summaryrefslogtreecommitdiffstats
path: root/doc/src/sgml
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:46:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:46:48 +0000
commit311bcfc6b3acdd6fd152798c7f287ddf74fa2a98 (patch)
tree0ec307299b1dada3701e42f4ca6eda57d708261e /doc/src/sgml
parentInitial commit. (diff)
downloadpostgresql-15-upstream.tar.xz
postgresql-15-upstream.zip
Adding upstream version 15.4.upstream/15.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/src/sgml')
-rw-r--r--doc/src/sgml/.gitignore25
-rw-r--r--doc/src/sgml/Makefile317
-rw-r--r--doc/src/sgml/README.links54
-rw-r--r--doc/src/sgml/acronyms.sgml818
-rw-r--r--doc/src/sgml/adminpack.sgml159
-rw-r--r--doc/src/sgml/advanced.sgml720
-rw-r--r--doc/src/sgml/amcheck.sgml558
-rw-r--r--doc/src/sgml/appendix-obsolete-default-roles.sgml22
-rw-r--r--doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml24
-rw-r--r--doc/src/sgml/appendix-obsolete-pgresetxlog.sgml24
-rw-r--r--doc/src/sgml/appendix-obsolete-pgxlogdump.sgml24
-rw-r--r--doc/src/sgml/appendix-obsolete-recovery-config.sgml58
-rw-r--r--doc/src/sgml/appendix-obsolete.sgml42
-rw-r--r--doc/src/sgml/arch-dev.sgml575
-rw-r--r--doc/src/sgml/archive-modules.sgml136
-rw-r--r--doc/src/sgml/array.sgml797
-rw-r--r--doc/src/sgml/auth-delay.sgml65
-rw-r--r--doc/src/sgml/auto-explain.sgml340
-rw-r--r--doc/src/sgml/backup-manifest.sgml216
-rw-r--r--doc/src/sgml/backup.sgml1496
-rw-r--r--doc/src/sgml/basebackup-to-shell.sgml85
-rw-r--r--doc/src/sgml/basic-archive.sgml81
-rw-r--r--doc/src/sgml/bgworker.sgml302
-rw-r--r--doc/src/sgml/biblio.sgml550
-rw-r--r--doc/src/sgml/bki.sgml1079
-rw-r--r--doc/src/sgml/bloom.sgml290
-rw-r--r--doc/src/sgml/brin.sgml1342
-rw-r--r--doc/src/sgml/btree-gin.sgml66
-rw-r--r--doc/src/sgml/btree-gist.sgml118
-rw-r--r--doc/src/sgml/btree.sgml914
-rw-r--r--doc/src/sgml/catalogs.sgml9584
-rw-r--r--doc/src/sgml/charset.sgml2741
-rw-r--r--doc/src/sgml/citext.sgml293
-rw-r--r--doc/src/sgml/client-auth.sgml2244
-rw-r--r--doc/src/sgml/color.sgml111
-rw-r--r--doc/src/sgml/config.sgml11607
-rw-r--r--doc/src/sgml/contrib-spi.sgml139
-rw-r--r--doc/src/sgml/contrib.sgml206
-rw-r--r--doc/src/sgml/cube.sgml639
-rw-r--r--doc/src/sgml/custom-rmgr.sgml98
-rw-r--r--doc/src/sgml/custom-scan.sgml407
-rw-r--r--doc/src/sgml/datatype.sgml5354
-rw-r--r--doc/src/sgml/datetime.sgml930
-rw-r--r--doc/src/sgml/dblink.sgml2136
-rw-r--r--doc/src/sgml/ddl.sgml5245
-rw-r--r--doc/src/sgml/dfunc.sgml252
-rw-r--r--doc/src/sgml/dict-int.sgml100
-rw-r--r--doc/src/sgml/dict-xsyn.sgml149
-rw-r--r--doc/src/sgml/diskusage.sgml144
-rw-r--r--doc/src/sgml/dml.sgml350
-rw-r--r--doc/src/sgml/docguide.sgml656
-rw-r--r--doc/src/sgml/earthdistance.sgml265
-rw-r--r--doc/src/sgml/ecpg.sgml10064
-rw-r--r--doc/src/sgml/errcodes.sgml89
-rw-r--r--doc/src/sgml/event-trigger.sgml1303
-rw-r--r--doc/src/sgml/extend.sgml1862
-rw-r--r--doc/src/sgml/external-projects.sgml251
-rw-r--r--doc/src/sgml/fdwhandler.sgml2139
-rw-r--r--doc/src/sgml/features.sgml494
-rw-r--r--doc/src/sgml/file-fdw.sgml282
-rw-r--r--doc/src/sgml/filelist.sgml201
-rw-r--r--doc/src/sgml/func.sgml28463
-rw-r--r--doc/src/sgml/fuzzystrmatch.sgml244
-rw-r--r--doc/src/sgml/generate-errcodes-table.pl59
-rw-r--r--doc/src/sgml/generate-keywords-table.pl139
-rw-r--r--doc/src/sgml/generic-wal.sgml174
-rw-r--r--doc/src/sgml/geqo.sgml303
-rw-r--r--doc/src/sgml/gin.sgml717
-rw-r--r--doc/src/sgml/gist.sgml1312
-rw-r--r--doc/src/sgml/glossary.sgml2063
-rw-r--r--doc/src/sgml/hash.sgml162
-rw-r--r--doc/src/sgml/high-availability.sgml2344
-rw-r--r--doc/src/sgml/history.sgml222
-rw-r--r--doc/src/sgml/hstore.sgml977
-rw-r--r--doc/src/sgml/html-stamp0
-rw-r--r--doc/src/sgml/html/acronyms.html219
-rw-r--r--doc/src/sgml/html/admin.html26
-rw-r--r--doc/src/sgml/html/adminpack.html89
-rw-r--r--doc/src/sgml/html/amcheck.html377
-rw-r--r--doc/src/sgml/html/app-clusterdb.html122
-rw-r--r--doc/src/sgml/html/app-createdb.html149
-rw-r--r--doc/src/sgml/html/app-createuser.html190
-rw-r--r--doc/src/sgml/html/app-dropdb.html111
-rw-r--r--doc/src/sgml/html/app-dropuser.html103
-rw-r--r--doc/src/sgml/html/app-ecpg.html106
-rw-r--r--doc/src/sgml/html/app-initdb.html251
-rw-r--r--doc/src/sgml/html/app-pg-ctl.html288
-rw-r--r--doc/src/sgml/html/app-pg-dumpall.html359
-rw-r--r--doc/src/sgml/html/app-pg-isready.html79
-rw-r--r--doc/src/sgml/html/app-pgamcheck.html295
-rw-r--r--doc/src/sgml/html/app-pgbasebackup.html550
-rw-r--r--doc/src/sgml/html/app-pgchecksums.html75
-rw-r--r--doc/src/sgml/html/app-pgconfig.html110
-rw-r--r--doc/src/sgml/html/app-pgcontroldata.html23
-rw-r--r--doc/src/sgml/html/app-pgdump.html821
-rw-r--r--doc/src/sgml/html/app-pgreceivewal.html249
-rw-r--r--doc/src/sgml/html/app-pgreceivexlog.html10
-rw-r--r--doc/src/sgml/html/app-pgrecvlogical.html177
-rw-r--r--doc/src/sgml/html/app-pgresetwal.html169
-rw-r--r--doc/src/sgml/html/app-pgresetxlog.html10
-rw-r--r--doc/src/sgml/html/app-pgrestore.html500
-rw-r--r--doc/src/sgml/html/app-pgrewind.html216
-rw-r--r--doc/src/sgml/html/app-pgverifybackup.html144
-rw-r--r--doc/src/sgml/html/app-postgres.html432
-rw-r--r--doc/src/sgml/html/app-postmaster.html6
-rw-r--r--doc/src/sgml/html/app-psql.html2955
-rw-r--r--doc/src/sgml/html/app-reindexdb.html164
-rw-r--r--doc/src/sgml/html/app-vacuumdb.html244
-rw-r--r--doc/src/sgml/html/appendix-obsolete.html8
-rw-r--r--doc/src/sgml/html/appendixes.html2
-rw-r--r--doc/src/sgml/html/applevel-consistency.html114
-rw-r--r--doc/src/sgml/html/archive-module-callbacks.html50
-rw-r--r--doc/src/sgml/html/archive-module-init.html24
-rw-r--r--doc/src/sgml/html/archive-modules.html24
-rw-r--r--doc/src/sgml/html/arrays.html647
-rw-r--r--doc/src/sgml/html/auth-bsd.html21
-rw-r--r--doc/src/sgml/html/auth-cert.html24
-rw-r--r--doc/src/sgml/html/auth-delay.html28
-rw-r--r--doc/src/sgml/html/auth-ident.html52
-rw-r--r--doc/src/sgml/html/auth-ldap.html190
-rw-r--r--doc/src/sgml/html/auth-methods.html59
-rw-r--r--doc/src/sgml/html/auth-pam.html31
-rw-r--r--doc/src/sgml/html/auth-password.html80
-rw-r--r--doc/src/sgml/html/auth-peer.html21
-rw-r--r--doc/src/sgml/html/auth-pg-hba-conf.html492
-rw-r--r--doc/src/sgml/html/auth-radius.html65
-rw-r--r--doc/src/sgml/html/auth-trust.html37
-rw-r--r--doc/src/sgml/html/auth-username-maps.html102
-rw-r--r--doc/src/sgml/html/auto-explain.html189
-rw-r--r--doc/src/sgml/html/backup-dump.html247
-rw-r--r--doc/src/sgml/html/backup-file.html91
-rw-r--r--doc/src/sgml/html/backup-manifest-files.html39
-rw-r--r--doc/src/sgml/html/backup-manifest-format.html16
-rw-r--r--doc/src/sgml/html/backup-manifest-toplevel.html25
-rw-r--r--doc/src/sgml/html/backup-manifest-wal-ranges.html22
-rw-r--r--doc/src/sgml/html/backup.html13
-rw-r--r--doc/src/sgml/html/basebackup-to-shell.html43
-rw-r--r--doc/src/sgml/html/basic-archive.html38
-rw-r--r--doc/src/sgml/html/bgworker.html231
-rw-r--r--doc/src/sgml/html/biblio.html23
-rw-r--r--doc/src/sgml/html/bki-commands.html111
-rw-r--r--doc/src/sgml/html/bki-example.html15
-rw-r--r--doc/src/sgml/html/bki-format.html19
-rw-r--r--doc/src/sgml/html/bki-structure.html42
-rw-r--r--doc/src/sgml/html/bki.html56
-rw-r--r--doc/src/sgml/html/bloom.html190
-rw-r--r--doc/src/sgml/html/bookindex.html62
-rw-r--r--doc/src/sgml/html/brin-builtin-opclasses.html46
-rw-r--r--doc/src/sgml/html/brin-extensibility.html168
-rw-r--r--doc/src/sgml/html/brin-intro.html99
-rw-r--r--doc/src/sgml/html/brin.html2
-rw-r--r--doc/src/sgml/html/btree-behavior.html118
-rw-r--r--doc/src/sgml/html/btree-gin.html38
-rw-r--r--doc/src/sgml/html/btree-gist.html80
-rw-r--r--doc/src/sgml/html/btree-implementation.html254
-rw-r--r--doc/src/sgml/html/btree-intro.html17
-rw-r--r--doc/src/sgml/html/btree-support-funcs.html291
-rw-r--r--doc/src/sgml/html/btree.html2
-rw-r--r--doc/src/sgml/html/bug-reporting.html248
-rw-r--r--doc/src/sgml/html/catalog-pg-aggregate.html170
-rw-r--r--doc/src/sgml/html/catalog-pg-am.html44
-rw-r--r--doc/src/sgml/html/catalog-pg-amop.html104
-rw-r--r--doc/src/sgml/html/catalog-pg-amproc.html55
-rw-r--r--doc/src/sgml/html/catalog-pg-attrdef.html37
-rw-r--r--doc/src/sgml/html/catalog-pg-attribute.html211
-rw-r--r--doc/src/sgml/html/catalog-pg-auth-members.html40
-rw-r--r--doc/src/sgml/html/catalog-pg-authid.html113
-rw-r--r--doc/src/sgml/html/catalog-pg-cast.html86
-rw-r--r--doc/src/sgml/html/catalog-pg-class.html264
-rw-r--r--doc/src/sgml/html/catalog-pg-collation.html93
-rw-r--r--doc/src/sgml/html/catalog-pg-constraint.html206
-rw-r--r--doc/src/sgml/html/catalog-pg-conversion.html56
-rw-r--r--doc/src/sgml/html/catalog-pg-database.html124
-rw-r--r--doc/src/sgml/html/catalog-pg-db-role-setting.html33
-rw-r--r--doc/src/sgml/html/catalog-pg-default-acl.html58
-rw-r--r--doc/src/sgml/html/catalog-pg-depend.html175
-rw-r--r--doc/src/sgml/html/catalog-pg-description.html43
-rw-r--r--doc/src/sgml/html/catalog-pg-enum.html49
-rw-r--r--doc/src/sgml/html/catalog-pg-event-trigger.html53
-rw-r--r--doc/src/sgml/html/catalog-pg-extension.html65
-rw-r--r--doc/src/sgml/html/catalog-pg-foreign-data-wrapper.html56
-rw-r--r--doc/src/sgml/html/catalog-pg-foreign-server.html54
-rw-r--r--doc/src/sgml/html/catalog-pg-foreign-table.html32
-rw-r--r--doc/src/sgml/html/catalog-pg-index.html163
-rw-r--r--doc/src/sgml/html/catalog-pg-inherits.html41
-rw-r--r--doc/src/sgml/html/catalog-pg-init-privs.html61
-rw-r--r--doc/src/sgml/html/catalog-pg-language.html76
-rw-r--r--doc/src/sgml/html/catalog-pg-largeobject-metadata.html28
-rw-r--r--doc/src/sgml/html/catalog-pg-largeobject.html48
-rw-r--r--doc/src/sgml/html/catalog-pg-namespace.html33
-rw-r--r--doc/src/sgml/html/catalog-pg-opclass.html75
-rw-r--r--doc/src/sgml/html/catalog-pg-operator.html101
-rw-r--r--doc/src/sgml/html/catalog-pg-opfamily.html53
-rw-r--r--doc/src/sgml/html/catalog-pg-parameter-acl.html31
-rw-r--r--doc/src/sgml/html/catalog-pg-partitioned-table.html71
-rw-r--r--doc/src/sgml/html/catalog-pg-policy.html68
-rw-r--r--doc/src/sgml/html/catalog-pg-proc.html256
-rw-r--r--doc/src/sgml/html/catalog-pg-publication-namespace.html28
-rw-r--r--doc/src/sgml/html/catalog-pg-publication-rel.html43
-rw-r--r--doc/src/sgml/html/catalog-pg-publication.html64
-rw-r--r--doc/src/sgml/html/catalog-pg-range.html61
-rw-r--r--doc/src/sgml/html/catalog-pg-replication-origin.html28
-rw-r--r--doc/src/sgml/html/catalog-pg-rewrite.html64
-rw-r--r--doc/src/sgml/html/catalog-pg-seclabel.html46
-rw-r--r--doc/src/sgml/html/catalog-pg-sequence.html54
-rw-r--r--doc/src/sgml/html/catalog-pg-shdepend.html98
-rw-r--r--doc/src/sgml/html/catalog-pg-shdescription.html38
-rw-r--r--doc/src/sgml/html/catalog-pg-shseclabel.html43
-rw-r--r--doc/src/sgml/html/catalog-pg-statistic-ext-data.html71
-rw-r--r--doc/src/sgml/html/catalog-pg-statistic-ext.html88
-rw-r--r--doc/src/sgml/html/catalog-pg-statistic.html134
-rw-r--r--doc/src/sgml/html/catalog-pg-subscription-rel.html45
-rw-r--r--doc/src/sgml/html/catalog-pg-subscription.html103
-rw-r--r--doc/src/sgml/html/catalog-pg-tablespace.html42
-rw-r--r--doc/src/sgml/html/catalog-pg-transform.html44
-rw-r--r--doc/src/sgml/html/catalog-pg-trigger.html148
-rw-r--r--doc/src/sgml/html/catalog-pg-ts-config-map.html38
-rw-r--r--doc/src/sgml/html/catalog-pg-ts-config.html45
-rw-r--r--doc/src/sgml/html/catalog-pg-ts-dict.html52
-rw-r--r--doc/src/sgml/html/catalog-pg-ts-parser.html62
-rw-r--r--doc/src/sgml/html/catalog-pg-ts-template.html44
-rw-r--r--doc/src/sgml/html/catalog-pg-type.html310
-rw-r--r--doc/src/sgml/html/catalog-pg-user-mapping.html35
-rw-r--r--doc/src/sgml/html/catalogs-overview.html10
-rw-r--r--doc/src/sgml/html/catalogs.html17
-rw-r--r--doc/src/sgml/html/charset.html20
-rw-r--r--doc/src/sgml/html/checksums.html25
-rw-r--r--doc/src/sgml/html/citext.html166
-rw-r--r--doc/src/sgml/html/client-authentication-problems.html40
-rw-r--r--doc/src/sgml/html/client-authentication.html37
-rw-r--r--doc/src/sgml/html/client-interfaces.html12
-rw-r--r--doc/src/sgml/html/collation.html417
-rw-r--r--doc/src/sgml/html/color-when.html15
-rw-r--r--doc/src/sgml/html/color-which.html26
-rw-r--r--doc/src/sgml/html/color.html5
-rw-r--r--doc/src/sgml/html/config-setting.html336
-rw-r--r--doc/src/sgml/html/connect-estab.html36
-rw-r--r--doc/src/sgml/html/continuous-archiving.html757
-rw-r--r--doc/src/sgml/html/contrib-dblink-build-sql-delete.html42
-rw-r--r--doc/src/sgml/html/contrib-dblink-build-sql-insert.html52
-rw-r--r--doc/src/sgml/html/contrib-dblink-build-sql-update.html54
-rw-r--r--doc/src/sgml/html/contrib-dblink-cancel-query.html19
-rw-r--r--doc/src/sgml/html/contrib-dblink-close.html42
-rw-r--r--doc/src/sgml/html/contrib-dblink-connect-u.html29
-rw-r--r--doc/src/sgml/html/contrib-dblink-connect.html105
-rw-r--r--doc/src/sgml/html/contrib-dblink-disconnect.html26
-rw-r--r--doc/src/sgml/html/contrib-dblink-error-message.html22
-rw-r--r--doc/src/sgml/html/contrib-dblink-exec.html65
-rw-r--r--doc/src/sgml/html/contrib-dblink-fetch.html77
-rw-r--r--doc/src/sgml/html/contrib-dblink-function.html143
-rw-r--r--doc/src/sgml/html/contrib-dblink-get-connections.html9
-rw-r--r--doc/src/sgml/html/contrib-dblink-get-notify.html33
-rw-r--r--doc/src/sgml/html/contrib-dblink-get-pkey.html43
-rw-r--r--doc/src/sgml/html/contrib-dblink-get-result.html98
-rw-r--r--doc/src/sgml/html/contrib-dblink-is-busy.html14
-rw-r--r--doc/src/sgml/html/contrib-dblink-open.html48
-rw-r--r--doc/src/sgml/html/contrib-dblink-send-query.html24
-rw-r--r--doc/src/sgml/html/contrib-prog-client.html9
-rw-r--r--doc/src/sgml/html/contrib-prog-server.html7
-rw-r--r--doc/src/sgml/html/contrib-prog.html15
-rw-r--r--doc/src/sgml/html/contrib-spi.html81
-rw-r--r--doc/src/sgml/html/contrib.html87
-rw-r--r--doc/src/sgml/html/creating-cluster.html203
-rw-r--r--doc/src/sgml/html/cube.html391
-rw-r--r--doc/src/sgml/html/custom-rmgr.html81
-rw-r--r--doc/src/sgml/html/custom-scan-execution.html139
-rw-r--r--doc/src/sgml/html/custom-scan-path.html101
-rw-r--r--doc/src/sgml/html/custom-scan-plan.html67
-rw-r--r--doc/src/sgml/html/custom-scan.html21
-rw-r--r--doc/src/sgml/html/database-roles.html70
-rw-r--r--doc/src/sgml/html/datatype-binary.html132
-rw-r--r--doc/src/sgml/html/datatype-bit.html49
-rw-r--r--doc/src/sgml/html/datatype-boolean.html58
-rw-r--r--doc/src/sgml/html/datatype-character.html142
-rw-r--r--doc/src/sgml/html/datatype-datetime.html549
-rw-r--r--doc/src/sgml/html/datatype-enum.html115
-rw-r--r--doc/src/sgml/html/datatype-geometric.html152
-rw-r--r--doc/src/sgml/html/datatype-json.html730
-rw-r--r--doc/src/sgml/html/datatype-money.html44
-rw-r--r--doc/src/sgml/html/datatype-net-types.html132
-rw-r--r--doc/src/sgml/html/datatype-numeric.html370
-rw-r--r--doc/src/sgml/html/datatype-oid.html166
-rw-r--r--doc/src/sgml/html/datatype-pg-lsn.html22
-rw-r--r--doc/src/sgml/html/datatype-pseudo.html59
-rw-r--r--doc/src/sgml/html/datatype-textsearch.html196
-rw-r--r--doc/src/sgml/html/datatype-uuid.html39
-rw-r--r--doc/src/sgml/html/datatype-xml.html151
-rw-r--r--doc/src/sgml/html/datatype.html36
-rw-r--r--doc/src/sgml/html/datetime-appendix.html15
-rw-r--r--doc/src/sgml/html/datetime-config-files.html98
-rw-r--r--doc/src/sgml/html/datetime-input-rules.html74
-rw-r--r--doc/src/sgml/html/datetime-invalid-input.html62
-rw-r--r--doc/src/sgml/html/datetime-julian-dates.html48
-rw-r--r--doc/src/sgml/html/datetime-keywords.html11
-rw-r--r--doc/src/sgml/html/datetime-posix-timezone-specs.html135
-rw-r--r--doc/src/sgml/html/datetime-units-history.html87
-rw-r--r--doc/src/sgml/html/dblink.html18
-rw-r--r--doc/src/sgml/html/ddl-alter.html156
-rw-r--r--doc/src/sgml/html/ddl-basics.html101
-rw-r--r--doc/src/sgml/html/ddl-constraints.html607
-rw-r--r--doc/src/sgml/html/ddl-default.html49
-rw-r--r--doc/src/sgml/html/ddl-depend.html99
-rw-r--r--doc/src/sgml/html/ddl-foreign-data.html41
-rw-r--r--doc/src/sgml/html/ddl-generated-columns.html85
-rw-r--r--doc/src/sgml/html/ddl-inherit.html289
-rw-r--r--doc/src/sgml/html/ddl-others.html20
-rw-r--r--doc/src/sgml/html/ddl-partitioning.html992
-rw-r--r--doc/src/sgml/html/ddl-priv.html307
-rw-r--r--doc/src/sgml/html/ddl-rowsecurity.html382
-rw-r--r--doc/src/sgml/html/ddl-schemas.html329
-rw-r--r--doc/src/sgml/html/ddl-system-columns.html58
-rw-r--r--doc/src/sgml/html/ddl.html13
-rw-r--r--doc/src/sgml/html/default-roles.html9
-rw-r--r--doc/src/sgml/html/dict-int.html62
-rw-r--r--doc/src/sgml/html/dict-xsyn.html97
-rw-r--r--doc/src/sgml/html/different-replication-solutions.html137
-rw-r--r--doc/src/sgml/html/disk-full.html20
-rw-r--r--doc/src/sgml/html/disk-usage.html83
-rw-r--r--doc/src/sgml/html/diskusage.html5
-rw-r--r--doc/src/sgml/html/dml-delete.html28
-rw-r--r--doc/src/sgml/html/dml-insert.html81
-rw-r--r--doc/src/sgml/html/dml-returning.html53
-rw-r--r--doc/src/sgml/html/dml-update.html61
-rw-r--r--doc/src/sgml/html/dml.html9
-rw-r--r--doc/src/sgml/html/docguide-authoring.html23
-rw-r--r--doc/src/sgml/html/docguide-build.html91
-rw-r--r--doc/src/sgml/html/docguide-docbook.html23
-rw-r--r--doc/src/sgml/html/docguide-style.html89
-rw-r--r--doc/src/sgml/html/docguide-toolsets.html115
-rw-r--r--doc/src/sgml/html/docguide.html24
-rw-r--r--doc/src/sgml/html/domains.html34
-rw-r--r--doc/src/sgml/html/dynamic-trace.html301
-rw-r--r--doc/src/sgml/html/earthdistance.html158
-rw-r--r--doc/src/sgml/html/ecpg-commands.html163
-rw-r--r--doc/src/sgml/html/ecpg-concept.html52
-rw-r--r--doc/src/sgml/html/ecpg-connect.html249
-rw-r--r--doc/src/sgml/html/ecpg-cpp.html228
-rw-r--r--doc/src/sgml/html/ecpg-descriptors.html710
-rw-r--r--doc/src/sgml/html/ecpg-develop.html124
-rw-r--r--doc/src/sgml/html/ecpg-dynamic.html103
-rw-r--r--doc/src/sgml/html/ecpg-errors.html441
-rw-r--r--doc/src/sgml/html/ecpg-informix-compat.html892
-rw-r--r--doc/src/sgml/html/ecpg-library.html46
-rw-r--r--doc/src/sgml/html/ecpg-lo.html100
-rw-r--r--doc/src/sgml/html/ecpg-oracle-compat.html19
-rw-r--r--doc/src/sgml/html/ecpg-pgtypes.html765
-rw-r--r--doc/src/sgml/html/ecpg-preproc.html129
-rw-r--r--doc/src/sgml/html/ecpg-process.html68
-rw-r--r--doc/src/sgml/html/ecpg-sql-allocate-descriptor.html19
-rw-r--r--doc/src/sgml/html/ecpg-sql-commands.html7
-rw-r--r--doc/src/sgml/html/ecpg-sql-connect.html109
-rw-r--r--doc/src/sgml/html/ecpg-sql-deallocate-descriptor.html16
-rw-r--r--doc/src/sgml/html/ecpg-sql-declare-statement.html33
-rw-r--r--doc/src/sgml/html/ecpg-sql-declare.html43
-rw-r--r--doc/src/sgml/html/ecpg-sql-describe.html26
-rw-r--r--doc/src/sgml/html/ecpg-sql-disconnect.html40
-rw-r--r--doc/src/sgml/html/ecpg-sql-execute-immediate.html37
-rw-r--r--doc/src/sgml/html/ecpg-sql-get-descriptor.html104
-rw-r--r--doc/src/sgml/html/ecpg-sql-open.html31
-rw-r--r--doc/src/sgml/html/ecpg-sql-prepare.html42
-rw-r--r--doc/src/sgml/html/ecpg-sql-set-autocommit.html13
-rw-r--r--doc/src/sgml/html/ecpg-sql-set-connection.html18
-rw-r--r--doc/src/sgml/html/ecpg-sql-set-descriptor.html38
-rw-r--r--doc/src/sgml/html/ecpg-sql-type.html88
-rw-r--r--doc/src/sgml/html/ecpg-sql-var.html19
-rw-r--r--doc/src/sgml/html/ecpg-sql-whenever.html57
-rw-r--r--doc/src/sgml/html/ecpg-variables.html881
-rw-r--r--doc/src/sgml/html/ecpg.html13
-rw-r--r--doc/src/sgml/html/encryption-options.html84
-rw-r--r--doc/src/sgml/html/errcodes-appendix.html45
-rw-r--r--doc/src/sgml/html/error-message-reporting.html250
-rw-r--r--doc/src/sgml/html/error-style-guide.html250
-rw-r--r--doc/src/sgml/html/event-log-registration.html28
-rw-r--r--doc/src/sgml/html/event-trigger-definition.html78
-rw-r--r--doc/src/sgml/html/event-trigger-example.html78
-rw-r--r--doc/src/sgml/html/event-trigger-interface.html68
-rw-r--r--doc/src/sgml/html/event-trigger-matrix.html5
-rw-r--r--doc/src/sgml/html/event-trigger-table-rewrite-example.html48
-rw-r--r--doc/src/sgml/html/event-triggers.html12
-rw-r--r--doc/src/sgml/html/executor.html78
-rw-r--r--doc/src/sgml/html/explicit-joins.html144
-rw-r--r--doc/src/sgml/html/explicit-locking.html396
-rw-r--r--doc/src/sgml/html/extend-extensions.html626
-rw-r--r--doc/src/sgml/html/extend-how.html33
-rw-r--r--doc/src/sgml/html/extend-pgxs.html230
-rw-r--r--doc/src/sgml/html/extend-type-system.html222
-rw-r--r--doc/src/sgml/html/extend.html20
-rw-r--r--doc/src/sgml/html/external-admin-tools.html7
-rw-r--r--doc/src/sgml/html/external-extensions.html14
-rw-r--r--doc/src/sgml/html/external-interfaces.html21
-rw-r--r--doc/src/sgml/html/external-pl.html14
-rw-r--r--doc/src/sgml/html/external-projects.html7
-rw-r--r--doc/src/sgml/html/fdw-callbacks.html1257
-rw-r--r--doc/src/sgml/html/fdw-functions.html36
-rw-r--r--doc/src/sgml/html/fdw-helpers.html114
-rw-r--r--doc/src/sgml/html/fdw-planning.html191
-rw-r--r--doc/src/sgml/html/fdw-row-locking.html93
-rw-r--r--doc/src/sgml/html/fdwhandler.html21
-rw-r--r--doc/src/sgml/html/features-sql-standard.html4
-rw-r--r--doc/src/sgml/html/features.html73
-rw-r--r--doc/src/sgml/html/file-fdw.html145
-rw-r--r--doc/src/sgml/html/functions-admin.html1648
-rw-r--r--doc/src/sgml/html/functions-aggregate.html729
-rw-r--r--doc/src/sgml/html/functions-array.html385
-rw-r--r--doc/src/sgml/html/functions-binarystring.html510
-rw-r--r--doc/src/sgml/html/functions-bitstring.html235
-rw-r--r--doc/src/sgml/html/functions-comparison.html400
-rw-r--r--doc/src/sgml/html/functions-comparisons.html215
-rw-r--r--doc/src/sgml/html/functions-conditional.html187
-rw-r--r--doc/src/sgml/html/functions-datetime.html1316
-rw-r--r--doc/src/sgml/html/functions-enum.html84
-rw-r--r--doc/src/sgml/html/functions-event-triggers.html133
-rw-r--r--doc/src/sgml/html/functions-formatting.html406
-rw-r--r--doc/src/sgml/html/functions-geometry.html886
-rw-r--r--doc/src/sgml/html/functions-info.html1774
-rw-r--r--doc/src/sgml/html/functions-json.html1781
-rw-r--r--doc/src/sgml/html/functions-logical.html36
-rw-r--r--doc/src/sgml/html/functions-matching.html1415
-rw-r--r--doc/src/sgml/html/functions-math.html1001
-rw-r--r--doc/src/sgml/html/functions-net.html397
-rw-r--r--doc/src/sgml/html/functions-range.html707
-rw-r--r--doc/src/sgml/html/functions-sequence.html139
-rw-r--r--doc/src/sgml/html/functions-srf.html218
-rw-r--r--doc/src/sgml/html/functions-statistics.html24
-rw-r--r--doc/src/sgml/html/functions-string.html1208
-rw-r--r--doc/src/sgml/html/functions-subquery.html213
-rw-r--r--doc/src/sgml/html/functions-textsearch.html763
-rw-r--r--doc/src/sgml/html/functions-trigger.html93
-rw-r--r--doc/src/sgml/html/functions-uuid.html16
-rw-r--r--doc/src/sgml/html/functions-window.html182
-rw-r--r--doc/src/sgml/html/functions-xml.html912
-rw-r--r--doc/src/sgml/html/functions.html33
-rw-r--r--doc/src/sgml/html/fuzzystrmatch.html138
-rw-r--r--doc/src/sgml/html/generic-wal.html102
-rw-r--r--doc/src/sgml/html/genetic-algorithm.svg140
-rw-r--r--doc/src/sgml/html/geqo-biblio.html18
-rw-r--r--doc/src/sgml/html/geqo-intro.html36
-rw-r--r--doc/src/sgml/html/geqo-intro2.html27
-rw-r--r--doc/src/sgml/html/geqo-pg-intro.html107
-rw-r--r--doc/src/sgml/html/geqo.html8
-rw-r--r--doc/src/sgml/html/gin-builtin-opclasses.html13
-rw-r--r--doc/src/sgml/html/gin-examples.html10
-rw-r--r--doc/src/sgml/html/gin-extensibility.html237
-rw-r--r--doc/src/sgml/html/gin-implementation.html64
-rw-r--r--doc/src/sgml/html/gin-intro.html40
-rw-r--r--doc/src/sgml/html/gin-limit.html10
-rw-r--r--doc/src/sgml/html/gin-tips.html58
-rw-r--r--doc/src/sgml/html/gin.html2
-rw-r--r--doc/src/sgml/html/gin.svg317
-rw-r--r--doc/src/sgml/html/gist-builtin-opclasses.html16
-rw-r--r--doc/src/sgml/html/gist-examples.html13
-rw-r--r--doc/src/sgml/html/gist-extensibility.html813
-rw-r--r--doc/src/sgml/html/gist-implementation.html38
-rw-r--r--doc/src/sgml/html/gist-intro.html23
-rw-r--r--doc/src/sgml/html/gist.html2
-rw-r--r--doc/src/sgml/html/git.html42
-rw-r--r--doc/src/sgml/html/glossary.html1061
-rw-r--r--doc/src/sgml/html/gssapi-auth.html118
-rw-r--r--doc/src/sgml/html/gssapi-enc.html31
-rw-r--r--doc/src/sgml/html/hash-implementation.html36
-rw-r--r--doc/src/sgml/html/hash-index.html2
-rw-r--r--doc/src/sgml/html/hash-intro.html77
-rw-r--r--doc/src/sgml/html/high-availability.html57
-rw-r--r--doc/src/sgml/html/history.html140
-rw-r--r--doc/src/sgml/html/hot-standby.html575
-rw-r--r--doc/src/sgml/html/how-parallel-query-works.html71
-rw-r--r--doc/src/sgml/html/hstore.html699
-rw-r--r--doc/src/sgml/html/index-api.html180
-rw-r--r--doc/src/sgml/html/index-cost-estimation.html142
-rw-r--r--doc/src/sgml/html/index-functions.html483
-rw-r--r--doc/src/sgml/html/index-locking.html91
-rw-r--r--doc/src/sgml/html/index-scanning.html123
-rw-r--r--doc/src/sgml/html/index-unique-checks.html109
-rw-r--r--doc/src/sgml/html/index.html2
-rw-r--r--doc/src/sgml/html/indexam.html35
-rw-r--r--doc/src/sgml/html/indexes-bitmap-scans.html61
-rw-r--r--doc/src/sgml/html/indexes-collations.html31
-rw-r--r--doc/src/sgml/html/indexes-examine.html82
-rw-r--r--doc/src/sgml/html/indexes-expressional.html49
-rw-r--r--doc/src/sgml/html/indexes-index-only-scans.html209
-rw-r--r--doc/src/sgml/html/indexes-intro.html77
-rw-r--r--doc/src/sgml/html/indexes-multicolumn.html82
-rw-r--r--doc/src/sgml/html/indexes-opclass.html107
-rw-r--r--doc/src/sgml/html/indexes-ordering.html64
-rw-r--r--doc/src/sgml/html/indexes-partial.html212
-rw-r--r--doc/src/sgml/html/indexes-types.html162
-rw-r--r--doc/src/sgml/html/indexes-unique.html26
-rw-r--r--doc/src/sgml/html/indexes.html8
-rw-r--r--doc/src/sgml/html/information-schema.html31
-rw-r--r--doc/src/sgml/html/infoschema-administrable-role-authorizations.html28
-rw-r--r--doc/src/sgml/html/infoschema-applicable-roles.html33
-rw-r--r--doc/src/sgml/html/infoschema-attributes.html226
-rw-r--r--doc/src/sgml/html/infoschema-character-sets.html86
-rw-r--r--doc/src/sgml/html/infoschema-check-constraint-routine-usage.html42
-rw-r--r--doc/src/sgml/html/infoschema-check-constraints.html32
-rw-r--r--doc/src/sgml/html/infoschema-collation-character-set-applicab.html44
-rw-r--r--doc/src/sgml/html/infoschema-collations.html31
-rw-r--r--doc/src/sgml/html/infoschema-column-column-usage.html36
-rw-r--r--doc/src/sgml/html/infoschema-column-domain-usage.html46
-rw-r--r--doc/src/sgml/html/infoschema-column-options.html42
-rw-r--r--doc/src/sgml/html/infoschema-column-privileges.html60
-rw-r--r--doc/src/sgml/html/infoschema-column-udt-usage.html52
-rw-r--r--doc/src/sgml/html/infoschema-columns.html337
-rw-r--r--doc/src/sgml/html/infoschema-constraint-column-usage.html55
-rw-r--r--doc/src/sgml/html/infoschema-constraint-table-usage.html50
-rw-r--r--doc/src/sgml/html/infoschema-data-type-privileges.html52
-rw-r--r--doc/src/sgml/html/infoschema-datatypes.html33
-rw-r--r--doc/src/sgml/html/infoschema-domain-constraints.html52
-rw-r--r--doc/src/sgml/html/infoschema-domain-udt-usage.html43
-rw-r--r--doc/src/sgml/html/infoschema-domains.html197
-rw-r--r--doc/src/sgml/html/infoschema-element-types.html194
-rw-r--r--doc/src/sgml/html/infoschema-enabled-roles.html28
-rw-r--r--doc/src/sgml/html/infoschema-foreign-data-wrapper-options.html33
-rw-r--r--doc/src/sgml/html/infoschema-foreign-data-wrappers.html38
-rw-r--r--doc/src/sgml/html/infoschema-foreign-server-options.html32
-rw-r--r--doc/src/sgml/html/infoschema-foreign-servers.html48
-rw-r--r--doc/src/sgml/html/infoschema-foreign-table-options.html37
-rw-r--r--doc/src/sgml/html/infoschema-foreign-tables.html37
-rw-r--r--doc/src/sgml/html/infoschema-information-schema-catalog-name.html16
-rw-r--r--doc/src/sgml/html/infoschema-key-column-usage.html65
-rw-r--r--doc/src/sgml/html/infoschema-parameters.html188
-rw-r--r--doc/src/sgml/html/infoschema-referential-constraints.html70
-rw-r--r--doc/src/sgml/html/infoschema-role-column-grants.html58
-rw-r--r--doc/src/sgml/html/infoschema-role-routine-grants.html66
-rw-r--r--doc/src/sgml/html/infoschema-role-table-grants.html64
-rw-r--r--doc/src/sgml/html/infoschema-role-udt-grants.html53
-rw-r--r--doc/src/sgml/html/infoschema-role-usage-grants.html57
-rw-r--r--doc/src/sgml/html/infoschema-routine-column-usage.html62
-rw-r--r--doc/src/sgml/html/infoschema-routine-privileges.html62
-rw-r--r--doc/src/sgml/html/infoschema-routine-routine-usage.html55
-rw-r--r--doc/src/sgml/html/infoschema-routine-sequence-usage.html59
-rw-r--r--doc/src/sgml/html/infoschema-routine-table-usage.html57
-rw-r--r--doc/src/sgml/html/infoschema-routines.html464
-rw-r--r--doc/src/sgml/html/infoschema-schema.html16
-rw-r--r--doc/src/sgml/html/infoschema-schemata.html46
-rw-r--r--doc/src/sgml/html/infoschema-sequences.html87
-rw-r--r--doc/src/sgml/html/infoschema-sql-features.html50
-rw-r--r--doc/src/sgml/html/infoschema-sql-implementation-info.html45
-rw-r--r--doc/src/sgml/html/infoschema-sql-parts.html39
-rw-r--r--doc/src/sgml/html/infoschema-sql-sizing.html38
-rw-r--r--doc/src/sgml/html/infoschema-table-constraints.html73
-rw-r--r--doc/src/sgml/html/infoschema-table-privileges.html60
-rw-r--r--doc/src/sgml/html/infoschema-tables.html82
-rw-r--r--doc/src/sgml/html/infoschema-transforms.html55
-rw-r--r--doc/src/sgml/html/infoschema-triggered-update-columns.html51
-rw-r--r--doc/src/sgml/html/infoschema-triggers.html150
-rw-r--r--doc/src/sgml/html/infoschema-udt-privileges.html50
-rw-r--r--doc/src/sgml/html/infoschema-usage-privileges.html66
-rw-r--r--doc/src/sgml/html/infoschema-user-defined-types.html168
-rw-r--r--doc/src/sgml/html/infoschema-user-mapping-options.html45
-rw-r--r--doc/src/sgml/html/infoschema-user-mappings.html30
-rw-r--r--doc/src/sgml/html/infoschema-view-column-usage.html54
-rw-r--r--doc/src/sgml/html/infoschema-view-routine-usage.html43
-rw-r--r--doc/src/sgml/html/infoschema-view-table-usage.html47
-rw-r--r--doc/src/sgml/html/infoschema-views.html70
-rw-r--r--doc/src/sgml/html/install-binaries.html13
-rw-r--r--doc/src/sgml/html/install-getsource.html20
-rw-r--r--doc/src/sgml/html/install-post.html103
-rw-r--r--doc/src/sgml/html/install-procedure.html818
-rw-r--r--doc/src/sgml/html/install-requirements.html197
-rw-r--r--doc/src/sgml/html/install-short.html19
-rw-r--r--doc/src/sgml/html/install-windows-full.html333
-rw-r--r--doc/src/sgml/html/install-windows.html44
-rw-r--r--doc/src/sgml/html/installation-platform-notes.html314
-rw-r--r--doc/src/sgml/html/installation.html13
-rw-r--r--doc/src/sgml/html/intagg.html89
-rw-r--r--doc/src/sgml/html/intarray.html321
-rw-r--r--doc/src/sgml/html/internals.html5
-rw-r--r--doc/src/sgml/html/intro-whatis.html26
-rw-r--r--doc/src/sgml/html/isn.html209
-rw-r--r--doc/src/sgml/html/jit-configuration.html17
-rw-r--r--doc/src/sgml/html/jit-decision.html71
-rw-r--r--doc/src/sgml/html/jit-extensibility.html51
-rw-r--r--doc/src/sgml/html/jit-reason.html47
-rw-r--r--doc/src/sgml/html/jit.html5
-rw-r--r--doc/src/sgml/html/kernel-resources.html553
-rw-r--r--doc/src/sgml/html/largeobjects.html17
-rw-r--r--doc/src/sgml/html/legalnotice.html27
-rw-r--r--doc/src/sgml/html/libpq-async.html337
-rw-r--r--doc/src/sgml/html/libpq-build.html106
-rw-r--r--doc/src/sgml/html/libpq-cancel.html74
-rw-r--r--doc/src/sgml/html/libpq-connect.html1134
-rw-r--r--doc/src/sgml/html/libpq-control.html139
-rw-r--r--doc/src/sgml/html/libpq-copy.html300
-rw-r--r--doc/src/sgml/html/libpq-envars.html156
-rw-r--r--doc/src/sgml/html/libpq-events.html425
-rw-r--r--doc/src/sgml/html/libpq-example.html529
-rw-r--r--doc/src/sgml/html/libpq-exec.html1050
-rw-r--r--doc/src/sgml/html/libpq-fastpath.html85
-rw-r--r--doc/src/sgml/html/libpq-ldap.html63
-rw-r--r--doc/src/sgml/html/libpq-misc.html233
-rw-r--r--doc/src/sgml/html/libpq-notice-processing.html86
-rw-r--r--doc/src/sgml/html/libpq-notify.html73
-rw-r--r--doc/src/sgml/html/libpq-pgpass.html45
-rw-r--r--doc/src/sgml/html/libpq-pgservice.html52
-rw-r--r--doc/src/sgml/html/libpq-pipeline-mode.html327
-rw-r--r--doc/src/sgml/html/libpq-single-row-mode.html64
-rw-r--r--doc/src/sgml/html/libpq-ssl.html273
-rw-r--r--doc/src/sgml/html/libpq-status.html427
-rw-r--r--doc/src/sgml/html/libpq-threading.html47
-rw-r--r--doc/src/sgml/html/libpq.html29
-rw-r--r--doc/src/sgml/html/limits.html27
-rw-r--r--doc/src/sgml/html/lo-examplesect.html281
-rw-r--r--doc/src/sgml/html/lo-funcs.html117
-rw-r--r--doc/src/sgml/html/lo-implementation.html30
-rw-r--r--doc/src/sgml/html/lo-interfaces.html322
-rw-r--r--doc/src/sgml/html/lo-intro.html18
-rw-r--r--doc/src/sgml/html/lo.html76
-rw-r--r--doc/src/sgml/html/locale.html246
-rw-r--r--doc/src/sgml/html/locking-indexes.html42
-rw-r--r--doc/src/sgml/html/logfile-maintenance.html112
-rw-r--r--doc/src/sgml/html/logical-replication-architecture.html54
-rw-r--r--doc/src/sgml/html/logical-replication-col-lists.html144
-rw-r--r--doc/src/sgml/html/logical-replication-config.html23
-rw-r--r--doc/src/sgml/html/logical-replication-conflicts.html56
-rw-r--r--doc/src/sgml/html/logical-replication-monitoring.html20
-rw-r--r--doc/src/sgml/html/logical-replication-publication.html53
-rw-r--r--doc/src/sgml/html/logical-replication-quick-setup.html31
-rw-r--r--doc/src/sgml/html/logical-replication-restrictions.html57
-rw-r--r--doc/src/sgml/html/logical-replication-row-filter.html440
-rw-r--r--doc/src/sgml/html/logical-replication-security.html48
-rw-r--r--doc/src/sgml/html/logical-replication-subscription.html278
-rw-r--r--doc/src/sgml/html/logical-replication.html55
-rw-r--r--doc/src/sgml/html/logicaldecoding-catalogs.html13
-rw-r--r--doc/src/sgml/html/logicaldecoding-example.html184
-rw-r--r--doc/src/sgml/html/logicaldecoding-explanation.html76
-rw-r--r--doc/src/sgml/html/logicaldecoding-output-plugin.html471
-rw-r--r--doc/src/sgml/html/logicaldecoding-sql.html10
-rw-r--r--doc/src/sgml/html/logicaldecoding-streaming.html86
-rw-r--r--doc/src/sgml/html/logicaldecoding-synchronous.html50
-rw-r--r--doc/src/sgml/html/logicaldecoding-two-phase-commits.html55
-rw-r--r--doc/src/sgml/html/logicaldecoding-walsender.html13
-rw-r--r--doc/src/sgml/html/logicaldecoding-writer.html9
-rw-r--r--doc/src/sgml/html/logicaldecoding.html27
-rw-r--r--doc/src/sgml/html/ltree.html582
-rw-r--r--doc/src/sgml/html/maintenance.html37
-rw-r--r--doc/src/sgml/html/manage-ag-config.html25
-rw-r--r--doc/src/sgml/html/manage-ag-createdb.html79
-rw-r--r--doc/src/sgml/html/manage-ag-dropdb.html28
-rw-r--r--doc/src/sgml/html/manage-ag-overview.html59
-rw-r--r--doc/src/sgml/html/manage-ag-tablespaces.html132
-rw-r--r--doc/src/sgml/html/manage-ag-templatedbs.html88
-rw-r--r--doc/src/sgml/html/managing-databases.html9
-rw-r--r--doc/src/sgml/html/monitoring-locks.html28
-rw-r--r--doc/src/sgml/html/monitoring-ps.html77
-rw-r--r--doc/src/sgml/html/monitoring-stats.html2470
-rw-r--r--doc/src/sgml/html/monitoring.html18
-rw-r--r--doc/src/sgml/html/multibyte.html351
-rw-r--r--doc/src/sgml/html/multivariate-statistics-examples.html210
-rw-r--r--doc/src/sgml/html/mvcc-caveats.html34
-rw-r--r--doc/src/sgml/html/mvcc-intro.html37
-rw-r--r--doc/src/sgml/html/mvcc-serialization-failure-handling.html47
-rw-r--r--doc/src/sgml/html/mvcc.html10
-rw-r--r--doc/src/sgml/html/nls-programmer.html154
-rw-r--r--doc/src/sgml/html/nls-translator.html218
-rw-r--r--doc/src/sgml/html/nls.html2
-rw-r--r--doc/src/sgml/html/non-durability.html39
-rw-r--r--doc/src/sgml/html/notation.html22
-rw-r--r--doc/src/sgml/html/oid2name.html192
-rw-r--r--doc/src/sgml/html/oldsnapshot.html10
-rw-r--r--doc/src/sgml/html/overview.html15
-rw-r--r--doc/src/sgml/html/pageinspect.html567
-rw-r--r--doc/src/sgml/html/pagelayout.svg35
-rw-r--r--doc/src/sgml/html/parallel-plans.html155
-rw-r--r--doc/src/sgml/html/parallel-query.html15
-rw-r--r--doc/src/sgml/html/parallel-safety.html83
-rw-r--r--doc/src/sgml/html/parser-stage.html91
-rw-r--r--doc/src/sgml/html/passwordcheck.html42
-rw-r--r--doc/src/sgml/html/performance-tips.html7
-rw-r--r--doc/src/sgml/html/perm-functions.html22
-rw-r--r--doc/src/sgml/html/pgarchivecleanup.html94
-rw-r--r--doc/src/sgml/html/pgbench.html1721
-rw-r--r--doc/src/sgml/html/pgbuffercache.html118
-rw-r--r--doc/src/sgml/html/pgcrypto.html544
-rw-r--r--doc/src/sgml/html/pgfreespacemap.html68
-rw-r--r--doc/src/sgml/html/pgprewarm.html82
-rw-r--r--doc/src/sgml/html/pgrowlocks.html51
-rw-r--r--doc/src/sgml/html/pgstatstatements.html613
-rw-r--r--doc/src/sgml/html/pgstattuple.html199
-rw-r--r--doc/src/sgml/html/pgsurgery.html68
-rw-r--r--doc/src/sgml/html/pgtestfsync.html41
-rw-r--r--doc/src/sgml/html/pgtesttiming.html179
-rw-r--r--doc/src/sgml/html/pgtrgm.html424
-rw-r--r--doc/src/sgml/html/pgupgrade.html434
-rw-r--r--doc/src/sgml/html/pgvisibility.html69
-rw-r--r--doc/src/sgml/html/pgwaldump.html108
-rw-r--r--doc/src/sgml/html/pgwalinspect.html130
-rw-r--r--doc/src/sgml/html/pgxlogdump.html10
-rw-r--r--doc/src/sgml/html/planner-optimizer.html111
-rw-r--r--doc/src/sgml/html/planner-stats-details.html13
-rw-r--r--doc/src/sgml/html/planner-stats-security.html49
-rw-r--r--doc/src/sgml/html/planner-stats.html336
-rw-r--r--doc/src/sgml/html/plhandler.html156
-rw-r--r--doc/src/sgml/html/plperl-builtins.html360
-rw-r--r--doc/src/sgml/html/plperl-data.html14
-rw-r--r--doc/src/sgml/html/plperl-event-triggers.html28
-rw-r--r--doc/src/sgml/html/plperl-funcs.html308
-rw-r--r--doc/src/sgml/html/plperl-global.html65
-rw-r--r--doc/src/sgml/html/plperl-triggers.html74
-rw-r--r--doc/src/sgml/html/plperl-trusted.html72
-rw-r--r--doc/src/sgml/html/plperl-under-the-hood.html111
-rw-r--r--doc/src/sgml/html/plperl.html22
-rw-r--r--doc/src/sgml/html/plpgsql-control-structures.html943
-rw-r--r--doc/src/sgml/html/plpgsql-cursors.html386
-rw-r--r--doc/src/sgml/html/plpgsql-declarations.html464
-rw-r--r--doc/src/sgml/html/plpgsql-development-tips.html228
-rw-r--r--doc/src/sgml/html/plpgsql-errors-and-messages.html148
-rw-r--r--doc/src/sgml/html/plpgsql-expressions.html55
-rw-r--r--doc/src/sgml/html/plpgsql-implementation.html276
-rw-r--r--doc/src/sgml/html/plpgsql-overview.html103
-rw-r--r--doc/src/sgml/html/plpgsql-porting.html560
-rw-r--r--doc/src/sgml/html/plpgsql-statements.html598
-rw-r--r--doc/src/sgml/html/plpgsql-structure.html108
-rw-r--r--doc/src/sgml/html/plpgsql-transactions.html82
-rw-r--r--doc/src/sgml/html/plpgsql-trigger.html516
-rw-r--r--doc/src/sgml/html/plpgsql.html2
-rw-r--r--doc/src/sgml/html/plpython-data.html343
-rw-r--r--doc/src/sgml/html/plpython-database.html238
-rw-r--r--doc/src/sgml/html/plpython-do.html14
-rw-r--r--doc/src/sgml/html/plpython-envar.html17
-rw-r--r--doc/src/sgml/html/plpython-funcs.html88
-rw-r--r--doc/src/sgml/html/plpython-python23.html7
-rw-r--r--doc/src/sgml/html/plpython-sharing.html14
-rw-r--r--doc/src/sgml/html/plpython-subtransaction.html68
-rw-r--r--doc/src/sgml/html/plpython-transactions.html31
-rw-r--r--doc/src/sgml/html/plpython-trigger.html40
-rw-r--r--doc/src/sgml/html/plpython-util.html60
-rw-r--r--doc/src/sgml/html/plpython.html28
-rw-r--r--doc/src/sgml/html/pltcl-config.html42
-rw-r--r--doc/src/sgml/html/pltcl-data.html9
-rw-r--r--doc/src/sgml/html/pltcl-dbaccess.html193
-rw-r--r--doc/src/sgml/html/pltcl-error-handling.html60
-rw-r--r--doc/src/sgml/html/pltcl-event-trigger.html30
-rw-r--r--doc/src/sgml/html/pltcl-functions.html141
-rw-r--r--doc/src/sgml/html/pltcl-global.html45
-rw-r--r--doc/src/sgml/html/pltcl-overview.html43
-rw-r--r--doc/src/sgml/html/pltcl-procnames.html13
-rw-r--r--doc/src/sgml/html/pltcl-subtransactions.html67
-rw-r--r--doc/src/sgml/html/pltcl-transactions.html33
-rw-r--r--doc/src/sgml/html/pltcl-trigger.html115
-rw-r--r--doc/src/sgml/html/pltcl.html8
-rw-r--r--doc/src/sgml/html/populate.html206
-rw-r--r--doc/src/sgml/html/postgres-fdw.html677
-rw-r--r--doc/src/sgml/html/postgres-user.html20
-rw-r--r--doc/src/sgml/html/predefined-roles.html79
-rw-r--r--doc/src/sgml/html/preface.html47
-rw-r--r--doc/src/sgml/html/preventing-server-spoofing.html44
-rw-r--r--doc/src/sgml/html/progress-reporting.html651
-rw-r--r--doc/src/sgml/html/protocol-changes.html73
-rw-r--r--doc/src/sgml/html/protocol-error-fields.html99
-rw-r--r--doc/src/sgml/html/protocol-flow.html975
-rw-r--r--doc/src/sgml/html/protocol-logical-replication.html84
-rw-r--r--doc/src/sgml/html/protocol-logicalrep-message-formats.html307
-rw-r--r--doc/src/sgml/html/protocol-message-formats.html676
-rw-r--r--doc/src/sgml/html/protocol-message-types.html34
-rw-r--r--doc/src/sgml/html/protocol-overview.html112
-rw-r--r--doc/src/sgml/html/protocol-replication.html529
-rw-r--r--doc/src/sgml/html/protocol.html35
-rw-r--r--doc/src/sgml/html/queries-limit.html48
-rw-r--r--doc/src/sgml/html/queries-order.html76
-rw-r--r--doc/src/sgml/html/queries-overview.html53
-rw-r--r--doc/src/sgml/html/queries-select-lists.html122
-rw-r--r--doc/src/sgml/html/queries-table-expressions.html1030
-rw-r--r--doc/src/sgml/html/queries-union.html76
-rw-r--r--doc/src/sgml/html/queries-values.html60
-rw-r--r--doc/src/sgml/html/queries-with.html564
-rw-r--r--doc/src/sgml/html/queries.html6
-rw-r--r--doc/src/sgml/html/query-path.html55
-rw-r--r--doc/src/sgml/html/querytree.html152
-rw-r--r--doc/src/sgml/html/rangetypes.html435
-rw-r--r--doc/src/sgml/html/recovery-config.html31
-rw-r--r--doc/src/sgml/html/reference-client.html24
-rw-r--r--doc/src/sgml/html/reference-server.html8
-rw-r--r--doc/src/sgml/html/reference.html31
-rw-r--r--doc/src/sgml/html/regress-coverage.html43
-rw-r--r--doc/src/sgml/html/regress-evaluation.html166
-rw-r--r--doc/src/sgml/html/regress-run.html257
-rw-r--r--doc/src/sgml/html/regress-tap.html42
-rw-r--r--doc/src/sgml/html/regress-variant.html77
-rw-r--r--doc/src/sgml/html/regress.html7
-rw-r--r--doc/src/sgml/html/release-15-1.html224
-rw-r--r--doc/src/sgml/html/release-15-2.html433
-rw-r--r--doc/src/sgml/html/release-15-3.html603
-rw-r--r--doc/src/sgml/html/release-15-4.html351
-rw-r--r--doc/src/sgml/html/release-15.html1113
-rw-r--r--doc/src/sgml/html/release-prior.html5
-rw-r--r--doc/src/sgml/html/release.html21
-rw-r--r--doc/src/sgml/html/replication-origins.html68
-rw-r--r--doc/src/sgml/html/resources.html32
-rw-r--r--doc/src/sgml/html/role-attributes.html120
-rw-r--r--doc/src/sgml/html/role-membership.html107
-rw-r--r--doc/src/sgml/html/role-removal.html54
-rw-r--r--doc/src/sgml/html/routine-reindex.html31
-rw-r--r--doc/src/sgml/html/routine-vacuuming.html643
-rw-r--r--doc/src/sgml/html/row-estimation-examples.html399
-rw-r--r--doc/src/sgml/html/rowtypes.html424
-rw-r--r--doc/src/sgml/html/rule-system.html30
-rw-r--r--doc/src/sgml/html/rules-materializedviews.html182
-rw-r--r--doc/src/sgml/html/rules-privileges.html160
-rw-r--r--doc/src/sgml/html/rules-status.html35
-rw-r--r--doc/src/sgml/html/rules-triggers.html178
-rw-r--r--doc/src/sgml/html/rules-update.html750
-rw-r--r--doc/src/sgml/html/rules-views.html506
-rw-r--r--doc/src/sgml/html/rules.html21
-rw-r--r--doc/src/sgml/html/runtime-config-autovacuum.html163
-rw-r--r--doc/src/sgml/html/runtime-config-client.html854
-rw-r--r--doc/src/sgml/html/runtime-config-compatible.html143
-rw-r--r--doc/src/sgml/html/runtime-config-connection.html542
-rw-r--r--doc/src/sgml/html/runtime-config-custom.html21
-rw-r--r--doc/src/sgml/html/runtime-config-developer.html377
-rw-r--r--doc/src/sgml/html/runtime-config-error-handling.html71
-rw-r--r--doc/src/sgml/html/runtime-config-file-locations.html74
-rw-r--r--doc/src/sgml/html/runtime-config-locks.html84
-rw-r--r--doc/src/sgml/html/runtime-config-logging.html938
-rw-r--r--doc/src/sgml/html/runtime-config-preset.html152
-rw-r--r--doc/src/sgml/html/runtime-config-query.html543
-rw-r--r--doc/src/sgml/html/runtime-config-replication.html562
-rw-r--r--doc/src/sgml/html/runtime-config-resource.html713
-rw-r--r--doc/src/sgml/html/runtime-config-short.html24
-rw-r--r--doc/src/sgml/html/runtime-config-statistics.html149
-rw-r--r--doc/src/sgml/html/runtime-config-wal.html830
-rw-r--r--doc/src/sgml/html/runtime-config.html7
-rw-r--r--doc/src/sgml/html/runtime.html16
-rw-r--r--doc/src/sgml/html/sasl-authentication.html104
-rw-r--r--doc/src/sgml/html/seg.html222
-rw-r--r--doc/src/sgml/html/sepgsql.html520
-rw-r--r--doc/src/sgml/html/server-programming.html13
-rw-r--r--doc/src/sgml/html/server-shutdown.html66
-rw-r--r--doc/src/sgml/html/server-start.html259
-rw-r--r--doc/src/sgml/html/source-conventions.html106
-rw-r--r--doc/src/sgml/html/source-format.html63
-rw-r--r--doc/src/sgml/html/source.html2
-rw-r--r--doc/src/sgml/html/sourcerepo.html17
-rw-r--r--doc/src/sgml/html/spgist-builtin-opclasses.html16
-rw-r--r--doc/src/sgml/html/spgist-examples.html8
-rw-r--r--doc/src/sgml/html/spgist-extensibility.html621
-rw-r--r--doc/src/sgml/html/spgist-implementation.html90
-rw-r--r--doc/src/sgml/html/spgist-intro.html34
-rw-r--r--doc/src/sgml/html/spgist.html2
-rw-r--r--doc/src/sgml/html/spi-examples.html170
-rw-r--r--doc/src/sgml/html/spi-interface-support.html9
-rw-r--r--doc/src/sgml/html/spi-interface.html6
-rw-r--r--doc/src/sgml/html/spi-memory.html46
-rw-r--r--doc/src/sgml/html/spi-realloc.html18
-rw-r--r--doc/src/sgml/html/spi-spi-commit.html23
-rw-r--r--doc/src/sgml/html/spi-spi-connect.html28
-rw-r--r--doc/src/sgml/html/spi-spi-copytuple.html18
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-close.html13
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-fetch.html22
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-find.html13
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-move.html18
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-open-with-args.html59
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-open-with-paramlist.html30
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-open.html47
-rw-r--r--doc/src/sgml/html/spi-spi-cursor-parse-open.html47
-rw-r--r--doc/src/sgml/html/spi-spi-exec.html16
-rw-r--r--doc/src/sgml/html/spi-spi-execp.html36
-rw-r--r--doc/src/sgml/html/spi-spi-execute-extended.html68
-rw-r--r--doc/src/sgml/html/spi-spi-execute-plan-extended.html68
-rw-r--r--doc/src/sgml/html/spi-spi-execute-plan-with-paramlist.html32
-rw-r--r--doc/src/sgml/html/spi-spi-execute-plan.html47
-rw-r--r--doc/src/sgml/html/spi-spi-execute-with-args.html60
-rw-r--r--doc/src/sgml/html/spi-spi-execute.html179
-rw-r--r--doc/src/sgml/html/spi-spi-finish.html15
-rw-r--r--doc/src/sgml/html/spi-spi-fname.html17
-rw-r--r--doc/src/sgml/html/spi-spi-fnumber.html22
-rw-r--r--doc/src/sgml/html/spi-spi-freeplan.html14
-rw-r--r--doc/src/sgml/html/spi-spi-freetuple.html13
-rw-r--r--doc/src/sgml/html/spi-spi-freetupletable.html26
-rw-r--r--doc/src/sgml/html/spi-spi-getargcount.html15
-rw-r--r--doc/src/sgml/html/spi-spi-getargtypeid.html21
-rw-r--r--doc/src/sgml/html/spi-spi-getbinval.html27
-rw-r--r--doc/src/sgml/html/spi-spi-getnspname.html14
-rw-r--r--doc/src/sgml/html/spi-spi-getrelname.html12
-rw-r--r--doc/src/sgml/html/spi-spi-gettype.html16
-rw-r--r--doc/src/sgml/html/spi-spi-gettypeid.html16
-rw-r--r--doc/src/sgml/html/spi-spi-getvalue.html25
-rw-r--r--doc/src/sgml/html/spi-spi-is-cursor-plan.html27
-rw-r--r--doc/src/sgml/html/spi-spi-keepplan.html20
-rw-r--r--doc/src/sgml/html/spi-spi-modifytuple.html59
-rw-r--r--doc/src/sgml/html/spi-spi-palloc.html14
-rw-r--r--doc/src/sgml/html/spi-spi-pfree.html14
-rw-r--r--doc/src/sgml/html/spi-spi-prepare-cursor.html35
-rw-r--r--doc/src/sgml/html/spi-spi-prepare-extended.html34
-rw-r--r--doc/src/sgml/html/spi-spi-prepare-params.html27
-rw-r--r--doc/src/sgml/html/spi-spi-prepare.html84
-rw-r--r--doc/src/sgml/html/spi-spi-register-relation.html29
-rw-r--r--doc/src/sgml/html/spi-spi-register-trigger-data.html32
-rw-r--r--doc/src/sgml/html/spi-spi-result-code-string.html12
-rw-r--r--doc/src/sgml/html/spi-spi-returntuple.html26
-rw-r--r--doc/src/sgml/html/spi-spi-rollback.html20
-rw-r--r--doc/src/sgml/html/spi-spi-saveplan.html30
-rw-r--r--doc/src/sgml/html/spi-spi-scroll-cursor-fetch.html34
-rw-r--r--doc/src/sgml/html/spi-spi-scroll-cursor-move.html36
-rw-r--r--doc/src/sgml/html/spi-spi-start-transaction.html11
-rw-r--r--doc/src/sgml/html/spi-spi-unregister-relation.html27
-rw-r--r--doc/src/sgml/html/spi-transaction.html19
-rw-r--r--doc/src/sgml/html/spi-visibility.html38
-rw-r--r--doc/src/sgml/html/spi.html38
-rw-r--r--doc/src/sgml/html/sql-abort.html31
-rw-r--r--doc/src/sgml/html/sql-alteraggregate.html83
-rw-r--r--doc/src/sgml/html/sql-altercollation.html98
-rw-r--r--doc/src/sgml/html/sql-alterconversion.html39
-rw-r--r--doc/src/sgml/html/sql-alterdatabase.html112
-rw-r--r--doc/src/sgml/html/sql-alterdefaultprivileges.html159
-rw-r--r--doc/src/sgml/html/sql-alterdomain.html152
-rw-r--r--doc/src/sgml/html/sql-altereventtrigger.html25
-rw-r--r--doc/src/sgml/html/sql-alterextension.html141
-rw-r--r--doc/src/sgml/html/sql-alterforeigndatawrapper.html68
-rw-r--r--doc/src/sgml/html/sql-alterforeigntable.html236
-rw-r--r--doc/src/sgml/html/sql-alterfunction.html174
-rw-r--r--doc/src/sgml/html/sql-altergroup.html53
-rw-r--r--doc/src/sgml/html/sql-alterindex.html138
-rw-r--r--doc/src/sgml/html/sql-alterlanguage.html19
-rw-r--r--doc/src/sgml/html/sql-alterlargeobject.html20
-rw-r--r--doc/src/sgml/html/sql-altermaterializedview.html75
-rw-r--r--doc/src/sgml/html/sql-alteropclass.html36
-rw-r--r--doc/src/sgml/html/sql-alteroperator.html49
-rw-r--r--doc/src/sgml/html/sql-alteropfamily.html181
-rw-r--r--doc/src/sgml/html/sql-alterpolicy.html45
-rw-r--r--doc/src/sgml/html/sql-alterprocedure.html133
-rw-r--r--doc/src/sgml/html/sql-alterpublication.html112
-rw-r--r--doc/src/sgml/html/sql-alterrole.html189
-rw-r--r--doc/src/sgml/html/sql-alterroutine.html49
-rw-r--r--doc/src/sgml/html/sql-alterrule.html25
-rw-r--r--doc/src/sgml/html/sql-alterschema.html26
-rw-r--r--doc/src/sgml/html/sql-altersequence.html165
-rw-r--r--doc/src/sgml/html/sql-alterserver.html48
-rw-r--r--doc/src/sgml/html/sql-alterstatistics.html46
-rw-r--r--doc/src/sgml/html/sql-altersubscription.html147
-rw-r--r--doc/src/sgml/html/sql-altersystem.html59
-rw-r--r--doc/src/sgml/html/sql-altertable.html1094
-rw-r--r--doc/src/sgml/html/sql-altertablespace.html50
-rw-r--r--doc/src/sgml/html/sql-altertrigger.html49
-rw-r--r--doc/src/sgml/html/sql-altertsconfig.html68
-rw-r--r--doc/src/sgml/html/sql-altertsdictionary.html60
-rw-r--r--doc/src/sgml/html/sql-altertsparser.html20
-rw-r--r--doc/src/sgml/html/sql-altertstemplate.html20
-rw-r--r--doc/src/sgml/html/sql-altertype.html226
-rw-r--r--doc/src/sgml/html/sql-alteruser.html38
-rw-r--r--doc/src/sgml/html/sql-alterusermapping.html43
-rw-r--r--doc/src/sgml/html/sql-alterview.html80
-rw-r--r--doc/src/sgml/html/sql-analyze.html187
-rw-r--r--doc/src/sgml/html/sql-begin.html71
-rw-r--r--doc/src/sgml/html/sql-call.html47
-rw-r--r--doc/src/sgml/html/sql-checkpoint.html28
-rw-r--r--doc/src/sgml/html/sql-close.html42
-rw-r--r--doc/src/sgml/html/sql-cluster.html137
-rw-r--r--doc/src/sgml/html/sql-commands.html19
-rw-r--r--doc/src/sgml/html/sql-comment.html198
-rw-r--r--doc/src/sgml/html/sql-commit-prepared.html33
-rw-r--r--doc/src/sgml/html/sql-commit.html28
-rw-r--r--doc/src/sgml/html/sql-copy.html641
-rw-r--r--doc/src/sgml/html/sql-create-access-method.html39
-rw-r--r--doc/src/sgml/html/sql-createaggregate.html510
-rw-r--r--doc/src/sgml/html/sql-createcast.html256
-rw-r--r--doc/src/sgml/html/sql-createcollation.html109
-rw-r--r--doc/src/sgml/html/sql-createconversion.html72
-rw-r--r--doc/src/sgml/html/sql-createdatabase.html240
-rw-r--r--doc/src/sgml/html/sql-createdomain.html148
-rw-r--r--doc/src/sgml/html/sql-createeventtrigger.html65
-rw-r--r--doc/src/sgml/html/sql-createextension.html128
-rw-r--r--doc/src/sgml/html/sql-createforeigndatawrapper.html77
-rw-r--r--doc/src/sgml/html/sql-createforeigntable.html244
-rw-r--r--doc/src/sgml/html/sql-createfunction.html554
-rw-r--r--doc/src/sgml/html/sql-creategroup.html29
-rw-r--r--doc/src/sgml/html/sql-createindex.html580
-rw-r--r--doc/src/sgml/html/sql-createlanguage.html120
-rw-r--r--doc/src/sgml/html/sql-creatematerializedview.html71
-rw-r--r--doc/src/sgml/html/sql-createopclass.html152
-rw-r--r--doc/src/sgml/html/sql-createoperator.html135
-rw-r--r--doc/src/sgml/html/sql-createopfamily.html43
-rw-r--r--doc/src/sgml/html/sql-createpolicy.html361
-rw-r--r--doc/src/sgml/html/sql-createprocedure.html208
-rw-r--r--doc/src/sgml/html/sql-createpublication.html232
-rw-r--r--doc/src/sgml/html/sql-createrole.html269
-rw-r--r--doc/src/sgml/html/sql-createrule.html174
-rw-r--r--doc/src/sgml/html/sql-createschema.html118
-rw-r--r--doc/src/sgml/html/sql-createsequence.html214
-rw-r--r--doc/src/sgml/html/sql-createserver.html53
-rw-r--r--doc/src/sgml/html/sql-createstatistics.html210
-rw-r--r--doc/src/sgml/html/sql-createsubscription.html217
-rw-r--r--doc/src/sgml/html/sql-createtable.html1470
-rw-r--r--doc/src/sgml/html/sql-createtableas.html148
-rw-r--r--doc/src/sgml/html/sql-createtablespace.html80
-rw-r--r--doc/src/sgml/html/sql-createtransform.html106
-rw-r--r--doc/src/sgml/html/sql-createtrigger.html461
-rw-r--r--doc/src/sgml/html/sql-createtsconfig.html40
-rw-r--r--doc/src/sgml/html/sql-createtsdictionary.html47
-rw-r--r--doc/src/sgml/html/sql-createtsparser.html51
-rw-r--r--doc/src/sgml/html/sql-createtstemplate.html45
-rw-r--r--doc/src/sgml/html/sql-createtype.html655
-rw-r--r--doc/src/sgml/html/sql-createuser.html35
-rw-r--r--doc/src/sgml/html/sql-createusermapping.html42
-rw-r--r--doc/src/sgml/html/sql-createview.html346
-rw-r--r--doc/src/sgml/html/sql-deallocate.html19
-rw-r--r--doc/src/sgml/html/sql-declare.html200
-rw-r--r--doc/src/sgml/html/sql-delete.html145
-rw-r--r--doc/src/sgml/html/sql-discard.html41
-rw-r--r--doc/src/sgml/html/sql-do.html49
-rw-r--r--doc/src/sgml/html/sql-drop-access-method.html27
-rw-r--r--doc/src/sgml/html/sql-drop-owned.html41
-rw-r--r--doc/src/sgml/html/sql-dropaggregate.html65
-rw-r--r--doc/src/sgml/html/sql-dropcast.html26
-rw-r--r--doc/src/sgml/html/sql-dropcollation.html28
-rw-r--r--doc/src/sgml/html/sql-dropconversion.html26
-rw-r--r--doc/src/sgml/html/sql-dropdatabase.html44
-rw-r--r--doc/src/sgml/html/sql-dropdomain.html29
-rw-r--r--doc/src/sgml/html/sql-dropeventtrigger.html28
-rw-r--r--doc/src/sgml/html/sql-dropextension.html38
-rw-r--r--doc/src/sgml/html/sql-dropforeigndatawrapper.html29
-rw-r--r--doc/src/sgml/html/sql-dropforeigntable.html30
-rw-r--r--doc/src/sgml/html/sql-dropfunction.html67
-rw-r--r--doc/src/sgml/html/sql-dropgroup.html9
-rw-r--r--doc/src/sgml/html/sql-dropindex.html50
-rw-r--r--doc/src/sgml/html/sql-droplanguage.html35
-rw-r--r--doc/src/sgml/html/sql-dropmaterializedview.html30
-rw-r--r--doc/src/sgml/html/sql-dropopclass.html47
-rw-r--r--doc/src/sgml/html/sql-dropoperator.html42
-rw-r--r--doc/src/sgml/html/sql-dropopfamily.html40
-rw-r--r--doc/src/sgml/html/sql-droppolicy.html30
-rw-r--r--doc/src/sgml/html/sql-dropprocedure.html96
-rw-r--r--doc/src/sgml/html/sql-droppublication.html24
-rw-r--r--doc/src/sgml/html/sql-droprole.html41
-rw-r--r--doc/src/sgml/html/sql-droproutine.html45
-rw-r--r--doc/src/sgml/html/sql-droprule.html30
-rw-r--r--doc/src/sgml/html/sql-dropschema.html38
-rw-r--r--doc/src/sgml/html/sql-dropsequence.html30
-rw-r--r--doc/src/sgml/html/sql-dropserver.html29
-rw-r--r--doc/src/sgml/html/sql-dropstatistics.html26
-rw-r--r--doc/src/sgml/html/sql-dropsubscription.html49
-rw-r--r--doc/src/sgml/html/sql-droptable.html42
-rw-r--r--doc/src/sgml/html/sql-droptablespace.html28
-rw-r--r--doc/src/sgml/html/sql-droptransform.html31
-rw-r--r--doc/src/sgml/html/sql-droptrigger.html35
-rw-r--r--doc/src/sgml/html/sql-droptsconfig.html35
-rw-r--r--doc/src/sgml/html/sql-droptsdictionary.html34
-rw-r--r--doc/src/sgml/html/sql-droptsparser.html32
-rw-r--r--doc/src/sgml/html/sql-droptstemplate.html33
-rw-r--r--doc/src/sgml/html/sql-droptype.html31
-rw-r--r--doc/src/sgml/html/sql-dropuser.html11
-rw-r--r--doc/src/sgml/html/sql-dropusermapping.html30
-rw-r--r--doc/src/sgml/html/sql-dropview.html29
-rw-r--r--doc/src/sgml/html/sql-end.html30
-rw-r--r--doc/src/sgml/html/sql-execute.html38
-rw-r--r--doc/src/sgml/html/sql-explain.html306
-rw-r--r--doc/src/sgml/html/sql-expressions.html995
-rw-r--r--doc/src/sgml/html/sql-fetch.html190
-rw-r--r--doc/src/sgml/html/sql-grant.html318
-rw-r--r--doc/src/sgml/html/sql-importforeignschema.html60
-rw-r--r--doc/src/sgml/html/sql-insert.html488
-rw-r--r--doc/src/sgml/html/sql-keywords-appendix.html63
-rw-r--r--doc/src/sgml/html/sql-listen.html70
-rw-r--r--doc/src/sgml/html/sql-load.html31
-rw-r--r--doc/src/sgml/html/sql-lock.html167
-rw-r--r--doc/src/sgml/html/sql-merge.html380
-rw-r--r--doc/src/sgml/html/sql-move.html59
-rw-r--r--doc/src/sgml/html/sql-notify.html132
-rw-r--r--doc/src/sgml/html/sql-prepare-transaction.html90
-rw-r--r--doc/src/sgml/html/sql-prepare.html151
-rw-r--r--doc/src/sgml/html/sql-reassign-owned.html42
-rw-r--r--doc/src/sgml/html/sql-refreshmaterializedview.html59
-rw-r--r--doc/src/sgml/html/sql-reindex.html327
-rw-r--r--doc/src/sgml/html/sql-release-savepoint.html45
-rw-r--r--doc/src/sgml/html/sql-reset.html39
-rw-r--r--doc/src/sgml/html/sql-revoke.html249
-rw-r--r--doc/src/sgml/html/sql-rollback-prepared.html33
-rw-r--r--doc/src/sgml/html/sql-rollback-to.html71
-rw-r--r--doc/src/sgml/html/sql-rollback.html27
-rw-r--r--doc/src/sgml/html/sql-savepoint.html79
-rw-r--r--doc/src/sgml/html/sql-security-label.html101
-rw-r--r--doc/src/sgml/html/sql-select.html1603
-rw-r--r--doc/src/sgml/html/sql-selectinto.html68
-rw-r--r--doc/src/sgml/html/sql-set-constraints.html71
-rw-r--r--doc/src/sgml/html/sql-set-role.html85
-rw-r--r--doc/src/sgml/html/sql-set-session-authorization.html64
-rw-r--r--doc/src/sgml/html/sql-set-transaction.html179
-rw-r--r--doc/src/sgml/html/sql-set.html155
-rw-r--r--doc/src/sgml/html/sql-show.html82
-rw-r--r--doc/src/sgml/html/sql-start-transaction.html37
-rw-r--r--doc/src/sgml/html/sql-syntax-calling-funcs.html132
-rw-r--r--doc/src/sgml/html/sql-syntax-lexical.html647
-rw-r--r--doc/src/sgml/html/sql-syntax.html11
-rw-r--r--doc/src/sgml/html/sql-truncate.html119
-rw-r--r--doc/src/sgml/html/sql-unlisten.html48
-rw-r--r--doc/src/sgml/html/sql-update.html290
-rw-r--r--doc/src/sgml/html/sql-vacuum.html258
-rw-r--r--doc/src/sgml/html/sql-values.html138
-rw-r--r--doc/src/sgml/html/sql.html30
-rw-r--r--doc/src/sgml/html/ssh-tunnels.html76
-rw-r--r--doc/src/sgml/html/ssl-tcp.html264
-rw-r--r--doc/src/sgml/html/sslinfo.html135
-rw-r--r--doc/src/sgml/html/sspi-auth.html68
-rw-r--r--doc/src/sgml/html/storage-file-layout.html133
-rw-r--r--doc/src/sgml/html/storage-fsm.html26
-rw-r--r--doc/src/sgml/html/storage-hot.html45
-rw-r--r--doc/src/sgml/html/storage-init.html8
-rw-r--r--doc/src/sgml/html/storage-page-layout.html157
-rw-r--r--doc/src/sgml/html/storage-toast.html225
-rw-r--r--doc/src/sgml/html/storage-vm.html29
-rw-r--r--doc/src/sgml/html/storage.html5
-rw-r--r--doc/src/sgml/html/stylesheet.css165
-rw-r--r--doc/src/sgml/html/supported-platforms.html39
-rw-r--r--doc/src/sgml/html/system-catalog-declarations.html74
-rw-r--r--doc/src/sgml/html/system-catalog-initial-data.html404
-rw-r--r--doc/src/sgml/html/tableam.html72
-rw-r--r--doc/src/sgml/html/tablefunc.html613
-rw-r--r--doc/src/sgml/html/tablesample-method.html57
-rw-r--r--doc/src/sgml/html/tablesample-support-functions.html163
-rw-r--r--doc/src/sgml/html/tcn.html55
-rw-r--r--doc/src/sgml/html/test-decoding.html48
-rw-r--r--doc/src/sgml/html/textsearch-configuration.html108
-rw-r--r--doc/src/sgml/html/textsearch-controls.html550
-rw-r--r--doc/src/sgml/html/textsearch-debugging.html253
-rw-r--r--doc/src/sgml/html/textsearch-dictionaries.html661
-rw-r--r--doc/src/sgml/html/textsearch-features.html392
-rw-r--r--doc/src/sgml/html/textsearch-indexes.html80
-rw-r--r--doc/src/sgml/html/textsearch-intro.html339
-rw-r--r--doc/src/sgml/html/textsearch-limitations.html21
-rw-r--r--doc/src/sgml/html/textsearch-parsers.html59
-rw-r--r--doc/src/sgml/html/textsearch-psql.html165
-rw-r--r--doc/src/sgml/html/textsearch-tables.html139
-rw-r--r--doc/src/sgml/html/textsearch.html2
-rw-r--r--doc/src/sgml/html/transaction-iso.html540
-rw-r--r--doc/src/sgml/html/trigger-datachanges.html46
-rw-r--r--doc/src/sgml/html/trigger-definition.html315
-rw-r--r--doc/src/sgml/html/trigger-example.html180
-rw-r--r--doc/src/sgml/html/trigger-interface.html184
-rw-r--r--doc/src/sgml/html/triggers.html18
-rw-r--r--doc/src/sgml/html/tsm-system-rows.html39
-rw-r--r--doc/src/sgml/html/tsm-system-time.html41
-rw-r--r--doc/src/sgml/html/tutorial-accessdb.html103
-rw-r--r--doc/src/sgml/html/tutorial-advanced-intro.html18
-rw-r--r--doc/src/sgml/html/tutorial-advanced.html2
-rw-r--r--doc/src/sgml/html/tutorial-agg.html172
-rw-r--r--doc/src/sgml/html/tutorial-arch.html49
-rw-r--r--doc/src/sgml/html/tutorial-concepts.html37
-rw-r--r--doc/src/sgml/html/tutorial-conclusion.html12
-rw-r--r--doc/src/sgml/html/tutorial-createdb.html118
-rw-r--r--doc/src/sgml/html/tutorial-delete.html34
-rw-r--r--doc/src/sgml/html/tutorial-fk.html51
-rw-r--r--doc/src/sgml/html/tutorial-inheritance.html113
-rw-r--r--doc/src/sgml/html/tutorial-install.html38
-rw-r--r--doc/src/sgml/html/tutorial-join.html162
-rw-r--r--doc/src/sgml/html/tutorial-populate.html59
-rw-r--r--doc/src/sgml/html/tutorial-select.html142
-rw-r--r--doc/src/sgml/html/tutorial-sql-intro.html43
-rw-r--r--doc/src/sgml/html/tutorial-sql.html2
-rw-r--r--doc/src/sgml/html/tutorial-start.html2
-rw-r--r--doc/src/sgml/html/tutorial-table.html69
-rw-r--r--doc/src/sgml/html/tutorial-transactions.html142
-rw-r--r--doc/src/sgml/html/tutorial-update.html26
-rw-r--r--doc/src/sgml/html/tutorial-views.html26
-rw-r--r--doc/src/sgml/html/tutorial-window.html202
-rw-r--r--doc/src/sgml/html/tutorial.html20
-rw-r--r--doc/src/sgml/html/typeconv-func.html268
-rw-r--r--doc/src/sgml/html/typeconv-oper.html247
-rw-r--r--doc/src/sgml/html/typeconv-overview.html113
-rw-r--r--doc/src/sgml/html/typeconv-query.html55
-rw-r--r--doc/src/sgml/html/typeconv-select.html30
-rw-r--r--doc/src/sgml/html/typeconv-union-case.html114
-rw-r--r--doc/src/sgml/html/typeconv.html19
-rw-r--r--doc/src/sgml/html/unaccent.html131
-rw-r--r--doc/src/sgml/html/unsupported-features-sql-standard.html9
-rw-r--r--doc/src/sgml/html/upgrading.html195
-rw-r--r--doc/src/sgml/html/user-manag.html20
-rw-r--r--doc/src/sgml/html/using-explain.html804
-rw-r--r--doc/src/sgml/html/uuid-ossp.html144
-rw-r--r--doc/src/sgml/html/vacuumlo.html74
-rw-r--r--doc/src/sgml/html/view-pg-available-extension-versions.html65
-rw-r--r--doc/src/sgml/html/view-pg-available-extensions.html37
-rw-r--r--doc/src/sgml/html/view-pg-backend-memory-contexts.html62
-rw-r--r--doc/src/sgml/html/view-pg-config.html29
-rw-r--r--doc/src/sgml/html/view-pg-cursors.html72
-rw-r--r--doc/src/sgml/html/view-pg-file-settings.html77
-rw-r--r--doc/src/sgml/html/view-pg-group.html32
-rw-r--r--doc/src/sgml/html/view-pg-hba-file-rules.html76
-rw-r--r--doc/src/sgml/html/view-pg-ident-file-mappings.html53
-rw-r--r--doc/src/sgml/html/view-pg-indexes.html40
-rw-r--r--doc/src/sgml/html/view-pg-locks.html255
-rw-r--r--doc/src/sgml/html/view-pg-matviews.html49
-rw-r--r--doc/src/sgml/html/view-pg-policies.html55
-rw-r--r--doc/src/sgml/html/view-pg-prepared-statements.html65
-rw-r--r--doc/src/sgml/html/view-pg-prepared-xacts.html50
-rw-r--r--doc/src/sgml/html/view-pg-publication-tables.html46
-rw-r--r--doc/src/sgml/html/view-pg-replication-origin-status.html36
-rw-r--r--doc/src/sgml/html/view-pg-replication-slots.html131
-rw-r--r--doc/src/sgml/html/view-pg-roles.html85
-rw-r--r--doc/src/sgml/html/view-pg-rules.html37
-rw-r--r--doc/src/sgml/html/view-pg-seclabels.html60
-rw-r--r--doc/src/sgml/html/view-pg-sequences.html74
-rw-r--r--doc/src/sgml/html/view-pg-settings.html201
-rw-r--r--doc/src/sgml/html/view-pg-shadow.html71
-rw-r--r--doc/src/sgml/html/view-pg-shmem-allocations.html52
-rw-r--r--doc/src/sgml/html/view-pg-stats-ext-exprs.html147
-rw-r--r--doc/src/sgml/html/view-pg-stats-ext.html124
-rw-r--r--doc/src/sgml/html/view-pg-stats.html128
-rw-r--r--doc/src/sgml/html/view-pg-tables.html58
-rw-r--r--doc/src/sgml/html/view-pg-timezone-abbrevs.html32
-rw-r--r--doc/src/sgml/html/view-pg-timezone-names.html38
-rw-r--r--doc/src/sgml/html/view-pg-user-mappings.html60
-rw-r--r--doc/src/sgml/html/view-pg-user.html60
-rw-r--r--doc/src/sgml/html/view-pg-views.html33
-rw-r--r--doc/src/sgml/html/views-overview.html6
-rw-r--r--doc/src/sgml/html/views.html20
-rw-r--r--doc/src/sgml/html/wal-async-commit.html99
-rw-r--r--doc/src/sgml/html/wal-configuration.html295
-rw-r--r--doc/src/sgml/html/wal-internals.html70
-rw-r--r--doc/src/sgml/html/wal-intro.html48
-rw-r--r--doc/src/sgml/html/wal-reliability.html161
-rw-r--r--doc/src/sgml/html/wal.html5
-rw-r--r--doc/src/sgml/html/warm-standby-failover.html65
-rw-r--r--doc/src/sgml/html/warm-standby.html657
-rw-r--r--doc/src/sgml/html/when-can-parallel-query-be-used.html78
-rw-r--r--doc/src/sgml/html/xaggr.html528
-rw-r--r--doc/src/sgml/html/xfunc-c.html1387
-rw-r--r--doc/src/sgml/html/xfunc-internal.html31
-rw-r--r--doc/src/sgml/html/xfunc-optimization.html94
-rw-r--r--doc/src/sgml/html/xfunc-overload.html67
-rw-r--r--doc/src/sgml/html/xfunc-pl.html12
-rw-r--r--doc/src/sgml/html/xfunc-sql.html1123
-rw-r--r--doc/src/sgml/html/xfunc-volatility.html107
-rw-r--r--doc/src/sgml/html/xfunc.html43
-rw-r--r--doc/src/sgml/html/xindex.html772
-rw-r--r--doc/src/sgml/html/xml-limits-conformance.html204
-rw-r--r--doc/src/sgml/html/xml2.html274
-rw-r--r--doc/src/sgml/html/xoper-optimization.html281
-rw-r--r--doc/src/sgml/html/xoper.html58
-rw-r--r--doc/src/sgml/html/xplang-install.html142
-rw-r--r--doc/src/sgml/html/xplang.html29
-rw-r--r--doc/src/sgml/html/xproc.html41
-rw-r--r--doc/src/sgml/html/xtypes.html302
-rw-r--r--doc/src/sgml/images/Makefile27
-rw-r--r--doc/src/sgml/images/README65
-rw-r--r--doc/src/sgml/images/fixup-svg.xsl44
-rw-r--r--doc/src/sgml/images/genetic-algorithm.gv48
-rw-r--r--doc/src/sgml/images/genetic-algorithm.svg140
-rw-r--r--doc/src/sgml/images/gin.gv93
-rw-r--r--doc/src/sgml/images/gin.svg317
-rw-r--r--doc/src/sgml/images/pagelayout.svg35
-rw-r--r--doc/src/sgml/images/pagelayout.txt11
-rw-r--r--doc/src/sgml/indexam.sgml1486
-rw-r--r--doc/src/sgml/indices.sgml1605
-rw-r--r--doc/src/sgml/info.sgml69
-rw-r--r--doc/src/sgml/information_schema.sgml8680
-rw-r--r--doc/src/sgml/install-binaries.sgml24
-rw-r--r--doc/src/sgml/install-windows.sgml573
-rw-r--r--doc/src/sgml/installation.sgml2637
-rw-r--r--doc/src/sgml/intagg.sgml131
-rw-r--r--doc/src/sgml/intarray.sgml503
-rw-r--r--doc/src/sgml/intro.sgml161
-rw-r--r--doc/src/sgml/isn.sgml424
-rw-r--r--doc/src/sgml/jit.sgml285
-rw-r--r--doc/src/sgml/json.sgml1013
-rw-r--r--doc/src/sgml/keywords.sgml90
-rw-r--r--doc/src/sgml/keywords/sql1992-nonreserved.txt50
-rw-r--r--doc/src/sgml/keywords/sql1992-reserved.txt227
-rw-r--r--doc/src/sgml/keywords/sql2011-02-nonreserved.txt219
-rw-r--r--doc/src/sgml/keywords/sql2011-02-reserved.txt324
-rw-r--r--doc/src/sgml/keywords/sql2011-09-nonreserved.txt23
-rw-r--r--doc/src/sgml/keywords/sql2011-09-reserved.txt13
-rw-r--r--doc/src/sgml/keywords/sql2011-14-nonreserved.txt29
-rw-r--r--doc/src/sgml/keywords/sql2011-14-reserved.txt20
-rw-r--r--doc/src/sgml/keywords/sql2016-02-nonreserved.txt256
-rw-r--r--doc/src/sgml/keywords/sql2016-02-reserved.txt368
-rw-r--r--doc/src/sgml/keywords/sql2016-09-nonreserved.txt23
-rw-r--r--doc/src/sgml/keywords/sql2016-09-reserved.txt13
-rw-r--r--doc/src/sgml/keywords/sql2016-14-nonreserved.txt27
-rw-r--r--doc/src/sgml/keywords/sql2016-14-reserved.txt20
-rw-r--r--doc/src/sgml/legal.sgml48
-rw-r--r--doc/src/sgml/libpq.sgml9573
-rw-r--r--doc/src/sgml/limits.sgml126
-rw-r--r--doc/src/sgml/lo.sgml136
-rw-r--r--doc/src/sgml/lobj.sgml996
-rw-r--r--doc/src/sgml/logical-replication.sgml1677
-rw-r--r--doc/src/sgml/logicaldecoding.sgml1355
-rw-r--r--doc/src/sgml/ltree.sgml858
-rw-r--r--doc/src/sgml/maintenance.sgml1116
-rw-r--r--doc/src/sgml/man-stamp0
-rw-r--r--doc/src/sgml/man1/clusterdb.1252
-rw-r--r--doc/src/sgml/man1/createdb.1310
-rw-r--r--doc/src/sgml/man1/createuser.1388
-rw-r--r--doc/src/sgml/man1/dropdb.1233
-rw-r--r--doc/src/sgml/man1/dropuser.1222
-rw-r--r--doc/src/sgml/man1/ecpg.1208
-rw-r--r--doc/src/sgml/man1/initdb.1415
-rw-r--r--doc/src/sgml/man1/oid2name.1379
-rw-r--r--doc/src/sgml/man1/pg_amcheck.1462
-rw-r--r--doc/src/sgml/man1/pg_archivecleanup.1207
-rw-r--r--doc/src/sgml/man1/pg_basebackup.1756
-rw-r--r--doc/src/sgml/man1/pg_checksums.1156
-rw-r--r--doc/src/sgml/man1/pg_config.1257
-rw-r--r--doc/src/sgml/man1/pg_controldata.165
-rw-r--r--doc/src/sgml/man1/pg_ctl.1537
-rw-r--r--doc/src/sgml/man1/pg_dump.11239
-rw-r--r--doc/src/sgml/man1/pg_dumpall.1581
-rw-r--r--doc/src/sgml/man1/pg_isready.1191
-rw-r--r--doc/src/sgml/man1/pg_receivewal.1419
-rw-r--r--doc/src/sgml/man1/pg_recvlogical.1328
-rw-r--r--doc/src/sgml/man1/pg_resetwal.1287
-rw-r--r--doc/src/sgml/man1/pg_restore.1873
-rw-r--r--doc/src/sgml/man1/pg_rewind.1357
-rw-r--r--doc/src/sgml/man1/pg_test_fsync.1100
-rw-r--r--doc/src/sgml/man1/pg_test_timing.1208
-rw-r--r--doc/src/sgml/man1/pg_upgrade.1944
-rw-r--r--doc/src/sgml/man1/pg_verifybackup.1217
-rw-r--r--doc/src/sgml/man1/pg_waldump.1239
-rw-r--r--doc/src/sgml/man1/pgbench.12897
-rw-r--r--doc/src/sgml/man1/postgres.1631
-rw-r--r--doc/src/sgml/man1/postmaster.142
-rw-r--r--doc/src/sgml/man1/psql.14515
-rw-r--r--doc/src/sgml/man1/reindexdb.1330
-rw-r--r--doc/src/sgml/man1/vacuumdb.1584
-rw-r--r--doc/src/sgml/man1/vacuumlo.1190
-rw-r--r--doc/src/sgml/man3/SPI_commit.352
-rw-r--r--doc/src/sgml/man3/SPI_commit_and_chain.31
-rw-r--r--doc/src/sgml/man3/SPI_connect.369
-rw-r--r--doc/src/sgml/man3/SPI_connect_ext.31
-rw-r--r--doc/src/sgml/man3/SPI_copytuple.360
-rw-r--r--doc/src/sgml/man3/SPI_cursor_close.350
-rw-r--r--doc/src/sgml/man3/SPI_cursor_fetch.373
-rw-r--r--doc/src/sgml/man3/SPI_cursor_find.351
-rw-r--r--doc/src/sgml/man3/SPI_cursor_move.365
-rw-r--r--doc/src/sgml/man3/SPI_cursor_open.3102
-rw-r--r--doc/src/sgml/man3/SPI_cursor_open_with_args.3130
-rw-r--r--doc/src/sgml/man3/SPI_cursor_open_with_paramlist.380
-rw-r--r--doc/src/sgml/man3/SPI_cursor_parse_open.3104
-rw-r--r--doc/src/sgml/man3/SPI_exec.361
-rw-r--r--doc/src/sgml/man3/SPI_execp.399
-rw-r--r--doc/src/sgml/man3/SPI_execute.3344
-rw-r--r--doc/src/sgml/man3/SPI_execute_extended.3144
-rw-r--r--doc/src/sgml/man3/SPI_execute_plan.3131
-rw-r--r--doc/src/sgml/man3/SPI_execute_plan_extended.3138
-rw-r--r--doc/src/sgml/man3/SPI_execute_plan_with_paramlist.388
-rw-r--r--doc/src/sgml/man3/SPI_execute_with_args.3133
-rw-r--r--doc/src/sgml/man3/SPI_finish.352
-rw-r--r--doc/src/sgml/man3/SPI_fname.364
-rw-r--r--doc/src/sgml/man3/SPI_fnumber.363
-rw-r--r--doc/src/sgml/man3/SPI_freeplan.360
-rw-r--r--doc/src/sgml/man3/SPI_freetuple.349
-rw-r--r--doc/src/sgml/man3/SPI_freetuptable.358
-rw-r--r--doc/src/sgml/man3/SPI_getargcount.360
-rw-r--r--doc/src/sgml/man3/SPI_getargtypeid.370
-rw-r--r--doc/src/sgml/man3/SPI_getbinval.375
-rw-r--r--doc/src/sgml/man3/SPI_getnspname.353
-rw-r--r--doc/src/sgml/man3/SPI_getrelname.351
-rw-r--r--doc/src/sgml/man3/SPI_gettype.362
-rw-r--r--doc/src/sgml/man3/SPI_gettypeid.363
-rw-r--r--doc/src/sgml/man3/SPI_getvalue.372
-rw-r--r--doc/src/sgml/man3/SPI_is_cursor_plan.382
-rw-r--r--doc/src/sgml/man3/SPI_keepplan.363
-rw-r--r--doc/src/sgml/man3/SPI_modifytuple.3143
-rw-r--r--doc/src/sgml/man3/SPI_palloc.351
-rw-r--r--doc/src/sgml/man3/SPI_pfree.352
-rw-r--r--doc/src/sgml/man3/SPI_prepare.3134
-rw-r--r--doc/src/sgml/man3/SPI_prepare_cursor.394
-rw-r--r--doc/src/sgml/man3/SPI_prepare_extended.387
-rw-r--r--doc/src/sgml/man3/SPI_prepare_params.374
-rw-r--r--doc/src/sgml/man3/SPI_register_relation.382
-rw-r--r--doc/src/sgml/man3/SPI_register_trigger_data.381
-rw-r--r--doc/src/sgml/man3/SPI_repalloc.358
-rw-r--r--doc/src/sgml/man3/SPI_result_code_string.350
-rw-r--r--doc/src/sgml/man3/SPI_returntuple.373
-rw-r--r--doc/src/sgml/man3/SPI_rollback.352
-rw-r--r--doc/src/sgml/man3/SPI_rollback_and_chain.31
-rw-r--r--doc/src/sgml/man3/SPI_saveplan.380
-rw-r--r--doc/src/sgml/man3/SPI_scroll_cursor_fetch.391
-rw-r--r--doc/src/sgml/man3/SPI_scroll_cursor_move.392
-rw-r--r--doc/src/sgml/man3/SPI_start_transaction.345
-rw-r--r--doc/src/sgml/man3/SPI_unregister_relation.376
-rw-r--r--doc/src/sgml/man3/dblink.3212
-rw-r--r--doc/src/sgml/man3/dblink_build_sql_delete.399
-rw-r--r--doc/src/sgml/man3/dblink_build_sql_insert.3105
-rw-r--r--doc/src/sgml/man3/dblink_build_sql_update.3109
-rw-r--r--doc/src/sgml/man3/dblink_cancel_query.363
-rw-r--r--doc/src/sgml/man3/dblink_close.3100
-rw-r--r--doc/src/sgml/man3/dblink_connect.3155
-rw-r--r--doc/src/sgml/man3/dblink_connect_u.362
-rw-r--r--doc/src/sgml/man3/dblink_disconnect.374
-rw-r--r--doc/src/sgml/man3/dblink_error_message.371
-rw-r--r--doc/src/sgml/man3/dblink_exec.3117
-rw-r--r--doc/src/sgml/man3/dblink_fetch.3129
-rw-r--r--doc/src/sgml/man3/dblink_get_connections.356
-rw-r--r--doc/src/sgml/man3/dblink_get_notify.386
-rw-r--r--doc/src/sgml/man3/dblink_get_pkey.393
-rw-r--r--doc/src/sgml/man3/dblink_get_result.3143
-rw-r--r--doc/src/sgml/man3/dblink_is_busy.362
-rw-r--r--doc/src/sgml/man3/dblink_open.3113
-rw-r--r--doc/src/sgml/man3/dblink_send_query.371
-rw-r--r--doc/src/sgml/man7/ABORT.790
-rw-r--r--doc/src/sgml/man7/ALTER_AGGREGATE.7187
-rw-r--r--doc/src/sgml/man7/ALTER_COLLATION.7178
-rw-r--r--doc/src/sgml/man7/ALTER_CONVERSION.7106
-rw-r--r--doc/src/sgml/man7/ALTER_DATABASE.7176
-rw-r--r--doc/src/sgml/man7/ALTER_DEFAULT_PRIVILEGES.7227
-rw-r--r--doc/src/sgml/man7/ALTER_DOMAIN.7293
-rw-r--r--doc/src/sgml/man7/ALTER_EVENT_TRIGGER.774
-rw-r--r--doc/src/sgml/man7/ALTER_EXTENSION.7260
-rw-r--r--doc/src/sgml/man7/ALTER_FOREIGN_DATA_WRAPPER.7144
-rw-r--r--doc/src/sgml/man7/ALTER_FOREIGN_TABLE.7377
-rw-r--r--doc/src/sgml/man7/ALTER_FUNCTION.7348
-rw-r--r--doc/src/sgml/man7/ALTER_GROUP.7113
-rw-r--r--doc/src/sgml/man7/ALTER_INDEX.7237
-rw-r--r--doc/src/sgml/man7/ALTER_LANGUAGE.765
-rw-r--r--doc/src/sgml/man7/ALTER_LARGE_OBJECT.761
-rw-r--r--doc/src/sgml/man7/ALTER_MATERIALIZED_VIEW.7142
-rw-r--r--doc/src/sgml/man7/ALTER_OPERATOR.7130
-rw-r--r--doc/src/sgml/man7/ALTER_OPERATOR_CLASS.785
-rw-r--r--doc/src/sgml/man7/ALTER_OPERATOR_FAMILY.7259
-rw-r--r--doc/src/sgml/man7/ALTER_POLICY.7108
-rw-r--r--doc/src/sgml/man7/ALTER_PROCEDURE.7263
-rw-r--r--doc/src/sgml/man7/ALTER_PUBLICATION.7221
-rw-r--r--doc/src/sgml/man7/ALTER_ROLE.7335
-rw-r--r--doc/src/sgml/man7/ALTER_ROUTINE.7105
-rw-r--r--doc/src/sgml/man7/ALTER_RULE.780
-rw-r--r--doc/src/sgml/man7/ALTER_SCHEMA.772
-rw-r--r--doc/src/sgml/man7/ALTER_SEQUENCE.7282
-rw-r--r--doc/src/sgml/man7/ALTER_SERVER.7118
-rw-r--r--doc/src/sgml/man7/ALTER_STATISTICS.791
-rw-r--r--doc/src/sgml/man7/ALTER_SUBSCRIPTION.7235
-rw-r--r--doc/src/sgml/man7/ALTER_SYSTEM.7132
-rw-r--r--doc/src/sgml/man7/ALTER_TABLE.71467
-rw-r--r--doc/src/sgml/man7/ALTER_TABLESPACE.7112
-rw-r--r--doc/src/sgml/man7/ALTER_TEXT_SEARCH_CONFIGURATION.7143
-rw-r--r--doc/src/sgml/man7/ALTER_TEXT_SEARCH_DICTIONARY.7132
-rw-r--r--doc/src/sgml/man7/ALTER_TEXT_SEARCH_PARSER.767
-rw-r--r--doc/src/sgml/man7/ALTER_TEXT_SEARCH_TEMPLATE.767
-rw-r--r--doc/src/sgml/man7/ALTER_TRIGGER.7114
-rw-r--r--doc/src/sgml/man7/ALTER_TYPE.7424
-rw-r--r--doc/src/sgml/man7/ALTER_USER.777
-rw-r--r--doc/src/sgml/man7/ALTER_USER_MAPPING.7104
-rw-r--r--doc/src/sgml/man7/ALTER_VIEW.7178
-rw-r--r--doc/src/sgml/man7/ANALYZE.7215
-rw-r--r--doc/src/sgml/man7/BEGIN.7128
-rw-r--r--doc/src/sgml/man7/CALL.7108
-rw-r--r--doc/src/sgml/man7/CHECKPOINT.765
-rw-r--r--doc/src/sgml/man7/CLOSE.799
-rw-r--r--doc/src/sgml/man7/CLUSTER.7219
-rw-r--r--doc/src/sgml/man7/COMMENT.7324
-rw-r--r--doc/src/sgml/man7/COMMIT.789
-rw-r--r--doc/src/sgml/man7/COMMIT_PREPARED.777
-rw-r--r--doc/src/sgml/man7/COPY.71006
-rw-r--r--doc/src/sgml/man7/CREATE_ACCESS_METHOD.7102
-rw-r--r--doc/src/sgml/man7/CREATE_AGGREGATE.7552
-rw-r--r--doc/src/sgml/man7/CREATE_CAST.7373
-rw-r--r--doc/src/sgml/man7/CREATE_COLLATION.7197
-rw-r--r--doc/src/sgml/man7/CREATE_CONVERSION.7145
-rw-r--r--doc/src/sgml/man7/CREATE_DATABASE.7353
-rw-r--r--doc/src/sgml/man7/CREATE_DOMAIN.7195
-rw-r--r--doc/src/sgml/man7/CREATE_EVENT_TRIGGER.7129
-rw-r--r--doc/src/sgml/man7/CREATE_EXTENSION.7188
-rw-r--r--doc/src/sgml/man7/CREATE_FOREIGN_DATA_WRAPPER.7143
-rw-r--r--doc/src/sgml/man7/CREATE_FOREIGN_TABLE.7309
-rw-r--r--doc/src/sgml/man7/CREATE_FUNCTION.7781
-rw-r--r--doc/src/sgml/man7/CREATE_GROUP.767
-rw-r--r--doc/src/sgml/man7/CREATE_INDEX.7766
-rw-r--r--doc/src/sgml/man7/CREATE_LANGUAGE.7178
-rw-r--r--doc/src/sgml/man7/CREATE_MATERIALIZED_VIEW.7131
-rw-r--r--doc/src/sgml/man7/CREATE_OPERATOR.7282
-rw-r--r--doc/src/sgml/man7/CREATE_OPERATOR_CLASS.7223
-rw-r--r--doc/src/sgml/man7/CREATE_OPERATOR_FAMILY.779
-rw-r--r--doc/src/sgml/man7/CREATE_POLICY.7655
-rw-r--r--doc/src/sgml/man7/CREATE_PROCEDURE.7309
-rw-r--r--doc/src/sgml/man7/CREATE_PUBLICATION.7341
-rw-r--r--doc/src/sgml/man7/CREATE_ROLE.7427
-rw-r--r--doc/src/sgml/man7/CREATE_RULE.7300
-rw-r--r--doc/src/sgml/man7/CREATE_SCHEMA.7207
-rw-r--r--doc/src/sgml/man7/CREATE_SEQUENCE.7357
-rw-r--r--doc/src/sgml/man7/CREATE_SERVER.7116
-rw-r--r--doc/src/sgml/man7/CREATE_STATISTICS.7236
-rw-r--r--doc/src/sgml/man7/CREATE_SUBSCRIPTION.7303
-rw-r--r--doc/src/sgml/man7/CREATE_TABLE.71779
-rw-r--r--doc/src/sgml/man7/CREATE_TABLESPACE.7162
-rw-r--r--doc/src/sgml/man7/CREATE_TABLE_AS.7320
-rw-r--r--doc/src/sgml/man7/CREATE_TEXT_SEARCH_CONFIGURATION.785
-rw-r--r--doc/src/sgml/man7/CREATE_TEXT_SEARCH_DICTIONARY.798
-rw-r--r--doc/src/sgml/man7/CREATE_TEXT_SEARCH_PARSER.797
-rw-r--r--doc/src/sgml/man7/CREATE_TEXT_SEARCH_TEMPLATE.781
-rw-r--r--doc/src/sgml/man7/CREATE_TRANSFORM.7198
-rw-r--r--doc/src/sgml/man7/CREATE_TRIGGER.7715
-rw-r--r--doc/src/sgml/man7/CREATE_TYPE.7733
-rw-r--r--doc/src/sgml/man7/CREATE_USER.775
-rw-r--r--doc/src/sgml/man7/CREATE_USER_MAPPING.794
-rw-r--r--doc/src/sgml/man7/CREATE_VIEW.7545
-rw-r--r--doc/src/sgml/man7/DEALLOCATE.766
-rw-r--r--doc/src/sgml/man7/DECLARE.7345
-rw-r--r--doc/src/sgml/man7/DELETE.7320
-rw-r--r--doc/src/sgml/man7/DISCARD.796
-rw-r--r--doc/src/sgml/man7/DO.7106
-rw-r--r--doc/src/sgml/man7/DROP_ACCESS_METHOD.784
-rw-r--r--doc/src/sgml/man7/DROP_AGGREGATE.7145
-rw-r--r--doc/src/sgml/man7/DROP_CAST.788
-rw-r--r--doc/src/sgml/man7/DROP_COLLATION.789
-rw-r--r--doc/src/sgml/man7/DROP_CONVERSION.785
-rw-r--r--doc/src/sgml/man7/DROP_DATABASE.786
-rw-r--r--doc/src/sgml/man7/DROP_DOMAIN.785
-rw-r--r--doc/src/sgml/man7/DROP_EVENT_TRIGGER.783
-rw-r--r--doc/src/sgml/man7/DROP_EXTENSION.798
-rw-r--r--doc/src/sgml/man7/DROP_FOREIGN_DATA_WRAPPER.786
-rw-r--r--doc/src/sgml/man7/DROP_FOREIGN_TABLE.787
-rw-r--r--doc/src/sgml/man7/DROP_FUNCTION.7186
-rw-r--r--doc/src/sgml/man7/DROP_GROUP.748
-rw-r--r--doc/src/sgml/man7/DROP_INDEX.7109
-rw-r--r--doc/src/sgml/man7/DROP_LANGUAGE.7106
-rw-r--r--doc/src/sgml/man7/DROP_MATERIALIZED_VIEW.784
-rw-r--r--doc/src/sgml/man7/DROP_OPERATOR.7124
-rw-r--r--doc/src/sgml/man7/DROP_OPERATOR_CLASS.7105
-rw-r--r--doc/src/sgml/man7/DROP_OPERATOR_FAMILY.797
-rw-r--r--doc/src/sgml/man7/DROP_OWNED.788
-rw-r--r--doc/src/sgml/man7/DROP_POLICY.790
-rw-r--r--doc/src/sgml/man7/DROP_PROCEDURE.7220
-rw-r--r--doc/src/sgml/man7/DROP_PUBLICATION.781
-rw-r--r--doc/src/sgml/man7/DROP_ROLE.792
-rw-r--r--doc/src/sgml/man7/DROP_ROUTINE.7148
-rw-r--r--doc/src/sgml/man7/DROP_RULE.789
-rw-r--r--doc/src/sgml/man7/DROP_SCHEMA.794
-rw-r--r--doc/src/sgml/man7/DROP_SEQUENCE.788
-rw-r--r--doc/src/sgml/man7/DROP_SERVER.787
-rw-r--r--doc/src/sgml/man7/DROP_STATISTICS.780
-rw-r--r--doc/src/sgml/man7/DROP_SUBSCRIPTION.797
-rw-r--r--doc/src/sgml/man7/DROP_TABLE.796
-rw-r--r--doc/src/sgml/man7/DROP_TABLESPACE.784
-rw-r--r--doc/src/sgml/man7/DROP_TEXT_SEARCH_CONFIGURATION.789
-rw-r--r--doc/src/sgml/man7/DROP_TEXT_SEARCH_DICTIONARY.787
-rw-r--r--doc/src/sgml/man7/DROP_TEXT_SEARCH_PARSER.787
-rw-r--r--doc/src/sgml/man7/DROP_TEXT_SEARCH_TEMPLATE.787
-rw-r--r--doc/src/sgml/man7/DROP_TRANSFORM.796
-rw-r--r--doc/src/sgml/man7/DROP_TRIGGER.793
-rw-r--r--doc/src/sgml/man7/DROP_TYPE.789
-rw-r--r--doc/src/sgml/man7/DROP_USER.750
-rw-r--r--doc/src/sgml/man7/DROP_USER_MAPPING.792
-rw-r--r--doc/src/sgml/man7/DROP_VIEW.785
-rw-r--r--doc/src/sgml/man7/END.790
-rw-r--r--doc/src/sgml/man7/EXECUTE.784
-rw-r--r--doc/src/sgml/man7/EXPLAIN.7421
-rw-r--r--doc/src/sgml/man7/FETCH.7352
-rw-r--r--doc/src/sgml/man7/GRANT.7416
-rw-r--r--doc/src/sgml/man7/IMPORT_FOREIGN_SCHEMA.7132
-rw-r--r--doc/src/sgml/man7/INSERT.7766
-rw-r--r--doc/src/sgml/man7/LISTEN.7117
-rw-r--r--doc/src/sgml/man7/LOAD.769
-rw-r--r--doc/src/sgml/man7/LOCK.7259
-rw-r--r--doc/src/sgml/man7/MERGE.7674
-rw-r--r--doc/src/sgml/man7/MOVE.7124
-rw-r--r--doc/src/sgml/man7/NOTIFY.7154
-rw-r--r--doc/src/sgml/man7/PREPARE.7189
-rw-r--r--doc/src/sgml/man7/PREPARE_TRANSACTION.7147
-rw-r--r--doc/src/sgml/man7/REASSIGN_OWNED.791
-rw-r--r--doc/src/sgml/man7/REFRESH_MATERIALIZED_VIEW.7117
-rw-r--r--doc/src/sgml/man7/REINDEX.7510
-rw-r--r--doc/src/sgml/man7/RELEASE_SAVEPOINT.790
-rw-r--r--doc/src/sgml/man7/RESET.7107
-rw-r--r--doc/src/sgml/man7/REVOKE.7314
-rw-r--r--doc/src/sgml/man7/ROLLBACK.789
-rw-r--r--doc/src/sgml/man7/ROLLBACK_PREPARED.777
-rw-r--r--doc/src/sgml/man7/ROLLBACK_TO_SAVEPOINT.7132
-rw-r--r--doc/src/sgml/man7/SAVEPOINT.7141
-rw-r--r--doc/src/sgml/man7/SECURITY_LABEL.7198
-rw-r--r--doc/src/sgml/man7/SELECT.72524
-rw-r--r--doc/src/sgml/man7/SELECT_INTO.7147
-rw-r--r--doc/src/sgml/man7/SET.7308
-rw-r--r--doc/src/sgml/man7/SET_CONSTRAINTS.7114
-rw-r--r--doc/src/sgml/man7/SET_ROLE.7143
-rw-r--r--doc/src/sgml/man7/SET_SESSION_AUTHORIZATION.7113
-rw-r--r--doc/src/sgml/man7/SET_TRANSACTION.7242
-rw-r--r--doc/src/sgml/man7/SHOW.7167
-rw-r--r--doc/src/sgml/man7/START_TRANSACTION.783
-rw-r--r--doc/src/sgml/man7/TABLE.71
-rw-r--r--doc/src/sgml/man7/TRUNCATE.7186
-rw-r--r--doc/src/sgml/man7/UNLISTEN.7117
-rw-r--r--doc/src/sgml/man7/UPDATE.7473
-rw-r--r--doc/src/sgml/man7/VACUUM.7364
-rw-r--r--doc/src/sgml/man7/VALUES.7292
-rw-r--r--doc/src/sgml/man7/WITH.71
-rw-r--r--doc/src/sgml/manage-ag.sgml552
-rw-r--r--doc/src/sgml/mk_feature_tables.pl77
-rw-r--r--doc/src/sgml/monitoring.sgml7821
-rw-r--r--doc/src/sgml/mvcc.sgml1941
-rw-r--r--doc/src/sgml/nls.sgml532
-rw-r--r--doc/src/sgml/notation.sgml31
-rw-r--r--doc/src/sgml/oid2name.sgml376
-rw-r--r--doc/src/sgml/oldsnapshot.sgml33
-rw-r--r--doc/src/sgml/pageinspect.sgml914
-rw-r--r--doc/src/sgml/parallel.sgml598
-rw-r--r--doc/src/sgml/passwordcheck.sgml62
-rw-r--r--doc/src/sgml/perform.sgml1961
-rw-r--r--doc/src/sgml/pgbuffercache.sgml213
-rw-r--r--doc/src/sgml/pgcrypto.sgml1332
-rw-r--r--doc/src/sgml/pgfreespacemap.sgml121
-rw-r--r--doc/src/sgml/pgprewarm.sgml148
-rw-r--r--doc/src/sgml/pgrowlocks.sgml150
-rw-r--r--doc/src/sgml/pgstatstatements.sgml973
-rw-r--r--doc/src/sgml/pgstattuple.sgml629
-rw-r--r--doc/src/sgml/pgsurgery.sgml107
-rw-r--r--doc/src/sgml/pgtrgm.sgml642
-rw-r--r--doc/src/sgml/pgvisibility.sgml158
-rw-r--r--doc/src/sgml/pgwalinspect.sgml203
-rw-r--r--doc/src/sgml/planstats.sgml762
-rw-r--r--doc/src/sgml/plhandler.sgml192
-rw-r--r--doc/src/sgml/plperl.sgml1595
-rw-r--r--doc/src/sgml/plpgsql.sgml6092
-rw-r--r--doc/src/sgml/plpython.sgml1397
-rw-r--r--doc/src/sgml/pltcl.sgml1135
-rw-r--r--doc/src/sgml/postgres-fdw.sgml1155
-rw-r--r--doc/src/sgml/postgres.sgml303
-rw-r--r--doc/src/sgml/problems.sgml362
-rw-r--r--doc/src/sgml/protocol.sgml7455
-rw-r--r--doc/src/sgml/queries.sgml2740
-rw-r--r--doc/src/sgml/query.sgml910
-rw-r--r--doc/src/sgml/rangetypes.sgml592
-rw-r--r--doc/src/sgml/ref/abort.sgml112
-rw-r--r--doc/src/sgml/ref/allfiles.sgml225
-rw-r--r--doc/src/sgml/ref/alter_aggregate.sgml202
-rw-r--r--doc/src/sgml/ref/alter_collation.sgml207
-rw-r--r--doc/src/sgml/ref/alter_conversion.sgml127
-rw-r--r--doc/src/sgml/ref/alter_database.sgml255
-rw-r--r--doc/src/sgml/ref/alter_default_privileges.sgml255
-rw-r--r--doc/src/sgml/ref/alter_domain.sgml365
-rw-r--r--doc/src/sgml/ref/alter_event_trigger.sgml105
-rw-r--r--doc/src/sgml/ref/alter_extension.sgml334
-rw-r--r--doc/src/sgml/ref/alter_foreign_data_wrapper.sgml188
-rw-r--r--doc/src/sgml/ref/alter_foreign_table.sgml556
-rw-r--r--doc/src/sgml/ref/alter_function.sgml392
-rw-r--r--doc/src/sgml/ref/alter_group.sgml135
-rw-r--r--doc/src/sgml/ref/alter_index.sgml323
-rw-r--r--doc/src/sgml/ref/alter_language.sgml91
-rw-r--r--doc/src/sgml/ref/alter_large_object.sgml86
-rw-r--r--doc/src/sgml/ref/alter_materialized_view.sgml186
-rw-r--r--doc/src/sgml/ref/alter_opclass.sgml124
-rw-r--r--doc/src/sgml/ref/alter_operator.sgml160
-rw-r--r--doc/src/sgml/ref/alter_opfamily.sgml360
-rw-r--r--doc/src/sgml/ref/alter_policy.sgml143
-rw-r--r--doc/src/sgml/ref/alter_procedure.sgml289
-rw-r--r--doc/src/sgml/ref/alter_publication.sgml235
-rw-r--r--doc/src/sgml/ref/alter_role.sgml354
-rw-r--r--doc/src/sgml/ref/alter_routine.sgml103
-rw-r--r--doc/src/sgml/ref/alter_rule.sgml105
-rw-r--r--doc/src/sgml/ref/alter_schema.sgml100
-rw-r--r--doc/src/sgml/ref/alter_sequence.sgml363
-rw-r--r--doc/src/sgml/ref/alter_server.sgml144
-rw-r--r--doc/src/sgml/ref/alter_statistics.sgml135
-rw-r--r--doc/src/sgml/ref/alter_subscription.sgml313
-rw-r--r--doc/src/sgml/ref/alter_system.sgml144
-rw-r--r--doc/src/sgml/ref/alter_table.sgml1785
-rw-r--r--doc/src/sgml/ref/alter_tablespace.sgml140
-rw-r--r--doc/src/sgml/ref/alter_trigger.sgml146
-rw-r--r--doc/src/sgml/ref/alter_tsconfig.sgml189
-rw-r--r--doc/src/sgml/ref/alter_tsdictionary.sgml170
-rw-r--r--doc/src/sgml/ref/alter_tsparser.sgml93
-rw-r--r--doc/src/sgml/ref/alter_tstemplate.sgml93
-rw-r--r--doc/src/sgml/ref/alter_type.sgml494
-rw-r--r--doc/src/sgml/ref/alter_user.sgml81
-rw-r--r--doc/src/sgml/ref/alter_user_mapping.sgml124
-rw-r--r--doc/src/sgml/ref/alter_view.sgml229
-rw-r--r--doc/src/sgml/ref/analyze.sgml321
-rw-r--r--doc/src/sgml/ref/begin.sgml161
-rw-r--r--doc/src/sgml/ref/call.sgml133
-rw-r--r--doc/src/sgml/ref/checkpoint.sgml69
-rw-r--r--doc/src/sgml/ref/close.sgml132
-rw-r--r--doc/src/sgml/ref/cluster.sgml259
-rw-r--r--doc/src/sgml/ref/clusterdb.sgml352
-rw-r--r--doc/src/sgml/ref/comment.sgml374
-rw-r--r--doc/src/sgml/ref/commit.sgml112
-rw-r--r--doc/src/sgml/ref/commit_prepared.sgml107
-rw-r--r--doc/src/sgml/ref/copy.sgml1081
-rw-r--r--doc/src/sgml/ref/create_access_method.sgml122
-rw-r--r--doc/src/sgml/ref/create_aggregate.sgml805
-rw-r--r--doc/src/sgml/ref/create_cast.sgml424
-rw-r--r--doc/src/sgml/ref/create_collation.sgml263
-rw-r--r--doc/src/sgml/ref/create_conversion.sgml189
-rw-r--r--doc/src/sgml/ref/create_database.sgml449
-rw-r--r--doc/src/sgml/ref/create_domain.sgml288
-rw-r--r--doc/src/sgml/ref/create_event_trigger.sgml170
-rw-r--r--doc/src/sgml/ref/create_extension.sgml247
-rw-r--r--doc/src/sgml/ref/create_foreign_data_wrapper.sgml183
-rw-r--r--doc/src/sgml/ref/create_foreign_table.sgml455
-rw-r--r--doc/src/sgml/ref/create_function.sgml935
-rw-r--r--doc/src/sgml/ref/create_group.sgml72
-rw-r--r--doc/src/sgml/ref/create_index.sgml999
-rw-r--r--doc/src/sgml/ref/create_language.sgml250
-rw-r--r--doc/src/sgml/ref/create_materialized_view.sgml187
-rw-r--r--doc/src/sgml/ref/create_opclass.sgml330
-rw-r--r--doc/src/sgml/ref/create_operator.sgml299
-rw-r--r--doc/src/sgml/ref/create_opfamily.sgml118
-rw-r--r--doc/src/sgml/ref/create_policy.sgml655
-rw-r--r--doc/src/sgml/ref/create_procedure.sgml411
-rw-r--r--doc/src/sgml/ref/create_publication.sgml409
-rw-r--r--doc/src/sgml/ref/create_role.sgml504
-rw-r--r--doc/src/sgml/ref/create_rule.sgml305
-rw-r--r--doc/src/sgml/ref/create_schema.sgml228
-rw-r--r--doc/src/sgml/ref/create_sequence.sgml413
-rw-r--r--doc/src/sgml/ref/create_server.sgml167
-rw-r--r--doc/src/sgml/ref/create_statistics.sgml331
-rw-r--r--doc/src/sgml/ref/create_subscription.sgml422
-rw-r--r--doc/src/sgml/ref/create_table.sgml2422
-rw-r--r--doc/src/sgml/ref/create_table_as.sgml362
-rw-r--r--doc/src/sgml/ref/create_tablespace.sgml187
-rw-r--r--doc/src/sgml/ref/create_transform.sgml214
-rw-r--r--doc/src/sgml/ref/create_trigger.sgml777
-rw-r--r--doc/src/sgml/ref/create_tsconfig.sgml126
-rw-r--r--doc/src/sgml/ref/create_tsdictionary.sgml141
-rw-r--r--doc/src/sgml/ref/create_tsparser.sgml153
-rw-r--r--doc/src/sgml/ref/create_tstemplate.sgml126
-rw-r--r--doc/src/sgml/ref/create_type.sgml1029
-rw-r--r--doc/src/sgml/ref/create_user.sgml78
-rw-r--r--doc/src/sgml/ref/create_user_mapping.sgml132
-rw-r--r--doc/src/sgml/ref/create_view.sgml575
-rw-r--r--doc/src/sgml/ref/createdb.sgml426
-rw-r--r--doc/src/sgml/ref/createuser.sgml506
-rw-r--r--doc/src/sgml/ref/deallocate.sgml98
-rw-r--r--doc/src/sgml/ref/declare.sgml361
-rw-r--r--doc/src/sgml/ref/delete.sgml289
-rw-r--r--doc/src/sgml/ref/discard.sgml118
-rw-r--r--doc/src/sgml/ref/do.sgml135
-rw-r--r--doc/src/sgml/ref/drop_access_method.sgml111
-rw-r--r--doc/src/sgml/ref/drop_aggregate.sgml184
-rw-r--r--doc/src/sgml/ref/drop_cast.sgml117
-rw-r--r--doc/src/sgml/ref/drop_collation.sgml114
-rw-r--r--doc/src/sgml/ref/drop_conversion.sgml107
-rw-r--r--doc/src/sgml/ref/drop_database.sgml126
-rw-r--r--doc/src/sgml/ref/drop_domain.sgml114
-rw-r--r--doc/src/sgml/ref/drop_event_trigger.sgml115
-rw-r--r--doc/src/sgml/ref/drop_extension.sgml126
-rw-r--r--doc/src/sgml/ref/drop_foreign_data_wrapper.sgml114
-rw-r--r--doc/src/sgml/ref/drop_foreign_table.sgml115
-rw-r--r--doc/src/sgml/ref/drop_function.sgml192
-rw-r--r--doc/src/sgml/ref/drop_group.sgml53
-rw-r--r--doc/src/sgml/ref/drop_index.sgml143
-rw-r--r--doc/src/sgml/ref/drop_language.sgml125
-rw-r--r--doc/src/sgml/ref/drop_materialized_view.sgml116
-rw-r--r--doc/src/sgml/ref/drop_opclass.sgml149
-rw-r--r--doc/src/sgml/ref/drop_operator.sgml146
-rw-r--r--doc/src/sgml/ref/drop_opfamily.sgml138
-rw-r--r--doc/src/sgml/ref/drop_owned.sgml126
-rw-r--r--doc/src/sgml/ref/drop_policy.sgml119
-rw-r--r--doc/src/sgml/ref/drop_procedure.sgml231
-rw-r--r--doc/src/sgml/ref/drop_publication.sgml105
-rw-r--r--doc/src/sgml/ref/drop_role.sgml124
-rw-r--r--doc/src/sgml/ref/drop_routine.sgml123
-rw-r--r--doc/src/sgml/ref/drop_rule.sgml123
-rw-r--r--doc/src/sgml/ref/drop_schema.sgml131
-rw-r--r--doc/src/sgml/ref/drop_sequence.sgml115
-rw-r--r--doc/src/sgml/ref/drop_server.sgml114
-rw-r--r--doc/src/sgml/ref/drop_statistics.sgml108
-rw-r--r--doc/src/sgml/ref/drop_subscription.sgml134
-rw-r--r--doc/src/sgml/ref/drop_table.sgml129
-rw-r--r--doc/src/sgml/ref/drop_tablespace.sgml110
-rw-r--r--doc/src/sgml/ref/drop_transform.sgml128
-rw-r--r--doc/src/sgml/ref/drop_trigger.sgml127
-rw-r--r--doc/src/sgml/ref/drop_tsconfig.sgml121
-rw-r--r--doc/src/sgml/ref/drop_tsdictionary.sgml120
-rw-r--r--doc/src/sgml/ref/drop_tsparser.sgml118
-rw-r--r--doc/src/sgml/ref/drop_tstemplate.sgml119
-rw-r--r--doc/src/sgml/ref/drop_type.sgml116
-rw-r--r--doc/src/sgml/ref/drop_user.sgml55
-rw-r--r--doc/src/sgml/ref/drop_user_mapping.sgml110
-rw-r--r--doc/src/sgml/ref/drop_view.sgml114
-rw-r--r--doc/src/sgml/ref/dropdb.sgml317
-rw-r--r--doc/src/sgml/ref/dropuser.sgml294
-rw-r--r--doc/src/sgml/ref/ecpg-ref.sgml278
-rw-r--r--doc/src/sgml/ref/end.sgml112
-rw-r--r--doc/src/sgml/ref/execute.sgml121
-rw-r--r--doc/src/sgml/ref/explain.sgml487
-rw-r--r--doc/src/sgml/ref/fetch.sgml418
-rw-r--r--doc/src/sgml/ref/grant.sgml479
-rw-r--r--doc/src/sgml/ref/import_foreign_schema.sgml166
-rw-r--r--doc/src/sgml/ref/initdb.sgml588
-rw-r--r--doc/src/sgml/ref/insert.sgml792
-rw-r--r--doc/src/sgml/ref/listen.sgml153
-rw-r--r--doc/src/sgml/ref/load.sgml81
-rw-r--r--doc/src/sgml/ref/lock.sgml266
-rw-r--r--doc/src/sgml/ref/merge.sgml634
-rw-r--r--doc/src/sgml/ref/move.sgml124
-rw-r--r--doc/src/sgml/ref/notify.sgml233
-rw-r--r--doc/src/sgml/ref/pg_amcheck.sgml652
-rw-r--r--doc/src/sgml/ref/pg_basebackup.sgml1008
-rw-r--r--doc/src/sgml/ref/pg_checksums.sgml229
-rw-r--r--doc/src/sgml/ref/pg_config-ref.sgml332
-rw-r--r--doc/src/sgml/ref/pg_controldata.sgml84
-rw-r--r--doc/src/sgml/ref/pg_ctl-ref.sgml713
-rw-r--r--doc/src/sgml/ref/pg_dump.sgml1535
-rw-r--r--doc/src/sgml/ref/pg_dumpall.sgml821
-rw-r--r--doc/src/sgml/ref/pg_isready.sgml217
-rw-r--r--doc/src/sgml/ref/pg_receivewal.sgml530
-rw-r--r--doc/src/sgml/ref/pg_recvlogical.sgml453
-rw-r--r--doc/src/sgml/ref/pg_resetwal.sgml386
-rw-r--r--doc/src/sgml/ref/pg_restore.sgml1044
-rw-r--r--doc/src/sgml/ref/pg_rewind.sgml418
-rw-r--r--doc/src/sgml/ref/pg_verifybackup.sgml289
-rw-r--r--doc/src/sgml/ref/pg_waldump.sgml340
-rw-r--r--doc/src/sgml/ref/pgarchivecleanup.sgml207
-rw-r--r--doc/src/sgml/ref/pgbench.sgml2950
-rw-r--r--doc/src/sgml/ref/pgtestfsync.sgml127
-rw-r--r--doc/src/sgml/ref/pgtesttiming.sgml303
-rw-r--r--doc/src/sgml/ref/pgupgrade.sgml857
-rw-r--r--doc/src/sgml/ref/postgres-ref.sgml845
-rw-r--r--doc/src/sgml/ref/postmaster.sgml44
-rw-r--r--doc/src/sgml/ref/prepare.sgml258
-rw-r--r--doc/src/sgml/ref/prepare_transaction.sgml181
-rw-r--r--doc/src/sgml/ref/psql-ref.sgml5183
-rw-r--r--doc/src/sgml/ref/reassign_owned.sgml123
-rw-r--r--doc/src/sgml/ref/refresh_materialized_view.sgml143
-rw-r--r--doc/src/sgml/ref/reindex.sgml560
-rw-r--r--doc/src/sgml/ref/reindexdb.sgml476
-rw-r--r--doc/src/sgml/ref/release_savepoint.sgml131
-rw-r--r--doc/src/sgml/ref/reset.sgml113
-rw-r--r--doc/src/sgml/ref/revoke.sgml332
-rw-r--r--doc/src/sgml/ref/rollback.sgml112
-rw-r--r--doc/src/sgml/ref/rollback_prepared.sgml107
-rw-r--r--doc/src/sgml/ref/rollback_to.sgml158
-rw-r--r--doc/src/sgml/ref/savepoint.sgml165
-rw-r--r--doc/src/sgml/ref/security_label.sgml233
-rw-r--r--doc/src/sgml/ref/select.sgml2197
-rw-r--r--doc/src/sgml/ref/select_into.sgml156
-rw-r--r--doc/src/sgml/ref/set.sgml332
-rw-r--r--doc/src/sgml/ref/set_constraints.sgml125
-rw-r--r--doc/src/sgml/ref/set_role.sgml155
-rw-r--r--doc/src/sgml/ref/set_session_auth.sgml130
-rw-r--r--doc/src/sgml/ref/set_transaction.sgml290
-rw-r--r--doc/src/sgml/ref/show.sgml200
-rw-r--r--doc/src/sgml/ref/start_transaction.sgml97
-rw-r--r--doc/src/sgml/ref/truncate.sgml233
-rw-r--r--doc/src/sgml/ref/unlisten.sgml133
-rw-r--r--doc/src/sgml/ref/update.sgml475
-rw-r--r--doc/src/sgml/ref/vacuum.sgml453
-rw-r--r--doc/src/sgml/ref/vacuumdb.sgml632
-rw-r--r--doc/src/sgml/ref/values.sgml251
-rw-r--r--doc/src/sgml/reference.sgml296
-rw-r--r--doc/src/sgml/regress.sgml851
-rw-r--r--doc/src/sgml/release-15.sgml8633
-rw-r--r--doc/src/sgml/release.sgml95
-rw-r--r--doc/src/sgml/replication-origins.sgml96
-rw-r--r--doc/src/sgml/rowtypes.sgml540
-rw-r--r--doc/src/sgml/rules.sgml2434
-rw-r--r--doc/src/sgml/runtime.sgml2773
-rw-r--r--doc/src/sgml/seg.sgml415
-rw-r--r--doc/src/sgml/sepgsql.sgml828
-rw-r--r--doc/src/sgml/sourcerepo.sgml94
-rw-r--r--doc/src/sgml/sources.sgml1035
-rw-r--r--doc/src/sgml/spgist.sgml1076
-rw-r--r--doc/src/sgml/spi.sgml5400
-rw-r--r--doc/src/sgml/sslinfo.sgml263
-rw-r--r--doc/src/sgml/standalone-install.xml171
-rw-r--r--doc/src/sgml/standalone-profile.xsl85
-rw-r--r--doc/src/sgml/start.sgml409
-rw-r--r--doc/src/sgml/storage.sgml1148
-rw-r--r--doc/src/sgml/stylesheet-common.xsl104
-rw-r--r--doc/src/sgml/stylesheet-fo.xsl135
-rw-r--r--doc/src/sgml/stylesheet-hh.xsl47
-rw-r--r--doc/src/sgml/stylesheet-html-common.xsl304
-rw-r--r--doc/src/sgml/stylesheet-html-nochunk.xsl21
-rw-r--r--doc/src/sgml/stylesheet-man.xsl226
-rw-r--r--doc/src/sgml/stylesheet-speedup-common.xsl100
-rw-r--r--doc/src/sgml/stylesheet-speedup-xhtml.xsl345
-rw-r--r--doc/src/sgml/stylesheet-text.xsl97
-rw-r--r--doc/src/sgml/stylesheet.css165
-rw-r--r--doc/src/sgml/stylesheet.xsl330
-rw-r--r--doc/src/sgml/syntax.sgml2737
-rw-r--r--doc/src/sgml/system-views.sgml4746
-rw-r--r--doc/src/sgml/tableam.sgml108
-rw-r--r--doc/src/sgml/tablefunc.sgml865
-rw-r--r--doc/src/sgml/tablesample-method.sgml300
-rw-r--r--doc/src/sgml/tcn.sgml77
-rw-r--r--doc/src/sgml/test-decoding.sgml64
-rw-r--r--doc/src/sgml/textsearch.sgml4009
-rw-r--r--doc/src/sgml/trigger.sgml1032
-rw-r--r--doc/src/sgml/tsm-system-rows.sgml69
-rw-r--r--doc/src/sgml/tsm-system-time.sgml71
-rw-r--r--doc/src/sgml/typeconv.sgml1262
-rw-r--r--doc/src/sgml/unaccent.sgml202
-rw-r--r--doc/src/sgml/user-manag.sgml732
-rw-r--r--doc/src/sgml/uuid-ossp.sgml242
-rw-r--r--doc/src/sgml/vacuumlo.sgml231
-rw-r--r--doc/src/sgml/wal.sgml911
-rw-r--r--doc/src/sgml/xaggr.sgml670
-rw-r--r--doc/src/sgml/xfunc.sgml3639
-rw-r--r--doc/src/sgml/xindex.sgml1452
-rw-r--r--doc/src/sgml/xml2.sgml443
-rw-r--r--doc/src/sgml/xoper.sgml486
-rw-r--r--doc/src/sgml/xplang.sgml230
-rw-r--r--doc/src/sgml/xtypes.sgml376
1881 files changed, 557650 insertions, 0 deletions
diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore
new file mode 100644
index 0000000..acf7b4f
--- /dev/null
+++ b/doc/src/sgml/.gitignore
@@ -0,0 +1,25 @@
+# Stuff shipped in tarballs
+/html/
+/html-stamp
+/man1/
+/man3/
+/man7/
+/man-stamp
+# Other popular build targets
+/INSTALL
+/postgres-US.pdf
+/postgres-A4.pdf
+/postgres.html
+/postgres.txt
+# GENERATED_SGML
+/features-supported.sgml
+/features-unsupported.sgml
+/errcodes-table.sgml
+/keywords-table.sgml
+/version.sgml
+# Assorted byproducts from building the above
+/postgres.xml
+/INSTALL.html
+/INSTALL.xml
+/postgres-US.fo
+/postgres-A4.fo
diff --git a/doc/src/sgml/Makefile b/doc/src/sgml/Makefile
new file mode 100644
index 0000000..16fff83
--- /dev/null
+++ b/doc/src/sgml/Makefile
@@ -0,0 +1,317 @@
+#----------------------------------------------------------------------------
+#
+# PostgreSQL documentation makefile
+#
+# doc/src/sgml/Makefile
+#
+#----------------------------------------------------------------------------
+
+# This makefile is for building and installing the documentation.
+# When a release tarball is created, the documentation files are
+# prepared using the distprep target. In Git-based trees these files
+# don't exist, unless explicitly built, so we skip the installation in
+# that case.
+
+
+# Make "html" the default target, since that is what most people tend
+# to want to use.
+html:
+
+# We don't need the tree-wide headers or install support here.
+NO_GENERATED_HEADERS=yes
+NO_TEMP_INSTALL=yes
+
+subdir = doc/src/sgml
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+
+all: html man
+
+distprep: html distprep-man
+
+
+ifndef DBTOEPUB
+DBTOEPUB = $(missing) dbtoepub
+endif
+
+ifndef FOP
+FOP = $(missing) fop
+endif
+
+XMLINCLUDE = --path .
+
+ifdef XMLLINT
+XMLLINT := $(XMLLINT) --nonet
+else
+XMLLINT = $(missing) xmllint
+endif
+
+ifdef XSLTPROC
+XSLTPROC := $(XSLTPROC) --nonet
+else
+XSLTPROC = $(missing) xsltproc
+endif
+
+override XSLTPROCFLAGS += --stringparam pg.version '$(VERSION)'
+
+
+GENERATED_SGML = version.sgml \
+ features-supported.sgml features-unsupported.sgml errcodes-table.sgml \
+ keywords-table.sgml
+
+ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML)
+
+ALL_IMAGES := $(wildcard $(srcdir)/images/*.svg)
+
+
+##
+## Man pages
+##
+
+man distprep-man: man-stamp
+
+man-stamp: stylesheet-man.xsl postgres.sgml $(ALLSGML)
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_MAN_FLAGS) $(wordlist 1,2,$^)
+ touch $@
+
+
+##
+## common files
+##
+
+# Technically, this should depend on Makefile.global, but then
+# version.sgml would need to be rebuilt after every configure run,
+# even in distribution tarballs. So this is cheating a bit, but it
+# will achieve the goal of updating the version number when it
+# changes.
+version.sgml: $(top_srcdir)/configure
+ { \
+ echo "<!ENTITY version \"$(VERSION)\">"; \
+ echo "<!ENTITY majorversion \"$(MAJORVERSION)\">"; \
+ } > $@
+
+features-supported.sgml: $(top_srcdir)/src/backend/catalog/sql_feature_packages.txt $(top_srcdir)/src/backend/catalog/sql_features.txt
+ $(PERL) $(srcdir)/mk_feature_tables.pl YES $^ > $@
+
+features-unsupported.sgml: $(top_srcdir)/src/backend/catalog/sql_feature_packages.txt $(top_srcdir)/src/backend/catalog/sql_features.txt
+ $(PERL) $(srcdir)/mk_feature_tables.pl NO $^ > $@
+
+errcodes-table.sgml: $(top_srcdir)/src/backend/utils/errcodes.txt generate-errcodes-table.pl
+ $(PERL) $(srcdir)/generate-errcodes-table.pl $< > $@
+
+keywords-table.sgml: $(top_srcdir)/src/include/parser/kwlist.h $(wildcard $(srcdir)/keywords/sql*.txt) generate-keywords-table.pl
+ $(PERL) $(srcdir)/generate-keywords-table.pl $(srcdir) > $@
+
+
+##
+## Generation of some text files.
+##
+
+ICONV = iconv
+PANDOC = pandoc
+
+INSTALL: % : %.html
+ $(PANDOC) -t plain -o $@.tmp $<
+ $(ICONV) -f utf8 -t us-ascii//TRANSLIT $@.tmp > $@
+ rm $@.tmp
+
+INSTALL.html: %.html : stylesheet-text.xsl %.xml
+ $(XMLLINT) --noout --valid $*.xml
+ $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $^ >$@
+
+INSTALL.xml: standalone-profile.xsl standalone-install.xml postgres.sgml $(ALLSGML)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) --xinclude $(wordlist 1,2,$^) >$@
+
+
+##
+## HTML
+##
+
+ifeq ($(STYLE),website)
+XSLTPROC_HTML_FLAGS += --param website.stylesheet 1
+endif
+
+html: html-stamp
+
+html-stamp: stylesheet.xsl postgres.sgml $(ALLSGML) $(ALL_IMAGES)
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $(wordlist 1,2,$^)
+ cp $(ALL_IMAGES) html/
+ cp $(srcdir)/stylesheet.css html/
+ touch $@
+
+htmlhelp: htmlhelp-stamp
+
+htmlhelp-stamp: stylesheet-hh.xsl postgres.sgml $(ALLSGML) $(ALL_IMAGES)
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(wordlist 1,2,$^)
+ cp $(ALL_IMAGES) htmlhelp/
+ cp $(srcdir)/stylesheet.css htmlhelp/
+ touch $@
+
+# single-page HTML
+postgres.html: stylesheet-html-nochunk.xsl postgres.sgml $(ALLSGML) $(ALL_IMAGES)
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) -o $@ $(wordlist 1,2,$^)
+
+# single-page text
+postgres.txt: postgres.html
+ $(PANDOC) -t plain -o $@ $<
+
+
+##
+## Print
+##
+
+postgres.pdf:
+ $(error Invalid target; use postgres-A4.pdf or postgres-US.pdf as targets)
+
+XSLTPROC_FO_FLAGS += --stringparam img.src.path '$(srcdir)/'
+
+%-A4.fo: stylesheet-fo.xsl %.sgml $(ALLSGML)
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type A4 -o $@ $(wordlist 1,2,$^)
+
+%-US.fo: stylesheet-fo.xsl %.sgml $(ALLSGML)
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^)
+ $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type USletter -o $@ $(wordlist 1,2,$^)
+
+%.pdf: %.fo $(ALL_IMAGES)
+ $(FOP) -fo $< -pdf $@
+
+
+##
+## EPUB
+##
+
+epub: postgres.epub
+postgres.epub: postgres.sgml $(ALLSGML) $(ALL_IMAGES)
+ $(XMLLINT) --noout --valid $<
+ $(DBTOEPUB) -o $@ $<
+
+
+##
+## Experimental Texinfo targets
+##
+
+DB2X_TEXIXML = db2x_texixml
+DB2X_XSLTPROC = db2x_xsltproc
+MAKEINFO = makeinfo
+
+%.texixml: %.sgml $(ALLSGML)
+ $(XMLLINT) --noout --valid $<
+ $(DB2X_XSLTPROC) -s texi -g output-file=$(basename $@) $< -o $@
+
+%.texi: %.texixml
+ $(DB2X_TEXIXML) --encoding=utf-8 $< --to-stdout > $@
+
+%.info: %.texi
+ $(MAKEINFO) --enable-encoding --no-split --no-validate $< -o $@
+
+
+##
+## Check
+##
+
+# Quick syntax check without style processing
+check: postgres.sgml $(ALLSGML) check-tabs
+ $(XMLLINT) $(XMLINCLUDE) --noout --valid $<
+
+
+##
+## Install
+##
+
+install: install-html install-man
+
+installdirs:
+ $(MKDIR_P) '$(DESTDIR)$(htmldir)'/html $(addprefix '$(DESTDIR)$(mandir)'/man, 1 3 $(sqlmansectnum))
+
+# If the install used a man directory shared with other applications, this will remove all files.
+uninstall:
+ rm -f '$(DESTDIR)$(htmldir)/html/'* $(addprefix '$(DESTDIR)$(mandir)'/man, 1/* 3/* $(sqlmansectnum)/*)
+
+
+## Install html
+
+install-html: html installdirs
+ cp -R $(call vpathsearch,html) '$(DESTDIR)$(htmldir)'
+
+
+## Install man
+
+install-man: man installdirs
+
+sqlmansect ?= 7
+sqlmansectnum = $(shell expr X'$(sqlmansect)' : X'\([0-9]\)')
+
+# Before we install the man pages, we massage the section numbers to
+# follow the local conventions.
+#
+ifeq ($(sqlmansectnum),7)
+install-man:
+ cp -R $(foreach dir,man1 man3 man7,$(call vpathsearch,$(dir))) '$(DESTDIR)$(mandir)'
+
+else # sqlmansectnum != 7
+fix_sqlmansectnum = sed -e '/^\.TH/s/"7"/"$(sqlmansect)"/' \
+ -e 's/\\fR(7)/\\fR($(sqlmansectnum))/g' \
+ -e '1s/^\.so man7/.so man$(sqlmansectnum)/g;1s/^\(\.so.*\)\.7$$/\1.$(sqlmansect)/g'
+
+man: fixed-man-stamp
+
+fixed-man-stamp: man-stamp
+ @$(MKDIR_P) $(addprefix fixedman/,man1 man3 man$(sqlmansectnum))
+ for file in $(call vpathsearch,man1)/*.1; do $(fix_sqlmansectnum) $$file >fixedman/man1/`basename $$file` || exit; done
+ for file in $(call vpathsearch,man3)/*.3; do $(fix_sqlmansectnum) $$file >fixedman/man3/`basename $$file` || exit; done
+ for file in $(call vpathsearch,man7)/*.7; do $(fix_sqlmansectnum) $$file >fixedman/man$(sqlmansectnum)/`basename $$file | sed s/\.7$$/.$(sqlmansect)/` || exit; done
+
+install-man:
+ cp -R $(foreach dir,man1 man3 man$(sqlmansectnum),fixedman/$(dir)) '$(DESTDIR)$(mandir)'
+
+clean: clean-man
+.PHONY: clean-man
+clean-man:
+ rm -rf fixedman/ fixed-man-stamp
+
+endif # sqlmansectnum != 7
+
+# tabs are harmless, but it is best to avoid them in SGML files
+check-tabs:
+ @( ! grep ' ' $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml $(srcdir)/*.xsl) ) || (echo "Tabs appear in SGML/XML files" 1>&2; exit 1)
+
+##
+## Clean
+##
+
+# This allows removing some files from the distribution tarballs while
+# keeping the dependencies satisfied.
+.SECONDARY: $(GENERATED_SGML)
+.SECONDARY: INSTALL.html INSTALL.xml
+.SECONDARY: postgres-A4.fo postgres-US.fo
+
+clean:
+# text --- these are shipped, but not in this directory
+ rm -f INSTALL
+ rm -f INSTALL.html INSTALL.xml
+# single-page output
+ rm -f postgres.html postgres.txt
+# print
+ rm -f *.fo *.pdf
+# generated SGML files
+ rm -f $(GENERATED_SGML)
+# HTML Help
+ rm -rf htmlhelp/ htmlhelp-stamp
+# EPUB
+ rm -f postgres.epub
+# Texinfo
+ rm -f *.texixml *.texi *.info db2texi.refs
+
+distclean: clean
+
+maintainer-clean: distclean
+# HTML
+ rm -fr html/ html-stamp
+# man
+ rm -rf man1/ man3/ man7/ man-stamp
diff --git a/doc/src/sgml/README.links b/doc/src/sgml/README.links
new file mode 100644
index 0000000..65df9c1
--- /dev/null
+++ b/doc/src/sgml/README.links
@@ -0,0 +1,54 @@
+<!-- doc/src/sgml/README.links -->
+
+Linking within DocBook documents can be confusing, so here is a summary:
+
+
+Intra-document Linking
+----------------------
+
+<xref>
+ use to get chapter/section number from the title of the target
+ link, or xreflabel if defined at the target, or refentrytitle if target
+ is a refentry; has no close tag
+ http://www.oasis-open.org/docbook/documentation/reference/html/xref.html
+
+linkend=
+ controls the target of the link/xref, required
+
+endterm=
+ for <xref>, allows the text of the link/xref to be taken from a
+ different link target title
+
+<link>
+ use to supply text for the link, only uses linkend, requires </link>
+ http://www.oasis-open.org/docbook/documentation/reference/html/link.html
+ can be embedded inside of <command>, unlike <xref>
+
+
+External Linking
+----------------
+
+<ulink>
+ like <link>, but uses a URL (not a document target); requires
+ </ulink>; if no text is specified, the URL appears as the link
+ text
+ http://www.oasis-open.org/docbook/documentation/reference/html/ulink.html
+
+url=
+ used by <ulink> to specify the URL, required
+
+
+Guidelines
+----------
+
+- For an internal link, if you want to supply text, use <link>, else
+ <xref>.
+
+- Specific nouns like GUC variables, SQL commands, and contrib modules
+ usually have xreflabels.
+
+- For an external link, use <ulink>, with or without link text.
+
+- xreflabels added to tags prevent the chapter/section for id's from being
+ referenced; only the xreflabel is accessible. Therefore, use xreflabels
+ only when linking is common, and chapter/section information is unneeded.
diff --git a/doc/src/sgml/acronyms.sgml b/doc/src/sgml/acronyms.sgml
new file mode 100644
index 0000000..2df6559
--- /dev/null
+++ b/doc/src/sgml/acronyms.sgml
@@ -0,0 +1,818 @@
+<!-- doc/src/sgml/acronyms.sgml -->
+
+<appendix id="acronyms">
+ <title>Acronyms</title>
+
+ <para>
+ This is a list of acronyms commonly used in the <productname>PostgreSQL</productname>
+ documentation and in discussions about <productname>PostgreSQL</productname>.
+
+ <variablelist>
+
+ <varlistentry>
+ <term><acronym>ANSI</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/American_National_Standards_Institute">
+ American National Standards Institute</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>API</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/API">Application Programming Interface</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ASCII</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Ascii">American Standard
+ Code for Information Interchange</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>BKI</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="bki">Backend Interface</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CA</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Certificate_authority">Certificate Authority</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CIDR</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing">Classless
+ Inter-Domain Routing</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CPAN</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://www.cpan.org/">Comprehensive Perl Archive Network</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CRL</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Certificate_revocation_list">Certificate
+ Revocation List</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CSV</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Comma-separated_values">Comma
+ Separated Values</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CTE</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="queries-with">Common Table Expression</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>CVE</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://cve.mitre.org/">Common Vulnerabilities and Exposures</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>DBA</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Database_administrator">Database
+ Administrator</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>DBI</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://dbi.perl.org/">Database Interface (Perl)</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>DBMS</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Dbms">Database Management
+ System</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>DDL</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Data_Definition_Language">Data
+ Definition Language</ulink>, SQL commands such as <command>CREATE
+ TABLE</command>, <command>ALTER USER</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>DML</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Data_Manipulation_Language">Data
+ Manipulation Language</ulink>, SQL commands such as <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>DST</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Daylight_saving_time">Daylight
+ Saving Time</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ECPG</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="ecpg">Embedded C for PostgreSQL</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ESQL</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Embedded_SQL">Embedded
+ SQL</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>FAQ</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/FAQ">Frequently Asked
+ Questions</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>FSM</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="storage-fsm">Free Space Map</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>GEQO</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="geqo">Genetic Query Optimizer</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>GIN</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="gin">Generalized Inverted Index</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>GiST</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="gist">Generalized Search Tree</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>Git</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Git_(software)">Git</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>GMT</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/GMT">Greenwich Mean Time</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>GSSAPI</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface">Generic
+ Security Services Application Programming Interface</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>GUC</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="config-setting">Grand Unified Configuration</link>,
+ the <productname>PostgreSQL</productname> subsystem that handles server configuration
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>HBA</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="auth-pg-hba-conf">Host-Based Authentication</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>HOT</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="storage-hot">Heap-Only Tuples</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>IEC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/International_Electrotechnical_Commission">International
+ Electrotechnical Commission</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>IEEE</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://standards.ieee.org/">Institute of Electrical and
+ Electronics Engineers</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>IPC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Inter-process_communication">Inter-Process
+ Communication</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ISO</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://www.iso.org/home.html">International Organization for
+ Standardization</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ISSN</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Issn">International Standard
+ Serial Number</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>JDBC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Java_Database_Connectivity">Java
+ Database Connectivity</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>JIT</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Just-in-time_compilation">Just-in-Time
+ compilation</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>JSON</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://www.json.org">JavaScript Object Notation</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>LDAP</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol">Lightweight
+ Directory Access Protocol</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>LSN</acronym></term>
+ <listitem>
+ <para>
+ Log Sequence Number, see <link linkend="datatype-pg-lsn"><type>pg_lsn</type></link>
+ and <link linkend="wal-internals">WAL Internals</link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>MITM</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">
+ Man-in-the-middle attack</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>MSVC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Visual_C++"><productname>Microsoft
+ Visual C</productname></ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>MVCC</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="mvcc">Multi-Version Concurrency Control</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>NLS</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Internationalization_and_localization">National
+ Language Support</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ODBC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Open_Database_Connectivity">Open
+ Database Connectivity</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>OID</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="datatype-oid">Object Identifier</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>OLAP</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Olap">Online Analytical
+ Processing</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>OLTP</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/OLTP">Online Transaction
+ Processing</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>ORDBMS</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/ORDBMS">Object-Relational
+ Database Management System</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>PAM</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Pluggable_Authentication_Modules">Pluggable
+ Authentication Modules</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>PGSQL</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="postgres"><productname>PostgreSQL</productname></link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>PGXS</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="extend-pgxs"><productname>PostgreSQL</productname> Extension System</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>PID</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Process_identifier">Process Identifier</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>PITR</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="continuous-archiving">Point-In-Time
+ Recovery</link> (Continuous Archiving)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>PL</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="server-programming">Procedural Languages (server-side)</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>POSIX</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/POSIX">Portable Operating
+ System Interface</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>RDBMS</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Relational_database_management_system">Relational
+ Database Management System</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>RFC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Request_for_Comments">Request For
+ Comments</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SGML</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/SGML">Standard Generalized
+ Markup Language</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SNI</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Server_Name_Indication">
+ Server Name Indication</ulink>,
+ <ulink url="https://tools.ietf.org/html/rfc6066#section-3">RFC 6066</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SPI</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="spi">Server Programming Interface</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SP-GiST</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="spgist">Space-Partitioned Generalized Search Tree</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SQL</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/SQL">Structured Query Language</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SRF</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="xfunc-c-return-set">Set-Returning Function</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SSH</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Secure_Shell">Secure
+ Shell</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SSL</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Secure_Sockets_Layer">Secure Sockets Layer</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SSPI</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://msdn.microsoft.com/en-us/library/aa380493%28VS.85%29.aspx">Security
+ Support Provider Interface</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>SYSV</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/System_V">Unix System V</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>TCP/IP</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">Transmission
+ Control Protocol (TCP) / Internet Protocol (IP)</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>TID</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="datatype-oid">Tuple Identifier</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>TLS</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Transport_Layer_Security">
+ Transport Layer Security</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>TOAST</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="storage-toast">The Oversized-Attribute Storage Technique</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>TPC</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="http://www.tpc.org/">Transaction Processing
+ Performance Council</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>URL</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/URL">Uniform Resource
+ Locator</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>UTC</acronym></term>
+ <listitem>
+ <para>
+ <ulink
+ url="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">Coordinated
+ Universal Time</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>UTF</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://www.unicode.org/">Unicode Transformation
+ Format</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>UTF8</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Utf8">Eight-Bit Unicode
+ Transformation Format</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>UUID</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="datatype-uuid">Universally Unique Identifier</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>WAL</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="wal">Write-Ahead Log</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>XID</acronym></term>
+ <listitem>
+ <para>
+ <link linkend="datatype-oid">Transaction Identifier</link>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><acronym>XML</acronym></term>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/XML">Extensible Markup
+ Language</ulink>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+</appendix>
diff --git a/doc/src/sgml/adminpack.sgml b/doc/src/sgml/adminpack.sgml
new file mode 100644
index 0000000..1150b7f
--- /dev/null
+++ b/doc/src/sgml/adminpack.sgml
@@ -0,0 +1,159 @@
+<!-- doc/src/sgml/adminpack.sgml -->
+
+<sect1 id="adminpack" xreflabel="adminpack">
+ <title>adminpack</title>
+
+ <indexterm zone="adminpack">
+ <primary>adminpack</primary>
+ </indexterm>
+
+ <para>
+ <filename>adminpack</filename> provides a number of support functions which
+ <application>pgAdmin</application> and other administration and management tools can
+ use to provide additional functionality, such as remote management
+ of server log files.
+ Use of all these functions is only allowed to the superuser by default but may be
+ allowed to other users by using the <command>GRANT</command> command.
+ </para>
+
+ <para>
+ The functions shown in <xref linkend="functions-adminpack-table"/> provide
+ write access to files on the machine hosting the server. (See also the
+ functions in <xref linkend="functions-admin-genfile-table"/>, which
+ provide read-only access.)
+ Only files within the database cluster directory can be accessed, unless the
+ user is a superuser or given privileges of one of the
+ <literal>pg_read_server_files</literal> or
+ <literal>pg_write_server_files</literal> roles, as appropriate for the
+ function, but either a relative or absolute path is allowable.
+ </para>
+
+ <table id="functions-adminpack-table">
+ <title><filename>adminpack</filename> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_catalog.pg_file_write</function> ( <parameter>filename</parameter> <type>text</type>, <parameter>data</parameter> <type>text</type>, <parameter>append</parameter> <type>boolean</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Writes, or appends to, a text file.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_catalog.pg_file_sync</function> ( <parameter>filename</parameter> <type>text</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Flushes a file or directory to disk.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_catalog.pg_file_rename</function> ( <parameter>oldname</parameter> <type>text</type>, <parameter>newname</parameter> <type>text</type> <optional>, <parameter>archivename</parameter> <type>text</type> </optional> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Renames a file.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_catalog.pg_file_unlink</function> ( <parameter>filename</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Removes a file.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_catalog.pg_logdir_ls</function> ()
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Lists the log files in the <varname>log_directory</varname> directory.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <indexterm>
+ <primary>pg_file_write</primary>
+ </indexterm>
+ <para>
+ <function>pg_file_write</function> writes the specified <parameter>data</parameter> into
+ the file named by <parameter>filename</parameter>. If <parameter>append</parameter> is
+ false, the file must not already exist. If <parameter>append</parameter> is true,
+ the file can already exist, and will be appended to if so.
+ Returns the number of bytes written.
+ </para>
+
+ <indexterm>
+ <primary>pg_file_sync</primary>
+ </indexterm>
+ <para>
+ <function>pg_file_sync</function> fsyncs the specified file or directory
+ named by <parameter>filename</parameter>. An error is thrown
+ on failure (e.g., the specified file is not present). Note that
+ <xref linkend="guc-data-sync-retry"/> has no effect on this function,
+ and therefore a PANIC-level error will not be raised even on failure to
+ flush database files.
+ </para>
+
+ <indexterm>
+ <primary>pg_file_rename</primary>
+ </indexterm>
+ <para>
+ <function>pg_file_rename</function> renames a file. If <parameter>archivename</parameter>
+ is omitted or NULL, it simply renames <parameter>oldname</parameter>
+ to <parameter>newname</parameter> (which must not already exist).
+ If <parameter>archivename</parameter> is provided, it first
+ renames <parameter>newname</parameter> to <parameter>archivename</parameter> (which must
+ not already exist), and then renames <parameter>oldname</parameter>
+ to <parameter>newname</parameter>. In event of failure of the second rename step,
+ it will try to rename <parameter>archivename</parameter> back
+ to <parameter>newname</parameter> before reporting the error.
+ Returns true on success, false if the source file(s) are not present or
+ not writable; other cases throw errors.
+ </para>
+
+ <indexterm>
+ <primary>pg_file_unlink</primary>
+ </indexterm>
+ <para>
+ <function>pg_file_unlink</function> removes the specified file.
+ Returns true on success, false if the specified file is not present
+ or the <function>unlink()</function> call fails; other cases throw errors.
+ </para>
+
+ <indexterm>
+ <primary>pg_logdir_ls</primary>
+ </indexterm>
+ <para>
+ <function>pg_logdir_ls</function> returns the start timestamps and path
+ names of all the log files in the <xref linkend="guc-log-directory"/>
+ directory. The <xref linkend="guc-log-filename"/> parameter must have its
+ default setting (<literal>postgresql-%Y-%m-%d_%H%M%S.log</literal>) to use this
+ function.
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/advanced.sgml b/doc/src/sgml/advanced.sgml
new file mode 100644
index 0000000..755c9f1
--- /dev/null
+++ b/doc/src/sgml/advanced.sgml
@@ -0,0 +1,720 @@
+<!-- doc/src/sgml/advanced.sgml -->
+
+ <chapter id="tutorial-advanced">
+ <title>Advanced Features</title>
+
+ <sect1 id="tutorial-advanced-intro">
+ <title>Introduction</title>
+
+ <para>
+ In the previous chapter we have covered the basics of using
+ <acronym>SQL</acronym> to store and access your data in
+ <productname>PostgreSQL</productname>. We will now discuss some
+ more advanced features of <acronym>SQL</acronym> that simplify
+ management and prevent loss or corruption of your data. Finally,
+ we will look at some <productname>PostgreSQL</productname>
+ extensions.
+ </para>
+
+ <para>
+ This chapter will on occasion refer to examples found in <xref
+ linkend="tutorial-sql"/> to change or improve them, so it will be
+ useful to have read that chapter. Some examples from
+ this chapter can also be found in
+ <filename>advanced.sql</filename> in the tutorial directory. This
+ file also contains some sample data to load, which is not
+ repeated here. (Refer to <xref linkend="tutorial-sql-intro"/> for
+ how to use the file.)
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-views">
+ <title>Views</title>
+
+ <indexterm zone="tutorial-views">
+ <primary>view</primary>
+ </indexterm>
+
+ <para>
+ Refer back to the queries in <xref linkend="tutorial-join"/>.
+ Suppose the combined listing of weather records and city location
+ is of particular interest to your application, but you do not want
+ to type the query each time you need it. You can create a
+ <firstterm>view</firstterm> over the query, which gives a name to
+ the query that you can refer to like an ordinary table:
+
+<programlisting>
+CREATE VIEW myview AS
+ SELECT name, temp_lo, temp_hi, prcp, date, location
+ FROM weather, cities
+ WHERE city = name;
+
+SELECT * FROM myview;
+</programlisting>
+ </para>
+
+ <para>
+ Making liberal use of views is a key aspect of good SQL database
+ design. Views allow you to encapsulate the details of the
+ structure of your tables, which might change as your application
+ evolves, behind consistent interfaces.
+ </para>
+
+ <para>
+ Views can be used in almost any place a real table can be used.
+ Building views upon other views is not uncommon.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-fk">
+ <title>Foreign Keys</title>
+
+ <indexterm zone="tutorial-fk">
+ <primary>foreign key</primary>
+ </indexterm>
+
+ <indexterm zone="tutorial-fk">
+ <primary>referential integrity</primary>
+ </indexterm>
+
+ <para>
+ Recall the <classname>weather</classname> and
+ <classname>cities</classname> tables from <xref
+ linkend="tutorial-sql"/>. Consider the following problem: You
+ want to make sure that no one can insert rows in the
+ <classname>weather</classname> table that do not have a matching
+ entry in the <classname>cities</classname> table. This is called
+ maintaining the <firstterm>referential integrity</firstterm> of
+ your data. In simplistic database systems this would be
+ implemented (if at all) by first looking at the
+ <classname>cities</classname> table to check if a matching record
+ exists, and then inserting or rejecting the new
+ <classname>weather</classname> records. This approach has a
+ number of problems and is very inconvenient, so
+ <productname>PostgreSQL</productname> can do this for you.
+ </para>
+
+ <para>
+ The new declaration of the tables would look like this:
+
+<programlisting>
+CREATE TABLE cities (
+ name varchar(80) primary key,
+ location point
+);
+
+CREATE TABLE weather (
+ city varchar(80) references cities(name),
+ temp_lo int,
+ temp_hi int,
+ prcp real,
+ date date
+);
+</programlisting>
+
+ Now try inserting an invalid record:
+
+<programlisting>
+INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');
+</programlisting>
+
+<screen>
+ERROR: insert or update on table "weather" violates foreign key constraint "weather_city_fkey"
+DETAIL: Key (city)=(Berkeley) is not present in table "cities".
+</screen>
+ </para>
+
+ <para>
+ The behavior of foreign keys can be finely tuned to your
+ application. We will not go beyond this simple example in this
+ tutorial, but just refer you to <xref linkend="ddl"/>
+ for more information. Making correct use of
+ foreign keys will definitely improve the quality of your database
+ applications, so you are strongly encouraged to learn about them.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-transactions">
+ <title>Transactions</title>
+
+ <indexterm zone="tutorial-transactions">
+ <primary>transaction</primary>
+ </indexterm>
+
+ <para>
+ <firstterm>Transactions</firstterm> are a fundamental concept of all database
+ systems. The essential point of a transaction is that it bundles
+ multiple steps into a single, all-or-nothing operation. The intermediate
+ states between the steps are not visible to other concurrent transactions,
+ and if some failure occurs that prevents the transaction from completing,
+ then none of the steps affect the database at all.
+ </para>
+
+ <para>
+ For example, consider a bank database that contains balances for various
+ customer accounts, as well as total deposit balances for branches.
+ Suppose that we want to record a payment of $100.00 from Alice's account
+ to Bob's account. Simplifying outrageously, the SQL commands for this
+ might look like:
+
+<programlisting>
+UPDATE accounts SET balance = balance - 100.00
+ WHERE name = 'Alice';
+UPDATE branches SET balance = balance - 100.00
+ WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice');
+UPDATE accounts SET balance = balance + 100.00
+ WHERE name = 'Bob';
+UPDATE branches SET balance = balance + 100.00
+ WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob');
+</programlisting>
+ </para>
+
+ <para>
+ The details of these commands are not important here; the important
+ point is that there are several separate updates involved to accomplish
+ this rather simple operation. Our bank's officers will want to be
+ assured that either all these updates happen, or none of them happen.
+ It would certainly not do for a system failure to result in Bob
+ receiving $100.00 that was not debited from Alice. Nor would Alice long
+ remain a happy customer if she was debited without Bob being credited.
+ We need a guarantee that if something goes wrong partway through the
+ operation, none of the steps executed so far will take effect. Grouping
+ the updates into a <firstterm>transaction</firstterm> gives us this guarantee.
+ A transaction is said to be <firstterm>atomic</firstterm>: from the point of
+ view of other transactions, it either happens completely or not at all.
+ </para>
+
+ <para>
+ We also want a
+ guarantee that once a transaction is completed and acknowledged by
+ the database system, it has indeed been permanently recorded
+ and won't be lost even if a crash ensues shortly thereafter.
+ For example, if we are recording a cash withdrawal by Bob,
+ we do not want any chance that the debit to his account will
+ disappear in a crash just after he walks out the bank door.
+ A transactional database guarantees that all the updates made by
+ a transaction are logged in permanent storage (i.e., on disk) before
+ the transaction is reported complete.
+ </para>
+
+ <para>
+ Another important property of transactional databases is closely
+ related to the notion of atomic updates: when multiple transactions
+ are running concurrently, each one should not be able to see the
+ incomplete changes made by others. For example, if one transaction
+ is busy totalling all the branch balances, it would not do for it
+ to include the debit from Alice's branch but not the credit to
+ Bob's branch, nor vice versa. So transactions must be all-or-nothing
+ not only in terms of their permanent effect on the database, but
+ also in terms of their visibility as they happen. The updates made
+ so far by an open transaction are invisible to other transactions
+ until the transaction completes, whereupon all the updates become
+ visible simultaneously.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname>, a transaction is set up by surrounding
+ the SQL commands of the transaction with
+ <command>BEGIN</command> and <command>COMMIT</command> commands. So our banking
+ transaction would actually look like:
+
+<programlisting>
+BEGIN;
+UPDATE accounts SET balance = balance - 100.00
+ WHERE name = 'Alice';
+-- etc etc
+COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ If, partway through the transaction, we decide we do not want to
+ commit (perhaps we just noticed that Alice's balance went negative),
+ we can issue the command <command>ROLLBACK</command> instead of
+ <command>COMMIT</command>, and all our updates so far will be canceled.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> actually treats every SQL statement as being
+ executed within a transaction. If you do not issue a <command>BEGIN</command>
+ command,
+ then each individual statement has an implicit <command>BEGIN</command> and
+ (if successful) <command>COMMIT</command> wrapped around it. A group of
+ statements surrounded by <command>BEGIN</command> and <command>COMMIT</command>
+ is sometimes called a <firstterm>transaction block</firstterm>.
+ </para>
+
+ <note>
+ <para>
+ Some client libraries issue <command>BEGIN</command> and <command>COMMIT</command>
+ commands automatically, so that you might get the effect of transaction
+ blocks without asking. Check the documentation for the interface
+ you are using.
+ </para>
+ </note>
+
+ <para>
+ It's possible to control the statements in a transaction in a more
+ granular fashion through the use of <firstterm>savepoints</firstterm>. Savepoints
+ allow you to selectively discard parts of the transaction, while
+ committing the rest. After defining a savepoint with
+ <command>SAVEPOINT</command>, you can if needed roll back to the savepoint
+ with <command>ROLLBACK TO</command>. All the transaction's database changes
+ between defining the savepoint and rolling back to it are discarded, but
+ changes earlier than the savepoint are kept.
+ </para>
+
+ <para>
+ After rolling back to a savepoint, it continues to be defined, so you can
+ roll back to it several times. Conversely, if you are sure you won't need
+ to roll back to a particular savepoint again, it can be released, so the
+ system can free some resources. Keep in mind that either releasing or
+ rolling back to a savepoint
+ will automatically release all savepoints that were defined after it.
+ </para>
+
+ <para>
+ All this is happening within the transaction block, so none of it
+ is visible to other database sessions. When and if you commit the
+ transaction block, the committed actions become visible as a unit
+ to other sessions, while the rolled-back actions never become visible
+ at all.
+ </para>
+
+ <para>
+ Remembering the bank database, suppose we debit $100.00 from Alice's
+ account, and credit Bob's account, only to find later that we should
+ have credited Wally's account. We could do it using savepoints like
+ this:
+
+<programlisting>
+BEGIN;
+UPDATE accounts SET balance = balance - 100.00
+ WHERE name = 'Alice';
+SAVEPOINT my_savepoint;
+UPDATE accounts SET balance = balance + 100.00
+ WHERE name = 'Bob';
+-- oops ... forget that and use Wally's account
+ROLLBACK TO my_savepoint;
+UPDATE accounts SET balance = balance + 100.00
+ WHERE name = 'Wally';
+COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ This example is, of course, oversimplified, but there's a lot of control
+ possible in a transaction block through the use of savepoints.
+ Moreover, <command>ROLLBACK TO</command> is the only way to regain control of a
+ transaction block that was put in aborted state by the
+ system due to an error, short of rolling it back completely and starting
+ again.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="tutorial-window">
+ <title>Window Functions</title>
+
+ <indexterm zone="tutorial-window">
+ <primary>window function</primary>
+ </indexterm>
+
+ <para>
+ A <firstterm>window function</firstterm> performs a calculation across a set of
+ table rows that are somehow related to the current row. This is comparable
+ to the type of calculation that can be done with an aggregate function.
+ However, window functions do not cause rows to become grouped into a single
+ output row like non-window aggregate calls would. Instead, the
+ rows retain their separate identities. Behind the scenes, the window
+ function is able to access more than just the current row of the query
+ result.
+ </para>
+
+ <para>
+ Here is an example that shows how to compare each employee's salary
+ with the average salary in his or her department:
+
+<programlisting>
+SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
+</programlisting>
+
+<screen>
+ depname | empno | salary | avg
+-----------+-------+--------+-----------------------
+ develop | 11 | 5200 | 5020.0000000000000000
+ develop | 7 | 4200 | 5020.0000000000000000
+ develop | 9 | 4500 | 5020.0000000000000000
+ develop | 8 | 6000 | 5020.0000000000000000
+ develop | 10 | 5200 | 5020.0000000000000000
+ personnel | 5 | 3500 | 3700.0000000000000000
+ personnel | 2 | 3900 | 3700.0000000000000000
+ sales | 3 | 4800 | 4866.6666666666666667
+ sales | 1 | 5000 | 4866.6666666666666667
+ sales | 4 | 4800 | 4866.6666666666666667
+(10 rows)
+</screen>
+
+ The first three output columns come directly from the table
+ <structname>empsalary</structname>, and there is one output row for each row in the
+ table. The fourth column represents an average taken across all the table
+ rows that have the same <structfield>depname</structfield> value as the current row.
+ (This actually is the same function as the non-window <function>avg</function>
+ aggregate, but the <literal>OVER</literal> clause causes it to be
+ treated as a window function and computed across the window frame.)
+ </para>
+
+ <para>
+ A window function call always contains an <literal>OVER</literal> clause
+ directly following the window function's name and argument(s). This is what
+ syntactically distinguishes it from a normal function or non-window
+ aggregate. The <literal>OVER</literal> clause determines exactly how the
+ rows of the query are split up for processing by the window function.
+ The <literal>PARTITION BY</literal> clause within <literal>OVER</literal>
+ divides the rows into groups, or partitions, that share the same
+ values of the <literal>PARTITION BY</literal> expression(s). For each row,
+ the window function is computed across the rows that fall into the
+ same partition as the current row.
+ </para>
+
+ <para>
+ You can also control the order in which rows are processed by
+ window functions using <literal>ORDER BY</literal> within <literal>OVER</literal>.
+ (The window <literal>ORDER BY</literal> does not even have to match the
+ order in which the rows are output.) Here is an example:
+
+<programlisting>
+SELECT depname, empno, salary,
+ rank() OVER (PARTITION BY depname ORDER BY salary DESC)
+FROM empsalary;
+</programlisting>
+
+<screen>
+ depname | empno | salary | rank
+-----------+-------+--------+------
+ develop | 8 | 6000 | 1
+ develop | 10 | 5200 | 2
+ develop | 11 | 5200 | 2
+ develop | 9 | 4500 | 4
+ develop | 7 | 4200 | 5
+ personnel | 2 | 3900 | 1
+ personnel | 5 | 3500 | 2
+ sales | 1 | 5000 | 1
+ sales | 4 | 4800 | 2
+ sales | 3 | 4800 | 2
+(10 rows)
+</screen>
+
+ As shown here, the <function>rank</function> function produces a numerical rank
+ for each distinct <literal>ORDER BY</literal> value in the current row's
+ partition, using the order defined by the <literal>ORDER BY</literal> clause.
+ <function>rank</function> needs no explicit parameter, because its behavior
+ is entirely determined by the <literal>OVER</literal> clause.
+ </para>
+
+ <para>
+ The rows considered by a window function are those of the <quote>virtual
+ table</quote> produced by the query's <literal>FROM</literal> clause as filtered by its
+ <literal>WHERE</literal>, <literal>GROUP BY</literal>, and <literal>HAVING</literal> clauses
+ if any. For example, a row removed because it does not meet the
+ <literal>WHERE</literal> condition is not seen by any window function.
+ A query can contain multiple window functions that slice up the data
+ in different ways using different <literal>OVER</literal> clauses, but
+ they all act on the same collection of rows defined by this virtual table.
+ </para>
+
+ <para>
+ We already saw that <literal>ORDER BY</literal> can be omitted if the ordering
+ of rows is not important. It is also possible to omit <literal>PARTITION
+ BY</literal>, in which case there is a single partition containing all rows.
+ </para>
+
+ <para>
+ There is another important concept associated with window functions:
+ for each row, there is a set of rows within its partition called its
+ <firstterm>window frame</firstterm>. Some window functions act only
+ on the rows of the window frame, rather than of the whole partition.
+ By default, if <literal>ORDER BY</literal> is supplied then the frame consists of
+ all rows from the start of the partition up through the current row, plus
+ any following rows that are equal to the current row according to the
+ <literal>ORDER BY</literal> clause. When <literal>ORDER BY</literal> is omitted the
+ default frame consists of all rows in the partition.
+ <footnote>
+ <para>
+ There are options to define the window frame in other ways, but
+ this tutorial does not cover them. See
+ <xref linkend="syntax-window-functions"/> for details.
+ </para>
+ </footnote>
+ Here is an example using <function>sum</function>:
+ </para>
+
+<programlisting>
+SELECT salary, sum(salary) OVER () FROM empsalary;
+</programlisting>
+
+<screen>
+ salary | sum
+--------+-------
+ 5200 | 47100
+ 5000 | 47100
+ 3500 | 47100
+ 4800 | 47100
+ 3900 | 47100
+ 4200 | 47100
+ 4500 | 47100
+ 4800 | 47100
+ 6000 | 47100
+ 5200 | 47100
+(10 rows)
+</screen>
+
+ <para>
+ Above, since there is no <literal>ORDER BY</literal> in the <literal>OVER</literal>
+ clause, the window frame is the same as the partition, which for lack of
+ <literal>PARTITION BY</literal> is the whole table; in other words each sum is
+ taken over the whole table and so we get the same result for each output
+ row. But if we add an <literal>ORDER BY</literal> clause, we get very different
+ results:
+ </para>
+
+<programlisting>
+SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
+</programlisting>
+
+<screen>
+ salary | sum
+--------+-------
+ 3500 | 3500
+ 3900 | 7400
+ 4200 | 11600
+ 4500 | 16100
+ 4800 | 25700
+ 4800 | 25700
+ 5000 | 30700
+ 5200 | 41100
+ 5200 | 41100
+ 6000 | 47100
+(10 rows)
+</screen>
+
+ <para>
+ Here the sum is taken from the first (lowest) salary up through the
+ current one, including any duplicates of the current one (notice the
+ results for the duplicated salaries).
+ </para>
+
+ <para>
+ Window functions are permitted only in the <literal>SELECT</literal> list
+ and the <literal>ORDER BY</literal> clause of the query. They are forbidden
+ elsewhere, such as in <literal>GROUP BY</literal>, <literal>HAVING</literal>
+ and <literal>WHERE</literal> clauses. This is because they logically
+ execute after the processing of those clauses. Also, window functions
+ execute after non-window aggregate functions. This means it is valid to
+ include an aggregate function call in the arguments of a window function,
+ but not vice versa.
+ </para>
+
+ <para>
+ If there is a need to filter or group rows after the window calculations
+ are performed, you can use a sub-select. For example:
+
+<programlisting>
+SELECT depname, empno, salary, enroll_date
+FROM
+ (SELECT depname, empno, salary, enroll_date,
+ rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos
+ FROM empsalary
+ ) AS ss
+WHERE pos &lt; 3;
+</programlisting>
+
+ The above query only shows the rows from the inner query having
+ <literal>rank</literal> less than 3.
+ </para>
+
+ <para>
+ When a query involves multiple window functions, it is possible to write
+ out each one with a separate <literal>OVER</literal> clause, but this is
+ duplicative and error-prone if the same windowing behavior is wanted
+ for several functions. Instead, each windowing behavior can be named
+ in a <literal>WINDOW</literal> clause and then referenced in <literal>OVER</literal>.
+ For example:
+
+<programlisting>
+SELECT sum(salary) OVER w, avg(salary) OVER w
+ FROM empsalary
+ WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
+</programlisting>
+ </para>
+
+ <para>
+ More details about window functions can be found in
+ <xref linkend="syntax-window-functions"/>,
+ <xref linkend="functions-window"/>,
+ <xref linkend="queries-window"/>, and the
+ <xref linkend="sql-select"/> reference page.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-inheritance">
+ <title>Inheritance</title>
+
+ <indexterm zone="tutorial-inheritance">
+ <primary>inheritance</primary>
+ </indexterm>
+
+ <para>
+ Inheritance is a concept from object-oriented databases. It opens
+ up interesting new possibilities of database design.
+ </para>
+
+ <para>
+ Let's create two tables: A table <classname>cities</classname>
+ and a table <classname>capitals</classname>. Naturally, capitals
+ are also cities, so you want some way to show the capitals
+ implicitly when you list all cities. If you're really clever you
+ might invent some scheme like this:
+
+<programlisting>
+CREATE TABLE capitals (
+ name text,
+ population real,
+ elevation int, -- (in ft)
+ state char(2)
+);
+
+CREATE TABLE non_capitals (
+ name text,
+ population real,
+ elevation int -- (in ft)
+);
+
+CREATE VIEW cities AS
+ SELECT name, population, elevation FROM capitals
+ UNION
+ SELECT name, population, elevation FROM non_capitals;
+</programlisting>
+
+ This works OK as far as querying goes, but it gets ugly when you
+ need to update several rows, for one thing.
+ </para>
+
+ <para>
+ A better solution is this:
+
+<programlisting>
+CREATE TABLE cities (
+ name text,
+ population real,
+ elevation int -- (in ft)
+);
+
+CREATE TABLE capitals (
+ state char(2) UNIQUE NOT NULL
+) INHERITS (cities);
+</programlisting>
+ </para>
+
+ <para>
+ In this case, a row of <classname>capitals</classname>
+ <firstterm>inherits</firstterm> all columns (<structfield>name</structfield>,
+ <structfield>population</structfield>, and <structfield>elevation</structfield>) from its
+ <firstterm>parent</firstterm>, <classname>cities</classname>. The
+ type of the column <structfield>name</structfield> is
+ <type>text</type>, a native <productname>PostgreSQL</productname>
+ type for variable length character strings. The
+ <classname>capitals</classname> table has
+ an additional column, <structfield>state</structfield>, which shows its
+ state abbreviation. In
+ <productname>PostgreSQL</productname>, a table can inherit from
+ zero or more other tables.
+ </para>
+
+ <para>
+ For example, the following query finds the names of all cities,
+ including state capitals, that are located at an elevation
+ over 500 feet:
+
+<programlisting>
+SELECT name, elevation
+ FROM cities
+ WHERE elevation &gt; 500;
+</programlisting>
+
+ which returns:
+
+<screen>
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+ Madison | 845
+(3 rows)
+</screen>
+ </para>
+
+ <para>
+ On the other hand, the following query finds
+ all the cities that are not state capitals and
+ are situated at an elevation over 500 feet:
+
+<programlisting>
+SELECT name, elevation
+ FROM ONLY cities
+ WHERE elevation &gt; 500;
+</programlisting>
+
+<screen>
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+(2 rows)
+</screen>
+ </para>
+
+ <para>
+ Here the <literal>ONLY</literal> before <literal>cities</literal>
+ indicates that the query should be run over only the
+ <classname>cities</classname> table, and not tables below
+ <classname>cities</classname> in the inheritance hierarchy. Many
+ of the commands that we have already discussed &mdash;
+ <command>SELECT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> &mdash; support this <literal>ONLY</literal>
+ notation.
+ </para>
+
+ <note>
+ <para>
+ Although inheritance is frequently useful, it has not been integrated
+ with unique constraints or foreign keys, which limits its usefulness.
+ See <xref linkend="ddl-inherit"/> for more detail.
+ </para>
+ </note>
+ </sect1>
+
+
+ <sect1 id="tutorial-conclusion">
+ <title>Conclusion</title>
+
+ <para>
+ <productname>PostgreSQL</productname> has many features not
+ touched upon in this tutorial introduction, which has been
+ oriented toward newer users of <acronym>SQL</acronym>. These
+ features are discussed in more detail in the remainder of this
+ book.
+ </para>
+
+ <para>
+ If you feel you need more introductory material, please visit the PostgreSQL
+ <ulink url="https://www.postgresql.org">web site</ulink>
+ for links to more resources.
+ </para>
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/amcheck.sgml b/doc/src/sgml/amcheck.sgml
new file mode 100644
index 0000000..5d61a33
--- /dev/null
+++ b/doc/src/sgml/amcheck.sgml
@@ -0,0 +1,558 @@
+<!-- doc/src/sgml/amcheck.sgml -->
+
+<sect1 id="amcheck" xreflabel="amcheck">
+ <title>amcheck</title>
+
+ <indexterm zone="amcheck">
+ <primary>amcheck</primary>
+ </indexterm>
+
+ <para>
+ The <filename>amcheck</filename> module provides functions that allow you to
+ verify the logical consistency of the structure of relations.
+ </para>
+
+ <para>
+ The B-Tree checking functions verify various <emphasis>invariants</emphasis> in the
+ structure of the representation of particular relations. The
+ correctness of the access method functions behind index scans and
+ other important operations relies on these invariants always
+ holding. For example, certain functions verify, among other things,
+ that all B-Tree pages have items in <quote>logical</quote> order (e.g.,
+ for B-Tree indexes on <type>text</type>, index tuples should be in
+ collated lexical order). If that particular invariant somehow fails
+ to hold, we can expect binary searches on the affected page to
+ incorrectly guide index scans, resulting in wrong answers to SQL
+ queries. If the structure appears to be valid, no error is raised.
+ </para>
+ <para>
+ Verification is performed using the same procedures as those used by
+ index scans themselves, which may be user-defined operator class
+ code. For example, B-Tree index verification relies on comparisons
+ made with one or more B-Tree support function 1 routines. See <xref
+ linkend="xindex-support"/> for details of operator class support
+ functions.
+ </para>
+ <para>
+ Unlike the B-Tree checking functions which report corruption by raising
+ errors, the heap checking function <function>verify_heapam</function> checks
+ a table and attempts to return a set of rows, one row per corruption
+ detected. Despite this, if facilities that
+ <function>verify_heapam</function> relies upon are themselves corrupted, the
+ function may be unable to continue and may instead raise an error.
+ </para>
+ <para>
+ Permission to execute <filename>amcheck</filename> functions may be granted
+ to non-superusers, but before granting such permissions careful consideration
+ should be given to data security and privacy concerns. Although the
+ corruption reports generated by these functions do not focus on the contents
+ of the corrupted data so much as on the structure of that data and the nature
+ of the corruptions found, an attacker who gains permission to execute these
+ functions, particularly if the attacker can also induce corruption, might be
+ able to infer something of the data itself from such messages.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>bt_index_check(index regclass, heapallindexed boolean) returns void</function>
+ <indexterm>
+ <primary>bt_index_check</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>bt_index_check</function> tests that its target, a
+ B-Tree index, respects a variety of invariants. Example usage:
+<screen>
+test=# SELECT bt_index_check(index =&gt; c.oid, heapallindexed =&gt; i.indisunique),
+ c.relname,
+ c.relpages
+FROM pg_index i
+JOIN pg_opclass op ON i.indclass[0] = op.oid
+JOIN pg_am am ON op.opcmethod = am.oid
+JOIN pg_class c ON i.indexrelid = c.oid
+JOIN pg_namespace n ON c.relnamespace = n.oid
+WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog'
+-- Don't check temp tables, which may be from another session:
+AND c.relpersistence != 't'
+-- Function may throw an error when this is omitted:
+AND c.relkind = 'i' AND i.indisready AND i.indisvalid
+ORDER BY c.relpages DESC LIMIT 10;
+ bt_index_check | relname | relpages
+----------------+---------------------------------+----------
+ | pg_depend_reference_index | 43
+ | pg_depend_depender_index | 40
+ | pg_proc_proname_args_nsp_index | 31
+ | pg_description_o_c_o_index | 21
+ | pg_attribute_relid_attnam_index | 14
+ | pg_proc_oid_index | 10
+ | pg_attribute_relid_attnum_index | 9
+ | pg_amproc_fam_proc_index | 5
+ | pg_amop_opr_fam_index | 5
+ | pg_amop_fam_strat_index | 5
+(10 rows)
+</screen>
+ This example shows a session that performs verification of the
+ 10 largest catalog indexes in the database <quote>test</quote>.
+ Verification of the presence of heap tuples as index tuples is
+ requested for the subset that are unique indexes. Since no
+ error is raised, all indexes tested appear to be logically
+ consistent. Naturally, this query could easily be changed to
+ call <function>bt_index_check</function> for every index in the
+ database where verification is supported.
+ </para>
+ <para>
+ <function>bt_index_check</function> acquires an <literal>AccessShareLock</literal>
+ on the target index and the heap relation it belongs to. This lock mode
+ is the same lock mode acquired on relations by simple
+ <literal>SELECT</literal> statements.
+ <function>bt_index_check</function> does not verify invariants
+ that span child/parent relationships, but will verify the
+ presence of all heap tuples as index tuples within the index
+ when <parameter>heapallindexed</parameter> is
+ <literal>true</literal>. When a routine, lightweight test for
+ corruption is required in a live production environment, using
+ <function>bt_index_check</function> often provides the best
+ trade-off between thoroughness of verification and limiting the
+ impact on application performance and availability.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void</function>
+ <indexterm>
+ <primary>bt_index_parent_check</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>bt_index_parent_check</function> tests that its
+ target, a B-Tree index, respects a variety of invariants.
+ Optionally, when the <parameter>heapallindexed</parameter>
+ argument is <literal>true</literal>, the function verifies the
+ presence of all heap tuples that should be found within the
+ index. When the optional <parameter>rootdescend</parameter>
+ argument is <literal>true</literal>, verification re-finds
+ tuples on the leaf level by performing a new search from the
+ root page for each tuple. The checks that can be performed by
+ <function>bt_index_parent_check</function> are a superset of the
+ checks that can be performed by <function>bt_index_check</function>.
+ <function>bt_index_parent_check</function> can be thought of as
+ a more thorough variant of <function>bt_index_check</function>:
+ unlike <function>bt_index_check</function>,
+ <function>bt_index_parent_check</function> also checks
+ invariants that span parent/child relationships, including checking
+ that there are no missing downlinks in the index structure.
+ <function>bt_index_parent_check</function> follows the general
+ convention of raising an error if it finds a logical
+ inconsistency or other problem.
+ </para>
+ <para>
+ A <literal>ShareLock</literal> is required on the target index by
+ <function>bt_index_parent_check</function> (a
+ <literal>ShareLock</literal> is also acquired on the heap relation).
+ These locks prevent concurrent data modification from
+ <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command>
+ commands. The locks also prevent the underlying relation from
+ being concurrently processed by <command>VACUUM</command>, as well as
+ all other utility commands. Note that the function holds locks
+ only while running, not for the entire transaction.
+ </para>
+ <para>
+ <function>bt_index_parent_check</function>'s additional
+ verification is more likely to detect various pathological
+ cases. These cases may involve an incorrectly implemented
+ B-Tree operator class used by the index that is checked, or,
+ hypothetically, undiscovered bugs in the underlying B-Tree index
+ access method code. Note that
+ <function>bt_index_parent_check</function> cannot be used when
+ hot standby mode is enabled (i.e., on read-only physical
+ replicas), unlike <function>bt_index_check</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <tip>
+ <para>
+ <function>bt_index_check</function> and
+ <function>bt_index_parent_check</function> both output log
+ messages about the verification process at
+ <literal>DEBUG1</literal> and <literal>DEBUG2</literal> severity
+ levels. These messages provide detailed information about the
+ verification process that may be of interest to
+ <productname>PostgreSQL</productname> developers. Advanced users
+ may also find this information helpful, since it provides
+ additional context should verification actually detect an
+ inconsistency. Running:
+<programlisting>
+SET client_min_messages = DEBUG1;
+</programlisting>
+ in an interactive <application>psql</application> session before
+ running a verification query will display messages about the
+ progress of verification with a manageable level of detail.
+ </para>
+ </tip>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>
+ verify_heapam(relation regclass,
+ on_error_stop boolean,
+ check_toast boolean,
+ skip text,
+ startblock bigint,
+ endblock bigint,
+ blkno OUT bigint,
+ offnum OUT integer,
+ attnum OUT integer,
+ msg OUT text)
+ returns setof record
+ </function>
+ </term>
+ <listitem>
+ <para>
+ Checks a table, sequence, or materialized view for structural corruption,
+ where pages in the relation contain data that is invalidly formatted, and
+ for logical corruption, where pages are structurally valid but
+ inconsistent with the rest of the database cluster.
+ </para>
+ <para>
+ The following optional arguments are recognized:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>on_error_stop</literal></term>
+ <listitem>
+ <para>
+ If true, corruption checking stops at the end of the first block in
+ which any corruptions are found.
+ </para>
+ <para>
+ Defaults to false.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>check_toast</literal></term>
+ <listitem>
+ <para>
+ If true, toasted values are checked against the target relation's
+ TOAST table.
+ </para>
+ <para>
+ This option is known to be slow. Also, if the toast table or its
+ index is corrupt, checking it against toast values could conceivably
+ crash the server, although in many cases this would just produce an
+ error.
+ </para>
+ <para>
+ Defaults to false.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>skip</literal></term>
+ <listitem>
+ <para>
+ If not <literal>none</literal>, corruption checking skips blocks that
+ are marked as all-visible or all-frozen, as specified.
+ Valid options are <literal>all-visible</literal>,
+ <literal>all-frozen</literal> and <literal>none</literal>.
+ </para>
+ <para>
+ Defaults to <literal>none</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>startblock</literal></term>
+ <listitem>
+ <para>
+ If specified, corruption checking begins at the specified block,
+ skipping all previous blocks. It is an error to specify a
+ <parameter>startblock</parameter> outside the range of blocks in the
+ target table.
+ </para>
+ <para>
+ By default, checking begins at the first block.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>endblock</literal></term>
+ <listitem>
+ <para>
+ If specified, corruption checking ends at the specified block,
+ skipping all remaining blocks. It is an error to specify an
+ <parameter>endblock</parameter> outside the range of blocks in the target
+ table.
+ </para>
+ <para>
+ By default, all blocks are checked.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ For each corruption detected, <function>verify_heapam</function> returns
+ a row with the following columns:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>blkno</literal></term>
+ <listitem>
+ <para>
+ The number of the block containing the corrupt page.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>offnum</literal></term>
+ <listitem>
+ <para>
+ The OffsetNumber of the corrupt tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>attnum</literal></term>
+ <listitem>
+ <para>
+ The attribute number of the corrupt column in the tuple, if the
+ corruption is specific to a column and not the tuple as a whole.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>msg</literal></term>
+ <listitem>
+ <para>
+ A message describing the problem detected.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Optional <parameter>heapallindexed</parameter> Verification</title>
+ <para>
+ When the <parameter>heapallindexed</parameter> argument to B-Tree
+ verification functions is <literal>true</literal>, an additional
+ phase of verification is performed against the table associated with
+ the target index relation. This consists of a <quote>dummy</quote>
+ <command>CREATE INDEX</command> operation, which checks for the
+ presence of all hypothetical new index tuples against a temporary,
+ in-memory summarizing structure (this is built when needed during
+ the basic first phase of verification). The summarizing structure
+ <quote>fingerprints</quote> every tuple found within the target
+ index. The high level principle behind
+ <parameter>heapallindexed</parameter> verification is that a new
+ index that is equivalent to the existing, target index must only
+ have entries that can be found in the existing structure.
+ </para>
+ <para>
+ The additional <parameter>heapallindexed</parameter> phase adds
+ significant overhead: verification will typically take several times
+ longer. However, there is no change to the relation-level locks
+ acquired when <parameter>heapallindexed</parameter> verification is
+ performed.
+ </para>
+ <para>
+ The summarizing structure is bound in size by
+ <varname>maintenance_work_mem</varname>. In order to ensure that
+ there is no more than a 2% probability of failure to detect an
+ inconsistency for each heap tuple that should be represented in the
+ index, approximately 2 bytes of memory are needed per tuple. As
+ less memory is made available per tuple, the probability of missing
+ an inconsistency slowly increases. This approach limits the
+ overhead of verification significantly, while only slightly reducing
+ the probability of detecting a problem, especially for installations
+ where verification is treated as a routine maintenance task. Any
+ single absent or malformed tuple has a new opportunity to be
+ detected with each new verification attempt.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Using <filename>amcheck</filename> Effectively</title>
+
+ <para>
+ <filename>amcheck</filename> can be effective at detecting various types of
+ failure modes that <link
+ linkend="app-initdb-data-checksums"><application>data
+ checksums</application></link> will fail to catch. These include:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Structural inconsistencies caused by incorrect operator class
+ implementations.
+ </para>
+ <para>
+ This includes issues caused by the comparison rules of operating
+ system collations changing. Comparisons of datums of a collatable
+ type like <type>text</type> must be immutable (just as all
+ comparisons used for B-Tree index scans must be immutable), which
+ implies that operating system collation rules must never change.
+ Though rare, updates to operating system collation rules can
+ cause these issues. More commonly, an inconsistency in the
+ collation order between a primary server and a standby server is
+ implicated, possibly because the <emphasis>major</emphasis> operating
+ system version in use is inconsistent. Such inconsistencies will
+ generally only arise on standby servers, and so can generally
+ only be detected on standby servers.
+ </para>
+ <para>
+ If a problem like this arises, it may not affect each individual
+ index that is ordered using an affected collation, simply because
+ <emphasis>indexed</emphasis> values might happen to have the same
+ absolute ordering regardless of the behavioral inconsistency. See
+ <xref linkend="locale"/> and <xref linkend="collation"/> for
+ further details about how <productname>PostgreSQL</productname> uses
+ operating system locales and collations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Structural inconsistencies between indexes and the heap relations
+ that are indexed (when <parameter>heapallindexed</parameter>
+ verification is performed).
+ </para>
+ <para>
+ There is no cross-checking of indexes against their heap relation
+ during normal operation. Symptoms of heap corruption can be subtle.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Corruption caused by hypothetical undiscovered bugs in the
+ underlying <productname>PostgreSQL</productname> access method
+ code, sort code, or transaction management code.
+ </para>
+ <para>
+ Automatic verification of the structural integrity of indexes
+ plays a role in the general testing of new or proposed
+ <productname>PostgreSQL</productname> features that could plausibly allow a
+ logical inconsistency to be introduced. Verification of table
+ structure and associated visibility and transaction status
+ information plays a similar role. One obvious testing strategy
+ is to call <filename>amcheck</filename> functions continuously
+ when running the standard regression tests. See <xref
+ linkend="regress-run"/> for details on running the tests.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ File system or storage subsystem faults where checksums happen to
+ simply not be enabled.
+ </para>
+ <para>
+ Note that <filename>amcheck</filename> examines a page as represented in some
+ shared memory buffer at the time of verification if there is only a
+ shared buffer hit when accessing the block. Consequently,
+ <filename>amcheck</filename> does not necessarily examine data read from the
+ file system at the time of verification. Note that when checksums are
+ enabled, <filename>amcheck</filename> may raise an error due to a checksum
+ failure when a corrupt block is read into a buffer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Corruption caused by faulty RAM, or the broader memory subsystem.
+ </para>
+ <para>
+ <productname>PostgreSQL</productname> does not protect against correctable
+ memory errors and it is assumed you will operate using RAM that
+ uses industry standard Error Correcting Codes (ECC) or better
+ protection. However, ECC memory is typically only immune to
+ single-bit errors, and should not be assumed to provide
+ <emphasis>absolute</emphasis> protection against failures that
+ result in memory corruption.
+ </para>
+ <para>
+ When <parameter>heapallindexed</parameter> verification is
+ performed, there is generally a greatly increased chance of
+ detecting single-bit errors, since strict binary equality is
+ tested, and the indexed attributes within the heap are tested.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Structural corruption can happen due to faulty storage hardware, or
+ relation files being overwritten or modified by unrelated software.
+ This kind of corruption can also be detected with
+ <link linkend="checksums"><application>data page
+ checksums</application></link>.
+ </para>
+
+ <para>
+ Relation pages which are correctly formatted, internally consistent, and
+ correct relative to their own internal checksums may still contain
+ logical corruption. As such, this kind of corruption cannot be detected
+ with <application>checksums</application>. Examples include toasted
+ values in the main table which lack a corresponding entry in the toast
+ table, and tuples in the main table with a Transaction ID that is older
+ than the oldest valid Transaction ID in the database or cluster.
+ </para>
+
+ <para>
+ Multiple causes of logical corruption have been observed in production
+ systems, including bugs in the <productname>PostgreSQL</productname>
+ server software, faulty and ill-conceived backup and restore tools, and
+ user error.
+ </para>
+
+ <para>
+ Corrupt relations are most concerning in live production environments,
+ precisely the same environments where high risk activities are least
+ welcome. For this reason, <function>verify_heapam</function> has been
+ designed to diagnose corruption without undue risk. It cannot guard
+ against all causes of backend crashes, as even executing the calling
+ query could be unsafe on a badly corrupted system. Access to <link
+ linkend="catalogs-overview">catalog tables</link> is performed and could
+ be problematic if the catalogs themselves are corrupted.
+ </para>
+
+ <para>
+ In general, <filename>amcheck</filename> can only prove the presence of
+ corruption; it cannot prove its absence.
+ </para>
+
+ </sect2>
+ <sect2>
+ <title>Repairing Corruption</title>
+ <para>
+ No error concerning corruption raised by <filename>amcheck</filename> should
+ ever be a false positive. <filename>amcheck</filename> raises
+ errors in the event of conditions that, by definition, should never
+ happen, and so careful analysis of <filename>amcheck</filename>
+ errors is often required.
+ </para>
+ <para>
+ There is no general method of repairing problems that
+ <filename>amcheck</filename> detects. An explanation for the root cause of
+ an invariant violation should be sought. <xref
+ linkend="pageinspect"/> may play a useful role in diagnosing
+ corruption that <filename>amcheck</filename> detects. A <command>REINDEX</command>
+ may not be effective in repairing corruption.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete-default-roles.sgml b/doc/src/sgml/appendix-obsolete-default-roles.sgml
new file mode 100644
index 0000000..f5133f9
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete-default-roles.sgml
@@ -0,0 +1,22 @@
+<!-- doc/src/sgml/appendix-obsolete-default-roles.sgml -->
+<!--
+ See doc/src/sgml/appendix-obsolete.sgml for why this file exists. Do not change the id attribute.
+-->
+
+<sect1 id="default-roles" xreflabel="default-roles">
+ <title>Default Roles Renamed to Predefined Roles</title>
+
+ <indexterm>
+ <primary>default-roles</primary>
+ </indexterm>
+
+ <para>
+ PostgreSQL 13 and below used the term <quote>Default Roles</quote>. However, as these
+ roles are not able to actually be changed and are installed as part of the
+ system at initialization time, the more appropriate term to use is <quote>Predefined Roles</quote>.
+ See <xref linkend="predefined-roles"/> for current documentation regarding
+ Predefined Roles, and <link linkend="release-prior">the release notes for
+ PostgreSQL 14</link> for details on this change.
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml b/doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml
new file mode 100644
index 0000000..d84412d
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml
@@ -0,0 +1,24 @@
+<!-- doc/src/sgml/appendix-obsolete-pgreceivexlog.sgml -->
+<!--
+ See doc/src/sgml/appendix-obsolete.sgml for why this file exists. Do not change the id attribute.
+-->
+
+<sect1 id="app-pgreceivexlog" xreflabel="pg_receivexlog">
+ <title><command>pg_receivexlog</command> renamed to <command>pg_receivewal</command></title>
+
+ <indexterm>
+ <primary>pg_receivexlog</primary>
+ <see>pg_receivewal</see>
+ </indexterm>
+
+ <para>
+ PostgreSQL 9.6 and below provided a command named
+ <command>pg_receivexlog</command>
+ <indexterm><primary>pg_receivexlog</primary></indexterm>
+ to fetch write-ahead-log (WAL) files. This command was renamed to <command>pg_receivewal</command>, see
+ <xref linkend="app-pgreceivewal"/> for documentation of <command>pg_receivewal</command> and see
+ <link linkend="release-prior">the release notes for PostgreSQL 10</link> for details
+ on this change.
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete-pgresetxlog.sgml b/doc/src/sgml/appendix-obsolete-pgresetxlog.sgml
new file mode 100644
index 0000000..3300861
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete-pgresetxlog.sgml
@@ -0,0 +1,24 @@
+<!-- doc/src/sgml/appendix-obsolete-pgresetxlog.sgml -->
+<!--
+ See doc/src/sgml/appendix-obsolete.sgml for why this file exists. Do not change the id attribute.
+-->
+
+<sect1 id="app-pgresetxlog" xreflabel="pg_resetxlog">
+ <title><command>pg_resetxlog</command> renamed to <command>pg_resetwal</command></title>
+
+ <indexterm>
+ <primary>pg_resetxlog</primary>
+ <see>pg_resetwal</see>
+ </indexterm>
+
+ <para>
+ PostgreSQL 9.6 and below provided a command named
+ <command>pg_resetxlog</command>
+ <indexterm><primary>pg_resetxlog</primary></indexterm>
+ to reset the write-ahead-log (WAL) files. This command was renamed to <command>pg_resetwal</command>, see
+ <xref linkend="app-pgresetwal"/> for documentation of <command>pg_resetwal</command> and see
+ <link linkend="release-prior">the release notes for PostgreSQL 10</link> for details
+ on this change.
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete-pgxlogdump.sgml b/doc/src/sgml/appendix-obsolete-pgxlogdump.sgml
new file mode 100644
index 0000000..76f2a8f
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete-pgxlogdump.sgml
@@ -0,0 +1,24 @@
+<!-- doc/src/sgml/appendix-obsolete-pgxlogdump.sgml -->
+<!--
+ See doc/src/sgml/appendix-obsolete.sgml for why this file exists. Do not change the id attribute.
+-->
+
+<sect1 id="pgxlogdump" xreflabel="pg_xlogdump">
+ <title><command>pg_xlogdump</command> renamed to <command>pg_waldump</command></title>
+
+ <indexterm>
+ <primary>pg_xlogdump</primary>
+ <see>pg_waldump</see>
+ </indexterm>
+
+ <para>
+ PostgreSQL 9.6 and below provided a command named
+ <command>pg_xlogdump</command>
+ <indexterm><primary>pg_xlogdump</primary></indexterm>
+ to read write-ahead-log (WAL) files. This command was renamed to <command>pg_waldump</command>, see
+ <xref linkend="pgwaldump"/> for documentation of <command>pg_waldump</command> and see
+ <link linkend="release-prior">the release notes for PostgreSQL 10</link> for details
+ on this change.
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete-recovery-config.sgml b/doc/src/sgml/appendix-obsolete-recovery-config.sgml
new file mode 100644
index 0000000..1cf4913
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete-recovery-config.sgml
@@ -0,0 +1,58 @@
+<!-- doc/src/sgml/appendix-obsolete-recovery-config.sgml -->
+<!--
+ See doc/src/sgml/appendix-obsolete.sgml for why this file exists. Do not change the id attribute.
+-->
+
+<sect1 id="recovery-config" xreflabel="recovery.conf">
+ <title><filename>recovery.conf</filename> file merged into <filename>postgresql.conf</filename></title>
+
+ <indexterm>
+ <primary><filename>recovery.conf</filename></primary>
+ </indexterm>
+
+ <para>
+ PostgreSQL 11 and below used a configuration file named
+ <filename>recovery.conf</filename>
+ <indexterm><primary>recovery.conf</primary></indexterm>
+ to manage replicas and standbys. Support for this file was removed in PostgreSQL 12. See
+ <link linkend="release-prior">the release notes for PostgreSQL 12</link> for details
+ on this change.
+ </para>
+
+ <para>
+ On PostgreSQL 12 and above,
+ <link linkend="continuous-archiving">archive recovery, streaming replication, and PITR</link>
+ are configured using
+ <link linkend="runtime-config-replication-standby">normal server configuration parameters</link>.
+ These are set in <filename>postgresql.conf</filename> or via
+ <link linkend="sql-altersystem">ALTER SYSTEM</link>
+ like any other parameter.
+ </para>
+
+ <para>
+ The server will not start if a <filename>recovery.conf</filename> exists.
+ </para>
+
+ <para>
+ The
+ <literal>trigger_file</literal>
+ <indexterm>
+ <primary>trigger_file</primary>
+ <see>promote_trigger_file</see>
+ </indexterm>
+ setting has been renamed to
+ <xref linkend="guc-promote-trigger-file"/>.
+ </para>
+
+ <para>
+ The
+ <literal>standby_mode</literal>
+ <indexterm>
+ <primary>standby_mode</primary>
+ <see>standby.signal</see>
+ </indexterm>
+ setting has been removed. A <filename>standby.signal</filename> file in the data directory
+ is used instead. See <xref linkend="standby-server-operation"/> for details.
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/appendix-obsolete.sgml b/doc/src/sgml/appendix-obsolete.sgml
new file mode 100644
index 0000000..b1a00c8
--- /dev/null
+++ b/doc/src/sgml/appendix-obsolete.sgml
@@ -0,0 +1,42 @@
+<!-- doc/src/sgml/appendix-obsolete.sgml -->
+
+<appendix id="appendix-obsolete">
+ <title>Obsolete or Renamed Features</title>
+
+ <para>
+ Functionality is sometimes removed from PostgreSQL, feature, setting
+ and file names sometimes change, or documentation moves to different
+ places. This section directs users coming from old versions of the
+ documentation or from external links to the appropriate new location
+ for the information they need.
+ </para>
+
+ <!--
+ This section exists so that people following /current/ links to documentation
+ don't get a 404 when we move or rename things. And users who find old versions
+ of the docs in searches or old command names when checking the index can
+ follow links to the new commands.
+
+ Each subsection here should retain the same <chapter>, <appendix> and/or
+ <sect1> "id" attribute that was used for the relevant documentation before
+ it was renamed or moved. Do not prepend "obsolete-" or anything, keep it
+ exactly the same. These ids are used to determine the filenames for generated
+ HTML docs so changing them will break links.
+
+ Each entry should also insert index terms redirecting from the old to new
+ names. The recommended spelling is
+
+ <indexterm><primary>oldname</primary><see>newname</see></indexterm>
+
+ We don't bother with attempting to maintain down-version linking, e.g from
+ pg_waldump to pg_xlogdump. Users of old versions should use old docs. There
+ is no need to add index terms pointing from the new to old names.
+ -->
+
+ &obsolete-recovery-config;
+ &obsolete-default-roles;
+ &obsolete-pgxlogdump;
+ &obsolete-pgresetxlog;
+ &obsolete-pgreceivexlog;
+
+</appendix>
diff --git a/doc/src/sgml/arch-dev.sgml b/doc/src/sgml/arch-dev.sgml
new file mode 100644
index 0000000..8aeac02
--- /dev/null
+++ b/doc/src/sgml/arch-dev.sgml
@@ -0,0 +1,575 @@
+<!-- doc/src/sgml/arch-dev.sgml -->
+
+ <chapter id="overview">
+ <title>Overview of PostgreSQL Internals</title>
+
+ <note>
+ <title>Author</title>
+ <para>
+ This chapter originated as part of
+ <xref linkend="sim98"/> Stefan Simkovics'
+ Master's Thesis prepared at Vienna University of Technology under the direction
+ of O.Univ.Prof.Dr. Georg Gottlob and Univ.Ass. Mag. Katrin Seyr.
+ </para>
+ </note>
+
+ <para>
+ This chapter gives an overview of the internal structure of the
+ backend of <productname>PostgreSQL</productname>. After having
+ read the following sections you should have an idea of how a query
+ is processed. This chapter is intended to help the reader
+ understand the general sequence of operations that occur within the
+ backend from the point at which a query is received, to the point
+ at which the results are returned to the client.
+ </para>
+
+ <sect1 id="query-path">
+ <title>The Path of a Query</title>
+
+ <para>
+ Here we give a short overview of the stages a query has to pass
+ to obtain a result.
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ A connection from an application program to the <productname>PostgreSQL</productname>
+ server has to be established. The application program transmits a
+ query to the server and waits to receive the results sent back by the
+ server.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ The <firstterm>parser stage</firstterm> checks the query
+ transmitted by the application
+ program for correct syntax and creates
+ a <firstterm>query tree</firstterm>.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ The <firstterm>rewrite system</firstterm> takes
+ the query tree created by the parser stage and looks for
+ any <firstterm>rules</firstterm> (stored in the
+ <firstterm>system catalogs</firstterm>) to apply to
+ the query tree. It performs the
+ transformations given in the <firstterm>rule bodies</firstterm>.
+ </para>
+
+ <para>
+ One application of the rewrite system is in the realization of
+ <firstterm>views</firstterm>.
+ Whenever a query against a view
+ (i.e., a <firstterm>virtual table</firstterm>) is made,
+ the rewrite system rewrites the user's query to
+ a query that accesses the <firstterm>base tables</firstterm> given in
+ the <firstterm>view definition</firstterm> instead.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ The <firstterm>planner/optimizer</firstterm> takes
+ the (rewritten) query tree and creates a
+ <firstterm>query plan</firstterm> that will be the input to the
+ <firstterm>executor</firstterm>.
+ </para>
+
+ <para>
+ It does so by first creating all possible <firstterm>paths</firstterm>
+ leading to the same result. For example if there is an index on a
+ relation to be scanned, there are two paths for the
+ scan. One possibility is a simple sequential scan and the other
+ possibility is to use the index. Next the cost for the execution of
+ each path is estimated and the cheapest path is chosen. The cheapest
+ path is expanded into a complete plan that the executor can use.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ The executor recursively steps through
+ the <firstterm>plan tree</firstterm> and
+ retrieves rows in the way represented by the plan.
+ The executor makes use of the
+ <firstterm>storage system</firstterm> while scanning
+ relations, performs <firstterm>sorts</firstterm> and <firstterm>joins</firstterm>,
+ evaluates <firstterm>qualifications</firstterm> and finally hands back the rows derived.
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ In the following sections we will cover each of the above listed items
+ in more detail to give a better understanding of <productname>PostgreSQL</productname>'s internal
+ control and data structures.
+ </para>
+ </sect1>
+
+ <sect1 id="connect-estab">
+ <title>How Connections Are Established</title>
+
+ <para>
+ <productname>PostgreSQL</productname> implements a
+ <quote>process per user</quote> client/server model.
+ In this model, every
+ <glossterm linkend="glossary-client">client process</glossterm>
+ connects to exactly one
+ <glossterm linkend="glossary-backend">backend process</glossterm>.
+ As we do not know ahead of time how many connections will be made,
+ we have to use a <quote>supervisor process</quote> that spawns a new
+ backend process every time a connection is requested. This supervisor
+ process is called
+ <glossterm linkend="glossary-postmaster">postmaster</glossterm>
+ and listens at a specified TCP/IP port for incoming connections.
+ Whenever it detects a request for a connection, it spawns a new
+ backend process. Those backend processes communicate with each
+ other and with other processes of the
+ <glossterm linkend="glossary-instance">instance</glossterm>
+ using <firstterm>semaphores</firstterm> and
+ <glossterm linkend="glossary-shared-memory">shared memory</glossterm>
+ to ensure data integrity throughout concurrent data access.
+ </para>
+
+ <para>
+ The client process can be any program that understands the
+ <productname>PostgreSQL</productname> protocol described in
+ <xref linkend="protocol"/>. Many clients are based on the
+ C-language library <application>libpq</application>, but several independent
+ implementations of the protocol exist, such as the Java
+ <application>JDBC</application> driver.
+ </para>
+
+ <para>
+ Once a connection is established, the client process can send a query
+ to the backend process it's connected to. The query is transmitted using
+ plain text, i.e., there is no parsing done in the client. The backend
+ process parses the query, creates an <firstterm>execution plan</firstterm>,
+ executes the plan, and returns the retrieved rows to the client
+ by transmitting them over the established connection.
+ </para>
+ </sect1>
+
+ <sect1 id="parser-stage">
+ <title>The Parser Stage</title>
+
+ <para>
+ The <firstterm>parser stage</firstterm> consists of two parts:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <firstterm>parser</firstterm> defined in
+ <filename>gram.y</filename> and <filename>scan.l</filename> is
+ built using the Unix tools <application>bison</application>
+ and <application>flex</application>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <firstterm>transformation process</firstterm> does
+ modifications and augmentations to the data structures returned by the parser.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect2>
+ <title>Parser</title>
+
+ <para>
+ The parser has to check the query string (which arrives as plain
+ text) for valid syntax. If the syntax is correct a
+ <firstterm>parse tree</firstterm> is built up and handed back;
+ otherwise an error is returned. The parser and lexer are
+ implemented using the well-known Unix tools <application>bison</application>
+ and <application>flex</application>.
+ </para>
+
+ <para>
+ The <firstterm>lexer</firstterm> is defined in the file
+ <filename>scan.l</filename> and is responsible
+ for recognizing <firstterm>identifiers</firstterm>,
+ the <firstterm>SQL key words</firstterm> etc. For
+ every key word or identifier that is found, a <firstterm>token</firstterm>
+ is generated and handed to the parser.
+ </para>
+
+ <para>
+ The parser is defined in the file <filename>gram.y</filename> and
+ consists of a set of <firstterm>grammar rules</firstterm> and
+ <firstterm>actions</firstterm> that are executed whenever a rule
+ is fired. The code of the actions (which is actually C code) is
+ used to build up the parse tree.
+ </para>
+
+ <para>
+ The file <filename>scan.l</filename> is transformed to the C
+ source file <filename>scan.c</filename> using the program
+ <application>flex</application> and <filename>gram.y</filename> is
+ transformed to <filename>gram.c</filename> using
+ <application>bison</application>. After these transformations
+ have taken place a normal C compiler can be used to create the
+ parser. Never make any changes to the generated C files as they
+ will be overwritten the next time <application>flex</application>
+ or <application>bison</application> is called.
+
+ <note>
+ <para>
+ The mentioned transformations and compilations are normally done
+ automatically using the <firstterm>makefiles</firstterm>
+ shipped with the <productname>PostgreSQL</productname>
+ source distribution.
+ </para>
+ </note>
+ </para>
+
+ <para>
+ A detailed description of <application>bison</application> or
+ the grammar rules given in <filename>gram.y</filename> would be
+ beyond the scope of this manual. There are many books and
+ documents dealing with <application>flex</application> and
+ <application>bison</application>. You should be familiar with
+ <application>bison</application> before you start to study the
+ grammar given in <filename>gram.y</filename> otherwise you won't
+ understand what happens there.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Transformation Process</title>
+
+ <para>
+ The parser stage creates a parse tree using only fixed rules about
+ the syntactic structure of SQL. It does not make any lookups in the
+ system catalogs, so there is no possibility to understand the detailed
+ semantics of the requested operations. After the parser completes,
+ the <firstterm>transformation process</firstterm> takes the tree handed
+ back by the parser as input and does the semantic interpretation needed
+ to understand which tables, functions, and operators are referenced by
+ the query. The data structure that is built to represent this
+ information is called the <firstterm>query tree</firstterm>.
+ </para>
+
+ <para>
+ The reason for separating raw parsing from semantic analysis is that
+ system catalog lookups can only be done within a transaction, and we
+ do not wish to start a transaction immediately upon receiving a query
+ string. The raw parsing stage is sufficient to identify the transaction
+ control commands (<command>BEGIN</command>, <command>ROLLBACK</command>, etc.), and
+ these can then be correctly executed without any further analysis.
+ Once we know that we are dealing with an actual query (such as
+ <command>SELECT</command> or <command>UPDATE</command>), it is okay to
+ start a transaction if we're not already in one. Only then can the
+ transformation process be invoked.
+ </para>
+
+ <para>
+ The query tree created by the transformation process is structurally
+ similar to the raw parse tree in most places, but it has many differences
+ in detail. For example, a <structname>FuncCall</structname> node in the
+ parse tree represents something that looks syntactically like a function
+ call. This might be transformed to either a <structname>FuncExpr</structname>
+ or <structname>Aggref</structname> node depending on whether the referenced
+ name turns out to be an ordinary function or an aggregate function.
+ Also, information about the actual data types of columns and expression
+ results is added to the query tree.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="rule-system">
+ <title>The <productname>PostgreSQL</productname> Rule System</title>
+
+ <para>
+ <productname>PostgreSQL</productname> supports a powerful
+ <firstterm>rule system</firstterm> for the specification
+ of <firstterm>views</firstterm> and ambiguous <firstterm>view updates</firstterm>.
+ Originally the <productname>PostgreSQL</productname>
+ rule system consisted of two implementations:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The first one worked using <firstterm>row level</firstterm> processing and was
+ implemented deep in the <firstterm>executor</firstterm>. The rule system was
+ called whenever an individual row had been accessed. This
+ implementation was removed in 1995 when the last official release
+ of the <productname>Berkeley Postgres</productname> project was
+ transformed into <productname>Postgres95</productname>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The second implementation of the rule system is a technique
+ called <firstterm>query rewriting</firstterm>.
+ The <firstterm>rewrite system</firstterm> is a module
+ that exists between the <firstterm>parser stage</firstterm> and the
+ <firstterm>planner/optimizer</firstterm>. This technique is still implemented.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The query rewriter is discussed in some detail in
+ <xref linkend="rules"/>, so there is no need to cover it here.
+ We will only point out that both the input and the output of the
+ rewriter are query trees, that is, there is no change in the
+ representation or level of semantic detail in the trees. Rewriting
+ can be thought of as a form of macro expansion.
+ </para>
+
+ </sect1>
+
+ <sect1 id="planner-optimizer">
+ <title>Planner/Optimizer</title>
+
+ <para>
+ The task of the <firstterm>planner/optimizer</firstterm> is to
+ create an optimal execution plan. A given SQL query (and hence, a
+ query tree) can be actually executed in a wide variety of
+ different ways, each of which will produce the same set of
+ results. If it is computationally feasible, the query optimizer
+ will examine each of these possible execution plans, ultimately
+ selecting the execution plan that is expected to run the fastest.
+ </para>
+
+ <note>
+ <para>
+ In some situations, examining each possible way in which a query
+ can be executed would take an excessive amount of time and memory.
+ In particular, this occurs when executing queries
+ involving large numbers of join operations. In order to determine
+ a reasonable (not necessarily optimal) query plan in a reasonable amount
+ of time, <productname>PostgreSQL</productname> uses a <firstterm>Genetic
+ Query Optimizer</firstterm> (see <xref linkend="geqo"/>) when the number of joins
+ exceeds a threshold (see <xref linkend="guc-geqo-threshold"/>).
+ </para>
+ </note>
+
+ <para>
+ The planner's search procedure actually works with data structures
+ called <firstterm>paths</firstterm>, which are simply cut-down representations of
+ plans containing only as much information as the planner needs to make
+ its decisions. After the cheapest path is determined, a full-fledged
+ <firstterm>plan tree</firstterm> is built to pass to the executor. This represents
+ the desired execution plan in sufficient detail for the executor to run it.
+ In the rest of this section we'll ignore the distinction between paths
+ and plans.
+ </para>
+
+ <sect2>
+ <title>Generating Possible Plans</title>
+
+ <para>
+ The planner/optimizer starts by generating plans for scanning each
+ individual relation (table) used in the query. The possible plans
+ are determined by the available indexes on each relation.
+ There is always the possibility of performing a
+ sequential scan on a relation, so a sequential scan plan is always
+ created. Assume an index is defined on a
+ relation (for example a B-tree index) and a query contains the
+ restriction
+ <literal>relation.attribute OPR constant</literal>. If
+ <literal>relation.attribute</literal> happens to match the key of the B-tree
+ index and <literal>OPR</literal> is one of the operators listed in
+ the index's <firstterm>operator class</firstterm>, another plan is created using
+ the B-tree index to scan the relation. If there are further indexes
+ present and the restrictions in the query happen to match a key of an
+ index, further plans will be considered. Index scan plans are also
+ generated for indexes that have a sort ordering that can match the
+ query's <literal>ORDER BY</literal> clause (if any), or a sort ordering that
+ might be useful for merge joining (see below).
+ </para>
+
+ <para>
+ If the query requires joining two or more relations,
+ plans for joining relations are considered
+ after all feasible plans have been found for scanning single relations.
+ The three available join strategies are:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <firstterm>nested loop join</firstterm>: The right relation is scanned
+ once for every row found in the left relation. This strategy
+ is easy to implement but can be very time consuming. (However,
+ if the right relation can be scanned with an index scan, this can
+ be a good strategy. It is possible to use values from the current
+ row of the left relation as keys for the index scan of the right.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <firstterm>merge join</firstterm>: Each relation is sorted on the join
+ attributes before the join starts. Then the two relations are
+ scanned in parallel, and matching rows are combined to form
+ join rows. This kind of join is
+ attractive because each relation has to be scanned only once.
+ The required sorting might be achieved either by an explicit sort
+ step, or by scanning the relation in the proper order using an
+ index on the join key.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <firstterm>hash join</firstterm>: the right relation is first scanned
+ and loaded into a hash table, using its join attributes as hash keys.
+ Next the left relation is scanned and the
+ appropriate values of every row found are used as hash keys to
+ locate the matching rows in the table.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ When the query involves more than two relations, the final result
+ must be built up by a tree of join steps, each with two inputs.
+ The planner examines different possible join sequences to find the
+ cheapest one.
+ </para>
+
+ <para>
+ If the query uses fewer than <xref linkend="guc-geqo-threshold"/>
+ relations, a near-exhaustive search is conducted to find the best
+ join sequence. The planner preferentially considers joins between any
+ two relations for which there exists a corresponding join clause in the
+ <literal>WHERE</literal> qualification (i.e., for
+ which a restriction like <literal>where rel1.attr1=rel2.attr2</literal>
+ exists). Join pairs with no join clause are considered only when there
+ is no other choice, that is, a particular relation has no available
+ join clauses to any other relation. All possible plans are generated for
+ every join pair considered by the planner, and the one that is
+ (estimated to be) the cheapest is chosen.
+ </para>
+
+ <para>
+ When <varname>geqo_threshold</varname> is exceeded, the join
+ sequences considered are determined by heuristics, as described
+ in <xref linkend="geqo"/>. Otherwise the process is the same.
+ </para>
+
+ <para>
+ The finished plan tree consists of sequential or index scans of
+ the base relations, plus nested-loop, merge, or hash join nodes as
+ needed, plus any auxiliary steps needed, such as sort nodes or
+ aggregate-function calculation nodes. Most of these plan node
+ types have the additional ability to do <firstterm>selection</firstterm>
+ (discarding rows that do not meet a specified Boolean condition)
+ and <firstterm>projection</firstterm> (computation of a derived column set
+ based on given column values, that is, evaluation of scalar
+ expressions where needed). One of the responsibilities of the
+ planner is to attach selection conditions from the
+ <literal>WHERE</literal> clause and computation of required
+ output expressions to the most appropriate nodes of the plan
+ tree.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="executor">
+ <title>Executor</title>
+
+ <para>
+ The <firstterm>executor</firstterm> takes the plan created by the
+ planner/optimizer and recursively processes it to extract the required set
+ of rows. This is essentially a demand-pull pipeline mechanism.
+ Each time a plan node is called, it must deliver one more row, or
+ report that it is done delivering rows.
+ </para>
+
+ <para>
+ To provide a concrete example, assume that the top
+ node is a <literal>MergeJoin</literal> node.
+ Before any merge can be done two rows have to be fetched (one from
+ each subplan). So the executor recursively calls itself to
+ process the subplans (it starts with the subplan attached to
+ <literal>lefttree</literal>). The new top node (the top node of the left
+ subplan) is, let's say, a
+ <literal>Sort</literal> node and again recursion is needed to obtain
+ an input row. The child node of the <literal>Sort</literal> might
+ be a <literal>SeqScan</literal> node, representing actual reading of a table.
+ Execution of this node causes the executor to fetch a row from the
+ table and return it up to the calling node. The <literal>Sort</literal>
+ node will repeatedly call its child to obtain all the rows to be sorted.
+ When the input is exhausted (as indicated by the child node returning
+ a NULL instead of a row), the <literal>Sort</literal> code performs
+ the sort, and finally is able to return its first output row, namely
+ the first one in sorted order. It keeps the remaining rows stored so
+ that it can deliver them in sorted order in response to later demands.
+ </para>
+
+ <para>
+ The <literal>MergeJoin</literal> node similarly demands the first row
+ from its right subplan. Then it compares the two rows to see if they
+ can be joined; if so, it returns a join row to its caller. On the next
+ call, or immediately if it cannot join the current pair of inputs,
+ it advances to the next row of one table
+ or the other (depending on how the comparison came out), and again
+ checks for a match. Eventually, one subplan or the other is exhausted,
+ and the <literal>MergeJoin</literal> node returns NULL to indicate that
+ no more join rows can be formed.
+ </para>
+
+ <para>
+ Complex queries can involve many levels of plan nodes, but the general
+ approach is the same: each node computes and returns its next output
+ row each time it is called. Each node is also responsible for applying
+ any selection or projection expressions that were assigned to it by
+ the planner.
+ </para>
+
+ <para>
+ The executor mechanism is used to evaluate all five basic SQL query
+ types: <command>SELECT</command>, <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, and
+ <command>MERGE</command>.
+ For <command>SELECT</command>, the top-level executor code
+ only needs to send each row returned by the query plan tree
+ off to the client. <command>INSERT ... SELECT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, and
+ <command>MERGE</command>
+ are effectively <command>SELECT</command>s under a special
+ top-level plan node called <literal>ModifyTable</literal>.
+ </para>
+
+ <para>
+ <command>INSERT ... SELECT</command> feeds the rows up
+ to <literal>ModifyTable</literal> for insertion. For
+ <command>UPDATE</command>, the planner arranges that each
+ computed row includes all the updated column values, plus the
+ <firstterm>TID</firstterm> (tuple ID, or row ID) of the original
+ target row; this data is fed up to the <literal>ModifyTable</literal>
+ node, which uses the information to create a new updated row and
+ mark the old row deleted. For <command>DELETE</command>, the only
+ column that is actually returned by the plan is the TID, and the
+ <literal>ModifyTable</literal> node simply uses the TID to visit each
+ target row and mark it deleted. For <command>MERGE</command>, the
+ planner joins the source and target relations, and includes all
+ column values required by any of the <literal>WHEN</literal> clauses,
+ plus the TID of the target row; this data is fed up to the
+ <literal>ModifyTable</literal> node, which uses the information to
+ work out which <literal>WHEN</literal> clause to execute, and then
+ inserts, updates or deletes the target row, as required.
+ </para>
+
+ <para>
+ A simple <command>INSERT ... VALUES</command> command creates a
+ trivial plan tree consisting of a single <literal>Result</literal>
+ node, which computes just one result row, feeding that up
+ to <literal>ModifyTable</literal> to perform the insertion.
+ </para>
+
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/archive-modules.sgml b/doc/src/sgml/archive-modules.sgml
new file mode 100644
index 0000000..ef02051
--- /dev/null
+++ b/doc/src/sgml/archive-modules.sgml
@@ -0,0 +1,136 @@
+<!-- doc/src/sgml/archive-modules.sgml -->
+
+<chapter id="archive-modules">
+ <title>Archive Modules</title>
+ <indexterm zone="archive-modules">
+ <primary>Archive Modules</primary>
+ </indexterm>
+
+ <para>
+ PostgreSQL provides infrastructure to create custom modules for continuous
+ archiving (see <xref linkend="continuous-archiving"/>). While archiving via
+ a shell command (i.e., <xref linkend="guc-archive-command"/>) is much
+ simpler, a custom archive module will often be considerably more robust and
+ performant.
+ </para>
+
+ <para>
+ When a custom <xref linkend="guc-archive-library"/> is configured, PostgreSQL
+ will submit completed WAL files to the module, and the server will avoid
+ recycling or removing these WAL files until the module indicates that the files
+ were successfully archived. It is ultimately up to the module to decide what
+ to do with each WAL file, but many recommendations are listed at
+ <xref linkend="backup-archiving-wal"/>.
+ </para>
+
+ <para>
+ Archiving modules must at least consist of an initialization function (see
+ <xref linkend="archive-module-init"/>) and the required callbacks (see
+ <xref linkend="archive-module-callbacks"/>). However, archive modules are
+ also permitted to do much more (e.g., declare GUCs and register background
+ workers).
+ </para>
+
+ <para>
+ The <filename>contrib/basic_archive</filename> module contains a working
+ example, which demonstrates some useful techniques.
+ </para>
+
+ <sect1 id="archive-module-init">
+ <title>Initialization Functions</title>
+ <indexterm zone="archive-module-init">
+ <primary>_PG_archive_module_init</primary>
+ </indexterm>
+ <para>
+ An archive library is loaded by dynamically loading a shared library with the
+ <xref linkend="guc-archive-library"/>'s name as the library base name. The
+ normal library search path is used to locate the library. To provide the
+ required archive module callbacks and to indicate that the library is
+ actually an archive module, it needs to provide a function named
+ <function>_PG_archive_module_init</function>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions.
+
+<programlisting>
+typedef struct ArchiveModuleCallbacks
+{
+ ArchiveCheckConfiguredCB check_configured_cb;
+ ArchiveFileCB archive_file_cb;
+ ArchiveShutdownCB shutdown_cb;
+} ArchiveModuleCallbacks;
+typedef void (*ArchiveModuleInit) (struct ArchiveModuleCallbacks *cb);
+</programlisting>
+
+ Only the <function>archive_file_cb</function> callback is required. The
+ others are optional.
+ </para>
+ </sect1>
+
+ <sect1 id="archive-module-callbacks">
+ <title>Archive Module Callbacks</title>
+ <para>
+ The archive callbacks define the actual archiving behavior of the module.
+ The server will call them as required to process each individual WAL file.
+ </para>
+
+ <sect2 id="archive-module-check">
+ <title>Check Callback</title>
+ <para>
+ The <function>check_configured_cb</function> callback is called to determine
+ whether the module is fully configured and ready to accept WAL files (e.g.,
+ its configuration parameters are set to valid values). If no
+ <function>check_configured_cb</function> is defined, the server always
+ assumes the module is configured.
+
+<programlisting>
+typedef bool (*ArchiveCheckConfiguredCB) (void);
+</programlisting>
+
+ If <literal>true</literal> is returned, the server will proceed with
+ archiving the file by calling the <function>archive_file_cb</function>
+ callback. If <literal>false</literal> is returned, archiving will not
+ proceed, and the archiver will emit the following message to the server log:
+<screen>
+WARNING: archive_mode enabled, yet archiving is not configured
+</screen>
+ In the latter case, the server will periodically call this function, and
+ archiving will proceed only when it returns <literal>true</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="archive-module-archive">
+ <title>Archive Callback</title>
+ <para>
+ The <function>archive_file_cb</function> callback is called to archive a
+ single WAL file.
+
+<programlisting>
+typedef bool (*ArchiveFileCB) (const char *file, const char *path);
+</programlisting>
+
+ If <literal>true</literal> is returned, the server proceeds as if the file
+ was successfully archived, which may include recycling or removing the
+ original WAL file. If <literal>false</literal> is returned, the server will
+ keep the original WAL file and retry archiving later.
+ <replaceable>file</replaceable> will contain just the file name of the WAL
+ file to archive, while <replaceable>path</replaceable> contains the full
+ path of the WAL file (including the file name).
+ </para>
+ </sect2>
+
+ <sect2 id="archive-module-shutdown">
+ <title>Shutdown Callback</title>
+ <para>
+ The <function>shutdown_cb</function> callback is called when the archiver
+ process exits (e.g., after an error) or the value of
+ <xref linkend="guc-archive-library"/> changes. If no
+ <function>shutdown_cb</function> is defined, no special action is taken in
+ these situations.
+
+<programlisting>
+typedef void (*ArchiveShutdownCB) (void);
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/array.sgml b/doc/src/sgml/array.sgml
new file mode 100644
index 0000000..56185b9
--- /dev/null
+++ b/doc/src/sgml/array.sgml
@@ -0,0 +1,797 @@
+<!-- doc/src/sgml/array.sgml -->
+
+<sect1 id="arrays">
+ <title>Arrays</title>
+
+ <indexterm>
+ <primary>array</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> allows columns of a table to be
+ defined as variable-length multidimensional arrays. Arrays of any
+ built-in or user-defined base type, enum type, composite type, range type,
+ or domain can be created.
+ </para>
+
+ <sect2 id="arrays-declaration">
+ <title>Declaration of Array Types</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>declaration</secondary>
+ </indexterm>
+
+ <para>
+ To illustrate the use of array types, we create this table:
+<programlisting>
+CREATE TABLE sal_emp (
+ name text,
+ pay_by_quarter integer[],
+ schedule text[][]
+);
+</programlisting>
+ As shown, an array data type is named by appending square brackets
+ (<literal>[]</literal>) to the data type name of the array elements. The
+ above command will create a table named
+ <structname>sal_emp</structname> with a column of type
+ <type>text</type> (<structfield>name</structfield>), a
+ one-dimensional array of type <type>integer</type>
+ (<structfield>pay_by_quarter</structfield>), which represents the
+ employee's salary by quarter, and a two-dimensional array of
+ <type>text</type> (<structfield>schedule</structfield>), which
+ represents the employee's weekly schedule.
+ </para>
+
+ <para>
+ The syntax for <command>CREATE TABLE</command> allows the exact size of
+ arrays to be specified, for example:
+
+<programlisting>
+CREATE TABLE tictactoe (
+ squares integer[3][3]
+);
+</programlisting>
+
+ However, the current implementation ignores any supplied array size
+ limits, i.e., the behavior is the same as for arrays of unspecified
+ length.
+ </para>
+
+ <para>
+ The current implementation does not enforce the declared
+ number of dimensions either. Arrays of a particular element type are
+ all considered to be of the same type, regardless of size or number
+ of dimensions. So, declaring the array size or number of dimensions in
+ <command>CREATE TABLE</command> is simply documentation; it does not
+ affect run-time behavior.
+ </para>
+
+ <para>
+ An alternative syntax, which conforms to the SQL standard by using
+ the keyword <literal>ARRAY</literal>, can be used for one-dimensional arrays.
+ <structfield>pay_by_quarter</structfield> could have been defined
+ as:
+<programlisting>
+ pay_by_quarter integer ARRAY[4],
+</programlisting>
+ Or, if no array size is to be specified:
+<programlisting>
+ pay_by_quarter integer ARRAY,
+</programlisting>
+ As before, however, <productname>PostgreSQL</productname> does not enforce the
+ size restriction in any case.
+ </para>
+ </sect2>
+
+ <sect2 id="arrays-input">
+ <title>Array Value Input</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>constant</secondary>
+ </indexterm>
+
+ <para>
+ To write an array value as a literal constant, enclose the element
+ values within curly braces and separate them by commas. (If you
+ know C, this is not unlike the C syntax for initializing
+ structures.) You can put double quotes around any element value,
+ and must do so if it contains commas or curly braces. (More
+ details appear below.) Thus, the general format of an array
+ constant is the following:
+<synopsis>
+'{ <replaceable>val1</replaceable> <replaceable>delim</replaceable> <replaceable>val2</replaceable> <replaceable>delim</replaceable> ... }'
+</synopsis>
+ where <replaceable>delim</replaceable> is the delimiter character
+ for the type, as recorded in its <literal>pg_type</literal> entry.
+ Among the standard data types provided in the
+ <productname>PostgreSQL</productname> distribution, all use a comma
+ (<literal>,</literal>), except for type <type>box</type> which uses a semicolon
+ (<literal>;</literal>). Each <replaceable>val</replaceable> is
+ either a constant of the array element type, or a subarray. An example
+ of an array constant is:
+<programlisting>
+'{{1,2,3},{4,5,6},{7,8,9}}'
+</programlisting>
+ This constant is a two-dimensional, 3-by-3 array consisting of
+ three subarrays of integers.
+ </para>
+
+ <para>
+ To set an element of an array constant to NULL, write <literal>NULL</literal>
+ for the element value. (Any upper- or lower-case variant of
+ <literal>NULL</literal> will do.) If you want an actual string value
+ <quote>NULL</quote>, you must put double quotes around it.
+ </para>
+
+ <para>
+ (These kinds of array constants are actually only a special case of
+ the generic type constants discussed in <xref
+ linkend="sql-syntax-constants-generic"/>. The constant is initially
+ treated as a string and passed to the array input conversion
+ routine. An explicit type specification might be necessary.)
+ </para>
+
+ <para>
+ Now we can show some <command>INSERT</command> statements:
+
+<programlisting>
+INSERT INTO sal_emp
+ VALUES ('Bill',
+ '{10000, 10000, 10000, 10000}',
+ '{{"meeting", "lunch"}, {"training", "presentation"}}');
+
+INSERT INTO sal_emp
+ VALUES ('Carol',
+ '{20000, 25000, 25000, 25000}',
+ '{{"breakfast", "consulting"}, {"meeting", "lunch"}}');
+</programlisting>
+ </para>
+
+ <para>
+ The result of the previous two inserts looks like this:
+
+<programlisting>
+SELECT * FROM sal_emp;
+ name | pay_by_quarter | schedule
+-------+---------------------------+-------------------------------------------
+ Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}}
+ Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}}
+(2 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Multidimensional arrays must have matching extents for each
+ dimension. A mismatch causes an error, for example:
+
+<programlisting>
+INSERT INTO sal_emp
+ VALUES ('Bill',
+ '{10000, 10000, 10000, 10000}',
+ '{{"meeting", "lunch"}, {"meeting"}}');
+ERROR: multidimensional arrays must have array expressions with matching dimensions
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>ARRAY</literal> constructor syntax can also be used:
+<programlisting>
+INSERT INTO sal_emp
+ VALUES ('Bill',
+ ARRAY[10000, 10000, 10000, 10000],
+ ARRAY[['meeting', 'lunch'], ['training', 'presentation']]);
+
+INSERT INTO sal_emp
+ VALUES ('Carol',
+ ARRAY[20000, 25000, 25000, 25000],
+ ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]);
+</programlisting>
+ Notice that the array elements are ordinary SQL constants or
+ expressions; for instance, string literals are single quoted, instead of
+ double quoted as they would be in an array literal. The <literal>ARRAY</literal>
+ constructor syntax is discussed in more detail in
+ <xref linkend="sql-syntax-array-constructors"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="arrays-accessing">
+ <title>Accessing Arrays</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>accessing</secondary>
+ </indexterm>
+
+ <para>
+ Now, we can run some queries on the table.
+ First, we show how to access a single element of an array.
+ This query retrieves the names of the employees whose pay changed in
+ the second quarter:
+
+<programlisting>
+SELECT name FROM sal_emp WHERE pay_by_quarter[1] &lt;&gt; pay_by_quarter[2];
+
+ name
+-------
+ Carol
+(1 row)
+</programlisting>
+
+ The array subscript numbers are written within square brackets.
+ By default <productname>PostgreSQL</productname> uses a
+ one-based numbering convention for arrays, that is,
+ an array of <replaceable>n</replaceable> elements starts with <literal>array[1]</literal> and
+ ends with <literal>array[<replaceable>n</replaceable>]</literal>.
+ </para>
+
+ <para>
+ This query retrieves the third quarter pay of all employees:
+
+<programlisting>
+SELECT pay_by_quarter[3] FROM sal_emp;
+
+ pay_by_quarter
+----------------
+ 10000
+ 25000
+(2 rows)
+</programlisting>
+ </para>
+
+ <para>
+ We can also access arbitrary rectangular slices of an array, or
+ subarrays. An array slice is denoted by writing
+ <literal><replaceable>lower-bound</replaceable>:<replaceable>upper-bound</replaceable></literal>
+ for one or more array dimensions. For example, this query retrieves the first
+ item on Bill's schedule for the first two days of the week:
+
+<programlisting>
+SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+------------------------
+ {{meeting},{training}}
+(1 row)
+</programlisting>
+
+ If any dimension is written as a slice, i.e., contains a colon, then all
+ dimensions are treated as slices. Any dimension that has only a single
+ number (no colon) is treated as being from 1
+ to the number specified. For example, <literal>[2]</literal> is treated as
+ <literal>[1:2]</literal>, as in this example:
+
+<programlisting>
+SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+-------------------------------------------
+ {{meeting,lunch},{training,presentation}}
+(1 row)
+</programlisting>
+
+ To avoid confusion with the non-slice case, it's best to use slice syntax
+ for all dimensions, e.g., <literal>[1:2][1:1]</literal>, not <literal>[2][1:1]</literal>.
+ </para>
+
+ <para>
+ It is possible to omit the <replaceable>lower-bound</replaceable> and/or
+ <replaceable>upper-bound</replaceable> of a slice specifier; the missing
+ bound is replaced by the lower or upper limit of the array's subscripts.
+ For example:
+
+<programlisting>
+SELECT schedule[:2][2:] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+------------------------
+ {{lunch},{presentation}}
+(1 row)
+
+SELECT schedule[:][1:1] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+------------------------
+ {{meeting},{training}}
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ An array subscript expression will return null if either the array itself or
+ any of the subscript expressions are null. Also, null is returned if a
+ subscript is outside the array bounds (this case does not raise an error).
+ For example, if <literal>schedule</literal>
+ currently has the dimensions <literal>[1:3][1:2]</literal> then referencing
+ <literal>schedule[3][3]</literal> yields NULL. Similarly, an array reference
+ with the wrong number of subscripts yields a null rather than an error.
+ </para>
+
+ <para>
+ An array slice expression likewise yields null if the array itself or
+ any of the subscript expressions are null. However, in other
+ cases such as selecting an array slice that
+ is completely outside the current array bounds, a slice expression
+ yields an empty (zero-dimensional) array instead of null. (This
+ does not match non-slice behavior and is done for historical reasons.)
+ If the requested slice partially overlaps the array bounds, then it
+ is silently reduced to just the overlapping region instead of
+ returning null.
+ </para>
+
+ <para>
+ The current dimensions of any array value can be retrieved with the
+ <function>array_dims</function> function:
+
+<programlisting>
+SELECT array_dims(schedule) FROM sal_emp WHERE name = 'Carol';
+
+ array_dims
+------------
+ [1:2][1:2]
+(1 row)
+</programlisting>
+
+ <function>array_dims</function> produces a <type>text</type> result,
+ which is convenient for people to read but perhaps inconvenient
+ for programs. Dimensions can also be retrieved with
+ <function>array_upper</function> and <function>array_lower</function>,
+ which return the upper and lower bound of a
+ specified array dimension, respectively:
+
+<programlisting>
+SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol';
+
+ array_upper
+-------------
+ 2
+(1 row)
+</programlisting>
+
+ <function>array_length</function> will return the length of a specified
+ array dimension:
+
+<programlisting>
+SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol';
+
+ array_length
+--------------
+ 2
+(1 row)
+</programlisting>
+
+ <function>cardinality</function> returns the total number of elements in an
+ array across all dimensions. It is effectively the number of rows a call to
+ <function>unnest</function> would yield:
+
+<programlisting>
+SELECT cardinality(schedule) FROM sal_emp WHERE name = 'Carol';
+
+ cardinality
+-------------
+ 4
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="arrays-modifying">
+ <title>Modifying Arrays</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>modifying</secondary>
+ </indexterm>
+
+ <para>
+ An array value can be replaced completely:
+
+<programlisting>
+UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
+ WHERE name = 'Carol';
+</programlisting>
+
+ or using the <literal>ARRAY</literal> expression syntax:
+
+<programlisting>
+UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000]
+ WHERE name = 'Carol';
+</programlisting>
+
+ An array can also be updated at a single element:
+
+<programlisting>
+UPDATE sal_emp SET pay_by_quarter[4] = 15000
+ WHERE name = 'Bill';
+</programlisting>
+
+ or updated in a slice:
+
+<programlisting>
+UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
+ WHERE name = 'Carol';
+</programlisting>
+
+ The slice syntaxes with omitted <replaceable>lower-bound</replaceable> and/or
+ <replaceable>upper-bound</replaceable> can be used too, but only when
+ updating an array value that is not NULL or zero-dimensional (otherwise,
+ there is no existing subscript limit to substitute).
+ </para>
+
+ <para>
+ A stored array value can be enlarged by assigning to elements not already
+ present. Any positions between those previously present and the newly
+ assigned elements will be filled with nulls. For example, if array
+ <literal>myarray</literal> currently has 4 elements, it will have six
+ elements after an update that assigns to <literal>myarray[6]</literal>;
+ <literal>myarray[5]</literal> will contain null.
+ Currently, enlargement in this fashion is only allowed for one-dimensional
+ arrays, not multidimensional arrays.
+ </para>
+
+ <para>
+ Subscripted assignment allows creation of arrays that do not use one-based
+ subscripts. For example one might assign to <literal>myarray[-2:7]</literal> to
+ create an array with subscript values from -2 to 7.
+ </para>
+
+ <para>
+ New array values can also be constructed using the concatenation operator,
+ <literal>||</literal>:
+<programlisting>
+SELECT ARRAY[1,2] || ARRAY[3,4];
+ ?column?
+-----------
+ {1,2,3,4}
+(1 row)
+
+SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
+ ?column?
+---------------------
+ {{5,6},{1,2},{3,4}}
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ The concatenation operator allows a single element to be pushed onto the
+ beginning or end of a one-dimensional array. It also accepts two
+ <replaceable>N</replaceable>-dimensional arrays, or an <replaceable>N</replaceable>-dimensional
+ and an <replaceable>N+1</replaceable>-dimensional array.
+ </para>
+
+ <para>
+ When a single element is pushed onto either the beginning or end of a
+ one-dimensional array, the result is an array with the same lower bound
+ subscript as the array operand. For example:
+<programlisting>
+SELECT array_dims(1 || '[0:1]={2,3}'::int[]);
+ array_dims
+------------
+ [0:2]
+(1 row)
+
+SELECT array_dims(ARRAY[1,2] || 3);
+ array_dims
+------------
+ [1:3]
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ When two arrays with an equal number of dimensions are concatenated, the
+ result retains the lower bound subscript of the left-hand operand's outer
+ dimension. The result is an array comprising every element of the left-hand
+ operand followed by every element of the right-hand operand. For example:
+<programlisting>
+SELECT array_dims(ARRAY[1,2] || ARRAY[3,4,5]);
+ array_dims
+------------
+ [1:5]
+(1 row)
+
+SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
+ array_dims
+------------
+ [1:5][1:2]
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ When an <replaceable>N</replaceable>-dimensional array is pushed onto the beginning
+ or end of an <replaceable>N+1</replaceable>-dimensional array, the result is
+ analogous to the element-array case above. Each <replaceable>N</replaceable>-dimensional
+ sub-array is essentially an element of the <replaceable>N+1</replaceable>-dimensional
+ array's outer dimension. For example:
+<programlisting>
+SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]);
+ array_dims
+------------
+ [1:3][1:2]
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ An array can also be constructed by using the functions
+ <function>array_prepend</function>, <function>array_append</function>,
+ or <function>array_cat</function>. The first two only support one-dimensional
+ arrays, but <function>array_cat</function> supports multidimensional arrays.
+ Some examples:
+
+<programlisting>
+SELECT array_prepend(1, ARRAY[2,3]);
+ array_prepend
+---------------
+ {1,2,3}
+(1 row)
+
+SELECT array_append(ARRAY[1,2], 3);
+ array_append
+--------------
+ {1,2,3}
+(1 row)
+
+SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);
+ array_cat
+-----------
+ {1,2,3,4}
+(1 row)
+
+SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);
+ array_cat
+---------------------
+ {{1,2},{3,4},{5,6}}
+(1 row)
+
+SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]);
+ array_cat
+---------------------
+ {{5,6},{1,2},{3,4}}
+</programlisting>
+ </para>
+
+ <para>
+ In simple cases, the concatenation operator discussed above is preferred
+ over direct use of these functions. However, because the concatenation
+ operator is overloaded to serve all three cases, there are situations where
+ use of one of the functions is helpful to avoid ambiguity. For example
+ consider:
+
+<programlisting>
+SELECT ARRAY[1, 2] || '{3, 4}'; -- the untyped literal is taken as an array
+ ?column?
+-----------
+ {1,2,3,4}
+
+SELECT ARRAY[1, 2] || '7'; -- so is this one
+ERROR: malformed array literal: "7"
+
+SELECT ARRAY[1, 2] || NULL; -- so is an undecorated NULL
+ ?column?
+----------
+ {1,2}
+(1 row)
+
+SELECT array_append(ARRAY[1, 2], NULL); -- this might have been meant
+ array_append
+--------------
+ {1,2,NULL}
+</programlisting>
+
+ In the examples above, the parser sees an integer array on one side of the
+ concatenation operator, and a constant of undetermined type on the other.
+ The heuristic it uses to resolve the constant's type is to assume it's of
+ the same type as the operator's other input &mdash; in this case,
+ integer array. So the concatenation operator is presumed to
+ represent <function>array_cat</function>, not <function>array_append</function>. When
+ that's the wrong choice, it could be fixed by casting the constant to the
+ array's element type; but explicit use of <function>array_append</function> might
+ be a preferable solution.
+ </para>
+ </sect2>
+
+ <sect2 id="arrays-searching">
+ <title>Searching in Arrays</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>searching</secondary>
+ </indexterm>
+
+ <para>
+ To search for a value in an array, each value must be checked.
+ This can be done manually, if you know the size of the array.
+ For example:
+
+<programlisting>
+SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR
+ pay_by_quarter[2] = 10000 OR
+ pay_by_quarter[3] = 10000 OR
+ pay_by_quarter[4] = 10000;
+</programlisting>
+
+ However, this quickly becomes tedious for large arrays, and is not
+ helpful if the size of the array is unknown. An alternative method is
+ described in <xref linkend="functions-comparisons"/>. The above
+ query could be replaced by:
+
+<programlisting>
+SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter);
+</programlisting>
+
+ In addition, you can find rows where the array has all values
+ equal to 10000 with:
+
+<programlisting>
+SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);
+</programlisting>
+
+ </para>
+
+ <para>
+ Alternatively, the <function>generate_subscripts</function> function can be used.
+ For example:
+
+<programlisting>
+SELECT * FROM
+ (SELECT pay_by_quarter,
+ generate_subscripts(pay_by_quarter, 1) AS s
+ FROM sal_emp) AS foo
+ WHERE pay_by_quarter[s] = 10000;
+</programlisting>
+
+ This function is described in <xref linkend="functions-srf-subscripts"/>.
+ </para>
+
+ <para>
+ You can also search an array using the <literal>&amp;&amp;</literal> operator,
+ which checks whether the left operand overlaps with the right operand.
+ For instance:
+
+<programlisting>
+SELECT * FROM sal_emp WHERE pay_by_quarter &amp;&amp; ARRAY[10000];
+</programlisting>
+
+ This and other array operators are further described in
+ <xref linkend="functions-array"/>. It can be accelerated by an appropriate
+ index, as described in <xref linkend="indexes-types"/>.
+ </para>
+
+ <para>
+ You can also search for specific values in an array using the <function>array_position</function>
+ and <function>array_positions</function> functions. The former returns the subscript of
+ the first occurrence of a value in an array; the latter returns an array with the
+ subscripts of all occurrences of the value in the array. For example:
+
+<programlisting>
+SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon');
+ array_position
+----------------
+ 2
+(1 row)
+
+SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);
+ array_positions
+-----------------
+ {1,4,8}
+(1 row)
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ Arrays are not sets; searching for specific array elements
+ can be a sign of database misdesign. Consider
+ using a separate table with a row for each item that would be an
+ array element. This will be easier to search, and is likely to
+ scale better for a large number of elements.
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2 id="arrays-io">
+ <title>Array Input and Output Syntax</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>I/O</secondary>
+ </indexterm>
+
+ <para>
+ The external text representation of an array value consists of items that
+ are interpreted according to the I/O conversion rules for the array's
+ element type, plus decoration that indicates the array structure.
+ The decoration consists of curly braces (<literal>{</literal> and <literal>}</literal>)
+ around the array value plus delimiter characters between adjacent items.
+ The delimiter character is usually a comma (<literal>,</literal>) but can be
+ something else: it is determined by the <literal>typdelim</literal> setting
+ for the array's element type. Among the standard data types provided
+ in the <productname>PostgreSQL</productname> distribution, all use a comma,
+ except for type <type>box</type>, which uses a semicolon (<literal>;</literal>).
+ In a multidimensional array, each dimension (row, plane,
+ cube, etc.) gets its own level of curly braces, and delimiters
+ must be written between adjacent curly-braced entities of the same level.
+ </para>
+
+ <para>
+ The array output routine will put double quotes around element values
+ if they are empty strings, contain curly braces, delimiter characters,
+ double quotes, backslashes, or white space, or match the word
+ <literal>NULL</literal>. Double quotes and backslashes
+ embedded in element values will be backslash-escaped. For numeric
+ data types it is safe to assume that double quotes will never appear, but
+ for textual data types one should be prepared to cope with either the presence
+ or absence of quotes.
+ </para>
+
+ <para>
+ By default, the lower bound index value of an array's dimensions is
+ set to one. To represent arrays with other lower bounds, the array
+ subscript ranges can be specified explicitly before writing the
+ array contents.
+ This decoration consists of square brackets (<literal>[]</literal>)
+ around each array dimension's lower and upper bounds, with
+ a colon (<literal>:</literal>) delimiter character in between. The
+ array dimension decoration is followed by an equal sign (<literal>=</literal>).
+ For example:
+<programlisting>
+SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
+ FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;
+
+ e1 | e2
+----+----
+ 1 | 6
+(1 row)
+</programlisting>
+ The array output routine will include explicit dimensions in its result
+ only when there are one or more lower bounds different from one.
+ </para>
+
+ <para>
+ If the value written for an element is <literal>NULL</literal> (in any case
+ variant), the element is taken to be NULL. The presence of any quotes
+ or backslashes disables this and allows the literal string value
+ <quote>NULL</quote> to be entered. Also, for backward compatibility with
+ pre-8.2 versions of <productname>PostgreSQL</productname>, the <xref
+ linkend="guc-array-nulls"/> configuration parameter can be turned
+ <literal>off</literal> to suppress recognition of <literal>NULL</literal> as a NULL.
+ </para>
+
+ <para>
+ As shown previously, when writing an array value you can use double
+ quotes around any individual array element. You <emphasis>must</emphasis> do so
+ if the element value would otherwise confuse the array-value parser.
+ For example, elements containing curly braces, commas (or the data type's
+ delimiter character), double quotes, backslashes, or leading or trailing
+ whitespace must be double-quoted. Empty strings and strings matching the
+ word <literal>NULL</literal> must be quoted, too. To put a double
+ quote or backslash in a quoted array element value, precede it
+ with a backslash. Alternatively, you can avoid quotes and use
+ backslash-escaping to protect all data characters that would otherwise
+ be taken as array syntax.
+ </para>
+
+ <para>
+ You can add whitespace before a left brace or after a right
+ brace. You can also add whitespace before or after any individual item
+ string. In all of these cases the whitespace will be ignored. However,
+ whitespace within double-quoted elements, or surrounded on both sides by
+ non-whitespace characters of an element, is not ignored.
+ </para>
+
+ <tip>
+ <para>
+ The <literal>ARRAY</literal> constructor syntax (see
+ <xref linkend="sql-syntax-array-constructors"/>) is often easier to work
+ with than the array-literal syntax when writing array values in SQL
+ commands. In <literal>ARRAY</literal>, individual element values are written the
+ same way they would be written when not members of an array.
+ </para>
+ </tip>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/auth-delay.sgml b/doc/src/sgml/auth-delay.sgml
new file mode 100644
index 0000000..3bc9cfb
--- /dev/null
+++ b/doc/src/sgml/auth-delay.sgml
@@ -0,0 +1,65 @@
+<!-- doc/src/sgml/auth-delay.sgml -->
+
+<sect1 id="auth-delay" xreflabel="auth_delay">
+ <title>auth_delay</title>
+
+ <indexterm zone="auth-delay">
+ <primary>auth_delay</primary>
+ </indexterm>
+
+ <para>
+ <filename>auth_delay</filename> causes the server to pause briefly before
+ reporting authentication failure, to make brute-force attacks on database
+ passwords more difficult. Note that it does nothing to prevent
+ denial-of-service attacks, and may even exacerbate them, since processes
+ that are waiting before reporting authentication failure will still consume
+ connection slots.
+ </para>
+
+ <para>
+ In order to function, this module must be loaded via
+ <xref linkend="guc-shared-preload-libraries"/> in <filename>postgresql.conf</filename>.
+ </para>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>auth_delay.milliseconds</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>auth_delay.milliseconds</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The number of milliseconds to wait before reporting an authentication
+ failure. The default is 0.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ These parameters must be set in <filename>postgresql.conf</filename>.
+ Typical usage might be:
+ </para>
+
+<programlisting>
+# postgresql.conf
+shared_preload_libraries = 'auth_delay'
+
+auth_delay.milliseconds = '500'
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ KaiGai Kohei <email>kaigai@ak.jp.nec.com</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/auto-explain.sgml b/doc/src/sgml/auto-explain.sgml
new file mode 100644
index 0000000..30e35a7
--- /dev/null
+++ b/doc/src/sgml/auto-explain.sgml
@@ -0,0 +1,340 @@
+<!-- doc/src/sgml/auto-explain.sgml -->
+
+<sect1 id="auto-explain" xreflabel="auto_explain">
+ <title>auto_explain</title>
+
+ <indexterm zone="auto-explain">
+ <primary>auto_explain</primary>
+ </indexterm>
+
+ <para>
+ The <filename>auto_explain</filename> module provides a means for
+ logging execution plans of slow statements automatically, without
+ having to run <xref linkend="sql-explain"/>
+ by hand. This is especially helpful for tracking down un-optimized queries
+ in large applications.
+ </para>
+
+ <para>
+ The module provides no SQL-accessible functions. To use it, simply
+ load it into the server. You can load it into an individual session:
+
+<programlisting>
+LOAD 'auto_explain';
+</programlisting>
+
+ (You must be superuser to do that.) More typical usage is to preload
+ it into some or all sessions by including <literal>auto_explain</literal> in
+ <xref linkend="guc-session-preload-libraries"/> or
+ <xref linkend="guc-shared-preload-libraries"/> in
+ <filename>postgresql.conf</filename>. Then you can track unexpectedly slow queries
+ no matter when they happen. Of course there is a price in overhead for
+ that.
+ </para>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <para>
+ There are several configuration parameters that control the behavior of
+ <filename>auto_explain</filename>. Note that the default behavior is
+ to do nothing, so you must set at least
+ <varname>auto_explain.log_min_duration</varname> if you want any results.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_min_duration</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_min_duration</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_min_duration</varname> is the minimum statement
+ execution time, in milliseconds, that will cause the statement's plan to
+ be logged. Setting this to <literal>0</literal> logs all plans.
+ <literal>-1</literal> (the default) disables logging of plans. For
+ example, if you set it to <literal>250ms</literal> then all statements
+ that run 250ms or longer will be logged. Only superusers can change this
+ setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_analyze</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_analyze</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_analyze</varname> causes <command>EXPLAIN ANALYZE</command>
+ output, rather than just <command>EXPLAIN</command> output, to be printed
+ when an execution plan is logged. This parameter is off by default.
+ Only superusers can change this setting.
+ </para>
+ <note>
+ <para>
+ When this parameter is on, per-plan-node timing occurs for all
+ statements executed, whether or not they run long enough to actually
+ get logged. This can have an extremely negative impact on performance.
+ Turning off <varname>auto_explain.log_timing</varname> ameliorates the
+ performance cost, at the price of obtaining less information.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_buffers</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_buffers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_buffers</varname> controls whether buffer
+ usage statistics are printed when an execution plan is logged; it's
+ equivalent to the <literal>BUFFERS</literal> option of <command>EXPLAIN</command>.
+ This parameter has no effect
+ unless <varname>auto_explain.log_analyze</varname> is enabled.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_wal</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_wal</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_wal</varname> controls whether WAL
+ usage statistics are printed when an execution plan is logged; it's
+ equivalent to the <literal>WAL</literal> option of <command>EXPLAIN</command>.
+ This parameter has no effect
+ unless <varname>auto_explain.log_analyze</varname> is enabled.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_timing</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_timing</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_timing</varname> controls whether per-node
+ timing information is printed when an execution plan is logged; it's
+ equivalent to the <literal>TIMING</literal> option of <command>EXPLAIN</command>.
+ The overhead of repeatedly reading the system clock can slow down
+ queries significantly on some systems, so it may be useful to set this
+ parameter to off when only actual row counts, and not exact times, are
+ needed.
+ This parameter has no effect
+ unless <varname>auto_explain.log_analyze</varname> is enabled.
+ This parameter is on by default.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_triggers</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_triggers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_triggers</varname> causes trigger
+ execution statistics to be included when an execution plan is logged.
+ This parameter has no effect
+ unless <varname>auto_explain.log_analyze</varname> is enabled.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_verbose</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_verbose</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_verbose</varname> controls whether verbose
+ details are printed when an execution plan is logged; it's
+ equivalent to the <literal>VERBOSE</literal> option of <command>EXPLAIN</command>.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_settings</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_settings</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_settings</varname> controls whether information
+ about modified configuration options is printed when an execution plan is logged.
+ Only options affecting query planning with value different from the built-in
+ default value are included in the output. This parameter is off by default.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_format</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_format</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_format</varname> selects the
+ <command>EXPLAIN</command> output format to be used.
+ The allowed values are <literal>text</literal>, <literal>xml</literal>,
+ <literal>json</literal>, and <literal>yaml</literal>. The default is text.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_level</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_level</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_level</varname> selects the log level at which
+ auto_explain will log the query plan.
+ Valid values are <literal>DEBUG5</literal>, <literal>DEBUG4</literal>,
+ <literal>DEBUG3</literal>, <literal>DEBUG2</literal>,
+ <literal>DEBUG1</literal>, <literal>INFO</literal>,
+ <literal>NOTICE</literal>, <literal>WARNING</literal>,
+ and <literal>LOG</literal>. The default is <literal>LOG</literal>.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.log_nested_statements</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>auto_explain.log_nested_statements</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.log_nested_statements</varname> causes nested
+ statements (statements executed inside a function) to be considered
+ for logging. When it is off, only top-level query plans are logged. This
+ parameter is off by default. Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>auto_explain.sample_rate</varname> (<type>real</type>)
+ <indexterm>
+ <primary><varname>auto_explain.sample_rate</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>auto_explain.sample_rate</varname> causes auto_explain to only
+ explain a fraction of the statements in each session. The default is 1,
+ meaning explain all the queries. In case of nested statements, either all
+ will be explained or none. Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ In ordinary usage, these parameters are set
+ in <filename>postgresql.conf</filename>, although superusers can alter them
+ on-the-fly within their own sessions.
+ Typical usage might be:
+ </para>
+
+<programlisting>
+# postgresql.conf
+session_preload_libraries = 'auto_explain'
+
+auto_explain.log_min_duration = '3s'
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Example</title>
+
+<programlisting>
+postgres=# LOAD 'auto_explain';
+postgres=# SET auto_explain.log_min_duration = 0;
+postgres=# SET auto_explain.log_analyze = true;
+postgres=# SELECT count(*)
+ FROM pg_class, pg_index
+ WHERE oid = indrelid AND indisunique;
+</programlisting>
+
+ <para>
+ This might produce log output such as:
+ </para>
+
+<screen><![CDATA[
+LOG: duration: 3.651 ms plan:
+ Query Text: SELECT count(*)
+ FROM pg_class, pg_index
+ WHERE oid = indrelid AND indisunique;
+ Aggregate (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1 loops=1)
+ -> Hash Join (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 loops=1)
+ Hash Cond: (pg_class.oid = pg_index.indrelid)
+ -> Seq Scan on pg_class (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255 loops=1)
+ -> Hash (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 loops=1)
+ Buckets: 1024 Batches: 1 Memory Usage: 4kB
+ -> Seq Scan on pg_index (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92 loops=1)
+ Filter: indisunique
+]]></screen>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Takahiro Itagaki <email>itagaki.takahiro@oss.ntt.co.jp</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/backup-manifest.sgml b/doc/src/sgml/backup-manifest.sgml
new file mode 100644
index 0000000..771be13
--- /dev/null
+++ b/doc/src/sgml/backup-manifest.sgml
@@ -0,0 +1,216 @@
+<!-- doc/src/sgml/backup-manifest.sgml -->
+
+<chapter id="backup-manifest-format">
+ <title>Backup Manifest Format</title>
+
+ <indexterm>
+ <primary>Backup Manifest</primary>
+ </indexterm>
+
+ <para>
+ The backup manifest generated by <xref linkend="app-pgbasebackup" /> is
+ primarily intended to permit the backup to be verified using
+ <xref linkend="app-pgverifybackup" />. However, it is
+ also possible for other tools to read the backup manifest file and use
+ the information contained therein for their own purposes. To that end,
+ this chapter describes the format of the backup manifest file.
+ </para>
+
+ <para>
+ A backup manifest is a JSON document encoded as UTF-8. (Although in
+ general JSON documents are required to be Unicode, PostgreSQL permits
+ the <type>json</type> and <type>jsonb</type> data types to be used with any
+ supported server encoding. There is no similar exception for backup
+ manifests.) The JSON document is always an object; the keys that are present
+ in this object are described in the next section.
+ </para>
+
+ <sect1 id="backup-manifest-toplevel">
+ <title>Backup Manifest Top-level Object</title>
+
+ <para>
+ The backup manifest JSON document contains the following keys.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>PostgreSQL-Backup-Manifest-Version</literal></term>
+ <listitem>
+ <para>
+ The associated value is always the integer 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Files</literal></term>
+ <listitem>
+ <para>
+ The associated value is always a list of objects, each describing one
+ file that is present in the backup. No entries are present in this
+ list for the WAL files that are needed in order to use the backup,
+ or for the backup manifest itself. The structure of each object in the
+ list is described in <xref linkend="backup-manifest-files" />.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAL-Ranges</literal></term>
+ <listitem>
+ <para>
+ The associated value is always a list of objects, each describing a
+ range of WAL records that must be readable from a particular timeline
+ in order to make use of the backup. The structure of these objects is
+ further described in <xref linkend="backup-manifest-wal-ranges" />.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Manifest-Checksum</literal></term>
+ <listitem>
+ <para>
+ This key is always present on the last line of the backup manifest file.
+ The associated value is a SHA256 checksum of all the preceding lines.
+ We use a fixed checksum method here to make it possible for clients
+ to do incremental parsing of the manifest. While a SHA256 checksum
+ is significantly more expensive than a CRC32C checksum, the manifest
+ should normally be small enough that the extra computation won't matter
+ very much.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="backup-manifest-files">
+ <title>Backup Manifest File Object</title>
+
+ <para>
+ The object which describes a single file contains either a
+ <literal>Path</literal> key or an <literal>Encoded-Path</literal> key.
+ Normally, the <literal>Path</literal> key will be present. The
+ associated string value is the path of the file relative to the root
+ of the backup directory. Files located in a user-defined tablespace
+ will have paths whose first two components are <filename>pg_tblspc</filename> and the OID
+ of the tablespace. If the path is not a string that is legal in UTF-8,
+ or if the user requests that encoded paths be used for all files, then
+ the <literal>Encoded-Path</literal> key will be present instead. This
+ stores the same data, but it is encoded as a string of hexadecimal
+ digits. Each pair of hexadecimal digits in the string represents a
+ single octet.
+ </para>
+
+ <para>
+ The following two keys are always present:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Size</literal></term>
+ <listitem>
+ <para>
+ The expected size of this file, as an integer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Last-Modified</literal></term>
+ <listitem>
+ <para>
+ The last modification time of the file as reported by the server at
+ the time of the backup. Unlike the other fields stored in the backup,
+ this field is not used by <xref linkend="app-pgverifybackup" />.
+ It is included only for informational purposes.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ If the backup was taken with file checksums enabled, the following
+ keys will be present:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Checksum-Algorithm</literal></term>
+ <listitem>
+ <para>
+ The checksum algorithm used to compute a checksum for this file.
+ Currently, this will be the same for every file in the backup
+ manifest, but this may change in future releases. At present, the
+ supported checksum algorithms are <literal>CRC32C</literal>,
+ <literal>SHA224</literal>,
+ <literal>SHA256</literal>,
+ <literal>SHA384</literal>, and
+ <literal>SHA512</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Checksum</literal></term>
+ <listitem>
+ <para>
+ The checksum computed for this file, stored as a series of
+ hexadecimal characters, two for each byte of the checksum.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="backup-manifest-wal-ranges">
+ <title>Backup Manifest WAL Range Object</title>
+
+ <para>
+ The object which describes a WAL range always has three keys:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Timeline</literal></term>
+ <listitem>
+ <para>
+ The timeline for this range of WAL records, as an integer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Start-LSN</literal></term>
+ <listitem>
+ <para>
+ The LSN at which replay must begin on the indicated timeline in order to
+ make use of this backup. The LSN is stored in the format normally used
+ by <productname>PostgreSQL</productname>; that is, it is a string
+ consisting of two strings of hexadecimal characters, each with a length
+ of between 1 and 8, separated by a slash.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>End-LSN</literal></term>
+ <listitem>
+ <para>
+ The earliest LSN at which replay on the indicated timeline may end when
+ making use of this backup. This is stored in the same format as
+ <literal>Start-LSN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Ordinarily, there will be only a single WAL range. However, if a backup is
+ taken from a standby which switches timelines during the backup due to an
+ upstream promotion, it is possible for multiple ranges to be present, each
+ with a different timeline. There will never be multiple WAL ranges present
+ for the same timeline.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml
new file mode 100644
index 0000000..6c55f74
--- /dev/null
+++ b/doc/src/sgml/backup.sgml
@@ -0,0 +1,1496 @@
+<!-- doc/src/sgml/backup.sgml -->
+
+<chapter id="backup">
+ <title>Backup and Restore</title>
+
+ <indexterm zone="backup"><primary>backup</primary></indexterm>
+
+ <para>
+ As with everything that contains valuable data, <productname>PostgreSQL</productname>
+ databases should be backed up regularly. While the procedure is
+ essentially simple, it is important to have a clear understanding of
+ the underlying techniques and assumptions.
+ </para>
+
+ <para>
+ There are three fundamentally different approaches to backing up
+ <productname>PostgreSQL</productname> data:
+ <itemizedlist>
+ <listitem><para><acronym>SQL</acronym> dump</para></listitem>
+ <listitem><para>File system level backup</para></listitem>
+ <listitem><para>Continuous archiving</para></listitem>
+ </itemizedlist>
+ Each has its own strengths and weaknesses; each is discussed in turn
+ in the following sections.
+ </para>
+
+ <sect1 id="backup-dump">
+ <title><acronym>SQL</acronym> Dump</title>
+
+ <para>
+ The idea behind this dump method is to generate a file with SQL
+ commands that, when fed back to the server, will recreate the
+ database in the same state as it was at the time of the dump.
+ <productname>PostgreSQL</productname> provides the utility program
+ <xref linkend="app-pgdump"/> for this purpose. The basic usage of this
+ command is:
+<synopsis>
+pg_dump <replaceable class="parameter">dbname</replaceable> &gt; <replaceable class="parameter">dumpfile</replaceable>
+</synopsis>
+ As you see, <application>pg_dump</application> writes its result to the
+ standard output. We will see below how this can be useful.
+ While the above command creates a text file, <application>pg_dump</application>
+ can create files in other formats that allow for parallelism and more
+ fine-grained control of object restoration.
+ </para>
+
+ <para>
+ <application>pg_dump</application> is a regular <productname>PostgreSQL</productname>
+ client application (albeit a particularly clever one). This means
+ that you can perform this backup procedure from any remote host that has
+ access to the database. But remember that <application>pg_dump</application>
+ does not operate with special permissions. In particular, it must
+ have read access to all tables that you want to back up, so in order
+ to back up the entire database you almost always have to run it as a
+ database superuser. (If you do not have sufficient privileges to back up
+ the entire database, you can still back up portions of the database to which
+ you do have access using options such as
+ <option>-n <replaceable>schema</replaceable></option>
+ or <option>-t <replaceable>table</replaceable></option>.)
+ </para>
+
+ <para>
+ To specify which database server <application>pg_dump</application> should
+ contact, use the command line options <option>-h
+ <replaceable>host</replaceable></option> and <option>-p <replaceable>port</replaceable></option>. The
+ default host is the local host or whatever your
+ <envar>PGHOST</envar> environment variable specifies. Similarly,
+ the default port is indicated by the <envar>PGPORT</envar>
+ environment variable or, failing that, by the compiled-in default.
+ (Conveniently, the server will normally have the same compiled-in
+ default.)
+ </para>
+
+ <para>
+ Like any other <productname>PostgreSQL</productname> client application,
+ <application>pg_dump</application> will by default connect with the database
+ user name that is equal to the current operating system user name. To override
+ this, either specify the <option>-U</option> option or set the
+ environment variable <envar>PGUSER</envar>. Remember that
+ <application>pg_dump</application> connections are subject to the normal
+ client authentication mechanisms (which are described in <xref
+ linkend="client-authentication"/>).
+ </para>
+
+ <para>
+ An important advantage of <application>pg_dump</application> over the other backup
+ methods described later is that <application>pg_dump</application>'s output can
+ generally be re-loaded into newer versions of <productname>PostgreSQL</productname>,
+ whereas file-level backups and continuous archiving are both extremely
+ server-version-specific. <application>pg_dump</application> is also the only method
+ that will work when transferring a database to a different machine
+ architecture, such as going from a 32-bit to a 64-bit server.
+ </para>
+
+ <para>
+ Dumps created by <application>pg_dump</application> are internally consistent,
+ meaning, the dump represents a snapshot of the database at the time
+ <application>pg_dump</application> began running. <application>pg_dump</application> does not
+ block other operations on the database while it is working.
+ (Exceptions are those operations that need to operate with an
+ exclusive lock, such as most forms of <command>ALTER TABLE</command>.)
+ </para>
+
+ <sect2 id="backup-dump-restore">
+ <title>Restoring the Dump</title>
+
+ <para>
+ Text files created by <application>pg_dump</application> are intended to
+ be read in by the <application>psql</application> program. The
+ general command form to restore a dump is
+<synopsis>
+psql <replaceable class="parameter">dbname</replaceable> &lt; <replaceable class="parameter">dumpfile</replaceable>
+</synopsis>
+ where <replaceable class="parameter">dumpfile</replaceable> is the
+ file output by the <application>pg_dump</application> command. The database <replaceable
+ class="parameter">dbname</replaceable> will not be created by this
+ command, so you must create it yourself from <literal>template0</literal>
+ before executing <application>psql</application> (e.g., with
+ <literal>createdb -T template0 <replaceable
+ class="parameter">dbname</replaceable></literal>). <application>psql</application>
+ supports options similar to <application>pg_dump</application> for specifying
+ the database server to connect to and the user name to use. See
+ the <xref linkend="app-psql"/> reference page for more information.
+ Non-text file dumps are restored using the <xref
+ linkend="app-pgrestore"/> utility.
+ </para>
+
+ <para>
+ Before restoring an SQL dump, all the users who own objects or were
+ granted permissions on objects in the dumped database must already
+ exist. If they do not, the restore will fail to recreate the
+ objects with the original ownership and/or permissions.
+ (Sometimes this is what you want, but usually it is not.)
+ </para>
+
+ <para>
+ By default, the <application>psql</application> script will continue to
+ execute after an SQL error is encountered. You might wish to run
+ <application>psql</application> with
+ the <literal>ON_ERROR_STOP</literal> variable set to alter that
+ behavior and have <application>psql</application> exit with an
+ exit status of 3 if an SQL error occurs:
+<programlisting>
+psql --set ON_ERROR_STOP=on <replaceable>dbname</replaceable> &lt; <replaceable>dumpfile</replaceable>
+</programlisting>
+ Either way, you will only have a partially restored database.
+ Alternatively, you can specify that the whole dump should be
+ restored as a single transaction, so the restore is either fully
+ completed or fully rolled back. This mode can be specified by
+ passing the <option>-1</option> or <option>--single-transaction</option>
+ command-line options to <application>psql</application>. When using this
+ mode, be aware that even a minor error can rollback a
+ restore that has already run for many hours. However, that might
+ still be preferable to manually cleaning up a complex database
+ after a partially restored dump.
+ </para>
+
+ <para>
+ The ability of <application>pg_dump</application> and <application>psql</application> to
+ write to or read from pipes makes it possible to dump a database
+ directly from one server to another, for example:
+<programlisting>
+pg_dump -h <replaceable>host1</replaceable> <replaceable>dbname</replaceable> | psql -h <replaceable>host2</replaceable> <replaceable>dbname</replaceable>
+</programlisting>
+ </para>
+
+ <important>
+ <para>
+ The dumps produced by <application>pg_dump</application> are relative to
+ <literal>template0</literal>. This means that any languages, procedures,
+ etc. added via <literal>template1</literal> will also be dumped by
+ <application>pg_dump</application>. As a result, when restoring, if you are
+ using a customized <literal>template1</literal>, you must create the
+ empty database from <literal>template0</literal>, as in the example
+ above.
+ </para>
+ </important>
+
+ <para>
+ After restoring a backup, it is wise to run <link
+ linkend="sql-analyze"><command>ANALYZE</command></link> on each
+ database so the query optimizer has useful statistics;
+ see <xref linkend="vacuum-for-statistics"/>
+ and <xref linkend="autovacuum"/> for more information.
+ For more advice on how to load large amounts of data
+ into <productname>PostgreSQL</productname> efficiently, refer to <xref
+ linkend="populate"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="backup-dump-all">
+ <title>Using <application>pg_dumpall</application></title>
+
+ <para>
+ <application>pg_dump</application> dumps only a single database at a time,
+ and it does not dump information about roles or tablespaces
+ (because those are cluster-wide rather than per-database).
+ To support convenient dumping of the entire contents of a database
+ cluster, the <xref linkend="app-pg-dumpall"/> program is provided.
+ <application>pg_dumpall</application> backs up each database in a given
+ cluster, and also preserves cluster-wide data such as role and
+ tablespace definitions. The basic usage of this command is:
+<synopsis>
+pg_dumpall &gt; <replaceable>dumpfile</replaceable>
+</synopsis>
+ The resulting dump can be restored with <application>psql</application>:
+<synopsis>
+psql -f <replaceable class="parameter">dumpfile</replaceable> postgres
+</synopsis>
+ (Actually, you can specify any existing database name to start from,
+ but if you are loading into an empty cluster then <literal>postgres</literal>
+ should usually be used.) It is always necessary to have
+ database superuser access when restoring a <application>pg_dumpall</application>
+ dump, as that is required to restore the role and tablespace information.
+ If you use tablespaces, make sure that the tablespace paths in the
+ dump are appropriate for the new installation.
+ </para>
+
+ <para>
+ <application>pg_dumpall</application> works by emitting commands to re-create
+ roles, tablespaces, and empty databases, then invoking
+ <application>pg_dump</application> for each database. This means that while
+ each database will be internally consistent, the snapshots of
+ different databases are not synchronized.
+ </para>
+
+ <para>
+ Cluster-wide data can be dumped alone using the
+ <application>pg_dumpall</application> <option>--globals-only</option> option.
+ This is necessary to fully backup the cluster if running the
+ <application>pg_dump</application> command on individual databases.
+ </para>
+ </sect2>
+
+ <sect2 id="backup-dump-large">
+ <title>Handling Large Databases</title>
+
+ <para>
+ Some operating systems have maximum file size limits that cause
+ problems when creating large <application>pg_dump</application> output files.
+ Fortunately, <application>pg_dump</application> can write to the standard
+ output, so you can use standard Unix tools to work around this
+ potential problem. There are several possible methods:
+ </para>
+
+ <formalpara>
+ <title>Use compressed dumps.</title>
+ <para>
+ You can use your favorite compression program, for example
+ <application>gzip</application>:
+
+<programlisting>
+pg_dump <replaceable class="parameter">dbname</replaceable> | gzip &gt; <replaceable class="parameter">filename</replaceable>.gz
+</programlisting>
+
+ Reload with:
+
+<programlisting>
+gunzip -c <replaceable class="parameter">filename</replaceable>.gz | psql <replaceable class="parameter">dbname</replaceable>
+</programlisting>
+
+ or:
+
+<programlisting>
+cat <replaceable class="parameter">filename</replaceable>.gz | gunzip | psql <replaceable class="parameter">dbname</replaceable>
+</programlisting>
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Use <command>split</command>.</title>
+ <para>
+ The <command>split</command> command
+ allows you to split the output into smaller files that are
+ acceptable in size to the underlying file system. For example, to
+ make 2 gigabyte chunks:
+
+<programlisting>
+pg_dump <replaceable class="parameter">dbname</replaceable> | split -b 2G - <replaceable class="parameter">filename</replaceable>
+</programlisting>
+
+ Reload with:
+
+<programlisting>
+cat <replaceable class="parameter">filename</replaceable>* | psql <replaceable class="parameter">dbname</replaceable>
+</programlisting>
+
+ If using GNU <application>split</application>, it is possible to
+ use it and <application>gzip</application> together:
+
+<programlisting>
+pg_dump <replaceable class="parameter">dbname</replaceable> | split -b 2G --filter='gzip > $FILE.gz'
+</programlisting>
+
+ It can be restored using <command>zcat</command>.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Use <application>pg_dump</application>'s custom dump format.</title>
+ <para>
+ If <productname>PostgreSQL</productname> was built on a system with the
+ <application>zlib</application> compression library installed, the custom dump
+ format will compress data as it writes it to the output file. This will
+ produce dump file sizes similar to using <command>gzip</command>, but it
+ has the added advantage that tables can be restored selectively. The
+ following command dumps a database using the custom dump format:
+
+<programlisting>
+pg_dump -Fc <replaceable class="parameter">dbname</replaceable> &gt; <replaceable class="parameter">filename</replaceable>
+</programlisting>
+
+ A custom-format dump is not a script for <application>psql</application>, but
+ instead must be restored with <application>pg_restore</application>, for example:
+
+<programlisting>
+pg_restore -d <replaceable class="parameter">dbname</replaceable> <replaceable class="parameter">filename</replaceable>
+</programlisting>
+
+ See the <xref linkend="app-pgdump"/> and <xref
+ linkend="app-pgrestore"/> reference pages for details.
+ </para>
+ </formalpara>
+
+ <para>
+ For very large databases, you might need to combine <command>split</command>
+ with one of the other two approaches.
+ </para>
+
+ <formalpara>
+ <title>Use <application>pg_dump</application>'s parallel dump feature.</title>
+ <para>
+ To speed up the dump of a large database, you can use
+ <application>pg_dump</application>'s parallel mode. This will dump
+ multiple tables at the same time. You can control the degree of
+ parallelism with the <command>-j</command> parameter. Parallel dumps
+ are only supported for the "directory" archive format.
+
+<programlisting>
+pg_dump -j <replaceable class="parameter">num</replaceable> -F d -f <replaceable class="parameter">out.dir</replaceable> <replaceable class="parameter">dbname</replaceable>
+</programlisting>
+
+ You can use <command>pg_restore -j</command> to restore a dump in parallel.
+ This will work for any archive of either the "custom" or the "directory"
+ archive mode, whether or not it has been created with <command>pg_dump -j</command>.
+ </para>
+ </formalpara>
+ </sect2>
+ </sect1>
+
+ <sect1 id="backup-file">
+ <title>File System Level Backup</title>
+
+ <para>
+ An alternative backup strategy is to directly copy the files that
+ <productname>PostgreSQL</productname> uses to store the data in the database;
+ <xref linkend="creating-cluster"/> explains where these files
+ are located. You can use whatever method you prefer
+ for doing file system backups; for example:
+
+<programlisting>
+tar -cf backup.tar /usr/local/pgsql/data
+</programlisting>
+ </para>
+
+ <para>
+ There are two restrictions, however, which make this method
+ impractical, or at least inferior to the <application>pg_dump</application>
+ method:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ The database server <emphasis>must</emphasis> be shut down in order to
+ get a usable backup. Half-way measures such as disallowing all
+ connections will <emphasis>not</emphasis> work
+ (in part because <command>tar</command> and similar tools do not take
+ an atomic snapshot of the state of the file system,
+ but also because of internal buffering within the server).
+ Information about stopping the server can be found in
+ <xref linkend="server-shutdown"/>. Needless to say, you
+ also need to shut down the server before restoring the data.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you have dug into the details of the file system layout of the
+ database, you might be tempted to try to back up or restore only certain
+ individual tables or databases from their respective files or
+ directories. This will <emphasis>not</emphasis> work because the
+ information contained in these files is not usable without
+ the commit log files,
+ <filename>pg_xact/*</filename>, which contain the commit status of
+ all transactions. A table file is only usable with this
+ information. Of course it is also impossible to restore only a
+ table and the associated <filename>pg_xact</filename> data
+ because that would render all other tables in the database
+ cluster useless. So file system backups only work for complete
+ backup and restoration of an entire database cluster.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ An alternative file-system backup approach is to make a
+ <quote>consistent snapshot</quote> of the data directory, if the
+ file system supports that functionality (and you are willing to
+ trust that it is implemented correctly). The typical procedure is
+ to make a <quote>frozen snapshot</quote> of the volume containing the
+ database, then copy the whole data directory (not just parts, see
+ above) from the snapshot to a backup device, then release the frozen
+ snapshot. This will work even while the database server is running.
+ However, a backup created in this way saves
+ the database files in a state as if the database server was not
+ properly shut down; therefore, when you start the database server
+ on the backed-up data, it will think the previous server instance
+ crashed and will replay the WAL log. This is not a problem; just
+ be aware of it (and be sure to include the WAL files in your backup).
+ You can perform a <command>CHECKPOINT</command> before taking the
+ snapshot to reduce recovery time.
+ </para>
+
+ <para>
+ If your database is spread across multiple file systems, there might not
+ be any way to obtain exactly-simultaneous frozen snapshots of all
+ the volumes. For example, if your data files and WAL log are on different
+ disks, or if tablespaces are on different file systems, it might
+ not be possible to use snapshot backup because the snapshots
+ <emphasis>must</emphasis> be simultaneous.
+ Read your file system documentation very carefully before trusting
+ the consistent-snapshot technique in such situations.
+ </para>
+
+ <para>
+ If simultaneous snapshots are not possible, one option is to shut down
+ the database server long enough to establish all the frozen snapshots.
+ Another option is to perform a continuous archiving base backup (<xref
+ linkend="backup-base-backup"/>) because such backups are immune to file
+ system changes during the backup. This requires enabling continuous
+ archiving just during the backup process; restore is done using
+ continuous archive recovery (<xref linkend="backup-pitr-recovery"/>).
+ </para>
+
+ <para>
+ Another option is to use <application>rsync</application> to perform a file
+ system backup. This is done by first running <application>rsync</application>
+ while the database server is running, then shutting down the database
+ server long enough to do an <command>rsync --checksum</command>.
+ (<option>--checksum</option> is necessary because <command>rsync</command> only
+ has file modification-time granularity of one second.) The
+ second <application>rsync</application> will be quicker than the first,
+ because it has relatively little data to transfer, and the end result
+ will be consistent because the server was down. This method
+ allows a file system backup to be performed with minimal downtime.
+ </para>
+
+ <para>
+ Note that a file system backup will typically be larger
+ than an SQL dump. (<application>pg_dump</application> does not need to dump
+ the contents of indexes for example, just the commands to recreate
+ them.) However, taking a file system backup might be faster.
+ </para>
+ </sect1>
+
+ <sect1 id="continuous-archiving">
+ <title>Continuous Archiving and Point-in-Time Recovery (PITR)</title>
+
+ <indexterm zone="backup">
+ <primary>continuous archiving</primary>
+ </indexterm>
+
+ <indexterm zone="backup">
+ <primary>point-in-time recovery</primary>
+ </indexterm>
+
+ <indexterm zone="backup">
+ <primary>PITR</primary>
+ </indexterm>
+
+ <para>
+ At all times, <productname>PostgreSQL</productname> maintains a
+ <firstterm>write ahead log</firstterm> (WAL) in the <filename>pg_wal/</filename>
+ subdirectory of the cluster's data directory. The log records
+ every change made to the database's data files. This log exists
+ primarily for crash-safety purposes: if the system crashes, the
+ database can be restored to consistency by <quote>replaying</quote> the
+ log entries made since the last checkpoint. However, the existence
+ of the log makes it possible to use a third strategy for backing up
+ databases: we can combine a file-system-level backup with backup of
+ the WAL files. If recovery is needed, we restore the file system backup and
+ then replay from the backed-up WAL files to bring the system to a
+ current state. This approach is more complex to administer than
+ either of the previous approaches, but it has some significant
+ benefits:
+ <itemizedlist>
+ <listitem>
+ <para>
+ We do not need a perfectly consistent file system backup as the starting point.
+ Any internal inconsistency in the backup will be corrected by log
+ replay (this is not significantly different from what happens during
+ crash recovery). So we do not need a file system snapshot capability,
+ just <application>tar</application> or a similar archiving tool.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Since we can combine an indefinitely long sequence of WAL files
+ for replay, continuous backup can be achieved simply by continuing to archive
+ the WAL files. This is particularly valuable for large databases, where
+ it might not be convenient to take a full backup frequently.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It is not necessary to replay the WAL entries all the
+ way to the end. We could stop the replay at any point and have a
+ consistent snapshot of the database as it was at that time. Thus,
+ this technique supports <firstterm>point-in-time recovery</firstterm>: it is
+ possible to restore the database to its state at any time since your base
+ backup was taken.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If we continuously feed the series of WAL files to another
+ machine that has been loaded with the same base backup file, we
+ have a <firstterm>warm standby</firstterm> system: at any point we can bring up
+ the second machine and it will have a nearly-current copy of the
+ database.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <note>
+ <para>
+ <application>pg_dump</application> and
+ <application>pg_dumpall</application> do not produce file-system-level
+ backups and cannot be used as part of a continuous-archiving solution.
+ Such dumps are <emphasis>logical</emphasis> and do not contain enough
+ information to be used by WAL replay.
+ </para>
+ </note>
+
+ <para>
+ As with the plain file-system-backup technique, this method can only
+ support restoration of an entire database cluster, not a subset.
+ Also, it requires a lot of archival storage: the base backup might be bulky,
+ and a busy system will generate many megabytes of WAL traffic that
+ have to be archived. Still, it is the preferred backup technique in
+ many situations where high reliability is needed.
+ </para>
+
+ <para>
+ To recover successfully using continuous archiving (also called
+ <quote>online backup</quote> by many database vendors), you need a continuous
+ sequence of archived WAL files that extends back at least as far as the
+ start time of your backup. So to get started, you should set up and test
+ your procedure for archiving WAL files <emphasis>before</emphasis> you take your
+ first base backup. Accordingly, we first discuss the mechanics of
+ archiving WAL files.
+ </para>
+
+ <sect2 id="backup-archiving-wal">
+ <title>Setting Up WAL Archiving</title>
+
+ <para>
+ In an abstract sense, a running <productname>PostgreSQL</productname> system
+ produces an indefinitely long sequence of WAL records. The system
+ physically divides this sequence into WAL <firstterm>segment
+ files</firstterm>, which are normally 16MB apiece (although the segment size
+ can be altered during <application>initdb</application>). The segment
+ files are given numeric names that reflect their position in the
+ abstract WAL sequence. When not using WAL archiving, the system
+ normally creates just a few segment files and then
+ <quote>recycles</quote> them by renaming no-longer-needed segment files
+ to higher segment numbers. It's assumed that segment files whose
+ contents precede the last checkpoint are no longer of
+ interest and can be recycled.
+ </para>
+
+ <para>
+ When archiving WAL data, we need to capture the contents of each segment
+ file once it is filled, and save that data somewhere before the segment
+ file is recycled for reuse. Depending on the application and the
+ available hardware, there could be many different ways of <quote>saving
+ the data somewhere</quote>: we could copy the segment files to an NFS-mounted
+ directory on another machine, write them onto a tape drive (ensuring that
+ you have a way of identifying the original name of each file), or batch
+ them together and burn them onto CDs, or something else entirely. To
+ provide the database administrator with flexibility,
+ <productname>PostgreSQL</productname> tries not to make any assumptions about how
+ the archiving will be done. Instead, <productname>PostgreSQL</productname> lets
+ the administrator specify a shell command or an archive library to be executed to copy a
+ completed segment file to wherever it needs to go. This could be as simple
+ as a shell command that uses <literal>cp</literal>, or it could invoke a
+ complex C function &mdash; it's all up to you.
+ </para>
+
+ <para>
+ To enable WAL archiving, set the <xref linkend="guc-wal-level"/>
+ configuration parameter to <literal>replica</literal> or higher,
+ <xref linkend="guc-archive-mode"/> to <literal>on</literal>,
+ specify the shell command to use in the <xref
+ linkend="guc-archive-command"/> configuration parameter
+ or specify the library to use in the <xref
+ linkend="guc-archive-library"/> configuration parameter. In practice
+ these settings will always be placed in the
+ <filename>postgresql.conf</filename> file.
+ </para>
+
+ <para>
+ In <varname>archive_command</varname>,
+ <literal>%p</literal> is replaced by the path name of the file to
+ archive, while <literal>%f</literal> is replaced by only the file name.
+ (The path name is relative to the current working directory,
+ i.e., the cluster's data directory.)
+ Use <literal>%%</literal> if you need to embed an actual <literal>%</literal>
+ character in the command. The simplest useful command is something
+ like:
+<programlisting>
+archive_command = 'test ! -f /mnt/server/archivedir/%f &amp;&amp; cp %p /mnt/server/archivedir/%f' # Unix
+archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows
+</programlisting>
+ which will copy archivable WAL segments to the directory
+ <filename>/mnt/server/archivedir</filename>. (This is an example, not a
+ recommendation, and might not work on all platforms.) After the
+ <literal>%p</literal> and <literal>%f</literal> parameters have been replaced,
+ the actual command executed might look like this:
+<programlisting>
+test ! -f /mnt/server/archivedir/00000001000000A900000065 &amp;&amp; cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065
+</programlisting>
+ A similar command will be generated for each new file to be archived.
+ </para>
+
+ <para>
+ The archive command will be executed under the ownership of the same
+ user that the <productname>PostgreSQL</productname> server is running as. Since
+ the series of WAL files being archived contains effectively everything
+ in your database, you will want to be sure that the archived data is
+ protected from prying eyes; for example, archive into a directory that
+ does not have group or world read access.
+ </para>
+
+ <para>
+ It is important that the archive command return zero exit status if and
+ only if it succeeds. Upon getting a zero result,
+ <productname>PostgreSQL</productname> will assume that the file has been
+ successfully archived, and will remove or recycle it. However, a nonzero
+ status tells <productname>PostgreSQL</productname> that the file was not archived;
+ it will try again periodically until it succeeds.
+ </para>
+
+ <para>
+ Another way to archive is to use a custom archive module as the
+ <varname>archive_library</varname>. Since such modules are written in
+ <literal>C</literal>, creating your own may require considerably more effort
+ than writing a shell command. However, archive modules can be more
+ performant than archiving via shell, and they will have access to many
+ useful server resources. For more information about archive modules, see
+ <xref linkend="archive-modules"/>.
+ </para>
+
+ <para>
+ When the archive command is terminated by a signal (other than
+ <systemitem>SIGTERM</systemitem> that is used as part of a server
+ shutdown) or an error by the shell with an exit status greater than
+ 125 (such as command not found), or if the archive function emits an
+ <literal>ERROR</literal> or <literal>FATAL</literal>, the archiver process
+ aborts and gets restarted by the postmaster. In such cases, the failure is
+ not reported in <xref linkend="pg-stat-archiver-view"/>.
+ </para>
+
+ <para>
+ Archive commands and libraries should generally be designed to refuse to overwrite
+ any pre-existing archive file. This is an important safety feature to
+ preserve the integrity of your archive in case of administrator error
+ (such as sending the output of two different servers to the same archive
+ directory).
+ </para>
+
+ <para>
+ It is advisable to test your proposed archive command or library to ensure that it
+ indeed does not overwrite an existing file, <emphasis>and that it returns
+ nonzero status or <literal>false</literal>, respectively, in this case</emphasis>.
+ The example command above for Unix ensures this by including a separate
+ <command>test</command> step. On some Unix platforms, <command>cp</command> has
+ switches such as <option>-i</option> that can be used to do the same thing
+ less verbosely, but you should not rely on these without verifying that
+ the right exit status is returned. (In particular, GNU <command>cp</command>
+ will return status zero when <option>-i</option> is used and the target file
+ already exists, which is <emphasis>not</emphasis> the desired behavior.)
+ </para>
+
+ <para>
+ While designing your archiving setup, consider what will happen if
+ the archive command or library fails repeatedly because some aspect requires
+ operator intervention or the archive runs out of space. For example, this
+ could occur if you write to tape without an autochanger; when the tape
+ fills, nothing further can be archived until the tape is swapped.
+ You should ensure that any error condition or request to a human operator
+ is reported appropriately so that the situation can be
+ resolved reasonably quickly. The <filename>pg_wal/</filename> directory will
+ continue to fill with WAL segment files until the situation is resolved.
+ (If the file system containing <filename>pg_wal/</filename> fills up,
+ <productname>PostgreSQL</productname> will do a PANIC shutdown. No committed
+ transactions will be lost, but the database will remain offline until
+ you free some space.)
+ </para>
+
+ <para>
+ The speed of the archive command or library is unimportant as long as it can keep up
+ with the average rate at which your server generates WAL data. Normal
+ operation continues even if the archiving process falls a little behind.
+ If archiving falls significantly behind, this will increase the amount of
+ data that would be lost in the event of a disaster. It will also mean that
+ the <filename>pg_wal/</filename> directory will contain large numbers of
+ not-yet-archived segment files, which could eventually exceed available
+ disk space. You are advised to monitor the archiving process to ensure that
+ it is working as you intend.
+ </para>
+
+ <para>
+ In writing your archive command or library, you should assume that the file names to
+ be archived can be up to 64 characters long and can contain any
+ combination of ASCII letters, digits, and dots. It is not necessary to
+ preserve the original relative path (<literal>%p</literal>) but it is necessary to
+ preserve the file name (<literal>%f</literal>).
+ </para>
+
+ <para>
+ Note that although WAL archiving will allow you to restore any
+ modifications made to the data in your <productname>PostgreSQL</productname> database,
+ it will not restore changes made to configuration files (that is,
+ <filename>postgresql.conf</filename>, <filename>pg_hba.conf</filename> and
+ <filename>pg_ident.conf</filename>), since those are edited manually rather
+ than through SQL operations.
+ You might wish to keep the configuration files in a location that will
+ be backed up by your regular file system backup procedures. See
+ <xref linkend="runtime-config-file-locations"/> for how to relocate the
+ configuration files.
+ </para>
+
+ <para>
+ The archive command or function is only invoked on completed WAL segments. Hence,
+ if your server generates only little WAL traffic (or has slack periods
+ where it does so), there could be a long delay between the completion
+ of a transaction and its safe recording in archive storage. To put
+ a limit on how old unarchived data can be, you can set
+ <xref linkend="guc-archive-timeout"/> to force the server to switch
+ to a new WAL segment file at least that often. Note that archived
+ files that are archived early due to a forced switch are still the same
+ length as completely full files. It is therefore unwise to set a very
+ short <varname>archive_timeout</varname> &mdash; it will bloat your archive
+ storage. <varname>archive_timeout</varname> settings of a minute or so are
+ usually reasonable.
+ </para>
+
+ <para>
+ Also, you can force a segment switch manually with
+ <function>pg_switch_wal</function> if you want to ensure that a
+ just-finished transaction is archived as soon as possible. Other utility
+ functions related to WAL management are listed in <xref
+ linkend="functions-admin-backup-table"/>.
+ </para>
+
+ <para>
+ When <varname>wal_level</varname> is <literal>minimal</literal> some SQL commands
+ are optimized to avoid WAL logging, as described in <xref
+ linkend="populate-pitr"/>. If archiving or streaming replication were
+ turned on during execution of one of these statements, WAL would not
+ contain enough information for archive recovery. (Crash recovery is
+ unaffected.) For this reason, <varname>wal_level</varname> can only be changed at
+ server start. However, <varname>archive_command</varname> and <varname>archive_library</varname> can be changed with a
+ configuration file reload. If you are archiving via shell and wish to
+ temporarily stop archiving,
+ one way to do it is to set <varname>archive_command</varname> to the empty
+ string (<literal>''</literal>).
+ This will cause WAL files to accumulate in <filename>pg_wal/</filename> until a
+ working <varname>archive_command</varname> is re-established.
+ </para>
+ </sect2>
+
+ <sect2 id="backup-base-backup">
+ <title>Making a Base Backup</title>
+
+ <para>
+ The easiest way to perform a base backup is to use the
+ <xref linkend="app-pgbasebackup"/> tool. It can create
+ a base backup either as regular files or as a tar archive. If more
+ flexibility than <xref linkend="app-pgbasebackup"/> can provide is
+ required, you can also make a base backup using the low level API
+ (see <xref linkend="backup-lowlevel-base-backup"/>).
+ </para>
+
+ <para>
+ It is not necessary to be concerned about the amount of time it takes
+ to make a base backup. However, if you normally run the
+ server with <varname>full_page_writes</varname> disabled, you might notice a drop
+ in performance while the backup runs since <varname>full_page_writes</varname> is
+ effectively forced on during backup mode.
+ </para>
+
+ <para>
+ To make use of the backup, you will need to keep all the WAL
+ segment files generated during and after the file system backup.
+ To aid you in doing this, the base backup process
+ creates a <firstterm>backup history file</firstterm> that is immediately
+ stored into the WAL archive area. This file is named after the first
+ WAL segment file that you need for the file system backup.
+ For example, if the starting WAL file is
+ <literal>0000000100001234000055CD</literal> the backup history file will be
+ named something like
+ <literal>0000000100001234000055CD.007C9330.backup</literal>. (The second
+ part of the file name stands for an exact position within the WAL
+ file, and can ordinarily be ignored.) Once you have safely archived
+ the file system backup and the WAL segment files used during the
+ backup (as specified in the backup history file), all archived WAL
+ segments with names numerically less are no longer needed to recover
+ the file system backup and can be deleted. However, you should
+ consider keeping several backup sets to be absolutely certain that
+ you can recover your data.
+ </para>
+
+ <para>
+ The backup history file is just a small text file. It contains the
+ label string you gave to <xref linkend="app-pgbasebackup"/>, as well as
+ the starting and ending times and WAL segments of the backup.
+ If you used the label to identify the associated dump file,
+ then the archived history file is enough to tell you which dump file to
+ restore.
+ </para>
+
+ <para>
+ Since you have to keep around all the archived WAL files back to your
+ last base backup, the interval between base backups should usually be
+ chosen based on how much storage you want to expend on archived WAL
+ files. You should also consider how long you are prepared to spend
+ recovering, if recovery should be necessary &mdash; the system will have to
+ replay all those WAL segments, and that could take awhile if it has
+ been a long time since the last base backup.
+ </para>
+ </sect2>
+
+ <sect2 id="backup-lowlevel-base-backup">
+ <title>Making a Base Backup Using the Low Level API</title>
+ <para>
+ The procedure for making a base backup using the low level
+ APIs contains a few more steps than
+ the <xref linkend="app-pgbasebackup"/> method, but is relatively
+ simple. It is very important that these steps are executed in
+ sequence, and that the success of a step is verified before
+ proceeding to the next step.
+ </para>
+ <para>
+ Multiple backups are able to be run concurrently (both those
+ started using this backup API and those started using
+ <xref linkend="app-pgbasebackup"/>).
+ </para>
+ <para>
+ <orderedlist>
+ <listitem>
+ <para>
+ Ensure that WAL archiving is enabled and working.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Connect to the server (it does not matter which database) as a user with
+ rights to run <function>pg_backup_start</function> (superuser,
+ or a user who has been granted <literal>EXECUTE</literal> on the
+ function) and issue the command:
+<programlisting>
+SELECT pg_backup_start(label => 'label', fast => false);
+</programlisting>
+ where <literal>label</literal> is any string you want to use to uniquely
+ identify this backup operation. The connection
+ calling <function>pg_backup_start</function> must be maintained until the end of
+ the backup, or the backup will be automatically aborted.
+ </para>
+
+ <para>
+ Online backups are always started at the beginning of a checkpoint.
+ By default, <function>pg_backup_start</function> will wait for the next
+ regularly scheduled checkpoint to complete, which may take a long time (see the
+ configuration parameters <xref linkend="guc-checkpoint-timeout"/> and
+ <xref linkend="guc-checkpoint-completion-target"/>). This is
+ usually preferable as it minimizes the impact on the running system. If you
+ want to start the backup as soon as possible, pass <literal>true</literal> as
+ the second parameter to <function>pg_backup_start</function> and it will
+ request an immediate checkpoint, which will finish as fast as possible using
+ as much I/O as possible.
+ </para>
+
+ </listitem>
+ <listitem>
+ <para>
+ Perform the backup, using any convenient file-system-backup tool
+ such as <application>tar</application> or <application>cpio</application> (not
+ <application>pg_dump</application> or
+ <application>pg_dumpall</application>). It is neither
+ necessary nor desirable to stop normal operation of the database
+ while you do this. See
+ <xref linkend="backup-lowlevel-base-backup-data"/> for things to
+ consider during this backup.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In the same connection as before, issue the command:
+<programlisting>
+SELECT * FROM pg_backup_stop(wait_for_archive => true);
+</programlisting>
+ This terminates backup mode. On a primary, it also performs an automatic
+ switch to the next WAL segment. On a standby, it is not possible to
+ automatically switch WAL segments, so you may wish to run
+ <function>pg_switch_wal</function> on the primary to perform a manual
+ switch. The reason for the switch is to arrange for
+ the last WAL segment file written during the backup interval to be
+ ready to archive.
+ </para>
+ <para>
+ <function>pg_backup_stop</function> will return one row with three
+ values. The second of these fields should be written to a file named
+ <filename>backup_label</filename> in the root directory of the backup. The
+ third field should be written to a file named
+ <filename>tablespace_map</filename> unless the field is empty. These files are
+ vital to the backup working and must be written byte for byte without
+ modification, which may require opening the file in binary mode.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Once the WAL segment files active during the backup are archived, you are
+ done. The file identified by <function>pg_backup_stop</function>'s first return
+ value is the last segment that is required to form a complete set of
+ backup files. On a primary, if <varname>archive_mode</varname> is enabled and the
+ <literal>wait_for_archive</literal> parameter is <literal>true</literal>,
+ <function>pg_backup_stop</function> does not return until the last segment has
+ been archived.
+ On a standby, <varname>archive_mode</varname> must be <literal>always</literal> in order
+ for <function>pg_backup_stop</function> to wait.
+ Archiving of these files happens automatically since you have
+ already configured <varname>archive_command</varname> or <varname>archive_library</varname>.
+ In most cases this happens quickly, but you are advised to monitor your
+ archive system to ensure there are no delays.
+ If the archive process has fallen behind because of failures of the
+ archive command or library, it will keep retrying
+ until the archive succeeds and the backup is complete.
+ If you wish to place a time limit on the execution of
+ <function>pg_backup_stop</function>, set an appropriate
+ <varname>statement_timeout</varname> value, but make note that if
+ <function>pg_backup_stop</function> terminates because of this your backup
+ may not be valid.
+ </para>
+ <para>
+ If the backup process monitors and ensures that all WAL segment files
+ required for the backup are successfully archived then the
+ <literal>wait_for_archive</literal> parameter (which defaults to true) can be set
+ to false to have
+ <function>pg_backup_stop</function> return as soon as the stop backup record is
+ written to the WAL. By default, <function>pg_backup_stop</function> will wait
+ until all WAL has been archived, which can take some time. This option
+ must be used with caution: if WAL archiving is not monitored correctly
+ then the backup might not include all of the WAL files and will
+ therefore be incomplete and not able to be restored.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ <sect3 id="backup-lowlevel-base-backup-data">
+ <title>Backing Up the Data Directory</title>
+ <para>
+ Some file system backup tools emit warnings or errors
+ if the files they are trying to copy change while the copy proceeds.
+ When taking a base backup of an active database, this situation is normal
+ and not an error. However, you need to ensure that you can distinguish
+ complaints of this sort from real errors. For example, some versions
+ of <application>rsync</application> return a separate exit code for
+ <quote>vanished source files</quote>, and you can write a driver script to
+ accept this exit code as a non-error case. Also, some versions of
+ GNU <application>tar</application> return an error code indistinguishable from
+ a fatal error if a file was truncated while <application>tar</application> was
+ copying it. Fortunately, GNU <application>tar</application> versions 1.16 and
+ later exit with 1 if a file was changed during the backup,
+ and 2 for other errors. With GNU <application>tar</application> version 1.23 and
+ later, you can use the warning options <literal>--warning=no-file-changed
+ --warning=no-file-removed</literal> to hide the related warning messages.
+ </para>
+
+ <para>
+ Be certain that your backup includes all of the files under
+ the database cluster directory (e.g., <filename>/usr/local/pgsql/data</filename>).
+ If you are using tablespaces that do not reside underneath this directory,
+ be careful to include them as well (and be sure that your backup
+ archives symbolic links as links, otherwise the restore will corrupt
+ your tablespaces).
+ </para>
+
+ <para>
+ You should, however, omit from the backup the files within the
+ cluster's <filename>pg_wal/</filename> subdirectory. This
+ slight adjustment is worthwhile because it reduces the risk
+ of mistakes when restoring. This is easy to arrange if
+ <filename>pg_wal/</filename> is a symbolic link pointing to someplace outside
+ the cluster directory, which is a common setup anyway for performance
+ reasons. You might also want to exclude <filename>postmaster.pid</filename>
+ and <filename>postmaster.opts</filename>, which record information
+ about the running <application>postmaster</application>, not about the
+ <application>postmaster</application> which will eventually use this backup.
+ (These files can confuse <application>pg_ctl</application>.)
+ </para>
+
+ <para>
+ It is often a good idea to also omit from the backup the files
+ within the cluster's <filename>pg_replslot/</filename> directory, so that
+ replication slots that exist on the primary do not become part of the
+ backup. Otherwise, the subsequent use of the backup to create a standby
+ may result in indefinite retention of WAL files on the standby, and
+ possibly bloat on the primary if hot standby feedback is enabled, because
+ the clients that are using those replication slots will still be connecting
+ to and updating the slots on the primary, not the standby. Even if the
+ backup is only intended for use in creating a new primary, copying the
+ replication slots isn't expected to be particularly useful, since the
+ contents of those slots will likely be badly out of date by the time
+ the new primary comes on line.
+ </para>
+
+ <para>
+ The contents of the directories <filename>pg_dynshmem/</filename>,
+ <filename>pg_notify/</filename>, <filename>pg_serial/</filename>,
+ <filename>pg_snapshots/</filename>, <filename>pg_stat_tmp/</filename>,
+ and <filename>pg_subtrans/</filename> (but not the directories themselves) can be
+ omitted from the backup as they will be initialized on postmaster startup.
+ </para>
+
+ <para>
+ Any file or directory beginning with <filename>pgsql_tmp</filename> can be
+ omitted from the backup. These files are removed on postmaster start and
+ the directories will be recreated as needed.
+ </para>
+
+ <para>
+ <filename>pg_internal.init</filename> files can be omitted from the
+ backup whenever a file of that name is found. These files contain
+ relation cache data that is always rebuilt when recovering.
+ </para>
+
+ <para>
+ The backup label
+ file includes the label string you gave to <function>pg_backup_start</function>,
+ as well as the time at which <function>pg_backup_start</function> was run, and
+ the name of the starting WAL file. In case of confusion it is therefore
+ possible to look inside a backup file and determine exactly which
+ backup session the dump file came from. The tablespace map file includes
+ the symbolic link names as they exist in the directory
+ <filename>pg_tblspc/</filename> and the full path of each symbolic link.
+ These files are not merely for your information; their presence and
+ contents are critical to the proper operation of the system's recovery
+ process.
+ </para>
+
+ <para>
+ It is also possible to make a backup while the server is
+ stopped. In this case, you obviously cannot use
+ <function>pg_backup_start</function> or <function>pg_backup_stop</function>, and
+ you will therefore be left to your own devices to keep track of which
+ backup is which and how far back the associated WAL files go.
+ It is generally better to follow the continuous archiving procedure above.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="backup-pitr-recovery">
+ <title>Recovering Using a Continuous Archive Backup</title>
+
+ <para>
+ Okay, the worst has happened and you need to recover from your backup.
+ Here is the procedure:
+ <orderedlist>
+ <listitem>
+ <para>
+ Stop the server, if it's running.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If you have the space to do so,
+ copy the whole cluster data directory and any tablespaces to a temporary
+ location in case you need them later. Note that this precaution will
+ require that you have enough free space on your system to hold two
+ copies of your existing database. If you do not have enough space,
+ you should at least save the contents of the cluster's <filename>pg_wal</filename>
+ subdirectory, as it might contain logs which
+ were not archived before the system went down.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Remove all existing files and subdirectories under the cluster data
+ directory and under the root directories of any tablespaces you are using.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Restore the database files from your file system backup. Be sure that they
+ are restored with the right ownership (the database system user, not
+ <literal>root</literal>!) and with the right permissions. If you are using
+ tablespaces,
+ you should verify that the symbolic links in <filename>pg_tblspc/</filename>
+ were correctly restored.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Remove any files present in <filename>pg_wal/</filename>; these came from the
+ file system backup and are therefore probably obsolete rather than current.
+ If you didn't archive <filename>pg_wal/</filename> at all, then recreate
+ it with proper permissions,
+ being careful to ensure that you re-establish it as a symbolic link
+ if you had it set up that way before.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If you have unarchived WAL segment files that you saved in step 2,
+ copy them into <filename>pg_wal/</filename>. (It is best to copy them,
+ not move them, so you still have the unmodified files if a
+ problem occurs and you have to start over.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Set recovery configuration settings in
+ <filename>postgresql.conf</filename> (see <xref
+ linkend="runtime-config-wal-archive-recovery"/>) and create a file
+ <filename>recovery.signal</filename> in the cluster
+ data directory. You might
+ also want to temporarily modify <filename>pg_hba.conf</filename> to prevent
+ ordinary users from connecting until you are sure the recovery was successful.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Start the server. The server will go into recovery mode and
+ proceed to read through the archived WAL files it needs. Should the
+ recovery be terminated because of an external error, the server can
+ simply be restarted and it will continue recovery. Upon completion
+ of the recovery process, the server will remove
+ <filename>recovery.signal</filename> (to prevent
+ accidentally re-entering recovery mode later) and then
+ commence normal database operations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Inspect the contents of the database to ensure you have recovered to
+ the desired state. If not, return to step 1. If all is well,
+ allow your users to connect by restoring <filename>pg_hba.conf</filename> to normal.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ The key part of all this is to set up a recovery configuration that
+ describes how you want to recover and how far the recovery should
+ run. The one thing that you absolutely must specify is the <varname>restore_command</varname>,
+ which tells <productname>PostgreSQL</productname> how to retrieve archived
+ WAL file segments. Like the <varname>archive_command</varname>, this is
+ a shell command string. It can contain <literal>%f</literal>, which is
+ replaced by the name of the desired log file, and <literal>%p</literal>,
+ which is replaced by the path name to copy the log file to.
+ (The path name is relative to the current working directory,
+ i.e., the cluster's data directory.)
+ Write <literal>%%</literal> if you need to embed an actual <literal>%</literal>
+ character in the command. The simplest useful command is
+ something like:
+<programlisting>
+restore_command = 'cp /mnt/server/archivedir/%f %p'
+</programlisting>
+ which will copy previously archived WAL segments from the directory
+ <filename>/mnt/server/archivedir</filename>. Of course, you can use something
+ much more complicated, perhaps even a shell script that requests the
+ operator to mount an appropriate tape.
+ </para>
+
+ <para>
+ It is important that the command return nonzero exit status on failure.
+ The command <emphasis>will</emphasis> be called requesting files that are not
+ present in the archive; it must return nonzero when so asked. This is not
+ an error condition. An exception is that if the command was terminated by
+ a signal (other than <systemitem>SIGTERM</systemitem>, which is used as
+ part of a database server shutdown) or an error by the shell (such as
+ command not found), then recovery will abort and the server will not start
+ up.
+ </para>
+
+ <para>
+ Not all of the requested files will be WAL segment
+ files; you should also expect requests for files with a suffix of
+ <literal>.history</literal>. Also be aware that
+ the base name of the <literal>%p</literal> path will be different from
+ <literal>%f</literal>; do not expect them to be interchangeable.
+ </para>
+
+ <para>
+ WAL segments that cannot be found in the archive will be sought in
+ <filename>pg_wal/</filename>; this allows use of recent un-archived segments.
+ However, segments that are available from the archive will be used in
+ preference to files in <filename>pg_wal/</filename>.
+ </para>
+
+ <para>
+ Normally, recovery will proceed through all available WAL segments,
+ thereby restoring the database to the current point in time (or as
+ close as possible given the available WAL segments). Therefore, a normal
+ recovery will end with a <quote>file not found</quote> message, the exact text
+ of the error message depending upon your choice of
+ <varname>restore_command</varname>. You may also see an error message
+ at the start of recovery for a file named something like
+ <filename>00000001.history</filename>. This is also normal and does not
+ indicate a problem in simple recovery situations; see
+ <xref linkend="backup-timelines"/> for discussion.
+ </para>
+
+ <para>
+ If you want to recover to some previous point in time (say, right before
+ the junior DBA dropped your main transaction table), just specify the
+ required <link linkend="runtime-config-wal-recovery-target">stopping point</link>. You can specify
+ the stop point, known as the <quote>recovery target</quote>, either by
+ date/time, named restore point or by completion of a specific transaction
+ ID. As of this writing only the date/time and named restore point options
+ are very usable, since there are no tools to help you identify with any
+ accuracy which transaction ID to use.
+ </para>
+
+ <note>
+ <para>
+ The stop point must be after the ending time of the base backup, i.e.,
+ the end time of <function>pg_backup_stop</function>. You cannot use a base backup
+ to recover to a time when that backup was in progress. (To
+ recover to such a time, you must go back to your previous base backup
+ and roll forward from there.)
+ </para>
+ </note>
+
+ <para>
+ If recovery finds corrupted WAL data, recovery will
+ halt at that point and the server will not start. In such a case the
+ recovery process could be re-run from the beginning, specifying a
+ <quote>recovery target</quote> before the point of corruption so that recovery
+ can complete normally.
+ If recovery fails for an external reason, such as a system crash or
+ if the WAL archive has become inaccessible, then the recovery can simply
+ be restarted and it will restart almost from where it failed.
+ Recovery restart works much like checkpointing in normal operation:
+ the server periodically forces all its state to disk, and then updates
+ the <filename>pg_control</filename> file to indicate that the already-processed
+ WAL data need not be scanned again.
+ </para>
+
+ </sect2>
+
+ <sect2 id="backup-timelines">
+ <title>Timelines</title>
+
+ <indexterm zone="backup">
+ <primary>timelines</primary>
+ </indexterm>
+
+ <para>
+ The ability to restore the database to a previous point in time creates
+ some complexities that are akin to science-fiction stories about time
+ travel and parallel universes. For example, in the original history of the database,
+ suppose you dropped a critical table at 5:15PM on Tuesday evening, but
+ didn't realize your mistake until Wednesday noon.
+ Unfazed, you get out your backup, restore to the point-in-time 5:14PM
+ Tuesday evening, and are up and running. In <emphasis>this</emphasis> history of
+ the database universe, you never dropped the table. But suppose
+ you later realize this wasn't such a great idea, and would like
+ to return to sometime Wednesday morning in the original history.
+ You won't be able
+ to if, while your database was up-and-running, it overwrote some of the
+ WAL segment files that led up to the time you now wish you
+ could get back to. Thus, to avoid this, you need to distinguish the series of
+ WAL records generated after you've done a point-in-time recovery from
+ those that were generated in the original database history.
+ </para>
+
+ <para>
+ To deal with this problem, <productname>PostgreSQL</productname> has a notion
+ of <firstterm>timelines</firstterm>. Whenever an archive recovery completes,
+ a new timeline is created to identify the series of WAL records
+ generated after that recovery. The timeline
+ ID number is part of WAL segment file names so a new timeline does
+ not overwrite the WAL data generated by previous timelines. It is
+ in fact possible to archive many different timelines. While that might
+ seem like a useless feature, it's often a lifesaver. Consider the
+ situation where you aren't quite sure what point-in-time to recover to,
+ and so have to do several point-in-time recoveries by trial and error
+ until you find the best place to branch off from the old history. Without
+ timelines this process would soon generate an unmanageable mess. With
+ timelines, you can recover to <emphasis>any</emphasis> prior state, including
+ states in timeline branches that you abandoned earlier.
+ </para>
+
+ <para>
+ Every time a new timeline is created, <productname>PostgreSQL</productname> creates
+ a <quote>timeline history</quote> file that shows which timeline it branched
+ off from and when. These history files are necessary to allow the system
+ to pick the right WAL segment files when recovering from an archive that
+ contains multiple timelines. Therefore, they are archived into the WAL
+ archive area just like WAL segment files. The history files are just
+ small text files, so it's cheap and appropriate to keep them around
+ indefinitely (unlike the segment files which are large). You can, if
+ you like, add comments to a history file to record your own notes about
+ how and why this particular timeline was created. Such comments will be
+ especially valuable when you have a thicket of different timelines as
+ a result of experimentation.
+ </para>
+
+ <para>
+ The default behavior of recovery is to recover to the latest timeline found
+ in the archive. If you wish to recover to the timeline that was current
+ when the base backup was taken or into a specific child timeline (that
+ is, you want to return to some state that was itself generated after a
+ recovery attempt), you need to specify <literal>current</literal> or the
+ target timeline ID in <xref linkend="guc-recovery-target-timeline"/>. You
+ cannot recover into timelines that branched off earlier than the base backup.
+ </para>
+ </sect2>
+
+ <sect2 id="backup-tips">
+ <title>Tips and Examples</title>
+
+ <para>
+ Some tips for configuring continuous archiving are given here.
+ </para>
+
+ <sect3 id="backup-standalone">
+ <title>Standalone Hot Backups</title>
+
+ <para>
+ It is possible to use <productname>PostgreSQL</productname>'s backup facilities to
+ produce standalone hot backups. These are backups that cannot be used
+ for point-in-time recovery, yet are typically much faster to backup and
+ restore than <application>pg_dump</application> dumps. (They are also much larger
+ than <application>pg_dump</application> dumps, so in some cases the speed advantage
+ might be negated.)
+ </para>
+
+ <para>
+ As with base backups, the easiest way to produce a standalone
+ hot backup is to use the <xref linkend="app-pgbasebackup"/>
+ tool. If you include the <literal>-X</literal> parameter when calling
+ it, all the write-ahead log required to use the backup will be
+ included in the backup automatically, and no special action is
+ required to restore the backup.
+ </para>
+ </sect3>
+
+ <sect3 id="compressed-archive-logs">
+ <title>Compressed Archive Logs</title>
+
+ <para>
+ If archive storage size is a concern, you can use
+ <application>gzip</application> to compress the archive files:
+<programlisting>
+archive_command = 'gzip &lt; %p &gt; /mnt/server/archivedir/%f.gz'
+</programlisting>
+ You will then need to use <application>gunzip</application> during recovery:
+<programlisting>
+restore_command = 'gunzip &lt; /mnt/server/archivedir/%f.gz &gt; %p'
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="backup-scripts">
+ <title><varname>archive_command</varname> Scripts</title>
+
+ <para>
+ Many people choose to use scripts to define their
+ <varname>archive_command</varname>, so that their
+ <filename>postgresql.conf</filename> entry looks very simple:
+<programlisting>
+archive_command = 'local_backup_script.sh "%p" "%f"'
+</programlisting>
+ Using a separate script file is advisable any time you want to use
+ more than a single command in the archiving process.
+ This allows all complexity to be managed within the script, which
+ can be written in a popular scripting language such as
+ <application>bash</application> or <application>perl</application>.
+ </para>
+
+ <para>
+ Examples of requirements that might be solved within a script include:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Copying data to secure off-site data storage
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Batching WAL files so that they are transferred every three hours,
+ rather than one at a time
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Interfacing with other backup and recovery software
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Interfacing with monitoring software to report errors
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <tip>
+ <para>
+ When using an <varname>archive_command</varname> script, it's desirable
+ to enable <xref linkend="guc-logging-collector"/>.
+ Any messages written to <systemitem>stderr</systemitem> from the script will then
+ appear in the database server log, allowing complex configurations to
+ be diagnosed easily if they fail.
+ </para>
+ </tip>
+ </sect3>
+ </sect2>
+
+ <sect2 id="continuous-archiving-caveats">
+ <title>Caveats</title>
+
+ <para>
+ At this writing, there are several limitations of the continuous archiving
+ technique. These will probably be fixed in future releases:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If a <link linkend="sql-createdatabase"><command>CREATE DATABASE</command></link>
+ command is executed while a base backup is being taken, and then
+ the template database that the <command>CREATE DATABASE</command> copied
+ is modified while the base backup is still in progress, it is
+ possible that recovery will cause those modifications to be
+ propagated into the created database as well. This is of course
+ undesirable. To avoid this risk, it is best not to modify any
+ template databases while taking a base backup.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <link linkend="sql-createtablespace"><command>CREATE TABLESPACE</command></link>
+ commands are WAL-logged with the literal absolute path, and will
+ therefore be replayed as tablespace creations with the same
+ absolute path. This might be undesirable if the log is being
+ replayed on a different machine. It can be dangerous even if the
+ log is being replayed on the same machine, but into a new data
+ directory: the replay will still overwrite the contents of the
+ original tablespace. To avoid potential gotchas of this sort,
+ the best practice is to take a new base backup after creating or
+ dropping tablespaces.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ It should also be noted that the default <acronym>WAL</acronym>
+ format is fairly bulky since it includes many disk page snapshots.
+ These page snapshots are designed to support crash recovery, since
+ we might need to fix partially-written disk pages. Depending on
+ your system hardware and software, the risk of partial writes might
+ be small enough to ignore, in which case you can significantly
+ reduce the total volume of archived logs by turning off page
+ snapshots using the <xref linkend="guc-full-page-writes"/>
+ parameter. (Read the notes and warnings in <xref linkend="wal"/>
+ before you do so.) Turning off page snapshots does not prevent
+ use of the logs for PITR operations. An area for future
+ development is to compress archived WAL data by removing
+ unnecessary page copies even when <varname>full_page_writes</varname> is
+ on. In the meantime, administrators might wish to reduce the number
+ of page snapshots included in WAL by increasing the checkpoint
+ interval parameters as much as feasible.
+ </para>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/basebackup-to-shell.sgml b/doc/src/sgml/basebackup-to-shell.sgml
new file mode 100644
index 0000000..b2ecc37
--- /dev/null
+++ b/doc/src/sgml/basebackup-to-shell.sgml
@@ -0,0 +1,85 @@
+<!-- doc/src/sgml/basebackup-to-shell.sgml -->
+
+<sect1 id="basebackup-to-shell" xreflabel="basebackup_to_shell">
+ <title>basebackup_to_shell</title>
+
+ <indexterm zone="basebackup-to-shell">
+ <primary>basebackup_to_shell</primary>
+ </indexterm>
+
+ <para>
+ <filename>basebackup_to_shell</filename> adds a custom basebackup target
+ called <literal>shell</literal>. This makes it possible to run
+ <command>pg_basebackup --target=shell</command> or, depending on how this
+ module is configured,
+ <command>pg_basebackup --target=shell:<replaceable>DETAIL_STRING</replaceable></command>,
+ and cause a server command chosen by the server administrator to be executed
+ for each tar archive generated by the backup process. The command will receive
+ the contents of the archive via standard input.
+ </para>
+
+ <para>
+ This module is primarily intended as an example of how to create a new
+ backup targets via an extension module, but in some scenarios it may be
+ useful for its own sake.
+ In order to function, this module must be loaded via
+ <xref linkend="guc-shared-preload-libraries"/> or
+ <xref linkend="guc-local-preload-libraries"/>.
+ </para>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>basebackup_to_shell.command</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>basebackup_to_shell.command</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The command which the server should execute for each archive generated
+ by the backup process. If <literal>%f</literal> occurs in the command
+ string, it will be replaced by the name of the archive (e.g.
+ <literal>base.tar</literal>). If <literal>%d</literal> occurs in the
+ command string, it will be replaced by the target detail provided by
+ the user. A target detail is required if <literal>%d</literal> is
+ used in the command string, and prohibited otherwise. For security
+ reasons, it may contain only alphanumeric characters. If
+ <literal>%%</literal> occurs in the command string, it will be replaced
+ by a single <literal>%</literal>. If <literal>%</literal> occurs in
+ the command string followed by any other character or at the end of the
+ string, an error occurs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>basebackup_to_shell.required_role</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>basebackup_to_shell.required_role</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The role required in order to make use of the <literal>shell</literal>
+ backup target. If this is not set, any replication user may make use of
+ the <literal>shell</literal> backup target.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Robert Haas <email>rhaas@postgresql.org</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/basic-archive.sgml b/doc/src/sgml/basic-archive.sgml
new file mode 100644
index 0000000..0b650f1
--- /dev/null
+++ b/doc/src/sgml/basic-archive.sgml
@@ -0,0 +1,81 @@
+<!-- doc/src/sgml/basic-archive.sgml -->
+
+<sect1 id="basic-archive" xreflabel="basic_archive">
+ <title>basic_archive</title>
+
+ <indexterm zone="basic-archive">
+ <primary>basic_archive</primary>
+ </indexterm>
+
+ <para>
+ <filename>basic_archive</filename> is an example of an archive module. This
+ module copies completed WAL segment files to the specified directory. This
+ may not be especially useful, but it can serve as a starting point for
+ developing your own archive module. For more information about archive
+ modules, see <xref linkend="archive-modules"/>.
+ </para>
+
+ <para>
+ In order to function, this module must be loaded via
+ <xref linkend="guc-archive-library"/>, and <xref linkend="guc-archive-mode"/>
+ must be enabled.
+ </para>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>basic_archive.archive_directory</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>basic_archive.archive_directory</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The directory where the server should copy WAL segment files. This
+ directory must already exist. The default is an empty string, which
+ effectively halts WAL archiving, but if <xref linkend="guc-archive-mode"/>
+ is enabled, the server will accumulate WAL segment files in the
+ expectation that a value will soon be provided.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ These parameters must be set in <filename>postgresql.conf</filename>.
+ Typical usage might be:
+ </para>
+
+<programlisting>
+# postgresql.conf
+archive_mode = 'on'
+archive_library = 'basic_archive'
+basic_archive.archive_directory = '/path/to/archive/directory'
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Notes</title>
+
+ <para>
+ Server crashes may leave temporary files with the prefix
+ <filename>archtemp</filename> in the archive directory. It is recommended to
+ delete such files before restarting the server after a crash. It is safe to
+ remove such files while the server is running as long as they are unrelated
+ to any archiving still in progress, but users should use extra caution when
+ doing so.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Nathan Bossart
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml
new file mode 100644
index 0000000..73207f7
--- /dev/null
+++ b/doc/src/sgml/bgworker.sgml
@@ -0,0 +1,302 @@
+<!-- doc/src/sgml/bgworker.sgml -->
+
+<chapter id="bgworker">
+ <title>Background Worker Processes</title>
+
+ <indexterm zone="bgworker">
+ <primary>Background workers</primary>
+ </indexterm>
+
+ <para>
+ PostgreSQL can be extended to run user-supplied code in separate processes.
+ Such processes are started, stopped and monitored by <command>postgres</command>,
+ which permits them to have a lifetime closely linked to the server's status.
+ These processes are attached to <productname>PostgreSQL</productname>'s
+ shared memory area and have the option to connect to databases internally; they can also run
+ multiple transactions serially, just like a regular client-connected server
+ process. Also, by linking to <application>libpq</application> they can connect to the
+ server and behave like a regular client application.
+ </para>
+
+ <warning>
+ <para>
+ There are considerable robustness and security risks in using background
+ worker processes because, being written in the <literal>C</literal> language,
+ they have unrestricted access to data. Administrators wishing to enable
+ modules that include background worker processes should exercise extreme
+ caution. Only carefully audited modules should be permitted to run
+ background worker processes.
+ </para>
+ </warning>
+
+ <para>
+ Background workers can be initialized at the time that
+ <productname>PostgreSQL</productname> is started by including the module name in
+ <varname>shared_preload_libraries</varname>. A module wishing to run a background
+ worker can register it by calling
+ <function>RegisterBackgroundWorker(<type>BackgroundWorker</type>
+ *<parameter>worker</parameter>)</function>
+ from its <function>_PG_init()</function> function.
+ Background workers can also be started
+ after the system is up and running by calling
+ <function>RegisterDynamicBackgroundWorker(<type>BackgroundWorker</type>
+ *<parameter>worker</parameter>, <type>BackgroundWorkerHandle</type>
+ **<parameter>handle</parameter>)</function>. Unlike
+ <function>RegisterBackgroundWorker</function>, which can only be called from
+ within the postmaster process,
+ <function>RegisterDynamicBackgroundWorker</function> must be called
+ from a regular backend or another background worker.
+ </para>
+
+ <para>
+ The structure <structname>BackgroundWorker</structname> is defined thus:
+<programlisting>
+typedef void (*bgworker_main_type)(Datum main_arg);
+typedef struct BackgroundWorker
+{
+ char bgw_name[BGW_MAXLEN];
+ char bgw_type[BGW_MAXLEN];
+ int bgw_flags;
+ BgWorkerStartTime bgw_start_time;
+ int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
+ char bgw_library_name[BGW_MAXLEN];
+ char bgw_function_name[BGW_MAXLEN];
+ Datum bgw_main_arg;
+ char bgw_extra[BGW_EXTRALEN];
+ int bgw_notify_pid;
+} BackgroundWorker;
+</programlisting>
+ </para>
+
+ <para>
+ <structfield>bgw_name</structfield> and <structfield>bgw_type</structfield> are
+ strings to be used in log messages, process listings and similar contexts.
+ <structfield>bgw_type</structfield> should be the same for all background
+ workers of the same type, so that it is possible to group such workers in a
+ process listing, for example. <structfield>bgw_name</structfield> on the
+ other hand can contain additional information about the specific process.
+ (Typically, the string for <structfield>bgw_name</structfield> will contain
+ the type somehow, but that is not strictly required.)
+ </para>
+
+ <para>
+ <structfield>bgw_flags</structfield> is a bitwise-or'd bit mask indicating the
+ capabilities that the module wants. Possible values are:
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>BGWORKER_SHMEM_ACCESS</literal></term>
+ <listitem>
+ <para>
+ <indexterm><primary>BGWORKER_SHMEM_ACCESS</primary></indexterm>
+ Requests shared memory access. This flag is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BGWORKER_BACKEND_DATABASE_CONNECTION</literal></term>
+ <listitem>
+ <para>
+ <indexterm><primary>BGWORKER_BACKEND_&zwsp;DATABASE_CONNECTION</primary></indexterm>
+ Requests the ability to establish a database connection through which it
+ can later run transactions and queries. A background worker using
+ <literal>BGWORKER_BACKEND_DATABASE_CONNECTION</literal> to connect to a
+ database must also attach shared memory using
+ <literal>BGWORKER_SHMEM_ACCESS</literal>, or worker start-up will fail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+
+ <para>
+ <structfield>bgw_start_time</structfield> is the server state during which
+ <command>postgres</command> should start the process; it can be one of
+ <literal>BgWorkerStart_PostmasterStart</literal> (start as soon as
+ <command>postgres</command> itself has finished its own initialization; processes
+ requesting this are not eligible for database connections),
+ <literal>BgWorkerStart_ConsistentState</literal> (start as soon as a consistent state
+ has been reached in a hot standby, allowing processes to connect to
+ databases and run read-only queries), and
+ <literal>BgWorkerStart_RecoveryFinished</literal> (start as soon as the system has
+ entered normal read-write state). Note the last two values are equivalent
+ in a server that's not a hot standby. Note that this setting only indicates
+ when the processes are to be started; they do not stop when a different state
+ is reached.
+ </para>
+
+ <para>
+ <structfield>bgw_restart_time</structfield> is the interval, in seconds, that
+ <command>postgres</command> should wait before restarting the process in
+ the event that it crashes. It can be any positive value,
+ or <literal>BGW_NEVER_RESTART</literal>, indicating not to restart the
+ process in case of a crash.
+ </para>
+
+ <para>
+ <structfield>bgw_library_name</structfield> is the name of a library in
+ which the initial entry point for the background worker should be sought.
+ The named library will be dynamically loaded by the worker process and
+ <structfield>bgw_function_name</structfield> will be used to identify the
+ function to be called. If loading a function from the core code, this must
+ be set to "postgres".
+ </para>
+
+ <para>
+ <structfield>bgw_function_name</structfield> is the name of a function in
+ a dynamically loaded library which should be used as the initial entry point
+ for a new background worker.
+ </para>
+
+ <para>
+ <structfield>bgw_main_arg</structfield> is the <type>Datum</type> argument
+ to the background worker main function. This main function should take a
+ single argument of type <type>Datum</type> and return <type>void</type>.
+ <structfield>bgw_main_arg</structfield> will be passed as the argument.
+ In addition, the global variable <literal>MyBgworkerEntry</literal>
+ points to a copy of the <structname>BackgroundWorker</structname> structure
+ passed at registration time; the worker may find it helpful to examine
+ this structure.
+ </para>
+
+ <para>
+ On Windows (and anywhere else where <literal>EXEC_BACKEND</literal> is
+ defined) or in dynamic background workers it is not safe to pass a
+ <type>Datum</type> by reference, only by value. If an argument is required, it
+ is safest to pass an int32 or other small value and use that as an index
+ into an array allocated in shared memory. If a value like a <type>cstring</type>
+ or <type>text</type> is passed then the pointer won't be valid from the
+ new background worker process.
+ </para>
+
+ <para>
+ <structfield>bgw_extra</structfield> can contain extra data to be passed
+ to the background worker. Unlike <structfield>bgw_main_arg</structfield>, this data
+ is not passed as an argument to the worker's main function, but it can be
+ accessed via <literal>MyBgworkerEntry</literal>, as discussed above.
+ </para>
+
+ <para>
+ <structfield>bgw_notify_pid</structfield> is the PID of a PostgreSQL
+ backend process to which the postmaster should send <literal>SIGUSR1</literal>
+ when the process is started or exits. It should be 0 for workers registered
+ at postmaster startup time, or when the backend registering the worker does
+ not wish to wait for the worker to start up. Otherwise, it should be
+ initialized to <literal>MyProcPid</literal>.
+ </para>
+
+ <para>Once running, the process can connect to a database by calling
+ <function>BackgroundWorkerInitializeConnection(<parameter>char *dbname</parameter>, <parameter>char *username</parameter>, <parameter>uint32 flags</parameter>)</function> or
+ <function>BackgroundWorkerInitializeConnectionByOid(<parameter>Oid dboid</parameter>, <parameter>Oid useroid</parameter>, <parameter>uint32 flags</parameter>)</function>.
+ This allows the process to run transactions and queries using the
+ <literal>SPI</literal> interface. If <varname>dbname</varname> is NULL or
+ <varname>dboid</varname> is <literal>InvalidOid</literal>, the session is not connected
+ to any particular database, but shared catalogs can be accessed.
+ If <varname>username</varname> is NULL or <varname>useroid</varname> is
+ <literal>InvalidOid</literal>, the process will run as the superuser created
+ during <command>initdb</command>. If <literal>BGWORKER_BYPASS_ALLOWCONN</literal>
+ is specified as <varname>flags</varname> it is possible to bypass the restriction
+ to connect to databases not allowing user connections.
+ A background worker can only call one of these two functions, and only
+ once. It is not possible to switch databases.
+ </para>
+
+ <para>
+ Signals are initially blocked when control reaches the
+ background worker's main function, and must be unblocked by it; this is to
+ allow the process to customize its signal handlers, if necessary.
+ Signals can be unblocked in the new process by calling
+ <function>BackgroundWorkerUnblockSignals</function> and blocked by calling
+ <function>BackgroundWorkerBlockSignals</function>.
+ </para>
+
+ <para>
+ If <structfield>bgw_restart_time</structfield> for a background worker is
+ configured as <literal>BGW_NEVER_RESTART</literal>, or if it exits with an exit
+ code of 0 or is terminated by <function>TerminateBackgroundWorker</function>,
+ it will be automatically unregistered by the postmaster on exit.
+ Otherwise, it will be restarted after the time period configured via
+ <structfield>bgw_restart_time</structfield>, or immediately if the postmaster
+ reinitializes the cluster due to a backend failure. Backends which need
+ to suspend execution only temporarily should use an interruptible sleep
+ rather than exiting; this can be achieved by calling
+ <function>WaitLatch()</function>. Make sure the
+ <literal>WL_POSTMASTER_DEATH</literal> flag is set when calling that function, and
+ verify the return code for a prompt exit in the emergency case that
+ <command>postgres</command> itself has terminated.
+ </para>
+
+ <para>
+ When a background worker is registered using the
+ <function>RegisterDynamicBackgroundWorker</function> function, it is
+ possible for the backend performing the registration to obtain information
+ regarding the status of the worker. Backends wishing to do this should
+ pass the address of a <type>BackgroundWorkerHandle *</type> as the second
+ argument to <function>RegisterDynamicBackgroundWorker</function>. If the
+ worker is successfully registered, this pointer will be initialized with an
+ opaque handle that can subsequently be passed to
+ <function>GetBackgroundWorkerPid(<parameter>BackgroundWorkerHandle *</parameter>, <parameter>pid_t *</parameter>)</function> or
+ <function>TerminateBackgroundWorker(<parameter>BackgroundWorkerHandle *</parameter>)</function>.
+ <function>GetBackgroundWorkerPid</function> can be used to poll the status of the
+ worker: a return value of <literal>BGWH_NOT_YET_STARTED</literal> indicates that
+ the worker has not yet been started by the postmaster;
+ <literal>BGWH_STOPPED</literal> indicates that it has been started but is
+ no longer running; and <literal>BGWH_STARTED</literal> indicates that it is
+ currently running. In this last case, the PID will also be returned via the
+ second argument.
+ <function>TerminateBackgroundWorker</function> causes the postmaster to send
+ <literal>SIGTERM</literal> to the worker if it is running, and to unregister it
+ as soon as it is not.
+ </para>
+
+ <para>
+ In some cases, a process which registers a background worker may wish to
+ wait for the worker to start up. This can be accomplished by initializing
+ <structfield>bgw_notify_pid</structfield> to <literal>MyProcPid</literal> and
+ then passing the <type>BackgroundWorkerHandle *</type> obtained at
+ registration time to
+ <function>WaitForBackgroundWorkerStartup(<parameter>BackgroundWorkerHandle
+ *handle</parameter>, <parameter>pid_t *</parameter>)</function> function.
+ This function will block until the postmaster has attempted to start the
+ background worker, or until the postmaster dies. If the background worker
+ is running, the return value will be <literal>BGWH_STARTED</literal>, and
+ the PID will be written to the provided address. Otherwise, the return
+ value will be <literal>BGWH_STOPPED</literal> or
+ <literal>BGWH_POSTMASTER_DIED</literal>.
+ </para>
+
+ <para>
+ A process can also wait for a background worker to shut down, by using the
+ <function>WaitForBackgroundWorkerShutdown(<parameter>BackgroundWorkerHandle
+ *handle</parameter>)</function> function and passing the
+ <type>BackgroundWorkerHandle *</type> obtained at registration. This
+ function will block until the background worker exits, or postmaster dies.
+ When the background worker exits, the return value is
+ <literal>BGWH_STOPPED</literal>, if postmaster dies it will return
+ <literal>BGWH_POSTMASTER_DIED</literal>.
+ </para>
+
+ <para>
+ Background workers can send asynchronous notification messages, either by
+ using the <command>NOTIFY</command> command via <acronym>SPI</acronym>,
+ or directly via <function>Async_Notify()</function>. Such notifications
+ will be sent at transaction commit.
+ Background workers should not register to receive asynchronous
+ notifications with the <command>LISTEN</command> command, as there is no
+ infrastructure for a worker to consume such notifications.
+ </para>
+
+ <para>
+ The <filename>src/test/modules/worker_spi</filename> module
+ contains a working example,
+ which demonstrates some useful techniques.
+ </para>
+
+ <para>
+ The maximum number of registered background workers is limited by
+ <xref linkend="guc-max-worker-processes"/>.
+ </para>
+</chapter>
diff --git a/doc/src/sgml/biblio.sgml b/doc/src/sgml/biblio.sgml
new file mode 100644
index 0000000..cd8aa3e
--- /dev/null
+++ b/doc/src/sgml/biblio.sgml
@@ -0,0 +1,550 @@
+<!-- doc/src/sgml/biblio.sgml -->
+
+ <bibliography id="biblio">
+ <title>Bibliography</title>
+
+ <para>
+ Selected references and readings for <acronym>SQL</acronym>
+ and <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ Some white papers and technical reports from the original
+ <productname>POSTGRES</productname> development team
+ are available at the University of California, Berkeley, Computer Science
+ Department <ulink url="https://dsf.berkeley.edu/papers/">web site</ulink>.
+ </para>
+
+ <bibliodiv>
+ <title><acronym>SQL</acronym> Reference Books</title>
+
+ <biblioentry id="bowman01">
+ <title>The Practical <acronym>SQL</acronym> Handbook</title>
+ <subtitle>Using SQL Variants</subtitle>
+ <edition>Fourth Edition</edition>
+ <authorgroup>
+ <author>
+ <firstname>Judith</firstname>
+ <surname>Bowman</surname>
+ </author>
+ <author>
+ <firstname>Sandra</firstname>
+ <surname>Emerson</surname>
+ </author>
+ <author>
+ <firstname>Marcy</firstname>
+ <surname>Darnovsky</surname>
+ </author>
+ </authorgroup>
+ <isbn>0-201-70309-2</isbn>
+ <publisher>
+ <publishername>Addison-Wesley Professional</publishername>
+ </publisher>
+ <pubdate>2001</pubdate>
+ </biblioentry>
+
+ <biblioentry id="date97">
+ <title>A Guide to the <acronym>SQL</acronym> Standard</title>
+ <subtitle>A user's guide to the standard database language <acronym>SQL</acronym></subtitle>
+ <edition>Fourth Edition</edition>
+ <authorgroup>
+ <author>
+ <firstname>C. J.</firstname>
+ <surname>Date</surname>
+ </author>
+ <author>
+ <firstname>Hugh</firstname>
+ <surname>Darwen</surname>
+ </author>
+ </authorgroup>
+ <isbn>0-201-96426-0</isbn>
+ <publisher>
+ <publishername>Addison-Wesley</publishername>
+ </publisher>
+ <pubdate>1997</pubdate>
+ </biblioentry>
+
+ <biblioentry id="date04">
+ <title>An Introduction to Database Systems</title>
+ <edition>Eighth Edition</edition>
+ <authorgroup>
+ <author>
+ <firstname>C. J.</firstname>
+ <surname>Date</surname>
+ </author>
+ </authorgroup>
+ <isbn>0-321-19784-4</isbn>
+ <publisher>
+ <publishername>Addison-Wesley</publishername>
+ </publisher>
+ <pubdate>2003</pubdate>
+ </biblioentry>
+
+ <biblioentry id="elma04">
+ <title>Fundamentals of Database Systems</title>
+ <edition>Fourth Edition</edition>
+ <authorgroup>
+ <author>
+ <firstname>Ramez</firstname>
+ <surname>Elmasri</surname>
+ </author>
+ <author>
+ <firstname>Shamkant</firstname>
+ <surname>Navathe</surname>
+ </author>
+ </authorgroup>
+ <isbn>0-321-12226-7</isbn>
+ <publisher>
+ <publishername>Addison-Wesley</publishername>
+ </publisher>
+ <pubdate>2003</pubdate>
+ </biblioentry>
+
+ <biblioentry id="melt93">
+ <title>Understanding the New <acronym>SQL</acronym></title>
+ <subtitle>A complete guide</subtitle>
+ <authorgroup>
+ <author>
+ <firstname>Jim</firstname>
+ <surname>Melton</surname>
+ </author>
+ <author>
+ <firstname>Alan R.</firstname>
+ <surname>Simon</surname>
+ </author>
+ </authorgroup>
+ <isbn>1-55860-245-3</isbn>
+ <publisher>
+ <publishername>Morgan Kaufmann</publishername>
+ </publisher>
+ <pubdate>1993</pubdate>
+ </biblioentry>
+
+ <biblioentry id="ull88">
+ <title>Principles of Database and Knowledge-Base Systems</title>
+ <subtitle>Classical Database Systems</subtitle>
+ <authorgroup>
+ <author>
+ <firstname>Jeffrey D.</firstname>
+ <surname>Ullman</surname>
+ </author>
+ </authorgroup>
+ <volumenum>Volume 1</volumenum>
+ <publisher>
+ <publishername>Computer Science Press</publishername>
+ </publisher>
+ <pubdate>1988</pubdate>
+ </biblioentry>
+
+ <biblioentry id="sqltr-19075-6">
+ <title>SQL Technical Report</title>
+ <subtitle>Part 6: SQL support for JavaScript Object
+ Notation (JSON)</subtitle>
+ <edition>First Edition</edition>
+ <pubdate>2017</pubdate>
+ </biblioentry>
+
+ </bibliodiv>
+
+ <bibliodiv>
+ <title>PostgreSQL-specific Documentation</title>
+
+ <biblioentry id="sim98">
+ <title>Enhancement of the ANSI SQL Implementation of PostgreSQL</title>
+ <authorgroup>
+ <author>
+ <firstname>Stefan</firstname>
+ <surname>Simkovics</surname>
+<!--
+Paul-Peters-Gasse 36
+2384 Breitenfurt
+AUSTRIA
+ssimkovi@ag.or.at
+-->
+ </author>
+ </authorgroup>
+<!--
+ <othercredit>
+ <contrib>
+ with support by
+ </contrib>
+ <honorific>O. Univ. Prof. Dr.</honorific>
+ <firstname>Georg</firstname>
+ <surname>Gottlob</surname>
+ <honorific>Univ. Ass. Mag.</honorific>
+ <firstname>Katrin</firstname>
+ <surname>Seyr</surname>
+ </othercredit>
+-->
+ <abstract>
+ <para>
+ Discusses SQL history and syntax, and describes the addition of
+ <literal>INTERSECT</literal> and <literal>EXCEPT</literal> constructs into
+ <productname>PostgreSQL</productname>. Prepared as a Master's
+ Thesis with the support of O. Univ. Prof. Dr. Georg Gottlob and
+ Univ. Ass. Mag. Katrin Seyr at Vienna University of Technology.
+ </para>
+ </abstract>
+
+ <publisher>
+ <publishername>Department of Information Systems, Vienna University of Technology</publishername>
+ <address>Vienna, Austria</address>
+ </publisher>
+ <pubdate>November 29, 1998</pubdate>
+ </biblioentry>
+
+ <biblioentry id="yu95">
+ <title>The <productname>Postgres95</productname> User Manual</title>
+ <authorgroup>
+ <author>
+ <firstname>A.</firstname>
+ <surname>Yu</surname>
+ </author>
+ <author>
+ <firstname>J.</firstname>
+ <surname>Chen</surname>
+ </author>
+ </authorgroup>
+ <publisher>
+ <publishername>University of California</publishername>
+ <address>Berkeley, California</address>
+ </publisher>
+ <pubdate>Sept. 5, 1995</pubdate>
+ </biblioentry>
+
+ <biblioentry id="fong">
+ <title><ulink url="https://dsf.berkeley.edu/papers/UCB-MS-zfong.pdf">The
+ design and implementation of the <productname>POSTGRES</productname> query
+ optimizer</ulink></title>
+ <author>
+ <firstname>Zelaine</firstname>
+ <surname>Fong</surname>
+ </author>
+ <publisher>
+ <publishername>University of California, Berkeley, Computer Science Department</publishername>
+ </publisher>
+ </biblioentry>
+
+ </bibliodiv>
+
+ <bibliodiv>
+ <title>Proceedings and Articles</title>
+
+ <biblioentry id="ports12">
+ <biblioset relation="article">
+ <title><ulink url="https://arxiv.org/pdf/1208.4179">Serializable Snapshot Isolation in PostgreSQL</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>D.</firstname>
+ <surname>Ports</surname>
+ </author>
+ <author>
+ <firstname>K.</firstname>
+ <surname>Grittner</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>VLDB Conference</conftitle>
+ <confdates>August 2012</confdates>
+ <address>Istanbul, Turkey</address>
+ </confgroup>
+ </biblioentry>
+
+ <biblioentry id="berenson95">
+ <biblioset relation="article">
+ <title><ulink url="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-95-51.pdf">A Critique of ANSI SQL Isolation Levels</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>H.</firstname>
+ <surname>Berenson</surname>
+ </author>
+ <author>
+ <firstname>P.</firstname>
+ <surname>Bernstein</surname>
+ </author>
+ <author>
+ <firstname>J.</firstname>
+ <surname>Gray</surname>
+ </author>
+ <author>
+ <firstname>J.</firstname>
+ <surname>Melton</surname>
+ </author>
+ <author>
+ <firstname>E.</firstname>
+ <surname>O'Neil</surname>
+ </author>
+ <author>
+ <firstname>P.</firstname>
+ <surname>O'Neil</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>ACM-SIGMOD Conference on Management of Data</conftitle>
+ <confdates>June 1995</confdates>
+ <address>San Jose, California</address>
+ </confgroup>
+ </biblioentry>
+
+ <biblioentry id="olson93">
+ <title>Partial indexing in POSTGRES: research project</title>
+ <authorgroup>
+ <author>
+ <firstname>Nels</firstname>
+ <surname>Olson</surname>
+ </author>
+ </authorgroup>
+ <pubsnumber>UCB Engin T7.49.1993 O676</pubsnumber>
+ <publisher>
+ <publishername>University of California</publishername>
+ <address>Berkeley, California</address>
+ </publisher>
+ <pubdate>1993</pubdate>
+ </biblioentry>
+
+ <biblioentry id="ong90">
+ <biblioset relation="article">
+ <title>A Unified Framework for Version Modeling Using Production Rules in a Database System</title>
+ <authorgroup>
+ <author>
+ <firstname>L.</firstname>
+ <surname>Ong</surname>
+ </author>
+ <author>
+ <firstname>J.</firstname>
+ <surname>Goh</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <biblioset relation="journal">
+ <title>ERL Technical Memorandum M90/33</title>
+ <publisher>
+ <publishername>University of California</publishername>
+ <address>Berkeley, California</address>
+ </publisher>
+ <pubdate>April, 1990</pubdate>
+ </biblioset>
+ </biblioentry>
+
+ <biblioentry id="rowe87">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M87-13.pdf">The <productname>POSTGRES</productname>
+ data model</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>L.</firstname>
+ <surname>Rowe</surname>
+ </author>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>VLDB Conference</conftitle>
+ <confdates>Sept. 1987</confdates>
+ <address>Brighton, England</address>
+ </confgroup>
+ </biblioentry>
+
+ <biblioentry id="seshadri95">
+ <biblioset relation="article">
+ <title><ulink url="https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.40.5740">Generalized
+ Partial Indexes</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>P.</firstname>
+ <surname>Seshadri</surname>
+ </author>
+ <author>
+ <firstname>A.</firstname>
+ <surname>Swami</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>Eleventh International Conference on Data Engineering</conftitle>
+ <confdates>6&ndash;10 March 1995</confdates>
+ <address>Taipeh, Taiwan</address>
+ </confgroup>
+ <pubsnumber>Cat. No.95CH35724</pubsnumber>
+ <publisher>
+ <publishername>IEEE Computer Society Press</publishername>
+ <address>Los Alamitos, California</address>
+ </publisher>
+ <pubdate>1995</pubdate>
+ <pagenums>420&ndash;7</pagenums>
+ </biblioentry>
+
+ <biblioentry id="ston86">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M85-95.pdf">The
+ design of <productname>POSTGRES</productname></ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ <author>
+ <firstname>L.</firstname>
+ <surname>Rowe</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>ACM-SIGMOD Conference on Management of Data</conftitle>
+ <confdates>May 1986</confdates>
+ <address>Washington, DC</address>
+ </confgroup>
+ </biblioentry>
+
+ <biblioentry id="ston87a">
+ <biblioset relation="article">
+ <title>The design of the <productname>POSTGRES</productname> rules system</title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ <author>
+ <firstname>E.</firstname>
+ <surname>Hanson</surname>
+ </author>
+ <author>
+ <firstname>C. H.</firstname>
+ <surname>Hong</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>IEEE Conference on Data Engineering</conftitle>
+ <confdates>Feb. 1987</confdates>
+ <address>Los Angeles, California</address>
+ </confgroup>
+ </biblioentry>
+
+ <biblioentry id="ston87b">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M87-06.pdf">The
+ design of the <productname>POSTGRES</productname> storage
+ system</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>VLDB Conference</conftitle>
+ <confdates>Sept. 1987</confdates>
+ <address>Brighton, England</address>
+ </confgroup>
+ </biblioentry>
+
+ <biblioentry id="ston89">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M89-82.pdf">A
+ commentary on the <productname>POSTGRES</productname> rules
+ system</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Hearst</surname>
+ </author>
+ <author>
+ <firstname>S.</firstname>
+ <surname>Potamianos</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <biblioset relation="journal">
+ <title>SIGMOD Record 18(3)</title>
+ <date>Sept. 1989</date>
+ </biblioset>
+ </biblioentry>
+
+ <biblioentry id="ston89b">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M89-17.pdf">The
+ case for partial indexes</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <biblioset relation="journal">
+ <title>SIGMOD Record 18(4)</title>
+ <date>Dec. 1989</date>
+ <pagenums>4&ndash;11</pagenums>
+ </biblioset>
+ </biblioentry>
+
+ <biblioentry id="ston90a">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M90-34.pdf">The
+ implementation of <productname>POSTGRES</productname></ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ <author>
+ <firstname>L. A.</firstname>
+ <surname>Rowe</surname>
+ </author>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Hirohama</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <biblioset relation="journal">
+ <title>Transactions on Knowledge and Data Engineering 2(1)</title>
+ <publisher>
+ <publishername>IEEE</publishername>
+ </publisher>
+ <date>March 1990</date>
+ </biblioset>
+ </biblioentry>
+
+ <biblioentry id="ston90b">
+ <biblioset relation="article">
+ <title><ulink url="https://dsf.berkeley.edu/papers/ERL-M90-36.pdf">On
+ Rules, Procedures, Caching and Views in Database Systems</ulink></title>
+ <authorgroup>
+ <author>
+ <firstname>M.</firstname>
+ <surname>Stonebraker</surname>
+ </author>
+ <author>
+ <firstname>A.</firstname>
+ <surname>Jhingran</surname>
+ </author>
+ <author>
+ <firstname>J.</firstname>
+ <surname>Goh</surname>
+ </author>
+ <author>
+ <firstname>S.</firstname>
+ <surname>Potamianos</surname>
+ </author>
+ </authorgroup>
+ </biblioset>
+ <confgroup>
+ <conftitle>ACM-SIGMOD Conference on Management of Data</conftitle>
+ <confdates>June 1990</confdates>
+ </confgroup>
+ </biblioentry>
+
+ </bibliodiv>
+ </bibliography>
diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
new file mode 100644
index 0000000..f71644e
--- /dev/null
+++ b/doc/src/sgml/bki.sgml
@@ -0,0 +1,1079 @@
+<!-- doc/src/sgml/bki.sgml -->
+
+<chapter id="bki">
+ <title>System Catalog Declarations and Initial Contents</title>
+
+ <para>
+ <productname>PostgreSQL</productname> uses many different system catalogs
+ to keep track of the existence and properties of database objects, such as
+ tables and functions. Physically there is no difference between a system
+ catalog and a plain user table, but the backend C code knows the structure
+ and properties of each catalog, and can manipulate it directly at a low
+ level. Thus, for example, it is inadvisable to attempt to alter the
+ structure of a catalog on-the-fly; that would break assumptions built into
+ the C code about how rows of the catalog are laid out. But the structure
+ of the catalogs can change between major versions.
+ </para>
+
+ <para>
+ The structures of the catalogs are declared in specially formatted C
+ header files in the <filename>src/include/catalog/</filename> directory of
+ the source tree. For each catalog there is a header file
+ named after the catalog (e.g., <filename>pg_class.h</filename>
+ for <structname>pg_class</structname>), which defines the set of columns
+ the catalog has, as well as some other basic properties such as its OID.
+ </para>
+
+ <para>
+ Many of the catalogs have initial data that must be loaded into them
+ during the <quote>bootstrap</quote> phase
+ of <application>initdb</application>, to bring the system up to a point
+ where it is capable of executing SQL commands. (For
+ example, <filename>pg_class.h</filename> must contain an entry for itself,
+ as well as one for each other system catalog and index.) This
+ initial data is kept in editable form in data files that are also stored
+ in the <filename>src/include/catalog/</filename> directory. For example,
+ <filename>pg_proc.dat</filename> describes all the initial rows that must
+ be inserted into the <structname>pg_proc</structname> catalog.
+ </para>
+
+ <para>
+ To create the catalog files and load this initial data into them, a
+ backend running in bootstrap mode reads a <acronym>BKI</acronym>
+ (Backend Interface) file containing commands and initial data.
+ The <filename>postgres.bki</filename> file used in this mode is prepared
+ from the aforementioned header and data files, while building
+ a <productname>PostgreSQL</productname> distribution, by a Perl script
+ named <filename>genbki.pl</filename>.
+ Although it's specific to a particular <productname>PostgreSQL</productname>
+ release, <filename>postgres.bki</filename> is platform-independent and is
+ installed in the <filename>share</filename> subdirectory of the
+ installation tree.
+ </para>
+
+ <para>
+ <filename>genbki.pl</filename> also produces a derived header file for
+ each catalog, for example <filename>pg_class_d.h</filename> for
+ the <structname>pg_class</structname> catalog. This file contains
+ automatically-generated macro definitions, and may contain other macros,
+ enum declarations, and so on that can be useful for client C code that
+ reads a particular catalog.
+ </para>
+
+ <para>
+ Most PostgreSQL developers don't need to be directly concerned with
+ the <acronym>BKI</acronym> file, but almost any nontrivial feature
+ addition in the backend will require modifying the catalog header files
+ and/or initial data files. The rest of this chapter gives some
+ information about that, and for completeness describes
+ the <acronym>BKI</acronym> file format.
+ </para>
+
+ <sect1 id="system-catalog-declarations">
+ <title>System Catalog Declaration Rules</title>
+
+ <para>
+ The key part of a catalog header file is a C structure definition
+ describing the layout of each row of the catalog. This begins with
+ a <literal>CATALOG</literal> macro, which so far as the C compiler is
+ concerned is just shorthand for <literal>typedef struct
+ FormData_<replaceable>catalogname</replaceable></literal>.
+ Each field in the struct gives rise to a catalog column.
+ Fields can be annotated using the BKI property macros described
+ in <filename>genbki.h</filename>, for example to define a default value
+ for a field or mark it as nullable or not nullable.
+ The <literal>CATALOG</literal> line can also be annotated, with some
+ other BKI property macros described in <filename>genbki.h</filename>, to
+ define other properties of the catalog as a whole, such as whether
+ it is a shared relation.
+ </para>
+
+ <para>
+ The system catalog cache code (and most catalog-munging code in general)
+ assumes that the fixed-length portions of all system catalog tuples are
+ in fact present, because it maps this C struct declaration onto them.
+ Thus, all variable-length fields and nullable fields must be placed at
+ the end, and they cannot be accessed as struct fields.
+ For example, if you tried to
+ set <structname>pg_type</structname>.<structfield>typrelid</structfield>
+ to be NULL, it would fail when some piece of code tried to reference
+ <literal>typetup-&gt;typrelid</literal> (or worse,
+ <literal>typetup-&gt;typelem</literal>, because that follows
+ <structfield>typrelid</structfield>). This would result in
+ random errors or even segmentation violations.
+ </para>
+
+ <para>
+ As a partial guard against this type of error, variable-length or
+ nullable fields should not be made directly visible to the C compiler.
+ This is accomplished by wrapping them in <literal>#ifdef
+ CATALOG_VARLEN</literal> ... <literal>#endif</literal> (where
+ <literal>CATALOG_VARLEN</literal> is a symbol that is never defined).
+ This prevents C code from carelessly trying to access fields that might
+ not be there or might be at some other offset.
+ As an independent guard against creating incorrect rows, we
+ require all columns that should be non-nullable to be marked so
+ in <structname>pg_attribute</structname>. The bootstrap code will
+ automatically mark catalog columns as <literal>NOT NULL</literal>
+ if they are fixed-width and are not preceded by any nullable or
+ variable-width column.
+ Where this rule is inadequate, you can force correct marking by using
+ <literal>BKI_FORCE_NOT_NULL</literal>
+ and <literal>BKI_FORCE_NULL</literal> annotations as needed.
+ </para>
+
+ <para>
+ Frontend code should not include any <filename>pg_xxx.h</filename>
+ catalog header file, as these files may contain C code that won't compile
+ outside the backend. (Typically, that happens because these files also
+ contain declarations for functions
+ in <filename>src/backend/catalog/</filename> files.)
+ Instead, frontend code may include the corresponding
+ generated <filename>pg_xxx_d.h</filename> header, which will contain
+ OID <literal>#define</literal>s and any other data that might be of use
+ on the client side. If you want macros or other code in a catalog header
+ to be visible to frontend code, write <literal>#ifdef
+ EXPOSE_TO_CLIENT_CODE</literal> ... <literal>#endif</literal> around that
+ section to instruct <filename>genbki.pl</filename> to copy that section
+ to the <filename>pg_xxx_d.h</filename> header.
+ </para>
+
+ <para>
+ A few of the catalogs are so fundamental that they can't even be created
+ by the <acronym>BKI</acronym> <literal>create</literal> command that's
+ used for most catalogs, because that command needs to write information
+ into these catalogs to describe the new catalog. These are
+ called <firstterm>bootstrap</firstterm> catalogs, and defining one takes
+ a lot of extra work: you have to manually prepare appropriate entries for
+ them in the pre-loaded contents of <structname>pg_class</structname>
+ and <structname>pg_type</structname>, and those entries will need to be
+ updated for subsequent changes to the catalog's structure.
+ (Bootstrap catalogs also need pre-loaded entries
+ in <structname>pg_attribute</structname>, but
+ fortunately <filename>genbki.pl</filename> handles that chore nowadays.)
+ Avoid making new catalogs be bootstrap catalogs if at all possible.
+ </para>
+ </sect1>
+
+ <sect1 id="system-catalog-initial-data">
+ <title>System Catalog Initial Data</title>
+
+ <para>
+ Each catalog that has any manually-created initial data (some do not)
+ has a corresponding <literal>.dat</literal> file that contains its
+ initial data in an editable format.
+ </para>
+
+ <sect2 id="system-catalog-initial-data-format">
+ <title>Data File Format</title>
+
+ <para>
+ Each <literal>.dat</literal> file contains Perl data structure literals
+ that are simply eval'd to produce an in-memory data structure consisting
+ of an array of hash references, one per catalog row.
+ A slightly modified excerpt from <filename>pg_database.dat</filename>
+ will demonstrate the key features:
+ </para>
+
+<!-- The "slight modification" is the apostrophe in the description. -->
+<programlisting><![CDATA[
+[
+
+# A comment could appear here.
+{ oid => '1', oid_symbol => 'Template1DbOid',
+ descr => 'database\'s default template',
+ datname => 'template1', encoding => 'ENCODING',
+ datlocprovider => 'LOCALE_PROVIDER', datistemplate => 't',
+ datallowconn => 't', datconnlimit => '-1', datfrozenxid => '0',
+ datminmxid => '1', dattablespace => 'pg_default', datcollate => 'LC_COLLATE',
+ datctype => 'LC_CTYPE', daticulocale => 'ICU_LOCALE', datacl => '_null_' },
+
+]
+]]></programlisting>
+
+ <para>
+ Points to note:
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ The overall file layout is: open square bracket, one or more sets of
+ curly braces each of which represents a catalog row, close square
+ bracket. Write a comma after each closing curly brace.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Within each catalog row, write comma-separated
+ <replaceable>key</replaceable> <literal>=&gt;</literal>
+ <replaceable>value</replaceable> pairs. The
+ allowed <replaceable>key</replaceable>s are the names of the catalog's
+ columns, plus the metadata keys <literal>oid</literal>,
+ <literal>oid_symbol</literal>,
+ <literal>array_type_oid</literal>, and <literal>descr</literal>.
+ (The use of <literal>oid</literal> and <literal>oid_symbol</literal>
+ is described in <xref linkend="system-catalog-oid-assignment"/> below,
+ while <literal>array_type_oid</literal> is described in
+ <xref linkend="system-catalog-auto-array-types"/>.
+ <literal>descr</literal> supplies a description string for the object,
+ which will be inserted into <structname>pg_description</structname>
+ or <structname>pg_shdescription</structname> as appropriate.)
+ While the metadata keys are optional, the catalog's defined columns
+ must all be provided, except when the catalog's <literal>.h</literal>
+ file specifies a default value for the column.
+ (In the example above, the <structfield>datdba</structfield> field has
+ been omitted because <filename>pg_database.h</filename> supplies a
+ suitable default value for it.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All values must be single-quoted. Escape single quotes used within a
+ value with a backslash. Backslashes meant as data can, but need not,
+ be doubled; this follows Perl's rules for simple quoted literals.
+ Note that backslashes appearing as data will be treated as escapes by
+ the bootstrap scanner, according to the same rules as for escape string
+ constants (see <xref linkend="sql-syntax-strings-escape"/>); for
+ example <literal>\t</literal> converts to a tab character. If you
+ actually want a backslash in the final value, you will need to write
+ four of them: Perl strips two, leaving <literal>\\</literal> for the
+ bootstrap scanner to see.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Null values are represented by <literal>_null_</literal>.
+ (Note that there is no way to create a value that is just that
+ string.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Comments are preceded by <literal>#</literal>, and must be on their
+ own lines.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Field values that are OIDs of other catalog entries should be
+ represented by symbolic names rather than actual numeric OIDs.
+ (In the example above, <structfield>dattablespace</structfield>
+ contains such a reference.)
+ This is described in <xref linkend="system-catalog-oid-references"/>
+ below.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Since hashes are unordered data structures, field order and line
+ layout aren't semantically significant. However, to maintain a
+ consistent appearance, we set a few rules that are applied by the
+ formatting script <filename>reformat_dat_file.pl</filename>:
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Within each pair of curly braces, the metadata
+ fields <literal>oid</literal>, <literal>oid_symbol</literal>,
+ <literal>array_type_oid</literal>, and <literal>descr</literal>
+ (if present) come first, in that order, then the catalog's own
+ fields appear in their defined order.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Newlines are inserted between fields as needed to limit line length
+ to 80 characters, if possible. A newline is also inserted between
+ the metadata fields and the regular fields.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the catalog's <literal>.h</literal> file specifies a default
+ value for a column, and a data entry has that same
+ value, <filename>reformat_dat_file.pl</filename> will omit it from
+ the data file. This keeps the data representation compact.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <filename>reformat_dat_file.pl</filename> preserves blank lines
+ and comment lines as-is.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ It's recommended to run <filename>reformat_dat_file.pl</filename>
+ before submitting catalog data patches. For convenience, you can
+ simply change to <filename>src/include/catalog/</filename> and
+ run <literal>make reformat-dat-files</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you want to add a new method of making the data representation
+ smaller, you must implement it
+ in <filename>reformat_dat_file.pl</filename> and also
+ teach <function>Catalog::ParseData()</function> how to expand the
+ data back into the full representation.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="system-catalog-oid-assignment">
+ <title>OID Assignment</title>
+
+ <para>
+ A catalog row appearing in the initial data can be given a
+ manually-assigned OID by writing an <literal>oid
+ =&gt; <replaceable>nnnn</replaceable></literal> metadata field.
+ Furthermore, if an OID is assigned, a C macro for that OID can be
+ created by writing an <literal>oid_symbol
+ =&gt; <replaceable>name</replaceable></literal> metadata field.
+ </para>
+
+ <para>
+ Pre-loaded catalog rows must have preassigned OIDs if there are OID
+ references to them in other pre-loaded rows. A preassigned OID is
+ also needed if the row's OID must be referenced from C code.
+ If neither case applies, the <literal>oid</literal> metadata field can
+ be omitted, in which case the bootstrap code assigns an OID
+ automatically.
+ In practice we usually preassign OIDs for all or none of the pre-loaded
+ rows in a given catalog, even if only some of them are actually
+ cross-referenced.
+ </para>
+
+ <para>
+ Writing the actual numeric value of any OID in C code is considered
+ very bad form; always use a macro, instead. Direct references
+ to <structname>pg_proc</structname> OIDs are common enough that there's
+ a special mechanism to create the necessary macros automatically;
+ see <filename>src/backend/utils/Gen_fmgrtab.pl</filename>. Similarly
+ &mdash; but, for historical reasons, not done the same way &mdash;
+ there's an automatic method for creating macros
+ for <structname>pg_type</structname>
+ OIDs. <literal>oid_symbol</literal> entries are therefore not
+ necessary in those two catalogs. Likewise, macros for
+ the <structname>pg_class</structname> OIDs of system catalogs and
+ indexes are set up automatically. For all other system catalogs, you
+ have to manually specify any macros you need
+ via <literal>oid_symbol</literal> entries.
+ </para>
+
+ <para>
+ To find an available OID for a new pre-loaded row, run the
+ script <filename>src/include/catalog/unused_oids</filename>.
+ It prints inclusive ranges of unused OIDs (e.g., the output
+ line <literal>45-900</literal> means OIDs 45 through 900 have not been
+ allocated yet). Currently, OIDs 1&ndash;9999 are reserved for manual
+ assignment; the <filename>unused_oids</filename> script simply looks
+ through the catalog headers and <filename>.dat</filename> files
+ to see which ones do not appear. You can also use
+ the <filename>duplicate_oids</filename> script to check for mistakes.
+ (<filename>genbki.pl</filename> will assign OIDs for any rows that
+ didn't get one hand-assigned to them, and it will also detect duplicate
+ OIDs at compile time.)
+ </para>
+
+ <para>
+ When choosing OIDs for a patch that is not expected to be committed
+ immediately, best practice is to use a group of more-or-less
+ consecutive OIDs starting with some random choice in the range
+ 8000&mdash;9999. This minimizes the risk of OID collisions with other
+ patches being developed concurrently. To keep the 8000&mdash;9999
+ range free for development purposes, after a patch has been committed
+ to the master git repository its OIDs should be renumbered into
+ available space below that range. Typically, this will be done
+ near the end of each development cycle, moving all OIDs consumed by
+ patches committed in that cycle at the same time. The script
+ <filename>renumber_oids.pl</filename> can be used for this purpose.
+ If an uncommitted patch is found to have OID conflicts with some
+ recently-committed patch, <filename>renumber_oids.pl</filename> may
+ also be useful for recovering from that situation.
+ </para>
+
+ <para>
+ Because of this convention of possibly renumbering OIDs assigned by
+ patches, the OIDs assigned by a patch should not be considered stable
+ until the patch has been included in an official release. We do not
+ change manually-assigned object OIDs once released, however, as that
+ would create assorted compatibility problems.
+ </para>
+
+ <para>
+ If <filename>genbki.pl</filename> needs to assign an OID to a catalog
+ entry that does not have a manually-assigned OID, it will use a value in
+ the range 10000&mdash;11999. The server's OID counter is set to 10000
+ at the start of a bootstrap run, so that any objects created on-the-fly
+ during bootstrap processing also receive OIDs in this range. (The
+ usual OID assignment mechanism takes care of preventing any conflicts.)
+ </para>
+
+ <para>
+ Objects with OIDs below <symbol>FirstUnpinnedObjectId</symbol> (12000)
+ are considered <quote>pinned</quote>, preventing them from being
+ deleted. (There are a small number of exceptions, which are
+ hard-wired into <function>IsPinnedObject()</function>.)
+ <application>initdb</application> forces the OID counter up
+ to <symbol>FirstUnpinnedObjectId</symbol> as soon as it's ready to
+ create unpinned objects. Thus objects created during the later phases
+ of <application>initdb</application>, such as objects created while
+ running the <filename>information_schema.sql</filename> script, will
+ not be pinned, while all objects known
+ to <filename>genbki.pl</filename> will be.
+ </para>
+
+ <para>
+ OIDs assigned during normal database operation are constrained to be
+ 16384 or higher. This ensures that the range 10000&mdash;16383 is free
+ for OIDs assigned automatically by <filename>genbki.pl</filename> or
+ during <application>initdb</application>. These
+ automatically-assigned OIDs are not considered stable, and may change
+ from one installation to another.
+ </para>
+ </sect2>
+
+ <sect2 id="system-catalog-oid-references">
+ <title>OID Reference Lookup</title>
+
+ <para>
+ In principle, cross-references from one initial catalog row to another
+ could be written just by writing the preassigned OID of the referenced
+ row in the referencing field. However, that is against project
+ policy, because it is error-prone, hard to read, and subject to
+ breakage if a newly-assigned OID is renumbered. Therefore
+ <filename>genbki.pl</filename> provides mechanisms to write
+ symbolic references instead.
+ The rules are as follows:
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Use of symbolic references is enabled in a particular catalog column
+ by attaching <literal>BKI_LOOKUP(<replaceable>lookuprule</replaceable>)</literal>
+ to the column's definition, where <replaceable>lookuprule</replaceable>
+ is the name of the referenced catalog, e.g., <literal>pg_proc</literal>.
+ <literal>BKI_LOOKUP</literal> can be attached to columns of
+ type <type>Oid</type>, <type>regproc</type>, <type>oidvector</type>,
+ or <type>Oid[]</type>; in the latter two cases it implies performing a
+ lookup on each element of the array.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ It's also permissible to attach <literal>BKI_LOOKUP(encoding)</literal>
+ to integer columns to reference character set encodings, which are
+ not currently represented as catalog OIDs, but have a set of values
+ known to <filename>genbki.pl</filename>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In some catalog columns, it's allowed for entries to be zero instead
+ of a valid reference. If this is allowed, write
+ <literal>BKI_LOOKUP_OPT</literal> instead
+ of <literal>BKI_LOOKUP</literal>. Then you can
+ write <literal>0</literal> for an entry. (If the column is
+ declared <type>regproc</type>, you can optionally
+ write <literal>-</literal> instead of <literal>0</literal>.)
+ Except for this special case, all entries in
+ a <literal>BKI_LOOKUP</literal> column must be symbolic references.
+ <filename>genbki.pl</filename> will warn about unrecognized names.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Most kinds of catalog objects are simply referenced by their names.
+ Note that type names must exactly match the
+ referenced <structname>pg_type</structname>
+ entry's <structfield>typname</structfield>; you do not get to use
+ any aliases such as <literal>integer</literal>
+ for <literal>int4</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A function can be represented by
+ its <structfield>proname</structfield>, if that is unique among
+ the <filename>pg_proc.dat</filename> entries (this works like regproc
+ input). Otherwise, write it
+ as <replaceable>proname(argtypename,argtypename,...)</replaceable>,
+ like regprocedure. The argument type names must be spelled exactly as
+ they are in the <filename>pg_proc.dat</filename> entry's
+ <structfield>proargtypes</structfield> field. Do not insert any
+ spaces.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Operators are represented
+ by <replaceable>oprname(lefttype,righttype)</replaceable>,
+ writing the type names exactly as they appear in
+ the <filename>pg_operator.dat</filename>
+ entry's <structfield>oprleft</structfield>
+ and <structfield>oprright</structfield> fields.
+ (Write <literal>0</literal> for the omitted operand of a unary
+ operator.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The names of opclasses and opfamilies are only unique within an
+ access method, so they are represented
+ by <replaceable>access_method_name</replaceable><literal>/</literal><replaceable>object_name</replaceable>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In none of these cases is there any provision for
+ schema-qualification; all objects created during bootstrap are
+ expected to be in the <literal>pg_catalog</literal> schema.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ <filename>genbki.pl</filename> resolves all symbolic references while it
+ runs, and puts simple numeric OIDs into the emitted BKI file. There is
+ therefore no need for the bootstrap backend to deal with symbolic
+ references.
+ </para>
+
+ <para>
+ It's desirable to mark OID reference columns
+ with <literal>BKI_LOOKUP</literal> or <literal>BKI_LOOKUP_OPT</literal>
+ even if the catalog has no initial data that requires lookup. This
+ allows <filename>genbki.pl</filename> to record the foreign key
+ relationships that exist in the system catalogs. That information is
+ used in the regression tests to check for incorrect entries. See also
+ the macros <literal>DECLARE_FOREIGN_KEY</literal>,
+ <literal>DECLARE_FOREIGN_KEY_OPT</literal>,
+ <literal>DECLARE_ARRAY_FOREIGN_KEY</literal>,
+ and <literal>DECLARE_ARRAY_FOREIGN_KEY_OPT</literal>, which are
+ used to declare foreign key relationships that are too complex
+ for <literal>BKI_LOOKUP</literal> (typically, multi-column foreign
+ keys).
+ </para>
+ </sect2>
+
+ <sect2 id="system-catalog-auto-array-types">
+ <title>Automatic Creation of Array Types</title>
+
+ <para>
+ Most scalar data types should have a corresponding array type (that is,
+ a standard varlena array type whose element type is the scalar type, and
+ which is referenced by the <structfield>typarray</structfield> field of
+ the scalar type's <structname>pg_type</structname>
+ entry). <filename>genbki.pl</filename> is able to generate
+ the <structname>pg_type</structname> entry for the array type
+ automatically in most cases.
+ </para>
+
+ <para>
+ To use this facility, just write an <literal>array_type_oid
+ =&gt; <replaceable>nnnn</replaceable></literal> metadata field in the
+ scalar type's <structname>pg_type</structname> entry, specifying the OID
+ to use for the array type. You may then omit
+ the <structfield>typarray</structfield> field, since it will be filled
+ automatically with that OID.
+ </para>
+
+ <para>
+ The generated array type's name is the scalar type's name with an
+ underscore prepended. The array entry's other fields are filled from
+ <literal>BKI_ARRAY_DEFAULT(<replaceable>value</replaceable>)</literal>
+ annotations in <filename>pg_type.h</filename>, or if there isn't one,
+ copied from the scalar type. (There's also a special case
+ for <structfield>typalign</structfield>.) Then
+ the <structfield>typelem</structfield>
+ and <structfield>typarray</structfield> fields of the two entries are
+ set to cross-reference each other.
+ </para>
+ </sect2>
+
+ <sect2 id="system-catalog-recipes">
+ <title>Recipes for Editing Data Files</title>
+
+ <para>
+ Here are some suggestions about the easiest ways to perform common tasks
+ when updating catalog data files.
+ </para>
+
+ <formalpara>
+ <title>Add a new column with a default to a catalog:</title>
+ <para>
+ Add the column to the header file with
+ a <literal>BKI_DEFAULT(<replaceable>value</replaceable>)</literal>
+ annotation. The data file need only be adjusted by adding the field
+ in existing rows where a non-default value is needed.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Add a default value to an existing column that doesn't have
+ one:</title>
+ <para>
+ Add a <literal>BKI_DEFAULT</literal> annotation to the header file,
+ then run <literal>make reformat-dat-files</literal> to remove
+ now-redundant field entries.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Remove a column, whether it has a default or not:</title>
+ <para>
+ Remove the column from the header, then run <literal>make
+ reformat-dat-files</literal> to remove now-useless field entries.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Change or remove an existing default value:</title>
+ <para>
+ You cannot simply change the header file, since that will cause the
+ current data to be interpreted incorrectly. First run <literal>make
+ expand-dat-files</literal> to rewrite the data files with all
+ default values inserted explicitly, then change or remove
+ the <literal>BKI_DEFAULT</literal> annotation, then run <literal>make
+ reformat-dat-files</literal> to remove superfluous fields again.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Ad-hoc bulk editing:</title>
+ <para>
+ <filename>reformat_dat_file.pl</filename> can be adapted to perform
+ many kinds of bulk changes. Look for its block comments showing where
+ one-off code can be inserted. In the following example, we are going
+ to consolidate two Boolean fields in <structname>pg_proc</structname>
+ into a char field:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ Add the new column, with a default,
+ to <filename>pg_proc.h</filename>:
+<programlisting>
++ /* see PROKIND_ categories below */
++ char prokind BKI_DEFAULT(f);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Create a new script based on <filename>reformat_dat_file.pl</filename>
+ to insert appropriate values on-the-fly:
+<programlisting>
+- # At this point we have the full row in memory as a hash
+- # and can do any operations we want. As written, it only
+- # removes default values, but this script can be adapted to
+- # do one-off bulk-editing.
++ # One-off change to migrate to prokind
++ # Default has already been filled in by now, so change to other
++ # values as appropriate
++ if ($values{proisagg} eq 't')
++ {
++ $values{prokind} = 'a';
++ }
++ elsif ($values{proiswindow} eq 't')
++ {
++ $values{prokind} = 'w';
++ }
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Run the new script:
+<programlisting>
+$ cd src/include/catalog
+$ perl rewrite_dat_with_prokind.pl pg_proc.dat
+</programlisting>
+ At this point <filename>pg_proc.dat</filename> has all three
+ columns, <structfield>prokind</structfield>,
+ <structfield>proisagg</structfield>,
+ and <structfield>proiswindow</structfield>, though they will appear
+ only in rows where they have non-default values.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Remove the old columns from <filename>pg_proc.h</filename>:
+<programlisting>
+- /* is it an aggregate? */
+- bool proisagg BKI_DEFAULT(f);
+-
+- /* is it a window function? */
+- bool proiswindow BKI_DEFAULT(f);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Finally, run <literal>make reformat-dat-files</literal> to remove
+ the useless old entries from <filename>pg_proc.dat</filename>.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ For further examples of scripts used for bulk editing, see
+ <filename>convert_oid2name.pl</filename>
+ and <filename>remove_pg_type_oid_symbols.pl</filename> attached to this
+ message:
+ <ulink url="https://www.postgresql.org/message-id/CAJVSVGVX8gXnPm+Xa=DxR7kFYprcQ1tNcCT5D0O3ShfnM6jehA@mail.gmail.com"></ulink>
+ </para>
+ </formalpara>
+ </sect2>
+ </sect1>
+
+ <sect1 id="bki-format">
+ <title><acronym>BKI</acronym> File Format</title>
+
+ <para>
+ This section describes how the <productname>PostgreSQL</productname>
+ backend interprets <acronym>BKI</acronym> files. This description
+ will be easier to understand if the <filename>postgres.bki</filename>
+ file is at hand as an example.
+ </para>
+
+ <para>
+ <acronym>BKI</acronym> input consists of a sequence of commands. Commands are made up
+ of a number of tokens, depending on the syntax of the command.
+ Tokens are usually separated by whitespace, but need not be if
+ there is no ambiguity. There is no special command separator; the
+ next token that syntactically cannot belong to the preceding
+ command starts a new one. (Usually you would put a new command on
+ a new line, for clarity.) Tokens can be certain key words, special
+ characters (parentheses, commas, etc.), identifiers, numbers, or
+ single-quoted strings. Everything is case sensitive.
+ </para>
+
+ <para>
+ Lines starting with <literal>#</literal> are ignored.
+ </para>
+
+ </sect1>
+
+ <sect1 id="bki-commands">
+ <title><acronym>BKI</acronym> Commands</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>create</literal>
+ <replaceable class="parameter">tablename</replaceable>
+ <replaceable class="parameter">tableoid</replaceable>
+ <optional><literal>bootstrap</literal></optional>
+ <optional><literal>shared_relation</literal></optional>
+ <optional><literal>rowtype_oid</literal> <replaceable>oid</replaceable></optional>
+ (<replaceable class="parameter">name1</replaceable> =
+ <replaceable class="parameter">type1</replaceable>
+ <optional><literal>FORCE NOT NULL</literal> | <literal>FORCE NULL</literal> </optional> <optional>,
+ <replaceable class="parameter">name2</replaceable> =
+ <replaceable class="parameter">type2</replaceable>
+ <optional><literal>FORCE NOT NULL</literal> | <literal>FORCE NULL</literal> </optional>,
+ ...</optional>)
+ </term>
+
+ <listitem>
+ <para>
+ Create a table named <replaceable
+ class="parameter">tablename</replaceable>, and having the OID
+ <replaceable class="parameter">tableoid</replaceable>,
+ with the columns given in parentheses.
+ </para>
+
+ <para>
+ The following column types are supported directly by
+ <filename>bootstrap.c</filename>: <type>bool</type>,
+ <type>bytea</type>, <type>char</type> (1 byte),
+ <type>name</type>, <type>int2</type>,
+ <type>int4</type>, <type>regproc</type>, <type>regclass</type>,
+ <type>regtype</type>, <type>text</type>,
+ <type>oid</type>, <type>tid</type>, <type>xid</type>,
+ <type>cid</type>, <type>int2vector</type>, <type>oidvector</type>,
+ <type>_int4</type> (array), <type>_text</type> (array),
+ <type>_oid</type> (array), <type>_char</type> (array),
+ <type>_aclitem</type> (array). Although it is possible to create
+ tables containing columns of other types, this cannot be done until
+ after <structname>pg_type</structname> has been created and filled with
+ appropriate entries. (That effectively means that only these
+ column types can be used in bootstrap catalogs, but non-bootstrap
+ catalogs can contain any built-in type.)
+ </para>
+
+ <para>
+ When <literal>bootstrap</literal> is specified,
+ the table will only be created on disk; nothing is entered into
+ <structname>pg_class</structname>,
+ <structname>pg_attribute</structname>, etc., for it. Thus the
+ table will not be accessible by ordinary SQL operations until
+ such entries are made the hard way (with <literal>insert</literal>
+ commands). This option is used for creating
+ <structname>pg_class</structname> etc. themselves.
+ </para>
+
+ <para>
+ The table is created as shared if <literal>shared_relation</literal> is
+ specified.
+ The table's row type OID (<structname>pg_type</structname> OID) can optionally
+ be specified via the <literal>rowtype_oid</literal> clause; if not specified,
+ an OID is automatically generated for it. (The <literal>rowtype_oid</literal>
+ clause is useless if <literal>bootstrap</literal> is specified, but it can be
+ provided anyway for documentation.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>open</literal> <replaceable class="parameter">tablename</replaceable>
+ </term>
+
+ <listitem>
+ <para>
+ Open the table named
+ <replaceable class="parameter">tablename</replaceable>
+ for insertion of data. Any currently open table is closed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>close</literal> <replaceable class="parameter">tablename</replaceable>
+ </term>
+
+ <listitem>
+ <para>
+ Close the open table. The name of the table must be given as a
+ cross-check.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>insert</literal> <literal>(</literal> <optional><replaceable class="parameter">oid_value</replaceable></optional> <replaceable class="parameter">value1</replaceable> <replaceable class="parameter">value2</replaceable> ... <literal>)</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Insert a new row into the open table using <replaceable
+ class="parameter">value1</replaceable>, <replaceable
+ class="parameter">value2</replaceable>, etc., for its column
+ values.
+ </para>
+
+ <para>
+ NULL values can be specified using the special key word
+ <literal>_null_</literal>. Values that do not look like
+ identifiers or digit strings must be single-quoted.
+ (To include a single quote in a value, write it twice.
+ Escape-string-style backslash escapes are allowed in the string, too.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>declare</literal> <optional><literal>unique</literal></optional>
+ <literal>index</literal> <replaceable class="parameter">indexname</replaceable>
+ <replaceable class="parameter">indexoid</replaceable>
+ <literal>on</literal> <replaceable class="parameter">tablename</replaceable>
+ <literal>using</literal> <replaceable class="parameter">amname</replaceable>
+ <literal>(</literal> <replaceable class="parameter">opclass1</replaceable>
+ <replaceable class="parameter">name1</replaceable>
+ <optional>, ...</optional> <literal>)</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Create an index named <replaceable
+ class="parameter">indexname</replaceable>, having OID
+ <replaceable class="parameter">indexoid</replaceable>,
+ on the table named
+ <replaceable class="parameter">tablename</replaceable>, using the
+ <replaceable class="parameter">amname</replaceable> access
+ method. The fields to index are called <replaceable
+ class="parameter">name1</replaceable>, <replaceable
+ class="parameter">name2</replaceable> etc., and the operator
+ classes to use are <replaceable
+ class="parameter">opclass1</replaceable>, <replaceable
+ class="parameter">opclass2</replaceable> etc., respectively.
+ The index file is created and appropriate catalog entries are
+ made for it, but the index contents are not initialized by this command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>declare toast</literal>
+ <replaceable class="parameter">toasttableoid</replaceable>
+ <replaceable class="parameter">toastindexoid</replaceable>
+ <literal>on</literal> <replaceable class="parameter">tablename</replaceable>
+ </term>
+
+ <listitem>
+ <para>
+ Create a TOAST table for the table named
+ <replaceable class="parameter">tablename</replaceable>.
+ The TOAST table is assigned OID
+ <replaceable class="parameter">toasttableoid</replaceable>
+ and its index is assigned OID
+ <replaceable class="parameter">toastindexoid</replaceable>.
+ As with <literal>declare index</literal>, filling of the index
+ is postponed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>build indices</literal></term>
+
+ <listitem>
+ <para>
+ Fill in the indices that have previously been declared.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="bki-structure">
+ <title>Structure of the Bootstrap <acronym>BKI</acronym> File</title>
+
+ <para>
+ The <literal>open</literal> command cannot be used until the tables it uses
+ exist and have entries for the table that is to be opened.
+ (These minimum tables are <structname>pg_class</structname>,
+ <structname>pg_attribute</structname>, <structname>pg_proc</structname>, and
+ <structname>pg_type</structname>.) To allow those tables themselves to be filled,
+ <literal>create</literal> with the <literal>bootstrap</literal> option implicitly opens
+ the created table for data insertion.
+ </para>
+
+ <para>
+ Also, the <literal>declare index</literal> and <literal>declare toast</literal>
+ commands cannot be used until the system catalogs they need have been
+ created and filled in.
+ </para>
+
+ <para>
+ Thus, the structure of the <filename>postgres.bki</filename> file has to
+ be:
+ <orderedlist>
+ <listitem>
+ <para>
+ <literal>create bootstrap</literal> one of the critical tables
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>insert</literal> data describing at least the critical tables
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>close</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Repeat for the other critical tables.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>create</literal> (without <literal>bootstrap</literal>) a noncritical table
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>open</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>insert</literal> desired data
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>close</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Repeat for the other noncritical tables.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Define indexes and toast tables.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>build indices</literal>
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ There are doubtless other, undocumented ordering dependencies.
+ </para>
+ </sect1>
+
+ <sect1 id="bki-example">
+ <title>BKI Example</title>
+
+ <para>
+ The following sequence of commands will create the table
+ <literal>test_table</literal> with OID 420, having three columns
+ <literal>oid</literal>, <literal>cola</literal> and <literal>colb</literal>
+ of type <type>oid</type>, <type>int4</type> and <type>text</type>,
+ respectively, and insert two rows into the table:
+<programlisting>
+create test_table 420 (oid = oid, cola = int4, colb = text)
+open test_table
+insert ( 421 1 'value 1' )
+insert ( 422 2 _null_ )
+close test_table
+</programlisting>
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml
new file mode 100644
index 0000000..a3f51cf
--- /dev/null
+++ b/doc/src/sgml/bloom.sgml
@@ -0,0 +1,290 @@
+<!-- doc/src/sgml/bloom.sgml -->
+
+<sect1 id="bloom" xreflabel="bloom">
+ <title>bloom</title>
+
+ <indexterm zone="bloom">
+ <primary>bloom</primary>
+ </indexterm>
+
+ <para>
+ <literal>bloom</literal> provides an index access method based on
+ <ulink url="https://en.wikipedia.org/wiki/Bloom_filter">Bloom filters</ulink>.
+ </para>
+
+ <para>
+ A Bloom filter is a space-efficient data structure that is used to test
+ whether an element is a member of a set. In the case of an index access
+ method, it allows fast exclusion of non-matching tuples via signatures
+ whose size is determined at index creation.
+ </para>
+
+ <para>
+ A signature is a lossy representation of the indexed attribute(s), and as
+ such is prone to reporting false positives; that is, it may be reported
+ that an element is in the set, when it is not. So index search results
+ must always be rechecked using the actual attribute values from the heap
+ entry. Larger signatures reduce the odds of a false positive and thus
+ reduce the number of useless heap visits, but of course also make the index
+ larger and hence slower to scan.
+ </para>
+
+ <para>
+ This type of index is most useful when a table has many attributes and
+ queries test arbitrary combinations of them. A traditional btree index is
+ faster than a bloom index, but it can require many btree indexes to support
+ all possible queries where one needs only a single bloom index. Note
+ however that bloom indexes only support equality queries, whereas btree
+ indexes can also perform inequality and range searches.
+ </para>
+
+ <sect2>
+ <title>Parameters</title>
+
+ <para>
+ A <literal>bloom</literal> index accepts the following parameters in its
+ <literal>WITH</literal> clause:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>length</literal></term>
+ <listitem>
+ <para>
+ Length of each signature (index entry) in bits. It is rounded up to the
+ nearest multiple of <literal>16</literal>. The default is
+ <literal>80</literal> bits and the maximum is <literal>4096</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <variablelist>
+ <varlistentry>
+ <term><literal>col1 &mdash; col32</literal></term>
+ <listitem>
+ <para>
+ Number of bits generated for each index column. Each parameter's name
+ refers to the number of the index column that it controls. The default
+ is <literal>2</literal> bits and the maximum is <literal>4095</literal>.
+ Parameters for index columns not actually used are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>
+ This is an example of creating a bloom index:
+ </para>
+
+<programlisting>
+CREATE INDEX bloomidx ON tbloom USING bloom (i1,i2,i3)
+ WITH (length=80, col1=2, col2=2, col3=4);
+</programlisting>
+
+ <para>
+ The index is created with a signature length of 80 bits, with attributes
+ i1 and i2 mapped to 2 bits, and attribute i3 mapped to 4 bits. We could
+ have omitted the <literal>length</literal>, <literal>col1</literal>,
+ and <literal>col2</literal> specifications since those have the default values.
+ </para>
+
+ <para>
+ Here is a more complete example of bloom index definition and usage, as
+ well as a comparison with equivalent btree indexes. The bloom index is
+ considerably smaller than the btree index, and can perform better.
+ </para>
+
+<programlisting>
+=# CREATE TABLE tbloom AS
+ SELECT
+ (random() * 1000000)::int as i1,
+ (random() * 1000000)::int as i2,
+ (random() * 1000000)::int as i3,
+ (random() * 1000000)::int as i4,
+ (random() * 1000000)::int as i5,
+ (random() * 1000000)::int as i6
+ FROM
+ generate_series(1,10000000);
+SELECT 10000000
+</programlisting>
+
+ <para>
+ A sequential scan over this large table takes a long time:
+<programlisting>
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------------------
+ Seq Scan on tbloom (cost=0.00..2137.14 rows=3 width=24) (actual time=16.971..16.971 rows=0 loops=1)
+ Filter: ((i2 = 898732) AND (i5 = 123451))
+ Rows Removed by Filter: 100000
+ Planning Time: 0.346 ms
+ Execution Time: 16.988 ms
+(5 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Even with the btree index defined the result will still be a
+ sequential scan:
+<programlisting>
+=# CREATE INDEX btreeidx ON tbloom (i1, i2, i3, i4, i5, i6);
+CREATE INDEX
+=# SELECT pg_size_pretty(pg_relation_size('btreeidx'));
+ pg_size_pretty
+----------------
+ 3976 kB
+(1 row)
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------------------
+ Seq Scan on tbloom (cost=0.00..2137.00 rows=2 width=24) (actual time=12.805..12.805 rows=0 loops=1)
+ Filter: ((i2 = 898732) AND (i5 = 123451))
+ Rows Removed by Filter: 100000
+ Planning Time: 0.138 ms
+ Execution Time: 12.817 ms
+(5 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Having the bloom index defined on the table is better than btree in
+ handling this type of search:
+<programlisting>
+=# CREATE INDEX bloomidx ON tbloom USING bloom (i1, i2, i3, i4, i5, i6);
+CREATE INDEX
+=# SELECT pg_size_pretty(pg_relation_size('bloomidx'));
+ pg_size_pretty
+----------------
+ 1584 kB
+(1 row)
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------------------------------------------------
+ Bitmap Heap Scan on tbloom (cost=1792.00..1799.69 rows=2 width=24) (actual time=0.388..0.388 rows=0 loops=1)
+ Recheck Cond: ((i2 = 898732) AND (i5 = 123451))
+ Rows Removed by Index Recheck: 29
+ Heap Blocks: exact=28
+ -&gt; Bitmap Index Scan on bloomidx (cost=0.00..1792.00 rows=2 width=0) (actual time=0.356..0.356 rows=29 loops=1)
+ Index Cond: ((i2 = 898732) AND (i5 = 123451))
+ Planning Time: 0.099 ms
+ Execution Time: 0.408 ms
+(8 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Now, the main problem with the btree search is that btree is inefficient
+ when the search conditions do not constrain the leading index column(s).
+ A better strategy for btree is to create a separate index on each column.
+ Then the planner will choose something like this:
+<programlisting>
+=# CREATE INDEX btreeidx1 ON tbloom (i1);
+CREATE INDEX
+=# CREATE INDEX btreeidx2 ON tbloom (i2);
+CREATE INDEX
+=# CREATE INDEX btreeidx3 ON tbloom (i3);
+CREATE INDEX
+=# CREATE INDEX btreeidx4 ON tbloom (i4);
+CREATE INDEX
+=# CREATE INDEX btreeidx5 ON tbloom (i5);
+CREATE INDEX
+=# CREATE INDEX btreeidx6 ON tbloom (i6);
+CREATE INDEX
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------------------------------------------------------
+ Bitmap Heap Scan on tbloom (cost=24.34..32.03 rows=2 width=24) (actual time=0.028..0.029 rows=0 loops=1)
+ Recheck Cond: ((i5 = 123451) AND (i2 = 898732))
+ -&gt; BitmapAnd (cost=24.34..24.34 rows=2 width=0) (actual time=0.027..0.027 rows=0 loops=1)
+ -&gt; Bitmap Index Scan on btreeidx5 (cost=0.00..12.04 rows=500 width=0) (actual time=0.026..0.026 rows=0 loops=1)
+ Index Cond: (i5 = 123451)
+ -&gt; Bitmap Index Scan on btreeidx2 (cost=0.00..12.04 rows=500 width=0) (never executed)
+ Index Cond: (i2 = 898732)
+ Planning Time: 0.491 ms
+ Execution Time: 0.055 ms
+(9 rows)
+</programlisting>
+ Although this query runs much faster than with either of the single
+ indexes, we pay a penalty in index size. Each of the single-column
+ btree indexes occupies 2 MB, so the total space needed is 12 MB,
+ eight times the space used by the bloom index.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Operator Class Interface</title>
+
+ <para>
+ An operator class for bloom indexes requires only a hash function for the
+ indexed data type and an equality operator for searching. This example
+ shows the operator class definition for the <type>text</type> data type:
+ </para>
+
+<programlisting>
+CREATE OPERATOR CLASS text_ops
+DEFAULT FOR TYPE text USING bloom AS
+ OPERATOR 1 =(text, text),
+ FUNCTION 1 hashtext(text);
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Limitations</title>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Only operator classes for <type>int4</type> and <type>text</type> are
+ included with the module.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Only the <literal>=</literal> operator is supported for search. But
+ it is possible to add support for arrays with union and intersection
+ operations in the future.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>bloom</literal> access method doesn't support
+ <literal>UNIQUE</literal> indexes.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>bloom</literal> access method doesn't support searching for
+ <literal>NULL</literal> values.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Teodor Sigaev <email>teodor@postgrespro.ru</email>,
+ Postgres Professional, Moscow, Russia
+ </para>
+
+ <para>
+ Alexander Korotkov <email>a.korotkov@postgrespro.ru</email>,
+ Postgres Professional, Moscow, Russia
+ </para>
+
+ <para>
+ Oleg Bartunov <email>obartunov@postgrespro.ru</email>,
+ Postgres Professional, Moscow, Russia
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml
new file mode 100644
index 0000000..9c5ffcd
--- /dev/null
+++ b/doc/src/sgml/brin.sgml
@@ -0,0 +1,1342 @@
+<!-- doc/src/sgml/brin.sgml -->
+
+<chapter id="brin">
+<title>BRIN Indexes</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>BRIN</secondary>
+ </indexterm>
+
+<sect1 id="brin-intro">
+ <title>Introduction</title>
+
+ <para>
+ <acronym>BRIN</acronym> stands for Block Range Index.
+ <acronym>BRIN</acronym> is designed for handling very large tables
+ in which certain columns have some natural correlation with their
+ physical location within the table.
+ </para>
+
+ <para>
+ <acronym>BRIN</acronym> works in terms of <firstterm>block ranges</firstterm>
+ (or <quote>page ranges</quote>).
+ A block range is a group of pages that are physically
+ adjacent in the table; for each block range, some summary info is stored
+ by the index.
+ For example, a table storing a store's sale orders might have
+ a date column on which each order was placed, and most of the time
+ the entries for earlier orders will appear earlier in the table as well;
+ a table storing a ZIP code column might have all codes for a city
+ grouped together naturally.
+ </para>
+
+ <para>
+ <acronym>BRIN</acronym> indexes can satisfy queries via regular bitmap
+ index scans, and will return all tuples in all pages within each range if
+ the summary info stored by the index is <firstterm>consistent</firstterm> with the
+ query conditions.
+ The query executor is in charge of rechecking these tuples and discarding
+ those that do not match the query conditions &mdash; in other words, these
+ indexes are lossy.
+ Because a <acronym>BRIN</acronym> index is very small, scanning the index
+ adds little overhead compared to a sequential scan, but may avoid scanning
+ large parts of the table that are known not to contain matching tuples.
+ </para>
+
+ <para>
+ The specific data that a <acronym>BRIN</acronym> index will store,
+ as well as the specific queries that the index will be able to satisfy,
+ depend on the operator class selected for each column of the index.
+ Data types having a linear sort order can have operator classes that
+ store the minimum and maximum value within each block range, for instance;
+ geometrical types might store the bounding box for all the objects
+ in the block range.
+ </para>
+
+ <para>
+ The size of the block range is determined at index creation time by
+ the <literal>pages_per_range</literal> storage parameter. The number of index
+ entries will be equal to the size of the relation in pages divided by
+ the selected value for <literal>pages_per_range</literal>. Therefore, the smaller
+ the number, the larger the index becomes (because of the need to
+ store more index entries), but at the same time the summary data stored can
+ be more precise and more data blocks can be skipped during an index scan.
+ </para>
+
+ <sect2 id="brin-operation">
+ <title>Index Maintenance</title>
+
+ <para>
+ At the time of creation, all existing heap pages are scanned and a
+ summary index tuple is created for each range, including the
+ possibly-incomplete range at the end.
+ As new pages are filled with data, page ranges that are already
+ summarized will cause the summary information to be updated with data
+ from the new tuples.
+ When a new page is created that does not fall within the last
+ summarized range, the range that the new page belongs to
+ does not automatically acquire a summary tuple;
+ those tuples remain unsummarized until a summarization run is
+ invoked later, creating the initial summary for that range.
+ </para>
+
+ <para>
+ There are several ways to trigger the initial summarization of a page range.
+ If the table is vacuumed, either manually or by
+ <link linkend="autovacuum">autovacuum</link>, all existing unsummarized
+ page ranges are summarized.
+ Also, if the index's
+ <xref linkend="index-reloption-autosummarize"/> parameter is enabled,
+ which it isn't by default,
+ whenever autovacuum runs in that database, summarization will occur for all
+ unsummarized page ranges that have been filled,
+ regardless of whether the table itself is processed by autovacuum; see below.
+ </para>
+
+ <para>
+ Lastly, the following functions can be used:
+ <simplelist>
+ <member>
+ <function>brin_summarize_new_values(regclass)</function>
+ which summarizes all unsummarized ranges;
+ </member>
+ <member>
+ <function>brin_summarize_range(regclass, bigint)</function>
+ which summarizes only the range containing the given page,
+ if it is unsummarized.
+ </member>
+ </simplelist>
+ </para>
+
+ <para>
+ When autosummarization is enabled, a request is sent to
+ <literal>autovacuum</literal> to execute a targeted summarization
+ for a block range when an insertion is detected for the first item
+ of the first page of the next block range,
+ to be fulfilled the next time an autovacuum
+ worker finishes running in the
+ same database. If the request queue is full, the request is not recorded
+ and a message is sent to the server log:
+<screen>
+LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded
+</screen>
+ When this happens, the range will remain unsummarized until the next
+ regular vacuum run on the table, or one of the functions mentioned above
+ are invoked.
+ </para>
+
+ <para>
+ Conversely, a range can be de-summarized using the
+ <function>brin_desummarize_range(regclass, bigint)</function> function,
+ which is useful when the index tuple is no longer a very good
+ representation because the existing values have changed.
+ See <xref linkend="functions-admin-index"/> for details.
+ </para>
+
+ </sect2>
+</sect1>
+
+<sect1 id="brin-builtin-opclasses">
+ <title>Built-in Operator Classes</title>
+
+ <para>
+ The core <productname>PostgreSQL</productname> distribution
+ includes the <acronym>BRIN</acronym> operator classes shown in
+ <xref linkend="brin-builtin-opclasses-table"/>.
+ </para>
+
+ <para>
+ The <firstterm>minmax</firstterm>
+ operator classes store the minimum and the maximum values appearing
+ in the indexed column within the range. The <firstterm>inclusion</firstterm>
+ operator classes store a value which includes the values in the indexed
+ column within the range. The <firstterm>bloom</firstterm> operator
+ classes build a Bloom filter for all values in the range. The
+ <firstterm>minmax-multi</firstterm> operator classes store multiple
+ minimum and maximum values, representing values appearing in the indexed
+ column within the range.
+ </para>
+
+ <table id="brin-builtin-opclasses-table">
+ <title>Built-in <acronym>BRIN</acronym> Operator Classes</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Indexable Operators</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="middle" morerows="4"><literal>bit_minmax_ops</literal></entry>
+ <entry><literal>= (bit,bit)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (bit,bit)</literal></entry></row>
+ <row><entry><literal>&gt; (bit,bit)</literal></entry></row>
+ <row><entry><literal>&lt;= (bit,bit)</literal></entry></row>
+ <row><entry><literal>&gt;= (bit,bit)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="12"><literal>box_inclusion_ops</literal></entry>
+ <entry><literal>@&gt; (box,point)</literal></entry>
+ </row>
+ <row><entry><literal>&lt;&lt; (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>&lt;@ (box,box)</literal></entry></row>
+ <row><entry><literal>@&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>~= (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (box,box)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&lt;| (box,box)</literal></entry></row>
+ <row><entry><literal>|&amp;&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>|&gt;&gt; (box,box)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>bpchar_bloom_ops</literal></entry>
+ <entry><literal>= (character,character)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>bpchar_minmax_ops</literal></entry>
+ <entry><literal>= (character,character)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (character,character)</literal></entry></row>
+ <row><entry><literal>&lt;= (character,character)</literal></entry></row>
+ <row><entry><literal>&gt; (character,character)</literal></entry></row>
+ <row><entry><literal>&gt;= (character,character)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>bytea_bloom_ops</literal></entry>
+ <entry><literal>= (bytea,bytea)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>bytea_minmax_ops</literal></entry>
+ <entry><literal>= (bytea,bytea)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (bytea,bytea)</literal></entry></row>
+ <row><entry><literal>&lt;= (bytea,bytea)</literal></entry></row>
+ <row><entry><literal>&gt; (bytea,bytea)</literal></entry></row>
+ <row><entry><literal>&gt;= (bytea,bytea)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>char_bloom_ops</literal></entry>
+ <entry><literal>= ("char","char")</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>char_minmax_ops</literal></entry>
+ <entry><literal>= ("char","char")</literal></entry>
+ </row>
+ <row><entry><literal>&lt; ("char","char")</literal></entry></row>
+ <row><entry><literal>&lt;= ("char","char")</literal></entry></row>
+ <row><entry><literal>&gt; ("char","char")</literal></entry></row>
+ <row><entry><literal>&gt;= ("char","char")</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>date_bloom_ops</literal></entry>
+ <entry><literal>= (date,date)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>date_minmax_ops</literal></entry>
+ <entry><literal>= (date,date)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (date,date)</literal></entry></row>
+ <row><entry><literal>&lt;= (date,date)</literal></entry></row>
+ <row><entry><literal>&gt; (date,date)</literal></entry></row>
+ <row><entry><literal>&gt;= (date,date)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>date_minmax_multi_ops</literal></entry>
+ <entry><literal>= (date,date)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (date,date)</literal></entry></row>
+ <row><entry><literal>&lt;= (date,date)</literal></entry></row>
+ <row><entry><literal>&gt; (date,date)</literal></entry></row>
+ <row><entry><literal>&gt;= (date,date)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>float4_bloom_ops</literal></entry>
+ <entry><literal>= (float4,float4)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>float4_minmax_ops</literal></entry>
+ <entry><literal>= (float4,float4)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (float4,float4)</literal></entry></row>
+ <row><entry><literal>&gt; (float4,float4)</literal></entry></row>
+ <row><entry><literal>&lt;= (float4,float4)</literal></entry></row>
+ <row><entry><literal>&gt;= (float4,float4)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>float4_minmax_multi_ops</literal></entry>
+ <entry><literal>= (float4,float4)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (float4,float4)</literal></entry></row>
+ <row><entry><literal>&gt; (float4,float4)</literal></entry></row>
+ <row><entry><literal>&lt;= (float4,float4)</literal></entry></row>
+ <row><entry><literal>&gt;= (float4,float4)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>float8_bloom_ops</literal></entry>
+ <entry><literal>= (float8,float8)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>float8_minmax_ops</literal></entry>
+ <entry><literal>= (float8,float8)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (float8,float8)</literal></entry></row>
+ <row><entry><literal>&lt;= (float8,float8)</literal></entry></row>
+ <row><entry><literal>&gt; (float8,float8)</literal></entry></row>
+ <row><entry><literal>&gt;= (float8,float8)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>float8_minmax_multi_ops</literal></entry>
+ <entry><literal>= (float8,float8)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (float8,float8)</literal></entry></row>
+ <row><entry><literal>&lt;= (float8,float8)</literal></entry></row>
+ <row><entry><literal>&gt; (float8,float8)</literal></entry></row>
+ <row><entry><literal>&gt;= (float8,float8)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="5"><literal>inet_inclusion_ops</literal></entry>
+ <entry><literal>&lt;&lt; (inet,inet)</literal></entry>
+ </row>
+ <row><entry><literal>&lt;&lt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;&gt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (inet,inet)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>inet_bloom_ops</literal></entry>
+ <entry><literal>= (inet,inet)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>inet_minmax_ops</literal></entry>
+ <entry><literal>= (inet,inet)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&lt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;= (inet,inet)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>inet_minmax_multi_ops</literal></entry>
+ <entry><literal>= (inet,inet)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&lt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;= (inet,inet)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>int2_bloom_ops</literal></entry>
+ <entry><literal>= (int2,int2)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>int2_minmax_ops</literal></entry>
+ <entry><literal>= (int2,int2)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (int2,int2)</literal></entry></row>
+ <row><entry><literal>&gt; (int2,int2)</literal></entry></row>
+ <row><entry><literal>&lt;= (int2,int2)</literal></entry></row>
+ <row><entry><literal>&gt;= (int2,int2)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>int2_minmax_multi_ops</literal></entry>
+ <entry><literal>= (int2,int2)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (int2,int2)</literal></entry></row>
+ <row><entry><literal>&gt; (int2,int2)</literal></entry></row>
+ <row><entry><literal>&lt;= (int2,int2)</literal></entry></row>
+ <row><entry><literal>&gt;= (int2,int2)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>int4_bloom_ops</literal></entry>
+ <entry><literal>= (int4,int4)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>int4_minmax_ops</literal></entry>
+ <entry><literal>= (int4,int4)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (int4,int4)</literal></entry></row>
+ <row><entry><literal>&gt; (int4,int4)</literal></entry></row>
+ <row><entry><literal>&lt;= (int4,int4)</literal></entry></row>
+ <row><entry><literal>&gt;= (int4,int4)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>int4_minmax_multi_ops</literal></entry>
+ <entry><literal>= (int4,int4)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (int4,int4)</literal></entry></row>
+ <row><entry><literal>&gt; (int4,int4)</literal></entry></row>
+ <row><entry><literal>&lt;= (int4,int4)</literal></entry></row>
+ <row><entry><literal>&gt;= (int4,int4)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>int8_bloom_ops</literal></entry>
+ <entry><literal>= (bigint,bigint)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>int8_minmax_ops</literal></entry>
+ <entry><literal>= (bigint,bigint)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (bigint,bigint)</literal></entry></row>
+ <row><entry><literal>&gt; (bigint,bigint)</literal></entry></row>
+ <row><entry><literal>&lt;= (bigint,bigint)</literal></entry></row>
+ <row><entry><literal>&gt;= (bigint,bigint)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>int8_minmax_multi_ops</literal></entry>
+ <entry><literal>= (bigint,bigint)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (bigint,bigint)</literal></entry></row>
+ <row><entry><literal>&gt; (bigint,bigint)</literal></entry></row>
+ <row><entry><literal>&lt;= (bigint,bigint)</literal></entry></row>
+ <row><entry><literal>&gt;= (bigint,bigint)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>interval_bloom_ops</literal></entry>
+ <entry><literal>= (interval,interval)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>interval_minmax_ops</literal></entry>
+ <entry><literal>= (interval,interval)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (interval,interval)</literal></entry></row>
+ <row><entry><literal>&lt;= (interval,interval)</literal></entry></row>
+ <row><entry><literal>&gt; (interval,interval)</literal></entry></row>
+ <row><entry><literal>&gt;= (interval,interval)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>interval_minmax_multi_ops</literal></entry>
+ <entry><literal>= (interval,interval)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (interval,interval)</literal></entry></row>
+ <row><entry><literal>&lt;= (interval,interval)</literal></entry></row>
+ <row><entry><literal>&gt; (interval,interval)</literal></entry></row>
+ <row><entry><literal>&gt;= (interval,interval)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>macaddr_bloom_ops</literal></entry>
+ <entry><literal>= (macaddr,macaddr)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>macaddr_minmax_ops</literal></entry>
+ <entry><literal>= (macaddr,macaddr)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (macaddr,macaddr)</literal></entry></row>
+ <row><entry><literal>&lt;= (macaddr,macaddr)</literal></entry></row>
+ <row><entry><literal>&gt; (macaddr,macaddr)</literal></entry></row>
+ <row><entry><literal>&gt;= (macaddr,macaddr)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>macaddr_minmax_multi_ops</literal></entry>
+ <entry><literal>= (macaddr,macaddr)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (macaddr,macaddr)</literal></entry></row>
+ <row><entry><literal>&lt;= (macaddr,macaddr)</literal></entry></row>
+ <row><entry><literal>&gt; (macaddr,macaddr)</literal></entry></row>
+ <row><entry><literal>&gt;= (macaddr,macaddr)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>macaddr8_bloom_ops</literal></entry>
+ <entry><literal>= (macaddr8,macaddr8)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>macaddr8_minmax_ops</literal></entry>
+ <entry><literal>= (macaddr8,macaddr8)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (macaddr8,macaddr8)</literal></entry></row>
+ <row><entry><literal>&lt;= (macaddr8,macaddr8)</literal></entry></row>
+ <row><entry><literal>&gt; (macaddr8,macaddr8)</literal></entry></row>
+ <row><entry><literal>&gt;= (macaddr8,macaddr8)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>macaddr8_minmax_multi_ops</literal></entry>
+ <entry><literal>= (macaddr8,macaddr8)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (macaddr8,macaddr8)</literal></entry></row>
+ <row><entry><literal>&lt;= (macaddr8,macaddr8)</literal></entry></row>
+ <row><entry><literal>&gt; (macaddr8,macaddr8)</literal></entry></row>
+ <row><entry><literal>&gt;= (macaddr8,macaddr8)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>name_bloom_ops</literal></entry>
+ <entry><literal>= (name,name)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>name_minmax_ops</literal></entry>
+ <entry><literal>= (name,name)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (name,name)</literal></entry></row>
+ <row><entry><literal>&lt;= (name,name)</literal></entry></row>
+ <row><entry><literal>&gt; (name,name)</literal></entry></row>
+ <row><entry><literal>&gt;= (name,name)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>numeric_bloom_ops</literal></entry>
+ <entry><literal>= (numeric,numeric)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>numeric_minmax_ops</literal></entry>
+ <entry><literal>= (numeric,numeric)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (numeric,numeric)</literal></entry></row>
+ <row><entry><literal>&lt;= (numeric,numeric)</literal></entry></row>
+ <row><entry><literal>&gt; (numeric,numeric)</literal></entry></row>
+ <row><entry><literal>&gt;= (numeric,numeric)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>numeric_minmax_multi_ops</literal></entry>
+ <entry><literal>= (numeric,numeric)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (numeric,numeric)</literal></entry></row>
+ <row><entry><literal>&lt;= (numeric,numeric)</literal></entry></row>
+ <row><entry><literal>&gt; (numeric,numeric)</literal></entry></row>
+ <row><entry><literal>&gt;= (numeric,numeric)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>oid_bloom_ops</literal></entry>
+ <entry><literal>= (oid,oid)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>oid_minmax_ops</literal></entry>
+ <entry><literal>= (oid,oid)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (oid,oid)</literal></entry></row>
+ <row><entry><literal>&gt; (oid,oid)</literal></entry></row>
+ <row><entry><literal>&lt;= (oid,oid)</literal></entry></row>
+ <row><entry><literal>&gt;= (oid,oid)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>oid_minmax_multi_ops</literal></entry>
+ <entry><literal>= (oid,oid)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (oid,oid)</literal></entry></row>
+ <row><entry><literal>&gt; (oid,oid)</literal></entry></row>
+ <row><entry><literal>&lt;= (oid,oid)</literal></entry></row>
+ <row><entry><literal>&gt;= (oid,oid)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>pg_lsn_bloom_ops</literal></entry>
+ <entry><literal>= (pg_lsn,pg_lsn)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>pg_lsn_minmax_ops</literal></entry>
+ <entry><literal>= (pg_lsn,pg_lsn)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (pg_lsn,pg_lsn)</literal></entry></row>
+ <row><entry><literal>&gt; (pg_lsn,pg_lsn)</literal></entry></row>
+ <row><entry><literal>&lt;= (pg_lsn,pg_lsn)</literal></entry></row>
+ <row><entry><literal>&gt;= (pg_lsn,pg_lsn)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>pg_lsn_minmax_multi_ops</literal></entry>
+ <entry><literal>= (pg_lsn,pg_lsn)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (pg_lsn,pg_lsn)</literal></entry></row>
+ <row><entry><literal>&gt; (pg_lsn,pg_lsn)</literal></entry></row>
+ <row><entry><literal>&lt;= (pg_lsn,pg_lsn)</literal></entry></row>
+ <row><entry><literal>&gt;= (pg_lsn,pg_lsn)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="13"><literal>range_inclusion_ops</literal></entry>
+ <entry><literal>= (anyrange,anyrange)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;= (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&gt;= (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange,anyelement)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;@ (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;&lt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>-|- (anyrange,anyrange)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>text_bloom_ops</literal></entry>
+ <entry><literal>= (text,text)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>text_minmax_ops</literal></entry>
+ <entry><literal>= (text,text)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (text,text)</literal></entry></row>
+ <row><entry><literal>&lt;= (text,text)</literal></entry></row>
+ <row><entry><literal>&gt; (text,text)</literal></entry></row>
+ <row><entry><literal>&gt;= (text,text)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>tid_bloom_ops</literal></entry>
+ <entry><literal>= (tid,tid)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>tid_minmax_ops</literal></entry>
+ <entry><literal>= (tid,tid)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (tid,tid)</literal></entry></row>
+ <row><entry><literal>&gt; (tid,tid)</literal></entry></row>
+ <row><entry><literal>&lt;= (tid,tid)</literal></entry></row>
+ <row><entry><literal>&gt;= (tid,tid)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>tid_minmax_multi_ops</literal></entry>
+ <entry><literal>= (tid,tid)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (tid,tid)</literal></entry></row>
+ <row><entry><literal>&gt; (tid,tid)</literal></entry></row>
+ <row><entry><literal>&lt;= (tid,tid)</literal></entry></row>
+ <row><entry><literal>&gt;= (tid,tid)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>timestamp_bloom_ops</literal></entry>
+ <entry><literal>= (timestamp,timestamp)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>timestamp_minmax_ops</literal></entry>
+ <entry><literal>= (timestamp,timestamp)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (timestamp,timestamp)</literal></entry></row>
+ <row><entry><literal>&lt;= (timestamp,timestamp)</literal></entry></row>
+ <row><entry><literal>&gt; (timestamp,timestamp)</literal></entry></row>
+ <row><entry><literal>&gt;= (timestamp,timestamp)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>timestamp_minmax_multi_ops</literal></entry>
+ <entry><literal>= (timestamp,timestamp)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (timestamp,timestamp)</literal></entry></row>
+ <row><entry><literal>&lt;= (timestamp,timestamp)</literal></entry></row>
+ <row><entry><literal>&gt; (timestamp,timestamp)</literal></entry></row>
+ <row><entry><literal>&gt;= (timestamp,timestamp)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>timestamptz_bloom_ops</literal></entry>
+ <entry><literal>= (timestamptz,timestamptz)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>timestamptz_minmax_ops</literal></entry>
+ <entry><literal>= (timestamptz,timestamptz)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (timestamptz,timestamptz)</literal></entry></row>
+ <row><entry><literal>&lt;= (timestamptz,timestamptz)</literal></entry></row>
+ <row><entry><literal>&gt; (timestamptz,timestamptz)</literal></entry></row>
+ <row><entry><literal>&gt;= (timestamptz,timestamptz)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>timestamptz_minmax_multi_ops</literal></entry>
+ <entry><literal>= (timestamptz,timestamptz)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (timestamptz,timestamptz)</literal></entry></row>
+ <row><entry><literal>&lt;= (timestamptz,timestamptz)</literal></entry></row>
+ <row><entry><literal>&gt; (timestamptz,timestamptz)</literal></entry></row>
+ <row><entry><literal>&gt;= (timestamptz,timestamptz)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>time_bloom_ops</literal></entry>
+ <entry><literal>= (time,time)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>time_minmax_ops</literal></entry>
+ <entry><literal>= (time,time)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (time,time)</literal></entry></row>
+ <row><entry><literal>&lt;= (time,time)</literal></entry></row>
+ <row><entry><literal>&gt; (time,time)</literal></entry></row>
+ <row><entry><literal>&gt;= (time,time)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>time_minmax_multi_ops</literal></entry>
+ <entry><literal>= (time,time)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (time,time)</literal></entry></row>
+ <row><entry><literal>&lt;= (time,time)</literal></entry></row>
+ <row><entry><literal>&gt; (time,time)</literal></entry></row>
+ <row><entry><literal>&gt;= (time,time)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>timetz_bloom_ops</literal></entry>
+ <entry><literal>= (timetz,timetz)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>timetz_minmax_ops</literal></entry>
+ <entry><literal>= (timetz,timetz)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (timetz,timetz)</literal></entry></row>
+ <row><entry><literal>&lt;= (timetz,timetz)</literal></entry></row>
+ <row><entry><literal>&gt; (timetz,timetz)</literal></entry></row>
+ <row><entry><literal>&gt;= (timetz,timetz)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>timetz_minmax_multi_ops</literal></entry>
+ <entry><literal>= (timetz,timetz)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (timetz,timetz)</literal></entry></row>
+ <row><entry><literal>&lt;= (timetz,timetz)</literal></entry></row>
+ <row><entry><literal>&gt; (timetz,timetz)</literal></entry></row>
+ <row><entry><literal>&gt;= (timetz,timetz)</literal></entry></row>
+
+ <row>
+ <entry valign="middle"><literal>uuid_bloom_ops</literal></entry>
+ <entry><literal>= (uuid,uuid)</literal></entry>
+ </row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>uuid_minmax_ops</literal></entry>
+ <entry><literal>= (uuid,uuid)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (uuid,uuid)</literal></entry></row>
+ <row><entry><literal>&gt; (uuid,uuid)</literal></entry></row>
+ <row><entry><literal>&lt;= (uuid,uuid)</literal></entry></row>
+ <row><entry><literal>&gt;= (uuid,uuid)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>uuid_minmax_multi_ops</literal></entry>
+ <entry><literal>= (uuid,uuid)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (uuid,uuid)</literal></entry></row>
+ <row><entry><literal>&gt; (uuid,uuid)</literal></entry></row>
+ <row><entry><literal>&lt;= (uuid,uuid)</literal></entry></row>
+ <row><entry><literal>&gt;= (uuid,uuid)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="4"><literal>varbit_minmax_ops</literal></entry>
+ <entry><literal>= (varbit,varbit)</literal></entry>
+ </row>
+ <row><entry><literal>&lt; (varbit,varbit)</literal></entry></row>
+ <row><entry><literal>&gt; (varbit,varbit)</literal></entry></row>
+ <row><entry><literal>&lt;= (varbit,varbit)</literal></entry></row>
+ <row><entry><literal>&gt;= (varbit,varbit)</literal></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="brin-builtin-opclasses--parameters">
+ <title>Operator Class Parameters</title>
+
+ <para>
+ Some of the built-in operator classes allow specifying parameters affecting
+ behavior of the operator class. Each operator class has its own set of
+ allowed parameters. Only the <literal>bloom</literal> and <literal>minmax-multi</literal>
+ operator classes allow specifying parameters:
+ </para>
+
+ <para>
+ bloom operator classes accept these parameters:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>n_distinct_per_range</literal></term>
+ <listitem>
+ <para>
+ Defines the estimated number of distinct non-null values in the block
+ range, used by <acronym>BRIN</acronym> bloom indexes for sizing of the
+ Bloom filter. It behaves similarly to <literal>n_distinct</literal> option
+ for <xref linkend="sql-altertable"/>. When set to a positive value,
+ each block range is assumed to contain this number of distinct non-null
+ values. When set to a negative value, which must be greater than or
+ equal to -1, the number of distinct non-null values is assumed to grow linearly with
+ the maximum possible number of tuples in the block range (about 290
+ rows per block). The default value is <literal>-0.1</literal>, and
+ the minimum number of distinct non-null values is <literal>16</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>false_positive_rate</literal></term>
+ <listitem>
+ <para>
+ Defines the desired false positive rate used by <acronym>BRIN</acronym>
+ bloom indexes for sizing of the Bloom filter. The values must be
+ between 0.0001 and 0.25. The default value is 0.01, which is 1% false
+ positive rate.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ minmax-multi operator classes accept these parameters:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>values_per_range</literal></term>
+ <listitem>
+ <para>
+ Defines the maximum number of values stored by <acronym>BRIN</acronym>
+ minmax indexes to summarize a block range. Each value may represent
+ either a point, or a boundary of an interval. Values must be between
+ 8 and 256, and the default value is 32.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+</sect1>
+
+<sect1 id="brin-extensibility">
+ <title>Extensibility</title>
+
+ <para>
+ The <acronym>BRIN</acronym> interface has a high level of abstraction,
+ requiring the access method implementer only to implement the semantics
+ of the data type being accessed. The <acronym>BRIN</acronym> layer
+ itself takes care of concurrency, logging and searching the index structure.
+ </para>
+
+ <para>
+ All it takes to get a <acronym>BRIN</acronym> access method working is to
+ implement a few user-defined methods, which define the behavior of
+ summary values stored in the index and the way they interact with
+ scan keys.
+ In short, <acronym>BRIN</acronym> combines
+ extensibility with generality, code reuse, and a clean interface.
+ </para>
+
+ <para>
+ There are four methods that an operator class for <acronym>BRIN</acronym>
+ must provide:
+
+ <variablelist>
+ <varlistentry>
+ <term><function>BrinOpcInfo *opcInfo(Oid type_oid)</function></term>
+ <listitem>
+ <para>
+ Returns internal information about the indexed columns' summary data.
+ The return value must point to a palloc'd <structname>BrinOpcInfo</structname>,
+ which has this definition:
+<programlisting>
+typedef struct BrinOpcInfo
+{
+ /* Number of columns stored in an index column of this opclass */
+ uint16 oi_nstored;
+
+ /* Opaque pointer for the opclass' private use */
+ void *oi_opaque;
+
+ /* Type cache entries of the stored columns */
+ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
+} BrinOpcInfo;
+</programlisting>
+ <structname>BrinOpcInfo</structname>.<structfield>oi_opaque</structfield> can be used by the
+ operator class routines to pass information between support functions
+ during an index scan.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>bool consistent(BrinDesc *bdesc, BrinValues *column,
+ ScanKey *keys, int nkeys)</function></term>
+ <listitem>
+ <para>
+ Returns whether all the ScanKey entries are consistent with the given
+ indexed values for a range.
+ The attribute number to use is passed as part of the scan key.
+ Multiple scan keys for the same attribute may be passed at once; the
+ number of entries is determined by the <literal>nkeys</literal> parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>bool consistent(BrinDesc *bdesc, BrinValues *column,
+ ScanKey key)</function></term>
+ <listitem>
+ <para>
+ Returns whether the ScanKey is consistent with the given indexed
+ values for a range.
+ The attribute number to use is passed as part of the scan key.
+ This is an older backward-compatible variant of the consistent function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>bool addValue(BrinDesc *bdesc, BrinValues *column,
+ Datum newval, bool isnull)</function></term>
+ <listitem>
+ <para>
+ Given an index tuple and an indexed value, modifies the indicated
+ attribute of the tuple so that it additionally represents the new value.
+ If any modification was done to the tuple, <literal>true</literal> is
+ returned.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>bool unionTuples(BrinDesc *bdesc, BrinValues *a,
+ BrinValues *b)</function></term>
+ <listitem>
+ <para>
+ Consolidates two index tuples. Given two index tuples, modifies the
+ indicated attribute of the first of them so that it represents both tuples.
+ The second tuple is not modified.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ An operator class for <acronym>BRIN</acronym> can optionally specify the
+ following method:
+
+ <variablelist>
+ <varlistentry>
+ <term><function>void options(local_relopts *relopts)</function></term>
+ <listitem>
+ <para>
+ Defines a set of user-visible parameters that control operator class
+ behavior.
+ </para>
+
+ <para>
+ The <function>options</function> function is passed a pointer to a
+ <structname>local_relopts</structname> struct, which needs to be
+ filled with a set of operator class specific options. The options
+ can be accessed from other support functions using the
+ <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+
+ <para>
+ Since both key extraction of indexed values and representation of the
+ key in <acronym>BRIN</acronym> are flexible, they may depend on
+ user-specified parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The core distribution includes support for four types of operator classes:
+ minmax, minmax-multi, inclusion and bloom. Operator class definitions
+ using them are shipped for in-core data types as appropriate. Additional
+ operator classes can be defined by the user for other data types using
+ equivalent definitions, without having to write any source code;
+ appropriate catalog entries being declared is enough. Note that
+ assumptions about the semantics of operator strategies are embedded in the
+ support functions' source code.
+ </para>
+
+ <para>
+ Operator classes that implement completely different semantics are also
+ possible, provided implementations of the four main support functions
+ described above are written. Note that backwards compatibility across major
+ releases is not guaranteed: for example, additional support functions might
+ be required in later releases.
+ </para>
+
+ <para>
+ To write an operator class for a data type that implements a totally
+ ordered set, it is possible to use the minmax support functions
+ alongside the corresponding operators, as shown in
+ <xref linkend="brin-extensibility-minmax-table"/>.
+ All operator class members (functions and operators) are mandatory.
+ </para>
+
+ <table id="brin-extensibility-minmax-table">
+ <title>Function and Support Numbers for Minmax Operator Classes</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Operator class member</entry>
+ <entry>Object</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Support Function 1</entry>
+ <entry>internal function <function>brin_minmax_opcinfo()</function></entry>
+ </row>
+ <row>
+ <entry>Support Function 2</entry>
+ <entry>internal function <function>brin_minmax_add_value()</function></entry>
+ </row>
+ <row>
+ <entry>Support Function 3</entry>
+ <entry>internal function <function>brin_minmax_consistent()</function></entry>
+ </row>
+ <row>
+ <entry>Support Function 4</entry>
+ <entry>internal function <function>brin_minmax_union()</function></entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 1</entry>
+ <entry>operator less-than</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 2</entry>
+ <entry>operator less-than-or-equal-to</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 3</entry>
+ <entry>operator equal-to</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 4</entry>
+ <entry>operator greater-than-or-equal-to</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 5</entry>
+ <entry>operator greater-than</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ To write an operator class for a complex data type which has values
+ included within another type, it's possible to use the inclusion support
+ functions alongside the corresponding operators, as shown
+ in <xref linkend="brin-extensibility-inclusion-table"/>. It requires
+ only a single additional function, which can be written in any language.
+ More functions can be defined for additional functionality. All operators
+ are optional. Some operators require other operators, as shown as
+ dependencies on the table.
+ </para>
+
+ <table id="brin-extensibility-inclusion-table">
+ <title>Function and Support Numbers for Inclusion Operator Classes</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Operator class member</entry>
+ <entry>Object</entry>
+ <entry>Dependency</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Support Function 1</entry>
+ <entry>internal function <function>brin_inclusion_opcinfo()</function></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 2</entry>
+ <entry>internal function <function>brin_inclusion_add_value()</function></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 3</entry>
+ <entry>internal function <function>brin_inclusion_consistent()</function></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 4</entry>
+ <entry>internal function <function>brin_inclusion_union()</function></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 11</entry>
+ <entry>function to merge two elements</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 12</entry>
+ <entry>optional function to check whether two elements are mergeable</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 13</entry>
+ <entry>optional function to check if an element is contained within another</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Support Function 14</entry>
+ <entry>optional function to check whether an element is empty</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 1</entry>
+ <entry>operator left-of</entry>
+ <entry>Operator Strategy 4</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 2</entry>
+ <entry>operator does-not-extend-to-the-right-of</entry>
+ <entry>Operator Strategy 5</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 3</entry>
+ <entry>operator overlaps</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 4</entry>
+ <entry>operator does-not-extend-to-the-left-of</entry>
+ <entry>Operator Strategy 1</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 5</entry>
+ <entry>operator right-of</entry>
+ <entry>Operator Strategy 2</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 6, 18</entry>
+ <entry>operator same-as-or-equal-to</entry>
+ <entry>Operator Strategy 7</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 7, 16, 24, 25</entry>
+ <entry>operator contains-or-equal-to</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 8, 26, 27</entry>
+ <entry>operator is-contained-by-or-equal-to</entry>
+ <entry>Operator Strategy 3</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 9</entry>
+ <entry>operator does-not-extend-above</entry>
+ <entry>Operator Strategy 11</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 10</entry>
+ <entry>operator is-below</entry>
+ <entry>Operator Strategy 12</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 11</entry>
+ <entry>operator is-above</entry>
+ <entry>Operator Strategy 9</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 12</entry>
+ <entry>operator does-not-extend-below</entry>
+ <entry>Operator Strategy 10</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 20</entry>
+ <entry>operator less-than</entry>
+ <entry>Operator Strategy 5</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 21</entry>
+ <entry>operator less-than-or-equal-to</entry>
+ <entry>Operator Strategy 5</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 22</entry>
+ <entry>operator greater-than</entry>
+ <entry>Operator Strategy 1</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 23</entry>
+ <entry>operator greater-than-or-equal-to</entry>
+ <entry>Operator Strategy 1</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Support function numbers 1 through 10 are reserved for the BRIN internal
+ functions, so the SQL level functions start with number 11. Support
+ function number 11 is the main function required to build the index.
+ It should accept two arguments with the same data type as the operator class,
+ and return the union of them. The inclusion operator class can store union
+ values with different data types if it is defined with the
+ <literal>STORAGE</literal> parameter. The return value of the union
+ function should match the <literal>STORAGE</literal> data type.
+ </para>
+
+ <para>
+ Support function numbers 12 and 14 are provided to support
+ irregularities of built-in data types. Function number 12
+ is used to support network addresses from different families which
+ are not mergeable. Function number 14 is used to support
+ empty ranges. Function number 13 is an optional but
+ recommended one, which allows the new value to be checked before
+ it is passed to the union function. As the BRIN framework can shortcut
+ some operations when the union is not changed, using this
+ function can improve index performance.
+ </para>
+
+ <para>
+ To write an operator class for a data type that implements only an equality
+ operator and supports hashing, it is possible to use the bloom support procedures
+ alongside the corresponding operators, as shown in
+ <xref linkend="brin-extensibility-bloom-table"/>.
+ All operator class members (procedures and operators) are mandatory.
+ </para>
+
+ <table id="brin-extensibility-bloom-table">
+ <title>Procedure and Support Numbers for Bloom Operator Classes</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operator class member</entry>
+ <entry>Object</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Support Procedure 1</entry>
+ <entry>internal function <function>brin_bloom_opcinfo()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 2</entry>
+ <entry>internal function <function>brin_bloom_add_value()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 3</entry>
+ <entry>internal function <function>brin_bloom_consistent()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 4</entry>
+ <entry>internal function <function>brin_bloom_union()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 5</entry>
+ <entry>internal function <function>brin_bloom_options()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 11</entry>
+ <entry>function to compute hash of an element</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 1</entry>
+ <entry>operator equal-to</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Support procedure numbers 1-10 are reserved for the BRIN internal
+ functions, so the SQL level functions start with number 11. Support
+ function number 11 is the main function required to build the index.
+ It should accept one argument with the same data type as the operator class,
+ and return a hash of the value.
+ </para>
+
+ <para>
+ The minmax-multi operator class is also intended for data types implementing
+ a totally ordered set, and may be seen as a simple extension of the minmax
+ operator class. While minmax operator class summarizes values from each block
+ range into a single contiguous interval, minmax-multi allows summarization
+ into multiple smaller intervals to improve handling of outlier values.
+ It is possible to use the minmax-multi support procedures alongside the
+ corresponding operators, as shown in
+ <xref linkend="brin-extensibility-minmax-multi-table"/>.
+ All operator class members (procedures and operators) are mandatory.
+ </para>
+
+ <table id="brin-extensibility-minmax-multi-table">
+ <title>Procedure and Support Numbers for minmax-multi Operator Classes</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operator class member</entry>
+ <entry>Object</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Support Procedure 1</entry>
+ <entry>internal function <function>brin_minmax_multi_opcinfo()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 2</entry>
+ <entry>internal function <function>brin_minmax_multi_add_value()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 3</entry>
+ <entry>internal function <function>brin_minmax_multi_consistent()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 4</entry>
+ <entry>internal function <function>brin_minmax_multi_union()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 5</entry>
+ <entry>internal function <function>brin_minmax_multi_options()</function></entry>
+ </row>
+ <row>
+ <entry>Support Procedure 11</entry>
+ <entry>function to compute distance between two values (length of a range)</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 1</entry>
+ <entry>operator less-than</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 2</entry>
+ <entry>operator less-than-or-equal-to</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 3</entry>
+ <entry>operator equal-to</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 4</entry>
+ <entry>operator greater-than-or-equal-to</entry>
+ </row>
+ <row>
+ <entry>Operator Strategy 5</entry>
+ <entry>operator greater-than</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Both minmax and inclusion operator classes support cross-data-type
+ operators, though with these the dependencies become more complicated.
+ The minmax operator class requires a full set of operators to be
+ defined with both arguments having the same data type. It allows
+ additional data types to be supported by defining extra sets
+ of operators. Inclusion operator class operator strategies are dependent
+ on another operator strategy as shown in
+ <xref linkend="brin-extensibility-inclusion-table"/>, or the same
+ operator strategy as themselves. They require the dependency
+ operator to be defined with the <literal>STORAGE</literal> data type as the
+ left-hand-side argument and the other supported data type to be the
+ right-hand-side argument of the supported operator. See
+ <literal>float4_minmax_ops</literal> as an example of minmax, and
+ <literal>box_inclusion_ops</literal> as an example of inclusion.
+ </para>
+</sect1>
+</chapter>
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
new file mode 100644
index 0000000..5bc5a05
--- /dev/null
+++ b/doc/src/sgml/btree-gin.sgml
@@ -0,0 +1,66 @@
+<!-- doc/src/sgml/btree-gin.sgml -->
+
+<sect1 id="btree-gin" xreflabel="btree_gin">
+ <title>btree_gin</title>
+
+ <indexterm zone="btree-gin">
+ <primary>btree_gin</primary>
+ </indexterm>
+
+ <para>
+ <filename>btree_gin</filename> provides sample GIN operator classes that
+ implement B-tree equivalent behavior for the data types
+ <type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
+ <type>float8</type>, <type>timestamp with time zone</type>,
+ <type>timestamp without time zone</type>, <type>time with time zone</type>,
+ <type>time without time zone</type>, <type>date</type>, <type>interval</type>,
+ <type>oid</type>, <type>money</type>, <type>"char"</type>,
+ <type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
+ <type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
+ <type>cidr</type>, <type>uuid</type>, <type>name</type>, <type>bool</type>,
+ <type>bpchar</type>, and all <type>enum</type> types.
+ </para>
+
+ <para>
+ In general, these operator classes will not outperform the equivalent
+ standard B-tree index methods, and they lack one major feature of the
+ standard B-tree code: the ability to enforce uniqueness. However,
+ they are useful for GIN testing and as a base for developing other
+ GIN operator classes. Also, for queries that test both a GIN-indexable
+ column and a B-tree-indexable column, it might be more efficient to create
+ a multicolumn GIN index that uses one of these operator classes than to create
+ two separate indexes that would have to be combined via bitmap ANDing.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Example Usage</title>
+
+<programlisting>
+CREATE TABLE test (a int4);
+-- create index
+CREATE INDEX testidx ON test USING GIN (a);
+-- query
+SELECT * FROM test WHERE a &lt; 10;
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Teodor Sigaev (<email>teodor@stack.net</email>) and
+ Oleg Bartunov (<email>oleg@sai.msu.su</email>). See
+ <ulink url="http://www.sai.msu.su/~megera/oddmuse/index.cgi/Gin"></ulink>
+ for additional information.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
new file mode 100644
index 0000000..b67f20a
--- /dev/null
+++ b/doc/src/sgml/btree-gist.sgml
@@ -0,0 +1,118 @@
+<!-- doc/src/sgml/btree-gist.sgml -->
+
+<sect1 id="btree-gist" xreflabel="btree_gist">
+ <title>btree_gist</title>
+
+ <indexterm zone="btree-gist">
+ <primary>btree_gist</primary>
+ </indexterm>
+
+ <para>
+ <filename>btree_gist</filename> provides GiST index operator classes that
+ implement B-tree equivalent behavior for the data types
+ <type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
+ <type>float8</type>, <type>numeric</type>, <type>timestamp with time zone</type>,
+ <type>timestamp without time zone</type>, <type>time with time zone</type>,
+ <type>time without time zone</type>, <type>date</type>, <type>interval</type>,
+ <type>oid</type>, <type>money</type>, <type>char</type>,
+ <type>varchar</type>, <type>text</type>, <type>bytea</type>, <type>bit</type>,
+ <type>varbit</type>, <type>macaddr</type>, <type>macaddr8</type>, <type>inet</type>,
+ <type>cidr</type>, <type>uuid</type>, <type>bool</type> and all <type>enum</type> types.
+ </para>
+
+ <para>
+ In general, these operator classes will not outperform the equivalent
+ standard B-tree index methods, and they lack one major feature of the
+ standard B-tree code: the ability to enforce uniqueness. However,
+ they provide some other features that are not available with a B-tree
+ index, as described below. Also, these operator classes are useful
+ when a multicolumn GiST index is needed, wherein some of the columns
+ are of data types that are only indexable with GiST but other columns
+ are just simple data types. Lastly, these operator classes are useful for
+ GiST testing and as a base for developing other GiST operator classes.
+ </para>
+
+ <para>
+ In addition to the typical B-tree search operators, <filename>btree_gist</filename>
+ also provides index support for <literal>&lt;&gt;</literal> (<quote>not
+ equals</quote>). This may be useful in combination with an
+ <link linkend="sql-createtable-exclude">exclusion constraint</link>,
+ as described below.
+ </para>
+
+ <para>
+ Also, for data types for which there is a natural distance metric,
+ <filename>btree_gist</filename> defines a distance operator <literal>&lt;-&gt;</literal>,
+ and provides GiST index support for nearest-neighbor searches using
+ this operator. Distance operators are provided for
+ <type>int2</type>, <type>int4</type>, <type>int8</type>, <type>float4</type>,
+ <type>float8</type>, <type>timestamp with time zone</type>,
+ <type>timestamp without time zone</type>,
+ <type>time without time zone</type>, <type>date</type>, <type>interval</type>,
+ <type>oid</type>, and <type>money</type>.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Example Usage</title>
+
+ <para>
+ Simple example using <literal>btree_gist</literal> instead of <literal>btree</literal>:
+ </para>
+
+<programlisting>
+CREATE TABLE test (a int4);
+-- create index
+CREATE INDEX testidx ON test USING GIST (a);
+-- query
+SELECT * FROM test WHERE a &lt; 10;
+-- nearest-neighbor search: find the ten entries closest to "42"
+SELECT *, a &lt;-&gt; 42 AS dist FROM test ORDER BY a &lt;-&gt; 42 LIMIT 10;
+</programlisting>
+
+ <para>
+ Use an <link linkend="sql-createtable-exclude">exclusion
+ constraint</link> to enforce the rule that a cage at a zoo
+ can contain only one kind of animal:
+ </para>
+
+<programlisting>
+=&gt; CREATE TABLE zoo (
+ cage INTEGER,
+ animal TEXT,
+ EXCLUDE USING GIST (cage WITH =, animal WITH &lt;&gt;)
+);
+
+=&gt; INSERT INTO zoo VALUES(123, 'zebra');
+INSERT 0 1
+=&gt; INSERT INTO zoo VALUES(123, 'zebra');
+INSERT 0 1
+=&gt; INSERT INTO zoo VALUES(123, 'lion');
+ERROR: conflicting key value violates exclusion constraint "zoo_cage_animal_excl"
+DETAIL: Key (cage, animal)=(123, lion) conflicts with existing key (cage, animal)=(123, zebra).
+=&gt; INSERT INTO zoo VALUES(124, 'lion');
+INSERT 0 1
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Teodor Sigaev (<email>teodor@stack.net</email>),
+ Oleg Bartunov (<email>oleg@sai.msu.su</email>),
+ Janko Richter (<email>jankorichter@yahoo.de</email>), and
+ Paul Jungwirth (<email>pj@illuminatedcomputing.com</email>). See
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/"></ulink>
+ for additional information.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/btree.sgml b/doc/src/sgml/btree.sgml
new file mode 100644
index 0000000..6f608a1
--- /dev/null
+++ b/doc/src/sgml/btree.sgml
@@ -0,0 +1,914 @@
+<!-- doc/src/sgml/btree.sgml -->
+
+<chapter id="btree">
+<title>B-Tree Indexes</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>B-Tree</secondary>
+ </indexterm>
+
+<sect1 id="btree-intro">
+ <title>Introduction</title>
+
+ <para>
+ <productname>PostgreSQL</productname> includes an implementation of the
+ standard <acronym>btree</acronym> (multi-way balanced tree) index data
+ structure. Any data type that can be sorted into a well-defined linear
+ order can be indexed by a btree index. The only limitation is that an
+ index entry cannot exceed approximately one-third of a page (after TOAST
+ compression, if applicable).
+ </para>
+
+ <para>
+ Because each btree operator class imposes a sort order on its data type,
+ btree operator classes (or, really, operator families) have come to be
+ used as <productname>PostgreSQL</productname>'s general representation
+ and understanding of sorting semantics. Therefore, they've acquired
+ some features that go beyond what would be needed just to support btree
+ indexes, and parts of the system that are quite distant from the
+ btree AM make use of them.
+ </para>
+
+</sect1>
+
+<sect1 id="btree-behavior">
+ <title>Behavior of B-Tree Operator Classes</title>
+
+ <para>
+ As shown in <xref linkend="xindex-btree-strat-table"/>, a btree operator
+ class must provide five comparison operators,
+ <literal>&lt;</literal>,
+ <literal>&lt;=</literal>,
+ <literal>=</literal>,
+ <literal>&gt;=</literal> and
+ <literal>&gt;</literal>.
+ One might expect that <literal>&lt;&gt;</literal> should also be part of
+ the operator class, but it is not, because it would almost never be
+ useful to use a <literal>&lt;&gt;</literal> WHERE clause in an index
+ search. (For some purposes, the planner treats <literal>&lt;&gt;</literal>
+ as associated with a btree operator class; but it finds that operator via
+ the <literal>=</literal> operator's negator link, rather than
+ from <structname>pg_amop</structname>.)
+ </para>
+
+ <para>
+ When several data types share near-identical sorting semantics, their
+ operator classes can be grouped into an operator family. Doing so is
+ advantageous because it allows the planner to make deductions about
+ cross-type comparisons. Each operator class within the family should
+ contain the single-type operators (and associated support functions)
+ for its input data type, while cross-type comparison operators and
+ support functions are <quote>loose</quote> in the family. It is
+ recommendable that a complete set of cross-type operators be included
+ in the family, thus ensuring that the planner can represent any
+ comparison conditions that it deduces from transitivity.
+ </para>
+
+ <para>
+ There are some basic assumptions that a btree operator family must
+ satisfy:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ An <literal>=</literal> operator must be an equivalence relation; that
+ is, for all non-null values <replaceable>A</replaceable>,
+ <replaceable>B</replaceable>, <replaceable>C</replaceable> of the
+ data type:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <replaceable>A</replaceable> <literal>=</literal>
+ <replaceable>A</replaceable> is true
+ (<firstterm>reflexive law</firstterm>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if <replaceable>A</replaceable> <literal>=</literal>
+ <replaceable>B</replaceable>,
+ then <replaceable>B</replaceable> <literal>=</literal>
+ <replaceable>A</replaceable>
+ (<firstterm>symmetric law</firstterm>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if <replaceable>A</replaceable> <literal>=</literal>
+ <replaceable>B</replaceable> and <replaceable>B</replaceable>
+ <literal>=</literal> <replaceable>C</replaceable>,
+ then <replaceable>A</replaceable> <literal>=</literal>
+ <replaceable>C</replaceable>
+ (<firstterm>transitive law</firstterm>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <literal>&lt;</literal> operator must be a strong ordering relation;
+ that is, for all non-null values <replaceable>A</replaceable>,
+ <replaceable>B</replaceable>, <replaceable>C</replaceable>:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <replaceable>A</replaceable> <literal>&lt;</literal>
+ <replaceable>A</replaceable> is false
+ (<firstterm>irreflexive law</firstterm>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if <replaceable>A</replaceable> <literal>&lt;</literal>
+ <replaceable>B</replaceable>
+ and <replaceable>B</replaceable> <literal>&lt;</literal>
+ <replaceable>C</replaceable>,
+ then <replaceable>A</replaceable> <literal>&lt;</literal>
+ <replaceable>C</replaceable>
+ (<firstterm>transitive law</firstterm>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Furthermore, the ordering is total; that is, for all non-null
+ values <replaceable>A</replaceable>, <replaceable>B</replaceable>:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ exactly one of <replaceable>A</replaceable> <literal>&lt;</literal>
+ <replaceable>B</replaceable>, <replaceable>A</replaceable>
+ <literal>=</literal> <replaceable>B</replaceable>, and
+ <replaceable>B</replaceable> <literal>&lt;</literal>
+ <replaceable>A</replaceable> is true
+ (<firstterm>trichotomy law</firstterm>)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ (The trichotomy law justifies the definition of the comparison support
+ function, of course.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The other three operators are defined in terms of <literal>=</literal>
+ and <literal>&lt;</literal> in the obvious way, and must act consistently
+ with them.
+ </para>
+
+ <para>
+ For an operator family supporting multiple data types, the above laws must
+ hold when <replaceable>A</replaceable>, <replaceable>B</replaceable>,
+ <replaceable>C</replaceable> are taken from any data types in the family.
+ The transitive laws are the trickiest to ensure, as in cross-type
+ situations they represent statements that the behaviors of two or three
+ different operators are consistent.
+ As an example, it would not work to put <type>float8</type>
+ and <type>numeric</type> into the same operator family, at least not with
+ the current semantics that <type>numeric</type> values are converted
+ to <type>float8</type> for comparison to a <type>float8</type>. Because
+ of the limited accuracy of <type>float8</type>, this means there are
+ distinct <type>numeric</type> values that will compare equal to the
+ same <type>float8</type> value, and thus the transitive law would fail.
+ </para>
+
+ <para>
+ Another requirement for a multiple-data-type family is that any implicit
+ or binary-coercion casts that are defined between data types included in
+ the operator family must not change the associated sort ordering.
+ </para>
+
+ <para>
+ It should be fairly clear why a btree index requires these laws to hold
+ within a single data type: without them there is no ordering to arrange
+ the keys with. Also, index searches using a comparison key of a
+ different data type require comparisons to behave sanely across two
+ data types. The extensions to three or more data types within a family
+ are not strictly required by the btree index mechanism itself, but the
+ planner relies on them for optimization purposes.
+ </para>
+
+</sect1>
+
+<sect1 id="btree-support-funcs">
+ <title>B-Tree Support Functions</title>
+
+ <para>
+ As shown in <xref linkend="xindex-btree-support-table"/>, btree defines
+ one required and four optional support functions. The five
+ user-defined methods are:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><function>order</function></term>
+ <listitem>
+ <para>
+ For each combination of data types that a btree operator family
+ provides comparison operators for, it must provide a comparison
+ support function, registered in
+ <structname>pg_amproc</structname> with support function number 1
+ and
+ <structfield>amproclefttype</structfield>/<structfield>amprocrighttype</structfield>
+ equal to the left and right data types for the comparison (i.e.,
+ the same data types that the matching operators are registered
+ with in <structname>pg_amop</structname>). The comparison
+ function must take two non-null values
+ <replaceable>A</replaceable> and <replaceable>B</replaceable> and
+ return an <type>int32</type> value that is
+ <literal>&lt;</literal> <literal>0</literal>,
+ <literal>0</literal>, or <literal>&gt;</literal>
+ <literal>0</literal> when <replaceable>A</replaceable>
+ <literal>&lt;</literal> <replaceable>B</replaceable>,
+ <replaceable>A</replaceable> <literal>=</literal>
+ <replaceable>B</replaceable>, or <replaceable>A</replaceable>
+ <literal>&gt;</literal> <replaceable>B</replaceable>,
+ respectively. A null result is disallowed: all values of the
+ data type must be comparable. See
+ <filename>src/backend/access/nbtree/nbtcompare.c</filename> for
+ examples.
+ </para>
+
+ <para>
+ If the compared values are of a collatable data type, the
+ appropriate collation OID will be passed to the comparison
+ support function, using the standard
+ <function>PG_GET_COLLATION()</function> mechanism.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>sortsupport</function></term>
+ <listitem>
+ <para>
+ Optionally, a btree operator family may provide <firstterm>sort
+ support</firstterm> function(s), registered under support
+ function number 2. These functions allow implementing
+ comparisons for sorting purposes in a more efficient way than
+ naively calling the comparison support function. The APIs
+ involved in this are defined in
+ <filename>src/include/utils/sortsupport.h</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>in_range</function></term>
+ <listitem>
+ <indexterm>
+ <primary>in_range support functions</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>support functions</primary>
+ <secondary>in_range</secondary>
+ </indexterm>
+ <para>
+ Optionally, a btree operator family may provide
+ <firstterm>in_range</firstterm> support function(s), registered
+ under support function number 3. These are not used during btree
+ index operations; rather, they extend the semantics of the
+ operator family so that it can support window clauses containing
+ the <literal>RANGE</literal> <replaceable>offset</replaceable>
+ <literal>PRECEDING</literal> and <literal>RANGE</literal>
+ <replaceable>offset</replaceable> <literal>FOLLOWING</literal>
+ frame bound types (see <xref
+ linkend="syntax-window-functions"/>). Fundamentally, the extra
+ information provided is how to add or subtract an
+ <replaceable>offset</replaceable> value in a way that is
+ compatible with the family's data ordering.
+ </para>
+
+ <para>
+ An <function>in_range</function> function must have the signature
+<synopsis>
+in_range(<replaceable>val</replaceable> type1, <replaceable>base</replaceable> type1, <replaceable>offset</replaceable> type2, <replaceable>sub</replaceable> bool, <replaceable>less</replaceable> bool)
+returns bool
+</synopsis>
+ <replaceable>val</replaceable> and
+ <replaceable>base</replaceable> must be of the same type, which
+ is one of the types supported by the operator family (i.e., a
+ type for which it provides an ordering). However,
+ <replaceable>offset</replaceable> could be of a different type,
+ which might be one otherwise unsupported by the family. An
+ example is that the built-in <literal>time_ops</literal> family
+ provides an <function>in_range</function> function that has
+ <replaceable>offset</replaceable> of type <type>interval</type>.
+ A family can provide <function>in_range</function> functions for
+ any of its supported types and one or more
+ <replaceable>offset</replaceable> types. Each
+ <function>in_range</function> function should be entered in
+ <structname>pg_amproc</structname> with
+ <structfield>amproclefttype</structfield> equal to
+ <type>type1</type> and <structfield>amprocrighttype</structfield>
+ equal to <type>type2</type>.
+ </para>
+
+ <para>
+ The essential semantics of an <function>in_range</function>
+ function depend on the two Boolean flag parameters. It should
+ add or subtract <replaceable>base</replaceable> and
+ <replaceable>offset</replaceable>, then compare
+ <replaceable>val</replaceable> to the result, as follows:
+ <itemizedlist>
+ <listitem>
+ <para>
+ if <literal>!</literal><replaceable>sub</replaceable> and
+ <literal>!</literal><replaceable>less</replaceable>, return
+ <replaceable>val</replaceable> <literal>&gt;=</literal>
+ (<replaceable>base</replaceable> <literal>+</literal>
+ <replaceable>offset</replaceable>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if <literal>!</literal><replaceable>sub</replaceable> and
+ <replaceable>less</replaceable>, return
+ <replaceable>val</replaceable> <literal>&lt;=</literal>
+ (<replaceable>base</replaceable> <literal>+</literal>
+ <replaceable>offset</replaceable>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if <replaceable>sub</replaceable> and
+ <literal>!</literal><replaceable>less</replaceable>, return
+ <replaceable>val</replaceable> <literal>&gt;=</literal>
+ (<replaceable>base</replaceable> <literal>-</literal>
+ <replaceable>offset</replaceable>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ if <replaceable>sub</replaceable> and
+ <replaceable>less</replaceable>, return
+ <replaceable>val</replaceable> <literal>&lt;=</literal>
+ (<replaceable>base</replaceable> <literal>-</literal>
+ <replaceable>offset</replaceable>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ Before doing so, the function should check the sign of
+ <replaceable>offset</replaceable>: if it is less than zero, raise
+ error
+ <literal>ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE</literal>
+ (22013) with error text like <quote>invalid preceding or
+ following size in window function</quote>. (This is required by
+ the SQL standard, although nonstandard operator families might
+ perhaps choose to ignore this restriction, since there seems to
+ be little semantic necessity for it.) This requirement is
+ delegated to the <function>in_range</function> function so that
+ the core code needn't understand what <quote>less than
+ zero</quote> means for a particular data type.
+ </para>
+
+ <para>
+ An additional expectation is that <function>in_range</function>
+ functions should, if practical, avoid throwing an error if
+ <replaceable>base</replaceable> <literal>+</literal>
+ <replaceable>offset</replaceable> or
+ <replaceable>base</replaceable> <literal>-</literal>
+ <replaceable>offset</replaceable> would overflow. The correct
+ comparison result can be determined even if that value would be
+ out of the data type's range. Note that if the data type
+ includes concepts such as <quote>infinity</quote> or
+ <quote>NaN</quote>, extra care may be needed to ensure that
+ <function>in_range</function>'s results agree with the normal
+ sort order of the operator family.
+ </para>
+
+ <para>
+ The results of the <function>in_range</function> function must be
+ consistent with the sort ordering imposed by the operator family.
+ To be precise, given any fixed values of
+ <replaceable>offset</replaceable> and
+ <replaceable>sub</replaceable>, then:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If <function>in_range</function> with
+ <replaceable>less</replaceable> = true is true for some
+ <replaceable>val1</replaceable> and
+ <replaceable>base</replaceable>, it must be true for every
+ <replaceable>val2</replaceable> <literal>&lt;=</literal>
+ <replaceable>val1</replaceable> with the same
+ <replaceable>base</replaceable>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <function>in_range</function> with
+ <replaceable>less</replaceable> = true is false for some
+ <replaceable>val1</replaceable> and
+ <replaceable>base</replaceable>, it must be false for every
+ <replaceable>val2</replaceable> <literal>&gt;=</literal>
+ <replaceable>val1</replaceable> with the same
+ <replaceable>base</replaceable>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <function>in_range</function> with
+ <replaceable>less</replaceable> = true is true for some
+ <replaceable>val</replaceable> and
+ <replaceable>base1</replaceable>, it must be true for every
+ <replaceable>base2</replaceable> <literal>&gt;=</literal>
+ <replaceable>base1</replaceable> with the same
+ <replaceable>val</replaceable>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <function>in_range</function> with
+ <replaceable>less</replaceable> = true is false for some
+ <replaceable>val</replaceable> and
+ <replaceable>base1</replaceable>, it must be false for every
+ <replaceable>base2</replaceable> <literal>&lt;=</literal>
+ <replaceable>base1</replaceable> with the same
+ <replaceable>val</replaceable>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ Analogous statements with inverted conditions hold when
+ <replaceable>less</replaceable> = false.
+ </para>
+
+ <para>
+ If the type being ordered (<type>type1</type>) is collatable, the
+ appropriate collation OID will be passed to the
+ <function>in_range</function> function, using the standard
+ PG_GET_COLLATION() mechanism.
+ </para>
+
+ <para>
+ <function>in_range</function> functions need not handle NULL
+ inputs, and typically will be marked strict.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>equalimage</function></term>
+ <listitem>
+ <para>
+ Optionally, a btree operator family may provide
+ <function>equalimage</function> (<quote>equality implies image
+ equality</quote>) support functions, registered under support
+ function number 4. These functions allow the core code to
+ determine when it is safe to apply the btree deduplication
+ optimization. Currently, <function>equalimage</function>
+ functions are only called when building or rebuilding an index.
+ </para>
+ <para>
+ An <function>equalimage</function> function must have the
+ signature
+<synopsis>
+equalimage(<replaceable>opcintype</replaceable> <type>oid</type>) returns bool
+</synopsis>
+ The return value is static information about an operator class
+ and collation. Returning <literal>true</literal> indicates that
+ the <function>order</function> function for the operator class is
+ guaranteed to only return <literal>0</literal> (<quote>arguments
+ are equal</quote>) when its <replaceable>A</replaceable> and
+ <replaceable>B</replaceable> arguments are also interchangeable
+ without any loss of semantic information. Not registering an
+ <function>equalimage</function> function or returning
+ <literal>false</literal> indicates that this condition cannot be
+ assumed to hold.
+ </para>
+ <para>
+ The <replaceable>opcintype</replaceable> argument is the
+ <literal><structname>pg_type</structname>.oid</literal> of the
+ data type that the operator class indexes. This is a convenience
+ that allows reuse of the same underlying
+ <function>equalimage</function> function across operator classes.
+ If <replaceable>opcintype</replaceable> is a collatable data
+ type, the appropriate collation OID will be passed to the
+ <function>equalimage</function> function, using the standard
+ <function>PG_GET_COLLATION()</function> mechanism.
+ </para>
+ <para>
+ As far as the operator class is concerned, returning
+ <literal>true</literal> indicates that deduplication is safe (or
+ safe for the collation whose OID was passed to its
+ <function>equalimage</function> function). However, the core
+ code will only deem deduplication safe for an index when
+ <emphasis>every</emphasis> indexed column uses an operator class
+ that registers an <function>equalimage</function> function, and
+ each function actually returns <literal>true</literal> when
+ called.
+ </para>
+ <para>
+ Image equality is <emphasis>almost</emphasis> the same condition
+ as simple bitwise equality. There is one subtle difference: When
+ indexing a varlena data type, the on-disk representation of two
+ image equal datums may not be bitwise equal due to inconsistent
+ application of <acronym>TOAST</acronym> compression on input.
+ Formally, when an operator class's
+ <function>equalimage</function> function returns
+ <literal>true</literal>, it is safe to assume that the
+ <literal>datum_image_eq()</literal> C function will always agree
+ with the operator class's <function>order</function> function
+ (provided that the same collation OID is passed to both the
+ <function>equalimage</function> and <function>order</function>
+ functions).
+ </para>
+ <para>
+ The core code is fundamentally unable to deduce anything about
+ the <quote>equality implies image equality</quote> status of an
+ operator class within a multiple-data-type family based on
+ details from other operator classes in the same family. Also, it
+ is not sensible for an operator family to register a cross-type
+ <function>equalimage</function> function, and attempting to do so
+ will result in an error. This is because <quote>equality implies
+ image equality</quote> status does not just depend on
+ sorting/equality semantics, which are more or less defined at the
+ operator family level. In general, the semantics that one
+ particular data type implements must be considered separately.
+ </para>
+ <para>
+ The convention followed by the operator classes included with the
+ core <productname>PostgreSQL</productname> distribution is to
+ register a stock, generic <function>equalimage</function>
+ function. Most operator classes register
+ <function>btequalimage()</function>, which indicates that
+ deduplication is safe unconditionally. Operator classes for
+ collatable data types such as <type>text</type> register
+ <function>btvarstrequalimage()</function>, which indicates that
+ deduplication is safe with deterministic collations. Best
+ practice for third-party extensions is to register their own
+ custom function to retain control.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>options</function></term>
+ <listitem>
+ <para>
+ Optionally, a B-tree operator family may provide
+ <function>options</function> (<quote>operator class specific
+ options</quote>) support functions, registered under support
+ function number 5. These functions define a set of user-visible
+ parameters that control operator class behavior.
+ </para>
+ <para>
+ An <function>options</function> support function must have the
+ signature
+<synopsis>
+options(<replaceable>relopts</replaceable> <type>local_relopts *</type>) returns void
+</synopsis>
+ The function is passed a pointer to a <structname>local_relopts</structname>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using the <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+ <para>
+ Currently, no B-Tree operator class has an <function>options</function>
+ support function. B-tree doesn't allow flexible representation of keys
+ like GiST, SP-GiST, GIN and BRIN do. So, <function>options</function>
+ probably doesn't have much application in the current B-tree index
+ access method. Nevertheless, this support function was added to B-tree
+ for uniformity, and will probably find uses during further
+ evolution of B-tree in <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</sect1>
+
+<sect1 id="btree-implementation">
+ <title>Implementation</title>
+
+ <para>
+ This section covers B-Tree index implementation details that may be
+ of use to advanced users. See
+ <filename>src/backend/access/nbtree/README</filename> in the source
+ distribution for a much more detailed, internals-focused description
+ of the B-Tree implementation.
+ </para>
+ <sect2 id="btree-structure">
+ <title>B-Tree Structure</title>
+ <para>
+ <productname>PostgreSQL</productname> B-Tree indexes are
+ multi-level tree structures, where each level of the tree can be
+ used as a doubly-linked list of pages. A single metapage is stored
+ in a fixed position at the start of the first segment file of the
+ index. All other pages are either leaf pages or internal pages.
+ Leaf pages are the pages on the lowest level of the tree. All
+ other levels consist of internal pages. Each leaf page contains
+ tuples that point to table rows. Each internal page contains
+ tuples that point to the next level down in the tree. Typically,
+ over 99% of all pages are leaf pages. Both internal pages and leaf
+ pages use the standard page format described in <xref
+ linkend="storage-page-layout"/>.
+ </para>
+ <para>
+ New leaf pages are added to a B-Tree index when an existing leaf
+ page cannot fit an incoming tuple. A <firstterm>page
+ split</firstterm> operation makes room for items that originally
+ belonged on the overflowing page by moving a portion of the items
+ to a new page. Page splits must also insert a new
+ <firstterm>downlink</firstterm> to the new page in the parent page,
+ which may cause the parent to split in turn. Page splits
+ <quote>cascade upwards</quote> in a recursive fashion. When the
+ root page finally cannot fit a new downlink, a <firstterm>root page
+ split</firstterm> operation takes place. This adds a new level to
+ the tree structure by creating a new root page that is one level
+ above the original root page.
+ </para>
+ </sect2>
+
+ <sect2 id="btree-deletion">
+ <title>Bottom-up Index Deletion</title>
+ <para>
+ B-Tree indexes are not directly aware that under MVCC, there might
+ be multiple extant versions of the same logical table row; to an
+ index, each tuple is an independent object that needs its own index
+ entry. <quote>Version churn</quote> tuples may sometimes
+ accumulate and adversely affect query latency and throughput. This
+ typically occurs with <command>UPDATE</command>-heavy workloads
+ where most individual updates cannot apply the
+ <link linkend="storage-hot"><acronym>HOT</acronym> optimization.</link>
+ Changing the value of only
+ one column covered by one index during an <command>UPDATE</command>
+ <emphasis>always</emphasis> necessitates a new set of index tuples
+ &mdash; one for <emphasis>each and every</emphasis> index on the
+ table. Note in particular that this includes indexes that were not
+ <quote>logically modified</quote> by the <command>UPDATE</command>.
+ All indexes will need a successor physical index tuple that points
+ to the latest version in the table. Each new tuple within each
+ index will generally need to coexist with the original
+ <quote>updated</quote> tuple for a short period of time (typically
+ until shortly after the <command>UPDATE</command> transaction
+ commits).
+ </para>
+ <para>
+ B-Tree indexes incrementally delete version churn index tuples by
+ performing <firstterm>bottom-up index deletion</firstterm> passes.
+ Each deletion pass is triggered in reaction to an anticipated
+ <quote>version churn page split</quote>. This only happens with
+ indexes that are not logically modified by
+ <command>UPDATE</command> statements, where concentrated build up
+ of obsolete versions in particular pages would occur otherwise. A
+ page split will usually be avoided, though it's possible that
+ certain implementation-level heuristics will fail to identify and
+ delete even one garbage index tuple (in which case a page split or
+ deduplication pass resolves the issue of an incoming new tuple not
+ fitting on a leaf page). The worst-case number of versions that
+ any index scan must traverse (for any single logical row) is an
+ important contributor to overall system responsiveness and
+ throughput. A bottom-up index deletion pass targets suspected
+ garbage tuples in a single leaf page based on
+ <emphasis>qualitative</emphasis> distinctions involving logical
+ rows and versions. This contrasts with the <quote>top-down</quote>
+ index cleanup performed by autovacuum workers, which is triggered
+ when certain <emphasis>quantitative</emphasis> table-level
+ thresholds are exceeded (see <xref linkend="autovacuum"/>).
+ </para>
+ <note>
+ <para>
+ Not all deletion operations that are performed within B-Tree
+ indexes are bottom-up deletion operations. There is a distinct
+ category of index tuple deletion: <firstterm>simple index tuple
+ deletion</firstterm>. This is a deferred maintenance operation
+ that deletes index tuples that are known to be safe to delete
+ (those whose item identifier's <literal>LP_DEAD</literal> bit is
+ already set). Like bottom-up index deletion, simple index
+ deletion takes place at the point that a page split is anticipated
+ as a way of avoiding the split.
+ </para>
+ <para>
+ Simple deletion is opportunistic in the sense that it can only
+ take place when recent index scans set the
+ <literal>LP_DEAD</literal> bits of affected items in passing.
+ Prior to <productname>PostgreSQL</productname> 14, the only
+ category of B-Tree deletion was simple deletion. The main
+ differences between it and bottom-up deletion are that only the
+ former is opportunistically driven by the activity of passing
+ index scans, while only the latter specifically targets version
+ churn from <command>UPDATE</command>s that do not logically modify
+ indexed columns.
+ </para>
+ </note>
+ <para>
+ Bottom-up index deletion performs the vast majority of all garbage
+ index tuple cleanup for particular indexes with certain workloads.
+ This is expected with any B-Tree index that is subject to
+ significant version churn from <command>UPDATE</command>s that
+ rarely or never logically modify the columns that the index covers.
+ The average and worst-case number of versions per logical row can
+ be kept low purely through targeted incremental deletion passes.
+ It's quite possible that the on-disk size of certain indexes will
+ never increase by even one single page/block despite
+ <emphasis>constant</emphasis> version churn from
+ <command>UPDATE</command>s. Even then, an exhaustive <quote>clean
+ sweep</quote> by a <command>VACUUM</command> operation (typically
+ run in an autovacuum worker process) will eventually be required as
+ a part of <emphasis>collective</emphasis> cleanup of the table and
+ each of its indexes.
+ </para>
+ <para>
+ Unlike <command>VACUUM</command>, bottom-up index deletion does not
+ provide any strong guarantees about how old the oldest garbage
+ index tuple may be. No index can be permitted to retain
+ <quote>floating garbage</quote> index tuples that became dead prior
+ to a conservative cutoff point shared by the table and all of its
+ indexes collectively. This fundamental table-level invariant makes
+ it safe to recycle table <acronym>TID</acronym>s. This is how it
+ is possible for distinct logical rows to reuse the same table
+ <acronym>TID</acronym> over time (though this can never happen with
+ two logical rows whose lifetimes span the same
+ <command>VACUUM</command> cycle).
+ </para>
+ </sect2>
+
+ <sect2 id="btree-deduplication">
+ <title>Deduplication</title>
+ <para>
+ A duplicate is a leaf page tuple (a tuple that points to a table
+ row) where <emphasis>all</emphasis> indexed key columns have values
+ that match corresponding column values from at least one other leaf
+ page tuple in the same index. Duplicate tuples are quite common in
+ practice. B-Tree indexes can use a special, space-efficient
+ representation for duplicates when an optional technique is
+ enabled: <firstterm>deduplication</firstterm>.
+ </para>
+ <para>
+ Deduplication works by periodically merging groups of duplicate
+ tuples together, forming a single <firstterm>posting list</firstterm> tuple for each
+ group. The column key value(s) only appear once in this
+ representation. This is followed by a sorted array of
+ <acronym>TID</acronym>s that point to rows in the table. This
+ significantly reduces the storage size of indexes where each value
+ (or each distinct combination of column values) appears several
+ times on average. The latency of queries can be reduced
+ significantly. Overall query throughput may increase
+ significantly. The overhead of routine index vacuuming may also be
+ reduced significantly.
+ </para>
+ <note>
+ <para>
+ B-Tree deduplication is just as effective with
+ <quote>duplicates</quote> that contain a NULL value, even though
+ NULL values are never equal to each other according to the
+ <literal>=</literal> member of any B-Tree operator class. As far
+ as any part of the implementation that understands the on-disk
+ B-Tree structure is concerned, NULL is just another value from the
+ domain of indexed values.
+ </para>
+ </note>
+ <para>
+ The deduplication process occurs lazily, when a new item is
+ inserted that cannot fit on an existing leaf page, though only when
+ index tuple deletion could not free sufficient space for the new
+ item (typically deletion is briefly considered and then skipped
+ over). Unlike GIN posting list tuples, B-Tree posting list tuples
+ do not need to expand every time a new duplicate is inserted; they
+ are merely an alternative physical representation of the original
+ logical contents of the leaf page. This design prioritizes
+ consistent performance with mixed read-write workloads. Most
+ client applications will at least see a moderate performance
+ benefit from using deduplication. Deduplication is enabled by
+ default.
+ </para>
+ <para>
+ <command>CREATE INDEX</command> and <command>REINDEX</command>
+ apply deduplication to create posting list tuples, though the
+ strategy they use is slightly different. Each group of duplicate
+ ordinary tuples encountered in the sorted input taken from the
+ table is merged into a posting list tuple
+ <emphasis>before</emphasis> being added to the current pending leaf
+ page. Individual posting list tuples are packed with as many
+ <acronym>TID</acronym>s as possible. Leaf pages are written out in
+ the usual way, without any separate deduplication pass. This
+ strategy is well-suited to <command>CREATE INDEX</command> and
+ <command>REINDEX</command> because they are once-off batch
+ operations.
+ </para>
+ <para>
+ Write-heavy workloads that don't benefit from deduplication due to
+ having few or no duplicate values in indexes will incur a small,
+ fixed performance penalty (unless deduplication is explicitly
+ disabled). The <literal>deduplicate_items</literal> storage
+ parameter can be used to disable deduplication within individual
+ indexes. There is never any performance penalty with read-only
+ workloads, since reading posting list tuples is at least as
+ efficient as reading the standard tuple representation. Disabling
+ deduplication isn't usually helpful.
+ </para>
+ <para>
+ It is sometimes possible for unique indexes (as well as unique
+ constraints) to use deduplication. This allows leaf pages to
+ temporarily <quote>absorb</quote> extra version churn duplicates.
+ Deduplication in unique indexes augments bottom-up index deletion,
+ especially in cases where a long-running transaction holds a
+ snapshot that blocks garbage collection. The goal is to buy time
+ for the bottom-up index deletion strategy to become effective
+ again. Delaying page splits until a single long-running
+ transaction naturally goes away can allow a bottom-up deletion pass
+ to succeed where an earlier deletion pass failed.
+ </para>
+ <tip>
+ <para>
+ A special heuristic is applied to determine whether a
+ deduplication pass in a unique index should take place. It can
+ often skip straight to splitting a leaf page, avoiding a
+ performance penalty from wasting cycles on unhelpful deduplication
+ passes. If you're concerned about the overhead of deduplication,
+ consider setting <literal>deduplicate_items = off</literal>
+ selectively. Leaving deduplication enabled in unique indexes has
+ little downside.
+ </para>
+ </tip>
+ <para>
+ Deduplication cannot be used in all cases due to
+ implementation-level restrictions. Deduplication safety is
+ determined when <command>CREATE INDEX</command> or
+ <command>REINDEX</command> is run.
+ </para>
+ <para>
+ Note that deduplication is deemed unsafe and cannot be used in the
+ following cases involving semantically significant differences
+ among equal datums:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <type>text</type>, <type>varchar</type>, and <type>char</type>
+ cannot use deduplication when a
+ <emphasis>nondeterministic</emphasis> collation is used. Case
+ and accent differences must be preserved among equal datums.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <type>numeric</type> cannot use deduplication. Numeric display
+ scale must be preserved among equal datums.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <type>jsonb</type> cannot use deduplication, since the
+ <type>jsonb</type> B-Tree operator class uses
+ <type>numeric</type> internally.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <type>float4</type> and <type>float8</type> cannot use
+ deduplication. These types have distinct representations for
+ <literal>-0</literal> and <literal>0</literal>, which are
+ nevertheless considered equal. This difference must be
+ preserved.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ There is one further implementation-level restriction that may be
+ lifted in a future version of
+ <productname>PostgreSQL</productname>:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Container types (such as composite types, arrays, or range
+ types) cannot use deduplication.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ There is one further implementation-level restriction that applies
+ regardless of the operator class or collation used:
+ </para>
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>INCLUDE</literal> indexes can never use deduplication.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect2>
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
new file mode 100644
index 0000000..7aaf729
--- /dev/null
+++ b/doc/src/sgml/catalogs.sgml
@@ -0,0 +1,9584 @@
+<!-- doc/src/sgml/catalogs.sgml -->
+<!--
+ Documentation of the system catalogs, directed toward PostgreSQL developers
+ -->
+
+<chapter id="catalogs">
+ <title>System Catalogs</title>
+
+ <para>
+ The system catalogs are the place where a relational database
+ management system stores schema metadata, such as information about
+ tables and columns, and internal bookkeeping information.
+ <productname>PostgreSQL</productname>'s system catalogs are regular
+ tables. You can drop and recreate the tables, add columns, insert
+ and update values, and severely mess up your system that way.
+ Normally, one should not change the system catalogs by hand, there
+ are normally SQL commands to do that. (For example, <command>CREATE
+ DATABASE</command> inserts a row into the
+ <structname>pg_database</structname> catalog &mdash; and actually
+ creates the database on disk.) There are some exceptions for
+ particularly esoteric operations, but many of those have been made
+ available as SQL commands over time, and so the need for direct manipulation
+ of the system catalogs is ever decreasing.
+ </para>
+
+ <sect1 id="catalogs-overview">
+ <title>Overview</title>
+
+ <para>
+ <xref linkend="catalog-table"/> lists the system catalogs.
+ More detailed documentation of each catalog follows below.
+ </para>
+
+ <para>
+ Most system catalogs are copied from the template database during
+ database creation and are thereafter database-specific. A few
+ catalogs are physically shared across all databases in a cluster;
+ these are noted in the descriptions of the individual catalogs.
+ </para>
+
+ <table id="catalog-table">
+ <title>System Catalogs</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Catalog Name</entry>
+ <entry>Purpose</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><link linkend="catalog-pg-aggregate"><structname>pg_aggregate</structname></link></entry>
+ <entry>aggregate functions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-am"><structname>pg_am</structname></link></entry>
+ <entry>relation access methods</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-amop"><structname>pg_amop</structname></link></entry>
+ <entry>access method operators</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-amproc"><structname>pg_amproc</structname></link></entry>
+ <entry>access method support functions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-attrdef"><structname>pg_attrdef</structname></link></entry>
+ <entry>column default values</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link></entry>
+ <entry>table columns (<quote>attributes</quote>)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-authid"><structname>pg_authid</structname></link></entry>
+ <entry>authorization identifiers (roles)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-auth-members"><structname>pg_auth_members</structname></link></entry>
+ <entry>authorization identifier membership relationships</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-cast"><structname>pg_cast</structname></link></entry>
+ <entry>casts (data type conversions)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-class"><structname>pg_class</structname></link></entry>
+ <entry>tables, indexes, sequences, views (<quote>relations</quote>)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-collation"><structname>pg_collation</structname></link></entry>
+ <entry>collations (locale information)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-constraint"><structname>pg_constraint</structname></link></entry>
+ <entry>check constraints, unique constraints, primary key constraints, foreign key constraints</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-conversion"><structname>pg_conversion</structname></link></entry>
+ <entry>encoding conversion information</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-database"><structname>pg_database</structname></link></entry>
+ <entry>databases within this database cluster</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-db-role-setting"><structname>pg_db_role_setting</structname></link></entry>
+ <entry>per-role and per-database settings</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-default-acl"><structname>pg_default_acl</structname></link></entry>
+ <entry>default privileges for object types</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-depend"><structname>pg_depend</structname></link></entry>
+ <entry>dependencies between database objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-description"><structname>pg_description</structname></link></entry>
+ <entry>descriptions or comments on database objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-enum"><structname>pg_enum</structname></link></entry>
+ <entry>enum label and value definitions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-event-trigger"><structname>pg_event_trigger</structname></link></entry>
+ <entry>event triggers</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-extension"><structname>pg_extension</structname></link></entry>
+ <entry>installed extensions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-foreign-data-wrapper"><structname>pg_foreign_data_wrapper</structname></link></entry>
+ <entry>foreign-data wrapper definitions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-foreign-server"><structname>pg_foreign_server</structname></link></entry>
+ <entry>foreign server definitions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-foreign-table"><structname>pg_foreign_table</structname></link></entry>
+ <entry>additional foreign table information</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-index"><structname>pg_index</structname></link></entry>
+ <entry>additional index information</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-inherits"><structname>pg_inherits</structname></link></entry>
+ <entry>table inheritance hierarchy</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-init-privs"><structname>pg_init_privs</structname></link></entry>
+ <entry>object initial privileges</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-language"><structname>pg_language</structname></link></entry>
+ <entry>languages for writing functions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-largeobject"><structname>pg_largeobject</structname></link></entry>
+ <entry>data pages for large objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</structname></link></entry>
+ <entry>metadata for large objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link></entry>
+ <entry>schemas</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link></entry>
+ <entry>access method operator classes</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-operator"><structname>pg_operator</structname></link></entry>
+ <entry>operators</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link></entry>
+ <entry>access method operator families</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-parameter-acl"><structname>pg_parameter_acl</structname></link></entry>
+ <entry>configuration parameters for which privileges have been granted</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-partitioned-table"><structname>pg_partitioned_table</structname></link></entry>
+ <entry>information about partition key of tables</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-policy"><structname>pg_policy</structname></link></entry>
+ <entry>row-security policies</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-proc"><structname>pg_proc</structname></link></entry>
+ <entry>functions and procedures</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-publication"><structname>pg_publication</structname></link></entry>
+ <entry>publications for logical replication</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-publication-namespace"><structname>pg_publication_namespace</structname></link></entry>
+ <entry>schema to publication mapping</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-publication-rel"><structname>pg_publication_rel</structname></link></entry>
+ <entry>relation to publication mapping</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-range"><structname>pg_range</structname></link></entry>
+ <entry>information about range types</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-replication-origin"><structname>pg_replication_origin</structname></link></entry>
+ <entry>registered replication origins</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-rewrite"><structname>pg_rewrite</structname></link></entry>
+ <entry>query rewrite rules</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link></entry>
+ <entry>security labels on database objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-sequence"><structname>pg_sequence</structname></link></entry>
+ <entry>information about sequences</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-shdepend"><structname>pg_shdepend</structname></link></entry>
+ <entry>dependencies on shared objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-shdescription"><structname>pg_shdescription</structname></link></entry>
+ <entry>comments on shared objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-shseclabel"><structname>pg_shseclabel</structname></link></entry>
+ <entry>security labels on shared database objects</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link></entry>
+ <entry>planner statistics</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link></entry>
+ <entry>extended planner statistics (definition)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link></entry>
+ <entry>extended planner statistics (built statistics)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-subscription"><structname>pg_subscription</structname></link></entry>
+ <entry>logical replication subscriptions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-subscription-rel"><structname>pg_subscription_rel</structname></link></entry>
+ <entry>relation state for subscriptions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link></entry>
+ <entry>tablespaces within this database cluster</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-transform"><structname>pg_transform</structname></link></entry>
+ <entry>transforms (data type to procedural language conversions)</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link></entry>
+ <entry>triggers</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-ts-config"><structname>pg_ts_config</structname></link></entry>
+ <entry>text search configurations</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-ts-config-map"><structname>pg_ts_config_map</structname></link></entry>
+ <entry>text search configurations' token mappings</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-ts-dict"><structname>pg_ts_dict</structname></link></entry>
+ <entry>text search dictionaries</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-ts-parser"><structname>pg_ts_parser</structname></link></entry>
+ <entry>text search parsers</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-ts-template"><structname>pg_ts_template</structname></link></entry>
+ <entry>text search templates</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-type"><structname>pg_type</structname></link></entry>
+ <entry>data types</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="catalog-pg-user-mapping"><structname>pg_user_mapping</structname></link></entry>
+ <entry>mappings of users to foreign servers</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-aggregate">
+ <title><structname>pg_aggregate</structname></title>
+
+ <indexterm zone="catalog-pg-aggregate">
+ <primary>pg_aggregate</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_aggregate</structname> stores information about
+ aggregate functions. An aggregate function is a function that
+ operates on a set of values (typically one column from each row
+ that matches a query condition) and returns a single value computed
+ from all these values. Typical aggregate functions are
+ <function>sum</function>, <function>count</function>, and
+ <function>max</function>. Each entry in
+ <structname>pg_aggregate</structname> is an extension of an entry
+ in <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.
+ The <structname>pg_proc</structname> entry carries the aggregate's name,
+ input and output data types, and other information that is similar to
+ ordinary functions.
+ </para>
+
+ <table>
+ <title><structname>pg_aggregate</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggfnoid</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ <structname>pg_proc</structname> OID of the aggregate function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggkind</structfield> <type>char</type>
+ </para>
+ <para>
+ Aggregate kind:
+ <literal>n</literal> for <quote>normal</quote> aggregates,
+ <literal>o</literal> for <quote>ordered-set</quote> aggregates, or
+ <literal>h</literal> for <quote>hypothetical-set</quote> aggregates
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggnumdirectargs</structfield> <type>int2</type>
+ </para>
+ <para>
+ Number of direct (non-aggregated) arguments of an ordered-set or
+ hypothetical-set aggregate, counting a variadic array as one argument.
+ If equal to <structfield>pronargs</structfield>, the aggregate must be variadic
+ and the variadic array describes the aggregated arguments as well as
+ the final direct arguments.
+ Always zero for normal aggregates.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggtransfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Transition function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggfinalfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Final function (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggcombinefn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Combine function (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggserialfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Serialization function (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggdeserialfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Deserialization function (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggmtransfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Forward transition function for moving-aggregate mode (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggminvtransfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Inverse transition function for moving-aggregate mode (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggmfinalfn</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Final function for moving-aggregate mode (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggfinalextra</structfield> <type>bool</type>
+ </para>
+ <para>
+ True to pass extra dummy arguments to <structfield>aggfinalfn</structfield>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggmfinalextra</structfield> <type>bool</type>
+ </para>
+ <para>
+ True to pass extra dummy arguments to <structfield>aggmfinalfn</structfield>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggfinalmodify</structfield> <type>char</type>
+ </para>
+ <para>
+ Whether <structfield>aggfinalfn</structfield> modifies the
+ transition state value:
+ <literal>r</literal> if it is read-only,
+ <literal>s</literal> if the <structfield>aggtransfn</structfield>
+ cannot be applied after the <structfield>aggfinalfn</structfield>, or
+ <literal>w</literal> if it writes on the value
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggmfinalmodify</structfield> <type>char</type>
+ </para>
+ <para>
+ Like <structfield>aggfinalmodify</structfield>, but for
+ the <structfield>aggmfinalfn</structfield>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggsortop</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Associated sort operator (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggtranstype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type of the aggregate function's internal transition (state) data
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggtransspace</structfield> <type>int4</type>
+ </para>
+ <para>
+ Approximate average size (in bytes) of the transition state
+ data, or zero to use a default estimate
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggmtranstype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type of the aggregate function's internal transition (state)
+ data for moving-aggregate mode (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggmtransspace</structfield> <type>int4</type>
+ </para>
+ <para>
+ Approximate average size (in bytes) of the transition state data
+ for moving-aggregate mode, or zero to use a default estimate
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>agginitval</structfield> <type>text</type>
+ </para>
+ <para>
+ The initial value of the transition state. This is a text
+ field containing the initial value in its external string
+ representation. If this field is null, the transition state
+ value starts out null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>aggminitval</structfield> <type>text</type>
+ </para>
+ <para>
+ The initial value of the transition state for moving-aggregate mode.
+ This is a text field containing the initial value in its external
+ string representation. If this field is null, the transition state
+ value starts out null.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ New aggregate functions are registered with the <link
+ linkend="sql-createaggregate"><command>CREATE AGGREGATE</command></link>
+ command. See <xref linkend="xaggr"/> for more information about
+ writing aggregate functions and the meaning of the transition
+ functions, etc.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-am">
+ <title><structname>pg_am</structname></title>
+
+ <indexterm zone="catalog-pg-am">
+ <primary>pg_am</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_am</structname> stores information about
+ relation access methods. There is one row for each access method supported
+ by the system.
+ Currently, only tables and indexes have access methods. The requirements for table
+ and index access methods are discussed in detail in <xref linkend="tableam"/> and
+ <xref linkend="indexam"/> respectively.
+ </para>
+
+ <table>
+ <title><structname>pg_am</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the access method
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amhandler</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of a handler function that is responsible for supplying information
+ about the access method
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amtype</structfield> <type>char</type>
+ </para>
+ <para>
+ <literal>t</literal> = table (including materialized views),
+ <literal>i</literal> = index.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 9.6, <structname>pg_am</structname>
+ contained many additional columns representing properties of index access
+ methods. That data is now only directly visible at the C code level.
+ However, <function>pg_index_column_has_property()</function> and related
+ functions have been added to allow SQL queries to inspect index access
+ method properties; see <xref linkend="functions-info-catalog-table"/>.
+ </para>
+ </note>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-amop">
+ <title><structname>pg_amop</structname></title>
+
+ <indexterm zone="catalog-pg-amop">
+ <primary>pg_amop</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_amop</structname> stores information about
+ operators associated with access method operator families. There is one
+ row for each operator that is a member of an operator family. A family
+ member can be either a <firstterm>search</firstterm> operator or an
+ <firstterm>ordering</firstterm> operator. An operator
+ can appear in more than one family, but cannot appear in more than one
+ search position nor more than one ordering position within a family.
+ (It is allowed, though unlikely, for an operator to be used for both
+ search and ordering purposes.)
+ </para>
+
+ <table>
+ <title><structname>pg_amop</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amopfamily</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The operator family this entry is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amoplefttype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Left-hand input data type of operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amoprighttype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Right-hand input data type of operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amopstrategy</structfield> <type>int2</type>
+ </para>
+ <para>
+ Operator strategy number
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amoppurpose</structfield> <type>char</type>
+ </para>
+ <para>
+ Operator purpose, either <literal>s</literal> for search or
+ <literal>o</literal> for ordering
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amopopr</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amopmethod</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-am"><structname>pg_am</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Index access method operator family is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amopsortfamily</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The B-tree operator family this entry sorts according to, if an
+ ordering operator; zero if a search operator
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ A <quote>search</quote> operator entry indicates that an index of this operator
+ family can be searched to find all rows satisfying
+ <literal>WHERE</literal>
+ <replaceable>indexed_column</replaceable>
+ <replaceable>operator</replaceable>
+ <replaceable>constant</replaceable>.
+ Obviously, such an operator must return <type>boolean</type>, and its left-hand input
+ type must match the index's column data type.
+ </para>
+
+ <para>
+ An <quote>ordering</quote> operator entry indicates that an index of this
+ operator family can be scanned to return rows in the order represented by
+ <literal>ORDER BY</literal>
+ <replaceable>indexed_column</replaceable>
+ <replaceable>operator</replaceable>
+ <replaceable>constant</replaceable>.
+ Such an operator could return any sortable data type, though again
+ its left-hand input type must match the index's column data type.
+ The exact semantics of the <literal>ORDER BY</literal> are specified by the
+ <structfield>amopsortfamily</structfield> column, which must reference
+ a B-tree operator family for the operator's result type.
+ </para>
+
+ <note>
+ <para>
+ At present, it's assumed that the sort order for an ordering operator
+ is the default for the referenced operator family, i.e., <literal>ASC NULLS
+ LAST</literal>. This might someday be relaxed by adding additional columns
+ to specify sort options explicitly.
+ </para>
+ </note>
+
+ <para>
+ An entry's <structfield>amopmethod</structfield> must match the
+ <structfield>opfmethod</structfield> of its containing operator family (including
+ <structfield>amopmethod</structfield> here is an intentional denormalization of the
+ catalog structure for performance reasons). Also,
+ <structfield>amoplefttype</structfield> and <structfield>amoprighttype</structfield> must match
+ the <structfield>oprleft</structfield> and <structfield>oprright</structfield> fields of the
+ referenced <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link> entry.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-amproc">
+ <title><structname>pg_amproc</structname></title>
+
+ <indexterm zone="catalog-pg-amproc">
+ <primary>pg_amproc</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_amproc</structname> stores information about
+ support functions associated with access method operator families. There
+ is one row for each support function belonging to an operator family.
+ </para>
+
+ <table>
+ <title><structname>pg_amproc</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amprocfamily</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The operator family this entry is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amproclefttype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Left-hand input data type of associated operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amprocrighttype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Right-hand input data type of associated operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amprocnum</structfield> <type>int2</type>
+ </para>
+ <para>
+ Support function number
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>amproc</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the function
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The usual interpretation of the
+ <structfield>amproclefttype</structfield> and <structfield>amprocrighttype</structfield> fields
+ is that they identify the left and right input types of the operator(s)
+ that a particular support function supports. For some access methods
+ these match the input data type(s) of the support function itself, for
+ others not. There is a notion of <quote>default</quote> support functions for
+ an index, which are those with <structfield>amproclefttype</structfield> and
+ <structfield>amprocrighttype</structfield> both equal to the index operator class's
+ <structfield>opcintype</structfield>.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-attrdef">
+ <title><structname>pg_attrdef</structname></title>
+
+ <indexterm zone="catalog-pg-attrdef">
+ <primary>pg_attrdef</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_attrdef</structname> stores column default
+ values. The main information about columns is stored in
+ <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.
+ Only columns for which a default value has been explicitly set will have
+ an entry here.
+ </para>
+
+ <table>
+ <title><structname>pg_attrdef</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>adrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table this column belongs to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>adnum</structfield> <type>int2</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ The number of the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>adbin</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ The column default value, in <function>nodeToString()</function>
+ representation. Use <literal>pg_get_expr(adbin, adrelid)</literal> to
+ convert it to an SQL expression.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-attribute">
+ <title><structname>pg_attribute</structname></title>
+
+ <indexterm zone="catalog-pg-attribute">
+ <primary>pg_attribute</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_attribute</structname> stores information about
+ table columns. There will be exactly one
+ <structname>pg_attribute</structname> row for every column in every
+ table in the database. (There will also be attribute entries for
+ indexes, and indeed all objects that have
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>
+ entries.)
+ </para>
+
+ <para>
+ The term attribute is equivalent to column and is used for
+ historical reasons.
+ </para>
+
+ <table>
+ <title><structname>pg_attribute</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table this column belongs to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attname</structfield> <type>name</type>
+ </para>
+ <para>
+ The column name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>atttypid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The data type of this column (zero for a dropped column)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attstattarget</structfield> <type>int4</type>
+ </para>
+ <para>
+ <structfield>attstattarget</structfield> controls the level of detail
+ of statistics accumulated for this column by
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>.
+ A zero value indicates that no statistics should be collected.
+ A negative value says to use the system default statistics target.
+ The exact meaning of positive values is data type-dependent.
+ For scalar data types, <structfield>attstattarget</structfield>
+ is both the target number of <quote>most common values</quote>
+ to collect, and the target number of histogram bins to create.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attlen</structfield> <type>int2</type>
+ </para>
+ <para>
+ A copy of <literal>pg_type.typlen</literal> of this column's
+ type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attnum</structfield> <type>int2</type>
+ </para>
+ <para>
+ The number of the column. Ordinary columns are numbered from 1
+ up. System columns, such as <structfield>ctid</structfield>,
+ have (arbitrary) negative numbers.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attndims</structfield> <type>int4</type>
+ </para>
+ <para>
+ Number of dimensions, if the column is an array type; otherwise 0.
+ (Presently, the number of dimensions of an array is not enforced,
+ so any nonzero value effectively means <quote>it's an array</quote>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attcacheoff</structfield> <type>int4</type>
+ </para>
+ <para>
+ Always -1 in storage, but when loaded into a row descriptor
+ in memory this might be updated to cache the offset of the attribute
+ within the row
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>atttypmod</structfield> <type>int4</type>
+ </para>
+ <para>
+ <structfield>atttypmod</structfield> records type-specific data
+ supplied at table creation time (for example, the maximum
+ length of a <type>varchar</type> column). It is passed to
+ type-specific input functions and length coercion functions.
+ The value will generally be -1 for types that do not need <structfield>atttypmod</structfield>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attbyval</structfield> <type>bool</type>
+ </para>
+ <para>
+ A copy of <literal>pg_type.typbyval</literal> of this column's type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attalign</structfield> <type>char</type>
+ </para>
+ <para>
+ A copy of <literal>pg_type.typalign</literal> of this column's type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attstorage</structfield> <type>char</type>
+ </para>
+ <para>
+ Normally a copy of <literal>pg_type.typstorage</literal> of this
+ column's type. For TOAST-able data types, this can be altered
+ after column creation to control storage policy.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attcompression</structfield> <type>char</type>
+ </para>
+ <para>
+ The current compression method of the column. Typically this is
+ <literal>'\0'</literal> to specify use of the current default setting
+ (see <xref linkend="guc-default-toast-compression"/>). Otherwise,
+ <literal>'p'</literal> selects pglz compression, while
+ <literal>'l'</literal> selects <productname>LZ4</productname>
+ compression. However, this field is ignored
+ whenever <structfield>attstorage</structfield> does not allow
+ compression.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attnotnull</structfield> <type>bool</type>
+ </para>
+ <para>
+ This represents a not-null constraint.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>atthasdef</structfield> <type>bool</type>
+ </para>
+ <para>
+ This column has a default expression or generation expression, in which
+ case there will be a corresponding entry in the
+ <link linkend="catalog-pg-attrdef"><structname>pg_attrdef</structname></link> catalog that actually defines the
+ expression. (Check <structfield>attgenerated</structfield> to
+ determine whether this is a default or a generation expression.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>atthasmissing</structfield> <type>bool</type>
+ </para>
+ <para>
+ This column has a value which is used where the column is entirely
+ missing from the row, as happens when a column is added with a
+ non-volatile <literal>DEFAULT</literal> value after the row is created.
+ The actual value used is stored in the
+ <structfield>attmissingval</structfield> column.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attidentity</structfield> <type>char</type>
+ </para>
+ <para>
+ If a zero byte (<literal>''</literal>), then not an identity column.
+ Otherwise, <literal>a</literal> = generated
+ always, <literal>d</literal> = generated by default.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attgenerated</structfield> <type>char</type>
+ </para>
+ <para>
+ If a zero byte (<literal>''</literal>), then not a generated column.
+ Otherwise, <literal>s</literal> = stored. (Other values might be added
+ in the future.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attisdropped</structfield> <type>bool</type>
+ </para>
+ <para>
+ This column has been dropped and is no longer valid. A dropped
+ column is still physically present in the table, but is
+ ignored by the parser and so cannot be accessed via SQL.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attislocal</structfield> <type>bool</type>
+ </para>
+ <para>
+ This column is defined locally in the relation. Note that a column can
+ be locally defined and inherited simultaneously.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attinhcount</structfield> <type>int4</type>
+ </para>
+ <para>
+ The number of direct ancestors this column has. A column with a
+ nonzero number of ancestors cannot be dropped nor renamed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attcollation</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The defined collation of the column, or zero if the column is
+ not of a collatable data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Column-level access privileges, if any have been granted specifically
+ on this column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Attribute-level options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attfdwoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Attribute-level foreign data wrapper options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attmissingval</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ This column has a one element array containing the value used when the
+ column is entirely missing from the row, as happens when the column is
+ added with a non-volatile <literal>DEFAULT</literal> value after the
+ row is created. The value is only used when
+ <structfield>atthasmissing</structfield> is true. If there is no value
+ the column is null.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In a dropped column's <structname>pg_attribute</structname> entry,
+ <structfield>atttypid</structfield> is reset to zero, but
+ <structfield>attlen</structfield> and the other fields copied from
+ <link linkend="catalog-pg-type"><structname>pg_type</structname></link> are still valid. This arrangement is needed
+ to cope with the situation where the dropped column's data type was
+ later dropped, and so there is no <structname>pg_type</structname> row anymore.
+ <structfield>attlen</structfield> and the other fields can be used
+ to interpret the contents of a row of the table.
+ </para>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-authid">
+ <title><structname>pg_authid</structname></title>
+
+ <indexterm zone="catalog-pg-authid">
+ <primary>pg_authid</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_authid</structname> contains information about
+ database authorization identifiers (roles). A role subsumes the concepts
+ of <quote>users</quote> and <quote>groups</quote>. A user is essentially just a
+ role with the <structfield>rolcanlogin</structfield> flag set. Any role (with or
+ without <structfield>rolcanlogin</structfield>) can have other roles as members; see
+ <link linkend="catalog-pg-auth-members"><structname>pg_auth_members</structname></link>.
+ </para>
+
+ <para>
+ Since this catalog contains passwords, it must not be publicly readable.
+ <link linkend="view-pg-roles"><structname>pg_roles</structname></link>
+ is a publicly readable view on
+ <structname>pg_authid</structname> that blanks out the password field.
+ </para>
+
+ <para>
+ <xref linkend="user-manag"/> contains detailed information about user and
+ privilege management.
+ </para>
+
+ <para>
+ Because user identities are cluster-wide,
+ <structname>pg_authid</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_authid</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_authid</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolname</structfield> <type>name</type>
+ </para>
+ <para>
+ Role name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolsuper</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role has superuser privileges
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolinherit</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role automatically inherits privileges of roles it is a
+ member of
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolcreaterole</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role can create more roles
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolcreatedb</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role can create databases
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolcanlogin</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role can log in. That is, this role can be given as the initial
+ session authorization identifier.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolreplication</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role is a replication role. A replication role can initiate replication
+ connections and create and drop replication slots.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolbypassrls</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role bypasses every row-level security policy, see
+ <xref linkend="ddl-rowsecurity"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolconnlimit</structfield> <type>int4</type>
+ </para>
+ <para>
+ For roles that can log in, this sets maximum number of concurrent
+ connections this role can make. -1 means no limit.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolpassword</structfield> <type>text</type>
+ </para>
+ <para>
+ Password (possibly encrypted); null if none. The format depends
+ on the form of encryption used.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolvaliduntil</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ Password expiry time (only used for password authentication);
+ null if no expiration
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ For an MD5 encrypted password, <structfield>rolpassword</structfield>
+ column will begin with the string <literal>md5</literal> followed by a
+ 32-character hexadecimal MD5 hash. The MD5 hash will be of the user's
+ password concatenated to their user name. For example, if user
+ <literal>joe</literal> has password <literal>xyzzy</literal>, <productname>PostgreSQL</productname>
+ will store the md5 hash of <literal>xyzzyjoe</literal>.
+ </para>
+
+ <para>
+ If the password is encrypted with SCRAM-SHA-256, it has the format:
+<synopsis>
+SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&lt;salt&gt;</replaceable>$<replaceable>&lt;StoredKey&gt;</replaceable>:<replaceable>&lt;ServerKey&gt;</replaceable>
+</synopsis>
+ where <replaceable>salt</replaceable>, <replaceable>StoredKey</replaceable> and
+ <replaceable>ServerKey</replaceable> are in Base64 encoded format. This format is
+ the same as that specified by <ulink url="https://tools.ietf.org/html/rfc5803">RFC 5803</ulink>.
+ </para>
+
+ <para>
+ A password that does not follow either of those formats is assumed to be
+ unencrypted.
+ </para>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-auth-members">
+ <title><structname>pg_auth_members</structname></title>
+
+ <indexterm zone="catalog-pg-auth-members">
+ <primary>pg_auth_members</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_auth_members</structname> shows the membership
+ relations between roles. Any non-circular set of relationships is allowed.
+ </para>
+
+ <para>
+ Because user identities are cluster-wide,
+ <structname>pg_auth_members</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_auth_members</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_auth_members</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>roleid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ ID of a role that has a member
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>member</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ ID of a role that is a member of <structfield>roleid</structfield>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ ID of the role that granted this membership
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>admin_option</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if <structfield>member</structfield> can grant membership in
+ <structfield>roleid</structfield> to others
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-cast">
+ <title><structname>pg_cast</structname></title>
+
+ <indexterm zone="catalog-pg-cast">
+ <primary>pg_cast</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_cast</structname> stores data type conversion
+ paths, both built-in and user-defined.
+ </para>
+
+ <para>
+ It should be noted that <structname>pg_cast</structname> does not represent
+ every type conversion that the system knows how to perform; only those that
+ cannot be deduced from some generic rule. For example, casting between a
+ domain and its base type is not explicitly represented in
+ <structname>pg_cast</structname>. Another important exception is that
+ <quote>automatic I/O conversion casts</quote>, those performed using a data
+ type's own I/O functions to convert to or from <type>text</type> or other
+ string types, are not explicitly represented in
+ <structname>pg_cast</structname>.
+ </para>
+
+ <table>
+ <title><structname>pg_cast</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>castsource</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the source data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>casttarget</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the target data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>castfunc</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the function to use to perform this cast. Zero is
+ stored if the cast method doesn't require a function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>castcontext</structfield> <type>char</type>
+ </para>
+ <para>
+ Indicates what contexts the cast can be invoked in.
+ <literal>e</literal> means only as an explicit cast (using
+ <literal>CAST</literal> or <literal>::</literal> syntax).
+ <literal>a</literal> means implicitly in assignment
+ to a target column, as well as explicitly.
+ <literal>i</literal> means implicitly in expressions, as well as the
+ other cases.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>castmethod</structfield> <type>char</type>
+ </para>
+ <para>
+ Indicates how the cast is performed.
+ <literal>f</literal> means that the function specified in the <structfield>castfunc</structfield> field is used.
+ <literal>i</literal> means that the input/output functions are used.
+ <literal>b</literal> means that the types are binary-coercible, thus no conversion is required.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The cast functions listed in <structname>pg_cast</structname> must
+ always take the cast source type as their first argument type, and
+ return the cast destination type as their result type. A cast
+ function can have up to three arguments. The second argument,
+ if present, must be type <type>integer</type>; it receives the type
+ modifier associated with the destination type, or -1
+ if there is none. The third argument,
+ if present, must be type <type>boolean</type>; it receives <literal>true</literal>
+ if the cast is an explicit cast, <literal>false</literal> otherwise.
+ </para>
+
+ <para>
+ It is legitimate to create a <structname>pg_cast</structname> entry
+ in which the source and target types are the same, if the associated
+ function takes more than one argument. Such entries represent
+ <quote>length coercion functions</quote> that coerce values of the type
+ to be legal for a particular type modifier value.
+ </para>
+
+ <para>
+ When a <structname>pg_cast</structname> entry has different source and
+ target types and a function that takes more than one argument, it
+ represents converting from one type to another and applying a length
+ coercion in a single step. When no such entry is available, coercion
+ to a type that uses a type modifier involves two steps, one to
+ convert between data types and a second to apply the modifier.
+ </para>
+ </sect1>
+
+ <sect1 id="catalog-pg-class">
+ <title><structname>pg_class</structname></title>
+
+ <indexterm zone="catalog-pg-class">
+ <primary>pg_class</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_class</structname> catalogs tables and most
+ everything else that has columns or is otherwise similar to a
+ table. This includes indexes (but see also <link
+ linkend="catalog-pg-index"><structname>pg_index</structname></link>),
+ sequences (but see also <link
+ linkend="catalog-pg-sequence"><structname>pg_sequence</structname></link>),
+ views, materialized views, composite types, and TOAST tables;
+ see <structfield>relkind</structfield>.
+ Below, when we mean all of these kinds of objects we speak of
+ <quote>relations</quote>. Not all columns are meaningful for all relation
+ types.
+ </para>
+
+ <table>
+ <title><structname>pg_class</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the table, index, view, etc.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reltype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the data type that corresponds to this table's row type,
+ if any; zero for indexes, sequences, and toast tables, which have
+ no <structname>pg_type</structname> entry
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reloftype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For typed tables, the OID of the underlying composite type;
+ zero for all other relations
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relam</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-am"><structname>pg_am</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If this is a table or an index, the access method used (heap,
+ B-tree, hash, etc.); otherwise zero (zero occurs for sequences,
+ as well as relations without storage, such as views)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relfilenode</structfield> <type>oid</type>
+ </para>
+ <para>
+ Name of the on-disk file of this relation; zero means this
+ is a <quote>mapped</quote> relation whose disk file name is determined
+ by low-level state
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reltablespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The tablespace in which this relation is stored. If zero,
+ the database's default tablespace is implied. (Not meaningful
+ if the relation has no on-disk file.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relpages</structfield> <type>int4</type>
+ </para>
+ <para>
+ Size of the on-disk representation of this table in pages (of size
+ <symbol>BLCKSZ</symbol>). This is only an estimate used by the
+ planner. It is updated by <link linkend="sql-vacuum"><command>VACUUM</command></link>,
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>, and a few DDL commands such as
+ <link linkend="sql-createindex"><command>CREATE INDEX</command></link>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reltuples</structfield> <type>float4</type>
+ </para>
+ <para>
+ Number of live rows in the table. This is only an estimate used by
+ the planner. It is updated by <link linkend="sql-vacuum"><command>VACUUM</command></link>,
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>, and a few DDL commands such as
+ <link linkend="sql-createindex"><command>CREATE INDEX</command></link>.
+ If the table has never yet been vacuumed or
+ analyzed, <structfield>reltuples</structfield>
+ contains <literal>-1</literal> indicating that the row count is
+ unknown.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relallvisible</structfield> <type>int4</type>
+ </para>
+ <para>
+ Number of pages that are marked all-visible in the table's
+ visibility map. This is only an estimate used by the
+ planner. It is updated by <link linkend="sql-vacuum"><command>VACUUM</command></link>,
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>, and a few DDL commands such as
+ <link linkend="sql-createindex"><command>CREATE INDEX</command></link>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reltoastrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the TOAST table associated with this table, zero if none. The
+ TOAST table stores large attributes <quote>out of line</quote> in a
+ secondary table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relhasindex</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this is a table and it has (or recently had) any indexes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relisshared</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this table is shared across all databases in the cluster. Only
+ certain system catalogs (such as <link linkend="catalog-pg-database"><structname>pg_database</structname></link>)
+ are shared.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relpersistence</structfield> <type>char</type>
+ </para>
+ <para>
+ <literal>p</literal> = permanent table/sequence, <literal>u</literal> = unlogged table/sequence,
+ <literal>t</literal> = temporary table/sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relkind</structfield> <type>char</type>
+ </para>
+ <para>
+ <literal>r</literal> = ordinary table,
+ <literal>i</literal> = index,
+ <literal>S</literal> = sequence,
+ <literal>t</literal> = TOAST table,
+ <literal>v</literal> = view,
+ <literal>m</literal> = materialized view,
+ <literal>c</literal> = composite type,
+ <literal>f</literal> = foreign table,
+ <literal>p</literal> = partitioned table,
+ <literal>I</literal> = partitioned index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relnatts</structfield> <type>int2</type>
+ </para>
+ <para>
+ Number of user columns in the relation (system columns not
+ counted). There must be this many corresponding entries in
+ <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>. See also
+ <structname>pg_attribute</structname>.<structfield>attnum</structfield>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relchecks</structfield> <type>int2</type>
+ </para>
+ <para>
+ Number of <literal>CHECK</literal> constraints on the table; see
+ <link linkend="catalog-pg-constraint"><structname>pg_constraint</structname></link> catalog
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relhasrules</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if table has (or once had) rules; see
+ <link linkend="catalog-pg-rewrite"><structname>pg_rewrite</structname></link> catalog
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relhastriggers</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if table has (or once had) triggers; see
+ <link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link> catalog
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relhassubclass</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if table or index has (or once had) any inheritance children or partitions
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relrowsecurity</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if table has row-level security enabled; see
+ <link linkend="catalog-pg-policy"><structname>pg_policy</structname></link> catalog
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relforcerowsecurity</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if row-level security (when enabled) will also apply to table owner; see
+ <link linkend="catalog-pg-policy"><structname>pg_policy</structname></link> catalog
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relispopulated</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if relation is populated (this is true for all
+ relations other than some materialized views)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relreplident</structfield> <type>char</type>
+ </para>
+ <para>
+ Columns used to form <quote>replica identity</quote> for rows:
+ <literal>d</literal> = default (primary key, if any),
+ <literal>n</literal> = nothing,
+ <literal>f</literal> = all columns,
+ <literal>i</literal> = index with
+ <structfield>indisreplident</structfield> set (same as nothing if the
+ index used has been dropped)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relispartition</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if table or index is a partition
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relrewrite</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For new relations being written during a DDL operation that requires a
+ table rewrite, this contains the OID of the original relation;
+ otherwise zero. That state is only visible internally; this field should
+ never contain anything other than zero for a user-visible relation.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relfrozenxid</structfield> <type>xid</type>
+ </para>
+ <para>
+ All transaction IDs before this one have been replaced with a permanent
+ (<quote>frozen</quote>) transaction ID in this table. This is used to track
+ whether the table needs to be vacuumed in order to prevent transaction
+ ID wraparound or to allow <literal>pg_xact</literal> to be shrunk. Zero
+ (<symbol>InvalidTransactionId</symbol>) if the relation is not a table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relminmxid</structfield> <type>xid</type>
+ </para>
+ <para>
+ All multixact IDs before this one have been replaced by a
+ transaction ID in this table. This is used to track
+ whether the table needs to be vacuumed in order to prevent multixact ID
+ wraparound or to allow <literal>pg_multixact</literal> to be shrunk. Zero
+ (<symbol>InvalidMultiXactId</symbol>) if the relation is not a table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reloptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Access-method-specific options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relpartbound</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ If table is a partition (see <structfield>relispartition</structfield>),
+ internal representation of the partition bound
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Several of the Boolean flags in <structname>pg_class</structname> are maintained
+ lazily: they are guaranteed to be true if that's the correct state, but
+ may not be reset to false immediately when the condition is no longer
+ true. For example, <structfield>relhasindex</structfield> is set by
+ <link linkend="sql-createindex"><command>CREATE INDEX</command></link>, but it is never cleared by
+ <link linkend="sql-dropindex"><command>DROP INDEX</command></link>. Instead, <link linkend="sql-vacuum"><command>VACUUM</command></link> clears
+ <structfield>relhasindex</structfield> if it finds the table has no indexes. This
+ arrangement avoids race conditions and improves concurrency.
+ </para>
+ </sect1>
+
+ <sect1 id="catalog-pg-collation">
+ <title><structname>pg_collation</structname></title>
+
+ <indexterm zone="catalog-pg-collation">
+ <primary>pg_collation</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_collation</structname> describes the
+ available collations, which are essentially mappings from an SQL
+ name to operating system locale categories.
+ See <xref linkend="collation"/> for more information.
+ </para>
+
+ <table>
+ <title><structname>pg_collation</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collname</structfield> <type>name</type>
+ </para>
+ <para>
+ Collation name (unique per namespace and encoding)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collprovider</structfield> <type>char</type>
+ </para>
+ <para>
+ Provider of the collation: <literal>d</literal> = database
+ default, <literal>c</literal> = libc, <literal>i</literal> = icu
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collisdeterministic</structfield> <type>bool</type>
+ </para>
+ <para>
+ Is the collation deterministic?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collencoding</structfield> <type>int4</type>
+ </para>
+ <para>
+ Encoding in which the collation is applicable, or -1 if it
+ works for any encoding
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collcollate</structfield> <type>text</type>
+ </para>
+ <para>
+ <symbol>LC_COLLATE</symbol> for this collation object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collctype</structfield> <type>text</type>
+ </para>
+ <para>
+ <symbol>LC_CTYPE</symbol> for this collation object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>colliculocale</structfield> <type>text</type>
+ </para>
+ <para>
+ ICU locale ID for this collation object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collversion</structfield> <type>text</type>
+ </para>
+ <para>
+ Provider-specific version of the collation. This is recorded when the
+ collation is created and then checked when it is used, to detect
+ changes in the collation definition that could lead to data corruption.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Note that the unique key on this catalog is (<structfield>collname</structfield>,
+ <structfield>collencoding</structfield>, <structfield>collnamespace</structfield>) not just
+ (<structfield>collname</structfield>, <structfield>collnamespace</structfield>).
+ <productname>PostgreSQL</productname> generally ignores all
+ collations that do not have <structfield>collencoding</structfield> equal to
+ either the current database's encoding or -1, and creation of new entries
+ with the same name as an entry with <structfield>collencoding</structfield> = -1
+ is forbidden. Therefore it is sufficient to use a qualified SQL name
+ (<replaceable>schema</replaceable>.<replaceable>name</replaceable>) to identify a collation,
+ even though this is not unique according to the catalog definition.
+ The reason for defining the catalog this way is that
+ <application>initdb</application> fills it in at cluster initialization time with
+ entries for all locales available on the system, so it must be able to
+ hold entries for all encodings that might ever be used in the cluster.
+ </para>
+
+ <para>
+ In the <literal>template0</literal> database, it could be useful to create
+ collations whose encoding does not match the database encoding,
+ since they could match the encodings of databases later cloned from
+ <literal>template0</literal>. This would currently have to be done manually.
+ </para>
+ </sect1>
+
+ <sect1 id="catalog-pg-constraint">
+ <title><structname>pg_constraint</structname></title>
+
+ <indexterm zone="catalog-pg-constraint">
+ <primary>pg_constraint</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_constraint</structname> stores check, primary
+ key, unique, foreign key, and exclusion constraints on tables.
+ (Column constraints are not treated specially. Every column constraint is
+ equivalent to some table constraint.)
+ Not-null constraints are represented in the
+ <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>
+ catalog, not here.
+ </para>
+
+ <para>
+ User-defined constraint triggers (created with <link linkend="sql-createtrigger">
+ <command>CREATE CONSTRAINT TRIGGER</command></link>) also give rise to an entry in this table.
+ </para>
+
+ <para>
+ Check constraints on domains are stored here, too.
+ </para>
+
+ <table>
+ <title><structname>pg_constraint</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conname</structfield> <type>name</type>
+ </para>
+ <para>
+ Constraint name (not necessarily unique!)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>connamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>contype</structfield> <type>char</type>
+ </para>
+ <para>
+ <literal>c</literal> = check constraint,
+ <literal>f</literal> = foreign key constraint,
+ <literal>p</literal> = primary key constraint,
+ <literal>u</literal> = unique constraint,
+ <literal>t</literal> = constraint trigger,
+ <literal>x</literal> = exclusion constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>condeferrable</structfield> <type>bool</type>
+ </para>
+ <para>
+ Is the constraint deferrable?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>condeferred</structfield> <type>bool</type>
+ </para>
+ <para>
+ Is the constraint deferred by default?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>convalidated</structfield> <type>bool</type>
+ </para>
+ <para>
+ Has the constraint been validated?
+ Currently, can be false only for foreign keys and CHECK constraints
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table this constraint is on; zero if not a table constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>contypid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The domain this constraint is on; zero if not a domain constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conindid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The index supporting this constraint, if it's a unique, primary
+ key, foreign key, or exclusion constraint; else zero
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conparentid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-constraint"><structname>pg_constraint</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The corresponding constraint of the parent partitioned table,
+ if this is a constraint on a partition; else zero
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If a foreign key, the referenced table; else zero
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confupdtype</structfield> <type>char</type>
+ </para>
+ <para>
+ Foreign key update action code:
+ <literal>a</literal> = no action,
+ <literal>r</literal> = restrict,
+ <literal>c</literal> = cascade,
+ <literal>n</literal> = set null,
+ <literal>d</literal> = set default
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confdeltype</structfield> <type>char</type>
+ </para>
+ <para>
+ Foreign key deletion action code:
+ <literal>a</literal> = no action,
+ <literal>r</literal> = restrict,
+ <literal>c</literal> = cascade,
+ <literal>n</literal> = set null,
+ <literal>d</literal> = set default
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confmatchtype</structfield> <type>char</type>
+ </para>
+ <para>
+ Foreign key match type:
+ <literal>f</literal> = full,
+ <literal>p</literal> = partial,
+ <literal>s</literal> = simple
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conislocal</structfield> <type>bool</type>
+ </para>
+ <para>
+ This constraint is defined locally for the relation. Note that a
+ constraint can be locally defined and inherited simultaneously.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>coninhcount</structfield> <type>int4</type>
+ </para>
+ <para>
+ The number of direct inheritance ancestors this constraint has.
+ A constraint with
+ a nonzero number of ancestors cannot be dropped nor renamed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>connoinherit</structfield> <type>bool</type>
+ </para>
+ <para>
+ This constraint is defined locally for the relation. It is a
+ non-inheritable constraint.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conkey</structfield> <type>int2[]</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ If a table constraint (including foreign keys, but not constraint
+ triggers), list of the constrained columns
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confkey</structfield> <type>int2[]</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ If a foreign key, list of the referenced columns
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conpfeqop</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If a foreign key, list of the equality operators for PK = FK comparisons
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conppeqop</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If a foreign key, list of the equality operators for PK = PK comparisons
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conffeqop</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If a foreign key, list of the equality operators for FK = FK comparisons
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confdelsetcols</structfield> <type>int2[]</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ If a foreign key with a <literal>SET NULL</literal> or <literal>SET
+ DEFAULT</literal> delete action, the columns that will be updated.
+ If null, all of the referencing columns will be updated.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conexclop</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If an exclusion constraint, list of the per-column exclusion operators
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conbin</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ If a check constraint, an internal representation of the
+ expression. (It's recommended to use
+ <function>pg_get_constraintdef()</function> to extract the definition of
+ a check constraint.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In the case of an exclusion constraint, <structfield>conkey</structfield>
+ is only useful for constraint elements that are simple column references.
+ For other cases, a zero appears in <structfield>conkey</structfield>
+ and the associated index must be consulted to discover the expression
+ that is constrained. (<structfield>conkey</structfield> thus has the
+ same contents as <link linkend="catalog-pg-index"><structname>pg_index</structname></link>.<structfield>indkey</structfield> for the
+ index.)
+ </para>
+
+ <note>
+ <para>
+ <literal>pg_class.relchecks</literal> needs to agree with the
+ number of check-constraint entries found in this table for each
+ relation.
+ </para>
+ </note>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-conversion">
+ <title><structname>pg_conversion</structname></title>
+
+ <indexterm zone="catalog-pg-conversion">
+ <primary>pg_conversion</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_conversion</structname> describes
+ encoding conversion functions. See <xref linkend="sql-createconversion"/>
+ for more information.
+ </para>
+
+ <table>
+ <title><structname>pg_conversion</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conname</structfield> <type>name</type>
+ </para>
+ <para>
+ Conversion name (unique within a namespace)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>connamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this conversion
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the conversion
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conforencoding</structfield> <type>int4</type>
+ </para>
+ <para>
+ Source encoding ID (<link linkend="pg-encoding-to-char"><function>pg_encoding_to_char()</function></link>
+ can translate this number to the encoding name)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>contoencoding</structfield> <type>int4</type>
+ </para>
+ <para>
+ Destination encoding ID (<link linkend="pg-encoding-to-char"><function>pg_encoding_to_char()</function></link>
+ can translate this number to the encoding name)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conproc</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Conversion function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>condefault</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this is the default conversion
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-database">
+ <title><structname>pg_database</structname></title>
+
+ <indexterm zone="catalog-pg-database">
+ <primary>pg_database</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_database</structname> stores information about
+ the available databases. Databases are created with the <link
+ linkend="sql-createdatabase"><command>CREATE DATABASE</command></link> command.
+ Consult <xref linkend="managing-databases"/> for details about the meaning
+ of some of the parameters.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_database</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_database</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_database</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Database name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datdba</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the database, usually the user who created it
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>encoding</structfield> <type>int4</type>
+ </para>
+ <para>
+ Character encoding for this database
+ (<link linkend="pg-encoding-to-char"><function>pg_encoding_to_char()</function></link> can translate
+ this number to the encoding name)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datlocprovider</structfield> <type>char</type>
+ </para>
+ <para>
+ Locale provider for this database: <literal>c</literal> = libc,
+ <literal>i</literal> = icu
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datistemplate</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, then this database can be cloned by
+ any user with <literal>CREATEDB</literal> privileges;
+ if false, then only superusers or the owner of
+ the database can clone it.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datallowconn</structfield> <type>bool</type>
+ </para>
+ <para>
+ If false then no one can connect to this database. This is
+ used to protect the <literal>template0</literal> database from being altered.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datconnlimit</structfield> <type>int4</type>
+ </para>
+ <para>
+ Sets maximum number of concurrent connections that can be made
+ to this database. -1 means no limit, -2 indicates the database is
+ invalid.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datfrozenxid</structfield> <type>xid</type>
+ </para>
+ <para>
+ All transaction IDs before this one have been replaced with a permanent
+ (<quote>frozen</quote>) transaction ID in this database. This is used to
+ track whether the database needs to be vacuumed in order to prevent
+ transaction ID wraparound or to allow <literal>pg_xact</literal> to be shrunk.
+ It is the minimum of the per-table
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relfrozenxid</structfield> values.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datminmxid</structfield> <type>xid</type>
+ </para>
+ <para>
+ All multixact IDs before this one have been replaced with a
+ transaction ID in this database. This is used to
+ track whether the database needs to be vacuumed in order to prevent
+ multixact ID wraparound or to allow <literal>pg_multixact</literal> to be shrunk.
+ It is the minimum of the per-table
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relminmxid</structfield> values.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dattablespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The default tablespace for the database.
+ Within this database, all tables for which
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>reltablespace</structfield> is zero
+ will be stored in this tablespace; in particular, all the non-shared
+ system catalogs will be there.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datcollate</structfield> <type>text</type>
+ </para>
+ <para>
+ LC_COLLATE for this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datctype</structfield> <type>text</type>
+ </para>
+ <para>
+ LC_CTYPE for this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>daticulocale</structfield> <type>text</type>
+ </para>
+ <para>
+ ICU locale ID for this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datcollversion</structfield> <type>text</type>
+ </para>
+ <para>
+ Provider-specific version of the collation. This is recorded when the
+ database is created and then checked when it is used, to detect
+ changes in the collation definition that could lead to data corruption.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-db-role-setting">
+ <title><structname>pg_db_role_setting</structname></title>
+
+ <indexterm zone="catalog-pg-db-role-setting">
+ <primary>pg_db_role_setting</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_db_role_setting</structname> records the default
+ values that have been set for run-time configuration variables,
+ for each role and database combination.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_db_role_setting</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_db_role_setting</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_db_role_setting</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>setdatabase</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the database the setting is applicable to, or zero if not database-specific
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>setrole</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the role the setting is applicable to, or zero if not role-specific
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>setconfig</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Defaults for run-time configuration variables
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-default-acl">
+ <title><structname>pg_default_acl</structname></title>
+
+ <indexterm zone="catalog-pg-default-acl">
+ <primary>pg_default_acl</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_default_acl</structname> stores initial
+ privileges to be assigned to newly created objects.
+ </para>
+
+ <table>
+ <title><structname>pg_default_acl</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>defaclrole</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the role associated with this entry
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>defaclnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace associated with this entry,
+ or zero if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>defaclobjtype</structfield> <type>char</type>
+ </para>
+ <para>
+ Type of object this entry is for:
+ <literal>r</literal> = relation (table, view),
+ <literal>S</literal> = sequence,
+ <literal>f</literal> = function,
+ <literal>T</literal> = type,
+ <literal>n</literal> = schema
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>defaclacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges that this type of object should have on creation
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ A <structname>pg_default_acl</structname> entry shows the initial privileges to
+ be assigned to an object belonging to the indicated user. There are
+ currently two types of entry: <quote>global</quote> entries with
+ <structfield>defaclnamespace</structfield> = zero, and <quote>per-schema</quote> entries
+ that reference a particular schema. If a global entry is present then
+ it <emphasis>overrides</emphasis> the normal hard-wired default privileges
+ for the object type. A per-schema entry, if present, represents privileges
+ to be <emphasis>added to</emphasis> the global or hard-wired default privileges.
+ </para>
+
+ <para>
+ Note that when an ACL entry in another catalog is null, it is taken
+ to represent the hard-wired default privileges for its object,
+ <emphasis>not</emphasis> whatever might be in <structname>pg_default_acl</structname>
+ at the moment. <structname>pg_default_acl</structname> is only consulted during
+ object creation.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-depend">
+ <title><structname>pg_depend</structname></title>
+
+ <indexterm zone="catalog-pg-depend">
+ <primary>pg_depend</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_depend</structname> records the dependency
+ relationships between database objects. This information allows
+ <command>DROP</command> commands to find which other objects must be dropped
+ by <command>DROP CASCADE</command> or prevent dropping in the <command>DROP
+ RESTRICT</command> case.
+ </para>
+
+ <para>
+ See also <link linkend="catalog-pg-shdepend"><structname>pg_shdepend</structname></link>,
+ which performs a similar function for dependencies involving objects
+ that are shared across a database cluster.
+ </para>
+
+ <table>
+ <title><structname>pg_depend</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog the dependent object is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the specific dependent object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a table column, this is the column number (the
+ <structfield>objid</structfield> and <structfield>classid</structfield> refer to the
+ table itself). For all other object types, this column is
+ zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>refclassid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog the referenced object is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>refobjid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the specific referenced object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>refobjsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a table column, this is the column number (the
+ <structfield>refobjid</structfield> and <structfield>refclassid</structfield> refer
+ to the table itself). For all other object types, this column
+ is zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>deptype</structfield> <type>char</type>
+ </para>
+ <para>
+ A code defining the specific semantics of this dependency relationship; see text
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In all cases, a <structname>pg_depend</structname> entry indicates that the
+ referenced object cannot be dropped without also dropping the dependent
+ object. However, there are several subflavors identified by
+ <structfield>deptype</structfield>:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>DEPENDENCY_NORMAL</symbol> (<literal>n</literal>)</term>
+ <listitem>
+ <para>
+ A normal relationship between separately-created objects. The
+ dependent object can be dropped without affecting the
+ referenced object. The referenced object can only be dropped
+ by specifying <literal>CASCADE</literal>, in which case the dependent
+ object is dropped, too. Example: a table column has a normal
+ dependency on its data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>DEPENDENCY_AUTO</symbol> (<literal>a</literal>)</term>
+ <listitem>
+ <para>
+ The dependent object can be dropped separately from the
+ referenced object, and should be automatically dropped
+ (regardless of <literal>RESTRICT</literal> or <literal>CASCADE</literal>
+ mode) if the referenced object is dropped. Example: a named
+ constraint on a table is made auto-dependent on the table, so
+ that it will go away if the table is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>DEPENDENCY_INTERNAL</symbol> (<literal>i</literal>)</term>
+ <listitem>
+ <para>
+ The dependent object was created as part of creation of the
+ referenced object, and is really just a part of its internal
+ implementation. A direct <command>DROP</command> of the dependent
+ object will be disallowed outright (we'll tell the user to issue
+ a <command>DROP</command> against the referenced object, instead).
+ A <command>DROP</command> of the referenced object will result in
+ automatically dropping the dependent object
+ whether <literal>CASCADE</literal> is specified or not. If the
+ dependent object has to be dropped due to a dependency on some other
+ object being removed, its drop is converted to a drop of the referenced
+ object, so that <literal>NORMAL</literal> and <literal>AUTO</literal>
+ dependencies of the dependent object behave much like they were
+ dependencies of the referenced object.
+ Example: a view's <literal>ON SELECT</literal> rule is made
+ internally dependent on the view, preventing it from being dropped
+ while the view remains. Dependencies of the rule (such as tables it
+ refers to) act as if they were dependencies of the view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>DEPENDENCY_PARTITION_PRI</symbol> (<literal>P</literal>)</term>
+ <term><symbol>DEPENDENCY_PARTITION_SEC</symbol> (<literal>S</literal>)</term>
+ <listitem>
+ <para>
+ The dependent object was created as part of creation of the
+ referenced object, and is really just a part of its internal
+ implementation; however, unlike <literal>INTERNAL</literal>,
+ there is more than one such referenced object. The dependent object
+ must not be dropped unless at least one of these referenced objects
+ is dropped; if any one is, the dependent object should be dropped
+ whether or not <literal>CASCADE</literal> is specified. Also
+ unlike <literal>INTERNAL</literal>, a drop of some other object
+ that the dependent object depends on does not result in automatic
+ deletion of any partition-referenced object. Hence, if the drop
+ does not cascade to at least one of these objects via some other
+ path, it will be refused. (In most cases, the dependent object
+ shares all its non-partition dependencies with at least one
+ partition-referenced object, so that this restriction does not
+ result in blocking any cascaded delete.)
+ Primary and secondary partition dependencies behave identically
+ except that the primary dependency is preferred for use in error
+ messages; hence, a partition-dependent object should have one
+ primary partition dependency and one or more secondary partition
+ dependencies.
+ Note that partition dependencies are made in addition to, not
+ instead of, any dependencies the object would normally have. This
+ simplifies <command>ATTACH/DETACH PARTITION</command> operations:
+ the partition dependencies need only be added or removed.
+ Example: a child partitioned index is made partition-dependent
+ on both the partition table it is on and the parent partitioned
+ index, so that it goes away if either of those is dropped, but
+ not otherwise. The dependency on the parent index is primary,
+ so that if the user tries to drop the child partitioned index,
+ the error message will suggest dropping the parent index instead
+ (not the table).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>DEPENDENCY_EXTENSION</symbol> (<literal>e</literal>)</term>
+ <listitem>
+ <para>
+ The dependent object is a member of the <firstterm>extension</firstterm> that is
+ the referenced object (see
+ <link linkend="catalog-pg-extension"><structname>pg_extension</structname></link>).
+ The dependent object can be dropped only via
+ <link linkend="sql-dropextension"><command>DROP EXTENSION</command></link> on the referenced object.
+ Functionally this dependency type acts the same as
+ an <literal>INTERNAL</literal> dependency, but it's kept separate for
+ clarity and to simplify <application>pg_dump</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>DEPENDENCY_AUTO_EXTENSION</symbol> (<literal>x</literal>)</term>
+ <listitem>
+ <para>
+ The dependent object is not a member of the extension that is the
+ referenced object (and so it should not be ignored
+ by <application>pg_dump</application>), but it cannot function
+ without the extension and should be auto-dropped if the extension is.
+ The dependent object may be dropped on its own as well.
+ Functionally this dependency type acts the same as
+ an <literal>AUTO</literal> dependency, but it's kept separate for
+ clarity and to simplify <application>pg_dump</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Other dependency flavors might be needed in future.
+ </para>
+
+ <para>
+ Note that it's quite possible for two objects to be linked by more than
+ one <structname>pg_depend</structname> entry. For example, a child
+ partitioned index would have both a partition-type dependency on its
+ associated partition table, and an auto dependency on each column of
+ that table that it indexes. This sort of situation expresses the union
+ of multiple dependency semantics. A dependent object can be dropped
+ without <literal>CASCADE</literal> if any of its dependencies satisfies
+ its condition for automatic dropping. Conversely, all the
+ dependencies' restrictions about which objects must be dropped together
+ must be satisfied.
+ </para>
+
+ <para>
+ Most objects created during <application>initdb</application> are
+ considered <quote>pinned</quote>, which means that the system itself
+ depends on them. Therefore, they are never allowed to be dropped.
+ Also, knowing that pinned objects will not be dropped, the dependency
+ mechanism doesn't bother to make <structname>pg_depend</structname>
+ entries showing dependencies on them. Thus, for example, a table
+ column of type <type>numeric</type> notionally has
+ a <literal>NORMAL</literal> dependency on the <type>numeric</type>
+ data type, but no such entry actually appears
+ in <structname>pg_depend</structname>.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-description">
+ <title><structname>pg_description</structname></title>
+
+ <indexterm zone="catalog-pg-description">
+ <primary>pg_description</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_description</structname> stores optional descriptions
+ (comments) for each database object. Descriptions can be manipulated
+ with the <link linkend="sql-comment"><command>COMMENT</command></link> command and viewed with
+ <application>psql</application>'s <literal>\d</literal> commands.
+ Descriptions of many built-in system objects are provided in the initial
+ contents of <structname>pg_description</structname>.
+ </para>
+
+ <para>
+ See also <link linkend="catalog-pg-shdescription"><structname>pg_shdescription</structname></link>,
+ which performs a similar function for descriptions involving objects that
+ are shared across a database cluster.
+ </para>
+
+ <table>
+ <title><structname>pg_description</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objoid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the object this description pertains to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog this object appears in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a comment on a table column, this is the column number (the
+ <structfield>objoid</structfield> and <structfield>classoid</structfield> refer to
+ the table itself). For all other object types, this column is
+ zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>description</structfield> <type>text</type>
+ </para>
+ <para>
+ Arbitrary text that serves as the description of this object
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-enum">
+ <title><structname>pg_enum</structname></title>
+
+ <indexterm zone="catalog-pg-enum">
+ <primary>pg_enum</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_enum</structname> catalog contains entries
+ showing the values and labels for each enum type. The
+ internal representation of a given enum value is actually the OID
+ of its associated row in <structname>pg_enum</structname>.
+ </para>
+
+ <table>
+ <title><structname>pg_enum</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>enumtypid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-type"><structname>pg_type</structname></link> entry owning this enum value
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>enumsortorder</structfield> <type>float4</type>
+ </para>
+ <para>
+ The sort position of this enum value within its enum type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>enumlabel</structfield> <type>name</type>
+ </para>
+ <para>
+ The textual label for this enum value
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The OIDs for <structname>pg_enum</structname> rows follow a special
+ rule: even-numbered OIDs are guaranteed to be ordered in the same way
+ as the sort ordering of their enum type. That is, if two even OIDs
+ belong to the same enum type, the smaller OID must have the smaller
+ <structfield>enumsortorder</structfield> value. Odd-numbered OID values
+ need bear no relationship to the sort order. This rule allows the
+ enum comparison routines to avoid catalog lookups in many common cases.
+ The routines that create and alter enum types attempt to assign even
+ OIDs to enum values whenever possible.
+ </para>
+
+ <para>
+ When an enum type is created, its members are assigned sort-order
+ positions 1..<replaceable>n</replaceable>. But members added later might be given
+ negative or fractional values of <structfield>enumsortorder</structfield>.
+ The only requirement on these values is that they be correctly
+ ordered and unique within each enum type.
+ </para>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-event-trigger">
+ <title><structname>pg_event_trigger</structname></title>
+
+ <indexterm zone="catalog-pg-event-trigger">
+ <primary>pg_event_trigger</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_event_trigger</structname> stores event triggers.
+ See <xref linkend="event-triggers"/> for more information.
+ </para>
+
+ <table>
+ <title><structname>pg_event_trigger</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>evtname</structfield> <type>name</type>
+ </para>
+ <para>
+ Trigger name (must be unique)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>evtevent</structfield> <type>name</type>
+ </para>
+ <para>
+ Identifies the event for which this trigger fires
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>evtowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the event trigger
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>evtfoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The function to be called
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>evtenabled</structfield> <type>char</type>
+ </para>
+ <para>
+ Controls in which <xref linkend="guc-session-replication-role"/> modes
+ the event trigger fires.
+ <literal>O</literal> = trigger fires in <quote>origin</quote> and <quote>local</quote> modes,
+ <literal>D</literal> = trigger is disabled,
+ <literal>R</literal> = trigger fires in <quote>replica</quote> mode,
+ <literal>A</literal> = trigger fires always.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>evttags</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Command tags for which this trigger will fire. If NULL, the firing
+ of this trigger is not restricted on the basis of the command tag.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-extension">
+ <title><structname>pg_extension</structname></title>
+
+ <indexterm zone="catalog-pg-extension">
+ <primary>pg_extension</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_extension</structname> stores information
+ about the installed extensions. See <xref linkend="extend-extensions"/>
+ for details about extensions.
+ </para>
+
+ <table>
+ <title><structname>pg_extension</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the extension
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the extension
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Schema containing the extension's exported objects
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extrelocatable</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if extension can be relocated to another schema
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extversion</structfield> <type>text</type>
+ </para>
+ <para>
+ Version name for the extension
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extconfig</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Array of <type>regclass</type> OIDs for the extension's configuration
+ table(s), or <literal>NULL</literal> if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extcondition</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Array of <literal>WHERE</literal>-clause filter conditions for the
+ extension's configuration table(s), or <literal>NULL</literal> if none
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Note that unlike most catalogs with a <quote>namespace</quote> column,
+ <structfield>extnamespace</structfield> is not meant to imply
+ that the extension belongs to that schema. Extension names are never
+ schema-qualified. Rather, <structfield>extnamespace</structfield>
+ indicates the schema that contains most or all of the extension's
+ objects. If <structfield>extrelocatable</structfield> is true, then
+ this schema must in fact contain all schema-qualifiable objects
+ belonging to the extension.
+ </para>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-foreign-data-wrapper">
+ <title><structname>pg_foreign_data_wrapper</structname></title>
+
+ <indexterm zone="catalog-pg-foreign-data-wrapper">
+ <primary>pg_foreign_data_wrapper</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_foreign_data_wrapper</structname> stores
+ foreign-data wrapper definitions. A foreign-data wrapper is the
+ mechanism by which external data, residing on foreign servers, is
+ accessed.
+ </para>
+
+ <table>
+ <title><structname>pg_foreign_data_wrapper</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fdwname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the foreign-data wrapper
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fdwowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the foreign-data wrapper
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fdwhandler</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ References a handler function that is responsible for
+ supplying execution routines for the foreign-data wrapper.
+ Zero if no handler is provided
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fdwvalidator</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ References a validator function that is responsible for
+ checking the validity of the options given to the
+ foreign-data wrapper, as well as options for foreign servers and user
+ mappings using the foreign-data wrapper. Zero if no validator
+ is provided
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fdwacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fdwoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Foreign-data wrapper specific options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-foreign-server">
+ <title><structname>pg_foreign_server</structname></title>
+
+ <indexterm zone="catalog-pg-foreign-server">
+ <primary>pg_foreign_server</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_foreign_server</structname> stores
+ foreign server definitions. A foreign server describes a source
+ of external data, such as a remote server. Foreign
+ servers are accessed via foreign-data wrappers.
+ </para>
+
+ <table>
+ <title><structname>pg_foreign_server</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvfdw</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-foreign-data-wrapper"><structname>pg_foreign_data_wrapper</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the foreign-data wrapper of this foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvtype</structfield> <type>text</type>
+ </para>
+ <para>
+ Type of the server (optional)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvversion</structfield> <type>text</type>
+ </para>
+ <para>
+ Version of the server (optional)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Foreign server specific options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-foreign-table">
+ <title><structname>pg_foreign_table</structname></title>
+
+ <indexterm zone="catalog-pg-foreign-table">
+ <primary>pg_foreign_table</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_foreign_table</structname> contains
+ auxiliary information about foreign tables. A foreign table is
+ primarily represented by a
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>
+ entry, just like a regular table. Its <structname>pg_foreign_table</structname>
+ entry contains the information that is pertinent only to foreign tables
+ and not any other kind of relation.
+ </para>
+
+ <table>
+ <title><structname>pg_foreign_table</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ftrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry for this foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ftserver</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-foreign-server"><structname>pg_foreign_server</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the foreign server for this foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ftoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Foreign table options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-index">
+ <title><structname>pg_index</structname></title>
+
+ <indexterm zone="catalog-pg-index">
+ <primary>pg_index</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_index</structname> contains part of the information
+ about indexes. The rest is mostly in
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_index</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry for this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry for the table this index is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indnatts</structfield> <type>int2</type>
+ </para>
+ <para>
+ The total number of columns in the index (duplicates
+ <literal>pg_class.relnatts</literal>); this number includes both key and included attributes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indnkeyatts</structfield> <type>int2</type>
+ </para>
+ <para>
+ The number of <firstterm>key columns</firstterm> in the index,
+ not counting any <firstterm>included columns</firstterm>, which are
+ merely stored and do not participate in the index semantics
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisunique</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, this is a unique index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indnullsnotdistinct</structfield> <type>bool</type>
+ </para>
+ <para>
+ This value is only used for unique indexes. If false, this unique
+ index will consider null values distinct (so the index can contain
+ multiple null values in a column, the default PostgreSQL behavior). If
+ it is true, it will consider null values to be equal (so the index can
+ only contain one null value in a column).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisprimary</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, this index represents the primary key of the table
+ (<structfield>indisunique</structfield> should always be true when this is true)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisexclusion</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, this index supports an exclusion constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indimmediate</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the uniqueness check is enforced immediately on
+ insertion
+ (irrelevant if <structfield>indisunique</structfield> is not true)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisclustered</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the table was last clustered on this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisvalid</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the index is currently valid for queries. False means the
+ index is possibly incomplete: it must still be modified by
+ <link linkend="sql-insert"><command>INSERT</command></link>/<link linkend="sql-update"><command>UPDATE</command></link> operations, but it cannot safely
+ be used for queries. If it is unique, the uniqueness property is not
+ guaranteed true either.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indcheckxmin</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, queries must not use the index until the <structfield>xmin</structfield>
+ of this <structname>pg_index</structname> row is below their <symbol>TransactionXmin</symbol>
+ event horizon, because the table may contain broken <link linkend="storage-hot">HOT chains</link> with
+ incompatible rows that they can see
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisready</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the index is currently ready for inserts. False means the
+ index must be ignored by <link linkend="sql-insert"><command>INSERT</command></link>/<link linkend="sql-update"><command>UPDATE</command></link>
+ operations.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indislive</structfield> <type>bool</type>
+ </para>
+ <para>
+ If false, the index is in process of being dropped, and should be
+ ignored for all purposes (including HOT-safety decisions)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indisreplident</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true this index has been chosen as <quote>replica identity</quote>
+ using <link linkend="sql-altertable-replica-identity"><command>ALTER TABLE ...
+ REPLICA IDENTITY USING INDEX ...</command></link>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indkey</structfield> <type>int2vector</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ This is an array of <structfield>indnatts</structfield> values that
+ indicate which table columns this index indexes. For example, a value
+ of <literal>1 3</literal> would mean that the first and the third table
+ columns make up the index entries. Key columns come before non-key
+ (included) columns. A zero in this array indicates that the
+ corresponding index attribute is an expression over the table columns,
+ rather than a simple column reference.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indcollation</structfield> <type>oidvector</type>
+ (references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For each column in the index key
+ (<structfield>indnkeyatts</structfield> values), this contains the OID
+ of the collation to use for the index, or zero if the column is not of
+ a collatable data type.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indclass</structfield> <type>oidvector</type>
+ (references <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For each column in the index key
+ (<structfield>indnkeyatts</structfield> values), this contains the OID
+ of the operator class to use. See
+ <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link> for details.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indoption</structfield> <type>int2vector</type>
+ </para>
+ <para>
+ This is an array of <structfield>indnkeyatts</structfield> values that
+ store per-column flag bits. The meaning of the bits is defined by
+ the index's access method.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexprs</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression trees (in <function>nodeToString()</function>
+ representation) for index attributes that are not simple column
+ references. This is a list with one element for each zero
+ entry in <structfield>indkey</structfield>. Null if all index attributes
+ are simple references.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indpred</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression tree (in <function>nodeToString()</function>
+ representation) for partial index predicate. Null if not a
+ partial index.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-inherits">
+ <title><structname>pg_inherits</structname></title>
+
+ <indexterm zone="catalog-pg-inherits">
+ <primary>pg_inherits</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_inherits</structname> records information about
+ table and index inheritance hierarchies. There is one entry for each direct
+ parent-child table or index relationship in the database. (Indirect
+ inheritance can be determined by following chains of entries.)
+ </para>
+
+ <table>
+ <title><structname>pg_inherits</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inhrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the child table or index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inhparent</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the parent table or index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inhseqno</structfield> <type>int4</type>
+ </para>
+ <para>
+ If there is more than one direct parent for a child table (multiple
+ inheritance), this number tells the order in which the
+ inherited columns are to be arranged. The count starts at 1.
+ </para>
+ <para>
+ Indexes cannot have multiple inheritance, since they can only inherit
+ when using declarative partitioning.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inhdetachpending</structfield> <type>bool</type>
+ </para>
+ <para>
+ <literal>true</literal> for a partition that is in the process of
+ being detached; <literal>false</literal> otherwise.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-init-privs">
+ <title><structname>pg_init_privs</structname></title>
+
+ <indexterm zone="catalog-pg-init-privs">
+ <primary>pg_init_privs</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_init_privs</structname> records information about
+ the initial privileges of objects in the system. There is one entry
+ for each object in the database which has a non-default (non-NULL)
+ initial set of privileges.
+ </para>
+
+ <para>
+ Objects can have initial privileges either by having those privileges set
+ when the system is initialized (by <application>initdb</application>) or when the
+ object is created during a <link linkend="sql-createextension"><command>CREATE EXTENSION</command></link> and the
+ extension script sets initial privileges using the <link linkend="sql-grant"><command>GRANT</command></link>
+ system. Note that the system will automatically handle recording of the
+ privileges during the extension script and that extension authors need
+ only use the <command>GRANT</command> and <command>REVOKE</command>
+ statements in their script to have the privileges recorded. The
+ <literal>privtype</literal> column indicates if the initial privilege was
+ set by <application>initdb</application> or during a
+ <command>CREATE EXTENSION</command> command.
+ </para>
+
+ <para>
+ Objects which have initial privileges set by <application>initdb</application> will
+ have entries where <literal>privtype</literal> is
+ <literal>'i'</literal>, while objects which have initial privileges set
+ by <command>CREATE EXTENSION</command> will have entries where
+ <literal>privtype</literal> is <literal>'e'</literal>.
+ </para>
+
+ <table>
+ <title><structname>pg_init_privs</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objoid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the specific object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog the object is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a table column, this is the column number (the
+ <structfield>objoid</structfield> and <structfield>classoid</structfield> refer to the
+ table itself). For all other object types, this column is
+ zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privtype</structfield> <type>char</type>
+ </para>
+ <para>
+ A code defining the type of initial privilege of this object; see text
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>initprivs</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ The initial access privileges; see
+ <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-language">
+ <title><structname>pg_language</structname></title>
+
+ <indexterm zone="catalog-pg-language">
+ <primary>pg_language</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_language</structname> registers
+ languages in which you can write functions or stored procedures.
+ See <xref linkend="sql-createlanguage"/>
+ and <xref linkend="xplang"/> for more information about language handlers.
+ </para>
+
+ <table>
+ <title><structname>pg_language</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the language
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the language
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanispl</structfield> <type>bool</type>
+ </para>
+ <para>
+ This is false for internal languages (such as
+ <acronym>SQL</acronym>) and true for user-defined languages.
+ Currently, <application>pg_dump</application> still uses this
+ to determine which languages need to be dumped, but this might be
+ replaced by a different mechanism in the future.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanpltrusted</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this is a trusted language, which means that it is believed
+ not to grant access to anything outside the normal SQL execution
+ environment. Only superusers can create functions in untrusted
+ languages.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanplcallfoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For noninternal languages this references the language
+ handler, which is a special function that is responsible for
+ executing all functions that are written in the particular
+ language. Zero for internal languages.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>laninline</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ This references a function that is responsible for executing
+ <quote>inline</quote> anonymous code blocks
+ (<xref linkend="sql-do"/> blocks).
+ Zero if inline blocks are not supported.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanvalidator</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ This references a language validator function that is responsible
+ for checking the syntax and validity of new functions when they
+ are created. Zero if no validator is provided.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lanacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-largeobject">
+ <title><structname>pg_largeobject</structname></title>
+
+ <indexterm zone="catalog-pg-largeobject">
+ <primary>pg_largeobject</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_largeobject</structname> holds the data making up
+ <quote>large objects</quote>. A large object is identified by an OID
+ assigned when it is created. Each large object is broken into
+ segments or <quote>pages</quote> small enough to be conveniently stored as rows
+ in <structname>pg_largeobject</structname>.
+ The amount of data per page is defined to be <symbol>LOBLKSIZE</symbol> (which is currently
+ <literal>BLCKSZ/4</literal>, or typically 2 kB).
+ </para>
+
+ <para>
+ Prior to <productname>PostgreSQL</productname> 9.0, there was no permission structure
+ associated with large objects. As a result,
+ <structname>pg_largeobject</structname> was publicly readable and could be
+ used to obtain the OIDs (and contents) of all large objects in the system.
+ This is no longer the case; use
+ <link linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</structname></link>
+ to obtain a list of large object OIDs.
+ </para>
+
+ <table>
+ <title><structname>pg_largeobject</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>loid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Identifier of the large object that includes this page
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pageno</structfield> <type>int4</type>
+ </para>
+ <para>
+ Page number of this page within its large object
+ (counting from zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data</structfield> <type>bytea</type>
+ </para>
+ <para>
+ Actual data stored in the large object.
+ This will never be more than <symbol>LOBLKSIZE</symbol> bytes and might be less.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Each row of <structname>pg_largeobject</structname> holds data
+ for one page of a large object, beginning at
+ byte offset (<literal>pageno * LOBLKSIZE</literal>) within the object. The implementation
+ allows sparse storage: pages might be missing, and might be shorter than
+ <literal>LOBLKSIZE</literal> bytes even if they are not the last page of the object.
+ Missing regions within a large object read as zeroes.
+ </para>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-largeobject-metadata">
+ <title><structname>pg_largeobject_metadata</structname></title>
+
+ <indexterm zone="catalog-pg-largeobject-metadata">
+ <primary>pg_largeobject_metadata</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_largeobject_metadata</structname>
+ holds metadata associated with large objects. The actual large object
+ data is stored in
+ <link linkend="catalog-pg-largeobject"><structname>pg_largeobject</structname></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_largeobject_metadata</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lomowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the large object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lomacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-namespace">
+ <title><structname>pg_namespace</structname></title>
+
+ <indexterm zone="catalog-pg-namespace">
+ <primary>pg_namespace</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_namespace</structname> stores namespaces.
+ A namespace is the structure underlying SQL schemas: each namespace
+ can have a separate collection of relations, types, etc. without name
+ conflicts.
+ </para>
+
+ <table>
+ <title><structname>pg_namespace</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>nspname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the namespace
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>nspowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the namespace
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>nspacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-opclass">
+ <title><structname>pg_opclass</structname></title>
+
+ <indexterm zone="catalog-pg-opclass">
+ <primary>pg_opclass</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_opclass</structname> defines
+ index access method operator classes. Each operator class defines
+ semantics for index columns of a particular data type and a particular
+ index access method. An operator class essentially specifies that a
+ particular operator family is applicable to a particular indexable column
+ data type. The set of operators from the family that are actually usable
+ with the indexed column are whichever ones accept the column's data type
+ as their left-hand input.
+ </para>
+
+ <para>
+ Operator classes are described at length in <xref linkend="xindex"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_opclass</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcmethod</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-am"><structname>pg_am</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Index access method operator class is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this operator class
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Namespace of this operator class
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the operator class
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcfamily</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Operator family containing the operator class
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcintype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type that the operator class indexes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opcdefault</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this operator class is the default for <structfield>opcintype</structfield>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opckeytype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Type of data stored in index, or zero if same as <structfield>opcintype</structfield>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ An operator class's <structfield>opcmethod</structfield> must match the
+ <structfield>opfmethod</structfield> of its containing operator family.
+ Also, there must be no more than one <structname>pg_opclass</structname>
+ row having <structfield>opcdefault</structfield> true for any given combination of
+ <structfield>opcmethod</structfield> and <structfield>opcintype</structfield>.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-operator">
+ <title><structname>pg_operator</structname></title>
+
+ <indexterm zone="catalog-pg-operator">
+ <primary>pg_operator</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_operator</structname> stores information about operators.
+ See <xref linkend="sql-createoperator"/>
+ and <xref linkend="xoper"/> for more information.
+ </para>
+
+ <table>
+ <title><structname>pg_operator</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the operator
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprkind</structfield> <type>char</type>
+ </para>
+ <para>
+ <literal>b</literal> = infix operator (<quote>both</quote>),
+ or <literal>l</literal> = prefix operator (<quote>left</quote>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprcanmerge</structfield> <type>bool</type>
+ </para>
+ <para>
+ This operator supports merge joins
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprcanhash</structfield> <type>bool</type>
+ </para>
+ <para>
+ This operator supports hash joins
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprleft</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Type of the left operand (zero for a prefix operator)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprright</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Type of the right operand
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprresult</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Type of the result
+ (zero for a not-yet-defined <quote>shell</quote> operator)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprcom</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Commutator of this operator (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprnegate</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Negator of this operator (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprcode</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Function that implements this operator
+ (zero for a not-yet-defined <quote>shell</quote> operator)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprrest</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Restriction selectivity estimation function for this operator
+ (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oprjoin</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Join selectivity estimation function for this operator
+ (zero if none)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-opfamily">
+ <title><structname>pg_opfamily</structname></title>
+
+ <indexterm zone="catalog-pg-opfamily">
+ <primary>pg_opfamily</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_opfamily</structname> defines operator families.
+ Each operator family is a collection of operators and associated
+ support routines that implement the semantics specified for a particular
+ index access method. Furthermore, the operators in a family are all
+ <quote>compatible</quote>, in a way that is specified by the access method.
+ The operator family concept allows cross-data-type operators to be used
+ with indexes and to be reasoned about using knowledge of access method
+ semantics.
+ </para>
+
+ <para>
+ Operator families are described at length in <xref linkend="xindex"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_opfamily</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opfmethod</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-am"><structname>pg_am</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Index access method operator family is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opfname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this operator family
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opfnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Namespace of this operator family
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>opfowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the operator family
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The majority of the information defining an operator family is not in its
+ <structname>pg_opfamily</structname> row, but in the associated rows in
+ <link linkend="catalog-pg-amop"><structname>pg_amop</structname></link>,
+ <link linkend="catalog-pg-amproc"><structname>pg_amproc</structname></link>,
+ and
+ <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-parameter-acl">
+ <title><structname>pg_parameter_acl</structname></title>
+
+ <indexterm zone="catalog-pg-parameter-acl">
+ <primary>pg_parameter_acl</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_parameter_acl</structname> records configuration
+ parameters for which privileges have been granted to one or more roles.
+ No entry is made for parameters that have default privileges.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_parameter_acl</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_parameter_acl</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_parameter_acl</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parname</structfield> <type>text</type>
+ </para>
+ <para>
+ The name of a configuration parameter for which privileges are granted
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>paracl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-partitioned-table">
+ <title><structname>pg_partitioned_table</structname></title>
+
+ <indexterm zone="catalog-pg-partitioned-table">
+ <primary>pg_partitioned_table</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_partitioned_table</structname> stores
+ information about how tables are partitioned.
+ </para>
+
+ <table>
+ <title><structname>pg_partitioned_table</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry for this partitioned table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partstrat</structfield> <type>char</type>
+ </para>
+ <para>
+ Partitioning strategy; <literal>h</literal> = hash partitioned table,
+ <literal>l</literal> = list partitioned table, <literal>r</literal> = range partitioned table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partnatts</structfield> <type>int2</type>
+ </para>
+ <para>
+ The number of columns in the partition key
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partdefid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry for the default partition
+ of this partitioned table, or zero if this partitioned table does not
+ have a default partition
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partattrs</structfield> <type>int2vector</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ This is an array of <structfield>partnatts</structfield> values that
+ indicate which table columns are part of the partition key. For
+ example, a value of <literal>1 3</literal> would mean that the first
+ and the third table columns make up the partition key. A zero in this
+ array indicates that the corresponding partition key column is an
+ expression, rather than a simple column reference.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partclass</structfield> <type>oidvector</type>
+ (references <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For each column in the partition key, this contains the OID of the
+ operator class to use. See
+ <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link> for details.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partcollation</structfield> <type>oidvector</type>
+ (references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ For each column in the partition key, this contains the OID of the
+ collation to use for partitioning, or zero if the column is not
+ of a collatable data type.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partexprs</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression trees (in <function>nodeToString()</function>
+ representation) for partition key columns that are not simple column
+ references. This is a list with one element for each zero
+ entry in <structfield>partattrs</structfield>. Null if all partition key columns
+ are simple references.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-policy">
+ <title><structname>pg_policy</structname></title>
+
+ <indexterm zone="catalog-pg-policy">
+ <primary>pg_policy</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_policy</structname> stores row-level
+ security policies for tables. A policy includes the kind of
+ command that it applies to (possibly all commands), the roles that it
+ applies to, the expression to be added as a security-barrier
+ qualification to queries that include the table, and the expression
+ to be added as a <literal>WITH CHECK</literal> option for queries that attempt to
+ add new records to the table.
+ </para>
+
+ <table>
+ <title><structname>pg_policy</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polname</structfield> <type>name</type>
+ </para>
+ <para>
+ The name of the policy
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table to which the policy applies
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polcmd</structfield> <type>char</type>
+ </para>
+ <para>
+ The command type to which the policy is applied:
+ <literal>r</literal> for <xref linkend="sql-select"/>,
+ <literal>a</literal> for <xref linkend="sql-insert"/>,
+ <literal>w</literal> for <xref linkend="sql-update"/>,
+ <literal>d</literal> for <xref linkend="sql-delete"/>,
+ or <literal>*</literal> for all
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polpermissive</structfield> <type>bool</type>
+ </para>
+ <para>
+ Is the policy permissive or restrictive?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polroles</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The roles to which the policy is applied;
+ zero means <literal>PUBLIC</literal>
+ (and normally appears alone in the array)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polqual</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ The expression tree to be added to the security barrier qualifications for queries that use the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>polwithcheck</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ The expression tree to be added to the WITH CHECK qualifications for queries that attempt to add rows to the table
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ Policies stored in <structname>pg_policy</structname> are applied only when
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relrowsecurity</structfield> is set for
+ their table.
+ </para>
+ </note>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-proc">
+ <title><structname>pg_proc</structname></title>
+
+ <indexterm zone="catalog-pg-proc">
+ <primary>pg_proc</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_proc</structname> stores information about
+ functions, procedures, aggregate functions, and window functions
+ (collectively also known as routines). See <xref
+ linkend="sql-createfunction"/>, <xref linkend="sql-createprocedure"/>, and
+ <xref linkend="xfunc"/> for more information.
+ </para>
+
+ <para>
+ If <structfield>prokind</structfield> indicates that the entry is for an
+ aggregate function, there should be a matching row in
+ <link linkend="catalog-pg-aggregate"><structfield>pg_aggregate</structfield></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_proc</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pronamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prolang</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-language"><structname>pg_language</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Implementation language or call interface of this function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>procost</structfield> <type>float4</type>
+ </para>
+ <para>
+ Estimated execution cost (in units of
+ <xref linkend="guc-cpu-operator-cost"/>); if <structfield>proretset</structfield>,
+ this is cost per row returned
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prorows</structfield> <type>float4</type>
+ </para>
+ <para>
+ Estimated number of result rows (zero if not <structfield>proretset</structfield>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>provariadic</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type of the variadic array parameter's elements,
+ or zero if the function does not have a variadic parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prosupport</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Planner support function for this function
+ (see <xref linkend="xfunc-optimization"/>), or zero if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prokind</structfield> <type>char</type>
+ </para>
+ <para>
+ <literal>f</literal> for a normal function, <literal>p</literal>
+ for a procedure, <literal>a</literal> for an aggregate function, or
+ <literal>w</literal> for a window function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prosecdef</structfield> <type>bool</type>
+ </para>
+ <para>
+ Function is a security definer (i.e., a <quote>setuid</quote>
+ function)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proleakproof</structfield> <type>bool</type>
+ </para>
+ <para>
+ The function has no side effects. No information about the
+ arguments is conveyed except via the return value. Any function
+ that might throw an error depending on the values of its arguments
+ is not leak-proof.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proisstrict</structfield> <type>bool</type>
+ </para>
+ <para>
+ Function returns null if any call argument is null. In that
+ case the function won't actually be called at all. Functions
+ that are not <quote>strict</quote> must be prepared to handle
+ null inputs.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proretset</structfield> <type>bool</type>
+ </para>
+ <para>
+ Function returns a set (i.e., multiple values of the specified
+ data type)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>provolatile</structfield> <type>char</type>
+ </para>
+ <para>
+ <structfield>provolatile</structfield> tells whether the function's
+ result depends only on its input arguments, or is affected by outside
+ factors.
+ It is <literal>i</literal> for <quote>immutable</quote> functions,
+ which always deliver the same result for the same inputs.
+ It is <literal>s</literal> for <quote>stable</quote> functions,
+ whose results (for fixed inputs) do not change within a scan.
+ It is <literal>v</literal> for <quote>volatile</quote> functions,
+ whose results might change at any time. (Use <literal>v</literal> also
+ for functions with side-effects, so that calls to them cannot get
+ optimized away.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proparallel</structfield> <type>char</type>
+ </para>
+ <para>
+ <structfield>proparallel</structfield> tells whether the function
+ can be safely run in parallel mode.
+ It is <literal>s</literal> for functions which are safe to run in
+ parallel mode without restriction.
+ It is <literal>r</literal> for functions which can be run in parallel
+ mode, but their execution is restricted to the parallel group leader;
+ parallel worker processes cannot invoke these functions.
+ It is <literal>u</literal> for functions which are unsafe in parallel
+ mode; the presence of such a function forces a serial execution plan.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pronargs</structfield> <type>int2</type>
+ </para>
+ <para>
+ Number of input arguments
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pronargdefaults</structfield> <type>int2</type>
+ </para>
+ <para>
+ Number of arguments that have defaults
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prorettype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type of the return value
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proargtypes</structfield> <type>oidvector</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ An array of the data types of the function arguments. This includes
+ only input arguments (including <literal>INOUT</literal> and
+ <literal>VARIADIC</literal> arguments), and thus represents
+ the call signature of the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proallargtypes</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ An array of the data types of the function arguments. This includes
+ all arguments (including <literal>OUT</literal> and
+ <literal>INOUT</literal> arguments); however, if all the
+ arguments are <literal>IN</literal> arguments, this field will be null.
+ Note that subscripting is 1-based, whereas for historical reasons
+ <structfield>proargtypes</structfield> is subscripted from 0.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proargmodes</structfield> <type>char[]</type>
+ </para>
+ <para>
+ An array of the modes of the function arguments, encoded as
+ <literal>i</literal> for <literal>IN</literal> arguments,
+ <literal>o</literal> for <literal>OUT</literal> arguments,
+ <literal>b</literal> for <literal>INOUT</literal> arguments,
+ <literal>v</literal> for <literal>VARIADIC</literal> arguments,
+ <literal>t</literal> for <literal>TABLE</literal> arguments.
+ If all the arguments are <literal>IN</literal> arguments,
+ this field will be null.
+ Note that subscripts correspond to positions of
+ <structfield>proallargtypes</structfield> not <structfield>proargtypes</structfield>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proargnames</structfield> <type>text[]</type>
+ </para>
+ <para>
+ An array of the names of the function arguments.
+ Arguments without a name are set to empty strings in the array.
+ If none of the arguments have a name, this field will be null.
+ Note that subscripts correspond to positions of
+ <structfield>proallargtypes</structfield> not <structfield>proargtypes</structfield>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proargdefaults</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression trees (in <function>nodeToString()</function> representation)
+ for default values. This is a list with
+ <structfield>pronargdefaults</structfield> elements, corresponding to the last
+ <replaceable>N</replaceable> <emphasis>input</emphasis> arguments (i.e., the last
+ <replaceable>N</replaceable> <structfield>proargtypes</structfield> positions).
+ If none of the arguments have defaults, this field will be null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>protrftypes</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ An array of the argument/result data type(s) for which to apply
+ transforms (from the function's <literal>TRANSFORM</literal>
+ clause). Null if none.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prosrc</structfield> <type>text</type>
+ </para>
+ <para>
+ This tells the function handler how to invoke the function. It
+ might be the actual source code of the function for interpreted
+ languages, a link symbol, a file name, or just about anything
+ else, depending on the implementation language/call convention.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>probin</structfield> <type>text</type>
+ </para>
+ <para>
+ Additional information about how to invoke the function.
+ Again, the interpretation is language-specific.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prosqlbody</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Pre-parsed SQL function body. This is used for SQL-language
+ functions when the body is given in SQL-standard notation
+ rather than as a string literal. It's null in other cases.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proconfig</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Function's local settings for run-time configuration variables
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>proacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ For compiled functions, both built-in and dynamically loaded,
+ <structfield>prosrc</structfield> contains the function's C-language
+ name (link symbol).
+ For SQL-language functions, <structfield>prosrc</structfield> contains
+ the function's source text if that is specified as a string literal;
+ but if the function body is specified in SQL-standard style,
+ <structfield>prosrc</structfield> is unused (typically it's an empty
+ string) and <structfield>prosqlbody</structfield> contains the
+ pre-parsed definition.
+ For all other currently-known language types,
+ <structfield>prosrc</structfield> contains the function's source
+ text. <structfield>probin</structfield> is null except for
+ dynamically-loaded C functions, for which it gives the name of the
+ shared library file containing the function.
+ </para>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-publication">
+ <title><structname>pg_publication</structname></title>
+
+ <indexterm zone="catalog-pg-publication">
+ <primary>pg_publication</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_publication</structname> contains all
+ publications created in the database. For more on publications see
+ <xref linkend="logical-replication-publication"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_publication</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the publication
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the publication
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>puballtables</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, this publication automatically includes all tables
+ in the database, including any that will be created in the future.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubinsert</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, <xref linkend="sql-insert"/> operations are replicated for
+ tables in the publication.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubupdate</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, <xref linkend="sql-update"/> operations are replicated for
+ tables in the publication.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubdelete</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, <xref linkend="sql-delete"/> operations are replicated for
+ tables in the publication.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubtruncate</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, <xref linkend="sql-truncate"/> operations are replicated for
+ tables in the publication.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubviaroot</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, operations on a leaf partition are replicated using the
+ identity and schema of its topmost partitioned ancestor mentioned in the
+ publication instead of its own.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-publication-namespace">
+ <title><structname>pg_publication_namespace</structname></title>
+
+ <indexterm zone="catalog-pg-publication-namespace">
+ <primary>pg_publication_namespace</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_publication_namespace</structname> contains the
+ mapping between schemas and publications in the database. This is a
+ many-to-many mapping.
+ </para>
+
+ <table>
+ <title><structname>pg_publication_namespace</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pnpubid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-publication"><structname>pg_publication</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Reference to publication
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pnnspid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Reference to schema
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-publication-rel">
+ <title><structname>pg_publication_rel</structname></title>
+
+ <indexterm zone="catalog-pg-publication-rel">
+ <primary>pg_publication_rel</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_publication_rel</structname> contains the
+ mapping between relations and publications in the database. This is a
+ many-to-many mapping. See also <xref linkend="view-pg-publication-tables"/>
+ for a more user-friendly view of this information.
+ </para>
+
+ <table>
+ <title><structname>pg_publication_rel</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prpubid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-publication"><structname>pg_publication</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Reference to publication
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Reference to relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prqual</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>Expression tree (in <function>nodeToString()</function>
+ representation) for the relation's publication qualifying condition. Null
+ if there is no publication qualifying condition.</para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prattrs</structfield> <type>int2vector</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ This is an array of values that indicates which table columns are
+ part of the publication. For example, a value of <literal>1 3</literal>
+ would mean that the first and the third table columns are published.
+ A null value indicates that all columns are published.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-range">
+ <title><structname>pg_range</structname></title>
+
+ <indexterm zone="catalog-pg-range">
+ <primary>pg_range</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_range</structname> stores information about
+ range types. This is in addition to the types' entries in
+ <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_range</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngtypid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the range type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngsubtype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the element type (subtype) of this range type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngmultitypid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the multirange type for this range type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngcollation</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the collation used for range comparisons, or zero if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngsubopc</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the subtype's operator class used for range comparisons
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngcanonical</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the function to convert a range value into canonical form,
+ or zero if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rngsubdiff</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the function to return the difference between two element
+ values as <type>double precision</type>, or zero if none
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <structfield>rngsubopc</structfield> (plus <structfield>rngcollation</structfield>, if the
+ element type is collatable) determines the sort ordering used by the range
+ type. <structfield>rngcanonical</structfield> is used when the element type is
+ discrete. <structfield>rngsubdiff</structfield> is optional but should be supplied to
+ improve performance of GiST indexes on the range type.
+ </para>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-replication-origin">
+ <title><structname>pg_replication_origin</structname></title>
+
+ <indexterm zone="catalog-pg-replication-origin">
+ <primary>pg_replication_origin</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_replication_origin</structname> catalog contains
+ all replication origins created. For more on replication origins
+ see <xref linkend="replication-origins"/>.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_replication_origin</structname>
+ is shared across all databases of a cluster: there is only one copy
+ of <structname>pg_replication_origin</structname> per cluster, not one per
+ database.
+ </para>
+
+ <table>
+ <title><structname>pg_replication_origin</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>roident</structfield> <type>oid</type>
+ </para>
+ <para>
+ A unique, cluster-wide identifier for the replication
+ origin. Should never leave the system.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>roname</structfield> <type>text</type>
+ </para>
+ <para>
+ The external, user defined, name of a replication
+ origin.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-rewrite">
+ <title><structname>pg_rewrite</structname></title>
+
+ <indexterm zone="catalog-pg-rewrite">
+ <primary>pg_rewrite</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_rewrite</structname> stores rewrite rules for tables and views.
+ </para>
+
+ <table>
+ <title><structname>pg_rewrite</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rulename</structfield> <type>name</type>
+ </para>
+ <para>
+ Rule name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ev_class</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table this rule is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ev_type</structfield> <type>char</type>
+ </para>
+ <para>
+ Event type that the rule is for: 1 = <xref linkend="sql-select"/>, 2 =
+ <xref linkend="sql-update"/>, 3 = <xref linkend="sql-insert"/>, 4 =
+ <xref linkend="sql-delete"/>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ev_enabled</structfield> <type>char</type>
+ </para>
+ <para>
+ Controls in which <xref linkend="guc-session-replication-role"/> modes
+ the rule fires.
+ <literal>O</literal> = rule fires in <quote>origin</quote> and <quote>local</quote> modes,
+ <literal>D</literal> = rule is disabled,
+ <literal>R</literal> = rule fires in <quote>replica</quote> mode,
+ <literal>A</literal> = rule fires always.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_instead</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the rule is an <literal>INSTEAD</literal> rule
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ev_qual</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression tree (in the form of a
+ <function>nodeToString()</function> representation) for the
+ rule's qualifying condition
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ev_action</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Query tree (in the form of a
+ <function>nodeToString()</function> representation) for the
+ rule's action
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ <literal>pg_class.relhasrules</literal>
+ must be true if a table has any rules in this catalog.
+ </para>
+ </note>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-seclabel">
+ <title><structname>pg_seclabel</structname></title>
+
+ <indexterm zone="catalog-pg-seclabel">
+ <primary>pg_seclabel</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_seclabel</structname> stores security
+ labels on database objects. Security labels can be manipulated
+ with the <link linkend="sql-security-label"><command>SECURITY LABEL</command></link> command. For an easier
+ way to view security labels, see <xref linkend="view-pg-seclabels"/>.
+ </para>
+
+ <para>
+ See also <link linkend="catalog-pg-shseclabel"><structname>pg_shseclabel</structname></link>,
+ which performs a similar function for security labels of database objects
+ that are shared across a database cluster.
+ </para>
+
+ <table>
+ <title><structname>pg_seclabel</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objoid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the object this security label pertains to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog this object appears in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a security label on a table column, this is the column number (the
+ <structfield>objoid</structfield> and <structfield>classoid</structfield> refer to
+ the table itself). For all other object types, this column is
+ zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>provider</structfield> <type>text</type>
+ </para>
+ <para>
+ The label provider associated with this label.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>label</structfield> <type>text</type>
+ </para>
+ <para>
+ The security label applied to this object.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-sequence">
+ <title><structname>pg_sequence</structname></title>
+
+ <indexterm zone="catalog-pg-sequence">
+ <primary>pg_sequence</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_sequence</structname> contains information about
+ sequences. Some of the information about sequences, such as the name and
+ the schema, is in
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>
+ </para>
+
+ <table>
+ <title><structname>pg_sequence</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry for this sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqtypid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqstart</structfield> <type>int8</type>
+ </para>
+ <para>
+ Start value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqincrement</structfield> <type>int8</type>
+ </para>
+ <para>
+ Increment value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqmax</structfield> <type>int8</type>
+ </para>
+ <para>
+ Maximum value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqmin</structfield> <type>int8</type>
+ </para>
+ <para>
+ Minimum value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqcache</structfield> <type>int8</type>
+ </para>
+ <para>
+ Cache size of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqcycle</structfield> <type>bool</type>
+ </para>
+ <para>
+ Whether the sequence cycles
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-shdepend">
+ <title><structname>pg_shdepend</structname></title>
+
+ <indexterm zone="catalog-pg-shdepend">
+ <primary>pg_shdepend</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_shdepend</structname> records the
+ dependency relationships between database objects and shared objects,
+ such as roles. This information allows
+ <productname>PostgreSQL</productname> to ensure that those objects are
+ unreferenced before attempting to delete them.
+ </para>
+
+ <para>
+ See also <link linkend="catalog-pg-depend"><structname>pg_depend</structname></link>,
+ which performs a similar function for dependencies involving objects
+ within a single database.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_shdepend</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_shdepend</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_shdepend</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dbid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the database the dependent object is in,
+ or zero for a shared object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog the dependent object is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the specific dependent object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a table column, this is the column number (the
+ <structfield>objid</structfield> and <structfield>classid</structfield> refer to the
+ table itself). For all other object types, this column is zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>refclassid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog the referenced object is in
+ (must be a shared catalog)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>refobjid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the specific referenced object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>deptype</structfield> <type>char</type>
+ </para>
+ <para>
+ A code defining the specific semantics of this dependency relationship; see text
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In all cases, a <structname>pg_shdepend</structname> entry indicates that
+ the referenced object cannot be dropped without also dropping the dependent
+ object. However, there are several subflavors identified by
+ <structfield>deptype</structfield>:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SHARED_DEPENDENCY_OWNER</symbol> (<literal>o</literal>)</term>
+ <listitem>
+ <para>
+ The referenced object (which must be a role) is the owner of the
+ dependent object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SHARED_DEPENDENCY_ACL</symbol> (<literal>a</literal>)</term>
+ <listitem>
+ <para>
+ The referenced object (which must be a role) is mentioned in the
+ ACL (access control list, i.e., privileges list) of the
+ dependent object. (A <symbol>SHARED_DEPENDENCY_ACL</symbol> entry is
+ not made for the owner of the object, since the owner will have
+ a <symbol>SHARED_DEPENDENCY_OWNER</symbol> entry anyway.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SHARED_DEPENDENCY_POLICY</symbol> (<literal>r</literal>)</term>
+ <listitem>
+ <para>
+ The referenced object (which must be a role) is mentioned as the
+ target of a dependent policy object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SHARED_DEPENDENCY_TABLESPACE</symbol> (<literal>t</literal>)</term>
+ <listitem>
+ <para>
+ The referenced object (which must be a tablespace) is mentioned as
+ the tablespace for a relation that doesn't have storage.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Other dependency flavors might be needed in future. Note in particular
+ that the current definition only supports roles and tablespaces as referenced
+ objects.
+ </para>
+
+ <para>
+ As in the <structname>pg_depend</structname> catalog, most objects
+ created during <application>initdb</application> are
+ considered <quote>pinned</quote>. No entries are made
+ in <structname>pg_shdepend</structname> that would have a pinned
+ object as either referenced or dependent object.
+ </para>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-shdescription">
+ <title><structname>pg_shdescription</structname></title>
+
+ <indexterm zone="catalog-pg-shdescription">
+ <primary>pg_shdescription</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_shdescription</structname> stores optional
+ descriptions (comments) for shared database objects. Descriptions can be
+ manipulated with the <link linkend="sql-comment"><command>COMMENT</command></link> command and viewed with
+ <application>psql</application>'s <literal>\d</literal> commands.
+ </para>
+
+ <para>
+ See also <link linkend="catalog-pg-description"><structname>pg_description</structname></link>,
+ which performs a similar function for descriptions involving objects
+ within a single database.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_shdescription</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_shdescription</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_shdescription</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objoid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the object this description pertains to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog this object appears in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>description</structfield> <type>text</type>
+ </para>
+ <para>
+ Arbitrary text that serves as the description of this object
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-shseclabel">
+ <title><structname>pg_shseclabel</structname></title>
+
+ <indexterm zone="catalog-pg-shseclabel">
+ <primary>pg_shseclabel</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_shseclabel</structname> stores security
+ labels on shared database objects. Security labels can be manipulated
+ with the <link linkend="sql-security-label"><command>SECURITY LABEL</command></link> command. For an easier
+ way to view security labels, see <xref linkend="view-pg-seclabels"/>.
+ </para>
+
+ <para>
+ See also <link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link>,
+ which performs a similar function for security labels involving objects
+ within a single database.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_shseclabel</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_shseclabel</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_shseclabel</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objoid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the object this security label pertains to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog this object appears in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>provider</structfield> <type>text</type>
+ </para>
+ <para>
+ The label provider associated with this label.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>label</structfield> <type>text</type>
+ </para>
+ <para>
+ The security label applied to this object.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-statistic">
+ <title><structname>pg_statistic</structname></title>
+
+ <indexterm zone="catalog-pg-statistic">
+ <primary>pg_statistic</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_statistic</structname> stores
+ statistical data about the contents of the database. Entries are
+ created by <link linkend="sql-analyze"><command>ANALYZE</command></link>
+ and subsequently used by the query planner. Note that all the
+ statistical data is inherently approximate, even assuming that it
+ is up-to-date.
+ </para>
+
+ <para>
+ Normally there is one entry, with <structfield>stainherit</structfield> =
+ <literal>false</literal>, for each table column that has been analyzed.
+ If the table has inheritance children or partitions, a second entry with
+ <structfield>stainherit</structfield> = <literal>true</literal> is also created. This row
+ represents the column's statistics over the inheritance tree, i.e.,
+ statistics for the data you'd see with
+ <literal>SELECT <replaceable>column</replaceable> FROM <replaceable>table</replaceable>*</literal>,
+ whereas the <structfield>stainherit</structfield> = <literal>false</literal> row represents
+ the results of
+ <literal>SELECT <replaceable>column</replaceable> FROM ONLY <replaceable>table</replaceable></literal>.
+ </para>
+
+ <para>
+ <structname>pg_statistic</structname> also stores statistical data about
+ the values of index expressions. These are described as if they were
+ actual data columns; in particular, <structfield>starelid</structfield>
+ references the index. No entry is made for an ordinary non-expression
+ index column, however, since it would be redundant with the entry
+ for the underlying table column. Currently, entries for index expressions
+ always have <structfield>stainherit</structfield> = <literal>false</literal>.
+ </para>
+
+ <para>
+ Since different kinds of statistics might be appropriate for different
+ kinds of data, <structname>pg_statistic</structname> is designed not
+ to assume very much about what sort of statistics it stores. Only
+ extremely general statistics (such as nullness) are given dedicated
+ columns in <structname>pg_statistic</structname>. Everything else
+ is stored in <quote>slots</quote>, which are groups of associated columns
+ whose content is identified by a code number in one of the slot's columns.
+ For more information see
+ <filename>src/include/catalog/pg_statistic.h</filename>.
+ </para>
+
+ <para>
+ <structname>pg_statistic</structname> should not be readable by the
+ public, since even statistical information about a table's contents
+ might be considered sensitive. (Example: minimum and maximum values
+ of a salary column might be quite interesting.)
+ <link linkend="view-pg-stats"><structname>pg_stats</structname></link>
+ is a publicly readable view on
+ <structname>pg_statistic</structname> that only exposes information
+ about those tables that are readable by the current user.
+ </para>
+
+ <table>
+ <title><structname>pg_statistic</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>starelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table or index that the described column belongs to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>staattnum</structfield> <type>int2</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ The number of the described column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stainherit</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stanullfrac</structfield> <type>float4</type>
+ </para>
+ <para>
+ The fraction of the column's entries that are null
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stawidth</structfield> <type>int4</type>
+ </para>
+ <para>
+ The average stored width, in bytes, of nonnull entries
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stadistinct</structfield> <type>float4</type>
+ </para>
+ <para>
+ The number of distinct nonnull data values in the column.
+ A value greater than zero is the actual number of distinct values.
+ A value less than zero is the negative of a multiplier for the number
+ of rows in the table; for example, a column in which about 80% of the
+ values are nonnull and each nonnull value appears about twice on
+ average could be represented by <structfield>stadistinct</structfield> = -0.4.
+ A zero value means the number of distinct values is unknown.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stakind<replaceable>N</replaceable></structfield> <type>int2</type>
+ </para>
+ <para>
+ A code number indicating the kind of statistics stored in the
+ <replaceable>N</replaceable>th <quote>slot</quote> of the
+ <structname>pg_statistic</structname> row.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>staop<replaceable>N</replaceable></structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-operator"><structname>pg_operator</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ An operator used to derive the statistics stored in the
+ <replaceable>N</replaceable>th <quote>slot</quote>. For example, a
+ histogram slot would show the <literal>&lt;</literal> operator
+ that defines the sort order of the data.
+ Zero if the statistics kind does not require an operator.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stacoll<replaceable>N</replaceable></structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The collation used to derive the statistics stored in the
+ <replaceable>N</replaceable>th <quote>slot</quote>. For example, a
+ histogram slot for a collatable column would show the collation that
+ defines the sort order of the data. Zero for noncollatable data.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stanumbers<replaceable>N</replaceable></structfield> <type>float4[]</type>
+ </para>
+ <para>
+ Numerical statistics of the appropriate kind for the
+ <replaceable>N</replaceable>th <quote>slot</quote>, or null if the slot
+ kind does not involve numerical values
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stavalues<replaceable>N</replaceable></structfield> <type>anyarray</type>
+ </para>
+ <para>
+ Column data values of the appropriate kind for the
+ <replaceable>N</replaceable>th <quote>slot</quote>, or null if the slot
+ kind does not store any data values. Each array's element
+ values are actually of the specific column's data type, or a related
+ type such as an array's element type, so there is no way to define
+ these columns' type more specifically than <type>anyarray</type>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-statistic-ext">
+ <title><structname>pg_statistic_ext</structname></title>
+
+ <indexterm zone="catalog-pg-statistic-ext">
+ <primary>pg_statistic_ext</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_statistic_ext</structname>
+ holds definitions of extended planner statistics.
+ Each row in this catalog corresponds to a <firstterm>statistics object</firstterm>
+ created with <link linkend="sql-createstatistics"><command>CREATE STATISTICS</command></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_statistic_ext</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Table containing the columns described by this object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxstattarget</structfield> <type>int4</type>
+ </para>
+ <para>
+ <structfield>stxstattarget</structfield> controls the level of detail
+ of statistics accumulated for this statistics object by
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>.
+ A zero value indicates that no statistics should be collected.
+ A negative value says to use the maximum of the statistics targets of
+ the referenced columns, if set, or the system default statistics target.
+ Positive values of <structfield>stxstattarget</structfield>
+ determine the target number of <quote>most common values</quote>
+ to collect.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxkeys</structfield> <type>int2vector</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ An array of attribute numbers, indicating which table columns are
+ covered by this statistics object;
+ for example a value of <literal>1 3</literal> would
+ mean that the first and the third table columns are covered
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxkind</structfield> <type>char[]</type>
+ </para>
+ <para>
+ An array containing codes for the enabled statistics kinds;
+ valid values are:
+ <literal>d</literal> for n-distinct statistics,
+ <literal>f</literal> for functional dependency statistics,
+ <literal>m</literal> for most common values (MCV) list statistics, and
+ <literal>e</literal> for expression statistics
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxexprs</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression trees (in <function>nodeToString()</function>
+ representation) for statistics object attributes that are not simple
+ column references. This is a list with one element per expression.
+ Null if all statistics object attributes are simple references.
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_statistic_ext</structname> entry is filled in
+ completely during <link linkend="sql-createstatistics"><command>CREATE STATISTICS</command></link>, but the actual
+ statistical values are not computed then.
+ Subsequent <link linkend="sql-analyze"><command>ANALYZE</command></link> commands compute the desired values
+ and populate an entry in the
+ <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>
+ catalog.
+ </para>
+ </sect1>
+
+ <sect1 id="catalog-pg-statistic-ext-data">
+ <title><structname>pg_statistic_ext_data</structname></title>
+
+ <indexterm zone="catalog-pg-statistic-ext">
+ <primary>pg_statistic_ext_data</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_statistic_ext_data</structname>
+ holds data for extended planner statistics defined in
+ <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.
+ Each row in this catalog corresponds to a <firstterm>statistics object</firstterm>
+ created with <link linkend="sql-createstatistics"><command>CREATE STATISTICS</command></link>.
+ </para>
+
+ <para>
+ Normally there is one entry, with <structfield>stxdinherit</structfield> =
+ <literal>false</literal>, for each statistics object that has been analyzed.
+ If the table has inheritance children or partitions, a second entry with
+ <structfield>stxdinherit</structfield> = <literal>true</literal> is also created.
+ This row represents the statistics object over the inheritance tree, i.e.,
+ statistics for the data you'd see with
+ <literal>SELECT * FROM <replaceable>table</replaceable>*</literal>,
+ whereas the <structfield>stxdinherit</structfield> = <literal>false</literal> row
+ represents the results of
+ <literal>SELECT * FROM ONLY <replaceable>table</replaceable></literal>.
+ </para>
+
+ <para>
+ Like <link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>,
+ <structname>pg_statistic_ext_data</structname> should not be
+ readable by the public, since the contents might be considered sensitive.
+ (Example: most common combinations of values in columns might be quite
+ interesting.)
+ <link linkend="view-pg-stats-ext"><structname>pg_stats_ext</structname></link>
+ is a publicly readable view
+ on <structname>pg_statistic_ext_data</structname> (after joining
+ with <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>) that only exposes
+ information about those tables and columns that are readable by the
+ current user.
+ </para>
+
+ <table>
+ <title><structname>pg_statistic_ext_data</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Extended statistics object containing the definition for this data
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxdinherit</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxdndistinct</structfield> <type>pg_ndistinct</type>
+ </para>
+ <para>
+ N-distinct counts, serialized as <structname>pg_ndistinct</structname> type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxddependencies</structfield> <type>pg_dependencies</type>
+ </para>
+ <para>
+ Functional dependency statistics, serialized
+ as <structname>pg_dependencies</structname> type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxdmcv</structfield> <type>pg_mcv_list</type>
+ </para>
+ <para>
+ MCV (most-common values) list statistics, serialized as
+ <structname>pg_mcv_list</structname> type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stxdexpr</structfield> <type>pg_statistic[]</type>
+ </para>
+ <para>
+ Per-expression statistics, serialized as an array of
+ <structname>pg_statistic</structname> type
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="catalog-pg-subscription">
+ <title><structname>pg_subscription</structname></title>
+
+ <indexterm zone="catalog-pg-subscription">
+ <primary>pg_subscription</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_subscription</structname> contains all existing
+ logical replication subscriptions. For more information about logical
+ replication see <xref linkend="logical-replication"/>.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_subscription</structname> is
+ shared across all databases of a cluster: there is only one copy
+ of <structname>pg_subscription</structname> per cluster, not one per
+ database.
+ </para>
+
+ <para>
+ Access to the column <structfield>subconninfo</structfield> is revoked from
+ normal users, because it could contain plain-text passwords.
+ </para>
+
+ <table>
+ <title><structname>pg_subscription</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subdbid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the database that the subscription resides in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subskiplsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Finish LSN of the transaction whose changes are to be skipped, if a valid
+ LSN; otherwise <literal>0/0</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subenabled</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the subscription is enabled and should be replicating
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subbinary</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the subscription will request that the publisher send data
+ in binary format
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>substream</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the subscription will allow streaming of in-progress
+ transactions
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subtwophasestate</structfield> <type>char</type>
+ </para>
+ <para>
+ State codes for two-phase mode:
+ <literal>d</literal> = disabled,
+ <literal>p</literal> = pending enablement,
+ <literal>e</literal> = enabled
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subdisableonerr</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, the subscription will be disabled if one of its workers
+ detects an error
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subconninfo</structfield> <type>text</type>
+ </para>
+ <para>
+ Connection string to the upstream database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subslotname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the replication slot in the upstream database (also used
+ for the local replication origin name);
+ null represents <literal>NONE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subsynccommit</structfield> <type>text</type>
+ </para>
+ <para>
+ The <varname>synchronous_commit</varname>
+ setting for the subscription's workers to use
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subpublications</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Array of subscribed publication names. These reference
+ publications defined in the upstream database. For more on publications
+ see <xref linkend="logical-replication-publication"/>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-subscription-rel">
+ <title><structname>pg_subscription_rel</structname></title>
+
+ <indexterm zone="catalog-pg-subscription-rel">
+ <primary>pg_subscription_rel</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_subscription_rel</structname> contains the
+ state for each replicated relation in each subscription. This is a
+ many-to-many mapping.
+ </para>
+
+ <para>
+ This catalog only contains tables known to the subscription after running
+ either <link linkend="sql-createsubscription"><command>CREATE SUBSCRIPTION</command></link> or
+ <link linkend="sql-altersubscription"><command>ALTER SUBSCRIPTION ... REFRESH
+ PUBLICATION</command></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_subscription_rel</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srsubid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-subscription"><structname>pg_subscription</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Reference to subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Reference to relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srsubstate</structfield> <type>char</type>
+ </para>
+ <para>
+ State code:
+ <literal>i</literal> = initialize,
+ <literal>d</literal> = data is being copied,
+ <literal>f</literal> = finished table copy,
+ <literal>s</literal> = synchronized,
+ <literal>r</literal> = ready (normal replication)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srsublsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Remote LSN of the state change used for synchronization coordination
+ when in <literal>s</literal> or <literal>r</literal> states,
+ otherwise null
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="catalog-pg-tablespace">
+ <title><structname>pg_tablespace</structname></title>
+
+ <indexterm zone="catalog-pg-tablespace">
+ <primary>pg_tablespace</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_tablespace</structname> stores information
+ about the available tablespaces. Tables can be placed in particular
+ tablespaces to aid administration of disk layout.
+ </para>
+
+ <para>
+ Unlike most system catalogs, <structname>pg_tablespace</structname>
+ is shared across all databases of a cluster: there is only one
+ copy of <structname>pg_tablespace</structname> per cluster, not
+ one per database.
+ </para>
+
+ <table>
+ <title><structname>pg_tablespace</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spcname</structfield> <type>name</type>
+ </para>
+ <para>
+ Tablespace name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spcowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the tablespace, usually the user who created it
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spcacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spcoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Tablespace-level options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-transform">
+ <title><structname>pg_transform</structname></title>
+
+ <indexterm zone="catalog-pg-transform">
+ <primary>pg_transform</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_transform</structname> stores information about
+ transforms, which are a mechanism to adapt data types to procedural
+ languages. See <xref linkend="sql-createtransform"/> for more information.
+ </para>
+
+ <table>
+ <title><structname>pg_transform</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trftype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the data type this transform is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trflang</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-language"><structname>pg_language</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the language this transform is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trffromsql</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the function to use when converting the data type for input
+ to the procedural language (e.g., function parameters). Zero is stored
+ if the default behavior should be used.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trftosql</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the function to use when converting output from the
+ procedural language (e.g., return values) to the data type. Zero is
+ stored if the default behavior should be used.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-trigger">
+ <title><structname>pg_trigger</structname></title>
+
+ <indexterm zone="catalog-pg-trigger">
+ <primary>pg_trigger</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_trigger</structname> stores triggers on tables
+ and views.
+ See <xref linkend="sql-createtrigger"/>
+ for more information.
+ </para>
+
+ <table>
+ <title><structname>pg_trigger</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table this trigger is on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgparentid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Parent trigger that this trigger is cloned from (this happens when
+ partitions are created or attached to a partitioned table);
+ zero if not a clone
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgname</structfield> <type>name</type>
+ </para>
+ <para>
+ Trigger name (must be unique among triggers of same table)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgfoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The function to be called
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgtype</structfield> <type>int2</type>
+ </para>
+ <para>
+ Bit mask identifying trigger firing conditions
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgenabled</structfield> <type>char</type>
+ </para>
+ <para>
+ Controls in which <xref linkend="guc-session-replication-role"/> modes
+ the trigger fires.
+ <literal>O</literal> = trigger fires in <quote>origin</quote> and <quote>local</quote> modes,
+ <literal>D</literal> = trigger is disabled,
+ <literal>R</literal> = trigger fires in <quote>replica</quote> mode,
+ <literal>A</literal> = trigger fires always.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgisinternal</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if trigger is internally generated (usually, to enforce
+ the constraint identified by <structfield>tgconstraint</structfield>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgconstrrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The table referenced by a referential integrity constraint
+ (zero if trigger is not for a referential integrity constraint)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgconstrindid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The index supporting a unique, primary key, referential integrity,
+ or exclusion constraint
+ (zero if trigger is not for one of these types of constraint)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgconstraint</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-constraint"><structname>pg_constraint</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The <link linkend="catalog-pg-constraint"><structname>pg_constraint</structname></link> entry associated with the trigger
+ (zero if trigger is not for a constraint)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgdeferrable</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if constraint trigger is deferrable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tginitdeferred</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if constraint trigger is initially deferred
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgnargs</structfield> <type>int2</type>
+ </para>
+ <para>
+ Number of argument strings passed to trigger function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgattr</structfield> <type>int2vector</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attnum</structfield>)
+ </para>
+ <para>
+ Column numbers, if trigger is column-specific; otherwise an
+ empty array
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgargs</structfield> <type>bytea</type>
+ </para>
+ <para>
+ Argument strings to pass to trigger, each NULL-terminated
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgqual</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ Expression tree (in <function>nodeToString()</function>
+ representation) for the trigger's <literal>WHEN</literal> condition, or null
+ if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgoldtable</structfield> <type>name</type>
+ </para>
+ <para>
+ <literal>REFERENCING</literal> clause name for <literal>OLD TABLE</literal>,
+ or null if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tgnewtable</structfield> <type>name</type>
+ </para>
+ <para>
+ <literal>REFERENCING</literal> clause name for <literal>NEW TABLE</literal>,
+ or null if none
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Currently, column-specific triggering is supported only for
+ <literal>UPDATE</literal> events, and so <structfield>tgattr</structfield> is relevant
+ only for that event type. <structfield>tgtype</structfield> might
+ contain bits for other event types as well, but those are presumed
+ to be table-wide regardless of what is in <structfield>tgattr</structfield>.
+ </para>
+
+ <note>
+ <para>
+ When <structfield>tgconstraint</structfield> is nonzero,
+ <structfield>tgconstrrelid</structfield>, <structfield>tgconstrindid</structfield>,
+ <structfield>tgdeferrable</structfield>, and <structfield>tginitdeferred</structfield> are
+ largely redundant with the referenced <link linkend="catalog-pg-constraint"><structname>pg_constraint</structname></link> entry.
+ However, it is possible for a non-deferrable trigger to be associated
+ with a deferrable constraint: foreign key constraints can have some
+ deferrable and some non-deferrable triggers.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ <literal>pg_class.relhastriggers</literal>
+ must be true if a relation has any triggers in this catalog.
+ </para>
+ </note>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-ts-config">
+ <title><structname>pg_ts_config</structname></title>
+
+ <indexterm zone="catalog-pg-ts-config">
+ <primary>pg_ts_config</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_ts_config</structname> catalog contains entries
+ representing text search configurations. A configuration specifies
+ a particular text search parser and a list of dictionaries to use
+ for each of the parser's output token types. The parser is shown
+ in the <structname>pg_ts_config</structname> entry, but the
+ token-to-dictionary mapping is defined by subsidiary entries in <link
+ linkend="catalog-pg-ts-config-map"><structname>pg_ts_config_map</structname></link>.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s text search features are
+ described at length in <xref linkend="textsearch"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_ts_config</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cfgname</structfield> <type>name</type>
+ </para>
+ <para>
+ Text search configuration name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cfgnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this configuration
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cfgowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the configuration
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cfgparser</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-ts-parser"><structname>pg_ts_parser</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the text search parser for this configuration
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-ts-config-map">
+ <title><structname>pg_ts_config_map</structname></title>
+
+ <indexterm zone="catalog-pg-ts-config-map">
+ <primary>pg_ts_config_map</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_ts_config_map</structname> catalog contains entries
+ showing which text search dictionaries should be consulted, and in
+ what order, for each output token type of each text search configuration's
+ parser.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s text search features are
+ described at length in <xref linkend="textsearch"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_ts_config_map</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mapcfg</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-ts-config"><structname>pg_ts_config</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the <link linkend="catalog-pg-ts-config"><structname>pg_ts_config</structname></link> entry owning this map entry
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maptokentype</structfield> <type>int4</type>
+ </para>
+ <para>
+ A token type emitted by the configuration's parser
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mapseqno</structfield> <type>int4</type>
+ </para>
+ <para>
+ Order in which to consult this entry (lower
+ <structfield>mapseqno</structfield>s first)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mapdict</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-ts-dict"><structname>pg_ts_dict</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the text search dictionary to consult
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-ts-dict">
+ <title><structname>pg_ts_dict</structname></title>
+
+ <indexterm zone="catalog-pg-ts-dict">
+ <primary>pg_ts_dict</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_ts_dict</structname> catalog contains entries
+ defining text search dictionaries. A dictionary depends on a text
+ search template, which specifies all the implementation functions
+ needed; the dictionary itself provides values for the user-settable
+ parameters supported by the template. This division of labor allows
+ dictionaries to be created by unprivileged users. The parameters
+ are specified by a text string <structfield>dictinitoption</structfield>,
+ whose format and meaning vary depending on the template.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s text search features are
+ described at length in <xref linkend="textsearch"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_ts_dict</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dictname</structfield> <type>name</type>
+ </para>
+ <para>
+ Text search dictionary name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dictnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this dictionary
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dictowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the dictionary
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dicttemplate</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-ts-template"><structname>pg_ts_template</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the text search template for this dictionary
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dictinitoption</structfield> <type>text</type>
+ </para>
+ <para>
+ Initialization option string for the template
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-ts-parser">
+ <title><structname>pg_ts_parser</structname></title>
+
+ <indexterm zone="catalog-pg-ts-parser">
+ <primary>pg_ts_parser</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_ts_parser</structname> catalog contains entries
+ defining text search parsers. A parser is responsible for splitting
+ input text into lexemes and assigning a token type to each lexeme.
+ Since a parser must be implemented by C-language-level functions,
+ creation of new parsers is restricted to database superusers.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s text search features are
+ described at length in <xref linkend="textsearch"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_ts_parser</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prsname</structfield> <type>name</type>
+ </para>
+ <para>
+ Text search parser name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prsnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this parser
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prsstart</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the parser's startup function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prstoken</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the parser's next-token function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prsend</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the parser's shutdown function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prsheadline</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the parser's headline function (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prslextype</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the parser's lextype function
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-ts-template">
+ <title><structname>pg_ts_template</structname></title>
+
+ <indexterm zone="catalog-pg-ts-template">
+ <primary>pg_ts_template</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_ts_template</structname> catalog contains entries
+ defining text search templates. A template is the implementation
+ skeleton for a class of text search dictionaries.
+ Since a template must be implemented by C-language-level functions,
+ creation of new templates is restricted to database superusers.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s text search features are
+ described at length in <xref linkend="textsearch"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_ts_template</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tmplname</structfield> <type>name</type>
+ </para>
+ <para>
+ Text search template name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tmplnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this template
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tmplinit</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the template's initialization function (zero if none)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tmpllexize</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the template's lexize function
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+
+ <sect1 id="catalog-pg-type">
+ <title><structname>pg_type</structname></title>
+
+ <indexterm zone="catalog-pg-type">
+ <primary>pg_type</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_type</structname> stores information about data
+ types. Base types and enum types (scalar types) are created with
+ <link linkend="sql-createtype"><command>CREATE TYPE</command></link>, and
+ domains with
+ <link linkend="sql-createdomain"><command>CREATE DOMAIN</command></link>.
+ A composite type is automatically created for each table in the database, to
+ represent the row structure of the table. It is also possible to create
+ composite types with <command>CREATE TYPE AS</command>.
+ </para>
+
+ <table>
+ <title><structname>pg_type</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typname</structfield> <type>name</type>
+ </para>
+ <para>
+ Data type name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace that contains this type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typowner</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Owner of the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typlen</structfield> <type>int2</type>
+ </para>
+ <para>
+ For a fixed-size type, <structfield>typlen</structfield> is the number
+ of bytes in the internal representation of the type. But for a
+ variable-length type, <structfield>typlen</structfield> is negative.
+ -1 indicates a <quote>varlena</quote> type (one that has a length word),
+ -2 indicates a null-terminated C string.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typbyval</structfield> <type>bool</type>
+ </para>
+ <para>
+ <structfield>typbyval</structfield> determines whether internal
+ routines pass a value of this type by value or by reference.
+ <structfield>typbyval</structfield> had better be false if
+ <structfield>typlen</structfield> is not 1, 2, or 4 (or 8 on machines
+ where Datum is 8 bytes).
+ Variable-length types are always passed by reference. Note that
+ <structfield>typbyval</structfield> can be false even if the
+ length would allow pass-by-value.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typtype</structfield> <type>char</type>
+ </para>
+ <para>
+ <structfield>typtype</structfield> is
+ <literal>b</literal> for a base type,
+ <literal>c</literal> for a composite type (e.g., a table's row type),
+ <literal>d</literal> for a domain,
+ <literal>e</literal> for an enum type,
+ <literal>p</literal> for a pseudo-type,
+ <literal>r</literal> for a range type, or
+ <literal>m</literal> for a multirange type.
+ See also <structfield>typrelid</structfield> and
+ <structfield>typbasetype</structfield>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typcategory</structfield> <type>char</type>
+ </para>
+ <para>
+ <structfield>typcategory</structfield> is an arbitrary classification
+ of data types that is used by the parser to determine which implicit
+ casts should be <quote>preferred</quote>.
+ See <xref linkend="catalog-typcategory-table"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typispreferred</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the type is a preferred cast target within its
+ <structfield>typcategory</structfield>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typisdefined</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the type is defined, false if this is a placeholder
+ entry for a not-yet-defined type. When
+ <structfield>typisdefined</structfield> is false, nothing
+ except the type name, namespace, and OID can be relied on.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typdelim</structfield> <type>char</type>
+ </para>
+ <para>
+ Character that separates two values of this type when parsing
+ array input. Note that the delimiter is associated with the array
+ element data type, not the array data type.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typrelid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If this is a composite type (see
+ <structfield>typtype</structfield>), then this column points to
+ the <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry that defines the
+ corresponding table. (For a free-standing composite type, the
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link> entry doesn't really represent
+ a table, but it is needed anyway for the type's
+ <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link> entries to link to.)
+ Zero for non-composite types.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typsubscript</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Subscripting handler function's OID, or zero if this type doesn't
+ support subscripting. Types that are <quote>true</quote> array
+ types have <structfield>typsubscript</structfield>
+ = <function>array_subscript_handler</function>, but other types may
+ have other handler functions to implement specialized subscripting
+ behavior.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typelem</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If <structfield>typelem</structfield> is not zero then it
+ identifies another row in <structname>pg_type</structname>,
+ defining the type yielded by subscripting. This should be zero
+ if <structfield>typsubscript</structfield> is zero. However, it can
+ be zero when <structfield>typsubscript</structfield> isn't zero, if the
+ handler doesn't need <structfield>typelem</structfield> to
+ determine the subscripting result type.
+ Note that a <structfield>typelem</structfield> dependency is
+ considered to imply physical containment of the element type in
+ this type; so DDL changes on the element type might be restricted
+ by the presence of this type.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typarray</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If <structfield>typarray</structfield> is not zero then it
+ identifies another row in <structname>pg_type</structname>, which
+ is the <quote>true</quote> array type having this type as element
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typinput</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Input conversion function (text format)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typoutput</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Output conversion function (text format)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typreceive</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Input conversion function (binary format), or zero if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typsend</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Output conversion function (binary format), or zero if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typmodin</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Type modifier input function, or zero if type does not support modifiers
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typmodout</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Type modifier output function, or zero to use the standard format
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typanalyze</structfield> <type>regproc</type>
+ (references <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Custom <xref linkend="sql-analyze"/> function,
+ or zero to use the standard function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typalign</structfield> <type>char</type>
+ </para>
+ <para>
+ <structfield>typalign</structfield> is the alignment required
+ when storing a value of this type. It applies to storage on
+ disk as well as most representations of the value inside
+ <productname>PostgreSQL</productname>.
+ When multiple values are stored consecutively, such
+ as in the representation of a complete row on disk, padding is
+ inserted before a datum of this type so that it begins on the
+ specified boundary. The alignment reference is the beginning
+ of the first datum in the sequence.
+ Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para><literal>c</literal> = <type>char</type> alignment, i.e., no alignment needed.</para>
+ </listitem>
+ <listitem>
+ <para><literal>s</literal> = <type>short</type> alignment (2 bytes on most machines).</para>
+ </listitem>
+ <listitem>
+ <para><literal>i</literal> = <type>int</type> alignment (4 bytes on most machines).</para>
+ </listitem>
+ <listitem>
+ <para><literal>d</literal> = <type>double</type> alignment (8 bytes on many machines, but by no means all).</para>
+ </listitem>
+ </itemizedlist>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typstorage</structfield> <type>char</type>
+ </para>
+ <para>
+ <structfield>typstorage</structfield> tells for varlena
+ types (those with <structfield>typlen</structfield> = -1) if
+ the type is prepared for toasting and what the default strategy
+ for attributes of this type should be.
+ Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>p</literal> (plain): Values must always be stored plain
+ (non-varlena types always use this value).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>e</literal> (external): Values can be stored in a
+ secondary <quote>TOAST</quote> relation (if relation has one, see
+ <literal>pg_class.reltoastrelid</literal>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>m</literal> (main): Values can be compressed and stored
+ inline.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>x</literal> (extended): Values can be compressed and/or
+ moved to a secondary relation.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <literal>x</literal> is the usual choice for toast-able types.
+ Note that <literal>m</literal> values can also be moved out to
+ secondary storage, but only as a last resort (<literal>e</literal>
+ and <literal>x</literal> values are moved first).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typnotnull</structfield> <type>bool</type>
+ </para>
+ <para>
+ <structfield>typnotnull</structfield> represents a not-null
+ constraint on a type. Used for domains only.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typbasetype</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ If this is a domain (see <structfield>typtype</structfield>), then
+ <structfield>typbasetype</structfield> identifies the type that this
+ one is based on. Zero if this type is not a domain.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typtypmod</structfield> <type>int4</type>
+ </para>
+ <para>
+ Domains use <structfield>typtypmod</structfield> to record the <literal>typmod</literal>
+ to be applied to their base type (-1 if base type does not use a
+ <literal>typmod</literal>). -1 if this type is not a domain.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typndims</structfield> <type>int4</type>
+ </para>
+ <para>
+ <structfield>typndims</structfield> is the number of array dimensions
+ for a domain over an array (that is, <structfield>typbasetype</structfield> is
+ an array type).
+ Zero for types other than domains over array types.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typcollation</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ <structfield>typcollation</structfield> specifies the collation
+ of the type. If the type does not support collations, this will
+ be zero. A base type that supports collations will have a nonzero
+ value here, typically <symbol>DEFAULT_COLLATION_OID</symbol>.
+ A domain over a collatable type can have a collation OID different
+ from its base type's, if one was specified for the domain.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typdefaultbin</structfield> <type>pg_node_tree</type>
+ </para>
+ <para>
+ If <structfield>typdefaultbin</structfield> is not null, it is the
+ <function>nodeToString()</function>
+ representation of a default expression for the type. This is
+ only used for domains.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typdefault</structfield> <type>text</type>
+ </para>
+ <para>
+ <structfield>typdefault</structfield> is null if the type has no associated
+ default value. If <structfield>typdefaultbin</structfield> is not null,
+ <structfield>typdefault</structfield> must contain a human-readable version of the
+ default expression represented by <structfield>typdefaultbin</structfield>. If
+ <structfield>typdefaultbin</structfield> is null and <structfield>typdefault</structfield> is
+ not, then <structfield>typdefault</structfield> is the external representation of
+ the type's default value, which can be fed to the type's input
+ converter to produce a constant.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>typacl</structfield> <type>aclitem[]</type>
+ </para>
+ <para>
+ Access privileges; see <xref linkend="ddl-priv"/> for details
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ For fixed-width types used in system tables, it is critical that the size
+ and alignment defined in <structname>pg_type</structname>
+ agree with the way that the compiler will lay out the column in
+ a structure representing a table row.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="catalog-typcategory-table"/> lists the system-defined values
+ of <structfield>typcategory</structfield>. Any future additions to this list will
+ also be upper-case ASCII letters. All other ASCII characters are reserved
+ for user-defined categories.
+ </para>
+
+ <table id="catalog-typcategory-table">
+ <title><structfield>typcategory</structfield> Codes</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Code</entry>
+ <entry>Category</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>A</literal></entry>
+ <entry>Array types</entry>
+ </row>
+ <row>
+ <entry><literal>B</literal></entry>
+ <entry>Boolean types</entry>
+ </row>
+ <row>
+ <entry><literal>C</literal></entry>
+ <entry>Composite types</entry>
+ </row>
+ <row>
+ <entry><literal>D</literal></entry>
+ <entry>Date/time types</entry>
+ </row>
+ <row>
+ <entry><literal>E</literal></entry>
+ <entry>Enum types</entry>
+ </row>
+ <row>
+ <entry><literal>G</literal></entry>
+ <entry>Geometric types</entry>
+ </row>
+ <row>
+ <entry><literal>I</literal></entry>
+ <entry>Network address types</entry>
+ </row>
+ <row>
+ <entry><literal>N</literal></entry>
+ <entry>Numeric types</entry>
+ </row>
+ <row>
+ <entry><literal>P</literal></entry>
+ <entry>Pseudo-types</entry>
+ </row>
+ <row>
+ <entry><literal>R</literal></entry>
+ <entry>Range types</entry>
+ </row>
+ <row>
+ <entry><literal>S</literal></entry>
+ <entry>String types</entry>
+ </row>
+ <row>
+ <entry><literal>T</literal></entry>
+ <entry>Timespan types</entry>
+ </row>
+ <row>
+ <entry><literal>U</literal></entry>
+ <entry>User-defined types</entry>
+ </row>
+ <row>
+ <entry><literal>V</literal></entry>
+ <entry>Bit-string types</entry>
+ </row>
+ <row>
+ <entry><literal>X</literal></entry>
+ <entry><type>unknown</type> type</entry>
+ </row>
+ <row>
+ <entry><literal>Z</literal></entry>
+ <entry>Internal-use types</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="catalog-pg-user-mapping">
+ <title><structname>pg_user_mapping</structname></title>
+
+ <indexterm zone="catalog-pg-user-mapping">
+ <primary>pg_user_mapping</primary>
+ </indexterm>
+
+ <para>
+ The catalog <structname>pg_user_mapping</structname> stores
+ the mappings from local user to remote. Access to this catalog is
+ restricted from normal users, use the view
+ <link linkend="view-pg-user-mappings"><structname>pg_user_mappings</structname></link>
+ instead.
+ </para>
+
+ <table>
+ <title><structname>pg_user_mapping</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ </para>
+ <para>
+ Row identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>umuser</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the local role being mapped, or zero if the user mapping is public
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>umserver</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-foreign-server"><structname>pg_foreign_server</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the foreign server that contains this mapping
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>umoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ User mapping specific options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml
new file mode 100644
index 0000000..445fd17
--- /dev/null
+++ b/doc/src/sgml/charset.sgml
@@ -0,0 +1,2741 @@
+<!-- doc/src/sgml/charset.sgml -->
+
+<chapter id="charset">
+ <title>Localization</title>
+
+ <para>
+ This chapter describes the available localization features from the
+ point of view of the administrator.
+ <productname>PostgreSQL</productname> supports two localization
+ facilities:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Using the locale features of the operating system to provide
+ locale-specific collation order, number formatting, translated
+ messages, and other aspects.
+ This is covered in <xref linkend="locale"/> and
+ <xref linkend="collation"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Providing a number of different character sets to support storing text
+ in all kinds of languages, and providing character set translation
+ between client and server.
+ This is covered in <xref linkend="multibyte"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+
+ <sect1 id="locale">
+ <title>Locale Support</title>
+
+ <indexterm zone="locale"><primary>locale</primary></indexterm>
+
+ <para>
+ <firstterm>Locale</firstterm> support refers to an application respecting
+ cultural preferences regarding alphabets, sorting, number
+ formatting, etc. <productname>PostgreSQL</productname> uses the standard ISO
+ C and <acronym>POSIX</acronym> locale facilities provided by the server operating
+ system. For additional information refer to the documentation of your
+ system.
+ </para>
+
+ <sect2>
+ <title>Overview</title>
+
+ <para>
+ Locale support is automatically initialized when a database
+ cluster is created using <command>initdb</command>.
+ <command>initdb</command> will initialize the database cluster
+ with the locale setting of its execution environment by default,
+ so if your system is already set to use the locale that you want
+ in your database cluster then there is nothing else you need to
+ do. If you want to use a different locale (or you are not sure
+ which locale your system is set to), you can instruct
+ <command>initdb</command> exactly which locale to use by
+ specifying the <option>--locale</option> option. For example:
+<screen>
+initdb --locale=sv_SE
+</screen>
+ </para>
+
+ <para>
+ This example for Unix systems sets the locale to Swedish
+ (<literal>sv</literal>) as spoken
+ in Sweden (<literal>SE</literal>). Other possibilities might include
+ <literal>en_US</literal> (U.S. English) and <literal>fr_CA</literal> (French
+ Canadian). If more than one character set can be used for a
+ locale then the specifications can take the form
+ <replaceable>language_territory.codeset</replaceable>. For example,
+ <literal>fr_BE.UTF-8</literal> represents the French language (fr) as
+ spoken in Belgium (BE), with a <acronym>UTF-8</acronym> character set
+ encoding.
+ </para>
+
+ <para>
+ What locales are available on your
+ system under what names depends on what was provided by the operating
+ system vendor and what was installed. On most Unix systems, the command
+ <literal>locale -a</literal> will provide a list of available locales.
+ Windows uses more verbose locale names, such as <literal>German_Germany</literal>
+ or <literal>Swedish_Sweden.1252</literal>, but the principles are the same.
+ </para>
+
+ <para>
+ Occasionally it is useful to mix rules from several locales, e.g.,
+ use English collation rules but Spanish messages. To support that, a
+ set of locale subcategories exist that control only certain
+ aspects of the localization rules:
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <tbody>
+ <row>
+ <entry><envar>LC_COLLATE</envar></entry>
+ <entry>String sort order</entry>
+ </row>
+ <row>
+ <entry><envar>LC_CTYPE</envar></entry>
+ <entry>Character classification (What is a letter? Its upper-case equivalent?)</entry>
+ </row>
+ <row>
+ <entry><envar>LC_MESSAGES</envar></entry>
+ <entry>Language of messages</entry>
+ </row>
+ <row>
+ <entry><envar>LC_MONETARY</envar></entry>
+ <entry>Formatting of currency amounts</entry>
+ </row>
+ <row>
+ <entry><envar>LC_NUMERIC</envar></entry>
+ <entry>Formatting of numbers</entry>
+ </row>
+ <row>
+ <entry><envar>LC_TIME</envar></entry>
+ <entry>Formatting of dates and times</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ The category names translate into names of
+ <command>initdb</command> options to override the locale choice
+ for a specific category. For instance, to set the locale to
+ French Canadian, but use U.S. rules for formatting currency, use
+ <literal>initdb --locale=fr_CA --lc-monetary=en_US</literal>.
+ </para>
+
+ <para>
+ If you want the system to behave as if it had no locale support,
+ use the special locale name <literal>C</literal>, or equivalently
+ <literal>POSIX</literal>.
+ </para>
+
+ <para>
+ Some locale categories must have their values
+ fixed when the database is created. You can use different settings
+ for different databases, but once a database is created, you cannot
+ change them for that database anymore. <literal>LC_COLLATE</literal>
+ and <literal>LC_CTYPE</literal> are these categories. They affect
+ the sort order of indexes, so they must be kept fixed, or indexes on
+ text columns would become corrupt.
+ (But you can alleviate this restriction using collations, as discussed
+ in <xref linkend="collation"/>.)
+ The default values for these
+ categories are determined when <command>initdb</command> is run, and
+ those values are used when new databases are created, unless
+ specified otherwise in the <command>CREATE DATABASE</command> command.
+ </para>
+
+ <para>
+ The other locale categories can be changed whenever desired
+ by setting the server configuration parameters
+ that have the same name as the locale categories (see <xref
+ linkend="runtime-config-client-format"/> for details). The values
+ that are chosen by <command>initdb</command> are actually only written
+ into the configuration file <filename>postgresql.conf</filename> to
+ serve as defaults when the server is started. If you remove these
+ assignments from <filename>postgresql.conf</filename> then the
+ server will inherit the settings from its execution environment.
+ </para>
+
+ <para>
+ Note that the locale behavior of the server is determined by the
+ environment variables seen by the server, not by the environment
+ of any client. Therefore, be careful to configure the correct locale settings
+ before starting the server. A consequence of this is that if
+ client and server are set up in different locales, messages might
+ appear in different languages depending on where they originated.
+ </para>
+
+ <note>
+ <para>
+ When we speak of inheriting the locale from the execution
+ environment, this means the following on most operating systems:
+ For a given locale category, say the collation, the following
+ environment variables are consulted in this order until one is
+ found to be set: <envar>LC_ALL</envar>, <envar>LC_COLLATE</envar>
+ (or the variable corresponding to the respective category),
+ <envar>LANG</envar>. If none of these environment variables are
+ set then the locale defaults to <literal>C</literal>.
+ </para>
+
+ <para>
+ Some message localization libraries also look at the environment
+ variable <envar>LANGUAGE</envar> which overrides all other locale
+ settings for the purpose of setting the language of messages. If
+ in doubt, please refer to the documentation of your operating
+ system, in particular the documentation about
+ <application>gettext</application>.
+ </para>
+ </note>
+
+ <para>
+ To enable messages to be translated to the user's preferred language,
+ <acronym>NLS</acronym> must have been selected at build time
+ (<literal>configure --enable-nls</literal>). All other locale support is
+ built in automatically.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Behavior</title>
+
+ <para>
+ The locale settings influence the following SQL features:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Sort order in queries using <literal>ORDER BY</literal> or the standard
+ comparison operators on textual data
+ <indexterm><primary>ORDER BY</primary><secondary>and locales</secondary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <function>upper</function>, <function>lower</function>, and <function>initcap</function>
+ functions
+ <indexterm><primary>upper</primary><secondary>and locales</secondary></indexterm>
+ <indexterm><primary>lower</primary><secondary>and locales</secondary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Pattern matching operators (<literal>LIKE</literal>, <literal>SIMILAR TO</literal>,
+ and POSIX-style regular expressions); locales affect both case
+ insensitive matching and the classification of characters by
+ character-class regular expressions
+ <indexterm><primary>LIKE</primary><secondary>and locales</secondary></indexterm>
+ <indexterm><primary>regular expressions</primary><secondary>and locales</secondary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <function>to_char</function> family of functions
+ <indexterm><primary>to_char</primary><secondary>and locales</secondary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The ability to use indexes with <literal>LIKE</literal> clauses
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The drawback of using locales other than <literal>C</literal> or
+ <literal>POSIX</literal> in <productname>PostgreSQL</productname> is its performance
+ impact. It slows character handling and prevents ordinary indexes
+ from being used by <literal>LIKE</literal>. For this reason use locales
+ only if you actually need them.
+ </para>
+
+ <para>
+ As a workaround to allow <productname>PostgreSQL</productname> to use indexes
+ with <literal>LIKE</literal> clauses under a non-C locale, several custom
+ operator classes exist. These allow the creation of an index that
+ performs a strict character-by-character comparison, ignoring
+ locale comparison rules. Refer to <xref linkend="indexes-opclass"/>
+ for more information. Another approach is to create indexes using
+ the <literal>C</literal> collation, as discussed in
+ <xref linkend="collation"/>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Selecting Locales</title>
+
+ <para>
+ Locales can be selected in different scopes depending on requirements.
+ The above overview showed how locales are specified using
+ <command>initdb</command> to set the defaults for the entire cluster. The
+ following list shows where locales can be selected. Each item provides
+ the defaults for the subsequent items, and each lower item allows
+ overriding the defaults on a finer granularity.
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ As explained above, the environment of the operating system provides the
+ defaults for the locales of a newly initialized database cluster. In
+ many cases, this is enough: If the operating system is configured for
+ the desired language/territory, then
+ <productname>PostgreSQL</productname> will by default also behave
+ according to that locale.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ As shown above, command-line options for <command>initdb</command>
+ specify the locale settings for a newly initialized database cluster.
+ Use this if the operating system does not have the locale configuration
+ you want for your database system.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A locale can be selected separately for each database. The SQL command
+ <command>CREATE DATABASE</command> and its command-line equivalent
+ <command>createdb</command> have options for that. Use this for example
+ if a database cluster houses databases for multiple tenants with
+ different requirements.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Locale settings can be made for individual table columns. This uses an
+ SQL object called <firstterm>collation</firstterm> and is explained in
+ <xref linkend="collation"/>. Use this for example to sort data in
+ different languages or customize the sort order of a particular table.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Finally, locales can be selected for an individual query. Again, this
+ uses SQL collation objects. This could be used to change the sort order
+ based on run-time choices or for ad-hoc experimentation.
+ </para>
+ </listitem>
+ </orderedlist>
+ </sect2>
+
+ <sect2>
+ <title>Locale Providers</title>
+
+ <para>
+ <productname>PostgreSQL</productname> supports multiple <firstterm>locale
+ providers</firstterm>. This specifies which library supplies the locale
+ data. One standard provider name is <literal>libc</literal>, which uses
+ the locales provided by the operating system C library. These are the
+ locales used by most tools provided by the operating system. Another
+ provider is <literal>icu</literal>, which uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can
+ only be used if support for ICU was configured when PostgreSQL was built.
+ </para>
+
+ <para>
+ The commands and tools that select the locale settings, as described
+ above, each have an option to select the locale provider. The examples
+ shown earlier all use the <literal>libc</literal> provider, which is the
+ default. Here is an example to initialize a database cluster using the
+ ICU provider:
+<programlisting>
+initdb --locale-provider=icu --icu-locale=en
+</programlisting>
+ See the description of the respective commands and programs for
+ details. Note that you can mix locale providers at different
+ granularities, for example use <literal>libc</literal> by default for the
+ cluster but have one database that uses the <literal>icu</literal>
+ provider, and then have collation objects using either provider within
+ those databases.
+ </para>
+
+ <para>
+ Which locale provider to use depends on individual requirements. For most
+ basic uses, either provider will give adequate results. For the libc
+ provider, it depends on what the operating system offers; some operating
+ systems are better than others. For advanced uses, ICU offers more locale
+ variants and customization options.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Problems</title>
+
+ <para>
+ If locale support doesn't work according to the explanation above,
+ check that the locale support in your operating system is
+ correctly configured. To check what locales are installed on your
+ system, you can use the command <literal>locale -a</literal> if
+ your operating system provides it.
+ </para>
+
+ <para>
+ Check that <productname>PostgreSQL</productname> is actually using the locale
+ that you think it is. The <envar>LC_COLLATE</envar> and <envar>LC_CTYPE</envar>
+ settings are determined when a database is created, and cannot be
+ changed except by creating a new database. Other locale
+ settings including <envar>LC_MESSAGES</envar> and <envar>LC_MONETARY</envar>
+ are initially determined by the environment the server is started
+ in, but can be changed on-the-fly. You can check the active locale
+ settings using the <command>SHOW</command> command.
+ </para>
+
+ <para>
+ The directory <filename>src/test/locale</filename> in the source
+ distribution contains a test suite for
+ <productname>PostgreSQL</productname>'s locale support.
+ </para>
+
+ <para>
+ Client applications that handle server-side errors by parsing the
+ text of the error message will obviously have problems when the
+ server's messages are in a different language. Authors of such
+ applications are advised to make use of the error code scheme
+ instead.
+ </para>
+
+ <para>
+ Maintaining catalogs of message translations requires the on-going
+ efforts of many volunteers that want to see
+ <productname>PostgreSQL</productname> speak their preferred language well.
+ If messages in your language are currently not available or not fully
+ translated, your assistance would be appreciated. If you want to
+ help, refer to <xref linkend="nls"/> or write to the developers'
+ mailing list.
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="collation">
+ <title>Collation Support</title>
+
+ <indexterm zone="collation"><primary>collation</primary></indexterm>
+
+ <para>
+ The collation feature allows specifying the sort order and character
+ classification behavior of data per-column, or even per-operation.
+ This alleviates the restriction that the
+ <symbol>LC_COLLATE</symbol> and <symbol>LC_CTYPE</symbol> settings
+ of a database cannot be changed after its creation.
+ </para>
+
+ <sect2>
+ <title>Concepts</title>
+
+ <para>
+ Conceptually, every expression of a collatable data type has a
+ collation. (The built-in collatable data types are
+ <type>text</type>, <type>varchar</type>, and <type>char</type>.
+ User-defined base types can also be marked collatable, and of course
+ a <glossterm linkend="glossary-domain">domain</glossterm> over a
+ collatable data type is collatable.) If the
+ expression is a column reference, the collation of the expression is the
+ defined collation of the column. If the expression is a constant, the
+ collation is the default collation of the data type of the
+ constant. The collation of a more complex expression is derived
+ from the collations of its inputs, as described below.
+ </para>
+
+ <para>
+ The collation of an expression can be the <quote>default</quote>
+ collation, which means the locale settings defined for the
+ database. It is also possible for an expression's collation to be
+ indeterminate. In such cases, ordering operations and other
+ operations that need to know the collation will fail.
+ </para>
+
+ <para>
+ When the database system has to perform an ordering or a character
+ classification, it uses the collation of the input expression. This
+ happens, for example, with <literal>ORDER BY</literal> clauses
+ and function or operator calls such as <literal>&lt;</literal>.
+ The collation to apply for an <literal>ORDER BY</literal> clause
+ is simply the collation of the sort key. The collation to apply for a
+ function or operator call is derived from the arguments, as described
+ below. In addition to comparison operators, collations are taken into
+ account by functions that convert between lower and upper case
+ letters, such as <function>lower</function>, <function>upper</function>, and
+ <function>initcap</function>; by pattern matching operators; and by
+ <function>to_char</function> and related functions.
+ </para>
+
+ <para>
+ For a function or operator call, the collation that is derived by
+ examining the argument collations is used at run time for performing
+ the specified operation. If the result of the function or operator
+ call is of a collatable data type, the collation is also used at parse
+ time as the defined collation of the function or operator expression,
+ in case there is a surrounding expression that requires knowledge of
+ its collation.
+ </para>
+
+ <para>
+ The <firstterm>collation derivation</firstterm> of an expression can be
+ implicit or explicit. This distinction affects how collations are
+ combined when multiple different collations appear in an
+ expression. An explicit collation derivation occurs when a
+ <literal>COLLATE</literal> clause is used; all other collation
+ derivations are implicit. When multiple collations need to be
+ combined, for example in a function call, the following rules are
+ used:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If any input expression has an explicit collation derivation, then
+ all explicitly derived collations among the input expressions must be
+ the same, otherwise an error is raised. If any explicitly
+ derived collation is present, that is the result of the
+ collation combination.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Otherwise, all input expressions must have the same implicit
+ collation derivation or the default collation. If any non-default
+ collation is present, that is the result of the collation combination.
+ Otherwise, the result is the default collation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If there are conflicting non-default implicit collations among the
+ input expressions, then the combination is deemed to have indeterminate
+ collation. This is not an error condition unless the particular
+ function being invoked requires knowledge of the collation it should
+ apply. If it does, an error will be raised at run-time.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ For example, consider this table definition:
+<programlisting>
+CREATE TABLE test1 (
+ a text COLLATE "de_DE",
+ b text COLLATE "es_ES",
+ ...
+);
+</programlisting>
+
+ Then in
+<programlisting>
+SELECT a &lt; 'foo' FROM test1;
+</programlisting>
+ the <literal>&lt;</literal> comparison is performed according to
+ <literal>de_DE</literal> rules, because the expression combines an
+ implicitly derived collation with the default collation. But in
+<programlisting>
+SELECT a &lt; ('foo' COLLATE "fr_FR") FROM test1;
+</programlisting>
+ the comparison is performed using <literal>fr_FR</literal> rules,
+ because the explicit collation derivation overrides the implicit one.
+ Furthermore, given
+<programlisting>
+SELECT a &lt; b FROM test1;
+</programlisting>
+ the parser cannot determine which collation to apply, since the
+ <structfield>a</structfield> and <structfield>b</structfield> columns have conflicting
+ implicit collations. Since the <literal>&lt;</literal> operator
+ does need to know which collation to use, this will result in an
+ error. The error can be resolved by attaching an explicit collation
+ specifier to either input expression, thus:
+<programlisting>
+SELECT a &lt; b COLLATE "de_DE" FROM test1;
+</programlisting>
+ or equivalently
+<programlisting>
+SELECT a COLLATE "de_DE" &lt; b FROM test1;
+</programlisting>
+ On the other hand, the structurally similar case
+<programlisting>
+SELECT a || b FROM test1;
+</programlisting>
+ does not result in an error, because the <literal>||</literal> operator
+ does not care about collations: its result is the same regardless
+ of the collation.
+ </para>
+
+ <para>
+ The collation assigned to a function or operator's combined input
+ expressions is also considered to apply to the function or operator's
+ result, if the function or operator delivers a result of a collatable
+ data type. So, in
+<programlisting>
+SELECT * FROM test1 ORDER BY a || 'foo';
+</programlisting>
+ the ordering will be done according to <literal>de_DE</literal> rules.
+ But this query:
+<programlisting>
+SELECT * FROM test1 ORDER BY a || b;
+</programlisting>
+ results in an error, because even though the <literal>||</literal> operator
+ doesn't need to know a collation, the <literal>ORDER BY</literal> clause does.
+ As before, the conflict can be resolved with an explicit collation
+ specifier:
+<programlisting>
+SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="collation-managing">
+ <title>Managing Collations</title>
+
+ <para>
+ A collation is an SQL schema object that maps an SQL name to locales
+ provided by libraries installed in the operating system. A collation
+ definition has a <firstterm>provider</firstterm> that specifies which
+ library supplies the locale data. One standard provider name
+ is <literal>libc</literal>, which uses the locales provided by the
+ operating system C library. These are the locales used by most tools
+ provided by the operating system. Another provider
+ is <literal>icu</literal>, which uses the external
+ ICU<indexterm><primary>ICU</primary></indexterm> library. ICU locales can only be
+ used if support for ICU was configured when PostgreSQL was built.
+ </para>
+
+ <para>
+ A collation object provided by <literal>libc</literal> maps to a
+ combination of <symbol>LC_COLLATE</symbol> and <symbol>LC_CTYPE</symbol>
+ settings, as accepted by the <literal>setlocale()</literal> system library call. (As
+ the name would suggest, the main purpose of a collation is to set
+ <symbol>LC_COLLATE</symbol>, which controls the sort order. But
+ it is rarely necessary in practice to have an
+ <symbol>LC_CTYPE</symbol> setting that is different from
+ <symbol>LC_COLLATE</symbol>, so it is more convenient to collect
+ these under one concept than to create another infrastructure for
+ setting <symbol>LC_CTYPE</symbol> per expression.) Also,
+ a <literal>libc</literal> collation
+ is tied to a character set encoding (see <xref linkend="multibyte"/>).
+ The same collation name may exist for different encodings.
+ </para>
+
+ <para>
+ A collation object provided by <literal>icu</literal> maps to a named
+ collator provided by the ICU library. ICU does not support
+ separate <quote>collate</quote> and <quote>ctype</quote> settings, so
+ they are always the same. Also, ICU collations are independent of the
+ encoding, so there is always only one ICU collation of a given name in
+ a database.
+ </para>
+
+ <sect3>
+ <title>Standard Collations</title>
+
+ <para>
+ On all platforms, the collations named <literal>default</literal>,
+ <literal>C</literal>, and <literal>POSIX</literal> are available. Additional
+ collations may be available depending on operating system support.
+ The <literal>default</literal> collation selects the <symbol>LC_COLLATE</symbol>
+ and <symbol>LC_CTYPE</symbol> values specified at database creation time.
+ The <literal>C</literal> and <literal>POSIX</literal> collations both specify
+ <quote>traditional C</quote> behavior, in which only the ASCII letters
+ <quote><literal>A</literal></quote> through <quote><literal>Z</literal></quote>
+ are treated as letters, and sorting is done strictly by character
+ code byte values.
+ </para>
+
+ <para>
+ Additionally, the SQL standard collation name <literal>ucs_basic</literal>
+ is available for encoding <literal>UTF8</literal>. It is equivalent
+ to <literal>C</literal> and sorts by Unicode code point.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Predefined Collations</title>
+
+ <para>
+ If the operating system provides support for using multiple locales
+ within a single program (<function>newlocale</function> and related functions),
+ or if support for ICU is configured,
+ then when a database cluster is initialized, <command>initdb</command>
+ populates the system catalog <literal>pg_collation</literal> with
+ collations based on all the locales it finds in the operating
+ system at the time.
+ </para>
+
+ <para>
+ To inspect the currently available locales, use the query <literal>SELECT
+ * FROM pg_collation</literal>, or the command <command>\dOS+</command>
+ in <application>psql</application>.
+ </para>
+
+ <sect4>
+ <title>libc Collations</title>
+
+ <para>
+ For example, the operating system might
+ provide a locale named <literal>de_DE.utf8</literal>.
+ <command>initdb</command> would then create a collation named
+ <literal>de_DE.utf8</literal> for encoding <literal>UTF8</literal>
+ that has both <symbol>LC_COLLATE</symbol> and
+ <symbol>LC_CTYPE</symbol> set to <literal>de_DE.utf8</literal>.
+ It will also create a collation with the <literal>.utf8</literal>
+ tag stripped off the name. So you could also use the collation
+ under the name <literal>de_DE</literal>, which is less cumbersome
+ to write and makes the name less encoding-dependent. Note that,
+ nevertheless, the initial set of collation names is
+ platform-dependent.
+ </para>
+
+ <para>
+ The default set of collations provided by <literal>libc</literal> map
+ directly to the locales installed in the operating system, which can be
+ listed using the command <literal>locale -a</literal>. In case
+ a <literal>libc</literal> collation is needed that has different values
+ for <symbol>LC_COLLATE</symbol> and <symbol>LC_CTYPE</symbol>, or if new
+ locales are installed in the operating system after the database system
+ was initialized, then a new collation may be created using
+ the <xref linkend="sql-createcollation"/> command.
+ New operating system locales can also be imported en masse using
+ the <link linkend="functions-admin-collation"><function>pg_import_system_collations()</function></link> function.
+ </para>
+
+ <para>
+ Within any particular database, only collations that use that
+ database's encoding are of interest. Other entries in
+ <literal>pg_collation</literal> are ignored. Thus, a stripped collation
+ name such as <literal>de_DE</literal> can be considered unique
+ within a given database even though it would not be unique globally.
+ Use of the stripped collation names is recommended, since it will
+ make one fewer thing you need to change if you decide to change to
+ another database encoding. Note however that the <literal>default</literal>,
+ <literal>C</literal>, and <literal>POSIX</literal> collations can be used regardless of
+ the database encoding.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> considers distinct collation
+ objects to be incompatible even when they have identical properties.
+ Thus for example,
+<programlisting>
+SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1;
+</programlisting>
+ will draw an error even though the <literal>C</literal> and <literal>POSIX</literal>
+ collations have identical behaviors. Mixing stripped and non-stripped
+ collation names is therefore not recommended.
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>ICU Collations</title>
+
+ <para>
+ With ICU, it is not sensible to enumerate all possible locale names. ICU
+ uses a particular naming system for locales, but there are many more ways
+ to name a locale than there are actually distinct locales.
+ <command>initdb</command> uses the ICU APIs to extract a set of distinct
+ locales to populate the initial set of collations. Collations provided by
+ ICU are created in the SQL environment with names in BCP 47 language tag
+ format, with a <quote>private use</quote>
+ extension <literal>-x-icu</literal> appended, to distinguish them from
+ libc locales.
+ </para>
+
+ <para>
+ Here are some example collations that might be created:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>de-x-icu</literal></term>
+ <listitem>
+ <para>German collation, default variant</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>de-AT-x-icu</literal></term>
+ <listitem>
+ <para>German collation for Austria, default variant</para>
+ <para>
+ (There are also, say, <literal>de-DE-x-icu</literal>
+ or <literal>de-CH-x-icu</literal>, but as of this writing, they are
+ equivalent to <literal>de-x-icu</literal>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>und-x-icu</literal> (for <quote>undefined</quote>)</term>
+ <listitem>
+ <para>
+ ICU <quote>root</quote> collation. Use this to get a reasonable
+ language-agnostic sort order.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Some (less frequently used) encodings are not supported by ICU. When the
+ database encoding is one of these, ICU collation entries
+ in <literal>pg_collation</literal> are ignored. Attempting to use one
+ will draw an error along the lines of <quote>collation "de-x-icu" for
+ encoding "WIN874" does not exist</quote>.
+ </para>
+ </sect4>
+ </sect3>
+
+ <sect3 id="collation-create">
+ <title>Creating New Collation Objects</title>
+
+ <para>
+ If the standard and predefined collations are not sufficient, users can
+ create their own collation objects using the SQL
+ command <xref linkend="sql-createcollation"/>.
+ </para>
+
+ <para>
+ The standard and predefined collations are in the
+ schema <literal>pg_catalog</literal>, like all predefined objects.
+ User-defined collations should be created in user schemas. This also
+ ensures that they are saved by <command>pg_dump</command>.
+ </para>
+
+ <sect4>
+ <title>libc Collations</title>
+
+ <para>
+ New libc collations can be created like this:
+<programlisting>
+CREATE COLLATION german (provider = libc, locale = 'de_DE');
+</programlisting>
+ The exact values that are acceptable for the <literal>locale</literal>
+ clause in this command depend on the operating system. On Unix-like
+ systems, the command <literal>locale -a</literal> will show a list.
+ </para>
+
+ <para>
+ Since the predefined libc collations already include all collations
+ defined in the operating system when the database instance is
+ initialized, it is not often necessary to manually create new ones.
+ Reasons might be if a different naming system is desired (in which case
+ see also <xref linkend="collation-copy"/>) or if the operating system has
+ been upgraded to provide new locale definitions (in which case see
+ also <link linkend="functions-admin-collation"><function>pg_import_system_collations()</function></link>).
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>ICU Collations</title>
+
+ <para>
+ ICU allows collations to be customized beyond the basic language+country
+ set that is preloaded by <command>initdb</command>. Users are encouraged
+ to define their own collation objects that make use of these facilities to
+ suit the sorting behavior to their requirements.
+ See <ulink url="https://unicode-org.github.io/icu/userguide/locale/"></ulink>
+ and <ulink url="https://unicode-org.github.io/icu/userguide/collation/api.html"></ulink> for
+ information on ICU locale naming. The set of acceptable names and
+ attributes depends on the particular ICU version.
+ </para>
+
+ <para>
+ Here are some examples:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk');</literal></term>
+ <term><literal>CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook');</literal></term>
+ <listitem>
+ <para>German collation with phone book collation type</para>
+ <para>
+ The first example selects the ICU locale using a <quote>language
+ tag</quote> per BCP 47. The second example uses the traditional
+ ICU-specific locale syntax. The first style is preferred going
+ forward, but it is not supported by older ICU versions.
+ </para>
+ <para>
+ Note that you can name the collation objects in the SQL environment
+ anything you want. In this example, we follow the naming style that
+ the predefined collations use, which in turn also follow BCP 47, but
+ that is not required for user-defined collations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji');</literal></term>
+ <term><literal>CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji');</literal></term>
+ <listitem>
+ <para>
+ Root collation with Emoji collation type, per Unicode Technical Standard #51
+ </para>
+ <para>
+ Observe how in the traditional ICU locale naming system, the root
+ locale is selected by an empty string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn');</literal></term>
+ <term><literal>CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn');</literal></term>
+ <listitem>
+ <para>
+ Sort Greek letters before Latin ones. (The default is Latin before Greek.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper');</literal></term>
+ <term><literal>CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper');</literal></term>
+ <listitem>
+ <para>
+ Sort upper-case letters before lower-case letters. (The default is
+ lower-case letters first.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn');</literal></term>
+ <term><literal>CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn');</literal></term>
+ <listitem>
+ <para>
+ Combines both of the above options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true');</literal></term>
+ <term><literal>CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes');</literal></term>
+ <listitem>
+ <para>
+ Numeric ordering, sorts sequences of digits by their numeric value,
+ for example: <literal>A-21</literal> &lt; <literal>A-123</literal>
+ (also known as natural sort).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ See <ulink url="https://www.unicode.org/reports/tr35/tr35-collation.html">Unicode
+ Technical Standard #35</ulink>
+ and <ulink url="https://tools.ietf.org/html/bcp47">BCP 47</ulink> for
+ details. The list of possible collation types (<literal>co</literal>
+ subtag) can be found in
+ the <ulink url="https://github.com/unicode-org/cldr/blob/master/common/bcp47/collation.xml">CLDR
+ repository</ulink>.
+ </para>
+
+ <para>
+ Note that while this system allows creating collations that <quote>ignore
+ case</quote> or <quote>ignore accents</quote> or similar (using the
+ <literal>ks</literal> key), in order for such collations to act in a
+ truly case- or accent-insensitive manner, they also need to be declared as not
+ <firstterm>deterministic</firstterm> in <command>CREATE COLLATION</command>;
+ see <xref linkend="collation-nondeterministic"/>.
+ Otherwise, any strings that compare equal according to the collation but
+ are not byte-wise equal will be sorted according to their byte values.
+ </para>
+
+ <note>
+ <para>
+ By design, ICU will accept almost any string as a locale name and match
+ it to the closest locale it can provide, using the fallback procedure
+ described in its documentation. Thus, there will be no direct feedback
+ if a collation specification is composed using features that the given
+ ICU installation does not actually support. It is therefore recommended
+ to create application-level test cases to check that the collation
+ definitions satisfy one's requirements.
+ </para>
+ </note>
+ </sect4>
+
+ <sect4 id="collation-copy">
+ <title>Copying Collations</title>
+
+ <para>
+ The command <xref linkend="sql-createcollation"/> can also be used to
+ create a new collation from an existing collation, which can be useful to
+ be able to use operating-system-independent collation names in
+ applications, create compatibility names, or use an ICU-provided collation
+ under a more readable name. For example:
+<programlisting>
+CREATE COLLATION german FROM "de_DE";
+CREATE COLLATION french FROM "fr-x-icu";
+</programlisting>
+ </para>
+ </sect4>
+ </sect3>
+
+ <sect3 id="collation-nondeterministic">
+ <title>Nondeterministic Collations</title>
+
+ <para>
+ A collation is either <firstterm>deterministic</firstterm> or
+ <firstterm>nondeterministic</firstterm>. A deterministic collation uses
+ deterministic comparisons, which means that it considers strings to be
+ equal only if they consist of the same byte sequence. Nondeterministic
+ comparison may determine strings to be equal even if they consist of
+ different bytes. Typical situations include case-insensitive comparison,
+ accent-insensitive comparison, as well as comparison of strings in
+ different Unicode normal forms. It is up to the collation provider to
+ actually implement such insensitive comparisons; the deterministic flag
+ only determines whether ties are to be broken using bytewise comparison.
+ See also <ulink url="https://www.unicode.org/reports/tr10">Unicode Technical
+ Standard 10</ulink> for more information on the terminology.
+ </para>
+
+ <para>
+ To create a nondeterministic collation, specify the property
+ <literal>deterministic = false</literal> to <command>CREATE
+ COLLATION</command>, for example:
+<programlisting>
+CREATE COLLATION ndcoll (provider = icu, locale = 'und', deterministic = false);
+</programlisting>
+ This example would use the standard Unicode collation in a
+ nondeterministic way. In particular, this would allow strings in
+ different normal forms to be compared correctly. More interesting
+ examples make use of the ICU customization facilities explained above.
+ For example:
+<programlisting>
+CREATE COLLATION case_insensitive (provider = icu, locale = 'und-u-ks-level2', deterministic = false);
+CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-true', deterministic = false);
+</programlisting>
+ </para>
+
+ <para>
+ All standard and predefined collations are deterministic, all
+ user-defined collations are deterministic by default. While
+ nondeterministic collations give a more <quote>correct</quote> behavior,
+ especially when considering the full power of Unicode and its many
+ special cases, they also have some drawbacks. Foremost, their use leads
+ to a performance penalty. Note, in particular, that B-tree cannot use
+ deduplication with indexes that use a nondeterministic collation. Also,
+ certain operations are not possible with nondeterministic collations,
+ such as pattern matching operations. Therefore, they should be used
+ only in cases where they are specifically wanted.
+ </para>
+
+ <tip>
+ <para>
+ To deal with text in different Unicode normalization forms, it is also
+ an option to use the functions/expressions
+ <function>normalize</function> and <literal>is normalized</literal> to
+ preprocess or check the strings, instead of using nondeterministic
+ collations. There are different trade-offs for each approach.
+ </para>
+ </tip>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="multibyte">
+ <title>Character Set Support</title>
+
+ <indexterm zone="multibyte"><primary>character set</primary></indexterm>
+
+ <para>
+ The character set support in <productname>PostgreSQL</productname>
+ allows you to store text in a variety of character sets (also called
+ encodings), including
+ single-byte character sets such as the ISO 8859 series and
+ multiple-byte character sets such as <acronym>EUC</acronym> (Extended Unix
+ Code), UTF-8, and Mule internal code. All supported character sets
+ can be used transparently by clients, but a few are not supported
+ for use within the server (that is, as a server-side encoding).
+ The default character set is selected while
+ initializing your <productname>PostgreSQL</productname> database
+ cluster using <command>initdb</command>. It can be overridden when you
+ create a database, so you can have multiple
+ databases each with a different character set.
+ </para>
+
+ <para>
+ An important restriction, however, is that each database's character set
+ must be compatible with the database's <envar>LC_CTYPE</envar> (character
+ classification) and <envar>LC_COLLATE</envar> (string sort order) locale
+ settings. For <literal>C</literal> or
+ <literal>POSIX</literal> locale, any character set is allowed, but for other
+ libc-provided locales there is only one character set that will work
+ correctly.
+ (On Windows, however, UTF-8 encoding can be used with any locale.)
+ If you have ICU support configured, ICU-provided locales can be used
+ with most but not all server-side encodings.
+ </para>
+
+ <sect2 id="multibyte-charset-supported">
+ <title>Supported Character Sets</title>
+
+ <para>
+ <xref linkend="charset-table"/> shows the character sets available
+ for use in <productname>PostgreSQL</productname>.
+ </para>
+
+ <table id="charset-table">
+ <title><productname>PostgreSQL</productname> Character Sets</title>
+ <tgroup cols="7">
+ <colspec colname="col1" colwidth="3*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <colspec colname="col4" colwidth="1.25*"/>
+ <colspec colname="col5" colwidth="1*"/>
+ <colspec colname="col6" colwidth="1*"/>
+ <colspec colname="col7" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ <entry>Language</entry>
+ <entry>Server?</entry>
+ <entry>ICU?</entry>
+ <!--
+ The Bytes/Char field is populated by looking at the values returned
+ by pg_wchar_table.mblen function for each encoding.
+ -->
+ <entry>Bytes/&zwsp;Char</entry>
+ <entry>Aliases</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>BIG5</literal></entry>
+ <entry>Big Five</entry>
+ <entry>Traditional Chinese</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;2</entry>
+ <entry><literal>WIN950</literal>, <literal>Windows950</literal></entry>
+ </row>
+ <row>
+ <entry><literal>EUC_CN</literal></entry>
+ <entry>Extended UNIX Code-CN</entry>
+ <entry>Simplified Chinese</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1&ndash;3</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>EUC_JP</literal></entry>
+ <entry>Extended UNIX Code-JP</entry>
+ <entry>Japanese</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1&ndash;3</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>EUC_JIS_2004</literal></entry>
+ <entry>Extended UNIX Code-JP, JIS X 0213</entry>
+ <entry>Japanese</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ <entry>1&ndash;3</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>EUC_KR</literal></entry>
+ <entry>Extended UNIX Code-KR</entry>
+ <entry>Korean</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1&ndash;3</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>EUC_TW</literal></entry>
+ <entry>Extended UNIX Code-TW</entry>
+ <entry>Traditional Chinese, Taiwanese</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1&ndash;3</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>GB18030</literal></entry>
+ <entry>National Standard</entry>
+ <entry>Chinese</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;4</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>GBK</literal></entry>
+ <entry>Extended National Standard</entry>
+ <entry>Simplified Chinese</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;2</entry>
+ <entry><literal>WIN936</literal>, <literal>Windows936</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry>ISO 8859-5, <acronym>ECMA</acronym> 113</entry>
+ <entry>Latin/Cyrillic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_6</literal></entry>
+ <entry>ISO 8859-6, <acronym>ECMA</acronym> 114</entry>
+ <entry>Latin/Arabic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_7</literal></entry>
+ <entry>ISO 8859-7, <acronym>ECMA</acronym> 118</entry>
+ <entry>Latin/Greek</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_8</literal></entry>
+ <entry>ISO 8859-8, <acronym>ECMA</acronym> 121</entry>
+ <entry>Latin/Hebrew</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>JOHAB</literal></entry>
+ <entry><acronym>JOHAB</acronym></entry>
+ <entry>Korean (Hangul)</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;3</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><acronym>KOI</acronym>8-R</entry>
+ <entry>Cyrillic (Russian)</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>KOI8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>KOI8U</literal></entry>
+ <entry><acronym>KOI</acronym>8-U</entry>
+ <entry>Cyrillic (Ukrainian)</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN1</literal></entry>
+ <entry>ISO 8859-1, <acronym>ECMA</acronym> 94</entry>
+ <entry>Western European</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO88591</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN2</literal></entry>
+ <entry>ISO 8859-2, <acronym>ECMA</acronym> 94</entry>
+ <entry>Central European</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO88592</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN3</literal></entry>
+ <entry>ISO 8859-3, <acronym>ECMA</acronym> 94</entry>
+ <entry>South European</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO88593</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN4</literal></entry>
+ <entry>ISO 8859-4, <acronym>ECMA</acronym> 94</entry>
+ <entry>North European</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO88594</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN5</literal></entry>
+ <entry>ISO 8859-9, <acronym>ECMA</acronym> 128</entry>
+ <entry>Turkish</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO88599</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN6</literal></entry>
+ <entry>ISO 8859-10, <acronym>ECMA</acronym> 144</entry>
+ <entry>Nordic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO885910</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN7</literal></entry>
+ <entry>ISO 8859-13</entry>
+ <entry>Baltic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO885913</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN8</literal></entry>
+ <entry>ISO 8859-14</entry>
+ <entry>Celtic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO885914</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN9</literal></entry>
+ <entry>ISO 8859-15</entry>
+ <entry>LATIN1 with Euro and accents</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ISO885915</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LATIN10</literal></entry>
+ <entry>ISO 8859-16, <acronym>ASRO</acronym> SR 14111</entry>
+ <entry>Romanian</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ <entry>1</entry>
+ <entry><literal>ISO885916</literal></entry>
+ </row>
+ <row>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry>Mule internal code</entry>
+ <entry>Multilingual Emacs</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ <entry>1&ndash;4</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>SJIS</literal></entry>
+ <entry>Shift JIS</entry>
+ <entry>Japanese</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;2</entry>
+ <entry><literal>Mskanji</literal>, <literal>ShiftJIS</literal>, <literal>WIN932</literal>, <literal>Windows932</literal></entry>
+ </row>
+ <row>
+ <entry><literal>SHIFT_JIS_2004</literal></entry>
+ <entry>Shift JIS, JIS X 0213</entry>
+ <entry>Japanese</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;2</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>SQL_ASCII</literal></entry>
+ <entry>unspecified (see text)</entry>
+ <entry><emphasis>any</emphasis></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>UHC</literal></entry>
+ <entry>Unified Hangul Code</entry>
+ <entry>Korean</entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>1&ndash;2</entry>
+ <entry><literal>WIN949</literal>, <literal>Windows949</literal></entry>
+ </row>
+ <row>
+ <entry><literal>UTF8</literal></entry>
+ <entry>Unicode, 8-bit</entry>
+ <entry><emphasis>all</emphasis></entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1&ndash;4</entry>
+ <entry><literal>Unicode</literal></entry>
+ </row>
+ <row>
+ <entry><literal>WIN866</literal></entry>
+ <entry>Windows CP866</entry>
+ <entry>Cyrillic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ALT</literal></entry>
+ </row>
+ <row>
+ <entry><literal>WIN874</literal></entry>
+ <entry>Windows CP874</entry>
+ <entry>Thai</entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1250</literal></entry>
+ <entry>Windows CP1250</entry>
+ <entry>Central European</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1251</literal></entry>
+ <entry>Windows CP1251</entry>
+ <entry>Cyrillic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>WIN</literal></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1252</literal></entry>
+ <entry>Windows CP1252</entry>
+ <entry>Western European</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1253</literal></entry>
+ <entry>Windows CP1253</entry>
+ <entry>Greek</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1254</literal></entry>
+ <entry>Windows CP1254</entry>
+ <entry>Turkish</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1255</literal></entry>
+ <entry>Windows CP1255</entry>
+ <entry>Hebrew</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1256</literal></entry>
+ <entry>Windows CP1256</entry>
+ <entry>Arabic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1257</literal></entry>
+ <entry>Windows CP1257</entry>
+ <entry>Baltic</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry><literal>WIN1258</literal></entry>
+ <entry>Windows CP1258</entry>
+ <entry>Vietnamese</entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>1</entry>
+ <entry><literal>ABC</literal>, <literal>TCVN</literal>, <literal>TCVN5712</literal>, <literal>VSCII</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Not all client <acronym>API</acronym>s support all the listed character sets. For example, the
+ <productname>PostgreSQL</productname>
+ JDBC driver does not support <literal>MULE_INTERNAL</literal>, <literal>LATIN6</literal>,
+ <literal>LATIN8</literal>, and <literal>LATIN10</literal>.
+ </para>
+
+ <para>
+ The <literal>SQL_ASCII</literal> setting behaves considerably differently
+ from the other settings. When the server character set is
+ <literal>SQL_ASCII</literal>, the server interprets byte values 0&ndash;127
+ according to the ASCII standard, while byte values 128&ndash;255 are taken
+ as uninterpreted characters. No encoding conversion will be done when
+ the setting is <literal>SQL_ASCII</literal>. Thus, this setting is not so
+ much a declaration that a specific encoding is in use, as a declaration
+ of ignorance about the encoding. In most cases, if you are
+ working with any non-ASCII data, it is unwise to use the
+ <literal>SQL_ASCII</literal> setting because
+ <productname>PostgreSQL</productname> will be unable to help you by
+ converting or validating non-ASCII characters.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Setting the Character Set</title>
+
+ <para>
+ <command>initdb</command> defines the default character set (encoding)
+ for a <productname>PostgreSQL</productname> cluster. For example,
+
+<screen>
+initdb -E EUC_JP
+</screen>
+
+ sets the default character set to
+ <literal>EUC_JP</literal> (Extended Unix Code for Japanese). You
+ can use <option>--encoding</option> instead of
+ <option>-E</option> if you prefer longer option strings.
+ If no <option>-E</option> or <option>--encoding</option> option is
+ given, <command>initdb</command> attempts to determine the appropriate
+ encoding to use based on the specified or default locale.
+ </para>
+
+ <para>
+ You can specify a non-default encoding at database creation time,
+ provided that the encoding is compatible with the selected locale:
+
+<screen>
+createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean
+</screen>
+
+ This will create a database named <literal>korean</literal> that
+ uses the character set <literal>EUC_KR</literal>, and locale <literal>ko_KR</literal>.
+ Another way to accomplish this is to use this SQL command:
+
+<programlisting>
+CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
+</programlisting>
+
+ Notice that the above commands specify copying the <literal>template0</literal>
+ database. When copying any other database, the encoding and locale
+ settings cannot be changed from those of the source database, because
+ that might result in corrupt data. For more information see
+ <xref linkend="manage-ag-templatedbs"/>.
+ </para>
+
+ <para>
+ The encoding for a database is stored in the system catalog
+ <literal>pg_database</literal>. You can see it by using the
+ <command>psql</command> <option>-l</option> option or the
+ <command>\l</command> command.
+
+<screen>
+$ <userinput>psql -l</userinput>
+ List of databases
+ Name | Owner | Encoding | Collation | Ctype | Access Privileges
+-----------+----------+-----------+-------------+-------------+-------------------------------------
+ clocaledb | hlinnaka | SQL_ASCII | C | C |
+ englishdb | hlinnaka | UTF8 | en_GB.UTF8 | en_GB.UTF8 |
+ japanese | hlinnaka | UTF8 | ja_JP.UTF8 | ja_JP.UTF8 |
+ korean | hlinnaka | EUC_KR | ko_KR.euckr | ko_KR.euckr |
+ postgres | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 |
+ template0 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
+ template1 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
+(7 rows)
+</screen>
+ </para>
+
+ <important>
+ <para>
+ On most modern operating systems, <productname>PostgreSQL</productname>
+ can determine which character set is implied by the <envar>LC_CTYPE</envar>
+ setting, and it will enforce that only the matching database encoding is
+ used. On older systems it is your responsibility to ensure that you use
+ the encoding expected by the locale you have selected. A mistake in
+ this area is likely to lead to strange behavior of locale-dependent
+ operations such as sorting.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> will allow superusers to create
+ databases with <literal>SQL_ASCII</literal> encoding even when
+ <envar>LC_CTYPE</envar> is not <literal>C</literal> or <literal>POSIX</literal>. As noted
+ above, <literal>SQL_ASCII</literal> does not enforce that the data stored in
+ the database has any particular encoding, and so this choice poses risks
+ of locale-dependent misbehavior. Using this combination of settings is
+ deprecated and may someday be forbidden altogether.
+ </para>
+ </important>
+ </sect2>
+
+ <sect2>
+ <title>Automatic Character Set Conversion Between Server and Client</title>
+
+ <para>
+ <productname>PostgreSQL</productname> supports automatic character
+ set conversion between server and client for many combinations of
+ character sets (<xref linkend="multibyte-conversions-supported"/>
+ shows which ones).
+ </para>
+
+ <para>
+ To enable automatic character set conversion, you have to
+ tell <productname>PostgreSQL</productname> the character set
+ (encoding) you would like to use in the client. There are several
+ ways to accomplish this:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Using the <command>\encoding</command> command in
+ <application>psql</application>.
+ <command>\encoding</command> allows you to change client
+ encoding on the fly. For
+ example, to change the encoding to <literal>SJIS</literal>, type:
+
+<programlisting>
+\encoding SJIS
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <application>libpq</application> (<xref linkend="libpq-control"/>) has functions to control the client encoding.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using <command>SET client_encoding TO</command>.
+
+ Setting the client encoding can be done with this SQL command:
+
+<programlisting>
+SET CLIENT_ENCODING TO '<replaceable>value</replaceable>';
+</programlisting>
+
+ Also you can use the standard SQL syntax <literal>SET NAMES</literal>
+ for this purpose:
+
+<programlisting>
+SET NAMES '<replaceable>value</replaceable>';
+</programlisting>
+
+ To query the current client encoding:
+
+<programlisting>
+SHOW client_encoding;
+</programlisting>
+
+ To return to the default encoding:
+
+<programlisting>
+RESET client_encoding;
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using <envar>PGCLIENTENCODING</envar>. If the environment variable
+ <envar>PGCLIENTENCODING</envar> is defined in the client's
+ environment, that client encoding is automatically selected
+ when a connection to the server is made. (This can
+ subsequently be overridden using any of the other methods
+ mentioned above.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using the configuration variable <xref
+ linkend="guc-client-encoding"/>. If the
+ <varname>client_encoding</varname> variable is set, that client
+ encoding is automatically selected when a connection to the
+ server is made. (This can subsequently be overridden using any
+ of the other methods mentioned above.)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ If the conversion of a particular character is not possible
+ &mdash; suppose you chose <literal>EUC_JP</literal> for the
+ server and <literal>LATIN1</literal> for the client, and some
+ Japanese characters are returned that do not have a representation in
+ <literal>LATIN1</literal> &mdash; an error is reported.
+ </para>
+
+ <para>
+ If the client character set is defined as <literal>SQL_ASCII</literal>,
+ encoding conversion is disabled, regardless of the server's character
+ set. (However, if the server's character set is
+ not <literal>SQL_ASCII</literal>, the server will still check that
+ incoming data is valid for that encoding; so the net effect is as
+ though the client character set were the same as the server's.)
+ Just as for the server, use of <literal>SQL_ASCII</literal> is unwise
+ unless you are working with all-ASCII data.
+ </para>
+ </sect2>
+
+ <sect2 id="multibyte-conversions-supported">
+ <title>Available Character Set Conversions</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows conversion between any
+ two character sets for which a conversion function is listed in the
+ <link linkend="catalog-pg-conversion"><structname>pg_conversion</structname></link>
+ system catalog. <productname>PostgreSQL</productname> comes with
+ some predefined conversions, as summarized in
+ <xref linkend="multibyte-translation-table"/> and shown in more
+ detail in <xref linkend="builtin-conversions-table"/>. You can
+ create a new conversion using the SQL command
+ <xref linkend="sql-createconversion"/>. (To be used for automatic
+ client/server conversions, a conversion must be marked
+ as <quote>default</quote> for its character set pair.)
+ </para>
+
+ <table id="multibyte-translation-table">
+ <title>Built-in Client/Server Character Set Conversions</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Server Character Set</entry>
+ <entry>Available Client Character Sets</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>BIG5</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>EUC_CN</literal></entry>
+ <entry><emphasis>EUC_CN</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>EUC_JP</literal></entry>
+ <entry><emphasis>EUC_JP</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>SJIS</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>EUC_JIS_2004</literal></entry>
+ <entry><emphasis>EUC_JIS_2004</emphasis>,
+ <literal>SHIFT_JIS_2004</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>EUC_KR</literal></entry>
+ <entry><emphasis>EUC_KR</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>EUC_TW</literal></entry>
+ <entry><emphasis>EUC_TW</emphasis>,
+ <literal>BIG5</literal>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>GB18030</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>GBK</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry><emphasis>ISO_8859_5</emphasis>,
+ <literal>KOI8R</literal>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>,
+ <literal>WIN866</literal>,
+ <literal>WIN1251</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_6</literal></entry>
+ <entry><emphasis>ISO_8859_6</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_7</literal></entry>
+ <entry><emphasis>ISO_8859_7</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>ISO_8859_8</literal></entry>
+ <entry><emphasis>ISO_8859_8</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>JOHAB</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><emphasis>KOI8R</emphasis>,
+ <literal>ISO_8859_5</literal>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>,
+ <literal>WIN866</literal>,
+ <literal>WIN1251</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>KOI8U</literal></entry>
+ <entry><emphasis>KOI8U</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN1</literal></entry>
+ <entry><emphasis>LATIN1</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN2</literal></entry>
+ <entry><emphasis>LATIN2</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>,
+ <literal>WIN1250</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN3</literal></entry>
+ <entry><emphasis>LATIN3</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN4</literal></entry>
+ <entry><emphasis>LATIN4</emphasis>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN5</literal></entry>
+ <entry><emphasis>LATIN5</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN6</literal></entry>
+ <entry><emphasis>LATIN6</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN7</literal></entry>
+ <entry><emphasis>LATIN7</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN8</literal></entry>
+ <entry><emphasis>LATIN8</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN9</literal></entry>
+ <entry><emphasis>LATIN9</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LATIN10</literal></entry>
+ <entry><emphasis>LATIN10</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><emphasis>MULE_INTERNAL</emphasis>,
+ <literal>BIG5</literal>,
+ <literal>EUC_CN</literal>,
+ <literal>EUC_JP</literal>,
+ <literal>EUC_KR</literal>,
+ <literal>EUC_TW</literal>,
+ <literal>ISO_8859_5</literal>,
+ <literal>KOI8R</literal>,
+ <literal>LATIN1</literal> to <literal>LATIN4</literal>,
+ <literal>SJIS</literal>,
+ <literal>WIN866</literal>,
+ <literal>WIN1250</literal>,
+ <literal>WIN1251</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>SJIS</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>SHIFT_JIS_2004</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>SQL_ASCII</literal></entry>
+ <entry><emphasis>any (no conversion will be performed)</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>UHC</literal></entry>
+ <entry><emphasis>not supported as a server encoding</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>UTF8</literal></entry>
+ <entry><emphasis>all supported encodings</emphasis>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN866</literal></entry>
+ <entry><emphasis>WIN866</emphasis>,
+ <literal>ISO_8859_5</literal>,
+ <literal>KOI8R</literal>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>,
+ <literal>WIN1251</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN874</literal></entry>
+ <entry><emphasis>WIN874</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1250</literal></entry>
+ <entry><emphasis>WIN1250</emphasis>,
+ <literal>LATIN2</literal>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1251</literal></entry>
+ <entry><emphasis>WIN1251</emphasis>,
+ <literal>ISO_8859_5</literal>,
+ <literal>KOI8R</literal>,
+ <literal>MULE_INTERNAL</literal>,
+ <literal>UTF8</literal>,
+ <literal>WIN866</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1252</literal></entry>
+ <entry><emphasis>WIN1252</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1253</literal></entry>
+ <entry><emphasis>WIN1253</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1254</literal></entry>
+ <entry><emphasis>WIN1254</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1255</literal></entry>
+ <entry><emphasis>WIN1255</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1256</literal></entry>
+ <entry><emphasis>WIN1256</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1257</literal></entry>
+ <entry><emphasis>WIN1257</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>WIN1258</literal></entry>
+ <entry><emphasis>WIN1258</emphasis>,
+ <literal>UTF8</literal>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="builtin-conversions-table">
+ <title>All Built-in Character Set Conversions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Conversion Name
+ <footnote>
+ <para>
+ The conversion names follow a standard naming scheme: The
+ official name of the source encoding with all
+ non-alphanumeric characters replaced by underscores, followed
+ by <literal>_to_</literal>, followed by the similarly processed
+ destination encoding name. Therefore, these names sometimes
+ deviate from the customary encoding names shown in
+ <xref linkend="charset-table"/>.
+ </para>
+ </footnote>
+ </entry>
+ <entry>Source Encoding</entry>
+ <entry>Destination Encoding</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>big5_to_euc_tw</literal></entry>
+ <entry><literal>BIG5</literal></entry>
+ <entry><literal>EUC_TW</literal></entry>
+ </row>
+ <row>
+ <entry><literal>big5_to_mic</literal></entry>
+ <entry><literal>BIG5</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>big5_to_utf8</literal></entry>
+ <entry><literal>BIG5</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_cn_to_mic</literal></entry>
+ <entry><literal>EUC_CN</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_cn_to_utf8</literal></entry>
+ <entry><literal>EUC_CN</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_jp_to_mic</literal></entry>
+ <entry><literal>EUC_JP</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_jp_to_sjis</literal></entry>
+ <entry><literal>EUC_JP</literal></entry>
+ <entry><literal>SJIS</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_jp_to_utf8</literal></entry>
+ <entry><literal>EUC_JP</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_kr_to_mic</literal></entry>
+ <entry><literal>EUC_KR</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_kr_to_utf8</literal></entry>
+ <entry><literal>EUC_KR</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_tw_to_big5</literal></entry>
+ <entry><literal>EUC_TW</literal></entry>
+ <entry><literal>BIG5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_tw_to_mic</literal></entry>
+ <entry><literal>EUC_TW</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_tw_to_utf8</literal></entry>
+ <entry><literal>EUC_TW</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>gb18030_to_utf8</literal></entry>
+ <entry><literal>GB18030</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>gbk_to_utf8</literal></entry>
+ <entry><literal>GBK</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_10_to_utf8</literal></entry>
+ <entry><literal>LATIN6</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_13_to_utf8</literal></entry>
+ <entry><literal>LATIN7</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_14_to_utf8</literal></entry>
+ <entry><literal>LATIN8</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_15_to_utf8</literal></entry>
+ <entry><literal>LATIN9</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_16_to_utf8</literal></entry>
+ <entry><literal>LATIN10</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_1_to_mic</literal></entry>
+ <entry><literal>LATIN1</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_1_to_utf8</literal></entry>
+ <entry><literal>LATIN1</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_2_to_mic</literal></entry>
+ <entry><literal>LATIN2</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_2_to_utf8</literal></entry>
+ <entry><literal>LATIN2</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_2_to_windows_1250</literal></entry>
+ <entry><literal>LATIN2</literal></entry>
+ <entry><literal>WIN1250</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_3_to_mic</literal></entry>
+ <entry><literal>LATIN3</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_3_to_utf8</literal></entry>
+ <entry><literal>LATIN3</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_4_to_mic</literal></entry>
+ <entry><literal>LATIN4</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_4_to_utf8</literal></entry>
+ <entry><literal>LATIN4</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_5_to_koi8_r</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_5_to_mic</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_5_to_utf8</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_5_to_windows_1251</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_5_to_windows_866</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_6_to_utf8</literal></entry>
+ <entry><literal>ISO_8859_6</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_7_to_utf8</literal></entry>
+ <entry><literal>ISO_8859_7</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_8_to_utf8</literal></entry>
+ <entry><literal>ISO_8859_8</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>iso_8859_9_to_utf8</literal></entry>
+ <entry><literal>LATIN5</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>johab_to_utf8</literal></entry>
+ <entry><literal>JOHAB</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>koi8_r_to_iso_8859_5</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>koi8_r_to_mic</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>koi8_r_to_utf8</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>koi8_r_to_windows_1251</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ </row>
+ <row>
+ <entry><literal>koi8_r_to_windows_866</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ </row>
+ <row>
+ <entry><literal>koi8_u_to_utf8</literal></entry>
+ <entry><literal>KOI8U</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_big5</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>BIG5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_euc_cn</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>EUC_CN</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_euc_jp</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>EUC_JP</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_euc_kr</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>EUC_KR</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_euc_tw</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>EUC_TW</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_iso_8859_1</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>LATIN1</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_iso_8859_2</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>LATIN2</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_iso_8859_3</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>LATIN3</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_iso_8859_4</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>LATIN4</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_iso_8859_5</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_koi8_r</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_sjis</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>SJIS</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_windows_1250</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>WIN1250</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_windows_1251</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mic_to_windows_866</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ </row>
+ <row>
+ <entry><literal>sjis_to_euc_jp</literal></entry>
+ <entry><literal>SJIS</literal></entry>
+ <entry><literal>EUC_JP</literal></entry>
+ </row>
+ <row>
+ <entry><literal>sjis_to_mic</literal></entry>
+ <entry><literal>SJIS</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>sjis_to_utf8</literal></entry>
+ <entry><literal>SJIS</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1258_to_utf8</literal></entry>
+ <entry><literal>WIN1258</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>uhc_to_utf8</literal></entry>
+ <entry><literal>UHC</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_big5</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>BIG5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_euc_cn</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>EUC_CN</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_euc_jp</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>EUC_JP</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_euc_kr</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>EUC_KR</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_euc_tw</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>EUC_TW</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_gb18030</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>GB18030</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_gbk</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>GBK</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_1</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN1</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_10</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN6</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_13</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN7</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_14</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_15</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN9</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_16</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN10</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_2</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN2</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_3</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN3</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_4</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN4</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_5</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_6</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>ISO_8859_6</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_7</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>ISO_8859_7</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_8</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>ISO_8859_8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_iso_8859_9</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>LATIN5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_johab</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>JOHAB</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_koi8_r</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_koi8_u</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>KOI8U</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_sjis</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>SJIS</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1258</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1258</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_uhc</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>UHC</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1250</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1250</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1251</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1252</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1252</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1253</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1253</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1254</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1254</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1255</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1255</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1256</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1256</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_1257</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN1257</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_866</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_windows_874</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>WIN874</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1250_to_iso_8859_2</literal></entry>
+ <entry><literal>WIN1250</literal></entry>
+ <entry><literal>LATIN2</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1250_to_mic</literal></entry>
+ <entry><literal>WIN1250</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1250_to_utf8</literal></entry>
+ <entry><literal>WIN1250</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1251_to_iso_8859_5</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1251_to_koi8_r</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1251_to_mic</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1251_to_utf8</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1251_to_windows_866</literal></entry>
+ <entry><literal>WIN1251</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1252_to_utf8</literal></entry>
+ <entry><literal>WIN1252</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_1256_to_utf8</literal></entry>
+ <entry><literal>WIN1256</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_866_to_iso_8859_5</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ <entry><literal>ISO_8859_5</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_866_to_koi8_r</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ <entry><literal>KOI8R</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_866_to_mic</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ <entry><literal>MULE_INTERNAL</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_866_to_utf8</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_866_to_windows_1251</literal></entry>
+ <entry><literal>WIN866</literal></entry>
+ <entry><literal>WIN</literal></entry>
+ </row>
+ <row>
+ <entry><literal>windows_874_to_utf8</literal></entry>
+ <entry><literal>WIN874</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_jis_2004_to_utf8</literal></entry>
+ <entry><literal>EUC_JIS_2004</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_euc_jis_2004</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>EUC_JIS_2004</literal></entry>
+ </row>
+ <row>
+ <entry><literal>shift_jis_2004_to_utf8</literal></entry>
+ <entry><literal>SHIFT_JIS_2004</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ </row>
+ <row>
+ <entry><literal>utf8_to_shift_jis_2004</literal></entry>
+ <entry><literal>UTF8</literal></entry>
+ <entry><literal>SHIFT_JIS_2004</literal></entry>
+ </row>
+ <row>
+ <entry><literal>euc_jis_2004_to_shift_jis_2004</literal></entry>
+ <entry><literal>EUC_JIS_2004</literal></entry>
+ <entry><literal>SHIFT_JIS_2004</literal></entry>
+ </row>
+ <row>
+ <entry><literal>shift_jis_2004_to_euc_jis_2004</literal></entry>
+ <entry><literal>SHIFT_JIS_2004</literal></entry>
+ <entry><literal>EUC_JIS_2004</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Further Reading</title>
+
+ <para>
+ These are good sources to start learning about various kinds of encoding
+ systems.
+
+ <variablelist>
+ <varlistentry>
+ <term><citetitle>CJKV Information Processing: Chinese, Japanese, Korean &amp; Vietnamese Computing</citetitle></term>
+
+ <listitem>
+ <para>
+ Contains detailed explanations of <literal>EUC_JP</literal>,
+ <literal>EUC_CN</literal>, <literal>EUC_KR</literal>,
+ <literal>EUC_TW</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><ulink url="https://www.unicode.org/"></ulink></term>
+
+ <listitem>
+ <para>
+ The web site of the Unicode Consortium.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><ulink url="https://tools.ietf.org/html/rfc3629">RFC 3629</ulink></term>
+
+ <listitem>
+ <para>
+ <acronym>UTF</acronym>-8 (8-bit UCS/Unicode Transformation
+ Format) is defined here.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/citext.sgml b/doc/src/sgml/citext.sgml
new file mode 100644
index 0000000..5986601
--- /dev/null
+++ b/doc/src/sgml/citext.sgml
@@ -0,0 +1,293 @@
+<!-- doc/src/sgml/citext.sgml -->
+
+<sect1 id="citext" xreflabel="citext">
+ <title>citext</title>
+
+ <indexterm zone="citext">
+ <primary>citext</primary>
+ </indexterm>
+
+ <para>
+ The <filename>citext</filename> module provides a case-insensitive
+ character string type, <type>citext</type>. Essentially, it internally calls
+ <function>lower</function> when comparing values. Otherwise, it behaves almost
+ exactly like <type>text</type>.
+ </para>
+
+ <tip>
+ <para>
+ Consider using <firstterm>nondeterministic collations</firstterm> (see
+ <xref linkend="collation-nondeterministic"/>) instead of this module. They
+ can be used for case-insensitive comparisons, accent-insensitive
+ comparisons, and other combinations, and they handle more Unicode special
+ cases correctly.
+ </para>
+ </tip>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Rationale</title>
+
+ <para>
+ The standard approach to doing case-insensitive matches
+ in <productname>PostgreSQL</productname> has been to use the <function>lower</function>
+ function when comparing values, for example
+
+<programlisting>
+SELECT * FROM tab WHERE lower(col) = LOWER(?);
+</programlisting>
+ </para>
+
+ <para>
+ This works reasonably well, but has a number of drawbacks:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ It makes your SQL statements verbose, and you always have to remember to
+ use <function>lower</function> on both the column and the query value.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It won't use an index, unless you create a functional index using
+ <function>lower</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If you declare a column as <literal>UNIQUE</literal> or <literal>PRIMARY
+ KEY</literal>, the implicitly generated index is case-sensitive. So it's
+ useless for case-insensitive searches, and it won't enforce
+ uniqueness case-insensitively.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The <type>citext</type> data type allows you to eliminate calls
+ to <function>lower</function> in SQL queries, and allows a primary key to
+ be case-insensitive. <type>citext</type> is locale-aware, just
+ like <type>text</type>, which means that the matching of upper case and
+ lower case characters is dependent on the rules of
+ the database's <literal>LC_CTYPE</literal> setting. Again, this behavior is
+ identical to the use of <function>lower</function> in queries. But because it's
+ done transparently by the data type, you don't have to remember to do
+ anything special in your queries.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>How to Use It</title>
+
+ <para>
+ Here's a simple example of usage:
+
+<programlisting>
+CREATE TABLE users (
+ nick CITEXT PRIMARY KEY,
+ pass TEXT NOT NULL
+);
+
+INSERT INTO users VALUES ( 'larry', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'Tom', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'Damian', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'NEAL', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'Bj&oslash;rn', sha256(random()::text::bytea) );
+
+SELECT * FROM users WHERE nick = 'Larry';
+</programlisting>
+
+ The <command>SELECT</command> statement will return one tuple, even though
+ the <structfield>nick</structfield> column was set to <literal>larry</literal> and the query
+ was for <literal>Larry</literal>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>String Comparison Behavior</title>
+
+ <para>
+ <type>citext</type> performs comparisons by converting each string to lower
+ case (as though <function>lower</function> were called) and then comparing the
+ results normally. Thus, for example, two strings are considered equal
+ if <function>lower</function> would produce identical results for them.
+ </para>
+
+ <para>
+ In order to emulate a case-insensitive collation as closely as possible,
+ there are <type>citext</type>-specific versions of a number of string-processing
+ operators and functions. So, for example, the regular expression
+ operators <literal>~</literal> and <literal>~*</literal> exhibit the same behavior when
+ applied to <type>citext</type>: they both match case-insensitively.
+ The same is true
+ for <literal>!~</literal> and <literal>!~*</literal>, as well as for the
+ <literal>LIKE</literal> operators <literal>~~</literal> and <literal>~~*</literal>, and
+ <literal>!~~</literal> and <literal>!~~*</literal>. If you'd like to match
+ case-sensitively, you can cast the operator's arguments to <type>text</type>.
+ </para>
+
+ <para>
+ Similarly, all of the following functions perform matching
+ case-insensitively if their arguments are <type>citext</type>:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <function>regexp_match()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>regexp_matches()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>regexp_replace()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>regexp_split_to_array()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>regexp_split_to_table()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>replace()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>split_part()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>strpos()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>translate()</function>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ For the regexp functions, if you want to match case-sensitively, you can
+ specify the <quote>c</quote> flag to force a case-sensitive match. Otherwise,
+ you must cast to <type>text</type> before using one of these functions if
+ you want case-sensitive behavior.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Limitations</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <type>citext</type>'s case-folding behavior depends on
+ the <literal>LC_CTYPE</literal> setting of your database. How it compares
+ values is therefore determined when the database is created.
+ It is not truly
+ case-insensitive in the terms defined by the Unicode standard.
+ Effectively, what this means is that, as long as you're happy with your
+ collation, you should be happy with <type>citext</type>'s comparisons. But
+ if you have data in different languages stored in your database, users
+ of one language may find their query results are not as expected if the
+ collation is for another language.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ As of <productname>PostgreSQL</productname> 9.1, you can attach a
+ <literal>COLLATE</literal> specification to <type>citext</type> columns or data
+ values. Currently, <type>citext</type> operators will honor a non-default
+ <literal>COLLATE</literal> specification while comparing case-folded strings,
+ but the initial folding to lower case is always done according to the
+ database's <literal>LC_CTYPE</literal> setting (that is, as though
+ <literal>COLLATE "default"</literal> were given). This may be changed in a
+ future release so that both steps follow the input <literal>COLLATE</literal>
+ specification.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <type>citext</type> is not as efficient as <type>text</type> because the
+ operator functions and the B-tree comparison functions must make copies
+ of the data and convert it to lower case for comparisons. Also, only
+ <type>text</type> can support B-Tree deduplication. However,
+ <type>citext</type> is slightly more efficient than using
+ <function>lower</function> to get case-insensitive matching.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <type>citext</type> doesn't help much if you need data to compare
+ case-sensitively in some contexts and case-insensitively in other
+ contexts. The standard answer is to use the <type>text</type> type and
+ manually use the <function>lower</function> function when you need to compare
+ case-insensitively; this works all right if case-insensitive comparison
+ is needed only infrequently. If you need case-insensitive behavior most
+ of the time and case-sensitive infrequently, consider storing the data
+ as <type>citext</type> and explicitly casting the column to <type>text</type>
+ when you want case-sensitive comparison. In either situation, you will
+ need two indexes if you want both types of searches to be fast.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The schema containing the <type>citext</type> operators must be
+ in the current <varname>search_path</varname> (typically <literal>public</literal>);
+ if it is not, the normal case-sensitive <type>text</type> operators
+ will be invoked instead.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The approach of lower-casing strings for comparison does not handle some
+ Unicode special cases correctly, for example when one upper-case letter
+ has two lower-case letter equivalents. Unicode distinguishes between
+ <firstterm>case mapping</firstterm> and <firstterm>case
+ folding</firstterm> for this reason. Use nondeterministic collations
+ instead of <type>citext</type> to handle that correctly.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ David E. Wheeler <email>david@kineticode.com</email>
+ </para>
+
+ <para>
+ Inspired by the original <type>citext</type> module by Donald Fraser.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
new file mode 100644
index 0000000..4337599
--- /dev/null
+++ b/doc/src/sgml/client-auth.sgml
@@ -0,0 +1,2244 @@
+<!-- doc/src/sgml/client-auth.sgml -->
+
+<chapter id="client-authentication">
+ <title>Client Authentication</title>
+
+ <indexterm zone="client-authentication">
+ <primary>client authentication</primary>
+ </indexterm>
+
+ <para>
+ When a client application connects to the database server, it
+ specifies which <productname>PostgreSQL</productname> database user name it
+ wants to connect as, much the same way one logs into a Unix computer
+ as a particular user. Within the SQL environment the active database
+ user name determines access privileges to database objects &mdash; see
+ <xref linkend="user-manag"/> for more information. Therefore, it is
+ essential to restrict which database users can connect.
+ </para>
+
+ <note>
+ <para>
+ As explained in <xref linkend="user-manag"/>,
+ <productname>PostgreSQL</productname> actually does privilege
+ management in terms of <quote>roles</quote>. In this chapter, we
+ consistently use <firstterm>database user</firstterm> to mean <quote>role with the
+ <literal>LOGIN</literal> privilege</quote>.
+ </para>
+ </note>
+
+ <para>
+ <firstterm>Authentication</firstterm> is the process by which the
+ database server establishes the identity of the client, and by
+ extension determines whether the client application (or the user
+ who runs the client application) is permitted to connect with the
+ database user name that was requested.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> offers a number of different
+ client authentication methods. The method used to authenticate a
+ particular client connection can be selected on the basis of
+ (client) host address, database, and user.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> database user names are logically
+ separate from user names of the operating system in which the server
+ runs. If all the users of a particular server also have accounts on
+ the server's machine, it makes sense to assign database user names
+ that match their operating system user names. However, a server that
+ accepts remote connections might have many database users who have no local
+ operating system
+ account, and in such cases there need be no connection between
+ database user names and OS user names.
+ </para>
+
+ <sect1 id="auth-pg-hba-conf">
+ <title>The <filename>pg_hba.conf</filename> File</title>
+
+ <indexterm zone="auth-pg-hba-conf">
+ <primary>pg_hba.conf</primary>
+ </indexterm>
+
+ <para>
+ Client authentication is controlled by a configuration file,
+ which traditionally is named
+ <filename>pg_hba.conf</filename> and is stored in the database
+ cluster's data directory.
+ (<acronym>HBA</acronym> stands for host-based authentication.) A default
+ <filename>pg_hba.conf</filename> file is installed when the data
+ directory is initialized by <xref linkend="app-initdb"/>. It is
+ possible to place the authentication configuration file elsewhere,
+ however; see the <xref linkend="guc-hba-file"/> configuration parameter.
+ </para>
+
+ <para>
+ The general format of the <filename>pg_hba.conf</filename> file is
+ a set of records, one per line. Blank lines are ignored, as is any
+ text after the <literal>#</literal> comment character.
+ A record can be continued onto the next line by ending the line with
+ a backslash. (Backslashes are not special except at the end of a line.)
+ A record is made
+ up of a number of fields which are separated by spaces and/or tabs.
+ Fields can contain white space if the field value is double-quoted.
+ Quoting one of the keywords in a database, user, or address field (e.g.,
+ <literal>all</literal> or <literal>replication</literal>) makes the word lose its special
+ meaning, and just match a database, user, or host with that name.
+ Backslash line continuation applies even within quoted text or comments.
+ </para>
+
+ <para>
+ Each record specifies a connection type, a client IP address range
+ (if relevant for the connection type), a database name, a user name,
+ and the authentication method to be used for connections matching
+ these parameters. The first record with a matching connection type,
+ client address, requested database, and user name is used to perform
+ authentication. There is no <quote>fall-through</quote> or
+ <quote>backup</quote>: if one record is chosen and the authentication
+ fails, subsequent records are not considered. If no record matches,
+ access is denied.
+ </para>
+
+ <para>
+ A record can have several formats:
+<synopsis>
+local <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>address</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+host <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostssl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostgssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+hostnogssenc <replaceable>database</replaceable> <replaceable>user</replaceable> <replaceable>IP-address</replaceable> <replaceable>IP-mask</replaceable> <replaceable>auth-method</replaceable> <optional><replaceable>auth-options</replaceable></optional>
+</synopsis>
+ The meaning of the fields is as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>local</literal></term>
+ <listitem>
+ <para>
+ This record matches connection attempts using Unix-domain
+ sockets. Without a record of this type, Unix-domain socket
+ connections are disallowed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>host</literal></term>
+ <listitem>
+ <para>
+ This record matches connection attempts made using TCP/IP.
+ <literal>host</literal> records match
+ <acronym>SSL</acronym> or non-<acronym>SSL</acronym> connection
+ attempts as well as <acronym>GSSAPI</acronym> encrypted or
+ non-<acronym>GSSAPI</acronym> encrypted connection attempts.
+ </para>
+ <note>
+ <para>
+ Remote TCP/IP connections will not be possible unless
+ the server is started with an appropriate value for the
+ <xref linkend="guc-listen-addresses"/> configuration parameter,
+ since the default behavior is to listen for TCP/IP connections
+ only on the local loopback address <literal>localhost</literal>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>hostssl</literal></term>
+ <listitem>
+ <para>
+ This record matches connection attempts made using TCP/IP,
+ but only when the connection is made with <acronym>SSL</acronym>
+ encryption.
+ </para>
+
+ <para>
+ To make use of this option the server must be built with
+ <acronym>SSL</acronym> support. Furthermore,
+ <acronym>SSL</acronym> must be enabled
+ by setting the <xref linkend="guc-ssl"/> configuration parameter (see
+ <xref linkend="ssl-tcp"/> for more information).
+ Otherwise, the <literal>hostssl</literal> record is ignored except for
+ logging a warning that it cannot match any connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>hostnossl</literal></term>
+ <listitem>
+ <para>
+ This record type has the opposite behavior of <literal>hostssl</literal>;
+ it only matches connection attempts made over
+ TCP/IP that do not use <acronym>SSL</acronym>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>hostgssenc</literal></term>
+ <listitem>
+ <para>
+ This record matches connection attempts made using TCP/IP,
+ but only when the connection is made with <acronym>GSSAPI</acronym>
+ encryption.
+ </para>
+
+ <para>
+ To make use of this option the server must be built with
+ <acronym>GSSAPI</acronym> support. Otherwise,
+ the <literal>hostgssenc</literal> record is ignored except for logging
+ a warning that it cannot match any connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>hostnogssenc</literal></term>
+ <listitem>
+ <para>
+ This record type has the opposite behavior of <literal>hostgssenc</literal>;
+ it only matches connection attempts made over
+ TCP/IP that do not use <acronym>GSSAPI</acronym> encryption.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>database</replaceable></term>
+ <listitem>
+ <para>
+ Specifies which database name(s) this record matches. The value
+ <literal>all</literal> specifies that it matches all databases.
+ The value <literal>sameuser</literal> specifies that the record
+ matches if the requested database has the same name as the
+ requested user. The value <literal>samerole</literal> specifies that
+ the requested user must be a member of the role with the same
+ name as the requested database. (<literal>samegroup</literal> is an
+ obsolete but still accepted spelling of <literal>samerole</literal>.)
+ Superusers are not considered to be members of a role for the
+ purposes of <literal>samerole</literal> unless they are explicitly
+ members of the role, directly or indirectly, and not just by
+ virtue of being a superuser.
+ The value <literal>replication</literal> specifies that the record
+ matches if a physical replication connection is requested, however, it
+ doesn't match with logical replication connections. Note that physical
+ replication connections do not specify any particular database whereas
+ logical replication connections do specify it.
+ Otherwise, this is the name of
+ a specific <productname>PostgreSQL</productname> database.
+ Multiple database names can be supplied by separating them with
+ commas. A separate file containing database names can be specified by
+ preceding the file name with <literal>@</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>user</replaceable></term>
+ <listitem>
+ <para>
+ Specifies which database user name(s) this record
+ matches. The value <literal>all</literal> specifies that it
+ matches all users. Otherwise, this is either the name of a specific
+ database user, or a group name preceded by <literal>+</literal>.
+ (Recall that there is no real distinction between users and groups
+ in <productname>PostgreSQL</productname>; a <literal>+</literal> mark really means
+ <quote>match any of the roles that are directly or indirectly members
+ of this role</quote>, while a name without a <literal>+</literal> mark matches
+ only that specific role.) For this purpose, a superuser is only
+ considered to be a member of a role if they are explicitly a member
+ of the role, directly or indirectly, and not just by virtue of
+ being a superuser.
+ Multiple user names can be supplied by separating them with commas.
+ A separate file containing user names can be specified by preceding the
+ file name with <literal>@</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>address</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the client machine address(es) that this record
+ matches. This field can contain either a host name, an IP
+ address range, or one of the special key words mentioned below.
+ </para>
+
+ <para>
+ An IP address range is specified using standard numeric notation
+ for the range's starting address, then a slash (<literal>/</literal>)
+ and a <acronym>CIDR</acronym> mask length. The mask
+ length indicates the number of high-order bits of the client
+ IP address that must match. Bits to the right of this should
+ be zero in the given IP address.
+ There must not be any white space between the IP address, the
+ <literal>/</literal>, and the CIDR mask length.
+ </para>
+
+ <para>
+ Typical examples of an IPv4 address range specified this way are
+ <literal>172.20.143.89/32</literal> for a single host, or
+ <literal>172.20.143.0/24</literal> for a small network, or
+ <literal>10.6.0.0/16</literal> for a larger one.
+ An IPv6 address range might look like <literal>::1/128</literal>
+ for a single host (in this case the IPv6 loopback address) or
+ <literal>fe80::7a31:c1ff:0000:0000/96</literal> for a small
+ network.
+ <literal>0.0.0.0/0</literal> represents all
+ IPv4 addresses, and <literal>::0/0</literal> represents
+ all IPv6 addresses.
+ To specify a single host, use a mask length of 32 for IPv4 or
+ 128 for IPv6. In a network address, do not omit trailing zeroes.
+ </para>
+
+ <para>
+ An entry given in IPv4 format will match only IPv4 connections,
+ and an entry given in IPv6 format will match only IPv6 connections,
+ even if the represented address is in the IPv4-in-IPv6 range.
+ Note that entries in IPv6 format will be rejected if the system's
+ C library does not have support for IPv6 addresses.
+ </para>
+
+ <para>
+ You can also write <literal>all</literal> to match any IP address,
+ <literal>samehost</literal> to match any of the server's own IP
+ addresses, or <literal>samenet</literal> to match any address in any
+ subnet that the server is directly connected to.
+ </para>
+
+ <para>
+ If a host name is specified (anything that is not an IP address
+ range or a special key word is treated as a host name),
+ that name is compared with the result of a reverse name
+ resolution of the client's IP address (e.g., reverse DNS
+ lookup, if DNS is used). Host name comparisons are case
+ insensitive. If there is a match, then a forward name
+ resolution (e.g., forward DNS lookup) is performed on the host
+ name to check whether any of the addresses it resolves to are
+ equal to the client's IP address. If both directions match,
+ then the entry is considered to match. (The host name that is
+ used in <filename>pg_hba.conf</filename> should be the one that
+ address-to-name resolution of the client's IP address returns,
+ otherwise the line won't be matched. Some host name databases
+ allow associating an IP address with multiple host names, but
+ the operating system will only return one host name when asked
+ to resolve an IP address.)
+ </para>
+
+ <para>
+ A host name specification that starts with a dot
+ (<literal>.</literal>) matches a suffix of the actual host
+ name. So <literal>.example.com</literal> would match
+ <literal>foo.example.com</literal> (but not just
+ <literal>example.com</literal>).
+ </para>
+
+ <para>
+ When host names are specified
+ in <filename>pg_hba.conf</filename>, you should make sure that
+ name resolution is reasonably fast. It can be of advantage to
+ set up a local name resolution cache such
+ as <command>nscd</command>. Also, you may wish to enable the
+ configuration parameter <varname>log_hostname</varname> to see
+ the client's host name instead of the IP address in the log.
+ </para>
+
+ <para>
+ These fields do not apply to <literal>local</literal> records.
+ </para>
+
+ <note>
+ <para>
+ Users sometimes wonder why host names are handled
+ in this seemingly complicated way, with two name resolutions
+ including a reverse lookup of the client's IP address. This
+ complicates use of the feature in case the client's reverse DNS
+ entry is not set up or yields some undesirable host name.
+ It is done primarily for efficiency: this way, a connection attempt
+ requires at most two resolver lookups, one reverse and one forward.
+ If there is a resolver problem with some address, it becomes only
+ that client's problem. A hypothetical alternative
+ implementation that only did forward lookups would have to
+ resolve every host name mentioned in
+ <filename>pg_hba.conf</filename> during every connection attempt.
+ That could be quite slow if many names are listed.
+ And if there is a resolver problem with one of the host names,
+ it becomes everyone's problem.
+ </para>
+
+ <para>
+ Also, a reverse lookup is necessary to implement the suffix
+ matching feature, because the actual client host name needs to
+ be known in order to match it against the pattern.
+ </para>
+
+ <para>
+ Note that this behavior is consistent with other popular
+ implementations of host name-based access control, such as the
+ Apache HTTP Server and TCP Wrappers.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>IP-address</replaceable></term>
+ <term><replaceable>IP-mask</replaceable></term>
+ <listitem>
+ <para>
+ These two fields can be used as an alternative to the
+ <replaceable>IP-address</replaceable><literal>/</literal><replaceable>mask-length</replaceable>
+ notation. Instead of
+ specifying the mask length, the actual mask is specified in a
+ separate column. For example, <literal>255.0.0.0</literal> represents an IPv4
+ CIDR mask length of 8, and <literal>255.255.255.255</literal> represents a
+ CIDR mask length of 32.
+ </para>
+
+ <para>
+ These fields do not apply to <literal>local</literal> records.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>auth-method</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the authentication method to use when a connection matches
+ this record. The possible choices are summarized here; details
+ are in <xref linkend="auth-methods"/>. All the options
+ are lower case and treated case sensitively, so even acronyms like
+ <literal>ldap</literal> must be specified as lower case.
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>trust</literal></term>
+ <listitem>
+ <para>
+ Allow the connection unconditionally. This method
+ allows anyone that can connect to the
+ <productname>PostgreSQL</productname> database server to login as
+ any <productname>PostgreSQL</productname> user they wish,
+ without the need for a password or any other authentication. See <xref
+ linkend="auth-trust"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>reject</literal></term>
+ <listitem>
+ <para>
+ Reject the connection unconditionally. This is useful for
+ <quote>filtering out</quote> certain hosts from a group, for example a
+ <literal>reject</literal> line could block a specific host from connecting,
+ while a later line allows the remaining hosts in a specific
+ network to connect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>scram-sha-256</literal></term>
+ <listitem>
+ <para>
+ Perform SCRAM-SHA-256 authentication to verify the user's
+ password. See <xref linkend="auth-password"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>md5</literal></term>
+ <listitem>
+ <para>
+ Perform SCRAM-SHA-256 or MD5 authentication to verify the
+ user's password. See <xref linkend="auth-password"/>
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>password</literal></term>
+ <listitem>
+ <para>
+ Require the client to supply an unencrypted password for
+ authentication.
+ Since the password is sent in clear text over the
+ network, this should not be used on untrusted networks.
+ See <xref linkend="auth-password"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>gss</literal></term>
+ <listitem>
+ <para>
+ Use GSSAPI to authenticate the user. This is only
+ available for TCP/IP connections. See <xref
+ linkend="gssapi-auth"/> for details. It can be used in conjunction
+ with GSSAPI encryption.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sspi</literal></term>
+ <listitem>
+ <para>
+ Use SSPI to authenticate the user. This is only
+ available on Windows. See <xref
+ linkend="sspi-auth"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ident</literal></term>
+ <listitem>
+ <para>
+ Obtain the operating system user name of the client
+ by contacting the ident server on the client
+ and check if it matches the requested database user name.
+ Ident authentication can only be used on TCP/IP
+ connections. When specified for local connections, peer
+ authentication will be used instead.
+ See <xref linkend="auth-ident"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>peer</literal></term>
+ <listitem>
+ <para>
+ Obtain the client's operating system user name from the operating
+ system and check if it matches the requested database user name.
+ This is only available for local connections.
+ See <xref linkend="auth-peer"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ldap</literal></term>
+ <listitem>
+ <para>
+ Authenticate using an <acronym>LDAP</acronym> server. See <xref
+ linkend="auth-ldap"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>radius</literal></term>
+ <listitem>
+ <para>
+ Authenticate using a RADIUS server. See <xref
+ linkend="auth-radius"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>cert</literal></term>
+ <listitem>
+ <para>
+ Authenticate using SSL client certificates. See
+ <xref linkend="auth-cert"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>pam</literal></term>
+ <listitem>
+ <para>
+ Authenticate using the Pluggable Authentication Modules
+ (PAM) service provided by the operating system. See <xref
+ linkend="auth-pam"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bsd</literal></term>
+ <listitem>
+ <para>
+ Authenticate using the BSD Authentication service provided by the
+ operating system. See <xref linkend="auth-bsd"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>auth-options</replaceable></term>
+ <listitem>
+ <para>
+ After the <replaceable>auth-method</replaceable> field, there can be field(s) of
+ the form <replaceable>name</replaceable><literal>=</literal><replaceable>value</replaceable> that
+ specify options for the authentication method. Details about which
+ options are available for which authentication methods appear below.
+ </para>
+
+ <para>
+ In addition to the method-specific options listed below, there is a
+ method-independent authentication option <literal>clientcert</literal>, which
+ can be specified in any <literal>hostssl</literal> record.
+ This option can be set to <literal>verify-ca</literal> or
+ <literal>verify-full</literal>. Both options require the client
+ to present a valid (trusted) SSL certificate, while
+ <literal>verify-full</literal> additionally enforces that the
+ <literal>cn</literal> (Common Name) in the certificate matches
+ the username or an applicable mapping.
+ This behavior is similar to the <literal>cert</literal> authentication
+ method (see <xref linkend="auth-cert"/>) but enables pairing
+ the verification of client certificates with any authentication
+ method that supports <literal>hostssl</literal> entries.
+ </para>
+ <para>
+ On any record using client certificate authentication (i.e. one
+ using the <literal>cert</literal> authentication method or one
+ using the <literal>clientcert</literal> option), you can specify
+ which part of the client certificate credentials to match using
+ the <literal>clientname</literal> option. This option can have one
+ of two values. If you specify <literal>clientname=CN</literal>, which
+ is the default, the username is matched against the certificate's
+ <literal>Common Name (CN)</literal>. If instead you specify
+ <literal>clientname=DN</literal> the username is matched against the
+ entire <literal>Distinguished Name (DN)</literal> of the certificate.
+ This option is probably best used in conjunction with a username map.
+ The comparison is done with the <literal>DN</literal> in
+ <ulink url="https://tools.ietf.org/html/rfc2253">RFC 2253</ulink>
+ format. To see the <literal>DN</literal> of a client certificate
+ in this format, do
+<programlisting>
+openssl x509 -in myclient.crt -noout --subject -nameopt RFC2253 | sed "s/^subject=//"
+</programlisting>
+ Care needs to be taken when using this option, especially when using
+ regular expression matching against the <literal>DN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Files included by <literal>@</literal> constructs are read as lists of names,
+ which can be separated by either whitespace or commas. Comments are
+ introduced by <literal>#</literal>, just as in
+ <filename>pg_hba.conf</filename>, and nested <literal>@</literal> constructs are
+ allowed. Unless the file name following <literal>@</literal> is an absolute
+ path, it is taken to be relative to the directory containing the
+ referencing file.
+ </para>
+
+ <para>
+ Since the <filename>pg_hba.conf</filename> records are examined
+ sequentially for each connection attempt, the order of the records is
+ significant. Typically, earlier records will have tight connection
+ match parameters and weaker authentication methods, while later
+ records will have looser match parameters and stronger authentication
+ methods. For example, one might wish to use <literal>trust</literal>
+ authentication for local TCP/IP connections but require a password for
+ remote TCP/IP connections. In this case a record specifying
+ <literal>trust</literal> authentication for connections from 127.0.0.1 would
+ appear before a record specifying password authentication for a wider
+ range of allowed client IP addresses.
+ </para>
+
+ <para>
+ The <filename>pg_hba.conf</filename> file is read on start-up and when
+ the main server process receives a
+ <systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
+ signal. If you edit the file on an
+ active system, you will need to signal the postmaster
+ (using <literal>pg_ctl reload</literal>, calling the SQL function
+ <function>pg_reload_conf()</function>, or using <literal>kill
+ -HUP</literal>) to make it re-read the file.
+ </para>
+
+ <note>
+ <para>
+ The preceding statement is not true on Microsoft Windows: there, any
+ changes in the <filename>pg_hba.conf</filename> file are immediately
+ applied by subsequent new connections.
+ </para>
+ </note>
+
+ <para>
+ The system view
+ <link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link>
+ can be helpful for pre-testing changes to the <filename>pg_hba.conf</filename>
+ file, or for diagnosing problems if loading of the file did not have the
+ desired effects. Rows in the view with
+ non-null <structfield>error</structfield> fields indicate problems in the
+ corresponding lines of the file.
+ </para>
+
+ <tip>
+ <para>
+ To connect to a particular database, a user must not only pass the
+ <filename>pg_hba.conf</filename> checks, but must have the
+ <literal>CONNECT</literal> privilege for the database. If you wish to
+ restrict which users can connect to which databases, it's usually
+ easier to control this by granting/revoking <literal>CONNECT</literal> privilege
+ than to put the rules in <filename>pg_hba.conf</filename> entries.
+ </para>
+ </tip>
+
+ <para>
+ Some examples of <filename>pg_hba.conf</filename> entries are shown in
+ <xref linkend="example-pg-hba.conf"/>. See the next section for details on the
+ different authentication methods.
+ </para>
+
+ <example id="example-pg-hba.conf">
+ <title>Example <filename>pg_hba.conf</filename> Entries</title>
+<programlisting>
+# Allow any user on the local system to connect to any database with
+# any database user name using Unix-domain sockets (the default for local
+# connections).
+#
+# TYPE DATABASE USER ADDRESS METHOD
+local all all trust
+
+# The same using local loopback TCP/IP connections.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all 127.0.0.1/32 trust
+
+# The same as the previous line, but using a separate netmask column
+#
+# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
+host all all 127.0.0.1 255.255.255.255 trust
+
+# The same over IPv6.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all ::1/128 trust
+
+# The same using a host name (would typically cover both IPv4 and IPv6).
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all localhost trust
+
+# Allow any user from any host with IP address 192.168.93.x to connect
+# to database "postgres" as the same user name that ident reports for
+# the connection (typically the operating system user name).
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host postgres all 192.168.93.0/24 ident
+
+# Allow any user from host 192.168.12.10 to connect to database
+# "postgres" if the user's password is correctly supplied.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host postgres all 192.168.12.10/32 scram-sha-256
+
+# Allow any user from hosts in the example.com domain to connect to
+# any database if the user's password is correctly supplied.
+#
+# Require SCRAM authentication for most users, but make an exception
+# for user 'mike', who uses an older client that doesn't support SCRAM
+# authentication.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all mike .example.com md5
+host all all .example.com scram-sha-256
+
+# In the absence of preceding "host" lines, these three lines will
+# reject all connections from 192.168.54.1 (since that entry will be
+# matched first), but allow GSSAPI-encrypted connections from anywhere else
+# on the Internet. The zero mask causes no bits of the host IP address to
+# be considered, so it matches any host. Unencrypted GSSAPI connections
+# (which "fall through" to the third line since "hostgssenc" only matches
+# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all 192.168.54.1/32 reject
+hostgssenc all all 0.0.0.0/0 gss
+host all all 192.168.12.10/32 gss
+
+# Allow users from 192.168.x.x hosts to connect to any database, if
+# they pass the ident check. If, for example, ident says the user is
+# "bryanh" and he requests to connect as PostgreSQL user "guest1", the
+# connection is allowed if there is an entry in pg_ident.conf for map
+# "omicron" that says "bryanh" is allowed to connect as "guest1".
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all 192.168.0.0/16 ident map=omicron
+
+# If these are the only three lines for local connections, they will
+# allow local users to connect only to their own databases (databases
+# with the same name as their database user name) except for administrators
+# and members of role "support", who can connect to all databases. The file
+# $PGDATA/admins contains a list of names of administrators. Passwords
+# are required in all cases.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+local sameuser all md5
+local all @admins md5
+local all +support md5
+
+# The last two lines above can be combined into a single line:
+local all @admins,+support md5
+
+# The database column can also use lists and file names:
+local db1,db2,@demodbs all md5
+</programlisting>
+ </example>
+ </sect1>
+
+ <sect1 id="auth-username-maps">
+ <title>User Name Maps</title>
+
+ <indexterm zone="auth-username-maps">
+ <primary>User name maps</primary>
+ </indexterm>
+
+ <para>
+ When using an external authentication system such as Ident or GSSAPI,
+ the name of the operating system user that initiated the connection
+ might not be the same as the database user (role) that is to be used.
+ In this case, a user name map can be applied to map the operating system
+ user name to a database user. To use user name mapping, specify
+ <literal>map</literal>=<replaceable>map-name</replaceable>
+ in the options field in <filename>pg_hba.conf</filename>. This option is
+ supported for all authentication methods that receive external user names.
+ Since different mappings might be needed for different connections,
+ the name of the map to be used is specified in the
+ <replaceable>map-name</replaceable> parameter in <filename>pg_hba.conf</filename>
+ to indicate which map to use for each individual connection.
+ </para>
+
+ <para>
+ User name maps are defined in the ident map file, which by default is named
+ <filename>pg_ident.conf</filename><indexterm><primary>pg_ident.conf</primary></indexterm>
+ and is stored in the
+ cluster's data directory. (It is possible to place the map file
+ elsewhere, however; see the <xref linkend="guc-ident-file"/>
+ configuration parameter.)
+ The ident map file contains lines of the general form:
+<synopsis>
+<replaceable>map-name</replaceable> <replaceable>system-username</replaceable> <replaceable>database-username</replaceable>
+</synopsis>
+ Comments, whitespace and line continuations are handled in the same way as in
+ <filename>pg_hba.conf</filename>. The
+ <replaceable>map-name</replaceable> is an arbitrary name that will be used to
+ refer to this mapping in <filename>pg_hba.conf</filename>. The other
+ two fields specify an operating system user name and a matching
+ database user name. The same <replaceable>map-name</replaceable> can be
+ used repeatedly to specify multiple user-mappings within a single map.
+ </para>
+ <para>
+ There is no restriction regarding how many database users a given
+ operating system user can correspond to, nor vice versa. Thus, entries
+ in a map should be thought of as meaning <quote>this operating system
+ user is allowed to connect as this database user</quote>, rather than
+ implying that they are equivalent. The connection will be allowed if
+ there is any map entry that pairs the user name obtained from the
+ external authentication system with the database user name that the
+ user has requested to connect as.
+ </para>
+ <para>
+ If the <replaceable>system-username</replaceable> field starts with a slash (<literal>/</literal>),
+ the remainder of the field is treated as a regular expression.
+ (See <xref linkend="posix-syntax-details"/> for details of
+ <productname>PostgreSQL</productname>'s regular expression syntax.) The regular
+ expression can include a single capture, or parenthesized subexpression,
+ which can then be referenced in the <replaceable>database-username</replaceable>
+ field as <literal>\1</literal> (backslash-one). This allows the mapping of
+ multiple user names in a single line, which is particularly useful for
+ simple syntax substitutions. For example, these entries
+<programlisting>
+mymap /^(.*)@mydomain\.com$ \1
+mymap /^(.*)@otherdomain\.com$ guest
+</programlisting>
+ will remove the domain part for users with system user names that end with
+ <literal>@mydomain.com</literal>, and allow any user whose system name ends with
+ <literal>@otherdomain.com</literal> to log in as <literal>guest</literal>.
+ </para>
+
+ <tip>
+ <para>
+ Keep in mind that by default, a regular expression can match just part of
+ a string. It's usually wise to use <literal>^</literal> and <literal>$</literal>, as
+ shown in the above example, to force the match to be to the entire
+ system user name.
+ </para>
+ </tip>
+
+ <para>
+ The <filename>pg_ident.conf</filename> file is read on start-up and
+ when the main server process receives a
+ <systemitem>SIGHUP</systemitem><indexterm><primary>SIGHUP</primary></indexterm>
+ signal. If you edit the file on an
+ active system, you will need to signal the postmaster
+ (using <literal>pg_ctl reload</literal>, calling the SQL function
+ <function>pg_reload_conf()</function>, or using <literal>kill
+ -HUP</literal>) to make it re-read the file.
+ </para>
+
+ <para>
+ The system view
+ <link linkend="view-pg-ident-file-mappings"><structname>pg_ident_file_mappings</structname></link>
+ can be helpful for pre-testing changes to the
+ <filename>pg_ident.conf</filename> file, or for diagnosing problems if
+ loading of the file did not have the desired effects. Rows in the view with
+ non-null <structfield>error</structfield> fields indicate problems in the
+ corresponding lines of the file.
+ </para>
+
+ <para>
+ A <filename>pg_ident.conf</filename> file that could be used in
+ conjunction with the <filename>pg_hba.conf</filename> file in <xref
+ linkend="example-pg-hba.conf"/> is shown in <xref
+ linkend="example-pg-ident.conf"/>. In this example, anyone
+ logged in to a machine on the 192.168 network that does not have the
+ operating system user name <literal>bryanh</literal>, <literal>ann</literal>, or
+ <literal>robert</literal> would not be granted access. Unix user
+ <literal>robert</literal> would only be allowed access when he tries to
+ connect as <productname>PostgreSQL</productname> user <literal>bob</literal>, not
+ as <literal>robert</literal> or anyone else. <literal>ann</literal> would
+ only be allowed to connect as <literal>ann</literal>. User
+ <literal>bryanh</literal> would be allowed to connect as either
+ <literal>bryanh</literal> or as <literal>guest1</literal>.
+ </para>
+
+ <example id="example-pg-ident.conf">
+ <title>An Example <filename>pg_ident.conf</filename> File</title>
+<programlisting>
+# MAPNAME SYSTEM-USERNAME PG-USERNAME
+
+omicron bryanh bryanh
+omicron ann ann
+# bob has user name robert on these machines
+omicron robert bob
+# bryanh can also connect as guest1
+omicron bryanh guest1
+</programlisting>
+ </example>
+ </sect1>
+
+ <sect1 id="auth-methods">
+ <title>Authentication Methods</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides various methods for
+ authenticating users:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <link linkend="auth-trust">Trust authentication</link>, which
+ simply trusts that users are who they say they are.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-password">Password authentication</link>, which
+ requires that users send a password.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="gssapi-auth">GSSAPI authentication</link>, which
+ relies on a GSSAPI-compatible security library. Typically this is
+ used to access an authentication server such as a Kerberos or
+ Microsoft Active Directory server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="sspi-auth">SSPI authentication</link>, which
+ uses a Windows-specific protocol similar to GSSAPI.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-ident">Ident authentication</link>, which
+ relies on an <quote>Identification Protocol</quote>
+ (<ulink url="https://tools.ietf.org/html/rfc1413">RFC 1413</ulink>)
+ service on the client's machine. (On local Unix-socket connections,
+ this is treated as peer authentication.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-peer">Peer authentication</link>, which
+ relies on operating system facilities to identify the process at the
+ other end of a local connection. This is not supported for remote
+ connections.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-ldap">LDAP authentication</link>, which
+ relies on an LDAP authentication server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-radius">RADIUS authentication</link>, which
+ relies on a RADIUS authentication server.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-cert">Certificate authentication</link>, which
+ requires an SSL connection and authenticates users by checking the
+ SSL certificate they send.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-pam">PAM authentication</link>, which
+ relies on a PAM (Pluggable Authentication Modules) library.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="auth-bsd">BSD authentication</link>, which
+ relies on the BSD Authentication framework (currently available
+ only on OpenBSD).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Peer authentication is usually recommendable for local connections,
+ though trust authentication might be sufficient in some circumstances.
+ Password authentication is the easiest choice for remote connections.
+ All the other options require some kind of external security
+ infrastructure (usually an authentication server or a certificate
+ authority for issuing SSL certificates), or are platform-specific.
+ </para>
+
+ <para>
+ The following sections describe each of these authentication methods
+ in more detail.
+ </para>
+ </sect1>
+
+ <sect1 id="auth-trust">
+ <title>Trust Authentication</title>
+
+ <para>
+ When <literal>trust</literal> authentication is specified,
+ <productname>PostgreSQL</productname> assumes that anyone who can
+ connect to the server is authorized to access the database with
+ whatever database user name they specify (even superuser names).
+ Of course, restrictions made in the <literal>database</literal> and
+ <literal>user</literal> columns still apply.
+ This method should only be used when there is adequate
+ operating-system-level protection on connections to the server.
+ </para>
+
+ <para>
+ <literal>trust</literal> authentication is appropriate and very
+ convenient for local connections on a single-user workstation. It
+ is usually <emphasis>not</emphasis> appropriate by itself on a multiuser
+ machine. However, you might be able to use <literal>trust</literal> even
+ on a multiuser machine, if you restrict access to the server's
+ Unix-domain socket file using file-system permissions. To do this, set the
+ <varname>unix_socket_permissions</varname> (and possibly
+ <varname>unix_socket_group</varname>) configuration parameters as
+ described in <xref linkend="runtime-config-connection"/>. Or you
+ could set the <varname>unix_socket_directories</varname>
+ configuration parameter to place the socket file in a suitably
+ restricted directory.
+ </para>
+
+ <para>
+ Setting file-system permissions only helps for Unix-socket connections.
+ Local TCP/IP connections are not restricted by file-system permissions.
+ Therefore, if you want to use file-system permissions for local security,
+ remove the <literal>host ... 127.0.0.1 ...</literal> line from
+ <filename>pg_hba.conf</filename>, or change it to a
+ non-<literal>trust</literal> authentication method.
+ </para>
+
+ <para>
+ <literal>trust</literal> authentication is only suitable for TCP/IP connections
+ if you trust every user on every machine that is allowed to connect
+ to the server by the <filename>pg_hba.conf</filename> lines that specify
+ <literal>trust</literal>. It is seldom reasonable to use <literal>trust</literal>
+ for any TCP/IP connections other than those from <systemitem>localhost</systemitem> (127.0.0.1).
+ </para>
+
+ </sect1>
+
+ <sect1 id="auth-password">
+ <title>Password Authentication</title>
+
+ <indexterm>
+ <primary>MD5</primary>
+ </indexterm>
+ <indexterm>
+ <primary>SCRAM</primary>
+ </indexterm>
+ <indexterm>
+ <primary>password</primary>
+ <secondary>authentication</secondary>
+ </indexterm>
+
+ <para>
+ There are several password-based authentication methods. These methods
+ operate similarly but differ in how the users' passwords are stored on the
+ server and how the password provided by a client is sent across the
+ connection.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>scram-sha-256</literal></term>
+ <listitem>
+ <para>
+ The method <literal>scram-sha-256</literal> performs SCRAM-SHA-256
+ authentication, as described in
+ <ulink url="https://tools.ietf.org/html/rfc7677">RFC 7677</ulink>. It
+ is a challenge-response scheme that prevents password sniffing on
+ untrusted connections and supports storing passwords on the server in a
+ cryptographically hashed form that is thought to be secure.
+ </para>
+
+ <para>
+ This is the most secure of the currently provided methods, but it is
+ not supported by older client libraries.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>md5</literal></term>
+ <listitem>
+ <para>
+ The method <literal>md5</literal> uses a custom less secure challenge-response
+ mechanism. It prevents password sniffing and avoids storing passwords
+ on the server in plain text but provides no protection if an attacker
+ manages to steal the password hash from the server. Also, the MD5 hash
+ algorithm is nowadays no longer considered secure against determined
+ attacks.
+ </para>
+
+ <para>
+ The <literal>md5</literal> method cannot be used with
+ the <xref linkend="guc-db-user-namespace"/> feature.
+ </para>
+
+ <para>
+ To ease transition from the <literal>md5</literal> method to the newer
+ SCRAM method, if <literal>md5</literal> is specified as a method
+ in <filename>pg_hba.conf</filename> but the user's password on the
+ server is encrypted for SCRAM (see below), then SCRAM-based
+ authentication will automatically be chosen instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>password</literal></term>
+ <listitem>
+ <para>
+ The method <literal>password</literal> sends the password in clear-text and is
+ therefore vulnerable to password <quote>sniffing</quote> attacks. It should
+ always be avoided if possible. If the connection is protected by SSL
+ encryption then <literal>password</literal> can be used safely, though.
+ (Though SSL certificate authentication might be a better choice if one
+ is depending on using SSL).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ <productname>PostgreSQL</productname> database passwords are
+ separate from operating system user passwords. The password for
+ each database user is stored in the <literal>pg_authid</literal> system
+ catalog. Passwords can be managed with the SQL commands
+ <xref linkend="sql-createrole"/> and
+ <xref linkend="sql-alterrole"/>,
+ e.g., <userinput>CREATE ROLE foo WITH LOGIN PASSWORD 'secret'</userinput>,
+ or the <application>psql</application>
+ command <literal>\password</literal>.
+ If no password has been set up for a user, the stored password
+ is null and password authentication will always fail for that user.
+ </para>
+
+ <para>
+ The availability of the different password-based authentication methods
+ depends on how a user's password on the server is encrypted (or hashed,
+ more accurately). This is controlled by the configuration
+ parameter <xref linkend="guc-password-encryption"/> at the time the
+ password is set. If a password was encrypted using
+ the <literal>scram-sha-256</literal> setting, then it can be used for the
+ authentication methods <literal>scram-sha-256</literal>
+ and <literal>password</literal> (but password transmission will be in
+ plain text in the latter case). The authentication method
+ specification <literal>md5</literal> will automatically switch to using
+ the <literal>scram-sha-256</literal> method in this case, as explained
+ above, so it will also work. If a password was encrypted using
+ the <literal>md5</literal> setting, then it can be used only for
+ the <literal>md5</literal> and <literal>password</literal> authentication
+ method specifications (again, with the password transmitted in plain text
+ in the latter case). (Previous PostgreSQL releases supported storing the
+ password on the server in plain text. This is no longer possible.) To
+ check the currently stored password hashes, see the system
+ catalog <literal>pg_authid</literal>.
+ </para>
+
+ <para>
+ To upgrade an existing installation from <literal>md5</literal>
+ to <literal>scram-sha-256</literal>, after having ensured that all client
+ libraries in use are new enough to support SCRAM,
+ set <literal>password_encryption = 'scram-sha-256'</literal>
+ in <filename>postgresql.conf</filename>, make all users set new passwords,
+ and change the authentication method specifications
+ in <filename>pg_hba.conf</filename> to <literal>scram-sha-256</literal>.
+ </para>
+ </sect1>
+
+ <sect1 id="gssapi-auth">
+ <title>GSSAPI Authentication</title>
+
+ <indexterm zone="gssapi-auth">
+ <primary>GSSAPI</primary>
+ </indexterm>
+
+ <para>
+ <productname>GSSAPI</productname> is an industry-standard protocol
+ for secure authentication defined in
+ <ulink url="https://tools.ietf.org/html/rfc2743">RFC 2743</ulink>.
+ <productname>PostgreSQL</productname>
+ supports <productname>GSSAPI</productname> for authentication,
+ communications encryption, or both.
+ <productname>GSSAPI</productname> provides automatic authentication
+ (single sign-on) for systems that support it. The authentication itself is
+ secure. If <productname>GSSAPI</productname> encryption
+ or <acronym>SSL</acronym> encryption is
+ used, the data sent along the database connection will be encrypted;
+ otherwise, it will not.
+ </para>
+
+ <para>
+ GSSAPI support has to be enabled when <productname>PostgreSQL</productname> is built;
+ see <xref linkend="installation"/> for more information.
+ </para>
+
+ <para>
+ When <productname>GSSAPI</productname> uses
+ <productname>Kerberos</productname>, it uses a standard service
+ principal (authentication identity) name in the format
+ <literal><replaceable>servicename</replaceable>/<replaceable>hostname</replaceable>@<replaceable>realm</replaceable></literal>.
+ The principal name used by a particular installation is not encoded in
+ the <productname>PostgreSQL</productname> server in any way; rather it
+ is specified in the <firstterm>keytab</firstterm> file that the server
+ reads to determine its identity. If multiple principals are listed in
+ the keytab file, the server will accept any one of them.
+ The server's realm name is the preferred realm specified in the Kerberos
+ configuration file(s) accessible to the server.
+ </para>
+
+ <para>
+ When connecting, the client must know the principal name of the server
+ it intends to connect to. The <replaceable>servicename</replaceable>
+ part of the principal is ordinarily <literal>postgres</literal>,
+ but another value can be selected via <application>libpq</application>'s
+ <xref linkend="libpq-connect-krbsrvname"/> connection parameter.
+ The <replaceable>hostname</replaceable> part is the fully qualified
+ host name that <application>libpq</application> is told to connect to.
+ The realm name is the preferred realm specified in the Kerberos
+ configuration file(s) accessible to the client.
+ </para>
+
+ <para>
+ The client will also have a principal name for its own identity
+ (and it must have a valid ticket for this principal). To
+ use <productname>GSSAPI</productname> for authentication, the client
+ principal must be associated with
+ a <productname>PostgreSQL</productname> database user name.
+ The <filename>pg_ident.conf</filename> configuration file can be used
+ to map principals to user names; for example,
+ <literal>pgusername@realm</literal> could be mapped to just <literal>pgusername</literal>.
+ Alternatively, you can use the full <literal>username@realm</literal> principal as
+ the role name in <productname>PostgreSQL</productname> without any mapping.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> also supports mapping
+ client principals to user names by just stripping the realm from
+ the principal. This method is supported for backwards compatibility and is
+ strongly discouraged as it is then impossible to distinguish different users
+ with the same user name but coming from different realms. To enable this,
+ set <literal>include_realm</literal> to 0. For simple single-realm
+ installations, doing that combined with setting the
+ <literal>krb_realm</literal> parameter (which checks that the principal's realm
+ matches exactly what is in the <literal>krb_realm</literal> parameter)
+ is still secure; but this is a
+ less capable approach compared to specifying an explicit mapping in
+ <filename>pg_ident.conf</filename>.
+ </para>
+
+ <para>
+ The location of the server's keytab file is specified by the <xref
+ linkend="guc-krb-server-keyfile"/> configuration parameter.
+ For security reasons, it is recommended to use a separate keytab
+ just for the <productname>PostgreSQL</productname> server rather
+ than allowing the server to read the system keytab file.
+ Make sure that your server keytab file is readable (and preferably
+ only readable, not writable) by the <productname>PostgreSQL</productname>
+ server account. (See also <xref linkend="postgres-user"/>.)
+ </para>
+
+ <para>
+ The keytab file is generated using the Kerberos software; see the
+ Kerberos documentation for details. The following example shows
+ doing this using the <application>kadmin</application> tool of
+ MIT-compatible Kerberos 5 implementations:
+<screen>
+<prompt>kadmin% </prompt><userinput>addprinc -randkey postgres/server.my.domain.org</userinput>
+<prompt>kadmin% </prompt><userinput>ktadd -k krb5.keytab postgres/server.my.domain.org</userinput>
+</screen>
+ </para>
+
+ <para>
+ The following authentication options are supported for
+ the <productname>GSSAPI</productname> authentication method:
+ <variablelist>
+ <varlistentry>
+ <term><literal>include_realm</literal></term>
+ <listitem>
+ <para>
+ If set to 0, the realm name from the authenticated user principal is
+ stripped off before being passed through the user name mapping
+ (<xref linkend="auth-username-maps"/>). This is discouraged and is
+ primarily available for backwards compatibility, as it is not secure
+ in multi-realm environments unless <literal>krb_realm</literal> is
+ also used. It is recommended to
+ leave <literal>include_realm</literal> set to the default (1) and to
+ provide an explicit mapping in <filename>pg_ident.conf</filename> to convert
+ principal names to <productname>PostgreSQL</productname> user names.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>map</literal></term>
+ <listitem>
+ <para>
+ Allows mapping from client principals to database user names. See
+ <xref linkend="auth-username-maps"/> for details. For a GSSAPI/Kerberos
+ principal, such as <literal>username@EXAMPLE.COM</literal> (or, less
+ commonly, <literal>username/hostbased@EXAMPLE.COM</literal>), the
+ user name used for mapping is
+ <literal>username@EXAMPLE.COM</literal> (or
+ <literal>username/hostbased@EXAMPLE.COM</literal>, respectively),
+ unless <literal>include_realm</literal> has been set to 0, in which case
+ <literal>username</literal> (or <literal>username/hostbased</literal>)
+ is what is seen as the system user name when mapping.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>krb_realm</literal></term>
+ <listitem>
+ <para>
+ Sets the realm to match user principal names against. If this parameter
+ is set, only users of that realm will be accepted. If it is not set,
+ users of any realm can connect, subject to whatever user name mapping
+ is done.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ In addition to these settings, which can be different for
+ different <filename>pg_hba.conf</filename> entries, there is the
+ server-wide <xref linkend="guc-krb-caseins-users"/> configuration
+ parameter. If that is set to true, client principals are matched to
+ user map entries case-insensitively. <literal>krb_realm</literal>, if
+ set, is also matched case-insensitively.
+ </para>
+ </sect1>
+
+ <sect1 id="sspi-auth">
+ <title>SSPI Authentication</title>
+
+ <indexterm zone="sspi-auth">
+ <primary>SSPI</primary>
+ </indexterm>
+
+ <para>
+ <productname>SSPI</productname> is a <productname>Windows</productname>
+ technology for secure authentication with single sign-on.
+ <productname>PostgreSQL</productname> will use SSPI in
+ <literal>negotiate</literal> mode, which will use
+ <productname>Kerberos</productname> when possible and automatically
+ fall back to <productname>NTLM</productname> in other cases.
+ <productname>SSPI</productname> authentication only works when both
+ server and client are running <productname>Windows</productname>,
+ or, on non-Windows platforms, when <productname>GSSAPI</productname>
+ is available.
+ </para>
+
+ <para>
+ When using <productname>Kerberos</productname> authentication,
+ <productname>SSPI</productname> works the same way
+ <productname>GSSAPI</productname> does; see <xref linkend="gssapi-auth"/>
+ for details.
+ </para>
+
+ <para>
+ The following configuration options are supported for <productname>SSPI</productname>:
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>include_realm</literal></term>
+ <listitem>
+ <para>
+ If set to 0, the realm name from the authenticated user principal is
+ stripped off before being passed through the user name mapping
+ (<xref linkend="auth-username-maps"/>). This is discouraged and is
+ primarily available for backwards compatibility, as it is not secure
+ in multi-realm environments unless <literal>krb_realm</literal> is
+ also used. It is recommended to
+ leave <literal>include_realm</literal> set to the default (1) and to
+ provide an explicit mapping in <filename>pg_ident.conf</filename> to convert
+ principal names to <productname>PostgreSQL</productname> user names.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>compat_realm</literal></term>
+ <listitem>
+ <para>
+ If set to 1, the domain's SAM-compatible name (also known as the
+ NetBIOS name) is used for the <literal>include_realm</literal>
+ option. This is the default. If set to 0, the true realm name from
+ the Kerberos user principal name is used.
+ </para>
+ <para>
+ Do not disable this option unless your server runs under a domain
+ account (this includes virtual service accounts on a domain member
+ system) and all clients authenticating through SSPI are also using
+ domain accounts, or authentication will fail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>upn_username</literal></term>
+ <listitem>
+ <para>
+ If this option is enabled along with <literal>compat_realm</literal>,
+ the user name from the Kerberos UPN is used for authentication. If
+ it is disabled (the default), the SAM-compatible user name is used.
+ By default, these two names are identical for new user accounts.
+ </para>
+ <para>
+ Note that <application>libpq</application> uses the SAM-compatible name if no
+ explicit user name is specified. If you use
+ <application>libpq</application> or a driver based on it, you should
+ leave this option disabled or explicitly specify user name in the
+ connection string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>map</literal></term>
+ <listitem>
+ <para>
+ Allows for mapping between system and database user names. See
+ <xref linkend="auth-username-maps"/> for details. For an SSPI/Kerberos
+ principal, such as <literal>username@EXAMPLE.COM</literal> (or, less
+ commonly, <literal>username/hostbased@EXAMPLE.COM</literal>), the
+ user name used for mapping is
+ <literal>username@EXAMPLE.COM</literal> (or
+ <literal>username/hostbased@EXAMPLE.COM</literal>, respectively),
+ unless <literal>include_realm</literal> has been set to 0, in which case
+ <literal>username</literal> (or <literal>username/hostbased</literal>)
+ is what is seen as the system user name when mapping.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>krb_realm</literal></term>
+ <listitem>
+ <para>
+ Sets the realm to match user principal names against. If this parameter
+ is set, only users of that realm will be accepted. If it is not set,
+ users of any realm can connect, subject to whatever user name mapping
+ is done.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+
+ <sect1 id="auth-ident">
+ <title>Ident Authentication</title>
+
+ <indexterm>
+ <primary>ident</primary>
+ </indexterm>
+
+ <para>
+ The ident authentication method works by obtaining the client's
+ operating system user name from an ident server and using it as
+ the allowed database user name (with an optional user name mapping).
+ This is only supported on TCP/IP connections.
+ </para>
+
+ <note>
+ <para>
+ When ident is specified for a local (non-TCP/IP) connection,
+ peer authentication (see <xref linkend="auth-peer"/>) will be
+ used instead.
+ </para>
+ </note>
+
+ <para>
+ The following configuration options are supported for <literal>ident</literal>:
+ <variablelist>
+ <varlistentry>
+ <term><literal>map</literal></term>
+ <listitem>
+ <para>
+ Allows for mapping between system and database user names. See
+ <xref linkend="auth-username-maps"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <quote>Identification Protocol</quote> is described in
+ <ulink url="https://tools.ietf.org/html/rfc1413">RFC 1413</ulink>.
+ Virtually every Unix-like
+ operating system ships with an ident server that listens on TCP
+ port 113 by default. The basic functionality of an ident server
+ is to answer questions like <quote>What user initiated the
+ connection that goes out of your port <replaceable>X</replaceable>
+ and connects to my port <replaceable>Y</replaceable>?</quote>.
+ Since <productname>PostgreSQL</productname> knows both <replaceable>X</replaceable> and
+ <replaceable>Y</replaceable> when a physical connection is established, it
+ can interrogate the ident server on the host of the connecting
+ client and can theoretically determine the operating system user
+ for any given connection.
+ </para>
+
+ <para>
+ The drawback of this procedure is that it depends on the integrity
+ of the client: if the client machine is untrusted or compromised,
+ an attacker could run just about any program on port 113 and
+ return any user name they choose. This authentication method is
+ therefore only appropriate for closed networks where each client
+ machine is under tight control and where the database and system
+ administrators operate in close contact. In other words, you must
+ trust the machine running the ident server.
+ Heed the warning:
+ <blockquote>
+ <attribution>RFC 1413</attribution>
+ <para>
+ The Identification Protocol is not intended as an authorization
+ or access control protocol.
+ </para>
+ </blockquote>
+ </para>
+
+ <para>
+ Some ident servers have a nonstandard option that causes the returned
+ user name to be encrypted, using a key that only the originating
+ machine's administrator knows. This option <emphasis>must not</emphasis> be
+ used when using the ident server with <productname>PostgreSQL</productname>,
+ since <productname>PostgreSQL</productname> does not have any way to decrypt the
+ returned string to determine the actual user name.
+ </para>
+ </sect1>
+
+ <sect1 id="auth-peer">
+ <title>Peer Authentication</title>
+
+ <indexterm>
+ <primary>peer</primary>
+ </indexterm>
+
+ <para>
+ The peer authentication method works by obtaining the client's
+ operating system user name from the kernel and using it as the
+ allowed database user name (with optional user name mapping). This
+ method is only supported on local connections.
+ </para>
+
+ <para>
+ The following configuration options are supported for <literal>peer</literal>:
+ <variablelist>
+ <varlistentry>
+ <term><literal>map</literal></term>
+ <listitem>
+ <para>
+ Allows for mapping between system and database user names. See
+ <xref linkend="auth-username-maps"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Peer authentication is only available on operating systems providing
+ the <function>getpeereid()</function> function, the <symbol>SO_PEERCRED</symbol>
+ socket parameter, or similar mechanisms. Currently that includes
+ <systemitem class="osname">Linux</systemitem>,
+ most flavors of <systemitem class="osname">BSD</systemitem> including
+ <systemitem class="osname">macOS</systemitem>,
+ and <systemitem class="osname">Solaris</systemitem>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="auth-ldap">
+ <title>LDAP Authentication</title>
+
+ <indexterm zone="auth-ldap">
+ <primary>LDAP</primary>
+ </indexterm>
+
+ <para>
+ This authentication method operates similarly to
+ <literal>password</literal> except that it uses LDAP
+ as the password verification method. LDAP is used only to validate
+ the user name/password pairs. Therefore the user must already
+ exist in the database before LDAP can be used for
+ authentication.
+ </para>
+
+ <para>
+ LDAP authentication can operate in two modes. In the first mode,
+ which we will call the simple bind mode,
+ the server will bind to the distinguished name constructed as
+ <replaceable>prefix</replaceable> <replaceable>username</replaceable> <replaceable>suffix</replaceable>.
+ Typically, the <replaceable>prefix</replaceable> parameter is used to specify
+ <literal>cn=</literal>, or <replaceable>DOMAIN</replaceable><literal>\</literal> in an Active
+ Directory environment. <replaceable>suffix</replaceable> is used to specify the
+ remaining part of the DN in a non-Active Directory environment.
+ </para>
+
+ <para>
+ In the second mode, which we will call the search+bind mode,
+ the server first binds to the LDAP directory with
+ a fixed user name and password, specified with <replaceable>ldapbinddn</replaceable>
+ and <replaceable>ldapbindpasswd</replaceable>, and performs a search for the user trying
+ to log in to the database. If no user and password is configured, an
+ anonymous bind will be attempted to the directory. The search will be
+ performed over the subtree at <replaceable>ldapbasedn</replaceable>, and will try to
+ do an exact match of the attribute specified in
+ <replaceable>ldapsearchattribute</replaceable>.
+ Once the user has been found in
+ this search, the server disconnects and re-binds to the directory as
+ this user, using the password specified by the client, to verify that the
+ login is correct. This mode is the same as that used by LDAP authentication
+ schemes in other software, such as Apache <literal>mod_authnz_ldap</literal> and <literal>pam_ldap</literal>.
+ This method allows for significantly more flexibility
+ in where the user objects are located in the directory, but will cause
+ two separate connections to the LDAP server to be made.
+ </para>
+
+ <para>
+ The following configuration options are used in both modes:
+ <variablelist>
+ <varlistentry>
+ <term><literal>ldapserver</literal></term>
+ <listitem>
+ <para>
+ Names or IP addresses of LDAP servers to connect to. Multiple
+ servers may be specified, separated by spaces.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapport</literal></term>
+ <listitem>
+ <para>
+ Port number on LDAP server to connect to. If no port is specified,
+ the LDAP library's default port setting will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapscheme</literal></term>
+ <listitem>
+ <para>
+ Set to <literal>ldaps</literal> to use LDAPS. This is a non-standard
+ way of using LDAP over SSL, supported by some LDAP server
+ implementations. See also the <literal>ldaptls</literal> option for
+ an alternative.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldaptls</literal></term>
+ <listitem>
+ <para>
+ Set to 1 to make the connection between PostgreSQL and the LDAP server
+ use TLS encryption. This uses the <literal>StartTLS</literal>
+ operation per <ulink url="https://tools.ietf.org/html/rfc4513">RFC 4513</ulink>.
+ See also the <literal>ldapscheme</literal> option for an alternative.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Note that using <literal>ldapscheme</literal> or
+ <literal>ldaptls</literal> only encrypts the traffic between the
+ PostgreSQL server and the LDAP server. The connection between the
+ PostgreSQL server and the PostgreSQL client will still be unencrypted
+ unless SSL is used there as well.
+ </para>
+
+ <para>
+ The following options are used in simple bind mode only:
+ <variablelist>
+ <varlistentry>
+ <term><literal>ldapprefix</literal></term>
+ <listitem>
+ <para>
+ String to prepend to the user name when forming the DN to bind as,
+ when doing simple bind authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapsuffix</literal></term>
+ <listitem>
+ <para>
+ String to append to the user name when forming the DN to bind as,
+ when doing simple bind authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following options are used in search+bind mode only:
+ <variablelist>
+ <varlistentry>
+ <term><literal>ldapbasedn</literal></term>
+ <listitem>
+ <para>
+ Root DN to begin the search for the user in, when doing search+bind
+ authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapbinddn</literal></term>
+ <listitem>
+ <para>
+ DN of user to bind to the directory with to perform the search when
+ doing search+bind authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapbindpasswd</literal></term>
+ <listitem>
+ <para>
+ Password for user to bind to the directory with to perform the search
+ when doing search+bind authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapsearchattribute</literal></term>
+ <listitem>
+ <para>
+ Attribute to match against the user name in the search when doing
+ search+bind authentication. If no attribute is specified, the
+ <literal>uid</literal> attribute will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapsearchfilter</literal></term>
+ <listitem>
+ <para>
+ The search filter to use when doing search+bind authentication.
+ Occurrences of <literal>$username</literal> will be replaced with the
+ user name. This allows for more flexible search filters than
+ <literal>ldapsearchattribute</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>ldapurl</literal></term>
+ <listitem>
+ <para>
+ An <ulink url="https://tools.ietf.org/html/rfc4516">RFC 4516</ulink>
+ LDAP URL. This is an alternative way to write some of the
+ other LDAP options in a more compact and standard form. The format is
+<synopsis>
+ldap[s]://<replaceable>host</replaceable>[:<replaceable>port</replaceable>]/<replaceable>basedn</replaceable>[?[<replaceable>attribute</replaceable>][?[<replaceable>scope</replaceable>][?[<replaceable>filter</replaceable>]]]]
+</synopsis>
+ <replaceable>scope</replaceable> must be one
+ of <literal>base</literal>, <literal>one</literal>, <literal>sub</literal>,
+ typically the last. (The default is <literal>base</literal>, which
+ is normally not useful in this application.) <replaceable>attribute</replaceable> can
+ nominate a single attribute, in which case it is used as a value for
+ <literal>ldapsearchattribute</literal>. If
+ <replaceable>attribute</replaceable> is empty then
+ <replaceable>filter</replaceable> can be used as a value for
+ <literal>ldapsearchfilter</literal>.
+ </para>
+
+ <para>
+ The URL scheme <literal>ldaps</literal> chooses the LDAPS method for
+ making LDAP connections over SSL, equivalent to using
+ <literal>ldapscheme=ldaps</literal>. To use encrypted LDAP
+ connections using the <literal>StartTLS</literal> operation, use the
+ normal URL scheme <literal>ldap</literal> and specify the
+ <literal>ldaptls</literal> option in addition to
+ <literal>ldapurl</literal>.
+ </para>
+
+ <para>
+ For non-anonymous binds, <literal>ldapbinddn</literal>
+ and <literal>ldapbindpasswd</literal> must be specified as separate
+ options.
+ </para>
+
+ <para>
+ LDAP URLs are currently only supported with
+ <productname>OpenLDAP</productname>, not on Windows.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ It is an error to mix configuration options for simple bind with options
+ for search+bind.
+ </para>
+
+ <para>
+ When using search+bind mode, the search can be performed using a single
+ attribute specified with <literal>ldapsearchattribute</literal>, or using
+ a custom search filter specified with
+ <literal>ldapsearchfilter</literal>.
+ Specifying <literal>ldapsearchattribute=foo</literal> is equivalent to
+ specifying <literal>ldapsearchfilter="(foo=$username)"</literal>. If neither
+ option is specified the default is
+ <literal>ldapsearchattribute=uid</literal>.
+ </para>
+
+ <para>
+ If <productname>PostgreSQL</productname> was compiled with
+ <productname>OpenLDAP</productname> as the LDAP client library, the
+ <literal>ldapserver</literal> setting may be omitted. In that case, a
+ list of host names and ports is looked up via
+ <ulink url="https://tools.ietf.org/html/rfc2782">RFC 2782</ulink> DNS SRV records.
+ The name <literal>_ldap._tcp.DOMAIN</literal> is looked up, where
+ <literal>DOMAIN</literal> is extracted from <literal>ldapbasedn</literal>.
+ </para>
+
+ <para>
+ Here is an example for a simple-bind LDAP configuration:
+<programlisting>
+host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
+</programlisting>
+ When a connection to the database server as database
+ user <literal>someuser</literal> is requested, PostgreSQL will attempt to
+ bind to the LDAP server using the DN <literal>cn=someuser, dc=example,
+ dc=net</literal> and the password provided by the client. If that connection
+ succeeds, the database access is granted.
+ </para>
+
+ <para>
+ Here is an example for a search+bind configuration:
+<programlisting>
+host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid
+</programlisting>
+ When a connection to the database server as database
+ user <literal>someuser</literal> is requested, PostgreSQL will attempt to
+ bind anonymously (since <literal>ldapbinddn</literal> was not specified) to
+ the LDAP server, perform a search for <literal>(uid=someuser)</literal>
+ under the specified base DN. If an entry is found, it will then attempt to
+ bind using that found information and the password supplied by the client.
+ If that second connection succeeds, the database access is granted.
+ </para>
+
+ <para>
+ Here is the same search+bind configuration written as a URL:
+<programlisting>
+host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
+</programlisting>
+ Some other software that supports authentication against LDAP uses the
+ same URL format, so it will be easier to share the configuration.
+ </para>
+
+ <para>
+ Here is an example for a search+bind configuration that uses
+ <literal>ldapsearchfilter</literal> instead of
+ <literal>ldapsearchattribute</literal> to allow authentication by
+ user ID or email address:
+<programlisting>
+host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))"
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example for a search+bind configuration that uses DNS SRV
+ discovery to find the host name(s) and port(s) for the LDAP service for the
+ domain name <literal>example.net</literal>:
+<programlisting>
+host ... ldap ldapbasedn="dc=example,dc=net"
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ Since LDAP often uses commas and spaces to separate the different
+ parts of a DN, it is often necessary to use double-quoted parameter
+ values when configuring LDAP options, as shown in the examples.
+ </para>
+ </tip>
+
+ </sect1>
+
+ <sect1 id="auth-radius">
+ <title>RADIUS Authentication</title>
+
+ <indexterm zone="auth-radius">
+ <primary>RADIUS</primary>
+ </indexterm>
+
+ <para>
+ This authentication method operates similarly to
+ <literal>password</literal> except that it uses RADIUS
+ as the password verification method. RADIUS is used only to validate
+ the user name/password pairs. Therefore the user must already
+ exist in the database before RADIUS can be used for
+ authentication.
+ </para>
+
+ <para>
+ When using RADIUS authentication, an Access Request message will be sent
+ to the configured RADIUS server. This request will be of type
+ <literal>Authenticate Only</literal>, and include parameters for
+ <literal>user name</literal>, <literal>password</literal> (encrypted) and
+ <literal>NAS Identifier</literal>. The request will be encrypted using
+ a secret shared with the server. The RADIUS server will respond to
+ this request with either <literal>Access Accept</literal> or
+ <literal>Access Reject</literal>. There is no support for RADIUS accounting.
+ </para>
+
+ <para>
+ Multiple RADIUS servers can be specified, in which case they will
+ be tried sequentially. If a negative response is received from
+ a server, the authentication will fail. If no response is received,
+ the next server in the list will be tried. To specify multiple
+ servers, separate the server names with commas and surround the list
+ with double quotes. If multiple servers are specified, the other
+ RADIUS options can also be given as comma-separated lists, to provide
+ individual values for each server. They can also be specified as
+ a single value, in which case that value will apply to all servers.
+ </para>
+
+ <para>
+ The following configuration options are supported for RADIUS:
+ <variablelist>
+ <varlistentry>
+ <term><literal>radiusservers</literal></term>
+ <listitem>
+ <para>
+ The DNS names or IP addresses of the RADIUS servers to connect to.
+ This parameter is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>radiussecrets</literal></term>
+ <listitem>
+ <para>
+ The shared secrets used when talking securely to the RADIUS
+ servers. This must have exactly the same value on the PostgreSQL
+ and RADIUS servers. It is recommended that this be a string of
+ at least 16 characters. This parameter is required.
+ <note>
+ <para>
+ The encryption vector used will only be cryptographically
+ strong if <productname>PostgreSQL</productname> is built with support for
+ <productname>OpenSSL</productname>. In other cases, the transmission to the
+ RADIUS server should only be considered obfuscated, not secured, and
+ external security measures should be applied if necessary.
+ </para>
+ </note>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>radiusports</literal></term>
+ <listitem>
+ <para>
+ The port numbers to connect to on the RADIUS servers. If no port
+ is specified, the default RADIUS port (<literal>1812</literal>)
+ will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>radiusidentifiers</literal></term>
+ <listitem>
+ <para>
+ The strings to be used as <literal>NAS Identifier</literal> in the
+ RADIUS requests. This parameter can be used, for example, to
+ identify which database cluster the user is attempting to connect
+ to, which can be useful for policy matching on
+ the RADIUS server. If no identifier is specified, the default
+ <literal>postgresql</literal> will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ If it is necessary to have a comma or whitespace in a RADIUS parameter
+ value, that can be done by putting double quotes around the value, but
+ it is tedious because two layers of double-quoting are now required.
+ An example of putting whitespace into RADIUS secret strings is:
+<programlisting>
+host ... radius radiusservers="server1,server2" radiussecrets="""secret one"",""secret two"""
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="auth-cert">
+ <title>Certificate Authentication</title>
+
+ <indexterm zone="auth-cert">
+ <primary>Certificate</primary>
+ </indexterm>
+
+ <para>
+ This authentication method uses SSL client certificates to perform
+ authentication. It is therefore only available for SSL connections.
+ When using this authentication method, the server will require that
+ the client provide a valid, trusted certificate. No password prompt
+ will be sent to the client. The <literal>cn</literal> (Common Name)
+ attribute of the certificate
+ will be compared to the requested database user name, and if they match
+ the login will be allowed. User name mapping can be used to allow
+ <literal>cn</literal> to be different from the database user name.
+ </para>
+
+ <para>
+ The following configuration options are supported for SSL certificate
+ authentication:
+ <variablelist>
+ <varlistentry>
+ <term><literal>map</literal></term>
+ <listitem>
+ <para>
+ Allows for mapping between system and database user names. See
+ <xref linkend="auth-username-maps"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ It is redundant to use the <literal>clientcert</literal> option with
+ <literal>cert</literal> authentication because <literal>cert</literal>
+ authentication is effectively <literal>trust</literal> authentication
+ with <literal>clientcert=verify-full</literal>.
+ </para>
+ </sect1>
+
+ <sect1 id="auth-pam">
+ <title>PAM Authentication</title>
+
+ <indexterm zone="auth-pam">
+ <primary>PAM</primary>
+ </indexterm>
+
+ <para>
+ This authentication method operates similarly to
+ <literal>password</literal> except that it uses PAM (Pluggable
+ Authentication Modules) as the authentication mechanism. The
+ default PAM service name is <literal>postgresql</literal>.
+ PAM is used only to validate user name/password pairs and optionally the
+ connected remote host name or IP address. Therefore the user must already
+ exist in the database before PAM can be used for authentication. For more
+ information about PAM, please read the
+ <ulink url="https://www.kernel.org/pub/linux/libs/pam/">
+ <productname>Linux-PAM</productname> Page</ulink>.
+ </para>
+
+ <para>
+ The following configuration options are supported for PAM:
+ <variablelist>
+ <varlistentry>
+ <term><literal>pamservice</literal></term>
+ <listitem>
+ <para>
+ PAM service name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>pam_use_hostname</literal></term>
+ <listitem>
+ <para>
+ Determines whether the remote IP address or the host name is provided
+ to PAM modules through the <symbol>PAM_RHOST</symbol> item. By
+ default, the IP address is used. Set this option to 1 to use the
+ resolved host name instead. Host name resolution can lead to login
+ delays. (Most PAM configurations don't use this information, so it is
+ only necessary to consider this setting if a PAM configuration was
+ specifically created to make use of it.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <note>
+ <para>
+ If PAM is set up to read <filename>/etc/shadow</filename>, authentication
+ will fail because the PostgreSQL server is started by a non-root
+ user. However, this is not an issue when PAM is configured to use
+ LDAP or other authentication methods.
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="auth-bsd">
+ <title>BSD Authentication</title>
+
+ <indexterm zone="auth-bsd">
+ <primary>BSD Authentication</primary>
+ </indexterm>
+
+ <para>
+ This authentication method operates similarly to
+ <literal>password</literal> except that it uses BSD Authentication
+ to verify the password. BSD Authentication is used only
+ to validate user name/password pairs. Therefore the user's role must
+ already exist in the database before BSD Authentication can be used
+ for authentication. The BSD Authentication framework is currently
+ only available on OpenBSD.
+ </para>
+
+ <para>
+ BSD Authentication in <productname>PostgreSQL</productname> uses
+ the <literal>auth-postgresql</literal> login type and authenticates with
+ the <literal>postgresql</literal> login class if that's defined
+ in <filename>login.conf</filename>. By default that login class does not
+ exist, and <productname>PostgreSQL</productname> will use the default login class.
+ </para>
+
+ <note>
+ <para>
+ To use BSD Authentication, the PostgreSQL user account (that is, the
+ operating system user running the server) must first be added to
+ the <literal>auth</literal> group. The <literal>auth</literal> group
+ exists by default on OpenBSD systems.
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="client-authentication-problems">
+ <title>Authentication Problems</title>
+
+ <para>
+ Authentication failures and related problems generally
+ manifest themselves through error messages like the following:
+ </para>
+
+ <para>
+<programlisting>
+FATAL: no pg_hba.conf entry for host "123.123.123.123", user "andym", database "testdb"
+</programlisting>
+ This is what you are most likely to get if you succeed in contacting
+ the server, but it does not want to talk to you. As the message
+ suggests, the server refused the connection request because it found
+ no matching entry in its <filename>pg_hba.conf</filename>
+ configuration file.
+ </para>
+
+ <para>
+<programlisting>
+FATAL: password authentication failed for user "andym"
+</programlisting>
+ Messages like this indicate that you contacted the server, and it is
+ willing to talk to you, but not until you pass the authorization
+ method specified in the <filename>pg_hba.conf</filename> file. Check
+ the password you are providing, or check your Kerberos or ident
+ software if the complaint mentions one of those authentication
+ types.
+ </para>
+
+ <para>
+<programlisting>
+FATAL: user "andym" does not exist
+</programlisting>
+ The indicated database user name was not found.
+ </para>
+
+ <para>
+<programlisting>
+FATAL: database "testdb" does not exist
+</programlisting>
+ The database you are trying to connect to does not exist. Note that
+ if you do not specify a database name, it defaults to the database
+ user name, which might or might not be the right thing.
+ </para>
+
+ <tip>
+ <para>
+ The server log might contain more information about an
+ authentication failure than is reported to the client. If you are
+ confused about the reason for a failure, check the server log.
+ </para>
+ </tip>
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/color.sgml b/doc/src/sgml/color.sgml
new file mode 100644
index 0000000..5b782f7
--- /dev/null
+++ b/doc/src/sgml/color.sgml
@@ -0,0 +1,111 @@
+<!-- doc/src/sgml/color.sgml -->
+
+<appendix id="color">
+ <title>Color Support</title>
+
+ <indexterm zone="color">
+ <primary>color</primary>
+ </indexterm>
+
+ <para>
+ Most programs in the PostgreSQL package can produce colorized console
+ output. This appendix describes how that is configured.
+ </para>
+
+ <sect1 id="color-when">
+ <title>When Color is Used</title>
+
+ <para>
+ To use colorized output, set the environment variable
+ <envar>PG_COLOR</envar><indexterm><primary>PG_COLOR</primary></indexterm>
+ as follows:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If the value is <literal>always</literal>, then color is used.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the value is <literal>auto</literal> and the standard error stream
+ is associated with a terminal device, then color is used.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Otherwise, color is not used.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </sect1>
+
+ <sect1 id="color-which">
+ <title>Configuring the Colors</title>
+
+ <para>
+ The actual colors to be used are configured using the environment variable
+ <envar>PG_COLORS</envar><indexterm><primary>PG_COLORS</primary></indexterm>
+ (note plural). The value is a colon-separated list of
+ <literal><replaceable>key</replaceable>=<replaceable>value</replaceable></literal>
+ pairs. The keys specify what the color is to be used for. The values are
+ SGR (Select Graphic Rendition) specifications, which are interpreted by the
+ terminal.
+ </para>
+
+ <para>
+ The following keys are currently in use:
+ <variablelist>
+ <varlistentry>
+ <term><literal>error</literal></term>
+ <listitem>
+ <para>used to highlight the text <quote>error</quote> in error messages</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>warning</literal></term>
+ <listitem>
+ <para>used to highlight the text <quote>warning</quote> in warning
+ messages</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>note</literal></term>
+ <listitem>
+ <para>used to highlight the text <quote>detail</quote> and
+ <quote>hint</quote> in such messages</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>locus</literal></term>
+ <listitem>
+ <para>used to highlight location information (e.g., program name and
+ file name) in messages</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The default value is
+ <literal>error=01;31:warning=01;35:note=01;36:locus=01</literal>
+ (<literal>01;31</literal> = bold red, <literal>01;35</literal> = bold
+ magenta, <literal>01;36</literal> = bold cyan, <literal>01</literal> = bold
+ default color).
+ </para>
+
+ <tip>
+ <para>
+ This color specification format is also used by other software packages
+ such as <productname>GCC</productname>, <productname>GNU
+ coreutils</productname>, and <productname>GNU grep</productname>.
+ </para>
+ </tip>
+ </sect1>
+</appendix>
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
new file mode 100644
index 0000000..9de2124
--- /dev/null
+++ b/doc/src/sgml/config.sgml
@@ -0,0 +1,11607 @@
+<!-- doc/src/sgml/config.sgml -->
+
+<chapter id="runtime-config">
+ <title>Server Configuration</title>
+
+ <indexterm>
+ <primary>configuration</primary>
+ <secondary>of the server</secondary>
+ </indexterm>
+
+ <para>
+ There are many configuration parameters that affect the behavior of
+ the database system. In the first section of this chapter we
+ describe how to interact with configuration parameters. The subsequent sections
+ discuss each parameter in detail.
+ </para>
+
+ <sect1 id="config-setting">
+ <title>Setting Parameters</title>
+
+ <sect2 id="config-setting-names-values">
+ <title>Parameter Names and Values</title>
+
+ <para>
+ All parameter names are case-insensitive. Every parameter takes a
+ value of one of five types: boolean, string, integer, floating point,
+ or enumerated (enum). The type determines the syntax for setting the
+ parameter:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis>Boolean:</emphasis>
+ Values can be written as
+ <literal>on</literal>,
+ <literal>off</literal>,
+ <literal>true</literal>,
+ <literal>false</literal>,
+ <literal>yes</literal>,
+ <literal>no</literal>,
+ <literal>1</literal>,
+ <literal>0</literal>
+ (all case-insensitive) or any unambiguous prefix of one of these.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>String:</emphasis>
+ In general, enclose the value in single quotes, doubling any single
+ quotes within the value. Quotes can usually be omitted if the value
+ is a simple number or identifier, however.
+ (Values that match an SQL keyword require quoting in some contexts.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>Numeric (integer and floating point):</emphasis>
+ Numeric parameters can be specified in the customary integer and
+ floating-point formats; fractional values are rounded to the nearest
+ integer if the parameter is of integer type. Integer parameters
+ additionally accept hexadecimal input (beginning
+ with <literal>0x</literal>) and octal input (beginning
+ with <literal>0</literal>), but these formats cannot have a fraction.
+ Do not use thousands separators.
+ Quotes are not required, except for hexadecimal input.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>Numeric with Unit:</emphasis>
+ Some numeric parameters have an implicit unit, because they describe
+ quantities of memory or time. The unit might be bytes, kilobytes, blocks
+ (typically eight kilobytes), milliseconds, seconds, or minutes.
+ An unadorned numeric value for one of these settings will use the
+ setting's default unit, which can be learned from
+ <structname>pg_settings</structname>.<structfield>unit</structfield>.
+ For convenience, settings can be given with a unit specified explicitly,
+ for example <literal>'120 ms'</literal> for a time value, and they will be
+ converted to whatever the parameter's actual unit is. Note that the
+ value must be written as a string (with quotes) to use this feature.
+ The unit name is case-sensitive, and there can be whitespace between
+ the numeric value and the unit.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Valid memory units are <literal>B</literal> (bytes),
+ <literal>kB</literal> (kilobytes),
+ <literal>MB</literal> (megabytes), <literal>GB</literal>
+ (gigabytes), and <literal>TB</literal> (terabytes).
+ The multiplier for memory units is 1024, not 1000.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Valid time units are
+ <literal>us</literal> (microseconds),
+ <literal>ms</literal> (milliseconds),
+ <literal>s</literal> (seconds), <literal>min</literal> (minutes),
+ <literal>h</literal> (hours), and <literal>d</literal> (days).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ If a fractional value is specified with a unit, it will be rounded
+ to a multiple of the next smaller unit if there is one.
+ For example, <literal>30.1 GB</literal> will be converted
+ to <literal>30822 MB</literal> not <literal>32319628902 B</literal>.
+ If the parameter is of integer type, a final rounding to integer
+ occurs after any unit conversion.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>Enumerated:</emphasis>
+ Enumerated-type parameters are written in the same way as string
+ parameters, but are restricted to have one of a limited set of
+ values. The values allowable for such a parameter can be found from
+ <structname>pg_settings</structname>.<structfield>enumvals</structfield>.
+ Enum parameter values are case-insensitive.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="config-setting-configuration-file">
+ <title>Parameter Interaction via the Configuration File</title>
+
+ <para>
+ The most fundamental way to set these parameters is to edit the file
+ <filename>postgresql.conf</filename><indexterm><primary>postgresql.conf</primary></indexterm>,
+ which is normally kept in the data directory. A default copy is
+ installed when the database cluster directory is initialized.
+ An example of what this file might look like is:
+<programlisting>
+# This is a comment
+log_connections = yes
+log_destination = 'syslog'
+search_path = '"$user", public'
+shared_buffers = 128MB
+</programlisting>
+ One parameter is specified per line. The equal sign between name and
+ value is optional. Whitespace is insignificant (except within a quoted
+ parameter value) and blank lines are
+ ignored. Hash marks (<literal>#</literal>) designate the remainder
+ of the line as a comment. Parameter values that are not simple
+ identifiers or numbers must be single-quoted. To embed a single
+ quote in a parameter value, write either two quotes (preferred)
+ or backslash-quote.
+ If the file contains multiple entries for the same parameter,
+ all but the last one are ignored.
+ </para>
+
+ <para>
+ Parameters set in this way provide default values for the cluster.
+ The settings seen by active sessions will be these values unless they
+ are overridden. The following sections describe ways in which the
+ administrator or user can override these defaults.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>SIGHUP</primary>
+ </indexterm>
+ The configuration file is reread whenever the main server process
+ receives a <systemitem>SIGHUP</systemitem> signal; this signal is most easily
+ sent by running <literal>pg_ctl reload</literal> from the command line or by
+ calling the SQL function <function>pg_reload_conf()</function>. The main
+ server process also propagates this signal to all currently running
+ server processes, so that existing sessions also adopt the new values
+ (this will happen after they complete any currently-executing client
+ command). Alternatively, you can
+ send the signal to a single server process directly. Some parameters
+ can only be set at server start; any changes to their entries in the
+ configuration file will be ignored until the server is restarted.
+ Invalid parameter settings in the configuration file are likewise
+ ignored (but logged) during <systemitem>SIGHUP</systemitem> processing.
+ </para>
+
+ <para>
+ In addition to <filename>postgresql.conf</filename>,
+ a <productname>PostgreSQL</productname> data directory contains a file
+ <filename>postgresql.auto.conf</filename><indexterm><primary>postgresql.auto.conf</primary></indexterm>,
+ which has the same format as <filename>postgresql.conf</filename> but
+ is intended to be edited automatically, not manually. This file holds
+ settings provided through the <link linkend="sql-altersystem"><command>ALTER SYSTEM</command></link> command.
+ This file is read whenever <filename>postgresql.conf</filename> is,
+ and its settings take effect in the same way. Settings
+ in <filename>postgresql.auto.conf</filename> override those
+ in <filename>postgresql.conf</filename>.
+ </para>
+
+ <para>
+ External tools may also
+ modify <filename>postgresql.auto.conf</filename>. It is not
+ recommended to do this while the server is running, since a
+ concurrent <command>ALTER SYSTEM</command> command could overwrite
+ such changes. Such tools might simply append new settings to the end,
+ or they might choose to remove duplicate settings and/or comments
+ (as <command>ALTER SYSTEM</command> will).
+ </para>
+
+ <para>
+ The system view
+ <link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link>
+ can be helpful for pre-testing changes to the configuration files, or for
+ diagnosing problems if a <systemitem>SIGHUP</systemitem> signal did not have the
+ desired effects.
+ </para>
+ </sect2>
+
+ <sect2 id="config-setting-sql-command-interaction">
+ <title>Parameter Interaction via SQL</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides three SQL
+ commands to establish configuration defaults.
+ The already-mentioned <command>ALTER SYSTEM</command> command
+ provides an SQL-accessible means of changing global defaults; it is
+ functionally equivalent to editing <filename>postgresql.conf</filename>.
+ In addition, there are two commands that allow setting of defaults
+ on a per-database or per-role basis:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link> command allows global
+ settings to be overridden on a per-database basis.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <link linkend="sql-alterrole"><command>ALTER ROLE</command></link> command allows both global and
+ per-database settings to be overridden with user-specific values.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Values set with <command>ALTER DATABASE</command> and <command>ALTER ROLE</command>
+ are applied only when starting a fresh database session. They
+ override values obtained from the configuration files or server
+ command line, and constitute defaults for the rest of the session.
+ Note that some settings cannot be changed after server start, and
+ so cannot be set with these commands (or the ones listed below).
+ </para>
+
+ <para>
+ Once a client is connected to the database, <productname>PostgreSQL</productname>
+ provides two additional SQL commands (and equivalent functions) to
+ interact with session-local configuration settings:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <link linkend="sql-show"><command>SHOW</command></link> command allows inspection of the
+ current value of any parameter. The corresponding SQL function is
+ <function>current_setting(setting_name text)</function>
+ (see <xref linkend="functions-admin-set"/>).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <link linkend="sql-set"><command>SET</command></link> command allows modification of the
+ current value of those parameters that can be set locally to a
+ session; it has no effect on other sessions.
+ Many parameters can be set this way by any user, but some can
+ only be set by superusers and users who have been
+ granted <literal>SET</literal> privilege on that parameter.
+ The corresponding SQL function is
+ <function>set_config(setting_name, new_value, is_local)</function>
+ (see <xref linkend="functions-admin-set"/>).
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ In addition, the system view <link
+ linkend="view-pg-settings"><structname>pg_settings</structname></link> can be
+ used to view and change session-local values:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Querying this view is similar to using <command>SHOW ALL</command> but
+ provides more detail. It is also more flexible, since it's possible
+ to specify filter conditions or join against other relations.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using <command>UPDATE</command> on this view, specifically
+ updating the <structname>setting</structname> column, is the equivalent
+ of issuing <command>SET</command> commands. For example, the equivalent of
+<programlisting>
+SET configuration_parameter TO DEFAULT;
+</programlisting>
+ is:
+<programlisting>
+UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter';
+</programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2>
+ <title>Parameter Interaction via the Shell</title>
+
+ <para>
+ In addition to setting global defaults or attaching
+ overrides at the database or role level, you can pass settings to
+ <productname>PostgreSQL</productname> via shell facilities.
+ Both the server and <application>libpq</application> client library
+ accept parameter values via the shell.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ During server startup, parameter settings can be
+ passed to the <command>postgres</command> command via the
+ <option>-c</option> command-line parameter. For example,
+<programlisting>
+postgres -c log_connections=yes -c log_destination='syslog'
+</programlisting>
+ Settings provided in this way override those set via
+ <filename>postgresql.conf</filename> or <command>ALTER SYSTEM</command>,
+ so they cannot be changed globally without restarting the server.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When starting a client session via <application>libpq</application>,
+ parameter settings can be
+ specified using the <envar>PGOPTIONS</envar> environment variable.
+ Settings established in this way constitute defaults for the life
+ of the session, but do not affect other sessions.
+ For historical reasons, the format of <envar>PGOPTIONS</envar> is
+ similar to that used when launching the <command>postgres</command>
+ command; specifically, the <option>-c</option> flag must be specified.
+ For example,
+<programlisting>
+env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql
+</programlisting>
+ </para>
+
+ <para>
+ Other clients and libraries might provide their own mechanisms,
+ via the shell or otherwise, that allow the user to alter session
+ settings without direct use of SQL commands.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2 id="config-includes">
+ <title>Managing Configuration File Contents</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides several features for breaking
+ down complex <filename>postgresql.conf</filename> files into sub-files.
+ These features are especially useful when managing multiple servers
+ with related, but not identical, configurations.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary><literal>include</literal></primary>
+ <secondary>in configuration file</secondary>
+ </indexterm>
+ In addition to individual parameter settings,
+ the <filename>postgresql.conf</filename> file can contain <firstterm>include
+ directives</firstterm>, which specify another file to read and process as if
+ it were inserted into the configuration file at this point. This
+ feature allows a configuration file to be divided into physically
+ separate parts. Include directives simply look like:
+<programlisting>
+include 'filename'
+</programlisting>
+ If the file name is not an absolute path, it is taken as relative to
+ the directory containing the referencing configuration file.
+ Inclusions can be nested.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary><literal>include_if_exists</literal></primary>
+ <secondary>in configuration file</secondary>
+ </indexterm>
+ There is also an <literal>include_if_exists</literal> directive, which acts
+ the same as the <literal>include</literal> directive, except
+ when the referenced file does not exist or cannot be read. A regular
+ <literal>include</literal> will consider this an error condition, but
+ <literal>include_if_exists</literal> merely logs a message and continues
+ processing the referencing configuration file.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary><literal>include_dir</literal></primary>
+ <secondary>in configuration file</secondary>
+ </indexterm>
+ The <filename>postgresql.conf</filename> file can also contain
+ <literal>include_dir</literal> directives, which specify an entire
+ directory of configuration files to include. These look like
+<programlisting>
+include_dir 'directory'
+</programlisting>
+ Non-absolute directory names are taken as relative to the directory
+ containing the referencing configuration file. Within the specified
+ directory, only non-directory files whose names end with the
+ suffix <literal>.conf</literal> will be included. File names that
+ start with the <literal>.</literal> character are also ignored, to
+ prevent mistakes since such files are hidden on some platforms. Multiple
+ files within an include directory are processed in file name order
+ (according to C locale rules, i.e., numbers before letters, and
+ uppercase letters before lowercase ones).
+ </para>
+
+ <para>
+ Include files or directories can be used to logically separate portions
+ of the database configuration, rather than having a single large
+ <filename>postgresql.conf</filename> file. Consider a company that has two
+ database servers, each with a different amount of memory. There are
+ likely elements of the configuration both will share, for things such
+ as logging. But memory-related parameters on the server will vary
+ between the two. And there might be server specific customizations,
+ too. One way to manage this situation is to break the custom
+ configuration changes for your site into three files. You could add
+ this to the end of your <filename>postgresql.conf</filename> file to include
+ them:
+<programlisting>
+include 'shared.conf'
+include 'memory.conf'
+include 'server.conf'
+</programlisting>
+ All systems would have the same <filename>shared.conf</filename>. Each
+ server with a particular amount of memory could share the
+ same <filename>memory.conf</filename>; you might have one for all servers
+ with 8GB of RAM, another for those having 16GB. And
+ finally <filename>server.conf</filename> could have truly server-specific
+ configuration information in it.
+ </para>
+
+ <para>
+ Another possibility is to create a configuration file directory and
+ put this information into files there. For example, a <filename>conf.d</filename>
+ directory could be referenced at the end of <filename>postgresql.conf</filename>:
+<programlisting>
+include_dir 'conf.d'
+</programlisting>
+ Then you could name the files in the <filename>conf.d</filename> directory
+ like this:
+<programlisting>
+00shared.conf
+01memory.conf
+02server.conf
+</programlisting>
+ This naming convention establishes a clear order in which these
+ files will be loaded. This is important because only the last
+ setting encountered for a particular parameter while the server is
+ reading configuration files will be used. In this example,
+ something set in <filename>conf.d/02server.conf</filename> would override a
+ value set in <filename>conf.d/01memory.conf</filename>.
+ </para>
+
+ <para>
+ You might instead use this approach to naming the files
+ descriptively:
+<programlisting>
+00shared.conf
+01memory-8GB.conf
+02server-foo.conf
+</programlisting>
+ This sort of arrangement gives a unique name for each configuration file
+ variation. This can help eliminate ambiguity when several servers have
+ their configurations all stored in one place, such as in a version
+ control repository. (Storing database configuration files under version
+ control is another good practice to consider.)
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-file-locations">
+ <title>File Locations</title>
+
+ <para>
+ In addition to the <filename>postgresql.conf</filename> file
+ already mentioned, <productname>PostgreSQL</productname> uses
+ two other manually-edited configuration files, which control
+ client authentication (their use is discussed in <xref
+ linkend="client-authentication"/>). By default, all three
+ configuration files are stored in the database cluster's data
+ directory. The parameters described in this section allow the
+ configuration files to be placed elsewhere. (Doing so can ease
+ administration. In particular it is often easier to ensure that
+ the configuration files are properly backed-up when they are
+ kept separate.)
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-data-directory" xreflabel="data_directory">
+ <term><varname>data_directory</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>data_directory</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the directory to use for data storage.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-config-file" xreflabel="config_file">
+ <term><varname>config_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>config_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the main server configuration file
+ (customarily called <filename>postgresql.conf</filename>).
+ This parameter can only be set on the <command>postgres</command> command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-hba-file" xreflabel="hba_file">
+ <term><varname>hba_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>hba_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the configuration file for host-based authentication
+ (customarily called <filename>pg_hba.conf</filename>).
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ident-file" xreflabel="ident_file">
+ <term><varname>ident_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ident_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the configuration file for user name mapping
+ (customarily called <filename>pg_ident.conf</filename>).
+ This parameter can only be set at server start.
+ See also <xref linkend="auth-username-maps"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-external-pid-file" xreflabel="external_pid_file">
+ <term><varname>external_pid_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>external_pid_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of an additional process-ID (PID) file that the
+ server should create for use by server administration programs.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ In a default installation, none of the above parameters are set
+ explicitly. Instead, the
+ data directory is specified by the <option>-D</option> command-line
+ option or the <envar>PGDATA</envar> environment variable, and the
+ configuration files are all found within the data directory.
+ </para>
+
+ <para>
+ If you wish to keep the configuration files elsewhere than the
+ data directory, the <command>postgres</command> <option>-D</option>
+ command-line option or <envar>PGDATA</envar> environment variable
+ must point to the directory containing the configuration files,
+ and the <varname>data_directory</varname> parameter must be set in
+ <filename>postgresql.conf</filename> (or on the command line) to show
+ where the data directory is actually located. Notice that
+ <varname>data_directory</varname> overrides <option>-D</option> and
+ <envar>PGDATA</envar> for the location
+ of the data directory, but not for the location of the configuration
+ files.
+ </para>
+
+ <para>
+ If you wish, you can specify the configuration file names and locations
+ individually using the parameters <varname>config_file</varname>,
+ <varname>hba_file</varname> and/or <varname>ident_file</varname>.
+ <varname>config_file</varname> can only be specified on the
+ <command>postgres</command> command line, but the others can be
+ set within the main configuration file. If all three parameters plus
+ <varname>data_directory</varname> are explicitly set, then it is not necessary
+ to specify <option>-D</option> or <envar>PGDATA</envar>.
+ </para>
+
+ <para>
+ When setting any of these parameters, a relative path will be interpreted
+ with respect to the directory in which <command>postgres</command>
+ is started.
+ </para>
+ </sect1>
+
+ <sect1 id="runtime-config-connection">
+ <title>Connections and Authentication</title>
+
+ <sect2 id="runtime-config-connection-settings">
+ <title>Connection Settings</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-listen-addresses" xreflabel="listen_addresses">
+ <term><varname>listen_addresses</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>listen_addresses</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the TCP/IP address(es) on which the server is
+ to listen for connections from client applications.
+ The value takes the form of a comma-separated list of host names
+ and/or numeric IP addresses. The special entry <literal>*</literal>
+ corresponds to all available IP interfaces. The entry
+ <literal>0.0.0.0</literal> allows listening for all IPv4 addresses and
+ <literal>::</literal> allows listening for all IPv6 addresses.
+ If the list is empty, the server does not listen on any IP interface
+ at all, in which case only Unix-domain sockets can be used to connect
+ to it.
+ The default value is <systemitem class="systemname">localhost</systemitem>,
+ which allows only local TCP/IP <quote>loopback</quote> connections to be
+ made. While client authentication (<xref
+ linkend="client-authentication"/>) allows fine-grained control
+ over who can access the server, <varname>listen_addresses</varname>
+ controls which interfaces accept connection attempts, which
+ can help prevent repeated malicious connection requests on
+ insecure network interfaces. This parameter can only be set
+ at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-port" xreflabel="port">
+ <term><varname>port</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>port</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The TCP port the server listens on; 5432 by default. Note that the
+ same port number is used for all IP addresses the server listens on.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-connections" xreflabel="max_connections">
+ <term><varname>max_connections</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_connections</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines the maximum number of concurrent connections to the
+ database server. The default is typically 100 connections, but
+ might be less if your kernel settings will not support it (as
+ determined during <application>initdb</application>). This parameter can
+ only be set at server start.
+ </para>
+
+ <para>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-superuser-reserved-connections"
+ xreflabel="superuser_reserved_connections">
+ <term><varname>superuser_reserved_connections</varname>
+ (<type>integer</type>)
+ <indexterm>
+ <primary><varname>superuser_reserved_connections</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines the number of connection <quote>slots</quote> that
+ are reserved for connections by <productname>PostgreSQL</productname>
+ superusers. At most <xref linkend="guc-max-connections"/>
+ connections can ever be active simultaneously. Whenever the
+ number of active concurrent connections is at least
+ <varname>max_connections</varname> minus
+ <varname>superuser_reserved_connections</varname>, new
+ connections will be accepted only for superusers, and no
+ new replication connections will be accepted.
+ </para>
+
+ <para>
+ The default value is three connections. The value must be less
+ than <varname>max_connections</varname>.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
+ <term><varname>unix_socket_directories</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>unix_socket_directories</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the directory of the Unix-domain socket(s) on which the
+ server is to listen for connections from client applications.
+ Multiple sockets can be created by listing multiple directories
+ separated by commas. Whitespace between entries is
+ ignored; surround a directory name with double quotes if you need
+ to include whitespace or commas in the name.
+ An empty value
+ specifies not listening on any Unix-domain sockets, in which case
+ only TCP/IP sockets can be used to connect to the server.
+ </para>
+
+ <para>
+ A value that starts with <literal>@</literal> specifies that a
+ Unix-domain socket in the abstract namespace should be created
+ (currently supported on Linux only). In that case, this value
+ does not specify a <quote>directory</quote> but a prefix from which
+ the actual socket name is computed in the same manner as for the
+ file-system namespace. While the abstract socket name prefix can be
+ chosen freely, since it is not a file-system location, the convention
+ is to nonetheless use file-system-like values such as
+ <literal>@/tmp</literal>.
+ </para>
+
+ <para>
+ The default value is normally
+ <filename>/tmp</filename>, but that can be changed at build time.
+ On Windows, the default is empty, which means no Unix-domain socket is
+ created by default.
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ In addition to the socket file itself, which is named
+ <literal>.s.PGSQL.<replaceable>nnnn</replaceable></literal> where
+ <replaceable>nnnn</replaceable> is the server's port number, an ordinary file
+ named <literal>.s.PGSQL.<replaceable>nnnn</replaceable>.lock</literal> will be
+ created in each of the <varname>unix_socket_directories</varname> directories.
+ Neither file should ever be removed manually.
+ For sockets in the abstract namespace, no lock file is created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-unix-socket-group" xreflabel="unix_socket_group">
+ <term><varname>unix_socket_group</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>unix_socket_group</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the owning group of the Unix-domain socket(s). (The owning
+ user of the sockets is always the user that starts the
+ server.) In combination with the parameter
+ <varname>unix_socket_permissions</varname> this can be used as
+ an additional access control mechanism for Unix-domain connections.
+ By default this is the empty string, which uses the default
+ group of the server user. This parameter can only be set at
+ server start.
+ </para>
+
+ <para>
+ This parameter is not supported on Windows. Any setting will be
+ ignored. Also, sockets in the abstract namespace have no file owner,
+ so this setting is also ignored in that case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-unix-socket-permissions" xreflabel="unix_socket_permissions">
+ <term><varname>unix_socket_permissions</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>unix_socket_permissions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the access permissions of the Unix-domain socket(s). Unix-domain
+ sockets use the usual Unix file system permission set.
+ The parameter value is expected to be a numeric mode
+ specified in the format accepted by the
+ <function>chmod</function> and <function>umask</function>
+ system calls. (To use the customary octal format the number
+ must start with a <literal>0</literal> (zero).)
+ </para>
+
+ <para>
+ The default permissions are <literal>0777</literal>, meaning
+ anyone can connect. Reasonable alternatives are
+ <literal>0770</literal> (only user and group, see also
+ <varname>unix_socket_group</varname>) and <literal>0700</literal>
+ (only user). (Note that for a Unix-domain socket, only write
+ permission matters, so there is no point in setting or revoking
+ read or execute permissions.)
+ </para>
+
+ <para>
+ This access control mechanism is independent of the one
+ described in <xref linkend="client-authentication"/>.
+ </para>
+
+ <para>
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ This parameter is irrelevant on systems, notably Solaris as of Solaris
+ 10, that ignore socket permissions entirely. There, one can achieve a
+ similar effect by pointing <varname>unix_socket_directories</varname> to a
+ directory having search permission limited to the desired audience.
+ </para>
+
+ <para>
+ Sockets in the abstract namespace have no file permissions, so this
+ setting is also ignored in that case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-bonjour" xreflabel="bonjour">
+ <term><varname>bonjour</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>bonjour</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables advertising the server's existence via
+ <productname>Bonjour</productname>. The default is off.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-bonjour-name" xreflabel="bonjour_name">
+ <term><varname>bonjour_name</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>bonjour_name</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the <productname>Bonjour</productname> service
+ name. The computer name is used if this parameter is set to the
+ empty string <literal>''</literal> (which is the default). This parameter is
+ ignored if the server was not compiled with
+ <productname>Bonjour</productname> support.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-tcp-keepalives-idle" xreflabel="tcp_keepalives_idle">
+ <term><varname>tcp_keepalives_idle</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>tcp_keepalives_idle</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the amount of time with no network activity after which
+ the operating system should send a TCP keepalive message to the client.
+ If this value is specified without units, it is taken as seconds.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <symbol>TCP_KEEPIDLE</symbol> or an equivalent socket option, and on
+ Windows; on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </para>
+ <note>
+ <para>
+ On Windows, setting a value of 0 will set this parameter to 2 hours,
+ since Windows does not provide a way to read the system default value.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-tcp-keepalives-interval" xreflabel="tcp_keepalives_interval">
+ <term><varname>tcp_keepalives_interval</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>tcp_keepalives_interval</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the amount of time after which a TCP keepalive message
+ that has not been acknowledged by the client should be retransmitted.
+ If this value is specified without units, it is taken as seconds.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <symbol>TCP_KEEPINTVL</symbol> or an equivalent socket option, and on
+ Windows; on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </para>
+ <note>
+ <para>
+ On Windows, setting a value of 0 will set this parameter to 1 second,
+ since Windows does not provide a way to read the system default value.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-tcp-keepalives-count" xreflabel="tcp_keepalives_count">
+ <term><varname>tcp_keepalives_count</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>tcp_keepalives_count</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the number of TCP keepalive messages that can be lost before
+ the server's connection to the client is considered dead.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <symbol>TCP_KEEPCNT</symbol> or an equivalent socket option;
+ on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </para>
+ <note>
+ <para>
+ This parameter is not supported on Windows, and must be zero.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-tcp-user-timeout" xreflabel="tcp_user_timeout">
+ <term><varname>tcp_user_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>tcp_user_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the amount of time that transmitted data may
+ remain unacknowledged before the TCP connection is forcibly closed.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <symbol>TCP_USER_TIMEOUT</symbol>; on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </para>
+ <note>
+ <para>
+ This parameter is not supported on Windows, and must be zero.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-client-connection-check-interval" xreflabel="client_connection_check_interval">
+ <term><varname>client_connection_check_interval</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>client_connection_check_interval</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the time interval between optional checks that the client is still
+ connected, while running queries. The check is performed by polling
+ the socket, and allows long running queries to be aborted sooner if
+ the kernel reports that the connection is closed.
+ </para>
+ <para>
+ This option relies on kernel events exposed by Linux, macOS, illumos
+ and the BSD family of operating systems, and is not currently available
+ on other systems.
+ </para>
+ <para>
+ If the value is specified without units, it is taken as milliseconds.
+ The default value is <literal>0</literal>, which disables connection
+ checks. Without connection checks, the server will detect the loss of
+ the connection only at the next interaction with the socket, when it
+ waits for, receives or sends data.
+ </para>
+ <para>
+ For the kernel itself to detect lost TCP connections reliably and within
+ a known timeframe in all scenarios including network failure, it may
+ also be necessary to adjust the TCP keepalive settings of the operating
+ system, or the <xref linkend="guc-tcp-keepalives-idle"/>,
+ <xref linkend="guc-tcp-keepalives-interval"/> and
+ <xref linkend="guc-tcp-keepalives-count"/> settings of
+ <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-connection-authentication">
+ <title>Authentication</title>
+
+ <variablelist>
+ <varlistentry id="guc-authentication-timeout" xreflabel="authentication_timeout">
+ <term><varname>authentication_timeout</varname> (<type>integer</type>)
+ <indexterm><primary>timeout</primary><secondary>client authentication</secondary></indexterm>
+ <indexterm><primary>client authentication</primary><secondary>timeout during</secondary></indexterm>
+ <indexterm>
+ <primary><varname>authentication_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ Maximum amount of time allowed to complete client authentication. If a
+ would-be client has not completed the authentication protocol in
+ this much time, the server closes the connection. This prevents
+ hung clients from occupying a connection indefinitely.
+ If this value is specified without units, it is taken as seconds.
+ The default is one minute (<literal>1m</literal>).
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-password-encryption" xreflabel="password_encryption">
+ <term><varname>password_encryption</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>password_encryption</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When a password is specified in <xref linkend="sql-createrole"/> or
+ <xref linkend="sql-alterrole"/>, this parameter determines the
+ algorithm to use to encrypt the password. Possible values are
+ <literal>scram-sha-256</literal>, which will encrypt the password with
+ SCRAM-SHA-256, and <literal>md5</literal>, which stores the password
+ as an MD5 hash. The default is <literal>scram-sha-256</literal>.
+ </para>
+ <para>
+ Note that older clients might lack support for the SCRAM authentication
+ mechanism, and hence not work with passwords encrypted with
+ SCRAM-SHA-256. See <xref linkend="auth-password"/> for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-krb-server-keyfile" xreflabel="krb_server_keyfile">
+ <term><varname>krb_server_keyfile</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>krb_server_keyfile</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the location of the server's Kerberos key file. The default is
+ <filename>FILE:/usr/local/pgsql/etc/krb5.keytab</filename>
+ (where the directory part is whatever was specified
+ as <varname>sysconfdir</varname> at build time; use
+ <literal>pg_config --sysconfdir</literal> to determine that).
+ If this parameter is set to an empty string, it is ignored and a
+ system-dependent default is used.
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ See <xref linkend="gssapi-auth"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-krb-caseins-users" xreflabel="krb_caseins_users">
+ <term><varname>krb_caseins_users</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>krb_caseins_users</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets whether GSSAPI user names should be treated
+ case-insensitively.
+ The default is <literal>off</literal> (case sensitive). This parameter can only be
+ set in the <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-db-user-namespace" xreflabel="db_user_namespace">
+ <term><varname>db_user_namespace</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>db_user_namespace</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter enables per-database user names. It is off by default.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+
+ <para>
+ If this is on, you should create users as <replaceable>username@dbname</replaceable>.
+ When <replaceable>username</replaceable> is passed by a connecting client,
+ <literal>@</literal> and the database name are appended to the user
+ name and that database-specific user name is looked up by the
+ server. Note that when you create users with names containing
+ <literal>@</literal> within the SQL environment, you will need to
+ quote the user name.
+ </para>
+
+ <para>
+ With this parameter enabled, you can still create ordinary global
+ users. Simply append <literal>@</literal> when specifying the user
+ name in the client, e.g., <literal>joe@</literal>. The <literal>@</literal>
+ will be stripped off before the user name is looked up by the
+ server.
+ </para>
+
+ <para>
+ <varname>db_user_namespace</varname> causes the client's and
+ server's user name representation to differ.
+ Authentication checks are always done with the server's user name
+ so authentication methods must be configured for the
+ server's user name, not the client's. Because
+ <literal>md5</literal> uses the user name as salt on both the
+ client and server, <literal>md5</literal> cannot be used with
+ <varname>db_user_namespace</varname>.
+ </para>
+
+ <note>
+ <para>
+ This feature is intended as a temporary measure until a
+ complete solution is found. At that time, this option will
+ be removed.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-connection-ssl">
+ <title>SSL</title>
+
+ <para>
+ See <xref linkend="ssl-tcp"/> for more information about setting up
+ <acronym>SSL</acronym>. The configuration parameters for controlling
+ transfer encryption using <acronym>TLS</acronym> protocols are named
+ <literal>ssl</literal> for historic reasons, even though support for
+ the <acronym>SSL</acronym> protocol has been deprecated.
+ <acronym>SSL</acronym> is in this context used interchangeably with
+ <acronym>TLS</acronym>.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-ssl" xreflabel="ssl">
+ <term><varname>ssl</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>ssl</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables <acronym>SSL</acronym> connections.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-ca-file" xreflabel="ssl_ca_file">
+ <term><varname>ssl_ca_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_ca_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate
+ authority (CA).
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is empty, meaning no CA file is loaded,
+ and client certificate verification is not performed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-cert-file" xreflabel="ssl_cert_file">
+ <term><varname>ssl_cert_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_cert_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server certificate.
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <filename>server.crt</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-crl-file" xreflabel="ssl_crl_file">
+ <term><varname>ssl_crl_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_crl_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL client certificate
+ revocation list (CRL).
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is empty, meaning no CRL file is loaded (unless
+ <xref linkend="guc-ssl-crl-dir"/> is set).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-crl-dir" xreflabel="ssl_crl_dir">
+ <term><varname>ssl_crl_dir</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_crl_dir</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the directory containing the SSL client
+ certificate revocation list (CRL). Relative paths are relative to the
+ data directory. This parameter can only be set in
+ the <filename>postgresql.conf</filename> file or on the server command
+ line. The default is empty, meaning no CRLs are used (unless
+ <xref linkend="guc-ssl-crl-file"/> is set).
+ </para>
+
+ <para>
+ The directory needs to be prepared with the
+ <productname>OpenSSL</productname> command
+ <literal>openssl rehash</literal> or <literal>c_rehash</literal>. See
+ its documentation for details.
+ </para>
+
+ <para>
+ When using this setting, CRLs in the specified directory are loaded
+ on-demand at connection time. New CRLs can be added to the directory
+ and will be used immediately. This is unlike <xref
+ linkend="guc-ssl-crl-file"/>, which causes the CRL in the file to be
+ loaded at server start time or when the configuration is reloaded.
+ Both settings can be used together.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-key-file" xreflabel="ssl_key_file">
+ <term><varname>ssl_key_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_key_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the file containing the SSL server private key.
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <filename>server.key</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers">
+ <term><varname>ssl_ciphers</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_ciphers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a list of <acronym>SSL</acronym> cipher suites that are
+ allowed to be used by SSL connections. See the
+ <citerefentry><refentrytitle>ciphers</refentrytitle></citerefentry>
+ manual page in the <productname>OpenSSL</productname> package for the
+ syntax of this setting and a list of supported values. Only
+ connections using TLS version 1.2 and lower are affected. There is
+ currently no setting that controls the cipher choices used by TLS
+ version 1.3 connections. The default value is
+ <literal>HIGH:MEDIUM:+3DES:!aNULL</literal>. The default is usually a
+ reasonable choice unless you have specific security requirements.
+ </para>
+
+ <para>
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command
+ line.
+ </para>
+
+ <para>
+ Explanation of the default value:
+ <variablelist>
+ <varlistentry>
+ <term><literal>HIGH</literal></term>
+ <listitem>
+ <para>
+ Cipher suites that use ciphers from <literal>HIGH</literal> group (e.g.,
+ AES, Camellia, 3DES)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MEDIUM</literal></term>
+ <listitem>
+ <para>
+ Cipher suites that use ciphers from <literal>MEDIUM</literal> group
+ (e.g., RC4, SEED)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>+3DES</literal></term>
+ <listitem>
+ <para>
+ The <productname>OpenSSL</productname> default order for
+ <literal>HIGH</literal> is problematic because it orders 3DES
+ higher than AES128. This is wrong because 3DES offers less
+ security than AES128, and it is also much slower.
+ <literal>+3DES</literal> reorders it after all other
+ <literal>HIGH</literal> and <literal>MEDIUM</literal> ciphers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>!aNULL</literal></term>
+ <listitem>
+ <para>
+ Disables anonymous cipher suites that do no authentication. Such
+ cipher suites are vulnerable to <acronym>MITM</acronym> attacks and
+ therefore should not be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Available cipher suite details will vary across
+ <productname>OpenSSL</productname> versions. Use the command
+ <literal>openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'</literal> to
+ see actual details for the currently installed
+ <productname>OpenSSL</productname> version. Note that this list is
+ filtered at run time based on the server key type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-prefer-server-ciphers" xreflabel="ssl_prefer_server_ciphers">
+ <term><varname>ssl_prefer_server_ciphers</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>ssl_prefer_server_ciphers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies whether to use the server's SSL cipher preferences, rather
+ than the client's.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <literal>on</literal>.
+ </para>
+
+ <para>
+ Older PostgreSQL versions do not have this setting and always use the
+ client's preferences. This setting is mainly for backward
+ compatibility with those versions. Using the server's preferences is
+ usually better because it is more likely that the server is appropriately
+ configured.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-ecdh-curve" xreflabel="ssl_ecdh_curve">
+ <term><varname>ssl_ecdh_curve</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_ecdh_curve</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the curve to use in <acronym>ECDH</acronym> key
+ exchange. It needs to be supported by all clients that connect.
+ It does not need to be the same curve used by the server's Elliptic
+ Curve key.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <literal>prime256v1</literal>.
+ </para>
+
+ <para>
+ <productname>OpenSSL</productname> names for the most common curves
+ are:
+ <literal>prime256v1</literal> (NIST P-256),
+ <literal>secp384r1</literal> (NIST P-384),
+ <literal>secp521r1</literal> (NIST P-521).
+ The full list of available curves can be shown with the command
+ <command>openssl ecparam -list_curves</command>. Not all of them
+ are usable in <acronym>TLS</acronym> though.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-min-protocol-version" xreflabel="ssl_min_protocol_version">
+ <term><varname>ssl_min_protocol_version</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>ssl_min_protocol_version</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the minimum SSL/TLS protocol version to use. Valid values are
+ currently: <literal>TLSv1</literal>, <literal>TLSv1.1</literal>,
+ <literal>TLSv1.2</literal>, <literal>TLSv1.3</literal>. Older
+ versions of the <productname>OpenSSL</productname> library do not
+ support all values; an error will be raised if an unsupported setting
+ is chosen. Protocol versions before TLS 1.0, namely SSL version 2 and
+ 3, are always disabled.
+ </para>
+
+ <para>
+ The default is <literal>TLSv1.2</literal>, which satisfies industry
+ best practices as of this writing.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-max-protocol-version" xreflabel="ssl_max_protocol_version">
+ <term><varname>ssl_max_protocol_version</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>ssl_max_protocol_version</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum SSL/TLS protocol version to use. Valid values are as
+ for <xref linkend="guc-ssl-min-protocol-version"/>, with addition of
+ an empty string, which allows any protocol version. The default is to
+ allow any version. Setting the maximum protocol version is mainly
+ useful for testing or if some component has issues working with a
+ newer protocol.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-dh-params-file" xreflabel="ssl_dh_params_file">
+ <term><varname>ssl_dh_params_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_dh_params_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the name of the file containing Diffie-Hellman parameters
+ used for so-called ephemeral DH family of SSL ciphers. The default is
+ empty, in which case compiled-in default DH parameters used. Using
+ custom DH parameters reduces the exposure if an attacker manages to
+ crack the well-known compiled-in DH parameters. You can create your own
+ DH parameters file with the command
+ <command>openssl dhparam -out dhparams.pem 2048</command>.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-passphrase-command" xreflabel="ssl_passphrase_command">
+ <term><varname>ssl_passphrase_command</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_passphrase_command</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets an external command to be invoked when a passphrase for
+ decrypting an SSL file such as a private key needs to be obtained. By
+ default, this parameter is empty, which means the built-in prompting
+ mechanism is used.
+ </para>
+ <para>
+ The command must print the passphrase to the standard output and exit
+ with code 0. In the parameter value, <literal>%p</literal> is
+ replaced by a prompt string. (Write <literal>%%</literal> for a
+ literal <literal>%</literal>.) Note that the prompt string will
+ probably contain whitespace, so be sure to quote adequately. A single
+ newline is stripped from the end of the output if present.
+ </para>
+ <para>
+ The command does not actually have to prompt the user for a
+ passphrase. It can read it from a file, obtain it from a keychain
+ facility, or similar. It is up to the user to make sure the chosen
+ mechanism is adequately secure.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-passphrase-command-supports-reload" xreflabel="ssl_passphrase_command_supports_reload">
+ <term><varname>ssl_passphrase_command_supports_reload</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>ssl_passphrase_command_supports_reload</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter determines whether the passphrase command set by
+ <varname>ssl_passphrase_command</varname> will also be called during a
+ configuration reload if a key file needs a passphrase. If this
+ parameter is off (the default), then
+ <varname>ssl_passphrase_command</varname> will be ignored during a
+ reload and the SSL configuration will not be reloaded if a passphrase
+ is needed. That setting is appropriate for a command that requires a
+ TTY for prompting, which might not be available when the server is
+ running. Setting this parameter to on might be appropriate if the
+ passphrase is obtained from a file, for example.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-resource">
+ <title>Resource Consumption</title>
+
+ <sect2 id="runtime-config-resource-memory">
+ <title>Memory</title>
+
+ <variablelist>
+ <varlistentry id="guc-shared-buffers" xreflabel="shared_buffers">
+ <term><varname>shared_buffers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>shared_buffers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the amount of memory the database server uses for shared
+ memory buffers. The default is typically 128 megabytes
+ (<literal>128MB</literal>), but might be less if your kernel settings will
+ not support it (as determined during <application>initdb</application>).
+ This setting must be at least 128 kilobytes. However,
+ settings significantly higher than the minimum are usually needed
+ for good performance.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ (Non-default values of <symbol>BLCKSZ</symbol> change the minimum
+ value.)
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ If you have a dedicated database server with 1GB or more of RAM, a
+ reasonable starting value for <varname>shared_buffers</varname> is 25%
+ of the memory in your system. There are some workloads where even
+ larger settings for <varname>shared_buffers</varname> are effective, but
+ because <productname>PostgreSQL</productname> also relies on the
+ operating system cache, it is unlikely that an allocation of more than
+ 40% of RAM to <varname>shared_buffers</varname> will work better than a
+ smaller amount. Larger settings for <varname>shared_buffers</varname>
+ usually require a corresponding increase in
+ <varname>max_wal_size</varname>, in order to spread out the
+ process of writing large quantities of new or changed data over a
+ longer period of time.
+ </para>
+
+ <para>
+ On systems with less than 1GB of RAM, a smaller percentage of RAM is
+ appropriate, so as to leave adequate space for the operating system.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-huge-pages" xreflabel="huge_pages">
+ <term><varname>huge_pages</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>huge_pages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls whether huge pages are requested for the main shared memory
+ area. Valid values are <literal>try</literal> (the default),
+ <literal>on</literal>, and <literal>off</literal>. With
+ <varname>huge_pages</varname> set to <literal>try</literal>, the
+ server will try to request huge pages, but fall back to the default if
+ that fails. With <literal>on</literal>, failure to request huge pages
+ will prevent the server from starting up. With <literal>off</literal>,
+ huge pages will not be requested.
+ </para>
+
+ <para>
+ At present, this setting is supported only on Linux and Windows. The
+ setting is ignored on other systems when set to
+ <literal>try</literal>. On Linux, it is only supported when
+ <varname>shared_memory_type</varname> is set to <literal>mmap</literal>
+ (the default).
+ </para>
+
+ <para>
+ The use of huge pages results in smaller page tables and less CPU time
+ spent on memory management, increasing performance. For more details about
+ using huge pages on Linux, see <xref linkend="linux-huge-pages"/>.
+ </para>
+
+ <para>
+ Huge pages are known as large pages on Windows. To use them, you need to
+ assign the user right <quote>Lock pages in memory</quote> to the Windows user account
+ that runs <productname>PostgreSQL</productname>.
+ You can use Windows Group Policy tool (gpedit.msc) to assign the user right
+ <quote>Lock pages in memory</quote>.
+ To start the database server on the command prompt as a standalone process,
+ not as a Windows service, the command prompt must be run as an administrator or
+ User Access Control (UAC) must be disabled. When the UAC is enabled, the normal
+ command prompt revokes the user right <quote>Lock pages in memory</quote> when started.
+ </para>
+
+ <para>
+ Note that this setting only affects the main shared memory area.
+ Operating systems such as Linux, FreeBSD, and Illumos can also use
+ huge pages (also known as <quote>super</quote> pages or
+ <quote>large</quote> pages) automatically for normal memory
+ allocation, without an explicit request from
+ <productname>PostgreSQL</productname>. On Linux, this is called
+ <quote>transparent huge pages</quote><indexterm><primary>transparent
+ huge pages</primary></indexterm> (THP). That feature has been known to
+ cause performance degradation with
+ <productname>PostgreSQL</productname> for some users on some Linux
+ versions, so its use is currently discouraged (unlike explicit use of
+ <varname>huge_pages</varname>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-huge-page-size" xreflabel="huge_page_size">
+ <term><varname>huge_page_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>huge_page_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the size of huge pages, when they are enabled with
+ <xref linkend="guc-huge-pages"/>.
+ The default is zero (<literal>0</literal>).
+ When set to <literal>0</literal>, the default huge page size on the
+ system will be used. This parameter can only be set at server start.
+ </para>
+ <para>
+ Some commonly available page sizes on modern 64 bit server architectures include:
+ <literal>2MB</literal> and <literal>1GB</literal> (Intel and AMD), <literal>16MB</literal> and
+ <literal>16GB</literal> (IBM POWER), and <literal>64kB</literal>, <literal>2MB</literal>,
+ <literal>32MB</literal> and <literal>1GB</literal> (ARM). For more information
+ about usage and support, see <xref linkend="linux-huge-pages"/>.
+ </para>
+ <para>
+ Non-default settings are currently supported only on Linux.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-temp-buffers" xreflabel="temp_buffers">
+ <term><varname>temp_buffers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>temp_buffers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum amount of memory used for temporary buffers within
+ each database session. These are session-local buffers used only
+ for access to temporary tables.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The default is eight megabytes (<literal>8MB</literal>).
+ (If <symbol>BLCKSZ</symbol> is not 8kB, the default value scales
+ proportionally to it.)
+ This setting can be changed within individual
+ sessions, but only before the first use of temporary tables
+ within the session; subsequent attempts to change the value will
+ have no effect on that session.
+ </para>
+
+ <para>
+ A session will allocate temporary buffers as needed up to the limit
+ given by <varname>temp_buffers</varname>. The cost of setting a large
+ value in sessions that do not actually need many temporary
+ buffers is only a buffer descriptor, or about 64 bytes, per
+ increment in <varname>temp_buffers</varname>. However if a buffer is
+ actually used an additional 8192 bytes will be consumed for it
+ (or in general, <symbol>BLCKSZ</symbol> bytes).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-prepared-transactions" xreflabel="max_prepared_transactions">
+ <term><varname>max_prepared_transactions</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_prepared_transactions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of transactions that can be in the
+ <quote>prepared</quote> state simultaneously (see <xref
+ linkend="sql-prepare-transaction"/>).
+ Setting this parameter to zero (which is the default)
+ disables the prepared-transaction feature.
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ If you are not planning to use prepared transactions, this parameter
+ should be set to zero to prevent accidental creation of prepared
+ transactions. If you are using prepared transactions, you will
+ probably want <varname>max_prepared_transactions</varname> to be at
+ least as large as <xref linkend="guc-max-connections"/>, so that every
+ session can have a prepared transaction pending.
+ </para>
+
+ <para>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-work-mem" xreflabel="work_mem">
+ <term><varname>work_mem</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>work_mem</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the base maximum amount of memory to be used by a query operation
+ (such as a sort or hash table) before writing to temporary disk files.
+ If this value is specified without units, it is taken as kilobytes.
+ The default value is four megabytes (<literal>4MB</literal>).
+ Note that for a complex query, several sort or hash operations might be
+ running in parallel; each operation will generally be allowed
+ to use as much memory as this value specifies before it starts
+ to write data into temporary files. Also, several running
+ sessions could be doing such operations concurrently.
+ Therefore, the total memory used could be many times the value
+ of <varname>work_mem</varname>; it is necessary to keep this
+ fact in mind when choosing the value. Sort operations are used
+ for <literal>ORDER BY</literal>, <literal>DISTINCT</literal>,
+ and merge joins.
+ Hash tables are used in hash joins, hash-based aggregation, memoize
+ nodes and hash-based processing of <literal>IN</literal> subqueries.
+ </para>
+ <para>
+ Hash-based operations are generally more sensitive to memory
+ availability than equivalent sort-based operations. The
+ memory available for hash tables is computed by multiplying
+ <varname>work_mem</varname> by
+ <varname>hash_mem_multiplier</varname>. This makes it
+ possible for hash-based operations to use an amount of memory
+ that exceeds the usual <varname>work_mem</varname> base
+ amount.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-hash-mem-multiplier" xreflabel="hash_mem_multiplier">
+ <term><varname>hash_mem_multiplier</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>hash_mem_multiplier</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Used to compute the maximum amount of memory that hash-based
+ operations can use. The final limit is determined by
+ multiplying <varname>work_mem</varname> by
+ <varname>hash_mem_multiplier</varname>. The default value is
+ 2.0, which makes hash-based operations use twice the usual
+ <varname>work_mem</varname> base amount.
+ </para>
+ <para>
+ Consider increasing <varname>hash_mem_multiplier</varname> in
+ environments where spilling by query operations is a regular
+ occurrence, especially when simply increasing
+ <varname>work_mem</varname> results in memory pressure (memory
+ pressure typically takes the form of intermittent out of
+ memory errors). The default setting of 2.0 is often effective with
+ mixed workloads. Higher settings in the range of 2.0 - 8.0 or
+ more may be effective in environments where
+ <varname>work_mem</varname> has already been increased to 40MB
+ or more.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-maintenance-work-mem" xreflabel="maintenance_work_mem">
+ <term><varname>maintenance_work_mem</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>maintenance_work_mem</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum amount of memory to be used by maintenance
+ operations, such as <command>VACUUM</command>, <command>CREATE
+ INDEX</command>, and <command>ALTER TABLE ADD FOREIGN KEY</command>.
+ If this value is specified without units, it is taken as kilobytes.
+ It defaults
+ to 64 megabytes (<literal>64MB</literal>). Since only one of these
+ operations can be executed at a time by a database session, and
+ an installation normally doesn't have many of them running
+ concurrently, it's safe to set this value significantly larger
+ than <varname>work_mem</varname>. Larger settings might improve
+ performance for vacuuming and for restoring database dumps.
+ </para>
+ <para>
+ Note that when autovacuum runs, up to
+ <xref linkend="guc-autovacuum-max-workers"/> times this memory
+ may be allocated, so be careful not to set the default value
+ too high. It may be useful to control for this by separately
+ setting <xref linkend="guc-autovacuum-work-mem"/>.
+ </para>
+ <para>
+ Note that for the collection of dead tuple identifiers,
+ <command>VACUUM</command> is only able to utilize up to a maximum of
+ <literal>1GB</literal> of memory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-work-mem" xreflabel="autovacuum_work_mem">
+ <term><varname>autovacuum_work_mem</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_work_mem</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum amount of memory to be used by each
+ autovacuum worker process.
+ If this value is specified without units, it is taken as kilobytes.
+ It defaults to -1, indicating that
+ the value of <xref linkend="guc-maintenance-work-mem"/> should
+ be used instead. The setting has no effect on the behavior of
+ <command>VACUUM</command> when run in other contexts.
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command
+ line.
+ </para>
+ <para>
+ For the collection of dead tuple identifiers, autovacuum is only able
+ to utilize up to a maximum of <literal>1GB</literal> of memory, so
+ setting <varname>autovacuum_work_mem</varname> to a value higher than
+ that has no effect on the number of dead tuples that autovacuum can
+ collect while scanning a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-logical-decoding-work-mem" xreflabel="logical_decoding_work_mem">
+ <term><varname>logical_decoding_work_mem</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>logical_decoding_work_mem</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum amount of memory to be used by logical decoding,
+ before some of the decoded changes are written to local disk. This
+ limits the amount of memory used by logical streaming replication
+ connections. It defaults to 64 megabytes (<literal>64MB</literal>).
+ Since each replication connection only uses a single buffer of this size,
+ and an installation normally doesn't have many such connections
+ concurrently (as limited by <varname>max_wal_senders</varname>), it's
+ safe to set this value significantly higher than <varname>work_mem</varname>,
+ reducing the amount of decoded changes written to disk.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-stack-depth" xreflabel="max_stack_depth">
+ <term><varname>max_stack_depth</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_stack_depth</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum safe depth of the server's execution stack.
+ The ideal setting for this parameter is the actual stack size limit
+ enforced by the kernel (as set by <literal>ulimit -s</literal> or local
+ equivalent), less a safety margin of a megabyte or so. The safety
+ margin is needed because the stack depth is not checked in every
+ routine in the server, but only in key potentially-recursive routines.
+ If this value is specified without units, it is taken as kilobytes.
+ The default setting is two megabytes (<literal>2MB</literal>), which
+ is conservatively small and unlikely to risk crashes. However,
+ it might be too small to allow execution of complex functions.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ Setting <varname>max_stack_depth</varname> higher than
+ the actual kernel limit will mean that a runaway recursive function
+ can crash an individual backend process. On platforms where
+ <productname>PostgreSQL</productname> can determine the kernel limit,
+ the server will not allow this variable to be set to an unsafe
+ value. However, not all platforms provide the information,
+ so caution is recommended in selecting a value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-shared-memory-type" xreflabel="shared_memory_type">
+ <term><varname>shared_memory_type</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>shared_memory_type</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the shared memory implementation that the server
+ should use for the main shared memory region that holds
+ <productname>PostgreSQL</productname>'s shared buffers and other
+ shared data. Possible values are <literal>mmap</literal> (for
+ anonymous shared memory allocated using <function>mmap</function>),
+ <literal>sysv</literal> (for System V shared memory allocated via
+ <function>shmget</function>) and <literal>windows</literal> (for Windows
+ shared memory). Not all values are supported on all platforms; the
+ first supported option is the default for that platform. The use of
+ the <literal>sysv</literal> option, which is not the default on any
+ platform, is generally discouraged because it typically requires
+ non-default kernel settings to allow for large allocations (see <xref
+ linkend="sysvipc"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-dynamic-shared-memory-type" xreflabel="dynamic_shared_memory_type">
+ <term><varname>dynamic_shared_memory_type</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>dynamic_shared_memory_type</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the dynamic shared memory implementation that the server
+ should use. Possible values are <literal>posix</literal> (for POSIX shared
+ memory allocated using <literal>shm_open</literal>), <literal>sysv</literal>
+ (for System V shared memory allocated via <literal>shmget</literal>),
+ <literal>windows</literal> (for Windows shared memory),
+ and <literal>mmap</literal> (to simulate shared memory using
+ memory-mapped files stored in the data directory).
+ Not all values are supported on all platforms; the first supported
+ option is usually the default for that platform. The use of the
+ <literal>mmap</literal> option, which is not the default on any platform,
+ is generally discouraged because the operating system may write
+ modified pages back to disk repeatedly, increasing system I/O load;
+ however, it may be useful for debugging, when the
+ <literal>pg_dynshmem</literal> directory is stored on a RAM disk, or when
+ other shared memory facilities are not available.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-min-dynamic-shared-memory" xreflabel="min_dynamic_shared_memory">
+ <term><varname>min_dynamic_shared_memory</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>min_dynamic_shared_memory</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the amount of memory that should be allocated at server
+ startup for use by parallel queries. When this memory region is
+ insufficient or exhausted by concurrent queries, new parallel queries
+ try to allocate extra shared memory temporarily from the operating
+ system using the method configured with
+ <varname>dynamic_shared_memory_type</varname>, which may be slower due
+ to memory management overheads. Memory that is allocated at startup
+ with <varname>min_dynamic_shared_memory</varname> is affected by
+ the <varname>huge_pages</varname> setting on operating systems where
+ that is supported, and may be more likely to benefit from larger pages
+ on operating systems where that is managed automatically.
+ The default value is <literal>0</literal> (none). This parameter can
+ only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-resource-disk">
+ <title>Disk</title>
+
+ <variablelist>
+ <varlistentry id="guc-temp-file-limit" xreflabel="temp_file_limit">
+ <term><varname>temp_file_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>temp_file_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum amount of disk space that a process can use
+ for temporary files, such as sort and hash temporary files, or the
+ storage file for a held cursor. A transaction attempting to exceed
+ this limit will be canceled.
+ If this value is specified without units, it is taken as kilobytes.
+ <literal>-1</literal> (the default) means no limit.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ <para>
+ This setting constrains the total space used at any instant by all
+ temporary files used by a given <productname>PostgreSQL</productname> process.
+ It should be noted that disk space used for explicit temporary
+ tables, as opposed to temporary files used behind-the-scenes in query
+ execution, does <emphasis>not</emphasis> count against this limit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-resource-kernel">
+ <title>Kernel Resource Usage</title>
+
+ <variablelist>
+ <varlistentry id="guc-max-files-per-process" xreflabel="max_files_per_process">
+ <term><varname>max_files_per_process</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_files_per_process</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of simultaneously open files allowed to each
+ server subprocess. The default is one thousand files. If the kernel is enforcing
+ a safe per-process limit, you don't need to worry about this setting.
+ But on some platforms (notably, most BSD systems), the kernel will
+ allow individual processes to open many more files than the system
+ can actually support if many processes all try to open
+ that many files. If you find yourself seeing <quote>Too many open
+ files</quote> failures, try reducing this setting.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-resource-vacuum-cost">
+ <title>Cost-based Vacuum Delay</title>
+
+ <para>
+ During the execution of <xref linkend="sql-vacuum"/>
+ and <xref linkend="sql-analyze"/>
+ commands, the system maintains an
+ internal counter that keeps track of the estimated cost of the
+ various I/O operations that are performed. When the accumulated
+ cost reaches a limit (specified by
+ <varname>vacuum_cost_limit</varname>), the process performing
+ the operation will sleep for a short period of time, as specified by
+ <varname>vacuum_cost_delay</varname>. Then it will reset the
+ counter and continue execution.
+ </para>
+
+ <para>
+ The intent of this feature is to allow administrators to reduce
+ the I/O impact of these commands on concurrent database
+ activity. There are many situations where it is not
+ important that maintenance commands like
+ <command>VACUUM</command> and <command>ANALYZE</command> finish
+ quickly; however, it is usually very important that these
+ commands do not significantly interfere with the ability of the
+ system to perform other database operations. Cost-based vacuum
+ delay provides a way for administrators to achieve this.
+ </para>
+
+ <para>
+ This feature is disabled by default for manually issued
+ <command>VACUUM</command> commands. To enable it, set the
+ <varname>vacuum_cost_delay</varname> variable to a nonzero
+ value.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-vacuum-cost-delay" xreflabel="vacuum_cost_delay">
+ <term><varname>vacuum_cost_delay</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>vacuum_cost_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The amount of time that the process will sleep
+ when the cost limit has been exceeded.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is zero, which disables the cost-based vacuum
+ delay feature. Positive values enable cost-based vacuuming.
+ </para>
+
+ <para>
+ When using cost-based vacuuming, appropriate values for
+ <varname>vacuum_cost_delay</varname> are usually quite small, perhaps
+ less than 1 millisecond. While <varname>vacuum_cost_delay</varname>
+ can be set to fractional-millisecond values, such delays may not be
+ measured accurately on older platforms. On such platforms,
+ increasing <command>VACUUM</command>'s throttled resource consumption
+ above what you get at 1ms will require changing the other vacuum cost
+ parameters. You should, nonetheless,
+ keep <varname>vacuum_cost_delay</varname> as small as your platform
+ will consistently measure; large delays are not helpful.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-cost-page-hit" xreflabel="vacuum_cost_page_hit">
+ <term><varname>vacuum_cost_page_hit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_cost_page_hit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The estimated cost for vacuuming a buffer found in the shared buffer
+ cache. It represents the cost to lock the buffer pool, lookup
+ the shared hash table and scan the content of the page. The
+ default value is one.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-cost-page-miss" xreflabel="vacuum_cost_page_miss">
+ <term><varname>vacuum_cost_page_miss</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_cost_page_miss</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The estimated cost for vacuuming a buffer that has to be read from
+ disk. This represents the effort to lock the buffer pool,
+ lookup the shared hash table, read the desired block in from
+ the disk and scan its content. The default value is 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-cost-page-dirty" xreflabel="vacuum_cost_page_dirty">
+ <term><varname>vacuum_cost_page_dirty</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_cost_page_dirty</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The estimated cost charged when vacuum modifies a block that was
+ previously clean. It represents the extra I/O required to
+ flush the dirty block out to disk again. The default value is
+ 20.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-cost-limit" xreflabel="vacuum_cost_limit">
+ <term><varname>vacuum_cost_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_cost_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The accumulated cost that will cause the vacuuming process to sleep.
+ The default value is 200.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <note>
+ <para>
+ There are certain operations that hold critical locks and should
+ therefore complete as quickly as possible. Cost-based vacuum
+ delays do not occur during such operations. Therefore it is
+ possible that the cost accumulates far higher than the specified
+ limit. To avoid uselessly long delays in such cases, the actual
+ delay is calculated as <varname>vacuum_cost_delay</varname> *
+ <varname>accumulated_balance</varname> /
+ <varname>vacuum_cost_limit</varname> with a maximum of
+ <varname>vacuum_cost_delay</varname> * 4.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="runtime-config-resource-background-writer">
+ <title>Background Writer</title>
+
+ <para>
+ There is a separate server
+ process called the <firstterm>background writer</firstterm>, whose function
+ is to issue writes of <quote>dirty</quote> (new or modified) shared
+ buffers. When the number of clean shared buffers appears to be
+ insufficient, the background writer writes some dirty buffers to the
+ file system and marks them as clean. This reduces the likelihood
+ that server processes handling user queries will be unable to find
+ clean buffers and have to write dirty buffers themselves.
+ However, the background writer does cause a net overall
+ increase in I/O load, because while a repeatedly-dirtied page might
+ otherwise be written only once per checkpoint interval, the
+ background writer might write it several times as it is dirtied
+ in the same interval. The parameters discussed in this subsection
+ can be used to tune the behavior for local needs.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-bgwriter-delay" xreflabel="bgwriter_delay">
+ <term><varname>bgwriter_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>bgwriter_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the delay between activity rounds for the
+ background writer. In each round the writer issues writes
+ for some number of dirty buffers (controllable by the
+ following parameters). It then sleeps for
+ the length of <varname>bgwriter_delay</varname>, and repeats.
+ When there are no dirty buffers in the
+ buffer pool, though, it goes into a longer sleep regardless of
+ <varname>bgwriter_delay</varname>.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 200
+ milliseconds (<literal>200ms</literal>). Note that on many systems, the
+ effective resolution of sleep delays is 10 milliseconds; setting
+ <varname>bgwriter_delay</varname> to a value that is not a multiple of 10
+ might have the same results as setting it to the next higher multiple
+ of 10. This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-bgwriter-lru-maxpages" xreflabel="bgwriter_lru_maxpages">
+ <term><varname>bgwriter_lru_maxpages</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>bgwriter_lru_maxpages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ In each round, no more than this many buffers will be written
+ by the background writer. Setting this to zero disables
+ background writing. (Note that checkpoints, which are managed by
+ a separate, dedicated auxiliary process, are unaffected.)
+ The default value is 100 buffers.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-bgwriter-lru-multiplier" xreflabel="bgwriter_lru_multiplier">
+ <term><varname>bgwriter_lru_multiplier</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>bgwriter_lru_multiplier</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The number of dirty buffers written in each round is based on the
+ number of new buffers that have been needed by server processes
+ during recent rounds. The average recent need is multiplied by
+ <varname>bgwriter_lru_multiplier</varname> to arrive at an estimate of the
+ number of buffers that will be needed during the next round. Dirty
+ buffers are written until there are that many clean, reusable buffers
+ available. (However, no more than <varname>bgwriter_lru_maxpages</varname>
+ buffers will be written per round.)
+ Thus, a setting of 1.0 represents a <quote>just in time</quote> policy
+ of writing exactly the number of buffers predicted to be needed.
+ Larger values provide some cushion against spikes in demand,
+ while smaller values intentionally leave writes to be done by
+ server processes.
+ The default is 2.0.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-bgwriter-flush-after" xreflabel="bgwriter_flush_after">
+ <term><varname>bgwriter_flush_after</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>bgwriter_flush_after</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Whenever more than this amount of data has
+ been written by the background writer, attempt to force the OS to issue these
+ writes to the underlying storage. Doing so will limit the amount of
+ dirty data in the kernel's page cache, reducing the likelihood of
+ stalls when an <function>fsync</function> is issued at the end of a checkpoint, or when
+ the OS writes data back in larger batches in the background. Often
+ that will result in greatly reduced transaction latency, but there
+ also are some cases, especially with workloads that are bigger than
+ <xref linkend="guc-shared-buffers"/>, but smaller than the OS's page
+ cache, where performance might degrade. This setting may have no
+ effect on some platforms.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The valid range is between
+ <literal>0</literal>, which disables forced writeback, and
+ <literal>2MB</literal>. The default is <literal>512kB</literal> on Linux,
+ <literal>0</literal> elsewhere. (If <symbol>BLCKSZ</symbol> is not 8kB,
+ the default and maximum values scale proportionally to it.)
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Smaller values of <varname>bgwriter_lru_maxpages</varname> and
+ <varname>bgwriter_lru_multiplier</varname> reduce the extra I/O load
+ caused by the background writer, but make it more likely that server
+ processes will have to issue writes for themselves, delaying interactive
+ queries.
+ </para>
+ </sect2>
+
+ <sect2 id="runtime-config-resource-async-behavior">
+ <title>Asynchronous Behavior</title>
+
+ <variablelist>
+ <varlistentry id="guc-backend-flush-after" xreflabel="backend_flush_after">
+ <term><varname>backend_flush_after</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>backend_flush_after</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Whenever more than this amount of data has
+ been written by a single backend, attempt to force the OS to issue
+ these writes to the underlying storage. Doing so will limit the
+ amount of dirty data in the kernel's page cache, reducing the
+ likelihood of stalls when an <function>fsync</function> is issued at the end of a
+ checkpoint, or when the OS writes data back in larger batches in the
+ background. Often that will result in greatly reduced transaction
+ latency, but there also are some cases, especially with workloads
+ that are bigger than <xref linkend="guc-shared-buffers"/>, but smaller
+ than the OS's page cache, where performance might degrade. This
+ setting may have no effect on some platforms.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The valid range is
+ between <literal>0</literal>, which disables forced writeback,
+ and <literal>2MB</literal>. The default is <literal>0</literal>, i.e., no
+ forced writeback. (If <symbol>BLCKSZ</symbol> is not 8kB,
+ the maximum value scales proportionally to it.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-effective-io-concurrency" xreflabel="effective_io_concurrency">
+ <term><varname>effective_io_concurrency</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>effective_io_concurrency</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the number of concurrent disk I/O operations that
+ <productname>PostgreSQL</productname> expects can be executed
+ simultaneously. Raising this value will increase the number of I/O
+ operations that any individual <productname>PostgreSQL</productname> session
+ attempts to initiate in parallel. The allowed range is 1 to 1000,
+ or zero to disable issuance of asynchronous I/O requests. Currently,
+ this setting only affects bitmap heap scans.
+ </para>
+
+ <para>
+ For magnetic drives, a good starting point for this setting is the
+ number of separate
+ drives comprising a RAID 0 stripe or RAID 1 mirror being used for the
+ database. (For RAID 5 the parity drive should not be counted.)
+ However, if the database is often busy with multiple queries issued in
+ concurrent sessions, lower values may be sufficient to keep the disk
+ array busy. A value higher than needed to keep the disks busy will
+ only result in extra CPU overhead.
+ SSDs and other memory-based storage can often process many
+ concurrent requests, so the best value might be in the hundreds.
+ </para>
+
+ <para>
+ Asynchronous I/O depends on an effective <function>posix_fadvise</function>
+ function, which some operating systems lack. If the function is not
+ present then setting this parameter to anything but zero will result
+ in an error. On some operating systems (e.g., Solaris), the function
+ is present but does not actually do anything.
+ </para>
+
+ <para>
+ The default is 1 on supported systems, otherwise 0. This value can
+ be overridden for tables in a particular tablespace by setting the
+ tablespace parameter of the same name (see
+ <xref linkend="sql-altertablespace"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-maintenance-io-concurrency" xreflabel="maintenance_io_concurrency">
+ <term><varname>maintenance_io_concurrency</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>maintenance_io_concurrency</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Similar to <varname>effective_io_concurrency</varname>, but used
+ for maintenance work that is done on behalf of many client sessions.
+ </para>
+ <para>
+ The default is 10 on supported systems, otherwise 0. This value can
+ be overridden for tables in a particular tablespace by setting the
+ tablespace parameter of the same name (see
+ <xref linkend="sql-altertablespace"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-worker-processes" xreflabel="max_worker_processes">
+ <term><varname>max_worker_processes</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_worker_processes</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of background processes that the system
+ can support. This parameter can only be set at server start. The
+ default is 8.
+ </para>
+
+ <para>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </para>
+
+ <para>
+ When changing this value, consider also adjusting
+ <xref linkend="guc-max-parallel-workers"/>,
+ <xref linkend="guc-max-parallel-maintenance-workers"/>, and
+ <xref linkend="guc-max-parallel-workers-per-gather"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-parallel-workers-per-gather" xreflabel="max_parallel_workers_per_gather">
+ <term><varname>max_parallel_workers_per_gather</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_parallel_workers_per_gather</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of workers that can be started by a single
+ <literal>Gather</literal> or <literal>Gather Merge</literal> node.
+ Parallel workers are taken from the pool of processes established by
+ <xref linkend="guc-max-worker-processes"/>, limited by
+ <xref linkend="guc-max-parallel-workers"/>. Note that the requested
+ number of workers may not actually be available at run time. If this
+ occurs, the plan will run with fewer workers than expected, which may
+ be inefficient. The default value is 2. Setting this value to 0
+ disables parallel query execution.
+ </para>
+
+ <para>
+ Note that parallel queries may consume very substantially more
+ resources than non-parallel queries, because each worker process is
+ a completely separate process which has roughly the same impact on the
+ system as an additional user session. This should be taken into
+ account when choosing a value for this setting, as well as when
+ configuring other settings that control resource utilization, such
+ as <xref linkend="guc-work-mem"/>. Resource limits such as
+ <varname>work_mem</varname> are applied individually to each worker,
+ which means the total utilization may be much higher across all
+ processes than it would normally be for any single process.
+ For example, a parallel query using 4 workers may use up to 5 times
+ as much CPU time, memory, I/O bandwidth, and so forth as a query which
+ uses no workers at all.
+ </para>
+
+ <para>
+ For more information on parallel query, see
+ <xref linkend="parallel-query"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-parallel-maintenance-workers" xreflabel="max_parallel_maintenance_workers">
+ <term><varname>max_parallel_maintenance_workers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_parallel_maintenance_workers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of parallel workers that can be
+ started by a single utility command. Currently, the parallel
+ utility commands that support the use of parallel workers are
+ <command>CREATE INDEX</command> only when building a B-tree index,
+ and <command>VACUUM</command> without <literal>FULL</literal>
+ option. Parallel workers are taken from the pool of processes
+ established by <xref linkend="guc-max-worker-processes"/>, limited
+ by <xref linkend="guc-max-parallel-workers"/>. Note that the requested
+ number of workers may not actually be available at run time.
+ If this occurs, the utility operation will run with fewer
+ workers than expected. The default value is 2. Setting this
+ value to 0 disables the use of parallel workers by utility
+ commands.
+ </para>
+
+ <para>
+ Note that parallel utility commands should not consume
+ substantially more memory than equivalent non-parallel
+ operations. This strategy differs from that of parallel
+ query, where resource limits generally apply per worker
+ process. Parallel utility commands treat the resource limit
+ <varname>maintenance_work_mem</varname> as a limit to be applied to
+ the entire utility command, regardless of the number of
+ parallel worker processes. However, parallel utility
+ commands may still consume substantially more CPU resources
+ and I/O bandwidth.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-parallel-workers" xreflabel="max_parallel_workers">
+ <term><varname>max_parallel_workers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_parallel_workers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum number of workers that the system can support for
+ parallel operations. The default value is 8. When increasing or
+ decreasing this value, consider also adjusting
+ <xref linkend="guc-max-parallel-maintenance-workers"/> and
+ <xref linkend="guc-max-parallel-workers-per-gather"/>.
+ Also, note that a setting for this value which is higher than
+ <xref linkend="guc-max-worker-processes"/> will have no effect,
+ since parallel workers are taken from the pool of worker processes
+ established by that setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-parallel-leader-participation" xreflabel="parallel_leader_participation">
+ <term>
+ <varname>parallel_leader_participation</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>parallel_leader_participation</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Allows the leader process to execute the query plan under
+ <literal>Gather</literal> and <literal>Gather Merge</literal> nodes
+ instead of waiting for worker processes. The default is
+ <literal>on</literal>. Setting this value to <literal>off</literal>
+ reduces the likelihood that workers will become blocked because the
+ leader is not reading tuples fast enough, but requires the leader
+ process to wait for worker processes to start up before the first
+ tuples can be produced. The degree to which the leader can help or
+ hinder performance depends on the plan type, number of workers and
+ query duration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-old-snapshot-threshold" xreflabel="old_snapshot_threshold">
+ <term><varname>old_snapshot_threshold</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>old_snapshot_threshold</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the minimum amount of time that a query snapshot can be used
+ without risk of a <quote>snapshot too old</quote> error occurring
+ when using the snapshot. Data that has been dead for longer than
+ this threshold is allowed to be vacuumed away. This can help
+ prevent bloat in the face of snapshots which remain in use for a
+ long time. To prevent incorrect results due to cleanup of data which
+ would otherwise be visible to the snapshot, an error is generated
+ when the snapshot is older than this threshold and the snapshot is
+ used to read a page which has been modified since the snapshot was
+ built.
+ </para>
+
+ <para>
+ If this value is specified without units, it is taken as minutes.
+ A value of <literal>-1</literal> (the default) disables this feature,
+ effectively setting the snapshot age limit to infinity.
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ Useful values for production work probably range from a small number
+ of hours to a few days. Small values (such as <literal>0</literal> or
+ <literal>1min</literal>) are only allowed because they may sometimes be
+ useful for testing. While a setting as high as <literal>60d</literal> is
+ allowed, please note that in many workloads extreme bloat or
+ transaction ID wraparound may occur in much shorter time frames.
+ </para>
+
+ <para>
+ When this feature is enabled, freed space at the end of a relation
+ cannot be released to the operating system, since that could remove
+ information needed to detect the <quote>snapshot too old</quote>
+ condition. All space allocated to a relation remains associated with
+ that relation for reuse only within that relation unless explicitly
+ freed (for example, with <command>VACUUM FULL</command>).
+ </para>
+
+ <para>
+ This setting does not attempt to guarantee that an error will be
+ generated under any particular circumstances. In fact, if the
+ correct results can be generated from (for example) a cursor which
+ has materialized a result set, no error will be generated even if the
+ underlying rows in the referenced table have been vacuumed away.
+ Some tables cannot safely be vacuumed early, and so will not be
+ affected by this setting, such as system catalogs. For such tables
+ this setting will neither reduce bloat nor create a possibility
+ of a <quote>snapshot too old</quote> error on scanning.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-wal">
+ <title>Write Ahead Log</title>
+
+ <para>
+ For additional information on tuning these settings,
+ see <xref linkend="wal-configuration"/>.
+ </para>
+
+ <sect2 id="runtime-config-wal-settings">
+ <title>Settings</title>
+ <variablelist>
+
+ <varlistentry id="guc-wal-level" xreflabel="wal_level">
+ <term><varname>wal_level</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>wal_level</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <varname>wal_level</varname> determines how much information is written to
+ the WAL. The default value is <literal>replica</literal>, which writes enough
+ data to support WAL archiving and replication, including running
+ read-only queries on a standby server. <literal>minimal</literal> removes all
+ logging except the information required to recover from a crash or
+ immediate shutdown. Finally,
+ <literal>logical</literal> adds information necessary to support logical
+ decoding. Each level includes the information logged at all lower
+ levels. This parameter can only be set at server start.
+ </para>
+ <para>
+ The <literal>minimal</literal> level generates the least WAL
+ volume. It logs no row information for permanent relations
+ in transactions that create or
+ rewrite them. This can make operations much faster (see
+ <xref linkend="populate-pitr"/>). Operations that initiate this
+ optimization include:
+ <simplelist>
+ <member><command>ALTER ... SET TABLESPACE</command></member>
+ <member><command>CLUSTER</command></member>
+ <member><command>CREATE TABLE</command></member>
+ <member><command>REFRESH MATERIALIZED VIEW</command>
+ (without <option>CONCURRENTLY</option>)</member>
+ <member><command>REINDEX</command></member>
+ <member><command>TRUNCATE</command></member>
+ </simplelist>
+ However, minimal WAL does not contain sufficient information for
+ point-in-time recovery, so <literal>replica</literal> or
+ higher must be used to enable continuous archiving
+ (<xref linkend="guc-archive-mode"/>) and streaming binary replication.
+ In fact, the server will not even start in this mode if
+ <varname>max_wal_senders</varname> is non-zero.
+ Note that changing <varname>wal_level</varname> to
+ <literal>minimal</literal> makes previous base backups unusable
+ for point-in-time recovery and standby servers.
+ </para>
+ <para>
+ In <literal>logical</literal> level, the same information is logged as
+ with <literal>replica</literal>, plus information needed to
+ extract logical change sets from the WAL. Using a level of
+ <literal>logical</literal> will increase the WAL volume, particularly if many
+ tables are configured for <literal>REPLICA IDENTITY FULL</literal> and
+ many <command>UPDATE</command> and <command>DELETE</command> statements are
+ executed.
+ </para>
+ <para>
+ In releases prior to 9.6, this parameter also allowed the
+ values <literal>archive</literal> and <literal>hot_standby</literal>.
+ These are still accepted but mapped to <literal>replica</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-fsync" xreflabel="fsync">
+ <term><varname>fsync</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>fsync</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If this parameter is on, the <productname>PostgreSQL</productname> server
+ will try to make sure that updates are physically written to
+ disk, by issuing <function>fsync()</function> system calls or various
+ equivalent methods (see <xref linkend="guc-wal-sync-method"/>).
+ This ensures that the database cluster can recover to a
+ consistent state after an operating system or hardware crash.
+ </para>
+
+ <para>
+ While turning off <varname>fsync</varname> is often a performance
+ benefit, this can result in unrecoverable data corruption in
+ the event of a power failure or system crash. Thus it
+ is only advisable to turn off <varname>fsync</varname> if
+ you can easily recreate your entire database from external
+ data.
+ </para>
+
+ <para>
+ Examples of safe circumstances for turning off
+ <varname>fsync</varname> include the initial loading of a new
+ database cluster from a backup file, using a database cluster
+ for processing a batch of data after which the database
+ will be thrown away and recreated,
+ or for a read-only database clone which
+ gets recreated frequently and is not used for failover. High
+ quality hardware alone is not a sufficient justification for
+ turning off <varname>fsync</varname>.
+ </para>
+
+ <para>
+ For reliable recovery when changing <varname>fsync</varname>
+ off to on, it is necessary to force all modified buffers in the
+ kernel to durable storage. This can be done while the cluster
+ is shutdown or while <varname>fsync</varname> is on by running <command>initdb
+ --sync-only</command>, running <command>sync</command>, unmounting the
+ file system, or rebooting the server.
+ </para>
+
+ <para>
+ In many situations, turning off <xref linkend="guc-synchronous-commit"/>
+ for noncritical transactions can provide much of the potential
+ performance benefit of turning off <varname>fsync</varname>, without
+ the attendant risks of data corruption.
+ </para>
+
+ <para>
+ <varname>fsync</varname> can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ If you turn this parameter off, also consider turning off
+ <xref linkend="guc-full-page-writes"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-synchronous-commit" xreflabel="synchronous_commit">
+ <term><varname>synchronous_commit</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>synchronous_commit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies how much WAL processing must complete before
+ the database server returns a <quote>success</quote>
+ indication to the client. Valid values are
+ <literal>remote_apply</literal>, <literal>on</literal>
+ (the default), <literal>remote_write</literal>,
+ <literal>local</literal>, and <literal>off</literal>.
+ </para>
+
+ <para>
+ If <varname>synchronous_standby_names</varname> is empty,
+ the only meaningful settings are <literal>on</literal> and
+ <literal>off</literal>; <literal>remote_apply</literal>,
+ <literal>remote_write</literal> and <literal>local</literal>
+ all provide the same local synchronization level
+ as <literal>on</literal>. The local behavior of all
+ non-<literal>off</literal> modes is to wait for local flush of WAL
+ to disk. In <literal>off</literal> mode, there is no waiting,
+ so there can be a delay between when success is reported to the
+ client and when the transaction is later guaranteed to be safe
+ against a server crash. (The maximum
+ delay is three times <xref linkend="guc-wal-writer-delay"/>.) Unlike
+ <xref linkend="guc-fsync"/>, setting this parameter to <literal>off</literal>
+ does not create any risk of database inconsistency: an operating
+ system or database crash might
+ result in some recent allegedly-committed transactions being lost, but
+ the database state will be just the same as if those transactions had
+ been aborted cleanly. So, turning <varname>synchronous_commit</varname> off
+ can be a useful alternative when performance is more important than
+ exact certainty about the durability of a transaction. For more
+ discussion see <xref linkend="wal-async-commit"/>.
+ </para>
+
+ <para>
+ If <xref linkend="guc-synchronous-standby-names"/> is non-empty,
+ <varname>synchronous_commit</varname> also controls whether
+ transaction commits will wait for their WAL records to be
+ processed on the standby server(s).
+ </para>
+
+ <para>
+ When set to <literal>remote_apply</literal>, commits will wait
+ until replies from the current synchronous standby(s) indicate they
+ have received the commit record of the transaction and applied
+ it, so that it has become visible to queries on the standby(s),
+ and also written to durable storage on the standbys. This will
+ cause much larger commit delays than previous settings since
+ it waits for WAL replay. When set to <literal>on</literal>,
+ commits wait until replies
+ from the current synchronous standby(s) indicate they have received
+ the commit record of the transaction and flushed it to durable storage. This
+ ensures the transaction will not be lost unless both the primary and
+ all synchronous standbys suffer corruption of their database storage.
+ When set to <literal>remote_write</literal>, commits will wait until replies
+ from the current synchronous standby(s) indicate they have
+ received the commit record of the transaction and written it to
+ their file systems. This setting ensures data preservation if a standby instance of
+ <productname>PostgreSQL</productname> crashes, but not if the standby
+ suffers an operating-system-level crash because the data has not
+ necessarily reached durable storage on the standby.
+ The setting <literal>local</literal> causes commits to wait for
+ local flush to disk, but not for replication. This is usually not
+ desirable when synchronous replication is in use, but is provided for
+ completeness.
+ </para>
+
+ <para>
+ This parameter can be changed at any time; the behavior for any
+ one transaction is determined by the setting in effect when it
+ commits. It is therefore possible, and useful, to have some
+ transactions commit synchronously and others asynchronously.
+ For example, to make a single multistatement transaction commit
+ asynchronously when the default is the opposite, issue <command>SET
+ LOCAL synchronous_commit TO OFF</command> within the transaction.
+ </para>
+
+ <para>
+ <xref linkend="synchronous-commit-matrix"/> summarizes the
+ capabilities of the <varname>synchronous_commit</varname> settings.
+ </para>
+
+ <table id="synchronous-commit-matrix">
+ <title>synchronous_commit Modes</title>
+ <tgroup cols="5">
+ <colspec colname="col1" colwidth="1.5*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <colspec colname="col5" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>synchronous_commit setting</entry>
+ <entry>local durable commit</entry>
+ <entry>standby durable commit after PG crash</entry>
+ <entry>standby durable commit after OS crash</entry>
+ <entry>standby query consistency</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry>remote_apply</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ <row>
+ <entry>on</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ </row>
+
+ <row>
+ <entry>remote_write</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ </row>
+
+ <row>
+ <entry>local</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ </row>
+
+ <row>
+ <entry>off</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-sync-method" xreflabel="wal_sync_method">
+ <term><varname>wal_sync_method</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>wal_sync_method</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Method used for forcing WAL updates out to disk.
+ If <varname>fsync</varname> is off then this setting is irrelevant,
+ since WAL file updates will not be forced out at all.
+ Possible values are:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>open_datasync</literal> (write WAL files with <function>open()</function> option <symbol>O_DSYNC</symbol>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>fdatasync</literal> (call <function>fdatasync()</function> at each commit)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>fsync</literal> (call <function>fsync()</function> at each commit)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>fsync_writethrough</literal> (call <function>fsync()</function> at each commit, forcing write-through of any disk write cache)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>open_sync</literal> (write WAL files with <function>open()</function> option <symbol>O_SYNC</symbol>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The <literal>open_</literal>* options also use <literal>O_DIRECT</literal> if available.
+ Not all of these choices are available on all platforms.
+ The default is the first method in the above list that is supported
+ by the platform, except that <literal>fdatasync</literal> is the default on
+ Linux and FreeBSD. The default is not necessarily ideal; it might be
+ necessary to change this setting or other aspects of your system
+ configuration in order to create a crash-safe configuration or
+ achieve optimal performance.
+ These aspects are discussed in <xref linkend="wal-reliability"/>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-full-page-writes" xreflabel="full_page_writes">
+ <term><varname>full_page_writes</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>full_page_writes</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When this parameter is on, the <productname>PostgreSQL</productname> server
+ writes the entire content of each disk page to WAL during the
+ first modification of that page after a checkpoint.
+ This is needed because
+ a page write that is in process during an operating system crash might
+ be only partially completed, leading to an on-disk page
+ that contains a mix of old and new data. The row-level change data
+ normally stored in WAL will not be enough to completely restore
+ such a page during post-crash recovery. Storing the full page image
+ guarantees that the page can be correctly restored, but at the price
+ of increasing the amount of data that must be written to WAL.
+ (Because WAL replay always starts from a checkpoint, it is sufficient
+ to do this during the first change of each page after a checkpoint.
+ Therefore, one way to reduce the cost of full-page writes is to
+ increase the checkpoint interval parameters.)
+ </para>
+
+ <para>
+ Turning this parameter off speeds normal operation, but
+ might lead to either unrecoverable data corruption, or silent
+ data corruption, after a system failure. The risks are similar to turning off
+ <varname>fsync</varname>, though smaller, and it should be turned off
+ only based on the same circumstances recommended for that parameter.
+ </para>
+
+ <para>
+ Turning off this parameter does not affect use of
+ WAL archiving for point-in-time recovery (PITR)
+ (see <xref linkend="continuous-archiving"/>).
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-log-hints" xreflabel="wal_log_hints">
+ <term><varname>wal_log_hints</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>wal_log_hints</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When this parameter is <literal>on</literal>, the <productname>PostgreSQL</productname>
+ server writes the entire content of each disk page to WAL during the
+ first modification of that page after a checkpoint, even for
+ non-critical modifications of so-called hint bits.
+ </para>
+
+ <para>
+ If data checksums are enabled, hint bit updates are always WAL-logged
+ and this setting is ignored. You can use this setting to test how much
+ extra WAL-logging would occur if your database had data checksums
+ enabled.
+ </para>
+
+ <para>
+ This parameter can only be set at server start. The default value is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-compression" xreflabel="wal_compression">
+ <term><varname>wal_compression</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>wal_compression</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter enables compression of WAL using the specified
+ compression method.
+ When enabled, the <productname>PostgreSQL</productname>
+ server compresses full page images written to WAL when
+ <xref linkend="guc-full-page-writes"/> is on or during a base backup.
+ A compressed page image will be decompressed during WAL replay.
+ The supported methods are <literal>pglz</literal>,
+ <literal>lz4</literal> (if <productname>PostgreSQL</productname>
+ was compiled with <option>--with-lz4</option>) and
+ <literal>zstd</literal> (if <productname>PostgreSQL</productname>
+ was compiled with <option>--with-zstd</option>).
+ The default value is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ Enabling compression can reduce the WAL volume without
+ increasing the risk of unrecoverable data corruption,
+ but at the cost of some extra CPU spent on the compression during
+ WAL logging and on the decompression during WAL replay.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-init-zero" xreflabel="wal_init_zero">
+ <term><varname>wal_init_zero</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>wal_init_zero</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If set to <literal>on</literal> (the default), this option causes new
+ WAL files to be filled with zeroes. On some file systems, this ensures
+ that space is allocated before we need to write WAL records. However,
+ <firstterm>Copy-On-Write</firstterm> (COW) file systems may not benefit
+ from this technique, so the option is given to skip the unnecessary
+ work. If set to <literal>off</literal>, only the final byte is written
+ when the file is created so that it has the expected size.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-recycle" xreflabel="wal_recycle">
+ <term><varname>wal_recycle</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>wal_recycle</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If set to <literal>on</literal> (the default), this option causes WAL
+ files to be recycled by renaming them, avoiding the need to create new
+ ones. On COW file systems, it may be faster to create new ones, so the
+ option is given to disable this behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-buffers" xreflabel="wal_buffers">
+ <term><varname>wal_buffers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_buffers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The amount of shared memory used for WAL data that has not yet been
+ written to disk. The default setting of -1 selects a size equal to
+ 1/32nd (about 3%) of <xref linkend="guc-shared-buffers"/>, but not less
+ than <literal>64kB</literal> nor more than the size of one WAL
+ segment, typically <literal>16MB</literal>. This value can be set
+ manually if the automatic choice is too large or too small,
+ but any positive value less than <literal>32kB</literal> will be
+ treated as <literal>32kB</literal>.
+ If this value is specified without units, it is taken as WAL blocks,
+ that is <symbol>XLOG_BLCKSZ</symbol> bytes, typically 8kB.
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ The contents of the WAL buffers are written out to disk at every
+ transaction commit, so extremely large values are unlikely to
+ provide a significant benefit. However, setting this value to at
+ least a few megabytes can improve write performance on a busy
+ server where many clients are committing at once. The auto-tuning
+ selected by the default setting of -1 should give reasonable
+ results in most cases.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-writer-delay" xreflabel="wal_writer_delay">
+ <term><varname>wal_writer_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_writer_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies how often the WAL writer flushes WAL, in time terms.
+ After flushing WAL the writer sleeps for the length of time given
+ by <varname>wal_writer_delay</varname>, unless woken up sooner
+ by an asynchronously committing transaction. If the last flush
+ happened less than <varname>wal_writer_delay</varname> ago and less
+ than <varname>wal_writer_flush_after</varname> worth of WAL has been
+ produced since, then WAL is only written to the operating system, not
+ flushed to disk.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 200 milliseconds (<literal>200ms</literal>). Note that
+ on many systems, the effective resolution of sleep delays is 10
+ milliseconds; setting <varname>wal_writer_delay</varname> to a value that is
+ not a multiple of 10 might have the same results as setting it to the
+ next higher multiple of 10. This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-writer-flush-after" xreflabel="wal_writer_flush_after">
+ <term><varname>wal_writer_flush_after</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_writer_flush_after</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies how often the WAL writer flushes WAL, in volume terms.
+ If the last flush happened less
+ than <varname>wal_writer_delay</varname> ago and less
+ than <varname>wal_writer_flush_after</varname> worth of WAL has been
+ produced since, then WAL is only written to the operating system, not
+ flushed to disk. If <varname>wal_writer_flush_after</varname> is set
+ to <literal>0</literal> then WAL data is always flushed immediately.
+ If this value is specified without units, it is taken as WAL blocks,
+ that is <symbol>XLOG_BLCKSZ</symbol> bytes, typically 8kB.
+ The default is <literal>1MB</literal>.
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-skip-threshold" xreflabel="wal_skip_threshold">
+ <term><varname>wal_skip_threshold</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_skip_threshold</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>wal_level</varname> is <literal>minimal</literal> and a
+ transaction commits after creating or rewriting a permanent relation,
+ this setting determines how to persist the new data. If the data is
+ smaller than this setting, write it to the WAL log; otherwise, use an
+ fsync of affected files. Depending on the properties of your storage,
+ raising or lowering this value might help if such commits are slowing
+ concurrent transactions. If this value is specified without units, it
+ is taken as kilobytes. The default is two megabytes
+ (<literal>2MB</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-commit-delay" xreflabel="commit_delay">
+ <term><varname>commit_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>commit_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Setting <varname>commit_delay</varname> adds a time delay
+ before a WAL flush is initiated. This can improve
+ group commit throughput by allowing a larger number of transactions
+ to commit via a single WAL flush, if system load is high enough
+ that additional transactions become ready to commit within the
+ given interval. However, it also increases latency by up to the
+ <varname>commit_delay</varname> for each WAL
+ flush. Because the delay is just wasted if no other transactions
+ become ready to commit, a delay is only performed if at least
+ <varname>commit_siblings</varname> other transactions are active
+ when a flush is about to be initiated. Also, no delays are
+ performed if <varname>fsync</varname> is disabled.
+ If this value is specified without units, it is taken as microseconds.
+ The default <varname>commit_delay</varname> is zero (no delay).
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ <para>
+ In <productname>PostgreSQL</productname> releases prior to 9.3,
+ <varname>commit_delay</varname> behaved differently and was much
+ less effective: it affected only commits, rather than all WAL flushes,
+ and waited for the entire configured delay even if the WAL flush
+ was completed sooner. Beginning in <productname>PostgreSQL</productname> 9.3,
+ the first process that becomes ready to flush waits for the configured
+ interval, while subsequent processes wait only until the leader
+ completes the flush operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-commit-siblings" xreflabel="commit_siblings">
+ <term><varname>commit_siblings</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>commit_siblings</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Minimum number of concurrent open transactions to require
+ before performing the <varname>commit_delay</varname> delay. A larger
+ value makes it more probable that at least one other
+ transaction will become ready to commit during the delay
+ interval. The default is five transactions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-wal-checkpoints">
+ <title>Checkpoints</title>
+
+ <variablelist>
+ <varlistentry id="guc-checkpoint-timeout" xreflabel="checkpoint_timeout">
+ <term><varname>checkpoint_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>checkpoint_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Maximum time between automatic WAL checkpoints.
+ If this value is specified without units, it is taken as seconds.
+ The valid range is between 30 seconds and one day.
+ The default is five minutes (<literal>5min</literal>).
+ Increasing this parameter can increase the amount of time needed
+ for crash recovery.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-checkpoint-completion-target" xreflabel="checkpoint_completion_target">
+ <term><varname>checkpoint_completion_target</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>checkpoint_completion_target</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the target of checkpoint completion, as a fraction of
+ total time between checkpoints. The default is 0.9, which spreads the
+ checkpoint across almost all of the available interval, providing fairly
+ consistent I/O load while also leaving some time for checkpoint
+ completion overhead. Reducing this parameter is not recommended because
+ it causes the checkpoint to complete faster. This results in a higher
+ rate of I/O during the checkpoint followed by a period of less I/O between
+ the checkpoint completion and the next scheduled checkpoint. This
+ parameter can only be set in the <filename>postgresql.conf</filename> file
+ or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-checkpoint-flush-after" xreflabel="checkpoint_flush_after">
+ <term><varname>checkpoint_flush_after</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>checkpoint_flush_after</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Whenever more than this amount of data has been
+ written while performing a checkpoint, attempt to force the
+ OS to issue these writes to the underlying storage. Doing so will
+ limit the amount of dirty data in the kernel's page cache, reducing
+ the likelihood of stalls when an <function>fsync</function> is issued at the end of the
+ checkpoint, or when the OS writes data back in larger batches in the
+ background. Often that will result in greatly reduced transaction
+ latency, but there also are some cases, especially with workloads
+ that are bigger than <xref linkend="guc-shared-buffers"/>, but smaller
+ than the OS's page cache, where performance might degrade. This
+ setting may have no effect on some platforms.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The valid range is
+ between <literal>0</literal>, which disables forced writeback,
+ and <literal>2MB</literal>. The default is <literal>256kB</literal> on
+ Linux, <literal>0</literal> elsewhere. (If <symbol>BLCKSZ</symbol> is not
+ 8kB, the default and maximum values scale proportionally to it.)
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-checkpoint-warning" xreflabel="checkpoint_warning">
+ <term><varname>checkpoint_warning</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>checkpoint_warning</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Write a message to the server log if checkpoints caused by
+ the filling of WAL segment files happen closer together
+ than this amount of time (which suggests that
+ <varname>max_wal_size</varname> ought to be raised).
+ If this value is specified without units, it is taken as seconds.
+ The default is 30 seconds (<literal>30s</literal>).
+ Zero disables the warning.
+ No warnings will be generated if <varname>checkpoint_timeout</varname>
+ is less than <varname>checkpoint_warning</varname>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-wal-size" xreflabel="max_wal_size">
+ <term><varname>max_wal_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_wal_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Maximum size to let the WAL grow during automatic
+ checkpoints. This is a soft limit; WAL size can exceed
+ <varname>max_wal_size</varname> under special circumstances, such as
+ heavy load, a failing <varname>archive_command</varname> or <varname>archive_library</varname>, or a high
+ <varname>wal_keep_size</varname> setting.
+ If this value is specified without units, it is taken as megabytes.
+ The default is 1 GB.
+ Increasing this parameter can increase the amount of time needed for
+ crash recovery.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-min-wal-size" xreflabel="min_wal_size">
+ <term><varname>min_wal_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>min_wal_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ As long as WAL disk usage stays below this setting, old WAL files are
+ always recycled for future use at a checkpoint, rather than removed.
+ This can be used to ensure that enough WAL space is reserved to
+ handle spikes in WAL usage, for example when running large batch
+ jobs.
+ If this value is specified without units, it is taken as megabytes.
+ The default is 80 MB.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-wal-archiving">
+ <title>Archiving</title>
+
+ <variablelist>
+ <varlistentry id="guc-archive-mode" xreflabel="archive_mode">
+ <term><varname>archive_mode</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>archive_mode</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>archive_mode</varname> is enabled, completed WAL segments
+ are sent to archive storage by setting
+ <xref linkend="guc-archive-command"/> or
+ <xref linkend="guc-archive-library"/>. In addition to <literal>off</literal>,
+ to disable, there are two modes: <literal>on</literal>, and
+ <literal>always</literal>. During normal operation, there is no
+ difference between the two modes, but when set to <literal>always</literal>
+ the WAL archiver is enabled also during archive recovery or standby
+ mode. In <literal>always</literal> mode, all files restored from the archive
+ or streamed with streaming replication will be archived (again). See
+ <xref linkend="continuous-archiving-in-standby"/> for details.
+ </para>
+ <para>
+ <varname>archive_mode</varname> is a separate setting from
+ <varname>archive_command</varname> and
+ <varname>archive_library</varname> so that
+ <varname>archive_command</varname> and
+ <varname>archive_library</varname> can be changed without leaving
+ archiving mode.
+ This parameter can only be set at server start.
+ <varname>archive_mode</varname> cannot be enabled when
+ <varname>wal_level</varname> is set to <literal>minimal</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-archive-command" xreflabel="archive_command">
+ <term><varname>archive_command</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>archive_command</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The local shell command to execute to archive a completed WAL file
+ segment. Any <literal>%p</literal> in the string is
+ replaced by the path name of the file to archive, and any
+ <literal>%f</literal> is replaced by only the file name.
+ (The path name is relative to the working directory of the server,
+ i.e., the cluster's data directory.)
+ Use <literal>%%</literal> to embed an actual <literal>%</literal> character in the
+ command. It is important for the command to return a zero
+ exit status only if it succeeds. For more information see
+ <xref linkend="backup-archiving-wal"/>.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line. It is ignored unless
+ <varname>archive_mode</varname> was enabled at server start and
+ <varname>archive_library</varname> is set to an empty string.
+ If <varname>archive_command</varname> is an empty string (the default) while
+ <varname>archive_mode</varname> is enabled (and <varname>archive_library</varname>
+ is set to an empty string), WAL archiving is temporarily
+ disabled, but the server continues to accumulate WAL segment files in
+ the expectation that a command will soon be provided. Setting
+ <varname>archive_command</varname> to a command that does nothing but
+ return true, e.g., <literal>/bin/true</literal> (<literal>REM</literal> on
+ Windows), effectively disables
+ archiving, but also breaks the chain of WAL files needed for
+ archive recovery, so it should only be used in unusual circumstances.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-archive-library" xreflabel="archive_library">
+ <term><varname>archive_library</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>archive_library</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The library to use for archiving completed WAL file segments. If set to
+ an empty string (the default), archiving via shell is enabled, and
+ <xref linkend="guc-archive-command"/> is used. Otherwise, the specified
+ shared library is used for archiving. The WAL archiver process is
+ restarted by the postmaster when this parameter changes. For more
+ information, see <xref linkend="backup-archiving-wal"/> and
+ <xref linkend="archive-modules"/>.
+ </para>
+ <para>
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-archive-timeout" xreflabel="archive_timeout">
+ <term><varname>archive_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>archive_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The <xref linkend="guc-archive-command"/> or <xref linkend="guc-archive-library"/> is only invoked for
+ completed WAL segments. Hence, if your server generates little WAL
+ traffic (or has slack periods where it does so), there could be a
+ long delay between the completion of a transaction and its safe
+ recording in archive storage. To limit how old unarchived
+ data can be, you can set <varname>archive_timeout</varname> to force the
+ server to switch to a new WAL segment file periodically. When this
+ parameter is greater than zero, the server will switch to a new
+ segment file whenever this amount of time has elapsed since the last
+ segment file switch, and there has been any database activity,
+ including a single checkpoint (checkpoints are skipped if there is
+ no database activity). Note that archived files that are closed
+ early due to a forced switch are still the same length as completely
+ full files. Therefore, it is unwise to use a very short
+ <varname>archive_timeout</varname> &mdash; it will bloat your archive
+ storage. <varname>archive_timeout</varname> settings of a minute or so are
+ usually reasonable. You should consider using streaming replication,
+ instead of archiving, if you want data to be copied off the primary
+ server more quickly than that.
+ If this value is specified without units, it is taken as seconds.
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-wal-recovery">
+
+ <title>Recovery</title>
+
+ <indexterm>
+ <primary>configuration</primary>
+ <secondary>of recovery</secondary>
+ <tertiary>general settings</tertiary>
+ </indexterm>
+
+ <para>
+ This section describes the settings that apply to recovery in general,
+ affecting crash recovery, streaming replication and archive-based
+ replication.
+ </para>
+
+
+ <variablelist>
+ <varlistentry id="guc-recovery-prefetch" xreflabel="recovery_prefetch">
+ <term><varname>recovery_prefetch</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>recovery_prefetch</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Whether to try to prefetch blocks that are referenced in the WAL that
+ are not yet in the buffer pool, during recovery. Valid values are
+ <literal>off</literal>, <literal>on</literal> and
+ <literal>try</literal> (the default). The setting
+ <literal>try</literal> enables
+ prefetching only if the operating system provides the
+ <function>posix_fadvise</function> function, which is currently used
+ to implement prefetching. Note that some operating systems provide the
+ function, but it doesn't do anything.
+ </para>
+ <para>
+ Prefetching blocks that will soon be needed can reduce I/O wait times
+ during recovery with some workloads.
+ See also the <xref linkend="guc-wal-decode-buffer-size"/> and
+ <xref linkend="guc-maintenance-io-concurrency"/> settings, which limit
+ prefetching activity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-decode-buffer-size" xreflabel="wal_decode_buffer_size">
+ <term><varname>wal_decode_buffer_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_decode_buffer_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ A limit on how far ahead the server can look in the WAL, to find
+ blocks to prefetch. If this value is specified without units, it is
+ taken as bytes.
+ The default is 512kB.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-wal-archive-recovery">
+
+ <title>Archive Recovery</title>
+
+ <indexterm>
+ <primary>configuration</primary>
+ <secondary>of recovery</secondary>
+ <tertiary>of a standby server</tertiary>
+ </indexterm>
+
+ <para>
+ This section describes the settings that apply only for the duration of
+ the recovery. They must be reset for any subsequent recovery you wish to
+ perform.
+ </para>
+
+ <para>
+ <quote>Recovery</quote> covers using the server as a standby or for
+ executing a targeted recovery. Typically, standby mode would be used to
+ provide high availability and/or read scalability, whereas a targeted
+ recovery is used to recover from data loss.
+ </para>
+
+ <para>
+ To start the server in standby mode, create a file called
+ <filename>standby.signal</filename><indexterm><primary>standby.signal</primary></indexterm>
+ in the data directory. The server will enter recovery and will not stop
+ recovery when the end of archived WAL is reached, but will keep trying to
+ continue recovery by connecting to the sending server as specified by the
+ <varname>primary_conninfo</varname> setting and/or by fetching new WAL
+ segments using <varname>restore_command</varname>. For this mode, the
+ parameters from this section and <xref
+ linkend="runtime-config-replication-standby"/> are of interest.
+ Parameters from <xref linkend="runtime-config-wal-recovery-target"/> will
+ also be applied but are typically not useful in this mode.
+ </para>
+
+ <para>
+ To start the server in targeted recovery mode, create a file called
+ <filename>recovery.signal</filename><indexterm><primary>recovery.signal</primary></indexterm>
+ in the data directory. If both <filename>standby.signal</filename> and
+ <filename>recovery.signal</filename> files are created, standby mode
+ takes precedence. Targeted recovery mode ends when the archived WAL is
+ fully replayed, or when <varname>recovery_target</varname> is reached.
+ In this mode, the parameters from both this section and <xref
+ linkend="runtime-config-wal-recovery-target"/> will be used.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-restore-command" xreflabel="restore_command">
+ <term><varname>restore_command</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>restore_command</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The local shell command to execute to retrieve an archived segment of
+ the WAL file series. This parameter is required for archive recovery,
+ but optional for streaming replication.
+ Any <literal>%f</literal> in the string is
+ replaced by the name of the file to retrieve from the archive,
+ and any <literal>%p</literal> is replaced by the copy destination path name
+ on the server.
+ (The path name is relative to the current working directory,
+ i.e., the cluster's data directory.)
+ Any <literal>%r</literal> is replaced by the name of the file containing the
+ last valid restart point. That is the earliest file that must be kept
+ to allow a restore to be restartable, so this information can be used
+ to truncate the archive to just the minimum required to support
+ restarting from the current restore. <literal>%r</literal> is typically only
+ used by warm-standby configurations
+ (see <xref linkend="warm-standby"/>).
+ Write <literal>%%</literal> to embed an actual <literal>%</literal> character.
+ </para>
+
+ <para>
+ It is important for the command to return a zero exit status
+ only if it succeeds. The command <emphasis>will</emphasis> be asked for file
+ names that are not present in the archive; it must return nonzero
+ when so asked. Examples:
+<programlisting>
+restore_command = 'cp /mnt/server/archivedir/%f "%p"'
+restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
+</programlisting>
+ An exception is that if the command was terminated by a signal (other
+ than <systemitem>SIGTERM</systemitem>, which is used as part of a
+ database server shutdown) or an error by the shell (such as command
+ not found), then recovery will abort and the server will not start up.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-archive-cleanup-command" xreflabel="archive_cleanup_command">
+ <term><varname>archive_cleanup_command</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>archive_cleanup_command</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This optional parameter specifies a shell command that will be executed
+ at every restartpoint. The purpose of
+ <varname>archive_cleanup_command</varname> is to provide a mechanism for
+ cleaning up old archived WAL files that are no longer needed by the
+ standby server.
+ Any <literal>%r</literal> is replaced by the name of the file containing the
+ last valid restart point.
+ That is the earliest file that must be <emphasis>kept</emphasis> to allow a
+ restore to be restartable, and so all files earlier than <literal>%r</literal>
+ may be safely removed.
+ This information can be used to truncate the archive to just the
+ minimum required to support restart from the current restore.
+ The <xref linkend="pgarchivecleanup"/> module
+ is often used in <varname>archive_cleanup_command</varname> for
+ single-standby configurations, for example:
+<programlisting>archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r'</programlisting>
+ Note however that if multiple standby servers are restoring from the
+ same archive directory, you will need to ensure that you do not delete
+ WAL files until they are no longer needed by any of the servers.
+ <varname>archive_cleanup_command</varname> would typically be used in a
+ warm-standby configuration (see <xref linkend="warm-standby"/>).
+ Write <literal>%%</literal> to embed an actual <literal>%</literal> character in the
+ command.
+ </para>
+ <para>
+ If the command returns a nonzero exit status then a warning log
+ message will be written. An exception is that if the command was
+ terminated by a signal or an error by the shell (such as command not
+ found), a fatal error will be raised.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-end-command" xreflabel="recovery_end_command">
+ <term><varname>recovery_end_command</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>recovery_end_command</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies a shell command that will be executed once only
+ at the end of recovery. This parameter is optional. The purpose of the
+ <varname>recovery_end_command</varname> is to provide a mechanism for cleanup
+ following replication or recovery.
+ Any <literal>%r</literal> is replaced by the name of the file containing the
+ last valid restart point, like in <xref linkend="guc-archive-cleanup-command"/>.
+ </para>
+ <para>
+ If the command returns a nonzero exit status then a warning log
+ message will be written and the database will proceed to start up
+ anyway. An exception is that if the command was terminated by a
+ signal or an error by the shell (such as command not found), the
+ database will not proceed with startup.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="runtime-config-wal-recovery-target">
+
+ <title>Recovery Target</title>
+
+ <para>
+ By default, recovery will recover to the end of the WAL log. The
+ following parameters can be used to specify an earlier stopping point.
+ At most one of <varname>recovery_target</varname>,
+ <varname>recovery_target_lsn</varname>, <varname>recovery_target_name</varname>,
+ <varname>recovery_target_time</varname>, or <varname>recovery_target_xid</varname>
+ can be used; if more than one of these is specified in the configuration
+ file, an error will be raised.
+ These parameters can only be set at server start.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-recovery-target" xreflabel="recovery_target">
+ <term><varname>recovery_target</varname><literal> = 'immediate'</literal>
+ <indexterm>
+ <primary><varname>recovery_target</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies that recovery should end as soon as a
+ consistent state is reached, i.e., as early as possible. When restoring
+ from an online backup, this means the point where taking the backup
+ ended.
+ </para>
+ <para>
+ Technically, this is a string parameter, but <literal>'immediate'</literal>
+ is currently the only allowed value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-target-name" xreflabel="recovery_target_name">
+ <term><varname>recovery_target_name</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>recovery_target_name</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies the named restore point (created with
+ <function>pg_create_restore_point()</function>) to which recovery will proceed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-target-time" xreflabel="recovery_target_time">
+ <term><varname>recovery_target_time</varname> (<type>timestamp</type>)
+ <indexterm>
+ <primary><varname>recovery_target_time</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies the time stamp up to which recovery
+ will proceed.
+ The precise stopping point is also influenced by
+ <xref linkend="guc-recovery-target-inclusive"/>.
+ </para>
+
+ <para>
+ The value of this parameter is a time stamp in the same format
+ accepted by the <type>timestamp with time zone</type> data type,
+ except that you cannot use a time zone abbreviation (unless the
+ <xref linkend="guc-timezone-abbreviations"/> variable has been set
+ earlier in the configuration file). Preferred style is to use a
+ numeric offset from UTC, or you can write a full time zone name,
+ e.g., <literal>Europe/Helsinki</literal> not <literal>EEST</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-target-xid" xreflabel="recovery_target_xid">
+ <term><varname>recovery_target_xid</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>recovery_target_xid</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies the transaction ID up to which recovery
+ will proceed. Keep in mind
+ that while transaction IDs are assigned sequentially at transaction
+ start, transactions can complete in a different numeric order.
+ The transactions that will be recovered are those that committed
+ before (and optionally including) the specified one.
+ The precise stopping point is also influenced by
+ <xref linkend="guc-recovery-target-inclusive"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-target-lsn" xreflabel="recovery_target_lsn">
+ <term><varname>recovery_target_lsn</varname> (<type>pg_lsn</type>)
+ <indexterm>
+ <primary><varname>recovery_target_lsn</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies the LSN of the write-ahead log location up
+ to which recovery will proceed. The precise stopping point is also
+ influenced by <xref linkend="guc-recovery-target-inclusive"/>. This
+ parameter is parsed using the system data type
+ <link linkend="datatype-pg-lsn"><type>pg_lsn</type></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The following options further specify the recovery target, and affect
+ what happens when the target is reached:
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-recovery-target-inclusive"
+ xreflabel="recovery_target_inclusive">
+ <term><varname>recovery_target_inclusive</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>recovery_target_inclusive</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies whether to stop just after the specified recovery target
+ (<literal>on</literal>), or just before the recovery target
+ (<literal>off</literal>).
+ Applies when <xref linkend="guc-recovery-target-lsn"/>,
+ <xref linkend="guc-recovery-target-time"/>, or
+ <xref linkend="guc-recovery-target-xid"/> is specified.
+ This setting controls whether transactions
+ having exactly the target WAL location (LSN), commit time, or transaction ID, respectively, will
+ be included in the recovery. Default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-target-timeline"
+ xreflabel="recovery_target_timeline">
+ <term><varname>recovery_target_timeline</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>recovery_target_timeline</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies recovering into a particular timeline. The value can be a
+ numeric timeline ID or a special value. The value
+ <literal>current</literal> recovers along the same timeline that was
+ current when the base backup was taken. The
+ value <literal>latest</literal> recovers
+ to the latest timeline found in the archive, which is useful in
+ a standby server. <literal>latest</literal> is the default.
+ </para>
+
+ <para>
+ You usually only need to set this parameter
+ in complex re-recovery situations, where you need to return to
+ a state that itself was reached after a point-in-time recovery.
+ See <xref linkend="backup-timelines"/> for discussion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-target-action"
+ xreflabel="recovery_target_action">
+ <term><varname>recovery_target_action</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>recovery_target_action</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies what action the server should take once the recovery target is
+ reached. The default is <literal>pause</literal>, which means recovery will
+ be paused. <literal>promote</literal> means the recovery process will finish
+ and the server will start to accept connections.
+ Finally <literal>shutdown</literal> will stop the server after reaching the
+ recovery target.
+ </para>
+ <para>
+ The intended use of the <literal>pause</literal> setting is to allow queries
+ to be executed against the database to check if this recovery target
+ is the most desirable point for recovery.
+ The paused state can be resumed by
+ using <function>pg_wal_replay_resume()</function> (see
+ <xref linkend="functions-recovery-control-table"/>), which then
+ causes recovery to end. If this recovery target is not the
+ desired stopping point, then shut down the server, change the
+ recovery target settings to a later target and restart to
+ continue recovery.
+ </para>
+ <para>
+ The <literal>shutdown</literal> setting is useful to have the instance ready
+ at the exact replay point desired. The instance will still be able to
+ replay more WAL records (and in fact will have to replay WAL records
+ since the last checkpoint next time it is started).
+ </para>
+ <para>
+ Note that because <filename>recovery.signal</filename> will not be
+ removed when <varname>recovery_target_action</varname> is set to <literal>shutdown</literal>,
+ any subsequent start will end with immediate shutdown unless the
+ configuration is changed or the <filename>recovery.signal</filename>
+ file is removed manually.
+ </para>
+ <para>
+ This setting has no effect if no recovery target is set.
+ If <xref linkend="guc-hot-standby"/> is not enabled, a setting of
+ <literal>pause</literal> will act the same as <literal>shutdown</literal>.
+ If the recovery target is reached while a promotion is ongoing,
+ a setting of <literal>pause</literal> will act the same as
+ <literal>promote</literal>.
+ </para>
+ <para>
+ In any case, if a recovery target is configured but the archive
+ recovery ends before the target is reached, the server will shut down
+ with a fatal error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="runtime-config-replication">
+ <title>Replication</title>
+
+ <para>
+ These settings control the behavior of the built-in
+ <firstterm>streaming replication</firstterm> feature (see
+ <xref linkend="streaming-replication"/>). Servers will be either a
+ primary or a standby server. Primaries can send data, while standbys
+ are always receivers of replicated data. When cascading replication
+ (see <xref linkend="cascading-replication"/>) is used, standby servers
+ can also be senders, as well as receivers.
+ Parameters are mainly for sending and standby servers, though some
+ parameters have meaning only on the primary server. Settings may vary
+ across the cluster without problems if that is required.
+ </para>
+
+ <sect2 id="runtime-config-replication-sender">
+ <title>Sending Servers</title>
+
+ <para>
+ These parameters can be set on any server that is
+ to send replication data to one or more standby servers.
+ The primary is always a sending server, so these parameters must
+ always be set on the primary.
+ The role and meaning of these parameters does not change after a
+ standby becomes the primary.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-max-wal-senders" xreflabel="max_wal_senders">
+ <term><varname>max_wal_senders</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_wal_senders</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum number of concurrent connections from standby
+ servers or streaming base backup clients (i.e., the maximum number of
+ simultaneously running WAL sender processes). The default is
+ <literal>10</literal>. The value <literal>0</literal> means
+ replication is disabled. Abrupt disconnection of a streaming client might
+ leave an orphaned connection slot behind until a timeout is reached,
+ so this parameter should be set slightly higher than the maximum
+ number of expected clients so disconnected clients can immediately
+ reconnect. This parameter can only be set at server start. Also,
+ <varname>wal_level</varname> must be set to
+ <literal>replica</literal> or higher to allow connections from standby
+ servers.
+ </para>
+
+ <para>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-replication-slots" xreflabel="max_replication_slots">
+ <term><varname>max_replication_slots</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_replication_slots</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum number of replication slots
+ (see <xref linkend="streaming-replication-slots"/>) that the server
+ can support. The default is 10. This parameter can only be set at
+ server start.
+ Setting it to a lower value than the number of currently
+ existing replication slots will prevent the server from starting.
+ Also, <varname>wal_level</varname> must be set
+ to <literal>replica</literal> or higher to allow replication slots to
+ be used.
+ </para>
+
+ <para>
+ On the subscriber side, specifies how many replication origins (see
+ <xref linkend="replication-origins"/>) can be tracked simultaneously,
+ effectively limiting how many logical replication subscriptions can
+ be created on the server. Setting it to a lower value than the current
+ number of tracked replication origins (reflected in
+ <link linkend="view-pg-replication-origin-status">pg_replication_origin_status</link>,
+ not <link linkend="catalog-pg-replication-origin">pg_replication_origin</link>)
+ will prevent the server from starting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-keep-size" xreflabel="wal_keep_size">
+ <term><varname>wal_keep_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_keep_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the minimum size of past log file segments kept in the
+ <filename>pg_wal</filename>
+ directory, in case a standby server needs to fetch them for streaming
+ replication. If a standby
+ server connected to the sending server falls behind by more than
+ <varname>wal_keep_size</varname> megabytes, the sending server might
+ remove a WAL segment still needed by the standby, in which case the
+ replication connection will be terminated. Downstream connections
+ will also eventually fail as a result. (However, the standby
+ server can recover by fetching the segment from archive, if WAL
+ archiving is in use.)
+ </para>
+
+ <para>
+ This sets only the minimum size of segments retained in
+ <filename>pg_wal</filename>; the system might need to retain more segments
+ for WAL archival or to recover from a checkpoint. If
+ <varname>wal_keep_size</varname> is zero (the default), the system
+ doesn't keep any extra segments for standby purposes, so the number
+ of old WAL segments available to standby servers is a function of
+ the location of the previous checkpoint and status of WAL
+ archiving.
+ If this value is specified without units, it is taken as megabytes.
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-slot-wal-keep-size" xreflabel="max_slot_wal_keep_size">
+ <term><varname>max_slot_wal_keep_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_slot_wal_keep_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specify the maximum size of WAL files
+ that <link linkend="streaming-replication-slots">replication
+ slots</link> are allowed to retain in the <filename>pg_wal</filename>
+ directory at checkpoint time.
+ If <varname>max_slot_wal_keep_size</varname> is -1 (the default),
+ replication slots may retain an unlimited amount of WAL files. Otherwise, if
+ restart_lsn of a replication slot falls behind the current LSN by more
+ than the given size, the standby using the slot may no longer be able
+ to continue replication due to removal of required WAL files. You
+ can see the WAL availability of replication slots
+ in <link linkend="view-pg-replication-slots">pg_replication_slots</link>.
+ If this value is specified without units, it is taken as megabytes.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-sender-timeout" xreflabel="wal_sender_timeout">
+ <term><varname>wal_sender_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_sender_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Terminate replication connections that are inactive for longer
+ than this amount of time. This is useful for
+ the sending server to detect a standby crash or network outage.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 60 seconds.
+ A value of zero disables the timeout mechanism.
+ </para>
+ <para>
+ With a cluster distributed across multiple geographic
+ locations, using different values per location brings more flexibility
+ in the cluster management. A smaller value is useful for faster
+ failure detection with a standby having a low-latency network
+ connection, and a larger value helps in judging better the health
+ of a standby if located on a remote location, with a high-latency
+ network connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-track-commit-timestamp" xreflabel="track_commit_timestamp">
+ <term><varname>track_commit_timestamp</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>track_commit_timestamp</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Record commit time of transactions. This parameter
+ can only be set in <filename>postgresql.conf</filename> file or on the server
+ command line. The default value is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-replication-primary">
+ <title>Primary Server</title>
+
+ <para>
+ These parameters can be set on the primary server that is
+ to send replication data to one or more standby servers.
+ Note that in addition to these parameters,
+ <xref linkend="guc-wal-level"/> must be set appropriately on the primary
+ server, and optionally WAL archiving can be enabled as
+ well (see <xref linkend="runtime-config-wal-archiving"/>).
+ The values of these parameters on standby servers are irrelevant,
+ although you may wish to set them there in preparation for the
+ possibility of a standby becoming the primary.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-synchronous-standby-names" xreflabel="synchronous_standby_names">
+ <term><varname>synchronous_standby_names</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>synchronous_standby_names</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a list of standby servers that can support
+ <firstterm>synchronous replication</firstterm>, as described in
+ <xref linkend="synchronous-replication"/>.
+ There will be one or more active synchronous standbys;
+ transactions waiting for commit will be allowed to proceed after
+ these standby servers confirm receipt of their data.
+ The synchronous standbys will be those whose names appear
+ in this list, and
+ that are both currently connected and streaming data in real-time
+ (as shown by a state of <literal>streaming</literal> in the
+ <link linkend="monitoring-pg-stat-replication-view">
+ <structname>pg_stat_replication</structname></link> view).
+ Specifying more than one synchronous standby can allow for very high
+ availability and protection against data loss.
+ </para>
+ <para>
+ The name of a standby server for this purpose is the
+ <varname>application_name</varname> setting of the standby, as set in the
+ standby's connection information. In case of a physical replication
+ standby, this should be set in the <varname>primary_conninfo</varname>
+ setting; the default is the setting of <xref linkend="guc-cluster-name"/>
+ if set, else <literal>walreceiver</literal>.
+ For logical replication, this can be set in the connection
+ information of the subscription, and it defaults to the
+ subscription name. For other replication stream consumers,
+ consult their documentation.
+ </para>
+ <para>
+ This parameter specifies a list of standby servers using
+ either of the following syntaxes:
+<synopsis>
+[FIRST] <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="parameter">standby_name</replaceable> [, ...] )
+ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="parameter">standby_name</replaceable> [, ...] )
+<replaceable class="parameter">standby_name</replaceable> [, ...]
+</synopsis>
+ where <replaceable class="parameter">num_sync</replaceable> is
+ the number of synchronous standbys that transactions need to
+ wait for replies from,
+ and <replaceable class="parameter">standby_name</replaceable>
+ is the name of a standby server.
+ <literal>FIRST</literal> and <literal>ANY</literal> specify the method to choose
+ synchronous standbys from the listed servers.
+ </para>
+ <para>
+ The keyword <literal>FIRST</literal>, coupled with
+ <replaceable class="parameter">num_sync</replaceable>, specifies a
+ priority-based synchronous replication and makes transaction commits
+ wait until their WAL records are replicated to
+ <replaceable class="parameter">num_sync</replaceable> synchronous
+ standbys chosen based on their priorities. For example, a setting of
+ <literal>FIRST 3 (s1, s2, s3, s4)</literal> will cause each commit to wait for
+ replies from three higher-priority standbys chosen from standby servers
+ <literal>s1</literal>, <literal>s2</literal>, <literal>s3</literal> and <literal>s4</literal>.
+ The standbys whose names appear earlier in the list are given higher
+ priority and will be considered as synchronous. Other standby servers
+ appearing later in this list represent potential synchronous standbys.
+ If any of the current synchronous standbys disconnects for whatever
+ reason, it will be replaced immediately with the next-highest-priority
+ standby. The keyword <literal>FIRST</literal> is optional.
+ </para>
+ <para>
+ The keyword <literal>ANY</literal>, coupled with
+ <replaceable class="parameter">num_sync</replaceable>, specifies a
+ quorum-based synchronous replication and makes transaction commits
+ wait until their WAL records are replicated to <emphasis>at least</emphasis>
+ <replaceable class="parameter">num_sync</replaceable> listed standbys.
+ For example, a setting of <literal>ANY 3 (s1, s2, s3, s4)</literal> will cause
+ each commit to proceed as soon as at least any three standbys of
+ <literal>s1</literal>, <literal>s2</literal>, <literal>s3</literal> and <literal>s4</literal>
+ reply.
+ </para>
+ <para>
+ <literal>FIRST</literal> and <literal>ANY</literal> are case-insensitive. If these
+ keywords are used as the name of a standby server,
+ its <replaceable class="parameter">standby_name</replaceable> must
+ be double-quoted.
+ </para>
+ <para>
+ The third syntax was used before <productname>PostgreSQL</productname>
+ version 9.6 and is still supported. It's the same as the first syntax
+ with <literal>FIRST</literal> and
+ <replaceable class="parameter">num_sync</replaceable> equal to 1.
+ For example, <literal>FIRST 1 (s1, s2)</literal> and <literal>s1, s2</literal> have
+ the same meaning: either <literal>s1</literal> or <literal>s2</literal> is chosen
+ as a synchronous standby.
+ </para>
+ <para>
+ The special entry <literal>*</literal> matches any standby name.
+ </para>
+ <para>
+ There is no mechanism to enforce uniqueness of standby names. In case
+ of duplicates one of the matching standbys will be considered as
+ higher priority, though exactly which one is indeterminate.
+ </para>
+ <note>
+ <para>
+ Each <replaceable class="parameter">standby_name</replaceable>
+ should have the form of a valid SQL identifier, unless it
+ is <literal>*</literal>. You can use double-quoting if necessary. But note
+ that <replaceable class="parameter">standby_name</replaceable>s are
+ compared to standby application names case-insensitively, whether
+ double-quoted or not.
+ </para>
+ </note>
+ <para>
+ If no synchronous standby names are specified here, then synchronous
+ replication is not enabled and transaction commits will not wait for
+ replication. This is the default configuration. Even when
+ synchronous replication is enabled, individual transactions can be
+ configured not to wait for replication by setting the
+ <xref linkend="guc-synchronous-commit"/> parameter to
+ <literal>local</literal> or <literal>off</literal>.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-defer-cleanup-age" xreflabel="vacuum_defer_cleanup_age">
+ <term><varname>vacuum_defer_cleanup_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_defer_cleanup_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the number of transactions by which <command>VACUUM</command> and
+ <link linkend="storage-hot"><acronym>HOT</acronym> updates</link>
+ will defer cleanup of dead row versions. The
+ default is zero transactions, meaning that dead row versions can be
+ removed as soon as possible, that is, as soon as they are no longer
+ visible to any open transaction. You may wish to set this to a
+ non-zero value on a primary server that is supporting hot standby
+ servers, as described in <xref linkend="hot-standby"/>. This allows
+ more time for queries on the standby to complete without incurring
+ conflicts due to early cleanup of rows. However, since the value
+ is measured in terms of number of write transactions occurring on the
+ primary server, it is difficult to predict just how much additional
+ grace time will be made available to standby queries.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ <para>
+ You should also consider setting <varname>hot_standby_feedback</varname>
+ on standby server(s) as an alternative to using this parameter.
+ </para>
+ <para>
+ This does not prevent cleanup of dead rows which have reached the age
+ specified by <varname>old_snapshot_threshold</varname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-replication-standby">
+ <title>Standby Servers</title>
+
+ <para>
+ These settings control the behavior of a
+ <link linkend="standby-server-operation">standby server</link>
+ that is
+ to receive replication data. Their values on the primary server
+ are irrelevant.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-primary-conninfo" xreflabel="primary_conninfo">
+ <term><varname>primary_conninfo</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>primary_conninfo</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a connection string to be used for the standby server
+ to connect with a sending server. This string is in the format
+ described in <xref linkend="libpq-connstring"/>. If any option is
+ unspecified in this string, then the corresponding environment
+ variable (see <xref linkend="libpq-envars"/>) is checked. If the
+ environment variable is not set either, then
+ defaults are used.
+ </para>
+ <para>
+ The connection string should specify the host name (or address)
+ of the sending server, as well as the port number if it is not
+ the same as the standby server's default.
+ Also specify a user name corresponding to a suitably-privileged role
+ on the sending server (see
+ <xref linkend="streaming-replication-authentication"/>).
+ A password needs to be provided too, if the sender demands password
+ authentication. It can be provided in the
+ <varname>primary_conninfo</varname> string, or in a separate
+ <filename>~/.pgpass</filename> file on the standby server (use
+ <literal>replication</literal> as the database name).
+ Do not specify a database name in the
+ <varname>primary_conninfo</varname> string.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ If this parameter is changed while the WAL receiver process is
+ running, that process is signaled to shut down and expected to
+ restart with the new setting (except if <varname>primary_conninfo</varname>
+ is an empty string).
+ This setting has no effect if the server is not in standby mode.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry id="guc-primary-slot-name" xreflabel="primary_slot_name">
+ <term><varname>primary_slot_name</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>primary_slot_name</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Optionally specifies an existing replication slot to be used when
+ connecting to the sending server via streaming replication to control
+ resource removal on the upstream node
+ (see <xref linkend="streaming-replication-slots"/>).
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ If this parameter is changed while the WAL receiver process is running,
+ that process is signaled to shut down and expected to restart with the
+ new setting.
+ This setting has no effect if <varname>primary_conninfo</varname> is not
+ set or the server is not in standby mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-promote-trigger-file" xreflabel="promote_trigger_file">
+ <term><varname>promote_trigger_file</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>promote_trigger_file</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a trigger file whose presence ends recovery in the
+ standby. Even if this value is not set, you can still promote
+ the standby using <command>pg_ctl promote</command> or calling
+ <function>pg_promote()</function>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-hot-standby" xreflabel="hot_standby">
+ <term><varname>hot_standby</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>hot_standby</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies whether or not you can connect and run queries during
+ recovery, as described in <xref linkend="hot-standby"/>.
+ The default value is <literal>on</literal>.
+ This parameter can only be set at server start. It only has effect
+ during archive recovery or in standby mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-standby-archive-delay" xreflabel="max_standby_archive_delay">
+ <term><varname>max_standby_archive_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_standby_archive_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When hot standby is active, this parameter determines how long the
+ standby server should wait before canceling standby queries that
+ conflict with about-to-be-applied WAL entries, as described in
+ <xref linkend="hot-standby-conflict"/>.
+ <varname>max_standby_archive_delay</varname> applies when WAL data is
+ being read from WAL archive (and is therefore not current).
+ If this value is specified without units, it is taken as milliseconds.
+ The default is 30 seconds.
+ A value of -1 allows the standby to wait forever for conflicting
+ queries to complete.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ <para>
+ Note that <varname>max_standby_archive_delay</varname> is not the same as the
+ maximum length of time a query can run before cancellation; rather it
+ is the maximum total time allowed to apply any one WAL segment's data.
+ Thus, if one query has resulted in significant delay earlier in the
+ WAL segment, subsequent conflicting queries will have much less grace
+ time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-standby-streaming-delay" xreflabel="max_standby_streaming_delay">
+ <term><varname>max_standby_streaming_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_standby_streaming_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When hot standby is active, this parameter determines how long the
+ standby server should wait before canceling standby queries that
+ conflict with about-to-be-applied WAL entries, as described in
+ <xref linkend="hot-standby-conflict"/>.
+ <varname>max_standby_streaming_delay</varname> applies when WAL data is
+ being received via streaming replication.
+ If this value is specified without units, it is taken as milliseconds.
+ The default is 30 seconds.
+ A value of -1 allows the standby to wait forever for conflicting
+ queries to complete.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ <para>
+ Note that <varname>max_standby_streaming_delay</varname> is not the same as
+ the maximum length of time a query can run before cancellation; rather
+ it is the maximum total time allowed to apply WAL data once it has
+ been received from the primary server. Thus, if one query has
+ resulted in significant delay, subsequent conflicting queries will
+ have much less grace time until the standby server has caught up
+ again.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-receiver-create-temp-slot" xreflabel="wal_receiver_create_temp_slot">
+ <term><varname>wal_receiver_create_temp_slot</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>wal_receiver_create_temp_slot</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies whether the WAL receiver process should create a temporary replication
+ slot on the remote instance when no permanent replication slot to use
+ has been configured (using <xref linkend="guc-primary-slot-name"/>).
+ The default is off. This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ If this parameter is changed while the WAL receiver process is running,
+ that process is signaled to shut down and expected to restart with
+ the new setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-receiver-status-interval" xreflabel="wal_receiver_status_interval">
+ <term><varname>wal_receiver_status_interval</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_receiver_status_interval</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the minimum frequency for the WAL receiver
+ process on the standby to send information about replication progress
+ to the primary or upstream standby, where it can be seen using the
+ <link linkend="monitoring-pg-stat-replication-view">
+ <structname>pg_stat_replication</structname></link>
+ view. The standby will report
+ the last write-ahead log location it has written, the last position it
+ has flushed to disk, and the last position it has applied.
+ This parameter's value is the maximum amount of time between reports.
+ Updates are sent each time the write or flush positions change, or as
+ often as specified by this parameter if set to a non-zero value.
+ There are additional cases where updates are sent while ignoring this
+ parameter; for example, when processing of the existing WAL completes
+ or when <varname>synchronous_commit</varname> is set to
+ <literal>remote_apply</literal>.
+ Thus, the apply position may lag slightly behind the true position.
+ If this value is specified without units, it is taken as seconds.
+ The default value is 10 seconds. This parameter can only be set in
+ the <filename>postgresql.conf</filename> file or on the server
+ command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-hot-standby-feedback" xreflabel="hot_standby_feedback">
+ <term><varname>hot_standby_feedback</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>hot_standby_feedback</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies whether or not a hot standby will send feedback to the primary
+ or upstream standby
+ about queries currently executing on the standby. This parameter can
+ be used to eliminate query cancels caused by cleanup records, but
+ can cause database bloat on the primary for some workloads.
+ Feedback messages will not be sent more frequently than once per
+ <varname>wal_receiver_status_interval</varname>. The default value is
+ <literal>off</literal>. This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ <para>
+ If cascaded replication is in use the feedback is passed upstream
+ until it eventually reaches the primary. Standbys make no other use
+ of feedback they receive other than to pass upstream.
+ </para>
+ <para>
+ This setting does not override the behavior of
+ <varname>old_snapshot_threshold</varname> on the primary; a snapshot on the
+ standby which exceeds the primary's age threshold can become invalid,
+ resulting in cancellation of transactions on the standby. This is
+ because <varname>old_snapshot_threshold</varname> is intended to provide an
+ absolute limit on the time which dead rows can contribute to bloat,
+ which would otherwise be violated because of the configuration of a
+ standby.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-receiver-timeout" xreflabel="wal_receiver_timeout">
+ <term><varname>wal_receiver_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_receiver_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Terminate replication connections that are inactive for longer
+ than this amount of time. This is useful for
+ the receiving standby server to detect a primary node crash or network
+ outage.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 60 seconds.
+ A value of zero disables the timeout mechanism.
+ This parameter can only be set in
+ the <filename>postgresql.conf</filename> file or on the server
+ command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-retrieve-retry-interval" xreflabel="wal_retrieve_retry_interval">
+ <term><varname>wal_retrieve_retry_interval</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_retrieve_retry_interval</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies how long the standby server should wait when WAL data is not
+ available from any sources (streaming replication,
+ local <filename>pg_wal</filename> or WAL archive) before trying
+ again to retrieve WAL data.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 5 seconds.
+ This parameter can only be set in
+ the <filename>postgresql.conf</filename> file or on the server
+ command line.
+ </para>
+ <para>
+ This parameter is useful in configurations where a node in recovery
+ needs to control the amount of time to wait for new WAL data to be
+ available. For example, in archive recovery, it is possible to
+ make the recovery more responsive in the detection of a new WAL
+ log file by reducing the value of this parameter. On a system with
+ low WAL activity, increasing it reduces the amount of requests necessary
+ to access WAL archives, something useful for example in cloud
+ environments where the number of times an infrastructure is accessed
+ is taken into account.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-min-apply-delay" xreflabel="recovery_min_apply_delay">
+ <term><varname>recovery_min_apply_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>recovery_min_apply_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ By default, a standby server restores WAL records from the
+ sending server as soon as possible. It may be useful to have a time-delayed
+ copy of the data, offering opportunities to correct data loss errors.
+ This parameter allows you to delay recovery by a specified amount
+ of time. For example, if
+ you set this parameter to <literal>5min</literal>, the standby will
+ replay each transaction commit only when the system time on the standby
+ is at least five minutes past the commit time reported by the primary.
+ If this value is specified without units, it is taken as milliseconds.
+ The default is zero, adding no delay.
+ </para>
+ <para>
+ It is possible that the replication delay between servers exceeds the
+ value of this parameter, in which case no delay is added.
+ Note that the delay is calculated between the WAL time stamp as written
+ on primary and the current time on the standby. Delays in transfer
+ because of network lag or cascading replication configurations
+ may reduce the actual wait time significantly. If the system
+ clocks on primary and standby are not synchronized, this may lead to
+ recovery applying records earlier than expected; but that is not a
+ major issue because useful settings of this parameter are much larger
+ than typical time deviations between servers.
+ </para>
+ <para>
+ The delay occurs only on WAL records for transaction commits.
+ Other records are replayed as quickly as possible, which
+ is not a problem because MVCC visibility rules ensure their effects
+ are not visible until the corresponding commit record is applied.
+ </para>
+ <para>
+ The delay occurs once the database in recovery has reached a consistent
+ state, until the standby is promoted or triggered. After that the standby
+ will end recovery without further waiting.
+ </para>
+ <para>
+ WAL records must be kept on the standby until they are ready to be
+ applied. Therefore, longer delays will result in a greater accumulation
+ of WAL files, increasing disk space requirements for the standby's
+ <filename>pg_wal</filename> directory.
+ </para>
+ <para>
+ This parameter is intended for use with streaming replication deployments;
+ however, if the parameter is specified it will be honored in all cases
+ except crash recovery.
+
+ <varname>hot_standby_feedback</varname> will be delayed by use of this feature
+ which could lead to bloat on the primary; use both together with care.
+
+ <warning>
+ <para>
+ Synchronous replication is affected by this setting when <varname>synchronous_commit</varname>
+ is set to <literal>remote_apply</literal>; every <literal>COMMIT</literal>
+ will need to wait to be applied.
+ </para>
+ </warning>
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-replication-subscriber">
+ <title>Subscribers</title>
+
+ <para>
+ These settings control the behavior of a logical replication subscriber.
+ Their values on the publisher are irrelevant.
+ </para>
+
+ <para>
+ Note that <varname>wal_receiver_timeout</varname>,
+ <varname>wal_receiver_status_interval</varname> and
+ <varname>wal_retrieve_retry_interval</varname> configuration parameters
+ affect the logical replication workers as well.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-max-logical-replication-workers" xreflabel="max_logical_replication_workers">
+ <term><varname>max_logical_replication_workers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_logical_replication_workers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies maximum number of logical replication workers. This includes
+ both apply workers and table synchronization workers.
+ </para>
+ <para>
+ Logical replication workers are taken from the pool defined by
+ <varname>max_worker_processes</varname>.
+ </para>
+ <para>
+ The default value is 4. This parameter can only be set at server
+ start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-sync-workers-per-subscription" xreflabel="max_sync_workers_per_subscription">
+ <term><varname>max_sync_workers_per_subscription</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_sync_workers_per_subscription</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Maximum number of synchronization workers per subscription. This
+ parameter controls the amount of parallelism of the initial data copy
+ during the subscription initialization or when new tables are added.
+ </para>
+ <para>
+ Currently, there can be only one synchronization worker per table.
+ </para>
+ <para>
+ The synchronization workers are taken from the pool defined by
+ <varname>max_logical_replication_workers</varname>.
+ </para>
+ <para>
+ The default value is 2. This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command
+ line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="runtime-config-query">
+ <title>Query Planning</title>
+
+ <sect2 id="runtime-config-query-enable">
+ <title>Planner Method Configuration</title>
+
+ <para>
+ These configuration parameters provide a crude method of
+ influencing the query plans chosen by the query optimizer. If
+ the default plan chosen by the optimizer for a particular query
+ is not optimal, a <emphasis>temporary</emphasis> solution is to use one
+ of these configuration parameters to force the optimizer to
+ choose a different plan.
+ Better ways to improve the quality of the
+ plans chosen by the optimizer include adjusting the planner cost
+ constants (see <xref linkend="runtime-config-query-constants"/>),
+ running <link linkend="sql-analyze"><command>ANALYZE</command></link> manually, increasing
+ the value of the <xref
+ linkend="guc-default-statistics-target"/> configuration parameter,
+ and increasing the amount of statistics collected for
+ specific columns using <command>ALTER TABLE SET
+ STATISTICS</command>.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-enable-async-append" xreflabel="enable_async_append">
+ <term><varname>enable_async_append</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_async_append</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of async-aware
+ append plan types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-bitmapscan" xreflabel="enable_bitmapscan">
+ <term><varname>enable_bitmapscan</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>bitmap scan</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>enable_bitmapscan</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of bitmap-scan plan
+ types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-gathermerge" xreflabel="enable_gathermerge">
+ <term><varname>enable_gathermerge</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_gathermerge</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of gather
+ merge plan types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-hashagg" xreflabel="enable_hashagg">
+ <term><varname>enable_hashagg</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_hashagg</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of hashed
+ aggregation plan types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-hashjoin" xreflabel="enable_hashjoin">
+ <term><varname>enable_hashjoin</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_hashjoin</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of hash-join plan
+ types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-incremental-sort" xreflabel="enable_incremental_sort">
+ <term><varname>enable_incremental_sort</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_incremental_sort</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of incremental sort steps.
+ The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-indexscan" xreflabel="enable_indexscan">
+ <term><varname>enable_indexscan</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>index scan</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>enable_indexscan</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of index-scan plan
+ types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-indexonlyscan" xreflabel="enable_indexonlyscan">
+ <term><varname>enable_indexonlyscan</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_indexonlyscan</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of index-only-scan plan
+ types (see <xref linkend="indexes-index-only-scans"/>).
+ The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-material" xreflabel="enable_material">
+ <term><varname>enable_material</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_material</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of materialization.
+ It is impossible to suppress materialization entirely,
+ but turning this variable off prevents the planner from inserting
+ materialize nodes except in cases where it is required for correctness.
+ The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-memoize" xreflabel="enable_memoize">
+ <term><varname>enable_memoize</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_memoize</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of memoize plans for
+ caching results from parameterized scans inside nested-loop joins.
+ This plan type allows scans to the underlying plans to be skipped when
+ the results for the current parameters are already in the cache. Less
+ commonly looked up results may be evicted from the cache when more
+ space is required for new entries. The default is
+ <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-mergejoin" xreflabel="enable_mergejoin">
+ <term><varname>enable_mergejoin</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_mergejoin</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of merge-join plan
+ types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-nestloop" xreflabel="enable_nestloop">
+ <term><varname>enable_nestloop</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_nestloop</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of nested-loop join
+ plans. It is impossible to suppress nested-loop joins entirely,
+ but turning this variable off discourages the planner from using
+ one if there are other methods available. The default is
+ <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-parallel-append" xreflabel="enable_parallel_append">
+ <term><varname>enable_parallel_append</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_parallel_append</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of parallel-aware
+ append plan types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-parallel-hash" xreflabel="enable_parallel_hash">
+ <term><varname>enable_parallel_hash</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_parallel_hash</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of hash-join plan
+ types with parallel hash. Has no effect if hash-join plans are not
+ also enabled. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-partition-pruning" xreflabel="enable_partition_pruning">
+ <term><varname>enable_partition_pruning</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_partition_pruning</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's ability to eliminate a
+ partitioned table's partitions from query plans. This also controls
+ the planner's ability to generate query plans which allow the query
+ executor to remove (ignore) partitions during query execution. The
+ default is <literal>on</literal>.
+ See <xref linkend="ddl-partition-pruning"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-partitionwise-join" xreflabel="enable_partitionwise_join">
+ <term><varname>enable_partitionwise_join</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_partitionwise_join</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of partitionwise join,
+ which allows a join between partitioned tables to be performed by
+ joining the matching partitions. Partitionwise join currently applies
+ only when the join conditions include all the partition keys, which
+ must be of the same data type and have one-to-one matching sets of
+ child partitions. Because partitionwise join planning can use
+ significantly more CPU time and memory during planning, the default is
+ <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-partitionwise-aggregate" xreflabel="enable_partitionwise_aggregate">
+ <term><varname>enable_partitionwise_aggregate</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_partitionwise_aggregate</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of partitionwise grouping
+ or aggregation, which allows grouping or aggregation on a partitioned
+ tables performed separately for each partition. If the <literal>GROUP
+ BY</literal> clause does not include the partition keys, only partial
+ aggregation can be performed on a per-partition basis, and
+ finalization must be performed later. Because partitionwise grouping
+ or aggregation can use significantly more CPU time and memory during
+ planning, the default is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-seqscan" xreflabel="enable_seqscan">
+ <term><varname>enable_seqscan</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>sequential scan</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>enable_seqscan</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of sequential scan
+ plan types. It is impossible to suppress sequential scans
+ entirely, but turning this variable off discourages the planner
+ from using one if there are other methods available. The
+ default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-sort" xreflabel="enable_sort">
+ <term><varname>enable_sort</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_sort</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of explicit sort
+ steps. It is impossible to suppress explicit sorts entirely,
+ but turning this variable off discourages the planner from
+ using one if there are other methods available. The default
+ is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-enable-tidscan" xreflabel="enable_tidscan">
+ <term><varname>enable_tidscan</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>enable_tidscan</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the query planner's use of <acronym>TID</acronym>
+ scan plan types. The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-query-constants">
+ <title>Planner Cost Constants</title>
+
+ <para>
+ The <firstterm>cost</firstterm> variables described in this section are measured
+ on an arbitrary scale. Only their relative values matter, hence
+ scaling them all up or down by the same factor will result in no change
+ in the planner's choices. By default, these cost variables are based on
+ the cost of sequential page fetches; that is,
+ <varname>seq_page_cost</varname> is conventionally set to <literal>1.0</literal>
+ and the other cost variables are set with reference to that. But
+ you can use a different scale if you prefer, such as actual execution
+ times in milliseconds on a particular machine.
+ </para>
+
+ <note>
+ <para>
+ Unfortunately, there is no well-defined method for determining ideal
+ values for the cost variables. They are best treated as averages over
+ the entire mix of queries that a particular installation will receive. This
+ means that changing them on the basis of just a few experiments is very
+ risky.
+ </para>
+ </note>
+
+ <variablelist>
+
+ <varlistentry id="guc-seq-page-cost" xreflabel="seq_page_cost">
+ <term><varname>seq_page_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>seq_page_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of a disk page fetch
+ that is part of a series of sequential fetches. The default is 1.0.
+ This value can be overridden for tables and indexes in a particular
+ tablespace by setting the tablespace parameter of the same name
+ (see <xref linkend="sql-altertablespace"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-random-page-cost" xreflabel="random_page_cost">
+ <term><varname>random_page_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>random_page_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of a
+ non-sequentially-fetched disk page. The default is 4.0.
+ This value can be overridden for tables and indexes in a particular
+ tablespace by setting the tablespace parameter of the same name
+ (see <xref linkend="sql-altertablespace"/>).
+ </para>
+
+ <para>
+ Reducing this value relative to <varname>seq_page_cost</varname>
+ will cause the system to prefer index scans; raising it will
+ make index scans look relatively more expensive. You can raise
+ or lower both values together to change the importance of disk I/O
+ costs relative to CPU costs, which are described by the following
+ parameters.
+ </para>
+
+ <para>
+ Random access to mechanical disk storage is normally much more expensive
+ than four times sequential access. However, a lower default is used
+ (4.0) because the majority of random accesses to disk, such as indexed
+ reads, are assumed to be in cache. The default value can be thought of
+ as modeling random access as 40 times slower than sequential, while
+ expecting 90% of random reads to be cached.
+ </para>
+
+ <para>
+ If you believe a 90% cache rate is an incorrect assumption
+ for your workload, you can increase random_page_cost to better
+ reflect the true cost of random storage reads. Correspondingly,
+ if your data is likely to be completely in cache, such as when
+ the database is smaller than the total server memory, decreasing
+ random_page_cost can be appropriate. Storage that has a low random
+ read cost relative to sequential, e.g., solid-state drives, might
+ also be better modeled with a lower value for random_page_cost,
+ e.g., <literal>1.1</literal>.
+ </para>
+
+ <tip>
+ <para>
+ Although the system will let you set <varname>random_page_cost</varname> to
+ less than <varname>seq_page_cost</varname>, it is not physically sensible
+ to do so. However, setting them equal makes sense if the database
+ is entirely cached in RAM, since in that case there is no penalty
+ for touching pages out of sequence. Also, in a heavily-cached
+ database you should lower both values relative to the CPU parameters,
+ since the cost of fetching a page already in RAM is much smaller
+ than it would normally be.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-cpu-tuple-cost" xreflabel="cpu_tuple_cost">
+ <term><varname>cpu_tuple_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>cpu_tuple_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of processing
+ each row during a query.
+ The default is 0.01.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-cpu-index-tuple-cost" xreflabel="cpu_index_tuple_cost">
+ <term><varname>cpu_index_tuple_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>cpu_index_tuple_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of processing
+ each index entry during an index scan.
+ The default is 0.005.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-cpu-operator-cost" xreflabel="cpu_operator_cost">
+ <term><varname>cpu_operator_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>cpu_operator_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of processing each
+ operator or function executed during a query.
+ The default is 0.0025.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-parallel-setup-cost" xreflabel="parallel_setup_cost">
+ <term><varname>parallel_setup_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>parallel_setup_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of launching parallel worker
+ processes.
+ The default is 1000.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-parallel-tuple-cost" xreflabel="parallel_tuple_cost">
+ <term><varname>parallel_tuple_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>parallel_tuple_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the cost of transferring one tuple
+ from a parallel worker process to another process.
+ The default is 0.1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-min-parallel-table-scan-size" xreflabel="min_parallel_table_scan_size">
+ <term><varname>min_parallel_table_scan_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>min_parallel_table_scan_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the minimum amount of table data that must be scanned in order
+ for a parallel scan to be considered. For a parallel sequential scan,
+ the amount of table data scanned is always equal to the size of the
+ table, but when indexes are used the amount of table data
+ scanned will normally be less.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The default is 8 megabytes (<literal>8MB</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-min-parallel-index-scan-size" xreflabel="min_parallel_index_scan_size">
+ <term><varname>min_parallel_index_scan_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>min_parallel_index_scan_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the minimum amount of index data that must be scanned in order
+ for a parallel scan to be considered. Note that a parallel index scan
+ typically won't touch the entire index; it is the number of pages
+ which the planner believes will actually be touched by the scan which
+ is relevant. This parameter is also used to decide whether a
+ particular index can participate in a parallel vacuum. See
+ <xref linkend="sql-vacuum"/>.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The default is 512 kilobytes (<literal>512kB</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-effective-cache-size" xreflabel="effective_cache_size">
+ <term><varname>effective_cache_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>effective_cache_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's assumption about the effective size of the
+ disk cache that is available to a single query. This is
+ factored into estimates of the cost of using an index; a
+ higher value makes it more likely index scans will be used, a
+ lower value makes it more likely sequential scans will be
+ used. When setting this parameter you should consider both
+ <productname>PostgreSQL</productname>'s shared buffers and the
+ portion of the kernel's disk cache that will be used for
+ <productname>PostgreSQL</productname> data files, though some
+ data might exist in both places. Also, take
+ into account the expected number of concurrent queries on different
+ tables, since they will have to share the available
+ space. This parameter has no effect on the size of shared
+ memory allocated by <productname>PostgreSQL</productname>, nor
+ does it reserve kernel disk cache; it is used only for estimation
+ purposes. The system also does not assume data remains in
+ the disk cache between queries.
+ If this value is specified without units, it is taken as blocks,
+ that is <symbol>BLCKSZ</symbol> bytes, typically 8kB.
+ The default is 4 gigabytes (<literal>4GB</literal>).
+ (If <symbol>BLCKSZ</symbol> is not 8kB, the default value scales
+ proportionally to it.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-above-cost" xreflabel="jit_above_cost">
+ <term><varname>jit_above_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>jit_above_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the query cost above which JIT compilation is activated, if
+ enabled (see <xref linkend="jit"/>).
+ Performing <acronym>JIT</acronym> costs planning time but can
+ accelerate query execution.
+ Setting this to <literal>-1</literal> disables JIT compilation.
+ The default is <literal>100000</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-inline-above-cost" xreflabel="jit_inline_above_cost">
+ <term><varname>jit_inline_above_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>jit_inline_above_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the query cost above which JIT compilation attempts to inline
+ functions and operators. Inlining adds planning time, but can
+ improve execution speed. It is not meaningful to set this to less
+ than <varname>jit_above_cost</varname>.
+ Setting this to <literal>-1</literal> disables inlining.
+ The default is <literal>500000</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-optimize-above-cost" xreflabel="jit_optimize_above_cost">
+ <term><varname>jit_optimize_above_cost</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>jit_optimize_above_cost</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the query cost above which JIT compilation applies expensive
+ optimizations. Such optimization adds planning time, but can improve
+ execution speed. It is not meaningful to set this to less
+ than <varname>jit_above_cost</varname>, and it is unlikely to be
+ beneficial to set it to more
+ than <varname>jit_inline_above_cost</varname>.
+ Setting this to <literal>-1</literal> disables expensive optimizations.
+ The default is <literal>500000</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+ <sect2 id="runtime-config-query-geqo">
+ <title>Genetic Query Optimizer</title>
+
+ <para>
+ The genetic query optimizer (GEQO) is an algorithm that does query
+ planning using heuristic searching. This reduces planning time for
+ complex queries (those joining many relations), at the cost of producing
+ plans that are sometimes inferior to those found by the normal
+ exhaustive-search algorithm.
+ For more information see <xref linkend="geqo"/>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-geqo" xreflabel="geqo">
+ <term><varname>geqo</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>genetic query optimization</primary>
+ </indexterm>
+ <indexterm>
+ <primary>GEQO</primary>
+ <see>genetic query optimization</see>
+ </indexterm>
+ <indexterm>
+ <primary><varname>geqo</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables genetic query optimization.
+ This is on by default. It is usually best not to turn it off in
+ production; the <varname>geqo_threshold</varname> variable provides
+ more granular control of GEQO.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-geqo-threshold" xreflabel="geqo_threshold">
+ <term><varname>geqo_threshold</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>geqo_threshold</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Use genetic query optimization to plan queries with at least
+ this many <literal>FROM</literal> items involved. (Note that a
+ <literal>FULL OUTER JOIN</literal> construct counts as only one <literal>FROM</literal>
+ item.) The default is 12. For simpler queries it is usually best
+ to use the regular, exhaustive-search planner, but for queries with
+ many tables the exhaustive search takes too long, often
+ longer than the penalty of executing a suboptimal plan. Thus,
+ a threshold on the size of the query is a convenient way to manage
+ use of GEQO.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-geqo-effort" xreflabel="geqo_effort">
+ <term><varname>geqo_effort</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>geqo_effort</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the trade-off between planning time and query plan
+ quality in GEQO. This variable must be an integer in the
+ range from 1 to 10. The default value is five. Larger values
+ increase the time spent doing query planning, but also
+ increase the likelihood that an efficient query plan will be
+ chosen.
+ </para>
+
+ <para>
+ <varname>geqo_effort</varname> doesn't actually do anything
+ directly; it is only used to compute the default values for
+ the other variables that influence GEQO behavior (described
+ below). If you prefer, you can set the other parameters by
+ hand instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-geqo-pool-size" xreflabel="geqo_pool_size">
+ <term><varname>geqo_pool_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>geqo_pool_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the pool size used by GEQO, that is the
+ number of individuals in the genetic population. It must be
+ at least two, and useful values are typically 100 to 1000. If
+ it is set to zero (the default setting) then a suitable
+ value is chosen based on <varname>geqo_effort</varname> and
+ the number of tables in the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-geqo-generations" xreflabel="geqo_generations">
+ <term><varname>geqo_generations</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>geqo_generations</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the number of generations used by GEQO, that is
+ the number of iterations of the algorithm. It must
+ be at least one, and useful values are in the same range as
+ the pool size. If it is set to zero (the default setting)
+ then a suitable value is chosen based on
+ <varname>geqo_pool_size</varname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-geqo-selection-bias" xreflabel="geqo_selection_bias">
+ <term><varname>geqo_selection_bias</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>geqo_selection_bias</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the selection bias used by GEQO. The selection bias
+ is the selective pressure within the population. Values can be
+ from 1.50 to 2.00; the latter is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-geqo-seed" xreflabel="geqo_seed">
+ <term><varname>geqo_seed</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>geqo_seed</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the initial value of the random number generator used
+ by GEQO to select random paths through the join order search space.
+ The value can range from zero (the default) to one. Varying the
+ value changes the set of join paths explored, and may result in a
+ better or worse best path being found.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-query-other">
+ <title>Other Planner Options</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-default-statistics-target" xreflabel="default_statistics_target">
+ <term><varname>default_statistics_target</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>default_statistics_target</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the default statistics target for table columns without
+ a column-specific target set via <command>ALTER TABLE
+ SET STATISTICS</command>. Larger values increase the time needed to
+ do <command>ANALYZE</command>, but might improve the quality of the
+ planner's estimates. The default is 100. For more information
+ on the use of statistics by the <productname>PostgreSQL</productname>
+ query planner, refer to <xref linkend="planner-stats"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-constraint-exclusion" xreflabel="constraint_exclusion">
+ <term><varname>constraint_exclusion</varname> (<type>enum</type>)
+ <indexterm>
+ <primary>constraint exclusion</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>constraint_exclusion</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the query planner's use of table constraints to
+ optimize queries.
+ The allowed values of <varname>constraint_exclusion</varname> are
+ <literal>on</literal> (examine constraints for all tables),
+ <literal>off</literal> (never examine constraints), and
+ <literal>partition</literal> (examine constraints only for inheritance
+ child tables and <literal>UNION ALL</literal> subqueries).
+ <literal>partition</literal> is the default setting.
+ It is often used with traditional inheritance trees to improve
+ performance.
+ </para>
+
+ <para>
+ When this parameter allows it for a particular table, the planner
+ compares query conditions with the table's <literal>CHECK</literal>
+ constraints, and omits scanning tables for which the conditions
+ contradict the constraints. For example:
+
+<programlisting>
+CREATE TABLE parent(key integer, ...);
+CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
+CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
+...
+SELECT * FROM parent WHERE key = 2400;
+</programlisting>
+
+ With constraint exclusion enabled, this <command>SELECT</command>
+ will not scan <structname>child1000</structname> at all, improving performance.
+ </para>
+
+ <para>
+ Currently, constraint exclusion is enabled by default
+ only for cases that are often used to implement table partitioning via
+ inheritance trees. Turning it on for all tables imposes extra
+ planning overhead that is quite noticeable on simple queries, and most
+ often will yield no benefit for simple queries. If you have no
+ tables that are partitioned using traditional inheritance, you might
+ prefer to turn it off entirely. (Note that the equivalent feature for
+ partitioned tables is controlled by a separate parameter,
+ <xref linkend="guc-enable-partition-pruning"/>.)
+ </para>
+
+ <para>
+ Refer to <xref linkend="ddl-partitioning-constraint-exclusion"/> for
+ more information on using constraint exclusion to implement
+ partitioning.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-cursor-tuple-fraction" xreflabel="cursor_tuple_fraction">
+ <term><varname>cursor_tuple_fraction</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>cursor_tuple_fraction</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the fraction of a cursor's rows that
+ will be retrieved. The default is 0.1. Smaller values of this
+ setting bias the planner towards using <quote>fast start</quote> plans
+ for cursors, which will retrieve the first few rows quickly while
+ perhaps taking a long time to fetch all rows. Larger values
+ put more emphasis on the total estimated time. At the maximum
+ setting of 1.0, cursors are planned exactly like regular queries,
+ considering only the total estimated time and not how soon the
+ first rows might be delivered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-from-collapse-limit" xreflabel="from_collapse_limit">
+ <term><varname>from_collapse_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>from_collapse_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The planner will merge sub-queries into upper queries if the
+ resulting <literal>FROM</literal> list would have no more than
+ this many items. Smaller values reduce planning time but might
+ yield inferior query plans. The default is eight.
+ For more information see <xref linkend="explicit-joins"/>.
+ </para>
+
+ <para>
+ Setting this value to <xref linkend="guc-geqo-threshold"/> or more
+ may trigger use of the GEQO planner, resulting in non-optimal
+ plans. See <xref linkend="runtime-config-query-geqo"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit" xreflabel="jit">
+ <term><varname>jit</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>jit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines whether <acronym>JIT</acronym> compilation may be used by
+ <productname>PostgreSQL</productname>, if available (see <xref
+ linkend="jit"/>).
+ The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-join-collapse-limit" xreflabel="join_collapse_limit">
+ <term><varname>join_collapse_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>join_collapse_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The planner will rewrite explicit <literal>JOIN</literal>
+ constructs (except <literal>FULL JOIN</literal>s) into lists of
+ <literal>FROM</literal> items whenever a list of no more than this many items
+ would result. Smaller values reduce planning time but might
+ yield inferior query plans.
+ </para>
+
+ <para>
+ By default, this variable is set the same as
+ <varname>from_collapse_limit</varname>, which is appropriate
+ for most uses. Setting it to 1 prevents any reordering of
+ explicit <literal>JOIN</literal>s. Thus, the explicit join order
+ specified in the query will be the actual order in which the
+ relations are joined. Because the query planner does not always choose
+ the optimal join order, advanced users can elect to
+ temporarily set this variable to 1, and then specify the join
+ order they desire explicitly.
+ For more information see <xref linkend="explicit-joins"/>.
+ </para>
+
+ <para>
+ Setting this value to <xref linkend="guc-geqo-threshold"/> or more
+ may trigger use of the GEQO planner, resulting in non-optimal
+ plans. See <xref linkend="runtime-config-query-geqo"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-plan-cache_mode" xreflabel="plan_cache_mode">
+ <term><varname>plan_cache_mode</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>plan_cache_mode</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Prepared statements (either explicitly prepared or implicitly
+ generated, for example by PL/pgSQL) can be executed using custom or
+ generic plans. Custom plans are made afresh for each execution
+ using its specific set of parameter values, while generic plans do
+ not rely on the parameter values and can be re-used across
+ executions. Thus, use of a generic plan saves planning time, but if
+ the ideal plan depends strongly on the parameter values then a
+ generic plan may be inefficient. The choice between these options
+ is normally made automatically, but it can be overridden
+ with <varname>plan_cache_mode</varname>.
+ The allowed values are <literal>auto</literal> (the default),
+ <literal>force_custom_plan</literal> and
+ <literal>force_generic_plan</literal>.
+ This setting is considered when a cached plan is to be executed,
+ not when it is prepared.
+ For more information see <xref linkend="sql-prepare"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recursive-worktable-factor" xreflabel="recursive_worktable_factor">
+ <term><varname>recursive_worktable_factor</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>recursive_worktable_factor</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the planner's estimate of the average size of the working
+ table of a <link linkend="queries-with-recursive">recursive
+ query</link>, as a multiple of the estimated size of the initial
+ non-recursive term of the query. This helps the planner choose
+ the most appropriate method for joining the working table to the
+ query's other tables.
+ The default value is <literal>10.0</literal>. A smaller value
+ such as <literal>1.0</literal> can be helpful when the recursion
+ has low <quote>fan-out</quote> from one step to the next, as for
+ example in shortest-path queries. Graph analytics queries may
+ benefit from larger-than-default values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-logging">
+ <title>Error Reporting and Logging</title>
+
+ <indexterm zone="runtime-config-logging">
+ <primary>server log</primary>
+ </indexterm>
+
+ <sect2 id="runtime-config-logging-where">
+ <title>Where to Log</title>
+
+ <indexterm zone="runtime-config-logging-where">
+ <primary>where to log</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>current_logfiles</primary>
+ <secondary>and the log_destination configuration parameter</secondary>
+ </indexterm>
+
+ <variablelist>
+
+ <varlistentry id="guc-log-destination" xreflabel="log_destination">
+ <term><varname>log_destination</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>log_destination</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> supports several methods
+ for logging server messages, including
+ <systemitem>stderr</systemitem>, <systemitem>csvlog</systemitem>,
+ <systemitem>jsonlog</systemitem>, and
+ <systemitem>syslog</systemitem>. On Windows,
+ <systemitem>eventlog</systemitem> is also supported. Set this
+ parameter to a list of desired log destinations separated by
+ commas. The default is to log to <systemitem>stderr</systemitem>
+ only.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ <para>
+ If <systemitem>csvlog</systemitem> is included in <varname>log_destination</varname>,
+ log entries are output in <quote>comma separated
+ value</quote> (<acronym>CSV</acronym>) format, which is convenient for
+ loading logs into programs.
+ See <xref linkend="runtime-config-logging-csvlog"/> for details.
+ <xref linkend="guc-logging-collector"/> must be enabled to generate
+ CSV-format log output.
+ </para>
+ <para>
+ If <systemitem>jsonlog</systemitem> is included in
+ <varname>log_destination</varname>, log entries are output in
+ <acronym>JSON</acronym> format, which is convenient for loading logs
+ into programs.
+ See <xref linkend="runtime-config-logging-jsonlog"/> for details.
+ <xref linkend="guc-logging-collector"/> must be enabled to generate
+ JSON-format log output.
+ </para>
+ <para>
+ When either <systemitem>stderr</systemitem>,
+ <systemitem>csvlog</systemitem> or <systemitem>jsonlog</systemitem> are
+ included, the file <filename>current_logfiles</filename> is created to
+ record the location of the log file(s) currently in use by the logging
+ collector and the associated logging destination. This provides a
+ convenient way to find the logs currently in use by the instance. Here
+ is an example of this file's content:
+<programlisting>
+stderr log/postgresql.log
+csvlog log/postgresql.csv
+jsonlog log/postgresql.json
+</programlisting>
+
+ <filename>current_logfiles</filename> is recreated when a new log file
+ is created as an effect of rotation, and
+ when <varname>log_destination</varname> is reloaded. It is removed when
+ none of <systemitem>stderr</systemitem>,
+ <systemitem>csvlog</systemitem> or <systemitem>jsonlog</systemitem> are
+ included in <varname>log_destination</varname>, and when the logging
+ collector is disabled.
+ </para>
+
+ <note>
+ <para>
+ On most Unix systems, you will need to alter the configuration of
+ your system's <application>syslog</application> daemon in order
+ to make use of the <systemitem>syslog</systemitem> option for
+ <varname>log_destination</varname>. <productname>PostgreSQL</productname>
+ can log to <application>syslog</application> facilities
+ <literal>LOCAL0</literal> through <literal>LOCAL7</literal> (see <xref
+ linkend="guc-syslog-facility"/>), but the default
+ <application>syslog</application> configuration on most platforms
+ will discard all such messages. You will need to add something like:
+<programlisting>
+local0.* /var/log/postgresql
+</programlisting>
+ to the <application>syslog</application> daemon's configuration file
+ to make it work.
+ </para>
+ <para>
+ On Windows, when you use the <literal>eventlog</literal>
+ option for <varname>log_destination</varname>, you should
+ register an event source and its library with the operating
+ system so that the Windows Event Viewer can display event
+ log messages cleanly.
+ See <xref linkend="event-log-registration"/> for details.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-logging-collector" xreflabel="logging_collector">
+ <term><varname>logging_collector</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>logging_collector</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter enables the <firstterm>logging collector</firstterm>, which
+ is a background process that captures log messages
+ sent to <systemitem>stderr</systemitem> and redirects them into log files.
+ This approach is often more useful than
+ logging to <application>syslog</application>, since some types of messages
+ might not appear in <application>syslog</application> output. (One common
+ example is dynamic-linker failure messages; another is error messages
+ produced by scripts such as <varname>archive_command</varname>.)
+ This parameter can only be set at server start.
+ </para>
+
+ <note>
+ <para>
+ It is possible to log to <systemitem>stderr</systemitem> without using the
+ logging collector; the log messages will just go to wherever the
+ server's <systemitem>stderr</systemitem> is directed. However, that method is
+ only suitable for low log volumes, since it provides no convenient
+ way to rotate log files. Also, on some platforms not using the
+ logging collector can result in lost or garbled log output, because
+ multiple processes writing concurrently to the same log file can
+ overwrite each other's output.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ The logging collector is designed to never lose messages. This means
+ that in case of extremely high load, server processes could be
+ blocked while trying to send additional log messages when the
+ collector has fallen behind. In contrast, <application>syslog</application>
+ prefers to drop messages if it cannot write them, which means it
+ may fail to log some messages in such cases but it will not block
+ the rest of the system.
+ </para>
+ </note>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-directory" xreflabel="log_directory">
+ <term><varname>log_directory</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>log_directory</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>logging_collector</varname> is enabled,
+ this parameter determines the directory in which log files will be created.
+ It can be specified as an absolute path, or relative to the
+ cluster data directory.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ The default is <literal>log</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-filename" xreflabel="log_filename">
+ <term><varname>log_filename</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>log_filename</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>logging_collector</varname> is enabled,
+ this parameter sets the file names of the created log files. The value
+ is treated as a <function>strftime</function> pattern,
+ so <literal>%</literal>-escapes can be used to specify time-varying
+ file names. (Note that if there are
+ any time-zone-dependent <literal>%</literal>-escapes, the computation
+ is done in the zone specified
+ by <xref linkend="guc-log-timezone"/>.)
+ The supported <literal>%</literal>-escapes are similar to those
+ listed in the Open Group's <ulink
+ url="https://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html">strftime
+ </ulink> specification.
+ Note that the system's <function>strftime</function> is not used
+ directly, so platform-specific (nonstandard) extensions do not work.
+ The default is <literal>postgresql-%Y-%m-%d_%H%M%S.log</literal>.
+ </para>
+ <para>
+ If you specify a file name without escapes, you should plan to
+ use a log rotation utility to avoid eventually filling the
+ entire disk. In releases prior to 8.4, if
+ no <literal>%</literal> escapes were
+ present, <productname>PostgreSQL</productname> would append
+ the epoch of the new log file's creation time, but this is no
+ longer the case.
+ </para>
+ <para>
+ If CSV-format output is enabled in <varname>log_destination</varname>,
+ <literal>.csv</literal> will be appended to the timestamped
+ log file name to create the file name for CSV-format output.
+ (If <varname>log_filename</varname> ends in <literal>.log</literal>, the suffix is
+ replaced instead.)
+ </para>
+ <para>
+ If JSON-format output is enabled in <varname>log_destination</varname>,
+ <literal>.json</literal> will be appended to the timestamped
+ log file name to create the file name for JSON-format output.
+ (If <varname>log_filename</varname> ends in <literal>.log</literal>, the suffix is
+ replaced instead.)
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-file-mode" xreflabel="log_file_mode">
+ <term><varname>log_file_mode</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_file_mode</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ On Unix systems this parameter sets the permissions for log files
+ when <varname>logging_collector</varname> is enabled. (On Microsoft
+ Windows this parameter is ignored.)
+ The parameter value is expected to be a numeric mode
+ specified in the format accepted by the
+ <function>chmod</function> and <function>umask</function>
+ system calls. (To use the customary octal format the number
+ must start with a <literal>0</literal> (zero).)
+ </para>
+ <para>
+ The default permissions are <literal>0600</literal>, meaning only the
+ server owner can read or write the log files. The other commonly
+ useful setting is <literal>0640</literal>, allowing members of the owner's
+ group to read the files. Note however that to make use of such a
+ setting, you'll need to alter <xref linkend="guc-log-directory"/> to
+ store the files somewhere outside the cluster data directory. In
+ any case, it's unwise to make the log files world-readable, since
+ they might contain sensitive data.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-rotation-age" xreflabel="log_rotation_age">
+ <term><varname>log_rotation_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_rotation_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>logging_collector</varname> is enabled,
+ this parameter determines the maximum amount of time to use an
+ individual log file, after which a new log file will be created.
+ If this value is specified without units, it is taken as minutes.
+ The default is 24 hours.
+ Set to zero to disable time-based creation of new log files.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-rotation-size" xreflabel="log_rotation_size">
+ <term><varname>log_rotation_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_rotation_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>logging_collector</varname> is enabled,
+ this parameter determines the maximum size of an individual log file.
+ After this amount of data has been emitted into a log file,
+ a new log file will be created.
+ If this value is specified without units, it is taken as kilobytes.
+ The default is 10 megabytes.
+ Set to zero to disable size-based creation of new log files.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-truncate-on-rotation" xreflabel="log_truncate_on_rotation">
+ <term><varname>log_truncate_on_rotation</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_truncate_on_rotation</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <varname>logging_collector</varname> is enabled,
+ this parameter will cause <productname>PostgreSQL</productname> to truncate (overwrite),
+ rather than append to, any existing log file of the same name.
+ However, truncation will occur only when a new file is being opened
+ due to time-based rotation, not during server startup or size-based
+ rotation. When off, pre-existing files will be appended to in
+ all cases. For example, using this setting in combination with
+ a <varname>log_filename</varname> like <literal>postgresql-%H.log</literal>
+ would result in generating twenty-four hourly log files and then
+ cyclically overwriting them.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ <para>
+ Example: To keep 7 days of logs, one log file per day named
+ <literal>server_log.Mon</literal>, <literal>server_log.Tue</literal>,
+ etc., and automatically overwrite last week's log with this week's log,
+ set <varname>log_filename</varname> to <literal>server_log.%a</literal>,
+ <varname>log_truncate_on_rotation</varname> to <literal>on</literal>, and
+ <varname>log_rotation_age</varname> to <literal>1440</literal>.
+ </para>
+ <para>
+ Example: To keep 24 hours of logs, one log file per hour, but
+ also rotate sooner if the log file size exceeds 1GB, set
+ <varname>log_filename</varname> to <literal>server_log.%H%M</literal>,
+ <varname>log_truncate_on_rotation</varname> to <literal>on</literal>,
+ <varname>log_rotation_age</varname> to <literal>60</literal>, and
+ <varname>log_rotation_size</varname> to <literal>1000000</literal>.
+ Including <literal>%M</literal> in <varname>log_filename</varname> allows
+ any size-driven rotations that might occur to select a file name
+ different from the hour's initial file name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-syslog-facility" xreflabel="syslog_facility">
+ <term><varname>syslog_facility</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>syslog_facility</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When logging to <application>syslog</application> is enabled, this parameter
+ determines the <application>syslog</application>
+ <quote>facility</quote> to be used. You can choose
+ from <literal>LOCAL0</literal>, <literal>LOCAL1</literal>,
+ <literal>LOCAL2</literal>, <literal>LOCAL3</literal>, <literal>LOCAL4</literal>,
+ <literal>LOCAL5</literal>, <literal>LOCAL6</literal>, <literal>LOCAL7</literal>;
+ the default is <literal>LOCAL0</literal>. See also the
+ documentation of your system's
+ <application>syslog</application> daemon.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-syslog-ident" xreflabel="syslog_ident">
+ <term><varname>syslog_ident</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>syslog_ident</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When logging to <application>syslog</application> is enabled, this parameter
+ determines the program name used to identify
+ <productname>PostgreSQL</productname> messages in
+ <application>syslog</application> logs. The default is
+ <literal>postgres</literal>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-syslog-sequence-numbers" xreflabel="syslog_sequence_numbers">
+ <term><varname>syslog_sequence_numbers</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>syslog_sequence_numbers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ When logging to <application>syslog</application> and this is on (the
+ default), then each message will be prefixed by an increasing
+ sequence number (such as <literal>[2]</literal>). This circumvents
+ the <quote>--- last message repeated N times ---</quote> suppression
+ that many syslog implementations perform by default. In more modern
+ syslog implementations, repeated message suppression can be configured
+ (for example, <literal>$RepeatedMsgReduction</literal>
+ in <productname>rsyslog</productname>), so this might not be
+ necessary. Also, you could turn this off if you actually want to
+ suppress repeated messages.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-syslog-split-messages" xreflabel="syslog_split_messages">
+ <term><varname>syslog_split_messages</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>syslog_split_messages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When logging to <application>syslog</application> is enabled, this parameter
+ determines how messages are delivered to syslog. When on (the
+ default), messages are split by lines, and long lines are split so
+ that they will fit into 1024 bytes, which is a typical size limit for
+ traditional syslog implementations. When off, PostgreSQL server log
+ messages are delivered to the syslog service as is, and it is up to
+ the syslog service to cope with the potentially bulky messages.
+ </para>
+
+ <para>
+ If syslog is ultimately logging to a text file, then the effect will
+ be the same either way, and it is best to leave the setting on, since
+ most syslog implementations either cannot handle large messages or
+ would need to be specially configured to handle them. But if syslog
+ is ultimately writing into some other medium, it might be necessary or
+ more useful to keep messages logically together.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-event-source" xreflabel="event_source">
+ <term><varname>event_source</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>event_source</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When logging to <application>event log</application> is enabled, this parameter
+ determines the program name used to identify
+ <productname>PostgreSQL</productname> messages in
+ the log. The default is <literal>PostgreSQL</literal>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-logging-when">
+ <title>When to Log</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-log-min-messages" xreflabel="log_min_messages">
+ <term><varname>log_min_messages</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>log_min_messages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls which <link linkend="runtime-config-severity-levels">message
+ levels</link> are written to the server log.
+ Valid values are <literal>DEBUG5</literal>, <literal>DEBUG4</literal>,
+ <literal>DEBUG3</literal>, <literal>DEBUG2</literal>, <literal>DEBUG1</literal>,
+ <literal>INFO</literal>, <literal>NOTICE</literal>, <literal>WARNING</literal>,
+ <literal>ERROR</literal>, <literal>LOG</literal>, <literal>FATAL</literal>, and
+ <literal>PANIC</literal>. Each level includes all the levels that
+ follow it. The later the level, the fewer messages are sent
+ to the log. The default is <literal>WARNING</literal>. Note that
+ <literal>LOG</literal> has a different rank here than in
+ <xref linkend="guc-client-min-messages"/>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-min-error-statement" xreflabel="log_min_error_statement">
+ <term><varname>log_min_error_statement</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>log_min_error_statement</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls which SQL statements that cause an error
+ condition are recorded in the server log. The current
+ SQL statement is included in the log entry for any message of
+ the specified
+ <link linkend="runtime-config-severity-levels">severity</link>
+ or higher.
+ Valid values are <literal>DEBUG5</literal>,
+ <literal>DEBUG4</literal>, <literal>DEBUG3</literal>,
+ <literal>DEBUG2</literal>, <literal>DEBUG1</literal>,
+ <literal>INFO</literal>, <literal>NOTICE</literal>,
+ <literal>WARNING</literal>, <literal>ERROR</literal>,
+ <literal>LOG</literal>,
+ <literal>FATAL</literal>, and <literal>PANIC</literal>.
+ The default is <literal>ERROR</literal>, which means statements
+ causing errors, log messages, fatal errors, or panics will be logged.
+ To effectively turn off logging of failing statements,
+ set this parameter to <literal>PANIC</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-min-duration-statement" xreflabel="log_min_duration_statement">
+ <term><varname>log_min_duration_statement</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_min_duration_statement</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes the duration of each completed statement to be logged
+ if the statement ran for at least the specified amount of time.
+ For example, if you set it to <literal>250ms</literal>
+ then all SQL statements that run 250ms or longer will be
+ logged. Enabling this parameter can be helpful in tracking down
+ unoptimized queries in your applications.
+ If this value is specified without units, it is taken as milliseconds.
+ Setting this to zero prints all statement durations.
+ <literal>-1</literal> (the default) disables logging statement
+ durations.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ This overrides <xref linkend="guc-log-min-duration-sample"/>,
+ meaning that queries with duration exceeding this setting are not
+ subject to sampling and are always logged.
+ </para>
+
+ <para>
+ For clients using extended query protocol, durations of the Parse,
+ Bind, and Execute steps are logged independently.
+ </para>
+
+ <note>
+ <para>
+ When using this option together with
+ <xref linkend="guc-log-statement"/>,
+ the text of statements that are logged because of
+ <varname>log_statement</varname> will not be repeated in the
+ duration log message.
+ If you are not using <application>syslog</application>, it is recommended
+ that you log the PID or session ID using
+ <xref linkend="guc-log-line-prefix"/>
+ so that you can link the statement message to the later
+ duration message using the process ID or session ID.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-min-duration-sample" xreflabel="log_min_duration_sample">
+ <term><varname>log_min_duration_sample</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_min_duration_sample</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Allows sampling the duration of completed statements that ran for
+ at least the specified amount of time. This produces the same
+ kind of log entries as
+ <xref linkend="guc-log-min-duration-statement"/>, but only for a
+ subset of the executed statements, with sample rate controlled by
+ <xref linkend="guc-log-statement-sample-rate"/>.
+ For example, if you set it to <literal>100ms</literal> then all
+ SQL statements that run 100ms or longer will be considered for
+ sampling. Enabling this parameter can be helpful when the
+ traffic is too high to log all queries.
+ If this value is specified without units, it is taken as milliseconds.
+ Setting this to zero samples all statement durations.
+ <literal>-1</literal> (the default) disables sampling statement
+ durations.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ This setting has lower priority
+ than <varname>log_min_duration_statement</varname>, meaning that
+ statements with durations
+ exceeding <varname>log_min_duration_statement</varname> are not
+ subject to sampling and are always logged.
+ </para>
+
+ <para>
+ Other notes for <varname>log_min_duration_statement</varname>
+ apply also to this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-statement-sample-rate" xreflabel="log_statement_sample_rate">
+ <term><varname>log_statement_sample_rate</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>log_statement_sample_rate</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines the fraction of statements with duration exceeding
+ <xref linkend="guc-log-min-duration-sample"/> that will be logged.
+ Sampling is stochastic, for example <literal>0.5</literal> means
+ there is statistically one chance in two that any given statement
+ will be logged.
+ The default is <literal>1.0</literal>, meaning to log all sampled
+ statements.
+ Setting this to zero disables sampled statement-duration logging,
+ the same as setting
+ <varname>log_min_duration_sample</varname> to
+ <literal>-1</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-transaction-sample-rate" xreflabel="log_transaction_sample_rate">
+ <term><varname>log_transaction_sample_rate</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>log_transaction_sample_rate</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the fraction of transactions whose statements are all logged,
+ in addition to statements logged for other reasons. It applies to
+ each new transaction regardless of its statements' durations.
+ Sampling is stochastic, for example <literal>0.1</literal> means
+ there is statistically one chance in ten that any given transaction
+ will be logged.
+ <varname>log_transaction_sample_rate</varname> can be helpful to
+ construct a sample of transactions.
+ The default is <literal>0</literal>, meaning not to log
+ statements from any additional transactions. Setting this
+ to <literal>1</literal> logs all statements of all transactions.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ <note>
+ <para>
+ Like all statement-logging options, this option can add significant
+ overhead.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-startup-progress-interval" xreflabel="log_startup_progress_interval">
+ <term><varname>log_startup_progress_interval</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_startup_progress_interval</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the amount of time after which the startup process will log
+ a message about a long-running operation that is still in progress,
+ as well as the interval between further progress messages for that
+ operation. The default is 10 seconds. A setting of <literal>0</literal>
+ disables the feature. If this value is specified without units,
+ it is taken as milliseconds. This setting is applied separately to
+ each operation.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+
+ <para>
+ For example, if syncing the data directory takes 25 seconds and
+ thereafter resetting unlogged relations takes 8 seconds, and if this
+ setting has the default value of 10 seconds, then a messages will be
+ logged for syncing the data directory after it has been in progress
+ for 10 seconds and again after it has been in progress for 20 seconds,
+ but nothing will be logged for resetting unlogged relations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ <xref linkend="runtime-config-severity-levels"/> explains the message
+ severity levels used by <productname>PostgreSQL</productname>. If logging output
+ is sent to <systemitem>syslog</systemitem> or Windows'
+ <systemitem>eventlog</systemitem>, the severity levels are translated
+ as shown in the table.
+ </para>
+
+ <table id="runtime-config-severity-levels">
+ <title>Message Severity Levels</title>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Severity</entry>
+ <entry>Usage</entry>
+ <entry><systemitem>syslog</systemitem></entry>
+ <entry><systemitem>eventlog</systemitem></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>DEBUG1 .. DEBUG5</literal></entry>
+ <entry>Provides successively-more-detailed information for use by
+ developers.</entry>
+ <entry><literal>DEBUG</literal></entry>
+ <entry><literal>INFORMATION</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>INFO</literal></entry>
+ <entry>Provides information implicitly requested by the user,
+ e.g., output from <command>VACUUM VERBOSE</command>.</entry>
+ <entry><literal>INFO</literal></entry>
+ <entry><literal>INFORMATION</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>NOTICE</literal></entry>
+ <entry>Provides information that might be helpful to users, e.g.,
+ notice of truncation of long identifiers.</entry>
+ <entry><literal>NOTICE</literal></entry>
+ <entry><literal>INFORMATION</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>WARNING</literal></entry>
+ <entry>Provides warnings of likely problems, e.g., <command>COMMIT</command>
+ outside a transaction block.</entry>
+ <entry><literal>NOTICE</literal></entry>
+ <entry><literal>WARNING</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>ERROR</literal></entry>
+ <entry>Reports an error that caused the current command to
+ abort.</entry>
+ <entry><literal>WARNING</literal></entry>
+ <entry><literal>ERROR</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>LOG</literal></entry>
+ <entry>Reports information of interest to administrators, e.g.,
+ checkpoint activity.</entry>
+ <entry><literal>INFO</literal></entry>
+ <entry><literal>INFORMATION</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>FATAL</literal></entry>
+ <entry>Reports an error that caused the current session to
+ abort.</entry>
+ <entry><literal>ERR</literal></entry>
+ <entry><literal>ERROR</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>PANIC</literal></entry>
+ <entry>Reports an error that caused all database sessions to abort.</entry>
+ <entry><literal>CRIT</literal></entry>
+ <entry><literal>ERROR</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+ <sect2 id="runtime-config-logging-what">
+ <title>What to Log</title>
+
+ <note>
+ <para>
+ What you choose to log can have security implications; see
+ <xref linkend="logfile-maintenance"/>.
+ </para>
+ </note>
+
+ <variablelist>
+
+ <varlistentry id="guc-application-name" xreflabel="application_name">
+ <term><varname>application_name</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>application_name</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The <varname>application_name</varname> can be any string of less than
+ <symbol>NAMEDATALEN</symbol> characters (64 characters in a standard build).
+ It is typically set by an application upon connection to the server.
+ The name will be displayed in the <structname>pg_stat_activity</structname> view
+ and included in CSV log entries. It can also be included in regular
+ log entries via the <xref linkend="guc-log-line-prefix"/> parameter.
+ Only printable ASCII characters may be used in the
+ <varname>application_name</varname> value. Other characters will be
+ replaced with question marks (<literal>?</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>debug_print_parse</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>debug_print_parse</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <term><varname>debug_print_rewritten</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>debug_print_rewritten</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <term><varname>debug_print_plan</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>debug_print_plan</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ These parameters enable various debugging output to be emitted.
+ When set, they print the resulting parse tree, the query rewriter
+ output, or the execution plan for each executed query.
+ These messages are emitted at <literal>LOG</literal> message level, so by
+ default they will appear in the server log but will not be sent to the
+ client. You can change that by adjusting
+ <xref linkend="guc-client-min-messages"/> and/or
+ <xref linkend="guc-log-min-messages"/>.
+ These parameters are off by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>debug_pretty_print</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>debug_pretty_print</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set, <varname>debug_pretty_print</varname> indents the messages
+ produced by <varname>debug_print_parse</varname>,
+ <varname>debug_print_rewritten</varname>, or
+ <varname>debug_print_plan</varname>. This results in more readable
+ but much longer output than the <quote>compact</quote> format used when
+ it is off. It is on by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration">
+ <term><varname>log_autovacuum_min_duration</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_autovacuum_min_duration</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes each action executed by autovacuum to be logged if it ran for at
+ least the specified amount of time. Setting this to zero logs
+ all autovacuum actions. <literal>-1</literal> disables logging autovacuum
+ actions. If this value is specified without units, it is taken as milliseconds.
+ For example, if you set this to
+ <literal>250ms</literal> then all automatic vacuums and analyzes that run
+ 250ms or longer will be logged. In addition, when this parameter is
+ set to any value other than <literal>-1</literal>, a message will be
+ logged if an autovacuum action is skipped due to a conflicting lock or a
+ concurrently dropped relation. The default is <literal>10min</literal>.
+ Enabling this parameter can be helpful in tracking autovacuum activity.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line; but the setting can be overridden for
+ individual tables by changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-checkpoints" xreflabel="log_checkpoints">
+ <term><varname>log_checkpoints</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_checkpoints</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes checkpoints and restartpoints to be logged in the server log.
+ Some statistics are included in the log messages, including the number
+ of buffers written and the time spent writing them.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line. The default is on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-connections" xreflabel="log_connections">
+ <term><varname>log_connections</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_connections</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes each attempted connection to the server to be logged,
+ as well as successful completion of both client authentication (if
+ necessary) and authorization.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this parameter at session start,
+ and it cannot be changed at all within a session.
+ The default is <literal>off</literal>.
+ </para>
+
+ <note>
+ <para>
+ Some client programs, like <application>psql</application>, attempt
+ to connect twice while determining if a password is required, so
+ duplicate <quote>connection received</quote> messages do not
+ necessarily indicate a problem.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-disconnections" xreflabel="log_disconnections">
+ <term><varname>log_disconnections</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_disconnections</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes session terminations to be logged. The log output
+ provides information similar to <varname>log_connections</varname>,
+ plus the duration of the session.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this parameter at session start,
+ and it cannot be changed at all within a session.
+ The default is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="guc-log-duration" xreflabel="log_duration">
+ <term><varname>log_duration</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_duration</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes the duration of every completed statement to be logged.
+ The default is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ For clients using extended query protocol, durations of the Parse,
+ Bind, and Execute steps are logged independently.
+ </para>
+
+ <note>
+ <para>
+ The difference between enabling <varname>log_duration</varname> and setting
+ <xref linkend="guc-log-min-duration-statement"/> to zero is that
+ exceeding <varname>log_min_duration_statement</varname> forces the text of
+ the query to be logged, but this option doesn't. Thus, if
+ <varname>log_duration</varname> is <literal>on</literal> and
+ <varname>log_min_duration_statement</varname> has a positive value, all
+ durations are logged but the query text is included only for
+ statements exceeding the threshold. This behavior can be useful for
+ gathering statistics in high-load installations.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-error-verbosity" xreflabel="log_error_verbosity">
+ <term><varname>log_error_verbosity</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>log_error_verbosity</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls the amount of detail written in the server log for each
+ message that is logged. Valid values are <literal>TERSE</literal>,
+ <literal>DEFAULT</literal>, and <literal>VERBOSE</literal>, each adding more
+ fields to displayed messages. <literal>TERSE</literal> excludes
+ the logging of <literal>DETAIL</literal>, <literal>HINT</literal>,
+ <literal>QUERY</literal>, and <literal>CONTEXT</literal> error information.
+ <literal>VERBOSE</literal> output includes the <symbol>SQLSTATE</symbol> error
+ code (see also <xref linkend="errcodes-appendix"/>) and the source code file name, function name,
+ and line number that generated the error.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-hostname" xreflabel="log_hostname">
+ <term><varname>log_hostname</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_hostname</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ By default, connection log messages only show the IP address of the
+ connecting host. Turning this parameter on causes logging of the
+ host name as well. Note that depending on your host name resolution
+ setup this might impose a non-negligible performance penalty.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-line-prefix" xreflabel="log_line_prefix">
+ <term><varname>log_line_prefix</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>log_line_prefix</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This is a <function>printf</function>-style string that is output at the
+ beginning of each log line.
+ <literal>%</literal> characters begin <quote>escape sequences</quote>
+ that are replaced with status information as outlined below.
+ Unrecognized escapes are ignored. Other
+ characters are copied straight to the log line. Some escapes are
+ only recognized by session processes, and will be treated as empty by
+ background processes such as the main server process. Status
+ information may be aligned either left or right by specifying a
+ numeric literal after the % and before the option. A negative
+ value will cause the status information to be padded on the
+ right with spaces to give it a minimum width, whereas a positive
+ value will pad on the left. Padding can be useful to aid human
+ readability in log files.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line. The default is
+ <literal>'%m [%p] '</literal> which logs a time stamp and the process ID.
+ </para>
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Escape</entry>
+ <entry>Effect</entry>
+ <entry>Session only</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>%a</literal></entry>
+ <entry>Application name</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%u</literal></entry>
+ <entry>User name</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%d</literal></entry>
+ <entry>Database name</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%r</literal></entry>
+ <entry>Remote host name or IP address, and remote port</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%h</literal></entry>
+ <entry>Remote host name or IP address</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%b</literal></entry>
+ <entry>Backend type</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%p</literal></entry>
+ <entry>Process ID</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%P</literal></entry>
+ <entry>Process ID of the parallel group leader, if this process
+ is a parallel query worker</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%t</literal></entry>
+ <entry>Time stamp without milliseconds</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%m</literal></entry>
+ <entry>Time stamp with milliseconds</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%n</literal></entry>
+ <entry>Time stamp with milliseconds (as a Unix epoch)</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%i</literal></entry>
+ <entry>Command tag: type of session's current command</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%e</literal></entry>
+ <entry>SQLSTATE error code</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%c</literal></entry>
+ <entry>Session ID: see below</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%l</literal></entry>
+ <entry>Number of the log line for each session or process, starting at 1</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%s</literal></entry>
+ <entry>Process start time stamp</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%v</literal></entry>
+ <entry>Virtual transaction ID (backendID/localXID)</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%x</literal></entry>
+ <entry>Transaction ID (0 if none is assigned)</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%q</literal></entry>
+ <entry>Produces no output, but tells non-session
+ processes to stop at this point in the string; ignored by
+ session processes</entry>
+ <entry>no</entry>
+ </row>
+ <row>
+ <entry><literal>%Q</literal></entry>
+ <entry>Query identifier of the current query. Query
+ identifiers are not computed by default, so this field
+ will be zero unless <xref linkend="guc-compute-query-id"/>
+ parameter is enabled or a third-party module that computes
+ query identifiers is configured.</entry>
+ <entry>yes</entry>
+ </row>
+ <row>
+ <entry><literal>%%</literal></entry>
+ <entry>Literal <literal>%</literal></entry>
+ <entry>no</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ The backend type corresponds to the column
+ <structfield>backend_type</structfield> in the view
+ <link linkend="monitoring-pg-stat-activity-view">
+ <structname>pg_stat_activity</structname></link>,
+ but additional types can appear
+ in the log that don't show in that view.
+ </para>
+
+ <para>
+ The <literal>%c</literal> escape prints a quasi-unique session identifier,
+ consisting of two 4-byte hexadecimal numbers (without leading zeros)
+ separated by a dot. The numbers are the process start time and the
+ process ID, so <literal>%c</literal> can also be used as a space saving way
+ of printing those items. For example, to generate the session
+ identifier from <literal>pg_stat_activity</literal>, use this query:
+<programlisting>
+SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' ||
+ to_hex(pid)
+FROM pg_stat_activity;
+</programlisting>
+
+ </para>
+
+ <tip>
+ <para>
+ If you set a nonempty value for <varname>log_line_prefix</varname>,
+ you should usually make its last character be a space, to provide
+ visual separation from the rest of the log line. A punctuation
+ character can be used too.
+ </para>
+ </tip>
+
+ <tip>
+ <para>
+ <application>Syslog</application> produces its own
+ time stamp and process ID information, so you probably do not want to
+ include those escapes if you are logging to <application>syslog</application>.
+ </para>
+ </tip>
+
+ <tip>
+ <para>
+ The <literal>%q</literal> escape is useful when including information that is
+ only available in session (backend) context like user or database
+ name. For example:
+<programlisting>
+log_line_prefix = '%m [%p] %q%u@%d/%a '
+</programlisting>
+ </para>
+ </tip>
+
+ <note>
+ <para>
+ The <literal>%Q</literal> escape always reports a zero identifier
+ for lines output by <xref linkend="guc-log-statement"/> because
+ <varname>log_statement</varname> generates output before an
+ identifier can be calculated, including invalid statements for
+ which an identifier cannot be calculated.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-lock-waits" xreflabel="log_lock_waits">
+ <term><varname>log_lock_waits</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_lock_waits</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls whether a log message is produced when a session waits
+ longer than <xref linkend="guc-deadlock-timeout"/> to acquire a
+ lock. This is useful in determining if lock waits are causing
+ poor performance. The default is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-recovery-conflict-waits" xreflabel="log_recovery_conflict_waits">
+ <term><varname>log_recovery_conflict_waits</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_recovery_conflict_waits</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls whether a log message is produced when the startup process
+ waits longer than <varname>deadlock_timeout</varname>
+ for recovery conflicts. This is useful in determining if recovery
+ conflicts prevent the recovery from applying WAL.
+ </para>
+
+ <para>
+ The default is <literal>off</literal>. This parameter can only be set
+ in the <filename>postgresql.conf</filename> file or on the server
+ command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-parameter-max-length" xreflabel="log_parameter_max_length">
+ <term><varname>log_parameter_max_length</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_parameter_max_length</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If greater than zero, each bind parameter value logged with a
+ non-error statement-logging message is trimmed to this many bytes.
+ Zero disables logging of bind parameters for non-error statement logs.
+ <literal>-1</literal> (the default) allows bind parameters to be
+ logged in full.
+ If this value is specified without units, it is taken as bytes.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ This setting only affects log messages printed as a result of
+ <xref linkend="guc-log-statement"/>,
+ <xref linkend="guc-log-duration"/>, and related settings. Non-zero
+ values of this setting add some overhead, particularly if parameters
+ are sent in binary form, since then conversion to text is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-parameter-max-length-on-error" xreflabel="log_parameter_max_length_on_error">
+ <term><varname>log_parameter_max_length_on_error</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_parameter_max_length_on_error</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If greater than zero, each bind parameter value reported in error
+ messages is trimmed to this many bytes.
+ Zero (the default) disables including bind parameters in error
+ messages.
+ <literal>-1</literal> allows bind parameters to be printed in full.
+ If this value is specified without units, it is taken as bytes.
+ </para>
+
+ <para>
+ Non-zero values of this setting add overhead, as
+ <productname>PostgreSQL</productname> will need to store textual
+ representations of parameter values in memory at the start of each
+ statement, whether or not an error eventually occurs. The overhead
+ is greater when bind parameters are sent in binary form than when
+ they are sent as text, since the former case requires data
+ conversion while the latter only requires copying the string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-statement" xreflabel="log_statement">
+ <term><varname>log_statement</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>log_statement</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls which SQL statements are logged. Valid values are
+ <literal>none</literal> (off), <literal>ddl</literal>, <literal>mod</literal>, and
+ <literal>all</literal> (all statements). <literal>ddl</literal> logs all data definition
+ statements, such as <command>CREATE</command>, <command>ALTER</command>, and
+ <command>DROP</command> statements. <literal>mod</literal> logs all
+ <literal>ddl</literal> statements, plus data-modifying statements
+ such as <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, <command>TRUNCATE</command>,
+ and <command>COPY FROM</command>.
+ <command>PREPARE</command>, <command>EXECUTE</command>, and
+ <command>EXPLAIN ANALYZE</command> statements are also logged if their
+ contained command is of an appropriate type. For clients using
+ extended query protocol, logging occurs when an Execute message
+ is received, and values of the Bind parameters are included
+ (with any embedded single-quote marks doubled).
+ </para>
+
+ <para>
+ The default is <literal>none</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <note>
+ <para>
+ Statements that contain simple syntax errors are not logged
+ even by the <varname>log_statement</varname> = <literal>all</literal> setting,
+ because the log message is emitted only after basic parsing has
+ been done to determine the statement type. In the case of extended
+ query protocol, this setting likewise does not log statements that
+ fail before the Execute phase (i.e., during parse analysis or
+ planning). Set <varname>log_min_error_statement</varname> to
+ <literal>ERROR</literal> (or lower) to log such statements.
+ </para>
+ <para>
+ Logged statements might reveal sensitive data and even contain
+ plaintext passwords.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-replication-commands" xreflabel="log_replication_commands">
+ <term><varname>log_replication_commands</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_replication_commands</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Causes each replication command to be logged in the server log.
+ See <xref linkend="protocol-replication"/> for more information about
+ replication command. The default value is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-temp-files" xreflabel="log_temp_files">
+ <term><varname>log_temp_files</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_temp_files</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls logging of temporary file names and sizes.
+ Temporary files can be
+ created for sorts, hashes, and temporary query results.
+ If enabled by this setting, a log entry is emitted for each
+ temporary file when it is deleted.
+ A value of zero logs all temporary file information, while positive
+ values log only files whose size is greater than or equal to
+ the specified amount of data.
+ If this value is specified without units, it is taken as kilobytes.
+ The default setting is -1, which disables such logging.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-timezone" xreflabel="log_timezone">
+ <term><varname>log_timezone</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>log_timezone</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the time zone used for timestamps written in the server log.
+ Unlike <xref linkend="guc-timezone"/>, this value is cluster-wide,
+ so that all sessions will report timestamps consistently.
+ The built-in default is <literal>GMT</literal>, but that is typically
+ overridden in <filename>postgresql.conf</filename>; <application>initdb</application>
+ will install a setting there corresponding to its system environment.
+ See <xref linkend="datatype-timezones"/> for more information.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-logging-csvlog">
+ <title>Using CSV-Format Log Output</title>
+
+ <para>
+ Including <literal>csvlog</literal> in the <varname>log_destination</varname> list
+ provides a convenient way to import log files into a database table.
+ This option emits log lines in comma-separated-values
+ (<acronym>CSV</acronym>) format,
+ with these columns:
+ time stamp with milliseconds,
+ user name,
+ database name,
+ process ID,
+ client host:port number,
+ session ID,
+ per-session line number,
+ command tag,
+ session start time,
+ virtual transaction ID,
+ regular transaction ID,
+ error severity,
+ SQLSTATE code,
+ error message,
+ error message detail,
+ hint,
+ internal query that led to the error (if any),
+ character count of the error position therein,
+ error context,
+ user query that led to the error (if any and enabled by
+ <varname>log_min_error_statement</varname>),
+ character count of the error position therein,
+ location of the error in the PostgreSQL source code
+ (if <varname>log_error_verbosity</varname> is set to <literal>verbose</literal>),
+ application name, backend type, process ID of parallel group leader,
+ and query id.
+ Here is a sample table definition for storing CSV-format log output:
+
+<programlisting>
+CREATE TABLE postgres_log
+(
+ log_time timestamp(3) with time zone,
+ user_name text,
+ database_name text,
+ process_id integer,
+ connection_from text,
+ session_id text,
+ session_line_num bigint,
+ command_tag text,
+ session_start_time timestamp with time zone,
+ virtual_transaction_id text,
+ transaction_id bigint,
+ error_severity text,
+ sql_state_code text,
+ message text,
+ detail text,
+ hint text,
+ internal_query text,
+ internal_query_pos integer,
+ context text,
+ query text,
+ query_pos integer,
+ location text,
+ application_name text,
+ backend_type text,
+ leader_pid integer,
+ query_id bigint,
+ PRIMARY KEY (session_id, session_line_num)
+);
+</programlisting>
+ </para>
+
+ <para>
+ To import a log file into this table, use the <command>COPY FROM</command>
+ command:
+
+<programlisting>
+COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
+</programlisting>
+ It is also possible to access the file as a foreign table, using
+ the supplied <xref linkend="file-fdw"/> module.
+ </para>
+
+ <para>
+ There are a few things you need to do to simplify importing CSV log
+ files:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ Set <varname>log_filename</varname> and
+ <varname>log_rotation_age</varname> to provide a consistent,
+ predictable naming scheme for your log files. This lets you
+ predict what the file name will be and know when an individual log
+ file is complete and therefore ready to be imported.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Set <varname>log_rotation_size</varname> to 0 to disable
+ size-based log rotation, as it makes the log file name difficult
+ to predict.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Set <varname>log_truncate_on_rotation</varname> to <literal>on</literal> so
+ that old log data isn't mixed with the new in the same file.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The table definition above includes a primary key specification.
+ This is useful to protect against accidentally importing the same
+ information twice. The <command>COPY</command> command commits all of the
+ data it imports at one time, so any error will cause the entire
+ import to fail. If you import a partial log file and later import
+ the file again when it is complete, the primary key violation will
+ cause the import to fail. Wait until the log is complete and
+ closed before importing. This procedure will also protect against
+ accidentally importing a partial line that hasn't been completely
+ written, which would also cause <command>COPY</command> to fail.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </sect2>
+ <sect2 id="runtime-config-logging-jsonlog">
+ <title>Using JSON-Format Log Output</title>
+
+ <para>
+ Including <literal>jsonlog</literal> in the
+ <varname>log_destination</varname> list provides a convenient way to
+ import log files into many different programs. This option emits log
+ lines in <acronym>JSON</acronym> format.
+ </para>
+
+ <para>
+ String fields with null values are excluded from output.
+ Additional fields may be added in the future. User applications that
+ process <literal>jsonlog</literal> output should ignore unknown fields.
+ </para>
+
+ <para>
+ Each log line is serialized as a JSON object with the set of keys and
+ their associated values shown in <xref
+ linkend="runtime-config-logging-jsonlog-keys-values"/>.
+ </para>
+
+ <table id="runtime-config-logging-jsonlog-keys-values">
+ <title>Keys and Values of JSON Log Entries</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Key name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>timestamp</literal></entry>
+ <entry>string</entry>
+ <entry>Time stamp with milliseconds</entry>
+ </row>
+ <row>
+ <entry><literal>user</literal></entry>
+ <entry>string</entry>
+ <entry>User name</entry>
+ </row>
+ <row>
+ <entry><literal>dbname</literal></entry>
+ <entry>string</entry>
+ <entry>Database name</entry>
+ </row>
+ <row>
+ <entry><literal>pid</literal></entry>
+ <entry>number</entry>
+ <entry>Process ID</entry>
+ </row>
+ <row>
+ <entry><literal>remote_host</literal></entry>
+ <entry>string</entry>
+ <entry>Client host</entry>
+ </row>
+ <row>
+ <entry><literal>remote_port</literal></entry>
+ <entry>number</entry>
+ <entry>Client port</entry>
+ </row>
+ <row>
+ <entry><literal>session_id</literal></entry>
+ <entry>string</entry>
+ <entry>Session ID</entry>
+ </row>
+ <row>
+ <entry><literal>line_num</literal></entry>
+ <entry>number</entry>
+ <entry>Per-session line number</entry>
+ </row>
+ <row>
+ <entry><literal>ps</literal></entry>
+ <entry>string</entry>
+ <entry>Current ps display</entry>
+ </row>
+ <row>
+ <entry><literal>session_start</literal></entry>
+ <entry>string</entry>
+ <entry>Session start time</entry>
+ </row>
+ <row>
+ <entry><literal>vxid</literal></entry>
+ <entry>string</entry>
+ <entry>Virtual transaction ID</entry>
+ </row>
+ <row>
+ <entry><literal>txid</literal></entry>
+ <entry>string</entry>
+ <entry>Regular transaction ID</entry>
+ </row>
+ <row>
+ <entry><literal>error_severity</literal></entry>
+ <entry>string</entry>
+ <entry>Error severity</entry>
+ </row>
+ <row>
+ <entry><literal>state_code</literal></entry>
+ <entry>string</entry>
+ <entry>SQLSTATE code</entry>
+ </row>
+ <row>
+ <entry><literal>message</literal></entry>
+ <entry>string</entry>
+ <entry>Error message</entry>
+ </row>
+ <row>
+ <entry><literal>detail</literal></entry>
+ <entry>string</entry>
+ <entry>Error message detail</entry>
+ </row>
+ <row>
+ <entry><literal>hint</literal></entry>
+ <entry>string</entry>
+ <entry>Error message hint</entry>
+ </row>
+ <row>
+ <entry><literal>internal_query</literal></entry>
+ <entry>string</entry>
+ <entry>Internal query that led to the error</entry>
+ </row>
+ <row>
+ <entry><literal>internal_position</literal></entry>
+ <entry>number</entry>
+ <entry>Cursor index into internal query</entry>
+ </row>
+ <row>
+ <entry><literal>context</literal></entry>
+ <entry>string</entry>
+ <entry>Error context</entry>
+ </row>
+ <row>
+ <entry><literal>statement</literal></entry>
+ <entry>string</entry>
+ <entry>Client-supplied query string</entry>
+ </row>
+ <row>
+ <entry><literal>cursor_position</literal></entry>
+ <entry>number</entry>
+ <entry>Cursor index into query string</entry>
+ </row>
+ <row>
+ <entry><literal>func_name</literal></entry>
+ <entry>string</entry>
+ <entry>Error location function name</entry>
+ </row>
+ <row>
+ <entry><literal>file_name</literal></entry>
+ <entry>string</entry>
+ <entry>File name of error location</entry>
+ </row>
+ <row>
+ <entry><literal>file_line_num</literal></entry>
+ <entry>number</entry>
+ <entry>File line number of the error location</entry>
+ </row>
+ <row>
+ <entry><literal>application_name</literal></entry>
+ <entry>string</entry>
+ <entry>Client application name</entry>
+ </row>
+ <row>
+ <entry><literal>backend_type</literal></entry>
+ <entry>string</entry>
+ <entry>Type of backend</entry>
+ </row>
+ <row>
+ <entry><literal>leader_pid</literal></entry>
+ <entry>number</entry>
+ <entry>Process ID of leader for active parallel workers</entry>
+ </row>
+ <row>
+ <entry><literal>query_id</literal></entry>
+ <entry>number</entry>
+ <entry>Query ID</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Process Title</title>
+
+ <para>
+ These settings control how process titles of server processes are
+ modified. Process titles are typically viewed using programs like
+ <application>ps</application> or, on Windows, <application>Process Explorer</application>.
+ See <xref linkend="monitoring-ps"/> for details.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-cluster-name" xreflabel="cluster_name">
+ <term><varname>cluster_name</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>cluster_name</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets a name that identifies this database cluster (instance) for
+ various purposes. The cluster name appears in the process title for
+ all server processes in this cluster. Moreover, it is the default
+ application name for a standby connection (see <xref
+ linkend="guc-synchronous-standby-names"/>.)
+ </para>
+
+ <para>
+ The name can be any string of less
+ than <symbol>NAMEDATALEN</symbol> characters (64 characters in a standard
+ build). Only printable ASCII characters may be used in the
+ <varname>cluster_name</varname> value. Other characters will be
+ replaced with question marks (<literal>?</literal>). No name is shown
+ if this parameter is set to the empty string <literal>''</literal> (which is
+ the default). This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-update-process-title" xreflabel="update_process_title">
+ <term><varname>update_process_title</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>update_process_title</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables updating of the process title every time a new SQL command
+ is received by the server.
+ This setting defaults to <literal>on</literal> on most platforms, but it
+ defaults to <literal>off</literal> on Windows due to that platform's larger
+ overhead for updating the process title.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-statistics">
+ <title>Run-time Statistics</title>
+
+ <sect2 id="runtime-config-cumulative-statistics">
+ <title>Cumulative Query and Index Statistics</title>
+
+ <para>
+ These parameters control the server-wide cumulative statistics system.
+ When enabled, the data that is collected can be accessed via the
+ <structname>pg_stat</structname> and <structname>pg_statio</structname>
+ family of system views. Refer to <xref linkend="monitoring"/> for more
+ information.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-track-activities" xreflabel="track_activities">
+ <term><varname>track_activities</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>track_activities</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables the collection of information on the currently
+ executing command of each session, along with its identifier and the
+ time when that command began execution. This parameter is on by
+ default. Note that even when enabled, this information is only
+ visible to superusers, roles with privileges of the
+ <literal>pg_read_all_stats</literal> role and the user owning the
+ sessions being reported on (including sessions belonging to a role they
+ have the privileges of), so it should not represent a security risk.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-track-activity-query-size" xreflabel="track_activity_query_size">
+ <term><varname>track_activity_query_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>track_activity_query_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the amount of memory reserved to store the text of the
+ currently executing command for each active session, for the
+ <structname>pg_stat_activity</structname>.<structfield>query</structfield> field.
+ If this value is specified without units, it is taken as bytes.
+ The default value is 1024 bytes.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-track-counts" xreflabel="track_counts">
+ <term><varname>track_counts</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>track_counts</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables collection of statistics on database activity.
+ This parameter is on by default, because the autovacuum
+ daemon needs the collected information.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-track-io-timing" xreflabel="track_io_timing">
+ <term><varname>track_io_timing</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>track_io_timing</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables timing of database I/O calls. This parameter is off by
+ default, as it will repeatedly query the operating system for
+ the current time, which may cause significant overhead on some
+ platforms. You can use the <xref linkend="pgtesttiming"/> tool to
+ measure the overhead of timing on your system.
+ I/O timing information is
+ displayed in <link linkend="monitoring-pg-stat-database-view">
+ <structname>pg_stat_database</structname></link>, in the output of
+ <xref linkend="sql-explain"/> when the <literal>BUFFERS</literal> option
+ is used, in the output of <xref linkend="sql-vacuum"/> when
+ the <literal>VERBOSE</literal> option is used, by autovacuum
+ for auto-vacuums and auto-analyzes, when <xref
+ linkend="guc-log-autovacuum-min-duration"/> is set and by
+ <xref linkend="pgstatstatements"/>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-track-wal-io-timing" xreflabel="track_wal_io_timing">
+ <term><varname>track_wal_io_timing</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>track_wal_io_timing</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables timing of WAL I/O calls. This parameter is off by default,
+ as it will repeatedly query the operating system for the current time,
+ which may cause significant overhead on some platforms.
+ You can use the <application>pg_test_timing</application> tool to
+ measure the overhead of timing on your system.
+ I/O timing information is
+ displayed in <link linkend="monitoring-pg-stat-wal-view">
+ <structname>pg_stat_wal</structname></link>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-track-functions" xreflabel="track_functions">
+ <term><varname>track_functions</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>track_functions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables tracking of function call counts and time used. Specify
+ <literal>pl</literal> to track only procedural-language functions,
+ <literal>all</literal> to also track SQL and C language functions.
+ The default is <literal>none</literal>, which disables function
+ statistics tracking.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <note>
+ <para>
+ SQL-language functions that are simple enough to be <quote>inlined</quote>
+ into the calling query will not be tracked, regardless of this
+ setting.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-stats-fetch-consistency" xreflabel="stats_fetch_consistency">
+ <term><varname>stats_fetch_consistency</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>stats_fetch_consistency</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines the behavior when cumulative statistics are accessed
+ multiple times within a transaction. When set to
+ <literal>none</literal>, each access re-fetches counters from shared
+ memory. When set to <literal>cache</literal>, the first access to
+ statistics for an object caches those statistics until the end of the
+ transaction unless <function>pg_stat_clear_snapshot()</function> is
+ called. When set to <literal>snapshot</literal>, the first statistics
+ access caches all statistics accessible in the current database, until
+ the end of the transaction unless
+ <function>pg_stat_clear_snapshot()</function> is called. Changing this
+ parameter in a transaction discards the statistics snapshot.
+ The default is <literal>cache</literal>.
+ </para>
+ <note>
+ <para>
+ <literal>none</literal> is most suitable for monitoring systems. If
+ values are only accessed once, it is the most
+ efficient. <literal>cache</literal> ensures repeat accesses yield the
+ same values, which is important for queries involving
+ e.g. self-joins. <literal>snapshot</literal> can be useful when
+ interactively inspecting statistics, but has higher overhead,
+ particularly if many database objects exist.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-statistics-monitor">
+ <title>Statistics Monitoring</title>
+ <variablelist>
+
+ <varlistentry id="guc-compute-query-id" xreflabel="compute_query_id">
+ <term><varname>compute_query_id</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>compute_query_id</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables in-core computation of a query identifier.
+ Query identifiers can be displayed in the <link
+ linkend="monitoring-pg-stat-activity-view"><structname>pg_stat_activity</structname></link>
+ view, using <command>EXPLAIN</command>, or emitted in the log if
+ configured via the <xref linkend="guc-log-line-prefix"/> parameter.
+ The <xref linkend="pgstatstatements"/> extension also requires a query
+ identifier to be computed. Note that an external module can
+ alternatively be used if the in-core query identifier computation
+ method is not acceptable. In this case, in-core computation
+ must be always disabled.
+ Valid values are <literal>off</literal> (always disabled),
+ <literal>on</literal> (always enabled), <literal>auto</literal>,
+ which lets modules such as <xref linkend="pgstatstatements"/>
+ automatically enable it, and <literal>regress</literal> which
+ has the same effect as <literal>auto</literal>, except that the
+ query identifier is not shown in the <literal>EXPLAIN</literal> output
+ in order to facilitate automated regression testing.
+ The default is <literal>auto</literal>.
+ </para>
+ <note>
+ <para>
+ To ensure that only one query identifier is calculated and
+ displayed, extensions that calculate query identifiers should
+ throw an error if a query identifier has already been computed.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>log_statement_stats</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_statement_stats</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <term><varname>log_parser_stats</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_parser_stats</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <term><varname>log_planner_stats</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_planner_stats</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <term><varname>log_executor_stats</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_executor_stats</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ For each query, output performance statistics of the respective
+ module to the server log. This is a crude profiling
+ instrument, similar to the Unix <function>getrusage()</function> operating
+ system facility. <varname>log_statement_stats</varname> reports total
+ statement statistics, while the others report per-module statistics.
+ <varname>log_statement_stats</varname> cannot be enabled together with
+ any of the per-module options. All of these options are disabled by
+ default.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change these settings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-autovacuum">
+ <title>Automatic Vacuuming</title>
+
+ <indexterm>
+ <primary>autovacuum</primary>
+ <secondary>configuration parameters</secondary>
+ </indexterm>
+
+ <para>
+ These settings control the behavior of the <firstterm>autovacuum</firstterm>
+ feature. Refer to <xref linkend="autovacuum"/> for more information.
+ Note that many of these settings can be overridden on a per-table
+ basis; see <xref linkend="sql-createtable-storage-parameters"/>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-autovacuum" xreflabel="autovacuum">
+ <term><varname>autovacuum</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>autovacuum</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls whether the server should run the
+ autovacuum launcher daemon. This is on by default; however,
+ <xref linkend="guc-track-counts"/> must also be enabled for
+ autovacuum to work.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line; however, autovacuuming can be
+ disabled for individual tables by changing table storage parameters.
+ </para>
+ <para>
+ Note that even when this parameter is disabled, the system
+ will launch autovacuum processes if necessary to
+ prevent transaction ID wraparound. See <xref
+ linkend="vacuum-for-wraparound"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-max-workers" xreflabel="autovacuum_max_workers">
+ <term><varname>autovacuum_max_workers</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_max_workers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum number of autovacuum processes (other than the
+ autovacuum launcher) that may be running at any one time. The default
+ is three. This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-naptime" xreflabel="autovacuum_naptime">
+ <term><varname>autovacuum_naptime</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_naptime</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the minimum delay between autovacuum runs on any given
+ database. In each round the daemon examines the
+ database and issues <command>VACUUM</command> and <command>ANALYZE</command> commands
+ as needed for tables in that database.
+ If this value is specified without units, it is taken as seconds.
+ The default is one minute (<literal>1min</literal>).
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold">
+ <term><varname>autovacuum_vacuum_threshold</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_threshold</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the minimum number of updated or deleted tuples needed
+ to trigger a <command>VACUUM</command> in any one table.
+ The default is 50 tuples.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold">
+ <term><varname>autovacuum_vacuum_insert_threshold</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the number of inserted tuples needed to trigger a
+ <command>VACUUM</command> in any one table.
+ The default is 1000 tuples. If -1 is specified, autovacuum will not
+ trigger a <command>VACUUM</command> operation on any tables based on
+ the number of inserts.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-analyze-threshold" xreflabel="autovacuum_analyze_threshold">
+ <term><varname>autovacuum_analyze_threshold</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_analyze_threshold</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the minimum number of inserted, updated or deleted tuples
+ needed to trigger an <command>ANALYZE</command> in any one table.
+ The default is 50 tuples.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor">
+ <term><varname>autovacuum_vacuum_scale_factor</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_scale_factor</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a fraction of the table size to add to
+ <varname>autovacuum_vacuum_threshold</varname>
+ when deciding whether to trigger a <command>VACUUM</command>.
+ The default is 0.2 (20% of table size).
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor">
+ <term><varname>autovacuum_vacuum_insert_scale_factor</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_insert_scale_factor</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a fraction of the table size to add to
+ <varname>autovacuum_vacuum_insert_threshold</varname>
+ when deciding whether to trigger a <command>VACUUM</command>.
+ The default is 0.2 (20% of table size).
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-analyze-scale-factor" xreflabel="autovacuum_analyze_scale_factor">
+ <term><varname>autovacuum_analyze_scale_factor</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_analyze_scale_factor</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a fraction of the table size to add to
+ <varname>autovacuum_analyze_threshold</varname>
+ when deciding whether to trigger an <command>ANALYZE</command>.
+ The default is 0.1 (10% of table size).
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age">
+ <term><varname>autovacuum_freeze_max_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_freeze_max_age</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum age (in transactions) that a table's
+ <structname>pg_class</structname>.<structfield>relfrozenxid</structfield> field can
+ attain before a <command>VACUUM</command> operation is forced
+ to prevent transaction ID wraparound within the table.
+ Note that the system will launch autovacuum processes to
+ prevent wraparound even when autovacuum is otherwise disabled.
+ </para>
+
+ <para>
+ Vacuum also allows removal of old files from the
+ <filename>pg_xact</filename> subdirectory, which is why the default
+ is a relatively low 200 million transactions.
+ This parameter can only be set at server start, but the setting
+ can be reduced for individual tables by
+ changing table storage parameters.
+ For more information see <xref linkend="vacuum-for-wraparound"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age">
+ <term><varname>autovacuum_multixact_freeze_max_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum age (in multixacts) that a table's
+ <structname>pg_class</structname>.<structfield>relminmxid</structfield> field can
+ attain before a <command>VACUUM</command> operation is forced to
+ prevent multixact ID wraparound within the table.
+ Note that the system will launch autovacuum processes to
+ prevent wraparound even when autovacuum is otherwise disabled.
+ </para>
+
+ <para>
+ Vacuuming multixacts also allows removal of old files from the
+ <filename>pg_multixact/members</filename> and <filename>pg_multixact/offsets</filename>
+ subdirectories, which is why the default is a relatively low
+ 400 million multixacts.
+ This parameter can only be set at server start, but the setting can
+ be reduced for individual tables by changing table storage parameters.
+ For more information see <xref linkend="vacuum-for-multixact-wraparound"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay">
+ <term><varname>autovacuum_vacuum_cost_delay</varname> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_cost_delay</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the cost delay value that will be used in automatic
+ <command>VACUUM</command> operations. If -1 is specified, the regular
+ <xref linkend="guc-vacuum-cost-delay"/> value will be used.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 2 milliseconds.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit">
+ <term><varname>autovacuum_vacuum_cost_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_cost_limit</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the cost limit value that will be used in automatic
+ <command>VACUUM</command> operations. If -1 is specified (which is the
+ default), the regular
+ <xref linkend="guc-vacuum-cost-limit"/> value will be used. Note that
+ the value is distributed proportionally among the running autovacuum
+ workers, if there is more than one, so that the sum of the limits for
+ each worker does not exceed the value of this variable.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+
+ <sect1 id="runtime-config-client">
+ <title>Client Connection Defaults</title>
+
+ <sect2 id="runtime-config-client-statement">
+ <title>Statement Behavior</title>
+ <variablelist>
+
+ <varlistentry id="guc-client-min-messages" xreflabel="client_min_messages">
+ <term><varname>client_min_messages</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>client_min_messages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls which
+ <link linkend="runtime-config-severity-levels">message levels</link>
+ are sent to the client.
+ Valid values are <literal>DEBUG5</literal>,
+ <literal>DEBUG4</literal>, <literal>DEBUG3</literal>, <literal>DEBUG2</literal>,
+ <literal>DEBUG1</literal>, <literal>LOG</literal>, <literal>NOTICE</literal>,
+ <literal>WARNING</literal>, and <literal>ERROR</literal>.
+ Each level includes all the levels that follow it. The later the level,
+ the fewer messages are sent. The default is
+ <literal>NOTICE</literal>. Note that <literal>LOG</literal> has a different
+ rank here than in <xref linkend="guc-log-min-messages"/>.
+ </para>
+ <para>
+ <literal>INFO</literal> level messages are always sent to the client.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-search-path" xreflabel="search_path">
+ <term><varname>search_path</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>search_path</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>path</primary><secondary>for schemas</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable specifies the order in which schemas are searched
+ when an object (table, data type, function, etc.) is referenced by a
+ simple name with no schema specified. When there are objects of
+ identical names in different schemas, the one found first
+ in the search path is used. An object that is not in any of the
+ schemas in the search path can only be referenced by specifying
+ its containing schema with a qualified (dotted) name.
+ </para>
+
+ <para>
+ The value for <varname>search_path</varname> must be a comma-separated
+ list of schema names. Any name that is not an existing schema, or is
+ a schema for which the user does not have <literal>USAGE</literal>
+ permission, is silently ignored.
+ </para>
+
+ <para>
+ If one of the list items is the special name
+ <literal>$user</literal>, then the schema having the name returned by
+ <function>CURRENT_USER</function> is substituted, if there is such a schema
+ and the user has <literal>USAGE</literal> permission for it.
+ (If not, <literal>$user</literal> is ignored.)
+ </para>
+
+ <para>
+ The system catalog schema, <literal>pg_catalog</literal>, is always
+ searched, whether it is mentioned in the path or not. If it is
+ mentioned in the path then it will be searched in the specified
+ order. If <literal>pg_catalog</literal> is not in the path then it will
+ be searched <emphasis>before</emphasis> searching any of the path items.
+ </para>
+
+ <!-- To further split hairs, funcname('foo') does not use the temporary
+ schema, even when it considers typname='funcname'. This paragraph
+ refers to function names in a loose sense, "pg_proc.proname or
+ func_name grammar production". -->
+ <para>
+ Likewise, the current session's temporary-table schema,
+ <literal>pg_temp_<replaceable>nnn</replaceable></literal>, is always searched if it
+ exists. It can be explicitly listed in the path by using the
+ alias <literal>pg_temp</literal><indexterm><primary>pg_temp</primary></indexterm>. If it is not listed in the path then
+ it is searched first (even before <literal>pg_catalog</literal>). However,
+ the temporary schema is only searched for relation (table, view,
+ sequence, etc.) and data type names. It is never searched for
+ function or operator names.
+ </para>
+
+ <para>
+ When objects are created without specifying a particular target
+ schema, they will be placed in the first valid schema named in
+ <varname>search_path</varname>. An error is reported if the search
+ path is empty.
+ </para>
+
+ <para>
+ The default value for this parameter is
+ <literal>"$user", public</literal>.
+ This setting supports shared use of a database (where no users
+ have private schemas, and all share use of <literal>public</literal>),
+ private per-user schemas, and combinations of these. Other
+ effects can be obtained by altering the default search path
+ setting, either globally or per-user.
+ </para>
+
+ <para>
+ For more information on schema handling, see
+ <xref linkend="ddl-schemas"/>. In particular, the default
+ configuration is suitable only when the database has a single user or
+ a few mutually-trusting users.
+ </para>
+
+ <para>
+ The current effective value of the search path can be examined
+ via the <acronym>SQL</acronym> function
+ <function>current_schemas</function>
+ (see <xref linkend="functions-info"/>).
+ This is not quite the same as
+ examining the value of <varname>search_path</varname>, since
+ <function>current_schemas</function> shows how the items
+ appearing in <varname>search_path</varname> were resolved.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-row-security" xreflabel="row_security">
+ <term><varname>row_security</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>row_security</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable controls whether to raise an error in lieu of applying a
+ row security policy. When set to <literal>on</literal>, policies apply
+ normally. When set to <literal>off</literal>, queries fail which would
+ otherwise apply at least one policy. The default is <literal>on</literal>.
+ Change to <literal>off</literal> where limited row visibility could cause
+ incorrect results; for example, <application>pg_dump</application> makes that
+ change by default. This variable has no effect on roles which bypass
+ every row security policy, to wit, superusers and roles with
+ the <literal>BYPASSRLS</literal> attribute.
+ </para>
+
+ <para>
+ For more information on row security policies,
+ see <xref linkend="sql-createpolicy"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-table-access-method" xreflabel="default_table_access_method">
+ <term><varname>default_table_access_method</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>default_table_access_method</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter specifies the default table access method to use when
+ creating tables or materialized views if the <command>CREATE</command>
+ command does not explicitly specify an access method, or when
+ <command>SELECT ... INTO</command> is used, which does not allow
+ specifying a table access method. The default is <literal>heap</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-tablespace" xreflabel="default_tablespace">
+ <term><varname>default_tablespace</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>default_tablespace</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>tablespace</primary><secondary>default</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable specifies the default tablespace in which to create
+ objects (tables and indexes) when a <command>CREATE</command> command does
+ not explicitly specify a tablespace.
+ </para>
+
+ <para>
+ The value is either the name of a tablespace, or an empty string
+ to specify using the default tablespace of the current database.
+ If the value does not match the name of any existing tablespace,
+ <productname>PostgreSQL</productname> will automatically use the default
+ tablespace of the current database. If a nondefault tablespace
+ is specified, the user must have <literal>CREATE</literal> privilege
+ for it, or creation attempts will fail.
+ </para>
+
+ <para>
+ This variable is not used for temporary tables; for them,
+ <xref linkend="guc-temp-tablespaces"/> is consulted instead.
+ </para>
+
+ <para>
+ This variable is also not used when creating databases.
+ By default, a new database inherits its tablespace setting from
+ the template database it is copied from.
+ </para>
+
+ <para>
+ If this parameter is set to a value other than the empty string
+ when a partitioned table is created, the partitioned table's
+ tablespace will be set to that value, which will be used as
+ the default tablespace for partitions created in the future,
+ even if <varname>default_tablespace</varname> has changed since then.
+ </para>
+
+ <para>
+ For more information on tablespaces,
+ see <xref linkend="manage-ag-tablespaces"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-toast-compression" xreflabel="default_toast_compression">
+ <term><varname>default_toast_compression</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>default_toast_compression</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable sets the default
+ <link linkend="storage-toast">TOAST</link>
+ compression method for values of compressible columns.
+ (This can be overridden for individual columns by setting
+ the <literal>COMPRESSION</literal> column option in
+ <command>CREATE TABLE</command> or
+ <command>ALTER TABLE</command>.)
+ The supported compression methods are <literal>pglz</literal> and
+ (if <productname>PostgreSQL</productname> was compiled with
+ <option>--with-lz4</option>) <literal>lz4</literal>.
+ The default is <literal>pglz</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-temp-tablespaces" xreflabel="temp_tablespaces">
+ <term><varname>temp_tablespaces</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>temp_tablespaces</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>tablespace</primary><secondary>temporary</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable specifies tablespaces in which to create temporary
+ objects (temp tables and indexes on temp tables) when a
+ <command>CREATE</command> command does not explicitly specify a tablespace.
+ Temporary files for purposes such as sorting large data sets
+ are also created in these tablespaces.
+ </para>
+
+ <para>
+ The value is a list of names of tablespaces. When there is more than
+ one name in the list, <productname>PostgreSQL</productname> chooses a random
+ member of the list each time a temporary object is to be created;
+ except that within a transaction, successively created temporary
+ objects are placed in successive tablespaces from the list.
+ If the selected element of the list is an empty string,
+ <productname>PostgreSQL</productname> will automatically use the default
+ tablespace of the current database instead.
+ </para>
+
+ <para>
+ When <varname>temp_tablespaces</varname> is set interactively, specifying a
+ nonexistent tablespace is an error, as is specifying a tablespace for
+ which the user does not have <literal>CREATE</literal> privilege. However,
+ when using a previously set value, nonexistent tablespaces are
+ ignored, as are tablespaces for which the user lacks
+ <literal>CREATE</literal> privilege. In particular, this rule applies when
+ using a value set in <filename>postgresql.conf</filename>.
+ </para>
+
+ <para>
+ The default value is an empty string, which results in all temporary
+ objects being created in the default tablespace of the current
+ database.
+ </para>
+
+ <para>
+ See also <xref linkend="guc-default-tablespace"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-check-function-bodies" xreflabel="check_function_bodies">
+ <term><varname>check_function_bodies</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>check_function_bodies</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter is normally on. When set to <literal>off</literal>, it
+ disables validation of the routine body string during <xref
+ linkend="sql-createfunction"/> and <xref
+ linkend="sql-createprocedure"/>. Disabling validation avoids side
+ effects of the validation process, in particular preventing false
+ positives due to problems such as forward references.
+ Set this parameter
+ to <literal>off</literal> before loading functions on behalf of other
+ users; <application>pg_dump</application> does so automatically.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-transaction-isolation" xreflabel="default_transaction_isolation">
+ <term><varname>default_transaction_isolation</varname> (<type>enum</type>)
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ <secondary>setting default</secondary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>default_transaction_isolation</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Each SQL transaction has an isolation level, which can be
+ either <quote>read uncommitted</quote>, <quote>read
+ committed</quote>, <quote>repeatable read</quote>, or
+ <quote>serializable</quote>. This parameter controls the
+ default isolation level of each new transaction. The default
+ is <quote>read committed</quote>.
+ </para>
+
+ <para>
+ Consult <xref linkend="mvcc"/> and <xref
+ linkend="sql-set-transaction"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-transaction-read-only" xreflabel="default_transaction_read_only">
+ <term><varname>default_transaction_read_only</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>read-only transaction</primary>
+ <secondary>setting default</secondary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>default_transaction_read_only</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ A read-only SQL transaction cannot alter non-temporary tables.
+ This parameter controls the default read-only status of each new
+ transaction. The default is <literal>off</literal> (read/write).
+ </para>
+
+ <para>
+ Consult <xref linkend="sql-set-transaction"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-transaction-deferrable" xreflabel="default_transaction_deferrable">
+ <term><varname>default_transaction_deferrable</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>deferrable transaction</primary>
+ <secondary>setting default</secondary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>default_transaction_deferrable</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When running at the <literal>serializable</literal> isolation level,
+ a deferrable read-only SQL transaction may be delayed before
+ it is allowed to proceed. However, once it begins executing
+ it does not incur any of the overhead required to ensure
+ serializability; so serialization code will have no reason to
+ force it to abort because of concurrent updates, making this
+ option suitable for long-running read-only transactions.
+ </para>
+
+ <para>
+ This parameter controls the default deferrable status of each
+ new transaction. It currently has no effect on read-write
+ transactions or those operating at isolation levels lower
+ than <literal>serializable</literal>. The default is <literal>off</literal>.
+ </para>
+
+ <para>
+ Consult <xref linkend="sql-set-transaction"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-transaction-isolation" xreflabel="transaction_isolation">
+ <term><varname>transaction_isolation</varname> (<type>enum</type>)
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>transaction_isolation</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter reflects the current transaction's isolation level.
+ At the beginning of each transaction, it is set to the current value
+ of <xref linkend="guc-default-transaction-isolation"/>.
+ Any subsequent attempt to change it is equivalent to a <xref
+ linkend="sql-set-transaction"/> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-transaction-read-only" xreflabel="transaction_read_only">
+ <term><varname>transaction_read_only</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>read-only transaction</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>transaction_read_only</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter reflects the current transaction's read-only status.
+ At the beginning of each transaction, it is set to the current value
+ of <xref linkend="guc-default-transaction-read-only"/>.
+ Any subsequent attempt to change it is equivalent to a <xref
+ linkend="sql-set-transaction"/> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-transaction-deferrable" xreflabel="transaction_deferrable">
+ <term><varname>transaction_deferrable</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary>deferrable transaction</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>transaction_deferrable</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter reflects the current transaction's deferrability status.
+ At the beginning of each transaction, it is set to the current value
+ of <xref linkend="guc-default-transaction-deferrable"/>.
+ Any subsequent attempt to change it is equivalent to a <xref
+ linkend="sql-set-transaction"/> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="guc-session-replication-role" xreflabel="session_replication_role">
+ <term><varname>session_replication_role</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>session_replication_role</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls firing of replication-related triggers and rules for the
+ current session.
+ Possible values are <literal>origin</literal> (the default),
+ <literal>replica</literal> and <literal>local</literal>.
+ Setting this parameter results in discarding any previously cached
+ query plans.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ The intended use of this setting is that logical replication systems
+ set it to <literal>replica</literal> when they are applying replicated
+ changes. The effect of that will be that triggers and rules (that
+ have not been altered from their default configuration) will not fire
+ on the replica. See the <link linkend="sql-altertable"><command>ALTER TABLE</command></link> clauses
+ <literal>ENABLE TRIGGER</literal> and <literal>ENABLE RULE</literal>
+ for more information.
+ </para>
+
+ <para>
+ PostgreSQL treats the settings <literal>origin</literal> and
+ <literal>local</literal> the same internally. Third-party replication
+ systems may use these two values for their internal purposes, for
+ example using <literal>local</literal> to designate a session whose
+ changes should not be replicated.
+ </para>
+
+ <para>
+ Since foreign keys are implemented as triggers, setting this parameter
+ to <literal>replica</literal> also disables all foreign key checks,
+ which can leave data in an inconsistent state if improperly used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-statement-timeout" xreflabel="statement_timeout">
+ <term><varname>statement_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>statement_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Abort any statement that takes more than the specified amount of time.
+ If <varname>log_min_error_statement</varname> is set
+ to <literal>ERROR</literal> or lower, the statement that timed out
+ will also be logged.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </para>
+
+ <para>
+ The timeout is measured from the time a command arrives at the
+ server until it is completed by the server. If multiple SQL
+ statements appear in a single simple-Query message, the timeout
+ is applied to each statement separately.
+ (<productname>PostgreSQL</productname> versions before 13 usually
+ treated the timeout as applying to the whole query string.)
+ In extended query protocol, the timeout starts running when any
+ query-related message (Parse, Bind, Execute, Describe) arrives, and
+ it is canceled by completion of an Execute or Sync message.
+ </para>
+
+ <para>
+ Setting <varname>statement_timeout</varname> in
+ <filename>postgresql.conf</filename> is not recommended because it would
+ affect all sessions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lock-timeout" xreflabel="lock_timeout">
+ <term><varname>lock_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>lock_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Abort any statement that waits longer than the specified amount of
+ time while attempting to acquire a lock on a table, index,
+ row, or other database object. The time limit applies separately to
+ each lock acquisition attempt. The limit applies both to explicit
+ locking requests (such as <command>LOCK TABLE</command>, or <command>SELECT
+ FOR UPDATE</command> without <literal>NOWAIT</literal>) and to implicitly-acquired
+ locks.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </para>
+
+ <para>
+ Unlike <varname>statement_timeout</varname>, this timeout can only occur
+ while waiting for locks. Note that if <varname>statement_timeout</varname>
+ is nonzero, it is rather pointless to set <varname>lock_timeout</varname> to
+ the same or larger value, since the statement timeout would always
+ trigger first. If <varname>log_min_error_statement</varname> is set to
+ <literal>ERROR</literal> or lower, the statement that timed out will be
+ logged.
+ </para>
+
+ <para>
+ Setting <varname>lock_timeout</varname> in
+ <filename>postgresql.conf</filename> is not recommended because it would
+ affect all sessions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-idle-in-transaction-session-timeout" xreflabel="idle_in_transaction_session_timeout">
+ <term><varname>idle_in_transaction_session_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>idle_in_transaction_session_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Terminate any session that has been idle (that is, waiting for a
+ client query) within an open transaction for longer than the
+ specified amount of time.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </para>
+
+ <para>
+ This option can be used to ensure that idle sessions do not hold
+ locks for an unreasonable amount of time. Even when no significant
+ locks are held, an open transaction prevents vacuuming away
+ recently-dead tuples that may be visible only to this transaction;
+ so remaining idle for a long time can contribute to table bloat.
+ See <xref linkend="routine-vacuuming"/> for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-idle-session-timeout" xreflabel="idle_session_timeout">
+ <term><varname>idle_session_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>idle_session_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Terminate any session that has been idle (that is, waiting for a
+ client query), but not within an open transaction, for longer than
+ the specified amount of time.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </para>
+
+ <para>
+ Unlike the case with an open transaction, an idle session without a
+ transaction imposes no large costs on the server, so there is less
+ need to enable this timeout
+ than <varname>idle_in_transaction_session_timeout</varname>.
+ </para>
+
+ <para>
+ Be wary of enforcing this timeout on connections made through
+ connection-pooling software or other middleware, as such a layer
+ may not react well to unexpected connection closure. It may be
+ helpful to enable this timeout only for interactive sessions,
+ perhaps by applying it only to particular users.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-freeze-table-age" xreflabel="vacuum_freeze_table_age">
+ <term><varname>vacuum_freeze_table_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_freeze_table_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <command>VACUUM</command> performs an aggressive scan if the table's
+ <structname>pg_class</structname>.<structfield>relfrozenxid</structfield> field has reached
+ the age specified by this setting. An aggressive scan differs from
+ a regular <command>VACUUM</command> in that it visits every page that might
+ contain unfrozen XIDs or MXIDs, not just those that might contain dead
+ tuples. The default is 150 million transactions. Although users can
+ set this value anywhere from zero to two billion, <command>VACUUM</command>
+ will silently limit the effective value to 95% of
+ <xref linkend="guc-autovacuum-freeze-max-age"/>, so that a
+ periodic manual <command>VACUUM</command> has a chance to run before an
+ anti-wraparound autovacuum is launched for the table. For more
+ information see
+ <xref linkend="vacuum-for-wraparound"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-freeze-min-age" xreflabel="vacuum_freeze_min_age">
+ <term><varname>vacuum_freeze_min_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_freeze_min_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the cutoff age (in transactions) that <command>VACUUM</command>
+ should use to decide whether to freeze row versions
+ while scanning a table.
+ The default is 50 million transactions. Although
+ users can set this value anywhere from zero to one billion,
+ <command>VACUUM</command> will silently limit the effective value to half
+ the value of <xref linkend="guc-autovacuum-freeze-max-age"/>, so
+ that there is not an unreasonably short time between forced
+ autovacuums. For more information see <xref
+ linkend="vacuum-for-wraparound"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-failsafe-age" xreflabel="vacuum_failsafe_age">
+ <term><varname>vacuum_failsafe_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_failsafe_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum age (in transactions) that a table's
+ <structname>pg_class</structname>.<structfield>relfrozenxid</structfield>
+ field can attain before <command>VACUUM</command> takes
+ extraordinary measures to avoid system-wide transaction ID
+ wraparound failure. This is <command>VACUUM</command>'s
+ strategy of last resort. The failsafe typically triggers
+ when an autovacuum to prevent transaction ID wraparound has
+ already been running for some time, though it's possible for
+ the failsafe to trigger during any <command>VACUUM</command>.
+ </para>
+ <para>
+ When the failsafe is triggered, any cost-based delay that is
+ in effect will no longer be applied, and further non-essential
+ maintenance tasks (such as index vacuuming) are bypassed.
+ </para>
+ <para>
+ The default is 1.6 billion transactions. Although users can
+ set this value anywhere from zero to 2.1 billion,
+ <command>VACUUM</command> will silently adjust the effective
+ value to no less than 105% of <xref
+ linkend="guc-autovacuum-freeze-max-age"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-multixact-freeze-table-age" xreflabel="vacuum_multixact_freeze_table_age">
+ <term><varname>vacuum_multixact_freeze_table_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_multixact_freeze_table_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <command>VACUUM</command> performs an aggressive scan if the table's
+ <structname>pg_class</structname>.<structfield>relminmxid</structfield> field has reached
+ the age specified by this setting. An aggressive scan differs from
+ a regular <command>VACUUM</command> in that it visits every page that might
+ contain unfrozen XIDs or MXIDs, not just those that might contain dead
+ tuples. The default is 150 million multixacts.
+ Although users can set this value anywhere from zero to two billion,
+ <command>VACUUM</command> will silently limit the effective value to 95% of
+ <xref linkend="guc-autovacuum-multixact-freeze-max-age"/>, so that a
+ periodic manual <command>VACUUM</command> has a chance to run before an
+ anti-wraparound is launched for the table.
+ For more information see <xref linkend="vacuum-for-multixact-wraparound"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-multixact-freeze-min-age" xreflabel="vacuum_multixact_freeze_min_age">
+ <term><varname>vacuum_multixact_freeze_min_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_multixact_freeze_min_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the cutoff age (in multixacts) that <command>VACUUM</command>
+ should use to decide whether to replace multixact IDs with a newer
+ transaction ID or multixact ID while scanning a table. The default
+ is 5 million multixacts.
+ Although users can set this value anywhere from zero to one billion,
+ <command>VACUUM</command> will silently limit the effective value to half
+ the value of <xref linkend="guc-autovacuum-multixact-freeze-max-age"/>,
+ so that there is not an unreasonably short time between forced
+ autovacuums.
+ For more information see <xref linkend="vacuum-for-multixact-wraparound"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-vacuum-multixact-failsafe-age" xreflabel="vacuum_multixact_failsafe_age">
+ <term><varname>vacuum_multixact_failsafe_age</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>vacuum_multixact_failsafe_age</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies the maximum age (in multixacts) that a table's
+ <structname>pg_class</structname>.<structfield>relminmxid</structfield>
+ field can attain before <command>VACUUM</command> takes
+ extraordinary measures to avoid system-wide multixact ID
+ wraparound failure. This is <command>VACUUM</command>'s
+ strategy of last resort. The failsafe typically triggers when
+ an autovacuum to prevent transaction ID wraparound has already
+ been running for some time, though it's possible for the
+ failsafe to trigger during any <command>VACUUM</command>.
+ </para>
+ <para>
+ When the failsafe is triggered, any cost-based delay that is
+ in effect will no longer be applied, and further non-essential
+ maintenance tasks (such as index vacuuming) are bypassed.
+ </para>
+ <para>
+ The default is 1.6 billion multixacts. Although users can set
+ this value anywhere from zero to 2.1 billion,
+ <command>VACUUM</command> will silently adjust the effective
+ value to no less than 105% of <xref
+ linkend="guc-autovacuum-multixact-freeze-max-age"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-bytea-output" xreflabel="bytea_output">
+ <term><varname>bytea_output</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>bytea_output</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the output format for values of type <type>bytea</type>.
+ Valid values are <literal>hex</literal> (the default)
+ and <literal>escape</literal> (the traditional PostgreSQL
+ format). See <xref linkend="datatype-binary"/> for more
+ information. The <type>bytea</type> type always
+ accepts both formats on input, regardless of this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-xmlbinary" xreflabel="xmlbinary">
+ <term><varname>xmlbinary</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>xmlbinary</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets how binary values are to be encoded in XML. This applies
+ for example when <type>bytea</type> values are converted to
+ XML by the functions <function>xmlelement</function> or
+ <function>xmlforest</function>. Possible values are
+ <literal>base64</literal> and <literal>hex</literal>, which
+ are both defined in the XML Schema standard. The default is
+ <literal>base64</literal>. For further information about
+ XML-related functions, see <xref linkend="functions-xml"/>.
+ </para>
+
+ <para>
+ The actual choice here is mostly a matter of taste,
+ constrained only by possible restrictions in client
+ applications. Both methods support all possible values,
+ although the hex encoding will be somewhat larger than the
+ base64 encoding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-xmloption" xreflabel="xmloption">
+ <term><varname>xmloption</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>xmloption</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>SET XML OPTION</varname></primary>
+ </indexterm>
+ <indexterm>
+ <primary>XML option</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets whether <literal>DOCUMENT</literal> or
+ <literal>CONTENT</literal> is implicit when converting between
+ XML and character string values. See <xref
+ linkend="datatype-xml"/> for a description of this. Valid
+ values are <literal>DOCUMENT</literal> and
+ <literal>CONTENT</literal>. The default is
+ <literal>CONTENT</literal>.
+ </para>
+
+ <para>
+ According to the SQL standard, the command to set this option is
+<synopsis>
+SET XML OPTION { DOCUMENT | CONTENT };
+</synopsis>
+ This syntax is also available in PostgreSQL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-gin-pending-list-limit" xreflabel="gin_pending_list_limit">
+ <term><varname>gin_pending_list_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>gin_pending_list_limit</varname></primary>
+ <secondary>configuration parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the maximum size of a GIN index's pending list, which is used
+ when <literal>fastupdate</literal> is enabled. If the list grows
+ larger than this maximum size, it is cleaned up by moving
+ the entries in it to the index's main GIN data structure in bulk.
+ If this value is specified without units, it is taken as kilobytes.
+ The default is four megabytes (<literal>4MB</literal>). This setting
+ can be overridden for individual GIN indexes by changing
+ index storage parameters.
+ See <xref linkend="gin-fast-update"/> and <xref linkend="gin-tips"/>
+ for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ <sect2 id="runtime-config-client-format">
+ <title>Locale and Formatting</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-datestyle" xreflabel="DateStyle">
+ <term><varname>DateStyle</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>DateStyle</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the display format for date and time values, as well as the
+ rules for interpreting ambiguous date input values. For
+ historical reasons, this variable contains two independent
+ components: the output format specification (<literal>ISO</literal>,
+ <literal>Postgres</literal>, <literal>SQL</literal>, or <literal>German</literal>)
+ and the input/output specification for year/month/day ordering
+ (<literal>DMY</literal>, <literal>MDY</literal>, or <literal>YMD</literal>). These
+ can be set separately or together. The keywords <literal>Euro</literal>
+ and <literal>European</literal> are synonyms for <literal>DMY</literal>; the
+ keywords <literal>US</literal>, <literal>NonEuro</literal>, and
+ <literal>NonEuropean</literal> are synonyms for <literal>MDY</literal>. See
+ <xref linkend="datatype-datetime"/> for more information. The
+ built-in default is <literal>ISO, MDY</literal>, but
+ <application>initdb</application> will initialize the
+ configuration file with a setting that corresponds to the
+ behavior of the chosen <varname>lc_time</varname> locale.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-intervalstyle" xreflabel="IntervalStyle">
+ <term><varname>IntervalStyle</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>IntervalStyle</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the display format for interval values.
+ The value <literal>sql_standard</literal> will produce
+ output matching <acronym>SQL</acronym> standard interval literals.
+ The value <literal>postgres</literal> (which is the default) will produce
+ output matching <productname>PostgreSQL</productname> releases prior to 8.4
+ when the <xref linkend="guc-datestyle"/>
+ parameter was set to <literal>ISO</literal>.
+ The value <literal>postgres_verbose</literal> will produce output
+ matching <productname>PostgreSQL</productname> releases prior to 8.4
+ when the <varname>DateStyle</varname>
+ parameter was set to non-<literal>ISO</literal> output.
+ The value <literal>iso_8601</literal> will produce output matching the time
+ interval <quote>format with designators</quote> defined in section
+ 4.4.3.2 of ISO 8601.
+ </para>
+ <para>
+ The <varname>IntervalStyle</varname> parameter also affects the
+ interpretation of ambiguous interval input. See
+ <xref linkend="datatype-interval-input"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-timezone" xreflabel="TimeZone">
+ <term><varname>TimeZone</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>TimeZone</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>time zone</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the time zone for displaying and interpreting time stamps.
+ The built-in default is <literal>GMT</literal>, but that is typically
+ overridden in <filename>postgresql.conf</filename>; <application>initdb</application>
+ will install a setting there corresponding to its system environment.
+ See <xref linkend="datatype-timezones"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-timezone-abbreviations" xreflabel="timezone_abbreviations">
+ <term><varname>timezone_abbreviations</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>timezone_abbreviations</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>time zone names</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the collection of time zone abbreviations that will be accepted
+ by the server for datetime input. The default is <literal>'Default'</literal>,
+ which is a collection that works in most of the world; there are
+ also <literal>'Australia'</literal> and <literal>'India'</literal>,
+ and other collections can be defined for a particular installation.
+ See <xref linkend="datetime-config-files"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-extra-float-digits" xreflabel="extra_float_digits">
+ <term><varname>extra_float_digits</varname> (<type>integer</type>)
+ <indexterm>
+ <primary>significant digits</primary>
+ </indexterm>
+ <indexterm>
+ <primary>floating-point</primary>
+ <secondary>display</secondary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>extra_float_digits</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter adjusts the number of digits used for textual output of
+ floating-point values, including <type>float4</type>, <type>float8</type>,
+ and geometric data types.
+ </para>
+ <para>
+ If the value is 1 (the default) or above, float values are output in
+ shortest-precise format; see <xref linkend="datatype-float"/>. The
+ actual number of digits generated depends only on the value being
+ output, not on the value of this parameter. At most 17 digits are
+ required for <type>float8</type> values, and 9 for <type>float4</type>
+ values. This format is both fast and precise, preserving the original
+ binary float value exactly when correctly read. For historical
+ compatibility, values up to 3 are permitted.
+ </para>
+ <para>
+ If the value is zero or negative, then the output is rounded to a
+ given decimal precision. The precision used is the standard number of
+ digits for the type (<literal>FLT_DIG</literal>
+ or <literal>DBL_DIG</literal> as appropriate) reduced according to the
+ value of this parameter. (For example, specifying -1 will cause
+ <type>float4</type> values to be output rounded to 5 significant
+ digits, and <type>float8</type> values
+ rounded to 14 digits.) This format is slower and does not preserve all
+ the bits of the binary float value, but may be more human-readable.
+ </para>
+ <note>
+ <para>
+ The meaning of this parameter, and its default value, changed
+ in <productname>PostgreSQL</productname> 12;
+ see <xref linkend="datatype-float"/> for further discussion.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-client-encoding" xreflabel="client_encoding">
+ <term><varname>client_encoding</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>client_encoding</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>character set</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the client-side encoding (character set).
+ The default is to use the database encoding.
+ The character sets supported by the <productname>PostgreSQL</productname>
+ server are described in <xref linkend="multibyte-charset-supported"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lc-messages" xreflabel="lc_messages">
+ <term><varname>lc_messages</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>lc_messages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the language in which messages are displayed. Acceptable
+ values are system-dependent; see <xref linkend="locale"/> for
+ more information. If this variable is set to the empty string
+ (which is the default) then the value is inherited from the
+ execution environment of the server in a system-dependent way.
+ </para>
+
+ <para>
+ On some systems, this locale category does not exist. Setting
+ this variable will still work, but there will be no effect.
+ Also, there is a chance that no translated messages for the
+ desired language exist. In that case you will continue to see
+ the English messages.
+ </para>
+
+ <para>
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lc-monetary" xreflabel="lc_monetary">
+ <term><varname>lc_monetary</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>lc_monetary</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the locale to use for formatting monetary amounts, for
+ example with the <function>to_char</function> family of
+ functions. Acceptable values are system-dependent; see <xref
+ linkend="locale"/> for more information. If this variable is
+ set to the empty string (which is the default) then the value
+ is inherited from the execution environment of the server in a
+ system-dependent way.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lc-numeric" xreflabel="lc_numeric">
+ <term><varname>lc_numeric</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>lc_numeric</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the locale to use for formatting numbers, for example
+ with the <function>to_char</function> family of
+ functions. Acceptable values are system-dependent; see <xref
+ linkend="locale"/> for more information. If this variable is
+ set to the empty string (which is the default) then the value
+ is inherited from the execution environment of the server in a
+ system-dependent way.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lc-time" xreflabel="lc_time">
+ <term><varname>lc_time</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>lc_time</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the locale to use for formatting dates and times, for example
+ with the <function>to_char</function> family of
+ functions. Acceptable values are system-dependent; see <xref
+ linkend="locale"/> for more information. If this variable is
+ set to the empty string (which is the default) then the value
+ is inherited from the execution environment of the server in a
+ system-dependent way.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-default-text-search-config" xreflabel="default_text_search_config">
+ <term><varname>default_text_search_config</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>default_text_search_config</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Selects the text search configuration that is used by those variants
+ of the text search functions that do not have an explicit argument
+ specifying the configuration.
+ See <xref linkend="textsearch"/> for further information.
+ The built-in default is <literal>pg_catalog.simple</literal>, but
+ <application>initdb</application> will initialize the
+ configuration file with a setting that corresponds to the
+ chosen <varname>lc_ctype</varname> locale, if a configuration
+ matching that locale can be identified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="runtime-config-client-preload">
+ <title>Shared Library Preloading</title>
+
+ <para>
+ Several settings are available for preloading shared libraries into the
+ server, in order to load additional functionality or achieve performance
+ benefits. For example, a setting of
+ <literal>'$libdir/mylib'</literal> would cause
+ <literal>mylib.so</literal> (or on some platforms,
+ <literal>mylib.sl</literal>) to be preloaded from the installation's standard
+ library directory. The differences between the settings are when they
+ take effect and what privileges are required to change them.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> procedural language libraries can
+ be preloaded in this way, typically by using the
+ syntax <literal>'$libdir/plXXX'</literal> where
+ <literal>XXX</literal> is <literal>pgsql</literal>, <literal>perl</literal>,
+ <literal>tcl</literal>, or <literal>python</literal>.
+ </para>
+
+ <para>
+ Only shared libraries specifically intended to be used with PostgreSQL
+ can be loaded this way. Every PostgreSQL-supported library has
+ a <quote>magic block</quote> that is checked to guarantee compatibility. For
+ this reason, non-PostgreSQL libraries cannot be loaded in this way. You
+ might be able to use operating-system facilities such
+ as <envar>LD_PRELOAD</envar> for that.
+ </para>
+
+ <para>
+ In general, refer to the documentation of a specific module for the
+ recommended way to load that module.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-local-preload-libraries" xreflabel="local_preload_libraries">
+ <term><varname>local_preload_libraries</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>local_preload_libraries</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm>
+ <primary><filename>$libdir/plugins</filename></primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable specifies one or more shared libraries that are to be
+ preloaded at connection start.
+ It contains a comma-separated list of library names, where each name
+ is interpreted as for the <link linkend="sql-load"><command>LOAD</command></link> command.
+ Whitespace between entries is ignored; surround a library name with
+ double quotes if you need to include whitespace or commas in the name.
+ The parameter value only takes effect at the start of the connection.
+ Subsequent changes have no effect. If a specified library is not
+ found, the connection attempt will fail.
+ </para>
+
+ <para>
+ This option can be set by any user. Because of that, the libraries
+ that can be loaded are restricted to those appearing in the
+ <filename>plugins</filename> subdirectory of the installation's
+ standard library directory. (It is the database administrator's
+ responsibility to ensure that only <quote>safe</quote> libraries
+ are installed there.) Entries in <varname>local_preload_libraries</varname>
+ can specify this directory explicitly, for example
+ <literal>$libdir/plugins/mylib</literal>, or just specify
+ the library name &mdash; <literal>mylib</literal> would have
+ the same effect as <literal>$libdir/plugins/mylib</literal>.
+ </para>
+
+ <para>
+ The intent of this feature is to allow unprivileged users to load
+ debugging or performance-measurement libraries into specific sessions
+ without requiring an explicit <command>LOAD</command> command. To that end,
+ it would be typical to set this parameter using
+ the <envar>PGOPTIONS</envar> environment variable on the client or by
+ using
+ <command>ALTER ROLE SET</command>.
+ </para>
+
+ <para>
+ However, unless a module is specifically designed to be used in this way by
+ non-superusers, this is usually not the right setting to use. Look
+ at <xref linkend="guc-session-preload-libraries"/> instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="guc-session-preload-libraries" xreflabel="session_preload_libraries">
+ <term><varname>session_preload_libraries</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>session_preload_libraries</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable specifies one or more shared libraries that are to be
+ preloaded at connection start.
+ It contains a comma-separated list of library names, where each name
+ is interpreted as for the <link linkend="sql-load"><command>LOAD</command></link> command.
+ Whitespace between entries is ignored; surround a library name with
+ double quotes if you need to include whitespace or commas in the name.
+ The parameter value only takes effect at the start of the connection.
+ Subsequent changes have no effect. If a specified library is not
+ found, the connection attempt will fail.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ The intent of this feature is to allow debugging or
+ performance-measurement libraries to be loaded into specific sessions
+ without an explicit
+ <command>LOAD</command> command being given. For
+ example, <xref linkend="auto-explain"/> could be enabled for all
+ sessions under a given user name by setting this parameter
+ with <command>ALTER ROLE SET</command>. Also, this parameter can be changed
+ without restarting the server (but changes only take effect when a new
+ session is started), so it is easier to add new modules this way, even
+ if they should apply to all sessions.
+ </para>
+
+ <para>
+ Unlike <xref linkend="guc-shared-preload-libraries"/>, there is no large
+ performance advantage to loading a library at session start rather than
+ when it is first used. There is some advantage, however, when
+ connection pooling is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-shared-preload-libraries" xreflabel="shared_preload_libraries">
+ <term><varname>shared_preload_libraries</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>shared_preload_libraries</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable specifies one or more shared libraries to be preloaded at
+ server start.
+ It contains a comma-separated list of library names, where each name
+ is interpreted as for the <link linkend="sql-load"><command>LOAD</command></link> command.
+ Whitespace between entries is ignored; surround a library name with
+ double quotes if you need to include whitespace or commas in the name.
+ This parameter can only be set at server start. If a specified
+ library is not found, the server will fail to start.
+ </para>
+
+ <para>
+ Some libraries need to perform certain operations that can only take
+ place at postmaster start, such as allocating shared memory, reserving
+ light-weight locks, or starting background workers. Those libraries
+ must be loaded at server start through this parameter. See the
+ documentation of each library for details.
+ </para>
+
+ <para>
+ Other libraries can also be preloaded. By preloading a shared library,
+ the library startup time is avoided when the library is first used.
+ However, the time to start each new server process might increase
+ slightly, even if that process never uses the library. So this
+ parameter is recommended only for libraries that will be used in most
+ sessions. Also, changing this parameter requires a server restart, so
+ this is not the right setting to use for short-term debugging tasks,
+ say. Use <xref linkend="guc-session-preload-libraries"/> for that
+ instead.
+ </para>
+
+ <note>
+ <para>
+ On Windows hosts, preloading a library at server start will not reduce
+ the time required to start each new server process; each server process
+ will re-load all preload libraries. However, <varname>shared_preload_libraries
+ </varname> is still useful on Windows hosts for libraries that need to
+ perform operations at postmaster start time.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-provider" xreflabel="jit_provider">
+ <term><varname>jit_provider</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>jit_provider</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This variable is the name of the JIT provider library to be used
+ (see <xref linkend="jit-pluggable"/>).
+ The default is <literal>llvmjit</literal>.
+ This parameter can only be set at server start.
+ </para>
+
+ <para>
+ If set to a non-existent library, <acronym>JIT</acronym> will not be
+ available, but no error will be raised. This allows JIT support to be
+ installed separately from the main
+ <productname>PostgreSQL</productname> package.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-client-other">
+ <title>Other Defaults</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-dynamic-library-path" xreflabel="dynamic_library_path">
+ <term><varname>dynamic_library_path</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>dynamic_library_path</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>dynamic loading</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ If a dynamically loadable module needs to be opened and the
+ file name specified in the <command>CREATE FUNCTION</command> or
+ <command>LOAD</command> command
+ does not have a directory component (i.e., the
+ name does not contain a slash), the system will search this
+ path for the required file.
+ </para>
+
+ <para>
+ The value for <varname>dynamic_library_path</varname> must be a
+ list of absolute directory paths separated by colons (or semi-colons
+ on Windows). If a list element starts
+ with the special string <literal>$libdir</literal>, the
+ compiled-in <productname>PostgreSQL</productname> package
+ library directory is substituted for <literal>$libdir</literal>; this
+ is where the modules provided by the standard
+ <productname>PostgreSQL</productname> distribution are installed.
+ (Use <literal>pg_config --pkglibdir</literal> to find out the name of
+ this directory.) For example:
+<programlisting>
+dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
+</programlisting>
+ or, in a Windows environment:
+<programlisting>
+dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
+</programlisting>
+ </para>
+
+ <para>
+ The default value for this parameter is
+ <literal>'$libdir'</literal>. If the value is set to an empty
+ string, the automatic path search is turned off.
+ </para>
+
+ <para>
+ This parameter can be changed at run time by superusers and users
+ with the appropriate <literal>SET</literal> privilege, but a
+ setting done that way will only persist until the end of the
+ client connection, so this method should be reserved for
+ development purposes. The recommended way to set this parameter
+ is in the <filename>postgresql.conf</filename> configuration
+ file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-gin-fuzzy-search-limit" xreflabel="gin_fuzzy_search_limit">
+ <term><varname>gin_fuzzy_search_limit</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>gin_fuzzy_search_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Soft upper limit of the size of the set returned by GIN index scans. For more
+ information see <xref linkend="gin-tips"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-locks">
+ <title>Lock Management</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-deadlock-timeout" xreflabel="deadlock_timeout">
+ <term><varname>deadlock_timeout</varname> (<type>integer</type>)
+ <indexterm>
+ <primary>deadlock</primary>
+ <secondary>timeout during</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>timeout</primary>
+ <secondary>deadlock</secondary>
+ </indexterm>
+ <indexterm>
+ <primary><varname>deadlock_timeout</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This is the amount of time to wait on a lock
+ before checking to see if there is a deadlock condition. The
+ check for deadlock is relatively expensive, so the server doesn't run
+ it every time it waits for a lock. We optimistically assume
+ that deadlocks are not common in production applications and
+ just wait on the lock for a while before checking for a
+ deadlock. Increasing this value reduces the amount of time
+ wasted in needless deadlock checks, but slows down reporting of
+ real deadlock errors.
+ If this value is specified without units, it is taken as milliseconds.
+ The default is one second (<literal>1s</literal>),
+ which is probably about the smallest value you would want in
+ practice. On a heavily loaded server you might want to raise it.
+ Ideally the setting should exceed your typical transaction time,
+ so as to improve the odds that a lock will be released before
+ the waiter decides to check for deadlock.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+
+ <para>
+ When <xref linkend="guc-log-lock-waits"/> is set,
+ this parameter also determines the amount of time to wait before
+ a log message is issued about the lock wait. If you are trying
+ to investigate locking delays you might want to set a shorter than
+ normal <varname>deadlock_timeout</varname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-locks-per-transaction" xreflabel="max_locks_per_transaction">
+ <term><varname>max_locks_per_transaction</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_locks_per_transaction</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The shared lock table tracks locks on
+ <varname>max_locks_per_transaction</varname> * (<xref
+ linkend="guc-max-connections"/> + <xref
+ linkend="guc-max-prepared-transactions"/>) objects (e.g., tables);
+ hence, no more than this many distinct objects can be locked at
+ any one time. This parameter controls the average number of object
+ locks allocated for each transaction; individual transactions
+ can lock more objects as long as the locks of all transactions
+ fit in the lock table. This is <emphasis>not</emphasis> the number of
+ rows that can be locked; that value is unlimited. The default,
+ 64, has historically proven sufficient, but you might need to
+ raise this value if you have queries that touch many different
+ tables in a single transaction, e.g., query of a parent table with
+ many children. This parameter can only be set at server start.
+ </para>
+
+ <para>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-pred-locks-per-transaction" xreflabel="max_pred_locks_per_transaction">
+ <term><varname>max_pred_locks_per_transaction</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_pred_locks_per_transaction</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The shared predicate lock table tracks locks on
+ <varname>max_pred_locks_per_transaction</varname> * (<xref
+ linkend="guc-max-connections"/> + <xref
+ linkend="guc-max-prepared-transactions"/>) objects (e.g., tables);
+ hence, no more than this many distinct objects can be locked at
+ any one time. This parameter controls the average number of object
+ locks allocated for each transaction; individual transactions
+ can lock more objects as long as the locks of all transactions
+ fit in the lock table. This is <emphasis>not</emphasis> the number of
+ rows that can be locked; that value is unlimited. The default,
+ 64, has generally been sufficient in testing, but you might need to
+ raise this value if you have clients that touch many different
+ tables in a single serializable transaction. This parameter can
+ only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-pred-locks-per-relation" xreflabel="max_pred_locks_per_relation">
+ <term><varname>max_pred_locks_per_relation</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_pred_locks_per_relation</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This controls how many pages or tuples of a single relation can be
+ predicate-locked before the lock is promoted to covering the whole
+ relation. Values greater than or equal to zero mean an absolute
+ limit, while negative values
+ mean <xref linkend="guc-max-pred-locks-per-transaction"/> divided by
+ the absolute value of this setting. The default is -2, which keeps
+ the behavior from previous versions of <productname>PostgreSQL</productname>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-pred-locks-per-page" xreflabel="max_pred_locks_per_page">
+ <term><varname>max_pred_locks_per_page</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_pred_locks_per_page</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This controls how many rows on a single page can be predicate-locked
+ before the lock is promoted to covering the whole page. The default
+ is 2. This parameter can only be set in
+ the <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+
+ <sect1 id="runtime-config-compatible">
+ <title>Version and Platform Compatibility</title>
+
+ <sect2 id="runtime-config-compatible-version">
+ <title>Previous PostgreSQL Versions</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-array-nulls" xreflabel="array_nulls">
+ <term><varname>array_nulls</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>array_nulls</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This controls whether the array input parser recognizes
+ unquoted <literal>NULL</literal> as specifying a null array element.
+ By default, this is <literal>on</literal>, allowing array values containing
+ null values to be entered. However, <productname>PostgreSQL</productname> versions
+ before 8.2 did not support null values in arrays, and therefore would
+ treat <literal>NULL</literal> as specifying a normal array element with
+ the string value <quote>NULL</quote>. For backward compatibility with
+ applications that require the old behavior, this variable can be
+ turned <literal>off</literal>.
+ </para>
+
+ <para>
+ Note that it is possible to create array values containing null values
+ even when this variable is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-backslash-quote" xreflabel="backslash_quote">
+ <term><varname>backslash_quote</varname> (<type>enum</type>)
+ <indexterm><primary>strings</primary><secondary>backslash quotes</secondary></indexterm>
+ <indexterm>
+ <primary><varname>backslash_quote</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This controls whether a quote mark can be represented by
+ <literal>\'</literal> in a string literal. The preferred, SQL-standard way
+ to represent a quote mark is by doubling it (<literal>''</literal>) but
+ <productname>PostgreSQL</productname> has historically also accepted
+ <literal>\'</literal>. However, use of <literal>\'</literal> creates security risks
+ because in some client character set encodings, there are multibyte
+ characters in which the last byte is numerically equivalent to ASCII
+ <literal>\</literal>. If client-side code does escaping incorrectly then an
+ SQL-injection attack is possible. This risk can be prevented by
+ making the server reject queries in which a quote mark appears to be
+ escaped by a backslash.
+ The allowed values of <varname>backslash_quote</varname> are
+ <literal>on</literal> (allow <literal>\'</literal> always),
+ <literal>off</literal> (reject always), and
+ <literal>safe_encoding</literal> (allow only if client encoding does not
+ allow ASCII <literal>\</literal> within a multibyte character).
+ <literal>safe_encoding</literal> is the default setting.
+ </para>
+
+ <para>
+ Note that in a standard-conforming string literal, <literal>\</literal> just
+ means <literal>\</literal> anyway. This parameter only affects the handling of
+ non-standard-conforming literals, including
+ escape string syntax (<literal>E'...'</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-escape-string-warning" xreflabel="escape_string_warning">
+ <term><varname>escape_string_warning</varname> (<type>boolean</type>)
+ <indexterm><primary>strings</primary><secondary>escape warning</secondary></indexterm>
+ <indexterm>
+ <primary><varname>escape_string_warning</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When on, a warning is issued if a backslash (<literal>\</literal>)
+ appears in an ordinary string literal (<literal>'...'</literal>
+ syntax) and <varname>standard_conforming_strings</varname> is off.
+ The default is <literal>on</literal>.
+ </para>
+ <para>
+ Applications that wish to use backslash as escape should be
+ modified to use escape string syntax (<literal>E'...'</literal>),
+ because the default behavior of ordinary strings is now to treat
+ backslash as an ordinary character, per SQL standard. This variable
+ can be enabled to help locate code that needs to be changed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lo-compat-privileges" xreflabel="lo_compat_privileges">
+ <term><varname>lo_compat_privileges</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>lo_compat_privileges</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ In <productname>PostgreSQL</productname> releases prior to 9.0, large objects
+ did not have access privileges and were, therefore, always readable
+ and writable by all users. Setting this variable to <literal>on</literal>
+ disables the new privilege checks, for compatibility with prior
+ releases. The default is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ <para>
+ Setting this variable does not disable all security checks related to
+ large objects &mdash; only those for which the default behavior has
+ changed in <productname>PostgreSQL</productname> 9.0.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-quote-all-identifiers" xreflabel="quote-all-identifiers">
+ <term><varname>quote_all_identifiers</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>quote_all_identifiers</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When the database generates SQL, force all identifiers to be quoted,
+ even if they are not (currently) keywords. This will affect the
+ output of <command>EXPLAIN</command> as well as the results of functions
+ like <function>pg_get_viewdef</function>. See also the
+ <option>--quote-all-identifiers</option> option of
+ <xref linkend="app-pgdump"/> and <xref linkend="app-pg-dumpall"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-standard-conforming-strings" xreflabel="standard_conforming_strings">
+ <term><varname>standard_conforming_strings</varname> (<type>boolean</type>)
+ <indexterm><primary>strings</primary><secondary>standard conforming</secondary></indexterm>
+ <indexterm>
+ <primary><varname>standard_conforming_strings</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This controls whether ordinary string literals
+ (<literal>'...'</literal>) treat backslashes literally, as specified in
+ the SQL standard.
+ Beginning in <productname>PostgreSQL</productname> 9.1, the default is
+ <literal>on</literal> (prior releases defaulted to <literal>off</literal>).
+ Applications can check this
+ parameter to determine how string literals will be processed.
+ The presence of this parameter can also be taken as an indication
+ that the escape string syntax (<literal>E'...'</literal>) is supported.
+ Escape string syntax (<xref linkend="sql-syntax-strings-escape"/>)
+ should be used if an application desires
+ backslashes to be treated as escape characters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-synchronize-seqscans" xreflabel="synchronize_seqscans">
+ <term><varname>synchronize_seqscans</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>synchronize_seqscans</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This allows sequential scans of large tables to synchronize with each
+ other, so that concurrent scans read the same block at about the
+ same time and hence share the I/O workload. When this is enabled,
+ a scan might start in the middle of the table and then <quote>wrap
+ around</quote> the end to cover all rows, so as to synchronize with the
+ activity of scans already in progress. This can result in
+ unpredictable changes in the row ordering returned by queries that
+ have no <literal>ORDER BY</literal> clause. Setting this parameter to
+ <literal>off</literal> ensures the pre-8.3 behavior in which a sequential
+ scan always starts from the beginning of the table. The default
+ is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2 id="runtime-config-compatible-clients">
+ <title>Platform and Client Compatibility</title>
+ <variablelist>
+
+ <varlistentry id="guc-transform-null-equals" xreflabel="transform_null_equals">
+ <term><varname>transform_null_equals</varname> (<type>boolean</type>)
+ <indexterm><primary>IS NULL</primary></indexterm>
+ <indexterm>
+ <primary><varname>transform_null_equals</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When on, expressions of the form <literal><replaceable>expr</replaceable> =
+ NULL</literal> (or <literal>NULL =
+ <replaceable>expr</replaceable></literal>) are treated as
+ <literal><replaceable>expr</replaceable> IS NULL</literal>, that is, they
+ return true if <replaceable>expr</replaceable> evaluates to the null value,
+ and false otherwise. The correct SQL-spec-compliant behavior of
+ <literal><replaceable>expr</replaceable> = NULL</literal> is to always
+ return null (unknown). Therefore this parameter defaults to
+ <literal>off</literal>.
+ </para>
+
+ <para>
+ However, filtered forms in <productname>Microsoft
+ Access</productname> generate queries that appear to use
+ <literal><replaceable>expr</replaceable> = NULL</literal> to test for
+ null values, so if you use that interface to access the database you
+ might want to turn this option on. Since expressions of the
+ form <literal><replaceable>expr</replaceable> = NULL</literal> always
+ return the null value (using the SQL standard interpretation), they are not
+ very useful and do not appear often in normal applications so
+ this option does little harm in practice. But new users are
+ frequently confused about the semantics of expressions
+ involving null values, so this option is off by default.
+ </para>
+
+ <para>
+ Note that this option only affects the exact form <literal>= NULL</literal>,
+ not other comparison operators or other expressions
+ that are computationally equivalent to some expression
+ involving the equals operator (such as <literal>IN</literal>).
+ Thus, this option is not a general fix for bad programming.
+ </para>
+
+ <para>
+ Refer to <xref linkend="functions-comparison"/> for related information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="runtime-config-error-handling">
+ <title>Error Handling</title>
+
+ <variablelist>
+
+ <varlistentry id="guc-exit-on-error" xreflabel="exit_on_error">
+ <term><varname>exit_on_error</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>exit_on_error</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If on, any error will terminate the current session. By default,
+ this is set to off, so that only FATAL errors will terminate the
+ session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-restart-after-crash" xreflabel="restart_after_crash">
+ <term><varname>restart_after_crash</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>restart_after_crash</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set to on, which is the default, <productname>PostgreSQL</productname>
+ will automatically reinitialize after a backend crash. Leaving this
+ value set to on is normally the best way to maximize the availability
+ of the database. However, in some circumstances, such as when
+ <productname>PostgreSQL</productname> is being invoked by clusterware, it may be
+ useful to disable the restart so that the clusterware can gain
+ control and take any actions it deems appropriate.
+ </para>
+
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-data-sync-retry" xreflabel="data_sync_retry">
+ <term><varname>data_sync_retry</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>data_sync_retry</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set to off, which is the default, <productname>PostgreSQL</productname>
+ will raise a PANIC-level error on failure to flush modified data files
+ to the file system. This causes the database server to crash. This
+ parameter can only be set at server start.
+ </para>
+ <para>
+ On some operating systems, the status of data in the kernel's page
+ cache is unknown after a write-back failure. In some cases it might
+ have been entirely forgotten, making it unsafe to retry; the second
+ attempt may be reported as successful, when in fact the data has been
+ lost. In these circumstances, the only way to avoid data loss is to
+ recover from the WAL after any failure is reported, preferably
+ after investigating the root cause of the failure and replacing any
+ faulty hardware.
+ </para>
+ <para>
+ If set to on, <productname>PostgreSQL</productname> will instead
+ report an error but continue to run so that the data flushing
+ operation can be retried in a later checkpoint. Only set it to on
+ after investigating the operating system's treatment of buffered data
+ in case of write-back failure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-recovery-init-sync-method" xreflabel="recovery_init_sync_method">
+ <term><varname>recovery_init_sync_method</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>recovery_init_sync_method</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set to <literal>fsync</literal>, which is the default,
+ <productname>PostgreSQL</productname> will recursively open and
+ synchronize all files in the data directory before crash recovery
+ begins. The search for files will follow symbolic links for the WAL
+ directory and each configured tablespace (but not any other symbolic
+ links). This is intended to make sure that all WAL and data files are
+ durably stored on disk before replaying changes. This applies whenever
+ starting a database cluster that did not shut down cleanly, including
+ copies created with <application>pg_basebackup</application>.
+ </para>
+ <para>
+ On Linux, <literal>syncfs</literal> may be used instead, to ask the
+ operating system to synchronize the whole file systems that contain the
+ data directory, the WAL files and each tablespace (but not any other
+ file systems that may be reachable through symbolic links). This may
+ be a lot faster than the <literal>fsync</literal> setting, because it
+ doesn't need to open each file one by one. On the other hand, it may
+ be slower if a file system is shared by other applications that
+ modify a lot of files, since those files will also be written to disk.
+ Furthermore, on versions of Linux before 5.8, I/O errors encountered
+ while writing data to disk may not be reported to
+ <productname>PostgreSQL</productname>, and relevant error messages may
+ appear only in kernel logs.
+ </para>
+ <para>
+ This parameter can only be set in the
+ <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="runtime-config-preset">
+ <title>Preset Options</title>
+
+ <para>
+ The following <quote>parameters</quote> are read-only.
+ As such, they have been excluded from the sample
+ <filename>postgresql.conf</filename> file. These options report
+ various aspects of <productname>PostgreSQL</productname> behavior
+ that might be of interest to certain applications, particularly
+ administrative front-ends.
+ Most of them are determined when <productname>PostgreSQL</productname>
+ is compiled or when it is installed.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-block-size" xreflabel="block_size">
+ <term><varname>block_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>block_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the size of a disk block. It is determined by the value
+ of <literal>BLCKSZ</literal> when building the server. The default
+ value is 8192 bytes. The meaning of some configuration
+ variables (such as <xref linkend="guc-shared-buffers"/>) is
+ influenced by <varname>block_size</varname>. See <xref
+ linkend="runtime-config-resource"/> for information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-data-checksums" xreflabel="data_checksums">
+ <term><varname>data_checksums</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>data_checksums</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports whether data checksums are enabled for this cluster.
+ See <xref linkend="app-initdb-data-checksums"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-data-directory-mode" xreflabel="data_directory_mode">
+ <term><varname>data_directory_mode</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>data_directory_mode</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ On Unix systems this parameter reports the permissions the data
+ directory (defined by <xref linkend="guc-data-directory"/>)
+ had at server startup.
+ (On Microsoft Windows this parameter will always display
+ <literal>0700</literal>.) See
+ <xref linkend="app-initdb-allow-group-access"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-debug-assertions" xreflabel="debug_assertions">
+ <term><varname>debug_assertions</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>debug_assertions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports whether <productname>PostgreSQL</productname> has been built
+ with assertions enabled. That is the case if the
+ macro <symbol>USE_ASSERT_CHECKING</symbol> is defined
+ when <productname>PostgreSQL</productname> is built (accomplished
+ e.g., by the <command>configure</command> option
+ <option>--enable-cassert</option>). By
+ default <productname>PostgreSQL</productname> is built without
+ assertions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-integer-datetimes" xreflabel="integer_datetimes">
+ <term><varname>integer_datetimes</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>integer_datetimes</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports whether <productname>PostgreSQL</productname> was built with support for
+ 64-bit-integer dates and times. As of <productname>PostgreSQL</productname> 10,
+ this is always <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-in-hot-standby" xreflabel="in_hot_standby">
+ <term><varname>in_hot_standby</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>in_hot_standby</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports whether the server is currently in hot standby mode. When
+ this is <literal>on</literal>, all transactions are forced to be
+ read-only. Within a session, this can change only if the server is
+ promoted to be primary. See <xref linkend="hot-standby"/> for more
+ information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lc-collate" xreflabel="lc_collate">
+ <term><varname>lc_collate</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>lc_collate</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the locale in which sorting of textual data is done.
+ See <xref linkend="locale"/> for more information.
+ This value is determined when a database is created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-lc-ctype" xreflabel="lc_ctype">
+ <term><varname>lc_ctype</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>lc_ctype</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the locale that determines character classifications.
+ See <xref linkend="locale"/> for more information.
+ This value is determined when a database is created.
+ Ordinarily this will be the same as <varname>lc_collate</varname>,
+ but for special applications it might be set differently.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-function-args" xreflabel="max_function_args">
+ <term><varname>max_function_args</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_function_args</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the maximum number of function arguments. It is determined by
+ the value of <literal>FUNC_MAX_ARGS</literal> when building the server. The
+ default value is 100 arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-identifier-length" xreflabel="max_identifier_length">
+ <term><varname>max_identifier_length</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_identifier_length</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the maximum identifier length. It is determined as one
+ less than the value of <literal>NAMEDATALEN</literal> when building
+ the server. The default value of <literal>NAMEDATALEN</literal> is
+ 64; therefore the default
+ <varname>max_identifier_length</varname> is 63 bytes, which
+ can be less than 63 characters when using multibyte encodings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-max-index-keys" xreflabel="max_index_keys">
+ <term><varname>max_index_keys</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>max_index_keys</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the maximum number of index keys. It is determined by
+ the value of <literal>INDEX_MAX_KEYS</literal> when building the server. The
+ default value is 32 keys.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-segment-size" xreflabel="segment_size">
+ <term><varname>segment_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>segment_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the number of blocks (pages) that can be stored within a file
+ segment. It is determined by the value of <literal>RELSEG_SIZE</literal>
+ when building the server. The maximum size of a segment file in bytes
+ is equal to <varname>segment_size</varname> multiplied by
+ <varname>block_size</varname>; by default this is 1GB.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-server-encoding" xreflabel="server_encoding">
+ <term><varname>server_encoding</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>server_encoding</varname> configuration parameter</primary>
+ </indexterm>
+ <indexterm><primary>character set</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the database encoding (character set).
+ It is determined when the database is created. Ordinarily,
+ clients need only be concerned with the value of <xref
+ linkend="guc-client-encoding"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-server-version" xreflabel="server_version">
+ <term><varname>server_version</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>server_version</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the version number of the server. It is determined by the
+ value of <literal>PG_VERSION</literal> when building the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-server-version-num" xreflabel="server_version_num">
+ <term><varname>server_version_num</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>server_version_num</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the version number of the server as an integer. It is determined
+ by the value of <literal>PG_VERSION_NUM</literal> when building the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-shared-memory-size" xreflabel="shared_memory_size">
+ <term><varname>shared_memory_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>shared_memory_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the size of the main shared memory area, rounded up to the
+ nearest megabyte.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-shared-memory-size-in-huge-pages" xreflabel="shared_memory_size_in_huge_pages">
+ <term><varname>shared_memory_size_in_huge_pages</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>shared_memory_size_in_huge_pages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the number of huge pages that are needed for the main shared
+ memory area based on the specified <xref linkend="guc-huge-page-size"/>.
+ If huge pages are not supported, this will be <literal>-1</literal>.
+ </para>
+ <para>
+ This setting is supported only on <productname>Linux</productname>. It
+ is always set to <literal>-1</literal> on other platforms. For more
+ details about using huge pages on <productname>Linux</productname>, see
+ <xref linkend="linux-huge-pages"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ssl-library" xreflabel="ssl_library">
+ <term><varname>ssl_library</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_library</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the name of the SSL library that this
+ <productname>PostgreSQL</productname> server was built with (even if
+ SSL is not currently configured or in use on this instance), for
+ example <literal>OpenSSL</literal>, or an empty string if none.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-block-size" xreflabel="wal_block_size">
+ <term><varname>wal_block_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_block_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the size of a WAL disk block. It is determined by the value
+ of <literal>XLOG_BLCKSZ</literal> when building the server. The default value
+ is 8192 bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-segment-size" xreflabel="wal_segment_size">
+ <term><varname>wal_segment_size</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>wal_segment_size</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Reports the size of write ahead log segments. The default value is
+ 16MB. See <xref linkend="wal-configuration"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+
+ <sect1 id="runtime-config-custom">
+ <title>Customized Options</title>
+
+ <para>
+ This feature was designed to allow parameters not normally known to
+ <productname>PostgreSQL</productname> to be added by add-on modules
+ (such as procedural languages). This allows extension modules to be
+ configured in the standard ways.
+ </para>
+
+ <para>
+ Custom options have two-part names: an extension name, then a dot, then
+ the parameter name proper, much like qualified names in SQL. An example
+ is <literal>plpgsql.variable_conflict</literal>.
+ </para>
+
+ <para>
+ Because custom options may need to be set in processes that have not
+ loaded the relevant extension module, <productname>PostgreSQL</productname>
+ will accept a setting for any two-part parameter name. Such variables
+ are treated as placeholders and have no function until the module that
+ defines them is loaded. When an extension module is loaded, it will add
+ its variable definitions and convert any placeholder values according to
+ those definitions. If there are any unrecognized placeholders
+ that begin with its extension name, warnings are issued and those
+ placeholders are removed.
+ </para>
+ </sect1>
+
+ <sect1 id="runtime-config-developer">
+ <title>Developer Options</title>
+
+ <para>
+ The following parameters are intended for developer testing, and
+ should never be used on a production database. However, some of
+ them can be used to assist with the recovery of severely damaged
+ databases. As such, they have been excluded from the sample
+ <filename>postgresql.conf</filename> file. Note that many of these
+ parameters require special source compilation flags to work at all.
+ </para>
+
+ <variablelist>
+ <varlistentry id="guc-allow-in-place-tablespaces" xreflabel="allow_in_place_tablespaces">
+ <term><varname>allow_in_place_tablespaces</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>allow_in_place_tablespaces</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Allows tablespaces to be created as directories inside
+ <filename>pg_tblspc</filename>, when an empty location string
+ is provided to the <command>CREATE TABLESPACE</command> command. This
+ is intended to allow testing replication scenarios where primary and
+ standby servers are running on the same machine. Such directories
+ are likely to confuse backup tools that expect to find only symbolic
+ links in that location.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-allow-system-table-mods" xreflabel="allow_system_table_mods">
+ <term><varname>allow_system_table_mods</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>allow_system_table_mods</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Allows modification of the structure of system tables as well as
+ certain other risky actions on system tables. This is otherwise not
+ allowed even for superusers. Ill-advised use of this setting can
+ cause irretrievable data loss or seriously corrupt the database
+ system.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-backtrace-functions" xreflabel="backtrace_functions">
+ <term><varname>backtrace_functions</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>backtrace_functions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter contains a comma-separated list of C function names.
+ If an error is raised and the name of the internal C function where
+ the error happens matches a value in the list, then a backtrace is
+ written to the server log together with the error message. This can
+ be used to debug specific areas of the source code.
+ </para>
+
+ <para>
+ Backtrace support is not available on all platforms, and the quality
+ of the backtraces depends on compilation options.
+ </para>
+
+ <para>
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-debug-discard-caches" xreflabel="debug_discard_caches">
+ <term><varname>debug_discard_caches</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>debug_discard_caches</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set to <literal>1</literal>, each system catalog cache entry is
+ invalidated at the first possible opportunity, whether or not
+ anything that would render it invalid really occurred. Caching of
+ system catalogs is effectively disabled as a result, so the server
+ will run extremely slowly. Higher values run the cache invalidation
+ recursively, which is even slower and only useful for testing
+ the caching logic itself. The default value of <literal>0</literal>
+ selects normal catalog caching behavior.
+ </para>
+
+ <para>
+ This parameter can be very helpful when trying to trigger
+ hard-to-reproduce bugs involving concurrent catalog changes, but it
+ is otherwise rarely needed. See the source code files
+ <filename>inval.c</filename> and
+ <filename>pg_config_manual.h</filename> for details.
+ </para>
+
+ <para>
+ This parameter is supported when
+ <symbol>DISCARD_CACHES_ENABLED</symbol> was defined at compile time
+ (which happens automatically when using the
+ <application>configure</application> option
+ <option>--enable-cassert</option>). In production builds, its value
+ will always be <literal>0</literal> and attempts to set it to another
+ value will raise an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-force-parallel-mode" xreflabel="force_parallel_mode">
+ <term><varname>force_parallel_mode</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>force_parallel_mode</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Allows the use of parallel queries for testing purposes even in cases
+ where no performance benefit is expected.
+ The allowed values of <varname>force_parallel_mode</varname> are
+ <literal>off</literal> (use parallel mode only when it is expected to improve
+ performance), <literal>on</literal> (force parallel query for all queries
+ for which it is thought to be safe), and <literal>regress</literal> (like
+ <literal>on</literal>, but with additional behavior changes as explained
+ below).
+ </para>
+
+ <para>
+ More specifically, setting this value to <literal>on</literal> will add
+ a <literal>Gather</literal> node to the top of any query plan for which this
+ appears to be safe, so that the query runs inside of a parallel worker.
+ Even when a parallel worker is not available or cannot be used,
+ operations such as starting a subtransaction that would be prohibited
+ in a parallel query context will be prohibited unless the planner
+ believes that this will cause the query to fail. If failures or
+ unexpected results occur when this option is set, some functions used
+ by the query may need to be marked <literal>PARALLEL UNSAFE</literal>
+ (or, possibly, <literal>PARALLEL RESTRICTED</literal>).
+ </para>
+
+ <para>
+ Setting this value to <literal>regress</literal> has all of the same effects
+ as setting it to <literal>on</literal> plus some additional effects that are
+ intended to facilitate automated regression testing. Normally,
+ messages from a parallel worker include a context line indicating that,
+ but a setting of <literal>regress</literal> suppresses this line so that the
+ output is the same as in non-parallel execution. Also,
+ the <literal>Gather</literal> nodes added to plans by this setting are hidden
+ in <literal>EXPLAIN</literal> output so that the output matches what
+ would be obtained if this setting were turned <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ignore-system-indexes" xreflabel="ignore_system_indexes">
+ <term><varname>ignore_system_indexes</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>ignore_system_indexes</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Ignore system indexes when reading system tables (but still
+ update the indexes when modifying the tables). This is useful
+ when recovering from damaged system indexes.
+ This parameter cannot be changed after session start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-post-auth-delay" xreflabel="post_auth_delay">
+ <term><varname>post_auth_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>post_auth_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The amount of time to delay when a new
+ server process is started, after it conducts the
+ authentication procedure. This is intended to give developers an
+ opportunity to attach to the server process with a debugger.
+ If this value is specified without units, it is taken as seconds.
+ A value of zero (the default) disables the delay.
+ This parameter cannot be changed after session start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-pre-auth-delay" xreflabel="pre_auth_delay">
+ <term><varname>pre_auth_delay</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>pre_auth_delay</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The amount of time to delay just after a
+ new server process is forked, before it conducts the
+ authentication procedure. This is intended to give developers an
+ opportunity to attach to the server process with a debugger to
+ trace down misbehavior in authentication.
+ If this value is specified without units, it is taken as seconds.
+ A value of zero (the default) disables the delay.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-notify" xreflabel="trace_notify">
+ <term><varname>trace_notify</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>trace_notify</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Generates a great amount of debugging output for the
+ <command>LISTEN</command> and <command>NOTIFY</command>
+ commands. <xref linkend="guc-client-min-messages"/> or
+ <xref linkend="guc-log-min-messages"/> must be
+ <literal>DEBUG1</literal> or lower to send this output to the
+ client or server logs, respectively.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-recovery-messages" xreflabel="trace_recovery_messages">
+ <term><varname>trace_recovery_messages</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>trace_recovery_messages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables logging of recovery-related debugging output that otherwise
+ would not be logged. This parameter allows the user to override the
+ normal setting of <xref linkend="guc-log-min-messages"/>, but only for
+ specific messages. This is intended for use in debugging hot standby.
+ Valid values are <literal>DEBUG5</literal>, <literal>DEBUG4</literal>,
+ <literal>DEBUG3</literal>, <literal>DEBUG2</literal>, <literal>DEBUG1</literal>, and
+ <literal>LOG</literal>. The default, <literal>LOG</literal>, does not affect
+ logging decisions at all. The other values cause recovery-related
+ debug messages of that priority or higher to be logged as though they
+ had <literal>LOG</literal> priority; for common settings of
+ <varname>log_min_messages</varname> this results in unconditionally sending
+ them to the server log.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-sort" xreflabel="trace_sort">
+ <term><varname>trace_sort</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>trace_sort</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If on, emit information about resource usage during sort operations.
+ This parameter is only available if the <symbol>TRACE_SORT</symbol> macro
+ was defined when <productname>PostgreSQL</productname> was compiled.
+ (However, <symbol>TRACE_SORT</symbol> is currently defined by default.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-locks" xreflabel="trace_locks">
+ <term><varname>trace_locks</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>trace_locks</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If on, emit information about lock usage. Information dumped
+ includes the type of lock operation, the type of lock and the unique
+ identifier of the object being locked or unlocked. Also included
+ are bit masks for the lock types already granted on this object as
+ well as for the lock types awaited on this object. For each lock
+ type a count of the number of granted locks and waiting locks is
+ also dumped as well as the totals. An example of the log file output
+ is shown here:
+<screen>
+LOG: LockAcquire: new: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
+ wait(0) type(AccessShareLock)
+LOG: GrantLock: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(2) req(1,0,0,0,0,0,0)=1 grant(1,0,0,0,0,0,0)=1
+ wait(0) type(AccessShareLock)
+LOG: UnGrantLock: updated: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
+ wait(0) type(AccessShareLock)
+LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
+ wait(0) type(INVALID)
+</screen>
+ Details of the structure being dumped may be found in
+ <filename>src/include/storage/lock.h</filename>.
+ </para>
+ <para>
+ This parameter is only available if the <symbol>LOCK_DEBUG</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-lwlocks" xreflabel="trace_lwlocks">
+ <term><varname>trace_lwlocks</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>trace_lwlocks</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If on, emit information about lightweight lock usage. Lightweight
+ locks are intended primarily to provide mutual exclusion of access
+ to shared-memory data structures.
+ </para>
+ <para>
+ This parameter is only available if the <symbol>LOCK_DEBUG</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-userlocks" xreflabel="trace_userlocks">
+ <term><varname>trace_userlocks</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>trace_userlocks</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If on, emit information about user lock usage. Output is the same
+ as for <symbol>trace_locks</symbol>, only for advisory locks.
+ </para>
+ <para>
+ This parameter is only available if the <symbol>LOCK_DEBUG</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-lock-oidmin" xreflabel="trace_lock_oidmin">
+ <term><varname>trace_lock_oidmin</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>trace_lock_oidmin</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If set, do not trace locks for tables below this OID (used to avoid
+ output on system tables).
+ </para>
+ <para>
+ This parameter is only available if the <symbol>LOCK_DEBUG</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-trace-lock-table" xreflabel="trace_lock_table">
+ <term><varname>trace_lock_table</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>trace_lock_table</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Unconditionally trace locks on this table (OID).
+ </para>
+ <para>
+ This parameter is only available if the <symbol>LOCK_DEBUG</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-debug-deadlocks" xreflabel="debug_deadlocks">
+ <term><varname>debug_deadlocks</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>debug_deadlocks</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If set, dumps information about all current locks when a
+ deadlock timeout occurs.
+ </para>
+ <para>
+ This parameter is only available if the <symbol>LOCK_DEBUG</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-log-btree-build-stats" xreflabel="log_btree_build_stats">
+ <term><varname>log_btree_build_stats</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>log_btree_build_stats</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If set, logs system resource usage statistics (memory and CPU) on
+ various B-tree operations.
+ </para>
+ <para>
+ This parameter is only available if the <symbol>BTREE_BUILD_STATS</symbol>
+ macro was defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-consistency-checking" xreflabel="wal_consistency_checking">
+ <term><varname>wal_consistency_checking</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>wal_consistency_checking</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter is intended to be used to check for bugs in the WAL
+ redo routines. When enabled, full-page images of any buffers modified
+ in conjunction with the WAL record are added to the record.
+ If the record is subsequently replayed, the system will first apply
+ each record and then test whether the buffers modified by the record
+ match the stored images. In certain cases (such as hint bits), minor
+ variations are acceptable, and will be ignored. Any unexpected
+ differences will result in a fatal error, terminating recovery.
+ </para>
+
+ <para>
+ The default value of this setting is the empty string, which disables
+ the feature. It can be set to <literal>all</literal> to check all
+ records, or to a comma-separated list of resource managers to check
+ only records originating from those resource managers. Currently,
+ the supported resource managers are <literal>heap</literal>,
+ <literal>heap2</literal>, <literal>btree</literal>, <literal>hash</literal>,
+ <literal>gin</literal>, <literal>gist</literal>, <literal>sequence</literal>,
+ <literal>spgist</literal>, <literal>brin</literal>, and <literal>generic</literal>.
+ Extensions may define additional resource managers. Only superusers and users with
+ the appropriate <literal>SET</literal> privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-wal-debug" xreflabel="wal_debug">
+ <term><varname>wal_debug</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>wal_debug</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If on, emit WAL-related debugging output. This parameter is
+ only available if the <symbol>WAL_DEBUG</symbol> macro was
+ defined when <productname>PostgreSQL</productname> was
+ compiled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ignore-checksum-failure" xreflabel="ignore_checksum_failure">
+ <term><varname>ignore_checksum_failure</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>ignore_checksum_failure</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Only has effect if <xref linkend="app-initdb-data-checksums"/> are enabled.
+ </para>
+ <para>
+ Detection of a checksum failure during a read normally causes
+ <productname>PostgreSQL</productname> to report an error, aborting the current
+ transaction. Setting <varname>ignore_checksum_failure</varname> to on causes
+ the system to ignore the failure (but still report a warning), and
+ continue processing. This behavior may <emphasis>cause crashes, propagate
+ or hide corruption, or other serious problems</emphasis>. However, it may allow
+ you to get past the error and retrieve undamaged tuples that might still be
+ present in the table if the block header is still sane. If the header is
+ corrupt an error will be reported even if this option is enabled. The
+ default setting is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-zero-damaged-pages" xreflabel="zero_damaged_pages">
+ <term><varname>zero_damaged_pages</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>zero_damaged_pages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Detection of a damaged page header normally causes
+ <productname>PostgreSQL</productname> to report an error, aborting the current
+ transaction. Setting <varname>zero_damaged_pages</varname> to on causes
+ the system to instead report a warning, zero out the damaged
+ page in memory, and continue processing. This behavior <emphasis>will destroy data</emphasis>,
+ namely all the rows on the damaged page. However, it does allow you to get
+ past the error and retrieve rows from any undamaged pages that might
+ be present in the table. It is useful for recovering data if
+ corruption has occurred due to a hardware or software error. You should
+ generally not set this on until you have given up hope of recovering
+ data from the damaged pages of a table. Zeroed-out pages are not
+ forced to disk so it is recommended to recreate the table or
+ the index before turning this parameter off again. The
+ default setting is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-ignore-invalid-pages" xreflabel="ignore_invalid_pages">
+ <term><varname>ignore_invalid_pages</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>ignore_invalid_pages</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If set to <literal>off</literal> (the default), detection of
+ WAL records having references to invalid pages during
+ recovery causes <productname>PostgreSQL</productname> to
+ raise a PANIC-level error, aborting the recovery. Setting
+ <varname>ignore_invalid_pages</varname> to <literal>on</literal>
+ causes the system to ignore invalid page references in WAL records
+ (but still report a warning), and continue the recovery.
+ This behavior may <emphasis>cause crashes, data loss,
+ propagate or hide corruption, or other serious problems</emphasis>.
+ However, it may allow you to get past the PANIC-level error,
+ to finish the recovery, and to cause the server to start up.
+ The parameter can only be set at server start. It only has effect
+ during recovery or in standby mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-debugging-support" xreflabel="jit_debugging_support">
+ <term><varname>jit_debugging_support</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>jit_debugging_support</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If LLVM has the required functionality, register generated functions
+ with <productname>GDB</productname>. This makes debugging easier.
+ The default setting is <literal>off</literal>.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-dump-bitcode" xreflabel="jit_dump_bitcode">
+ <term><varname>jit_dump_bitcode</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>jit_dump_bitcode</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Writes the generated <productname>LLVM</productname> IR out to the
+ file system, inside <xref linkend="guc-data-directory"/>. This is only
+ useful for working on the internals of the JIT implementation.
+ The default setting is <literal>off</literal>.
+ Only superusers and users with the appropriate <literal>SET</literal>
+ privilege can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-expressions" xreflabel="jit_expressions">
+ <term><varname>jit_expressions</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>jit_expressions</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines whether expressions are JIT compiled, when JIT compilation
+ is activated (see <xref linkend="jit-decision"/>). The default is
+ <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-profiling-support" xreflabel="jit_profiling_support">
+ <term><varname>jit_profiling_support</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>jit_profiling_support</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ If LLVM has the required functionality, emit the data needed to allow
+ <productname>perf</productname> to profile functions generated by JIT.
+ This writes out files to <filename>~/.debug/jit/</filename>; the
+ user is responsible for performing cleanup when desired.
+ The default setting is <literal>off</literal>.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-jit-tuple-deforming" xreflabel="jit_tuple_deforming">
+ <term><varname>jit_tuple_deforming</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>jit_tuple_deforming</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines whether tuple deforming is JIT compiled, when JIT
+ compilation is activated (see <xref linkend="jit-decision"/>).
+ The default is <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-remove-temp-files-after-crash" xreflabel="remove_temp_files_after_crash">
+ <term><varname>remove_temp_files_after_crash</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>remove_temp_files_after_crash</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set to <literal>on</literal>, which is the default,
+ <productname>PostgreSQL</productname> will automatically remove
+ temporary files after a backend crash. If disabled, the files will be
+ retained and may be used for debugging, for example. Repeated crashes
+ may however result in accumulation of useless files. This parameter
+ can only be set in the <filename>postgresql.conf</filename> file or on
+ the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+ <sect1 id="runtime-config-short">
+ <title>Short Options</title>
+
+ <para>
+ For convenience there are also single letter command-line option
+ switches available for some parameters. They are described in
+ <xref linkend="runtime-config-short-table"/>. Some of these
+ options exist for historical reasons, and their presence as a
+ single-letter option does not necessarily indicate an endorsement
+ to use the option heavily.
+ </para>
+
+ <table id="runtime-config-short-table">
+ <title>Short Option Key</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Short Option</entry>
+ <entry>Equivalent</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><option>-B <replaceable>x</replaceable></option></entry>
+ <entry><literal>shared_buffers = <replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-d <replaceable>x</replaceable></option></entry>
+ <entry><literal>log_min_messages = DEBUG<replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-e</option></entry>
+ <entry><literal>datestyle = euro</literal></entry>
+ </row>
+ <row>
+ <entry>
+ <option>-fb</option>, <option>-fh</option>, <option>-fi</option>,
+ <option>-fm</option>, <option>-fn</option>, <option>-fo</option>,
+ <option>-fs</option>, <option>-ft</option>
+ </entry>
+ <entry>
+ <literal>enable_bitmapscan = off</literal>,
+ <literal>enable_hashjoin = off</literal>,
+ <literal>enable_indexscan = off</literal>,
+ <literal>enable_mergejoin = off</literal>,
+ <literal>enable_nestloop = off</literal>,
+ <literal>enable_indexonlyscan = off</literal>,
+ <literal>enable_seqscan = off</literal>,
+ <literal>enable_tidscan = off</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><option>-F</option></entry>
+ <entry><literal>fsync = off</literal></entry>
+ </row>
+ <row>
+ <entry><option>-h <replaceable>x</replaceable></option></entry>
+ <entry><literal>listen_addresses = <replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-i</option></entry>
+ <entry><literal>listen_addresses = '*'</literal></entry>
+ </row>
+ <row>
+ <entry><option>-k <replaceable>x</replaceable></option></entry>
+ <entry><literal>unix_socket_directories = <replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-l</option></entry>
+ <entry><literal>ssl = on</literal></entry>
+ </row>
+ <row>
+ <entry><option>-N <replaceable>x</replaceable></option></entry>
+ <entry><literal>max_connections = <replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-O</option></entry>
+ <entry><literal>allow_system_table_mods = on</literal></entry>
+ </row>
+ <row>
+ <entry><option>-p <replaceable>x</replaceable></option></entry>
+ <entry><literal>port = <replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-P</option></entry>
+ <entry><literal>ignore_system_indexes = on</literal></entry>
+ </row>
+ <row>
+ <entry><option>-s</option></entry>
+ <entry><literal>log_statement_stats = on</literal></entry>
+ </row>
+ <row>
+ <entry><option>-S <replaceable>x</replaceable></option></entry>
+ <entry><literal>work_mem = <replaceable>x</replaceable></literal></entry>
+ </row>
+ <row>
+ <entry><option>-tpa</option>, <option>-tpl</option>, <option>-te</option></entry>
+ <entry><literal>log_parser_stats = on</literal>,
+ <literal>log_planner_stats = on</literal>,
+ <literal>log_executor_stats = on</literal></entry>
+ </row>
+ <row>
+ <entry><option>-W <replaceable>x</replaceable></option></entry>
+ <entry><literal>post_auth_delay = <replaceable>x</replaceable></literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/contrib-spi.sgml b/doc/src/sgml/contrib-spi.sgml
new file mode 100644
index 0000000..fed6f24
--- /dev/null
+++ b/doc/src/sgml/contrib-spi.sgml
@@ -0,0 +1,139 @@
+<!-- doc/src/sgml/contrib-spi.sgml -->
+
+<sect1 id="contrib-spi" xreflabel="spi">
+ <title>spi</title>
+
+ <indexterm zone="contrib-spi">
+ <primary>SPI</primary>
+ <secondary>examples</secondary>
+ </indexterm>
+
+ <para>
+ The <application>spi</application> module provides several workable examples
+ of using the <link linkend="spi">Server Programming Interface</link>
+ (<acronym>SPI</acronym>) and triggers. While these functions are of
+ some value in
+ their own right, they are even more useful as examples to modify for
+ your own purposes. The functions are general enough to be used
+ with any table, but you have to specify table and field names (as described
+ below) while creating a trigger.
+ </para>
+
+ <para>
+ Each of the groups of functions described below is provided as a
+ separately-installable extension.
+ </para>
+
+ <sect2>
+ <title>refint &mdash; Functions for Implementing Referential Integrity</title>
+
+ <para>
+ <function>check_primary_key()</function> and
+ <function>check_foreign_key()</function> are used to check foreign key constraints.
+ (This functionality is long since superseded by the built-in foreign
+ key mechanism, of course, but the module is still useful as an example.)
+ </para>
+
+ <para>
+ <function>check_primary_key()</function> checks the referencing table.
+ To use, create a <literal>BEFORE INSERT OR UPDATE</literal> trigger using this
+ function on a table referencing another table. Specify as the trigger
+ arguments: the referencing table's column name(s) which form the foreign
+ key, the referenced table name, and the column names in the referenced table
+ which form the primary/unique key. To handle multiple foreign
+ keys, create a trigger for each reference.
+ </para>
+
+ <para>
+ <function>check_foreign_key()</function> checks the referenced table.
+ To use, create a <literal>BEFORE DELETE OR UPDATE</literal> trigger using this
+ function on a table referenced by other table(s). Specify as the trigger
+ arguments: the number of referencing tables for which the function has to
+ perform checking, the action if a referencing key is found
+ (<literal>cascade</literal> &mdash; to delete the referencing row,
+ <literal>restrict</literal> &mdash; to abort transaction if referencing keys
+ exist, <literal>setnull</literal> &mdash; to set referencing key fields to null),
+ the triggered table's column names which form the primary/unique key, then
+ the referencing table name and column names (repeated for as many
+ referencing tables as were specified by first argument). Note that the
+ primary/unique key columns should be marked NOT NULL and should have a
+ unique index.
+ </para>
+
+ <para>
+ There are examples in <filename>refint.example</filename>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>autoinc &mdash; Functions for Autoincrementing Fields</title>
+
+ <para>
+ <function>autoinc()</function> is a trigger that stores the next value of
+ a sequence into an integer field. This has some overlap with the
+ built-in <quote>serial column</quote> feature, but it is not the same:
+ <function>autoinc()</function> will override attempts to substitute a
+ different field value during inserts, and optionally it can be
+ used to increment the field during updates, too.
+ </para>
+
+ <para>
+ To use, create a <literal>BEFORE INSERT</literal> (or optionally <literal>BEFORE
+ INSERT OR UPDATE</literal>) trigger using this function. Specify two
+ trigger arguments: the name of the integer column to be modified,
+ and the name of the sequence object that will supply values.
+ (Actually, you can specify any number of pairs of such names, if
+ you'd like to update more than one autoincrementing column.)
+ </para>
+
+ <para>
+ There is an example in <filename>autoinc.example</filename>.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>insert_username &mdash; Functions for Tracking Who Changed a Table</title>
+
+ <para>
+ <function>insert_username()</function> is a trigger that stores the current
+ user's name into a text field. This can be useful for tracking
+ who last modified a particular row within a table.
+ </para>
+
+ <para>
+ To use, create a <literal>BEFORE INSERT</literal> and/or <literal>UPDATE</literal>
+ trigger using this function. Specify a single trigger
+ argument: the name of the text column to be modified.
+ </para>
+
+ <para>
+ There is an example in <filename>insert_username.example</filename>.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>moddatetime &mdash; Functions for Tracking Last Modification Time</title>
+
+ <para>
+ <function>moddatetime()</function> is a trigger that stores the current
+ time into a <type>timestamp</type> field. This can be useful for tracking
+ the last modification time of a particular row within a table.
+ </para>
+
+ <para>
+ To use, create a <literal>BEFORE UPDATE</literal>
+ trigger using this function. Specify a single trigger
+ argument: the name of the column to be modified.
+ The column must be of type <type>timestamp</type> or <type>timestamp with
+ time zone</type>.
+ </para>
+
+ <para>
+ There is an example in <filename>moddatetime.example</filename>.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/contrib.sgml b/doc/src/sgml/contrib.sgml
new file mode 100644
index 0000000..4e7b87a
--- /dev/null
+++ b/doc/src/sgml/contrib.sgml
@@ -0,0 +1,206 @@
+<!-- doc/src/sgml/contrib.sgml -->
+
+<appendix id="contrib">
+ <title>Additional Supplied Modules</title>
+
+ <para>
+ This appendix and the next one contain information regarding the modules that
+ can be found in the <literal>contrib</literal> directory of the
+ <productname>PostgreSQL</productname> distribution.
+ These include porting tools, analysis utilities,
+ and plug-in features that are not part of the core PostgreSQL system,
+ mainly because they address a limited audience or are too experimental
+ to be part of the main source tree. This does not preclude their
+ usefulness.
+ </para>
+
+ <para>
+ This appendix covers extensions and other server plug-in modules found in
+ <literal>contrib</literal>. <xref linkend="contrib-prog"/> covers utility
+ programs.
+ </para>
+
+ <para>
+ When building from the source distribution, these components are not built
+ automatically, unless you build the "world" target
+ (see <xref linkend="build"/>).
+ You can build and install all of them by running:
+<screen>
+<userinput>make</userinput>
+<userinput>make install</userinput>
+</screen>
+ in the <literal>contrib</literal> directory of a configured source tree;
+ or to build and install
+ just one selected module, do the same in that module's subdirectory.
+ Many of the modules have regression tests, which can be executed by
+ running:
+<screen>
+<userinput>make check</userinput>
+</screen>
+ before installation or
+<screen>
+<userinput>make installcheck</userinput>
+</screen>
+ once you have a <productname>PostgreSQL</productname> server running.
+ </para>
+
+ <para>
+ If you are using a pre-packaged version of <productname>PostgreSQL</productname>,
+ these modules are typically made available as a separate subpackage,
+ such as <literal>postgresql-contrib</literal>.
+ </para>
+
+ <para>
+ Many modules supply new user-defined functions, operators, or types.
+ To make use of one of these modules, after you have installed the code
+ you need to register the new SQL objects in the database system.
+ This is done by executing
+ a <xref linkend="sql-createextension"/> command. In a fresh database,
+ you can simply do
+
+<programlisting>
+CREATE EXTENSION <replaceable>module_name</replaceable>;
+</programlisting>
+
+ This command registers the new SQL objects in the current database only,
+ so you need to run it in each database that you want
+ the module's facilities to be available in. Alternatively, run it in
+ database <literal>template1</literal> so that the extension will be copied into
+ subsequently-created databases by default.
+ </para>
+
+ <para>
+ For all these modules, <command>CREATE EXTENSION</command> must be run
+ by a database superuser, unless the module is
+ considered <quote>trusted</quote>, in which case it can be run by any
+ user who has <literal>CREATE</literal> privilege on the current
+ database. Modules that are trusted are identified as such in the
+ sections that follow. Generally, trusted modules are ones that cannot
+ provide access to outside-the-database functionality.
+ </para>
+
+ <para>
+ Many modules allow you to install their objects in a schema of your
+ choice. To do that, add <literal>SCHEMA
+ <replaceable>schema_name</replaceable></literal> to the <command>CREATE EXTENSION</command>
+ command. By default, the objects will be placed in your current creation
+ target schema, which in turn defaults to <literal>public</literal>.
+ </para>
+
+ <para>
+ Note, however, that some of these modules are not <quote>extensions</quote>
+ in this sense, but are loaded into the server in some other way, for instance
+ by way of
+ <xref linkend="guc-shared-preload-libraries"/>. See the documentation of each
+ module for details.
+ </para>
+
+ &adminpack;
+ &amcheck;
+ &auth-delay;
+ &auto-explain;
+ &basebackup-to-shell;
+ &basic-archive;
+ &bloom;
+ &btree-gin;
+ &btree-gist;
+ &citext;
+ &cube;
+ &dblink;
+ &dict-int;
+ &dict-xsyn;
+ &earthdistance;
+ &file-fdw;
+ &fuzzystrmatch;
+ &hstore;
+ &intagg;
+ &intarray;
+ &isn;
+ &lo;
+ &ltree;
+ &oldsnapshot;
+ &pageinspect;
+ &passwordcheck;
+ &pgbuffercache;
+ &pgcrypto;
+ &pgfreespacemap;
+ &pgprewarm;
+ &pgrowlocks;
+ &pgstatstatements;
+ &pgstattuple;
+ &pgsurgery;
+ &pgtrgm;
+ &pgvisibility;
+ &pgwalinspect;
+ &postgres-fdw;
+ &seg;
+ &sepgsql;
+ &contrib-spi;
+ &sslinfo;
+ &tablefunc;
+ &tcn;
+ &test-decoding;
+ &tsm-system-rows;
+ &tsm-system-time;
+ &unaccent;
+ &uuid-ossp;
+ &xml2;
+
+</appendix>
+
+<!--
+These are two separate appendixes because it is difficult to mix regular
+sections (for extensions) and refentries (for programs) in one chapter or
+appendix. And we do want the programs as refentries so that we can produce man
+pages.
+-->
+
+<appendix id="contrib-prog">
+ <title>Additional Supplied Programs</title>
+
+ <para>
+ This appendix and the previous one contain information regarding the modules that
+ can be found in the <literal>contrib</literal> directory of the
+ <productname>PostgreSQL</productname> distribution. See <xref linkend="contrib"/> for
+ more information about the <literal>contrib</literal> section in general and
+ server extensions and plug-ins found in <literal>contrib</literal>
+ specifically.
+ </para>
+
+ <para>
+ This appendix covers utility programs found in <literal>contrib</literal>.
+ Once installed, either from source or a packaging system, they are found in
+ the <filename>bin</filename> directory of the
+ <productname>PostgreSQL</productname> installation and can be used like any
+ other program.
+ </para>
+
+ <sect1 id="contrib-prog-client">
+ <title>Client Applications</title>
+
+ <para>
+ This section covers <productname>PostgreSQL</productname> client
+ applications in <literal>contrib</literal>. They can be run from anywhere,
+ independent of where the database server resides. See
+ also <xref linkend="reference-client"/> for information about client
+ applications that are part of the core <productname>PostgreSQL</productname>
+ distribution.
+ </para>
+
+ &oid2name;
+ &vacuumlo;
+ </sect1>
+
+ <sect1 id="contrib-prog-server">
+ <title>Server Applications</title>
+
+ <para>
+ Some applications run on the <productname>PostgreSQL</productname> server
+ itself. Currently, no such applications are included in the
+ <literal>contrib</literal> directory. See also <xref
+ linkend="reference-server"/> for information about server applications that
+ are part of the core <productname>PostgreSQL</productname> distribution.
+ </para>
+
+ </sect1>
+</appendix>
diff --git a/doc/src/sgml/cube.sgml b/doc/src/sgml/cube.sgml
new file mode 100644
index 0000000..adf8dba
--- /dev/null
+++ b/doc/src/sgml/cube.sgml
@@ -0,0 +1,639 @@
+<!-- doc/src/sgml/cube.sgml -->
+
+<sect1 id="cube" xreflabel="cube">
+ <title>cube</title>
+
+ <indexterm zone="cube">
+ <primary>cube (extension)</primary>
+ </indexterm>
+
+ <para>
+ This module implements a data type <type>cube</type> for
+ representing multidimensional cubes.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Syntax</title>
+
+ <para>
+ <xref linkend="cube-repr-table"/> shows the valid external
+ representations for the <type>cube</type>
+ type. <replaceable>x</replaceable>, <replaceable>y</replaceable>, etc. denote
+ floating-point numbers.
+ </para>
+
+ <table id="cube-repr-table">
+ <title>Cube External Representations</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>External Syntax</entry>
+ <entry>Meaning</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal><replaceable>x</replaceable></literal></entry>
+ <entry>A one-dimensional point
+ (or, zero-length one-dimensional interval)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>(<replaceable>x</replaceable>)</literal></entry>
+ <entry>Same as above</entry>
+ </row>
+ <row>
+ <entry><literal><replaceable>x1</replaceable>,<replaceable>x2</replaceable>,...,<replaceable>xn</replaceable></literal></entry>
+ <entry>A point in n-dimensional space, represented internally as a
+ zero-volume cube
+ </entry>
+ </row>
+ <row>
+ <entry><literal>(<replaceable>x1</replaceable>,<replaceable>x2</replaceable>,...,<replaceable>xn</replaceable>)</literal></entry>
+ <entry>Same as above</entry>
+ </row>
+ <row>
+ <entry><literal>(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)</literal></entry>
+ <entry>A one-dimensional interval starting at <replaceable>x</replaceable> and ending at <replaceable>y</replaceable> or vice versa; the
+ order does not matter
+ </entry>
+ </row>
+ <row>
+ <entry><literal>[(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)]</literal></entry>
+ <entry>Same as above</entry>
+ </row>
+ <row>
+ <entry><literal>(<replaceable>x1</replaceable>,...,<replaceable>xn</replaceable>),(<replaceable>y1</replaceable>,...,<replaceable>yn</replaceable>)</literal></entry>
+ <entry>An n-dimensional cube represented by a pair of its diagonally
+ opposite corners
+ </entry>
+ </row>
+ <row>
+ <entry><literal>[(<replaceable>x1</replaceable>,...,<replaceable>xn</replaceable>),(<replaceable>y1</replaceable>,...,<replaceable>yn</replaceable>)]</literal></entry>
+ <entry>Same as above</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ It does not matter which order the opposite corners of a cube are
+ entered in. The <type>cube</type> functions
+ automatically swap values if needed to create a uniform
+ <quote>lower left &mdash; upper right</quote> internal representation.
+ When the corners coincide, <type>cube</type> stores only one corner
+ along with an <quote>is point</quote> flag to avoid wasting space.
+ </para>
+
+ <para>
+ White space is ignored on input, so
+ <literal>[(<replaceable>x</replaceable>),(<replaceable>y</replaceable>)]</literal> is the same as
+ <literal>[ ( <replaceable>x</replaceable> ), ( <replaceable>y</replaceable> ) ]</literal>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Precision</title>
+
+ <para>
+ Values are stored internally as 64-bit floating point numbers. This means
+ that numbers with more than about 16 significant digits will be truncated.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Usage</title>
+
+ <para>
+ <xref linkend="cube-operators-table"/> shows the specialized operators
+ provided for type <type>cube</type>.
+ </para>
+
+ <table id="cube-operators-table">
+ <title>Cube Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>&amp;&amp;</literal> <type>cube</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do the cubes overlap?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>@&gt;</literal> <type>cube</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first cube contain the second?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>&lt;@</literal> <type>cube</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first cube contained in the second?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>-&gt;</literal> <type>integer</type>
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Extracts the <parameter>n</parameter>-th coordinate of the cube
+ (counting from 1).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>~&gt;</literal> <type>integer</type>
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Extracts the <parameter>n</parameter>-th coordinate of the cube,
+ counting in the following way: <parameter>n</parameter> = 2
+ * <parameter>k</parameter> - 1 means lower bound
+ of <parameter>k</parameter>-th dimension, <parameter>n</parameter> = 2
+ * <parameter>k</parameter> means upper bound of
+ <parameter>k</parameter>-th dimension. Negative
+ <parameter>n</parameter> denotes the inverse value of the corresponding
+ positive coordinate. This operator is designed for KNN-GiST support.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>&lt;-&gt;</literal> <type>cube</type>
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Computes the Euclidean distance between the two cubes.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>&lt;#&gt;</literal> <type>cube</type>
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Computes the taxicab (L-1 metric) distance between the two cubes.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>cube</type> <literal>&lt;=&gt;</literal> <type>cube</type>
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Computes the Chebyshev (L-inf metric) distance between the two cubes.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In addition to the above operators, the usual comparison
+ operators shown in <xref linkend="functions-comparison-op-table"/> are
+ available for type <type>cube</type>. These
+ operators first compare the first coordinates, and if those are equal,
+ compare the second coordinates, etc. They exist mainly to support the
+ b-tree index operator class for <type>cube</type>, which can be useful for
+ example if you would like a UNIQUE constraint on a <type>cube</type> column.
+ Otherwise, this ordering is not of much practical use.
+ </para>
+
+ <para>
+ The <filename>cube</filename> module also provides a GiST index operator class for
+ <type>cube</type> values.
+ A <type>cube</type> GiST index can be used to search for values using the
+ <literal>=</literal>, <literal>&amp;&amp;</literal>, <literal>@&gt;</literal>, and
+ <literal>&lt;@</literal> operators in <literal>WHERE</literal> clauses.
+ </para>
+
+ <para>
+ In addition, a <type>cube</type> GiST index can be used to find nearest
+ neighbors using the metric operators
+ <literal>&lt;-&gt;</literal>, <literal>&lt;#&gt;</literal>, and
+ <literal>&lt;=&gt;</literal> in <literal>ORDER BY</literal> clauses.
+ For example, the nearest neighbor of the 3-D point (0.5, 0.5, 0.5)
+ could be found efficiently with:
+<programlisting>
+SELECT c FROM test ORDER BY c &lt;-&gt; cube(array[0.5,0.5,0.5]) LIMIT 1;
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>~&gt;</literal> operator can also be used in this way to
+ efficiently retrieve the first few values sorted by a selected coordinate.
+ For example, to get the first few cubes ordered by the first coordinate
+ (lower left corner) ascending one could use the following query:
+<programlisting>
+SELECT c FROM test ORDER BY c ~&gt; 1 LIMIT 5;
+</programlisting>
+ And to get 2-D cubes ordered by the first coordinate of the upper right
+ corner descending:
+<programlisting>
+SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
+</programlisting>
+ </para>
+
+ <para>
+ <xref linkend="cube-functions-table"/> shows the available functions.
+ </para>
+
+ <table id="cube-functions-table">
+ <title>Cube Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube</function> ( <type>float8</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a one dimensional cube with both coordinates the same.
+ </para>
+ <para>
+ <literal>cube(1)</literal>
+ <returnvalue>(1)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube</function> ( <type>float8</type>, <type>float8</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a one dimensional cube.
+ </para>
+ <para>
+ <literal>cube(1, 2)</literal>
+ <returnvalue>(1),(2)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube</function> ( <type>float8[]</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a zero-volume cube using the coordinates defined by the array.
+ </para>
+ <para>
+ <literal>cube(ARRAY[1,2,3])</literal>
+ <returnvalue>(1, 2, 3)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube</function> ( <type>float8[]</type>, <type>float8[]</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a cube with upper right and lower left coordinates as defined by
+ the two arrays, which must be of the same length.
+ </para>
+ <para>
+ <literal>cube(ARRAY[1,2], ARRAY[3,4])</literal>
+ <returnvalue>(1, 2),(3, 4)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube</function> ( <type>cube</type>, <type>float8</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a new cube by adding a dimension on to an existing cube,
+ with the same values for both endpoints of the new coordinate. This
+ is useful for building cubes piece by piece from calculated values.
+ </para>
+ <para>
+ <literal>cube('(1,2),(3,4)'::cube, 5)</literal>
+ <returnvalue>(1, 2, 5),(3, 4, 5)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube</function> ( <type>cube</type>, <type>float8</type>, <type>float8</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a new cube by adding a dimension on to an existing cube. This is
+ useful for building cubes piece by piece from calculated values.
+ </para>
+ <para>
+ <literal>cube('(1,2),(3,4)'::cube, 5, 6)</literal>
+ <returnvalue>(1, 2, 5),(3, 4, 6)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_dim</function> ( <type>cube</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of dimensions of the cube.
+ </para>
+ <para>
+ <literal>cube_dim('(1,2),(3,4)')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_ll_coord</function> ( <type>cube</type>, <type>integer</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the <parameter>n</parameter>-th coordinate value for the lower
+ left corner of the cube.
+ </para>
+ <para>
+ <literal>cube_ll_coord('(1,2),(3,4)', 2)</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_ur_coord</function> ( <type>cube</type>, <type>integer</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the <parameter>n</parameter>-th coordinate value for the
+ upper right corner of the cube.
+ </para>
+ <para>
+ <literal>cube_ur_coord('(1,2),(3,4)', 2)</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_is_point</function> ( <type>cube</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if the cube is a point, that is,
+ the two defining corners are the same.
+ </para>
+ <para>
+ <literal>cube_is_point(cube(1,1))</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_distance</function> ( <type>cube</type>, <type>cube</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the distance between two cubes. If both
+ cubes are points, this is the normal distance function.
+ </para>
+ <para>
+ <literal>cube_distance('(1,2)', '(3,4)')</literal>
+ <returnvalue>2.8284271247461903</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_subset</function> ( <type>cube</type>, <type>integer[]</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Makes a new cube from an existing cube, using a list of
+ dimension indexes from an array. Can be used to extract the endpoints
+ of a single dimension, or to drop dimensions, or to reorder them as
+ desired.
+ </para>
+ <para>
+ <literal>cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2])</literal>
+ <returnvalue>(3),(7)</returnvalue>
+ </para>
+ <para>
+ <literal>cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1])</literal>
+ <returnvalue>(5, 3, 1, 1),(8, 7, 6, 6)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_union</function> ( <type>cube</type>, <type>cube</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Produces the union of two cubes.
+ </para>
+ <para>
+ <literal>cube_union('(1,2)', '(3,4)')</literal>
+ <returnvalue>(1, 2),(3, 4)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_inter</function> ( <type>cube</type>, <type>cube</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Produces the intersection of two cubes.
+ </para>
+ <para>
+ <literal>cube_inter('(1,2)', '(3,4)')</literal>
+ <returnvalue>(3, 4),(1, 2)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>cube_enlarge</function> ( <parameter>c</parameter> <type>cube</type>, <parameter>r</parameter> <type>double</type>, <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Increases the size of the cube by the specified
+ radius <parameter>r</parameter> in at least <parameter>n</parameter>
+ dimensions. If the radius is negative the cube is shrunk instead.
+ All defined dimensions are changed by the
+ radius <parameter>r</parameter>. Lower-left coordinates are decreased
+ by <parameter>r</parameter> and upper-right coordinates are increased
+ by <parameter>r</parameter>. If a lower-left coordinate is increased
+ to more than the corresponding upper-right coordinate (this can only
+ happen when <parameter>r</parameter> &lt; 0) than both coordinates are
+ set to their average. If <parameter>n</parameter> is greater than the
+ number of defined dimensions and the cube is being enlarged
+ (<parameter>r</parameter> &gt; 0), then extra dimensions are added to
+ make <parameter>n</parameter> altogether; 0 is used as the initial
+ value for the extra coordinates. This function is useful for creating
+ bounding boxes around a point for searching for nearby points.
+ </para>
+ <para>
+ <literal>cube_enlarge('(1,2),(3,4)', 0.5, 3)</literal>
+ <returnvalue>(0.5, 1.5, -0.5),(3.5, 4.5, 0.5)</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Defaults</title>
+
+ <para>
+ I believe this union:
+ </para>
+<programlisting>
+select cube_union('(0,5,2),(2,3,1)', '0');
+cube_union
+-------------------
+(0, 0, 0),(2, 5, 2)
+(1 row)
+</programlisting>
+
+ <para>
+ does not contradict common sense, neither does the intersection
+ </para>
+
+<programlisting>
+select cube_inter('(0,-1),(1,1)', '(-2),(2)');
+cube_inter
+-------------
+(0, 0),(1, 0)
+(1 row)
+</programlisting>
+
+ <para>
+ In all binary operations on differently-dimensioned cubes, I assume the
+ lower-dimensional one to be a Cartesian projection, i. e., having zeroes
+ in place of coordinates omitted in the string representation. The above
+ examples are equivalent to:
+ </para>
+
+<programlisting>
+cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
+cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');
+</programlisting>
+
+ <para>
+ The following containment predicate uses the point syntax,
+ while in fact the second argument is internally represented by a box.
+ This syntax makes it unnecessary to define a separate point type
+ and functions for (box,point) predicates.
+ </para>
+
+<programlisting>
+select cube_contains('(0,0),(1,1)', '0.5,0.5');
+cube_contains
+--------------
+t
+(1 row)
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Notes</title>
+
+ <para>
+ For examples of usage, see the regression test <filename>sql/cube.sql</filename>.
+ </para>
+
+ <para>
+ To make it harder for people to break things, there
+ is a limit of 100 on the number of dimensions of cubes. This is set
+ in <filename>cubedata.h</filename> if you need something bigger.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Credits</title>
+
+ <para>
+ Original author: Gene Selkov, Jr. <email>selkovjr@mcs.anl.gov</email>,
+ Mathematics and Computer Science Division, Argonne National Laboratory.
+ </para>
+
+ <para>
+ My thanks are primarily to Prof. Joe Hellerstein
+ (<ulink url="https://dsf.berkeley.edu/jmh/"></ulink>) for elucidating the
+ gist of the GiST (<ulink url="http://gist.cs.berkeley.edu/"></ulink>), and
+ to his former student Andy Dong for his example written for Illustra.
+ I am also grateful to all Postgres developers, present and past, for
+ enabling myself to create my own world and live undisturbed in it. And I
+ would like to acknowledge my gratitude to Argonne Lab and to the
+ U.S. Department of Energy for the years of faithful support of my database
+ research.
+ </para>
+
+ <para>
+ Minor updates to this package were made by Bruno Wolff III
+ <email>bruno@wolff.to</email> in August/September of 2002. These include
+ changing the precision from single precision to double precision and adding
+ some new functions.
+ </para>
+
+ <para>
+ Additional updates were made by Joshua Reich <email>josh@root.net</email> in
+ July 2006. These include <literal>cube(float8[], float8[])</literal> and
+ cleaning up the code to use the V1 call protocol instead of the deprecated
+ V0 protocol.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/custom-rmgr.sgml b/doc/src/sgml/custom-rmgr.sgml
new file mode 100644
index 0000000..2893016
--- /dev/null
+++ b/doc/src/sgml/custom-rmgr.sgml
@@ -0,0 +1,98 @@
+<!-- doc/src/sgml/custom-rmgr.sgml -->
+
+<chapter id="custom-rmgr">
+ <title>Custom WAL Resource Managers</title>
+
+ <para>
+ This chapter explains the interface between the core
+ <productname>PostgreSQL</productname> system and custom WAL resource
+ managers, which enable extensions to integrate directly with the <link
+ linkend="wal"><acronym>WAL</acronym></link>.
+ </para>
+ <para>
+ An extension, especially a <link linkend="tableam">Table Access
+ Method</link> or <link linkend="indexam">Index Access Method</link>, may
+ need to use WAL for recovery, replication, and/or <link
+ linkend="logicaldecoding">Logical Decoding</link>. Custom resource managers
+ are a more flexible alternative to <link linkend="generic-wal">Generic
+ WAL</link> (which does not support logical decoding), but more complex for
+ an extension to implement.
+ </para>
+ <para>
+ To create a new custom WAL resource manager, first define an
+ <structname>RmgrData</structname> structure with implementations for the
+ resource manager methods. Refer to
+ <filename>src/backend/access/transam/README</filename> and
+ <filename>src/include/access/xlog_internal.h</filename> in the
+ <productname>PostgreSQL</productname> source.
+<programlisting>
+/*
+ * Method table for resource managers.
+ *
+ * This struct must be kept in sync with the PG_RMGR definition in
+ * rmgr.c.
+ *
+ * rm_identify must return a name for the record based on xl_info (without
+ * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named
+ * "VACUUM". rm_desc can then be called to obtain additional detail for the
+ * record, if available (e.g. the last block).
+ *
+ * rm_mask takes as input a page modified by the resource manager and masks
+ * out bits that shouldn't be flagged by wal_consistency_checking.
+ *
+ * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). If rm_name is
+ * NULL, the corresponding RmgrTable entry is considered invalid.
+ */
+typedef struct RmgrData
+{
+ const char *rm_name;
+ void (*rm_redo) (XLogReaderState *record);
+ void (*rm_desc) (StringInfo buf, XLogReaderState *record);
+ const char *(*rm_identify) (uint8 info);
+ void (*rm_startup) (void);
+ void (*rm_cleanup) (void);
+ void (*rm_mask) (char *pagedata, BlockNumber blkno);
+ void (*rm_decode) (struct LogicalDecodingContext *ctx,
+ struct XLogRecordBuffer *buf);
+} RmgrData;
+</programlisting>
+ </para>
+ <para>
+ Then, register your new resource
+ manager.
+
+<programlisting>
+/*
+ * Register a new custom WAL resource manager.
+ *
+ * Resource manager IDs must be globally unique across all extensions. Refer
+ * to https://wiki.postgresql.org/wiki/CustomWALResourceManagers to reserve a
+ * unique RmgrId for your extension, to avoid conflicts with other extension
+ * developers. During development, use RM_EXPERIMENTAL_ID to avoid needlessly
+ * reserving a new ID.
+ */
+extern void RegisterCustomRmgr(RmgrId rmid, RmgrData *rmgr);
+</programlisting>
+ <function>RegisterCustomRmgr</function> must be called from the
+ extension module's <link linkend="xfunc-c-dynload">_PG_init</link> function.
+ While developing a new extension, use <literal>RM_EXPERIMENTAL_ID</literal>
+ for <parameter>rmid</parameter>. When you are ready to release the extension
+ to users, reserve a new resource manager ID at the <ulink
+ url="https://wiki.postgresql.org/wiki/CustomWALResourceManagers">Custom WAL
+ Resource Manager</ulink> page.
+ </para>
+
+ <para>
+ Place the extension module implementing the custom resource manager in <xref
+ linkend="guc-shared-preload-libraries"/> so that it will be loaded early
+ during <productname>PostgreSQL</productname> startup.
+ </para>
+ <note>
+ <para>
+ The extension must remain in shared_preload_libraries as long as any
+ custom WAL records may exist in the system. Otherwise
+ <productname>PostgreSQL</productname> will not be able to apply or decode
+ the custom WAL records, which may prevent the server from starting.
+ </para>
+ </note>
+</chapter>
diff --git a/doc/src/sgml/custom-scan.sgml b/doc/src/sgml/custom-scan.sgml
new file mode 100644
index 0000000..cd989e7
--- /dev/null
+++ b/doc/src/sgml/custom-scan.sgml
@@ -0,0 +1,407 @@
+<!-- doc/src/sgml/custom-scan.sgml -->
+
+<chapter id="custom-scan">
+ <title>Writing a Custom Scan Provider</title>
+
+ <indexterm zone="custom-scan">
+ <primary>custom scan provider</primary>
+ <secondary>handler for</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> supports a set of experimental facilities which
+ are intended to allow extension modules to add new scan types to the system.
+ Unlike a <link linkend="fdwhandler">foreign data wrapper</link>, which is only
+ responsible for knowing how to scan its own foreign tables, a custom scan
+ provider can provide an alternative method of scanning any relation in the
+ system. Typically, the motivation for writing a custom scan provider will
+ be to allow the use of some optimization not supported by the core
+ system, such as caching or some form of hardware acceleration. This chapter
+ outlines how to write a new custom scan provider.
+ </para>
+
+ <para>
+ Implementing a new type of custom scan is a three-step process. First,
+ during planning, it is necessary to generate access paths representing a
+ scan using the proposed strategy. Second, if one of those access paths
+ is selected by the planner as the optimal strategy for scanning a
+ particular relation, the access path must be converted to a plan.
+ Finally, it must be possible to execute the plan and generate the same
+ results that would have been generated for any other access path targeting
+ the same relation.
+ </para>
+
+ <sect1 id="custom-scan-path">
+ <title>Creating Custom Scan Paths</title>
+
+ <para>
+ A custom scan provider will typically add paths for a base relation by
+ setting the following hook, which is called after the core code has
+ generated all the access paths it can for the relation (except for
+ Gather paths, which are made after this call so that they can use
+ partial paths added by the hook):
+<programlisting>
+typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
+ RelOptInfo *rel,
+ Index rti,
+ RangeTblEntry *rte);
+extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
+</programlisting>
+ </para>
+
+ <para>
+ Although this hook function can be used to examine, modify, or remove
+ paths generated by the core system, a custom scan provider will typically
+ confine itself to generating <structname>CustomPath</structname> objects and adding
+ them to <literal>rel</literal> using <function>add_path</function>. The custom scan
+ provider is responsible for initializing the <structname>CustomPath</structname>
+ object, which is declared like this:
+<programlisting>
+typedef struct CustomPath
+{
+ Path path;
+ uint32 flags;
+ List *custom_paths;
+ List *custom_private;
+ const CustomPathMethods *methods;
+} CustomPath;
+</programlisting>
+ </para>
+
+ <para>
+ <structfield>path</structfield> must be initialized as for any other path, including
+ the row-count estimate, start and total cost, and sort ordering provided
+ by this path. <structfield>flags</structfield> is a bit mask, which
+ specifies whether the scan provider can support certain optional
+ capabilities. <structfield>flags</structfield> should include
+ <literal>CUSTOMPATH_SUPPORT_BACKWARD_SCAN</literal> if the custom path can support
+ a backward scan, <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> if it
+ can support mark and restore,
+ and <literal>CUSTOMPATH_SUPPORT_PROJECTION</literal> if it can perform
+ projections. (If <literal>CUSTOMPATH_SUPPORT_PROJECTION</literal> is not
+ set, the scan node will only be asked to produce Vars of the scanned
+ relation; while if that flag is set, the scan node must be able to
+ evaluate scalar expressions over these Vars.)
+ An optional <structfield>custom_paths</structfield> is a list of <structname>Path</structname>
+ nodes used by this custom-path node; these will be transformed into
+ <structname>Plan</structname> nodes by planner.
+ <structfield>custom_private</structfield> can be used to store the custom path's
+ private data. Private data should be stored in a form that can be handled
+ by <literal>nodeToString</literal>, so that debugging routines that attempt to
+ print the custom path will work as designed. <structfield>methods</structfield> must
+ point to a (usually statically allocated) object implementing the required
+ custom path methods, which are further detailed below.
+ </para>
+
+ <para>
+ A custom scan provider can also provide join paths. Just as for base
+ relations, such a path must produce the same output as would normally be
+ produced by the join it replaces. To do this, the join provider should
+ set the following hook, and then within the hook function,
+ create <structname>CustomPath</structname> path(s) for the join relation.
+<programlisting>
+typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
+ RelOptInfo *joinrel,
+ RelOptInfo *outerrel,
+ RelOptInfo *innerrel,
+ JoinType jointype,
+ JoinPathExtraData *extra);
+extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;
+</programlisting>
+
+ This hook will be invoked repeatedly for the same join relation, with
+ different combinations of inner and outer relations; it is the
+ responsibility of the hook to minimize duplicated work.
+ </para>
+
+ <sect2 id="custom-scan-path-callbacks">
+ <title>Custom Scan Path Callbacks</title>
+
+ <para>
+<programlisting>
+Plan *(*PlanCustomPath) (PlannerInfo *root,
+ RelOptInfo *rel,
+ CustomPath *best_path,
+ List *tlist,
+ List *clauses,
+ List *custom_plans);
+</programlisting>
+ Convert a custom path to a finished plan. The return value will generally
+ be a <literal>CustomScan</literal> object, which the callback must allocate and
+ initialize. See <xref linkend="custom-scan-plan"/> for more details.
+ </para>
+
+ <para>
+<programlisting>
+List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
+ List *custom_private,
+ RelOptInfo *child_rel);
+</programlisting>
+ This callback is called while converting a path parameterized by the
+ top-most parent of the given child relation <literal>child_rel</literal>
+ to be parameterized by the child relation. The callback is used to
+ reparameterize any paths or translate any expression nodes saved in the
+ given <literal>custom_private</literal> member of a
+ <structname>CustomPath</structname>. The callback may use
+ <literal>reparameterize_path_by_child</literal>,
+ <literal>adjust_appendrel_attrs</literal> or
+ <literal>adjust_appendrel_attrs_multilevel</literal> as required.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="custom-scan-plan">
+ <title>Creating Custom Scan Plans</title>
+
+ <para>
+ A custom scan is represented in a finished plan tree using the following
+ structure:
+<programlisting>
+typedef struct CustomScan
+{
+ Scan scan;
+ uint32 flags;
+ List *custom_plans;
+ List *custom_exprs;
+ List *custom_private;
+ List *custom_scan_tlist;
+ Bitmapset *custom_relids;
+ const CustomScanMethods *methods;
+} CustomScan;
+</programlisting>
+ </para>
+
+ <para>
+ <structfield>scan</structfield> must be initialized as for any other scan, including
+ estimated costs, target lists, qualifications, and so on.
+ <structfield>flags</structfield> is a bit mask with the same meaning as in
+ <structname>CustomPath</structname>.
+ <structfield>custom_plans</structfield> can be used to store child
+ <structname>Plan</structname> nodes.
+ <structfield>custom_exprs</structfield> should be used to
+ store expression trees that will need to be fixed up by
+ <filename>setrefs.c</filename> and <filename>subselect.c</filename>, while
+ <structfield>custom_private</structfield> should be used to store other private data
+ that is only used by the custom scan provider itself.
+ <structfield>custom_scan_tlist</structfield> can be NIL when scanning a base
+ relation, indicating that the custom scan returns scan tuples that match
+ the base relation's row type. Otherwise it is a target list describing
+ the actual scan tuples. <structfield>custom_scan_tlist</structfield> must be
+ provided for joins, and could be provided for scans if the custom scan
+ provider can compute some non-Var expressions.
+ <structfield>custom_relids</structfield> is set by the core code to the set of
+ relations (range table indexes) that this scan node handles; except when
+ this scan is replacing a join, it will have only one member.
+ <structfield>methods</structfield> must point to a (usually statically allocated)
+ object implementing the required custom scan methods, which are further
+ detailed below.
+ </para>
+
+ <para>
+ When a <structname>CustomScan</structname> scans a single relation,
+ <structfield>scan.scanrelid</structfield> must be the range table index of the table
+ to be scanned. When it replaces a join, <structfield>scan.scanrelid</structfield>
+ should be zero.
+ </para>
+
+ <para>
+ Plan trees must be able to be duplicated using <function>copyObject</function>,
+ so all the data stored within the <quote>custom</quote> fields must consist of
+ nodes that that function can handle. Furthermore, custom scan providers
+ cannot substitute a larger structure that embeds
+ a <structname>CustomScan</structname> for the structure itself, as would be possible
+ for a <structname>CustomPath</structname> or <structname>CustomScanState</structname>.
+ </para>
+
+ <sect2 id="custom-scan-plan-callbacks">
+ <title>Custom Scan Plan Callbacks</title>
+ <para>
+<programlisting>
+Node *(*CreateCustomScanState) (CustomScan *cscan);
+</programlisting>
+ Allocate a <structname>CustomScanState</structname> for this
+ <structname>CustomScan</structname>. The actual allocation will often be larger than
+ required for an ordinary <structname>CustomScanState</structname>, because many
+ providers will wish to embed that as the first field of a larger structure.
+ The value returned must have the node tag and <structfield>methods</structfield>
+ set appropriately, but other fields should be left as zeroes at this
+ stage; after <function>ExecInitCustomScan</function> performs basic initialization,
+ the <function>BeginCustomScan</function> callback will be invoked to give the
+ custom scan provider a chance to do whatever else is needed.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="custom-scan-execution">
+ <title>Executing Custom Scans</title>
+
+ <para>
+ When a <structfield>CustomScan</structfield> is executed, its execution state is
+ represented by a <structfield>CustomScanState</structfield>, which is declared as
+ follows:
+<programlisting>
+typedef struct CustomScanState
+{
+ ScanState ss;
+ uint32 flags;
+ const CustomExecMethods *methods;
+} CustomScanState;
+</programlisting>
+ </para>
+
+ <para>
+ <structfield>ss</structfield> is initialized as for any other scan state,
+ except that if the scan is for a join rather than a base relation,
+ <literal>ss.ss_currentRelation</literal> is left NULL.
+ <structfield>flags</structfield> is a bit mask with the same meaning as in
+ <structname>CustomPath</structname> and <structname>CustomScan</structname>.
+ <structfield>methods</structfield> must point to a (usually statically allocated)
+ object implementing the required custom scan state methods, which are
+ further detailed below. Typically, a <structname>CustomScanState</structname>, which
+ need not support <function>copyObject</function>, will actually be a larger
+ structure embedding the above as its first member.
+ </para>
+
+ <sect2 id="custom-scan-execution-callbacks">
+ <title>Custom Scan Execution Callbacks</title>
+
+ <para>
+<programlisting>
+void (*BeginCustomScan) (CustomScanState *node,
+ EState *estate,
+ int eflags);
+</programlisting>
+ Complete initialization of the supplied <structname>CustomScanState</structname>.
+ Standard fields have been initialized by <function>ExecInitCustomScan</function>,
+ but any private fields should be initialized here.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
+</programlisting>
+ Fetch the next scan tuple. If any tuples remain, it should fill
+ <literal>ps_ResultTupleSlot</literal> with the next tuple in the current scan
+ direction, and then return the tuple slot. If not,
+ <literal>NULL</literal> or an empty slot should be returned.
+ </para>
+
+ <para>
+<programlisting>
+void (*EndCustomScan) (CustomScanState *node);
+</programlisting>
+ Clean up any private data associated with the <literal>CustomScanState</literal>.
+ This method is required, but it does not need to do anything if there is
+ no associated data or it will be cleaned up automatically.
+ </para>
+
+ <para>
+<programlisting>
+void (*ReScanCustomScan) (CustomScanState *node);
+</programlisting>
+ Rewind the current scan to the beginning and prepare to rescan the
+ relation.
+ </para>
+
+ <para>
+<programlisting>
+void (*MarkPosCustomScan) (CustomScanState *node);
+</programlisting>
+ Save the current scan position so that it can subsequently be restored
+ by the <function>RestrPosCustomScan</function> callback. This callback is
+ optional, and need only be supplied if the
+ <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> flag is set.
+ </para>
+
+ <para>
+<programlisting>
+void (*RestrPosCustomScan) (CustomScanState *node);
+</programlisting>
+ Restore the previous scan position as saved by the
+ <function>MarkPosCustomScan</function> callback. This callback is optional,
+ and need only be supplied if the
+ <literal>CUSTOMPATH_SUPPORT_MARK_RESTORE</literal> flag is set.
+ </para>
+
+ <para>
+<programlisting>
+Size (*EstimateDSMCustomScan) (CustomScanState *node,
+ ParallelContext *pcxt);
+</programlisting>
+ Estimate the amount of dynamic shared memory that will be required
+ for parallel operation. This may be higher than the amount that will
+ actually be used, but it must not be lower. The return value is in bytes.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ </para>
+
+ <para>
+<programlisting>
+void (*InitializeDSMCustomScan) (CustomScanState *node,
+ ParallelContext *pcxt,
+ void *coordinate);
+</programlisting>
+ Initialize the dynamic shared memory that will be required for parallel
+ operation. <literal>coordinate</literal> points to a shared memory area of
+ size equal to the return value of <function>EstimateDSMCustomScan</function>.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ </para>
+
+ <para>
+<programlisting>
+void (*ReInitializeDSMCustomScan) (CustomScanState *node,
+ ParallelContext *pcxt,
+ void *coordinate);
+</programlisting>
+ Re-initialize the dynamic shared memory required for parallel operation
+ when the custom-scan plan node is about to be re-scanned.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ Recommended practice is that this callback reset only shared state,
+ while the <function>ReScanCustomScan</function> callback resets only local
+ state. Currently, this callback will be called
+ before <function>ReScanCustomScan</function>, but it's best not to rely on
+ that ordering.
+ </para>
+
+ <para>
+<programlisting>
+void (*InitializeWorkerCustomScan) (CustomScanState *node,
+ shm_toc *toc,
+ void *coordinate);
+</programlisting>
+ Initialize a parallel worker's local state based on the shared state
+ set up by the leader during <function>InitializeDSMCustomScan</function>.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ </para>
+
+ <para>
+<programlisting>
+void (*ShutdownCustomScan) (CustomScanState *node);
+</programlisting>
+ Release resources when it is anticipated the node will not be executed
+ to completion. This is not called in all cases; sometimes,
+ <literal>EndCustomScan</literal> may be called without this function having
+ been called first. Since the DSM segment used by parallel query is
+ destroyed just after this callback is invoked, custom scan providers that
+ wish to take some action before the DSM segment goes away should implement
+ this method.
+ </para>
+
+ <para>
+<programlisting>
+void (*ExplainCustomScan) (CustomScanState *node,
+ List *ancestors,
+ ExplainState *es);
+</programlisting>
+ Output additional information for <command>EXPLAIN</command> of a custom-scan
+ plan node. This callback is optional. Common data stored in the
+ <structname>ScanState</structname>, such as the target list and scan relation, will
+ be shown even without this callback, but the callback allows the display
+ of additional, private state.
+ </para>
+ </sect2>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
new file mode 100644
index 0000000..a903dcc
--- /dev/null
+++ b/doc/src/sgml/datatype.sgml
@@ -0,0 +1,5354 @@
+<!-- doc/src/sgml/datatype.sgml -->
+
+ <chapter id="datatype">
+ <title>Data Types</title>
+
+ <indexterm zone="datatype">
+ <primary>data type</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>type</primary>
+ <see>data type</see>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> has a rich set of native data
+ types available to users. Users can add new types to
+ <productname>PostgreSQL</productname> using the <xref
+ linkend="sql-createtype"/> command.
+ </para>
+
+ <para>
+ <xref linkend="datatype-table"/> shows all the built-in general-purpose data
+ types. Most of the alternative names listed in the
+ <quote>Aliases</quote> column are the names used internally by
+ <productname>PostgreSQL</productname> for historical reasons. In
+ addition, some internally used or deprecated types are available,
+ but are not listed here.
+ </para>
+
+ <table id="datatype-table">
+ <title>Data Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Aliases</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>bigint</type></entry>
+ <entry><type>int8</type></entry>
+ <entry>signed eight-byte integer</entry>
+ </row>
+
+ <row>
+ <entry><type>bigserial</type></entry>
+ <entry><type>serial8</type></entry>
+ <entry>autoincrementing eight-byte integer</entry>
+ </row>
+
+ <row>
+ <entry><type>bit [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry></entry>
+ <entry>fixed-length bit string</entry>
+ </row>
+
+ <row>
+ <entry><type>bit varying [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry><type>varbit [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry>variable-length bit string</entry>
+ </row>
+
+ <row>
+ <entry><type>boolean</type></entry>
+ <entry><type>bool</type></entry>
+ <entry>logical Boolean (true/false)</entry>
+ </row>
+
+ <row>
+ <entry><type>box</type></entry>
+ <entry></entry>
+ <entry>rectangular box on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>bytea</type></entry>
+ <entry></entry>
+ <entry>binary data (<quote>byte array</quote>)</entry>
+ </row>
+
+ <row>
+ <entry><type>character [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry><type>char [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry>fixed-length character string</entry>
+ </row>
+
+ <row>
+ <entry><type>character varying [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry><type>varchar [ (<replaceable>n</replaceable>) ]</type></entry>
+ <entry>variable-length character string</entry>
+ </row>
+
+ <row>
+ <entry><type>cidr</type></entry>
+ <entry></entry>
+ <entry>IPv4 or IPv6 network address</entry>
+ </row>
+
+ <row>
+ <entry><type>circle</type></entry>
+ <entry></entry>
+ <entry>circle on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>date</type></entry>
+ <entry></entry>
+ <entry>calendar date (year, month, day)</entry>
+ </row>
+
+ <row>
+ <entry><type>double precision</type></entry>
+ <entry><type>float8</type></entry>
+ <entry>double precision floating-point number (8 bytes)</entry>
+ </row>
+
+ <row>
+ <entry><type>inet</type></entry>
+ <entry></entry>
+ <entry>IPv4 or IPv6 host address</entry>
+ </row>
+
+ <row>
+ <entry><type>integer</type></entry>
+ <entry><type>int</type>, <type>int4</type></entry>
+ <entry>signed four-byte integer</entry>
+ </row>
+
+ <row>
+ <entry><type>interval [ <replaceable>fields</replaceable> ] [ (<replaceable>p</replaceable>) ]</type></entry>
+ <entry></entry>
+ <entry>time span</entry>
+ </row>
+
+ <row>
+ <entry><type>json</type></entry>
+ <entry></entry>
+ <entry>textual JSON data</entry>
+ </row>
+
+ <row>
+ <entry><type>jsonb</type></entry>
+ <entry></entry>
+ <entry>binary JSON data, decomposed</entry>
+ </row>
+
+ <row>
+ <entry><type>line</type></entry>
+ <entry></entry>
+ <entry>infinite line on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>lseg</type></entry>
+ <entry></entry>
+ <entry>line segment on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>macaddr</type></entry>
+ <entry></entry>
+ <entry>MAC (Media Access Control) address</entry>
+ </row>
+
+ <row>
+ <entry><type>macaddr8</type></entry>
+ <entry></entry>
+ <entry>MAC (Media Access Control) address (EUI-64 format)</entry>
+ </row>
+
+ <row>
+ <entry><type>money</type></entry>
+ <entry></entry>
+ <entry>currency amount</entry>
+ </row>
+
+ <row>
+ <entry><type>numeric [ (<replaceable>p</replaceable>,
+ <replaceable>s</replaceable>) ]</type></entry>
+ <entry><type>decimal [ (<replaceable>p</replaceable>,
+ <replaceable>s</replaceable>) ]</type></entry>
+ <entry>exact numeric of selectable precision</entry>
+ </row>
+
+ <row>
+ <entry><type>path</type></entry>
+ <entry></entry>
+ <entry>geometric path on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>pg_lsn</type></entry>
+ <entry></entry>
+ <entry><productname>PostgreSQL</productname> Log Sequence Number</entry>
+ </row>
+
+ <row>
+ <entry><type>pg_snapshot</type></entry>
+ <entry></entry>
+ <entry>user-level transaction ID snapshot</entry>
+ </row>
+
+ <row>
+ <entry><type>point</type></entry>
+ <entry></entry>
+ <entry>geometric point on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>polygon</type></entry>
+ <entry></entry>
+ <entry>closed geometric path on a plane</entry>
+ </row>
+
+ <row>
+ <entry><type>real</type></entry>
+ <entry><type>float4</type></entry>
+ <entry>single precision floating-point number (4 bytes)</entry>
+ </row>
+
+ <row>
+ <entry><type>smallint</type></entry>
+ <entry><type>int2</type></entry>
+ <entry>signed two-byte integer</entry>
+ </row>
+
+ <row>
+ <entry><type>smallserial</type></entry>
+ <entry><type>serial2</type></entry>
+ <entry>autoincrementing two-byte integer</entry>
+ </row>
+
+ <row>
+ <entry><type>serial</type></entry>
+ <entry><type>serial4</type></entry>
+ <entry>autoincrementing four-byte integer</entry>
+ </row>
+
+ <row>
+ <entry><type>text</type></entry>
+ <entry></entry>
+ <entry>variable-length character string</entry>
+ </row>
+
+ <row>
+ <entry><type>time [ (<replaceable>p</replaceable>) ] [ without time zone ]</type></entry>
+ <entry></entry>
+ <entry>time of day (no time zone)</entry>
+ </row>
+
+ <row>
+ <entry><type>time [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
+ <entry><type>timetz</type></entry>
+ <entry>time of day, including time zone</entry>
+ </row>
+
+ <row>
+ <entry><type>timestamp [ (<replaceable>p</replaceable>) ] [ without time zone ]</type></entry>
+ <entry></entry>
+ <entry>date and time (no time zone)</entry>
+ </row>
+
+ <row>
+ <entry><type>timestamp [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
+ <entry><type>timestamptz</type></entry>
+ <entry>date and time, including time zone</entry>
+ </row>
+
+ <row>
+ <entry><type>tsquery</type></entry>
+ <entry></entry>
+ <entry>text search query</entry>
+ </row>
+
+ <row>
+ <entry><type>tsvector</type></entry>
+ <entry></entry>
+ <entry>text search document</entry>
+ </row>
+
+ <row>
+ <entry><type>txid_snapshot</type></entry>
+ <entry></entry>
+ <entry>user-level transaction ID snapshot (deprecated; see <type>pg_snapshot</type>)</entry>
+ </row>
+
+ <row>
+ <entry><type>uuid</type></entry>
+ <entry></entry>
+ <entry>universally unique identifier</entry>
+ </row>
+
+ <row>
+ <entry><type>xml</type></entry>
+ <entry></entry>
+ <entry>XML data</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <title>Compatibility</title>
+ <para>
+ The following types (or spellings thereof) are specified by
+ <acronym>SQL</acronym>: <type>bigint</type>, <type>bit</type>, <type>bit
+ varying</type>, <type>boolean</type>, <type>char</type>,
+ <type>character varying</type>, <type>character</type>,
+ <type>varchar</type>, <type>date</type>, <type>double
+ precision</type>, <type>integer</type>, <type>interval</type>,
+ <type>numeric</type>, <type>decimal</type>, <type>real</type>,
+ <type>smallint</type>, <type>time</type> (with or without time zone),
+ <type>timestamp</type> (with or without time zone),
+ <type>xml</type>.
+ </para>
+ </note>
+
+ <para>
+ Each data type has an external representation determined by its input
+ and output functions. Many of the built-in types have
+ obvious external formats. However, several types are either unique
+ to <productname>PostgreSQL</productname>, such as geometric
+ paths, or have several possible formats, such as the date
+ and time types.
+ Some of the input and output functions are not invertible, i.e.,
+ the result of an output function might lose accuracy when compared to
+ the original input.
+ </para>
+
+ <sect1 id="datatype-numeric">
+ <title>Numeric Types</title>
+
+ <indexterm zone="datatype-numeric">
+ <primary>data type</primary>
+ <secondary>numeric</secondary>
+ </indexterm>
+
+ <para>
+ Numeric types consist of two-, four-, and eight-byte integers,
+ four- and eight-byte floating-point numbers, and selectable-precision
+ decimals. <xref linkend="datatype-numeric-table"/> lists the
+ available types.
+ </para>
+
+ <table id="datatype-numeric-table">
+ <title>Numeric Types</title>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <colspec colname="col4" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ <entry>Range</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>smallint</type></entry>
+ <entry>2 bytes</entry>
+ <entry>small-range integer</entry>
+ <entry>-32768 to +32767</entry>
+ </row>
+ <row>
+ <entry><type>integer</type></entry>
+ <entry>4 bytes</entry>
+ <entry>typical choice for integer</entry>
+ <entry>-2147483648 to +2147483647</entry>
+ </row>
+ <row>
+ <entry><type>bigint</type></entry>
+ <entry>8 bytes</entry>
+ <entry>large-range integer</entry>
+ <entry>-9223372036854775808 to +9223372036854775807</entry>
+ </row>
+
+ <row>
+ <entry><type>decimal</type></entry>
+ <entry>variable</entry>
+ <entry>user-specified precision, exact</entry>
+ <entry>up to 131072 digits before the decimal point; up to 16383 digits after the decimal point</entry>
+ </row>
+ <row>
+ <entry><type>numeric</type></entry>
+ <entry>variable</entry>
+ <entry>user-specified precision, exact</entry>
+ <entry>up to 131072 digits before the decimal point; up to 16383 digits after the decimal point</entry>
+ </row>
+
+ <row>
+ <entry><type>real</type></entry>
+ <entry>4 bytes</entry>
+ <entry>variable-precision, inexact</entry>
+ <entry>6 decimal digits precision</entry>
+ </row>
+ <row>
+ <entry><type>double precision</type></entry>
+ <entry>8 bytes</entry>
+ <entry>variable-precision, inexact</entry>
+ <entry>15 decimal digits precision</entry>
+ </row>
+
+ <row>
+ <entry><type>smallserial</type></entry>
+ <entry>2 bytes</entry>
+ <entry>small autoincrementing integer</entry>
+ <entry>1 to 32767</entry>
+ </row>
+
+ <row>
+ <entry><type>serial</type></entry>
+ <entry>4 bytes</entry>
+ <entry>autoincrementing integer</entry>
+ <entry>1 to 2147483647</entry>
+ </row>
+
+ <row>
+ <entry><type>bigserial</type></entry>
+ <entry>8 bytes</entry>
+ <entry>large autoincrementing integer</entry>
+ <entry>1 to 9223372036854775807</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The syntax of constants for the numeric types is described in
+ <xref linkend="sql-syntax-constants"/>. The numeric types have a
+ full set of corresponding arithmetic operators and
+ functions. Refer to <xref linkend="functions"/> for more
+ information. The following sections describe the types in detail.
+ </para>
+
+ <sect2 id="datatype-int">
+ <title>Integer Types</title>
+
+ <indexterm zone="datatype-int">
+ <primary>integer</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-int">
+ <primary>smallint</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-int">
+ <primary>bigint</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>int4</primary>
+ <see>integer</see>
+ </indexterm>
+
+ <indexterm>
+ <primary>int2</primary>
+ <see>smallint</see>
+ </indexterm>
+
+ <indexterm>
+ <primary>int8</primary>
+ <see>bigint</see>
+ </indexterm>
+
+ <para>
+ The types <type>smallint</type>, <type>integer</type>, and
+ <type>bigint</type> store whole numbers, that is, numbers without
+ fractional components, of various ranges. Attempts to store
+ values outside of the allowed range will result in an error.
+ </para>
+
+ <para>
+ The type <type>integer</type> is the common choice, as it offers
+ the best balance between range, storage size, and performance.
+ The <type>smallint</type> type is generally only used if disk
+ space is at a premium. The <type>bigint</type> type is designed to be
+ used when the range of the <type>integer</type> type is insufficient.
+ </para>
+
+ <para>
+ <acronym>SQL</acronym> only specifies the integer types
+ <type>integer</type> (or <type>int</type>),
+ <type>smallint</type>, and <type>bigint</type>. The
+ type names <type>int2</type>, <type>int4</type>, and
+ <type>int8</type> are extensions, which are also used by some
+ other <acronym>SQL</acronym> database systems.
+ </para>
+
+ </sect2>
+
+ <sect2 id="datatype-numeric-decimal">
+ <title>Arbitrary Precision Numbers</title>
+
+ <indexterm>
+ <primary>numeric (data type)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>arbitrary precision numbers</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>decimal</primary>
+ <see>numeric</see>
+ </indexterm>
+
+ <para>
+ The type <type>numeric</type> can store numbers with a
+ very large number of digits. It is especially recommended for
+ storing monetary amounts and other quantities where exactness is
+ required. Calculations with <type>numeric</type> values yield exact
+ results where possible, e.g., addition, subtraction, multiplication.
+ However, calculations on <type>numeric</type> values are very slow
+ compared to the integer types, or to the floating-point types
+ described in the next section.
+ </para>
+
+ <para>
+ We use the following terms below: The
+ <firstterm>precision</firstterm> of a <type>numeric</type>
+ is the total count of significant digits in the whole number,
+ that is, the number of digits to both sides of the decimal point.
+ The <firstterm>scale</firstterm> of a <type>numeric</type> is the
+ count of decimal digits in the fractional part, to the right of the
+ decimal point. So the number 23.5141 has a precision of 6 and a
+ scale of 4. Integers can be considered to have a scale of zero.
+ </para>
+
+ <para>
+ Both the maximum precision and the maximum scale of a
+ <type>numeric</type> column can be
+ configured. To declare a column of type <type>numeric</type> use
+ the syntax:
+<programlisting>
+NUMERIC(<replaceable>precision</replaceable>, <replaceable>scale</replaceable>)
+</programlisting>
+ The precision must be positive, while the scale may be positive or
+ negative (see below). Alternatively:
+<programlisting>
+NUMERIC(<replaceable>precision</replaceable>)
+</programlisting>
+ selects a scale of 0. Specifying:
+<programlisting>
+NUMERIC
+</programlisting>
+ without any precision or scale creates an <quote>unconstrained
+ numeric</quote> column in which numeric values of any length can be
+ stored, up to the implementation limits. A column of this kind will
+ not coerce input values to any particular scale, whereas
+ <type>numeric</type> columns with a declared scale will coerce
+ input values to that scale. (The <acronym>SQL</acronym> standard
+ requires a default scale of 0, i.e., coercion to integer
+ precision. We find this a bit useless. If you're concerned
+ about portability, always specify the precision and scale
+ explicitly.)
+ </para>
+
+ <note>
+ <para>
+ The maximum precision that can be explicitly specified in
+ a <type>numeric</type> type declaration is 1000. An
+ unconstrained <type>numeric</type> column is subject to the limits
+ described in <xref linkend="datatype-numeric-table"/>.
+ </para>
+ </note>
+
+ <para>
+ If the scale of a value to be stored is greater than the declared
+ scale of the column, the system will round the value to the specified
+ number of fractional digits. Then, if the number of digits to the
+ left of the decimal point exceeds the declared precision minus the
+ declared scale, an error is raised.
+ For example, a column declared as
+<programlisting>
+NUMERIC(3, 1)
+</programlisting>
+ will round values to 1 decimal place and can store values between
+ -99.9 and 99.9, inclusive.
+ </para>
+
+ <para>
+ Beginning in <productname>PostgreSQL</productname> 15, it is allowed
+ to declare a <type>numeric</type> column with a negative scale. Then
+ values will be rounded to the left of the decimal point. The
+ precision still represents the maximum number of non-rounded digits.
+ Thus, a column declared as
+<programlisting>
+NUMERIC(2, -3)
+</programlisting>
+ will round values to the nearest thousand and can store values
+ between -99000 and 99000, inclusive.
+ It is also allowed to declare a scale larger than the declared
+ precision. Such a column can only hold fractional values, and it
+ requires the number of zero digits just to the right of the decimal
+ point to be at least the declared scale minus the declared precision.
+ For example, a column declared as
+<programlisting>
+NUMERIC(3, 5)
+</programlisting>
+ will round values to 5 decimal places and can store values between
+ -0.00999 and 0.00999, inclusive.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> permits the scale in a
+ <type>numeric</type> type declaration to be any value in the range
+ -1000 to 1000. However, the <acronym>SQL</acronym> standard requires
+ the scale to be in the range 0 to <replaceable>precision</replaceable>.
+ Using scales outside that range may not be portable to other database
+ systems.
+ </para>
+ </note>
+
+ <para>
+ Numeric values are physically stored without any extra leading or
+ trailing zeroes. Thus, the declared precision and scale of a column
+ are maximums, not fixed allocations. (In this sense the <type>numeric</type>
+ type is more akin to <type>varchar(<replaceable>n</replaceable>)</type>
+ than to <type>char(<replaceable>n</replaceable>)</type>.) The actual storage
+ requirement is two bytes for each group of four decimal digits,
+ plus three to eight bytes overhead.
+ </para>
+
+ <indexterm>
+ <primary>infinity</primary>
+ <secondary>numeric (data type)</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NaN</primary>
+ <see>not a number</see>
+ </indexterm>
+
+ <indexterm>
+ <primary>not a number</primary>
+ <secondary>numeric (data type)</secondary>
+ </indexterm>
+
+ <para>
+ In addition to ordinary numeric values, the <type>numeric</type> type
+ has several special values:
+<literallayout>
+<literal>Infinity</literal>
+<literal>-Infinity</literal>
+<literal>NaN</literal>
+</literallayout>
+ These are adapted from the IEEE 754 standard, and represent
+ <quote>infinity</quote>, <quote>negative infinity</quote>, and
+ <quote>not-a-number</quote>, respectively. When writing these values
+ as constants in an SQL command, you must put quotes around them,
+ for example <literal>UPDATE table SET x = '-Infinity'</literal>.
+ On input, these strings are recognized in a case-insensitive manner.
+ The infinity values can alternatively be spelled <literal>inf</literal>
+ and <literal>-inf</literal>.
+ </para>
+
+ <para>
+ The infinity values behave as per mathematical expectations. For
+ example, <literal>Infinity</literal> plus any finite value equals
+ <literal>Infinity</literal>, as does <literal>Infinity</literal>
+ plus <literal>Infinity</literal>; but <literal>Infinity</literal>
+ minus <literal>Infinity</literal> yields <literal>NaN</literal> (not a
+ number), because it has no well-defined interpretation. Note that an
+ infinity can only be stored in an unconstrained <type>numeric</type>
+ column, because it notionally exceeds any finite precision limit.
+ </para>
+
+ <para>
+ The <literal>NaN</literal> (not a number) value is used to represent
+ undefined calculational results. In general, any operation with
+ a <literal>NaN</literal> input yields another <literal>NaN</literal>.
+ The only exception is when the operation's other inputs are such that
+ the same output would be obtained if the <literal>NaN</literal> were to
+ be replaced by any finite or infinite numeric value; then, that output
+ value is used for <literal>NaN</literal> too. (An example of this
+ principle is that <literal>NaN</literal> raised to the zero power
+ yields one.)
+ </para>
+
+ <note>
+ <para>
+ In most implementations of the <quote>not-a-number</quote> concept,
+ <literal>NaN</literal> is not considered equal to any other numeric
+ value (including <literal>NaN</literal>). In order to allow
+ <type>numeric</type> values to be sorted and used in tree-based
+ indexes, <productname>PostgreSQL</productname> treats <literal>NaN</literal>
+ values as equal, and greater than all non-<literal>NaN</literal>
+ values.
+ </para>
+ </note>
+
+ <para>
+ The types <type>decimal</type> and <type>numeric</type> are
+ equivalent. Both types are part of the <acronym>SQL</acronym>
+ standard.
+ </para>
+
+ <para>
+ When rounding values, the <type>numeric</type> type rounds ties away
+ from zero, while (on most machines) the <type>real</type>
+ and <type>double precision</type> types round ties to the nearest even
+ number. For example:
+
+<programlisting>
+SELECT x,
+ round(x::numeric) AS num_round,
+ round(x::double precision) AS dbl_round
+FROM generate_series(-3.5, 3.5, 1) as x;
+ x | num_round | dbl_round
+------+-----------+-----------
+ -3.5 | -4 | -4
+ -2.5 | -3 | -2
+ -1.5 | -2 | -2
+ -0.5 | -1 | -0
+ 0.5 | 1 | 0
+ 1.5 | 2 | 2
+ 2.5 | 3 | 2
+ 3.5 | 4 | 4
+(8 rows)
+</programlisting>
+ </para>
+ </sect2>
+
+
+ <sect2 id="datatype-float">
+ <title>Floating-Point Types</title>
+
+ <indexterm zone="datatype-float">
+ <primary>real</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-float">
+ <primary>double precision</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>float4</primary>
+ <see>real</see>
+ </indexterm>
+
+ <indexterm>
+ <primary>float8</primary>
+ <see>double precision</see>
+ </indexterm>
+
+ <indexterm zone="datatype-float">
+ <primary>floating point</primary>
+ </indexterm>
+
+ <para>
+ The data types <type>real</type> and <type>double precision</type> are
+ inexact, variable-precision numeric types. On all currently supported
+ platforms, these types are implementations of <acronym>IEEE</acronym>
+ Standard 754 for Binary Floating-Point Arithmetic (single and double
+ precision, respectively), to the extent that the underlying processor,
+ operating system, and compiler support it.
+ </para>
+
+ <para>
+ Inexact means that some values cannot be converted exactly to the
+ internal format and are stored as approximations, so that storing
+ and retrieving a value might show slight discrepancies.
+ Managing these errors and how they propagate through calculations
+ is the subject of an entire branch of mathematics and computer
+ science and will not be discussed here, except for the
+ following points:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If you require exact storage and calculations (such as for
+ monetary amounts), use the <type>numeric</type> type instead.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you want to do complicated calculations with these types
+ for anything important, especially if you rely on certain
+ behavior in boundary cases (infinity, underflow), you should
+ evaluate the implementation carefully.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Comparing two floating-point values for equality might not
+ always work as expected.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ On all currently supported platforms, the <type>real</type> type has a
+ range of around 1E-37 to 1E+37 with a precision of at least 6 decimal
+ digits. The <type>double precision</type> type has a range of around
+ 1E-307 to 1E+308 with a precision of at least 15 digits. Values that are
+ too large or too small will cause an error. Rounding might take place if
+ the precision of an input number is too high. Numbers too close to zero
+ that are not representable as distinct from zero will cause an underflow
+ error.
+ </para>
+
+ <para>
+ By default, floating point values are output in text form in their
+ shortest precise decimal representation; the decimal value produced is
+ closer to the true stored binary value than to any other value
+ representable in the same binary precision. (However, the output value is
+ currently never <emphasis>exactly</emphasis> midway between two
+ representable values, in order to avoid a widespread bug where input
+ routines do not properly respect the round-to-nearest-even rule.) This value will
+ use at most 17 significant decimal digits for <type>float8</type>
+ values, and at most 9 digits for <type>float4</type> values.
+ </para>
+
+ <note>
+ <para>
+ This shortest-precise output format is much faster to generate than the
+ historical rounded format.
+ </para>
+ </note>
+
+ <para>
+ For compatibility with output generated by older versions
+ of <productname>PostgreSQL</productname>, and to allow the output
+ precision to be reduced, the <xref linkend="guc-extra-float-digits"/>
+ parameter can be used to select rounded decimal output instead. Setting a
+ value of 0 restores the previous default of rounding the value to 6
+ (for <type>float4</type>) or 15 (for <type>float8</type>)
+ significant decimal digits. Setting a negative value reduces the number
+ of digits further; for example -2 would round output to 4 or 13 digits
+ respectively.
+ </para>
+
+ <para>
+ Any value of <xref linkend="guc-extra-float-digits"/> greater than 0
+ selects the shortest-precise format.
+ </para>
+
+ <note>
+ <para>
+ Applications that wanted precise values have historically had to set
+ <xref linkend="guc-extra-float-digits"/> to 3 to obtain them. For
+ maximum compatibility between versions, they should continue to do so.
+ </para>
+ </note>
+
+ <indexterm>
+ <primary>infinity</primary>
+ <secondary>floating point</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>not a number</primary>
+ <secondary>floating point</secondary>
+ </indexterm>
+
+ <para>
+ In addition to ordinary numeric values, the floating-point types
+ have several special values:
+<literallayout>
+<literal>Infinity</literal>
+<literal>-Infinity</literal>
+<literal>NaN</literal>
+</literallayout>
+ These represent the IEEE 754 special values
+ <quote>infinity</quote>, <quote>negative infinity</quote>, and
+ <quote>not-a-number</quote>, respectively. When writing these values
+ as constants in an SQL command, you must put quotes around them,
+ for example <literal>UPDATE table SET x = '-Infinity'</literal>. On input,
+ these strings are recognized in a case-insensitive manner.
+ The infinity values can alternatively be spelled <literal>inf</literal>
+ and <literal>-inf</literal>.
+ </para>
+
+ <note>
+ <para>
+ IEEE 754 specifies that <literal>NaN</literal> should not compare equal
+ to any other floating-point value (including <literal>NaN</literal>).
+ In order to allow floating-point values to be sorted and used
+ in tree-based indexes, <productname>PostgreSQL</productname> treats
+ <literal>NaN</literal> values as equal, and greater than all
+ non-<literal>NaN</literal> values.
+ </para>
+ </note>
+
+ <para>
+ <productname>PostgreSQL</productname> also supports the SQL-standard
+ notations <type>float</type> and
+ <type>float(<replaceable>p</replaceable>)</type> for specifying
+ inexact numeric types. Here, <replaceable>p</replaceable> specifies
+ the minimum acceptable precision in <emphasis>binary</emphasis> digits.
+ <productname>PostgreSQL</productname> accepts
+ <type>float(1)</type> to <type>float(24)</type> as selecting the
+ <type>real</type> type, while
+ <type>float(25)</type> to <type>float(53)</type> select
+ <type>double precision</type>. Values of <replaceable>p</replaceable>
+ outside the allowed range draw an error.
+ <type>float</type> with no precision specified is taken to mean
+ <type>double precision</type>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="datatype-serial">
+ <title>Serial Types</title>
+
+ <indexterm zone="datatype-serial">
+ <primary>smallserial</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-serial">
+ <primary>serial</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-serial">
+ <primary>bigserial</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-serial">
+ <primary>serial2</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-serial">
+ <primary>serial4</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-serial">
+ <primary>serial8</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>auto-increment</primary>
+ <see>serial</see>
+ </indexterm>
+
+ <indexterm>
+ <primary>sequence</primary>
+ <secondary>and serial type</secondary>
+ </indexterm>
+
+ <note>
+ <para>
+ This section describes a PostgreSQL-specific way to create an
+ autoincrementing column. Another way is to use the SQL-standard
+ identity column feature, described at <xref linkend="sql-createtable"/>.
+ </para>
+ </note>
+
+ <para>
+ The data types <type>smallserial</type>, <type>serial</type> and
+ <type>bigserial</type> are not true types, but merely
+ a notational convenience for creating unique identifier columns
+ (similar to the <literal>AUTO_INCREMENT</literal> property
+ supported by some other databases). In the current
+ implementation, specifying:
+
+<programlisting>
+CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
+ <replaceable class="parameter">colname</replaceable> SERIAL
+);
+</programlisting>
+
+ is equivalent to specifying:
+
+<programlisting>
+CREATE SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq AS integer;
+CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
+ <replaceable class="parameter">colname</replaceable> integer NOT NULL DEFAULT nextval('<replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq')
+);
+ALTER SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq OWNED BY <replaceable class="parameter">tablename</replaceable>.<replaceable class="parameter">colname</replaceable>;
+</programlisting>
+
+ Thus, we have created an integer column and arranged for its default
+ values to be assigned from a sequence generator. A <literal>NOT NULL</literal>
+ constraint is applied to ensure that a null value cannot be
+ inserted. (In most cases you would also want to attach a
+ <literal>UNIQUE</literal> or <literal>PRIMARY KEY</literal> constraint to prevent
+ duplicate values from being inserted by accident, but this is
+ not automatic.) Lastly, the sequence is marked as <quote>owned by</quote>
+ the column, so that it will be dropped if the column or table is dropped.
+ </para>
+
+ <note>
+ <para>
+ Because <type>smallserial</type>, <type>serial</type> and
+ <type>bigserial</type> are implemented using sequences, there may
+ be "holes" or gaps in the sequence of values which appears in the
+ column, even if no rows are ever deleted. A value allocated
+ from the sequence is still "used up" even if a row containing that
+ value is never successfully inserted into the table column. This
+ may happen, for example, if the inserting transaction rolls back.
+ See <literal>nextval()</literal> in <xref linkend="functions-sequence"/>
+ for details.
+ </para>
+ </note>
+
+ <para>
+ To insert the next value of the sequence into the <type>serial</type>
+ column, specify that the <type>serial</type>
+ column should be assigned its default value. This can be done
+ either by excluding the column from the list of columns in
+ the <command>INSERT</command> statement, or through the use of
+ the <literal>DEFAULT</literal> key word.
+ </para>
+
+ <para>
+ The type names <type>serial</type> and <type>serial4</type> are
+ equivalent: both create <type>integer</type> columns. The type
+ names <type>bigserial</type> and <type>serial8</type> work
+ the same way, except that they create a <type>bigint</type>
+ column. <type>bigserial</type> should be used if you anticipate
+ the use of more than 2<superscript>31</superscript> identifiers over the
+ lifetime of the table. The type names <type>smallserial</type> and
+ <type>serial2</type> also work the same way, except that they
+ create a <type>smallint</type> column.
+ </para>
+
+ <para>
+ The sequence created for a <type>serial</type> column is
+ automatically dropped when the owning column is dropped.
+ You can drop the sequence without dropping the column, but this
+ will force removal of the column default expression.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="datatype-money">
+ <title>Monetary Types</title>
+
+ <para>
+ The <type>money</type> type stores a currency amount with a fixed
+ fractional precision; see <xref
+ linkend="datatype-money-table"/>. The fractional precision is
+ determined by the database's <xref linkend="guc-lc-monetary"/> setting.
+ The range shown in the table assumes there are two fractional digits.
+ Input is accepted in a variety of formats, including integer and
+ floating-point literals, as well as typical
+ currency formatting, such as <literal>'$1,000.00'</literal>.
+ Output is generally in the latter form but depends on the locale.
+ </para>
+
+ <table id="datatype-money-table">
+ <title>Monetary Types</title>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <colspec colname="col4" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ <entry>Range</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>money</type></entry>
+ <entry>8 bytes</entry>
+ <entry>currency amount</entry>
+ <entry>-92233720368547758.08 to +92233720368547758.07</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Since the output of this data type is locale-sensitive, it might not
+ work to load <type>money</type> data into a database that has a different
+ setting of <varname>lc_monetary</varname>. To avoid problems, before
+ restoring a dump into a new database make sure <varname>lc_monetary</varname> has
+ the same or equivalent value as in the database that was dumped.
+ </para>
+
+ <para>
+ Values of the <type>numeric</type>, <type>int</type>, and
+ <type>bigint</type> data types can be cast to <type>money</type>.
+ Conversion from the <type>real</type> and <type>double precision</type>
+ data types can be done by casting to <type>numeric</type> first, for
+ example:
+<programlisting>
+SELECT '12.34'::float8::numeric::money;
+</programlisting>
+ However, this is not recommended. Floating point numbers should not be
+ used to handle money due to the potential for rounding errors.
+ </para>
+
+ <para>
+ A <type>money</type> value can be cast to <type>numeric</type> without
+ loss of precision. Conversion to other types could potentially lose
+ precision, and must also be done in two stages:
+<programlisting>
+SELECT '52093.89'::money::numeric::float8;
+</programlisting>
+ </para>
+
+ <para>
+ Division of a <type>money</type> value by an integer value is performed
+ with truncation of the fractional part towards zero. To get a rounded
+ result, divide by a floating-point value, or cast the <type>money</type>
+ value to <type>numeric</type> before dividing and back to <type>money</type>
+ afterwards. (The latter is preferable to avoid risking precision loss.)
+ When a <type>money</type> value is divided by another <type>money</type>
+ value, the result is <type>double precision</type> (i.e., a pure number,
+ not money); the currency units cancel each other out in the division.
+ </para>
+ </sect1>
+
+
+ <sect1 id="datatype-character">
+ <title>Character Types</title>
+
+ <indexterm zone="datatype-character">
+ <primary>character string</primary>
+ <secondary>data types</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>string</primary>
+ <see>character string</see>
+ </indexterm>
+
+ <indexterm zone="datatype-character">
+ <primary>character</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-character">
+ <primary>character varying</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-character">
+ <primary>text</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-character">
+ <primary>char</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-character">
+ <primary>varchar</primary>
+ </indexterm>
+
+ <table id="datatype-character-table">
+ <title>Character Types</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>character varying(<replaceable>n</replaceable>)</type>, <type>varchar(<replaceable>n</replaceable>)</type></entry>
+ <entry>variable-length with limit</entry>
+ </row>
+ <row>
+ <entry><type>character(<replaceable>n</replaceable>)</type>, <type>char(<replaceable>n</replaceable>)</type></entry>
+ <entry>fixed-length, blank padded</entry>
+ </row>
+ <row>
+ <entry><type>text</type></entry>
+ <entry>variable unlimited length</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="datatype-character-table"/> shows the
+ general-purpose character types available in
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ <acronym>SQL</acronym> defines two primary character types:
+ <type>character varying(<replaceable>n</replaceable>)</type> and
+ <type>character(<replaceable>n</replaceable>)</type>, where <replaceable>n</replaceable>
+ is a positive integer. Both of these types can store strings up to
+ <replaceable>n</replaceable> characters (not bytes) in length. An attempt to store a
+ longer string into a column of these types will result in an
+ error, unless the excess characters are all spaces, in which case
+ the string will be truncated to the maximum length. (This somewhat
+ bizarre exception is required by the <acronym>SQL</acronym>
+ standard.) If the string to be stored is shorter than the declared
+ length, values of type <type>character</type> will be space-padded;
+ values of type <type>character varying</type> will simply store the
+ shorter
+ string.
+ </para>
+
+ <para>
+ If one explicitly casts a value to <type>character
+ varying(<replaceable>n</replaceable>)</type> or
+ <type>character(<replaceable>n</replaceable>)</type>, then an over-length
+ value will be truncated to <replaceable>n</replaceable> characters without
+ raising an error. (This too is required by the
+ <acronym>SQL</acronym> standard.)
+ </para>
+
+ <para>
+ The notations <type>varchar(<replaceable>n</replaceable>)</type> and
+ <type>char(<replaceable>n</replaceable>)</type> are aliases for <type>character
+ varying(<replaceable>n</replaceable>)</type> and
+ <type>character(<replaceable>n</replaceable>)</type>, respectively.
+ If specified, the length must be greater than zero and cannot exceed
+ 10485760.
+ <type>character</type> without length specifier is equivalent to
+ <type>character(1)</type>. If <type>character varying</type> is used
+ without length specifier, the type accepts strings of any size. The
+ latter is a <productname>PostgreSQL</productname> extension.
+ </para>
+
+ <para>
+ In addition, <productname>PostgreSQL</productname> provides the
+ <type>text</type> type, which stores strings of any length.
+ Although the type <type>text</type> is not in the
+ <acronym>SQL</acronym> standard, several other SQL database
+ management systems have it as well.
+ </para>
+
+ <para>
+ Values of type <type>character</type> are physically padded
+ with spaces to the specified width <replaceable>n</replaceable>, and are
+ stored and displayed that way. However, trailing spaces are treated as
+ semantically insignificant and disregarded when comparing two values
+ of type <type>character</type>. In collations where whitespace
+ is significant, this behavior can produce unexpected results;
+ for example <command>SELECT 'a '::CHAR(2) collate "C" &lt;
+ E'a\n'::CHAR(2)</command> returns true, even though <literal>C</literal>
+ locale would consider a space to be greater than a newline.
+ Trailing spaces are removed when converting a <type>character</type> value
+ to one of the other string types. Note that trailing spaces
+ <emphasis>are</emphasis> semantically significant in
+ <type>character varying</type> and <type>text</type> values, and
+ when using pattern matching, that is <literal>LIKE</literal> and
+ regular expressions.
+ </para>
+
+ <para>
+ The characters that can be stored in any of these data types are
+ determined by the database character set, which is selected when
+ the database is created. Regardless of the specific character set,
+ the character with code zero (sometimes called NUL) cannot be stored.
+ For more information refer to <xref linkend="multibyte"/>.
+ </para>
+
+ <para>
+ The storage requirement for a short string (up to 126 bytes) is 1 byte
+ plus the actual string, which includes the space padding in the case of
+ <type>character</type>. Longer strings have 4 bytes of overhead instead
+ of 1. Long strings are compressed by the system automatically, so
+ the physical requirement on disk might be less. Very long values are also
+ stored in background tables so that they do not interfere with rapid
+ access to shorter column values. In any case, the longest
+ possible character string that can be stored is about 1 GB. (The
+ maximum value that will be allowed for <replaceable>n</replaceable> in the data
+ type declaration is less than that. It wouldn't be useful to
+ change this because with multibyte character encodings the number of
+ characters and bytes can be quite different. If you desire to
+ store long strings with no specific upper limit, use
+ <type>text</type> or <type>character varying</type> without a length
+ specifier, rather than making up an arbitrary length limit.)
+ </para>
+
+ <tip>
+ <para>
+ There is no performance difference among these three types,
+ apart from increased storage space when using the blank-padded
+ type, and a few extra CPU cycles to check the length when storing into
+ a length-constrained column. While
+ <type>character(<replaceable>n</replaceable>)</type> has performance
+ advantages in some other database systems, there is no such advantage in
+ <productname>PostgreSQL</productname>; in fact
+ <type>character(<replaceable>n</replaceable>)</type> is usually the slowest of
+ the three because of its additional storage costs. In most situations
+ <type>text</type> or <type>character varying</type> should be used
+ instead.
+ </para>
+ </tip>
+
+ <para>
+ Refer to <xref linkend="sql-syntax-strings"/> for information about
+ the syntax of string literals, and to <xref linkend="functions"/>
+ for information about available operators and functions.
+ </para>
+
+ <example>
+ <title>Using the Character Types</title>
+
+<programlisting>
+CREATE TABLE test1 (a character(4));
+INSERT INTO test1 VALUES ('ok');
+SELECT a, char_length(a) FROM test1; -- <co id="co.datatype-char"/>
+<computeroutput>
+ a | char_length
+------+-------------
+ ok | 2
+</computeroutput>
+
+CREATE TABLE test2 (b varchar(5));
+INSERT INTO test2 VALUES ('ok');
+INSERT INTO test2 VALUES ('good ');
+INSERT INTO test2 VALUES ('too long');
+<computeroutput>ERROR: value too long for type character varying(5)</computeroutput>
+INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation
+SELECT b, char_length(b) FROM test2;
+<computeroutput>
+ b | char_length
+-------+-------------
+ ok | 2
+ good | 5
+ too l | 5
+</computeroutput>
+</programlisting>
+ <calloutlist>
+ <callout arearefs="co.datatype-char">
+ <para>
+ The <function>char_length</function> function is discussed in
+ <xref linkend="functions-string"/>.
+ </para>
+ </callout>
+ </calloutlist>
+ </example>
+
+ <para>
+ There are two other fixed-length character types in
+ <productname>PostgreSQL</productname>, shown in <xref
+ linkend="datatype-character-special-table"/>.
+ These are not intended for general-purpose use, only for use
+ in the internal system catalogs.
+ The <type>name</type> type is used to store identifiers. Its
+ length is currently defined as 64 bytes (63 usable characters plus
+ terminator) but should be referenced using the constant
+ <symbol>NAMEDATALEN</symbol> in <literal>C</literal> source code.
+ The length is set at compile time (and
+ is therefore adjustable for special uses); the default maximum
+ length might change in a future release. The type <type>"char"</type>
+ (note the quotes) is different from <type>char(1)</type> in that it
+ only uses one byte of storage, and therefore can store only a single
+ ASCII character. It is used in the system
+ catalogs as a simplistic enumeration type.
+ </para>
+
+ <table id="datatype-character-special-table">
+ <title>Special Character Types</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>"char"</type></entry>
+ <entry>1 byte</entry>
+ <entry>single-byte internal type</entry>
+ </row>
+ <row>
+ <entry><type>name</type></entry>
+ <entry>64 bytes</entry>
+ <entry>internal type for object names</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="datatype-binary">
+ <title>Binary Data Types</title>
+
+ <indexterm zone="datatype-binary">
+ <primary>binary data</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-binary">
+ <primary>bytea</primary>
+ </indexterm>
+
+ <para>
+ The <type>bytea</type> data type allows storage of binary strings;
+ see <xref linkend="datatype-binary-table"/>.
+ </para>
+
+ <table id="datatype-binary-table">
+ <title>Binary Data Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>bytea</type></entry>
+ <entry>1 or 4 bytes plus the actual binary string</entry>
+ <entry>variable-length binary string</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ A binary string is a sequence of octets (or bytes). Binary
+ strings are distinguished from character strings in two
+ ways. First, binary strings specifically allow storing
+ octets of value zero and other <quote>non-printable</quote>
+ octets (usually, octets outside the decimal range 32 to 126).
+ Character strings disallow zero octets, and also disallow any
+ other octet values and sequences of octet values that are invalid
+ according to the database's selected character set encoding.
+ Second, operations on binary strings process the actual bytes,
+ whereas the processing of character strings depends on locale settings.
+ In short, binary strings are appropriate for storing data that the
+ programmer thinks of as <quote>raw bytes</quote>, whereas character
+ strings are appropriate for storing text.
+ </para>
+
+ <para>
+ The <type>bytea</type> type supports two
+ formats for input and output: <quote>hex</quote> format
+ and <productname>PostgreSQL</productname>'s historical
+ <quote>escape</quote> format. Both
+ of these are always accepted on input. The output format depends
+ on the configuration parameter <xref linkend="guc-bytea-output"/>;
+ the default is hex. (Note that the hex format was introduced in
+ <productname>PostgreSQL</productname> 9.0; earlier versions and some
+ tools don't understand it.)
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> standard defines a different binary
+ string type, called <type>BLOB</type> or <type>BINARY LARGE
+ OBJECT</type>. The input format is different from
+ <type>bytea</type>, but the provided functions and operators are
+ mostly the same.
+ </para>
+
+ <sect2>
+ <title><type>bytea</type> Hex Format</title>
+
+ <para>
+ The <quote>hex</quote> format encodes binary data as 2 hexadecimal digits
+ per byte, most significant nibble first. The entire string is
+ preceded by the sequence <literal>\x</literal> (to distinguish it
+ from the escape format). In some contexts, the initial backslash may
+ need to be escaped by doubling it
+ (see <xref linkend="sql-syntax-strings"/>).
+ For input, the hexadecimal digits can
+ be either upper or lower case, and whitespace is permitted between
+ digit pairs (but not within a digit pair nor in the starting
+ <literal>\x</literal> sequence).
+ The hex format is compatible with a wide
+ range of external applications and protocols, and it tends to be
+ faster to convert than the escape format, so its use is preferred.
+ </para>
+
+ <para>
+ Example:
+<programlisting>
+SET bytea_output = 'hex';
+
+SELECT '\xDEADBEEF'::bytea;
+ bytea
+------------
+ \xdeadbeef
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><type>bytea</type> Escape Format</title>
+
+ <para>
+ The <quote>escape</quote> format is the traditional
+ <productname>PostgreSQL</productname> format for the <type>bytea</type>
+ type. It
+ takes the approach of representing a binary string as a sequence
+ of ASCII characters, while converting those bytes that cannot be
+ represented as an ASCII character into special escape sequences.
+ If, from the point of view of the application, representing bytes
+ as characters makes sense, then this representation can be
+ convenient. But in practice it is usually confusing because it
+ fuzzes up the distinction between binary strings and character
+ strings, and also the particular escape mechanism that was chosen is
+ somewhat unwieldy. Therefore, this format should probably be avoided
+ for most new applications.
+ </para>
+
+ <para>
+ When entering <type>bytea</type> values in escape format,
+ octets of certain
+ values <emphasis>must</emphasis> be escaped, while all octet
+ values <emphasis>can</emphasis> be escaped. In
+ general, to escape an octet, convert it into its three-digit
+ octal value and precede it by a backslash.
+ Backslash itself (octet decimal value 92) can alternatively be represented by
+ double backslashes.
+ <xref linkend="datatype-binary-sqlesc"/>
+ shows the characters that must be escaped, and gives the alternative
+ escape sequences where applicable.
+ </para>
+
+ <table id="datatype-binary-sqlesc">
+ <title><type>bytea</type> Literal Escaped Octets</title>
+ <tgroup cols="5">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1.25*"/>
+ <colspec colname="col5" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Decimal Octet Value</entry>
+ <entry>Description</entry>
+ <entry>Escaped Input Representation</entry>
+ <entry>Example</entry>
+ <entry>Hex Representation</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>0</entry>
+ <entry>zero octet</entry>
+ <entry><literal>'\000'</literal></entry>
+ <entry><literal>'\000'::bytea</literal></entry>
+ <entry><literal>\x00</literal></entry>
+ </row>
+
+ <row>
+ <entry>39</entry>
+ <entry>single quote</entry>
+ <entry><literal>''''</literal> or <literal>'\047'</literal></entry>
+ <entry><literal>''''::bytea</literal></entry>
+ <entry><literal>\x27</literal></entry>
+ </row>
+
+ <row>
+ <entry>92</entry>
+ <entry>backslash</entry>
+ <entry><literal>'\\'</literal> or <literal>'\134'</literal></entry>
+ <entry><literal>'\\'::bytea</literal></entry>
+ <entry><literal>\x5c</literal></entry>
+ </row>
+
+ <row>
+ <entry>0 to 31 and 127 to 255</entry>
+ <entry><quote>non-printable</quote> octets</entry>
+ <entry><literal>'\<replaceable>xxx'</replaceable></literal> (octal value)</entry>
+ <entry><literal>'\001'::bytea</literal></entry>
+ <entry><literal>\x01</literal></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The requirement to escape <emphasis>non-printable</emphasis> octets
+ varies depending on locale settings. In some instances you can get away
+ with leaving them unescaped.
+ </para>
+
+ <para>
+ The reason that single quotes must be doubled, as shown
+ in <xref linkend="datatype-binary-sqlesc"/>, is that this
+ is true for any string literal in an SQL command. The generic
+ string-literal parser consumes the outermost single quotes
+ and reduces any pair of single quotes to one data character.
+ What the <type>bytea</type> input function sees is just one
+ single quote, which it treats as a plain data character.
+ However, the <type>bytea</type> input function treats
+ backslashes as special, and the other behaviors shown in
+ <xref linkend="datatype-binary-sqlesc"/> are implemented by
+ that function.
+ </para>
+
+ <para>
+ In some contexts, backslashes must be doubled compared to what is
+ shown above, because the generic string-literal parser will also
+ reduce pairs of backslashes to one data character;
+ see <xref linkend="sql-syntax-strings"/>.
+ </para>
+
+ <para>
+ <type>Bytea</type> octets are output in <literal>hex</literal>
+ format by default. If you change <xref linkend="guc-bytea-output"/>
+ to <literal>escape</literal>,
+ <quote>non-printable</quote> octets are converted to their
+ equivalent three-digit octal value and preceded by one backslash.
+ Most <quote>printable</quote> octets are output by their standard
+ representation in the client character set, e.g.:
+
+<programlisting>
+SET bytea_output = 'escape';
+
+SELECT 'abc \153\154\155 \052\251\124'::bytea;
+ bytea
+----------------
+ abc klm *\251T
+</programlisting>
+
+ The octet with decimal value 92 (backslash) is doubled in the output.
+ Details are in <xref linkend="datatype-binary-resesc"/>.
+ </para>
+
+ <table id="datatype-binary-resesc">
+ <title><type>bytea</type> Output Escaped Octets</title>
+ <tgroup cols="5">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1.25*"/>
+ <colspec colname="col5" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Decimal Octet Value</entry>
+ <entry>Description</entry>
+ <entry>Escaped Output Representation</entry>
+ <entry>Example</entry>
+ <entry>Output Result</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry>92</entry>
+ <entry>backslash</entry>
+ <entry><literal>\\</literal></entry>
+ <entry><literal>'\134'::bytea</literal></entry>
+ <entry><literal>\\</literal></entry>
+ </row>
+
+ <row>
+ <entry>0 to 31 and 127 to 255</entry>
+ <entry><quote>non-printable</quote> octets</entry>
+ <entry><literal>\<replaceable>xxx</replaceable></literal> (octal value)</entry>
+ <entry><literal>'\001'::bytea</literal></entry>
+ <entry><literal>\001</literal></entry>
+ </row>
+
+ <row>
+ <entry>32 to 126</entry>
+ <entry><quote>printable</quote> octets</entry>
+ <entry>client character set representation</entry>
+ <entry><literal>'\176'::bytea</literal></entry>
+ <entry><literal>~</literal></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Depending on the front end to <productname>PostgreSQL</productname> you use,
+ you might have additional work to do in terms of escaping and
+ unescaping <type>bytea</type> strings. For example, you might also
+ have to escape line feeds and carriage returns if your interface
+ automatically translates these.
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="datatype-datetime">
+ <title>Date/Time Types</title>
+
+ <indexterm zone="datatype-datetime">
+ <primary>date</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>time</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>time without time zone</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>time with time zone</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>timestamp</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>timestamptz</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>timestamp with time zone</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>timestamp without time zone</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>interval</primary>
+ </indexterm>
+ <indexterm zone="datatype-datetime">
+ <primary>time span</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> supports the full set of
+ <acronym>SQL</acronym> date and time types, shown in <xref
+ linkend="datatype-datetime-table"/>. The operations available
+ on these data types are described in
+ <xref linkend="functions-datetime"/>.
+ Dates are counted according to the Gregorian calendar, even in
+ years before that calendar was introduced (see <xref
+ linkend="datetime-units-history"/> for more information).
+ </para>
+
+ <table id="datatype-datetime-table">
+ <title>Date/Time Types</title>
+ <tgroup cols="6">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ <entry>Low Value</entry>
+ <entry>High Value</entry>
+ <entry>Resolution</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>timestamp [ (<replaceable>p</replaceable>) ] [ without time zone ]</type></entry>
+ <entry>8 bytes</entry>
+ <entry>both date and time (no time zone)</entry>
+ <entry>4713 BC</entry>
+ <entry>294276 AD</entry>
+ <entry>1 microsecond</entry>
+ </row>
+ <row>
+ <entry><type>timestamp [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
+ <entry>8 bytes</entry>
+ <entry>both date and time, with time zone</entry>
+ <entry>4713 BC</entry>
+ <entry>294276 AD</entry>
+ <entry>1 microsecond</entry>
+ </row>
+ <row>
+ <entry><type>date</type></entry>
+ <entry>4 bytes</entry>
+ <entry>date (no time of day)</entry>
+ <entry>4713 BC</entry>
+ <entry>5874897 AD</entry>
+ <entry>1 day</entry>
+ </row>
+ <row>
+ <entry><type>time [ (<replaceable>p</replaceable>) ] [ without time zone ]</type></entry>
+ <entry>8 bytes</entry>
+ <entry>time of day (no date)</entry>
+ <entry>00:00:00</entry>
+ <entry>24:00:00</entry>
+ <entry>1 microsecond</entry>
+ </row>
+ <row>
+ <entry><type>time [ (<replaceable>p</replaceable>) ] with time zone</type></entry>
+ <entry>12 bytes</entry>
+ <entry>time of day (no date), with time zone</entry>
+ <!-- see MAX_TZDISP_HOUR in datatype/timestamp.h -->
+ <entry>00:00:00+1559</entry>
+ <entry>24:00:00-1559</entry>
+ <entry>1 microsecond</entry>
+ </row>
+ <row>
+ <entry><type>interval [ <replaceable>fields</replaceable> ] [ (<replaceable>p</replaceable>) ]</type></entry>
+ <entry>16 bytes</entry>
+ <entry>time interval</entry>
+ <entry>-178000000 years</entry>
+ <entry>178000000 years</entry>
+ <entry>1 microsecond</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The SQL standard requires that writing just <type>timestamp</type>
+ be equivalent to <type>timestamp without time
+ zone</type>, and <productname>PostgreSQL</productname> honors that
+ behavior. <type>timestamptz</type> is accepted as an
+ abbreviation for <type>timestamp with time zone</type>; this is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </note>
+
+ <para>
+ <type>time</type>, <type>timestamp</type>, and
+ <type>interval</type> accept an optional precision value
+ <replaceable>p</replaceable> which specifies the number of
+ fractional digits retained in the seconds field. By default, there
+ is no explicit bound on precision. The allowed range of
+ <replaceable>p</replaceable> is from 0 to 6.
+ </para>
+
+ <para>
+ The <type>interval</type> type has an additional option, which is
+ to restrict the set of stored fields by writing one of these phrases:
+<literallayout class="monospaced">
+YEAR
+MONTH
+DAY
+HOUR
+MINUTE
+SECOND
+YEAR TO MONTH
+DAY TO HOUR
+DAY TO MINUTE
+DAY TO SECOND
+HOUR TO MINUTE
+HOUR TO SECOND
+MINUTE TO SECOND
+</literallayout>
+ Note that if both <replaceable>fields</replaceable> and
+ <replaceable>p</replaceable> are specified, the
+ <replaceable>fields</replaceable> must include <literal>SECOND</literal>,
+ since the precision applies only to the seconds.
+ </para>
+
+ <para>
+ The type <type>time with time zone</type> is defined by the SQL
+ standard, but the definition exhibits properties which lead to
+ questionable usefulness. In most cases, a combination of
+ <type>date</type>, <type>time</type>, <type>timestamp without time
+ zone</type>, and <type>timestamp with time zone</type> should
+ provide a complete range of date/time functionality required by
+ any application.
+ </para>
+
+ <sect2 id="datatype-datetime-input">
+ <title>Date/Time Input</title>
+
+ <para>
+ Date and time input is accepted in almost any reasonable format, including
+ ISO 8601, <acronym>SQL</acronym>-compatible,
+ traditional <productname>POSTGRES</productname>, and others.
+ For some formats, ordering of day, month, and year in date input is
+ ambiguous and there is support for specifying the expected
+ ordering of these fields. Set the <xref linkend="guc-datestyle"/> parameter
+ to <literal>MDY</literal> to select month-day-year interpretation,
+ <literal>DMY</literal> to select day-month-year interpretation, or
+ <literal>YMD</literal> to select year-month-day interpretation.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> is more flexible in
+ handling date/time input than the
+ <acronym>SQL</acronym> standard requires.
+ See <xref linkend="datetime-appendix"/>
+ for the exact parsing rules of date/time input and for the
+ recognized text fields including months, days of the week, and
+ time zones.
+ </para>
+
+ <para>
+ Remember that any date or time literal input needs to be enclosed
+ in single quotes, like text strings. Refer to
+ <xref linkend="sql-syntax-constants-generic"/> for more
+ information.
+ <acronym>SQL</acronym> requires the following syntax
+<synopsis>
+<replaceable>type</replaceable> [ (<replaceable>p</replaceable>) ] '<replaceable>value</replaceable>'
+</synopsis>
+ where <replaceable>p</replaceable> is an optional precision
+ specification giving the number of
+ fractional digits in the seconds field. Precision can be
+ specified for <type>time</type>, <type>timestamp</type>, and
+ <type>interval</type> types, and can range from 0 to 6.
+ If no precision is specified in a constant specification,
+ it defaults to the precision of the literal value (but not
+ more than 6 digits).
+ </para>
+
+ <sect3>
+ <title>Dates</title>
+
+ <indexterm>
+ <primary>date</primary>
+ </indexterm>
+
+ <para>
+ <xref linkend="datatype-datetime-date-table"/> shows some possible
+ inputs for the <type>date</type> type.
+ </para>
+
+ <table id="datatype-datetime-date-table">
+ <title>Date Input</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Example</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>1999-01-08</entry>
+ <entry>ISO 8601; January 8 in any mode
+ (recommended format)</entry>
+ </row>
+ <row>
+ <entry>January 8, 1999</entry>
+ <entry>unambiguous in any <varname>datestyle</varname> input mode</entry>
+ </row>
+ <row>
+ <entry>1/8/1999</entry>
+ <entry>January 8 in <literal>MDY</literal> mode;
+ August 1 in <literal>DMY</literal> mode</entry>
+ </row>
+ <row>
+ <entry>1/18/1999</entry>
+ <entry>January 18 in <literal>MDY</literal> mode;
+ rejected in other modes</entry>
+ </row>
+ <row>
+ <entry>01/02/03</entry>
+ <entry>January 2, 2003 in <literal>MDY</literal> mode;
+ February 1, 2003 in <literal>DMY</literal> mode;
+ February 3, 2001 in <literal>YMD</literal> mode
+ </entry>
+ </row>
+ <row>
+ <entry>1999-Jan-08</entry>
+ <entry>January 8 in any mode</entry>
+ </row>
+ <row>
+ <entry>Jan-08-1999</entry>
+ <entry>January 8 in any mode</entry>
+ </row>
+ <row>
+ <entry>08-Jan-1999</entry>
+ <entry>January 8 in any mode</entry>
+ </row>
+ <row>
+ <entry>99-Jan-08</entry>
+ <entry>January 8 in <literal>YMD</literal> mode, else error</entry>
+ </row>
+ <row>
+ <entry>08-Jan-99</entry>
+ <entry>January 8, except error in <literal>YMD</literal> mode</entry>
+ </row>
+ <row>
+ <entry>Jan-08-99</entry>
+ <entry>January 8, except error in <literal>YMD</literal> mode</entry>
+ </row>
+ <row>
+ <entry>19990108</entry>
+ <entry>ISO 8601; January 8, 1999 in any mode</entry>
+ </row>
+ <row>
+ <entry>990108</entry>
+ <entry>ISO 8601; January 8, 1999 in any mode</entry>
+ </row>
+ <row>
+ <entry>1999.008</entry>
+ <entry>year and day of year</entry>
+ </row>
+ <row>
+ <entry>J2451187</entry>
+ <entry>Julian date</entry>
+ </row>
+ <row>
+ <entry>January 8, 99 BC</entry>
+ <entry>year 99 BC</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect3>
+
+ <sect3>
+ <title>Times</title>
+
+ <indexterm>
+ <primary>time</primary>
+ </indexterm>
+ <indexterm>
+ <primary>time without time zone</primary>
+ </indexterm>
+ <indexterm>
+ <primary>time with time zone</primary>
+ </indexterm>
+
+ <para>
+ The time-of-day types are <type>time [
+ (<replaceable>p</replaceable>) ] without time zone</type> and
+ <type>time [ (<replaceable>p</replaceable>) ] with time
+ zone</type>. <type>time</type> alone is equivalent to
+ <type>time without time zone</type>.
+ </para>
+
+ <para>
+ Valid input for these types consists of a time of day followed
+ by an optional time zone. (See <xref
+ linkend="datatype-datetime-time-table"/>
+ and <xref linkend="datatype-timezone-table"/>.) If a time zone is
+ specified in the input for <type>time without time zone</type>,
+ it is silently ignored. You can also specify a date but it will
+ be ignored, except when you use a time zone name that involves a
+ daylight-savings rule, such as
+ <literal>America/New_York</literal>. In this case specifying the date
+ is required in order to determine whether standard or daylight-savings
+ time applies. The appropriate time zone offset is recorded in the
+ <type>time with time zone</type> value.
+ </para>
+
+ <table id="datatype-datetime-time-table">
+ <title>Time Input</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="3*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Example</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>04:05:06.789</literal></entry>
+ <entry>ISO 8601</entry>
+ </row>
+ <row>
+ <entry><literal>04:05:06</literal></entry>
+ <entry>ISO 8601</entry>
+ </row>
+ <row>
+ <entry><literal>04:05</literal></entry>
+ <entry>ISO 8601</entry>
+ </row>
+ <row>
+ <entry><literal>040506</literal></entry>
+ <entry>ISO 8601</entry>
+ </row>
+ <row>
+ <entry><literal>04:05 AM</literal></entry>
+ <entry>same as 04:05; AM does not affect value</entry>
+ </row>
+ <row>
+ <entry><literal>04:05 PM</literal></entry>
+ <entry>same as 16:05; input hour must be &lt;= 12</entry>
+ </row>
+ <row>
+ <entry><literal>04:05:06.789-8</literal></entry>
+ <entry>ISO 8601, with time zone as UTC offset</entry>
+ </row>
+ <row>
+ <entry><literal>04:05:06-08:00</literal></entry>
+ <entry>ISO 8601, with time zone as UTC offset</entry>
+ </row>
+ <row>
+ <entry><literal>04:05-08:00</literal></entry>
+ <entry>ISO 8601, with time zone as UTC offset</entry>
+ </row>
+ <row>
+ <entry><literal>040506-08</literal></entry>
+ <entry>ISO 8601, with time zone as UTC offset</entry>
+ </row>
+ <row>
+ <entry><literal>040506+0730</literal></entry>
+ <entry>ISO 8601, with fractional-hour time zone as UTC offset</entry>
+ </row>
+ <row>
+ <entry><literal>040506+07:30:00</literal></entry>
+ <entry>UTC offset specified to seconds (not allowed in ISO 8601)</entry>
+ </row>
+ <row>
+ <entry><literal>04:05:06 PST</literal></entry>
+ <entry>time zone specified by abbreviation</entry>
+ </row>
+ <row>
+ <entry><literal>2003-04-12 04:05:06 America/New_York</literal></entry>
+ <entry>time zone specified by full name</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table tocentry="1" id="datatype-timezone-table">
+ <title>Time Zone Input</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Example</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>PST</literal></entry>
+ <entry>Abbreviation (for Pacific Standard Time)</entry>
+ </row>
+ <row>
+ <entry><literal>America/New_York</literal></entry>
+ <entry>Full time zone name</entry>
+ </row>
+ <row>
+ <entry><literal>PST8PDT</literal></entry>
+ <entry>POSIX-style time zone specification</entry>
+ </row>
+ <row>
+ <entry><literal>-8:00:00</literal></entry>
+ <entry>UTC offset for PST</entry>
+ </row>
+ <row>
+ <entry><literal>-8:00</literal></entry>
+ <entry>UTC offset for PST (ISO 8601 extended format)</entry>
+ </row>
+ <row>
+ <entry><literal>-800</literal></entry>
+ <entry>UTC offset for PST (ISO 8601 basic format)</entry>
+ </row>
+ <row>
+ <entry><literal>-8</literal></entry>
+ <entry>UTC offset for PST (ISO 8601 basic format)</entry>
+ </row>
+ <row>
+ <entry><literal>zulu</literal></entry>
+ <entry>Military abbreviation for UTC</entry>
+ </row>
+ <row>
+ <entry><literal>z</literal></entry>
+ <entry>Short form of <literal>zulu</literal> (also in ISO 8601)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Refer to <xref linkend="datatype-timezones"/> for more information on how
+ to specify time zones.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Time Stamps</title>
+
+ <indexterm>
+ <primary>timestamp</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>timestamp with time zone</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>timestamp without time zone</primary>
+ </indexterm>
+
+ <para>
+ Valid input for the time stamp types consists of the concatenation
+ of a date and a time, followed by an optional time zone,
+ followed by an optional <literal>AD</literal> or <literal>BC</literal>.
+ (Alternatively, <literal>AD</literal>/<literal>BC</literal> can appear
+ before the time zone, but this is not the preferred ordering.)
+ Thus:
+
+<programlisting>
+1999-01-08 04:05:06
+</programlisting>
+ and:
+<programlisting>
+1999-01-08 04:05:06 -8:00
+</programlisting>
+
+ are valid values, which follow the <acronym>ISO</acronym> 8601
+ standard. In addition, the common format:
+<programlisting>
+January 8 04:05:06 1999 PST
+</programlisting>
+ is supported.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> standard differentiates
+ <type>timestamp without time zone</type>
+ and <type>timestamp with time zone</type> literals by the presence of a
+ <quote>+</quote> or <quote>-</quote> symbol and time zone offset after
+ the time. Hence, according to the standard,
+
+<programlisting>
+TIMESTAMP '2004-10-19 10:23:54'
+</programlisting>
+
+ is a <type>timestamp without time zone</type>, while
+
+<programlisting>
+TIMESTAMP '2004-10-19 10:23:54+02'
+</programlisting>
+
+ is a <type>timestamp with time zone</type>.
+ <productname>PostgreSQL</productname> never examines the content of a
+ literal string before determining its type, and therefore will treat
+ both of the above as <type>timestamp without time zone</type>. To
+ ensure that a literal is treated as <type>timestamp with time
+ zone</type>, give it the correct explicit type:
+
+<programlisting>
+TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
+</programlisting>
+
+ In a literal that has been determined to be <type>timestamp without time
+ zone</type>, <productname>PostgreSQL</productname> will silently ignore
+ any time zone indication.
+ That is, the resulting value is derived from the date/time
+ fields in the input value, and is not adjusted for time zone.
+ </para>
+
+ <para>
+ For <type>timestamp with time zone</type>, the internally stored
+ value is always in UTC (Universal
+ Coordinated Time, traditionally known as Greenwich Mean Time,
+ <acronym>GMT</acronym>). An input value that has an explicit
+ time zone specified is converted to UTC using the appropriate offset
+ for that time zone. If no time zone is stated in the input string,
+ then it is assumed to be in the time zone indicated by the system's
+ <xref linkend="guc-timezone"/> parameter, and is converted to UTC using the
+ offset for the <varname>timezone</varname> zone.
+ </para>
+
+ <para>
+ When a <type>timestamp with time
+ zone</type> value is output, it is always converted from UTC to the
+ current <varname>timezone</varname> zone, and displayed as local time in that
+ zone. To see the time in another time zone, either change
+ <varname>timezone</varname> or use the <literal>AT TIME ZONE</literal> construct
+ (see <xref linkend="functions-datetime-zoneconvert"/>).
+ </para>
+
+ <para>
+ Conversions between <type>timestamp without time zone</type> and
+ <type>timestamp with time zone</type> normally assume that the
+ <type>timestamp without time zone</type> value should be taken or given
+ as <varname>timezone</varname> local time. A different time zone can
+ be specified for the conversion using <literal>AT TIME ZONE</literal>.
+ </para>
+ </sect3>
+
+ <sect3 id="datatype-datetime-special-values">
+ <title>Special Values</title>
+
+ <indexterm>
+ <primary>time</primary>
+ <secondary>constants</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>date</primary>
+ <secondary>constants</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> supports several
+ special date/time input values for convenience, as shown in <xref
+ linkend="datatype-datetime-special-table"/>. The values
+ <literal>infinity</literal> and <literal>-infinity</literal>
+ are specially represented inside the system and will be displayed
+ unchanged; but the others are simply notational shorthands
+ that will be converted to ordinary date/time values when read.
+ (In particular, <literal>now</literal> and related strings are converted
+ to a specific time value as soon as they are read.)
+ All of these values need to be enclosed in single quotes when used
+ as constants in SQL commands.
+ </para>
+
+ <table id="datatype-datetime-special-table">
+ <title>Special Date/Time Inputs</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Input String</entry>
+ <entry>Valid Types</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>epoch</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
+ <entry>1970-01-01 00:00:00+00 (Unix system time zero)</entry>
+ </row>
+ <row>
+ <entry><literal>infinity</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
+ <entry>later than all other time stamps</entry>
+ </row>
+ <row>
+ <entry><literal>-infinity</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
+ <entry>earlier than all other time stamps</entry>
+ </row>
+ <row>
+ <entry><literal>now</literal></entry>
+ <entry><type>date</type>, <type>time</type>, <type>timestamp</type></entry>
+ <entry>current transaction's start time</entry>
+ </row>
+ <row>
+ <entry><literal>today</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
+ <entry>midnight (<literal>00:00</literal>) today</entry>
+ </row>
+ <row>
+ <entry><literal>tomorrow</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
+ <entry>midnight (<literal>00:00</literal>) tomorrow</entry>
+ </row>
+ <row>
+ <entry><literal>yesterday</literal></entry>
+ <entry><type>date</type>, <type>timestamp</type></entry>
+ <entry>midnight (<literal>00:00</literal>) yesterday</entry>
+ </row>
+ <row>
+ <entry><literal>allballs</literal></entry>
+ <entry><type>time</type></entry>
+ <entry>00:00:00.00 UTC</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The following <acronym>SQL</acronym>-compatible functions can also
+ be used to obtain the current time value for the corresponding data
+ type:
+ <literal>CURRENT_DATE</literal>, <literal>CURRENT_TIME</literal>,
+ <literal>CURRENT_TIMESTAMP</literal>, <literal>LOCALTIME</literal>,
+ <literal>LOCALTIMESTAMP</literal>. (See <xref
+ linkend="functions-datetime-current"/>.) Note that these are
+ SQL functions and are <emphasis>not</emphasis> recognized in data input strings.
+ </para>
+
+ <caution>
+ <para>
+ While the input strings <literal>now</literal>,
+ <literal>today</literal>, <literal>tomorrow</literal>,
+ and <literal>yesterday</literal> are fine to use in interactive SQL
+ commands, they can have surprising behavior when the command is
+ saved to be executed later, for example in prepared statements,
+ views, and function definitions. The string can be converted to a
+ specific time value that continues to be used long after it becomes
+ stale. Use one of the SQL functions instead in such contexts.
+ For example, <literal>CURRENT_DATE + 1</literal> is safer than
+ <literal>'tomorrow'::date</literal>.
+ </para>
+ </caution>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="datatype-datetime-output">
+ <title>Date/Time Output</title>
+
+ <indexterm>
+ <primary>date</primary>
+ <secondary>output format</secondary>
+ <seealso>formatting</seealso>
+ </indexterm>
+
+ <indexterm>
+ <primary>time</primary>
+ <secondary>output format</secondary>
+ <seealso>formatting</seealso>
+ </indexterm>
+
+ <para>
+ The output format of the date/time types can be set to one of the four
+ styles ISO 8601,
+ <acronym>SQL</acronym> (Ingres), traditional <productname>POSTGRES</productname>
+ (Unix <application>date</application> format), or
+ German. The default
+ is the <acronym>ISO</acronym> format. (The
+ <acronym>SQL</acronym> standard requires the use of the ISO 8601
+ format. The name of the <quote>SQL</quote> output format is a
+ historical accident.) <xref
+ linkend="datatype-datetime-output-table"/> shows examples of each
+ output style. The output of the <type>date</type> and
+ <type>time</type> types is generally only the date or time part
+ in accordance with the given examples. However, the
+ <productname>POSTGRES</productname> style outputs date-only values in
+ <acronym>ISO</acronym> format.
+ </para>
+
+ <table id="datatype-datetime-output-table">
+ <title>Date/Time Output Styles</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Style Specification</entry>
+ <entry>Description</entry>
+ <entry>Example</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>ISO</literal></entry>
+ <entry>ISO 8601, SQL standard</entry>
+ <entry><literal>1997-12-17 07:37:16-08</literal></entry>
+ </row>
+ <row>
+ <entry><literal>SQL</literal></entry>
+ <entry>traditional style</entry>
+ <entry><literal>12/17/1997 07:37:16.00 PST</literal></entry>
+ </row>
+ <row>
+ <entry><literal>Postgres</literal></entry>
+ <entry>original style</entry>
+ <entry><literal>Wed Dec 17 07:37:16 1997 PST</literal></entry>
+ </row>
+ <row>
+ <entry><literal>German</literal></entry>
+ <entry>regional style</entry>
+ <entry><literal>17.12.1997 07:37:16.00 PST</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ ISO 8601 specifies the use of uppercase letter <literal>T</literal> to separate
+ the date and time. <productname>PostgreSQL</productname> accepts that format on
+ input, but on output it uses a space rather than <literal>T</literal>, as shown
+ above. This is for readability and for consistency with
+ <ulink url="https://tools.ietf.org/html/rfc3339">RFC 3339</ulink> as
+ well as some other database systems.
+ </para>
+ </note>
+
+ <para>
+ In the <acronym>SQL</acronym> and POSTGRES styles, day appears before
+ month if DMY field ordering has been specified, otherwise month appears
+ before day.
+ (See <xref linkend="datatype-datetime-input"/>
+ for how this setting also affects interpretation of input values.)
+ <xref linkend="datatype-datetime-output2-table"/> shows examples.
+ </para>
+
+ <table id="datatype-datetime-output2-table">
+ <title>Date Order Conventions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry><varname>datestyle</varname> Setting</entry>
+ <entry>Input Ordering</entry>
+ <entry>Example Output</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>SQL, DMY</literal></entry>
+ <entry><replaceable>day</replaceable>/<replaceable>month</replaceable>/<replaceable>year</replaceable></entry>
+ <entry><literal>17/12/1997 15:37:16.00 CET</literal></entry>
+ </row>
+ <row>
+ <entry><literal>SQL, MDY</literal></entry>
+ <entry><replaceable>month</replaceable>/<replaceable>day</replaceable>/<replaceable>year</replaceable></entry>
+ <entry><literal>12/17/1997 07:37:16.00 PST</literal></entry>
+ </row>
+ <row>
+ <entry><literal>Postgres, DMY</literal></entry>
+ <entry><replaceable>day</replaceable>/<replaceable>month</replaceable>/<replaceable>year</replaceable></entry>
+ <entry><literal>Wed 17 Dec 07:37:16 1997 PST</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In the <acronym>ISO</acronym> style, the time zone is always shown as
+ a signed numeric offset from UTC, with positive sign used for zones
+ east of Greenwich. The offset will be shown
+ as <replaceable>hh</replaceable> (hours only) if it is an integral
+ number of hours, else
+ as <replaceable>hh</replaceable>:<replaceable>mm</replaceable> if it
+ is an integral number of minutes, else as
+ <replaceable>hh</replaceable>:<replaceable>mm</replaceable>:<replaceable>ss</replaceable>.
+ (The third case is not possible with any modern time zone standard,
+ but it can appear when working with timestamps that predate the
+ adoption of standardized time zones.)
+ In the other date styles, the time zone is shown as an alphabetic
+ abbreviation if one is in common use in the current zone. Otherwise
+ it appears as a signed numeric offset in ISO 8601 basic format
+ (<replaceable>hh</replaceable> or <replaceable>hhmm</replaceable>).
+ </para>
+
+ <para>
+ The date/time style can be selected by the user using the
+ <command>SET datestyle</command> command, the <xref
+ linkend="guc-datestyle"/> parameter in the
+ <filename>postgresql.conf</filename> configuration file, or the
+ <envar>PGDATESTYLE</envar> environment variable on the server or
+ client.
+ </para>
+
+ <para>
+ The formatting function <function>to_char</function>
+ (see <xref linkend="functions-formatting"/>) is also available as
+ a more flexible way to format date/time output.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-timezones">
+ <title>Time Zones</title>
+
+ <indexterm zone="datatype-timezones">
+ <primary>time zone</primary>
+ </indexterm>
+
+ <para>
+ Time zones, and time-zone conventions, are influenced by
+ political decisions, not just earth geometry. Time zones around the
+ world became somewhat standardized during the 1900s,
+ but continue to be prone to arbitrary changes, particularly with
+ respect to daylight-savings rules.
+ <productname>PostgreSQL</productname> uses the widely-used
+ IANA (Olson) time zone database for information about
+ historical time zone rules. For times in the future, the assumption
+ is that the latest known rules for a given time zone will
+ continue to be observed indefinitely far into the future.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> endeavors to be compatible with
+ the <acronym>SQL</acronym> standard definitions for typical usage.
+ However, the <acronym>SQL</acronym> standard has an odd mix of date and
+ time types and capabilities. Two obvious problems are:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Although the <type>date</type> type
+ cannot have an associated time zone, the
+ <type>time</type> type can.
+ Time zones in the real world have little meaning unless
+ associated with a date as well as a time,
+ since the offset can vary through the year with daylight-saving
+ time boundaries.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The default time zone is specified as a constant numeric offset
+ from <acronym>UTC</acronym>. It is therefore impossible to adapt to
+ daylight-saving time when doing date/time arithmetic across
+ <acronym>DST</acronym> boundaries.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ To address these difficulties, we recommend using date/time types
+ that contain both date and time when using time zones. We
+ do <emphasis>not</emphasis> recommend using the type <type>time with
+ time zone</type> (though it is supported by
+ <productname>PostgreSQL</productname> for legacy applications and
+ for compliance with the <acronym>SQL</acronym> standard).
+ <productname>PostgreSQL</productname> assumes
+ your local time zone for any type containing only date or time.
+ </para>
+
+ <para>
+ All timezone-aware dates and times are stored internally in
+ <acronym>UTC</acronym>. They are converted to local time
+ in the zone specified by the <xref linkend="guc-timezone"/> configuration
+ parameter before being displayed to the client.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> allows you to specify time zones in
+ three different forms:
+ <itemizedlist>
+ <listitem>
+ <para>
+ A full time zone name, for example <literal>America/New_York</literal>.
+ The recognized time zone names are listed in the
+ <literal>pg_timezone_names</literal> view (see <xref
+ linkend="view-pg-timezone-names"/>).
+ <productname>PostgreSQL</productname> uses the widely-used IANA
+ time zone data for this purpose, so the same time zone
+ names are also recognized by other software.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A time zone abbreviation, for example <literal>PST</literal>. Such a
+ specification merely defines a particular offset from UTC, in
+ contrast to full time zone names which can imply a set of daylight
+ savings transition rules as well. The recognized abbreviations
+ are listed in the <literal>pg_timezone_abbrevs</literal> view (see <xref
+ linkend="view-pg-timezone-abbrevs"/>). You cannot set the
+ configuration parameters <xref linkend="guc-timezone"/> or
+ <xref linkend="guc-log-timezone"/> to a time
+ zone abbreviation, but you can use abbreviations in
+ date/time input values and with the <literal>AT TIME ZONE</literal>
+ operator.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In addition to the timezone names and abbreviations,
+ <productname>PostgreSQL</productname> will accept POSIX-style time zone
+ specifications, as described in
+ <xref linkend="datetime-posix-timezone-specs"/>. This option is not
+ normally preferable to using a named time zone, but it may be
+ necessary if no suitable IANA time zone entry is available.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ In short, this is the difference between abbreviations
+ and full names: abbreviations represent a specific offset from UTC,
+ whereas many of the full names imply a local daylight-savings time
+ rule, and so have two possible UTC offsets. As an example,
+ <literal>2014-06-04 12:00 America/New_York</literal> represents noon local
+ time in New York, which for this particular date was Eastern Daylight
+ Time (UTC-4). So <literal>2014-06-04 12:00 EDT</literal> specifies that
+ same time instant. But <literal>2014-06-04 12:00 EST</literal> specifies
+ noon Eastern Standard Time (UTC-5), regardless of whether daylight
+ savings was nominally in effect on that date.
+ </para>
+
+ <para>
+ To complicate matters, some jurisdictions have used the same timezone
+ abbreviation to mean different UTC offsets at different times; for
+ example, in Moscow <literal>MSK</literal> has meant UTC+3 in some years and
+ UTC+4 in others. <application>PostgreSQL</application> interprets such
+ abbreviations according to whatever they meant (or had most recently
+ meant) on the specified date; but, as with the <literal>EST</literal> example
+ above, this is not necessarily the same as local civil time on that date.
+ </para>
+
+ <para>
+ In all cases, timezone names and abbreviations are recognized
+ case-insensitively. (This is a change from <productname>PostgreSQL</productname>
+ versions prior to 8.2, which were case-sensitive in some contexts but
+ not others.)
+ </para>
+
+ <para>
+ Neither timezone names nor abbreviations are hard-wired into the server;
+ they are obtained from configuration files stored under
+ <filename>.../share/timezone/</filename> and <filename>.../share/timezonesets/</filename>
+ of the installation directory
+ (see <xref linkend="datetime-config-files"/>).
+ </para>
+
+ <para>
+ The <xref linkend="guc-timezone"/> configuration parameter can
+ be set in the file <filename>postgresql.conf</filename>, or in any of the
+ other standard ways described in <xref linkend="runtime-config"/>.
+ There are also some special ways to set it:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <acronym>SQL</acronym> command <command>SET TIME ZONE</command>
+ sets the time zone for the session. This is an alternative spelling
+ of <command>SET TIMEZONE TO</command> with a more SQL-spec-compatible syntax.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <envar>PGTZ</envar> environment variable is used by
+ <application>libpq</application> clients
+ to send a <command>SET TIME ZONE</command>
+ command to the server upon connection.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-interval-input">
+ <title>Interval Input</title>
+
+ <indexterm>
+ <primary>interval</primary>
+ </indexterm>
+
+ <para>
+ <type>interval</type> values can be written using the following
+ verbose syntax:
+
+<synopsis>
+<optional>@</optional> <replaceable>quantity</replaceable> <replaceable>unit</replaceable> <optional><replaceable>quantity</replaceable> <replaceable>unit</replaceable>...</optional> <optional><replaceable>direction</replaceable></optional>
+</synopsis>
+
+ where <replaceable>quantity</replaceable> is a number (possibly signed);
+ <replaceable>unit</replaceable> is <literal>microsecond</literal>,
+ <literal>millisecond</literal>, <literal>second</literal>,
+ <literal>minute</literal>, <literal>hour</literal>, <literal>day</literal>,
+ <literal>week</literal>, <literal>month</literal>, <literal>year</literal>,
+ <literal>decade</literal>, <literal>century</literal>, <literal>millennium</literal>,
+ or abbreviations or plurals of these units;
+ <replaceable>direction</replaceable> can be <literal>ago</literal> or
+ empty. The at sign (<literal>@</literal>) is optional noise. The amounts
+ of the different units are implicitly added with appropriate
+ sign accounting. <literal>ago</literal> negates all the fields.
+ This syntax is also used for interval output, if
+ <xref linkend="guc-intervalstyle"/> is set to
+ <literal>postgres_verbose</literal>.
+ </para>
+
+ <para>
+ Quantities of days, hours, minutes, and seconds can be specified without
+ explicit unit markings. For example, <literal>'1 12:59:10'</literal> is read
+ the same as <literal>'1 day 12 hours 59 min 10 sec'</literal>. Also,
+ a combination of years and months can be specified with a dash;
+ for example <literal>'200-10'</literal> is read the same as <literal>'200 years
+ 10 months'</literal>. (These shorter forms are in fact the only ones allowed
+ by the <acronym>SQL</acronym> standard, and are used for output when
+ <varname>IntervalStyle</varname> is set to <literal>sql_standard</literal>.)
+ </para>
+
+ <para>
+ Interval values can also be written as ISO 8601 time intervals, using
+ either the <quote>format with designators</quote> of the standard's section
+ 4.4.3.2 or the <quote>alternative format</quote> of section 4.4.3.3. The
+ format with designators looks like this:
+<synopsis>
+P <replaceable>quantity</replaceable> <replaceable>unit</replaceable> <optional> <replaceable>quantity</replaceable> <replaceable>unit</replaceable> ...</optional> <optional> T <optional> <replaceable>quantity</replaceable> <replaceable>unit</replaceable> ...</optional></optional>
+</synopsis>
+ The string must start with a <literal>P</literal>, and may include a
+ <literal>T</literal> that introduces the time-of-day units. The
+ available unit abbreviations are given in <xref
+ linkend="datatype-interval-iso8601-units"/>. Units may be
+ omitted, and may be specified in any order, but units smaller than
+ a day must appear after <literal>T</literal>. In particular, the meaning of
+ <literal>M</literal> depends on whether it is before or after
+ <literal>T</literal>.
+ </para>
+
+ <table id="datatype-interval-iso8601-units">
+ <title>ISO 8601 Interval Unit Abbreviations</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Abbreviation</entry>
+ <entry>Meaning</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Y</entry>
+ <entry>Years</entry>
+ </row>
+ <row>
+ <entry>M</entry>
+ <entry>Months (in the date part)</entry>
+ </row>
+ <row>
+ <entry>W</entry>
+ <entry>Weeks</entry>
+ </row>
+ <row>
+ <entry>D</entry>
+ <entry>Days</entry>
+ </row>
+ <row>
+ <entry>H</entry>
+ <entry>Hours</entry>
+ </row>
+ <row>
+ <entry>M</entry>
+ <entry>Minutes (in the time part)</entry>
+ </row>
+ <row>
+ <entry>S</entry>
+ <entry>Seconds</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In the alternative format:
+<synopsis>
+P <optional> <replaceable>years</replaceable>-<replaceable>months</replaceable>-<replaceable>days</replaceable> </optional> <optional> T <replaceable>hours</replaceable>:<replaceable>minutes</replaceable>:<replaceable>seconds</replaceable> </optional>
+</synopsis>
+ the string must begin with <literal>P</literal>, and a
+ <literal>T</literal> separates the date and time parts of the interval.
+ The values are given as numbers similar to ISO 8601 dates.
+ </para>
+
+ <para>
+ When writing an interval constant with a <replaceable>fields</replaceable>
+ specification, or when assigning a string to an interval column that was
+ defined with a <replaceable>fields</replaceable> specification, the interpretation of
+ unmarked quantities depends on the <replaceable>fields</replaceable>. For
+ example <literal>INTERVAL '1' YEAR</literal> is read as 1 year, whereas
+ <literal>INTERVAL '1'</literal> means 1 second. Also, field values
+ <quote>to the right</quote> of the least significant field allowed by the
+ <replaceable>fields</replaceable> specification are silently discarded. For
+ example, writing <literal>INTERVAL '1 day 2:03:04' HOUR TO MINUTE</literal>
+ results in dropping the seconds field, but not the day field.
+ </para>
+
+ <para>
+ According to the <acronym>SQL</acronym> standard all fields of an interval
+ value must have the same sign, so a leading negative sign applies to all
+ fields; for example the negative sign in the interval literal
+ <literal>'-1 2:03:04'</literal> applies to both the days and hour/minute/second
+ parts. <productname>PostgreSQL</productname> allows the fields to have different
+ signs, and traditionally treats each field in the textual representation
+ as independently signed, so that the hour/minute/second part is
+ considered positive in this example. If <varname>IntervalStyle</varname> is
+ set to <literal>sql_standard</literal> then a leading sign is considered
+ to apply to all fields (but only if no additional signs appear).
+ Otherwise the traditional <productname>PostgreSQL</productname> interpretation is
+ used. To avoid ambiguity, it's recommended to attach an explicit sign
+ to each field if any field is negative.
+ </para>
+
+ <para>
+ Field values can have fractional parts: for example, <literal>'1.5
+ weeks'</literal> or <literal>'01:02:03.45'</literal>. However,
+ because interval internally stores only three integer units (months,
+ days, microseconds), fractional units must be spilled to smaller
+ units. Fractional parts of units greater than months are rounded to
+ be an integer number of months, e.g. <literal>'1.5 years'</literal>
+ becomes <literal>'1 year 6 mons'</literal>. Fractional parts of
+ weeks and days are computed to be an integer number of days and
+ microseconds, assuming 30 days per month and 24 hours per day, e.g.,
+ <literal>'1.75 months'</literal> becomes <literal>1 mon 22 days
+ 12:00:00</literal>. Only seconds will ever be shown as fractional
+ on output.
+ </para>
+
+ <para>
+ <xref linkend="datatype-interval-input-examples"/> shows some examples
+ of valid <type>interval</type> input.
+ </para>
+
+ <table id="datatype-interval-input-examples">
+ <title>Interval Input</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Example</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>1-2</literal></entry>
+ <entry>SQL standard format: 1 year 2 months</entry>
+ </row>
+ <row>
+ <entry><literal>3 4:05:06</literal></entry>
+ <entry>SQL standard format: 3 days 4 hours 5 minutes 6 seconds</entry>
+ </row>
+ <row>
+ <entry><literal>1 year 2 months 3 days 4 hours 5 minutes 6 seconds</literal></entry>
+ <entry>Traditional Postgres format: 1 year 2 months 3 days 4 hours 5 minutes 6 seconds</entry>
+ </row>
+ <row>
+ <entry><literal>P1Y2M3DT4H5M6S</literal></entry>
+ <entry>ISO 8601 <quote>format with designators</quote>: same meaning as above</entry>
+ </row>
+ <row>
+ <entry><literal>P0001-02-03T04:05:06</literal></entry>
+ <entry>ISO 8601 <quote>alternative format</quote>: same meaning as above</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Internally <type>interval</type> values are stored as months, days,
+ and microseconds. This is done because the number of days in a month
+ varies, and a day can have 23 or 25 hours if a daylight savings
+ time adjustment is involved. The months and days fields are integers
+ while the microseconds field can store fractional seconds. Because intervals are
+ usually created from constant strings or <type>timestamp</type> subtraction,
+ this storage method works well in most cases, but can cause unexpected
+ results:
+
+<programlisting>
+SELECT EXTRACT(hours from '80 minutes'::interval);
+ date_part
+-----------
+ 1
+
+SELECT EXTRACT(days from '80 hours'::interval);
+ date_part
+-----------
+ 0
+</programlisting>
+
+ Functions <function>justify_days</function> and
+ <function>justify_hours</function> are available for adjusting days
+ and hours that overflow their normal ranges.
+ </para>
+
+ </sect2>
+
+ <sect2 id="datatype-interval-output">
+ <title>Interval Output</title>
+
+ <indexterm>
+ <primary>interval</primary>
+ <secondary>output format</secondary>
+ <seealso>formatting</seealso>
+ </indexterm>
+
+ <para>
+ The output format of the interval type can be set to one of the
+ four styles <literal>sql_standard</literal>, <literal>postgres</literal>,
+ <literal>postgres_verbose</literal>, or <literal>iso_8601</literal>,
+ using the command <literal>SET intervalstyle</literal>.
+ The default is the <literal>postgres</literal> format.
+ <xref linkend="interval-style-output-table"/> shows examples of each
+ output style.
+ </para>
+
+ <para>
+ The <literal>sql_standard</literal> style produces output that conforms to
+ the SQL standard's specification for interval literal strings, if
+ the interval value meets the standard's restrictions (either year-month
+ only or day-time only, with no mixing of positive
+ and negative components). Otherwise the output looks like a standard
+ year-month literal string followed by a day-time literal string,
+ with explicit signs added to disambiguate mixed-sign intervals.
+ </para>
+
+ <para>
+ The output of the <literal>postgres</literal> style matches the output of
+ <productname>PostgreSQL</productname> releases prior to 8.4 when the
+ <xref linkend="guc-datestyle"/> parameter was set to <literal>ISO</literal>.
+ </para>
+
+ <para>
+ The output of the <literal>postgres_verbose</literal> style matches the output of
+ <productname>PostgreSQL</productname> releases prior to 8.4 when the
+ <varname>DateStyle</varname> parameter was set to non-<literal>ISO</literal> output.
+ </para>
+
+ <para>
+ The output of the <literal>iso_8601</literal> style matches the <quote>format
+ with designators</quote> described in section 4.4.3.2 of the
+ ISO 8601 standard.
+ </para>
+
+ <table id="interval-style-output-table">
+ <title>Interval Output Style Examples</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Style Specification</entry>
+ <entry>Year-Month Interval</entry>
+ <entry>Day-Time Interval</entry>
+ <entry>Mixed Interval</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>sql_standard</literal></entry>
+ <entry>1-2</entry>
+ <entry>3 4:05:06</entry>
+ <entry>-1-2 +3 -4:05:06</entry>
+ </row>
+ <row>
+ <entry><literal>postgres</literal></entry>
+ <entry>1 year 2 mons</entry>
+ <entry>3 days 04:05:06</entry>
+ <entry>-1 year -2 mons +3 days -04:05:06</entry>
+ </row>
+ <row>
+ <entry><literal>postgres_verbose</literal></entry>
+ <entry>@ 1 year 2 mons</entry>
+ <entry>@ 3 days 4 hours 5 mins 6 secs</entry>
+ <entry>@ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago</entry>
+ </row>
+ <row>
+ <entry><literal>iso_8601</literal></entry>
+ <entry>P1Y2M</entry>
+ <entry>P3DT4H5M6S</entry>
+ <entry>P-1Y-2M3D&zwsp;T-4H-5M-6S</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="datatype-boolean">
+ <title>Boolean Type</title>
+
+ <indexterm zone="datatype-boolean">
+ <primary>Boolean</primary>
+ <secondary>data type</secondary>
+ </indexterm>
+
+ <indexterm zone="datatype-boolean">
+ <primary>true</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-boolean">
+ <primary>false</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides the
+ standard <acronym>SQL</acronym> type <type>boolean</type>;
+ see <xref linkend="datatype-boolean-table"/>.
+ The <type>boolean</type> type can have several states:
+ <quote>true</quote>, <quote>false</quote>, and a third state,
+ <quote>unknown</quote>, which is represented by the
+ <acronym>SQL</acronym> null value.
+ </para>
+
+ <table id="datatype-boolean-table">
+ <title>Boolean Data Type</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>boolean</type></entry>
+ <entry>1 byte</entry>
+ <entry>state of true or false</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Boolean constants can be represented in SQL queries by the SQL
+ key words <literal>TRUE</literal>, <literal>FALSE</literal>,
+ and <literal>NULL</literal>.
+ </para>
+
+ <para>
+ The datatype input function for type <type>boolean</type> accepts these
+ string representations for the <quote>true</quote> state:
+ <simplelist>
+ <member><literal>true</literal></member>
+ <member><literal>yes</literal></member>
+ <member><literal>on</literal></member>
+ <member><literal>1</literal></member>
+ </simplelist>
+ and these representations for the <quote>false</quote> state:
+ <simplelist>
+ <member><literal>false</literal></member>
+ <member><literal>no</literal></member>
+ <member><literal>off</literal></member>
+ <member><literal>0</literal></member>
+ </simplelist>
+ Unique prefixes of these strings are also accepted, for
+ example <literal>t</literal> or <literal>n</literal>.
+ Leading or trailing whitespace is ignored, and case does not matter.
+ </para>
+
+ <para>
+ The datatype output function for type <type>boolean</type> always emits
+ either <literal>t</literal> or <literal>f</literal>, as shown in
+ <xref linkend="datatype-boolean-example"/>.
+ </para>
+
+ <example id="datatype-boolean-example">
+ <title>Using the <type>boolean</type> Type</title>
+
+<programlisting>
+CREATE TABLE test1 (a boolean, b text);
+INSERT INTO test1 VALUES (TRUE, 'sic est');
+INSERT INTO test1 VALUES (FALSE, 'non est');
+SELECT * FROM test1;
+ a | b
+---+---------
+ t | sic est
+ f | non est
+
+SELECT * FROM test1 WHERE a;
+ a | b
+---+---------
+ t | sic est
+</programlisting>
+ </example>
+
+ <para>
+ The key words <literal>TRUE</literal> and <literal>FALSE</literal> are
+ the preferred (<acronym>SQL</acronym>-compliant) method for writing
+ Boolean constants in SQL queries. But you can also use the string
+ representations by following the generic string-literal constant syntax
+ described in <xref linkend="sql-syntax-constants-generic"/>, for
+ example <literal>'yes'::boolean</literal>.
+ </para>
+
+ <para>
+ Note that the parser automatically understands
+ that <literal>TRUE</literal> and <literal>FALSE</literal> are of
+ type <type>boolean</type>, but this is not so
+ for <literal>NULL</literal> because that can have any type.
+ So in some contexts you might have to cast <literal>NULL</literal>
+ to <type>boolean</type> explicitly, for
+ example <literal>NULL::boolean</literal>. Conversely, the cast can be
+ omitted from a string-literal Boolean value in contexts where the parser
+ can deduce that the literal must be of type <type>boolean</type>.
+ </para>
+ </sect1>
+
+ <sect1 id="datatype-enum">
+ <title>Enumerated Types</title>
+
+ <indexterm zone="datatype-enum">
+ <primary>data type</primary>
+ <secondary>enumerated (enum)</secondary>
+ </indexterm>
+
+ <indexterm zone="datatype-enum">
+ <primary>enumerated types</primary>
+ </indexterm>
+
+ <para>
+ Enumerated (enum) types are data types that
+ comprise a static, ordered set of values.
+ They are equivalent to the <type>enum</type>
+ types supported in a number of programming languages. An example of an enum
+ type might be the days of the week, or a set of status values for
+ a piece of data.
+ </para>
+
+ <sect2>
+ <title>Declaration of Enumerated Types</title>
+
+ <para>
+ Enum types are created using the <xref
+ linkend="sql-createtype"/> command,
+ for example:
+
+<programlisting>
+CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
+</programlisting>
+
+ Once created, the enum type can be used in table and function
+ definitions much like any other type:
+<programlisting>
+CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
+CREATE TABLE person (
+ name text,
+ current_mood mood
+);
+INSERT INTO person VALUES ('Moe', 'happy');
+SELECT * FROM person WHERE current_mood = 'happy';
+ name | current_mood
+------+--------------
+ Moe | happy
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Ordering</title>
+
+ <para>
+ The ordering of the values in an enum type is the
+ order in which the values were listed when the type was created.
+ All standard comparison operators and related
+ aggregate functions are supported for enums. For example:
+
+<programlisting>
+INSERT INTO person VALUES ('Larry', 'sad');
+INSERT INTO person VALUES ('Curly', 'ok');
+SELECT * FROM person WHERE current_mood > 'sad';
+ name | current_mood
+-------+--------------
+ Moe | happy
+ Curly | ok
+(2 rows)
+
+SELECT * FROM person WHERE current_mood > 'sad' ORDER BY current_mood;
+ name | current_mood
+-------+--------------
+ Curly | ok
+ Moe | happy
+(2 rows)
+
+SELECT name
+FROM person
+WHERE current_mood = (SELECT MIN(current_mood) FROM person);
+ name
+-------
+ Larry
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Type Safety</title>
+
+ <para>
+ Each enumerated data type is separate and cannot
+ be compared with other enumerated types. See this example:
+
+<programlisting>
+CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
+CREATE TABLE holidays (
+ num_weeks integer,
+ happiness happiness
+);
+INSERT INTO holidays(num_weeks,happiness) VALUES (4, 'happy');
+INSERT INTO holidays(num_weeks,happiness) VALUES (6, 'very happy');
+INSERT INTO holidays(num_weeks,happiness) VALUES (8, 'ecstatic');
+INSERT INTO holidays(num_weeks,happiness) VALUES (2, 'sad');
+ERROR: invalid input value for enum happiness: "sad"
+SELECT person.name, holidays.num_weeks FROM person, holidays
+ WHERE person.current_mood = holidays.happiness;
+ERROR: operator does not exist: mood = happiness
+</programlisting>
+ </para>
+
+ <para>
+ If you really need to do something like that, you can either
+ write a custom operator or add explicit casts to your query:
+
+<programlisting>
+SELECT person.name, holidays.num_weeks FROM person, holidays
+ WHERE person.current_mood::text = holidays.happiness::text;
+ name | num_weeks
+------+-----------
+ Moe | 4
+(1 row)
+
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Implementation Details</title>
+
+ <para>
+ Enum labels are case sensitive, so
+ <type>'happy'</type> is not the same as <type>'HAPPY'</type>.
+ White space in the labels is significant too.
+ </para>
+
+ <para>
+ Although enum types are primarily intended for static sets of values,
+ there is support for adding new values to an existing enum type, and for
+ renaming values (see <xref linkend="sql-altertype"/>). Existing values
+ cannot be removed from an enum type, nor can the sort ordering of such
+ values be changed, short of dropping and re-creating the enum type.
+ </para>
+
+ <para>
+ An enum value occupies four bytes on disk. The length of an enum
+ value's textual label is limited by the <symbol>NAMEDATALEN</symbol>
+ setting compiled into <productname>PostgreSQL</productname>; in standard
+ builds this means at most 63 bytes.
+ </para>
+
+ <para>
+ The translations from internal enum values to textual labels are
+ kept in the system catalog
+ <link linkend="catalog-pg-enum"><structname>pg_enum</structname></link>.
+ Querying this catalog directly can be useful.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="datatype-geometric">
+ <title>Geometric Types</title>
+
+ <para>
+ Geometric data types represent two-dimensional spatial
+ objects. <xref linkend="datatype-geo-table"/> shows the geometric
+ types available in <productname>PostgreSQL</productname>.
+ </para>
+
+ <table id="datatype-geo-table">
+ <title>Geometric Types</title>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ <entry>Representation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>point</type></entry>
+ <entry>16 bytes</entry>
+ <entry>Point on a plane</entry>
+ <entry>(x,y)</entry>
+ </row>
+ <row>
+ <entry><type>line</type></entry>
+ <entry>32 bytes</entry>
+ <entry>Infinite line</entry>
+ <entry>{A,B,C}</entry>
+ </row>
+ <row>
+ <entry><type>lseg</type></entry>
+ <entry>32 bytes</entry>
+ <entry>Finite line segment</entry>
+ <entry>((x1,y1),(x2,y2))</entry>
+ </row>
+ <row>
+ <entry><type>box</type></entry>
+ <entry>32 bytes</entry>
+ <entry>Rectangular box</entry>
+ <entry>((x1,y1),(x2,y2))</entry>
+ </row>
+ <row>
+ <entry><type>path</type></entry>
+ <entry>16+16n bytes</entry>
+ <entry>Closed path (similar to polygon)</entry>
+ <entry>((x1,y1),...)</entry>
+ </row>
+ <row>
+ <entry><type>path</type></entry>
+ <entry>16+16n bytes</entry>
+ <entry>Open path</entry>
+ <entry>[(x1,y1),...]</entry>
+ </row>
+ <row>
+ <entry><type>polygon</type></entry>
+ <entry>40+16n bytes</entry>
+ <entry>Polygon (similar to closed path)</entry>
+ <entry>((x1,y1),...)</entry>
+ </row>
+ <row>
+ <entry><type>circle</type></entry>
+ <entry>24 bytes</entry>
+ <entry>Circle</entry>
+ <entry>&lt;(x,y),r&gt; (center point and radius)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ A rich set of functions and operators is available to perform various geometric
+ operations such as scaling, translation, rotation, and determining
+ intersections. They are explained in <xref linkend="functions-geometry"/>.
+ </para>
+
+ <sect2>
+ <title>Points</title>
+
+ <indexterm>
+ <primary>point</primary>
+ </indexterm>
+
+ <para>
+ Points are the fundamental two-dimensional building block for geometric
+ types. Values of type <type>point</type> are specified using either of
+ the following syntaxes:
+
+<synopsis>
+( <replaceable>x</replaceable> , <replaceable>y</replaceable> )
+ <replaceable>x</replaceable> , <replaceable>y</replaceable>
+</synopsis>
+
+ where <replaceable>x</replaceable> and <replaceable>y</replaceable> are the respective
+ coordinates, as floating-point numbers.
+ </para>
+
+ <para>
+ Points are output using the first syntax.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-line">
+ <title>Lines</title>
+
+ <indexterm>
+ <primary>line</primary>
+ </indexterm>
+
+ <para>
+ Lines are represented by the linear
+ equation <replaceable>A</replaceable>x + <replaceable>B</replaceable>y + <replaceable>C</replaceable> = 0,
+ where <replaceable>A</replaceable> and <replaceable>B</replaceable> are not both zero. Values
+ of type <type>line</type> are input and output in the following form:
+<synopsis>
+{ <replaceable>A</replaceable>, <replaceable>B</replaceable>, <replaceable>C</replaceable> }
+</synopsis>
+
+ Alternatively, any of the following forms can be used for input:
+
+<synopsis>
+[ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) ]
+( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> )
+ <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , <replaceable>x2</replaceable> , <replaceable>y2</replaceable>
+</synopsis>
+
+ where
+ <literal>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</literal>
+ and
+ <literal>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</literal>
+ are two different points on the line.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-lseg">
+ <title>Line Segments</title>
+
+ <indexterm>
+ <primary>lseg</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>line segment</primary>
+ </indexterm>
+
+ <para>
+ Line segments are represented by pairs of points that are the endpoints
+ of the segment. Values of type <type>lseg</type> are specified using any
+ of the following syntaxes:
+
+<synopsis>
+[ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) ]
+( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> )
+ <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , <replaceable>x2</replaceable> , <replaceable>y2</replaceable>
+</synopsis>
+
+ where
+ <literal>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</literal>
+ and
+ <literal>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</literal>
+ are the end points of the line segment.
+ </para>
+
+ <para>
+ Line segments are output using the first syntax.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Boxes</title>
+
+ <indexterm>
+ <primary>box (data type)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>rectangle</primary>
+ </indexterm>
+
+ <para>
+ Boxes are represented by pairs of points that are opposite
+ corners of the box.
+ Values of type <type>box</type> are specified using any of the following
+ syntaxes:
+
+<synopsis>
+( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> ) )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable> )
+ <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , <replaceable>x2</replaceable> , <replaceable>y2</replaceable>
+</synopsis>
+
+ where
+ <literal>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</literal>
+ and
+ <literal>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</literal>
+ are any two opposite corners of the box.
+ </para>
+
+ <para>
+ Boxes are output using the second syntax.
+ </para>
+
+ <para>
+ Any two opposite corners can be supplied on input, but the values
+ will be reordered as needed to store the
+ upper right and lower left corners, in that order.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Paths</title>
+
+ <indexterm>
+ <primary>path (data type)</primary>
+ </indexterm>
+
+ <para>
+ Paths are represented by lists of connected points. Paths can be
+ <firstterm>open</firstterm>, where
+ the first and last points in the list are considered not connected, or
+ <firstterm>closed</firstterm>,
+ where the first and last points are considered connected.
+ </para>
+
+ <para>
+ Values of type <type>path</type> are specified using any of the following
+ syntaxes:
+
+<synopsis>
+[ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> ) ]
+( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> ) )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , ... , <replaceable>xn</replaceable> , <replaceable>yn</replaceable> )
+ <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , ... , <replaceable>xn</replaceable> , <replaceable>yn</replaceable>
+</synopsis>
+
+ where the points are the end points of the line segments
+ comprising the path. Square brackets (<literal>[]</literal>) indicate
+ an open path, while parentheses (<literal>()</literal>) indicate a
+ closed path. When the outermost parentheses are omitted, as
+ in the third through fifth syntaxes, a closed path is assumed.
+ </para>
+
+ <para>
+ Paths are output using the first or second syntax, as appropriate.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-polygon">
+ <title>Polygons</title>
+
+ <indexterm>
+ <primary>polygon</primary>
+ </indexterm>
+
+ <para>
+ Polygons are represented by lists of points (the vertexes of the
+ polygon). Polygons are very similar to closed paths; the essential
+ difference is that a polygon is considered to include the area
+ within it, while a path is not.
+ </para>
+
+ <para>
+ Values of type <type>polygon</type> are specified using any of the
+ following syntaxes:
+
+<synopsis>
+( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> ) )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ... , ( <replaceable>xn</replaceable> , <replaceable>yn</replaceable> )
+ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , ... , <replaceable>xn</replaceable> , <replaceable>yn</replaceable> )
+ <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , ... , <replaceable>xn</replaceable> , <replaceable>yn</replaceable>
+</synopsis>
+
+ where the points are the end points of the line segments
+ comprising the boundary of the polygon.
+ </para>
+
+ <para>
+ Polygons are output using the first syntax.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-circle">
+ <title>Circles</title>
+
+ <indexterm>
+ <primary>circle</primary>
+ </indexterm>
+
+ <para>
+ Circles are represented by a center point and radius.
+ Values of type <type>circle</type> are specified using any of the
+ following syntaxes:
+
+<synopsis>
+&lt; ( <replaceable>x</replaceable> , <replaceable>y</replaceable> ) , <replaceable>r</replaceable> &gt;
+( ( <replaceable>x</replaceable> , <replaceable>y</replaceable> ) , <replaceable>r</replaceable> )
+ ( <replaceable>x</replaceable> , <replaceable>y</replaceable> ) , <replaceable>r</replaceable>
+ <replaceable>x</replaceable> , <replaceable>y</replaceable> , <replaceable>r</replaceable>
+</synopsis>
+
+ where
+ <literal>(<replaceable>x</replaceable>,<replaceable>y</replaceable>)</literal>
+ is the center point and <replaceable>r</replaceable> is the radius of the
+ circle.
+ </para>
+
+ <para>
+ Circles are output using the first syntax.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="datatype-net-types">
+ <title>Network Address Types</title>
+
+ <indexterm zone="datatype-net-types">
+ <primary>network</primary>
+ <secondary>data types</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> offers data types to store IPv4, IPv6, and MAC
+ addresses, as shown in <xref linkend="datatype-net-types-table"/>. It
+ is better to use these types instead of plain text types to store
+ network addresses, because
+ these types offer input error checking and specialized
+ operators and functions (see <xref linkend="functions-net"/>).
+ </para>
+
+ <table tocentry="1" id="datatype-net-types-table">
+ <title>Network Address Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Storage Size</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row>
+ <entry><type>cidr</type></entry>
+ <entry>7 or 19 bytes</entry>
+ <entry>IPv4 and IPv6 networks</entry>
+ </row>
+
+ <row>
+ <entry><type>inet</type></entry>
+ <entry>7 or 19 bytes</entry>
+ <entry>IPv4 and IPv6 hosts and networks</entry>
+ </row>
+
+ <row>
+ <entry><type>macaddr</type></entry>
+ <entry>6 bytes</entry>
+ <entry>MAC addresses</entry>
+ </row>
+
+ <row>
+ <entry><type>macaddr8</type></entry>
+ <entry>8 bytes</entry>
+ <entry>MAC addresses (EUI-64 format)</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ When sorting <type>inet</type> or <type>cidr</type> data types,
+ IPv4 addresses will always sort before IPv6 addresses, including
+ IPv4 addresses encapsulated or mapped to IPv6 addresses, such as
+ ::10.2.3.4 or ::ffff:10.4.3.2.
+ </para>
+
+
+ <sect2 id="datatype-inet">
+ <title><type>inet</type></title>
+
+ <indexterm>
+ <primary>inet (data type)</primary>
+ </indexterm>
+
+ <para>
+ The <type>inet</type> type holds an IPv4 or IPv6 host address, and
+ optionally its subnet, all in one field.
+ The subnet is represented by the number of network address bits
+ present in the host address (the
+ <quote>netmask</quote>). If the netmask is 32 and the address is IPv4,
+ then the value does not indicate a subnet, only a single host.
+ In IPv6, the address length is 128 bits, so 128 bits specify a
+ unique host address. Note that if you
+ want to accept only networks, you should use the
+ <type>cidr</type> type rather than <type>inet</type>.
+ </para>
+
+ <para>
+ The input format for this type is
+ <replaceable class="parameter">address/y</replaceable>
+ where
+ <replaceable class="parameter">address</replaceable>
+ is an IPv4 or IPv6 address and
+ <replaceable class="parameter">y</replaceable>
+ is the number of bits in the netmask. If the
+ <replaceable class="parameter">/y</replaceable>
+ portion is omitted, the
+ netmask is taken to be 32 for IPv4 or 128 for IPv6,
+ so the value represents
+ just a single host. On display, the
+ <replaceable class="parameter">/y</replaceable>
+ portion is suppressed if the netmask specifies a single host.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-cidr">
+ <title><type>cidr</type></title>
+
+ <indexterm>
+ <primary>cidr</primary>
+ </indexterm>
+
+ <para>
+ The <type>cidr</type> type holds an IPv4 or IPv6 network specification.
+ Input and output formats follow Classless Internet Domain Routing
+ conventions.
+ The format for specifying networks is <replaceable
+ class="parameter">address/y</replaceable> where <replaceable
+ class="parameter">address</replaceable> is the network's lowest
+ address represented as an
+ IPv4 or IPv6 address, and <replaceable
+ class="parameter">y</replaceable> is the number of bits in the netmask. If
+ <replaceable class="parameter">y</replaceable> is omitted, it is calculated
+ using assumptions from the older classful network numbering system, except
+ it will be at least large enough to include all of the octets
+ written in the input. It is an error to specify a network address
+ that has bits set to the right of the specified netmask.
+ </para>
+
+ <para>
+ <xref linkend="datatype-net-cidr-table"/> shows some examples.
+ </para>
+
+ <table id="datatype-net-cidr-table">
+ <title><type>cidr</type> Type Input Examples</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry><type>cidr</type> Input</entry>
+ <entry><type>cidr</type> Output</entry>
+ <entry><literal><function>abbrev(<type>cidr</type>)</function></literal></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>192.168.100.128/25</entry>
+ <entry>192.168.100.128/25</entry>
+ <entry>192.168.100.128/25</entry>
+ </row>
+ <row>
+ <entry>192.168/24</entry>
+ <entry>192.168.0.0/24</entry>
+ <entry>192.168.0/24</entry>
+ </row>
+ <row>
+ <entry>192.168/25</entry>
+ <entry>192.168.0.0/25</entry>
+ <entry>192.168.0.0/25</entry>
+ </row>
+ <row>
+ <entry>192.168.1</entry>
+ <entry>192.168.1.0/24</entry>
+ <entry>192.168.1/24</entry>
+ </row>
+ <row>
+ <entry>192.168</entry>
+ <entry>192.168.0.0/24</entry>
+ <entry>192.168.0/24</entry>
+ </row>
+ <row>
+ <entry>128.1</entry>
+ <entry>128.1.0.0/16</entry>
+ <entry>128.1/16</entry>
+ </row>
+ <row>
+ <entry>128</entry>
+ <entry>128.0.0.0/16</entry>
+ <entry>128.0/16</entry>
+ </row>
+ <row>
+ <entry>128.1.2</entry>
+ <entry>128.1.2.0/24</entry>
+ <entry>128.1.2/24</entry>
+ </row>
+ <row>
+ <entry>10.1.2</entry>
+ <entry>10.1.2.0/24</entry>
+ <entry>10.1.2/24</entry>
+ </row>
+ <row>
+ <entry>10.1</entry>
+ <entry>10.1.0.0/16</entry>
+ <entry>10.1/16</entry>
+ </row>
+ <row>
+ <entry>10</entry>
+ <entry>10.0.0.0/8</entry>
+ <entry>10/8</entry>
+ </row>
+ <row>
+ <entry>10.1.2.3/32</entry>
+ <entry>10.1.2.3/32</entry>
+ <entry>10.1.2.3/32</entry>
+ </row>
+ <row>
+ <entry>2001:4f8:3:ba::/64</entry>
+ <entry>2001:4f8:3:ba::/64</entry>
+ <entry>2001:4f8:3:ba/64</entry>
+ </row>
+ <row>
+ <entry>2001:4f8:3:ba:&zwsp;2e0:81ff:fe22:d1f1/128</entry>
+ <entry>2001:4f8:3:ba:&zwsp;2e0:81ff:fe22:d1f1/128</entry>
+ <entry>2001:4f8:3:ba:&zwsp;2e0:81ff:fe22:d1f1/128</entry>
+ </row>
+ <row>
+ <entry>::ffff:1.2.3.0/120</entry>
+ <entry>::ffff:1.2.3.0/120</entry>
+ <entry>::ffff:1.2.3/120</entry>
+ </row>
+ <row>
+ <entry>::ffff:1.2.3.0/128</entry>
+ <entry>::ffff:1.2.3.0/128</entry>
+ <entry>::ffff:1.2.3.0/128</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="datatype-inet-vs-cidr">
+ <title><type>inet</type> vs. <type>cidr</type></title>
+
+ <para>
+ The essential difference between <type>inet</type> and <type>cidr</type>
+ data types is that <type>inet</type> accepts values with nonzero bits to
+ the right of the netmask, whereas <type>cidr</type> does not. For
+ example, <literal>192.168.0.1/24</literal> is valid for <type>inet</type>
+ but not for <type>cidr</type>.
+ </para>
+
+ <tip>
+ <para>
+ If you do not like the output format for <type>inet</type> or
+ <type>cidr</type> values, try the functions <function>host</function>,
+ <function>text</function>, and <function>abbrev</function>.
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2 id="datatype-macaddr">
+ <title><type>macaddr</type></title>
+
+ <indexterm>
+ <primary>macaddr (data type)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>MAC address</primary>
+ <see>macaddr</see>
+ </indexterm>
+
+ <para>
+ The <type>macaddr</type> type stores MAC addresses, known for example
+ from Ethernet card hardware addresses (although MAC addresses are
+ used for other purposes as well). Input is accepted in the
+ following formats:
+
+ <simplelist>
+ <member><literal>'08:00:2b:01:02:03'</literal></member>
+ <member><literal>'08-00-2b-01-02-03'</literal></member>
+ <member><literal>'08002b:010203'</literal></member>
+ <member><literal>'08002b-010203'</literal></member>
+ <member><literal>'0800.2b01.0203'</literal></member>
+ <member><literal>'0800-2b01-0203'</literal></member>
+ <member><literal>'08002b010203'</literal></member>
+ </simplelist>
+
+ These examples all specify the same address. Upper and
+ lower case is accepted for the digits
+ <literal>a</literal> through <literal>f</literal>. Output is always in the
+ first of the forms shown.
+ </para>
+
+ <para>
+ IEEE Standard 802-2001 specifies the second form shown (with hyphens)
+ as the canonical form for MAC addresses, and specifies the first
+ form (with colons) as used with bit-reversed, MSB-first notation, so that
+ 08-00-2b-01-02-03 = 10:00:D4:80:40:C0. This convention is widely
+ ignored nowadays, and it is relevant only for obsolete network
+ protocols (such as Token Ring). PostgreSQL makes no provisions
+ for bit reversal; all accepted formats use the canonical LSB
+ order.
+ </para>
+
+ <para>
+ The remaining five input formats are not part of any standard.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-macaddr8">
+ <title><type>macaddr8</type></title>
+
+ <indexterm>
+ <primary>macaddr8 (data type)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>MAC address (EUI-64 format)</primary>
+ <see>macaddr</see>
+ </indexterm>
+
+ <para>
+ The <type>macaddr8</type> type stores MAC addresses in EUI-64
+ format, known for example from Ethernet card hardware addresses
+ (although MAC addresses are used for other purposes as well).
+ This type can accept both 6 and 8 byte length MAC addresses
+ and stores them in 8 byte length format. MAC addresses given
+ in 6 byte format will be stored in 8 byte length format with the
+ 4th and 5th bytes set to FF and FE, respectively.
+
+ Note that IPv6 uses a modified EUI-64 format where the 7th bit
+ should be set to one after the conversion from EUI-48. The
+ function <function>macaddr8_set7bit</function> is provided to make this
+ change.
+
+ Generally speaking, any input which is comprised of pairs of hex
+ digits (on byte boundaries), optionally separated consistently by
+ one of <literal>':'</literal>, <literal>'-'</literal> or <literal>'.'</literal>, is
+ accepted. The number of hex digits must be either 16 (8 bytes) or
+ 12 (6 bytes). Leading and trailing whitespace is ignored.
+
+ The following are examples of input formats that are accepted:
+
+ <simplelist>
+ <member><literal>'08:00:2b:01:02:03:04:05'</literal></member>
+ <member><literal>'08-00-2b-01-02-03-04-05'</literal></member>
+ <member><literal>'08002b:0102030405'</literal></member>
+ <member><literal>'08002b-0102030405'</literal></member>
+ <member><literal>'0800.2b01.0203.0405'</literal></member>
+ <member><literal>'0800-2b01-0203-0405'</literal></member>
+ <member><literal>'08002b01:02030405'</literal></member>
+ <member><literal>'08002b0102030405'</literal></member>
+ </simplelist>
+
+ These examples all specify the same address. Upper and
+ lower case is accepted for the digits
+ <literal>a</literal> through <literal>f</literal>. Output is always in the
+ first of the forms shown.
+ </para>
+
+ <para>
+ The last six input formats shown above are not part of any standard.
+ </para>
+
+ <para>
+ To convert a traditional 48 bit MAC address in EUI-48 format to
+ modified EUI-64 format to be included as the host portion of an
+ IPv6 address, use <function>macaddr8_set7bit</function> as shown:
+
+<programlisting>
+SELECT macaddr8_set7bit('08:00:2b:01:02:03');
+<computeroutput>
+ macaddr8_set7bit
+-------------------------
+ 0a:00:2b:ff:fe:01:02:03
+(1 row)
+</computeroutput>
+</programlisting>
+
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="datatype-bit">
+ <title>Bit String Types</title>
+
+ <indexterm zone="datatype-bit">
+ <primary>bit string</primary>
+ <secondary>data type</secondary>
+ </indexterm>
+
+ <para>
+ Bit strings are strings of 1's and 0's. They can be used to store
+ or visualize bit masks. There are two SQL bit types:
+ <type>bit(<replaceable>n</replaceable>)</type> and <type>bit
+ varying(<replaceable>n</replaceable>)</type>, where
+ <replaceable>n</replaceable> is a positive integer.
+ </para>
+
+ <para>
+ <type>bit</type> type data must match the length
+ <replaceable>n</replaceable> exactly; it is an error to attempt to
+ store shorter or longer bit strings. <type>bit varying</type> data is
+ of variable length up to the maximum length
+ <replaceable>n</replaceable>; longer strings will be rejected.
+ Writing <type>bit</type> without a length is equivalent to
+ <literal>bit(1)</literal>, while <type>bit varying</type> without a length
+ specification means unlimited length.
+ </para>
+
+ <note>
+ <para>
+ If one explicitly casts a bit-string value to
+ <type>bit(<replaceable>n</replaceable>)</type>, it will be truncated or
+ zero-padded on the right to be exactly <replaceable>n</replaceable> bits,
+ without raising an error. Similarly,
+ if one explicitly casts a bit-string value to
+ <type>bit varying(<replaceable>n</replaceable>)</type>, it will be truncated
+ on the right if it is more than <replaceable>n</replaceable> bits.
+ </para>
+ </note>
+
+ <para>
+ Refer to <xref
+ linkend="sql-syntax-bit-strings"/> for information about the syntax
+ of bit string constants. Bit-logical operators and string
+ manipulation functions are available; see <xref
+ linkend="functions-bitstring"/>.
+ </para>
+
+ <example>
+ <title>Using the Bit String Types</title>
+
+<programlisting>
+CREATE TABLE test (a BIT(3), b BIT VARYING(5));
+INSERT INTO test VALUES (B'101', B'00');
+INSERT INTO test VALUES (B'10', B'101');
+<computeroutput>
+ERROR: bit string length 2 does not match type bit(3)
+</computeroutput>
+INSERT INTO test VALUES (B'10'::bit(3), B'101');
+SELECT * FROM test;
+<computeroutput>
+ a | b
+-----+-----
+ 101 | 00
+ 100 | 101
+</computeroutput>
+</programlisting>
+ </example>
+
+ <para>
+ A bit string value requires 1 byte for each group of 8 bits, plus
+ 5 or 8 bytes overhead depending on the length of the string
+ (but long values may be compressed or moved out-of-line, as explained
+ in <xref linkend="datatype-character"/> for character strings).
+ </para>
+ </sect1>
+
+ <sect1 id="datatype-textsearch">
+ <title>Text Search Types</title>
+
+ <indexterm zone="datatype-textsearch">
+ <primary>full text search</primary>
+ <secondary>data types</secondary>
+ </indexterm>
+
+ <indexterm zone="datatype-textsearch">
+ <primary>text search</primary>
+ <secondary>data types</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides two data types that
+ are designed to support full text search, which is the activity of
+ searching through a collection of natural-language <firstterm>documents</firstterm>
+ to locate those that best match a <firstterm>query</firstterm>.
+ The <type>tsvector</type> type represents a document in a form optimized
+ for text search; the <type>tsquery</type> type similarly represents
+ a text query.
+ <xref linkend="textsearch"/> provides a detailed explanation of this
+ facility, and <xref linkend="functions-textsearch"/> summarizes the
+ related functions and operators.
+ </para>
+
+ <sect2 id="datatype-tsvector">
+ <title><type>tsvector</type></title>
+
+ <indexterm>
+ <primary>tsvector (data type)</primary>
+ </indexterm>
+
+ <para>
+ A <type>tsvector</type> value is a sorted list of distinct
+ <firstterm>lexemes</firstterm>, which are words that have been
+ <firstterm>normalized</firstterm> to merge different variants of the same word
+ (see <xref linkend="textsearch"/> for details). Sorting and
+ duplicate-elimination are done automatically during input, as shown in
+ this example:
+
+<programlisting>
+SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;
+ tsvector
+----------------------------------------------------
+ 'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat'
+</programlisting>
+
+ To represent
+ lexemes containing whitespace or punctuation, surround them with quotes:
+
+<programlisting>
+SELECT $$the lexeme ' ' contains spaces$$::tsvector;
+ tsvector
+-------------------------------------------
+ ' ' 'contains' 'lexeme' 'spaces' 'the'
+</programlisting>
+
+ (We use dollar-quoted string literals in this example and the next one
+ to avoid the confusion of having to double quote marks within the
+ literals.) Embedded quotes and backslashes must be doubled:
+
+<programlisting>
+SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector;
+ tsvector
+------------------------------------------------
+ 'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the'
+</programlisting>
+
+ Optionally, integer <firstterm>positions</firstterm>
+ can be attached to lexemes:
+
+<programlisting>
+SELECT 'a:1 fat:2 cat:3 sat:4 on:5 a:6 mat:7 and:8 ate:9 a:10 fat:11 rat:12'::tsvector;
+ tsvector
+-------------------------------------------------------------------&zwsp;------------
+ 'a':1,6,10 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'on':5 'rat':12 'sat':4
+</programlisting>
+
+ A position normally indicates the source word's location in the
+ document. Positional information can be used for
+ <firstterm>proximity ranking</firstterm>. Position values can
+ range from 1 to 16383; larger numbers are silently set to 16383.
+ Duplicate positions for the same lexeme are discarded.
+ </para>
+
+ <para>
+ Lexemes that have positions can further be labeled with a
+ <firstterm>weight</firstterm>, which can be <literal>A</literal>,
+ <literal>B</literal>, <literal>C</literal>, or <literal>D</literal>.
+ <literal>D</literal> is the default and hence is not shown on output:
+
+<programlisting>
+SELECT 'a:1A fat:2B,4C cat:5D'::tsvector;
+ tsvector
+----------------------------
+ 'a':1A 'cat':5 'fat':2B,4C
+</programlisting>
+
+ Weights are typically used to reflect document structure, for example
+ by marking title words differently from body words. Text search
+ ranking functions can assign different priorities to the different
+ weight markers.
+ </para>
+
+ <para>
+ It is important to understand that the
+ <type>tsvector</type> type itself does not perform any word
+ normalization; it assumes the words it is given are normalized
+ appropriately for the application. For example,
+
+<programlisting>
+SELECT 'The Fat Rats'::tsvector;
+ tsvector
+--------------------
+ 'Fat' 'Rats' 'The'
+</programlisting>
+
+ For most English-text-searching applications the above words would
+ be considered non-normalized, but <type>tsvector</type> doesn't care.
+ Raw document text should usually be passed through
+ <function>to_tsvector</function> to normalize the words appropriately
+ for searching:
+
+<programlisting>
+SELECT to_tsvector('english', 'The Fat Rats');
+ to_tsvector
+-----------------
+ 'fat':2 'rat':3
+</programlisting>
+
+ Again, see <xref linkend="textsearch"/> for more detail.
+ </para>
+
+ </sect2>
+
+ <sect2 id="datatype-tsquery">
+ <title><type>tsquery</type></title>
+
+ <indexterm>
+ <primary>tsquery (data type)</primary>
+ </indexterm>
+
+ <para>
+ A <type>tsquery</type> value stores lexemes that are to be
+ searched for, and can combine them using the Boolean operators
+ <literal>&amp;</literal> (AND), <literal>|</literal> (OR), and
+ <literal>!</literal> (NOT), as well as the phrase search operator
+ <literal>&lt;-&gt;</literal> (FOLLOWED BY). There is also a variant
+ <literal>&lt;<replaceable>N</replaceable>&gt;</literal> of the FOLLOWED BY
+ operator, where <replaceable>N</replaceable> is an integer constant that
+ specifies the distance between the two lexemes being searched
+ for. <literal>&lt;-&gt;</literal> is equivalent to <literal>&lt;1&gt;</literal>.
+ </para>
+
+ <para>
+ Parentheses can be used to enforce grouping of these operators.
+ In the absence of parentheses, <literal>!</literal> (NOT) binds most tightly,
+ <literal>&lt;-&gt;</literal> (FOLLOWED BY) next most tightly, then
+ <literal>&amp;</literal> (AND), with <literal>|</literal> (OR) binding
+ the least tightly.
+ </para>
+
+ <para>
+ Here are some examples:
+
+<programlisting>
+SELECT 'fat &amp; rat'::tsquery;
+ tsquery
+---------------
+ 'fat' &amp; 'rat'
+
+SELECT 'fat &amp; (rat | cat)'::tsquery;
+ tsquery
+---------------------------
+ 'fat' &amp; ( 'rat' | 'cat' )
+
+SELECT 'fat &amp; rat &amp; ! cat'::tsquery;
+ tsquery
+------------------------
+ 'fat' &amp; 'rat' &amp; !'cat'
+</programlisting>
+ </para>
+
+ <para>
+ Optionally, lexemes in a <type>tsquery</type> can be labeled with
+ one or more weight letters, which restricts them to match only
+ <type>tsvector</type> lexemes with one of those weights:
+
+<programlisting>
+SELECT 'fat:ab &amp; cat'::tsquery;
+ tsquery
+------------------
+ 'fat':AB &amp; 'cat'
+</programlisting>
+ </para>
+
+ <para>
+ Also, lexemes in a <type>tsquery</type> can be labeled with <literal>*</literal>
+ to specify prefix matching:
+<programlisting>
+SELECT 'super:*'::tsquery;
+ tsquery
+-----------
+ 'super':*
+</programlisting>
+ This query will match any word in a <type>tsvector</type> that begins
+ with <quote>super</quote>.
+ </para>
+
+ <para>
+ Quoting rules for lexemes are the same as described previously for
+ lexemes in <type>tsvector</type>; and, as with <type>tsvector</type>,
+ any required normalization of words must be done before converting
+ to the <type>tsquery</type> type. The <function>to_tsquery</function>
+ function is convenient for performing such normalization:
+
+<programlisting>
+SELECT to_tsquery('Fat:ab &amp; Cats');
+ to_tsquery
+------------------
+ 'fat':AB &amp; 'cat'
+</programlisting>
+
+ Note that <function>to_tsquery</function> will process prefixes in the same way
+ as other words, which means this comparison returns true:
+
+<programlisting>
+SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' );
+ ?column?
+----------
+ t
+</programlisting>
+ because <literal>postgres</literal> gets stemmed to <literal>postgr</literal>:
+<programlisting>
+SELECT to_tsvector( 'postgraduate' ), to_tsquery( 'postgres:*' );
+ to_tsvector | to_tsquery
+---------------+------------
+ 'postgradu':1 | 'postgr':*
+</programlisting>
+ which will match the stemmed form of <literal>postgraduate</literal>.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="datatype-uuid">
+ <title><acronym>UUID</acronym> Type</title>
+
+ <indexterm zone="datatype-uuid">
+ <primary>UUID</primary>
+ </indexterm>
+
+ <para>
+ The data type <type>uuid</type> stores Universally Unique Identifiers
+ (UUID) as defined by <ulink url="https://tools.ietf.org/html/rfc4122">RFC 4122</ulink>,
+ ISO/IEC 9834-8:2005, and related standards.
+ (Some systems refer to this data type as a globally unique identifier, or
+ GUID,<indexterm><primary>GUID</primary></indexterm> instead.) This
+ identifier is a 128-bit quantity that is generated by an algorithm chosen
+ to make it very unlikely that the same identifier will be generated by
+ anyone else in the known universe using the same algorithm. Therefore,
+ for distributed systems, these identifiers provide a better uniqueness
+ guarantee than sequence generators, which
+ are only unique within a single database.
+ </para>
+
+ <para>
+ A UUID is written as a sequence of lower-case hexadecimal digits,
+ in several groups separated by hyphens, specifically a group of 8
+ digits followed by three groups of 4 digits followed by a group of
+ 12 digits, for a total of 32 digits representing the 128 bits. An
+ example of a UUID in this standard form is:
+<programlisting>
+a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
+</programlisting>
+ <productname>PostgreSQL</productname> also accepts the following
+ alternative forms for input:
+ use of upper-case digits, the standard format surrounded by
+ braces, omitting some or all hyphens, adding a hyphen after any
+ group of four digits. Examples are:
+<programlisting>
+A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
+{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
+a0eebc999c0b4ef8bb6d6bb9bd380a11
+a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
+{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
+</programlisting>
+ Output is always in the standard form.
+ </para>
+
+ <para>
+ See <xref linkend="functions-uuid"/> for how to generate a UUID in
+ <productname>PostgreSQL</productname>.
+ </para>
+ </sect1>
+
+ <sect1 id="datatype-xml">
+ <title><acronym>XML</acronym> Type</title>
+
+ <indexterm zone="datatype-xml">
+ <primary>XML</primary>
+ </indexterm>
+
+ <para>
+ The <type>xml</type> data type can be used to store XML data. Its
+ advantage over storing XML data in a <type>text</type> field is that it
+ checks the input values for well-formedness, and there are support
+ functions to perform type-safe operations on it; see <xref
+ linkend="functions-xml"/>. Use of this data type requires the
+ installation to have been built with <command>configure
+ --with-libxml</command>.
+ </para>
+
+ <para>
+ The <type>xml</type> type can store well-formed
+ <quote>documents</quote>, as defined by the XML standard, as well
+ as <quote>content</quote> fragments, which are defined by reference
+ to the more permissive
+ <ulink url="https://www.w3.org/TR/2010/REC-xpath-datamodel-20101214/#DocumentNode"><quote>document node</quote></ulink>
+ of the XQuery and XPath data model.
+ Roughly, this means that content fragments can have
+ more than one top-level element or character node. The expression
+ <literal><replaceable>xmlvalue</replaceable> IS DOCUMENT</literal>
+ can be used to evaluate whether a particular <type>xml</type>
+ value is a full document or only a content fragment.
+ </para>
+
+ <para>
+ Limits and compatibility notes for the <type>xml</type> data type
+ can be found in <xref linkend="xml-limits-conformance"/>.
+ </para>
+
+ <sect2>
+ <title>Creating XML Values</title>
+ <para>
+ To produce a value of type <type>xml</type> from character data,
+ use the function
+ <function>xmlparse</function>:<indexterm><primary>xmlparse</primary></indexterm>
+<synopsis>
+XMLPARSE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable>)
+</synopsis>
+ Examples:
+<programlisting><![CDATA[
+XMLPARSE (DOCUMENT '<?xml version="1.0"?><book><title>Manual</title><chapter>...</chapter></book>')
+XMLPARSE (CONTENT 'abc<foo>bar</foo><bar>foo</bar>')
+]]></programlisting>
+ While this is the only way to convert character strings into XML
+ values according to the SQL standard, the PostgreSQL-specific
+ syntaxes:
+<programlisting><![CDATA[
+xml '<foo>bar</foo>'
+'<foo>bar</foo>'::xml
+]]></programlisting>
+ can also be used.
+ </para>
+
+ <para>
+ The <type>xml</type> type does not validate input values
+ against a document type declaration
+ (DTD),<indexterm><primary>DTD</primary></indexterm>
+ even when the input value specifies a DTD.
+ There is also currently no built-in support for validating against
+ other XML schema languages such as XML Schema.
+ </para>
+
+ <para>
+ The inverse operation, producing a character string value from
+ <type>xml</type>, uses the function
+ <function>xmlserialize</function>:<indexterm><primary>xmlserialize</primary></indexterm>
+<synopsis>
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <replaceable>value</replaceable> AS <replaceable>type</replaceable> )
+</synopsis>
+ <replaceable>type</replaceable> can be
+ <type>character</type>, <type>character varying</type>, or
+ <type>text</type> (or an alias for one of those). Again, according
+ to the SQL standard, this is the only way to convert between type
+ <type>xml</type> and character types, but PostgreSQL also allows
+ you to simply cast the value.
+ </para>
+
+ <para>
+ When a character string value is cast to or from type
+ <type>xml</type> without going through <type>XMLPARSE</type> or
+ <type>XMLSERIALIZE</type>, respectively, the choice of
+ <literal>DOCUMENT</literal> versus <literal>CONTENT</literal> is
+ determined by the <quote>XML option</quote>
+ <indexterm><primary>XML option</primary></indexterm>
+ session configuration parameter, which can be set using the
+ standard command:
+<synopsis>
+SET XML OPTION { DOCUMENT | CONTENT };
+</synopsis>
+ or the more PostgreSQL-like syntax
+<synopsis>
+SET xmloption TO { DOCUMENT | CONTENT };
+</synopsis>
+ The default is <literal>CONTENT</literal>, so all forms of XML
+ data are allowed.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Encoding Handling</title>
+ <para>
+ Care must be taken when dealing with multiple character encodings
+ on the client, server, and in the XML data passed through them.
+ When using the text mode to pass queries to the server and query
+ results to the client (which is the normal mode), PostgreSQL
+ converts all character data passed between the client and the
+ server and vice versa to the character encoding of the respective
+ end; see <xref linkend="multibyte"/>. This includes string
+ representations of XML values, such as in the above examples.
+ This would ordinarily mean that encoding declarations contained in
+ XML data can become invalid as the character data is converted
+ to other encodings while traveling between client and server,
+ because the embedded encoding declaration is not changed. To cope
+ with this behavior, encoding declarations contained in
+ character strings presented for input to the <type>xml</type> type
+ are <emphasis>ignored</emphasis>, and content is assumed
+ to be in the current server encoding. Consequently, for correct
+ processing, character strings of XML data must be sent
+ from the client in the current client encoding. It is the
+ responsibility of the client to either convert documents to the
+ current client encoding before sending them to the server, or to
+ adjust the client encoding appropriately. On output, values of
+ type <type>xml</type> will not have an encoding declaration, and
+ clients should assume all data is in the current client
+ encoding.
+ </para>
+
+ <para>
+ When using binary mode to pass query parameters to the server
+ and query results back to the client, no encoding conversion
+ is performed, so the situation is different. In this case, an
+ encoding declaration in the XML data will be observed, and if it
+ is absent, the data will be assumed to be in UTF-8 (as required by
+ the XML standard; note that PostgreSQL does not support UTF-16).
+ On output, data will have an encoding declaration
+ specifying the client encoding, unless the client encoding is
+ UTF-8, in which case it will be omitted.
+ </para>
+
+ <para>
+ Needless to say, processing XML data with PostgreSQL will be less
+ error-prone and more efficient if the XML data encoding, client encoding,
+ and server encoding are the same. Since XML data is internally
+ processed in UTF-8, computations will be most efficient if the
+ server encoding is also UTF-8.
+ </para>
+
+ <caution>
+ <para>
+ Some XML-related functions may not work at all on non-ASCII data
+ when the server encoding is not UTF-8. This is known to be an
+ issue for <function>xmltable()</function> and <function>xpath()</function> in particular.
+ </para>
+ </caution>
+ </sect2>
+
+ <sect2>
+ <title>Accessing XML Values</title>
+
+ <para>
+ The <type>xml</type> data type is unusual in that it does not
+ provide any comparison operators. This is because there is no
+ well-defined and universally useful comparison algorithm for XML
+ data. One consequence of this is that you cannot retrieve rows by
+ comparing an <type>xml</type> column against a search value. XML
+ values should therefore typically be accompanied by a separate key
+ field such as an ID. An alternative solution for comparing XML
+ values is to convert them to character strings first, but note
+ that character string comparison has little to do with a useful
+ XML comparison method.
+ </para>
+
+ <para>
+ Since there are no comparison operators for the <type>xml</type>
+ data type, it is not possible to create an index directly on a
+ column of this type. If speedy searches in XML data are desired,
+ possible workarounds include casting the expression to a
+ character string type and indexing that, or indexing an XPath
+ expression. Of course, the actual query would have to be adjusted
+ to search by the indexed expression.
+ </para>
+
+ <para>
+ The text-search functionality in PostgreSQL can also be used to speed
+ up full-document searches of XML data. The necessary
+ preprocessing support is, however, not yet available in the PostgreSQL
+ distribution.
+ </para>
+ </sect2>
+ </sect1>
+
+ &json;
+
+ &array;
+
+ &rowtypes;
+
+ &rangetypes;
+
+ <sect1 id="domains">
+ <title>Domain Types</title>
+
+ <indexterm zone="domains">
+ <primary>domain</primary>
+ </indexterm>
+
+ <indexterm zone="domains">
+ <primary>data type</primary>
+ <secondary>domain</secondary>
+ </indexterm>
+
+ <para>
+ A <firstterm>domain</firstterm> is a user-defined data type that is
+ based on another <firstterm>underlying type</firstterm>. Optionally,
+ it can have constraints that restrict its valid values to a subset of
+ what the underlying type would allow. Otherwise it behaves like the
+ underlying type &mdash; for example, any operator or function that
+ can be applied to the underlying type will work on the domain type.
+ The underlying type can be any built-in or user-defined base type,
+ enum type, array type, composite type, range type, or another domain.
+ </para>
+
+ <para>
+ For example, we could create a domain over integers that accepts only
+ positive integers:
+<programlisting>
+CREATE DOMAIN posint AS integer CHECK (VALUE &gt; 0);
+CREATE TABLE mytable (id posint);
+INSERT INTO mytable VALUES(1); -- works
+INSERT INTO mytable VALUES(-1); -- fails
+</programlisting>
+ </para>
+
+ <para>
+ When an operator or function of the underlying type is applied to a
+ domain value, the domain is automatically down-cast to the underlying
+ type. Thus, for example, the result of <literal>mytable.id - 1</literal>
+ is considered to be of type <type>integer</type> not <type>posint</type>.
+ We could write <literal>(mytable.id - 1)::posint</literal> to cast the
+ result back to <type>posint</type>, causing the domain's constraints
+ to be rechecked. In this case, that would result in an error if the
+ expression had been applied to an <structfield>id</structfield> value of
+ 1. Assigning a value of the underlying type to a field or variable of
+ the domain type is allowed without writing an explicit cast, but the
+ domain's constraints will be checked.
+ </para>
+
+ <para>
+ For additional information see <xref linkend="sql-createdomain"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="datatype-oid">
+ <title>Object Identifier Types</title>
+
+ <indexterm zone="datatype-oid">
+ <primary>object identifier</primary>
+ <secondary>data type</secondary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>oid</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regclass</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regcollation</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regconfig</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regdictionary</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regnamespace</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regoper</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regoperator</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regproc</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regprocedure</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regrole</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>regtype</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>xid8</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>cid</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>tid</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-oid">
+ <primary>xid</primary>
+ </indexterm>
+
+ <para>
+ Object identifiers (OIDs) are used internally by
+ <productname>PostgreSQL</productname> as primary keys for various
+ system tables.
+ Type <type>oid</type> represents an object identifier. There are also
+ several alias types for <type>oid</type>, each
+ named <type>reg<replaceable>something</replaceable></type>.
+ <xref linkend="datatype-oid-table"/> shows an
+ overview.
+ </para>
+
+ <para>
+ The <type>oid</type> type is currently implemented as an unsigned
+ four-byte integer. Therefore, it is not large enough to provide
+ database-wide uniqueness in large databases, or even in large
+ individual tables.
+ </para>
+
+ <para>
+ The <type>oid</type> type itself has few operations beyond comparison.
+ It can be cast to integer, however, and then manipulated using the
+ standard integer operators. (Beware of possible
+ signed-versus-unsigned confusion if you do this.)
+ </para>
+
+ <para>
+ The OID alias types have no operations of their own except
+ for specialized input and output routines. These routines are able
+ to accept and display symbolic names for system objects, rather than
+ the raw numeric value that type <type>oid</type> would use. The alias
+ types allow simplified lookup of OID values for objects. For example,
+ to examine the <structname>pg_attribute</structname> rows related to a table
+ <literal>mytable</literal>, one could write:
+<programlisting>
+SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;
+</programlisting>
+ rather than:
+<programlisting>
+SELECT * FROM pg_attribute
+ WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');
+</programlisting>
+ While that doesn't look all that bad by itself, it's still oversimplified.
+ A far more complicated sub-select would be needed to
+ select the right OID if there are multiple tables named
+ <literal>mytable</literal> in different schemas.
+ The <type>regclass</type> input converter handles the table lookup according
+ to the schema path setting, and so it does the <quote>right thing</quote>
+ automatically. Similarly, casting a table's OID to
+ <type>regclass</type> is handy for symbolic display of a numeric OID.
+ </para>
+
+ <table id="datatype-oid-table">
+ <title>Object Identifier Types</title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>References</entry>
+ <entry>Description</entry>
+ <entry>Value Example</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><type>oid</type></entry>
+ <entry>any</entry>
+ <entry>numeric object identifier</entry>
+ <entry><literal>564182</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regclass</type></entry>
+ <entry><structname>pg_class</structname></entry>
+ <entry>relation name</entry>
+ <entry><literal>pg_type</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regcollation</type></entry>
+ <entry><structname>pg_collation</structname></entry>
+ <entry>collation name</entry>
+ <entry><literal>"POSIX"</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regconfig</type></entry>
+ <entry><structname>pg_ts_config</structname></entry>
+ <entry>text search configuration</entry>
+ <entry><literal>english</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regdictionary</type></entry>
+ <entry><structname>pg_ts_dict</structname></entry>
+ <entry>text search dictionary</entry>
+ <entry><literal>simple</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regnamespace</type></entry>
+ <entry><structname>pg_namespace</structname></entry>
+ <entry>namespace name</entry>
+ <entry><literal>pg_catalog</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regoper</type></entry>
+ <entry><structname>pg_operator</structname></entry>
+ <entry>operator name</entry>
+ <entry><literal>+</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regoperator</type></entry>
+ <entry><structname>pg_operator</structname></entry>
+ <entry>operator with argument types</entry>
+ <entry><literal>*(integer,&zwsp;integer)</literal>
+ or <literal>-(NONE,&zwsp;integer)</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regproc</type></entry>
+ <entry><structname>pg_proc</structname></entry>
+ <entry>function name</entry>
+ <entry><literal>sum</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regprocedure</type></entry>
+ <entry><structname>pg_proc</structname></entry>
+ <entry>function with argument types</entry>
+ <entry><literal>sum(int4)</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regrole</type></entry>
+ <entry><structname>pg_authid</structname></entry>
+ <entry>role name</entry>
+ <entry><literal>smithee</literal></entry>
+ </row>
+
+ <row>
+ <entry><type>regtype</type></entry>
+ <entry><structname>pg_type</structname></entry>
+ <entry>data type name</entry>
+ <entry><literal>integer</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ All of the OID alias types for objects that are grouped by namespace
+ accept schema-qualified names, and will
+ display schema-qualified names on output if the object would not
+ be found in the current search path without being qualified.
+ For example, <literal>myschema.mytable</literal> is acceptable input
+ for <type>regclass</type> (if there is such a table). That value
+ might be output as <literal>myschema.mytable</literal>, or
+ just <literal>mytable</literal>, depending on the current search path.
+ The <type>regproc</type> and <type>regoper</type> alias types will only
+ accept input names that are unique (not overloaded), so they are
+ of limited use; for most uses <type>regprocedure</type> or
+ <type>regoperator</type> are more appropriate. For <type>regoperator</type>,
+ unary operators are identified by writing <literal>NONE</literal> for the unused
+ operand.
+ </para>
+
+ <para>
+ The input functions for these types allow whitespace between tokens,
+ and will fold upper-case letters to lower case, except within double
+ quotes; this is done to make the syntax rules similar to the way
+ object names are written in SQL. Conversely, the output functions
+ will use double quotes if needed to make the output be a valid SQL
+ identifier. For example, the OID of a function
+ named <literal>Foo</literal> (with upper case <literal>F</literal>)
+ taking two integer arguments could be entered as
+ <literal>' "Foo" ( int, integer ) '::regprocedure</literal>. The
+ output would look like <literal>"Foo"(integer,integer)</literal>.
+ Both the function name and the argument type names could be
+ schema-qualified, too.
+ </para>
+
+ <para>
+ Many built-in <productname>PostgreSQL</productname> functions accept
+ the OID of a table, or another kind of database object, and for
+ convenience are declared as taking <type>regclass</type> (or the
+ appropriate OID alias type). This means you do not have to look up
+ the object's OID by hand, but can just enter its name as a string
+ literal. For example, the <function>nextval(regclass)</function> function
+ takes a sequence relation's OID, so you could call it like this:
+<programlisting>
+nextval('foo') <lineannotation>operates on sequence <literal>foo</literal></lineannotation>
+nextval('FOO') <lineannotation>same as above</lineannotation>
+nextval('"Foo"') <lineannotation>operates on sequence <literal>Foo</literal></lineannotation>
+nextval('myschema.foo') <lineannotation>operates on <literal>myschema.foo</literal></lineannotation>
+nextval('"myschema".foo') <lineannotation>same as above</lineannotation>
+nextval('foo') <lineannotation>searches search path for <literal>foo</literal></lineannotation>
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ When you write the argument of such a function as an unadorned
+ literal string, it becomes a constant of type <type>regclass</type>
+ (or the appropriate type).
+ Since this is really just an OID, it will track the originally
+ identified object despite later renaming, schema reassignment,
+ etc. This <quote>early binding</quote> behavior is usually desirable for
+ object references in column defaults and views. But sometimes you might
+ want <quote>late binding</quote> where the object reference is resolved
+ at run time. To get late-binding behavior, force the constant to be
+ stored as a <type>text</type> constant instead of <type>regclass</type>:
+<programlisting>
+nextval('foo'::text) <lineannotation><literal>foo</literal> is looked up at runtime</lineannotation>
+</programlisting>
+ The <function>to_regclass()</function> function and its siblings
+ can also be used to perform run-time lookups. See
+ <xref linkend="functions-info-catalog-table"/>.
+ </para>
+ </note>
+
+ <para>
+ Another practical example of use of <type>regclass</type>
+ is to look up the OID of a table listed in
+ the <literal>information_schema</literal> views, which don't supply
+ such OIDs directly. One might for example wish to call
+ the <function>pg_relation_size()</function> function, which requires
+ the table OID. Taking the above rules into account, the correct way
+ to do that is
+<programlisting>
+SELECT table_schema, table_name,
+ pg_relation_size((quote_ident(table_schema) || '.' ||
+ quote_ident(table_name))::regclass)
+FROM information_schema.tables
+WHERE ...
+</programlisting>
+ The <function>quote_ident()</function> function will take care of
+ double-quoting the identifiers where needed. The seemingly easier
+<programlisting>
+SELECT pg_relation_size(table_name)
+FROM information_schema.tables
+WHERE ...
+</programlisting>
+ is <emphasis>not recommended</emphasis>, because it will fail for
+ tables that are outside your search path or have names that require
+ quoting.
+ </para>
+
+ <para>
+ An additional property of most of the OID alias types is the creation of
+ dependencies. If a
+ constant of one of these types appears in a stored expression
+ (such as a column default expression or view), it creates a dependency
+ on the referenced object. For example, if a column has a default
+ expression <literal>nextval('my_seq'::regclass)</literal>,
+ <productname>PostgreSQL</productname>
+ understands that the default expression depends on the sequence
+ <literal>my_seq</literal>, so the system will not let the sequence
+ be dropped without first removing the default expression. The
+ alternative of <literal>nextval('my_seq'::text)</literal> does not
+ create a dependency.
+ (<type>regrole</type> is an exception to this property. Constants of this
+ type are not allowed in stored expressions.)
+ </para>
+
+ <para>
+ Another identifier type used by the system is <type>xid</type>, or transaction
+ (abbreviated <abbrev>xact</abbrev>) identifier. This is the data type of the system columns
+ <structfield>xmin</structfield> and <structfield>xmax</structfield>. Transaction identifiers are 32-bit quantities.
+ In some contexts, a 64-bit variant <type>xid8</type> is used. Unlike
+ <type>xid</type> values, <type>xid8</type> values increase strictly
+ monotonically and cannot be reused in the lifetime of a database cluster.
+ </para>
+
+ <para>
+ A third identifier type used by the system is <type>cid</type>, or
+ command identifier. This is the data type of the system columns
+ <structfield>cmin</structfield> and <structfield>cmax</structfield>. Command identifiers are also 32-bit quantities.
+ </para>
+
+ <para>
+ A final identifier type used by the system is <type>tid</type>, or tuple
+ identifier (row identifier). This is the data type of the system column
+ <structfield>ctid</structfield>. A tuple ID is a pair
+ (block number, tuple index within block) that identifies the
+ physical location of the row within its table.
+ </para>
+
+ <para>
+ (The system columns are further explained in <xref
+ linkend="ddl-system-columns"/>.)
+ </para>
+ </sect1>
+
+ <sect1 id="datatype-pg-lsn">
+ <title><type>pg_lsn</type> Type</title>
+
+ <indexterm zone="datatype-pg-lsn">
+ <primary>pg_lsn</primary>
+ </indexterm>
+
+ <para>
+ The <type>pg_lsn</type> data type can be used to store LSN (Log Sequence
+ Number) data which is a pointer to a location in the WAL. This type is a
+ representation of <type>XLogRecPtr</type> and an internal system type of
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ Internally, an LSN is a 64-bit integer, representing a byte position in
+ the write-ahead log stream. It is printed as two hexadecimal numbers of
+ up to 8 digits each, separated by a slash; for example,
+ <literal>16/B374D848</literal>. The <type>pg_lsn</type> type supports the
+ standard comparison operators, like <literal>=</literal> and
+ <literal>&gt;</literal>. Two LSNs can be subtracted using the
+ <literal>-</literal> operator; the result is the number of bytes separating
+ those write-ahead log locations. Also the number of bytes can be
+ added into and subtracted from LSN using the
+ <literal>+(pg_lsn,numeric)</literal> and
+ <literal>-(pg_lsn,numeric)</literal> operators, respectively. Note that
+ the calculated LSN should be in the range of <type>pg_lsn</type> type,
+ i.e., between <literal>0/0</literal> and
+ <literal>FFFFFFFF/FFFFFFFF</literal>.
+ </para>
+ </sect1>
+
+ <sect1 id="datatype-pseudo">
+ <title>Pseudo-Types</title>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>record</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>any</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anyelement</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anyarray</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anynonarray</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anyenum</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anyrange</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anymultirange</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anycompatible</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anycompatiblearray</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anycompatiblenonarray</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anycompatiblerange</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>anycompatiblemultirange</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>void</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>trigger</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>event_trigger</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>pg_ddl_command</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>language_handler</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>fdw_handler</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>table_am_handler</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>index_am_handler</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>tsm_handler</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>cstring</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>internal</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-pseudo">
+ <primary>unknown</primary>
+ </indexterm>
+
+ <para>
+ The <productname>PostgreSQL</productname> type system contains a
+ number of special-purpose entries that are collectively called
+ <firstterm>pseudo-types</firstterm>. A pseudo-type cannot be used as a
+ column data type, but it can be used to declare a function's
+ argument or result type. Each of the available pseudo-types is
+ useful in situations where a function's behavior does not
+ correspond to simply taking or returning a value of a specific
+ <acronym>SQL</acronym> data type. <xref
+ linkend="datatype-pseudotypes-table"/> lists the existing
+ pseudo-types.
+ </para>
+
+ <table id="datatype-pseudotypes-table">
+ <title>Pseudo-Types</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>any</type></entry>
+ <entry>Indicates that a function accepts any input data type.</entry>
+ </row>
+
+ <row>
+ <entry><type>anyelement</type></entry>
+ <entry>Indicates that a function accepts any data type
+ (see <xref linkend="extend-types-polymorphic"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anyarray</type></entry>
+ <entry>Indicates that a function accepts any array data type
+ (see <xref linkend="extend-types-polymorphic"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anynonarray</type></entry>
+ <entry>Indicates that a function accepts any non-array data type
+ (see <xref linkend="extend-types-polymorphic"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anyenum</type></entry>
+ <entry>Indicates that a function accepts any enum data type
+ (see <xref linkend="extend-types-polymorphic"/> and
+ <xref linkend="datatype-enum"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anyrange</type></entry>
+ <entry>Indicates that a function accepts any range data type
+ (see <xref linkend="extend-types-polymorphic"/> and
+ <xref linkend="rangetypes"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anymultirange</type></entry>
+ <entry>Indicates that a function accepts any multirange data type
+ (see <xref linkend="extend-types-polymorphic"/> and
+ <xref linkend="rangetypes"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatible</type></entry>
+ <entry>Indicates that a function accepts any data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <xref linkend="extend-types-polymorphic"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblearray</type></entry>
+ <entry>Indicates that a function accepts any array data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <xref linkend="extend-types-polymorphic"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblenonarray</type></entry>
+ <entry>Indicates that a function accepts any non-array data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <xref linkend="extend-types-polymorphic"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblerange</type></entry>
+ <entry>Indicates that a function accepts any range data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <xref linkend="extend-types-polymorphic"/> and
+ <xref linkend="rangetypes"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblemultirange</type></entry>
+ <entry>Indicates that a function accepts any multirange data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <xref linkend="extend-types-polymorphic"/> and
+ <xref linkend="rangetypes"/>).</entry>
+ </row>
+
+ <row>
+ <entry><type>cstring</type></entry>
+ <entry>Indicates that a function accepts or returns a null-terminated C string.</entry>
+ </row>
+
+ <row>
+ <entry><type>internal</type></entry>
+ <entry>Indicates that a function accepts or returns a server-internal
+ data type.</entry>
+ </row>
+
+ <row>
+ <entry><type>language_handler</type></entry>
+ <entry>A procedural language call handler is declared to return <type>language_handler</type>.</entry>
+ </row>
+
+ <row>
+ <entry><type>fdw_handler</type></entry>
+ <entry>A foreign-data wrapper handler is declared to return <type>fdw_handler</type>.</entry>
+ </row>
+
+ <row>
+ <entry><type>table_am_handler</type></entry>
+ <entry>A table access method handler is declared to return <type>table_am_handler</type>.</entry>
+ </row>
+
+ <row>
+ <entry><type>index_am_handler</type></entry>
+ <entry>An index access method handler is declared to return <type>index_am_handler</type>.</entry>
+ </row>
+
+ <row>
+ <entry><type>tsm_handler</type></entry>
+ <entry>A tablesample method handler is declared to return <type>tsm_handler</type>.</entry>
+ </row>
+
+ <row>
+ <entry><type>record</type></entry>
+ <entry>Identifies a function taking or returning an unspecified row type.</entry>
+ </row>
+
+ <row>
+ <entry><type>trigger</type></entry>
+ <entry>A trigger function is declared to return <type>trigger.</type></entry>
+ </row>
+
+ <row>
+ <entry><type>event_trigger</type></entry>
+ <entry>An event trigger function is declared to return <type>event_trigger.</type></entry>
+ </row>
+
+ <row>
+ <entry><type>pg_ddl_command</type></entry>
+ <entry>Identifies a representation of DDL commands that is available to event triggers.</entry>
+ </row>
+
+ <row>
+ <entry><type>void</type></entry>
+ <entry>Indicates that a function returns no value.</entry>
+ </row>
+
+ <row>
+ <entry><type>unknown</type></entry>
+ <entry>Identifies a not-yet-resolved type, e.g., of an undecorated
+ string literal.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Functions coded in C (whether built-in or dynamically loaded) can be
+ declared to accept or return any of these pseudo-types. It is up to
+ the function author to ensure that the function will behave safely
+ when a pseudo-type is used as an argument type.
+ </para>
+
+ <para>
+ Functions coded in procedural languages can use pseudo-types only as
+ allowed by their implementation languages. At present most procedural
+ languages forbid use of a pseudo-type as an argument type, and allow
+ only <type>void</type> and <type>record</type> as a result type (plus
+ <type>trigger</type> or <type>event_trigger</type> when the function is used
+ as a trigger or event trigger). Some also support polymorphic functions
+ using the polymorphic pseudo-types, which are shown above and discussed
+ in detail in <xref linkend="extend-types-polymorphic"/>.
+ </para>
+
+ <para>
+ The <type>internal</type> pseudo-type is used to declare functions
+ that are meant only to be called internally by the database
+ system, and not by direct invocation in an <acronym>SQL</acronym>
+ query. If a function has at least one <type>internal</type>-type
+ argument then it cannot be called from <acronym>SQL</acronym>. To
+ preserve the type safety of this restriction it is important to
+ follow this coding rule: do not create any function that is
+ declared to return <type>internal</type> unless it has at least one
+ <type>internal</type> argument.
+ </para>
+
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/datetime.sgml b/doc/src/sgml/datetime.sgml
new file mode 100644
index 0000000..ecc3245
--- /dev/null
+++ b/doc/src/sgml/datetime.sgml
@@ -0,0 +1,930 @@
+<!-- doc/src/sgml/datetime.sgml -->
+
+ <appendix id="datetime-appendix">
+ <title>Date/Time Support</title>
+
+ <para>
+ <productname>PostgreSQL</productname> uses an internal heuristic
+ parser for all date/time input support. Dates and times are input as
+ strings, and are broken up into distinct fields with a preliminary
+ determination of what kind of information can be in the
+ field. Each field is interpreted and either assigned a numeric
+ value, ignored, or rejected.
+ The parser contains internal lookup tables for all textual fields,
+ including months, days of the week, and time zones.
+ </para>
+
+ <para>
+ This appendix includes information on the content of these
+ lookup tables and describes the steps used by the parser to decode
+ dates and times.
+ </para>
+
+ <sect1 id="datetime-input-rules">
+ <title>Date/Time Input Interpretation</title>
+
+ <para>
+ Date/time input strings are decoded using the following procedure.
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ Break the input string into tokens and categorize each token as
+ a string, time, time zone, or number.
+ </para>
+
+ <substeps>
+ <step>
+ <para>
+ If the numeric token contains a colon (<literal>:</literal>), this is
+ a time string. Include all subsequent digits and colons.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If the numeric token contains a dash (<literal>-</literal>), slash
+ (<literal>/</literal>), or two or more dots (<literal>.</literal>), this is
+ a date string which might have a text month. If a date token has
+ already been seen, it is instead interpreted as a time zone
+ name (e.g., <literal>America/New_York</literal>).
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If the token is numeric only, then it is either a single field
+ or an ISO 8601 concatenated date (e.g.,
+ <literal>19990113</literal> for January 13, 1999) or time
+ (e.g., <literal>141516</literal> for 14:15:16).
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If the token starts with a plus (<literal>+</literal>) or minus
+ (<literal>-</literal>), then it is either a numeric time zone or a special
+ field.
+ </para>
+ </step>
+ </substeps>
+ </step>
+
+ <step>
+ <para>
+ If the token is an alphabetic string, match up with possible strings:
+ </para>
+
+ <substeps>
+ <step>
+ <para>
+ See if the token matches any known time zone abbreviation.
+ These abbreviations are supplied by the configuration file
+ described in <xref linkend="datetime-config-files"/>.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If not found, search an internal table to match
+ the token as either a special string (e.g., <literal>today</literal>),
+ day (e.g., <literal>Thursday</literal>),
+ month (e.g., <literal>January</literal>),
+ or noise word (e.g., <literal>at</literal>, <literal>on</literal>).
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If still not found, throw an error.
+ </para>
+ </step>
+ </substeps>
+ </step>
+
+ <step>
+ <para>
+ When the token is a number or number field:
+ </para>
+
+ <substeps>
+ <step>
+ <para>
+ If there are eight or six digits,
+ and if no other date fields have been previously read, then interpret
+ as a <quote>concatenated date</quote> (e.g.,
+ <literal>19990118</literal> or <literal>990118</literal>).
+ The interpretation is <literal>YYYYMMDD</literal> or <literal>YYMMDD</literal>.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If the token is three digits
+ and a year has already been read, then interpret as day of year.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If four or six digits and a year has already been read, then
+ interpret as a time (<literal>HHMM</literal> or <literal>HHMMSS</literal>).
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If three or more digits and no date fields have yet been found,
+ interpret as a year (this forces yy-mm-dd ordering of the remaining
+ date fields).
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Otherwise the date field ordering is assumed to follow the
+ <varname>DateStyle</varname> setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd.
+ Throw an error if a month or day field is found to be out of range.
+ </para>
+ </step>
+ </substeps>
+ </step>
+
+ <step>
+ <para>
+ If BC has been specified, negate the year and add one for
+ internal storage. (There is no year zero in the Gregorian
+ calendar, so numerically 1 BC becomes year zero.)
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If BC was not specified, and if the year field was two digits in length,
+ then adjust the year to four digits. If the field is less than 70, then
+ add 2000, otherwise add 1900.
+
+ <tip>
+ <para>
+ Gregorian years AD 1&ndash;99 can be entered by using 4 digits with leading
+ zeros (e.g., <literal>0099</literal> is AD 99).
+ </para>
+ </tip>
+ </para>
+ </step>
+ </procedure>
+ </sect1>
+
+
+ <sect1 id="datetime-invalid-input">
+ <title>Handling of Invalid or Ambiguous Timestamps</title>
+
+ <para>
+ Ordinarily, if a date/time string is syntactically valid but contains
+ out-of-range field values, an error will be thrown. For example, input
+ specifying the 31st of February will be rejected.
+ </para>
+
+ <para>
+ During a daylight-savings-time transition, it is possible for a
+ seemingly valid timestamp string to represent a nonexistent or ambiguous
+ timestamp. Such cases are not rejected; the ambiguity is resolved by
+ determining which UTC offset to apply. For example, supposing that the
+ <xref linkend="guc-timezone"/> parameter is set
+ to <literal>America/New_York</literal>, consider
+<programlisting>
+=&gt; SELECT '2018-03-11 02:30'::timestamptz;
+ timestamptz
+------------------------
+ 2018-03-11 03:30:00-04
+(1 row)
+</programlisting>
+ Because that day was a spring-forward transition date in that time zone,
+ there was no civil time instant 2:30AM; clocks jumped forward from 2AM
+ EST to 3AM EDT. <productname>PostgreSQL</productname> interprets the
+ given time as if it were standard time (UTC-5), which then renders as
+ 3:30AM EDT (UTC-4).
+ </para>
+
+ <para>
+ Conversely, consider the behavior during a fall-back transition:
+<programlisting>
+=&gt; SELECT '2018-11-04 01:30'::timestamptz;
+ timestamptz
+------------------------
+ 2018-11-04 01:30:00-05
+(1 row)
+</programlisting>
+ On that date, there were two possible interpretations of 1:30AM; there
+ was 1:30AM EDT, and then an hour later after clocks jumped back from
+ 2AM EDT to 1AM EST, there was 1:30AM EST.
+ Again, <productname>PostgreSQL</productname> interprets the given time
+ as if it were standard time (UTC-5). We can force the other
+ interpretation by specifying daylight-savings time:
+<programlisting>
+=&gt; SELECT '2018-11-04 01:30 EDT'::timestamptz;
+ timestamptz
+------------------------
+ 2018-11-04 01:30:00-04
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ The precise rule that is applied in such cases is that an invalid
+ timestamp that appears to fall within a jump-forward daylight savings
+ transition is assigned the UTC offset that prevailed in the time zone
+ just before the transition, while an ambiguous timestamp that could fall
+ on either side of a jump-back transition is assigned the UTC offset that
+ prevailed just after the transition. In most time zones this is
+ equivalent to saying that <quote>the standard-time interpretation is
+ preferred when in doubt</quote>.
+ </para>
+
+ <para>
+ In all cases, the UTC offset associated with a timestamp can be
+ specified explicitly, using either a numeric UTC offset or a time zone
+ abbreviation that corresponds to a fixed UTC offset. The rule just
+ given applies only when it is necessary to infer a UTC offset for a time
+ zone in which the offset varies.
+ </para>
+ </sect1>
+
+
+ <sect1 id="datetime-keywords">
+ <title>Date/Time Key Words</title>
+
+ <para>
+ <xref linkend="datetime-month-table"/> shows the tokens that are
+ recognized as names of months.
+ </para>
+
+ <table id="datetime-month-table">
+ <title>Month Names</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Month</entry>
+ <entry>Abbreviations</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>January</entry>
+ <entry>Jan</entry>
+ </row>
+ <row>
+ <entry>February</entry>
+ <entry>Feb</entry>
+ </row>
+ <row>
+ <entry>March</entry>
+ <entry>Mar</entry>
+ </row>
+ <row>
+ <entry>April</entry>
+ <entry>Apr</entry>
+ </row>
+ <row>
+ <entry>May</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>June</entry>
+ <entry>Jun</entry>
+ </row>
+ <row>
+ <entry>July</entry>
+ <entry>Jul</entry>
+ </row>
+ <row>
+ <entry>August</entry>
+ <entry>Aug</entry>
+ </row>
+ <row>
+ <entry>September</entry>
+ <entry>Sep, Sept</entry>
+ </row>
+ <row>
+ <entry>October</entry>
+ <entry>Oct</entry>
+ </row>
+ <row>
+ <entry>November</entry>
+ <entry>Nov</entry>
+ </row>
+ <row>
+ <entry>December</entry>
+ <entry>Dec</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="datetime-dow-table"/> shows the tokens that are
+ recognized as names of days of the week.
+ </para>
+
+ <table id="datetime-dow-table">
+ <title>Day of the Week Names</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Day</entry>
+ <entry>Abbreviations</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Sunday</entry>
+ <entry>Sun</entry>
+ </row>
+ <row>
+ <entry>Monday</entry>
+ <entry>Mon</entry>
+ </row>
+ <row>
+ <entry>Tuesday</entry>
+ <entry>Tue, Tues</entry>
+ </row>
+ <row>
+ <entry>Wednesday</entry>
+ <entry>Wed, Weds</entry>
+ </row>
+ <row>
+ <entry>Thursday</entry>
+ <entry>Thu, Thur, Thurs</entry>
+ </row>
+ <row>
+ <entry>Friday</entry>
+ <entry>Fri</entry>
+ </row>
+ <row>
+ <entry>Saturday</entry>
+ <entry>Sat</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="datetime-mod-table"/> shows the tokens that serve
+ various modifier purposes.
+ </para>
+
+ <table id="datetime-mod-table">
+ <title>Date/Time Field Modifiers</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>AM</literal></entry>
+ <entry>Time is before 12:00</entry>
+ </row>
+ <row>
+ <entry><literal>AT</literal></entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry><literal>JULIAN</literal>, <literal>JD</literal>, <literal>J</literal></entry>
+ <entry>Next field is Julian Date</entry>
+ </row>
+ <row>
+ <entry><literal>ON</literal></entry>
+ <entry>Ignored</entry>
+ </row>
+ <row>
+ <entry><literal>PM</literal></entry>
+ <entry>Time is on or after 12:00</entry>
+ </row>
+ <row>
+ <entry><literal>T</literal></entry>
+ <entry>Next field is time</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="datetime-config-files">
+ <title>Date/Time Configuration Files</title>
+
+ <indexterm>
+ <primary>time zone</primary>
+ <secondary>input abbreviations</secondary>
+ </indexterm>
+
+ <para>
+ Since timezone abbreviations are not well standardized,
+ <productname>PostgreSQL</productname> provides a means to customize
+ the set of abbreviations accepted by the server. The
+ <xref linkend="guc-timezone-abbreviations"/> run-time parameter
+ determines the active set of abbreviations. While this parameter
+ can be altered by any database user, the possible values for it
+ are under the control of the database administrator &mdash; they
+ are in fact names of configuration files stored in
+ <filename>.../share/timezonesets/</filename> of the installation directory.
+ By adding or altering files in that directory, the administrator
+ can set local policy for timezone abbreviations.
+ </para>
+
+ <para>
+ <varname>timezone_abbreviations</varname> can be set to any file name
+ found in <filename>.../share/timezonesets/</filename>, if the file's name
+ is entirely alphabetic. (The prohibition against non-alphabetic
+ characters in <varname>timezone_abbreviations</varname> prevents reading
+ files outside the intended directory, as well as reading editor
+ backup files and other extraneous files.)
+ </para>
+
+ <para>
+ A timezone abbreviation file can contain blank lines and comments
+ beginning with <literal>#</literal>. Non-comment lines must have one of
+ these formats:
+
+<synopsis>
+<replaceable>zone_abbreviation</replaceable> <replaceable>offset</replaceable>
+<replaceable>zone_abbreviation</replaceable> <replaceable>offset</replaceable> D
+<replaceable>zone_abbreviation</replaceable> <replaceable>time_zone_name</replaceable>
+@INCLUDE <replaceable>file_name</replaceable>
+@OVERRIDE
+</synopsis>
+ </para>
+
+ <para>
+ A <replaceable>zone_abbreviation</replaceable> is just the abbreviation
+ being defined. An <replaceable>offset</replaceable> is an integer giving
+ the equivalent offset in seconds from UTC, positive being east from
+ Greenwich and negative being west. For example, -18000 would be five
+ hours west of Greenwich, or North American east coast standard time.
+ <literal>D</literal> indicates that the zone name represents local
+ daylight-savings time rather than standard time.
+ </para>
+
+ <para>
+ Alternatively, a <replaceable>time_zone_name</replaceable> can be given, referencing
+ a zone name defined in the IANA timezone database. The zone's definition
+ is consulted to see whether the abbreviation is or has been in use in
+ that zone, and if so, the appropriate meaning is used &mdash; that is,
+ the meaning that was currently in use at the timestamp whose value is
+ being determined, or the meaning in use immediately before that if it
+ wasn't current at that time, or the oldest meaning if it was used only
+ after that time. This behavior is essential for dealing with
+ abbreviations whose meaning has historically varied. It is also allowed
+ to define an abbreviation in terms of a zone name in which that
+ abbreviation does not appear; then using the abbreviation is just
+ equivalent to writing out the zone name.
+ </para>
+
+ <tip>
+ <para>
+ Using a simple integer <replaceable>offset</replaceable> is preferred
+ when defining an abbreviation whose offset from UTC has never changed,
+ as such abbreviations are much cheaper to process than those that
+ require consulting a time zone definition.
+ </para>
+ </tip>
+
+ <para>
+ The <literal>@INCLUDE</literal> syntax allows inclusion of another file in the
+ <filename>.../share/timezonesets/</filename> directory. Inclusion can be nested,
+ to a limited depth.
+ </para>
+
+ <para>
+ The <literal>@OVERRIDE</literal> syntax indicates that subsequent entries in the
+ file can override previous entries (typically, entries obtained from
+ included files). Without this, conflicting definitions of the same
+ timezone abbreviation are considered an error.
+ </para>
+
+ <para>
+ In an unmodified installation, the file <filename>Default</filename> contains
+ all the non-conflicting time zone abbreviations for most of the world.
+ Additional files <filename>Australia</filename> and <filename>India</filename> are
+ provided for those regions: these files first include the
+ <literal>Default</literal> file and then add or modify abbreviations as needed.
+ </para>
+
+ <para>
+ For reference purposes, a standard installation also contains files
+ <filename>Africa.txt</filename>, <filename>America.txt</filename>, etc., containing
+ information about every time zone abbreviation known to be in use
+ according to the IANA timezone database. The zone name
+ definitions found in these files can be copied and pasted into a custom
+ configuration file as needed. Note that these files cannot be directly
+ referenced as <varname>timezone_abbreviations</varname> settings, because of
+ the dot embedded in their names.
+ </para>
+
+ <note>
+ <para>
+ If an error occurs while reading the time zone abbreviation set, no new
+ value is applied and the old set is kept. If the error occurs while
+ starting the database, startup fails.
+ </para>
+ </note>
+
+ <caution>
+ <para>
+ Time zone abbreviations defined in the configuration file override
+ non-timezone meanings built into <productname>PostgreSQL</productname>.
+ For example, the <filename>Australia</filename> configuration file defines
+ <literal>SAT</literal> (for South Australian Standard Time). When this
+ file is active, <literal>SAT</literal> will not be recognized as an abbreviation
+ for Saturday.
+ </para>
+ </caution>
+
+ <caution>
+ <para>
+ If you modify files in <filename>.../share/timezonesets/</filename>,
+ it is up to you to make backups &mdash; a normal database dump
+ will not include this directory.
+ </para>
+ </caution>
+
+ </sect1>
+
+ <sect1 id="datetime-posix-timezone-specs">
+ <title><acronym>POSIX</acronym> Time Zone Specifications</title>
+
+ <indexterm zone="datetime-posix-timezone-specs">
+ <primary>time zone</primary>
+ <secondary><acronym>POSIX</acronym>-style specification</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> can accept time zone specifications
+ that are written according to the <acronym>POSIX</acronym> standard's rules
+ for the <varname>TZ</varname> environment
+ variable. <acronym>POSIX</acronym> time zone specifications are
+ inadequate to deal with the complexity of real-world time zone history,
+ but there are sometimes reasons to use them.
+ </para>
+
+ <para>
+ A POSIX time zone specification has the form
+<synopsis>
+<replaceable>STD</replaceable> <replaceable>offset</replaceable> <optional> <replaceable>DST</replaceable> <optional> <replaceable>dstoffset</replaceable> </optional> <optional> , <replaceable>rule</replaceable> </optional> </optional>
+</synopsis>
+ (For readability, we show spaces between the fields, but spaces should
+ not be used in practice.) The fields are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <replaceable>STD</replaceable> is the zone abbreviation to be used
+ for standard time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>offset</replaceable> is the zone's standard-time offset
+ from UTC.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>DST</replaceable> is the zone abbreviation to be used
+ for daylight-savings time. If this field and the following ones are
+ omitted, the zone uses a fixed UTC offset with no daylight-savings
+ rule.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>dstoffset</replaceable> is the daylight-savings offset
+ from UTC. This field is typically omitted, since it defaults to one
+ hour less than the standard-time <replaceable>offset</replaceable>,
+ which is usually the right thing.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>rule</replaceable> defines the rule for when daylight
+ savings is in effect, as described below.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In this syntax, a zone abbreviation can be a string of letters, such
+ as <literal>EST</literal>, or an arbitrary string surrounded by angle
+ brackets, such as <literal>&lt;UTC-05&gt;</literal>.
+ Note that the zone abbreviations given here are only used for output,
+ and even then only in some timestamp output formats. The zone
+ abbreviations recognized in timestamp input are determined as explained
+ in <xref linkend="datetime-config-files"/>.
+ </para>
+
+ <para>
+ The offset fields specify the hours, and optionally minutes and seconds,
+ difference from UTC. They have the format
+ <replaceable>hh</replaceable><optional><literal>:</literal><replaceable>mm</replaceable><optional><literal>:</literal><replaceable>ss</replaceable></optional></optional>
+ optionally with a leading sign (<literal>+</literal>
+ or <literal>-</literal>). The positive sign is used for
+ zones <emphasis>west</emphasis> of Greenwich. (Note that this is the
+ opposite of the ISO-8601 sign convention used elsewhere in
+ <productname>PostgreSQL</productname>.) <replaceable>hh</replaceable>
+ can have one or two digits; <replaceable>mm</replaceable>
+ and <replaceable>ss</replaceable> (if used) must have two.
+ </para>
+
+ <para>
+ The daylight-savings transition <replaceable>rule</replaceable> has the
+ format
+<synopsis>
+<replaceable>dstdate</replaceable> <optional> <literal>/</literal> <replaceable>dsttime</replaceable> </optional> <literal>,</literal> <replaceable>stddate</replaceable> <optional> <literal>/</literal> <replaceable>stdtime</replaceable> </optional>
+</synopsis>
+ (As before, spaces should not be included in practice.)
+ The <replaceable>dstdate</replaceable>
+ and <replaceable>dsttime</replaceable> fields define when daylight-savings
+ time starts, while <replaceable>stddate</replaceable>
+ and <replaceable>stdtime</replaceable> define when standard time
+ starts. (In some cases, notably in zones south of the equator, the
+ former might be later in the year than the latter.) The date fields
+ have one of these formats:
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ A plain integer denotes a day of the year, counting from zero to
+ 364, or to 365 in leap years.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>J</literal><replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ In this form, <replaceable>n</replaceable> counts from 1 to 365,
+ and February 29 is not counted even if it is present. (Thus, a
+ transition occurring on February 29 could not be specified this
+ way. However, days after February have the same numbers whether
+ it's a leap year or not, so that this form is usually more useful
+ than the plain-integer form for transitions on fixed dates.)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>M</literal><replaceable>m</replaceable><literal>.</literal><replaceable>n</replaceable><literal>.</literal><replaceable>d</replaceable></term>
+ <listitem>
+ <para>
+ This form specifies a transition that always happens during the same
+ month and on the same day of the week. <replaceable>m</replaceable>
+ identifies the month, from 1 to 12. <replaceable>n</replaceable>
+ specifies the <replaceable>n</replaceable>'th occurrence of the
+ weekday identified by <replaceable>d</replaceable>.
+ <replaceable>n</replaceable> is a number between 1 and 4, or 5
+ meaning the last occurrence of that weekday in the month (which
+ could be the fourth or the fifth). <replaceable>d</replaceable> is
+ a number between 0 and 6, with 0 indicating Sunday.
+ For example, <literal>M3.2.0</literal> means <quote>the second
+ Sunday in March</quote>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <note>
+ <para>
+ The <literal>M</literal> format is sufficient to describe many common
+ daylight-savings transition laws. But note that none of these variants
+ can deal with daylight-savings law changes, so in practice the
+ historical data stored for named time zones (in the IANA time zone
+ database) is necessary to interpret past time stamps correctly.
+ </para>
+ </note>
+
+ <para>
+ The time fields in a transition rule have the same format as the offset
+ fields described previously, except that they cannot contain signs.
+ They define the current local time at which the change to the other
+ time occurs. If omitted, they default to <literal>02:00:00</literal>.
+ </para>
+
+ <para>
+ If a daylight-savings abbreviation is given but the
+ transition <replaceable>rule</replaceable> field is omitted,
+ the fallback behavior is to use the
+ rule <literal>M3.2.0,M11.1.0</literal>, which corresponds to USA
+ practice as of 2020 (that is, spring forward on the second Sunday of
+ March, fall back on the first Sunday of November, both transitions
+ occurring at 2AM prevailing time). Note that this rule does not
+ give correct USA transition dates for years before 2007.
+ </para>
+
+ <para>
+ As an example, <literal>CET-1CEST,M3.5.0,M10.5.0/3</literal> describes
+ current (as of 2020) timekeeping practice in Paris. This specification
+ says that standard time has the abbreviation <literal>CET</literal> and
+ is one hour ahead (east) of UTC; daylight savings time has the
+ abbreviation <literal>CEST</literal> and is implicitly two hours ahead
+ of UTC; daylight savings time begins on the last Sunday in March at 2AM
+ CET and ends on the last Sunday in October at 3AM CEST.
+ </para>
+
+ <para>
+ The four timezone names <literal>EST5EDT</literal>,
+ <literal>CST6CDT</literal>, <literal>MST7MDT</literal>,
+ and <literal>PST8PDT</literal> look like they are POSIX zone
+ specifications. However, they actually are treated as named time zones
+ because (for historical reasons) there are files by those names in the
+ IANA time zone database. The practical implication of this is that
+ these zone names will produce valid historical USA daylight-savings
+ transitions, even when a plain POSIX specification would not.
+ </para>
+
+ <para>
+ One should be wary that it is easy to misspell a POSIX-style time zone
+ specification, since there is no check on the reasonableness of the
+ zone abbreviation(s). For example, <literal>SET TIMEZONE TO
+ FOOBAR0</literal> will work, leaving the system effectively using a
+ rather peculiar abbreviation for UTC.
+ </para>
+
+ </sect1>
+
+ <sect1 id="datetime-units-history">
+ <title>History of Units</title>
+
+ <indexterm zone="datetime-units-history">
+ <primary>Gregorian calendar</primary>
+ </indexterm>
+
+ <para>
+ The SQL standard states that <quote>Within the definition of a
+ <quote>datetime literal</quote>, the <quote>datetime
+ values</quote> are constrained by the natural rules for dates and
+ times according to the Gregorian calendar</quote>.
+ <productname>PostgreSQL</productname> follows the SQL
+ standard's lead by counting dates exclusively in the Gregorian
+ calendar, even for years before that calendar was in use.
+ This rule is known as the <firstterm>proleptic Gregorian calendar</firstterm>.
+ </para>
+
+ <para>
+ The Julian calendar was introduced by Julius Caesar in 45 BC.
+ It was in common use in the Western world
+ until the year 1582, when countries started changing to the Gregorian
+ calendar. In the Julian calendar, the tropical year is
+ approximated as 365 1/4 days = 365.25 days. This gives an error of
+ about 1 day in 128 years.
+ </para>
+
+ <para>
+ The accumulating calendar error prompted
+ Pope Gregory XIII to reform the calendar in accordance with
+ instructions from the Council of Trent.
+ In the Gregorian calendar, the tropical year is approximated as
+ 365 + 97 / 400 days = 365.2425 days. Thus it takes approximately 3300
+ years for the tropical year to shift one day with respect to the
+ Gregorian calendar.
+ </para>
+
+ <para>
+ The approximation 365+97/400 is achieved by having 97 leap years
+ every 400 years, using the following rules:
+
+ <simplelist>
+ <member>
+ Every year divisible by 4 is a leap year.
+ </member>
+ <member>
+ However, every year divisible by 100 is not a leap year.
+ </member>
+ <member>
+ However, every year divisible by 400 is a leap year after all.
+ </member>
+ </simplelist>
+
+ So, 1700, 1800, 1900, 2100, and 2200 are not leap years. But 1600,
+ 2000, and 2400 are leap years.
+
+ By contrast, in the older Julian calendar all years divisible by 4 are leap
+ years.
+ </para>
+
+ <para>
+ The papal bull of February 1582 decreed that 10 days should be dropped
+ from October 1582 so that 15 October should follow immediately after
+ 4 October.
+ This was observed in Italy, Poland, Portugal, and Spain. Other Catholic
+ countries followed shortly after, but Protestant countries were
+ reluctant to change, and the Greek Orthodox countries didn't change
+ until the start of the 20th century.
+
+ The reform was observed by Great Britain and its dominions (including what
+ is now the USA) in 1752.
+ Thus 2 September 1752 was followed by 14 September 1752.
+
+ This is why Unix systems that have the <command>cal</command> program
+ produce the following:
+
+<screen>
+$ <userinput>cal 9 1752</userinput>
+ September 1752
+ S M Tu W Th F S
+ 1 2 14 15 16
+17 18 19 20 21 22 23
+24 25 26 27 28 29 30
+</screen>
+
+ But, of course, this calendar is only valid for Great Britain and
+ dominions, not other places.
+ Since it would be difficult and confusing to try to track the actual
+ calendars that were in use in various places at various times,
+ <productname>PostgreSQL</productname> does not try, but rather follows the Gregorian
+ calendar rules for all dates, even though this method is not historically
+ accurate.
+ </para>
+
+ <para>
+ Different calendars have been developed in various parts of the
+ world, many predating the Gregorian system.
+
+ For example,
+ the beginnings of the Chinese calendar can be traced back to the 14th
+ century BC. Legend has it that the Emperor Huangdi invented that
+ calendar in 2637 BC.
+
+ The People's Republic of China uses the Gregorian calendar
+ for civil purposes. The Chinese calendar is used for determining
+ festivals.
+ </para>
+
+ </sect1>
+
+ <sect1 id="datetime-julian-dates">
+ <title>Julian Dates</title>
+
+ <indexterm zone="datetime-julian-dates">
+ <primary>Julian date</primary>
+ </indexterm>
+
+ <para>
+ The <firstterm>Julian Date</firstterm> system is a method for
+ numbering days. It is
+ unrelated to the Julian calendar, though it is confusingly
+ named similarly to that calendar.
+ The Julian Date system was invented by the French scholar
+ Joseph Justus Scaliger (1540&ndash;1609)
+ and probably takes its name from Scaliger's father,
+ the Italian scholar Julius Caesar Scaliger (1484&ndash;1558).
+ </para>
+
+ <para>
+ In the Julian Date system, each day has a sequential number, starting
+ from JD 0 (which is sometimes called <emphasis>the</emphasis> Julian Date).
+ JD 0 corresponds to 1 January 4713 BC in the Julian calendar, or
+ 24 November 4714 BC in the Gregorian calendar. Julian Date counting
+ is most often used by astronomers for labeling their nightly observations,
+ and therefore a date runs from noon UTC to the next noon UTC, rather than
+ from midnight to midnight: JD 0 designates the 24 hours from noon UTC on
+ 24 November 4714 BC to noon UTC on 25 November 4714 BC.
+ </para>
+
+ <para>
+ Although <productname>PostgreSQL</productname> supports Julian Date notation for
+ input and output of dates (and also uses Julian dates for some internal
+ datetime calculations), it does not observe the nicety of having dates
+ run from noon to noon. <productname>PostgreSQL</productname> treats a Julian Date
+ as running from local midnight to local midnight, the same as a normal
+ date.
+ </para>
+
+ <para>
+ This definition does, however, provide a way to obtain the astronomical
+ definition when you need it: do the arithmetic in time
+ zone <literal>UTC+12</literal>. For example,
+<programlisting>
+=&gt; SELECT extract(julian from '2021-06-23 7:00:00-04'::timestamptz at time zone 'UTC+12');
+ extract
+------------------------------
+ 2459388.95833333333333333333
+(1 row)
+=&gt; SELECT extract(julian from '2021-06-23 8:00:00-04'::timestamptz at time zone 'UTC+12');
+ extract
+--------------------------------------
+ 2459389.0000000000000000000000000000
+(1 row)
+=&gt; SELECT extract(julian from date '2021-06-23');
+ extract
+---------
+ 2459389
+(1 row)
+</programlisting>
+ </para>
+
+ </sect1>
+</appendix>
diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml
new file mode 100644
index 0000000..50c49f5
--- /dev/null
+++ b/doc/src/sgml/dblink.sgml
@@ -0,0 +1,2136 @@
+<!-- doc/src/sgml/dblink.sgml -->
+
+<sect1 id="dblink" xreflabel="dblink">
+ <title>dblink</title>
+
+ <indexterm zone="dblink">
+ <primary>dblink</primary>
+ </indexterm>
+
+ <para>
+ <filename>dblink</filename> is a module that supports connections to
+ other <productname>PostgreSQL</productname> databases from within a database
+ session.
+ </para>
+
+ <para>
+ See also <xref linkend="postgres-fdw"/>, which provides roughly the same
+ functionality using a more modern and standards-compliant infrastructure.
+ </para>
+
+ <refentry id="contrib-dblink-connect">
+ <indexterm>
+ <primary>dblink_connect</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_connect</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_connect</refname>
+ <refpurpose>opens a persistent connection to a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_connect(text connstr) returns text
+dblink_connect(text connname, text connstr) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_connect()</function> establishes a connection to a remote
+ <productname>PostgreSQL</productname> database. The server and database to
+ be contacted are identified through a standard <application>libpq</application>
+ connection string. Optionally, a name can be assigned to the
+ connection. Multiple named connections can be open at once, but
+ only one unnamed connection is permitted at a time. The connection
+ will persist until closed or until the database session is ended.
+ </para>
+
+ <para>
+ The connection string may also be the name of an existing foreign
+ server. It is recommended to use the foreign-data wrapper
+ <literal>dblink_fdw</literal> when defining the foreign
+ server. See the example below, as well as
+ <xref linkend="sql-createserver"/> and
+ <xref linkend="sql-createusermapping"/>.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ The name to use for this connection; if omitted, an unnamed
+ connection is opened, replacing any existing unnamed connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>connstr</parameter></term>
+ <listitem>
+ <para><application>libpq</application>-style connection info string, for example
+ <literal>hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres
+ password=mypasswd options=-csearch_path=</literal>.
+ For details see <xref linkend="libpq-connstring"/>.
+ Alternatively, the name of a foreign server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns status, which is always <literal>OK</literal> (since any error
+ causes the function to throw an error instead of returning).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If untrusted users have access to a database that has not adopted a
+ <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
+ begin each session by removing publicly-writable schemas from
+ <varname>search_path</varname>. One could, for example,
+ add <literal>options=-csearch_path=</literal> to
+ <parameter>connstr</parameter>. This consideration is not specific
+ to <filename>dblink</filename>; it applies to every interface for
+ executing arbitrary SQL commands.
+ </para>
+
+ <para>
+ Only superusers may use <function>dblink_connect</function> to create
+ non-password-authenticated connections. If non-superusers need this
+ capability, use <function>dblink_connect_u</function> instead.
+ </para>
+
+ <para>
+ It is unwise to choose connection names that contain equal signs,
+ as this opens a risk of confusion with connection info strings
+ in other <filename>dblink</filename> functions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+-- FOREIGN DATA WRAPPER functionality
+-- Note: local connection must require password authentication for this to work properly
+-- Otherwise, you will receive the following error from dblink_connect():
+-- ERROR: password is required
+-- DETAIL: Non-superuser cannot connect if the server does not request a password.
+-- HINT: Target server's authentication method must be changed.
+
+CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw OPTIONS (hostaddr '127.0.0.1', dbname 'contrib_regression');
+
+CREATE USER regress_dblink_user WITH PASSWORD 'secret';
+CREATE USER MAPPING FOR regress_dblink_user SERVER fdtest OPTIONS (user 'regress_dblink_user', password 'secret');
+GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
+GRANT SELECT ON TABLE foo TO regress_dblink_user;
+
+\set ORIGINAL_USER :USER
+\c - regress_dblink_user
+SELECT dblink_connect('myconn', 'fdtest');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]);
+ a | b | c
+----+---+---------------
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+ 3 | d | {a3,b3,c3}
+ 4 | e | {a4,b4,c4}
+ 5 | f | {a5,b5,c5}
+ 6 | g | {a6,b6,c6}
+ 7 | h | {a7,b7,c7}
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ 10 | k | {a10,b10,c10}
+(11 rows)
+
+\c - :ORIGINAL_USER
+REVOKE USAGE ON FOREIGN SERVER fdtest FROM regress_dblink_user;
+REVOKE SELECT ON TABLE foo FROM regress_dblink_user;
+DROP USER MAPPING FOR regress_dblink_user SERVER fdtest;
+DROP USER regress_dblink_user;
+DROP SERVER fdtest;
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-connect-u">
+ <indexterm>
+ <primary>dblink_connect_u</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_connect_u</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_connect_u</refname>
+ <refpurpose>opens a persistent connection to a remote database, insecurely</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_connect_u(text connstr) returns text
+dblink_connect_u(text connname, text connstr) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_connect_u()</function> is identical to
+ <function>dblink_connect()</function>, except that it will allow non-superusers
+ to connect using any authentication method.
+ </para>
+
+ <para>
+ If the remote server selects an authentication method that does not
+ involve a password, then impersonation and subsequent escalation of
+ privileges can occur, because the session will appear to have
+ originated from the user as which the local <productname>PostgreSQL</productname>
+ server runs. Also, even if the remote server does demand a password,
+ it is possible for the password to be supplied from the server
+ environment, such as a <filename>~/.pgpass</filename> file belonging to the
+ server's user. This opens not only a risk of impersonation, but the
+ possibility of exposing a password to an untrustworthy remote server.
+ Therefore, <function>dblink_connect_u()</function> is initially
+ installed with all privileges revoked from <literal>PUBLIC</literal>,
+ making it un-callable except by superusers. In some situations
+ it may be appropriate to grant <literal>EXECUTE</literal> permission for
+ <function>dblink_connect_u()</function> to specific users who are considered
+ trustworthy, but this should be done with care. It is also recommended
+ that any <filename>~/.pgpass</filename> file belonging to the server's user
+ <emphasis>not</emphasis> contain any records specifying a wildcard host name.
+ </para>
+
+ <para>
+ For further details see <function>dblink_connect()</function>.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-disconnect">
+ <indexterm>
+ <primary>dblink_disconnect</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_disconnect</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_disconnect</refname>
+ <refpurpose>closes a persistent connection to a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_disconnect() returns text
+dblink_disconnect(text connname) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_disconnect()</function> closes a connection previously opened
+ by <function>dblink_connect()</function>. The form with no arguments closes
+ an unnamed connection.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ The name of a named connection to be closed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns status, which is always <literal>OK</literal> (since any error
+ causes the function to throw an error instead of returning).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_disconnect();
+ dblink_disconnect
+-------------------
+ OK
+(1 row)
+
+SELECT dblink_disconnect('myconn');
+ dblink_disconnect
+-------------------
+ OK
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-function">
+ <indexterm>
+ <primary>dblink</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink</refname>
+ <refpurpose>executes a query in a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink(text connname, text sql [, bool fail_on_error]) returns setof record
+dblink(text connstr, text sql [, bool fail_on_error]) returns setof record
+dblink(text sql [, bool fail_on_error]) returns setof record
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink</function> executes a query (usually a <command>SELECT</command>,
+ but it can be any SQL statement that returns rows) in a remote database.
+ </para>
+
+ <para>
+ When two <type>text</type> arguments are given, the first one is first
+ looked up as a persistent connection's name; if found, the command
+ is executed on that connection. If not found, the first argument
+ is treated as a connection info string as for <function>dblink_connect</function>,
+ and the indicated connection is made just for the duration of this command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>connstr</parameter></term>
+ <listitem>
+ <para>
+ A connection info string, as previously described for
+ <function>dblink_connect</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>sql</parameter></term>
+ <listitem>
+ <para>
+ The SQL query that you wish to execute in the remote database,
+ for example <literal>select * from foo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>fail_on_error</parameter></term>
+ <listitem>
+ <para>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function returns no rows.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The function returns the row(s) produced by the query. Since
+ <function>dblink</function> can be used with any query, it is declared
+ to return <type>record</type>, rather than specifying any particular
+ set of columns. This means that you must specify the expected
+ set of columns in the calling query &mdash; otherwise
+ <productname>PostgreSQL</productname> would not know what to expect.
+ Here is an example:
+
+<programlisting>
+SELECT *
+ FROM dblink('dbname=mydb options=-csearch_path=',
+ 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text)
+ WHERE proname LIKE 'bytea%';
+</programlisting>
+
+ The <quote>alias</quote> part of the <literal>FROM</literal> clause must
+ specify the column names and types that the function will return.
+ (Specifying column names in an alias is actually standard SQL
+ syntax, but specifying column types is a <productname>PostgreSQL</productname>
+ extension.) This allows the system to understand what
+ <literal>*</literal> should expand to, and what <structname>proname</structname>
+ in the <literal>WHERE</literal> clause refers to, in advance of trying
+ to execute the function. At run time, an error will be thrown
+ if the actual query result from the remote database does not
+ have the same number of columns shown in the <literal>FROM</literal> clause.
+ The column names need not match, however, and <function>dblink</function>
+ does not insist on exact type matches either. It will succeed
+ so long as the returned data strings are valid input for the
+ column type declared in the <literal>FROM</literal> clause.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ A convenient way to use <function>dblink</function> with predetermined
+ queries is to create a view.
+ This allows the column type information to be buried in the view,
+ instead of having to spell it out in every query. For example,
+
+<programlisting>
+CREATE VIEW myremote_pg_proc AS
+ SELECT *
+ FROM dblink('dbname=postgres options=-csearch_path=',
+ 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text);
+
+SELECT * FROM myremote_pg_proc WHERE proname LIKE 'bytea%';
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT * FROM dblink('dbname=postgres options=-csearch_path=',
+ 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
+ proname | prosrc
+------------+------------
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteain | byteain
+ byteaout | byteaout
+(12 rows)
+
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT * FROM dblink('select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
+ proname | prosrc
+------------+------------
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteain | byteain
+ byteaout | byteaout
+(12 rows)
+
+SELECT dblink_connect('myconn', 'dbname=regression options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
+ proname | prosrc
+------------+------------
+ bytearecv | bytearecv
+ byteasend | byteasend
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteain | byteain
+ byteaout | byteaout
+(14 rows)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-exec">
+ <indexterm>
+ <primary>dblink_exec</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_exec</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_exec</refname>
+ <refpurpose>executes a command in a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_exec(text connname, text sql [, bool fail_on_error]) returns text
+dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text
+dblink_exec(text sql [, bool fail_on_error]) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_exec</function> executes a command (that is, any SQL statement
+ that doesn't return rows) in a remote database.
+ </para>
+
+ <para>
+ When two <type>text</type> arguments are given, the first one is first
+ looked up as a persistent connection's name; if found, the command
+ is executed on that connection. If not found, the first argument
+ is treated as a connection info string as for <function>dblink_connect</function>,
+ and the indicated connection is made just for the duration of this command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>connstr</parameter></term>
+ <listitem>
+ <para>
+ A connection info string, as previously described for
+ <function>dblink_connect</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>sql</parameter></term>
+ <listitem>
+ <para>
+ The SQL command that you wish to execute in the remote database,
+ for example
+ <literal>insert into foo values(0, 'a', '{"a0","b0","c0"}')</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>fail_on_error</parameter></term>
+ <listitem>
+ <para>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function's return value is set to <literal>ERROR</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns status, either the command's status string or <literal>ERROR</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_connect('dbname=dblink_test_standby');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_exec('insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');');
+ dblink_exec
+-----------------
+ INSERT 943366 1
+(1 row)
+
+SELECT dblink_connect('myconn', 'dbname=regression');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_exec('myconn', 'insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');');
+ dblink_exec
+------------------
+ INSERT 6432584 1
+(1 row)
+
+SELECT dblink_exec('myconn', 'insert into pg_class values (''foo'')',false);
+NOTICE: sql error
+DETAIL: ERROR: null value in column "relnamespace" violates not-null constraint
+
+ dblink_exec
+-------------
+ ERROR
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-open">
+ <indexterm>
+ <primary>dblink_open</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_open</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_open</refname>
+ <refpurpose>opens a cursor in a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text
+dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_open()</function> opens a cursor in a remote database.
+ The cursor can subsequently be manipulated with
+ <function>dblink_fetch()</function> and <function>dblink_close()</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>cursorname</parameter></term>
+ <listitem>
+ <para>
+ The name to assign to this cursor.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>sql</parameter></term>
+ <listitem>
+ <para>
+ The <command>SELECT</command> statement that you wish to execute in the remote
+ database, for example <literal>select * from pg_class</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>fail_on_error</parameter></term>
+ <listitem>
+ <para>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function's return value is set to <literal>ERROR</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns status, either <literal>OK</literal> or <literal>ERROR</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Since a cursor can only persist within a transaction,
+ <function>dblink_open</function> starts an explicit transaction block
+ (<command>BEGIN</command>) on the remote side, if the remote side was
+ not already within a transaction. This transaction will be
+ closed again when the matching <function>dblink_close</function> is
+ executed. Note that if
+ you use <function>dblink_exec</function> to change data between
+ <function>dblink_open</function> and <function>dblink_close</function>,
+ and then an error occurs or you use <function>dblink_disconnect</function> before
+ <function>dblink_close</function>, your change <emphasis>will be
+ lost</emphasis> because the transaction will be aborted.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_open('foo', 'select proname, prosrc from pg_proc');
+ dblink_open
+-------------
+ OK
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-fetch">
+ <indexterm>
+ <primary>dblink_fetch</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_fetch</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_fetch</refname>
+ <refpurpose>returns rows from an open cursor in a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record
+dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_fetch</function> fetches rows from a cursor previously
+ established by <function>dblink_open</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>cursorname</parameter></term>
+ <listitem>
+ <para>
+ The name of the cursor to fetch from.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>howmany</parameter></term>
+ <listitem>
+ <para>
+ The maximum number of rows to retrieve. The next <parameter>howmany</parameter>
+ rows are fetched, starting at the current cursor position, moving
+ forward. Once the cursor has reached its end, no more rows are produced.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>fail_on_error</parameter></term>
+ <listitem>
+ <para>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function returns no rows.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The function returns the row(s) fetched from the cursor. To use this
+ function, you will need to specify the expected set of columns,
+ as previously discussed for <function>dblink</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ On a mismatch between the number of return columns specified in the
+ <literal>FROM</literal> clause, and the actual number of columns returned by the
+ remote cursor, an error will be thrown. In this event, the remote cursor
+ is still advanced by as many rows as it would have been if the error had
+ not occurred. The same is true for any other error occurring in the local
+ query after the remote <command>FETCH</command> has been done.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_open('foo', 'select proname, prosrc from pg_proc where proname like ''bytea%''');
+ dblink_open
+-------------
+ OK
+(1 row)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+----------+----------
+ byteacat | byteacat
+ byteacmp | byteacmp
+ byteaeq | byteaeq
+ byteage | byteage
+ byteagt | byteagt
+(5 rows)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+-----------+-----------
+ byteain | byteain
+ byteale | byteale
+ bytealike | bytealike
+ bytealt | bytealt
+ byteane | byteane
+(5 rows)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+------------+------------
+ byteanlike | byteanlike
+ byteaout | byteaout
+(2 rows)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+----------+--------
+(0 rows)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-close">
+ <indexterm>
+ <primary>dblink_close</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_close</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_close</refname>
+ <refpurpose>closes a cursor in a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_close(text cursorname [, bool fail_on_error]) returns text
+dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_close</function> closes a cursor previously opened with
+ <function>dblink_open</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>cursorname</parameter></term>
+ <listitem>
+ <para>
+ The name of the cursor to close.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>fail_on_error</parameter></term>
+ <listitem>
+ <para>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function's return value is set to <literal>ERROR</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns status, either <literal>OK</literal> or <literal>ERROR</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If <function>dblink_open</function> started an explicit transaction block,
+ and this is the last remaining open cursor in this connection,
+ <function>dblink_close</function> will issue the matching <command>COMMIT</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_open('foo', 'select proname, prosrc from pg_proc');
+ dblink_open
+-------------
+ OK
+(1 row)
+
+SELECT dblink_close('foo');
+ dblink_close
+--------------
+ OK
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-get-connections">
+ <indexterm>
+ <primary>dblink_get_connections</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_get_connections</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_get_connections</refname>
+ <refpurpose>returns the names of all open named dblink connections</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_get_connections() returns text[]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_get_connections</function> returns an array of the names
+ of all open named <filename>dblink</filename> connections.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>Returns a text array of connection names, or NULL if none.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT dblink_get_connections();
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-error-message">
+ <indexterm>
+ <primary>dblink_error_message</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_error_message</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_error_message</refname>
+ <refpurpose>gets last error message on the named connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_error_message(text connname) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_error_message</function> fetches the most recent remote
+ error message for a given connection.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns last error message, or <literal>OK</literal> if there has been
+ no error in this connection.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When asynchronous queries are initiated by
+ <function>dblink_send_query</function>, the error message associated with
+ the connection might not get updated until the server's response message
+ is consumed. This typically means that <function>dblink_is_busy</function>
+ or <function>dblink_get_result</function> should be called prior to
+ <function>dblink_error_message</function>, so that any error generated by
+ the asynchronous query will be visible.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT dblink_error_message('dtest1');
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-send-query">
+ <indexterm>
+ <primary>dblink_send_query</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_send_query</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_send_query</refname>
+ <refpurpose>sends an async query to a remote database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_send_query(text connname, text sql) returns int
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_send_query</function> sends a query to be executed
+ asynchronously, that is, without immediately waiting for the result.
+ There must not be an async query already in progress on the
+ connection.
+ </para>
+
+ <para>
+ After successfully dispatching an async query, completion status
+ can be checked with <function>dblink_is_busy</function>, and the results
+ are ultimately collected with <function>dblink_get_result</function>.
+ It is also possible to attempt to cancel an active async query
+ using <function>dblink_cancel_query</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>sql</parameter></term>
+ <listitem>
+ <para>
+ The SQL statement that you wish to execute in the remote database,
+ for example <literal>select * from pg_class</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns 1 if the query was successfully dispatched, 0 otherwise.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 &lt; 3');
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-is-busy">
+ <indexterm>
+ <primary>dblink_is_busy</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_is_busy</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_is_busy</refname>
+ <refpurpose>checks if connection is busy with an async query</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_is_busy(text connname) returns int
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_is_busy</function> tests whether an async query is in progress.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to check.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns 1 if connection is busy, 0 if it is not busy.
+ If this function returns 0, it is guaranteed that
+ <function>dblink_get_result</function> will not block.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT dblink_is_busy('dtest1');
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-get-notify">
+ <indexterm>
+ <primary>dblink_get_notify</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_get_notify</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_get_notify</refname>
+ <refpurpose>retrieve async notifications on a connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_get_notify() returns setof (notify_name text, be_pid int, extra text)
+dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_get_notify</function> retrieves notifications on either
+ the unnamed connection, or on a named connection if specified.
+ To receive notifications via dblink, <function>LISTEN</function> must
+ first be issued, using <function>dblink_exec</function>.
+ For details see <xref linkend="sql-listen"/> and <xref linkend="sql-notify"/>.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ The name of a named connection to get notifications on.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+ <para>Returns <type>setof (notify_name text, be_pid int, extra text)</type>, or an empty set if none.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_exec('LISTEN virtual');
+ dblink_exec
+-------------
+ LISTEN
+(1 row)
+
+SELECT * FROM dblink_get_notify();
+ notify_name | be_pid | extra
+-------------+--------+-------
+(0 rows)
+
+NOTIFY virtual;
+NOTIFY
+
+SELECT * FROM dblink_get_notify();
+ notify_name | be_pid | extra
+-------------+--------+-------
+ virtual | 1229 |
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-get-result">
+ <indexterm>
+ <primary>dblink_get_result</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_get_result</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_get_result</refname>
+ <refpurpose>gets an async query result</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_get_result(text connname [, bool fail_on_error]) returns setof record
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_get_result</function> collects the results of an
+ asynchronous query previously sent with <function>dblink_send_query</function>.
+ If the query is not already completed, <function>dblink_get_result</function>
+ will wait until it is.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>fail_on_error</parameter></term>
+ <listitem>
+ <para>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function returns no rows.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ For an async query (that is, an SQL statement returning rows),
+ the function returns the row(s) produced by the query. To use this
+ function, you will need to specify the expected set of columns,
+ as previously discussed for <function>dblink</function>.
+ </para>
+
+ <para>
+ For an async command (that is, an SQL statement not returning rows),
+ the function returns a single row with a single text column containing
+ the command's status string. It is still necessary to specify that
+ the result will have a single text column in the calling <literal>FROM</literal>
+ clause.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ This function <emphasis>must</emphasis> be called if
+ <function>dblink_send_query</function> returned 1.
+ It must be called once for each query
+ sent, and one additional time to obtain an empty set result,
+ before the connection can be used again.
+ </para>
+
+ <para>
+ When using <function>dblink_send_query</function> and
+ <function>dblink_get_result</function>, <application>dblink</application> fetches the entire
+ remote query result before returning any of it to the local query
+ processor. If the query returns a large number of rows, this can result
+ in transient memory bloat in the local session. It may be better to open
+ such a query as a cursor with <function>dblink_open</function> and then fetch a
+ manageable number of rows at a time. Alternatively, use plain
+ <function>dblink()</function>, which avoids memory bloat by spooling large result
+ sets to disk.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+contrib_regression=# SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+contrib_regression=# SELECT * FROM
+contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 &lt; 3') AS t1;
+ t1
+----
+ 1
+(1 row)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+------------
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+(3 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+----
+(0 rows)
+
+contrib_regression=# SELECT * FROM
+contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 &lt; 3; select * from foo where f1 &gt; 6') AS t1;
+ t1
+----
+ 1
+(1 row)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+------------
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+(3 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+---------------
+ 7 | h | {a7,b7,c7}
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ 10 | k | {a10,b10,c10}
+(4 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+----
+(0 rows)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-cancel-query">
+ <indexterm>
+ <primary>dblink_cancel_query</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_cancel_query</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_cancel_query</refname>
+ <refpurpose>cancels any active query on the named connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_cancel_query(text connname) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_cancel_query</function> attempts to cancel any query that
+ is in progress on the named connection. Note that this is not
+ certain to succeed (since, for example, the remote query might
+ already have finished). A cancel request simply improves the
+ odds that the query will fail soon. You must still complete the
+ normal query protocol, for example by calling
+ <function>dblink_get_result</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>connname</parameter></term>
+ <listitem>
+ <para>
+ Name of the connection to use.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns <literal>OK</literal> if the cancel request has been sent, or
+ the text of an error message on failure.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT dblink_cancel_query('dtest1');
+</programlisting>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-get-pkey">
+ <indexterm>
+ <primary>dblink_get_pkey</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_get_pkey</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_get_pkey</refname>
+ <refpurpose>returns the positions and field names of a relation's
+ primary key fields
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_get_pkey(text relname) returns setof dblink_pkey_results
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_get_pkey</function> provides information about the primary
+ key of a relation in the local database. This is sometimes useful
+ in generating queries to be sent to remote databases.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>relname</parameter></term>
+ <listitem>
+ <para>
+ Name of a local relation, for example <literal>foo</literal> or
+ <literal>myschema.mytab</literal>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <literal>"FooBar"</literal>; without quotes, the string
+ will be folded to lower case.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Returns one row for each primary key field, or no rows if the relation
+ has no primary key. The result row type is defined as
+
+<programlisting>
+CREATE TYPE dblink_pkey_results AS (position int, colname text);
+</programlisting>
+
+ The <literal>position</literal> column simply runs from 1 to <replaceable>N</replaceable>;
+ it is the number of the field within the primary key, not the number
+ within the table's columns.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+CREATE TABLE foobar (
+ f1 int,
+ f2 int,
+ f3 int,
+ PRIMARY KEY (f1, f2, f3)
+);
+CREATE TABLE
+
+SELECT * FROM dblink_get_pkey('foobar');
+ position | colname
+----------+---------
+ 1 | f1
+ 2 | f2
+ 3 | f3
+(3 rows)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-build-sql-insert">
+ <indexterm>
+ <primary>dblink_build_sql_insert</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_build_sql_insert</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_build_sql_insert</refname>
+ <refpurpose>
+ builds an INSERT statement using a local tuple, replacing the
+ primary key field values with alternative supplied values
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_build_sql_insert(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] src_pk_att_vals_array,
+ text[] tgt_pk_att_vals_array) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_build_sql_insert</function> can be useful in doing selective
+ replication of a local table to a remote database. It selects a row
+ from the local table based on primary key, and then builds an SQL
+ <command>INSERT</command> command that will duplicate that row, but with
+ the primary key values replaced by the values in the last argument.
+ (To make an exact copy of the row, just specify the same values for
+ the last two arguments.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>relname</parameter></term>
+ <listitem>
+ <para>
+ Name of a local relation, for example <literal>foo</literal> or
+ <literal>myschema.mytab</literal>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <literal>"FooBar"</literal>; without quotes, the string
+ will be folded to lower case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>primary_key_attnums</parameter></term>
+ <listitem>
+ <para>
+ Attribute numbers (1-based) of the primary key fields,
+ for example <literal>1 2</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>num_primary_key_atts</parameter></term>
+ <listitem>
+ <para>
+ The number of primary key fields.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>src_pk_att_vals_array</parameter></term>
+ <listitem>
+ <para>
+ Values of the primary key fields to be used to look up the
+ local tuple. Each field is represented in text form.
+ An error is thrown if there is no local row with these
+ primary key values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>tgt_pk_att_vals_array</parameter></term>
+ <listitem>
+ <para>
+ Values of the primary key fields to be placed in the resulting
+ <command>INSERT</command> command. Each field is represented in text form.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>Returns the requested SQL statement as text.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ As of <productname>PostgreSQL</productname> 9.0, the attribute numbers in
+ <parameter>primary_key_attnums</parameter> are interpreted as logical
+ column numbers, corresponding to the column's position in
+ <literal>SELECT * FROM relname</literal>. Previous versions interpreted the
+ numbers as physical column positions. There is a difference if any
+ column(s) to the left of the indicated column have been dropped during
+ the lifetime of the table.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}');
+ dblink_build_sql_insert
+--------------------------------------------------
+ INSERT INTO foo(f1,f2,f3) VALUES('1','b''a','1')
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-build-sql-delete">
+ <indexterm>
+ <primary>dblink_build_sql_delete</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_build_sql_delete</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_build_sql_delete</refname>
+ <refpurpose>builds a DELETE statement using supplied values for primary
+ key field values
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_build_sql_delete(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] tgt_pk_att_vals_array) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_build_sql_delete</function> can be useful in doing selective
+ replication of a local table to a remote database. It builds an SQL
+ <command>DELETE</command> command that will delete the row with the given
+ primary key values.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>relname</parameter></term>
+ <listitem>
+ <para>
+ Name of a local relation, for example <literal>foo</literal> or
+ <literal>myschema.mytab</literal>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <literal>"FooBar"</literal>; without quotes, the string
+ will be folded to lower case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>primary_key_attnums</parameter></term>
+ <listitem>
+ <para>
+ Attribute numbers (1-based) of the primary key fields,
+ for example <literal>1 2</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>num_primary_key_atts</parameter></term>
+ <listitem>
+ <para>
+ The number of primary key fields.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>tgt_pk_att_vals_array</parameter></term>
+ <listitem>
+ <para>
+ Values of the primary key fields to be used in the resulting
+ <command>DELETE</command> command. Each field is represented in text form.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>Returns the requested SQL statement as text.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ As of <productname>PostgreSQL</productname> 9.0, the attribute numbers in
+ <parameter>primary_key_attnums</parameter> are interpreted as logical
+ column numbers, corresponding to the column's position in
+ <literal>SELECT * FROM relname</literal>. Previous versions interpreted the
+ numbers as physical column positions. There is a difference if any
+ column(s) to the left of the indicated column have been dropped during
+ the lifetime of the table.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_build_sql_delete('"MyFoo"', '1 2', 2, '{"1", "b"}');
+ dblink_build_sql_delete
+---------------------------------------------
+ DELETE FROM "MyFoo" WHERE f1='1' AND f2='b'
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+ <refentry id="contrib-dblink-build-sql-update">
+ <indexterm>
+ <primary>dblink_build_sql_update</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>dblink_build_sql_update</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dblink_build_sql_update</refname>
+ <refpurpose>builds an UPDATE statement using a local tuple, replacing
+ the primary key field values with alternative supplied values
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+dblink_build_sql_update(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] src_pk_att_vals_array,
+ text[] tgt_pk_att_vals_array) returns text
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>dblink_build_sql_update</function> can be useful in doing selective
+ replication of a local table to a remote database. It selects a row
+ from the local table based on primary key, and then builds an SQL
+ <command>UPDATE</command> command that will duplicate that row, but with
+ the primary key values replaced by the values in the last argument.
+ (To make an exact copy of the row, just specify the same values for
+ the last two arguments.) The <command>UPDATE</command> command always assigns
+ all fields of the row &mdash; the main difference between this and
+ <function>dblink_build_sql_insert</function> is that it's assumed that
+ the target row already exists in the remote table.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>relname</parameter></term>
+ <listitem>
+ <para>
+ Name of a local relation, for example <literal>foo</literal> or
+ <literal>myschema.mytab</literal>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <literal>"FooBar"</literal>; without quotes, the string
+ will be folded to lower case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>primary_key_attnums</parameter></term>
+ <listitem>
+ <para>
+ Attribute numbers (1-based) of the primary key fields,
+ for example <literal>1 2</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>num_primary_key_atts</parameter></term>
+ <listitem>
+ <para>
+ The number of primary key fields.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>src_pk_att_vals_array</parameter></term>
+ <listitem>
+ <para>
+ Values of the primary key fields to be used to look up the
+ local tuple. Each field is represented in text form.
+ An error is thrown if there is no local row with these
+ primary key values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>tgt_pk_att_vals_array</parameter></term>
+ <listitem>
+ <para>
+ Values of the primary key fields to be placed in the resulting
+ <command>UPDATE</command> command. Each field is represented in text form.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>Returns the requested SQL statement as text.</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ As of <productname>PostgreSQL</productname> 9.0, the attribute numbers in
+ <parameter>primary_key_attnums</parameter> are interpreted as logical
+ column numbers, corresponding to the column's position in
+ <literal>SELECT * FROM relname</literal>. Previous versions interpreted the
+ numbers as physical column positions. There is a difference if any
+ column(s) to the left of the indicated column have been dropped during
+ the lifetime of the table.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+SELECT dblink_build_sql_update('foo', '1 2', 2, '{"1", "a"}', '{"1", "b"}');
+ dblink_build_sql_update
+-------------------------------------------------------------
+ UPDATE foo SET f1='1',f2='b',f3='1' WHERE f1='1' AND f2='b'
+(1 row)
+</screen>
+ </refsect1>
+ </refentry>
+
+</sect1>
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
new file mode 100644
index 0000000..cfe3dcb
--- /dev/null
+++ b/doc/src/sgml/ddl.sgml
@@ -0,0 +1,5245 @@
+<!-- doc/src/sgml/ddl.sgml -->
+
+<chapter id="ddl">
+ <title>Data Definition</title>
+
+ <para>
+ This chapter covers how one creates the database structures that
+ will hold one's data. In a relational database, the raw data is
+ stored in tables, so the majority of this chapter is devoted to
+ explaining how tables are created and modified and what features are
+ available to control what data is stored in the tables.
+ Subsequently, we discuss how tables can be organized into
+ schemas, and how privileges can be assigned to tables. Finally,
+ we will briefly look at other features that affect the data storage,
+ such as inheritance, table partitioning, views, functions, and
+ triggers.
+ </para>
+
+ <sect1 id="ddl-basics">
+ <title>Table Basics</title>
+
+ <indexterm zone="ddl-basics">
+ <primary>table</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>row</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>column</primary>
+ </indexterm>
+
+ <para>
+ A table in a relational database is much like a table on paper: It
+ consists of rows and columns. The number and order of the columns
+ is fixed, and each column has a name. The number of rows is
+ variable &mdash; it reflects how much data is stored at a given moment.
+ SQL does not make any guarantees about the order of the rows in a
+ table. When a table is read, the rows will appear in an unspecified order,
+ unless sorting is explicitly requested. This is covered in <xref
+ linkend="queries"/>. Furthermore, SQL does not assign unique
+ identifiers to rows, so it is possible to have several completely
+ identical rows in a table. This is a consequence of the
+ mathematical model that underlies SQL but is usually not desirable.
+ Later in this chapter we will see how to deal with this issue.
+ </para>
+
+ <para>
+ Each column has a data type. The data type constrains the set of
+ possible values that can be assigned to a column and assigns
+ semantics to the data stored in the column so that it can be used
+ for computations. For instance, a column declared to be of a
+ numerical type will not accept arbitrary text strings, and the data
+ stored in such a column can be used for mathematical computations.
+ By contrast, a column declared to be of a character string type
+ will accept almost any kind of data but it does not lend itself to
+ mathematical calculations, although other operations such as string
+ concatenation are available.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> includes a sizable set of
+ built-in data types that fit many applications. Users can also
+ define their own data types. Most built-in data types have obvious
+ names and semantics, so we defer a detailed explanation to <xref
+ linkend="datatype"/>. Some of the frequently used data types are
+ <type>integer</type> for whole numbers, <type>numeric</type> for
+ possibly fractional numbers, <type>text</type> for character
+ strings, <type>date</type> for dates, <type>time</type> for
+ time-of-day values, and <type>timestamp</type> for values
+ containing both date and time.
+ </para>
+
+ <indexterm>
+ <primary>table</primary>
+ <secondary>creating</secondary>
+ </indexterm>
+
+ <para>
+ To create a table, you use the aptly named <xref
+ linkend="sql-createtable"/> command.
+ In this command you specify at least a name for the new table, the
+ names of the columns and the data type of each column. For
+ example:
+<programlisting>
+CREATE TABLE my_first_table (
+ first_column text,
+ second_column integer
+);
+</programlisting>
+ This creates a table named <literal>my_first_table</literal> with
+ two columns. The first column is named
+ <literal>first_column</literal> and has a data type of
+ <type>text</type>; the second column has the name
+ <literal>second_column</literal> and the type <type>integer</type>.
+ The table and column names follow the identifier syntax explained
+ in <xref linkend="sql-syntax-identifiers"/>. The type names are
+ usually also identifiers, but there are some exceptions. Note that the
+ column list is comma-separated and surrounded by parentheses.
+ </para>
+
+ <para>
+ Of course, the previous example was heavily contrived. Normally,
+ you would give names to your tables and columns that convey what
+ kind of data they store. So let's look at a more realistic
+ example:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric
+);
+</programlisting>
+ (The <type>numeric</type> type can store fractional components, as
+ would be typical of monetary amounts.)
+ </para>
+
+ <tip>
+ <para>
+ When you create many interrelated tables it is wise to choose a
+ consistent naming pattern for the tables and columns. For
+ instance, there is a choice of using singular or plural nouns for
+ table names, both of which are favored by some theorist or other.
+ </para>
+ </tip>
+
+ <para>
+ There is a limit on how many columns a table can contain.
+ Depending on the column types, it is between 250 and 1600.
+ However, defining a table with anywhere near this many columns is
+ highly unusual and often a questionable design.
+ </para>
+
+ <indexterm>
+ <primary>table</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+
+ <para>
+ If you no longer need a table, you can remove it using the <xref
+ linkend="sql-droptable"/> command.
+ For example:
+<programlisting>
+DROP TABLE my_first_table;
+DROP TABLE products;
+</programlisting>
+ Attempting to drop a table that does not exist is an error.
+ Nevertheless, it is common in SQL script files to unconditionally
+ try to drop each table before creating it, ignoring any error
+ messages, so that the script works whether or not the table exists.
+ (If you like, you can use the <literal>DROP TABLE IF EXISTS</literal> variant
+ to avoid the error messages, but this is not standard SQL.)
+ </para>
+
+ <para>
+ If you need to modify a table that already exists, see <xref
+ linkend="ddl-alter"/> later in this chapter.
+ </para>
+
+ <para>
+ With the tools discussed so far you can create fully functional
+ tables. The remainder of this chapter is concerned with adding
+ features to the table definition to ensure data integrity,
+ security, or convenience. If you are eager to fill your tables with
+ data now you can skip ahead to <xref linkend="dml"/> and read the
+ rest of this chapter later.
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-default">
+ <title>Default Values</title>
+
+ <indexterm zone="ddl-default">
+ <primary>default value</primary>
+ </indexterm>
+
+ <para>
+ A column can be assigned a default value. When a new row is
+ created and no values are specified for some of the columns, those
+ columns will be filled with their respective default values. A
+ data manipulation command can also request explicitly that a column
+ be set to its default value, without having to know what that value is.
+ (Details about data manipulation commands are in <xref linkend="dml"/>.)
+ </para>
+
+ <para>
+ <indexterm><primary>null value</primary><secondary>default value</secondary></indexterm>
+ If no default value is declared explicitly, the default value is the
+ null value. This usually makes sense because a null value can
+ be considered to represent unknown data.
+ </para>
+
+ <para>
+ In a table definition, default values are listed after the column
+ data type. For example:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric <emphasis>DEFAULT 9.99</emphasis>
+);
+</programlisting>
+ </para>
+
+ <para>
+ The default value can be an expression, which will be
+ evaluated whenever the default value is inserted
+ (<emphasis>not</emphasis> when the table is created). A common example
+ is for a <type>timestamp</type> column to have a default of <literal>CURRENT_TIMESTAMP</literal>,
+ so that it gets set to the time of row insertion. Another common
+ example is generating a <quote>serial number</quote> for each row.
+ In <productname>PostgreSQL</productname> this is typically done by
+ something like:
+<programlisting>
+CREATE TABLE products (
+ product_no integer <emphasis>DEFAULT nextval('products_product_no_seq')</emphasis>,
+ ...
+);
+</programlisting>
+ where the <literal>nextval()</literal> function supplies successive values
+ from a <firstterm>sequence object</firstterm> (see <xref
+ linkend="functions-sequence"/>). This arrangement is sufficiently common
+ that there's a special shorthand for it:
+<programlisting>
+CREATE TABLE products (
+ product_no <emphasis>SERIAL</emphasis>,
+ ...
+);
+</programlisting>
+ The <literal>SERIAL</literal> shorthand is discussed further in <xref
+ linkend="datatype-serial"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-generated-columns">
+ <title>Generated Columns</title>
+
+ <indexterm zone="ddl-generated-columns">
+ <primary>generated column</primary>
+ </indexterm>
+
+ <para>
+ A generated column is a special column that is always computed from other
+ columns. Thus, it is for columns what a view is for tables. There are two
+ kinds of generated columns: stored and virtual. A stored generated column
+ is computed when it is written (inserted or updated) and occupies storage
+ as if it were a normal column. A virtual generated column occupies no
+ storage and is computed when it is read. Thus, a virtual generated column
+ is similar to a view and a stored generated column is similar to a
+ materialized view (except that it is always updated automatically).
+ PostgreSQL currently implements only stored generated columns.
+ </para>
+
+ <para>
+ To create a generated column, use the <literal>GENERATED ALWAYS
+ AS</literal> clause in <command>CREATE TABLE</command>, for example:
+<programlisting>
+CREATE TABLE people (
+ ...,
+ height_cm numeric,
+ height_in numeric <emphasis>GENERATED ALWAYS AS (height_cm / 2.54) STORED</emphasis>
+);
+</programlisting>
+ The keyword <literal>STORED</literal> must be specified to choose the
+ stored kind of generated column. See <xref linkend="sql-createtable"/> for
+ more details.
+ </para>
+
+ <para>
+ A generated column cannot be written to directly. In
+ <command>INSERT</command> or <command>UPDATE</command> commands, a value
+ cannot be specified for a generated column, but the keyword
+ <literal>DEFAULT</literal> may be specified.
+ </para>
+
+ <para>
+ Consider the differences between a column with a default and a generated
+ column. The column default is evaluated once when the row is first
+ inserted if no other value was provided; a generated column is updated
+ whenever the row changes and cannot be overridden. A column default may
+ not refer to other columns of the table; a generation expression would
+ normally do so. A column default can use volatile functions, for example
+ <literal>random()</literal> or functions referring to the current time;
+ this is not allowed for generated columns.
+ </para>
+
+ <para>
+ Several restrictions apply to the definition of generated columns and
+ tables involving generated columns:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The generation expression can only use immutable functions and cannot
+ use subqueries or reference anything other than the current row in any
+ way.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A generation expression cannot reference another generated column.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A generation expression cannot reference a system column, except
+ <varname>tableoid</varname>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A generated column cannot have a column default or an identity definition.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A generated column cannot be part of a partition key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Foreign tables can have generated columns. See <xref
+ linkend="sql-createforeigntable"/> for details.
+ </para>
+ </listitem>
+ <listitem>
+ <para>For inheritance:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ If a parent column is a generated column, a child column must also be
+ a generated column using the same expression. In the definition of
+ the child column, leave off the <literal>GENERATED</literal> clause,
+ as it will be copied from the parent.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In case of multiple inheritance, if one parent column is a generated
+ column, then all parent columns must be generated columns and with the
+ same expression.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a parent column is not a generated column, a child column may be
+ defined to be a generated column or not.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Additional considerations apply to the use of generated columns.
+ <itemizedlist>
+ <listitem>
+ <para>
+ Generated columns maintain access privileges separately from their
+ underlying base columns. So, it is possible to arrange it so that a
+ particular role can read from a generated column but not from the
+ underlying base columns.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Generated columns are, conceptually, updated after
+ <literal>BEFORE</literal> triggers have run. Therefore, changes made to
+ base columns in a <literal>BEFORE</literal> trigger will be reflected in
+ generated columns. But conversely, it is not allowed to access
+ generated columns in <literal>BEFORE</literal> triggers.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-constraints">
+ <title>Constraints</title>
+
+ <indexterm zone="ddl-constraints">
+ <primary>constraint</primary>
+ </indexterm>
+
+ <para>
+ Data types are a way to limit the kind of data that can be stored
+ in a table. For many applications, however, the constraint they
+ provide is too coarse. For example, a column containing a product
+ price should probably only accept positive values. But there is no
+ standard data type that accepts only positive numbers. Another issue is
+ that you might want to constrain column data with respect to other
+ columns or rows. For example, in a table containing product
+ information, there should be only one row for each product number.
+ </para>
+
+ <para>
+ To that end, SQL allows you to define constraints on columns and
+ tables. Constraints give you as much control over the data in your
+ tables as you wish. If a user attempts to store data in a column
+ that would violate a constraint, an error is raised. This applies
+ even if the value came from the default value definition.
+ </para>
+
+ <sect2 id="ddl-constraints-check-constraints">
+ <title>Check Constraints</title>
+
+ <indexterm>
+ <primary>check constraint</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>check</secondary>
+ </indexterm>
+
+ <para>
+ A check constraint is the most generic constraint type. It allows
+ you to specify that the value in a certain column must satisfy a
+ Boolean (truth-value) expression. For instance, to require positive
+ product prices, you could use:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric <emphasis>CHECK (price &gt; 0)</emphasis>
+);
+</programlisting>
+ </para>
+
+ <para>
+ As you see, the constraint definition comes after the data type,
+ just like default value definitions. Default values and
+ constraints can be listed in any order. A check constraint
+ consists of the key word <literal>CHECK</literal> followed by an
+ expression in parentheses. The check constraint expression should
+ involve the column thus constrained, otherwise the constraint
+ would not make too much sense.
+ </para>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>name</secondary>
+ </indexterm>
+
+ <para>
+ You can also give the constraint a separate name. This clarifies
+ error messages and allows you to refer to the constraint when you
+ need to change it. The syntax is:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric <emphasis>CONSTRAINT positive_price</emphasis> CHECK (price &gt; 0)
+);
+</programlisting>
+ So, to specify a named constraint, use the key word
+ <literal>CONSTRAINT</literal> followed by an identifier followed
+ by the constraint definition. (If you don't specify a constraint
+ name in this way, the system chooses a name for you.)
+ </para>
+
+ <para>
+ A check constraint can also refer to several columns. Say you
+ store a regular price and a discounted price, and you want to
+ ensure that the discounted price is lower than the regular price:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric CHECK (price &gt; 0),
+ discounted_price numeric CHECK (discounted_price &gt; 0),
+ <emphasis>CHECK (price &gt; discounted_price)</emphasis>
+);
+</programlisting>
+ </para>
+
+ <para>
+ The first two constraints should look familiar. The third one
+ uses a new syntax. It is not attached to a particular column,
+ instead it appears as a separate item in the comma-separated
+ column list. Column definitions and these constraint
+ definitions can be listed in mixed order.
+ </para>
+
+ <para>
+ We say that the first two constraints are column constraints, whereas the
+ third one is a table constraint because it is written separately
+ from any one column definition. Column constraints can also be
+ written as table constraints, while the reverse is not necessarily
+ possible, since a column constraint is supposed to refer to only the
+ column it is attached to. (<productname>PostgreSQL</productname> doesn't
+ enforce that rule, but you should follow it if you want your table
+ definitions to work with other database systems.) The above example could
+ also be written as:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ CHECK (price &gt; 0),
+ discounted_price numeric,
+ CHECK (discounted_price &gt; 0),
+ CHECK (price &gt; discounted_price)
+);
+</programlisting>
+ or even:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric CHECK (price &gt; 0),
+ discounted_price numeric,
+ CHECK (discounted_price &gt; 0 AND price &gt; discounted_price)
+);
+</programlisting>
+ It's a matter of taste.
+ </para>
+
+ <para>
+ Names can be assigned to table constraints in the same way as
+ column constraints:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ CHECK (price &gt; 0),
+ discounted_price numeric,
+ CHECK (discounted_price &gt; 0),
+ <emphasis>CONSTRAINT valid_discount</emphasis> CHECK (price &gt; discounted_price)
+);
+</programlisting>
+ </para>
+
+ <indexterm>
+ <primary>null value</primary>
+ <secondary sortas="check constraints">with check constraints</secondary>
+ </indexterm>
+
+ <para>
+ It should be noted that a check constraint is satisfied if the
+ check expression evaluates to true or the null value. Since most
+ expressions will evaluate to the null value if any operand is null,
+ they will not prevent null values in the constrained columns. To
+ ensure that a column does not contain null values, the not-null
+ constraint described in the next section can be used.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> does not support
+ <literal>CHECK</literal> constraints that reference table data other than
+ the new or updated row being checked. While a <literal>CHECK</literal>
+ constraint that violates this rule may appear to work in simple
+ tests, it cannot guarantee that the database will not reach a state
+ in which the constraint condition is false (due to subsequent changes
+ of the other row(s) involved). This would cause a database dump and
+ restore to fail. The restore could fail even when the complete
+ database state is consistent with the constraint, due to rows not
+ being loaded in an order that will satisfy the constraint. If
+ possible, use <literal>UNIQUE</literal>, <literal>EXCLUDE</literal>,
+ or <literal>FOREIGN KEY</literal> constraints to express
+ cross-row and cross-table restrictions.
+ </para>
+
+ <para>
+ If what you desire is a one-time check against other rows at row
+ insertion, rather than a continuously-maintained consistency
+ guarantee, a custom <link linkend="triggers">trigger</link> can be used
+ to implement that. (This approach avoids the dump/restore problem because
+ <application>pg_dump</application> does not reinstall triggers until after
+ restoring data, so that the check will not be enforced during a
+ dump/restore.)
+ </para>
+ </note>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> assumes that
+ <literal>CHECK</literal> constraints' conditions are immutable, that
+ is, they will always give the same result for the same input row.
+ This assumption is what justifies examining <literal>CHECK</literal>
+ constraints only when rows are inserted or updated, and not at other
+ times. (The warning above about not referencing other table data is
+ really a special case of this restriction.)
+ </para>
+
+ <para>
+ An example of a common way to break this assumption is to reference a
+ user-defined function in a <literal>CHECK</literal> expression, and
+ then change the behavior of that
+ function. <productname>PostgreSQL</productname> does not disallow
+ that, but it will not notice if there are rows in the table that now
+ violate the <literal>CHECK</literal> constraint. That would cause a
+ subsequent database dump and restore to fail.
+ The recommended way to handle such a change is to drop the constraint
+ (using <command>ALTER TABLE</command>), adjust the function definition,
+ and re-add the constraint, thereby rechecking it against all table rows.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Not-Null Constraints</title>
+
+ <indexterm>
+ <primary>not-null constraint</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>NOT NULL</secondary>
+ </indexterm>
+
+ <para>
+ A not-null constraint simply specifies that a column must not
+ assume the null value. A syntax example:
+<programlisting>
+CREATE TABLE products (
+ product_no integer <emphasis>NOT NULL</emphasis>,
+ name text <emphasis>NOT NULL</emphasis>,
+ price numeric
+);
+</programlisting>
+ </para>
+
+ <para>
+ A not-null constraint is always written as a column constraint. A
+ not-null constraint is functionally equivalent to creating a check
+ constraint <literal>CHECK (<replaceable>column_name</replaceable>
+ IS NOT NULL)</literal>, but in
+ <productname>PostgreSQL</productname> creating an explicit
+ not-null constraint is more efficient. The drawback is that you
+ cannot give explicit names to not-null constraints created this
+ way.
+ </para>
+
+ <para>
+ Of course, a column can have more than one constraint. Just write
+ the constraints one after another:
+<programlisting>
+CREATE TABLE products (
+ product_no integer NOT NULL,
+ name text NOT NULL,
+ price numeric NOT NULL CHECK (price &gt; 0)
+);
+</programlisting>
+ The order doesn't matter. It does not necessarily determine in which
+ order the constraints are checked.
+ </para>
+
+ <para>
+ The <literal>NOT NULL</literal> constraint has an inverse: the
+ <literal>NULL</literal> constraint. This does not mean that the
+ column must be null, which would surely be useless. Instead, this
+ simply selects the default behavior that the column might be null.
+ The <literal>NULL</literal> constraint is not present in the SQL
+ standard and should not be used in portable applications. (It was
+ only added to <productname>PostgreSQL</productname> to be
+ compatible with some other database systems.) Some users, however,
+ like it because it makes it easy to toggle the constraint in a
+ script file. For example, you could start with:
+<programlisting>
+CREATE TABLE products (
+ product_no integer NULL,
+ name text NULL,
+ price numeric NULL
+);
+</programlisting>
+ and then insert the <literal>NOT</literal> key word where desired.
+ </para>
+
+ <tip>
+ <para>
+ In most database designs the majority of columns should be marked
+ not null.
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2 id="ddl-constraints-unique-constraints">
+ <title>Unique Constraints</title>
+
+ <indexterm>
+ <primary>unique constraint</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>unique</secondary>
+ </indexterm>
+
+ <para>
+ Unique constraints ensure that the data contained in a column, or a
+ group of columns, is unique among all the rows in the
+ table. The syntax is:
+<programlisting>
+CREATE TABLE products (
+ product_no integer <emphasis>UNIQUE</emphasis>,
+ name text,
+ price numeric
+);
+</programlisting>
+ when written as a column constraint, and:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ <emphasis>UNIQUE (product_no)</emphasis>
+);
+</programlisting>
+ when written as a table constraint.
+ </para>
+
+ <para>
+ To define a unique constraint for a group of columns, write it as a
+ table constraint with the column names separated by commas:
+<programlisting>
+CREATE TABLE example (
+ a integer,
+ b integer,
+ c integer,
+ <emphasis>UNIQUE (a, c)</emphasis>
+);
+</programlisting>
+ This specifies that the combination of values in the indicated columns
+ is unique across the whole table, though any one of the columns
+ need not be (and ordinarily isn't) unique.
+ </para>
+
+ <para>
+ You can assign your own name for a unique constraint, in the usual way:
+<programlisting>
+CREATE TABLE products (
+ product_no integer <emphasis>CONSTRAINT must_be_different</emphasis> UNIQUE,
+ name text,
+ price numeric
+);
+</programlisting>
+ </para>
+
+ <para>
+ Adding a unique constraint will automatically create a unique B-tree
+ index on the column or group of columns listed in the constraint.
+ A uniqueness restriction covering only some rows cannot be written as
+ a unique constraint, but it is possible to enforce such a restriction by
+ creating a unique <link linkend="indexes-partial">partial index</link>.
+ </para>
+
+ <indexterm>
+ <primary>null value</primary>
+ <secondary sortas="unique constraints">with unique constraints</secondary>
+ </indexterm>
+
+ <para>
+ In general, a unique constraint is violated if there is more than
+ one row in the table where the values of all of the
+ columns included in the constraint are equal.
+ By default, two null values are not considered equal in this
+ comparison. That means even in the presence of a
+ unique constraint it is possible to store duplicate
+ rows that contain a null value in at least one of the constrained
+ columns. This behavior can be changed by adding the clause <literal>NULLS
+ NOT DISTINCT</literal>, like
+<programlisting>
+CREATE TABLE products (
+ product_no integer UNIQUE <emphasis>NULLS NOT DISTINCT</emphasis>,
+ name text,
+ price numeric
+);
+</programlisting>
+ or
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ UNIQUE <emphasis>NULLS NOT DISTINCT</emphasis> (product_no)
+);
+</programlisting>
+ The default behavior can be specified explicitly using <literal>NULLS
+ DISTINCT</literal>. The default null treatment in unique constraints is
+ implementation-defined according to the SQL standard, and other
+ implementations have a different behavior. So be careful when developing
+ applications that are intended to be portable.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-constraints-primary-keys">
+ <title>Primary Keys</title>
+
+ <indexterm>
+ <primary>primary key</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>primary key</secondary>
+ </indexterm>
+
+ <para>
+ A primary key constraint indicates that a column, or group of columns,
+ can be used as a unique identifier for rows in the table. This
+ requires that the values be both unique and not null. So, the following
+ two table definitions accept the same data:
+<programlisting>
+CREATE TABLE products (
+ product_no integer UNIQUE NOT NULL,
+ name text,
+ price numeric
+);
+</programlisting>
+
+<programlisting>
+CREATE TABLE products (
+ product_no integer <emphasis>PRIMARY KEY</emphasis>,
+ name text,
+ price numeric
+);
+</programlisting>
+ </para>
+
+ <para>
+ Primary keys can span more than one column; the syntax
+ is similar to unique constraints:
+<programlisting>
+CREATE TABLE example (
+ a integer,
+ b integer,
+ c integer,
+ <emphasis>PRIMARY KEY (a, c)</emphasis>
+);
+</programlisting>
+ </para>
+
+ <para>
+ Adding a primary key will automatically create a unique B-tree index
+ on the column or group of columns listed in the primary key, and will
+ force the column(s) to be marked <literal>NOT NULL</literal>.
+ </para>
+
+ <para>
+ A table can have at most one primary key. (There can be any number
+ of unique and not-null constraints, which are functionally almost the
+ same thing, but only one can be identified as the primary key.)
+ Relational database theory
+ dictates that every table must have a primary key. This rule is
+ not enforced by <productname>PostgreSQL</productname>, but it is
+ usually best to follow it.
+ </para>
+
+ <para>
+ Primary keys are useful both for
+ documentation purposes and for client applications. For example,
+ a GUI application that allows modifying row values probably needs
+ to know the primary key of a table to be able to identify rows
+ uniquely. There are also various ways in which the database system
+ makes use of a primary key if one has been declared; for example,
+ the primary key defines the default target column(s) for foreign keys
+ referencing its table.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-constraints-fk">
+ <title>Foreign Keys</title>
+
+ <indexterm>
+ <primary>foreign key</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>foreign key</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>referential integrity</primary>
+ </indexterm>
+
+ <para>
+ A foreign key constraint specifies that the values in a column (or
+ a group of columns) must match the values appearing in some row
+ of another table.
+ We say this maintains the <firstterm>referential
+ integrity</firstterm> between two related tables.
+ </para>
+
+ <para>
+ Say you have the product table that we have used several times already:
+<programlisting>
+CREATE TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+</programlisting>
+ Let's also assume you have a table storing orders of those
+ products. We want to ensure that the orders table only contains
+ orders of products that actually exist. So we define a foreign
+ key constraint in the orders table that references the products
+ table:
+<programlisting>
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ product_no integer <emphasis>REFERENCES products (product_no)</emphasis>,
+ quantity integer
+);
+</programlisting>
+ Now it is impossible to create orders with non-NULL
+ <structfield>product_no</structfield> entries that do not appear in the
+ products table.
+ </para>
+
+ <para>
+ We say that in this situation the orders table is the
+ <firstterm>referencing</firstterm> table and the products table is
+ the <firstterm>referenced</firstterm> table. Similarly, there are
+ referencing and referenced columns.
+ </para>
+
+ <para>
+ You can also shorten the above command to:
+<programlisting>
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ product_no integer <emphasis>REFERENCES products</emphasis>,
+ quantity integer
+);
+</programlisting>
+ because in absence of a column list the primary key of the
+ referenced table is used as the referenced column(s).
+ </para>
+
+ <para>
+ You can assign your own name for a foreign key constraint,
+ in the usual way.
+ </para>
+
+ <para>
+ A foreign key can also constrain and reference a group of columns.
+ As usual, it then needs to be written in table constraint form.
+ Here is a contrived syntax example:
+<programlisting>
+CREATE TABLE t1 (
+ a integer PRIMARY KEY,
+ b integer,
+ c integer,
+ <emphasis>FOREIGN KEY (b, c) REFERENCES other_table (c1, c2)</emphasis>
+);
+</programlisting>
+ Of course, the number and type of the constrained columns need to
+ match the number and type of the referenced columns.
+ </para>
+
+ <indexterm>
+ <primary>foreign key</primary>
+ <secondary>self-referential</secondary>
+ </indexterm>
+
+ <para>
+ Sometimes it is useful for the <quote>other table</quote> of a
+ foreign key constraint to be the same table; this is called
+ a <firstterm>self-referential</firstterm> foreign key. For
+ example, if you want rows of a table to represent nodes of a tree
+ structure, you could write
+<programlisting>
+CREATE TABLE tree (
+ node_id integer PRIMARY KEY,
+ parent_id integer REFERENCES tree,
+ name text,
+ ...
+);
+</programlisting>
+ A top-level node would have NULL <structfield>parent_id</structfield>,
+ while non-NULL <structfield>parent_id</structfield> entries would be
+ constrained to reference valid rows of the table.
+ </para>
+
+ <para>
+ A table can have more than one foreign key constraint. This is
+ used to implement many-to-many relationships between tables. Say
+ you have tables about products and orders, but now you want to
+ allow one order to contain possibly many products (which the
+ structure above did not allow). You could use this table structure:
+<programlisting>
+CREATE TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ shipping_address text,
+ ...
+);
+
+CREATE TABLE order_items (
+ product_no integer REFERENCES products,
+ order_id integer REFERENCES orders,
+ quantity integer,
+ PRIMARY KEY (product_no, order_id)
+);
+</programlisting>
+ Notice that the primary key overlaps with the foreign keys in
+ the last table.
+ </para>
+
+ <indexterm>
+ <primary>CASCADE</primary>
+ <secondary>foreign key action</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>RESTRICT</primary>
+ <secondary>foreign key action</secondary>
+ </indexterm>
+
+ <para>
+ We know that the foreign keys disallow creation of orders that
+ do not relate to any products. But what if a product is removed
+ after an order is created that references it? SQL allows you to
+ handle that as well. Intuitively, we have a few options:
+ <itemizedlist spacing="compact">
+ <listitem><para>Disallow deleting a referenced product</para></listitem>
+ <listitem><para>Delete the orders as well</para></listitem>
+ <listitem><para>Something else?</para></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ To illustrate this, let's implement the following policy on the
+ many-to-many relationship example above: when someone wants to
+ remove a product that is still referenced by an order (via
+ <literal>order_items</literal>), we disallow it. If someone
+ removes an order, the order items are removed as well:
+<programlisting>
+CREATE TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ shipping_address text,
+ ...
+);
+
+CREATE TABLE order_items (
+ product_no integer REFERENCES products <emphasis>ON DELETE RESTRICT</emphasis>,
+ order_id integer REFERENCES orders <emphasis>ON DELETE CASCADE</emphasis>,
+ quantity integer,
+ PRIMARY KEY (product_no, order_id)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Restricting and cascading deletes are the two most common options.
+ <literal>RESTRICT</literal> prevents deletion of a
+ referenced row. <literal>NO ACTION</literal> means that if any
+ referencing rows still exist when the constraint is checked, an error
+ is raised; this is the default behavior if you do not specify anything.
+ (The essential difference between these two choices is that
+ <literal>NO ACTION</literal> allows the check to be deferred until
+ later in the transaction, whereas <literal>RESTRICT</literal> does not.)
+ <literal>CASCADE</literal> specifies that when a referenced row is deleted,
+ row(s) referencing it should be automatically deleted as well.
+ There are two other options:
+ <literal>SET NULL</literal> and <literal>SET DEFAULT</literal>.
+ These cause the referencing column(s) in the referencing row(s)
+ to be set to nulls or their default
+ values, respectively, when the referenced row is deleted.
+ Note that these do not excuse you from observing any constraints.
+ For example, if an action specifies <literal>SET DEFAULT</literal>
+ but the default value would not satisfy the foreign key constraint, the
+ operation will fail.
+ </para>
+
+ <para>
+ The appropriate choice of <literal>ON DELETE</literal> action depends on
+ what kinds of objects the related tables represent. When the referencing
+ table represents something that is a component of what is represented by
+ the referenced table and cannot exist independently, then
+ <literal>CASCADE</literal> could be appropriate. If the two tables
+ represent independent objects, then <literal>RESTRICT</literal> or
+ <literal>NO ACTION</literal> is more appropriate; an application that
+ actually wants to delete both objects would then have to be explicit about
+ this and run two delete commands. In the above example, order items are
+ part of an order, and it is convenient if they are deleted automatically
+ if an order is deleted. But products and orders are different things, and
+ so making a deletion of a product automatically cause the deletion of some
+ order items could be considered problematic. The actions <literal>SET
+ NULL</literal> or <literal>SET DEFAULT</literal> can be appropriate if a
+ foreign-key relationship represents optional information. For example, if
+ the products table contained a reference to a product manager, and the
+ product manager entry gets deleted, then setting the product's product
+ manager to null or a default might be useful.
+ </para>
+
+ <para>
+ The actions <literal>SET NULL</literal> and <literal>SET DEFAULT</literal>
+ can take a column list to specify which columns to set. Normally, all
+ columns of the foreign-key constraint are set; setting only a subset is
+ useful in some special cases. Consider the following example:
+<programlisting>
+CREATE TABLE tenants (
+ tenant_id integer PRIMARY KEY
+);
+
+CREATE TABLE users (
+ tenant_id integer REFERENCES tenants ON DELETE CASCADE,
+ user_id integer NOT NULL,
+ PRIMARY KEY (tenant_id, user_id)
+);
+
+CREATE TABLE posts (
+ tenant_id integer REFERENCES tenants ON DELETE CASCADE,
+ post_id integer NOT NULL,
+ author_id integer,
+ PRIMARY KEY (tenant_id, post_id),
+ FOREIGN KEY (tenant_id, author_id) REFERENCES users ON DELETE SET NULL <emphasis>(author_id)</emphasis>
+);
+</programlisting>
+ Without the specification of the column, the foreign key would also set
+ the column <literal>tenant_id</literal> to null, but that column is still
+ required as part of the primary key.
+ </para>
+
+ <para>
+ Analogous to <literal>ON DELETE</literal> there is also
+ <literal>ON UPDATE</literal> which is invoked when a referenced
+ column is changed (updated). The possible actions are the same,
+ except that column lists cannot be specified for <literal>SET
+ NULL</literal> and <literal>SET DEFAULT</literal>.
+ In this case, <literal>CASCADE</literal> means that the updated values of the
+ referenced column(s) should be copied into the referencing row(s).
+ </para>
+
+ <para>
+ Normally, a referencing row need not satisfy the foreign key constraint
+ if any of its referencing columns are null. If <literal>MATCH FULL</literal>
+ is added to the foreign key declaration, a referencing row escapes
+ satisfying the constraint only if all its referencing columns are null
+ (so a mix of null and non-null values is guaranteed to fail a
+ <literal>MATCH FULL</literal> constraint). If you don't want referencing rows
+ to be able to avoid satisfying the foreign key constraint, declare the
+ referencing column(s) as <literal>NOT NULL</literal>.
+ </para>
+
+ <para>
+ A foreign key must reference columns that either are a primary key or
+ form a unique constraint. This means that the referenced columns always
+ have an index (the one underlying the primary key or unique constraint);
+ so checks on whether a referencing row has a match will be efficient.
+ Since a <command>DELETE</command> of a row from the referenced table
+ or an <command>UPDATE</command> of a referenced column will require
+ a scan of the referencing table for rows matching the old value, it
+ is often a good idea to index the referencing columns too. Because this
+ is not always needed, and there are many choices available on how
+ to index, declaration of a foreign key constraint does not
+ automatically create an index on the referencing columns.
+ </para>
+
+ <para>
+ More information about updating and deleting data is in <xref
+ linkend="dml"/>. Also see the description of foreign key constraint
+ syntax in the reference documentation for
+ <xref linkend="sql-createtable"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-constraints-exclusion">
+ <title>Exclusion Constraints</title>
+
+ <indexterm>
+ <primary>exclusion constraint</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>exclusion</secondary>
+ </indexterm>
+
+ <para>
+ Exclusion constraints ensure that if any two rows are compared on
+ the specified columns or expressions using the specified operators,
+ at least one of these operator comparisons will return false or null.
+ The syntax is:
+<programlisting>
+CREATE TABLE circles (
+ c circle,
+ EXCLUDE USING gist (c WITH &amp;&amp;)
+);
+</programlisting>
+ </para>
+
+ <para>
+ See also <link linkend="sql-createtable-exclude"><command>CREATE
+ TABLE ... CONSTRAINT ... EXCLUDE</command></link> for details.
+ </para>
+
+ <para>
+ Adding an exclusion constraint will automatically create an index
+ of the type specified in the constraint declaration.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ddl-system-columns">
+ <title>System Columns</title>
+
+ <para>
+ Every table has several <firstterm>system columns</firstterm> that are
+ implicitly defined by the system. Therefore, these names cannot be
+ used as names of user-defined columns. (Note that these
+ restrictions are separate from whether the name is a key word or
+ not; quoting a name will not allow you to escape these
+ restrictions.) You do not really need to be concerned about these
+ columns; just know they exist.
+ </para>
+
+ <indexterm>
+ <primary>column</primary>
+ <secondary>system column</secondary>
+ </indexterm>
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>tableoid</structfield></term>
+ <listitem>
+ <indexterm>
+ <primary>tableoid</primary>
+ </indexterm>
+
+ <para>
+ The OID of the table containing this row. This column is
+ particularly handy for queries that select from partitioned
+ tables (see <xref linkend="ddl-partitioning"/>) or inheritance
+ hierarchies (see <xref linkend="ddl-inherit"/>), since without it,
+ it's difficult to tell which individual table a row came from. The
+ <structfield>tableoid</structfield> can be joined against the
+ <structfield>oid</structfield> column of
+ <structname>pg_class</structname> to obtain the table name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>xmin</structfield></term>
+ <listitem>
+ <indexterm>
+ <primary>xmin</primary>
+ </indexterm>
+
+ <para>
+ The identity (transaction ID) of the inserting transaction for
+ this row version. (A row version is an individual state of a
+ row; each update of a row creates a new row version for the same
+ logical row.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>cmin</structfield></term>
+ <listitem>
+ <indexterm>
+ <primary>cmin</primary>
+ </indexterm>
+
+ <para>
+ The command identifier (starting at zero) within the inserting
+ transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>xmax</structfield></term>
+ <listitem>
+ <indexterm>
+ <primary>xmax</primary>
+ </indexterm>
+
+ <para>
+ The identity (transaction ID) of the deleting transaction, or
+ zero for an undeleted row version. It is possible for this column to
+ be nonzero in a visible row version. That usually indicates that the
+ deleting transaction hasn't committed yet, or that an attempted
+ deletion was rolled back.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>cmax</structfield></term>
+ <listitem>
+ <indexterm>
+ <primary>cmax</primary>
+ </indexterm>
+
+ <para>
+ The command identifier within the deleting transaction, or zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>ctid</structfield></term>
+ <listitem>
+ <indexterm>
+ <primary>ctid</primary>
+ </indexterm>
+
+ <para>
+ The physical location of the row version within its table. Note that
+ although the <structfield>ctid</structfield> can be used to
+ locate the row version very quickly, a row's
+ <structfield>ctid</structfield> will change if it is
+ updated or moved by <command>VACUUM FULL</command>. Therefore
+ <structfield>ctid</structfield> is useless as a long-term row
+ identifier. A primary key should be used to identify logical rows.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Transaction identifiers are also 32-bit quantities. In a
+ long-lived database it is possible for transaction IDs to wrap
+ around. This is not a fatal problem given appropriate maintenance
+ procedures; see <xref linkend="maintenance"/> for details. It is
+ unwise, however, to depend on the uniqueness of transaction IDs
+ over the long term (more than one billion transactions).
+ </para>
+
+ <para>
+ Command identifiers are also 32-bit quantities. This creates a hard limit
+ of 2<superscript>32</superscript> (4 billion) <acronym>SQL</acronym> commands
+ within a single transaction. In practice this limit is not a
+ problem &mdash; note that the limit is on the number of
+ <acronym>SQL</acronym> commands, not the number of rows processed.
+ Also, only commands that actually modify the database contents will
+ consume a command identifier.
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-alter">
+ <title>Modifying Tables</title>
+
+ <indexterm zone="ddl-alter">
+ <primary>table</primary>
+ <secondary>modifying</secondary>
+ </indexterm>
+
+ <para>
+ When you create a table and you realize that you made a mistake, or
+ the requirements of the application change, you can drop the
+ table and create it again. But this is not a convenient option if
+ the table is already filled with data, or if the table is
+ referenced by other database objects (for instance a foreign key
+ constraint). Therefore <productname>PostgreSQL</productname>
+ provides a family of commands to make modifications to existing
+ tables. Note that this is conceptually distinct from altering
+ the data contained in the table: here we are interested in altering
+ the definition, or structure, of the table.
+ </para>
+
+ <para>
+ You can:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>Add columns</para>
+ </listitem>
+ <listitem>
+ <para>Remove columns</para>
+ </listitem>
+ <listitem>
+ <para>Add constraints</para>
+ </listitem>
+ <listitem>
+ <para>Remove constraints</para>
+ </listitem>
+ <listitem>
+ <para>Change default values</para>
+ </listitem>
+ <listitem>
+ <para>Change column data types</para>
+ </listitem>
+ <listitem>
+ <para>Rename columns</para>
+ </listitem>
+ <listitem>
+ <para>Rename tables</para>
+ </listitem>
+ </itemizedlist>
+
+ All these actions are performed using the
+ <xref linkend="sql-altertable"/>
+ command, whose reference page contains details beyond those given
+ here.
+ </para>
+
+ <sect2 id="ddl-alter-adding-a-column">
+ <title>Adding a Column</title>
+
+ <indexterm>
+ <primary>column</primary>
+ <secondary>adding</secondary>
+ </indexterm>
+
+ <para>
+ To add a column, use a command like:
+<programlisting>
+ALTER TABLE products ADD COLUMN description text;
+</programlisting>
+ The new column is initially filled with whatever default
+ value is given (null if you don't specify a <literal>DEFAULT</literal> clause).
+ </para>
+
+ <tip>
+ <para>
+ From <productname>PostgreSQL</productname> 11, adding a column with
+ a constant default value no longer means that each row of the table
+ needs to be updated when the <command>ALTER TABLE</command> statement
+ is executed. Instead, the default value will be returned the next time
+ the row is accessed, and applied when the table is rewritten, making
+ the <command>ALTER TABLE</command> very fast even on large tables.
+ </para>
+
+ <para>
+ However, if the default value is volatile (e.g.,
+ <function>clock_timestamp()</function>)
+ each row will need to be updated with the value calculated at the time
+ <command>ALTER TABLE</command> is executed. To avoid a potentially
+ lengthy update operation, particularly if you intend to fill the column
+ with mostly nondefault values anyway, it may be preferable to add the
+ column with no default, insert the correct values using
+ <command>UPDATE</command>, and then add any desired default as described
+ below.
+ </para>
+ </tip>
+
+ <para>
+ You can also define constraints on the column at the same time,
+ using the usual syntax:
+<programlisting>
+ALTER TABLE products ADD COLUMN description text CHECK (description &lt;&gt; '');
+</programlisting>
+ In fact all the options that can be applied to a column description
+ in <command>CREATE TABLE</command> can be used here. Keep in mind however
+ that the default value must satisfy the given constraints, or the
+ <literal>ADD</literal> will fail. Alternatively, you can add
+ constraints later (see below) after you've filled in the new column
+ correctly.
+ </para>
+
+ </sect2>
+
+ <sect2 id="ddl-alter-removing-a-column">
+ <title>Removing a Column</title>
+
+ <indexterm>
+ <primary>column</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+
+ <para>
+ To remove a column, use a command like:
+<programlisting>
+ALTER TABLE products DROP COLUMN description;
+</programlisting>
+ Whatever data was in the column disappears. Table constraints involving
+ the column are dropped, too. However, if the column is referenced by a
+ foreign key constraint of another table,
+ <productname>PostgreSQL</productname> will not silently drop that
+ constraint. You can authorize dropping everything that depends on
+ the column by adding <literal>CASCADE</literal>:
+<programlisting>
+ALTER TABLE products DROP COLUMN description CASCADE;
+</programlisting>
+ See <xref linkend="ddl-depend"/> for a description of the general
+ mechanism behind this.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-alter-adding-a-constraint">
+ <title>Adding a Constraint</title>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>adding</secondary>
+ </indexterm>
+
+ <para>
+ To add a constraint, the table constraint syntax is used. For example:
+<programlisting>
+ALTER TABLE products ADD CHECK (name &lt;&gt; '');
+ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no);
+ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;
+</programlisting>
+ To add a not-null constraint, which cannot be written as a table
+ constraint, use this syntax:
+<programlisting>
+ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;
+</programlisting>
+ </para>
+
+ <para>
+ The constraint will be checked immediately, so the table data must
+ satisfy the constraint before it can be added.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-alter-removing-a-constraint">
+ <title>Removing a Constraint</title>
+
+ <indexterm>
+ <primary>constraint</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+
+ <para>
+ To remove a constraint you need to know its name. If you gave it
+ a name then that's easy. Otherwise the system assigned a
+ generated name, which you need to find out. The
+ <application>psql</application> command <literal>\d
+ <replaceable>tablename</replaceable></literal> can be helpful
+ here; other interfaces might also provide a way to inspect table
+ details. Then the command is:
+<programlisting>
+ALTER TABLE products DROP CONSTRAINT some_name;
+</programlisting>
+ (If you are dealing with a generated constraint name like <literal>$2</literal>,
+ don't forget that you'll need to double-quote it to make it a valid
+ identifier.)
+ </para>
+
+ <para>
+ As with dropping a column, you need to add <literal>CASCADE</literal> if you
+ want to drop a constraint that something else depends on. An example
+ is that a foreign key constraint depends on a unique or primary key
+ constraint on the referenced column(s).
+ </para>
+
+ <para>
+ This works the same for all constraint types except not-null
+ constraints. To drop a not null constraint use:
+<programlisting>
+ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
+</programlisting>
+ (Recall that not-null constraints do not have names.)
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Changing a Column's Default Value</title>
+
+ <indexterm>
+ <primary>default value</primary>
+ <secondary>changing</secondary>
+ </indexterm>
+
+ <para>
+ To set a new default for a column, use a command like:
+<programlisting>
+ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
+</programlisting>
+ Note that this doesn't affect any existing rows in the table, it
+ just changes the default for future <command>INSERT</command> commands.
+ </para>
+
+ <para>
+ To remove any default value, use:
+<programlisting>
+ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
+</programlisting>
+ This is effectively the same as setting the default to null.
+ As a consequence, it is not an error
+ to drop a default where one hadn't been defined, because the
+ default is implicitly the null value.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Changing a Column's Data Type</title>
+
+ <indexterm>
+ <primary>column data type</primary>
+ <secondary>changing</secondary>
+ </indexterm>
+
+ <para>
+ To convert a column to a different data type, use a command like:
+<programlisting>
+ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
+</programlisting>
+ This will succeed only if each existing entry in the column can be
+ converted to the new type by an implicit cast. If a more complex
+ conversion is needed, you can add a <literal>USING</literal> clause that
+ specifies how to compute the new values from the old.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> will attempt to convert the column's
+ default value (if any) to the new type, as well as any constraints
+ that involve the column. But these conversions might fail, or might
+ produce surprising results. It's often best to drop any constraints
+ on the column before altering its type, and then add back suitably
+ modified constraints afterwards.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Renaming a Column</title>
+
+ <indexterm>
+ <primary>column</primary>
+ <secondary>renaming</secondary>
+ </indexterm>
+
+ <para>
+ To rename a column:
+<programlisting>
+ALTER TABLE products RENAME COLUMN product_no TO product_number;
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Renaming a Table</title>
+
+ <indexterm>
+ <primary>table</primary>
+ <secondary>renaming</secondary>
+ </indexterm>
+
+ <para>
+ To rename a table:
+<programlisting>
+ALTER TABLE products RENAME TO items;
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ddl-priv">
+ <title>Privileges</title>
+
+ <indexterm zone="ddl-priv">
+ <primary>privilege</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>permission</primary>
+ <see>privilege</see>
+ </indexterm>
+
+ <indexterm zone="ddl-priv">
+ <primary>owner</primary>
+ </indexterm>
+
+ <indexterm zone="ddl-priv">
+ <primary>GRANT</primary>
+ </indexterm>
+
+ <indexterm zone="ddl-priv">
+ <primary>REVOKE</primary>
+ </indexterm>
+
+ <indexterm zone="ddl-priv">
+ <primary>ACL</primary>
+ </indexterm>
+
+ <para>
+ When an object is created, it is assigned an owner. The
+ owner is normally the role that executed the creation statement.
+ For most kinds of objects, the initial state is that only the owner
+ (or a superuser) can do anything with the object. To allow
+ other roles to use it, <firstterm>privileges</firstterm> must be
+ granted.
+ </para>
+
+ <para>
+ There are different kinds of privileges: <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>,
+ <literal>TRUNCATE</literal>, <literal>REFERENCES</literal>, <literal>TRIGGER</literal>,
+ <literal>CREATE</literal>, <literal>CONNECT</literal>, <literal>TEMPORARY</literal>,
+ <literal>EXECUTE</literal>, <literal>USAGE</literal>, <literal>SET</literal>
+ and <literal>ALTER SYSTEM</literal>.
+ The privileges applicable to a particular
+ object vary depending on the object's type (table, function, etc.).
+ More detail about the meanings of these privileges appears below.
+ The following sections and chapters will also show you how
+ these privileges are used.
+ </para>
+
+ <para>
+ The right to modify or destroy an object is inherent in being the
+ object's owner, and cannot be granted or revoked in itself.
+ (However, like all privileges, that right can be inherited by
+ members of the owning role; see <xref linkend="role-membership"/>.)
+ </para>
+
+ <para>
+ An object can be assigned to a new owner with an <command>ALTER</command>
+ command of the appropriate kind for the object, for example
+<programlisting>
+ALTER TABLE <replaceable>table_name</replaceable> OWNER TO <replaceable>new_owner</replaceable>;
+</programlisting>
+ Superusers can always do this; ordinary roles can only do it if they are
+ both the current owner of the object (or a member of the owning role) and
+ a member of the new owning role.
+ </para>
+
+ <para>
+ To assign privileges, the <xref linkend="sql-grant"/> command is
+ used. For example, if <literal>joe</literal> is an existing role, and
+ <literal>accounts</literal> is an existing table, the privilege to
+ update the table can be granted with:
+<programlisting>
+GRANT UPDATE ON accounts TO joe;
+</programlisting>
+ Writing <literal>ALL</literal> in place of a specific privilege grants all
+ privileges that are relevant for the object type.
+ </para>
+
+ <para>
+ The special <quote>role</quote> name <literal>PUBLIC</literal> can
+ be used to grant a privilege to every role on the system. Also,
+ <quote>group</quote> roles can be set up to help manage privileges when
+ there are many users of a database &mdash; for details see
+ <xref linkend="user-manag"/>.
+ </para>
+
+ <para>
+ To revoke a previously-granted privilege, use the fittingly named
+ <xref linkend="sql-revoke"/> command:
+<programlisting>
+REVOKE ALL ON accounts FROM PUBLIC;
+</programlisting>
+ </para>
+
+ <para>
+ Ordinarily, only the object's owner (or a superuser) can grant or
+ revoke privileges on an object. However, it is possible to grant a
+ privilege <quote>with grant option</quote>, which gives the recipient
+ the right to grant it in turn to others. If the grant option is
+ subsequently revoked then all who received the privilege from that
+ recipient (directly or through a chain of grants) will lose the
+ privilege. For details see the <xref linkend="sql-grant"/> and
+ <xref linkend="sql-revoke"/> reference pages.
+ </para>
+
+ <para>
+ An object's owner can choose to revoke their own ordinary privileges,
+ for example to make a table read-only for themselves as well as others.
+ But owners are always treated as holding all grant options, so they
+ can always re-grant their own privileges.
+ </para>
+
+ <para>
+ The available privileges are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SELECT</literal></term>
+ <listitem>
+ <para>
+ Allows <command>SELECT</command> from
+ any column, or specific column(s), of a table, view, materialized
+ view, or other table-like object.
+ Also allows use of <command>COPY TO</command>.
+ This privilege is also needed to reference existing column values in
+ <command>UPDATE</command>, <command>DELETE</command>,
+ or <command>MERGE</command>.
+ For sequences, this privilege also allows use of the
+ <function>currval</function> function.
+ For large objects, this privilege allows the object to be read.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INSERT</literal></term>
+ <listitem>
+ <para>
+ Allows <command>INSERT</command> of a new row into a table, view,
+ etc. Can be granted on specific column(s), in which case
+ only those columns may be assigned to in the <command>INSERT</command>
+ command (other columns will therefore receive default values).
+ Also allows use of <command>COPY FROM</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>UPDATE</literal></term>
+ <listitem>
+ <para>
+ Allows <command>UPDATE</command> of any
+ column, or specific column(s), of a table, view, etc.
+ (In practice, any nontrivial <command>UPDATE</command> command will
+ require <literal>SELECT</literal> privilege as well, since it must
+ reference table columns to determine which rows to update, and/or to
+ compute new values for columns.)
+ <literal>SELECT ... FOR UPDATE</literal>
+ and <literal>SELECT ... FOR SHARE</literal>
+ also require this privilege on at least one column, in addition to the
+ <literal>SELECT</literal> privilege. For sequences, this
+ privilege allows use of the <function>nextval</function> and
+ <function>setval</function> functions.
+ For large objects, this privilege allows writing or truncating the
+ object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DELETE</literal></term>
+ <listitem>
+ <para>
+ Allows <command>DELETE</command> of a row from a table, view, etc.
+ (In practice, any nontrivial <command>DELETE</command> command will
+ require <literal>SELECT</literal> privilege as well, since it must
+ reference table columns to determine which rows to delete.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRUNCATE</literal></term>
+ <listitem>
+ <para>
+ Allows <command>TRUNCATE</command> on a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REFERENCES</literal></term>
+ <listitem>
+ <para>
+ Allows creation of a foreign key constraint referencing a
+ table, or specific column(s) of a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER</literal></term>
+ <listitem>
+ <para>
+ Allows creation of a trigger on a table, view, etc.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATE</literal></term>
+ <listitem>
+ <para>
+ For databases, allows new schemas and publications to be created within
+ the database, and allows trusted extensions to be installed within
+ the database.
+ </para>
+ <para>
+ For schemas, allows new objects to be created within the schema.
+ To rename an existing object, you must own the
+ object <emphasis>and</emphasis> have this privilege for the containing
+ schema.
+ </para>
+ <para>
+ For tablespaces, allows tables, indexes, and temporary files to be
+ created within the tablespace, and allows databases to be created that
+ have the tablespace as their default tablespace.
+ </para>
+ <para>
+ Note that revoking this privilege will not alter the existence or
+ location of existing objects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONNECT</literal></term>
+ <listitem>
+ <para>
+ Allows the grantee to connect to the database. This
+ privilege is checked at connection startup (in addition to checking
+ any restrictions imposed by <filename>pg_hba.conf</filename>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TEMPORARY</literal></term>
+ <listitem>
+ <para>
+ Allows temporary tables to be created while using the database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXECUTE</literal></term>
+ <listitem>
+ <para>
+ Allows calling a function or procedure, including use of
+ any operators that are implemented on top of the function. This is the
+ only type of privilege that is applicable to functions and procedures.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USAGE</literal></term>
+ <listitem>
+ <para>
+ For procedural languages, allows use of the language for
+ the creation of functions in that language. This is the only type
+ of privilege that is applicable to procedural languages.
+ </para>
+ <para>
+ For schemas, allows access to objects contained in the
+ schema (assuming that the objects' own privilege requirements are
+ also met). Essentially this allows the grantee to <quote>look up</quote>
+ objects within the schema. Without this permission, it is still
+ possible to see the object names, e.g., by querying system catalogs.
+ Also, after revoking this permission, existing sessions might have
+ statements that have previously performed this lookup, so this is not
+ a completely secure way to prevent object access.
+ </para>
+ <para>
+ For sequences, allows use of the
+ <function>currval</function> and <function>nextval</function> functions.
+ </para>
+ <para>
+ For types and domains, allows use of the type or domain in the
+ creation of tables, functions, and other schema objects. (Note that
+ this privilege does not control all <quote>usage</quote> of the
+ type, such as values of the type appearing in queries. It only
+ prevents objects from being created that depend on the type. The
+ main purpose of this privilege is controlling which users can create
+ dependencies on a type, which could prevent the owner from changing
+ the type later.)
+ </para>
+ <para>
+ For foreign-data wrappers, allows creation of new servers using the
+ foreign-data wrapper.
+ </para>
+ <para>
+ For foreign servers, allows creation of foreign tables using the
+ server. Grantees may also create, alter, or drop their own user
+ mappings associated with that server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal></term>
+ <listitem>
+ <para>
+ Allows a server configuration parameter to be set to a new value
+ within the current session. (While this privilege can be granted
+ on any parameter, it is meaningless except for parameters that would
+ normally require superuser privilege to set.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALTER SYSTEM</literal></term>
+ <listitem>
+ <para>
+ Allows a server configuration parameter to be configured to a new
+ value using the <xref linkend="sql-altersystem"/> command.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The privileges required by other commands are listed on the
+ reference page of the respective command.
+ </para>
+
+ <para>
+ PostgreSQL grants privileges on some types of objects to
+ <literal>PUBLIC</literal> by default when the objects are created.
+ No privileges are granted to <literal>PUBLIC</literal> by default on
+ tables,
+ table columns,
+ sequences,
+ foreign data wrappers,
+ foreign servers,
+ large objects,
+ schemas,
+ tablespaces,
+ or configuration parameters.
+ For other types of objects, the default privileges
+ granted to <literal>PUBLIC</literal> are as follows:
+ <literal>CONNECT</literal> and <literal>TEMPORARY</literal> (create
+ temporary tables) privileges for databases;
+ <literal>EXECUTE</literal> privilege for functions and procedures; and
+ <literal>USAGE</literal> privilege for languages and data types
+ (including domains).
+ The object owner can, of course, <command>REVOKE</command>
+ both default and expressly granted privileges. (For maximum
+ security, issue the <command>REVOKE</command> in the same transaction that
+ creates the object; then there is no window in which another user
+ can use the object.)
+ Also, these default privilege settings can be overridden using the
+ <xref linkend="sql-alterdefaultprivileges"/> command.
+ </para>
+
+ <para>
+ <xref linkend="privilege-abbrevs-table"/> shows the one-letter
+ abbreviations that are used for these privilege types in
+ <firstterm>ACL</firstterm> (Access Control List) values.
+ You will see these letters in the output of the <xref linkend="app-psql"/>
+ commands listed below, or when looking at ACL columns of system catalogs.
+ </para>
+
+ <table id="privilege-abbrevs-table">
+ <title>ACL Privilege Abbreviations</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Privilege</entry>
+ <entry>Abbreviation</entry>
+ <entry>Applicable Object Types</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>SELECT</literal></entry>
+ <entry><literal>r</literal> (<quote>read</quote>)</entry>
+ <entry>
+ <literal>LARGE OBJECT</literal>,
+ <literal>SEQUENCE</literal>,
+ <literal>TABLE</literal> (and table-like objects),
+ table column
+ </entry>
+ </row>
+ <row>
+ <entry><literal>INSERT</literal></entry>
+ <entry><literal>a</literal> (<quote>append</quote>)</entry>
+ <entry><literal>TABLE</literal>, table column</entry>
+ </row>
+ <row>
+ <entry><literal>UPDATE</literal></entry>
+ <entry><literal>w</literal> (<quote>write</quote>)</entry>
+ <entry>
+ <literal>LARGE OBJECT</literal>,
+ <literal>SEQUENCE</literal>,
+ <literal>TABLE</literal>,
+ table column
+ </entry>
+ </row>
+ <row>
+ <entry><literal>DELETE</literal></entry>
+ <entry><literal>d</literal></entry>
+ <entry><literal>TABLE</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TRUNCATE</literal></entry>
+ <entry><literal>D</literal></entry>
+ <entry><literal>TABLE</literal></entry>
+ </row>
+ <row>
+ <entry><literal>REFERENCES</literal></entry>
+ <entry><literal>x</literal></entry>
+ <entry><literal>TABLE</literal>, table column</entry>
+ </row>
+ <row>
+ <entry><literal>TRIGGER</literal></entry>
+ <entry><literal>t</literal></entry>
+ <entry><literal>TABLE</literal></entry>
+ </row>
+ <row>
+ <entry><literal>CREATE</literal></entry>
+ <entry><literal>C</literal></entry>
+ <entry>
+ <literal>DATABASE</literal>,
+ <literal>SCHEMA</literal>,
+ <literal>TABLESPACE</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>CONNECT</literal></entry>
+ <entry><literal>c</literal></entry>
+ <entry><literal>DATABASE</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TEMPORARY</literal></entry>
+ <entry><literal>T</literal></entry>
+ <entry><literal>DATABASE</literal></entry>
+ </row>
+ <row>
+ <entry><literal>EXECUTE</literal></entry>
+ <entry><literal>X</literal></entry>
+ <entry><literal>FUNCTION</literal>, <literal>PROCEDURE</literal></entry>
+ </row>
+ <row>
+ <entry><literal>USAGE</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry>
+ <literal>DOMAIN</literal>,
+ <literal>FOREIGN DATA WRAPPER</literal>,
+ <literal>FOREIGN SERVER</literal>,
+ <literal>LANGUAGE</literal>,
+ <literal>SCHEMA</literal>,
+ <literal>SEQUENCE</literal>,
+ <literal>TYPE</literal>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>SET</literal></entry>
+ <entry><literal>s</literal></entry>
+ <entry><literal>PARAMETER</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ALTER SYSTEM</literal></entry>
+ <entry><literal>A</literal></entry>
+ <entry><literal>PARAMETER</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="privileges-summary-table"/> summarizes the privileges
+ available for each type of SQL object, using the abbreviations shown
+ above.
+ It also shows the <application>psql</application> command
+ that can be used to examine privilege settings for each object type.
+ </para>
+
+ <table id="privileges-summary-table">
+ <title>Summary of Access Privileges</title>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Object Type</entry>
+ <entry>All Privileges</entry>
+ <entry>Default <literal>PUBLIC</literal> Privileges</entry>
+ <entry><application>psql</application> Command</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>DATABASE</literal></entry>
+ <entry><literal>CTc</literal></entry>
+ <entry><literal>Tc</literal></entry>
+ <entry><literal>\l</literal></entry>
+ </row>
+ <row>
+ <entry><literal>DOMAIN</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry><literal>\dD+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>FUNCTION</literal> or <literal>PROCEDURE</literal></entry>
+ <entry><literal>X</literal></entry>
+ <entry><literal>X</literal></entry>
+ <entry><literal>\df+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>FOREIGN DATA WRAPPER</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dew+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>FOREIGN SERVER</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\des+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LANGUAGE</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry><literal>\dL+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>LARGE OBJECT</literal></entry>
+ <entry><literal>rw</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dl+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>PARAMETER</literal></entry>
+ <entry><literal>sA</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dconfig+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>SCHEMA</literal></entry>
+ <entry><literal>UC</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dn+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>SEQUENCE</literal></entry>
+ <entry><literal>rwU</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dp</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TABLE</literal> (and table-like objects)</entry>
+ <entry><literal>arwdDxt</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dp</literal></entry>
+ </row>
+ <row>
+ <entry>Table column</entry>
+ <entry><literal>arwx</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\dp</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TABLESPACE</literal></entry>
+ <entry><literal>C</literal></entry>
+ <entry>none</entry>
+ <entry><literal>\db+</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TYPE</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry><literal>U</literal></entry>
+ <entry><literal>\dT+</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <indexterm>
+ <primary><type>aclitem</type></primary>
+ </indexterm>
+ The privileges that have been granted for a particular object are
+ displayed as a list of <type>aclitem</type> entries, where each
+ <type>aclitem</type> describes the permissions of one grantee that
+ have been granted by a particular grantor. For example,
+ <literal>calvin=r*w/hobbes</literal> specifies that the role
+ <literal>calvin</literal> has the privilege
+ <literal>SELECT</literal> (<literal>r</literal>) with grant option
+ (<literal>*</literal>) as well as the non-grantable
+ privilege <literal>UPDATE</literal> (<literal>w</literal>), both granted
+ by the role <literal>hobbes</literal>. If <literal>calvin</literal>
+ also has some privileges on the same object granted by a different
+ grantor, those would appear as a separate <type>aclitem</type> entry.
+ An empty grantee field in an <type>aclitem</type> stands
+ for <literal>PUBLIC</literal>.
+ </para>
+
+ <para>
+ As an example, suppose that user <literal>miriam</literal> creates
+ table <literal>mytable</literal> and does:
+<programlisting>
+GRANT SELECT ON mytable TO PUBLIC;
+GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
+GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;
+</programlisting>
+ Then <application>psql</application>'s <literal>\dp</literal> command
+ would show:
+<programlisting>
+=&gt; \dp mytable
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+---------+-------+-----------------------+-----------------------+----------
+ public | mytable | table | miriam=arwdDxt/miriam+| col1: +|
+ | | | =r/miriam +| miriam_rw=rw/miriam |
+ | | | admin=arw/miriam | |
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ If the <quote>Access privileges</quote> column is empty for a given
+ object, it means the object has default privileges (that is, its
+ privileges entry in the relevant system catalog is null). Default
+ privileges always include all privileges for the owner, and can include
+ some privileges for <literal>PUBLIC</literal> depending on the object
+ type, as explained above. The first <command>GRANT</command>
+ or <command>REVOKE</command> on an object will instantiate the default
+ privileges (producing, for
+ example, <literal>miriam=arwdDxt/miriam</literal>) and then modify them
+ per the specified request. Similarly, entries are shown in <quote>Column
+ privileges</quote> only for columns with nondefault privileges.
+ (Note: for this purpose, <quote>default privileges</quote> always means
+ the built-in default privileges for the object's type. An object whose
+ privileges have been affected by an <command>ALTER DEFAULT
+ PRIVILEGES</command> command will always be shown with an explicit
+ privilege entry that includes the effects of
+ the <command>ALTER</command>.)
+ </para>
+
+ <para>
+ Notice that the owner's implicit grant options are not marked in the
+ access privileges display. A <literal>*</literal> will appear only when
+ grant options have been explicitly granted to someone.
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-rowsecurity">
+ <title>Row Security Policies</title>
+
+ <indexterm zone="ddl-rowsecurity">
+ <primary>row-level security</primary>
+ </indexterm>
+
+ <indexterm zone="ddl-rowsecurity">
+ <primary>policy</primary>
+ </indexterm>
+
+ <para>
+ In addition to the SQL-standard <link linkend="ddl-priv">privilege
+ system</link> available through <xref linkend="sql-grant"/>,
+ tables can have <firstterm>row security policies</firstterm> that restrict,
+ on a per-user basis, which rows can be returned by normal queries
+ or inserted, updated, or deleted by data modification commands.
+ This feature is also known as <firstterm>Row-Level Security</firstterm>.
+ By default, tables do not have any policies, so that if a user has
+ access privileges to a table according to the SQL privilege system,
+ all rows within it are equally available for querying or updating.
+ </para>
+
+ <para>
+ When row security is enabled on a table (with
+ <link linkend="sql-altertable">ALTER TABLE ... ENABLE ROW LEVEL
+ SECURITY</link>), all normal access to the table for selecting rows or
+ modifying rows must be allowed by a row security policy. (However, the
+ table's owner is typically not subject to row security policies.) If no
+ policy exists for the table, a default-deny policy is used, meaning that
+ no rows are visible or can be modified. Operations that apply to the
+ whole table, such as <command>TRUNCATE</command> and <literal>REFERENCES</literal>,
+ are not subject to row security.
+ </para>
+
+ <para>
+ Row security policies can be specific to commands, or to roles, or to
+ both. A policy can be specified to apply to <literal>ALL</literal>
+ commands, or to <literal>SELECT</literal>, <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ or <literal>DELETE</literal>. Multiple roles can be assigned to a given
+ policy, and normal role membership and inheritance rules apply.
+ </para>
+
+ <para>
+ To specify which rows are visible or modifiable according to a policy,
+ an expression is required that returns a Boolean result. This
+ expression will be evaluated for each row prior to any conditions or
+ functions coming from the user's query. (The only exceptions to this
+ rule are <literal>leakproof</literal> functions, which are guaranteed to
+ not leak information; the optimizer may choose to apply such functions
+ ahead of the row-security check.) Rows for which the expression does
+ not return <literal>true</literal> will not be processed. Separate expressions
+ may be specified to provide independent control over the rows which are
+ visible and the rows which are allowed to be modified. Policy
+ expressions are run as part of the query and with the privileges of the
+ user running the query, although security-definer functions can be used
+ to access data not available to the calling user.
+ </para>
+
+ <para>
+ Superusers and roles with the <literal>BYPASSRLS</literal> attribute always
+ bypass the row security system when accessing a table. Table owners
+ normally bypass row security as well, though a table owner can choose to
+ be subject to row security with <link linkend="sql-altertable">ALTER
+ TABLE ... FORCE ROW LEVEL SECURITY</link>.
+ </para>
+
+ <para>
+ Enabling and disabling row security, as well as adding policies to a
+ table, is always the privilege of the table owner only.
+ </para>
+
+ <para>
+ Policies are created using the <xref linkend="sql-createpolicy"/>
+ command, altered using the <xref linkend="sql-alterpolicy"/> command,
+ and dropped using the <xref linkend="sql-droppolicy"/> command. To
+ enable and disable row security for a given table, use the
+ <xref linkend="sql-altertable"/> command.
+ </para>
+
+ <para>
+ Each policy has a name and multiple policies can be defined for a
+ table. As policies are table-specific, each policy for a table must
+ have a unique name. Different tables may have policies with the
+ same name.
+ </para>
+
+ <para>
+ When multiple policies apply to a given query, they are combined using
+ either <literal>OR</literal> (for permissive policies, which are the
+ default) or using <literal>AND</literal> (for restrictive policies).
+ This is similar to the rule that a given role has the privileges
+ of all roles that they are a member of. Permissive vs. restrictive
+ policies are discussed further below.
+ </para>
+
+ <para>
+ As a simple example, here is how to create a policy on
+ the <literal>account</literal> relation to allow only members of
+ the <literal>managers</literal> role to access rows, and only rows of their
+ accounts:
+ </para>
+
+<programlisting>
+CREATE TABLE accounts (manager text, company text, contact_email text);
+
+ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;
+
+CREATE POLICY account_managers ON accounts TO managers
+ USING (manager = current_user);
+</programlisting>
+
+ <para>
+ The policy above implicitly provides a <literal>WITH CHECK</literal>
+ clause identical to its <literal>USING</literal> clause, so that the
+ constraint applies both to rows selected by a command (so a manager
+ cannot <command>SELECT</command>, <command>UPDATE</command>,
+ or <command>DELETE</command> existing rows belonging to a different
+ manager) and to rows modified by a command (so rows belonging to a
+ different manager cannot be created via <command>INSERT</command>
+ or <command>UPDATE</command>).
+ </para>
+
+ <para>
+ If no role is specified, or the special user name
+ <literal>PUBLIC</literal> is used, then the policy applies to all
+ users on the system. To allow all users to access only their own row in
+ a <literal>users</literal> table, a simple policy can be used:
+ </para>
+
+<programlisting>
+CREATE POLICY user_policy ON users
+ USING (user_name = current_user);
+</programlisting>
+
+ <para>
+ This works similarly to the previous example.
+ </para>
+
+ <para>
+ To use a different policy for rows that are being added to the table
+ compared to those rows that are visible, multiple policies can be
+ combined. This pair of policies would allow all users to view all rows
+ in the <literal>users</literal> table, but only modify their own:
+ </para>
+
+<programlisting>
+CREATE POLICY user_sel_policy ON users
+ FOR SELECT
+ USING (true);
+CREATE POLICY user_mod_policy ON users
+ USING (user_name = current_user);
+</programlisting>
+
+ <para>
+ In a <command>SELECT</command> command, these two policies are combined
+ using <literal>OR</literal>, with the net effect being that all rows
+ can be selected. In other command types, only the second policy applies,
+ so that the effects are the same as before.
+ </para>
+
+ <para>
+ Row security can also be disabled with the <command>ALTER TABLE</command>
+ command. Disabling row security does not remove any policies that are
+ defined on the table; they are simply ignored. Then all rows in the
+ table are visible and modifiable, subject to the standard SQL privileges
+ system.
+ </para>
+
+ <para>
+ Below is a larger example of how this feature can be used in production
+ environments. The table <literal>passwd</literal> emulates a Unix password
+ file:
+ </para>
+
+<programlisting>
+-- Simple passwd-file based example
+CREATE TABLE passwd (
+ user_name text UNIQUE NOT NULL,
+ pwhash text,
+ uid int PRIMARY KEY,
+ gid int NOT NULL,
+ real_name text NOT NULL,
+ home_phone text,
+ extra_info text,
+ home_dir text NOT NULL,
+ shell text NOT NULL
+);
+
+CREATE ROLE admin; -- Administrator
+CREATE ROLE bob; -- Normal user
+CREATE ROLE alice; -- Normal user
+
+-- Populate the table
+INSERT INTO passwd VALUES
+ ('admin','xxx',0,0,'Admin','111-222-3333',null,'/root','/bin/dash');
+INSERT INTO passwd VALUES
+ ('bob','xxx',1,1,'Bob','123-456-7890',null,'/home/bob','/bin/zsh');
+INSERT INTO passwd VALUES
+ ('alice','xxx',2,1,'Alice','098-765-4321',null,'/home/alice','/bin/zsh');
+
+-- Be sure to enable row-level security on the table
+ALTER TABLE passwd ENABLE ROW LEVEL SECURITY;
+
+-- Create policies
+-- Administrator can see all rows and add any rows
+CREATE POLICY admin_all ON passwd TO admin USING (true) WITH CHECK (true);
+-- Normal users can view all rows
+CREATE POLICY all_view ON passwd FOR SELECT USING (true);
+-- Normal users can update their own records, but
+-- limit which shells a normal user is allowed to set
+CREATE POLICY user_mod ON passwd FOR UPDATE
+ USING (current_user = user_name)
+ WITH CHECK (
+ current_user = user_name AND
+ shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh')
+ );
+
+-- Allow admin all normal rights
+GRANT SELECT, INSERT, UPDATE, DELETE ON passwd TO admin;
+-- Users only get select access on public columns
+GRANT SELECT
+ (user_name, uid, gid, real_name, home_phone, extra_info, home_dir, shell)
+ ON passwd TO public;
+-- Allow users to update certain columns
+GRANT UPDATE
+ (pwhash, real_name, home_phone, extra_info, shell)
+ ON passwd TO public;
+</programlisting>
+
+ <para>
+ As with any security settings, it's important to test and ensure that
+ the system is behaving as expected. Using the example above, this
+ demonstrates that the permission system is working properly.
+ </para>
+
+<programlisting>
+-- admin can view all rows and fields
+postgres=&gt; set role admin;
+SET
+postgres=&gt; table passwd;
+ user_name | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell
+-----------+--------+-----+-----+-----------+--------------+------------+-------------+-----------
+ admin | xxx | 0 | 0 | Admin | 111-222-3333 | | /root | /bin/dash
+ bob | xxx | 1 | 1 | Bob | 123-456-7890 | | /home/bob | /bin/zsh
+ alice | xxx | 2 | 1 | Alice | 098-765-4321 | | /home/alice | /bin/zsh
+(3 rows)
+
+-- Test what Alice is able to do
+postgres=&gt; set role alice;
+SET
+postgres=&gt; table passwd;
+ERROR: permission denied for table passwd
+postgres=&gt; select user_name,real_name,home_phone,extra_info,home_dir,shell from passwd;
+ user_name | real_name | home_phone | extra_info | home_dir | shell
+-----------+-----------+--------------+------------+-------------+-----------
+ admin | Admin | 111-222-3333 | | /root | /bin/dash
+ bob | Bob | 123-456-7890 | | /home/bob | /bin/zsh
+ alice | Alice | 098-765-4321 | | /home/alice | /bin/zsh
+(3 rows)
+
+postgres=&gt; update passwd set user_name = 'joe';
+ERROR: permission denied for table passwd
+-- Alice is allowed to change her own real_name, but no others
+postgres=&gt; update passwd set real_name = 'Alice Doe';
+UPDATE 1
+postgres=&gt; update passwd set real_name = 'John Doe' where user_name = 'admin';
+UPDATE 0
+postgres=&gt; update passwd set shell = '/bin/xx';
+ERROR: new row violates WITH CHECK OPTION for "passwd"
+postgres=&gt; delete from passwd;
+ERROR: permission denied for table passwd
+postgres=&gt; insert into passwd (user_name) values ('xxx');
+ERROR: permission denied for table passwd
+-- Alice can change her own password; RLS silently prevents updating other rows
+postgres=&gt; update passwd set pwhash = 'abc';
+UPDATE 1
+</programlisting>
+
+ <para>
+ All of the policies constructed thus far have been permissive policies,
+ meaning that when multiple policies are applied they are combined using
+ the <quote>OR</quote> Boolean operator. While permissive policies can be constructed
+ to only allow access to rows in the intended cases, it can be simpler to
+ combine permissive policies with restrictive policies (which the records
+ must pass and which are combined using the <quote>AND</quote> Boolean operator).
+ Building on the example above, we add a restrictive policy to require
+ the administrator to be connected over a local Unix socket to access the
+ records of the <literal>passwd</literal> table:
+ </para>
+
+<programlisting>
+CREATE POLICY admin_local_only ON passwd AS RESTRICTIVE TO admin
+ USING (pg_catalog.inet_client_addr() IS NULL);
+</programlisting>
+
+ <para>
+ We can then see that an administrator connecting over a network will not
+ see any records, due to the restrictive policy:
+ </para>
+
+<programlisting>
+=&gt; SELECT current_user;
+ current_user
+--------------
+ admin
+(1 row)
+
+=&gt; select inet_client_addr();
+ inet_client_addr
+------------------
+ 127.0.0.1
+(1 row)
+
+=&gt; TABLE passwd;
+ user_name | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell
+-----------+--------+-----+-----+-----------+------------+------------+----------+-------
+(0 rows)
+
+=&gt; UPDATE passwd set pwhash = NULL;
+UPDATE 0
+</programlisting>
+
+ <para>
+ Referential integrity checks, such as unique or primary key constraints
+ and foreign key references, always bypass row security to ensure that
+ data integrity is maintained. Care must be taken when developing
+ schemas and row level policies to avoid <quote>covert channel</quote> leaks of
+ information through such referential integrity checks.
+ </para>
+
+ <para>
+ In some contexts it is important to be sure that row security is
+ not being applied. For example, when taking a backup, it could be
+ disastrous if row security silently caused some rows to be omitted
+ from the backup. In such a situation, you can set the
+ <xref linkend="guc-row-security"/> configuration parameter
+ to <literal>off</literal>. This does not in itself bypass row security;
+ what it does is throw an error if any query's results would get filtered
+ by a policy. The reason for the error can then be investigated and
+ fixed.
+ </para>
+
+ <para>
+ In the examples above, the policy expressions consider only the current
+ values in the row to be accessed or updated. This is the simplest and
+ best-performing case; when possible, it's best to design row security
+ applications to work this way. If it is necessary to consult other rows
+ or other tables to make a policy decision, that can be accomplished using
+ sub-<command>SELECT</command>s, or functions that contain <command>SELECT</command>s,
+ in the policy expressions. Be aware however that such accesses can
+ create race conditions that could allow information leakage if care is
+ not taken. As an example, consider the following table design:
+ </para>
+
+<programlisting>
+-- definition of privilege groups
+CREATE TABLE groups (group_id int PRIMARY KEY,
+ group_name text NOT NULL);
+
+INSERT INTO groups VALUES
+ (1, 'low'),
+ (2, 'medium'),
+ (5, 'high');
+
+GRANT ALL ON groups TO alice; -- alice is the administrator
+GRANT SELECT ON groups TO public;
+
+-- definition of users' privilege levels
+CREATE TABLE users (user_name text PRIMARY KEY,
+ group_id int NOT NULL REFERENCES groups);
+
+INSERT INTO users VALUES
+ ('alice', 5),
+ ('bob', 2),
+ ('mallory', 2);
+
+GRANT ALL ON users TO alice;
+GRANT SELECT ON users TO public;
+
+-- table holding the information to be protected
+CREATE TABLE information (info text,
+ group_id int NOT NULL REFERENCES groups);
+
+INSERT INTO information VALUES
+ ('barely secret', 1),
+ ('slightly secret', 2),
+ ('very secret', 5);
+
+ALTER TABLE information ENABLE ROW LEVEL SECURITY;
+
+-- a row should be visible to/updatable by users whose security group_id is
+-- greater than or equal to the row's group_id
+CREATE POLICY fp_s ON information FOR SELECT
+ USING (group_id &lt;= (SELECT group_id FROM users WHERE user_name = current_user));
+CREATE POLICY fp_u ON information FOR UPDATE
+ USING (group_id &lt;= (SELECT group_id FROM users WHERE user_name = current_user));
+
+-- we rely only on RLS to protect the information table
+GRANT ALL ON information TO public;
+</programlisting>
+
+ <para>
+ Now suppose that <literal>alice</literal> wishes to change the <quote>slightly
+ secret</quote> information, but decides that <literal>mallory</literal> should not
+ be trusted with the new content of that row, so she does:
+ </para>
+
+<programlisting>
+BEGIN;
+UPDATE users SET group_id = 1 WHERE user_name = 'mallory';
+UPDATE information SET info = 'secret from mallory' WHERE group_id = 2;
+COMMIT;
+</programlisting>
+
+ <para>
+ That looks safe; there is no window wherein <literal>mallory</literal> should be
+ able to see the <quote>secret from mallory</quote> string. However, there is
+ a race condition here. If <literal>mallory</literal> is concurrently doing,
+ say,
+<programlisting>
+SELECT * FROM information WHERE group_id = 2 FOR UPDATE;
+</programlisting>
+ and her transaction is in <literal>READ COMMITTED</literal> mode, it is possible
+ for her to see <quote>secret from mallory</quote>. That happens if her
+ transaction reaches the <structname>information</structname> row just
+ after <literal>alice</literal>'s does. It blocks waiting
+ for <literal>alice</literal>'s transaction to commit, then fetches the updated
+ row contents thanks to the <literal>FOR UPDATE</literal> clause. However, it
+ does <emphasis>not</emphasis> fetch an updated row for the
+ implicit <command>SELECT</command> from <structname>users</structname>, because that
+ sub-<command>SELECT</command> did not have <literal>FOR UPDATE</literal>; instead
+ the <structname>users</structname> row is read with the snapshot taken at the start
+ of the query. Therefore, the policy expression tests the old value
+ of <literal>mallory</literal>'s privilege level and allows her to see the
+ updated row.
+ </para>
+
+ <para>
+ There are several ways around this problem. One simple answer is to use
+ <literal>SELECT ... FOR SHARE</literal> in sub-<command>SELECT</command>s in row
+ security policies. However, that requires granting <literal>UPDATE</literal>
+ privilege on the referenced table (here <structname>users</structname>) to the
+ affected users, which might be undesirable. (But another row security
+ policy could be applied to prevent them from actually exercising that
+ privilege; or the sub-<command>SELECT</command> could be embedded into a security
+ definer function.) Also, heavy concurrent use of row share locks on the
+ referenced table could pose a performance problem, especially if updates
+ of it are frequent. Another solution, practical if updates of the
+ referenced table are infrequent, is to take an
+ <literal>ACCESS EXCLUSIVE</literal> lock on the
+ referenced table when updating it, so that no concurrent transactions
+ could be examining old row values. Or one could just wait for all
+ concurrent transactions to end after committing an update of the
+ referenced table and before making changes that rely on the new security
+ situation.
+ </para>
+
+ <para>
+ For additional details see <xref linkend="sql-createpolicy"/>
+ and <xref linkend="sql-altertable"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="ddl-schemas">
+ <title>Schemas</title>
+
+ <indexterm zone="ddl-schemas">
+ <primary>schema</primary>
+ </indexterm>
+
+ <para>
+ A <productname>PostgreSQL</productname> database cluster contains
+ one or more named databases. Roles and a few other object types are
+ shared across the entire cluster. A client connection to the server
+ can only access data in a single database, the one specified in the
+ connection request.
+ </para>
+
+ <note>
+ <para>
+ Users of a cluster do not necessarily have the privilege to access every
+ database in the cluster. Sharing of role names means that there
+ cannot be different roles named, say, <literal>joe</literal> in two databases
+ in the same cluster; but the system can be configured to allow
+ <literal>joe</literal> access to only some of the databases.
+ </para>
+ </note>
+
+ <para>
+ A database contains one or more named <firstterm>schemas</firstterm>, which
+ in turn contain tables. Schemas also contain other kinds of named
+ objects, including data types, functions, and operators. The same
+ object name can be used in different schemas without conflict; for
+ example, both <literal>schema1</literal> and <literal>myschema</literal> can
+ contain tables named <literal>mytable</literal>. Unlike databases,
+ schemas are not rigidly separated: a user can access objects in any
+ of the schemas in the database they are connected to, if they have
+ privileges to do so.
+ </para>
+
+ <para>
+ There are several reasons why one might want to use schemas:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ To allow many users to use one database without interfering with
+ each other.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ To organize database objects into logical groups to make them
+ more manageable.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Third-party applications can be put into separate schemas so
+ they do not collide with the names of other objects.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Schemas are analogous to directories at the operating system level,
+ except that schemas cannot be nested.
+ </para>
+
+ <sect2 id="ddl-schemas-create">
+ <title>Creating a Schema</title>
+
+ <indexterm zone="ddl-schemas-create">
+ <primary>schema</primary>
+ <secondary>creating</secondary>
+ </indexterm>
+
+ <para>
+ To create a schema, use the <xref linkend="sql-createschema"/>
+ command. Give the schema a name
+ of your choice. For example:
+<programlisting>
+CREATE SCHEMA myschema;
+</programlisting>
+ </para>
+
+ <indexterm>
+ <primary>qualified name</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>name</primary>
+ <secondary>qualified</secondary>
+ </indexterm>
+
+ <para>
+ To create or access objects in a schema, write a
+ <firstterm>qualified name</firstterm> consisting of the schema name and
+ table name separated by a dot:
+<synopsis>
+<replaceable>schema</replaceable><literal>.</literal><replaceable>table</replaceable>
+</synopsis>
+ This works anywhere a table name is expected, including the table
+ modification commands and the data access commands discussed in
+ the following chapters.
+ (For brevity we will speak of tables only, but the same ideas apply
+ to other kinds of named objects, such as types and functions.)
+ </para>
+
+ <para>
+ Actually, the even more general syntax
+<synopsis>
+<replaceable>database</replaceable><literal>.</literal><replaceable>schema</replaceable><literal>.</literal><replaceable>table</replaceable>
+</synopsis>
+ can be used too, but at present this is just for pro forma
+ compliance with the SQL standard. If you write a database name,
+ it must be the same as the database you are connected to.
+ </para>
+
+ <para>
+ So to create a table in the new schema, use:
+<programlisting>
+CREATE TABLE myschema.mytable (
+ ...
+);
+</programlisting>
+ </para>
+
+ <indexterm>
+ <primary>schema</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+
+ <para>
+ To drop a schema if it's empty (all objects in it have been
+ dropped), use:
+<programlisting>
+DROP SCHEMA myschema;
+</programlisting>
+ To drop a schema including all contained objects, use:
+<programlisting>
+DROP SCHEMA myschema CASCADE;
+</programlisting>
+ See <xref linkend="ddl-depend"/> for a description of the general
+ mechanism behind this.
+ </para>
+
+ <para>
+ Often you will want to create a schema owned by someone else
+ (since this is one of the ways to restrict the activities of your
+ users to well-defined namespaces). The syntax for that is:
+<programlisting>
+CREATE SCHEMA <replaceable>schema_name</replaceable> AUTHORIZATION <replaceable>user_name</replaceable>;
+</programlisting>
+ You can even omit the schema name, in which case the schema name
+ will be the same as the user name. See <xref
+ linkend="ddl-schemas-patterns"/> for how this can be useful.
+ </para>
+
+ <para>
+ Schema names beginning with <literal>pg_</literal> are reserved for
+ system purposes and cannot be created by users.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-schemas-public">
+ <title>The Public Schema</title>
+
+ <indexterm zone="ddl-schemas-public">
+ <primary>schema</primary>
+ <secondary>public</secondary>
+ </indexterm>
+
+ <para>
+ In the previous sections we created tables without specifying any
+ schema names. By default such tables (and other objects) are
+ automatically put into a schema named <quote>public</quote>. Every new
+ database contains such a schema. Thus, the following are equivalent:
+<programlisting>
+CREATE TABLE products ( ... );
+</programlisting>
+ and:
+<programlisting>
+CREATE TABLE public.products ( ... );
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-schemas-path">
+ <title>The Schema Search Path</title>
+
+ <indexterm>
+ <primary>search path</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>unqualified name</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>name</primary>
+ <secondary>unqualified</secondary>
+ </indexterm>
+
+ <para>
+ Qualified names are tedious to write, and it's often best not to
+ wire a particular schema name into applications anyway. Therefore
+ tables are often referred to by <firstterm>unqualified names</firstterm>,
+ which consist of just the table name. The system determines which table
+ is meant by following a <firstterm>search path</firstterm>, which is a list
+ of schemas to look in. The first matching table in the search path
+ is taken to be the one wanted. If there is no match in the search
+ path, an error is reported, even if matching table names exist
+ in other schemas in the database.
+ </para>
+
+ <para>
+ The ability to create like-named objects in different schemas complicates
+ writing a query that references precisely the same objects every time. It
+ also opens up the potential for users to change the behavior of other
+ users' queries, maliciously or accidentally. Due to the prevalence of
+ unqualified names in queries and their use
+ in <productname>PostgreSQL</productname> internals, adding a schema
+ to <varname>search_path</varname> effectively trusts all users having
+ <literal>CREATE</literal> privilege on that schema. When you run an
+ ordinary query, a malicious user able to create objects in a schema of
+ your search path can take control and execute arbitrary SQL functions as
+ though you executed them.
+ </para>
+
+ <indexterm>
+ <primary>schema</primary>
+ <secondary>current</secondary>
+ </indexterm>
+
+ <para>
+ The first schema named in the search path is called the current schema.
+ Aside from being the first schema searched, it is also the schema in
+ which new tables will be created if the <command>CREATE TABLE</command>
+ command does not specify a schema name.
+ </para>
+
+ <indexterm>
+ <primary><varname>search_path</varname> configuration parameter</primary>
+ </indexterm>
+
+ <para>
+ To show the current search path, use the following command:
+<programlisting>
+SHOW search_path;
+</programlisting>
+ In the default setup this returns:
+<screen>
+ search_path
+--------------
+ "$user", public
+</screen>
+ The first element specifies that a schema with the same name as
+ the current user is to be searched. If no such schema exists,
+ the entry is ignored. The second element refers to the
+ public schema that we have seen already.
+ </para>
+
+ <para>
+ The first schema in the search path that exists is the default
+ location for creating new objects. That is the reason that by
+ default objects are created in the public schema. When objects
+ are referenced in any other context without schema qualification
+ (table modification, data modification, or query commands) the
+ search path is traversed until a matching object is found.
+ Therefore, in the default configuration, any unqualified access
+ again can only refer to the public schema.
+ </para>
+
+ <para>
+ To put our new schema in the path, we use:
+<programlisting>
+SET search_path TO myschema,public;
+</programlisting>
+ (We omit the <literal>$user</literal> here because we have no
+ immediate need for it.) And then we can access the table without
+ schema qualification:
+<programlisting>
+DROP TABLE mytable;
+</programlisting>
+ Also, since <literal>myschema</literal> is the first element in
+ the path, new objects would by default be created in it.
+ </para>
+
+ <para>
+ We could also have written:
+<programlisting>
+SET search_path TO myschema;
+</programlisting>
+ Then we no longer have access to the public schema without
+ explicit qualification. There is nothing special about the public
+ schema except that it exists by default. It can be dropped, too.
+ </para>
+
+ <para>
+ See also <xref linkend="functions-info"/> for other ways to manipulate
+ the schema search path.
+ </para>
+
+ <para>
+ The search path works in the same way for data type names, function names,
+ and operator names as it does for table names. Data type and function
+ names can be qualified in exactly the same way as table names. If you
+ need to write a qualified operator name in an expression, there is a
+ special provision: you must write
+<synopsis>
+<literal>OPERATOR(</literal><replaceable>schema</replaceable><literal>.</literal><replaceable>operator</replaceable><literal>)</literal>
+</synopsis>
+ This is needed to avoid syntactic ambiguity. An example is:
+<programlisting>
+SELECT 3 OPERATOR(pg_catalog.+) 4;
+</programlisting>
+ In practice one usually relies on the search path for operators,
+ so as not to have to write anything so ugly as that.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-schemas-priv">
+ <title>Schemas and Privileges</title>
+
+ <indexterm zone="ddl-schemas-priv">
+ <primary>privilege</primary>
+ <secondary sortas="schemas">for schemas</secondary>
+ </indexterm>
+
+ <para>
+ By default, users cannot access any objects in schemas they do not
+ own. To allow that, the owner of the schema must grant the
+ <literal>USAGE</literal> privilege on the schema. By default, everyone
+ has that privilege on the schema <literal>public</literal>. To allow
+ users to make use of the objects in a schema, additional privileges might
+ need to be granted, as appropriate for the object.
+ </para>
+
+ <para>
+ A user can also be allowed to create objects in someone else's schema. To
+ allow that, the <literal>CREATE</literal> privilege on the schema needs to
+ be granted. In databases upgraded from
+ <productname>PostgreSQL</productname> 14 or earlier, everyone has that
+ privilege on the schema <literal>public</literal>.
+ Some <link linkend="ddl-schemas-patterns">usage patterns</link> call for
+ revoking that privilege:
+<programlisting>
+REVOKE CREATE ON SCHEMA public FROM PUBLIC;
+</programlisting>
+ (The first <quote>public</quote> is the schema, the second
+ <quote>public</quote> means <quote>every user</quote>. In the
+ first sense it is an identifier, in the second sense it is a
+ key word, hence the different capitalization; recall the
+ guidelines from <xref linkend="sql-syntax-identifiers"/>.)
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-schemas-catalog">
+ <title>The System Catalog Schema</title>
+
+ <indexterm zone="ddl-schemas-catalog">
+ <primary>system catalog</primary>
+ <secondary>schema</secondary>
+ </indexterm>
+
+ <para>
+ In addition to <literal>public</literal> and user-created schemas, each
+ database contains a <literal>pg_catalog</literal> schema, which contains
+ the system tables and all the built-in data types, functions, and
+ operators. <literal>pg_catalog</literal> is always effectively part of
+ the search path. If it is not named explicitly in the path then
+ it is implicitly searched <emphasis>before</emphasis> searching the path's
+ schemas. This ensures that built-in names will always be
+ findable. However, you can explicitly place
+ <literal>pg_catalog</literal> at the end of your search path if you
+ prefer to have user-defined names override built-in names.
+ </para>
+
+ <para>
+ Since system table names begin with <literal>pg_</literal>, it is best to
+ avoid such names to ensure that you won't suffer a conflict if some
+ future version defines a system table named the same as your
+ table. (With the default search path, an unqualified reference to
+ your table name would then be resolved as the system table instead.)
+ System tables will continue to follow the convention of having
+ names beginning with <literal>pg_</literal>, so that they will not
+ conflict with unqualified user-table names so long as users avoid
+ the <literal>pg_</literal> prefix.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-schemas-patterns">
+ <title>Usage Patterns</title>
+
+ <para>
+ Schemas can be used to organize your data in many ways.
+ A <firstterm>secure schema usage pattern</firstterm> prevents untrusted
+ users from changing the behavior of other users' queries. When a database
+ does not use a secure schema usage pattern, users wishing to securely
+ query that database would take protective action at the beginning of each
+ session. Specifically, they would begin each session by
+ setting <varname>search_path</varname> to the empty string or otherwise
+ removing schemas that are writable by non-superusers
+ from <varname>search_path</varname>. There are a few usage patterns
+ easily supported by the default configuration:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Constrain ordinary users to user-private schemas.
+ To implement this pattern, first ensure that no schemas have
+ public <literal>CREATE</literal> privileges. Then, for every user
+ needing to create non-temporary objects, create a schema with the
+ same name as that user, for example
+ <literal>CREATE SCHEMA alice AUTHORIZATION alice</literal>.
+ (Recall that the default search path starts
+ with <literal>$user</literal>, which resolves to the user
+ name. Therefore, if each user has a separate schema, they access
+ their own schemas by default.) This pattern is a secure schema
+ usage pattern unless an untrusted user is the database owner or
+ holds the <literal>CREATEROLE</literal> privilege, in which case no
+ secure schema usage pattern exists.
+ </para>
+ <!-- A database owner can attack the database's users via "CREATE SCHEMA
+ trojan; ALTER DATABASE $mydb SET search_path = trojan, public;". A
+ CREATEROLE user can issue "GRANT $dbowner TO $me" and then use the
+ database owner attack. -->
+
+ <para>
+ In <productname>PostgreSQL</productname> 15 and later, the default
+ configuration supports this usage pattern. In prior versions, or
+ when using a database that has been upgraded from a prior version,
+ you will need to remove the public <literal>CREATE</literal>
+ privilege from the <literal>public</literal> schema (issue
+ <literal>REVOKE CREATE ON SCHEMA public FROM PUBLIC</literal>).
+ Then consider auditing the <literal>public</literal> schema for
+ objects named like objects in schema <literal>pg_catalog</literal>.
+ </para>
+ <!-- "DROP SCHEMA public" is inferior to this REVOKE, because pg_dump
+ doesn't preserve that DROP. -->
+ </listitem>
+
+ <listitem>
+ <para>
+ Remove the public schema from the default search path, by modifying
+ <link linkend="config-setting-configuration-file"><filename>postgresql.conf</filename></link>
+ or by issuing <literal>ALTER ROLE ALL SET search_path =
+ "$user"</literal>. Then, grant privileges to create in the public
+ schema. Only qualified names will choose public schema objects. While
+ qualified table references are fine, calls to functions in the public
+ schema <link linkend="typeconv-func">will be unsafe or
+ unreliable</link>. If you create functions or extensions in the public
+ schema, use the first pattern instead. Otherwise, like the first
+ pattern, this is secure unless an untrusted user is the database owner
+ or holds the <literal>CREATEROLE</literal> privilege.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Keep the default search path, and grant privileges to create in the
+ public schema. All users access the public schema implicitly. This
+ simulates the situation where schemas are not available at all, giving
+ a smooth transition from the non-schema-aware world. However, this is
+ never a secure pattern. It is acceptable only when the database has a
+ single user or a few mutually-trusting users. In databases upgraded
+ from <productname>PostgreSQL</productname> 14 or earlier, this is the
+ default.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ For any pattern, to install shared applications (tables to be used by
+ everyone, additional functions provided by third parties, etc.), put them
+ into separate schemas. Remember to grant appropriate privileges to allow
+ the other users to access them. Users can then refer to these additional
+ objects by qualifying the names with a schema name, or they can put the
+ additional schemas into their search path, as they choose.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-schemas-portability">
+ <title>Portability</title>
+
+ <para>
+ In the SQL standard, the notion of objects in the same schema
+ being owned by different users does not exist. Moreover, some
+ implementations do not allow you to create schemas that have a
+ different name than their owner. In fact, the concepts of schema
+ and user are nearly equivalent in a database system that
+ implements only the basic schema support specified in the
+ standard. Therefore, many users consider qualified names to
+ really consist of
+ <literal><replaceable>user_name</replaceable>.<replaceable>table_name</replaceable></literal>.
+ This is how <productname>PostgreSQL</productname> will effectively
+ behave if you create a per-user schema for every user.
+ </para>
+
+ <para>
+ Also, there is no concept of a <literal>public</literal> schema in the
+ SQL standard. For maximum conformance to the standard, you should
+ not use the <literal>public</literal> schema.
+ </para>
+
+ <para>
+ Of course, some SQL database systems might not implement schemas
+ at all, or provide namespace support by allowing (possibly
+ limited) cross-database access. If you need to work with those
+ systems, then maximum portability would be achieved by not using
+ schemas at all.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ddl-inherit">
+ <title>Inheritance</title>
+
+ <indexterm>
+ <primary>inheritance</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>table</primary>
+ <secondary>inheritance</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> implements table inheritance,
+ which can be a useful tool for database designers. (SQL:1999 and
+ later define a type inheritance feature, which differs in many
+ respects from the features described here.)
+ </para>
+
+ <para>
+ Let's start with an example: suppose we are trying to build a data
+ model for cities. Each state has many cities, but only one
+ capital. We want to be able to quickly retrieve the capital city
+ for any particular state. This can be done by creating two tables,
+ one for state capitals and one for cities that are not
+ capitals. However, what happens when we want to ask for data about
+ a city, regardless of whether it is a capital or not? The
+ inheritance feature can help to resolve this problem. We define the
+ <structname>capitals</structname> table so that it inherits from
+ <structname>cities</structname>:
+
+<programlisting>
+CREATE TABLE cities (
+ name text,
+ population float,
+ elevation int -- in feet
+);
+
+CREATE TABLE capitals (
+ state char(2)
+) INHERITS (cities);
+</programlisting>
+
+ In this case, the <structname>capitals</structname> table <firstterm>inherits</firstterm>
+ all the columns of its parent table, <structname>cities</structname>. State
+ capitals also have an extra column, <structfield>state</structfield>, that shows
+ their state.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname>, a table can inherit from
+ zero or more other tables, and a query can reference either all
+ rows of a table or all rows of a table plus all of its descendant tables.
+ The latter behavior is the default.
+ For example, the following query finds the names of all cities,
+ including state capitals, that are located at an elevation over
+ 500 feet:
+
+<programlisting>
+SELECT name, elevation
+ FROM cities
+ WHERE elevation &gt; 500;
+</programlisting>
+
+ Given the sample data from the <productname>PostgreSQL</productname>
+ tutorial (see <xref linkend="tutorial-sql-intro"/>), this returns:
+
+<programlisting>
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+ Madison | 845
+</programlisting>
+ </para>
+
+ <para>
+ On the other hand, the following query finds all the cities that
+ are not state capitals and are situated at an elevation over 500 feet:
+
+<programlisting>
+SELECT name, elevation
+ FROM ONLY cities
+ WHERE elevation &gt; 500;
+
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+</programlisting>
+ </para>
+
+ <para>
+ Here the <literal>ONLY</literal> keyword indicates that the query
+ should apply only to <structname>cities</structname>, and not any tables
+ below <structname>cities</structname> in the inheritance hierarchy. Many
+ of the commands that we have already discussed &mdash;
+ <command>SELECT</command>, <command>UPDATE</command> and
+ <command>DELETE</command> &mdash; support the
+ <literal>ONLY</literal> keyword.
+ </para>
+
+ <para>
+ You can also write the table name with a trailing <literal>*</literal>
+ to explicitly specify that descendant tables are included:
+
+<programlisting>
+SELECT name, elevation
+ FROM cities*
+ WHERE elevation &gt; 500;
+</programlisting>
+
+ Writing <literal>*</literal> is not necessary, since this behavior is always
+ the default. However, this syntax is still supported for
+ compatibility with older releases where the default could be changed.
+ </para>
+
+ <para>
+ In some cases you might wish to know which table a particular row
+ originated from. There is a system column called
+ <structfield>tableoid</structfield> in each table which can tell you the
+ originating table:
+
+<programlisting>
+SELECT c.tableoid, c.name, c.elevation
+FROM cities c
+WHERE c.elevation &gt; 500;
+</programlisting>
+
+ which returns:
+
+<programlisting>
+ tableoid | name | elevation
+----------+-----------+-----------
+ 139793 | Las Vegas | 2174
+ 139793 | Mariposa | 1953
+ 139798 | Madison | 845
+</programlisting>
+
+ (If you try to reproduce this example, you will probably get
+ different numeric OIDs.) By doing a join with
+ <structname>pg_class</structname> you can see the actual table names:
+
+<programlisting>
+SELECT p.relname, c.name, c.elevation
+FROM cities c, pg_class p
+WHERE c.elevation &gt; 500 AND c.tableoid = p.oid;
+</programlisting>
+
+ which returns:
+
+<programlisting>
+ relname | name | elevation
+----------+-----------+-----------
+ cities | Las Vegas | 2174
+ cities | Mariposa | 1953
+ capitals | Madison | 845
+</programlisting>
+ </para>
+
+ <para>
+ Another way to get the same effect is to use the <type>regclass</type>
+ alias type, which will print the table OID symbolically:
+
+<programlisting>
+SELECT c.tableoid::regclass, c.name, c.elevation
+FROM cities c
+WHERE c.elevation &gt; 500;
+</programlisting>
+ </para>
+
+ <para>
+ Inheritance does not automatically propagate data from
+ <command>INSERT</command> or <command>COPY</command> commands to
+ other tables in the inheritance hierarchy. In our example, the
+ following <command>INSERT</command> statement will fail:
+<programlisting>
+INSERT INTO cities (name, population, elevation, state)
+VALUES ('Albany', NULL, NULL, 'NY');
+</programlisting>
+ We might hope that the data would somehow be routed to the
+ <structname>capitals</structname> table, but this does not happen:
+ <command>INSERT</command> always inserts into exactly the table
+ specified. In some cases it is possible to redirect the insertion
+ using a rule (see <xref linkend="rules"/>). However that does not
+ help for the above case because the <structname>cities</structname> table
+ does not contain the column <structfield>state</structfield>, and so the
+ command will be rejected before the rule can be applied.
+ </para>
+
+ <para>
+ All check constraints and not-null constraints on a parent table are
+ automatically inherited by its children, unless explicitly specified
+ otherwise with <literal>NO INHERIT</literal> clauses. Other types of constraints
+ (unique, primary key, and foreign key constraints) are not inherited.
+ </para>
+
+ <para>
+ A table can inherit from more than one parent table, in which case it has
+ the union of the columns defined by the parent tables. Any columns
+ declared in the child table's definition are added to these. If the
+ same column name appears in multiple parent tables, or in both a parent
+ table and the child's definition, then these columns are <quote>merged</quote>
+ so that there is only one such column in the child table. To be merged,
+ columns must have the same data types, else an error is raised.
+ Inheritable check constraints and not-null constraints are merged in a
+ similar fashion. Thus, for example, a merged column will be marked
+ not-null if any one of the column definitions it came from is marked
+ not-null. Check constraints are merged if they have the same name,
+ and the merge will fail if their conditions are different.
+ </para>
+
+ <para>
+ Table inheritance is typically established when the child table is
+ created, using the <literal>INHERITS</literal> clause of the
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link>
+ statement.
+ Alternatively, a table which is already defined in a compatible way can
+ have a new parent relationship added, using the <literal>INHERIT</literal>
+ variant of <link linkend="sql-altertable"><command>ALTER TABLE</command></link>.
+ To do this the new child table must already include columns with
+ the same names and types as the columns of the parent. It must also include
+ check constraints with the same names and check expressions as those of the
+ parent. Similarly an inheritance link can be removed from a child using the
+ <literal>NO INHERIT</literal> variant of <command>ALTER TABLE</command>.
+ Dynamically adding and removing inheritance links like this can be useful
+ when the inheritance relationship is being used for table
+ partitioning (see <xref linkend="ddl-partitioning"/>).
+ </para>
+
+ <para>
+ One convenient way to create a compatible table that will later be made
+ a new child is to use the <literal>LIKE</literal> clause in <command>CREATE
+ TABLE</command>. This creates a new table with the same columns as
+ the source table. If there are any <literal>CHECK</literal>
+ constraints defined on the source table, the <literal>INCLUDING
+ CONSTRAINTS</literal> option to <literal>LIKE</literal> should be
+ specified, as the new child must have constraints matching the parent
+ to be considered compatible.
+ </para>
+
+ <para>
+ A parent table cannot be dropped while any of its children remain. Neither
+ can columns or check constraints of child tables be dropped or altered
+ if they are inherited
+ from any parent tables. If you wish to remove a table and all of its
+ descendants, one easy way is to drop the parent table with the
+ <literal>CASCADE</literal> option (see <xref linkend="ddl-depend"/>).
+ </para>
+
+ <para>
+ <command>ALTER TABLE</command> will
+ propagate any changes in column data definitions and check
+ constraints down the inheritance hierarchy. Again, dropping
+ columns that are depended on by other tables is only possible when using
+ the <literal>CASCADE</literal> option. <command>ALTER
+ TABLE</command> follows the same rules for duplicate column merging
+ and rejection that apply during <command>CREATE TABLE</command>.
+ </para>
+
+ <para>
+ Inherited queries perform access permission checks on the parent table
+ only. Thus, for example, granting <literal>UPDATE</literal> permission on
+ the <structname>cities</structname> table implies permission to update rows in
+ the <structname>capitals</structname> table as well, when they are
+ accessed through <structname>cities</structname>. This preserves the appearance
+ that the data is (also) in the parent table. But
+ the <structname>capitals</structname> table could not be updated directly
+ without an additional grant. In a similar way, the parent table's row
+ security policies (see <xref linkend="ddl-rowsecurity"/>) are applied to
+ rows coming from child tables during an inherited query. A child table's
+ policies, if any, are applied only when it is the table explicitly named
+ in the query; and in that case, any policies attached to its parent(s) are
+ ignored.
+ </para>
+
+ <para>
+ Foreign tables (see <xref linkend="ddl-foreign-data"/>) can also
+ be part of inheritance hierarchies, either as parent or child
+ tables, just as regular tables can be. If a foreign table is part
+ of an inheritance hierarchy then any operations not supported by
+ the foreign table are not supported on the whole hierarchy either.
+ </para>
+
+ <sect2 id="ddl-inherit-caveats">
+ <title>Caveats</title>
+
+ <para>
+ Note that not all SQL commands are able to work on
+ inheritance hierarchies. Commands that are used for data querying,
+ data modification, or schema modification
+ (e.g., <literal>SELECT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>,
+ most variants of <literal>ALTER TABLE</literal>, but
+ not <literal>INSERT</literal> or <literal>ALTER TABLE ...
+ RENAME</literal>) typically default to including child tables and
+ support the <literal>ONLY</literal> notation to exclude them.
+ Commands that do database maintenance and tuning
+ (e.g., <literal>REINDEX</literal>, <literal>VACUUM</literal>)
+ typically only work on individual, physical tables and do not
+ support recursing over inheritance hierarchies. The respective
+ behavior of each individual command is documented in its reference
+ page (<xref linkend="sql-commands"/>).
+ </para>
+
+ <para>
+ A serious limitation of the inheritance feature is that indexes (including
+ unique constraints) and foreign key constraints only apply to single
+ tables, not to their inheritance children. This is true on both the
+ referencing and referenced sides of a foreign key constraint. Thus,
+ in the terms of the above example:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If we declared <structname>cities</structname>.<structfield>name</structfield> to be
+ <literal>UNIQUE</literal> or a <literal>PRIMARY KEY</literal>, this would not stop the
+ <structname>capitals</structname> table from having rows with names duplicating
+ rows in <structname>cities</structname>. And those duplicate rows would by
+ default show up in queries from <structname>cities</structname>. In fact, by
+ default <structname>capitals</structname> would have no unique constraint at all,
+ and so could contain multiple rows with the same name.
+ You could add a unique constraint to <structname>capitals</structname>, but this
+ would not prevent duplication compared to <structname>cities</structname>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Similarly, if we were to specify that
+ <structname>cities</structname>.<structfield>name</structfield> <literal>REFERENCES</literal> some
+ other table, this constraint would not automatically propagate to
+ <structname>capitals</structname>. In this case you could work around it by
+ manually adding the same <literal>REFERENCES</literal> constraint to
+ <structname>capitals</structname>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Specifying that another table's column <literal>REFERENCES
+ cities(name)</literal> would allow the other table to contain city names, but
+ not capital names. There is no good workaround for this case.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Some functionality not implemented for inheritance hierarchies is
+ implemented for declarative partitioning.
+ Considerable care is needed in deciding whether partitioning with legacy
+ inheritance is useful for your application.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="ddl-partitioning">
+ <title>Table Partitioning</title>
+
+ <indexterm>
+ <primary>partitioning</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>table</primary>
+ <secondary>partitioning</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>partitioned table</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> supports basic table
+ partitioning. This section describes why and how to implement
+ partitioning as part of your database design.
+ </para>
+
+ <sect2 id="ddl-partitioning-overview">
+ <title>Overview</title>
+
+ <para>
+ Partitioning refers to splitting what is logically one large table into
+ smaller physical pieces. Partitioning can provide several benefits:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Query performance can be improved dramatically in certain situations,
+ particularly when most of the heavily accessed rows of the table are in a
+ single partition or a small number of partitions. Partitioning
+ effectively substitutes for the upper tree levels of indexes,
+ making it more likely that the heavily-used parts of the indexes
+ fit in memory.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When queries or updates access a large percentage of a single
+ partition, performance can be improved by using a
+ sequential scan of that partition instead of using an
+ index, which would require random-access reads scattered across the
+ whole table.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Bulk loads and deletes can be accomplished by adding or removing
+ partitions, if the usage pattern is accounted for in the
+ partitioning design. Dropping an individual partition
+ using <command>DROP TABLE</command>, or doing <command>ALTER TABLE
+ DETACH PARTITION</command>, is far faster than a bulk
+ operation. These commands also entirely avoid the
+ <command>VACUUM</command> overhead caused by a bulk <command>DELETE</command>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Seldom-used data can be migrated to cheaper and slower storage media.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ These benefits will normally be worthwhile only when a table would
+ otherwise be very large. The exact point at which a table will
+ benefit from partitioning depends on the application, although a
+ rule of thumb is that the size of the table should exceed the physical
+ memory of the database server.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> offers built-in support for the
+ following forms of partitioning:
+
+ <variablelist>
+ <varlistentry>
+ <term>Range Partitioning</term>
+
+ <listitem>
+ <para>
+ The table is partitioned into <quote>ranges</quote> defined
+ by a key column or set of columns, with no overlap between
+ the ranges of values assigned to different partitions. For
+ example, one might partition by date ranges, or by ranges of
+ identifiers for particular business objects.
+ Each range's bounds are understood as being inclusive at the
+ lower end and exclusive at the upper end. For example, if one
+ partition's range is from <literal>1</literal>
+ to <literal>10</literal>, and the next one's range is
+ from <literal>10</literal> to <literal>20</literal>, then
+ value <literal>10</literal> belongs to the second partition not
+ the first.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>List Partitioning</term>
+
+ <listitem>
+ <para>
+ The table is partitioned by explicitly listing which key value(s)
+ appear in each partition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Hash Partitioning</term>
+
+ <listitem>
+ <para>
+ The table is partitioned by specifying a modulus and a remainder for
+ each partition. Each partition will hold the rows for which the hash
+ value of the partition key divided by the specified modulus will
+ produce the specified remainder.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ If your application needs to use other forms of partitioning not listed
+ above, alternative methods such as inheritance and
+ <literal>UNION ALL</literal> views can be used instead. Such methods
+ offer flexibility but do not have some of the performance benefits
+ of built-in declarative partitioning.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-partitioning-declarative">
+ <title>Declarative Partitioning</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows you to declare
+ that a table is divided into partitions. The table that is divided
+ is referred to as a <firstterm>partitioned table</firstterm>. The
+ declaration includes the <firstterm>partitioning method</firstterm>
+ as described above, plus a list of columns or expressions to be used
+ as the <firstterm>partition key</firstterm>.
+ </para>
+
+ <para>
+ The partitioned table itself is a <quote>virtual</quote> table having
+ no storage of its own. Instead, the storage belongs
+ to <firstterm>partitions</firstterm>, which are otherwise-ordinary
+ tables associated with the partitioned table.
+ Each partition stores a subset of the data as defined by its
+ <firstterm>partition bounds</firstterm>.
+ All rows inserted into a partitioned table will be routed to the
+ appropriate one of the partitions based on the values of the partition
+ key column(s).
+ Updating the partition key of a row will cause it to be moved into a
+ different partition if it no longer satisfies the partition bounds
+ of its original partition.
+ </para>
+
+ <para>
+ Partitions may themselves be defined as partitioned tables, resulting
+ in <firstterm>sub-partitioning</firstterm>. Although all partitions
+ must have the same columns as their partitioned parent, partitions may
+ have their
+ own indexes, constraints and default values, distinct from those of other
+ partitions. See <xref linkend="sql-createtable"/> for more details on
+ creating partitioned tables and partitions.
+ </para>
+
+ <para>
+ It is not possible to turn a regular table into a partitioned table or
+ vice versa. However, it is possible to add an existing regular or
+ partitioned table as a partition of a partitioned table, or remove a
+ partition from a partitioned table turning it into a standalone table;
+ this can simplify and speed up many maintenance processes.
+ See <xref linkend="sql-altertable"/> to learn more about the
+ <command>ATTACH PARTITION</command> and <command>DETACH PARTITION</command>
+ sub-commands.
+ </para>
+
+ <para>
+ Partitions can also be <link linkend="ddl-foreign-data">foreign
+ tables</link>, although considerable care is needed because it is then
+ the user's responsibility that the contents of the foreign table
+ satisfy the partitioning rule. There are some other restrictions as
+ well. See <xref linkend="sql-createforeigntable"/> for more
+ information.
+ </para>
+
+ <sect3 id="ddl-partitioning-declarative-example">
+ <title>Example</title>
+
+ <para>
+ Suppose we are constructing a database for a large ice cream company.
+ The company measures peak temperatures every day as well as ice cream
+ sales in each region. Conceptually, we want a table like:
+
+<programlisting>
+CREATE TABLE measurement (
+ city_id int not null,
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+);
+</programlisting>
+
+ We know that most queries will access just the last week's, month's or
+ quarter's data, since the main use of this table will be to prepare
+ online reports for management. To reduce the amount of old data that
+ needs to be stored, we decide to keep only the most recent 3 years
+ worth of data. At the beginning of each month we will remove the oldest
+ month's data. In this situation we can use partitioning to help us meet
+ all of our different requirements for the measurements table.
+ </para>
+
+ <para>
+ To use declarative partitioning in this case, use the following steps:
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Create the <structname>measurement</structname> table as a partitioned
+ table by specifying the <literal>PARTITION BY</literal> clause, which
+ includes the partitioning method (<literal>RANGE</literal> in this
+ case) and the list of column(s) to use as the partition key.
+
+<programlisting>
+CREATE TABLE measurement (
+ city_id int not null,
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (logdate);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Create partitions. Each partition's definition must specify bounds
+ that correspond to the partitioning method and partition key of the
+ parent. Note that specifying bounds such that the new partition's
+ values would overlap with those in one or more existing partitions will
+ cause an error.
+ </para>
+
+ <para>
+ Partitions thus created are in every way normal
+ <productname>PostgreSQL</productname>
+ tables (or, possibly, foreign tables). It is possible to specify a
+ tablespace and storage parameters for each partition separately.
+ </para>
+
+ <para>
+ For our example, each partition should hold one month's worth of
+ data, to match the requirement of deleting one month's data at a
+ time. So the commands might look like:
+
+<programlisting>
+CREATE TABLE measurement_y2006m02 PARTITION OF measurement
+ FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
+
+CREATE TABLE measurement_y2006m03 PARTITION OF measurement
+ FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
+
+...
+CREATE TABLE measurement_y2007m11 PARTITION OF measurement
+ FOR VALUES FROM ('2007-11-01') TO ('2007-12-01');
+
+CREATE TABLE measurement_y2007m12 PARTITION OF measurement
+ FOR VALUES FROM ('2007-12-01') TO ('2008-01-01')
+ TABLESPACE fasttablespace;
+
+CREATE TABLE measurement_y2008m01 PARTITION OF measurement
+ FOR VALUES FROM ('2008-01-01') TO ('2008-02-01')
+ WITH (parallel_workers = 4)
+ TABLESPACE fasttablespace;
+</programlisting>
+
+ (Recall that adjacent partitions can share a bound value, since
+ range upper bounds are treated as exclusive bounds.)
+ </para>
+
+ <para>
+ If you wish to implement sub-partitioning, again specify the
+ <literal>PARTITION BY</literal> clause in the commands used to create
+ individual partitions, for example:
+
+<programlisting>
+CREATE TABLE measurement_y2006m02 PARTITION OF measurement
+ FOR VALUES FROM ('2006-02-01') TO ('2006-03-01')
+ PARTITION BY RANGE (peaktemp);
+</programlisting>
+
+ After creating partitions of <structname>measurement_y2006m02</structname>,
+ any data inserted into <structname>measurement</structname> that is mapped to
+ <structname>measurement_y2006m02</structname> (or data that is
+ directly inserted into <structname>measurement_y2006m02</structname>,
+ which is allowed provided its partition constraint is satisfied)
+ will be further redirected to one of its
+ partitions based on the <structfield>peaktemp</structfield> column. The partition
+ key specified may overlap with the parent's partition key, although
+ care should be taken when specifying the bounds of a sub-partition
+ such that the set of data it accepts constitutes a subset of what
+ the partition's own bounds allow; the system does not try to check
+ whether that's really the case.
+ </para>
+
+ <para>
+ Inserting data into the parent table that does not map
+ to one of the existing partitions will cause an error; an appropriate
+ partition must be added manually.
+ </para>
+
+ <para>
+ It is not necessary to manually create table constraints describing
+ the partition boundary conditions for partitions. Such constraints
+ will be created automatically.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Create an index on the key column(s), as well as any other indexes you
+ might want, on the partitioned table. (The key index is not strictly
+ necessary, but in most scenarios it is helpful.)
+ This automatically creates a matching index on each partition, and
+ any partitions you create or attach later will also have such an
+ index.
+ An index or unique constraint declared on a partitioned table
+ is <quote>virtual</quote> in the same way that the partitioned table
+ is: the actual data is in child indexes on the individual partition
+ tables.
+
+<programlisting>
+CREATE INDEX ON measurement (logdate);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Ensure that the <xref linkend="guc-enable-partition-pruning"/>
+ configuration parameter is not disabled in <filename>postgresql.conf</filename>.
+ If it is, queries will not be optimized as desired.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ In the above example we would be creating a new partition each month, so
+ it might be wise to write a script that generates the required DDL
+ automatically.
+ </para>
+ </sect3>
+
+ <sect3 id="ddl-partitioning-declarative-maintenance">
+ <title>Partition Maintenance</title>
+
+ <para>
+ Normally the set of partitions established when initially defining the
+ table is not intended to remain static. It is common to want to
+ remove partitions holding old data and periodically add new partitions for
+ new data. One of the most important advantages of partitioning is
+ precisely that it allows this otherwise painful task to be executed
+ nearly instantaneously by manipulating the partition structure, rather
+ than physically moving large amounts of data around.
+ </para>
+
+ <para>
+ The simplest option for removing old data is to drop the partition that
+ is no longer necessary:
+<programlisting>
+DROP TABLE measurement_y2006m02;
+</programlisting>
+ This can very quickly delete millions of records because it doesn't have
+ to individually delete every record. Note however that the above command
+ requires taking an <literal>ACCESS EXCLUSIVE</literal> lock on the parent
+ table.
+ </para>
+
+ <para>
+ Another option that is often preferable is to remove the partition from
+ the partitioned table but retain access to it as a table in its own
+ right. This has two forms:
+
+<programlisting>
+ALTER TABLE measurement DETACH PARTITION measurement_y2006m02;
+ALTER TABLE measurement DETACH PARTITION measurement_y2006m02 CONCURRENTLY;
+</programlisting>
+
+ These allow further operations to be performed on the data before
+ it is dropped. For example, this is often a useful time to back up
+ the data using <command>COPY</command>, <application>pg_dump</application>, or
+ similar tools. It might also be a useful time to aggregate data
+ into smaller formats, perform other data manipulations, or run
+ reports. The first form of the command requires an
+ <literal>ACCESS EXCLUSIVE</literal> lock on the parent table.
+ Adding the <literal>CONCURRENTLY</literal> qualifier as in the second
+ form allows the detach operation to require only
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the parent table, but see
+ <link linkend="sql-altertable-detach-partition"><literal>ALTER TABLE ... DETACH PARTITION</literal></link>
+ for details on the restrictions.
+ </para>
+
+ <para>
+ Similarly we can add a new partition to handle new data. We can create an
+ empty partition in the partitioned table just as the original partitions
+ were created above:
+
+<programlisting>
+CREATE TABLE measurement_y2008m02 PARTITION OF measurement
+ FOR VALUES FROM ('2008-02-01') TO ('2008-03-01')
+ TABLESPACE fasttablespace;
+</programlisting>
+
+ As an alternative, it is sometimes more convenient to create the
+ new table outside the partition structure, and attach it as a
+ partition later. This allows new data to be loaded, checked, and
+ transformed prior to it appearing in the partitioned table.
+ Moreover, the <literal>ATTACH PARTITION</literal> operation requires
+ only <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the
+ partitioned table, as opposed to the <literal>ACCESS
+ EXCLUSIVE</literal> lock that is required by <command>CREATE TABLE
+ ... PARTITION OF</command>, so it is more friendly to concurrent
+ operations on the partitioned table.
+ The <literal>CREATE TABLE ... LIKE</literal> option is helpful
+ to avoid tediously repeating the parent table's definition:
+
+<programlisting>
+CREATE TABLE measurement_y2008m02
+ (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS)
+ TABLESPACE fasttablespace;
+
+ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02
+ CHECK ( logdate &gt;= DATE '2008-02-01' AND logdate &lt; DATE '2008-03-01' );
+
+\copy measurement_y2008m02 from 'measurement_y2008m02'
+-- possibly some other data preparation work
+
+ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02
+ FOR VALUES FROM ('2008-02-01') TO ('2008-03-01' );
+</programlisting>
+ </para>
+
+ <para>
+ Before running the <command>ATTACH PARTITION</command> command, it is
+ recommended to create a <literal>CHECK</literal> constraint on the table to
+ be attached that matches the expected partition constraint, as
+ illustrated above. That way, the system will be able to skip the scan
+ which is otherwise needed to validate the implicit
+ partition constraint. Without the <literal>CHECK</literal> constraint,
+ the table will be scanned to validate the partition constraint while
+ holding an <literal>ACCESS EXCLUSIVE</literal> lock on that partition.
+ It is recommended to drop the now-redundant <literal>CHECK</literal>
+ constraint after the <command>ATTACH PARTITION</command> is complete. If
+ the table being attached is itself a partitioned table, then each of its
+ sub-partitions will be recursively locked and scanned until either a
+ suitable <literal>CHECK</literal> constraint is encountered or the leaf
+ partitions are reached.
+ </para>
+
+ <para>
+ Similarly, if the partitioned table has a <literal>DEFAULT</literal>
+ partition, it is recommended to create a <literal>CHECK</literal>
+ constraint which excludes the to-be-attached partition's constraint. If
+ this is not done then the <literal>DEFAULT</literal> partition will be
+ scanned to verify that it contains no records which should be located in
+ the partition being attached. This operation will be performed whilst
+ holding an <literal>ACCESS EXCLUSIVE</literal> lock on the <literal>
+ DEFAULT</literal> partition. If the <literal>DEFAULT</literal> partition
+ is itself a partitioned table, then each of its partitions will be
+ recursively checked in the same way as the table being attached, as
+ mentioned above.
+ </para>
+
+ <para>
+ As explained above, it is possible to create indexes on partitioned tables
+ so that they are applied automatically to the entire hierarchy.
+ This is very
+ convenient, as not only will the existing partitions become indexed, but
+ also any partitions that are created in the future will. One limitation is
+ that it's not possible to use the <literal>CONCURRENTLY</literal>
+ qualifier when creating such a partitioned index. To avoid long lock
+ times, it is possible to use <command>CREATE INDEX ON ONLY</command>
+ the partitioned table; such an index is marked invalid, and the partitions
+ do not get the index applied automatically. The indexes on partitions can
+ be created individually using <literal>CONCURRENTLY</literal>, and then
+ <firstterm>attached</firstterm> to the index on the parent using
+ <command>ALTER INDEX .. ATTACH PARTITION</command>. Once indexes for all
+ partitions are attached to the parent index, the parent index is marked
+ valid automatically. Example:
+<programlisting>
+CREATE INDEX measurement_usls_idx ON ONLY measurement (unitsales);
+
+CREATE INDEX measurement_usls_200602_idx
+ ON measurement_y2006m02 (unitsales);
+ALTER INDEX measurement_usls_idx
+ ATTACH PARTITION measurement_usls_200602_idx;
+...
+</programlisting>
+
+ This technique can be used with <literal>UNIQUE</literal> and
+ <literal>PRIMARY KEY</literal> constraints too; the indexes are created
+ implicitly when the constraint is created. Example:
+<programlisting>
+ALTER TABLE ONLY measurement ADD UNIQUE (city_id, logdate);
+
+ALTER TABLE measurement_y2006m02 ADD UNIQUE (city_id, logdate);
+ALTER INDEX measurement_city_id_logdate_key
+ ATTACH PARTITION measurement_y2006m02_city_id_logdate_key;
+...
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="ddl-partitioning-declarative-limitations">
+ <title>Limitations</title>
+
+ <para>
+ The following limitations apply to partitioned tables:
+ <itemizedlist>
+ <listitem>
+ <para>
+ To create a unique or primary key constraint on a partitioned table,
+ the partition keys must not include any expressions or function calls
+ and the constraint's columns must include all of the partition key
+ columns. This limitation exists because the individual indexes making
+ up the constraint can only directly enforce uniqueness within their own
+ partitions; therefore, the partition structure itself must guarantee
+ that there are not duplicates in different partitions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ There is no way to create an exclusion constraint spanning the
+ whole partitioned table. It is only possible to put such a
+ constraint on each leaf partition individually. Again, this
+ limitation stems from not being able to enforce cross-partition
+ restrictions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>BEFORE ROW</literal> triggers on <literal>INSERT</literal>
+ cannot change which partition is the final destination for a new row.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Mixing temporary and permanent relations in the same partition tree is
+ not allowed. Hence, if the partitioned table is permanent, so must be
+ its partitions and likewise if the partitioned table is temporary. When
+ using temporary relations, all members of the partition tree have to be
+ from the same session.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Individual partitions are linked to their partitioned table using
+ inheritance behind-the-scenes. However, it is not possible to use
+ all of the generic features of inheritance with declaratively
+ partitioned tables or their partitions, as discussed below. Notably,
+ a partition cannot have any parents other than the partitioned table
+ it is a partition of, nor can a table inherit from both a partitioned
+ table and a regular table. That means partitioned tables and their
+ partitions never share an inheritance hierarchy with regular tables.
+ </para>
+
+ <para>
+ Since a partition hierarchy consisting of the partitioned table and its
+ partitions is still an inheritance hierarchy,
+ <structfield>tableoid</structfield> and all the normal rules of
+ inheritance apply as described in <xref linkend="ddl-inherit"/>, with
+ a few exceptions:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Partitions cannot have columns that are not present in the parent. It
+ is not possible to specify columns when creating partitions with
+ <command>CREATE TABLE</command>, nor is it possible to add columns to
+ partitions after-the-fact using <command>ALTER TABLE</command>.
+ Tables may be added as a partition with <command>ALTER TABLE
+ ... ATTACH PARTITION</command> only if their columns exactly match
+ the parent.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Both <literal>CHECK</literal> and <literal>NOT NULL</literal>
+ constraints of a partitioned table are always inherited by all its
+ partitions. <literal>CHECK</literal> constraints that are marked
+ <literal>NO INHERIT</literal> are not allowed to be created on
+ partitioned tables.
+ You cannot drop a <literal>NOT NULL</literal> constraint on a
+ partition's column if the same constraint is present in the parent
+ table.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using <literal>ONLY</literal> to add or drop a constraint on only
+ the partitioned table is supported as long as there are no
+ partitions. Once partitions exist, using <literal>ONLY</literal>
+ will result in an error. Instead, constraints on the partitions
+ themselves can be added and (if they are not present in the parent
+ table) dropped.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ As a partitioned table does not have any data itself, attempts to use
+ <command>TRUNCATE</command> <literal>ONLY</literal> on a partitioned
+ table will always return an error.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="ddl-partitioning-using-inheritance">
+ <title>Partitioning Using Inheritance</title>
+
+ <para>
+ While the built-in declarative partitioning is suitable for most
+ common use cases, there are some circumstances where a more flexible
+ approach may be useful. Partitioning can be implemented using table
+ inheritance, which allows for several features not supported
+ by declarative partitioning, such as:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ For declarative partitioning, partitions must have exactly the same set
+ of columns as the partitioned table, whereas with table inheritance,
+ child tables may have extra columns not present in the parent.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Table inheritance allows for multiple inheritance.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Declarative partitioning only supports range, list and hash
+ partitioning, whereas table inheritance allows data to be divided in a
+ manner of the user's choosing. (Note, however, that if constraint
+ exclusion is unable to prune child tables effectively, query performance
+ might be poor.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect3 id="ddl-partitioning-inheritance-example">
+ <title>Example</title>
+
+ <para>
+ This example builds a partitioning structure equivalent to the
+ declarative partitioning example above. Use
+ the following steps:
+
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Create the <quote>root</quote> table, from which all of the
+ <quote>child</quote> tables will inherit. This table will contain no data. Do not
+ define any check constraints on this table, unless you intend them
+ to be applied equally to all child tables. There is no point in
+ defining any indexes or unique constraints on it, either. For our
+ example, the root table is the <structname>measurement</structname>
+ table as originally defined:
+
+<programlisting>
+CREATE TABLE measurement (
+ city_id int not null,
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Create several <quote>child</quote> tables that each inherit from
+ the root table. Normally, these tables will not add any columns
+ to the set inherited from the root. Just as with declarative
+ partitioning, these tables are in every way normal
+ <productname>PostgreSQL</productname> tables (or foreign tables).
+ </para>
+
+ <para>
+<programlisting>
+CREATE TABLE measurement_y2006m02 () INHERITS (measurement);
+CREATE TABLE measurement_y2006m03 () INHERITS (measurement);
+...
+CREATE TABLE measurement_y2007m11 () INHERITS (measurement);
+CREATE TABLE measurement_y2007m12 () INHERITS (measurement);
+CREATE TABLE measurement_y2008m01 () INHERITS (measurement);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Add non-overlapping table constraints to the child tables to
+ define the allowed key values in each.
+ </para>
+
+ <para>
+ Typical examples would be:
+<programlisting>
+CHECK ( x = 1 )
+CHECK ( county IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' ))
+CHECK ( outletID &gt;= 100 AND outletID &lt; 200 )
+</programlisting>
+ Ensure that the constraints guarantee that there is no overlap
+ between the key values permitted in different child tables. A common
+ mistake is to set up range constraints like:
+<programlisting>
+CHECK ( outletID BETWEEN 100 AND 200 )
+CHECK ( outletID BETWEEN 200 AND 300 )
+</programlisting>
+ This is wrong since it is not clear which child table the key
+ value 200 belongs in.
+ Instead, ranges should be defined in this style:
+
+<programlisting>
+CREATE TABLE measurement_y2006m02 (
+ CHECK ( logdate &gt;= DATE '2006-02-01' AND logdate &lt; DATE '2006-03-01' )
+) INHERITS (measurement);
+
+CREATE TABLE measurement_y2006m03 (
+ CHECK ( logdate &gt;= DATE '2006-03-01' AND logdate &lt; DATE '2006-04-01' )
+) INHERITS (measurement);
+
+...
+CREATE TABLE measurement_y2007m11 (
+ CHECK ( logdate &gt;= DATE '2007-11-01' AND logdate &lt; DATE '2007-12-01' )
+) INHERITS (measurement);
+
+CREATE TABLE measurement_y2007m12 (
+ CHECK ( logdate &gt;= DATE '2007-12-01' AND logdate &lt; DATE '2008-01-01' )
+) INHERITS (measurement);
+
+CREATE TABLE measurement_y2008m01 (
+ CHECK ( logdate &gt;= DATE '2008-01-01' AND logdate &lt; DATE '2008-02-01' )
+) INHERITS (measurement);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For each child table, create an index on the key column(s),
+ as well as any other indexes you might want.
+<programlisting>
+CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate);
+CREATE INDEX measurement_y2006m03_logdate ON measurement_y2006m03 (logdate);
+CREATE INDEX measurement_y2007m11_logdate ON measurement_y2007m11 (logdate);
+CREATE INDEX measurement_y2007m12_logdate ON measurement_y2007m12 (logdate);
+CREATE INDEX measurement_y2008m01_logdate ON measurement_y2008m01 (logdate);
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ We want our application to be able to say <literal>INSERT INTO
+ measurement ...</literal> and have the data be redirected into the
+ appropriate child table. We can arrange that by attaching
+ a suitable trigger function to the root table.
+ If data will be added only to the latest child, we can
+ use a very simple trigger function:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION measurement_insert_trigger()
+RETURNS TRIGGER AS $$
+BEGIN
+ INSERT INTO measurement_y2008m01 VALUES (NEW.*);
+ RETURN NULL;
+END;
+$$
+LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ After creating the function, we create a trigger which
+ calls the trigger function:
+
+<programlisting>
+CREATE TRIGGER insert_measurement_trigger
+ BEFORE INSERT ON measurement
+ FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger();
+</programlisting>
+
+ We must redefine the trigger function each month so that it always
+ inserts into the current child table. The trigger definition does
+ not need to be updated, however.
+ </para>
+
+ <para>
+ We might want to insert data and have the server automatically
+ locate the child table into which the row should be added. We
+ could do this with a more complex trigger function, for example:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION measurement_insert_trigger()
+RETURNS TRIGGER AS $$
+BEGIN
+ IF ( NEW.logdate &gt;= DATE '2006-02-01' AND
+ NEW.logdate &lt; DATE '2006-03-01' ) THEN
+ INSERT INTO measurement_y2006m02 VALUES (NEW.*);
+ ELSIF ( NEW.logdate &gt;= DATE '2006-03-01' AND
+ NEW.logdate &lt; DATE '2006-04-01' ) THEN
+ INSERT INTO measurement_y2006m03 VALUES (NEW.*);
+ ...
+ ELSIF ( NEW.logdate &gt;= DATE '2008-01-01' AND
+ NEW.logdate &lt; DATE '2008-02-01' ) THEN
+ INSERT INTO measurement_y2008m01 VALUES (NEW.*);
+ ELSE
+ RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!';
+ END IF;
+ RETURN NULL;
+END;
+$$
+LANGUAGE plpgsql;
+</programlisting>
+
+ The trigger definition is the same as before.
+ Note that each <literal>IF</literal> test must exactly match the
+ <literal>CHECK</literal> constraint for its child table.
+ </para>
+
+ <para>
+ While this function is more complex than the single-month case,
+ it doesn't need to be updated as often, since branches can be
+ added in advance of being needed.
+ </para>
+
+ <note>
+ <para>
+ In practice, it might be best to check the newest child first,
+ if most inserts go into that child. For simplicity, we have
+ shown the trigger's tests in the same order as in other parts
+ of this example.
+ </para>
+ </note>
+
+ <para>
+ A different approach to redirecting inserts into the appropriate
+ child table is to set up rules, instead of a trigger, on the
+ root table. For example:
+
+<programlisting>
+CREATE RULE measurement_insert_y2006m02 AS
+ON INSERT TO measurement WHERE
+ ( logdate &gt;= DATE '2006-02-01' AND logdate &lt; DATE '2006-03-01' )
+DO INSTEAD
+ INSERT INTO measurement_y2006m02 VALUES (NEW.*);
+...
+CREATE RULE measurement_insert_y2008m01 AS
+ON INSERT TO measurement WHERE
+ ( logdate &gt;= DATE '2008-01-01' AND logdate &lt; DATE '2008-02-01' )
+DO INSTEAD
+ INSERT INTO measurement_y2008m01 VALUES (NEW.*);
+</programlisting>
+
+ A rule has significantly more overhead than a trigger, but the
+ overhead is paid once per query rather than once per row, so this
+ method might be advantageous for bulk-insert situations. In most
+ cases, however, the trigger method will offer better performance.
+ </para>
+
+ <para>
+ Be aware that <command>COPY</command> ignores rules. If you want to
+ use <command>COPY</command> to insert data, you'll need to copy into the
+ correct child table rather than directly into the root. <command>COPY</command>
+ does fire triggers, so you can use it normally if you use the trigger
+ approach.
+ </para>
+
+ <para>
+ Another disadvantage of the rule approach is that there is no simple
+ way to force an error if the set of rules doesn't cover the insertion
+ date; the data will silently go into the root table instead.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Ensure that the <xref linkend="guc-constraint-exclusion"/>
+ configuration parameter is not disabled in
+ <filename>postgresql.conf</filename>; otherwise
+ child tables may be accessed unnecessarily.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ As we can see, a complex table hierarchy could require a
+ substantial amount of DDL. In the above example we would be creating
+ a new child table each month, so it might be wise to write a script that
+ generates the required DDL automatically.
+ </para>
+ </sect3>
+
+ <sect3 id="ddl-partitioning-inheritance-maintenance">
+ <title>Maintenance for Inheritance Partitioning</title>
+ <para>
+ To remove old data quickly, simply drop the child table that is no longer
+ necessary:
+<programlisting>
+DROP TABLE measurement_y2006m02;
+</programlisting>
+ </para>
+
+ <para>
+ To remove the child table from the inheritance hierarchy table but retain access to
+ it as a table in its own right:
+
+<programlisting>
+ALTER TABLE measurement_y2006m02 NO INHERIT measurement;
+</programlisting>
+ </para>
+
+ <para>
+ To add a new child table to handle new data, create an empty child table
+ just as the original children were created above:
+
+<programlisting>
+CREATE TABLE measurement_y2008m02 (
+ CHECK ( logdate &gt;= DATE '2008-02-01' AND logdate &lt; DATE '2008-03-01' )
+) INHERITS (measurement);
+</programlisting>
+
+ Alternatively, one may want to create and populate the new child table
+ before adding it to the table hierarchy. This could allow data to be
+ loaded, checked, and transformed before being made visible to queries on
+ the parent table.
+
+<programlisting>
+CREATE TABLE measurement_y2008m02
+ (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
+ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02
+ CHECK ( logdate &gt;= DATE '2008-02-01' AND logdate &lt; DATE '2008-03-01' );
+\copy measurement_y2008m02 from 'measurement_y2008m02'
+-- possibly some other data preparation work
+ALTER TABLE measurement_y2008m02 INHERIT measurement;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="ddl-partitioning-inheritance-caveats">
+ <title>Caveats</title>
+
+ <para>
+ The following caveats apply to partitioning implemented using
+ inheritance:
+ <itemizedlist>
+ <listitem>
+ <para>
+ There is no automatic way to verify that all of the
+ <literal>CHECK</literal> constraints are mutually
+ exclusive. It is safer to create code that generates
+ child tables and creates and/or modifies associated objects than
+ to write each by hand.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Indexes and foreign key constraints apply to single tables and not
+ to their inheritance children, hence they have some
+ <link linkend="ddl-inherit-caveats">caveats</link> to be aware of.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The schemes shown here assume that the values of a row's key column(s)
+ never change, or at least do not change enough to require it to move to another partition.
+ An <command>UPDATE</command> that attempts
+ to do that will fail because of the <literal>CHECK</literal> constraints.
+ If you need to handle such cases, you can put suitable update triggers
+ on the child tables, but it makes management of the structure
+ much more complicated.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you are using manual <command>VACUUM</command> or
+ <command>ANALYZE</command> commands, don't forget that
+ you need to run them on each child table individually. A command like:
+<programlisting>
+ANALYZE measurement;
+</programlisting>
+ will only process the root table.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <command>INSERT</command> statements with <literal>ON CONFLICT</literal>
+ clauses are unlikely to work as expected, as the <literal>ON CONFLICT</literal>
+ action is only taken in case of unique violations on the specified
+ target relation, not its child relations.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Triggers or rules will be needed to route rows to the desired
+ child table, unless the application is explicitly aware of the
+ partitioning scheme. Triggers may be complicated to write, and will
+ be much slower than the tuple routing performed internally by
+ declarative partitioning.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="ddl-partition-pruning">
+ <title>Partition Pruning</title>
+
+ <indexterm>
+ <primary>partition pruning</primary>
+ </indexterm>
+
+ <para>
+ <firstterm>Partition pruning</firstterm> is a query optimization technique
+ that improves performance for declaratively partitioned tables.
+ As an example:
+
+<programlisting>
+SET enable_partition_pruning = on; -- the default
+SELECT count(*) FROM measurement WHERE logdate &gt;= DATE '2008-01-01';
+</programlisting>
+
+ Without partition pruning, the above query would scan each of the
+ partitions of the <structname>measurement</structname> table. With
+ partition pruning enabled, the planner will examine the definition
+ of each partition and prove that the partition need not
+ be scanned because it could not contain any rows meeting the query's
+ <literal>WHERE</literal> clause. When the planner can prove this, it
+ excludes (<firstterm>prunes</firstterm>) the partition from the query
+ plan.
+ </para>
+
+ <para>
+ By using the EXPLAIN command and the <xref
+ linkend="guc-enable-partition-pruning"/> configuration parameter, it's
+ possible to show the difference between a plan for which partitions have
+ been pruned and one for which they have not. A typical unoptimized
+ plan for this type of table setup is:
+<programlisting>
+SET enable_partition_pruning = off;
+EXPLAIN SELECT count(*) FROM measurement WHERE logdate &gt;= DATE '2008-01-01';
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;----------------
+ Aggregate (cost=188.76..188.77 rows=1 width=8)
+ -&gt; Append (cost=0.00..181.05 rows=3085 width=0)
+ -&gt; Seq Scan on measurement_y2006m02 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+ -&gt; Seq Scan on measurement_y2006m03 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+...
+ -&gt; Seq Scan on measurement_y2007m11 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+ -&gt; Seq Scan on measurement_y2007m12 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+ -&gt; Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+</programlisting>
+
+ Some or all of the partitions might use index scans instead of
+ full-table sequential scans, but the point here is that there
+ is no need to scan the older partitions at all to answer this query.
+ When we enable partition pruning, we get a significantly
+ cheaper plan that will deliver the same answer:
+<programlisting>
+SET enable_partition_pruning = on;
+EXPLAIN SELECT count(*) FROM measurement WHERE logdate &gt;= DATE '2008-01-01';
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;----------------
+ Aggregate (cost=37.75..37.76 rows=1 width=8)
+ -&gt; Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+</programlisting>
+ </para>
+
+ <para>
+ Note that partition pruning is driven only by the constraints defined
+ implicitly by the partition keys, not by the presence of indexes.
+ Therefore it isn't necessary to define indexes on the key columns.
+ Whether an index needs to be created for a given partition depends on
+ whether you expect that queries that scan the partition will
+ generally scan a large part of the partition or just a small part.
+ An index will be helpful in the latter case but not the former.
+ </para>
+
+ <para>
+ Partition pruning can be performed not only during the planning of a
+ given query, but also during its execution. This is useful as it can
+ allow more partitions to be pruned when clauses contain expressions
+ whose values are not known at query planning time, for example,
+ parameters defined in a <command>PREPARE</command> statement, using a
+ value obtained from a subquery, or using a parameterized value on the
+ inner side of a nested loop join. Partition pruning during execution
+ can be performed at any of the following times:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ During initialization of the query plan. Partition pruning can be
+ performed here for parameter values which are known during the
+ initialization phase of execution. Partitions which are pruned
+ during this stage will not show up in the query's
+ <command>EXPLAIN</command> or <command>EXPLAIN ANALYZE</command>.
+ It is possible to determine the number of partitions which were
+ removed during this phase by observing the
+ <quote>Subplans Removed</quote> property in the
+ <command>EXPLAIN</command> output.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ During actual execution of the query plan. Partition pruning may
+ also be performed here to remove partitions using values which are
+ only known during actual query execution. This includes values
+ from subqueries and values from execution-time parameters such as
+ those from parameterized nested loop joins. Since the value of
+ these parameters may change many times during the execution of the
+ query, partition pruning is performed whenever one of the
+ execution parameters being used by partition pruning changes.
+ Determining if partitions were pruned during this phase requires
+ careful inspection of the <literal>loops</literal> property in
+ the <command>EXPLAIN ANALYZE</command> output. Subplans
+ corresponding to different partitions may have different values
+ for it depending on how many times each of them was pruned during
+ execution. Some may be shown as <literal>(never executed)</literal>
+ if they were pruned every time.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Partition pruning can be disabled using the
+ <xref linkend="guc-enable-partition-pruning"/> setting.
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-partitioning-constraint-exclusion">
+ <title>Partitioning and Constraint Exclusion</title>
+
+ <indexterm>
+ <primary>constraint exclusion</primary>
+ </indexterm>
+
+ <para>
+ <firstterm>Constraint exclusion</firstterm> is a query optimization
+ technique similar to partition pruning. While it is primarily used
+ for partitioning implemented using the legacy inheritance method, it can be
+ used for other purposes, including with declarative partitioning.
+ </para>
+
+ <para>
+ Constraint exclusion works in a very similar way to partition
+ pruning, except that it uses each table's <literal>CHECK</literal>
+ constraints &mdash; which gives it its name &mdash; whereas partition
+ pruning uses the table's partition bounds, which exist only in the
+ case of declarative partitioning. Another difference is that
+ constraint exclusion is only applied at plan time; there is no attempt
+ to remove partitions at execution time.
+ </para>
+
+ <para>
+ The fact that constraint exclusion uses <literal>CHECK</literal>
+ constraints, which makes it slow compared to partition pruning, can
+ sometimes be used as an advantage: because constraints can be defined
+ even on declaratively-partitioned tables, in addition to their internal
+ partition bounds, constraint exclusion may be able
+ to elide additional partitions from the query plan.
+ </para>
+
+ <para>
+ The default (and recommended) setting of
+ <xref linkend="guc-constraint-exclusion"/> is neither
+ <literal>on</literal> nor <literal>off</literal>, but an intermediate setting
+ called <literal>partition</literal>, which causes the technique to be
+ applied only to queries that are likely to be working on inheritance partitioned
+ tables. The <literal>on</literal> setting causes the planner to examine
+ <literal>CHECK</literal> constraints in all queries, even simple ones that
+ are unlikely to benefit.
+ </para>
+
+ <para>
+ The following caveats apply to constraint exclusion:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Constraint exclusion is only applied during query planning, unlike
+ partition pruning, which can also be applied during query execution.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Constraint exclusion only works when the query's <literal>WHERE</literal>
+ clause contains constants (or externally supplied parameters).
+ For example, a comparison against a non-immutable function such as
+ <function>CURRENT_TIMESTAMP</function> cannot be optimized, since the
+ planner cannot know which child table the function's value might fall
+ into at run time.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Keep the partitioning constraints simple, else the planner may not be
+ able to prove that child tables might not need to be visited. Use simple
+ equality conditions for list partitioning, or simple
+ range tests for range partitioning, as illustrated in the preceding
+ examples. A good rule of thumb is that partitioning constraints should
+ contain only comparisons of the partitioning column(s) to constants
+ using B-tree-indexable operators, because only B-tree-indexable
+ column(s) are allowed in the partition key.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All constraints on all children of the parent table are examined
+ during constraint exclusion, so large numbers of children are likely
+ to increase query planning time considerably. So the legacy
+ inheritance based partitioning will work well with up to perhaps a
+ hundred child tables; don't try to use many thousands of children.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2 id="ddl-partitioning-declarative-best-practices">
+ <title>Best Practices for Declarative Partitioning</title>
+
+ <para>
+ The choice of how to partition a table should be made carefully, as the
+ performance of query planning and execution can be negatively affected by
+ poor design.
+ </para>
+
+ <para>
+ One of the most critical design decisions will be the column or columns
+ by which you partition your data. Often the best choice will be to
+ partition by the column or set of columns which most commonly appear in
+ <literal>WHERE</literal> clauses of queries being executed on the
+ partitioned table. <literal>WHERE</literal> clauses that are compatible
+ with the partition bound constraints can be used to prune unneeded
+ partitions. However, you may be forced into making other decisions by
+ requirements for the <literal>PRIMARY KEY</literal> or a
+ <literal>UNIQUE</literal> constraint. Removal of unwanted data is also a
+ factor to consider when planning your partitioning strategy. An entire
+ partition can be detached fairly quickly, so it may be beneficial to
+ design the partition strategy in such a way that all data to be removed
+ at once is located in a single partition.
+ </para>
+
+ <para>
+ Choosing the target number of partitions that the table should be divided
+ into is also a critical decision to make. Not having enough partitions
+ may mean that indexes remain too large and that data locality remains poor
+ which could result in low cache hit ratios. However, dividing the table
+ into too many partitions can also cause issues. Too many partitions can
+ mean longer query planning times and higher memory consumption during both
+ query planning and execution, as further described below.
+ When choosing how to partition your table,
+ it's also important to consider what changes may occur in the future. For
+ example, if you choose to have one partition per customer and you
+ currently have a small number of large customers, consider the
+ implications if in several years you instead find yourself with a large
+ number of small customers. In this case, it may be better to choose to
+ partition by <literal>HASH</literal> and choose a reasonable number of
+ partitions rather than trying to partition by <literal>LIST</literal> and
+ hoping that the number of customers does not increase beyond what it is
+ practical to partition the data by.
+ </para>
+
+ <para>
+ Sub-partitioning can be useful to further divide partitions that are
+ expected to become larger than other partitions.
+ Another option is to use range partitioning with multiple columns in
+ the partition key.
+ Either of these can easily lead to excessive numbers of partitions,
+ so restraint is advisable.
+ </para>
+
+ <para>
+ It is important to consider the overhead of partitioning during
+ query planning and execution. The query planner is generally able to
+ handle partition hierarchies with up to a few thousand partitions fairly
+ well, provided that typical queries allow the query planner to prune all
+ but a small number of partitions. Planning times become longer and memory
+ consumption becomes higher when more partitions remain after the planner
+ performs partition pruning. Another
+ reason to be concerned about having a large number of partitions is that
+ the server's memory consumption may grow significantly over
+ time, especially if many sessions touch large numbers of partitions.
+ That's because each partition requires its metadata to be loaded into the
+ local memory of each session that touches it.
+ </para>
+
+ <para>
+ With data warehouse type workloads, it can make sense to use a larger
+ number of partitions than with an <acronym>OLTP</acronym> type workload.
+ Generally, in data warehouses, query planning time is less of a concern as
+ the majority of processing time is spent during query execution. With
+ either of these two types of workload, it is important to make the right
+ decisions early, as re-partitioning large quantities of data can be
+ painfully slow. Simulations of the intended workload are often beneficial
+ for optimizing the partitioning strategy. Never just assume that more
+ partitions are better than fewer partitions, nor vice-versa.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="ddl-foreign-data">
+ <title>Foreign Data</title>
+
+ <indexterm>
+ <primary>foreign data</primary>
+ </indexterm>
+ <indexterm>
+ <primary>foreign table</primary>
+ </indexterm>
+ <indexterm>
+ <primary>user mapping</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> implements portions of the SQL/MED
+ specification, allowing you to access data that resides outside
+ PostgreSQL using regular SQL queries. Such data is referred to as
+ <firstterm>foreign data</firstterm>. (Note that this usage is not to be confused
+ with foreign keys, which are a type of constraint within the database.)
+ </para>
+
+ <para>
+ Foreign data is accessed with help from a
+ <firstterm>foreign data wrapper</firstterm>. A foreign data wrapper is a
+ library that can communicate with an external data source, hiding the
+ details of connecting to the data source and obtaining data from it.
+ There are some foreign data wrappers available as <filename>contrib</filename>
+ modules; see <xref linkend="contrib"/>. Other kinds of foreign data
+ wrappers might be found as third party products. If none of the existing
+ foreign data wrappers suit your needs, you can write your own; see <xref
+ linkend="fdwhandler"/>.
+ </para>
+
+ <para>
+ To access foreign data, you need to create a <firstterm>foreign server</firstterm>
+ object, which defines how to connect to a particular external data source
+ according to the set of options used by its supporting foreign data
+ wrapper. Then you need to create one or more <firstterm>foreign
+ tables</firstterm>, which define the structure of the remote data. A
+ foreign table can be used in queries just like a normal table, but a
+ foreign table has no storage in the PostgreSQL server. Whenever it is
+ used, <productname>PostgreSQL</productname> asks the foreign data wrapper
+ to fetch data from the external source, or transmit data to the external
+ source in the case of update commands.
+ </para>
+
+ <para>
+ Accessing remote data may require authenticating to the external
+ data source. This information can be provided by a
+ <firstterm>user mapping</firstterm>, which can provide additional data
+ such as user names and passwords based
+ on the current <productname>PostgreSQL</productname> role.
+ </para>
+
+ <para>
+ For additional information, see
+ <xref linkend="sql-createforeigndatawrapper"/>,
+ <xref linkend="sql-createserver"/>,
+ <xref linkend="sql-createusermapping"/>,
+ <xref linkend="sql-createforeigntable"/>, and
+ <xref linkend="sql-importforeignschema"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-others">
+ <title>Other Database Objects</title>
+
+ <para>
+ Tables are the central objects in a relational database structure,
+ because they hold your data. But they are not the only objects
+ that exist in a database. Many other kinds of objects can be
+ created to make the use and management of the data more efficient
+ or convenient. They are not discussed in this chapter, but we give
+ you a list here so that you are aware of what is possible:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Views
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Functions, procedures, and operators
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Data types and domains
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Triggers and rewrite rules
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Detailed information on
+ these topics appears in <xref linkend="server-programming"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="ddl-depend">
+ <title>Dependency Tracking</title>
+
+ <indexterm zone="ddl-depend">
+ <primary>CASCADE</primary>
+ <secondary sortas="DROP">with DROP</secondary>
+ </indexterm>
+
+ <indexterm zone="ddl-depend">
+ <primary>RESTRICT</primary>
+ <secondary sortas="DROP">with DROP</secondary>
+ </indexterm>
+
+ <para>
+ When you create complex database structures involving many tables
+ with foreign key constraints, views, triggers, functions, etc. you
+ implicitly create a net of dependencies between the objects.
+ For instance, a table with a foreign key constraint depends on the
+ table it references.
+ </para>
+
+ <para>
+ To ensure the integrity of the entire database structure,
+ <productname>PostgreSQL</productname> makes sure that you cannot
+ drop objects that other objects still depend on. For example,
+ attempting to drop the products table we considered in <xref
+ linkend="ddl-constraints-fk"/>, with the orders table depending on
+ it, would result in an error message like this:
+<screen>
+DROP TABLE products;
+
+ERROR: cannot drop table products because other objects depend on it
+DETAIL: constraint orders_product_no_fkey on table orders depends on table products
+HINT: Use DROP ... CASCADE to drop the dependent objects too.
+</screen>
+ The error message contains a useful hint: if you do not want to
+ bother deleting all the dependent objects individually, you can run:
+<screen>
+DROP TABLE products CASCADE;
+</screen>
+ and all the dependent objects will be removed, as will any objects
+ that depend on them, recursively. In this case, it doesn't remove
+ the orders table, it only removes the foreign key constraint.
+ It stops there because nothing depends on the foreign key constraint.
+ (If you want to check what <command>DROP ... CASCADE</command> will do,
+ run <command>DROP</command> without <literal>CASCADE</literal> and read the
+ <literal>DETAIL</literal> output.)
+ </para>
+
+ <para>
+ Almost all <command>DROP</command> commands in <productname>PostgreSQL</productname> support
+ specifying <literal>CASCADE</literal>. Of course, the nature of
+ the possible dependencies varies with the type of the object. You
+ can also write <literal>RESTRICT</literal> instead of
+ <literal>CASCADE</literal> to get the default behavior, which is to
+ prevent dropping objects that any other objects depend on.
+ </para>
+
+ <note>
+ <para>
+ According to the SQL standard, specifying either
+ <literal>RESTRICT</literal> or <literal>CASCADE</literal> is
+ required in a <command>DROP</command> command. No database system actually
+ enforces that rule, but whether the default behavior
+ is <literal>RESTRICT</literal> or <literal>CASCADE</literal> varies
+ across systems.
+ </para>
+ </note>
+
+ <para>
+ If a <command>DROP</command> command lists multiple
+ objects, <literal>CASCADE</literal> is only required when there are
+ dependencies outside the specified group. For example, when saying
+ <literal>DROP TABLE tab1, tab2</literal> the existence of a foreign
+ key referencing <literal>tab1</literal> from <literal>tab2</literal> would not mean
+ that <literal>CASCADE</literal> is needed to succeed.
+ </para>
+
+ <para>
+ For a user-defined function or procedure whose body is defined as a string
+ literal, <productname>PostgreSQL</productname> tracks
+ dependencies associated with the function's externally-visible properties,
+ such as its argument and result types, but <emphasis>not</emphasis> dependencies
+ that could only be known by examining the function body. As an example,
+ consider this situation:
+
+<programlisting>
+CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow',
+ 'green', 'blue', 'purple');
+
+CREATE TABLE my_colors (color rainbow, note text);
+
+CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
+ 'SELECT note FROM my_colors WHERE color = $1'
+ LANGUAGE SQL;
+</programlisting>
+
+ (See <xref linkend="xfunc-sql"/> for an explanation of SQL-language
+ functions.) <productname>PostgreSQL</productname> will be aware that
+ the <function>get_color_note</function> function depends on the <type>rainbow</type>
+ type: dropping the type would force dropping the function, because its
+ argument type would no longer be defined. But <productname>PostgreSQL</productname>
+ will not consider <function>get_color_note</function> to depend on
+ the <structname>my_colors</structname> table, and so will not drop the function if
+ the table is dropped. While there are disadvantages to this approach,
+ there are also benefits. The function is still valid in some sense if the
+ table is missing, though executing it would cause an error; creating a new
+ table of the same name would allow the function to work again.
+ </para>
+
+ <para>
+ On the other hand, for a SQL-language function or procedure whose body
+ is written in SQL-standard style, the body is parsed at function
+ definition time and all dependencies recognized by the parser are
+ stored. Thus, if we write the function above as
+
+<programlisting>
+CREATE FUNCTION get_color_note (rainbow) RETURNS text
+BEGIN ATOMIC
+ SELECT note FROM my_colors WHERE color = $1;
+END;
+</programlisting>
+
+ then the function's dependency on the <structname>my_colors</structname>
+ table will be known and enforced by <command>DROP</command>.
+ </para>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml
new file mode 100644
index 0000000..a635767
--- /dev/null
+++ b/doc/src/sgml/dfunc.sgml
@@ -0,0 +1,252 @@
+<!-- doc/src/sgml/dfunc.sgml -->
+
+<sect2 id="dfunc">
+ <title>Compiling and Linking Dynamically-Loaded Functions</title>
+
+ <para>
+ Before you are able to use your
+ <productname>PostgreSQL</productname> extension functions written in
+ C, they must be compiled and linked in a special way to produce a
+ file that can be dynamically loaded by the server. To be precise, a
+ <firstterm>shared library</firstterm> needs to be
+ created.<indexterm><primary>shared library</primary></indexterm>
+
+ </para>
+
+ <para>
+ For information beyond what is contained in this section
+ you should read the documentation of your
+ operating system, in particular the manual pages for the C compiler,
+ <command>cc</command>, and the link editor, <command>ld</command>.
+ In addition, the <productname>PostgreSQL</productname> source code
+ contains several working examples in the
+ <filename>contrib</filename> directory. If you rely on these
+ examples you will make your modules dependent on the availability
+ of the <productname>PostgreSQL</productname> source code, however.
+ </para>
+
+ <para>
+ Creating shared libraries is generally analogous to linking
+ executables: first the source files are compiled into object files,
+ then the object files are linked together. The object files need to
+ be created as <firstterm>position-independent code</firstterm>
+ (<acronym>PIC</acronym>),<indexterm><primary>PIC</primary></indexterm> which
+ conceptually means that they can be placed at an arbitrary location
+ in memory when they are loaded by the executable. (Object files
+ intended for executables are usually not compiled that way.) The
+ command to link a shared library contains special flags to
+ distinguish it from linking an executable (at least in theory
+ &mdash; on some systems the practice is much uglier).
+ </para>
+
+ <para>
+ In the following examples we assume that your source code is in a
+ file <filename>foo.c</filename> and we will create a shared library
+ <filename>foo.so</filename>. The intermediate object file will be
+ called <filename>foo.o</filename> unless otherwise noted. A shared
+ library can contain more than one object file, but we only use one
+ here.
+ </para>
+
+<!--
+ Note: Reading GNU Libtool sources is generally a good way of
+ figuring out this information. The methods used within PostgreSQL
+ source code are not necessarily ideal.
+-->
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <systemitem class="osname">FreeBSD</systemitem>
+ <indexterm><primary>FreeBSD</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag to create <acronym>PIC</acronym> is
+ <option>-fPIC</option>. To create shared libraries the compiler
+ flag is <option>-shared</option>.
+<programlisting>
+gcc -fPIC -c foo.c
+gcc -shared -o foo.so foo.o
+</programlisting>
+ This is applicable as of version 3.0 of
+ <systemitem class="osname">FreeBSD</systemitem>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">HP-UX</systemitem>
+ <indexterm><primary>HP-UX</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag of the system compiler to create
+ <acronym>PIC</acronym> is <option>+z</option>. When using
+ <application>GCC</application> it's <option>-fPIC</option>. The
+ linker flag for shared libraries is <option>-b</option>. So:
+<programlisting>
+cc +z -c foo.c
+</programlisting>
+ or:
+<programlisting>
+gcc -fPIC -c foo.c
+</programlisting>
+ and then:
+<programlisting>
+ld -b -o foo.sl foo.o
+</programlisting>
+ <systemitem class="osname">HP-UX</systemitem> uses the extension
+ <filename>.sl</filename> for shared libraries, unlike most other
+ systems.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">Linux</systemitem>
+ <indexterm><primary>Linux</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag to create <acronym>PIC</acronym> is
+ <option>-fPIC</option>.
+ The compiler flag to create a shared library is
+ <option>-shared</option>. A complete example looks like this:
+<programlisting>
+cc -fPIC -c foo.c
+cc -shared -o foo.so foo.o
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">macOS</systemitem>
+ <indexterm><primary>macOS</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Here is an example. It assumes the developer tools are installed.
+<programlisting>
+cc -c foo.c
+cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">NetBSD</systemitem>
+ <indexterm><primary>NetBSD</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag to create <acronym>PIC</acronym> is
+ <option>-fPIC</option>. For <acronym>ELF</acronym> systems, the
+ compiler with the flag <option>-shared</option> is used to link
+ shared libraries. On the older non-ELF systems, <literal>ld
+ -Bshareable</literal> is used.
+<programlisting>
+gcc -fPIC -c foo.c
+gcc -shared -o foo.so foo.o
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">OpenBSD</systemitem>
+ <indexterm><primary>OpenBSD</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag to create <acronym>PIC</acronym> is
+ <option>-fPIC</option>. <literal>ld -Bshareable</literal> is
+ used to link shared libraries.
+<programlisting>
+gcc -fPIC -c foo.c
+ld -Bshareable -o foo.so foo.o
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <systemitem class="osname">Solaris</systemitem>
+ <indexterm><primary>Solaris</primary><secondary>shared library</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The compiler flag to create <acronym>PIC</acronym> is
+ <option>-KPIC</option> with the Sun compiler and
+ <option>-fPIC</option> with <application>GCC</application>. To
+ link shared libraries, the compiler option is
+ <option>-G</option> with either compiler or alternatively
+ <option>-shared</option> with <application>GCC</application>.
+<programlisting>
+cc -KPIC -c foo.c
+cc -G -o foo.so foo.o
+</programlisting>
+ or
+<programlisting>
+gcc -fPIC -c foo.c
+gcc -G -o foo.so foo.o
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <tip>
+ <para>
+ If this is too complicated for you, you should consider using
+ <ulink url="https://www.gnu.org/software/libtool/">
+ <productname>GNU Libtool</productname></ulink>,
+ which hides the platform differences behind a uniform interface.
+ </para>
+ </tip>
+
+ <para>
+ The resulting shared library file can then be loaded into
+ <productname>PostgreSQL</productname>. When specifying the file name
+ to the <command>CREATE FUNCTION</command> command, one must give it
+ the name of the shared library file, not the intermediate object file.
+ Note that the system's standard shared-library extension (usually
+ <literal>.so</literal> or <literal>.sl</literal>) can be omitted from
+ the <command>CREATE FUNCTION</command> command, and normally should
+ be omitted for best portability.
+ </para>
+
+ <para>
+ Refer back to <xref linkend="xfunc-c-dynload"/> about where the
+ server expects to find the shared library files.
+ </para>
+
+<!--
+Under AIX, object files are compiled normally but building the shared
+library requires a couple of steps. First, create the object file:
+.nf
+cc <other flags> -c foo.c
+.fi
+You must then create a symbol \*(lqexports\*(rq file for the object
+file:
+.nf
+mkldexport foo.o `pwd` &gt; foo.exp
+.fi
+Finally, you can create the shared library:
+.nf
+ld <other flags> -H512 -T512 -o foo.so -e _nostart \e
+ -bI:.../lib/postgres.exp -bE:foo.exp foo.o \e
+ -lm -lc 2>/dev/null
+.fi
+ -->
+
+</sect2>
diff --git a/doc/src/sgml/dict-int.sgml b/doc/src/sgml/dict-int.sgml
new file mode 100644
index 0000000..8babfdd
--- /dev/null
+++ b/doc/src/sgml/dict-int.sgml
@@ -0,0 +1,100 @@
+<!-- doc/src/sgml/dict-int.sgml -->
+
+<sect1 id="dict-int" xreflabel="dict_int">
+ <title>dict_int</title>
+
+ <indexterm zone="dict-int">
+ <primary>dict_int</primary>
+ </indexterm>
+
+ <para>
+ <filename>dict_int</filename> is an example of an add-on dictionary template
+ for full-text search. The motivation for this example dictionary is to
+ control the indexing of integers (signed and unsigned), allowing such
+ numbers to be indexed while preventing excessive growth in the number of
+ unique words, which greatly affects the performance of searching.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <para>
+ The dictionary accepts three options:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <literal>maxlen</literal> parameter specifies the maximum number of
+ digits allowed in an integer word. The default value is 6.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>rejectlong</literal> parameter specifies whether an overlength
+ integer should be truncated or ignored. If <literal>rejectlong</literal> is
+ <literal>false</literal> (the default), the dictionary returns the first
+ <literal>maxlen</literal> digits of the integer. If <literal>rejectlong</literal> is
+ <literal>true</literal>, the dictionary treats an overlength integer as a stop
+ word, so that it will not be indexed. Note that this also means that
+ such an integer cannot be searched for.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>absval</literal> parameter specifies whether leading
+ <quote><literal>+</literal></quote> or <quote><literal>-</literal></quote>
+ signs should be removed from integer words. The default
+ is <literal>false</literal>. When <literal>true</literal>, the sign is
+ removed before <literal>maxlen</literal> is applied.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Usage</title>
+
+ <para>
+ Installing the <literal>dict_int</literal> extension creates a text search
+ template <literal>intdict_template</literal> and a dictionary <literal>intdict</literal>
+ based on it, with the default parameters. You can alter the
+ parameters, for example
+
+<programlisting>
+mydb# ALTER TEXT SEARCH DICTIONARY intdict (MAXLEN = 4, REJECTLONG = true);
+ALTER TEXT SEARCH DICTIONARY
+</programlisting>
+
+ or create new dictionaries based on the template.
+ </para>
+
+ <para>
+ To test the dictionary, you can try
+
+<programlisting>
+mydb# select ts_lexize('intdict', '12345678');
+ ts_lexize
+-----------
+ {123456}
+</programlisting>
+
+ but real-world usage will involve including it in a text search
+ configuration as described in <xref linkend="textsearch"/>.
+ That might look like this:
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION english
+ ALTER MAPPING FOR int, uint WITH intdict;
+</programlisting>
+
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/dict-xsyn.sgml b/doc/src/sgml/dict-xsyn.sgml
new file mode 100644
index 0000000..256aff7
--- /dev/null
+++ b/doc/src/sgml/dict-xsyn.sgml
@@ -0,0 +1,149 @@
+<!-- doc/src/sgml/dict-xsyn.sgml -->
+
+<sect1 id="dict-xsyn" xreflabel="dict_xsyn">
+ <title>dict_xsyn</title>
+
+ <indexterm zone="dict-xsyn">
+ <primary>dict_xsyn</primary>
+ </indexterm>
+
+ <para>
+ <filename>dict_xsyn</filename> (Extended Synonym Dictionary) is an example of an
+ add-on dictionary template for full-text search. This dictionary type
+ replaces words with groups of their synonyms, and so makes it possible to
+ search for a word using any of its synonyms.
+ </para>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <para>
+ A <literal>dict_xsyn</literal> dictionary accepts the following options:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>matchorig</literal> controls whether the original word is accepted by
+ the dictionary. Default is <literal>true</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>matchsynonyms</literal> controls whether the synonyms are
+ accepted by the dictionary. Default is <literal>false</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>keeporig</literal> controls whether the original word is included in
+ the dictionary's output. Default is <literal>true</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>keepsynonyms</literal> controls whether the synonyms are included in
+ the dictionary's output. Default is <literal>true</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>rules</literal> is the base name of the file containing the list of
+ synonyms. This file must be stored in
+ <filename>$SHAREDIR/tsearch_data/</filename> (where <literal>$SHAREDIR</literal> means
+ the <productname>PostgreSQL</productname> installation's shared-data directory).
+ Its name must end in <literal>.rules</literal> (which is not to be included in
+ the <literal>rules</literal> parameter).
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The rules file has the following format:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Each line represents a group of synonyms for a single word, which is
+ given first on the line. Synonyms are separated by whitespace, thus:
+<programlisting>
+word syn1 syn2 syn3
+</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The sharp (<literal>#</literal>) sign is a comment delimiter. It may appear at
+ any position in a line. The rest of the line will be skipped.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Look at <filename>xsyn_sample.rules</filename>, which is installed in
+ <filename>$SHAREDIR/tsearch_data/</filename>, for an example.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Usage</title>
+
+ <para>
+ Installing the <literal>dict_xsyn</literal> extension creates a text search
+ template <literal>xsyn_template</literal> and a dictionary <literal>xsyn</literal>
+ based on it, with default parameters. You can alter the
+ parameters, for example
+
+<programlisting>
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=false);
+ALTER TEXT SEARCH DICTIONARY
+</programlisting>
+
+ or create new dictionaries based on the template.
+ </para>
+
+ <para>
+ To test the dictionary, you can try
+
+<programlisting>
+mydb=# SELECT ts_lexize('xsyn', 'word');
+ ts_lexize
+-----------------------
+ {syn1,syn2,syn3}
+
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=true);
+ALTER TEXT SEARCH DICTIONARY
+
+mydb=# SELECT ts_lexize('xsyn', 'word');
+ ts_lexize
+-----------------------
+ {word,syn1,syn2,syn3}
+
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=false, MATCHSYNONYMS=true);
+ALTER TEXT SEARCH DICTIONARY
+
+mydb=# SELECT ts_lexize('xsyn', 'syn1');
+ ts_lexize
+-----------------------
+ {syn1,syn2,syn3}
+
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=true, MATCHORIG=false, KEEPSYNONYMS=false);
+ALTER TEXT SEARCH DICTIONARY
+
+mydb=# SELECT ts_lexize('xsyn', 'syn1');
+ ts_lexize
+-----------------------
+ {word}
+</programlisting>
+
+ Real-world usage will involve including it in a text search
+ configuration as described in <xref linkend="textsearch"/>.
+ That might look like this:
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION english
+ ALTER MAPPING FOR word, asciiword WITH xsyn, english_stem;
+</programlisting>
+
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/diskusage.sgml b/doc/src/sgml/diskusage.sgml
new file mode 100644
index 0000000..7546758
--- /dev/null
+++ b/doc/src/sgml/diskusage.sgml
@@ -0,0 +1,144 @@
+<!-- doc/src/sgml/diskusage.sgml -->
+
+<chapter id="diskusage">
+ <title>Monitoring Disk Usage</title>
+
+ <para>
+ This chapter discusses how to monitor the disk usage of a
+ <productname>PostgreSQL</productname> database system.
+ </para>
+
+ <sect1 id="disk-usage">
+ <title>Determining Disk Usage</title>
+
+ <indexterm zone="disk-usage">
+ <primary>disk usage</primary>
+ </indexterm>
+
+ <para>
+ Each table has a primary heap disk file where most of the data is
+ stored. If the table has any columns with potentially-wide values,
+ there also might be a <acronym>TOAST</acronym> file associated with the table,
+ which is used to store values too wide to fit comfortably in the main
+ table (see <xref linkend="storage-toast"/>). There will be one valid index
+ on the <acronym>TOAST</acronym> table, if present. There also might be indexes
+ associated with the base table. Each table and index is stored in a
+ separate disk file &mdash; possibly more than one file, if the file would
+ exceed one gigabyte. Naming conventions for these files are described
+ in <xref linkend="storage-file-layout"/>.
+ </para>
+
+ <para>
+ You can monitor disk space in three ways:
+ using the SQL functions listed in <xref linkend="functions-admin-dbsize"/>,
+ using the <xref linkend="oid2name"/> module, or
+ using manual inspection of the system catalogs.
+ The SQL functions are the easiest to use and are generally recommended.
+ The remainder of this section shows how to do it by inspection of the
+ system catalogs.
+ </para>
+
+ <para>
+ Using <application>psql</application> on a recently vacuumed or analyzed database,
+ you can issue queries to see the disk usage of any table:
+<programlisting>
+SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
+
+ pg_relation_filepath | relpages
+----------------------+----------
+ base/16384/16806 | 60
+(1 row)
+</programlisting>
+ Each page is typically 8 kilobytes. (Remember, <structfield>relpages</structfield>
+ is only updated by <command>VACUUM</command>, <command>ANALYZE</command>, and
+ a few DDL commands such as <command>CREATE INDEX</command>.) The file path name
+ is of interest if you want to examine the table's disk file directly.
+ </para>
+
+ <para>
+ To show the space used by <acronym>TOAST</acronym> tables, use a query
+ like the following:
+<programlisting>
+SELECT relname, relpages
+FROM pg_class,
+ (SELECT reltoastrelid
+ FROM pg_class
+ WHERE relname = 'customer') AS ss
+WHERE oid = ss.reltoastrelid OR
+ oid = (SELECT indexrelid
+ FROM pg_index
+ WHERE indrelid = ss.reltoastrelid)
+ORDER BY relname;
+
+ relname | relpages
+----------------------+----------
+ pg_toast_16806 | 0
+ pg_toast_16806_index | 1
+</programlisting>
+ </para>
+
+ <para>
+ You can easily display index sizes, too:
+<programlisting>
+SELECT c2.relname, c2.relpages
+FROM pg_class c, pg_class c2, pg_index i
+WHERE c.relname = 'customer' AND
+ c.oid = i.indrelid AND
+ c2.oid = i.indexrelid
+ORDER BY c2.relname;
+
+ relname | relpages
+-------------------+----------
+ customer_id_index | 26
+</programlisting>
+ </para>
+
+ <para>
+ It is easy to find your largest tables and indexes using this
+ information:
+<programlisting>
+SELECT relname, relpages
+FROM pg_class
+ORDER BY relpages DESC;
+
+ relname | relpages
+----------------------+----------
+ bigtable | 3290
+ customer | 3144
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="disk-full">
+ <title>Disk Full Failure</title>
+
+ <para>
+ The most important disk monitoring task of a database administrator
+ is to make sure the disk doesn't become full. A filled data disk will
+ not result in data corruption, but it might prevent useful activity
+ from occurring. If the disk holding the WAL files grows full, database
+ server panic and consequent shutdown might occur.
+ </para>
+
+ <para>
+ If you cannot free up additional space on the disk by deleting
+ other things, you can move some of the database files to other file
+ systems by making use of tablespaces. See <xref
+ linkend="manage-ag-tablespaces"/> for more information about that.
+ </para>
+
+ <tip>
+ <para>
+ Some file systems perform badly when they are almost full, so do
+ not wait until the disk is completely full to take action.
+ </para>
+ </tip>
+
+ <para>
+ If your system supports per-user disk quotas, then the database
+ will naturally be subject to whatever quota is placed on the user
+ the server runs as. Exceeding the quota will have the same bad
+ effects as running out of disk space entirely.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/dml.sgml b/doc/src/sgml/dml.sgml
new file mode 100644
index 0000000..cbbc5e2
--- /dev/null
+++ b/doc/src/sgml/dml.sgml
@@ -0,0 +1,350 @@
+<!-- doc/src/sgml/dml.sgml -->
+
+<chapter id="dml">
+ <title>Data Manipulation</title>
+
+ <para>
+ The previous chapter discussed how to create tables and other
+ structures to hold your data. Now it is time to fill the tables
+ with data. This chapter covers how to insert, update, and delete
+ table data. The chapter
+ after this will finally explain how to extract your long-lost data
+ from the database.
+ </para>
+
+ <sect1 id="dml-insert">
+ <title>Inserting Data</title>
+
+ <indexterm zone="dml-insert">
+ <primary>inserting</primary>
+ </indexterm>
+
+ <indexterm zone="dml-insert">
+ <primary>INSERT</primary>
+ </indexterm>
+
+ <para>
+ When a table is created, it contains no data. The first thing to
+ do before a database can be of much use is to insert data. Data is
+ inserted one row at a time. You can also insert more than one row
+ in a single command, but it is not possible to insert something that
+ is not a complete row. Even if you know only some column values, a
+ complete row must be created.
+ </para>
+
+ <para>
+ To create a new row, use the <xref linkend="sql-insert"/>
+ command. The command requires the
+ table name and column values. For
+ example, consider the products table from <xref linkend="ddl"/>:
+<programlisting>
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric
+);
+</programlisting>
+ An example command to insert a row would be:
+<programlisting>
+INSERT INTO products VALUES (1, 'Cheese', 9.99);
+</programlisting>
+ The data values are listed in the order in which the columns appear
+ in the table, separated by commas. Usually, the data values will
+ be literals (constants), but scalar expressions are also allowed.
+ </para>
+
+ <para>
+ The above syntax has the drawback that you need to know the order
+ of the columns in the table. To avoid this you can also list the
+ columns explicitly. For example, both of the following commands
+ have the same effect as the one above:
+<programlisting>
+INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99);
+INSERT INTO products (name, price, product_no) VALUES ('Cheese', 9.99, 1);
+</programlisting>
+ Many users consider it good practice to always list the column
+ names.
+ </para>
+
+ <para>
+ If you don't have values for all the columns, you can omit some of
+ them. In that case, the columns will be filled with their default
+ values. For example:
+<programlisting>
+INSERT INTO products (product_no, name) VALUES (1, 'Cheese');
+INSERT INTO products VALUES (1, 'Cheese');
+</programlisting>
+ The second form is a <productname>PostgreSQL</productname>
+ extension. It fills the columns from the left with as many values
+ as are given, and the rest will be defaulted.
+ </para>
+
+ <para>
+ For clarity, you can also request default values explicitly, for
+ individual columns or for the entire row:
+<programlisting>
+INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', DEFAULT);
+INSERT INTO products DEFAULT VALUES;
+</programlisting>
+ </para>
+
+ <para>
+ You can insert multiple rows in a single command:
+<programlisting>
+INSERT INTO products (product_no, name, price) VALUES
+ (1, 'Cheese', 9.99),
+ (2, 'Bread', 1.99),
+ (3, 'Milk', 2.99);
+</programlisting>
+ </para>
+
+ <para>
+ It is also possible to insert the result of a query (which might be no
+ rows, one row, or many rows):
+<programlisting>
+INSERT INTO products (product_no, name, price)
+ SELECT product_no, name, price FROM new_products
+ WHERE release_date = 'today';
+</programlisting>
+ This provides the full power of the SQL query mechanism (<xref
+ linkend="queries"/>) for computing the rows to be inserted.
+ </para>
+
+ <tip>
+ <para>
+ When inserting a lot of data at the same time, consider using
+ the <xref linkend="sql-copy"/> command.
+ It is not as flexible as the <xref linkend="sql-insert"/>
+ command, but is more efficient. Refer
+ to <xref linkend="populate"/> for more information on improving
+ bulk loading performance.
+ </para>
+ </tip>
+ </sect1>
+
+ <sect1 id="dml-update">
+ <title>Updating Data</title>
+
+ <indexterm zone="dml-update">
+ <primary>updating</primary>
+ </indexterm>
+
+ <indexterm zone="dml-update">
+ <primary>UPDATE</primary>
+ </indexterm>
+
+ <para>
+ The modification of data that is already in the database is
+ referred to as updating. You can update individual rows, all the
+ rows in a table, or a subset of all rows. Each column can be
+ updated separately; the other columns are not affected.
+ </para>
+
+ <para>
+ To update existing rows, use the <xref linkend="sql-update"/>
+ command. This requires
+ three pieces of information:
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>The name of the table and column to update</para>
+ </listitem>
+
+ <listitem>
+ <para>The new value of the column</para>
+ </listitem>
+
+ <listitem>
+ <para>Which row(s) to update</para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ Recall from <xref linkend="ddl"/> that SQL does not, in general,
+ provide a unique identifier for rows. Therefore it is not
+ always possible to directly specify which row to update.
+ Instead, you specify which conditions a row must meet in order to
+ be updated. Only if you have a primary key in the table (independent of
+ whether you declared it or not) can you reliably address individual rows
+ by choosing a condition that matches the primary key.
+ Graphical database access tools rely on this fact to allow you to
+ update rows individually.
+ </para>
+
+ <para>
+ For example, this command updates all products that have a price of
+ 5 to have a price of 10:
+<programlisting>
+UPDATE products SET price = 10 WHERE price = 5;
+</programlisting>
+ This might cause zero, one, or many rows to be updated. It is not
+ an error to attempt an update that does not match any rows.
+ </para>
+
+ <para>
+ Let's look at that command in detail. First is the key word
+ <literal>UPDATE</literal> followed by the table name. As usual,
+ the table name can be schema-qualified, otherwise it is looked up
+ in the path. Next is the key word <literal>SET</literal> followed
+ by the column name, an equal sign, and the new column value. The
+ new column value can be any scalar expression, not just a constant.
+ For example, if you want to raise the price of all products by 10%
+ you could use:
+<programlisting>
+UPDATE products SET price = price * 1.10;
+</programlisting>
+ As you see, the expression for the new value can refer to the existing
+ value(s) in the row. We also left out the <literal>WHERE</literal> clause.
+ If it is omitted, it means that all rows in the table are updated.
+ If it is present, only those rows that match the
+ <literal>WHERE</literal> condition are updated. Note that the equals
+ sign in the <literal>SET</literal> clause is an assignment while
+ the one in the <literal>WHERE</literal> clause is a comparison, but
+ this does not create any ambiguity. Of course, the
+ <literal>WHERE</literal> condition does
+ not have to be an equality test. Many other operators are
+ available (see <xref linkend="functions"/>). But the expression
+ needs to evaluate to a Boolean result.
+ </para>
+
+ <para>
+ You can update more than one column in an
+ <command>UPDATE</command> command by listing more than one
+ assignment in the <literal>SET</literal> clause. For example:
+<programlisting>
+UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a &gt; 0;
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="dml-delete">
+ <title>Deleting Data</title>
+
+ <indexterm zone="dml-delete">
+ <primary>deleting</primary>
+ </indexterm>
+
+ <indexterm zone="dml-delete">
+ <primary>DELETE</primary>
+ </indexterm>
+
+ <para>
+ So far we have explained how to add data to tables and how to
+ change data. What remains is to discuss how to remove data that is
+ no longer needed. Just as adding data is only possible in whole
+ rows, you can only remove entire rows from a table. In the
+ previous section we explained that SQL does not provide a way to
+ directly address individual rows. Therefore, removing rows can
+ only be done by specifying conditions that the rows to be removed
+ have to match. If you have a primary key in the table then you can
+ specify the exact row. But you can also remove groups of rows
+ matching a condition, or you can remove all rows in the table at
+ once.
+ </para>
+
+ <para>
+ You use the <xref linkend="sql-delete"/>
+ command to remove rows; the syntax is very similar to the
+ <xref linkend="sql-update"/> command. For instance, to remove all
+ rows from the products table that have a price of 10, use:
+<programlisting>
+DELETE FROM products WHERE price = 10;
+</programlisting>
+ </para>
+
+ <para>
+ If you simply write:
+<programlisting>
+DELETE FROM products;
+</programlisting>
+ then all rows in the table will be deleted! Caveat programmer.
+ </para>
+ </sect1>
+
+ <sect1 id="dml-returning">
+ <title>Returning Data from Modified Rows</title>
+
+ <indexterm zone="dml-returning">
+ <primary>RETURNING</primary>
+ </indexterm>
+
+ <indexterm zone="dml-returning">
+ <primary>INSERT</primary>
+ <secondary>RETURNING</secondary>
+ </indexterm>
+
+ <indexterm zone="dml-returning">
+ <primary>UPDATE</primary>
+ <secondary>RETURNING</secondary>
+ </indexterm>
+
+ <indexterm zone="dml-returning">
+ <primary>DELETE</primary>
+ <secondary>RETURNING</secondary>
+ </indexterm>
+
+ <para>
+ Sometimes it is useful to obtain data from modified rows while they are
+ being manipulated. The <command>INSERT</command>, <command>UPDATE</command>,
+ and <command>DELETE</command> commands all have an
+ optional <literal>RETURNING</literal> clause that supports this. Use
+ of <literal>RETURNING</literal> avoids performing an extra database query to
+ collect the data, and is especially valuable when it would otherwise be
+ difficult to identify the modified rows reliably.
+ </para>
+
+ <para>
+ The allowed contents of a <literal>RETURNING</literal> clause are the same as
+ a <command>SELECT</command> command's output list
+ (see <xref linkend="queries-select-lists"/>). It can contain column
+ names of the command's target table, or value expressions using those
+ columns. A common shorthand is <literal>RETURNING *</literal>, which selects
+ all columns of the target table in order.
+ </para>
+
+ <para>
+ In an <command>INSERT</command>, the data available to <literal>RETURNING</literal> is
+ the row as it was inserted. This is not so useful in trivial inserts,
+ since it would just repeat the data provided by the client. But it can
+ be very handy when relying on computed default values. For example,
+ when using a <link linkend="datatype-serial"><type>serial</type></link>
+ column to provide unique identifiers, <literal>RETURNING</literal> can return
+ the ID assigned to a new row:
+<programlisting>
+CREATE TABLE users (firstname text, lastname text, id serial primary key);
+
+INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
+</programlisting>
+ The <literal>RETURNING</literal> clause is also very useful
+ with <literal>INSERT ... SELECT</literal>.
+ </para>
+
+ <para>
+ In an <command>UPDATE</command>, the data available to <literal>RETURNING</literal> is
+ the new content of the modified row. For example:
+<programlisting>
+UPDATE products SET price = price * 1.10
+ WHERE price &lt;= 99.99
+ RETURNING name, price AS new_price;
+</programlisting>
+ </para>
+
+ <para>
+ In a <command>DELETE</command>, the data available to <literal>RETURNING</literal> is
+ the content of the deleted row. For example:
+<programlisting>
+DELETE FROM products
+ WHERE obsoletion_date = 'today'
+ RETURNING *;
+</programlisting>
+ </para>
+
+ <para>
+ If there are triggers (<xref linkend="triggers"/>) on the target table,
+ the data available to <literal>RETURNING</literal> is the row as modified by
+ the triggers. Thus, inspecting columns computed by triggers is another
+ common use-case for <literal>RETURNING</literal>.
+ </para>
+
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/docguide.sgml b/doc/src/sgml/docguide.sgml
new file mode 100644
index 0000000..2d8d5cd
--- /dev/null
+++ b/doc/src/sgml/docguide.sgml
@@ -0,0 +1,656 @@
+<!-- doc/src/sgml/docguide.sgml -->
+
+<appendix id="docguide">
+ <title>Documentation</title>
+
+ <para>
+ <productname>PostgreSQL</productname> has four primary documentation
+ formats:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Plain text, for pre-installation information
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <acronym>HTML</acronym>, for on-line browsing and reference
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ PDF, for printing
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ man pages, for quick reference.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Additionally, a number of plain-text <filename>README</filename> files can
+ be found throughout the <productname>PostgreSQL</productname> source tree,
+ documenting various implementation issues.
+ </para>
+
+ <para>
+ <acronym>HTML</acronym> documentation and man pages are part of a
+ standard distribution and are installed by default. PDF
+ format documentation is available separately for
+ download.
+ </para>
+
+ <sect1 id="docguide-docbook">
+ <title>DocBook</title>
+ <para>
+ The documentation sources are written in
+ <firstterm>DocBook</firstterm>, which is a markup language
+ defined in <acronym>XML</acronym>. In what
+ follows, the terms DocBook and <acronym>XML</acronym> are both
+ used, but technically they are not interchangeable.
+ </para>
+
+ <para>
+ <productname>DocBook</productname> allows an author to specify the
+ structure and content of a technical document without worrying
+ about presentation details. A document style defines how that
+ content is rendered into one of several final forms. DocBook is
+ maintained by the <ulink url="https://www.oasis-open.org">
+ OASIS group</ulink>. The <ulink url="https://www.oasis-open.org/docbook/">
+ official DocBook site</ulink> has good introductory and reference documentation and
+ a complete O'Reilly book for your online reading pleasure. The
+ <ulink url="http://newbiedoc.sourceforge.net/metadoc/docbook-guide.html">
+ NewbieDoc Docbook Guide</ulink> is very helpful for beginners.
+ The <ulink url="https://www.freebsd.org/docproj/">
+ FreeBSD Documentation Project</ulink> also uses DocBook and has some good
+ information, including a number of style guidelines that might be
+ worth considering.
+ </para>
+ </sect1>
+
+
+ <sect1 id="docguide-toolsets">
+ <title>Tool Sets</title>
+
+ <para>
+ The following tools are used to process the documentation. Some
+ might be optional, as noted.
+
+ <variablelist>
+ <varlistentry>
+ <term><ulink url="https://www.oasis-open.org/docbook/">DocBook DTD</ulink></term>
+ <listitem>
+ <para>
+ This is the definition of DocBook itself. We currently use version
+ 4.5; you cannot use later or earlier versions. You need
+ the <acronym>XML</acronym> variant of the DocBook DTD, not
+ the <acronym>SGML</acronym> variant.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><ulink url="https://github.com/docbook/wiki/wiki/DocBookXslStylesheets">DocBook XSL Stylesheets</ulink></term>
+ <listitem>
+ <para>
+ These contain the processing instructions for converting the
+ DocBook sources to other formats, such as
+ <acronym>HTML</acronym>.
+ </para>
+
+ <para>
+ The minimum required version is currently 1.77.0, but it is recommended
+ to use the latest available version for best results.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><ulink url="http://xmlsoft.org/">Libxml2</ulink> for <command>xmllint</command></term>
+ <listitem>
+ <para>
+ This library and the <command>xmllint</command> tool it contains are
+ used for processing XML. Many developers will already
+ have <application>Libxml2</application> installed, because it is also
+ used when building the PostgreSQL code. Note, however,
+ that <command>xmllint</command> might need to be installed from a
+ separate subpackage.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><ulink url="http://xmlsoft.org/XSLT/">Libxslt</ulink> for <command>xsltproc</command></term>
+ <listitem>
+ <para>
+ <command>xsltproc</command> is an XSLT processor, that is, a program to
+ convert XML to other formats using XSLT stylesheets.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><ulink url="https://xmlgraphics.apache.org/fop/">FOP</ulink></term>
+ <listitem>
+ <para>
+ This is a program for converting, among other things, XML to PDF.
+ It is needed only if you want to build the documentation in PDF format.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ We have documented experience with several installation methods for
+ the various tools that are needed to process the documentation.
+ These will be described below. There might be some other packaged
+ distributions for these tools. Please report package status to the
+ documentation mailing list, and we will include that information
+ here.
+ </para>
+
+ <sect2>
+ <title>Installation on Fedora, RHEL, and Derivatives</title>
+
+ <para>
+ To install the required packages, use:
+<programlisting>
+yum install docbook-dtds docbook-style-xsl libxslt fop
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Installation on FreeBSD</title>
+
+ <para>
+ To install the required packages with <command>pkg</command>, use:
+<programlisting>
+pkg install docbook-xml docbook-xsl libxslt fop
+</programlisting>
+ </para>
+
+ <para>
+ When building the documentation from the <filename>doc</filename>
+ directory you'll need to use <command>gmake</command>, because the
+ makefile provided is not suitable for FreeBSD's <command>make</command>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Debian Packages</title>
+
+ <para>
+ There is a full set of packages of the documentation tools
+ available for <productname>Debian GNU/Linux</productname>.
+ To install, simply use:
+<programlisting>
+apt-get install docbook-xml docbook-xsl libxml2-utils xsltproc fop
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>macOS</title>
+
+ <para>
+ If you use MacPorts, the following will get you set up:
+<programlisting>
+sudo port install docbook-xml docbook-xsl-nons libxslt fop
+</programlisting>
+ If you use Homebrew, use this:
+<programlisting>
+brew install docbook docbook-xsl libxslt fop
+</programlisting>
+ </para>
+
+ <para>
+ The Homebrew-supplied programs require the following environment variable
+ to be set. For Intel based machines, use this:
+<programlisting>
+export XML_CATALOG_FILES=/usr/local/etc/xml/catalog
+</programlisting>
+ On Apple Silicon based machines, use this:
+<programlisting>
+export XML_CATALOG_FILES=/opt/homebrew/etc/xml/catalog
+</programlisting>
+ Without it, <command>xsltproc</command> will throw errors like this:
+<programlisting>
+I/O error : Attempt to load network entity http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd
+postgres.sgml:21: warning: failed to load external entity "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
+...
+</programlisting>
+ </para>
+
+ <para>
+ While it is possible to use the Apple-provided versions
+ of <command>xmllint</command> and <command>xsltproc</command>
+ instead of those from MacPorts or Homebrew, you'll still need
+ to install the DocBook DTD and stylesheets, and set up a catalog
+ file that points to them.
+ </para>
+ </sect2>
+
+ <sect2 id="docguide-toolsets-configure">
+ <title>Detection by <command>configure</command></title>
+
+ <para>
+ Before you can build the documentation you need to run the
+ <filename>configure</filename> script, as you would when building
+ the <productname>PostgreSQL</productname> programs themselves.
+ Check the output near the end of the run; it should look something
+ like this:
+<screen>
+checking for xmllint... xmllint
+checking for xsltproc... xsltproc
+checking for fop... fop
+checking for dbtoepub... dbtoepub
+</screen>
+ If <filename>xmllint</filename> or <filename>xsltproc</filename> is not
+ found, you will not be able to build any of the documentation.
+ <filename>fop</filename> is only needed to build the documentation in
+ PDF format.
+ <filename>dbtoepub</filename> is only needed to build the documentation
+ in EPUB format.
+ </para>
+
+ <para>
+ If necessary, you can tell <filename>configure</filename> where to find
+ these programs, for example
+<screen>
+./configure ... XMLLINT=/opt/local/bin/xmllint ...
+</screen>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="docguide-build">
+ <title>Building the Documentation</title>
+
+ <para>
+ Once you have everything set up, change to the directory
+ <filename>doc/src/sgml</filename> and run one of the commands
+ described in the following subsections to build the
+ documentation. (Remember to use GNU make.)
+ </para>
+
+ <sect2>
+ <title>HTML</title>
+
+ <para>
+ To build the <acronym>HTML</acronym> version of the documentation:
+<screen>
+<prompt>doc/src/sgml$ </prompt><userinput>make html</userinput>
+</screen>
+ This is also the default target. The output appears in the
+ subdirectory <filename>html</filename>.
+ </para>
+
+ <para>
+ To produce HTML documentation with the stylesheet used on <ulink
+ url="https://www.postgresql.org/docs/current/">postgresql.org</ulink> instead of the
+ default simple style use:
+<screen>
+<prompt>doc/src/sgml$ </prompt><userinput>make STYLE=website html</userinput>
+</screen>
+ </para>
+
+ <para>
+ If the <literal>STYLE=website</literal> option is used, the generated HTML
+ files include references to stylesheets hosted on <ulink
+ url="https://www.postgresql.org/docs/current/">postgresql.org</ulink> and
+ require network access to view.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Manpages</title>
+
+ <para>
+ We use the DocBook XSL stylesheets to
+ convert <productname>DocBook</productname>
+ <sgmltag>refentry</sgmltag> pages to *roff output suitable for man
+ pages. To create the man pages, use the command:
+<screen>
+<prompt>doc/src/sgml$ </prompt><userinput>make man</userinput>
+</screen>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>PDF</title>
+
+ <para>
+ To produce a PDF rendition of the documentation
+ using <productname>FOP</productname>, you can use one of the following
+ commands, depending on the preferred paper format:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ For A4 format:
+<screen>
+<prompt>doc/src/sgml$ </prompt><userinput>make postgres-A4.pdf</userinput>
+</screen>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For U.S. letter format:
+<screen>
+<prompt>doc/src/sgml$ </prompt><userinput>make postgres-US.pdf</userinput>
+</screen>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Because the PostgreSQL documentation is fairly
+ big, <productname>FOP</productname> will require a significant amount of
+ memory. Because of that, on some systems, the build will fail with a
+ memory-related error message. This can usually be fixed by configuring
+ Java heap settings in the configuration
+ file <filename>~/.foprc</filename>, for example:
+<programlisting>
+# FOP binary distribution
+FOP_OPTS='-Xmx1500m'
+# Debian
+JAVA_ARGS='-Xmx1500m'
+# Red Hat
+ADDITIONAL_FLAGS='-Xmx1500m'
+</programlisting>
+ There is a minimum amount of memory that is required, and to some extent
+ more memory appears to make things a bit faster. On systems with very
+ little memory (less than 1 GB), the build will either be very slow due to
+ swapping or will not work at all.
+ </para>
+
+ <para>
+ Other XSL-FO processors can also be used manually, but the automated build
+ process only supports FOP.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Plain Text Files</title>
+
+ <para>
+ The installation instructions are also distributed as plain text,
+ in case they are needed in a situation where better reading tools
+ are not available. The <filename>INSTALL</filename> file
+ corresponds to <xref linkend="installation"/>, with some minor
+ changes to account for the different context. To recreate the
+ file, change to the directory <filename>doc/src/sgml</filename>
+ and enter <userinput>make INSTALL</userinput>. Building text output
+ requires <productname>Pandoc</productname> version 1.13 or newer as an
+ additional build tool.
+ </para>
+
+ <para>
+ In the past, the release notes and regression testing instructions
+ were also distributed as plain text, but this practice has been
+ discontinued.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Syntax Check</title>
+
+ <para>
+ Building the documentation can take very long. But there is a
+ method to just check the correct syntax of the documentation
+ files, which only takes a few seconds:
+<screen>
+<prompt>doc/src/sgml$ </prompt><userinput>make check</userinput>
+</screen>
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="docguide-authoring">
+ <title>Documentation Authoring</title>
+
+ <para>
+ The documentation sources are most conveniently modified with an editor
+ that has a mode for editing XML, and even more so if it has some awareness
+ of XML schema languages so that it can know about
+ <productname>DocBook</productname> syntax specifically.
+ </para>
+
+ <para>
+ Note that for historical reasons the documentation source files are named
+ with an extension <filename>.sgml</filename> even though they are now XML
+ files. So you might need to adjust your editor configuration to set the
+ correct mode.
+ </para>
+
+ <sect2>
+ <title>Emacs</title>
+
+ <para>
+ <productname>nXML Mode</productname>, which ships with
+ <productname>Emacs</productname>, is the most common mode for editing
+ <acronym>XML</acronym> documents with <productname>Emacs</productname>.
+ It will allow you to use <application>Emacs</application> to insert tags
+ and check markup consistency, and it supports
+ <productname>DocBook</productname> out of the box. Check the <ulink
+ url="https://www.gnu.org/software/emacs/manual/html_mono/nxml-mode.html">
+ nXML manual</ulink> for detailed documentation.
+ </para>
+
+ <para>
+ <filename>src/tools/editors/emacs.samples</filename> contains
+ recommended settings for this mode.
+ </para>
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="docguide-style">
+ <title>Style Guide</title>
+
+ <sect2>
+ <title>Reference Pages</title>
+
+ <para>
+ Reference pages should follow a standard layout. This allows
+ users to find the desired information more quickly, and it also
+ encourages writers to document all relevant aspects of a command.
+ Consistency is not only desired among
+ <productname>PostgreSQL</productname> reference pages, but also
+ with reference pages provided by the operating system and other
+ packages. Hence the following guidelines have been developed.
+ They are for the most part consistent with similar guidelines
+ established by various operating systems.
+ </para>
+
+ <para>
+ Reference pages that describe executable commands should contain
+ the following sections, in this order. Sections that do not apply
+ can be omitted. Additional top-level sections should only be used
+ in special circumstances; often that information belongs in the
+ <quote>Usage</quote> section.
+
+ <variablelist>
+ <varlistentry>
+ <term>Name</term>
+ <listitem>
+ <para>
+ This section is generated automatically. It contains the
+ command name and a half-sentence summary of its functionality.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Synopsis</term>
+ <listitem>
+ <para>
+ This section contains the syntax diagram of the command. The
+ synopsis should normally not list each command-line option;
+ that is done below. Instead, list the major components of the
+ command line, such as where input and output files go.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Description</term>
+ <listitem>
+ <para>
+ Several paragraphs explaining what the command does.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Options</term>
+ <listitem>
+ <para>
+ A list describing each command-line option. If there are a
+ lot of options, subsections can be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Exit Status</term>
+ <listitem>
+ <para>
+ If the program uses 0 for success and non-zero for failure,
+ then you do not need to document it. If there is a meaning
+ behind the different non-zero exit codes, list them here.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Usage</term>
+ <listitem>
+ <para>
+ Describe any sublanguage or run-time interface of the program.
+ If the program is not interactive, this section can usually be
+ omitted. Otherwise, this section is a catch-all for
+ describing run-time features. Use subsections if appropriate.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Environment</term>
+ <listitem>
+ <para>
+ List all environment variables that the program might use.
+ Try to be complete; even seemingly trivial variables like
+ <envar>SHELL</envar> might be of interest to the user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Files</term>
+ <listitem>
+ <para>
+ List any files that the program might access implicitly. That
+ is, do not list input and output files that were specified on
+ the command line, but list configuration files, etc.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Diagnostics</term>
+ <listitem>
+ <para>
+ Explain any unusual output that the program might create.
+ Refrain from listing every possible error message. This is a
+ lot of work and has little use in practice. But if, say, the
+ error messages have a standard format that the user can parse,
+ this would be the place to explain it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Notes</term>
+ <listitem>
+ <para>
+ Anything that doesn't fit elsewhere, but in particular bugs,
+ implementation flaws, security considerations, compatibility
+ issues.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Examples</term>
+ <listitem>
+ <para>
+ Examples
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>History</term>
+ <listitem>
+ <para>
+ If there were some major milestones in the history of the
+ program, they might be listed here. Usually, this section can
+ be omitted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Author</term>
+ <listitem>
+ <para>
+ Author (only used in the contrib section)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>See Also</term>
+ <listitem>
+ <para>
+ Cross-references, listed in the following order: other
+ <productname>PostgreSQL</productname> command reference pages,
+ <productname>PostgreSQL</productname> SQL command reference
+ pages, citation of <productname>PostgreSQL</productname>
+ manuals, other reference pages (e.g., operating system, other
+ packages), other documentation. Items in the same group are
+ listed alphabetically.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ Reference pages describing SQL commands should contain the
+ following sections: Name, Synopsis, Description, Parameters,
+ Outputs, Notes, Examples, Compatibility, History, See
+ Also. The Parameters section is like the Options section, but
+ there is more freedom about which clauses of the command can be
+ listed. The Outputs section is only needed if the command returns
+ something other than a default command-completion tag. The Compatibility
+ section should explain to what extent
+ this command conforms to the SQL standard(s), or to which other
+ database system it is compatible. The See Also section of SQL
+ commands should list SQL commands before cross-references to
+ programs.
+ </para>
+ </sect2>
+
+ </sect1>
+</appendix>
diff --git a/doc/src/sgml/earthdistance.sgml b/doc/src/sgml/earthdistance.sgml
new file mode 100644
index 0000000..4377249
--- /dev/null
+++ b/doc/src/sgml/earthdistance.sgml
@@ -0,0 +1,265 @@
+<!-- doc/src/sgml/earthdistance.sgml -->
+
+<sect1 id="earthdistance" xreflabel="earthdistance">
+ <title>earthdistance</title>
+
+ <indexterm zone="earthdistance">
+ <primary>earthdistance</primary>
+ </indexterm>
+
+ <para>
+ The <filename>earthdistance</filename> module provides two different approaches to
+ calculating great circle distances on the surface of the Earth. The one
+ described first depends on the <filename>cube</filename> module.
+ The second one is based on the built-in <type>point</type> data type,
+ using longitude and latitude for the coordinates.
+ </para>
+
+ <para>
+ In this module, the Earth is assumed to be perfectly spherical.
+ (If that's too inaccurate for you, you might want to look at the
+ <application><ulink url="https://postgis.net/">PostGIS</ulink></application>
+ project.)
+ </para>
+
+ <para>
+ The <filename>cube</filename> module must be installed
+ before <filename>earthdistance</filename> can be installed
+ (although you can use the <literal>CASCADE</literal> option
+ of <command>CREATE EXTENSION</command> to install both in one command).
+ </para>
+
+ <caution>
+ <para>
+ It is strongly recommended that <filename>earthdistance</filename>
+ and <filename>cube</filename> be installed in the same schema, and that
+ that schema be one for which CREATE privilege has not been and will not
+ be granted to any untrusted users.
+ Otherwise there are installation-time security hazards
+ if <filename>earthdistance</filename>'s schema contains objects defined
+ by a hostile user.
+ Furthermore, when using <filename>earthdistance</filename>'s functions
+ after installation, the entire search path should contain only trusted
+ schemas.
+ </para>
+ </caution>
+
+ <sect2>
+ <title>Cube-Based Earth Distances</title>
+
+ <para>
+ Data is stored in cubes that are points (both corners are the same) using 3
+ coordinates representing the x, y, and z distance from the center of the
+ Earth. A <glossterm linkend="glossary-domain">domain</glossterm>
+ <type>earth</type> over type <type>cube</type> is provided, which
+ includes constraint checks that the value meets these restrictions and
+ is reasonably close to the actual surface of the Earth.
+ </para>
+
+ <para>
+ The radius of the Earth is obtained from the <function>earth()</function>
+ function. It is given in meters. But by changing this one function you can
+ change the module to use some other units, or to use a different value of
+ the radius that you feel is more appropriate.
+ </para>
+
+ <para>
+ This package has applications to astronomical databases as well.
+ Astronomers will probably want to change <function>earth()</function> to return a
+ radius of <literal>180/pi()</literal> so that distances are in degrees.
+ </para>
+
+ <para>
+ Functions are provided to support input in latitude and longitude (in
+ degrees), to support output of latitude and longitude, to calculate
+ the great circle distance between two points and to easily specify a
+ bounding box usable for index searches.
+ </para>
+
+ <para>
+ The provided functions are shown
+ in <xref linkend="earthdistance-cube-functions"/>.
+ </para>
+
+ <table id="earthdistance-cube-functions">
+ <title>Cube-Based Earthdistance Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>earth</primary></indexterm>
+ <function>earth</function> ()
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the assumed radius of the Earth.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>sec_to_gc</primary></indexterm>
+ <function>sec_to_gc</function> ( <type>float8</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Converts the normal straight line
+ (secant) distance between two points on the surface of the Earth
+ to the great circle distance between them.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>gc_to_sec</primary></indexterm>
+ <function>gc_to_sec</function> ( <type>float8</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Converts the great circle distance between two points on the
+ surface of the Earth to the normal straight line (secant) distance
+ between them.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>ll_to_earth</primary></indexterm>
+ <function>ll_to_earth</function> ( <type>float8</type>, <type>float8</type> )
+ <returnvalue>earth</returnvalue>
+ </para>
+ <para>
+ Returns the location of a point on the surface of the Earth given
+ its latitude (argument 1) and longitude (argument 2) in degrees.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>latitude</primary></indexterm>
+ <function>latitude</function> ( <type>earth</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the latitude in degrees of a point on the surface of the
+ Earth.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>longitude</primary></indexterm>
+ <function>longitude</function> ( <type>earth</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the longitude in degrees of a point on the surface of the
+ Earth.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>earth_distance</primary></indexterm>
+ <function>earth_distance</function> ( <type>earth</type>, <type>earth</type> )
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Returns the great circle distance between two points on the
+ surface of the Earth.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>earth_box</primary></indexterm>
+ <function>earth_box</function> ( <type>earth</type>, <type>float8</type> )
+ <returnvalue>cube</returnvalue>
+ </para>
+ <para>
+ Returns a box suitable for an indexed search using the <type>cube</type>
+ <literal>@&gt;</literal>
+ operator for points within a given great circle distance of a location.
+ Some points in this box are further than the specified great circle
+ distance from the location, so a second check using
+ <function>earth_distance</function> should be included in the query.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2>
+ <title>Point-Based Earth Distances</title>
+
+ <para>
+ The second part of the module relies on representing Earth locations as
+ values of type <type>point</type>, in which the first component is taken to
+ represent longitude in degrees, and the second component is taken to
+ represent latitude in degrees. Points are taken as (longitude, latitude)
+ and not vice versa because longitude is closer to the intuitive idea of
+ x-axis and latitude to y-axis.
+ </para>
+
+ <para>
+ A single operator is provided, shown
+ in <xref linkend="earthdistance-point-operators"/>.
+ </para>
+
+ <table id="earthdistance-point-operators">
+ <title>Point-Based Earthdistance Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>point</type> <literal>&lt;@&gt;</literal> <type>point</type>
+ <returnvalue>float8</returnvalue>
+ </para>
+ <para>
+ Computes the distance in statute miles between
+ two points on the Earth's surface.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Note that unlike the <type>cube</type>-based part of the module, units
+ are hardwired here: changing the <function>earth()</function> function will
+ not affect the results of this operator.
+ </para>
+
+ <para>
+ One disadvantage of the longitude/latitude representation is that
+ you need to be careful about the edge conditions near the poles
+ and near +/- 180 degrees of longitude. The <type>cube</type>-based
+ representation avoids these discontinuities.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
new file mode 100644
index 0000000..bb81b03
--- /dev/null
+++ b/doc/src/sgml/ecpg.sgml
@@ -0,0 +1,10064 @@
+<!-- doc/src/sgml/ecpg.sgml -->
+
+<chapter id="ecpg">
+ <title><application>ECPG</application> &mdash; Embedded <acronym>SQL</acronym> in C</title>
+
+ <indexterm zone="ecpg"><primary>embedded SQL</primary><secondary>in C</secondary></indexterm>
+ <indexterm zone="ecpg"><primary>C</primary></indexterm>
+ <indexterm zone="ecpg"><primary>ECPG</primary></indexterm>
+
+ <para>
+ This chapter describes the embedded <acronym>SQL</acronym> package
+ for <productname>PostgreSQL</productname>. It was written by
+ Linus Tolke (<email>linus@epact.se</email>) and Michael Meskes
+ (<email>meskes@postgresql.org</email>). Originally it was written to work with
+ <acronym>C</acronym>. It also works with <acronym>C++</acronym>, but
+ it does not recognize all <acronym>C++</acronym> constructs yet.
+ </para>
+
+ <para>
+ This documentation is quite incomplete. But since this
+ interface is standardized, additional information can be found in
+ many resources about SQL.
+ </para>
+
+ <sect1 id="ecpg-concept">
+ <title>The Concept</title>
+
+ <para>
+ An embedded SQL program consists of code written in an ordinary
+ programming language, in this case C, mixed with SQL commands in
+ specially marked sections. To build the program, the source code (<filename>*.pgc</filename>)
+ is first passed through the embedded SQL preprocessor, which converts it
+ to an ordinary C program (<filename>*.c</filename>), and afterwards it can be processed by a C
+ compiler. (For details about the compiling and linking see <xref linkend="ecpg-process"/>.)
+ Converted ECPG applications call functions in the libpq library
+ through the embedded SQL library (ecpglib), and communicate with
+ the PostgreSQL server using the normal frontend-backend protocol.
+ </para>
+
+ <para>
+ Embedded <acronym>SQL</acronym> has advantages over other methods
+ for handling <acronym>SQL</acronym> commands from C code. First, it
+ takes care of the tedious passing of information to and from
+ variables in your <acronym>C</acronym> program. Second, the SQL
+ code in the program is checked at build time for syntactical
+ correctness. Third, embedded <acronym>SQL</acronym> in C is
+ specified in the <acronym>SQL</acronym> standard and supported by
+ many other <acronym>SQL</acronym> database systems. The
+ <productname>PostgreSQL</productname> implementation is designed to match this
+ standard as much as possible, and it is usually possible to port
+ embedded <acronym>SQL</acronym> programs written for other SQL
+ databases to <productname>PostgreSQL</productname> with relative
+ ease.
+ </para>
+
+ <para>
+ As already stated, programs written for the embedded
+ <acronym>SQL</acronym> interface are normal C programs with special
+ code inserted to perform database-related actions. This special
+ code always has the form:
+<programlisting>
+EXEC SQL ...;
+</programlisting>
+ These statements syntactically take the place of a C statement.
+ Depending on the particular statement, they can appear at the
+ global level or within a function.
+ </para>
+
+ <para>
+ Embedded
+ <acronym>SQL</acronym> statements follow the case-sensitivity rules of
+ normal <acronym>SQL</acronym> code, and not those of C. Also they allow nested
+ C-style comments as per the SQL standard. The C part of the
+ program, however, follows the C standard of not accepting nested comments.
+ Embedded <acronym>SQL</acronym> statements likewise use SQL rules, not
+ C rules, for parsing quoted strings and identifiers.
+ (See <xref linkend="sql-syntax-strings"/> and
+ <xref linkend="sql-syntax-identifiers"/> respectively. Note that
+ ECPG assumes that <varname>standard_conforming_strings</varname>
+ is <literal>on</literal>.)
+ Of course, the C part of the program follows C quoting rules.
+ </para>
+
+ <para>
+ The following sections explain all the embedded SQL statements.
+ </para>
+ </sect1>
+
+ <sect1 id="ecpg-connect">
+ <title>Managing Database Connections</title>
+
+ <para>
+ This section describes how to open, close, and switch database
+ connections.
+ </para>
+
+ <sect2 id="ecpg-connecting">
+ <title>Connecting to the Database Server</title>
+
+ <para>
+ One connects to a database using the following statement:
+<programlisting>
+EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>connection-name</replaceable></optional> <optional>USER <replaceable>user-name</replaceable></optional>;
+</programlisting>
+ The <replaceable>target</replaceable> can be specified in the
+ following ways:
+
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ <literal><replaceable>dbname</replaceable><optional>@<replaceable>hostname</replaceable></optional><optional>:<replaceable>port</replaceable></optional></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal>tcp:postgresql://<replaceable>hostname</replaceable><optional>:<replaceable>port</replaceable></optional><optional>/<replaceable>dbname</replaceable></optional><optional>?<replaceable>options</replaceable></optional></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal>unix:postgresql://localhost<optional>:<replaceable>port</replaceable></optional><optional>/<replaceable>dbname</replaceable></optional><optional>?<replaceable>options</replaceable></optional></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ an SQL string literal containing one of the above forms
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ a reference to a character variable containing one of the above forms (see examples)
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal>DEFAULT</literal>
+ </simpara>
+ </listitem>
+ </itemizedlist>
+
+ The connection target <literal>DEFAULT</literal> initiates a connection
+ to the default database under the default user name. No separate
+ user name or connection name can be specified in that case.
+ </para>
+
+ <para>
+ If you specify the connection target directly (that is, not as a string
+ literal or variable reference), then the components of the target are
+ passed through normal SQL parsing; this means that, for example,
+ the <replaceable>hostname</replaceable> must look like one or more SQL
+ identifiers separated by dots, and those identifiers will be
+ case-folded unless double-quoted. Values of
+ any <replaceable>options</replaceable> must be SQL identifiers,
+ integers, or variable references. Of course, you can put nearly
+ anything into an SQL identifier by double-quoting it.
+ In practice, it is probably less error-prone to use a (single-quoted)
+ string literal or a variable reference than to write the connection
+ target directly.
+ </para>
+
+ <para>
+ There are also different ways to specify the user name:
+
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ <literal><replaceable>username</replaceable></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal><replaceable>username</replaceable>/<replaceable>password</replaceable></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal><replaceable>username</replaceable> IDENTIFIED BY <replaceable>password</replaceable></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal><replaceable>username</replaceable> USING <replaceable>password</replaceable></literal>
+ </simpara>
+ </listitem>
+ </itemizedlist>
+
+ As above, the parameters <replaceable>username</replaceable> and
+ <replaceable>password</replaceable> can be an SQL identifier, an
+ SQL string literal, or a reference to a character variable.
+ </para>
+
+ <para>
+ If the connection target includes any <replaceable>options</replaceable>,
+ those consist of
+ <literal><replaceable>keyword</replaceable>=<replaceable>value</replaceable></literal>
+ specifications separated by ampersands (<literal>&amp;</literal>).
+ The allowed key words are the same ones recognized
+ by <application>libpq</application> (see
+ <xref linkend="libpq-paramkeywords"/>). Spaces are ignored before
+ any <replaceable>keyword</replaceable> or <replaceable>value</replaceable>,
+ though not within or after one. Note that there is no way to
+ write <literal>&amp;</literal> within a <replaceable>value</replaceable>.
+ </para>
+
+ <para>
+ Notice that when specifying a socket connection
+ (with the <literal>unix:</literal> prefix), the host name must be
+ exactly <literal>localhost</literal>. To select a non-default
+ socket directory, write the directory's pathname as the value of
+ a <varname>host</varname> option in
+ the <replaceable>options</replaceable> part of the target.
+ </para>
+
+ <para>
+ The <replaceable>connection-name</replaceable> is used to handle
+ multiple connections in one program. It can be omitted if a
+ program uses only one connection. The most recently opened
+ connection becomes the current connection, which is used by default
+ when an SQL statement is to be executed (see later in this
+ chapter).
+ </para>
+
+ <para>
+ Here are some examples of <command>CONNECT</command> statements:
+<programlisting>
+EXEC SQL CONNECT TO mydb@sql.mydomain.com;
+
+EXEC SQL CONNECT TO tcp:postgresql://sql.mydomain.com/mydb AS myconnection USER john;
+
+EXEC SQL BEGIN DECLARE SECTION;
+const char *target = "mydb@sql.mydomain.com";
+const char *user = "john";
+const char *passwd = "secret";
+EXEC SQL END DECLARE SECTION;
+ ...
+EXEC SQL CONNECT TO :target USER :user USING :passwd;
+/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */
+</programlisting>
+ The last example makes use of the feature referred to above as
+ character variable references. You will see in later sections how C
+ variables can be used in SQL statements when you prefix them with a
+ colon.
+ </para>
+
+ <para>
+ Be advised that the format of the connection target is not
+ specified in the SQL standard. So if you want to develop portable
+ applications, you might want to use something based on the last
+ example above to encapsulate the connection target string
+ somewhere.
+ </para>
+
+ <para>
+ If untrusted users have access to a database that has not adopted a
+ <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
+ begin each session by removing publicly-writable schemas
+ from <varname>search_path</varname>. For example,
+ add <literal>options=-c search_path=</literal>
+ to <literal><replaceable>options</replaceable></literal>, or
+ issue <literal>EXEC SQL SELECT pg_catalog.set_config('search_path', '',
+ false);</literal> after connecting. This consideration is not specific to
+ ECPG; it applies to every interface for executing arbitrary SQL commands.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-set-connection">
+ <title>Choosing a Connection</title>
+
+ <para>
+ SQL statements in embedded SQL programs are by default executed on
+ the current connection, that is, the most recently opened one. If
+ an application needs to manage multiple connections, then there are
+ three ways to handle this.
+ </para>
+
+ <para>
+ The first option is to explicitly choose a connection for each SQL
+ statement, for example:
+<programlisting>
+EXEC SQL AT <replaceable>connection-name</replaceable> SELECT ...;
+</programlisting>
+ This option is particularly suitable if the application needs to
+ use several connections in mixed order.
+ </para>
+
+ <para>
+ If your application uses multiple threads of execution, they cannot share a
+ connection concurrently. You must either explicitly control access to the connection
+ (using mutexes) or use a connection for each thread.
+ </para>
+
+ <para>
+ The second option is to execute a statement to switch the current
+ connection. That statement is:
+<programlisting>
+EXEC SQL SET CONNECTION <replaceable>connection-name</replaceable>;
+</programlisting>
+ This option is particularly convenient if many statements are to be
+ executed on the same connection.
+ </para>
+
+ <para>
+ Here is an example program managing multiple database connections:
+<programlisting><![CDATA[
+#include <stdio.h>
+
+EXEC SQL BEGIN DECLARE SECTION;
+ char dbname[1024];
+EXEC SQL END DECLARE SECTION;
+
+int
+main()
+{
+ EXEC SQL CONNECT TO testdb1 AS con1 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL CONNECT TO testdb2 AS con2 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL CONNECT TO testdb3 AS con3 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ /* This query would be executed in the last opened database "testdb3". */
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current=%s (should be testdb3)\n", dbname);
+
+ /* Using "AT" to run a query in "testdb2" */
+ EXEC SQL AT con2 SELECT current_database() INTO :dbname;
+ printf("current=%s (should be testdb2)\n", dbname);
+
+ /* Switch the current connection to "testdb1". */
+ EXEC SQL SET CONNECTION con1;
+
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current=%s (should be testdb1)\n", dbname);
+
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+]]></programlisting>
+
+ This example would produce this output:
+<screen>
+current=testdb3 (should be testdb3)
+current=testdb2 (should be testdb2)
+current=testdb1 (should be testdb1)
+</screen>
+ </para>
+
+ <para>
+ The third option is to declare an SQL identifier linked to
+ the connection, for example:
+<programlisting>
+EXEC SQL AT <replaceable>connection-name</replaceable> DECLARE <replaceable>statement-name</replaceable> STATEMENT;
+EXEC SQL PREPARE <replaceable>statement-name</replaceable> FROM :<replaceable>dyn-string</replaceable>;
+</programlisting>
+ Once you link an SQL identifier to a connection, you execute dynamic SQL
+ without an AT clause. Note that this option behaves like preprocessor
+ directives, therefore the link is enabled only in the file.
+ </para>
+ <para>
+ Here is an example program using this option:
+<programlisting><![CDATA[
+#include <stdio.h>
+
+EXEC SQL BEGIN DECLARE SECTION;
+char dbname[128];
+char *dyn_sql = "SELECT current_database()";
+EXEC SQL END DECLARE SECTION;
+
+int main(){
+ EXEC SQL CONNECT TO postgres AS con1;
+ EXEC SQL CONNECT TO testdb AS con2;
+ EXEC SQL AT con1 DECLARE stmt STATEMENT;
+ EXEC SQL PREPARE stmt FROM :dyn_sql;
+ EXEC SQL EXECUTE stmt INTO :dbname;
+ printf("%s\n", dbname);
+
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+]]></programlisting>
+
+ This example would produce this output, even if the default connection is testdb:
+<screen>
+postgres
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-disconnect">
+ <title>Closing a Connection</title>
+
+ <para>
+ To close a connection, use the following statement:
+<programlisting>
+EXEC SQL DISCONNECT <optional><replaceable>connection</replaceable></optional>;
+</programlisting>
+ The <replaceable>connection</replaceable> can be specified
+ in the following ways:
+
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ <literal><replaceable>connection-name</replaceable></literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal>DEFAULT</literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal>CURRENT</literal>
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ <literal>ALL</literal>
+ </simpara>
+ </listitem>
+ </itemizedlist>
+
+ If no connection name is specified, the current connection is
+ closed.
+ </para>
+
+ <para>
+ It is good style that an application always explicitly disconnect
+ from every connection it opened.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="ecpg-commands">
+ <title>Running SQL Commands</title>
+
+ <para>
+ Any SQL command can be run from within an embedded SQL application.
+ Below are some examples of how to do that.
+ </para>
+
+ <sect2 id="ecpg-executing">
+ <title>Executing SQL Statements</title>
+
+ <para>
+ Creating a table:
+<programlisting>
+EXEC SQL CREATE TABLE foo (number integer, ascii char(16));
+EXEC SQL CREATE UNIQUE INDEX num1 ON foo(number);
+EXEC SQL COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ Inserting rows:
+<programlisting>
+EXEC SQL INSERT INTO foo (number, ascii) VALUES (9999, 'doodad');
+EXEC SQL COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ Deleting rows:
+<programlisting>
+EXEC SQL DELETE FROM foo WHERE number = 9999;
+EXEC SQL COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ Updates:
+<programlisting>
+EXEC SQL UPDATE foo
+ SET ascii = 'foobar'
+ WHERE number = 9999;
+EXEC SQL COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ <literal>SELECT</literal> statements that return a single result
+ row can also be executed using
+ <literal>EXEC SQL</literal> directly. To handle result sets with
+ multiple rows, an application has to use a cursor;
+ see <xref linkend="ecpg-cursors"/> below. (As a special case, an
+ application can fetch multiple rows at once into an array host
+ variable; see <xref linkend="ecpg-variables-arrays"/>.)
+ </para>
+
+ <para>
+ Single-row select:
+<programlisting>
+EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad';
+</programlisting>
+ </para>
+
+ <para>
+ Also, a configuration parameter can be retrieved with the
+ <literal>SHOW</literal> command:
+<programlisting>
+EXEC SQL SHOW search_path INTO :var;
+</programlisting>
+ </para>
+
+ <para>
+ The tokens of the form
+ <literal>:<replaceable>something</replaceable></literal> are
+ <firstterm>host variables</firstterm>, that is, they refer to
+ variables in the C program. They are explained in <xref
+ linkend="ecpg-variables"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-cursors">
+ <title>Using Cursors</title>
+
+ <para>
+ To retrieve a result set holding multiple rows, an application has
+ to declare a cursor and fetch each row from the cursor. The steps
+ to use a cursor are the following: declare a cursor, open it, fetch
+ a row from the cursor, repeat, and finally close it.
+ </para>
+
+ <para>
+ Select using cursors:
+<programlisting>
+EXEC SQL DECLARE foo_bar CURSOR FOR
+ SELECT number, ascii FROM foo
+ ORDER BY ascii;
+EXEC SQL OPEN foo_bar;
+EXEC SQL FETCH foo_bar INTO :FooBar, DooDad;
+...
+EXEC SQL CLOSE foo_bar;
+EXEC SQL COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ For more details about declaring a cursor, see <xref
+ linkend="ecpg-sql-declare"/>; for more details about fetching rows from a
+ cursor, see <xref linkend="sql-fetch"/>.
+ </para>
+
+ <note>
+ <para>
+ The ECPG <command>DECLARE</command> command does not actually
+ cause a statement to be sent to the PostgreSQL backend. The
+ cursor is opened in the backend (using the
+ backend's <command>DECLARE</command> command) at the point when
+ the <command>OPEN</command> command is executed.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="ecpg-transactions">
+ <title>Managing Transactions</title>
+
+ <para>
+ In the default mode, statements are committed only when
+ <command>EXEC SQL COMMIT</command> is issued. The embedded SQL
+ interface also supports autocommit of transactions (similar to
+ <application>psql</application>'s default behavior) via the <option>-t</option>
+ command-line option to <command>ecpg</command> (see <xref
+ linkend="app-ecpg"/>) or via the <literal>EXEC SQL SET AUTOCOMMIT TO
+ ON</literal> statement. In autocommit mode, each command is
+ automatically committed unless it is inside an explicit transaction
+ block. This mode can be explicitly turned off using <literal>EXEC
+ SQL SET AUTOCOMMIT TO OFF</literal>.
+ </para>
+
+ <para>
+ The following transaction management commands are available:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>EXEC SQL COMMIT</literal></term>
+ <listitem>
+ <para>
+ Commit an in-progress transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL ROLLBACK</literal></term>
+ <listitem>
+ <para>
+ Roll back an in-progress transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL PREPARE TRANSACTION </literal><replaceable class="parameter">transaction_id</replaceable></term>
+ <listitem>
+ <para>
+ Prepare the current transaction for two-phase commit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL COMMIT PREPARED </literal><replaceable class="parameter">transaction_id</replaceable></term>
+ <listitem>
+ <para>
+ Commit a transaction that is in prepared state.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL ROLLBACK PREPARED </literal><replaceable class="parameter">transaction_id</replaceable></term>
+ <listitem>
+ <para>
+ Roll back a transaction that is in prepared state.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL SET AUTOCOMMIT TO ON</literal></term>
+ <listitem>
+ <para>
+ Enable autocommit mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL SET AUTOCOMMIT TO OFF</literal></term>
+ <listitem>
+ <para>
+ Disable autocommit mode. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-prepared">
+ <title>Prepared Statements</title>
+
+ <para>
+ When the values to be passed to an SQL statement are not known at
+ compile time, or the same statement is going to be used many
+ times, then prepared statements can be useful.
+ </para>
+
+ <para>
+ The statement is prepared using the
+ command <literal>PREPARE</literal>. For the values that are not
+ known yet, use the
+ placeholder <quote><literal>?</literal></quote>:
+<programlisting>
+EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?";
+</programlisting>
+ </para>
+
+ <para>
+ If a statement returns a single row, the application can
+ call <literal>EXECUTE</literal> after
+ <literal>PREPARE</literal> to execute the statement, supplying the
+ actual values for the placeholders with a <literal>USING</literal>
+ clause:
+<programlisting>
+EXEC SQL EXECUTE stmt1 INTO :dboid, :dbname USING 1;
+</programlisting>
+ </para>
+
+ <para>
+ If a statement returns multiple rows, the application can use a
+ cursor declared based on the prepared statement. To bind input
+ parameters, the cursor must be opened with
+ a <literal>USING</literal> clause:
+<programlisting>
+EXEC SQL PREPARE stmt1 FROM "SELECT oid,datname FROM pg_database WHERE oid &gt; ?";
+EXEC SQL DECLARE foo_bar CURSOR FOR stmt1;
+
+/* when end of result set reached, break out of while loop */
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+EXEC SQL OPEN foo_bar USING 100;
+...
+while (1)
+{
+ EXEC SQL FETCH NEXT FROM foo_bar INTO :dboid, :dbname;
+ ...
+}
+EXEC SQL CLOSE foo_bar;
+</programlisting>
+ </para>
+
+ <para>
+ When you don't need the prepared statement anymore, you should
+ deallocate it:
+<programlisting>
+EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>;
+</programlisting>
+ </para>
+
+ <para>
+ For more details about <literal>PREPARE</literal>,
+ see <xref linkend="ecpg-sql-prepare"/>. Also
+ see <xref linkend="ecpg-dynamic"/> for more details about using
+ placeholders and input parameters.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-variables">
+ <title>Using Host Variables</title>
+
+ <para>
+ In <xref linkend="ecpg-commands"/> you saw how you can execute SQL
+ statements from an embedded SQL program. Some of those statements
+ only used fixed values and did not provide a way to insert
+ user-supplied values into statements or have the program process
+ the values returned by the query. Those kinds of statements are
+ not really useful in real applications. This section explains in
+ detail how you can pass data between your C program and the
+ embedded SQL statements using a simple mechanism called
+ <firstterm>host variables</firstterm>. In an embedded SQL program we
+ consider the SQL statements to be <firstterm>guests</firstterm> in the C
+ program code which is the <firstterm>host language</firstterm>. Therefore
+ the variables of the C program are called <firstterm>host
+ variables</firstterm>.
+ </para>
+
+ <para>
+ Another way to exchange values between PostgreSQL backends and ECPG
+ applications is the use of SQL descriptors, described
+ in <xref linkend="ecpg-descriptors"/>.
+ </para>
+
+ <sect2 id="ecpg-variables-overview">
+ <title>Overview</title>
+
+ <para>
+ Passing data between the C program and the SQL statements is
+ particularly simple in embedded SQL. Instead of having the
+ program paste the data into the statement, which entails various
+ complications, such as properly quoting the value, you can simply
+ write the name of a C variable into the SQL statement, prefixed by
+ a colon. For example:
+<programlisting>
+EXEC SQL INSERT INTO sometable VALUES (:v1, 'foo', :v2);
+</programlisting>
+ This statement refers to two C variables named
+ <varname>v1</varname> and <varname>v2</varname> and also uses a
+ regular SQL string literal, to illustrate that you are not
+ restricted to use one kind of data or the other.
+ </para>
+
+ <para>
+ This style of inserting C variables in SQL statements works
+ anywhere a value expression is expected in an SQL statement.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-declare-sections">
+ <title>Declare Sections</title>
+
+ <para>
+ To pass data from the program to the database, for example as
+ parameters in a query, or to pass data from the database back to
+ the program, the C variables that are intended to contain this
+ data need to be declared in specially marked sections, so the
+ embedded SQL preprocessor is made aware of them.
+ </para>
+
+ <para>
+ This section starts with:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+</programlisting>
+ and ends with:
+<programlisting>
+EXEC SQL END DECLARE SECTION;
+</programlisting>
+ Between those lines, there must be normal C variable declarations,
+ such as:
+<programlisting>
+int x = 4;
+char foo[16], bar[16];
+</programlisting>
+ As you can see, you can optionally assign an initial value to the variable.
+ The variable's scope is determined by the location of its declaring
+ section within the program.
+ You can also declare variables with the following syntax which implicitly
+ creates a declare section:
+<programlisting>
+EXEC SQL int i = 4;
+</programlisting>
+ You can have as many declare sections in a program as you like.
+ </para>
+
+ <para>
+ The declarations are also echoed to the output file as normal C
+ variables, so there's no need to declare them again. Variables
+ that are not intended to be used in SQL commands can be declared
+ normally outside these special sections.
+ </para>
+
+ <para>
+ The definition of a structure or union also must be listed inside
+ a <literal>DECLARE</literal> section. Otherwise the preprocessor cannot
+ handle these types since it does not know the definition.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-retrieving">
+ <title>Retrieving Query Results</title>
+
+ <para>
+ Now you should be able to pass data generated by your program into
+ an SQL command. But how do you retrieve the results of a query?
+ For that purpose, embedded SQL provides special variants of the
+ usual commands <command>SELECT</command> and
+ <command>FETCH</command>. These commands have a special
+ <literal>INTO</literal> clause that specifies which host variables
+ the retrieved values are to be stored in.
+ <command>SELECT</command> is used for a query that returns only
+ single row, and <command>FETCH</command> is used for a query that
+ returns multiple rows, using a cursor.
+ </para>
+
+ <para>
+ Here is an example:
+<programlisting>
+/*
+ * assume this table:
+ * CREATE TABLE test1 (a int, b varchar(50));
+ */
+
+EXEC SQL BEGIN DECLARE SECTION;
+int v1;
+VARCHAR v2;
+EXEC SQL END DECLARE SECTION;
+
+ ...
+
+EXEC SQL SELECT a, b INTO :v1, :v2 FROM test;
+</programlisting>
+ So the <literal>INTO</literal> clause appears between the select
+ list and the <literal>FROM</literal> clause. The number of
+ elements in the select list and the list after
+ <literal>INTO</literal> (also called the target list) must be
+ equal.
+ </para>
+
+ <para>
+ Here is an example using the command <command>FETCH</command>:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int v1;
+VARCHAR v2;
+EXEC SQL END DECLARE SECTION;
+
+ ...
+
+EXEC SQL DECLARE foo CURSOR FOR SELECT a, b FROM test;
+
+ ...
+
+do
+{
+ ...
+ EXEC SQL FETCH NEXT FROM foo INTO :v1, :v2;
+ ...
+} while (...);
+</programlisting>
+ Here the <literal>INTO</literal> clause appears after all the
+ normal clauses.
+ </para>
+
+ </sect2>
+
+ <sect2 id="ecpg-variables-type-mapping">
+ <title>Type Mapping</title>
+
+ <para>
+ When ECPG applications exchange values between the PostgreSQL
+ server and the C application, such as when retrieving query
+ results from the server or executing SQL statements with input
+ parameters, the values need to be converted between PostgreSQL
+ data types and host language variable types (C language data
+ types, concretely). One of the main points of ECPG is that it
+ takes care of this automatically in most cases.
+ </para>
+
+ <para>
+ In this respect, there are two kinds of data types: Some simple
+ PostgreSQL data types, such as <type>integer</type>
+ and <type>text</type>, can be read and written by the application
+ directly. Other PostgreSQL data types, such
+ as <type>timestamp</type> and <type>numeric</type> can only be
+ accessed through special library functions; see
+ <xref linkend="ecpg-special-types"/>.
+ </para>
+
+ <para>
+ <xref linkend="ecpg-datatype-hostvars-table"/> shows which PostgreSQL
+ data types correspond to which C data types. When you wish to
+ send or receive a value of a given PostgreSQL data type, you
+ should declare a C variable of the corresponding C data type in
+ the declare section.
+ </para>
+
+ <table id="ecpg-datatype-hostvars-table">
+ <title>Mapping Between PostgreSQL Data Types and C Variable Types</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>PostgreSQL data type</entry>
+ <entry>Host variable type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>smallint</type></entry>
+ <entry><type>short</type></entry>
+ </row>
+
+ <row>
+ <entry><type>integer</type></entry>
+ <entry><type>int</type></entry>
+ </row>
+
+ <row>
+ <entry><type>bigint</type></entry>
+ <entry><type>long long int</type></entry>
+ </row>
+
+ <row>
+ <entry><type>decimal</type></entry>
+ <entry><type>decimal</type><footnote id="ecpg-datatype-table-fn"><para>This type can only be accessed through special library functions; see <xref linkend="ecpg-special-types"/>.</para></footnote></entry>
+ </row>
+
+ <row>
+ <entry><type>numeric</type></entry>
+ <entry><type>numeric</type><footnoteref linkend="ecpg-datatype-table-fn"/></entry>
+ </row>
+
+ <row>
+ <entry><type>real</type></entry>
+ <entry><type>float</type></entry>
+ </row>
+
+ <row>
+ <entry><type>double precision</type></entry>
+ <entry><type>double</type></entry>
+ </row>
+
+ <row>
+ <entry><type>smallserial</type></entry>
+ <entry><type>short</type></entry>
+ </row>
+
+ <row>
+ <entry><type>serial</type></entry>
+ <entry><type>int</type></entry>
+ </row>
+
+ <row>
+ <entry><type>bigserial</type></entry>
+ <entry><type>long long int</type></entry>
+ </row>
+
+ <row>
+ <entry><type>oid</type></entry>
+ <entry><type>unsigned int</type></entry>
+ </row>
+
+ <row>
+ <entry><type>character(<replaceable>n</replaceable>)</type>, <type>varchar(<replaceable>n</replaceable>)</type>, <type>text</type></entry>
+ <entry><type>char[<replaceable>n</replaceable>+1]</type>, <type>VARCHAR[<replaceable>n</replaceable>+1]</type></entry>
+ </row>
+
+ <row>
+ <entry><type>name</type></entry>
+ <entry><type>char[NAMEDATALEN]</type></entry>
+ </row>
+
+ <row>
+ <entry><type>timestamp</type></entry>
+ <entry><type>timestamp</type><footnoteref linkend="ecpg-datatype-table-fn"/></entry>
+ </row>
+
+ <row>
+ <entry><type>interval</type></entry>
+ <entry><type>interval</type><footnoteref linkend="ecpg-datatype-table-fn"/></entry>
+ </row>
+
+ <row>
+ <entry><type>date</type></entry>
+ <entry><type>date</type><footnoteref linkend="ecpg-datatype-table-fn"/></entry>
+ </row>
+
+ <row>
+ <entry><type>boolean</type></entry>
+ <entry><type>bool</type><footnote><para>declared in <filename>ecpglib.h</filename> if not native</para></footnote></entry>
+ </row>
+
+ <row>
+ <entry><type>bytea</type></entry>
+ <entry><type>char *</type>, <type>bytea[<replaceable>n</replaceable>]</type></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect3 id="ecpg-char">
+ <title>Handling Character Strings</title>
+
+ <para>
+ To handle SQL character string data types, such
+ as <type>varchar</type> and <type>text</type>, there are two
+ possible ways to declare the host variables.
+ </para>
+
+ <para>
+ One way is using <type>char[]</type>, an array
+ of <type>char</type>, which is the most common way to handle
+ character data in C.
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ char str[50];
+EXEC SQL END DECLARE SECTION;
+</programlisting>
+ Note that you have to take care of the length yourself. If you
+ use this host variable as the target variable of a query which
+ returns a string with more than 49 characters, a buffer overflow
+ occurs.
+ </para>
+
+ <para>
+ The other way is using the <type>VARCHAR</type> type, which is a
+ special type provided by ECPG. The definition on an array of
+ type <type>VARCHAR</type> is converted into a
+ named <type>struct</type> for every variable. A declaration like:
+<programlisting>
+VARCHAR var[180];
+</programlisting>
+ is converted into:
+<programlisting>
+struct varchar_var { int len; char arr[180]; } var;
+</programlisting>
+ The member <structfield>arr</structfield> hosts the string
+ including a terminating zero byte. Thus, to store a string in
+ a <type>VARCHAR</type> host variable, the host variable has to be
+ declared with the length including the zero byte terminator. The
+ member <structfield>len</structfield> holds the length of the
+ string stored in the <structfield>arr</structfield> without the
+ terminating zero byte. When a host variable is used as input for
+ a query, if <literal>strlen(arr)</literal>
+ and <structfield>len</structfield> are different, the shorter one
+ is used.
+ </para>
+
+ <para>
+ <type>VARCHAR</type> can be written in upper or lower case, but
+ not in mixed case.
+ </para>
+
+ <para>
+ <type>char</type> and <type>VARCHAR</type> host variables can
+ also hold values of other SQL types, which will be stored in
+ their string forms.
+ </para>
+ </sect3>
+
+ <sect3 id="ecpg-special-types">
+ <title>Accessing Special Data Types</title>
+
+ <para>
+ ECPG contains some special types that help you to interact easily
+ with some special data types from the PostgreSQL server. In
+ particular, it has implemented support for the
+ <type>numeric</type>, <type>decimal</type>, <type>date</type>, <type>timestamp</type>,
+ and <type>interval</type> types. These data types cannot usefully be
+ mapped to primitive host variable types (such
+ as <type>int</type>, <type>long long int</type>,
+ or <type>char[]</type>), because they have a complex internal
+ structure. Applications deal with these types by declaring host
+ variables in special types and accessing them using functions in
+ the pgtypes library. The pgtypes library, described in detail
+ in <xref linkend="ecpg-pgtypes"/> contains basic functions to deal
+ with those types, such that you do not need to send a query to
+ the SQL server just for adding an interval to a time stamp for
+ example.
+ </para>
+
+ <para>
+ The follow subsections describe these special data types. For
+ more details about pgtypes library functions,
+ see <xref linkend="ecpg-pgtypes"/>.
+ </para>
+
+ <sect4>
+ <title>timestamp, date</title>
+
+ <para>
+ Here is a pattern for handling <type>timestamp</type> variables
+ in the ECPG host application.
+ </para>
+
+ <para>
+ First, the program has to include the header file for the
+ <type>timestamp</type> type:
+<programlisting>
+#include &lt;pgtypes_timestamp.h>
+</programlisting>
+ </para>
+
+ <para>
+ Next, declare a host variable as type <type>timestamp</type> in
+ the declare section:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+timestamp ts;
+EXEC SQL END DECLARE SECTION;
+</programlisting>
+ </para>
+
+ <para>
+ And after reading a value into the host variable, process it
+ using pgtypes library functions. In following example, the
+ <type>timestamp</type> value is converted into text (ASCII) form
+ with the <function>PGTYPEStimestamp_to_asc()</function>
+ function:
+<programlisting>
+EXEC SQL SELECT now()::timestamp INTO :ts;
+
+printf("ts = %s\n", PGTYPEStimestamp_to_asc(ts));
+</programlisting>
+ This example will show some result like following:
+<screen>
+ts = 2010-06-27 18:03:56.949343
+</screen>
+ </para>
+
+ <para>
+ In addition, the DATE type can be handled in the same way. The
+ program has to include <filename>pgtypes_date.h</filename>, declare a host variable
+ as the date type and convert a DATE value into a text form using
+ <function>PGTYPESdate_to_asc()</function> function. For more details about the
+ pgtypes library functions, see <xref linkend="ecpg-pgtypes"/>.
+ </para>
+ </sect4>
+
+ <sect4 id="ecpg-type-interval">
+ <title>interval</title>
+
+ <para>
+ The handling of the <type>interval</type> type is also similar
+ to the <type>timestamp</type> and <type>date</type> types. It
+ is required, however, to allocate memory for
+ an <type>interval</type> type value explicitly. In other words,
+ the memory space for the variable has to be allocated in the
+ heap memory, not in the stack memory.
+ </para>
+
+ <para>
+ Here is an example program:
+<programlisting>
+#include &lt;stdio.h>
+#include &lt;stdlib.h>
+#include &lt;pgtypes_interval.h>
+
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ interval *in;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ in = PGTYPESinterval_new();
+ EXEC SQL SELECT '1 min'::interval INTO :in;
+ printf("interval = %s\n", PGTYPESinterval_to_asc(in));
+ PGTYPESinterval_free(in);
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</programlisting>
+ </para>
+ </sect4>
+
+ <sect4 id="ecpg-type-numeric-decimal">
+ <title>numeric, decimal</title>
+
+ <para>
+ The handling of the <type>numeric</type>
+ and <type>decimal</type> types is similar to the
+ <type>interval</type> type: It requires defining a pointer,
+ allocating some memory space on the heap, and accessing the
+ variable using the pgtypes library functions. For more details
+ about the pgtypes library functions,
+ see <xref linkend="ecpg-pgtypes"/>.
+ </para>
+
+ <para>
+ No functions are provided specifically for
+ the <type>decimal</type> type. An application has to convert it
+ to a <type>numeric</type> variable using a pgtypes library
+ function to do further processing.
+ </para>
+
+ <para>
+ Here is an example program handling <type>numeric</type>
+ and <type>decimal</type> type variables.
+<programlisting>
+#include &lt;stdio.h>
+#include &lt;stdlib.h>
+#include &lt;pgtypes_numeric.h>
+
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ numeric *num;
+ numeric *num2;
+ decimal *dec;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ num = PGTYPESnumeric_new();
+ dec = PGTYPESdecimal_new();
+
+ EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;
+
+ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
+ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
+ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));
+
+ /* Convert decimal to numeric to show a decimal value. */
+ num2 = PGTYPESnumeric_new();
+ PGTYPESnumeric_from_decimal(dec, num2);
+
+ printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
+ printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
+ printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));
+
+ PGTYPESnumeric_free(num2);
+ PGTYPESdecimal_free(dec);
+ PGTYPESnumeric_free(num);
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</programlisting>
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>bytea</title>
+
+ <para>
+ The handling of the <type>bytea</type> type is similar to
+ that of <type>VARCHAR</type>. The definition on an array of type
+ <type>bytea</type> is converted into a named struct for every
+ variable. A declaration like:
+<programlisting>
+bytea var[180];
+</programlisting>
+ is converted into:
+<programlisting>
+struct bytea_var { int len; char arr[180]; } var;
+</programlisting>
+ The member <structfield>arr</structfield> hosts binary format
+ data. It can also handle <literal>'\0'</literal> as part of
+ data, unlike <type>VARCHAR</type>.
+ The data is converted from/to hex format and sent/received by
+ ecpglib.
+ </para>
+
+ <note>
+ <para>
+ <type>bytea</type> variable can be used only when
+ <xref linkend="guc-bytea-output"/> is set to <literal>hex</literal>.
+ </para>
+ </note>
+ </sect4>
+ </sect3>
+
+ <sect3 id="ecpg-variables-nonprimitive-c">
+ <title>Host Variables with Nonprimitive Types</title>
+
+ <para>
+ As a host variable you can also use arrays, typedefs, structs, and
+ pointers.
+ </para>
+
+ <sect4 id="ecpg-variables-arrays">
+ <title>Arrays</title>
+
+ <para>
+ There are two use cases for arrays as host variables. The first
+ is a way to store some text string in <type>char[]</type>
+ or <type>VARCHAR[]</type>, as
+ explained in <xref linkend="ecpg-char"/>. The second use case is to
+ retrieve multiple rows from a query result without using a
+ cursor. Without an array, to process a query result consisting
+ of multiple rows, it is required to use a cursor and
+ the <command>FETCH</command> command. But with array host
+ variables, multiple rows can be received at once. The length of
+ the array has to be defined to be able to accommodate all rows,
+ otherwise a buffer overflow will likely occur.
+ </para>
+
+ <para>
+ Following example scans the <literal>pg_database</literal>
+ system table and shows all OIDs and names of the available
+ databases:
+<programlisting>
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ int dbid[8];
+ char dbname[8][16];
+ int i;
+EXEC SQL END DECLARE SECTION;
+
+ memset(dbname, 0, sizeof(char)* 16 * 8);
+ memset(dbid, 0, sizeof(int) * 8);
+
+ EXEC SQL CONNECT TO testdb;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ /* Retrieve multiple rows into arrays at once. */
+ EXEC SQL SELECT oid,datname INTO :dbid, :dbname FROM pg_database;
+
+ for (i = 0; i &lt; 8; i++)
+ printf("oid=%d, dbname=%s\n", dbid[i], dbname[i]);
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</programlisting>
+
+ This example shows following result. (The exact values depend on
+ local circumstances.)
+<screen>
+oid=1, dbname=template1
+oid=11510, dbname=template0
+oid=11511, dbname=postgres
+oid=313780, dbname=testdb
+oid=0, dbname=
+oid=0, dbname=
+oid=0, dbname=
+</screen>
+ </para>
+ </sect4>
+
+ <sect4 id="ecpg-variables-struct">
+ <title>Structures</title>
+
+ <para>
+ A structure whose member names match the column names of a query
+ result, can be used to retrieve multiple columns at once. The
+ structure enables handling multiple column values in a single
+ host variable.
+ </para>
+
+ <para>
+ The following example retrieves OIDs, names, and sizes of the
+ available databases from the <literal>pg_database</literal>
+ system table and using
+ the <function>pg_database_size()</function> function. In this
+ example, a structure variable <varname>dbinfo_t</varname> with
+ members whose names match each column in
+ the <literal>SELECT</literal> result is used to retrieve one
+ result row without putting multiple host variables in
+ the <literal>FETCH</literal> statement.
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ typedef struct
+ {
+ int oid;
+ char datname[65];
+ long long int size;
+ } dbinfo_t;
+
+ dbinfo_t dbval;
+EXEC SQL END DECLARE SECTION;
+
+ memset(&amp;dbval, 0, sizeof(dbinfo_t));
+
+ EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size FROM pg_database;
+ EXEC SQL OPEN cur1;
+
+ /* when end of result set reached, break out of while loop */
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ /* Fetch multiple columns into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :dbval;
+
+ /* Print members of the structure. */
+ printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, dbval.size);
+ }
+
+ EXEC SQL CLOSE cur1;
+</programlisting>
+ </para>
+
+ <para>
+ This example shows following result. (The exact values depend on
+ local circumstances.)
+<screen>
+oid=1, datname=template1, size=4324580
+oid=11510, datname=template0, size=4243460
+oid=11511, datname=postgres, size=4324580
+oid=313780, datname=testdb, size=8183012
+</screen>
+ </para>
+
+ <para>
+ Structure host variables <quote>absorb</quote> as many columns
+ as the structure as fields. Additional columns can be assigned
+ to other host variables. For example, the above program could
+ also be restructured like this, with the <varname>size</varname>
+ variable outside the structure:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ typedef struct
+ {
+ int oid;
+ char datname[65];
+ } dbinfo_t;
+
+ dbinfo_t dbval;
+ long long int size;
+EXEC SQL END DECLARE SECTION;
+
+ memset(&amp;dbval, 0, sizeof(dbinfo_t));
+
+ EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size FROM pg_database;
+ EXEC SQL OPEN cur1;
+
+ /* when end of result set reached, break out of while loop */
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ /* Fetch multiple columns into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :dbval, :size;
+
+ /* Print members of the structure. */
+ printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, size);
+ }
+
+ EXEC SQL CLOSE cur1;
+</programlisting>
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>Typedefs</title>
+
+ <para>
+ Use the <literal>typedef</literal> keyword to map new types to already
+ existing types.
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ typedef char mychartype[40];
+ typedef long serial_t;
+EXEC SQL END DECLARE SECTION;
+</programlisting>
+ Note that you could also use:
+<programlisting>
+EXEC SQL TYPE serial_t IS long;
+</programlisting>
+ This declaration does not need to be part of a declare section.
+ </para>
+ </sect4>
+
+ <sect4>
+ <title>Pointers</title>
+
+ <para>
+ You can declare pointers to the most common types. Note however
+ that you cannot use pointers as target variables of queries
+ without auto-allocation. See <xref linkend="ecpg-descriptors"/>
+ for more information on auto-allocation.
+ </para>
+
+ <para>
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ int *intp;
+ char **charp;
+EXEC SQL END DECLARE SECTION;
+</programlisting>
+ </para>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2 id="ecpg-variables-nonprimitive-sql">
+ <title>Handling Nonprimitive SQL Data Types</title>
+
+ <para>
+ This section contains information on how to handle nonscalar and
+ user-defined SQL-level data types in ECPG applications. Note that
+ this is distinct from the handling of host variables of
+ nonprimitive types, described in the previous section.
+ </para>
+
+ <sect3>
+ <title>Arrays</title>
+
+ <para>
+ Multi-dimensional SQL-level arrays are not directly supported in ECPG.
+ One-dimensional SQL-level arrays can be mapped into C array host
+ variables and vice-versa. However, when creating a statement ecpg does
+ not know the types of the columns, so that it cannot check if a C array
+ is input into a corresponding SQL-level array. When processing the
+ output of an SQL statement, ecpg has the necessary information and thus
+ checks if both are arrays.
+ </para>
+
+ <para>
+ If a query accesses <emphasis>elements</emphasis> of an array
+ separately, then this avoids the use of arrays in ECPG. Then, a
+ host variable with a type that can be mapped to the element type
+ should be used. For example, if a column type is array of
+ <type>integer</type>, a host variable of type <type>int</type>
+ can be used. Also if the element type is <type>varchar</type>
+ or <type>text</type>, a host variable of type <type>char[]</type>
+ or <type>VARCHAR[]</type> can be used.
+ </para>
+
+ <para>
+ Here is an example. Assume the following table:
+<programlisting>
+CREATE TABLE t3 (
+ ii integer[]
+);
+
+testdb=&gt; SELECT * FROM t3;
+ ii
+-------------
+ {1,2,3,4,5}
+(1 row)
+</programlisting>
+
+ The following example program retrieves the 4th element of the
+ array and stores it into a host variable of
+ type <type>int</type>:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int ii;
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[4] FROM t3;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ EXEC SQL FETCH FROM cur1 INTO :ii ;
+ printf("ii=%d\n", ii);
+}
+
+EXEC SQL CLOSE cur1;
+</programlisting>
+
+ This example shows the following result:
+<screen>
+ii=4
+</screen>
+ </para>
+
+ <para>
+ To map multiple array elements to the multiple elements in an
+ array type host variables each element of array column and each
+ element of the host variable array have to be managed separately,
+ for example:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int ii_a[8];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[1], ii[2], ii[3], ii[4] FROM t3;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ EXEC SQL FETCH FROM cur1 INTO :ii_a[0], :ii_a[1], :ii_a[2], :ii_a[3];
+ ...
+}
+</programlisting>
+ </para>
+
+ <para>
+ Note again that
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int ii_a[8];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii FROM t3;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* WRONG */
+ EXEC SQL FETCH FROM cur1 INTO :ii_a;
+ ...
+}
+</programlisting>
+ would not work correctly in this case, because you cannot map an
+ array type column to an array host variable directly.
+ </para>
+
+ <para>
+ Another workaround is to store arrays in their external string
+ representation in host variables of type <type>char[]</type>
+ or <type>VARCHAR[]</type>. For more details about this
+ representation, see <xref linkend="arrays-input"/>. Note that
+ this means that the array cannot be accessed naturally as an
+ array in the host program (without further processing that parses
+ the text representation).
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Composite Types</title>
+
+ <para>
+ Composite types are not directly supported in ECPG, but an easy workaround is possible.
+ The
+ available workarounds are similar to the ones described for
+ arrays above: Either access each attribute separately or use the
+ external string representation.
+ </para>
+
+ <para>
+ For the following examples, assume the following type and table:
+<programlisting>
+CREATE TYPE comp_t AS (intval integer, textval varchar(32));
+CREATE TABLE t4 (compval comp_t);
+INSERT INTO t4 VALUES ( (256, 'PostgreSQL') );
+</programlisting>
+
+ The most obvious solution is to access each attribute separately.
+ The following program retrieves data from the example table by
+ selecting each attribute of the type <type>comp_t</type>
+ separately:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int intval;
+varchar textval[33];
+EXEC SQL END DECLARE SECTION;
+
+/* Put each element of the composite type column in the SELECT list. */
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* Fetch each element of the composite type column into host variables. */
+ EXEC SQL FETCH FROM cur1 INTO :intval, :textval;
+
+ printf("intval=%d, textval=%s\n", intval, textval.arr);
+}
+
+EXEC SQL CLOSE cur1;
+</programlisting>
+ </para>
+
+ <para>
+ To enhance this example, the host variables to store values in
+ the <command>FETCH</command> command can be gathered into one
+ structure. For more details about the host variable in the
+ structure form, see <xref linkend="ecpg-variables-struct"/>.
+ To switch to the structure, the example can be modified as below.
+ The two host variables, <varname>intval</varname>
+ and <varname>textval</varname>, become members of
+ the <structname>comp_t</structname> structure, and the structure
+ is specified on the <command>FETCH</command> command.
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+typedef struct
+{
+ int intval;
+ varchar textval[33];
+} comp_t;
+
+comp_t compval;
+EXEC SQL END DECLARE SECTION;
+
+/* Put each element of the composite type column in the SELECT list. */
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* Put all values in the SELECT list into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :compval;
+
+ printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
+}
+
+EXEC SQL CLOSE cur1;
+</programlisting>
+
+ Although a structure is used in the <command>FETCH</command>
+ command, the attribute names in the <command>SELECT</command>
+ clause are specified one by one. This can be enhanced by using
+ a <literal>*</literal> to ask for all attributes of the composite
+ type value.
+<programlisting>
+...
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).* FROM t4;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* Put all values in the SELECT list into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :compval;
+
+ printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
+}
+...
+</programlisting>
+ This way, composite types can be mapped into structures almost
+ seamlessly, even though ECPG does not understand the composite
+ type itself.
+ </para>
+
+ <para>
+ Finally, it is also possible to store composite type values in
+ their external string representation in host variables of
+ type <type>char[]</type> or <type>VARCHAR[]</type>. But that
+ way, it is not easily possible to access the fields of the value
+ from the host program.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>User-Defined Base Types</title>
+
+ <para>
+ New user-defined base types are not directly supported by ECPG.
+ You can use the external string representation and host variables
+ of type <type>char[]</type> or <type>VARCHAR[]</type>, and this
+ solution is indeed appropriate and sufficient for many types.
+ </para>
+
+ <para>
+ Here is an example using the data type <type>complex</type> from
+ the example in <xref linkend="xtypes"/>. The external string
+ representation of that type is <literal>(%f,%f)</literal>,
+ which is defined in the
+ functions <function>complex_in()</function>
+ and <function>complex_out()</function> functions
+ in <xref linkend="xtypes"/>. The following example inserts the
+ complex type values <literal>(1,1)</literal>
+ and <literal>(3,3)</literal> into the
+ columns <literal>a</literal> and <literal>b</literal>, and select
+ them from the table after that.
+
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+ varchar a[64];
+ varchar b[64];
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL INSERT INTO test_complex VALUES ('(1,1)', '(3,3)');
+
+ EXEC SQL DECLARE cur1 CURSOR FOR SELECT a, b FROM test_complex;
+ EXEC SQL OPEN cur1;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ EXEC SQL FETCH FROM cur1 INTO :a, :b;
+ printf("a=%s, b=%s\n", a.arr, b.arr);
+ }
+
+ EXEC SQL CLOSE cur1;
+</programlisting>
+
+ This example shows following result:
+<screen>
+a=(1,1), b=(3,3)
+</screen>
+ </para>
+
+ <para>
+ Another workaround is avoiding the direct use of the user-defined
+ types in ECPG and instead create a function or cast that converts
+ between the user-defined type and a primitive type that ECPG can
+ handle. Note, however, that type casts, especially implicit
+ ones, should be introduced into the type system very carefully.
+ </para>
+
+ <para>
+ For example,
+<programlisting>
+CREATE FUNCTION create_complex(r double, i double) RETURNS complex
+LANGUAGE SQL
+IMMUTABLE
+AS $$ SELECT $1 * complex '(1,0')' + $2 * complex '(0,1)' $$;
+</programlisting>
+ After this definition, the following
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+double a, b, c, d;
+EXEC SQL END DECLARE SECTION;
+
+a = 1;
+b = 2;
+c = 3;
+d = 4;
+
+EXEC SQL INSERT INTO test_complex VALUES (create_complex(:a, :b), create_complex(:c, :d));
+</programlisting>
+ has the same effect as
+<programlisting>
+EXEC SQL INSERT INTO test_complex VALUES ('(1,2)', '(3,4)');
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="ecpg-indicators">
+ <title>Indicators</title>
+
+ <para>
+ The examples above do not handle null values. In fact, the
+ retrieval examples will raise an error if they fetch a null value
+ from the database. To be able to pass null values to the database
+ or retrieve null values from the database, you need to append a
+ second host variable specification to each host variable that
+ contains data. This second host variable is called the
+ <firstterm>indicator</firstterm> and contains a flag that tells
+ whether the datum is null, in which case the value of the real
+ host variable is ignored. Here is an example that handles the
+ retrieval of null values correctly:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+VARCHAR val;
+int val_ind;
+EXEC SQL END DECLARE SECTION:
+
+ ...
+
+EXEC SQL SELECT b INTO :val :val_ind FROM test1;
+</programlisting>
+ The indicator variable <varname>val_ind</varname> will be zero if
+ the value was not null, and it will be negative if the value was
+ null. (See <xref linkend="ecpg-oracle-compat"/> to enable
+ Oracle-specific behavior.)
+ </para>
+
+ <para>
+ The indicator has another function: if the indicator value is
+ positive, it means that the value is not null, but it was
+ truncated when it was stored in the host variable.
+ </para>
+
+ <para>
+ If the argument <literal>-r no_indicator</literal> is passed to
+ the preprocessor <command>ecpg</command>, it works in
+ <quote>no-indicator</quote> mode. In no-indicator mode, if no
+ indicator variable is specified, null values are signaled (on
+ input and output) for character string types as empty string and
+ for integer types as the lowest possible value for type (for
+ example, <symbol>INT_MIN</symbol> for <type>int</type>).
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-dynamic">
+ <title>Dynamic SQL</title>
+
+ <para>
+ In many cases, the particular SQL statements that an application
+ has to execute are known at the time the application is written.
+ In some cases, however, the SQL statements are composed at run time
+ or provided by an external source. In these cases you cannot embed
+ the SQL statements directly into the C source code, but there is a
+ facility that allows you to call arbitrary SQL statements that you
+ provide in a string variable.
+ </para>
+
+ <sect2 id="ecpg-dynamic-without-result">
+ <title>Executing Statements without a Result Set</title>
+
+ <para>
+ The simplest way to execute an arbitrary SQL statement is to use
+ the command <command>EXECUTE IMMEDIATE</command>. For example:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+const char *stmt = "CREATE TABLE test1 (...);";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL EXECUTE IMMEDIATE :stmt;
+</programlisting>
+ <command>EXECUTE IMMEDIATE</command> can be used for SQL
+ statements that do not return a result set (e.g.,
+ DDL, <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>). You cannot execute statements that
+ retrieve data (e.g., <command>SELECT</command>) this way. The
+ next section describes how to do that.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-dynamic-input">
+ <title>Executing a Statement with Input Parameters</title>
+
+ <para>
+ A more powerful way to execute arbitrary SQL statements is to
+ prepare them once and execute the prepared statement as often as
+ you like. It is also possible to prepare a generalized version of
+ a statement and then execute specific versions of it by
+ substituting parameters. When preparing the statement, write
+ question marks where you want to substitute parameters later. For
+ example:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+const char *stmt = "INSERT INTO test1 VALUES(?, ?);";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE mystmt FROM :stmt;
+ ...
+EXEC SQL EXECUTE mystmt USING 42, 'foobar';
+</programlisting>
+ </para>
+
+ <para>
+ When you don't need the prepared statement anymore, you should
+ deallocate it:
+<programlisting>
+EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>;
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-dynamic-with-result">
+ <title>Executing a Statement with a Result Set</title>
+
+ <para>
+ To execute an SQL statement with a single result row,
+ <command>EXECUTE</command> can be used. To save the result, add
+ an <literal>INTO</literal> clause.
+<programlisting><![CDATA[
+EXEC SQL BEGIN DECLARE SECTION;
+const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
+int v1, v2;
+VARCHAR v3[50];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE mystmt FROM :stmt;
+ ...
+EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;
+]]>
+</programlisting>
+ An <command>EXECUTE</command> command can have an
+ <literal>INTO</literal> clause, a <literal>USING</literal> clause,
+ both, or neither.
+ </para>
+
+ <para>
+ If a query is expected to return more than one result row, a
+ cursor should be used, as in the following example.
+ (See <xref linkend="ecpg-cursors"/> for more details about the
+ cursor.)
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+char dbaname[128];
+char datname[128];
+char *stmt = "SELECT u.usename as dbaname, d.datname "
+ " FROM pg_database d, pg_user u "
+ " WHERE d.datdba = u.usesysid";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+EXEC SQL PREPARE stmt1 FROM :stmt;
+
+EXEC SQL DECLARE cursor1 CURSOR FOR stmt1;
+EXEC SQL OPEN cursor1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ EXEC SQL FETCH cursor1 INTO :dbaname,:datname;
+ printf("dbaname=%s, datname=%s\n", dbaname, datname);
+}
+
+EXEC SQL CLOSE cursor1;
+
+EXEC SQL COMMIT;
+EXEC SQL DISCONNECT ALL;
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-pgtypes">
+ <title>pgtypes Library</title>
+
+ <para>
+ The pgtypes library maps <productname>PostgreSQL</productname> database
+ types to C equivalents that can be used in C programs. It also offers
+ functions to do basic calculations with those types within C, i.e., without
+ the help of the <productname>PostgreSQL</productname> server. See the
+ following example:
+<programlisting><![CDATA[
+EXEC SQL BEGIN DECLARE SECTION;
+ date date1;
+ timestamp ts1, tsout;
+ interval iv1;
+ char *out;
+EXEC SQL END DECLARE SECTION;
+
+PGTYPESdate_today(&date1);
+EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
+PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout);
+out = PGTYPEStimestamp_to_asc(&tsout);
+printf("Started + duration: %s\n", out);
+PGTYPESchar_free(out);
+]]>
+</programlisting>
+ </para>
+
+ <sect2 id="ecpg-pgtypes-cstrings">
+ <title>Character Strings</title>
+ <para>
+ Some functions such as <function>PGTYPESnumeric_to_asc</function> return
+ a pointer to a freshly allocated character string. These results should be
+ freed with <function>PGTYPESchar_free</function> instead of
+ <function>free</function>. (This is important only on Windows, where
+ memory allocation and release sometimes need to be done by the same
+ library.)
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-numeric">
+ <title>The numeric Type</title>
+ <para>
+ The numeric type offers to do calculations with arbitrary precision. See
+ <xref linkend="datatype-numeric"/> for the equivalent type in the
+ <productname>PostgreSQL</productname> server. Because of the arbitrary precision this
+ variable needs to be able to expand and shrink dynamically. That's why you
+ can only create numeric variables on the heap, by means of the
+ <function>PGTYPESnumeric_new</function> and <function>PGTYPESnumeric_free</function>
+ functions. The decimal type, which is similar but limited in precision,
+ can be created on the stack as well as on the heap.
+ </para>
+ <para>
+ The following functions can be used to work with the numeric type:
+ <variablelist>
+ <varlistentry>
+ <term><function>PGTYPESnumeric_new</function></term>
+ <listitem>
+ <para>
+ Request a pointer to a newly allocated numeric variable.
+<synopsis>
+numeric *PGTYPESnumeric_new(void);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_free</function></term>
+ <listitem>
+ <para>
+ Free a numeric type, release all of its memory.
+<synopsis>
+void PGTYPESnumeric_free(numeric *var);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_from_asc</function></term>
+ <listitem>
+ <para>
+ Parse a numeric type from its string notation.
+<synopsis>
+numeric *PGTYPESnumeric_from_asc(char *str, char **endptr);
+</synopsis>
+ Valid formats are for example:
+ <literal>-2</literal>,
+ <literal>.794</literal>,
+ <literal>+3.44</literal>,
+ <literal>592.49E07</literal> or
+ <literal>-32.84e-4</literal>.
+ If the value could be parsed successfully, a valid pointer is returned,
+ else the NULL pointer. At the moment ECPG always parses the complete
+ string and so it currently does not support to store the address of the
+ first invalid character in <literal>*endptr</literal>. You can safely
+ set <literal>endptr</literal> to NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_to_asc</function></term>
+ <listitem>
+ <para>
+ Returns a pointer to a string allocated by <function>malloc</function> that contains the string
+ representation of the numeric type <literal>num</literal>.
+<synopsis>
+char *PGTYPESnumeric_to_asc(numeric *num, int dscale);
+</synopsis>
+ The numeric value will be printed with <literal>dscale</literal> decimal
+ digits, with rounding applied if necessary.
+ The result must be freed with <function>PGTYPESchar_free()</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_add</function></term>
+ <listitem>
+ <para>
+ Add two numeric variables into a third one.
+<synopsis>
+int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result);
+</synopsis>
+ The function adds the variables <literal>var1</literal> and
+ <literal>var2</literal> into the result variable
+ <literal>result</literal>.
+ The function returns 0 on success and -1 in case of error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_sub</function></term>
+ <listitem>
+ <para>
+ Subtract two numeric variables and return the result in a third one.
+<synopsis>
+int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result);
+</synopsis>
+ The function subtracts the variable <literal>var2</literal> from
+ the variable <literal>var1</literal>. The result of the operation is
+ stored in the variable <literal>result</literal>.
+ The function returns 0 on success and -1 in case of error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_mul</function></term>
+ <listitem>
+ <para>
+ Multiply two numeric variables and return the result in a third one.
+<synopsis>
+int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result);
+</synopsis>
+ The function multiplies the variables <literal>var1</literal> and
+ <literal>var2</literal>. The result of the operation is stored in the
+ variable <literal>result</literal>.
+ The function returns 0 on success and -1 in case of error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_div</function></term>
+ <listitem>
+ <para>
+ Divide two numeric variables and return the result in a third one.
+<synopsis>
+int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result);
+</synopsis>
+ The function divides the variables <literal>var1</literal> by
+ <literal>var2</literal>. The result of the operation is stored in the
+ variable <literal>result</literal>.
+ The function returns 0 on success and -1 in case of error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_cmp</function></term>
+ <listitem>
+ <para>
+ Compare two numeric variables.
+<synopsis>
+int PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
+</synopsis>
+ This function compares two numeric variables. In case of error,
+ <literal>INT_MAX</literal> is returned. On success, the function
+ returns one of three possible results:
+ <itemizedlist>
+ <listitem>
+ <para>
+ 1, if <literal>var1</literal> is bigger than <literal>var2</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ -1, if <literal>var1</literal> is smaller than <literal>var2</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 0, if <literal>var1</literal> and <literal>var2</literal> are equal
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_from_int</function></term>
+ <listitem>
+ <para>
+ Convert an int variable to a numeric variable.
+<synopsis>
+int PGTYPESnumeric_from_int(signed int int_val, numeric *var);
+</synopsis>
+ This function accepts a variable of type signed int and stores it
+ in the numeric variable <literal>var</literal>. Upon success, 0 is returned and
+ -1 in case of a failure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_from_long</function></term>
+ <listitem>
+ <para>
+ Convert a long int variable to a numeric variable.
+<synopsis>
+int PGTYPESnumeric_from_long(signed long int long_val, numeric *var);
+</synopsis>
+ This function accepts a variable of type signed long int and stores it
+ in the numeric variable <literal>var</literal>. Upon success, 0 is returned and
+ -1 in case of a failure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_copy</function></term>
+ <listitem>
+ <para>
+ Copy over one numeric variable into another one.
+<synopsis>
+int PGTYPESnumeric_copy(numeric *src, numeric *dst);
+</synopsis>
+ This function copies over the value of the variable that
+ <literal>src</literal> points to into the variable that <literal>dst</literal>
+ points to. It returns 0 on success and -1 if an error occurs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_from_double</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type double to a numeric.
+<synopsis>
+int PGTYPESnumeric_from_double(double d, numeric *dst);
+</synopsis>
+ This function accepts a variable of type double and stores the result
+ in the variable that <literal>dst</literal> points to. It returns 0 on success
+ and -1 if an error occurs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_to_double</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type numeric to double.
+<synopsis>
+int PGTYPESnumeric_to_double(numeric *nv, double *dp)
+</synopsis>
+ The function converts the numeric value from the variable that
+ <literal>nv</literal> points to into the double variable that <literal>dp</literal> points
+ to. It returns 0 on success and -1 if an error occurs, including
+ overflow. On overflow, the global variable <literal>errno</literal> will be set
+ to <literal>PGTYPES_NUM_OVERFLOW</literal> additionally.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_to_int</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type numeric to int.
+<synopsis>
+int PGTYPESnumeric_to_int(numeric *nv, int *ip);
+</synopsis>
+ The function converts the numeric value from the variable that
+ <literal>nv</literal> points to into the integer variable that <literal>ip</literal>
+ points to. It returns 0 on success and -1 if an error occurs, including
+ overflow. On overflow, the global variable <literal>errno</literal> will be set
+ to <literal>PGTYPES_NUM_OVERFLOW</literal> additionally.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_to_long</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type numeric to long.
+<synopsis>
+int PGTYPESnumeric_to_long(numeric *nv, long *lp);
+</synopsis>
+ The function converts the numeric value from the variable that
+ <literal>nv</literal> points to into the long integer variable that
+ <literal>lp</literal> points to. It returns 0 on success and -1 if an error
+ occurs, including overflow. On overflow, the global variable
+ <literal>errno</literal> will be set to <literal>PGTYPES_NUM_OVERFLOW</literal>
+ additionally.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_to_decimal</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type numeric to decimal.
+<synopsis>
+int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst);
+</synopsis>
+ The function converts the numeric value from the variable that
+ <literal>src</literal> points to into the decimal variable that
+ <literal>dst</literal> points to. It returns 0 on success and -1 if an error
+ occurs, including overflow. On overflow, the global variable
+ <literal>errno</literal> will be set to <literal>PGTYPES_NUM_OVERFLOW</literal>
+ additionally.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESnumeric_from_decimal</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type decimal to numeric.
+<synopsis>
+int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst);
+</synopsis>
+ The function converts the decimal value from the variable that
+ <literal>src</literal> points to into the numeric variable that
+ <literal>dst</literal> points to. It returns 0 on success and -1 if an error
+ occurs. Since the decimal type is implemented as a limited version of
+ the numeric type, overflow cannot occur with this conversion.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-date">
+ <title>The date Type</title>
+ <para>
+ The date type in C enables your programs to deal with data of the SQL type
+ date. See <xref linkend="datatype-datetime"/> for the equivalent type in the
+ <productname>PostgreSQL</productname> server.
+ </para>
+ <para>
+ The following functions can be used to work with the date type:
+ <variablelist>
+ <varlistentry id="pgtypesdatefromtimestamp">
+ <term><function>PGTYPESdate_from_timestamp</function></term>
+ <listitem>
+ <para>
+ Extract the date part from a timestamp.
+<synopsis>
+date PGTYPESdate_from_timestamp(timestamp dt);
+</synopsis>
+ The function receives a timestamp as its only argument and returns the
+ extracted date part from this timestamp.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatefromasc">
+ <term><function>PGTYPESdate_from_asc</function></term>
+ <listitem>
+ <para>
+ Parse a date from its textual representation.
+<synopsis>
+date PGTYPESdate_from_asc(char *str, char **endptr);
+</synopsis>
+ The function receives a C char* string <literal>str</literal> and a pointer to
+ a C char* string <literal>endptr</literal>. At the moment ECPG always parses
+ the complete string and so it currently does not support to store the
+ address of the first invalid character in <literal>*endptr</literal>.
+ You can safely set <literal>endptr</literal> to NULL.
+ </para>
+ <para>
+ Note that the function always assumes MDY-formatted dates and there is
+ currently no variable to change that within ECPG.
+ </para>
+ <para>
+ <xref linkend="ecpg-pgtypesdate-from-asc-table"/> shows the allowed input formats.
+ </para>
+ <table id="ecpg-pgtypesdate-from-asc-table">
+ <title>Valid Input Formats for <function>PGTYPESdate_from_asc</function></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Input</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>January 8, 1999</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1999-01-08</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1/8/1999</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1/18/1999</literal></entry>
+ <entry><literal>January 18, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>01/02/03</literal></entry>
+ <entry><literal>February 1, 2003</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1999-Jan-08</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>Jan-08-1999</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>08-Jan-1999</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>99-Jan-08</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>08-Jan-99</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>08-Jan-06</literal></entry>
+ <entry><literal>January 8, 2006</literal></entry>
+ </row>
+ <row>
+ <entry><literal>Jan-08-99</literal></entry>
+ <entry><literal>January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>19990108</literal></entry>
+ <entry><literal>ISO 8601; January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>990108</literal></entry>
+ <entry><literal>ISO 8601; January 8, 1999</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1999.008</literal></entry>
+ <entry><literal>year and day of year</literal></entry>
+ </row>
+ <row>
+ <entry><literal>J2451187</literal></entry>
+ <entry><literal>Julian day</literal></entry>
+ </row>
+ <row>
+ <entry><literal>January 8, 99 BC</literal></entry>
+ <entry><literal>year 99 before the Common Era</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatetoasc">
+ <term><function>PGTYPESdate_to_asc</function></term>
+ <listitem>
+ <para>
+ Return the textual representation of a date variable.
+<synopsis>
+char *PGTYPESdate_to_asc(date dDate);
+</synopsis>
+ The function receives the date <literal>dDate</literal> as its only parameter.
+ It will output the date in the form <literal>1999-01-18</literal>, i.e., in the
+ <literal>YYYY-MM-DD</literal> format.
+ The result must be freed with <function>PGTYPESchar_free()</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatejulmdy">
+ <term><function>PGTYPESdate_julmdy</function></term>
+ <listitem>
+ <para>
+ Extract the values for the day, the month and the year from a variable
+ of type date.
+<synopsis>
+void PGTYPESdate_julmdy(date d, int *mdy);
+</synopsis>
+ <!-- almost same description as for rjulmdy() -->
+ The function receives the date <literal>d</literal> and a pointer to an array
+ of 3 integer values <literal>mdy</literal>. The variable name indicates
+ the sequential order: <literal>mdy[0]</literal> will be set to contain the
+ number of the month, <literal>mdy[1]</literal> will be set to the value of the
+ day and <literal>mdy[2]</literal> will contain the year.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatemdyjul">
+ <term><function>PGTYPESdate_mdyjul</function></term>
+ <listitem>
+ <para>
+ Create a date value from an array of 3 integers that specify the
+ day, the month and the year of the date.
+<synopsis>
+void PGTYPESdate_mdyjul(int *mdy, date *jdate);
+</synopsis>
+ The function receives the array of the 3 integers (<literal>mdy</literal>) as
+ its first argument and as its second argument a pointer to a variable
+ of type date that should hold the result of the operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatedayofweek">
+ <term><function>PGTYPESdate_dayofweek</function></term>
+ <listitem>
+ <para>
+ Return a number representing the day of the week for a date value.
+<synopsis>
+int PGTYPESdate_dayofweek(date d);
+</synopsis>
+ The function receives the date variable <literal>d</literal> as its only
+ argument and returns an integer that indicates the day of the week for
+ this date.
+ <itemizedlist>
+ <listitem>
+ <para>
+ 0 - Sunday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 1 - Monday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 2 - Tuesday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 3 - Wednesday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 4 - Thursday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 5 - Friday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 6 - Saturday
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatetoday">
+ <term><function>PGTYPESdate_today</function></term>
+ <listitem>
+ <para>
+ Get the current date.
+<synopsis>
+void PGTYPESdate_today(date *d);
+</synopsis>
+ The function receives a pointer to a date variable (<literal>d</literal>)
+ that it sets to the current date.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatefmtasc">
+ <term><function>PGTYPESdate_fmt_asc</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type date to its textual representation using a
+ format mask.
+<synopsis>
+int PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf);
+</synopsis>
+ The function receives the date to convert (<literal>dDate</literal>), the
+ format mask (<literal>fmtstring</literal>) and the string that will hold the
+ textual representation of the date (<literal>outbuf</literal>).
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if an error occurred.
+ </para>
+ <para>
+ The following literals are the field specifiers you can use:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>dd</literal> - The number of the day of the month.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>mm</literal> - The number of the month of the year.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>yy</literal> - The number of the year as a two digit number.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>yyyy</literal> - The number of the year as a four digit number.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ddd</literal> - The name of the day (abbreviated).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>mmm</literal> - The name of the month (abbreviated).
+ </para>
+ </listitem>
+ </itemizedlist>
+ All other characters are copied 1:1 to the output string.
+ </para>
+ <para>
+ <xref linkend="ecpg-pgtypesdate-fmt-asc-example-table"/> indicates a few possible formats. This will give
+ you an idea of how to use this function. All output lines are based on
+ the same date: November 23, 1959.
+ </para>
+ <table id="ecpg-pgtypesdate-fmt-asc-example-table">
+ <title>Valid Input Formats for <function>PGTYPESdate_fmt_asc</function></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Format</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>mmddyy</literal></entry>
+ <entry><literal>112359</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ddmmyy</literal></entry>
+ <entry><literal>231159</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yymmdd</literal></entry>
+ <entry><literal>591123</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yy/mm/dd</literal></entry>
+ <entry><literal>59/11/23</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yy mm dd</literal></entry>
+ <entry><literal>59 11 23</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yy.mm.dd</literal></entry>
+ <entry><literal>59.11.23</literal></entry>
+ </row>
+ <row>
+ <entry><literal>.mm.yyyy.dd.</literal></entry>
+ <entry><literal>.11.1959.23.</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmm. dd, yyyy</literal></entry>
+ <entry><literal>Nov. 23, 1959</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmm dd yyyy</literal></entry>
+ <entry><literal>Nov 23 1959</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yyyy dd mm</literal></entry>
+ <entry><literal>1959 23 11</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ddd, mmm. dd, yyyy</literal></entry>
+ <entry><literal>Mon, Nov. 23, 1959</literal></entry>
+ </row>
+ <row>
+ <entry><literal>(ddd) mmm. dd, yyyy</literal></entry>
+ <entry><literal>(Mon) Nov. 23, 1959</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesdatedefmtasc">
+ <term><function>PGTYPESdate_defmt_asc</function></term>
+ <listitem>
+ <para>
+ Use a format mask to convert a C <type>char*</type> string to a value of type
+ date.
+<synopsis>
+int PGTYPESdate_defmt_asc(date *d, char *fmt, char *str);
+</synopsis>
+ <!-- same description as rdefmtdate -->
+ The function receives a pointer to the date value that should hold the
+ result of the operation (<literal>d</literal>), the format mask to use for
+ parsing the date (<literal>fmt</literal>) and the C char* string containing
+ the textual representation of the date (<literal>str</literal>). The textual
+ representation is expected to match the format mask. However you do not
+ need to have a 1:1 mapping of the string to the format mask. The
+ function only analyzes the sequential order and looks for the literals
+ <literal>yy</literal> or <literal>yyyy</literal> that indicate the
+ position of the year, <literal>mm</literal> to indicate the position of
+ the month and <literal>dd</literal> to indicate the position of the
+ day.
+ </para>
+ <para>
+ <xref linkend="ecpg-rdefmtdate-example-table"/> indicates a few possible formats. This will give
+ you an idea of how to use this function.
+ </para>
+ <table id="ecpg-rdefmtdate-example-table">
+ <title>Valid Input Formats for <function>rdefmtdate</function></title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Format</entry>
+ <entry>String</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>ddmmyy</literal></entry>
+ <entry><literal>21-2-54</literal></entry>
+ <entry><literal>1954-02-21</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ddmmyy</literal></entry>
+ <entry><literal>2-12-54</literal></entry>
+ <entry><literal>1954-12-02</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ddmmyy</literal></entry>
+ <entry><literal>20111954</literal></entry>
+ <entry><literal>1954-11-20</literal></entry>
+ </row>
+ <row>
+ <entry><literal>ddmmyy</literal></entry>
+ <entry><literal>130464</literal></entry>
+ <entry><literal>1964-04-13</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmm.dd.yyyy</literal></entry>
+ <entry><literal>MAR-12-1967</literal></entry>
+ <entry><literal>1967-03-12</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yy/mm/dd</literal></entry>
+ <entry><literal>1954, February 3rd</literal></entry>
+ <entry><literal>1954-02-03</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmm.dd.yyyy</literal></entry>
+ <entry><literal>041269</literal></entry>
+ <entry><literal>1969-04-12</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yy/mm/dd</literal></entry>
+ <entry><literal>In the year 2525, in the month of July, mankind will be alive on the 28th day</literal></entry>
+ <entry><literal>2525-07-28</literal></entry>
+ </row>
+ <row>
+ <entry><literal>dd-mm-yy</literal></entry>
+ <entry><literal>I said on the 28th of July in the year 2525</literal></entry>
+ <entry><literal>2525-07-28</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmm.dd.yyyy</literal></entry>
+ <entry><literal>9/14/58</literal></entry>
+ <entry><literal>1958-09-14</literal></entry>
+ </row>
+ <row>
+ <entry><literal>yy/mm/dd</literal></entry>
+ <entry><literal>47/03/29</literal></entry>
+ <entry><literal>1947-03-29</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmm.dd.yyyy</literal></entry>
+ <entry><literal>oct 28 1975</literal></entry>
+ <entry><literal>1975-10-28</literal></entry>
+ </row>
+ <row>
+ <entry><literal>mmddyy</literal></entry>
+ <entry><literal>Nov 14th, 1985</literal></entry>
+ <entry><literal>1985-11-14</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-timestamp">
+ <title>The timestamp Type</title>
+ <para>
+ The timestamp type in C enables your programs to deal with data of the SQL
+ type timestamp. See <xref linkend="datatype-datetime"/> for the equivalent
+ type in the <productname>PostgreSQL</productname> server.
+ </para>
+ <para>
+ The following functions can be used to work with the timestamp type:
+ <variablelist>
+ <varlistentry id="pgtypestimestampfromasc">
+ <term><function>PGTYPEStimestamp_from_asc</function></term>
+ <listitem>
+ <para>
+ Parse a timestamp from its textual representation into a timestamp
+ variable.
+<synopsis>
+timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr);
+</synopsis>
+ The function receives the string to parse (<literal>str</literal>) and a
+ pointer to a C char* (<literal>endptr</literal>).
+ At the moment ECPG always parses
+ the complete string and so it currently does not support to store the
+ address of the first invalid character in <literal>*endptr</literal>.
+ You can safely set <literal>endptr</literal> to NULL.
+ </para>
+ <para>
+ The function returns the parsed timestamp on success. On error,
+ <literal>PGTYPESInvalidTimestamp</literal> is returned and <varname>errno</varname> is
+ set to <literal>PGTYPES_TS_BAD_TIMESTAMP</literal>. See <xref linkend="pgtypesinvalidtimestamp"/> for important notes on this value.
+ </para>
+ <para>
+ In general, the input string can contain any combination of an allowed
+ date specification, a whitespace character and an allowed time
+ specification. Note that time zones are not supported by ECPG. It can
+ parse them but does not apply any calculation as the
+ <productname>PostgreSQL</productname> server does for example. Timezone
+ specifiers are silently discarded.
+ </para>
+ <para>
+ <xref linkend="ecpg-pgtypestimestamp-from-asc-example-table"/> contains a few examples for input strings.
+ </para>
+ <table id="ecpg-pgtypestimestamp-from-asc-example-table">
+ <title>Valid Input Formats for <function>PGTYPEStimestamp_from_asc</function></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Input</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>1999-01-08 04:05:06</literal></entry>
+ <entry><literal>1999-01-08 04:05:06</literal></entry>
+ </row>
+ <row>
+ <entry><literal>January 8 04:05:06 1999 PST</literal></entry>
+ <entry><literal>1999-01-08 04:05:06</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1999-Jan-08 04:05:06.789-8</literal></entry>
+ <entry><literal>1999-01-08 04:05:06.789 (time zone specifier ignored)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>J2451187 04:05-08:00</literal></entry>
+ <entry><literal>1999-01-08 04:05:00 (time zone specifier ignored)</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestamptoasc">
+ <term><function>PGTYPEStimestamp_to_asc</function></term>
+ <listitem>
+ <para>
+ Converts a date to a C char* string.
+<synopsis>
+char *PGTYPEStimestamp_to_asc(timestamp tstamp);
+</synopsis>
+ The function receives the timestamp <literal>tstamp</literal> as
+ its only argument and returns an allocated string that contains the
+ textual representation of the timestamp.
+ The result must be freed with <function>PGTYPESchar_free()</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestampcurrent">
+ <term><function>PGTYPEStimestamp_current</function></term>
+ <listitem>
+ <para>
+ Retrieve the current timestamp.
+<synopsis>
+void PGTYPEStimestamp_current(timestamp *ts);
+</synopsis>
+ The function retrieves the current timestamp and saves it into the
+ timestamp variable that <literal>ts</literal> points to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestampfmtasc">
+ <term><function>PGTYPEStimestamp_fmt_asc</function></term>
+ <listitem>
+ <para>
+ Convert a timestamp variable to a C char* using a format mask.
+<synopsis>
+int PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr);
+</synopsis>
+ The function receives a pointer to the timestamp to convert as its
+ first argument (<literal>ts</literal>), a pointer to the output buffer
+ (<literal>output</literal>), the maximal length that has been allocated for
+ the output buffer (<literal>str_len</literal>) and the format mask to
+ use for the conversion (<literal>fmtstr</literal>).
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ <para>
+ You can use the following format specifiers for the format mask. The
+ format specifiers are the same ones that are used in the
+ <function>strftime</function> function in <productname>libc</productname>. Any
+ non-format specifier will be copied into the output buffer.
+ <!-- This is from the FreeBSD man page:
+ http://www.freebsd.org/cgi/man.cgi?query=strftime&apropos=0&sektion=3&manpath=FreeBSD+7.0-current&format=html
+ -->
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>%A</literal> - is replaced by national representation of
+ the full weekday name.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%a</literal> - is replaced by national representation of
+ the abbreviated weekday name.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%B</literal> - is replaced by national representation of
+ the full month name.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%b</literal> - is replaced by national representation of
+ the abbreviated month name.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%C</literal> - is replaced by (year / 100) as decimal
+ number; single digits are preceded by a zero.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%c</literal> - is replaced by national representation of
+ time and date.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%D</literal> - is equivalent to
+ <literal>%m/%d/%y</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%d</literal> - is replaced by the day of the month as a
+ decimal number (01&ndash;31).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%E*</literal> <literal>%O*</literal> - POSIX locale
+ extensions. The sequences
+ <literal>%Ec</literal>
+ <literal>%EC</literal>
+ <literal>%Ex</literal>
+ <literal>%EX</literal>
+ <literal>%Ey</literal>
+ <literal>%EY</literal>
+ <literal>%Od</literal>
+ <literal>%Oe</literal>
+ <literal>%OH</literal>
+ <literal>%OI</literal>
+ <literal>%Om</literal>
+ <literal>%OM</literal>
+ <literal>%OS</literal>
+ <literal>%Ou</literal>
+ <literal>%OU</literal>
+ <literal>%OV</literal>
+ <literal>%Ow</literal>
+ <literal>%OW</literal>
+ <literal>%Oy</literal>
+ are supposed to provide alternative representations.
+ </para>
+ <para>
+ Additionally <literal>%OB</literal> implemented to represent
+ alternative months names (used standalone, without day mentioned).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%e</literal> - is replaced by the day of month as a decimal
+ number (1&ndash;31); single digits are preceded by a blank.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%F</literal> - is equivalent to <literal>%Y-%m-%d</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%G</literal> - is replaced by a year as a decimal number
+ with century. This year is the one that contains the greater part of
+ the week (Monday as the first day of the week).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%g</literal> - is replaced by the same year as in
+ <literal>%G</literal>, but as a decimal number without century
+ (00&ndash;99).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%H</literal> - is replaced by the hour (24-hour clock) as a
+ decimal number (00&ndash;23).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%h</literal> - the same as <literal>%b</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%I</literal> - is replaced by the hour (12-hour clock) as a
+ decimal number (01&ndash;12).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%j</literal> - is replaced by the day of the year as a
+ decimal number (001&ndash;366).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%k</literal> - is replaced by the hour (24-hour clock) as a
+ decimal number (0&ndash;23); single digits are preceded by a blank.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%l</literal> - is replaced by the hour (12-hour clock) as a
+ decimal number (1&ndash;12); single digits are preceded by a blank.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%M</literal> - is replaced by the minute as a decimal
+ number (00&ndash;59).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%m</literal> - is replaced by the month as a decimal number
+ (01&ndash;12).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%n</literal> - is replaced by a newline.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%O*</literal> - the same as <literal>%E*</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%p</literal> - is replaced by national representation of
+ either <quote>ante meridiem</quote> or <quote>post meridiem</quote> as appropriate.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%R</literal> - is equivalent to <literal>%H:%M</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%r</literal> - is equivalent to <literal>%I:%M:%S
+ %p</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%S</literal> - is replaced by the second as a decimal
+ number (00&ndash;60).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%s</literal> - is replaced by the number of seconds since
+ the Epoch, UTC.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%T</literal> - is equivalent to <literal>%H:%M:%S</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%t</literal> - is replaced by a tab.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%U</literal> - is replaced by the week number of the year
+ (Sunday as the first day of the week) as a decimal number (00&ndash;53).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%u</literal> - is replaced by the weekday (Monday as the
+ first day of the week) as a decimal number (1&ndash;7).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%V</literal> - is replaced by the week number of the year
+ (Monday as the first day of the week) as a decimal number (01&ndash;53).
+ If the week containing January 1 has four or more days in the new
+ year, then it is week 1; otherwise it is the last week of the
+ previous year, and the next week is week 1.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%v</literal> - is equivalent to
+ <literal>%e-%b-%Y</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%W</literal> - is replaced by the week number of the year
+ (Monday as the first day of the week) as a decimal number (00&ndash;53).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%w</literal> - is replaced by the weekday (Sunday as the
+ first day of the week) as a decimal number (0&ndash;6).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%X</literal> - is replaced by national representation of
+ the time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%x</literal> - is replaced by national representation of
+ the date.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%Y</literal> - is replaced by the year with century as a
+ decimal number.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%y</literal> - is replaced by the year without century as a
+ decimal number (00&ndash;99).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%Z</literal> - is replaced by the time zone name.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%z</literal> - is replaced by the time zone offset from
+ UTC; a leading plus sign stands for east of UTC, a minus sign for
+ west of UTC, hours and minutes follow with two digits each and no
+ delimiter between them (common form for <ulink url="https://tools.ietf.org/html/rfc822">RFC 822</ulink> date headers).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%+</literal> - is replaced by national representation of
+ the date and time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%-*</literal> - GNU libc extension. Do not do any padding
+ when performing numerical outputs.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ $_* - GNU libc extension. Explicitly specify space for padding.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%0*</literal> - GNU libc extension. Explicitly specify zero
+ for padding.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>%%</literal> - is replaced by <literal>%</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestampsub">
+ <term><function>PGTYPEStimestamp_sub</function></term>
+ <listitem>
+ <para>
+ Subtract one timestamp from another one and save the result in a
+ variable of type interval.
+<synopsis>
+int PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv);
+</synopsis>
+ The function will subtract the timestamp variable that <literal>ts2</literal>
+ points to from the timestamp variable that <literal>ts1</literal> points to
+ and will store the result in the interval variable that <literal>iv</literal>
+ points to.
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestampdefmtasc">
+ <term><function>PGTYPEStimestamp_defmt_asc</function></term>
+ <listitem>
+ <para>
+ Parse a timestamp value from its textual representation using a
+ formatting mask.
+<synopsis>
+int PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d);
+</synopsis>
+ The function receives the textual representation of a timestamp in the
+ variable <literal>str</literal> as well as the formatting mask to use in the
+ variable <literal>fmt</literal>. The result will be stored in the variable
+ that <literal>d</literal> points to.
+ </para>
+ <para>
+ If the formatting mask <literal>fmt</literal> is NULL, the function will fall
+ back to the default formatting mask which is <literal>%Y-%m-%d
+ %H:%M:%S</literal>.
+ </para>
+ <para>
+ This is the reverse function to <xref
+ linkend="pgtypestimestampfmtasc"/>. See the documentation there in
+ order to find out about the possible formatting mask entries.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestampaddinterval">
+ <term><function>PGTYPEStimestamp_add_interval</function></term>
+ <listitem>
+ <para>
+ Add an interval variable to a timestamp variable.
+<synopsis>
+int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout);
+</synopsis>
+ The function receives a pointer to a timestamp variable <literal>tin</literal>
+ and a pointer to an interval variable <literal>span</literal>. It adds the
+ interval to the timestamp and saves the resulting timestamp in the
+ variable that <literal>tout</literal> points to.
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypestimestampsubinterval">
+ <term><function>PGTYPEStimestamp_sub_interval</function></term>
+ <listitem>
+ <para>
+ Subtract an interval variable from a timestamp variable.
+<synopsis>
+int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout);
+</synopsis>
+ The function subtracts the interval variable that <literal>span</literal>
+ points to from the timestamp variable that <literal>tin</literal> points to
+ and saves the result into the variable that <literal>tout</literal> points
+ to.
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-interval">
+ <title>The interval Type</title>
+ <para>
+ The interval type in C enables your programs to deal with data of the SQL
+ type interval. See <xref linkend="datatype-datetime"/> for the equivalent
+ type in the <productname>PostgreSQL</productname> server.
+ </para>
+ <para>
+ The following functions can be used to work with the interval type:
+ <variablelist>
+
+ <varlistentry id="pgtypesintervalnew">
+ <term><function>PGTYPESinterval_new</function></term>
+ <listitem>
+ <para>
+ Return a pointer to a newly allocated interval variable.
+<synopsis>
+interval *PGTYPESinterval_new(void);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesintervalfree">
+ <term><function>PGTYPESinterval_free</function></term>
+ <listitem>
+ <para>
+ Release the memory of a previously allocated interval variable.
+<synopsis>
+void PGTYPESinterval_free(interval *intvl);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesintervalfromasc">
+ <term><function>PGTYPESinterval_from_asc</function></term>
+ <listitem>
+ <para>
+ Parse an interval from its textual representation.
+<synopsis>
+interval *PGTYPESinterval_from_asc(char *str, char **endptr);
+</synopsis>
+ The function parses the input string <literal>str</literal> and returns a
+ pointer to an allocated interval variable.
+ At the moment ECPG always parses
+ the complete string and so it currently does not support to store the
+ address of the first invalid character in <literal>*endptr</literal>.
+ You can safely set <literal>endptr</literal> to NULL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesintervaltoasc">
+ <term><function>PGTYPESinterval_to_asc</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type interval to its textual representation.
+<synopsis>
+char *PGTYPESinterval_to_asc(interval *span);
+</synopsis>
+ The function converts the interval variable that <literal>span</literal>
+ points to into a C char*. The output looks like this example:
+ <literal>@ 1 day 12 hours 59 mins 10 secs</literal>.
+ The result must be freed with <function>PGTYPESchar_free()</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="pgtypesintervalcopy">
+ <term><function>PGTYPESinterval_copy</function></term>
+ <listitem>
+ <para>
+ Copy a variable of type interval.
+<synopsis>
+int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest);
+</synopsis>
+ The function copies the interval variable that <literal>intvlsrc</literal>
+ points to into the variable that <literal>intvldest</literal> points to. Note
+ that you need to allocate the memory for the destination variable
+ before.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-decimal">
+ <title>The decimal Type</title>
+ <para>
+ The decimal type is similar to the numeric type. However it is limited to
+ a maximum precision of 30 significant digits. In contrast to the numeric
+ type which can be created on the heap only, the decimal type can be
+ created either on the stack or on the heap (by means of the functions
+ <function>PGTYPESdecimal_new</function> and
+ <function>PGTYPESdecimal_free</function>).
+ There are a lot of other functions that deal with the decimal type in the
+ <productname>Informix</productname> compatibility mode described in <xref
+ linkend="ecpg-informix-compat"/>.
+ </para>
+ <para>
+ The following functions can be used to work with the decimal type and are
+ not only contained in the <literal>libcompat</literal> library.
+ <variablelist>
+ <varlistentry>
+ <term><function>PGTYPESdecimal_new</function></term>
+ <listitem>
+ <para>
+ Request a pointer to a newly allocated decimal variable.
+<synopsis>
+decimal *PGTYPESdecimal_new(void);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>PGTYPESdecimal_free</function></term>
+ <listitem>
+ <para>
+ Free a decimal type, release all of its memory.
+<synopsis>
+void PGTYPESdecimal_free(decimal *var);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-errno">
+ <title>errno Values of pgtypeslib</title>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>PGTYPES_NUM_BAD_NUMERIC</literal></term>
+ <listitem>
+ <para>
+ An argument should contain a numeric variable (or point to a numeric
+ variable) but in fact its in-memory representation was invalid.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_NUM_OVERFLOW</literal></term>
+ <listitem>
+ <para>
+ An overflow occurred. Since the numeric type can deal with almost
+ arbitrary precision, converting a numeric variable into other types
+ might cause overflow.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_NUM_UNDERFLOW</literal></term>
+ <listitem>
+ <para>
+ An underflow occurred. Since the numeric type can deal with almost
+ arbitrary precision, converting a numeric variable into other types
+ might cause underflow.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_NUM_DIVIDE_ZERO</literal></term>
+ <listitem>
+ <para>
+ A division by zero has been attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_DATE_BAD_DATE</literal></term>
+ <listitem>
+ <para>
+ An invalid date string was passed to
+ the <function>PGTYPESdate_from_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_DATE_ERR_EARGS</literal></term>
+ <listitem>
+ <para>
+ Invalid arguments were passed to the
+ <function>PGTYPESdate_defmt_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_DATE_ERR_ENOSHORTDATE</literal></term>
+ <listitem>
+ <para>
+ An invalid token in the input string was found by the
+ <function>PGTYPESdate_defmt_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_INTVL_BAD_INTERVAL</literal></term>
+ <listitem>
+ <para>
+ An invalid interval string was passed to the
+ <function>PGTYPESinterval_from_asc</function> function, or an
+ invalid interval value was passed to the
+ <function>PGTYPESinterval_to_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_DATE_ERR_ENOTDMY</literal></term>
+ <listitem>
+ <para>
+ There was a mismatch in the day/month/year assignment in the
+ <function>PGTYPESdate_defmt_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_DATE_BAD_DAY</literal></term>
+ <listitem>
+ <para>
+ An invalid day of the month value was found by
+ the <function>PGTYPESdate_defmt_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_DATE_BAD_MONTH</literal></term>
+ <listitem>
+ <para>
+ An invalid month value was found by
+ the <function>PGTYPESdate_defmt_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_TS_BAD_TIMESTAMP</literal></term>
+ <listitem>
+ <para>
+ An invalid timestamp string pass passed to
+ the <function>PGTYPEStimestamp_from_asc</function> function,
+ or an invalid timestamp value was passed to
+ the <function>PGTYPEStimestamp_to_asc</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PGTYPES_TS_ERR_EINFTIME</literal></term>
+ <listitem>
+ <para>
+ An infinite timestamp value was encountered in a context that
+ cannot handle it.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-pgtypes-constants">
+ <title>Special Constants of pgtypeslib</title>
+ <para>
+ <variablelist>
+ <varlistentry id="pgtypesinvalidtimestamp">
+ <term><literal>PGTYPESInvalidTimestamp</literal></term>
+ <listitem>
+ <para>
+ A value of type timestamp representing an invalid time stamp. This is
+ returned by the function <function>PGTYPEStimestamp_from_asc</function> on
+ parse error.
+ Note that due to the internal representation of the <type>timestamp</type> data type,
+ <literal>PGTYPESInvalidTimestamp</literal> is also a valid timestamp at
+ the same time. It is set to <literal>1899-12-31 23:59:59</literal>. In order
+ to detect errors, make sure that your application does not only test
+ for <literal>PGTYPESInvalidTimestamp</literal> but also for
+ <literal>errno != 0</literal> after each call to
+ <function>PGTYPEStimestamp_from_asc</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-descriptors">
+ <title>Using Descriptor Areas</title>
+
+ <para>
+ An SQL descriptor area is a more sophisticated method for processing
+ the result of a <command>SELECT</command>, <command>FETCH</command> or
+ a <command>DESCRIBE</command> statement. An SQL descriptor area groups
+ the data of one row of data together with metadata items into one
+ data structure. The metadata is particularly useful when executing
+ dynamic SQL statements, where the nature of the result columns might
+ not be known ahead of time. PostgreSQL provides two ways to use
+ Descriptor Areas: the named SQL Descriptor Areas and the C-structure
+ SQLDAs.
+ </para>
+
+ <sect2 id="ecpg-named-descriptors">
+ <title>Named SQL Descriptor Areas</title>
+
+ <para>
+ A named SQL descriptor area consists of a header, which contains
+ information concerning the entire descriptor, and one or more item
+ descriptor areas, which basically each describe one column in the
+ result row.
+ </para>
+
+ <para>
+ Before you can use an SQL descriptor area, you need to allocate one:
+<programlisting>
+EXEC SQL ALLOCATE DESCRIPTOR <replaceable>identifier</replaceable>;
+</programlisting>
+ The identifier serves as the <quote>variable name</quote> of the
+ descriptor area. <!-- The scope of the allocated descriptor is WHAT?. -->
+ When you don't need the descriptor anymore, you should deallocate
+ it:
+<programlisting>
+EXEC SQL DEALLOCATE DESCRIPTOR <replaceable>identifier</replaceable>;
+</programlisting>
+ </para>
+
+ <para>
+ To use a descriptor area, specify it as the storage target in an
+ <literal>INTO</literal> clause, instead of listing host variables:
+<programlisting>
+EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;
+</programlisting>
+ If the result set is empty, the Descriptor Area will still contain
+ the metadata from the query, i.e., the field names.
+ </para>
+
+ <para>
+ For not yet executed prepared queries, the <command>DESCRIBE</command>
+ statement can be used to get the metadata of the result set:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+char *sql_stmt = "SELECT * FROM table1";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE stmt1 FROM :sql_stmt;
+EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
+</programlisting>
+ </para>
+
+ <para>
+ Before PostgreSQL 9.0, the <literal>SQL</literal> keyword was optional,
+ so using <literal>DESCRIPTOR</literal> and <literal>SQL DESCRIPTOR</literal>
+ produced named SQL Descriptor Areas. Now it is mandatory, omitting
+ the <literal>SQL</literal> keyword produces SQLDA Descriptor Areas,
+ see <xref linkend="ecpg-sqlda-descriptors"/>.
+ </para>
+
+ <para>
+ In <command>DESCRIBE</command> and <command>FETCH</command> statements,
+ the <literal>INTO</literal> and <literal>USING</literal> keywords can be
+ used to similarly: they produce the result set and the metadata in a
+ Descriptor Area.
+ </para>
+
+ <para>
+ Now how do you get the data out of the descriptor area? You can
+ think of the descriptor area as a structure with named fields. To
+ retrieve the value of a field from the header and store it into a
+ host variable, use the following command:
+<programlisting>
+EXEC SQL GET DESCRIPTOR <replaceable>name</replaceable> :<replaceable>hostvar</replaceable> = <replaceable>field</replaceable>;
+</programlisting>
+ Currently, there is only one header field defined:
+ <replaceable>COUNT</replaceable>, which tells how many item
+ descriptor areas exist (that is, how many columns are contained in
+ the result). The host variable needs to be of an integer type. To
+ get a field from the item descriptor area, use the following
+ command:
+<programlisting>
+EXEC SQL GET DESCRIPTOR <replaceable>name</replaceable> VALUE <replaceable>num</replaceable> :<replaceable>hostvar</replaceable> = <replaceable>field</replaceable>;
+</programlisting>
+ <replaceable>num</replaceable> can be a literal integer or a host
+ variable containing an integer. Possible fields are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>CARDINALITY</literal> (integer)</term>
+ <listitem>
+ <para>
+ number of rows in the result set
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DATA</literal></term>
+ <listitem>
+ <para>
+ actual data item (therefore, the data type of this field
+ depends on the query)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DATETIME_INTERVAL_CODE</literal> (integer)</term>
+ <listitem>
+ <para>
+ When <literal>TYPE</literal> is <literal>9</literal>,
+ <literal>DATETIME_INTERVAL_CODE</literal> will have a value of
+ <literal>1</literal> for <literal>DATE</literal>,
+ <literal>2</literal> for <literal>TIME</literal>,
+ <literal>3</literal> for <literal>TIMESTAMP</literal>,
+ <literal>4</literal> for <literal>TIME WITH TIME ZONE</literal>, or
+ <literal>5</literal> for <literal>TIMESTAMP WITH TIME ZONE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DATETIME_INTERVAL_PRECISION</literal> (integer)</term>
+ <listitem>
+ <para>
+ not implemented
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INDICATOR</literal> (integer)</term>
+ <listitem>
+ <para>
+ the indicator (indicating a null value or a value truncation)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>KEY_MEMBER</literal> (integer)</term>
+ <listitem>
+ <para>
+ not implemented
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LENGTH</literal> (integer)</term>
+ <listitem>
+ <para>
+ length of the datum in characters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NAME</literal> (string)</term>
+ <listitem>
+ <para>
+ name of the column
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULLABLE</literal> (integer)</term>
+ <listitem>
+ <para>
+ not implemented
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OCTET_LENGTH</literal> (integer)</term>
+ <listitem>
+ <para>
+ length of the character representation of the datum in bytes
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PRECISION</literal> (integer)</term>
+ <listitem>
+ <para>
+ precision (for type <type>numeric</type>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RETURNED_LENGTH</literal> (integer)</term>
+ <listitem>
+ <para>
+ length of the datum in characters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RETURNED_OCTET_LENGTH</literal> (integer)</term>
+ <listitem>
+ <para>
+ length of the character representation of the datum in bytes
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SCALE</literal> (integer)</term>
+ <listitem>
+ <para>
+ scale (for type <type>numeric</type>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TYPE</literal> (integer)</term>
+ <listitem>
+ <para>
+ numeric code of the data type of the column
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ In <command>EXECUTE</command>, <command>DECLARE</command> and <command>OPEN</command>
+ statements, the effect of the <literal>INTO</literal> and <literal>USING</literal>
+ keywords are different. A Descriptor Area can also be manually built to
+ provide the input parameters for a query or a cursor and
+ <literal>USING SQL DESCRIPTOR <replaceable>name</replaceable></literal>
+ is the way to pass the input parameters into a parameterized query. The statement
+ to build a named SQL Descriptor Area is below:
+<programlisting>
+EXEC SQL SET DESCRIPTOR <replaceable>name</replaceable> VALUE <replaceable>num</replaceable> <replaceable>field</replaceable> = :<replaceable>hostvar</replaceable>;
+</programlisting>
+ </para>
+
+ <para>
+ PostgreSQL supports retrieving more that one record in one <command>FETCH</command>
+ statement and storing the data in host variables in this case assumes that the
+ variable is an array. E.g.:
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int id[5];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc;
+
+EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA;
+</programlisting>
+
+ </para>
+
+ </sect2>
+
+ <sect2 id="ecpg-sqlda-descriptors">
+ <title>SQLDA Descriptor Areas</title>
+
+ <para>
+ An SQLDA Descriptor Area is a C language structure which can be also used
+ to get the result set and the metadata of a query. One structure stores one
+ record from the result set.
+<programlisting>
+EXEC SQL include sqlda.h;
+sqlda_t *mysqlda;
+
+EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda;
+</programlisting>
+ Note that the <literal>SQL</literal> keyword is omitted. The paragraphs about
+ the use cases of the <literal>INTO</literal> and <literal>USING</literal>
+ keywords in <xref linkend="ecpg-named-descriptors"/> also apply here with an addition.
+ In a <command>DESCRIBE</command> statement the <literal>DESCRIPTOR</literal>
+ keyword can be completely omitted if the <literal>INTO</literal> keyword is used:
+<programlisting>
+EXEC SQL DESCRIBE prepared_statement INTO mysqlda;
+</programlisting>
+ </para>
+
+ <procedure>
+ <para>
+ The general flow of a program that uses SQLDA is:
+ </para>
+ <step><simpara>Prepare a query, and declare a cursor for it.</simpara></step>
+ <step><simpara>Declare an SQLDA for the result rows.</simpara></step>
+ <step><simpara>Declare an SQLDA for the input parameters, and initialize them (memory allocation, parameter settings).</simpara></step>
+ <step><simpara>Open a cursor with the input SQLDA.</simpara></step>
+ <step><simpara>Fetch rows from the cursor, and store them into an output SQLDA.</simpara></step>
+ <step><simpara>Read values from the output SQLDA into the host variables (with conversion if necessary).</simpara></step>
+ <step><simpara>Close the cursor.</simpara></step>
+ <step><simpara>Free the memory area allocated for the input SQLDA.</simpara></step>
+ </procedure>
+
+ <sect3>
+ <title>SQLDA Data Structure</title>
+
+ <para>
+ SQLDA uses three data structure
+ types: <type>sqlda_t</type>, <type>sqlvar_t</type>,
+ and <type>struct sqlname</type>.
+ </para>
+
+ <tip>
+ <para>
+ PostgreSQL's SQLDA has a similar data structure to the one in
+ IBM DB2 Universal Database, so some technical information on
+ DB2's SQLDA could help understanding PostgreSQL's one better.
+ </para>
+ </tip>
+
+ <sect4 id="ecpg-sqlda-sqlda">
+ <title>sqlda_t Structure</title>
+
+ <para>
+ The structure type <type>sqlda_t</type> is the type of the
+ actual SQLDA. It holds one record. And two or
+ more <type>sqlda_t</type> structures can be connected in a
+ linked list with the pointer in
+ the <structfield>desc_next</structfield> field, thus
+ representing an ordered collection of rows. So, when two or
+ more rows are fetched, the application can read them by
+ following the <structfield>desc_next</structfield> pointer in
+ each <type>sqlda_t</type> node.
+ </para>
+
+ <para>
+ The definition of <type>sqlda_t</type> is:
+<programlisting>
+struct sqlda_struct
+{
+ char sqldaid[8];
+ long sqldabc;
+ short sqln;
+ short sqld;
+ struct sqlda_struct *desc_next;
+ struct sqlvar_struct sqlvar[1];
+};
+
+typedef struct sqlda_struct sqlda_t;
+</programlisting>
+
+ The meaning of the fields is:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>sqldaid</literal></term>
+ <listitem>
+ <para>
+ It contains the literal string <literal>"SQLDA "</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqldabc</literal></term>
+ <listitem>
+ <para>
+ It contains the size of the allocated space in bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqln</literal></term>
+ <listitem>
+ <para>
+ It contains the number of input parameters for a parameterized query in
+ case it's passed into <command>OPEN</command>, <command>DECLARE</command> or
+ <command>EXECUTE</command> statements using the <literal>USING</literal>
+ keyword. In case it's used as output of <command>SELECT</command>,
+ <command>EXECUTE</command> or <command>FETCH</command> statements,
+ its value is the same as <literal>sqld</literal>
+ statement
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqld</literal></term>
+ <listitem>
+ <para>
+ It contains the number of fields in a result set.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>desc_next</literal></term>
+ <listitem>
+ <para>
+ If the query returns more than one record, multiple linked
+ SQLDA structures are returned, and <literal>desc_next</literal> holds
+ a pointer to the next entry in the list.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>sqlvar</literal></term>
+ <listitem>
+ <para>
+ This is the array of the columns in the result set.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect4>
+
+ <sect4 id="ecpg-sqlda-sqlvar">
+ <title>sqlvar_t Structure</title>
+
+ <para>
+ The structure type <type>sqlvar_t</type> holds a column value
+ and metadata such as type and length. The definition of the type
+ is:
+
+<programlisting>
+struct sqlvar_struct
+{
+ short sqltype;
+ short sqllen;
+ char *sqldata;
+ short *sqlind;
+ struct sqlname sqlname;
+};
+
+typedef struct sqlvar_struct sqlvar_t;
+</programlisting>
+
+ The meaning of the fields is:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>sqltype</literal></term>
+ <listitem>
+ <para>
+ Contains the type identifier of the field. For values,
+ see <literal>enum ECPGttype</literal> in <literal>ecpgtype.h</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqllen</literal></term>
+ <listitem>
+ <para>
+ Contains the binary length of the field. e.g., 4 bytes for <type>ECPGt_int</type>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqldata</literal></term>
+ <listitem>
+ <para>
+ Points to the data. The format of the data is described
+ in <xref linkend="ecpg-variables-type-mapping"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlind</literal></term>
+ <listitem>
+ <para>
+ Points to the null indicator. 0 means not null, -1 means
+ null.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlname</literal></term>
+ <listitem>
+ <para>
+ The name of the field.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect4>
+
+ <sect4 id="ecpg-sqlda-sqlname">
+ <title>struct sqlname Structure</title>
+
+ <para>
+ A <type>struct sqlname</type> structure holds a column name. It
+ is used as a member of the <type>sqlvar_t</type> structure. The
+ definition of the structure is:
+<programlisting>
+#define NAMEDATALEN 64
+
+struct sqlname
+{
+ short length;
+ char data[NAMEDATALEN];
+};
+</programlisting>
+ The meaning of the fields is:
+ <variablelist>
+ <varlistentry>
+ <term><literal>length</literal></term>
+ <listitem>
+ <para>
+ Contains the length of the field name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>data</literal></term>
+ <listitem>
+ <para>
+ Contains the actual field name.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect4>
+ </sect3>
+
+ <sect3 id="ecpg-sqlda-output">
+ <title>Retrieving a Result Set Using an SQLDA</title>
+
+ <procedure>
+ <para>
+ The general steps to retrieve a query result set through an
+ SQLDA are:
+ </para>
+ <step><simpara>Declare an <type>sqlda_t</type> structure to receive the result set.</simpara></step>
+ <step><simpara>Execute <command>FETCH</command>/<command>EXECUTE</command>/<command>DESCRIBE</command> commands to process a query specifying the declared SQLDA.</simpara></step>
+ <step><simpara>Check the number of records in the result set by looking at <structfield>sqln</structfield>, a member of the <type>sqlda_t</type> structure.</simpara></step>
+ <step><simpara>Get the values of each column from <literal>sqlvar[0]</literal>, <literal>sqlvar[1]</literal>, etc., members of the <type>sqlda_t</type> structure.</simpara></step>
+ <step><simpara>Go to next row (<type>sqlda_t</type> structure) by following the <structfield>desc_next</structfield> pointer, a member of the <type>sqlda_t</type> structure.</simpara></step>
+ <step><simpara>Repeat above as you need.</simpara></step>
+ </procedure>
+
+ <para>
+ Here is an example retrieving a result set through an SQLDA.
+ </para>
+
+ <para>
+ First, declare a <type>sqlda_t</type> structure to receive the result set.
+<programlisting>
+sqlda_t *sqlda1;
+</programlisting>
+ </para>
+
+ <para>
+ Next, specify the SQLDA in a command. This is
+ a <command>FETCH</command> command example.
+<programlisting>
+EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
+</programlisting>
+ </para>
+
+ <para>
+ Run a loop following the linked list to retrieve the rows.
+<programlisting>
+sqlda_t *cur_sqlda;
+
+for (cur_sqlda = sqlda1;
+ cur_sqlda != NULL;
+ cur_sqlda = cur_sqlda->desc_next)
+{
+ ...
+}
+</programlisting>
+ </para>
+
+ <para>
+ Inside the loop, run another loop to retrieve each column data
+ (<type>sqlvar_t</type> structure) of the row.
+<programlisting>
+for (i = 0; i &lt; cur_sqlda->sqld; i++)
+{
+ sqlvar_t v = cur_sqlda->sqlvar[i];
+ char *sqldata = v.sqldata;
+ short sqllen = v.sqllen;
+ ...
+}
+</programlisting>
+ </para>
+
+ <para>
+ To get a column value, check the <structfield>sqltype</structfield> value,
+ a member of the <type>sqlvar_t</type> structure. Then, switch
+ to an appropriate way, depending on the column type, to copy
+ data from the <structfield>sqlvar</structfield> field to a host variable.
+<programlisting>
+char var_buf[1024];
+
+switch (v.sqltype)
+{
+ case ECPGt_char:
+ memset(&amp;var_buf, 0, sizeof(var_buf));
+ memcpy(&amp;var_buf, sqldata, (sizeof(var_buf) &lt;= sqllen ? sizeof(var_buf) - 1 : sqllen));
+ break;
+
+ case ECPGt_int: /* integer */
+ memcpy(&amp;intval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%d", intval);
+ break;
+
+ ...
+}
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="ecpg-sqlda-input">
+ <title>Passing Query Parameters Using an SQLDA</title>
+
+ <procedure>
+ <para>
+ The general steps to use an SQLDA to pass input
+ parameters to a prepared query are:
+ </para>
+ <step><simpara>Create a prepared query (prepared statement)</simpara></step>
+ <step><simpara>Declare an sqlda_t structure as an input SQLDA.</simpara></step>
+ <step><simpara>Allocate memory area (as sqlda_t structure) for the input SQLDA.</simpara></step>
+ <step><simpara>Set (copy) input values in the allocated memory.</simpara></step>
+ <step><simpara>Open a cursor with specifying the input SQLDA.</simpara></step>
+ </procedure>
+
+ <para>
+ Here is an example.
+ </para>
+
+ <para>
+ First, create a prepared statement.
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid = s.datid AND (d.datname = ? OR d.oid = ?)";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE stmt1 FROM :query;
+</programlisting>
+ </para>
+
+ <para>
+ Next, allocate memory for an SQLDA, and set the number of input
+ parameters in <structfield>sqln</structfield>, a member variable of
+ the <type>sqlda_t</type> structure. When two or more input
+ parameters are required for the prepared query, the application
+ has to allocate additional memory space which is calculated by
+ (nr. of params - 1) * sizeof(sqlvar_t). The example shown here
+ allocates memory space for two input parameters.
+<programlisting>
+sqlda_t *sqlda2;
+
+sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
+memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
+
+sqlda2->sqln = 2; /* number of input variables */
+</programlisting>
+ </para>
+
+ <para>
+ After memory allocation, store the parameter values into the
+ <literal>sqlvar[]</literal> array. (This is same array used for
+ retrieving column values when the SQLDA is receiving a result
+ set.) In this example, the input parameters
+ are <literal>"postgres"</literal>, having a string type,
+ and <literal>1</literal>, having an integer type.
+<programlisting>
+sqlda2->sqlvar[0].sqltype = ECPGt_char;
+sqlda2->sqlvar[0].sqldata = "postgres";
+sqlda2->sqlvar[0].sqllen = 8;
+
+int intval = 1;
+sqlda2->sqlvar[1].sqltype = ECPGt_int;
+sqlda2->sqlvar[1].sqldata = (char *) &amp;intval;
+sqlda2->sqlvar[1].sqllen = sizeof(intval);
+</programlisting>
+ </para>
+
+ <para>
+ By opening a cursor and specifying the SQLDA that was set up
+ beforehand, the input parameters are passed to the prepared
+ statement.
+<programlisting>
+EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
+</programlisting>
+ </para>
+
+ <para>
+ Finally, after using input SQLDAs, the allocated memory space
+ must be freed explicitly, unlike SQLDAs used for receiving query
+ results.
+<programlisting>
+free(sqlda2);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="ecpg-sqlda-example">
+ <title>A Sample Application Using SQLDA</title>
+
+ <para>
+ Here is an example program, which describes how to fetch access
+ statistics of the databases, specified by the input parameters,
+ from the system catalogs.
+ </para>
+
+ <para>
+ This application joins two system tables, pg_database and
+ pg_stat_database on the database OID, and also fetches and shows
+ the database statistics which are retrieved by two input
+ parameters (a database <literal>postgres</literal>, and OID <literal>1</literal>).
+ </para>
+
+ <para>
+ First, declare an SQLDA for input and an SQLDA for output.
+<programlisting>
+EXEC SQL include sqlda.h;
+
+sqlda_t *sqlda1; /* an output descriptor */
+sqlda_t *sqlda2; /* an input descriptor */
+</programlisting>
+ </para>
+
+ <para>
+ Next, connect to the database, prepare a statement, and declare a
+ cursor for the prepared statement.
+<programlisting>
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ EXEC SQL PREPARE stmt1 FROM :query;
+ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+</programlisting>
+ </para>
+
+ <para>
+ Next, put some values in the input SQLDA for the input
+ parameters. Allocate memory for the input SQLDA, and set the
+ number of input parameters to <literal>sqln</literal>. Store
+ type, value, and value length into <literal>sqltype</literal>,
+ <literal>sqldata</literal>, and <literal>sqllen</literal> in the
+ <literal>sqlvar</literal> structure.
+
+<programlisting>
+ /* Create SQLDA structure for input parameters. */
+ sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
+ memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
+ sqlda2->sqln = 2; /* number of input variables */
+
+ sqlda2->sqlvar[0].sqltype = ECPGt_char;
+ sqlda2->sqlvar[0].sqldata = "postgres";
+ sqlda2->sqlvar[0].sqllen = 8;
+
+ intval = 1;
+ sqlda2->sqlvar[1].sqltype = ECPGt_int;
+ sqlda2->sqlvar[1].sqldata = (char *)&amp;intval;
+ sqlda2->sqlvar[1].sqllen = sizeof(intval);
+</programlisting>
+ </para>
+
+ <para>
+ After setting up the input SQLDA, open a cursor with the input
+ SQLDA.
+
+<programlisting>
+ /* Open a cursor with input parameters. */
+ EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
+</programlisting>
+ </para>
+
+ <para>
+ Fetch rows into the output SQLDA from the opened cursor.
+ (Generally, you have to call <command>FETCH</command> repeatedly
+ in the loop, to fetch all rows in the result set.)
+<programlisting>
+ while (1)
+ {
+ sqlda_t *cur_sqlda;
+
+ /* Assign descriptor to the cursor */
+ EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
+</programlisting>
+ </para>
+
+ <para>
+ Next, retrieve the fetched records from the SQLDA, by following
+ the linked list of the <type>sqlda_t</type> structure.
+<programlisting>
+ for (cur_sqlda = sqlda1 ;
+ cur_sqlda != NULL ;
+ cur_sqlda = cur_sqlda->desc_next)
+ {
+ ...
+</programlisting>
+ </para>
+
+ <para>
+ Read each columns in the first record. The number of columns is
+ stored in <structfield>sqld</structfield>, the actual data of the first
+ column is stored in <literal>sqlvar[0]</literal>, both members of
+ the <type>sqlda_t</type> structure.
+
+<programlisting>
+ /* Print every column in a row. */
+ for (i = 0; i &lt; sqlda1-&gt;sqld; i++)
+ {
+ sqlvar_t v = sqlda1->sqlvar[i];
+ char *sqldata = v.sqldata;
+ short sqllen = v.sqllen;
+
+ strncpy(name_buf, v.sqlname.data, v.sqlname.length);
+ name_buf[v.sqlname.length] = '\0';
+</programlisting>
+ </para>
+
+ <para>
+ Now, the column data is stored in the variable <varname>v</varname>.
+ Copy every datum into host variables, looking
+ at <literal>v.sqltype</literal> for the type of the column.
+<programlisting>
+ switch (v.sqltype) {
+ int intval;
+ double doubleval;
+ unsigned long long int longlongval;
+
+ case ECPGt_char:
+ memset(&amp;var_buf, 0, sizeof(var_buf));
+ memcpy(&amp;var_buf, sqldata, (sizeof(var_buf) &lt;= sqllen ? sizeof(var_buf)-1 : sqllen));
+ break;
+
+ case ECPGt_int: /* integer */
+ memcpy(&amp;intval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%d", intval);
+ break;
+
+ ...
+
+ default:
+ ...
+ }
+
+ printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
+ }
+</programlisting>
+ </para>
+
+ <para>
+ Close the cursor after processing all of records, and disconnect
+ from the database.
+<programlisting>
+ EXEC SQL CLOSE cur1;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DISCONNECT ALL;
+</programlisting>
+ </para>
+
+ <para>
+ The whole program is shown
+ in <xref linkend="ecpg-sqlda-example-example"/>.
+ </para>
+
+ <example id="ecpg-sqlda-example-example">
+ <title>Example SQLDA Program</title>
+<programlisting>
+#include &lt;stdlib.h>
+#include &lt;string.h>
+#include &lt;stdlib.h>
+#include &lt;stdio.h>
+#include &lt;unistd.h>
+
+EXEC SQL include sqlda.h;
+
+sqlda_t *sqlda1; /* descriptor for output */
+sqlda_t *sqlda2; /* descriptor for input */
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
+
+ int intval;
+ unsigned long long int longlongval;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO uptimedb AS con1 USER uptime;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ EXEC SQL PREPARE stmt1 FROM :query;
+ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+
+ /* Create an SQLDA structure for an input parameter */
+ sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
+ memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
+ sqlda2->sqln = 2; /* a number of input variables */
+
+ sqlda2->sqlvar[0].sqltype = ECPGt_char;
+ sqlda2->sqlvar[0].sqldata = "postgres";
+ sqlda2->sqlvar[0].sqllen = 8;
+
+ intval = 1;
+ sqlda2->sqlvar[1].sqltype = ECPGt_int;
+ sqlda2->sqlvar[1].sqldata = (char *) &amp;intval;
+ sqlda2->sqlvar[1].sqllen = sizeof(intval);
+
+ /* Open a cursor with input parameters. */
+ EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
+
+ while (1)
+ {
+ sqlda_t *cur_sqlda;
+
+ /* Assign descriptor to the cursor */
+ EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
+
+ for (cur_sqlda = sqlda1 ;
+ cur_sqlda != NULL ;
+ cur_sqlda = cur_sqlda->desc_next)
+ {
+ int i;
+ char name_buf[1024];
+ char var_buf[1024];
+
+ /* Print every column in a row. */
+ for (i=0 ; i&lt;cur_sqlda->sqld ; i++)
+ {
+ sqlvar_t v = cur_sqlda->sqlvar[i];
+ char *sqldata = v.sqldata;
+ short sqllen = v.sqllen;
+
+ strncpy(name_buf, v.sqlname.data, v.sqlname.length);
+ name_buf[v.sqlname.length] = '\0';
+
+ switch (v.sqltype)
+ {
+ case ECPGt_char:
+ memset(&amp;var_buf, 0, sizeof(var_buf));
+ memcpy(&amp;var_buf, sqldata, (sizeof(var_buf)&lt;=sqllen ? sizeof(var_buf)-1 : sqllen) );
+ break;
+
+ case ECPGt_int: /* integer */
+ memcpy(&amp;intval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%d", intval);
+ break;
+
+ case ECPGt_long_long: /* bigint */
+ memcpy(&amp;longlongval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%lld", longlongval);
+ break;
+
+ default:
+ {
+ int i;
+ memset(var_buf, 0, sizeof(var_buf));
+ for (i = 0; i &lt; sqllen; i++)
+ {
+ char tmpbuf[16];
+ snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char) sqldata[i]);
+ strncat(var_buf, tmpbuf, sizeof(var_buf));
+ }
+ }
+ break;
+ }
+
+ printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
+ }
+
+ printf("\n");
+ }
+ }
+
+ EXEC SQL CLOSE cur1;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+</programlisting>
+
+ <para>
+ The output of this example should look something like the
+ following (some numbers will vary).
+ </para>
+
+<screen>
+oid = 1 (type: 1)
+datname = template1 (type: 1)
+datdba = 10 (type: 1)
+encoding = 0 (type: 5)
+datistemplate = t (type: 1)
+datallowconn = t (type: 1)
+datconnlimit = -1 (type: 5)
+datfrozenxid = 379 (type: 1)
+dattablespace = 1663 (type: 1)
+datconfig = (type: 1)
+datacl = {=c/uptime,uptime=CTc/uptime} (type: 1)
+datid = 1 (type: 1)
+datname = template1 (type: 1)
+numbackends = 0 (type: 5)
+xact_commit = 113606 (type: 9)
+xact_rollback = 0 (type: 9)
+blks_read = 130 (type: 9)
+blks_hit = 7341714 (type: 9)
+tup_returned = 38262679 (type: 9)
+tup_fetched = 1836281 (type: 9)
+tup_inserted = 0 (type: 9)
+tup_updated = 0 (type: 9)
+tup_deleted = 0 (type: 9)
+
+oid = 11511 (type: 1)
+datname = postgres (type: 1)
+datdba = 10 (type: 1)
+encoding = 0 (type: 5)
+datistemplate = f (type: 1)
+datallowconn = t (type: 1)
+datconnlimit = -1 (type: 5)
+datfrozenxid = 379 (type: 1)
+dattablespace = 1663 (type: 1)
+datconfig = (type: 1)
+datacl = (type: 1)
+datid = 11511 (type: 1)
+datname = postgres (type: 1)
+numbackends = 0 (type: 5)
+xact_commit = 221069 (type: 9)
+xact_rollback = 18 (type: 9)
+blks_read = 1176 (type: 9)
+blks_hit = 13943750 (type: 9)
+tup_returned = 77410091 (type: 9)
+tup_fetched = 3253694 (type: 9)
+tup_inserted = 0 (type: 9)
+tup_updated = 0 (type: 9)
+tup_deleted = 0 (type: 9)
+</screen>
+ </example>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-errors">
+ <title>Error Handling</title>
+
+ <para>
+ This section describes how you can handle exceptional conditions
+ and warnings in an embedded SQL program. There are two
+ nonexclusive facilities for this.
+
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Callbacks can be configured to handle warning and error
+ conditions using the <literal>WHENEVER</literal> command.
+ </simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>
+ Detailed information about the error or warning can be obtained
+ from the <varname>sqlca</varname> variable.
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect2 id="ecpg-whenever">
+ <title>Setting Callbacks</title>
+
+ <para>
+ One simple method to catch errors and warnings is to set a
+ specific action to be executed whenever a particular condition
+ occurs. In general:
+<programlisting>
+EXEC SQL WHENEVER <replaceable>condition</replaceable> <replaceable>action</replaceable>;
+</programlisting>
+ </para>
+
+ <para>
+ <replaceable>condition</replaceable> can be one of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SQLERROR</literal></term>
+ <listitem>
+ <para>
+ The specified action is called whenever an error occurs during
+ the execution of an SQL statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SQLWARNING</literal></term>
+ <listitem>
+ <para>
+ The specified action is called whenever a warning occurs
+ during the execution of an SQL statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOT FOUND</literal></term>
+ <listitem>
+ <para>
+ The specified action is called whenever an SQL statement
+ retrieves or affects zero rows. (This condition is not an
+ error, but you might be interested in handling it specially.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <replaceable>action</replaceable> can be one of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>CONTINUE</literal></term>
+ <listitem>
+ <para>
+ This effectively means that the condition is ignored. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>GOTO <replaceable>label</replaceable></literal></term>
+ <term><literal>GO TO <replaceable>label</replaceable></literal></term>
+ <listitem>
+ <para>
+ Jump to the specified label (using a C <literal>goto</literal>
+ statement).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SQLPRINT</literal></term>
+ <listitem>
+ <para>
+ Print a message to standard error. This is useful for simple
+ programs or during prototyping. The details of the message
+ cannot be configured.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>STOP</literal></term>
+ <listitem>
+ <para>
+ Call <literal>exit(1)</literal>, which will terminate the
+ program.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DO BREAK</literal></term>
+ <listitem>
+ <para>
+ Execute the C statement <literal>break</literal>. This should
+ only be used in loops or <literal>switch</literal> statements.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DO CONTINUE</literal></term>
+ <listitem>
+ <para>
+ Execute the C statement <literal>continue</literal>. This should
+ only be used in loops statements. if executed, will cause the flow
+ of control to return to the top of the loop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CALL <replaceable>name</replaceable> (<replaceable>args</replaceable>)</literal></term>
+ <term><literal>DO <replaceable>name</replaceable> (<replaceable>args</replaceable>)</literal></term>
+ <listitem>
+ <para>
+ Call the specified C functions with the specified arguments. (This
+ use is different from the meaning of <literal>CALL</literal>
+ and <literal>DO</literal> in the normal PostgreSQL grammar.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The SQL standard only provides for the actions
+ <literal>CONTINUE</literal> and <literal>GOTO</literal> (and
+ <literal>GO TO</literal>).
+ </para>
+
+ <para>
+ Here is an example that you might want to use in a simple program.
+ It prints a simple message when a warning occurs and aborts the
+ program when an error happens:
+<programlisting>
+EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+EXEC SQL WHENEVER SQLERROR STOP;
+</programlisting>
+ </para>
+
+ <para>
+ The statement <literal>EXEC SQL WHENEVER</literal> is a directive
+ of the SQL preprocessor, not a C statement. The error or warning
+ actions that it sets apply to all embedded SQL statements that
+ appear below the point where the handler is set, unless a
+ different action was set for the same condition between the first
+ <literal>EXEC SQL WHENEVER</literal> and the SQL statement causing
+ the condition, regardless of the flow of control in the C program.
+ So neither of the two following C program excerpts will have the
+ desired effect:
+<programlisting>
+/*
+ * WRONG
+ */
+int main(int argc, char *argv[])
+{
+ ...
+ if (verbose) {
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ }
+ ...
+ EXEC SQL SELECT ...;
+ ...
+}
+</programlisting>
+
+<programlisting>
+/*
+ * WRONG
+ */
+int main(int argc, char *argv[])
+{
+ ...
+ set_error_handler();
+ ...
+ EXEC SQL SELECT ...;
+ ...
+}
+
+static void set_error_handler(void)
+{
+ EXEC SQL WHENEVER SQLERROR STOP;
+}
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-sqlca">
+ <title>sqlca</title>
+
+ <para>
+ For more powerful error handling, the embedded SQL interface
+ provides a global variable with the name <varname>sqlca</varname>
+ (SQL communication area)
+ that has the following structure:
+<programlisting>
+struct
+{
+ char sqlcaid[8];
+ long sqlabc;
+ long sqlcode;
+ struct
+ {
+ int sqlerrml;
+ char sqlerrmc[SQLERRMC_LEN];
+ } sqlerrm;
+ char sqlerrp[8];
+ long sqlerrd[6];
+ char sqlwarn[8];
+ char sqlstate[5];
+} sqlca;
+</programlisting>
+ (In a multithreaded program, every thread automatically gets its
+ own copy of <varname>sqlca</varname>. This works similarly to the
+ handling of the standard C global variable
+ <varname>errno</varname>.)
+ </para>
+
+ <para>
+ <varname>sqlca</varname> covers both warnings and errors. If
+ multiple warnings or errors occur during the execution of a
+ statement, then <varname>sqlca</varname> will only contain
+ information about the last one.
+ </para>
+
+ <para>
+ If no error occurred in the last <acronym>SQL</acronym> statement,
+ <literal>sqlca.sqlcode</literal> will be 0 and
+ <literal>sqlca.sqlstate</literal> will be
+ <literal>"00000"</literal>. If a warning or error occurred, then
+ <literal>sqlca.sqlcode</literal> will be negative and
+ <literal>sqlca.sqlstate</literal> will be different from
+ <literal>"00000"</literal>. A positive
+ <literal>sqlca.sqlcode</literal> indicates a harmless condition,
+ such as that the last query returned zero rows.
+ <literal>sqlcode</literal> and <literal>sqlstate</literal> are two
+ different error code schemes; details appear below.
+ </para>
+
+ <para>
+ If the last SQL statement was successful, then
+ <literal>sqlca.sqlerrd[1]</literal> contains the OID of the
+ processed row, if applicable, and
+ <literal>sqlca.sqlerrd[2]</literal> contains the number of
+ processed or returned rows, if applicable to the command.
+ </para>
+
+ <para>
+ In case of an error or warning,
+ <literal>sqlca.sqlerrm.sqlerrmc</literal> will contain a string
+ that describes the error. The field
+ <literal>sqlca.sqlerrm.sqlerrml</literal> contains the length of
+ the error message that is stored in
+ <literal>sqlca.sqlerrm.sqlerrmc</literal> (the result of
+ <function>strlen()</function>, not really interesting for a C
+ programmer). Note that some messages are too long to fit in the
+ fixed-size <literal>sqlerrmc</literal> array; they will be truncated.
+ </para>
+
+ <para>
+ In case of a warning, <literal>sqlca.sqlwarn[2]</literal> is set
+ to <literal>W</literal>. (In all other cases, it is set to
+ something different from <literal>W</literal>.) If
+ <literal>sqlca.sqlwarn[1]</literal> is set to
+ <literal>W</literal>, then a value was truncated when it was
+ stored in a host variable. <literal>sqlca.sqlwarn[0]</literal> is
+ set to <literal>W</literal> if any of the other elements are set
+ to indicate a warning.
+ </para>
+
+ <para>
+ The fields <structfield>sqlcaid</structfield>,
+ <structfield>sqlabc</structfield>,
+ <structfield>sqlerrp</structfield>, and the remaining elements of
+ <structfield>sqlerrd</structfield> and
+ <structfield>sqlwarn</structfield> currently contain no useful
+ information.
+ </para>
+
+ <para>
+ The structure <varname>sqlca</varname> is not defined in the SQL
+ standard, but is implemented in several other SQL database
+ systems. The definitions are similar at the core, but if you want
+ to write portable applications, then you should investigate the
+ different implementations carefully.
+ </para>
+
+ <para>
+ Here is one example that combines the use of <literal>WHENEVER</literal>
+ and <varname>sqlca</varname>, printing out the contents
+ of <varname>sqlca</varname> when an error occurs. This is perhaps
+ useful for debugging or prototyping applications, before
+ installing a more <quote>user-friendly</quote> error handler.
+
+<programlisting>
+EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
+
+void
+print_sqlca()
+{
+ fprintf(stderr, "==== sqlca ====\n");
+ fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
+ fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
+ fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
+ fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2],
+ sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]);
+ fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2],
+ sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5],
+ sqlca.sqlwarn[6], sqlca.sqlwarn[7]);
+ fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
+ fprintf(stderr, "===============\n");
+}
+</programlisting>
+
+ The result could look as follows (here an error due to a
+ misspelled table name):
+
+<screen>
+==== sqlca ====
+sqlcode: -400
+sqlerrm.sqlerrml: 49
+sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38
+sqlerrd: 0 0 0 0 0 0
+sqlwarn: 0 0 0 0 0 0 0 0
+sqlstate: 42P01
+===============
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-sqlstate-sqlcode">
+ <title><literal>SQLSTATE</literal> vs. <literal>SQLCODE</literal></title>
+
+ <para>
+ The fields <literal>sqlca.sqlstate</literal> and
+ <literal>sqlca.sqlcode</literal> are two different schemes that
+ provide error codes. Both are derived from the SQL standard, but
+ <literal>SQLCODE</literal> has been marked deprecated in the SQL-92
+ edition of the standard and has been dropped in later editions.
+ Therefore, new applications are strongly encouraged to use
+ <literal>SQLSTATE</literal>.
+ </para>
+
+ <para>
+ <literal>SQLSTATE</literal> is a five-character array. The five
+ characters contain digits or upper-case letters that represent
+ codes of various error and warning conditions.
+ <literal>SQLSTATE</literal> has a hierarchical scheme: the first
+ two characters indicate the general class of the condition, the
+ last three characters indicate a subclass of the general
+ condition. A successful state is indicated by the code
+ <literal>00000</literal>. The <literal>SQLSTATE</literal> codes are for
+ the most part defined in the SQL standard. The
+ <productname>PostgreSQL</productname> server natively supports
+ <literal>SQLSTATE</literal> error codes; therefore a high degree
+ of consistency can be achieved by using this error code scheme
+ throughout all applications. For further information see
+ <xref linkend="errcodes-appendix"/>.
+ </para>
+
+ <para>
+ <literal>SQLCODE</literal>, the deprecated error code scheme, is a
+ simple integer. A value of 0 indicates success, a positive value
+ indicates success with additional information, a negative value
+ indicates an error. The SQL standard only defines the positive
+ value +100, which indicates that the last command returned or
+ affected zero rows, and no specific negative values. Therefore,
+ this scheme can only achieve poor portability and does not have a
+ hierarchical code assignment. Historically, the embedded SQL
+ processor for <productname>PostgreSQL</productname> has assigned
+ some specific <literal>SQLCODE</literal> values for its use, which
+ are listed below with their numeric value and their symbolic name.
+ Remember that these are not portable to other SQL implementations.
+ To simplify the porting of applications to the
+ <literal>SQLSTATE</literal> scheme, the corresponding
+ <literal>SQLSTATE</literal> is also listed. There is, however, no
+ one-to-one or one-to-many mapping between the two schemes (indeed
+ it is many-to-many), so you should consult the global
+ <literal>SQLSTATE</literal> listing in <xref linkend="errcodes-appendix"/>
+ in each case.
+ </para>
+
+ <para>
+ These are the assigned <literal>SQLCODE</literal> values:
+
+ <variablelist>
+ <varlistentry>
+ <term>0 (<symbol>ECPG_NO_ERROR</symbol>)</term>
+ <listitem>
+ <para>
+ Indicates no error. (SQLSTATE 00000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>100 (<symbol>ECPG_NOT_FOUND</symbol>)</term>
+ <listitem>
+ <para>
+ This is a harmless condition indicating that the last command
+ retrieved or processed zero rows, or that you are at the end of
+ the cursor. (SQLSTATE 02000)
+ </para>
+
+ <para>
+ When processing a cursor in a loop, you could use this code as
+ a way to detect when to abort the loop, like this:
+<programlisting>
+while (1)
+{
+ EXEC SQL FETCH ... ;
+ if (sqlca.sqlcode == ECPG_NOT_FOUND)
+ break;
+}
+</programlisting>
+ But <literal>WHENEVER NOT FOUND DO BREAK</literal> effectively
+ does this internally, so there is usually no advantage in
+ writing this out explicitly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-12 (<symbol>ECPG_OUT_OF_MEMORY</symbol>)</term>
+ <listitem>
+ <para>
+ Indicates that your virtual memory is exhausted. The numeric
+ value is defined as <literal>-ENOMEM</literal>. (SQLSTATE
+ YE001)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-200 (<symbol>ECPG_UNSUPPORTED</symbol>)</term>
+ <listitem>
+ <para>
+ Indicates the preprocessor has generated something that the
+ library does not know about. Perhaps you are running
+ incompatible versions of the preprocessor and the
+ library. (SQLSTATE YE002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-201 (<symbol>ECPG_TOO_MANY_ARGUMENTS</symbol>)</term>
+ <listitem>
+ <para>
+ This means that the command specified more host variables than
+ the command expected. (SQLSTATE 07001 or 07002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-202 (<symbol>ECPG_TOO_FEW_ARGUMENTS</symbol>)</term>
+ <listitem>
+ <para>
+ This means that the command specified fewer host variables than
+ the command expected. (SQLSTATE 07001 or 07002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-203 (<symbol>ECPG_TOO_MANY_MATCHES</symbol>)</term>
+ <listitem>
+ <para>
+ This means a query has returned multiple rows but the statement
+ was only prepared to store one result row (for example, because
+ the specified variables are not arrays). (SQLSTATE 21000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-204 (<symbol>ECPG_INT_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>int</type> and the datum in
+ the database is of a different type and contains a value that
+ cannot be interpreted as an <type>int</type>. The library uses
+ <function>strtol()</function> for this conversion. (SQLSTATE
+ 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-205 (<symbol>ECPG_UINT_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>unsigned int</type> and the
+ datum in the database is of a different type and contains a
+ value that cannot be interpreted as an <type>unsigned
+ int</type>. The library uses <function>strtoul()</function>
+ for this conversion. (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-206 (<symbol>ECPG_FLOAT_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>float</type> and the datum
+ in the database is of another type and contains a value that
+ cannot be interpreted as a <type>float</type>. The library
+ uses <function>strtod()</function> for this conversion.
+ (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-207 (<symbol>ECPG_NUMERIC_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>numeric</type> and the datum
+ in the database is of another type and contains a value that
+ cannot be interpreted as a <type>numeric</type> value.
+ (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-208 (<symbol>ECPG_INTERVAL_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>interval</type> and the datum
+ in the database is of another type and contains a value that
+ cannot be interpreted as an <type>interval</type> value.
+ (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-209 (<symbol>ECPG_DATE_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>date</type> and the datum in
+ the database is of another type and contains a value that
+ cannot be interpreted as a <type>date</type> value.
+ (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-210 (<symbol>ECPG_TIMESTAMP_FORMAT</symbol>)</term>
+ <listitem>
+ <para>
+ The host variable is of type <type>timestamp</type> and the
+ datum in the database is of another type and contains a value
+ that cannot be interpreted as a <type>timestamp</type> value.
+ (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-211 (<symbol>ECPG_CONVERT_BOOL</symbol>)</term>
+ <listitem>
+ <para>
+ This means the host variable is of type <type>bool</type> and
+ the datum in the database is neither <literal>'t'</literal> nor
+ <literal>'f'</literal>. (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-212 (<symbol>ECPG_EMPTY</symbol>)</term>
+ <listitem>
+ <para>
+ The statement sent to the <productname>PostgreSQL</productname>
+ server was empty. (This cannot normally happen in an embedded
+ SQL program, so it might point to an internal error.) (SQLSTATE
+ YE002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-213 (<symbol>ECPG_MISSING_INDICATOR</symbol>)</term>
+ <listitem>
+ <para>
+ A null value was returned and no null indicator variable was
+ supplied. (SQLSTATE 22002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-214 (<symbol>ECPG_NO_ARRAY</symbol>)</term>
+ <listitem>
+ <para>
+ An ordinary variable was used in a place that requires an
+ array. (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-215 (<symbol>ECPG_DATA_NOT_ARRAY</symbol>)</term>
+ <listitem>
+ <para>
+ The database returned an ordinary variable in a place that
+ requires array value. (SQLSTATE 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-216 (<symbol>ECPG_ARRAY_INSERT</symbol>)</term>
+ <listitem>
+ <para>
+ The value could not be inserted into the array. (SQLSTATE
+ 42804)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-220 (<symbol>ECPG_NO_CONN</symbol>)</term>
+ <listitem>
+ <para>
+ The program tried to access a connection that does not exist.
+ (SQLSTATE 08003)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-221 (<symbol>ECPG_NOT_CONN</symbol>)</term>
+ <listitem>
+ <para>
+ The program tried to access a connection that does exist but is
+ not open. (This is an internal error.) (SQLSTATE YE002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-230 (<symbol>ECPG_INVALID_STMT</symbol>)</term>
+ <listitem>
+ <para>
+ The statement you are trying to use has not been prepared.
+ (SQLSTATE 26000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-239 (<symbol>ECPG_INFORMIX_DUPLICATE_KEY</symbol>)</term>
+ <listitem>
+ <para>
+ Duplicate key error, violation of unique constraint (Informix
+ compatibility mode). (SQLSTATE 23505)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-240 (<symbol>ECPG_UNKNOWN_DESCRIPTOR</symbol>)</term>
+ <listitem>
+ <para>
+ The descriptor specified was not found. The statement you are
+ trying to use has not been prepared. (SQLSTATE 33000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-241 (<symbol>ECPG_INVALID_DESCRIPTOR_INDEX</symbol>)</term>
+ <listitem>
+ <para>
+ The descriptor index specified was out of range. (SQLSTATE
+ 07009)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-242 (<symbol>ECPG_UNKNOWN_DESCRIPTOR_ITEM</symbol>)</term>
+ <listitem>
+ <para>
+ An invalid descriptor item was requested. (This is an internal
+ error.) (SQLSTATE YE002)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-243 (<symbol>ECPG_VAR_NOT_NUMERIC</symbol>)</term>
+ <listitem>
+ <para>
+ During the execution of a dynamic statement, the database
+ returned a numeric value and the host variable was not numeric.
+ (SQLSTATE 07006)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-244 (<symbol>ECPG_VAR_NOT_CHAR</symbol>)</term>
+ <listitem>
+ <para>
+ During the execution of a dynamic statement, the database
+ returned a non-numeric value and the host variable was numeric.
+ (SQLSTATE 07006)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-284 (<symbol>ECPG_INFORMIX_SUBSELECT_NOT_ONE</symbol>)</term>
+ <listitem>
+ <para>
+ A result of the subquery is not single row (Informix
+ compatibility mode). (SQLSTATE 21000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-400 (<symbol>ECPG_PGSQL</symbol>)</term>
+ <listitem>
+ <para>
+ Some error caused by the <productname>PostgreSQL</productname>
+ server. The message contains the error message from the
+ <productname>PostgreSQL</productname> server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-401 (<symbol>ECPG_TRANS</symbol>)</term>
+ <listitem>
+ <para>
+ The <productname>PostgreSQL</productname> server signaled that
+ we cannot start, commit, or rollback the transaction.
+ (SQLSTATE 08007)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-402 (<symbol>ECPG_CONNECT</symbol>)</term>
+ <listitem>
+ <para>
+ The connection attempt to the database did not succeed.
+ (SQLSTATE 08001)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-403 (<symbol>ECPG_DUPLICATE_KEY</symbol>)</term>
+ <listitem>
+ <para>
+ Duplicate key error, violation of unique constraint. (SQLSTATE
+ 23505)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-404 (<symbol>ECPG_SUBSELECT_NOT_ONE</symbol>)</term>
+ <listitem>
+ <para>
+ A result for the subquery is not single row. (SQLSTATE 21000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <!-- currently not used by the code -->
+<!--
+ <varlistentry>
+ <term>-600 (<symbol>ECPG_WARNING_UNRECOGNIZED</symbol>)</term>
+ <listitem>
+ <para>
+ An unrecognized warning was received from the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-601 (<symbol>ECPG_WARNING_QUERY_IGNORED</symbol>)</term>
+ <listitem>
+ <para>
+ Current transaction is aborted. Queries are ignored until the
+ end of the transaction block.
+ </para>
+ </listitem>
+ </varlistentry>
+-->
+
+ <varlistentry>
+ <term>-602 (<symbol>ECPG_WARNING_UNKNOWN_PORTAL</symbol>)</term>
+ <listitem>
+ <para>
+ An invalid cursor name was specified. (SQLSTATE 34000)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-603 (<symbol>ECPG_WARNING_IN_TRANSACTION</symbol>)</term>
+ <listitem>
+ <para>
+ Transaction is in progress. (SQLSTATE 25001)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-604 (<symbol>ECPG_WARNING_NO_TRANSACTION</symbol>)</term>
+ <listitem>
+ <para>
+ There is no active (in-progress) transaction. (SQLSTATE 25P01)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-605 (<symbol>ECPG_WARNING_PORTAL_EXISTS</symbol>)</term>
+ <listitem>
+ <para>
+ An existing cursor name was specified. (SQLSTATE 42P03)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-preproc">
+ <title>Preprocessor Directives</title>
+
+ <para>
+ Several preprocessor directives are available that modify how
+ the <command>ecpg</command> preprocessor parses and processes a
+ file.
+ </para>
+
+ <sect2 id="ecpg-include">
+ <title>Including Files</title>
+
+ <para>
+ To include an external file into your embedded SQL program, use:
+<programlisting>
+EXEC SQL INCLUDE <replaceable>filename</replaceable>;
+EXEC SQL INCLUDE &lt;<replaceable>filename</replaceable>&gt;;
+EXEC SQL INCLUDE "<replaceable>filename</replaceable>";
+</programlisting>
+ The embedded SQL preprocessor will look for a file named
+ <literal><replaceable>filename</replaceable>.h</literal>,
+ preprocess it, and include it in the resulting C output. Thus,
+ embedded SQL statements in the included file are handled correctly.
+ </para>
+
+ <para>
+ The <command>ecpg</command> preprocessor will search a file at
+ several directories in following order:
+
+ <itemizedlist>
+ <listitem><simpara>current directory</simpara></listitem>
+ <listitem><simpara><filename>/usr/local/include</filename></simpara></listitem>
+ <listitem><simpara>PostgreSQL include directory, defined at build time (e.g., <filename>/usr/local/pgsql/include</filename>)</simpara></listitem>
+ <listitem><simpara><filename>/usr/include</filename></simpara></listitem>
+ </itemizedlist>
+
+ But when <literal>EXEC SQL INCLUDE
+ "<replaceable>filename</replaceable>"</literal> is used, only the
+ current directory is searched.
+ </para>
+
+ <para>
+ In each directory, the preprocessor will first look for the file
+ name as given, and if not found will append <literal>.h</literal>
+ to the file name and try again (unless the specified file name
+ already has that suffix).
+ </para>
+
+ <para>
+ Note that <command>EXEC SQL INCLUDE</command> is <emphasis>not</emphasis> the same as:
+<programlisting>
+#include &lt;<replaceable>filename</replaceable>.h&gt;
+</programlisting>
+ because this file would not be subject to SQL command preprocessing.
+ Naturally, you can continue to use the C
+ <literal>#include</literal> directive to include other header
+ files.
+ </para>
+
+ <note>
+ <para>
+ The include file name is case-sensitive, even though the rest of
+ the <literal>EXEC SQL INCLUDE</literal> command follows the normal
+ SQL case-sensitivity rules.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="ecpg-define">
+ <title>The define and undef Directives</title>
+ <para>
+ Similar to the directive <literal>#define</literal> that is known from C,
+ embedded SQL has a similar concept:
+<programlisting>
+EXEC SQL DEFINE <replaceable>name</replaceable>;
+EXEC SQL DEFINE <replaceable>name</replaceable> <replaceable>value</replaceable>;
+</programlisting>
+ So you can define a name:
+<programlisting>
+EXEC SQL DEFINE HAVE_FEATURE;
+</programlisting>
+ And you can also define constants:
+<programlisting>
+EXEC SQL DEFINE MYNUMBER 12;
+EXEC SQL DEFINE MYSTRING 'abc';
+</programlisting>
+ Use <literal>undef</literal> to remove a previous definition:
+<programlisting>
+EXEC SQL UNDEF MYNUMBER;
+</programlisting>
+ </para>
+
+ <para>
+ Of course you can continue to use the C versions <literal>#define</literal>
+ and <literal>#undef</literal> in your embedded SQL program. The difference
+ is where your defined values get evaluated. If you use <literal>EXEC SQL
+ DEFINE</literal> then the <command>ecpg</command> preprocessor evaluates the defines and substitutes
+ the values. For example if you write:
+<programlisting>
+EXEC SQL DEFINE MYNUMBER 12;
+...
+EXEC SQL UPDATE Tbl SET col = MYNUMBER;
+</programlisting>
+ then <command>ecpg</command> will already do the substitution and your C compiler will never
+ see any name or identifier <literal>MYNUMBER</literal>. Note that you cannot use
+ <literal>#define</literal> for a constant that you are going to use in an
+ embedded SQL query because in this case the embedded SQL precompiler is not
+ able to see this declaration.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-ifdef">
+ <title>ifdef, ifndef, elif, else, and endif Directives</title>
+ <para>
+ You can use the following directives to compile code sections conditionally:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>EXEC SQL ifdef <replaceable>name</replaceable>;</literal></term>
+ <listitem>
+ <para>
+ Checks a <replaceable>name</replaceable> and processes subsequent lines if
+ <replaceable>name</replaceable> has been defined via <literal>EXEC SQL define
+ <replaceable>name</replaceable></literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL ifndef <replaceable>name</replaceable>;</literal></term>
+ <listitem>
+ <para>
+ Checks a <replaceable>name</replaceable> and processes subsequent lines if
+ <replaceable>name</replaceable> has <emphasis>not</emphasis> been defined via
+ <literal>EXEC SQL define <replaceable>name</replaceable></literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL elif <replaceable>name</replaceable>;</literal></term>
+ <listitem>
+ <para>
+ Begins an optional alternative section after an
+ <literal>EXEC SQL ifdef <replaceable>name</replaceable></literal> or
+ <literal>EXEC SQL ifndef <replaceable>name</replaceable></literal>
+ directive. Any number of <literal>elif</literal> sections can appear.
+ Lines following an <literal>elif</literal> will be processed
+ if <replaceable>name</replaceable> has been
+ defined <emphasis>and</emphasis> no previous section of the same
+ <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+ construct has been processed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL else;</literal></term>
+ <listitem>
+ <para>
+ Begins an optional, final alternative section after an
+ <literal>EXEC SQL ifdef <replaceable>name</replaceable></literal> or
+ <literal>EXEC SQL ifndef <replaceable>name</replaceable></literal>
+ directive. Subsequent lines will be processed if no previous section
+ of the same
+ <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+ construct has been processed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXEC SQL endif;</literal></term>
+ <listitem>
+ <para>
+ Ends an
+ <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+ construct. Subsequent lines are processed normally.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <literal>ifdef</literal>/<literal>ifndef</literal>...<literal>endif</literal>
+ constructs can be nested, up to 127 levels deep.
+ </para>
+
+ <para>
+ This example will compile exactly one of the three <literal>SET
+ TIMEZONE</literal> commands:
+<programlisting>
+EXEC SQL ifdef TZVAR;
+EXEC SQL SET TIMEZONE TO TZVAR;
+EXEC SQL elif TZNAME;
+EXEC SQL SET TIMEZONE TO TZNAME;
+EXEC SQL else;
+EXEC SQL SET TIMEZONE TO 'GMT';
+EXEC SQL endif;
+</programlisting>
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-process">
+ <title>Processing Embedded SQL Programs</title>
+
+ <para>
+ Now that you have an idea how to form embedded SQL C programs, you
+ probably want to know how to compile them. Before compiling you
+ run the file through the embedded <acronym>SQL</acronym>
+ <acronym>C</acronym> preprocessor, which converts the
+ <acronym>SQL</acronym> statements you used to special function
+ calls. After compiling, you must link with a special library that
+ contains the needed functions. These functions fetch information
+ from the arguments, perform the <acronym>SQL</acronym> command using
+ the <application>libpq</application> interface, and put the result
+ in the arguments specified for output.
+ </para>
+
+ <para>
+ The preprocessor program is called <filename>ecpg</filename> and is
+ included in a normal <productname>PostgreSQL</productname> installation.
+ Embedded SQL programs are typically named with an extension
+ <filename>.pgc</filename>. If you have a program file called
+ <filename>prog1.pgc</filename>, you can preprocess it by simply
+ calling:
+<programlisting>
+ecpg prog1.pgc
+</programlisting>
+ This will create a file called <filename>prog1.c</filename>. If
+ your input files do not follow the suggested naming pattern, you
+ can specify the output file explicitly using the
+ <option>-o</option> option.
+ </para>
+
+ <para>
+ The preprocessed file can be compiled normally, for example:
+<programlisting>
+cc -c prog1.c
+</programlisting>
+ The generated C source files include header files from the
+ <productname>PostgreSQL</productname> installation, so if you installed
+ <productname>PostgreSQL</productname> in a location that is not searched by
+ default, you have to add an option such as
+ <literal>-I/usr/local/pgsql/include</literal> to the compilation
+ command line.
+ </para>
+
+ <para>
+ To link an embedded SQL program, you need to include the
+ <filename>libecpg</filename> library, like so:
+<programlisting>
+cc -o myprog prog1.o prog2.o ... -lecpg
+</programlisting>
+ Again, you might have to add an option like
+ <literal>-L/usr/local/pgsql/lib</literal> to that command line.
+ </para>
+
+ <para>
+ You can
+ use <command>pg_config</command><indexterm><primary>pg_config</primary><secondary sortas="ecpg">with
+ ecpg</secondary></indexterm>
+ or <command>pkg-config</command><indexterm><primary>pkg-config</primary><secondary sortas="ecpg">with
+ ecpg</secondary></indexterm> with package name <literal>libecpg</literal> to
+ get the paths for your installation.
+ </para>
+
+ <para>
+ If you manage the build process of a larger project using
+ <application>make</application>, it might be convenient to include
+ the following implicit rule to your makefiles:
+<programlisting>
+ECPG = ecpg
+
+%.c: %.pgc
+ $(ECPG) $&lt;
+</programlisting>
+ </para>
+
+ <para>
+ The complete syntax of the <command>ecpg</command> command is
+ detailed in <xref linkend="app-ecpg"/>.
+ </para>
+
+ <para>
+ The <application>ecpg</application> library is thread-safe by
+ default. However, you might need to use some threading
+ command-line options to compile your client code.
+ </para>
+ </sect1>
+
+ <sect1 id="ecpg-library">
+ <title>Library Functions</title>
+
+ <para>
+ The <filename>libecpg</filename> library primarily contains
+ <quote>hidden</quote> functions that are used to implement the
+ functionality expressed by the embedded SQL commands. But there
+ are some functions that can usefully be called directly. Note that
+ this makes your code unportable.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <function>ECPGdebug(int <replaceable>on</replaceable>, FILE
+ *<replaceable>stream</replaceable>)</function> turns on debug
+ logging if called with the first argument non-zero. Debug logging
+ is done on <replaceable>stream</replaceable>. The log contains
+ all <acronym>SQL</acronym> statements with all the input
+ variables inserted, and the results from the
+ <productname>PostgreSQL</productname> server. This can be very
+ useful when searching for errors in your <acronym>SQL</acronym>
+ statements.
+ </para>
+ <note>
+ <para>
+ On Windows, if the <application>ecpg</application> libraries and an application are
+ compiled with different flags, this function call will crash the
+ application because the internal representation of the
+ <literal>FILE</literal> pointers differ. Specifically,
+ multithreaded/single-threaded, release/debug, and static/dynamic
+ flags should be the same for the library and all applications using
+ that library.
+ </para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>ECPGget_PGconn(const char *<replaceable>connection_name</replaceable>)
+ </function> returns the library database connection handle identified by the given name.
+ If <replaceable>connection_name</replaceable> is set to <literal>NULL</literal>, the current
+ connection handle is returned. If no connection handle can be identified, the function returns
+ <literal>NULL</literal>. The returned connection handle can be used to call any other functions
+ from <application>libpq</application>, if necessary.
+ </para>
+ <note>
+ <para>
+ It is a bad idea to manipulate database connection handles made from <application>ecpg</application> directly
+ with <application>libpq</application> routines.
+ </para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>ECPGtransactionStatus(const char *<replaceable>connection_name</replaceable>)</function>
+ returns the current transaction status of the given connection identified by <replaceable>connection_name</replaceable>.
+ See <xref linkend="libpq-status"/> and libpq's <xref linkend="libpq-PQtransactionStatus"/> for details about the returned status codes.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>ECPGstatus(int <replaceable>lineno</replaceable>,
+ const char* <replaceable>connection_name</replaceable>)</function>
+ returns true if you are connected to a database and false if not.
+ <replaceable>connection_name</replaceable> can be <literal>NULL</literal>
+ if a single connection is being used.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 id="ecpg-lo">
+ <title>Large Objects</title>
+
+ <para>
+ Large objects are not directly supported by ECPG, but ECPG
+ application can manipulate large objects through the libpq large
+ object functions, obtaining the necessary <type>PGconn</type>
+ object by calling the <function>ECPGget_PGconn()</function>
+ function. (However, use of
+ the <function>ECPGget_PGconn()</function> function and touching
+ <type>PGconn</type> objects directly should be done very carefully
+ and ideally not mixed with other ECPG database access calls.)
+ </para>
+
+ <para>
+ For more details about the <function>ECPGget_PGconn()</function>, see
+ <xref linkend="ecpg-library"/>. For information about the large
+ object function interface, see <xref linkend="largeobjects"/>.
+ </para>
+
+ <para>
+ Large object functions have to be called in a transaction block, so
+ when autocommit is off, <command>BEGIN</command> commands have to
+ be issued explicitly.
+ </para>
+
+ <para>
+ <xref linkend="ecpg-lo-example"/> shows an example program that
+ illustrates how to create, write, and read a large object in an
+ ECPG application.
+ </para>
+
+ <example id="ecpg-lo-example">
+ <title>ECPG Program Accessing Large Objects</title>
+<programlisting><![CDATA[
+#include <stdio.h>
+#include <stdlib.h>
+#include <libpq-fe.h>
+#include <libpq/libpq-fs.h>
+
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+main(void)
+{
+ PGconn *conn;
+ Oid loid;
+ int fd;
+ char buf[256];
+ int buflen = 256;
+ char buf2[256];
+ int rc;
+
+ memset(buf, 1, buflen);
+
+ EXEC SQL CONNECT TO testdb AS con1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ conn = ECPGget_PGconn("con1");
+ printf("conn = %p\n", conn);
+
+ /* create */
+ loid = lo_create(conn, 0);
+ if (loid &lt; 0)
+ printf("lo_create() failed: %s", PQerrorMessage(conn));
+
+ printf("loid = %d\n", loid);
+
+ /* write test */
+ fd = lo_open(conn, loid, INV_READ|INV_WRITE);
+ if (fd &lt; 0)
+ printf("lo_open() failed: %s", PQerrorMessage(conn));
+
+ printf("fd = %d\n", fd);
+
+ rc = lo_write(conn, fd, buf, buflen);
+ if (rc &lt; 0)
+ printf("lo_write() failed\n");
+
+ rc = lo_close(conn, fd);
+ if (rc &lt; 0)
+ printf("lo_close() failed: %s", PQerrorMessage(conn));
+
+ /* read test */
+ fd = lo_open(conn, loid, INV_READ);
+ if (fd &lt; 0)
+ printf("lo_open() failed: %s", PQerrorMessage(conn));
+
+ printf("fd = %d\n", fd);
+
+ rc = lo_read(conn, fd, buf2, buflen);
+ if (rc &lt; 0)
+ printf("lo_read() failed\n");
+
+ rc = lo_close(conn, fd);
+ if (rc &lt; 0)
+ printf("lo_close() failed: %s", PQerrorMessage(conn));
+
+ /* check */
+ rc = memcmp(buf, buf2, buflen);
+ printf("memcmp() = %d\n", rc);
+
+ /* cleanup */
+ rc = lo_unlink(conn, loid);
+ if (rc &lt; 0)
+ printf("lo_unlink() failed: %s", PQerrorMessage(conn));
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+]]></programlisting>
+ </example>
+ </sect1>
+
+ <sect1 id="ecpg-cpp">
+ <title><acronym>C++</acronym> Applications</title>
+
+ <para>
+ ECPG has some limited support for C++ applications. This section
+ describes some caveats.
+ </para>
+
+ <para>
+ The <command>ecpg</command> preprocessor takes an input file
+ written in C (or something like C) and embedded SQL commands,
+ converts the embedded SQL commands into C language chunks, and
+ finally generates a <filename>.c</filename> file. The header file
+ declarations of the library functions used by the C language chunks
+ that <command>ecpg</command> generates are wrapped
+ in <literal>extern "C" { ... }</literal> blocks when used under
+ C++, so they should work seamlessly in C++.
+ </para>
+
+ <para>
+ In general, however, the <command>ecpg</command> preprocessor only
+ understands C; it does not handle the special syntax and reserved
+ words of the C++ language. So, some embedded SQL code written in
+ C++ application code that uses complicated features specific to C++
+ might fail to be preprocessed correctly or might not work as
+ expected.
+ </para>
+
+ <para>
+ A safe way to use the embedded SQL code in a C++ application is
+ hiding the ECPG calls in a C module, which the C++ application code
+ calls into to access the database, and linking that together with
+ the rest of the C++ code. See <xref linkend="ecpg-cpp-and-c"/>
+ about that.
+ </para>
+
+ <sect2 id="ecpg-cpp-scope">
+ <title>Scope for Host Variables</title>
+
+ <para>
+ The <command>ecpg</command> preprocessor understands the scope of
+ variables in C. In the C language, this is rather simple because
+ the scopes of variables is based on their code blocks. In C++,
+ however, the class member variables are referenced in a different
+ code block from the declared position, so
+ the <command>ecpg</command> preprocessor will not understand the
+ scope of the class member variables.
+ </para>
+
+ <para>
+ For example, in the following case, the <command>ecpg</command>
+ preprocessor cannot find any declaration for the
+ variable <literal>dbname</literal> in the <literal>test</literal>
+ method, so an error will occur.
+
+<programlisting>
+class TestCpp
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char dbname[1024];
+ EXEC SQL END DECLARE SECTION;
+
+ public:
+ TestCpp();
+ void test();
+ ~TestCpp();
+};
+
+TestCpp::TestCpp()
+{
+ EXEC SQL CONNECT TO testdb1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+}
+
+void Test::test()
+{
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current_database = %s\n", dbname);
+}
+
+TestCpp::~TestCpp()
+{
+ EXEC SQL DISCONNECT ALL;
+}
+</programlisting>
+
+ This code will result in an error like this:
+<screen>
+<userinput>ecpg test_cpp.pgc</userinput>
+test_cpp.pgc:28: ERROR: variable "dbname" is not declared
+</screen>
+ </para>
+
+ <para>
+ To avoid this scope issue, the <literal>test</literal> method
+ could be modified to use a local variable as intermediate storage.
+ But this approach is only a poor workaround, because it uglifies
+ the code and reduces performance.
+
+<programlisting>
+void TestCpp::test()
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char tmp[1024];
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL SELECT current_database() INTO :tmp;
+ strlcpy(dbname, tmp, sizeof(tmp));
+
+ printf("current_database = %s\n", dbname);
+}
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-cpp-and-c">
+ <title>C++ Application Development with External C Module</title>
+
+ <para>
+ If you understand these technical limitations of
+ the <command>ecpg</command> preprocessor in C++, you might come to
+ the conclusion that linking C objects and C++ objects at the link
+ stage to enable C++ applications to use ECPG features could be
+ better than writing some embedded SQL commands in C++ code
+ directly. This section describes a way to separate some embedded
+ SQL commands from C++ application code with a simple example. In
+ this example, the application is implemented in C++, while C and
+ ECPG is used to connect to the PostgreSQL server.
+ </para>
+
+ <para>
+ Three kinds of files have to be created: a C file
+ (<filename>*.pgc</filename>), a header file, and a C++ file:
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>test_mod.pgc</filename></term>
+ <listitem>
+ <para>
+ A sub-routine module to execute SQL commands embedded in C.
+ It is going to be converted
+ into <filename>test_mod.c</filename> by the preprocessor.
+
+<programlisting>
+#include "test_mod.h"
+#include &lt;stdio.h&gt;
+
+void
+db_connect()
+{
+ EXEC SQL CONNECT TO testdb1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+}
+
+void
+db_test()
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char dbname[1024];
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current_database = %s\n", dbname);
+}
+
+void
+db_disconnect()
+{
+ EXEC SQL DISCONNECT ALL;
+}
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>test_mod.h</filename></term>
+ <listitem>
+ <para>
+ A header file with declarations of the functions in the C
+ module (<filename>test_mod.pgc</filename>). It is included by
+ <filename>test_cpp.cpp</filename>. This file has to have an
+ <literal>extern "C"</literal> block around the declarations,
+ because it will be linked from the C++ module.
+
+<programlisting>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void db_connect();
+void db_test();
+void db_disconnect();
+
+#ifdef __cplusplus
+}
+#endif
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>test_cpp.cpp</filename></term>
+ <listitem>
+ <para>
+ The main code for the application, including
+ the <function>main</function> routine, and in this example a
+ C++ class.
+
+<programlisting>
+#include "test_mod.h"
+
+class TestCpp
+{
+ public:
+ TestCpp();
+ void test();
+ ~TestCpp();
+};
+
+TestCpp::TestCpp()
+{
+ db_connect();
+}
+
+void
+TestCpp::test()
+{
+ db_test();
+}
+
+TestCpp::~TestCpp()
+{
+ db_disconnect();
+}
+
+int
+main(void)
+{
+ TestCpp *t = new TestCpp();
+
+ t->test();
+ return 0;
+}
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ To build the application, proceed as follows. Convert
+ <filename>test_mod.pgc</filename> into <filename>test_mod.c</filename> by
+ running <command>ecpg</command>, and generate
+ <filename>test_mod.o</filename> by compiling
+ <filename>test_mod.c</filename> with the C compiler:
+<programlisting>
+ecpg -o test_mod.c test_mod.pgc
+cc -c test_mod.c -o test_mod.o
+</programlisting>
+ </para>
+
+ <para>
+ Next, generate <filename>test_cpp.o</filename> by compiling
+ <filename>test_cpp.cpp</filename> with the C++ compiler:
+<programlisting>
+c++ -c test_cpp.cpp -o test_cpp.o
+</programlisting>
+ </para>
+
+ <para>
+ Finally, link these object files, <filename>test_cpp.o</filename>
+ and <filename>test_mod.o</filename>, into one executable, using the C++
+ compiler driver:
+<programlisting>
+c++ test_cpp.o test_mod.o -lecpg -o test_cpp
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-sql-commands">
+ <title>Embedded SQL Commands</title>
+
+ <para>
+ This section describes all SQL commands that are specific to
+ embedded SQL. Also refer to the SQL commands listed
+ in <xref linkend="sql-commands"/>, which can also be used in
+ embedded SQL, unless stated otherwise.
+ </para>
+
+ <refentry id="ecpg-sql-allocate-descriptor">
+ <refnamediv>
+ <refname>ALLOCATE DESCRIPTOR</refname>
+ <refpurpose>allocate an SQL descriptor area</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALLOCATE DESCRIPTOR <replaceable class="parameter">name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALLOCATE DESCRIPTOR</command> allocates a new named SQL
+ descriptor area, which can be used to exchange data between the
+ PostgreSQL server and the host program.
+ </para>
+
+ <para>
+ Descriptor areas should be freed after use using
+ the <command>DEALLOCATE DESCRIPTOR</command> command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ A name of SQL descriptor, case sensitive. This can be an SQL
+ identifier or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL ALLOCATE DESCRIPTOR mydesc;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALLOCATE DESCRIPTOR</command> is specified in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-deallocate-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-get-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-set-descriptor"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-connect">
+ <refnamediv>
+ <refname>CONNECT</refname>
+ <refpurpose>establish a database connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CONNECT TO <replaceable>connection_target</replaceable> [ AS <replaceable>connection_name</replaceable> ] [ USER <replaceable>connection_user</replaceable> ]
+CONNECT TO DEFAULT
+CONNECT <replaceable>connection_user</replaceable>
+DATABASE <replaceable>connection_target</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>CONNECT</command> command establishes a connection
+ between the client and the PostgreSQL server.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">connection_target</replaceable></term>
+ <listitem>
+ <para>
+ <replaceable class="parameter">connection_target</replaceable>
+ specifies the target server of the connection on one of
+ several forms.
+
+ <variablelist>
+ <varlistentry>
+ <term>[ <replaceable>database_name</replaceable> ] [ <literal>@</literal><replaceable>host</replaceable> ] [ <literal>:</literal><replaceable>port</replaceable> ]</term>
+ <listitem>
+ <para>
+ Connect over TCP/IP
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unix:postgresql://</literal><replaceable>host</replaceable> [ <literal>:</literal><replaceable>port</replaceable> ] <literal>/</literal> [ <replaceable>database_name</replaceable> ] [ <literal>?</literal><replaceable>connection_option</replaceable> ]</term>
+ <listitem>
+ <para>
+ Connect over Unix-domain sockets
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>tcp:postgresql://</literal><replaceable>host</replaceable> [ <literal>:</literal><replaceable>port</replaceable> ] <literal>/</literal> [ <replaceable>database_name</replaceable> ] [ <literal>?</literal><replaceable>connection_option</replaceable> ]</term>
+ <listitem>
+ <para>
+ Connect over TCP/IP
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SQL string constant</term>
+ <listitem>
+ <para>
+ containing a value in one of the above forms
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>host variable</term>
+ <listitem>
+ <para>
+ host variable of type <type>char[]</type>
+ or <type>VARCHAR[]</type> containing a value in one of the
+ above forms
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">connection_name</replaceable></term>
+ <listitem>
+ <para>
+ An optional identifier for the connection, so that it can be
+ referred to in other commands. This can be an SQL identifier
+ or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">connection_user</replaceable></term>
+ <listitem>
+ <para>
+ The user name for the database connection.
+ </para>
+
+ <para>
+ This parameter can also specify user name and password, using one the forms
+ <literal><replaceable>user_name</replaceable>/<replaceable>password</replaceable></literal>,
+ <literal><replaceable>user_name</replaceable> IDENTIFIED BY <replaceable>password</replaceable></literal>, or
+ <literal><replaceable>user_name</replaceable> USING <replaceable>password</replaceable></literal>.
+ </para>
+
+ <para>
+ User name and password can be SQL identifiers, string
+ constants, or host variables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Use all default connection parameters, as defined by libpq.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Here a several variants for specifying connection parameters:
+<programlisting>
+EXEC SQL CONNECT TO "connectdb" AS main;
+EXEC SQL CONNECT TO "connectdb" AS second;
+EXEC SQL CONNECT TO "unix:postgresql://200.46.204.71/connectdb" AS main USER connectuser;
+EXEC SQL CONNECT TO "unix:postgresql://localhost/connectdb" AS main USER connectuser;
+EXEC SQL CONNECT TO 'connectdb' AS main;
+EXEC SQL CONNECT TO 'unix:postgresql://localhost/connectdb' AS main USER :user;
+EXEC SQL CONNECT TO :db AS :id;
+EXEC SQL CONNECT TO :db USER connectuser USING :pw;
+EXEC SQL CONNECT TO @localhost AS main USER connectdb;
+EXEC SQL CONNECT TO REGRESSDB1 as main;
+EXEC SQL CONNECT TO AS main USER connectdb;
+EXEC SQL CONNECT TO connectdb AS :id;
+EXEC SQL CONNECT TO connectdb AS main USER connectuser/connectdb;
+EXEC SQL CONNECT TO connectdb AS main;
+EXEC SQL CONNECT TO connectdb@localhost AS main;
+EXEC SQL CONNECT TO tcp:postgresql://localhost/ USER connectdb;
+EXEC SQL CONNECT TO tcp:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY connectpw;
+EXEC SQL CONNECT TO tcp:postgresql://localhost:20/connectdb USER connectuser IDENTIFIED BY connectpw;
+EXEC SQL CONNECT TO unix:postgresql://localhost/ AS main USER connectdb;
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb AS main USER connectuser;
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY "connectpw";
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb USER connectuser USING "connectpw";
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb?connect_timeout=14 USER connectuser;
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example program that illustrates the use of host
+ variables to specify connection parameters:
+<programlisting>
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ char *dbname = "testdb"; /* database name */
+ char *user = "testuser"; /* connection user name */
+ char *connection = "tcp:postgresql://localhost:5432/testdb";
+ /* connection string */
+ char ver[256]; /* buffer to store the version string */
+EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+
+ EXEC SQL CONNECT TO :dbname USER :user;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL SELECT version() INTO :ver;
+ EXEC SQL DISCONNECT;
+
+ printf("version: %s\n", ver);
+
+ EXEC SQL CONNECT TO :connection USER :user;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL SELECT version() INTO :ver;
+ EXEC SQL DISCONNECT;
+
+ printf("version: %s\n", ver);
+
+ return 0;
+}
+</programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CONNECT</command> is specified in the SQL standard, but
+ the format of the connection parameters is
+ implementation-specific.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-disconnect"/></member>
+ <member><xref linkend="ecpg-sql-set-connection"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-deallocate-descriptor">
+ <refnamediv>
+ <refname>DEALLOCATE DESCRIPTOR</refname>
+ <refpurpose>deallocate an SQL descriptor area</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DEALLOCATE DESCRIPTOR <replaceable class="parameter">name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DEALLOCATE DESCRIPTOR</command> deallocates a named SQL
+ descriptor area.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the descriptor which is going to be deallocated.
+ It is case sensitive. This can be an SQL identifier or a host
+ variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL DEALLOCATE DESCRIPTOR mydesc;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DEALLOCATE DESCRIPTOR</command> is specified in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-allocate-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-get-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-set-descriptor"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-declare">
+ <refnamediv>
+ <refname>DECLARE</refname>
+ <refpurpose>define a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DECLARE <replaceable class="parameter">cursor_name</replaceable> [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="parameter">prepared_name</replaceable>
+DECLARE <replaceable class="parameter">cursor_name</replaceable> [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="parameter">query</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DECLARE</command> declares a cursor for iterating over
+ the result set of a prepared statement. This command has
+ slightly different semantics from the direct SQL
+ command <command>DECLARE</command>: Whereas the latter executes a
+ query and prepares the result set for retrieval, this embedded
+ SQL command merely declares a name as a <quote>loop
+ variable</quote> for iterating over the result set of a query;
+ the actual execution happens when the cursor is opened with
+ the <command>OPEN</command> command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cursor_name</replaceable></term>
+ <listitem>
+ <para>
+ A cursor name, case sensitive. This can be an SQL identifier
+ or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">prepared_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a prepared query, either as an SQL identifier or a
+ host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">query</replaceable></term>
+ <listitem>
+ <para>
+ A <xref linkend="sql-select"/> or
+ <xref linkend="sql-values"/> command which will provide the
+ rows to be returned by the cursor.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ For the meaning of the cursor options,
+ see <xref linkend="sql-declare"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Examples declaring a cursor for a query:
+<programlisting>
+EXEC SQL DECLARE C CURSOR FOR SELECT * FROM My_Table;
+EXEC SQL DECLARE C CURSOR FOR SELECT Item1 FROM T;
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT version();
+</programlisting>
+ </para>
+
+ <para>
+ An example declaring a cursor for a prepared statement:
+<programlisting>
+EXEC SQL PREPARE stmt1 AS SELECT version();
+EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+</programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DECLARE</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-open"/></member>
+ <member><xref linkend="sql-close"/></member>
+ <member><xref linkend="sql-declare"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-declare-statement">
+ <refnamediv>
+ <refname>DECLARE STATEMENT</refname>
+ <refpurpose>declare SQL statement identifier</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+EXEC SQL [ AT <replaceable class="parameter">connection_name</replaceable> ] DECLARE <replaceable class="parameter">statement_name</replaceable> STATEMENT
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DECLARE STATEMENT</command> declares an SQL statement identifier.
+ SQL statement identifier can be associated with the connection.
+ When the identifier is used by dynamic SQL statements, the statements
+ are executed using the associated connection.
+ The namespace of the declaration is the precompile unit, and multiple
+ declarations to the same SQL statement identifier are not allowed.
+ Note that if the precompiler runs in Informix compatibility mode and
+ some SQL statement is declared, "database" can not be used as a cursor
+ name.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">connection_name</replaceable></term>
+ <listitem>
+ <para>
+ A database connection name established by the <command>CONNECT</command> command.
+ </para>
+ <para>
+ AT clause can be omitted, but such statement has no meaning.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">statement_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an SQL statement identifier, either as an SQL identifier or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ This association is valid only if the declaration is physically placed on top of a dynamic statement.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL CONNECT TO postgres AS con1;
+EXEC SQL AT con1 DECLARE sql_stmt STATEMENT;
+EXEC SQL DECLARE cursor_name CURSOR FOR sql_stmt;
+EXEC SQL PREPARE sql_stmt FROM :dyn_string;
+EXEC SQL OPEN cursor_name;
+EXEC SQL FETCH cursor_name INTO :column1;
+EXEC SQL CLOSE cursor_name;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DECLARE STATEMENT</command> is an extension of the SQL standard,
+ but can be used in famous DBMSs.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-connect"/></member>
+ <member><xref linkend="ecpg-sql-declare"/></member>
+ <member><xref linkend="ecpg-sql-open"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-describe">
+ <refnamediv>
+ <refname>DESCRIBE</refname>
+ <refpurpose>obtain information about a prepared statement or result set</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DESCRIBE [ OUTPUT ] <replaceable class="parameter">prepared_name</replaceable> USING [ SQL ] DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable>
+DESCRIBE [ OUTPUT ] <replaceable class="parameter">prepared_name</replaceable> INTO [ SQL ] DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable>
+DESCRIBE [ OUTPUT ] <replaceable class="parameter">prepared_name</replaceable> INTO <replaceable class="parameter">sqlda_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DESCRIBE</command> retrieves metadata information about
+ the result columns contained in a prepared statement, without
+ actually fetching a row.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">prepared_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a prepared statement. This can be an SQL
+ identifier or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_name</replaceable></term>
+ <listitem>
+ <para>
+ A descriptor name. It is case sensitive. It can be an SQL
+ identifier or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sqlda_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an SQLDA variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL ALLOCATE DESCRIPTOR mydesc;
+EXEC SQL PREPARE stmt1 FROM :sql_stmt;
+EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
+EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :charvar = NAME;
+EXEC SQL DEALLOCATE DESCRIPTOR mydesc;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DESCRIBE</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-allocate-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-get-descriptor"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-disconnect">
+ <refnamediv>
+ <refname>DISCONNECT</refname>
+ <refpurpose>terminate a database connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DISCONNECT <replaceable class="parameter">connection_name</replaceable>
+DISCONNECT [ CURRENT ]
+DISCONNECT DEFAULT
+DISCONNECT ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DISCONNECT</command> closes a connection (or all
+ connections) to the database.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">connection_name</replaceable></term>
+ <listitem>
+ <para>
+ A database connection name established by
+ the <command>CONNECT</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CURRENT</literal></term>
+ <listitem>
+ <para>
+ Close the <quote>current</quote> connection, which is either
+ the most recently opened connection, or the connection set by
+ the <command>SET CONNECTION</command> command. This is also
+ the default if no argument is given to
+ the <command>DISCONNECT</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Close the default connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Close all open connections.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+int
+main(void)
+{
+ EXEC SQL CONNECT TO testdb AS DEFAULT USER testuser;
+ EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+ EXEC SQL CONNECT TO testdb AS con2 USER testuser;
+ EXEC SQL CONNECT TO testdb AS con3 USER testuser;
+
+ EXEC SQL DISCONNECT CURRENT; /* close con3 */
+ EXEC SQL DISCONNECT DEFAULT; /* close DEFAULT */
+ EXEC SQL DISCONNECT ALL; /* close con2 and con1 */
+
+ return 0;
+}
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DISCONNECT</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-connect"/></member>
+ <member><xref linkend="ecpg-sql-set-connection"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-execute-immediate">
+ <refnamediv>
+ <refname>EXECUTE IMMEDIATE</refname>
+ <refpurpose>dynamically prepare and execute a statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+EXECUTE IMMEDIATE <replaceable class="parameter">string</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>EXECUTE IMMEDIATE</command> immediately prepares and
+ executes a dynamically specified SQL statement, without
+ retrieving result rows.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">string</replaceable></term>
+ <listitem>
+ <para>
+ A literal string or a host variable containing the SQL
+ statement to be executed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ In typical usage, the <replaceable>string</replaceable> is a host
+ variable reference to a string containing a dynamically-constructed
+ SQL statement. The case of a literal string is not very useful;
+ you might as well just write the SQL statement directly, without
+ the extra typing of <command>EXECUTE IMMEDIATE</command>.
+ </para>
+
+ <para>
+ If you do use a literal string, keep in mind that any double quotes
+ you might wish to include in the SQL statement must be written as
+ octal escapes (<literal>\042</literal>) not the usual C
+ idiom <literal>\"</literal>. This is because the string is inside
+ an <literal>EXEC SQL</literal> section, so the ECPG lexer parses it
+ according to SQL rules not C rules. Any embedded backslashes will
+ later be handled according to C rules; but <literal>\"</literal>
+ causes an immediate syntax error because it is seen as ending the
+ literal.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Here is an example that executes an <command>INSERT</command>
+ statement using <command>EXECUTE IMMEDIATE</command> and a host
+ variable named <varname>command</varname>:
+<programlisting>
+sprintf(command, "INSERT INTO test (name, amount, letter) VALUES ('db: ''r1''', 1, 'f')");
+EXEC SQL EXECUTE IMMEDIATE :command;
+</programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>EXECUTE IMMEDIATE</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-get-descriptor">
+ <refnamediv>
+ <refname>GET DESCRIPTOR</refname>
+ <refpurpose>get information from an SQL descriptor area</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+GET DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable> <replaceable class="parameter">:cvariable</replaceable> = <replaceable class="parameter">descriptor_header_item</replaceable> [, ... ]
+GET DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable> VALUE <replaceable class="parameter">column_number</replaceable> <replaceable class="parameter">:cvariable</replaceable> = <replaceable class="parameter">descriptor_item</replaceable> [, ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>GET DESCRIPTOR</command> retrieves information about a
+ query result set from an SQL descriptor area and stores it into
+ host variables. A descriptor area is typically populated
+ using <command>FETCH</command> or <command>SELECT</command>
+ before using this command to transfer the information into host
+ language variables.
+ </para>
+
+ <para>
+ This command has two forms: The first form retrieves
+ descriptor <quote>header</quote> items, which apply to the result
+ set in its entirety. One example is the row count. The second
+ form, which requires the column number as additional parameter,
+ retrieves information about a particular column. Examples are
+ the column name and the actual column value.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_name</replaceable></term>
+ <listitem>
+ <para>
+ A descriptor name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_header_item</replaceable></term>
+ <listitem>
+ <para>
+ A token identifying which header information item to retrieve.
+ Only <literal>COUNT</literal>, to get the number of columns in the
+ result set, is currently supported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_number</replaceable></term>
+ <listitem>
+ <para>
+ The number of the column about which information is to be
+ retrieved. The count starts at 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_item</replaceable></term>
+ <listitem>
+ <para>
+ A token identifying which item of information about a column
+ to retrieve. See <xref linkend="ecpg-named-descriptors"/> for
+ a list of supported items.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cvariable</replaceable></term>
+ <listitem>
+ <para>
+ A host variable that will receive the data retrieved from the
+ descriptor area.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ An example to retrieve the number of columns in a result set:
+<programlisting>
+EXEC SQL GET DESCRIPTOR d :d_count = COUNT;
+</programlisting>
+ </para>
+
+ <para>
+ An example to retrieve a data length in the first column:
+<programlisting>
+EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH;
+</programlisting>
+ </para>
+
+ <para>
+ An example to retrieve the data body of the second column as a
+ string:
+<programlisting>
+EXEC SQL GET DESCRIPTOR d VALUE 2 :d_data = DATA;
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example for a whole procedure of
+ executing <literal>SELECT current_database();</literal> and showing the number of
+ columns, the column data length, and the column data:
+<programlisting>
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ int d_count;
+ char d_data[1024];
+ int d_returned_octet_length;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL ALLOCATE DESCRIPTOR d;
+
+ /* Declare, open a cursor, and assign a descriptor to the cursor */
+ EXEC SQL DECLARE cur CURSOR FOR SELECT current_database();
+ EXEC SQL OPEN cur;
+ EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d;
+
+ /* Get a number of total columns */
+ EXEC SQL GET DESCRIPTOR d :d_count = COUNT;
+ printf("d_count = %d\n", d_count);
+
+ /* Get length of a returned column */
+ EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH;
+ printf("d_returned_octet_length = %d\n", d_returned_octet_length);
+
+ /* Fetch the returned column as a string */
+ EXEC SQL GET DESCRIPTOR d VALUE 1 :d_data = DATA;
+ printf("d_data = %s\n", d_data);
+
+ /* Closing */
+ EXEC SQL CLOSE cur;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DEALLOCATE DESCRIPTOR d;
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+</programlisting>
+ When the example is executed, the result will look like this:
+<screen>
+d_count = 1
+d_returned_octet_length = 6
+d_data = testdb
+</screen>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>GET DESCRIPTOR</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-allocate-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-set-descriptor"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-open">
+ <refnamediv>
+ <refname>OPEN</refname>
+ <refpurpose>open a dynamic cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+OPEN <replaceable class="parameter">cursor_name</replaceable>
+OPEN <replaceable class="parameter">cursor_name</replaceable> USING <replaceable class="parameter">value</replaceable> [, ... ]
+OPEN <replaceable class="parameter">cursor_name</replaceable> USING SQL DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>OPEN</command> opens a cursor and optionally binds
+ actual values to the placeholders in the cursor's declaration.
+ The cursor must previously have been declared with
+ the <command>DECLARE</command> command. The execution
+ of <command>OPEN</command> causes the query to start executing on
+ the server.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">cursor_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the cursor to be opened. This can be an SQL
+ identifier or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ A value to be bound to a placeholder in the cursor. This can
+ be an SQL constant, a host variable, or a host variable with
+ indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a descriptor containing values to be bound to the
+ placeholders in the cursor. This can be an SQL identifier or
+ a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL OPEN a;
+EXEC SQL OPEN d USING 1, 'test';
+EXEC SQL OPEN c1 USING SQL DESCRIPTOR mydesc;
+EXEC SQL OPEN :curname1;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>OPEN</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-declare"/></member>
+ <member><xref linkend="sql-close"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-prepare">
+ <refnamediv>
+ <refname>PREPARE</refname>
+ <refpurpose>prepare a statement for execution</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+PREPARE <replaceable class="parameter">prepared_name</replaceable> FROM <replaceable class="parameter">string</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>PREPARE</command> prepares a statement dynamically
+ specified as a string for execution. This is different from the
+ direct SQL statement <xref linkend="sql-prepare"/>, which can also
+ be used in embedded programs. The <xref linkend="sql-execute"/>
+ command is used to execute either kind of prepared statement.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">prepared_name</replaceable></term>
+ <listitem>
+ <para>
+ An identifier for the prepared query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">string</replaceable></term>
+ <listitem>
+ <para>
+ A literal string or a host variable containing a preparable
+ SQL statement, one of SELECT, INSERT, UPDATE, or DELETE.
+ Use question marks (<literal>?</literal>) for parameter values
+ to be supplied at execution.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ In typical usage, the <replaceable>string</replaceable> is a host
+ variable reference to a string containing a dynamically-constructed
+ SQL statement. The case of a literal string is not very useful;
+ you might as well just write a direct SQL <command>PREPARE</command>
+ statement.
+ </para>
+
+ <para>
+ If you do use a literal string, keep in mind that any double quotes
+ you might wish to include in the SQL statement must be written as
+ octal escapes (<literal>\042</literal>) not the usual C
+ idiom <literal>\"</literal>. This is because the string is inside
+ an <literal>EXEC SQL</literal> section, so the ECPG lexer parses it
+ according to SQL rules not C rules. Any embedded backslashes will
+ later be handled according to C rules; but <literal>\"</literal>
+ causes an immediate syntax error because it is seen as ending the
+ literal.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+<programlisting>
+char *stmt = "SELECT * FROM test1 WHERE a = ? AND b = ?";
+
+EXEC SQL ALLOCATE DESCRIPTOR outdesc;
+EXEC SQL PREPARE foo FROM :stmt;
+
+EXEC SQL EXECUTE foo USING SQL DESCRIPTOR indesc INTO SQL DESCRIPTOR outdesc;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>PREPARE</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-execute"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-set-autocommit">
+ <refnamediv>
+ <refname>SET AUTOCOMMIT</refname>
+ <refpurpose>set the autocommit behavior of the current session</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET AUTOCOMMIT { = | TO } { ON | OFF }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SET AUTOCOMMIT</command> sets the autocommit behavior of
+ the current database session. By default, embedded SQL programs
+ are <emphasis>not</emphasis> in autocommit mode,
+ so <command>COMMIT</command> needs to be issued explicitly when
+ desired. This command can change the session to autocommit mode,
+ where each individual statement is committed implicitly.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>SET AUTOCOMMIT</command> is an extension of PostgreSQL ECPG.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-set-connection">
+ <refnamediv>
+ <refname>SET CONNECTION</refname>
+ <refpurpose>select a database connection</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET CONNECTION [ TO | = ] <replaceable class="parameter">connection_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SET CONNECTION</command> sets the <quote>current</quote>
+ database connection, which is the one that all commands use
+ unless overridden.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">connection_name</replaceable></term>
+ <listitem>
+ <para>
+ A database connection name established by
+ the <command>CONNECT</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Set the connection to the default connection.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL SET CONNECTION TO con2;
+EXEC SQL SET CONNECTION = con1;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>SET CONNECTION</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-connect"/></member>
+ <member><xref linkend="ecpg-sql-disconnect"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-set-descriptor">
+ <refnamediv>
+ <refname>SET DESCRIPTOR</refname>
+ <refpurpose>set information in an SQL descriptor area</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable> <replaceable class="parameter">descriptor_header_item</replaceable> = <replaceable>value</replaceable> [, ... ]
+SET DESCRIPTOR <replaceable class="parameter">descriptor_name</replaceable> VALUE <replaceable class="parameter">number</replaceable> <replaceable class="parameter">descriptor_item</replaceable> = <replaceable>value</replaceable> [, ...]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SET DESCRIPTOR</command> populates an SQL descriptor
+ area with values. The descriptor area is then typically used to
+ bind parameters in a prepared query execution.
+ </para>
+
+ <para>
+ This command has two forms: The first form applies to the
+ descriptor <quote>header</quote>, which is independent of a
+ particular datum. The second form assigns values to particular
+ datums, identified by number.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_name</replaceable></term>
+ <listitem>
+ <para>
+ A descriptor name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_header_item</replaceable></term>
+ <listitem>
+ <para>
+ A token identifying which header information item to set.
+ Only <literal>COUNT</literal>, to set the number of descriptor
+ items, is currently supported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">number</replaceable></term>
+ <listitem>
+ <para>
+ The number of the descriptor item to set. The count starts at
+ 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">descriptor_item</replaceable></term>
+ <listitem>
+ <para>
+ A token identifying which item of information to set in the
+ descriptor. See <xref linkend="ecpg-named-descriptors"/> for a
+ list of supported items.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ A value to store into the descriptor item. This can be an SQL
+ constant or a host variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+<programlisting>
+EXEC SQL SET DESCRIPTOR indesc COUNT = 1;
+EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2;
+EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1;
+EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val1, DATA = 'some string';
+EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2null, DATA = :val2;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>SET DESCRIPTOR</command> is specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="ecpg-sql-allocate-descriptor"/></member>
+ <member><xref linkend="ecpg-sql-get-descriptor"/></member>
+ </simplelist>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-type">
+ <refnamediv>
+ <refname>TYPE</refname>
+ <refpurpose>define a new data type</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+TYPE <replaceable class="parameter">type_name</replaceable> IS <replaceable class="parameter">ctype</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>TYPE</command> command defines a new C type. It is
+ equivalent to putting a <literal>typedef</literal> into a declare
+ section.
+ </para>
+
+ <para>
+ This command is only recognized when <command>ecpg</command> is
+ run with the <option>-c</option> option.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">type_name</replaceable></term>
+ <listitem>
+ <para>
+ The name for the new type. It must be a valid C type name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">ctype</replaceable></term>
+ <listitem>
+ <para>
+ A C type specification.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL TYPE customer IS
+ struct
+ {
+ varchar name[50];
+ int phone;
+ };
+
+EXEC SQL TYPE cust_ind IS
+ struct ind
+ {
+ short name_ind;
+ short phone_ind;
+ };
+
+EXEC SQL TYPE c IS char reference;
+EXEC SQL TYPE ind IS union { int integer; short smallint; };
+EXEC SQL TYPE intarray IS int[AMOUNT];
+EXEC SQL TYPE str IS varchar[BUFFERSIZ];
+EXEC SQL TYPE string IS char[11];
+</programlisting>
+
+ <para>
+ Here is an example program that uses <command>EXEC SQL
+ TYPE</command>:
+<programlisting>
+EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+EXEC SQL TYPE tt IS
+ struct
+ {
+ varchar v[256];
+ int i;
+ };
+
+EXEC SQL TYPE tt_ind IS
+ struct ind {
+ short v_ind;
+ short i_ind;
+ };
+
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ tt t;
+ tt_ind t_ind;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb AS con1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ EXEC SQL SELECT current_database(), 256 INTO :t:t_ind LIMIT 1;
+
+ printf("t.v = %s\n", t.v.arr);
+ printf("t.i = %d\n", t.i);
+
+ printf("t_ind.v_ind = %d\n", t_ind.v_ind);
+ printf("t_ind.i_ind = %d\n", t_ind.i_ind);
+
+ EXEC SQL DISCONNECT con1;
+
+ return 0;
+}
+</programlisting>
+
+ The output from this program looks like this:
+<screen>
+t.v = testdb
+t.i = 256
+t_ind.v_ind = 0
+t_ind.i_ind = 0
+</screen>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>TYPE</command> command is a PostgreSQL extension.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-var">
+ <refnamediv>
+ <refname>VAR</refname>
+ <refpurpose>define a variable</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+VAR <replaceable>varname</replaceable> IS <replaceable>ctype</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>VAR</command> command assigns a new C data type
+ to a host variable. The host variable must be previously
+ declared in a declare section.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">varname</replaceable></term>
+ <listitem>
+ <para>
+ A C variable name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">ctype</replaceable></term>
+ <listitem>
+ <para>
+ A C type specification.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+Exec sql begin declare section;
+short a;
+exec sql end declare section;
+EXEC SQL VAR a IS int;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>VAR</command> command is a PostgreSQL extension.
+ </para>
+ </refsect1>
+ </refentry>
+
+ <refentry id="ecpg-sql-whenever">
+ <refnamediv>
+ <refname>WHENEVER</refname>
+ <refpurpose>specify the action to be taken when an SQL statement causes a specific class condition to be raised</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+WHENEVER { NOT FOUND | SQLERROR | SQLWARNING } <replaceable class="parameter">action</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ Define a behavior which is called on the special cases (Rows not
+ found, SQL warnings or errors) in the result of SQL execution.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ See <xref linkend="ecpg-whenever"/> for a description of the
+ parameters.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+EXEC SQL WHENEVER NOT FOUND CONTINUE;
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+EXEC SQL WHENEVER NOT FOUND DO CONTINUE;
+EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+EXEC SQL WHENEVER SQLWARNING DO warn();
+EXEC SQL WHENEVER SQLERROR sqlprint;
+EXEC SQL WHENEVER SQLERROR CALL print2();
+EXEC SQL WHENEVER SQLERROR DO handle_error("select");
+EXEC SQL WHENEVER SQLERROR DO sqlnotice(NULL, NONO);
+EXEC SQL WHENEVER SQLERROR DO sqlprint();
+EXEC SQL WHENEVER SQLERROR GOTO error_label;
+EXEC SQL WHENEVER SQLERROR STOP;
+</programlisting>
+
+ <para>
+ A typical application is the use of <literal>WHENEVER NOT FOUND
+ BREAK</literal> to handle looping through result sets:
+<programlisting>
+int
+main(void)
+{
+ EXEC SQL CONNECT TO testdb AS con1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL ALLOCATE DESCRIPTOR d;
+ EXEC SQL DECLARE cur CURSOR FOR SELECT current_database(), 'hoge', 256;
+ EXEC SQL OPEN cur;
+
+ /* when end of result set reached, break out of while loop */
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d;
+ ...
+ }
+
+ EXEC SQL CLOSE cur;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DEALLOCATE DESCRIPTOR d;
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+</programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>WHENEVER</command> is specified in the SQL standard, but
+ most of the actions are PostgreSQL extensions.
+ </para>
+ </refsect1>
+ </refentry>
+ </sect1>
+
+ <sect1 id="ecpg-informix-compat">
+ <title><productname>Informix</productname> Compatibility Mode</title>
+ <para>
+ <command>ecpg</command> can be run in a so-called <firstterm>Informix compatibility mode</firstterm>. If
+ this mode is active, it tries to behave as if it were the <productname>Informix</productname>
+ precompiler for <productname>Informix</productname> E/SQL. Generally spoken this will allow you to use
+ the dollar sign instead of the <literal>EXEC SQL</literal> primitive to introduce
+ embedded SQL commands:
+<programlisting>
+$int j = 3;
+$CONNECT TO :dbname;
+$CREATE TABLE test(i INT PRIMARY KEY, j INT);
+$INSERT INTO test(i, j) VALUES (7, :j);
+$COMMIT;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ There must not be any white space between the <literal>$</literal>
+ and a following preprocessor directive, that is,
+ <literal>include</literal>, <literal>define</literal>, <literal>ifdef</literal>,
+ etc. Otherwise, the preprocessor will parse the token as a host
+ variable.
+ </para>
+ </note>
+
+ <para>
+ There are two compatibility modes: <literal>INFORMIX</literal>, <literal>INFORMIX_SE</literal>
+ </para>
+ <para>
+ When linking programs that use this compatibility mode, remember to link
+ against <literal>libcompat</literal> that is shipped with ECPG.
+ </para>
+ <para>
+ Besides the previously explained syntactic sugar, the <productname>Informix</productname> compatibility
+ mode ports some functions for input, output and transformation of data as
+ well as embedded SQL statements known from E/SQL to ECPG.
+ </para>
+ <para>
+ <productname>Informix</productname> compatibility mode is closely connected to the pgtypeslib library
+ of ECPG. pgtypeslib maps SQL data types to data types within the C host
+ program and most of the additional functions of the <productname>Informix</productname> compatibility
+ mode allow you to operate on those C host program types. Note however that
+ the extent of the compatibility is limited. It does not try to copy <productname>Informix</productname>
+ behavior; it allows you to do more or less the same operations and gives
+ you functions that have the same name and the same basic behavior but it is
+ no drop-in replacement if you are using <productname>Informix</productname> at the moment. Moreover,
+ some of the data types are different. For example,
+ <productname>PostgreSQL</productname>'s datetime and interval types do not
+ know about ranges like for example <literal>YEAR TO MINUTE</literal> so you won't
+ find support in ECPG for that either.
+ </para>
+
+ <sect2 id="ecpg-informix-types">
+ <title>Additional Types</title>
+ <para>
+ The Informix-special "string" pseudo-type for storing right-trimmed character string data is now
+ supported in Informix-mode without using <literal>typedef</literal>. In fact, in Informix-mode,
+ ECPG refuses to process source files that contain <literal>typedef sometype string;</literal>
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+string userid; /* this variable will contain trimmed data */
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL FETCH MYCUR INTO :userid;
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-informix-statements">
+ <title>Additional/Missing Embedded SQL Statements</title>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><literal>CLOSE DATABASE</literal></term>
+ <listitem>
+ <para>
+ This statement closes the current connection. In fact, this is a
+ synonym for ECPG's <literal>DISCONNECT CURRENT</literal>:
+<programlisting>
+$CLOSE DATABASE; /* close the current connection */
+EXEC SQL CLOSE DATABASE;
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>FREE cursor_name</literal></term>
+ <listitem>
+ <para>
+ Due to differences in how ECPG works compared to Informix's ESQL/C (namely, which steps
+ are purely grammar transformations and which steps rely on the underlying run-time library)
+ there is no <literal>FREE cursor_name</literal> statement in ECPG. This is because in ECPG,
+ <literal>DECLARE CURSOR</literal> doesn't translate to a function call into
+ the run-time library that uses to the cursor name. This means that there's no run-time
+ bookkeeping of SQL cursors in the ECPG run-time library, only in the PostgreSQL server.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>FREE statement_name</literal></term>
+ <listitem>
+ <para>
+ <literal>FREE statement_name</literal> is a synonym for <literal>DEALLOCATE PREPARE statement_name</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-informix-sqlda">
+ <title>Informix-compatible SQLDA Descriptor Areas</title>
+ <para>
+ Informix-compatible mode supports a different structure than the one described in
+ <xref linkend="ecpg-sqlda-descriptors"/>. See below:
+<programlisting>
+struct sqlvar_compat
+{
+ short sqltype;
+ int sqllen;
+ char *sqldata;
+ short *sqlind;
+ char *sqlname;
+ char *sqlformat;
+ short sqlitype;
+ short sqlilen;
+ char *sqlidata;
+ int sqlxid;
+ char *sqltypename;
+ short sqltypelen;
+ short sqlownerlen;
+ short sqlsourcetype;
+ char *sqlownername;
+ int sqlsourceid;
+ char *sqlilongdata;
+ int sqlflags;
+ void *sqlreserved;
+};
+
+struct sqlda_compat
+{
+ short sqld;
+ struct sqlvar_compat *sqlvar;
+ char desc_name[19];
+ short desc_occ;
+ struct sqlda_compat *desc_next;
+ void *reserved;
+};
+
+typedef struct sqlvar_compat sqlvar_t;
+typedef struct sqlda_compat sqlda_t;
+</programlisting>
+ </para>
+
+ <para>
+ The global properties are:
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>sqld</literal></term>
+ <listitem>
+ <para>
+ The number of fields in the <literal>SQLDA</literal> descriptor.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlvar</literal></term>
+ <listitem>
+ <para>
+ Pointer to the per-field properties.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>desc_name</literal></term>
+ <listitem>
+ <para>
+ Unused, filled with zero-bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>desc_occ</literal></term>
+ <listitem>
+ <para>
+ Size of the allocated structure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>desc_next</literal></term>
+ <listitem>
+ <para>
+ Pointer to the next SQLDA structure if the result set contains more than one record.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>reserved</literal></term>
+ <listitem>
+ <para>
+ Unused pointer, contains NULL. Kept for Informix-compatibility.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ The per-field properties are below, they are stored in the <literal>sqlvar</literal> array:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>sqltype</literal></term>
+ <listitem>
+ <para>
+ Type of the field. Constants are in <literal>sqltypes.h</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqllen</literal></term>
+ <listitem>
+ <para>
+ Length of the field data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqldata</literal></term>
+ <listitem>
+ <para>
+ Pointer to the field data. The pointer is of <literal>char *</literal> type,
+ the data pointed by it is in a binary format. Example:
+<programlisting>
+int intval;
+
+switch (sqldata->sqlvar[i].sqltype)
+{
+ case SQLINTEGER:
+ intval = *(int *)sqldata->sqlvar[i].sqldata;
+ break;
+ ...
+}
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlind</literal></term>
+ <listitem>
+ <para>
+ Pointer to the NULL indicator. If returned by DESCRIBE or FETCH then it's always a valid pointer.
+ If used as input for <literal>EXECUTE ... USING sqlda;</literal> then NULL-pointer value means
+ that the value for this field is non-NULL. Otherwise a valid pointer and <literal>sqlitype</literal>
+ has to be properly set. Example:
+<programlisting>
+if (*(int2 *)sqldata->sqlvar[i].sqlind != 0)
+ printf("value is NULL\n");
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlname</literal></term>
+ <listitem>
+ <para>
+ Name of the field. 0-terminated string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlformat</literal></term>
+ <listitem>
+ <para>
+ Reserved in Informix, value of <xref linkend="libpq-PQfformat"/> for the field.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlitype</literal></term>
+ <listitem>
+ <para>
+ Type of the NULL indicator data. It's always SQLSMINT when returning data from the server.
+ When the <literal>SQLDA</literal> is used for a parameterized query, the data is treated
+ according to the set type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlilen</literal></term>
+ <listitem>
+ <para>
+ Length of the NULL indicator data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlxid</literal></term>
+ <listitem>
+ <para>
+ Extended type of the field, result of <xref linkend="libpq-PQftype"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqltypename</literal></term>
+ <term><literal>sqltypelen</literal></term>
+ <term><literal>sqlownerlen</literal></term>
+ <term><literal>sqlsourcetype</literal></term>
+ <term><literal>sqlownername</literal></term>
+ <term><literal>sqlsourceid</literal></term>
+ <term><literal>sqlflags</literal></term>
+ <term><literal>sqlreserved</literal></term>
+ <listitem>
+ <para>
+ Unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>sqlilongdata</literal></term>
+ <listitem>
+ <para>
+ It equals to <literal>sqldata</literal> if <literal>sqllen</literal> is larger than 32kB.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ Example:
+<programlisting>
+EXEC SQL INCLUDE sqlda.h;
+
+ sqlda_t *sqlda; /* This doesn't need to be under embedded DECLARE SECTION */
+
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *prep_stmt = "select * from table1";
+ int i;
+ EXEC SQL END DECLARE SECTION;
+
+ ...
+
+ EXEC SQL PREPARE mystmt FROM :prep_stmt;
+
+ EXEC SQL DESCRIBE mystmt INTO sqlda;
+
+ printf("# of fields: %d\n", sqlda-&gt;sqld);
+ for (i = 0; i &lt; sqlda-&gt;sqld; i++)
+ printf("field %d: \"%s\"\n", sqlda-&gt;sqlvar[i]-&gt;sqlname);
+
+ EXEC SQL DECLARE mycursor CURSOR FOR mystmt;
+ EXEC SQL OPEN mycursor;
+ EXEC SQL WHENEVER NOT FOUND GOTO out;
+
+ while (1)
+ {
+ EXEC SQL FETCH mycursor USING sqlda;
+ }
+
+ EXEC SQL CLOSE mycursor;
+
+ free(sqlda); /* The main structure is all to be free(),
+ * sqlda and sqlda-&gt;sqlvar is in one allocated area */
+</programlisting>
+ For more information, see the <literal>sqlda.h</literal> header and the
+ <literal>src/interfaces/ecpg/test/compat_informix/sqlda.pgc</literal> regression test.
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-informix-functions">
+ <title>Additional Functions</title>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><function>decadd</function></term>
+ <listitem>
+ <para>
+ Add two decimal type values.
+<synopsis>
+int decadd(decimal *arg1, decimal *arg2, decimal *sum);
+</synopsis>
+ The function receives a pointer to the first operand of type decimal
+ (<literal>arg1</literal>), a pointer to the second operand of type decimal
+ (<literal>arg2</literal>) and a pointer to a value of type decimal that will
+ contain the sum (<literal>sum</literal>). On success, the function returns 0.
+ <symbol>ECPG_INFORMIX_NUM_OVERFLOW</symbol> is returned in case of overflow and
+ <symbol>ECPG_INFORMIX_NUM_UNDERFLOW</symbol> in case of underflow. -1 is returned for
+ other failures and <varname>errno</varname> is set to the respective <varname>errno</varname> number of the
+ pgtypeslib.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>deccmp</function></term>
+ <listitem>
+ <para>
+ Compare two variables of type decimal.
+<synopsis>
+int deccmp(decimal *arg1, decimal *arg2);
+</synopsis>
+ The function receives a pointer to the first decimal value
+ (<literal>arg1</literal>), a pointer to the second decimal value
+ (<literal>arg2</literal>) and returns an integer value that indicates which is
+ the bigger value.
+ <itemizedlist>
+ <listitem>
+ <para>
+ 1, if the value that <literal>arg1</literal> points to is bigger than the
+ value that <literal>var2</literal> points to
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ -1, if the value that <literal>arg1</literal> points to is smaller than the
+ value that <literal>arg2</literal> points to </para>
+ </listitem>
+ <listitem>
+ <para>
+ 0, if the value that <literal>arg1</literal> points to and the value that
+ <literal>arg2</literal> points to are equal
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>deccopy</function></term>
+ <listitem>
+ <para>
+ Copy a decimal value.
+<synopsis>
+void deccopy(decimal *src, decimal *target);
+</synopsis>
+ The function receives a pointer to the decimal value that should be
+ copied as the first argument (<literal>src</literal>) and a pointer to the
+ target structure of type decimal (<literal>target</literal>) as the second
+ argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>deccvasc</function></term>
+ <listitem>
+ <para>
+ Convert a value from its ASCII representation into a decimal type.
+<synopsis>
+int deccvasc(char *cp, int len, decimal *np);
+</synopsis>
+ The function receives a pointer to string that contains the string
+ representation of the number to be converted (<literal>cp</literal>) as well
+ as its length <literal>len</literal>. <literal>np</literal> is a pointer to the
+ decimal value that saves the result of the operation.
+ </para>
+ <para>
+ Valid formats are for example:
+ <literal>-2</literal>,
+ <literal>.794</literal>,
+ <literal>+3.44</literal>,
+ <literal>592.49E07</literal> or
+ <literal>-32.84e-4</literal>.
+ </para>
+ <para>
+ The function returns 0 on success. If overflow or underflow occurred,
+ <literal>ECPG_INFORMIX_NUM_OVERFLOW</literal> or
+ <literal>ECPG_INFORMIX_NUM_UNDERFLOW</literal> is returned. If the ASCII
+ representation could not be parsed,
+ <literal>ECPG_INFORMIX_BAD_NUMERIC</literal> is returned or
+ <literal>ECPG_INFORMIX_BAD_EXPONENT</literal> if this problem occurred while
+ parsing the exponent.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>deccvdbl</function></term>
+ <listitem>
+ <para>
+ Convert a value of type double to a value of type decimal.
+<synopsis>
+int deccvdbl(double dbl, decimal *np);
+</synopsis>
+ The function receives the variable of type double that should be
+ converted as its first argument (<literal>dbl</literal>). As the second
+ argument (<literal>np</literal>), the function receives a pointer to the
+ decimal variable that should hold the result of the operation.
+ </para>
+ <para>
+ The function returns 0 on success and a negative value if the
+ conversion failed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>deccvint</function></term>
+ <listitem>
+ <para>
+ Convert a value of type int to a value of type decimal.
+<synopsis>
+int deccvint(int in, decimal *np);
+</synopsis>
+ The function receives the variable of type int that should be
+ converted as its first argument (<literal>in</literal>). As the second
+ argument (<literal>np</literal>), the function receives a pointer to the
+ decimal variable that should hold the result of the operation.
+ </para>
+ <para>
+ The function returns 0 on success and a negative value if the
+ conversion failed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>deccvlong</function></term>
+ <listitem>
+ <para>
+ Convert a value of type long to a value of type decimal.
+<synopsis>
+int deccvlong(long lng, decimal *np);
+</synopsis>
+ The function receives the variable of type long that should be
+ converted as its first argument (<literal>lng</literal>). As the second
+ argument (<literal>np</literal>), the function receives a pointer to the
+ decimal variable that should hold the result of the operation.
+ </para>
+ <para>
+ The function returns 0 on success and a negative value if the
+ conversion failed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>decdiv</function></term>
+ <listitem>
+ <para>
+ Divide two variables of type decimal.
+<synopsis>
+int decdiv(decimal *n1, decimal *n2, decimal *result);
+</synopsis>
+ The function receives pointers to the variables that are the first
+ (<literal>n1</literal>) and the second (<literal>n2</literal>) operands and
+ calculates <literal>n1</literal>/<literal>n2</literal>. <literal>result</literal> is a
+ pointer to the variable that should hold the result of the operation.
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if the division fails.
+ If overflow or underflow occurred, the function returns
+ <literal>ECPG_INFORMIX_NUM_OVERFLOW</literal> or
+ <literal>ECPG_INFORMIX_NUM_UNDERFLOW</literal> respectively. If an attempt to
+ divide by zero is observed, the function returns
+ <literal>ECPG_INFORMIX_DIVIDE_ZERO</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>decmul</function></term>
+ <listitem>
+ <para>
+ Multiply two decimal values.
+<synopsis>
+int decmul(decimal *n1, decimal *n2, decimal *result);
+</synopsis>
+ The function receives pointers to the variables that are the first
+ (<literal>n1</literal>) and the second (<literal>n2</literal>) operands and
+ calculates <literal>n1</literal>*<literal>n2</literal>. <literal>result</literal> is a
+ pointer to the variable that should hold the result of the operation.
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if the multiplication
+ fails. If overflow or underflow occurred, the function returns
+ <literal>ECPG_INFORMIX_NUM_OVERFLOW</literal> or
+ <literal>ECPG_INFORMIX_NUM_UNDERFLOW</literal> respectively.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>decsub</function></term>
+ <listitem>
+ <para>
+ Subtract one decimal value from another.
+<synopsis>
+int decsub(decimal *n1, decimal *n2, decimal *result);
+</synopsis>
+ The function receives pointers to the variables that are the first
+ (<literal>n1</literal>) and the second (<literal>n2</literal>) operands and
+ calculates <literal>n1</literal>-<literal>n2</literal>. <literal>result</literal> is a
+ pointer to the variable that should hold the result of the operation.
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if the subtraction
+ fails. If overflow or underflow occurred, the function returns
+ <literal>ECPG_INFORMIX_NUM_OVERFLOW</literal> or
+ <literal>ECPG_INFORMIX_NUM_UNDERFLOW</literal> respectively.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dectoasc</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type decimal to its ASCII representation in a C
+ char* string.
+<synopsis>
+int dectoasc(decimal *np, char *cp, int len, int right)
+</synopsis>
+ The function receives a pointer to a variable of type decimal
+ (<literal>np</literal>) that it converts to its textual representation.
+ <literal>cp</literal> is the buffer that should hold the result of the
+ operation. The parameter <literal>right</literal> specifies, how many digits
+ right of the decimal point should be included in the output. The result
+ will be rounded to this number of decimal digits. Setting
+ <literal>right</literal> to -1 indicates that all available decimal digits
+ should be included in the output. If the length of the output buffer,
+ which is indicated by <literal>len</literal> is not sufficient to hold the
+ textual representation including the trailing zero byte, only a
+ single <literal>*</literal> character is stored in the result and -1 is
+ returned.
+ </para>
+ <para>
+ The function returns either -1 if the buffer <literal>cp</literal> was too
+ small or <literal>ECPG_INFORMIX_OUT_OF_MEMORY</literal> if memory was
+ exhausted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dectodbl</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type decimal to a double.
+<synopsis>
+int dectodbl(decimal *np, double *dblp);
+</synopsis>
+ The function receives a pointer to the decimal value to convert
+ (<literal>np</literal>) and a pointer to the double variable that
+ should hold the result of the operation (<literal>dblp</literal>).
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if the conversion
+ failed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dectoint</function></term>
+ <listitem>
+ <para>
+ Convert a variable to type decimal to an integer.
+<synopsis>
+int dectoint(decimal *np, int *ip);
+</synopsis>
+ The function receives a pointer to the decimal value to convert
+ (<literal>np</literal>) and a pointer to the integer variable that
+ should hold the result of the operation (<literal>ip</literal>).
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if the conversion
+ failed. If an overflow occurred, <literal>ECPG_INFORMIX_NUM_OVERFLOW</literal>
+ is returned.
+ </para>
+ <para>
+ Note that the ECPG implementation differs from the <productname>Informix</productname>
+ implementation. <productname>Informix</productname> limits an integer to the range from -32767 to
+ 32767, while the limits in the ECPG implementation depend on the
+ architecture (<literal>INT_MIN .. INT_MAX</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dectolong</function></term>
+ <listitem>
+ <para>
+ Convert a variable to type decimal to a long integer.
+<synopsis>
+int dectolong(decimal *np, long *lngp);
+</synopsis>
+ The function receives a pointer to the decimal value to convert
+ (<literal>np</literal>) and a pointer to the long variable that
+ should hold the result of the operation (<literal>lngp</literal>).
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if the conversion
+ failed. If an overflow occurred, <literal>ECPG_INFORMIX_NUM_OVERFLOW</literal>
+ is returned.
+ </para>
+ <para>
+ Note that the ECPG implementation differs from the <productname>Informix</productname>
+ implementation. <productname>Informix</productname> limits a long integer to the range from
+ -2,147,483,647 to 2,147,483,647, while the limits in the ECPG
+ implementation depend on the architecture (<literal>-LONG_MAX ..
+ LONG_MAX</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rdatestr</function></term>
+ <listitem>
+ <para>
+ Converts a date to a C char* string.
+<synopsis>
+int rdatestr(date d, char *str);
+</synopsis>
+ The function receives two arguments, the first one is the date to
+ convert (<literal>d</literal>) and the second one is a pointer to the target
+ string. The output format is always <literal>yyyy-mm-dd</literal>, so you need
+ to allocate at least 11 bytes (including the zero-byte terminator) for the
+ string.
+ </para>
+ <para>
+ The function returns 0 on success and a negative value in case of
+ error.
+ </para>
+ <para>
+ Note that ECPG's implementation differs from the <productname>Informix</productname>
+ implementation. In <productname>Informix</productname> the format can be influenced by setting
+ environment variables. In ECPG however, you cannot change the output
+ format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rstrdate</function></term>
+ <listitem>
+ <para>
+ Parse the textual representation of a date.
+<synopsis>
+int rstrdate(char *str, date *d);
+</synopsis>
+ The function receives the textual representation of the date to convert
+ (<literal>str</literal>) and a pointer to a variable of type date
+ (<literal>d</literal>). This function does not allow you to specify a format
+ mask. It uses the default format mask of <productname>Informix</productname> which is
+ <literal>mm/dd/yyyy</literal>. Internally, this function is implemented by
+ means of <function>rdefmtdate</function>. Therefore, <function>rstrdate</function> is
+ not faster and if you have the choice you should opt for
+ <function>rdefmtdate</function> which allows you to specify the format mask
+ explicitly.
+ </para>
+ <para>
+ The function returns the same values as <function>rdefmtdate</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rtoday</function></term>
+ <listitem>
+ <para>
+ Get the current date.
+<synopsis>
+void rtoday(date *d);
+</synopsis>
+ The function receives a pointer to a date variable (<literal>d</literal>)
+ that it sets to the current date.
+ </para>
+ <para>
+ Internally this function uses the <xref linkend="pgtypesdatetoday"/>
+ function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rjulmdy</function></term>
+ <listitem>
+ <para>
+ Extract the values for the day, the month and the year from a variable
+ of type date.
+<synopsis>
+int rjulmdy(date d, short mdy[3]);
+</synopsis>
+ The function receives the date <literal>d</literal> and a pointer to an array
+ of 3 short integer values <literal>mdy</literal>. The variable name indicates
+ the sequential order: <literal>mdy[0]</literal> will be set to contain the
+ number of the month, <literal>mdy[1]</literal> will be set to the value of the
+ day and <literal>mdy[2]</literal> will contain the year.
+ </para>
+ <para>
+ The function always returns 0 at the moment.
+ </para>
+ <para>
+ Internally the function uses the <xref linkend="pgtypesdatejulmdy"/>
+ function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rdefmtdate</function></term>
+ <listitem>
+ <para>
+ Use a format mask to convert a character string to a value of type
+ date.
+<synopsis>
+int rdefmtdate(date *d, char *fmt, char *str);
+</synopsis>
+ The function receives a pointer to the date value that should hold the
+ result of the operation (<literal>d</literal>), the format mask to use for
+ parsing the date (<literal>fmt</literal>) and the C char* string containing
+ the textual representation of the date (<literal>str</literal>). The textual
+ representation is expected to match the format mask. However you do not
+ need to have a 1:1 mapping of the string to the format mask. The
+ function only analyzes the sequential order and looks for the literals
+ <literal>yy</literal> or <literal>yyyy</literal> that indicate the
+ position of the year, <literal>mm</literal> to indicate the position of
+ the month and <literal>dd</literal> to indicate the position of the
+ day.
+ </para>
+ <para>
+ The function returns the following values:
+ <itemizedlist>
+ <listitem>
+ <para>
+ 0 - The function terminated successfully.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ECPG_INFORMIX_ENOSHORTDATE</literal> - The date does not contain
+ delimiters between day, month and year. In this case the input
+ string must be exactly 6 or 8 bytes long but isn't.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ECPG_INFORMIX_ENOTDMY</literal> - The format string did not
+ correctly indicate the sequential order of year, month and day.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ECPG_INFORMIX_BAD_DAY</literal> - The input string does not
+ contain a valid day.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ECPG_INFORMIX_BAD_MONTH</literal> - The input string does not
+ contain a valid month.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ECPG_INFORMIX_BAD_YEAR</literal> - The input string does not
+ contain a valid year.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Internally this function is implemented to use the <xref
+ linkend="pgtypesdatedefmtasc"/> function. See the reference there for a
+ table of example input.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rfmtdate</function></term>
+ <listitem>
+ <para>
+ Convert a variable of type date to its textual representation using a
+ format mask.
+<synopsis>
+int rfmtdate(date d, char *fmt, char *str);
+</synopsis>
+ The function receives the date to convert (<literal>d</literal>), the format
+ mask (<literal>fmt</literal>) and the string that will hold the textual
+ representation of the date (<literal>str</literal>).
+ </para>
+ <para>
+ On success, 0 is returned and a negative value if an error occurred.
+ </para>
+ <para>
+ Internally this function uses the <xref linkend="pgtypesdatefmtasc"/>
+ function, see the reference there for examples.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rmdyjul</function></term>
+ <listitem>
+ <para>
+ Create a date value from an array of 3 short integers that specify the
+ day, the month and the year of the date.
+<synopsis>
+int rmdyjul(short mdy[3], date *d);
+</synopsis>
+ The function receives the array of the 3 short integers
+ (<literal>mdy</literal>) and a pointer to a variable of type date that should
+ hold the result of the operation.
+ </para>
+ <para>
+ Currently the function returns always 0.
+ </para>
+ <para>
+ Internally the function is implemented to use the function <xref
+ linkend="pgtypesdatemdyjul"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rdayofweek</function></term>
+ <listitem>
+ <para>
+ Return a number representing the day of the week for a date value.
+<synopsis>
+int rdayofweek(date d);
+</synopsis>
+ The function receives the date variable <literal>d</literal> as its only
+ argument and returns an integer that indicates the day of the week for
+ this date.
+ <itemizedlist>
+ <listitem>
+ <para>
+ 0 - Sunday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 1 - Monday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 2 - Tuesday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 3 - Wednesday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 4 - Thursday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 5 - Friday
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 6 - Saturday
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Internally the function is implemented to use the function <xref
+ linkend="pgtypesdatedayofweek"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dtcurrent</function></term>
+ <listitem>
+ <para>
+ Retrieve the current timestamp.
+<synopsis>
+void dtcurrent(timestamp *ts);
+</synopsis>
+ The function retrieves the current timestamp and saves it into the
+ timestamp variable that <literal>ts</literal> points to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dtcvasc</function></term>
+ <listitem>
+ <para>
+ Parses a timestamp from its textual representation
+ into a timestamp variable.
+<synopsis>
+int dtcvasc(char *str, timestamp *ts);
+</synopsis>
+ The function receives the string to parse (<literal>str</literal>) and a
+ pointer to the timestamp variable that should hold the result of the
+ operation (<literal>ts</literal>).
+ </para>
+ <para>
+ The function returns 0 on success and a negative value in case of
+ error.
+ </para>
+ <para>
+ Internally this function uses the <xref
+ linkend="pgtypestimestampfromasc"/> function. See the reference there
+ for a table with example inputs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dtcvfmtasc</function></term>
+ <listitem>
+ <para>
+ Parses a timestamp from its textual representation
+ using a format mask into a timestamp variable.
+<synopsis>
+dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue)
+</synopsis>
+ The function receives the string to parse (<literal>inbuf</literal>), the
+ format mask to use (<literal>fmtstr</literal>) and a pointer to the timestamp
+ variable that should hold the result of the operation
+ (<literal>dtvalue</literal>).
+ </para>
+ <para>
+ This function is implemented by means of the <xref
+ linkend="pgtypestimestampdefmtasc"/> function. See the documentation
+ there for a list of format specifiers that can be used.
+ </para>
+ <para>
+ The function returns 0 on success and a negative value in case of
+ error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dtsub</function></term>
+ <listitem>
+ <para>
+ Subtract one timestamp from another and return a variable of type
+ interval.
+<synopsis>
+int dtsub(timestamp *ts1, timestamp *ts2, interval *iv);
+</synopsis>
+ The function will subtract the timestamp variable that <literal>ts2</literal>
+ points to from the timestamp variable that <literal>ts1</literal> points to
+ and will store the result in the interval variable that <literal>iv</literal>
+ points to.
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dttoasc</function></term>
+ <listitem>
+ <para>
+ Convert a timestamp variable to a C char* string.
+<synopsis>
+int dttoasc(timestamp *ts, char *output);
+</synopsis>
+ The function receives a pointer to the timestamp variable to convert
+ (<literal>ts</literal>) and the string that should hold the result of the
+ operation (<literal>output</literal>). It converts <literal>ts</literal> to its
+ textual representation according to the SQL standard, which is
+ be <literal>YYYY-MM-DD HH:MM:SS</literal>.
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>dttofmtasc</function></term>
+ <listitem>
+ <para>
+ Convert a timestamp variable to a C char* using a format mask.
+<synopsis>
+int dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr);
+</synopsis>
+ The function receives a pointer to the timestamp to convert as its
+ first argument (<literal>ts</literal>), a pointer to the output buffer
+ (<literal>output</literal>), the maximal length that has been allocated for
+ the output buffer (<literal>str_len</literal>) and the format mask to
+ use for the conversion (<literal>fmtstr</literal>).
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ <para>
+ Internally, this function uses the <xref
+ linkend="pgtypestimestampfmtasc"/> function. See the reference there for
+ information on what format mask specifiers can be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>intoasc</function></term>
+ <listitem>
+ <para>
+ Convert an interval variable to a C char* string.
+<synopsis>
+int intoasc(interval *i, char *str);
+</synopsis>
+ The function receives a pointer to the interval variable to convert
+ (<literal>i</literal>) and the string that should hold the result of the
+ operation (<literal>str</literal>). It converts <literal>i</literal> to its
+ textual representation according to the SQL standard, which is
+ be <literal>YYYY-MM-DD HH:MM:SS</literal>.
+ </para>
+ <para>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rfmtlong</function></term>
+ <listitem>
+ <para>
+ Convert a long integer value to its textual representation using a
+ format mask.
+<synopsis>
+int rfmtlong(long lng_val, char *fmt, char *outbuf);
+</synopsis>
+ The function receives the long value <literal>lng_val</literal>, the format
+ mask <literal>fmt</literal> and a pointer to the output buffer
+ <literal>outbuf</literal>. It converts the long value according to the format
+ mask to its textual representation.
+ </para>
+ <para>
+ The format mask can be composed of the following format specifying
+ characters:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>*</literal> (asterisk) - if this position would be blank
+ otherwise, fill it with an asterisk.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>&amp;</literal> (ampersand) - if this position would be
+ blank otherwise, fill it with a zero.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>#</literal> - turn leading zeroes into blanks.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>&lt;</literal> - left-justify the number in the string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>,</literal> (comma) - group numbers of four or more digits
+ into groups of three digits separated by a comma.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>.</literal> (period) - this character separates the
+ whole-number part of the number from the fractional part.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>-</literal> (minus) - the minus sign appears if the number
+ is a negative value.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>+</literal> (plus) - the plus sign appears if the number is
+ a positive value.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>(</literal> - this replaces the minus sign in front of the
+ negative number. The minus sign will not appear.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>)</literal> - this character replaces the minus and is
+ printed behind the negative value.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>$</literal> - the currency symbol.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rupshift</function></term>
+ <listitem>
+ <para>
+ Convert a string to upper case.
+<synopsis>
+void rupshift(char *str);
+</synopsis>
+ The function receives a pointer to the string and transforms every
+ lower case character to upper case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>byleng</function></term>
+ <listitem>
+ <para>
+ Return the number of characters in a string without counting trailing
+ blanks.
+<synopsis>
+int byleng(char *str, int len);
+</synopsis>
+ The function expects a fixed-length string as its first argument
+ (<literal>str</literal>) and its length as its second argument
+ (<literal>len</literal>). It returns the number of significant characters,
+ that is the length of the string without trailing blanks.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>ldchar</function></term>
+ <listitem>
+ <para>
+ Copy a fixed-length string into a null-terminated string.
+<synopsis>
+void ldchar(char *src, int len, char *dest);
+</synopsis>
+ The function receives the fixed-length string to copy
+ (<literal>src</literal>), its length (<literal>len</literal>) and a pointer to the
+ destination memory (<literal>dest</literal>). Note that you need to reserve at
+ least <literal>len+1</literal> bytes for the string that <literal>dest</literal>
+ points to. The function copies at most <literal>len</literal> bytes to the new
+ location (less if the source string has trailing blanks) and adds the
+ null-terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rgetmsg</function></term>
+ <listitem>
+ <para>
+<synopsis>
+int rgetmsg(int msgnum, char *s, int maxsize);
+</synopsis>
+ This function exists but is not implemented at the moment!
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rtypalign</function></term>
+ <listitem>
+ <para>
+<synopsis>
+int rtypalign(int offset, int type);
+</synopsis>
+ This function exists but is not implemented at the moment!
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rtypmsize</function></term>
+ <listitem>
+ <para>
+<synopsis>
+int rtypmsize(int type, int len);
+</synopsis>
+ This function exists but is not implemented at the moment!
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>rtypwidth</function></term>
+ <listitem>
+ <para>
+<synopsis>
+int rtypwidth(int sqltype, int sqllen);
+</synopsis>
+ This function exists but is not implemented at the moment!
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="rsetnull">
+ <term><function>rsetnull</function></term>
+ <listitem>
+ <para>
+ Set a variable to NULL.
+<synopsis>
+int rsetnull(int t, char *ptr);
+</synopsis>
+ The function receives an integer that indicates the type of the
+ variable and a pointer to the variable itself that is cast to a C
+ char* pointer.
+ </para>
+ <para>
+ The following types exist:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>CCHARTYPE</literal> - For a variable of type <type>char</type> or <type>char*</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CSHORTTYPE</literal> - For a variable of type <type>short int</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CINTTYPE</literal> - For a variable of type <type>int</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CBOOLTYPE</literal> - For a variable of type <type>boolean</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CFLOATTYPE</literal> - For a variable of type <type>float</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CLONGTYPE</literal> - For a variable of type <type>long</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CDOUBLETYPE</literal> - For a variable of type <type>double</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CDECIMALTYPE</literal> - For a variable of type <type>decimal</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CDATETYPE</literal> - For a variable of type <type>date</type>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>CDTIMETYPE</literal> - For a variable of type <type>timestamp</type>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Here is an example of a call to this function:
+<programlisting><![CDATA[
+$char c[] = "abc ";
+$short s = 17;
+$int i = -74874;
+
+rsetnull(CCHARTYPE, (char *) c);
+rsetnull(CSHORTTYPE, (char *) &s);
+rsetnull(CINTTYPE, (char *) &i);
+]]>
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>risnull</function></term>
+ <listitem>
+ <para>
+ Test if a variable is NULL.
+<synopsis>
+int risnull(int t, char *ptr);
+</synopsis>
+ The function receives the type of the variable to test (<literal>t</literal>)
+ as well a pointer to this variable (<literal>ptr</literal>). Note that the
+ latter needs to be cast to a char*. See the function <xref
+ linkend="rsetnull"/> for a list of possible variable types.
+ </para>
+ <para>
+ Here is an example of how to use this function:
+<programlisting><![CDATA[
+$char c[] = "abc ";
+$short s = 17;
+$int i = -74874;
+
+risnull(CCHARTYPE, (char *) c);
+risnull(CSHORTTYPE, (char *) &s);
+risnull(CINTTYPE, (char *) &i);
+]]>
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="ecpg-informix-constants">
+ <title>Additional Constants</title>
+ <para>
+ Note that all constants here describe errors and all of them are defined
+ to represent negative values. In the descriptions of the different
+ constants you can also find the value that the constants represent in the
+ current implementation. However you should not rely on this number. You can
+ however rely on the fact all of them are defined to represent negative
+ values.
+ <variablelist>
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_NUM_OVERFLOW</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if an overflow occurred in a
+ calculation. Internally it is defined as -1200 (the <productname>Informix</productname>
+ definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_NUM_UNDERFLOW</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if an underflow occurred in a calculation.
+ Internally it is defined as -1201 (the <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_DIVIDE_ZERO</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if an attempt to divide by zero is
+ observed. Internally it is defined as -1202 (the <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_BAD_YEAR</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a bad value for a year was found while
+ parsing a date. Internally it is defined as -1204 (the <productname>Informix</productname>
+ definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_BAD_MONTH</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a bad value for a month was found while
+ parsing a date. Internally it is defined as -1205 (the <productname>Informix</productname>
+ definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_BAD_DAY</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a bad value for a day was found while
+ parsing a date. Internally it is defined as -1206 (the <productname>Informix</productname>
+ definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_ENOSHORTDATE</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a parsing routine needs a short date
+ representation but did not get the date string in the right length.
+ Internally it is defined as -1209 (the <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_DATE_CONVERT</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if an error occurred during date
+ formatting. Internally it is defined as -1210 (the
+ <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_OUT_OF_MEMORY</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if memory was exhausted during
+ their operation. Internally it is defined as -1211 (the
+ <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_ENOTDMY</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a parsing routine was supposed to get a
+ format mask (like <literal>mmddyy</literal>) but not all fields were listed
+ correctly. Internally it is defined as -1212 (the <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_BAD_NUMERIC</literal></term>
+ <listitem>
+ <para>
+ Functions return this value either if a parsing routine cannot parse
+ the textual representation for a numeric value because it contains
+ errors or if a routine cannot complete a calculation involving numeric
+ variables because at least one of the numeric variables is invalid.
+ Internally it is defined as -1213 (the <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_BAD_EXPONENT</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a parsing routine cannot parse
+ an exponent. Internally it is defined as -1216 (the
+ <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_BAD_DATE</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a parsing routine cannot parse
+ a date. Internally it is defined as -1218 (the
+ <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ECPG_INFORMIX_EXTRA_CHARS</literal></term>
+ <listitem>
+ <para>
+ Functions return this value if a parsing routine is passed extra
+ characters it cannot parse. Internally it is defined as -1264 (the
+ <productname>Informix</productname> definition).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ecpg-oracle-compat">
+ <title><productname>Oracle</productname> Compatibility Mode</title>
+ <para>
+ <command>ecpg</command> can be run in a so-called <firstterm>Oracle
+ compatibility mode</firstterm>. If this mode is active, it tries to
+ behave as if it were Oracle <productname>Pro*C</productname>.
+ </para>
+
+ <para>
+ Specifically, this mode changes <command>ecpg</command> in three ways:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Pad character arrays receiving character string types with
+ trailing spaces to the specified length
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Zero byte terminate these character arrays, and set the indicator
+ variable if truncation occurs
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Set the null indicator to <literal>-1</literal> when character
+ arrays receive empty character string types
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect1>
+
+ <sect1 id="ecpg-develop">
+ <title>Internals</title>
+
+ <para>
+ This section explains how <application>ECPG</application> works
+ internally. This information can occasionally be useful to help
+ users understand how to use <application>ECPG</application>.
+ </para>
+
+ <para>
+ The first four lines written by <command>ecpg</command> to the
+ output are fixed lines. Two are comments and two are include
+ lines necessary to interface to the library. Then the
+ preprocessor reads through the file and writes output. Normally
+ it just echoes everything to the output.
+ </para>
+
+ <para>
+ When it sees an <command>EXEC SQL</command> statement, it
+ intervenes and changes it. The command starts with <command>EXEC
+ SQL</command> and ends with <command>;</command>. Everything in
+ between is treated as an <acronym>SQL</acronym> statement and
+ parsed for variable substitution.
+ </para>
+
+ <para>
+ Variable substitution occurs when a symbol starts with a colon
+ (<literal>:</literal>). The variable with that name is looked up
+ among the variables that were previously declared within a
+ <literal>EXEC SQL DECLARE</literal> section.
+ </para>
+
+ <para>
+ The most important function in the library is
+ <function>ECPGdo</function>, which takes care of executing most
+ commands. It takes a variable number of arguments. This can easily
+ add up to 50 or so arguments, and we hope this will not be a
+ problem on any platform.
+ </para>
+
+ <para>
+ The arguments are:
+
+ <variablelist>
+ <varlistentry>
+ <term>A line number</term>
+ <listitem>
+ <para>
+ This is the line number of the original line; used in error
+ messages only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>A string</term>
+ <listitem>
+ <para>
+ This is the <acronym>SQL</acronym> command that is to be issued.
+ It is modified by the input variables, i.e., the variables that
+ where not known at compile time but are to be entered in the
+ command. Where the variables should go the string contains
+ <literal>?</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Input variables</term>
+ <listitem>
+ <para>
+ Every input variable causes ten arguments to be created. (See below.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>ECPGt_EOIT</parameter></term>
+ <listitem>
+ <para>
+ An <type>enum</type> telling that there are no more input
+ variables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Output variables</term>
+ <listitem>
+ <para>
+ Every output variable causes ten arguments to be created.
+ (See below.) These variables are filled by the function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>ECPGt_EORT</parameter></term>
+ <listitem>
+ <para>
+ An <type>enum</type> telling that there are no more variables.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ For every variable that is part of the <acronym>SQL</acronym>
+ command, the function gets ten arguments:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ The type as a special symbol.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A pointer to the value or a pointer to the pointer.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The size of the variable if it is a <type>char</type> or <type>varchar</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The number of elements in the array (for array fetches).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The offset to the next element in the array (for array fetches).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The type of the indicator variable as a special symbol.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A pointer to the indicator variable.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ 0
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The number of elements in the indicator array (for array fetches).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The offset to the next element in the indicator array (for
+ array fetches).
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ Note that not all SQL commands are treated in this way. For
+ instance, an open cursor statement like:
+<programlisting>
+EXEC SQL OPEN <replaceable>cursor</replaceable>;
+</programlisting>
+ is not copied to the output. Instead, the cursor's
+ <command>DECLARE</command> command is used at the position of the <command>OPEN</command> command
+ because it indeed opens the cursor.
+ </para>
+
+ <para>
+ Here is a complete example describing the output of the
+ preprocessor of a file <filename>foo.pgc</filename> (details might
+ change with each particular version of the preprocessor):
+<programlisting>
+EXEC SQL BEGIN DECLARE SECTION;
+int index;
+int result;
+EXEC SQL END DECLARE SECTION;
+...
+EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;
+</programlisting>
+ is translated into:
+<programlisting><![CDATA[
+/* Processed by ecpg (2.6.0) */
+/* These two include files are added by the preprocessor */
+#include <ecpgtype.h>;
+#include <ecpglib.h>;
+
+/* exec sql begin declare section */
+
+#line 1 "foo.pgc"
+
+ int index;
+ int result;
+/* exec sql end declare section */
+...
+ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ",
+ ECPGt_int,&(index),1L,1L,sizeof(int),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
+ ECPGt_int,&(result),1L,1L,sizeof(int),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 147 "foo.pgc"
+]]>
+</programlisting>
+ (The indentation here is added for readability and not
+ something the preprocessor does.)
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/errcodes.sgml b/doc/src/sgml/errcodes.sgml
new file mode 100644
index 0000000..861fa51
--- /dev/null
+++ b/doc/src/sgml/errcodes.sgml
@@ -0,0 +1,89 @@
+<!-- doc/src/sgml/errcodes.sgml -->
+
+<appendix id="errcodes-appendix">
+ <title><productname>PostgreSQL</productname> Error Codes</title>
+
+ <indexterm zone="errcodes-appendix">
+ <primary>error codes</primary>
+ <secondary>list of</secondary>
+ </indexterm>
+
+ <para>
+ All messages emitted by the <productname>PostgreSQL</productname>
+ server are assigned five-character error codes that follow the SQL
+ standard's conventions for <quote>SQLSTATE</quote> codes. Applications
+ that need to know which error condition has occurred should usually
+ test the error code, rather than looking at the textual error
+ message. The error codes are less likely to change across
+ <productname>PostgreSQL</productname> releases, and also are not subject to
+ change due to localization of error messages. Note that some, but
+ not all, of the error codes produced by <productname>PostgreSQL</productname>
+ are defined by the SQL standard; some additional error codes for
+ conditions not defined by the standard have been invented or
+ borrowed from other databases.
+ </para>
+
+ <para>
+ According to the standard, the first two characters of an error code
+ denote a class of errors, while the last three characters indicate
+ a specific condition within that class. Thus, an application that
+ does not recognize the specific error code might still be able to infer
+ what to do from the error class.
+ </para>
+
+ <para>
+ <xref linkend="errcodes-table"/> lists all the error codes defined in
+ <productname>PostgreSQL</productname> &version;. (Some are not actually
+ used at present, but are defined by the SQL standard.)
+ The error classes are also shown. For each error class there is a
+ <quote>standard</quote> error code having the last three characters
+ <literal>000</literal>. This code is used only for error conditions that fall
+ within the class but do not have any more-specific code assigned.
+ </para>
+
+ <para>
+ The symbol shown in the column <quote>Condition Name</quote> is
+ the condition name to use in <application>PL/pgSQL</application>. Condition
+ names can be written in either upper or lower case. (Note that
+ <application>PL/pgSQL</application> does not recognize warning, as opposed to error,
+ condition names; those are classes 00, 01, and 02.)
+ </para>
+
+ <para>
+ For some types of errors, the server reports the name of a database object
+ (a table, table column, data type, or constraint) associated with the error;
+ for example, the name of the unique constraint that caused a
+ <symbol>unique_violation</symbol> error. Such names are supplied in separate
+ fields of the error report message so that applications need not try to
+ extract them from the possibly-localized human-readable text of the message.
+ As of <productname>PostgreSQL</productname> 9.3, complete coverage for this feature
+ exists only for errors in SQLSTATE class 23 (integrity constraint
+ violation), but this is likely to be expanded in future.
+ </para>
+
+
+<table id="errcodes-table">
+ <title><productname>PostgreSQL</productname> Error Codes</title>
+
+ <tgroup cols="2">
+ <colspec colnum="1" colname="errorcode" colwidth="1*"/>
+ <colspec colnum="2" colname="condname" colwidth="8*"/>
+ <spanspec namest="errorcode" nameend="condname" spanname="span12"/>
+
+ <thead>
+ <row>
+ <entry>Error Code</entry>
+ <entry>Condition Name</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ &errcodes-table;
+
+ </tbody>
+ </tgroup>
+</table>
+
+
+</appendix>
diff --git a/doc/src/sgml/event-trigger.sgml b/doc/src/sgml/event-trigger.sgml
new file mode 100644
index 0000000..3b6a536
--- /dev/null
+++ b/doc/src/sgml/event-trigger.sgml
@@ -0,0 +1,1303 @@
+<!-- doc/src/sgml/event-trigger.sgml -->
+
+ <chapter id="event-triggers">
+ <title>Event Triggers</title>
+
+ <indexterm zone="event-triggers">
+ <primary>event trigger</primary>
+ </indexterm>
+
+ <para>
+ To supplement the trigger mechanism discussed in <xref linkend="triggers"/>,
+ <productname>PostgreSQL</productname> also provides event triggers. Unlike regular
+ triggers, which are attached to a single table and capture only DML events,
+ event triggers are global to a particular database and are capable of
+ capturing DDL events.
+ </para>
+
+ <para>
+ Like regular triggers, event triggers can be written in any procedural
+ language that includes event trigger support, or in C, but not in plain
+ SQL.
+ </para>
+
+ <sect1 id="event-trigger-definition">
+ <title>Overview of Event Trigger Behavior</title>
+
+ <para>
+ An event trigger fires whenever the event with which it is associated
+ occurs in the database in which it is defined. Currently, the only
+ supported events are
+ <literal>ddl_command_start</literal>,
+ <literal>ddl_command_end</literal>,
+ <literal>table_rewrite</literal>
+ and <literal>sql_drop</literal>.
+ Support for additional events may be added in future releases.
+ </para>
+
+ <para>
+ The <literal>ddl_command_start</literal> event occurs just before the
+ execution of a <literal>CREATE</literal>, <literal>ALTER</literal>, <literal>DROP</literal>,
+ <literal>SECURITY LABEL</literal>,
+ <literal>COMMENT</literal>, <literal>GRANT</literal> or <literal>REVOKE</literal>
+ command. No check whether the affected object exists or doesn't exist is
+ performed before the event trigger fires.
+ As an exception, however, this event does not occur for
+ DDL commands targeting shared objects &mdash; databases, roles, and tablespaces
+ &mdash; or for commands targeting event triggers themselves. The event trigger
+ mechanism does not support these object types.
+ <literal>ddl_command_start</literal> also occurs just before the execution of a
+ <literal>SELECT INTO</literal> command, since this is equivalent to
+ <literal>CREATE TABLE AS</literal>.
+ </para>
+
+ <para>
+ The <literal>ddl_command_end</literal> event occurs just after the execution of
+ this same set of commands. To obtain more details on the <acronym>DDL</acronym>
+ operations that took place, use the set-returning function
+ <literal>pg_event_trigger_ddl_commands()</literal> from the
+ <literal>ddl_command_end</literal> event trigger code (see
+ <xref linkend="functions-event-triggers"/>). Note that the trigger fires
+ after the actions have taken place (but before the transaction commits),
+ and thus the system catalogs can be read as already changed.
+ </para>
+
+ <para>
+ The <literal>sql_drop</literal> event occurs just before the
+ <literal>ddl_command_end</literal> event trigger for any operation that drops
+ database objects. To list the objects that have been dropped, use the
+ set-returning function <literal>pg_event_trigger_dropped_objects()</literal> from the
+ <literal>sql_drop</literal> event trigger code (see
+ <xref linkend="functions-event-triggers"/>). Note that
+ the trigger is executed after the objects have been deleted from the
+ system catalogs, so it's not possible to look them up anymore.
+ </para>
+
+ <para>
+ The <literal>table_rewrite</literal> event occurs just before a table is
+ rewritten by some actions of the commands <literal>ALTER TABLE</literal> and
+ <literal>ALTER TYPE</literal>. While other
+ control statements are available to rewrite a table,
+ like <literal>CLUSTER</literal> and <literal>VACUUM</literal>,
+ the <literal>table_rewrite</literal> event is not triggered by them.
+ </para>
+
+ <para>
+ Event triggers (like other functions) cannot be executed in an aborted
+ transaction. Thus, if a DDL command fails with an error, any associated
+ <literal>ddl_command_end</literal> triggers will not be executed. Conversely,
+ if a <literal>ddl_command_start</literal> trigger fails with an error, no
+ further event triggers will fire, and no attempt will be made to execute
+ the command itself. Similarly, if a <literal>ddl_command_end</literal> trigger
+ fails with an error, the effects of the DDL statement will be rolled
+ back, just as they would be in any other case where the containing
+ transaction aborts.
+ </para>
+
+ <para>
+ For a complete list of commands supported by the event trigger mechanism,
+ see <xref linkend="event-trigger-matrix"/>.
+ </para>
+
+ <para>
+ Event triggers are created using the command <xref linkend="sql-createeventtrigger"/>.
+ In order to create an event trigger, you must first create a function with
+ the special return type <literal>event_trigger</literal>. This function
+ need not (and may not) return a value; the return type serves merely as
+ a signal that the function is to be invoked as an event trigger.
+ </para>
+
+ <para>
+ If more than one event trigger is defined for a particular event, they will
+ fire in alphabetical order by trigger name.
+ </para>
+
+ <para>
+ A trigger definition can also specify a <literal>WHEN</literal>
+ condition so that, for example, a <literal>ddl_command_start</literal>
+ trigger can be fired only for particular commands which the user wishes
+ to intercept. A common use of such triggers is to restrict the range of
+ DDL operations which users may perform.
+ </para>
+ </sect1>
+
+ <sect1 id="event-trigger-matrix">
+ <title>Event Trigger Firing Matrix</title>
+
+ <para>
+ <xref linkend="event-trigger-by-command-tag"/> lists all commands
+ for which event triggers are supported.
+ </para>
+
+ <table id="event-trigger-by-command-tag">
+ <title>Event Trigger Support by Command Tag</title>
+ <tgroup cols="6">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <colspec colname="col5" colwidth="1*"/>
+ <colspec colname="col6" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Command Tag</entry>
+ <entry><literal>ddl_&zwsp;command_&zwsp;start</literal></entry>
+ <entry><literal>ddl_&zwsp;command_&zwsp;end</literal></entry>
+ <entry><literal>sql_&zwsp;drop</literal></entry>
+ <entry><literal>table_&zwsp;rewrite</literal></entry>
+ <entry>Notes</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry align="left"><literal>ALTER AGGREGATE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER COLLATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER CONVERSION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER DOMAIN</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER DEFAULT PRIVILEGES</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER EXTENSION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER FOREIGN DATA WRAPPER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER FOREIGN TABLE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER FUNCTION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER LANGUAGE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER LARGE OBJECT</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER MATERIALIZED VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER OPERATOR</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER OPERATOR CLASS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER OPERATOR FAMILY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER POLICY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER PROCEDURE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER PUBLICATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER ROUTINE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER SCHEMA</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER SEQUENCE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER SERVER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER STATISTICS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER SUBSCRIPTION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TABLE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TEXT SEARCH CONFIGURATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TEXT SEARCH DICTIONARY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TEXT SEARCH PARSER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TEXT SEARCH TEMPLATE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TRIGGER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER TYPE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER USER MAPPING</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>ALTER VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>COMMENT</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left">Only for local objects</entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE ACCESS METHOD</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE AGGREGATE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE CAST</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE COLLATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE CONVERSION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE DOMAIN</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE EXTENSION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE FOREIGN DATA WRAPPER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE FOREIGN TABLE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE FUNCTION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE INDEX</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE LANGUAGE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE MATERIALIZED VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE OPERATOR</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE OPERATOR CLASS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE OPERATOR FAMILY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE POLICY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE PROCEDURE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE PUBLICATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE RULE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE SCHEMA</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE SEQUENCE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE SERVER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE STATISTICS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE SUBSCRIPTION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TABLE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TABLE AS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TEXT SEARCH CONFIGURATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TEXT SEARCH DICTIONARY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TEXT SEARCH PARSER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TEXT SEARCH TEMPLATE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TRIGGER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE TYPE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE USER MAPPING</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>CREATE VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP ACCESS METHOD</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP AGGREGATE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP CAST</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP COLLATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP CONVERSION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP DOMAIN</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP EXTENSION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP FOREIGN DATA WRAPPER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP FOREIGN TABLE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP FUNCTION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP INDEX</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP LANGUAGE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP MATERIALIZED VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP OPERATOR</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP OPERATOR CLASS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP OPERATOR FAMILY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP OWNED</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP POLICY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP PROCEDURE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP PUBLICATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP ROUTINE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP RULE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP SCHEMA</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP SEQUENCE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP SERVER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP STATISTICS</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP SUBSCRIPTION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TABLE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TEXT SEARCH CONFIGURATION</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TEXT SEARCH DICTIONARY</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TEXT SEARCH PARSER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TEXT SEARCH TEMPLATE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TRIGGER</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP TYPE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP USER MAPPING</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>DROP VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>GRANT</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left">Only for local objects</entry>
+ </row>
+ <row>
+ <entry align="left"><literal>IMPORT FOREIGN SCHEMA</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>REFRESH MATERIALIZED VIEW</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ <row>
+ <entry align="left"><literal>REVOKE</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left">Only for local objects</entry>
+ </row>
+ <row>
+ <entry align="left"><literal>SECURITY LABEL</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left">Only for local objects</entry>
+ </row>
+ <row>
+ <entry align="left"><literal>SELECT INTO</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>X</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="center"><literal>-</literal></entry>
+ <entry align="left"></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="event-trigger-interface">
+ <title>Writing Event Trigger Functions in C</title>
+
+ <indexterm zone="event-trigger-interface">
+ <primary>event trigger</primary>
+ <secondary>in C</secondary>
+ </indexterm>
+
+ <para>
+ This section describes the low-level details of the interface to an
+ event trigger function. This information is only needed when writing
+ event trigger functions in C. If you are using a higher-level language
+ then these details are handled for you. In most cases you should
+ consider using a procedural language before writing your event triggers
+ in C. The documentation of each procedural language explains how to
+ write an event trigger in that language.
+ </para>
+
+ <para>
+ Event trigger functions must use the <quote>version 1</quote> function
+ manager interface.
+ </para>
+
+ <para>
+ When a function is called by the event trigger manager, it is not passed
+ any normal arguments, but it is passed a <quote>context</quote> pointer
+ pointing to a <structname>EventTriggerData</structname> structure. C functions can
+ check whether they were called from the event trigger manager or not by
+ executing the macro:
+<programlisting>
+CALLED_AS_EVENT_TRIGGER(fcinfo)
+</programlisting>
+ which expands to:
+<programlisting>
+((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, EventTriggerData))
+</programlisting>
+ If this returns true, then it is safe to cast
+ <literal>fcinfo-&gt;context</literal> to type <literal>EventTriggerData
+ *</literal> and make use of the pointed-to
+ <structname>EventTriggerData</structname> structure. The function must
+ <emphasis>not</emphasis> alter the <structname>EventTriggerData</structname>
+ structure or any of the data it points to.
+ </para>
+
+ <para>
+ <structname>struct EventTriggerData</structname> is defined in
+ <filename>commands/event_trigger.h</filename>:
+
+<programlisting>
+typedef struct EventTriggerData
+{
+ NodeTag type;
+ const char *event; /* event name */
+ Node *parsetree; /* parse tree */
+ CommandTag tag; /* command tag */
+} EventTriggerData;
+</programlisting>
+
+ where the members are defined as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>type</structfield></term>
+ <listitem>
+ <para>
+ Always <literal>T_EventTriggerData</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>event</structfield></term>
+ <listitem>
+ <para>
+ Describes the event for which the function is called, one of
+ <literal>"ddl_command_start"</literal>, <literal>"ddl_command_end"</literal>,
+ <literal>"sql_drop"</literal>, <literal>"table_rewrite"</literal>.
+ See <xref linkend="event-trigger-definition"/> for the meaning of these
+ events.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>parsetree</structfield></term>
+ <listitem>
+ <para>
+ A pointer to the parse tree of the command. Check the PostgreSQL
+ source code for details. The parse tree structure is subject to change
+ without notice.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tag</structfield></term>
+ <listitem>
+ <para>
+ The command tag associated with the event for which the event trigger
+ is run, for example <literal>"CREATE FUNCTION"</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ An event trigger function must return a <symbol>NULL</symbol> pointer
+ (<emphasis>not</emphasis> an SQL null value, that is, do not
+ set <parameter>isNull</parameter> true).
+ </para>
+ </sect1>
+
+ <sect1 id="event-trigger-example">
+ <title>A Complete Event Trigger Example</title>
+
+ <para>
+ Here is a very simple example of an event trigger function written in C.
+ (Examples of triggers written in procedural languages can be found in
+ the documentation of the procedural languages.)
+ </para>
+
+ <para>
+ The function <function>noddl</function> raises an exception each time it is called.
+ The event trigger definition associated the function with
+ the <literal>ddl_command_start</literal> event. The effect is that all DDL
+ commands (with the exceptions mentioned
+ in <xref linkend="event-trigger-definition"/>) are prevented from running.
+ </para>
+
+ <para>
+ This is the source code of the trigger function:
+<programlisting><![CDATA[
+#include "postgres.h"
+#include "commands/event_trigger.h"
+
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(noddl);
+
+Datum
+noddl(PG_FUNCTION_ARGS)
+{
+ EventTriggerData *trigdata;
+
+ if (!CALLED_AS_EVENT_TRIGGER(fcinfo)) /* internal error */
+ elog(ERROR, "not fired by event trigger manager");
+
+ trigdata = (EventTriggerData *) fcinfo->context;
+
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("command \"%s\" denied",
+ GetCommandTagName(trigdata->tag))));
+
+ PG_RETURN_NULL();
+}
+]]></programlisting>
+ </para>
+
+ <para>
+ After you have compiled the source code (see <xref linkend="dfunc"/>),
+ declare the function and the triggers:
+<programlisting>
+CREATE FUNCTION noddl() RETURNS event_trigger
+ AS 'noddl' LANGUAGE C;
+
+CREATE EVENT TRIGGER noddl ON ddl_command_start
+ EXECUTE FUNCTION noddl();
+</programlisting>
+ </para>
+
+ <para>
+ Now you can test the operation of the trigger:
+<screen>
+=# \dy
+ List of event triggers
+ Name | Event | Owner | Enabled | Function | Tags
+-------+-------------------+-------+---------+----------+------
+ noddl | ddl_command_start | dim | enabled | noddl |
+(1 row)
+
+=# CREATE TABLE foo(id serial);
+ERROR: command "CREATE TABLE" denied
+</screen>
+ </para>
+
+ <para>
+ In this situation, in order to be able to run some DDL commands when you
+ need to do so, you have to either drop the event trigger or disable it. It
+ can be convenient to disable the trigger for only the duration of a
+ transaction:
+<programlisting>
+BEGIN;
+ALTER EVENT TRIGGER noddl DISABLE;
+CREATE TABLE foo (id serial);
+ALTER EVENT TRIGGER noddl ENABLE;
+COMMIT;
+</programlisting>
+ (Recall that DDL commands on event triggers themselves are not affected by
+ event triggers.)
+ </para>
+ </sect1>
+
+ <sect1 id="event-trigger-table-rewrite-example">
+ <title>A Table Rewrite Event Trigger Example</title>
+
+ <para>
+ Thanks to the <literal>table_rewrite</literal> event, it is possible to implement
+ a table rewriting policy only allowing the rewrite in maintenance windows.
+ </para>
+
+ <para>
+ Here's an example implementing such a policy.
+<programlisting>
+CREATE OR REPLACE FUNCTION no_rewrite()
+ RETURNS event_trigger
+ LANGUAGE plpgsql AS
+$$
+---
+--- Implement local Table Rewriting policy:
+--- public.foo is not allowed rewriting, ever
+--- other tables are only allowed rewriting between 1am and 6am
+--- unless they have more than 100 blocks
+---
+DECLARE
+ table_oid oid := pg_event_trigger_table_rewrite_oid();
+ current_hour integer := extract('hour' from current_time);
+ pages integer;
+ max_pages integer := 100;
+BEGIN
+ IF pg_event_trigger_table_rewrite_oid() = 'public.foo'::regclass
+ THEN
+ RAISE EXCEPTION 'you''re not allowed to rewrite the table %',
+ table_oid::regclass;
+ END IF;
+
+ SELECT INTO pages relpages FROM pg_class WHERE oid = table_oid;
+ IF pages > max_pages
+ THEN
+ RAISE EXCEPTION 'rewrites only allowed for table with less than % pages',
+ max_pages;
+ END IF;
+
+ IF current_hour NOT BETWEEN 1 AND 6
+ THEN
+ RAISE EXCEPTION 'rewrites only allowed between 1am and 6am';
+ END IF;
+END;
+$$;
+
+CREATE EVENT TRIGGER no_rewrite_allowed
+ ON table_rewrite
+ EXECUTE FUNCTION no_rewrite();
+</programlisting>
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
new file mode 100644
index 0000000..46e873a
--- /dev/null
+++ b/doc/src/sgml/extend.sgml
@@ -0,0 +1,1862 @@
+<!-- doc/src/sgml/extend.sgml -->
+
+ <chapter id="extend">
+ <title>Extending <acronym>SQL</acronym></title>
+
+ <indexterm zone="extend">
+ <primary>extending SQL</primary>
+ </indexterm>
+
+ <para>
+ In the sections that follow, we will discuss how you
+ can extend the <productname>PostgreSQL</productname>
+ <acronym>SQL</acronym> query language by adding:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ functions (starting in <xref linkend="xfunc"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ aggregates (starting in <xref linkend="xaggr"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ data types (starting in <xref linkend="xtypes"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ operators (starting in <xref linkend="xoper"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ operator classes for indexes (starting in <xref linkend="xindex"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ packages of related objects (starting in <xref linkend="extend-extensions"/>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect1 id="extend-how">
+ <title>How Extensibility Works</title>
+
+ <para>
+ <productname>PostgreSQL</productname> is extensible because its operation is
+ catalog-driven. If you are familiar with standard
+ relational database systems, you know that they store information
+ about databases, tables, columns, etc., in what are
+ commonly known as system catalogs. (Some systems call
+ this the data dictionary.) The catalogs appear to the
+ user as tables like any other, but the <acronym>DBMS</acronym> stores
+ its internal bookkeeping in them. One key difference
+ between <productname>PostgreSQL</productname> and standard relational database systems is
+ that <productname>PostgreSQL</productname> stores much more information in its
+ catalogs: not only information about tables and columns,
+ but also information about data types, functions, access
+ methods, and so on. These tables can be modified by
+ the user, and since <productname>PostgreSQL</productname> bases its operation
+ on these tables, this means that <productname>PostgreSQL</productname> can be
+ extended by users. By comparison, conventional
+ database systems can only be extended by changing hardcoded
+ procedures in the source code or by loading modules
+ specially written by the <acronym>DBMS</acronym> vendor.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> server can moreover
+ incorporate user-written code into itself through dynamic loading.
+ That is, the user can specify an object code file (e.g., a shared
+ library) that implements a new type or function, and
+ <productname>PostgreSQL</productname> will load it as required.
+ Code written in <acronym>SQL</acronym> is even more trivial to add
+ to the server. This ability to modify its operation <quote>on the
+ fly</quote> makes <productname>PostgreSQL</productname> uniquely
+ suited for rapid prototyping of new applications and storage
+ structures.
+ </para>
+ </sect1>
+
+ <sect1 id="extend-type-system">
+ <title>The <productname>PostgreSQL</productname> Type System</title>
+
+ <indexterm zone="extend-type-system">
+ <primary>base type</primary>
+ </indexterm>
+
+ <indexterm zone="extend-type-system">
+ <primary>data type</primary>
+ <secondary>base</secondary>
+ </indexterm>
+
+ <indexterm zone="extend-type-system">
+ <primary>composite type</primary>
+ </indexterm>
+
+ <indexterm zone="extend-type-system">
+ <primary>data type</primary>
+ <secondary>composite</secondary>
+ </indexterm>
+
+ <indexterm zone="extend-type-system">
+ <primary>container type</primary>
+ </indexterm>
+
+ <indexterm zone="extend-type-system">
+ <primary>data type</primary>
+ <secondary>container</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> data types can be divided into base
+ types, container types, domains, and pseudo-types.
+ </para>
+
+ <sect2>
+ <title>Base Types</title>
+
+ <para>
+ Base types are those, like <type>integer</type>, that are
+ implemented below the level of the <acronym>SQL</acronym> language
+ (typically in a low-level language such as C). They generally
+ correspond to what are often known as abstract data types.
+ <productname>PostgreSQL</productname> can only operate on such
+ types through functions provided by the user and only understands
+ the behavior of such types to the extent that the user describes
+ them.
+ The built-in base types are described in <xref linkend="datatype"/>.
+ </para>
+
+ <para>
+ Enumerated (enum) types can be considered as a subcategory of base
+ types. The main difference is that they can be created using
+ just <acronym>SQL</acronym> commands, without any low-level programming.
+ Refer to <xref linkend="datatype-enum"/> for more information.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Container Types</title>
+
+ <para>
+ <productname>PostgreSQL</productname> has three kinds
+ of <quote>container</quote> types, which are types that contain multiple
+ values of other types. These are arrays, composites, and ranges.
+ </para>
+
+ <para>
+ Arrays can hold multiple values that are all of the same type. An array
+ type is automatically created for each base type, composite type, range
+ type, and domain type. But there are no arrays of arrays. So far as
+ the type system is concerned, multi-dimensional arrays are the same as
+ one-dimensional arrays. Refer to <xref linkend="arrays"/> for more
+ information.
+ </para>
+
+ <para>
+ Composite types, or row types, are created whenever the user
+ creates a table. It is also possible to use <xref
+ linkend="sql-createtype"/> to
+ define a <quote>stand-alone</quote> composite type with no associated
+ table. A composite type is simply a list of types with
+ associated field names. A value of a composite type is a row or
+ record of field values. Refer to <xref linkend="rowtypes"/>
+ for more information.
+ </para>
+
+ <para>
+ A range type can hold two values of the same type, which are the lower
+ and upper bounds of the range. Range types are user-created, although
+ a few built-in ones exist. Refer to <xref linkend="rangetypes"/>
+ for more information.
+ </para>
+ </sect2>
+
+ <sect2 id="extend-type-system-domains">
+ <title>Domains</title>
+
+ <para>
+ A domain is based on a particular underlying type and for many purposes
+ is interchangeable with its underlying type. However, a domain can have
+ constraints that restrict its valid values to a subset of what the
+ underlying type would allow. Domains are created using
+ the <acronym>SQL</acronym> command <xref linkend="sql-createdomain"/>.
+ Refer to <xref linkend="domains"/> for more information.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Pseudo-Types</title>
+
+ <para>
+ There are a few <quote>pseudo-types</quote> for special purposes.
+ Pseudo-types cannot appear as columns of tables or components of
+ container types, but they can be used to declare the argument and
+ result types of functions. This provides a mechanism within the
+ type system to identify special classes of functions. <xref
+ linkend="datatype-pseudotypes-table"/> lists the existing
+ pseudo-types.
+ </para>
+ </sect2>
+
+ <sect2 id="extend-types-polymorphic">
+ <title>Polymorphic Types</title>
+
+ <indexterm zone="extend-types-polymorphic">
+ <primary>polymorphic type</primary>
+ </indexterm>
+
+ <indexterm zone="extend-types-polymorphic">
+ <primary>polymorphic function</primary>
+ </indexterm>
+
+ <indexterm zone="extend-types-polymorphic">
+ <primary>data type</primary>
+ <secondary>polymorphic</secondary>
+ </indexterm>
+
+ <indexterm zone="extend-types-polymorphic">
+ <primary>function</primary>
+ <secondary>polymorphic</secondary>
+ </indexterm>
+
+ <para>
+ Some pseudo-types of special interest are the <firstterm>polymorphic
+ types</firstterm>, which are used to declare <firstterm>polymorphic
+ functions</firstterm>. This powerful feature allows a single function
+ definition to operate on many different data types, with the specific
+ data type(s) being determined by the data types actually passed to it
+ in a particular call. The polymorphic types are shown in
+ <xref linkend="extend-types-polymorphic-table"/>. Some examples of
+ their use appear in <xref linkend="xfunc-sql-polymorphic-functions"/>.
+ </para>
+
+ <table id="extend-types-polymorphic-table">
+ <title>Polymorphic Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Family</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>anyelement</type></entry>
+ <entry>Simple</entry>
+ <entry>Indicates that a function accepts any data type</entry>
+ </row>
+
+ <row>
+ <entry><type>anyarray</type></entry>
+ <entry>Simple</entry>
+ <entry>Indicates that a function accepts any array data type</entry>
+ </row>
+
+ <row>
+ <entry><type>anynonarray</type></entry>
+ <entry>Simple</entry>
+ <entry>Indicates that a function accepts any non-array data type</entry>
+ </row>
+
+ <row>
+ <entry><type>anyenum</type></entry>
+ <entry>Simple</entry>
+ <entry>Indicates that a function accepts any enum data type
+ (see <xref linkend="datatype-enum"/>)
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anyrange</type></entry>
+ <entry>Simple</entry>
+ <entry>Indicates that a function accepts any range data type
+ (see <xref linkend="rangetypes"/>)
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anymultirange</type></entry>
+ <entry>Simple</entry>
+ <entry>Indicates that a function accepts any multirange data type
+ (see <xref linkend="rangetypes"/>)
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatible</type></entry>
+ <entry>Common</entry>
+ <entry>Indicates that a function accepts any data type,
+ with automatic promotion of multiple arguments to a common data type
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblearray</type></entry>
+ <entry>Common</entry>
+ <entry>Indicates that a function accepts any array data type,
+ with automatic promotion of multiple arguments to a common data type
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblenonarray</type></entry>
+ <entry>Common</entry>
+ <entry>Indicates that a function accepts any non-array data type,
+ with automatic promotion of multiple arguments to a common data type
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblerange</type></entry>
+ <entry>Common</entry>
+ <entry>Indicates that a function accepts any range data type,
+ with automatic promotion of multiple arguments to a common data type
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>anycompatiblemultirange</type></entry>
+ <entry>Common</entry>
+ <entry>Indicates that a function accepts any multirange data type,
+ with automatic promotion of multiple arguments to a common data type
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Polymorphic arguments and results are tied to each other and are resolved
+ to specific data types when a query calling a polymorphic function is
+ parsed. When there is more than one polymorphic argument, the actual
+ data types of the input values must match up as described below. If the
+ function's result type is polymorphic, or it has output parameters of
+ polymorphic types, the types of those results are deduced from the
+ actual types of the polymorphic inputs as described below.
+ </para>
+
+ <para>
+ For the <quote>simple</quote> family of polymorphic types, the
+ matching and deduction rules work like this:
+ </para>
+
+ <para>
+ Each position (either argument or return value) declared as
+ <type>anyelement</type> is allowed to have any specific actual
+ data type, but in any given call they must all be the
+ <emphasis>same</emphasis> actual type. Each
+ position declared as <type>anyarray</type> can have any array data type,
+ but similarly they must all be the same type. And similarly,
+ positions declared as <type>anyrange</type> must all be the same range
+ type. Likewise for <type>anymultirange</type>.
+ </para>
+
+ <para>
+ Furthermore, if there are
+ positions declared <type>anyarray</type> and others declared
+ <type>anyelement</type>, the actual array type in the
+ <type>anyarray</type> positions must be an array whose elements are
+ the same type appearing in the <type>anyelement</type> positions.
+ <type>anynonarray</type> is treated exactly the same as <type>anyelement</type>,
+ but adds the additional constraint that the actual type must not be
+ an array type.
+ <type>anyenum</type> is treated exactly the same as <type>anyelement</type>,
+ but adds the additional constraint that the actual type must
+ be an enum type.
+ </para>
+
+ <para>
+ Similarly, if there are positions declared <type>anyrange</type>
+ and others declared <type>anyelement</type> or <type>anyarray</type>,
+ the actual range type in the <type>anyrange</type> positions must be a
+ range whose subtype is the same type appearing in
+ the <type>anyelement</type> positions and the same as the element type
+ of the <type>anyarray</type> positions.
+ If there are positions declared <type>anymultirange</type>,
+ their actual multirange type must contain ranges matching parameters declared
+ <type>anyrange</type> and base elements matching parameters declared
+ <type>anyelement</type> and <type>anyarray</type>.
+ </para>
+
+ <para>
+ Thus, when more than one argument position is declared with a polymorphic
+ type, the net effect is that only certain combinations of actual argument
+ types are allowed. For example, a function declared as
+ <literal>equal(anyelement, anyelement)</literal> will take any two input values,
+ so long as they are of the same data type.
+ </para>
+
+ <para>
+ When the return value of a function is declared as a polymorphic type,
+ there must be at least one argument position that is also polymorphic,
+ and the actual data type(s) supplied for the polymorphic arguments
+ determine the actual
+ result type for that call. For example, if there were not already
+ an array subscripting mechanism, one could define a function that
+ implements subscripting as <literal>subscript(anyarray, integer)
+ returns anyelement</literal>. This declaration constrains the actual first
+ argument to be an array type, and allows the parser to infer the correct
+ result type from the actual first argument's type. Another example
+ is that a function declared as <literal>f(anyarray) returns anyenum</literal>
+ will only accept arrays of enum types.
+ </para>
+
+ <para>
+ In most cases, the parser can infer the actual data type for a
+ polymorphic result type from arguments that are of a different
+ polymorphic type in the same family; for example <type>anyarray</type>
+ can be deduced from <type>anyelement</type> or vice versa.
+ An exception is that a
+ polymorphic result of type <type>anyrange</type> requires an argument
+ of type <type>anyrange</type>; it cannot be deduced
+ from <type>anyarray</type> or <type>anyelement</type> arguments. This
+ is because there could be multiple range types with the same subtype.
+ </para>
+
+ <para>
+ Note that <type>anynonarray</type> and <type>anyenum</type> do not represent
+ separate type variables; they are the same type as
+ <type>anyelement</type>, just with an additional constraint. For
+ example, declaring a function as <literal>f(anyelement, anyenum)</literal>
+ is equivalent to declaring it as <literal>f(anyenum, anyenum)</literal>:
+ both actual arguments have to be the same enum type.
+ </para>
+
+ <para>
+ For the <quote>common</quote> family of polymorphic types, the
+ matching and deduction rules work approximately the same as for
+ the <quote>simple</quote> family, with one major difference: the
+ actual types of the arguments need not be identical, so long as they
+ can be implicitly cast to a single common type. The common type is
+ selected following the same rules as for <literal>UNION</literal> and
+ related constructs (see <xref linkend="typeconv-union-case"/>).
+ Selection of the common type considers the actual types
+ of <type>anycompatible</type> and <type>anycompatiblenonarray</type>
+ inputs, the array element types of <type>anycompatiblearray</type>
+ inputs, the range subtypes of <type>anycompatiblerange</type> inputs,
+ and the multirange subtypes of <type>anycompatiblemultirange</type>
+ inputs. If <type>anycompatiblenonarray</type> is present then the
+ common type is required to be a non-array type. Once a common type is
+ identified, arguments in <type>anycompatible</type>
+ and <type>anycompatiblenonarray</type> positions are automatically
+ cast to that type, and arguments in <type>anycompatiblearray</type>
+ positions are automatically cast to the array type for that type.
+ </para>
+
+ <para>
+ Since there is no way to select a range type knowing only its subtype,
+ use of <type>anycompatiblerange</type> and/or
+ <type>anycompatiblemultirange</type> requires that all arguments declared
+ with that type have the same actual range and/or multirange type, and that
+ that type's subtype agree with the selected common type, so that no casting
+ of the range values is required. As with <type>anyrange</type> and
+ <type>anymultirange</type>, use of <type>anycompatiblerange</type> and
+ <type>anymultirange</type> as a function result type requires that there be
+ an <type>anycompatiblerange</type> or <type>anycompatiblemultirange</type>
+ argument.
+ </para>
+
+ <para>
+ Notice that there is no <type>anycompatibleenum</type> type. Such a
+ type would not be very useful, since there normally are not any
+ implicit casts to enum types, meaning that there would be no way to
+ resolve a common type for dissimilar enum inputs.
+ </para>
+
+ <para>
+ The <quote>simple</quote> and <quote>common</quote> polymorphic
+ families represent two independent sets of type variables. Consider
+ for example
+<programlisting>
+CREATE FUNCTION myfunc(a anyelement, b anyelement,
+ c anycompatible, d anycompatible)
+RETURNS anycompatible AS ...
+</programlisting>
+ In an actual call of this function, the first two inputs must have
+ exactly the same type. The last two inputs must be promotable to a
+ common type, but this type need not have anything to do with the type
+ of the first two inputs. The result will have the common type of the
+ last two inputs.
+ </para>
+
+ <para>
+ A variadic function (one taking a variable number of arguments, as in
+ <xref linkend="xfunc-sql-variadic-functions"/>) can be
+ polymorphic: this is accomplished by declaring its last parameter as
+ <literal>VARIADIC</literal> <type>anyarray</type> or
+ <literal>VARIADIC</literal> <type>anycompatiblearray</type>.
+ For purposes of argument
+ matching and determining the actual result type, such a function behaves
+ the same as if you had written the appropriate number of
+ <type>anynonarray</type> or <type>anycompatiblenonarray</type>
+ parameters.
+ </para>
+ </sect2>
+ </sect1>
+
+ &xfunc;
+ &xaggr;
+ &xtypes;
+ &xoper;
+ &xindex;
+
+
+ <sect1 id="extend-extensions">
+ <title>Packaging Related Objects into an Extension</title>
+
+ <indexterm zone="extend-extensions">
+ <primary>extension</primary>
+ </indexterm>
+
+ <para>
+ A useful extension to <productname>PostgreSQL</productname> typically includes
+ multiple SQL objects; for example, a new data type will require new
+ functions, new operators, and probably new index operator classes.
+ It is helpful to collect all these objects into a single package
+ to simplify database management. <productname>PostgreSQL</productname> calls
+ such a package an <firstterm>extension</firstterm>. To define an extension,
+ you need at least a <firstterm>script file</firstterm> that contains the
+ <acronym>SQL</acronym> commands to create the extension's objects, and a
+ <firstterm>control file</firstterm> that specifies a few basic properties
+ of the extension itself. If the extension includes C code, there
+ will typically also be a shared library file into which the C code
+ has been built. Once you have these files, a simple
+ <link linkend="sql-createextension"><command>CREATE EXTENSION</command></link> command loads the objects into
+ your database.
+ </para>
+
+ <para>
+ The main advantage of using an extension, rather than just running the
+ <acronym>SQL</acronym> script to load a bunch of <quote>loose</quote> objects
+ into your database, is that <productname>PostgreSQL</productname> will then
+ understand that the objects of the extension go together. You can
+ drop all the objects with a single <link linkend="sql-dropextension"><command>DROP EXTENSION</command></link>
+ command (no need to maintain a separate <quote>uninstall</quote> script).
+ Even more useful, <application>pg_dump</application> knows that it should not
+ dump the individual member objects of the extension &mdash; it will
+ just include a <command>CREATE EXTENSION</command> command in dumps, instead.
+ This vastly simplifies migration to a new version of the extension
+ that might contain more or different objects than the old version.
+ Note however that you must have the extension's control, script, and
+ other files available when loading such a dump into a new database.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> will not let you drop an individual object
+ contained in an extension, except by dropping the whole extension.
+ Also, while you can change the definition of an extension member object
+ (for example, via <command>CREATE OR REPLACE FUNCTION</command> for a
+ function), bear in mind that the modified definition will not be dumped
+ by <application>pg_dump</application>. Such a change is usually only sensible if
+ you concurrently make the same change in the extension's script file.
+ (But there are special provisions for tables containing configuration
+ data; see <xref linkend="extend-extensions-config-tables"/>.)
+ In production situations, it's generally better to create an extension
+ update script to perform changes to extension member objects.
+ </para>
+
+ <para>
+ The extension script may set privileges on objects that are part of the
+ extension, using <command>GRANT</command> and <command>REVOKE</command>
+ statements. The final set of privileges for each object (if any are set)
+ will be stored in the
+ <link linkend="catalog-pg-init-privs"><structname>pg_init_privs</structname></link>
+ system catalog. When <application>pg_dump</application> is used, the
+ <command>CREATE EXTENSION</command> command will be included in the dump, followed
+ by the set of <command>GRANT</command> and <command>REVOKE</command>
+ statements necessary to set the privileges on the objects to what they were
+ at the time the dump was taken.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> does not currently support extension scripts
+ issuing <command>CREATE POLICY</command> or <command>SECURITY LABEL</command>
+ statements. These are expected to be set after the extension has been
+ created. All RLS policies and security labels on extension objects will be
+ included in dumps created by <application>pg_dump</application>.
+ </para>
+
+ <para>
+ The extension mechanism also has provisions for packaging modification
+ scripts that adjust the definitions of the SQL objects contained in an
+ extension. For example, if version 1.1 of an extension adds one function
+ and changes the body of another function compared to 1.0, the extension
+ author can provide an <firstterm>update script</firstterm> that makes just those
+ two changes. The <command>ALTER EXTENSION UPDATE</command> command can then
+ be used to apply these changes and track which version of the extension
+ is actually installed in a given database.
+ </para>
+
+ <para>
+ The kinds of SQL objects that can be members of an extension are shown in
+ the description of <link linkend="sql-alterextension"><command>ALTER EXTENSION</command></link>. Notably, objects
+ that are database-cluster-wide, such as databases, roles, and tablespaces,
+ cannot be extension members since an extension is only known within one
+ database. (Although an extension script is not prohibited from creating
+ such objects, if it does so they will not be tracked as part of the
+ extension.) Also notice that while a table can be a member of an
+ extension, its subsidiary objects such as indexes are not directly
+ considered members of the extension.
+ Another important point is that schemas can belong to extensions, but not
+ vice versa: an extension as such has an unqualified name and does not
+ exist <quote>within</quote> any schema. The extension's member objects,
+ however, will belong to schemas whenever appropriate for their object
+ types. It may or may not be appropriate for an extension to own the
+ schema(s) its member objects are within.
+ </para>
+
+ <para>
+ If an extension's script creates any temporary objects (such as temp
+ tables), those objects are treated as extension members for the
+ remainder of the current session, but are automatically dropped at
+ session end, as any temporary object would be. This is an exception
+ to the rule that extension member objects cannot be dropped without
+ dropping the whole extension.
+ </para>
+
+ <sect2>
+ <title>Extension Files</title>
+
+ <indexterm>
+ <primary>control file</primary>
+ </indexterm>
+
+ <para>
+ The <command>CREATE EXTENSION</command> command relies on a control
+ file for each extension, which must be named the same as the extension
+ with a suffix of <literal>.control</literal>, and must be placed in the
+ installation's <literal>SHAREDIR/extension</literal> directory. There
+ must also be at least one <acronym>SQL</acronym> script file, which follows the
+ naming pattern
+ <literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.sql</literal>
+ (for example, <literal>foo--1.0.sql</literal> for version <literal>1.0</literal> of
+ extension <literal>foo</literal>). By default, the script file(s) are also
+ placed in the <literal>SHAREDIR/extension</literal> directory; but the
+ control file can specify a different directory for the script file(s).
+ </para>
+
+ <para>
+ The file format for an extension control file is the same as for the
+ <filename>postgresql.conf</filename> file, namely a list of
+ <replaceable>parameter_name</replaceable> <literal>=</literal> <replaceable>value</replaceable>
+ assignments, one per line. Blank lines and comments introduced by
+ <literal>#</literal> are allowed. Be sure to quote any value that is not
+ a single word or number.
+ </para>
+
+ <para>
+ A control file can set the following parameters:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><varname>directory</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ The directory containing the extension's <acronym>SQL</acronym> script
+ file(s). Unless an absolute path is given, the name is relative to
+ the installation's <literal>SHAREDIR</literal> directory. The
+ default behavior is equivalent to specifying
+ <literal>directory = 'extension'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>default_version</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ The default version of the extension (the one that will be installed
+ if no version is specified in <command>CREATE EXTENSION</command>). Although
+ this can be omitted, that will result in <command>CREATE EXTENSION</command>
+ failing if no <literal>VERSION</literal> option appears, so you generally
+ don't want to do that.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>comment</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ A comment (any string) about the extension. The comment is applied
+ when initially creating an extension, but not during extension updates
+ (since that might override user-added comments). Alternatively,
+ the extension's comment can be set by writing
+ a <xref linkend="sql-comment"/> command in the script file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>encoding</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ The character set encoding used by the script file(s). This should
+ be specified if the script files contain any non-ASCII characters.
+ Otherwise the files will be assumed to be in the database encoding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>module_pathname</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ The value of this parameter will be substituted for each occurrence
+ of <literal>MODULE_PATHNAME</literal> in the script file(s). If it is not
+ set, no substitution is made. Typically, this is set to
+ <literal>$libdir/<replaceable>shared_library_name</replaceable></literal> and
+ then <literal>MODULE_PATHNAME</literal> is used in <command>CREATE
+ FUNCTION</command> commands for C-language functions, so that the script
+ files do not need to hard-wire the name of the shared library.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>requires</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ A list of names of extensions that this extension depends on,
+ for example <literal>requires = 'foo, bar'</literal>. Those
+ extensions must be installed before this one can be installed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>superuser</varname> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ If this parameter is <literal>true</literal> (which is the default),
+ only superusers can create the extension or update it to a new
+ version (but see also <varname>trusted</varname>, below).
+ If it is set to <literal>false</literal>, just the privileges
+ required to execute the commands in the installation or update script
+ are required.
+ This should normally be set to <literal>true</literal> if any of the
+ script commands require superuser privileges. (Such commands would
+ fail anyway, but it's more user-friendly to give the error up front.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>trusted</varname> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This parameter, if set to <literal>true</literal> (which is not the
+ default), allows some non-superusers to install an extension that
+ has <varname>superuser</varname> set to <literal>true</literal>.
+ Specifically, installation will be permitted for anyone who has
+ <literal>CREATE</literal> privilege on the current database.
+ When the user executing <command>CREATE EXTENSION</command> is not
+ a superuser but is allowed to install by virtue of this parameter,
+ then the installation or update script is run as the bootstrap
+ superuser, not as the calling user.
+ This parameter is irrelevant if <varname>superuser</varname> is
+ <literal>false</literal>.
+ Generally, this should not be set true for extensions that could
+ allow access to otherwise-superuser-only abilities, such as
+ file system access.
+ Also, marking an extension trusted requires significant extra effort
+ to write the extension's installation and update script(s) securely;
+ see <xref linkend="extend-extensions-security"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>relocatable</varname> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ An extension is <firstterm>relocatable</firstterm> if it is possible to move
+ its contained objects into a different schema after initial creation
+ of the extension. The default is <literal>false</literal>, i.e., the
+ extension is not relocatable.
+ See <xref linkend="extend-extensions-relocation"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>schema</varname> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This parameter can only be set for non-relocatable extensions.
+ It forces the extension to be loaded into exactly the named schema
+ and not any other.
+ The <varname>schema</varname> parameter is consulted only when
+ initially creating an extension, not during extension updates.
+ See <xref linkend="extend-extensions-relocation"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ In addition to the primary control file
+ <literal><replaceable>extension</replaceable>.control</literal>,
+ an extension can have secondary control files named in the style
+ <literal><replaceable>extension</replaceable>--<replaceable>version</replaceable>.control</literal>.
+ If supplied, these must be located in the script file directory.
+ Secondary control files follow the same format as the primary control
+ file. Any parameters set in a secondary control file override the
+ primary control file when installing or updating to that version of
+ the extension. However, the parameters <varname>directory</varname> and
+ <varname>default_version</varname> cannot be set in a secondary control file.
+ </para>
+
+ <para>
+ An extension's <acronym>SQL</acronym> script files can contain any SQL commands,
+ except for transaction control commands (<command>BEGIN</command>,
+ <command>COMMIT</command>, etc.) and commands that cannot be executed inside a
+ transaction block (such as <command>VACUUM</command>). This is because the
+ script files are implicitly executed within a transaction block.
+ </para>
+
+ <para>
+ An extension's <acronym>SQL</acronym> script files can also contain lines
+ beginning with <literal>\echo</literal>, which will be ignored (treated as
+ comments) by the extension mechanism. This provision is commonly used
+ to throw an error if the script file is fed to <application>psql</application>
+ rather than being loaded via <command>CREATE EXTENSION</command> (see example
+ script in <xref linkend="extend-extensions-example"/>).
+ Without that, users might accidentally load the
+ extension's contents as <quote>loose</quote> objects rather than as an
+ extension, a state of affairs that's a bit tedious to recover from.
+ </para>
+
+ <para>
+ If the extension script contains the
+ string <literal>@extowner@</literal>, that string is replaced with the
+ (suitably quoted) name of the user calling <command>CREATE
+ EXTENSION</command> or <command>ALTER EXTENSION</command>. Typically
+ this feature is used by extensions that are marked trusted to assign
+ ownership of selected objects to the calling user rather than the
+ bootstrap superuser. (One should be careful about doing so, however.
+ For example, assigning ownership of a C-language function to a
+ non-superuser would create a privilege escalation path for that user.)
+ </para>
+
+ <para>
+ While the script files can contain any characters allowed by the specified
+ encoding, control files should contain only plain ASCII, because there
+ is no way for <productname>PostgreSQL</productname> to know what encoding a
+ control file is in. In practice this is only an issue if you want to
+ use non-ASCII characters in the extension's comment. Recommended
+ practice in that case is to not use the control file <varname>comment</varname>
+ parameter, but instead use <command>COMMENT ON EXTENSION</command>
+ within a script file to set the comment.
+ </para>
+
+ </sect2>
+
+ <sect2 id="extend-extensions-relocation">
+ <title>Extension Relocatability</title>
+
+ <para>
+ Users often wish to load the objects contained in an extension into a
+ different schema than the extension's author had in mind. There are
+ three supported levels of relocatability:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A fully relocatable extension can be moved into another schema
+ at any time, even after it's been loaded into a database.
+ This is done with the <command>ALTER EXTENSION SET SCHEMA</command>
+ command, which automatically renames all the member objects into
+ the new schema. Normally, this is only possible if the extension
+ contains no internal assumptions about what schema any of its
+ objects are in. Also, the extension's objects must all be in one
+ schema to begin with (ignoring objects that do not belong to any
+ schema, such as procedural languages). Mark a fully relocatable
+ extension by setting <literal>relocatable = true</literal> in its control
+ file.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ An extension might be relocatable during installation but not
+ afterwards. This is typically the case if the extension's script
+ file needs to reference the target schema explicitly, for example
+ in setting <literal>search_path</literal> properties for SQL functions.
+ For such an extension, set <literal>relocatable = false</literal> in its
+ control file, and use <literal>@extschema@</literal> to refer to the target
+ schema in the script file. All occurrences of this string will be
+ replaced by the actual target schema's name before the script is
+ executed. The user can set the target schema using the
+ <literal>SCHEMA</literal> option of <command>CREATE EXTENSION</command>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the extension does not support relocation at all, set
+ <literal>relocatable = false</literal> in its control file, and also set
+ <literal>schema</literal> to the name of the intended target schema. This
+ will prevent use of the <literal>SCHEMA</literal> option of <command>CREATE
+ EXTENSION</command>, unless it specifies the same schema named in the control
+ file. This choice is typically necessary if the extension contains
+ internal assumptions about schema names that can't be replaced by
+ uses of <literal>@extschema@</literal>. The <literal>@extschema@</literal>
+ substitution mechanism is available in this case too, although it is
+ of limited use since the schema name is determined by the control file.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ In all cases, the script file will be executed with
+ <xref linkend="guc-search-path"/> initially set to point to the target
+ schema; that is, <command>CREATE EXTENSION</command> does the equivalent of
+ this:
+<programlisting>
+SET LOCAL search_path TO @extschema@, pg_temp;
+</programlisting>
+ This allows the objects created by the script file to go into the target
+ schema. The script file can change <varname>search_path</varname> if it wishes,
+ but that is generally undesirable. <varname>search_path</varname> is restored
+ to its previous setting upon completion of <command>CREATE EXTENSION</command>.
+ </para>
+
+ <para>
+ The target schema is determined by the <varname>schema</varname> parameter in
+ the control file if that is given, otherwise by the <literal>SCHEMA</literal>
+ option of <command>CREATE EXTENSION</command> if that is given, otherwise the
+ current default object creation schema (the first one in the caller's
+ <varname>search_path</varname>). When the control file <varname>schema</varname>
+ parameter is used, the target schema will be created if it doesn't
+ already exist, but in the other two cases it must already exist.
+ </para>
+
+ <para>
+ If any prerequisite extensions are listed in <varname>requires</varname>
+ in the control file, their target schemas are added to the initial
+ setting of <varname>search_path</varname>, following the new
+ extension's target schema. This allows their objects to be visible to
+ the new extension's script file.
+ </para>
+
+ <para>
+ For security, <literal>pg_temp</literal> is automatically appended to
+ the end of <varname>search_path</varname> in all cases.
+ </para>
+
+ <para>
+ Although a non-relocatable extension can contain objects spread across
+ multiple schemas, it is usually desirable to place all the objects meant
+ for external use into a single schema, which is considered the extension's
+ target schema. Such an arrangement works conveniently with the default
+ setting of <varname>search_path</varname> during creation of dependent
+ extensions.
+ </para>
+ </sect2>
+
+ <sect2 id="extend-extensions-config-tables">
+ <title>Extension Configuration Tables</title>
+
+ <para>
+ Some extensions include configuration tables, which contain data that
+ might be added or changed by the user after installation of the
+ extension. Ordinarily, if a table is part of an extension, neither
+ the table's definition nor its content will be dumped by
+ <application>pg_dump</application>. But that behavior is undesirable for a
+ configuration table; any data changes made by the user need to be
+ included in dumps, or the extension will behave differently after a dump
+ and restore.
+ </para>
+
+ <indexterm>
+ <primary>pg_extension_config_dump</primary>
+ </indexterm>
+
+ <para>
+ To solve this problem, an extension's script file can mark a table
+ or a sequence it has created as a configuration relation, which will
+ cause <application>pg_dump</application> to include the table's or the sequence's
+ contents (not its definition) in dumps. To do that, call the function
+ <function>pg_extension_config_dump(regclass, text)</function> after creating the
+ table or the sequence, for example
+<programlisting>
+CREATE TABLE my_config (key text, value text);
+CREATE SEQUENCE my_config_seq;
+
+SELECT pg_catalog.pg_extension_config_dump('my_config', '');
+SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');
+</programlisting>
+ Any number of tables or sequences can be marked this way. Sequences
+ associated with <type>serial</type> or <type>bigserial</type> columns can
+ be marked as well.
+ </para>
+
+ <para>
+ When the second argument of <function>pg_extension_config_dump</function> is
+ an empty string, the entire contents of the table are dumped by
+ <application>pg_dump</application>. This is usually only correct if the table
+ is initially empty as created by the extension script. If there is
+ a mixture of initial data and user-provided data in the table,
+ the second argument of <function>pg_extension_config_dump</function> provides
+ a <literal>WHERE</literal> condition that selects the data to be dumped.
+ For example, you might do
+<programlisting>
+CREATE TABLE my_config (key text, value text, standard_entry boolean);
+
+SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
+</programlisting>
+ and then make sure that <structfield>standard_entry</structfield> is true only
+ in the rows created by the extension's script.
+ </para>
+
+ <para>
+ For sequences, the second argument of <function>pg_extension_config_dump</function>
+ has no effect.
+ </para>
+
+ <para>
+ More complicated situations, such as initially-provided rows that might
+ be modified by users, can be handled by creating triggers on the
+ configuration table to ensure that modified rows are marked correctly.
+ </para>
+
+ <para>
+ You can alter the filter condition associated with a configuration table
+ by calling <function>pg_extension_config_dump</function> again. (This would
+ typically be useful in an extension update script.) The only way to mark
+ a table as no longer a configuration table is to dissociate it from the
+ extension with <command>ALTER EXTENSION ... DROP TABLE</command>.
+ </para>
+
+ <para>
+ Note that foreign key relationships between these tables will dictate the
+ order in which the tables are dumped out by pg_dump. Specifically, pg_dump
+ will attempt to dump the referenced-by table before the referencing table.
+ As the foreign key relationships are set up at CREATE EXTENSION time (prior
+ to data being loaded into the tables) circular dependencies are not
+ supported. When circular dependencies exist, the data will still be dumped
+ out but the dump will not be able to be restored directly and user
+ intervention will be required.
+ </para>
+
+ <para>
+ Sequences associated with <type>serial</type> or <type>bigserial</type> columns
+ need to be directly marked to dump their state. Marking their parent
+ relation is not enough for this purpose.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Extension Updates</title>
+
+ <para>
+ One advantage of the extension mechanism is that it provides convenient
+ ways to manage updates to the SQL commands that define an extension's
+ objects. This is done by associating a version name or number with
+ each released version of the extension's installation script.
+ In addition, if you want users to be able to update their databases
+ dynamically from one version to the next, you should provide
+ <firstterm>update scripts</firstterm> that make the necessary changes to go from
+ one version to the next. Update scripts have names following the pattern
+ <literal><replaceable>extension</replaceable>--<replaceable>old_version</replaceable>--<replaceable>target_version</replaceable>.sql</literal>
+ (for example, <literal>foo--1.0--1.1.sql</literal> contains the commands to modify
+ version <literal>1.0</literal> of extension <literal>foo</literal> into version
+ <literal>1.1</literal>).
+ </para>
+
+ <para>
+ Given that a suitable update script is available, the command
+ <command>ALTER EXTENSION UPDATE</command> will update an installed extension
+ to the specified new version. The update script is run in the same
+ environment that <command>CREATE EXTENSION</command> provides for installation
+ scripts: in particular, <varname>search_path</varname> is set up in the same
+ way, and any new objects created by the script are automatically added
+ to the extension. Also, if the script chooses to drop extension member
+ objects, they are automatically dissociated from the extension.
+ </para>
+
+ <para>
+ If an extension has secondary control files, the control parameters
+ that are used for an update script are those associated with the script's
+ target (new) version.
+ </para>
+
+ <para>
+ <command>ALTER EXTENSION</command> is able to execute sequences of update
+ script files to achieve a requested update. For example, if only
+ <literal>foo--1.0--1.1.sql</literal> and <literal>foo--1.1--2.0.sql</literal> are
+ available, <command>ALTER EXTENSION</command> will apply them in sequence if an
+ update to version <literal>2.0</literal> is requested when <literal>1.0</literal> is
+ currently installed.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> doesn't assume anything about the properties
+ of version names: for example, it does not know whether <literal>1.1</literal>
+ follows <literal>1.0</literal>. It just matches up the available version names
+ and follows the path that requires applying the fewest update scripts.
+ (A version name can actually be any string that doesn't contain
+ <literal>--</literal> or leading or trailing <literal>-</literal>.)
+ </para>
+
+ <para>
+ Sometimes it is useful to provide <quote>downgrade</quote> scripts, for
+ example <literal>foo--1.1--1.0.sql</literal> to allow reverting the changes
+ associated with version <literal>1.1</literal>. If you do that, be careful
+ of the possibility that a downgrade script might unexpectedly
+ get applied because it yields a shorter path. The risky case is where
+ there is a <quote>fast path</quote> update script that jumps ahead several
+ versions as well as a downgrade script to the fast path's start point.
+ It might take fewer steps to apply the downgrade and then the fast
+ path than to move ahead one version at a time. If the downgrade script
+ drops any irreplaceable objects, this will yield undesirable results.
+ </para>
+
+ <para>
+ To check for unexpected update paths, use this command:
+<programlisting>
+SELECT * FROM pg_extension_update_paths('<replaceable>extension_name</replaceable>');
+</programlisting>
+ This shows each pair of distinct known version names for the specified
+ extension, together with the update path sequence that would be taken to
+ get from the source version to the target version, or <literal>NULL</literal> if
+ there is no available update path. The path is shown in textual form
+ with <literal>--</literal> separators. You can use
+ <literal>regexp_split_to_array(path,'--')</literal> if you prefer an array
+ format.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Installing Extensions Using Update Scripts</title>
+
+ <para>
+ An extension that has been around for awhile will probably exist in
+ several versions, for which the author will need to write update scripts.
+ For example, if you have released a <literal>foo</literal> extension in
+ versions <literal>1.0</literal>, <literal>1.1</literal>, and <literal>1.2</literal>, there
+ should be update scripts <filename>foo--1.0--1.1.sql</filename>
+ and <filename>foo--1.1--1.2.sql</filename>.
+ Before <productname>PostgreSQL</productname> 10, it was necessary to also create
+ new script files <filename>foo--1.1.sql</filename> and <filename>foo--1.2.sql</filename>
+ that directly build the newer extension versions, or else the newer
+ versions could not be installed directly, only by
+ installing <literal>1.0</literal> and then updating. That was tedious and
+ duplicative, but now it's unnecessary, because <command>CREATE
+ EXTENSION</command> can follow update chains automatically.
+ For example, if only the script
+ files <filename>foo--1.0.sql</filename>, <filename>foo--1.0--1.1.sql</filename>,
+ and <filename>foo--1.1--1.2.sql</filename> are available then a request to
+ install version <literal>1.2</literal> is honored by running those three
+ scripts in sequence. The processing is the same as if you'd first
+ installed <literal>1.0</literal> and then updated to <literal>1.2</literal>.
+ (As with <command>ALTER EXTENSION UPDATE</command>, if multiple pathways are
+ available then the shortest is preferred.) Arranging an extension's
+ script files in this style can reduce the amount of maintenance effort
+ needed to produce small updates.
+ </para>
+
+ <para>
+ If you use secondary (version-specific) control files with an extension
+ maintained in this style, keep in mind that each version needs a control
+ file even if it has no stand-alone installation script, as that control
+ file will determine how the implicit update to that version is performed.
+ For example, if <filename>foo--1.0.control</filename> specifies <literal>requires
+ = 'bar'</literal> but <literal>foo</literal>'s other control files do not, the
+ extension's dependency on <literal>bar</literal> will be dropped when updating
+ from <literal>1.0</literal> to another version.
+ </para>
+ </sect2>
+
+ <sect2 id="extend-extensions-security">
+ <title>Security Considerations for Extensions</title>
+
+ <para>
+ Widely-distributed extensions should assume little about the database
+ they occupy. Therefore, it's appropriate to write functions provided
+ by an extension in a secure style that cannot be compromised by
+ search-path-based attacks.
+ </para>
+
+ <para>
+ An extension that has the <varname>superuser</varname> property set to
+ true must also consider security hazards for the actions taken within
+ its installation and update scripts. It is not terribly difficult for
+ a malicious user to create trojan-horse objects that will compromise
+ later execution of a carelessly-written extension script, allowing that
+ user to acquire superuser privileges.
+ </para>
+
+ <para>
+ If an extension is marked <varname>trusted</varname>, then its
+ installation schema can be selected by the installing user, who might
+ intentionally use an insecure schema in hopes of gaining superuser
+ privileges. Therefore, a trusted extension is extremely exposed from a
+ security standpoint, and all its script commands must be carefully
+ examined to ensure that no compromise is possible.
+ </para>
+
+ <para>
+ Advice about writing functions securely is provided in
+ <xref linkend="extend-extensions-security-funcs"/> below, and advice
+ about writing installation scripts securely is provided in
+ <xref linkend="extend-extensions-security-scripts"/>.
+ </para>
+
+ <sect3 id="extend-extensions-security-funcs">
+ <title>Security Considerations for Extension Functions</title>
+
+ <para>
+ SQL-language and PL-language functions provided by extensions are at
+ risk of search-path-based attacks when they are executed, since
+ parsing of these functions occurs at execution time not creation time.
+ </para>
+
+ <para>
+ The <link linkend="sql-createfunction-security"><command>CREATE
+ FUNCTION</command></link> reference page contains advice about
+ writing <literal>SECURITY DEFINER</literal> functions safely. It's
+ good practice to apply those techniques for any function provided by
+ an extension, since the function might be called by a high-privilege
+ user.
+ </para>
+
+ <!-- XXX It's not enough to use qualified names, because one might write a
+ qualified name to an object that itself uses unqualified names. Many
+ information_schema functions have that defect, for example. However,
+ that's a defect in the referenced object, and relatively few queries
+ will be affected. Also, we direct applications to secure search_path
+ when connecting to an untrusted database; if applications do that,
+ they are immune to known attacks even if some extension refers to a
+ defective object. Therefore, guide extension authors as though core
+ PostgreSQL contained no such defect. -->
+ <para>
+ If you cannot set the <varname>search_path</varname> to contain only
+ secure schemas, assume that each unqualified name could resolve to an
+ object that a malicious user has defined. Beware of constructs that
+ depend on <varname>search_path</varname> implicitly; for
+ example, <token>IN</token>
+ and <literal>CASE <replaceable>expression</replaceable> WHEN</literal>
+ always select an operator using the search path. In their place, use
+ <literal>OPERATOR(<replaceable>schema</replaceable>.=) ANY</literal>
+ and <literal>CASE WHEN <replaceable>expression</replaceable></literal>.
+ </para>
+
+ <para>
+ A general-purpose extension usually should not assume that it's been
+ installed into a secure schema, which means that even schema-qualified
+ references to its own objects are not entirely risk-free. For
+ example, if the extension has defined a
+ function <literal>myschema.myfunc(bigint)</literal> then a call such
+ as <literal>myschema.myfunc(42)</literal> could be captured by a
+ hostile function <literal>myschema.myfunc(integer)</literal>. Be
+ careful that the data types of function and operator parameters exactly
+ match the declared argument types, using explicit casts where necessary.
+ </para>
+ </sect3>
+
+ <sect3 id="extend-extensions-security-scripts">
+ <title>Security Considerations for Extension Scripts</title>
+
+ <para>
+ An extension installation or update script should be written to guard
+ against search-path-based attacks occurring when the script executes.
+ If an object reference in the script can be made to resolve to some
+ other object than the script author intended, then a compromise might
+ occur immediately, or later when the mis-defined extension object is
+ used.
+ </para>
+
+ <para>
+ DDL commands such as <command>CREATE FUNCTION</command>
+ and <command>CREATE OPERATOR CLASS</command> are generally secure,
+ but beware of any command having a general-purpose expression as a
+ component. For example, <command>CREATE VIEW</command> needs to be
+ vetted, as does a <literal>DEFAULT</literal> expression
+ in <command>CREATE FUNCTION</command>.
+ </para>
+
+ <para>
+ Sometimes an extension script might need to execute general-purpose
+ SQL, for example to make catalog adjustments that aren't possible via
+ DDL. Be careful to execute such commands with a
+ secure <varname>search_path</varname>; do <emphasis>not</emphasis>
+ trust the path provided by <command>CREATE/ALTER EXTENSION</command>
+ to be secure. Best practice is to temporarily
+ set <varname>search_path</varname> to <literal>'pg_catalog,
+ pg_temp'</literal> and insert references to the extension's
+ installation schema explicitly where needed. (This practice might
+ also be helpful for creating views.) Examples can be found in
+ the <filename>contrib</filename> modules in
+ the <productname>PostgreSQL</productname> source code distribution.
+ </para>
+
+ <para>
+ Cross-extension references are extremely difficult to make fully
+ secure, partially because of uncertainty about which schema the other
+ extension is in. The hazards are reduced if both extensions are
+ installed in the same schema, because then a hostile object cannot be
+ placed ahead of the referenced extension in the installation-time
+ <varname>search_path</varname>. However, no mechanism currently exists
+ to require that. For now, best practice is to not mark an extension
+ trusted if it depends on another one, unless that other one is always
+ installed in <literal>pg_catalog</literal>.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="extend-extensions-example">
+ <title>Extension Example</title>
+
+ <para>
+ Here is a complete example of an <acronym>SQL</acronym>-only
+ extension, a two-element composite type that can store any type of value
+ in its slots, which are named <quote>k</quote> and <quote>v</quote>. Non-text
+ values are automatically coerced to text for storage.
+ </para>
+
+ <para>
+ The script file <filename>pair--1.0.sql</filename> looks like this:
+
+<programlisting><![CDATA[
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pair" to load this file. \quit
+
+CREATE TYPE pair AS ( k text, v text );
+
+CREATE FUNCTION pair(text, text)
+RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';
+
+CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);
+
+-- "SET search_path" is easy to get right, but qualified names perform better.
+CREATE FUNCTION lower(pair)
+RETURNS pair LANGUAGE SQL
+AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;'
+SET search_path = pg_temp;
+
+CREATE FUNCTION pair_concat(pair, pair)
+RETURNS pair LANGUAGE SQL
+AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k,
+ $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;';
+]]>
+</programlisting>
+ </para>
+
+ <para>
+ The control file <filename>pair.control</filename> looks like this:
+
+<programlisting>
+# pair extension
+comment = 'A key/value pair data type'
+default_version = '1.0'
+# cannot be relocatable because of use of @extschema@
+relocatable = false
+</programlisting>
+ </para>
+
+ <para>
+ While you hardly need a makefile to install these two files into the
+ correct directory, you could use a <filename>Makefile</filename> containing this:
+
+<programlisting>
+EXTENSION = pair
+DATA = pair--1.0.sql
+
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+</programlisting>
+
+ This makefile relies on <acronym>PGXS</acronym>, which is described
+ in <xref linkend="extend-pgxs"/>. The command <literal>make install</literal>
+ will install the control and script files into the correct
+ directory as reported by <application>pg_config</application>.
+ </para>
+
+ <para>
+ Once the files are installed, use the
+ <command>CREATE EXTENSION</command> command to load the objects into
+ any particular database.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="extend-pgxs">
+ <title>Extension Building Infrastructure</title>
+
+ <indexterm zone="extend-pgxs">
+ <primary>pgxs</primary>
+ </indexterm>
+
+ <para>
+ If you are thinking about distributing your
+ <productname>PostgreSQL</productname> extension modules, setting up a
+ portable build system for them can be fairly difficult. Therefore
+ the <productname>PostgreSQL</productname> installation provides a build
+ infrastructure for extensions, called <acronym>PGXS</acronym>, so
+ that simple extension modules can be built simply against an
+ already installed server. <acronym>PGXS</acronym> is mainly intended
+ for extensions that include C code, although it can be used for
+ pure-SQL extensions too. Note that <acronym>PGXS</acronym> is not
+ intended to be a universal build system framework that can be used
+ to build any software interfacing to <productname>PostgreSQL</productname>;
+ it simply automates common build rules for simple server extension
+ modules. For more complicated packages, you might need to write your
+ own build system.
+ </para>
+
+ <para>
+ To use the <acronym>PGXS</acronym> infrastructure for your extension,
+ you must write a simple makefile.
+ In the makefile, you need to set some variables
+ and include the global <acronym>PGXS</acronym> makefile.
+ Here is an example that builds an extension module named
+ <literal>isbn_issn</literal>, consisting of a shared library containing
+ some C code, an extension control file, an SQL script, an include file
+ (only needed if other modules might need to access the extension functions
+ without going via SQL), and a documentation text file:
+<programlisting>
+MODULES = isbn_issn
+EXTENSION = isbn_issn
+DATA = isbn_issn--1.0.sql
+DOCS = README.isbn_issn
+HEADERS_isbn_issn = isbn_issn.h
+
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+</programlisting>
+ The last three lines should always be the same. Earlier in the
+ file, you assign variables or add custom
+ <application>make</application> rules.
+ </para>
+
+ <para>
+ Set one of these three variables to specify what is built:
+
+ <variablelist>
+ <varlistentry>
+ <term><varname>MODULES</varname></term>
+ <listitem>
+ <para>
+ list of shared-library objects to be built from source files with same
+ stem (do not include library suffixes in this list)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MODULE_big</varname></term>
+ <listitem>
+ <para>
+ a shared library to build from multiple source files
+ (list object files in <varname>OBJS</varname>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PROGRAM</varname></term>
+ <listitem>
+ <para>
+ an executable program to build
+ (list object files in <varname>OBJS</varname>)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The following variables can also be set:
+
+ <variablelist>
+ <varlistentry>
+ <term><varname>EXTENSION</varname></term>
+ <listitem>
+ <para>
+ extension name(s); for each name you must provide an
+ <literal><replaceable>extension</replaceable>.control</literal> file,
+ which will be installed into
+ <literal><replaceable>prefix</replaceable>/share/extension</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MODULEDIR</varname></term>
+ <listitem>
+ <para>
+ subdirectory of <literal><replaceable>prefix</replaceable>/share</literal>
+ into which DATA and DOCS files should be installed
+ (if not set, default is <literal>extension</literal> if
+ <varname>EXTENSION</varname> is set,
+ or <literal>contrib</literal> if not)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DATA</varname></term>
+ <listitem>
+ <para>
+ random files to install into <literal><replaceable>prefix</replaceable>/share/$MODULEDIR</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DATA_built</varname></term>
+ <listitem>
+ <para>
+ random files to install into
+ <literal><replaceable>prefix</replaceable>/share/$MODULEDIR</literal>,
+ which need to be built first
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DATA_TSEARCH</varname></term>
+ <listitem>
+ <para>
+ random files to install under
+ <literal><replaceable>prefix</replaceable>/share/tsearch_data</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DOCS</varname></term>
+ <listitem>
+ <para>
+ random files to install under
+ <literal><replaceable>prefix</replaceable>/doc/$MODULEDIR</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HEADERS</varname></term>
+ <term><varname>HEADERS_built</varname></term>
+ <listitem>
+ <para>
+ Files to (optionally build and) install under
+ <literal><replaceable>prefix</replaceable>/include/server/$MODULEDIR/$MODULE_big</literal>.
+ </para>
+ <para>
+ Unlike <literal>DATA_built</literal>, files in <literal>HEADERS_built</literal>
+ are not removed by the <literal>clean</literal> target; if you want them removed,
+ also add them to <literal>EXTRA_CLEAN</literal> or add your own rules to do it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HEADERS_$MODULE</varname></term>
+ <term><varname>HEADERS_built_$MODULE</varname></term>
+ <listitem>
+ <para>
+ Files to install (after building if specified) under
+ <literal><replaceable>prefix</replaceable>/include/server/$MODULEDIR/$MODULE</literal>,
+ where <literal>$MODULE</literal> must be a module name used
+ in <literal>MODULES</literal> or <literal>MODULE_big</literal>.
+ </para>
+ <para>
+ Unlike <literal>DATA_built</literal>, files in <literal>HEADERS_built_$MODULE</literal>
+ are not removed by the <literal>clean</literal> target; if you want them removed,
+ also add them to <literal>EXTRA_CLEAN</literal> or add your own rules to do it.
+ </para>
+ <para>
+ It is legal to use both variables for the same module, or any
+ combination, unless you have two module names in the
+ <literal>MODULES</literal> list that differ only by the presence of a
+ prefix <literal>built_</literal>, which would cause ambiguity. In
+ that (hopefully unlikely) case, you should use only the
+ <literal>HEADERS_built_$MODULE</literal> variables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SCRIPTS</varname></term>
+ <listitem>
+ <para>
+ script files (not binaries) to install into
+ <literal><replaceable>prefix</replaceable>/bin</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SCRIPTS_built</varname></term>
+ <listitem>
+ <para>
+ script files (not binaries) to install into
+ <literal><replaceable>prefix</replaceable>/bin</literal>,
+ which need to be built first
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>REGRESS</varname></term>
+ <listitem>
+ <para>
+ list of regression test cases (without suffix), see below
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>REGRESS_OPTS</varname></term>
+ <listitem>
+ <para>
+ additional switches to pass to <application>pg_regress</application>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ISOLATION</varname></term>
+ <listitem>
+ <para>
+ list of isolation test cases, see below for more details
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ISOLATION_OPTS</varname></term>
+ <listitem>
+ <para>
+ additional switches to pass to
+ <application>pg_isolation_regress</application>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TAP_TESTS</varname></term>
+ <listitem>
+ <para>
+ switch defining if TAP tests need to be run, see below
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>NO_INSTALL</varname></term>
+ <listitem>
+ <para>
+ don't define an <literal>install</literal> target, useful for test
+ modules that don't need their build products to be installed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>NO_INSTALLCHECK</varname></term>
+ <listitem>
+ <para>
+ don't define an <literal>installcheck</literal> target, useful e.g., if tests require special configuration, or don't use <application>pg_regress</application>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>EXTRA_CLEAN</varname></term>
+ <listitem>
+ <para>
+ extra files to remove in <literal>make clean</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PG_CPPFLAGS</varname></term>
+ <listitem>
+ <para>
+ will be prepended to <varname>CPPFLAGS</varname>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PG_CFLAGS</varname></term>
+ <listitem>
+ <para>
+ will be appended to <varname>CFLAGS</varname>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PG_CXXFLAGS</varname></term>
+ <listitem>
+ <para>
+ will be appended to <varname>CXXFLAGS</varname>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PG_LDFLAGS</varname></term>
+ <listitem>
+ <para>
+ will be prepended to <varname>LDFLAGS</varname>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PG_LIBS</varname></term>
+ <listitem>
+ <para>
+ will be added to <varname>PROGRAM</varname> link line
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SHLIB_LINK</varname></term>
+ <listitem>
+ <para>
+ will be added to <varname>MODULE_big</varname> link line
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PG_CONFIG</varname></term>
+ <listitem>
+ <para>
+ path to <application>pg_config</application> program for the
+ <productname>PostgreSQL</productname> installation to build against
+ (typically just <literal>pg_config</literal> to use the first one in your
+ <varname>PATH</varname>)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Put this makefile as <literal>Makefile</literal> in the directory
+ which holds your extension. Then you can do
+ <literal>make</literal> to compile, and then <literal>make
+ install</literal> to install your module. By default, the extension is
+ compiled and installed for the
+ <productname>PostgreSQL</productname> installation that
+ corresponds to the first <command>pg_config</command> program
+ found in your <varname>PATH</varname>. You can use a different installation by
+ setting <varname>PG_CONFIG</varname> to point to its
+ <command>pg_config</command> program, either within the makefile
+ or on the <literal>make</literal> command line.
+ </para>
+
+ <para>
+ You can also run <literal>make</literal> in a directory outside the source
+ tree of your extension, if you want to keep the build directory separate.
+ This procedure is also called a
+ <indexterm><primary>VPATH</primary></indexterm><firstterm>VPATH</firstterm>
+ build. Here's how:
+<programlisting>
+mkdir build_dir
+cd build_dir
+make -f /path/to/extension/source/tree/Makefile
+make -f /path/to/extension/source/tree/Makefile install
+</programlisting>
+ </para>
+
+ <para>
+ Alternatively, you can set up a directory for a VPATH build in a similar
+ way to how it is done for the core code. One way to do this is using the
+ core script <filename>config/prep_buildtree</filename>. Once this has been done
+ you can build by setting the <literal>make</literal> variable
+ <varname>VPATH</varname> like this:
+<programlisting>
+make VPATH=/path/to/extension/source/tree
+make VPATH=/path/to/extension/source/tree install
+</programlisting>
+ This procedure can work with a greater variety of directory layouts.
+ </para>
+
+ <para>
+ The scripts listed in the <varname>REGRESS</varname> variable are used for
+ regression testing of your module, which can be invoked by <literal>make
+ installcheck</literal> after doing <literal>make install</literal>. For this to
+ work you must have a running <productname>PostgreSQL</productname> server.
+ The script files listed in <varname>REGRESS</varname> must appear in a
+ subdirectory named <literal>sql/</literal> in your extension's directory.
+ These files must have extension <literal>.sql</literal>, which must not be
+ included in the <varname>REGRESS</varname> list in the makefile. For each
+ test there should also be a file containing the expected output in a
+ subdirectory named <literal>expected/</literal>, with the same stem and
+ extension <literal>.out</literal>. <literal>make installcheck</literal>
+ executes each test script with <application>psql</application>, and compares the
+ resulting output to the matching expected file. Any differences will be
+ written to the file <literal>regression.diffs</literal> in <command>diff
+ -c</command> format. Note that trying to run a test that is missing its
+ expected file will be reported as <quote>trouble</quote>, so make sure you
+ have all expected files.
+ </para>
+
+ <para>
+ The scripts listed in the <varname>ISOLATION</varname> variable are used
+ for tests stressing behavior of concurrent session with your module, which
+ can be invoked by <literal>make installcheck</literal> after doing
+ <literal>make install</literal>. For this to work you must have a
+ running <productname>PostgreSQL</productname> server. The script files
+ listed in <varname>ISOLATION</varname> must appear in a subdirectory
+ named <literal>specs/</literal> in your extension's directory. These files
+ must have extension <literal>.spec</literal>, which must not be included
+ in the <varname>ISOLATION</varname> list in the makefile. For each test
+ there should also be a file containing the expected output in a
+ subdirectory named <literal>expected/</literal>, with the same stem and
+ extension <literal>.out</literal>. <literal>make installcheck</literal>
+ executes each test script, and compares the resulting output to the
+ matching expected file. Any differences will be written to the file
+ <literal>output_iso/regression.diffs</literal> in
+ <command>diff -c</command> format. Note that trying to run a test that is
+ missing its expected file will be reported as <quote>trouble</quote>, so
+ make sure you have all expected files.
+ </para>
+
+ <para>
+ <literal>TAP_TESTS</literal> enables the use of TAP tests. Data from each
+ run is present in a subdirectory named <literal>tmp_check/</literal>.
+ See also <xref linkend="regress-tap"/> for more details.
+ </para>
+
+ <tip>
+ <para>
+ The easiest way to create the expected files is to create empty files,
+ then do a test run (which will of course report differences). Inspect
+ the actual result files found in the <literal>results/</literal>
+ directory (for tests in <literal>REGRESS</literal>), or
+ <literal>output_iso/results/</literal> directory (for tests in
+ <literal>ISOLATION</literal>), then copy them to
+ <literal>expected/</literal> if they match what you expect from the test.
+ </para>
+
+ </tip>
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/external-projects.sgml b/doc/src/sgml/external-projects.sgml
new file mode 100644
index 0000000..bf590ab
--- /dev/null
+++ b/doc/src/sgml/external-projects.sgml
@@ -0,0 +1,251 @@
+<!-- doc/src/sgml/external-projects.sgml -->
+
+ <appendix id="external-projects">
+ <title>External Projects</title>
+
+ <para>
+ <productname>PostgreSQL</productname> is a complex software project,
+ and managing the project is difficult. We have found that many
+ enhancements to <productname>PostgreSQL</productname> can be more
+ efficiently developed separately from the core project.
+ </para>
+
+ <sect1 id="external-interfaces">
+ <title>Client Interfaces</title>
+
+ <indexterm>
+ <primary>interfaces</primary>
+ <secondary>externally maintained</secondary>
+ </indexterm>
+
+ <para>
+ There are only two client interfaces included in the base
+ <productname>PostgreSQL</productname> distribution:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <link linkend="libpq">libpq</link> is included because it is the
+ primary C language interface, and because many other client interfaces
+ are built on top of it.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <link linkend="ecpg">ECPG</link> is included because it depends on the
+ server-side SQL grammar, and is therefore sensitive to changes in
+ <productname>PostgreSQL</productname> itself.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ All other language interfaces are external projects and are distributed
+ separately. <xref linkend="language-interface-table"/> includes a list of
+ some of these projects. Note that some of these packages might not be
+ released under the same license as <productname>PostgreSQL</productname>. For more
+ information on each language interface, including licensing terms, refer to
+ its website and documentation.
+ </para>
+
+ <table id="language-interface-table">
+ <title>Externally Maintained Client Interfaces</title>
+
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Language</entry>
+ <entry>Comments</entry>
+ <entry>Website</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>DBD::Pg</entry>
+ <entry>Perl</entry>
+ <entry>Perl DBI driver</entry>
+ <entry><ulink url="https://metacpan.org/release/DBD-Pg"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>JDBC</entry>
+ <entry>Java</entry>
+ <entry>Type 4 JDBC driver</entry>
+ <entry><ulink url="https://jdbc.postgresql.org/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>libpqxx</entry>
+ <entry>C++</entry>
+ <entry>C++ interface</entry>
+ <entry><ulink url="https://pqxx.org/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>node-postgres</entry>
+ <entry>JavaScript</entry>
+ <entry>Node.js driver</entry>
+ <entry><ulink url="https://node-postgres.com/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>Npgsql</entry>
+ <entry>.NET</entry>
+ <entry>.NET data provider</entry>
+ <entry><ulink url="https://www.npgsql.org/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>pgtcl</entry>
+ <entry>Tcl</entry>
+ <entry></entry>
+ <entry><ulink url="https://github.com/flightaware/Pgtcl"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>pgtclng</entry>
+ <entry>Tcl</entry>
+ <entry></entry>
+ <entry><ulink url="https://sourceforge.net/projects/pgtclng/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>pq</entry>
+ <entry>Go</entry>
+ <entry>Pure Go driver for Go's database/sql</entry>
+ <entry><ulink url="https://github.com/lib/pq"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>psqlODBC</entry>
+ <entry>ODBC</entry>
+ <entry>ODBC driver</entry>
+ <entry><ulink url="https://odbc.postgresql.org/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>psycopg</entry>
+ <entry>Python</entry>
+ <entry>DB API 2.0-compliant</entry>
+ <entry><ulink url="https://www.psycopg.org/"></ulink></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="external-admin-tools">
+ <title>Administration Tools</title>
+
+ <indexterm>
+ <primary>administration tools</primary>
+ <secondary>externally maintained</secondary>
+ </indexterm>
+
+ <para>
+ There are several administration tools available for
+ <productname>PostgreSQL</productname>. The most popular is
+ <application><ulink url="https://www.pgadmin.org/">pgAdmin</ulink></application>,
+ and there are several commercially available ones as well.
+ </para>
+ </sect1>
+
+ <sect1 id="external-pl">
+ <title>Procedural Languages</title>
+
+ <indexterm>
+ <primary>procedural language</primary>
+ <secondary>externally maintained</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> includes several procedural
+ languages with the base distribution: <link
+ linkend="plpgsql">PL/pgSQL</link>, <link linkend="pltcl">PL/Tcl</link>,
+ <link linkend="plperl">PL/Perl</link>, and <link
+ linkend="plpython">PL/Python</link>.
+ </para>
+
+ <para>
+ In addition, there are a number of procedural languages that are developed
+ and maintained outside the core <productname>PostgreSQL</productname>
+ distribution. <xref linkend="pl-language-table"/> lists some of these
+ packages. Note that some of these projects might not be released under the same
+ license as <productname>PostgreSQL</productname>. For more information on each
+ procedural language, including licensing information, refer to its website
+ and documentation.
+ </para>
+
+ <table id="pl-language-table">
+ <title>Externally Maintained Procedural Languages</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Language</entry>
+ <entry>Website</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>PL/Java</entry>
+ <entry>Java</entry>
+ <entry><ulink url="https://tada.github.io/pljava/"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>PL/Lua</entry>
+ <entry>Lua</entry>
+ <entry><ulink url="https://github.com/pllua/pllua-ng"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>PL/R</entry>
+ <entry>R</entry>
+ <entry><ulink url="https://github.com/postgres-plr/plr"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>PL/sh</entry>
+ <entry>Unix shell</entry>
+ <entry><ulink url="https://github.com/petere/plsh"></ulink></entry>
+ </row>
+
+ <row>
+ <entry>PL/v8</entry>
+ <entry>JavaScript</entry>
+ <entry><ulink url="https://github.com/plv8/plv8"></ulink></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="external-extensions">
+ <title>Extensions</title>
+
+ <indexterm>
+ <primary>extension</primary>
+ <secondary>externally maintained</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> is designed to be easily extensible. For
+ this reason, extensions loaded into the database can function
+ just like features that are built in. The
+ <filename>contrib/</filename> directory shipped with the source code
+ contains several extensions, which are described in
+ <xref linkend="contrib"/>. Other extensions are developed
+ independently, like <application><ulink
+ url="https://postgis.net/">PostGIS</ulink></application>. Even
+ <productname>PostgreSQL</productname> replication solutions can be developed
+ externally. For example, <application> <ulink
+ url="https://www.slony.info">Slony-I</ulink></application> is a popular
+ primary/standby replication solution that is developed independently
+ from the core project.
+ </para>
+ </sect1>
+</appendix>
diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml
new file mode 100644
index 0000000..d0b5951
--- /dev/null
+++ b/doc/src/sgml/fdwhandler.sgml
@@ -0,0 +1,2139 @@
+<!-- doc/src/sgml/fdwhandler.sgml -->
+
+ <chapter id="fdwhandler">
+ <title>Writing a Foreign Data Wrapper</title>
+
+ <indexterm zone="fdwhandler">
+ <primary>foreign data wrapper</primary>
+ <secondary>handler for</secondary>
+ </indexterm>
+
+ <para>
+ All operations on a foreign table are handled through its foreign data
+ wrapper, which consists of a set of functions that the core server
+ calls. The foreign data wrapper is responsible for fetching
+ data from the remote data source and returning it to the
+ <productname>PostgreSQL</productname> executor. If updating foreign
+ tables is to be supported, the wrapper must handle that, too.
+ This chapter outlines how to write a new foreign data wrapper.
+ </para>
+
+ <para>
+ The foreign data wrappers included in the standard distribution are good
+ references when trying to write your own. Look into the
+ <filename>contrib</filename> subdirectory of the source tree.
+ The <xref linkend="sql-createforeigndatawrapper"/> reference page also has
+ some useful details.
+ </para>
+
+ <note>
+ <para>
+ The SQL standard specifies an interface for writing foreign data wrappers.
+ However, PostgreSQL does not implement that API, because the effort to
+ accommodate it into PostgreSQL would be large, and the standard API hasn't
+ gained wide adoption anyway.
+ </para>
+ </note>
+
+ <sect1 id="fdw-functions">
+ <title>Foreign Data Wrapper Functions</title>
+
+ <para>
+ The FDW author needs to implement a handler function, and optionally
+ a validator function. Both functions must be written in a compiled
+ language such as C, using the version-1 interface.
+ For details on C language calling conventions and dynamic loading,
+ see <xref linkend="xfunc-c"/>.
+ </para>
+
+ <para>
+ The handler function simply returns a struct of function pointers to
+ callback functions that will be called by the planner, executor, and
+ various maintenance commands.
+ Most of the effort in writing an FDW is in implementing these callback
+ functions.
+ The handler function must be registered with
+ <productname>PostgreSQL</productname> as taking no arguments and
+ returning the special pseudo-type <type>fdw_handler</type>. The
+ callback functions are plain C functions and are not visible or
+ callable at the SQL level. The callback functions are described in
+ <xref linkend="fdw-callbacks"/>.
+ </para>
+
+ <para>
+ The validator function is responsible for validating options given in
+ <command>CREATE</command> and <command>ALTER</command> commands for its
+ foreign data wrapper, as well as foreign servers, user mappings, and
+ foreign tables using the wrapper.
+ The validator function must be registered as taking two arguments, a
+ text array containing the options to be validated, and an OID
+ representing the type of object the options are associated with (in
+ the form of the OID of the system catalog the object would be stored
+ in, either
+ <literal>ForeignDataWrapperRelationId</literal>,
+ <literal>ForeignServerRelationId</literal>,
+ <literal>UserMappingRelationId</literal>,
+ or <literal>ForeignTableRelationId</literal>).
+ If no validator function is supplied, options are not checked at object
+ creation time or object alteration time.
+ </para>
+
+ </sect1>
+
+ <sect1 id="fdw-callbacks">
+ <title>Foreign Data Wrapper Callback Routines</title>
+
+ <para>
+ The FDW handler function returns a palloc'd <structname>FdwRoutine</structname>
+ struct containing pointers to the callback functions described below.
+ The scan-related functions are required, the rest are optional.
+ </para>
+
+ <para>
+ The <structname>FdwRoutine</structname> struct type is declared in
+ <filename>src/include/foreign/fdwapi.h</filename>, which see for additional
+ details.
+ </para>
+
+ <sect2 id="fdw-callbacks-scan">
+ <title>FDW Routines for Scanning Foreign Tables</title>
+
+ <para>
+<programlisting>
+void
+GetForeignRelSize(PlannerInfo *root,
+ RelOptInfo *baserel,
+ Oid foreigntableid);
+</programlisting>
+
+ Obtain relation size estimates for a foreign table. This is called
+ at the beginning of planning for a query that scans a foreign table.
+ <literal>root</literal> is the planner's global information about the query;
+ <literal>baserel</literal> is the planner's information about this table; and
+ <literal>foreigntableid</literal> is the <structname>pg_class</structname> OID of the
+ foreign table. (<literal>foreigntableid</literal> could be obtained from the
+ planner data structures, but it's passed explicitly to save effort.)
+ </para>
+
+ <para>
+ This function should update <literal>baserel-&gt;rows</literal> to be the
+ expected number of rows returned by the table scan, after accounting for
+ the filtering done by the restriction quals. The initial value of
+ <literal>baserel-&gt;rows</literal> is just a constant default estimate, which
+ should be replaced if at all possible. The function may also choose to
+ update <literal>baserel-&gt;width</literal> if it can compute a better estimate
+ of the average result row width.
+ (The initial value is based on column data types and on column
+ average-width values measured by the last <command>ANALYZE</command>.)
+ Also, this function may update <literal>baserel-&gt;tuples</literal> if
+ it can compute a better estimate of the foreign table's total row count.
+ (The initial value is
+ from <structname>pg_class</structname>.<structfield>reltuples</structfield>
+ which represents the total row count seen by the
+ last <command>ANALYZE</command>; it will be <literal>-1</literal> if
+ no <command>ANALYZE</command> has been done on this foreign table.)
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+
+ <para>
+<programlisting>
+void
+GetForeignPaths(PlannerInfo *root,
+ RelOptInfo *baserel,
+ Oid foreigntableid);
+</programlisting>
+
+ Create possible access paths for a scan on a foreign table.
+ This is called during query planning.
+ The parameters are the same as for <function>GetForeignRelSize</function>,
+ which has already been called.
+ </para>
+
+ <para>
+ This function must generate at least one access path
+ (<structname>ForeignPath</structname> node) for a scan on the foreign table and
+ must call <function>add_path</function> to add each such path to
+ <literal>baserel-&gt;pathlist</literal>. It's recommended to use
+ <function>create_foreignscan_path</function> to build the
+ <structname>ForeignPath</structname> nodes. The function can generate multiple
+ access paths, e.g., a path which has valid <literal>pathkeys</literal> to
+ represent a pre-sorted result. Each access path must contain cost
+ estimates, and can contain any FDW-private information that is needed to
+ identify the specific scan method intended.
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+
+ <para>
+<programlisting>
+ForeignScan *
+GetForeignPlan(PlannerInfo *root,
+ RelOptInfo *baserel,
+ Oid foreigntableid,
+ ForeignPath *best_path,
+ List *tlist,
+ List *scan_clauses,
+ Plan *outer_plan);
+</programlisting>
+
+ Create a <structname>ForeignScan</structname> plan node from the selected foreign
+ access path. This is called at the end of query planning.
+ The parameters are as for <function>GetForeignRelSize</function>, plus
+ the selected <structname>ForeignPath</structname> (previously produced by
+ <function>GetForeignPaths</function>, <function>GetForeignJoinPaths</function>,
+ or <function>GetForeignUpperPaths</function>),
+ the target list to be emitted by the plan node,
+ the restriction clauses to be enforced by the plan node,
+ and the outer subplan of the <structname>ForeignScan</structname>,
+ which is used for rechecks performed by <function>RecheckForeignScan</function>.
+ (If the path is for a join rather than a base
+ relation, <literal>foreigntableid</literal> is <literal>InvalidOid</literal>.)
+ </para>
+
+ <para>
+ This function must create and return a <structname>ForeignScan</structname> plan
+ node; it's recommended to use <function>make_foreignscan</function> to build the
+ <structname>ForeignScan</structname> node.
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+
+ <para>
+<programlisting>
+void
+BeginForeignScan(ForeignScanState *node,
+ int eflags);
+</programlisting>
+
+ Begin executing a foreign scan. This is called during executor startup.
+ It should perform any initialization needed before the scan can start,
+ but not start executing the actual scan (that should be done upon the
+ first call to <function>IterateForeignScan</function>).
+ The <structname>ForeignScanState</structname> node has already been created, but
+ its <structfield>fdw_state</structfield> field is still NULL. Information about
+ the table to scan is accessible through the
+ <structname>ForeignScanState</structname> node (in particular, from the underlying
+ <structname>ForeignScan</structname> plan node, which contains any FDW-private
+ information provided by <function>GetForeignPlan</function>).
+ <literal>eflags</literal> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </para>
+
+ <para>
+ Note that when <literal>(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</literal> is
+ true, this function should not perform any externally-visible actions;
+ it should only do the minimum required to make the node state valid
+ for <function>ExplainForeignScan</function> and <function>EndForeignScan</function>.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot *
+IterateForeignScan(ForeignScanState *node);
+</programlisting>
+
+ Fetch one row from the foreign source, returning it in a tuple table slot
+ (the node's <structfield>ScanTupleSlot</structfield> should be used for this
+ purpose). Return NULL if no more rows are available. The tuple table
+ slot infrastructure allows either a physical or virtual tuple to be
+ returned; in most cases the latter choice is preferable from a
+ performance standpoint. Note that this is called in a short-lived memory
+ context that will be reset between invocations. Create a memory context
+ in <function>BeginForeignScan</function> if you need longer-lived storage, or use
+ the <structfield>es_query_cxt</structfield> of the node's <structname>EState</structname>.
+ </para>
+
+ <para>
+ The rows returned must match the <structfield>fdw_scan_tlist</structfield> target
+ list if one was supplied, otherwise they must match the row type of the
+ foreign table being scanned. If you choose to optimize away fetching
+ columns that are not needed, you should insert nulls in those column
+ positions, or else generate a <structfield>fdw_scan_tlist</structfield> list with
+ those columns omitted.
+ </para>
+
+ <para>
+ Note that <productname>PostgreSQL</productname>'s executor doesn't care
+ whether the rows returned violate any constraints that were defined on
+ the foreign table &mdash; but the planner does care, and may optimize
+ queries incorrectly if there are rows visible in the foreign table that
+ do not satisfy a declared constraint. If a constraint is violated when
+ the user has declared that the constraint should hold true, it may be
+ appropriate to raise an error (just as you would need to do in the case
+ of a data type mismatch).
+ </para>
+
+ <para>
+<programlisting>
+void
+ReScanForeignScan(ForeignScanState *node);
+</programlisting>
+
+ Restart the scan from the beginning. Note that any parameters the
+ scan depends on may have changed value, so the new scan does not
+ necessarily return exactly the same rows.
+ </para>
+
+ <para>
+<programlisting>
+void
+EndForeignScan(ForeignScanState *node);
+</programlisting>
+
+ End the scan and release resources. It is normally not important
+ to release palloc'd memory, but for example open files and connections
+ to remote servers should be cleaned up.
+ </para>
+
+ </sect2>
+
+ <sect2 id="fdw-callbacks-join-scan">
+ <title>FDW Routines for Scanning Foreign Joins</title>
+
+ <para>
+ If an FDW supports performing foreign joins remotely (rather than
+ by fetching both tables' data and doing the join locally), it should
+ provide this callback function:
+ </para>
+
+ <para>
+<programlisting>
+void
+GetForeignJoinPaths(PlannerInfo *root,
+ RelOptInfo *joinrel,
+ RelOptInfo *outerrel,
+ RelOptInfo *innerrel,
+ JoinType jointype,
+ JoinPathExtraData *extra);
+</programlisting>
+ Create possible access paths for a join of two (or more) foreign tables
+ that all belong to the same foreign server. This optional
+ function is called during query planning. As
+ with <function>GetForeignPaths</function>, this function should
+ generate <structname>ForeignPath</structname> path(s) for the
+ supplied <literal>joinrel</literal>
+ (use <function>create_foreign_join_path</function> to build them),
+ and call <function>add_path</function> to add these
+ paths to the set of paths considered for the join. But unlike
+ <function>GetForeignPaths</function>, it is not necessary that this function
+ succeed in creating at least one path, since paths involving local
+ joining are always possible.
+ </para>
+
+ <para>
+ Note that this function will be invoked repeatedly for the same join
+ relation, with different combinations of inner and outer relations; it is
+ the responsibility of the FDW to minimize duplicated work.
+ </para>
+
+ <para>
+ If a <structname>ForeignPath</structname> path is chosen for the join, it will
+ represent the entire join process; paths generated for the component
+ tables and subsidiary joins will not be used. Subsequent processing of
+ the join path proceeds much as it does for a path scanning a single
+ foreign table. One difference is that the <structfield>scanrelid</structfield> of
+ the resulting <structname>ForeignScan</structname> plan node should be set to zero,
+ since there is no single relation that it represents; instead,
+ the <structfield>fs_relids</structfield> field of the <structname>ForeignScan</structname>
+ node represents the set of relations that were joined. (The latter field
+ is set up automatically by the core planner code, and need not be filled
+ by the FDW.) Another difference is that, because the column list for a
+ remote join cannot be found from the system catalogs, the FDW must
+ fill <structfield>fdw_scan_tlist</structfield> with an appropriate list
+ of <structfield>TargetEntry</structfield> nodes, representing the set of columns
+ it will supply at run time in the tuples it returns.
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+ </sect2>
+
+ <sect2 id="fdw-callbacks-upper-planning">
+ <title>FDW Routines for Planning Post-Scan/Join Processing</title>
+
+ <para>
+ If an FDW supports performing remote post-scan/join processing, such as
+ remote aggregation, it should provide this callback function:
+ </para>
+
+ <para>
+<programlisting>
+void
+GetForeignUpperPaths(PlannerInfo *root,
+ UpperRelationKind stage,
+ RelOptInfo *input_rel,
+ RelOptInfo *output_rel,
+ void *extra);
+</programlisting>
+ Create possible access paths for <firstterm>upper relation</firstterm> processing,
+ which is the planner's term for all post-scan/join query processing, such
+ as aggregation, window functions, sorting, and table updates. This
+ optional function is called during query planning. Currently, it is
+ called only if all base relation(s) involved in the query belong to the
+ same FDW. This function should generate <structname>ForeignPath</structname>
+ path(s) for any post-scan/join processing that the FDW knows how to
+ perform remotely
+ (use <function>create_foreign_upper_path</function> to build them),
+ and call <function>add_path</function> to add these paths to
+ the indicated upper relation. As with <function>GetForeignJoinPaths</function>,
+ it is not necessary that this function succeed in creating any paths,
+ since paths involving local processing are always possible.
+ </para>
+
+ <para>
+ The <literal>stage</literal> parameter identifies which post-scan/join step is
+ currently being considered. <literal>output_rel</literal> is the upper relation
+ that should receive paths representing computation of this step,
+ and <literal>input_rel</literal> is the relation representing the input to this
+ step. The <literal>extra</literal> parameter provides additional details,
+ currently, it is set only for <literal>UPPERREL_PARTIAL_GROUP_AGG</literal>
+ or <literal>UPPERREL_GROUP_AGG</literal>, in which case it points to a
+ <literal>GroupPathExtraData</literal> structure;
+ or for <literal>UPPERREL_FINAL</literal>, in which case it points to a
+ <literal>FinalPathExtraData</literal> structure.
+ (Note that <structname>ForeignPath</structname> paths added
+ to <literal>output_rel</literal> would typically not have any direct dependency
+ on paths of the <literal>input_rel</literal>, since their processing is expected
+ to be done externally. However, examining paths previously generated for
+ the previous processing step can be useful to avoid redundant planning
+ work.)
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+ </sect2>
+
+ <sect2 id="fdw-callbacks-update">
+ <title>FDW Routines for Updating Foreign Tables</title>
+
+ <para>
+ If an FDW supports writable foreign tables, it should provide
+ some or all of the following callback functions depending on
+ the needs and capabilities of the FDW:
+ </para>
+
+ <para>
+<programlisting>
+void
+AddForeignUpdateTargets(PlannerInfo *root,
+ Index rtindex,
+ RangeTblEntry *target_rte,
+ Relation target_relation);
+</programlisting>
+
+ <command>UPDATE</command> and <command>DELETE</command> operations are performed
+ against rows previously fetched by the table-scanning functions. The
+ FDW may need extra information, such as a row ID or the values of
+ primary-key columns, to ensure that it can identify the exact row to
+ update or delete. To support that, this function can add extra hidden,
+ or <quote>junk</quote>, target columns to the list of columns that are to be
+ retrieved from the foreign table during an <command>UPDATE</command> or
+ <command>DELETE</command>.
+ </para>
+
+ <para>
+ To do that, construct a <structname>Var</structname> representing
+ an extra value you need, and pass it
+ to <function>add_row_identity_var</function>, along with a name for
+ the junk column. (You can do this more than once if several columns
+ are needed.) You must choose a distinct junk column name for each
+ different <structname>Var</structname> you need, except
+ that <structname>Var</structname>s that are identical except for
+ the <structfield>varno</structfield> field can and should share a
+ column name.
+ The core system uses the junk column names
+ <literal>tableoid</literal> for a
+ table's <structfield>tableoid</structfield> column,
+ <literal>ctid</literal>
+ or <literal>ctid<replaceable>N</replaceable></literal>
+ for <structfield>ctid</structfield>,
+ <literal>wholerow</literal>
+ for a whole-row <structname>Var</structname> marked with
+ <structfield>vartype</structfield> = <type>RECORD</type>,
+ and <literal>wholerow<replaceable>N</replaceable></literal>
+ for a whole-row <structname>Var</structname> with
+ <structfield>vartype</structfield> equal to the table's declared row type.
+ Re-use these names when you can (the planner will combine duplicate
+ requests for identical junk columns). If you need another kind of
+ junk column besides these, it might be wise to choose a name prefixed
+ with your extension name, to avoid conflicts against other FDWs.
+ </para>
+
+ <para>
+ If the <function>AddForeignUpdateTargets</function> pointer is set to
+ <literal>NULL</literal>, no extra target expressions are added.
+ (This will make it impossible to implement <command>DELETE</command>
+ operations, though <command>UPDATE</command> may still be feasible if the FDW
+ relies on an unchanging primary key to identify rows.)
+ </para>
+
+ <para>
+<programlisting>
+List *
+PlanForeignModify(PlannerInfo *root,
+ ModifyTable *plan,
+ Index resultRelation,
+ int subplan_index);
+</programlisting>
+
+ Perform any additional planning actions needed for an insert, update, or
+ delete on a foreign table. This function generates the FDW-private
+ information that will be attached to the <structname>ModifyTable</structname> plan
+ node that performs the update action. This private information must
+ have the form of a <literal>List</literal>, and will be delivered to
+ <function>BeginForeignModify</function> during the execution stage.
+ </para>
+
+ <para>
+ <literal>root</literal> is the planner's global information about the query.
+ <literal>plan</literal> is the <structname>ModifyTable</structname> plan node, which is
+ complete except for the <structfield>fdwPrivLists</structfield> field.
+ <literal>resultRelation</literal> identifies the target foreign table by its
+ range table index. <literal>subplan_index</literal> identifies which target of
+ the <structname>ModifyTable</structname> plan node this is, counting from zero;
+ use this if you want to index into per-target-relation substructures of the
+ <literal>plan</literal> node.
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+
+ <para>
+ If the <function>PlanForeignModify</function> pointer is set to
+ <literal>NULL</literal>, no additional plan-time actions are taken, and the
+ <literal>fdw_private</literal> list delivered to
+ <function>BeginForeignModify</function> will be NIL.
+ </para>
+
+ <para>
+<programlisting>
+void
+BeginForeignModify(ModifyTableState *mtstate,
+ ResultRelInfo *rinfo,
+ List *fdw_private,
+ int subplan_index,
+ int eflags);
+</programlisting>
+
+ Begin executing a foreign table modification operation. This routine is
+ called during executor startup. It should perform any initialization
+ needed prior to the actual table modifications. Subsequently,
+ <function>ExecForeignInsert/ExecForeignBatchInsert</function>,
+ <function>ExecForeignUpdate</function> or
+ <function>ExecForeignDelete</function> will be called for tuple(s) to be
+ inserted, updated, or deleted.
+ </para>
+
+ <para>
+ <literal>mtstate</literal> is the overall state of the
+ <structname>ModifyTable</structname> plan node being executed; global data about
+ the plan and execution state is available via this structure.
+ <literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
+ the target foreign table. (The <structfield>ri_FdwState</structfield> field of
+ <structname>ResultRelInfo</structname> is available for the FDW to store any
+ private state it needs for this operation.)
+ <literal>fdw_private</literal> contains the private data generated by
+ <function>PlanForeignModify</function>, if any.
+ <literal>subplan_index</literal> identifies which target of
+ the <structname>ModifyTable</structname> plan node this is.
+ <literal>eflags</literal> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </para>
+
+ <para>
+ Note that when <literal>(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</literal> is
+ true, this function should not perform any externally-visible actions;
+ it should only do the minimum required to make the node state valid
+ for <function>ExplainForeignModify</function> and <function>EndForeignModify</function>.
+ </para>
+
+ <para>
+ If the <function>BeginForeignModify</function> pointer is set to
+ <literal>NULL</literal>, no action is taken during executor startup.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot *
+ExecForeignInsert(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot *slot,
+ TupleTableSlot *planSlot);
+</programlisting>
+
+ Insert one tuple into the foreign table.
+ <literal>estate</literal> is global execution state for the query.
+ <literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
+ the target foreign table.
+ <literal>slot</literal> contains the tuple to be inserted; it will match the
+ row-type definition of the foreign table.
+ <literal>planSlot</literal> contains the tuple that was generated by the
+ <structname>ModifyTable</structname> plan node's subplan; it differs from
+ <literal>slot</literal> in possibly containing additional <quote>junk</quote>
+ columns. (The <literal>planSlot</literal> is typically of little interest
+ for <command>INSERT</command> cases, but is provided for completeness.)
+ </para>
+
+ <para>
+ The return value is either a slot containing the data that was actually
+ inserted (this might differ from the data supplied, for example as a
+ result of trigger actions), or NULL if no row was actually inserted
+ (again, typically as a result of triggers). The passed-in
+ <literal>slot</literal> can be re-used for this purpose.
+ </para>
+
+ <para>
+ The data in the returned slot is used only if the <command>INSERT</command>
+ statement has a <literal>RETURNING</literal> clause or involves a view
+ <literal>WITH CHECK OPTION</literal>; or if the foreign table has
+ an <literal>AFTER ROW</literal> trigger. Triggers require all columns,
+ but the FDW could choose to optimize away returning some or all columns
+ depending on the contents of the <literal>RETURNING</literal> clause or
+ <literal>WITH CHECK OPTION</literal> constraints. Regardless, some slot
+ must be returned to indicate success, or the query's reported row count
+ will be wrong.
+ </para>
+
+ <para>
+ If the <function>ExecForeignInsert</function> pointer is set to
+ <literal>NULL</literal>, attempts to insert into the foreign table will fail
+ with an error message.
+ </para>
+
+ <para>
+ Note that this function is also called when inserting routed tuples into
+ a foreign-table partition or executing <command>COPY FROM</command> on
+ a foreign table, in which case it is called in a different way than it
+ is in the <command>INSERT</command> case. See the callback functions
+ described below that allow the FDW to support that.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot **
+ExecForeignBatchInsert(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot **slots,
+ TupleTableSlot **planSlots,
+ int *numSlots);
+</programlisting>
+
+ Insert multiple tuples in bulk into the foreign table.
+ The parameters are the same for <function>ExecForeignInsert</function>
+ except <literal>slots</literal> and <literal>planSlots</literal> contain
+ multiple tuples and <literal>*numSlots</literal> specifies the number of
+ tuples in those arrays.
+ </para>
+
+ <para>
+ The return value is an array of slots containing the data that was
+ actually inserted (this might differ from the data supplied, for
+ example as a result of trigger actions.)
+ The passed-in <literal>slots</literal> can be re-used for this purpose.
+ The number of successfully inserted tuples is returned in
+ <literal>*numSlots</literal>.
+ </para>
+
+ <para>
+ The data in the returned slot is used only if the <command>INSERT</command>
+ statement involves a view
+ <literal>WITH CHECK OPTION</literal>; or if the foreign table has
+ an <literal>AFTER ROW</literal> trigger. Triggers require all columns,
+ but the FDW could choose to optimize away returning some or all columns
+ depending on the contents of the
+ <literal>WITH CHECK OPTION</literal> constraints.
+ </para>
+
+ <para>
+ If the <function>ExecForeignBatchInsert</function> or
+ <function>GetForeignModifyBatchSize</function> pointer is set to
+ <literal>NULL</literal>, attempts to insert into the foreign table will
+ use <function>ExecForeignInsert</function>.
+ This function is not used if the <command>INSERT</command> has the
+ <literal>RETURNING</literal> clause.
+ </para>
+
+ <para>
+ Note that this function is also called when inserting routed tuples into
+ a foreign-table partition. See the callback functions
+ described below that allow the FDW to support that.
+ </para>
+
+ <para>
+<programlisting>
+int
+GetForeignModifyBatchSize(ResultRelInfo *rinfo);
+</programlisting>
+
+ Report the maximum number of tuples that a single
+ <function>ExecForeignBatchInsert</function> call can handle for
+ the specified foreign table. The executor passes at most
+ the given number of tuples to <function>ExecForeignBatchInsert</function>.
+ <literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
+ the target foreign table.
+ The FDW is expected to provide a foreign server and/or foreign
+ table option for the user to set this value, or some hard-coded value.
+ </para>
+
+ <para>
+ If the <function>ExecForeignBatchInsert</function> or
+ <function>GetForeignModifyBatchSize</function> pointer is set to
+ <literal>NULL</literal>, attempts to insert into the foreign table will
+ use <function>ExecForeignInsert</function>.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot *
+ExecForeignUpdate(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot *slot,
+ TupleTableSlot *planSlot);
+</programlisting>
+
+ Update one tuple in the foreign table.
+ <literal>estate</literal> is global execution state for the query.
+ <literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
+ the target foreign table.
+ <literal>slot</literal> contains the new data for the tuple; it will match the
+ row-type definition of the foreign table.
+ <literal>planSlot</literal> contains the tuple that was generated by the
+ <structname>ModifyTable</structname> plan node's subplan. Unlike
+ <literal>slot</literal>, this tuple contains only the new values for
+ columns changed by the query, so do not rely on attribute numbers of the
+ foreign table to index into <literal>planSlot</literal>.
+ Also, <literal>planSlot</literal> typically contains
+ additional <quote>junk</quote> columns. In particular, any junk columns
+ that were requested by <function>AddForeignUpdateTargets</function> will
+ be available from this slot.
+ </para>
+
+ <para>
+ The return value is either a slot containing the row as it was actually
+ updated (this might differ from the data supplied, for example as a
+ result of trigger actions), or NULL if no row was actually updated
+ (again, typically as a result of triggers). The passed-in
+ <literal>slot</literal> can be re-used for this purpose.
+ </para>
+
+ <para>
+ The data in the returned slot is used only if the <command>UPDATE</command>
+ statement has a <literal>RETURNING</literal> clause or involves a view
+ <literal>WITH CHECK OPTION</literal>; or if the foreign table has
+ an <literal>AFTER ROW</literal> trigger. Triggers require all columns,
+ but the FDW could choose to optimize away returning some or all columns
+ depending on the contents of the <literal>RETURNING</literal> clause or
+ <literal>WITH CHECK OPTION</literal> constraints. Regardless, some slot
+ must be returned to indicate success, or the query's reported row count
+ will be wrong.
+ </para>
+
+ <para>
+ If the <function>ExecForeignUpdate</function> pointer is set to
+ <literal>NULL</literal>, attempts to update the foreign table will fail
+ with an error message.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot *
+ExecForeignDelete(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot *slot,
+ TupleTableSlot *planSlot);
+</programlisting>
+
+ Delete one tuple from the foreign table.
+ <literal>estate</literal> is global execution state for the query.
+ <literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
+ the target foreign table.
+ <literal>slot</literal> contains nothing useful upon call, but can be used to
+ hold the returned tuple.
+ <literal>planSlot</literal> contains the tuple that was generated by the
+ <structname>ModifyTable</structname> plan node's subplan; in particular, it will
+ carry any junk columns that were requested by
+ <function>AddForeignUpdateTargets</function>. The junk column(s) must be used
+ to identify the tuple to be deleted.
+ </para>
+
+ <para>
+ The return value is either a slot containing the row that was deleted,
+ or NULL if no row was deleted (typically as a result of triggers). The
+ passed-in <literal>slot</literal> can be used to hold the tuple to be returned.
+ </para>
+
+ <para>
+ The data in the returned slot is used only if the <command>DELETE</command>
+ query has a <literal>RETURNING</literal> clause or the foreign table has
+ an <literal>AFTER ROW</literal> trigger. Triggers require all columns, but the
+ FDW could choose to optimize away returning some or all columns depending
+ on the contents of the <literal>RETURNING</literal> clause. Regardless, some
+ slot must be returned to indicate success, or the query's reported row
+ count will be wrong.
+ </para>
+
+ <para>
+ If the <function>ExecForeignDelete</function> pointer is set to
+ <literal>NULL</literal>, attempts to delete from the foreign table will fail
+ with an error message.
+ </para>
+
+ <para>
+<programlisting>
+void
+EndForeignModify(EState *estate,
+ ResultRelInfo *rinfo);
+</programlisting>
+
+ End the table update and release resources. It is normally not important
+ to release palloc'd memory, but for example open files and connections
+ to remote servers should be cleaned up.
+ </para>
+
+ <para>
+ If the <function>EndForeignModify</function> pointer is set to
+ <literal>NULL</literal>, no action is taken during executor shutdown.
+ </para>
+
+ <para>
+ Tuples inserted into a partitioned table by <command>INSERT</command> or
+ <command>COPY FROM</command> are routed to partitions. If an FDW
+ supports routable foreign-table partitions, it should also provide the
+ following callback functions. These functions are also called when
+ <command>COPY FROM</command> is executed on a foreign table.
+ </para>
+
+ <para>
+<programlisting>
+void
+BeginForeignInsert(ModifyTableState *mtstate,
+ ResultRelInfo *rinfo);
+</programlisting>
+
+ Begin executing an insert operation on a foreign table. This routine is
+ called right before the first tuple is inserted into the foreign table
+ in both cases when it is the partition chosen for tuple routing and the
+ target specified in a <command>COPY FROM</command> command. It should
+ perform any initialization needed prior to the actual insertion.
+ Subsequently, <function>ExecForeignInsert</function> or
+ <function>ExecForeignBatchInsert</function> will be called for
+ tuple(s) to be inserted into the foreign table.
+ </para>
+
+ <para>
+ <literal>mtstate</literal> is the overall state of the
+ <structname>ModifyTable</structname> plan node being executed; global data about
+ the plan and execution state is available via this structure.
+ <literal>rinfo</literal> is the <structname>ResultRelInfo</structname> struct describing
+ the target foreign table. (The <structfield>ri_FdwState</structfield> field of
+ <structname>ResultRelInfo</structname> is available for the FDW to store any
+ private state it needs for this operation.)
+ </para>
+
+ <para>
+ When this is called by a <command>COPY FROM</command> command, the
+ plan-related global data in <literal>mtstate</literal> is not provided
+ and the <literal>planSlot</literal> parameter of
+ <function>ExecForeignInsert</function> subsequently called for each
+ inserted tuple is <literal>NULL</literal>, whether the foreign table is
+ the partition chosen for tuple routing or the target specified in the
+ command.
+ </para>
+
+ <para>
+ If the <function>BeginForeignInsert</function> pointer is set to
+ <literal>NULL</literal>, no action is taken for the initialization.
+ </para>
+
+ <para>
+ Note that if the FDW does not support routable foreign-table partitions
+ and/or executing <command>COPY FROM</command> on foreign tables, this
+ function or <function>ExecForeignInsert/ExecForeignBatchInsert</function>
+ subsequently called must throw error as needed.
+ </para>
+
+ <para>
+<programlisting>
+void
+EndForeignInsert(EState *estate,
+ ResultRelInfo *rinfo);
+</programlisting>
+
+ End the insert operation and release resources. It is normally not important
+ to release palloc'd memory, but for example open files and connections
+ to remote servers should be cleaned up.
+ </para>
+
+ <para>
+ If the <function>EndForeignInsert</function> pointer is set to
+ <literal>NULL</literal>, no action is taken for the termination.
+ </para>
+
+ <para>
+<programlisting>
+int
+IsForeignRelUpdatable(Relation rel);
+</programlisting>
+
+ Report which update operations the specified foreign table supports.
+ The return value should be a bit mask of rule event numbers indicating
+ which operations are supported by the foreign table, using the
+ <literal>CmdType</literal> enumeration; that is,
+ <literal>(1 &lt;&lt; CMD_UPDATE) = 4</literal> for <command>UPDATE</command>,
+ <literal>(1 &lt;&lt; CMD_INSERT) = 8</literal> for <command>INSERT</command>, and
+ <literal>(1 &lt;&lt; CMD_DELETE) = 16</literal> for <command>DELETE</command>.
+ </para>
+
+ <para>
+ If the <function>IsForeignRelUpdatable</function> pointer is set to
+ <literal>NULL</literal>, foreign tables are assumed to be insertable, updatable,
+ or deletable if the FDW provides <function>ExecForeignInsert</function>,
+ <function>ExecForeignUpdate</function>, or <function>ExecForeignDelete</function>
+ respectively. This function is only needed if the FDW supports some
+ tables that are updatable and some that are not. (Even then, it's
+ permissible to throw an error in the execution routine instead of
+ checking in this function. However, this function is used to determine
+ updatability for display in the <literal>information_schema</literal> views.)
+ </para>
+
+ <para>
+ Some inserts, updates, and deletes to foreign tables can be optimized
+ by implementing an alternative set of interfaces. The ordinary
+ interfaces for inserts, updates, and deletes fetch rows from the remote
+ server and then modify those rows one at a time. In some cases, this
+ row-by-row approach is necessary, but it can be inefficient. If it is
+ possible for the foreign server to determine which rows should be
+ modified without actually retrieving them, and if there are no local
+ structures which would affect the operation (row-level local triggers,
+ stored generated columns, or <literal>WITH CHECK OPTION</literal>
+ constraints from parent views), then it is possible to arrange things
+ so that the entire operation is performed on the remote server. The
+ interfaces described below make this possible.
+ </para>
+
+ <para>
+<programlisting>
+bool
+PlanDirectModify(PlannerInfo *root,
+ ModifyTable *plan,
+ Index resultRelation,
+ int subplan_index);
+</programlisting>
+
+ Decide whether it is safe to execute a direct modification
+ on the remote server. If so, return <literal>true</literal> after performing
+ planning actions needed for that. Otherwise, return <literal>false</literal>.
+ This optional function is called during query planning.
+ If this function succeeds, <function>BeginDirectModify</function>,
+ <function>IterateDirectModify</function> and <function>EndDirectModify</function> will
+ be called at the execution stage, instead. Otherwise, the table
+ modification will be executed using the table-updating functions
+ described above.
+ The parameters are the same as for <function>PlanForeignModify</function>.
+ </para>
+
+ <para>
+ To execute the direct modification on the remote server, this function
+ must rewrite the target subplan with a <structname>ForeignScan</structname> plan
+ node that executes the direct modification on the remote server. The
+ <structfield>operation</structfield> and <structfield>resultRelation</structfield> fields
+ of the <structname>ForeignScan</structname> must be set appropriately.
+ <structfield>operation</structfield> must be set to the <literal>CmdType</literal>
+ enumeration corresponding to the statement kind (that is,
+ <literal>CMD_UPDATE</literal> for <command>UPDATE</command>,
+ <literal>CMD_INSERT</literal> for <command>INSERT</command>, and
+ <literal>CMD_DELETE</literal> for <command>DELETE</command>), and the
+ <literal>resultRelation</literal> argument must be copied to the
+ <structfield>resultRelation</structfield> field.
+ </para>
+
+ <para>
+ See <xref linkend="fdw-planning"/> for additional information.
+ </para>
+
+ <para>
+ If the <function>PlanDirectModify</function> pointer is set to
+ <literal>NULL</literal>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </para>
+
+ <para>
+<programlisting>
+void
+BeginDirectModify(ForeignScanState *node,
+ int eflags);
+</programlisting>
+
+ Prepare to execute a direct modification on the remote server.
+ This is called during executor startup. It should perform any
+ initialization needed prior to the direct modification (that should be
+ done upon the first call to <function>IterateDirectModify</function>).
+ The <structname>ForeignScanState</structname> node has already been created, but
+ its <structfield>fdw_state</structfield> field is still NULL. Information about
+ the table to modify is accessible through the
+ <structname>ForeignScanState</structname> node (in particular, from the underlying
+ <structname>ForeignScan</structname> plan node, which contains any FDW-private
+ information provided by <function>PlanDirectModify</function>).
+ <literal>eflags</literal> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </para>
+
+ <para>
+ Note that when <literal>(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</literal> is
+ true, this function should not perform any externally-visible actions;
+ it should only do the minimum required to make the node state valid
+ for <function>ExplainDirectModify</function> and <function>EndDirectModify</function>.
+ </para>
+
+ <para>
+ If the <function>BeginDirectModify</function> pointer is set to
+ <literal>NULL</literal>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </para>
+
+ <para>
+<programlisting>
+TupleTableSlot *
+IterateDirectModify(ForeignScanState *node);
+</programlisting>
+
+ When the <command>INSERT</command>, <command>UPDATE</command> or <command>DELETE</command>
+ query doesn't have a <literal>RETURNING</literal> clause, just return NULL
+ after a direct modification on the remote server.
+ When the query has the clause, fetch one result containing the data
+ needed for the <literal>RETURNING</literal> calculation, returning it in a
+ tuple table slot (the node's <structfield>ScanTupleSlot</structfield> should be
+ used for this purpose). The data that was actually inserted, updated
+ or deleted must be stored in
+ <literal>node->resultRelInfo->ri_projectReturning-&gt;pi_exprContext-&gt;ecxt_scantuple</literal>.
+ Return NULL if no more rows are available.
+ Note that this is called in a short-lived memory context that will be
+ reset between invocations. Create a memory context in
+ <function>BeginDirectModify</function> if you need longer-lived storage, or use
+ the <structfield>es_query_cxt</structfield> of the node's <structname>EState</structname>.
+ </para>
+
+ <para>
+ The rows returned must match the <structfield>fdw_scan_tlist</structfield> target
+ list if one was supplied, otherwise they must match the row type of the
+ foreign table being updated. If you choose to optimize away fetching
+ columns that are not needed for the <literal>RETURNING</literal> calculation,
+ you should insert nulls in those column positions, or else generate a
+ <structfield>fdw_scan_tlist</structfield> list with those columns omitted.
+ </para>
+
+ <para>
+ Whether the query has the clause or not, the query's reported row count
+ must be incremented by the FDW itself. When the query doesn't have the
+ clause, the FDW must also increment the row count for the
+ <structname>ForeignScanState</structname> node in the <command>EXPLAIN ANALYZE</command>
+ case.
+ </para>
+
+ <para>
+ If the <function>IterateDirectModify</function> pointer is set to
+ <literal>NULL</literal>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </para>
+
+ <para>
+<programlisting>
+void
+EndDirectModify(ForeignScanState *node);
+</programlisting>
+
+ Clean up following a direct modification on the remote server. It is
+ normally not important to release palloc'd memory, but for example open
+ files and connections to the remote server should be cleaned up.
+ </para>
+
+ <para>
+ If the <function>EndDirectModify</function> pointer is set to
+ <literal>NULL</literal>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </para>
+
+ </sect2>
+
+ <sect2 id="fdw-callbacks-truncate">
+ <title>FDW Routines for <command>TRUNCATE</command></title>
+
+ <para>
+<programlisting>
+void
+ExecForeignTruncate(List *rels,
+ DropBehavior behavior,
+ bool restart_seqs);
+</programlisting>
+
+ Truncate foreign tables. This function is called when
+ <xref linkend="sql-truncate"/> is executed on a foreign table.
+ <literal>rels</literal> is a list of <structname>Relation</structname>
+ data structures of foreign tables to truncate.
+ </para>
+
+ <para>
+ <literal>behavior</literal> is either <literal>DROP_RESTRICT</literal>
+ or <literal>DROP_CASCADE</literal> indicating that the
+ <literal>RESTRICT</literal> or <literal>CASCADE</literal> option was
+ requested in the original <command>TRUNCATE</command> command,
+ respectively.
+ </para>
+
+ <para>
+ If <literal>restart_seqs</literal> is <literal>true</literal>,
+ the original <command>TRUNCATE</command> command requested the
+ <literal>RESTART IDENTITY</literal> behavior, otherwise the
+ <literal>CONTINUE IDENTITY</literal> behavior was requested.
+ </para>
+
+ <para>
+ Note that the <literal>ONLY</literal> options specified
+ in the original <command>TRUNCATE</command> command are not passed to
+ <function>ExecForeignTruncate</function>. This behavior is similar to
+ the callback functions of <command>SELECT</command>,
+ <command>UPDATE</command> and <command>DELETE</command> on
+ a foreign table.
+ </para>
+
+ <para>
+ <function>ExecForeignTruncate</function> is invoked once per
+ foreign server for which foreign tables are to be truncated.
+ This means that all foreign tables included in <literal>rels</literal>
+ must belong to the same server.
+ </para>
+
+ <para>
+ If the <function>ExecForeignTruncate</function> pointer is set to
+ <literal>NULL</literal>, attempts to truncate foreign tables will
+ fail with an error message.
+ </para>
+ </sect2>
+
+ <sect2 id="fdw-callbacks-row-locking">
+ <title>FDW Routines for Row Locking</title>
+
+ <para>
+ If an FDW wishes to support <firstterm>late row locking</firstterm> (as described
+ in <xref linkend="fdw-row-locking"/>), it must provide the following
+ callback functions:
+ </para>
+
+ <para>
+<programlisting>
+RowMarkType
+GetForeignRowMarkType(RangeTblEntry *rte,
+ LockClauseStrength strength);
+</programlisting>
+
+ Report which row-marking option to use for a foreign table.
+ <literal>rte</literal> is the <structname>RangeTblEntry</structname> node for the table
+ and <literal>strength</literal> describes the lock strength requested by the
+ relevant <literal>FOR UPDATE/SHARE</literal> clause, if any. The result must be
+ a member of the <literal>RowMarkType</literal> enum type.
+ </para>
+
+ <para>
+ This function is called during query planning for each foreign table that
+ appears in an <command>UPDATE</command>, <command>DELETE</command>, or <command>SELECT
+ FOR UPDATE/SHARE</command> query and is not the target of <command>UPDATE</command>
+ or <command>DELETE</command>.
+ </para>
+
+ <para>
+ If the <function>GetForeignRowMarkType</function> pointer is set to
+ <literal>NULL</literal>, the <literal>ROW_MARK_COPY</literal> option is always used.
+ (This implies that <function>RefetchForeignRow</function> will never be called,
+ so it need not be provided either.)
+ </para>
+
+ <para>
+ See <xref linkend="fdw-row-locking"/> for more information.
+ </para>
+
+ <para>
+<programlisting>
+void
+RefetchForeignRow(EState *estate,
+ ExecRowMark *erm,
+ Datum rowid,
+ TupleTableSlot *slot,
+ bool *updated);
+</programlisting>
+
+ Re-fetch one tuple slot from the foreign table, after locking it if required.
+ <literal>estate</literal> is global execution state for the query.
+ <literal>erm</literal> is the <structname>ExecRowMark</structname> struct describing
+ the target foreign table and the row lock type (if any) to acquire.
+ <literal>rowid</literal> identifies the tuple to be fetched.
+ <literal>slot</literal> contains nothing useful upon call, but can be used to
+ hold the returned tuple. <literal>updated</literal> is an output parameter.
+ </para>
+
+ <para>
+ This function should store the tuple into the provided slot, or clear it if
+ the row lock couldn't be obtained. The row lock type to acquire is
+ defined by <literal>erm-&gt;markType</literal>, which is the value
+ previously returned by <function>GetForeignRowMarkType</function>.
+ (<literal>ROW_MARK_REFERENCE</literal> means to just re-fetch the tuple
+ without acquiring any lock, and <literal>ROW_MARK_COPY</literal> will
+ never be seen by this routine.)
+ </para>
+
+ <para>
+ In addition, <literal>*updated</literal> should be set to <literal>true</literal>
+ if what was fetched was an updated version of the tuple rather than
+ the same version previously obtained. (If the FDW cannot be sure about
+ this, always returning <literal>true</literal> is recommended.)
+ </para>
+
+ <para>
+ Note that by default, failure to acquire a row lock should result in
+ raising an error; returning with an empty slot is only appropriate if
+ the <literal>SKIP LOCKED</literal> option is specified
+ by <literal>erm-&gt;waitPolicy</literal>.
+ </para>
+
+ <para>
+ The <literal>rowid</literal> is the <structfield>ctid</structfield> value previously read
+ for the row to be re-fetched. Although the <literal>rowid</literal> value is
+ passed as a <type>Datum</type>, it can currently only be a <type>tid</type>. The
+ function API is chosen in hopes that it may be possible to allow other
+ data types for row IDs in future.
+ </para>
+
+ <para>
+ If the <function>RefetchForeignRow</function> pointer is set to
+ <literal>NULL</literal>, attempts to re-fetch rows will fail
+ with an error message.
+ </para>
+
+ <para>
+ See <xref linkend="fdw-row-locking"/> for more information.
+ </para>
+
+ <para>
+<programlisting>
+bool
+RecheckForeignScan(ForeignScanState *node,
+ TupleTableSlot *slot);
+</programlisting>
+ Recheck that a previously-returned tuple still matches the relevant
+ scan and join qualifiers, and possibly provide a modified version of
+ the tuple. For foreign data wrappers which do not perform join pushdown,
+ it will typically be more convenient to set this to <literal>NULL</literal> and
+ instead set <structfield>fdw_recheck_quals</structfield> appropriately.
+ When outer joins are pushed down, however, it isn't sufficient to
+ reapply the checks relevant to all the base tables to the result tuple,
+ even if all needed attributes are present, because failure to match some
+ qualifier might result in some attributes going to NULL, rather than in
+ no tuple being returned. <literal>RecheckForeignScan</literal> can recheck
+ qualifiers and return true if they are still satisfied and false
+ otherwise, but it can also store a replacement tuple into the supplied
+ slot.
+ </para>
+
+ <para>
+ To implement join pushdown, a foreign data wrapper will typically
+ construct an alternative local join plan which is used only for
+ rechecks; this will become the outer subplan of the
+ <literal>ForeignScan</literal>. When a recheck is required, this subplan
+ can be executed and the resulting tuple can be stored in the slot.
+ This plan need not be efficient since no base table will return more
+ than one row; for example, it may implement all joins as nested loops.
+ The function <literal>GetExistingLocalJoinPath</literal> may be used to search
+ existing paths for a suitable local join path, which can be used as the
+ alternative local join plan. <literal>GetExistingLocalJoinPath</literal>
+ searches for an unparameterized path in the path list of the specified
+ join relation. (If it does not find such a path, it returns NULL, in
+ which case a foreign data wrapper may build the local path by itself or
+ may choose not to create access paths for that join.)
+ </para>
+ </sect2>
+
+ <sect2 id="fdw-callbacks-explain">
+ <title>FDW Routines for <command>EXPLAIN</command></title>
+
+ <para>
+<programlisting>
+void
+ExplainForeignScan(ForeignScanState *node,
+ ExplainState *es);
+</programlisting>
+
+ Print additional <command>EXPLAIN</command> output for a foreign table scan.
+ This function can call <function>ExplainPropertyText</function> and
+ related functions to add fields to the <command>EXPLAIN</command> output.
+ The flag fields in <literal>es</literal> can be used to determine what to
+ print, and the state of the <structname>ForeignScanState</structname> node
+ can be inspected to provide run-time statistics in the <command>EXPLAIN
+ ANALYZE</command> case.
+ </para>
+
+ <para>
+ If the <function>ExplainForeignScan</function> pointer is set to
+ <literal>NULL</literal>, no additional information is printed during
+ <command>EXPLAIN</command>.
+ </para>
+
+ <para>
+<programlisting>
+void
+ExplainForeignModify(ModifyTableState *mtstate,
+ ResultRelInfo *rinfo,
+ List *fdw_private,
+ int subplan_index,
+ struct ExplainState *es);
+</programlisting>
+
+ Print additional <command>EXPLAIN</command> output for a foreign table update.
+ This function can call <function>ExplainPropertyText</function> and
+ related functions to add fields to the <command>EXPLAIN</command> output.
+ The flag fields in <literal>es</literal> can be used to determine what to
+ print, and the state of the <structname>ModifyTableState</structname> node
+ can be inspected to provide run-time statistics in the <command>EXPLAIN
+ ANALYZE</command> case. The first four arguments are the same as for
+ <function>BeginForeignModify</function>.
+ </para>
+
+ <para>
+ If the <function>ExplainForeignModify</function> pointer is set to
+ <literal>NULL</literal>, no additional information is printed during
+ <command>EXPLAIN</command>.
+ </para>
+
+ <para>
+<programlisting>
+void
+ExplainDirectModify(ForeignScanState *node,
+ ExplainState *es);
+</programlisting>
+
+ Print additional <command>EXPLAIN</command> output for a direct modification
+ on the remote server.
+ This function can call <function>ExplainPropertyText</function> and
+ related functions to add fields to the <command>EXPLAIN</command> output.
+ The flag fields in <literal>es</literal> can be used to determine what to
+ print, and the state of the <structname>ForeignScanState</structname> node
+ can be inspected to provide run-time statistics in the <command>EXPLAIN
+ ANALYZE</command> case.
+ </para>
+
+ <para>
+ If the <function>ExplainDirectModify</function> pointer is set to
+ <literal>NULL</literal>, no additional information is printed during
+ <command>EXPLAIN</command>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="fdw-callbacks-analyze">
+ <title>FDW Routines for <command>ANALYZE</command></title>
+
+ <para>
+<programlisting>
+bool
+AnalyzeForeignTable(Relation relation,
+ AcquireSampleRowsFunc *func,
+ BlockNumber *totalpages);
+</programlisting>
+
+ This function is called when <xref linkend="sql-analyze"/> is executed on
+ a foreign table. If the FDW can collect statistics for this
+ foreign table, it should return <literal>true</literal>, and provide a pointer
+ to a function that will collect sample rows from the table in
+ <parameter>func</parameter>, plus the estimated size of the table in pages in
+ <parameter>totalpages</parameter>. Otherwise, return <literal>false</literal>.
+ </para>
+
+ <para>
+ If the FDW does not support collecting statistics for any tables, the
+ <function>AnalyzeForeignTable</function> pointer can be set to <literal>NULL</literal>.
+ </para>
+
+ <para>
+ If provided, the sample collection function must have the signature
+<programlisting>
+int
+AcquireSampleRowsFunc(Relation relation,
+ int elevel,
+ HeapTuple *rows,
+ int targrows,
+ double *totalrows,
+ double *totaldeadrows);
+</programlisting>
+
+ A random sample of up to <parameter>targrows</parameter> rows should be collected
+ from the table and stored into the caller-provided <parameter>rows</parameter>
+ array. The actual number of rows collected must be returned. In
+ addition, store estimates of the total numbers of live and dead rows in
+ the table into the output parameters <parameter>totalrows</parameter> and
+ <parameter>totaldeadrows</parameter>. (Set <parameter>totaldeadrows</parameter> to zero
+ if the FDW does not have any concept of dead rows.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="fdw-callbacks-import">
+ <title>FDW Routines for <command>IMPORT FOREIGN SCHEMA</command></title>
+
+ <para>
+<programlisting>
+List *
+ImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid);
+</programlisting>
+
+ Obtain a list of foreign table creation commands. This function is
+ called when executing <xref linkend="sql-importforeignschema"/>, and is
+ passed the parse tree for that statement, as well as the OID of the
+ foreign server to use. It should return a list of C strings, each of
+ which must contain a <xref linkend="sql-createforeigntable"/> command.
+ These strings will be parsed and executed by the core server.
+ </para>
+
+ <para>
+ Within the <structname>ImportForeignSchemaStmt</structname> struct,
+ <structfield>remote_schema</structfield> is the name of the remote schema from
+ which tables are to be imported.
+ <structfield>list_type</structfield> identifies how to filter table names:
+ <literal>FDW_IMPORT_SCHEMA_ALL</literal> means that all tables in the remote
+ schema should be imported (in this case <structfield>table_list</structfield> is
+ empty), <literal>FDW_IMPORT_SCHEMA_LIMIT_TO</literal> means to include only
+ tables listed in <structfield>table_list</structfield>,
+ and <literal>FDW_IMPORT_SCHEMA_EXCEPT</literal> means to exclude the tables
+ listed in <structfield>table_list</structfield>.
+ <structfield>options</structfield> is a list of options used for the import process.
+ The meanings of the options are up to the FDW.
+ For example, an FDW could use an option to define whether the
+ <literal>NOT NULL</literal> attributes of columns should be imported.
+ These options need not have anything to do with those supported by the
+ FDW as database object options.
+ </para>
+
+ <para>
+ The FDW may ignore the <structfield>local_schema</structfield> field of
+ the <structname>ImportForeignSchemaStmt</structname>, because the core server
+ will automatically insert that name into the parsed <command>CREATE
+ FOREIGN TABLE</command> commands.
+ </para>
+
+ <para>
+ The FDW does not have to concern itself with implementing the filtering
+ specified by <structfield>list_type</structfield> and <structfield>table_list</structfield>,
+ either, as the core server will automatically skip any returned commands
+ for tables excluded according to those options. However, it's often
+ useful to avoid the work of creating commands for excluded tables in the
+ first place. The function <function>IsImportableForeignTable()</function> may be
+ useful to test whether a given foreign-table name will pass the filter.
+ </para>
+
+ <para>
+ If the FDW does not support importing table definitions, the
+ <function>ImportForeignSchema</function> pointer can be set to <literal>NULL</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="fdw-callbacks-parallel">
+ <title>FDW Routines for Parallel Execution</title>
+ <para>
+ A <structname>ForeignScan</structname> node can, optionally, support parallel
+ execution. A parallel <structname>ForeignScan</structname> will be executed
+ in multiple processes and must return each row exactly once across
+ all cooperating processes. To do this, processes can coordinate through
+ fixed-size chunks of dynamic shared memory. This shared memory is not
+ guaranteed to be mapped at the same address in every process, so it
+ must not contain pointers. The following functions are all optional,
+ but most are required if parallel execution is to be supported.
+ </para>
+
+ <para>
+<programlisting>
+bool
+IsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
+ RangeTblEntry *rte);
+</programlisting>
+ Test whether a scan can be performed within a parallel worker. This
+ function will only be called when the planner believes that a parallel
+ plan might be possible, and should return true if it is safe for that scan
+ to run within a parallel worker. This will generally not be the case if
+ the remote data source has transaction semantics, unless the worker's
+ connection to the data can somehow be made to share the same transaction
+ context as the leader.
+ </para>
+
+ <para>
+ If this function is not defined, it is assumed that the scan must take
+ place within the parallel leader. Note that returning true does not mean
+ that the scan itself can be done in parallel, only that the scan can be
+ performed within a parallel worker. Therefore, it can be useful to define
+ this method even when parallel execution is not supported.
+ </para>
+
+ <para>
+<programlisting>
+Size
+EstimateDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt);
+</programlisting>
+ Estimate the amount of dynamic shared memory that will be required
+ for parallel operation. This may be higher than the amount that will
+ actually be used, but it must not be lower. The return value is in bytes.
+ This function is optional, and can be omitted if not needed; but if it
+ is omitted, the next three functions must be omitted as well, because
+ no shared memory will be allocated for the FDW's use.
+ </para>
+
+ <para>
+<programlisting>
+void
+InitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
+ void *coordinate);
+</programlisting>
+ Initialize the dynamic shared memory that will be required for parallel
+ operation. <literal>coordinate</literal> points to a shared memory area of
+ size equal to the return value of <function>EstimateDSMForeignScan</function>.
+ This function is optional, and can be omitted if not needed.
+ </para>
+
+ <para>
+<programlisting>
+void
+ReInitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
+ void *coordinate);
+</programlisting>
+ Re-initialize the dynamic shared memory required for parallel operation
+ when the foreign-scan plan node is about to be re-scanned.
+ This function is optional, and can be omitted if not needed.
+ Recommended practice is that this function reset only shared state,
+ while the <function>ReScanForeignScan</function> function resets only local
+ state. Currently, this function will be called
+ before <function>ReScanForeignScan</function>, but it's best not to rely on
+ that ordering.
+ </para>
+
+ <para>
+<programlisting>
+void
+InitializeWorkerForeignScan(ForeignScanState *node, shm_toc *toc,
+ void *coordinate);
+</programlisting>
+ Initialize a parallel worker's local state based on the shared state
+ set up by the leader during <function>InitializeDSMForeignScan</function>.
+ This function is optional, and can be omitted if not needed.
+ </para>
+
+ <para>
+<programlisting>
+void
+ShutdownForeignScan(ForeignScanState *node);
+</programlisting>
+ Release resources when it is anticipated the node will not be executed
+ to completion. This is not called in all cases; sometimes,
+ <literal>EndForeignScan</literal> may be called without this function having
+ been called first. Since the DSM segment used by parallel query is
+ destroyed just after this callback is invoked, foreign data wrappers that
+ wish to take some action before the DSM segment goes away should implement
+ this method.
+ </para>
+ </sect2>
+
+ <sect2 id="fdw-callbacks-async">
+ <title>FDW Routines for Asynchronous Execution</title>
+ <para>
+ A <structname>ForeignScan</structname> node can, optionally, support
+ asynchronous execution as described in
+ <filename>src/backend/executor/README</filename>. The following
+ functions are all optional, but are all required if asynchronous
+ execution is to be supported.
+ </para>
+
+ <para>
+<programlisting>
+bool
+IsForeignPathAsyncCapable(ForeignPath *path);
+</programlisting>
+ Test whether a given <structname>ForeignPath</structname> path can scan
+ the underlying foreign relation asynchronously.
+ This function will only be called at the end of query planning when the
+ given path is a direct child of an <structname>AppendPath</structname>
+ path and when the planner believes that asynchronous execution improves
+ performance, and should return true if the given path is able to scan the
+ foreign relation asynchronously.
+ </para>
+
+ <para>
+ If this function is not defined, it is assumed that the given path scans
+ the foreign relation using <function>IterateForeignScan</function>.
+ (This implies that the callback functions described below will never be
+ called, so they need not be provided either.)
+ </para>
+
+ <para>
+<programlisting>
+void
+ForeignAsyncRequest(AsyncRequest *areq);
+</programlisting>
+ Produce one tuple asynchronously from the
+ <structname>ForeignScan</structname> node. <literal>areq</literal> is
+ the <structname>AsyncRequest</structname> struct describing the
+ <structname>ForeignScan</structname> node and the parent
+ <structname>Append</structname> node that requested the tuple from it.
+ This function should store the tuple into the slot specified by
+ <literal>areq-&gt;result</literal>, and set
+ <literal>areq-&gt;request_complete</literal> to <literal>true</literal>;
+ or if it needs to wait on an event external to the core server such as
+ network I/O, and cannot produce any tuple immediately, set the flag to
+ <literal>false</literal>, and set
+ <literal>areq-&gt;callback_pending</literal> to <literal>true</literal>
+ for the <structname>ForeignScan</structname> node to get a callback from
+ the callback functions described below. If no more tuples are available,
+ set the slot to NULL or an empty slot, and the
+ <literal>areq-&gt;request_complete</literal> flag to
+ <literal>true</literal>. It's recommended to use
+ <function>ExecAsyncRequestDone</function> or
+ <function>ExecAsyncRequestPending</function> to set the output parameters
+ in the <literal>areq</literal>.
+ </para>
+
+ <para>
+<programlisting>
+void
+ForeignAsyncConfigureWait(AsyncRequest *areq);
+</programlisting>
+ Configure a file descriptor event for which the
+ <structname>ForeignScan</structname> node wishes to wait.
+ This function will only be called when the
+ <structname>ForeignScan</structname> node has the
+ <literal>areq-&gt;callback_pending</literal> flag set, and should add
+ the event to the <structfield>as_eventset</structfield> of the parent
+ <structname>Append</structname> node described by the
+ <literal>areq</literal>. See the comments for
+ <function>ExecAsyncConfigureWait</function> in
+ <filename>src/backend/executor/execAsync.c</filename> for additional
+ information. When the file descriptor event occurs,
+ <function>ForeignAsyncNotify</function> will be called.
+ </para>
+
+ <para>
+<programlisting>
+void
+ForeignAsyncNotify(AsyncRequest *areq);
+</programlisting>
+ Process a relevant event that has occurred, then produce one tuple
+ asynchronously from the <structname>ForeignScan</structname> node.
+ This function should set the output parameters in the
+ <literal>areq</literal> in the same way as
+ <function>ForeignAsyncRequest</function>.
+ </para>
+ </sect2>
+
+ <sect2 id="fdw-callbacks-reparameterize-paths">
+ <title>FDW Routines for Reparameterization of Paths</title>
+
+ <para>
+<programlisting>
+List *
+ReparameterizeForeignPathByChild(PlannerInfo *root, List *fdw_private,
+ RelOptInfo *child_rel);
+</programlisting>
+ This function is called while converting a path parameterized by the
+ top-most parent of the given child relation <literal>child_rel</literal> to be
+ parameterized by the child relation. The function is used to reparameterize
+ any paths or translate any expression nodes saved in the given
+ <literal>fdw_private</literal> member of a <structname>ForeignPath</structname>. The
+ callback may use <literal>reparameterize_path_by_child</literal>,
+ <literal>adjust_appendrel_attrs</literal> or
+ <literal>adjust_appendrel_attrs_multilevel</literal> as required.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="fdw-helpers">
+ <title>Foreign Data Wrapper Helper Functions</title>
+
+ <para>
+ Several helper functions are exported from the core server so that
+ authors of foreign data wrappers can get easy access to attributes of
+ FDW-related objects, such as FDW options.
+ To use any of these functions, you need to include the header file
+ <filename>foreign/foreign.h</filename> in your source file.
+ That header also defines the struct types that are returned by
+ these functions.
+ </para>
+
+ <para>
+<programlisting>
+ForeignDataWrapper *
+GetForeignDataWrapperExtended(Oid fdwid, bits16 flags);
+</programlisting>
+
+ This function returns a <structname>ForeignDataWrapper</structname>
+ object for the foreign-data wrapper with the given OID. A
+ <structname>ForeignDataWrapper</structname> object contains properties
+ of the FDW (see <filename>foreign/foreign.h</filename> for details).
+ <structfield>flags</structfield> is a bitwise-or'd bit mask indicating
+ an extra set of options. It can take the value
+ <literal>FDW_MISSING_OK</literal>, in which case a <literal>NULL</literal>
+ result is returned to the caller instead of an error for an undefined
+ object.
+ </para>
+
+ <para>
+<programlisting>
+ForeignDataWrapper *
+GetForeignDataWrapper(Oid fdwid);
+</programlisting>
+
+ This function returns a <structname>ForeignDataWrapper</structname>
+ object for the foreign-data wrapper with the given OID. A
+ <structname>ForeignDataWrapper</structname> object contains properties
+ of the FDW (see <filename>foreign/foreign.h</filename> for details).
+ </para>
+
+ <para>
+<programlisting>
+ForeignServer *
+GetForeignServerExtended(Oid serverid, bits16 flags);
+</programlisting>
+
+ This function returns a <structname>ForeignServer</structname> object
+ for the foreign server with the given OID. A
+ <structname>ForeignServer</structname> object contains properties
+ of the server (see <filename>foreign/foreign.h</filename> for details).
+ <structfield>flags</structfield> is a bitwise-or'd bit mask indicating
+ an extra set of options. It can take the value
+ <literal>FSV_MISSING_OK</literal>, in which case a <literal>NULL</literal>
+ result is returned to the caller instead of an error for an undefined
+ object.
+ </para>
+
+ <para>
+<programlisting>
+ForeignServer *
+GetForeignServer(Oid serverid);
+</programlisting>
+
+ This function returns a <structname>ForeignServer</structname> object
+ for the foreign server with the given OID. A
+ <structname>ForeignServer</structname> object contains properties
+ of the server (see <filename>foreign/foreign.h</filename> for details).
+ </para>
+
+ <para>
+<programlisting>
+UserMapping *
+GetUserMapping(Oid userid, Oid serverid);
+</programlisting>
+
+ This function returns a <structname>UserMapping</structname> object for
+ the user mapping of the given role on the given server. (If there is no
+ mapping for the specific user, it will return the mapping for
+ <literal>PUBLIC</literal>, or throw error if there is none.) A
+ <structname>UserMapping</structname> object contains properties of the
+ user mapping (see <filename>foreign/foreign.h</filename> for details).
+ </para>
+
+ <para>
+<programlisting>
+ForeignTable *
+GetForeignTable(Oid relid);
+</programlisting>
+
+ This function returns a <structname>ForeignTable</structname> object for
+ the foreign table with the given OID. A
+ <structname>ForeignTable</structname> object contains properties of the
+ foreign table (see <filename>foreign/foreign.h</filename> for details).
+ </para>
+
+ <para>
+<programlisting>
+List *
+GetForeignColumnOptions(Oid relid, AttrNumber attnum);
+</programlisting>
+
+ This function returns the per-column FDW options for the column with the
+ given foreign table OID and attribute number, in the form of a list of
+ <structname>DefElem</structname>. NIL is returned if the column has no
+ options.
+ </para>
+
+ <para>
+ Some object types have name-based lookup functions in addition to the
+ OID-based ones:
+ </para>
+
+ <para>
+<programlisting>
+ForeignDataWrapper *
+GetForeignDataWrapperByName(const char *name, bool missing_ok);
+</programlisting>
+
+ This function returns a <structname>ForeignDataWrapper</structname>
+ object for the foreign-data wrapper with the given name. If the wrapper
+ is not found, return NULL if missing_ok is true, otherwise raise an
+ error.
+ </para>
+
+ <para>
+<programlisting>
+ForeignServer *
+GetForeignServerByName(const char *name, bool missing_ok);
+</programlisting>
+
+ This function returns a <structname>ForeignServer</structname> object
+ for the foreign server with the given name. If the server is not found,
+ return NULL if missing_ok is true, otherwise raise an error.
+ </para>
+
+ </sect1>
+
+ <sect1 id="fdw-planning">
+ <title>Foreign Data Wrapper Query Planning</title>
+
+ <para>
+ The FDW callback functions <function>GetForeignRelSize</function>,
+ <function>GetForeignPaths</function>, <function>GetForeignPlan</function>,
+ <function>PlanForeignModify</function>, <function>GetForeignJoinPaths</function>,
+ <function>GetForeignUpperPaths</function>, and <function>PlanDirectModify</function>
+ must fit into the workings of the <productname>PostgreSQL</productname> planner.
+ Here are some notes about what they must do.
+ </para>
+
+ <para>
+ The information in <literal>root</literal> and <literal>baserel</literal> can be used
+ to reduce the amount of information that has to be fetched from the
+ foreign table (and therefore reduce the cost).
+ <literal>baserel-&gt;baserestrictinfo</literal> is particularly interesting, as
+ it contains restriction quals (<literal>WHERE</literal> clauses) that should be
+ used to filter the rows to be fetched. (The FDW itself is not required
+ to enforce these quals, as the core executor can check them instead.)
+ <literal>baserel-&gt;reltarget-&gt;exprs</literal> can be used to determine which
+ columns need to be fetched; but note that it only lists columns that
+ have to be emitted by the <structname>ForeignScan</structname> plan node, not
+ columns that are used in qual evaluation but not output by the query.
+ </para>
+
+ <para>
+ Various private fields are available for the FDW planning functions to
+ keep information in. Generally, whatever you store in FDW private fields
+ should be palloc'd, so that it will be reclaimed at the end of planning.
+ </para>
+
+ <para>
+ <literal>baserel-&gt;fdw_private</literal> is a <type>void</type> pointer that is
+ available for FDW planning functions to store information relevant to
+ the particular foreign table. The core planner does not touch it except
+ to initialize it to NULL when the <literal>RelOptInfo</literal> node is created.
+ It is useful for passing information forward from
+ <function>GetForeignRelSize</function> to <function>GetForeignPaths</function> and/or
+ <function>GetForeignPaths</function> to <function>GetForeignPlan</function>, thereby
+ avoiding recalculation.
+ </para>
+
+ <para>
+ <function>GetForeignPaths</function> can identify the meaning of different
+ access paths by storing private information in the
+ <structfield>fdw_private</structfield> field of <structname>ForeignPath</structname> nodes.
+ <structfield>fdw_private</structfield> is declared as a <type>List</type> pointer, but
+ could actually contain anything since the core planner does not touch
+ it. However, best practice is to use a representation that's dumpable
+ by <function>nodeToString</function>, for use with debugging support available
+ in the backend.
+ </para>
+
+ <para>
+ <function>GetForeignPlan</function> can examine the <structfield>fdw_private</structfield>
+ field of the selected <structname>ForeignPath</structname> node, and can generate
+ <structfield>fdw_exprs</structfield> and <structfield>fdw_private</structfield> lists to be
+ placed in the <structname>ForeignScan</structname> plan node, where they will be
+ available at execution time. Both of these lists must be
+ represented in a form that <function>copyObject</function> knows how to copy.
+ The <structfield>fdw_private</structfield> list has no other restrictions and is
+ not interpreted by the core backend in any way. The
+ <structfield>fdw_exprs</structfield> list, if not NIL, is expected to contain
+ expression trees that are intended to be executed at run time. These
+ trees will undergo post-processing by the planner to make them fully
+ executable.
+ </para>
+
+ <para>
+ In <function>GetForeignPlan</function>, generally the passed-in target list can
+ be copied into the plan node as-is. The passed <literal>scan_clauses</literal> list
+ contains the same clauses as <literal>baserel-&gt;baserestrictinfo</literal>,
+ but may be re-ordered for better execution efficiency. In simple cases
+ the FDW can just strip <structname>RestrictInfo</structname> nodes from the
+ <literal>scan_clauses</literal> list (using <function>extract_actual_clauses</function>) and put
+ all the clauses into the plan node's qual list, which means that all the
+ clauses will be checked by the executor at run time. More complex FDWs
+ may be able to check some of the clauses internally, in which case those
+ clauses can be removed from the plan node's qual list so that the
+ executor doesn't waste time rechecking them.
+ </para>
+
+ <para>
+ As an example, the FDW might identify some restriction clauses of the
+ form <replaceable>foreign_variable</replaceable> <literal>=</literal>
+ <replaceable>sub_expression</replaceable>, which it determines can be executed on
+ the remote server given the locally-evaluated value of the
+ <replaceable>sub_expression</replaceable>. The actual identification of such a
+ clause should happen during <function>GetForeignPaths</function>, since it would
+ affect the cost estimate for the path. The path's
+ <structfield>fdw_private</structfield> field would probably include a pointer to
+ the identified clause's <structname>RestrictInfo</structname> node. Then
+ <function>GetForeignPlan</function> would remove that clause from <literal>scan_clauses</literal>,
+ but add the <replaceable>sub_expression</replaceable> to <structfield>fdw_exprs</structfield>
+ to ensure that it gets massaged into executable form. It would probably
+ also put control information into the plan node's
+ <structfield>fdw_private</structfield> field to tell the execution functions what
+ to do at run time. The query transmitted to the remote server would
+ involve something like <literal>WHERE <replaceable>foreign_variable</replaceable> =
+ $1</literal>, with the parameter value obtained at run time from
+ evaluation of the <structfield>fdw_exprs</structfield> expression tree.
+ </para>
+
+ <para>
+ Any clauses removed from the plan node's qual list must instead be added
+ to <literal>fdw_recheck_quals</literal> or rechecked by
+ <literal>RecheckForeignScan</literal> in order to ensure correct behavior
+ at the <literal>READ COMMITTED</literal> isolation level. When a concurrent
+ update occurs for some other table involved in the query, the executor
+ may need to verify that all of the original quals are still satisfied for
+ the tuple, possibly against a different set of parameter values. Using
+ <literal>fdw_recheck_quals</literal> is typically easier than implementing checks
+ inside <literal>RecheckForeignScan</literal>, but this method will be
+ insufficient when outer joins have been pushed down, since the join tuples
+ in that case might have some fields go to NULL without rejecting the
+ tuple entirely.
+ </para>
+
+ <para>
+ Another <structname>ForeignScan</structname> field that can be filled by FDWs
+ is <structfield>fdw_scan_tlist</structfield>, which describes the tuples returned by
+ the FDW for this plan node. For simple foreign table scans this can be
+ set to <literal>NIL</literal>, implying that the returned tuples have the
+ row type declared for the foreign table. A non-<symbol>NIL</symbol> value must be a
+ target list (list of <structname>TargetEntry</structname>s) containing Vars and/or
+ expressions representing the returned columns. This might be used, for
+ example, to show that the FDW has omitted some columns that it noticed
+ won't be needed for the query. Also, if the FDW can compute expressions
+ used by the query more cheaply than can be done locally, it could add
+ those expressions to <structfield>fdw_scan_tlist</structfield>. Note that join
+ plans (created from paths made by <function>GetForeignJoinPaths</function>) must
+ always supply <structfield>fdw_scan_tlist</structfield> to describe the set of
+ columns they will return.
+ </para>
+
+ <para>
+ The FDW should always construct at least one path that depends only on
+ the table's restriction clauses. In join queries, it might also choose
+ to construct path(s) that depend on join clauses, for example
+ <replaceable>foreign_variable</replaceable> <literal>=</literal>
+ <replaceable>local_variable</replaceable>. Such clauses will not be found in
+ <literal>baserel-&gt;baserestrictinfo</literal> but must be sought in the
+ relation's join lists. A path using such a clause is called a
+ <quote>parameterized path</quote>. It must identify the other relations
+ used in the selected join clause(s) with a suitable value of
+ <literal>param_info</literal>; use <function>get_baserel_parampathinfo</function>
+ to compute that value. In <function>GetForeignPlan</function>, the
+ <replaceable>local_variable</replaceable> portion of the join clause would be added
+ to <structfield>fdw_exprs</structfield>, and then at run time the case works the
+ same as for an ordinary restriction clause.
+ </para>
+
+ <para>
+ If an FDW supports remote joins, <function>GetForeignJoinPaths</function> should
+ produce <structname>ForeignPath</structname>s for potential remote joins in much
+ the same way as <function>GetForeignPaths</function> works for base tables.
+ Information about the intended join can be passed forward
+ to <function>GetForeignPlan</function> in the same ways described above.
+ However, <structfield>baserestrictinfo</structfield> is not relevant for join
+ relations; instead, the relevant join clauses for a particular join are
+ passed to <function>GetForeignJoinPaths</function> as a separate parameter
+ (<literal>extra-&gt;restrictlist</literal>).
+ </para>
+
+ <para>
+ An FDW might additionally support direct execution of some plan actions
+ that are above the level of scans and joins, such as grouping or
+ aggregation. To offer such options, the FDW should generate paths and
+ insert them into the appropriate <firstterm>upper relation</firstterm>. For
+ example, a path representing remote aggregation should be inserted into
+ the <literal>UPPERREL_GROUP_AGG</literal> relation, using <function>add_path</function>.
+ This path will be compared on a cost basis with local aggregation
+ performed by reading a simple scan path for the foreign relation (note
+ that such a path must also be supplied, else there will be an error at
+ plan time). If the remote-aggregation path wins, which it usually would,
+ it will be converted into a plan in the usual way, by
+ calling <function>GetForeignPlan</function>. The recommended place to generate
+ such paths is in the <function>GetForeignUpperPaths</function>
+ callback function, which is called for each upper relation (i.e., each
+ post-scan/join processing step), if all the base relations of the query
+ come from the same FDW.
+ </para>
+
+ <para>
+ <function>PlanForeignModify</function> and the other callbacks described in
+ <xref linkend="fdw-callbacks-update"/> are designed around the assumption
+ that the foreign relation will be scanned in the usual way and then
+ individual row updates will be driven by a local <literal>ModifyTable</literal>
+ plan node. This approach is necessary for the general case where an
+ update requires reading local tables as well as foreign tables.
+ However, if the operation could be executed entirely by the foreign
+ server, the FDW could generate a path representing that and insert it
+ into the <literal>UPPERREL_FINAL</literal> upper relation, where it would
+ compete against the <literal>ModifyTable</literal> approach. This approach
+ could also be used to implement remote <literal>SELECT FOR UPDATE</literal>,
+ rather than using the row locking callbacks described in
+ <xref linkend="fdw-callbacks-row-locking"/>. Keep in mind that a path
+ inserted into <literal>UPPERREL_FINAL</literal> is responsible for
+ implementing <emphasis>all</emphasis> behavior of the query.
+ </para>
+
+ <para>
+ When planning an <command>UPDATE</command> or <command>DELETE</command>,
+ <function>PlanForeignModify</function> and <function>PlanDirectModify</function>
+ can look up the <structname>RelOptInfo</structname>
+ struct for the foreign table and make use of the
+ <literal>baserel-&gt;fdw_private</literal> data previously created by the
+ scan-planning functions. However, in <command>INSERT</command> the target
+ table is not scanned so there is no <structname>RelOptInfo</structname> for it.
+ The <structname>List</structname> returned by <function>PlanForeignModify</function> has
+ the same restrictions as the <structfield>fdw_private</structfield> list of a
+ <structname>ForeignScan</structname> plan node, that is it must contain only
+ structures that <function>copyObject</function> knows how to copy.
+ </para>
+
+ <para>
+ <command>INSERT</command> with an <literal>ON CONFLICT</literal> clause does not
+ support specifying the conflict target, as unique constraints or
+ exclusion constraints on remote tables are not locally known. This
+ in turn implies that <literal>ON CONFLICT DO UPDATE</literal> is not supported,
+ since the specification is mandatory there.
+ </para>
+
+ </sect1>
+
+ <sect1 id="fdw-row-locking">
+ <title>Row Locking in Foreign Data Wrappers</title>
+
+ <para>
+ If an FDW's underlying storage mechanism has a concept of locking
+ individual rows to prevent concurrent updates of those rows, it is
+ usually worthwhile for the FDW to perform row-level locking with as
+ close an approximation as practical to the semantics used in
+ ordinary <productname>PostgreSQL</productname> tables. There are multiple
+ considerations involved in this.
+ </para>
+
+ <para>
+ One key decision to be made is whether to perform <firstterm>early
+ locking</firstterm> or <firstterm>late locking</firstterm>. In early locking, a row is
+ locked when it is first retrieved from the underlying store, while in
+ late locking, the row is locked only when it is known that it needs to
+ be locked. (The difference arises because some rows may be discarded by
+ locally-checked restriction or join conditions.) Early locking is much
+ simpler and avoids extra round trips to a remote store, but it can cause
+ locking of rows that need not have been locked, resulting in reduced
+ concurrency or even unexpected deadlocks. Also, late locking is only
+ possible if the row to be locked can be uniquely re-identified later.
+ Preferably the row identifier should identify a specific version of the
+ row, as <productname>PostgreSQL</productname> TIDs do.
+ </para>
+
+ <para>
+ By default, <productname>PostgreSQL</productname> ignores locking considerations
+ when interfacing to FDWs, but an FDW can perform early locking without
+ any explicit support from the core code. The API functions described
+ in <xref linkend="fdw-callbacks-row-locking"/>, which were added
+ in <productname>PostgreSQL</productname> 9.5, allow an FDW to use late locking if
+ it wishes.
+ </para>
+
+ <para>
+ An additional consideration is that in <literal>READ COMMITTED</literal>
+ isolation mode, <productname>PostgreSQL</productname> may need to re-check
+ restriction and join conditions against an updated version of some
+ target tuple. Rechecking join conditions requires re-obtaining copies
+ of the non-target rows that were previously joined to the target tuple.
+ When working with standard <productname>PostgreSQL</productname> tables, this is
+ done by including the TIDs of the non-target tables in the column list
+ projected through the join, and then re-fetching non-target rows when
+ required. This approach keeps the join data set compact, but it
+ requires inexpensive re-fetch capability, as well as a TID that can
+ uniquely identify the row version to be re-fetched. By default,
+ therefore, the approach used with foreign tables is to include a copy of
+ the entire row fetched from a foreign table in the column list projected
+ through the join. This puts no special demands on the FDW but can
+ result in reduced performance of merge and hash joins. An FDW that is
+ capable of meeting the re-fetch requirements can choose to do it the
+ first way.
+ </para>
+
+ <para>
+ For an <command>UPDATE</command> or <command>DELETE</command> on a foreign table, it
+ is recommended that the <literal>ForeignScan</literal> operation on the target
+ table perform early locking on the rows that it fetches, perhaps via the
+ equivalent of <command>SELECT FOR UPDATE</command>. An FDW can detect whether
+ a table is an <command>UPDATE</command>/<command>DELETE</command> target at plan time
+ by comparing its relid to <literal>root-&gt;parse-&gt;resultRelation</literal>,
+ or at execution time by using <function>ExecRelationIsTargetRelation()</function>.
+ An alternative possibility is to perform late locking within the
+ <function>ExecForeignUpdate</function> or <function>ExecForeignDelete</function>
+ callback, but no special support is provided for this.
+ </para>
+
+ <para>
+ For foreign tables that are specified to be locked by a <command>SELECT
+ FOR UPDATE/SHARE</command> command, the <literal>ForeignScan</literal> operation can
+ again perform early locking by fetching tuples with the equivalent
+ of <command>SELECT FOR UPDATE/SHARE</command>. To perform late locking
+ instead, provide the callback functions defined
+ in <xref linkend="fdw-callbacks-row-locking"/>.
+ In <function>GetForeignRowMarkType</function>, select rowmark option
+ <literal>ROW_MARK_EXCLUSIVE</literal>, <literal>ROW_MARK_NOKEYEXCLUSIVE</literal>,
+ <literal>ROW_MARK_SHARE</literal>, or <literal>ROW_MARK_KEYSHARE</literal> depending
+ on the requested lock strength. (The core code will act the same
+ regardless of which of these four options you choose.)
+ Elsewhere, you can detect whether a foreign table was specified to be
+ locked by this type of command by using <function>get_plan_rowmark</function> at
+ plan time, or <function>ExecFindRowMark</function> at execution time; you must
+ check not only whether a non-null rowmark struct is returned, but that
+ its <structfield>strength</structfield> field is not <literal>LCS_NONE</literal>.
+ </para>
+
+ <para>
+ Lastly, for foreign tables that are used in an <command>UPDATE</command>,
+ <command>DELETE</command> or <command>SELECT FOR UPDATE/SHARE</command> command but
+ are not specified to be row-locked, you can override the default choice
+ to copy entire rows by having <function>GetForeignRowMarkType</function> select
+ option <literal>ROW_MARK_REFERENCE</literal> when it sees lock strength
+ <literal>LCS_NONE</literal>. This will cause <function>RefetchForeignRow</function> to
+ be called with that value for <structfield>markType</structfield>; it should then
+ re-fetch the row without acquiring any new lock. (If you have
+ a <function>GetForeignRowMarkType</function> function but don't wish to re-fetch
+ unlocked rows, select option <literal>ROW_MARK_COPY</literal>
+ for <literal>LCS_NONE</literal>.)
+ </para>
+
+ <para>
+ See <filename>src/include/nodes/lockoptions.h</filename>, the comments
+ for <type>RowMarkType</type> and <type>PlanRowMark</type>
+ in <filename>src/include/nodes/plannodes.h</filename>, and the comments for
+ <type>ExecRowMark</type> in <filename>src/include/nodes/execnodes.h</filename> for
+ additional information.
+ </para>
+
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/features.sgml b/doc/src/sgml/features.sgml
new file mode 100644
index 0000000..05365d8
--- /dev/null
+++ b/doc/src/sgml/features.sgml
@@ -0,0 +1,494 @@
+<!-- doc/src/sgml/features.sgml -->
+
+<appendix id="features">
+ <title>SQL Conformance</title>
+
+ <para>
+ This section attempts to outline to what extent
+ <productname>PostgreSQL</productname> conforms to the current SQL
+ standard. The following information is not a full statement of
+ conformance, but it presents the main topics in as much detail as is
+ both reasonable and useful for users.
+ </para>
+
+ <para>
+ The formal name of the SQL standard is ISO/IEC 9075 <quote>Database
+ Language SQL</quote>. A revised version of the standard is released
+ from time to time; the most recent update appearing in 2016.
+ The 2016 version is referred to as ISO/IEC 9075:2016, or simply as SQL:2016.
+ The versions prior to that were SQL:2011, SQL:2008, SQL:2006, SQL:2003,
+ SQL:1999, and SQL-92. Each version
+ replaces the previous one, so claims of conformance to earlier
+ versions have no official merit.
+ <productname>PostgreSQL</productname> development aims for
+ conformance with the latest official version of the standard where
+ such conformance does not contradict traditional features or common
+ sense. Many of the features required by the SQL
+ standard are supported, though sometimes with slightly differing
+ syntax or function. Further moves towards conformance can be
+ expected over time.
+ </para>
+
+ <para>
+ <acronym>SQL-92</acronym> defined three feature sets for
+ conformance: Entry, Intermediate, and Full. Most database
+ management systems claiming <acronym>SQL</acronym> standard
+ conformance were conforming at only the Entry level, since the
+ entire set of features in the Intermediate and Full levels was
+ either too voluminous or in conflict with legacy behaviors.
+ </para>
+
+ <para>
+ Starting with <acronym>SQL:1999</acronym>, the SQL standard defines
+ a large set of individual features rather than the ineffectively
+ broad three levels found in <acronym>SQL-92</acronym>. A large
+ subset of these features represents the <quote>Core</quote>
+ features, which every conforming SQL implementation must supply.
+ The rest of the features are purely optional.
+ </para>
+
+ <para>
+ The standard versions beginning with <acronym>SQL:2003</acronym>
+ are also split into a number
+ of parts. Each is known by a shorthand name. Note that these parts
+ are not consecutively numbered.
+
+ <itemizedlist>
+ <listitem><para>ISO/IEC 9075-1 Framework (SQL/Framework)</para><indexterm><primary>SQL/Framework</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-2 Foundation (SQL/Foundation)</para><indexterm><primary>SQL/Foundation</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-3 Call Level Interface (SQL/CLI)</para><indexterm><primary>SQL/CLI</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-4 Persistent Stored Modules (SQL/PSM)</para><indexterm><primary>SQL/PSM</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-9 Management of External Data (SQL/MED)</para><indexterm><primary>SQL/MED</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-10 Object Language Bindings (SQL/OLB)</para><indexterm><primary>SQL/OLB</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-11 Information and Definition Schemas (SQL/Schemata)</para><indexterm><primary>SQL/Schemata</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-13 Routines and Types using the Java Language (SQL/JRT)</para><indexterm><primary>SQL/JRT</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-14 XML-related specifications (SQL/XML)</para><indexterm><primary>SQL/XML</primary></indexterm></listitem>
+ <listitem><para>ISO/IEC 9075-15 Multi-dimensional arrays (SQL/MDA)</para><indexterm><primary>SQL/MDA</primary></indexterm></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> core covers parts 1, 2, 9,
+ 11, and 14. Part 3 is covered by the ODBC driver, and part 13 is
+ covered by the PL/Java plug-in, but exact conformance is currently
+ not being verified for these components. There are currently no
+ implementations of parts 4, 10, and 15
+ for <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ PostgreSQL supports most of the major features of SQL:2016. Out of
+ 177 mandatory features required for full Core conformance,
+ PostgreSQL conforms to at least 170. In addition, there is a long
+ list of supported optional features. It might be worth noting that at
+ the time of writing, no current version of any database management
+ system claims full conformance to Core SQL:2016.
+ </para>
+
+ <para>
+ In the following two sections, we provide a list of those features
+ that <productname>PostgreSQL</productname> supports, followed by a
+ list of the features defined in <acronym>SQL:2016</acronym> which
+ are not yet supported in <productname>PostgreSQL</productname>.
+ Both of these lists are approximate: There might be minor details that
+ are nonconforming for a feature that is listed as supported, and
+ large parts of an unsupported feature might in fact be implemented.
+ The main body of the documentation always contains the most accurate
+ information about what does and does not work.
+ </para>
+
+ <note>
+ <para>
+ Feature codes containing a hyphen are subfeatures. Therefore, if a
+ particular subfeature is not supported, the main feature is listed
+ as unsupported even if some other subfeatures are supported.
+ </para>
+ </note>
+
+ <sect1 id="features-sql-standard">
+ <title>Supported Features</title>
+
+ <para>
+ <informaltable>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="1.5*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="7*"/>
+ <colspec colname="col4" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Core?</entry>
+ <entry>Description</entry>
+ <entry>Comment</entry>
+ </row>
+ </thead>
+
+ &features-supported;
+
+ </tgroup>
+ </informaltable>
+ </para>
+ </sect1>
+
+ <sect1 id="unsupported-features-sql-standard">
+ <title>Unsupported Features</title>
+
+ <para>
+ The following features defined in <acronym>SQL:2016</acronym> are not
+ implemented in this release of
+ <productname>PostgreSQL</productname>. In a few cases, equivalent
+ functionality is available.
+
+ <informaltable>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="1.5*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="7*"/>
+ <colspec colname="col4" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Identifier</entry>
+ <entry>Core?</entry>
+ <entry>Description</entry>
+ <entry>Comment</entry>
+ </row>
+ </thead>
+
+ &features-unsupported;
+
+ </tgroup>
+ </informaltable>
+ </para>
+ </sect1>
+
+ <sect1 id="xml-limits-conformance">
+ <title>XML Limits and Conformance to SQL/XML</title>
+
+ <indexterm>
+ <primary>SQL/XML</primary>
+ <secondary>limits and conformance</secondary>
+ </indexterm>
+
+ <para>
+ Significant revisions to the XML-related specifications in ISO/IEC 9075-14
+ (SQL/XML) were introduced with SQL:2006.
+ <productname>PostgreSQL</productname>'s implementation of the XML data
+ type and related functions largely follows the earlier 2003 edition,
+ with some borrowing from later editions. In particular:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Where the current standard provides a family of XML data types
+ to hold <quote>document</quote> or <quote>content</quote> in
+ untyped or XML Schema-typed variants, and a type
+ <type>XML(SEQUENCE)</type> to hold arbitrary pieces of XML content,
+ <productname>PostgreSQL</productname> provides the single
+ <type>xml</type> type, which can hold <quote>document</quote> or
+ <quote>content</quote>. There is no equivalent of the
+ standard's <quote>sequence</quote> type.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> provides two functions
+ introduced in SQL:2006, but in variants that use the XPath 1.0
+ language, rather than XML Query as specified for them in the
+ standard.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ This section presents some of the resulting differences you may encounter.
+ </para>
+
+ <sect2 id="functions-xml-limits-xpath1">
+ <title>Queries Are Restricted to XPath 1.0</title>
+
+ <para>
+ The <productname>PostgreSQL</productname>-specific functions
+ <function>xpath()</function> and <function>xpath_exists()</function>
+ query XML documents using the XPath language.
+ <productname>PostgreSQL</productname> also provides XPath-only variants
+ of the standard functions <function>XMLEXISTS</function> and
+ <function>XMLTABLE</function>, which officially use
+ the XQuery language. For all of these functions,
+ <productname>PostgreSQL</productname> relies on the
+ <application>libxml2</application> library, which provides only XPath 1.0.
+ </para>
+
+ <para>
+ There is a strong connection between the XQuery language and XPath
+ versions 2.0 and later: any expression that is syntactically valid and
+ executes successfully in both produces the same result (with a minor
+ exception for expressions containing numeric character references or
+ predefined entity references, which XQuery replaces with the
+ corresponding character while XPath leaves them alone). But there is
+ no such connection between these languages and XPath 1.0; it was an
+ earlier language and differs in many respects.
+ </para>
+
+ <para>
+ There are two categories of limitation to keep in mind: the restriction
+ from XQuery to XPath for the functions specified in the SQL standard, and
+ the restriction of XPath to version 1.0 for both the standard and the
+ <productname>PostgreSQL</productname>-specific functions.
+ </para>
+
+ <sect3>
+ <title>Restriction of XQuery to XPath</title>
+
+ <para>
+ Features of XQuery beyond those of XPath include:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ XQuery expressions can construct and return new XML nodes, in
+ addition to all possible XPath values. XPath can create and return
+ values of the atomic types (numbers, strings, and so on) but can
+ only return XML nodes that were already present in documents
+ supplied as input to the expression.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ XQuery has control constructs for iteration, sorting, and grouping.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ XQuery allows declaration and use of local functions.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Recent XPath versions begin to offer capabilities overlapping with
+ these (such as functional-style <function>for-each</function> and
+ <function>sort</function>, anonymous functions, and
+ <function>parse-xml</function> to create a node from a string),
+ but such features were not available before XPath 3.0.
+ </para>
+ </sect3>
+
+ <sect3 id="xml-xpath-1-specifics">
+ <title>Restriction of XPath to 1.0</title>
+
+ <para>
+ For developers familiar with XQuery and XPath 2.0 or later, XPath 1.0
+ presents a number of differences to contend with:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The fundamental type of an XQuery/XPath expression, the
+ <type>sequence</type>, which can contain XML nodes, atomic values,
+ or both, does not exist in XPath 1.0. A 1.0 expression can only
+ produce a node-set (containing zero or more XML nodes), or a single
+ atomic value.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Unlike an XQuery/XPath sequence, which can contain any desired
+ items in any desired order, an XPath 1.0 node-set has no
+ guaranteed order and, like any set, does not allow multiple
+ appearances of the same item.
+ <note>
+ <para>
+ The <application>libxml2</application> library does seem to
+ always return node-sets to <productname>PostgreSQL</productname>
+ with their members in the same relative order they had in the
+ input document. Its documentation does not commit to this
+ behavior, and an XPath 1.0 expression cannot control it.
+ </para>
+ </note>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ While XQuery/XPath provides all of the types defined in XML Schema
+ and many operators and functions over those types, XPath 1.0 has only
+ node-sets and the three atomic types <type>boolean</type>,
+ <type>double</type>, and <type>string</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ XPath 1.0 has no conditional operator. An XQuery/XPath expression
+ such as <literal>if ( hat ) then hat/@size else "no hat"</literal>
+ has no XPath 1.0 equivalent.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ XPath 1.0 has no ordering comparison operator for strings. Both
+ <literal>"cat" &lt; "dog"</literal> and
+ <literal>"cat" &gt; "dog"</literal> are false, because each is a
+ numeric comparison of two <literal>NaN</literal>s. In contrast,
+ <literal>=</literal> and <literal>!=</literal> do compare the strings
+ as strings.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ XPath 1.0 blurs the distinction between
+ <firstterm>value comparisons</firstterm> and
+ <firstterm>general comparisons</firstterm> as XQuery/XPath define
+ them. Both <literal>sale/@hatsize = 7</literal> and
+ <literal>sale/@customer = "alice"</literal> are existentially
+ quantified comparisons, true if there is
+ any <literal>sale</literal> with the given value for the
+ attribute, but <literal>sale/@taxable = false()</literal> is a
+ value comparison to the
+ <firstterm>effective boolean value</firstterm> of a whole node-set.
+ It is true only if no <literal>sale</literal> has
+ a <literal>taxable</literal> attribute at all.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In the XQuery/XPath data model, a <firstterm>document
+ node</firstterm> can have either document form (i.e., exactly one
+ top-level element, with only comments and processing instructions
+ outside of it) or content form (with those constraints
+ relaxed). Its equivalent in XPath 1.0, the
+ <firstterm>root node</firstterm>, can only be in document form.
+ This is part of the reason an <type>xml</type> value passed as the
+ context item to any <productname>PostgreSQL</productname>
+ XPath-based function must be in document form.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The differences highlighted here are not all of them. In XQuery and
+ the 2.0 and later versions of XPath, there is an XPath 1.0 compatibility
+ mode, and the W3C lists of
+ <ulink url='https://www.w3.org/TR/2010/REC-xpath-functions-20101214/#xpath1-compatibility'>function library changes</ulink>
+ and
+ <ulink url='https://www.w3.org/TR/xpath20/#id-backwards-compatibility'>language changes</ulink>
+ applied in that mode offer a more complete (but still not exhaustive)
+ account of the differences. The compatibility mode cannot make the
+ later languages exactly equivalent to XPath 1.0.
+ </para>
+ </sect3>
+
+ <sect3 id="functions-xml-limits-casts">
+ <title>Mappings between SQL and XML Data Types and Values</title>
+
+ <para>
+ In SQL:2006 and later, both directions of conversion between standard SQL
+ data types and the XML Schema types are specified precisely. However, the
+ rules are expressed using the types and semantics of XQuery/XPath, and
+ have no direct application to the different data model of XPath 1.0.
+ </para>
+
+ <para>
+ When <productname>PostgreSQL</productname> maps SQL data values to XML
+ (as in <function>xmlelement</function>), or XML to SQL (as in the output
+ columns of <function>xmltable</function>), except for a few cases
+ treated specially, <productname>PostgreSQL</productname> simply assumes
+ that the XML data type's XPath 1.0 string form will be valid as the
+ text-input form of the SQL datatype, and conversely. This rule has the
+ virtue of simplicity while producing, for many data types, results similar
+ to the mappings specified in the standard.
+ </para>
+
+ <para>
+ Where interoperability with other systems is a concern, for some data
+ types, it may be necessary to use data type formatting functions (such
+ as those in <xref linkend="functions-formatting"/>) explicitly to
+ produce the standard mappings.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="functions-xml-limits-postgresql">
+ <title>Incidental Limits of the Implementation</title>
+
+ <para>
+ This section concerns limits that are not inherent in the
+ <application>libxml2</application> library, but apply to the current
+ implementation in <productname>PostgreSQL</productname>.
+ </para>
+
+ <sect3>
+ <title>Only <literal>BY VALUE</literal> Passing Mechanism Is Supported</title>
+
+ <para>
+ The SQL standard defines two <firstterm>passing mechanisms</firstterm>
+ that apply when passing an XML argument from SQL to an XML function or
+ receiving a result: <literal>BY REF</literal>, in which a particular XML
+ value retains its node identity, and <literal>BY VALUE</literal>, in which
+ the content of the XML is passed but node identity is not preserved. A
+ mechanism can be specified before a list of parameters, as the default
+ mechanism for all of them, or after any parameter, to override the
+ default.
+ </para>
+
+ <para>
+ To illustrate the difference, if
+ <replaceable>x</replaceable> is an XML value, these two queries in
+ an SQL:2006 environment would produce true and false, respectively:
+
+<programlisting>
+SELECT XMLQUERY('$a is $b' PASSING BY REF <replaceable>x</replaceable> AS a, <replaceable>x</replaceable> AS b NULL ON EMPTY);
+SELECT XMLQUERY('$a is $b' PASSING BY VALUE <replaceable>x</replaceable> AS a, <replaceable>x</replaceable> AS b NULL ON EMPTY);
+</programlisting>
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> will accept
+ <literal>BY VALUE</literal> or <literal>BY REF</literal> in an
+ <function>XMLEXISTS</function> or <function>XMLTABLE</function>
+ construct, but it ignores them. The <type>xml</type> data type holds
+ a character-string serialized representation, so there is no node
+ identity to preserve, and passing is always effectively <literal>BY
+ VALUE</literal>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Cannot Pass Named Parameters to Queries</title>
+
+ <para>
+ The XPath-based functions support passing one parameter to serve as the
+ XPath expression's context item, but do not support passing additional
+ values to be available to the expression as named parameters.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>No <type>XML(SEQUENCE)</type> Type</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> <type>xml</type> data type
+ can only hold a value in <literal>DOCUMENT</literal>
+ or <literal>CONTENT</literal> form. An XQuery/XPath expression
+ context item must be a single XML node or atomic value, but XPath 1.0
+ further restricts it to be only an XML node, and has no node type
+ allowing <literal>CONTENT</literal>. The upshot is that a
+ well-formed <literal>DOCUMENT</literal> is the only form of XML value
+ that <productname>PostgreSQL</productname> can supply as an XPath
+ context item.
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ </appendix>
diff --git a/doc/src/sgml/file-fdw.sgml b/doc/src/sgml/file-fdw.sgml
new file mode 100644
index 0000000..5b98782
--- /dev/null
+++ b/doc/src/sgml/file-fdw.sgml
@@ -0,0 +1,282 @@
+<!-- doc/src/sgml/file-fdw.sgml -->
+
+<sect1 id="file-fdw" xreflabel="file_fdw">
+ <title>file_fdw</title>
+
+ <indexterm zone="file-fdw">
+ <primary>file_fdw</primary>
+ </indexterm>
+
+ <para>
+ The <filename>file_fdw</filename> module provides the foreign-data wrapper
+ <function>file_fdw</function>, which can be used to access data
+ files in the server's file system, or to execute programs on the server
+ and read their output. The data file or program output must be in a format
+ that can be read by <command>COPY FROM</command>;
+ see <xref linkend="sql-copy"/> for details.
+ Access to data files is currently read-only.
+ </para>
+
+ <para>
+ A foreign table created using this wrapper can have the following options:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>filename</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the file to be read. Relative paths are relative to the
+ data directory.
+ Either <literal>filename</literal> or <literal>program</literal> must be
+ specified, but not both.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>program</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the command to be executed. The standard output of this
+ command will be read as though <command>COPY FROM PROGRAM</command> were used.
+ Either <literal>program</literal> or <literal>filename</literal> must be
+ specified, but not both.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>format</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the data format,
+ the same as <command>COPY</command>'s <literal>FORMAT</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>header</literal></term>
+
+ <listitem>
+ <para>
+ Specifies whether the data has a header line,
+ the same as <command>COPY</command>'s <literal>HEADER</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>delimiter</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the data delimiter character,
+ the same as <command>COPY</command>'s <literal>DELIMITER</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>quote</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the data quote character,
+ the same as <command>COPY</command>'s <literal>QUOTE</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>escape</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the data escape character,
+ the same as <command>COPY</command>'s <literal>ESCAPE</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>null</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the data null string,
+ the same as <command>COPY</command>'s <literal>NULL</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>encoding</literal></term>
+
+ <listitem>
+ <para>
+ Specifies the data encoding,
+ the same as <command>COPY</command>'s <literal>ENCODING</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Note that while <command>COPY</command> allows options such as <literal>HEADER</literal>
+ to be specified without a corresponding value, the foreign table option
+ syntax requires a value to be present in all cases. To activate
+ <command>COPY</command> options typically written without a value, you can pass
+ the value TRUE, since all such options are Booleans.
+ </para>
+
+ <para>
+ A column of a foreign table created using this wrapper can have the
+ following options:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>force_not_null</literal></term>
+
+ <listitem>
+ <para>
+ This is a Boolean option. If true, it specifies that values of the
+ column should not be matched against the null string (that is, the
+ table-level <literal>null</literal> option). This has the same effect
+ as listing the column in <command>COPY</command>'s
+ <literal>FORCE_NOT_NULL</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>force_null</literal></term>
+
+ <listitem>
+ <para>
+ This is a Boolean option. If true, it specifies that values of the
+ column which match the null string are returned as <literal>NULL</literal>
+ even if the value is quoted. Without this option, only unquoted
+ values matching the null string are returned as <literal>NULL</literal>.
+ This has the same effect as listing the column in
+ <command>COPY</command>'s <literal>FORCE_NULL</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ <command>COPY</command>'s <literal>FORCE_QUOTE</literal> option is
+ currently not supported by <literal>file_fdw</literal>.
+ </para>
+
+ <para>
+ These options can only be specified for a foreign table or its columns, not
+ in the options of the <literal>file_fdw</literal> foreign-data wrapper, nor in the
+ options of a server or user mapping using the wrapper.
+ </para>
+
+ <para>
+ Changing table-level options requires being a superuser or having the privileges
+ of the role <literal>pg_read_server_files</literal> (to use a filename) or
+ the role <literal>pg_execute_server_program</literal> (to use a program),
+ for security reasons: only certain users should be able to control which file is
+ read or which program is run. In principle regular users could be allowed to
+ change the other options, but that's not supported at present.
+ </para>
+
+ <para>
+ When specifying the <literal>program</literal> option, keep in mind that the option
+ string is executed by the shell. If you need to pass any arguments to the
+ command that come from an untrusted source, you must be careful to strip or
+ escape any characters that might have special meaning to the shell.
+ For security reasons, it is best to use a fixed command string, or at least
+ avoid passing any user input in it.
+ </para>
+
+ <para>
+ For a foreign table using <literal>file_fdw</literal>, <command>EXPLAIN</command> shows
+ the name of the file to be read or program to be run.
+ For a file, unless <literal>COSTS OFF</literal> is
+ specified, the file size (in bytes) is shown as well.
+ </para>
+
+ <example>
+ <title>Create a Foreign Table for PostgreSQL CSV Logs</title>
+
+ <para>
+ One of the obvious uses for <literal>file_fdw</literal> is to make
+ the PostgreSQL activity log available as a table for querying. To
+ do this, first you must be <link
+ linkend="runtime-config-logging-csvlog">logging to a CSV file,</link>
+ which here we
+ will call <literal>pglog.csv</literal>. First, install <literal>file_fdw</literal>
+ as an extension:
+ </para>
+
+<programlisting>
+CREATE EXTENSION file_fdw;
+</programlisting>
+
+ <para>
+ Then create a foreign server:
+
+<programlisting>
+CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
+</programlisting>
+ </para>
+
+ <para>
+ Now you are ready to create the foreign data table. Using the
+ <command>CREATE FOREIGN TABLE</command> command, you will need to define
+ the columns for the table, the CSV file name, and its format:
+
+<programlisting>
+CREATE FOREIGN TABLE pglog (
+ log_time timestamp(3) with time zone,
+ user_name text,
+ database_name text,
+ process_id integer,
+ connection_from text,
+ session_id text,
+ session_line_num bigint,
+ command_tag text,
+ session_start_time timestamp with time zone,
+ virtual_transaction_id text,
+ transaction_id bigint,
+ error_severity text,
+ sql_state_code text,
+ message text,
+ detail text,
+ hint text,
+ internal_query text,
+ internal_query_pos integer,
+ context text,
+ query text,
+ query_pos integer,
+ location text,
+ application_name text,
+ backend_type text,
+ leader_pid integer,
+ query_id bigint
+) SERVER pglog
+OPTIONS ( filename 'log/pglog.csv', format 'csv' );
+</programlisting>
+ </para>
+
+ <para>
+ That's it &mdash; now you can query your log directly. In production, of
+ course, you would need to define some way to deal with log rotation.
+ </para>
+ </example>
+
+</sect1>
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
new file mode 100644
index 0000000..51dca79
--- /dev/null
+++ b/doc/src/sgml/filelist.sgml
@@ -0,0 +1,201 @@
+<!-- doc/src/sgml/filelist.sgml -->
+
+<!ENTITY history SYSTEM "history.sgml">
+<!ENTITY info SYSTEM "info.sgml">
+<!ENTITY intro SYSTEM "intro.sgml">
+<!ENTITY legal SYSTEM "legal.sgml">
+<!ENTITY notation SYSTEM "notation.sgml">
+<!ENTITY problems SYSTEM "problems.sgml">
+
+<!-- tutorial -->
+<!ENTITY advanced SYSTEM "advanced.sgml">
+<!ENTITY query SYSTEM "query.sgml">
+<!ENTITY start SYSTEM "start.sgml">
+
+<!-- user's guide -->
+<!ENTITY array SYSTEM "array.sgml">
+<!ENTITY datatype SYSTEM "datatype.sgml">
+<!ENTITY ddl SYSTEM "ddl.sgml">
+<!ENTITY dml SYSTEM "dml.sgml">
+<!ENTITY func SYSTEM "func.sgml">
+<!ENTITY indices SYSTEM "indices.sgml">
+<!ENTITY json SYSTEM "json.sgml">
+<!ENTITY mvcc SYSTEM "mvcc.sgml">
+<!ENTITY parallel SYSTEM "parallel.sgml">
+<!ENTITY perform SYSTEM "perform.sgml">
+<!ENTITY queries SYSTEM "queries.sgml">
+<!ENTITY rangetypes SYSTEM "rangetypes.sgml">
+<!ENTITY rowtypes SYSTEM "rowtypes.sgml">
+<!ENTITY syntax SYSTEM "syntax.sgml">
+<!ENTITY textsearch SYSTEM "textsearch.sgml">
+<!ENTITY typeconv SYSTEM "typeconv.sgml">
+
+<!-- administrator's guide -->
+<!ENTITY backup SYSTEM "backup.sgml">
+<!ENTITY charset SYSTEM "charset.sgml">
+<!ENTITY client-auth SYSTEM "client-auth.sgml">
+<!ENTITY diskusage SYSTEM "diskusage.sgml">
+<!ENTITY high-availability SYSTEM "high-availability.sgml">
+<!ENTITY installbin SYSTEM "install-binaries.sgml">
+<!ENTITY installation SYSTEM "installation.sgml">
+<!ENTITY installw SYSTEM "install-windows.sgml">
+<!ENTITY maintenance SYSTEM "maintenance.sgml">
+<!ENTITY manage-ag SYSTEM "manage-ag.sgml">
+<!ENTITY monitoring SYSTEM "monitoring.sgml">
+<!ENTITY regress SYSTEM "regress.sgml">
+<!ENTITY runtime SYSTEM "runtime.sgml">
+<!ENTITY config SYSTEM "config.sgml">
+<!ENTITY user-manag SYSTEM "user-manag.sgml">
+<!ENTITY wal SYSTEM "wal.sgml">
+<!ENTITY logical-replication SYSTEM "logical-replication.sgml">
+<!ENTITY jit SYSTEM "jit.sgml">
+
+<!-- programmer's guide -->
+<!ENTITY bgworker SYSTEM "bgworker.sgml">
+<!ENTITY dfunc SYSTEM "dfunc.sgml">
+<!ENTITY ecpg SYSTEM "ecpg.sgml">
+<!ENTITY extend SYSTEM "extend.sgml">
+<!ENTITY external-projects SYSTEM "external-projects.sgml">
+<!ENTITY func-ref SYSTEM "func-ref.sgml">
+<!ENTITY infoschema SYSTEM "information_schema.sgml">
+<!ENTITY libpq SYSTEM "libpq.sgml">
+<!ENTITY lobj SYSTEM "lobj.sgml">
+<!ENTITY rules SYSTEM "rules.sgml">
+<!ENTITY spi SYSTEM "spi.sgml">
+<!ENTITY trigger SYSTEM "trigger.sgml">
+<!ENTITY event-trigger SYSTEM "event-trigger.sgml">
+<!ENTITY xaggr SYSTEM "xaggr.sgml">
+<!ENTITY xfunc SYSTEM "xfunc.sgml">
+<!ENTITY xindex SYSTEM "xindex.sgml">
+<!ENTITY xplang SYSTEM "xplang.sgml">
+<!ENTITY xoper SYSTEM "xoper.sgml">
+<!ENTITY xtypes SYSTEM "xtypes.sgml">
+<!ENTITY plperl SYSTEM "plperl.sgml">
+<!ENTITY plpython SYSTEM "plpython.sgml">
+<!ENTITY plsql SYSTEM "plpgsql.sgml">
+<!ENTITY pltcl SYSTEM "pltcl.sgml">
+
+<!-- reference pages -->
+<!ENTITY % allfiles SYSTEM "ref/allfiles.sgml">
+%allfiles;
+
+<!-- developer's guide -->
+<!ENTITY arch-dev SYSTEM "arch-dev.sgml">
+<!ENTITY bki SYSTEM "bki.sgml">
+<!ENTITY catalogs SYSTEM "catalogs.sgml">
+<!ENTITY system-views SYSTEM "system-views.sgml">
+<!ENTITY geqo SYSTEM "geqo.sgml">
+<!ENTITY btree SYSTEM "btree.sgml">
+<!ENTITY gist SYSTEM "gist.sgml">
+<!ENTITY spgist SYSTEM "spgist.sgml">
+<!ENTITY gin SYSTEM "gin.sgml">
+<!ENTITY brin SYSTEM "brin.sgml">
+<!ENTITY hash SYSTEM "hash.sgml">
+<!ENTITY planstats SYSTEM "planstats.sgml">
+<!ENTITY tableam SYSTEM "tableam.sgml">
+<!ENTITY indexam SYSTEM "indexam.sgml">
+<!ENTITY nls SYSTEM "nls.sgml">
+<!ENTITY plhandler SYSTEM "plhandler.sgml">
+<!ENTITY fdwhandler SYSTEM "fdwhandler.sgml">
+<!ENTITY custom-scan SYSTEM "custom-scan.sgml">
+<!ENTITY logicaldecoding SYSTEM "logicaldecoding.sgml">
+<!ENTITY replication-origins SYSTEM "replication-origins.sgml">
+<!ENTITY archive-modules SYSTEM "archive-modules.sgml">
+<!ENTITY protocol SYSTEM "protocol.sgml">
+<!ENTITY sources SYSTEM "sources.sgml">
+<!ENTITY storage SYSTEM "storage.sgml">
+<!ENTITY tablesample-method SYSTEM "tablesample-method.sgml">
+<!ENTITY generic-wal SYSTEM "generic-wal.sgml">
+<!ENTITY custom-rmgr SYSTEM "custom-rmgr.sgml">
+<!ENTITY backup-manifest SYSTEM "backup-manifest.sgml">
+
+<!-- contrib information -->
+<!ENTITY contrib SYSTEM "contrib.sgml">
+<!ENTITY adminpack SYSTEM "adminpack.sgml">
+<!ENTITY amcheck SYSTEM "amcheck.sgml">
+<!ENTITY auth-delay SYSTEM "auth-delay.sgml">
+<!ENTITY auto-explain SYSTEM "auto-explain.sgml">
+<!ENTITY basic-archive SYSTEM "basic-archive.sgml">
+<!ENTITY basebackup-to-shell SYSTEM "basebackup-to-shell.sgml">
+<!ENTITY bloom SYSTEM "bloom.sgml">
+<!ENTITY btree-gin SYSTEM "btree-gin.sgml">
+<!ENTITY btree-gist SYSTEM "btree-gist.sgml">
+<!ENTITY citext SYSTEM "citext.sgml">
+<!ENTITY cube SYSTEM "cube.sgml">
+<!ENTITY dblink SYSTEM "dblink.sgml">
+<!ENTITY dict-int SYSTEM "dict-int.sgml">
+<!ENTITY dict-xsyn SYSTEM "dict-xsyn.sgml">
+<!ENTITY dummy-seclabel SYSTEM "dummy-seclabel.sgml">
+<!ENTITY earthdistance SYSTEM "earthdistance.sgml">
+<!ENTITY file-fdw SYSTEM "file-fdw.sgml">
+<!ENTITY fuzzystrmatch SYSTEM "fuzzystrmatch.sgml">
+<!ENTITY hstore SYSTEM "hstore.sgml">
+<!ENTITY intagg SYSTEM "intagg.sgml">
+<!ENTITY intarray SYSTEM "intarray.sgml">
+<!ENTITY isn SYSTEM "isn.sgml">
+<!ENTITY lo SYSTEM "lo.sgml">
+<!ENTITY ltree SYSTEM "ltree.sgml">
+<!ENTITY oid2name SYSTEM "oid2name.sgml">
+<!ENTITY oldsnapshot SYSTEM "oldsnapshot.sgml">
+<!ENTITY pageinspect SYSTEM "pageinspect.sgml">
+<!ENTITY passwordcheck SYSTEM "passwordcheck.sgml">
+<!ENTITY pgbuffercache SYSTEM "pgbuffercache.sgml">
+<!ENTITY pgcrypto SYSTEM "pgcrypto.sgml">
+<!ENTITY pgfreespacemap SYSTEM "pgfreespacemap.sgml">
+<!ENTITY pgprewarm SYSTEM "pgprewarm.sgml">
+<!ENTITY pgrowlocks SYSTEM "pgrowlocks.sgml">
+<!ENTITY pgstatstatements SYSTEM "pgstatstatements.sgml">
+<!ENTITY pgstattuple SYSTEM "pgstattuple.sgml">
+<!ENTITY pgsurgery SYSTEM "pgsurgery.sgml">
+<!ENTITY pgtrgm SYSTEM "pgtrgm.sgml">
+<!ENTITY pgvisibility SYSTEM "pgvisibility.sgml">
+<!ENTITY pgwalinspect SYSTEM "pgwalinspect.sgml">
+<!ENTITY postgres-fdw SYSTEM "postgres-fdw.sgml">
+<!ENTITY seg SYSTEM "seg.sgml">
+<!ENTITY contrib-spi SYSTEM "contrib-spi.sgml">
+<!ENTITY sepgsql SYSTEM "sepgsql.sgml">
+<!ENTITY sslinfo SYSTEM "sslinfo.sgml">
+<!ENTITY tablefunc SYSTEM "tablefunc.sgml">
+<!ENTITY tcn SYSTEM "tcn.sgml">
+<!ENTITY test-decoding SYSTEM "test-decoding.sgml">
+<!ENTITY test-parser SYSTEM "test-parser.sgml">
+<!ENTITY test-shm-mq SYSTEM "test-shm-mq.sgml">
+<!ENTITY tsm-system-rows SYSTEM "tsm-system-rows.sgml">
+<!ENTITY tsm-system-time SYSTEM "tsm-system-time.sgml">
+<!ENTITY unaccent SYSTEM "unaccent.sgml">
+<!ENTITY uuid-ossp SYSTEM "uuid-ossp.sgml">
+<!ENTITY vacuumlo SYSTEM "vacuumlo.sgml">
+<!ENTITY xml2 SYSTEM "xml2.sgml">
+
+<!-- appendixes -->
+<!ENTITY datetime SYSTEM "datetime.sgml">
+<!ENTITY docguide SYSTEM "docguide.sgml">
+<!ENTITY errcodes SYSTEM "errcodes.sgml">
+<!ENTITY features SYSTEM "features.sgml">
+<!ENTITY keywords SYSTEM "keywords.sgml">
+<!ENTITY sourcerepo SYSTEM "sourcerepo.sgml">
+
+<!ENTITY release SYSTEM "release.sgml">
+<!ENTITY release-15 SYSTEM "release-15.sgml">
+
+<!ENTITY limits SYSTEM "limits.sgml">
+<!ENTITY acronyms SYSTEM "acronyms.sgml">
+<!ENTITY glossary SYSTEM "glossary.sgml">
+<!ENTITY color SYSTEM "color.sgml">
+
+<!ENTITY features-supported SYSTEM "features-supported.sgml">
+<!ENTITY features-unsupported SYSTEM "features-unsupported.sgml">
+
+<!ENTITY errcodes-table SYSTEM "errcodes-table.sgml">
+<!ENTITY keywords-table SYSTEM "keywords-table.sgml">
+
+<!-- back matter -->
+<!ENTITY biblio SYSTEM "biblio.sgml">
+
+<!-- Stubs for removed entries to preserve public links -->
+<!ENTITY obsolete SYSTEM "appendix-obsolete.sgml">
+<!ENTITY obsolete-recovery-config SYSTEM "appendix-obsolete-recovery-config.sgml">
+<!ENTITY obsolete-default-roles SYSTEM "appendix-obsolete-default-roles.sgml">
+<!ENTITY obsolete-pgxlogdump SYSTEM "appendix-obsolete-pgxlogdump.sgml">
+<!ENTITY obsolete-pgresetxlog SYSTEM "appendix-obsolete-pgresetxlog.sgml">
+<!ENTITY obsolete-pgreceivexlog SYSTEM "appendix-obsolete-pgreceivexlog.sgml">
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
new file mode 100644
index 0000000..b8736c3
--- /dev/null
+++ b/doc/src/sgml/func.sgml
@@ -0,0 +1,28463 @@
+<!-- doc/src/sgml/func.sgml -->
+
+ <chapter id="functions">
+ <title>Functions and Operators</title>
+
+ <indexterm zone="functions">
+ <primary>function</primary>
+ </indexterm>
+
+ <indexterm zone="functions">
+ <primary>operator</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a large number of
+ functions and operators for the built-in data types. This chapter
+ describes most of them, although additional special-purpose functions
+ appear in relevant sections of the manual. Users can also
+ define their own functions and operators, as described in
+ <xref linkend="server-programming"/>. The
+ <application>psql</application> commands <command>\df</command> and
+ <command>\do</command> can be used to list all
+ available functions and operators, respectively.
+ </para>
+
+ <para>
+ The notation used throughout this chapter to describe the argument and
+ result data types of a function or operator is like this:
+<synopsis>
+<function>repeat</function> ( <type>text</type>, <type>integer</type> ) <returnvalue>text</returnvalue>
+</synopsis>
+ which says that the function <function>repeat</function> takes one text and
+ one integer argument and returns a result of type text. The right arrow
+ is also used to indicate the result of an example, thus:
+<programlisting>
+repeat('Pg', 4) <returnvalue>PgPgPgPg</returnvalue>
+</programlisting>
+ </para>
+
+ <para>
+ If you are concerned about portability then note that most of
+ the functions and operators described in this chapter, with the
+ exception of the most trivial arithmetic and comparison operators
+ and some explicitly marked functions, are not specified by the
+ <acronym>SQL</acronym> standard. Some of this extended functionality
+ is present in other <acronym>SQL</acronym> database management
+ systems, and in many cases this functionality is compatible and
+ consistent between the various implementations.
+ </para>
+
+
+ <sect1 id="functions-logical">
+ <title>Logical Operators</title>
+
+ <indexterm zone="functions-logical">
+ <primary>operator</primary>
+ <secondary>logical</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>Boolean</primary>
+ <secondary>operators</secondary>
+ <see>operators, logical</see>
+ </indexterm>
+
+ <para>
+ The usual logical operators are available:
+
+ <indexterm>
+ <primary>AND (operator)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>OR (operator)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NOT (operator)</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>conjunction</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>disjunction</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>negation</primary>
+ </indexterm>
+
+<synopsis>
+<type>boolean</type> <literal>AND</literal> <type>boolean</type> <returnvalue>boolean</returnvalue>
+<type>boolean</type> <literal>OR</literal> <type>boolean</type> <returnvalue>boolean</returnvalue>
+<literal>NOT</literal> <type>boolean</type> <returnvalue>boolean</returnvalue>
+</synopsis>
+
+ <acronym>SQL</acronym> uses a three-valued logic system with true,
+ false, and <literal>null</literal>, which represents <quote>unknown</quote>.
+ Observe the following truth tables:
+
+ <informaltable>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry><replaceable>a</replaceable></entry>
+ <entry><replaceable>b</replaceable></entry>
+ <entry><replaceable>a</replaceable> AND <replaceable>b</replaceable></entry>
+ <entry><replaceable>a</replaceable> OR <replaceable>b</replaceable></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>TRUE</entry>
+ <entry>TRUE</entry>
+ <entry>TRUE</entry>
+ <entry>TRUE</entry>
+ </row>
+
+ <row>
+ <entry>TRUE</entry>
+ <entry>FALSE</entry>
+ <entry>FALSE</entry>
+ <entry>TRUE</entry>
+ </row>
+
+ <row>
+ <entry>TRUE</entry>
+ <entry>NULL</entry>
+ <entry>NULL</entry>
+ <entry>TRUE</entry>
+ </row>
+
+ <row>
+ <entry>FALSE</entry>
+ <entry>FALSE</entry>
+ <entry>FALSE</entry>
+ <entry>FALSE</entry>
+ </row>
+
+ <row>
+ <entry>FALSE</entry>
+ <entry>NULL</entry>
+ <entry>FALSE</entry>
+ <entry>NULL</entry>
+ </row>
+
+ <row>
+ <entry>NULL</entry>
+ <entry>NULL</entry>
+ <entry>NULL</entry>
+ <entry>NULL</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><replaceable>a</replaceable></entry>
+ <entry>NOT <replaceable>a</replaceable></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>TRUE</entry>
+ <entry>FALSE</entry>
+ </row>
+
+ <row>
+ <entry>FALSE</entry>
+ <entry>TRUE</entry>
+ </row>
+
+ <row>
+ <entry>NULL</entry>
+ <entry>NULL</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+
+ <para>
+ The operators <literal>AND</literal> and <literal>OR</literal> are
+ commutative, that is, you can switch the left and right operands
+ without affecting the result. (However, it is not guaranteed that
+ the left operand is evaluated before the right operand. See <xref
+ linkend="syntax-express-eval"/> for more information about the
+ order of evaluation of subexpressions.)
+ </para>
+ </sect1>
+
+ <sect1 id="functions-comparison">
+ <title>Comparison Functions and Operators</title>
+
+ <indexterm zone="functions-comparison">
+ <primary>comparison</primary>
+ <secondary>operators</secondary>
+ </indexterm>
+
+ <para>
+ The usual comparison operators are available, as shown in <xref
+ linkend="functions-comparison-op-table"/>.
+ </para>
+
+ <table id="functions-comparison-op-table">
+ <title>Comparison Operators</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operator</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>&lt;</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Less than</entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>&gt;</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Greater than</entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>&lt;=</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Less than or equal to</entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>&gt;=</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Greater than or equal to</entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>=</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Equal</entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>&lt;&gt;</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Not equal</entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>datatype</replaceable> <literal>!=</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </entry>
+ <entry>Not equal</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ <literal>&lt;&gt;</literal> is the standard SQL notation for <quote>not
+ equal</quote>. <literal>!=</literal> is an alias, which is converted
+ to <literal>&lt;&gt;</literal> at a very early stage of parsing.
+ Hence, it is not possible to implement <literal>!=</literal>
+ and <literal>&lt;&gt;</literal> operators that do different things.
+ </para>
+ </note>
+
+ <para>
+ These comparison operators are available for all built-in data types
+ that have a natural ordering, including numeric, string, and date/time
+ types. In addition, arrays, composite types, and ranges can be compared
+ if their component data types are comparable.
+ </para>
+
+ <para>
+ It is usually possible to compare values of related data
+ types as well; for example <type>integer</type> <literal>&gt;</literal>
+ <type>bigint</type> will work. Some cases of this sort are implemented
+ directly by <quote>cross-type</quote> comparison operators, but if no
+ such operator is available, the parser will coerce the less-general type
+ to the more-general type and apply the latter's comparison operator.
+ </para>
+
+ <para>
+ As shown above, all comparison operators are binary operators that
+ return values of type <type>boolean</type>. Thus, expressions like
+ <literal>1 &lt; 2 &lt; 3</literal> are not valid (because there is
+ no <literal>&lt;</literal> operator to compare a Boolean value with
+ <literal>3</literal>). Use the <literal>BETWEEN</literal> predicates
+ shown below to perform range tests.
+ </para>
+
+ <para>
+ There are also some comparison predicates, as shown in <xref
+ linkend="functions-comparison-pred-table"/>. These behave much like
+ operators, but have special syntax mandated by the SQL standard.
+ </para>
+
+ <table id="functions-comparison-pred-table">
+ <title>Comparison Predicates</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Predicate
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>BETWEEN</literal> <replaceable>datatype</replaceable> <literal>AND</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Between (inclusive of the range endpoints).
+ </para>
+ <para>
+ <literal>2 BETWEEN 1 AND 3</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>2 BETWEEN 3 AND 1</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>NOT BETWEEN</literal> <replaceable>datatype</replaceable> <literal>AND</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Not between (the negation of <literal>BETWEEN</literal>).
+ </para>
+ <para>
+ <literal>2 NOT BETWEEN 1 AND 3</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>BETWEEN SYMMETRIC</literal> <replaceable>datatype</replaceable> <literal>AND</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Between, after sorting the two endpoint values.
+ </para>
+ <para>
+ <literal>2 BETWEEN SYMMETRIC 3 AND 1</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>NOT BETWEEN SYMMETRIC</literal> <replaceable>datatype</replaceable> <literal>AND</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Not between, after sorting the two endpoint values.
+ </para>
+ <para>
+ <literal>2 NOT BETWEEN SYMMETRIC 3 AND 1</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>IS DISTINCT FROM</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Not equal, treating null as a comparable value.
+ </para>
+ <para>
+ <literal>1 IS DISTINCT FROM NULL</literal>
+ <returnvalue>t</returnvalue> (rather than <literal>NULL</literal>)
+ </para>
+ <para>
+ <literal>NULL IS DISTINCT FROM NULL</literal>
+ <returnvalue>f</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>IS NOT DISTINCT FROM</literal> <replaceable>datatype</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Equal, treating null as a comparable value.
+ </para>
+ <para>
+ <literal>1 IS NOT DISTINCT FROM NULL</literal>
+ <returnvalue>f</returnvalue> (rather than <literal>NULL</literal>)
+ </para>
+ <para>
+ <literal>NULL IS NOT DISTINCT FROM NULL</literal>
+ <returnvalue>t</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>IS NULL</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether value is null.
+ </para>
+ <para>
+ <literal>1.5 IS NULL</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>IS NOT NULL</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether value is not null.
+ </para>
+ <para>
+ <literal>'null' IS NOT NULL</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>ISNULL</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether value is null (nonstandard syntax).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>datatype</replaceable> <literal>NOTNULL</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether value is not null (nonstandard syntax).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>boolean</type> <literal>IS TRUE</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether boolean expression yields true.
+ </para>
+ <para>
+ <literal>true IS TRUE</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>NULL::boolean IS TRUE</literal>
+ <returnvalue>f</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>boolean</type> <literal>IS NOT TRUE</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether boolean expression yields false or unknown.
+ </para>
+ <para>
+ <literal>true IS NOT TRUE</literal>
+ <returnvalue>f</returnvalue>
+ </para>
+ <para>
+ <literal>NULL::boolean IS NOT TRUE</literal>
+ <returnvalue>t</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>boolean</type> <literal>IS FALSE</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether boolean expression yields false.
+ </para>
+ <para>
+ <literal>true IS FALSE</literal>
+ <returnvalue>f</returnvalue>
+ </para>
+ <para>
+ <literal>NULL::boolean IS FALSE</literal>
+ <returnvalue>f</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>boolean</type> <literal>IS NOT FALSE</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether boolean expression yields true or unknown.
+ </para>
+ <para>
+ <literal>true IS NOT FALSE</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>NULL::boolean IS NOT FALSE</literal>
+ <returnvalue>t</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>boolean</type> <literal>IS UNKNOWN</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether boolean expression yields unknown.
+ </para>
+ <para>
+ <literal>true IS UNKNOWN</literal>
+ <returnvalue>f</returnvalue>
+ </para>
+ <para>
+ <literal>NULL::boolean IS UNKNOWN</literal>
+ <returnvalue>t</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>boolean</type> <literal>IS NOT UNKNOWN</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test whether boolean expression yields true or false.
+ </para>
+ <para>
+ <literal>true IS NOT UNKNOWN</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>NULL::boolean IS NOT UNKNOWN</literal>
+ <returnvalue>f</returnvalue> (rather than <literal>NULL</literal>)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <indexterm>
+ <primary>BETWEEN</primary>
+ </indexterm>
+ <indexterm>
+ <primary>BETWEEN SYMMETRIC</primary>
+ </indexterm>
+ The <token>BETWEEN</token> predicate simplifies range tests:
+<synopsis>
+<replaceable>a</replaceable> BETWEEN <replaceable>x</replaceable> AND <replaceable>y</replaceable>
+</synopsis>
+ is equivalent to
+<synopsis>
+<replaceable>a</replaceable> &gt;= <replaceable>x</replaceable> AND <replaceable>a</replaceable> &lt;= <replaceable>y</replaceable>
+</synopsis>
+ Notice that <token>BETWEEN</token> treats the endpoint values as included
+ in the range.
+ <literal>BETWEEN SYMMETRIC</literal> is like <literal>BETWEEN</literal>
+ except there is no requirement that the argument to the left of
+ <literal>AND</literal> be less than or equal to the argument on the right.
+ If it is not, those two arguments are automatically swapped, so that
+ a nonempty range is always implied.
+ </para>
+
+ <para>
+ The various variants of <literal>BETWEEN</literal> are implemented in
+ terms of the ordinary comparison operators, and therefore will work for
+ any data type(s) that can be compared.
+ </para>
+
+ <note>
+ <para>
+ The use of <literal>AND</literal> in the <literal>BETWEEN</literal>
+ syntax creates an ambiguity with the use of <literal>AND</literal> as a
+ logical operator. To resolve this, only a limited set of expression
+ types are allowed as the second argument of a <literal>BETWEEN</literal>
+ clause. If you need to write a more complex sub-expression
+ in <literal>BETWEEN</literal>, write parentheses around the
+ sub-expression.
+ </para>
+ </note>
+
+ <para>
+ <indexterm>
+ <primary>IS DISTINCT FROM</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS NOT DISTINCT FROM</primary>
+ </indexterm>
+ Ordinary comparison operators yield null (signifying <quote>unknown</quote>),
+ not true or false, when either input is null. For example,
+ <literal>7 = NULL</literal> yields null, as does <literal>7 &lt;&gt; NULL</literal>. When
+ this behavior is not suitable, use the
+ <literal>IS <optional> NOT </optional> DISTINCT FROM</literal> predicates:
+<synopsis>
+<replaceable>a</replaceable> IS DISTINCT FROM <replaceable>b</replaceable>
+<replaceable>a</replaceable> IS NOT DISTINCT FROM <replaceable>b</replaceable>
+</synopsis>
+ For non-null inputs, <literal>IS DISTINCT FROM</literal> is
+ the same as the <literal>&lt;&gt;</literal> operator. However, if both
+ inputs are null it returns false, and if only one input is
+ null it returns true. Similarly, <literal>IS NOT DISTINCT
+ FROM</literal> is identical to <literal>=</literal> for non-null
+ inputs, but it returns true when both inputs are null, and false when only
+ one input is null. Thus, these predicates effectively act as though null
+ were a normal data value, rather than <quote>unknown</quote>.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>IS NULL</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS NOT NULL</primary>
+ </indexterm>
+ <indexterm>
+ <primary>ISNULL</primary>
+ </indexterm>
+ <indexterm>
+ <primary>NOTNULL</primary>
+ </indexterm>
+ To check whether a value is or is not null, use the predicates:
+<synopsis>
+<replaceable>expression</replaceable> IS NULL
+<replaceable>expression</replaceable> IS NOT NULL
+</synopsis>
+ or the equivalent, but nonstandard, predicates:
+<synopsis>
+<replaceable>expression</replaceable> ISNULL
+<replaceable>expression</replaceable> NOTNULL
+</synopsis>
+ <indexterm><primary>null value</primary><secondary>comparing</secondary></indexterm>
+ </para>
+
+ <para>
+ Do <emphasis>not</emphasis> write
+ <literal><replaceable>expression</replaceable> = NULL</literal>
+ because <literal>NULL</literal> is not <quote>equal to</quote>
+ <literal>NULL</literal>. (The null value represents an unknown value,
+ and it is not known whether two unknown values are equal.)
+ </para>
+
+ <tip>
+ <para>
+ Some applications might expect that
+ <literal><replaceable>expression</replaceable> = NULL</literal>
+ returns true if <replaceable>expression</replaceable> evaluates to
+ the null value. It is highly recommended that these applications
+ be modified to comply with the SQL standard. However, if that
+ cannot be done the <xref linkend="guc-transform-null-equals"/>
+ configuration variable is available. If it is enabled,
+ <productname>PostgreSQL</productname> will convert <literal>x =
+ NULL</literal> clauses to <literal>x IS NULL</literal>.
+ </para>
+ </tip>
+
+ <para>
+ If the <replaceable>expression</replaceable> is row-valued, then
+ <literal>IS NULL</literal> is true when the row expression itself is null
+ or when all the row's fields are null, while
+ <literal>IS NOT NULL</literal> is true when the row expression itself is non-null
+ and all the row's fields are non-null. Because of this behavior,
+ <literal>IS NULL</literal> and <literal>IS NOT NULL</literal> do not always return
+ inverse results for row-valued expressions; in particular, a row-valued
+ expression that contains both null and non-null fields will return false
+ for both tests. In some cases, it may be preferable to
+ write <replaceable>row</replaceable> <literal>IS DISTINCT FROM NULL</literal>
+ or <replaceable>row</replaceable> <literal>IS NOT DISTINCT FROM NULL</literal>,
+ which will simply check whether the overall row value is null without any
+ additional tests on the row fields.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>IS TRUE</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS NOT TRUE</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS FALSE</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS NOT FALSE</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS UNKNOWN</primary>
+ </indexterm>
+ <indexterm>
+ <primary>IS NOT UNKNOWN</primary>
+ </indexterm>
+ Boolean values can also be tested using the predicates
+<synopsis>
+<replaceable>boolean_expression</replaceable> IS TRUE
+<replaceable>boolean_expression</replaceable> IS NOT TRUE
+<replaceable>boolean_expression</replaceable> IS FALSE
+<replaceable>boolean_expression</replaceable> IS NOT FALSE
+<replaceable>boolean_expression</replaceable> IS UNKNOWN
+<replaceable>boolean_expression</replaceable> IS NOT UNKNOWN
+</synopsis>
+ These will always return true or false, never a null value, even when the
+ operand is null.
+ A null input is treated as the logical value <quote>unknown</quote>.
+ Notice that <literal>IS UNKNOWN</literal> and <literal>IS NOT UNKNOWN</literal> are
+ effectively the same as <literal>IS NULL</literal> and
+ <literal>IS NOT NULL</literal>, respectively, except that the input
+ expression must be of Boolean type.
+ </para>
+
+ <para>
+ Some comparison-related functions are also available, as shown in <xref
+ linkend="functions-comparison-func-table"/>.
+ </para>
+
+ <table id="functions-comparison-func-table">
+ <title>Comparison Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>num_nonnulls</primary>
+ </indexterm>
+ <function>num_nonnulls</function> ( <literal>VARIADIC</literal> <type>"any"</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of non-null arguments.
+ </para>
+ <para>
+ <literal>num_nonnulls(1, NULL, 2)</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>num_nulls</primary>
+ </indexterm>
+ <function>num_nulls</function> ( <literal>VARIADIC</literal> <type>"any"</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of null arguments.
+ </para>
+ <para>
+ <literal>num_nulls(1, NULL, 2)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="functions-math">
+ <title>Mathematical Functions and Operators</title>
+
+ <para>
+ Mathematical operators are provided for many
+ <productname>PostgreSQL</productname> types. For types without
+ standard mathematical conventions
+ (e.g., date/time types) we
+ describe the actual behavior in subsequent sections.
+ </para>
+
+ <para>
+ <xref linkend="functions-math-op-table"/> shows the mathematical
+ operators that are available for the standard numeric types.
+ Unless otherwise noted, operators shown as
+ accepting <replaceable>numeric_type</replaceable> are available for all
+ the types <type>smallint</type>, <type>integer</type>,
+ <type>bigint</type>, <type>numeric</type>, <type>real</type>,
+ and <type>double precision</type>.
+ Operators shown as accepting <replaceable>integral_type</replaceable>
+ are available for the types <type>smallint</type>, <type>integer</type>,
+ and <type>bigint</type>.
+ Except where noted, each form of an operator returns the same data type
+ as its argument(s). Calls involving multiple argument data types, such
+ as <type>integer</type> <literal>+</literal> <type>numeric</type>,
+ are resolved by using the type appearing later in these lists.
+ </para>
+
+ <table id="functions-math-op-table">
+ <title>Mathematical Operators</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>numeric_type</replaceable> <literal>+</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Addition
+ </para>
+ <para>
+ <literal>2 + 3</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>+</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Unary plus (no operation)
+ </para>
+ <para>
+ <literal>+ 3.5</literal>
+ <returnvalue>3.5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>numeric_type</replaceable> <literal>-</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Subtraction
+ </para>
+ <para>
+ <literal>2 - 3</literal>
+ <returnvalue>-1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>-</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Negation
+ </para>
+ <para>
+ <literal>- (-4)</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>numeric_type</replaceable> <literal>*</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Multiplication
+ </para>
+ <para>
+ <literal>2 * 3</literal>
+ <returnvalue>6</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>numeric_type</replaceable> <literal>/</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Division (for integral types, division truncates the result towards
+ zero)
+ </para>
+ <para>
+ <literal>5.0 / 2</literal>
+ <returnvalue>2.5000000000000000</returnvalue>
+ </para>
+ <para>
+ <literal>5 / 2</literal>
+ <returnvalue>2</returnvalue>
+ </para>
+ <para>
+ <literal>(-5) / 2</literal>
+ <returnvalue>-2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>numeric_type</replaceable> <literal>%</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Modulo (remainder); available for <type>smallint</type>,
+ <type>integer</type>, <type>bigint</type>, and <type>numeric</type>
+ </para>
+ <para>
+ <literal>5 % 4</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>numeric</type> <literal>^</literal> <type>numeric</type>
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>double precision</type> <literal>^</literal> <type>double precision</type>
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Exponentiation
+ </para>
+ <para>
+ <literal>2 ^ 3</literal>
+ <returnvalue>8</returnvalue>
+ </para>
+ <para>
+ Unlike typical mathematical practice, multiple uses of
+ <literal>^</literal> will associate left to right by default:
+ </para>
+ <para>
+ <literal>2 ^ 3 ^ 3</literal>
+ <returnvalue>512</returnvalue>
+ </para>
+ <para>
+ <literal>2 ^ (3 ^ 3)</literal>
+ <returnvalue>134217728</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>|/</literal> <type>double precision</type>
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Square root
+ </para>
+ <para>
+ <literal>|/ 25.0</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>||/</literal> <type>double precision</type>
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Cube root
+ </para>
+ <para>
+ <literal>||/ 64.0</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>@</literal> <replaceable>numeric_type</replaceable>
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Absolute value
+ </para>
+ <para>
+ <literal>@ -5.0</literal>
+ <returnvalue>5.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integral_type</replaceable> <literal>&amp;</literal> <replaceable>integral_type</replaceable>
+ <returnvalue><replaceable>integral_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise AND
+ </para>
+ <para>
+ <literal>91 &amp; 15</literal>
+ <returnvalue>11</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integral_type</replaceable> <literal>|</literal> <replaceable>integral_type</replaceable>
+ <returnvalue><replaceable>integral_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise OR
+ </para>
+ <para>
+ <literal>32 | 3</literal>
+ <returnvalue>35</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integral_type</replaceable> <literal>#</literal> <replaceable>integral_type</replaceable>
+ <returnvalue><replaceable>integral_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise exclusive OR
+ </para>
+ <para>
+ <literal>17 # 5</literal>
+ <returnvalue>20</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>~</literal> <replaceable>integral_type</replaceable>
+ <returnvalue><replaceable>integral_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise NOT
+ </para>
+ <para>
+ <literal>~1</literal>
+ <returnvalue>-2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integral_type</replaceable> <literal>&lt;&lt;</literal> <type>integer</type>
+ <returnvalue><replaceable>integral_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise shift left
+ </para>
+ <para>
+ <literal>1 &lt;&lt; 4</literal>
+ <returnvalue>16</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integral_type</replaceable> <literal>&gt;&gt;</literal> <type>integer</type>
+ <returnvalue><replaceable>integral_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise shift right
+ </para>
+ <para>
+ <literal>8 &gt;&gt; 2</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-math-func-table"/> shows the available
+ mathematical functions.
+ Many of these functions are provided in multiple forms with different
+ argument types.
+ Except where noted, any given form of a function returns the same
+ data type as its argument(s); cross-type cases are resolved in the
+ same way as explained above for operators.
+ The functions working with <type>double precision</type> data are mostly
+ implemented on top of the host system's C library; accuracy and behavior in
+ boundary cases can therefore vary depending on the host system.
+ </para>
+
+ <table id="functions-math-func-table">
+ <title>Mathematical Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>abs</primary>
+ </indexterm>
+ <function>abs</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Absolute value
+ </para>
+ <para>
+ <literal>abs(-17.4)</literal>
+ <returnvalue>17.4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cbrt</primary>
+ </indexterm>
+ <function>cbrt</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Cube root
+ </para>
+ <para>
+ <literal>cbrt(64.0)</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ceil</primary>
+ </indexterm>
+ <function>ceil</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>ceil</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Nearest integer greater than or equal to argument
+ </para>
+ <para>
+ <literal>ceil(42.2)</literal>
+ <returnvalue>43</returnvalue>
+ </para>
+ <para>
+ <literal>ceil(-42.8)</literal>
+ <returnvalue>-42</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ceiling</primary>
+ </indexterm>
+ <function>ceiling</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>ceiling</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Nearest integer greater than or equal to argument (same
+ as <function>ceil</function>)
+ </para>
+ <para>
+ <literal>ceiling(95.3)</literal>
+ <returnvalue>96</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>degrees</primary>
+ </indexterm>
+ <function>degrees</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Converts radians to degrees
+ </para>
+ <para>
+ <literal>degrees(0.5)</literal>
+ <returnvalue>28.64788975654116</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>div</primary>
+ </indexterm>
+ <function>div</function> ( <parameter>y</parameter> <type>numeric</type>,
+ <parameter>x</parameter> <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Integer quotient of <parameter>y</parameter>/<parameter>x</parameter>
+ (truncates towards zero)
+ </para>
+ <para>
+ <literal>div(9, 4)</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>exp</primary>
+ </indexterm>
+ <function>exp</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>exp</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Exponential (<literal>e</literal> raised to the given power)
+ </para>
+ <para>
+ <literal>exp(1.0)</literal>
+ <returnvalue>2.7182818284590452</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm id="function-factorial">
+ <primary>factorial</primary>
+ </indexterm>
+ <function>factorial</function> ( <type>bigint</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Factorial
+ </para>
+ <para>
+ <literal>factorial(5)</literal>
+ <returnvalue>120</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>floor</primary>
+ </indexterm>
+ <function>floor</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>floor</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Nearest integer less than or equal to argument
+ </para>
+ <para>
+ <literal>floor(42.8)</literal>
+ <returnvalue>42</returnvalue>
+ </para>
+ <para>
+ <literal>floor(-42.8)</literal>
+ <returnvalue>-43</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>gcd</primary>
+ </indexterm>
+ <function>gcd</function> ( <replaceable>numeric_type</replaceable>, <replaceable>numeric_type</replaceable> )
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Greatest common divisor (the largest positive number that divides both
+ inputs with no remainder); returns <literal>0</literal> if both inputs
+ are zero; available for <type>integer</type>, <type>bigint</type>,
+ and <type>numeric</type>
+ </para>
+ <para>
+ <literal>gcd(1071, 462)</literal>
+ <returnvalue>21</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lcm</primary>
+ </indexterm>
+ <function>lcm</function> ( <replaceable>numeric_type</replaceable>, <replaceable>numeric_type</replaceable> )
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Least common multiple (the smallest strictly positive number that is
+ an integral multiple of both inputs); returns <literal>0</literal> if
+ either input is zero; available for <type>integer</type>,
+ <type>bigint</type>, and <type>numeric</type>
+ </para>
+ <para>
+ <literal>lcm(1071, 462)</literal>
+ <returnvalue>23562</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ln</primary>
+ </indexterm>
+ <function>ln</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>ln</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Natural logarithm
+ </para>
+ <para>
+ <literal>ln(2.0)</literal>
+ <returnvalue>0.6931471805599453</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>log</primary>
+ </indexterm>
+ <function>log</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>log</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Base 10 logarithm
+ </para>
+ <para>
+ <literal>log(100)</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>log10</primary>
+ </indexterm>
+ <function>log10</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>log10</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Base 10 logarithm (same as <function>log</function>)
+ </para>
+ <para>
+ <literal>log10(1000)</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>log</function> ( <parameter>b</parameter> <type>numeric</type>,
+ <parameter>x</parameter> <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Logarithm of <parameter>x</parameter> to base <parameter>b</parameter>
+ </para>
+ <para>
+ <literal>log(2.0, 64.0)</literal>
+ <returnvalue>6.0000000000000000</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>min_scale</primary>
+ </indexterm>
+ <function>min_scale</function> ( <type>numeric</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Minimum scale (number of fractional decimal digits) needed
+ to represent the supplied value precisely
+ </para>
+ <para>
+ <literal>min_scale(8.4100)</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>mod</primary>
+ </indexterm>
+ <function>mod</function> ( <parameter>y</parameter> <replaceable>numeric_type</replaceable>,
+ <parameter>x</parameter> <replaceable>numeric_type</replaceable> )
+ <returnvalue><replaceable>numeric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Remainder of <parameter>y</parameter>/<parameter>x</parameter>;
+ available for <type>smallint</type>, <type>integer</type>,
+ <type>bigint</type>, and <type>numeric</type>
+ </para>
+ <para>
+ <literal>mod(9, 4)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pi</primary>
+ </indexterm>
+ <function>pi</function> ( )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Approximate value of <phrase role="symbol_font">&pi;</phrase>
+ </para>
+ <para>
+ <literal>pi()</literal>
+ <returnvalue>3.141592653589793</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>power</primary>
+ </indexterm>
+ <function>power</function> ( <parameter>a</parameter> <type>numeric</type>,
+ <parameter>b</parameter> <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>power</function> ( <parameter>a</parameter> <type>double precision</type>,
+ <parameter>b</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ <parameter>a</parameter> raised to the power of <parameter>b</parameter>
+ </para>
+ <para>
+ <literal>power(9, 3)</literal>
+ <returnvalue>729</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>radians</primary>
+ </indexterm>
+ <function>radians</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Converts degrees to radians
+ </para>
+ <para>
+ <literal>radians(45.0)</literal>
+ <returnvalue>0.7853981633974483</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>round</primary>
+ </indexterm>
+ <function>round</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>round</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Rounds to nearest integer. For <type>numeric</type>, ties are
+ broken by rounding away from zero. For <type>double precision</type>,
+ the tie-breaking behavior is platform dependent, but
+ <quote>round to nearest even</quote> is the most common rule.
+ </para>
+ <para>
+ <literal>round(42.4)</literal>
+ <returnvalue>42</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>round</function> ( <parameter>v</parameter> <type>numeric</type>, <parameter>s</parameter> <type>integer</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Rounds <parameter>v</parameter> to <parameter>s</parameter> decimal
+ places. Ties are broken by rounding away from zero.
+ </para>
+ <para>
+ <literal>round(42.4382, 2)</literal>
+ <returnvalue>42.44</returnvalue>
+ </para>
+ <para>
+ <literal>round(1234.56, -1)</literal>
+ <returnvalue>1230</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>scale</primary>
+ </indexterm>
+ <function>scale</function> ( <type>numeric</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Scale of the argument (the number of decimal digits in the fractional part)
+ </para>
+ <para>
+ <literal>scale(8.4100)</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sign</primary>
+ </indexterm>
+ <function>sign</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sign</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Sign of the argument (-1, 0, or +1)
+ </para>
+ <para>
+ <literal>sign(-8.4)</literal>
+ <returnvalue>-1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sqrt</primary>
+ </indexterm>
+ <function>sqrt</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sqrt</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Square root
+ </para>
+ <para>
+ <literal>sqrt(2)</literal>
+ <returnvalue>1.4142135623730951</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>trim_scale</primary>
+ </indexterm>
+ <function>trim_scale</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Reduces the value's scale (number of fractional decimal digits) by
+ removing trailing zeroes
+ </para>
+ <para>
+ <literal>trim_scale(8.4100)</literal>
+ <returnvalue>8.41</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>trunc</primary>
+ </indexterm>
+ <function>trunc</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>trunc</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Truncates to integer (towards zero)
+ </para>
+ <para>
+ <literal>trunc(42.8)</literal>
+ <returnvalue>42</returnvalue>
+ </para>
+ <para>
+ <literal>trunc(-42.8)</literal>
+ <returnvalue>-42</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>trunc</function> ( <parameter>v</parameter> <type>numeric</type>, <parameter>s</parameter> <type>integer</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Truncates <parameter>v</parameter> to <parameter>s</parameter>
+ decimal places
+ </para>
+ <para>
+ <literal>trunc(42.4382, 2)</literal>
+ <returnvalue>42.43</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>width_bucket</primary>
+ </indexterm>
+ <function>width_bucket</function> ( <parameter>operand</parameter> <type>numeric</type>, <parameter>low</parameter> <type>numeric</type>, <parameter>high</parameter> <type>numeric</type>, <parameter>count</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>width_bucket</function> ( <parameter>operand</parameter> <type>double precision</type>, <parameter>low</parameter> <type>double precision</type>, <parameter>high</parameter> <type>double precision</type>, <parameter>count</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of the bucket in
+ which <parameter>operand</parameter> falls in a histogram
+ having <parameter>count</parameter> equal-width buckets spanning the
+ range <parameter>low</parameter> to <parameter>high</parameter>.
+ Returns <literal>0</literal>
+ or <literal><parameter>count</parameter>+1</literal> for an input
+ outside that range.
+ </para>
+ <para>
+ <literal>width_bucket(5.35, 0.024, 10.06, 5)</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>width_bucket</function> ( <parameter>operand</parameter> <type>anycompatible</type>, <parameter>thresholds</parameter> <type>anycompatiblearray</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of the bucket in
+ which <parameter>operand</parameter> falls given an array listing the
+ lower bounds of the buckets. Returns <literal>0</literal> for an
+ input less than the first lower
+ bound. <parameter>operand</parameter> and the array elements can be
+ of any type having standard comparison operators.
+ The <parameter>thresholds</parameter> array <emphasis>must be
+ sorted</emphasis>, smallest first, or unexpected results will be
+ obtained.
+ </para>
+ <para>
+ <literal>width_bucket(now(), array['yesterday', 'today', 'tomorrow']::timestamptz[])</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-math-random-table"/> shows functions for
+ generating random numbers.
+ </para>
+
+ <table id="functions-math-random-table">
+ <title>Random Functions</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>random</primary>
+ </indexterm>
+ <function>random</function> ( )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Returns a random value in the range 0.0 &lt;= x &lt; 1.0
+ </para>
+ <para>
+ <literal>random()</literal>
+ <returnvalue>0.897124072839091</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>setseed</primary>
+ </indexterm>
+ <function>setseed</function> ( <type>double precision</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Sets the seed for subsequent <literal>random()</literal> calls;
+ argument must be between -1.0 and 1.0, inclusive
+ </para>
+ <para>
+ <literal>setseed(0.12345)</literal>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <function>random()</function> function uses a deterministic
+ pseudo-random number generator.
+ It is fast but not suitable for cryptographic
+ applications; see the <xref linkend="pgcrypto"/> module for a more
+ secure alternative.
+ If <function>setseed()</function> is called, the series of results of
+ subsequent <function>random()</function> calls in the current session
+ can be repeated by re-issuing <function>setseed()</function> with the same
+ argument.
+ Without any prior <function>setseed()</function> call in the same
+ session, the first <function>random()</function> call obtains a seed
+ from a platform-dependent source of random bits.
+ </para>
+
+ <para>
+ <xref linkend="functions-math-trig-table"/> shows the
+ available trigonometric functions. Each of these functions comes in
+ two variants, one that measures angles in radians and one that
+ measures angles in degrees.
+ </para>
+
+ <table id="functions-math-trig-table">
+ <title>Trigonometric Functions</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>acos</primary>
+ </indexterm>
+ <function>acos</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse cosine, result in radians
+ </para>
+ <para>
+ <literal>acos(1)</literal>
+ <returnvalue>0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>acosd</primary>
+ </indexterm>
+ <function>acosd</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse cosine, result in degrees
+ </para>
+ <para>
+ <literal>acosd(0.5)</literal>
+ <returnvalue>60</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>asin</primary>
+ </indexterm>
+ <function>asin</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse sine, result in radians
+ </para>
+ <para>
+ <literal>asin(1)</literal>
+ <returnvalue>1.5707963267948966</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>asind</primary>
+ </indexterm>
+ <function>asind</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse sine, result in degrees
+ </para>
+ <para>
+ <literal>asind(0.5)</literal>
+ <returnvalue>30</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>atan</primary>
+ </indexterm>
+ <function>atan</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse tangent, result in radians
+ </para>
+ <para>
+ <literal>atan(1)</literal>
+ <returnvalue>0.7853981633974483</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>atand</primary>
+ </indexterm>
+ <function>atand</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse tangent, result in degrees
+ </para>
+ <para>
+ <literal>atand(1)</literal>
+ <returnvalue>45</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>atan2</primary>
+ </indexterm>
+ <function>atan2</function> ( <parameter>y</parameter> <type>double precision</type>,
+ <parameter>x</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse tangent of
+ <parameter>y</parameter>/<parameter>x</parameter>,
+ result in radians
+ </para>
+ <para>
+ <literal>atan2(1, 0)</literal>
+ <returnvalue>1.5707963267948966</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>atan2d</primary>
+ </indexterm>
+ <function>atan2d</function> ( <parameter>y</parameter> <type>double precision</type>,
+ <parameter>x</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse tangent of
+ <parameter>y</parameter>/<parameter>x</parameter>,
+ result in degrees
+ </para>
+ <para>
+ <literal>atan2d(1, 0)</literal>
+ <returnvalue>90</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cos</primary>
+ </indexterm>
+ <function>cos</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Cosine, argument in radians
+ </para>
+ <para>
+ <literal>cos(0)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cosd</primary>
+ </indexterm>
+ <function>cosd</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Cosine, argument in degrees
+ </para>
+ <para>
+ <literal>cosd(60)</literal>
+ <returnvalue>0.5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cot</primary>
+ </indexterm>
+ <function>cot</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Cotangent, argument in radians
+ </para>
+ <para>
+ <literal>cot(0.5)</literal>
+ <returnvalue>1.830487721712452</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cotd</primary>
+ </indexterm>
+ <function>cotd</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Cotangent, argument in degrees
+ </para>
+ <para>
+ <literal>cotd(45)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sin</primary>
+ </indexterm>
+ <function>sin</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Sine, argument in radians
+ </para>
+ <para>
+ <literal>sin(1)</literal>
+ <returnvalue>0.8414709848078965</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sind</primary>
+ </indexterm>
+ <function>sind</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Sine, argument in degrees
+ </para>
+ <para>
+ <literal>sind(30)</literal>
+ <returnvalue>0.5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tan</primary>
+ </indexterm>
+ <function>tan</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Tangent, argument in radians
+ </para>
+ <para>
+ <literal>tan(1)</literal>
+ <returnvalue>1.5574077246549023</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tand</primary>
+ </indexterm>
+ <function>tand</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Tangent, argument in degrees
+ </para>
+ <para>
+ <literal>tand(45)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ Another way to work with angles measured in degrees is to use the unit
+ transformation functions <literal><function>radians()</function></literal>
+ and <literal><function>degrees()</function></literal> shown earlier.
+ However, using the degree-based trigonometric functions is preferred,
+ as that way avoids round-off error for special cases such
+ as <literal>sind(30)</literal>.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="functions-math-hyp-table"/> shows the
+ available hyperbolic functions.
+ </para>
+
+ <table id="functions-math-hyp-table">
+ <title>Hyperbolic Functions</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sinh</primary>
+ </indexterm>
+ <function>sinh</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Hyperbolic sine
+ </para>
+ <para>
+ <literal>sinh(1)</literal>
+ <returnvalue>1.1752011936438014</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cosh</primary>
+ </indexterm>
+ <function>cosh</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Hyperbolic cosine
+ </para>
+ <para>
+ <literal>cosh(0)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tanh</primary>
+ </indexterm>
+ <function>tanh</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Hyperbolic tangent
+ </para>
+ <para>
+ <literal>tanh(1)</literal>
+ <returnvalue>0.7615941559557649</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>asinh</primary>
+ </indexterm>
+ <function>asinh</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse hyperbolic sine
+ </para>
+ <para>
+ <literal>asinh(1)</literal>
+ <returnvalue>0.881373587019543</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>acosh</primary>
+ </indexterm>
+ <function>acosh</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse hyperbolic cosine
+ </para>
+ <para>
+ <literal>acosh(1)</literal>
+ <returnvalue>0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>atanh</primary>
+ </indexterm>
+ <function>atanh</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Inverse hyperbolic tangent
+ </para>
+ <para>
+ <literal>atanh(0.5)</literal>
+ <returnvalue>0.5493061443340548</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="functions-string">
+ <title>String Functions and Operators</title>
+
+ <para>
+ This section describes functions and operators for examining and
+ manipulating string values. Strings in this context include values
+ of the types <type>character</type>, <type>character varying</type>,
+ and <type>text</type>. Except where noted, these functions and operators
+ are declared to accept and return type <type>text</type>. They will
+ interchangeably accept <type>character varying</type> arguments.
+ Values of type <type>character</type> will be converted
+ to <type>text</type> before the function or operator is applied, resulting
+ in stripping any trailing spaces in the <type>character</type> value.
+ </para>
+
+ <para>
+ <acronym>SQL</acronym> defines some string functions that use
+ key words, rather than commas, to separate
+ arguments. Details are in
+ <xref linkend="functions-string-sql"/>.
+ <productname>PostgreSQL</productname> also provides versions of these functions
+ that use the regular function invocation syntax
+ (see <xref linkend="functions-string-other"/>).
+ </para>
+
+ <note>
+ <para>
+ The string concatenation operator (<literal>||</literal>) will accept
+ non-string input, so long as at least one input is of string type, as shown
+ in <xref linkend="functions-string-sql"/>. For other cases, inserting an
+ explicit coercion to <type>text</type> can be used to have non-string input
+ accepted.
+ </para>
+ </note>
+
+ <table id="functions-string-sql">
+ <title><acronym>SQL</acronym> String Functions and Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function/Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>character string</primary>
+ <secondary>concatenation</secondary>
+ </indexterm>
+ <type>text</type> <literal>||</literal> <type>text</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Concatenates the two strings.
+ </para>
+ <para>
+ <literal>'Post' || 'greSQL'</literal>
+ <returnvalue>PostgreSQL</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>||</literal> <type>anynonarray</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>anynonarray</type> <literal>||</literal> <type>text</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the non-string input to text, then concatenates the two
+ strings. (The non-string input cannot be of an array type, because
+ that would create ambiguity with the array <literal>||</literal>
+ operators. If you want to concatenate an array's text equivalent,
+ cast it to <type>text</type> explicitly.)
+ </para>
+ <para>
+ <literal>'Value: ' || 42</literal>
+ <returnvalue>Value: 42</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>normalized</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Unicode normalization</primary>
+ </indexterm>
+ <type>text</type> <literal>IS</literal> <optional><literal>NOT</literal></optional> <optional><parameter>form</parameter></optional> <literal>NORMALIZED</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Checks whether the string is in the specified Unicode normalization
+ form. The optional <parameter>form</parameter> key word specifies the
+ form: <literal>NFC</literal> (the default), <literal>NFD</literal>,
+ <literal>NFKC</literal>, or <literal>NFKD</literal>. This expression can
+ only be used when the server encoding is <literal>UTF8</literal>. Note
+ that checking for normalization using this expression is often faster
+ than normalizing possibly already normalized strings.
+ </para>
+ <para>
+ <literal>U&amp;'\0061\0308bc' IS NFD NORMALIZED</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_length</primary>
+ </indexterm>
+ <function>bit_length</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bits in the string (8
+ times the <function>octet_length</function>).
+ </para>
+ <para>
+ <literal>bit_length('jose')</literal>
+ <returnvalue>32</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>char_length</primary>
+ </indexterm>
+ <indexterm>
+ <primary>character string</primary>
+ <secondary>length</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>length</primary>
+ <secondary sortas="character string">of a character string</secondary>
+ <see>character string, length</see>
+ </indexterm>
+ <function>char_length</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>character_length</primary>
+ </indexterm>
+ <function>character_length</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of characters in the string.
+ </para>
+ <para>
+ <literal>char_length('jos&eacute;')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower</primary>
+ </indexterm>
+ <function>lower</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the string to all lower case, according to the rules of the
+ database's locale.
+ </para>
+ <para>
+ <literal>lower('TOM')</literal>
+ <returnvalue>tom</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>normalize</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Unicode normalization</primary>
+ </indexterm>
+ <function>normalize</function> ( <type>text</type>
+ <optional>, <parameter>form</parameter> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the string to the specified Unicode
+ normalization form. The optional <parameter>form</parameter> key word
+ specifies the form: <literal>NFC</literal> (the default),
+ <literal>NFD</literal>, <literal>NFKC</literal>, or
+ <literal>NFKD</literal>. This function can only be used when the
+ server encoding is <literal>UTF8</literal>.
+ </para>
+ <para>
+ <literal>normalize(U&amp;'\0061\0308bc', NFC)</literal>
+ <returnvalue>U&amp;'\00E4bc'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>octet_length</primary>
+ </indexterm>
+ <function>octet_length</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bytes in the string.
+ </para>
+ <para>
+ <literal>octet_length('jos&eacute;')</literal>
+ <returnvalue>5</returnvalue> (if server encoding is UTF8)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>octet_length</primary>
+ </indexterm>
+ <function>octet_length</function> ( <type>character</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bytes in the string. Since this version of the
+ function accepts type <type>character</type> directly, it will not
+ strip trailing spaces.
+ </para>
+ <para>
+ <literal>octet_length('abc '::character(4))</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>overlay</primary>
+ </indexterm>
+ <function>overlay</function> ( <parameter>string</parameter> <type>text</type> <literal>PLACING</literal> <parameter>newsubstring</parameter> <type>text</type> <literal>FROM</literal> <parameter>start</parameter> <type>integer</type> <optional> <literal>FOR</literal> <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Replaces the substring of <parameter>string</parameter> that starts at
+ the <parameter>start</parameter>'th character and extends
+ for <parameter>count</parameter> characters
+ with <parameter>newsubstring</parameter>.
+ If <parameter>count</parameter> is omitted, it defaults to the length
+ of <parameter>newsubstring</parameter>.
+ </para>
+ <para>
+ <literal>overlay('Txxxxas' placing 'hom' from 2 for 4)</literal>
+ <returnvalue>Thomas</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>position</primary>
+ </indexterm>
+ <function>position</function> ( <parameter>substring</parameter> <type>text</type> <literal>IN</literal> <parameter>string</parameter> <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns first starting index of the specified
+ <parameter>substring</parameter> within
+ <parameter>string</parameter>, or zero if it's not present.
+ </para>
+ <para>
+ <literal>position('om' in 'Thomas')</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>substring</primary>
+ </indexterm>
+ <function>substring</function> ( <parameter>string</parameter> <type>text</type> <optional> <literal>FROM</literal> <parameter>start</parameter> <type>integer</type> </optional> <optional> <literal>FOR</literal> <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts the substring of <parameter>string</parameter> starting at
+ the <parameter>start</parameter>'th character if that is specified,
+ and stopping after <parameter>count</parameter> characters if that is
+ specified. Provide at least one of <parameter>start</parameter>
+ and <parameter>count</parameter>.
+ </para>
+ <para>
+ <literal>substring('Thomas' from 2 for 3)</literal>
+ <returnvalue>hom</returnvalue>
+ </para>
+ <para>
+ <literal>substring('Thomas' from 3)</literal>
+ <returnvalue>omas</returnvalue>
+ </para>
+ <para>
+ <literal>substring('Thomas' for 2)</literal>
+ <returnvalue>Th</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>substring</function> ( <parameter>string</parameter> <type>text</type> <literal>FROM</literal> <parameter>pattern</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts the first substring matching POSIX regular expression; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>substring('Thomas' from '...$')</literal>
+ <returnvalue>mas</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>substring</function> ( <parameter>string</parameter> <type>text</type> <literal>SIMILAR</literal> <parameter>pattern</parameter> <type>text</type> <literal>ESCAPE</literal> <parameter>escape</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>substring</function> ( <parameter>string</parameter> <type>text</type> <literal>FROM</literal> <parameter>pattern</parameter> <type>text</type> <literal>FOR</literal> <parameter>escape</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts the first substring matching <acronym>SQL</acronym> regular expression;
+ see <xref linkend="functions-similarto-regexp"/>. The first form has
+ been specified since SQL:2003; the second form was only in SQL:1999
+ and should be considered obsolete.
+ </para>
+ <para>
+ <literal>substring('Thomas' similar '%#"o_a#"_' escape '#')</literal>
+ <returnvalue>oma</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>trim</primary>
+ </indexterm>
+ <function>trim</function> ( <optional> <literal>LEADING</literal> | <literal>TRAILING</literal> | <literal>BOTH</literal> </optional>
+ <optional> <parameter>characters</parameter> <type>text</type> </optional> <literal>FROM</literal>
+ <parameter>string</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only characters in
+ <parameter>characters</parameter> (a space by default) from the
+ start, end, or both ends (<literal>BOTH</literal> is the default)
+ of <parameter>string</parameter>.
+ </para>
+ <para>
+ <literal>trim(both 'xyz' from 'yxTomxx')</literal>
+ <returnvalue>Tom</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>trim</function> ( <optional> <literal>LEADING</literal> | <literal>TRAILING</literal> | <literal>BOTH</literal> </optional> <optional> <literal>FROM</literal> </optional>
+ <parameter>string</parameter> <type>text</type> <optional>,
+ <parameter>characters</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ This is a non-standard syntax for <function>trim()</function>.
+ </para>
+ <para>
+ <literal>trim(both from 'yxTomxx', 'xyz')</literal>
+ <returnvalue>Tom</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper</primary>
+ </indexterm>
+ <function>upper</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the string to all upper case, according to the rules of the
+ database's locale.
+ </para>
+ <para>
+ <literal>upper('tom')</literal>
+ <returnvalue>TOM</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Additional string manipulation functions and operators are available
+ and are listed in <xref linkend="functions-string-other"/>. (Some of
+ these are used internally to implement
+ the <acronym>SQL</acronym>-standard string functions listed in
+ <xref linkend="functions-string-sql"/>.)
+ There are also pattern-matching operators, which are described in
+ <xref linkend="functions-matching"/>, and operators for full-text
+ search, which are described in <xref linkend="textsearch"/>.
+ </para>
+
+ <table id="functions-string-other">
+ <title>Other String Functions and Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function/Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>character string</primary>
+ <secondary>prefix test</secondary>
+ </indexterm>
+ <type>text</type> <literal>^@</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if the first string starts with the second string
+ (equivalent to the <function>starts_with()</function> function).
+ </para>
+ <para>
+ <literal>'alphabet' ^@ 'alph'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ascii</primary>
+ </indexterm>
+ <function>ascii</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the numeric code of the first character of the argument.
+ In <acronym>UTF8</acronym> encoding, returns the Unicode code point
+ of the character. In other multibyte encodings, the argument must
+ be an <acronym>ASCII</acronym> character.
+ </para>
+ <para>
+ <literal>ascii('x')</literal>
+ <returnvalue>120</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>btrim</primary>
+ </indexterm>
+ <function>btrim</function> ( <parameter>string</parameter> <type>text</type>
+ <optional>, <parameter>characters</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only characters
+ in <parameter>characters</parameter> (a space by default)
+ from the start and end of <parameter>string</parameter>.
+ </para>
+ <para>
+ <literal>btrim('xyxtrimyyx', 'xyz')</literal>
+ <returnvalue>trim</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>chr</primary>
+ </indexterm>
+ <function>chr</function> ( <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the character with the given code. In <acronym>UTF8</acronym>
+ encoding the argument is treated as a Unicode code point. In other
+ multibyte encodings the argument must designate
+ an <acronym>ASCII</acronym> character. <literal>chr(0)</literal> is
+ disallowed because text data types cannot store that character.
+ </para>
+ <para>
+ <literal>chr(65)</literal>
+ <returnvalue>A</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>concat</primary>
+ </indexterm>
+ <function>concat</function> ( <parameter>val1</parameter> <type>"any"</type>
+ [, <parameter>val2</parameter> <type>"any"</type> [, ...] ] )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Concatenates the text representations of all the arguments.
+ NULL arguments are ignored.
+ </para>
+ <para>
+ <literal>concat('abcde', 2, NULL, 22)</literal>
+ <returnvalue>abcde222</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>concat_ws</primary>
+ </indexterm>
+ <function>concat_ws</function> ( <parameter>sep</parameter> <type>text</type>,
+ <parameter>val1</parameter> <type>"any"</type>
+ [, <parameter>val2</parameter> <type>"any"</type> [, ...] ] )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Concatenates all but the first argument, with separators. The first
+ argument is used as the separator string, and should not be NULL.
+ Other NULL arguments are ignored.
+ </para>
+ <para>
+ <literal>concat_ws(',', 'abcde', 2, NULL, 22)</literal>
+ <returnvalue>abcde,2,22</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>format</primary>
+ </indexterm>
+ <function>format</function> ( <parameter>formatstr</parameter> <type>text</type>
+ [, <parameter>formatarg</parameter> <type>"any"</type> [, ...] ] )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Formats arguments according to a format string;
+ see <xref linkend="functions-string-format"/>.
+ This function is similar to the C function <function>sprintf</function>.
+ </para>
+ <para>
+ <literal>format('Hello %s, %1$s', 'World')</literal>
+ <returnvalue>Hello World, World</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>initcap</primary>
+ </indexterm>
+ <function>initcap</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the first letter of each word to upper case and the
+ rest to lower case. Words are sequences of alphanumeric
+ characters separated by non-alphanumeric characters.
+ </para>
+ <para>
+ <literal>initcap('hi THOMAS')</literal>
+ <returnvalue>Hi Thomas</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>left</primary>
+ </indexterm>
+ <function>left</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns first <parameter>n</parameter> characters in the
+ string, or when <parameter>n</parameter> is negative, returns
+ all but last |<parameter>n</parameter>| characters.
+ </para>
+ <para>
+ <literal>left('abcde', 2)</literal>
+ <returnvalue>ab</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>length</primary>
+ </indexterm>
+ <function>length</function> ( <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of characters in the string.
+ </para>
+ <para>
+ <literal>length('jose')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lpad</primary>
+ </indexterm>
+ <function>lpad</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>length</parameter> <type>integer</type>
+ <optional>, <parameter>fill</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extends the <parameter>string</parameter> to length
+ <parameter>length</parameter> by prepending the characters
+ <parameter>fill</parameter> (a space by default). If the
+ <parameter>string</parameter> is already longer than
+ <parameter>length</parameter> then it is truncated (on the right).
+ </para>
+ <para>
+ <literal>lpad('hi', 5, 'xy')</literal>
+ <returnvalue>xyxhi</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ltrim</primary>
+ </indexterm>
+ <function>ltrim</function> ( <parameter>string</parameter> <type>text</type>
+ <optional>, <parameter>characters</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only characters in
+ <parameter>characters</parameter> (a space by default) from the start of
+ <parameter>string</parameter>.
+ </para>
+ <para>
+ <literal>ltrim('zzzytest', 'xyz')</literal>
+ <returnvalue>test</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>md5</primary>
+ </indexterm>
+ <function>md5</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Computes the MD5 <link linkend="functions-hash-note">hash</link> of
+ the argument, with the result written in hexadecimal.
+ </para>
+ <para>
+ <literal>md5('abc')</literal>
+ <returnvalue>900150983cd24fb0&zwsp;d6963f7d28e17f72</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>parse_ident</primary>
+ </indexterm>
+ <function>parse_ident</function> ( <parameter>qualified_identifier</parameter> <type>text</type>
+ [, <parameter>strict_mode</parameter> <type>boolean</type> <literal>DEFAULT</literal> <literal>true</literal> ] )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Splits <parameter>qualified_identifier</parameter> into an array of
+ identifiers, removing any quoting of individual identifiers. By
+ default, extra characters after the last identifier are considered an
+ error; but if the second parameter is <literal>false</literal>, then such
+ extra characters are ignored. (This behavior is useful for parsing
+ names for objects like functions.) Note that this function does not
+ truncate over-length identifiers. If you want truncation you can cast
+ the result to <type>name[]</type>.
+ </para>
+ <para>
+ <literal>parse_ident('"SomeSchema".someTable')</literal>
+ <returnvalue>{SomeSchema,sometable}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_client_encoding</primary>
+ </indexterm>
+ <function>pg_client_encoding</function> ( )
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Returns current client encoding name.
+ </para>
+ <para>
+ <literal>pg_client_encoding()</literal>
+ <returnvalue>UTF8</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>quote_ident</primary>
+ </indexterm>
+ <function>quote_ident</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the given string suitably quoted to be used as an identifier
+ in an <acronym>SQL</acronym> statement string.
+ Quotes are added only if necessary (i.e., if the string contains
+ non-identifier characters or would be case-folded).
+ Embedded quotes are properly doubled.
+ See also <xref linkend="plpgsql-quote-literal-example"/>.
+ </para>
+ <para>
+ <literal>quote_ident('Foo bar')</literal>
+ <returnvalue>"Foo bar"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>quote_literal</primary>
+ </indexterm>
+ <function>quote_literal</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the given string suitably quoted to be used as a string literal
+ in an <acronym>SQL</acronym> statement string.
+ Embedded single-quotes and backslashes are properly doubled.
+ Note that <function>quote_literal</function> returns null on null
+ input; if the argument might be null,
+ <function>quote_nullable</function> is often more suitable.
+ See also <xref linkend="plpgsql-quote-literal-example"/>.
+ </para>
+ <para>
+ <literal>quote_literal(E'O\'Reilly')</literal>
+ <returnvalue>'O''Reilly'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>quote_literal</function> ( <type>anyelement</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the given value to text and then quotes it as a literal.
+ Embedded single-quotes and backslashes are properly doubled.
+ </para>
+ <para>
+ <literal>quote_literal(42.5)</literal>
+ <returnvalue>'42.5'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>quote_nullable</primary>
+ </indexterm>
+ <function>quote_nullable</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the given string suitably quoted to be used as a string literal
+ in an <acronym>SQL</acronym> statement string; or, if the argument
+ is null, returns <literal>NULL</literal>.
+ Embedded single-quotes and backslashes are properly doubled.
+ See also <xref linkend="plpgsql-quote-literal-example"/>.
+ </para>
+ <para>
+ <literal>quote_nullable(NULL)</literal>
+ <returnvalue>NULL</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>quote_nullable</function> ( <type>anyelement</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the given value to text and then quotes it as a literal;
+ or, if the argument is null, returns <literal>NULL</literal>.
+ Embedded single-quotes and backslashes are properly doubled.
+ </para>
+ <para>
+ <literal>quote_nullable(42.5)</literal>
+ <returnvalue>'42.5'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_count</primary>
+ </indexterm>
+ <function>regexp_count</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type>
+ [, <parameter>start</parameter> <type>integer</type>
+ [, <parameter>flags</parameter> <type>text</type> ] ] )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of times the POSIX regular
+ expression <parameter>pattern</parameter> matches in
+ the <parameter>string</parameter>; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_count('123456789012', '\d\d\d', 2)</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_instr</primary>
+ </indexterm>
+ <function>regexp_instr</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type>
+ [, <parameter>start</parameter> <type>integer</type>
+ [, <parameter>N</parameter> <type>integer</type>
+ [, <parameter>endoption</parameter> <type>integer</type>
+ [, <parameter>flags</parameter> <type>text</type>
+ [, <parameter>subexpr</parameter> <type>integer</type> ] ] ] ] ] )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the position within <parameter>string</parameter> where
+ the <parameter>N</parameter>'th match of the POSIX regular
+ expression <parameter>pattern</parameter> occurs, or zero if there is
+ no such match; see <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i')</literal>
+ <returnvalue>3</returnvalue>
+ </para>
+ <para>
+ <literal>regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i', 2)</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_like</primary>
+ </indexterm>
+ <function>regexp_like</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type>
+ [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Checks whether a match of the POSIX regular
+ expression <parameter>pattern</parameter> occurs
+ within <parameter>string</parameter>; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_like('Hello World', 'world$', 'i')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_match</primary>
+ </indexterm>
+ <function>regexp_match</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type> [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Returns substrings within the first match of the POSIX regular
+ expression <parameter>pattern</parameter> to
+ the <parameter>string</parameter>; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_match('foobarbequebaz', '(bar)(beque)')</literal>
+ <returnvalue>{bar,beque}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_matches</primary>
+ </indexterm>
+ <function>regexp_matches</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type> [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>setof text[]</returnvalue>
+ </para>
+ <para>
+ Returns substrings within the first match of the POSIX regular
+ expression <parameter>pattern</parameter> to
+ the <parameter>string</parameter>, or substrings within all
+ such matches if the <literal>g</literal> flag is used;
+ see <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_matches('foobarbequebaz', 'ba.', 'g')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ {bar}
+ {baz}
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_replace</primary>
+ </indexterm>
+ <function>regexp_replace</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type>, <parameter>replacement</parameter> <type>text</type>
+ [, <parameter>start</parameter> <type>integer</type> ]
+ [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Replaces the substring that is the first match to the POSIX
+ regular expression <parameter>pattern</parameter>, or all such
+ matches if the <literal>g</literal> flag is used; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_replace('Thomas', '.[mN]a.', 'M')</literal>
+ <returnvalue>ThM</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>regexp_replace</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type>, <parameter>replacement</parameter> <type>text</type>,
+ <parameter>start</parameter> <type>integer</type>,
+ <parameter>N</parameter> <type>integer</type>
+ [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Replaces the substring that is the <parameter>N</parameter>'th
+ match to the POSIX regular expression <parameter>pattern</parameter>,
+ or all such matches if <parameter>N</parameter> is zero; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_replace('Thomas', '.', 'X', 3, 2)</literal>
+ <returnvalue>ThoXas</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_split_to_array</primary>
+ </indexterm>
+ <function>regexp_split_to_array</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type> [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Splits <parameter>string</parameter> using a POSIX regular
+ expression as the delimiter, producing an array of results; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_split_to_array('hello world', '\s+')</literal>
+ <returnvalue>{hello,world}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_split_to_table</primary>
+ </indexterm>
+ <function>regexp_split_to_table</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type> [, <parameter>flags</parameter> <type>text</type> ] )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Splits <parameter>string</parameter> using a POSIX regular
+ expression as the delimiter, producing a set of results; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_split_to_table('hello world', '\s+')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ hello
+ world
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regexp_substr</primary>
+ </indexterm>
+ <function>regexp_substr</function> ( <parameter>string</parameter> <type>text</type>, <parameter>pattern</parameter> <type>text</type>
+ [, <parameter>start</parameter> <type>integer</type>
+ [, <parameter>N</parameter> <type>integer</type>
+ [, <parameter>flags</parameter> <type>text</type>
+ [, <parameter>subexpr</parameter> <type>integer</type> ] ] ] ] )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the substring within <parameter>string</parameter> that
+ matches the <parameter>N</parameter>'th occurrence of the POSIX
+ regular expression <parameter>pattern</parameter>,
+ or <literal>NULL</literal> if there is no such match; see
+ <xref linkend="functions-posix-regexp"/>.
+ </para>
+ <para>
+ <literal>regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i')</literal>
+ <returnvalue>CDEF</returnvalue>
+ </para>
+ <para>
+ <literal>regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i', 2)</literal>
+ <returnvalue>EF</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>repeat</primary>
+ </indexterm>
+ <function>repeat</function> ( <parameter>string</parameter> <type>text</type>, <parameter>number</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Repeats <parameter>string</parameter> the specified
+ <parameter>number</parameter> of times.
+ </para>
+ <para>
+ <literal>repeat('Pg', 4)</literal>
+ <returnvalue>PgPgPgPg</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>replace</primary>
+ </indexterm>
+ <function>replace</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>from</parameter> <type>text</type>,
+ <parameter>to</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Replaces all occurrences in <parameter>string</parameter> of
+ substring <parameter>from</parameter> with
+ substring <parameter>to</parameter>.
+ </para>
+ <para>
+ <literal>replace('abcdefabcdef', 'cd', 'XX')</literal>
+ <returnvalue>abXXefabXXef</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>reverse</primary>
+ </indexterm>
+ <function>reverse</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reverses the order of the characters in the string.
+ </para>
+ <para>
+ <literal>reverse('abcde')</literal>
+ <returnvalue>edcba</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>right</primary>
+ </indexterm>
+ <function>right</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns last <parameter>n</parameter> characters in the string,
+ or when <parameter>n</parameter> is negative, returns all but
+ first |<parameter>n</parameter>| characters.
+ </para>
+ <para>
+ <literal>right('abcde', 2)</literal>
+ <returnvalue>de</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>rpad</primary>
+ </indexterm>
+ <function>rpad</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>length</parameter> <type>integer</type>
+ <optional>, <parameter>fill</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extends the <parameter>string</parameter> to length
+ <parameter>length</parameter> by appending the characters
+ <parameter>fill</parameter> (a space by default). If the
+ <parameter>string</parameter> is already longer than
+ <parameter>length</parameter> then it is truncated.
+ </para>
+ <para>
+ <literal>rpad('hi', 5, 'xy')</literal>
+ <returnvalue>hixyx</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>rtrim</primary>
+ </indexterm>
+ <function>rtrim</function> ( <parameter>string</parameter> <type>text</type>
+ <optional>, <parameter>characters</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only characters in
+ <parameter>characters</parameter> (a space by default) from the end of
+ <parameter>string</parameter>.
+ </para>
+ <para>
+ <literal>rtrim('testxxzx', 'xyz')</literal>
+ <returnvalue>test</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>split_part</primary>
+ </indexterm>
+ <function>split_part</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>delimiter</parameter> <type>text</type>,
+ <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Splits <parameter>string</parameter> at occurrences
+ of <parameter>delimiter</parameter> and returns
+ the <parameter>n</parameter>'th field (counting from one),
+ or when <parameter>n</parameter> is negative, returns
+ the |<parameter>n</parameter>|'th-from-last field.
+ </para>
+ <para>
+ <literal>split_part('abc~@~def~@~ghi', '~@~', 2)</literal>
+ <returnvalue>def</returnvalue>
+ </para>
+ <para>
+ <literal>split_part('abc,def,ghi,jkl', ',', -2)</literal>
+ <returnvalue>ghi</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>starts_with</primary>
+ </indexterm>
+ <function>starts_with</function> ( <parameter>string</parameter> <type>text</type>, <parameter>prefix</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if <parameter>string</parameter> starts
+ with <parameter>prefix</parameter>.
+ </para>
+ <para>
+ <literal>starts_with('alphabet', 'alph')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm id="function-string-to-array">
+ <primary>string_to_array</primary>
+ </indexterm>
+ <function>string_to_array</function> ( <parameter>string</parameter> <type>text</type>, <parameter>delimiter</parameter> <type>text</type> <optional>, <parameter>null_string</parameter> <type>text</type> </optional> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Splits the <parameter>string</parameter> at occurrences
+ of <parameter>delimiter</parameter> and forms the resulting fields
+ into a <type>text</type> array.
+ If <parameter>delimiter</parameter> is <literal>NULL</literal>,
+ each character in the <parameter>string</parameter> will become a
+ separate element in the array.
+ If <parameter>delimiter</parameter> is an empty string, then
+ the <parameter>string</parameter> is treated as a single field.
+ If <parameter>null_string</parameter> is supplied and is
+ not <literal>NULL</literal>, fields matching that string are
+ replaced by <literal>NULL</literal>.
+ See also <link linkend="function-array-to-string"><function>array_to_string</function></link>.
+ </para>
+ <para>
+ <literal>string_to_array('xx~~yy~~zz', '~~', 'yy')</literal>
+ <returnvalue>{xx,NULL,zz}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>string_to_table</primary>
+ </indexterm>
+ <function>string_to_table</function> ( <parameter>string</parameter> <type>text</type>, <parameter>delimiter</parameter> <type>text</type> <optional>, <parameter>null_string</parameter> <type>text</type> </optional> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Splits the <parameter>string</parameter> at occurrences
+ of <parameter>delimiter</parameter> and returns the resulting fields
+ as a set of <type>text</type> rows.
+ If <parameter>delimiter</parameter> is <literal>NULL</literal>,
+ each character in the <parameter>string</parameter> will become a
+ separate row of the result.
+ If <parameter>delimiter</parameter> is an empty string, then
+ the <parameter>string</parameter> is treated as a single field.
+ If <parameter>null_string</parameter> is supplied and is
+ not <literal>NULL</literal>, fields matching that string are
+ replaced by <literal>NULL</literal>.
+ </para>
+ <para>
+ <literal>string_to_table('xx~^~yy~^~zz', '~^~', 'yy')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ xx
+ NULL
+ zz
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>strpos</primary>
+ </indexterm>
+ <function>strpos</function> ( <parameter>string</parameter> <type>text</type>, <parameter>substring</parameter> <type>text</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns first starting index of the specified <parameter>substring</parameter>
+ within <parameter>string</parameter>, or zero if it's not present.
+ (Same as <literal>position(<parameter>substring</parameter> in
+ <parameter>string</parameter>)</literal>, but note the reversed
+ argument order.)
+ </para>
+ <para>
+ <literal>strpos('high', 'ig')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>substr</primary>
+ </indexterm>
+ <function>substr</function> ( <parameter>string</parameter> <type>text</type>, <parameter>start</parameter> <type>integer</type> <optional>, <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts the substring of <parameter>string</parameter> starting at
+ the <parameter>start</parameter>'th character,
+ and extending for <parameter>count</parameter> characters if that is
+ specified. (Same
+ as <literal>substring(<parameter>string</parameter>
+ from <parameter>start</parameter>
+ for <parameter>count</parameter>)</literal>.)
+ </para>
+ <para>
+ <literal>substr('alphabet', 3)</literal>
+ <returnvalue>phabet</returnvalue>
+ </para>
+ <para>
+ <literal>substr('alphabet', 3, 2)</literal>
+ <returnvalue>ph</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_ascii</primary>
+ </indexterm>
+ <function>to_ascii</function> ( <parameter>string</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>to_ascii</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>encoding</parameter> <type>name</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>to_ascii</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>encoding</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts <parameter>string</parameter> to <acronym>ASCII</acronym>
+ from another encoding, which may be identified by name or number.
+ If <parameter>encoding</parameter> is omitted the database encoding
+ is assumed (which in practice is the only useful case).
+ The conversion consists primarily of dropping accents.
+ Conversion is only supported
+ from <literal>LATIN1</literal>, <literal>LATIN2</literal>,
+ <literal>LATIN9</literal>, and <literal>WIN1250</literal> encodings.
+ (See the <xref linkend="unaccent"/> module for another, more flexible
+ solution.)
+ </para>
+ <para>
+ <literal>to_ascii('Kar&eacute;l')</literal>
+ <returnvalue>Karel</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_hex</primary>
+ </indexterm>
+ <function>to_hex</function> ( <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>to_hex</function> ( <type>bigint</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the number to its equivalent hexadecimal representation.
+ </para>
+ <para>
+ <literal>to_hex(2147483647)</literal>
+ <returnvalue>7fffffff</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>translate</primary>
+ </indexterm>
+ <function>translate</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>from</parameter> <type>text</type>,
+ <parameter>to</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Replaces each character in <parameter>string</parameter> that
+ matches a character in the <parameter>from</parameter> set with the
+ corresponding character in the <parameter>to</parameter>
+ set. If <parameter>from</parameter> is longer than
+ <parameter>to</parameter>, occurrences of the extra characters in
+ <parameter>from</parameter> are deleted.
+ </para>
+ <para>
+ <literal>translate('12345', '143', 'ax')</literal>
+ <returnvalue>a2x5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>unistr</primary>
+ </indexterm>
+ <function>unistr</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Evaluate escaped Unicode characters in the argument. Unicode characters
+ can be specified as
+ <literal>\<replaceable>XXXX</replaceable></literal> (4 hexadecimal
+ digits), <literal>\+<replaceable>XXXXXX</replaceable></literal> (6
+ hexadecimal digits),
+ <literal>\u<replaceable>XXXX</replaceable></literal> (4 hexadecimal
+ digits), or <literal>\U<replaceable>XXXXXXXX</replaceable></literal>
+ (8 hexadecimal digits). To specify a backslash, write two
+ backslashes. All other characters are taken literally.
+ </para>
+
+ <para>
+ If the server encoding is not UTF-8, the Unicode code point identified
+ by one of these escape sequences is converted to the actual server
+ encoding; an error is reported if that's not possible.
+ </para>
+
+ <para>
+ This function provides a (non-standard) alternative to string
+ constants with Unicode escapes (see <xref
+ linkend="sql-syntax-strings-uescape"/>).
+ </para>
+
+ <para>
+ <literal>unistr('d\0061t\+000061')</literal>
+ <returnvalue>data</returnvalue>
+ </para>
+ <para>
+ <literal>unistr('d\u0061t\U00000061')</literal>
+ <returnvalue>data</returnvalue>
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <function>concat</function>, <function>concat_ws</function> and
+ <function>format</function> functions are variadic, so it is possible to
+ pass the values to be concatenated or formatted as an array marked with
+ the <literal>VARIADIC</literal> keyword (see <xref
+ linkend="xfunc-sql-variadic-functions"/>). The array's elements are
+ treated as if they were separate ordinary arguments to the function.
+ If the variadic array argument is NULL, <function>concat</function>
+ and <function>concat_ws</function> return NULL, but
+ <function>format</function> treats a NULL as a zero-element array.
+ </para>
+
+ <para>
+ See also the aggregate function <function>string_agg</function> in
+ <xref linkend="functions-aggregate"/>, and the functions for
+ converting between strings and the <type>bytea</type> type in
+ <xref linkend="functions-binarystring-conversions"/>.
+ </para>
+
+ <sect2 id="functions-string-format">
+ <title><function>format</function></title>
+
+ <indexterm>
+ <primary>format</primary>
+ </indexterm>
+
+ <para>
+ The function <function>format</function> produces output formatted according to
+ a format string, in a style similar to the C function
+ <function>sprintf</function>.
+ </para>
+
+ <para>
+<synopsis>
+<function>format</function>(<parameter>formatstr</parameter> <type>text</type> [, <parameter>formatarg</parameter> <type>"any"</type> [, ...] ])
+</synopsis>
+ <parameter>formatstr</parameter> is a format string that specifies how the
+ result should be formatted. Text in the format string is copied
+ directly to the result, except where <firstterm>format specifiers</firstterm> are
+ used. Format specifiers act as placeholders in the string, defining how
+ subsequent function arguments should be formatted and inserted into the
+ result. Each <parameter>formatarg</parameter> argument is converted to text
+ according to the usual output rules for its data type, and then formatted
+ and inserted into the result string according to the format specifier(s).
+ </para>
+
+ <para>
+ Format specifiers are introduced by a <literal>%</literal> character and have
+ the form
+<synopsis>
+%[<parameter>position</parameter>][<parameter>flags</parameter>][<parameter>width</parameter>]<parameter>type</parameter>
+</synopsis>
+ where the component fields are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>position</parameter> (optional)</term>
+ <listitem>
+ <para>
+ A string of the form <literal><parameter>n</parameter>$</literal> where
+ <parameter>n</parameter> is the index of the argument to print.
+ Index 1 means the first argument after
+ <parameter>formatstr</parameter>. If the <parameter>position</parameter> is
+ omitted, the default is to use the next argument in sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>flags</parameter> (optional)</term>
+ <listitem>
+ <para>
+ Additional options controlling how the format specifier's output is
+ formatted. Currently the only supported flag is a minus sign
+ (<literal>-</literal>) which will cause the format specifier's output to be
+ left-justified. This has no effect unless the <parameter>width</parameter>
+ field is also specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>width</parameter> (optional)</term>
+ <listitem>
+ <para>
+ Specifies the <emphasis>minimum</emphasis> number of characters to use to
+ display the format specifier's output. The output is padded on the
+ left or right (depending on the <literal>-</literal> flag) with spaces as
+ needed to fill the width. A too-small width does not cause
+ truncation of the output, but is simply ignored. The width may be
+ specified using any of the following: a positive integer; an
+ asterisk (<literal>*</literal>) to use the next function argument as the
+ width; or a string of the form <literal>*<parameter>n</parameter>$</literal> to
+ use the <parameter>n</parameter>th function argument as the width.
+ </para>
+
+ <para>
+ If the width comes from a function argument, that argument is
+ consumed before the argument that is used for the format specifier's
+ value. If the width argument is negative, the result is left
+ aligned (as if the <literal>-</literal> flag had been specified) within a
+ field of length <function>abs</function>(<parameter>width</parameter>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>type</parameter> (required)</term>
+ <listitem>
+ <para>
+ The type of format conversion to use to produce the format
+ specifier's output. The following types are supported:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>s</literal> formats the argument value as a simple
+ string. A null value is treated as an empty string.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>I</literal> treats the argument value as an SQL
+ identifier, double-quoting it if necessary.
+ It is an error for the value to be null (equivalent to
+ <function>quote_ident</function>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>L</literal> quotes the argument value as an SQL literal.
+ A null value is displayed as the string <literal>NULL</literal>, without
+ quotes (equivalent to <function>quote_nullable</function>).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ In addition to the format specifiers described above, the special sequence
+ <literal>%%</literal> may be used to output a literal <literal>%</literal> character.
+ </para>
+
+ <para>
+ Here are some examples of the basic format conversions:
+
+<screen>
+SELECT format('Hello %s', 'World');
+<lineannotation>Result: </lineannotation><computeroutput>Hello World</computeroutput>
+
+SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three');
+<lineannotation>Result: </lineannotation><computeroutput>Testing one, two, three, %</computeroutput>
+
+SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
+<lineannotation>Result: </lineannotation><computeroutput>INSERT INTO "Foo bar" VALUES('O''Reilly')</computeroutput>
+
+SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files');
+<lineannotation>Result: </lineannotation><computeroutput>INSERT INTO locations VALUES('C:\Program Files')</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ Here are examples using <parameter>width</parameter> fields
+ and the <literal>-</literal> flag:
+
+<screen>
+SELECT format('|%10s|', 'foo');
+<lineannotation>Result: </lineannotation><computeroutput>| foo|</computeroutput>
+
+SELECT format('|%-10s|', 'foo');
+<lineannotation>Result: </lineannotation><computeroutput>|foo |</computeroutput>
+
+SELECT format('|%*s|', 10, 'foo');
+<lineannotation>Result: </lineannotation><computeroutput>| foo|</computeroutput>
+
+SELECT format('|%*s|', -10, 'foo');
+<lineannotation>Result: </lineannotation><computeroutput>|foo |</computeroutput>
+
+SELECT format('|%-*s|', 10, 'foo');
+<lineannotation>Result: </lineannotation><computeroutput>|foo |</computeroutput>
+
+SELECT format('|%-*s|', -10, 'foo');
+<lineannotation>Result: </lineannotation><computeroutput>|foo |</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ These examples show use of <parameter>position</parameter> fields:
+
+<screen>
+SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three');
+<lineannotation>Result: </lineannotation><computeroutput>Testing three, two, one</computeroutput>
+
+SELECT format('|%*2$s|', 'foo', 10, 'bar');
+<lineannotation>Result: </lineannotation><computeroutput>| bar|</computeroutput>
+
+SELECT format('|%1$*2$s|', 'foo', 10, 'bar');
+<lineannotation>Result: </lineannotation><computeroutput>| foo|</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ Unlike the standard C function <function>sprintf</function>,
+ <productname>PostgreSQL</productname>'s <function>format</function> function allows format
+ specifiers with and without <parameter>position</parameter> fields to be mixed
+ in the same format string. A format specifier without a
+ <parameter>position</parameter> field always uses the next argument after the
+ last argument consumed.
+ In addition, the <function>format</function> function does not require all
+ function arguments to be used in the format string.
+ For example:
+
+<screen>
+SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
+<lineannotation>Result: </lineannotation><computeroutput>Testing three, two, three</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ The <literal>%I</literal> and <literal>%L</literal> format specifiers are particularly
+ useful for safely constructing dynamic SQL statements. See
+ <xref linkend="plpgsql-quote-literal-example"/>.
+ </para>
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="functions-binarystring">
+ <title>Binary String Functions and Operators</title>
+
+ <indexterm zone="functions-binarystring">
+ <primary>binary data</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <para>
+ This section describes functions and operators for examining and
+ manipulating binary strings, that is values of type <type>bytea</type>.
+ Many of these are equivalent, in purpose and syntax, to the
+ text-string functions described in the previous section.
+ </para>
+
+ <para>
+ <acronym>SQL</acronym> defines some string functions that use
+ key words, rather than commas, to separate
+ arguments. Details are in
+ <xref linkend="functions-binarystring-sql"/>.
+ <productname>PostgreSQL</productname> also provides versions of these functions
+ that use the regular function invocation syntax
+ (see <xref linkend="functions-binarystring-other"/>).
+ </para>
+
+ <table id="functions-binarystring-sql">
+ <title><acronym>SQL</acronym> Binary String Functions and Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function/Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>binary string</primary>
+ <secondary>concatenation</secondary>
+ </indexterm>
+ <type>bytea</type> <literal>||</literal> <type>bytea</type>
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Concatenates the two binary strings.
+ </para>
+ <para>
+ <literal>'\x123456'::bytea || '\x789a00bcde'::bytea</literal>
+ <returnvalue>\x123456789a00bcde</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_length</primary>
+ </indexterm>
+ <function>bit_length</function> ( <type>bytea</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bits in the binary string (8
+ times the <function>octet_length</function>).
+ </para>
+ <para>
+ <literal>bit_length('\x123456'::bytea)</literal>
+ <returnvalue>24</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>octet_length</primary>
+ </indexterm>
+ <function>octet_length</function> ( <type>bytea</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bytes in the binary string.
+ </para>
+ <para>
+ <literal>octet_length('\x123456'::bytea)</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>overlay</primary>
+ </indexterm>
+ <function>overlay</function> ( <parameter>bytes</parameter> <type>bytea</type> <literal>PLACING</literal> <parameter>newsubstring</parameter> <type>bytea</type> <literal>FROM</literal> <parameter>start</parameter> <type>integer</type> <optional> <literal>FOR</literal> <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Replaces the substring of <parameter>bytes</parameter> that starts at
+ the <parameter>start</parameter>'th byte and extends
+ for <parameter>count</parameter> bytes
+ with <parameter>newsubstring</parameter>.
+ If <parameter>count</parameter> is omitted, it defaults to the length
+ of <parameter>newsubstring</parameter>.
+ </para>
+ <para>
+ <literal>overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3)</literal>
+ <returnvalue>\x12020390</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>position</primary>
+ </indexterm>
+ <function>position</function> ( <parameter>substring</parameter> <type>bytea</type> <literal>IN</literal> <parameter>bytes</parameter> <type>bytea</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns first starting index of the specified
+ <parameter>substring</parameter> within
+ <parameter>bytes</parameter>, or zero if it's not present.
+ </para>
+ <para>
+ <literal>position('\x5678'::bytea in '\x1234567890'::bytea)</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>substring</primary>
+ </indexterm>
+ <function>substring</function> ( <parameter>bytes</parameter> <type>bytea</type> <optional> <literal>FROM</literal> <parameter>start</parameter> <type>integer</type> </optional> <optional> <literal>FOR</literal> <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Extracts the substring of <parameter>bytes</parameter> starting at
+ the <parameter>start</parameter>'th byte if that is specified,
+ and stopping after <parameter>count</parameter> bytes if that is
+ specified. Provide at least one of <parameter>start</parameter>
+ and <parameter>count</parameter>.
+ </para>
+ <para>
+ <literal>substring('\x1234567890'::bytea from 3 for 2)</literal>
+ <returnvalue>\x5678</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>trim</primary>
+ </indexterm>
+ <function>trim</function> ( <optional> <literal>LEADING</literal> | <literal>TRAILING</literal> | <literal>BOTH</literal> </optional>
+ <parameter>bytesremoved</parameter> <type>bytea</type> <literal>FROM</literal>
+ <parameter>bytes</parameter> <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only bytes appearing in
+ <parameter>bytesremoved</parameter> from the start,
+ end, or both ends (<literal>BOTH</literal> is the default)
+ of <parameter>bytes</parameter>.
+ </para>
+ <para>
+ <literal>trim('\x9012'::bytea from '\x1234567890'::bytea)</literal>
+ <returnvalue>\x345678</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>trim</function> ( <optional> <literal>LEADING</literal> | <literal>TRAILING</literal> | <literal>BOTH</literal> </optional> <optional> <literal>FROM</literal> </optional>
+ <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>bytesremoved</parameter> <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ This is a non-standard syntax for <function>trim()</function>.
+ </para>
+ <para>
+ <literal>trim(both from '\x1234567890'::bytea, '\x9012'::bytea)</literal>
+ <returnvalue>\x345678</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Additional binary string manipulation functions are available and
+ are listed in <xref linkend="functions-binarystring-other"/>. Some
+ of them are used internally to implement the
+ <acronym>SQL</acronym>-standard string functions listed in <xref
+ linkend="functions-binarystring-sql"/>.
+ </para>
+
+ <table id="functions-binarystring-other">
+ <title>Other Binary String Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_count</primary>
+ </indexterm>
+ <indexterm>
+ <primary>popcount</primary>
+ <see>bit_count</see>
+ </indexterm>
+ <function>bit_count</function> ( <parameter>bytes</parameter> <type>bytea</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the number of bits set in the binary string (also known as
+ <quote>popcount</quote>).
+ </para>
+ <para>
+ <literal>bit_count('\x1234567890'::bytea)</literal>
+ <returnvalue>15</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>btrim</primary>
+ </indexterm>
+ <function>btrim</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>bytesremoved</parameter> <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only bytes appearing in
+ <parameter>bytesremoved</parameter> from the start and end of
+ <parameter>bytes</parameter>.
+ </para>
+ <para>
+ <literal>btrim('\x1234567890'::bytea, '\x9012'::bytea)</literal>
+ <returnvalue>\x345678</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>get_bit</primary>
+ </indexterm>
+ <function>get_bit</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>n</parameter> <type>bigint</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Extracts <link linkend="functions-zerobased-note">n'th</link> bit
+ from binary string.
+ </para>
+ <para>
+ <literal>get_bit('\x1234567890'::bytea, 30)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>get_byte</primary>
+ </indexterm>
+ <function>get_byte</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Extracts <link linkend="functions-zerobased-note">n'th</link> byte
+ from binary string.
+ </para>
+ <para>
+ <literal>get_byte('\x1234567890'::bytea, 4)</literal>
+ <returnvalue>144</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>length</primary>
+ </indexterm>
+ <indexterm>
+ <primary>binary string</primary>
+ <secondary>length</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>length</primary>
+ <secondary sortas="binary string">of a binary string</secondary>
+ <see>binary strings, length</see>
+ </indexterm>
+ <function>length</function> ( <type>bytea</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of bytes in the binary string.
+ </para>
+ <para>
+ <literal>length('\x1234567890'::bytea)</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>length</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>encoding</parameter> <type>name</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of characters in the binary string, assuming
+ that it is text in the given <parameter>encoding</parameter>.
+ </para>
+ <para>
+ <literal>length('jose'::bytea, 'UTF8')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ltrim</primary>
+ </indexterm>
+ <function>ltrim</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>bytesremoved</parameter> <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only bytes appearing in
+ <parameter>bytesremoved</parameter> from the start of
+ <parameter>bytes</parameter>.
+ </para>
+ <para>
+ <literal>ltrim('\x1234567890'::bytea, '\x9012'::bytea)</literal>
+ <returnvalue>\x34567890</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>md5</primary>
+ </indexterm>
+ <function>md5</function> ( <type>bytea</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Computes the MD5 <link linkend="functions-hash-note">hash</link> of
+ the binary string, with the result written in hexadecimal.
+ </para>
+ <para>
+ <literal>md5('Th\000omas'::bytea)</literal>
+ <returnvalue>8ab2d3c9689aaf18&zwsp;b4958c334c82d8b1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>rtrim</primary>
+ </indexterm>
+ <function>rtrim</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>bytesremoved</parameter> <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Removes the longest string containing only bytes appearing in
+ <parameter>bytesremoved</parameter> from the end of
+ <parameter>bytes</parameter>.
+ </para>
+ <para>
+ <literal>rtrim('\x1234567890'::bytea, '\x9012'::bytea)</literal>
+ <returnvalue>\x12345678</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>set_bit</primary>
+ </indexterm>
+ <function>set_bit</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>n</parameter> <type>bigint</type>,
+ <parameter>newvalue</parameter> <type>integer</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Sets <link linkend="functions-zerobased-note">n'th</link> bit in
+ binary string to <parameter>newvalue</parameter>.
+ </para>
+ <para>
+ <literal>set_bit('\x1234567890'::bytea, 30, 0)</literal>
+ <returnvalue>\x1234563890</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>set_byte</primary>
+ </indexterm>
+ <function>set_byte</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>n</parameter> <type>integer</type>,
+ <parameter>newvalue</parameter> <type>integer</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Sets <link linkend="functions-zerobased-note">n'th</link> byte in
+ binary string to <parameter>newvalue</parameter>.
+ </para>
+ <para>
+ <literal>set_byte('\x1234567890'::bytea, 4, 64)</literal>
+ <returnvalue>\x1234567840</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sha224</primary>
+ </indexterm>
+ <function>sha224</function> ( <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Computes the SHA-224 <link linkend="functions-hash-note">hash</link>
+ of the binary string.
+ </para>
+ <para>
+ <literal>sha224('abc'::bytea)</literal>
+ <returnvalue>\x23097d223405d8228642a477bda2&zwsp;55b32aadbce4bda0b3f7e36c9da7</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sha256</primary>
+ </indexterm>
+ <function>sha256</function> ( <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Computes the SHA-256 <link linkend="functions-hash-note">hash</link>
+ of the binary string.
+ </para>
+ <para>
+ <literal>sha256('abc'::bytea)</literal>
+ <returnvalue>\xba7816bf8f01cfea414140de5dae2223&zwsp;b00361a396177a9cb410ff61f20015ad</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sha384</primary>
+ </indexterm>
+ <function>sha384</function> ( <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Computes the SHA-384 <link linkend="functions-hash-note">hash</link>
+ of the binary string.
+ </para>
+ <para>
+ <literal>sha384('abc'::bytea)</literal>
+ <returnvalue>\xcb00753f45a35e8bb5a03d699ac65007&zwsp;272c32ab0eded1631a8b605a43ff5bed&zwsp;8086072ba1e7cc2358baeca134c825a7</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sha512</primary>
+ </indexterm>
+ <function>sha512</function> ( <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Computes the SHA-512 <link linkend="functions-hash-note">hash</link>
+ of the binary string.
+ </para>
+ <para>
+ <literal>sha512('abc'::bytea)</literal>
+ <returnvalue>\xddaf35a193617abacc417349ae204131&zwsp;12e6fa4e89a97ea20a9eeee64b55d39a&zwsp;2192992a274fc1a836ba3c23a3feebbd&zwsp;454d4423643ce80e2a9ac94fa54ca49f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>substr</primary>
+ </indexterm>
+ <function>substr</function> ( <parameter>bytes</parameter> <type>bytea</type>, <parameter>start</parameter> <type>integer</type> <optional>, <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Extracts the substring of <parameter>bytes</parameter> starting at
+ the <parameter>start</parameter>'th byte,
+ and extending for <parameter>count</parameter> bytes if that is
+ specified. (Same
+ as <literal>substring(<parameter>bytes</parameter>
+ from <parameter>start</parameter>
+ for <parameter>count</parameter>)</literal>.)
+ </para>
+ <para>
+ <literal>substr('\x1234567890'::bytea, 3, 2)</literal>
+ <returnvalue>\x5678</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para id="functions-zerobased-note">
+ Functions <function>get_byte</function> and <function>set_byte</function>
+ number the first byte of a binary string as byte 0.
+ Functions <function>get_bit</function> and <function>set_bit</function>
+ number bits from the right within each byte; for example bit 0 is the least
+ significant bit of the first byte, and bit 15 is the most significant bit
+ of the second byte.
+ </para>
+
+ <para id="functions-hash-note">
+ For historical reasons, the function <function>md5</function>
+ returns a hex-encoded value of type <type>text</type> whereas the SHA-2
+ functions return type <type>bytea</type>. Use the functions
+ <link linkend="function-encode"><function>encode</function></link>
+ and <link linkend="function-decode"><function>decode</function></link> to
+ convert between the two. For example write <literal>encode(sha256('abc'),
+ 'hex')</literal> to get a hex-encoded text representation,
+ or <literal>decode(md5('abc'), 'hex')</literal> to get
+ a <type>bytea</type> value.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>character string</primary>
+ <secondary>converting to binary string</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>binary string</primary>
+ <secondary>converting to character string</secondary>
+ </indexterm>
+ Functions for converting strings between different character sets
+ (encodings), and for representing arbitrary binary data in textual
+ form, are shown in
+ <xref linkend="functions-binarystring-conversions"/>. For these
+ functions, an argument or result of type <type>text</type> is expressed
+ in the database's default encoding, while arguments or results of
+ type <type>bytea</type> are in an encoding named by another argument.
+ </para>
+
+ <table id="functions-binarystring-conversions">
+ <title>Text/Binary String Conversion Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>convert</primary>
+ </indexterm>
+ <function>convert</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>src_encoding</parameter> <type>name</type>,
+ <parameter>dest_encoding</parameter> <type>name</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Converts a binary string representing text in
+ encoding <parameter>src_encoding</parameter>
+ to a binary string in encoding <parameter>dest_encoding</parameter>
+ (see <xref linkend="multibyte-conversions-supported"/> for
+ available conversions).
+ </para>
+ <para>
+ <literal>convert('text_in_utf8', 'UTF8', 'LATIN1')</literal>
+ <returnvalue>\x746578745f696e5f75746638</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>convert_from</primary>
+ </indexterm>
+ <function>convert_from</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>src_encoding</parameter> <type>name</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts a binary string representing text in
+ encoding <parameter>src_encoding</parameter>
+ to <type>text</type> in the database encoding
+ (see <xref linkend="multibyte-conversions-supported"/> for
+ available conversions).
+ </para>
+ <para>
+ <literal>convert_from('text_in_utf8', 'UTF8')</literal>
+ <returnvalue>text_in_utf8</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>convert_to</primary>
+ </indexterm>
+ <function>convert_to</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>dest_encoding</parameter> <type>name</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Converts a <type>text</type> string (in the database encoding) to a
+ binary string encoded in encoding <parameter>dest_encoding</parameter>
+ (see <xref linkend="multibyte-conversions-supported"/> for
+ available conversions).
+ </para>
+ <para>
+ <literal>convert_to('some_text', 'UTF8')</literal>
+ <returnvalue>\x736f6d655f74657874</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm id="function-encode">
+ <primary>encode</primary>
+ </indexterm>
+ <function>encode</function> ( <parameter>bytes</parameter> <type>bytea</type>,
+ <parameter>format</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Encodes binary data into a textual representation; supported
+ <parameter>format</parameter> values are:
+ <link linkend="encode-format-base64"><literal>base64</literal></link>,
+ <link linkend="encode-format-escape"><literal>escape</literal></link>,
+ <link linkend="encode-format-hex"><literal>hex</literal></link>.
+ </para>
+ <para>
+ <literal>encode('123\000\001', 'base64')</literal>
+ <returnvalue>MTIzAAE=</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm id="function-decode">
+ <primary>decode</primary>
+ </indexterm>
+ <function>decode</function> ( <parameter>string</parameter> <type>text</type>,
+ <parameter>format</parameter> <type>text</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Decodes binary data from a textual representation; supported
+ <parameter>format</parameter> values are the same as
+ for <function>encode</function>.
+ </para>
+ <para>
+ <literal>decode('MTIzAAE=', 'base64')</literal>
+ <returnvalue>\x3132330001</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <function>encode</function> and <function>decode</function>
+ functions support the following textual formats:
+
+ <variablelist>
+ <varlistentry id="encode-format-base64">
+ <term>base64
+ <indexterm>
+ <primary>base64 format</primary>
+ </indexterm></term>
+ <listitem>
+ <para>
+ The <literal>base64</literal> format is that
+ of <ulink url="https://tools.ietf.org/html/rfc2045#section-6.8">RFC
+ 2045 Section 6.8</ulink>. As per the <acronym>RFC</acronym>, encoded lines are
+ broken at 76 characters. However instead of the MIME CRLF
+ end-of-line marker, only a newline is used for end-of-line.
+ The <function>decode</function> function ignores carriage-return,
+ newline, space, and tab characters. Otherwise, an error is
+ raised when <function>decode</function> is supplied invalid
+ base64 data &mdash; including when trailing padding is incorrect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="encode-format-escape">
+ <term>escape
+ <indexterm>
+ <primary>escape format</primary>
+ </indexterm></term>
+ <listitem>
+ <para>
+ The <literal>escape</literal> format converts zero bytes and
+ bytes with the high bit set into octal escape sequences
+ (<literal>\</literal><replaceable>nnn</replaceable>), and it doubles
+ backslashes. Other byte values are represented literally.
+ The <function>decode</function> function will raise an error if a
+ backslash is not followed by either a second backslash or three
+ octal digits; it accepts other byte values unchanged.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="encode-format-hex">
+ <term>hex
+ <indexterm>
+ <primary>hex format</primary>
+ </indexterm></term>
+ <listitem>
+ <para>
+ The <literal>hex</literal> format represents each 4 bits of
+ data as one hexadecimal digit, <literal>0</literal>
+ through <literal>f</literal>, writing the higher-order digit of
+ each byte first. The <function>encode</function> function outputs
+ the <literal>a</literal>-<literal>f</literal> hex digits in lower
+ case. Because the smallest unit of data is 8 bits, there are
+ always an even number of characters returned
+ by <function>encode</function>.
+ The <function>decode</function> function
+ accepts the <literal>a</literal>-<literal>f</literal> characters in
+ either upper or lower case. An error is raised
+ when <function>decode</function> is given invalid hex data
+ &mdash; including when given an odd number of characters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ See also the aggregate function <function>string_agg</function> in
+ <xref linkend="functions-aggregate"/> and the large object functions
+ in <xref linkend="lo-funcs"/>.
+ </para>
+ </sect1>
+
+
+ <sect1 id="functions-bitstring">
+ <title>Bit String Functions and Operators</title>
+
+ <indexterm zone="functions-bitstring">
+ <primary>bit strings</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <para>
+ This section describes functions and operators for examining and
+ manipulating bit strings, that is values of the types
+ <type>bit</type> and <type>bit varying</type>. (While only
+ type <type>bit</type> is mentioned in these tables, values of
+ type <type>bit varying</type> can be used interchangeably.)
+ Bit strings support the usual comparison operators shown in
+ <xref linkend="functions-comparison-op-table"/>, as well as the
+ operators shown in <xref linkend="functions-bit-string-op-table"/>.
+ </para>
+
+ <table id="functions-bit-string-op-table">
+ <title>Bit String Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bit</type> <literal>||</literal> <type>bit</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Concatenation
+ </para>
+ <para>
+ <literal>B'10001' || B'011'</literal>
+ <returnvalue>10001011</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bit</type> <literal>&amp;</literal> <type>bit</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Bitwise AND (inputs must be of equal length)
+ </para>
+ <para>
+ <literal>B'10001' &amp; B'01101'</literal>
+ <returnvalue>00001</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bit</type> <literal>|</literal> <type>bit</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Bitwise OR (inputs must be of equal length)
+ </para>
+ <para>
+ <literal>B'10001' | B'01101'</literal>
+ <returnvalue>11101</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bit</type> <literal>#</literal> <type>bit</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Bitwise exclusive OR (inputs must be of equal length)
+ </para>
+ <para>
+ <literal>B'10001' # B'01101'</literal>
+ <returnvalue>11100</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>~</literal> <type>bit</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Bitwise NOT
+ </para>
+ <para>
+ <literal>~ B'10001'</literal>
+ <returnvalue>01110</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bit</type> <literal>&lt;&lt;</literal> <type>integer</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Bitwise shift left
+ (string length is preserved)
+ </para>
+ <para>
+ <literal>B'10001' &lt;&lt; 3</literal>
+ <returnvalue>01000</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bit</type> <literal>&gt;&gt;</literal> <type>integer</type>
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Bitwise shift right
+ (string length is preserved)
+ </para>
+ <para>
+ <literal>B'10001' &gt;&gt; 2</literal>
+ <returnvalue>00100</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Some of the functions available for binary strings are also available
+ for bit strings, as shown in <xref linkend="functions-bit-string-table"/>.
+ </para>
+
+ <table id="functions-bit-string-table">
+ <title>Bit String Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_count</primary>
+ </indexterm>
+ <function>bit_count</function> ( <type>bit</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the number of bits set in the bit string (also known as
+ <quote>popcount</quote>).
+ </para>
+ <para>
+ <literal>bit_count(B'10111')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_length</primary>
+ </indexterm>
+ <function>bit_length</function> ( <type>bit</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bits in the bit string.
+ </para>
+ <para>
+ <literal>bit_length(B'10111')</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>length</primary>
+ </indexterm>
+ <indexterm>
+ <primary>bit string</primary>
+ <secondary>length</secondary>
+ </indexterm>
+ <function>length</function> ( <type>bit</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bits in the bit string.
+ </para>
+ <para>
+ <literal>length(B'10111')</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>octet_length</primary>
+ </indexterm>
+ <function>octet_length</function> ( <type>bit</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of bytes in the bit string.
+ </para>
+ <para>
+ <literal>octet_length(B'1011111011')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>overlay</primary>
+ </indexterm>
+ <function>overlay</function> ( <parameter>bits</parameter> <type>bit</type> <literal>PLACING</literal> <parameter>newsubstring</parameter> <type>bit</type> <literal>FROM</literal> <parameter>start</parameter> <type>integer</type> <optional> <literal>FOR</literal> <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Replaces the substring of <parameter>bits</parameter> that starts at
+ the <parameter>start</parameter>'th bit and extends
+ for <parameter>count</parameter> bits
+ with <parameter>newsubstring</parameter>.
+ If <parameter>count</parameter> is omitted, it defaults to the length
+ of <parameter>newsubstring</parameter>.
+ </para>
+ <para>
+ <literal>overlay(B'01010101010101010' placing B'11111' from 2 for 3)</literal>
+ <returnvalue>0111110101010101010</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>position</primary>
+ </indexterm>
+ <function>position</function> ( <parameter>substring</parameter> <type>bit</type> <literal>IN</literal> <parameter>bits</parameter> <type>bit</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns first starting index of the specified <parameter>substring</parameter>
+ within <parameter>bits</parameter>, or zero if it's not present.
+ </para>
+ <para>
+ <literal>position(B'010' in B'000001101011')</literal>
+ <returnvalue>8</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>substring</primary>
+ </indexterm>
+ <function>substring</function> ( <parameter>bits</parameter> <type>bit</type> <optional> <literal>FROM</literal> <parameter>start</parameter> <type>integer</type> </optional> <optional> <literal>FOR</literal> <parameter>count</parameter> <type>integer</type> </optional> )
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Extracts the substring of <parameter>bits</parameter> starting at
+ the <parameter>start</parameter>'th bit if that is specified,
+ and stopping after <parameter>count</parameter> bits if that is
+ specified. Provide at least one of <parameter>start</parameter>
+ and <parameter>count</parameter>.
+ </para>
+ <para>
+ <literal>substring(B'110010111111' from 3 for 2)</literal>
+ <returnvalue>00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>get_bit</primary>
+ </indexterm>
+ <function>get_bit</function> ( <parameter>bits</parameter> <type>bit</type>,
+ <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Extracts <parameter>n</parameter>'th bit
+ from bit string; the first (leftmost) bit is bit 0.
+ </para>
+ <para>
+ <literal>get_bit(B'101010101010101010', 6)</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>set_bit</primary>
+ </indexterm>
+ <function>set_bit</function> ( <parameter>bits</parameter> <type>bit</type>,
+ <parameter>n</parameter> <type>integer</type>,
+ <parameter>newvalue</parameter> <type>integer</type> )
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Sets <parameter>n</parameter>'th bit in
+ bit string to <parameter>newvalue</parameter>;
+ the first (leftmost) bit is bit 0.
+ </para>
+ <para>
+ <literal>set_bit(B'101010101010101010', 6, 0)</literal>
+ <returnvalue>101010001010101010</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In addition, it is possible to cast integral values to and from type
+ <type>bit</type>.
+ Casting an integer to <type>bit(n)</type> copies the rightmost
+ <literal>n</literal> bits. Casting an integer to a bit string width wider
+ than the integer itself will sign-extend on the left.
+ Some examples:
+<programlisting>
+44::bit(10) <lineannotation>0000101100</lineannotation>
+44::bit(3) <lineannotation>100</lineannotation>
+cast(-44 as bit(12)) <lineannotation>111111010100</lineannotation>
+'1110'::bit(4)::integer <lineannotation>14</lineannotation>
+</programlisting>
+ Note that casting to just <quote>bit</quote> means casting to
+ <literal>bit(1)</literal>, and so will deliver only the least significant
+ bit of the integer.
+ </para>
+ </sect1>
+
+
+ <sect1 id="functions-matching">
+ <title>Pattern Matching</title>
+
+ <indexterm zone="functions-matching">
+ <primary>pattern matching</primary>
+ </indexterm>
+
+ <para>
+ There are three separate approaches to pattern matching provided
+ by <productname>PostgreSQL</productname>: the traditional
+ <acronym>SQL</acronym> <function>LIKE</function> operator, the
+ more recent <function>SIMILAR TO</function> operator (added in
+ SQL:1999), and <acronym>POSIX</acronym>-style regular
+ expressions. Aside from the basic <quote>does this string match
+ this pattern?</quote> operators, functions are available to extract
+ or replace matching substrings and to split a string at matching
+ locations.
+ </para>
+
+ <tip>
+ <para>
+ If you have pattern matching needs that go beyond this,
+ consider writing a user-defined function in Perl or Tcl.
+ </para>
+ </tip>
+
+ <caution>
+ <para>
+ While most regular-expression searches can be executed very quickly,
+ regular expressions can be contrived that take arbitrary amounts of
+ time and memory to process. Be wary of accepting regular-expression
+ search patterns from hostile sources. If you must do so, it is
+ advisable to impose a statement timeout.
+ </para>
+
+ <para>
+ Searches using <function>SIMILAR TO</function> patterns have the same
+ security hazards, since <function>SIMILAR TO</function> provides many
+ of the same capabilities as <acronym>POSIX</acronym>-style regular
+ expressions.
+ </para>
+
+ <para>
+ <function>LIKE</function> searches, being much simpler than the other
+ two options, are safer to use with possibly-hostile pattern sources.
+ </para>
+ </caution>
+
+ <para>
+ The pattern matching operators of all three kinds do not support
+ nondeterministic collations. If required, apply a different collation to
+ the expression to work around this limitation.
+ </para>
+
+ <sect2 id="functions-like">
+ <title><function>LIKE</function></title>
+
+ <indexterm>
+ <primary>LIKE</primary>
+ </indexterm>
+
+<synopsis>
+<replaceable>string</replaceable> LIKE <replaceable>pattern</replaceable> <optional>ESCAPE <replaceable>escape-character</replaceable></optional>
+<replaceable>string</replaceable> NOT LIKE <replaceable>pattern</replaceable> <optional>ESCAPE <replaceable>escape-character</replaceable></optional>
+</synopsis>
+
+ <para>
+ The <function>LIKE</function> expression returns true if the
+ <replaceable>string</replaceable> matches the supplied
+ <replaceable>pattern</replaceable>. (As
+ expected, the <function>NOT LIKE</function> expression returns
+ false if <function>LIKE</function> returns true, and vice versa.
+ An equivalent expression is
+ <literal>NOT (<replaceable>string</replaceable> LIKE
+ <replaceable>pattern</replaceable>)</literal>.)
+ </para>
+
+ <para>
+ If <replaceable>pattern</replaceable> does not contain percent
+ signs or underscores, then the pattern only represents the string
+ itself; in that case <function>LIKE</function> acts like the
+ equals operator. An underscore (<literal>_</literal>) in
+ <replaceable>pattern</replaceable> stands for (matches) any single
+ character; a percent sign (<literal>%</literal>) matches any sequence
+ of zero or more characters.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+'abc' LIKE 'abc' <lineannotation>true</lineannotation>
+'abc' LIKE 'a%' <lineannotation>true</lineannotation>
+'abc' LIKE '_b_' <lineannotation>true</lineannotation>
+'abc' LIKE 'c' <lineannotation>false</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ <function>LIKE</function> pattern matching always covers the entire
+ string. Therefore, if it's desired to match a sequence anywhere within
+ a string, the pattern must start and end with a percent sign.
+ </para>
+
+ <para>
+ To match a literal underscore or percent sign without matching
+ other characters, the respective character in
+ <replaceable>pattern</replaceable> must be
+ preceded by the escape character. The default escape
+ character is the backslash but a different one can be selected by
+ using the <literal>ESCAPE</literal> clause. To match the escape
+ character itself, write two escape characters.
+ </para>
+
+ <note>
+ <para>
+ If you have <xref linkend="guc-standard-conforming-strings"/> turned off,
+ any backslashes you write in literal string constants will need to be
+ doubled. See <xref linkend="sql-syntax-strings"/> for more information.
+ </para>
+ </note>
+
+ <para>
+ It's also possible to select no escape character by writing
+ <literal>ESCAPE ''</literal>. This effectively disables the
+ escape mechanism, which makes it impossible to turn off the
+ special meaning of underscore and percent signs in the pattern.
+ </para>
+
+ <para>
+ According to the SQL standard, omitting <literal>ESCAPE</literal>
+ means there is no escape character (rather than defaulting to a
+ backslash), and a zero-length <literal>ESCAPE</literal> value is
+ disallowed. <productname>PostgreSQL</productname>'s behavior in
+ this regard is therefore slightly nonstandard.
+ </para>
+
+ <para>
+ The key word <token>ILIKE</token> can be used instead of
+ <token>LIKE</token> to make the match case-insensitive according
+ to the active locale. This is not in the <acronym>SQL</acronym> standard but is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+
+ <para>
+ The operator <literal>~~</literal> is equivalent to
+ <function>LIKE</function>, and <literal>~~*</literal> corresponds to
+ <function>ILIKE</function>. There are also
+ <literal>!~~</literal> and <literal>!~~*</literal> operators that
+ represent <function>NOT LIKE</function> and <function>NOT
+ ILIKE</function>, respectively. All of these operators are
+ <productname>PostgreSQL</productname>-specific. You may see these
+ operator names in <command>EXPLAIN</command> output and similar
+ places, since the parser actually translates <function>LIKE</function>
+ et al. to these operators.
+ </para>
+
+ <para>
+ The phrases <function>LIKE</function>, <function>ILIKE</function>,
+ <function>NOT LIKE</function>, and <function>NOT ILIKE</function> are
+ generally treated as operators
+ in <productname>PostgreSQL</productname> syntax; for example they can
+ be used in <replaceable>expression</replaceable>
+ <replaceable>operator</replaceable> ANY
+ (<replaceable>subquery</replaceable>) constructs, although
+ an <literal>ESCAPE</literal> clause cannot be included there. In some
+ obscure cases it may be necessary to use the underlying operator names
+ instead.
+ </para>
+
+ <para>
+ Also see the starts-with operator <literal>^@</literal> and the
+ corresponding <function>starts_with()</function> function, which are
+ useful in cases where simply matching the beginning of a string is
+ needed.
+ </para>
+ </sect2>
+
+
+ <sect2 id="functions-similarto-regexp">
+ <title><function>SIMILAR TO</function> Regular Expressions</title>
+
+ <indexterm>
+ <primary>regular expression</primary>
+ <!-- <seealso>pattern matching</seealso> breaks index build -->
+ </indexterm>
+
+ <indexterm>
+ <primary>SIMILAR TO</primary>
+ </indexterm>
+ <indexterm>
+ <primary>substring</primary>
+ </indexterm>
+
+<synopsis>
+<replaceable>string</replaceable> SIMILAR TO <replaceable>pattern</replaceable> <optional>ESCAPE <replaceable>escape-character</replaceable></optional>
+<replaceable>string</replaceable> NOT SIMILAR TO <replaceable>pattern</replaceable> <optional>ESCAPE <replaceable>escape-character</replaceable></optional>
+</synopsis>
+
+ <para>
+ The <function>SIMILAR TO</function> operator returns true or
+ false depending on whether its pattern matches the given string.
+ It is similar to <function>LIKE</function>, except that it
+ interprets the pattern using the SQL standard's definition of a
+ regular expression. SQL regular expressions are a curious cross
+ between <function>LIKE</function> notation and common (POSIX) regular
+ expression notation.
+ </para>
+
+ <para>
+ Like <function>LIKE</function>, the <function>SIMILAR TO</function>
+ operator succeeds only if its pattern matches the entire string;
+ this is unlike common regular expression behavior where the pattern
+ can match any part of the string.
+ Also like
+ <function>LIKE</function>, <function>SIMILAR TO</function> uses
+ <literal>_</literal> and <literal>%</literal> as wildcard characters denoting
+ any single character and any string, respectively (these are
+ comparable to <literal>.</literal> and <literal>.*</literal> in POSIX regular
+ expressions).
+ </para>
+
+ <para>
+ In addition to these facilities borrowed from <function>LIKE</function>,
+ <function>SIMILAR TO</function> supports these pattern-matching
+ metacharacters borrowed from POSIX regular expressions:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>|</literal> denotes alternation (either of two alternatives).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>*</literal> denotes repetition of the previous item zero
+ or more times.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>+</literal> denotes repetition of the previous item one
+ or more times.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>?</literal> denotes repetition of the previous item zero
+ or one time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>{</literal><replaceable>m</replaceable><literal>}</literal> denotes repetition
+ of the previous item exactly <replaceable>m</replaceable> times.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>{</literal><replaceable>m</replaceable><literal>,}</literal> denotes repetition
+ of the previous item <replaceable>m</replaceable> or more times.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>{</literal><replaceable>m</replaceable><literal>,</literal><replaceable>n</replaceable><literal>}</literal>
+ denotes repetition of the previous item at least <replaceable>m</replaceable> and
+ not more than <replaceable>n</replaceable> times.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Parentheses <literal>()</literal> can be used to group items into
+ a single logical item.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A bracket expression <literal>[...]</literal> specifies a character
+ class, just as in POSIX regular expressions.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Notice that the period (<literal>.</literal>) is not a metacharacter
+ for <function>SIMILAR TO</function>.
+ </para>
+
+ <para>
+ As with <function>LIKE</function>, a backslash disables the special
+ meaning of any of these metacharacters. A different escape character
+ can be specified with <literal>ESCAPE</literal>, or the escape
+ capability can be disabled by writing <literal>ESCAPE ''</literal>.
+ </para>
+
+ <para>
+ According to the SQL standard, omitting <literal>ESCAPE</literal>
+ means there is no escape character (rather than defaulting to a
+ backslash), and a zero-length <literal>ESCAPE</literal> value is
+ disallowed. <productname>PostgreSQL</productname>'s behavior in
+ this regard is therefore slightly nonstandard.
+ </para>
+
+ <para>
+ Another nonstandard extension is that following the escape character
+ with a letter or digit provides access to the escape sequences
+ defined for POSIX regular expressions; see
+ <xref linkend="posix-character-entry-escapes-table"/>,
+ <xref linkend="posix-class-shorthand-escapes-table"/>, and
+ <xref linkend="posix-constraint-escapes-table"/> below.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+'abc' SIMILAR TO 'abc' <lineannotation>true</lineannotation>
+'abc' SIMILAR TO 'a' <lineannotation>false</lineannotation>
+'abc' SIMILAR TO '%(b|d)%' <lineannotation>true</lineannotation>
+'abc' SIMILAR TO '(b|c)%' <lineannotation>false</lineannotation>
+'-abc-' SIMILAR TO '%\mabc\M%' <lineannotation>true</lineannotation>
+'xabcy' SIMILAR TO '%\mabc\M%' <lineannotation>false</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <function>substring</function> function with three parameters
+ provides extraction of a substring that matches an SQL
+ regular expression pattern. The function can be written according
+ to standard SQL syntax:
+<synopsis>
+substring(<replaceable>string</replaceable> similar <replaceable>pattern</replaceable> escape <replaceable>escape-character</replaceable>)
+</synopsis>
+ or using the now obsolete SQL:1999 syntax:
+<synopsis>
+substring(<replaceable>string</replaceable> from <replaceable>pattern</replaceable> for <replaceable>escape-character</replaceable>)
+</synopsis>
+ or as a plain three-argument function:
+<synopsis>
+substring(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>, <replaceable>escape-character</replaceable>)
+</synopsis>
+ As with <literal>SIMILAR TO</literal>, the
+ specified pattern must match the entire data string, or else the
+ function fails and returns null. To indicate the part of the
+ pattern for which the matching data sub-string is of interest,
+ the pattern should contain
+ two occurrences of the escape character followed by a double quote
+ (<literal>"</literal>). <!-- " font-lock sanity -->
+ The text matching the portion of the pattern
+ between these separators is returned when the match is successful.
+ </para>
+
+ <para>
+ The escape-double-quote separators actually
+ divide <function>substring</function>'s pattern into three independent
+ regular expressions; for example, a vertical bar (<literal>|</literal>)
+ in any of the three sections affects only that section. Also, the first
+ and third of these regular expressions are defined to match the smallest
+ possible amount of text, not the largest, when there is any ambiguity
+ about how much of the data string matches which pattern. (In POSIX
+ parlance, the first and third regular expressions are forced to be
+ non-greedy.)
+ </para>
+
+ <para>
+ As an extension to the SQL standard, <productname>PostgreSQL</productname>
+ allows there to be just one escape-double-quote separator, in which case
+ the third regular expression is taken as empty; or no separators, in which
+ case the first and third regular expressions are taken as empty.
+ </para>
+
+ <para>
+ Some examples, with <literal>#&quot;</literal> delimiting the return string:
+<programlisting>
+substring('foobar' similar '%#"o_b#"%' escape '#') <lineannotation>oob</lineannotation>
+substring('foobar' similar '#"o_b#"%' escape '#') <lineannotation>NULL</lineannotation>
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="functions-posix-regexp">
+ <title><acronym>POSIX</acronym> Regular Expressions</title>
+
+ <indexterm zone="functions-posix-regexp">
+ <primary>regular expression</primary>
+ <seealso>pattern matching</seealso>
+ </indexterm>
+ <indexterm>
+ <primary>substring</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_count</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_instr</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_like</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_match</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_matches</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_replace</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_split_to_table</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_split_to_array</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regexp_substr</primary>
+ </indexterm>
+
+ <para>
+ <xref linkend="functions-posix-table"/> lists the available
+ operators for pattern matching using POSIX regular expressions.
+ </para>
+
+ <table id="functions-posix-table">
+ <title>Regular Expression Match Operators</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>~</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ String matches regular expression, case sensitively
+ </para>
+ <para>
+ <literal>'thomas' ~ 't.*ma'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>~*</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ String matches regular expression, case insensitively
+ </para>
+ <para>
+ <literal>'thomas' ~* 'T.*ma'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>!~</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ String does not match regular expression, case sensitively
+ </para>
+ <para>
+ <literal>'thomas' !~ 't.*max'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>!~*</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ String does not match regular expression, case insensitively
+ </para>
+ <para>
+ <literal>'thomas' !~* 'T.*ma'</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <acronym>POSIX</acronym> regular expressions provide a more
+ powerful means for pattern matching than the <function>LIKE</function> and
+ <function>SIMILAR TO</function> operators.
+ Many Unix tools such as <command>egrep</command>,
+ <command>sed</command>, or <command>awk</command> use a pattern
+ matching language that is similar to the one described here.
+ </para>
+
+ <para>
+ A regular expression is a character sequence that is an
+ abbreviated definition of a set of strings (a <firstterm>regular
+ set</firstterm>). A string is said to match a regular expression
+ if it is a member of the regular set described by the regular
+ expression. As with <function>LIKE</function>, pattern characters
+ match string characters exactly unless they are special characters
+ in the regular expression language &mdash; but regular expressions use
+ different special characters than <function>LIKE</function> does.
+ Unlike <function>LIKE</function> patterns, a
+ regular expression is allowed to match anywhere within a string, unless
+ the regular expression is explicitly anchored to the beginning or
+ end of the string.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+'abcd' ~ 'bc' <lineannotation>true</lineannotation>
+'abcd' ~ 'a.c' <lineannotation>true &mdash; dot matches any character</lineannotation>
+'abcd' ~ 'a.*d' <lineannotation>true &mdash; <literal>*</literal> repeats the preceding pattern item</lineannotation>
+'abcd' ~ '(b|x)' <lineannotation>true &mdash; <literal>|</literal> means OR, parentheses group</lineannotation>
+'abcd' ~ '^a' <lineannotation>true &mdash; <literal>^</literal> anchors to start of string</lineannotation>
+'abcd' ~ '^(b|c)' <lineannotation>false &mdash; would match except for anchoring</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <acronym>POSIX</acronym> pattern language is described in much
+ greater detail below.
+ </para>
+
+ <para>
+ The <function>substring</function> function with two parameters,
+ <function>substring(<replaceable>string</replaceable> from
+ <replaceable>pattern</replaceable>)</function>, provides extraction of a
+ substring
+ that matches a POSIX regular expression pattern. It returns null if
+ there is no match, otherwise the first portion of the text that matched the
+ pattern. But if the pattern contains any parentheses, the portion
+ of the text that matched the first parenthesized subexpression (the
+ one whose left parenthesis comes first) is
+ returned. You can put parentheses around the whole expression
+ if you want to use parentheses within it without triggering this
+ exception. If you need parentheses in the pattern before the
+ subexpression you want to extract, see the non-capturing parentheses
+ described below.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+substring('foobar' from 'o.b') <lineannotation>oob</lineannotation>
+substring('foobar' from 'o(.)b') <lineannotation>o</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <function>regexp_count</function> function counts the number of
+ places where a POSIX regular expression pattern matches a string.
+ It has the syntax
+ <function>regexp_count</function>(<replaceable>string</replaceable>,
+ <replaceable>pattern</replaceable>
+ <optional>, <replaceable>start</replaceable>
+ <optional>, <replaceable>flags</replaceable>
+ </optional></optional>).
+ <replaceable>pattern</replaceable> is searched for
+ in <replaceable>string</replaceable>, normally from the beginning of
+ the string, but if the <replaceable>start</replaceable> parameter is
+ provided then beginning from that character index.
+ The <replaceable>flags</replaceable> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. For example, including <literal>i</literal> in
+ <replaceable>flags</replaceable> specifies case-insensitive matching.
+ Supported flags are described in
+ <xref linkend="posix-embedded-options-table"/>.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+regexp_count('ABCABCAXYaxy', 'A.') <lineannotation>3</lineannotation>
+regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') <lineannotation>4</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <function>regexp_instr</function> function returns the starting or
+ ending position of the <replaceable>N</replaceable>'th match of a
+ POSIX regular expression pattern to a string, or zero if there is no
+ such match. It has the syntax
+ <function>regexp_instr</function>(<replaceable>string</replaceable>,
+ <replaceable>pattern</replaceable>
+ <optional>, <replaceable>start</replaceable>
+ <optional>, <replaceable>N</replaceable>
+ <optional>, <replaceable>endoption</replaceable>
+ <optional>, <replaceable>flags</replaceable>
+ <optional>, <replaceable>subexpr</replaceable>
+ </optional></optional></optional></optional></optional>).
+ <replaceable>pattern</replaceable> is searched for
+ in <replaceable>string</replaceable>, normally from the beginning of
+ the string, but if the <replaceable>start</replaceable> parameter is
+ provided then beginning from that character index.
+ If <replaceable>N</replaceable> is specified
+ then the <replaceable>N</replaceable>'th match of the pattern
+ is located, otherwise the first match is located.
+ If the <replaceable>endoption</replaceable> parameter is omitted or
+ specified as zero, the function returns the position of the first
+ character of the match. Otherwise, <replaceable>endoption</replaceable>
+ must be one, and the function returns the position of the character
+ following the match.
+ The <replaceable>flags</replaceable> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags are described
+ in <xref linkend="posix-embedded-options-table"/>.
+ For a pattern containing parenthesized
+ subexpressions, <replaceable>subexpr</replaceable> is an integer
+ indicating which subexpression is of interest: the result identifies
+ the position of the substring matching that subexpression.
+ Subexpressions are numbered in the order of their leading parentheses.
+ When <replaceable>subexpr</replaceable> is omitted or zero, the result
+ identifies the position of the whole match regardless of
+ parenthesized subexpressions.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2)
+ <lineannotation>23</lineannotation>
+regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2)
+ <lineannotation>6</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <function>regexp_like</function> function checks whether a match
+ of a POSIX regular expression pattern occurs within a string,
+ returning boolean true or false. It has the syntax
+ <function>regexp_like</function>(<replaceable>string</replaceable>,
+ <replaceable>pattern</replaceable>
+ <optional>, <replaceable>flags</replaceable> </optional>).
+ The <replaceable>flags</replaceable> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags are described
+ in <xref linkend="posix-embedded-options-table"/>.
+ This function has the same results as the <literal>~</literal>
+ operator if no flags are specified. If only the <literal>i</literal>
+ flag is specified, it has the same results as
+ the <literal>~*</literal> operator.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+regexp_like('Hello World', 'world') <lineannotation>false</lineannotation>
+regexp_like('Hello World', 'world', 'i') <lineannotation>true</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <function>regexp_match</function> function returns a text array of
+ matching substring(s) within the first match of a POSIX
+ regular expression pattern to a string. It has the syntax
+ <function>regexp_match</function>(<replaceable>string</replaceable>,
+ <replaceable>pattern</replaceable> <optional>, <replaceable>flags</replaceable> </optional>).
+ If there is no match, the result is <literal>NULL</literal>.
+ If a match is found, and the <replaceable>pattern</replaceable> contains no
+ parenthesized subexpressions, then the result is a single-element text
+ array containing the substring matching the whole pattern.
+ If a match is found, and the <replaceable>pattern</replaceable> contains
+ parenthesized subexpressions, then the result is a text array
+ whose <replaceable>n</replaceable>'th element is the substring matching
+ the <replaceable>n</replaceable>'th parenthesized subexpression of
+ the <replaceable>pattern</replaceable> (not counting <quote>non-capturing</quote>
+ parentheses; see below for details).
+ The <replaceable>flags</replaceable> parameter is an optional text string
+ containing zero or more single-letter flags that change the function's
+ behavior. Supported flags are described
+ in <xref linkend="posix-embedded-options-table"/>.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+SELECT regexp_match('foobarbequebaz', 'bar.*que');
+ regexp_match
+--------------
+ {barbeque}
+(1 row)
+
+SELECT regexp_match('foobarbequebaz', '(bar)(beque)');
+ regexp_match
+--------------
+ {bar,beque}
+(1 row)
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ In the common case where you just want the whole matching substring
+ or <literal>NULL</literal> for no match, the best solution is to
+ use <function>regexp_substr()</function>.
+ However, <function>regexp_substr()</function> only exists
+ in <productname>PostgreSQL</productname> version 15 and up. When
+ working in older versions, you can extract the first element
+ of <function>regexp_match()</function>'s result, for example:
+<programlisting>
+SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
+ regexp_match
+--------------
+ barbeque
+(1 row)
+</programlisting>
+ </para>
+ </tip>
+
+ <para>
+ The <function>regexp_matches</function> function returns a set of text arrays
+ of matching substring(s) within matches of a POSIX regular
+ expression pattern to a string. It has the same syntax as
+ <function>regexp_match</function>.
+ This function returns no rows if there is no match, one row if there is
+ a match and the <literal>g</literal> flag is not given, or <replaceable>N</replaceable>
+ rows if there are <replaceable>N</replaceable> matches and the <literal>g</literal> flag
+ is given. Each returned row is a text array containing the whole
+ matched substring or the substrings matching parenthesized
+ subexpressions of the <replaceable>pattern</replaceable>, just as described above
+ for <function>regexp_match</function>.
+ <function>regexp_matches</function> accepts all the flags shown
+ in <xref linkend="posix-embedded-options-table"/>, plus
+ the <literal>g</literal> flag which commands it to return all matches, not
+ just the first one.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+SELECT regexp_matches('foo', 'not there');
+ regexp_matches
+----------------
+(0 rows)
+
+SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
+ regexp_matches
+----------------
+ {bar,beque}
+ {bazil,barf}
+(2 rows)
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ In most cases <function>regexp_matches()</function> should be used with
+ the <literal>g</literal> flag, since if you only want the first match, it's
+ easier and more efficient to use <function>regexp_match()</function>.
+ However, <function>regexp_match()</function> only exists
+ in <productname>PostgreSQL</productname> version 10 and up. When working in older
+ versions, a common trick is to place a <function>regexp_matches()</function>
+ call in a sub-select, for example:
+<programlisting>
+SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;
+</programlisting>
+ This produces a text array if there's a match, or <literal>NULL</literal> if
+ not, the same as <function>regexp_match()</function> would do. Without the
+ sub-select, this query would produce no output at all for table rows
+ without a match, which is typically not the desired behavior.
+ </para>
+ </tip>
+
+ <para>
+ The <function>regexp_replace</function> function provides substitution of
+ new text for substrings that match POSIX regular expression patterns.
+ It has the syntax
+ <function>regexp_replace</function>(<replaceable>source</replaceable>,
+ <replaceable>pattern</replaceable>, <replaceable>replacement</replaceable>
+ <optional>, <replaceable>start</replaceable>
+ <optional>, <replaceable>N</replaceable>
+ </optional></optional>
+ <optional>, <replaceable>flags</replaceable> </optional>).
+ (Notice that <replaceable>N</replaceable> cannot be specified
+ unless <replaceable>start</replaceable> is,
+ but <replaceable>flags</replaceable> can be given in any case.)
+ The <replaceable>source</replaceable> string is returned unchanged if
+ there is no match to the <replaceable>pattern</replaceable>. If there is a
+ match, the <replaceable>source</replaceable> string is returned with the
+ <replaceable>replacement</replaceable> string substituted for the matching
+ substring. The <replaceable>replacement</replaceable> string can contain
+ <literal>\</literal><replaceable>n</replaceable>, where <replaceable>n</replaceable> is 1
+ through 9, to indicate that the source substring matching the
+ <replaceable>n</replaceable>'th parenthesized subexpression of the pattern should be
+ inserted, and it can contain <literal>\&amp;</literal> to indicate that the
+ substring matching the entire pattern should be inserted. Write
+ <literal>\\</literal> if you need to put a literal backslash in the replacement
+ text.
+ <replaceable>pattern</replaceable> is searched for
+ in <replaceable>string</replaceable>, normally from the beginning of
+ the string, but if the <replaceable>start</replaceable> parameter is
+ provided then beginning from that character index.
+ By default, only the first match of the pattern is replaced.
+ If <replaceable>N</replaceable> is specified and is greater than zero,
+ then the <replaceable>N</replaceable>'th match of the pattern
+ is replaced.
+ If the <literal>g</literal> flag is given, or
+ if <replaceable>N</replaceable> is specified and is zero, then all
+ matches at or after the <replaceable>start</replaceable> position are
+ replaced. (The <literal>g</literal> flag is ignored
+ when <replaceable>N</replaceable> is specified.)
+ The <replaceable>flags</replaceable> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags (though
+ not <literal>g</literal>) are
+ described in <xref linkend="posix-embedded-options-table"/>.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+regexp_replace('foobarbaz', 'b..', 'X')
+ <lineannotation>fooXbaz</lineannotation>
+regexp_replace('foobarbaz', 'b..', 'X', 'g')
+ <lineannotation>fooXX</lineannotation>
+regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
+ <lineannotation>fooXarYXazY</lineannotation>
+regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i')
+ <lineannotation>X PXstgrXSQL fXnctXXn</lineannotation>
+regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i')
+ <lineannotation>A PostgrXSQL function</lineannotation>
+</programlisting>
+ </para>
+
+ <para>
+ The <function>regexp_split_to_table</function> function splits a string using a POSIX
+ regular expression pattern as a delimiter. It has the syntax
+ <function>regexp_split_to_table</function>(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>
+ <optional>, <replaceable>flags</replaceable> </optional>).
+ If there is no match to the <replaceable>pattern</replaceable>, the function returns the
+ <replaceable>string</replaceable>. If there is at least one match, for each match it returns
+ the text from the end of the last match (or the beginning of the string)
+ to the beginning of the match. When there are no more matches, it
+ returns the text from the end of the last match to the end of the string.
+ The <replaceable>flags</replaceable> parameter is an optional text string containing
+ zero or more single-letter flags that change the function's behavior.
+ <function>regexp_split_to_table</function> supports the flags described in
+ <xref linkend="posix-embedded-options-table"/>.
+ </para>
+
+ <para>
+ The <function>regexp_split_to_array</function> function behaves the same as
+ <function>regexp_split_to_table</function>, except that <function>regexp_split_to_array</function>
+ returns its result as an array of <type>text</type>. It has the syntax
+ <function>regexp_split_to_array</function>(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>
+ <optional>, <replaceable>flags</replaceable> </optional>).
+ The parameters are the same as for <function>regexp_split_to_table</function>.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo;
+ foo
+-------
+ the
+ quick
+ brown
+ fox
+ jumps
+ over
+ the
+ lazy
+ dog
+(9 rows)
+
+SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+');
+ regexp_split_to_array
+-----------------------------------------------
+ {the,quick,brown,fox,jumps,over,the,lazy,dog}
+(1 row)
+
+SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
+ foo
+-----
+ t
+ h
+ e
+ q
+ u
+ i
+ c
+ k
+ b
+ r
+ o
+ w
+ n
+ f
+ o
+ x
+(16 rows)
+</programlisting>
+ </para>
+
+ <para>
+ As the last example demonstrates, the regexp split functions ignore
+ zero-length matches that occur at the start or end of the string
+ or immediately after a previous match. This is contrary to the strict
+ definition of regexp matching that is implemented by
+ the other regexp functions, but is usually the most convenient behavior
+ in practice. Other software systems such as Perl use similar definitions.
+ </para>
+
+ <para>
+ The <function>regexp_substr</function> function returns the substring
+ that matches a POSIX regular expression pattern,
+ or <literal>NULL</literal> if there is no match. It has the syntax
+ <function>regexp_substr</function>(<replaceable>string</replaceable>,
+ <replaceable>pattern</replaceable>
+ <optional>, <replaceable>start</replaceable>
+ <optional>, <replaceable>N</replaceable>
+ <optional>, <replaceable>flags</replaceable>
+ <optional>, <replaceable>subexpr</replaceable>
+ </optional></optional></optional></optional>).
+ <replaceable>pattern</replaceable> is searched for
+ in <replaceable>string</replaceable>, normally from the beginning of
+ the string, but if the <replaceable>start</replaceable> parameter is
+ provided then beginning from that character index.
+ If <replaceable>N</replaceable> is specified
+ then the <replaceable>N</replaceable>'th match of the pattern
+ is returned, otherwise the first match is returned.
+ The <replaceable>flags</replaceable> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags are described
+ in <xref linkend="posix-embedded-options-table"/>.
+ For a pattern containing parenthesized
+ subexpressions, <replaceable>subexpr</replaceable> is an integer
+ indicating which subexpression is of interest: the result is the
+ substring matching that subexpression.
+ Subexpressions are numbered in the order of their leading parentheses.
+ When <replaceable>subexpr</replaceable> is omitted or zero, the result
+ is the whole match regardless of parenthesized subexpressions.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2)
+ <lineannotation> town zip</lineannotation>
+regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
+ <lineannotation>FGH</lineannotation>
+</programlisting>
+ </para>
+
+<!-- derived from the re_syntax.n man page -->
+
+ <sect3 id="posix-syntax-details">
+ <title>Regular Expression Details</title>
+
+ <para>
+ <productname>PostgreSQL</productname>'s regular expressions are implemented
+ using a software package written by Henry Spencer. Much of
+ the description of regular expressions below is copied verbatim from his
+ manual.
+ </para>
+
+ <para>
+ Regular expressions (<acronym>RE</acronym>s), as defined in
+ <acronym>POSIX</acronym> 1003.2, come in two forms:
+ <firstterm>extended</firstterm> <acronym>RE</acronym>s or <acronym>ERE</acronym>s
+ (roughly those of <command>egrep</command>), and
+ <firstterm>basic</firstterm> <acronym>RE</acronym>s or <acronym>BRE</acronym>s
+ (roughly those of <command>ed</command>).
+ <productname>PostgreSQL</productname> supports both forms, and
+ also implements some extensions
+ that are not in the POSIX standard, but have become widely used
+ due to their availability in programming languages such as Perl and Tcl.
+ <acronym>RE</acronym>s using these non-POSIX extensions are called
+ <firstterm>advanced</firstterm> <acronym>RE</acronym>s or <acronym>ARE</acronym>s
+ in this documentation. AREs are almost an exact superset of EREs,
+ but BREs have several notational incompatibilities (as well as being
+ much more limited).
+ We first describe the ARE and ERE forms, noting features that apply
+ only to AREs, and then describe how BREs differ.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> always initially presumes that a regular
+ expression follows the ARE rules. However, the more limited ERE or
+ BRE rules can be chosen by prepending an <firstterm>embedded option</firstterm>
+ to the RE pattern, as described in <xref linkend="posix-metasyntax"/>.
+ This can be useful for compatibility with applications that expect
+ exactly the <acronym>POSIX</acronym> 1003.2 rules.
+ </para>
+ </note>
+
+ <para>
+ A regular expression is defined as one or more
+ <firstterm>branches</firstterm>, separated by
+ <literal>|</literal>. It matches anything that matches one of the
+ branches.
+ </para>
+
+ <para>
+ A branch is zero or more <firstterm>quantified atoms</firstterm> or
+ <firstterm>constraints</firstterm>, concatenated.
+ It matches a match for the first, followed by a match for the second, etc.;
+ an empty branch matches the empty string.
+ </para>
+
+ <para>
+ A quantified atom is an <firstterm>atom</firstterm> possibly followed
+ by a single <firstterm>quantifier</firstterm>.
+ Without a quantifier, it matches a match for the atom.
+ With a quantifier, it can match some number of matches of the atom.
+ An <firstterm>atom</firstterm> can be any of the possibilities
+ shown in <xref linkend="posix-atoms-table"/>.
+ The possible quantifiers and their meanings are shown in
+ <xref linkend="posix-quantifiers-table"/>.
+ </para>
+
+ <para>
+ A <firstterm>constraint</firstterm> matches an empty string, but matches only when
+ specific conditions are met. A constraint can be used where an atom
+ could be used, except it cannot be followed by a quantifier.
+ The simple constraints are shown in
+ <xref linkend="posix-constraints-table"/>;
+ some more constraints are described later.
+ </para>
+
+
+ <table id="posix-atoms-table">
+ <title>Regular Expression Atoms</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Atom</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>(</literal><replaceable>re</replaceable><literal>)</literal> </entry>
+ <entry> (where <replaceable>re</replaceable> is any regular expression)
+ matches a match for
+ <replaceable>re</replaceable>, with the match noted for possible reporting </entry>
+ </row>
+
+ <row>
+ <entry> <literal>(?:</literal><replaceable>re</replaceable><literal>)</literal> </entry>
+ <entry> as above, but the match is not noted for reporting
+ (a <quote>non-capturing</quote> set of parentheses)
+ (AREs only) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>.</literal> </entry>
+ <entry> matches any single character </entry>
+ </row>
+
+ <row>
+ <entry> <literal>[</literal><replaceable>chars</replaceable><literal>]</literal> </entry>
+ <entry> a <firstterm>bracket expression</firstterm>,
+ matching any one of the <replaceable>chars</replaceable> (see
+ <xref linkend="posix-bracket-expressions"/> for more detail) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\</literal><replaceable>k</replaceable> </entry>
+ <entry> (where <replaceable>k</replaceable> is a non-alphanumeric character)
+ matches that character taken as an ordinary character,
+ e.g., <literal>\\</literal> matches a backslash character </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\</literal><replaceable>c</replaceable> </entry>
+ <entry> where <replaceable>c</replaceable> is alphanumeric
+ (possibly followed by other characters)
+ is an <firstterm>escape</firstterm>, see <xref linkend="posix-escape-sequences"/>
+ (AREs only; in EREs and BREs, this matches <replaceable>c</replaceable>) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>{</literal> </entry>
+ <entry> when followed by a character other than a digit,
+ matches the left-brace character <literal>{</literal>;
+ when followed by a digit, it is the beginning of a
+ <replaceable>bound</replaceable> (see below) </entry>
+ </row>
+
+ <row>
+ <entry> <replaceable>x</replaceable> </entry>
+ <entry> where <replaceable>x</replaceable> is a single character with no other
+ significance, matches that character </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ An RE cannot end with a backslash (<literal>\</literal>).
+ </para>
+
+ <note>
+ <para>
+ If you have <xref linkend="guc-standard-conforming-strings"/> turned off,
+ any backslashes you write in literal string constants will need to be
+ doubled. See <xref linkend="sql-syntax-strings"/> for more information.
+ </para>
+ </note>
+
+ <table id="posix-quantifiers-table">
+ <title>Regular Expression Quantifiers</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Quantifier</entry>
+ <entry>Matches</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>*</literal> </entry>
+ <entry> a sequence of 0 or more matches of the atom </entry>
+ </row>
+
+ <row>
+ <entry> <literal>+</literal> </entry>
+ <entry> a sequence of 1 or more matches of the atom </entry>
+ </row>
+
+ <row>
+ <entry> <literal>?</literal> </entry>
+ <entry> a sequence of 0 or 1 matches of the atom </entry>
+ </row>
+
+ <row>
+ <entry> <literal>{</literal><replaceable>m</replaceable><literal>}</literal> </entry>
+ <entry> a sequence of exactly <replaceable>m</replaceable> matches of the atom </entry>
+ </row>
+
+ <row>
+ <entry> <literal>{</literal><replaceable>m</replaceable><literal>,}</literal> </entry>
+ <entry> a sequence of <replaceable>m</replaceable> or more matches of the atom </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>{</literal><replaceable>m</replaceable><literal>,</literal><replaceable>n</replaceable><literal>}</literal> </entry>
+ <entry> a sequence of <replaceable>m</replaceable> through <replaceable>n</replaceable>
+ (inclusive) matches of the atom; <replaceable>m</replaceable> cannot exceed
+ <replaceable>n</replaceable> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>*?</literal> </entry>
+ <entry> non-greedy version of <literal>*</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>+?</literal> </entry>
+ <entry> non-greedy version of <literal>+</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>??</literal> </entry>
+ <entry> non-greedy version of <literal>?</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>{</literal><replaceable>m</replaceable><literal>}?</literal> </entry>
+ <entry> non-greedy version of <literal>{</literal><replaceable>m</replaceable><literal>}</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>{</literal><replaceable>m</replaceable><literal>,}?</literal> </entry>
+ <entry> non-greedy version of <literal>{</literal><replaceable>m</replaceable><literal>,}</literal> </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>{</literal><replaceable>m</replaceable><literal>,</literal><replaceable>n</replaceable><literal>}?</literal> </entry>
+ <entry> non-greedy version of <literal>{</literal><replaceable>m</replaceable><literal>,</literal><replaceable>n</replaceable><literal>}</literal> </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The forms using <literal>{</literal><replaceable>...</replaceable><literal>}</literal>
+ are known as <firstterm>bounds</firstterm>.
+ The numbers <replaceable>m</replaceable> and <replaceable>n</replaceable> within a bound are
+ unsigned decimal integers with permissible values from 0 to 255 inclusive.
+ </para>
+
+ <para>
+ <firstterm>Non-greedy</firstterm> quantifiers (available in AREs only) match the
+ same possibilities as their corresponding normal (<firstterm>greedy</firstterm>)
+ counterparts, but prefer the smallest number rather than the largest
+ number of matches.
+ See <xref linkend="posix-matching-rules"/> for more detail.
+ </para>
+
+ <note>
+ <para>
+ A quantifier cannot immediately follow another quantifier, e.g.,
+ <literal>**</literal> is invalid.
+ A quantifier cannot
+ begin an expression or subexpression or follow
+ <literal>^</literal> or <literal>|</literal>.
+ </para>
+ </note>
+
+ <table id="posix-constraints-table">
+ <title>Regular Expression Constraints</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Constraint</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>^</literal> </entry>
+ <entry> matches at the beginning of the string </entry>
+ </row>
+
+ <row>
+ <entry> <literal>$</literal> </entry>
+ <entry> matches at the end of the string </entry>
+ </row>
+
+ <row>
+ <entry> <literal>(?=</literal><replaceable>re</replaceable><literal>)</literal> </entry>
+ <entry> <firstterm>positive lookahead</firstterm> matches at any point
+ where a substring matching <replaceable>re</replaceable> begins
+ (AREs only) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>(?!</literal><replaceable>re</replaceable><literal>)</literal> </entry>
+ <entry> <firstterm>negative lookahead</firstterm> matches at any point
+ where no substring matching <replaceable>re</replaceable> begins
+ (AREs only) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>(?&lt;=</literal><replaceable>re</replaceable><literal>)</literal> </entry>
+ <entry> <firstterm>positive lookbehind</firstterm> matches at any point
+ where a substring matching <replaceable>re</replaceable> ends
+ (AREs only) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>(?&lt;!</literal><replaceable>re</replaceable><literal>)</literal> </entry>
+ <entry> <firstterm>negative lookbehind</firstterm> matches at any point
+ where no substring matching <replaceable>re</replaceable> ends
+ (AREs only) </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Lookahead and lookbehind constraints cannot contain <firstterm>back
+ references</firstterm> (see <xref linkend="posix-escape-sequences"/>),
+ and all parentheses within them are considered non-capturing.
+ </para>
+ </sect3>
+
+ <sect3 id="posix-bracket-expressions">
+ <title>Bracket Expressions</title>
+
+ <para>
+ A <firstterm>bracket expression</firstterm> is a list of
+ characters enclosed in <literal>[]</literal>. It normally matches
+ any single character from the list (but see below). If the list
+ begins with <literal>^</literal>, it matches any single character
+ <emphasis>not</emphasis> from the rest of the list.
+ If two characters
+ in the list are separated by <literal>-</literal>, this is
+ shorthand for the full range of characters between those two
+ (inclusive) in the collating sequence,
+ e.g., <literal>[0-9]</literal> in <acronym>ASCII</acronym> matches
+ any decimal digit. It is illegal for two ranges to share an
+ endpoint, e.g., <literal>a-c-e</literal>. Ranges are very
+ collating-sequence-dependent, so portable programs should avoid
+ relying on them.
+ </para>
+
+ <para>
+ To include a literal <literal>]</literal> in the list, make it the
+ first character (after <literal>^</literal>, if that is used). To
+ include a literal <literal>-</literal>, make it the first or last
+ character, or the second endpoint of a range. To use a literal
+ <literal>-</literal> as the first endpoint of a range, enclose it
+ in <literal>[.</literal> and <literal>.]</literal> to make it a
+ collating element (see below). With the exception of these characters,
+ some combinations using <literal>[</literal>
+ (see next paragraphs), and escapes (AREs only), all other special
+ characters lose their special significance within a bracket expression.
+ In particular, <literal>\</literal> is not special when following
+ ERE or BRE rules, though it is special (as introducing an escape)
+ in AREs.
+ </para>
+
+ <para>
+ Within a bracket expression, a collating element (a character, a
+ multiple-character sequence that collates as if it were a single
+ character, or a collating-sequence name for either) enclosed in
+ <literal>[.</literal> and <literal>.]</literal> stands for the
+ sequence of characters of that collating element. The sequence is
+ treated as a single element of the bracket expression's list. This
+ allows a bracket
+ expression containing a multiple-character collating element to
+ match more than one character, e.g., if the collating sequence
+ includes a <literal>ch</literal> collating element, then the RE
+ <literal>[[.ch.]]*c</literal> matches the first five characters of
+ <literal>chchcc</literal>.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> currently does not support multi-character collating
+ elements. This information describes possible future behavior.
+ </para>
+ </note>
+
+ <para>
+ Within a bracket expression, a collating element enclosed in
+ <literal>[=</literal> and <literal>=]</literal> is an <firstterm>equivalence
+ class</firstterm>, standing for the sequences of characters of all collating
+ elements equivalent to that one, including itself. (If there are
+ no other equivalent collating elements, the treatment is as if the
+ enclosing delimiters were <literal>[.</literal> and
+ <literal>.]</literal>.) For example, if <literal>o</literal> and
+ <literal>^</literal> are the members of an equivalence class, then
+ <literal>[[=o=]]</literal>, <literal>[[=^=]]</literal>, and
+ <literal>[o^]</literal> are all synonymous. An equivalence class
+ cannot be an endpoint of a range.
+ </para>
+
+ <para>
+ Within a bracket expression, the name of a character class
+ enclosed in <literal>[:</literal> and <literal>:]</literal> stands
+ for the list of all characters belonging to that class. A character
+ class cannot be used as an endpoint of a range.
+ The <acronym>POSIX</acronym> standard defines these character class
+ names:
+ <literal>alnum</literal> (letters and numeric digits),
+ <literal>alpha</literal> (letters),
+ <literal>blank</literal> (space and tab),
+ <literal>cntrl</literal> (control characters),
+ <literal>digit</literal> (numeric digits),
+ <literal>graph</literal> (printable characters except space),
+ <literal>lower</literal> (lower-case letters),
+ <literal>print</literal> (printable characters including space),
+ <literal>punct</literal> (punctuation),
+ <literal>space</literal> (any white space),
+ <literal>upper</literal> (upper-case letters),
+ and <literal>xdigit</literal> (hexadecimal digits).
+ The behavior of these standard character classes is generally
+ consistent across platforms for characters in the 7-bit ASCII set.
+ Whether a given non-ASCII character is considered to belong to one
+ of these classes depends on the <firstterm>collation</firstterm>
+ that is used for the regular-expression function or operator
+ (see <xref linkend="collation"/>), or by default on the
+ database's <envar>LC_CTYPE</envar> locale setting (see
+ <xref linkend="locale"/>). The classification of non-ASCII
+ characters can vary across platforms even in similarly-named
+ locales. (But the <literal>C</literal> locale never considers any
+ non-ASCII characters to belong to any of these classes.)
+ In addition to these standard character
+ classes, <productname>PostgreSQL</productname> defines
+ the <literal>word</literal> character class, which is the same as
+ <literal>alnum</literal> plus the underscore (<literal>_</literal>)
+ character, and
+ the <literal>ascii</literal> character class, which contains exactly
+ the 7-bit ASCII set.
+ </para>
+
+ <para>
+ There are two special cases of bracket expressions: the bracket
+ expressions <literal>[[:&lt;:]]</literal> and
+ <literal>[[:&gt;:]]</literal> are constraints,
+ matching empty strings at the beginning
+ and end of a word respectively. A word is defined as a sequence
+ of word characters that is neither preceded nor followed by word
+ characters. A word character is any character belonging to the
+ <literal>word</literal> character class, that is, any letter, digit,
+ or underscore. This is an extension, compatible with but not
+ specified by <acronym>POSIX</acronym> 1003.2, and should be used with
+ caution in software intended to be portable to other systems.
+ The constraint escapes described below are usually preferable; they
+ are no more standard, but are easier to type.
+ </para>
+ </sect3>
+
+ <sect3 id="posix-escape-sequences">
+ <title>Regular Expression Escapes</title>
+
+ <para>
+ <firstterm>Escapes</firstterm> are special sequences beginning with <literal>\</literal>
+ followed by an alphanumeric character. Escapes come in several varieties:
+ character entry, class shorthands, constraint escapes, and back references.
+ A <literal>\</literal> followed by an alphanumeric character but not constituting
+ a valid escape is illegal in AREs.
+ In EREs, there are no escapes: outside a bracket expression,
+ a <literal>\</literal> followed by an alphanumeric character merely stands for
+ that character as an ordinary character, and inside a bracket expression,
+ <literal>\</literal> is an ordinary character.
+ (The latter is the one actual incompatibility between EREs and AREs.)
+ </para>
+
+ <para>
+ <firstterm>Character-entry escapes</firstterm> exist to make it easier to specify
+ non-printing and other inconvenient characters in REs. They are
+ shown in <xref linkend="posix-character-entry-escapes-table"/>.
+ </para>
+
+ <para>
+ <firstterm>Class-shorthand escapes</firstterm> provide shorthands for certain
+ commonly-used character classes. They are
+ shown in <xref linkend="posix-class-shorthand-escapes-table"/>.
+ </para>
+
+ <para>
+ A <firstterm>constraint escape</firstterm> is a constraint,
+ matching the empty string if specific conditions are met,
+ written as an escape. They are
+ shown in <xref linkend="posix-constraint-escapes-table"/>.
+ </para>
+
+ <para>
+ A <firstterm>back reference</firstterm> (<literal>\</literal><replaceable>n</replaceable>) matches the
+ same string matched by the previous parenthesized subexpression specified
+ by the number <replaceable>n</replaceable>
+ (see <xref linkend="posix-constraint-backref-table"/>). For example,
+ <literal>([bc])\1</literal> matches <literal>bb</literal> or <literal>cc</literal>
+ but not <literal>bc</literal> or <literal>cb</literal>.
+ The subexpression must entirely precede the back reference in the RE.
+ Subexpressions are numbered in the order of their leading parentheses.
+ Non-capturing parentheses do not define subexpressions.
+ The back reference considers only the string characters matched by the
+ referenced subexpression, not any constraints contained in it. For
+ example, <literal>(^\d)\1</literal> will match <literal>22</literal>.
+ </para>
+
+ <table id="posix-character-entry-escapes-table">
+ <title>Regular Expression Character-Entry Escapes</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Escape</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>\a</literal> </entry>
+ <entry> alert (bell) character, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\b</literal> </entry>
+ <entry> backspace, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\B</literal> </entry>
+ <entry> synonym for backslash (<literal>\</literal>) to help reduce the need for backslash
+ doubling </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\c</literal><replaceable>X</replaceable> </entry>
+ <entry> (where <replaceable>X</replaceable> is any character) the character whose
+ low-order 5 bits are the same as those of
+ <replaceable>X</replaceable>, and whose other bits are all zero </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\e</literal> </entry>
+ <entry> the character whose collating-sequence name
+ is <literal>ESC</literal>,
+ or failing that, the character with octal value <literal>033</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\f</literal> </entry>
+ <entry> form feed, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\n</literal> </entry>
+ <entry> newline, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\r</literal> </entry>
+ <entry> carriage return, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\t</literal> </entry>
+ <entry> horizontal tab, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\u</literal><replaceable>wxyz</replaceable> </entry>
+ <entry> (where <replaceable>wxyz</replaceable> is exactly four hexadecimal digits)
+ the character whose hexadecimal value is
+ <literal>0x</literal><replaceable>wxyz</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\U</literal><replaceable>stuvwxyz</replaceable> </entry>
+ <entry> (where <replaceable>stuvwxyz</replaceable> is exactly eight hexadecimal
+ digits)
+ the character whose hexadecimal value is
+ <literal>0x</literal><replaceable>stuvwxyz</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\v</literal> </entry>
+ <entry> vertical tab, as in C </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\x</literal><replaceable>hhh</replaceable> </entry>
+ <entry> (where <replaceable>hhh</replaceable> is any sequence of hexadecimal
+ digits)
+ the character whose hexadecimal value is
+ <literal>0x</literal><replaceable>hhh</replaceable>
+ (a single character no matter how many hexadecimal digits are used)
+ </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\0</literal> </entry>
+ <entry> the character whose value is <literal>0</literal> (the null byte)</entry>
+ </row>
+
+ <row>
+ <entry> <literal>\</literal><replaceable>xy</replaceable> </entry>
+ <entry> (where <replaceable>xy</replaceable> is exactly two octal digits,
+ and is not a <firstterm>back reference</firstterm>)
+ the character whose octal value is
+ <literal>0</literal><replaceable>xy</replaceable> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\</literal><replaceable>xyz</replaceable> </entry>
+ <entry> (where <replaceable>xyz</replaceable> is exactly three octal digits,
+ and is not a <firstterm>back reference</firstterm>)
+ the character whose octal value is
+ <literal>0</literal><replaceable>xyz</replaceable> </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Hexadecimal digits are <literal>0</literal>-<literal>9</literal>,
+ <literal>a</literal>-<literal>f</literal>, and <literal>A</literal>-<literal>F</literal>.
+ Octal digits are <literal>0</literal>-<literal>7</literal>.
+ </para>
+
+ <para>
+ Numeric character-entry escapes specifying values outside the ASCII range
+ (0&ndash;127) have meanings dependent on the database encoding. When the
+ encoding is UTF-8, escape values are equivalent to Unicode code points,
+ for example <literal>\u1234</literal> means the character <literal>U+1234</literal>.
+ For other multibyte encodings, character-entry escapes usually just
+ specify the concatenation of the byte values for the character. If the
+ escape value does not correspond to any legal character in the database
+ encoding, no error will be raised, but it will never match any data.
+ </para>
+
+ <para>
+ The character-entry escapes are always taken as ordinary characters.
+ For example, <literal>\135</literal> is <literal>]</literal> in ASCII, but
+ <literal>\135</literal> does not terminate a bracket expression.
+ </para>
+
+ <table id="posix-class-shorthand-escapes-table">
+ <title>Regular Expression Class-Shorthand Escapes</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Escape</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>\d</literal> </entry>
+ <entry> matches any digit, like
+ <literal>[[:digit:]]</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\s</literal> </entry>
+ <entry> matches any whitespace character, like
+ <literal>[[:space:]]</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\w</literal> </entry>
+ <entry> matches any word character, like
+ <literal>[[:word:]]</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\D</literal> </entry>
+ <entry> matches any non-digit, like
+ <literal>[^[:digit:]]</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\S</literal> </entry>
+ <entry> matches any non-whitespace character, like
+ <literal>[^[:space:]]</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\W</literal> </entry>
+ <entry> matches any non-word character, like
+ <literal>[^[:word:]]</literal> </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The class-shorthand escapes also work within bracket expressions,
+ although the definitions shown above are not quite syntactically
+ valid in that context.
+ For example, <literal>[a-c\d]</literal> is equivalent to
+ <literal>[a-c[:digit:]]</literal>.
+ </para>
+
+ <table id="posix-constraint-escapes-table">
+ <title>Regular Expression Constraint Escapes</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Escape</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>\A</literal> </entry>
+ <entry> matches only at the beginning of the string
+ (see <xref linkend="posix-matching-rules"/> for how this differs from
+ <literal>^</literal>) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\m</literal> </entry>
+ <entry> matches only at the beginning of a word </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\M</literal> </entry>
+ <entry> matches only at the end of a word </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\y</literal> </entry>
+ <entry> matches only at the beginning or end of a word </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\Y</literal> </entry>
+ <entry> matches only at a point that is not the beginning or end of a
+ word </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\Z</literal> </entry>
+ <entry> matches only at the end of the string
+ (see <xref linkend="posix-matching-rules"/> for how this differs from
+ <literal>$</literal>) </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ A word is defined as in the specification of
+ <literal>[[:&lt;:]]</literal> and <literal>[[:&gt;:]]</literal> above.
+ Constraint escapes are illegal within bracket expressions.
+ </para>
+
+ <table id="posix-constraint-backref-table">
+ <title>Regular Expression Back References</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Escape</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>\</literal><replaceable>m</replaceable> </entry>
+ <entry> (where <replaceable>m</replaceable> is a nonzero digit)
+ a back reference to the <replaceable>m</replaceable>'th subexpression </entry>
+ </row>
+
+ <row>
+ <entry> <literal>\</literal><replaceable>mnn</replaceable> </entry>
+ <entry> (where <replaceable>m</replaceable> is a nonzero digit, and
+ <replaceable>nn</replaceable> is some more digits, and the decimal value
+ <replaceable>mnn</replaceable> is not greater than the number of closing capturing
+ parentheses seen so far)
+ a back reference to the <replaceable>mnn</replaceable>'th subexpression </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ There is an inherent ambiguity between octal character-entry
+ escapes and back references, which is resolved by the following heuristics,
+ as hinted at above.
+ A leading zero always indicates an octal escape.
+ A single non-zero digit, not followed by another digit,
+ is always taken as a back reference.
+ A multi-digit sequence not starting with a zero is taken as a back
+ reference if it comes after a suitable subexpression
+ (i.e., the number is in the legal range for a back reference),
+ and otherwise is taken as octal.
+ </para>
+ </note>
+ </sect3>
+
+ <sect3 id="posix-metasyntax">
+ <title>Regular Expression Metasyntax</title>
+
+ <para>
+ In addition to the main syntax described above, there are some special
+ forms and miscellaneous syntactic facilities available.
+ </para>
+
+ <para>
+ An RE can begin with one of two special <firstterm>director</firstterm> prefixes.
+ If an RE begins with <literal>***:</literal>,
+ the rest of the RE is taken as an ARE. (This normally has no effect in
+ <productname>PostgreSQL</productname>, since REs are assumed to be AREs;
+ but it does have an effect if ERE or BRE mode had been specified by
+ the <replaceable>flags</replaceable> parameter to a regex function.)
+ If an RE begins with <literal>***=</literal>,
+ the rest of the RE is taken to be a literal string,
+ with all characters considered ordinary characters.
+ </para>
+
+ <para>
+ An ARE can begin with <firstterm>embedded options</firstterm>:
+ a sequence <literal>(?</literal><replaceable>xyz</replaceable><literal>)</literal>
+ (where <replaceable>xyz</replaceable> is one or more alphabetic characters)
+ specifies options affecting the rest of the RE.
+ These options override any previously determined options &mdash;
+ in particular, they can override the case-sensitivity behavior implied by
+ a regex operator, or the <replaceable>flags</replaceable> parameter to a regex
+ function.
+ The available option letters are
+ shown in <xref linkend="posix-embedded-options-table"/>.
+ Note that these same option letters are used in the <replaceable>flags</replaceable>
+ parameters of regex functions.
+ </para>
+
+ <table id="posix-embedded-options-table">
+ <title>ARE Embedded-Option Letters</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>b</literal> </entry>
+ <entry> rest of RE is a BRE </entry>
+ </row>
+
+ <row>
+ <entry> <literal>c</literal> </entry>
+ <entry> case-sensitive matching (overrides operator type) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>e</literal> </entry>
+ <entry> rest of RE is an ERE </entry>
+ </row>
+
+ <row>
+ <entry> <literal>i</literal> </entry>
+ <entry> case-insensitive matching (see
+ <xref linkend="posix-matching-rules"/>) (overrides operator type) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>m</literal> </entry>
+ <entry> historical synonym for <literal>n</literal> </entry>
+ </row>
+
+ <row>
+ <entry> <literal>n</literal> </entry>
+ <entry> newline-sensitive matching (see
+ <xref linkend="posix-matching-rules"/>) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>p</literal> </entry>
+ <entry> partial newline-sensitive matching (see
+ <xref linkend="posix-matching-rules"/>) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>q</literal> </entry>
+ <entry> rest of RE is a literal (<quote>quoted</quote>) string, all ordinary
+ characters </entry>
+ </row>
+
+ <row>
+ <entry> <literal>s</literal> </entry>
+ <entry> non-newline-sensitive matching (default) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>t</literal> </entry>
+ <entry> tight syntax (default; see below) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>w</literal> </entry>
+ <entry> inverse partial newline-sensitive (<quote>weird</quote>) matching
+ (see <xref linkend="posix-matching-rules"/>) </entry>
+ </row>
+
+ <row>
+ <entry> <literal>x</literal> </entry>
+ <entry> expanded syntax (see below) </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Embedded options take effect at the <literal>)</literal> terminating the sequence.
+ They can appear only at the start of an ARE (after the
+ <literal>***:</literal> director if any).
+ </para>
+
+ <para>
+ In addition to the usual (<firstterm>tight</firstterm>) RE syntax, in which all
+ characters are significant, there is an <firstterm>expanded</firstterm> syntax,
+ available by specifying the embedded <literal>x</literal> option.
+ In the expanded syntax,
+ white-space characters in the RE are ignored, as are
+ all characters between a <literal>#</literal>
+ and the following newline (or the end of the RE). This
+ permits paragraphing and commenting a complex RE.
+ There are three exceptions to that basic rule:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ a white-space character or <literal>#</literal> preceded by <literal>\</literal> is
+ retained
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ white space or <literal>#</literal> within a bracket expression is retained
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ white space and comments cannot appear within multi-character symbols,
+ such as <literal>(?:</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ For this purpose, white-space characters are blank, tab, newline, and
+ any character that belongs to the <replaceable>space</replaceable> character class.
+ </para>
+
+ <para>
+ Finally, in an ARE, outside bracket expressions, the sequence
+ <literal>(?#</literal><replaceable>ttt</replaceable><literal>)</literal>
+ (where <replaceable>ttt</replaceable> is any text not containing a <literal>)</literal>)
+ is a comment, completely ignored.
+ Again, this is not allowed between the characters of
+ multi-character symbols, like <literal>(?:</literal>.
+ Such comments are more a historical artifact than a useful facility,
+ and their use is deprecated; use the expanded syntax instead.
+ </para>
+
+ <para>
+ <emphasis>None</emphasis> of these metasyntax extensions is available if
+ an initial <literal>***=</literal> director
+ has specified that the user's input be treated as a literal string
+ rather than as an RE.
+ </para>
+ </sect3>
+
+ <sect3 id="posix-matching-rules">
+ <title>Regular Expression Matching Rules</title>
+
+ <para>
+ In the event that an RE could match more than one substring of a given
+ string, the RE matches the one starting earliest in the string.
+ If the RE could match more than one substring starting at that point,
+ either the longest possible match or the shortest possible match will
+ be taken, depending on whether the RE is <firstterm>greedy</firstterm> or
+ <firstterm>non-greedy</firstterm>.
+ </para>
+
+ <para>
+ Whether an RE is greedy or not is determined by the following rules:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Most atoms, and all constraints, have no greediness attribute (because
+ they cannot match variable amounts of text anyway).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Adding parentheses around an RE does not change its greediness.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A quantified atom with a fixed-repetition quantifier
+ (<literal>{</literal><replaceable>m</replaceable><literal>}</literal>
+ or
+ <literal>{</literal><replaceable>m</replaceable><literal>}?</literal>)
+ has the same greediness (possibly none) as the atom itself.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A quantified atom with other normal quantifiers (including
+ <literal>{</literal><replaceable>m</replaceable><literal>,</literal><replaceable>n</replaceable><literal>}</literal>
+ with <replaceable>m</replaceable> equal to <replaceable>n</replaceable>)
+ is greedy (prefers longest match).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A quantified atom with a non-greedy quantifier (including
+ <literal>{</literal><replaceable>m</replaceable><literal>,</literal><replaceable>n</replaceable><literal>}?</literal>
+ with <replaceable>m</replaceable> equal to <replaceable>n</replaceable>)
+ is non-greedy (prefers shortest match).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A branch &mdash; that is, an RE that has no top-level
+ <literal>|</literal> operator &mdash; has the same greediness as the first
+ quantified atom in it that has a greediness attribute.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An RE consisting of two or more branches connected by the
+ <literal>|</literal> operator is always greedy.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The above rules associate greediness attributes not only with individual
+ quantified atoms, but with branches and entire REs that contain quantified
+ atoms. What that means is that the matching is done in such a way that
+ the branch, or whole RE, matches the longest or shortest possible
+ substring <emphasis>as a whole</emphasis>. Once the length of the entire match
+ is determined, the part of it that matches any particular subexpression
+ is determined on the basis of the greediness attribute of that
+ subexpression, with subexpressions starting earlier in the RE taking
+ priority over ones starting later.
+ </para>
+
+ <para>
+ An example of what this means:
+<screen>
+SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
+<lineannotation>Result: </lineannotation><computeroutput>123</computeroutput>
+SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
+<lineannotation>Result: </lineannotation><computeroutput>1</computeroutput>
+</screen>
+ In the first case, the RE as a whole is greedy because <literal>Y*</literal>
+ is greedy. It can match beginning at the <literal>Y</literal>, and it matches
+ the longest possible string starting there, i.e., <literal>Y123</literal>.
+ The output is the parenthesized part of that, or <literal>123</literal>.
+ In the second case, the RE as a whole is non-greedy because <literal>Y*?</literal>
+ is non-greedy. It can match beginning at the <literal>Y</literal>, and it matches
+ the shortest possible string starting there, i.e., <literal>Y1</literal>.
+ The subexpression <literal>[0-9]{1,3}</literal> is greedy but it cannot change
+ the decision as to the overall match length; so it is forced to match
+ just <literal>1</literal>.
+ </para>
+
+ <para>
+ In short, when an RE contains both greedy and non-greedy subexpressions,
+ the total match length is either as long as possible or as short as
+ possible, according to the attribute assigned to the whole RE. The
+ attributes assigned to the subexpressions only affect how much of that
+ match they are allowed to <quote>eat</quote> relative to each other.
+ </para>
+
+ <para>
+ The quantifiers <literal>{1,1}</literal> and <literal>{1,1}?</literal>
+ can be used to force greediness or non-greediness, respectively,
+ on a subexpression or a whole RE.
+ This is useful when you need the whole RE to have a greediness attribute
+ different from what's deduced from its elements. As an example,
+ suppose that we are trying to separate a string containing some digits
+ into the digits and the parts before and after them. We might try to
+ do that like this:
+<screen>
+SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
+<lineannotation>Result: </lineannotation><computeroutput>{abc0123,4,xyz}</computeroutput>
+</screen>
+ That didn't work: the first <literal>.*</literal> is greedy so
+ it <quote>eats</quote> as much as it can, leaving the <literal>\d+</literal> to
+ match at the last possible place, the last digit. We might try to fix
+ that by making it non-greedy:
+<screen>
+SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
+<lineannotation>Result: </lineannotation><computeroutput>{abc,0,""}</computeroutput>
+</screen>
+ That didn't work either, because now the RE as a whole is non-greedy
+ and so it ends the overall match as soon as possible. We can get what
+ we want by forcing the RE as a whole to be greedy:
+<screen>
+SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
+<lineannotation>Result: </lineannotation><computeroutput>{abc,01234,xyz}</computeroutput>
+</screen>
+ Controlling the RE's overall greediness separately from its components'
+ greediness allows great flexibility in handling variable-length patterns.
+ </para>
+
+ <para>
+ When deciding what is a longer or shorter match,
+ match lengths are measured in characters, not collating elements.
+ An empty string is considered longer than no match at all.
+ For example:
+ <literal>bb*</literal>
+ matches the three middle characters of <literal>abbbc</literal>;
+ <literal>(week|wee)(night|knights)</literal>
+ matches all ten characters of <literal>weeknights</literal>;
+ when <literal>(.*).*</literal>
+ is matched against <literal>abc</literal> the parenthesized subexpression
+ matches all three characters; and when
+ <literal>(a*)*</literal> is matched against <literal>bc</literal>
+ both the whole RE and the parenthesized
+ subexpression match an empty string.
+ </para>
+
+ <para>
+ If case-independent matching is specified,
+ the effect is much as if all case distinctions had vanished from the
+ alphabet.
+ When an alphabetic that exists in multiple cases appears as an
+ ordinary character outside a bracket expression, it is effectively
+ transformed into a bracket expression containing both cases,
+ e.g., <literal>x</literal> becomes <literal>[xX]</literal>.
+ When it appears inside a bracket expression, all case counterparts
+ of it are added to the bracket expression, e.g.,
+ <literal>[x]</literal> becomes <literal>[xX]</literal>
+ and <literal>[^x]</literal> becomes <literal>[^xX]</literal>.
+ </para>
+
+ <para>
+ If newline-sensitive matching is specified, <literal>.</literal>
+ and bracket expressions using <literal>^</literal>
+ will never match the newline character
+ (so that matches will not cross lines unless the RE
+ explicitly includes a newline)
+ and <literal>^</literal> and <literal>$</literal>
+ will match the empty string after and before a newline
+ respectively, in addition to matching at beginning and end of string
+ respectively.
+ But the ARE escapes <literal>\A</literal> and <literal>\Z</literal>
+ continue to match beginning or end of string <emphasis>only</emphasis>.
+ Also, the character class shorthands <literal>\D</literal>
+ and <literal>\W</literal> will match a newline regardless of this mode.
+ (Before <productname>PostgreSQL</productname> 14, they did not match
+ newlines when in newline-sensitive mode.
+ Write <literal>[^[:digit:]]</literal>
+ or <literal>[^[:word:]]</literal> to get the old behavior.)
+ </para>
+
+ <para>
+ If partial newline-sensitive matching is specified,
+ this affects <literal>.</literal> and bracket expressions
+ as with newline-sensitive matching, but not <literal>^</literal>
+ and <literal>$</literal>.
+ </para>
+
+ <para>
+ If inverse partial newline-sensitive matching is specified,
+ this affects <literal>^</literal> and <literal>$</literal>
+ as with newline-sensitive matching, but not <literal>.</literal>
+ and bracket expressions.
+ This isn't very useful but is provided for symmetry.
+ </para>
+ </sect3>
+
+ <sect3 id="posix-limits-compatibility">
+ <title>Limits and Compatibility</title>
+
+ <para>
+ No particular limit is imposed on the length of REs in this
+ implementation. However,
+ programs intended to be highly portable should not employ REs longer
+ than 256 bytes,
+ as a POSIX-compliant implementation can refuse to accept such REs.
+ </para>
+
+ <para>
+ The only feature of AREs that is actually incompatible with
+ POSIX EREs is that <literal>\</literal> does not lose its special
+ significance inside bracket expressions.
+ All other ARE features use syntax which is illegal or has
+ undefined or unspecified effects in POSIX EREs;
+ the <literal>***</literal> syntax of directors likewise is outside the POSIX
+ syntax for both BREs and EREs.
+ </para>
+
+ <para>
+ Many of the ARE extensions are borrowed from Perl, but some have
+ been changed to clean them up, and a few Perl extensions are not present.
+ Incompatibilities of note include <literal>\b</literal>, <literal>\B</literal>,
+ the lack of special treatment for a trailing newline,
+ the addition of complemented bracket expressions to the things
+ affected by newline-sensitive matching,
+ the restrictions on parentheses and back references in lookahead/lookbehind
+ constraints, and the longest/shortest-match (rather than first-match)
+ matching semantics.
+ </para>
+ </sect3>
+
+ <sect3 id="posix-basic-regexes">
+ <title>Basic Regular Expressions</title>
+
+ <para>
+ BREs differ from EREs in several respects.
+ In BREs, <literal>|</literal>, <literal>+</literal>, and <literal>?</literal>
+ are ordinary characters and there is no equivalent
+ for their functionality.
+ The delimiters for bounds are
+ <literal>\{</literal> and <literal>\}</literal>,
+ with <literal>{</literal> and <literal>}</literal>
+ by themselves ordinary characters.
+ The parentheses for nested subexpressions are
+ <literal>\(</literal> and <literal>\)</literal>,
+ with <literal>(</literal> and <literal>)</literal> by themselves ordinary characters.
+ <literal>^</literal> is an ordinary character except at the beginning of the
+ RE or the beginning of a parenthesized subexpression,
+ <literal>$</literal> is an ordinary character except at the end of the
+ RE or the end of a parenthesized subexpression,
+ and <literal>*</literal> is an ordinary character if it appears at the beginning
+ of the RE or the beginning of a parenthesized subexpression
+ (after a possible leading <literal>^</literal>).
+ Finally, single-digit back references are available, and
+ <literal>\&lt;</literal> and <literal>\&gt;</literal>
+ are synonyms for
+ <literal>[[:&lt;:]]</literal> and <literal>[[:&gt;:]]</literal>
+ respectively; no other escapes are available in BREs.
+ </para>
+ </sect3>
+
+<!-- end re_syntax.n man page -->
+
+ <sect3 id="posix-vs-xquery">
+ <title>Differences from SQL Standard and XQuery</title>
+
+ <indexterm zone="posix-vs-xquery">
+ <primary>LIKE_REGEX</primary>
+ </indexterm>
+
+ <indexterm zone="posix-vs-xquery">
+ <primary>OCCURRENCES_REGEX</primary>
+ </indexterm>
+
+ <indexterm zone="posix-vs-xquery">
+ <primary>POSITION_REGEX</primary>
+ </indexterm>
+
+ <indexterm zone="posix-vs-xquery">
+ <primary>SUBSTRING_REGEX</primary>
+ </indexterm>
+
+ <indexterm zone="posix-vs-xquery">
+ <primary>TRANSLATE_REGEX</primary>
+ </indexterm>
+
+ <indexterm zone="posix-vs-xquery">
+ <primary>XQuery regular expressions</primary>
+ </indexterm>
+
+ <para>
+ Since SQL:2008, the SQL standard includes regular expression operators
+ and functions that performs pattern
+ matching according to the XQuery regular expression
+ standard:
+ <itemizedlist>
+ <listitem><para><literal>LIKE_REGEX</literal></para></listitem>
+ <listitem><para><literal>OCCURRENCES_REGEX</literal></para></listitem>
+ <listitem><para><literal>POSITION_REGEX</literal></para></listitem>
+ <listitem><para><literal>SUBSTRING_REGEX</literal></para></listitem>
+ <listitem><para><literal>TRANSLATE_REGEX</literal></para></listitem>
+ </itemizedlist>
+ <productname>PostgreSQL</productname> does not currently implement these
+ operators and functions. You can get approximately equivalent
+ functionality in each case as shown in <xref
+ linkend="functions-regexp-sql-table"/>. (Various optional clauses on
+ both sides have been omitted in this table.)
+ </para>
+
+ <table id="functions-regexp-sql-table">
+ <title>Regular Expression Functions Equivalencies</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>SQL standard</entry>
+ <entry>PostgreSQL</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal><replaceable>string</replaceable> LIKE_REGEX <replaceable>pattern</replaceable></literal></entry>
+ <entry><literal>regexp_like(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>)</literal> or <literal><replaceable>string</replaceable> ~ <replaceable>pattern</replaceable></literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>OCCURRENCES_REGEX(<replaceable>pattern</replaceable> IN <replaceable>string</replaceable>)</literal></entry>
+ <entry><literal>regexp_count(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>)</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>POSITION_REGEX(<replaceable>pattern</replaceable> IN <replaceable>string</replaceable>)</literal></entry>
+ <entry><literal>regexp_instr(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>)</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>SUBSTRING_REGEX(<replaceable>pattern</replaceable> IN <replaceable>string</replaceable>)</literal></entry>
+ <entry><literal>regexp_substr(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>)</literal></entry>
+ </row>
+
+ <row>
+ <entry><literal>TRANSLATE_REGEX(<replaceable>pattern</replaceable> IN <replaceable>string</replaceable> WITH <replaceable>replacement</replaceable>)</literal></entry>
+ <entry><literal>regexp_replace(<replaceable>string</replaceable>, <replaceable>pattern</replaceable>, <replaceable>replacement</replaceable>)</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Regular expression functions similar to those provided by PostgreSQL are
+ also available in a number of other SQL implementations, whereas the
+ SQL-standard functions are not as widely implemented. Some of the
+ details of the regular expression syntax will likely differ in each
+ implementation.
+ </para>
+
+ <para>
+ The SQL-standard operators and functions use XQuery regular expressions,
+ which are quite close to the ARE syntax described above.
+ Notable differences between the existing POSIX-based
+ regular-expression feature and XQuery regular expressions include:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ XQuery character class subtraction is not supported. An example of
+ this feature is using the following to match only English
+ consonants: <literal>[a-z-[aeiou]]</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ XQuery character class shorthands <literal>\c</literal>,
+ <literal>\C</literal>, <literal>\i</literal>,
+ and <literal>\I</literal> are not supported.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ XQuery character class elements
+ using <literal>\p{UnicodeProperty}</literal> or the
+ inverse <literal>\P{UnicodeProperty}</literal> are not supported.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ POSIX interprets character classes such as <literal>\w</literal>
+ (see <xref linkend="posix-class-shorthand-escapes-table"/>)
+ according to the prevailing locale (which you can control by
+ attaching a <literal>COLLATE</literal> clause to the operator or
+ function). XQuery specifies these classes by reference to Unicode
+ character properties, so equivalent behavior is obtained only with
+ a locale that follows the Unicode rules.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The SQL standard (not XQuery itself) attempts to cater for more
+ variants of <quote>newline</quote> than POSIX does. The
+ newline-sensitive matching options described above consider only
+ ASCII NL (<literal>\n</literal>) to be a newline, but SQL would have
+ us treat CR (<literal>\r</literal>), CRLF (<literal>\r\n</literal>)
+ (a Windows-style newline), and some Unicode-only characters like
+ LINE SEPARATOR (U+2028) as newlines as well.
+ Notably, <literal>.</literal> and <literal>\s</literal> should
+ count <literal>\r\n</literal> as one character not two according to
+ SQL.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Of the character-entry escapes described in
+ <xref linkend="posix-character-entry-escapes-table"/>,
+ XQuery supports only <literal>\n</literal>, <literal>\r</literal>,
+ and <literal>\t</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ XQuery does not support
+ the <literal>[:<replaceable>name</replaceable>:]</literal> syntax
+ for character classes within bracket expressions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ XQuery does not have lookahead or lookbehind constraints,
+ nor any of the constraint escapes described in
+ <xref linkend="posix-constraint-escapes-table"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The metasyntax forms described in <xref linkend="posix-metasyntax"/>
+ do not exist in XQuery.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The regular expression flag letters defined by XQuery are
+ related to but not the same as the option letters for POSIX
+ (<xref linkend="posix-embedded-options-table"/>). While the
+ <literal>i</literal> and <literal>q</literal> options behave the
+ same, others do not:
+ <itemizedlist>
+ <listitem>
+ <para>
+ XQuery's <literal>s</literal> (allow dot to match newline)
+ and <literal>m</literal> (allow <literal>^</literal>
+ and <literal>$</literal> to match at newlines) flags provide
+ access to the same behaviors as
+ POSIX's <literal>n</literal>, <literal>p</literal>
+ and <literal>w</literal> flags, but they
+ do <emphasis>not</emphasis> match the behavior of
+ POSIX's <literal>s</literal> and <literal>m</literal> flags.
+ Note in particular that dot-matches-newline is the default
+ behavior in POSIX but not XQuery.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ XQuery's <literal>x</literal> (ignore whitespace in pattern) flag
+ is noticeably different from POSIX's expanded-mode flag.
+ POSIX's <literal>x</literal> flag also
+ allows <literal>#</literal> to begin a comment in the pattern,
+ and POSIX will not ignore a whitespace character after a
+ backslash.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect3>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="functions-formatting">
+ <title>Data Type Formatting Functions</title>
+
+ <indexterm>
+ <primary>formatting</primary>
+ </indexterm>
+
+ <para>
+ The <productname>PostgreSQL</productname> formatting functions
+ provide a powerful set of tools for converting various data types
+ (date/time, integer, floating point, numeric) to formatted strings
+ and for converting from formatted strings to specific data types.
+ <xref linkend="functions-formatting-table"/> lists them.
+ These functions all follow a common calling convention: the first
+ argument is the value to be formatted and the second argument is a
+ template that defines the output or input format.
+ </para>
+
+ <table id="functions-formatting-table">
+ <title>Formatting Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_char</primary>
+ </indexterm>
+ <function>to_char</function> ( <type>timestamp</type>, <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>to_char</function> ( <type>timestamp with time zone</type>, <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts time stamp to string according to the given format.
+ </para>
+ <para>
+ <literal>to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS')</literal>
+ <returnvalue>05:31:12</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>to_char</function> ( <type>interval</type>, <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts interval to string according to the given format.
+ </para>
+ <para>
+ <literal>to_char(interval '15h 2m 12s', 'HH24:MI:SS')</literal>
+ <returnvalue>15:02:12</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>to_char</function> ( <replaceable>numeric_type</replaceable>, <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts number to string according to the given format; available
+ for <type>integer</type>, <type>bigint</type>, <type>numeric</type>,
+ <type>real</type>, <type>double precision</type>.
+ </para>
+ <para>
+ <literal>to_char(125, '999')</literal>
+ <returnvalue>125</returnvalue>
+ </para>
+ <para>
+ <literal>to_char(125.8::real, '999D9')</literal>
+ <returnvalue>125.8</returnvalue>
+ </para>
+ <para>
+ <literal>to_char(-125.8, '999D99S')</literal>
+ <returnvalue>125.80-</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_date</primary>
+ </indexterm>
+ <function>to_date</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>date</returnvalue>
+ </para>
+ <para>
+ Converts string to date according to the given format.
+ </para>
+ <para>
+ <literal>to_date('05 Dec 2000', 'DD Mon YYYY')</literal>
+ <returnvalue>2000-12-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_number</primary>
+ </indexterm>
+ <function>to_number</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Converts string to numeric according to the given format.
+ </para>
+ <para>
+ <literal>to_number('12,454.8-', '99G999D9S')</literal>
+ <returnvalue>-12454.8</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_timestamp</primary>
+ </indexterm>
+ <function>to_timestamp</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Converts string to time stamp according to the given format.
+ (See also <function>to_timestamp(double precision)</function> in
+ <xref linkend="functions-datetime-table"/>.)
+ </para>
+ <para>
+ <literal>to_timestamp('05 Dec 2000', 'DD Mon YYYY')</literal>
+ <returnvalue>2000-12-05 00:00:00-05</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <tip>
+ <para>
+ <function>to_timestamp</function> and <function>to_date</function>
+ exist to handle input formats that cannot be converted by
+ simple casting. For most standard date/time formats, simply casting the
+ source string to the required data type works, and is much easier.
+ Similarly, <function>to_number</function> is unnecessary for standard numeric
+ representations.
+ </para>
+ </tip>
+
+ <para>
+ In a <function>to_char</function> output template string, there are certain
+ patterns that are recognized and replaced with appropriately-formatted
+ data based on the given value. Any text that is not a template pattern is
+ simply copied verbatim. Similarly, in an input template string (for the
+ other functions), template patterns identify the values to be supplied by
+ the input data string. If there are characters in the template string
+ that are not template patterns, the corresponding characters in the input
+ data string are simply skipped over (whether or not they are equal to the
+ template string characters).
+ </para>
+
+ <para>
+ <xref linkend="functions-formatting-datetime-table"/> shows the
+ template patterns available for formatting date and time values.
+ </para>
+
+ <table id="functions-formatting-datetime-table">
+ <title>Template Patterns for Date/Time Formatting</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Pattern</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>HH</literal></entry>
+ <entry>hour of day (01&ndash;12)</entry>
+ </row>
+ <row>
+ <entry><literal>HH12</literal></entry>
+ <entry>hour of day (01&ndash;12)</entry>
+ </row>
+ <row>
+ <entry><literal>HH24</literal></entry>
+ <entry>hour of day (00&ndash;23)</entry>
+ </row>
+ <row>
+ <entry><literal>MI</literal></entry>
+ <entry>minute (00&ndash;59)</entry>
+ </row>
+ <row>
+ <entry><literal>SS</literal></entry>
+ <entry>second (00&ndash;59)</entry>
+ </row>
+ <row>
+ <entry><literal>MS</literal></entry>
+ <entry>millisecond (000&ndash;999)</entry>
+ </row>
+ <row>
+ <entry><literal>US</literal></entry>
+ <entry>microsecond (000000&ndash;999999)</entry>
+ </row>
+ <row>
+ <entry><literal>FF1</literal></entry>
+ <entry>tenth of second (0&ndash;9)</entry>
+ </row>
+ <row>
+ <entry><literal>FF2</literal></entry>
+ <entry>hundredth of second (00&ndash;99)</entry>
+ </row>
+ <row>
+ <entry><literal>FF3</literal></entry>
+ <entry>millisecond (000&ndash;999)</entry>
+ </row>
+ <row>
+ <entry><literal>FF4</literal></entry>
+ <entry>tenth of a millisecond (0000&ndash;9999)</entry>
+ </row>
+ <row>
+ <entry><literal>FF5</literal></entry>
+ <entry>hundredth of a millisecond (00000&ndash;99999)</entry>
+ </row>
+ <row>
+ <entry><literal>FF6</literal></entry>
+ <entry>microsecond (000000&ndash;999999)</entry>
+ </row>
+ <row>
+ <entry><literal>SSSS</literal>, <literal>SSSSS</literal></entry>
+ <entry>seconds past midnight (0&ndash;86399)</entry>
+ </row>
+ <row>
+ <entry><literal>AM</literal>, <literal>am</literal>,
+ <literal>PM</literal> or <literal>pm</literal></entry>
+ <entry>meridiem indicator (without periods)</entry>
+ </row>
+ <row>
+ <entry><literal>A.M.</literal>, <literal>a.m.</literal>,
+ <literal>P.M.</literal> or <literal>p.m.</literal></entry>
+ <entry>meridiem indicator (with periods)</entry>
+ </row>
+ <row>
+ <entry><literal>Y,YYY</literal></entry>
+ <entry>year (4 or more digits) with comma</entry>
+ </row>
+ <row>
+ <entry><literal>YYYY</literal></entry>
+ <entry>year (4 or more digits)</entry>
+ </row>
+ <row>
+ <entry><literal>YYY</literal></entry>
+ <entry>last 3 digits of year</entry>
+ </row>
+ <row>
+ <entry><literal>YY</literal></entry>
+ <entry>last 2 digits of year</entry>
+ </row>
+ <row>
+ <entry><literal>Y</literal></entry>
+ <entry>last digit of year</entry>
+ </row>
+ <row>
+ <entry><literal>IYYY</literal></entry>
+ <entry>ISO 8601 week-numbering year (4 or more digits)</entry>
+ </row>
+ <row>
+ <entry><literal>IYY</literal></entry>
+ <entry>last 3 digits of ISO 8601 week-numbering year</entry>
+ </row>
+ <row>
+ <entry><literal>IY</literal></entry>
+ <entry>last 2 digits of ISO 8601 week-numbering year</entry>
+ </row>
+ <row>
+ <entry><literal>I</literal></entry>
+ <entry>last digit of ISO 8601 week-numbering year</entry>
+ </row>
+ <row>
+ <entry><literal>BC</literal>, <literal>bc</literal>,
+ <literal>AD</literal> or <literal>ad</literal></entry>
+ <entry>era indicator (without periods)</entry>
+ </row>
+ <row>
+ <entry><literal>B.C.</literal>, <literal>b.c.</literal>,
+ <literal>A.D.</literal> or <literal>a.d.</literal></entry>
+ <entry>era indicator (with periods)</entry>
+ </row>
+ <row>
+ <entry><literal>MONTH</literal></entry>
+ <entry>full upper case month name (blank-padded to 9 chars)</entry>
+ </row>
+ <row>
+ <entry><literal>Month</literal></entry>
+ <entry>full capitalized month name (blank-padded to 9 chars)</entry>
+ </row>
+ <row>
+ <entry><literal>month</literal></entry>
+ <entry>full lower case month name (blank-padded to 9 chars)</entry>
+ </row>
+ <row>
+ <entry><literal>MON</literal></entry>
+ <entry>abbreviated upper case month name (3 chars in English, localized lengths vary)</entry>
+ </row>
+ <row>
+ <entry><literal>Mon</literal></entry>
+ <entry>abbreviated capitalized month name (3 chars in English, localized lengths vary)</entry>
+ </row>
+ <row>
+ <entry><literal>mon</literal></entry>
+ <entry>abbreviated lower case month name (3 chars in English, localized lengths vary)</entry>
+ </row>
+ <row>
+ <entry><literal>MM</literal></entry>
+ <entry>month number (01&ndash;12)</entry>
+ </row>
+ <row>
+ <entry><literal>DAY</literal></entry>
+ <entry>full upper case day name (blank-padded to 9 chars)</entry>
+ </row>
+ <row>
+ <entry><literal>Day</literal></entry>
+ <entry>full capitalized day name (blank-padded to 9 chars)</entry>
+ </row>
+ <row>
+ <entry><literal>day</literal></entry>
+ <entry>full lower case day name (blank-padded to 9 chars)</entry>
+ </row>
+ <row>
+ <entry><literal>DY</literal></entry>
+ <entry>abbreviated upper case day name (3 chars in English, localized lengths vary)</entry>
+ </row>
+ <row>
+ <entry><literal>Dy</literal></entry>
+ <entry>abbreviated capitalized day name (3 chars in English, localized lengths vary)</entry>
+ </row>
+ <row>
+ <entry><literal>dy</literal></entry>
+ <entry>abbreviated lower case day name (3 chars in English, localized lengths vary)</entry>
+ </row>
+ <row>
+ <entry><literal>DDD</literal></entry>
+ <entry>day of year (001&ndash;366)</entry>
+ </row>
+ <row>
+ <entry><literal>IDDD</literal></entry>
+ <entry>day of ISO 8601 week-numbering year (001&ndash;371; day 1 of the year is Monday of the first ISO week)</entry>
+ </row>
+ <row>
+ <entry><literal>DD</literal></entry>
+ <entry>day of month (01&ndash;31)</entry>
+ </row>
+ <row>
+ <entry><literal>D</literal></entry>
+ <entry>day of the week, Sunday (<literal>1</literal>) to Saturday (<literal>7</literal>)</entry>
+ </row>
+ <row>
+ <entry><literal>ID</literal></entry>
+ <entry>ISO 8601 day of the week, Monday (<literal>1</literal>) to Sunday (<literal>7</literal>)</entry>
+ </row>
+ <row>
+ <entry><literal>W</literal></entry>
+ <entry>week of month (1&ndash;5) (the first week starts on the first day of the month)</entry>
+ </row>
+ <row>
+ <entry><literal>WW</literal></entry>
+ <entry>week number of year (1&ndash;53) (the first week starts on the first day of the year)</entry>
+ </row>
+ <row>
+ <entry><literal>IW</literal></entry>
+ <entry>week number of ISO 8601 week-numbering year (01&ndash;53; the first Thursday of the year is in week 1)</entry>
+ </row>
+ <row>
+ <entry><literal>CC</literal></entry>
+ <entry>century (2 digits) (the twenty-first century starts on 2001-01-01)</entry>
+ </row>
+ <row>
+ <entry><literal>J</literal></entry>
+ <entry>Julian Date (integer days since November 24, 4714 BC at local
+ midnight; see <xref linkend="datetime-julian-dates"/>)</entry>
+ </row>
+ <row>
+ <entry><literal>Q</literal></entry>
+ <entry>quarter</entry>
+ </row>
+ <row>
+ <entry><literal>RM</literal></entry>
+ <entry>month in upper case Roman numerals (I&ndash;XII; I=January)</entry>
+ </row>
+ <row>
+ <entry><literal>rm</literal></entry>
+ <entry>month in lower case Roman numerals (i&ndash;xii; i=January)</entry>
+ </row>
+ <row>
+ <entry><literal>TZ</literal></entry>
+ <entry>upper case time-zone abbreviation
+ (only supported in <function>to_char</function>)</entry>
+ </row>
+ <row>
+ <entry><literal>tz</literal></entry>
+ <entry>lower case time-zone abbreviation
+ (only supported in <function>to_char</function>)</entry>
+ </row>
+ <row>
+ <entry><literal>TZH</literal></entry>
+ <entry>time-zone hours</entry>
+ </row>
+ <row>
+ <entry><literal>TZM</literal></entry>
+ <entry>time-zone minutes</entry>
+ </row>
+ <row>
+ <entry><literal>OF</literal></entry>
+ <entry>time-zone offset from UTC
+ (only supported in <function>to_char</function>)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Modifiers can be applied to any template pattern to alter its
+ behavior. For example, <literal>FMMonth</literal>
+ is the <literal>Month</literal> pattern with the
+ <literal>FM</literal> modifier.
+ <xref linkend="functions-formatting-datetimemod-table"/> shows the
+ modifier patterns for date/time formatting.
+ </para>
+
+ <table id="functions-formatting-datetimemod-table">
+ <title>Template Pattern Modifiers for Date/Time Formatting</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Modifier</entry>
+ <entry>Description</entry>
+ <entry>Example</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>FM</literal> prefix</entry>
+ <entry>fill mode (suppress leading zeroes and padding blanks)</entry>
+ <entry><literal>FMMonth</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TH</literal> suffix</entry>
+ <entry>upper case ordinal number suffix</entry>
+ <entry><literal>DDTH</literal>, e.g., <literal>12TH</literal></entry>
+ </row>
+ <row>
+ <entry><literal>th</literal> suffix</entry>
+ <entry>lower case ordinal number suffix</entry>
+ <entry><literal>DDth</literal>, e.g., <literal>12th</literal></entry>
+ </row>
+ <row>
+ <entry><literal>FX</literal> prefix</entry>
+ <entry>fixed format global option (see usage notes)</entry>
+ <entry><literal>FX&nbsp;Month&nbsp;DD&nbsp;Day</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TM</literal> prefix</entry>
+ <entry>translation mode (use localized day and month names based on
+ <xref linkend="guc-lc-time"/>)</entry>
+ <entry><literal>TMMonth</literal></entry>
+ </row>
+ <row>
+ <entry><literal>SP</literal> suffix</entry>
+ <entry>spell mode (not implemented)</entry>
+ <entry><literal>DDSP</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Usage notes for date/time formatting:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>FM</literal> suppresses leading zeroes and trailing blanks
+ that would otherwise be added to make the output of a pattern be
+ fixed-width. In <productname>PostgreSQL</productname>,
+ <literal>FM</literal> modifies only the next specification, while in
+ Oracle <literal>FM</literal> affects all subsequent
+ specifications, and repeated <literal>FM</literal> modifiers
+ toggle fill mode on and off.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>TM</literal> suppresses trailing blanks whether or
+ not <literal>FM</literal> is specified.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>to_timestamp</function> and <function>to_date</function>
+ ignore letter case in the input; so for
+ example <literal>MON</literal>, <literal>Mon</literal>,
+ and <literal>mon</literal> all accept the same strings. When using
+ the <literal>TM</literal> modifier, case-folding is done according to
+ the rules of the function's input collation (see
+ <xref linkend="collation"/>).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>to_timestamp</function> and <function>to_date</function>
+ skip multiple blank spaces at the beginning of the input string and
+ around date and time values unless the <literal>FX</literal> option is used. For example,
+ <literal>to_timestamp('&nbsp;2000&nbsp;&nbsp;&nbsp;&nbsp;JUN', 'YYYY MON')</literal> and
+ <literal>to_timestamp('2000 - JUN', 'YYYY-MON')</literal> work, but
+ <literal>to_timestamp('2000&nbsp;&nbsp;&nbsp;&nbsp;JUN', 'FXYYYY MON')</literal> returns an error
+ because <function>to_timestamp</function> expects only a single space.
+ <literal>FX</literal> must be specified as the first item in
+ the template.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A separator (a space or non-letter/non-digit character) in the template string of
+ <function>to_timestamp</function> and <function>to_date</function>
+ matches any single separator in the input string or is skipped,
+ unless the <literal>FX</literal> option is used.
+ For example, <literal>to_timestamp('2000JUN', 'YYYY///MON')</literal> and
+ <literal>to_timestamp('2000/JUN', 'YYYY MON')</literal> work, but
+ <literal>to_timestamp('2000//JUN', 'YYYY/MON')</literal>
+ returns an error because the number of separators in the input string
+ exceeds the number of separators in the template.
+ </para>
+ <para>
+ If <literal>FX</literal> is specified, a separator in the template string
+ matches exactly one character in the input string. But note that the
+ input string character is not required to be the same as the separator from the template string.
+ For example, <literal>to_timestamp('2000/JUN', 'FXYYYY MON')</literal>
+ works, but <literal>to_timestamp('2000/JUN', 'FXYYYY&nbsp;&nbsp;MON')</literal>
+ returns an error because the second space in the template string consumes
+ the letter <literal>J</literal> from the input string.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <literal>TZH</literal> template pattern can match a signed number.
+ Without the <literal>FX</literal> option, minus signs may be ambiguous,
+ and could be interpreted as a separator.
+ This ambiguity is resolved as follows: If the number of separators before
+ <literal>TZH</literal> in the template string is less than the number of
+ separators before the minus sign in the input string, the minus sign
+ is interpreted as part of <literal>TZH</literal>.
+ Otherwise, the minus sign is considered to be a separator between values.
+ For example, <literal>to_timestamp('2000 -10', 'YYYY TZH')</literal> matches
+ <literal>-10</literal> to <literal>TZH</literal>, but
+ <literal>to_timestamp('2000 -10', 'YYYY&nbsp;&nbsp;TZH')</literal>
+ matches <literal>10</literal> to <literal>TZH</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Ordinary text is allowed in <function>to_char</function>
+ templates and will be output literally. You can put a substring
+ in double quotes to force it to be interpreted as literal text
+ even if it contains template patterns. For example, in
+ <literal>'"Hello Year "YYYY'</literal>, the <literal>YYYY</literal>
+ will be replaced by the year data, but the single <literal>Y</literal> in <literal>Year</literal>
+ will not be.
+ In <function>to_date</function>, <function>to_number</function>,
+ and <function>to_timestamp</function>, literal text and double-quoted
+ strings result in skipping the number of characters contained in the
+ string; for example <literal>"XX"</literal> skips two input characters
+ (whether or not they are <literal>XX</literal>).
+ </para>
+ <tip>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 12, it was possible to
+ skip arbitrary text in the input string using non-letter or non-digit
+ characters. For example,
+ <literal>to_timestamp('2000y6m1d', 'yyyy-MM-DD')</literal> used to
+ work. Now you can only use letter characters for this purpose. For example,
+ <literal>to_timestamp('2000y6m1d', 'yyyytMMtDDt')</literal> and
+ <literal>to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"')</literal>
+ skip <literal>y</literal>, <literal>m</literal>, and
+ <literal>d</literal>.
+ </para>
+ </tip>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you want to have a double quote in the output you must
+ precede it with a backslash, for example <literal>'\"YYYY
+ Month\"'</literal>. <!-- "" font-lock sanity :-) -->
+ Backslashes are not otherwise special outside of double-quoted
+ strings. Within a double-quoted string, a backslash causes the
+ next character to be taken literally, whatever it is (but this
+ has no special effect unless the next character is a double quote
+ or another backslash).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function> and <function>to_date</function>,
+ if the year format specification is less than four digits, e.g.,
+ <literal>YYY</literal>, and the supplied year is less than four digits,
+ the year will be adjusted to be nearest to the year 2020, e.g.,
+ <literal>95</literal> becomes 1995.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function> and <function>to_date</function>,
+ negative years are treated as signifying BC. If you write both a
+ negative year and an explicit <literal>BC</literal> field, you get AD
+ again. An input of year zero is treated as 1 BC.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function> and <function>to_date</function>,
+ the <literal>YYYY</literal> conversion has a restriction when
+ processing years with more than 4 digits. You must
+ use some non-digit character or template after <literal>YYYY</literal>,
+ otherwise the year is always interpreted as 4 digits. For example
+ (with the year 20000):
+ <literal>to_date('200001131', 'YYYYMMDD')</literal> will be
+ interpreted as a 4-digit year; instead use a non-digit
+ separator after the year, like
+ <literal>to_date('20000-1131', 'YYYY-MMDD')</literal> or
+ <literal>to_date('20000Nov31', 'YYYYMonDD')</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function> and <function>to_date</function>,
+ the <literal>CC</literal> (century) field is accepted but ignored
+ if there is a <literal>YYY</literal>, <literal>YYYY</literal> or
+ <literal>Y,YYY</literal> field. If <literal>CC</literal> is used with
+ <literal>YY</literal> or <literal>Y</literal> then the result is
+ computed as that year in the specified century. If the century is
+ specified but the year is not, the first year of the century
+ is assumed.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function> and <function>to_date</function>,
+ weekday names or numbers (<literal>DAY</literal>, <literal>D</literal>,
+ and related field types) are accepted but are ignored for purposes of
+ computing the result. The same is true for quarter
+ (<literal>Q</literal>) fields.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function> and <function>to_date</function>,
+ an ISO 8601 week-numbering date (as distinct from a Gregorian date)
+ can be specified in one of two ways:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Year, week number, and weekday: for
+ example <literal>to_date('2006-42-4', 'IYYY-IW-ID')</literal>
+ returns the date <literal>2006-10-19</literal>.
+ If you omit the weekday it is assumed to be 1 (Monday).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Year and day of year: for example <literal>to_date('2006-291',
+ 'IYYY-IDDD')</literal> also returns <literal>2006-10-19</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Attempting to enter a date using a mixture of ISO 8601 week-numbering
+ fields and Gregorian date fields is nonsensical, and will cause an
+ error. In the context of an ISO 8601 week-numbering year, the
+ concept of a <quote>month</quote> or <quote>day of month</quote> has no
+ meaning. In the context of a Gregorian year, the ISO week has no
+ meaning.
+ </para>
+ <caution>
+ <para>
+ While <function>to_date</function> will reject a mixture of
+ Gregorian and ISO week-numbering date
+ fields, <function>to_char</function> will not, since output format
+ specifications like <literal>YYYY-MM-DD (IYYY-IDDD)</literal> can be
+ useful. But avoid writing something like <literal>IYYY-MM-DD</literal>;
+ that would yield surprising results near the start of the year.
+ (See <xref linkend="functions-datetime-extract"/> for more
+ information.)
+ </para>
+ </caution>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_timestamp</function>, millisecond
+ (<literal>MS</literal>) or microsecond (<literal>US</literal>)
+ fields are used as the
+ seconds digits after the decimal point. For example
+ <literal>to_timestamp('12.3', 'SS.MS')</literal> is not 3 milliseconds,
+ but 300, because the conversion treats it as 12 + 0.3 seconds.
+ So, for the format <literal>SS.MS</literal>, the input values
+ <literal>12.3</literal>, <literal>12.30</literal>,
+ and <literal>12.300</literal> specify the
+ same number of milliseconds. To get three milliseconds, one must write
+ <literal>12.003</literal>, which the conversion treats as
+ 12 + 0.003 = 12.003 seconds.
+ </para>
+
+ <para>
+ Here is a more
+ complex example:
+ <literal>to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US')</literal>
+ is 15 hours, 12 minutes, and 2 seconds + 20 milliseconds +
+ 1230 microseconds = 2.021230 seconds.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>to_char(..., 'ID')</function>'s day of the week numbering
+ matches the <function>extract(isodow from ...)</function> function, but
+ <function>to_char(..., 'D')</function>'s does not match
+ <function>extract(dow from ...)</function>'s day numbering.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>to_char(interval)</function> formats <literal>HH</literal> and
+ <literal>HH12</literal> as shown on a 12-hour clock, for example zero hours
+ and 36 hours both output as <literal>12</literal>, while <literal>HH24</literal>
+ outputs the full hour value, which can exceed 23 in
+ an <type>interval</type> value.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ <xref linkend="functions-formatting-numeric-table"/> shows the
+ template patterns available for formatting numeric values.
+ </para>
+
+ <table id="functions-formatting-numeric-table">
+ <title>Template Patterns for Numeric Formatting</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Pattern</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>9</literal></entry>
+ <entry>digit position (can be dropped if insignificant)</entry>
+ </row>
+ <row>
+ <entry><literal>0</literal></entry>
+ <entry>digit position (will not be dropped, even if insignificant)</entry>
+ </row>
+ <row>
+ <entry><literal>.</literal> (period)</entry>
+ <entry>decimal point</entry>
+ </row>
+ <row>
+ <entry><literal>,</literal> (comma)</entry>
+ <entry>group (thousands) separator</entry>
+ </row>
+ <row>
+ <entry><literal>PR</literal></entry>
+ <entry>negative value in angle brackets</entry>
+ </row>
+ <row>
+ <entry><literal>S</literal></entry>
+ <entry>sign anchored to number (uses locale)</entry>
+ </row>
+ <row>
+ <entry><literal>L</literal></entry>
+ <entry>currency symbol (uses locale)</entry>
+ </row>
+ <row>
+ <entry><literal>D</literal></entry>
+ <entry>decimal point (uses locale)</entry>
+ </row>
+ <row>
+ <entry><literal>G</literal></entry>
+ <entry>group separator (uses locale)</entry>
+ </row>
+ <row>
+ <entry><literal>MI</literal></entry>
+ <entry>minus sign in specified position (if number &lt; 0)</entry>
+ </row>
+ <row>
+ <entry><literal>PL</literal></entry>
+ <entry>plus sign in specified position (if number &gt; 0)</entry>
+ </row>
+ <row>
+ <entry><literal>SG</literal></entry>
+ <entry>plus/minus sign in specified position</entry>
+ </row>
+ <row>
+ <entry><literal>RN</literal></entry>
+ <entry>Roman numeral (input between 1 and 3999)</entry>
+ </row>
+ <row>
+ <entry><literal>TH</literal> or <literal>th</literal></entry>
+ <entry>ordinal number suffix</entry>
+ </row>
+ <row>
+ <entry><literal>V</literal></entry>
+ <entry>shift specified number of digits (see notes)</entry>
+ </row>
+ <row>
+ <entry><literal>EEEE</literal></entry>
+ <entry>exponent for scientific notation</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Usage notes for numeric formatting:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>0</literal> specifies a digit position that will always be printed,
+ even if it contains a leading/trailing zero. <literal>9</literal> also
+ specifies a digit position, but if it is a leading zero then it will
+ be replaced by a space, while if it is a trailing zero and fill mode
+ is specified then it will be deleted. (For <function>to_number()</function>,
+ these two pattern characters are equivalent.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The pattern characters <literal>S</literal>, <literal>L</literal>, <literal>D</literal>,
+ and <literal>G</literal> represent the sign, currency symbol, decimal point,
+ and thousands separator characters defined by the current locale
+ (see <xref linkend="guc-lc-monetary"/>
+ and <xref linkend="guc-lc-numeric"/>). The pattern characters period
+ and comma represent those exact characters, with the meanings of
+ decimal point and thousands separator, regardless of locale.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If no explicit provision is made for a sign
+ in <function>to_char()</function>'s pattern, one column will be reserved for
+ the sign, and it will be anchored to (appear just left of) the
+ number. If <literal>S</literal> appears just left of some <literal>9</literal>'s,
+ it will likewise be anchored to the number.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A sign formatted using <literal>SG</literal>, <literal>PL</literal>, or
+ <literal>MI</literal> is not anchored to
+ the number; for example,
+ <literal>to_char(-12, 'MI9999')</literal> produces <literal>'-&nbsp;&nbsp;12'</literal>
+ but <literal>to_char(-12, 'S9999')</literal> produces <literal>'&nbsp;&nbsp;-12'</literal>.
+ (The Oracle implementation does not allow the use of
+ <literal>MI</literal> before <literal>9</literal>, but rather
+ requires that <literal>9</literal> precede
+ <literal>MI</literal>.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>TH</literal> does not convert values less than zero
+ and does not convert fractional numbers.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>PL</literal>, <literal>SG</literal>, and
+ <literal>TH</literal> are <productname>PostgreSQL</productname>
+ extensions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <function>to_number</function>, if non-data template patterns such
+ as <literal>L</literal> or <literal>TH</literal> are used, the
+ corresponding number of input characters are skipped, whether or not
+ they match the template pattern, unless they are data characters
+ (that is, digits, sign, decimal point, or comma). For
+ example, <literal>TH</literal> would skip two non-data characters.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>V</literal> with <function>to_char</function>
+ multiplies the input values by
+ <literal>10^<replaceable>n</replaceable></literal>, where
+ <replaceable>n</replaceable> is the number of digits following
+ <literal>V</literal>. <literal>V</literal> with
+ <function>to_number</function> divides in a similar manner.
+ <function>to_char</function> and <function>to_number</function>
+ do not support the use of
+ <literal>V</literal> combined with a decimal point
+ (e.g., <literal>99.9V99</literal> is not allowed).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>EEEE</literal> (scientific notation) cannot be used in
+ combination with any of the other formatting patterns or
+ modifiers other than digit and decimal point patterns, and must be at the end of the format string
+ (e.g., <literal>9.99EEEE</literal> is a valid pattern).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Certain modifiers can be applied to any template pattern to alter its
+ behavior. For example, <literal>FM99.99</literal>
+ is the <literal>99.99</literal> pattern with the
+ <literal>FM</literal> modifier.
+ <xref linkend="functions-formatting-numericmod-table"/> shows the
+ modifier patterns for numeric formatting.
+ </para>
+
+ <table id="functions-formatting-numericmod-table">
+ <title>Template Pattern Modifiers for Numeric Formatting</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Modifier</entry>
+ <entry>Description</entry>
+ <entry>Example</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>FM</literal> prefix</entry>
+ <entry>fill mode (suppress trailing zeroes and padding blanks)</entry>
+ <entry><literal>FM99.99</literal></entry>
+ </row>
+ <row>
+ <entry><literal>TH</literal> suffix</entry>
+ <entry>upper case ordinal number suffix</entry>
+ <entry><literal>999TH</literal></entry>
+ </row>
+ <row>
+ <entry><literal>th</literal> suffix</entry>
+ <entry>lower case ordinal number suffix</entry>
+ <entry><literal>999th</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-formatting-examples-table"/> shows some
+ examples of the use of the <function>to_char</function> function.
+ </para>
+
+ <table id="functions-formatting-examples-table">
+ <title><function>to_char</function> Examples</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Expression</entry>
+ <entry>Result</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>to_char(current_timestamp, 'Day,&nbsp;DD&nbsp;&nbsp;HH12:MI:SS')</literal></entry>
+ <entry><literal>'Tuesday&nbsp;&nbsp;,&nbsp;06&nbsp;&nbsp;05:39:18'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(current_timestamp, 'FMDay,&nbsp;FMDD&nbsp;&nbsp;HH12:MI:SS')</literal></entry>
+ <entry><literal>'Tuesday,&nbsp;6&nbsp;&nbsp;05:39:18'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-0.1, '99.99')</literal></entry>
+ <entry><literal>'&nbsp;&nbsp;-.10'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-0.1, 'FM9.99')</literal></entry>
+ <entry><literal>'-.1'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-0.1, 'FM90.99')</literal></entry>
+ <entry><literal>'-0.1'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(0.1, '0.9')</literal></entry>
+ <entry><literal>'&nbsp;0.1'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(12, '9990999.9')</literal></entry>
+ <entry><literal>'&nbsp;&nbsp;&nbsp;&nbsp;0012.0'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(12, 'FM9990999.9')</literal></entry>
+ <entry><literal>'0012.'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, '999')</literal></entry>
+ <entry><literal>'&nbsp;485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-485, '999')</literal></entry>
+ <entry><literal>'-485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, '9&nbsp;9&nbsp;9')</literal></entry>
+ <entry><literal>'&nbsp;4&nbsp;8&nbsp;5'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(1485, '9,999')</literal></entry>
+ <entry><literal>'&nbsp;1,485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(1485, '9G999')</literal></entry>
+ <entry><literal>'&nbsp;1&nbsp;485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(148.5, '999.999')</literal></entry>
+ <entry><literal>'&nbsp;148.500'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(148.5, 'FM999.999')</literal></entry>
+ <entry><literal>'148.5'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(148.5, 'FM999.990')</literal></entry>
+ <entry><literal>'148.500'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(148.5, '999D999')</literal></entry>
+ <entry><literal>'&nbsp;148,500'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(3148.5, '9G999D999')</literal></entry>
+ <entry><literal>'&nbsp;3&nbsp;148,500'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-485, '999S')</literal></entry>
+ <entry><literal>'485-'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-485, '999MI')</literal></entry>
+ <entry><literal>'485-'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, '999MI')</literal></entry>
+ <entry><literal>'485&nbsp;'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, 'FM999MI')</literal></entry>
+ <entry><literal>'485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, 'PL999')</literal></entry>
+ <entry><literal>'+485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, 'SG999')</literal></entry>
+ <entry><literal>'+485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-485, 'SG999')</literal></entry>
+ <entry><literal>'-485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-485, '9SG99')</literal></entry>
+ <entry><literal>'4-85'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(-485, '999PR')</literal></entry>
+ <entry><literal>'&lt;485&gt;'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, 'L999')</literal></entry>
+ <entry><literal>'DM&nbsp;485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, 'RN')</literal></entry>
+ <entry><literal>'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CDLXXXV'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, 'FMRN')</literal></entry>
+ <entry><literal>'CDLXXXV'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(5.2, 'FMRN')</literal></entry>
+ <entry><literal>'V'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(482, '999th')</literal></entry>
+ <entry><literal>'&nbsp;482nd'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485, '"Good&nbsp;number:"999')</literal></entry>
+ <entry><literal>'Good&nbsp;number:&nbsp;485'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(485.8, '"Pre:"999"&nbsp;Post:"&nbsp;.999')</literal></entry>
+ <entry><literal>'Pre:&nbsp;485&nbsp;Post:&nbsp;.800'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(12, '99V999')</literal></entry>
+ <entry><literal>'&nbsp;12000'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(12.4, '99V999')</literal></entry>
+ <entry><literal>'&nbsp;12400'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(12.45, '99V9')</literal></entry>
+ <entry><literal>'&nbsp;125'</literal></entry>
+ </row>
+ <row>
+ <entry><literal>to_char(0.0004859, '9.99EEEE')</literal></entry>
+ <entry><literal>' 4.86e-04'</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="functions-datetime">
+ <title>Date/Time Functions and Operators</title>
+
+ <para>
+ <xref linkend="functions-datetime-table"/> shows the available
+ functions for date/time value processing, with details appearing in
+ the following subsections. <xref
+ linkend="operators-datetime-table"/> illustrates the behaviors of
+ the basic arithmetic operators (<literal>+</literal>,
+ <literal>*</literal>, etc.). For formatting functions, refer to
+ <xref linkend="functions-formatting"/>. You should be familiar with
+ the background information on date/time data types from <xref
+ linkend="datatype-datetime"/>.
+ </para>
+
+ <para>
+ In addition, the usual comparison operators shown in
+ <xref linkend="functions-comparison-op-table"/> are available for the
+ date/time types. Dates and timestamps (with or without time zone) are
+ all comparable, while times (with or without time zone) and intervals
+ can only be compared to other values of the same data type. When
+ comparing a timestamp without time zone to a timestamp with time zone,
+ the former value is assumed to be given in the time zone specified by
+ the <xref linkend="guc-timezone"/> configuration parameter, and is
+ rotated to UTC for comparison to the latter value (which is already
+ in UTC internally). Similarly, a date value is assumed to represent
+ midnight in the <varname>TimeZone</varname> zone when comparing it
+ to a timestamp.
+ </para>
+
+ <para>
+ All the functions and operators described below that take <type>time</type> or <type>timestamp</type>
+ inputs actually come in two variants: one that takes <type>time with time zone</type> or <type>timestamp
+ with time zone</type>, and one that takes <type>time without time zone</type> or <type>timestamp without time zone</type>.
+ For brevity, these variants are not shown separately. Also, the
+ <literal>+</literal> and <literal>*</literal> operators come in commutative pairs (for
+ example both <type>date</type> <literal>+</literal> <type>integer</type>
+ and <type>integer</type> <literal>+</literal> <type>date</type>); we show
+ only one of each such pair.
+ </para>
+
+ <table id="operators-datetime-table">
+ <title>Date/Time Operators</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>date</type> <literal>+</literal> <type>integer</type>
+ <returnvalue>date</returnvalue>
+ </para>
+ <para>
+ Add a number of days to a date
+ </para>
+ <para>
+ <literal>date '2001-09-28' + 7</literal>
+ <returnvalue>2001-10-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>date</type> <literal>+</literal> <type>interval</type>
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Add an interval to a date
+ </para>
+ <para>
+ <literal>date '2001-09-28' + interval '1 hour'</literal>
+ <returnvalue>2001-09-28 01:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>date</type> <literal>+</literal> <type>time</type>
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Add a time-of-day to a date
+ </para>
+ <para>
+ <literal>date '2001-09-28' + time '03:00'</literal>
+ <returnvalue>2001-09-28 03:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>interval</type> <literal>+</literal> <type>interval</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Add intervals
+ </para>
+ <para>
+ <literal>interval '1 day' + interval '1 hour'</literal>
+ <returnvalue>1 day 01:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>timestamp</type> <literal>+</literal> <type>interval</type>
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Add an interval to a timestamp
+ </para>
+ <para>
+ <literal>timestamp '2001-09-28 01:00' + interval '23 hours'</literal>
+ <returnvalue>2001-09-29 00:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>time</type> <literal>+</literal> <type>interval</type>
+ <returnvalue>time</returnvalue>
+ </para>
+ <para>
+ Add an interval to a time
+ </para>
+ <para>
+ <literal>time '01:00' + interval '3 hours'</literal>
+ <returnvalue>04:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>-</literal> <type>interval</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Negate an interval
+ </para>
+ <para>
+ <literal>- interval '23 hours'</literal>
+ <returnvalue>-23:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>date</type> <literal>-</literal> <type>date</type>
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Subtract dates, producing the number of days elapsed
+ </para>
+ <para>
+ <literal>date '2001-10-01' - date '2001-09-28'</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>date</type> <literal>-</literal> <type>integer</type>
+ <returnvalue>date</returnvalue>
+ </para>
+ <para>
+ Subtract a number of days from a date
+ </para>
+ <para>
+ <literal>date '2001-10-01' - 7</literal>
+ <returnvalue>2001-09-24</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>date</type> <literal>-</literal> <type>interval</type>
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Subtract an interval from a date
+ </para>
+ <para>
+ <literal>date '2001-09-28' - interval '1 hour'</literal>
+ <returnvalue>2001-09-27 23:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>time</type> <literal>-</literal> <type>time</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Subtract times
+ </para>
+ <para>
+ <literal>time '05:00' - time '03:00'</literal>
+ <returnvalue>02:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>time</type> <literal>-</literal> <type>interval</type>
+ <returnvalue>time</returnvalue>
+ </para>
+ <para>
+ Subtract an interval from a time
+ </para>
+ <para>
+ <literal>time '05:00' - interval '2 hours'</literal>
+ <returnvalue>03:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>timestamp</type> <literal>-</literal> <type>interval</type>
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Subtract an interval from a timestamp
+ </para>
+ <para>
+ <literal>timestamp '2001-09-28 23:00' - interval '23 hours'</literal>
+ <returnvalue>2001-09-28 00:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>interval</type> <literal>-</literal> <type>interval</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Subtract intervals
+ </para>
+ <para>
+ <literal>interval '1 day' - interval '1 hour'</literal>
+ <returnvalue>1 day -01:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>timestamp</type> <literal>-</literal> <type>timestamp</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Subtract timestamps (converting 24-hour intervals into days,
+ similarly to <function>justify_hours()</function>)
+ </para>
+ <para>
+ <literal>timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00'</literal>
+ <returnvalue>63 days 15:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>interval</type> <literal>*</literal> <type>double precision</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Multiply an interval by a scalar
+ </para>
+ <para>
+ <literal>interval '1 second' * 900</literal>
+ <returnvalue>00:15:00</returnvalue>
+ </para>
+ <para>
+ <literal>interval '1 day' * 21</literal>
+ <returnvalue>21 days</returnvalue>
+ </para>
+ <para>
+ <literal>interval '1 hour' * 3.5</literal>
+ <returnvalue>03:30:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>interval</type> <literal>/</literal> <type>double precision</type>
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Divide an interval by a scalar
+ </para>
+ <para>
+ <literal>interval '1 hour' / 1.5</literal>
+ <returnvalue>00:40:00</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-datetime-table">
+ <title>Date/Time Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>age</primary>
+ </indexterm>
+ <function>age</function> ( <type>timestamp</type>, <type>timestamp</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Subtract arguments, producing a <quote>symbolic</quote> result that
+ uses years and months, rather than just days
+ </para>
+ <para>
+ <literal>age(timestamp '2001-04-10', timestamp '1957-06-13')</literal>
+ <returnvalue>43 years 9 mons 27 days</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>age</function> ( <type>timestamp</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Subtract argument from <function>current_date</function> (at midnight)
+ </para>
+ <para>
+ <literal>age(timestamp '1957-06-13')</literal>
+ <returnvalue>62 years 6 mons 10 days</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>clock_timestamp</primary>
+ </indexterm>
+ <function>clock_timestamp</function> ( )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Current date and time (changes during statement execution);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>clock_timestamp()</literal>
+ <returnvalue>2019-12-23 14:39:53.662522-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_date</primary>
+ </indexterm>
+ <function>current_date</function>
+ <returnvalue>date</returnvalue>
+ </para>
+ <para>
+ Current date; see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>current_date</literal>
+ <returnvalue>2019-12-23</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_time</primary>
+ </indexterm>
+ <function>current_time</function>
+ <returnvalue>time with time zone</returnvalue>
+ </para>
+ <para>
+ Current time of day; see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>current_time</literal>
+ <returnvalue>14:39:53.662522-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>current_time</function> ( <type>integer</type> )
+ <returnvalue>time with time zone</returnvalue>
+ </para>
+ <para>
+ Current time of day, with limited precision;
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>current_time(2)</literal>
+ <returnvalue>14:39:53.66-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_timestamp</primary>
+ </indexterm>
+ <function>current_timestamp</function>
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current transaction);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>current_timestamp</literal>
+ <returnvalue>2019-12-23 14:39:53.662522-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>current_timestamp</function> ( <type>integer</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current transaction), with limited precision;
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>current_timestamp(0)</literal>
+ <returnvalue>2019-12-23 14:39:53-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>date_bin</function> ( <type>interval</type>, <type>timestamp</type>, <type>timestamp</type> )
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Bin input into specified interval aligned with specified origin; see <xref linkend="functions-datetime-bin"/>
+ </para>
+ <para>
+ <literal>date_bin('15 minutes', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00')</literal>
+ <returnvalue>2001-02-16 20:35:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>date_part</primary>
+ </indexterm>
+ <function>date_part</function> ( <type>text</type>, <type>timestamp</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Get timestamp subfield (equivalent to <function>extract</function>);
+ see <xref linkend="functions-datetime-extract"/>
+ </para>
+ <para>
+ <literal>date_part('hour', timestamp '2001-02-16 20:38:40')</literal>
+ <returnvalue>20</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>date_part</function> ( <type>text</type>, <type>interval</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Get interval subfield (equivalent to <function>extract</function>);
+ see <xref linkend="functions-datetime-extract"/>
+ </para>
+ <para>
+ <literal>date_part('month', interval '2 years 3 months')</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>date_trunc</primary>
+ </indexterm>
+ <function>date_trunc</function> ( <type>text</type>, <type>timestamp</type> )
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Truncate to specified precision; see <xref linkend="functions-datetime-trunc"/>
+ </para>
+ <para>
+ <literal>date_trunc('hour', timestamp '2001-02-16 20:38:40')</literal>
+ <returnvalue>2001-02-16 20:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>date_trunc</function> ( <type>text</type>, <type>timestamp with time zone</type>, <type>text</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Truncate to specified precision in the specified time zone; see
+ <xref linkend="functions-datetime-trunc"/>
+ </para>
+ <para>
+ <literal>date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Australia/Sydney')</literal>
+ <returnvalue>2001-02-16 13:00:00+00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>date_trunc</function> ( <type>text</type>, <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Truncate to specified precision; see
+ <xref linkend="functions-datetime-trunc"/>
+ </para>
+ <para>
+ <literal>date_trunc('hour', interval '2 days 3 hours 40 minutes')</literal>
+ <returnvalue>2 days 03:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>extract</primary>
+ </indexterm>
+ <function>extract</function> ( <parameter>field</parameter> <literal>from</literal> <type>timestamp</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Get timestamp subfield; see <xref linkend="functions-datetime-extract"/>
+ </para>
+ <para>
+ <literal>extract(hour from timestamp '2001-02-16 20:38:40')</literal>
+ <returnvalue>20</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>extract</function> ( <parameter>field</parameter> <literal>from</literal> <type>interval</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Get interval subfield; see <xref linkend="functions-datetime-extract"/>
+ </para>
+ <para>
+ <literal>extract(month from interval '2 years 3 months')</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>isfinite</primary>
+ </indexterm>
+ <function>isfinite</function> ( <type>date</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test for finite date (not +/-infinity)
+ </para>
+ <para>
+ <literal>isfinite(date '2001-02-16')</literal>
+ <returnvalue>true</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>isfinite</function> ( <type>timestamp</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test for finite timestamp (not +/-infinity)
+ </para>
+ <para>
+ <literal>isfinite(timestamp 'infinity')</literal>
+ <returnvalue>false</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>isfinite</function> ( <type>interval</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Test for finite interval (currently always true)
+ </para>
+ <para>
+ <literal>isfinite(interval '4 hours')</literal>
+ <returnvalue>true</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>justify_days</primary>
+ </indexterm>
+ <function>justify_days</function> ( <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Adjust interval so 30-day time periods are represented as months
+ </para>
+ <para>
+ <literal>justify_days(interval '35 days')</literal>
+ <returnvalue>1 mon 5 days</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>justify_hours</primary>
+ </indexterm>
+ <function>justify_hours</function> ( <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Adjust interval so 24-hour time periods are represented as days
+ </para>
+ <para>
+ <literal>justify_hours(interval '27 hours')</literal>
+ <returnvalue>1 day 03:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>justify_interval</primary>
+ </indexterm>
+ <function>justify_interval</function> ( <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Adjust interval using <function>justify_days</function>
+ and <function>justify_hours</function>, with additional sign
+ adjustments
+ </para>
+ <para>
+ <literal>justify_interval(interval '1 mon -1 hour')</literal>
+ <returnvalue>29 days 23:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>localtime</primary>
+ </indexterm>
+ <function>localtime</function>
+ <returnvalue>time</returnvalue>
+ </para>
+ <para>
+ Current time of day;
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>localtime</literal>
+ <returnvalue>14:39:53.662522</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>localtime</function> ( <type>integer</type> )
+ <returnvalue>time</returnvalue>
+ </para>
+ <para>
+ Current time of day, with limited precision;
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>localtime(0)</literal>
+ <returnvalue>14:39:53</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>localtimestamp</primary>
+ </indexterm>
+ <function>localtimestamp</function>
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current transaction);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>localtimestamp</literal>
+ <returnvalue>2019-12-23 14:39:53.662522</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>localtimestamp</function> ( <type>integer</type> )
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current
+ transaction), with limited precision;
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>localtimestamp(2)</literal>
+ <returnvalue>2019-12-23 14:39:53.66</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>make_date</primary>
+ </indexterm>
+ <function>make_date</function> ( <parameter>year</parameter> <type>int</type>,
+ <parameter>month</parameter> <type>int</type>,
+ <parameter>day</parameter> <type>int</type> )
+ <returnvalue>date</returnvalue>
+ </para>
+ <para>
+ Create date from year, month and day fields
+ (negative years signify BC)
+ </para>
+ <para>
+ <literal>make_date(2013, 7, 15)</literal>
+ <returnvalue>2013-07-15</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature"><indexterm>
+ <primary>make_interval</primary>
+ </indexterm>
+ <function>make_interval</function> ( <optional> <parameter>years</parameter> <type>int</type>
+ <optional>, <parameter>months</parameter> <type>int</type>
+ <optional>, <parameter>weeks</parameter> <type>int</type>
+ <optional>, <parameter>days</parameter> <type>int</type>
+ <optional>, <parameter>hours</parameter> <type>int</type>
+ <optional>, <parameter>mins</parameter> <type>int</type>
+ <optional>, <parameter>secs</parameter> <type>double precision</type>
+ </optional></optional></optional></optional></optional></optional></optional> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Create interval from years, months, weeks, days, hours, minutes and
+ seconds fields, each of which can default to zero
+ </para>
+ <para>
+ <literal>make_interval(days =&gt; 10)</literal>
+ <returnvalue>10 days</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>make_time</primary>
+ </indexterm>
+ <function>make_time</function> ( <parameter>hour</parameter> <type>int</type>,
+ <parameter>min</parameter> <type>int</type>,
+ <parameter>sec</parameter> <type>double precision</type> )
+ <returnvalue>time</returnvalue>
+ </para>
+ <para>
+ Create time from hour, minute and seconds fields
+ </para>
+ <para>
+ <literal>make_time(8, 15, 23.5)</literal>
+ <returnvalue>08:15:23.5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>make_timestamp</primary>
+ </indexterm>
+ <function>make_timestamp</function> ( <parameter>year</parameter> <type>int</type>,
+ <parameter>month</parameter> <type>int</type>,
+ <parameter>day</parameter> <type>int</type>,
+ <parameter>hour</parameter> <type>int</type>,
+ <parameter>min</parameter> <type>int</type>,
+ <parameter>sec</parameter> <type>double precision</type> )
+ <returnvalue>timestamp</returnvalue>
+ </para>
+ <para>
+ Create timestamp from year, month, day, hour, minute and seconds fields
+ (negative years signify BC)
+ </para>
+ <para>
+ <literal>make_timestamp(2013, 7, 15, 8, 15, 23.5)</literal>
+ <returnvalue>2013-07-15 08:15:23.5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>make_timestamptz</primary>
+ </indexterm>
+ <function>make_timestamptz</function> ( <parameter>year</parameter> <type>int</type>,
+ <parameter>month</parameter> <type>int</type>,
+ <parameter>day</parameter> <type>int</type>,
+ <parameter>hour</parameter> <type>int</type>,
+ <parameter>min</parameter> <type>int</type>,
+ <parameter>sec</parameter> <type>double precision</type>
+ <optional>, <parameter>timezone</parameter> <type>text</type> </optional> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Create timestamp with time zone from year, month, day, hour, minute
+ and seconds fields (negative years signify BC).
+ If <parameter>timezone</parameter> is not
+ specified, the current time zone is used; the examples assume the
+ session time zone is <literal>Europe/London</literal>
+ </para>
+ <para>
+ <literal>make_timestamptz(2013, 7, 15, 8, 15, 23.5)</literal>
+ <returnvalue>2013-07-15 08:15:23.5+01</returnvalue>
+ </para>
+ <para>
+ <literal>make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New_York')</literal>
+ <returnvalue>2013-07-15 13:15:23.5+01</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>now</primary>
+ </indexterm>
+ <function>now</function> ( )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current transaction);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>now()</literal>
+ <returnvalue>2019-12-23 14:39:53.662522-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>statement_timestamp</primary>
+ </indexterm>
+ <function>statement_timestamp</function> ( )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current statement);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>statement_timestamp()</literal>
+ <returnvalue>2019-12-23 14:39:53.662522-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>timeofday</primary>
+ </indexterm>
+ <function>timeofday</function> ( )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Current date and time
+ (like <function>clock_timestamp</function>, but as a <type>text</type> string);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>timeofday()</literal>
+ <returnvalue>Mon Dec 23 14:39:53.662522 2019 EST</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>transaction_timestamp</primary>
+ </indexterm>
+ <function>transaction_timestamp</function> ( )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Current date and time (start of current transaction);
+ see <xref linkend="functions-datetime-current"/>
+ </para>
+ <para>
+ <literal>transaction_timestamp()</literal>
+ <returnvalue>2019-12-23 14:39:53.662522-05</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_timestamp</primary>
+ </indexterm>
+ <function>to_timestamp</function> ( <type>double precision</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to
+ timestamp with time zone
+ </para>
+ <para>
+ <literal>to_timestamp(1284352323)</literal>
+ <returnvalue>2010-09-13 04:32:03+00</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <indexterm>
+ <primary>OVERLAPS</primary>
+ </indexterm>
+ In addition to these functions, the SQL <literal>OVERLAPS</literal> operator is
+ supported:
+<synopsis>
+(<replaceable>start1</replaceable>, <replaceable>end1</replaceable>) OVERLAPS (<replaceable>start2</replaceable>, <replaceable>end2</replaceable>)
+(<replaceable>start1</replaceable>, <replaceable>length1</replaceable>) OVERLAPS (<replaceable>start2</replaceable>, <replaceable>length2</replaceable>)
+</synopsis>
+ This expression yields true when two time periods (defined by their
+ endpoints) overlap, false when they do not overlap. The endpoints
+ can be specified as pairs of dates, times, or time stamps; or as
+ a date, time, or time stamp followed by an interval. When a pair
+ of values is provided, either the start or the end can be written
+ first; <literal>OVERLAPS</literal> automatically takes the earlier value
+ of the pair as the start. Each time period is considered to
+ represent the half-open interval <replaceable>start</replaceable> <literal>&lt;=</literal>
+ <replaceable>time</replaceable> <literal>&lt;</literal> <replaceable>end</replaceable>, unless
+ <replaceable>start</replaceable> and <replaceable>end</replaceable> are equal in which case it
+ represents that single time instant. This means for instance that two
+ time periods with only an endpoint in common do not overlap.
+ </para>
+
+<screen>
+SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
+ (DATE '2001-10-30', DATE '2002-10-30');
+<lineannotation>Result: </lineannotation><computeroutput>true</computeroutput>
+SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
+ (DATE '2001-10-30', DATE '2002-10-30');
+<lineannotation>Result: </lineannotation><computeroutput>false</computeroutput>
+SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
+ (DATE '2001-10-30', DATE '2001-10-31');
+<lineannotation>Result: </lineannotation><computeroutput>false</computeroutput>
+SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
+ (DATE '2001-10-30', DATE '2001-10-31');
+<lineannotation>Result: </lineannotation><computeroutput>true</computeroutput>
+</screen>
+
+ <para>
+ When adding an <type>interval</type> value to (or subtracting an
+ <type>interval</type> value from) a <type>timestamp with time zone</type>
+ value, the days component advances or decrements the date of the
+ <type>timestamp with time zone</type> by the indicated number of days,
+ keeping the time of day the same.
+ Across daylight saving time changes (when the session time zone is set to a
+ time zone that recognizes DST), this means <literal>interval '1 day'</literal>
+ does not necessarily equal <literal>interval '24 hours'</literal>.
+ For example, with the session time zone set
+ to <literal>America/Denver</literal>:
+<screen>
+SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day';
+<lineannotation>Result: </lineannotation><computeroutput>2005-04-03 12:00:00-06</computeroutput>
+SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours';
+<lineannotation>Result: </lineannotation><computeroutput>2005-04-03 13:00:00-06</computeroutput>
+</screen>
+ This happens because an hour was skipped due to a change in daylight saving
+ time at <literal>2005-04-03 02:00:00</literal> in time zone
+ <literal>America/Denver</literal>.
+ </para>
+
+ <para>
+ Note there can be ambiguity in the <literal>months</literal> field returned by
+ <function>age</function> because different months have different numbers of
+ days. <productname>PostgreSQL</productname>'s approach uses the month from the
+ earlier of the two dates when calculating partial months. For example,
+ <literal>age('2004-06-01', '2004-04-30')</literal> uses April to yield
+ <literal>1 mon 1 day</literal>, while using May would yield <literal>1 mon 2
+ days</literal> because May has 31 days, while April has only 30.
+ </para>
+
+ <para>
+ Subtraction of dates and timestamps can also be complex. One conceptually
+ simple way to perform subtraction is to convert each value to a number
+ of seconds using <literal>EXTRACT(EPOCH FROM ...)</literal>, then subtract the
+ results; this produces the
+ number of <emphasis>seconds</emphasis> between the two values. This will adjust
+ for the number of days in each month, timezone changes, and daylight
+ saving time adjustments. Subtraction of date or timestamp
+ values with the <quote><literal>-</literal></quote> operator
+ returns the number of days (24-hours) and hours/minutes/seconds
+ between the values, making the same adjustments. The <function>age</function>
+ function returns years, months, days, and hours/minutes/seconds,
+ performing field-by-field subtraction and then adjusting for negative
+ field values. The following queries illustrate the differences in these
+ approaches. The sample results were produced with <literal>timezone
+ = 'US/Eastern'</literal>; there is a daylight saving time change between the
+ two dates used:
+ </para>
+
+<screen>
+SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
+ EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
+<lineannotation>Result: </lineannotation><computeroutput>10537200.000000</computeroutput>
+SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
+ EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
+ / 60 / 60 / 24;
+<lineannotation>Result: </lineannotation><computeroutput>121.9583333333333333</computeroutput>
+SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
+<lineannotation>Result: </lineannotation><computeroutput>121 days 23:00:00</computeroutput>
+SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
+<lineannotation>Result: </lineannotation><computeroutput>4 mons</computeroutput>
+</screen>
+
+ <sect2 id="functions-datetime-extract">
+ <title><function>EXTRACT</function>, <function>date_part</function></title>
+
+ <indexterm>
+ <primary>date_part</primary>
+ </indexterm>
+ <indexterm>
+ <primary>extract</primary>
+ </indexterm>
+
+<synopsis>
+EXTRACT(<replaceable>field</replaceable> FROM <replaceable>source</replaceable>)
+</synopsis>
+
+ <para>
+ The <function>extract</function> function retrieves subfields
+ such as year or hour from date/time values.
+ <replaceable>source</replaceable> must be a value expression of
+ type <type>timestamp</type>, <type>time</type>, or <type>interval</type>.
+ (Expressions of type <type>date</type> are
+ cast to <type>timestamp</type> and can therefore be used as
+ well.) <replaceable>field</replaceable> is an identifier or
+ string that selects what field to extract from the source value.
+ The <function>extract</function> function returns values of type
+ <type>numeric</type>.
+ The following are valid field names:
+
+ <!-- alphabetical -->
+ <variablelist>
+ <varlistentry>
+ <term><literal>century</literal></term>
+ <listitem>
+ <para>
+ The century
+ </para>
+
+<screen>
+SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
+<lineannotation>Result: </lineannotation><computeroutput>20</computeroutput>
+SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>21</computeroutput>
+</screen>
+
+ <para>
+ The first century starts at 0001-01-01 00:00:00 AD, although
+ they did not know it at the time. This definition applies to all
+ Gregorian calendar countries. There is no century number 0,
+ you go from -1 century to 1 century.
+
+ If you disagree with this, please write your complaint to:
+ Pope, Cathedral Saint-Peter of Roma, Vatican.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>day</literal></term>
+ <listitem>
+ <para>
+ For <type>timestamp</type> values, the day (of the month) field
+ (1&ndash;31) ; for <type>interval</type> values, the number of days
+ </para>
+
+<screen>
+SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>16</computeroutput>
+
+SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
+<lineannotation>Result: </lineannotation><computeroutput>40</computeroutput>
+</screen>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>decade</literal></term>
+ <listitem>
+ <para>
+ The year field divided by 10
+ </para>
+
+<screen>
+SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>200</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>dow</literal></term>
+ <listitem>
+ <para>
+ The day of the week as Sunday (<literal>0</literal>) to
+ Saturday (<literal>6</literal>)
+ </para>
+
+<screen>
+SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>5</computeroutput>
+</screen>
+ <para>
+ Note that <function>extract</function>'s day of the week numbering
+ differs from that of the <function>to_char(...,
+ 'D')</function> function.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>doy</literal></term>
+ <listitem>
+ <para>
+ The day of the year (1&ndash;365/366)
+ </para>
+
+<screen>
+SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>47</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>epoch</literal></term>
+ <listitem>
+ <para>
+ For <type>timestamp with time zone</type> values, the
+ number of seconds since 1970-01-01 00:00:00 UTC (negative for
+ timestamps before that);
+ for <type>date</type> and <type>timestamp</type> values, the
+ nominal number of seconds since 1970-01-01 00:00:00,
+ without regard to timezone or daylight-savings rules;
+ for <type>interval</type> values, the total number
+ of seconds in the interval
+ </para>
+
+<screen>
+SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
+<lineannotation>Result: </lineannotation><computeroutput>982384720.120000</computeroutput>
+
+SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12');
+<lineannotation>Result: </lineannotation><computeroutput>982355920.120000</computeroutput>
+
+SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
+<lineannotation>Result: </lineannotation><computeroutput>442800.000000</computeroutput>
+</screen>
+
+ <para>
+ You can convert an epoch value back to a <type>timestamp with time zone</type>
+ with <function>to_timestamp</function>:
+ </para>
+<screen>
+SELECT to_timestamp(982384720.12);
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-17 04:38:40.12+00</computeroutput>
+</screen>
+
+ <para>
+ Beware that applying <function>to_timestamp</function> to an epoch
+ extracted from a <type>date</type> or <type>timestamp</type> value
+ could produce a misleading result: the result will effectively
+ assume that the original value had been given in UTC, which might
+ not be the case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>hour</literal></term>
+ <listitem>
+ <para>
+ The hour field (0&ndash;23)
+ </para>
+
+<screen>
+SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>20</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>isodow</literal></term>
+ <listitem>
+ <para>
+ The day of the week as Monday (<literal>1</literal>) to
+ Sunday (<literal>7</literal>)
+ </para>
+
+<screen>
+SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>7</computeroutput>
+</screen>
+ <para>
+ This is identical to <literal>dow</literal> except for Sunday. This
+ matches the <acronym>ISO</acronym> 8601 day of the week numbering.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>isoyear</literal></term>
+ <listitem>
+ <para>
+ The <acronym>ISO</acronym> 8601 week-numbering year that the date
+ falls in (not applicable to intervals)
+ </para>
+
+<screen>
+SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
+<lineannotation>Result: </lineannotation><computeroutput>2005</computeroutput>
+SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
+<lineannotation>Result: </lineannotation><computeroutput>2006</computeroutput>
+</screen>
+
+ <para>
+ Each <acronym>ISO</acronym> 8601 week-numbering year begins with the
+ Monday of the week containing the 4th of January, so in early
+ January or late December the <acronym>ISO</acronym> year may be
+ different from the Gregorian year. See the <literal>week</literal>
+ field for more information.
+ </para>
+ <para>
+ This field is not available in PostgreSQL releases prior to 8.3.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>julian</literal></term>
+ <listitem>
+ <para>
+ The <firstterm>Julian Date</firstterm> corresponding to the
+ date or timestamp (not applicable to intervals). Timestamps
+ that are not local midnight result in a fractional value. See
+ <xref linkend="datetime-julian-dates"/> for more information.
+ </para>
+
+<screen>
+SELECT EXTRACT(JULIAN FROM DATE '2006-01-01');
+<lineannotation>Result: </lineannotation><computeroutput>2453737</computeroutput>
+SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00');
+<lineannotation>Result: </lineannotation><computeroutput>2453737.50000000000000000000</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>microseconds</literal></term>
+ <listitem>
+ <para>
+ The seconds field, including fractional parts, multiplied by 1
+ 000 000; note that this includes full seconds
+ </para>
+
+<screen>
+SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
+<lineannotation>Result: </lineannotation><computeroutput>28500000</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>millennium</literal></term>
+ <listitem>
+ <para>
+ The millennium
+ </para>
+
+<screen>
+SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>3</computeroutput>
+</screen>
+
+ <para>
+ Years in the 1900s are in the second millennium.
+ The third millennium started January 1, 2001.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>milliseconds</literal></term>
+ <listitem>
+ <para>
+ The seconds field, including fractional parts, multiplied by
+ 1000. Note that this includes full seconds.
+ </para>
+
+<screen>
+SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
+<lineannotation>Result: </lineannotation><computeroutput>28500.000</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>minute</literal></term>
+ <listitem>
+ <para>
+ The minutes field (0&ndash;59)
+ </para>
+
+<screen>
+SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>38</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>month</literal></term>
+ <listitem>
+ <para>
+ For <type>timestamp</type> values, the number of the month
+ within the year (1&ndash;12) ; for <type>interval</type> values,
+ the number of months, modulo 12 (0&ndash;11)
+ </para>
+
+<screen>
+SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>2</computeroutput>
+
+SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
+<lineannotation>Result: </lineannotation><computeroutput>3</computeroutput>
+
+SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
+<lineannotation>Result: </lineannotation><computeroutput>1</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>quarter</literal></term>
+ <listitem>
+ <para>
+ The quarter of the year (1&ndash;4) that the date is in
+ </para>
+
+<screen>
+SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>1</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>second</literal></term>
+ <listitem>
+ <para>
+ The seconds field, including any fractional seconds
+ </para>
+
+<screen>
+SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>40.000000</computeroutput>
+
+SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
+<lineannotation>Result: </lineannotation><computeroutput>28.500000</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>timezone</literal></term>
+ <listitem>
+ <para>
+ The time zone offset from UTC, measured in seconds. Positive values
+ correspond to time zones east of UTC, negative values to
+ zones west of UTC. (Technically,
+ <productname>PostgreSQL</productname> does not use UTC because
+ leap seconds are not handled.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>timezone_hour</literal></term>
+ <listitem>
+ <para>
+ The hour component of the time zone offset
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>timezone_minute</literal></term>
+ <listitem>
+ <para>
+ The minute component of the time zone offset
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>week</literal></term>
+ <listitem>
+ <para>
+ The number of the <acronym>ISO</acronym> 8601 week-numbering week of
+ the year. By definition, ISO weeks start on Mondays and the first
+ week of a year contains January 4 of that year. In other words, the
+ first Thursday of a year is in week 1 of that year.
+ </para>
+ <para>
+ In the ISO week-numbering system, it is possible for early-January
+ dates to be part of the 52nd or 53rd week of the previous year, and for
+ late-December dates to be part of the first week of the next year.
+ For example, <literal>2005-01-01</literal> is part of the 53rd week of year
+ 2004, and <literal>2006-01-01</literal> is part of the 52nd week of year
+ 2005, while <literal>2012-12-31</literal> is part of the first week of 2013.
+ It's recommended to use the <literal>isoyear</literal> field together with
+ <literal>week</literal> to get consistent results.
+ </para>
+
+<screen>
+SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>7</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>year</literal></term>
+ <listitem>
+ <para>
+ The year field. Keep in mind there is no <literal>0 AD</literal>, so subtracting
+ <literal>BC</literal> years from <literal>AD</literal> years should be done with care.
+ </para>
+
+<screen>
+SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>2001</computeroutput>
+</screen>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <note>
+ <para>
+ When the input value is +/-Infinity, <function>extract</function> returns
+ +/-Infinity for monotonically-increasing fields (<literal>epoch</literal>,
+ <literal>julian</literal>, <literal>year</literal>, <literal>isoyear</literal>,
+ <literal>decade</literal>, <literal>century</literal>, and <literal>millennium</literal>).
+ For other fields, NULL is returned. <productname>PostgreSQL</productname>
+ versions before 9.6 returned zero for all cases of infinite input.
+ </para>
+ </note>
+
+ <para>
+ The <function>extract</function> function is primarily intended
+ for computational processing. For formatting date/time values for
+ display, see <xref linkend="functions-formatting"/>.
+ </para>
+
+ <para>
+ The <function>date_part</function> function is modeled on the traditional
+ <productname>Ingres</productname> equivalent to the
+ <acronym>SQL</acronym>-standard function <function>extract</function>:
+<synopsis>
+date_part('<replaceable>field</replaceable>', <replaceable>source</replaceable>)
+</synopsis>
+ Note that here the <replaceable>field</replaceable> parameter needs to
+ be a string value, not a name. The valid field names for
+ <function>date_part</function> are the same as for
+ <function>extract</function>.
+ For historical reasons, the <function>date_part</function> function
+ returns values of type <type>double precision</type>. This can result in
+ a loss of precision in certain uses. Using <function>extract</function>
+ is recommended instead.
+ </para>
+
+<screen>
+SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>16</computeroutput>
+
+SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
+<lineannotation>Result: </lineannotation><computeroutput>4</computeroutput>
+</screen>
+
+ </sect2>
+
+ <sect2 id="functions-datetime-trunc">
+ <title><function>date_trunc</function></title>
+
+ <indexterm>
+ <primary>date_trunc</primary>
+ </indexterm>
+
+ <para>
+ The function <function>date_trunc</function> is conceptually
+ similar to the <function>trunc</function> function for numbers.
+ </para>
+
+ <para>
+<synopsis>
+date_trunc(<replaceable>field</replaceable>, <replaceable>source</replaceable> [, <replaceable>time_zone</replaceable> ])
+</synopsis>
+ <replaceable>source</replaceable> is a value expression of type
+ <type>timestamp</type>, <type>timestamp with time zone</type>,
+ or <type>interval</type>.
+ (Values of type <type>date</type> and
+ <type>time</type> are cast automatically to <type>timestamp</type> or
+ <type>interval</type>, respectively.)
+ <replaceable>field</replaceable> selects to which precision to
+ truncate the input value. The return value is likewise of type
+ <type>timestamp</type>, <type>timestamp with time zone</type>,
+ or <type>interval</type>,
+ and it has all fields that are less significant than the
+ selected one set to zero (or one, for day and month).
+ </para>
+
+ <para>
+ Valid values for <replaceable>field</replaceable> are:
+ <simplelist>
+ <member><literal>microseconds</literal></member>
+ <member><literal>milliseconds</literal></member>
+ <member><literal>second</literal></member>
+ <member><literal>minute</literal></member>
+ <member><literal>hour</literal></member>
+ <member><literal>day</literal></member>
+ <member><literal>week</literal></member>
+ <member><literal>month</literal></member>
+ <member><literal>quarter</literal></member>
+ <member><literal>year</literal></member>
+ <member><literal>decade</literal></member>
+ <member><literal>century</literal></member>
+ <member><literal>millennium</literal></member>
+ </simplelist>
+ </para>
+
+ <para>
+ When the input value is of type <type>timestamp with time zone</type>,
+ the truncation is performed with respect to a particular time zone;
+ for example, truncation to <literal>day</literal> produces a value that
+ is midnight in that zone. By default, truncation is done with respect
+ to the current <xref linkend="guc-timezone"/> setting, but the
+ optional <replaceable>time_zone</replaceable> argument can be provided
+ to specify a different time zone. The time zone name can be specified
+ in any of the ways described in <xref linkend="datatype-timezones"/>.
+ </para>
+
+ <para>
+ A time zone cannot be specified when processing <type>timestamp without
+ time zone</type> or <type>interval</type> inputs. These are always
+ taken at face value.
+ </para>
+
+ <para>
+ Examples (assuming the local time zone is <literal>America/New_York</literal>):
+<screen>
+SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 20:00:00</computeroutput>
+
+SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
+<lineannotation>Result: </lineannotation><computeroutput>2001-01-01 00:00:00</computeroutput>
+
+SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 00:00:00-05</computeroutput>
+
+SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 08:00:00-05</computeroutput>
+
+SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
+<lineannotation>Result: </lineannotation><computeroutput>3 days 02:00:00</computeroutput>
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="functions-datetime-bin">
+ <title><function>date_bin</function></title>
+
+ <indexterm>
+ <primary>date_bin</primary>
+ </indexterm>
+
+ <para>
+ The function <function>date_bin</function> <quote>bins</quote> the input
+ timestamp into the specified interval (the <firstterm>stride</firstterm>)
+ aligned with a specified origin.
+ </para>
+
+ <para>
+<synopsis>
+date_bin(<replaceable>stride</replaceable>, <replaceable>source</replaceable>, <replaceable>origin</replaceable>)
+</synopsis>
+ <replaceable>source</replaceable> is a value expression of type
+ <type>timestamp</type> or <type>timestamp with time zone</type>. (Values
+ of type <type>date</type> are cast automatically to
+ <type>timestamp</type>.) <replaceable>stride</replaceable> is a value
+ expression of type <type>interval</type>. The return value is likewise
+ of type <type>timestamp</type> or <type>timestamp with time zone</type>,
+ and it marks the beginning of the bin into which the
+ <replaceable>source</replaceable> is placed.
+ </para>
+
+ <para>
+ Examples:
+<screen>
+SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01');
+<lineannotation>Result: </lineannotation><computeroutput>2020-02-11 15:30:00</computeroutput>
+
+SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30');
+<lineannotation>Result: </lineannotation><computeroutput>2020-02-11 15:32:30</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ In the case of full units (1 minute, 1 hour, etc.), it gives the same result as
+ the analogous <function>date_trunc</function> call, but the difference is
+ that <function>date_bin</function> can truncate to an arbitrary interval.
+ </para>
+
+ <para>
+ The <parameter>stride</parameter> interval must be greater than zero and
+ cannot contain units of month or larger.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-datetime-zoneconvert">
+ <title><literal>AT TIME ZONE</literal></title>
+
+ <indexterm>
+ <primary>time zone</primary>
+ <secondary>conversion</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>AT TIME ZONE</primary>
+ </indexterm>
+
+ <para>
+ The <literal>AT TIME ZONE</literal> operator converts time
+ stamp <emphasis>without</emphasis> time zone to/from
+ time stamp <emphasis>with</emphasis> time zone, and
+ <type>time with time zone</type> values to different time
+ zones. <xref linkend="functions-datetime-zoneconvert-table"/> shows its
+ variants.
+ </para>
+
+ <table id="functions-datetime-zoneconvert-table">
+ <title><literal>AT TIME ZONE</literal> Variants</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>timestamp without time zone</type> <literal>AT TIME ZONE</literal> <replaceable>zone</replaceable>
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Converts given time stamp <emphasis>without</emphasis> time zone to
+ time stamp <emphasis>with</emphasis> time zone, assuming the given
+ value is in the named time zone.
+ </para>
+ <para>
+ <literal>timestamp '2001-02-16 20:38:40' at time zone 'America/Denver'</literal>
+ <returnvalue>2001-02-17 03:38:40+00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>timestamp with time zone</type> <literal>AT TIME ZONE</literal> <replaceable>zone</replaceable>
+ <returnvalue>timestamp without time zone</returnvalue>
+ </para>
+ <para>
+ Converts given time stamp <emphasis>with</emphasis> time zone to
+ time stamp <emphasis>without</emphasis> time zone, as the time would
+ appear in that zone.
+ </para>
+ <para>
+ <literal>timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'America/Denver'</literal>
+ <returnvalue>2001-02-16 18:38:40</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>time with time zone</type> <literal>AT TIME ZONE</literal> <replaceable>zone</replaceable>
+ <returnvalue>time with time zone</returnvalue>
+ </para>
+ <para>
+ Converts given time <emphasis>with</emphasis> time zone to a new time
+ zone. Since no date is supplied, this uses the currently active UTC
+ offset for the named destination zone.
+ </para>
+ <para>
+ <literal>time with time zone '05:34:17-05' at time zone 'UTC'</literal>
+ <returnvalue>10:34:17+00</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In these expressions, the desired time zone <replaceable>zone</replaceable> can be
+ specified either as a text value (e.g., <literal>'America/Los_Angeles'</literal>)
+ or as an interval (e.g., <literal>INTERVAL '-08:00'</literal>).
+ In the text case, a time zone name can be specified in any of the ways
+ described in <xref linkend="datatype-timezones"/>.
+ The interval case is only useful for zones that have fixed offsets from
+ UTC, so it is not very common in practice.
+ </para>
+
+ <para>
+ Examples (assuming the current <xref linkend="guc-timezone"/> setting
+ is <literal>America/Los_Angeles</literal>):
+<screen>
+SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 19:38:40-08</computeroutput>
+
+SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 18:38:40</computeroutput>
+
+SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
+<lineannotation>Result: </lineannotation><computeroutput>2001-02-16 05:38:40</computeroutput>
+</screen>
+ The first example adds a time zone to a value that lacks it, and
+ displays the value using the current <varname>TimeZone</varname>
+ setting. The second example shifts the time stamp with time zone value
+ to the specified time zone, and returns the value without a time zone.
+ This allows storage and display of values different from the current
+ <varname>TimeZone</varname> setting. The third example converts
+ Tokyo time to Chicago time.
+ </para>
+
+ <para>
+ The function <literal><function>timezone</function>(<replaceable>zone</replaceable>,
+ <replaceable>timestamp</replaceable>)</literal> is equivalent to the SQL-conforming construct
+ <literal><replaceable>timestamp</replaceable> AT TIME ZONE
+ <replaceable>zone</replaceable></literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-datetime-current">
+ <title>Current Date/Time</title>
+
+ <indexterm>
+ <primary>date</primary>
+ <secondary>current</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>time</primary>
+ <secondary>current</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a number of functions
+ that return values related to the current date and time. These
+ SQL-standard functions all return values based on the start time of
+ the current transaction:
+<synopsis>
+CURRENT_DATE
+CURRENT_TIME
+CURRENT_TIMESTAMP
+CURRENT_TIME(<replaceable>precision</replaceable>)
+CURRENT_TIMESTAMP(<replaceable>precision</replaceable>)
+LOCALTIME
+LOCALTIMESTAMP
+LOCALTIME(<replaceable>precision</replaceable>)
+LOCALTIMESTAMP(<replaceable>precision</replaceable>)
+</synopsis>
+ </para>
+
+ <para>
+ <function>CURRENT_TIME</function> and
+ <function>CURRENT_TIMESTAMP</function> deliver values with time zone;
+ <function>LOCALTIME</function> and
+ <function>LOCALTIMESTAMP</function> deliver values without time zone.
+ </para>
+
+ <para>
+ <function>CURRENT_TIME</function>,
+ <function>CURRENT_TIMESTAMP</function>,
+ <function>LOCALTIME</function>, and
+ <function>LOCALTIMESTAMP</function>
+ can optionally take
+ a precision parameter, which causes the result to be rounded
+ to that many fractional digits in the seconds field. Without a precision parameter,
+ the result is given to the full available precision.
+ </para>
+
+ <para>
+ Some examples:
+<screen>
+SELECT CURRENT_TIME;
+<lineannotation>Result: </lineannotation><computeroutput>14:39:53.662522-05</computeroutput>
+
+SELECT CURRENT_DATE;
+<lineannotation>Result: </lineannotation><computeroutput>2019-12-23</computeroutput>
+
+SELECT CURRENT_TIMESTAMP;
+<lineannotation>Result: </lineannotation><computeroutput>2019-12-23 14:39:53.662522-05</computeroutput>
+
+SELECT CURRENT_TIMESTAMP(2);
+<lineannotation>Result: </lineannotation><computeroutput>2019-12-23 14:39:53.66-05</computeroutput>
+
+SELECT LOCALTIMESTAMP;
+<lineannotation>Result: </lineannotation><computeroutput>2019-12-23 14:39:53.662522</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ Since these functions return
+ the start time of the current transaction, their values do not
+ change during the transaction. This is considered a feature:
+ the intent is to allow a single transaction to have a consistent
+ notion of the <quote>current</quote> time, so that multiple
+ modifications within the same transaction bear the same
+ time stamp.
+ </para>
+
+ <note>
+ <para>
+ Other database systems might advance these values more
+ frequently.
+ </para>
+ </note>
+
+ <para>
+ <productname>PostgreSQL</productname> also provides functions that
+ return the start time of the current statement, as well as the actual
+ current time at the instant the function is called. The complete list
+ of non-SQL-standard time functions is:
+<synopsis>
+transaction_timestamp()
+statement_timestamp()
+clock_timestamp()
+timeofday()
+now()
+</synopsis>
+ </para>
+
+ <para>
+ <function>transaction_timestamp()</function> is equivalent to
+ <function>CURRENT_TIMESTAMP</function>, but is named to clearly reflect
+ what it returns.
+ <function>statement_timestamp()</function> returns the start time of the current
+ statement (more specifically, the time of receipt of the latest command
+ message from the client).
+ <function>statement_timestamp()</function> and <function>transaction_timestamp()</function>
+ return the same value during the first command of a transaction, but might
+ differ during subsequent commands.
+ <function>clock_timestamp()</function> returns the actual current time, and
+ therefore its value changes even within a single SQL command.
+ <function>timeofday()</function> is a historical
+ <productname>PostgreSQL</productname> function. Like
+ <function>clock_timestamp()</function>, it returns the actual current time,
+ but as a formatted <type>text</type> string rather than a <type>timestamp
+ with time zone</type> value.
+ <function>now()</function> is a traditional <productname>PostgreSQL</productname>
+ equivalent to <function>transaction_timestamp()</function>.
+ </para>
+
+ <para>
+ All the date/time data types also accept the special literal value
+ <literal>now</literal> to specify the current date and time (again,
+ interpreted as the transaction start time). Thus,
+ the following three all return the same result:
+<programlisting>
+SELECT CURRENT_TIMESTAMP;
+SELECT now();
+SELECT TIMESTAMP 'now'; -- but see tip below
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ Do not use the third form when specifying a value to be evaluated later,
+ for example in a <literal>DEFAULT</literal> clause for a table column.
+ The system will convert <literal>now</literal>
+ to a <type>timestamp</type> as soon as the constant is parsed, so that when
+ the default value is needed,
+ the time of the table creation would be used! The first two
+ forms will not be evaluated until the default value is used,
+ because they are function calls. Thus they will give the desired
+ behavior of defaulting to the time of row insertion.
+ (See also <xref linkend="datatype-datetime-special-values"/>.)
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2 id="functions-datetime-delay">
+ <title>Delaying Execution</title>
+
+ <indexterm>
+ <primary>pg_sleep</primary>
+ </indexterm>
+ <indexterm>
+ <primary>pg_sleep_for</primary>
+ </indexterm>
+ <indexterm>
+ <primary>pg_sleep_until</primary>
+ </indexterm>
+ <indexterm>
+ <primary>sleep</primary>
+ </indexterm>
+ <indexterm>
+ <primary>delay</primary>
+ </indexterm>
+
+ <para>
+ The following functions are available to delay execution of the server
+ process:
+<synopsis>
+pg_sleep ( <type>double precision</type> )
+pg_sleep_for ( <type>interval</type> )
+pg_sleep_until ( <type>timestamp with time zone</type> )
+</synopsis>
+
+ <function>pg_sleep</function> makes the current session's process
+ sleep until the given number of seconds have
+ elapsed. Fractional-second delays can be specified.
+ <function>pg_sleep_for</function> is a convenience function to
+ allow the sleep time to be specified as an <type>interval</type>.
+ <function>pg_sleep_until</function> is a convenience function for when
+ a specific wake-up time is desired.
+ For example:
+
+<programlisting>
+SELECT pg_sleep(1.5);
+SELECT pg_sleep_for('5 minutes');
+SELECT pg_sleep_until('tomorrow 03:00');
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ The effective resolution of the sleep interval is platform-specific;
+ 0.01 seconds is a common value. The sleep delay will be at least as long
+ as specified. It might be longer depending on factors such as server load.
+ In particular, <function>pg_sleep_until</function> is not guaranteed to
+ wake up exactly at the specified time, but it will not wake up any earlier.
+ </para>
+ </note>
+
+ <warning>
+ <para>
+ Make sure that your session does not hold more locks than necessary
+ when calling <function>pg_sleep</function> or its variants. Otherwise
+ other sessions might have to wait for your sleeping process, slowing down
+ the entire system.
+ </para>
+ </warning>
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="functions-enum">
+ <title>Enum Support Functions</title>
+
+ <para>
+ For enum types (described in <xref linkend="datatype-enum"/>),
+ there are several functions that allow cleaner programming without
+ hard-coding particular values of an enum type.
+ These are listed in <xref linkend="functions-enum-table"/>. The examples
+ assume an enum type created as:
+
+<programlisting>
+CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+</programlisting>
+
+ </para>
+
+ <table id="functions-enum-table">
+ <title>Enum Support Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>enum_first</primary>
+ </indexterm>
+ <function>enum_first</function> ( <type>anyenum</type> )
+ <returnvalue>anyenum</returnvalue>
+ </para>
+ <para>
+ Returns the first value of the input enum type.
+ </para>
+ <para>
+ <literal>enum_first(null::rainbow)</literal>
+ <returnvalue>red</returnvalue>
+ </para></entry>
+ </row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>enum_last</primary>
+ </indexterm>
+ <function>enum_last</function> ( <type>anyenum</type> )
+ <returnvalue>anyenum</returnvalue>
+ </para>
+ <para>
+ Returns the last value of the input enum type.
+ </para>
+ <para>
+ <literal>enum_last(null::rainbow)</literal>
+ <returnvalue>purple</returnvalue>
+ </para></entry>
+ </row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>enum_range</primary>
+ </indexterm>
+ <function>enum_range</function> ( <type>anyenum</type> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Returns all values of the input enum type in an ordered array.
+ </para>
+ <para>
+ <literal>enum_range(null::rainbow)</literal>
+ <returnvalue>{red,orange,yellow,&zwsp;green,blue,purple}</returnvalue>
+ </para></entry>
+ </row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>enum_range</function> ( <type>anyenum</type>, <type>anyenum</type> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Returns the range between the two given enum values, as an ordered
+ array. The values must be from the same enum type. If the first
+ parameter is null, the result will start with the first value of
+ the enum type.
+ If the second parameter is null, the result will end with the last
+ value of the enum type.
+ </para>
+ <para>
+ <literal>enum_range('orange'::rainbow, 'green'::rainbow)</literal>
+ <returnvalue>{orange,yellow,green}</returnvalue>
+ </para>
+ <para>
+ <literal>enum_range(NULL, 'green'::rainbow)</literal>
+ <returnvalue>{red,orange,&zwsp;yellow,green}</returnvalue>
+ </para>
+ <para>
+ <literal>enum_range('orange'::rainbow, NULL)</literal>
+ <returnvalue>{orange,yellow,green,&zwsp;blue,purple}</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Notice that except for the two-argument form of <function>enum_range</function>,
+ these functions disregard the specific value passed to them; they care
+ only about its declared data type. Either null or a specific value of
+ the type can be passed, with the same result. It is more common to
+ apply these functions to a table column or function argument than to
+ a hardwired type name as used in the examples.
+ </para>
+ </sect1>
+
+ <sect1 id="functions-geometry">
+ <title>Geometric Functions and Operators</title>
+
+ <para>
+ The geometric types <type>point</type>, <type>box</type>,
+ <type>lseg</type>, <type>line</type>, <type>path</type>,
+ <type>polygon</type>, and <type>circle</type> have a large set of
+ native support functions and operators, shown in <xref
+ linkend="functions-geometry-op-table"/>, <xref
+ linkend="functions-geometry-func-table"/>, and <xref
+ linkend="functions-geometry-conv-table"/>.
+ </para>
+
+ <table id="functions-geometry-op-table">
+ <title>Geometric Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>+</literal> <type>point</type>
+ <returnvalue><replaceable>geometric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Adds the coordinates of the second <type>point</type> to those of each
+ point of the first argument, thus performing translation.
+ Available for <type>point</type>, <type>box</type>, <type>path</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(1,1),(0,0)' + point '(2,0)'</literal>
+ <returnvalue>(3,1),(2,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>path</type> <literal>+</literal> <type>path</type>
+ <returnvalue>path</returnvalue>
+ </para>
+ <para>
+ Concatenates two open paths (returns NULL if either path is closed).
+ </para>
+ <para>
+ <literal>path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]'</literal>
+ <returnvalue>[(0,0),(1,1),(2,2),(3,3),(4,4)]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>-</literal> <type>point</type>
+ <returnvalue><replaceable>geometric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Subtracts the coordinates of the second <type>point</type> from those
+ of each point of the first argument, thus performing translation.
+ Available for <type>point</type>, <type>box</type>, <type>path</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(1,1),(0,0)' - point '(2,0)'</literal>
+ <returnvalue>(-1,1),(-2,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>*</literal> <type>point</type>
+ <returnvalue><replaceable>geometric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Multiplies each point of the first argument by the second
+ <type>point</type> (treating a point as being a complex number
+ represented by real and imaginary parts, and performing standard
+ complex multiplication). If one interprets
+ the second <type>point</type> as a vector, this is equivalent to
+ scaling the object's size and distance from the origin by the length
+ of the vector, and rotating it counterclockwise around the origin by
+ the vector's angle from the <replaceable>x</replaceable> axis.
+ Available for <type>point</type>, <type>box</type>,<footnote
+ id="functions-geometry-rotation-fn"><para><quote>Rotating</quote> a
+ box with these operators only moves its corner points: the box is
+ still considered to have sides parallel to the axes. Hence the box's
+ size is not preserved, as a true rotation would do.</para></footnote>
+ <type>path</type>, <type>circle</type>.
+ </para>
+ <para>
+ <literal>path '((0,0),(1,0),(1,1))' * point '(3.0,0)'</literal>
+ <returnvalue>((0,0),(3,0),(3,3))</returnvalue>
+ </para>
+ <para>
+ <literal>path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45))</literal>
+ <returnvalue>((0,0),&zwsp;(0.7071067811865475,0.7071067811865475),&zwsp;(0,1.414213562373095))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>/</literal> <type>point</type>
+ <returnvalue><replaceable>geometric_type</replaceable></returnvalue>
+ </para>
+ <para>
+ Divides each point of the first argument by the second
+ <type>point</type> (treating a point as being a complex number
+ represented by real and imaginary parts, and performing standard
+ complex division). If one interprets
+ the second <type>point</type> as a vector, this is equivalent to
+ scaling the object's size and distance from the origin down by the
+ length of the vector, and rotating it clockwise around the origin by
+ the vector's angle from the <replaceable>x</replaceable> axis.
+ Available for <type>point</type>, <type>box</type>,<footnoteref
+ linkend="functions-geometry-rotation-fn"/> <type>path</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>path '((0,0),(1,0),(1,1))' / point '(2.0,0)'</literal>
+ <returnvalue>((0,0),(0.5,0),(0.5,0.5))</returnvalue>
+ </para>
+ <para>
+ <literal>path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45))</literal>
+ <returnvalue>((0,0),&zwsp;(0.7071067811865476,-0.7071067811865476),&zwsp;(1.4142135623730951,0))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>@-@</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the total length.
+ Available for <type>lseg</type>, <type>path</type>.
+ </para>
+ <para>
+ <literal>@-@ path '[(0,0),(1,0),(1,1)]'</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>@@</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes the center point.
+ Available for <type>box</type>, <type>lseg</type>,
+ <type>polygon</type>, <type>circle</type>.
+ </para>
+ <para>
+ <literal>@@ box '(2,2),(0,0)'</literal>
+ <returnvalue>(1,1)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>#</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of points.
+ Available for <type>path</type>, <type>polygon</type>.
+ </para>
+ <para>
+ <literal># path '((1,0),(0,1),(-1,0))'</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>#</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes the point of intersection, or NULL if there is none.
+ Available for <type>lseg</type>, <type>line</type>.
+ </para>
+ <para>
+ <literal>lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'</literal>
+ <returnvalue>(0.5,0.5)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>box</type> <literal>#</literal> <type>box</type>
+ <returnvalue>box</returnvalue>
+ </para>
+ <para>
+ Computes the intersection of two boxes, or NULL if there is none.
+ </para>
+ <para>
+ <literal>box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'</literal>
+ <returnvalue>(1,1),(-1,-1)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>##</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes the closest point to the first object on the second object.
+ Available for these pairs of types:
+ (<type>point</type>, <type>box</type>),
+ (<type>point</type>, <type>lseg</type>),
+ (<type>point</type>, <type>line</type>),
+ (<type>lseg</type>, <type>box</type>),
+ (<type>lseg</type>, <type>lseg</type>),
+ (<type>line</type>, <type>lseg</type>).
+ </para>
+ <para>
+ <literal>point '(0,0)' ## lseg '[(2,0),(0,2)]'</literal>
+ <returnvalue>(1,1)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&lt;-&gt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the distance between the objects.
+ Available for all seven geometric types, for all combinations
+ of <type>point</type> with another geometric type, and for
+ these additional pairs of types:
+ (<type>box</type>, <type>lseg</type>),
+ (<type>lseg</type>, <type>line</type>),
+ (<type>polygon</type>, <type>circle</type>)
+ (and the commutator cases).
+ </para>
+ <para>
+ <literal>circle '&lt;(0,0),1&gt;' &lt;-&gt; circle '&lt;(5,0),1&gt;'</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>@&gt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does first object contain second?
+ Available for these pairs of types:
+ (<literal>box</literal>, <literal>point</literal>),
+ (<literal>box</literal>, <literal>box</literal>),
+ (<literal>path</literal>, <literal>point</literal>),
+ (<literal>polygon</literal>, <literal>point</literal>),
+ (<literal>polygon</literal>, <literal>polygon</literal>),
+ (<literal>circle</literal>, <literal>point</literal>),
+ (<literal>circle</literal>, <literal>circle</literal>).
+ </para>
+ <para>
+ <literal>circle '&lt;(0,0),2&gt;' @&gt; point '(1,1)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&lt;@</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object contained in or on second?
+ Available for these pairs of types:
+ (<literal>point</literal>, <literal>box</literal>),
+ (<literal>point</literal>, <literal>lseg</literal>),
+ (<literal>point</literal>, <literal>line</literal>),
+ (<literal>point</literal>, <literal>path</literal>),
+ (<literal>point</literal>, <literal>polygon</literal>),
+ (<literal>point</literal>, <literal>circle</literal>),
+ (<literal>box</literal>, <literal>box</literal>),
+ (<literal>lseg</literal>, <literal>box</literal>),
+ (<literal>lseg</literal>, <literal>line</literal>),
+ (<literal>polygon</literal>, <literal>polygon</literal>),
+ (<literal>circle</literal>, <literal>circle</literal>).
+ </para>
+ <para>
+ <literal>point '(1,1)' &lt;@ circle '&lt;(0,0),2&gt;'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&amp;&amp;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do these objects overlap? (One point in common makes this true.)
+ Available for <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(1,1),(0,0)' &amp;&amp; box '(2,2),(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&lt;&lt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object strictly left of second?
+ Available for <type>point</type>, <type>box</type>,
+ <type>polygon</type>, <type>circle</type>.
+ </para>
+ <para>
+ <literal>circle '&lt;(0,0),1&gt;' &lt;&lt; circle '&lt;(5,0),1&gt;'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&gt;&gt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object strictly right of second?
+ Available for <type>point</type>, <type>box</type>,
+ <type>polygon</type>, <type>circle</type>.
+ </para>
+ <para>
+ <literal>circle '&lt;(5,0),1&gt;' &gt;&gt; circle '&lt;(0,0),1&gt;'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&amp;&lt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does first object not extend to the right of second?
+ Available for <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(1,1),(0,0)' &amp;&lt; box '(2,2),(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&amp;&gt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does first object not extend to the left of second?
+ Available for <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(3,3),(0,0)' &amp;&gt; box '(2,2),(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&lt;&lt;|</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object strictly below second?
+ Available for <type>point</type>, <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(3,3),(0,0)' &lt;&lt;| box '(5,5),(3,4)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>|&gt;&gt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object strictly above second?
+ Available for <type>point</type>, <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(5,5),(3,4)' |&gt;&gt; box '(3,3),(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>&amp;&lt;|</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does first object not extend above second?
+ Available for <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(1,1),(0,0)' &amp;&lt;| box '(2,2),(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>|&amp;&gt;</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does first object not extend below second?
+ Available for <type>box</type>, <type>polygon</type>,
+ <type>circle</type>.
+ </para>
+ <para>
+ <literal>box '(3,3),(0,0)' |&amp;&gt; box '(2,2),(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>box</type> <literal>&lt;^</literal> <type>box</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object below second (allows edges to touch)?
+ </para>
+ <para>
+ <literal>box '((1,1),(0,0))' &lt;^ box '((2,2),(1,1))'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>box</type> <literal>&gt;^</literal> <type>box</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first object above second (allows edges to touch)?
+ </para>
+ <para>
+ <literal>box '((2,2),(1,1))' &gt;^ box '((1,1),(0,0))'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>?#</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do these objects intersect?
+ Available for these pairs of types:
+ (<type>box</type>, <type>box</type>),
+ (<type>lseg</type>, <type>box</type>),
+ (<type>lseg</type>, <type>lseg</type>),
+ (<type>lseg</type>, <type>line</type>),
+ (<type>line</type>, <type>box</type>),
+ (<type>line</type>, <type>line</type>),
+ (<type>path</type>, <type>path</type>).
+ </para>
+ <para>
+ <literal>lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>?-</literal> <type>line</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <literal>?-</literal> <type>lseg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is line horizontal?
+ </para>
+ <para>
+ <literal>?- lseg '[(-1,0),(1,0)]'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>point</type> <literal>?-</literal> <type>point</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are points horizontally aligned (that is, have same y coordinate)?
+ </para>
+ <para>
+ <literal>point '(1,0)' ?- point '(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>?|</literal> <type>line</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <literal>?|</literal> <type>lseg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is line vertical?
+ </para>
+ <para>
+ <literal>?| lseg '[(-1,0),(1,0)]'</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>point</type> <literal>?|</literal> <type>point</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are points vertically aligned (that is, have same x coordinate)?
+ </para>
+ <para>
+ <literal>point '(0,1)' ?| point '(0,0)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>line</type> <literal>?-|</literal> <type>line</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>lseg</type> <literal>?-|</literal> <type>lseg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are lines perpendicular?
+ </para>
+ <para>
+ <literal>lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>line</type> <literal>?||</literal> <type>line</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>lseg</type> <literal>?||</literal> <type>lseg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are lines parallel?
+ </para>
+ <para>
+ <literal>lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>geometric_type</replaceable> <literal>~=</literal> <replaceable>geometric_type</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are these objects the same?
+ Available for <type>point</type>, <type>box</type>,
+ <type>polygon</type>, <type>circle</type>.
+ </para>
+ <para>
+ <literal>polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <caution>
+ <para>
+ Note that the <quote>same as</quote> operator, <literal>~=</literal>,
+ represents the usual notion of equality for the <type>point</type>,
+ <type>box</type>, <type>polygon</type>, and <type>circle</type> types.
+ Some of the geometric types also have an <literal>=</literal> operator, but
+ <literal>=</literal> compares for equal <emphasis>areas</emphasis> only.
+ The other scalar comparison operators (<literal>&lt;=</literal> and so
+ on), where available for these types, likewise compare areas.
+ </para>
+ </caution>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 14, the point
+ is strictly below/above comparison operators <type>point</type>
+ <literal>&lt;&lt;|</literal> <type>point</type> and <type>point</type>
+ <literal>|&gt;&gt;</literal> <type>point</type> were respectively
+ called <literal>&lt;^</literal> and <literal>&gt;^</literal>. These
+ names are still available, but are deprecated and will eventually be
+ removed.
+ </para>
+ </note>
+
+ <table id="functions-geometry-func-table">
+ <title>Geometric Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>area</primary>
+ </indexterm>
+ <function>area</function> ( <replaceable>geometric_type</replaceable> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes area.
+ Available for <type>box</type>, <type>path</type>, <type>circle</type>.
+ A <type>path</type> input must be closed, else NULL is returned.
+ Also, if the <type>path</type> is self-intersecting, the result may be
+ meaningless.
+ </para>
+ <para>
+ <literal>area(box '(2,2),(0,0)')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>center</primary>
+ </indexterm>
+ <function>center</function> ( <replaceable>geometric_type</replaceable> )
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes center point.
+ Available for <type>box</type>, <type>circle</type>.
+ </para>
+ <para>
+ <literal>center(box '(1,2),(0,0)')</literal>
+ <returnvalue>(0.5,1)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>diagonal</primary>
+ </indexterm>
+ <function>diagonal</function> ( <type>box</type> )
+ <returnvalue>lseg</returnvalue>
+ </para>
+ <para>
+ Extracts box's diagonal as a line segment
+ (same as <function>lseg(box)</function>).
+ </para>
+ <para>
+ <literal>diagonal(box '(1,2),(0,0)')</literal>
+ <returnvalue>[(1,2),(0,0)]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>diameter</primary>
+ </indexterm>
+ <function>diameter</function> ( <type>circle</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes diameter of circle.
+ </para>
+ <para>
+ <literal>diameter(circle '&lt;(0,0),2&gt;')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>height</primary>
+ </indexterm>
+ <function>height</function> ( <type>box</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes vertical size of box.
+ </para>
+ <para>
+ <literal>height(box '(1,2),(0,0)')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>isclosed</primary>
+ </indexterm>
+ <function>isclosed</function> ( <type>path</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is path closed?
+ </para>
+ <para>
+ <literal>isclosed(path '((0,0),(1,1),(2,0))')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>isopen</primary>
+ </indexterm>
+ <function>isopen</function> ( <type>path</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is path open?
+ </para>
+ <para>
+ <literal>isopen(path '[(0,0),(1,1),(2,0)]')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>length</primary>
+ </indexterm>
+ <function>length</function> ( <replaceable>geometric_type</replaceable> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the total length.
+ Available for <type>lseg</type>, <type>path</type>.
+ </para>
+ <para>
+ <literal>length(path '((-1,0),(1,0))')</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>npoints</primary>
+ </indexterm>
+ <function>npoints</function> ( <replaceable>geometric_type</replaceable> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of points.
+ Available for <type>path</type>, <type>polygon</type>.
+ </para>
+ <para>
+ <literal>npoints(path '[(0,0),(1,1),(2,0)]')</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pclose</primary>
+ </indexterm>
+ <function>pclose</function> ( <type>path</type> )
+ <returnvalue>path</returnvalue>
+ </para>
+ <para>
+ Converts path to closed form.
+ </para>
+ <para>
+ <literal>pclose(path '[(0,0),(1,1),(2,0)]')</literal>
+ <returnvalue>((0,0),(1,1),(2,0))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>popen</primary>
+ </indexterm>
+ <function>popen</function> ( <type>path</type> )
+ <returnvalue>path</returnvalue>
+ </para>
+ <para>
+ Converts path to open form.
+ </para>
+ <para>
+ <literal>popen(path '((0,0),(1,1),(2,0))')</literal>
+ <returnvalue>[(0,0),(1,1),(2,0)]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>radius</primary>
+ </indexterm>
+ <function>radius</function> ( <type>circle</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes radius of circle.
+ </para>
+ <para>
+ <literal>radius(circle '&lt;(0,0),2&gt;')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>slope</primary>
+ </indexterm>
+ <function>slope</function> ( <type>point</type>, <type>point</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes slope of a line drawn through the two points.
+ </para>
+ <para>
+ <literal>slope(point '(0,0)', point '(2,1)')</literal>
+ <returnvalue>0.5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>width</primary>
+ </indexterm>
+ <function>width</function> ( <type>box</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes horizontal size of box.
+ </para>
+ <para>
+ <literal>width(box '(1,2),(0,0)')</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-geometry-conv-table">
+ <title>Geometric Type Conversion Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>box</primary>
+ </indexterm>
+ <function>box</function> ( <type>circle</type> )
+ <returnvalue>box</returnvalue>
+ </para>
+ <para>
+ Computes box inscribed within the circle.
+ </para>
+ <para>
+ <literal>box(circle '&lt;(0,0),2&gt;')</literal>
+ <returnvalue>(1.414213562373095,1.414213562373095),&zwsp;(-1.414213562373095,-1.414213562373095)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>box</function> ( <type>point</type> )
+ <returnvalue>box</returnvalue>
+ </para>
+ <para>
+ Converts point to empty box.
+ </para>
+ <para>
+ <literal>box(point '(1,0)')</literal>
+ <returnvalue>(1,0),(1,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>box</function> ( <type>point</type>, <type>point</type> )
+ <returnvalue>box</returnvalue>
+ </para>
+ <para>
+ Converts any two corner points to box.
+ </para>
+ <para>
+ <literal>box(point '(0,1)', point '(1,0)')</literal>
+ <returnvalue>(1,1),(0,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>box</function> ( <type>polygon</type> )
+ <returnvalue>box</returnvalue>
+ </para>
+ <para>
+ Computes bounding box of polygon.
+ </para>
+ <para>
+ <literal>box(polygon '((0,0),(1,1),(2,0))')</literal>
+ <returnvalue>(2,1),(0,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bound_box</primary>
+ </indexterm>
+ <function>bound_box</function> ( <type>box</type>, <type>box</type> )
+ <returnvalue>box</returnvalue>
+ </para>
+ <para>
+ Computes bounding box of two boxes.
+ </para>
+ <para>
+ <literal>bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)')</literal>
+ <returnvalue>(4,4),(0,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>circle</primary>
+ </indexterm>
+ <function>circle</function> ( <type>box</type> )
+ <returnvalue>circle</returnvalue>
+ </para>
+ <para>
+ Computes smallest circle enclosing box.
+ </para>
+ <para>
+ <literal>circle(box '(1,1),(0,0)')</literal>
+ <returnvalue>&lt;(0.5,0.5),0.7071067811865476&gt;</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>circle</function> ( <type>point</type>, <type>double precision</type> )
+ <returnvalue>circle</returnvalue>
+ </para>
+ <para>
+ Constructs circle from center and radius.
+ </para>
+ <para>
+ <literal>circle(point '(0,0)', 2.0)</literal>
+ <returnvalue>&lt;(0,0),2&gt;</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>circle</function> ( <type>polygon</type> )
+ <returnvalue>circle</returnvalue>
+ </para>
+ <para>
+ Converts polygon to circle. The circle's center is the mean of the
+ positions of the polygon's points, and the radius is the average
+ distance of the polygon's points from that center.
+ </para>
+ <para>
+ <literal>circle(polygon '((0,0),(1,3),(2,0))')</literal>
+ <returnvalue>&lt;(1,1),1.6094757082487299&gt;</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>line</primary>
+ </indexterm>
+ <function>line</function> ( <type>point</type>, <type>point</type> )
+ <returnvalue>line</returnvalue>
+ </para>
+ <para>
+ Converts two points to the line through them.
+ </para>
+ <para>
+ <literal>line(point '(-1,0)', point '(1,0)')</literal>
+ <returnvalue>{0,-1,0}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lseg</primary>
+ </indexterm>
+ <function>lseg</function> ( <type>box</type> )
+ <returnvalue>lseg</returnvalue>
+ </para>
+ <para>
+ Extracts box's diagonal as a line segment.
+ </para>
+ <para>
+ <literal>lseg(box '(1,0),(-1,0)')</literal>
+ <returnvalue>[(1,0),(-1,0)]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>lseg</function> ( <type>point</type>, <type>point</type> )
+ <returnvalue>lseg</returnvalue>
+ </para>
+ <para>
+ Constructs line segment from two endpoints.
+ </para>
+ <para>
+ <literal>lseg(point '(-1,0)', point '(1,0)')</literal>
+ <returnvalue>[(-1,0),(1,0)]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>path</primary>
+ </indexterm>
+ <function>path</function> ( <type>polygon</type> )
+ <returnvalue>path</returnvalue>
+ </para>
+ <para>
+ Converts polygon to a closed path with the same list of points.
+ </para>
+ <para>
+ <literal>path(polygon '((0,0),(1,1),(2,0))')</literal>
+ <returnvalue>((0,0),(1,1),(2,0))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>point</primary>
+ </indexterm>
+ <function>point</function> ( <type>double precision</type>, <type>double precision</type> )
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Constructs point from its coordinates.
+ </para>
+ <para>
+ <literal>point(23.4, -44.5)</literal>
+ <returnvalue>(23.4,-44.5)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>point</function> ( <type>box</type> )
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes center of box.
+ </para>
+ <para>
+ <literal>point(box '(1,0),(-1,0)')</literal>
+ <returnvalue>(0,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>point</function> ( <type>circle</type> )
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes center of circle.
+ </para>
+ <para>
+ <literal>point(circle '&lt;(0,0),2&gt;')</literal>
+ <returnvalue>(0,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>point</function> ( <type>lseg</type> )
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes center of line segment.
+ </para>
+ <para>
+ <literal>point(lseg '[(-1,0),(1,0)]')</literal>
+ <returnvalue>(0,0)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>point</function> ( <type>polygon</type> )
+ <returnvalue>point</returnvalue>
+ </para>
+ <para>
+ Computes center of polygon (the mean of the
+ positions of the polygon's points).
+ </para>
+ <para>
+ <literal>point(polygon '((0,0),(1,1),(2,0))')</literal>
+ <returnvalue>(1,0.3333333333333333)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>polygon</primary>
+ </indexterm>
+ <function>polygon</function> ( <type>box</type> )
+ <returnvalue>polygon</returnvalue>
+ </para>
+ <para>
+ Converts box to a 4-point polygon.
+ </para>
+ <para>
+ <literal>polygon(box '(1,1),(0,0)')</literal>
+ <returnvalue>((0,0),(0,1),(1,1),(1,0))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>polygon</function> ( <type>circle</type> )
+ <returnvalue>polygon</returnvalue>
+ </para>
+ <para>
+ Converts circle to a 12-point polygon.
+ </para>
+ <para>
+ <literal>polygon(circle '&lt;(0,0),2&gt;')</literal>
+ <returnvalue>((-2,0),&zwsp;(-1.7320508075688774,0.9999999999999999),&zwsp;(-1.0000000000000002,1.7320508075688772),&zwsp;(-1.2246063538223773e-16,2),&zwsp;(0.9999999999999996,1.7320508075688774),&zwsp;(1.732050807568877,1.0000000000000007),&zwsp;(2,2.4492127076447545e-16),&zwsp;(1.7320508075688776,-0.9999999999999994),&zwsp;(1.0000000000000009,-1.7320508075688767),&zwsp;(3.673819061467132e-16,-2),&zwsp;(-0.9999999999999987,-1.732050807568878),&zwsp;(-1.7320508075688767,-1.0000000000000009))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>polygon</function> ( <type>integer</type>, <type>circle</type> )
+ <returnvalue>polygon</returnvalue>
+ </para>
+ <para>
+ Converts circle to an <replaceable>n</replaceable>-point polygon.
+ </para>
+ <para>
+ <literal>polygon(4, circle '&lt;(3,0),1&gt;')</literal>
+ <returnvalue>((2,0),&zwsp;(3,1),&zwsp;(4,1.2246063538223773e-16),&zwsp;(3,-1))</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>polygon</function> ( <type>path</type> )
+ <returnvalue>polygon</returnvalue>
+ </para>
+ <para>
+ Converts closed path to a polygon with the same list of points.
+ </para>
+ <para>
+ <literal>polygon(path '((0,0),(1,1),(2,0))')</literal>
+ <returnvalue>((0,0),(1,1),(2,0))</returnvalue>
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ It is possible to access the two component numbers of a <type>point</type>
+ as though the point were an array with indexes 0 and 1. For example, if
+ <literal>t.p</literal> is a <type>point</type> column then
+ <literal>SELECT p[0] FROM t</literal> retrieves the X coordinate and
+ <literal>UPDATE t SET p[1] = ...</literal> changes the Y coordinate.
+ In the same way, a value of type <type>box</type> or <type>lseg</type> can be treated
+ as an array of two <type>point</type> values.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="functions-net">
+ <title>Network Address Functions and Operators</title>
+
+ <para>
+ The IP network address types, <type>cidr</type> and <type>inet</type>,
+ support the usual comparison operators shown in
+ <xref linkend="functions-comparison-op-table"/>
+ as well as the specialized operators and functions shown in
+ <xref linkend="cidr-inet-operators-table"/> and
+ <xref linkend="cidr-inet-functions-table"/>.
+ </para>
+
+ <para>
+ Any <type>cidr</type> value can be cast to <type>inet</type> implicitly;
+ therefore, the operators and functions shown below as operating on
+ <type>inet</type> also work on <type>cidr</type> values. (Where there are
+ separate functions for <type>inet</type> and <type>cidr</type>, it is
+ because the behavior should be different for the two cases.)
+ Also, it is permitted to cast an <type>inet</type> value
+ to <type>cidr</type>. When this is done, any bits to the right of the
+ netmask are silently zeroed to create a valid <type>cidr</type> value.
+ </para>
+
+ <table id="cidr-inet-operators-table">
+ <title>IP Address Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>&lt;&lt;</literal> <type>inet</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is subnet strictly contained by subnet?
+ This operator, and the next four, test for subnet inclusion. They
+ consider only the network parts of the two addresses (ignoring any
+ bits to the right of the netmasks) and determine whether one network
+ is identical to or a subnet of the other.
+ </para>
+ <para>
+ <literal>inet '192.168.1.5' &lt;&lt; inet '192.168.1/24'</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>inet '192.168.0.5' &lt;&lt; inet '192.168.1/24'</literal>
+ <returnvalue>f</returnvalue>
+ </para>
+ <para>
+ <literal>inet '192.168.1/24' &lt;&lt; inet '192.168.1/24'</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>&lt;&lt;=</literal> <type>inet</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is subnet contained by or equal to subnet?
+ </para>
+ <para>
+ <literal>inet '192.168.1/24' &lt;&lt;= inet '192.168.1/24'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>&gt;&gt;</literal> <type>inet</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does subnet strictly contain subnet?
+ </para>
+ <para>
+ <literal>inet '192.168.1/24' &gt;&gt; inet '192.168.1.5'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>&gt;&gt;=</literal> <type>inet</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does subnet contain or equal subnet?
+ </para>
+ <para>
+ <literal>inet '192.168.1/24' &gt;&gt;= inet '192.168.1/24'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>&amp;&amp;</literal> <type>inet</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does either subnet contain or equal the other?
+ </para>
+ <para>
+ <literal>inet '192.168.1/24' &amp;&amp; inet '192.168.1.80/28'</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>inet '192.168.1/24' &amp;&amp; inet '192.168.2.0/28'</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>~</literal> <type>inet</type>
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Computes bitwise NOT.
+ </para>
+ <para>
+ <literal>~ inet '192.168.1.6'</literal>
+ <returnvalue>63.87.254.249</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>&amp;</literal> <type>inet</type>
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Computes bitwise AND.
+ </para>
+ <para>
+ <literal>inet '192.168.1.6' &amp; inet '0.0.0.255'</literal>
+ <returnvalue>0.0.0.6</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>|</literal> <type>inet</type>
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Computes bitwise OR.
+ </para>
+ <para>
+ <literal>inet '192.168.1.6' | inet '0.0.0.255'</literal>
+ <returnvalue>192.168.1.255</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>+</literal> <type>bigint</type>
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Adds an offset to an address.
+ </para>
+ <para>
+ <literal>inet '192.168.1.6' + 25</literal>
+ <returnvalue>192.168.1.31</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>bigint</type> <literal>+</literal> <type>inet</type>
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Adds an offset to an address.
+ </para>
+ <para>
+ <literal>200 + inet '::ffff:fff0:1'</literal>
+ <returnvalue>::ffff:255.240.0.201</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>-</literal> <type>bigint</type>
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Subtracts an offset from an address.
+ </para>
+ <para>
+ <literal>inet '192.168.1.43' - 36</literal>
+ <returnvalue>192.168.1.7</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>inet</type> <literal>-</literal> <type>inet</type>
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the difference of two addresses.
+ </para>
+ <para>
+ <literal>inet '192.168.1.43' - inet '192.168.1.19'</literal>
+ <returnvalue>24</returnvalue>
+ </para>
+ <para>
+ <literal>inet '::1' - inet '::ffff:1'</literal>
+ <returnvalue>-4294901760</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="cidr-inet-functions-table">
+ <title>IP Address Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>abbrev</primary>
+ </indexterm>
+ <function>abbrev</function> ( <type>inet</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Creates an abbreviated display format as text.
+ (The result is the same as the <type>inet</type> output function
+ produces; it is <quote>abbreviated</quote> only in comparison to the
+ result of an explicit cast to <type>text</type>, which for historical
+ reasons will never suppress the netmask part.)
+ </para>
+ <para>
+ <literal>abbrev(inet '10.1.0.0/32')</literal>
+ <returnvalue>10.1.0.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>abbrev</function> ( <type>cidr</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Creates an abbreviated display format as text.
+ (The abbreviation consists of dropping all-zero octets to the right
+ of the netmask; more examples are in
+ <xref linkend="datatype-net-cidr-table"/>.)
+ </para>
+ <para>
+ <literal>abbrev(cidr '10.1.0.0/16')</literal>
+ <returnvalue>10.1/16</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>broadcast</primary>
+ </indexterm>
+ <function>broadcast</function> ( <type>inet</type> )
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Computes the broadcast address for the address's network.
+ </para>
+ <para>
+ <literal>broadcast(inet '192.168.1.5/24')</literal>
+ <returnvalue>192.168.1.255/24</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>family</primary>
+ </indexterm>
+ <function>family</function> ( <type>inet</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the address's family: <literal>4</literal> for IPv4,
+ <literal>6</literal> for IPv6.
+ </para>
+ <para>
+ <literal>family(inet '::1')</literal>
+ <returnvalue>6</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>host</primary>
+ </indexterm>
+ <function>host</function> ( <type>inet</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the IP address as text, ignoring the netmask.
+ </para>
+ <para>
+ <literal>host(inet '192.168.1.0/24')</literal>
+ <returnvalue>192.168.1.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>hostmask</primary>
+ </indexterm>
+ <function>hostmask</function> ( <type>inet</type> )
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Computes the host mask for the address's network.
+ </para>
+ <para>
+ <literal>hostmask(inet '192.168.23.20/30')</literal>
+ <returnvalue>0.0.0.3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>inet_merge</primary>
+ </indexterm>
+ <function>inet_merge</function> ( <type>inet</type>, <type>inet</type> )
+ <returnvalue>cidr</returnvalue>
+ </para>
+ <para>
+ Computes the smallest network that includes both of the given networks.
+ </para>
+ <para>
+ <literal>inet_merge(inet '192.168.1.5/24', inet '192.168.2.5/24')</literal>
+ <returnvalue>192.168.0.0/22</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>inet_same_family</primary>
+ </indexterm>
+ <function>inet_same_family</function> ( <type>inet</type>, <type>inet</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether the addresses belong to the same IP family.
+ </para>
+ <para>
+ <literal>inet_same_family(inet '192.168.1.5/24', inet '::1')</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>masklen</primary>
+ </indexterm>
+ <function>masklen</function> ( <type>inet</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the netmask length in bits.
+ </para>
+ <para>
+ <literal>masklen(inet '192.168.1.5/24')</literal>
+ <returnvalue>24</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>netmask</primary>
+ </indexterm>
+ <function>netmask</function> ( <type>inet</type> )
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Computes the network mask for the address's network.
+ </para>
+ <para>
+ <literal>netmask(inet '192.168.1.5/24')</literal>
+ <returnvalue>255.255.255.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>network</primary>
+ </indexterm>
+ <function>network</function> ( <type>inet</type> )
+ <returnvalue>cidr</returnvalue>
+ </para>
+ <para>
+ Returns the network part of the address, zeroing out
+ whatever is to the right of the netmask.
+ (This is equivalent to casting the value to <type>cidr</type>.)
+ </para>
+ <para>
+ <literal>network(inet '192.168.1.5/24')</literal>
+ <returnvalue>192.168.1.0/24</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>set_masklen</primary>
+ </indexterm>
+ <function>set_masklen</function> ( <type>inet</type>, <type>integer</type> )
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Sets the netmask length for an <type>inet</type> value.
+ The address part does not change.
+ </para>
+ <para>
+ <literal>set_masklen(inet '192.168.1.5/24', 16)</literal>
+ <returnvalue>192.168.1.5/16</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>set_masklen</function> ( <type>cidr</type>, <type>integer</type> )
+ <returnvalue>cidr</returnvalue>
+ </para>
+ <para>
+ Sets the netmask length for a <type>cidr</type> value.
+ Address bits to the right of the new netmask are set to zero.
+ </para>
+ <para>
+ <literal>set_masklen(cidr '192.168.1.0/24', 16)</literal>
+ <returnvalue>192.168.0.0/16</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>text</primary>
+ </indexterm>
+ <function>text</function> ( <type>inet</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the unabbreviated IP address and netmask length as text.
+ (This has the same result as an explicit cast to <type>text</type>.)
+ </para>
+ <para>
+ <literal>text(inet '192.168.1.5')</literal>
+ <returnvalue>192.168.1.5/32</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <tip>
+ <para>
+ The <function>abbrev</function>, <function>host</function>,
+ and <function>text</function> functions are primarily intended to offer
+ alternative display formats for IP addresses.
+ </para>
+ </tip>
+
+ <para>
+ The MAC address types, <type>macaddr</type> and <type>macaddr8</type>,
+ support the usual comparison operators shown in
+ <xref linkend="functions-comparison-op-table"/>
+ as well as the specialized functions shown in
+ <xref linkend="macaddr-functions-table"/>.
+ In addition, they support the bitwise logical operators
+ <literal>~</literal>, <literal>&amp;</literal> and <literal>|</literal>
+ (NOT, AND and OR), just as shown above for IP addresses.
+ </para>
+
+ <table id="macaddr-functions-table">
+ <title>MAC Address Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>trunc</primary>
+ </indexterm>
+ <function>trunc</function> ( <type>macaddr</type> )
+ <returnvalue>macaddr</returnvalue>
+ </para>
+ <para>
+ Sets the last 3 bytes of the address to zero. The remaining prefix
+ can be associated with a particular manufacturer (using data not
+ included in <productname>PostgreSQL</productname>).
+ </para>
+ <para>
+ <literal>trunc(macaddr '12:34:56:78:90:ab')</literal>
+ <returnvalue>12:34:56:00:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>trunc</function> ( <type>macaddr8</type> )
+ <returnvalue>macaddr8</returnvalue>
+ </para>
+ <para>
+ Sets the last 5 bytes of the address to zero. The remaining prefix
+ can be associated with a particular manufacturer (using data not
+ included in <productname>PostgreSQL</productname>).
+ </para>
+ <para>
+ <literal>trunc(macaddr8 '12:34:56:78:90:ab:cd:ef')</literal>
+ <returnvalue>12:34:56:00:00:00:00:00</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>macaddr8_set7bit</primary>
+ </indexterm>
+ <function>macaddr8_set7bit</function> ( <type>macaddr8</type> )
+ <returnvalue>macaddr8</returnvalue>
+ </para>
+ <para>
+ Sets the 7th bit of the address to one, creating what is known as
+ modified EUI-64, for inclusion in an IPv6 address.
+ </para>
+ <para>
+ <literal>macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef')</literal>
+ <returnvalue>02:34:56:ff:fe:ab:cd:ef</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+
+ <sect1 id="functions-textsearch">
+ <title>Text Search Functions and Operators</title>
+
+ <indexterm zone="datatype-textsearch">
+ <primary>full text search</primary>
+ <secondary>functions and operators</secondary>
+ </indexterm>
+
+ <indexterm zone="datatype-textsearch">
+ <primary>text search</primary>
+ <secondary>functions and operators</secondary>
+ </indexterm>
+
+ <para>
+ <xref linkend="textsearch-operators-table"/>,
+ <xref linkend="textsearch-functions-table"/> and
+ <xref linkend="textsearch-functions-debug-table"/>
+ summarize the functions and operators that are provided
+ for full text searching. See <xref linkend="textsearch"/> for a detailed
+ explanation of <productname>PostgreSQL</productname>'s text search
+ facility.
+ </para>
+
+ <table id="textsearch-operators-table">
+ <title>Text Search Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsvector</type> <literal>@@</literal> <type>tsquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>tsquery</type> <literal>@@</literal> <type>tsvector</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>tsvector</type> match <type>tsquery</type>?
+ (The arguments can be given in either order.)
+ </para>
+ <para>
+ <literal>to_tsvector('fat cats ate rats') @@ to_tsquery('cat &amp; rat')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>@@</literal> <type>tsquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does text string, after implicit invocation
+ of <function>to_tsvector()</function>, match <type>tsquery</type>?
+ </para>
+ <para>
+ <literal>'fat cats ate rats' @@ to_tsquery('cat &amp; rat')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsvector</type> <literal>@@@</literal> <type>tsquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>tsquery</type> <literal>@@@</literal> <type>tsvector</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ This is a deprecated synonym for <literal>@@</literal>.
+ </para>
+ <para>
+ <literal>to_tsvector('fat cats ate rats') @@@ to_tsquery('cat &amp; rat')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsvector</type> <literal>||</literal> <type>tsvector</type>
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Concatenates two <type>tsvector</type>s. If both inputs contain
+ lexeme positions, the second input's positions are adjusted
+ accordingly.
+ </para>
+ <para>
+ <literal>'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector</literal>
+ <returnvalue>'a':1 'b':2,5 'c':3 'd':4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsquery</type> <literal>&amp;&amp;</literal> <type>tsquery</type>
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ ANDs two <type>tsquery</type>s together, producing a query that
+ matches documents that match both input queries.
+ </para>
+ <para>
+ <literal>'fat | rat'::tsquery &amp;&amp; 'cat'::tsquery</literal>
+ <returnvalue>( 'fat' | 'rat' ) &amp; 'cat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsquery</type> <literal>||</literal> <type>tsquery</type>
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ ORs two <type>tsquery</type>s together, producing a query that
+ matches documents that match either input query.
+ </para>
+ <para>
+ <literal>'fat | rat'::tsquery || 'cat'::tsquery</literal>
+ <returnvalue>'fat' | 'rat' | 'cat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>!!</literal> <type>tsquery</type>
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Negates a <type>tsquery</type>, producing a query that matches
+ documents that do not match the input query.
+ </para>
+ <para>
+ <literal>!! 'cat'::tsquery</literal>
+ <returnvalue>!'cat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsquery</type> <literal>&lt;-&gt;</literal> <type>tsquery</type>
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Constructs a phrase query, which matches if the two input queries
+ match at successive lexemes.
+ </para>
+ <para>
+ <literal>to_tsquery('fat') &lt;-&gt; to_tsquery('rat')</literal>
+ <returnvalue>'fat' &lt;-&gt; 'rat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsquery</type> <literal>@&gt;</literal> <type>tsquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does first <type>tsquery</type> contain the second? (This considers
+ only whether all the lexemes appearing in one query appear in the
+ other, ignoring the combining operators.)
+ </para>
+ <para>
+ <literal>'cat'::tsquery @&gt; 'cat &amp; rat'::tsquery</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>tsquery</type> <literal>&lt;@</literal> <type>tsquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is first <type>tsquery</type> contained in the second? (This
+ considers only whether all the lexemes appearing in one query appear
+ in the other, ignoring the combining operators.)
+ </para>
+ <para>
+ <literal>'cat'::tsquery &lt;@ 'cat &amp; rat'::tsquery</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>'cat'::tsquery &lt;@ '!cat &amp; rat'::tsquery</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In addition to these specialized operators, the usual comparison
+ operators shown in <xref linkend="functions-comparison-op-table"/> are
+ available for types <type>tsvector</type> and <type>tsquery</type>.
+ These are not very
+ useful for text searching but allow, for example, unique indexes to be
+ built on columns of these types.
+ </para>
+
+ <table id="textsearch-functions-table">
+ <title>Text Search Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_to_tsvector</primary>
+ </indexterm>
+ <function>array_to_tsvector</function> ( <type>text[]</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Converts an array of text strings to a <type>tsvector</type>.
+ The given strings are used as lexemes as-is, without further
+ processing. Array elements must not be empty strings
+ or <literal>NULL</literal>.
+ </para>
+ <para>
+ <literal>array_to_tsvector('{fat,cat,rat}'::text[])</literal>
+ <returnvalue>'cat' 'fat' 'rat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>get_current_ts_config</primary>
+ </indexterm>
+ <function>get_current_ts_config</function> ( )
+ <returnvalue>regconfig</returnvalue>
+ </para>
+ <para>
+ Returns the OID of the current default text search configuration
+ (as set by <xref linkend="guc-default-text-search-config"/>).
+ </para>
+ <para>
+ <literal>get_current_ts_config()</literal>
+ <returnvalue>english</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>length</primary>
+ </indexterm>
+ <function>length</function> ( <type>tsvector</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of lexemes in the <type>tsvector</type>.
+ </para>
+ <para>
+ <literal>length('fat:2,4 cat:3 rat:5A'::tsvector)</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>numnode</primary>
+ </indexterm>
+ <function>numnode</function> ( <type>tsquery</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of lexemes plus operators in
+ the <type>tsquery</type>.
+ </para>
+ <para>
+ <literal>numnode('(fat &amp; rat) | cat'::tsquery)</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>plainto_tsquery</primary>
+ </indexterm>
+ <function>plainto_tsquery</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>query</parameter> <type>text</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Converts text to a <type>tsquery</type>, normalizing words according to
+ the specified or default configuration. Any punctuation in the string
+ is ignored (it does not determine query operators). The resulting
+ query matches documents containing all non-stopwords in the text.
+ </para>
+ <para>
+ <literal>plainto_tsquery('english', 'The Fat Rats')</literal>
+ <returnvalue>'fat' &amp; 'rat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>phraseto_tsquery</primary>
+ </indexterm>
+ <function>phraseto_tsquery</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>query</parameter> <type>text</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Converts text to a <type>tsquery</type>, normalizing words according to
+ the specified or default configuration. Any punctuation in the string
+ is ignored (it does not determine query operators). The resulting
+ query matches phrases containing all non-stopwords in the text.
+ </para>
+ <para>
+ <literal>phraseto_tsquery('english', 'The Fat Rats')</literal>
+ <returnvalue>'fat' &lt;-&gt; 'rat'</returnvalue>
+ </para>
+ <para>
+ <literal>phraseto_tsquery('english', 'The Cat and Rats')</literal>
+ <returnvalue>'cat' &lt;2&gt; 'rat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>websearch_to_tsquery</primary>
+ </indexterm>
+ <function>websearch_to_tsquery</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>query</parameter> <type>text</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Converts text to a <type>tsquery</type>, normalizing words according
+ to the specified or default configuration. Quoted word sequences are
+ converted to phrase tests. The word <quote>or</quote> is understood
+ as producing an OR operator, and a dash produces a NOT operator;
+ other punctuation is ignored.
+ This approximates the behavior of some common web search tools.
+ </para>
+ <para>
+ <literal>websearch_to_tsquery('english', '"fat rat" or cat dog')</literal>
+ <returnvalue>'fat' &lt;-&gt; 'rat' | 'cat' &amp; 'dog'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>querytree</primary>
+ </indexterm>
+ <function>querytree</function> ( <type>tsquery</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Produces a representation of the indexable portion of
+ a <type>tsquery</type>. A result that is empty or
+ just <literal>T</literal> indicates a non-indexable query.
+ </para>
+ <para>
+ <literal>querytree('foo &amp; ! bar'::tsquery)</literal>
+ <returnvalue>'foo'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>setweight</primary>
+ </indexterm>
+ <function>setweight</function> ( <parameter>vector</parameter> <type>tsvector</type>, <parameter>weight</parameter> <type>"char"</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Assigns the specified <parameter>weight</parameter> to each element
+ of the <parameter>vector</parameter>.
+ </para>
+ <para>
+ <literal>setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A')</literal>
+ <returnvalue>'cat':3A 'fat':2A,4A 'rat':5A</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>setweight</primary>
+ <secondary>setweight for specific lexeme(s)</secondary>
+ </indexterm>
+ <function>setweight</function> ( <parameter>vector</parameter> <type>tsvector</type>, <parameter>weight</parameter> <type>"char"</type>, <parameter>lexemes</parameter> <type>text[]</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Assigns the specified <parameter>weight</parameter> to elements
+ of the <parameter>vector</parameter> that are listed
+ in <parameter>lexemes</parameter>.
+ The strings in <parameter>lexemes</parameter> are taken as lexemes
+ as-is, without further processing. Strings that do not match any
+ lexeme in <parameter>vector</parameter> are ignored.
+ </para>
+ <para>
+ <literal>setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}')</literal>
+ <returnvalue>'cat':3A 'fat':2,4 'rat':5A,6A</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>strip</primary>
+ </indexterm>
+ <function>strip</function> ( <type>tsvector</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Removes positions and weights from the <type>tsvector</type>.
+ </para>
+ <para>
+ <literal>strip('fat:2,4 cat:3 rat:5A'::tsvector)</literal>
+ <returnvalue>'cat' 'fat' 'rat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_tsquery</primary>
+ </indexterm>
+ <function>to_tsquery</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>query</parameter> <type>text</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Converts text to a <type>tsquery</type>, normalizing words according to
+ the specified or default configuration. The words must be combined
+ by valid <type>tsquery</type> operators.
+ </para>
+ <para>
+ <literal>to_tsquery('english', 'The &amp; Fat &amp; Rats')</literal>
+ <returnvalue>'fat' &amp; 'rat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_tsvector</primary>
+ </indexterm>
+ <function>to_tsvector</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>text</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Converts text to a <type>tsvector</type>, normalizing words according
+ to the specified or default configuration. Position information is
+ included in the result.
+ </para>
+ <para>
+ <literal>to_tsvector('english', 'The Fat Rats')</literal>
+ <returnvalue>'fat':2 'rat':3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>to_tsvector</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>json</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>to_tsvector</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>jsonb</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Converts each string value in the JSON document to
+ a <type>tsvector</type>, normalizing words according to the specified
+ or default configuration. The results are then concatenated in
+ document order to produce the output. Position information is
+ generated as though one stopword exists between each pair of string
+ values. (Beware that <quote>document order</quote> of the fields of a
+ JSON object is implementation-dependent when the input
+ is <type>jsonb</type>; observe the difference in the examples.)
+ </para>
+ <para>
+ <literal>to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json)</literal>
+ <returnvalue>'dog':5 'fat':2 'rat':3</returnvalue>
+ </para>
+ <para>
+ <literal>to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::jsonb)</literal>
+ <returnvalue>'dog':1 'fat':4 'rat':5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_to_tsvector</primary>
+ </indexterm>
+ <function>json_to_tsvector</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>json</type>,
+ <parameter>filter</parameter> <type>jsonb</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_to_tsvector</primary>
+ </indexterm>
+ <function>jsonb_to_tsvector</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>jsonb</type>,
+ <parameter>filter</parameter> <type>jsonb</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Selects each item in the JSON document that is requested by
+ the <parameter>filter</parameter> and converts each one to
+ a <type>tsvector</type>, normalizing words according to the specified
+ or default configuration. The results are then concatenated in
+ document order to produce the output. Position information is
+ generated as though one stopword exists between each pair of selected
+ items. (Beware that <quote>document order</quote> of the fields of a
+ JSON object is implementation-dependent when the input
+ is <type>jsonb</type>.)
+ The <parameter>filter</parameter> must be a <type>jsonb</type>
+ array containing zero or more of these keywords:
+ <literal>"string"</literal> (to include all string values),
+ <literal>"numeric"</literal> (to include all numeric values),
+ <literal>"boolean"</literal> (to include all boolean values),
+ <literal>"key"</literal> (to include all keys), or
+ <literal>"all"</literal> (to include all the above).
+ As a special case, the <parameter>filter</parameter> can also be a
+ simple JSON value that is one of these keywords.
+ </para>
+ <para>
+ <literal>json_to_tsvector('english', '{"a": "The Fat Rats", "b": 123}'::json, '["string", "numeric"]')</literal>
+ <returnvalue>'123':5 'fat':2 'rat':3</returnvalue>
+ </para>
+ <para>
+ <literal>json_to_tsvector('english', '{"cat": "The Fat Rats", "dog": 123}'::json, '"all"')</literal>
+ <returnvalue>'123':9 'cat':1 'dog':7 'fat':4 'rat':5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_delete</primary>
+ </indexterm>
+ <function>ts_delete</function> ( <parameter>vector</parameter> <type>tsvector</type>, <parameter>lexeme</parameter> <type>text</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Removes any occurrence of the given <parameter>lexeme</parameter>
+ from the <parameter>vector</parameter>.
+ The <parameter>lexeme</parameter> string is treated as a lexeme as-is,
+ without further processing.
+ </para>
+ <para>
+ <literal>ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat')</literal>
+ <returnvalue>'cat':3 'rat':5A</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>ts_delete</function> ( <parameter>vector</parameter> <type>tsvector</type>, <parameter>lexemes</parameter> <type>text[]</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Removes any occurrences of the lexemes
+ in <parameter>lexemes</parameter>
+ from the <parameter>vector</parameter>.
+ The strings in <parameter>lexemes</parameter> are taken as lexemes
+ as-is, without further processing. Strings that do not match any
+ lexeme in <parameter>vector</parameter> are ignored.
+ </para>
+ <para>
+ <literal>ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat'])</literal>
+ <returnvalue>'cat':3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_filter</primary>
+ </indexterm>
+ <function>ts_filter</function> ( <parameter>vector</parameter> <type>tsvector</type>, <parameter>weights</parameter> <type>"char"[]</type> )
+ <returnvalue>tsvector</returnvalue>
+ </para>
+ <para>
+ Selects only elements with the given <parameter>weights</parameter>
+ from the <parameter>vector</parameter>.
+ </para>
+ <para>
+ <literal>ts_filter('fat:2,4 cat:3b,7c rat:5A'::tsvector, '{a,b}')</literal>
+ <returnvalue>'cat':3B 'rat':5A</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_headline</primary>
+ </indexterm>
+ <function>ts_headline</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>text</type>,
+ <parameter>query</parameter> <type>tsquery</type>
+ <optional>, <parameter>options</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Displays, in an abbreviated form, the match(es) for
+ the <parameter>query</parameter> in
+ the <parameter>document</parameter>, which must be raw text not
+ a <type>tsvector</type>. Words in the document are normalized
+ according to the specified or default configuration before matching to
+ the query. Use of this function is discussed in
+ <xref linkend="textsearch-headline"/>, which also describes the
+ available <parameter>options</parameter>.
+ </para>
+ <para>
+ <literal>ts_headline('The fat cat ate the rat.', 'cat')</literal>
+ <returnvalue>The fat &lt;b&gt;cat&lt;/b&gt; ate the rat.</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>ts_headline</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>json</type>,
+ <parameter>query</parameter> <type>tsquery</type>
+ <optional>, <parameter>options</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>ts_headline</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>jsonb</type>,
+ <parameter>query</parameter> <type>tsquery</type>
+ <optional>, <parameter>options</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Displays, in an abbreviated form, match(es) for
+ the <parameter>query</parameter> that occur in string values
+ within the JSON <parameter>document</parameter>.
+ See <xref linkend="textsearch-headline"/> for more details.
+ </para>
+ <para>
+ <literal>ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat')</literal>
+ <returnvalue>{"cat": "raining &lt;b&gt;cats&lt;/b&gt; and dogs"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_rank</primary>
+ </indexterm>
+ <function>ts_rank</function> (
+ <optional> <parameter>weights</parameter> <type>real[]</type>, </optional>
+ <parameter>vector</parameter> <type>tsvector</type>,
+ <parameter>query</parameter> <type>tsquery</type>
+ <optional>, <parameter>normalization</parameter> <type>integer</type> </optional> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Computes a score showing how well
+ the <parameter>vector</parameter> matches
+ the <parameter>query</parameter>. See
+ <xref linkend="textsearch-ranking"/> for details.
+ </para>
+ <para>
+ <literal>ts_rank(to_tsvector('raining cats and dogs'), 'cat')</literal>
+ <returnvalue>0.06079271</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_rank_cd</primary>
+ </indexterm>
+ <function>ts_rank_cd</function> (
+ <optional> <parameter>weights</parameter> <type>real[]</type>, </optional>
+ <parameter>vector</parameter> <type>tsvector</type>,
+ <parameter>query</parameter> <type>tsquery</type>
+ <optional>, <parameter>normalization</parameter> <type>integer</type> </optional> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Computes a score showing how well
+ the <parameter>vector</parameter> matches
+ the <parameter>query</parameter>, using a cover density
+ algorithm. See <xref linkend="textsearch-ranking"/> for details.
+ </para>
+ <para>
+ <literal>ts_rank_cd(to_tsvector('raining cats and dogs'), 'cat')</literal>
+ <returnvalue>0.1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_rewrite</primary>
+ </indexterm>
+ <function>ts_rewrite</function> ( <parameter>query</parameter> <type>tsquery</type>,
+ <parameter>target</parameter> <type>tsquery</type>,
+ <parameter>substitute</parameter> <type>tsquery</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Replaces occurrences of <parameter>target</parameter>
+ with <parameter>substitute</parameter>
+ within the <parameter>query</parameter>.
+ See <xref linkend="textsearch-query-rewriting"/> for details.
+ </para>
+ <para>
+ <literal>ts_rewrite('a &amp; b'::tsquery, 'a'::tsquery, 'foo|bar'::tsquery)</literal>
+ <returnvalue>'b' &amp; ( 'foo' | 'bar' )</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>ts_rewrite</function> ( <parameter>query</parameter> <type>tsquery</type>,
+ <parameter>select</parameter> <type>text</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Replaces portions of the <parameter>query</parameter> according to
+ target(s) and substitute(s) obtained by executing
+ a <command>SELECT</command> command.
+ See <xref linkend="textsearch-query-rewriting"/> for details.
+ </para>
+ <para>
+ <literal>SELECT ts_rewrite('a &amp; b'::tsquery, 'SELECT t,s FROM aliases')</literal>
+ <returnvalue>'b' &amp; ( 'foo' | 'bar' )</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tsquery_phrase</primary>
+ </indexterm>
+ <function>tsquery_phrase</function> ( <parameter>query1</parameter> <type>tsquery</type>, <parameter>query2</parameter> <type>tsquery</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Constructs a phrase query that searches
+ for matches of <parameter>query1</parameter>
+ and <parameter>query2</parameter> at successive lexemes (same
+ as <literal>&lt;-&gt;</literal> operator).
+ </para>
+ <para>
+ <literal>tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'))</literal>
+ <returnvalue>'fat' &lt;-&gt; 'cat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>tsquery_phrase</function> ( <parameter>query1</parameter> <type>tsquery</type>, <parameter>query2</parameter> <type>tsquery</type>, <parameter>distance</parameter> <type>integer</type> )
+ <returnvalue>tsquery</returnvalue>
+ </para>
+ <para>
+ Constructs a phrase query that searches
+ for matches of <parameter>query1</parameter> and
+ <parameter>query2</parameter> that occur exactly
+ <parameter>distance</parameter> lexemes apart.
+ </para>
+ <para>
+ <literal>tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10)</literal>
+ <returnvalue>'fat' &lt;10&gt; 'cat'</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tsvector_to_array</primary>
+ </indexterm>
+ <function>tsvector_to_array</function> ( <type>tsvector</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Converts a <type>tsvector</type> to an array of lexemes.
+ </para>
+ <para>
+ <literal>tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector)</literal>
+ <returnvalue>{cat,fat,rat}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>unnest</primary>
+ <secondary>for tsvector</secondary>
+ </indexterm>
+ <function>unnest</function> ( <type>tsvector</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>lexeme</parameter> <type>text</type>,
+ <parameter>positions</parameter> <type>smallint[]</type>,
+ <parameter>weights</parameter> <type>text</type> )
+ </para>
+ <para>
+ Expands a <type>tsvector</type> into a set of rows, one per lexeme.
+ </para>
+ <para>
+ <literal>select * from unnest('cat:3 fat:2,4 rat:5A'::tsvector)</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ lexeme | positions | weights
+--------+-----------+---------
+ cat | {3} | {D}
+ fat | {2,4} | {D,D}
+ rat | {5} | {A}
+</programlisting>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ All the text search functions that accept an optional <type>regconfig</type>
+ argument will use the configuration specified by
+ <xref linkend="guc-default-text-search-config"/>
+ when that argument is omitted.
+ </para>
+ </note>
+
+ <para>
+ The functions in
+ <xref linkend="textsearch-functions-debug-table"/>
+ are listed separately because they are not usually used in everyday text
+ searching operations. They are primarily helpful for development and
+ debugging of new text search configurations.
+ </para>
+
+ <table id="textsearch-functions-debug-table">
+ <title>Text Search Debugging Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_debug</primary>
+ </indexterm>
+ <function>ts_debug</function> (
+ <optional> <parameter>config</parameter> <type>regconfig</type>, </optional>
+ <parameter>document</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>alias</parameter> <type>text</type>,
+ <parameter>description</parameter> <type>text</type>,
+ <parameter>token</parameter> <type>text</type>,
+ <parameter>dictionaries</parameter> <type>regdictionary[]</type>,
+ <parameter>dictionary</parameter> <type>regdictionary</type>,
+ <parameter>lexemes</parameter> <type>text[]</type> )
+ </para>
+ <para>
+ Extracts and normalizes tokens from
+ the <parameter>document</parameter> according to the specified or
+ default text search configuration, and returns information about how
+ each token was processed.
+ See <xref linkend="textsearch-configuration-testing"/> for details.
+ </para>
+ <para>
+ <literal>ts_debug('english', 'The Brightest supernovaes')</literal>
+ <returnvalue>(asciiword,"Word, all ASCII",The,{english_stem},english_stem,{}) ...</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_lexize</primary>
+ </indexterm>
+ <function>ts_lexize</function> ( <parameter>dict</parameter> <type>regdictionary</type>, <parameter>token</parameter> <type>text</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of replacement lexemes if the input token is known to
+ the dictionary, or an empty array if the token is known to the
+ dictionary but it is a stop word, or NULL if it is not a known word.
+ See <xref linkend="textsearch-dictionary-testing"/> for details.
+ </para>
+ <para>
+ <literal>ts_lexize('english_stem', 'stars')</literal>
+ <returnvalue>{star}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_parse</primary>
+ </indexterm>
+ <function>ts_parse</function> ( <parameter>parser_name</parameter> <type>text</type>,
+ <parameter>document</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>tokid</parameter> <type>integer</type>,
+ <parameter>token</parameter> <type>text</type> )
+ </para>
+ <para>
+ Extracts tokens from the <parameter>document</parameter> using the
+ named parser.
+ See <xref linkend="textsearch-parser-testing"/> for details.
+ </para>
+ <para>
+ <literal>ts_parse('default', 'foo - bar')</literal>
+ <returnvalue>(1,foo) ...</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>ts_parse</function> ( <parameter>parser_oid</parameter> <type>oid</type>,
+ <parameter>document</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>tokid</parameter> <type>integer</type>,
+ <parameter>token</parameter> <type>text</type> )
+ </para>
+ <para>
+ Extracts tokens from the <parameter>document</parameter> using a
+ parser specified by OID.
+ See <xref linkend="textsearch-parser-testing"/> for details.
+ </para>
+ <para>
+ <literal>ts_parse(3722, 'foo - bar')</literal>
+ <returnvalue>(1,foo) ...</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_token_type</primary>
+ </indexterm>
+ <function>ts_token_type</function> ( <parameter>parser_name</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>tokid</parameter> <type>integer</type>,
+ <parameter>alias</parameter> <type>text</type>,
+ <parameter>description</parameter> <type>text</type> )
+ </para>
+ <para>
+ Returns a table that describes each type of token the named parser can
+ recognize.
+ See <xref linkend="textsearch-parser-testing"/> for details.
+ </para>
+ <para>
+ <literal>ts_token_type('default')</literal>
+ <returnvalue>(1,asciiword,"Word, all ASCII") ...</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>ts_token_type</function> ( <parameter>parser_oid</parameter> <type>oid</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>tokid</parameter> <type>integer</type>,
+ <parameter>alias</parameter> <type>text</type>,
+ <parameter>description</parameter> <type>text</type> )
+ </para>
+ <para>
+ Returns a table that describes each type of token a parser specified
+ by OID can recognize.
+ See <xref linkend="textsearch-parser-testing"/> for details.
+ </para>
+ <para>
+ <literal>ts_token_type(3722)</literal>
+ <returnvalue>(1,asciiword,"Word, all ASCII") ...</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ts_stat</primary>
+ </indexterm>
+ <function>ts_stat</function> ( <parameter>sqlquery</parameter> <type>text</type>
+ <optional>, <parameter>weights</parameter> <type>text</type> </optional> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>word</parameter> <type>text</type>,
+ <parameter>ndoc</parameter> <type>integer</type>,
+ <parameter>nentry</parameter> <type>integer</type> )
+ </para>
+ <para>
+ Executes the <parameter>sqlquery</parameter>, which must return a
+ single <type>tsvector</type> column, and returns statistics about each
+ distinct lexeme contained in the data.
+ See <xref linkend="textsearch-statistics"/> for details.
+ </para>
+ <para>
+ <literal>ts_stat('SELECT vector FROM apod')</literal>
+ <returnvalue>(foo,10,15) ...</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="functions-uuid">
+ <title>UUID Functions</title>
+
+ <indexterm zone="datatype-uuid">
+ <primary>UUID</primary>
+ <secondary>generating</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>gen_random_uuid</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> includes one function to generate a UUID:
+<synopsis>
+<function>gen_random_uuid</function> () <returnvalue>uuid</returnvalue>
+</synopsis>
+ This function returns a version 4 (random) UUID. This is the most commonly
+ used type of UUID and is appropriate for most applications.
+ </para>
+
+ <para>
+ The <xref linkend="uuid-ossp"/> module provides additional functions that
+ implement other standard algorithms for generating UUIDs.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> also provides the usual comparison
+ operators shown in <xref linkend="functions-comparison-op-table"/> for
+ UUIDs.
+ </para>
+ </sect1>
+
+ <sect1 id="functions-xml">
+
+ <title>XML Functions</title>
+
+ <indexterm>
+ <primary>XML Functions</primary>
+ </indexterm>
+
+ <para>
+ The functions and function-like expressions described in this
+ section operate on values of type <type>xml</type>. See <xref
+ linkend="datatype-xml"/> for information about the <type>xml</type>
+ type. The function-like expressions <function>xmlparse</function>
+ and <function>xmlserialize</function> for converting to and from
+ type <type>xml</type> are documented there, not in this section.
+ </para>
+
+ <para>
+ Use of most of these functions
+ requires <productname>PostgreSQL</productname> to have been built
+ with <command>configure --with-libxml</command>.
+ </para>
+
+ <sect2 id="functions-producing-xml">
+ <title>Producing XML Content</title>
+
+ <para>
+ A set of functions and function-like expressions is available for
+ producing XML content from SQL data. As such, they are
+ particularly suitable for formatting query results into XML
+ documents for processing in client applications.
+ </para>
+
+ <sect3>
+ <title><literal>xmlcomment</literal></title>
+
+ <indexterm>
+ <primary>xmlcomment</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlcomment</function> ( <type>text</type> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The function <function>xmlcomment</function> creates an XML value
+ containing an XML comment with the specified text as content.
+ The text cannot contain <quote><literal>--</literal></quote> or end with a
+ <quote><literal>-</literal></quote>, otherwise the resulting construct
+ would not be a valid XML comment.
+ If the argument is null, the result is null.
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlcomment('hello');
+
+ xmlcomment
+--------------
+ <!--hello-->
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlconcat</literal></title>
+
+ <indexterm>
+ <primary>xmlconcat</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlconcat</function> ( <type>xml</type> <optional>, ...</optional> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The function <function>xmlconcat</function> concatenates a list
+ of individual XML values to create a single value containing an
+ XML content fragment. Null values are omitted; the result is
+ only null if there are no nonnull arguments.
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlconcat('<abc/>', '<bar>foo</bar>');
+
+ xmlconcat
+----------------------
+ <abc/><bar>foo</bar>
+]]></screen>
+ </para>
+
+ <para>
+ XML declarations, if present, are combined as follows. If all
+ argument values have the same XML version declaration, that
+ version is used in the result, else no version is used. If all
+ argument values have the standalone declaration value
+ <quote>yes</quote>, then that value is used in the result. If
+ all argument values have a standalone declaration value and at
+ least one is <quote>no</quote>, then that is used in the result.
+ Else the result will have no standalone declaration. If the
+ result is determined to require a standalone declaration but no
+ version declaration, a version declaration with version 1.0 will
+ be used because XML requires an XML declaration to contain a
+ version declaration. Encoding declarations are ignored and
+ removed in all cases.
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlconcat('<?xml version="1.1"?><foo/>', '<?xml version="1.1" standalone="no"?><bar/>');
+
+ xmlconcat
+-----------------------------------
+ <?xml version="1.1"?><foo/><bar/>
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlelement</literal></title>
+
+ <indexterm>
+ <primary>xmlelement</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlelement</function> ( <literal>NAME</literal> <replaceable>name</replaceable> <optional>, <literal>XMLATTRIBUTES</literal> ( <replaceable>attvalue</replaceable> <optional> <literal>AS</literal> <replaceable>attname</replaceable> </optional> <optional>, ...</optional> ) </optional> <optional>, <replaceable>content</replaceable> <optional>, ...</optional></optional> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The <function>xmlelement</function> expression produces an XML
+ element with the given name, attributes, and content.
+ The <replaceable>name</replaceable>
+ and <replaceable>attname</replaceable> items shown in the syntax are
+ simple identifiers, not values. The <replaceable>attvalue</replaceable>
+ and <replaceable>content</replaceable> items are expressions, which can
+ yield any <productname>PostgreSQL</productname> data type. The
+ argument(s) within <literal>XMLATTRIBUTES</literal> generate attributes
+ of the XML element; the <replaceable>content</replaceable> value(s) are
+ concatenated to form its content.
+ </para>
+
+ <para>
+ Examples:
+<screen><![CDATA[
+SELECT xmlelement(name foo);
+
+ xmlelement
+------------
+ <foo/>
+
+SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
+
+ xmlelement
+------------------
+ <foo bar="xyz"/>
+
+SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
+
+ xmlelement
+-------------------------------------
+ <foo bar="2007-01-26">content</foo>
+]]></screen>
+ </para>
+
+ <para>
+ Element and attribute names that are not valid XML names are
+ escaped by replacing the offending characters by the sequence
+ <literal>_x<replaceable>HHHH</replaceable>_</literal>, where
+ <replaceable>HHHH</replaceable> is the character's Unicode
+ codepoint in hexadecimal notation. For example:
+<screen><![CDATA[
+SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&b"));
+
+ xmlelement
+----------------------------------
+ <foo_x0024_bar a_x0026_b="xyz"/>
+]]></screen>
+ </para>
+
+ <para>
+ An explicit attribute name need not be specified if the attribute
+ value is a column reference, in which case the column's name will
+ be used as the attribute name by default. In other cases, the
+ attribute must be given an explicit name. So this example is
+ valid:
+<screen>
+CREATE TABLE test (a xml, b xml);
+SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
+</screen>
+ But these are not:
+<screen>
+SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
+SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
+</screen>
+ </para>
+
+ <para>
+ Element content, if specified, will be formatted according to
+ its data type. If the content is itself of type <type>xml</type>,
+ complex XML documents can be constructed. For example:
+<screen><![CDATA[
+SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
+ xmlelement(name abc),
+ xmlcomment('test'),
+ xmlelement(name xyz));
+
+ xmlelement
+----------------------------------------------
+ <foo bar="xyz"><abc/><!--test--><xyz/></foo>
+]]></screen>
+
+ Content of other types will be formatted into valid XML character
+ data. This means in particular that the characters &lt;, &gt;,
+ and &amp; will be converted to entities. Binary data (data type
+ <type>bytea</type>) will be represented in base64 or hex
+ encoding, depending on the setting of the configuration parameter
+ <xref linkend="guc-xmlbinary"/>. The particular behavior for
+ individual data types is expected to evolve in order to align the
+ PostgreSQL mappings with those specified in SQL:2006 and later,
+ as discussed in <xref linkend="functions-xml-limits-casts"/>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlforest</literal></title>
+
+ <indexterm>
+ <primary>xmlforest</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlforest</function> ( <replaceable>content</replaceable> <optional> <literal>AS</literal> <replaceable>name</replaceable> </optional> <optional>, ...</optional> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The <function>xmlforest</function> expression produces an XML
+ forest (sequence) of elements using the given names and content.
+ As for <function>xmlelement</function>,
+ each <replaceable>name</replaceable> must be a simple identifier, while
+ the <replaceable>content</replaceable> expressions can have any data
+ type.
+ </para>
+
+ <para>
+ Examples:
+<screen>
+SELECT xmlforest('abc' AS foo, 123 AS bar);
+
+ xmlforest
+------------------------------
+ &lt;foo&gt;abc&lt;/foo&gt;&lt;bar&gt;123&lt;/bar&gt;
+
+
+SELECT xmlforest(table_name, column_name)
+FROM information_schema.columns
+WHERE table_schema = 'pg_catalog';
+
+ xmlforest
+------------------------------------&zwsp;-----------------------------------
+ &lt;table_name&gt;pg_authid&lt;/table_name&gt;&zwsp;&lt;column_name&gt;rolname&lt;/column_name&gt;
+ &lt;table_name&gt;pg_authid&lt;/table_name&gt;&zwsp;&lt;column_name&gt;rolsuper&lt;/column_name&gt;
+ ...
+</screen>
+
+ As seen in the second example, the element name can be omitted if
+ the content value is a column reference, in which case the column
+ name is used by default. Otherwise, a name must be specified.
+ </para>
+
+ <para>
+ Element names that are not valid XML names are escaped as shown
+ for <function>xmlelement</function> above. Similarly, content
+ data is escaped to make valid XML content, unless it is already
+ of type <type>xml</type>.
+ </para>
+
+ <para>
+ Note that XML forests are not valid XML documents if they consist
+ of more than one element, so it might be useful to wrap
+ <function>xmlforest</function> expressions in
+ <function>xmlelement</function>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlpi</literal></title>
+
+ <indexterm>
+ <primary>xmlpi</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlpi</function> ( <literal>NAME</literal> <replaceable>name</replaceable> <optional>, <replaceable>content</replaceable> </optional> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The <function>xmlpi</function> expression creates an XML
+ processing instruction.
+ As for <function>xmlelement</function>,
+ the <replaceable>name</replaceable> must be a simple identifier, while
+ the <replaceable>content</replaceable> expression can have any data type.
+ The <replaceable>content</replaceable>, if present, must not contain the
+ character sequence <literal>?&gt;</literal>.
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xmlpi(name php, 'echo "hello world";');
+
+ xmlpi
+-----------------------------
+ <?php echo "hello world";?>
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>xmlroot</literal></title>
+
+ <indexterm>
+ <primary>xmlroot</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlroot</function> ( <type>xml</type>, <literal>VERSION</literal> {<type>text</type>|<literal>NO VALUE</literal>} <optional>, <literal>STANDALONE</literal> {<literal>YES</literal>|<literal>NO</literal>|<literal>NO VALUE</literal>} </optional> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The <function>xmlroot</function> expression alters the properties
+ of the root node of an XML value. If a version is specified,
+ it replaces the value in the root node's version declaration; if a
+ standalone setting is specified, it replaces the value in the
+ root node's standalone declaration.
+ </para>
+
+ <para>
+<screen><![CDATA[
+SELECT xmlroot(xmlparse(document '<?xml version="1.1"?><content>abc</content>'),
+ version '1.0', standalone yes);
+
+ xmlroot
+----------------------------------------
+ <?xml version="1.0" standalone="yes"?>
+ <content>abc</content>
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3 id="functions-xml-xmlagg">
+ <title><literal>xmlagg</literal></title>
+
+ <indexterm>
+ <primary>xmlagg</primary>
+ </indexterm>
+
+<synopsis>
+<function>xmlagg</function> ( <type>xml</type> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ <para>
+ The function <function>xmlagg</function> is, unlike the other
+ functions described here, an aggregate function. It concatenates the
+ input values to the aggregate function call,
+ much like <function>xmlconcat</function> does, except that concatenation
+ occurs across rows rather than across expressions in a single row.
+ See <xref linkend="functions-aggregate"/> for additional information
+ about aggregate functions.
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+CREATE TABLE test (y int, x xml);
+INSERT INTO test VALUES (1, '<foo>abc</foo>');
+INSERT INTO test VALUES (2, '<bar/>');
+SELECT xmlagg(x) FROM test;
+ xmlagg
+----------------------
+ <foo>abc</foo><bar/>
+]]></screen>
+ </para>
+
+ <para>
+ To determine the order of the concatenation, an <literal>ORDER BY</literal>
+ clause may be added to the aggregate call as described in
+ <xref linkend="syntax-aggregates"/>. For example:
+
+<screen><![CDATA[
+SELECT xmlagg(x ORDER BY y DESC) FROM test;
+ xmlagg
+----------------------
+ <bar/><foo>abc</foo>
+]]></screen>
+ </para>
+
+ <para>
+ The following non-standard approach used to be recommended
+ in previous versions, and may still be useful in specific
+ cases:
+
+<screen><![CDATA[
+SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
+ xmlagg
+----------------------
+ <bar/><foo>abc</foo>
+]]></screen>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="functions-xml-predicates">
+ <title>XML Predicates</title>
+
+ <para>
+ The expressions described in this section check properties
+ of <type>xml</type> values.
+ </para>
+
+ <sect3>
+ <title><literal>IS DOCUMENT</literal></title>
+
+ <indexterm>
+ <primary>IS DOCUMENT</primary>
+ </indexterm>
+
+<synopsis>
+<type>xml</type> <literal>IS DOCUMENT</literal> <returnvalue>boolean</returnvalue>
+</synopsis>
+
+ <para>
+ The expression <literal>IS DOCUMENT</literal> returns true if the
+ argument XML value is a proper XML document, false if it is not
+ (that is, it is a content fragment), or null if the argument is
+ null. See <xref linkend="datatype-xml"/> about the difference
+ between documents and content fragments.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>IS NOT DOCUMENT</literal></title>
+
+ <indexterm>
+ <primary>IS NOT DOCUMENT</primary>
+ </indexterm>
+
+<synopsis>
+<type>xml</type> <literal>IS NOT DOCUMENT</literal> <returnvalue>boolean</returnvalue>
+</synopsis>
+
+ <para>
+ The expression <literal>IS NOT DOCUMENT</literal> returns false if the
+ argument XML value is a proper XML document, true if it is not (that is,
+ it is a content fragment), or null if the argument is null.
+ </para>
+ </sect3>
+
+ <sect3 id="xml-exists">
+ <title><literal>XMLEXISTS</literal></title>
+
+ <indexterm>
+ <primary>XMLEXISTS</primary>
+ </indexterm>
+
+<synopsis>
+<function>XMLEXISTS</function> ( <type>text</type> <literal>PASSING</literal> <optional><literal>BY</literal> {<literal>REF</literal>|<literal>VALUE</literal>}</optional> <type>xml</type> <optional><literal>BY</literal> {<literal>REF</literal>|<literal>VALUE</literal>}</optional> ) <returnvalue>boolean</returnvalue>
+</synopsis>
+
+ <para>
+ The function <function>xmlexists</function> evaluates an XPath 1.0
+ expression (the first argument), with the passed XML value as its context
+ item. The function returns false if the result of that evaluation
+ yields an empty node-set, true if it yields any other value. The
+ function returns null if any argument is null. A nonnull value
+ passed as the context item must be an XML document, not a content
+ fragment or any non-XML value.
+ </para>
+
+ <para>
+ Example:
+ <screen><![CDATA[
+SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '<towns><town>Toronto</town><town>Ottawa</town></towns>');
+
+ xmlexists
+------------
+ t
+(1 row)
+]]></screen>
+ </para>
+
+ <para>
+ The <literal>BY REF</literal> and <literal>BY VALUE</literal> clauses
+ are accepted in <productname>PostgreSQL</productname>, but are ignored,
+ as discussed in <xref linkend="functions-xml-limits-postgresql"/>.
+ </para>
+
+ <para>
+ In the SQL standard, the <function>xmlexists</function> function
+ evaluates an expression in the XML Query language,
+ but <productname>PostgreSQL</productname> allows only an XPath 1.0
+ expression, as discussed in
+ <xref linkend="functions-xml-limits-xpath1"/>.
+ </para>
+ </sect3>
+
+ <sect3 id="xml-is-well-formed">
+ <title><literal>xml_is_well_formed</literal></title>
+
+ <indexterm>
+ <primary>xml_is_well_formed</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>xml_is_well_formed_document</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>xml_is_well_formed_content</primary>
+ </indexterm>
+
+<synopsis>
+<function>xml_is_well_formed</function> ( <type>text</type> ) <returnvalue>boolean</returnvalue>
+<function>xml_is_well_formed_document</function> ( <type>text</type> ) <returnvalue>boolean</returnvalue>
+<function>xml_is_well_formed_content</function> ( <type>text</type> ) <returnvalue>boolean</returnvalue>
+</synopsis>
+
+ <para>
+ These functions check whether a <type>text</type> string represents
+ well-formed XML, returning a Boolean result.
+ <function>xml_is_well_formed_document</function> checks for a well-formed
+ document, while <function>xml_is_well_formed_content</function> checks
+ for well-formed content. <function>xml_is_well_formed</function> does
+ the former if the <xref linkend="guc-xmloption"/> configuration
+ parameter is set to <literal>DOCUMENT</literal>, or the latter if it is set to
+ <literal>CONTENT</literal>. This means that
+ <function>xml_is_well_formed</function> is useful for seeing whether
+ a simple cast to type <type>xml</type> will succeed, whereas the other two
+ functions are useful for seeing whether the corresponding variants of
+ <function>XMLPARSE</function> will succeed.
+ </para>
+
+ <para>
+ Examples:
+
+<screen><![CDATA[
+SET xmloption TO DOCUMENT;
+SELECT xml_is_well_formed('<>');
+ xml_is_well_formed
+--------------------
+ f
+(1 row)
+
+SELECT xml_is_well_formed('<abc/>');
+ xml_is_well_formed
+--------------------
+ t
+(1 row)
+
+SET xmloption TO CONTENT;
+SELECT xml_is_well_formed('abc');
+ xml_is_well_formed
+--------------------
+ t
+(1 row)
+
+SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</pg:foo>');
+ xml_is_well_formed_document
+-----------------------------
+ t
+(1 row)
+
+SELECT xml_is_well_formed_document('<pg:foo xmlns:pg="http://postgresql.org/stuff">bar</my:foo>');
+ xml_is_well_formed_document
+-----------------------------
+ f
+(1 row)
+]]></screen>
+
+ The last example shows that the checks include whether
+ namespaces are correctly matched.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="functions-xml-processing">
+ <title>Processing XML</title>
+
+ <para>
+ To process values of data type <type>xml</type>, PostgreSQL offers
+ the functions <function>xpath</function> and
+ <function>xpath_exists</function>, which evaluate XPath 1.0
+ expressions, and the <function>XMLTABLE</function>
+ table function.
+ </para>
+
+ <sect3 id="functions-xml-processing-xpath">
+ <title><literal>xpath</literal></title>
+
+ <indexterm>
+ <primary>XPath</primary>
+ </indexterm>
+
+<synopsis>
+<function>xpath</function> ( <parameter>xpath</parameter> <type>text</type>, <parameter>xml</parameter> <type>xml</type> <optional>, <parameter>nsarray</parameter> <type>text[]</type> </optional> ) <returnvalue>xml[]</returnvalue>
+</synopsis>
+
+ <para>
+ The function <function>xpath</function> evaluates the XPath 1.0
+ expression <parameter>xpath</parameter> (given as text)
+ against the XML value
+ <parameter>xml</parameter>. It returns an array of XML values
+ corresponding to the node-set produced by the XPath expression.
+ If the XPath expression returns a scalar value rather than a node-set,
+ a single-element array is returned.
+ </para>
+
+ <para>
+ The second argument must be a well formed XML document. In particular,
+ it must have a single root node element.
+ </para>
+
+ <para>
+ The optional third argument of the function is an array of namespace
+ mappings. This array should be a two-dimensional <type>text</type> array with
+ the length of the second axis being equal to 2 (i.e., it should be an
+ array of arrays, each of which consists of exactly 2 elements).
+ The first element of each array entry is the namespace name (alias), the
+ second the namespace URI. It is not required that aliases provided in
+ this array be the same as those being used in the XML document itself (in
+ other words, both in the XML document and in the <function>xpath</function>
+ function context, aliases are <emphasis>local</emphasis>).
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xpath('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
+ ARRAY[ARRAY['my', 'http://example.com']]);
+
+ xpath
+--------
+ {test}
+(1 row)
+]]></screen>
+ </para>
+
+ <para>
+ To deal with default (anonymous) namespaces, do something like this:
+<screen><![CDATA[
+SELECT xpath('//mydefns:b/text()', '<a xmlns="http://example.com"><b>test</b></a>',
+ ARRAY[ARRAY['mydefns', 'http://example.com']]);
+
+ xpath
+--------
+ {test}
+(1 row)
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3 id="functions-xml-processing-xpath-exists">
+ <title><literal>xpath_exists</literal></title>
+
+ <indexterm>
+ <primary>xpath_exists</primary>
+ </indexterm>
+
+<synopsis>
+<function>xpath_exists</function> ( <parameter>xpath</parameter> <type>text</type>, <parameter>xml</parameter> <type>xml</type> <optional>, <parameter>nsarray</parameter> <type>text[]</type> </optional> ) <returnvalue>boolean</returnvalue>
+</synopsis>
+
+ <para>
+ The function <function>xpath_exists</function> is a specialized form
+ of the <function>xpath</function> function. Instead of returning the
+ individual XML values that satisfy the XPath 1.0 expression, this function
+ returns a Boolean indicating whether the query was satisfied or not
+ (specifically, whether it produced any value other than an empty node-set).
+ This function is equivalent to the <literal>XMLEXISTS</literal> predicate,
+ except that it also offers support for a namespace mapping argument.
+ </para>
+
+ <para>
+ Example:
+<screen><![CDATA[
+SELECT xpath_exists('/my:a/text()', '<my:a xmlns:my="http://example.com">test</my:a>',
+ ARRAY[ARRAY['my', 'http://example.com']]);
+
+ xpath_exists
+--------------
+ t
+(1 row)
+]]></screen>
+ </para>
+ </sect3>
+
+ <sect3 id="functions-xml-processing-xmltable">
+ <title><literal>xmltable</literal></title>
+
+ <indexterm>
+ <primary>xmltable</primary>
+ </indexterm>
+
+ <indexterm zone="functions-xml-processing-xmltable">
+ <primary>table function</primary>
+ <secondary>XMLTABLE</secondary>
+ </indexterm>
+
+<synopsis>
+<function>XMLTABLE</function> (
+ <optional> <literal>XMLNAMESPACES</literal> ( <replaceable>namespace_uri</replaceable> <literal>AS</literal> <replaceable>namespace_name</replaceable> <optional>, ...</optional> ), </optional>
+ <replaceable>row_expression</replaceable> <literal>PASSING</literal> <optional><literal>BY</literal> {<literal>REF</literal>|<literal>VALUE</literal>}</optional> <replaceable>document_expression</replaceable> <optional><literal>BY</literal> {<literal>REF</literal>|<literal>VALUE</literal>}</optional>
+ <literal>COLUMNS</literal> <replaceable>name</replaceable> { <replaceable>type</replaceable> <optional><literal>PATH</literal> <replaceable>column_expression</replaceable></optional> <optional><literal>DEFAULT</literal> <replaceable>default_expression</replaceable></optional> <optional><literal>NOT NULL</literal> | <literal>NULL</literal></optional>
+ | <literal>FOR ORDINALITY</literal> }
+ <optional>, ...</optional>
+) <returnvalue>setof record</returnvalue>
+</synopsis>
+
+ <para>
+ The <function>xmltable</function> expression produces a table based
+ on an XML value, an XPath filter to extract rows, and a
+ set of column definitions.
+ Although it syntactically resembles a function, it can only appear
+ as a table in a query's <literal>FROM</literal> clause.
+ </para>
+
+ <para>
+ The optional <literal>XMLNAMESPACES</literal> clause gives a
+ comma-separated list of namespace definitions, where
+ each <replaceable>namespace_uri</replaceable> is a <type>text</type>
+ expression and each <replaceable>namespace_name</replaceable> is a simple
+ identifier. It specifies the XML namespaces used in the document and
+ their aliases. A default namespace specification is not currently
+ supported.
+ </para>
+
+ <para>
+ The required <replaceable>row_expression</replaceable> argument is an
+ XPath 1.0 expression (given as <type>text</type>) that is evaluated,
+ passing the XML value <replaceable>document_expression</replaceable> as
+ its context item, to obtain a set of XML nodes. These nodes are what
+ <function>xmltable</function> transforms into output rows. No rows
+ will be produced if the <replaceable>document_expression</replaceable>
+ is null, nor if the <replaceable>row_expression</replaceable> produces
+ an empty node-set or any value other than a node-set.
+ </para>
+
+ <para>
+ <replaceable>document_expression</replaceable> provides the context
+ item for the <replaceable>row_expression</replaceable>. It must be a
+ well-formed XML document; fragments/forests are not accepted.
+ The <literal>BY REF</literal> and <literal>BY VALUE</literal> clauses
+ are accepted but ignored, as discussed in
+ <xref linkend="functions-xml-limits-postgresql"/>.
+ </para>
+
+ <para>
+ In the SQL standard, the <function>xmltable</function> function
+ evaluates expressions in the XML Query language,
+ but <productname>PostgreSQL</productname> allows only XPath 1.0
+ expressions, as discussed in
+ <xref linkend="functions-xml-limits-xpath1"/>.
+ </para>
+
+ <para>
+ The required <literal>COLUMNS</literal> clause specifies the
+ column(s) that will be produced in the output table.
+ See the syntax summary above for the format.
+ A name is required for each column, as is a data type
+ (unless <literal>FOR ORDINALITY</literal> is specified, in which case
+ type <type>integer</type> is implicit). The path, default and
+ nullability clauses are optional.
+ </para>
+
+ <para>
+ A column marked <literal>FOR ORDINALITY</literal> will be populated
+ with row numbers, starting with 1, in the order of nodes retrieved from
+ the <replaceable>row_expression</replaceable>'s result node-set.
+ At most one column may be marked <literal>FOR ORDINALITY</literal>.
+ </para>
+
+ <note>
+ <para>
+ XPath 1.0 does not specify an order for nodes in a node-set, so code
+ that relies on a particular order of the results will be
+ implementation-dependent. Details can be found in
+ <xref linkend="xml-xpath-1-specifics"/>.
+ </para>
+ </note>
+
+ <para>
+ The <replaceable>column_expression</replaceable> for a column is an
+ XPath 1.0 expression that is evaluated for each row, with the current
+ node from the <replaceable>row_expression</replaceable> result as its
+ context item, to find the value of the column. If
+ no <replaceable>column_expression</replaceable> is given, then the
+ column name is used as an implicit path.
+ </para>
+
+ <para>
+ If a column's XPath expression returns a non-XML value (which is limited
+ to string, boolean, or double in XPath 1.0) and the column has a
+ PostgreSQL type other than <type>xml</type>, the column will be set
+ as if by assigning the value's string representation to the PostgreSQL
+ type. (If the value is a boolean, its string representation is taken
+ to be <literal>1</literal> or <literal>0</literal> if the output
+ column's type category is numeric, otherwise <literal>true</literal> or
+ <literal>false</literal>.)
+ </para>
+
+ <para>
+ If a column's XPath expression returns a non-empty set of XML nodes
+ and the column's PostgreSQL type is <type>xml</type>, the column will
+ be assigned the expression result exactly, if it is of document or
+ content form.
+ <footnote>
+ <para>
+ A result containing more than one element node at the top level, or
+ non-whitespace text outside of an element, is an example of content form.
+ An XPath result can be of neither form, for example if it returns an
+ attribute node selected from the element that contains it. Such a result
+ will be put into content form with each such disallowed node replaced by
+ its string value, as defined for the XPath 1.0
+ <function>string</function> function.
+ </para>
+ </footnote>
+ </para>
+
+ <para>
+ A non-XML result assigned to an <type>xml</type> output column produces
+ content, a single text node with the string value of the result.
+ An XML result assigned to a column of any other type may not have more than
+ one node, or an error is raised. If there is exactly one node, the column
+ will be set as if by assigning the node's string
+ value (as defined for the XPath 1.0 <function>string</function> function)
+ to the PostgreSQL type.
+ </para>
+
+ <para>
+ The string value of an XML element is the concatenation, in document order,
+ of all text nodes contained in that element and its descendants. The string
+ value of an element with no descendant text nodes is an
+ empty string (not <literal>NULL</literal>).
+ Any <literal>xsi:nil</literal> attributes are ignored.
+ Note that the whitespace-only <literal>text()</literal> node between two non-text
+ elements is preserved, and that leading whitespace on a <literal>text()</literal>
+ node is not flattened.
+ The XPath 1.0 <function>string</function> function may be consulted for the
+ rules defining the string value of other XML node types and non-XML values.
+ </para>
+
+ <para>
+ The conversion rules presented here are not exactly those of the SQL
+ standard, as discussed in <xref linkend="functions-xml-limits-casts"/>.
+ </para>
+
+ <para>
+ If the path expression returns an empty node-set
+ (typically, when it does not match)
+ for a given row, the column will be set to <literal>NULL</literal>, unless
+ a <replaceable>default_expression</replaceable> is specified; then the
+ value resulting from evaluating that expression is used.
+ </para>
+
+ <para>
+ A <replaceable>default_expression</replaceable>, rather than being
+ evaluated immediately when <function>xmltable</function> is called,
+ is evaluated each time a default is needed for the column.
+ If the expression qualifies as stable or immutable, the repeat
+ evaluation may be skipped.
+ This means that you can usefully use volatile functions like
+ <function>nextval</function> in
+ <replaceable>default_expression</replaceable>.
+ </para>
+
+ <para>
+ Columns may be marked <literal>NOT NULL</literal>. If the
+ <replaceable>column_expression</replaceable> for a <literal>NOT
+ NULL</literal> column does not match anything and there is
+ no <literal>DEFAULT</literal> or
+ the <replaceable>default_expression</replaceable> also evaluates to null,
+ an error is reported.
+ </para>
+
+ <para>
+ Examples:
+ <screen><![CDATA[
+CREATE TABLE xmldata AS SELECT
+xml $$
+<ROWS>
+ <ROW id="1">
+ <COUNTRY_ID>AU</COUNTRY_ID>
+ <COUNTRY_NAME>Australia</COUNTRY_NAME>
+ </ROW>
+ <ROW id="5">
+ <COUNTRY_ID>JP</COUNTRY_ID>
+ <COUNTRY_NAME>Japan</COUNTRY_NAME>
+ <PREMIER_NAME>Shinzo Abe</PREMIER_NAME>
+ <SIZE unit="sq_mi">145935</SIZE>
+ </ROW>
+ <ROW id="6">
+ <COUNTRY_ID>SG</COUNTRY_ID>
+ <COUNTRY_NAME>Singapore</COUNTRY_NAME>
+ <SIZE unit="sq_km">697</SIZE>
+ </ROW>
+</ROWS>
+$$ AS data;
+
+SELECT xmltable.*
+ FROM xmldata,
+ XMLTABLE('//ROWS/ROW'
+ PASSING data
+ COLUMNS id int PATH '@id',
+ ordinality FOR ORDINALITY,
+ "COUNTRY_NAME" text,
+ country_id text PATH 'COUNTRY_ID',
+ size_sq_km float PATH 'SIZE[@unit = "sq_km"]',
+ size_other text PATH
+ 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)',
+ premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified');
+
+ id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name
+----+------------+--------------+------------+------------+--------------+---------------
+ 1 | 1 | Australia | AU | | | not specified
+ 5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe
+ 6 | 3 | Singapore | SG | 697 | | not specified
+]]></screen>
+
+ The following example shows concatenation of multiple text() nodes,
+ usage of the column name as XPath filter, and the treatment of whitespace,
+ XML comments and processing instructions:
+
+ <screen><![CDATA[
+CREATE TABLE xmlelements AS SELECT
+xml $$
+ <root>
+ <element> Hello<!-- xyxxz -->2a2<?aaaaa?> <!--x--> bbb<x>xxx</x>CC </element>
+ </root>
+$$ AS data;
+
+SELECT xmltable.*
+ FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
+ element
+-------------------------
+ Hello2a2 bbbxxxCC
+]]></screen>
+ </para>
+
+ <para>
+ The following example illustrates how
+ the <literal>XMLNAMESPACES</literal> clause can be used to specify
+ a list of namespaces
+ used in the XML document as well as in the XPath expressions:
+
+ <screen><![CDATA[
+WITH xmldata(data) AS (VALUES ('
+<example xmlns="http://example.com/myns" xmlns:B="http://example.com/b">
+ <item foo="1" B:bar="2"/>
+ <item foo="3" B:bar="4"/>
+ <item foo="4" B:bar="5"/>
+</example>'::xml)
+)
+SELECT xmltable.*
+ FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x,
+ 'http://example.com/b' AS "B"),
+ '/x:example/x:item'
+ PASSING (SELECT data FROM xmldata)
+ COLUMNS foo int PATH '@foo',
+ bar int PATH '@B:bar');
+ foo | bar
+-----+-----
+ 1 | 2
+ 3 | 4
+ 4 | 5
+(3 rows)
+]]></screen>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="functions-xml-mapping">
+ <title>Mapping Tables to XML</title>
+
+ <indexterm zone="functions-xml-mapping">
+ <primary>XML export</primary>
+ </indexterm>
+
+ <para>
+ The following functions map the contents of relational tables to
+ XML values. They can be thought of as XML export functionality:
+<synopsis>
+<function>table_to_xml</function> ( <parameter>table</parameter> <type>regclass</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>query_to_xml</function> ( <parameter>query</parameter> <type>text</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>cursor_to_xml</function> ( <parameter>cursor</parameter> <type>refcursor</type>, <parameter>count</parameter> <type>integer</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+</synopsis>
+ </para>
+
+ <para>
+ <function>table_to_xml</function> maps the content of the named
+ table, passed as parameter <parameter>table</parameter>. The
+ <type>regclass</type> type accepts strings identifying tables using the
+ usual notation, including optional schema qualification and
+ double quotes (see <xref linkend="datatype-oid"/> for details).
+ <function>query_to_xml</function> executes the
+ query whose text is passed as parameter
+ <parameter>query</parameter> and maps the result set.
+ <function>cursor_to_xml</function> fetches the indicated number of
+ rows from the cursor specified by the parameter
+ <parameter>cursor</parameter>. This variant is recommended if
+ large tables have to be mapped, because the result value is built
+ up in memory by each function.
+ </para>
+
+ <para>
+ If <parameter>tableforest</parameter> is false, then the resulting
+ XML document looks like this:
+<screen><![CDATA[
+<tablename>
+ <row>
+ <columnname1>data</columnname1>
+ <columnname2>data</columnname2>
+ </row>
+
+ <row>
+ ...
+ </row>
+
+ ...
+</tablename>
+]]></screen>
+
+ If <parameter>tableforest</parameter> is true, the result is an
+ XML content fragment that looks like this:
+<screen><![CDATA[
+<tablename>
+ <columnname1>data</columnname1>
+ <columnname2>data</columnname2>
+</tablename>
+
+<tablename>
+ ...
+</tablename>
+
+...
+]]></screen>
+
+ If no table name is available, that is, when mapping a query or a
+ cursor, the string <literal>table</literal> is used in the first
+ format, <literal>row</literal> in the second format.
+ </para>
+
+ <para>
+ The choice between these formats is up to the user. The first
+ format is a proper XML document, which will be important in many
+ applications. The second format tends to be more useful in the
+ <function>cursor_to_xml</function> function if the result values are to be
+ reassembled into one document later on. The functions for
+ producing XML content discussed above, in particular
+ <function>xmlelement</function>, can be used to alter the results
+ to taste.
+ </para>
+
+ <para>
+ The data values are mapped in the same way as described for the
+ function <function>xmlelement</function> above.
+ </para>
+
+ <para>
+ The parameter <parameter>nulls</parameter> determines whether null
+ values should be included in the output. If true, null values in
+ columns are represented as:
+<screen><![CDATA[
+<columnname xsi:nil="true"/>
+]]></screen>
+ where <literal>xsi</literal> is the XML namespace prefix for XML
+ Schema Instance. An appropriate namespace declaration will be
+ added to the result value. If false, columns containing null
+ values are simply omitted from the output.
+ </para>
+
+ <para>
+ The parameter <parameter>targetns</parameter> specifies the
+ desired XML namespace of the result. If no particular namespace
+ is wanted, an empty string should be passed.
+ </para>
+
+ <para>
+ The following functions return XML Schema documents describing the
+ mappings performed by the corresponding functions above:
+<synopsis>
+<function>table_to_xmlschema</function> ( <parameter>table</parameter> <type>regclass</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>query_to_xmlschema</function> ( <parameter>query</parameter> <type>text</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>cursor_to_xmlschema</function> ( <parameter>cursor</parameter> <type>refcursor</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+</synopsis>
+ It is essential that the same parameters are passed in order to
+ obtain matching XML data mappings and XML Schema documents.
+ </para>
+
+ <para>
+ The following functions produce XML data mappings and the
+ corresponding XML Schema in one document (or forest), linked
+ together. They can be useful where self-contained and
+ self-describing results are wanted:
+<synopsis>
+<function>table_to_xml_and_xmlschema</function> ( <parameter>table</parameter> <type>regclass</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>query_to_xml_and_xmlschema</function> ( <parameter>query</parameter> <type>text</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+</synopsis>
+ </para>
+
+ <para>
+ In addition, the following functions are available to produce
+ analogous mappings of entire schemas or the entire current
+ database:
+<synopsis>
+<function>schema_to_xml</function> ( <parameter>schema</parameter> <type>name</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>schema_to_xmlschema</function> ( <parameter>schema</parameter> <type>name</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>schema_to_xml_and_xmlschema</function> ( <parameter>schema</parameter> <type>name</type>, <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+
+<function>database_to_xml</function> ( <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>database_to_xmlschema</function> ( <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+<function>database_to_xml_and_xmlschema</function> ( <parameter>nulls</parameter> <type>boolean</type>,
+ <parameter>tableforest</parameter> <type>boolean</type>, <parameter>targetns</parameter> <type>text</type> ) <returnvalue>xml</returnvalue>
+</synopsis>
+
+ These functions ignore tables that are not readable by the current user.
+ The database-wide functions additionally ignore schemas that the current
+ user does not have <literal>USAGE</literal> (lookup) privilege for.
+ </para>
+
+ <para>
+ Note that these potentially produce a lot of data, which needs to
+ be built up in memory. When requesting content mappings of large
+ schemas or databases, it might be worthwhile to consider mapping the
+ tables separately instead, possibly even through a cursor.
+ </para>
+
+ <para>
+ The result of a schema content mapping looks like this:
+
+<screen><![CDATA[
+<schemaname>
+
+table1-mapping
+
+table2-mapping
+
+...
+
+</schemaname>]]></screen>
+
+ where the format of a table mapping depends on the
+ <parameter>tableforest</parameter> parameter as explained above.
+ </para>
+
+ <para>
+ The result of a database content mapping looks like this:
+
+<screen><![CDATA[
+<dbname>
+
+<schema1name>
+ ...
+</schema1name>
+
+<schema2name>
+ ...
+</schema2name>
+
+...
+
+</dbname>]]></screen>
+
+ where the schema mapping is as above.
+ </para>
+
+ <para>
+ As an example of using the output produced by these functions,
+ <xref linkend="xslt-xml-html"/> shows an XSLT stylesheet that
+ converts the output of
+ <function>table_to_xml_and_xmlschema</function> to an HTML
+ document containing a tabular rendition of the table data. In a
+ similar manner, the results from these functions can be
+ converted into other XML-based formats.
+ </para>
+
+ <example id="xslt-xml-html">
+ <title>XSLT Stylesheet for Converting SQL/XML Output to HTML</title>
+<programlisting><![CDATA[
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/1999/xhtml"
+>
+
+ <xsl:output method="xml"
+ doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+ doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
+ indent="yes"/>
+
+ <xsl:template match="/*">
+ <xsl:variable name="schema" select="//xsd:schema"/>
+ <xsl:variable name="tabletypename"
+ select="$schema/xsd:element[@name=name(current())]/@type"/>
+ <xsl:variable name="rowtypename"
+ select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/>
+
+ <html>
+ <head>
+ <title><xsl:value-of select="name(current())"/></title>
+ </head>
+ <body>
+ <table>
+ <tr>
+ <xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name">
+ <th><xsl:value-of select="."/></th>
+ </xsl:for-each>
+ </tr>
+
+ <xsl:for-each select="row">
+ <tr>
+ <xsl:for-each select="*">
+ <td><xsl:value-of select="."/></td>
+ </xsl:for-each>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </body>
+ </html>
+ </xsl:template>
+
+</xsl:stylesheet>
+]]></programlisting>
+ </example>
+ </sect2>
+ </sect1>
+
+ <sect1 id="functions-json">
+ <title>JSON Functions and Operators</title>
+
+ <indexterm zone="functions-json">
+ <primary>JSON</primary>
+ <secondary>functions and operators</secondary>
+ </indexterm>
+
+ <para>
+ This section describes:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ functions and operators for processing and creating JSON data
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the SQL/JSON path language
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ To learn more about the SQL/JSON standard, see
+ <xref linkend="sqltr-19075-6"/>. For details on JSON types
+ supported in <productname>PostgreSQL</productname>,
+ see <xref linkend="datatype-json"/>.
+ </para>
+
+ <sect2 id="functions-json-processing">
+ <title>Processing and Creating JSON Data</title>
+
+ <para>
+ <xref linkend="functions-json-op-table"/> shows the operators that
+ are available for use with JSON data types (see <xref
+ linkend="datatype-json"/>).
+ In addition, the usual comparison operators shown in <xref
+ linkend="functions-comparison-op-table"/> are available for
+ <type>jsonb</type>, though not for <type>json</type>. The comparison
+ operators follow the ordering rules for B-tree operations outlined in
+ <xref linkend="json-indexing"/>.
+ See also <xref linkend="functions-aggregate"/> for the aggregate
+ function <function>json_agg</function> which aggregates record
+ values as JSON, the aggregate function
+ <function>json_object_agg</function> which aggregates pairs of values
+ into a JSON object, and their <type>jsonb</type> equivalents,
+ <function>jsonb_agg</function> and <function>jsonb_object_agg</function>.
+ </para>
+
+ <table id="functions-json-op-table">
+ <title><type>json</type> and <type>jsonb</type> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>json</type> <literal>-&gt;</literal> <type>integer</type>
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>jsonb</type> <literal>-&gt;</literal> <type>integer</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Extracts <parameter>n</parameter>'th element of JSON array
+ (array elements are indexed from zero, but negative integers count
+ from the end).
+ </para>
+ <para>
+ <literal>'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -&gt; 2</literal>
+ <returnvalue>{"c":"baz"}</returnvalue>
+ </para>
+ <para>
+ <literal>'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -&gt; -3</literal>
+ <returnvalue>{"a":"foo"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>json</type> <literal>-&gt;</literal> <type>text</type>
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>jsonb</type> <literal>-&gt;</literal> <type>text</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Extracts JSON object field with the given key.
+ </para>
+ <para>
+ <literal>'{"a": {"b":"foo"}}'::json -&gt; 'a'</literal>
+ <returnvalue>{"b":"foo"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>json</type> <literal>-&gt;&gt;</literal> <type>integer</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>jsonb</type> <literal>-&gt;&gt;</literal> <type>integer</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts <parameter>n</parameter>'th element of JSON array,
+ as <type>text</type>.
+ </para>
+ <para>
+ <literal>'[1,2,3]'::json -&gt;&gt; 2</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>json</type> <literal>-&gt;&gt;</literal> <type>text</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>jsonb</type> <literal>-&gt;&gt;</literal> <type>text</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts JSON object field with the given key, as <type>text</type>.
+ </para>
+ <para>
+ <literal>'{"a":1,"b":2}'::json -&gt;&gt; 'b'</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>json</type> <literal>#&gt;</literal> <type>text[]</type>
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>jsonb</type> <literal>#&gt;</literal> <type>text[]</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Extracts JSON sub-object at the specified path, where path elements
+ can be either field keys or array indexes.
+ </para>
+ <para>
+ <literal>'{"a": {"b": ["foo","bar"]}}'::json #&gt; '{a,b,1}'</literal>
+ <returnvalue>"bar"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>json</type> <literal>#&gt;&gt;</literal> <type>text[]</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>jsonb</type> <literal>#&gt;&gt;</literal> <type>text[]</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts JSON sub-object at the specified path as <type>text</type>.
+ </para>
+ <para>
+ <literal>'{"a": {"b": ["foo","bar"]}}'::json #&gt;&gt; '{a,b,1}'</literal>
+ <returnvalue>bar</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The field/element/path extraction operators return NULL, rather than
+ failing, if the JSON input does not have the right structure to match
+ the request; for example if no such key or array element exists.
+ </para>
+ </note>
+
+ <para>
+ Some further operators exist only for <type>jsonb</type>, as shown
+ in <xref linkend="functions-jsonb-op-table"/>.
+ <xref linkend="json-indexing"/>
+ describes how these operators can be used to effectively search indexed
+ <type>jsonb</type> data.
+ </para>
+
+ <table id="functions-jsonb-op-table">
+ <title>Additional <type>jsonb</type> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>@&gt;</literal> <type>jsonb</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first JSON value contain the second?
+ (See <xref linkend="json-containment"/> for details about containment.)
+ </para>
+ <para>
+ <literal>'{"a":1, "b":2}'::jsonb &#64;&gt; '{"b":2}'::jsonb</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>&lt;@</literal> <type>jsonb</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first JSON value contained in the second?
+ </para>
+ <para>
+ <literal>'{"b":2}'::jsonb &lt;@ '{"a":1, "b":2}'::jsonb</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>?</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the text string exist as a top-level key or array element within
+ the JSON value?
+ </para>
+ <para>
+ <literal>'{"a":1, "b":2}'::jsonb ? 'b'</literal>
+ <returnvalue>t</returnvalue>
+ </para>
+ <para>
+ <literal>'["a", "b", "c"]'::jsonb ? 'b'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>?|</literal> <type>text[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do any of the strings in the text array exist as top-level keys or
+ array elements?
+ </para>
+ <para>
+ <literal>'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd']</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>?&amp;</literal> <type>text[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do all of the strings in the text array exist as top-level keys or
+ array elements?
+ </para>
+ <para>
+ <literal>'["a", "b", "c"]'::jsonb ?&amp; array['a', 'b']</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>||</literal> <type>jsonb</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Concatenates two <type>jsonb</type> values.
+ Concatenating two arrays generates an array containing all the
+ elements of each input. Concatenating two objects generates an
+ object containing the union of their
+ keys, taking the second object's value when there are duplicate keys.
+ All other cases are treated by converting a non-array input into a
+ single-element array, and then proceeding as for two arrays.
+ Does not operate recursively: only the top-level array or object
+ structure is merged.
+ </para>
+ <para>
+ <literal>'["a", "b"]'::jsonb || '["a", "d"]'::jsonb</literal>
+ <returnvalue>["a", "b", "a", "d"]</returnvalue>
+ </para>
+ <para>
+ <literal>'{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb</literal>
+ <returnvalue>{"a": "b", "c": "d"}</returnvalue>
+ </para>
+ <para>
+ <literal>'[1, 2]'::jsonb || '3'::jsonb</literal>
+ <returnvalue>[1, 2, 3]</returnvalue>
+ </para>
+ <para>
+ <literal>'{"a": "b"}'::jsonb || '42'::jsonb</literal>
+ <returnvalue>[{"a": "b"}, 42]</returnvalue>
+ </para>
+ <para>
+ To append an array to another array as a single entry, wrap it
+ in an additional layer of array, for example:
+ </para>
+ <para>
+ <literal>'[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb)</literal>
+ <returnvalue>[1, 2, [3, 4]]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>-</literal> <type>text</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Deletes a key (and its value) from a JSON object, or matching string
+ value(s) from a JSON array.
+ </para>
+ <para>
+ <literal>'{"a": "b", "c": "d"}'::jsonb - 'a'</literal>
+ <returnvalue>{"c": "d"}</returnvalue>
+ </para>
+ <para>
+ <literal>'["a", "b", "c", "b"]'::jsonb - 'b'</literal>
+ <returnvalue>["a", "c"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>-</literal> <type>text[]</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Deletes all matching keys or array elements from the left operand.
+ </para>
+ <para>
+ <literal>'{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[]</literal>
+ <returnvalue>{}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>-</literal> <type>integer</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Deletes the array element with specified index (negative
+ integers count from the end). Throws an error if JSON value
+ is not an array.
+ </para>
+ <para>
+ <literal>'["a", "b"]'::jsonb - 1 </literal>
+ <returnvalue>["a"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>#-</literal> <type>text[]</type>
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Deletes the field or array element at the specified path, where path
+ elements can be either field keys or array indexes.
+ </para>
+ <para>
+ <literal>'["a", {"b":1}]'::jsonb #- '{1,b}'</literal>
+ <returnvalue>["a", {}]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>@?</literal> <type>jsonpath</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does JSON path return any item for the specified JSON value?
+ </para>
+ <para>
+ <literal>'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>jsonb</type> <literal>@@</literal> <type>jsonpath</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns the result of a JSON path predicate check for the
+ specified JSON value. Only the first item of the result is taken into
+ account. If the result is not Boolean, then <literal>NULL</literal>
+ is returned.
+ </para>
+ <para>
+ <literal>'{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The <type>jsonpath</type> operators <literal>@?</literal>
+ and <literal>@@</literal> suppress the following errors: missing object
+ field or array element, unexpected JSON item type, datetime and numeric
+ errors. The <type>jsonpath</type>-related functions described below can
+ also be told to suppress these types of errors. This behavior might be
+ helpful when searching JSON document collections of varying structure.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="functions-json-creation-table"/> shows the functions that are
+ available for constructing <type>json</type> and <type>jsonb</type> values.
+ </para>
+
+ <table id="functions-json-creation-table">
+ <title>JSON Creation Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_json</primary>
+ </indexterm>
+ <function>to_json</function> ( <type>anyelement</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>to_jsonb</primary>
+ </indexterm>
+ <function>to_jsonb</function> ( <type>anyelement</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Converts any SQL value to <type>json</type> or <type>jsonb</type>.
+ Arrays and composites are converted recursively to arrays and
+ objects (multidimensional arrays become arrays of arrays in JSON).
+ Otherwise, if there is a cast from the SQL data type
+ to <type>json</type>, the cast function will be used to perform the
+ conversion;<footnote>
+ <para>
+ For example, the <xref linkend="hstore"/> extension has a cast
+ from <type>hstore</type> to <type>json</type>, so that
+ <type>hstore</type> values converted via the JSON creation functions
+ will be represented as JSON objects, not as primitive string values.
+ </para>
+ </footnote>
+ otherwise, a scalar JSON value is produced. For any scalar other than
+ a number, a Boolean, or a null value, the text representation will be
+ used, with escaping as necessary to make it a valid JSON string value.
+ </para>
+ <para>
+ <literal>to_json('Fred said "Hi."'::text)</literal>
+ <returnvalue>"Fred said \"Hi.\""</returnvalue>
+ </para>
+ <para>
+ <literal>to_jsonb(row(42, 'Fred said "Hi."'::text))</literal>
+ <returnvalue>{"f1": 42, "f2": "Fred said \"Hi.\""}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_to_json</primary>
+ </indexterm>
+ <function>array_to_json</function> ( <type>anyarray</type> <optional>, <type>boolean</type> </optional> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para>
+ Converts an SQL array to a JSON array. The behavior is the same
+ as <function>to_json</function> except that line feeds will be added
+ between top-level array elements if the optional boolean parameter is
+ true.
+ </para>
+ <para>
+ <literal>array_to_json('{{1,5},{99,100}}'::int[])</literal>
+ <returnvalue>[[1,5],[99,100]]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>row_to_json</primary>
+ </indexterm>
+ <function>row_to_json</function> ( <type>record</type> <optional>, <type>boolean</type> </optional> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para>
+ Converts an SQL composite value to a JSON object. The behavior is the
+ same as <function>to_json</function> except that line feeds will be
+ added between top-level elements if the optional boolean parameter is
+ true.
+ </para>
+ <para>
+ <literal>row_to_json(row(1,'foo'))</literal>
+ <returnvalue>{"f1":1,"f2":"foo"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_build_array</primary>
+ </indexterm>
+ <function>json_build_array</function> ( <literal>VARIADIC</literal> <type>"any"</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_build_array</primary>
+ </indexterm>
+ <function>jsonb_build_array</function> ( <literal>VARIADIC</literal> <type>"any"</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Builds a possibly-heterogeneously-typed JSON array out of a variadic
+ argument list. Each argument is converted as
+ per <function>to_json</function> or <function>to_jsonb</function>.
+ </para>
+ <para>
+ <literal>json_build_array(1, 2, 'foo', 4, 5)</literal>
+ <returnvalue>[1, 2, "foo", 4, 5]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_build_object</primary>
+ </indexterm>
+ <function>json_build_object</function> ( <literal>VARIADIC</literal> <type>"any"</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_build_object</primary>
+ </indexterm>
+ <function>jsonb_build_object</function> ( <literal>VARIADIC</literal> <type>"any"</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Builds a JSON object out of a variadic argument list. By convention,
+ the argument list consists of alternating keys and values. Key
+ arguments are coerced to text; value arguments are converted as
+ per <function>to_json</function> or <function>to_jsonb</function>.
+ </para>
+ <para>
+ <literal>json_build_object('foo', 1, 2, row(3,'bar'))</literal>
+ <returnvalue>{"foo" : 1, "2" : {"f1":3,"f2":"bar"}}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_object</primary>
+ </indexterm>
+ <function>json_object</function> ( <type>text[]</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_object</primary>
+ </indexterm>
+ <function>jsonb_object</function> ( <type>text[]</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Builds a JSON object out of a text array. The array must have either
+ exactly one dimension with an even number of members, in which case
+ they are taken as alternating key/value pairs, or two dimensions
+ such that each inner array has exactly two elements, which
+ are taken as a key/value pair. All values are converted to JSON
+ strings.
+ </para>
+ <para>
+ <literal>json_object('{a, 1, b, "def", c, 3.5}')</literal>
+ <returnvalue>{"a" : "1", "b" : "def", "c" : "3.5"}</returnvalue>
+ </para>
+ <para><literal>json_object('{{a, 1}, {b, "def"}, {c, 3.5}}')</literal>
+ <returnvalue>{"a" : "1", "b" : "def", "c" : "3.5"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>json_object</function> ( <parameter>keys</parameter> <type>text[]</type>, <parameter>values</parameter> <type>text[]</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>jsonb_object</function> ( <parameter>keys</parameter> <type>text[]</type>, <parameter>values</parameter> <type>text[]</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ This form of <function>json_object</function> takes keys and values
+ pairwise from separate text arrays. Otherwise it is identical to
+ the one-argument form.
+ </para>
+ <para>
+ <literal>json_object('{a,b}', '{1,2}')</literal>
+ <returnvalue>{"a": "1", "b": "2"}</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-json-processing-table"/> shows the functions that
+ are available for processing <type>json</type> and <type>jsonb</type> values.
+ </para>
+
+ <table id="functions-json-processing-table">
+ <title>JSON Processing Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_array_elements</primary>
+ </indexterm>
+ <function>json_array_elements</function> ( <type>json</type> )
+ <returnvalue>setof json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_array_elements</primary>
+ </indexterm>
+ <function>jsonb_array_elements</function> ( <type>jsonb</type> )
+ <returnvalue>setof jsonb</returnvalue>
+ </para>
+ <para>
+ Expands the top-level JSON array into a set of JSON values.
+ </para>
+ <para>
+ <literal>select * from json_array_elements('[1,true, [2,false]]')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ value
+-----------
+ 1
+ true
+ [2,false]
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_array_elements_text</primary>
+ </indexterm>
+ <function>json_array_elements_text</function> ( <type>json</type> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_array_elements_text</primary>
+ </indexterm>
+ <function>jsonb_array_elements_text</function> ( <type>jsonb</type> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Expands the top-level JSON array into a set of <type>text</type> values.
+ </para>
+ <para>
+ <literal>select * from json_array_elements_text('["foo", "bar"]')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ value
+-----------
+ foo
+ bar
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_array_length</primary>
+ </indexterm>
+ <function>json_array_length</function> ( <type>json</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_array_length</primary>
+ </indexterm>
+ <function>jsonb_array_length</function> ( <type>jsonb</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of elements in the top-level JSON array.
+ </para>
+ <para>
+ <literal>json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')</literal>
+ <returnvalue>5</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_array_length('[]')</literal>
+ <returnvalue>0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_each</primary>
+ </indexterm>
+ <function>json_each</function> ( <type>json</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>key</parameter> <type>text</type>,
+ <parameter>value</parameter> <type>json</type> )
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_each</primary>
+ </indexterm>
+ <function>jsonb_each</function> ( <type>jsonb</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>key</parameter> <type>text</type>,
+ <parameter>value</parameter> <type>jsonb</type> )
+ </para>
+ <para>
+ Expands the top-level JSON object into a set of key/value pairs.
+ </para>
+ <para>
+ <literal>select * from json_each('{"a":"foo", "b":"bar"}')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ key | value
+-----+-------
+ a | "foo"
+ b | "bar"
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_each_text</primary>
+ </indexterm>
+ <function>json_each_text</function> ( <type>json</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>key</parameter> <type>text</type>,
+ <parameter>value</parameter> <type>text</type> )
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_each_text</primary>
+ </indexterm>
+ <function>jsonb_each_text</function> ( <type>jsonb</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>key</parameter> <type>text</type>,
+ <parameter>value</parameter> <type>text</type> )
+ </para>
+ <para>
+ Expands the top-level JSON object into a set of key/value pairs.
+ The returned <parameter>value</parameter>s will be of
+ type <type>text</type>.
+ </para>
+ <para>
+ <literal>select * from json_each_text('{"a":"foo", "b":"bar"}')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ key | value
+-----+-------
+ a | foo
+ b | bar
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_extract_path</primary>
+ </indexterm>
+ <function>json_extract_path</function> ( <parameter>from_json</parameter> <type>json</type>, <literal>VARIADIC</literal> <parameter>path_elems</parameter> <type>text[]</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_extract_path</primary>
+ </indexterm>
+ <function>jsonb_extract_path</function> ( <parameter>from_json</parameter> <type>jsonb</type>, <literal>VARIADIC</literal> <parameter>path_elems</parameter> <type>text[]</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Extracts JSON sub-object at the specified path.
+ (This is functionally equivalent to the <literal>#&gt;</literal>
+ operator, but writing the path out as a variadic list can be more
+ convenient in some cases.)
+ </para>
+ <para>
+ <literal>json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')</literal>
+ <returnvalue>"foo"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_extract_path_text</primary>
+ </indexterm>
+ <function>json_extract_path_text</function> ( <parameter>from_json</parameter> <type>json</type>, <literal>VARIADIC</literal> <parameter>path_elems</parameter> <type>text[]</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_extract_path_text</primary>
+ </indexterm>
+ <function>jsonb_extract_path_text</function> ( <parameter>from_json</parameter> <type>jsonb</type>, <literal>VARIADIC</literal> <parameter>path_elems</parameter> <type>text[]</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Extracts JSON sub-object at the specified path as <type>text</type>.
+ (This is functionally equivalent to the <literal>#&gt;&gt;</literal>
+ operator.)
+ </para>
+ <para>
+ <literal>json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')</literal>
+ <returnvalue>foo</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_object_keys</primary>
+ </indexterm>
+ <function>json_object_keys</function> ( <type>json</type> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_object_keys</primary>
+ </indexterm>
+ <function>jsonb_object_keys</function> ( <type>jsonb</type> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Returns the set of keys in the top-level JSON object.
+ </para>
+ <para>
+ <literal>select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ json_object_keys
+------------------
+ f1
+ f2
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_populate_record</primary>
+ </indexterm>
+ <function>json_populate_record</function> ( <parameter>base</parameter> <type>anyelement</type>, <parameter>from_json</parameter> <type>json</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_populate_record</primary>
+ </indexterm>
+ <function>jsonb_populate_record</function> ( <parameter>base</parameter> <type>anyelement</type>, <parameter>from_json</parameter> <type>jsonb</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Expands the top-level JSON object to a row having the composite type
+ of the <parameter>base</parameter> argument. The JSON object
+ is scanned for fields whose names match column names of the output row
+ type, and their values are inserted into those columns of the output.
+ (Fields that do not correspond to any output column name are ignored.)
+ In typical use, the value of <parameter>base</parameter> is just
+ <literal>NULL</literal>, which means that any output columns that do
+ not match any object field will be filled with nulls. However,
+ if <parameter>base</parameter> isn't <literal>NULL</literal> then
+ the values it contains will be used for unmatched columns.
+ </para>
+ <para>
+ To convert a JSON value to the SQL type of an output column, the
+ following rules are applied in sequence:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ A JSON null value is converted to an SQL null in all cases.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the output column is of type <type>json</type>
+ or <type>jsonb</type>, the JSON value is just reproduced exactly.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the output column is a composite (row) type, and the JSON value
+ is a JSON object, the fields of the object are converted to columns
+ of the output row type by recursive application of these rules.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Likewise, if the output column is an array type and the JSON value
+ is a JSON array, the elements of the JSON array are converted to
+ elements of the output array by recursive application of these
+ rules.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, if the JSON value is a string, the contents of the
+ string are fed to the input conversion function for the column's
+ data type.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Otherwise, the ordinary text representation of the JSON value is
+ fed to the input conversion function for the column's data type.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ While the example below uses a constant JSON value, typical use would
+ be to reference a <type>json</type> or <type>jsonb</type> column
+ laterally from another table in the query's <literal>FROM</literal>
+ clause. Writing <function>json_populate_record</function> in
+ the <literal>FROM</literal> clause is good practice, since all of the
+ extracted columns are available for use without duplicate function
+ calls.
+ </para>
+ <para>
+ <literal>create type subrowtype as (d int, e text);</literal>
+ <literal>create type myrowtype as (a int, b text[], c subrowtype);</literal>
+ </para>
+ <para>
+ <literal>select * from json_populate_record(null::myrowtype,
+ '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}, "x": "foo"}')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ a | b | c
+---+-----------+-------------
+ 1 | {2,"a b"} | (4,"a b c")
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_populate_recordset</primary>
+ </indexterm>
+ <function>json_populate_recordset</function> ( <parameter>base</parameter> <type>anyelement</type>, <parameter>from_json</parameter> <type>json</type> )
+ <returnvalue>setof anyelement</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_populate_recordset</primary>
+ </indexterm>
+ <function>jsonb_populate_recordset</function> ( <parameter>base</parameter> <type>anyelement</type>, <parameter>from_json</parameter> <type>jsonb</type> )
+ <returnvalue>setof anyelement</returnvalue>
+ </para>
+ <para>
+ Expands the top-level JSON array of objects to a set of rows having
+ the composite type of the <parameter>base</parameter> argument.
+ Each element of the JSON array is processed as described above
+ for <function>json[b]_populate_record</function>.
+ </para>
+ <para>
+ <literal>create type twoints as (a int, b int);</literal>
+ </para>
+ <para>
+ <literal>select * from json_populate_recordset(null::twoints, '[{"a":1,"b":2}, {"a":3,"b":4}]')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ a | b
+---+---
+ 1 | 2
+ 3 | 4
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_to_record</primary>
+ </indexterm>
+ <function>json_to_record</function> ( <type>json</type> )
+ <returnvalue>record</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_to_record</primary>
+ </indexterm>
+ <function>jsonb_to_record</function> ( <type>jsonb</type> )
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Expands the top-level JSON object to a row having the composite type
+ defined by an <literal>AS</literal> clause. (As with all functions
+ returning <type>record</type>, the calling query must explicitly
+ define the structure of the record with an <literal>AS</literal>
+ clause.) The output record is filled from fields of the JSON object,
+ in the same way as described above
+ for <function>json[b]_populate_record</function>. Since there is no
+ input record value, unmatched columns are always filled with nulls.
+ </para>
+ <para>
+ <literal>create type myrowtype as (a int, b text);</literal>
+ </para>
+ <para>
+ <literal>select * from json_to_record('{"a":1,"b":[1,2,3],"c":[1,2,3],"e":"bar","r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype)</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ a | b | c | d | r
+---+---------+---------+---+---------------
+ 1 | [1,2,3] | {1,2,3} | | (123,"a b c")
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_to_recordset</primary>
+ </indexterm>
+ <function>json_to_recordset</function> ( <type>json</type> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_to_recordset</primary>
+ </indexterm>
+ <function>jsonb_to_recordset</function> ( <type>jsonb</type> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Expands the top-level JSON array of objects to a set of rows having
+ the composite type defined by an <literal>AS</literal> clause. (As
+ with all functions returning <type>record</type>, the calling query
+ must explicitly define the structure of the record with
+ an <literal>AS</literal> clause.) Each element of the JSON array is
+ processed as described above
+ for <function>json[b]_populate_record</function>.
+ </para>
+ <para>
+ <literal>select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text)</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ a | b
+---+-----
+ 1 | foo
+ 2 |
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_set</primary>
+ </indexterm>
+ <function>jsonb_set</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>text[]</type>, <parameter>new_value</parameter> <type>jsonb</type> <optional>, <parameter>create_if_missing</parameter> <type>boolean</type> </optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>target</parameter>
+ with the item designated by <parameter>path</parameter>
+ replaced by <parameter>new_value</parameter>, or with
+ <parameter>new_value</parameter> added if
+ <parameter>create_if_missing</parameter> is true (which is the
+ default) and the item designated by <parameter>path</parameter>
+ does not exist.
+ All earlier steps in the path must exist, or
+ the <parameter>target</parameter> is returned unchanged.
+ As with the path oriented operators, negative integers that
+ appear in the <parameter>path</parameter> count from the end
+ of JSON arrays.
+ If the last path step is an array index that is out of range,
+ and <parameter>create_if_missing</parameter> is true, the new
+ value is added at the beginning of the array if the index is negative,
+ or at the end of the array if it is positive.
+ </para>
+ <para>
+ <literal>jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', '[2,3,4]', false)</literal>
+ <returnvalue>[{"f1": [2, 3, 4], "f2": null}, 2, null, 3]</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}', '[2,3,4]')</literal>
+ <returnvalue>[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_set_lax</primary>
+ </indexterm>
+ <function>jsonb_set_lax</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>text[]</type>, <parameter>new_value</parameter> <type>jsonb</type> <optional>, <parameter>create_if_missing</parameter> <type>boolean</type> <optional>, <parameter>null_value_treatment</parameter> <type>text</type> </optional></optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ If <parameter>new_value</parameter> is not <literal>NULL</literal>,
+ behaves identically to <literal>jsonb_set</literal>. Otherwise behaves
+ according to the value
+ of <parameter>null_value_treatment</parameter> which must be one
+ of <literal>'raise_exception'</literal>,
+ <literal>'use_json_null'</literal>, <literal>'delete_key'</literal>, or
+ <literal>'return_target'</literal>. The default is
+ <literal>'use_json_null'</literal>.
+ </para>
+ <para>
+ <literal>jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null)</literal>
+ <returnvalue>[{"f1": null, "f2": null}, 2, null, 3]</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target')</literal>
+ <returnvalue>[{"f1": 99, "f2": null}, 2]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_insert</primary>
+ </indexterm>
+ <function>jsonb_insert</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>text[]</type>, <parameter>new_value</parameter> <type>jsonb</type> <optional>, <parameter>insert_after</parameter> <type>boolean</type> </optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>target</parameter>
+ with <parameter>new_value</parameter> inserted. If the item
+ designated by the <parameter>path</parameter> is an array
+ element, <parameter>new_value</parameter> will be inserted before
+ that item if <parameter>insert_after</parameter> is false (which
+ is the default), or after it
+ if <parameter>insert_after</parameter> is true. If the item
+ designated by the <parameter>path</parameter> is an object
+ field, <parameter>new_value</parameter> will be inserted only if
+ the object does not already contain that key.
+ All earlier steps in the path must exist, or
+ the <parameter>target</parameter> is returned unchanged.
+ As with the path oriented operators, negative integers that
+ appear in the <parameter>path</parameter> count from the end
+ of JSON arrays.
+ If the last path step is an array index that is out of range, the new
+ value is added at the beginning of the array if the index is negative,
+ or at the end of the array if it is positive.
+ </para>
+ <para>
+ <literal>jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"')</literal>
+ <returnvalue>{"a": [0, "new_value", 1, 2]}</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true)</literal>
+ <returnvalue>{"a": [0, 1, "new_value", 2]}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_strip_nulls</primary>
+ </indexterm>
+ <function>json_strip_nulls</function> ( <type>json</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_strip_nulls</primary>
+ </indexterm>
+ <function>jsonb_strip_nulls</function> ( <type>jsonb</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Deletes all object fields that have null values from the given JSON
+ value, recursively. Null values that are not object fields are
+ untouched.
+ </para>
+ <para>
+ <literal>json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]')</literal>
+ <returnvalue>[{"f1":1},2,null,3]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_exists</primary>
+ </indexterm>
+ <function>jsonb_path_exists</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Checks whether the JSON path returns any item for the specified JSON
+ value.
+ If the <parameter>vars</parameter> argument is specified, it must
+ be a JSON object, and its fields provide named values to be
+ substituted into the <type>jsonpath</type> expression.
+ If the <parameter>silent</parameter> argument is specified and
+ is <literal>true</literal>, the function suppresses the same errors
+ as the <literal>@?</literal> and <literal>@@</literal> operators do.
+ </para>
+ <para>
+ <literal>jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_match</primary>
+ </indexterm>
+ <function>jsonb_path_match</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns the result of a JSON path predicate check for the specified
+ JSON value. Only the first item of the result is taken into account.
+ If the result is not Boolean, then <literal>NULL</literal> is returned.
+ The optional <parameter>vars</parameter>
+ and <parameter>silent</parameter> arguments act the same as
+ for <function>jsonb_path_exists</function>.
+ </para>
+ <para>
+ <literal>jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min &amp;&amp; @ &lt;= $max))', '{"min":2, "max":4}')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_query</primary>
+ </indexterm>
+ <function>jsonb_path_query</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>setof jsonb</returnvalue>
+ </para>
+ <para>
+ Returns all JSON items returned by the JSON path for the specified
+ JSON value.
+ The optional <parameter>vars</parameter>
+ and <parameter>silent</parameter> arguments act the same as
+ for <function>jsonb_path_exists</function>.
+ </para>
+ <para>
+ <literal>select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ jsonb_path_query
+------------------
+ 2
+ 3
+ 4
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_query_array</primary>
+ </indexterm>
+ <function>jsonb_path_query_array</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Returns all JSON items returned by the JSON path for the specified
+ JSON value, as a JSON array.
+ The optional <parameter>vars</parameter>
+ and <parameter>silent</parameter> arguments act the same as
+ for <function>jsonb_path_exists</function>.
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</literal>
+ <returnvalue>[2, 3, 4]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_query_first</primary>
+ </indexterm>
+ <function>jsonb_path_query_first</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Returns the first JSON item returned by the JSON path for the
+ specified JSON value. Returns <literal>NULL</literal> if there are no
+ results.
+ The optional <parameter>vars</parameter>
+ and <parameter>silent</parameter> arguments act the same as
+ for <function>jsonb_path_exists</function>.
+ </para>
+ <para>
+ <literal>jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_exists_tz</primary>
+ </indexterm>
+ <function>jsonb_path_exists_tz</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_match_tz</primary>
+ </indexterm>
+ <function>jsonb_path_match_tz</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_query_tz</primary>
+ </indexterm>
+ <function>jsonb_path_query_tz</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>setof jsonb</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_query_array_tz</primary>
+ </indexterm>
+ <function>jsonb_path_query_array_tz</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_path_query_first_tz</primary>
+ </indexterm>
+ <function>jsonb_path_query_first_tz</function> ( <parameter>target</parameter> <type>jsonb</type>, <parameter>path</parameter> <type>jsonpath</type> <optional>, <parameter>vars</parameter> <type>jsonb</type> <optional>, <parameter>silent</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ These functions act like their counterparts described above without
+ the <literal>_tz</literal> suffix, except that these functions support
+ comparisons of date/time values that require timezone-aware
+ conversions. The example below requires interpretation of the
+ date-only value <literal>2015-08-02</literal> as a timestamp with time
+ zone, so the result depends on the current
+ <xref linkend="guc-timezone"/> setting. Due to this dependency, these
+ functions are marked as stable, which means these functions cannot be
+ used in indexes. Their counterparts are immutable, and so can be used
+ in indexes; but they will throw errors if asked to make such
+ comparisons.
+ </para>
+ <para>
+ <literal>jsonb_path_exists_tz('["2015-08-01 12:00:00-05"]', '$[*] ? (@.datetime() &lt; "2015-08-02".datetime())')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>jsonb_pretty</primary>
+ </indexterm>
+ <function>jsonb_pretty</function> ( <type>jsonb</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts the given JSON value to pretty-printed, indented text.
+ </para>
+ <para>
+ <literal>jsonb_pretty('[{"f1":1,"f2":null}, 2]')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+[
+ {
+ "f1": 1,
+ "f2": null
+ },
+ 2
+]
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_typeof</primary>
+ </indexterm>
+ <function>json_typeof</function> ( <type>json</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_typeof</primary>
+ </indexterm>
+ <function>jsonb_typeof</function> ( <type>jsonb</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the type of the top-level JSON value as a text string.
+ Possible types are
+ <literal>object</literal>, <literal>array</literal>,
+ <literal>string</literal>, <literal>number</literal>,
+ <literal>boolean</literal>, and <literal>null</literal>.
+ (The <literal>null</literal> result should not be confused
+ with an SQL NULL; see the examples.)
+ </para>
+ <para>
+ <literal>json_typeof('-123.4')</literal>
+ <returnvalue>number</returnvalue>
+ </para>
+ <para>
+ <literal>json_typeof('null'::json)</literal>
+ <returnvalue>null</returnvalue>
+ </para>
+ <para>
+ <literal>json_typeof(NULL::json) IS NULL</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="functions-sqljson-path">
+ <title>The SQL/JSON Path Language</title>
+
+ <indexterm zone="functions-sqljson-path">
+ <primary>SQL/JSON path language</primary>
+ </indexterm>
+
+ <para>
+ SQL/JSON path expressions specify the items to be retrieved
+ from the JSON data, similar to XPath expressions used
+ for SQL access to XML. In <productname>PostgreSQL</productname>,
+ path expressions are implemented as the <type>jsonpath</type>
+ data type and can use any elements described in
+ <xref linkend="datatype-jsonpath"/>.
+ </para>
+
+ <para>
+ JSON query functions and operators
+ pass the provided path expression to the <firstterm>path engine</firstterm>
+ for evaluation. If the expression matches the queried JSON data,
+ the corresponding JSON item, or set of items, is returned.
+ Path expressions are written in the SQL/JSON path language
+ and can include arithmetic expressions and functions.
+ </para>
+
+ <para>
+ A path expression consists of a sequence of elements allowed
+ by the <type>jsonpath</type> data type.
+ The path expression is normally evaluated from left to right, but
+ you can use parentheses to change the order of operations.
+ If the evaluation is successful, a sequence of JSON items is produced,
+ and the evaluation result is returned to the JSON query function
+ that completes the specified computation.
+ </para>
+
+ <para>
+ To refer to the JSON value being queried (the
+ <firstterm>context item</firstterm>), use the <literal>$</literal> variable
+ in the path expression. It can be followed by one or more
+ <link linkend="type-jsonpath-accessors">accessor operators</link>,
+ which go down the JSON structure level by level to retrieve sub-items
+ of the context item. Each operator that follows deals with the
+ result of the previous evaluation step.
+ </para>
+
+ <para>
+ For example, suppose you have some JSON data from a GPS tracker that you
+ would like to parse, such as:
+<programlisting>
+{
+ "track": {
+ "segments": [
+ {
+ "location": [ 47.763, 13.4034 ],
+ "start time": "2018-10-14 10:05:14",
+ "HR": 73
+ },
+ {
+ "location": [ 47.706, 13.2635 ],
+ "start time": "2018-10-14 10:39:21",
+ "HR": 135
+ }
+ ]
+ }
+}
+</programlisting>
+ </para>
+
+ <para>
+ To retrieve the available track segments, you need to use the
+ <literal>.<replaceable>key</replaceable></literal> accessor
+ operator to descend through surrounding JSON objects:
+<programlisting>
+$.track.segments
+</programlisting>
+ </para>
+
+ <para>
+ To retrieve the contents of an array, you typically use the
+ <literal>[*]</literal> operator. For example,
+ the following path will return the location coordinates for all
+ the available track segments:
+<programlisting>
+$.track.segments[*].location
+</programlisting>
+ </para>
+
+ <para>
+ To return the coordinates of the first segment only, you can
+ specify the corresponding subscript in the <literal>[]</literal>
+ accessor operator. Recall that JSON array indexes are 0-relative:
+<programlisting>
+$.track.segments[0].location
+</programlisting>
+ </para>
+
+ <para>
+ The result of each path evaluation step can be processed
+ by one or more <type>jsonpath</type> operators and methods
+ listed in <xref linkend="functions-sqljson-path-operators"/>.
+ Each method name must be preceded by a dot. For example,
+ you can get the size of an array:
+<programlisting>
+$.track.segments.size()
+</programlisting>
+ More examples of using <type>jsonpath</type> operators
+ and methods within path expressions appear below in
+ <xref linkend="functions-sqljson-path-operators"/>.
+ </para>
+
+ <para>
+ When defining a path, you can also use one or more
+ <firstterm>filter expressions</firstterm> that work similarly to the
+ <literal>WHERE</literal> clause in SQL. A filter expression begins with
+ a question mark and provides a condition in parentheses:
+
+<programlisting>
+? (<replaceable>condition</replaceable>)
+</programlisting>
+ </para>
+
+ <para>
+ Filter expressions must be written just after the path evaluation step
+ to which they should apply. The result of that step is filtered to include
+ only those items that satisfy the provided condition. SQL/JSON defines
+ three-valued logic, so the condition can be <literal>true</literal>, <literal>false</literal>,
+ or <literal>unknown</literal>. The <literal>unknown</literal> value
+ plays the same role as SQL <literal>NULL</literal> and can be tested
+ for with the <literal>is unknown</literal> predicate. Further path
+ evaluation steps use only those items for which the filter expression
+ returned <literal>true</literal>.
+ </para>
+
+ <para>
+ The functions and operators that can be used in filter expressions are
+ listed in <xref linkend="functions-sqljson-filter-ex-table"/>. Within a
+ filter expression, the <literal>@</literal> variable denotes the value
+ being filtered (i.e., one result of the preceding path step). You can
+ write accessor operators after <literal>@</literal> to retrieve component
+ items.
+ </para>
+
+ <para>
+ For example, suppose you would like to retrieve all heart rate values higher
+ than 130. You can achieve this using the following expression:
+<programlisting>
+$.track.segments[*].HR ? (@ &gt; 130)
+</programlisting>
+ </para>
+
+ <para>
+ To get the start times of segments with such values, you have to
+ filter out irrelevant segments before returning the start times, so the
+ filter expression is applied to the previous step, and the path used
+ in the condition is different:
+<programlisting>
+$.track.segments[*] ? (@.HR &gt; 130)."start time"
+</programlisting>
+ </para>
+
+ <para>
+ You can use several filter expressions in sequence, if required. For
+ example, the following expression selects start times of all segments that
+ contain locations with relevant coordinates and high heart rate values:
+<programlisting>
+$.track.segments[*] ? (@.location[1] &lt; 13.4) ? (@.HR &gt; 130)."start time"
+</programlisting>
+ </para>
+
+ <para>
+ Using filter expressions at different nesting levels is also allowed.
+ The following example first filters all segments by location, and then
+ returns high heart rate values for these segments, if available:
+<programlisting>
+$.track.segments[*] ? (@.location[1] &lt; 13.4).HR ? (@ &gt; 130)
+</programlisting>
+ </para>
+
+ <para>
+ You can also nest filter expressions within each other:
+<programlisting>
+$.track ? (exists(@.segments[*] ? (@.HR &gt; 130))).segments.size()
+</programlisting>
+ This expression returns the size of the track if it contains any
+ segments with high heart rate values, or an empty sequence otherwise.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s implementation of the SQL/JSON path
+ language has the following deviations from the SQL/JSON standard:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A path expression can be a Boolean predicate, although the SQL/JSON
+ standard allows predicates only in filters. This is necessary for
+ implementation of the <literal>@@</literal> operator. For example,
+ the following <type>jsonpath</type> expression is valid in
+ <productname>PostgreSQL</productname>:
+<programlisting>
+$.track.segments[*].HR &lt; 70
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ There are minor differences in the interpretation of regular
+ expression patterns used in <literal>like_regex</literal> filters, as
+ described in <xref linkend="jsonpath-regular-expressions"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <sect3 id="strict-and-lax-modes">
+ <title>Strict and Lax Modes</title>
+ <para>
+ When you query JSON data, the path expression may not match the
+ actual JSON data structure. An attempt to access a non-existent
+ member of an object or element of an array results in a
+ structural error. SQL/JSON path expressions have two modes
+ of handling structural errors:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ lax (default) &mdash; the path engine implicitly adapts
+ the queried data to the specified path.
+ Any remaining structural errors are suppressed and converted
+ to empty SQL/JSON sequences.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ strict &mdash; if a structural error occurs, an error is raised.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The lax mode facilitates matching of a JSON document structure and path
+ expression if the JSON data does not conform to the expected schema.
+ If an operand does not match the requirements of a particular operation,
+ it can be automatically wrapped as an SQL/JSON array or unwrapped by
+ converting its elements into an SQL/JSON sequence before performing
+ this operation. Besides, comparison operators automatically unwrap their
+ operands in the lax mode, so you can compare SQL/JSON arrays
+ out-of-the-box. An array of size 1 is considered equal to its sole element.
+ Automatic unwrapping is not performed only when:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The path expression contains <literal>type()</literal> or
+ <literal>size()</literal> methods that return the type
+ and the number of elements in the array, respectively.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The queried JSON data contain nested arrays. In this case, only
+ the outermost array is unwrapped, while all the inner arrays
+ remain unchanged. Thus, implicit unwrapping can only go one
+ level down within each path evaluation step.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ For example, when querying the GPS data listed above, you can
+ abstract from the fact that it stores an array of segments
+ when using the lax mode:
+<programlisting>
+lax $.track.segments.location
+</programlisting>
+ </para>
+
+ <para>
+ In the strict mode, the specified path must exactly match the structure of
+ the queried JSON document to return an SQL/JSON item, so using this
+ path expression will cause an error. To get the same result as in
+ the lax mode, you have to explicitly unwrap the
+ <literal>segments</literal> array:
+<programlisting>
+strict $.track.segments[*].location
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>.**</literal> accessor can lead to surprising results
+ when using the lax mode. For instance, the following query selects every
+ <literal>HR</literal> value twice:
+<programlisting>
+lax $.**.HR
+</programlisting>
+ This happens because the <literal>.**</literal> accessor selects both
+ the <literal>segments</literal> array and each of its elements, while
+ the <literal>.HR</literal> accessor automatically unwraps arrays when
+ using the lax mode. To avoid surprising results, we recommend using
+ the <literal>.**</literal> accessor only in the strict mode. The
+ following query selects each <literal>HR</literal> value just once:
+<programlisting>
+strict $.**.HR
+</programlisting>
+ </para>
+
+ </sect3>
+
+ <sect3 id="functions-sqljson-path-operators">
+ <title>SQL/JSON Path Operators and Methods</title>
+
+ <para>
+ <xref linkend="functions-sqljson-op-table"/> shows the operators and
+ methods available in <type>jsonpath</type>. Note that while the unary
+ operators and methods can be applied to multiple values resulting from a
+ preceding path step, the binary operators (addition etc.) can only be
+ applied to single values.
+ </para>
+
+ <table id="functions-sqljson-op-table">
+ <title><type>jsonpath</type> Operators and Methods</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator/Method
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>+</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Addition
+ </para>
+ <para>
+ <literal>jsonb_path_query('[2]', '$[0] + 3')</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>+</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Unary plus (no operation); unlike addition, this can iterate over
+ multiple values
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x')</literal>
+ <returnvalue>[2, 3, 4]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>-</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Subtraction
+ </para>
+ <para>
+ <literal>jsonb_path_query('[2]', '7 - $[0]')</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>-</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Negation; unlike subtraction, this can iterate over
+ multiple values
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('{"x": [2,3,4]}', '- $.x')</literal>
+ <returnvalue>[-2, -3, -4]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>*</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Multiplication
+ </para>
+ <para>
+ <literal>jsonb_path_query('[4]', '2 * $[0]')</literal>
+ <returnvalue>8</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>/</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Division
+ </para>
+ <para>
+ <literal>jsonb_path_query('[8.5]', '$[0] / 2')</literal>
+ <returnvalue>4.2500000000000000</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>%</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Modulo (remainder)
+ </para>
+ <para>
+ <literal>jsonb_path_query('[32]', '$[0] % 10')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>.</literal> <literal>type()</literal>
+ <returnvalue><replaceable>string</replaceable></returnvalue>
+ </para>
+ <para>
+ Type of the JSON item (see <function>json_typeof</function>)
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, "2", {}]', '$[*].type()')</literal>
+ <returnvalue>["number", "string", "object"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>.</literal> <literal>size()</literal>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Size of the JSON item (number of array elements, or 1 if not an
+ array)
+ </para>
+ <para>
+ <literal>jsonb_path_query('{"m": [11, 15]}', '$.m.size()')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>.</literal> <literal>double()</literal>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Approximate floating-point number converted from a JSON number or
+ string
+ </para>
+ <para>
+ <literal>jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2')</literal>
+ <returnvalue>3.8</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>.</literal> <literal>ceiling()</literal>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Nearest integer greater than or equal to the given number
+ </para>
+ <para>
+ <literal>jsonb_path_query('{"h": 1.3}', '$.h.ceiling()')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>.</literal> <literal>floor()</literal>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Nearest integer less than or equal to the given number
+ </para>
+ <para>
+ <literal>jsonb_path_query('{"h": 1.7}', '$.h.floor()')</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>.</literal> <literal>abs()</literal>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Absolute value of the given number
+ </para>
+ <para>
+ <literal>jsonb_path_query('{"z": -0.3}', '$.z.abs()')</literal>
+ <returnvalue>0.3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>string</replaceable> <literal>.</literal> <literal>datetime()</literal>
+ <returnvalue><replaceable>datetime_type</replaceable></returnvalue>
+ (see note)
+ </para>
+ <para>
+ Date/time value converted from a string
+ </para>
+ <para>
+ <literal>jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() &lt; "2015-08-2".datetime())')</literal>
+ <returnvalue>"2015-8-1"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>string</replaceable> <literal>.</literal> <literal>datetime(<replaceable>template</replaceable>)</literal>
+ <returnvalue><replaceable>datetime_type</replaceable></returnvalue>
+ (see note)
+ </para>
+ <para>
+ Date/time value converted from a string using the
+ specified <function>to_timestamp</function> template
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")')</literal>
+ <returnvalue>["12:30:00", "18:40:00"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>object</replaceable> <literal>.</literal> <literal>keyvalue()</literal>
+ <returnvalue><replaceable>array</replaceable></returnvalue>
+ </para>
+ <para>
+ The object's key-value pairs, represented as an array of objects
+ containing three fields: <literal>"key"</literal>,
+ <literal>"value"</literal>, and <literal>"id"</literal>;
+ <literal>"id"</literal> is a unique identifier of the object the
+ key-value pair belongs to
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()')</literal>
+ <returnvalue>[{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}]</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The result type of the <literal>datetime()</literal> and
+ <literal>datetime(<replaceable>template</replaceable>)</literal>
+ methods can be <type>date</type>, <type>timetz</type>, <type>time</type>,
+ <type>timestamptz</type>, or <type>timestamp</type>.
+ Both methods determine their result type dynamically.
+ </para>
+ <para>
+ The <literal>datetime()</literal> method sequentially tries to
+ match its input string to the ISO formats
+ for <type>date</type>, <type>timetz</type>, <type>time</type>,
+ <type>timestamptz</type>, and <type>timestamp</type>. It stops on
+ the first matching format and emits the corresponding data type.
+ </para>
+ <para>
+ The <literal>datetime(<replaceable>template</replaceable>)</literal>
+ method determines the result type according to the fields used in the
+ provided template string.
+ </para>
+ <para>
+ The <literal>datetime()</literal> and
+ <literal>datetime(<replaceable>template</replaceable>)</literal> methods
+ use the same parsing rules as the <literal>to_timestamp</literal> SQL
+ function does (see <xref linkend="functions-formatting"/>), with three
+ exceptions. First, these methods don't allow unmatched template
+ patterns. Second, only the following separators are allowed in the
+ template string: minus sign, period, solidus (slash), comma, apostrophe,
+ semicolon, colon and space. Third, separators in the template string
+ must exactly match the input string.
+ </para>
+ <para>
+ If different date/time types need to be compared, an implicit cast is
+ applied. A <type>date</type> value can be cast to <type>timestamp</type>
+ or <type>timestamptz</type>, <type>timestamp</type> can be cast to
+ <type>timestamptz</type>, and <type>time</type> to <type>timetz</type>.
+ However, all but the first of these conversions depend on the current
+ <xref linkend="guc-timezone"/> setting, and thus can only be performed
+ within timezone-aware <type>jsonpath</type> functions.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="functions-sqljson-filter-ex-table"/> shows the available
+ filter expression elements.
+ </para>
+
+ <table id="functions-sqljson-filter-ex-table">
+ <title><type>jsonpath</type> Filter Expression Elements</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Predicate/Value
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>==</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Equality comparison (this, and the other comparison operators, work on
+ all JSON scalar values)
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)')</literal>
+ <returnvalue>[1, 1]</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == "a")')</literal>
+ <returnvalue>["a"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>!=</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <replaceable>value</replaceable> <literal>&lt;&gt;</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Non-equality comparison
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)')</literal>
+ <returnvalue>[2, 3]</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ &lt;&gt; "b")')</literal>
+ <returnvalue>["a", "c"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>&lt;</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Less-than comparison
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ &lt; 2)')</literal>
+ <returnvalue>[1]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>&lt;=</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Less-than-or-equal-to comparison
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ &lt;= "b")')</literal>
+ <returnvalue>["a", "b"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>&gt;</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Greater-than comparison
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ &gt; 2)')</literal>
+ <returnvalue>[3]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>&gt;=</literal> <replaceable>value</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Greater-than-or-equal-to comparison
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ &gt;= 2)')</literal>
+ <returnvalue>[2, 3]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>true</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ JSON constant <literal>true</literal>
+ </para>
+ <para>
+ <literal>jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)')</literal>
+ <returnvalue>{"name": "Chris", "parent": true}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>false</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ JSON constant <literal>false</literal>
+ </para>
+ <para>
+ <literal>jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)')</literal>
+ <returnvalue>{"name": "John", "parent": false}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>null</literal>
+ <returnvalue><replaceable>value</replaceable></returnvalue>
+ </para>
+ <para>
+ JSON constant <literal>null</literal> (note that, unlike in SQL,
+ comparison to <literal>null</literal> works normally)
+ </para>
+ <para>
+ <literal>jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name')</literal>
+ <returnvalue>"Mary"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>boolean</replaceable> <literal>&amp;&amp;</literal> <replaceable>boolean</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Boolean AND
+ </para>
+ <para>
+ <literal>jsonb_path_query('[1, 3, 7]', '$[*] ? (@ &gt; 1 &amp;&amp; @ &lt; 5)')</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>boolean</replaceable> <literal>||</literal> <replaceable>boolean</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Boolean OR
+ </para>
+ <para>
+ <literal>jsonb_path_query('[1, 3, 7]', '$[*] ? (@ &lt; 1 || @ &gt; 5)')</literal>
+ <returnvalue>7</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>!</literal> <replaceable>boolean</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Boolean NOT
+ </para>
+ <para>
+ <literal>jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ &lt; 5))')</literal>
+ <returnvalue>7</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>boolean</replaceable> <literal>is unknown</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether a Boolean condition is <literal>unknown</literal>.
+ </para>
+ <para>
+ <literal>jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ > 0) is unknown)')</literal>
+ <returnvalue>"foo"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>string</replaceable> <literal>like_regex</literal> <replaceable>string</replaceable> <optional> <literal>flag</literal> <replaceable>string</replaceable> </optional>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether the first operand matches the regular expression
+ given by the second operand, optionally with modifications
+ described by a string of <literal>flag</literal> characters (see
+ <xref linkend="jsonpath-regular-expressions"/>).
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")')</literal>
+ <returnvalue>["abc", "abdacb"]</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")')</literal>
+ <returnvalue>["abc", "aBdC", "abdacb"]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>string</replaceable> <literal>starts with</literal> <replaceable>string</replaceable>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether the second operand is an initial substring of the first
+ operand.
+ </para>
+ <para>
+ <literal>jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")')</literal>
+ <returnvalue>"John Smith"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>exists</literal> <literal>(</literal> <replaceable>path_expression</replaceable> <literal>)</literal>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether a path expression matches at least one SQL/JSON item.
+ Returns <literal>unknown</literal> if the path expression would result
+ in an error; the second example uses this to avoid a no-such-key error
+ in strict mode.
+ </para>
+ <para>
+ <literal>jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] &gt; 2)))')</literal>
+ <returnvalue>[2, 4]</returnvalue>
+ </para>
+ <para>
+ <literal>jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name')</literal>
+ <returnvalue>[]</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect3>
+
+ <sect3 id="jsonpath-regular-expressions">
+ <title>SQL/JSON Regular Expressions</title>
+
+ <indexterm zone="jsonpath-regular-expressions">
+ <primary><literal>LIKE_REGEX</literal></primary>
+ <secondary>in SQL/JSON</secondary>
+ </indexterm>
+
+ <para>
+ SQL/JSON path expressions allow matching text to a regular expression
+ with the <literal>like_regex</literal> filter. For example, the
+ following SQL/JSON path query would case-insensitively match all
+ strings in an array that start with an English vowel:
+<programlisting>
+$[*] ? (@ like_regex "^[aeiou]" flag "i")
+</programlisting>
+ </para>
+
+ <para>
+ The optional <literal>flag</literal> string may include one or more of
+ the characters
+ <literal>i</literal> for case-insensitive match,
+ <literal>m</literal> to allow <literal>^</literal>
+ and <literal>$</literal> to match at newlines,
+ <literal>s</literal> to allow <literal>.</literal> to match a newline,
+ and <literal>q</literal> to quote the whole pattern (reducing the
+ behavior to a simple substring match).
+ </para>
+
+ <para>
+ The SQL/JSON standard borrows its definition for regular expressions
+ from the <literal>LIKE_REGEX</literal> operator, which in turn uses the
+ XQuery standard. PostgreSQL does not currently support the
+ <literal>LIKE_REGEX</literal> operator. Therefore,
+ the <literal>like_regex</literal> filter is implemented using the
+ POSIX regular expression engine described in
+ <xref linkend="functions-posix-regexp"/>. This leads to various minor
+ discrepancies from standard SQL/JSON behavior, which are cataloged in
+ <xref linkend="posix-vs-xquery"/>.
+ Note, however, that the flag-letter incompatibilities described there
+ do not apply to SQL/JSON, as it translates the XQuery flag letters to
+ match what the POSIX engine expects.
+ </para>
+
+ <para>
+ Keep in mind that the pattern argument of <literal>like_regex</literal>
+ is a JSON path string literal, written according to the rules given in
+ <xref linkend="datatype-jsonpath"/>. This means in particular that any
+ backslashes you want to use in the regular expression must be doubled.
+ For example, to match string values of the root document that contain
+ only digits:
+<programlisting>
+$.* ? (@ like_regex "^\\d+$")
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="functions-sequence">
+ <title>Sequence Manipulation Functions</title>
+
+ <indexterm>
+ <primary>sequence</primary>
+ </indexterm>
+
+ <para>
+ This section describes functions for operating on <firstterm>sequence
+ objects</firstterm>, also called sequence generators or just sequences.
+ Sequence objects are special single-row tables created with <xref
+ linkend="sql-createsequence"/>.
+ Sequence objects are commonly used to generate unique identifiers
+ for rows of a table. The sequence functions, listed in <xref
+ linkend="functions-sequence-table"/>, provide simple, multiuser-safe
+ methods for obtaining successive sequence values from sequence
+ objects.
+ </para>
+
+ <table id="functions-sequence-table">
+ <title>Sequence Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>nextval</primary>
+ </indexterm>
+ <function>nextval</function> ( <type>regclass</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Advances the sequence object to its next value and returns that value.
+ This is done atomically: even if multiple sessions
+ execute <function>nextval</function> concurrently, each will safely
+ receive a distinct sequence value.
+ If the sequence object has been created with default parameters,
+ successive <function>nextval</function> calls will return successive
+ values beginning with 1. Other behaviors can be obtained by using
+ appropriate parameters in the <xref linkend="sql-createsequence"/>
+ command.
+ </para>
+ <para>
+ This function requires <literal>USAGE</literal>
+ or <literal>UPDATE</literal> privilege on the sequence.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>setval</primary>
+ </indexterm>
+ <function>setval</function> ( <type>regclass</type>, <type>bigint</type> <optional>, <type>boolean</type> </optional> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Sets the sequence object's current value, and optionally
+ its <literal>is_called</literal> flag. The two-parameter
+ form sets the sequence's <literal>last_value</literal> field to the
+ specified value and sets its <literal>is_called</literal> field to
+ <literal>true</literal>, meaning that the next
+ <function>nextval</function> will advance the sequence before
+ returning a value. The value that will be reported
+ by <function>currval</function> is also set to the specified value.
+ In the three-parameter form, <literal>is_called</literal> can be set
+ to either <literal>true</literal>
+ or <literal>false</literal>. <literal>true</literal> has the same
+ effect as the two-parameter form. If it is set
+ to <literal>false</literal>, the next <function>nextval</function>
+ will return exactly the specified value, and sequence advancement
+ commences with the following <function>nextval</function>.
+ Furthermore, the value reported by <function>currval</function> is not
+ changed in this case. For example,
+<programlisting>
+SELECT setval('myseq', 42); <lineannotation>Next <function>nextval</function> will return 43</lineannotation>
+SELECT setval('myseq', 42, true); <lineannotation>Same as above</lineannotation>
+SELECT setval('myseq', 42, false); <lineannotation>Next <function>nextval</function> will return 42</lineannotation>
+</programlisting>
+ The result returned by <function>setval</function> is just the value of its
+ second argument.
+ </para>
+ <para>
+ This function requires <literal>UPDATE</literal> privilege on the
+ sequence.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>currval</primary>
+ </indexterm>
+ <function>currval</function> ( <type>regclass</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the value most recently obtained
+ by <function>nextval</function> for this sequence in the current
+ session. (An error is reported if <function>nextval</function> has
+ never been called for this sequence in this session.) Because this is
+ returning a session-local value, it gives a predictable answer whether
+ or not other sessions have executed <function>nextval</function> since
+ the current session did.
+ </para>
+ <para>
+ This function requires <literal>USAGE</literal>
+ or <literal>SELECT</literal> privilege on the sequence.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lastval</primary>
+ </indexterm>
+ <function>lastval</function> ()
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the value most recently returned by
+ <function>nextval</function> in the current session. This function is
+ identical to <function>currval</function>, except that instead
+ of taking the sequence name as an argument it refers to whichever
+ sequence <function>nextval</function> was most recently applied to
+ in the current session. It is an error to call
+ <function>lastval</function> if <function>nextval</function>
+ has not yet been called in the current session.
+ </para>
+ <para>
+ This function requires <literal>USAGE</literal>
+ or <literal>SELECT</literal> privilege on the last used sequence.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <caution>
+ <para>
+ To avoid blocking concurrent transactions that obtain numbers from
+ the same sequence, the value obtained by <function>nextval</function>
+ is not reclaimed for re-use if the calling transaction later aborts.
+ This means that transaction aborts or database crashes can result in
+ gaps in the sequence of assigned values. That can happen without a
+ transaction abort, too. For example an <command>INSERT</command> with
+ an <literal>ON CONFLICT</literal> clause will compute the to-be-inserted
+ tuple, including doing any required <function>nextval</function>
+ calls, before detecting any conflict that would cause it to follow
+ the <literal>ON CONFLICT</literal> rule instead.
+ Thus, <productname>PostgreSQL</productname> sequence
+ objects <emphasis>cannot be used to obtain <quote>gapless</quote>
+ sequences</emphasis>.
+ </para>
+
+ <para>
+ Likewise, sequence state changes made by <function>setval</function>
+ are immediately visible to other transactions, and are not undone if
+ the calling transaction rolls back.
+ </para>
+
+ <para>
+ If the database cluster crashes before committing a transaction
+ containing a <function>nextval</function>
+ or <function>setval</function> call, the sequence state change might
+ not have made its way to persistent storage, so that it is uncertain
+ whether the sequence will have its original or updated state after the
+ cluster restarts. This is harmless for usage of the sequence within
+ the database, since other effects of uncommitted transactions will not
+ be visible either. However, if you wish to use a sequence value for
+ persistent outside-the-database purposes, make sure that the
+ <function>nextval</function> call has been committed before doing so.
+ </para>
+ </caution>
+
+ <para>
+ The sequence to be operated on by a sequence function is specified by
+ a <type>regclass</type> argument, which is simply the OID of the sequence in the
+ <structname>pg_class</structname> system catalog. You do not have to look up the
+ OID by hand, however, since the <type>regclass</type> data type's input
+ converter will do the work for you. See <xref linkend="datatype-oid"/>
+ for details.
+ </para>
+ </sect1>
+
+
+ <sect1 id="functions-conditional">
+ <title>Conditional Expressions</title>
+
+ <indexterm>
+ <primary>CASE</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>conditional expression</primary>
+ </indexterm>
+
+ <para>
+ This section describes the <acronym>SQL</acronym>-compliant conditional expressions
+ available in <productname>PostgreSQL</productname>.
+ </para>
+
+ <tip>
+ <para>
+ If your needs go beyond the capabilities of these conditional
+ expressions, you might want to consider writing a server-side function
+ in a more expressive programming language.
+ </para>
+ </tip>
+
+ <note>
+ <para>
+ Although <token>COALESCE</token>, <token>GREATEST</token>, and
+ <token>LEAST</token> are syntactically similar to functions, they are
+ not ordinary functions, and thus cannot be used with explicit
+ <token>VARIADIC</token> array arguments.
+ </para>
+ </note>
+
+ <sect2 id="functions-case">
+ <title><literal>CASE</literal></title>
+
+ <para>
+ The <acronym>SQL</acronym> <token>CASE</token> expression is a
+ generic conditional expression, similar to if/else statements in
+ other programming languages:
+
+<synopsis>
+CASE WHEN <replaceable>condition</replaceable> THEN <replaceable>result</replaceable>
+ <optional>WHEN ...</optional>
+ <optional>ELSE <replaceable>result</replaceable></optional>
+END
+</synopsis>
+
+ <token>CASE</token> clauses can be used wherever
+ an expression is valid. Each <replaceable>condition</replaceable> is an
+ expression that returns a <type>boolean</type> result. If the condition's
+ result is true, the value of the <token>CASE</token> expression is the
+ <replaceable>result</replaceable> that follows the condition, and the
+ remainder of the <token>CASE</token> expression is not processed. If the
+ condition's result is not true, any subsequent <token>WHEN</token> clauses
+ are examined in the same manner. If no <token>WHEN</token>
+ <replaceable>condition</replaceable> yields true, the value of the
+ <token>CASE</token> expression is the <replaceable>result</replaceable> of the
+ <token>ELSE</token> clause. If the <token>ELSE</token> clause is
+ omitted and no condition is true, the result is null.
+ </para>
+
+ <para>
+ An example:
+<screen>
+SELECT * FROM test;
+
+ a
+---
+ 1
+ 2
+ 3
+
+
+SELECT a,
+ CASE WHEN a=1 THEN 'one'
+ WHEN a=2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
+ a | case
+---+-------
+ 1 | one
+ 2 | two
+ 3 | other
+</screen>
+ </para>
+
+ <para>
+ The data types of all the <replaceable>result</replaceable>
+ expressions must be convertible to a single output type.
+ See <xref linkend="typeconv-union-case"/> for more details.
+ </para>
+
+ <para>
+ There is a <quote>simple</quote> form of <token>CASE</token> expression
+ that is a variant of the general form above:
+
+<synopsis>
+CASE <replaceable>expression</replaceable>
+ WHEN <replaceable>value</replaceable> THEN <replaceable>result</replaceable>
+ <optional>WHEN ...</optional>
+ <optional>ELSE <replaceable>result</replaceable></optional>
+END
+</synopsis>
+
+ The first
+ <replaceable>expression</replaceable> is computed, then compared to
+ each of the <replaceable>value</replaceable> expressions in the
+ <token>WHEN</token> clauses until one is found that is equal to it. If
+ no match is found, the <replaceable>result</replaceable> of the
+ <token>ELSE</token> clause (or a null value) is returned. This is similar
+ to the <function>switch</function> statement in C.
+ </para>
+
+ <para>
+ The example above can be written using the simple
+ <token>CASE</token> syntax:
+<screen>
+SELECT a,
+ CASE a WHEN 1 THEN 'one'
+ WHEN 2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
+ a | case
+---+-------
+ 1 | one
+ 2 | two
+ 3 | other
+</screen>
+ </para>
+
+ <para>
+ A <token>CASE</token> expression does not evaluate any subexpressions
+ that are not needed to determine the result. For example, this is a
+ possible way of avoiding a division-by-zero failure:
+<programlisting>
+SELECT ... WHERE CASE WHEN x &lt;&gt; 0 THEN y/x &gt; 1.5 ELSE false END;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ As described in <xref linkend="syntax-express-eval"/>, there are various
+ situations in which subexpressions of an expression are evaluated at
+ different times, so that the principle that <quote><token>CASE</token>
+ evaluates only necessary subexpressions</quote> is not ironclad. For
+ example a constant <literal>1/0</literal> subexpression will usually result in
+ a division-by-zero failure at planning time, even if it's within
+ a <token>CASE</token> arm that would never be entered at run time.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="functions-coalesce-nvl-ifnull">
+ <title><literal>COALESCE</literal></title>
+
+ <indexterm>
+ <primary>COALESCE</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NVL</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IFNULL</primary>
+ </indexterm>
+
+<synopsis>
+<function>COALESCE</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+
+ <para>
+ The <function>COALESCE</function> function returns the first of its
+ arguments that is not null. Null is returned only if all arguments
+ are null. It is often used to substitute a default value for
+ null values when data is retrieved for display, for example:
+<programlisting>
+SELECT COALESCE(description, short_description, '(none)') ...
+</programlisting>
+ This returns <varname>description</varname> if it is not null, otherwise
+ <varname>short_description</varname> if it is not null, otherwise <literal>(none)</literal>.
+ </para>
+
+ <para>
+ The arguments must all be convertible to a common data type, which
+ will be the type of the result (see
+ <xref linkend="typeconv-union-case"/> for details).
+ </para>
+
+ <para>
+ Like a <token>CASE</token> expression, <function>COALESCE</function> only
+ evaluates the arguments that are needed to determine the result;
+ that is, arguments to the right of the first non-null argument are
+ not evaluated. This SQL-standard function provides capabilities similar
+ to <function>NVL</function> and <function>IFNULL</function>, which are used in some other
+ database systems.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-nullif">
+ <title><literal>NULLIF</literal></title>
+
+ <indexterm>
+ <primary>NULLIF</primary>
+ </indexterm>
+
+<synopsis>
+<function>NULLIF</function>(<replaceable>value1</replaceable>, <replaceable>value2</replaceable>)
+</synopsis>
+
+ <para>
+ The <function>NULLIF</function> function returns a null value if
+ <replaceable>value1</replaceable> equals <replaceable>value2</replaceable>;
+ otherwise it returns <replaceable>value1</replaceable>.
+ This can be used to perform the inverse operation of the
+ <function>COALESCE</function> example given above:
+<programlisting>
+SELECT NULLIF(value, '(none)') ...
+</programlisting>
+ In this example, if <literal>value</literal> is <literal>(none)</literal>,
+ null is returned, otherwise the value of <literal>value</literal>
+ is returned.
+ </para>
+
+ <para>
+ The two arguments must be of comparable types.
+ To be specific, they are compared exactly as if you had
+ written <literal><replaceable>value1</replaceable>
+ = <replaceable>value2</replaceable></literal>, so there must be a
+ suitable <literal>=</literal> operator available.
+ </para>
+
+ <para>
+ The result has the same type as the first argument &mdash; but there is
+ a subtlety. What is actually returned is the first argument of the
+ implied <literal>=</literal> operator, and in some cases that will have
+ been promoted to match the second argument's type. For
+ example, <literal>NULLIF(1, 2.2)</literal> yields <type>numeric</type>,
+ because there is no <type>integer</type> <literal>=</literal>
+ <type>numeric</type> operator,
+ only <type>numeric</type> <literal>=</literal> <type>numeric</type>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="functions-greatest-least">
+ <title><literal>GREATEST</literal> and <literal>LEAST</literal></title>
+
+ <indexterm>
+ <primary>GREATEST</primary>
+ </indexterm>
+ <indexterm>
+ <primary>LEAST</primary>
+ </indexterm>
+
+<synopsis>
+<function>GREATEST</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+<synopsis>
+<function>LEAST</function>(<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+
+ <para>
+ The <function>GREATEST</function> and <function>LEAST</function> functions select the
+ largest or smallest value from a list of any number of expressions.
+ The expressions must all be convertible to a common data type, which
+ will be the type of the result
+ (see <xref linkend="typeconv-union-case"/> for details). NULL values
+ in the list are ignored. The result will be NULL only if all the
+ expressions evaluate to NULL.
+ </para>
+
+ <para>
+ Note that <function>GREATEST</function> and <function>LEAST</function> are not in
+ the SQL standard, but are a common extension. Some other databases
+ make them return NULL if any argument is NULL, rather than only when
+ all are NULL.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="functions-array">
+ <title>Array Functions and Operators</title>
+
+ <para>
+ <xref linkend="array-operators-table"/> shows the specialized operators
+ available for array types.
+ In addition to those, the usual comparison operators shown in <xref
+ linkend="functions-comparison-op-table"/> are available for
+ arrays. The comparison operators compare the array contents
+ element-by-element, using the default B-tree comparison function for
+ the element data type, and sort based on the first difference.
+ In multidimensional arrays the elements are visited in row-major order
+ (last subscript varies most rapidly).
+ If the contents of two arrays are equal but the dimensionality is
+ different, the first difference in the dimensionality information
+ determines the sort order.
+ </para>
+
+ <table id="array-operators-table">
+ <title>Array Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyarray</type> <literal>@&gt;</literal> <type>anyarray</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first array contain the second, that is, does each element
+ appearing in the second array equal some element of the first array?
+ (Duplicates are not treated specially,
+ thus <literal>ARRAY[1]</literal> and <literal>ARRAY[1,1]</literal> are
+ each considered to contain the other.)
+ </para>
+ <para>
+ <literal>ARRAY[1,4,3] @&gt; ARRAY[3,1,3]</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyarray</type> <literal>&lt;@</literal> <type>anyarray</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first array contained by the second?
+ </para>
+ <para>
+ <literal>ARRAY[2,2,7] &lt;@ ARRAY[1,7,4,2,6]</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyarray</type> <literal>&amp;&amp;</literal> <type>anyarray</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do the arrays overlap, that is, have any elements in common?
+ </para>
+ <para>
+ <literal>ARRAY[1,4,3] &amp;&amp; ARRAY[2,1]</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatiblearray</type>
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Concatenates the two arrays. Concatenating a null or empty array is a
+ no-op; otherwise the arrays must have the same number of dimensions
+ (as illustrated by the first example) or differ in number of
+ dimensions by one (as illustrated by the second).
+ If the arrays are not of identical element types, they will be coerced
+ to a common type (see <xref linkend="typeconv-union-case"/>).
+ </para>
+ <para>
+ <literal>ARRAY[1,2,3] || ARRAY[4,5,6,7]</literal>
+ <returnvalue>{1,2,3,4,5,6,7}</returnvalue>
+ </para>
+ <para>
+ <literal>ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]]</literal>
+ <returnvalue>{{1,2,3},{4,5,6},{7,8,9.9}}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anycompatible</type> <literal>||</literal> <type>anycompatiblearray</type>
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Concatenates an element onto the front of an array (which must be
+ empty or one-dimensional).
+ </para>
+ <para>
+ <literal>3 || ARRAY[4,5,6]</literal>
+ <returnvalue>{3,4,5,6}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatible</type>
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Concatenates an element onto the end of an array (which must be
+ empty or one-dimensional).
+ </para>
+ <para>
+ <literal>ARRAY[4,5,6] || 7</literal>
+ <returnvalue>{4,5,6,7}</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ See <xref linkend="arrays"/> for more details about array operator
+ behavior. See <xref linkend="indexes-types"/> for more details about
+ which operators support indexed operations.
+ </para>
+
+ <para>
+ <xref linkend="array-functions-table"/> shows the functions
+ available for use with array types. See <xref linkend="arrays"/>
+ for more information and examples of the use of these functions.
+ </para>
+
+ <table id="array-functions-table">
+ <title>Array Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_append</primary>
+ </indexterm>
+ <function>array_append</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> )
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Appends an element to the end of an array (same as
+ the <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatible</type>
+ operator).
+ </para>
+ <para>
+ <literal>array_append(ARRAY[1,2], 3)</literal>
+ <returnvalue>{1,2,3}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_cat</primary>
+ </indexterm>
+ <function>array_cat</function> ( <type>anycompatiblearray</type>, <type>anycompatiblearray</type> )
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Concatenates two arrays (same as
+ the <type>anycompatiblearray</type> <literal>||</literal> <type>anycompatiblearray</type>
+ operator).
+ </para>
+ <para>
+ <literal>array_cat(ARRAY[1,2,3], ARRAY[4,5])</literal>
+ <returnvalue>{1,2,3,4,5}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_dims</primary>
+ </indexterm>
+ <function>array_dims</function> ( <type>anyarray</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns a text representation of the array's dimensions.
+ </para>
+ <para>
+ <literal>array_dims(ARRAY[[1,2,3], [4,5,6]])</literal>
+ <returnvalue>[1:2][1:3]</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_fill</primary>
+ </indexterm>
+ <function>array_fill</function> ( <type>anyelement</type>, <type>integer[]</type>
+ <optional>, <type>integer[]</type> </optional> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Returns an array filled with copies of the given value, having
+ dimensions of the lengths specified by the second argument.
+ The optional third argument supplies lower-bound values for each
+ dimension (which default to all <literal>1</literal>).
+ </para>
+ <para>
+ <literal>array_fill(11, ARRAY[2,3])</literal>
+ <returnvalue>{{11,11,11},{11,11,11}}</returnvalue>
+ </para>
+ <para>
+ <literal>array_fill(7, ARRAY[3], ARRAY[2])</literal>
+ <returnvalue>[2:4]={7,7,7}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_length</primary>
+ </indexterm>
+ <function>array_length</function> ( <type>anyarray</type>, <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the length of the requested array dimension.
+ (Produces NULL instead of 0 for empty or missing array dimensions.)
+ </para>
+ <para>
+ <literal>array_length(array[1,2,3], 1)</literal>
+ <returnvalue>3</returnvalue>
+ </para>
+ <para>
+ <literal>array_length(array[]::int[], 1)</literal>
+ <returnvalue>NULL</returnvalue>
+ </para>
+ <para>
+ <literal>array_length(array['text'], 2)</literal>
+ <returnvalue>NULL</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_lower</primary>
+ </indexterm>
+ <function>array_lower</function> ( <type>anyarray</type>, <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the lower bound of the requested array dimension.
+ </para>
+ <para>
+ <literal>array_lower('[0:2]={1,2,3}'::integer[], 1)</literal>
+ <returnvalue>0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_ndims</primary>
+ </indexterm>
+ <function>array_ndims</function> ( <type>anyarray</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of dimensions of the array.
+ </para>
+ <para>
+ <literal>array_ndims(ARRAY[[1,2,3], [4,5,6]])</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_position</primary>
+ </indexterm>
+ <function>array_position</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> <optional>, <type>integer</type> </optional> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the subscript of the first occurrence of the second argument
+ in the array, or <literal>NULL</literal> if it's not present.
+ If the third argument is given, the search begins at that subscript.
+ The array must be one-dimensional.
+ Comparisons are done using <literal>IS NOT DISTINCT FROM</literal>
+ semantics, so it is possible to search for <literal>NULL</literal>.
+ </para>
+ <para>
+ <literal>array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 'mon')</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_positions</primary>
+ </indexterm>
+ <function>array_positions</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of the subscripts of all occurrences of the second
+ argument in the array given as first argument.
+ The array must be one-dimensional.
+ Comparisons are done using <literal>IS NOT DISTINCT FROM</literal>
+ semantics, so it is possible to search for <literal>NULL</literal>.
+ <literal>NULL</literal> is returned only if the array
+ is <literal>NULL</literal>; if the value is not found in the array, an
+ empty array is returned.
+ </para>
+ <para>
+ <literal>array_positions(ARRAY['A','A','B','A'], 'A')</literal>
+ <returnvalue>{1,2,4}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_prepend</primary>
+ </indexterm>
+ <function>array_prepend</function> ( <type>anycompatible</type>, <type>anycompatiblearray</type> )
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Prepends an element to the beginning of an array (same as
+ the <type>anycompatible</type> <literal>||</literal> <type>anycompatiblearray</type>
+ operator).
+ </para>
+ <para>
+ <literal>array_prepend(1, ARRAY[2,3])</literal>
+ <returnvalue>{1,2,3}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_remove</primary>
+ </indexterm>
+ <function>array_remove</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type> )
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Removes all elements equal to the given value from the array.
+ The array must be one-dimensional.
+ Comparisons are done using <literal>IS NOT DISTINCT FROM</literal>
+ semantics, so it is possible to remove <literal>NULL</literal>s.
+ </para>
+ <para>
+ <literal>array_remove(ARRAY[1,2,3,2], 2)</literal>
+ <returnvalue>{1,3}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_replace</primary>
+ </indexterm>
+ <function>array_replace</function> ( <type>anycompatiblearray</type>, <type>anycompatible</type>, <type>anycompatible</type> )
+ <returnvalue>anycompatiblearray</returnvalue>
+ </para>
+ <para>
+ Replaces each array element equal to the second argument with the
+ third argument.
+ </para>
+ <para>
+ <literal>array_replace(ARRAY[1,2,5,4], 5, 3)</literal>
+ <returnvalue>{1,2,3,4}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm id="function-array-to-string">
+ <primary>array_to_string</primary>
+ </indexterm>
+ <function>array_to_string</function> ( <parameter>array</parameter> <type>anyarray</type>, <parameter>delimiter</parameter> <type>text</type> <optional>, <parameter>null_string</parameter> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts each array element to its text representation, and
+ concatenates those separated by
+ the <parameter>delimiter</parameter> string.
+ If <parameter>null_string</parameter> is given and is
+ not <literal>NULL</literal>, then <literal>NULL</literal> array
+ entries are represented by that string; otherwise, they are omitted.
+ See also <link linkend="function-string-to-array"><function>string_to_array</function></link>.
+ </para>
+ <para>
+ <literal>array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*')</literal>
+ <returnvalue>1,2,3,*,5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_upper</primary>
+ </indexterm>
+ <function>array_upper</function> ( <type>anyarray</type>, <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the upper bound of the requested array dimension.
+ </para>
+ <para>
+ <literal>array_upper(ARRAY[1,8,3,7], 1)</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cardinality</primary>
+ </indexterm>
+ <function>cardinality</function> ( <type>anyarray</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the total number of elements in the array, or 0 if the array
+ is empty.
+ </para>
+ <para>
+ <literal>cardinality(ARRAY[[1,2],[3,4]])</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>trim_array</primary>
+ </indexterm>
+ <function>trim_array</function> ( <parameter>array</parameter> <type>anyarray</type>, <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Trims an array by removing the last <parameter>n</parameter> elements.
+ If the array is multidimensional, only the first dimension is trimmed.
+ </para>
+ <para>
+ <literal>trim_array(ARRAY[1,2,3,4,5,6], 2)</literal>
+ <returnvalue>{1,2,3,4}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>unnest</primary>
+ </indexterm>
+ <function>unnest</function> ( <type>anyarray</type> )
+ <returnvalue>setof anyelement</returnvalue>
+ </para>
+ <para>
+ Expands an array into a set of rows.
+ The array's elements are read out in storage order.
+ </para>
+ <para>
+ <literal>unnest(ARRAY[1,2])</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ 1
+ 2
+</programlisting>
+ </para>
+ <para>
+ <literal>unnest(ARRAY[['foo','bar'],['baz','quux']])</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ foo
+ bar
+ baz
+ quux
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>unnest</function> ( <type>anyarray</type>, <type>anyarray</type> <optional>, ... </optional> )
+ <returnvalue>setof anyelement, anyelement [, ... ]</returnvalue>
+ </para>
+ <para>
+ Expands multiple arrays (possibly of different data types) into a set of
+ rows. If the arrays are not all the same length then the shorter ones
+ are padded with <literal>NULL</literal>s. This form is only allowed
+ in a query's FROM clause; see <xref linkend="queries-tablefunctions"/>.
+ </para>
+ <para>
+ <literal>select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b)</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ a | b
+---+-----
+ 1 | foo
+ 2 | bar
+ | baz
+</programlisting>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ See also <xref linkend="functions-aggregate"/> about the aggregate
+ function <function>array_agg</function> for use with arrays.
+ </para>
+ </sect1>
+
+ <sect1 id="functions-range">
+ <title>Range/Multirange Functions and Operators</title>
+
+ <para>
+ See <xref linkend="rangetypes"/> for an overview of range types.
+ </para>
+
+ <para>
+ <xref linkend="range-operators-table"/> shows the specialized operators
+ available for range types.
+ <xref linkend="multirange-operators-table"/> shows the specialized operators
+ available for multirange types.
+ In addition to those, the usual comparison operators shown in
+ <xref linkend="functions-comparison-op-table"/> are available for range
+ and multirange types. The comparison operators order first by the range lower
+ bounds, and only if those are equal do they compare the upper bounds. The
+ multirange operators compare each range until one is unequal. This
+ does not usually result in a useful overall ordering, but the operators are
+ provided to allow unique indexes to be constructed on ranges.
+ </para>
+
+ <table id="range-operators-table">
+ <title>Range Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>@&gt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first range contain the second?
+ </para>
+ <para>
+ <literal>int4range(2,4) @&gt; int4range(2,3)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>@&gt;</literal> <type>anyelement</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the range contain the element?
+ </para>
+ <para>
+ <literal>'[2011-01-01,2011-03-01)'::tsrange @&gt; '2011-01-10'::timestamp</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&lt;@</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first range contained by the second?
+ </para>
+ <para>
+ <literal>int4range(2,4) &lt;@ int4range(1,7)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyelement</type> <literal>&lt;@</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the element contained in the range?
+ </para>
+ <para>
+ <literal>42 &lt;@ int4range(1,7)</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&amp;&amp;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do the ranges overlap, that is, have any elements in common?
+ </para>
+ <para>
+ <literal>int8range(3,7) &amp;&amp; int8range(4,12)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&lt;&lt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first range strictly left of the second?
+ </para>
+ <para>
+ <literal>int8range(1,10) &lt;&lt; int8range(100,110)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&gt;&gt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first range strictly right of the second?
+ </para>
+ <para>
+ <literal>int8range(50,60) &gt;&gt; int8range(20,30)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&amp;&lt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first range not extend to the right of the second?
+ </para>
+ <para>
+ <literal>int8range(1,20) &amp;&lt; int8range(18,20)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&amp;&gt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first range not extend to the left of the second?
+ </para>
+ <para>
+ <literal>int8range(7,20) &amp;&gt; int8range(5,10)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>-|-</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are the ranges adjacent?
+ </para>
+ <para>
+ <literal>numrange(1.1,2.2) -|- numrange(2.2,3.3)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>+</literal> <type>anyrange</type>
+ <returnvalue>anyrange</returnvalue>
+ </para>
+ <para>
+ Computes the union of the ranges. The ranges must overlap or be
+ adjacent, so that the union is a single range (but
+ see <function>range_merge()</function>).
+ </para>
+ <para>
+ <literal>numrange(5,15) + numrange(10,20)</literal>
+ <returnvalue>[5,20)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>*</literal> <type>anyrange</type>
+ <returnvalue>anyrange</returnvalue>
+ </para>
+ <para>
+ Computes the intersection of the ranges.
+ </para>
+ <para>
+ <literal>int8range(5,15) * int8range(10,20)</literal>
+ <returnvalue>[10,15)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>-</literal> <type>anyrange</type>
+ <returnvalue>anyrange</returnvalue>
+ </para>
+ <para>
+ Computes the difference of the ranges. The second range must not be
+ contained in the first in such a way that the difference would not be
+ a single range.
+ </para>
+ <para>
+ <literal>int8range(5,15) - int8range(10,20)</literal>
+ <returnvalue>[5,10)</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="multirange-operators-table">
+ <title>Multirange Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>@&gt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first multirange contain the second?
+ </para>
+ <para>
+ <literal>'{[2,4)}'::int4multirange @&gt; '{[2,3)}'::int4multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>@&gt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the multirange contain the range?
+ </para>
+ <para>
+ <literal>'{[2,4)}'::int4multirange @&gt; int4range(2,3)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>@&gt;</literal> <type>anyelement</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the multirange contain the element?
+ </para>
+ <para>
+ <literal>'{[2011-01-01,2011-03-01)}'::tsmultirange @&gt; '2011-01-10'::timestamp</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>@&gt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the range contain the multirange?
+ </para>
+ <para>
+ <literal>'[2,4)'::int4range @&gt; '{[2,3)}'::int4multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&lt;@</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first multirange contained by the second?
+ </para>
+ <para>
+ <literal>'{[2,4)}'::int4multirange &lt;@ '{[1,7)}'::int4multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&lt;@</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange contained by the range?
+ </para>
+ <para>
+ <literal>'{[2,4)}'::int4multirange &lt;@ int4range(1,7)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&lt;@</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range contained by the multirange?
+ </para>
+ <para>
+ <literal>int4range(2,4) &lt;@ '{[1,7)}'::int4multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyelement</type> <literal>&lt;@</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the element contained by the multirange?
+ </para>
+ <para>
+ <literal>4 &lt;@ '{[1,7)}'::int4multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&amp;&amp;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do the multiranges overlap, that is, have any elements in common?
+ </para>
+ <para>
+ <literal>'{[3,7)}'::int8multirange &amp;&amp; '{[4,12)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&amp;&amp;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the multirange overlap the range?
+ </para>
+ <para>
+ <literal>'{[3,7)}'::int8multirange &amp;&amp; int8range(4,12)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&amp;&amp;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the range overlap the multirange?
+ </para>
+ <para>
+ <literal>int8range(3,7) &amp;&amp; '{[4,12)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&lt;&lt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first multirange strictly left of the second?
+ </para>
+ <para>
+ <literal>'{[1,10)}'::int8multirange &lt;&lt; '{[100,110)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&lt;&lt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange strictly left of the range?
+ </para>
+ <para>
+ <literal>'{[1,10)}'::int8multirange &lt;&lt; int8range(100,110)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&lt;&lt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range strictly left of the multirange?
+ </para>
+ <para>
+ <literal>int8range(1,10) &lt;&lt; '{[100,110)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&gt;&gt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first multirange strictly right of the second?
+ </para>
+ <para>
+ <literal>'{[50,60)}'::int8multirange &gt;&gt; '{[20,30)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&gt;&gt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange strictly right of the range?
+ </para>
+ <para>
+ <literal>'{[50,60)}'::int8multirange &gt;&gt; int8range(20,30)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&gt;&gt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range strictly right of the multirange?
+ </para>
+ <para>
+ <literal>int8range(50,60) &gt;&gt; '{[20,30)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&amp;&lt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first multirange not extend to the right of the second?
+ </para>
+ <para>
+ <literal>'{[1,20)}'::int8multirange &amp;&lt; '{[18,20)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&amp;&lt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the multirange not extend to the right of the range?
+ </para>
+ <para>
+ <literal>'{[1,20)}'::int8multirange &amp;&lt; int8range(18,20)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&amp;&lt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the range not extend to the right of the multirange?
+ </para>
+ <para>
+ <literal>int8range(1,20) &amp;&lt; '{[18,20)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&amp;&gt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first multirange not extend to the left of the second?
+ </para>
+ <para>
+ <literal>'{[7,20)}'::int8multirange &amp;&gt; '{[5,10)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>&amp;&gt;</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the multirange not extend to the left of the range?
+ </para>
+ <para>
+ <literal>'{[7,20)}'::int8multirange &amp;&gt; int8range(5,10)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>&amp;&gt;</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the range not extend to the left of the multirange?
+ </para>
+ <para>
+ <literal>int8range(7,20) &amp;&gt; '{[5,10)}'::int8multirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>-|-</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are the multiranges adjacent?
+ </para>
+ <para>
+ <literal>'{[1.1,2.2)}'::nummultirange -|- '{[2.2,3.3)}'::nummultirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>-|-</literal> <type>anyrange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange adjacent to the range?
+ </para>
+ <para>
+ <literal>'{[1.1,2.2)}'::nummultirange -|- numrange(2.2,3.3)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyrange</type> <literal>-|-</literal> <type>anymultirange</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range adjacent to the multirange?
+ </para>
+ <para>
+ <literal>numrange(1.1,2.2) -|- '{[2.2,3.3)}'::nummultirange</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>+</literal> <type>anymultirange</type>
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para>
+ Computes the union of the multiranges. The multiranges need not overlap
+ or be adjacent.
+ </para>
+ <para>
+ <literal>'{[5,10)}'::nummultirange + '{[15,20)}'::nummultirange</literal>
+ <returnvalue>{[5,10), [15,20)}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>*</literal> <type>anymultirange</type>
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para>
+ Computes the intersection of the multiranges.
+ </para>
+ <para>
+ <literal>'{[5,15)}'::int8multirange * '{[10,20)}'::int8multirange</literal>
+ <returnvalue>{[10,15)}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anymultirange</type> <literal>-</literal> <type>anymultirange</type>
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para>
+ Computes the difference of the multiranges.
+ </para>
+ <para>
+ <literal>'{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange</literal>
+ <returnvalue>{[5,10), [15,20)}</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The left-of/right-of/adjacent operators always return false when an empty
+ range or multirange is involved; that is, an empty range is not considered to
+ be either before or after any other range.
+ </para>
+
+ <para>
+ Elsewhere empty ranges and multiranges are treated as the additive identity:
+ anything unioned with an empty value is itself. Anything minus an empty
+ value is itself. An empty multirange has exactly the same points as an empty
+ range. Every range contains the empty range. Every multirange contains as many
+ empty ranges as you like.
+ </para>
+
+ <para>
+ The range union and difference operators will fail if the resulting range would
+ need to contain two disjoint sub-ranges, as such a range cannot be
+ represented. There are separate operators for union and difference that take
+ multirange parameters and return a multirange, and they do not fail even if
+ their arguments are disjoint. So if you need a union or difference operation
+ for ranges that may be disjoint, you can avoid errors by first casting your
+ ranges to multiranges.
+ </para>
+
+ <para>
+ <xref linkend="range-functions-table"/> shows the functions
+ available for use with range types.
+ <xref linkend="multirange-functions-table"/> shows the functions
+ available for use with multirange types.
+ </para>
+
+ <table id="range-functions-table">
+ <title>Range Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower</primary>
+ </indexterm>
+ <function>lower</function> ( <type>anyrange</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Extracts the lower bound of the range (<literal>NULL</literal> if the
+ range is empty or the lower bound is infinite).
+ </para>
+ <para>
+ <literal>lower(numrange(1.1,2.2))</literal>
+ <returnvalue>1.1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper</primary>
+ </indexterm>
+ <function>upper</function> ( <type>anyrange</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Extracts the upper bound of the range (<literal>NULL</literal> if the
+ range is empty or the upper bound is infinite).
+ </para>
+ <para>
+ <literal>upper(numrange(1.1,2.2))</literal>
+ <returnvalue>2.2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>isempty</primary>
+ </indexterm>
+ <function>isempty</function> ( <type>anyrange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range empty?
+ </para>
+ <para>
+ <literal>isempty(numrange(1.1,2.2))</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower_inc</primary>
+ </indexterm>
+ <function>lower_inc</function> ( <type>anyrange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range's lower bound inclusive?
+ </para>
+ <para>
+ <literal>lower_inc(numrange(1.1,2.2))</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper_inc</primary>
+ </indexterm>
+ <function>upper_inc</function> ( <type>anyrange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range's upper bound inclusive?
+ </para>
+ <para>
+ <literal>upper_inc(numrange(1.1,2.2))</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower_inf</primary>
+ </indexterm>
+ <function>lower_inf</function> ( <type>anyrange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range's lower bound infinite?
+ </para>
+ <para>
+ <literal>lower_inf('(,)'::daterange)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper_inf</primary>
+ </indexterm>
+ <function>upper_inf</function> ( <type>anyrange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the range's upper bound infinite?
+ </para>
+ <para>
+ <literal>upper_inf('(,)'::daterange)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>range_merge</primary>
+ </indexterm>
+ <function>range_merge</function> ( <type>anyrange</type>, <type>anyrange</type> )
+ <returnvalue>anyrange</returnvalue>
+ </para>
+ <para>
+ Computes the smallest range that includes both of the given ranges.
+ </para>
+ <para>
+ <literal>range_merge('[1,2)'::int4range, '[3,4)'::int4range)</literal>
+ <returnvalue>[1,4)</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="multirange-functions-table">
+ <title>Multirange Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower</primary>
+ </indexterm>
+ <function>lower</function> ( <type>anymultirange</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Extracts the lower bound of the multirange (<literal>NULL</literal> if the
+ multirange is empty or the lower bound is infinite).
+ </para>
+ <para>
+ <literal>lower('{[1.1,2.2)}'::nummultirange)</literal>
+ <returnvalue>1.1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper</primary>
+ </indexterm>
+ <function>upper</function> ( <type>anymultirange</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Extracts the upper bound of the multirange (<literal>NULL</literal> if the
+ multirange is empty or the upper bound is infinite).
+ </para>
+ <para>
+ <literal>upper('{[1.1,2.2)}'::nummultirange)</literal>
+ <returnvalue>2.2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>isempty</primary>
+ </indexterm>
+ <function>isempty</function> ( <type>anymultirange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange empty?
+ </para>
+ <para>
+ <literal>isempty('{[1.1,2.2)}'::nummultirange)</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower_inc</primary>
+ </indexterm>
+ <function>lower_inc</function> ( <type>anymultirange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange's lower bound inclusive?
+ </para>
+ <para>
+ <literal>lower_inc('{[1.1,2.2)}'::nummultirange)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper_inc</primary>
+ </indexterm>
+ <function>upper_inc</function> ( <type>anymultirange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange's upper bound inclusive?
+ </para>
+ <para>
+ <literal>upper_inc('{[1.1,2.2)}'::nummultirange)</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lower_inf</primary>
+ </indexterm>
+ <function>lower_inf</function> ( <type>anymultirange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange's lower bound infinite?
+ </para>
+ <para>
+ <literal>lower_inf('{(,)}'::datemultirange)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>upper_inf</primary>
+ </indexterm>
+ <function>upper_inf</function> ( <type>anymultirange</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the multirange's upper bound infinite?
+ </para>
+ <para>
+ <literal>upper_inf('{(,)}'::datemultirange)</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>range_merge</primary>
+ </indexterm>
+ <function>range_merge</function> ( <type>anymultirange</type> )
+ <returnvalue>anyrange</returnvalue>
+ </para>
+ <para>
+ Computes the smallest range that includes the entire multirange.
+ </para>
+ <para>
+ <literal>range_merge('{[1,2), [3,4)}'::int4multirange)</literal>
+ <returnvalue>[1,4)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>multirange (function)</primary>
+ </indexterm>
+ <function>multirange</function> ( <type>anyrange</type> )
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para>
+ Returns a multirange containing just the given range.
+ </para>
+ <para>
+ <literal>multirange('[1,2)'::int4range)</literal>
+ <returnvalue>{[1,2)}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>unnest</primary>
+ <secondary>for multirange</secondary>
+ </indexterm>
+ <function>unnest</function> ( <type>anymultirange</type> )
+ <returnvalue>setof anyrange</returnvalue>
+ </para>
+ <para>
+ Expands a multirange into a set of ranges.
+ The ranges are read out in storage order (ascending).
+ </para>
+ <para>
+ <literal>unnest('{[1,2), [3,4)}'::int4multirange)</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ [1,2)
+ [3,4)
+</programlisting>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <function>lower_inc</function>, <function>upper_inc</function>,
+ <function>lower_inf</function>, and <function>upper_inf</function>
+ functions all return false for an empty range or multirange.
+ </para>
+ </sect1>
+
+ <sect1 id="functions-aggregate">
+ <title>Aggregate Functions</title>
+
+ <indexterm zone="functions-aggregate">
+ <primary>aggregate function</primary>
+ <secondary>built-in</secondary>
+ </indexterm>
+
+ <para>
+ <firstterm>Aggregate functions</firstterm> compute a single result
+ from a set of input values. The built-in general-purpose aggregate
+ functions are listed in <xref linkend="functions-aggregate-table"/>
+ while statistical aggregates are in <xref
+ linkend="functions-aggregate-statistics-table"/>.
+ The built-in within-group ordered-set aggregate functions
+ are listed in <xref linkend="functions-orderedset-table"/>
+ while the built-in within-group hypothetical-set ones are in <xref
+ linkend="functions-hypothetical-table"/>. Grouping operations,
+ which are closely related to aggregate functions, are listed in
+ <xref linkend="functions-grouping-table"/>.
+ The special syntax considerations for aggregate
+ functions are explained in <xref linkend="syntax-aggregates"/>.
+ Consult <xref linkend="tutorial-agg"/> for additional introductory
+ information.
+ </para>
+
+ <para>
+ Aggregate functions that support <firstterm>Partial Mode</firstterm>
+ are eligible to participate in various optimizations, such as parallel
+ aggregation.
+ </para>
+
+ <table id="functions-aggregate-table">
+ <title>General-Purpose Aggregate Functions</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="10*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ <entry>Partial Mode</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>array_agg</primary>
+ </indexterm>
+ <function>array_agg</function> ( <type>anynonarray</type> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Collects all the input values, including nulls, into an array.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>array_agg</function> ( <type>anyarray</type> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Concatenates all the input arrays into an array of one higher
+ dimension. (The inputs must all have the same dimensionality, and
+ cannot be empty or null.)
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>average</primary>
+ </indexterm>
+ <indexterm>
+ <primary>avg</primary>
+ </indexterm>
+ <function>avg</function> ( <type>smallint</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>avg</function> ( <type>integer</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>avg</function> ( <type>bigint</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>avg</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>avg</function> ( <type>real</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>avg</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>avg</function> ( <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Computes the average (arithmetic mean) of all the non-null input
+ values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_and</primary>
+ </indexterm>
+ <function>bit_and</function> ( <type>smallint</type> )
+ <returnvalue>smallint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_and</function> ( <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_and</function> ( <type>bigint</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_and</function> ( <type>bit</type> )
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Computes the bitwise AND of all non-null input values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_or</primary>
+ </indexterm>
+ <function>bit_or</function> ( <type>smallint</type> )
+ <returnvalue>smallint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_or</function> ( <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_or</function> ( <type>bigint</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_or</function> ( <type>bit</type> )
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Computes the bitwise OR of all non-null input values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bit_xor</primary>
+ </indexterm>
+ <function>bit_xor</function> ( <type>smallint</type> )
+ <returnvalue>smallint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_xor</function> ( <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_xor</function> ( <type>bigint</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>bit_xor</function> ( <type>bit</type> )
+ <returnvalue>bit</returnvalue>
+ </para>
+ <para>
+ Computes the bitwise exclusive OR of all non-null input values.
+ Can be useful as a checksum for an unordered set of values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bool_and</primary>
+ </indexterm>
+ <function>bool_and</function> ( <type>boolean</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if all non-null input values are true, otherwise false.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>bool_or</primary>
+ </indexterm>
+ <function>bool_or</function> ( <type>boolean</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if any non-null input value is true, otherwise false.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>count</primary>
+ </indexterm>
+ <function>count</function> ( <literal>*</literal> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the number of input rows.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>count</function> ( <type>"any"</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the number of input rows in which the input value is not
+ null.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>every</primary>
+ </indexterm>
+ <function>every</function> ( <type>boolean</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ This is the SQL standard's equivalent to <function>bool_and</function>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_agg</primary>
+ </indexterm>
+ <function>json_agg</function> ( <type>anyelement</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_agg</primary>
+ </indexterm>
+ <function>jsonb_agg</function> ( <type>anyelement</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Collects all the input values, including nulls, into a JSON array.
+ Values are converted to JSON as per <function>to_json</function>
+ or <function>to_jsonb</function>.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>json_object_agg</primary>
+ </indexterm>
+ <function>json_object_agg</function> ( <parameter>key</parameter>
+ <type>"any"</type>, <parameter>value</parameter>
+ <type>"any"</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>jsonb_object_agg</primary>
+ </indexterm>
+ <function>jsonb_object_agg</function> ( <parameter>key</parameter>
+ <type>"any"</type>, <parameter>value</parameter>
+ <type>"any"</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Collects all the key/value pairs into a JSON object. Key arguments
+ are coerced to text; value arguments are converted as
+ per <function>to_json</function> or <function>to_jsonb</function>.
+ Values can be null, but not keys.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>max</primary>
+ </indexterm>
+ <function>max</function> ( <replaceable>see text</replaceable> )
+ <returnvalue><replaceable>same as input type</replaceable></returnvalue>
+ </para>
+ <para>
+ Computes the maximum of the non-null input
+ values. Available for any numeric, string, date/time, or enum type,
+ as well as <type>inet</type>, <type>interval</type>,
+ <type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
+ <type>tid</type>, <type>xid8</type>,
+ and arrays of any of these types.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>min</primary>
+ </indexterm>
+ <function>min</function> ( <replaceable>see text</replaceable> )
+ <returnvalue><replaceable>same as input type</replaceable></returnvalue>
+ </para>
+ <para>
+ Computes the minimum of the non-null input
+ values. Available for any numeric, string, date/time, or enum type,
+ as well as <type>inet</type>, <type>interval</type>,
+ <type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
+ <type>tid</type>, <type>xid8</type>,
+ and arrays of any of these types.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>range_agg</primary>
+ </indexterm>
+ <function>range_agg</function> ( <parameter>value</parameter>
+ <type>anyrange</type> )
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>range_agg</function> ( <parameter>value</parameter>
+ <type>anymultirange</type> )
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para>
+ Computes the union of the non-null input values.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>range_intersect_agg</primary>
+ </indexterm>
+ <function>range_intersect_agg</function> ( <parameter>value</parameter>
+ <type>anyrange</type> )
+ <returnvalue>anyrange</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>range_intersect_agg</function> ( <parameter>value</parameter>
+ <type>anymultirange</type> )
+ <returnvalue>anymultirange</returnvalue>
+ </para>
+ <para>
+ Computes the intersection of the non-null input values.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>string_agg</primary>
+ </indexterm>
+ <function>string_agg</function> ( <parameter>value</parameter>
+ <type>text</type>, <parameter>delimiter</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>string_agg</function> ( <parameter>value</parameter>
+ <type>bytea</type>, <parameter>delimiter</parameter> <type>bytea</type> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Concatenates the non-null input values into a string. Each value
+ after the first is preceded by the
+ corresponding <parameter>delimiter</parameter> (if it's not null).
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>sum</primary>
+ </indexterm>
+ <function>sum</function> ( <type>smallint</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>integer</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>bigint</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>numeric</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>real</type> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>sum</function> ( <type>money</type> )
+ <returnvalue>money</returnvalue>
+ </para>
+ <para>
+ Computes the sum of the non-null input values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>xmlagg</primary>
+ </indexterm>
+ <function>xmlagg</function> ( <type>xml</type> )
+ <returnvalue>xml</returnvalue>
+ </para>
+ <para>
+ Concatenates the non-null XML input values (see
+ <xref linkend="functions-xml-xmlagg"/>).
+ </para></entry>
+ <entry>No</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ It should be noted that except for <function>count</function>,
+ these functions return a null value when no rows are selected. In
+ particular, <function>sum</function> of no rows returns null, not
+ zero as one might expect, and <function>array_agg</function>
+ returns null rather than an empty array when there are no input
+ rows. The <function>coalesce</function> function can be used to
+ substitute zero or an empty array for null when necessary.
+ </para>
+
+ <para>
+ The aggregate functions <function>array_agg</function>,
+ <function>json_agg</function>, <function>jsonb_agg</function>,
+ <function>json_object_agg</function>, <function>jsonb_object_agg</function>,
+ <function>string_agg</function>,
+ and <function>xmlagg</function>, as well as similar user-defined
+ aggregate functions, produce meaningfully different result values
+ depending on the order of the input values. This ordering is
+ unspecified by default, but can be controlled by writing an
+ <literal>ORDER BY</literal> clause within the aggregate call, as shown in
+ <xref linkend="syntax-aggregates"/>.
+ Alternatively, supplying the input values from a sorted subquery
+ will usually work. For example:
+
+<screen><![CDATA[
+SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
+]]></screen>
+
+ Beware that this approach can fail if the outer query level contains
+ additional processing, such as a join, because that might cause the
+ subquery's output to be reordered before the aggregate is computed.
+ </para>
+
+ <note>
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
+ <para>
+ The boolean aggregates <function>bool_and</function> and
+ <function>bool_or</function> correspond to the standard SQL aggregates
+ <function>every</function> and <function>any</function> or
+ <function>some</function>.
+ <productname>PostgreSQL</productname>
+ supports <function>every</function>, but not <function>any</function>
+ or <function>some</function>, because there is an ambiguity built into
+ the standard syntax:
+<programlisting>
+SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
+</programlisting>
+ Here <function>ANY</function> can be considered either as introducing
+ a subquery, or as being an aggregate function, if the subquery
+ returns one row with a Boolean value.
+ Thus the standard name cannot be given to these aggregates.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Users accustomed to working with other SQL database management
+ systems might be disappointed by the performance of the
+ <function>count</function> aggregate when it is applied to the
+ entire table. A query like:
+<programlisting>
+SELECT count(*) FROM sometable;
+</programlisting>
+ will require effort proportional to the size of the table:
+ <productname>PostgreSQL</productname> will need to scan either the
+ entire table or the entirety of an index that includes all rows in
+ the table.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="functions-aggregate-statistics-table"/> shows
+ aggregate functions typically used in statistical analysis.
+ (These are separated out merely to avoid cluttering the listing
+ of more-commonly-used aggregates.) Functions shown as
+ accepting <replaceable>numeric_type</replaceable> are available for all
+ the types <type>smallint</type>, <type>integer</type>,
+ <type>bigint</type>, <type>numeric</type>, <type>real</type>,
+ and <type>double precision</type>.
+ Where the description mentions
+ <parameter>N</parameter>, it means the
+ number of input rows for which all the input expressions are non-null.
+ In all cases, null is returned if the computation is meaningless,
+ for example when <parameter>N</parameter> is zero.
+ </para>
+
+ <indexterm>
+ <primary>statistics</primary>
+ </indexterm>
+ <indexterm>
+ <primary>linear regression</primary>
+ </indexterm>
+
+ <table id="functions-aggregate-statistics-table">
+ <title>Aggregate Functions for Statistics</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="10*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ <entry>Partial Mode</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>correlation</primary>
+ </indexterm>
+ <indexterm>
+ <primary>corr</primary>
+ </indexterm>
+ <function>corr</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the correlation coefficient.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>covariance</primary>
+ <secondary>population</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>covar_pop</primary>
+ </indexterm>
+ <function>covar_pop</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the population covariance.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>covariance</primary>
+ <secondary>sample</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>covar_samp</primary>
+ </indexterm>
+ <function>covar_samp</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the sample covariance.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_avgx</primary>
+ </indexterm>
+ <function>regr_avgx</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the average of the independent variable,
+ <literal>sum(<parameter>X</parameter>)/<parameter>N</parameter></literal>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_avgy</primary>
+ </indexterm>
+ <function>regr_avgy</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the average of the dependent variable,
+ <literal>sum(<parameter>Y</parameter>)/<parameter>N</parameter></literal>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_count</primary>
+ </indexterm>
+ <function>regr_count</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the number of rows in which both inputs are non-null.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regression intercept</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regr_intercept</primary>
+ </indexterm>
+ <function>regr_intercept</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the y-intercept of the least-squares-fit linear equation
+ determined by the
+ (<parameter>X</parameter>, <parameter>Y</parameter>) pairs.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_r2</primary>
+ </indexterm>
+ <function>regr_r2</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the square of the correlation coefficient.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regression slope</primary>
+ </indexterm>
+ <indexterm>
+ <primary>regr_slope</primary>
+ </indexterm>
+ <function>regr_slope</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the slope of the least-squares-fit linear equation determined
+ by the (<parameter>X</parameter>, <parameter>Y</parameter>)
+ pairs.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_sxx</primary>
+ </indexterm>
+ <function>regr_sxx</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the <quote>sum of squares</quote> of the independent
+ variable,
+ <literal>sum(<parameter>X</parameter>^2) - sum(<parameter>X</parameter>)^2/<parameter>N</parameter></literal>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_sxy</primary>
+ </indexterm>
+ <function>regr_sxy</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the <quote>sum of products</quote> of independent times
+ dependent variables,
+ <literal>sum(<parameter>X</parameter>*<parameter>Y</parameter>) - sum(<parameter>X</parameter>) * sum(<parameter>Y</parameter>)/<parameter>N</parameter></literal>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>regr_syy</primary>
+ </indexterm>
+ <function>regr_syy</function> ( <parameter>Y</parameter> <type>double precision</type>, <parameter>X</parameter> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the <quote>sum of squares</quote> of the dependent
+ variable,
+ <literal>sum(<parameter>Y</parameter>^2) - sum(<parameter>Y</parameter>)^2/<parameter>N</parameter></literal>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>standard deviation</primary>
+ </indexterm>
+ <indexterm>
+ <primary>stddev</primary>
+ </indexterm>
+ <function>stddev</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue></returnvalue> <type>double precision</type>
+ for <type>real</type> or <type>double precision</type>,
+ otherwise <type>numeric</type>
+ </para>
+ <para>
+ This is a historical alias for <function>stddev_samp</function>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>standard deviation</primary>
+ <secondary>population</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>stddev_pop</primary>
+ </indexterm>
+ <function>stddev_pop</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue></returnvalue> <type>double precision</type>
+ for <type>real</type> or <type>double precision</type>,
+ otherwise <type>numeric</type>
+ </para>
+ <para>
+ Computes the population standard deviation of the input values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>standard deviation</primary>
+ <secondary>sample</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>stddev_samp</primary>
+ </indexterm>
+ <function>stddev_samp</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue></returnvalue> <type>double precision</type>
+ for <type>real</type> or <type>double precision</type>,
+ otherwise <type>numeric</type>
+ </para>
+ <para>
+ Computes the sample standard deviation of the input values.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>variance</primary>
+ </indexterm>
+ <function>variance</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue></returnvalue> <type>double precision</type>
+ for <type>real</type> or <type>double precision</type>,
+ otherwise <type>numeric</type>
+ </para>
+ <para>
+ This is a historical alias for <function>var_samp</function>.
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>variance</primary>
+ <secondary>population</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>var_pop</primary>
+ </indexterm>
+ <function>var_pop</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue></returnvalue> <type>double precision</type>
+ for <type>real</type> or <type>double precision</type>,
+ otherwise <type>numeric</type>
+ </para>
+ <para>
+ Computes the population variance of the input values (square of the
+ population standard deviation).
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>variance</primary>
+ <secondary>sample</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>var_samp</primary>
+ </indexterm>
+ <function>var_samp</function> ( <replaceable>numeric_type</replaceable> )
+ <returnvalue></returnvalue> <type>double precision</type>
+ for <type>real</type> or <type>double precision</type>,
+ otherwise <type>numeric</type>
+ </para>
+ <para>
+ Computes the sample variance of the input values (square of the sample
+ standard deviation).
+ </para></entry>
+ <entry>Yes</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-orderedset-table"/> shows some
+ aggregate functions that use the <firstterm>ordered-set aggregate</firstterm>
+ syntax. These functions are sometimes referred to as <quote>inverse
+ distribution</quote> functions. Their aggregated input is introduced by
+ <literal>ORDER BY</literal>, and they may also take a <firstterm>direct
+ argument</firstterm> that is not aggregated, but is computed only once.
+ All these functions ignore null values in their aggregated input.
+ For those that take a <parameter>fraction</parameter> parameter, the
+ fraction value must be between 0 and 1; an error is thrown if not.
+ However, a null <parameter>fraction</parameter> value simply produces a
+ null result.
+ </para>
+
+ <indexterm>
+ <primary>ordered-set aggregate</primary>
+ <secondary>built-in</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>inverse distribution</primary>
+ </indexterm>
+
+ <table id="functions-orderedset-table">
+ <title>Ordered-Set Aggregate Functions</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="10*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ <entry>Partial Mode</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>mode</primary>
+ <secondary>statistical</secondary>
+ </indexterm>
+ <function>mode</function> () <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>anyelement</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Computes the <firstterm>mode</firstterm>, the most frequent
+ value of the aggregated argument (arbitrarily choosing the first one
+ if there are multiple equally-frequent values). The aggregated
+ argument must be of a sortable type.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>percentile</primary>
+ <secondary>continuous</secondary>
+ </indexterm>
+ <function>percentile_cont</function> ( <parameter>fraction</parameter> <type>double precision</type> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>double precision</type> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>percentile_cont</function> ( <parameter>fraction</parameter> <type>double precision</type> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>interval</type> )
+ <returnvalue>interval</returnvalue>
+ </para>
+ <para>
+ Computes the <firstterm>continuous percentile</firstterm>, a value
+ corresponding to the specified <parameter>fraction</parameter>
+ within the ordered set of aggregated argument values. This will
+ interpolate between adjacent input items if needed.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>percentile_cont</function> ( <parameter>fractions</parameter> <type>double precision[]</type> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>double precision</type> )
+ <returnvalue>double precision[]</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>percentile_cont</function> ( <parameter>fractions</parameter> <type>double precision[]</type> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>interval</type> )
+ <returnvalue>interval[]</returnvalue>
+ </para>
+ <para>
+ Computes multiple continuous percentiles. The result is an array of
+ the same dimensions as the <parameter>fractions</parameter>
+ parameter, with each non-null element replaced by the (possibly
+ interpolated) value corresponding to that percentile.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>percentile</primary>
+ <secondary>discrete</secondary>
+ </indexterm>
+ <function>percentile_disc</function> ( <parameter>fraction</parameter> <type>double precision</type> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>anyelement</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Computes the <firstterm>discrete percentile</firstterm>, the first
+ value within the ordered set of aggregated argument values whose
+ position in the ordering equals or exceeds the
+ specified <parameter>fraction</parameter>. The aggregated
+ argument must be of a sortable type.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>percentile_disc</function> ( <parameter>fractions</parameter> <type>double precision[]</type> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <type>anyelement</type> )
+ <returnvalue>anyarray</returnvalue>
+ </para>
+ <para>
+ Computes multiple discrete percentiles. The result is an array of the
+ same dimensions as the <parameter>fractions</parameter> parameter,
+ with each non-null element replaced by the input value corresponding
+ to that percentile.
+ The aggregated argument must be of a sortable type.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <indexterm>
+ <primary>hypothetical-set aggregate</primary>
+ <secondary>built-in</secondary>
+ </indexterm>
+
+ <para>
+ Each of the <quote>hypothetical-set</quote> aggregates listed in
+ <xref linkend="functions-hypothetical-table"/> is associated with a
+ window function of the same name defined in
+ <xref linkend="functions-window"/>. In each case, the aggregate's result
+ is the value that the associated window function would have
+ returned for the <quote>hypothetical</quote> row constructed from
+ <replaceable>args</replaceable>, if such a row had been added to the sorted
+ group of rows represented by the <replaceable>sorted_args</replaceable>.
+ For each of these functions, the list of direct arguments
+ given in <replaceable>args</replaceable> must match the number and types of
+ the aggregated arguments given in <replaceable>sorted_args</replaceable>.
+ Unlike most built-in aggregates, these aggregates are not strict, that is
+ they do not drop input rows containing nulls. Null values sort according
+ to the rule specified in the <literal>ORDER BY</literal> clause.
+ </para>
+
+ <table id="functions-hypothetical-table">
+ <title>Hypothetical-Set Aggregate Functions</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="10*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ <entry>Partial Mode</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>rank</primary>
+ <secondary>hypothetical</secondary>
+ </indexterm>
+ <function>rank</function> ( <replaceable>args</replaceable> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <replaceable>sorted_args</replaceable> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the rank of the hypothetical row, with gaps; that is, the row
+ number of the first row in its peer group.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>dense_rank</primary>
+ <secondary>hypothetical</secondary>
+ </indexterm>
+ <function>dense_rank</function> ( <replaceable>args</replaceable> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <replaceable>sorted_args</replaceable> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the rank of the hypothetical row, without gaps; this function
+ effectively counts peer groups.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>percent_rank</primary>
+ <secondary>hypothetical</secondary>
+ </indexterm>
+ <function>percent_rank</function> ( <replaceable>args</replaceable> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <replaceable>sorted_args</replaceable> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the relative rank of the hypothetical row, that is
+ (<function>rank</function> - 1) / (total rows - 1).
+ The value thus ranges from 0 to 1 inclusive.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cume_dist</primary>
+ <secondary>hypothetical</secondary>
+ </indexterm>
+ <function>cume_dist</function> ( <replaceable>args</replaceable> ) <literal>WITHIN GROUP</literal> ( <literal>ORDER BY</literal> <replaceable>sorted_args</replaceable> )
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Computes the cumulative distribution, that is (number of rows
+ preceding or peers with hypothetical row) / (total rows). The value
+ thus ranges from 1/<parameter>N</parameter> to 1.
+ </para></entry>
+ <entry>No</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-grouping-table">
+ <title>Grouping Operations</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>GROUPING</primary>
+ </indexterm>
+ <function>GROUPING</function> ( <replaceable>group_by_expression(s)</replaceable> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns a bit mask indicating which <literal>GROUP BY</literal>
+ expressions are not included in the current grouping set.
+ Bits are assigned with the rightmost argument corresponding to the
+ least-significant bit; each bit is 0 if the corresponding expression
+ is included in the grouping criteria of the grouping set generating
+ the current result row, and 1 if it is not included.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The grouping operations shown in
+ <xref linkend="functions-grouping-table"/> are used in conjunction with
+ grouping sets (see <xref linkend="queries-grouping-sets"/>) to distinguish
+ result rows. The arguments to the <literal>GROUPING</literal> function
+ are not actually evaluated, but they must exactly match expressions given
+ in the <literal>GROUP BY</literal> clause of the associated query level.
+ For example:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM items_sold;</userinput>
+ make | model | sales
+-------+-------+-------
+ Foo | GT | 10
+ Foo | Tour | 20
+ Bar | City | 15
+ Bar | Sport | 5
+(4 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT make, model, GROUPING(make,model), sum(sales) FROM items_sold GROUP BY ROLLUP(make,model);</userinput>
+ make | model | grouping | sum
+-------+-------+----------+-----
+ Foo | GT | 0 | 10
+ Foo | Tour | 0 | 20
+ Bar | City | 0 | 15
+ Bar | Sport | 0 | 5
+ Foo | | 1 | 30
+ Bar | | 1 | 20
+ | | 3 | 50
+(7 rows)
+</screen>
+ Here, the <literal>grouping</literal> value <literal>0</literal> in the
+ first four rows shows that those have been grouped normally, over both the
+ grouping columns. The value <literal>1</literal> indicates
+ that <literal>model</literal> was not grouped by in the next-to-last two
+ rows, and the value <literal>3</literal> indicates that
+ neither <literal>make</literal> nor <literal>model</literal> was grouped
+ by in the last row (which therefore is an aggregate over all the input
+ rows).
+ </para>
+
+ </sect1>
+
+ <sect1 id="functions-window">
+ <title>Window Functions</title>
+
+ <indexterm zone="functions-window">
+ <primary>window function</primary>
+ <secondary>built-in</secondary>
+ </indexterm>
+
+ <para>
+ <firstterm>Window functions</firstterm> provide the ability to perform
+ calculations across sets of rows that are related to the current query
+ row. See <xref linkend="tutorial-window"/> for an introduction to this
+ feature, and <xref linkend="syntax-window-functions"/> for syntax
+ details.
+ </para>
+
+ <para>
+ The built-in window functions are listed in
+ <xref linkend="functions-window-table"/>. Note that these functions
+ <emphasis>must</emphasis> be invoked using window function syntax, i.e., an
+ <literal>OVER</literal> clause is required.
+ </para>
+
+ <para>
+ In addition to these functions, any built-in or user-defined
+ ordinary aggregate (i.e., not ordered-set or hypothetical-set aggregates)
+ can be used as a window function; see
+ <xref linkend="functions-aggregate"/> for a list of the built-in aggregates.
+ Aggregate functions act as window functions only when an <literal>OVER</literal>
+ clause follows the call; otherwise they act as plain aggregates
+ and return a single row for the entire set.
+ </para>
+
+ <table id="functions-window-table">
+ <title>General-Purpose Window Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>row_number</primary>
+ </indexterm>
+ <function>row_number</function> ()
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the number of the current row within its partition, counting
+ from 1.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>rank</primary>
+ </indexterm>
+ <function>rank</function> ()
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the rank of the current row, with gaps; that is,
+ the <function>row_number</function> of the first row in its peer
+ group.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>dense_rank</primary>
+ </indexterm>
+ <function>dense_rank</function> ()
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the rank of the current row, without gaps; this function
+ effectively counts peer groups.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>percent_rank</primary>
+ </indexterm>
+ <function>percent_rank</function> ()
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Returns the relative rank of the current row, that is
+ (<function>rank</function> - 1) / (total partition rows - 1).
+ The value thus ranges from 0 to 1 inclusive.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>cume_dist</primary>
+ </indexterm>
+ <function>cume_dist</function> ()
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Returns the cumulative distribution, that is (number of partition rows
+ preceding or peers with current row) / (total partition rows).
+ The value thus ranges from 1/<parameter>N</parameter> to 1.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>ntile</primary>
+ </indexterm>
+ <function>ntile</function> ( <parameter>num_buckets</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns an integer ranging from 1 to the argument value, dividing the
+ partition as equally as possible.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lag</primary>
+ </indexterm>
+ <function>lag</function> ( <parameter>value</parameter> <type>anycompatible</type>
+ <optional>, <parameter>offset</parameter> <type>integer</type>
+ <optional>, <parameter>default</parameter> <type>anycompatible</type> </optional></optional> )
+ <returnvalue>anycompatible</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>value</parameter> evaluated at
+ the row that is <parameter>offset</parameter>
+ rows before the current row within the partition; if there is no such
+ row, instead returns <parameter>default</parameter>
+ (which must be of a type compatible with
+ <parameter>value</parameter>).
+ Both <parameter>offset</parameter> and
+ <parameter>default</parameter> are evaluated
+ with respect to the current row. If omitted,
+ <parameter>offset</parameter> defaults to 1 and
+ <parameter>default</parameter> to <literal>NULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lead</primary>
+ </indexterm>
+ <function>lead</function> ( <parameter>value</parameter> <type>anycompatible</type>
+ <optional>, <parameter>offset</parameter> <type>integer</type>
+ <optional>, <parameter>default</parameter> <type>anycompatible</type> </optional></optional> )
+ <returnvalue>anycompatible</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>value</parameter> evaluated at
+ the row that is <parameter>offset</parameter>
+ rows after the current row within the partition; if there is no such
+ row, instead returns <parameter>default</parameter>
+ (which must be of a type compatible with
+ <parameter>value</parameter>).
+ Both <parameter>offset</parameter> and
+ <parameter>default</parameter> are evaluated
+ with respect to the current row. If omitted,
+ <parameter>offset</parameter> defaults to 1 and
+ <parameter>default</parameter> to <literal>NULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>first_value</primary>
+ </indexterm>
+ <function>first_value</function> ( <parameter>value</parameter> <type>anyelement</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>value</parameter> evaluated
+ at the row that is the first row of the window frame.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>last_value</primary>
+ </indexterm>
+ <function>last_value</function> ( <parameter>value</parameter> <type>anyelement</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>value</parameter> evaluated
+ at the row that is the last row of the window frame.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>nth_value</primary>
+ </indexterm>
+ <function>nth_value</function> ( <parameter>value</parameter> <type>anyelement</type>, <parameter>n</parameter> <type>integer</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Returns <parameter>value</parameter> evaluated
+ at the row that is the <parameter>n</parameter>'th
+ row of the window frame (counting from 1);
+ returns <literal>NULL</literal> if there is no such row.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ All of the functions listed in
+ <xref linkend="functions-window-table"/> depend on the sort ordering
+ specified by the <literal>ORDER BY</literal> clause of the associated window
+ definition. Rows that are not distinct when considering only the
+ <literal>ORDER BY</literal> columns are said to be <firstterm>peers</firstterm>.
+ The four ranking functions (including <function>cume_dist</function>) are
+ defined so that they give the same answer for all rows of a peer group.
+ </para>
+
+ <para>
+ Note that <function>first_value</function>, <function>last_value</function>, and
+ <function>nth_value</function> consider only the rows within the <quote>window
+ frame</quote>, which by default contains the rows from the start of the
+ partition through the last peer of the current row. This is
+ likely to give unhelpful results for <function>last_value</function> and
+ sometimes also <function>nth_value</function>. You can redefine the frame by
+ adding a suitable frame specification (<literal>RANGE</literal>,
+ <literal>ROWS</literal> or <literal>GROUPS</literal>) to
+ the <literal>OVER</literal> clause.
+ See <xref linkend="syntax-window-functions"/> for more information
+ about frame specifications.
+ </para>
+
+ <para>
+ When an aggregate function is used as a window function, it aggregates
+ over the rows within the current row's window frame.
+ An aggregate used with <literal>ORDER BY</literal> and the default window frame
+ definition produces a <quote>running sum</quote> type of behavior, which may or
+ may not be what's wanted. To obtain
+ aggregation over the whole partition, omit <literal>ORDER BY</literal> or use
+ <literal>ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING</literal>.
+ Other frame specifications can be used to obtain other effects.
+ </para>
+
+ <note>
+ <para>
+ The SQL standard defines a <literal>RESPECT NULLS</literal> or
+ <literal>IGNORE NULLS</literal> option for <function>lead</function>, <function>lag</function>,
+ <function>first_value</function>, <function>last_value</function>, and
+ <function>nth_value</function>. This is not implemented in
+ <productname>PostgreSQL</productname>: the behavior is always the
+ same as the standard's default, namely <literal>RESPECT NULLS</literal>.
+ Likewise, the standard's <literal>FROM FIRST</literal> or <literal>FROM LAST</literal>
+ option for <function>nth_value</function> is not implemented: only the
+ default <literal>FROM FIRST</literal> behavior is supported. (You can achieve
+ the result of <literal>FROM LAST</literal> by reversing the <literal>ORDER BY</literal>
+ ordering.)
+ </para>
+ </note>
+
+ </sect1>
+
+ <sect1 id="functions-subquery">
+ <title>Subquery Expressions</title>
+
+ <indexterm>
+ <primary>EXISTS</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NOT IN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ALL</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>subquery</primary>
+ </indexterm>
+
+ <para>
+ This section describes the <acronym>SQL</acronym>-compliant subquery
+ expressions available in <productname>PostgreSQL</productname>.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </para>
+
+ <sect2 id="functions-subquery-exists">
+ <title><literal>EXISTS</literal></title>
+
+<synopsis>
+EXISTS (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The argument of <token>EXISTS</token> is an arbitrary <command>SELECT</command> statement,
+ or <firstterm>subquery</firstterm>. The
+ subquery is evaluated to determine whether it returns any rows.
+ If it returns at least one row, the result of <token>EXISTS</token> is
+ <quote>true</quote>; if the subquery returns no rows, the result of <token>EXISTS</token>
+ is <quote>false</quote>.
+ </para>
+
+ <para>
+ The subquery can refer to variables from the surrounding query,
+ which will act as constants during any one evaluation of the subquery.
+ </para>
+
+ <para>
+ The subquery will generally only be executed long enough to determine
+ whether at least one row is returned, not all the way to completion.
+ It is unwise to write a subquery that has side effects (such as
+ calling sequence functions); whether the side effects occur
+ might be unpredictable.
+ </para>
+
+ <para>
+ Since the result depends only on whether any rows are returned,
+ and not on the contents of those rows, the output list of the
+ subquery is normally unimportant. A common coding convention is
+ to write all <literal>EXISTS</literal> tests in the form
+ <literal>EXISTS(SELECT 1 WHERE ...)</literal>. There are exceptions to
+ this rule however, such as subqueries that use <token>INTERSECT</token>.
+ </para>
+
+ <para>
+ This simple example is like an inner join on <literal>col2</literal>, but
+ it produces at most one output row for each <literal>tab1</literal> row,
+ even if there are several matching <literal>tab2</literal> rows:
+<screen>
+SELECT col1
+FROM tab1
+WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-in">
+ <title><literal>IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <token>IN</token> is <quote>true</quote> if any equal subquery row is found.
+ The result is <quote>false</quote> if no equal row is found (including the
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <token>IN</token> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>IN</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <token>IN</token> is <quote>true</quote> if any equal subquery row is found.
+ The result is <quote>false</quote> if no equal row is found (including the
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <token>IN</token> is null.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-notin">
+ <title><literal>NOT IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <token>NOT IN</token> is <quote>true</quote> if only unequal subquery rows
+ are found (including the case where the subquery returns no rows).
+ The result is <quote>false</quote> if any equal row is found.
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <token>NOT IN</token> construct will be null, not true.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> NOT IN (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>NOT IN</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <token>NOT IN</token> is <quote>true</quote> if only unequal subquery rows
+ are found (including the case where the subquery returns no rows).
+ The result is <quote>false</quote> if any equal row is found.
+ </para>
+
+ <para>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <token>NOT IN</token> is null.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-any-some">
+ <title><literal>ANY</literal>/<literal>SOME</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ANY</token> is <quote>true</quote> if any true result is obtained.
+ The result is <quote>false</quote> if no true result is found (including the
+ case where the subquery returns no rows).
+ </para>
+
+ <para>
+ <token>SOME</token> is a synonym for <token>ANY</token>.
+ <token>IN</token> is equivalent to <literal>= ANY</literal>.
+ </para>
+
+ <para>
+ Note that if there are no successes and at least one right-hand row yields
+ null for the operator's result, the result of the <token>ANY</token> construct
+ will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>subquery</replaceable>)
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>ANY</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <replaceable>operator</replaceable>.
+ The result of <token>ANY</token> is <quote>true</quote> if the comparison
+ returns true for any subquery row.
+ The result is <quote>false</quote> if the comparison returns false for every
+ subquery row (including the case where the subquery returns no
+ rows).
+ The result is NULL if no comparison with a subquery row returns true,
+ and at least one comparison returns NULL.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"/> for details about the meaning
+ of a row constructor comparison.
+ </para>
+ </sect2>
+
+ <sect2 id="functions-subquery-all">
+ <title><literal>ALL</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ALL</token> is <quote>true</quote> if all rows yield true
+ (including the case where the subquery returns no rows).
+ The result is <quote>false</quote> if any false result is found.
+ The result is NULL if no comparison with a subquery row returns false,
+ and at least one comparison returns NULL.
+ </para>
+
+ <para>
+ <token>NOT IN</token> is equivalent to <literal>&lt;&gt; ALL</literal>.
+ </para>
+
+ <para>
+ As with <token>EXISTS</token>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side of this form of <token>ALL</token> is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <replaceable>operator</replaceable>.
+ The result of <token>ALL</token> is <quote>true</quote> if the comparison
+ returns true for all subquery rows (including the
+ case where the subquery returns no rows).
+ The result is <quote>false</quote> if the comparison returns false for any
+ subquery row.
+ The result is NULL if no comparison with a subquery row returns false,
+ and at least one comparison returns NULL.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"/> for details about the meaning
+ of a row constructor comparison.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Single-Row Comparison</title>
+
+ <indexterm zone="functions-subquery">
+ <primary>comparison</primary>
+ <secondary>subquery result row</secondary>
+ </indexterm>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> (<replaceable>subquery</replaceable>)
+</synopsis>
+
+ <para>
+ The left-hand side is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The right-hand side is a parenthesized subquery, which must return exactly
+ as many columns as there are expressions in the left-hand row. Furthermore,
+ the subquery cannot return more than one row. (If it returns zero rows,
+ the result is taken to be null.) The left-hand side is evaluated and
+ compared row-wise to the single subquery result row.
+ </para>
+
+ <para>
+ See <xref linkend="row-wise-comparison"/> for details about the meaning
+ of a row constructor comparison.
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="functions-comparisons">
+ <title>Row and Array Comparisons</title>
+
+ <indexterm>
+ <primary>IN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>NOT IN</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ANY</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ALL</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>SOME</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>composite type</primary>
+ <secondary>comparison</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>row-wise comparison</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>comparison</primary>
+ <secondary>composite type</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>comparison</primary>
+ <secondary>row constructor</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IS DISTINCT FROM</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>IS NOT DISTINCT FROM</primary>
+ </indexterm>
+
+ <para>
+ This section describes several specialized constructs for making
+ multiple comparisons between groups of values. These forms are
+ syntactically related to the subquery forms of the previous section,
+ but do not involve subqueries.
+ The forms involving array subexpressions are
+ <productname>PostgreSQL</productname> extensions; the rest are
+ <acronym>SQL</acronym>-compliant.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </para>
+
+ <sect2 id="functions-comparisons-in-scalar">
+ <title><literal>IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> IN (<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized list
+ of expressions. The result is <quote>true</quote> if the left-hand expression's
+ result is equal to any of the right-hand expressions. This is a shorthand
+ notation for
+
+<synopsis>
+<replaceable>expression</replaceable> = <replaceable>value1</replaceable>
+OR
+<replaceable>expression</replaceable> = <replaceable>value2</replaceable>
+OR
+...
+</synopsis>
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand expression yields
+ null, the result of the <token>IN</token> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><literal>NOT IN</literal></title>
+
+<synopsis>
+<replaceable>expression</replaceable> NOT IN (<replaceable>value</replaceable> <optional>, ...</optional>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized list
+ of expressions. The result is <quote>true</quote> if the left-hand expression's
+ result is unequal to all of the right-hand expressions. This is a shorthand
+ notation for
+
+<synopsis>
+<replaceable>expression</replaceable> &lt;&gt; <replaceable>value1</replaceable>
+AND
+<replaceable>expression</replaceable> &lt;&gt; <replaceable>value2</replaceable>
+AND
+...
+</synopsis>
+ </para>
+
+ <para>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand expression yields
+ null, the result of the <token>NOT IN</token> construct will be null, not true
+ as one might naively expect.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <tip>
+ <para>
+ <literal>x NOT IN y</literal> is equivalent to <literal>NOT (x IN y)</literal> in all
+ cases. However, null values are much more likely to trip up the novice when
+ working with <token>NOT IN</token> than when working with <token>IN</token>.
+ It is best to express your condition positively if possible.
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2>
+ <title><literal>ANY</literal>/<literal>SOME</literal> (array)</title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ANY (<replaceable>array expression</replaceable>)
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> SOME (<replaceable>array expression</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized expression, which must yield an
+ array value.
+ The left-hand expression
+ is evaluated and compared to each element of the array using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ANY</token> is <quote>true</quote> if any true result is obtained.
+ The result is <quote>false</quote> if no true result is found (including the
+ case where the array has zero elements).
+ </para>
+
+ <para>
+ If the array expression yields a null array, the result of
+ <token>ANY</token> will be null. If the left-hand expression yields null,
+ the result of <token>ANY</token> is ordinarily null (though a non-strict
+ comparison operator could possibly yield a different result).
+ Also, if the right-hand array contains any null elements and no true
+ comparison result is obtained, the result of <token>ANY</token>
+ will be null, not false (again, assuming a strict comparison operator).
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+
+ <para>
+ <token>SOME</token> is a synonym for <token>ANY</token>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><literal>ALL</literal> (array)</title>
+
+<synopsis>
+<replaceable>expression</replaceable> <replaceable>operator</replaceable> ALL (<replaceable>array expression</replaceable>)
+</synopsis>
+
+ <para>
+ The right-hand side is a parenthesized expression, which must yield an
+ array value.
+ The left-hand expression
+ is evaluated and compared to each element of the array using the
+ given <replaceable>operator</replaceable>, which must yield a Boolean
+ result.
+ The result of <token>ALL</token> is <quote>true</quote> if all comparisons yield true
+ (including the case where the array has zero elements).
+ The result is <quote>false</quote> if any false result is found.
+ </para>
+
+ <para>
+ If the array expression yields a null array, the result of
+ <token>ALL</token> will be null. If the left-hand expression yields null,
+ the result of <token>ALL</token> is ordinarily null (though a non-strict
+ comparison operator could possibly yield a different result).
+ Also, if the right-hand array contains any null elements and no false
+ comparison result is obtained, the result of <token>ALL</token>
+ will be null, not true (again, assuming a strict comparison operator).
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </para>
+ </sect2>
+
+ <sect2 id="row-wise-comparison">
+ <title>Row Constructor Comparison</title>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> <replaceable>operator</replaceable> <replaceable>row_constructor</replaceable>
+</synopsis>
+
+ <para>
+ Each side is a row constructor,
+ as described in <xref linkend="sql-syntax-row-constructors"/>.
+ The two row constructors must have the same number of fields.
+ The given <replaceable>operator</replaceable> is applied to each pair
+ of corresponding fields. (Since the fields could be of different
+ types, this means that a different specific operator could be selected
+ for each pair.)
+ All the selected operators must be members of some B-tree operator
+ class, or be the negator of an <literal>=</literal> member of a B-tree
+ operator class, meaning that row constructor comparison is only
+ possible when the <replaceable>operator</replaceable> is
+ <literal>=</literal>,
+ <literal>&lt;&gt;</literal>,
+ <literal>&lt;</literal>,
+ <literal>&lt;=</literal>,
+ <literal>&gt;</literal>, or
+ <literal>&gt;=</literal>,
+ or has semantics similar to one of these.
+ </para>
+
+ <para>
+ The <literal>=</literal> and <literal>&lt;&gt;</literal> cases work slightly differently
+ from the others. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of the row comparison is unknown (null).
+ </para>
+
+ <para>
+ For the <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>&gt;</literal> and
+ <literal>&gt;=</literal> cases, the row elements are compared left-to-right,
+ stopping as soon as an unequal or null pair of elements is found.
+ If either of this pair of elements is null, the result of the
+ row comparison is unknown (null); otherwise comparison of this pair
+ of elements determines the result. For example,
+ <literal>ROW(1,2,NULL) &lt; ROW(1,3,0)</literal>
+ yields true, not null, because the third pair of elements are not
+ considered.
+ </para>
+
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 8.2, the
+ <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>&gt;</literal> and <literal>&gt;=</literal>
+ cases were not handled per SQL specification. A comparison like
+ <literal>ROW(a,b) &lt; ROW(c,d)</literal>
+ was implemented as
+ <literal>a &lt; c AND b &lt; d</literal>
+ whereas the correct behavior is equivalent to
+ <literal>a &lt; c OR (a = c AND b &lt; d)</literal>.
+ </para>
+ </note>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> IS DISTINCT FROM <replaceable>row_constructor</replaceable>
+</synopsis>
+
+ <para>
+ This construct is similar to a <literal>&lt;&gt;</literal> row comparison,
+ but it does not yield null for null inputs. Instead, any null value is
+ considered unequal to (distinct from) any non-null value, and any two
+ nulls are considered equal (not distinct). Thus the result will
+ either be true or false, never null.
+ </para>
+
+<synopsis>
+<replaceable>row_constructor</replaceable> IS NOT DISTINCT FROM <replaceable>row_constructor</replaceable>
+</synopsis>
+
+ <para>
+ This construct is similar to a <literal>=</literal> row comparison,
+ but it does not yield null for null inputs. Instead, any null value is
+ considered unequal to (distinct from) any non-null value, and any two
+ nulls are considered equal (not distinct). Thus the result will always
+ be either true or false, never null.
+ </para>
+
+ </sect2>
+
+ <sect2 id="composite-type-comparison">
+ <title>Composite Type Comparison</title>
+
+<synopsis>
+<replaceable>record</replaceable> <replaceable>operator</replaceable> <replaceable>record</replaceable>
+</synopsis>
+
+ <para>
+ The SQL specification requires row-wise comparison to return NULL if the
+ result depends on comparing two NULL values or a NULL and a non-NULL.
+ <productname>PostgreSQL</productname> does this only when comparing the
+ results of two row constructors (as in
+ <xref linkend="row-wise-comparison"/>) or comparing a row constructor
+ to the output of a subquery (as in <xref linkend="functions-subquery"/>).
+ In other contexts where two composite-type values are compared, two
+ NULL field values are considered equal, and a NULL is considered larger
+ than a non-NULL. This is necessary in order to have consistent sorting
+ and indexing behavior for composite types.
+ </para>
+
+ <para>
+ Each side is evaluated and they are compared row-wise. Composite type
+ comparisons are allowed when the <replaceable>operator</replaceable> is
+ <literal>=</literal>,
+ <literal>&lt;&gt;</literal>,
+ <literal>&lt;</literal>,
+ <literal>&lt;=</literal>,
+ <literal>&gt;</literal> or
+ <literal>&gt;=</literal>,
+ or has semantics similar to one of these. (To be specific, an operator
+ can be a row comparison operator if it is a member of a B-tree operator
+ class, or is the negator of the <literal>=</literal> member of a B-tree operator
+ class.) The default behavior of the above operators is the same as for
+ <literal>IS [ NOT ] DISTINCT FROM</literal> for row constructors (see
+ <xref linkend="row-wise-comparison"/>).
+ </para>
+
+ <para>
+ To support matching of rows which include elements without a default
+ B-tree operator class, the following operators are defined for composite
+ type comparison:
+ <literal>*=</literal>,
+ <literal>*&lt;&gt;</literal>,
+ <literal>*&lt;</literal>,
+ <literal>*&lt;=</literal>,
+ <literal>*&gt;</literal>, and
+ <literal>*&gt;=</literal>.
+ These operators compare the internal binary representation of the two
+ rows. Two rows might have a different binary representation even
+ though comparisons of the two rows with the equality operator is true.
+ The ordering of rows under these comparison operators is deterministic
+ but not otherwise meaningful. These operators are used internally
+ for materialized views and might be useful for other specialized
+ purposes such as replication and B-Tree deduplication (see <xref
+ linkend="btree-deduplication"/>). They are not intended to be
+ generally useful for writing queries, though.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="functions-srf">
+ <title>Set Returning Functions</title>
+
+ <indexterm zone="functions-srf">
+ <primary>set returning functions</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <para>
+ This section describes functions that possibly return more than one row.
+ The most widely used functions in this class are series generating
+ functions, as detailed in <xref linkend="functions-srf-series"/> and
+ <xref linkend="functions-srf-subscripts"/>. Other, more specialized
+ set-returning functions are described elsewhere in this manual.
+ See <xref linkend="queries-tablefunctions"/> for ways to combine multiple
+ set-returning functions.
+ </para>
+
+ <table id="functions-srf-series">
+ <title>Series Generating Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>generate_series</primary>
+ </indexterm>
+ <function>generate_series</function> ( <parameter>start</parameter> <type>integer</type>, <parameter>stop</parameter> <type>integer</type> <optional>, <parameter>step</parameter> <type>integer</type> </optional> )
+ <returnvalue>setof integer</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>generate_series</function> ( <parameter>start</parameter> <type>bigint</type>, <parameter>stop</parameter> <type>bigint</type> <optional>, <parameter>step</parameter> <type>bigint</type> </optional> )
+ <returnvalue>setof bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>generate_series</function> ( <parameter>start</parameter> <type>numeric</type>, <parameter>stop</parameter> <type>numeric</type> <optional>, <parameter>step</parameter> <type>numeric</type> </optional> )
+ <returnvalue>setof numeric</returnvalue>
+ </para>
+ <para>
+ Generates a series of values from <parameter>start</parameter>
+ to <parameter>stop</parameter>, with a step size
+ of <parameter>step</parameter>. <parameter>step</parameter>
+ defaults to 1.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>generate_series</function> ( <parameter>start</parameter> <type>timestamp</type>, <parameter>stop</parameter> <type>timestamp</type>, <parameter>step</parameter> <type>interval</type> )
+ <returnvalue>setof timestamp</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>generate_series</function> ( <parameter>start</parameter> <type>timestamp with time zone</type>, <parameter>stop</parameter> <type>timestamp with time zone</type>, <parameter>step</parameter> <type>interval</type> )
+ <returnvalue>setof timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Generates a series of values from <parameter>start</parameter>
+ to <parameter>stop</parameter>, with a step size
+ of <parameter>step</parameter>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ When <parameter>step</parameter> is positive, zero rows are returned if
+ <parameter>start</parameter> is greater than <parameter>stop</parameter>.
+ Conversely, when <parameter>step</parameter> is negative, zero rows are
+ returned if <parameter>start</parameter> is less than <parameter>stop</parameter>.
+ Zero rows are also returned if any input is <literal>NULL</literal>.
+ It is an error
+ for <parameter>step</parameter> to be zero. Some examples follow:
+<programlisting>
+SELECT * FROM generate_series(2,4);
+ generate_series
+-----------------
+ 2
+ 3
+ 4
+(3 rows)
+
+SELECT * FROM generate_series(5,1,-2);
+ generate_series
+-----------------
+ 5
+ 3
+ 1
+(3 rows)
+
+SELECT * FROM generate_series(4,3);
+ generate_series
+-----------------
+(0 rows)
+
+SELECT generate_series(1.1, 4, 1.3);
+ generate_series
+-----------------
+ 1.1
+ 2.4
+ 3.7
+(3 rows)
+
+-- this example relies on the date-plus-integer operator:
+SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
+ dates
+------------
+ 2004-02-05
+ 2004-02-12
+ 2004-02-19
+(3 rows)
+
+SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
+ '2008-03-04 12:00', '10 hours');
+ generate_series
+---------------------
+ 2008-03-01 00:00:00
+ 2008-03-01 10:00:00
+ 2008-03-01 20:00:00
+ 2008-03-02 06:00:00
+ 2008-03-02 16:00:00
+ 2008-03-03 02:00:00
+ 2008-03-03 12:00:00
+ 2008-03-03 22:00:00
+ 2008-03-04 08:00:00
+(9 rows)
+</programlisting>
+ </para>
+
+ <table id="functions-srf-subscripts">
+ <title>Subscript Generating Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>generate_subscripts</primary>
+ </indexterm>
+ <function>generate_subscripts</function> ( <parameter>array</parameter> <type>anyarray</type>, <parameter>dim</parameter> <type>integer</type> )
+ <returnvalue>setof integer</returnvalue>
+ </para>
+ <para>
+ Generates a series comprising the valid subscripts of
+ the <parameter>dim</parameter>'th dimension of the given array.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>generate_subscripts</function> ( <parameter>array</parameter> <type>anyarray</type>, <parameter>dim</parameter> <type>integer</type>, <parameter>reverse</parameter> <type>boolean</type> )
+ <returnvalue>setof integer</returnvalue>
+ </para>
+ <para>
+ Generates a series comprising the valid subscripts of
+ the <parameter>dim</parameter>'th dimension of the given array.
+ When <parameter>reverse</parameter> is true, returns the series in
+ reverse order.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <function>generate_subscripts</function> is a convenience function that generates
+ the set of valid subscripts for the specified dimension of the given
+ array.
+ Zero rows are returned for arrays that do not have the requested dimension,
+ or if any input is <literal>NULL</literal>.
+ Some examples follow:
+<programlisting>
+-- basic usage:
+SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s;
+ s
+---
+ 1
+ 2
+ 3
+ 4
+(4 rows)
+
+-- presenting an array, the subscript and the subscripted
+-- value requires a subquery:
+SELECT * FROM arrays;
+ a
+--------------------
+ {-1,-2}
+ {100,200,300}
+(2 rows)
+
+SELECT a AS array, s AS subscript, a[s] AS value
+FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo;
+ array | subscript | value
+---------------+-----------+-------
+ {-1,-2} | 1 | -1
+ {-1,-2} | 2 | -2
+ {100,200,300} | 1 | 100
+ {100,200,300} | 2 | 200
+ {100,200,300} | 3 | 300
+(5 rows)
+
+-- unnest a 2D array:
+CREATE OR REPLACE FUNCTION unnest2(anyarray)
+RETURNS SETOF anyelement AS $$
+select $1[i][j]
+ from generate_subscripts($1,1) g1(i),
+ generate_subscripts($1,2) g2(j);
+$$ LANGUAGE sql IMMUTABLE;
+CREATE FUNCTION
+SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]);
+ unnest2
+---------
+ 1
+ 2
+ 3
+ 4
+(4 rows)
+</programlisting>
+ </para>
+
+ <indexterm>
+ <primary>ordinality</primary>
+ </indexterm>
+
+ <para>
+ When a function in the <literal>FROM</literal> clause is suffixed
+ by <literal>WITH ORDINALITY</literal>, a <type>bigint</type> column is
+ appended to the function's output column(s), which starts from 1 and
+ increments by 1 for each row of the function's output.
+ This is most useful in the case of set returning
+ functions such as <function>unnest()</function>.
+
+<programlisting>
+-- set returning function WITH ORDINALITY:
+SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
+ ls | n
+-----------------+----
+ pg_serial | 1
+ pg_twophase | 2
+ postmaster.opts | 3
+ pg_notify | 4
+ postgresql.conf | 5
+ pg_tblspc | 6
+ logfile | 7
+ base | 8
+ postmaster.pid | 9
+ pg_ident.conf | 10
+ global | 11
+ pg_xact | 12
+ pg_snapshots | 13
+ pg_multixact | 14
+ PG_VERSION | 15
+ pg_wal | 16
+ pg_hba.conf | 17
+ pg_stat_tmp | 18
+ pg_subtrans | 19
+(19 rows)
+</programlisting>
+ </para>
+
+ </sect1>
+
+ <sect1 id="functions-info">
+ <title>System Information Functions and Operators</title>
+
+ <para>
+ <xref linkend="functions-info-session-table"/> shows several
+ functions that extract session and system information.
+ </para>
+
+ <para>
+ In addition to the functions listed in this section, there are a number of
+ functions related to the statistics system that also provide system
+ information. See <xref linkend="monitoring-stats-views"/> for more
+ information.
+ </para>
+
+ <table id="functions-info-session-table">
+ <title>Session Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_catalog</primary>
+ </indexterm>
+ <function>current_catalog</function>
+ <returnvalue>name</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm>
+ <primary>current_database</primary>
+ </indexterm>
+ <function>current_database</function> ()
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Returns the name of the current database. (Databases are
+ called <quote>catalogs</quote> in the SQL standard,
+ so <function>current_catalog</function> is the standard's
+ spelling.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_query</primary>
+ </indexterm>
+ <function>current_query</function> ()
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the text of the currently executing query, as submitted
+ by the client (which might contain more than one statement).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_role</primary>
+ </indexterm>
+ <function>current_role</function>
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ This is equivalent to <function>current_user</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_schema</primary>
+ </indexterm>
+ <indexterm>
+ <primary>schema</primary>
+ <secondary>current</secondary>
+ </indexterm>
+ <function>current_schema</function>
+ <returnvalue>name</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>current_schema</function> ()
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Returns the name of the schema that is first in the search path (or a
+ null value if the search path is empty). This is the schema that will
+ be used for any tables or other named objects that are created without
+ specifying a target schema.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_schemas</primary>
+ </indexterm>
+ <indexterm>
+ <primary>search path</primary>
+ <secondary>current</secondary>
+ </indexterm>
+ <function>current_schemas</function> ( <parameter>include_implicit</parameter> <type>boolean</type> )
+ <returnvalue>name[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of the names of all schemas presently in the
+ effective search path, in their priority order. (Items in the current
+ <xref linkend="guc-search-path"/> setting that do not correspond to
+ existing, searchable schemas are omitted.) If the Boolean argument
+ is <literal>true</literal>, then implicitly-searched system schemas
+ such as <literal>pg_catalog</literal> are included in the result.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_user</primary>
+ </indexterm>
+ <indexterm>
+ <primary>user</primary>
+ <secondary>current</secondary>
+ </indexterm>
+ <function>current_user</function>
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Returns the user name of the current execution context.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>inet_client_addr</primary>
+ </indexterm>
+ <function>inet_client_addr</function> ()
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Returns the IP address of the current client,
+ or <literal>NULL</literal> if the current connection is via a
+ Unix-domain socket.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>inet_client_port</primary>
+ </indexterm>
+ <function>inet_client_port</function> ()
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the IP port number of the current client,
+ or <literal>NULL</literal> if the current connection is via a
+ Unix-domain socket.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>inet_server_addr</primary>
+ </indexterm>
+ <function>inet_server_addr</function> ()
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Returns the IP address on which the server accepted the current
+ connection,
+ or <literal>NULL</literal> if the current connection is via a
+ Unix-domain socket.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>inet_server_port</primary>
+ </indexterm>
+ <function>inet_server_port</function> ()
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the IP port number on which the server accepted the current
+ connection,
+ or <literal>NULL</literal> if the current connection is via a
+ Unix-domain socket.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_backend_pid</primary>
+ </indexterm>
+ <function>pg_backend_pid</function> ()
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the process ID of the server process attached to the current
+ session.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_blocking_pids</primary>
+ </indexterm>
+ <function>pg_blocking_pids</function> ( <type>integer</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of the process ID(s) of the sessions that are
+ blocking the server process with the specified process ID from
+ acquiring a lock, or an empty array if there is no such server process
+ or it is not blocked.
+ </para>
+ <para>
+ One server process blocks another if it either holds a lock that
+ conflicts with the blocked process's lock request (hard block), or is
+ waiting for a lock that would conflict with the blocked process's lock
+ request and is ahead of it in the wait queue (soft block). When using
+ parallel queries the result always lists client-visible process IDs
+ (that is, <function>pg_backend_pid</function> results) even if the
+ actual lock is held or awaited by a child worker process. As a result
+ of that, there may be duplicated PIDs in the result. Also note that
+ when a prepared transaction holds a conflicting lock, it will be
+ represented by a zero process ID.
+ </para>
+ <para>
+ Frequent calls to this function could have some impact on database
+ performance, because it needs exclusive access to the lock manager's
+ shared state for a short time.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_conf_load_time</primary>
+ </indexterm>
+ <function>pg_conf_load_time</function> ()
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the time when the server configuration files were last loaded.
+ If the current session was alive at the time, this will be the time
+ when the session itself re-read the configuration files (so the
+ reading will vary a little in different sessions). Otherwise it is
+ the time when the postmaster process re-read the configuration files.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_logfile</primary>
+ </indexterm>
+ <indexterm>
+ <primary>Logging</primary>
+ <secondary>pg_current_logfile function</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>current_logfiles</primary>
+ <secondary>and the pg_current_logfile function</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>Logging</primary>
+ <secondary>current_logfiles file and the pg_current_logfile
+ function</secondary>
+ </indexterm>
+ <function>pg_current_logfile</function> ( <optional> <type>text</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the path name of the log file currently in use by the logging
+ collector. The path includes the <xref linkend="guc-log-directory"/>
+ directory and the individual log file name. The result
+ is <literal>NULL</literal> if the logging collector is disabled.
+ When multiple log files exist, each in a different
+ format, <function>pg_current_logfile</function> without an argument
+ returns the path of the file having the first format found in the
+ ordered list: <literal>stderr</literal>,
+ <literal>csvlog</literal>, <literal>jsonlog</literal>.
+ <literal>NULL</literal> is returned if no log file has any of these
+ formats.
+ To request information about a specific log file format, supply
+ either <literal>csvlog</literal>, <literal>jsonlog</literal> or
+ <literal>stderr</literal> as the
+ value of the optional parameter. The result is <literal>NULL</literal>
+ if the log format requested is not configured in
+ <xref linkend="guc-log-destination"/>.
+ The result reflects the contents of
+ the <filename>current_logfiles</filename> file.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_my_temp_schema</primary>
+ </indexterm>
+ <function>pg_my_temp_schema</function> ()
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Returns the OID of the current session's temporary schema, or zero if
+ it has none (because it has not created any temporary tables).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_is_other_temp_schema</primary>
+ </indexterm>
+ <function>pg_is_other_temp_schema</function> ( <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if the given OID is the OID of another session's
+ temporary schema. (This can be useful, for example, to exclude other
+ sessions' temporary tables from a catalog display.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_jit_available</primary>
+ </indexterm>
+ <function>pg_jit_available</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if a <acronym>JIT</acronym> compiler extension is
+ available (see <xref linkend="jit"/>) and the
+ <xref linkend="guc-jit"/> configuration parameter is set to
+ <literal>on</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_listening_channels</primary>
+ </indexterm>
+ <function>pg_listening_channels</function> ()
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Returns the set of names of asynchronous notification channels that
+ the current session is listening to.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_notification_queue_usage</primary>
+ </indexterm>
+ <function>pg_notification_queue_usage</function> ()
+ <returnvalue>double precision</returnvalue>
+ </para>
+ <para>
+ Returns the fraction (0&ndash;1) of the asynchronous notification
+ queue's maximum size that is currently occupied by notifications that
+ are waiting to be processed.
+ See <xref linkend="sql-listen"/> and <xref linkend="sql-notify"/>
+ for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_postmaster_start_time</primary>
+ </indexterm>
+ <function>pg_postmaster_start_time</function> ()
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the time when the server started.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_safe_snapshot_blocking_pids</primary>
+ </indexterm>
+ <function>pg_safe_snapshot_blocking_pids</function> ( <type>integer</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of the process ID(s) of the sessions that are blocking
+ the server process with the specified process ID from acquiring a safe
+ snapshot, or an empty array if there is no such server process or it
+ is not blocked.
+ </para>
+ <para>
+ A session running a <literal>SERIALIZABLE</literal> transaction blocks
+ a <literal>SERIALIZABLE READ ONLY DEFERRABLE</literal> transaction
+ from acquiring a snapshot until the latter determines that it is safe
+ to avoid taking any predicate locks. See
+ <xref linkend="xact-serializable"/> for more information about
+ serializable and deferrable transactions.
+ </para>
+ <para>
+ Frequent calls to this function could have some impact on database
+ performance, because it needs access to the predicate lock manager's
+ shared state for a short time.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_trigger_depth</primary>
+ </indexterm>
+ <function>pg_trigger_depth</function> ()
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the current nesting level
+ of <productname>PostgreSQL</productname> triggers (0 if not called,
+ directly or indirectly, from inside a trigger).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>session_user</primary>
+ </indexterm>
+ <function>session_user</function>
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Returns the session user's name.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>user</primary>
+ </indexterm>
+ <function>user</function>
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ This is equivalent to <function>current_user</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>version</primary>
+ </indexterm>
+ <function>version</function> ()
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns a string describing the <productname>PostgreSQL</productname>
+ server's version. You can also get this information from
+ <xref linkend="guc-server-version"/>, or for a machine-readable
+ version use <xref linkend="guc-server-version-num"/>. Software
+ developers should use <varname>server_version_num</varname> (available
+ since 8.2) or <xref linkend="libpq-PQserverVersion"/> instead of
+ parsing the text version.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ <function>current_catalog</function>,
+ <function>current_role</function>,
+ <function>current_schema</function>,
+ <function>current_user</function>,
+ <function>session_user</function>,
+ and <function>user</function> have special syntactic status
+ in <acronym>SQL</acronym>: they must be called without trailing
+ parentheses. In PostgreSQL, parentheses can optionally be used with
+ <function>current_schema</function>, but not with the others.
+ </para>
+ </note>
+
+ <para>
+ The <function>session_user</function> is normally the user who initiated
+ the current database connection; but superusers can change this setting
+ with <xref linkend="sql-set-session-authorization"/>.
+ The <function>current_user</function> is the user identifier
+ that is applicable for permission checking. Normally it is equal
+ to the session user, but it can be changed with
+ <xref linkend="sql-set-role"/>.
+ It also changes during the execution of
+ functions with the attribute <literal>SECURITY DEFINER</literal>.
+ In Unix parlance, the session user is the <quote>real user</quote> and
+ the current user is the <quote>effective user</quote>.
+ <function>current_role</function> and <function>user</function> are
+ synonyms for <function>current_user</function>. (The SQL standard draws
+ a distinction between <function>current_role</function>
+ and <function>current_user</function>, but <productname>PostgreSQL</productname>
+ does not, since it unifies users and roles into a single kind of entity.)
+ </para>
+
+ <indexterm>
+ <primary>privilege</primary>
+ <secondary>querying</secondary>
+ </indexterm>
+
+ <para>
+ <xref linkend="functions-info-access-table"/> lists functions that
+ allow querying object access privileges programmatically.
+ (See <xref linkend="ddl-priv"/> for more information about
+ privileges.)
+ In these functions, the user whose privileges are being inquired about
+ can be specified by name or by OID
+ (<structname>pg_authid</structname>.<structfield>oid</structfield>), or if
+ the name is given as <literal>public</literal> then the privileges of the
+ PUBLIC pseudo-role are checked. Also, the <parameter>user</parameter>
+ argument can be omitted entirely, in which case
+ the <function>current_user</function> is assumed.
+ The object that is being inquired about can be specified either by name or
+ by OID, too. When specifying by name, a schema name can be included if
+ relevant.
+ The access privilege of interest is specified by a text string, which must
+ evaluate to one of the appropriate privilege keywords for the object's type
+ (e.g., <literal>SELECT</literal>). Optionally, <literal>WITH GRANT
+ OPTION</literal> can be added to a privilege type to test whether the
+ privilege is held with grant option. Also, multiple privilege types can be
+ listed separated by commas, in which case the result will be true if any of
+ the listed privileges is held. (Case of the privilege string is not
+ significant, and extra whitespace is allowed between but not within
+ privilege names.)
+ Some examples:
+<programlisting>
+SELECT has_table_privilege('myschema.mytable', 'select');
+SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');
+</programlisting>
+ </para>
+
+ <table id="functions-info-access-table">
+ <title>Access Privilege Inquiry Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_any_column_privilege</primary>
+ </indexterm>
+ <function>has_any_column_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>table</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for any column of table?
+ This succeeds either if the privilege is held for the whole table, or
+ if there is a column-level grant of the privilege for at least one
+ column.
+ Allowable privilege types are
+ <literal>SELECT</literal>, <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, and <literal>REFERENCES</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_column_privilege</primary>
+ </indexterm>
+ <function>has_column_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>table</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>column</parameter> <type>text</type> or <type>smallint</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for the specified table column?
+ This succeeds either if the privilege is held for the whole table, or
+ if there is a column-level grant of the privilege for the column.
+ The column can be specified by name or by attribute number
+ (<structname>pg_attribute</structname>.<structfield>attnum</structfield>).
+ Allowable privilege types are
+ <literal>SELECT</literal>, <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, and <literal>REFERENCES</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_database_privilege</primary>
+ </indexterm>
+ <function>has_database_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>database</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for database?
+ Allowable privilege types are
+ <literal>CREATE</literal>,
+ <literal>CONNECT</literal>,
+ <literal>TEMPORARY</literal>, and
+ <literal>TEMP</literal> (which is equivalent to
+ <literal>TEMPORARY</literal>).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_foreign_data_wrapper_privilege</primary>
+ </indexterm>
+ <function>has_foreign_data_wrapper_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>fdw</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for foreign-data wrapper?
+ The only allowable privilege type is <literal>USAGE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_function_privilege</primary>
+ </indexterm>
+ <function>has_function_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>function</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for function?
+ The only allowable privilege type is <literal>EXECUTE</literal>.
+ </para>
+ <para>
+ When specifying a function by name rather than by OID, the allowed
+ input is the same as for the <type>regprocedure</type> data type (see
+ <xref linkend="datatype-oid"/>).
+ An example is:
+<programlisting>
+SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_language_privilege</primary>
+ </indexterm>
+ <function>has_language_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>language</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for language?
+ The only allowable privilege type is <literal>USAGE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_parameter_privilege</primary>
+ </indexterm>
+ <function>has_parameter_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>parameter</parameter> <type>text</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for configuration parameter?
+ The parameter name is case-insensitive.
+ Allowable privilege types are <literal>SET</literal>
+ and <literal>ALTER SYSTEM</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_schema_privilege</primary>
+ </indexterm>
+ <function>has_schema_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>schema</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for schema?
+ Allowable privilege types are
+ <literal>CREATE</literal> and
+ <literal>USAGE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_sequence_privilege</primary>
+ </indexterm>
+ <function>has_sequence_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>sequence</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for sequence?
+ Allowable privilege types are
+ <literal>USAGE</literal>,
+ <literal>SELECT</literal>, and
+ <literal>UPDATE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_server_privilege</primary>
+ </indexterm>
+ <function>has_server_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>server</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for foreign server?
+ The only allowable privilege type is <literal>USAGE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_table_privilege</primary>
+ </indexterm>
+ <function>has_table_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>table</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for table?
+ Allowable privilege types
+ are <literal>SELECT</literal>, <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, <literal>DELETE</literal>,
+ <literal>TRUNCATE</literal>, <literal>REFERENCES</literal>,
+ and <literal>TRIGGER</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_tablespace_privilege</primary>
+ </indexterm>
+ <function>has_tablespace_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>tablespace</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for tablespace?
+ The only allowable privilege type is <literal>CREATE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>has_type_privilege</primary>
+ </indexterm>
+ <function>has_type_privilege</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>type</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for data type?
+ The only allowable privilege type is <literal>USAGE</literal>.
+ When specifying a type by name rather than by OID, the allowed input
+ is the same as for the <type>regtype</type> data type (see
+ <xref linkend="datatype-oid"/>).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_has_role</primary>
+ </indexterm>
+ <function>pg_has_role</function> (
+ <optional> <parameter>user</parameter> <type>name</type> or <type>oid</type>, </optional>
+ <parameter>role</parameter> <type>text</type> or <type>oid</type>,
+ <parameter>privilege</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does user have privilege for role?
+ Allowable privilege types are
+ <literal>MEMBER</literal> and <literal>USAGE</literal>.
+ <literal>MEMBER</literal> denotes direct or indirect membership in
+ the role (that is, the right to do <command>SET ROLE</command>), while
+ <literal>USAGE</literal> denotes whether the privileges of the role
+ are immediately available without doing <command>SET ROLE</command>.
+ This function does not allow the special case of
+ setting <parameter>user</parameter> to <literal>public</literal>,
+ because the PUBLIC pseudo-role can never be a member of real roles.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>row_security_active</primary>
+ </indexterm>
+ <function>row_security_active</function> (
+ <parameter>table</parameter> <type>text</type> or <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is row-level security active for the specified table in the context of
+ the current user and current environment?
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-aclitem-op-table"/> shows the operators
+ available for the <type>aclitem</type> type, which is the catalog
+ representation of access privileges. See <xref linkend="ddl-priv"/>
+ for information about how to read access privilege values.
+ </para>
+
+ <table id="functions-aclitem-op-table">
+ <title><type>aclitem</type> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>aclitemeq</primary>
+ </indexterm>
+ <type>aclitem</type> <literal>=</literal> <type>aclitem</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are <type>aclitem</type>s equal? (Notice that
+ type <type>aclitem</type> lacks the usual set of comparison
+ operators; it has only equality. In turn, <type>aclitem</type>
+ arrays can only be compared for equality.)
+ </para>
+ <para>
+ <literal>'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>aclcontains</primary>
+ </indexterm>
+ <type>aclitem[]</type> <literal>@&gt;</literal> <type>aclitem</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array contain the specified privileges? (This is true if there
+ is an array entry that matches the <type>aclitem</type>'s grantee and
+ grantor, and has at least the specified set of privileges.)
+ </para>
+ <para>
+ <literal>'{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @&gt; 'calvin=r*/hobbes'::aclitem</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>aclitem[]</type> <literal>~</literal> <type>aclitem</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ This is a deprecated alias for <literal>@&gt;</literal>.
+ </para>
+ <para>
+ <literal>'{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] ~ 'calvin=r*/hobbes'::aclitem</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-aclitem-fn-table"/> shows some additional
+ functions to manage the <type>aclitem</type> type.
+ </para>
+
+ <table id="functions-aclitem-fn-table">
+ <title><type>aclitem</type> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>acldefault</primary>
+ </indexterm>
+ <function>acldefault</function> (
+ <parameter>type</parameter> <type>"char"</type>,
+ <parameter>ownerId</parameter> <type>oid</type> )
+ <returnvalue>aclitem[]</returnvalue>
+ </para>
+ <para>
+ Constructs an <type>aclitem</type> array holding the default access
+ privileges for an object of type <parameter>type</parameter> belonging
+ to the role with OID <parameter>ownerId</parameter>. This represents
+ the access privileges that will be assumed when an object's ACL entry
+ is null. (The default access privileges are described in
+ <xref linkend="ddl-priv"/>.)
+ The <parameter>type</parameter> parameter must be one of
+ 'c' for <literal>COLUMN</literal>,
+ 'r' for <literal>TABLE</literal> and table-like objects,
+ 's' for <literal>SEQUENCE</literal>,
+ 'd' for <literal>DATABASE</literal>,
+ 'f' for <literal>FUNCTION</literal> or <literal>PROCEDURE</literal>,
+ 'l' for <literal>LANGUAGE</literal>,
+ 'L' for <literal>LARGE OBJECT</literal>,
+ 'n' for <literal>SCHEMA</literal>,
+ 'p' for <literal>PARAMETER</literal>,
+ 't' for <literal>TABLESPACE</literal>,
+ 'F' for <literal>FOREIGN DATA WRAPPER</literal>,
+ 'S' for <literal>FOREIGN SERVER</literal>,
+ or
+ 'T' for <literal>TYPE</literal> or <literal>DOMAIN</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>aclexplode</primary>
+ </indexterm>
+ <function>aclexplode</function> ( <type>aclitem[]</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>grantor</parameter> <type>oid</type>,
+ <parameter>grantee</parameter> <type>oid</type>,
+ <parameter>privilege_type</parameter> <type>text</type>,
+ <parameter>is_grantable</parameter> <type>boolean</type> )
+ </para>
+ <para>
+ Returns the <type>aclitem</type> array as a set of rows.
+ If the grantee is the pseudo-role PUBLIC, it is represented by zero in
+ the <parameter>grantee</parameter> column. Each granted privilege is
+ represented as <literal>SELECT</literal>, <literal>INSERT</literal>,
+ etc. Note that each privilege is broken out as a separate row, so
+ only one keyword appears in the <parameter>privilege_type</parameter>
+ column.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>makeaclitem</primary>
+ </indexterm>
+ <function>makeaclitem</function> (
+ <parameter>grantee</parameter> <type>oid</type>,
+ <parameter>grantor</parameter> <type>oid</type>,
+ <parameter>privileges</parameter> <type>text</type>,
+ <parameter>is_grantable</parameter> <type>boolean</type> )
+ <returnvalue>aclitem</returnvalue>
+ </para>
+ <para>
+ Constructs an <type>aclitem</type> with the given properties.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-info-schema-table"/> shows functions that
+ determine whether a certain object is <firstterm>visible</firstterm> in the
+ current schema search path.
+ For example, a table is said to be visible if its
+ containing schema is in the search path and no table of the same
+ name appears earlier in the search path. This is equivalent to the
+ statement that the table can be referenced by name without explicit
+ schema qualification. Thus, to list the names of all visible tables:
+<programlisting>
+SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
+</programlisting>
+ For functions and operators, an object in the search path is said to be
+ visible if there is no object of the same name <emphasis>and argument data
+ type(s)</emphasis> earlier in the path. For operator classes and families,
+ both the name and the associated index access method are considered.
+ </para>
+
+ <indexterm>
+ <primary>search path</primary>
+ <secondary>object visibility</secondary>
+ </indexterm>
+
+ <table id="functions-info-schema-table">
+ <title>Schema Visibility Inquiry Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_collation_is_visible</primary>
+ </indexterm>
+ <function>pg_collation_is_visible</function> ( <parameter>collation</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is collation visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_conversion_is_visible</primary>
+ </indexterm>
+ <function>pg_conversion_is_visible</function> ( <parameter>conversion</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is conversion visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_function_is_visible</primary>
+ </indexterm>
+ <function>pg_function_is_visible</function> ( <parameter>function</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is function visible in search path?
+ (This also works for procedures and aggregates.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_opclass_is_visible</primary>
+ </indexterm>
+ <function>pg_opclass_is_visible</function> ( <parameter>opclass</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is operator class visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_operator_is_visible</primary>
+ </indexterm>
+ <function>pg_operator_is_visible</function> ( <parameter>operator</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is operator visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_opfamily_is_visible</primary>
+ </indexterm>
+ <function>pg_opfamily_is_visible</function> ( <parameter>opclass</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is operator family visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_statistics_obj_is_visible</primary>
+ </indexterm>
+ <function>pg_statistics_obj_is_visible</function> ( <parameter>stat</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is statistics object visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_table_is_visible</primary>
+ </indexterm>
+ <function>pg_table_is_visible</function> ( <parameter>table</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is table visible in search path?
+ (This works for all types of relations, including views, materialized
+ views, indexes, sequences and foreign tables.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ts_config_is_visible</primary>
+ </indexterm>
+ <function>pg_ts_config_is_visible</function> ( <parameter>config</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is text search configuration visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ts_dict_is_visible</primary>
+ </indexterm>
+ <function>pg_ts_dict_is_visible</function> ( <parameter>dict</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is text search dictionary visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ts_parser_is_visible</primary>
+ </indexterm>
+ <function>pg_ts_parser_is_visible</function> ( <parameter>parser</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is text search parser visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ts_template_is_visible</primary>
+ </indexterm>
+ <function>pg_ts_template_is_visible</function> ( <parameter>template</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is text search template visible in search path?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_type_is_visible</primary>
+ </indexterm>
+ <function>pg_type_is_visible</function> ( <parameter>type</parameter> <type>oid</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is type (or domain) visible in search path?
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ All these functions require object OIDs to identify the object to be
+ checked. If you want to test an object by name, it is convenient to use
+ the OID alias types (<type>regclass</type>, <type>regtype</type>,
+ <type>regprocedure</type>, <type>regoperator</type>, <type>regconfig</type>,
+ or <type>regdictionary</type>),
+ for example:
+<programlisting>
+SELECT pg_type_is_visible('myschema.widget'::regtype);
+</programlisting>
+ Note that it would not make much sense to test a non-schema-qualified
+ type name in this way &mdash; if the name can be recognized at all, it must be visible.
+ </para>
+
+ <para>
+ <xref linkend="functions-info-catalog-table"/> lists functions that
+ extract information from the system catalogs.
+ </para>
+
+ <table id="functions-info-catalog-table">
+ <title>System Catalog Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>format_type</primary>
+ </indexterm>
+ <function>format_type</function> ( <parameter>type</parameter> <type>oid</type>, <parameter>typemod</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the SQL name for a data type that is identified by its type
+ OID and possibly a type modifier. Pass NULL for the type modifier if
+ no specific modifier is known.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-char-to-encoding" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_char_to_encoding</primary>
+ </indexterm>
+ <function>pg_char_to_encoding</function> ( <parameter>encoding</parameter> <type>name</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Converts the supplied encoding name into an integer representing the
+ internal identifier used in some system catalog tables.
+ Returns <literal>-1</literal> if an unknown encoding name is provided.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-encoding-to-char" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_encoding_to_char</primary>
+ </indexterm>
+ <function>pg_encoding_to_char</function> ( <parameter>encoding</parameter> <type>integer</type> )
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Converts the integer used as the internal identifier of an encoding in some
+ system catalog tables into a human-readable string.
+ Returns an empty string if an invalid encoding number is provided.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_catalog_foreign_keys</primary>
+ </indexterm>
+ <function>pg_get_catalog_foreign_keys</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>fktable</parameter> <type>regclass</type>,
+ <parameter>fkcols</parameter> <type>text[]</type>,
+ <parameter>pktable</parameter> <type>regclass</type>,
+ <parameter>pkcols</parameter> <type>text[]</type>,
+ <parameter>is_array</parameter> <type>boolean</type>,
+ <parameter>is_opt</parameter> <type>boolean</type> )
+ </para>
+ <para>
+ Returns a set of records describing the foreign key relationships
+ that exist within the <productname>PostgreSQL</productname> system
+ catalogs.
+ The <parameter>fktable</parameter> column contains the name of the
+ referencing catalog, and the <parameter>fkcols</parameter> column
+ contains the name(s) of the referencing column(s). Similarly,
+ the <parameter>pktable</parameter> column contains the name of the
+ referenced catalog, and the <parameter>pkcols</parameter> column
+ contains the name(s) of the referenced column(s).
+ If <parameter>is_array</parameter> is true, the last referencing
+ column is an array, each of whose elements should match some entry
+ in the referenced catalog.
+ If <parameter>is_opt</parameter> is true, the referencing column(s)
+ are allowed to contain zeroes instead of a valid reference.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_constraintdef</primary>
+ </indexterm>
+ <function>pg_get_constraintdef</function> ( <parameter>constraint</parameter> <type>oid</type> <optional>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the creating command for a constraint.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_expr</primary>
+ </indexterm>
+ <function>pg_get_expr</function> ( <parameter>expr</parameter> <type>pg_node_tree</type>, <parameter>relation</parameter> <type>oid</type> <optional>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Decompiles the internal form of an expression stored in the system
+ catalogs, such as the default value for a column. If the expression
+ might contain Vars, specify the OID of the relation they refer to as
+ the second parameter; if no Vars are expected, passing zero is
+ sufficient.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_functiondef</primary>
+ </indexterm>
+ <function>pg_get_functiondef</function> ( <parameter>func</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the creating command for a function or procedure.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ The result is a complete <command>CREATE OR REPLACE FUNCTION</command>
+ or <command>CREATE OR REPLACE PROCEDURE</command> statement.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_function_arguments</primary>
+ </indexterm>
+ <function>pg_get_function_arguments</function> ( <parameter>func</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the argument list of a function or procedure, in the form
+ it would need to appear in within <command>CREATE FUNCTION</command>
+ (including default values).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_function_identity_arguments</primary>
+ </indexterm>
+ <function>pg_get_function_identity_arguments</function> ( <parameter>func</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the argument list necessary to identify a function or
+ procedure, in the form it would need to appear in within commands such
+ as <command>ALTER FUNCTION</command>. This form omits default values.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_function_result</primary>
+ </indexterm>
+ <function>pg_get_function_result</function> ( <parameter>func</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the <literal>RETURNS</literal> clause of a function, in
+ the form it would need to appear in within <command>CREATE
+ FUNCTION</command>. Returns <literal>NULL</literal> for a procedure.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_indexdef</primary>
+ </indexterm>
+ <function>pg_get_indexdef</function> ( <parameter>index</parameter> <type>oid</type> <optional>, <parameter>column</parameter> <type>integer</type>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the creating command for an index.
+ (This is a decompiled reconstruction, not the original text
+ of the command.) If <parameter>column</parameter> is supplied and is
+ not zero, only the definition of that column is reconstructed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_keywords</primary>
+ </indexterm>
+ <function>pg_get_keywords</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>word</parameter> <type>text</type>,
+ <parameter>catcode</parameter> <type>"char"</type>,
+ <parameter>barelabel</parameter> <type>boolean</type>,
+ <parameter>catdesc</parameter> <type>text</type>,
+ <parameter>baredesc</parameter> <type>text</type> )
+ </para>
+ <para>
+ Returns a set of records describing the SQL keywords recognized by the
+ server. The <parameter>word</parameter> column contains the
+ keyword. The <parameter>catcode</parameter> column contains a
+ category code: <literal>U</literal> for an unreserved
+ keyword, <literal>C</literal> for a keyword that can be a column
+ name, <literal>T</literal> for a keyword that can be a type or
+ function name, or <literal>R</literal> for a fully reserved keyword.
+ The <parameter>barelabel</parameter> column
+ contains <literal>true</literal> if the keyword can be used as
+ a <quote>bare</quote> column label in <command>SELECT</command> lists,
+ or <literal>false</literal> if it can only be used
+ after <literal>AS</literal>.
+ The <parameter>catdesc</parameter> column contains a
+ possibly-localized string describing the keyword's category.
+ The <parameter>baredesc</parameter> column contains a
+ possibly-localized string describing the keyword's column label status.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_ruledef</primary>
+ </indexterm>
+ <function>pg_get_ruledef</function> ( <parameter>rule</parameter> <type>oid</type> <optional>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the creating command for a rule.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_serial_sequence</primary>
+ </indexterm>
+ <function>pg_get_serial_sequence</function> ( <parameter>table</parameter> <type>text</type>, <parameter>column</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the name of the sequence associated with a column,
+ or NULL if no sequence is associated with the column.
+ If the column is an identity column, the associated sequence is the
+ sequence internally created for that column.
+ For columns created using one of the serial types
+ (<type>serial</type>, <type>smallserial</type>, <type>bigserial</type>),
+ it is the sequence created for that serial column definition.
+ In the latter case, the association can be modified or removed
+ with <command>ALTER SEQUENCE OWNED BY</command>.
+ (This function probably should have been
+ called <function>pg_get_owned_sequence</function>; its current name
+ reflects the fact that it has historically been used with serial-type
+ columns.) The first parameter is a table name with optional
+ schema, and the second parameter is a column name. Because the first
+ parameter potentially contains both schema and table names, it is
+ parsed per usual SQL rules, meaning it is lower-cased by default.
+ The second parameter, being just a column name, is treated literally
+ and so has its case preserved. The result is suitably formatted
+ for passing to the sequence functions (see
+ <xref linkend="functions-sequence"/>).
+ </para>
+ <para>
+ A typical use is in reading the current value of the sequence for an
+ identity or serial column, for example:
+<programlisting>
+SELECT currval(pg_get_serial_sequence('sometable', 'id'));
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_statisticsobjdef</primary>
+ </indexterm>
+ <function>pg_get_statisticsobjdef</function> ( <parameter>statobj</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the creating command for an extended statistics object.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_triggerdef</primary>
+ </indexterm>
+<function>pg_get_triggerdef</function> ( <parameter>trigger</parameter> <type>oid</type> <optional>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the creating command for a trigger.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_userbyid</primary>
+ </indexterm>
+ <function>pg_get_userbyid</function> ( <parameter>role</parameter> <type>oid</type> )
+ <returnvalue>name</returnvalue>
+ </para>
+ <para>
+ Returns a role's name given its OID.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_viewdef</primary>
+ </indexterm>
+ <function>pg_get_viewdef</function> ( <parameter>view</parameter> <type>oid</type> <optional>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the underlying <command>SELECT</command> command for a
+ view or materialized view. (This is a decompiled reconstruction, not
+ the original text of the command.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_get_viewdef</function> ( <parameter>view</parameter> <type>oid</type>, <parameter>wrap_column</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the underlying <command>SELECT</command> command for a
+ view or materialized view. (This is a decompiled reconstruction, not
+ the original text of the command.) In this form of the function,
+ pretty-printing is always enabled, and long lines are wrapped to try
+ to keep them shorter than the specified number of columns.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_get_viewdef</function> ( <parameter>view</parameter> <type>text</type> <optional>, <parameter>pretty</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reconstructs the underlying <command>SELECT</command> command for a
+ view or materialized view, working from a textual name for the view
+ rather than its OID. (This is deprecated; use the OID variant
+ instead.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_index_column_has_property</primary>
+ </indexterm>
+ <function>pg_index_column_has_property</function> ( <parameter>index</parameter> <type>regclass</type>, <parameter>column</parameter> <type>integer</type>, <parameter>property</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether an index column has the named property.
+ Common index column properties are listed in
+ <xref linkend="functions-info-index-column-props"/>.
+ (Note that extension access methods can define additional property
+ names for their indexes.)
+ <literal>NULL</literal> is returned if the property name is not known
+ or does not apply to the particular object, or if the OID or column
+ number does not identify a valid object.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_index_has_property</primary>
+ </indexterm>
+ <function>pg_index_has_property</function> ( <parameter>index</parameter> <type>regclass</type>, <parameter>property</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether an index has the named property.
+ Common index properties are listed in
+ <xref linkend="functions-info-index-props"/>.
+ (Note that extension access methods can define additional property
+ names for their indexes.)
+ <literal>NULL</literal> is returned if the property name is not known
+ or does not apply to the particular object, or if the OID does not
+ identify a valid object.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_indexam_has_property</primary>
+ </indexterm>
+ <function>pg_indexam_has_property</function> ( <parameter>am</parameter> <type>oid</type>, <parameter>property</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Tests whether an index access method has the named property.
+ Access method properties are listed in
+ <xref linkend="functions-info-indexam-props"/>.
+ <literal>NULL</literal> is returned if the property name is not known
+ or does not apply to the particular object, or if the OID does not
+ identify a valid object.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_options_to_table</primary>
+ </indexterm>
+ <function>pg_options_to_table</function> ( <parameter>options_array</parameter> <type>text[]</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>option_name</parameter> <type>text</type>,
+ <parameter>option_value</parameter> <type>text</type> )
+ </para>
+ <para>
+ Returns the set of storage options represented by a value from
+ <structname>pg_class</structname>.<structfield>reloptions</structfield> or
+ <structname>pg_attribute</structname>.<structfield>attoptions</structfield>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_settings_get_flags</primary>
+ </indexterm>
+ <function>pg_settings_get_flags</function> ( <parameter>guc</parameter> <type>text</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of the flags associated with the given GUC, or
+ <literal>NULL</literal> if it does not exist. The result is
+ an empty array if the GUC exists but there are no flags to show.
+ Only the most useful flags listed in
+ <xref linkend="functions-pg-settings-flags"/> are exposed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_tablespace_databases</primary>
+ </indexterm>
+ <function>pg_tablespace_databases</function> ( <parameter>tablespace</parameter> <type>oid</type> )
+ <returnvalue>setof oid</returnvalue>
+ </para>
+ <para>
+ Returns the set of OIDs of databases that have objects stored in the
+ specified tablespace. If this function returns any rows, the
+ tablespace is not empty and cannot be dropped. To identify the specific
+ objects populating the tablespace, you will need to connect to the
+ database(s) identified by <function>pg_tablespace_databases</function>
+ and query their <structname>pg_class</structname> catalogs.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_tablespace_location</primary>
+ </indexterm>
+ <function>pg_tablespace_location</function> ( <parameter>tablespace</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the file system path that this tablespace is located in.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_typeof</primary>
+ </indexterm>
+ <function>pg_typeof</function> ( <type>"any"</type> )
+ <returnvalue>regtype</returnvalue>
+ </para>
+ <para>
+ Returns the OID of the data type of the value that is passed to it.
+ This can be helpful for troubleshooting or dynamically constructing
+ SQL queries. The function is declared as
+ returning <type>regtype</type>, which is an OID alias type (see
+ <xref linkend="datatype-oid"/>); this means that it is the same as an
+ OID for comparison purposes but displays as a type name.
+ </para>
+ <para>
+ For example:
+<programlisting>
+SELECT pg_typeof(33);
+ pg_typeof
+-----------
+ integer
+
+SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
+ typlen
+--------
+ 4
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>COLLATION FOR</primary>
+ </indexterm>
+ <function>COLLATION FOR</function> ( <type>"any"</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the name of the collation of the value that is passed to it.
+ The value is quoted and schema-qualified if necessary. If no
+ collation was derived for the argument expression,
+ then <literal>NULL</literal> is returned. If the argument is not of a
+ collatable data type, then an error is raised.
+ </para>
+ <para>
+ For example:
+<programlisting>
+SELECT collation for (description) FROM pg_description LIMIT 1;
+ pg_collation_for
+------------------
+ "default"
+
+SELECT collation for ('foo' COLLATE "de_DE");
+ pg_collation_for
+------------------
+ "de_DE"
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regclass</primary>
+ </indexterm>
+ <function>to_regclass</function> ( <type>text</type> )
+ <returnvalue>regclass</returnvalue>
+ </para>
+ <para>
+ Translates a textual relation name to its OID. A similar result is
+ obtained by casting the string to type <type>regclass</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regcollation</primary>
+ </indexterm>
+ <function>to_regcollation</function> ( <type>text</type> )
+ <returnvalue>regcollation</returnvalue>
+ </para>
+ <para>
+ Translates a textual collation name to its OID. A similar result is
+ obtained by casting the string to type <type>regcollation</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regnamespace</primary>
+ </indexterm>
+ <function>to_regnamespace</function> ( <type>text</type> )
+ <returnvalue>regnamespace</returnvalue>
+ </para>
+ <para>
+ Translates a textual schema name to its OID. A similar result is
+ obtained by casting the string to type <type>regnamespace</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regoper</primary>
+ </indexterm>
+ <function>to_regoper</function> ( <type>text</type> )
+ <returnvalue>regoper</returnvalue>
+ </para>
+ <para>
+ Translates a textual operator name to its OID. A similar result is
+ obtained by casting the string to type <type>regoper</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found or is ambiguous. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regoperator</primary>
+ </indexterm>
+ <function>to_regoperator</function> ( <type>text</type> )
+ <returnvalue>regoperator</returnvalue>
+ </para>
+ <para>
+ Translates a textual operator name (with parameter types) to its OID. A similar result is
+ obtained by casting the string to type <type>regoperator</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regproc</primary>
+ </indexterm>
+ <function>to_regproc</function> ( <type>text</type> )
+ <returnvalue>regproc</returnvalue>
+ </para>
+ <para>
+ Translates a textual function or procedure name to its OID. A similar result is
+ obtained by casting the string to type <type>regproc</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found or is ambiguous. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regprocedure</primary>
+ </indexterm>
+ <function>to_regprocedure</function> ( <type>text</type> )
+ <returnvalue>regprocedure</returnvalue>
+ </para>
+ <para>
+ Translates a textual function or procedure name (with argument types) to its OID. A similar result is
+ obtained by casting the string to type <type>regprocedure</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regrole</primary>
+ </indexterm>
+ <function>to_regrole</function> ( <type>text</type> )
+ <returnvalue>regrole</returnvalue>
+ </para>
+ <para>
+ Translates a textual role name to its OID. A similar result is
+ obtained by casting the string to type <type>regrole</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>to_regtype</primary>
+ </indexterm>
+ <function>to_regtype</function> ( <type>text</type> )
+ <returnvalue>regtype</returnvalue>
+ </para>
+ <para>
+ Translates a textual type name to its OID. A similar result is
+ obtained by casting the string to type <type>regtype</type> (see
+ <xref linkend="datatype-oid"/>); however, this function will return
+ <literal>NULL</literal> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Most of the functions that reconstruct (decompile) database objects
+ have an optional <parameter>pretty</parameter> flag, which
+ if <literal>true</literal> causes the result to
+ be <quote>pretty-printed</quote>. Pretty-printing suppresses unnecessary
+ parentheses and adds whitespace for legibility.
+ The pretty-printed format is more readable, but the default format
+ is more likely to be interpreted the same way by future versions of
+ <productname>PostgreSQL</productname>; so avoid using pretty-printed output
+ for dump purposes. Passing <literal>false</literal> for
+ the <parameter>pretty</parameter> parameter yields the same result as
+ omitting the parameter.
+ </para>
+
+ <table id="functions-info-index-column-props">
+ <title>Index Column Properties</title>
+ <tgroup cols="2">
+ <thead>
+ <row><entry>Name</entry><entry>Description</entry></row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>asc</literal></entry>
+ <entry>Does the column sort in ascending order on a forward scan?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>desc</literal></entry>
+ <entry>Does the column sort in descending order on a forward scan?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>nulls_first</literal></entry>
+ <entry>Does the column sort with nulls first on a forward scan?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>nulls_last</literal></entry>
+ <entry>Does the column sort with nulls last on a forward scan?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>orderable</literal></entry>
+ <entry>Does the column possess any defined sort ordering?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>distance_orderable</literal></entry>
+ <entry>Can the column be scanned in order by a <quote>distance</quote>
+ operator, for example <literal>ORDER BY col &lt;-&gt; constant</literal> ?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>returnable</literal></entry>
+ <entry>Can the column value be returned by an index-only scan?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>search_array</literal></entry>
+ <entry>Does the column natively support <literal>col = ANY(array)</literal>
+ searches?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>search_nulls</literal></entry>
+ <entry>Does the column support <literal>IS NULL</literal> and
+ <literal>IS NOT NULL</literal> searches?
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-info-index-props">
+ <title>Index Properties</title>
+ <tgroup cols="2">
+ <thead>
+ <row><entry>Name</entry><entry>Description</entry></row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>clusterable</literal></entry>
+ <entry>Can the index be used in a <literal>CLUSTER</literal> command?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>index_scan</literal></entry>
+ <entry>Does the index support plain (non-bitmap) scans?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>bitmap_scan</literal></entry>
+ <entry>Does the index support bitmap scans?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>backward_scan</literal></entry>
+ <entry>Can the scan direction be changed in mid-scan (to
+ support <literal>FETCH BACKWARD</literal> on a cursor without
+ needing materialization)?
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-info-indexam-props">
+ <title>Index Access Method Properties</title>
+ <tgroup cols="2">
+ <thead>
+ <row><entry>Name</entry><entry>Description</entry></row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>can_order</literal></entry>
+ <entry>Does the access method support <literal>ASC</literal>,
+ <literal>DESC</literal> and related keywords in
+ <literal>CREATE INDEX</literal>?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>can_unique</literal></entry>
+ <entry>Does the access method support unique indexes?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>can_multi_col</literal></entry>
+ <entry>Does the access method support indexes with multiple columns?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>can_exclude</literal></entry>
+ <entry>Does the access method support exclusion constraints?
+ </entry>
+ </row>
+ <row>
+ <entry><literal>can_include</literal></entry>
+ <entry>Does the access method support the <literal>INCLUDE</literal>
+ clause of <literal>CREATE INDEX</literal>?
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-pg-settings-flags">
+ <title>GUC Flags</title>
+ <tgroup cols="2">
+ <thead>
+ <row><entry>Flag</entry><entry>Description</entry></row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>EXPLAIN</literal></entry>
+ <entry>Parameters with this flag are included in
+ <command>EXPLAIN (SETTINGS)</command> commands.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>NO_SHOW_ALL</literal></entry>
+ <entry>Parameters with this flag are excluded from
+ <command>SHOW ALL</command> commands.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>NO_RESET_ALL</literal></entry>
+ <entry>Parameters with this flag are excluded from
+ <command>RESET ALL</command> commands.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>NOT_IN_SAMPLE</literal></entry>
+ <entry>Parameters with this flag are not included in
+ <filename>postgresql.conf</filename> by default.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>RUNTIME_COMPUTED</literal></entry>
+ <entry>Parameters with this flag are runtime-computed ones.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-info-object-table"/> lists functions related to
+ database object identification and addressing.
+ </para>
+
+ <table id="functions-info-object-table">
+ <title>Object Information and Addressing Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_describe_object</primary>
+ </indexterm>
+ <function>pg_describe_object</function> ( <parameter>classid</parameter> <type>oid</type>, <parameter>objid</parameter> <type>oid</type>, <parameter>objsubid</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns a textual description of a database object identified by
+ catalog OID, object OID, and sub-object ID (such as a column number
+ within a table; the sub-object ID is zero when referring to a whole
+ object). This description is intended to be human-readable, and might
+ be translated, depending on server configuration. This is especially
+ useful to determine the identity of an object referenced in the
+ <structname>pg_depend</structname> catalog. This function returns
+ <literal>NULL</literal> values for undefined objects.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_identify_object</primary>
+ </indexterm>
+ <function>pg_identify_object</function> ( <parameter>classid</parameter> <type>oid</type>, <parameter>objid</parameter> <type>oid</type>, <parameter>objsubid</parameter> <type>integer</type> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>type</parameter> <type>text</type>,
+ <parameter>schema</parameter> <type>text</type>,
+ <parameter>name</parameter> <type>text</type>,
+ <parameter>identity</parameter> <type>text</type> )
+ </para>
+ <para>
+ Returns a row containing enough information to uniquely identify the
+ database object specified by catalog OID, object OID and sub-object
+ ID.
+ This information is intended to be machine-readable, and is never
+ translated.
+ <parameter>type</parameter> identifies the type of database object;
+ <parameter>schema</parameter> is the schema name that the object
+ belongs in, or <literal>NULL</literal> for object types that do not
+ belong to schemas;
+ <parameter>name</parameter> is the name of the object, quoted if
+ necessary, if the name (along with schema name, if pertinent) is
+ sufficient to uniquely identify the object,
+ otherwise <literal>NULL</literal>;
+ <parameter>identity</parameter> is the complete object identity, with
+ the precise format depending on object type, and each name within the
+ format being schema-qualified and quoted as necessary. Undefined
+ objects are identified with <literal>NULL</literal> values.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_identify_object_as_address</primary>
+ </indexterm>
+ <function>pg_identify_object_as_address</function> ( <parameter>classid</parameter> <type>oid</type>, <parameter>objid</parameter> <type>oid</type>, <parameter>objsubid</parameter> <type>integer</type> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>type</parameter> <type>text</type>,
+ <parameter>object_names</parameter> <type>text[]</type>,
+ <parameter>object_args</parameter> <type>text[]</type> )
+ </para>
+ <para>
+ Returns a row containing enough information to uniquely identify the
+ database object specified by catalog OID, object OID and sub-object
+ ID.
+ The returned information is independent of the current server, that
+ is, it could be used to identify an identically named object in
+ another server.
+ <parameter>type</parameter> identifies the type of database object;
+ <parameter>object_names</parameter> and
+ <parameter>object_args</parameter>
+ are text arrays that together form a reference to the object.
+ These three values can be passed
+ to <function>pg_get_object_address</function> to obtain the internal
+ address of the object.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_object_address</primary>
+ </indexterm>
+ <function>pg_get_object_address</function> ( <parameter>type</parameter> <type>text</type>, <parameter>object_names</parameter> <type>text[]</type>, <parameter>object_args</parameter> <type>text[]</type> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>classid</parameter> <type>oid</type>,
+ <parameter>objid</parameter> <type>oid</type>,
+ <parameter>objsubid</parameter> <type>integer</type> )
+ </para>
+ <para>
+ Returns a row containing enough information to uniquely identify the
+ database object specified by a type code and object name and argument
+ arrays.
+ The returned values are the ones that would be used in system catalogs
+ such as <structname>pg_depend</structname>; they can be passed to
+ other system functions such as <function>pg_describe_object</function>
+ or <function>pg_identify_object</function>.
+ <parameter>classid</parameter> is the OID of the system catalog
+ containing the object;
+ <parameter>objid</parameter> is the OID of the object itself, and
+ <parameter>objsubid</parameter> is the sub-object ID, or zero if none.
+ This function is the inverse
+ of <function>pg_identify_object_as_address</function>.
+ Undefined objects are identified with <literal>NULL</literal> values.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <indexterm>
+ <primary>comment</primary>
+ <secondary sortas="database objects">about database objects</secondary>
+ </indexterm>
+
+ <para>
+ The functions shown in <xref linkend="functions-info-comment-table"/>
+ extract comments previously stored with the <xref linkend="sql-comment"/>
+ command. A null value is returned if no
+ comment could be found for the specified parameters.
+ </para>
+
+ <table id="functions-info-comment-table">
+ <title>Comment Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>col_description</primary>
+ </indexterm>
+ <function>col_description</function> ( <parameter>table</parameter> <type>oid</type>, <parameter>column</parameter> <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the comment for a table column, which is specified by the OID
+ of its table and its column number.
+ (<function>obj_description</function> cannot be used for table
+ columns, since columns do not have OIDs of their own.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>obj_description</primary>
+ </indexterm>
+ <function>obj_description</function> ( <parameter>object</parameter> <type>oid</type>, <parameter>catalog</parameter> <type>name</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the comment for a database object specified by its OID and the
+ name of the containing system catalog. For
+ example, <literal>obj_description(123456, 'pg_class')</literal> would
+ retrieve the comment for the table with OID 123456.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>obj_description</function> ( <parameter>object</parameter> <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the comment for a database object specified by its OID alone.
+ This is <emphasis>deprecated</emphasis> since there is no guarantee
+ that OIDs are unique across different system catalogs; therefore, the
+ wrong comment might be returned.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>shobj_description</primary>
+ </indexterm>
+ <function>shobj_description</function> ( <parameter>object</parameter> <type>oid</type>, <parameter>catalog</parameter> <type>name</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the comment for a shared database object specified by its OID
+ and the name of the containing system catalog. This is just
+ like <function>obj_description</function> except that it is used for
+ retrieving comments on shared objects (that is, databases, roles, and
+ tablespaces). Some system catalogs are global to all databases within
+ each cluster, and the descriptions for objects in them are stored
+ globally as well.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The functions shown in <xref linkend="functions-pg-snapshot"/>
+ provide server transaction information in an exportable form. The main
+ use of these functions is to determine which transactions were committed
+ between two snapshots.
+ </para>
+
+ <table id="functions-pg-snapshot">
+ <title>Transaction ID and Snapshot Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_xact_id</primary>
+ </indexterm>
+ <function>pg_current_xact_id</function> ()
+ <returnvalue>xid8</returnvalue>
+ </para>
+ <para>
+ Returns the current transaction's ID. It will assign a new one if the
+ current transaction does not have one already (because it has not
+ performed any database updates).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_xact_id_if_assigned</primary>
+ </indexterm>
+ <function>pg_current_xact_id_if_assigned</function> ()
+ <returnvalue>xid8</returnvalue>
+ </para>
+ <para>
+ Returns the current transaction's ID, or <literal>NULL</literal> if no
+ ID is assigned yet. (It's best to use this variant if the transaction
+ might otherwise be read-only, to avoid unnecessary consumption of an
+ XID.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_xact_status</primary>
+ </indexterm>
+ <function>pg_xact_status</function> ( <type>xid8</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Reports the commit status of a recent transaction.
+ The result is one of <literal>in progress</literal>,
+ <literal>committed</literal>, or <literal>aborted</literal>,
+ provided that the transaction is recent enough that the system retains
+ the commit status of that transaction.
+ If it is old enough that no references to the transaction survive in
+ the system and the commit status information has been discarded, the
+ result is <literal>NULL</literal>.
+ Applications might use this function, for example, to determine
+ whether their transaction committed or aborted after the application
+ and database server become disconnected while
+ a <literal>COMMIT</literal> is in progress.
+ Note that prepared transactions are reported as <literal>in
+ progress</literal>; applications must check <link
+ linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>
+ if they need to determine whether a transaction ID belongs to a
+ prepared transaction.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_snapshot</primary>
+ </indexterm>
+ <function>pg_current_snapshot</function> ()
+ <returnvalue>pg_snapshot</returnvalue>
+ </para>
+ <para>
+ Returns a current <firstterm>snapshot</firstterm>, a data structure
+ showing which transaction IDs are now in-progress.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_snapshot_xip</primary>
+ </indexterm>
+ <function>pg_snapshot_xip</function> ( <type>pg_snapshot</type> )
+ <returnvalue>setof xid8</returnvalue>
+ </para>
+ <para>
+ Returns the set of in-progress transaction IDs contained in a snapshot.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_snapshot_xmax</primary>
+ </indexterm>
+ <function>pg_snapshot_xmax</function> ( <type>pg_snapshot</type> )
+ <returnvalue>xid8</returnvalue>
+ </para>
+ <para>
+ Returns the <structfield>xmax</structfield> of a snapshot.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_snapshot_xmin</primary>
+ </indexterm>
+ <function>pg_snapshot_xmin</function> ( <type>pg_snapshot</type> )
+ <returnvalue>xid8</returnvalue>
+ </para>
+ <para>
+ Returns the <structfield>xmin</structfield> of a snapshot.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_visible_in_snapshot</primary>
+ </indexterm>
+ <function>pg_visible_in_snapshot</function> ( <type>xid8</type>, <type>pg_snapshot</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the given transaction ID <firstterm>visible</firstterm> according
+ to this snapshot (that is, was it completed before the snapshot was
+ taken)? Note that this function will not give the correct answer for
+ a subtransaction ID.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The internal transaction ID type <type>xid</type> is 32 bits wide and
+ wraps around every 4 billion transactions. However,
+ the functions shown in <xref linkend="functions-pg-snapshot"/> use a
+ 64-bit type <type>xid8</type> that does not wrap around during the life
+ of an installation, and can be converted to <type>xid</type> by casting if
+ required. The data type <type>pg_snapshot</type> stores information about
+ transaction ID visibility at a particular moment in time. Its components
+ are described in <xref linkend="functions-pg-snapshot-parts"/>.
+ <type>pg_snapshot</type>'s textual representation is
+ <literal><replaceable>xmin</replaceable>:<replaceable>xmax</replaceable>:<replaceable>xip_list</replaceable></literal>.
+ For example <literal>10:20:10,14,15</literal> means
+ <literal>xmin=10, xmax=20, xip_list=10, 14, 15</literal>.
+ </para>
+
+ <table id="functions-pg-snapshot-parts">
+ <title>Snapshot Components</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>xmin</structfield></entry>
+ <entry>
+ Lowest transaction ID that was still active. All transaction IDs
+ less than <structfield>xmin</structfield> are either committed and visible,
+ or rolled back and dead.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>xmax</structfield></entry>
+ <entry>
+ One past the highest completed transaction ID. All transaction IDs
+ greater than or equal to <structfield>xmax</structfield> had not yet
+ completed as of the time of the snapshot, and thus are invisible.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structfield>xip_list</structfield></entry>
+ <entry>
+ Transactions in progress at the time of the snapshot. A transaction
+ ID that is <literal>xmin &lt;= <replaceable>X</replaceable> &lt;
+ xmax</literal> and not in this list was already completed at the time
+ of the snapshot, and thus is either visible or dead according to its
+ commit status. This list does not include the transaction IDs of
+ subtransactions.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In releases of <productname>PostgreSQL</productname> before 13 there was
+ no <type>xid8</type> type, so variants of these functions were provided
+ that used <type>bigint</type> to represent a 64-bit XID, with a
+ correspondingly distinct snapshot data type <type>txid_snapshot</type>.
+ These older functions have <literal>txid</literal> in their names. They
+ are still supported for backward compatibility, but may be removed from a
+ future release. See <xref linkend="functions-txid-snapshot"/>.
+ </para>
+
+ <table id="functions-txid-snapshot">
+ <title>Deprecated Transaction ID and Snapshot Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_current</primary>
+ </indexterm>
+ <function>txid_current</function> ()
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ See <function>pg_current_xact_id()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_current_if_assigned</primary>
+ </indexterm>
+ <function>txid_current_if_assigned</function> ()
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ See <function>pg_current_xact_id_if_assigned()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_current_snapshot</primary>
+ </indexterm>
+ <function>txid_current_snapshot</function> ()
+ <returnvalue>txid_snapshot</returnvalue>
+ </para>
+ <para>
+ See <function>pg_current_snapshot()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_snapshot_xip</primary>
+ </indexterm>
+ <function>txid_snapshot_xip</function> ( <type>txid_snapshot</type> )
+ <returnvalue>setof bigint</returnvalue>
+ </para>
+ <para>
+ See <function>pg_snapshot_xip()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_snapshot_xmax</primary>
+ </indexterm>
+ <function>txid_snapshot_xmax</function> ( <type>txid_snapshot</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ See <function>pg_snapshot_xmax()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_snapshot_xmin</primary>
+ </indexterm>
+ <function>txid_snapshot_xmin</function> ( <type>txid_snapshot</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ See <function>pg_snapshot_xmin()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_visible_in_snapshot</primary>
+ </indexterm>
+ <function>txid_visible_in_snapshot</function> ( <type>bigint</type>, <type>txid_snapshot</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ See <function>pg_visible_in_snapshot()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>txid_status</primary>
+ </indexterm>
+ <function>txid_status</function> ( <type>bigint</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ See <function>pg_xact_status()</function>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The functions shown in <xref linkend="functions-commit-timestamp"/>
+ provide information about when past transactions were committed.
+ They only provide useful data when the
+ <xref linkend="guc-track-commit-timestamp"/> configuration option is
+ enabled, and only for transactions that were committed after it was
+ enabled.
+ </para>
+
+ <table id="functions-commit-timestamp">
+ <title>Committed Transaction Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_xact_commit_timestamp</primary>
+ </indexterm>
+ <function>pg_xact_commit_timestamp</function> ( <type>xid</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the commit timestamp of a transaction.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_xact_commit_timestamp_origin</primary>
+ </indexterm>
+ <function>pg_xact_commit_timestamp_origin</function> ( <type>xid</type> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>timestamp</parameter> <type>timestamp with time zone</type>,
+ <parameter>roident</parameter> <type>oid</type>)
+ </para>
+ <para>
+ Returns the commit timestamp and replication origin of a transaction.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_last_committed_xact</primary>
+ </indexterm>
+ <function>pg_last_committed_xact</function> ()
+ <returnvalue>record</returnvalue>
+ ( <parameter>xid</parameter> <type>xid</type>,
+ <parameter>timestamp</parameter> <type>timestamp with time zone</type>,
+ <parameter>roident</parameter> <type>oid</type> )
+ </para>
+ <para>
+ Returns the transaction ID, commit timestamp and replication origin
+ of the latest committed transaction.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The functions shown in <xref linkend="functions-controldata"/>
+ print information initialized during <command>initdb</command>, such
+ as the catalog version. They also show information about write-ahead
+ logging and checkpoint processing. This information is cluster-wide,
+ not specific to any one database. These functions provide most of the same
+ information, from the same source, as the
+ <xref linkend="app-pgcontroldata"/> application.
+ </para>
+
+ <table id="functions-controldata">
+ <title>Control Data Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_control_checkpoint</primary>
+ </indexterm>
+ <function>pg_control_checkpoint</function> ()
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns information about current checkpoint state, as shown in
+ <xref linkend="functions-pg-control-checkpoint"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_control_system</primary>
+ </indexterm>
+ <function>pg_control_system</function> ()
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns information about current control file state, as shown in
+ <xref linkend="functions-pg-control-system"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_control_init</primary>
+ </indexterm>
+ <function>pg_control_init</function> ()
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns information about cluster initialization state, as shown in
+ <xref linkend="functions-pg-control-init"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_control_recovery</primary>
+ </indexterm>
+ <function>pg_control_recovery</function> ()
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns information about recovery state, as shown in
+ <xref linkend="functions-pg-control-recovery"/>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-pg-control-checkpoint">
+ <title><function>pg_control_checkpoint</function> Output Columns</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Column Name</entry>
+ <entry>Data Type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><structfield>checkpoint_lsn</structfield></entry>
+ <entry><type>pg_lsn</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>redo_lsn</structfield></entry>
+ <entry><type>pg_lsn</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>redo_wal_file</structfield></entry>
+ <entry><type>text</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>timeline_id</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>prev_timeline_id</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>full_page_writes</structfield></entry>
+ <entry><type>boolean</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>next_xid</structfield></entry>
+ <entry><type>text</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>next_oid</structfield></entry>
+ <entry><type>oid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>next_multixact_id</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>next_multi_offset</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>oldest_xid</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>oldest_xid_dbid</structfield></entry>
+ <entry><type>oid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>oldest_active_xid</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>oldest_multi_xid</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>oldest_multi_dbid</structfield></entry>
+ <entry><type>oid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>oldest_commit_ts_xid</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>newest_commit_ts_xid</structfield></entry>
+ <entry><type>xid</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>checkpoint_time</structfield></entry>
+ <entry><type>timestamp with time zone</type></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-pg-control-system">
+ <title><function>pg_control_system</function> Output Columns</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Column Name</entry>
+ <entry>Data Type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><structfield>pg_control_version</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>catalog_version_no</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>system_identifier</structfield></entry>
+ <entry><type>bigint</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>pg_control_last_modified</structfield></entry>
+ <entry><type>timestamp with time zone</type></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-pg-control-init">
+ <title><function>pg_control_init</function> Output Columns</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Column Name</entry>
+ <entry>Data Type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><structfield>max_data_alignment</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>database_block_size</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>blocks_per_segment</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>wal_block_size</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>bytes_per_wal_segment</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>max_identifier_length</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>max_index_columns</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>max_toast_chunk_size</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>large_object_chunk_size</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>float8_pass_by_value</structfield></entry>
+ <entry><type>boolean</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>data_page_checksum_version</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="functions-pg-control-recovery">
+ <title><function>pg_control_recovery</function> Output Columns</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Column Name</entry>
+ <entry>Data Type</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><structfield>min_recovery_end_lsn</structfield></entry>
+ <entry><type>pg_lsn</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>min_recovery_end_timeline</structfield></entry>
+ <entry><type>integer</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>backup_start_lsn</structfield></entry>
+ <entry><type>pg_lsn</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>backup_end_lsn</structfield></entry>
+ <entry><type>pg_lsn</type></entry>
+ </row>
+
+ <row>
+ <entry><structfield>end_of_backup_record_required</structfield></entry>
+ <entry><type>boolean</type></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="functions-admin">
+ <title>System Administration Functions</title>
+
+ <para>
+ The functions described in this section are used to control and
+ monitor a <productname>PostgreSQL</productname> installation.
+ </para>
+
+ <sect2 id="functions-admin-set">
+ <title>Configuration Settings Functions</title>
+
+ <indexterm>
+ <primary>SET</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>SHOW</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>configuration</primary>
+ <secondary sortas="server">of the server</secondary>
+ <tertiary>functions</tertiary>
+ </indexterm>
+
+ <para>
+ <xref linkend="functions-admin-set-table"/> shows the functions
+ available to query and alter run-time configuration parameters.
+ </para>
+
+ <table id="functions-admin-set-table">
+ <title>Configuration Settings Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>current_setting</primary>
+ </indexterm>
+ <function>current_setting</function> ( <parameter>setting_name</parameter> <type>text</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the current value of the
+ setting <parameter>setting_name</parameter>. If there is no such
+ setting, <function>current_setting</function> throws an error
+ unless <parameter>missing_ok</parameter> is supplied and
+ is <literal>true</literal> (in which case NULL is returned).
+ This function corresponds to
+ the <acronym>SQL</acronym> command <xref linkend="sql-show"/>.
+ </para>
+ <para>
+ <literal>current_setting('datestyle')</literal>
+ <returnvalue>ISO, MDY</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>set_config</primary>
+ </indexterm>
+ <function>set_config</function> (
+ <parameter>setting_name</parameter> <type>text</type>,
+ <parameter>new_value</parameter> <type>text</type>,
+ <parameter>is_local</parameter> <type>boolean</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Sets the parameter <parameter>setting_name</parameter>
+ to <parameter>new_value</parameter>, and returns that value.
+ If <parameter>is_local</parameter> is <literal>true</literal>, the new
+ value will only apply during the current transaction. If you want the
+ new value to apply for the rest of the current session,
+ use <literal>false</literal> instead. This function corresponds to
+ the SQL command <xref linkend="sql-set"/>.
+ </para>
+ <para>
+ <literal>set_config('log_statement_stats', 'off', false)</literal>
+ <returnvalue>off</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="functions-admin-signal">
+ <title>Server Signaling Functions</title>
+
+ <indexterm>
+ <primary>signal</primary>
+ <secondary sortas="backend">backend processes</secondary>
+ </indexterm>
+
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-signal-table"/> send control signals to
+ other server processes. Use of these functions is restricted to
+ superusers by default but access may be granted to others using
+ <command>GRANT</command>, with noted exceptions.
+ </para>
+
+ <para>
+ Each of these functions returns <literal>true</literal> if
+ the signal was successfully sent and <literal>false</literal>
+ if sending the signal failed.
+ </para>
+
+ <table id="functions-admin-signal-table">
+ <title>Server Signaling Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_cancel_backend</primary>
+ </indexterm>
+ <function>pg_cancel_backend</function> ( <parameter>pid</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Cancels the current query of the session whose backend process has the
+ specified process ID. This is also allowed if the
+ calling role is a member of the role whose backend is being canceled or
+ the calling role has privileges of <literal>pg_signal_backend</literal>,
+ however only superusers can cancel superuser backends.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_log_backend_memory_contexts</primary>
+ </indexterm>
+ <function>pg_log_backend_memory_contexts</function> ( <parameter>pid</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Requests to log the memory contexts of the backend with the
+ specified process ID. This function can send the request to
+ backends and auxiliary processes except logger. These memory contexts
+ will be logged at
+ <literal>LOG</literal> message level. They will appear in
+ the server log based on the log configuration set
+ (see <xref linkend="runtime-config-logging"/> for more information),
+ but will not be sent to the client regardless of
+ <xref linkend="guc-client-min-messages"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_reload_conf</primary>
+ </indexterm>
+ <function>pg_reload_conf</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Causes all processes of the <productname>PostgreSQL</productname>
+ server to reload their configuration files. (This is initiated by
+ sending a <systemitem>SIGHUP</systemitem> signal to the postmaster
+ process, which in turn sends <systemitem>SIGHUP</systemitem> to each
+ of its children.) You can use the
+ <link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link>,
+ <link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link> and
+ <link linkend="view-pg-hba-file-rules"><structname>pg_ident_file_mappings</structname></link> views
+ to check the configuration files for possible errors, before reloading.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_rotate_logfile</primary>
+ </indexterm>
+ <function>pg_rotate_logfile</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Signals the log-file manager to switch to a new output file
+ immediately. This works only when the built-in log collector is
+ running, since otherwise there is no log-file manager subprocess.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_terminate_backend</primary>
+ </indexterm>
+ <function>pg_terminate_backend</function> ( <parameter>pid</parameter> <type>integer</type>, <parameter>timeout</parameter> <type>bigint</type> <literal>DEFAULT</literal> <literal>0</literal> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Terminates the session whose backend process has the
+ specified process ID. This is also allowed if the calling role
+ is a member of the role whose backend is being terminated or the
+ calling role has privileges of <literal>pg_signal_backend</literal>,
+ however only superusers can terminate superuser backends.
+ </para>
+ <para>
+ If <parameter>timeout</parameter> is not specified or zero, this
+ function returns <literal>true</literal> whether the process actually
+ terminates or not, indicating only that the sending of the signal was
+ successful. If the <parameter>timeout</parameter> is specified (in
+ milliseconds) and greater than zero, the function waits until the
+ process is actually terminated or until the given time has passed. If
+ the process is terminated, the function
+ returns <literal>true</literal>. On timeout, a warning is emitted and
+ <literal>false</literal> is returned.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <function>pg_cancel_backend</function> and <function>pg_terminate_backend</function>
+ send signals (<systemitem>SIGINT</systemitem> or <systemitem>SIGTERM</systemitem>
+ respectively) to backend processes identified by process ID.
+ The process ID of an active backend can be found from
+ the <structfield>pid</structfield> column of the
+ <structname>pg_stat_activity</structname> view, or by listing the
+ <command>postgres</command> processes on the server (using
+ <application>ps</application> on Unix or the <application>Task
+ Manager</application> on <productname>Windows</productname>).
+ The role of an active backend can be found from the
+ <structfield>usename</structfield> column of the
+ <structname>pg_stat_activity</structname> view.
+ </para>
+
+ <para>
+ <function>pg_log_backend_memory_contexts</function> can be used
+ to log the memory contexts of a backend process. For example:
+<programlisting>
+postgres=# SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+ pg_log_backend_memory_contexts
+--------------------------------
+ t
+(1 row)
+</programlisting>
+One message for each memory context will be logged. For example:
+<screen>
+LOG: logging memory contexts of PID 10377
+STATEMENT: SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+LOG: level: 0; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used
+LOG: level: 1; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used
+LOG: level: 1; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used
+LOG: level: 1; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used
+LOG: level: 1; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used
+LOG: level: 1; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used
+LOG: level: 1; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used
+LOG: level: 1; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used
+...
+LOG: level: 1; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used
+LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 used
+</screen>
+ If there are more than 100 child contexts under the same parent, the first
+ 100 child contexts are logged, along with a summary of the remaining contexts.
+ Note that frequent calls to this function could incur significant overhead,
+ because it may generate a large number of log messages.
+ </para>
+
+ </sect2>
+
+ <sect2 id="functions-admin-backup">
+ <title>Backup Control Functions</title>
+
+ <indexterm>
+ <primary>backup</primary>
+ </indexterm>
+
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-backup-table"/> assist in making on-line backups.
+ These functions cannot be executed during recovery (except
+ <function>pg_backup_start</function>,
+ <function>pg_backup_stop</function>,
+ and <function>pg_wal_lsn_diff</function>).
+ </para>
+
+ <para>
+ For details about proper usage of these functions, see
+ <xref linkend="continuous-archiving"/>.
+ </para>
+
+ <table id="functions-admin-backup-table">
+ <title>Backup Control Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_create_restore_point</primary>
+ </indexterm>
+ <function>pg_create_restore_point</function> ( <parameter>name</parameter> <type>text</type> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Creates a named marker record in the write-ahead log that can later be
+ used as a recovery target, and returns the corresponding write-ahead
+ log location. The given name can then be used with
+ <xref linkend="guc-recovery-target-name"/> to specify the point up to
+ which recovery will proceed. Avoid creating multiple restore points
+ with the same name, since recovery will stop at the first one whose
+ name matches the recovery target.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_wal_flush_lsn</primary>
+ </indexterm>
+ <function>pg_current_wal_flush_lsn</function> ()
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the current write-ahead log flush location (see notes below).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_wal_insert_lsn</primary>
+ </indexterm>
+ <function>pg_current_wal_insert_lsn</function> ()
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the current write-ahead log insert location (see notes below).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_current_wal_lsn</primary>
+ </indexterm>
+ <function>pg_current_wal_lsn</function> ()
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the current write-ahead log write location (see notes below).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_backup_start</primary>
+ </indexterm>
+ <function>pg_backup_start</function> (
+ <parameter>label</parameter> <type>text</type>
+ <optional>, <parameter>fast</parameter> <type>boolean</type>
+ </optional> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Prepares the server to begin an on-line backup. The only required
+ parameter is an arbitrary user-defined label for the backup.
+ (Typically this would be the name under which the backup dump file
+ will be stored.)
+ If the optional second parameter is given as <literal>true</literal>,
+ it specifies executing <function>pg_backup_start</function> as quickly
+ as possible. This forces an immediate checkpoint which will cause a
+ spike in I/O operations, slowing any concurrently executing queries.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_backup_stop</primary>
+ </indexterm>
+ <function>pg_backup_stop</function> (
+ <optional><parameter>wait_for_archive</parameter> <type>boolean</type>
+ </optional> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>lsn</parameter> <type>pg_lsn</type>,
+ <parameter>labelfile</parameter> <type>text</type>,
+ <parameter>spcmapfile</parameter> <type>text</type> )
+ </para>
+ <para>
+ Finishes performing an on-line backup. The desired contents of the
+ backup label file and the tablespace map file are returned as part of
+ the result of the function and must be written to files in the
+ backup area. These files must not be written to the live data directory
+ (doing so will cause PostgreSQL to fail to restart in the event of a
+ crash).
+ </para>
+ <para>
+ There is an optional parameter of type <type>boolean</type>.
+ If false, the function will return immediately after the backup is
+ completed, without waiting for WAL to be archived. This behavior is
+ only useful with backup software that independently monitors WAL
+ archiving. Otherwise, WAL required to make the backup consistent might
+ be missing and make the backup useless. By default or when this
+ parameter is true, <function>pg_backup_stop</function> will wait for
+ WAL to be archived when archiving is enabled. (On a standby, this
+ means that it will wait only when <varname>archive_mode</varname> =
+ <literal>always</literal>. If write activity on the primary is low,
+ it may be useful to run <function>pg_switch_wal</function> on the
+ primary in order to trigger an immediate segment switch.)
+ </para>
+ <para>
+ When executed on a primary, this function also creates a backup
+ history file in the write-ahead log archive area. The history file
+ includes the label given to <function>pg_backup_start</function>, the
+ starting and ending write-ahead log locations for the backup, and the
+ starting and ending times of the backup. After recording the ending
+ location, the current write-ahead log insertion point is automatically
+ advanced to the next write-ahead log file, so that the ending
+ write-ahead log file can be archived immediately to complete the
+ backup.
+ </para>
+ <para>
+ The result of the function is a single record.
+ The <parameter>lsn</parameter> column holds the backup's ending
+ write-ahead log location (which again can be ignored). The second
+ column returns the contents of the backup label file, and the third
+ column returns the contents of the tablespace map file. These must be
+ stored as part of the backup and are required as part of the restore
+ process.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_switch_wal</primary>
+ </indexterm>
+ <function>pg_switch_wal</function> ()
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Forces the server to switch to a new write-ahead log file, which
+ allows the current file to be archived (assuming you are using
+ continuous archiving). The result is the ending write-ahead log
+ location plus 1 within the just-completed write-ahead log file. If
+ there has been no write-ahead log activity since the last write-ahead
+ log switch, <function>pg_switch_wal</function> does nothing and
+ returns the start location of the write-ahead log file currently in
+ use.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_walfile_name</primary>
+ </indexterm>
+ <function>pg_walfile_name</function> ( <parameter>lsn</parameter> <type>pg_lsn</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts a write-ahead log location to the name of the WAL file
+ holding that location.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_walfile_name_offset</primary>
+ </indexterm>
+ <function>pg_walfile_name_offset</function> ( <parameter>lsn</parameter> <type>pg_lsn</type> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>file_name</parameter> <type>text</type>,
+ <parameter>file_offset</parameter> <type>integer</type> )
+ </para>
+ <para>
+ Converts a write-ahead log location to a WAL file name and byte offset
+ within that file.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_wal_lsn_diff</primary>
+ </indexterm>
+ <function>pg_wal_lsn_diff</function> ( <parameter>lsn1</parameter> <type>pg_lsn</type>, <parameter>lsn2</parameter> <type>pg_lsn</type> )
+ <returnvalue>numeric</returnvalue>
+ </para>
+ <para>
+ Calculates the difference in bytes (<parameter>lsn1</parameter> - <parameter>lsn2</parameter>) between two write-ahead log
+ locations. This can be used
+ with <structname>pg_stat_replication</structname> or some of the
+ functions shown in <xref linkend="functions-admin-backup-table"/> to
+ get the replication lag.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <function>pg_current_wal_lsn</function> displays the current write-ahead
+ log write location in the same format used by the above functions.
+ Similarly, <function>pg_current_wal_insert_lsn</function> displays the
+ current write-ahead log insertion location
+ and <function>pg_current_wal_flush_lsn</function> displays the current
+ write-ahead log flush location. The insertion location is
+ the <quote>logical</quote> end of the write-ahead log at any instant,
+ while the write location is the end of what has actually been written out
+ from the server's internal buffers, and the flush location is the last
+ location known to be written to durable storage. The write location is the
+ end of what can be examined from outside the server, and is usually what
+ you want if you are interested in archiving partially-complete write-ahead
+ log files. The insertion and flush locations are made available primarily
+ for server debugging purposes. These are all read-only operations and do
+ not require superuser permissions.
+ </para>
+
+ <para>
+ You can use <function>pg_walfile_name_offset</function> to extract the
+ corresponding write-ahead log file name and byte offset from
+ a <type>pg_lsn</type> value. For example:
+<programlisting>
+postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
+ file_name | file_offset
+--------------------------+-------------
+ 00000001000000000000000D | 4039624
+(1 row)
+</programlisting>
+ Similarly, <function>pg_walfile_name</function> extracts just the write-ahead log file name.
+ When the given write-ahead log location is exactly at a write-ahead log file boundary, both
+ these functions return the name of the preceding write-ahead log file.
+ This is usually the desired behavior for managing write-ahead log archiving
+ behavior, since the preceding file is the last one that currently
+ needs to be archived.
+ </para>
+
+ </sect2>
+
+ <sect2 id="functions-recovery-control">
+ <title>Recovery Control Functions</title>
+
+ <para>
+ The functions shown in <xref
+ linkend="functions-recovery-info-table"/> provide information
+ about the current status of a standby server.
+ These functions may be executed both during recovery and in normal running.
+ </para>
+
+ <table id="functions-recovery-info-table">
+ <title>Recovery Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_is_in_recovery</primary>
+ </indexterm>
+ <function>pg_is_in_recovery</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if recovery is still in progress.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_last_wal_receive_lsn</primary>
+ </indexterm>
+ <function>pg_last_wal_receive_lsn</function> ()
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the last write-ahead log location that has been received and
+ synced to disk by streaming replication. While streaming replication
+ is in progress this will increase monotonically. If recovery has
+ completed then this will remain static at the location of the last WAL
+ record received and synced to disk during recovery. If streaming
+ replication is disabled, or if it has not yet started, the function
+ returns <literal>NULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_last_wal_replay_lsn</primary>
+ </indexterm>
+ <function>pg_last_wal_replay_lsn</function> ()
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the last write-ahead log location that has been replayed
+ during recovery. If recovery is still in progress this will increase
+ monotonically. If recovery has completed then this will remain
+ static at the location of the last WAL record applied during recovery.
+ When the server has been started normally without recovery, the
+ function returns <literal>NULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_last_xact_replay_timestamp</primary>
+ </indexterm>
+ <function>pg_last_xact_replay_timestamp</function> ()
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the time stamp of the last transaction replayed during
+ recovery. This is the time at which the commit or abort WAL record
+ for that transaction was generated on the primary. If no transactions
+ have been replayed during recovery, the function
+ returns <literal>NULL</literal>. Otherwise, if recovery is still in
+ progress this will increase monotonically. If recovery has completed
+ then this will remain static at the time of the last transaction
+ applied during recovery. When the server has been started normally
+ without recovery, the function returns <literal>NULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_wal_resource_managers</primary>
+ </indexterm>
+ <function>pg_get_wal_resource_managers</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>rm_id</parameter> <type>integer</type>,
+ <parameter>rm_name</parameter> <type>text</type>,
+ <parameter>rm_builtin</parameter> <type>boolean</type> )
+ </para>
+ <para>
+ Returns the currently-loaded WAL resource managers in the system. The
+ column <parameter>rm_builtin</parameter> indicates whether it's a
+ built-in resource manager, or a custom resource manager loaded by an
+ extension.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The functions shown in <xref
+ linkend="functions-recovery-control-table"/> control the progress of recovery.
+ These functions may be executed only during recovery.
+ </para>
+
+ <table id="functions-recovery-control-table">
+ <title>Recovery Control Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_is_wal_replay_paused</primary>
+ </indexterm>
+ <function>pg_is_wal_replay_paused</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if recovery pause is requested.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_get_wal_replay_pause_state</primary>
+ </indexterm>
+ <function>pg_get_wal_replay_pause_state</function> ()
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns recovery pause state. The return values are <literal>
+ not paused</literal> if pause is not requested, <literal>
+ pause requested</literal> if pause is requested but recovery is
+ not yet paused, and <literal>paused</literal> if the recovery is
+ actually paused.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_promote</primary>
+ </indexterm>
+ <function>pg_promote</function> ( <parameter>wait</parameter> <type>boolean</type> <literal>DEFAULT</literal> <literal>true</literal>, <parameter>wait_seconds</parameter> <type>integer</type> <literal>DEFAULT</literal> <literal>60</literal> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Promotes a standby server to primary status.
+ With <parameter>wait</parameter> set to <literal>true</literal> (the
+ default), the function waits until promotion is completed
+ or <parameter>wait_seconds</parameter> seconds have passed, and
+ returns <literal>true</literal> if promotion is successful
+ and <literal>false</literal> otherwise.
+ If <parameter>wait</parameter> is set to <literal>false</literal>, the
+ function returns <literal>true</literal> immediately after sending a
+ <literal>SIGUSR1</literal> signal to the postmaster to trigger
+ promotion.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_wal_replay_pause</primary>
+ </indexterm>
+ <function>pg_wal_replay_pause</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Request to pause recovery. A request doesn't mean that recovery stops
+ right away. If you want a guarantee that recovery is actually paused,
+ you need to check for the recovery pause state returned by
+ <function>pg_get_wal_replay_pause_state()</function>. Note that
+ <function>pg_is_wal_replay_paused()</function> returns whether a request
+ is made. While recovery is paused, no further database changes are applied.
+ If hot standby is active, all new queries will see the same consistent
+ snapshot of the database, and no further query conflicts will be generated
+ until recovery is resumed.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_wal_replay_resume</primary>
+ </indexterm>
+ <function>pg_wal_replay_resume</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Restarts recovery if it was paused.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <function>pg_wal_replay_pause</function> and
+ <function>pg_wal_replay_resume</function> cannot be executed while
+ a promotion is ongoing. If a promotion is triggered while recovery
+ is paused, the paused state ends and promotion continues.
+ </para>
+
+ <para>
+ If streaming replication is disabled, the paused state may continue
+ indefinitely without a problem. If streaming replication is in
+ progress then WAL records will continue to be received, which will
+ eventually fill available disk space, depending upon the duration of
+ the pause, the rate of WAL generation and available disk space.
+ </para>
+
+ </sect2>
+
+ <sect2 id="functions-snapshot-synchronization">
+ <title>Snapshot Synchronization Functions</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows database sessions to synchronize their
+ snapshots. A <firstterm>snapshot</firstterm> determines which data is visible to the
+ transaction that is using the snapshot. Synchronized snapshots are
+ necessary when two or more sessions need to see identical content in the
+ database. If two sessions just start their transactions independently,
+ there is always a possibility that some third transaction commits
+ between the executions of the two <command>START TRANSACTION</command> commands,
+ so that one session sees the effects of that transaction and the other
+ does not.
+ </para>
+
+ <para>
+ To solve this problem, <productname>PostgreSQL</productname> allows a transaction to
+ <firstterm>export</firstterm> the snapshot it is using. As long as the exporting
+ transaction remains open, other transactions can <firstterm>import</firstterm> its
+ snapshot, and thereby be guaranteed that they see exactly the same view
+ of the database that the first transaction sees. But note that any
+ database changes made by any one of these transactions remain invisible
+ to the other transactions, as is usual for changes made by uncommitted
+ transactions. So the transactions are synchronized with respect to
+ pre-existing data, but act normally for changes they make themselves.
+ </para>
+
+ <para>
+ Snapshots are exported with the <function>pg_export_snapshot</function> function,
+ shown in <xref linkend="functions-snapshot-synchronization-table"/>, and
+ imported with the <xref linkend="sql-set-transaction"/> command.
+ </para>
+
+ <table id="functions-snapshot-synchronization-table">
+ <title>Snapshot Synchronization Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_export_snapshot</primary>
+ </indexterm>
+ <function>pg_export_snapshot</function> ()
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Saves the transaction's current snapshot and returns
+ a <type>text</type> string identifying the snapshot. This string must
+ be passed (outside the database) to clients that want to import the
+ snapshot. The snapshot is available for import only until the end of
+ the transaction that exported it.
+ </para>
+ <para>
+ A transaction can export more than one snapshot, if needed. Note that
+ doing so is only useful in <literal>READ COMMITTED</literal>
+ transactions, since in <literal>REPEATABLE READ</literal> and higher
+ isolation levels, transactions use the same snapshot throughout their
+ lifetime. Once a transaction has exported any snapshots, it cannot be
+ prepared with <xref linkend="sql-prepare-transaction"/>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="functions-replication">
+ <title>Replication Management Functions</title>
+
+ <para>
+ The functions shown
+ in <xref linkend="functions-replication-table"/> are for
+ controlling and interacting with replication features.
+ See <xref linkend="streaming-replication"/>,
+ <xref linkend="streaming-replication-slots"/>, and
+ <xref linkend="replication-origins"/>
+ for information about the underlying features.
+ Use of functions for replication origin is only allowed to the
+ superuser by default, but may be allowed to other users by using the
+ <literal>GRANT</literal> command.
+ Use of functions for replication slots is restricted to superusers
+ and users having <literal>REPLICATION</literal> privilege.
+ </para>
+
+ <para>
+ Many of these functions have equivalent commands in the replication
+ protocol; see <xref linkend="protocol-replication"/>.
+ </para>
+
+ <para>
+ The functions described in
+ <xref linkend="functions-admin-backup"/>,
+ <xref linkend="functions-recovery-control"/>, and
+ <xref linkend="functions-snapshot-synchronization"/>
+ are also relevant for replication.
+ </para>
+
+ <table id="functions-replication-table">
+ <title>Replication Management Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_create_physical_replication_slot</primary>
+ </indexterm>
+ <function>pg_create_physical_replication_slot</function> ( <parameter>slot_name</parameter> <type>name</type> <optional>, <parameter>immediately_reserve</parameter> <type>boolean</type>, <parameter>temporary</parameter> <type>boolean</type> </optional> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>slot_name</parameter> <type>name</type>,
+ <parameter>lsn</parameter> <type>pg_lsn</type> )
+ </para>
+ <para>
+ Creates a new physical replication slot named
+ <parameter>slot_name</parameter>. The optional second parameter,
+ when <literal>true</literal>, specifies that the <acronym>LSN</acronym> for this
+ replication slot be reserved immediately; otherwise
+ the <acronym>LSN</acronym> is reserved on first connection from a streaming
+ replication client. Streaming changes from a physical slot is only
+ possible with the streaming-replication protocol &mdash;
+ see <xref linkend="protocol-replication"/>. The optional third
+ parameter, <parameter>temporary</parameter>, when set to true, specifies that
+ the slot should not be permanently stored to disk and is only meant
+ for use by the current session. Temporary slots are also
+ released upon any error. This function corresponds
+ to the replication protocol command <literal>CREATE_REPLICATION_SLOT
+ ... PHYSICAL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_drop_replication_slot</primary>
+ </indexterm>
+ <function>pg_drop_replication_slot</function> ( <parameter>slot_name</parameter> <type>name</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Drops the physical or logical replication slot
+ named <parameter>slot_name</parameter>. Same as replication protocol
+ command <literal>DROP_REPLICATION_SLOT</literal>. For logical slots, this must
+ be called while connected to the same database the slot was created on.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_create_logical_replication_slot</primary>
+ </indexterm>
+ <function>pg_create_logical_replication_slot</function> ( <parameter>slot_name</parameter> <type>name</type>, <parameter>plugin</parameter> <type>name</type> <optional>, <parameter>temporary</parameter> <type>boolean</type>, <parameter>twophase</parameter> <type>boolean</type> </optional> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>slot_name</parameter> <type>name</type>,
+ <parameter>lsn</parameter> <type>pg_lsn</type> )
+ </para>
+ <para>
+ Creates a new logical (decoding) replication slot named
+ <parameter>slot_name</parameter> using the output plugin
+ <parameter>plugin</parameter>. The optional third
+ parameter, <parameter>temporary</parameter>, when set to true, specifies that
+ the slot should not be permanently stored to disk and is only meant
+ for use by the current session. Temporary slots are also
+ released upon any error. The optional fourth parameter,
+ <parameter>twophase</parameter>, when set to true, specifies
+ that the decoding of prepared transactions is enabled for this
+ slot. A call to this function has the same effect as the replication
+ protocol command <literal>CREATE_REPLICATION_SLOT ... LOGICAL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_copy_physical_replication_slot</primary>
+ </indexterm>
+ <function>pg_copy_physical_replication_slot</function> ( <parameter>src_slot_name</parameter> <type>name</type>, <parameter>dst_slot_name</parameter> <type>name</type> <optional>, <parameter>temporary</parameter> <type>boolean</type> </optional> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>slot_name</parameter> <type>name</type>,
+ <parameter>lsn</parameter> <type>pg_lsn</type> )
+ </para>
+ <para>
+ Copies an existing physical replication slot named <parameter>src_slot_name</parameter>
+ to a physical replication slot named <parameter>dst_slot_name</parameter>.
+ The copied physical slot starts to reserve WAL from the same <acronym>LSN</acronym> as the
+ source slot.
+ <parameter>temporary</parameter> is optional. If <parameter>temporary</parameter>
+ is omitted, the same value as the source slot is used.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_copy_logical_replication_slot</primary>
+ </indexterm>
+ <function>pg_copy_logical_replication_slot</function> ( <parameter>src_slot_name</parameter> <type>name</type>, <parameter>dst_slot_name</parameter> <type>name</type> <optional>, <parameter>temporary</parameter> <type>boolean</type> <optional>, <parameter>plugin</parameter> <type>name</type> </optional></optional> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>slot_name</parameter> <type>name</type>,
+ <parameter>lsn</parameter> <type>pg_lsn</type> )
+ </para>
+ <para>
+ Copies an existing logical replication slot
+ named <parameter>src_slot_name</parameter> to a logical replication
+ slot named <parameter>dst_slot_name</parameter>, optionally changing
+ the output plugin and persistence. The copied logical slot starts
+ from the same <acronym>LSN</acronym> as the source logical slot. Both
+ <parameter>temporary</parameter> and <parameter>plugin</parameter> are
+ optional; if they are omitted, the values of the source slot are used.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_logical_slot_get_changes</primary>
+ </indexterm>
+ <function>pg_logical_slot_get_changes</function> ( <parameter>slot_name</parameter> <type>name</type>, <parameter>upto_lsn</parameter> <type>pg_lsn</type>, <parameter>upto_nchanges</parameter> <type>integer</type>, <literal>VARIADIC</literal> <parameter>options</parameter> <type>text[]</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>lsn</parameter> <type>pg_lsn</type>,
+ <parameter>xid</parameter> <type>xid</type>,
+ <parameter>data</parameter> <type>text</type> )
+ </para>
+ <para>
+ Returns changes in the slot <parameter>slot_name</parameter>, starting
+ from the point from which changes have been consumed last. If
+ <parameter>upto_lsn</parameter>
+ and <parameter>upto_nchanges</parameter> are NULL,
+ logical decoding will continue until end of WAL. If
+ <parameter>upto_lsn</parameter> is non-NULL, decoding will include only
+ those transactions which commit prior to the specified LSN. If
+ <parameter>upto_nchanges</parameter> is non-NULL, decoding will
+ stop when the number of rows produced by decoding exceeds
+ the specified value. Note, however, that the actual number of
+ rows returned may be larger, since this limit is only checked after
+ adding the rows produced when decoding each new transaction commit.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_logical_slot_peek_changes</primary>
+ </indexterm>
+ <function>pg_logical_slot_peek_changes</function> ( <parameter>slot_name</parameter> <type>name</type>, <parameter>upto_lsn</parameter> <type>pg_lsn</type>, <parameter>upto_nchanges</parameter> <type>integer</type>, <literal>VARIADIC</literal> <parameter>options</parameter> <type>text[]</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>lsn</parameter> <type>pg_lsn</type>,
+ <parameter>xid</parameter> <type>xid</type>,
+ <parameter>data</parameter> <type>text</type> )
+ </para>
+ <para>
+ Behaves just like
+ the <function>pg_logical_slot_get_changes()</function> function,
+ except that changes are not consumed; that is, they will be returned
+ again on future calls.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_logical_slot_get_binary_changes</primary>
+ </indexterm>
+ <function>pg_logical_slot_get_binary_changes</function> ( <parameter>slot_name</parameter> <type>name</type>, <parameter>upto_lsn</parameter> <type>pg_lsn</type>, <parameter>upto_nchanges</parameter> <type>integer</type>, <literal>VARIADIC</literal> <parameter>options</parameter> <type>text[]</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>lsn</parameter> <type>pg_lsn</type>,
+ <parameter>xid</parameter> <type>xid</type>,
+ <parameter>data</parameter> <type>bytea</type> )
+ </para>
+ <para>
+ Behaves just like
+ the <function>pg_logical_slot_get_changes()</function> function,
+ except that changes are returned as <type>bytea</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_logical_slot_peek_binary_changes</primary>
+ </indexterm>
+ <function>pg_logical_slot_peek_binary_changes</function> ( <parameter>slot_name</parameter> <type>name</type>, <parameter>upto_lsn</parameter> <type>pg_lsn</type>, <parameter>upto_nchanges</parameter> <type>integer</type>, <literal>VARIADIC</literal> <parameter>options</parameter> <type>text[]</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>lsn</parameter> <type>pg_lsn</type>,
+ <parameter>xid</parameter> <type>xid</type>,
+ <parameter>data</parameter> <type>bytea</type> )
+ </para>
+ <para>
+ Behaves just like
+ the <function>pg_logical_slot_peek_changes()</function> function,
+ except that changes are returned as <type>bytea</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_slot_advance</primary>
+ </indexterm>
+ <function>pg_replication_slot_advance</function> ( <parameter>slot_name</parameter> <type>name</type>, <parameter>upto_lsn</parameter> <type>pg_lsn</type> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>slot_name</parameter> <type>name</type>,
+ <parameter>end_lsn</parameter> <type>pg_lsn</type> )
+ </para>
+ <para>
+ Advances the current confirmed position of a replication slot named
+ <parameter>slot_name</parameter>. The slot will not be moved backwards,
+ and it will not be moved beyond the current insert location. Returns
+ the name of the slot and the actual position that it was advanced to.
+ The updated slot position information is written out at the next
+ checkpoint if any advancing is done. So in the event of a crash, the
+ slot may return to an earlier position.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-create" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_create</primary>
+ </indexterm>
+ <function>pg_replication_origin_create</function> ( <parameter>node_name</parameter> <type>text</type> )
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Creates a replication origin with the given external
+ name, and returns the internal ID assigned to it.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-drop" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_drop</primary>
+ </indexterm>
+ <function>pg_replication_origin_drop</function> ( <parameter>node_name</parameter> <type>text</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Deletes a previously-created replication origin, including any
+ associated replay progress.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_oid</primary>
+ </indexterm>
+ <function>pg_replication_origin_oid</function> ( <parameter>node_name</parameter> <type>text</type> )
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Looks up a replication origin by name and returns the internal ID. If
+ no such replication origin is found, <literal>NULL</literal> is
+ returned.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-session-setup" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_session_setup</primary>
+ </indexterm>
+ <function>pg_replication_origin_session_setup</function> ( <parameter>node_name</parameter> <type>text</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Marks the current session as replaying from the given
+ origin, allowing replay progress to be tracked.
+ Can only be used if no origin is currently selected.
+ Use <function>pg_replication_origin_session_reset</function> to undo.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_session_reset</primary>
+ </indexterm>
+ <function>pg_replication_origin_session_reset</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Cancels the effects
+ of <function>pg_replication_origin_session_setup()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_session_is_setup</primary>
+ </indexterm>
+ <function>pg_replication_origin_session_is_setup</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns true if a replication origin has been selected in the
+ current session.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-session-progress" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_session_progress</primary>
+ </indexterm>
+ <function>pg_replication_origin_session_progress</function> ( <parameter>flush</parameter> <type>boolean</type> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the replay location for the replication origin selected in
+ the current session. The parameter <parameter>flush</parameter>
+ determines whether the corresponding local transaction will be
+ guaranteed to have been flushed to disk or not.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-xact-setup" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_xact_setup</primary>
+ </indexterm>
+ <function>pg_replication_origin_xact_setup</function> ( <parameter>origin_lsn</parameter> <type>pg_lsn</type>, <parameter>origin_timestamp</parameter> <type>timestamp with time zone</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Marks the current transaction as replaying a transaction that has
+ committed at the given <acronym>LSN</acronym> and timestamp. Can
+ only be called when a replication origin has been selected
+ using <function>pg_replication_origin_session_setup</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-xact-reset" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_xact_reset</primary>
+ </indexterm>
+ <function>pg_replication_origin_xact_reset</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Cancels the effects of
+ <function>pg_replication_origin_xact_setup()</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-advance" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_advance</primary>
+ </indexterm>
+ <function>pg_replication_origin_advance</function> ( <parameter>node_name</parameter> <type>text</type>, <parameter>lsn</parameter> <type>pg_lsn</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Sets replication progress for the given node to the given
+ location. This is primarily useful for setting up the initial
+ location, or setting a new location after configuration changes and
+ similar. Be aware that careless use of this function can lead to
+ inconsistently replicated data.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-replication-origin-progress" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_replication_origin_progress</primary>
+ </indexterm>
+ <function>pg_replication_origin_progress</function> ( <parameter>node_name</parameter> <type>text</type>, <parameter>flush</parameter> <type>boolean</type> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Returns the replay location for the given replication origin. The
+ parameter <parameter>flush</parameter> determines whether the
+ corresponding local transaction will be guaranteed to have been
+ flushed to disk or not.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry id="pg-logical-emit-message" role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_logical_emit_message</primary>
+ </indexterm>
+ <function>pg_logical_emit_message</function> ( <parameter>transactional</parameter> <type>boolean</type>, <parameter>prefix</parameter> <type>text</type>, <parameter>content</parameter> <type>text</type> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_logical_emit_message</function> ( <parameter>transactional</parameter> <type>boolean</type>, <parameter>prefix</parameter> <type>text</type>, <parameter>content</parameter> <type>bytea</type> )
+ <returnvalue>pg_lsn</returnvalue>
+ </para>
+ <para>
+ Emits a logical decoding message. This can be used to pass generic
+ messages to logical decoding plugins through
+ WAL. The <parameter>transactional</parameter> parameter specifies if
+ the message should be part of the current transaction, or if it should
+ be written immediately and decoded as soon as the logical decoder
+ reads the record. The <parameter>prefix</parameter> parameter is a
+ textual prefix that can be used by logical decoding plugins to easily
+ recognize messages that are interesting for them.
+ The <parameter>content</parameter> parameter is the content of the
+ message, given either in text or binary form.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="functions-admin-dbobject">
+ <title>Database Object Management Functions</title>
+
+ <para>
+ The functions shown in <xref linkend="functions-admin-dbsize"/> calculate
+ the disk space usage of database objects, or assist in presentation
+ or understanding of usage results. <literal>bigint</literal> results
+ are measured in bytes. If an OID that does
+ not represent an existing object is passed to one of these
+ functions, <literal>NULL</literal> is returned.
+ </para>
+
+ <table id="functions-admin-dbsize">
+ <title>Database Object Size Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_column_size</primary>
+ </indexterm>
+ <function>pg_column_size</function> ( <type>"any"</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Shows the number of bytes used to store any individual data value. If
+ applied directly to a table column value, this reflects any
+ compression that was done.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_column_compression</primary>
+ </indexterm>
+ <function>pg_column_compression</function> ( <type>"any"</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Shows the compression algorithm that was used to compress
+ an individual variable-length value. Returns <literal>NULL</literal>
+ if the value is not compressed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_database_size</primary>
+ </indexterm>
+ <function>pg_database_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_database_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by the database with the specified
+ name or OID. To use this function, you must
+ have <literal>CONNECT</literal> privilege on the specified database
+ (which is granted by default) or have privileges of
+ the <literal>pg_read_all_stats</literal> role.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_indexes_size</primary>
+ </indexterm>
+ <function>pg_indexes_size</function> ( <type>regclass</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by indexes attached to the
+ specified table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_relation_size</primary>
+ </indexterm>
+ <function>pg_relation_size</function> ( <parameter>relation</parameter> <type>regclass</type> <optional>, <parameter>fork</parameter> <type>text</type> </optional> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the disk space used by one <quote>fork</quote> of the
+ specified relation. (Note that for most purposes it is more
+ convenient to use the higher-level
+ functions <function>pg_total_relation_size</function>
+ or <function>pg_table_size</function>, which sum the sizes of all
+ forks.) With one argument, this returns the size of the main data
+ fork of the relation. The second argument can be provided to specify
+ which fork to examine:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>main</literal> returns the size of the main
+ data fork of the relation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>fsm</literal> returns the size of the Free Space Map
+ (see <xref linkend="storage-fsm"/>) associated with the relation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>vm</literal> returns the size of the Visibility Map
+ (see <xref linkend="storage-vm"/>) associated with the relation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>init</literal> returns the size of the initialization
+ fork, if any, associated with the relation.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_size_bytes</primary>
+ </indexterm>
+ <function>pg_size_bytes</function> ( <type>text</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Converts a size in human-readable format (as returned
+ by <function>pg_size_pretty</function>) into bytes.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_size_pretty</primary>
+ </indexterm>
+ <function>pg_size_pretty</function> ( <type>bigint</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_size_pretty</function> ( <type>numeric</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Converts a size in bytes into a more easily human-readable format with
+ size units (bytes, kB, MB, GB, TB, or PB as appropriate). Note that the
+ units are powers of 2 rather than powers of 10, so 1kB is 1024 bytes,
+ 1MB is 1024<superscript>2</superscript> = 1048576 bytes, and so on.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_table_size</primary>
+ </indexterm>
+ <function>pg_table_size</function> ( <type>regclass</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the disk space used by the specified table, excluding indexes
+ (but including its TOAST table if any, free space map, and visibility
+ map).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_tablespace_size</primary>
+ </indexterm>
+ <function>pg_tablespace_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_tablespace_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used in the tablespace with the
+ specified name or OID. To use this function, you must
+ have <literal>CREATE</literal> privilege on the specified tablespace
+ or have privileges of the <literal>pg_read_all_stats</literal> role,
+ unless it is the default tablespace for the current database.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_total_relation_size</primary>
+ </indexterm>
+ <function>pg_total_relation_size</function> ( <type>regclass</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by the specified table, including
+ all indexes and <acronym>TOAST</acronym> data. The result is
+ equivalent to <function>pg_table_size</function>
+ <literal>+</literal> <function>pg_indexes_size</function>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The functions above that operate on tables or indexes accept a
+ <type>regclass</type> argument, which is simply the OID of the table or index
+ in the <structname>pg_class</structname> system catalog. You do not have to look up
+ the OID by hand, however, since the <type>regclass</type> data type's input
+ converter will do the work for you. See <xref linkend="datatype-oid"/>
+ for details.
+ </para>
+
+ <para>
+ The functions shown in <xref linkend="functions-admin-dblocation"/> assist
+ in identifying the specific disk files associated with database objects.
+ </para>
+
+ <table id="functions-admin-dblocation">
+ <title>Database Object Location Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_relation_filenode</primary>
+ </indexterm>
+ <function>pg_relation_filenode</function> ( <parameter>relation</parameter> <type>regclass</type> )
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Returns the <quote>filenode</quote> number currently assigned to the
+ specified relation. The filenode is the base component of the file
+ name(s) used for the relation (see
+ <xref linkend="storage-file-layout"/> for more information).
+ For most relations the result is the same as
+ <structname>pg_class</structname>.<structfield>relfilenode</structfield>,
+ but for certain system catalogs <structfield>relfilenode</structfield>
+ is zero and this function must be used to get the correct value. The
+ function returns NULL if passed a relation that does not have storage,
+ such as a view.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_relation_filepath</primary>
+ </indexterm>
+ <function>pg_relation_filepath</function> ( <parameter>relation</parameter> <type>regclass</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the entire file path name (relative to the database cluster's
+ data directory, <varname>PGDATA</varname>) of the relation.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_filenode_relation</primary>
+ </indexterm>
+ <function>pg_filenode_relation</function> ( <parameter>tablespace</parameter> <type>oid</type>, <parameter>filenode</parameter> <type>oid</type> )
+ <returnvalue>regclass</returnvalue>
+ </para>
+ <para>
+ Returns a relation's OID given the tablespace OID and filenode it is
+ stored under. This is essentially the inverse mapping of
+ <function>pg_relation_filepath</function>. For a relation in the
+ database's default tablespace, the tablespace can be specified as zero.
+ Returns <literal>NULL</literal> if no relation in the current database
+ is associated with the given values.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-admin-collation"/> lists functions used to manage
+ collations.
+ </para>
+
+ <table id="functions-admin-collation">
+ <title>Collation Management Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_collation_actual_version</primary>
+ </indexterm>
+ <function>pg_collation_actual_version</function> ( <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the actual version of the collation object as it is currently
+ installed in the operating system. If this is different from the
+ value in
+ <structname>pg_collation</structname>.<structfield>collversion</structfield>,
+ then objects depending on the collation might need to be rebuilt. See
+ also <xref linkend="sql-altercollation"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_database_collation_actual_version</primary>
+ </indexterm>
+ <function>pg_database_collation_actual_version</function> ( <type>oid</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the actual version of the database's collation as it is currently
+ installed in the operating system. If this is different from the
+ value in
+ <structname>pg_database</structname>.<structfield>datcollversion</structfield>,
+ then objects depending on the collation might need to be rebuilt. See
+ also <xref linkend="sql-alterdatabase"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_import_system_collations</primary>
+ </indexterm>
+ <function>pg_import_system_collations</function> ( <parameter>schema</parameter> <type>regnamespace</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Adds collations to the system
+ catalog <structname>pg_collation</structname> based on all the locales
+ it finds in the operating system. This is
+ what <command>initdb</command> uses; see
+ <xref linkend="collation-managing"/> for more details. If additional
+ locales are installed into the operating system later on, this
+ function can be run again to add collations for the new locales.
+ Locales that match existing entries
+ in <structname>pg_collation</structname> will be skipped. (But
+ collation objects based on locales that are no longer present in the
+ operating system are not removed by this function.)
+ The <parameter>schema</parameter> parameter would typically
+ be <literal>pg_catalog</literal>, but that is not a requirement; the
+ collations could be installed into some other schema as well. The
+ function returns the number of new collation objects it created.
+ Use of this function is restricted to superusers.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <xref linkend="functions-info-partition"/> lists functions that provide
+ information about the structure of partitioned tables.
+ </para>
+
+ <table id="functions-info-partition">
+ <title>Partitioning Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_partition_tree</primary>
+ </indexterm>
+ <function>pg_partition_tree</function> ( <type>regclass</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>relid</parameter> <type>regclass</type>,
+ <parameter>parentrelid</parameter> <type>regclass</type>,
+ <parameter>isleaf</parameter> <type>boolean</type>,
+ <parameter>level</parameter> <type>integer</type> )
+ </para>
+ <para>
+ Lists the tables or indexes in the partition tree of the
+ given partitioned table or partitioned index, with one row for each
+ partition. Information provided includes the OID of the partition,
+ the OID of its immediate parent, a boolean value telling if the
+ partition is a leaf, and an integer telling its level in the hierarchy.
+ The level value is 0 for the input table or index, 1 for its
+ immediate child partitions, 2 for their partitions, and so on.
+ Returns no rows if the relation does not exist or is not a partition
+ or partitioned table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_partition_ancestors</primary>
+ </indexterm>
+ <function>pg_partition_ancestors</function> ( <type>regclass</type> )
+ <returnvalue>setof regclass</returnvalue>
+ </para>
+ <para>
+ Lists the ancestor relations of the given partition,
+ including the relation itself. Returns no rows if the relation
+ does not exist or is not a partition or partitioned table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_partition_root</primary>
+ </indexterm>
+ <function>pg_partition_root</function> ( <type>regclass</type> )
+ <returnvalue>regclass</returnvalue>
+ </para>
+ <para>
+ Returns the top-most parent of the partition tree to which the given
+ relation belongs. Returns <literal>NULL</literal> if the relation
+ does not exist or is not a partition or partitioned table.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ For example, to check the total size of the data contained in a
+ partitioned table <structname>measurement</structname>, one could use the
+ following query:
+<programlisting>
+SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
+ FROM pg_partition_tree('measurement');
+</programlisting>
+ </para>
+
+ </sect2>
+
+ <sect2 id="functions-admin-index">
+ <title>Index Maintenance Functions</title>
+
+ <para>
+ <xref linkend="functions-admin-index-table"/> shows the functions
+ available for index maintenance tasks. (Note that these maintenance
+ tasks are normally done automatically by autovacuum; use of these
+ functions is only required in special cases.)
+ These functions cannot be executed during recovery.
+ Use of these functions is restricted to superusers and the owner
+ of the given index.
+ </para>
+
+ <table id="functions-admin-index-table">
+ <title>Index Maintenance Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>brin_summarize_new_values</primary>
+ </indexterm>
+ <function>brin_summarize_new_values</function> ( <parameter>index</parameter> <type>regclass</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Scans the specified BRIN index to find page ranges in the base table
+ that are not currently summarized by the index; for any such range it
+ creates a new summary index tuple by scanning those table pages.
+ Returns the number of new page range summaries that were inserted
+ into the index.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>brin_summarize_range</primary>
+ </indexterm>
+ <function>brin_summarize_range</function> ( <parameter>index</parameter> <type>regclass</type>, <parameter>blockNumber</parameter> <type>bigint</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Summarizes the page range covering the given block, if not already
+ summarized. This is
+ like <function>brin_summarize_new_values</function> except that it
+ only processes the page range that covers the given table block number.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>brin_desummarize_range</primary>
+ </indexterm>
+ <function>brin_desummarize_range</function> ( <parameter>index</parameter> <type>regclass</type>, <parameter>blockNumber</parameter> <type>bigint</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Removes the BRIN index tuple that summarizes the page range covering
+ the given table block, if there is one.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>gin_clean_pending_list</primary>
+ </indexterm>
+ <function>gin_clean_pending_list</function> ( <parameter>index</parameter> <type>regclass</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Cleans up the <quote>pending</quote> list of the specified GIN index
+ by moving entries in it, in bulk, to the main GIN data structure.
+ Returns the number of pages removed from the pending list.
+ If the argument is a GIN index built with
+ the <literal>fastupdate</literal> option disabled, no cleanup happens
+ and the result is zero, because the index doesn't have a pending list.
+ See <xref linkend="gin-fast-update"/> and <xref linkend="gin-tips"/>
+ for details about the pending list and <literal>fastupdate</literal>
+ option.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="functions-admin-genfile">
+ <title>Generic File Access Functions</title>
+
+ <para>
+ The functions shown in <xref
+ linkend="functions-admin-genfile-table"/> provide native access to
+ files on the machine hosting the server. Only files within the
+ database cluster directory and the <varname>log_directory</varname> can be
+ accessed, unless the user is a superuser or is granted the role
+ <literal>pg_read_server_files</literal>. Use a relative path for files in
+ the cluster directory, and a path matching the <varname>log_directory</varname>
+ configuration setting for log files.
+ </para>
+
+ <para>
+ Note that granting users the EXECUTE privilege on
+ <function>pg_read_file()</function>, or related functions, allows them the
+ ability to read any file on the server that the database server process can
+ read; these functions bypass all in-database privilege checks. This means
+ that, for example, a user with such access is able to read the contents of
+ the <structname>pg_authid</structname> table where authentication
+ information is stored, as well as read any table data in the database.
+ Therefore, granting access to these functions should be carefully
+ considered.
+ </para>
+
+ <para>
+ Some of these functions take an optional <parameter>missing_ok</parameter>
+ parameter, which specifies the behavior when the file or directory does
+ not exist. If <literal>true</literal>, the function
+ returns <literal>NULL</literal> or an empty result set, as appropriate.
+ If <literal>false</literal>, an error is raised. The default
+ is <literal>false</literal>.
+ </para>
+
+ <table id="functions-admin-genfile-table">
+ <title>Generic File Access Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_dir</primary>
+ </indexterm>
+ <function>pg_ls_dir</function> ( <parameter>dirname</parameter> <type>text</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type>, <parameter>include_dot_dirs</parameter> <type>boolean</type> </optional> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Returns the names of all files (and directories and other special
+ files) in the specified
+ directory. The <parameter>include_dot_dirs</parameter> parameter
+ indicates whether <quote>.</quote> and <quote>..</quote> are to be
+ included in the result set; the default is to exclude them. Including
+ them can be useful when <parameter>missing_ok</parameter>
+ is <literal>true</literal>, to distinguish an empty directory from a
+ non-existent directory.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_logdir</primary>
+ </indexterm>
+ <function>pg_ls_logdir</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's log directory. Filenames beginning with
+ a dot, directories, and other special files are excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and roles with privileges of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_waldir</primary>
+ </indexterm>
+ <function>pg_ls_waldir</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's write-ahead log (WAL) directory.
+ Filenames beginning with a dot, directories, and other special files
+ are excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and roles with privileges of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_logicalmapdir</primary>
+ </indexterm>
+ <function>pg_ls_logicalmapdir</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's <filename>pg_logical/mappings</filename>
+ directory. Filenames beginning with a dot, directories, and other
+ special files are excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and members of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_logicalsnapdir</primary>
+ </indexterm>
+ <function>pg_ls_logicalsnapdir</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's <filename>pg_logical/snapshots</filename>
+ directory. Filenames beginning with a dot, directories, and other
+ special files are excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and members of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_replslotdir</primary>
+ </indexterm>
+ <function>pg_ls_replslotdir</function> ( <parameter>slot_name</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's <filename>pg_replslot/slot_name</filename>
+ directory, where <parameter>slot_name</parameter> is the name of the
+ replication slot provided as input of the function. Filenames beginning
+ with a dot, directories, and other special files are excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and members of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_ls_archive_statusdir</primary>
+ </indexterm>
+ <function>pg_ls_archive_statusdir</function> ()
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's WAL archive status directory
+ (<filename>pg_wal/archive_status</filename>). Filenames beginning
+ with a dot, directories, and other special files are excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and members of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+
+ <indexterm>
+ <primary>pg_ls_tmpdir</primary>
+ </indexterm>
+ <function>pg_ls_tmpdir</function> ( <optional> <parameter>tablespace</parameter> <type>oid</type> </optional> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>name</parameter> <type>text</type>,
+ <parameter>size</parameter> <type>bigint</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type> )
+ </para>
+ <para>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the temporary file directory for the
+ specified <parameter>tablespace</parameter>.
+ If <parameter>tablespace</parameter> is not provided,
+ the <literal>pg_default</literal> tablespace is examined. Filenames
+ beginning with a dot, directories, and other special files are
+ excluded.
+ </para>
+ <para>
+ This function is restricted to superusers and members of
+ the <literal>pg_monitor</literal> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_read_file</primary>
+ </indexterm>
+ <function>pg_read_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>bigint</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns all or part of a text file, starting at the
+ given byte <parameter>offset</parameter>, returning at
+ most <parameter>length</parameter> bytes (less if the end of file is
+ reached first). If <parameter>offset</parameter> is negative, it is
+ relative to the end of the file. If <parameter>offset</parameter>
+ and <parameter>length</parameter> are omitted, the entire file is
+ returned. The bytes read from the file are interpreted as a string in
+ the database's encoding; an error is thrown if they are not valid in
+ that encoding.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_read_binary_file</primary>
+ </indexterm>
+ <function>pg_read_binary_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>bigint</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional></optional> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Returns all or part of a file. This function is identical to
+ <function>pg_read_file</function> except that it can read arbitrary
+ binary data, returning the result as <type>bytea</type>
+ not <type>text</type>; accordingly, no encoding checks are performed.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para>
+ <para>
+ In combination with the <function>convert_from</function> function,
+ this function can be used to read a text file in a specified encoding
+ and convert to the database's encoding:
+<programlisting>
+SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8');
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_file</primary>
+ </indexterm>
+ <function>pg_stat_file</function> ( <parameter>filename</parameter> <type>text</type> <optional>, <parameter>missing_ok</parameter> <type>boolean</type> </optional> )
+ <returnvalue>record</returnvalue>
+ ( <parameter>size</parameter> <type>bigint</type>,
+ <parameter>access</parameter> <type>timestamp with time zone</type>,
+ <parameter>modification</parameter> <type>timestamp with time zone</type>,
+ <parameter>change</parameter> <type>timestamp with time zone</type>,
+ <parameter>creation</parameter> <type>timestamp with time zone</type>,
+ <parameter>isdir</parameter> <type>boolean</type> )
+ </para>
+ <para>
+ Returns a record containing the file's size, last access time stamp,
+ last modification time stamp, last file status change time stamp (Unix
+ platforms only), file creation time stamp (Windows only), and a flag
+ indicating if it is a directory.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="functions-advisory-locks">
+ <title>Advisory Lock Functions</title>
+
+ <para>
+ The functions shown in <xref linkend="functions-advisory-locks-table"/>
+ manage advisory locks. For details about proper use of these functions,
+ see <xref linkend="advisory-locks"/>.
+ </para>
+
+ <para>
+ All these functions are intended to be used to lock application-defined
+ resources, which can be identified either by a single 64-bit key value or
+ two 32-bit key values (note that these two key spaces do not overlap).
+ If another session already holds a conflicting lock on the same resource
+ identifier, the functions will either wait until the resource becomes
+ available, or return a <literal>false</literal> result, as appropriate for
+ the function.
+ Locks can be either shared or exclusive: a shared lock does not conflict
+ with other shared locks on the same resource, only with exclusive locks.
+ Locks can be taken at session level (so that they are held until released
+ or the session ends) or at transaction level (so that they are held until
+ the current transaction ends; there is no provision for manual release).
+ Multiple session-level lock requests stack, so that if the same resource
+ identifier is locked three times there must then be three unlock requests
+ to release the resource in advance of session end.
+ </para>
+
+ <table id="functions-advisory-locks-table">
+ <title>Advisory Lock Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_lock</primary>
+ </indexterm>
+ <function>pg_advisory_lock</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_advisory_lock</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Obtains an exclusive session-level advisory lock, waiting if necessary.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_lock_shared</primary>
+ </indexterm>
+ <function>pg_advisory_lock_shared</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_advisory_lock_shared</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Obtains a shared session-level advisory lock, waiting if necessary.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_unlock</primary>
+ </indexterm>
+ <function>pg_advisory_unlock</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_advisory_unlock</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Releases a previously-acquired exclusive session-level advisory lock.
+ Returns <literal>true</literal> if the lock is successfully released.
+ If the lock was not held, <literal>false</literal> is returned, and in
+ addition, an SQL warning will be reported by the server.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_unlock_all</primary>
+ </indexterm>
+ <function>pg_advisory_unlock_all</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Releases all session-level advisory locks held by the current session.
+ (This function is implicitly invoked at session end, even if the
+ client disconnects ungracefully.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_unlock_shared</primary>
+ </indexterm>
+ <function>pg_advisory_unlock_shared</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_advisory_unlock_shared</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Releases a previously-acquired shared session-level advisory lock.
+ Returns <literal>true</literal> if the lock is successfully released.
+ If the lock was not held, <literal>false</literal> is returned, and in
+ addition, an SQL warning will be reported by the server.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_xact_lock</primary>
+ </indexterm>
+ <function>pg_advisory_xact_lock</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_advisory_xact_lock</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Obtains an exclusive transaction-level advisory lock, waiting if
+ necessary.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_advisory_xact_lock_shared</primary>
+ </indexterm>
+ <function>pg_advisory_xact_lock_shared</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_advisory_xact_lock_shared</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Obtains a shared transaction-level advisory lock, waiting if
+ necessary.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_try_advisory_lock</primary>
+ </indexterm>
+ <function>pg_try_advisory_lock</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_try_advisory_lock</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Obtains an exclusive session-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <literal>true</literal>, or return <literal>false</literal>
+ without waiting if the lock cannot be acquired immediately.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_try_advisory_lock_shared</primary>
+ </indexterm>
+ <function>pg_try_advisory_lock_shared</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_try_advisory_lock_shared</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Obtains a shared session-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <literal>true</literal>, or return <literal>false</literal>
+ without waiting if the lock cannot be acquired immediately.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_try_advisory_xact_lock</primary>
+ </indexterm>
+ <function>pg_try_advisory_xact_lock</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_try_advisory_xact_lock</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Obtains an exclusive transaction-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <literal>true</literal>, or return <literal>false</literal>
+ without waiting if the lock cannot be acquired immediately.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_try_advisory_xact_lock_shared</primary>
+ </indexterm>
+ <function>pg_try_advisory_xact_lock_shared</function> ( <parameter>key</parameter> <type>bigint</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_try_advisory_xact_lock_shared</function> ( <parameter>key1</parameter> <type>integer</type>, <parameter>key2</parameter> <type>integer</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Obtains a shared transaction-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <literal>true</literal>, or return <literal>false</literal>
+ without waiting if the lock cannot be acquired immediately.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="functions-trigger">
+ <title>Trigger Functions</title>
+
+ <para>
+ While many uses of triggers involve user-written trigger functions,
+ <productname>PostgreSQL</productname> provides a few built-in trigger
+ functions that can be used directly in user-defined triggers. These
+ are summarized in <xref linkend="builtin-triggers-table"/>.
+ (Additional built-in trigger functions exist, which implement foreign
+ key constraints and deferred index constraints. Those are not documented
+ here since users need not use them directly.)
+ </para>
+
+ <para>
+ For more information about creating triggers, see
+ <xref linkend="sql-createtrigger"/>.
+ </para>
+
+ <table id="builtin-triggers-table">
+ <title>Built-In Trigger Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example Usage
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>suppress_redundant_updates_trigger</primary>
+ </indexterm>
+ <function>suppress_redundant_updates_trigger</function> ( )
+ <returnvalue>trigger</returnvalue>
+ </para>
+ <para>
+ Suppresses do-nothing update operations. See below for details.
+ </para>
+ <para>
+ <literal>CREATE TRIGGER ... suppress_redundant_updates_trigger()</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tsvector_update_trigger</primary>
+ </indexterm>
+ <function>tsvector_update_trigger</function> ( )
+ <returnvalue>trigger</returnvalue>
+ </para>
+ <para>
+ Automatically updates a <type>tsvector</type> column from associated
+ plain-text document column(s). The text search configuration to use
+ is specified by name as a trigger argument. See
+ <xref linkend="textsearch-update-triggers"/> for details.
+ </para>
+ <para>
+ <literal>CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body)</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>tsvector_update_trigger_column</primary>
+ </indexterm>
+ <function>tsvector_update_trigger_column</function> ( )
+ <returnvalue>trigger</returnvalue>
+ </para>
+ <para>
+ Automatically updates a <type>tsvector</type> column from associated
+ plain-text document column(s). The text search configuration to use
+ is taken from a <type>regconfig</type> column of the table. See
+ <xref linkend="textsearch-update-triggers"/> for details.
+ </para>
+ <para>
+ <literal>CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body)</literal>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <function>suppress_redundant_updates_trigger</function> function,
+ when applied as a row-level <literal>BEFORE UPDATE</literal> trigger,
+ will prevent any update that does not actually change the data in the
+ row from taking place. This overrides the normal behavior which always
+ performs a physical row update
+ regardless of whether or not the data has changed. (This normal behavior
+ makes updates run faster, since no checking is required, and is also
+ useful in certain cases.)
+ </para>
+
+ <para>
+ Ideally, you should avoid running updates that don't actually
+ change the data in the record. Redundant updates can cost considerable
+ unnecessary time, especially if there are lots of indexes to alter,
+ and space in dead rows that will eventually have to be vacuumed.
+ However, detecting such situations in client code is not
+ always easy, or even possible, and writing expressions to detect
+ them can be error-prone. An alternative is to use
+ <function>suppress_redundant_updates_trigger</function>, which will skip
+ updates that don't change the data. You should use this with care,
+ however. The trigger takes a small but non-trivial time for each record,
+ so if most of the records affected by updates do actually change,
+ use of this trigger will make updates run slower on average.
+ </para>
+
+ <para>
+ The <function>suppress_redundant_updates_trigger</function> function can be
+ added to a table like this:
+<programlisting>
+CREATE TRIGGER z_min_update
+BEFORE UPDATE ON tablename
+FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger();
+</programlisting>
+ In most cases, you need to fire this trigger last for each row, so that
+ it does not override other triggers that might wish to alter the row.
+ Bearing in mind that triggers fire in name order, you would therefore
+ choose a trigger name that comes after the name of any other trigger
+ you might have on the table. (Hence the <quote>z</quote> prefix in the
+ example.)
+ </para>
+ </sect1>
+
+ <sect1 id="functions-event-triggers">
+ <title>Event Trigger Functions</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides these helper functions
+ to retrieve information from event triggers.
+ </para>
+
+ <para>
+ For more information about event triggers,
+ see <xref linkend="event-triggers"/>.
+ </para>
+
+ <sect2 id="pg-event-trigger-ddl-command-end-functions">
+ <title>Capturing Changes at Command End</title>
+
+ <indexterm>
+ <primary>pg_event_trigger_ddl_commands</primary>
+ </indexterm>
+
+<synopsis>
+<function>pg_event_trigger_ddl_commands</function> () <returnvalue>setof record</returnvalue>
+</synopsis>
+
+ <para>
+ <function>pg_event_trigger_ddl_commands</function> returns a list of
+ <acronym>DDL</acronym> commands executed by each user action,
+ when invoked in a function attached to a
+ <literal>ddl_command_end</literal> event trigger. If called in any other
+ context, an error is raised.
+ <function>pg_event_trigger_ddl_commands</function> returns one row for each
+ base command executed; some commands that are a single SQL sentence
+ may return more than one row. This function returns the following
+ columns:
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>classid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry>OID of catalog the object belongs in</entry>
+ </row>
+ <row>
+ <entry><literal>objid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry>OID of the object itself</entry>
+ </row>
+ <row>
+ <entry><literal>objsubid</literal></entry>
+ <entry><type>integer</type></entry>
+ <entry>Sub-object ID (e.g., attribute number for a column)</entry>
+ </row>
+ <row>
+ <entry><literal>command_tag</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>Command tag</entry>
+ </row>
+ <row>
+ <entry><literal>object_type</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>Type of the object</entry>
+ </row>
+ <row>
+ <entry><literal>schema_name</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Name of the schema the object belongs in, if any; otherwise <literal>NULL</literal>.
+ No quoting is applied.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>object_identity</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Text rendering of the object identity, schema-qualified. Each
+ identifier included in the identity is quoted if necessary.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>in_extension</literal></entry>
+ <entry><type>boolean</type></entry>
+ <entry>True if the command is part of an extension script</entry>
+ </row>
+ <row>
+ <entry><literal>command</literal></entry>
+ <entry><type>pg_ddl_command</type></entry>
+ <entry>
+ A complete representation of the command, in internal format.
+ This cannot be output directly, but it can be passed to other
+ functions to obtain different pieces of information about the
+ command.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </sect2>
+
+ <sect2 id="pg-event-trigger-sql-drop-functions">
+ <title>Processing Objects Dropped by a DDL Command</title>
+
+ <indexterm>
+ <primary>pg_event_trigger_dropped_objects</primary>
+ </indexterm>
+
+<synopsis>
+<function>pg_event_trigger_dropped_objects</function> () <returnvalue>setof record</returnvalue>
+</synopsis>
+
+ <para>
+ <function>pg_event_trigger_dropped_objects</function> returns a list of all objects
+ dropped by the command in whose <literal>sql_drop</literal> event it is called.
+ If called in any other context, an error is raised.
+ This function returns the following columns:
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>classid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry>OID of catalog the object belonged in</entry>
+ </row>
+ <row>
+ <entry><literal>objid</literal></entry>
+ <entry><type>oid</type></entry>
+ <entry>OID of the object itself</entry>
+ </row>
+ <row>
+ <entry><literal>objsubid</literal></entry>
+ <entry><type>integer</type></entry>
+ <entry>Sub-object ID (e.g., attribute number for a column)</entry>
+ </row>
+ <row>
+ <entry><literal>original</literal></entry>
+ <entry><type>boolean</type></entry>
+ <entry>True if this was one of the root object(s) of the deletion</entry>
+ </row>
+ <row>
+ <entry><literal>normal</literal></entry>
+ <entry><type>boolean</type></entry>
+ <entry>
+ True if there was a normal dependency relationship
+ in the dependency graph leading to this object
+ </entry>
+ </row>
+ <row>
+ <entry><literal>is_temporary</literal></entry>
+ <entry><type>boolean</type></entry>
+ <entry>
+ True if this was a temporary object
+ </entry>
+ </row>
+ <row>
+ <entry><literal>object_type</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>Type of the object</entry>
+ </row>
+ <row>
+ <entry><literal>schema_name</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Name of the schema the object belonged in, if any; otherwise <literal>NULL</literal>.
+ No quoting is applied.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>object_name</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Name of the object, if the combination of schema and name can be
+ used as a unique identifier for the object; otherwise <literal>NULL</literal>.
+ No quoting is applied, and name is never schema-qualified.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>object_identity</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>
+ Text rendering of the object identity, schema-qualified. Each
+ identifier included in the identity is quoted if necessary.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>address_names</literal></entry>
+ <entry><type>text[]</type></entry>
+ <entry>
+ An array that, together with <literal>object_type</literal> and
+ <literal>address_args</literal>, can be used by
+ the <function>pg_get_object_address</function> function to
+ recreate the object address in a remote server containing an
+ identically named object of the same kind.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>address_args</literal></entry>
+ <entry><type>text[]</type></entry>
+ <entry>
+ Complement for <literal>address_names</literal>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+
+ <para>
+ The <function>pg_event_trigger_dropped_objects</function> function can be used
+ in an event trigger like this:
+<programlisting>
+CREATE FUNCTION test_event_trigger_for_drops()
+ RETURNS event_trigger LANGUAGE plpgsql AS $$
+DECLARE
+ obj record;
+BEGIN
+ FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
+ LOOP
+ RAISE NOTICE '% dropped object: % %.% %',
+ tg_tag,
+ obj.object_type,
+ obj.schema_name,
+ obj.object_name,
+ obj.object_identity;
+ END LOOP;
+END;
+$$;
+CREATE EVENT TRIGGER test_event_trigger_for_drops
+ ON sql_drop
+ EXECUTE FUNCTION test_event_trigger_for_drops();
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="pg-event-trigger-table-rewrite-functions">
+ <title>Handling a Table Rewrite Event</title>
+
+ <para>
+ The functions shown in
+ <xref linkend="functions-event-trigger-table-rewrite"/>
+ provide information about a table for which a
+ <literal>table_rewrite</literal> event has just been called.
+ If called in any other context, an error is raised.
+ </para>
+
+ <table id="functions-event-trigger-table-rewrite">
+ <title>Table Rewrite Information Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_event_trigger_table_rewrite_oid</primary>
+ </indexterm>
+ <function>pg_event_trigger_table_rewrite_oid</function> ()
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Returns the OID of the table about to be rewritten.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_event_trigger_table_rewrite_reason</primary>
+ </indexterm>
+ <function>pg_event_trigger_table_rewrite_reason</function> ()
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns a code explaining the reason(s) for rewriting. The exact
+ meaning of the codes is release dependent.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ These functions can be used in an event trigger like this:
+<programlisting>
+CREATE FUNCTION test_event_trigger_table_rewrite_oid()
+ RETURNS event_trigger
+ LANGUAGE plpgsql AS
+$$
+BEGIN
+ RAISE NOTICE 'rewriting table % for reason %',
+ pg_event_trigger_table_rewrite_oid()::regclass,
+ pg_event_trigger_table_rewrite_reason();
+END;
+$$;
+
+CREATE EVENT TRIGGER test_table_rewrite_oid
+ ON table_rewrite
+ EXECUTE FUNCTION test_event_trigger_table_rewrite_oid();
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="functions-statistics">
+ <title>Statistics Information Functions</title>
+
+ <indexterm zone="functions-statistics">
+ <primary>function</primary>
+ <secondary>statistics</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a function to inspect complex
+ statistics defined using the <command>CREATE STATISTICS</command> command.
+ </para>
+
+ <sect2 id="functions-statistics-mcv">
+ <title>Inspecting MCV Lists</title>
+
+ <indexterm>
+ <primary>pg_mcv_list_items</primary>
+ </indexterm>
+
+<synopsis>
+<function>pg_mcv_list_items</function> ( <type>pg_mcv_list</type> ) <returnvalue>setof record</returnvalue>
+</synopsis>
+
+ <para>
+ <function>pg_mcv_list_items</function> returns a set of records describing
+ all items stored in a multi-column <acronym>MCV</acronym> list. It
+ returns the following columns:
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>index</literal></entry>
+ <entry><type>integer</type></entry>
+ <entry>index of the item in the <acronym>MCV</acronym> list</entry>
+ </row>
+ <row>
+ <entry><literal>values</literal></entry>
+ <entry><type>text[]</type></entry>
+ <entry>values stored in the MCV item</entry>
+ </row>
+ <row>
+ <entry><literal>nulls</literal></entry>
+ <entry><type>boolean[]</type></entry>
+ <entry>flags identifying <literal>NULL</literal> values</entry>
+ </row>
+ <row>
+ <entry><literal>frequency</literal></entry>
+ <entry><type>double precision</type></entry>
+ <entry>frequency of this <acronym>MCV</acronym> item</entry>
+ </row>
+ <row>
+ <entry><literal>base_frequency</literal></entry>
+ <entry><type>double precision</type></entry>
+ <entry>base frequency of this <acronym>MCV</acronym> item</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+
+ <para>
+ The <function>pg_mcv_list_items</function> function can be used like this:
+
+<programlisting>
+SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
+ pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts';
+</programlisting>
+
+ Values of the <type>pg_mcv_list</type> type can be obtained only from the
+ <structname>pg_statistic_ext_data</structname>.<structfield>stxdmcv</structfield>
+ column.
+ </para>
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/fuzzystrmatch.sgml b/doc/src/sgml/fuzzystrmatch.sgml
new file mode 100644
index 0000000..382e54b
--- /dev/null
+++ b/doc/src/sgml/fuzzystrmatch.sgml
@@ -0,0 +1,244 @@
+<!-- doc/src/sgml/fuzzystrmatch.sgml -->
+
+<sect1 id="fuzzystrmatch" xreflabel="fuzzystrmatch">
+ <title>fuzzystrmatch</title>
+
+ <indexterm zone="fuzzystrmatch">
+ <primary>fuzzystrmatch</primary>
+ </indexterm>
+
+ <para>
+ The <filename>fuzzystrmatch</filename> module provides several
+ functions to determine similarities and distance between strings.
+ </para>
+
+ <caution>
+ <para>
+ At present, the <function>soundex</function>, <function>metaphone</function>,
+ <function>dmetaphone</function>, and <function>dmetaphone_alt</function> functions do
+ not work well with multibyte encodings (such as UTF-8).
+ </para>
+ </caution>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Soundex</title>
+
+ <para>
+ The Soundex system is a method of matching similar-sounding names
+ by converting them to the same code. It was initially used by the
+ United States Census in 1880, 1900, and 1910. Note that Soundex
+ is not very useful for non-English names.
+ </para>
+
+ <para>
+ The <filename>fuzzystrmatch</filename> module provides two functions
+ for working with Soundex codes:
+ </para>
+
+ <indexterm>
+ <primary>soundex</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>difference</primary>
+ </indexterm>
+
+<synopsis>
+soundex(text) returns text
+difference(text, text) returns int
+</synopsis>
+
+ <para>
+ The <function>soundex</function> function converts a string to its Soundex code.
+ The <function>difference</function> function converts two strings to their Soundex
+ codes and then reports the number of matching code positions. Since
+ Soundex codes have four characters, the result ranges from zero to four,
+ with zero being no match and four being an exact match. (Thus, the
+ function is misnamed &mdash; <function>similarity</function> would have been
+ a better name.)
+ </para>
+
+ <para>
+ Here are some usage examples:
+ </para>
+
+<programlisting>
+SELECT soundex('hello world!');
+
+SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann');
+SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew');
+SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret');
+
+CREATE TABLE s (nm text);
+
+INSERT INTO s VALUES ('john');
+INSERT INTO s VALUES ('joan');
+INSERT INTO s VALUES ('wobbly');
+INSERT INTO s VALUES ('jack');
+
+SELECT * FROM s WHERE soundex(nm) = soundex('john');
+
+SELECT * FROM s WHERE difference(s.nm, 'john') &gt; 2;
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Levenshtein</title>
+
+ <para>
+ This function calculates the Levenshtein distance between two strings:
+ </para>
+
+ <indexterm>
+ <primary>levenshtein</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>levenshtein_less_equal</primary>
+ </indexterm>
+
+<synopsis>
+levenshtein(text source, text target, int ins_cost, int del_cost, int sub_cost) returns int
+levenshtein(text source, text target) returns int
+levenshtein_less_equal(text source, text target, int ins_cost, int del_cost, int sub_cost, int max_d) returns int
+levenshtein_less_equal(text source, text target, int max_d) returns int
+</synopsis>
+
+ <para>
+ Both <literal>source</literal> and <literal>target</literal> can be any
+ non-null string, with a maximum of 255 characters. The cost parameters
+ specify how much to charge for a character insertion, deletion, or
+ substitution, respectively. You can omit the cost parameters, as in
+ the second version of the function; in that case they all default to 1.
+ </para>
+
+ <para>
+ <function>levenshtein_less_equal</function> is an accelerated version of the
+ Levenshtein function for use when only small distances are of interest.
+ If the actual distance is less than or equal to <literal>max_d</literal>,
+ then <function>levenshtein_less_equal</function> returns the correct
+ distance; otherwise it returns some value greater than <literal>max_d</literal>.
+ If <literal>max_d</literal> is negative then the behavior is the same as
+ <function>levenshtein</function>.
+ </para>
+
+ <para>
+ Examples:
+ </para>
+
+<screen>
+test=# SELECT levenshtein('GUMBO', 'GAMBOL');
+ levenshtein
+-------------
+ 2
+(1 row)
+
+test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
+ levenshtein
+-------------
+ 3
+(1 row)
+
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
+ levenshtein_less_equal
+------------------------
+ 3
+(1 row)
+
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
+ levenshtein_less_equal
+------------------------
+ 4
+(1 row)
+</screen>
+ </sect2>
+
+ <sect2>
+ <title>Metaphone</title>
+
+ <para>
+ Metaphone, like Soundex, is based on the idea of constructing a
+ representative code for an input string. Two strings are then
+ deemed similar if they have the same codes.
+ </para>
+
+ <para>
+ This function calculates the metaphone code of an input string:
+ </para>
+
+ <indexterm>
+ <primary>metaphone</primary>
+ </indexterm>
+
+<synopsis>
+metaphone(text source, int max_output_length) returns text
+</synopsis>
+
+ <para>
+ <literal>source</literal> has to be a non-null string with a maximum of
+ 255 characters. <literal>max_output_length</literal> sets the maximum
+ length of the output metaphone code; if longer, the output is truncated
+ to this length.
+ </para>
+
+ <para>
+ Example:
+ </para>
+
+<screen>
+test=# SELECT metaphone('GUMBO', 4);
+ metaphone
+-----------
+ KM
+(1 row)
+</screen>
+ </sect2>
+
+ <sect2>
+ <title>Double Metaphone</title>
+
+ <para>
+ The Double Metaphone system computes two <quote>sounds like</quote> strings
+ for a given input string &mdash; a <quote>primary</quote> and an
+ <quote>alternate</quote>. In most cases they are the same, but for non-English
+ names especially they can be a bit different, depending on pronunciation.
+ These functions compute the primary and alternate codes:
+ </para>
+
+ <indexterm>
+ <primary>dmetaphone</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>dmetaphone_alt</primary>
+ </indexterm>
+
+<synopsis>
+dmetaphone(text source) returns text
+dmetaphone_alt(text source) returns text
+</synopsis>
+
+ <para>
+ There is no length limit on the input strings.
+ </para>
+
+ <para>
+ Example:
+ </para>
+
+<screen>
+test=# SELECT dmetaphone('gumbo');
+ dmetaphone
+------------
+ KMP
+(1 row)
+</screen>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/generate-errcodes-table.pl b/doc/src/sgml/generate-errcodes-table.pl
new file mode 100644
index 0000000..28637e8
--- /dev/null
+++ b/doc/src/sgml/generate-errcodes-table.pl
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+#
+# Generate the errcodes-table.sgml file from errcodes.txt
+# Copyright (c) 2000-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+
+print
+ "<!-- autogenerated from src/backend/utils/errcodes.txt, do not edit -->\n";
+
+open my $errcodes, '<', $ARGV[0] or die;
+
+while (<$errcodes>)
+{
+ chomp;
+
+ # Skip comments
+ next if /^#/;
+ next if /^\s*$/;
+
+ # Emit section headers
+ if (/^Section:/)
+ {
+
+ # Remove the Section: string
+ s/^Section: //;
+
+ # Escape dashes for SGML
+ s/-/&mdash;/;
+
+ # Wrap PostgreSQL in <productname/>
+ s/PostgreSQL/<productname>PostgreSQL<\/productname>/g;
+
+ print "\n\n";
+ print "<row>\n";
+ print "<entry spanname=\"span12\">";
+ print "<emphasis role=\"bold\">$_</emphasis></entry>\n";
+ print "</row>\n";
+
+ next;
+ }
+
+ die unless /^([^\s]{5})\s+([EWS])\s+([^\s]+)(?:\s+)?([^\s]+)?/;
+
+ (my $sqlstate, my $type, my $errcode_macro, my $condition_name) =
+ ($1, $2, $3, $4);
+
+ # Skip lines without PL/pgSQL condition names
+ next unless defined($condition_name);
+
+ print "\n";
+ print "<row>\n";
+ print "<entry><literal>$sqlstate</literal></entry>\n";
+ print "<entry><symbol>$condition_name</symbol></entry>\n";
+ print "</row>\n";
+}
+
+close $errcodes;
diff --git a/doc/src/sgml/generate-keywords-table.pl b/doc/src/sgml/generate-keywords-table.pl
new file mode 100644
index 0000000..2ed4372
--- /dev/null
+++ b/doc/src/sgml/generate-keywords-table.pl
@@ -0,0 +1,139 @@
+#!/usr/bin/perl
+#
+# Generate the keywords table for the documentation's SQL Key Words appendix
+#
+# Copyright (c) 2019-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+
+my @sql_versions = reverse sort ('1992', '2011', '2016');
+
+my $srcdir = $ARGV[0];
+
+my %keywords;
+my %as_keywords;
+
+# read SQL-spec keywords
+
+foreach my $ver (@sql_versions)
+{
+ foreach my $res ('reserved', 'nonreserved')
+ {
+ foreach my $file (glob "$srcdir/keywords/sql${ver}*-${res}.txt")
+ {
+ open my $fh, '<', $file or die;
+
+ while (<$fh>)
+ {
+ chomp;
+ $keywords{$_}{$ver}{$res} = 1;
+ }
+
+ close $fh;
+ }
+ }
+}
+
+# read PostgreSQL keywords
+
+open my $fh, '<', "$srcdir/../../../src/include/parser/kwlist.h" or die;
+
+while (<$fh>)
+{
+ if (/^PG_KEYWORD\("(\w+)", \w+, (\w+)_KEYWORD\, (\w+)\)/)
+ {
+ $keywords{ uc $1 }{'pg'}{ lc $2 } = 1;
+ $as_keywords{ uc $1 } = 1 if $3 eq 'AS_LABEL';
+ }
+}
+
+close $fh;
+
+# print output
+
+print "<!-- autogenerated, do not edit -->\n";
+
+print <<END;
+<table id="keywords-table">
+ <title><acronym>SQL</acronym> Key Words</title>
+
+ <tgroup cols="5">
+ <colspec colname="col1" colwidth="5*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <colspec colname="col4" colwidth="2*"/>
+ <colspec colname="col5" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Key Word</entry>
+ <entry><productname>PostgreSQL</productname></entry>
+END
+
+foreach my $ver (@sql_versions)
+{
+ my $s = ($ver eq '1992' ? 'SQL-92' : "SQL:$ver");
+ print " <entry>$s</entry>\n";
+}
+
+print <<END;
+ </row>
+ </thead>
+
+ <tbody>
+END
+
+foreach my $word (sort keys %keywords)
+{
+ # Insert zwsp's into very long keywords, so that they can be broken
+ # into multiple lines in PDF format (or narrow HTML windows).
+ my $printword = $word;
+ $printword =~ s/_/_&zwsp;/g if (length($printword) > 20);
+
+ print " <row>\n";
+ print " <entry><token>$printword</token></entry>\n";
+
+ print " <entry>";
+ if ($keywords{$word}{pg}{'unreserved'})
+ {
+ print "non-reserved";
+ }
+ elsif ($keywords{$word}{pg}{'col_name'})
+ {
+ print "non-reserved (cannot be function or type)";
+ }
+ elsif ($keywords{$word}{pg}{'type_func_name'})
+ {
+ print "reserved (can be function or type)";
+ }
+ elsif ($keywords{$word}{pg}{'reserved'})
+ {
+ print "reserved";
+ }
+ if ($as_keywords{$word})
+ {
+ print ", requires <literal>AS</literal>";
+ }
+ print "</entry>\n";
+
+ foreach my $ver (@sql_versions)
+ {
+ print " <entry>";
+ if ($keywords{$word}{$ver}{'reserved'})
+ {
+ print "reserved";
+ }
+ elsif ($keywords{$word}{$ver}{'nonreserved'})
+ {
+ print "non-reserved";
+ }
+ print "</entry>\n";
+ }
+ print " </row>\n";
+}
+
+print <<END;
+ </tbody>
+ </tgroup>
+</table>
+END
diff --git a/doc/src/sgml/generic-wal.sgml b/doc/src/sgml/generic-wal.sgml
new file mode 100644
index 0000000..a028856
--- /dev/null
+++ b/doc/src/sgml/generic-wal.sgml
@@ -0,0 +1,174 @@
+<!-- doc/src/sgml/generic-wal.sgml -->
+
+<chapter id="generic-wal">
+ <title>Generic WAL Records</title>
+
+ <para>
+ Although all built-in WAL-logged modules have their own types of WAL
+ records, there is also a generic WAL record type, which describes changes
+ to pages in a generic way. This is useful for extensions that provide
+ custom access methods.
+ </para>
+
+ <para>
+ In comparison with <link linkend="custom-rmgr">Custom WAL Resource
+ Managers</link>, Generic WAL is simpler for an extension to implement and
+ does not require the extension library to be loaded in order to apply the
+ records.
+ </para>
+
+ <note>
+ <para>
+ Generic WAL records are ignored during <link
+ linkend="logicaldecoding">Logical Decoding</link>. If logical decoding is
+ required for your extension, consider a Custom WAL Resource Manager.
+ </para>
+ </note>
+
+ <para>
+ The API for constructing generic WAL records is defined in
+ <filename>access/generic_xlog.h</filename> and implemented
+ in <filename>access/transam/generic_xlog.c</filename>.
+ </para>
+
+ <para>
+ To perform a WAL-logged data update using the generic WAL record
+ facility, follow these steps:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ <function>state = GenericXLogStart(relation)</function> &mdash; start
+ construction of a generic WAL record for the given relation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>page = GenericXLogRegisterBuffer(state, buffer, flags)</function>
+ &mdash; register a buffer to be modified within the current generic WAL
+ record. This function returns a pointer to a temporary copy of the
+ buffer's page, where modifications should be made. (Do not modify the
+ buffer's contents directly.) The third argument is a bit mask of flags
+ applicable to the operation. Currently the only such flag is
+ <literal>GENERIC_XLOG_FULL_IMAGE</literal>, which indicates that a full-page
+ image rather than a delta update should be included in the WAL record.
+ Typically this flag would be set if the page is new or has been
+ rewritten completely.
+ <function>GenericXLogRegisterBuffer</function> can be repeated if the
+ WAL-logged action needs to modify multiple pages.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Apply modifications to the page images obtained in the previous step.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>GenericXLogFinish(state)</function> &mdash; apply the changes to
+ the buffers and emit the generic WAL record.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ WAL record construction can be canceled between any of the above steps by
+ calling <function>GenericXLogAbort(state)</function>. This will discard all
+ changes to the page image copies.
+ </para>
+
+ <para>
+ Please note the following points when using the generic WAL record
+ facility:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ No direct modifications of buffers are allowed! All modifications must
+ be done in copies acquired from <function>GenericXLogRegisterBuffer()</function>.
+ In other words, code that makes generic WAL records should never call
+ <function>BufferGetPage()</function> for itself. However, it remains the
+ caller's responsibility to pin/unpin and lock/unlock the buffers at
+ appropriate times. Exclusive lock must be held on each target buffer
+ from before <function>GenericXLogRegisterBuffer()</function> until after
+ <function>GenericXLogFinish()</function>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Registrations of buffers (step 2) and modifications of page images
+ (step 3) can be mixed freely, i.e., both steps may be repeated in any
+ sequence. Keep in mind that buffers should be registered in the same
+ order in which locks are to be obtained on them during replay.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The maximum number of buffers that can be registered for a generic WAL
+ record is <literal>MAX_GENERIC_XLOG_PAGES</literal>. An error will be thrown
+ if this limit is exceeded.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Generic WAL assumes that the pages to be modified have standard
+ layout, and in particular that there is no useful data between
+ <structfield>pd_lower</structfield> and <structfield>pd_upper</structfield>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Since you are modifying copies of buffer
+ pages, <function>GenericXLogStart()</function> does not start a critical
+ section. Thus, you can safely do memory allocation, error throwing,
+ etc. between <function>GenericXLogStart()</function> and
+ <function>GenericXLogFinish()</function>. The only actual critical section is
+ present inside <function>GenericXLogFinish()</function>. There is no need to
+ worry about calling <function>GenericXLogAbort()</function> during an error
+ exit, either.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <function>GenericXLogFinish()</function> takes care of marking buffers dirty
+ and setting their LSNs. You do not need to do this explicitly.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For unlogged relations, everything works the same except that no
+ actual WAL record is emitted. Thus, you typically do not need to do
+ any explicit checks for unlogged relations.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The generic WAL redo function will acquire exclusive locks to buffers
+ in the same order as they were registered. After redoing all changes,
+ the locks will be released in the same order.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If <literal>GENERIC_XLOG_FULL_IMAGE</literal> is not specified for a
+ registered buffer, the generic WAL record contains a delta between
+ the old and the new page images. This delta is based on byte-by-byte
+ comparison. This is not very compact for the case of moving data
+ within a page, and might be improved in the future.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+</chapter>
diff --git a/doc/src/sgml/geqo.sgml b/doc/src/sgml/geqo.sgml
new file mode 100644
index 0000000..ac552ef
--- /dev/null
+++ b/doc/src/sgml/geqo.sgml
@@ -0,0 +1,303 @@
+<!-- doc/src/sgml/geqo.sgml -->
+
+ <chapter id="geqo">
+ <title>Genetic Query Optimizer</title>
+
+ <para>
+ <note>
+ <title>Author</title>
+ <para>
+ Written by Martin Utesch (<email>utesch@aut.tu-freiberg.de</email>)
+ for the Institute of Automatic Control at the University of Mining and Technology in Freiberg, Germany.
+ </para>
+ </note>
+ </para>
+
+ <sect1 id="geqo-intro">
+ <title>Query Handling as a Complex Optimization Problem</title>
+
+ <para>
+ Among all relational operators the most difficult one to process
+ and optimize is the <firstterm>join</firstterm>. The number of
+ possible query plans grows exponentially with the
+ number of joins in the query. Further optimization effort is
+ caused by the support of a variety of <firstterm>join
+ methods</firstterm> (e.g., nested loop, hash join, merge join in
+ <productname>PostgreSQL</productname>) to process individual joins
+ and a diversity of <firstterm>indexes</firstterm> (e.g.,
+ B-tree, hash, GiST and GIN in <productname>PostgreSQL</productname>) as
+ access paths for relations.
+ </para>
+
+ <para>
+ The normal <productname>PostgreSQL</productname> query optimizer
+ performs a <firstterm>near-exhaustive search</firstterm> over the
+ space of alternative strategies. This algorithm, first introduced
+ in IBM's System R database, produces a near-optimal join order,
+ but can take an enormous amount of time and memory space when the
+ number of joins in the query grows large. This makes the ordinary
+ <productname>PostgreSQL</productname> query optimizer
+ inappropriate for queries that join a large number of tables.
+ </para>
+
+ <para>
+ The Institute of Automatic Control at the University of Mining and
+ Technology, in Freiberg, Germany, encountered some problems when
+ it wanted to use <productname>PostgreSQL</productname> as the
+ backend for a decision support knowledge based system for the
+ maintenance of an electrical power grid. The DBMS needed to handle
+ large join queries for the inference machine of the knowledge
+ based system. The number of joins in these queries made using the
+ normal query optimizer infeasible.
+ </para>
+
+ <para>
+ In the following we describe the implementation of a
+ <firstterm>genetic algorithm</firstterm> to solve the join
+ ordering problem in a manner that is efficient for queries
+ involving large numbers of joins.
+ </para>
+ </sect1>
+
+ <sect1 id="geqo-intro2">
+ <title>Genetic Algorithms</title>
+
+ <para>
+ The genetic algorithm (<acronym>GA</acronym>) is a heuristic optimization method which
+ operates through randomized search. The set of possible solutions for the
+ optimization problem is considered as a
+ <firstterm>population</firstterm> of <firstterm>individuals</firstterm>.
+ The degree of adaptation of an individual to its environment is specified
+ by its <firstterm>fitness</firstterm>.
+ </para>
+
+ <para>
+ The coordinates of an individual in the search space are represented
+ by <firstterm>chromosomes</firstterm>, in essence a set of character
+ strings. A <firstterm>gene</firstterm> is a
+ subsection of a chromosome which encodes the value of a single parameter
+ being optimized. Typical encodings for a gene could be <firstterm>binary</firstterm> or
+ <firstterm>integer</firstterm>.
+ </para>
+
+ <para>
+ Through simulation of the evolutionary operations <firstterm>recombination</firstterm>,
+ <firstterm>mutation</firstterm>, and
+ <firstterm>selection</firstterm> new generations of search points are found
+ that show a higher average fitness than their ancestors. <xref linkend="geqo-figure"/>
+ illustrates these steps.
+ </para>
+
+ <figure id="geqo-figure">
+ <title>Structure of a Genetic Algorithm</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/genetic-algorithm.svg" format="SVG" width="100%"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+ According to the <systemitem class="resource">comp.ai.genetic</systemitem> <acronym>FAQ</acronym> it cannot be stressed too
+ strongly that a <acronym>GA</acronym> is not a pure random search for a solution to a
+ problem. A <acronym>GA</acronym> uses stochastic processes, but the result is distinctly
+ non-random (better than random).
+ </para>
+
+ </sect1>
+
+ <sect1 id="geqo-pg-intro">
+ <title>Genetic Query Optimization (<acronym>GEQO</acronym>) in PostgreSQL</title>
+
+ <para>
+ The <acronym>GEQO</acronym> module approaches the query
+ optimization problem as though it were the well-known traveling salesman
+ problem (<acronym>TSP</acronym>).
+ Possible query plans are encoded as integer strings. Each string
+ represents the join order from one relation of the query to the next.
+ For example, the join tree
+<literallayout class="monospaced">
+ /\
+ /\ 2
+ /\ 3
+4 1
+</literallayout>
+ is encoded by the integer string '4-1-3-2',
+ which means, first join relation '4' and '1', then '3', and
+ then '2', where 1, 2, 3, 4 are relation IDs within the
+ <productname>PostgreSQL</productname> optimizer.
+ </para>
+
+ <para>
+ Specific characteristics of the <acronym>GEQO</acronym>
+ implementation in <productname>PostgreSQL</productname>
+ are:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ Usage of a <firstterm>steady state</firstterm> <acronym>GA</acronym> (replacement of the least fit
+ individuals in a population, not whole-generational replacement)
+ allows fast convergence towards improved query plans. This is
+ essential for query handling with reasonable time;
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Usage of <firstterm>edge recombination crossover</firstterm>
+ which is especially suited to keep edge losses low for the
+ solution of the <acronym>TSP</acronym> by means of a
+ <acronym>GA</acronym>;
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Mutation as genetic operator is deprecated so that no repair
+ mechanisms are needed to generate legal <acronym>TSP</acronym> tours.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Parts of the <acronym>GEQO</acronym> module are adapted from D. Whitley's
+ Genitor algorithm.
+ </para>
+
+ <para>
+ The <acronym>GEQO</acronym> module allows
+ the <productname>PostgreSQL</productname> query optimizer to
+ support large join queries effectively through
+ non-exhaustive search.
+ </para>
+
+ <sect2>
+ <title>Generating Possible Plans with <acronym>GEQO</acronym></title>
+
+ <para>
+ The <acronym>GEQO</acronym> planning process uses the standard planner
+ code to generate plans for scans of individual relations. Then join
+ plans are developed using the genetic approach. As shown above, each
+ candidate join plan is represented by a sequence in which to join
+ the base relations. In the initial stage, the <acronym>GEQO</acronym>
+ code simply generates some possible join sequences at random. For each
+ join sequence considered, the standard planner code is invoked to
+ estimate the cost of performing the query using that join sequence.
+ (For each step of the join sequence, all three possible join strategies
+ are considered; and all the initially-determined relation scan plans
+ are available. The estimated cost is the cheapest of these
+ possibilities.) Join sequences with lower estimated cost are considered
+ <quote>more fit</quote> than those with higher cost. The genetic algorithm
+ discards the least fit candidates. Then new candidates are generated
+ by combining genes of more-fit candidates &mdash; that is, by using
+ randomly-chosen portions of known low-cost join sequences to create
+ new sequences for consideration. This process is repeated until a
+ preset number of join sequences have been considered; then the best
+ one found at any time during the search is used to generate the finished
+ plan.
+ </para>
+
+ <para>
+ This process is inherently nondeterministic, because of the randomized
+ choices made during both the initial population selection and subsequent
+ <quote>mutation</quote> of the best candidates. To avoid surprising changes
+ of the selected plan, each run of the GEQO algorithm restarts its
+ random number generator with the current <xref linkend="guc-geqo-seed"/>
+ parameter setting. As long as <varname>geqo_seed</varname> and the other
+ GEQO parameters are kept fixed, the same plan will be generated for a
+ given query (and other planner inputs such as statistics). To experiment
+ with different search paths, try changing <varname>geqo_seed</varname>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="geqo-future">
+ <title>Future Implementation Tasks for
+ <productname>PostgreSQL</productname> <acronym>GEQO</acronym></title>
+
+ <para>
+ Work is still needed to improve the genetic algorithm parameter
+ settings.
+ In file <filename>src/backend/optimizer/geqo/geqo_main.c</filename>,
+ routines
+ <function>gimme_pool_size</function> and <function>gimme_number_generations</function>,
+ we have to find a compromise for the parameter settings
+ to satisfy two competing demands:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ Optimality of the query plan
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Computing time
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In the current implementation, the fitness of each candidate join
+ sequence is estimated by running the standard planner's join selection
+ and cost estimation code from scratch. To the extent that different
+ candidates use similar sub-sequences of joins, a great deal of work
+ will be repeated. This could be made significantly faster by retaining
+ cost estimates for sub-joins. The problem is to avoid expending
+ unreasonable amounts of memory on retaining that state.
+ </para>
+
+ <para>
+ At a more basic level, it is not clear that solving query optimization
+ with a GA algorithm designed for TSP is appropriate. In the TSP case,
+ the cost associated with any substring (partial tour) is independent
+ of the rest of the tour, but this is certainly not true for query
+ optimization. Thus it is questionable whether edge recombination
+ crossover is the most effective mutation procedure.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="geqo-biblio">
+ <title>Further Reading</title>
+
+ <para>
+ The following resources contain additional information about
+ genetic algorithms:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://www.faqs.org/faqs/ai-faq/genetic/part1/">
+ The Hitch-Hiker's Guide to Evolutionary Computation</ulink>, (FAQ for <ulink
+ url="news://comp.ai.genetic"></ulink>)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <ulink url="https://www.red3d.com/cwr/evolve.html">
+ Evolutionary Computation and its application to art and design</ulink>, by
+ Craig Reynolds
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="elma04"/>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="fong"/>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/gin.sgml b/doc/src/sgml/gin.sgml
new file mode 100644
index 0000000..d68d12d
--- /dev/null
+++ b/doc/src/sgml/gin.sgml
@@ -0,0 +1,717 @@
+<!-- doc/src/sgml/gin.sgml -->
+
+<chapter id="gin">
+<title>GIN Indexes</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>GIN</secondary>
+ </indexterm>
+
+<sect1 id="gin-intro">
+ <title>Introduction</title>
+
+ <para>
+ <acronym>GIN</acronym> stands for Generalized Inverted Index.
+ <acronym>GIN</acronym> is designed for handling cases where the items
+ to be indexed are composite values, and the queries to be handled by
+ the index need to search for element values that appear within
+ the composite items. For example, the items could be documents,
+ and the queries could be searches for documents containing specific words.
+ </para>
+
+ <para>
+ We use the word <firstterm>item</firstterm> to refer to a composite value that
+ is to be indexed, and the word <firstterm>key</firstterm> to refer to an element
+ value. <acronym>GIN</acronym> always stores and searches for keys,
+ not item values per se.
+ </para>
+
+ <para>
+ A <acronym>GIN</acronym> index stores a set of (key, posting list) pairs,
+ where a <firstterm>posting list</firstterm> is a set of row IDs in which the key
+ occurs. The same row ID can appear in multiple posting lists, since
+ an item can contain more than one key. Each key value is stored only
+ once, so a <acronym>GIN</acronym> index is very compact for cases
+ where the same key appears many times.
+ </para>
+
+ <para>
+ <acronym>GIN</acronym> is generalized in the sense that the
+ <acronym>GIN</acronym> access method code does not need to know the
+ specific operations that it accelerates.
+ Instead, it uses custom strategies defined for particular data types.
+ The strategy defines how keys are extracted from indexed items and
+ query conditions, and how to determine whether a row that contains
+ some of the key values in a query actually satisfies the query.
+ </para>
+
+ <para>
+ One advantage of <acronym>GIN</acronym> is that it allows the development
+ of custom data types with the appropriate access methods, by
+ an expert in the domain of the data type, rather than a database expert.
+ This is much the same advantage as using <acronym>GiST</acronym>.
+ </para>
+
+ <para>
+ The <acronym>GIN</acronym>
+ implementation in <productname>PostgreSQL</productname> is primarily
+ maintained by Teodor Sigaev and Oleg Bartunov. There is more
+ information about <acronym>GIN</acronym> on their
+ <ulink url="http://www.sai.msu.su/~megera/wiki/Gin">website</ulink>.
+ </para>
+</sect1>
+
+<sect1 id="gin-builtin-opclasses">
+ <title>Built-in Operator Classes</title>
+
+ <para>
+ The core <productname>PostgreSQL</productname> distribution
+ includes the <acronym>GIN</acronym> operator classes shown in
+ <xref linkend="gin-builtin-opclasses-table"/>.
+ (Some of the optional modules described in <xref linkend="contrib"/>
+ provide additional <acronym>GIN</acronym> operator classes.)
+ </para>
+
+ <table id="gin-builtin-opclasses-table">
+ <title>Built-in <acronym>GIN</acronym> Operator Classes</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Indexable Operators</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry morerows="3" valign="middle"><literal>array_ops</literal></entry>
+ <entry><literal>&amp;&amp; (anyarray,anyarray)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>@&gt; (anyarray,anyarray)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>&lt;@ (anyarray,anyarray)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>= (anyarray,anyarray)</literal></entry>
+ </row>
+ <row>
+ <entry morerows="5" valign="middle"><literal>jsonb_ops</literal></entry>
+ <entry><literal>@&gt; (jsonb,jsonb)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>@? (jsonb,jsonpath)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>@@ (jsonb,jsonpath)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>? (jsonb,text)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>?| (jsonb,text[])</literal></entry>
+ </row>
+ <row>
+ <entry><literal>?&amp; (jsonb,text[])</literal></entry>
+ </row>
+ <row>
+ <entry morerows="2" valign="middle"><literal>jsonb_path_ops</literal></entry>
+ <entry><literal>@&gt; (jsonb,jsonb)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>@? (jsonb,jsonpath)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>@@ (jsonb,jsonpath)</literal></entry>
+ </row>
+ <row>
+ <entry morerows="1" valign="middle"><literal>tsvector_ops</literal></entry>
+ <entry><literal>@@ (tsvector,tsquery)</literal></entry>
+ </row>
+ <row>
+ <entry><literal>@@@ (tsvector,tsquery)</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Of the two operator classes for type <type>jsonb</type>, <literal>jsonb_ops</literal>
+ is the default. <literal>jsonb_path_ops</literal> supports fewer operators but
+ offers better performance for those operators.
+ See <xref linkend="json-indexing"/> for details.
+ </para>
+
+</sect1>
+
+<sect1 id="gin-extensibility">
+ <title>Extensibility</title>
+
+ <para>
+ The <acronym>GIN</acronym> interface has a high level of abstraction,
+ requiring the access method implementer only to implement the semantics of
+ the data type being accessed. The <acronym>GIN</acronym> layer itself
+ takes care of concurrency, logging and searching the tree structure.
+ </para>
+
+ <para>
+ All it takes to get a <acronym>GIN</acronym> access method working is to
+ implement a few user-defined methods, which define the behavior of
+ keys in the tree and the relationships between keys, indexed items,
+ and indexable queries. In short, <acronym>GIN</acronym> combines
+ extensibility with generality, code reuse, and a clean interface.
+ </para>
+
+ <para>
+ There are two methods that an operator class for
+ <acronym>GIN</acronym> must provide:
+
+ <variablelist>
+ <varlistentry>
+ <term><function>Datum *extractValue(Datum itemValue, int32 *nkeys,
+ bool **nullFlags)</function></term>
+ <listitem>
+ <para>
+ Returns a palloc'd array of keys given an item to be indexed. The
+ number of returned keys must be stored into <literal>*nkeys</literal>.
+ If any of the keys can be null, also palloc an array of
+ <literal>*nkeys</literal> <type>bool</type> fields, store its address at
+ <literal>*nullFlags</literal>, and set these null flags as needed.
+ <literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
+ if all keys are non-null.
+ The return value can be <symbol>NULL</symbol> if the item contains no keys.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>Datum *extractQuery(Datum query, int32 *nkeys,
+ StrategyNumber n, bool **pmatch, Pointer **extra_data,
+ bool **nullFlags, int32 *searchMode)</function></term>
+ <listitem>
+ <para>
+ Returns a palloc'd array of keys given a value to be queried; that is,
+ <literal>query</literal> is the value on the right-hand side of an
+ indexable operator whose left-hand side is the indexed column.
+ <literal>n</literal> is the strategy number of the operator within the
+ operator class (see <xref linkend="xindex-strategies"/>).
+ Often, <function>extractQuery</function> will need
+ to consult <literal>n</literal> to determine the data type of
+ <literal>query</literal> and the method it should use to extract key values.
+ The number of returned keys must be stored into <literal>*nkeys</literal>.
+ If any of the keys can be null, also palloc an array of
+ <literal>*nkeys</literal> <type>bool</type> fields, store its address at
+ <literal>*nullFlags</literal>, and set these null flags as needed.
+ <literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
+ if all keys are non-null.
+ The return value can be <symbol>NULL</symbol> if the <literal>query</literal> contains no keys.
+ </para>
+
+ <para>
+ <literal>searchMode</literal> is an output argument that allows
+ <function>extractQuery</function> to specify details about how the search
+ will be done.
+ If <literal>*searchMode</literal> is set to
+ <literal>GIN_SEARCH_MODE_DEFAULT</literal> (which is the value it is
+ initialized to before call), only items that match at least one of
+ the returned keys are considered candidate matches.
+ If <literal>*searchMode</literal> is set to
+ <literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</literal>, then in addition to items
+ containing at least one matching key, items that contain no keys at
+ all are considered candidate matches. (This mode is useful for
+ implementing is-subset-of operators, for example.)
+ If <literal>*searchMode</literal> is set to <literal>GIN_SEARCH_MODE_ALL</literal>,
+ then all non-null items in the index are considered candidate
+ matches, whether they match any of the returned keys or not. (This
+ mode is much slower than the other two choices, since it requires
+ scanning essentially the entire index, but it may be necessary to
+ implement corner cases correctly. An operator that needs this mode
+ in most cases is probably not a good candidate for a GIN operator
+ class.)
+ The symbols to use for setting this mode are defined in
+ <filename>access/gin.h</filename>.
+ </para>
+
+ <para>
+ <literal>pmatch</literal> is an output argument for use when partial match
+ is supported. To use it, <function>extractQuery</function> must allocate
+ an array of <literal>*nkeys</literal> <type>bool</type>s and store its address at
+ <literal>*pmatch</literal>. Each element of the array should be set to true
+ if the corresponding key requires partial match, false if not.
+ If <literal>*pmatch</literal> is set to <symbol>NULL</symbol> then GIN assumes partial match
+ is not required. The variable is initialized to <symbol>NULL</symbol> before call,
+ so this argument can simply be ignored by operator classes that do
+ not support partial match.
+ </para>
+
+ <para>
+ <literal>extra_data</literal> is an output argument that allows
+ <function>extractQuery</function> to pass additional data to the
+ <function>consistent</function> and <function>comparePartial</function> methods.
+ To use it, <function>extractQuery</function> must allocate
+ an array of <literal>*nkeys</literal> pointers and store its address at
+ <literal>*extra_data</literal>, then store whatever it wants to into the
+ individual pointers. The variable is initialized to <symbol>NULL</symbol> before
+ call, so this argument can simply be ignored by operator classes that
+ do not require extra data. If <literal>*extra_data</literal> is set, the
+ whole array is passed to the <function>consistent</function> method, and
+ the appropriate element to the <function>comparePartial</function> method.
+ </para>
+
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ An operator class must also provide a function to check if an indexed item
+ matches the query. It comes in two flavors, a Boolean <function>consistent</function>
+ function, and a ternary <function>triConsistent</function> function.
+ <function>triConsistent</function> covers the functionality of both, so providing
+ <function>triConsistent</function> alone is sufficient. However, if the Boolean
+ variant is significantly cheaper to calculate, it can be advantageous to
+ provide both. If only the Boolean variant is provided, some optimizations
+ that depend on refuting index items before fetching all the keys are
+ disabled.
+
+ <variablelist>
+ <varlistentry>
+ <term><function>bool consistent(bool check[], StrategyNumber n, Datum query,
+ int32 nkeys, Pointer extra_data[], bool *recheck,
+ Datum queryKeys[], bool nullFlags[])</function></term>
+ <listitem>
+ <para>
+ Returns true if an indexed item satisfies the query operator with
+ strategy number <literal>n</literal> (or might satisfy it, if the recheck
+ indication is returned). This function does not have direct access
+ to the indexed item's value, since <acronym>GIN</acronym> does not
+ store items explicitly. Rather, what is available is knowledge
+ about which key values extracted from the query appear in a given
+ indexed item. The <literal>check</literal> array has length
+ <literal>nkeys</literal>, which is the same as the number of keys previously
+ returned by <function>extractQuery</function> for this <literal>query</literal> datum.
+ Each element of the
+ <literal>check</literal> array is true if the indexed item contains the
+ corresponding query key, i.e., if (check[i] == true) the i-th key of the
+ <function>extractQuery</function> result array is present in the indexed item.
+ The original <literal>query</literal> datum is
+ passed in case the <function>consistent</function> method needs to consult it,
+ and so are the <literal>queryKeys[]</literal> and <literal>nullFlags[]</literal>
+ arrays previously returned by <function>extractQuery</function>.
+ <literal>extra_data</literal> is the extra-data array returned by
+ <function>extractQuery</function>, or <symbol>NULL</symbol> if none.
+ </para>
+
+ <para>
+ When <function>extractQuery</function> returns a null key in
+ <literal>queryKeys[]</literal>, the corresponding <literal>check[]</literal> element
+ is true if the indexed item contains a null key; that is, the
+ semantics of <literal>check[]</literal> are like <literal>IS NOT DISTINCT
+ FROM</literal>. The <function>consistent</function> function can examine the
+ corresponding <literal>nullFlags[]</literal> element if it needs to tell
+ the difference between a regular value match and a null match.
+ </para>
+
+ <para>
+ On success, <literal>*recheck</literal> should be set to true if the heap
+ tuple needs to be rechecked against the query operator, or false if
+ the index test is exact. That is, a false return value guarantees
+ that the heap tuple does not match the query; a true return value with
+ <literal>*recheck</literal> set to false guarantees that the heap tuple does
+ match the query; and a true return value with
+ <literal>*recheck</literal> set to true means that the heap tuple might match
+ the query, so it needs to be fetched and rechecked by evaluating the
+ query operator directly against the originally indexed item.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,
+ int32 nkeys, Pointer extra_data[],
+ Datum queryKeys[], bool nullFlags[])</function></term>
+ <listitem>
+ <para>
+ <function>triConsistent</function> is similar to <function>consistent</function>,
+ but instead of Booleans in the <literal>check</literal> vector, there are
+ three possible values for each
+ key: <literal>GIN_TRUE</literal>, <literal>GIN_FALSE</literal> and
+ <literal>GIN_MAYBE</literal>. <literal>GIN_FALSE</literal> and <literal>GIN_TRUE</literal>
+ have the same meaning as regular Boolean values, while
+ <literal>GIN_MAYBE</literal> means that the presence of that key is not known.
+ When <literal>GIN_MAYBE</literal> values are present, the function should only
+ return <literal>GIN_TRUE</literal> if the item certainly matches whether or
+ not the index item contains the corresponding query keys. Likewise, the
+ function must return <literal>GIN_FALSE</literal> only if the item certainly
+ does not match, whether or not it contains the <literal>GIN_MAYBE</literal>
+ keys. If the result depends on the <literal>GIN_MAYBE</literal> entries, i.e.,
+ the match cannot be confirmed or refuted based on the known query keys,
+ the function must return <literal>GIN_MAYBE</literal>.
+ </para>
+ <para>
+ When there are no <literal>GIN_MAYBE</literal> values in the <literal>check</literal>
+ vector, a <literal>GIN_MAYBE</literal> return value is the equivalent of
+ setting the <literal>recheck</literal> flag in the
+ Boolean <function>consistent</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ In addition, GIN must have a way to sort the key values stored in the index.
+ The operator class can define the sort ordering by specifying a comparison
+ method:
+
+ <variablelist>
+ <varlistentry>
+ <term><function>int compare(Datum a, Datum b)</function></term>
+ <listitem>
+ <para>
+ Compares two keys (not indexed items!) and returns an integer less than
+ zero, zero, or greater than zero, indicating whether the first key is
+ less than, equal to, or greater than the second. Null keys are never
+ passed to this function.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Alternatively, if the operator class does not provide a <function>compare</function>
+ method, GIN will look up the default btree operator class for the index
+ key data type, and use its comparison function. It is recommended to
+ specify the comparison function in a GIN operator class that is meant for
+ just one data type, as looking up the btree operator class costs a few
+ cycles. However, polymorphic GIN operator classes (such
+ as <literal>array_ops</literal>) typically cannot specify a single comparison
+ function.
+ </para>
+
+ <para>
+ An operator class for <acronym>GIN</acronym> can optionally supply the
+ following methods:
+
+ <variablelist>
+ <varlistentry>
+ <term><function>int comparePartial(Datum partial_key, Datum key, StrategyNumber n,
+ Pointer extra_data)</function></term>
+ <listitem>
+ <para>
+ Compare a partial-match query key to an index key. Returns an integer
+ whose sign indicates the result: less than zero means the index key
+ does not match the query, but the index scan should continue; zero
+ means that the index key does match the query; greater than zero
+ indicates that the index scan should stop because no more matches
+ are possible. The strategy number <literal>n</literal> of the operator
+ that generated the partial match query is provided, in case its
+ semantics are needed to determine when to end the scan. Also,
+ <literal>extra_data</literal> is the corresponding element of the extra-data
+ array made by <function>extractQuery</function>, or <symbol>NULL</symbol> if none.
+ Null keys are never passed to this function.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><function>void options(local_relopts *relopts)</function></term>
+ <listitem>
+ <para>
+ Defines a set of user-visible parameters that control operator class
+ behavior.
+ </para>
+
+ <para>
+ The <function>options</function> function is passed a pointer to a
+ <structname>local_relopts</structname> struct, which needs to be
+ filled with a set of operator class specific options. The options
+ can be accessed from other support functions using the
+ <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+
+ <para>
+ Since both key extraction of indexed values and representation of the
+ key in <acronym>GIN</acronym> are flexible, they may depend on
+ user-specified parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ To support <quote>partial match</quote> queries, an operator class must
+ provide the <function>comparePartial</function> method, and its
+ <function>extractQuery</function> method must set the <literal>pmatch</literal>
+ parameter when a partial-match query is encountered. See
+ <xref linkend="gin-partial-match"/> for details.
+ </para>
+
+ <para>
+ The actual data types of the various <literal>Datum</literal> values mentioned
+ above vary depending on the operator class. The item values passed to
+ <function>extractValue</function> are always of the operator class's input type, and
+ all key values must be of the class's <literal>STORAGE</literal> type. The type of
+ the <literal>query</literal> argument passed to <function>extractQuery</function>,
+ <function>consistent</function> and <function>triConsistent</function> is whatever is the
+ right-hand input type of the class member operator identified by the
+ strategy number. This need not be the same as the indexed type, so long as
+ key values of the correct type can be extracted from it. However, it is
+ recommended that the SQL declarations of these three support functions use
+ the opclass's indexed data type for the <literal>query</literal> argument, even
+ though the actual type might be something else depending on the operator.
+ </para>
+
+</sect1>
+
+<sect1 id="gin-implementation">
+ <title>Implementation</title>
+
+ <para>
+ Internally, a <acronym>GIN</acronym> index contains a B-tree index
+ constructed over keys, where each key is an element of one or more indexed
+ items (a member of an array, for example) and where each tuple in a leaf
+ page contains either a pointer to a B-tree of heap pointers (a
+ <quote>posting tree</quote>), or a simple list of heap pointers (a <quote>posting
+ list</quote>) when the list is small enough to fit into a single index tuple along
+ with the key value. <xref linkend="gin-internals-figure"/> illustrates
+ these components of a GIN index.
+ </para>
+
+ <para>
+ As of <productname>PostgreSQL</productname> 9.1, null key values can be
+ included in the index. Also, placeholder nulls are included in the index
+ for indexed items that are null or contain no keys according to
+ <function>extractValue</function>. This allows searches that should find empty
+ items to do so.
+ </para>
+
+ <para>
+ Multicolumn <acronym>GIN</acronym> indexes are implemented by building
+ a single B-tree over composite values (column number, key value). The
+ key values for different columns can be of different types.
+ </para>
+
+ <figure id="gin-internals-figure">
+ <title>GIN Internals</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/gin.svg" format="SVG" width="100%"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <sect2 id="gin-fast-update">
+ <title>GIN Fast Update Technique</title>
+
+ <para>
+ Updating a <acronym>GIN</acronym> index tends to be slow because of the
+ intrinsic nature of inverted indexes: inserting or updating one heap row
+ can cause many inserts into the index (one for each key extracted
+ from the indexed item).
+ <acronym>GIN</acronym> is capable of postponing much of this work by inserting
+ new tuples into a temporary, unsorted list of pending entries.
+ When the table is vacuumed or autoanalyzed, or when
+ <function>gin_clean_pending_list</function> function is called, or if the
+ pending list becomes larger than
+ <xref linkend="guc-gin-pending-list-limit"/>, the entries are moved to the
+ main <acronym>GIN</acronym> data structure using the same bulk insert
+ techniques used during initial index creation. This greatly improves
+ <acronym>GIN</acronym> index update speed, even counting the additional
+ vacuum overhead. Moreover the overhead work can be done by a background
+ process instead of in foreground query processing.
+ </para>
+
+ <para>
+ The main disadvantage of this approach is that searches must scan the list
+ of pending entries in addition to searching the regular index, and so
+ a large list of pending entries will slow searches significantly.
+ Another disadvantage is that, while most updates are fast, an update
+ that causes the pending list to become <quote>too large</quote> will incur an
+ immediate cleanup cycle and thus be much slower than other updates.
+ Proper use of autovacuum can minimize both of these problems.
+ </para>
+
+ <para>
+ If consistent response time is more important than update speed,
+ use of pending entries can be disabled by turning off the
+ <literal>fastupdate</literal> storage parameter for a
+ <acronym>GIN</acronym> index. See <xref linkend="sql-createindex"/>
+ for details.
+ </para>
+ </sect2>
+
+ <sect2 id="gin-partial-match">
+ <title>Partial Match Algorithm</title>
+
+ <para>
+ GIN can support <quote>partial match</quote> queries, in which the query
+ does not determine an exact match for one or more keys, but the possible
+ matches fall within a reasonably narrow range of key values (within the
+ key sorting order determined by the <function>compare</function> support method).
+ The <function>extractQuery</function> method, instead of returning a key value
+ to be matched exactly, returns a key value that is the lower bound of
+ the range to be searched, and sets the <literal>pmatch</literal> flag true.
+ The key range is then scanned using the <function>comparePartial</function>
+ method. <function>comparePartial</function> must return zero for a matching
+ index key, less than zero for a non-match that is still within the range
+ to be searched, or greater than zero if the index key is past the range
+ that could match.
+ </para>
+ </sect2>
+
+</sect1>
+
+<sect1 id="gin-tips">
+<title>GIN Tips and Tricks</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>Create vs. insert</term>
+ <listitem>
+ <para>
+ Insertion into a <acronym>GIN</acronym> index can be slow
+ due to the likelihood of many keys being inserted for each item.
+ So, for bulk insertions into a table it is advisable to drop the GIN
+ index and recreate it after finishing bulk insertion.
+ </para>
+
+ <para>
+ When <literal>fastupdate</literal> is enabled for <acronym>GIN</acronym>
+ (see <xref linkend="gin-fast-update"/> for details), the penalty is
+ less than when it is not. But for very large updates it may still be
+ best to drop and recreate the index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><xref linkend="guc-maintenance-work-mem"/></term>
+ <listitem>
+ <para>
+ Build time for a <acronym>GIN</acronym> index is very sensitive to
+ the <varname>maintenance_work_mem</varname> setting; it doesn't pay to
+ skimp on work memory during index creation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><xref linkend="guc-gin-pending-list-limit"/></term>
+ <listitem>
+ <para>
+ During a series of insertions into an existing <acronym>GIN</acronym>
+ index that has <literal>fastupdate</literal> enabled, the system will clean up
+ the pending-entry list whenever the list grows larger than
+ <varname>gin_pending_list_limit</varname>. To avoid fluctuations in observed
+ response time, it's desirable to have pending-list cleanup occur in the
+ background (i.e., via autovacuum). Foreground cleanup operations
+ can be avoided by increasing <varname>gin_pending_list_limit</varname>
+ or making autovacuum more aggressive.
+ However, enlarging the threshold of the cleanup operation means that
+ if a foreground cleanup does occur, it will take even longer.
+ </para>
+ <para>
+ <varname>gin_pending_list_limit</varname> can be overridden for individual
+ GIN indexes by changing storage parameters, which allows each
+ GIN index to have its own cleanup threshold.
+ For example, it's possible to increase the threshold only for the GIN
+ index which can be updated heavily, and decrease it otherwise.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><xref linkend="guc-gin-fuzzy-search-limit"/></term>
+ <listitem>
+ <para>
+ The primary goal of developing <acronym>GIN</acronym> indexes was
+ to create support for highly scalable full-text search in
+ <productname>PostgreSQL</productname>, and there are often situations when
+ a full-text search returns a very large set of results. Moreover, this
+ often happens when the query contains very frequent words, so that the
+ large result set is not even useful. Since reading many
+ tuples from the disk and sorting them could take a lot of time, this is
+ unacceptable for production. (Note that the index search itself is very
+ fast.)
+ </para>
+ <para>
+ To facilitate controlled execution of such queries,
+ <acronym>GIN</acronym> has a configurable soft upper limit on the
+ number of rows returned: the
+ <varname>gin_fuzzy_search_limit</varname> configuration parameter.
+ It is set to 0 (meaning no limit) by default.
+ If a non-zero limit is set, then the returned set is a subset of
+ the whole result set, chosen at random.
+ </para>
+ <para>
+ <quote>Soft</quote> means that the actual number of returned results
+ could differ somewhat from the specified limit, depending on the query
+ and the quality of the system's random number generator.
+ </para>
+ <para>
+ From experience, values in the thousands (e.g., 5000 &mdash; 20000)
+ work well.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</sect1>
+
+<sect1 id="gin-limit">
+ <title>Limitations</title>
+
+ <para>
+ <acronym>GIN</acronym> assumes that indexable operators are strict. This
+ means that <function>extractValue</function> will not be called at all on a null
+ item value (instead, a placeholder index entry is created automatically),
+ and <function>extractQuery</function> will not be called on a null query
+ value either (instead, the query is presumed to be unsatisfiable). Note
+ however that null key values contained within a non-null composite item
+ or query value are supported.
+ </para>
+</sect1>
+
+<sect1 id="gin-examples">
+ <title>Examples</title>
+
+ <para>
+ The core <productname>PostgreSQL</productname> distribution
+ includes the <acronym>GIN</acronym> operator classes previously shown in
+ <xref linkend="gin-builtin-opclasses-table"/>.
+ The following <filename>contrib</filename> modules also contain
+ <acronym>GIN</acronym> operator classes:
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>btree_gin</filename></term>
+ <listitem>
+ <para>B-tree equivalent functionality for several data types</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>hstore</filename></term>
+ <listitem>
+ <para>Module for storing (key, value) pairs</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>intarray</filename></term>
+ <listitem>
+ <para>Enhanced support for <type>int[]</type></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>pg_trgm</filename></term>
+ <listitem>
+ <para>Text similarity using trigram matching</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml
new file mode 100644
index 0000000..9ac6b03
--- /dev/null
+++ b/doc/src/sgml/gist.sgml
@@ -0,0 +1,1312 @@
+<!-- doc/src/sgml/gist.sgml -->
+
+<chapter id="gist">
+<title>GiST Indexes</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>GiST</secondary>
+ </indexterm>
+
+<sect1 id="gist-intro">
+ <title>Introduction</title>
+
+ <para>
+ <acronym>GiST</acronym> stands for Generalized Search Tree. It is a
+ balanced, tree-structured access method, that acts as a base template in
+ which to implement arbitrary indexing schemes. B-trees, R-trees and many
+ other indexing schemes can be implemented in <acronym>GiST</acronym>.
+ </para>
+
+ <para>
+ One advantage of <acronym>GiST</acronym> is that it allows the development
+ of custom data types with the appropriate access methods, by
+ an expert in the domain of the data type, rather than a database expert.
+ </para>
+
+ <para>
+ Some of the information here is derived from the University of California
+ at Berkeley's GiST Indexing Project
+ <ulink url="http://gist.cs.berkeley.edu/">web site</ulink> and
+ Marcel Kornacker's thesis,
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/papers/concurrency/access-methods-for-next-generation.pdf.gz">
+ Access Methods for Next-Generation Database Systems</ulink>.
+ The <acronym>GiST</acronym>
+ implementation in <productname>PostgreSQL</productname> is primarily
+ maintained by Teodor Sigaev and Oleg Bartunov, and there is more
+ information on their
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/">web site</ulink>.
+ </para>
+
+</sect1>
+
+<sect1 id="gist-builtin-opclasses">
+ <title>Built-in Operator Classes</title>
+
+ <para>
+ The core <productname>PostgreSQL</productname> distribution
+ includes the <acronym>GiST</acronym> operator classes shown in
+ <xref linkend="gist-builtin-opclasses-table"/>.
+ (Some of the optional modules described in <xref linkend="contrib"/>
+ provide additional <acronym>GiST</acronym> operator classes.)
+ </para>
+
+ <table id="gist-builtin-opclasses-table">
+ <title>Built-in <acronym>GiST</acronym> Operator Classes</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Indexable Operators</entry>
+ <entry>Ordering Operators</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="middle" morerows="13"><literal>box_ops</literal></entry>
+ <entry><literal>&lt;&lt; (box, box)</literal></entry>
+ <entry valign="middle" morerows="13"><literal>&lt;-&gt; (box, point)</literal></entry>
+ </row>
+ <row><entry><literal>&amp;&lt; (box, box)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (box, box)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (box, box)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (box, box)</literal></entry></row>
+ <row><entry><literal>~= (box, box)</literal></entry></row>
+ <row><entry><literal>@&gt; (box, box)</literal></entry></row>
+ <row><entry><literal>&lt;@ (box, box)</literal></entry></row>
+ <row><entry><literal>&amp;&lt;| (box, box)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (box, box)</literal></entry></row>
+ <row><entry><literal>|&gt;&gt; (box, box)</literal></entry></row>
+ <row><entry><literal>|&amp;&gt; (box, box)</literal></entry></row>
+ <row><entry><literal>~ (box, box)</literal></entry></row>
+ <row><entry><literal>@ (box, box)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="13"><literal>circle_ops</literal></entry>
+ <entry><literal>&lt;&lt; (circle, circle)</literal></entry>
+ <entry valign="middle" morerows="13"><literal>&lt;-&gt; (circle, point)</literal></entry>
+ </row>
+ <row><entry><literal>&amp;&lt; (circle, circle)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (circle, circle)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (circle, circle)</literal></entry></row>
+ <row><entry><literal>&lt;@ (circle, circle)</literal></entry></row>
+ <row><entry><literal>@&gt; (circle, circle)</literal></entry></row>
+ <row><entry><literal>~= (circle, circle)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (circle, circle)</literal></entry></row>
+ <row><entry><literal>|&gt;&gt; (circle, circle)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (circle, circle)</literal></entry></row>
+ <row><entry><literal>&amp;&lt;| (circle, circle)</literal></entry></row>
+ <row><entry><literal>|&amp;&gt; (circle, circle)</literal></entry></row>
+ <row><entry><literal>@ (circle, circle)</literal></entry></row>
+ <row><entry><literal>~ (circle, circle)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="10"><literal>inet_ops</literal></entry>
+ <entry><literal>&lt;&lt; (inet, inet)</literal></entry>
+ <entry valign="middle" morerows="10"></entry>
+ </row>
+ <row><entry><literal>&lt;&lt;= (inet, inet)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (inet, inet)</literal></entry></row>
+ <row><entry><literal>&gt;&gt;= (inet, inet)</literal></entry></row>
+ <row><entry><literal>= (inet, inet)</literal></entry></row>
+ <row><entry><literal>&lt;&gt; (inet, inet)</literal></entry></row>
+ <row><entry><literal>&lt; (inet, inet)</literal></entry></row>
+ <row><entry><literal>&lt;= (inet, inet)</literal></entry></row>
+ <row><entry><literal>&gt; (inet, inet)</literal></entry></row>
+ <row><entry><literal>&gt;= (inet, inet)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (inet, inet)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="17"><literal>multirange_ops</literal></entry>
+ <entry><literal>= (anymultirange, anymultirange)</literal></entry>
+ <entry valign="middle" morerows="17"></entry>
+ </row>
+ <row><entry><literal>&amp;&amp; (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>@&gt; (anymultirange, anyelement)</literal></entry></row>
+ <row><entry><literal>@&gt; (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>@&gt; (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;@ (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&lt;@ (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;&lt; (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&lt;&lt; (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (anymultirange, anyrange)</literal></entry></row>
+ <row><entry><literal>-|- (anymultirange, anymultirange)</literal></entry></row>
+ <row><entry><literal>-|- (anymultirange, anyrange)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="7"><literal>point_ops</literal></entry>
+ <entry><literal>|&gt;&gt; (point, point)</literal></entry>
+ <entry valign="middle" morerows="7"><literal>&lt;-&gt; (point, point)</literal></entry>
+ </row>
+ <row><entry><literal>&lt;&lt; (point, point)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (point, point)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (point, point)</literal></entry></row>
+ <row><entry><literal>~= (point, point)</literal></entry></row>
+ <row><entry><literal>&lt;@ (point, box)</literal></entry></row>
+ <row><entry><literal>&lt;@ (point, polygon)</literal></entry></row>
+ <row><entry><literal>&lt;@ (point, circle)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="13"><literal>poly_ops</literal></entry>
+ <entry><literal>&lt;&lt; (polygon, polygon)</literal></entry>
+ <entry valign="middle" morerows="13"><literal>&lt;-&gt; (polygon, point)</literal></entry>
+ </row>
+ <row><entry><literal>&amp;&lt; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>&lt;@ (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>@&gt; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>~= (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>&amp;&lt;| (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>|&amp;&gt; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>|&gt;&gt; (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>@ (polygon, polygon)</literal></entry></row>
+ <row><entry><literal>~ (polygon, polygon)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="17"><literal>range_ops</literal></entry>
+ <entry><literal>= (anyrange, anyrange)</literal></entry>
+ <entry valign="middle" morerows="17"></entry>
+ </row>
+ <row><entry><literal>&amp;&amp; (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange, anyelement)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&lt;@ (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;@ (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&lt;&lt; (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;&lt; (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (anyrange, anymultirange)</literal></entry></row>
+ <row><entry><literal>-|- (anyrange, anyrange)</literal></entry></row>
+ <row><entry><literal>-|- (anyrange, anymultirange)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="1"><literal>tsquery_ops</literal></entry>
+ <entry><literal>&lt;@ (tsquery, tsquery)</literal></entry>
+ <entry valign="middle" morerows="1"></entry>
+ </row>
+ <row><entry><literal>@&gt; (tsquery, tsquery)</literal></entry></row>
+ <row>
+ <entry valign="middle"><literal>tsvector_ops</literal></entry>
+ <entry><literal>@@ (tsvector, tsquery)</literal></entry>
+ <entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ For historical reasons, the <literal>inet_ops</literal> operator class is
+ not the default class for types <type>inet</type> and <type>cidr</type>.
+ To use it, mention the class name in <command>CREATE INDEX</command>,
+ for example
+<programlisting>
+CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
+</programlisting>
+ </para>
+
+</sect1>
+
+<sect1 id="gist-extensibility">
+ <title>Extensibility</title>
+
+ <para>
+ Traditionally, implementing a new index access method meant a lot of
+ difficult work. It was necessary to understand the inner workings of the
+ database, such as the lock manager and Write-Ahead Log. The
+ <acronym>GiST</acronym> interface has a high level of abstraction,
+ requiring the access method implementer only to implement the semantics of
+ the data type being accessed. The <acronym>GiST</acronym> layer itself
+ takes care of concurrency, logging and searching the tree structure.
+ </para>
+
+ <para>
+ This extensibility should not be confused with the extensibility of the
+ other standard search trees in terms of the data they can handle. For
+ example, <productname>PostgreSQL</productname> supports extensible B-trees
+ and hash indexes. That means that you can use
+ <productname>PostgreSQL</productname> to build a B-tree or hash over any
+ data type you want. But B-trees only support range predicates
+ (<literal>&lt;</literal>, <literal>=</literal>, <literal>&gt;</literal>),
+ and hash indexes only support equality queries.
+ </para>
+
+ <para>
+ So if you index, say, an image collection with a
+ <productname>PostgreSQL</productname> B-tree, you can only issue queries
+ such as <quote>is imagex equal to imagey</quote>, <quote>is imagex less
+ than imagey</quote> and <quote>is imagex greater than imagey</quote>.
+ Depending on how you define <quote>equals</quote>, <quote>less than</quote>
+ and <quote>greater than</quote> in this context, this could be useful.
+ However, by using a <acronym>GiST</acronym> based index, you could create
+ ways to ask domain-specific questions, perhaps <quote>find all images of
+ horses</quote> or <quote>find all over-exposed images</quote>.
+ </para>
+
+ <para>
+ All it takes to get a <acronym>GiST</acronym> access method up and running
+ is to implement several user-defined methods, which define the behavior of
+ keys in the tree. Of course these methods have to be pretty fancy to
+ support fancy queries, but for all the standard queries (B-trees,
+ R-trees, etc.) they're relatively straightforward. In short,
+ <acronym>GiST</acronym> combines extensibility along with generality, code
+ reuse, and a clean interface.
+ </para>
+
+ <para>
+ There are five methods that an index operator class for
+ <acronym>GiST</acronym> must provide, and six that are optional.
+ Correctness of the index is ensured
+ by proper implementation of the <function>same</function>, <function>consistent</function>
+ and <function>union</function> methods, while efficiency (size and speed) of the
+ index will depend on the <function>penalty</function> and <function>picksplit</function>
+ methods.
+ Two optional methods are <function>compress</function> and
+ <function>decompress</function>, which allow an index to have internal tree data of
+ a different type than the data it indexes. The leaves are to be of the
+ indexed data type, while the other tree nodes can be of any C struct (but
+ you still have to follow <productname>PostgreSQL</productname> data type rules here,
+ see about <literal>varlena</literal> for variable sized data). If the tree's
+ internal data type exists at the SQL level, the <literal>STORAGE</literal> option
+ of the <command>CREATE OPERATOR CLASS</command> command can be used.
+ The optional eighth method is <function>distance</function>, which is needed
+ if the operator class wishes to support ordered scans (nearest-neighbor
+ searches). The optional ninth method <function>fetch</function> is needed if the
+ operator class wishes to support index-only scans, except when the
+ <function>compress</function> method is omitted. The optional tenth method
+ <function>options</function> is needed if the operator class has
+ user-specified parameters.
+ The optional eleventh method <function>sortsupport</function> is used to
+ speed up building a <acronym>GiST</acronym> index.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>consistent</function></term>
+ <listitem>
+ <para>
+ Given an index entry <literal>p</literal> and a query value <literal>q</literal>,
+ this function determines whether the index entry is
+ <quote>consistent</quote> with the query; that is, could the predicate
+ <quote><replaceable>indexed_column</replaceable>
+ <replaceable>indexable_operator</replaceable> <literal>q</literal></quote> be true for
+ any row represented by the index entry? For a leaf index entry this is
+ equivalent to testing the indexable condition, while for an internal
+ tree node this determines whether it is necessary to scan the subtree
+ of the index represented by the tree node. When the result is
+ <literal>true</literal>, a <literal>recheck</literal> flag must also be returned.
+ This indicates whether the predicate is certainly true or only possibly
+ true. If <literal>recheck</literal> = <literal>false</literal> then the index has
+ tested the predicate condition exactly, whereas if <literal>recheck</literal>
+ = <literal>true</literal> the row is only a candidate match. In that case the
+ system will automatically evaluate the
+ <replaceable>indexable_operator</replaceable> against the actual row value to see
+ if it is really a match. This convention allows
+ <acronym>GiST</acronym> to support both lossless and lossy index
+ structures.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_consistent);
+
+Datum
+my_consistent(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ data_type *query = PG_GETARG_DATA_TYPE_P(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+ /* Oid subtype = PG_GETARG_OID(3); */
+ bool *recheck = (bool *) PG_GETARG_POINTER(4);
+ data_type *key = DatumGetDataType(entry-&gt;key);
+ bool retval;
+
+ /*
+ * determine return value as a function of strategy, key and query.
+ *
+ * Use GIST_LEAF(entry) to know where you're called in the index tree,
+ * which comes handy when supporting the = operator for example (you could
+ * check for non empty union() in non-leaf nodes and equality in leaf
+ * nodes).
+ */
+
+ *recheck = true; /* or false if check is exact */
+
+ PG_RETURN_BOOL(retval);
+}
+</programlisting>
+
+ Here, <varname>key</varname> is an element in the index and <varname>query</varname>
+ the value being looked up in the index. The <literal>StrategyNumber</literal>
+ parameter indicates which operator of your operator class is being
+ applied &mdash; it matches one of the operator numbers in the
+ <command>CREATE OPERATOR CLASS</command> command.
+ </para>
+
+ <para>
+ Depending on which operators you have included in the class, the data
+ type of <varname>query</varname> could vary with the operator, since it will
+ be whatever type is on the right-hand side of the operator, which might
+ be different from the indexed data type appearing on the left-hand side.
+ (The above code skeleton assumes that only one type is possible; if
+ not, fetching the <varname>query</varname> argument value would have to depend
+ on the operator.) It is recommended that the SQL declaration of
+ the <function>consistent</function> function use the opclass's indexed data
+ type for the <varname>query</varname> argument, even though the actual type
+ might be something else depending on the operator.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>union</function></term>
+ <listitem>
+ <para>
+ This method consolidates information in the tree. Given a set of
+ entries, this function generates a new index entry that represents
+ all the given entries.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_union(internal, internal)
+RETURNS storage_type
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_union);
+
+Datum
+my_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GISTENTRY *ent = entryvec-&gt;vector;
+ data_type *out,
+ *tmp,
+ *old;
+ int numranges,
+ i = 0;
+
+ numranges = entryvec-&gt;n;
+ tmp = DatumGetDataType(ent[0].key);
+ out = tmp;
+
+ if (numranges == 1)
+ {
+ out = data_type_deep_copy(tmp);
+
+ PG_RETURN_DATA_TYPE_P(out);
+ }
+
+ for (i = 1; i &lt; numranges; i++)
+ {
+ old = out;
+ tmp = DatumGetDataType(ent[i].key);
+ out = my_union_implementation(out, tmp);
+ }
+
+ PG_RETURN_DATA_TYPE_P(out);
+}
+</programlisting>
+ </para>
+
+ <para>
+ As you can see, in this skeleton we're dealing with a data type
+ where <literal>union(X, Y, Z) = union(union(X, Y), Z)</literal>. It's easy
+ enough to support data types where this is not the case, by
+ implementing the proper union algorithm in this
+ <acronym>GiST</acronym> support method.
+ </para>
+
+ <para>
+ The result of the <function>union</function> function must be a value of the
+ index's storage type, whatever that is (it might or might not be
+ different from the indexed column's type). The <function>union</function>
+ function should return a pointer to newly <function>palloc()</function>ed
+ memory. You can't just return the input value as-is, even if there is
+ no type change.
+ </para>
+
+ <para>
+ As shown above, the <function>union</function> function's
+ first <type>internal</type> argument is actually
+ a <structname>GistEntryVector</structname> pointer. The second argument is a
+ pointer to an integer variable, which can be ignored. (It used to be
+ required that the <function>union</function> function store the size of its
+ result value into that variable, but this is no longer necessary.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>compress</function></term>
+ <listitem>
+ <para>
+ Converts a data item into a format suitable for physical storage in
+ an index page.
+ If the <function>compress</function> method is omitted, data items are stored
+ in the index without modification.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_compress);
+
+Datum
+my_compress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *retval;
+
+ if (entry-&gt;leafkey)
+ {
+ /* replace entry-&gt;key with a compressed version */
+ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type));
+
+ /* fill *compressed_data from entry-&gt;key ... */
+
+ retval = palloc(sizeof(GISTENTRY));
+ gistentryinit(*retval, PointerGetDatum(compressed_data),
+ entry-&gt;rel, entry-&gt;page, entry-&gt;offset, FALSE);
+ }
+ else
+ {
+ /* typically we needn't do anything with non-leaf entries */
+ retval = entry;
+ }
+
+ PG_RETURN_POINTER(retval);
+}
+</programlisting>
+ </para>
+
+ <para>
+ You have to adapt <replaceable>compressed_data_type</replaceable> to the specific
+ type you're converting to in order to compress your leaf nodes, of
+ course.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>decompress</function></term>
+ <listitem>
+ <para>
+ Converts the stored representation of a data item into a format that
+ can be manipulated by the other GiST methods in the operator class.
+ If the <function>decompress</function> method is omitted, it is assumed that
+ the other GiST methods can work directly on the stored data format.
+ (<function>decompress</function> is not necessarily the reverse of
+ the <function>compress</function> method; in particular,
+ if <function>compress</function> is lossy then it's impossible
+ for <function>decompress</function> to exactly reconstruct the original
+ data. <function>decompress</function> is not necessarily equivalent
+ to <function>fetch</function>, either, since the other GiST methods might not
+ require full reconstruction of the data.)
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_decompress);
+
+Datum
+my_decompress(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+</programlisting>
+
+ The above skeleton is suitable for the case where no decompression
+ is needed. (But, of course, omitting the method altogether is even
+ easier, and is recommended in such cases.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>penalty</function></term>
+ <listitem>
+ <para>
+ Returns a value indicating the <quote>cost</quote> of inserting the new
+ entry into a particular branch of the tree. Items will be inserted
+ down the path of least <function>penalty</function> in the tree.
+ Values returned by <function>penalty</function> should be non-negative.
+ If a negative value is returned, it will be treated as zero.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT; -- in some cases penalty functions need not be strict
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_penalty);
+
+Datum
+my_penalty(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+ float *penalty = (float *) PG_GETARG_POINTER(2);
+ data_type *orig = DatumGetDataType(origentry-&gt;key);
+ data_type *new = DatumGetDataType(newentry-&gt;key);
+
+ *penalty = my_penalty_implementation(orig, new);
+ PG_RETURN_POINTER(penalty);
+}
+</programlisting>
+
+ For historical reasons, the <function>penalty</function> function doesn't
+ just return a <type>float</type> result; instead it has to store the value
+ at the location indicated by the third argument. The return
+ value per se is ignored, though it's conventional to pass back the
+ address of that argument.
+ </para>
+
+ <para>
+ The <function>penalty</function> function is crucial to good performance of
+ the index. It'll get used at insertion time to determine which branch
+ to follow when choosing where to add the new entry in the tree. At
+ query time, the more balanced the index, the quicker the lookup.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>picksplit</function></term>
+ <listitem>
+ <para>
+ When an index page split is necessary, this function decides which
+ entries on the page are to stay on the old page, and which are to move
+ to the new page.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_picksplit);
+
+Datum
+my_picksplit(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+ OffsetNumber maxoff = entryvec-&gt;n - 1;
+ GISTENTRY *ent = entryvec-&gt;vector;
+ int i,
+ nbytes;
+ OffsetNumber *left,
+ *right;
+ data_type *tmp_union;
+ data_type *unionL;
+ data_type *unionR;
+ GISTENTRY **raw_entryvec;
+
+ maxoff = entryvec-&gt;n - 1;
+ nbytes = (maxoff + 1) * sizeof(OffsetNumber);
+
+ v-&gt;spl_left = (OffsetNumber *) palloc(nbytes);
+ left = v-&gt;spl_left;
+ v-&gt;spl_nleft = 0;
+
+ v-&gt;spl_right = (OffsetNumber *) palloc(nbytes);
+ right = v-&gt;spl_right;
+ v-&gt;spl_nright = 0;
+
+ unionL = NULL;
+ unionR = NULL;
+
+ /* Initialize the raw entry vector. */
+ raw_entryvec = (GISTENTRY **) malloc(entryvec-&gt;n * sizeof(void *));
+ for (i = FirstOffsetNumber; i &lt;= maxoff; i = OffsetNumberNext(i))
+ raw_entryvec[i] = &amp;(entryvec-&gt;vector[i]);
+
+ for (i = FirstOffsetNumber; i &lt;= maxoff; i = OffsetNumberNext(i))
+ {
+ int real_index = raw_entryvec[i] - entryvec-&gt;vector;
+
+ tmp_union = DatumGetDataType(entryvec-&gt;vector[real_index].key);
+ Assert(tmp_union != NULL);
+
+ /*
+ * Choose where to put the index entries and update unionL and unionR
+ * accordingly. Append the entries to either v-&gt;spl_left or
+ * v-&gt;spl_right, and care about the counters.
+ */
+
+ if (my_choice_is_left(unionL, curl, unionR, curr))
+ {
+ if (unionL == NULL)
+ unionL = tmp_union;
+ else
+ unionL = my_union_implementation(unionL, tmp_union);
+
+ *left = real_index;
+ ++left;
+ ++(v-&gt;spl_nleft);
+ }
+ else
+ {
+ /*
+ * Same on the right
+ */
+ }
+ }
+
+ v-&gt;spl_ldatum = DataTypeGetDatum(unionL);
+ v-&gt;spl_rdatum = DataTypeGetDatum(unionR);
+ PG_RETURN_POINTER(v);
+}
+</programlisting>
+
+ Notice that the <function>picksplit</function> function's result is delivered
+ by modifying the passed-in <structname>v</structname> structure. The return
+ value per se is ignored, though it's conventional to pass back the
+ address of <structname>v</structname>.
+ </para>
+
+ <para>
+ Like <function>penalty</function>, the <function>picksplit</function> function
+ is crucial to good performance of the index. Designing suitable
+ <function>penalty</function> and <function>picksplit</function> implementations
+ is where the challenge of implementing well-performing
+ <acronym>GiST</acronym> indexes lies.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>same</function></term>
+ <listitem>
+ <para>
+ Returns true if two index entries are identical, false otherwise.
+ (An <quote>index entry</quote> is a value of the index's storage type,
+ not necessarily the original indexed column's type.)
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_same);
+
+Datum
+my_same(PG_FUNCTION_ARGS)
+{
+ prefix_range *v1 = PG_GETARG_PREFIX_RANGE_P(0);
+ prefix_range *v2 = PG_GETARG_PREFIX_RANGE_P(1);
+ bool *result = (bool *) PG_GETARG_POINTER(2);
+
+ *result = my_eq(v1, v2);
+ PG_RETURN_POINTER(result);
+}
+</programlisting>
+
+ For historical reasons, the <function>same</function> function doesn't
+ just return a Boolean result; instead it has to store the flag
+ at the location indicated by the third argument. The return
+ value per se is ignored, though it's conventional to pass back the
+ address of that argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>distance</function></term>
+ <listitem>
+ <para>
+ Given an index entry <literal>p</literal> and a query value <literal>q</literal>,
+ this function determines the index entry's
+ <quote>distance</quote> from the query value. This function must be
+ supplied if the operator class contains any ordering operators.
+ A query using the ordering operator will be implemented by returning
+ index entries with the smallest <quote>distance</quote> values first,
+ so the results must be consistent with the operator's semantics.
+ For a leaf index entry the result just represents the distance to
+ the index entry; for an internal tree node, the result must be the
+ smallest distance that any child entry could have.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ And the matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_distance);
+
+Datum
+my_distance(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ data_type *query = PG_GETARG_DATA_TYPE_P(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+ /* Oid subtype = PG_GETARG_OID(3); */
+ /* bool *recheck = (bool *) PG_GETARG_POINTER(4); */
+ data_type *key = DatumGetDataType(entry-&gt;key);
+ double retval;
+
+ /*
+ * determine return value as a function of strategy, key and query.
+ */
+
+ PG_RETURN_FLOAT8(retval);
+}
+</programlisting>
+
+ The arguments to the <function>distance</function> function are identical to
+ the arguments of the <function>consistent</function> function.
+ </para>
+
+ <para>
+ Some approximation is allowed when determining the distance, so long
+ as the result is never greater than the entry's actual distance. Thus,
+ for example, distance to a bounding box is usually sufficient in
+ geometric applications. For an internal tree node, the distance
+ returned must not be greater than the distance to any of the child
+ nodes. If the returned distance is not exact, the function must set
+ <literal>*recheck</literal> to true. (This is not necessary for internal tree
+ nodes; for them, the calculation is always assumed to be inexact.) In
+ this case the executor will calculate the accurate distance after
+ fetching the tuple from the heap, and reorder the tuples if necessary.
+ </para>
+
+ <para>
+ If the distance function returns <literal>*recheck = true</literal> for any
+ leaf node, the original ordering operator's return type must
+ be <type>float8</type> or <type>float4</type>, and the distance function's
+ result values must be comparable to those of the original ordering
+ operator, since the executor will sort using both distance function
+ results and recalculated ordering-operator results. Otherwise, the
+ distance function's result values can be any finite <type>float8</type>
+ values, so long as the relative order of the result values matches the
+ order returned by the ordering operator. (Infinity and minus infinity
+ are used internally to handle cases such as nulls, so it is not
+ recommended that <function>distance</function> functions return these values.)
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>fetch</function></term>
+ <listitem>
+ <para>
+ Converts the compressed index representation of a data item into the
+ original data type, for index-only scans. The returned data must be an
+ exact, non-lossy copy of the originally indexed value.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ The argument is a pointer to a <structname>GISTENTRY</structname> struct. On
+ entry, its <structfield>key</structfield> field contains a non-NULL leaf datum in
+ compressed form. The return value is another <structname>GISTENTRY</structname>
+ struct, whose <structfield>key</structfield> field contains the same datum in its
+ original, uncompressed form. If the opclass's compress function does
+ nothing for leaf entries, the <function>fetch</function> method can return the
+ argument as-is. Or, if the opclass does not have a compress function,
+ the <function>fetch</function> method can be omitted as well, since it would
+ necessarily be a no-op.
+ </para>
+
+ <para>
+ The matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_fetch);
+
+Datum
+my_fetch(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ input_data_type *in = DatumGetPointer(entry->key);
+ fetched_data_type *fetched_data;
+ GISTENTRY *retval;
+
+ retval = palloc(sizeof(GISTENTRY));
+ fetched_data = palloc(sizeof(fetched_data_type));
+
+ /*
+ * Convert 'fetched_data' into the a Datum of the original datatype.
+ */
+
+ /* fill *retval from fetched_data. */
+ gistentryinit(*retval, PointerGetDatum(converted_datum),
+ entry->rel, entry->page, entry->offset, FALSE);
+
+ PG_RETURN_POINTER(retval);
+}
+</programlisting>
+ </para>
+
+ <para>
+ If the compress method is lossy for leaf entries, the operator class
+ cannot support index-only scans, and must not define
+ a <function>fetch</function> function.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>options</function></term>
+ <listitem>
+ <para>
+ Allows definition of user-visible parameters that control operator
+ class behavior.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_options(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ The function is passed a pointer to a <structname>local_relopts</structname>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using the <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+
+ <para>
+ An example implementation of my_options() and parameters use
+ from other support functions are given below:
+
+<programlisting>
+typedef enum MyEnumType
+{
+ MY_ENUM_ON,
+ MY_ENUM_OFF,
+ MY_ENUM_AUTO
+} MyEnumType;
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */
+ int int_param; /* integer parameter */
+ double real_param; /* real parameter */
+ MyEnumType enum_param; /* enum parameter */
+ int str_param; /* string parameter */
+} MyOptionsStruct;
+
+/* String representation of enum values */
+static relopt_enum_elt_def myEnumValues[] =
+{
+ {"on", MY_ENUM_ON},
+ {"off", MY_ENUM_OFF},
+ {"auto", MY_ENUM_AUTO},
+ {(const char *) NULL} /* list terminator */
+};
+
+static char *str_param_default = "default";
+
+/*
+ * Sample validator: checks that string is not longer than 8 bytes.
+ */
+static void
+validate_my_string_relopt(const char *value)
+{
+ if (strlen(value) > 8)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("str_param must be at most 8 bytes")));
+}
+
+/*
+ * Sample filler: switches characters to lower case.
+ */
+static Size
+fill_my_string_relopt(const char *value, void *ptr)
+{
+ char *tmp = str_tolower(value, strlen(value), DEFAULT_COLLATION_OID);
+ int len = strlen(tmp);
+
+ if (ptr)
+ strcpy((char *) ptr, tmp);
+
+ pfree(tmp);
+ return len + 1;
+}
+
+PG_FUNCTION_INFO_V1(my_options);
+
+Datum
+my_options(PG_FUNCTION_ARGS)
+{
+ local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
+
+ init_local_reloptions(relopts, sizeof(MyOptionsStruct));
+ add_local_int_reloption(relopts, "int_param", "integer parameter",
+ 100, 0, 1000000,
+ offsetof(MyOptionsStruct, int_param));
+ add_local_real_reloption(relopts, "real_param", "real parameter",
+ 1.0, 0.0, 1000000.0,
+ offsetof(MyOptionsStruct, real_param));
+ add_local_enum_reloption(relopts, "enum_param", "enum parameter",
+ myEnumValues, MY_ENUM_ON,
+ "Valid values are: \"on\", \"off\" and \"auto\".",
+ offsetof(MyOptionsStruct, enum_param));
+ add_local_string_reloption(relopts, "str_param", "string parameter",
+ str_param_default,
+ &amp;validate_my_string_relopt,
+ &amp;fill_my_string_relopt,
+ offsetof(MyOptionsStruct, str_param));
+
+ PG_RETURN_VOID();
+}
+
+PG_FUNCTION_INFO_V1(my_compress);
+
+Datum
+my_compress(PG_FUNCTION_ARGS)
+{
+ int int_param = 100;
+ double real_param = 1.0;
+ MyEnumType enum_param = MY_ENUM_ON;
+ char *str_param = str_param_default;
+
+ /*
+ * Normally, when opclass contains 'options' method, then options are always
+ * passed to support functions. However, if you add 'options' method to
+ * existing opclass, previously defined indexes have no options, so the
+ * check is required.
+ */
+ if (PG_HAS_OPCLASS_OPTIONS())
+ {
+ MyOptionsStruct *options = (MyOptionsStruct *) PG_GET_OPCLASS_OPTIONS();
+
+ int_param = options->int_param;
+ real_param = options->real_param;
+ enum_param = options->enum_param;
+ str_param = GET_STRING_RELOPTION(options, str_param);
+ }
+
+ /* the rest implementation of support function */
+}
+
+</programlisting>
+ </para>
+
+ <para>
+ Since the representation of the key in <acronym>GiST</acronym> is
+ flexible, it may depend on user-specified parameters. For instance,
+ the length of key signature may be specified. See
+ <literal>gtsvector_options()</literal> for example.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>sortsupport</function></term>
+ <listitem>
+ <para>
+ Returns a comparator function to sort data in a way that preserves
+ locality. It is used by <command>CREATE INDEX</command> and
+ <command>REINDEX</command> commands. The quality of the created index
+ depends on how well the sort order determined by the comparator function
+ preserves locality of the inputs.
+ </para>
+ <para>
+ The <function>sortsupport</function> method is optional. If it is not
+ provided, <command>CREATE INDEX</command> builds the index by inserting
+ each tuple to the tree using the <function>penalty</function> and
+ <function>picksplit</function> functions, which is much slower.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like
+ this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_sortsupport(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+
+ The argument is a pointer to a <structname>SortSupport</structname>
+ struct. At a minimum, the function must fill in its comparator field.
+ The comparator takes three arguments: two Datums to compare, and
+ a pointer to the <structname>SortSupport</structname> struct. The
+ Datums are the two indexed values in the format that they are stored
+ in the index; that is, in the format returned by the
+ <function>compress</function> method. The full API is defined in
+ <filename>src/include/utils/sortsupport.h</filename>.
+ </para>
+
+ <para>
+ The matching code in the C module could then follow this skeleton:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(my_sortsupport);
+
+static int
+my_fastcmp(Datum x, Datum y, SortSupport ssup)
+{
+ /* establish order between x and y by computing some sorting value z */
+
+ int z1 = ComputeSpatialCode(x);
+ int z2 = ComputeSpatialCode(y);
+
+ return z1 == z2 ? 0 : z1 > z2 ? 1 : -1;
+}
+
+Datum
+my_sortsupport(PG_FUNCTION_ARGS)
+{
+ SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
+
+ ssup->comparator = my_fastcmp;
+ PG_RETURN_VOID();
+}
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ All the GiST support methods are normally called in short-lived memory
+ contexts; that is, <varname>CurrentMemoryContext</varname> will get reset after
+ each tuple is processed. It is therefore not very important to worry about
+ pfree'ing everything you palloc. However, in some cases it's useful for a
+ support method to cache data across repeated calls. To do that, allocate
+ the longer-lived data in <literal>fcinfo-&gt;flinfo-&gt;fn_mcxt</literal>, and
+ keep a pointer to it in <literal>fcinfo-&gt;flinfo-&gt;fn_extra</literal>. Such
+ data will survive for the life of the index operation (e.g., a single GiST
+ index scan, index build, or index tuple insertion). Be careful to pfree
+ the previous value when replacing a <literal>fn_extra</literal> value, or the leak
+ will accumulate for the duration of the operation.
+ </para>
+
+</sect1>
+
+<sect1 id="gist-implementation">
+ <title>Implementation</title>
+
+ <sect2 id="gist-buffering-build">
+ <title>GiST Index Build Methods</title>
+
+ <para>
+ The simplest way to build a GiST index is just to insert all the entries,
+ one by one. This tends to be slow for large indexes, because if the
+ index tuples are scattered across the index and the index is large enough
+ to not fit in cache, a lot of random I/O will be
+ needed. <productname>PostgreSQL</productname> supports two alternative
+ methods for initial build of a GiST index: <firstterm>sorted</firstterm>
+ and <firstterm>buffered</firstterm> modes.
+ </para>
+
+ <para>
+ The sorted method is only available if each of the opclasses used by the
+ index provides a <function>sortsupport</function> function, as described
+ in <xref linkend="gist-extensibility"/>. If they do, this method is
+ usually the best, so it is used by default.
+ </para>
+
+ <para>
+ The buffered method works by not inserting tuples directly into the index
+ right away. It can dramatically reduce the amount of random I/O needed
+ for non-ordered data sets. For well-ordered data sets the benefit is
+ smaller or non-existent, because only a small number of pages receive new
+ tuples at a time, and those pages fit in cache even if the index as a
+ whole does not.
+ </para>
+
+ <para>
+ The buffered method needs to call the <function>penalty</function>
+ function more often than the simple method does, which consumes some
+ extra CPU resources. Also, the buffers need temporary disk space, up to
+ the size of the resulting index. Buffering can also influence the quality
+ of the resulting index, in both positive and negative directions. That
+ influence depends on various factors, like the distribution of the input
+ data and the operator class implementation.
+ </para>
+
+ <para>
+ If sorting is not possible, then by default a GiST index build switches
+ to the buffering method when the index size reaches
+ <xref linkend="guc-effective-cache-size"/>. Buffering can be manually
+ forced or prevented by the <literal>buffering</literal> parameter to the
+ CREATE INDEX command. The default behavior is good for most cases, but
+ turning buffering off might speed up the build somewhat if the input data
+ is ordered.
+ </para>
+
+ </sect2>
+</sect1>
+
+<sect1 id="gist-examples">
+ <title>Examples</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> source distribution includes
+ several examples of index methods implemented using
+ <acronym>GiST</acronym>. The core system currently provides text search
+ support (indexing for <type>tsvector</type> and <type>tsquery</type>) as well as
+ R-Tree equivalent functionality for some of the built-in geometric data types
+ (see <filename>src/backend/access/gist/gistproc.c</filename>). The following
+ <filename>contrib</filename> modules also contain <acronym>GiST</acronym>
+ operator classes:
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>btree_gist</filename></term>
+ <listitem>
+ <para>B-tree equivalent functionality for several data types</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>cube</filename></term>
+ <listitem>
+ <para>Indexing for multidimensional cubes</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>hstore</filename></term>
+ <listitem>
+ <para>Module for storing (key, value) pairs</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>intarray</filename></term>
+ <listitem>
+ <para>RD-Tree for one-dimensional array of int4 values</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>ltree</filename></term>
+ <listitem>
+ <para>Indexing for tree-like structures</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>pg_trgm</filename></term>
+ <listitem>
+ <para>Text similarity using trigram matching</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>seg</filename></term>
+ <listitem>
+ <para>Indexing for <quote>float ranges</quote></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/glossary.sgml b/doc/src/sgml/glossary.sgml
new file mode 100644
index 0000000..d6d0a3a
--- /dev/null
+++ b/doc/src/sgml/glossary.sgml
@@ -0,0 +1,2063 @@
+<appendix id="glossary">
+ <title>Glossary</title>
+ <para>
+ This is a list of terms and their meaning in the context of
+ <productname>PostgreSQL</productname> and relational database
+ systems in general.
+ </para>
+
+ <glosslist>
+ <glossentry id="glossary-acid">
+ <glossterm>ACID</glossterm>
+ <glossdef>
+ <para>
+ <glossterm linkend="glossary-atomicity">Atomicity</glossterm>,
+ <glossterm linkend="glossary-consistency">Consistency</glossterm>,
+ <glossterm linkend="glossary-isolation">Isolation</glossterm>, and
+ <glossterm linkend="glossary-durability">Durability</glossterm>.
+ This set of properties of database transactions is intended to
+ guarantee validity in concurrent operation and even in event of
+ errors, power failures, etc.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-aggregate">
+ <glossterm>Aggregate function (routine)</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-function">function</glossterm> that
+ combines (<firstterm>aggregates</firstterm>) multiple input values,
+ for example by counting, averaging or adding,
+ yielding a single output value.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="functions-aggregate"/>.
+ </para>
+ <glossseealso otherterm="glossary-window-function" />
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Analytic function</glossterm>
+ <glosssee otherterm="glossary-window-function" />
+ </glossentry>
+
+ <glossentry id="glossary-analyze">
+ <glossterm>Analyze (operation)</glossterm>
+ <glossdef>
+ <para>
+ The act of collecting statistics from data in
+ <glossterm linkend="glossary-table">tables</glossterm>
+ and other <glossterm linkend="glossary-relation">relations</glossterm>
+ to help the <glossterm linkend="glossary-planner">query planner</glossterm>
+ to make decisions about how to execute
+ <glossterm linkend="glossary-query">queries</glossterm>.
+ </para>
+ <para>
+ (Don't confuse this term with the <literal>ANALYZE</literal> option
+ to the <xref linkend="sql-explain"/> command.)
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-analyze"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-atomic">
+ <glossterm>Atomic</glossterm>
+ <glossdef>
+ <para>
+ In reference to a <glossterm linkend="glossary-datum">datum</glossterm>:
+ the fact that its value cannot be broken down into smaller
+ components.
+ </para>
+ </glossdef>
+ <glossdef>
+ <para>
+ In reference to a
+ <glossterm linkend="glossary-transaction">database transaction</glossterm>:
+ see <glossterm linkend="glossary-atomicity">atomicity</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-atomicity">
+ <glossterm>Atomicity</glossterm>
+ <glossdef>
+ <para>
+ The property of a <glossterm linkend="glossary-transaction">transaction</glossterm>
+ that either all its operations complete as a single unit or none do.
+ In addition, if a system failure occurs during the execution of a
+ transaction, no partial results are visible after recovery.
+ This is one of the <acronym>ACID</acronym> properties.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-attribute">
+ <glossterm>Attribute</glossterm>
+ <glossdef>
+ <para>
+ An element with a certain name and data type found within a
+ <glossterm linkend="glossary-tuple">tuple</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-autovacuum">
+ <glossterm>Autovacuum (process)</glossterm>
+ <glossdef>
+ <para>
+ A set of background processes that routinely perform
+ <glossterm linkend="glossary-vacuum">vacuum</glossterm>
+ and <glossterm linkend="glossary-analyze">analyze</glossterm> operations.
+ The <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ that coordinates the work and is always present (unless autovacuum
+ is disabled) is known as the <firstterm>autovacuum launcher</firstterm>,
+ and the processes that carry out the tasks are known as the
+ <firstterm>autovacuum workers</firstterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="autovacuum"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-auxiliary-proc">
+ <glossterm>Auxiliary process</glossterm>
+ <glossdef>
+ <para>
+ A process within an <glossterm linkend="glossary-instance">instance</glossterm>
+ that is in charge of some specific background task for the instance.
+ The auxiliary processes consist of <!-- in alphabetical order -->
+ <!-- NB: In the code, the autovac launcher doesn't use the auxiliary
+ process scaffolding; however it does behave as one so we list it
+ here anyway. In addition, logger isn't connected to shared memory so
+ most code outside postmaster.c doesn't even consider it a "proc" in
+ the first place.
+ -->
+ the <glossterm linkend="glossary-autovacuum">autovacuum launcher</glossterm>
+ (but not the autovacuum workers),
+ the <glossterm linkend="glossary-background-writer">background writer</glossterm>,
+ the <glossterm linkend="glossary-checkpointer">checkpointer</glossterm>,
+ the <glossterm linkend="glossary-logger">logger</glossterm>,
+ the <glossterm linkend="glossary-startup-process">startup process</glossterm>,
+ the <glossterm linkend="glossary-wal-archiver">WAL archiver</glossterm>,
+ the <glossterm linkend="glossary-wal-receiver">WAL receiver</glossterm>
+ (but not the <glossterm linkend="glossary-wal-sender">WAL senders</glossterm>),
+ and the <glossterm linkend="glossary-wal-writer">WAL writer</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-backend">
+ <glossterm>Backend (process)</glossterm>
+ <glossdef>
+ <para>
+ Process of an <glossterm linkend="glossary-instance">instance</glossterm>
+ which acts on behalf of a <glossterm linkend="glossary-session">client session</glossterm>
+ and handles its requests.
+ </para>
+ <para>
+ (Don't confuse this term with the similar terms
+ <glossterm linkend="glossary-background-worker">Background Worker</glossterm> or
+ <glossterm linkend="glossary-background-writer">Background Writer</glossterm>).
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-background-worker">
+ <glossterm>Background worker (process)</glossterm>
+ <glossdef>
+ <para>
+ Process within an <glossterm linkend="glossary-instance">instance</glossterm>,
+ which runs system- or user-supplied code.
+ Serves as infrastructure for several features in
+ <productname>PostgreSQL</productname>, such as
+ <glossterm linkend="glossary-replication">logical replication</glossterm>
+ and <glossterm linkend="glossary-parallel-query">parallel queries</glossterm>.
+ In addition, <glossterm linkend="glossary-extension">Extensions</glossterm> can add
+ custom background worker processes.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="bgworker"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-background-writer">
+ <glossterm>Background writer (process)</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ that writes dirty
+ <glossterm linkend="glossary-data-page">data pages</glossterm> from
+ <glossterm linkend="glossary-shared-memory">shared memory</glossterm> to
+ the file system. It wakes up periodically, but works only for a short
+ period in order to distribute its expensive <acronym>I/O</acronym>
+ activity over time to avoid generating larger
+ <acronym>I/O</acronym> peaks which could block other processes.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="runtime-config-resource-background-writer"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-basebackup">
+ <glossterm>Base Backup</glossterm>
+ <glossdef>
+ <para>
+ A binary copy of all
+ <glossterm linkend="glossary-db-cluster">database cluster</glossterm>
+ files. It is generated by the tool <xref linkend="app-pgbasebackup"/>.
+ In combination with WAL files it can be used as the starting point
+ for recovery, log shipping, or streaming replication.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-bloat">
+ <glossterm>Bloat</glossterm>
+ <glossdef>
+ <para>
+ Space in data pages which does not contain current row versions,
+ such as unused (free) space or outdated row versions.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-cast">
+ <glossterm>Cast</glossterm>
+ <glossdef>
+ <para>
+ A conversion of a <glossterm linkend="glossary-datum">datum</glossterm>
+ from its current data type to another data type.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createcast"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-catalog">
+ <glossterm>Catalog</glossterm>
+ <glossdef>
+ <para>
+ The <acronym>SQL</acronym> standard uses this term to
+ indicate what is called a
+ <glossterm linkend="glossary-database">database</glossterm> in
+ <productname>PostgreSQL</productname>'s terminology.
+ </para>
+ <para>
+ (Don't confuse this term with
+ <glossterm linkend="glossary-system-catalog">system catalog</glossterm>).
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="manage-ag-overview"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-check-constraint">
+ <glossterm>Check constraint</glossterm>
+ <glossdef>
+ <para>
+ A type of <glossterm linkend="glossary-constraint">constraint</glossterm>
+ defined on a <glossterm linkend="glossary-relation">relation</glossterm>
+ which restricts the values allowed in one or more
+ <glossterm linkend="glossary-attribute">attributes</glossterm>. The
+ check constraint can make reference to any attribute of the same row in
+ the relation, but cannot reference other rows of the same relation or
+ other relations.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="ddl-constraints"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-checkpoint">
+ <glossterm>Checkpoint</glossterm>
+ <glossdef>
+ <para>
+ A point in the <glossterm linkend="glossary-wal">WAL</glossterm> sequence
+ at which it is guaranteed that the heap and index data files have been
+ updated with all information from
+ <glossterm linkend="glossary-shared-memory">shared memory</glossterm>
+ modified before that checkpoint;
+ a <firstterm>checkpoint record</firstterm> is written and flushed to WAL
+ to mark that point.
+ </para>
+ <para>
+ A checkpoint is also the act of carrying out all the actions that
+ are necessary to reach a checkpoint as defined above.
+ This process is initiated when predefined conditions are met,
+ such as a specified amount of time has passed, or a certain volume
+ of records has been written; or it can be invoked by the user
+ with the command <command>CHECKPOINT</command>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="wal-configuration"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-checkpointer">
+ <glossterm>Checkpointer (process)</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ that is responsible for executing
+ <glossterm linkend="glossary-checkpoint">checkpoints</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Class (archaic)</glossterm>
+ <glosssee otherterm="glossary-relation" />
+ </glossentry>
+
+ <glossentry id="glossary-client">
+ <glossterm>Client (process)</glossterm>
+ <glossdef>
+ <para>
+ Any process, possibly remote, that establishes a
+ <glossterm linkend="glossary-session">session</glossterm>
+ by <glossterm linkend="glossary-connection">connecting</glossterm> to an
+ <glossterm linkend="glossary-instance">instance</glossterm>
+ to interact with a <glossterm linkend="glossary-database">database</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-column">
+ <glossterm>Column</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-attribute">attribute</glossterm> found in
+ a <glossterm linkend="glossary-table">table</glossterm> or
+ <glossterm linkend="glossary-view">view</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-commit">
+ <glossterm>Commit</glossterm>
+ <glossdef>
+ <para>
+ The act of finalizing a
+ <glossterm linkend="glossary-transaction">transaction</glossterm> within
+ the <glossterm linkend="glossary-database">database</glossterm>, which
+ makes it visible to other transactions and assures its
+ <glossterm linkend="glossary-durability">durability</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-commit"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-concurrency">
+ <glossterm>Concurrency</glossterm>
+ <glossdef>
+ <para>
+ The concept that multiple independent operations happen within the
+ <glossterm linkend="glossary-database">database</glossterm> at the same time.
+ In <productname>PostgreSQL</productname>, concurrency is controlled by
+ the <glossterm linkend="glossary-mvcc">multiversion concurrency control</glossterm>
+ mechanism.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-connection">
+ <glossterm>Connection</glossterm>
+ <glossdef>
+ <para>
+ An established line of communication between a client process and a
+ <glossterm linkend="glossary-backend">backend</glossterm> process,
+ usually over a network, supporting a
+ <glossterm linkend="glossary-session">session</glossterm>. This term is
+ sometimes used as a synonym for session.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="runtime-config-connection"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-consistency">
+ <glossterm>Consistency</glossterm>
+ <glossdef>
+ <para>
+ The property that the data in the
+ <glossterm linkend="glossary-database">database</glossterm>
+ is always in compliance with
+ <glossterm linkend="glossary-constraint">integrity constraints</glossterm>.
+ Transactions may be allowed to violate some of the constraints
+ transiently before it commits, but if such violations are not resolved
+ by the time it commits, such a transaction is automatically
+ <glossterm linkend="glossary-rollback">rolled back</glossterm>.
+ This is one of the <acronym>ACID</acronym> properties.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-constraint">
+ <glossterm>Constraint</glossterm>
+ <glossdef>
+ <para>
+ A restriction on the values of data allowed within a
+ <glossterm linkend="glossary-table">table</glossterm>,
+ or in attributes of a
+ <glossterm linkend="glossary-domain">domain</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="ddl-constraints"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-cumulative-statistics">
+ <glossterm>Cumulative Statistics System</glossterm>
+ <glossdef>
+ <para>
+ A system which, if enabled, accumulates statistical information
+ about the <glossterm linkend="glossary-instance">instance</glossterm>'s
+ activities.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="monitoring-stats"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Data area</glossterm>
+ <glosssee otherterm="glossary-data-directory" />
+ </glossentry>
+
+ <glossentry id="glossary-database">
+ <glossterm>Database</glossterm>
+ <glossdef>
+ <para>
+ A named collection of
+ <glossterm linkend="glossary-sql-object">local SQL objects</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="manage-ag-overview"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-db-cluster">
+ <glossterm>Database cluster</glossterm>
+ <glossdef>
+ <para>
+ A collection of databases and global SQL objects,
+ and their common static and dynamic metadata.
+ Sometimes referred to as a
+ <firstterm>cluster</firstterm>.
+ </para>
+ <para>
+ In <productname>PostgreSQL</productname>, the term
+ <firstterm>cluster</firstterm> is also sometimes used to refer to an instance.
+ (Don't confuse this term with the SQL command <command>CLUSTER</command>.)
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Database server</glossterm>
+ <glosssee otherterm="glossary-instance" />
+ </glossentry>
+
+ <glossentry id="glossary-data-directory">
+ <glossterm>Data directory</glossterm>
+ <glossdef>
+ <para>
+ The base directory on the file system of a
+ <glossterm linkend="glossary-server">server</glossterm> that contains all
+ data files and subdirectories associated with a
+ <glossterm linkend="glossary-db-cluster">database cluster</glossterm>
+ (with the exception of
+ <glossterm linkend="glossary-tablespace">tablespaces</glossterm>,
+ and optionally <glossterm linkend="glossary-wal">WAL</glossterm>).
+ The environment variable <literal>PGDATA</literal> is commonly used to
+ refer to the data directory.
+ </para>
+ <para>
+ A <glossterm linkend="glossary-db-cluster">cluster</glossterm>'s storage
+ space comprises the data directory plus any additional tablespaces.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="storage-file-layout"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-data-page">
+ <glossterm>Data page</glossterm>
+ <glossdef>
+ <para>
+ The basic structure used to store relation data.
+ All pages are of the same size.
+ Data pages are typically stored on disk, each in a specific file,
+ and can be read to <glossterm linkend="glossary-shared-memory">shared buffers</glossterm>
+ where they can be modified, becoming
+ <firstterm>dirty</firstterm>. They become clean when written
+ to disk. New pages, which initially exist in memory only, are also
+ dirty until written.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-datum">
+ <glossterm>Datum</glossterm>
+ <glossdef>
+ <para>
+ The internal representation of one value of an <acronym>SQL</acronym>
+ data type.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-delete">
+ <glossterm>Delete</glossterm>
+ <glossdef>
+ <para>
+ An <acronym>SQL</acronym> command which removes
+ <glossterm linkend="glossary-tuple">rows</glossterm> from a given
+ <glossterm linkend="glossary-table">table</glossterm>
+ or <glossterm linkend="glossary-relation">relation</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-delete"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-domain">
+ <glossterm>Domain</glossterm>
+ <glossdef>
+ <para>
+ A user-defined data type that is based on another underlying data type.
+ It acts the same as the underlying type except for possibly restricting
+ the set of allowed values.
+ </para>
+ <para>
+ For more information, see <xref linkend="domains"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-durability">
+ <glossterm>Durability</glossterm>
+ <glossdef>
+ <para>
+ The assurance that once a
+ <glossterm linkend="glossary-transaction">transaction</glossterm> has
+ been <glossterm linkend="glossary-commit">committed</glossterm>, the
+ changes remain even after a system failure or crash.
+ This is one of the <acronym>ACID</acronym> properties.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Epoch</glossterm>
+ <glosssee otherterm="glossary-xid" />
+ </glossentry>
+
+ <glossentry id="glossary-extension">
+ <glossterm>Extension</glossterm>
+ <glossdef>
+ <para>
+ A software add-on package that can be installed on an
+ <glossterm linkend="glossary-instance">instance</glossterm> to
+ get extra features.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="extend-extensions" />.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-file-segment">
+ <glossterm>File segment</glossterm>
+ <glossdef>
+ <para>
+ A physical file which stores data for a given
+ <glossterm linkend="glossary-relation">relation</glossterm>.
+ File segments are limited in size by a configuration value
+ (typically 1 gigabyte),
+ so if a relation exceeds that size, it is split into multiple segments.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="storage-file-layout"/>.
+ </para>
+ <para>
+ (Don't confuse this term with the similar term
+ <glossterm linkend="glossary-wal-file">WAL segment</glossterm>).
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-foreign-data-wrapper">
+ <glossterm>Foreign data wrapper</glossterm>
+ <glossdef>
+ <para>
+ A means of representing data that is not contained in the local
+ <glossterm linkend="glossary-database">database</glossterm> so that it appears as if were in local
+ <glossterm linkend="glossary-table">table(s)</glossterm>. With a foreign data wrapper it is
+ possible to define a <glossterm linkend="glossary-foreign-server">foreign server</glossterm> and
+ <glossterm linkend="glossary-foreign-table">foreign tables</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createforeigndatawrapper"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-foreign-key">
+ <glossterm>Foreign key</glossterm>
+ <glossdef>
+ <para>
+ A type of <glossterm linkend="glossary-constraint">constraint</glossterm>
+ defined on one or more <glossterm linkend="glossary-column">columns</glossterm>
+ in a <glossterm linkend="glossary-table">table</glossterm> which
+ requires the value(s) in those <glossterm linkend="glossary-column">columns</glossterm> to
+ identify zero or one <glossterm linkend="glossary-tuple">row</glossterm>
+ in another (or, infrequently, the same)
+ <glossterm linkend="glossary-table">table</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-foreign-server">
+ <glossterm>Foreign server</glossterm>
+ <glossdef>
+ <para>
+ A named collection of
+ <glossterm linkend="glossary-foreign-table">foreign tables</glossterm> which
+ all use the same
+ <glossterm linkend="glossary-foreign-data-wrapper">foreign data wrapper</glossterm>
+ and have other configuration values in common.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createserver"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-foreign-table">
+ <glossterm>Foreign table (relation)</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-relation">relation</glossterm> which appears to have
+ <glossterm linkend="glossary-tuple">rows</glossterm> and
+ <glossterm linkend="glossary-column">columns</glossterm> similar to a
+ regular <glossterm linkend="glossary-table">table</glossterm>, but will forward
+ requests for data through its
+ <glossterm linkend="glossary-foreign-data-wrapper">foreign data wrapper</glossterm>,
+ which will return <glossterm linkend="glossary-result-set">result sets</glossterm>
+ structured according to the definition of the
+ <glossterm linkend="glossary-foreign-table">foreign table</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createforeigntable"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-fork">
+ <glossterm>Fork</glossterm>
+ <glossdef>
+ <para>
+ Each of the separate segmented file sets in which a relation is stored.
+ The <firstterm>main fork</firstterm> is where the actual data resides.
+ There also exist two secondary forks for metadata:
+ the <glossterm linkend="glossary-fsm">free space map</glossterm>
+ and the <glossterm linkend="glossary-vm">visibility map</glossterm>.
+ <glossterm linkend="glossary-unlogged">Unlogged relations</glossterm>
+ also have an <firstterm>init fork</firstterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-fsm">
+ <glossterm>Free space map (fork)</glossterm>
+ <glossdef>
+ <para>
+ A storage structure that keeps metadata about each data page of a table's
+ main fork. The free space map entry for each page stores the
+ amount of free space that's available for future tuples, and is structured
+ to be efficiently searched for available space for a new tuple of a given
+ size.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="storage-fsm"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-function">
+ <glossterm>Function (routine)</glossterm>
+ <glossdef>
+ <para>
+ A type of routine that receives zero or more arguments, returns zero or more
+ output values, and is constrained to run within one transaction.
+ Functions are invoked as part of a query, for example via
+ <command>SELECT</command>.
+ Certain functions can return
+ <glossterm linkend="glossary-result-set">sets</glossterm>; those are
+ called <firstterm>set-returning functions</firstterm>.
+ </para>
+ <para>
+ Functions can also be used for
+ <glossterm linkend="glossary-trigger">triggers</glossterm> to invoke.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createfunction"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-grant">
+ <glossterm>Grant</glossterm>
+ <glossdef>
+ <para>
+ An <acronym>SQL</acronym> command that is used to allow a
+ <glossterm linkend="glossary-user">user</glossterm> or
+ <glossterm linkend="glossary-role">role</glossterm> to access
+ specific objects within the <glossterm linkend="glossary-database">database</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-grant"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-heap">
+ <glossterm>Heap</glossterm>
+ <glossdef>
+ <para>
+ Contains the values of <glossterm linkend="glossary-tuple">row</glossterm>
+ attributes (i.e., the data) for a
+ <glossterm linkend="glossary-relation">relation</glossterm>.
+ The heap is realized within one or more
+ <glossterm linkend="glossary-file-segment">file segments</glossterm>
+ in the relation's <glossterm linkend="glossary-fork">main fork</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-host">
+ <glossterm>Host</glossterm>
+ <glossdef>
+ <para>
+ A computer that communicates with other computers over a network.
+ This is sometimes used as a synonym for
+ <glossterm linkend="glossary-server">server</glossterm>.
+ It is also used to refer to a computer where
+ <glossterm linkend="glossary-client">client processes</glossterm> run.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-index">
+ <glossterm>Index (relation)</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-relation">relation</glossterm> that contains
+ data derived from a <glossterm linkend="glossary-table">table</glossterm>
+ or <glossterm linkend="glossary-materialized-view">materialized view</glossterm>.
+ Its internal structure supports fast retrieval of and access to the original
+ data.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createindex"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-insert">
+ <glossterm>Insert</glossterm>
+ <glossdef>
+ <para>
+ An <acronym>SQL</acronym> command used to add new data into a
+ <glossterm linkend="glossary-table">table</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-insert"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-instance">
+ <glossterm>Instance</glossterm>
+ <glossdef>
+ <para>
+ A group of <glossterm linkend="glossary-backend">backend</glossterm> and
+ <glossterm linkend="glossary-auxiliary-proc">auxiliary processes</glossterm>
+ that communicate using a common shared memory area. One
+ <glossterm linkend="glossary-postmaster">postmaster process</glossterm>
+ manages the instance; one instance manages exactly one
+ <glossterm linkend="glossary-db-cluster">database cluster</glossterm>
+ with all its databases. Many instances can run on the same
+ <glossterm linkend="glossary-server">server</glossterm>
+ as long as their <acronym>TCP</acronym> ports do not conflict.
+ </para>
+ <para>
+ The instance handles all key features of a <acronym>DBMS</acronym>:
+ read and write access to files and shared memory,
+ assurance of the <acronym>ACID</acronym> properties,
+ <glossterm linkend="glossary-connection">connections</glossterm> to
+ <glossterm linkend="glossary-client">client processes</glossterm>,
+ privilege verification, crash recovery, replication, etc.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-isolation">
+ <glossterm>Isolation</glossterm>
+ <glossdef>
+ <para>
+ The property that the effects of a transaction are not visible to
+ <glossterm linkend="glossary-concurrency">concurrent transactions</glossterm>
+ before it commits.
+ This is one of the <acronym>ACID</acronym> properties.
+ </para>
+ <para>
+ For more information, see <xref linkend="transaction-iso" />.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-join">
+ <glossterm>Join</glossterm>
+ <glossdef>
+ <para>
+ An operation and <acronym>SQL</acronym> keyword used in
+ <glossterm linkend="glossary-query">queries</glossterm>
+ for combining data from multiple
+ <glossterm linkend="glossary-relation">relations</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-key">
+ <glossterm>Key</glossterm>
+ <glossdef>
+ <para>
+ A means of identifying a <glossterm linkend="glossary-tuple">row</glossterm> within a
+ <glossterm linkend="glossary-table">table</glossterm> or
+ other <glossterm linkend="glossary-relation">relation</glossterm> by
+ values contained within one or more
+ <glossterm linkend="glossary-attribute">attributes</glossterm>
+ in that relation.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-lock">
+ <glossterm>Lock</glossterm>
+ <glossdef>
+ <para>
+ A mechanism that allows a process to limit or prevent simultaneous
+ access to a resource.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-log-file">
+ <glossterm>Log file</glossterm>
+ <glossdef>
+ <para>
+ Log files contain human-readable text lines about events.
+ Examples include login failures, long-running queries, etc.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="logfile-maintenance"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-logged">
+ <glossterm>Logged</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-table">table</glossterm> is considered
+ <glossterm linkend="glossary-logged">logged</glossterm> if changes to it are sent to the
+ <glossterm linkend="glossary-wal">WAL</glossterm>. By default, all regular
+ tables are logged. A table can be specified as
+ <glossterm linkend="glossary-unlogged">unlogged</glossterm> either at
+ creation time or via the <command>ALTER TABLE</command> command.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-logger">
+ <glossterm>Logger (process)</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ which, if enabled, writes information about database events into the current
+ <glossterm linkend="glossary-log-file">log file</glossterm>.
+ When reaching certain time- or
+ volume-dependent criteria, a new log file is created.
+ Also called <firstterm>syslogger</firstterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="runtime-config-logging"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-log-record">
+ <glossterm>Log record</glossterm>
+ <glossdef>
+ <para>
+ Archaic term for a <glossterm linkend="glossary-wal-record">WAL record</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Master (server)</glossterm>
+ <glosssee otherterm="glossary-primary-server" />
+ </glossentry>
+
+ <glossentry id="glossary-materialized">
+ <glossterm>Materialized</glossterm>
+ <glossdef>
+ <para>
+ The property that some information has been pre-computed and stored
+ for later use, rather than computing it on-the-fly.
+ </para>
+ <para>
+ This term is used in
+ <glossterm linkend="glossary-materialized-view">materialized view</glossterm>,
+ to mean that the data derived from the view's query is stored on
+ disk separately from the sources of that data.
+ </para>
+ <para>
+ This term is also used to refer to some multi-step queries to mean that
+ the data resulting from executing a given step is stored in memory
+ (with the possibility of spilling to disk), so that it can be read multiple
+ times by another step.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-materialized-view">
+ <glossterm>Materialized view (relation)</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-relation">relation</glossterm> that is
+ defined by a <command>SELECT</command> statement
+ (just like a <glossterm linkend="glossary-view">view</glossterm>),
+ but stores data in the same way that a
+ <glossterm linkend="glossary-table">table</glossterm> does. It cannot be
+ modified via <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> operations.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-creatematerializedview"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-mvcc">
+ <glossterm>Multi-version concurrency control (MVCC)</glossterm>
+ <glossdef>
+ <para>
+ A mechanism designed to allow several
+ <glossterm linkend="glossary-transaction">transactions</glossterm> to be
+ reading and writing the same rows without one process causing other
+ processes to stall.
+ In <productname>PostgreSQL</productname>, MVCC is implemented by
+ creating copies (<firstterm>versions</firstterm>) of
+ <glossterm linkend="glossary-tuple">tuples</glossterm> as they are
+ modified; after transactions that can see the old versions terminate,
+ those old versions need to be removed.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-null">
+ <glossterm>Null</glossterm>
+ <glossdef>
+ <para>
+ A concept of non-existence that is a central tenet of relational
+ database theory. It represents the absence of a definite value.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Optimizer</glossterm>
+ <glosssee otherterm="glossary-planner" />
+ </glossentry>
+
+ <glossentry id="glossary-parallel-query">
+ <glossterm>Parallel query</glossterm>
+ <glossdef>
+ <para>
+ The ability to handle parts of executing a
+ <glossterm linkend="glossary-query">query</glossterm> to take advantage
+ of parallel processes on servers with multiple <acronym>CPU</acronym>s.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-partition">
+ <glossterm>Partition</glossterm>
+ <glossdef>
+ <para>
+ One of several disjoint (not overlapping) subsets of a larger set.
+ </para>
+ </glossdef>
+ <glossdef>
+ <para>
+ In reference to a
+ <glossterm linkend="glossary-partitioned-table">partitioned table</glossterm>:
+ One of the tables that each contain part of the data of the partitioned table,
+ which is said to be the <firstterm>parent</firstterm>.
+ The partition is itself a table, so it can also be queried directly;
+ at the same time, a partition can sometimes be a partitioned table,
+ allowing hierarchies to be created.
+ </para>
+ </glossdef>
+ <glossdef>
+ <para>
+ In reference to a <glossterm linkend="glossary-window-function">window function</glossterm>
+ in a <glossterm linkend="glossary-query">query</glossterm>,
+ a partition is a user-defined criterion that identifies which neighboring
+ <glossterm linkend="glossary-tuple">rows</glossterm>
+ of the <glossterm linkend="glossary-result-set">query's result set</glossterm>
+ can be considered by the function.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-partitioned-table">
+ <glossterm>Partitioned table (relation)</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-relation">relation</glossterm> that is
+ in semantic terms the same as a <glossterm linkend="glossary-table">table</glossterm>,
+ but whose storage is distributed across several
+ <glossterm linkend="glossary-partition">partitions</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-postmaster">
+ <glossterm>Postmaster (process)</glossterm>
+ <glossdef>
+ <para>
+ The very first process of an <glossterm linkend="glossary-instance">instance</glossterm>.
+ It starts and manages the
+ <glossterm linkend="glossary-auxiliary-proc">auxiliary processes</glossterm>
+ and creates <glossterm linkend="glossary-backend">backend processes</glossterm>
+ on demand.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="server-start"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-primary-key">
+ <glossterm>Primary key</glossterm>
+ <glossdef>
+ <para>
+ A special case of a
+ <glossterm linkend="glossary-unique-constraint">unique constraint</glossterm>
+ defined on a
+ <glossterm linkend="glossary-table">table</glossterm> or other
+ <glossterm linkend="glossary-relation">relation</glossterm> that also
+ guarantees that all of the
+ <glossterm linkend="glossary-attribute">attributes</glossterm>
+ within the <glossterm linkend="glossary-primary-key">primary key</glossterm>
+ do not have <glossterm linkend="glossary-null">null</glossterm> values.
+ As the name implies, there can be only one
+ primary key per table, though it is possible to have multiple unique
+ constraints that also have no null-capable attributes.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-primary-server">
+ <glossterm>Primary (server)</glossterm>
+ <glossdef>
+ <para>
+ When two or more <glossterm linkend="glossary-database">databases</glossterm>
+ are linked via <glossterm linkend="glossary-replication">replication</glossterm>,
+ the <glossterm linkend="glossary-server">server</glossterm>
+ that is considered the authoritative source of information is called
+ the <firstterm>primary</firstterm>,
+ also known as a <firstterm>master</firstterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-procedure">
+ <glossterm>Procedure (routine)</glossterm>
+ <glossdef>
+ <para>
+ A type of routine.
+ Their distinctive qualities are that they do not return values,
+ and that they are allowed to make transactional statements such
+ as <command>COMMIT</command> and <command>ROLLBACK</command>.
+ They are invoked via the <command>CALL</command> command.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createprocedure"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-query">
+ <glossterm>Query</glossterm>
+ <glossdef>
+ <para>
+ A request sent by a client to a <glossterm linkend="glossary-backend">backend</glossterm>,
+ usually to return results or to modify data on the database.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-planner">
+ <glossterm>Query planner</glossterm>
+ <glossdef>
+ <para>
+ The part of <productname>PostgreSQL</productname> that is devoted to
+ determining (<firstterm>planning</firstterm>) the most efficient way to
+ execute <glossterm linkend="glossary-query">queries</glossterm>.
+ Also known as <firstterm>query optimizer</firstterm>,
+ <firstterm>optimizer</firstterm>, or simply <firstterm>planner</firstterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Record</glossterm>
+ <glosssee otherterm="glossary-tuple" />
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Recycling</glossterm>
+ <glosssee otherterm="glossary-wal-file" />
+ </glossentry>
+
+ <glossentry id="glossary-referential-integrity">
+ <glossterm>Referential integrity</glossterm>
+ <glossdef>
+ <para>
+ A means of restricting data in one <glossterm linkend="glossary-relation">relation</glossterm>
+ by a <glossterm linkend="glossary-foreign-key">foreign key</glossterm>
+ so that it must have matching data in another
+ <glossterm linkend="glossary-relation">relation</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-relation">
+ <glossterm>Relation</glossterm>
+ <glossdef>
+ <para>
+ The generic term for all objects in a
+ <glossterm linkend="glossary-database">database</glossterm>
+ that have a name and a list of
+ <glossterm linkend="glossary-attribute">attributes</glossterm>
+ defined in a specific order.
+ <glossterm linkend="glossary-table">Tables</glossterm>,
+ <glossterm linkend="glossary-sequence">sequences</glossterm>,
+ <glossterm linkend="glossary-view">views</glossterm>,
+ <glossterm linkend="glossary-foreign-table">foreign tables</glossterm>,
+ <glossterm linkend="glossary-materialized-view">materialized views</glossterm>,
+ composite types, and
+ <glossterm linkend="glossary-index">indexes</glossterm> are all relations.
+ </para>
+ <para>
+ More generically, a relation is a set of tuples; for example,
+ the result of a query is also a relation.
+ </para>
+ <para>
+ In <productname>PostgreSQL</productname>,
+ <firstterm>Class</firstterm> is an archaic synonym for
+ <firstterm>relation</firstterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-replica">
+ <glossterm>Replica (server)</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-database">database</glossterm> that is paired
+ with a <glossterm linkend="glossary-primary-server">primary</glossterm>
+ database and is maintaining a copy of some or all of the primary database's
+ data. The foremost reasons for doing this are to allow for greater access
+ to that data, and to maintain availability of the data in the event that
+ the <glossterm linkend="glossary-primary-server">primary</glossterm>
+ becomes unavailable.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-replication">
+ <glossterm>Replication</glossterm>
+ <glossdef>
+ <para>
+ The act of reproducing data on one
+ <glossterm linkend="glossary-server">server</glossterm> onto another
+ server called a <glossterm linkend="glossary-replica">replica</glossterm>.
+ This can take the form of <firstterm>physical replication</firstterm>,
+ where all file changes from one server are copied verbatim,
+ or <firstterm>logical replication</firstterm> where a defined subset
+ of data changes are conveyed using a higher-level representation.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-result-set">
+ <glossterm>Result set</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-relation">relation</glossterm> transmitted
+ from a <glossterm linkend="glossary-backend">backend process</glossterm>
+ to a <glossterm linkend="glossary-client">client</glossterm> upon the
+ completion of an <acronym>SQL</acronym> command, usually a
+ <command>SELECT</command> but it can be an
+ <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> command if the <literal>RETURNING</literal>
+ clause is specified.
+ </para>
+ <para>
+ The fact that a result set is a relation means that a query can be used
+ in the definition of another query, becoming a
+ <firstterm>subquery</firstterm>.
+ </para>
+ </glossdef>
+ <glossdef>
+ <para>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-revoke">
+ <glossterm>Revoke</glossterm>
+ <glossdef>
+ <para>
+ A command to prevent access to a named set of
+ <glossterm linkend="glossary-database">database</glossterm> objects for a
+ named list of <glossterm linkend="glossary-role">roles</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-revoke"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-role">
+ <glossterm>Role</glossterm>
+ <glossdef>
+ <para>
+ A collection of access privileges to the
+ <glossterm linkend="glossary-database">instance</glossterm>.
+ Roles are themselves a privilege that can be granted to other roles.
+ This is often done for convenience or to ensure completeness
+ when multiple <glossterm linkend="glossary-user">users</glossterm> need
+ the same privileges.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createrole"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-rollback">
+ <glossterm>Rollback</glossterm>
+ <glossdef>
+ <para>
+ A command to undo all of the operations performed since the beginning
+ of a <glossterm linkend="glossary-transaction">transaction</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-rollback"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-routine">
+ <glossterm>Routine</glossterm>
+ <glossdef>
+ <para>
+ A defined set of instructions stored in the database system
+ that can be invoked for execution.
+ A routine can be written in a variety of programming
+ languages. Routines can be
+ <glossterm linkend="glossary-function">functions</glossterm>
+ (including set-returning functions and
+ <glossterm linkend="glossary-trigger">trigger functions</glossterm>),
+ <glossterm linkend="glossary-aggregate">aggregate functions</glossterm>,
+ and <glossterm linkend="glossary-procedure">procedures</glossterm>.
+ </para>
+ <para>
+ Many routines are already defined within <productname>PostgreSQL</productname>
+ itself, but user-defined ones can also be added.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Row</glossterm>
+ <glosssee otherterm="glossary-tuple" />
+ </glossentry>
+
+ <glossentry id="glossary-savepoint">
+ <glossterm>Savepoint</glossterm>
+ <glossdef>
+ <para>
+ A special mark in the sequence of steps in a
+ <glossterm linkend="glossary-transaction">transaction</glossterm>.
+ Data modifications after this point in time may be reverted
+ to the time of the savepoint.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-savepoint"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-schema">
+ <glossterm>Schema</glossterm>
+ <glossdef>
+ <para>
+ A schema is a namespace for
+ <glossterm linkend="glossary-sql-object">SQL objects</glossterm>,
+ which all reside in the same
+ <glossterm linkend="glossary-database">database</glossterm>.
+ Each SQL object must reside in exactly one schema.
+ </para>
+ <para>
+ All system-defined SQL objects reside in schema <literal>pg_catalog</literal>.
+ </para>
+ </glossdef>
+ <glossdef>
+ <para>
+ More generically, the term <firstterm>schema</firstterm> is used to mean
+ all data descriptions (<glossterm linkend="glossary-table">table</glossterm> definitions,
+ <glossterm linkend="glossary-constraint">constraints</glossterm>, comments, etc.)
+ for a given <glossterm linkend="glossary-database">database</glossterm> or
+ subset thereof.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="ddl-schemas"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Segment</glossterm>
+ <glosssee otherterm="glossary-file-segment" />
+ </glossentry>
+
+ <glossentry id="glossary-select">
+ <glossterm>Select</glossterm>
+ <glossdef>
+ <para>
+ The <acronym>SQL</acronym> command used to request data from a
+ <glossterm linkend="glossary-database">database</glossterm>.
+ Normally, <command>SELECT</command> commands are not expected to modify the
+ <glossterm linkend="glossary-database">database</glossterm> in any way,
+ but it is possible that
+ <glossterm linkend="glossary-function">functions</glossterm> invoked within
+ the query could have side effects that do modify data.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-select"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-sequence">
+ <glossterm>Sequence (relation)</glossterm>
+ <glossdef>
+ <para>
+ A type of relation that is used to generate values.
+ Typically the generated values are sequential non-repeating numbers.
+ They are commonly used to generate surrogate
+ <glossterm linkend="glossary-primary-key">primary key</glossterm>
+ values.
+ </para>
+ </glossdef>
+ </glossentry>
+
+<!-- XXX should define all other isolation levels (and improve this definition)
+ <glossentry id="glossary-serializable">
+ <glossterm>Serializable (isolation level)</glossterm>
+ <glossdef>
+ <para>
+ Transactions defined as <literal>SERIALIZABLE</literal> are unable to
+ see changes made within other transactions. In effect, for the
+ initializing session the entire <glossterm linkend="glossary-database">database</glossterm>
+ appears to be frozen for the duration of the
+ <glossterm linkend="glossary-transaction">Transaction</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+-->
+
+ <glossentry id="glossary-server">
+ <glossterm>Server</glossterm>
+ <glossdef>
+ <para>
+ A computer on which <productname>PostgreSQL</productname>
+ <glossterm linkend="glossary-instance">instances</glossterm> run.
+ The term <firstterm>server</firstterm> denotes real hardware, a
+ container, or a <firstterm>virtual machine</firstterm>.
+ </para>
+ <para>
+ This term is sometimes used to refer to an instance or to a host.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-session">
+ <glossterm>Session</glossterm>
+ <glossdef>
+ <para>
+ A state that allows a client and a backend to interact,
+ communicating over a <glossterm linkend="glossary-connection">connection</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-shared-memory">
+ <glossterm>Shared memory</glossterm>
+ <glossdef>
+ <para>
+ <acronym>RAM</acronym> which is used by the processes common to an
+ <glossterm linkend="glossary-instance">instance</glossterm>.
+ It mirrors parts of <glossterm linkend="glossary-database">database</glossterm>
+ files, provides a transient area for
+ <glossterm linkend="glossary-wal-record">WAL records</glossterm>,
+ and stores additional common information.
+ Note that shared memory belongs to the complete instance, not to a single
+ database.
+ </para>
+ <para>
+ The largest part of shared memory is known as <firstterm>shared buffers</firstterm>
+ and is used to mirror part of data files, organized into pages.
+ When a page is modified, it is called a dirty page until it is
+ written back to the file system.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="runtime-config-resource-memory"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-sql-object">
+ <glossterm>SQL object</glossterm>
+ <glossdef>
+ <para>
+ Any object that can be created with a <command>CREATE</command>
+ command. Most objects are specific to one database, and are commonly
+ known as <firstterm>local objects</firstterm>.
+ </para>
+ <para>
+ Most local objects reside in a specific
+ <glossterm linkend="glossary-schema">schema</glossterm> in their
+ containing database, such as
+ <glossterm linkend="glossary-relation">relations</glossterm> (all types),
+ <glossterm linkend="glossary-function">routines</glossterm> (all types),
+ data types, etc.
+ The names of such objects of the same type in the same schema
+ are enforced to be unique.
+ </para>
+ <para>
+ There also exist local objects that do not reside in schemas; some examples are
+ <glossterm linkend="glossary-extension">extensions</glossterm>,
+ <glossterm linkend="glossary-cast">data type casts</glossterm>, and
+ <glossterm linkend="glossary-foreign-data-wrapper">foreign data wrappers</glossterm>.
+ The names of such objects of the same type are enforced to be unique
+ within the database.
+ </para>
+ <para>
+ Other object types, such as
+ <glossterm linkend="glossary-role">roles</glossterm>,
+ <glossterm linkend="glossary-tablespace">tablespaces</glossterm>,
+ replication origins, subscriptions for logical replication, and
+ databases themselves are not local SQL objects since they exist
+ entirely outside of any specific database;
+ they are called <firstterm>global objects</firstterm>.
+ The names of such objects are enforced to be unique within the whole
+ database cluster.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="manage-ag-overview"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-sql-standard">
+ <glossterm>SQL standard</glossterm>
+ <glossdef>
+ <para>
+ A series of documents that define the <acronym>SQL</acronym> language.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Standby (server)</glossterm>
+ <glosssee otherterm="glossary-replica" />
+ </glossentry>
+
+ <glossentry id="glossary-startup-process">
+ <glossterm>Startup process</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ that replays WAL during crash recovery and in a
+ <glossterm linkend="glossary-replication">physical replica</glossterm>.
+ </para>
+ <para>
+ (The name is historical: the startup process was named before
+ replication was implemented; the name refers to its task as it
+ relates to the server startup following a crash.)
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-system-catalog">
+ <glossterm>System catalog</glossterm>
+ <glossdef>
+ <para>
+ A collection of <glossterm linkend="glossary-table">tables</glossterm>
+ which describe the structure of all
+ <glossterm linkend="glossary-sql-object">SQL objects</glossterm>
+ of the instance.
+ The system catalog resides in the schema <literal>pg_catalog</literal>.
+ These tables contain data in internal representation and are
+ not typically considered useful for user examination;
+ a number of user-friendlier <glossterm linkend="glossary-view">views</glossterm>,
+ also in schema <literal>pg_catalog</literal>, offer more convenient access to
+ some of that information, while additional tables and views
+ exist in schema <literal>information_schema</literal>
+ (see <xref linkend="information-schema" />) that expose some
+ of the same and additional information as mandated by the
+ <glossterm linkend="glossary-sql-standard">SQL standard</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="ddl-schemas"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-table">
+ <glossterm>Table</glossterm>
+ <glossdef>
+ <para>
+ A collection of <glossterm linkend="glossary-tuple">tuples</glossterm> having
+ a common data structure (the same number of
+ <glossterm linkend="glossary-attribute">attributes</glossterm>, in the same
+ order, having the same name and type per position).
+ A table is the most common form of
+ <glossterm linkend="glossary-relation">relation</glossterm> in
+ <productname>PostgreSQL</productname>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createtable"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-tablespace">
+ <glossterm>Tablespace</glossterm>
+ <glossdef>
+ <para>
+ A named location on the server file system.
+ All <glossterm linkend="glossary-sql-object">SQL objects</glossterm>
+ which require storage beyond their definition in the
+ <glossterm linkend="glossary-system-catalog">system catalog</glossterm>
+ must belong to a single tablespace.
+ Initially, a database cluster contains a single usable tablespace which is
+ used as the default for all SQL objects, called <literal>pg_default</literal>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="manage-ag-tablespaces"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-temporary-table">
+ <glossterm>Temporary table</glossterm>
+ <glossdef>
+ <para>
+ <glossterm linkend="glossary-table">Tables</glossterm> that exist either
+ for the lifetime of a
+ <glossterm linkend="glossary-session">session</glossterm> or a
+ <glossterm linkend="glossary-transaction">transaction</glossterm>, as
+ specified at the time of creation.
+ The data in them is not visible to other sessions, and is not
+ <glossterm linkend="glossary-logged">logged</glossterm>.
+ Temporary tables are often used to store intermediate data for a
+ multi-step operation.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createtable"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-toast">
+ <glossterm>TOAST</glossterm>
+ <glossdef>
+ <para>
+ A mechanism by which large attributes of table rows are split and
+ stored in a secondary table, called the <firstterm>TOAST table</firstterm>.
+ Each relation with large attributes has its own TOAST table.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="storage-toast" />.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-transaction">
+ <glossterm>Transaction</glossterm>
+ <glossdef>
+ <para>
+ A combination of commands that must act as a single
+ <glossterm linkend="glossary-atomic">atomic</glossterm> command: they all
+ succeed or all fail as a single unit, and their effects are not visible to
+ other <glossterm linkend="glossary-session">sessions</glossterm> until
+ the transaction is complete, and possibly even later, depending on the
+ isolation level.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="transaction-iso"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-xid">
+ <glossterm>Transaction ID</glossterm>
+ <glossdef>
+ <para>
+ The numerical, unique, sequentially-assigned identifier that each
+ transaction receives when it first causes a database modification.
+ Frequently abbreviated as <firstterm>xid</firstterm>.
+ When stored on disk, xids are only 32-bits wide, so only
+ approximately four billion write transaction IDs can be generated;
+ to permit the system to run for longer than that,
+ <firstterm>epochs</firstterm> are used, also 32 bits wide.
+ When the counter reaches the maximum xid value, it starts over at
+ <literal>3</literal> (values under that are reserved) and the
+ epoch value is incremented by one.
+ In some contexts, the epoch and xid values are
+ considered together as a single 64-bit value.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="datatype-oid"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-tps">
+ <glossterm>Transactions per second (TPS)</glossterm>
+ <glossdef>
+ <para>
+ Average number of transactions that are executed per second,
+ totaled across all sessions active for a measured run.
+ This is used as a measure of the performance characteristics of
+ an instance.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-trigger">
+ <glossterm>Trigger</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-function">function</glossterm> which can
+ be defined to execute whenever a certain operation (<command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>,
+ <command>TRUNCATE</command>) is applied to a
+ <glossterm linkend="glossary-relation">relation</glossterm>.
+ A trigger executes within the same
+ <glossterm linkend="glossary-transaction">transaction</glossterm> as the
+ statement which invoked it, and if the function fails, then the invoking
+ statement also fails.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createtrigger"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-tuple">
+ <glossterm>Tuple</glossterm>
+ <glossdef>
+ <para>
+ A collection of <glossterm linkend="glossary-attribute">attributes</glossterm>
+ in a fixed order.
+ That order may be defined by the <glossterm linkend="glossary-table">table</glossterm>
+ (or other <glossterm linkend="glossary-relation">relation</glossterm>)
+ where the tuple is contained, in which case the tuple is often called a
+ <firstterm>row</firstterm>. It may also be defined by the structure of a
+ result set, in which case it is sometimes called a <firstterm>record</firstterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-unique-constraint">
+ <glossterm>Unique constraint</glossterm>
+ <glossdef>
+ <para>
+ A type of <glossterm linkend="glossary-constraint">constraint</glossterm>
+ defined on a <glossterm linkend="glossary-relation">relation</glossterm>
+ which restricts the values allowed in one or a combination of columns
+ so that each value or combination of values can only appear once in the
+ relation &mdash; that is, no other row in the relation contains values
+ that are equal to those.
+ </para>
+ <para>
+ Because <glossterm linkend="glossary-null">null values</glossterm> are
+ not considered equal to each other, multiple rows with null values are
+ allowed to exist without violating the unique constraint.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-unlogged">
+ <glossterm>Unlogged</glossterm>
+ <glossdef>
+ <para>
+ The property of certain <glossterm linkend="glossary-relation">relations</glossterm>
+ that the changes to them are not reflected in the
+ <glossterm linkend="glossary-wal">WAL</glossterm>.
+ This disables replication and crash recovery for these relations.
+ </para>
+ <para>
+ The primary use of unlogged tables is for storing
+ transient work data that must be shared across processes.
+ </para>
+ <para>
+ <glossterm linkend="glossary-temporary-table">Temporary tables</glossterm>
+ are always unlogged.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-update">
+ <glossterm>Update</glossterm>
+ <glossdef>
+ <para>
+ An <acronym>SQL</acronym> command used to modify
+ <glossterm linkend="glossary-tuple">rows</glossterm>
+ that may already exist in a specified <glossterm linkend="glossary-table">table</glossterm>.
+ It cannot create or remove rows.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-update"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-user">
+ <glossterm>User</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-role">role</glossterm> that has the
+ <literal>LOGIN</literal> privilege.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-user-mapping">
+ <glossterm>User mapping</glossterm>
+ <glossdef>
+ <para>
+ The translation of login credentials in the local
+ <glossterm linkend="glossary-database">database</glossterm> to credentials
+ in a remote data system defined by a
+ <glossterm linkend="glossary-foreign-data-wrapper">foreign data wrapper</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createusermapping"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-vacuum">
+ <glossterm>Vacuum</glossterm>
+ <glossdef>
+ <para>
+ The process of removing outdated
+ <glossterm linkend="glossary-tuple">tuple versions</glossterm>
+ from tables or materialized views, and other closely related
+ processing required by <productname>PostgreSQL</productname>'s
+ implementation of <glossterm linkend="glossary-mvcc">MVCC</glossterm>.
+ This can be initiated through the use of
+ the <command>VACUUM</command> command, but can also be handled automatically
+ via <glossterm linkend="glossary-autovacuum">autovacuum</glossterm> processes.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="routine-vacuuming"/> .
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-view">
+ <glossterm>View</glossterm>
+ <glossdef>
+ <para>
+ A <glossterm linkend="glossary-relation">relation</glossterm> that is defined by a
+ <command>SELECT</command> statement, but has no storage of its own.
+ Any time a query references a view, the definition of the view is
+ substituted into the query as if the user had typed it as a subquery
+ instead of the name of the view.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="sql-createview"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-vm">
+ <glossterm>Visibility map (fork)</glossterm>
+ <glossdef>
+ <para>
+ A storage structure that keeps metadata about each data page
+ of a table's main fork. The visibility map entry for
+ each page stores two bits: the first one
+ (<literal>all-visible</literal>) indicates that all tuples
+ in the page are visible to all transactions. The second one
+ (<literal>all-frozen</literal>) indicates that all tuples
+ in the page are marked frozen.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>WAL</glossterm>
+ <glosssee otherterm="glossary-wal" />
+ </glossentry>
+
+ <glossentry id="glossary-wal-archiver">
+ <glossterm>WAL archiver (process)</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ which, if enabled, saves copies of
+ <glossterm linkend="glossary-wal-file">WAL files</glossterm>
+ for the purpose of creating backups or keeping
+ <glossterm linkend="glossary-replica">replicas</glossterm> current.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="continuous-archiving"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-wal-file">
+ <glossterm>WAL file</glossterm>
+ <glossdef>
+ <para>
+ Also known as <firstterm>WAL segment</firstterm> or
+ <firstterm>WAL segment file</firstterm>.
+ Each of the sequentially-numbered files that provide storage space for
+ <glossterm linkend="glossary-wal">WAL</glossterm>.
+ The files are all of the same predefined size
+ and are written in sequential order, interspersing changes
+ as they occur in multiple simultaneous sessions.
+ If the system crashes, the files are read in order, and each of the
+ changes is replayed to restore the system to the state it was in
+ before the crash.
+ </para>
+ <para>
+ Each WAL file can be released after a
+ <glossterm linkend="glossary-checkpoint">checkpoint</glossterm>
+ writes all the changes in it to the corresponding data files.
+ Releasing the file can be done either by deleting it, or by changing its
+ name so that it will be used in the future, which is called
+ <firstterm>recycling</firstterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="wal-internals"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-wal-record">
+ <glossterm>WAL record</glossterm>
+ <glossdef>
+ <para>
+ A low-level description of an individual data change.
+ It contains sufficient information for the data change to be
+ re-executed (<firstterm>replayed</firstterm>) in case a system failure
+ causes the change to be lost.
+ WAL records use a non-printable binary format.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="wal-internals"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-wal-receiver">
+ <glossterm>WAL receiver (process)</glossterm>
+ <glossdef>
+ <para>
+ An <glossterm linkend="glossary-auxiliary-proc">auxiliary process</glossterm>
+ that runs on a <glossterm linkend="glossary-replica">replica</glossterm>
+ to receive WAL from the
+ <glossterm linkend="glossary-primary-server">primary server</glossterm>
+ for replay by the
+ <glossterm linkend="glossary-startup-process">startup process</glossterm>.
+ </para>
+
+ <para>
+ For more information, see
+ <xref linkend="warm-standby"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>WAL segment</glossterm>
+ <glosssee otherterm="glossary-wal-file" />
+ </glossentry>
+
+ <glossentry id="glossary-wal-sender">
+ <glossterm>WAL sender (process)</glossterm>
+ <glossdef>
+ <para>
+ A special <glossterm linkend="glossary-backend">backend process</glossterm>
+ that streams WAL over a network. The receiving end can be a
+ <glossterm linkend="glossary-wal-receiver">WAL receiver</glossterm>
+ in a <glossterm linkend="glossary-replica">replica</glossterm>,
+ <xref linkend="app-pgreceivewal"/>, or any other client program
+ that speaks the replication protocol.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-wal-writer">
+ <glossterm>WAL writer (process)</glossterm>
+ <glossdef>
+ <para>
+ A process that writes <glossterm linkend="glossary-wal-record">WAL records</glossterm>
+ from <glossterm linkend="glossary-shared-memory">shared memory</glossterm> to
+ <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="runtime-config-wal"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-window-function">
+ <glossterm>Window function (routine)</glossterm>
+ <glossdef>
+ <para>
+ A type of <glossterm linkend="glossary-function">function</glossterm>
+ used in a <glossterm linkend="glossary-query">query</glossterm>
+ that applies to a <glossterm linkend="glossary-partition">partition</glossterm>
+ of the query's <glossterm linkend="glossary-result-set">result set</glossterm>;
+ the function's result is based on values found in
+ <glossterm linkend="glossary-tuple">rows</glossterm> of the same partition or frame.
+ </para>
+ <para>
+ All <glossterm linkend="glossary-aggregate">aggregate functions</glossterm>
+ can be used as window functions, but window functions can also be
+ used to, for example, give ranks to each of the rows in the partition.
+ Also known as <firstterm>analytic functions</firstterm>.
+ </para>
+ <para>
+ For more information, see
+ <xref linkend="tutorial-window"/>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry id="glossary-wal">
+ <glossterm>Write-ahead log</glossterm>
+ <glossdef>
+ <para>
+ The journal that keeps track of the changes in the
+ <glossterm linkend="glossary-db-cluster">database cluster</glossterm>
+ as user- and system-invoked operations take place.
+ It comprises many individual
+ <glossterm linkend="glossary-wal-record">WAL records</glossterm> written
+ sequentially to <glossterm linkend="glossary-wal-file">WAL files</glossterm>.
+ </para>
+ </glossdef>
+ </glossentry>
+ </glosslist>
+</appendix>
diff --git a/doc/src/sgml/hash.sgml b/doc/src/sgml/hash.sgml
new file mode 100644
index 0000000..e35911e
--- /dev/null
+++ b/doc/src/sgml/hash.sgml
@@ -0,0 +1,162 @@
+<!-- doc/src/sgml/hash.sgml -->
+
+<chapter id="hash-index">
+<title>Hash Indexes</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>Hash</secondary>
+ </indexterm>
+
+<sect1 id="hash-intro">
+ <title>Overview</title>
+
+ <para>
+ <productname>PostgreSQL</productname>
+ includes an implementation of persistent on-disk hash indexes,
+ which are fully crash recoverable. Any data type can be indexed by a
+ hash index, including data types that do not have a well-defined linear
+ ordering. Hash indexes store only the hash value of the data being
+ indexed, thus there are no restrictions on the size of the data column
+ being indexed.
+ </para>
+
+ <para>
+ Hash indexes support only single-column indexes and do not allow
+ uniqueness checking.
+ </para>
+
+ <para>
+ Hash indexes support only the <literal>=</literal> operator,
+ so WHERE clauses that specify range operations will not be able to take
+ advantage of hash indexes.
+ </para>
+
+ <para>
+ Each hash index tuple stores just the 4-byte hash value, not the actual
+ column value. As a result, hash indexes may be much smaller than B-trees
+ when indexing longer data items such as UUIDs, URLs, etc. The absence of
+ the column value also makes all hash index scans lossy. Hash indexes may
+ take part in bitmap index scans and backward scans.
+ </para>
+
+ <para>
+ Hash indexes are best optimized for SELECT and UPDATE-heavy workloads
+ that use equality scans on larger tables. In a B-tree index, searches must
+ descend through the tree until the leaf page is found. In tables with
+ millions of rows, this descent can increase access time to data. The
+ equivalent of a leaf page in a hash index is referred to as a bucket page. In
+ contrast, a hash index allows accessing the bucket pages directly,
+ thereby potentially reducing index access time in larger tables. This
+ reduction in "logical I/O" becomes even more pronounced on indexes/data
+ larger than shared_buffers/RAM.
+ </para>
+
+ <para>
+ Hash indexes have been designed to cope with uneven distributions of
+ hash values. Direct access to the bucket pages works well if the hash
+ values are evenly distributed. When inserts mean that the bucket page
+ becomes full, additional overflow pages are chained to that specific
+ bucket page, locally expanding the storage for index tuples that match
+ that hash value. When scanning a hash bucket during queries, we need to
+ scan through all of the overflow pages. Thus an unbalanced hash index
+ might actually be worse than a B-tree in terms of number of block
+ accesses required, for some data.
+ </para>
+
+ <para>
+ As a result of the overflow cases, we can say that hash indexes are
+ most suitable for unique, nearly unique data or data with a low number
+ of rows per hash bucket.
+ One possible way to avoid problems is to exclude highly non-unique
+ values from the index using a partial index condition, but this may
+ not be suitable in many cases.
+ </para>
+
+ <para>
+ Like B-Trees, hash indexes perform simple index tuple deletion. This
+ is a deferred maintenance operation that deletes index tuples that are
+ known to be safe to delete (those whose item identifier's LP_DEAD bit
+ is already set). If an insert finds no space is available on a page we
+ try to avoid creating a new overflow page by attempting to remove dead
+ index tuples. Removal cannot occur if the page is pinned at that time.
+ Deletion of dead index pointers also occurs during VACUUM.
+ </para>
+
+ <para>
+ If it can, VACUUM will also try to squeeze the index tuples onto as
+ few overflow pages as possible, minimizing the overflow chain. If an
+ overflow page becomes empty, overflow pages can be recycled for reuse
+ in other buckets, though we never return them to the operating system.
+ There is currently no provision to shrink a hash index, other than by
+ rebuilding it with REINDEX.
+ There is no provision for reducing the number of buckets, either.
+ </para>
+
+ <para>
+ Hash indexes may expand the number of bucket pages as the number of
+ rows indexed grows. The hash key-to-bucket-number mapping is chosen so that
+ the index can be incrementally expanded. When a new bucket is to be added to
+ the index, exactly one existing bucket will need to be "split", with some of
+ its tuples being transferred to the new bucket according to the updated
+ key-to-bucket-number mapping.
+ </para>
+
+ <para>
+ The expansion occurs in the foreground, which could increase execution
+ time for user inserts. Thus, hash indexes may not be suitable for tables
+ with rapidly increasing number of rows.
+ </para>
+
+</sect1>
+
+<sect1 id="hash-implementation">
+ <title>Implementation</title>
+
+ <para>
+ There are four kinds of pages in a hash index: the meta page (page zero),
+ which contains statically allocated control information; primary bucket
+ pages; overflow pages; and bitmap pages, which keep track of overflow
+ pages that have been freed and are available for re-use. For addressing
+ purposes, bitmap pages are regarded as a subset of the overflow pages.
+ </para>
+
+ <para>
+ Both scanning the index and inserting tuples require locating the bucket
+ where a given tuple ought to be located. To do this, we need the bucket
+ count, highmask, and lowmask from the metapage; however, it's undesirable
+ for performance reasons to have to have to lock and pin the metapage for
+ every such operation. Instead, we retain a cached copy of the metapage
+ in each backend's relcache entry. This will produce the correct bucket
+ mapping as long as the target bucket hasn't been split since the last
+ cache refresh.
+ </para>
+
+ <para>
+ Primary bucket pages and overflow pages are allocated independently since
+ any given index might need more or fewer overflow pages relative to its
+ number of buckets. The hash code uses an interesting set of addressing
+ rules to support a variable number of overflow pages while not having to
+ move primary bucket pages around after they are created.
+ </para>
+
+ <para>
+ Each row in the table indexed is represented by a single index tuple in
+ the hash index. Hash index tuples are stored in bucket pages, and if
+ they exist, overflow pages. We speed up searches by keeping the index entries
+ in any one index page sorted by hash code, thus allowing binary search to be
+ used within an index page. Note however that there is *no* assumption about
+ the relative ordering of hash codes across different index pages of a bucket.
+ </para>
+
+ <para>
+ The bucket splitting algorithms to expand the hash index are too complex to
+ be worthy of mention here, though are described in more detail in
+ <filename>src/backend/access/hash/README</filename>.
+ The split algorithm is crash safe and can be restarted if not completed
+ successfully.
+ </para>
+
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml
new file mode 100644
index 0000000..e4f4903
--- /dev/null
+++ b/doc/src/sgml/high-availability.sgml
@@ -0,0 +1,2344 @@
+<!-- doc/src/sgml/high-availability.sgml -->
+
+<chapter id="high-availability">
+ <title>High Availability, Load Balancing, and Replication</title>
+
+ <indexterm><primary>high availability</primary></indexterm>
+ <indexterm><primary>failover</primary></indexterm>
+ <indexterm><primary>replication</primary></indexterm>
+ <indexterm><primary>load balancing</primary></indexterm>
+ <indexterm><primary>clustering</primary></indexterm>
+ <indexterm><primary>data partitioning</primary></indexterm>
+
+ <para>
+ Database servers can work together to allow a second server to
+ take over quickly if the primary server fails (high
+ availability), or to allow several computers to serve the same
+ data (load balancing). Ideally, database servers could work
+ together seamlessly. Web servers serving static web pages can
+ be combined quite easily by merely load-balancing web requests
+ to multiple machines. In fact, read-only database servers can
+ be combined relatively easily too. Unfortunately, most database
+ servers have a read/write mix of requests, and read/write servers
+ are much harder to combine. This is because though read-only
+ data needs to be placed on each server only once, a write to any
+ server has to be propagated to all servers so that future read
+ requests to those servers return consistent results.
+ </para>
+
+ <para>
+ This synchronization problem is the fundamental difficulty for
+ servers working together. Because there is no single solution
+ that eliminates the impact of the sync problem for all use cases,
+ there are multiple solutions. Each solution addresses this
+ problem in a different way, and minimizes its impact for a specific
+ workload.
+ </para>
+
+ <para>
+ Some solutions deal with synchronization by allowing only one
+ server to modify the data. Servers that can modify data are
+ called read/write, <firstterm>master</firstterm> or <firstterm>primary</firstterm> servers.
+ Servers that track changes in the primary are called <firstterm>standby</firstterm>
+ or <firstterm>secondary</firstterm> servers. A standby server that cannot be connected
+ to until it is promoted to a primary server is called a <firstterm>warm
+ standby</firstterm> server, and one that can accept connections and serves read-only
+ queries is called a <firstterm>hot standby</firstterm> server.
+ </para>
+
+ <para>
+ Some solutions are synchronous,
+ meaning that a data-modifying transaction is not considered
+ committed until all servers have committed the transaction. This
+ guarantees that a failover will not lose any data and that all
+ load-balanced servers will return consistent results no matter
+ which server is queried. In contrast, asynchronous solutions allow some
+ delay between the time of a commit and its propagation to the other servers,
+ opening the possibility that some transactions might be lost in
+ the switch to a backup server, and that load balanced servers
+ might return slightly stale results. Asynchronous communication
+ is used when synchronous would be too slow.
+ </para>
+
+ <para>
+ Solutions can also be categorized by their granularity. Some solutions
+ can deal only with an entire database server, while others allow control
+ at the per-table or per-database level.
+ </para>
+
+ <para>
+ Performance must be considered in any choice. There is usually a
+ trade-off between functionality and
+ performance. For example, a fully synchronous solution over a slow
+ network might cut performance by more than half, while an asynchronous
+ one might have a minimal performance impact.
+ </para>
+
+ <para>
+ The remainder of this section outlines various failover, replication,
+ and load balancing solutions.
+ </para>
+
+ <sect1 id="different-replication-solutions">
+ <title>Comparison of Different Solutions</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Shared Disk Failover</term>
+ <listitem>
+
+ <para>
+ Shared disk failover avoids synchronization overhead by having only one
+ copy of the database. It uses a single disk array that is shared by
+ multiple servers. If the main database server fails, the standby server
+ is able to mount and start the database as though it were recovering from
+ a database crash. This allows rapid failover with no data loss.
+ </para>
+
+ <para>
+ Shared hardware functionality is common in network storage devices.
+ Using a network file system is also possible, though care must be
+ taken that the file system has full <acronym>POSIX</acronym> behavior (see <xref
+ linkend="creating-cluster-nfs"/>). One significant limitation of this
+ method is that if the shared disk array fails or becomes corrupt, the
+ primary and standby servers are both nonfunctional. Another issue is
+ that the standby server should never access the shared storage while
+ the primary server is running.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>File System (Block Device) Replication</term>
+ <listitem>
+
+ <para>
+ A modified version of shared hardware functionality is file system
+ replication, where all changes to a file system are mirrored to a file
+ system residing on another computer. The only restriction is that
+ the mirroring must be done in a way that ensures the standby server
+ has a consistent copy of the file system &mdash; specifically, writes
+ to the standby must be done in the same order as those on the primary.
+ <productname>DRBD</productname> is a popular file system replication solution
+ for Linux.
+ </para>
+
+<!--
+https://forge.continuent.org/pipermail/sequoia/2006-November/004070.html
+
+Oracle RAC is a shared disk approach and just send cache invalidations
+to other nodes but not actual data. As the disk is shared, data is
+only committed once to disk and there is a distributed locking
+protocol to make nodes agree on a serializable transactional order.
+-->
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Write-Ahead Log Shipping</term>
+ <listitem>
+
+ <para>
+ Warm and hot standby servers can be kept current by reading a
+ stream of write-ahead log (<acronym>WAL</acronym>)
+ records. If the main server fails, the standby contains
+ almost all of the data of the main server, and can be quickly
+ made the new primary database server. This can be synchronous or
+ asynchronous and can only be done for the entire database server.
+ </para>
+ <para>
+ A standby server can be implemented using file-based log shipping
+ (<xref linkend="warm-standby"/>) or streaming replication (see
+ <xref linkend="streaming-replication"/>), or a combination of both. For
+ information on hot standby, see <xref linkend="hot-standby"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Logical Replication</term>
+ <listitem>
+ <para>
+ Logical replication allows a database server to send a stream of data
+ modifications to another server. <productname>PostgreSQL</productname>
+ logical replication constructs a stream of logical data modifications
+ from the WAL. Logical replication allows replication of data changes on
+ a per-table basis. In addition, a server that is publishing its own
+ changes can also subscribe to changes from another server, allowing data
+ to flow in multiple directions. For more information on logical
+ replication, see <xref linkend="logical-replication"/>. Through the
+ logical decoding interface (<xref linkend="logicaldecoding"/>),
+ third-party extensions can also provide similar functionality.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Trigger-Based Primary-Standby Replication</term>
+ <listitem>
+
+ <para>
+ A trigger-based replication setup typically funnels data modification
+ queries to a designated primary server. Operating on a per-table basis,
+ the primary server sends data changes (typically) asynchronously to the
+ standby servers. Standby servers can answer queries while the primary is
+ running, and may allow some local data changes or write activity. This
+ form of replication is often used for offloading large analytical or data
+ warehouse queries.
+ </para>
+
+ <para>
+ <productname>Slony-I</productname> is an example of this type of
+ replication, with per-table granularity, and support for multiple standby
+ servers. Because it updates the standby server asynchronously (in
+ batches), there is possible data loss during fail over.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SQL-Based Replication Middleware</term>
+ <listitem>
+
+ <para>
+ With SQL-based replication middleware, a program intercepts
+ every SQL query and sends it to one or all servers. Each server
+ operates independently. Read-write queries must be sent to all servers,
+ so that every server receives any changes. But read-only queries can be
+ sent to just one server, allowing the read workload to be distributed
+ among them.
+ </para>
+
+ <para>
+ If queries are simply broadcast unmodified, functions like
+ <function>random()</function>, <function>CURRENT_TIMESTAMP</function>, and
+ sequences can have different values on different servers.
+ This is because each server operates independently, and because
+ SQL queries are broadcast rather than actual data changes. If
+ this is unacceptable, either the middleware or the application
+ must determine such values from a single source and then use those
+ values in write queries. Care must also be taken that all
+ transactions either commit or abort on all servers, perhaps
+ using two-phase commit (<xref linkend="sql-prepare-transaction"/>
+ and <xref linkend="sql-commit-prepared"/>).
+ <productname>Pgpool-II</productname> and <productname>Continuent Tungsten</productname>
+ are examples of this type of replication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Asynchronous Multimaster Replication</term>
+ <listitem>
+
+ <para>
+ For servers that are not regularly connected or have slow
+ communication links, like laptops or
+ remote servers, keeping data consistent among servers is a
+ challenge. Using asynchronous multimaster replication, each
+ server works independently, and periodically communicates with
+ the other servers to identify conflicting transactions. The
+ conflicts can be resolved by users or conflict resolution rules.
+ Bucardo is an example of this type of replication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Synchronous Multimaster Replication</term>
+ <listitem>
+
+ <para>
+ In synchronous multimaster replication, each server can accept
+ write requests, and modified data is transmitted from the
+ original server to every other server before each transaction
+ commits. Heavy write activity can cause excessive locking and
+ commit delays, leading to poor performance. Read requests can
+ be sent to any server. Some implementations use shared disk
+ to reduce the communication overhead. Synchronous multimaster
+ replication is best for mostly read workloads, though its big
+ advantage is that any server can accept write requests &mdash;
+ there is no need to partition workloads between primary and
+ standby servers, and because the data changes are sent from one
+ server to another, there is no problem with non-deterministic
+ functions like <function>random()</function>.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> does not offer this type of replication,
+ though <productname>PostgreSQL</productname> two-phase commit (<xref
+ linkend="sql-prepare-transaction"/> and <xref
+ linkend="sql-commit-prepared"/>)
+ can be used to implement this in application code or middleware.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ <xref linkend="high-availability-matrix"/> summarizes
+ the capabilities of the various solutions listed above.
+ </para>
+
+ <table id="high-availability-matrix">
+ <title>High Availability, Load Balancing, and Replication Feature Matrix</title>
+ <tgroup cols="9">
+ <colspec colname="col1" colwidth="1.1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <colspec colname="col5" colwidth="1*"/>
+ <colspec colname="col6" colwidth="1*"/>
+ <colspec colname="col7" colwidth="1*"/>
+ <colspec colname="col8" colwidth="1*"/>
+ <colspec colname="col9" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Feature</entry>
+ <entry>Shared Disk</entry>
+ <entry>File System Repl.</entry>
+ <entry>Write-Ahead Log Shipping</entry>
+ <entry>Logical Repl.</entry>
+ <entry>Trigger-&zwsp;Based Repl.</entry>
+ <entry>SQL Repl. Middle-ware</entry>
+ <entry>Async. MM Repl.</entry>
+ <entry>Sync. MM Repl.</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry>Popular examples</entry>
+ <entry align="center">NAS</entry>
+ <entry align="center">DRBD</entry>
+ <entry align="center">built-in streaming repl.</entry>
+ <entry align="center">built-in logical repl., pglogical</entry>
+ <entry align="center">Londiste, Slony</entry>
+ <entry align="center">pgpool-II</entry>
+ <entry align="center">Bucardo</entry>
+ <entry align="center"></entry>
+ </row>
+
+ <row>
+ <entry>Comm. method</entry>
+ <entry align="center">shared disk</entry>
+ <entry align="center">disk blocks</entry>
+ <entry align="center">WAL</entry>
+ <entry align="center">logical decoding</entry>
+ <entry align="center">table rows</entry>
+ <entry align="center">SQL</entry>
+ <entry align="center">table rows</entry>
+ <entry align="center">table rows and row locks</entry>
+ </row>
+
+ <row>
+ <entry>No special hardware required</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ <row>
+ <entry>Allows multiple primary servers</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ <row>
+ <entry>No overhead on primary</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ </row>
+
+ <row>
+ <entry>No waiting for multiple servers</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">with sync off</entry>
+ <entry align="center">with sync off</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ </row>
+
+ <row>
+ <entry>Primary failure will never lose data</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">with sync on</entry>
+ <entry align="center">with sync on</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ <row>
+ <entry>Replicas accept read-only queries</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">with hot standby</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ <row>
+ <entry>Per-table granularity</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ <row>
+ <entry>No conflict resolution necessary</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center">&bull;</entry>
+ <entry align="center"></entry>
+ <entry align="center">&bull;</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ There are a few solutions that do not fit into the above categories:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Data Partitioning</term>
+ <listitem>
+
+ <para>
+ Data partitioning splits tables into data sets. Each set can
+ be modified by only one server. For example, data can be
+ partitioned by offices, e.g., London and Paris, with a server
+ in each office. If queries combining London and Paris data
+ are necessary, an application can query both servers, or
+ primary/standby replication can be used to keep a read-only copy
+ of the other office's data on each server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Multiple-Server Parallel Query Execution</term>
+ <listitem>
+
+ <para>
+ Many of the above solutions allow multiple servers to handle multiple
+ queries, but none allow a single query to use multiple servers to
+ complete faster. This solution allows multiple servers to work
+ concurrently on a single query. It is usually accomplished by
+ splitting the data among servers and having each server execute its
+ part of the query and return results to a central server where they
+ are combined and returned to the user. This can be implemented using the
+ <productname>PL/Proxy</productname> tool set.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ It should also be noted that because <productname>PostgreSQL</productname>
+ is open source and easily extended, a number of companies have
+ taken <productname>PostgreSQL</productname> and created commercial
+ closed-source solutions with unique failover, replication, and load
+ balancing capabilities. These are not discussed here.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="warm-standby">
+ <title>Log-Shipping Standby Servers</title>
+
+
+ <para>
+ Continuous archiving can be used to create a <firstterm>high
+ availability</firstterm> (HA) cluster configuration with one or more
+ <firstterm>standby servers</firstterm> ready to take over operations if the
+ primary server fails. This capability is widely referred to as
+ <firstterm>warm standby</firstterm> or <firstterm>log shipping</firstterm>.
+ </para>
+
+ <para>
+ The primary and standby server work together to provide this capability,
+ though the servers are only loosely coupled. The primary server operates
+ in continuous archiving mode, while each standby server operates in
+ continuous recovery mode, reading the WAL files from the primary. No
+ changes to the database tables are required to enable this capability,
+ so it offers low administration overhead compared to some other
+ replication solutions. This configuration also has relatively low
+ performance impact on the primary server.
+ </para>
+
+ <para>
+ Directly moving WAL records from one database server to another
+ is typically described as log shipping. <productname>PostgreSQL</productname>
+ implements file-based log shipping by transferring WAL records
+ one file (WAL segment) at a time. WAL files (16MB) can be
+ shipped easily and cheaply over any distance, whether it be to an
+ adjacent system, another system at the same site, or another system on
+ the far side of the globe. The bandwidth required for this technique
+ varies according to the transaction rate of the primary server.
+ Record-based log shipping is more granular and streams WAL changes
+ incrementally over a network connection (see <xref
+ linkend="streaming-replication"/>).
+ </para>
+
+ <para>
+ It should be noted that log shipping is asynchronous, i.e., the WAL
+ records are shipped after transaction commit. As a result, there is a
+ window for data loss should the primary server suffer a catastrophic
+ failure; transactions not yet shipped will be lost. The size of the
+ data loss window in file-based log shipping can be limited by use of the
+ <varname>archive_timeout</varname> parameter, which can be set as low
+ as a few seconds. However such a low setting will
+ substantially increase the bandwidth required for file shipping.
+ Streaming replication (see <xref linkend="streaming-replication"/>)
+ allows a much smaller window of data loss.
+ </para>
+
+ <para>
+ Recovery performance is sufficiently good that the standby will
+ typically be only moments away from full
+ availability once it has been activated. As a result, this is called
+ a warm standby configuration which offers high
+ availability. Restoring a server from an archived base backup and
+ rollforward will take considerably longer, so that technique only
+ offers a solution for disaster recovery, not high availability.
+ A standby server can also be used for read-only queries, in which case
+ it is called a <firstterm>hot standby</firstterm> server. See
+ <xref linkend="hot-standby"/> for more information.
+ </para>
+
+ <indexterm zone="high-availability">
+ <primary>warm standby</primary>
+ </indexterm>
+
+ <indexterm zone="high-availability">
+ <primary>PITR standby</primary>
+ </indexterm>
+
+ <indexterm zone="high-availability">
+ <primary>standby server</primary>
+ </indexterm>
+
+ <indexterm zone="high-availability">
+ <primary>log shipping</primary>
+ </indexterm>
+
+ <indexterm zone="high-availability">
+ <primary>witness server</primary>
+ </indexterm>
+
+ <indexterm zone="high-availability">
+ <primary>STONITH</primary>
+ </indexterm>
+
+ <sect2 id="standby-planning">
+ <title>Planning</title>
+
+ <para>
+ It is usually wise to create the primary and standby servers
+ so that they are as similar as possible, at least from the
+ perspective of the database server. In particular, the path names
+ associated with tablespaces will be passed across unmodified, so both
+ primary and standby servers must have the same mount paths for
+ tablespaces if that feature is used. Keep in mind that if
+ <xref linkend="sql-createtablespace"/>
+ is executed on the primary, any new mount point needed for it must
+ be created on the primary and all standby servers before the command
+ is executed. Hardware need not be exactly the same, but experience shows
+ that maintaining two identical systems is easier than maintaining two
+ dissimilar ones over the lifetime of the application and system.
+ In any case the hardware architecture must be the same &mdash; shipping
+ from, say, a 32-bit to a 64-bit system will not work.
+ </para>
+
+ <para>
+ In general, log shipping between servers running different major
+ <productname>PostgreSQL</productname> release
+ levels is not possible. It is the policy of the PostgreSQL Global
+ Development Group not to make changes to disk formats during minor release
+ upgrades, so it is likely that running different minor release levels
+ on primary and standby servers will work successfully. However, no
+ formal support for that is offered and you are advised to keep primary
+ and standby servers at the same release level as much as possible.
+ When updating to a new minor release, the safest policy is to update
+ the standby servers first &mdash; a new minor release is more likely
+ to be able to read WAL files from a previous minor release than vice
+ versa.
+ </para>
+
+ </sect2>
+
+ <sect2 id="standby-server-operation" xreflabel="Standby Server Operation">
+ <title>Standby Server Operation</title>
+
+ <para>
+ A server enters standby mode if a
+ <anchor id="file-standby-signal" xreflabel="standby.signal"/>
+ <filename>standby.signal</filename>
+ <indexterm><primary><filename>standby.signal</filename></primary></indexterm>
+ file exists in the data directory when the server is started.
+ </para>
+
+ <para>
+ In standby mode, the server continuously applies WAL received from the
+ primary server. The standby server can read WAL from a WAL archive
+ (see <xref linkend="guc-restore-command"/>) or directly from the primary
+ over a TCP connection (streaming replication). The standby server will
+ also attempt to restore any WAL found in the standby cluster's
+ <filename>pg_wal</filename> directory. That typically happens after a server
+ restart, when the standby replays again WAL that was streamed from the
+ primary before the restart, but you can also manually copy files to
+ <filename>pg_wal</filename> at any time to have them replayed.
+ </para>
+
+ <para>
+ At startup, the standby begins by restoring all WAL available in the
+ archive location, calling <varname>restore_command</varname>. Once it
+ reaches the end of WAL available there and <varname>restore_command</varname>
+ fails, it tries to restore any WAL available in the <filename>pg_wal</filename> directory.
+ If that fails, and streaming replication has been configured, the
+ standby tries to connect to the primary server and start streaming WAL
+ from the last valid record found in archive or <filename>pg_wal</filename>. If that fails
+ or streaming replication is not configured, or if the connection is
+ later disconnected, the standby goes back to step 1 and tries to
+ restore the file from the archive again. This loop of retries from the
+ archive, <filename>pg_wal</filename>, and via streaming replication goes on until the server
+ is stopped or failover is triggered by a trigger file.
+ </para>
+
+ <para>
+ Standby mode is exited and the server switches to normal operation
+ when <command>pg_ctl promote</command> is run,
+ <function>pg_promote()</function> is called, or a trigger file is found
+ (<varname>promote_trigger_file</varname>). Before failover,
+ any WAL immediately available in the archive or in <filename>pg_wal</filename> will be
+ restored, but no attempt is made to connect to the primary.
+ </para>
+ </sect2>
+
+ <sect2 id="preparing-primary-for-standby">
+ <title>Preparing the Primary for Standby Servers</title>
+
+ <para>
+ Set up continuous archiving on the primary to an archive directory
+ accessible from the standby, as described
+ in <xref linkend="continuous-archiving"/>. The archive location should be
+ accessible from the standby even when the primary is down, i.e., it should
+ reside on the standby server itself or another trusted server, not on
+ the primary server.
+ </para>
+
+ <para>
+ If you want to use streaming replication, set up authentication on the
+ primary server to allow replication connections from the standby
+ server(s); that is, create a role and provide a suitable entry or
+ entries in <filename>pg_hba.conf</filename> with the database field set to
+ <literal>replication</literal>. Also ensure <varname>max_wal_senders</varname> is set
+ to a sufficiently large value in the configuration file of the primary
+ server. If replication slots will be used,
+ ensure that <varname>max_replication_slots</varname> is set sufficiently
+ high as well.
+ </para>
+
+ <para>
+ Take a base backup as described in <xref linkend="backup-base-backup"/>
+ to bootstrap the standby server.
+ </para>
+ </sect2>
+
+ <sect2 id="standby-server-setup">
+ <title>Setting Up a Standby Server</title>
+
+ <para>
+ To set up the standby server, restore the base backup taken from primary
+ server (see <xref linkend="backup-pitr-recovery"/>). Create a file
+ <link linkend="file-standby-signal"><filename>standby.signal</filename></link><indexterm><primary>standby.signal</primary></indexterm>
+ in the standby's cluster data
+ directory. Set <xref linkend="guc-restore-command"/> to a simple command to copy files from
+ the WAL archive. If you plan to have multiple standby servers for high
+ availability purposes, make sure that <varname>recovery_target_timeline</varname> is set to
+ <literal>latest</literal> (the default), to make the standby server follow the timeline change
+ that occurs at failover to another standby.
+ </para>
+
+ <note>
+ <para>
+ <xref linkend="guc-restore-command"/> should return immediately
+ if the file does not exist; the server will retry the command again if
+ necessary.
+ </para>
+ </note>
+
+ <para>
+ If you want to use streaming replication, fill in
+ <xref linkend="guc-primary-conninfo"/> with a libpq connection string, including
+ the host name (or IP address) and any additional details needed to
+ connect to the primary server. If the primary needs a password for
+ authentication, the password needs to be specified in
+ <xref linkend="guc-primary-conninfo"/> as well.
+ </para>
+
+ <para>
+ If you're setting up the standby server for high availability purposes,
+ set up WAL archiving, connections and authentication like the primary
+ server, because the standby server will work as a primary server after
+ failover.
+ </para>
+
+ <para>
+ If you're using a WAL archive, its size can be minimized using the <xref
+ linkend="guc-archive-cleanup-command"/> parameter to remove files that are no
+ longer required by the standby server.
+ The <application>pg_archivecleanup</application> utility is designed specifically to
+ be used with <varname>archive_cleanup_command</varname> in typical single-standby
+ configurations, see <xref linkend="pgarchivecleanup"/>.
+ Note however, that if you're using the archive for backup purposes, you
+ need to retain files needed to recover from at least the latest base
+ backup, even if they're no longer needed by the standby.
+ </para>
+
+ <para>
+ A simple example of configuration is:
+<programlisting>
+primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000'''
+restore_command = 'cp /path/to/archive/%f %p'
+archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'
+</programlisting>
+ </para>
+
+ <para>
+ You can have any number of standby servers, but if you use streaming
+ replication, make sure you set <varname>max_wal_senders</varname> high enough in
+ the primary to allow them to be connected simultaneously.
+ </para>
+
+ </sect2>
+
+ <sect2 id="streaming-replication">
+ <title>Streaming Replication</title>
+
+ <indexterm zone="high-availability">
+ <primary>Streaming Replication</primary>
+ </indexterm>
+
+ <para>
+ Streaming replication allows a standby server to stay more up-to-date
+ than is possible with file-based log shipping. The standby connects
+ to the primary, which streams WAL records to the standby as they're
+ generated, without waiting for the WAL file to be filled.
+ </para>
+
+ <para>
+ Streaming replication is asynchronous by default
+ (see <xref linkend="synchronous-replication"/>), in which case there is
+ a small delay between committing a transaction in the primary and the
+ changes becoming visible in the standby. This delay is however much
+ smaller than with file-based log shipping, typically under one second
+ assuming the standby is powerful enough to keep up with the load. With
+ streaming replication, <varname>archive_timeout</varname> is not required to
+ reduce the data loss window.
+ </para>
+
+ <para>
+ If you use streaming replication without file-based continuous
+ archiving, the server might recycle old WAL segments before the standby
+ has received them. If this occurs, the standby will need to be
+ reinitialized from a new base backup. You can avoid this by setting
+ <varname>wal_keep_size</varname> to a value large enough to ensure that
+ WAL segments are not recycled too early, or by configuring a replication
+ slot for the standby. If you set up a WAL archive that's accessible from
+ the standby, these solutions are not required, since the standby can
+ always use the archive to catch up provided it retains enough segments.
+ </para>
+
+ <para>
+ To use streaming replication, set up a file-based log-shipping standby
+ server as described in <xref linkend="warm-standby"/>. The step that
+ turns a file-based log-shipping standby into streaming replication
+ standby is setting the <varname>primary_conninfo</varname> setting
+ to point to the primary server. Set
+ <xref linkend="guc-listen-addresses"/> and authentication options
+ (see <filename>pg_hba.conf</filename>) on the primary so that the standby server
+ can connect to the <literal>replication</literal> pseudo-database on the primary
+ server (see <xref linkend="streaming-replication-authentication"/>).
+ </para>
+
+ <para>
+ On systems that support the keepalive socket option, setting
+ <xref linkend="guc-tcp-keepalives-idle"/>,
+ <xref linkend="guc-tcp-keepalives-interval"/> and
+ <xref linkend="guc-tcp-keepalives-count"/> helps the primary promptly
+ notice a broken connection.
+ </para>
+
+ <para>
+ Set the maximum number of concurrent connections from the standby servers
+ (see <xref linkend="guc-max-wal-senders"/> for details).
+ </para>
+
+ <para>
+ When the standby is started and <varname>primary_conninfo</varname> is set
+ correctly, the standby will connect to the primary after replaying all
+ WAL files available in the archive. If the connection is established
+ successfully, you will see a <literal>walreceiver</literal> in the standby, and
+ a corresponding <literal>walsender</literal> process in the primary.
+ </para>
+
+ <sect3 id="streaming-replication-authentication">
+ <title>Authentication</title>
+ <para>
+ It is very important that the access privileges for replication be set up
+ so that only trusted users can read the WAL stream, because it is
+ easy to extract privileged information from it. Standby servers must
+ authenticate to the primary as an account that has the
+ <literal>REPLICATION</literal> privilege or a superuser. It is
+ recommended to create a dedicated user account with
+ <literal>REPLICATION</literal> and <literal>LOGIN</literal>
+ privileges for replication. While <literal>REPLICATION</literal>
+ privilege gives very high permissions, it does not allow the user to
+ modify any data on the primary system, which the
+ <literal>SUPERUSER</literal> privilege does.
+ </para>
+
+ <para>
+ Client authentication for replication is controlled by a
+ <filename>pg_hba.conf</filename> record specifying <literal>replication</literal> in the
+ <replaceable>database</replaceable> field. For example, if the standby is running on
+ host IP <literal>192.168.1.100</literal> and the account name for replication
+ is <literal>foo</literal>, the administrator can add the following line to the
+ <filename>pg_hba.conf</filename> file on the primary:
+
+<programlisting>
+# Allow the user "foo" from host 192.168.1.100 to connect to the primary
+# as a replication standby if the user's password is correctly supplied.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host replication foo 192.168.1.100/32 md5
+</programlisting>
+ </para>
+ <para>
+ The host name and port number of the primary, connection user name,
+ and password are specified in the <xref linkend="guc-primary-conninfo"/>.
+ The password can also be set in the <filename>~/.pgpass</filename> file on the
+ standby (specify <literal>replication</literal> in the <replaceable>database</replaceable>
+ field).
+ For example, if the primary is running on host IP <literal>192.168.1.50</literal>,
+ port <literal>5432</literal>, the account name for replication is
+ <literal>foo</literal>, and the password is <literal>foopass</literal>, the administrator
+ can add the following line to the <filename>postgresql.conf</filename> file on the
+ standby:
+
+<programlisting>
+# The standby connects to the primary that is running on host 192.168.1.50
+# and port 5432 as the user "foo" whose password is "foopass".
+primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="streaming-replication-monitoring">
+ <title>Monitoring</title>
+ <para>
+ An important health indicator of streaming replication is the amount
+ of WAL records generated in the primary, but not yet applied in the
+ standby. You can calculate this lag by comparing the current WAL write
+ location on the primary with the last WAL location received by the
+ standby. These locations can be retrieved using
+ <function>pg_current_wal_lsn</function> on the primary and
+ <function>pg_last_wal_receive_lsn</function> on the standby,
+ respectively (see <xref linkend="functions-admin-backup-table"/> and
+ <xref linkend="functions-recovery-info-table"/> for details).
+ The last WAL receive location in the standby is also displayed in the
+ process status of the WAL receiver process, displayed using the
+ <command>ps</command> command (see <xref linkend="monitoring-ps"/> for details).
+ </para>
+ <para>
+ You can retrieve a list of WAL sender processes via the
+ <link linkend="monitoring-pg-stat-replication-view"><structname>
+ pg_stat_replication</structname></link> view. Large differences between
+ <function>pg_current_wal_lsn</function> and the view's <literal>sent_lsn</literal> field
+ might indicate that the primary server is under heavy load, while
+ differences between <literal>sent_lsn</literal> and
+ <function>pg_last_wal_receive_lsn</function> on the standby might indicate
+ network delay, or that the standby is under heavy load.
+ </para>
+ <para>
+ On a hot standby, the status of the WAL receiver process can be retrieved
+ via the <link linkend="monitoring-pg-stat-wal-receiver-view">
+ <structname>pg_stat_wal_receiver</structname></link> view. A large
+ difference between <function>pg_last_wal_replay_lsn</function> and the
+ view's <literal>flushed_lsn</literal> indicates that WAL is being
+ received faster than it can be replayed.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="streaming-replication-slots">
+ <title>Replication Slots</title>
+ <indexterm>
+ <primary>replication slot</primary>
+ <secondary>streaming replication</secondary>
+ </indexterm>
+ <para>
+ Replication slots provide an automated way to ensure that the primary does
+ not remove WAL segments until they have been received by all standbys,
+ and that the primary does not remove rows which could cause a
+ <link linkend="hot-standby-conflict">recovery conflict</link> even when the
+ standby is disconnected.
+ </para>
+ <para>
+ In lieu of using replication slots, it is possible to prevent the removal
+ of old WAL segments using <xref linkend="guc-wal-keep-size"/>, or by
+ storing the segments in an archive using
+ <xref linkend="guc-archive-command"/> or <xref linkend="guc-archive-library"/>.
+ However, these methods often result in retaining more WAL segments than
+ required, whereas replication slots retain only the number of segments
+ known to be needed. On the other hand, replication slots can retain so
+ many WAL segments that they fill up the space allocated
+ for <literal>pg_wal</literal>;
+ <xref linkend="guc-max-slot-wal-keep-size"/> limits the size of WAL files
+ retained by replication slots.
+ </para>
+ <para>
+ Similarly, <xref linkend="guc-hot-standby-feedback"/>
+ and <xref linkend="guc-vacuum-defer-cleanup-age"/> provide protection against
+ relevant rows being removed by vacuum, but the former provides no
+ protection during any time period when the standby is not connected,
+ and the latter often needs to be set to a high value to provide adequate
+ protection. Replication slots overcome these disadvantages.
+ </para>
+ <sect3 id="streaming-replication-slots-manipulation">
+ <title>Querying and Manipulating Replication Slots</title>
+ <para>
+ Each replication slot has a name, which can contain lower-case letters,
+ numbers, and the underscore character.
+ </para>
+ <para>
+ Existing replication slots and their state can be seen in the
+ <link linkend="view-pg-replication-slots"><structname>pg_replication_slots</structname></link>
+ view.
+ </para>
+ <para>
+ Slots can be created and dropped either via the streaming replication
+ protocol (see <xref linkend="protocol-replication"/>) or via SQL
+ functions (see <xref linkend="functions-replication"/>).
+ </para>
+ </sect3>
+ <sect3 id="streaming-replication-slots-config">
+ <title>Configuration Example</title>
+ <para>
+ You can create a replication slot like this:
+<programlisting>
+postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
+ slot_name | lsn
+-------------+-----
+ node_a_slot |
+
+postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
+ slot_name | slot_type | active
+-------------+-----------+--------
+ node_a_slot | physical | f
+(1 row)
+</programlisting>
+ To configure the standby to use this slot, <varname>primary_slot_name</varname>
+ should be configured on the standby. Here is a simple example:
+<programlisting>
+primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
+primary_slot_name = 'node_a_slot'
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="cascading-replication">
+ <title>Cascading Replication</title>
+
+ <indexterm zone="high-availability">
+ <primary>Cascading Replication</primary>
+ </indexterm>
+
+ <para>
+ The cascading replication feature allows a standby server to accept replication
+ connections and stream WAL records to other standbys, acting as a relay.
+ This can be used to reduce the number of direct connections to the primary
+ and also to minimize inter-site bandwidth overheads.
+ </para>
+
+ <para>
+ A standby acting as both a receiver and a sender is known as a cascading
+ standby. Standbys that are more directly connected to the primary are known
+ as upstream servers, while those standby servers further away are downstream
+ servers. Cascading replication does not place limits on the number or
+ arrangement of downstream servers, though each standby connects to only
+ one upstream server which eventually links to a single primary server.
+ </para>
+
+ <para>
+ A cascading standby sends not only WAL records received from the
+ primary but also those restored from the archive. So even if the replication
+ connection in some upstream connection is terminated, streaming replication
+ continues downstream for as long as new WAL records are available.
+ </para>
+
+ <para>
+ Cascading replication is currently asynchronous. Synchronous replication
+ (see <xref linkend="synchronous-replication"/>) settings have no effect on
+ cascading replication at present.
+ </para>
+
+ <para>
+ Hot standby feedback propagates upstream, whatever the cascaded arrangement.
+ </para>
+
+ <para>
+ If an upstream standby server is promoted to become the new primary, downstream
+ servers will continue to stream from the new primary if
+ <varname>recovery_target_timeline</varname> is set to <literal>'latest'</literal> (the default).
+ </para>
+
+ <para>
+ To use cascading replication, set up the cascading standby so that it can
+ accept replication connections (that is, set
+ <xref linkend="guc-max-wal-senders"/> and <xref linkend="guc-hot-standby"/>,
+ and configure
+ <link linkend="auth-pg-hba-conf">host-based authentication</link>).
+ You will also need to set <varname>primary_conninfo</varname> in the downstream
+ standby to point to the cascading standby.
+ </para>
+ </sect2>
+
+ <sect2 id="synchronous-replication">
+ <title>Synchronous Replication</title>
+
+ <indexterm zone="high-availability">
+ <primary>Synchronous Replication</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> streaming replication is asynchronous by
+ default. If the primary server
+ crashes then some transactions that were committed may not have been
+ replicated to the standby server, causing data loss. The amount
+ of data loss is proportional to the replication delay at the time of
+ failover.
+ </para>
+
+ <para>
+ Synchronous replication offers the ability to confirm that all changes
+ made by a transaction have been transferred to one or more synchronous
+ standby servers. This extends that standard level of durability
+ offered by a transaction commit. This level of protection is referred
+ to as 2-safe replication in computer science theory, and group-1-safe
+ (group-safe and 1-safe) when <varname>synchronous_commit</varname> is set to
+ <literal>remote_write</literal>.
+ </para>
+
+ <para>
+ When requesting synchronous replication, each commit of a
+ write transaction will wait until confirmation is
+ received that the commit has been written to the write-ahead log on disk
+ of both the primary and standby server. The only possibility that data
+ can be lost is if both the primary and the standby suffer crashes at the
+ same time. This can provide a much higher level of durability, though only
+ if the sysadmin is cautious about the placement and management of the two
+ servers. Waiting for confirmation increases the user's confidence that the
+ changes will not be lost in the event of server crashes but it also
+ necessarily increases the response time for the requesting transaction.
+ The minimum wait time is the round-trip time between primary and standby.
+ </para>
+
+ <para>
+ Read-only transactions and transaction rollbacks need not wait for
+ replies from standby servers. Subtransaction commits do not wait for
+ responses from standby servers, only top-level commits. Long
+ running actions such as data loading or index building do not wait
+ until the very final commit message. All two-phase commit actions
+ require commit waits, including both prepare and commit.
+ </para>
+
+ <para>
+ A synchronous standby can be a physical replication standby or a logical
+ replication subscriber. It can also be any other physical or logical WAL
+ replication stream consumer that knows how to send the appropriate
+ feedback messages. Besides the built-in physical and logical replication
+ systems, this includes special programs such
+ as <command>pg_receivewal</command> and <command>pg_recvlogical</command>
+ as well as some third-party replication systems and custom programs.
+ Check the respective documentation for details on synchronous replication
+ support.
+ </para>
+
+ <sect3 id="synchronous-replication-config">
+ <title>Basic Configuration</title>
+
+ <para>
+ Once streaming replication has been configured, configuring synchronous
+ replication requires only one additional configuration step:
+ <xref linkend="guc-synchronous-standby-names"/> must be set to
+ a non-empty value. <varname>synchronous_commit</varname> must also be set to
+ <literal>on</literal>, but since this is the default value, typically no change is
+ required. (See <xref linkend="runtime-config-wal-settings"/> and
+ <xref linkend="runtime-config-replication-primary"/>.)
+ This configuration will cause each commit to wait for
+ confirmation that the standby has written the commit record to durable
+ storage.
+ <varname>synchronous_commit</varname> can be set by individual
+ users, so it can be configured in the configuration file, for particular
+ users or databases, or dynamically by applications, in order to control
+ the durability guarantee on a per-transaction basis.
+ </para>
+
+ <para>
+ After a commit record has been written to disk on the primary, the
+ WAL record is then sent to the standby. The standby sends reply
+ messages each time a new batch of WAL data is written to disk, unless
+ <varname>wal_receiver_status_interval</varname> is set to zero on the standby.
+ In the case that <varname>synchronous_commit</varname> is set to
+ <literal>remote_apply</literal>, the standby sends reply messages when the commit
+ record is replayed, making the transaction visible.
+ If the standby is chosen as a synchronous standby, according to the setting
+ of <varname>synchronous_standby_names</varname> on the primary, the reply
+ messages from that standby will be considered along with those from other
+ synchronous standbys to decide when to release transactions waiting for
+ confirmation that the commit record has been received. These parameters
+ allow the administrator to specify which standby servers should be
+ synchronous standbys. Note that the configuration of synchronous
+ replication is mainly on the primary. Named standbys must be directly
+ connected to the primary; the primary knows nothing about downstream
+ standby servers using cascaded replication.
+ </para>
+
+ <para>
+ Setting <varname>synchronous_commit</varname> to <literal>remote_write</literal> will
+ cause each commit to wait for confirmation that the standby has received
+ the commit record and written it out to its own operating system, but not
+ for the data to be flushed to disk on the standby. This
+ setting provides a weaker guarantee of durability than <literal>on</literal>
+ does: the standby could lose the data in the event of an operating system
+ crash, though not a <productname>PostgreSQL</productname> crash.
+ However, it's a useful setting in practice
+ because it can decrease the response time for the transaction.
+ Data loss could only occur if both the primary and the standby crash and
+ the database of the primary gets corrupted at the same time.
+ </para>
+
+ <para>
+ Setting <varname>synchronous_commit</varname> to <literal>remote_apply</literal> will
+ cause each commit to wait until the current synchronous standbys report
+ that they have replayed the transaction, making it visible to user
+ queries. In simple cases, this allows for load balancing with causal
+ consistency.
+ </para>
+
+ <para>
+ Users will stop waiting if a fast shutdown is requested. However, as
+ when using asynchronous replication, the server will not fully
+ shutdown until all outstanding WAL records are transferred to the currently
+ connected standby servers.
+ </para>
+
+ </sect3>
+
+ <sect3 id="synchronous-replication-multiple-standbys">
+ <title>Multiple Synchronous Standbys</title>
+
+ <para>
+ Synchronous replication supports one or more synchronous standby servers;
+ transactions will wait until all the standby servers which are considered
+ as synchronous confirm receipt of their data. The number of synchronous
+ standbys that transactions must wait for replies from is specified in
+ <varname>synchronous_standby_names</varname>. This parameter also specifies
+ a list of standby names and the method (<literal>FIRST</literal> and
+ <literal>ANY</literal>) to choose synchronous standbys from the listed ones.
+ </para>
+ <para>
+ The method <literal>FIRST</literal> specifies a priority-based synchronous
+ replication and makes transaction commits wait until their WAL records are
+ replicated to the requested number of synchronous standbys chosen based on
+ their priorities. The standbys whose names appear earlier in the list are
+ given higher priority and will be considered as synchronous. Other standby
+ servers appearing later in this list represent potential synchronous
+ standbys. If any of the current synchronous standbys disconnects for
+ whatever reason, it will be replaced immediately with the
+ next-highest-priority standby.
+ </para>
+ <para>
+ An example of <varname>synchronous_standby_names</varname> for
+ a priority-based multiple synchronous standbys is:
+<programlisting>
+synchronous_standby_names = 'FIRST 2 (s1, s2, s3)'
+</programlisting>
+ In this example, if four standby servers <literal>s1</literal>, <literal>s2</literal>,
+ <literal>s3</literal> and <literal>s4</literal> are running, the two standbys
+ <literal>s1</literal> and <literal>s2</literal> will be chosen as synchronous standbys
+ because their names appear early in the list of standby names.
+ <literal>s3</literal> is a potential synchronous standby and will take over
+ the role of synchronous standby when either of <literal>s1</literal> or
+ <literal>s2</literal> fails. <literal>s4</literal> is an asynchronous standby since
+ its name is not in the list.
+ </para>
+ <para>
+ The method <literal>ANY</literal> specifies a quorum-based synchronous
+ replication and makes transaction commits wait until their WAL records
+ are replicated to <emphasis>at least</emphasis> the requested number of
+ synchronous standbys in the list.
+ </para>
+ <para>
+ An example of <varname>synchronous_standby_names</varname> for
+ a quorum-based multiple synchronous standbys is:
+<programlisting>
+synchronous_standby_names = 'ANY 2 (s1, s2, s3)'
+</programlisting>
+ In this example, if four standby servers <literal>s1</literal>, <literal>s2</literal>,
+ <literal>s3</literal> and <literal>s4</literal> are running, transaction commits will
+ wait for replies from at least any two standbys of <literal>s1</literal>,
+ <literal>s2</literal> and <literal>s3</literal>. <literal>s4</literal> is an asynchronous
+ standby since its name is not in the list.
+ </para>
+ <para>
+ The synchronous states of standby servers can be viewed using
+ the <structname>pg_stat_replication</structname> view.
+ </para>
+ </sect3>
+
+ <sect3 id="synchronous-replication-performance">
+ <title>Planning for Performance</title>
+
+ <para>
+ Synchronous replication usually requires carefully planned and placed
+ standby servers to ensure applications perform acceptably. Waiting
+ doesn't utilize system resources, but transaction locks continue to be
+ held until the transfer is confirmed. As a result, incautious use of
+ synchronous replication will reduce performance for database
+ applications because of increased response times and higher contention.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> allows the application developer
+ to specify the durability level required via replication. This can be
+ specified for the system overall, though it can also be specified for
+ specific users or connections, or even individual transactions.
+ </para>
+
+ <para>
+ For example, an application workload might consist of:
+ 10% of changes are important customer details, while
+ 90% of changes are less important data that the business can more
+ easily survive if it is lost, such as chat messages between users.
+ </para>
+
+ <para>
+ With synchronous replication options specified at the application level
+ (on the primary) we can offer synchronous replication for the most
+ important changes, without slowing down the bulk of the total workload.
+ Application level options are an important and practical tool for allowing
+ the benefits of synchronous replication for high performance applications.
+ </para>
+
+ <para>
+ You should consider that the network bandwidth must be higher than
+ the rate of generation of WAL data.
+ </para>
+
+ </sect3>
+
+ <sect3 id="synchronous-replication-ha">
+ <title>Planning for High Availability</title>
+
+ <para>
+ <varname>synchronous_standby_names</varname> specifies the number and
+ names of synchronous standbys that transaction commits made when
+ <varname>synchronous_commit</varname> is set to <literal>on</literal>,
+ <literal>remote_apply</literal> or <literal>remote_write</literal> will wait for
+ responses from. Such transaction commits may never be completed
+ if any one of synchronous standbys should crash.
+ </para>
+
+ <para>
+ The best solution for high availability is to ensure you keep as many
+ synchronous standbys as requested. This can be achieved by naming multiple
+ potential synchronous standbys using <varname>synchronous_standby_names</varname>.
+ </para>
+
+ <para>
+ In a priority-based synchronous replication, the standbys whose names
+ appear earlier in the list will be used as synchronous standbys.
+ Standbys listed after these will take over the role of synchronous standby
+ if one of current ones should fail.
+ </para>
+
+ <para>
+ In a quorum-based synchronous replication, all the standbys appearing
+ in the list will be used as candidates for synchronous standbys.
+ Even if one of them should fail, the other standbys will keep performing
+ the role of candidates of synchronous standby.
+ </para>
+
+ <para>
+ When a standby first attaches to the primary, it will not yet be properly
+ synchronized. This is described as <literal>catchup</literal> mode. Once
+ the lag between standby and primary reaches zero for the first time
+ we move to real-time <literal>streaming</literal> state.
+ The catch-up duration may be long immediately after the standby has
+ been created. If the standby is shut down, then the catch-up period
+ will increase according to the length of time the standby has been down.
+ The standby is only able to become a synchronous standby
+ once it has reached <literal>streaming</literal> state.
+ This state can be viewed using
+ the <structname>pg_stat_replication</structname> view.
+ </para>
+
+ <para>
+ If primary restarts while commits are waiting for acknowledgment, those
+ waiting transactions will be marked fully committed once the primary
+ database recovers.
+ There is no way to be certain that all standbys have received all
+ outstanding WAL data at time of the crash of the primary. Some
+ transactions may not show as committed on the standby, even though
+ they show as committed on the primary. The guarantee we offer is that
+ the application will not receive explicit acknowledgment of the
+ successful commit of a transaction until the WAL data is known to be
+ safely received by all the synchronous standbys.
+ </para>
+
+ <para>
+ If you really cannot keep as many synchronous standbys as requested
+ then you should decrease the number of synchronous standbys that
+ transaction commits must wait for responses from
+ in <varname>synchronous_standby_names</varname> (or disable it) and
+ reload the configuration file on the primary server.
+ </para>
+
+ <para>
+ If the primary is isolated from remaining standby servers you should
+ fail over to the best candidate of those other remaining standby servers.
+ </para>
+
+ <para>
+ If you need to re-create a standby server while transactions are
+ waiting, make sure that the commands pg_backup_start() and
+ pg_backup_stop() are run in a session with
+ <varname>synchronous_commit</varname> = <literal>off</literal>, otherwise those
+ requests will wait forever for the standby to appear.
+ </para>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="continuous-archiving-in-standby">
+ <title>Continuous Archiving in Standby</title>
+
+ <indexterm>
+ <primary>continuous archiving</primary>
+ <secondary>in standby</secondary>
+ </indexterm>
+
+ <para>
+ When continuous WAL archiving is used in a standby, there are two
+ different scenarios: the WAL archive can be shared between the primary
+ and the standby, or the standby can have its own WAL archive. When
+ the standby has its own WAL archive, set <varname>archive_mode</varname>
+ to <literal>always</literal>, and the standby will call the archive
+ command for every WAL segment it receives, whether it's by restoring
+ from the archive or by streaming replication. The shared archive can
+ be handled similarly, but the <varname>archive_command</varname> or <varname>archive_library</varname> must
+ test if the file being archived exists already, and if the existing file
+ has identical contents. This requires more care in the
+ <varname>archive_command</varname> or <varname>archive_library</varname>, as it must
+ be careful to not overwrite an existing file with different contents,
+ but return success if the exactly same file is archived twice. And
+ all that must be done free of race conditions, if two servers attempt
+ to archive the same file at the same time.
+ </para>
+
+ <para>
+ If <varname>archive_mode</varname> is set to <literal>on</literal>, the
+ archiver is not enabled during recovery or standby mode. If the standby
+ server is promoted, it will start archiving after the promotion, but
+ will not archive any WAL or timeline history files that
+ it did not generate itself. To get a complete
+ series of WAL files in the archive, you must ensure that all WAL is
+ archived, before it reaches the standby. This is inherently true with
+ file-based log shipping, as the standby can only restore files that
+ are found in the archive, but not if streaming replication is enabled.
+ When a server is not in recovery mode, there is no difference between
+ <literal>on</literal> and <literal>always</literal> modes.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="warm-standby-failover">
+ <title>Failover</title>
+
+ <para>
+ If the primary server fails then the standby server should begin
+ failover procedures.
+ </para>
+
+ <para>
+ If the standby server fails then no failover need take place. If the
+ standby server can be restarted, even some time later, then the recovery
+ process can also be restarted immediately, taking advantage of
+ restartable recovery. If the standby server cannot be restarted, then a
+ full new standby server instance should be created.
+ </para>
+
+ <para>
+ If the primary server fails and the standby server becomes the
+ new primary, and then the old primary restarts, you must have
+ a mechanism for informing the old primary that it is no longer the primary. This is
+ sometimes known as <acronym>STONITH</acronym> (Shoot The Other Node In The Head), which is
+ necessary to avoid situations where both systems think they are the
+ primary, which will lead to confusion and ultimately data loss.
+ </para>
+
+ <para>
+ Many failover systems use just two systems, the primary and the standby,
+ connected by some kind of heartbeat mechanism to continually verify the
+ connectivity between the two and the viability of the primary. It is
+ also possible to use a third system (called a witness server) to prevent
+ some cases of inappropriate failover, but the additional complexity
+ might not be worthwhile unless it is set up with sufficient care and
+ rigorous testing.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> does not provide the system
+ software required to identify a failure on the primary and notify
+ the standby database server. Many such tools exist and are well
+ integrated with the operating system facilities required for
+ successful failover, such as IP address migration.
+ </para>
+
+ <para>
+ Once failover to the standby occurs, there is only a
+ single server in operation. This is known as a degenerate state.
+ The former standby is now the primary, but the former primary is down
+ and might stay down. To return to normal operation, a standby server
+ must be recreated,
+ either on the former primary system when it comes up, or on a third,
+ possibly new, system. The <xref linkend="app-pgrewind"/> utility can be
+ used to speed up this process on large clusters.
+ Once complete, the primary and standby can be
+ considered to have switched roles. Some people choose to use a third
+ server to provide backup for the new primary until the new standby
+ server is recreated,
+ though clearly this complicates the system configuration and
+ operational processes.
+ </para>
+
+ <para>
+ So, switching from primary to standby server can be fast but requires
+ some time to re-prepare the failover cluster. Regular switching from
+ primary to standby is useful, since it allows regular downtime on
+ each system for maintenance. This also serves as a test of the
+ failover mechanism to ensure that it will really work when you need it.
+ Written administration procedures are advised.
+ </para>
+
+ <para>
+ To trigger failover of a log-shipping standby server, run
+ <command>pg_ctl promote</command>, call <function>pg_promote()</function>,
+ or create a trigger file with the file name and path specified by the
+ <varname>promote_trigger_file</varname>. If you're planning to use
+ <command>pg_ctl promote</command> or to call
+ <function>pg_promote()</function> to fail over,
+ <varname>promote_trigger_file</varname> is not required. If you're
+ setting up the reporting servers that are only used to offload read-only
+ queries from the primary, not for high availability purposes, you don't
+ need to promote it.
+ </para>
+ </sect1>
+
+ <sect1 id="hot-standby">
+ <title>Hot Standby</title>
+
+ <indexterm zone="high-availability">
+ <primary>hot standby</primary>
+ </indexterm>
+
+ <para>
+ Hot standby is the term used to describe the ability to connect to
+ the server and run read-only queries while the server is in archive
+ recovery or standby mode. This
+ is useful both for replication purposes and for restoring a backup
+ to a desired state with great precision.
+ The term hot standby also refers to the ability of the server to move
+ from recovery through to normal operation while users continue running
+ queries and/or keep their connections open.
+ </para>
+
+ <para>
+ Running queries in hot standby mode is similar to normal query operation,
+ though there are several usage and administrative differences
+ explained below.
+ </para>
+
+ <sect2 id="hot-standby-users">
+ <title>User's Overview</title>
+
+ <para>
+ When the <xref linkend="guc-hot-standby"/> parameter is set to true on a
+ standby server, it will begin accepting connections once the recovery has
+ brought the system to a consistent state. All such connections are
+ strictly read-only; not even temporary tables may be written.
+ </para>
+
+ <para>
+ The data on the standby takes some time to arrive from the primary server
+ so there will be a measurable delay between primary and standby. Running the
+ same query nearly simultaneously on both primary and standby might therefore
+ return differing results. We say that data on the standby is
+ <firstterm>eventually consistent</firstterm> with the primary. Once the
+ commit record for a transaction is replayed on the standby, the changes
+ made by that transaction will be visible to any new snapshots taken on
+ the standby. Snapshots may be taken at the start of each query or at the
+ start of each transaction, depending on the current transaction isolation
+ level. For more details, see <xref linkend="transaction-iso"/>.
+ </para>
+
+ <para>
+ Transactions started during hot standby may issue the following commands:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Query access: <command>SELECT</command>, <command>COPY TO</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Cursor commands: <command>DECLARE</command>, <command>FETCH</command>, <command>CLOSE</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Settings: <command>SHOW</command>, <command>SET</command>, <command>RESET</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Transaction management commands:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <command>BEGIN</command>, <command>END</command>, <command>ABORT</command>, <command>START TRANSACTION</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>SAVEPOINT</command>, <command>RELEASE</command>, <command>ROLLBACK TO SAVEPOINT</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>EXCEPTION</command> blocks and other internal subtransactions
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>LOCK TABLE</command>, though only when explicitly in one of these modes:
+ <literal>ACCESS SHARE</literal>, <literal>ROW SHARE</literal> or <literal>ROW EXCLUSIVE</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Plans and resources: <command>PREPARE</command>, <command>EXECUTE</command>,
+ <command>DEALLOCATE</command>, <command>DISCARD</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Plugins and extensions: <command>LOAD</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>UNLISTEN</command>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Transactions started during hot standby will never be assigned a
+ transaction ID and cannot write to the system write-ahead log.
+ Therefore, the following actions will produce error messages:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Data Manipulation Language (DML): <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>,
+ <command>MERGE</command>, <command>COPY FROM</command>,
+ <command>TRUNCATE</command>.
+ Note that there are no allowed actions that result in a trigger
+ being executed during recovery. This restriction applies even to
+ temporary tables, because table rows cannot be read or written without
+ assigning a transaction ID, which is currently not possible in a
+ hot standby environment.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Data Definition Language (DDL): <command>CREATE</command>,
+ <command>DROP</command>, <command>ALTER</command>, <command>COMMENT</command>.
+ This restriction applies even to temporary tables, because carrying
+ out these operations would require updating the system catalog tables.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>SELECT ... FOR SHARE | UPDATE</command>, because row locks cannot be
+ taken without updating the underlying data files.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Rules on <command>SELECT</command> statements that generate DML commands.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>LOCK</command> that explicitly requests a mode higher than <literal>ROW EXCLUSIVE MODE</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>LOCK</command> in short default form, since it requests <literal>ACCESS EXCLUSIVE MODE</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Transaction management commands that explicitly set non-read-only state:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <command>BEGIN READ WRITE</command>,
+ <command>START TRANSACTION READ WRITE</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>SET TRANSACTION READ WRITE</command>,
+ <command>SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>SET transaction_read_only = off</command>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Two-phase commit commands: <command>PREPARE TRANSACTION</command>,
+ <command>COMMIT PREPARED</command>, <command>ROLLBACK PREPARED</command>
+ because even read-only transactions need to write WAL in the
+ prepare phase (the first phase of two phase commit).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Sequence updates: <function>nextval()</function>, <function>setval()</function>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>LISTEN</command>, <command>NOTIFY</command>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In normal operation, <quote>read-only</quote> transactions are allowed to
+ use <command>LISTEN</command> and <command>NOTIFY</command>,
+ so hot standby sessions operate under slightly tighter
+ restrictions than ordinary read-only sessions. It is possible that some
+ of these restrictions might be loosened in a future release.
+ </para>
+
+ <para>
+ During hot standby, the parameter <varname>transaction_read_only</varname> is always
+ true and may not be changed. But as long as no attempt is made to modify
+ the database, connections during hot standby will act much like any other
+ database connection. If failover or switchover occurs, the database will
+ switch to normal processing mode. Sessions will remain connected while the
+ server changes mode. Once hot standby finishes, it will be possible to
+ initiate read-write transactions (even from a session begun during
+ hot standby).
+ </para>
+
+ <para>
+ Users can determine whether hot standby is currently active for their
+ session by issuing <command>SHOW in_hot_standby</command>.
+ (In server versions before 14, the <varname>in_hot_standby</varname>
+ parameter did not exist; a workable substitute method for older servers
+ is <command>SHOW transaction_read_only</command>.) In addition, a set of
+ functions (<xref linkend="functions-recovery-info-table"/>) allow users to
+ access information about the standby server. These allow you to write
+ programs that are aware of the current state of the database. These
+ can be used to monitor the progress of recovery, or to allow you to
+ write complex programs that restore the database to particular states.
+ </para>
+ </sect2>
+
+ <sect2 id="hot-standby-conflict">
+ <title>Handling Query Conflicts</title>
+
+ <para>
+ The primary and standby servers are in many ways loosely connected. Actions
+ on the primary will have an effect on the standby. As a result, there is
+ potential for negative interactions or conflicts between them. The easiest
+ conflict to understand is performance: if a huge data load is taking place
+ on the primary then this will generate a similar stream of WAL records on the
+ standby, so standby queries may contend for system resources, such as I/O.
+ </para>
+
+ <para>
+ There are also additional types of conflict that can occur with hot standby.
+ These conflicts are <emphasis>hard conflicts</emphasis> in the sense that queries
+ might need to be canceled and, in some cases, sessions disconnected to resolve them.
+ The user is provided with several ways to handle these
+ conflicts. Conflict cases include:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Access Exclusive locks taken on the primary server, including both
+ explicit <command>LOCK</command> commands and various <acronym>DDL</acronym>
+ actions, conflict with table accesses in standby queries.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Dropping a tablespace on the primary conflicts with standby queries
+ using that tablespace for temporary work files.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Dropping a database on the primary conflicts with sessions connected
+ to that database on the standby.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Application of a vacuum cleanup record from WAL conflicts with
+ standby transactions whose snapshots can still <quote>see</quote> any of
+ the rows to be removed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Application of a vacuum cleanup record from WAL conflicts with
+ queries accessing the target page on the standby, whether or not
+ the data to be removed is visible.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ On the primary server, these cases simply result in waiting; and the
+ user might choose to cancel either of the conflicting actions. However,
+ on the standby there is no choice: the WAL-logged action already occurred
+ on the primary so the standby must not fail to apply it. Furthermore,
+ allowing WAL application to wait indefinitely may be very undesirable,
+ because the standby's state will become increasingly far behind the
+ primary's. Therefore, a mechanism is provided to forcibly cancel standby
+ queries that conflict with to-be-applied WAL records.
+ </para>
+
+ <para>
+ An example of the problem situation is an administrator on the primary
+ server running <command>DROP TABLE</command> on a table that is currently being
+ queried on the standby server. Clearly the standby query cannot continue
+ if the <command>DROP TABLE</command> is applied on the standby. If this situation
+ occurred on the primary, the <command>DROP TABLE</command> would wait until the
+ other query had finished. But when <command>DROP TABLE</command> is run on the
+ primary, the primary doesn't have information about what queries are
+ running on the standby, so it will not wait for any such standby
+ queries. The WAL change records come through to the standby while the
+ standby query is still running, causing a conflict. The standby server
+ must either delay application of the WAL records (and everything after
+ them, too) or else cancel the conflicting query so that the <command>DROP
+ TABLE</command> can be applied.
+ </para>
+
+ <para>
+ When a conflicting query is short, it's typically desirable to allow it to
+ complete by delaying WAL application for a little bit; but a long delay in
+ WAL application is usually not desirable. So the cancel mechanism has
+ parameters, <xref linkend="guc-max-standby-archive-delay"/> and <xref
+ linkend="guc-max-standby-streaming-delay"/>, that define the maximum
+ allowed delay in WAL application. Conflicting queries will be canceled
+ once it has taken longer than the relevant delay setting to apply any
+ newly-received WAL data. There are two parameters so that different delay
+ values can be specified for the case of reading WAL data from an archive
+ (i.e., initial recovery from a base backup or <quote>catching up</quote> a
+ standby server that has fallen far behind) versus reading WAL data via
+ streaming replication.
+ </para>
+
+ <para>
+ In a standby server that exists primarily for high availability, it's
+ best to set the delay parameters relatively short, so that the server
+ cannot fall far behind the primary due to delays caused by standby
+ queries. However, if the standby server is meant for executing
+ long-running queries, then a high or even infinite delay value may be
+ preferable. Keep in mind however that a long-running query could
+ cause other sessions on the standby server to not see recent changes
+ on the primary, if it delays application of WAL records.
+ </para>
+
+ <para>
+ Once the delay specified by <varname>max_standby_archive_delay</varname> or
+ <varname>max_standby_streaming_delay</varname> has been exceeded, conflicting
+ queries will be canceled. This usually results just in a cancellation
+ error, although in the case of replaying a <command>DROP DATABASE</command>
+ the entire conflicting session will be terminated. Also, if the conflict
+ is over a lock held by an idle transaction, the conflicting session is
+ terminated (this behavior might change in the future).
+ </para>
+
+ <para>
+ Canceled queries may be retried immediately (after beginning a new
+ transaction, of course). Since query cancellation depends on
+ the nature of the WAL records being replayed, a query that was
+ canceled may well succeed if it is executed again.
+ </para>
+
+ <para>
+ Keep in mind that the delay parameters are compared to the elapsed time
+ since the WAL data was received by the standby server. Thus, the grace
+ period allowed to any one query on the standby is never more than the
+ delay parameter, and could be considerably less if the standby has already
+ fallen behind as a result of waiting for previous queries to complete, or
+ as a result of being unable to keep up with a heavy update load.
+ </para>
+
+ <para>
+ The most common reason for conflict between standby queries and WAL replay
+ is <quote>early cleanup</quote>. Normally, <productname>PostgreSQL</productname> allows
+ cleanup of old row versions when there are no transactions that need to
+ see them to ensure correct visibility of data according to MVCC rules.
+ However, this rule can only be applied for transactions executing on the
+ primary. So it is possible that cleanup on the primary will remove row
+ versions that are still visible to a transaction on the standby.
+ </para>
+
+ <para>
+ Experienced users should note that both row version cleanup and row version
+ freezing will potentially conflict with standby queries. Running a manual
+ <command>VACUUM FREEZE</command> is likely to cause conflicts even on tables with
+ no updated or deleted rows.
+ </para>
+
+ <para>
+ Users should be clear that tables that are regularly and heavily updated
+ on the primary server will quickly cause cancellation of longer running
+ queries on the standby. In such cases the setting of a finite value for
+ <varname>max_standby_archive_delay</varname> or
+ <varname>max_standby_streaming_delay</varname> can be considered similar to
+ setting <varname>statement_timeout</varname>.
+ </para>
+
+ <para>
+ Remedial possibilities exist if the number of standby-query cancellations
+ is found to be unacceptable. The first option is to set the parameter
+ <varname>hot_standby_feedback</varname>, which prevents <command>VACUUM</command> from
+ removing recently-dead rows and so cleanup conflicts do not occur.
+ If you do this, you
+ should note that this will delay cleanup of dead rows on the primary,
+ which may result in undesirable table bloat. However, the cleanup
+ situation will be no worse than if the standby queries were running
+ directly on the primary server, and you are still getting the benefit of
+ off-loading execution onto the standby.
+ If standby servers connect and disconnect frequently, you
+ might want to make adjustments to handle the period when
+ <varname>hot_standby_feedback</varname> feedback is not being provided.
+ For example, consider increasing <varname>max_standby_archive_delay</varname>
+ so that queries are not rapidly canceled by conflicts in WAL archive
+ files during disconnected periods. You should also consider increasing
+ <varname>max_standby_streaming_delay</varname> to avoid rapid cancellations
+ by newly-arrived streaming WAL entries after reconnection.
+ </para>
+
+ <para>
+ Another option is to increase <xref linkend="guc-vacuum-defer-cleanup-age"/>
+ on the primary server, so that dead rows will not be cleaned up as quickly
+ as they normally would be. This will allow more time for queries to
+ execute before they are canceled on the standby, without having to set
+ a high <varname>max_standby_streaming_delay</varname>. However it is
+ difficult to guarantee any specific execution-time window with this
+ approach, since <varname>vacuum_defer_cleanup_age</varname> is measured in
+ transactions executed on the primary server.
+ </para>
+
+ <para>
+ The number of query cancels and the reason for them can be viewed using
+ the <structname>pg_stat_database_conflicts</structname> system view on the standby
+ server. The <structname>pg_stat_database</structname> system view also contains
+ summary information.
+ </para>
+
+ <para>
+ Users can control whether a log message is produced when WAL replay is waiting
+ longer than <varname>deadlock_timeout</varname> for conflicts. This
+ is controlled by the <xref linkend="guc-log-recovery-conflict-waits"/> parameter.
+ </para>
+ </sect2>
+
+ <sect2 id="hot-standby-admin">
+ <title>Administrator's Overview</title>
+
+ <para>
+ If <varname>hot_standby</varname> is <literal>on</literal> in <filename>postgresql.conf</filename>
+ (the default value) and there is a
+ <link linkend="file-standby-signal"><filename>standby.signal</filename></link><indexterm><primary>standby.signal</primary><secondary>for hot standby</secondary></indexterm>
+ file present, the server will run in hot standby mode.
+ However, it may take some time for hot standby connections to be allowed,
+ because the server will not accept connections until it has completed
+ sufficient recovery to provide a consistent state against which queries
+ can run. During this period,
+ clients that attempt to connect will be refused with an error message.
+ To confirm the server has come up, either loop trying to connect from
+ the application, or look for these messages in the server logs:
+
+<programlisting>
+LOG: entering standby mode
+
+... then some time later ...
+
+LOG: consistent recovery state reached
+LOG: database system is ready to accept read-only connections
+</programlisting>
+
+ Consistency information is recorded once per checkpoint on the primary.
+ It is not possible to enable hot standby when reading WAL
+ written during a period when <varname>wal_level</varname> was not set to
+ <literal>replica</literal> or <literal>logical</literal> on the primary. Reaching
+ a consistent state can also be delayed in the presence of both of these
+ conditions:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A write transaction has more than 64 subtransactions
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Very long-lived write transactions
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ If you are running file-based log shipping ("warm standby"), you might need
+ to wait until the next WAL file arrives, which could be as long as the
+ <varname>archive_timeout</varname> setting on the primary.
+ </para>
+
+ <para>
+ The settings of some parameters determine the size of shared memory for
+ tracking transaction IDs, locks, and prepared transactions. These shared
+ memory structures must be no smaller on a standby than on the primary in
+ order to ensure that the standby does not run out of shared memory during
+ recovery. For example, if the primary had used a prepared transaction but
+ the standby had not allocated any shared memory for tracking prepared
+ transactions, then recovery could not continue until the standby's
+ configuration is changed. The parameters affected are:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <varname>max_connections</varname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <varname>max_prepared_transactions</varname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <varname>max_locks_per_transaction</varname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <varname>max_wal_senders</varname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <varname>max_worker_processes</varname>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ The easiest way to ensure this does not become a problem is to have these
+ parameters set on the standbys to values equal to or greater than on the
+ primary. Therefore, if you want to increase these values, you should do
+ so on all standby servers first, before applying the changes to the
+ primary server. Conversely, if you want to decrease these values, you
+ should do so on the primary server first, before applying the changes to
+ all standby servers. Keep in mind that when a standby is promoted, it
+ becomes the new reference for the required parameter settings for the
+ standbys that follow it. Therefore, to avoid this becoming a problem
+ during a switchover or failover, it is recommended to keep these settings
+ the same on all standby servers.
+ </para>
+
+ <para>
+ The WAL tracks changes to these parameters on the
+ primary. If a hot standby processes WAL that indicates that the current
+ value on the primary is higher than its own value, it will log a warning
+ and pause recovery, for example:
+<screen>
+WARNING: hot standby is not possible because of insufficient parameter settings
+DETAIL: max_connections = 80 is a lower setting than on the primary server, where its value was 100.
+LOG: recovery has paused
+DETAIL: If recovery is unpaused, the server will shut down.
+HINT: You can then restart the server after making the necessary configuration changes.
+</screen>
+ At that point, the settings on the standby need to be updated and the
+ instance restarted before recovery can continue. If the standby is not a
+ hot standby, then when it encounters the incompatible parameter change, it
+ will shut down immediately without pausing, since there is then no value
+ in keeping it up.
+ </para>
+
+ <para>
+ It is important that the administrator select appropriate settings for
+ <xref linkend="guc-max-standby-archive-delay"/> and <xref
+ linkend="guc-max-standby-streaming-delay"/>. The best choices vary
+ depending on business priorities. For example if the server is primarily
+ tasked as a High Availability server, then you will want low delay
+ settings, perhaps even zero, though that is a very aggressive setting. If
+ the standby server is tasked as an additional server for decision support
+ queries then it might be acceptable to set the maximum delay values to
+ many hours, or even -1 which means wait forever for queries to complete.
+ </para>
+
+ <para>
+ Transaction status "hint bits" written on the primary are not WAL-logged,
+ so data on the standby will likely re-write the hints again on the standby.
+ Thus, the standby server will still perform disk writes even though
+ all users are read-only; no changes occur to the data values
+ themselves. Users will still write large sort temporary files and
+ re-generate relcache info files, so no part of the database
+ is truly read-only during hot standby mode.
+ Note also that writes to remote databases using
+ <application>dblink</application> module, and other operations outside the
+ database using PL functions will still be possible, even though the
+ transaction is read-only locally.
+ </para>
+
+ <para>
+ The following types of administration commands are not accepted
+ during recovery mode:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Data Definition Language (DDL): e.g., <command>CREATE INDEX</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Privilege and Ownership: <command>GRANT</command>, <command>REVOKE</command>,
+ <command>REASSIGN</command>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Maintenance commands: <command>ANALYZE</command>, <command>VACUUM</command>,
+ <command>CLUSTER</command>, <command>REINDEX</command>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Again, note that some of these commands are actually allowed during
+ "read only" mode transactions on the primary.
+ </para>
+
+ <para>
+ As a result, you cannot create additional indexes that exist solely
+ on the standby, nor statistics that exist solely on the standby.
+ If these administration commands are needed, they should be executed
+ on the primary, and eventually those changes will propagate to the
+ standby.
+ </para>
+
+ <para>
+ <function>pg_cancel_backend()</function>
+ and <function>pg_terminate_backend()</function> will work on user backends,
+ but not the startup process, which performs
+ recovery. <structname>pg_stat_activity</structname> does not show
+ recovering transactions as active. As a result,
+ <structname>pg_prepared_xacts</structname> is always empty during
+ recovery. If you wish to resolve in-doubt prepared transactions, view
+ <literal>pg_prepared_xacts</literal> on the primary and issue commands to
+ resolve transactions there or resolve them after the end of recovery.
+ </para>
+
+ <para>
+ <structname>pg_locks</structname> will show locks held by backends,
+ as normal. <structname>pg_locks</structname> also shows
+ a virtual transaction managed by the startup process that owns all
+ <literal>AccessExclusiveLocks</literal> held by transactions being replayed by recovery.
+ Note that the startup process does not acquire locks to
+ make database changes, and thus locks other than <literal>AccessExclusiveLocks</literal>
+ do not show in <structname>pg_locks</structname> for the Startup
+ process; they are just presumed to exist.
+ </para>
+
+ <para>
+ The <productname>Nagios</productname> plugin <productname>check_pgsql</productname> will
+ work, because the simple information it checks for exists.
+ The <productname>check_postgres</productname> monitoring script will also work,
+ though some reported values could give different or confusing results.
+ For example, last vacuum time will not be maintained, since no
+ vacuum occurs on the standby. Vacuums running on the primary
+ do still send their changes to the standby.
+ </para>
+
+ <para>
+ WAL file control commands will not work during recovery,
+ e.g., <function>pg_backup_start</function>, <function>pg_switch_wal</function> etc.
+ </para>
+
+ <para>
+ Dynamically loadable modules work, including <structname>pg_stat_statements</structname>.
+ </para>
+
+ <para>
+ Advisory locks work normally in recovery, including deadlock detection.
+ Note that advisory locks are never WAL logged, so it is impossible for
+ an advisory lock on either the primary or the standby to conflict with WAL
+ replay. Nor is it possible to acquire an advisory lock on the primary
+ and have it initiate a similar advisory lock on the standby. Advisory
+ locks relate only to the server on which they are acquired.
+ </para>
+
+ <para>
+ Trigger-based replication systems such as <productname>Slony</productname>,
+ <productname>Londiste</productname> and <productname>Bucardo</productname> won't run on the
+ standby at all, though they will run happily on the primary server as
+ long as the changes are not sent to standby servers to be applied.
+ WAL replay is not trigger-based so you cannot relay from the
+ standby to any system that requires additional database writes or
+ relies on the use of triggers.
+ </para>
+
+ <para>
+ New OIDs cannot be assigned, though some <acronym>UUID</acronym> generators may still
+ work as long as they do not rely on writing new status to the database.
+ </para>
+
+ <para>
+ Currently, temporary table creation is not allowed during read-only
+ transactions, so in some cases existing scripts will not run correctly.
+ This restriction might be relaxed in a later release. This is
+ both an SQL standard compliance issue and a technical issue.
+ </para>
+
+ <para>
+ <command>DROP TABLESPACE</command> can only succeed if the tablespace is empty.
+ Some standby users may be actively using the tablespace via their
+ <varname>temp_tablespaces</varname> parameter. If there are temporary files in the
+ tablespace, all active queries are canceled to ensure that temporary
+ files are removed, so the tablespace can be removed and WAL replay
+ can continue.
+ </para>
+
+ <para>
+ Running <command>DROP DATABASE</command> or <command>ALTER DATABASE ... SET
+ TABLESPACE</command> on the primary
+ will generate a WAL entry that will cause all users connected to that
+ database on the standby to be forcibly disconnected. This action occurs
+ immediately, whatever the setting of
+ <varname>max_standby_streaming_delay</varname>. Note that
+ <command>ALTER DATABASE ... RENAME</command> does not disconnect users, which
+ in most cases will go unnoticed, though might in some cases cause a
+ program confusion if it depends in some way upon database name.
+ </para>
+
+ <para>
+ In normal (non-recovery) mode, if you issue <command>DROP USER</command> or <command>DROP ROLE</command>
+ for a role with login capability while that user is still connected then
+ nothing happens to the connected user &mdash; they remain connected. The user cannot
+ reconnect however. This behavior applies in recovery also, so a
+ <command>DROP USER</command> on the primary does not disconnect that user on the standby.
+ </para>
+
+ <para>
+ The cumulative statistics system is active during recovery. All scans,
+ reads, blocks, index usage, etc., will be recorded normally on the
+ standby. However, WAL replay will not increment relation and database
+ specific counters. I.e. replay will not increment pg_stat_all_tables
+ columns (like n_tup_ins), nor will reads or writes performed by the
+ startup process be tracked in the pg_statio views, nor will associated
+ pg_stat_database columns be incremented.
+ </para>
+
+ <para>
+ Autovacuum is not active during recovery. It will start normally at the
+ end of recovery.
+ </para>
+
+ <para>
+ The checkpointer process and the background writer process are active during
+ recovery. The checkpointer process will perform restartpoints (similar to
+ checkpoints on the primary) and the background writer process will perform
+ normal block cleaning activities. This can include updates of the hint bit
+ information stored on the standby server.
+ The <command>CHECKPOINT</command> command is accepted during recovery,
+ though it performs a restartpoint rather than a new checkpoint.
+ </para>
+ </sect2>
+
+ <sect2 id="hot-standby-parameters">
+ <title>Hot Standby Parameter Reference</title>
+
+ <para>
+ Various parameters have been mentioned above in
+ <xref linkend="hot-standby-conflict"/> and
+ <xref linkend="hot-standby-admin"/>.
+ </para>
+
+ <para>
+ On the primary, parameters <xref linkend="guc-wal-level"/> and
+ <xref linkend="guc-vacuum-defer-cleanup-age"/> can be used.
+ <xref linkend="guc-max-standby-archive-delay"/> and
+ <xref linkend="guc-max-standby-streaming-delay"/> have no effect if set on
+ the primary.
+ </para>
+
+ <para>
+ On the standby, parameters <xref linkend="guc-hot-standby"/>,
+ <xref linkend="guc-max-standby-archive-delay"/> and
+ <xref linkend="guc-max-standby-streaming-delay"/> can be used.
+ <xref linkend="guc-vacuum-defer-cleanup-age"/> has no effect
+ as long as the server remains in standby mode, though it will
+ become relevant if the standby becomes primary.
+ </para>
+ </sect2>
+
+ <sect2 id="hot-standby-caveats">
+ <title>Caveats</title>
+
+ <para>
+ There are several limitations of hot standby.
+ These can and probably will be fixed in future releases:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Full knowledge of running transactions is required before snapshots
+ can be taken. Transactions that use large numbers of subtransactions
+ (currently greater than 64) will delay the start of read-only
+ connections until the completion of the longest running write transaction.
+ If this situation occurs, explanatory messages will be sent to the server log.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Valid starting points for standby queries are generated at each
+ checkpoint on the primary. If the standby is shut down while the primary
+ is in a shutdown state, it might not be possible to re-enter hot standby
+ until the primary is started up, so that it generates further starting
+ points in the WAL logs. This situation isn't a problem in the most
+ common situations where it might happen. Generally, if the primary is
+ shut down and not available anymore, that's likely due to a serious
+ failure that requires the standby being converted to operate as
+ the new primary anyway. And in situations where the primary is
+ being intentionally taken down, coordinating to make sure the standby
+ becomes the new primary smoothly is also standard procedure.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ At the end of recovery, <literal>AccessExclusiveLocks</literal> held by prepared transactions
+ will require twice the normal number of lock table entries. If you plan
+ on running either a large number of concurrent prepared transactions
+ that normally take <literal>AccessExclusiveLocks</literal>, or you plan on having one
+ large transaction that takes many <literal>AccessExclusiveLocks</literal>, you are
+ advised to select a larger value of <varname>max_locks_per_transaction</varname>,
+ perhaps as much as twice the value of the parameter on
+ the primary server. You need not consider this at all if
+ your setting of <varname>max_prepared_transactions</varname> is 0.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The Serializable transaction isolation level is not yet available in hot
+ standby. (See <xref linkend="xact-serializable"/> and
+ <xref linkend="serializable-consistency"/> for details.)
+ An attempt to set a transaction to the serializable isolation level in
+ hot standby mode will generate an error.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </para>
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/history.sgml b/doc/src/sgml/history.sgml
new file mode 100644
index 0000000..120b4b3
--- /dev/null
+++ b/doc/src/sgml/history.sgml
@@ -0,0 +1,222 @@
+<!-- doc/src/sgml/history.sgml -->
+
+<sect1 id="history">
+ <title>A Brief History of <productname>PostgreSQL</productname></title>
+
+ <indexterm zone="history">
+ <primary>history</primary>
+ <secondary>of PostgreSQL</secondary>
+ </indexterm>
+
+ <para>
+ The object-relational database management system now known as
+ <productname>PostgreSQL</productname> is derived from the
+ <productname>POSTGRES</productname> package written at the
+ University of California at Berkeley. With decades of
+ development behind it, <productname>PostgreSQL</productname> is now
+ the most advanced open-source database available anywhere.
+ </para>
+
+ <sect2 id="history-berkeley">
+ <title>The Berkeley <productname>POSTGRES</productname> Project</title>
+
+ <indexterm zone="history-berkeley">
+ <primary>POSTGRES</primary>
+ </indexterm>
+
+ <para>
+ The <productname>POSTGRES</productname> project, led by Professor
+ Michael Stonebraker, was sponsored by the Defense Advanced Research
+ Projects Agency (<acronym>DARPA</acronym>), the Army Research
+ Office (<acronym>ARO</acronym>), the National Science Foundation
+ (<acronym>NSF</acronym>), and ESL, Inc. The implementation of
+ <productname>POSTGRES</productname> began in 1986. The initial
+ concepts for the system were presented in <xref linkend="ston86"/>,
+ and the definition of the initial data model appeared in <xref
+ linkend="rowe87"/>. The design of the rule system at that time was
+ described in <xref linkend="ston87a"/>. The rationale and
+ architecture of the storage manager were detailed in <xref
+ linkend="ston87b"/>.
+ </para>
+
+ <para>
+ <productname>POSTGRES</productname> has undergone several major
+ releases since then. The first <quote>demoware</quote> system
+ became operational in 1987 and was shown at the 1988
+ <acronym>ACM-SIGMOD</acronym> Conference. Version 1, described in
+ <xref linkend="ston90a"/>, was released to a few external users in
+ June 1989. In response to a critique of the first rule system
+ (<xref linkend="ston89"/>), the rule system was redesigned (<xref
+ linkend="ston90b"/>), and Version 2 was released in June 1990 with
+ the new rule system. Version 3 appeared in 1991 and added support
+ for multiple storage managers, an improved query executor, and a
+ rewritten rule system. For the most part, subsequent releases
+ until <productname>Postgres95</productname> (see below) focused on
+ portability and reliability.
+ </para>
+
+ <para>
+ <productname>POSTGRES</productname> has been used to implement many
+ different research and production applications. These include: a
+ financial data analysis system, a jet engine performance monitoring
+ package, an asteroid tracking database, a medical information
+ database, and several geographic information systems.
+ <productname>POSTGRES</productname> has also been used as an
+ educational tool at several universities. Finally, Illustra
+ Information Technologies (later merged into
+ <ulink url="https://www.ibm.com/analytics/informix"><productname>Informix</productname></ulink>,
+ which is now owned by <ulink
+ url="https://www.ibm.com/">IBM</ulink>) picked up the code and
+ commercialized it. In late 1992,
+ <productname>POSTGRES</productname> became the primary data manager
+ for the
+ <ulink url="http://meteora.ucsd.edu/s2k/s2k_home.html">
+ Sequoia 2000 scientific computing project</ulink>.
+ </para>
+
+ <para>
+ The size of the external user community nearly doubled during 1993.
+ It became increasingly obvious that maintenance of the prototype
+ code and support was taking up large amounts of time that should
+ have been devoted to database research. In an effort to reduce
+ this support burden, the Berkeley
+ <productname>POSTGRES</productname> project officially ended with
+ Version 4.2.
+ </para>
+ </sect2>
+
+ <sect2 id="history-postgres95">
+ <title><productname>Postgres95</productname></title>
+
+ <indexterm zone="history-postgres95">
+ <primary>Postgres95</primary>
+ </indexterm>
+
+ <para>
+ In 1994, Andrew Yu and Jolly Chen added an SQL language interpreter
+ to <productname>POSTGRES</productname>. Under a new name,
+ <productname>Postgres95</productname> was subsequently released to
+ the web to find its own way in the world as an open-source
+ descendant of the original <productname>POSTGRES</productname>
+ Berkeley code.
+ </para>
+
+ <para>
+ <productname>Postgres95</productname> code was completely ANSI C
+ and trimmed in size by 25%. Many internal changes improved
+ performance and
+ maintainability. <productname>Postgres95</productname> release
+ 1.0.x ran about 30&ndash;50% faster on the Wisconsin Benchmark compared
+ to <productname>POSTGRES</productname>, Version 4.2. Apart from
+ bug fixes, the following were the major enhancements:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The query language PostQUEL was replaced with
+ <acronym>SQL</acronym> (implemented in the server). (Interface
+ library <link linkend="libpq">libpq</link> was named after PostQUEL.)
+ Subqueries
+ were not supported until <productname>PostgreSQL</productname>
+ (see below), but they could be imitated in
+ <productname>Postgres95</productname> with user-defined
+ <acronym>SQL</acronym> functions. Aggregate functions were
+ re-implemented. Support for the <literal>GROUP BY</literal>
+ query clause was also added.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A new program
+ (<application>psql</application>) was provided for interactive
+ SQL queries, which used <acronym>GNU</acronym>
+ <application>Readline</application>. This largely superseded
+ the old <application>monitor</application> program.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A new front-end library, <filename>libpgtcl</filename>,
+ supported <acronym>Tcl</acronym>-based clients. A sample shell,
+ <command>pgtclsh</command>, provided new Tcl commands to
+ interface <application>Tcl</application> programs with the
+ <productname>Postgres95</productname> server.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The large-object interface was overhauled. The inversion large
+ objects were the only mechanism for storing large objects. (The
+ inversion file system was removed.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The instance-level rule system was removed. Rules were still
+ available as rewrite rules.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A short tutorial introducing regular <acronym>SQL</acronym>
+ features as well as those of
+ <productname>Postgres95</productname> was distributed with the
+ source code
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <acronym>GNU</acronym> make (instead of <acronym>BSD</acronym>
+ make) was used for the build. Also,
+ <productname>Postgres95</productname> could be compiled with an
+ unpatched <productname>GCC</productname> (data alignment of
+ doubles was fixed).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><productname>PostgreSQL</productname></title>
+
+ <para>
+ By 1996, it became clear that the name <quote>Postgres95</quote>
+ would not stand the test of time. We chose a new name,
+ <productname>PostgreSQL</productname>, to reflect the relationship
+ between the original <productname>POSTGRES</productname> and the
+ more recent versions with <acronym>SQL</acronym> capability. At
+ the same time, we set the version numbering to start at 6.0,
+ putting the numbers back into the sequence originally begun by the
+ Berkeley <productname>POSTGRES</productname> project.
+ </para>
+
+ <para>
+ Many people continue to refer to
+ <productname>PostgreSQL</productname> as <quote>Postgres</quote>
+ (now rarely in all capital letters) because of tradition or because
+ it is easier to pronounce. This usage is widely accepted as a
+ nickname or alias.
+ </para>
+
+ <para>
+ The emphasis during development of
+ <productname>Postgres95</productname> was on identifying and
+ understanding existing problems in the server code. With
+ <productname>PostgreSQL</productname>, the emphasis has shifted to
+ augmenting features and capabilities, although work continues in
+ all areas.
+ </para>
+
+ <para>
+ Details about what has happened in <productname>PostgreSQL</productname> since
+ then can be found in <xref linkend="release"/>.
+ </para>
+ </sect2>
+</sect1>
diff --git a/doc/src/sgml/hstore.sgml b/doc/src/sgml/hstore.sgml
new file mode 100644
index 0000000..335d646
--- /dev/null
+++ b/doc/src/sgml/hstore.sgml
@@ -0,0 +1,977 @@
+<!-- doc/src/sgml/hstore.sgml -->
+
+<sect1 id="hstore" xreflabel="hstore">
+ <title>hstore</title>
+
+ <indexterm zone="hstore">
+ <primary>hstore</primary>
+ </indexterm>
+
+ <para>
+ This module implements the <type>hstore</type> data type for storing sets of
+ key/value pairs within a single <productname>PostgreSQL</productname> value.
+ This can be useful in various scenarios, such as rows with many attributes
+ that are rarely examined, or semi-structured data. Keys and values are
+ simply text strings.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title><type>hstore</type> External Representation</title>
+
+ <para>
+
+ The text representation of an <type>hstore</type>, used for input and output,
+ includes zero or more <replaceable>key</replaceable> <literal>=&gt;</literal>
+ <replaceable>value</replaceable> pairs separated by commas. Some examples:
+
+<synopsis>
+k =&gt; v
+foo =&gt; bar, baz =&gt; whatever
+"1-a" =&gt; "anything at all"
+</synopsis>
+
+ The order of the pairs is not significant (and may not be reproduced on
+ output). Whitespace between pairs or around the <literal>=&gt;</literal> sign is
+ ignored. Double-quote keys and values that include whitespace, commas,
+ <literal>=</literal>s or <literal>&gt;</literal>s. To include a double quote or a
+ backslash in a key or value, escape it with a backslash.
+ </para>
+
+ <para>
+ Each key in an <type>hstore</type> is unique. If you declare an <type>hstore</type>
+ with duplicate keys, only one will be stored in the <type>hstore</type> and
+ there is no guarantee as to which will be kept:
+
+<programlisting>
+SELECT 'a=&gt;1,a=&gt;2'::hstore;
+ hstore
+----------
+ "a"=&gt;"1"
+</programlisting>
+ </para>
+
+ <para>
+ A value (but not a key) can be an SQL <literal>NULL</literal>. For example:
+
+<programlisting>
+key =&gt; NULL
+</programlisting>
+
+ The <literal>NULL</literal> keyword is case-insensitive. Double-quote the
+ <literal>NULL</literal> to treat it as the ordinary string <quote>NULL</quote>.
+ </para>
+
+ <note>
+ <para>
+ Keep in mind that the <type>hstore</type> text format, when used for input,
+ applies <emphasis>before</emphasis> any required quoting or escaping. If you are
+ passing an <type>hstore</type> literal via a parameter, then no additional
+ processing is needed. But if you're passing it as a quoted literal
+ constant, then any single-quote characters and (depending on the setting of
+ the <varname>standard_conforming_strings</varname> configuration parameter)
+ backslash characters need to be escaped correctly. See
+ <xref linkend="sql-syntax-strings"/> for more on the handling of string
+ constants.
+ </para>
+ </note>
+
+ <para>
+ On output, double quotes always surround keys and values, even when it's
+ not strictly necessary.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title><type>hstore</type> Operators and Functions</title>
+
+ <para>
+ The operators provided by the <literal>hstore</literal> module are
+ shown in <xref linkend="hstore-op-table"/>, the functions
+ in <xref linkend="hstore-func-table"/>.
+ </para>
+
+ <table id="hstore-op-table">
+ <title><type>hstore</type> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>-&gt;</literal> <type>text</type>
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns value associated with given key, or <literal>NULL</literal> if
+ not present.
+ </para>
+ <para>
+ <literal>'a=&gt;x, b=&gt;y'::hstore -&gt; 'a'</literal>
+ <returnvalue>x</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>-&gt;</literal> <type>text[]</type>
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Returns values associated with given keys, or <literal>NULL</literal>
+ if not present.
+ </para>
+ <para>
+ <literal>'a=&gt;x, b=&gt;y, c=&gt;z'::hstore -&gt; ARRAY['c','a']</literal>
+ <returnvalue>{"z","x"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>||</literal> <type>hstore</type>
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Concatenates two <type>hstore</type>s.
+ </para>
+ <para>
+ <literal>'a=&gt;b, c=&gt;d'::hstore || 'c=&gt;x, d=&gt;q'::hstore</literal>
+ <returnvalue>"a"=&gt;"b", "c"=&gt;"x", "d"=&gt;"q"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>?</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>hstore</type> contain key?
+ </para>
+ <para>
+ <literal>'a=&gt;1'::hstore ? 'a'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>?&amp;</literal> <type>text[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>hstore</type> contain all the specified keys?
+ </para>
+ <para>
+ <literal>'a=&gt;1,b=&gt;2'::hstore ?&amp; ARRAY['a','b']</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>?|</literal> <type>text[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>hstore</type> contain any of the specified keys?
+ </para>
+ <para>
+ <literal>'a=&gt;1,b=&gt;2'::hstore ?| ARRAY['b','c']</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>@&gt;</literal> <type>hstore</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does left operand contain right?
+ </para>
+ <para>
+ <literal>'a=&gt;b, b=&gt;1, c=&gt;NULL'::hstore @&gt; 'b=&gt;1'</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>&lt;@</literal> <type>hstore</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is left operand contained in right?
+ </para>
+ <para>
+ <literal>'a=&gt;c'::hstore &lt;@ 'a=&gt;b, b=&gt;1, c=&gt;NULL'</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>-</literal> <type>text</type>
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Deletes key from left operand.
+ </para>
+ <para>
+ <literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'b'::text</literal>
+ <returnvalue>"a"=&gt;"1", "c"=&gt;"3"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>-</literal> <type>text[]</type>
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Deletes keys from left operand.
+ </para>
+ <para>
+ <literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - ARRAY['a','b']</literal>
+ <returnvalue>"c"=&gt;"3"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>hstore</type> <literal>-</literal> <type>hstore</type>
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Deletes pairs from left operand that match pairs in the right operand.
+ </para>
+ <para>
+ <literal>'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'a=&gt;4, b=&gt;2'::hstore</literal>
+ <returnvalue>"a"=&gt;"1", "c"=&gt;"3"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>anyelement</type> <literal>#=</literal> <type>hstore</type>
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Replaces fields in the left operand (which must be a composite type)
+ with matching values from <type>hstore</type>.
+ </para>
+ <para>
+ <literal>ROW(1,3) #= 'f1=>11'::hstore</literal>
+ <returnvalue>(11,3)</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>%%</literal> <type>hstore</type>
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Converts <type>hstore</type> to an array of alternating keys and
+ values.
+ </para>
+ <para>
+ <literal>%% 'a=&gt;foo, b=&gt;bar'::hstore</literal>
+ <returnvalue>{a,foo,b,bar}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>%#</literal> <type>hstore</type>
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Converts <type>hstore</type> to a two-dimensional key/value array.
+ </para>
+ <para>
+ <literal>%# 'a=&gt;foo, b=&gt;bar'::hstore</literal>
+ <returnvalue>{{a,foo},{b,bar}}</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="hstore-func-table">
+ <title><type>hstore</type> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore</primary></indexterm>
+ <function>hstore</function> ( <type>record</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Constructs an <type>hstore</type> from a record or row.
+ </para>
+ <para>
+ <literal>hstore(ROW(1,2))</literal>
+ <returnvalue>"f1"=&gt;"1", "f2"=&gt;"2"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>hstore</function> ( <type>text[]</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Constructs an <type>hstore</type> from an array, which may be either
+ a key/value array, or a two-dimensional array.
+ </para>
+ <para>
+ <literal>hstore(ARRAY['a','1','b','2'])</literal>
+ <returnvalue>"a"=&gt;"1", "b"=&gt;"2"</returnvalue>
+ </para>
+ <para>
+ <literal>hstore(ARRAY[['c','3'],['d','4']])</literal>
+ <returnvalue>"c"=&gt;"3", "d"=&gt;"4"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>hstore</function> ( <type>text[]</type>, <type>text[]</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Constructs an <type>hstore</type> from separate key and value arrays.
+ </para>
+ <para>
+ <literal>hstore(ARRAY['a','b'], ARRAY['1','2'])</literal>
+ <returnvalue>"a"=&gt;"1", "b"=&gt;"2"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>hstore</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Makes a single-item <type>hstore</type>.
+ </para>
+ <para>
+ <literal>hstore('a', 'b')</literal>
+ <returnvalue>"a"=&gt;"b"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>akeys</primary></indexterm>
+ <function>akeys</function> ( <type>hstore</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s keys as an array.
+ </para>
+ <para>
+ <literal>akeys('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue>{a,b}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>skeys</primary></indexterm>
+ <function>skeys</function> ( <type>hstore</type> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s keys as a set.
+ </para>
+ <para>
+ <literal>skeys('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+a
+b
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>avals</primary></indexterm>
+ <function>avals</function> ( <type>hstore</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s values as an array.
+ </para>
+ <para>
+ <literal>avals('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue>{1,2}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>svals</primary></indexterm>
+ <function>svals</function> ( <type>hstore</type> )
+ <returnvalue>setof text</returnvalue>
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s values as a set.
+ </para>
+ <para>
+ <literal>svals('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+1
+2
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore_to_array</primary></indexterm>
+ <function>hstore_to_array</function> ( <type>hstore</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s keys and values as an array of
+ alternating keys and values.
+ </para>
+ <para>
+ <literal>hstore_to_array('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue>{a,1,b,2}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore_to_matrix</primary></indexterm>
+ <function>hstore_to_matrix</function> ( <type>hstore</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s keys and values as a two-dimensional
+ array.
+ </para>
+ <para>
+ <literal>hstore_to_matrix('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue>{{a,1},{b,2}}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore_to_json</primary></indexterm>
+ <function>hstore_to_json</function> ( <type>hstore</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para>
+ Converts an <type>hstore</type> to a <type>json</type> value,
+ converting all non-null values to JSON strings.
+ </para>
+ <para>
+ This function is used implicitly when an <type>hstore</type> value is
+ cast to <type>json</type>.
+ </para>
+ <para>
+ <literal>hstore_to_json('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</literal>
+ <returnvalue>{"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore_to_jsonb</primary></indexterm>
+ <function>hstore_to_jsonb</function> ( <type>hstore</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Converts an <type>hstore</type> to a <type>jsonb</type> value,
+ converting all non-null values to JSON strings.
+ </para>
+ <para>
+ This function is used implicitly when an <type>hstore</type> value is
+ cast to <type>jsonb</type>.
+ </para>
+ <para>
+ <literal>hstore_to_jsonb('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</literal>
+ <returnvalue>{"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore_to_json_loose</primary></indexterm>
+ <function>hstore_to_json_loose</function> ( <type>hstore</type> )
+ <returnvalue>json</returnvalue>
+ </para>
+ <para>
+ Converts an <type>hstore</type> to a <type>json</type> value, but
+ attempts to distinguish numerical and Boolean values so they are
+ unquoted in the JSON.
+ </para>
+ <para>
+ <literal>hstore_to_json_loose('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</literal>
+ <returnvalue>{"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>hstore_to_jsonb_loose</primary></indexterm>
+ <function>hstore_to_jsonb_loose</function> ( <type>hstore</type> )
+ <returnvalue>jsonb</returnvalue>
+ </para>
+ <para>
+ Converts an <type>hstore</type> to a <type>jsonb</type> value, but
+ attempts to distinguish numerical and Boolean values so they are
+ unquoted in the JSON.
+ </para>
+ <para>
+ <literal>hstore_to_jsonb_loose('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</literal>
+ <returnvalue>{"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>slice</primary></indexterm>
+ <function>slice</function> ( <type>hstore</type>, <type>text[]</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Extracts a subset of an <type>hstore</type> containing only the
+ specified keys.
+ </para>
+ <para>
+ <literal>slice('a=&gt;1,b=&gt;2,c=&gt;3'::hstore, ARRAY['b','c','x'])</literal>
+ <returnvalue>"b"=&gt;"2", "c"=&gt;"3"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>each</primary></indexterm>
+ <function>each</function> ( <type>hstore</type> )
+ <returnvalue>setof record</returnvalue>
+ ( <parameter>key</parameter> <type>text</type>,
+ <parameter>value</parameter> <type>text</type> )
+ </para>
+ <para>
+ Extracts an <type>hstore</type>'s keys and values as a set of records.
+ </para>
+ <para>
+ <literal>select * from each('a=&gt;1,b=&gt;2')</literal>
+ <returnvalue></returnvalue>
+<programlisting>
+ key | value
+-----+-------
+ a | 1
+ b | 2
+</programlisting>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>exist</primary></indexterm>
+ <function>exist</function> ( <type>hstore</type>, <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>hstore</type> contain key?
+ </para>
+ <para>
+ <literal>exist('a=&gt;1', 'a')</literal>
+ <returnvalue>t</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>defined</primary></indexterm>
+ <function>defined</function> ( <type>hstore</type>, <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>hstore</type> contain a non-<literal>NULL</literal> value
+ for key?
+ </para>
+ <para>
+ <literal>defined('a=&gt;NULL', 'a')</literal>
+ <returnvalue>f</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>delete</primary></indexterm>
+ <function>delete</function> ( <type>hstore</type>, <type>text</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Deletes pair with matching key.
+ </para>
+ <para>
+ <literal>delete('a=&gt;1,b=&gt;2', 'b')</literal>
+ <returnvalue>"a"=&gt;"1"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>delete</function> ( <type>hstore</type>, <type>text[]</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Deletes pairs with matching keys.
+ </para>
+ <para>
+ <literal>delete('a=&gt;1,b=&gt;2,c=&gt;3', ARRAY['a','b'])</literal>
+ <returnvalue>"c"=&gt;"3"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>delete</function> ( <type>hstore</type>, <type>hstore</type> )
+ <returnvalue>hstore</returnvalue>
+ </para>
+ <para>
+ Deletes pairs matching those in the second argument.
+ </para>
+ <para>
+ <literal>delete('a=&gt;1,b=&gt;2', 'a=&gt;4,b=&gt;2'::hstore)</literal>
+ <returnvalue>"a"=&gt;"1"</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>populate_record</primary></indexterm>
+ <function>populate_record</function> ( <type>anyelement</type>, <type>hstore</type> )
+ <returnvalue>anyelement</returnvalue>
+ </para>
+ <para>
+ Replaces fields in the left operand (which must be a composite type)
+ with matching values from <type>hstore</type>.
+ </para>
+ <para>
+ <literal>populate_record(ROW(1,2), 'f1=>42'::hstore)</literal>
+ <returnvalue>(42,2)</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In addition to these operators and functions, values of
+ the <type>hstore</type> type can be subscripted, allowing them to act
+ like associative arrays. Only a single subscript of type <type>text</type>
+ can be specified; it is interpreted as a key and the corresponding
+ value is fetched or stored. For example,
+
+<programlisting>
+CREATE TABLE mytable (h hstore);
+INSERT INTO mytable VALUES ('a=>b, c=>d');
+SELECT h['a'] FROM mytable;
+ h
+---
+ b
+(1 row)
+
+UPDATE mytable SET h['c'] = 'new';
+SELECT h FROM mytable;
+ h
+----------------------
+ "a"=>"b", "c"=>"new"
+(1 row)
+</programlisting>
+
+ A subscripted fetch returns <literal>NULL</literal> if the subscript
+ is <literal>NULL</literal> or that key does not exist in
+ the <type>hstore</type>. (Thus, a subscripted fetch is not greatly
+ different from the <literal>-&gt;</literal> operator.)
+ A subscripted update fails if the subscript is <literal>NULL</literal>;
+ otherwise, it replaces the value for that key, adding an entry to
+ the <type>hstore</type> if the key does not already exist.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Indexes</title>
+
+ <para>
+ <type>hstore</type> has GiST and GIN index support for the <literal>@&gt;</literal>,
+ <literal>?</literal>, <literal>?&amp;</literal> and <literal>?|</literal> operators. For example:
+ </para>
+<programlisting>
+CREATE INDEX hidx ON testhstore USING GIST (h);
+
+CREATE INDEX hidx ON testhstore USING GIN (h);
+</programlisting>
+
+ <para>
+ <literal>gist_hstore_ops</literal> GiST opclass approximates a set of
+ key/value pairs as a bitmap signature. Its optional integer parameter
+ <literal>siglen</literal> determines the
+ signature length in bytes. The default length is 16 bytes.
+ Valid values of signature length are between 1 and 2024 bytes. Longer
+ signatures lead to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </para>
+
+ <para>
+ Example of creating such an index with a signature length of 32 bytes:
+<programlisting>
+CREATE INDEX hidx ON testhstore USING GIST (h gist_hstore_ops(siglen=32));
+</programlisting>
+ </para>
+
+ <para>
+ <type>hstore</type> also supports <type>btree</type> or <type>hash</type> indexes for
+ the <literal>=</literal> operator. This allows <type>hstore</type> columns to be
+ declared <literal>UNIQUE</literal>, or to be used in <literal>GROUP BY</literal>,
+ <literal>ORDER BY</literal> or <literal>DISTINCT</literal> expressions. The sort ordering
+ for <type>hstore</type> values is not particularly useful, but these indexes
+ may be useful for equivalence lookups. Create indexes for <literal>=</literal>
+ comparisons as follows:
+ </para>
+<programlisting>
+CREATE INDEX hidx ON testhstore USING BTREE (h);
+
+CREATE INDEX hidx ON testhstore USING HASH (h);
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>
+ Add a key, or update an existing key with a new value:
+<programlisting>
+UPDATE tab SET h['c'] = '3';
+</programlisting>
+ Another way to do the same thing is:
+<programlisting>
+UPDATE tab SET h = h || hstore('c', '3');
+</programlisting>
+ If multiple keys are to be added or changed in one operation,
+ the concatenation approach is more efficient than subscripting:
+<programlisting>
+UPDATE tab SET h = h || hstore(array['q', 'w'], array['11', '12']);
+</programlisting>
+ </para>
+
+ <para>
+ Delete a key:
+<programlisting>
+UPDATE tab SET h = delete(h, 'k1');
+</programlisting>
+ </para>
+
+ <para>
+ Convert a <type>record</type> to an <type>hstore</type>:
+<programlisting>
+CREATE TABLE test (col1 integer, col2 text, col3 text);
+INSERT INTO test VALUES (123, 'foo', 'bar');
+
+SELECT hstore(t) FROM test AS t;
+ hstore
+---------------------------------------------
+ "col1"=&gt;"123", "col2"=&gt;"foo", "col3"=&gt;"bar"
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Convert an <type>hstore</type> to a predefined <type>record</type> type:
+<programlisting>
+CREATE TABLE test (col1 integer, col2 text, col3 text);
+
+SELECT * FROM populate_record(null::test,
+ '"col1"=&gt;"456", "col2"=&gt;"zzz"');
+ col1 | col2 | col3
+------+------+------
+ 456 | zzz |
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Modify an existing record using the values from an <type>hstore</type>:
+<programlisting>
+CREATE TABLE test (col1 integer, col2 text, col3 text);
+INSERT INTO test VALUES (123, 'foo', 'bar');
+
+SELECT (r).* FROM (SELECT t #= '"col3"=&gt;"baz"' AS r FROM test t) s;
+ col1 | col2 | col3
+------+------+------
+ 123 | foo | baz
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Statistics</title>
+
+ <para>
+ The <type>hstore</type> type, because of its intrinsic liberality, could
+ contain a lot of different keys. Checking for valid keys is the task of the
+ application. The following examples demonstrate several techniques for
+ checking keys and obtaining statistics.
+ </para>
+
+ <para>
+ Simple example:
+<programlisting>
+SELECT * FROM each('aaa=&gt;bq, b=&gt;NULL, ""=&gt;1');
+</programlisting>
+ </para>
+
+ <para>
+ Using a table:
+<programlisting>
+CREATE TABLE stat AS SELECT (each(h)).key, (each(h)).value FROM testhstore;
+</programlisting>
+ </para>
+
+ <para>
+ Online statistics:
+<programlisting>
+SELECT key, count(*) FROM
+ (SELECT (each(h)).key FROM testhstore) AS stat
+ GROUP BY key
+ ORDER BY count DESC, key;
+ key | count
+-----------+-------
+ line | 883
+ query | 207
+ pos | 203
+ node | 202
+ space | 197
+ status | 195
+ public | 194
+ title | 190
+ org | 189
+...................
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Compatibility</title>
+
+ <para>
+ As of PostgreSQL 9.0, <type>hstore</type> uses a different internal
+ representation than previous versions. This presents no obstacle for
+ dump/restore upgrades since the text representation (used in the dump) is
+ unchanged.
+ </para>
+
+ <para>
+ In the event of a binary upgrade, upward compatibility is maintained by
+ having the new code recognize old-format data. This will entail a slight
+ performance penalty when processing data that has not yet been modified by
+ the new code. It is possible to force an upgrade of all values in a table
+ column by doing an <literal>UPDATE</literal> statement as follows:
+<programlisting>
+UPDATE tablename SET hstorecol = hstorecol || '';
+</programlisting>
+ </para>
+
+ <para>
+ Another way to do it is:
+<programlisting>
+ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
+</programlisting>
+ The <command>ALTER TABLE</command> method requires an
+ <literal>ACCESS EXCLUSIVE</literal> lock on the table,
+ but does not result in bloating the table with old row versions.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Transforms</title>
+
+ <para>
+ Additional extensions are available that implement transforms for
+ the <type>hstore</type> type for the languages PL/Perl and PL/Python. The
+ extensions for PL/Perl are called <literal>hstore_plperl</literal>
+ and <literal>hstore_plperlu</literal>, for trusted and untrusted PL/Perl.
+ If you install these transforms and specify them when creating a
+ function, <type>hstore</type> values are mapped to Perl hashes. The
+ extension for PL/Python is called <literal>hstore_plpython3u</literal>.
+ If you use it, <type>hstore</type> values are mapped to Python dictionaries.
+ </para>
+
+ <caution>
+ <para>
+ It is strongly recommended that the transform extensions be installed in
+ the same schema as <filename>hstore</filename>. Otherwise there are
+ installation-time security hazards if a transform extension's schema
+ contains objects defined by a hostile user.
+ </para>
+ </caution>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Oleg Bartunov <email>oleg@sai.msu.su</email>, Moscow, Moscow University, Russia
+ </para>
+
+ <para>
+ Teodor Sigaev <email>teodor@sigaev.ru</email>, Moscow, Delta-Soft Ltd., Russia
+ </para>
+
+ <para>
+ Additional enhancements by Andrew Gierth <email>andrew@tao11.riddles.org.uk</email>,
+ United Kingdom
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/html-stamp b/doc/src/sgml/html-stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/src/sgml/html-stamp
diff --git a/doc/src/sgml/html/acronyms.html b/doc/src/sgml/html/acronyms.html
new file mode 100644
index 0000000..a028302
--- /dev/null
+++ b/doc/src/sgml/html/acronyms.html
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix L. Acronyms</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="limits.html" title="Appendix K. PostgreSQL Limits" /><link rel="next" href="glossary.html" title="Appendix M. Glossary" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix L. Acronyms</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="limits.html" title="Appendix K. PostgreSQL Limits">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="glossary.html" title="Appendix M. Glossary">Next</a></td></tr></table><hr /></div><div class="appendix" id="ACRONYMS"><div class="titlepage"><div><div><h2 class="title">Appendix L. Acronyms</h2></div></div></div><p>
+ This is a list of acronyms commonly used in the <span class="productname">PostgreSQL</span>
+ documentation and in discussions about <span class="productname">PostgreSQL</span>.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><acronym class="acronym">ANSI</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/American_National_Standards_Institute" target="_top">
+ American National Standards Institute</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">API</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/API" target="_top">Application Programming Interface</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ASCII</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Ascii" target="_top">American Standard
+ Code for Information Interchange</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">BKI</acronym></span></dt><dd><p>
+ <a class="link" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Backend Interface</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CA</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Certificate_authority" target="_top">Certificate Authority</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CIDR</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing" target="_top">Classless
+ Inter-Domain Routing</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CPAN</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://www.cpan.org/" target="_top">Comprehensive Perl Archive Network</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CRL</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Certificate_revocation_list" target="_top">Certificate
+ Revocation List</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CSV</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Comma-separated_values" target="_top">Comma
+ Separated Values</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CTE</acronym></span></dt><dd><p>
+ <a class="link" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Common Table Expression</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">CVE</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://cve.mitre.org/" target="_top">Common Vulnerabilities and Exposures</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">DBA</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Database_administrator" target="_top">Database
+ Administrator</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">DBI</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://dbi.perl.org/" target="_top">Database Interface (Perl)</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">DBMS</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Dbms" target="_top">Database Management
+ System</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">DDL</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Data_Definition_Language" target="_top">Data
+ Definition Language</a>, SQL commands such as <code class="command">CREATE
+ TABLE</code>, <code class="command">ALTER USER</code>
+ </p></dd><dt><span class="term"><acronym class="acronym">DML</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Data_Manipulation_Language" target="_top">Data
+ Manipulation Language</a>, SQL commands such as <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>
+ </p></dd><dt><span class="term"><acronym class="acronym">DST</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Daylight_saving_time" target="_top">Daylight
+ Saving Time</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ECPG</acronym></span></dt><dd><p>
+ <a class="link" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Embedded C for PostgreSQL</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ESQL</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Embedded_SQL" target="_top">Embedded
+ SQL</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">FAQ</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/FAQ" target="_top">Frequently Asked
+ Questions</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">FSM</acronym></span></dt><dd><p>
+ <a class="link" href="storage-fsm.html" title="73.3. Free Space Map">Free Space Map</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">GEQO</acronym></span></dt><dd><p>
+ <a class="link" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Genetic Query Optimizer</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">GIN</acronym></span></dt><dd><p>
+ <a class="link" href="gin.html" title="Chapter 70. GIN Indexes">Generalized Inverted Index</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">GiST</acronym></span></dt><dd><p>
+ <a class="link" href="gist.html" title="Chapter 68. GiST Indexes">Generalized Search Tree</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">Git</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Git_(software)" target="_top">Git</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">GMT</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/GMT" target="_top">Greenwich Mean Time</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">GSSAPI</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface" target="_top">Generic
+ Security Services Application Programming Interface</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">GUC</acronym></span></dt><dd><p>
+ <a class="link" href="config-setting.html" title="20.1. Setting Parameters">Grand Unified Configuration</a>,
+ the <span class="productname">PostgreSQL</span> subsystem that handles server configuration
+ </p></dd><dt><span class="term"><acronym class="acronym">HBA</acronym></span></dt><dd><p>
+ <a class="link" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Host-Based Authentication</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">HOT</acronym></span></dt><dd><p>
+ <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">Heap-Only Tuples</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">IEC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/International_Electrotechnical_Commission" target="_top">International
+ Electrotechnical Commission</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">IEEE</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://standards.ieee.org/" target="_top">Institute of Electrical and
+ Electronics Engineers</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">IPC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Inter-process_communication" target="_top">Inter-Process
+ Communication</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ISO</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://www.iso.org/home.html" target="_top">International Organization for
+ Standardization</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ISSN</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Issn" target="_top">International Standard
+ Serial Number</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">JDBC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Java_Database_Connectivity" target="_top">Java
+ Database Connectivity</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">JIT</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Just-in-time_compilation" target="_top">Just-in-Time
+ compilation</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">JSON</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://www.json.org" target="_top">JavaScript Object Notation</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">LDAP</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol" target="_top">Lightweight
+ Directory Access Protocol</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">LSN</acronym></span></dt><dd><p>
+ Log Sequence Number, see <a class="link" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type"><code class="type">pg_lsn</code></a>
+ and <a class="link" href="wal-internals.html" title="30.6. WAL Internals">WAL Internals</a>.
+ </p></dd><dt><span class="term"><acronym class="acronym">MITM</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack" target="_top">
+ Man-in-the-middle attack</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">MSVC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Visual_C++" target="_top"><span class="productname">Microsoft
+ Visual C</span></a>
+ </p></dd><dt><span class="term"><acronym class="acronym">MVCC</acronym></span></dt><dd><p>
+ <a class="link" href="mvcc.html" title="Chapter 13. Concurrency Control">Multi-Version Concurrency Control</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">NLS</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Internationalization_and_localization" target="_top">National
+ Language Support</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ODBC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Open_Database_Connectivity" target="_top">Open
+ Database Connectivity</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">OID</acronym></span></dt><dd><p>
+ <a class="link" href="datatype-oid.html" title="8.19. Object Identifier Types">Object Identifier</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">OLAP</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Olap" target="_top">Online Analytical
+ Processing</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">OLTP</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/OLTP" target="_top">Online Transaction
+ Processing</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">ORDBMS</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/ORDBMS" target="_top">Object-Relational
+ Database Management System</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">PAM</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Pluggable_Authentication_Modules" target="_top">Pluggable
+ Authentication Modules</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">PGSQL</acronym></span></dt><dd><p>
+ <a class="link" href="index.html" title="PostgreSQL 15.4 Documentation"><span class="productname">PostgreSQL</span></a>
+ </p></dd><dt><span class="term"><acronym class="acronym">PGXS</acronym></span></dt><dd><p>
+ <a class="link" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure"><span class="productname">PostgreSQL</span> Extension System</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">PID</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Process_identifier" target="_top">Process Identifier</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">PITR</acronym></span></dt><dd><p>
+ <a class="link" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Point-In-Time
+ Recovery</a> (Continuous Archiving)
+ </p></dd><dt><span class="term"><acronym class="acronym">PL</acronym></span></dt><dd><p>
+ <a class="link" href="server-programming.html" title="Part V. Server Programming">Procedural Languages (server-side)</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">POSIX</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/POSIX" target="_top">Portable Operating
+ System Interface</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">RDBMS</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Relational_database_management_system" target="_top">Relational
+ Database Management System</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">RFC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Request_for_Comments" target="_top">Request For
+ Comments</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SGML</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/SGML" target="_top">Standard Generalized
+ Markup Language</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SNI</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Server_Name_Indication" target="_top">
+ Server Name Indication</a>,
+ <a class="ulink" href="https://tools.ietf.org/html/rfc6066#section-3" target="_top">RFC 6066</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SPI</acronym></span></dt><dd><p>
+ <a class="link" href="spi.html" title="Chapter 47. Server Programming Interface">Server Programming Interface</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SP-GiST</acronym></span></dt><dd><p>
+ <a class="link" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Space-Partitioned Generalized Search Tree</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SQL</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/SQL" target="_top">Structured Query Language</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SRF</acronym></span></dt><dd><p>
+ <a class="link" href="xfunc-c.html#XFUNC-C-RETURN-SET" title="38.10.8. Returning Sets">Set-Returning Function</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SSH</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Secure_Shell" target="_top">Secure
+ Shell</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SSL</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Secure_Sockets_Layer" target="_top">Secure Sockets Layer</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SSPI</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://msdn.microsoft.com/en-us/library/aa380493%28VS.85%29.aspx" target="_top">Security
+ Support Provider Interface</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">SYSV</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/System_V" target="_top">Unix System V</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">TCP/IP</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol" target="_top">Transmission
+ Control Protocol (TCP) / Internet Protocol (IP)</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">TID</acronym></span></dt><dd><p>
+ <a class="link" href="datatype-oid.html" title="8.19. Object Identifier Types">Tuple Identifier</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">TLS</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Transport_Layer_Security" target="_top">
+ Transport Layer Security</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">TOAST</acronym></span></dt><dd><p>
+ <a class="link" href="storage-toast.html" title="73.2. TOAST">The Oversized-Attribute Storage Technique</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">TPC</acronym></span></dt><dd><p>
+ <a class="ulink" href="http://www.tpc.org/" target="_top">Transaction Processing
+ Performance Council</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">URL</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/URL" target="_top">Uniform Resource
+ Locator</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">UTC</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Coordinated_Universal_Time" target="_top">Coordinated
+ Universal Time</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">UTF</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://www.unicode.org/" target="_top">Unicode Transformation
+ Format</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">UTF8</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Utf8" target="_top">Eight-Bit Unicode
+ Transformation Format</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">UUID</acronym></span></dt><dd><p>
+ <a class="link" href="datatype-uuid.html" title="8.12. UUID Type">Universally Unique Identifier</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">WAL</acronym></span></dt><dd><p>
+ <a class="link" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Write-Ahead Log</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">XID</acronym></span></dt><dd><p>
+ <a class="link" href="datatype-oid.html" title="8.19. Object Identifier Types">Transaction Identifier</a>
+ </p></dd><dt><span class="term"><acronym class="acronym">XML</acronym></span></dt><dd><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/XML" target="_top">Extensible Markup
+ Language</a>
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="limits.html" title="Appendix K. PostgreSQL Limits">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="glossary.html" title="Appendix M. Glossary">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix K. <span class="productname">PostgreSQL</span> Limits </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix M. Glossary</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/admin.html b/doc/src/sgml/html/admin.html
new file mode 100644
index 0000000..e97fda2
--- /dev/null
+++ b/doc/src/sgml/html/admin.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part III. Server Administration</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="parallel-safety.html" title="15.4. Parallel Safety" /><link rel="next" href="install-binaries.html" title="Chapter 16. Installation from Binaries" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part III. Server Administration</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="parallel-safety.html" title="15.4. Parallel Safety">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-binaries.html" title="Chapter 16. Installation from Binaries">Next</a></td></tr></table><hr /></div><div class="part" id="ADMIN"><div class="titlepage"><div><div><h1 class="title">Part III. Server Administration</h1></div></div></div><div class="partintro" id="id-1.6.2"><div></div><p>
+ This part covers topics that are of interest to a
+ <span class="productname">PostgreSQL</span> database administrator. This includes
+ installation of the software, set up and configuration of the
+ server, management of users and databases, and maintenance tasks.
+ Anyone who runs a <span class="productname">PostgreSQL</span> server, even for
+ personal use, but especially in production, should be familiar
+ with the topics covered in this part.
+ </p><p>
+ The information in this part is arranged approximately in the
+ order in which a new user should read it. But the chapters are
+ self-contained and can be read individually as desired. The
+ information in this part is presented in a narrative fashion in
+ topical units. Readers looking for a complete description of a
+ particular command should see <a class="xref" href="reference.html" title="Part VI. Reference">Part VI</a>.
+ </p><p>
+ The first few chapters are written so they can be understood
+ without prerequisite knowledge, so new users who need to set
+ up their own server can begin their exploration with this part.
+ The rest of this part is about tuning and management; that material
+ assumes that the reader is familiar with the general use of
+ the <span class="productname">PostgreSQL</span> database system. Readers are
+ encouraged to look at <a class="xref" href="tutorial.html" title="Part I. Tutorial">Part I</a> and <a class="xref" href="sql.html" title="Part II. The SQL Language">Part II</a> for additional information.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="install-binaries.html">16. Installation from Binaries</a></span></dt><dt><span class="chapter"><a href="installation.html">17. Installation from Source Code</a></span></dt><dd><dl><dt><span class="sect1"><a href="install-short.html">17.1. Short Version</a></span></dt><dt><span class="sect1"><a href="install-requirements.html">17.2. Requirements</a></span></dt><dt><span class="sect1"><a href="install-getsource.html">17.3. Getting the Source</a></span></dt><dt><span class="sect1"><a href="install-procedure.html">17.4. Installation Procedure</a></span></dt><dt><span class="sect1"><a href="install-post.html">17.5. Post-Installation Setup</a></span></dt><dt><span class="sect1"><a href="supported-platforms.html">17.6. Supported Platforms</a></span></dt><dt><span class="sect1"><a href="installation-platform-notes.html">17.7. Platform-Specific Notes</a></span></dt></dl></dd><dt><span class="chapter"><a href="install-windows.html">18. Installation from Source Code on <span class="productname">Windows</span></a></span></dt><dd><dl><dt><span class="sect1"><a href="install-windows-full.html">18.1. Building with <span class="productname">Visual C++</span> or the
+ <span class="productname">Microsoft Windows SDK</span></a></span></dt></dl></dd><dt><span class="chapter"><a href="runtime.html">19. Server Setup and Operation</a></span></dt><dd><dl><dt><span class="sect1"><a href="postgres-user.html">19.1. The <span class="productname">PostgreSQL</span> User Account</a></span></dt><dt><span class="sect1"><a href="creating-cluster.html">19.2. Creating a Database Cluster</a></span></dt><dt><span class="sect1"><a href="server-start.html">19.3. Starting the Database Server</a></span></dt><dt><span class="sect1"><a href="kernel-resources.html">19.4. Managing Kernel Resources</a></span></dt><dt><span class="sect1"><a href="server-shutdown.html">19.5. Shutting Down the Server</a></span></dt><dt><span class="sect1"><a href="upgrading.html">19.6. Upgrading a <span class="productname">PostgreSQL</span> Cluster</a></span></dt><dt><span class="sect1"><a href="preventing-server-spoofing.html">19.7. Preventing Server Spoofing</a></span></dt><dt><span class="sect1"><a href="encryption-options.html">19.8. Encryption Options</a></span></dt><dt><span class="sect1"><a href="ssl-tcp.html">19.9. Secure TCP/IP Connections with SSL</a></span></dt><dt><span class="sect1"><a href="gssapi-enc.html">19.10. Secure TCP/IP Connections with GSSAPI Encryption</a></span></dt><dt><span class="sect1"><a href="ssh-tunnels.html">19.11. Secure TCP/IP Connections with <span class="application">SSH</span> Tunnels</a></span></dt><dt><span class="sect1"><a href="event-log-registration.html">19.12. Registering <span class="application">Event Log</span> on <span class="systemitem">Windows</span></a></span></dt></dl></dd><dt><span class="chapter"><a href="runtime-config.html">20. Server Configuration</a></span></dt><dd><dl><dt><span class="sect1"><a href="config-setting.html">20.1. Setting Parameters</a></span></dt><dt><span class="sect1"><a href="runtime-config-file-locations.html">20.2. File Locations</a></span></dt><dt><span class="sect1"><a href="runtime-config-connection.html">20.3. Connections and Authentication</a></span></dt><dt><span class="sect1"><a href="runtime-config-resource.html">20.4. Resource Consumption</a></span></dt><dt><span class="sect1"><a href="runtime-config-wal.html">20.5. Write Ahead Log</a></span></dt><dt><span class="sect1"><a href="runtime-config-replication.html">20.6. Replication</a></span></dt><dt><span class="sect1"><a href="runtime-config-query.html">20.7. Query Planning</a></span></dt><dt><span class="sect1"><a href="runtime-config-logging.html">20.8. Error Reporting and Logging</a></span></dt><dt><span class="sect1"><a href="runtime-config-statistics.html">20.9. Run-time Statistics</a></span></dt><dt><span class="sect1"><a href="runtime-config-autovacuum.html">20.10. Automatic Vacuuming</a></span></dt><dt><span class="sect1"><a href="runtime-config-client.html">20.11. Client Connection Defaults</a></span></dt><dt><span class="sect1"><a href="runtime-config-locks.html">20.12. Lock Management</a></span></dt><dt><span class="sect1"><a href="runtime-config-compatible.html">20.13. Version and Platform Compatibility</a></span></dt><dt><span class="sect1"><a href="runtime-config-error-handling.html">20.14. Error Handling</a></span></dt><dt><span class="sect1"><a href="runtime-config-preset.html">20.15. Preset Options</a></span></dt><dt><span class="sect1"><a href="runtime-config-custom.html">20.16. Customized Options</a></span></dt><dt><span class="sect1"><a href="runtime-config-developer.html">20.17. Developer Options</a></span></dt><dt><span class="sect1"><a href="runtime-config-short.html">20.18. Short Options</a></span></dt></dl></dd><dt><span class="chapter"><a href="client-authentication.html">21. Client Authentication</a></span></dt><dd><dl><dt><span class="sect1"><a href="auth-pg-hba-conf.html">21.1. The <code class="filename">pg_hba.conf</code> File</a></span></dt><dt><span class="sect1"><a href="auth-username-maps.html">21.2. User Name Maps</a></span></dt><dt><span class="sect1"><a href="auth-methods.html">21.3. Authentication Methods</a></span></dt><dt><span class="sect1"><a href="auth-trust.html">21.4. Trust Authentication</a></span></dt><dt><span class="sect1"><a href="auth-password.html">21.5. Password Authentication</a></span></dt><dt><span class="sect1"><a href="gssapi-auth.html">21.6. GSSAPI Authentication</a></span></dt><dt><span class="sect1"><a href="sspi-auth.html">21.7. SSPI Authentication</a></span></dt><dt><span class="sect1"><a href="auth-ident.html">21.8. Ident Authentication</a></span></dt><dt><span class="sect1"><a href="auth-peer.html">21.9. Peer Authentication</a></span></dt><dt><span class="sect1"><a href="auth-ldap.html">21.10. LDAP Authentication</a></span></dt><dt><span class="sect1"><a href="auth-radius.html">21.11. RADIUS Authentication</a></span></dt><dt><span class="sect1"><a href="auth-cert.html">21.12. Certificate Authentication</a></span></dt><dt><span class="sect1"><a href="auth-pam.html">21.13. PAM Authentication</a></span></dt><dt><span class="sect1"><a href="auth-bsd.html">21.14. BSD Authentication</a></span></dt><dt><span class="sect1"><a href="client-authentication-problems.html">21.15. Authentication Problems</a></span></dt></dl></dd><dt><span class="chapter"><a href="user-manag.html">22. Database Roles</a></span></dt><dd><dl><dt><span class="sect1"><a href="database-roles.html">22.1. Database Roles</a></span></dt><dt><span class="sect1"><a href="role-attributes.html">22.2. Role Attributes</a></span></dt><dt><span class="sect1"><a href="role-membership.html">22.3. Role Membership</a></span></dt><dt><span class="sect1"><a href="role-removal.html">22.4. Dropping Roles</a></span></dt><dt><span class="sect1"><a href="predefined-roles.html">22.5. Predefined Roles</a></span></dt><dt><span class="sect1"><a href="perm-functions.html">22.6. Function Security</a></span></dt></dl></dd><dt><span class="chapter"><a href="managing-databases.html">23. Managing Databases</a></span></dt><dd><dl><dt><span class="sect1"><a href="manage-ag-overview.html">23.1. Overview</a></span></dt><dt><span class="sect1"><a href="manage-ag-createdb.html">23.2. Creating a Database</a></span></dt><dt><span class="sect1"><a href="manage-ag-templatedbs.html">23.3. Template Databases</a></span></dt><dt><span class="sect1"><a href="manage-ag-config.html">23.4. Database Configuration</a></span></dt><dt><span class="sect1"><a href="manage-ag-dropdb.html">23.5. Destroying a Database</a></span></dt><dt><span class="sect1"><a href="manage-ag-tablespaces.html">23.6. Tablespaces</a></span></dt></dl></dd><dt><span class="chapter"><a href="charset.html">24. Localization</a></span></dt><dd><dl><dt><span class="sect1"><a href="locale.html">24.1. Locale Support</a></span></dt><dt><span class="sect1"><a href="collation.html">24.2. Collation Support</a></span></dt><dt><span class="sect1"><a href="multibyte.html">24.3. Character Set Support</a></span></dt></dl></dd><dt><span class="chapter"><a href="maintenance.html">25. Routine Database Maintenance Tasks</a></span></dt><dd><dl><dt><span class="sect1"><a href="routine-vacuuming.html">25.1. Routine Vacuuming</a></span></dt><dt><span class="sect1"><a href="routine-reindex.html">25.2. Routine Reindexing</a></span></dt><dt><span class="sect1"><a href="logfile-maintenance.html">25.3. Log File Maintenance</a></span></dt></dl></dd><dt><span class="chapter"><a href="backup.html">26. Backup and Restore</a></span></dt><dd><dl><dt><span class="sect1"><a href="backup-dump.html">26.1. <acronym class="acronym">SQL</acronym> Dump</a></span></dt><dt><span class="sect1"><a href="backup-file.html">26.2. File System Level Backup</a></span></dt><dt><span class="sect1"><a href="continuous-archiving.html">26.3. Continuous Archiving and Point-in-Time Recovery (PITR)</a></span></dt></dl></dd><dt><span class="chapter"><a href="high-availability.html">27. High Availability, Load Balancing, and Replication</a></span></dt><dd><dl><dt><span class="sect1"><a href="different-replication-solutions.html">27.1. Comparison of Different Solutions</a></span></dt><dt><span class="sect1"><a href="warm-standby.html">27.2. Log-Shipping Standby Servers</a></span></dt><dt><span class="sect1"><a href="warm-standby-failover.html">27.3. Failover</a></span></dt><dt><span class="sect1"><a href="hot-standby.html">27.4. Hot Standby</a></span></dt></dl></dd><dt><span class="chapter"><a href="monitoring.html">28. Monitoring Database Activity</a></span></dt><dd><dl><dt><span class="sect1"><a href="monitoring-ps.html">28.1. Standard Unix Tools</a></span></dt><dt><span class="sect1"><a href="monitoring-stats.html">28.2. The Cumulative Statistics System</a></span></dt><dt><span class="sect1"><a href="monitoring-locks.html">28.3. Viewing Locks</a></span></dt><dt><span class="sect1"><a href="progress-reporting.html">28.4. Progress Reporting</a></span></dt><dt><span class="sect1"><a href="dynamic-trace.html">28.5. Dynamic Tracing</a></span></dt></dl></dd><dt><span class="chapter"><a href="diskusage.html">29. Monitoring Disk Usage</a></span></dt><dd><dl><dt><span class="sect1"><a href="disk-usage.html">29.1. Determining Disk Usage</a></span></dt><dt><span class="sect1"><a href="disk-full.html">29.2. Disk Full Failure</a></span></dt></dl></dd><dt><span class="chapter"><a href="wal.html">30. Reliability and the Write-Ahead Log</a></span></dt><dd><dl><dt><span class="sect1"><a href="wal-reliability.html">30.1. Reliability</a></span></dt><dt><span class="sect1"><a href="checksums.html">30.2. Data Checksums</a></span></dt><dt><span class="sect1"><a href="wal-intro.html">30.3. Write-Ahead Logging (<acronym class="acronym">WAL</acronym>)</a></span></dt><dt><span class="sect1"><a href="wal-async-commit.html">30.4. Asynchronous Commit</a></span></dt><dt><span class="sect1"><a href="wal-configuration.html">30.5. <acronym class="acronym">WAL</acronym> Configuration</a></span></dt><dt><span class="sect1"><a href="wal-internals.html">30.6. WAL Internals</a></span></dt></dl></dd><dt><span class="chapter"><a href="logical-replication.html">31. Logical Replication</a></span></dt><dd><dl><dt><span class="sect1"><a href="logical-replication-publication.html">31.1. Publication</a></span></dt><dt><span class="sect1"><a href="logical-replication-subscription.html">31.2. Subscription</a></span></dt><dt><span class="sect1"><a href="logical-replication-row-filter.html">31.3. Row Filters</a></span></dt><dt><span class="sect1"><a href="logical-replication-col-lists.html">31.4. Column Lists</a></span></dt><dt><span class="sect1"><a href="logical-replication-conflicts.html">31.5. Conflicts</a></span></dt><dt><span class="sect1"><a href="logical-replication-restrictions.html">31.6. Restrictions</a></span></dt><dt><span class="sect1"><a href="logical-replication-architecture.html">31.7. Architecture</a></span></dt><dt><span class="sect1"><a href="logical-replication-monitoring.html">31.8. Monitoring</a></span></dt><dt><span class="sect1"><a href="logical-replication-security.html">31.9. Security</a></span></dt><dt><span class="sect1"><a href="logical-replication-config.html">31.10. Configuration Settings</a></span></dt><dt><span class="sect1"><a href="logical-replication-quick-setup.html">31.11. Quick Setup</a></span></dt></dl></dd><dt><span class="chapter"><a href="jit.html">32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</a></span></dt><dd><dl><dt><span class="sect1"><a href="jit-reason.html">32.1. What Is <acronym class="acronym">JIT</acronym> compilation?</a></span></dt><dt><span class="sect1"><a href="jit-decision.html">32.2. When to <acronym class="acronym">JIT</acronym>?</a></span></dt><dt><span class="sect1"><a href="jit-configuration.html">32.3. Configuration</a></span></dt><dt><span class="sect1"><a href="jit-extensibility.html">32.4. Extensibility</a></span></dt></dl></dd><dt><span class="chapter"><a href="regress.html">33. Regression Tests</a></span></dt><dd><dl><dt><span class="sect1"><a href="regress-run.html">33.1. Running the Tests</a></span></dt><dt><span class="sect1"><a href="regress-evaluation.html">33.2. Test Evaluation</a></span></dt><dt><span class="sect1"><a href="regress-variant.html">33.3. Variant Comparison Files</a></span></dt><dt><span class="sect1"><a href="regress-tap.html">33.4. TAP Tests</a></span></dt><dt><span class="sect1"><a href="regress-coverage.html">33.5. Test Coverage Examination</a></span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="parallel-safety.html" title="15.4. Parallel Safety">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-binaries.html" title="Chapter 16. Installation from Binaries">Next</a></td></tr><tr><td width="40%" align="left" valign="top">15.4. Parallel Safety </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 16. Installation from Binaries</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/adminpack.html b/doc/src/sgml/html/adminpack.html
new file mode 100644
index 0000000..556d3ba
--- /dev/null
+++ b/doc/src/sgml/html/adminpack.html
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.1. adminpack</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib.html" title="Appendix F. Additional Supplied Modules" /><link rel="next" href="amcheck.html" title="F.2. amcheck" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.1. adminpack</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib.html" title="Appendix F. Additional Supplied Modules">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="amcheck.html" title="F.2. amcheck">Next</a></td></tr></table><hr /></div><div class="sect1" id="ADMINPACK"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.1. adminpack</h2></div></div></div><a id="id-1.11.7.10.2" class="indexterm"></a><p>
+ <code class="filename">adminpack</code> provides a number of support functions which
+ <span class="application">pgAdmin</span> and other administration and management tools can
+ use to provide additional functionality, such as remote management
+ of server log files.
+ Use of all these functions is only allowed to the superuser by default but may be
+ allowed to other users by using the <code class="command">GRANT</code> command.
+ </p><p>
+ The functions shown in <a class="xref" href="adminpack.html#FUNCTIONS-ADMINPACK-TABLE" title="Table F.1. adminpack Functions">Table F.1</a> provide
+ write access to files on the machine hosting the server. (See also the
+ functions in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE-TABLE" title="Table 9.99. Generic File Access Functions">Table 9.99</a>, which
+ provide read-only access.)
+ Only files within the database cluster directory can be accessed, unless the
+ user is a superuser or given privileges of one of the
+ <code class="literal">pg_read_server_files</code> or
+ <code class="literal">pg_write_server_files</code> roles, as appropriate for the
+ function, but either a relative or absolute path is allowable.
+ </p><div class="table" id="FUNCTIONS-ADMINPACK-TABLE"><p class="title"><strong>Table F.1. <code class="filename">adminpack</code> Functions</strong></p><div class="table-contents"><table class="table" summary="adminpack Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_catalog.pg_file_write</code> ( <em class="parameter"><code>filename</code></em> <code class="type">text</code>, <em class="parameter"><code>data</code></em> <code class="type">text</code>, <em class="parameter"><code>append</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Writes, or appends to, a text file.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_catalog.pg_file_sync</code> ( <em class="parameter"><code>filename</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Flushes a file or directory to disk.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_catalog.pg_file_rename</code> ( <em class="parameter"><code>oldname</code></em> <code class="type">text</code>, <em class="parameter"><code>newname</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>archivename</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Renames a file.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_catalog.pg_file_unlink</code> ( <em class="parameter"><code>filename</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Removes a file.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_catalog.pg_logdir_ls</code> ()
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Lists the log files in the <code class="varname">log_directory</code> directory.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><a id="id-1.11.7.10.6" class="indexterm"></a><p>
+ <code class="function">pg_file_write</code> writes the specified <em class="parameter"><code>data</code></em> into
+ the file named by <em class="parameter"><code>filename</code></em>. If <em class="parameter"><code>append</code></em> is
+ false, the file must not already exist. If <em class="parameter"><code>append</code></em> is true,
+ the file can already exist, and will be appended to if so.
+ Returns the number of bytes written.
+ </p><a id="id-1.11.7.10.8" class="indexterm"></a><p>
+ <code class="function">pg_file_sync</code> fsyncs the specified file or directory
+ named by <em class="parameter"><code>filename</code></em>. An error is thrown
+ on failure (e.g., the specified file is not present). Note that
+ <a class="xref" href="runtime-config-error-handling.html#GUC-DATA-SYNC-RETRY">data_sync_retry</a> has no effect on this function,
+ and therefore a PANIC-level error will not be raised even on failure to
+ flush database files.
+ </p><a id="id-1.11.7.10.10" class="indexterm"></a><p>
+ <code class="function">pg_file_rename</code> renames a file. If <em class="parameter"><code>archivename</code></em>
+ is omitted or NULL, it simply renames <em class="parameter"><code>oldname</code></em>
+ to <em class="parameter"><code>newname</code></em> (which must not already exist).
+ If <em class="parameter"><code>archivename</code></em> is provided, it first
+ renames <em class="parameter"><code>newname</code></em> to <em class="parameter"><code>archivename</code></em> (which must
+ not already exist), and then renames <em class="parameter"><code>oldname</code></em>
+ to <em class="parameter"><code>newname</code></em>. In event of failure of the second rename step,
+ it will try to rename <em class="parameter"><code>archivename</code></em> back
+ to <em class="parameter"><code>newname</code></em> before reporting the error.
+ Returns true on success, false if the source file(s) are not present or
+ not writable; other cases throw errors.
+ </p><a id="id-1.11.7.10.12" class="indexterm"></a><p>
+ <code class="function">pg_file_unlink</code> removes the specified file.
+ Returns true on success, false if the specified file is not present
+ or the <code class="function">unlink()</code> call fails; other cases throw errors.
+ </p><a id="id-1.11.7.10.14" class="indexterm"></a><p>
+ <code class="function">pg_logdir_ls</code> returns the start timestamps and path
+ names of all the log files in the <a class="xref" href="runtime-config-logging.html#GUC-LOG-DIRECTORY">log_directory</a>
+ directory. The <a class="xref" href="runtime-config-logging.html#GUC-LOG-FILENAME">log_filename</a> parameter must have its
+ default setting (<code class="literal">postgresql-%Y-%m-%d_%H%M%S.log</code>) to use this
+ function.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib.html" title="Appendix F. Additional Supplied Modules">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="amcheck.html" title="F.2. amcheck">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix F. Additional Supplied Modules </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.2. amcheck</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/amcheck.html b/doc/src/sgml/html/amcheck.html
new file mode 100644
index 0000000..6662420
--- /dev/null
+++ b/doc/src/sgml/html/amcheck.html
@@ -0,0 +1,377 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.2. amcheck</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="adminpack.html" title="F.1. adminpack" /><link rel="next" href="auth-delay.html" title="F.3. auth_delay" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.2. amcheck</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="adminpack.html" title="F.1. adminpack">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-delay.html" title="F.3. auth_delay">Next</a></td></tr></table><hr /></div><div class="sect1" id="AMCHECK"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.2. amcheck</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.8">F.2.1. Functions</a></span></dt><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.9">F.2.2. Optional <em class="parameter"><code>heapallindexed</code></em> Verification</a></span></dt><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.10">F.2.3. Using <code class="filename">amcheck</code> Effectively</a></span></dt><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.11">F.2.4. Repairing Corruption</a></span></dt></dl></div><a id="id-1.11.7.11.2" class="indexterm"></a><p>
+ The <code class="filename">amcheck</code> module provides functions that allow you to
+ verify the logical consistency of the structure of relations.
+ </p><p>
+ The B-Tree checking functions verify various <span class="emphasis"><em>invariants</em></span> in the
+ structure of the representation of particular relations. The
+ correctness of the access method functions behind index scans and
+ other important operations relies on these invariants always
+ holding. For example, certain functions verify, among other things,
+ that all B-Tree pages have items in <span class="quote">“<span class="quote">logical</span>”</span> order (e.g.,
+ for B-Tree indexes on <code class="type">text</code>, index tuples should be in
+ collated lexical order). If that particular invariant somehow fails
+ to hold, we can expect binary searches on the affected page to
+ incorrectly guide index scans, resulting in wrong answers to SQL
+ queries. If the structure appears to be valid, no error is raised.
+ </p><p>
+ Verification is performed using the same procedures as those used by
+ index scans themselves, which may be user-defined operator class
+ code. For example, B-Tree index verification relies on comparisons
+ made with one or more B-Tree support function 1 routines. See <a class="xref" href="xindex.html#XINDEX-SUPPORT" title="38.16.3. Index Method Support Routines">Section 38.16.3</a> for details of operator class support
+ functions.
+ </p><p>
+ Unlike the B-Tree checking functions which report corruption by raising
+ errors, the heap checking function <code class="function">verify_heapam</code> checks
+ a table and attempts to return a set of rows, one row per corruption
+ detected. Despite this, if facilities that
+ <code class="function">verify_heapam</code> relies upon are themselves corrupted, the
+ function may be unable to continue and may instead raise an error.
+ </p><p>
+ Permission to execute <code class="filename">amcheck</code> functions may be granted
+ to non-superusers, but before granting such permissions careful consideration
+ should be given to data security and privacy concerns. Although the
+ corruption reports generated by these functions do not focus on the contents
+ of the corrupted data so much as on the structure of that data and the nature
+ of the corruptions found, an attacker who gains permission to execute these
+ functions, particularly if the attacker can also induce corruption, might be
+ able to infer something of the data itself from such messages.
+ </p><div class="sect2" id="id-1.11.7.11.8"><div class="titlepage"><div><div><h3 class="title">F.2.1. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">bt_index_check(index regclass, heapallindexed boolean) returns void</code>
+ <a id="id-1.11.7.11.8.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">bt_index_check</code> tests that its target, a
+ B-Tree index, respects a variety of invariants. Example usage:
+</p><pre class="screen">
+test=# SELECT bt_index_check(index =&gt; c.oid, heapallindexed =&gt; i.indisunique),
+ c.relname,
+ c.relpages
+FROM pg_index i
+JOIN pg_opclass op ON i.indclass[0] = op.oid
+JOIN pg_am am ON op.opcmethod = am.oid
+JOIN pg_class c ON i.indexrelid = c.oid
+JOIN pg_namespace n ON c.relnamespace = n.oid
+WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog'
+-- Don't check temp tables, which may be from another session:
+AND c.relpersistence != 't'
+-- Function may throw an error when this is omitted:
+AND c.relkind = 'i' AND i.indisready AND i.indisvalid
+ORDER BY c.relpages DESC LIMIT 10;
+ bt_index_check | relname | relpages
+----------------+---------------------------------+----------
+ | pg_depend_reference_index | 43
+ | pg_depend_depender_index | 40
+ | pg_proc_proname_args_nsp_index | 31
+ | pg_description_o_c_o_index | 21
+ | pg_attribute_relid_attnam_index | 14
+ | pg_proc_oid_index | 10
+ | pg_attribute_relid_attnum_index | 9
+ | pg_amproc_fam_proc_index | 5
+ | pg_amop_opr_fam_index | 5
+ | pg_amop_fam_strat_index | 5
+(10 rows)
+</pre><p>
+ This example shows a session that performs verification of the
+ 10 largest catalog indexes in the database <span class="quote">“<span class="quote">test</span>”</span>.
+ Verification of the presence of heap tuples as index tuples is
+ requested for the subset that are unique indexes. Since no
+ error is raised, all indexes tested appear to be logically
+ consistent. Naturally, this query could easily be changed to
+ call <code class="function">bt_index_check</code> for every index in the
+ database where verification is supported.
+ </p><p>
+ <code class="function">bt_index_check</code> acquires an <code class="literal">AccessShareLock</code>
+ on the target index and the heap relation it belongs to. This lock mode
+ is the same lock mode acquired on relations by simple
+ <code class="literal">SELECT</code> statements.
+ <code class="function">bt_index_check</code> does not verify invariants
+ that span child/parent relationships, but will verify the
+ presence of all heap tuples as index tuples within the index
+ when <em class="parameter"><code>heapallindexed</code></em> is
+ <code class="literal">true</code>. When a routine, lightweight test for
+ corruption is required in a live production environment, using
+ <code class="function">bt_index_check</code> often provides the best
+ trade-off between thoroughness of verification and limiting the
+ impact on application performance and availability.
+ </p></dd><dt><span class="term">
+ <code class="function">bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void</code>
+ <a id="id-1.11.7.11.8.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">bt_index_parent_check</code> tests that its
+ target, a B-Tree index, respects a variety of invariants.
+ Optionally, when the <em class="parameter"><code>heapallindexed</code></em>
+ argument is <code class="literal">true</code>, the function verifies the
+ presence of all heap tuples that should be found within the
+ index. When the optional <em class="parameter"><code>rootdescend</code></em>
+ argument is <code class="literal">true</code>, verification re-finds
+ tuples on the leaf level by performing a new search from the
+ root page for each tuple. The checks that can be performed by
+ <code class="function">bt_index_parent_check</code> are a superset of the
+ checks that can be performed by <code class="function">bt_index_check</code>.
+ <code class="function">bt_index_parent_check</code> can be thought of as
+ a more thorough variant of <code class="function">bt_index_check</code>:
+ unlike <code class="function">bt_index_check</code>,
+ <code class="function">bt_index_parent_check</code> also checks
+ invariants that span parent/child relationships, including checking
+ that there are no missing downlinks in the index structure.
+ <code class="function">bt_index_parent_check</code> follows the general
+ convention of raising an error if it finds a logical
+ inconsistency or other problem.
+ </p><p>
+ A <code class="literal">ShareLock</code> is required on the target index by
+ <code class="function">bt_index_parent_check</code> (a
+ <code class="literal">ShareLock</code> is also acquired on the heap relation).
+ These locks prevent concurrent data modification from
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code>
+ commands. The locks also prevent the underlying relation from
+ being concurrently processed by <code class="command">VACUUM</code>, as well as
+ all other utility commands. Note that the function holds locks
+ only while running, not for the entire transaction.
+ </p><p>
+ <code class="function">bt_index_parent_check</code>'s additional
+ verification is more likely to detect various pathological
+ cases. These cases may involve an incorrectly implemented
+ B-Tree operator class used by the index that is checked, or,
+ hypothetically, undiscovered bugs in the underlying B-Tree index
+ access method code. Note that
+ <code class="function">bt_index_parent_check</code> cannot be used when
+ hot standby mode is enabled (i.e., on read-only physical
+ replicas), unlike <code class="function">bt_index_check</code>.
+ </p></dd></dl></div><div class="tip"><h3 class="title">Tip</h3><p>
+ <code class="function">bt_index_check</code> and
+ <code class="function">bt_index_parent_check</code> both output log
+ messages about the verification process at
+ <code class="literal">DEBUG1</code> and <code class="literal">DEBUG2</code> severity
+ levels. These messages provide detailed information about the
+ verification process that may be of interest to
+ <span class="productname">PostgreSQL</span> developers. Advanced users
+ may also find this information helpful, since it provides
+ additional context should verification actually detect an
+ inconsistency. Running:
+</p><pre class="programlisting">
+SET client_min_messages = DEBUG1;
+</pre><p>
+ in an interactive <span class="application">psql</span> session before
+ running a verification query will display messages about the
+ progress of verification with a manageable level of detail.
+ </p></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">
+ verify_heapam(relation regclass,
+ on_error_stop boolean,
+ check_toast boolean,
+ skip text,
+ startblock bigint,
+ endblock bigint,
+ blkno OUT bigint,
+ offnum OUT integer,
+ attnum OUT integer,
+ msg OUT text)
+ returns setof record
+ </code>
+ </span></dt><dd><p>
+ Checks a table, sequence, or materialized view for structural corruption,
+ where pages in the relation contain data that is invalidly formatted, and
+ for logical corruption, where pages are structurally valid but
+ inconsistent with the rest of the database cluster.
+ </p><p>
+ The following optional arguments are recognized:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">on_error_stop</code></span></dt><dd><p>
+ If true, corruption checking stops at the end of the first block in
+ which any corruptions are found.
+ </p><p>
+ Defaults to false.
+ </p></dd><dt><span class="term"><code class="literal">check_toast</code></span></dt><dd><p>
+ If true, toasted values are checked against the target relation's
+ TOAST table.
+ </p><p>
+ This option is known to be slow. Also, if the toast table or its
+ index is corrupt, checking it against toast values could conceivably
+ crash the server, although in many cases this would just produce an
+ error.
+ </p><p>
+ Defaults to false.
+ </p></dd><dt><span class="term"><code class="literal">skip</code></span></dt><dd><p>
+ If not <code class="literal">none</code>, corruption checking skips blocks that
+ are marked as all-visible or all-frozen, as specified.
+ Valid options are <code class="literal">all-visible</code>,
+ <code class="literal">all-frozen</code> and <code class="literal">none</code>.
+ </p><p>
+ Defaults to <code class="literal">none</code>.
+ </p></dd><dt><span class="term"><code class="literal">startblock</code></span></dt><dd><p>
+ If specified, corruption checking begins at the specified block,
+ skipping all previous blocks. It is an error to specify a
+ <em class="parameter"><code>startblock</code></em> outside the range of blocks in the
+ target table.
+ </p><p>
+ By default, checking begins at the first block.
+ </p></dd><dt><span class="term"><code class="literal">endblock</code></span></dt><dd><p>
+ If specified, corruption checking ends at the specified block,
+ skipping all remaining blocks. It is an error to specify an
+ <em class="parameter"><code>endblock</code></em> outside the range of blocks in the target
+ table.
+ </p><p>
+ By default, all blocks are checked.
+ </p></dd></dl></div><p>
+ For each corruption detected, <code class="function">verify_heapam</code> returns
+ a row with the following columns:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">blkno</code></span></dt><dd><p>
+ The number of the block containing the corrupt page.
+ </p></dd><dt><span class="term"><code class="literal">offnum</code></span></dt><dd><p>
+ The OffsetNumber of the corrupt tuple.
+ </p></dd><dt><span class="term"><code class="literal">attnum</code></span></dt><dd><p>
+ The attribute number of the corrupt column in the tuple, if the
+ corruption is specific to a column and not the tuple as a whole.
+ </p></dd><dt><span class="term"><code class="literal">msg</code></span></dt><dd><p>
+ A message describing the problem detected.
+ </p></dd></dl></div></dd></dl></div></div><div class="sect2" id="id-1.11.7.11.9"><div class="titlepage"><div><div><h3 class="title">F.2.2. Optional <em class="parameter"><code>heapallindexed</code></em> Verification</h3></div></div></div><p>
+ When the <em class="parameter"><code>heapallindexed</code></em> argument to B-Tree
+ verification functions is <code class="literal">true</code>, an additional
+ phase of verification is performed against the table associated with
+ the target index relation. This consists of a <span class="quote">“<span class="quote">dummy</span>”</span>
+ <code class="command">CREATE INDEX</code> operation, which checks for the
+ presence of all hypothetical new index tuples against a temporary,
+ in-memory summarizing structure (this is built when needed during
+ the basic first phase of verification). The summarizing structure
+ <span class="quote">“<span class="quote">fingerprints</span>”</span> every tuple found within the target
+ index. The high level principle behind
+ <em class="parameter"><code>heapallindexed</code></em> verification is that a new
+ index that is equivalent to the existing, target index must only
+ have entries that can be found in the existing structure.
+ </p><p>
+ The additional <em class="parameter"><code>heapallindexed</code></em> phase adds
+ significant overhead: verification will typically take several times
+ longer. However, there is no change to the relation-level locks
+ acquired when <em class="parameter"><code>heapallindexed</code></em> verification is
+ performed.
+ </p><p>
+ The summarizing structure is bound in size by
+ <code class="varname">maintenance_work_mem</code>. In order to ensure that
+ there is no more than a 2% probability of failure to detect an
+ inconsistency for each heap tuple that should be represented in the
+ index, approximately 2 bytes of memory are needed per tuple. As
+ less memory is made available per tuple, the probability of missing
+ an inconsistency slowly increases. This approach limits the
+ overhead of verification significantly, while only slightly reducing
+ the probability of detecting a problem, especially for installations
+ where verification is treated as a routine maintenance task. Any
+ single absent or malformed tuple has a new opportunity to be
+ detected with each new verification attempt.
+ </p></div><div class="sect2" id="id-1.11.7.11.10"><div class="titlepage"><div><div><h3 class="title">F.2.3. Using <code class="filename">amcheck</code> Effectively</h3></div></div></div><p>
+ <code class="filename">amcheck</code> can be effective at detecting various types of
+ failure modes that <a class="link" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS"><span class="application">data
+ checksums</span></a> will fail to catch. These include:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Structural inconsistencies caused by incorrect operator class
+ implementations.
+ </p><p>
+ This includes issues caused by the comparison rules of operating
+ system collations changing. Comparisons of datums of a collatable
+ type like <code class="type">text</code> must be immutable (just as all
+ comparisons used for B-Tree index scans must be immutable), which
+ implies that operating system collation rules must never change.
+ Though rare, updates to operating system collation rules can
+ cause these issues. More commonly, an inconsistency in the
+ collation order between a primary server and a standby server is
+ implicated, possibly because the <span class="emphasis"><em>major</em></span> operating
+ system version in use is inconsistent. Such inconsistencies will
+ generally only arise on standby servers, and so can generally
+ only be detected on standby servers.
+ </p><p>
+ If a problem like this arises, it may not affect each individual
+ index that is ordered using an affected collation, simply because
+ <span class="emphasis"><em>indexed</em></span> values might happen to have the same
+ absolute ordering regardless of the behavioral inconsistency. See
+ <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> and <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a> for
+ further details about how <span class="productname">PostgreSQL</span> uses
+ operating system locales and collations.
+ </p></li><li class="listitem"><p>
+ Structural inconsistencies between indexes and the heap relations
+ that are indexed (when <em class="parameter"><code>heapallindexed</code></em>
+ verification is performed).
+ </p><p>
+ There is no cross-checking of indexes against their heap relation
+ during normal operation. Symptoms of heap corruption can be subtle.
+ </p></li><li class="listitem"><p>
+ Corruption caused by hypothetical undiscovered bugs in the
+ underlying <span class="productname">PostgreSQL</span> access method
+ code, sort code, or transaction management code.
+ </p><p>
+ Automatic verification of the structural integrity of indexes
+ plays a role in the general testing of new or proposed
+ <span class="productname">PostgreSQL</span> features that could plausibly allow a
+ logical inconsistency to be introduced. Verification of table
+ structure and associated visibility and transaction status
+ information plays a similar role. One obvious testing strategy
+ is to call <code class="filename">amcheck</code> functions continuously
+ when running the standard regression tests. See <a class="xref" href="regress-run.html" title="33.1. Running the Tests">Section 33.1</a> for details on running the tests.
+ </p></li><li class="listitem"><p>
+ File system or storage subsystem faults where checksums happen to
+ simply not be enabled.
+ </p><p>
+ Note that <code class="filename">amcheck</code> examines a page as represented in some
+ shared memory buffer at the time of verification if there is only a
+ shared buffer hit when accessing the block. Consequently,
+ <code class="filename">amcheck</code> does not necessarily examine data read from the
+ file system at the time of verification. Note that when checksums are
+ enabled, <code class="filename">amcheck</code> may raise an error due to a checksum
+ failure when a corrupt block is read into a buffer.
+ </p></li><li class="listitem"><p>
+ Corruption caused by faulty RAM, or the broader memory subsystem.
+ </p><p>
+ <span class="productname">PostgreSQL</span> does not protect against correctable
+ memory errors and it is assumed you will operate using RAM that
+ uses industry standard Error Correcting Codes (ECC) or better
+ protection. However, ECC memory is typically only immune to
+ single-bit errors, and should not be assumed to provide
+ <span class="emphasis"><em>absolute</em></span> protection against failures that
+ result in memory corruption.
+ </p><p>
+ When <em class="parameter"><code>heapallindexed</code></em> verification is
+ performed, there is generally a greatly increased chance of
+ detecting single-bit errors, since strict binary equality is
+ tested, and the indexed attributes within the heap are tested.
+ </p></li></ul></div><p>
+ </p><p>
+ Structural corruption can happen due to faulty storage hardware, or
+ relation files being overwritten or modified by unrelated software.
+ This kind of corruption can also be detected with
+ <a class="link" href="checksums.html" title="30.2. Data Checksums"><span class="application">data page
+ checksums</span></a>.
+ </p><p>
+ Relation pages which are correctly formatted, internally consistent, and
+ correct relative to their own internal checksums may still contain
+ logical corruption. As such, this kind of corruption cannot be detected
+ with <span class="application">checksums</span>. Examples include toasted
+ values in the main table which lack a corresponding entry in the toast
+ table, and tuples in the main table with a Transaction ID that is older
+ than the oldest valid Transaction ID in the database or cluster.
+ </p><p>
+ Multiple causes of logical corruption have been observed in production
+ systems, including bugs in the <span class="productname">PostgreSQL</span>
+ server software, faulty and ill-conceived backup and restore tools, and
+ user error.
+ </p><p>
+ Corrupt relations are most concerning in live production environments,
+ precisely the same environments where high risk activities are least
+ welcome. For this reason, <code class="function">verify_heapam</code> has been
+ designed to diagnose corruption without undue risk. It cannot guard
+ against all causes of backend crashes, as even executing the calling
+ query could be unsafe on a badly corrupted system. Access to <a class="link" href="catalogs-overview.html" title="53.1. Overview">catalog tables</a> is performed and could
+ be problematic if the catalogs themselves are corrupted.
+ </p><p>
+ In general, <code class="filename">amcheck</code> can only prove the presence of
+ corruption; it cannot prove its absence.
+ </p></div><div class="sect2" id="id-1.11.7.11.11"><div class="titlepage"><div><div><h3 class="title">F.2.4. Repairing Corruption</h3></div></div></div><p>
+ No error concerning corruption raised by <code class="filename">amcheck</code> should
+ ever be a false positive. <code class="filename">amcheck</code> raises
+ errors in the event of conditions that, by definition, should never
+ happen, and so careful analysis of <code class="filename">amcheck</code>
+ errors is often required.
+ </p><p>
+ There is no general method of repairing problems that
+ <code class="filename">amcheck</code> detects. An explanation for the root cause of
+ an invariant violation should be sought. <a class="xref" href="pageinspect.html" title="F.25. pageinspect">pageinspect</a> may play a useful role in diagnosing
+ corruption that <code class="filename">amcheck</code> detects. A <code class="command">REINDEX</code>
+ may not be effective in repairing corruption.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="adminpack.html" title="F.1. adminpack">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-delay.html" title="F.3. auth_delay">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.1. adminpack </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.3. auth_delay</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-clusterdb.html b/doc/src/sgml/html/app-clusterdb.html
new file mode 100644
index 0000000..523878c
--- /dev/null
+++ b/doc/src/sgml/html/app-clusterdb.html
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>clusterdb</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="reference-client.html" title="PostgreSQL Client Applications" /><link rel="next" href="app-createdb.html" title="createdb" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">clusterdb</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="reference-client.html" title="PostgreSQL Client Applications">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-createdb.html" title="createdb">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-CLUSTERDB"><div class="titlepage"></div><a id="id-1.9.4.3.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">clusterdb</span></span></h2><p>clusterdb — cluster a <span class="productname">PostgreSQL</span> database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.3.4.1"><code class="command">clusterdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [ <code class="option">--verbose</code> | <code class="option">-v</code> ]
+ [
+ <code class="option">--table</code> | <code class="option">-t</code>
+ <em class="replaceable"><code>table</code></em>
+ ]
+ ... [<em class="replaceable"><code>dbname</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.4.3.4.2"><code class="command">clusterdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [ <code class="option">--verbose</code> | <code class="option">-v</code> ] <code class="option">--all</code> | <code class="option">-a</code> </p></div></div><div class="refsect1" id="id-1.9.4.3.5"><h2>Description</h2><p>
+ <span class="application">clusterdb</span> is a utility for reclustering tables
+ in a <span class="productname">PostgreSQL</span> database. It finds tables
+ that have previously been clustered, and clusters them again on the same
+ index that was last used. Tables that have never been clustered are not
+ affected.
+ </p><p>
+ <span class="application">clusterdb</span> is a wrapper around the SQL
+ command <a class="xref" href="sql-cluster.html" title="CLUSTER"><span class="refentrytitle">CLUSTER</span></a>.
+ There is no effective difference between clustering databases via
+ this utility and via other methods for accessing the server.
+ </p></div><div class="refsect1" id="id-1.9.4.3.6"><h2>Options</h2><p>
+ <span class="application">clusterdb</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--all</code></span></dt><dd><p>
+ Cluster all databases.
+ </p></dd><dt><span class="term"><code class="option">[<span class="optional">-d</span>] <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">[<span class="optional">--dbname=</span>]<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to be clustered,
+ when <code class="option">-a</code>/<code class="option">--all</code> is not used.
+ If this is not specified, the database name is read
+ from the environment variable <code class="envar">PGDATABASE</code>. If
+ that is not set, the user name specified for the connection is
+ used. The <em class="replaceable"><code>dbname</code></em> can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">clusterdb</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Do not display progress messages.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>table</code></em></code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>table</code></em></code></span></dt><dd><p>
+ Cluster <em class="replaceable"><code>table</code></em> only.
+ Multiple tables can be clustered by writing multiple
+ <code class="option">-t</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Print detailed information during processing.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">clusterdb</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">clusterdb</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">clusterdb</span> also accepts
+ the following command-line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">clusterdb</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">clusterdb</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">clusterdb</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--maintenance-db=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to to discover which
+ databases should be clustered,
+ when <code class="option">-a</code>/<code class="option">--all</code> is used.
+ If not specified, the <code class="literal">postgres</code> database will be used,
+ or if that does not exist, <code class="literal">template1</code> will be used.
+ This can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection
+ string</a>. If so, connection string parameters will override any
+ conflicting command line options. Also, connection string parameters
+ other than the database name itself will be re-used when connecting
+ to other databases.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.3.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATABASE</code><br /></span><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.3.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-cluster.html" title="CLUSTER"><span class="refentrytitle">CLUSTER</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.3.9"><h2>Examples</h2><p>
+ To cluster the database <code class="literal">test</code>:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>clusterdb test</code></strong>
+</pre><p>
+ </p><p>
+ To cluster a single table
+ <code class="literal">foo</code> in a database named
+ <code class="literal">xyzzy</code>:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>clusterdb --table=foo xyzzy</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.3.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-cluster.html" title="CLUSTER"><span class="refentrytitle">CLUSTER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="reference-client.html" title="PostgreSQL Client Applications">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-createdb.html" title="createdb">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PostgreSQL Client Applications </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">createdb</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-createdb.html b/doc/src/sgml/html/app-createdb.html
new file mode 100644
index 0000000..7ae048d
--- /dev/null
+++ b/doc/src/sgml/html/app-createdb.html
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>createdb</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-clusterdb.html" title="clusterdb" /><link rel="next" href="app-createuser.html" title="createuser" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">createdb</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-clusterdb.html" title="clusterdb">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-createuser.html" title="createuser">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-CREATEDB"><div class="titlepage"></div><a id="id-1.9.4.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">createdb</span></span></h2><p>createdb — create a new <span class="productname">PostgreSQL</span> database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.4.4.1"><code class="command">createdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>dbname</code></em>
+ [<em class="replaceable"><code>description</code></em>]]</p></div></div><div class="refsect1" id="R1-APP-CREATEDB-1"><h2>Description</h2><p>
+ <span class="application">createdb</span> creates a new <span class="productname">PostgreSQL</span>
+ database.
+ </p><p>
+ Normally, the database user who executes this command becomes the owner of
+ the new database.
+ However, a different owner can be specified via the <code class="option">-O</code>
+ option, if the executing user has appropriate privileges.
+ </p><p>
+ <span class="application">createdb</span> is a wrapper around the
+ <acronym class="acronym">SQL</acronym> command <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE"><code class="command">CREATE DATABASE</code></a>.
+ There is no effective difference between creating databases via
+ this utility and via other methods for accessing the server.
+ </p></div><div class="refsect1" id="id-1.9.4.4.6"><h2>Options</h2><p>
+ <span class="application">createdb</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>dbname</code></em></span></dt><dd><p>
+ Specifies the name of the database to be created. The name must be
+ unique among all <span class="productname">PostgreSQL</span> databases in this cluster.
+ The default is to create a database with the same name as the
+ current system user.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>description</code></em></span></dt><dd><p>
+ Specifies a comment to be associated with the newly created
+ database.
+ </p></dd><dt><span class="term"><code class="option">-D <em class="replaceable"><code>tablespace</code></em></code><br /></span><span class="term"><code class="option">--tablespace=<em class="replaceable"><code>tablespace</code></em></code></span></dt><dd><p>
+ Specifies the default tablespace for the database. (This name
+ is processed as a double-quoted identifier.)
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">createdb</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-E <em class="replaceable"><code>encoding</code></em></code><br /></span><span class="term"><code class="option">--encoding=<em class="replaceable"><code>encoding</code></em></code></span></dt><dd><p>
+ Specifies the character encoding scheme to be used in this
+ database. The character sets supported by the
+ <span class="productname">PostgreSQL</span> server are described in
+ <a class="xref" href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED" title="24.3.1. Supported Character Sets">Section 24.3.1</a>.
+ </p></dd><dt><span class="term"><code class="option">-l <em class="replaceable"><code>locale</code></em></code><br /></span><span class="term"><code class="option">--locale=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Specifies the locale to be used in this database. This is equivalent
+ to specifying both <code class="option">--lc-collate</code> and <code class="option">--lc-ctype</code>.
+ </p></dd><dt><span class="term"><code class="option">--lc-collate=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Specifies the LC_COLLATE setting to be used in this database.
+ </p></dd><dt><span class="term"><code class="option">--lc-ctype=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Specifies the LC_CTYPE setting to be used in this database.
+ </p></dd><dt><span class="term"><code class="option">--icu-locale=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Specifies the ICU locale ID to be used in this database, if the
+ ICU locale provider is selected.
+ </p></dd><dt><span class="term"><code class="option">--locale-provider={<code class="literal">libc</code>|<code class="literal">icu</code>}</code></span></dt><dd><p>
+ Specifies the locale provider for the database's default collation.
+ </p></dd><dt><span class="term"><code class="option">-O <em class="replaceable"><code>owner</code></em></code><br /></span><span class="term"><code class="option">--owner=<em class="replaceable"><code>owner</code></em></code></span></dt><dd><p>
+ Specifies the database user who will own the new database.
+ (This name is processed as a double-quoted identifier.)
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>template</code></em></code><br /></span><span class="term"><code class="option">--strategy=<em class="replaceable"><code>strategy</code></em></code></span></dt><dd><p>
+ Specifies the database creation strategy. See
+ <a class="xref" href="sql-createdatabase.html#CREATE-DATABASE-STRATEGY">CREATE DATABASE STRATEGY</a> for more details.
+ </p></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>template</code></em></code><br /></span><span class="term"><code class="option">--template=<em class="replaceable"><code>template</code></em></code></span></dt><dd><p>
+ Specifies the template database from which to build this
+ database. (This name is processed as a double-quoted identifier.)
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">createdb</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">createdb</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ The options <code class="option">-D</code>, <code class="option">-l</code>, <code class="option">-E</code>,
+ <code class="option">-O</code>, and
+ <code class="option">-T</code> correspond to options of the underlying
+ SQL command <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE"><code class="command">CREATE DATABASE</code></a>; see there for more information
+ about them.
+ </p><p>
+ <span class="application">createdb</span> also accepts the following
+ command-line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the
+ server is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or the local Unix domain socket file
+ extension on which the server is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">createdb</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">createdb</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">createdb</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--maintenance-db=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to when creating the
+ new database. If not specified, the <code class="literal">postgres</code>
+ database will be used; if that does not exist (or if it is the name
+ of the new database being created), <code class="literal">template1</code> will
+ be used.
+ This can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection
+ string</a>. If so, connection string parameters will override any
+ conflicting command line options.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.4.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATABASE</code></span></dt><dd><p>
+ If set, the name of the database to create, unless overridden on
+ the command line.
+ </p></dd><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters. <code class="envar">PGUSER</code> also
+ determines the name of the database to create, if it is not
+ specified on the command line or by <code class="envar">PGDATABASE</code>.
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.4.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.4.9"><h2>Examples</h2><p>
+ To create the database <code class="literal">demo</code> using the default
+ database server:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>createdb demo</code></strong>
+</pre><p>
+ </p><p>
+ To create the database <code class="literal">demo</code> using the
+ server on host <code class="literal">eden</code>, port 5000, using the
+ <code class="literal">template0</code> template database, here is the
+ command-line command and the underlying SQL command:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>createdb -p 5000 -h eden -T template0 -e demo</code></strong>
+<code class="computeroutput">CREATE DATABASE demo TEMPLATE template0;</code>
+</pre></div><div class="refsect1" id="id-1.9.4.4.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-dropdb.html" title="dropdb"><span class="refentrytitle"><span class="application">dropdb</span></span></a>, <a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-clusterdb.html" title="clusterdb">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-createuser.html" title="createuser">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">clusterdb</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">createuser</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-createuser.html b/doc/src/sgml/html/app-createuser.html
new file mode 100644
index 0000000..9fa3caa
--- /dev/null
+++ b/doc/src/sgml/html/app-createuser.html
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>createuser</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-createdb.html" title="createdb" /><link rel="next" href="app-dropdb.html" title="dropdb" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">createuser</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-createdb.html" title="createdb">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-dropdb.html" title="dropdb">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-CREATEUSER"><div class="titlepage"></div><a id="id-1.9.4.5.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">createuser</span></span></h2><p>createuser — define a new <span class="productname">PostgreSQL</span> user account</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.5.4.1"><code class="command">createuser</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>username</code></em>]</p></div></div><div class="refsect1" id="id-1.9.4.5.5"><h2>Description</h2><p>
+ <span class="application">createuser</span> creates a
+ new <span class="productname">PostgreSQL</span> user (or more precisely, a role).
+ Only superusers and users with <code class="literal">CREATEROLE</code> privilege can create
+ new users, so <span class="application">createuser</span> must be
+ invoked by someone who can connect as a superuser or a user with
+ <code class="literal">CREATEROLE</code> privilege.
+ </p><p>
+ If you wish to create a role with the <code class="literal">SUPERUSER</code>,
+ <code class="literal">REPLICATION</code>, or <code class="literal">BYPASSRLS</code> privilege,
+ you must connect as a superuser, not merely with
+ <code class="literal">CREATEROLE</code> privilege.
+ Being a superuser implies the ability to bypass all access permission
+ checks within the database, so superuser access should not be granted
+ lightly. <code class="literal">CREATEROLE</code> also conveys
+ <a class="link" href="role-attributes.html#ROLE-CREATION">very extensive privileges</a>.
+ </p><p>
+ <span class="application">createuser</span> is a wrapper around the
+ <acronym class="acronym">SQL</acronym> command <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="command">CREATE ROLE</code></a>.
+ There is no effective difference between creating users via
+ this utility and via other methods for accessing the server.
+ </p></div><div class="refsect1" id="id-1.9.4.5.6"><h2>Options</h2><p>
+ <span class="application">createuser</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>username</code></em></span></dt><dd><p>
+ Specifies the name of the <span class="productname">PostgreSQL</span> user
+ to be created.
+ This name must be different from all existing roles in this
+ <span class="productname">PostgreSQL</span> installation.
+ </p></dd><dt><span class="term"><code class="option">-c <em class="replaceable"><code>number</code></em></code><br /></span><span class="term"><code class="option">--connection-limit=<em class="replaceable"><code>number</code></em></code></span></dt><dd><p>
+ Set a maximum number of connections for the new user.
+ The default is to set no limit.
+ </p></dd><dt><span class="term"><code class="option">-d</code><br /></span><span class="term"><code class="option">--createdb</code></span></dt><dd><p>
+ The new user will be allowed to create databases.
+ </p></dd><dt><span class="term"><code class="option">-D</code><br /></span><span class="term"><code class="option">--no-createdb</code></span></dt><dd><p>
+ The new user will not be allowed to create databases. This is the
+ default.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">createuser</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-E</code><br /></span><span class="term"><code class="option">--encrypted</code></span></dt><dd><p>
+ This option is obsolete but still accepted for backward
+ compatibility.
+ </p></dd><dt><span class="term"><code class="option">-g <em class="replaceable"><code>role</code></em></code><br /></span><span class="term"><code class="option">--role=<em class="replaceable"><code>role</code></em></code></span></dt><dd><p>
+ Indicates role to which this role will be added immediately as a new
+ member. Multiple roles to which this role will be added as a member
+ can be specified by writing multiple
+ <code class="option">-g</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-i</code><br /></span><span class="term"><code class="option">--inherit</code></span></dt><dd><p>
+ The new role will automatically inherit privileges of roles
+ it is a member of.
+ This is the default.
+ </p></dd><dt><span class="term"><code class="option">-I</code><br /></span><span class="term"><code class="option">--no-inherit</code></span></dt><dd><p>
+ The new role will not automatically inherit privileges of roles
+ it is a member of.
+ </p></dd><dt><span class="term"><code class="option">--interactive</code></span></dt><dd><p>
+ Prompt for the user name if none is specified on the command line, and
+ also prompt for whichever of the options
+ <code class="option">-d</code>/<code class="option">-D</code>,
+ <code class="option">-r</code>/<code class="option">-R</code>,
+ <code class="option">-s</code>/<code class="option">-S</code> is not specified on the command
+ line. (This was the default behavior up to PostgreSQL 9.1.)
+ </p></dd><dt><span class="term"><code class="option">-l</code><br /></span><span class="term"><code class="option">--login</code></span></dt><dd><p>
+ The new user will be allowed to log in (that is, the user name
+ can be used as the initial session user identifier).
+ This is the default.
+ </p></dd><dt><span class="term"><code class="option">-L</code><br /></span><span class="term"><code class="option">--no-login</code></span></dt><dd><p>
+ The new user will not be allowed to log in.
+ (A role without login privilege is still useful as a means of
+ managing database permissions.)
+ </p></dd><dt><span class="term"><code class="option">-P</code><br /></span><span class="term"><code class="option">--pwprompt</code></span></dt><dd><p>
+ If given, <span class="application">createuser</span> will issue a prompt for
+ the password of the new user. This is not necessary if you do not plan
+ on using password authentication.
+ </p></dd><dt><span class="term"><code class="option">-r</code><br /></span><span class="term"><code class="option">--createrole</code></span></dt><dd><p>
+ The new user will be allowed to create, alter, drop, comment on,
+ change the security label for, and grant or revoke membership in
+ other roles; that is,
+ this user will have <code class="literal">CREATEROLE</code> privilege.
+ See <a class="xref" href="role-attributes.html#ROLE-CREATION">role creation</a> for more details about what
+ capabilities are conferred by this privilege.
+ </p></dd><dt><span class="term"><code class="option">-R</code><br /></span><span class="term"><code class="option">--no-createrole</code></span></dt><dd><p>
+ The new user will not be allowed to create new roles. This is the
+ default.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--superuser</code></span></dt><dd><p>
+ The new user will be a superuser.
+ </p></dd><dt><span class="term"><code class="option">-S</code><br /></span><span class="term"><code class="option">--no-superuser</code></span></dt><dd><p>
+ The new user will not be a superuser. This is the default.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">createuser</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">--replication</code></span></dt><dd><p>
+ The new user will have the <code class="literal">REPLICATION</code> privilege,
+ which is described more fully in the documentation for <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>.
+ </p></dd><dt><span class="term"><code class="option">--no-replication</code></span></dt><dd><p>
+ The new user will not have the <code class="literal">REPLICATION</code>
+ privilege, which is described more fully in the documentation for <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">createuser</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">createuser</span> also accepts the following
+ command-line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the
+ server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as (not the user name to create).
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">createuser</span> to prompt for a
+ password (for connecting to the server, not for the
+ password of the new user).
+ </p><p>
+ This option is never essential, since
+ <span class="application">createuser</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">createuser</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.5.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.5.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.5.9"><h2>Examples</h2><p>
+ To create a user <code class="literal">joe</code> on the default database
+ server:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>createuser joe</code></strong>
+</pre><p>
+ </p><p>
+ To create a user <code class="literal">joe</code> on the default database
+ server with prompting for some additional attributes:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>createuser --interactive joe</code></strong>
+<code class="computeroutput">Shall the new role be a superuser? (y/n) </code><strong class="userinput"><code>n</code></strong>
+<code class="computeroutput">Shall the new role be allowed to create databases? (y/n) </code><strong class="userinput"><code>n</code></strong>
+<code class="computeroutput">Shall the new role be allowed to create more new roles? (y/n) </code><strong class="userinput"><code>n</code></strong>
+</pre><p>
+ </p><p>
+ To create the same user <code class="literal">joe</code> using the
+ server on host <code class="literal">eden</code>, port 5000, with attributes explicitly specified,
+ taking a look at the underlying command:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>createuser -h eden -p 5000 -S -D -R -e joe</code></strong>
+<code class="computeroutput">CREATE ROLE joe NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;</code>
+</pre><p>
+ </p><p>
+ To create the user <code class="literal">joe</code> as a superuser,
+ and assign a password immediately:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>createuser -P -s -e joe</code></strong>
+<code class="computeroutput">Enter password for new role: </code><strong class="userinput"><code>xyzzy</code></strong>
+<code class="computeroutput">Enter it again: </code><strong class="userinput"><code>xyzzy</code></strong>
+<code class="computeroutput">CREATE ROLE joe PASSWORD 'md5b5f5ba1a423792b526f799ae4eb3d59e' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;</code>
+</pre><p>
+ In the above example, the new password isn't actually echoed when typed,
+ but we show what was typed for clarity. As you see, the password is
+ encrypted before it is sent to the client.
+ </p></div><div class="refsect1" id="id-1.9.4.5.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-dropuser.html" title="dropuser"><span class="refentrytitle"><span class="application">dropuser</span></span></a>, <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-createdb.html" title="createdb">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-dropdb.html" title="dropdb">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">createdb</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">dropdb</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-dropdb.html b/doc/src/sgml/html/app-dropdb.html
new file mode 100644
index 0000000..706e87b
--- /dev/null
+++ b/doc/src/sgml/html/app-dropdb.html
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dropdb</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-createuser.html" title="createuser" /><link rel="next" href="app-dropuser.html" title="dropuser" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">dropdb</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-createuser.html" title="createuser">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-dropuser.html" title="dropuser">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-DROPDB"><div class="titlepage"></div><a id="id-1.9.4.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">dropdb</span></span></h2><p>dropdb — remove a <span class="productname">PostgreSQL</span> database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.6.4.1"><code class="command">dropdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] <em class="replaceable"><code>dbname</code></em> </p></div></div><div class="refsect1" id="id-1.9.4.6.5"><h2>Description</h2><p>
+ <span class="application">dropdb</span> destroys an existing
+ <span class="productname">PostgreSQL</span> database.
+ The user who executes this command must be a database
+ superuser or the owner of the database.
+ </p><p>
+ <span class="application">dropdb</span> is a wrapper around the
+ <acronym class="acronym">SQL</acronym> command <a class="link" href="sql-dropdatabase.html" title="DROP DATABASE"><code class="command">DROP DATABASE</code></a>.
+ There is no effective difference between dropping databases via
+ this utility and via other methods for accessing the server.
+ </p></div><div class="refsect1" id="id-1.9.4.6.6"><h2>Options</h2><p>
+ <span class="application">dropdb</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>dbname</code></em></span></dt><dd><p>
+ Specifies the name of the database to be removed.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">dropdb</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-f</code><br /></span><span class="term"><code class="option">--force</code></span></dt><dd><p>
+ Attempt to terminate all existing connections to the target database
+ before dropping it. See <a class="xref" href="sql-dropdatabase.html" title="DROP DATABASE"><span class="refentrytitle">DROP DATABASE</span></a> for more
+ information on this option.
+ </p></dd><dt><span class="term"><code class="option">-i</code><br /></span><span class="term"><code class="option">--interactive</code></span></dt><dd><p>
+ Issues a verification prompt before doing anything destructive.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">dropdb</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">--if-exists</code></span></dt><dd><p>
+ Do not throw an error if the database does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">dropdb</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+
+ </p><p>
+ <span class="application">dropdb</span> also accepts the following
+ command-line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the
+ server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">dropdb</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">dropdb</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">dropdb</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--maintenance-db=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to in order to drop the
+ target database. If not specified, the <code class="literal">postgres</code>
+ database will be used; if that does not exist (or is the database
+ being dropped), <code class="literal">template1</code> will be used.
+ This can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection
+ string</a>. If so, connection string parameters will override any
+ conflicting command line options.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.6.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.6.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-dropdatabase.html" title="DROP DATABASE"><span class="refentrytitle">DROP DATABASE</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.6.9"><h2>Examples</h2><p>
+ To destroy the database <code class="literal">demo</code> on the default
+ database server:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>dropdb demo</code></strong>
+</pre><p>
+ </p><p>
+ To destroy the database <code class="literal">demo</code> using the
+ server on host <code class="literal">eden</code>, port 5000, with verification and a peek
+ at the underlying command:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>dropdb -p 5000 -h eden -i -e demo</code></strong>
+<code class="computeroutput">Database "demo" will be permanently deleted.
+Are you sure? (y/n) </code><strong class="userinput"><code>y</code></strong>
+<code class="computeroutput">DROP DATABASE demo;</code>
+</pre></div><div class="refsect1" id="id-1.9.4.6.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-createdb.html" title="createdb"><span class="refentrytitle"><span class="application">createdb</span></span></a>, <a class="xref" href="sql-dropdatabase.html" title="DROP DATABASE"><span class="refentrytitle">DROP DATABASE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-createuser.html" title="createuser">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-dropuser.html" title="dropuser">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">createuser</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">dropuser</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-dropuser.html b/doc/src/sgml/html/app-dropuser.html
new file mode 100644
index 0000000..3e10083
--- /dev/null
+++ b/doc/src/sgml/html/app-dropuser.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dropuser</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-dropdb.html" title="dropdb" /><link rel="next" href="app-ecpg.html" title="ecpg" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">dropuser</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-dropdb.html" title="dropdb">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-ecpg.html" title="ecpg">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-DROPUSER"><div class="titlepage"></div><a id="id-1.9.4.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">dropuser</span></span></h2><p>dropuser — remove a <span class="productname">PostgreSQL</span> user account</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.7.4.1"><code class="command">dropuser</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>username</code></em>]</p></div></div><div class="refsect1" id="id-1.9.4.7.5"><h2>Description</h2><p>
+ <span class="application">dropuser</span> removes an existing
+ <span class="productname">PostgreSQL</span> user.
+ Only superusers and users with the <code class="literal">CREATEROLE</code> privilege can
+ remove <span class="productname">PostgreSQL</span> users. (To remove a
+ superuser, you must yourself be a superuser.)
+ </p><p>
+ <span class="application">dropuser</span> is a wrapper around the
+ <acronym class="acronym">SQL</acronym> command <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a>.
+ There is no effective difference between dropping users via
+ this utility and via other methods for accessing the server.
+ </p></div><div class="refsect1" id="id-1.9.4.7.6"><h2>Options</h2><p>
+ <span class="application">dropuser</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>username</code></em></span></dt><dd><p>
+ Specifies the name of the <span class="productname">PostgreSQL</span> user to be removed.
+ You will be prompted for a name if none is specified on the command
+ line and the <code class="option">-i</code>/<code class="option">--interactive</code> option
+ is used.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">dropuser</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-i</code><br /></span><span class="term"><code class="option">--interactive</code></span></dt><dd><p>
+ Prompt for confirmation before actually removing the user, and prompt
+ for the user name if none is specified on the command line.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">dropuser</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">--if-exists</code></span></dt><dd><p>
+ Do not throw an error if the user does not exist. A notice is
+ issued in this case.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">dropuser</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">dropuser</span> also accepts the following
+ command-line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the
+ server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as (not the user name to drop).
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">dropuser</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">dropuser</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">dropuser</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.7.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.7.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.7.9"><h2>Examples</h2><p>
+ To remove user <code class="literal">joe</code> from the default database
+ server:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>dropuser joe</code></strong>
+</pre><p>
+ </p><p>
+ To remove user <code class="literal">joe</code> using the server on host
+ <code class="literal">eden</code>, port 5000, with verification and a peek at the underlying
+ command:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>dropuser -p 5000 -h eden -i -e joe</code></strong>
+<code class="computeroutput">Role "joe" will be permanently removed.
+Are you sure? (y/n) </code><strong class="userinput"><code>y</code></strong>
+<code class="computeroutput">DROP ROLE joe;</code>
+</pre></div><div class="refsect1" id="id-1.9.4.7.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-createuser.html" title="createuser"><span class="refentrytitle"><span class="application">createuser</span></span></a>, <a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-dropdb.html" title="dropdb">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-ecpg.html" title="ecpg">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">dropdb</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">ecpg</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-ecpg.html b/doc/src/sgml/html/app-ecpg.html
new file mode 100644
index 0000000..1d9f2c1
--- /dev/null
+++ b/doc/src/sgml/html/app-ecpg.html
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ecpg</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-dropuser.html" title="dropuser" /><link rel="next" href="app-pgamcheck.html" title="pg_amcheck" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">ecpg</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-dropuser.html" title="dropuser">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgamcheck.html" title="pg_amcheck">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-ECPG"><div class="titlepage"></div><a id="id-1.9.4.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">ecpg</span></span></h2><p><span class="application">ecpg</span> — embedded SQL C preprocessor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.8.4.1"><code class="command">ecpg</code> [<em class="replaceable"><code>option</code></em>...] <em class="replaceable"><code>file</code></em>... </p></div></div><div class="refsect1" id="APP-ECPG-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">ecpg</code> is the embedded SQL preprocessor for C
+ programs. It converts C programs with embedded SQL statements to
+ normal C code by replacing the SQL invocations with special
+ function calls. The output files can then be processed with any C
+ compiler tool chain.
+ </p><p>
+ <code class="command">ecpg</code> will convert each input file given on the
+ command line to the corresponding C output file. If an input file
+ name does not have any extension, <code class="filename">.pgc</code> is
+ assumed. The file's extension will be replaced
+ by <code class="filename">.c</code> to construct the output file name.
+ But the output file name can be overridden using the
+ <code class="option">-o</code> option.
+ </p><p>
+ If an input file name is just <code class="literal">-</code>,
+ <code class="command">ecpg</code> reads the program from standard input
+ (and writes to standard output, unless that is overridden
+ with <code class="option">-o</code>).
+ </p><p>
+ This reference page does not describe the embedded SQL language.
+ See <a class="xref" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Chapter 36</a> for more information on that topic.
+ </p></div><div class="refsect1" id="id-1.9.4.8.6"><h2>Options</h2><p>
+ <code class="command">ecpg</code> accepts the following command-line
+ arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-c</code></span></dt><dd><p>
+ Automatically generate certain C code from SQL code. Currently, this
+ works for <code class="literal">EXEC SQL TYPE</code>.
+ </p></dd><dt><span class="term"><code class="option">-C <em class="replaceable"><code>mode</code></em></code></span></dt><dd><p>
+ Set a compatibility mode. <em class="replaceable"><code>mode</code></em> can
+ be <code class="literal">INFORMIX</code>,
+ <code class="literal">INFORMIX_SE</code>, or <code class="literal">ORACLE</code>.
+ </p></dd><dt><span class="term"><code class="option">-D <em class="replaceable"><code>symbol</code></em></code></span></dt><dd><p>
+ Define a C preprocessor symbol.
+ </p></dd><dt><span class="term"><code class="option">-h</code></span></dt><dd><p>
+ Process header files. When this option is specified, the output file
+ extension becomes <code class="literal">.h</code> not <code class="literal">.c</code>,
+ and the default input file extension is <code class="literal">.pgh</code>
+ not <code class="literal">.pgc</code>. Also, the <code class="option">-c</code> option is
+ forced on.
+ </p></dd><dt><span class="term"><code class="option">-i</code></span></dt><dd><p>
+ Parse system include files as well.
+ </p></dd><dt><span class="term"><code class="option">-I <em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Specify an additional include path, used to find files included
+ via <code class="literal">EXEC SQL INCLUDE</code>. Defaults are
+ <code class="filename">.</code> (current directory),
+ <code class="filename">/usr/local/include</code>, the
+ <span class="productname">PostgreSQL</span> include directory which
+ is defined at compile time (default:
+ <code class="filename">/usr/local/pgsql/include</code>), and
+ <code class="filename">/usr/include</code>, in that order.
+ </p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Specifies that <code class="command">ecpg</code> should write all
+ its output to the given <em class="replaceable"><code>filename</code></em>.
+ Write <code class="literal">-o -</code> to send all output to standard output.
+ </p></dd><dt><span class="term"><code class="option">-r <em class="replaceable"><code>option</code></em></code></span></dt><dd><p>
+ Selects run-time behavior. <em class="replaceable"><code>Option</code></em> can be
+ one of the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">no_indicator</code></span></dt><dd><p>
+ Do not use indicators but instead use special values to represent
+ null values. Historically there have been databases using this approach.
+ </p></dd><dt><span class="term"><code class="option">prepare</code></span></dt><dd><p>
+ Prepare all statements before using them. Libecpg will keep a cache of
+ prepared statements and reuse a statement if it gets executed again. If the
+ cache runs full, libecpg will free the least used statement.
+ </p></dd><dt><span class="term"><code class="option">questionmarks</code></span></dt><dd><p>
+ Allow question mark as placeholder for compatibility reasons.
+ This used to be the default long ago.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="option">-t</code></span></dt><dd><p>
+ Turn on autocommit of transactions. In this mode, each SQL command is
+ automatically committed unless it is inside an explicit
+ transaction block. In the default mode, commands are committed
+ only when <code class="command">EXEC SQL COMMIT</code> is issued.
+ </p></dd><dt><span class="term"><code class="option">-v</code></span></dt><dd><p>
+ Print additional information including the version and the
+ "include" path.
+ </p></dd><dt><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">ecpg</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">ecpg</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.8.7"><h2>Notes</h2><p>
+ When compiling the preprocessed C code files, the compiler needs to
+ be able to find the <span class="application">ECPG</span> header files in the
+ <span class="productname">PostgreSQL</span> include directory. Therefore, you might
+ have to use the <code class="option">-I</code> option when invoking the compiler
+ (e.g., <code class="literal">-I/usr/local/pgsql/include</code>).
+ </p><p>
+ Programs using C code with embedded SQL have to be linked against
+ the <code class="filename">libecpg</code> library, for example using the
+ linker options <code class="literal">-L/usr/local/pgsql/lib -lecpg</code>.
+ </p><p>
+ The value of either of these directories that is appropriate for
+ the installation can be found out using <a class="xref" href="app-pgconfig.html" title="pg_config"><span class="refentrytitle"><span class="application">pg_config</span></span></a>.
+ </p></div><div class="refsect1" id="id-1.9.4.8.8"><h2>Examples</h2><p>
+ If you have an embedded SQL C source file named
+ <code class="filename">prog1.pgc</code>, you can create an executable
+ program using the following sequence of commands:
+</p><pre class="programlisting">
+ecpg prog1.pgc
+cc -I/usr/local/pgsql/include -c prog1.c
+cc -o prog1 prog1.o -L/usr/local/pgsql/lib -lecpg
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-dropuser.html" title="dropuser">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgamcheck.html" title="pg_amcheck">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">dropuser</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_amcheck</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-initdb.html b/doc/src/sgml/html/app-initdb.html
new file mode 100644
index 0000000..970c12b
--- /dev/null
+++ b/doc/src/sgml/html/app-initdb.html
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>initdb</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="reference-server.html" title="PostgreSQL Server Applications" /><link rel="next" href="pgarchivecleanup.html" title="pg_archivecleanup" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">initdb</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="reference-server.html" title="PostgreSQL Server Applications">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgarchivecleanup.html" title="pg_archivecleanup">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-INITDB"><div class="titlepage"></div><a id="id-1.9.5.3.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">initdb</span></span></h2><p>initdb — create a new <span class="productname">PostgreSQL</span> database cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.3.4.1"><code class="command">initdb</code> [<em class="replaceable"><code>option</code></em>...] [ <code class="option">--pgdata</code> | <code class="option">-D</code> ]<em class="replaceable"><code> directory</code></em> </p></div></div><div class="refsect1" id="R1-APP-INITDB-1"><h2>Description</h2><p>
+ <code class="command">initdb</code> creates a new
+ <span class="productname">PostgreSQL</span> database cluster. A database
+ cluster is a collection of databases that are managed by a single
+ server instance.
+ </p><p>
+ Creating a database cluster consists of creating the directories in
+ which the database data will live, generating the shared catalog
+ tables (tables that belong to the whole cluster rather than to any
+ particular database), and creating the <code class="literal">postgres</code>,
+ <code class="literal">template1</code>, and <code class="literal">template0</code> databases.
+ The <code class="literal">postgres</code> database is a default database meant
+ for use by users, utilities and third party applications.
+ <code class="literal">template1</code> and <code class="literal">template0</code> are
+ meant as source databases to be copied by later <code class="command">CREATE
+ DATABASE</code> commands. <code class="literal">template0</code> should never
+ be modified, but you can add objects to <code class="literal">template1</code>,
+ which by default will be copied into databases created later. See
+ <a class="xref" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Section 23.3</a> for more details.
+ </p><p>
+ Although <code class="command">initdb</code> will attempt to create the
+ specified data directory, it might not have permission if the parent
+ directory of the desired data directory is root-owned. To initialize
+ in such a setup, create an empty data directory as root, then use
+ <code class="command">chown</code> to assign ownership of that directory to the
+ database user account, then <code class="command">su</code> to become the
+ database user to run <code class="command">initdb</code>.
+ </p><p>
+ <code class="command">initdb</code> must be run as the user that will own the
+ server process, because the server needs to have access to the
+ files and directories that <code class="command">initdb</code> creates.
+ Since the server cannot be run as root, you must not run
+ <code class="command">initdb</code> as root either. (It will in fact refuse
+ to do so.)
+ </p><p>
+ For security reasons the new cluster created by <code class="command">initdb</code>
+ will only be accessible by the cluster owner by default. The
+ <code class="option">--allow-group-access</code> option allows any user in the same
+ group as the cluster owner to read files in the cluster. This is useful
+ for performing backups as a non-privileged user.
+ </p><p>
+ <code class="command">initdb</code> initializes the database cluster's default locale
+ and character set encoding. These can also be set separately for each
+ database when it is created. <code class="command">initdb</code> determines those
+ settings for the template databases, which will serve as the default for
+ all other databases. By default, <code class="command">initdb</code> uses the
+ locale provider <code class="literal">libc</code>, takes the locale settings from
+ the environment, and determines the encoding from the locale settings.
+ This is almost always sufficient, unless there are special requirements.
+ </p><p>
+ To choose a different locale for the cluster, use the option
+ <code class="option">--locale</code>. There are also individual options
+ <code class="option">--lc-*</code> (see below) to set values for the individual locale
+ categories. Note that inconsistent settings for different locale
+ categories can give nonsensical results, so this should be used with care.
+ </p><p>
+ Alternatively, the ICU library can be used to provide locale services.
+ (Again, this only sets the default for subsequently created databases.) To
+ select this option, specify <code class="literal">--locale-provider=icu</code>.
+ To choose the specific ICU locale ID to apply, use the option
+ <code class="option">--icu-locale</code>. Note that
+ for implementation reasons and to support legacy code,
+ <code class="command">initdb</code> will still select and initialize libc locale
+ settings when the ICU locale provider is used.
+ </p><p>
+ When <code class="command">initdb</code> runs, it will print out the locale settings
+ it has chosen. If you have complex requirements or specified multiple
+ options, it is advisable to check that the result matches what was
+ intended.
+ </p><p>
+ More details about locale settings can be found in <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a>.
+ </p><p>
+ To alter the default encoding, use the <code class="option">--encoding</code>.
+ More details can be found in <a class="xref" href="multibyte.html" title="24.3. Character Set Support">Section 24.3</a>.
+ </p></div><div class="refsect1" id="id-1.9.5.3.6"><h2>Options</h2><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-A <em class="replaceable"><code>authmethod</code></em></code><br /></span><span class="term"><code class="option">--auth=<em class="replaceable"><code>authmethod</code></em></code></span></dt><dd><p>
+ This option specifies the default authentication method for local
+ users used in <code class="filename">pg_hba.conf</code> (<code class="literal">host</code>
+ and <code class="literal">local</code> lines). See <a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a>
+ for an overview of valid values.
+ </p><p>
+ <code class="command">initdb</code> will
+ prepopulate <code class="filename">pg_hba.conf</code> entries using the
+ specified authentication method for non-replication as well as
+ replication connections.
+ </p><p>
+ Do not use <code class="literal">trust</code> unless you trust all local users on your
+ system. <code class="literal">trust</code> is the default for ease of installation.
+ </p></dd><dt><span class="term"><code class="option">--auth-host=<em class="replaceable"><code>authmethod</code></em></code></span></dt><dd><p>
+ This option specifies the authentication method for local users via
+ TCP/IP connections used in <code class="filename">pg_hba.conf</code>
+ (<code class="literal">host</code> lines).
+ </p></dd><dt><span class="term"><code class="option">--auth-local=<em class="replaceable"><code>authmethod</code></em></code></span></dt><dd><p>
+ This option specifies the authentication method for local users via
+ Unix-domain socket connections used in <code class="filename">pg_hba.conf</code>
+ (<code class="literal">local</code> lines).
+ </p></dd><dt><span class="term"><code class="option">-D <em class="replaceable"><code>directory</code></em></code><br /></span><span class="term"><code class="option">--pgdata=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ This option specifies the directory where the database cluster
+ should be stored. This is the only information required by
+ <code class="command">initdb</code>, but you can avoid writing it by
+ setting the <code class="envar">PGDATA</code> environment variable, which
+ can be convenient since the database server
+ (<code class="command">postgres</code>) can find the database
+ directory later by the same variable.
+ </p></dd><dt><span class="term"><code class="option">-E <em class="replaceable"><code>encoding</code></em></code><br /></span><span class="term"><code class="option">--encoding=<em class="replaceable"><code>encoding</code></em></code></span></dt><dd><p>
+ Selects the encoding of the template databases. This will also
+ be the default encoding of any database you create later,
+ unless you override it then. The default is derived from the locale,
+ if the libc locale provider is used, or <code class="literal">UTF8</code> if the
+ ICU locale provider is used. The character sets supported by
+ the <span class="productname">PostgreSQL</span> server are described
+ in <a class="xref" href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED" title="24.3.1. Supported Character Sets">Section 24.3.1</a>.
+ </p></dd><dt id="APP-INITDB-ALLOW-GROUP-ACCESS"><span class="term"><code class="option">-g</code><br /></span><span class="term"><code class="option">--allow-group-access</code></span></dt><dd><p>
+ Allows users in the same group as the cluster owner to read all cluster
+ files created by <code class="command">initdb</code>. This option is ignored
+ on <span class="productname">Windows</span> as it does not support
+ <acronym class="acronym">POSIX</acronym>-style group permissions.
+ </p></dd><dt><span class="term"><code class="option">--icu-locale=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Specifies the ICU locale ID, if the ICU locale provider is used.
+ </p></dd><dt id="APP-INITDB-DATA-CHECKSUMS"><span class="term"><code class="option">-k</code><br /></span><span class="term"><code class="option">--data-checksums</code></span></dt><dd><p>
+ Use checksums on data pages to help detect corruption by the
+ I/O system that would otherwise be silent. Enabling checksums
+ may incur a noticeable performance penalty. If set, checksums
+ are calculated for all objects, in all databases. All checksum
+ failures will be reported in the
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW" title="28.2.15. pg_stat_database">
+ <code class="structname">pg_stat_database</code></a> view.
+ See <a class="xref" href="checksums.html" title="30.2. Data Checksums">Section 30.2</a> for details.
+ </p></dd><dt><span class="term"><code class="option">--locale=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Sets the default locale for the database cluster. If this
+ option is not specified, the locale is inherited from the
+ environment that <code class="command">initdb</code> runs in. Locale
+ support is described in <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a>.
+ </p></dd><dt><span class="term"><code class="option">--lc-collate=<em class="replaceable"><code>locale</code></em></code><br /></span><span class="term"><code class="option">--lc-ctype=<em class="replaceable"><code>locale</code></em></code><br /></span><span class="term"><code class="option">--lc-messages=<em class="replaceable"><code>locale</code></em></code><br /></span><span class="term"><code class="option">--lc-monetary=<em class="replaceable"><code>locale</code></em></code><br /></span><span class="term"><code class="option">--lc-numeric=<em class="replaceable"><code>locale</code></em></code><br /></span><span class="term"><code class="option">--lc-time=<em class="replaceable"><code>locale</code></em></code></span></dt><dd><p>
+ Like <code class="option">--locale</code>, but only sets the locale in
+ the specified category.
+ </p></dd><dt><span class="term"><code class="option">--no-locale</code></span></dt><dd><p>
+ Equivalent to <code class="option">--locale=C</code>.
+ </p></dd><dt><span class="term"><code class="option">--locale-provider={<code class="literal">libc</code>|<code class="literal">icu</code>}</code></span></dt><dd><p>
+ This option sets the locale provider for databases created in the
+ new cluster. It can be overridden in the <code class="command">CREATE
+ DATABASE</code> command when new databases are subsequently
+ created. The default is <code class="literal">libc</code>.
+ </p></dd><dt><span class="term"><code class="option">-N</code><br /></span><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">initdb</code> will wait for all files to be
+ written safely to disk. This option causes <code class="command">initdb</code>
+ to return without waiting, which is faster, but means that a
+ subsequent operating system crash can leave the data directory
+ corrupt. Generally, this option is useful for testing, but should not
+ be used when creating a production installation.
+ </p></dd><dt><span class="term"><code class="option">--no-instructions</code></span></dt><dd><p>
+ By default, <code class="command">initdb</code> will write instructions for how
+ to start the cluster at the end of its output. This option causes
+ those instructions to be left out. This is primarily intended for use
+ by tools that wrap <code class="command">initdb</code> in platform-specific
+ behavior, where those instructions are likely to be incorrect.
+ </p></dd><dt><span class="term"><code class="option">--pwfile=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Makes <code class="command">initdb</code> read the database superuser's password
+ from a file. The first line of the file is taken as the password.
+ </p></dd><dt><span class="term"><code class="option">-S</code><br /></span><span class="term"><code class="option">--sync-only</code></span></dt><dd><p>
+ Safely write all database files to disk and exit. This does not
+ perform any of the normal <span class="application">initdb</span> operations.
+ Generally, this option is useful for ensuring reliable recovery after
+ changing <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a> from <code class="literal">off</code> to
+ <code class="literal">on</code>.
+ </p></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>config</code></em></code><br /></span><span class="term"><code class="option">--text-search-config=<em class="replaceable"><code>config</code></em></code></span></dt><dd><p>
+ Sets the default text search configuration.
+ See <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a> for further information.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Selects the user name of the database superuser. This defaults
+ to the name of the effective user running
+ <code class="command">initdb</code>. It is really not important what the
+ superuser's name is, but one might choose to keep the
+ customary name <span class="systemitem">postgres</span>, even if the operating
+ system user's name is different.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--pwprompt</code></span></dt><dd><p>
+ Makes <code class="command">initdb</code> prompt for a password
+ to give the database superuser. If you don't plan on using password
+ authentication, this is not important. Otherwise you won't be
+ able to use password authentication until you have a password
+ set up.
+ </p></dd><dt><span class="term"><code class="option">-X <em class="replaceable"><code>directory</code></em></code><br /></span><span class="term"><code class="option">--waldir=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ This option specifies the directory where the write-ahead log
+ should be stored.
+ </p></dd><dt><span class="term"><code class="option">--wal-segsize=<em class="replaceable"><code>size</code></em></code></span></dt><dd><p>
+ Set the <em class="firstterm">WAL segment size</em>, in megabytes. This
+ is the size of each individual file in the WAL log. The default size
+ is 16 megabytes. The value must be a power of 2 between 1 and 1024
+ (megabytes). This option can only be set during initialization, and
+ cannot be changed later.
+ </p><p>
+ It may be useful to adjust this size to control the granularity of
+ WAL log shipping or archiving. Also, in databases with a high volume
+ of WAL, the sheer number of WAL files per directory can become a
+ performance and management problem. Increasing the WAL file size
+ will reduce the number of WAL files.
+ </p></dd></dl></div><p>
+ </p><p>
+ Other, less commonly used, options are also available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d</code><br /></span><span class="term"><code class="option">--debug</code></span></dt><dd><p>
+ Print debugging output from the bootstrap backend and a few other
+ messages of lesser interest for the general public.
+ The bootstrap backend is the program <code class="command">initdb</code>
+ uses to create the catalog tables. This option generates a tremendous
+ amount of extremely boring output.
+ </p></dd><dt><span class="term"><code class="option">--discard-caches</code></span></dt><dd><p>
+ Run the bootstrap backend with the
+ <code class="literal">debug_discard_caches=1</code> option.
+ This takes a very long time and is only of use for deep debugging.
+ </p></dd><dt><span class="term"><code class="option">-L <em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Specifies where <code class="command">initdb</code> should find
+ its input files to initialize the database cluster. This is
+ normally not necessary. You will be told if you need to
+ specify their location explicitly.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-clean</code></span></dt><dd><p>
+ By default, when <code class="command">initdb</code>
+ determines that an error prevented it from completely creating the database
+ cluster, it removes any files it might have created before discovering
+ that it cannot finish the job. This option inhibits tidying-up and is
+ thus useful for debugging.
+ </p></dd></dl></div><p>
+ </p><p>
+ Other options:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">initdb</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">initdb</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.3.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATA</code></span></dt><dd><p>
+ Specifies the directory where the database cluster is to be
+ stored; can be overridden using the <code class="option">-D</code> option.
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd><dt><span class="term"><code class="envar">TZ</code></span></dt><dd><p>
+ Specifies the default time zone of the created database cluster. The
+ value should be a full time zone name
+ (see <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a>).
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.5.3.8"><h2>Notes</h2><p>
+ <code class="command">initdb</code> can also be invoked via
+ <code class="command">pg_ctl initdb</code>.
+ </p></div><div class="refsect1" id="id-1.9.5.3.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a>, <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a>, <a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="reference-server.html" title="PostgreSQL Server Applications">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgarchivecleanup.html" title="pg_archivecleanup">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PostgreSQL Server Applications </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_archivecleanup</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pg-ctl.html b/doc/src/sgml/html/app-pg-ctl.html
new file mode 100644
index 0000000..2d39401
--- /dev/null
+++ b/doc/src/sgml/html/app-pg-ctl.html
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_ctl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgcontroldata.html" title="pg_controldata" /><link rel="next" href="app-pgresetwal.html" title="pg_resetwal" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_ctl</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgcontroldata.html" title="pg_controldata">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgresetwal.html" title="pg_resetwal">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PG-CTL"><div class="titlepage"></div><a id="id-1.9.5.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_ctl</span></span></h2><p>pg_ctl — initialize, start, stop, or control a <span class="productname">PostgreSQL</span> server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.7.4.1"><code class="command">pg_ctl</code> <code class="option">init[db]</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-s</code>] [<code class="option">-o</code> <em class="replaceable"><code>initdb-options</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.2"><code class="command">pg_ctl</code> <code class="option">start</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-l</code> <em class="replaceable"><code>filename</code></em>] [<code class="option">-W</code>] [<code class="option">-t</code> <em class="replaceable"><code>seconds</code></em>] [<code class="option">-s</code>] [<code class="option">-o</code> <em class="replaceable"><code>options</code></em>] [<code class="option">-p</code> <em class="replaceable"><code>path</code></em>] [<code class="option">-c</code>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.3"><code class="command">pg_ctl</code> <code class="option">stop</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-m</code>
+ <code class="option">s[mart]</code> | <code class="option">f[ast]</code> | <code class="option">i[mmediate]</code>
+ ] [<code class="option">-W</code>] [<code class="option">-t</code> <em class="replaceable"><code>seconds</code></em>] [<code class="option">-s</code>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.4"><code class="command">pg_ctl</code> <code class="option">restart</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-m</code>
+ <code class="option">s[mart]</code> | <code class="option">f[ast]</code> | <code class="option">i[mmediate]</code>
+ ] [<code class="option">-W</code>] [<code class="option">-t</code> <em class="replaceable"><code>seconds</code></em>] [<code class="option">-s</code>] [<code class="option">-o</code> <em class="replaceable"><code>options</code></em>] [<code class="option">-c</code>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.5"><code class="command">pg_ctl</code> <code class="option">reload</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-s</code>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.6"><code class="command">pg_ctl</code> <code class="option">status</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.7"><code class="command">pg_ctl</code> <code class="option">promote</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-W</code>] [<code class="option">-t</code> <em class="replaceable"><code>seconds</code></em>] [<code class="option">-s</code>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.8"><code class="command">pg_ctl</code> <code class="option">logrotate</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-s</code>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.9"><code class="command">pg_ctl</code> <code class="option">kill</code> <em class="replaceable"><code>signal_name</code></em> <em class="replaceable"><code>process_id</code></em> </p></div><p>On Microsoft Windows, also:</p><div class="cmdsynopsis"><p id="id-1.9.5.7.4.11"><code class="command">pg_ctl</code> <code class="option">register</code> [<code class="option">-D</code> <em class="replaceable"><code>datadir</code></em>] [<code class="option">-N</code> <em class="replaceable"><code>servicename</code></em>] [<code class="option">-U</code> <em class="replaceable"><code>username</code></em>] [<code class="option">-P</code> <em class="replaceable"><code>password</code></em>] [<code class="option">-S</code>
+ <code class="option">a[uto]</code> | <code class="option">d[emand]</code>
+ ] [<code class="option">-e</code> <em class="replaceable"><code>source</code></em>] [<code class="option">-W</code>] [<code class="option">-t</code> <em class="replaceable"><code>seconds</code></em>] [<code class="option">-s</code>] [<code class="option">-o</code> <em class="replaceable"><code>options</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.5.7.4.12"><code class="command">pg_ctl</code> <code class="option">unregister</code> [<code class="option">-N</code> <em class="replaceable"><code>servicename</code></em>]</p></div></div><div class="refsect1" id="APP-PG-CTL-DESCRIPTION"><h2>Description</h2><p>
+ <span class="application">pg_ctl</span> is a utility for initializing a
+ <span class="productname">PostgreSQL</span> database cluster, starting,
+ stopping, or restarting the <span class="productname">PostgreSQL</span>
+ database server (<a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a>), or displaying the
+ status of a running server. Although the server can be started
+ manually, <span class="application">pg_ctl</span> encapsulates tasks such
+ as redirecting log output and properly detaching from the terminal
+ and process group. It also provides convenient options for
+ controlled shutdown.
+ </p><p>
+ The <code class="option">init</code> or <code class="option">initdb</code> mode creates a new
+ <span class="productname">PostgreSQL</span> database cluster, that is,
+ a collection of databases that will be managed by a single
+ server instance. This mode invokes the <code class="command">initdb</code>
+ command. See <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a> for details.
+ </p><p>
+ <code class="option">start</code> mode launches a new server. The
+ server is started in the background, and its standard input is attached
+ to <code class="filename">/dev/null</code> (or <code class="literal">nul</code> on Windows).
+ On Unix-like systems, by default, the server's standard output and
+ standard error are sent to <span class="application">pg_ctl</span>'s
+ standard output (not standard error). The standard output of
+ <span class="application">pg_ctl</span> should then be redirected to a
+ file or piped to another process such as a log rotating program
+ like <span class="application">rotatelogs</span>; otherwise <code class="command">postgres</code>
+ will write its output to the controlling terminal (from the
+ background) and will not leave the shell's process group. On
+ Windows, by default the server's standard output and standard error
+ are sent to the terminal. These default behaviors can be changed
+ by using <code class="option">-l</code> to append the server's output to a log file.
+ Use of either <code class="option">-l</code> or output redirection is recommended.
+ </p><p>
+ <code class="option">stop</code> mode shuts down the server that is running in
+ the specified data directory. Three different
+ shutdown methods can be selected with the <code class="option">-m</code>
+ option. <span class="quote">“<span class="quote">Smart</span>”</span> mode disallows new connections, then waits
+ for all existing clients to disconnect.
+ If the server is in hot standby, recovery and streaming replication
+ will be terminated once all clients have disconnected.
+ <span class="quote">“<span class="quote">Fast</span>”</span> mode (the default) does not wait for clients to disconnect.
+ All active transactions are
+ rolled back and clients are forcibly disconnected, then the
+ server is shut down. <span class="quote">“<span class="quote">Immediate</span>”</span> mode will abort
+ all server processes immediately, without a clean shutdown. This choice
+ will lead to a crash-recovery cycle during the next server start.
+ </p><p>
+ <code class="option">restart</code> mode effectively executes a stop followed
+ by a start. This allows changing the <code class="command">postgres</code>
+ command-line options, or changing configuration-file options that
+ cannot be changed without restarting the server.
+ If relative paths were used on the command line during server
+ start, <code class="option">restart</code> might fail unless
+ <span class="application">pg_ctl</span> is executed in the same current
+ directory as it was during server start.
+ </p><p>
+ <code class="option">reload</code> mode simply sends the
+ <code class="command">postgres</code> server process a <span class="systemitem">SIGHUP</span>
+ signal, causing it to reread its configuration files
+ (<code class="filename">postgresql.conf</code>,
+ <code class="filename">pg_hba.conf</code>, etc.). This allows changing
+ configuration-file options that do not require a full server restart
+ to take effect.
+ </p><p>
+ <code class="option">status</code> mode checks whether a server is running in
+ the specified data directory. If it is, the server's <acronym class="acronym">PID</acronym>
+ and the command line options that were used to invoke it are displayed.
+ If the server is not running, <span class="application">pg_ctl</span> returns
+ an exit status of 3. If an accessible data directory is not
+ specified, <span class="application">pg_ctl</span> returns an exit status of 4.
+ </p><p>
+ <code class="option">promote</code> mode commands the standby server that is
+ running in the specified data directory to end standby mode
+ and begin read-write operations.
+ </p><p>
+ <code class="option">logrotate</code> mode rotates the server log file.
+ For details on how to use this mode with external log rotation tools, see
+ <a class="xref" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Section 25.3</a>.
+ </p><p>
+ <code class="option">kill</code> mode sends a signal to a specified process.
+ This is primarily valuable on <span class="productname">Microsoft Windows</span>
+ which does not have a built-in <span class="application">kill</span> command. Use
+ <code class="literal">--help</code> to see a list of supported signal names.
+ </p><p>
+ <code class="option">register</code> mode registers the <span class="productname">PostgreSQL</span>
+ server as a system service on <span class="productname">Microsoft Windows</span>.
+ The <code class="option">-S</code> option allows selection of service start type,
+ either <span class="quote">“<span class="quote">auto</span>”</span> (start service automatically on system startup)
+ or <span class="quote">“<span class="quote">demand</span>”</span> (start service on demand).
+ </p><p>
+ <code class="option">unregister</code> mode unregisters a system service
+ on <span class="productname">Microsoft Windows</span>. This undoes the effects of the
+ <code class="option">register</code> command.
+ </p></div><div class="refsect1" id="APP-PG-CTL-OPTIONS"><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--core-files</code></span></dt><dd><p>
+ Attempt to allow server crashes to produce core files, on platforms
+ where this is possible, by lifting any soft resource limit placed on
+ core files.
+ This is useful in debugging or diagnosing problems by allowing a
+ stack trace to be obtained from a failed server process.
+ </p></dd><dt><span class="term"><code class="option">-D <em class="replaceable"><code>datadir</code></em></code><br /></span><span class="term"><code class="option">--pgdata=<em class="replaceable"><code>datadir</code></em></code></span></dt><dd><p>
+ Specifies the file system location of the database configuration files. If
+ this option is omitted, the environment variable
+ <code class="envar">PGDATA</code> is used.
+ </p></dd><dt><span class="term"><code class="option">-l <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--log=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Append the server log output to
+ <em class="replaceable"><code>filename</code></em>. If the file does not
+ exist, it is created. The <span class="systemitem">umask</span> is set to 077,
+ so access to the log file is disallowed to other users by default.
+ </p></dd><dt><span class="term"><code class="option">-m <em class="replaceable"><code>mode</code></em></code><br /></span><span class="term"><code class="option">--mode=<em class="replaceable"><code>mode</code></em></code></span></dt><dd><p>
+ Specifies the shutdown mode. <em class="replaceable"><code>mode</code></em>
+ can be <code class="literal">smart</code>, <code class="literal">fast</code>, or
+ <code class="literal">immediate</code>, or the first letter of one of
+ these three. If this option is omitted, <code class="literal">fast</code> is
+ the default.
+ </p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>options</code></em></code><br /></span><span class="term"><code class="option">--options=<em class="replaceable"><code>options</code></em></code></span></dt><dd><p>
+ Specifies options to be passed directly to the
+ <code class="command">postgres</code> command.
+ <code class="option">-o</code> can be specified multiple times, with all the given
+ options being passed through.
+ </p><p>
+ The <em class="replaceable"><code>options</code></em> should usually be surrounded by single or
+ double quotes to ensure that they are passed through as a group.
+ </p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>initdb-options</code></em></code><br /></span><span class="term"><code class="option">--options=<em class="replaceable"><code>initdb-options</code></em></code></span></dt><dd><p>
+ Specifies options to be passed directly to the
+ <code class="command">initdb</code> command.
+ <code class="option">-o</code> can be specified multiple times, with all the given
+ options being passed through.
+ </p><p>
+ The <em class="replaceable"><code>initdb-options</code></em> should usually be surrounded by single or
+ double quotes to ensure that they are passed through as a group.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>path</code></em></code></span></dt><dd><p>
+ Specifies the location of the <code class="filename">postgres</code>
+ executable. By default the <code class="filename">postgres</code> executable is taken from the same
+ directory as <code class="command">pg_ctl</code>, or failing that, the hard-wired
+ installation directory. It is not necessary to use this
+ option unless you are doing something unusual and get errors
+ that the <code class="filename">postgres</code> executable was not found.
+ </p><p>
+ In <code class="literal">init</code> mode, this option analogously
+ specifies the location of the <code class="filename">initdb</code>
+ executable.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--silent</code></span></dt><dd><p>
+ Print only errors, no informational messages.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>seconds</code></em></code><br /></span><span class="term"><code class="option">--timeout=<em class="replaceable"><code>seconds</code></em></code></span></dt><dd><p>
+ Specifies the maximum number of seconds to wait when waiting for an
+ operation to complete (see option <code class="option">-w</code>). Defaults to
+ the value of the <code class="envar">PGCTLTIMEOUT</code> environment variable or, if
+ not set, to 60 seconds.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_ctl</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--wait</code></span></dt><dd><p>
+ Wait for the operation to complete. This is supported for the
+ modes <code class="literal">start</code>, <code class="literal">stop</code>,
+ <code class="literal">restart</code>, <code class="literal">promote</code>,
+ and <code class="literal">register</code>, and is the default for those modes.
+ </p><p>
+ When waiting, <code class="command">pg_ctl</code> repeatedly checks the
+ server's <acronym class="acronym">PID</acronym> file, sleeping for a short amount
+ of time between checks. Startup is considered complete when
+ the <acronym class="acronym">PID</acronym> file indicates that the server is ready to
+ accept connections. Shutdown is considered complete when the server
+ removes the <acronym class="acronym">PID</acronym> file.
+ <code class="command">pg_ctl</code> returns an exit code based on the
+ success of the startup or shutdown.
+ </p><p>
+ If the operation does not complete within the timeout (see
+ option <code class="option">-t</code>), then <code class="command">pg_ctl</code> exits with
+ a nonzero exit status. But note that the operation might continue in
+ the background and eventually succeed.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--no-wait</code></span></dt><dd><p>
+ Do not wait for the operation to complete. This is the opposite of
+ the option <code class="option">-w</code>.
+ </p><p>
+ If waiting is disabled, the requested action is triggered, but there
+ is no feedback about its success. In that case, the server log file
+ or an external monitoring system would have to be used to check the
+ progress and success of the operation.
+ </p><p>
+ In prior releases of PostgreSQL, this was the default except for
+ the <code class="literal">stop</code> mode.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_ctl</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ If an option is specified that is valid, but not relevant to the selected
+ operating mode, <span class="application">pg_ctl</span> ignores it.
+ </p><div class="refsect2" id="APP-PG-CTL-WINDOWS-OPTIONS"><h3>Options for Windows</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-e <em class="replaceable"><code>source</code></em></code></span></dt><dd><p>
+ Name of the event source for <span class="application">pg_ctl</span> to use
+ for logging to the event log when running as a Windows service. The
+ default is <code class="literal">PostgreSQL</code>. Note that this only controls
+ messages sent from <span class="application">pg_ctl</span> itself; once
+ started, the server will use the event source specified
+ by its <a class="xref" href="runtime-config-logging.html#GUC-EVENT-SOURCE">event_source</a> parameter. Should the server
+ fail very early in startup, before that parameter has been set,
+ it might also log using the default event
+ source name <code class="literal">PostgreSQL</code>.
+ </p></dd><dt><span class="term"><code class="option">-N <em class="replaceable"><code>servicename</code></em></code></span></dt><dd><p>
+ Name of the system service to register. This name will be used
+ as both the service name and the display name.
+ The default is <code class="literal">PostgreSQL</code>.
+ </p></dd><dt><span class="term"><code class="option">-P <em class="replaceable"><code>password</code></em></code></span></dt><dd><p>
+ Password for the user to run the service as.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>start-type</code></em></code></span></dt><dd><p>
+ Start type of the system service. <em class="replaceable"><code>start-type</code></em> can
+ be <code class="literal">auto</code>, or <code class="literal">demand</code>, or
+ the first letter of one of these two. If this option is omitted,
+ <code class="literal">auto</code> is the default.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name for the user to run the service as. For domain users, use the
+ format <code class="literal">DOMAIN\username</code>.
+ </p></dd></dl></div></div></div><div class="refsect1" id="id-1.9.5.7.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGCTLTIMEOUT</code></span></dt><dd><p>
+ Default limit on the number of seconds to wait when waiting for startup
+ or shutdown to complete. If not set, the default is 60 seconds.
+ </p></dd><dt><span class="term"><code class="envar">PGDATA</code></span></dt><dd><p>
+ Default data directory location.
+ </p></dd></dl></div><p>
+ Most <code class="command">pg_ctl</code> modes require knowing the data directory
+ location; therefore, the <code class="option">-D</code> option is required
+ unless <code class="envar">PGDATA</code> is set.
+ </p><p>
+ <code class="command">pg_ctl</code>, like most other <span class="productname">PostgreSQL</span>
+ utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ For additional variables that affect the server,
+ see <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a>.
+ </p></div><div class="refsect1" id="id-1.9.5.7.8"><h2>Files</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="filename">postmaster.pid</code></span></dt><dd><p>
+ <span class="application">pg_ctl</span> examines this file in the data
+ directory to determine whether the server is currently running.
+ </p></dd><dt><span class="term"><code class="filename">postmaster.opts</code></span></dt><dd><p>If this file exists in the data directory,
+ <span class="application">pg_ctl</span> (in <code class="option">restart</code> mode)
+ will pass the contents of the file as options to
+ <span class="application">postgres</span>, unless overridden
+ by the <code class="option">-o</code> option. The contents of this file
+ are also displayed in <code class="option">status</code> mode.
+ </p></dd></dl></div></div><div class="refsect1" id="R1-APP-PGCTL-2"><h2>Examples</h2><div class="refsect2" id="R2-APP-PGCTL-3"><h3>Starting the Server</h3><p>
+ To start the server, waiting until the server is
+ accepting connections:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl start</code></strong>
+</pre><p>
+ </p><p>
+ To start the server using port 5433, and
+ running without <code class="function">fsync</code>, use:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl -o "-F -p 5433" start</code></strong>
+</pre></div><div class="refsect2" id="R2-APP-PGCTL-4"><h3>Stopping the Server</h3><p>
+ To stop the server, use:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl stop</code></strong>
+</pre><p>
+ The <code class="option">-m</code> option allows control over
+ <span class="emphasis"><em>how</em></span> the server shuts down:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl stop -m smart</code></strong>
+</pre></div><div class="refsect2" id="R2-APP-PGCTL-5"><h3>Restarting the Server</h3><p>
+ Restarting the server is almost equivalent to stopping the
+ server and starting it again, except that by default,
+ <code class="command">pg_ctl</code> saves and reuses the command line options that
+ were passed to the previously-running instance. To restart
+ the server using the same options as before, use:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl restart</code></strong>
+</pre><p>
+ </p><p>
+ But if <code class="option">-o</code> is specified, that replaces any previous options.
+ To restart using port 5433, disabling <code class="function">fsync</code> upon restart:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl -o "-F -p 5433" restart</code></strong>
+</pre></div><div class="refsect2" id="R2-APP-PGCTL-6"><h3>Showing the Server Status</h3><p>
+ Here is sample status output from
+ <span class="application">pg_ctl</span>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl status</code></strong>
+<code class="computeroutput">
+pg_ctl: server is running (PID: 13718)
+/usr/local/pgsql/bin/postgres "-D" "/usr/local/pgsql/data" "-p" "5433" "-B" "128"
+</code></pre><p>
+ The second line is the command that would be invoked in restart mode.
+ </p></div></div><div class="refsect1" id="id-1.9.5.7.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a>, <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgcontroldata.html" title="pg_controldata">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgresetwal.html" title="pg_resetwal">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_controldata</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_resetwal</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pg-dumpall.html b/doc/src/sgml/html/app-pg-dumpall.html
new file mode 100644
index 0000000..2ebabd8
--- /dev/null
+++ b/doc/src/sgml/html/app-pg-dumpall.html
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_dumpall</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgdump.html" title="pg_dump" /><link rel="next" href="app-pg-isready.html" title="pg_isready" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_dumpall</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgdump.html" title="pg_dump">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pg-isready.html" title="pg_isready">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PG-DUMPALL"><div class="titlepage"></div><a id="id-1.9.4.14.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_dumpall</span></span></h2><p>pg_dumpall — extract a <span class="productname">PostgreSQL</span> database cluster into a script file</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.14.4.1"><code class="command">pg_dumpall</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="APP-PG-DUMPALL-DESCRIPTION"><h2>Description</h2><p>
+ <span class="application">pg_dumpall</span> is a utility for writing out
+ (<span class="quote">“<span class="quote">dumping</span>”</span>) all <span class="productname">PostgreSQL</span> databases
+ of a cluster into one script file. The script file contains
+ <acronym class="acronym">SQL</acronym> commands that can be used as input to <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> to restore the databases. It does this by
+ calling <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> for each database in the cluster.
+ <span class="application">pg_dumpall</span> also dumps global objects
+ that are common to all databases, namely database roles, tablespaces,
+ and privilege grants for configuration parameters.
+ (<span class="application">pg_dump</span> does not save these objects.)
+ </p><p>
+ Since <span class="application">pg_dumpall</span> reads tables from all
+ databases you will most likely have to connect as a database
+ superuser in order to produce a complete dump. Also you will need
+ superuser privileges to execute the saved script in order to be
+ allowed to add roles and create databases.
+ </p><p>
+ The SQL script will be written to the standard output. Use the
+ <code class="option">-f</code>/<code class="option">--file</code> option or shell operators to
+ redirect it into a file.
+ </p><p>
+ <span class="application">pg_dumpall</span> needs to connect several
+ times to the <span class="productname">PostgreSQL</span> server (once per
+ database). If you use password authentication it will ask for
+ a password each time. It is convenient to have a
+ <code class="filename">~/.pgpass</code> file in such cases. See <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a> for more information.
+ </p></div><div class="refsect1" id="id-1.9.4.14.6"><h2>Options</h2><p>
+ The following command-line options control the content and
+ format of the output.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--data-only</code></span></dt><dd><p>
+ Dump only the data, not the schema (data definitions).
+ </p></dd><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--clean</code></span></dt><dd><p>
+ Include SQL commands to clean (drop) databases before
+ recreating them. <code class="command">DROP</code> commands for roles and
+ tablespaces are added as well.
+ </p></dd><dt><span class="term"><code class="option">-E <em class="replaceable"><code>encoding</code></em></code><br /></span><span class="term"><code class="option">--encoding=<em class="replaceable"><code>encoding</code></em></code></span></dt><dd><p>
+ Create the dump in the specified character set encoding. By default,
+ the dump is created in the database encoding. (Another way to get the
+ same result is to set the <code class="envar">PGCLIENTENCODING</code> environment
+ variable to the desired dump encoding.)
+ </p></dd><dt><span class="term"><code class="option">-f <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--file=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Send output to the specified file. If this is omitted, the
+ standard output is used.
+ </p></dd><dt><span class="term"><code class="option">-g</code><br /></span><span class="term"><code class="option">--globals-only</code></span></dt><dd><p>
+ Dump only global objects (roles and tablespaces), no databases.
+ </p></dd><dt><span class="term"><code class="option">-O</code><br /></span><span class="term"><code class="option">--no-owner</code></span></dt><dd><p>
+ Do not output commands to set
+ ownership of objects to match the original database.
+ By default, <span class="application">pg_dumpall</span> issues
+ <code class="command">ALTER OWNER</code> or
+ <code class="command">SET SESSION AUTHORIZATION</code>
+ statements to set ownership of created schema elements.
+ These statements
+ will fail when the script is run unless it is started by a superuser
+ (or the same user that owns all of the objects in the script).
+ To make a script that can be restored by any user, but will give
+ that user ownership of all the objects, specify <code class="option">-O</code>.
+ </p></dd><dt><span class="term"><code class="option">-r</code><br /></span><span class="term"><code class="option">--roles-only</code></span></dt><dd><p>
+ Dump only roles, no databases or tablespaces.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--schema-only</code></span></dt><dd><p>
+ Dump only the object definitions (schema), not data.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--superuser=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Specify the superuser user name to use when disabling triggers.
+ This is relevant only if <code class="option">--disable-triggers</code> is used.
+ (Usually, it's better to leave this out, and instead start the
+ resulting script as superuser.)
+ </p></dd><dt><span class="term"><code class="option">-t</code><br /></span><span class="term"><code class="option">--tablespaces-only</code></span></dt><dd><p>
+ Dump only tablespaces, no databases or roles.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Specifies verbose mode. This will cause
+ <span class="application">pg_dumpall</span> to output start/stop
+ times to the dump file, and progress messages to standard error.
+ Repeating the option causes additional debug-level messages
+ to appear on standard error.
+ The option is also passed down to <span class="application">pg_dump</span>.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_dumpall</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-x</code><br /></span><span class="term"><code class="option">--no-privileges</code><br /></span><span class="term"><code class="option">--no-acl</code></span></dt><dd><p>
+ Prevent dumping of access privileges (grant/revoke commands).
+ </p></dd><dt><span class="term"><code class="option">--binary-upgrade</code></span></dt><dd><p>
+ This option is for use by in-place upgrade utilities. Its use
+ for other purposes is not recommended or supported. The
+ behavior of the option may change in future releases without
+ notice.
+ </p></dd><dt><span class="term"><code class="option">--column-inserts</code><br /></span><span class="term"><code class="option">--attribute-inserts</code></span></dt><dd><p>
+ Dump data as <code class="command">INSERT</code> commands with explicit
+ column names (<code class="literal">INSERT INTO
+ <em class="replaceable"><code>table</code></em>
+ (<em class="replaceable"><code>column</code></em>, ...) VALUES
+ ...</code>). This will make restoration very slow; it is mainly
+ useful for making dumps that can be loaded into
+ non-<span class="productname">PostgreSQL</span> databases.
+ </p></dd><dt><span class="term"><code class="option">--disable-dollar-quoting</code></span></dt><dd><p>
+ This option disables the use of dollar quoting for function bodies,
+ and forces them to be quoted using SQL standard string syntax.
+ </p></dd><dt><span class="term"><code class="option">--disable-triggers</code></span></dt><dd><p>
+ This option is relevant only when creating a data-only dump.
+ It instructs <span class="application">pg_dumpall</span> to include commands
+ to temporarily disable triggers on the target tables while
+ the data is restored. Use this if you have referential
+ integrity checks or other triggers on the tables that you
+ do not want to invoke during data restore.
+ </p><p>
+ Presently, the commands emitted for <code class="option">--disable-triggers</code>
+ must be done as superuser. So, you should also specify
+ a superuser name with <code class="option">-S</code>, or preferably be careful to
+ start the resulting script as a superuser.
+ </p></dd><dt><span class="term"><code class="option">--exclude-database=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Do not dump databases whose name matches
+ <em class="replaceable"><code>pattern</code></em>.
+ Multiple patterns can be excluded by writing multiple
+ <code class="option">--exclude-database</code> switches. The
+ <em class="replaceable"><code>pattern</code></em> parameter is
+ interpreted as a pattern according to the same rules used by
+ <span class="application">psql</span>'s <code class="literal">\d</code>
+ commands (see <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a> below),
+ so multiple databases can also be excluded by writing wildcard
+ characters in the pattern. When using wildcards, be careful to
+ quote the pattern if needed to prevent shell wildcard expansion.
+ </p></dd><dt><span class="term"><code class="option">--extra-float-digits=<em class="replaceable"><code>ndigits</code></em></code></span></dt><dd><p>
+ Use the specified value of extra_float_digits when dumping
+ floating-point data, instead of the maximum available precision.
+ Routine dumps made for backup purposes should not use this option.
+ </p></dd><dt><span class="term"><code class="option">--if-exists</code></span></dt><dd><p>
+ Use conditional commands (i.e., add an <code class="literal">IF EXISTS</code>
+ clause) to drop databases and other objects. This option is not valid
+ unless <code class="option">--clean</code> is also specified.
+ </p></dd><dt><span class="term"><code class="option">--inserts</code></span></dt><dd><p>
+ Dump data as <code class="command">INSERT</code> commands (rather
+ than <code class="command">COPY</code>). This will make restoration very slow;
+ it is mainly useful for making dumps that can be loaded into
+ non-<span class="productname">PostgreSQL</span> databases. Note that
+ the restore might fail altogether if you have rearranged column order.
+ The <code class="option">--column-inserts</code> option is safer, though even
+ slower.
+ </p></dd><dt><span class="term"><code class="option">--load-via-partition-root</code></span></dt><dd><p>
+ When dumping data for a table partition, make
+ the <code class="command">COPY</code> or <code class="command">INSERT</code> statements
+ target the root of the partitioning hierarchy that contains it, rather
+ than the partition itself. This causes the appropriate partition to
+ be re-determined for each row when the data is loaded. This may be
+ useful when restoring data on a server where rows do not always fall
+ into the same partitions as they did on the original server. That
+ could happen, for example, if the partitioning column is of type text
+ and the two systems have different definitions of the collation used
+ to sort the partitioning column.
+ </p></dd><dt><span class="term"><code class="option">--lock-wait-timeout=<em class="replaceable"><code>timeout</code></em></code></span></dt><dd><p>
+ Do not wait forever to acquire shared table locks at the beginning of
+ the dump. Instead, fail if unable to lock a table within the specified
+ <em class="replaceable"><code>timeout</code></em>. The timeout may be
+ specified in any of the formats accepted by <code class="command">SET
+ statement_timeout</code>.
+ </p></dd><dt><span class="term"><code class="option">--no-comments</code></span></dt><dd><p>
+ Do not dump comments.
+ </p></dd><dt><span class="term"><code class="option">--no-publications</code></span></dt><dd><p>
+ Do not dump publications.
+ </p></dd><dt><span class="term"><code class="option">--no-role-passwords</code></span></dt><dd><p>
+ Do not dump passwords for roles. When restored, roles will have a
+ null password, and password authentication will always fail until the
+ password is set. Since password values aren't needed when this option
+ is specified, the role information is read from the catalog
+ view <code class="structname">pg_roles</code> instead
+ of <code class="structname">pg_authid</code>. Therefore, this option also
+ helps if access to <code class="structname">pg_authid</code> is restricted by
+ some security policy.
+ </p></dd><dt><span class="term"><code class="option">--no-security-labels</code></span></dt><dd><p>
+ Do not dump security labels.
+ </p></dd><dt><span class="term"><code class="option">--no-subscriptions</code></span></dt><dd><p>
+ Do not dump subscriptions.
+ </p></dd><dt><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">pg_dumpall</code> will wait for all files
+ to be written safely to disk. This option causes
+ <code class="command">pg_dumpall</code> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the dump corrupt. Generally, this option is useful for testing
+ but should not be used when dumping data from production installation.
+ </p></dd><dt><span class="term"><code class="option">--no-table-access-method</code></span></dt><dd><p>
+ Do not output commands to select table access methods.
+ With this option, all objects will be created with whichever
+ table access method is the default during restore.
+ </p></dd><dt><span class="term"><code class="option">--no-tablespaces</code></span></dt><dd><p>
+ Do not output commands to create tablespaces nor select tablespaces
+ for objects.
+ With this option, all objects will be created in whichever
+ tablespace is the default during restore.
+ </p></dd><dt><span class="term"><code class="option">--no-toast-compression</code></span></dt><dd><p>
+ Do not output commands to set <acronym class="acronym">TOAST</acronym> compression
+ methods.
+ With this option, all columns will be restored with the default
+ compression setting.
+ </p></dd><dt><span class="term"><code class="option">--no-unlogged-table-data</code></span></dt><dd><p>
+ Do not dump the contents of unlogged tables. This option has no
+ effect on whether or not the table definitions (schema) are dumped;
+ it only suppresses dumping the table data.
+ </p></dd><dt><span class="term"><code class="option">--on-conflict-do-nothing</code></span></dt><dd><p>
+ Add <code class="literal">ON CONFLICT DO NOTHING</code> to
+ <code class="command">INSERT</code> commands.
+ This option is not valid unless <code class="option">--inserts</code> or
+ <code class="option">--column-inserts</code> is also specified.
+ </p></dd><dt><span class="term"><code class="option">--quote-all-identifiers</code></span></dt><dd><p>
+ Force quoting of all identifiers. This option is recommended when
+ dumping a database from a server whose <span class="productname">PostgreSQL</span>
+ major version is different from <span class="application">pg_dumpall</span>'s, or when
+ the output is intended to be loaded into a server of a different
+ major version. By default, <span class="application">pg_dumpall</span> quotes only
+ identifiers that are reserved words in its own major version.
+ This sometimes results in compatibility issues when dealing with
+ servers of other versions that may have slightly different sets
+ of reserved words. Using <code class="option">--quote-all-identifiers</code> prevents
+ such issues, at the price of a harder-to-read dump script.
+ </p></dd><dt><span class="term"><code class="option">--rows-per-insert=<em class="replaceable"><code>nrows</code></em></code></span></dt><dd><p>
+ Dump data as <code class="command">INSERT</code> commands (rather than
+ <code class="command">COPY</code>). Controls the maximum number of rows per
+ <code class="command">INSERT</code> command. The value specified must be a
+ number greater than zero. Any error during restoring will cause only
+ rows that are part of the problematic <code class="command">INSERT</code> to be
+ lost, rather than the entire table contents.
+ </p></dd><dt><span class="term"><code class="option">--use-set-session-authorization</code></span></dt><dd><p>
+ Output SQL-standard <code class="command">SET SESSION AUTHORIZATION</code> commands
+ instead of <code class="command">ALTER OWNER</code> commands to determine object
+ ownership. This makes the dump more standards compatible, but
+ depending on the history of the objects in the dump, might not restore
+ properly.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_dumpall</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control the database connection parameters.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>connstr</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>connstr</code></em></code></span></dt><dd><p>
+ Specifies parameters used to connect to the server, as a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>; these
+ will override any conflicting command line options.
+ </p><p>
+ The option is called <code class="literal">--dbname</code> for consistency with other
+ client applications, but because <span class="application">pg_dumpall</span>
+ needs to connect to many databases, the database name in the
+ connection string will be ignored. Use the <code class="literal">-l</code>
+ option to specify the name of the database used for the initial
+ connection, which will dump global objects and discover what other
+ databases should be dumped.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the database
+ server is running. If the value begins with a slash, it is
+ used as the directory for the Unix domain socket. The default
+ is taken from the <code class="envar">PGHOST</code> environment variable,
+ if set, else a Unix domain socket connection is attempted.
+ </p></dd><dt><span class="term"><code class="option">-l <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">--database=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to for dumping global
+ objects and discovering what other databases should be dumped. If
+ not specified, the <code class="literal">postgres</code> database will be used,
+ and if that does not exist, <code class="literal">template1</code> will be used.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <code class="envar">PGPORT</code> environment variable, if
+ set, or a compiled-in default.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">pg_dumpall</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_dumpall</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">pg_dumpall</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p><p>
+ Note that the password prompt will occur again for each database
+ to be dumped. Usually, it's better to set up a
+ <code class="filename">~/.pgpass</code> file than to rely on manual password entry.
+ </p></dd><dt><span class="term"><code class="option">--role=<em class="replaceable"><code>rolename</code></em></code></span></dt><dd><p>
+ Specifies a role name to be used to create the dump.
+ This option causes <span class="application">pg_dumpall</span> to issue a
+ <code class="command">SET ROLE</code> <em class="replaceable"><code>rolename</code></em>
+ command after connecting to the database. It is useful when the
+ authenticated user (specified by <code class="option">-U</code>) lacks privileges
+ needed by <span class="application">pg_dumpall</span>, but can switch to a role with
+ the required rights. Some installations have a policy against
+ logging in directly as a superuser, and use of this option allows
+ dumps to be made without violating the policy.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.14.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGOPTIONS</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.14.8"><h2>Notes</h2><p>
+ Since <span class="application">pg_dumpall</span> calls
+ <span class="application">pg_dump</span> internally, some diagnostic
+ messages will refer to <span class="application">pg_dump</span>.
+ </p><p>
+ The <code class="option">--clean</code> option can be useful even when your
+ intention is to restore the dump script into a fresh cluster. Use of
+ <code class="option">--clean</code> authorizes the script to drop and re-create the
+ built-in <code class="literal">postgres</code> and <code class="literal">template1</code>
+ databases, ensuring that those databases will retain the same properties
+ (for instance, locale and encoding) that they had in the source cluster.
+ Without the option, those databases will retain their existing
+ database-level properties, as well as any pre-existing contents.
+ </p><p>
+ Once restored, it is wise to run <code class="command">ANALYZE</code> on each
+ database so the optimizer has useful statistics. You
+ can also run <code class="command">vacuumdb -a -z</code> to analyze all
+ databases.
+ </p><p>
+ The dump script should not be expected to run completely without errors.
+ In particular, because the script will issue <code class="command">CREATE ROLE</code>
+ for every role existing in the source cluster, it is certain to get a
+ <span class="quote">“<span class="quote">role already exists</span>”</span> error for the bootstrap superuser,
+ unless the destination cluster was initialized with a different bootstrap
+ superuser name. This error is harmless and should be ignored. Use of
+ the <code class="option">--clean</code> option is likely to produce additional
+ harmless error messages about non-existent objects, although you can
+ minimize those by adding <code class="option">--if-exists</code>.
+ </p><p>
+ <span class="application">pg_dumpall</span> requires all needed
+ tablespace directories to exist before the restore; otherwise,
+ database creation will fail for databases in non-default
+ locations.
+ </p></div><div class="refsect1" id="APP-PG-DUMPALL-EX"><h2>Examples</h2><p>
+ To dump all databases:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dumpall &gt; db.out</code></strong>
+</pre><p>
+ </p><p>
+ To restore database(s) from this file, you can use:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>psql -f db.out postgres</code></strong>
+</pre><p>
+ It is not important to which database you connect here since the
+ script file created by <span class="application">pg_dumpall</span> will
+ contain the appropriate commands to create and connect to the saved
+ databases. An exception is that if you specified <code class="option">--clean</code>,
+ you must connect to the <code class="literal">postgres</code> database initially;
+ the script will attempt to drop other databases immediately, and that
+ will fail for the database you are connected to.
+ </p></div><div class="refsect1" id="id-1.9.4.14.10"><h2>See Also</h2><p>
+ Check <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> for details on possible
+ error conditions.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgdump.html" title="pg_dump">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pg-isready.html" title="pg_isready">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_dump</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_isready</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pg-isready.html b/doc/src/sgml/html/app-pg-isready.html
new file mode 100644
index 0000000..6af1dea
--- /dev/null
+++ b/doc/src/sgml/html/app-pg-isready.html
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_isready</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pg-dumpall.html" title="pg_dumpall" /><link rel="next" href="app-pgreceivewal.html" title="pg_receivewal" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_isready</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pg-dumpall.html" title="pg_dumpall">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgreceivewal.html" title="pg_receivewal">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PG-ISREADY"><div class="titlepage"></div><a id="id-1.9.4.15.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_isready</span></span></h2><p>pg_isready — check the connection status of a <span class="productname">PostgreSQL</span> server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.15.4.1"><code class="command">pg_isready</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="APP-PG-ISREADY-DESCRIPTION"><h2>Description</h2><p>
+ <span class="application">pg_isready</span> is a utility for checking the connection
+ status of a <span class="productname">PostgreSQL</span> database server. The exit
+ status specifies the result of the connection check.
+ </p></div><div class="refsect1" id="APP-PG-ISREADY-OPTIONS"><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to. The
+ <em class="replaceable"><code>dbname</code></em> can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>hostname</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>hostname</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the
+ server is running. If the value begins
+ with a slash, it is used as the directory for the Unix-domain
+ socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or the local Unix-domain
+ socket file extension on which the server is listening for
+ connections. Defaults to the value of the <code class="envar">PGPORT</code>
+ environment variable or, if not set, to the port specified at
+ compile time, usually 5432.
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Do not display status message. This is useful when scripting.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>seconds</code></em></code><br /></span><span class="term"><code class="option">--timeout=<em class="replaceable"><code>seconds</code></em></code></span></dt><dd><p>
+ The maximum number of seconds to wait when attempting connection before
+ returning that the server is not responding. Setting to 0 disables. The
+ default is 3 seconds.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Connect to the database as the user <em class="replaceable"><code>username</code></em> instead of the default.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_isready</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_isready</span> command line
+ arguments, and exit.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.4.15.7"><h2>Exit Status</h2><p>
+ <span class="application">pg_isready</span> returns <code class="literal">0</code> to the shell if the server
+ is accepting connections normally, <code class="literal">1</code> if the server is rejecting
+ connections (for example during startup), <code class="literal">2</code> if there was no response to the
+ connection attempt, and <code class="literal">3</code> if no attempt was made (for example due to invalid
+ parameters).
+ </p></div><div class="refsect1" id="id-1.9.4.15.8"><h2>Environment</h2><p>
+ <code class="command">pg_isready</code>, like most other <span class="productname">PostgreSQL</span>
+ utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="APP-PG-ISREADY-NOTES"><h2>Notes</h2><p>
+ It is not necessary to supply correct user name, password, or database
+ name values to obtain the server status; however, if incorrect values
+ are provided, the server will log a failed connection attempt.
+ </p></div><div class="refsect1" id="APP-PG-ISREADY-EXAMPLES"><h2>Examples</h2><p>
+ Standard Usage:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_isready</code></strong>
+<code class="computeroutput">/tmp:5432 - accepting connections</code>
+<code class="prompt">$</code> <strong class="userinput"><code>echo $?</code></strong>
+<code class="computeroutput">0</code>
+</pre><p>
+ </p><p>
+ Running with connection parameters to a <span class="productname">PostgreSQL</span> cluster in startup:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>pg_isready -h localhost -p 5433</code></strong>
+<code class="computeroutput">localhost:5433 - rejecting connections</code>
+<code class="prompt">$</code> <strong class="userinput"><code>echo $?</code></strong>
+<code class="computeroutput">1</code>
+</pre><p>
+ </p><p>
+ Running with connection parameters to a non-responsive <span class="productname">PostgreSQL</span> cluster:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>pg_isready -h someremotehost</code></strong>
+<code class="computeroutput">someremotehost:5432 - no response</code>
+<code class="prompt">$</code> <strong class="userinput"><code>echo $?</code></strong>
+<code class="computeroutput">2</code>
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pg-dumpall.html" title="pg_dumpall">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgreceivewal.html" title="pg_receivewal">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_dumpall</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_receivewal</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgamcheck.html b/doc/src/sgml/html/app-pgamcheck.html
new file mode 100644
index 0000000..833be43
--- /dev/null
+++ b/doc/src/sgml/html/app-pgamcheck.html
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_amcheck</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-ecpg.html" title="ecpg" /><link rel="next" href="app-pgbasebackup.html" title="pg_basebackup" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_amcheck</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-ecpg.html" title="ecpg">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgbasebackup.html" title="pg_basebackup">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGAMCHECK"><div class="titlepage"></div><a id="id-1.9.4.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_amcheck</span></span></h2><p>pg_amcheck — checks for corruption in one or more
+ <span class="productname">PostgreSQL</span> databases</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.9.4.1"><code class="command">pg_amcheck</code> [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>dbname</code></em>]</p></div></div><div class="refsect1" id="id-1.9.4.9.5"><h2>Description</h2><p>
+ <span class="application">pg_amcheck</span> supports running
+ <a class="xref" href="amcheck.html" title="F.2. amcheck">amcheck</a>'s corruption checking functions against one or
+ more databases, with options to select which schemas, tables and indexes to
+ check, which kinds of checking to perform, and whether to perform the checks
+ in parallel, and if so, the number of parallel connections to establish and
+ use.
+ </p><p>
+ Only ordinary and toast table relations, materialized views, sequences, and
+ btree indexes are currently supported. Other relation types are silently
+ skipped.
+ </p><p>
+ If <code class="literal">dbname</code> is specified, it should be the name of a
+ single database to check, and no other database selection options should
+ be present. Otherwise, if any database selection options are present,
+ all matching databases will be checked. If no such options are present,
+ the default database will be checked. Database selection options include
+ <code class="option">--all</code>, <code class="option">--database</code> and
+ <code class="option">--exclude-database</code>. They also include
+ <code class="option">--relation</code>, <code class="option">--exclude-relation</code>,
+ <code class="option">--table</code>, <code class="option">--exclude-table</code>,
+ <code class="option">--index</code>, and <code class="option">--exclude-index</code>,
+ but only when such options are used with a three-part pattern
+ (e.g. <code class="option">mydb*.myschema*.myrel*</code>). Finally, they include
+ <code class="option">--schema</code> and <code class="option">--exclude-schema</code>
+ when such options are used with a two-part pattern
+ (e.g. <code class="option">mydb*.myschema*</code>).
+ </p><p>
+ <em class="replaceable"><code>dbname</code></em> can also be a
+ <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>.
+ </p></div><div class="refsect1" id="id-1.9.4.9.6"><h2>Options</h2><p>
+ The following command-line options control what is checked:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--all</code></span></dt><dd><p>
+ Check all databases, except for any excluded via
+ <code class="option">--exclude-database</code>.
+ </p></dd><dt><span class="term"><code class="option">-d <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--database=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Check databases matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>,
+ except for any excluded by <code class="option">--exclude-database</code>.
+ This option can be specified more than once.
+ </p></dd><dt><span class="term"><code class="option">-D <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-database=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Exclude databases matching the given
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>.
+ This option can be specified more than once.
+ </p></dd><dt><span class="term"><code class="option">-i <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--index=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Check indexes matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>,
+ unless they are otherwise excluded.
+ This option can be specified more than once.
+ </p><p>
+ This is similar to the <code class="option">--relation</code> option, except that
+ it applies only to indexes, not to other relation types.
+ </p></dd><dt><span class="term"><code class="option">-I <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-index=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Exclude indexes matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>.
+ This option can be specified more than once.
+ </p><p>
+ This is similar to the <code class="option">--exclude-relation</code> option,
+ except that it applies only to indexes, not other relation types.
+ </p></dd><dt><span class="term"><code class="option">-r <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--relation=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Check relations matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>,
+ unless they are otherwise excluded.
+ This option can be specified more than once.
+ </p><p>
+ Patterns may be unqualified, e.g. <code class="literal">myrel*</code>, or they
+ may be schema-qualified, e.g. <code class="literal">myschema*.myrel*</code> or
+ database-qualified and schema-qualified, e.g.
+ <code class="literal">mydb*.myschema*.myrel*</code>. A database-qualified
+ pattern will add matching databases to the list of databases to be
+ checked.
+ </p></dd><dt><span class="term"><code class="option">-R <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-relation=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Exclude relations matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>.
+ This option can be specified more than once.
+ </p><p>
+ As with <code class="option">--relation</code>, the
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> may be unqualified, schema-qualified,
+ or database- and schema-qualified.
+ </p></dd><dt><span class="term"><code class="option">-s <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--schema=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Check tables and indexes in schemas matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>, unless they are otherwise excluded.
+ This option can be specified more than once.
+ </p><p>
+ To select only tables in schemas matching a particular pattern,
+ consider using something like
+ <code class="literal">--table=SCHEMAPAT.* --no-dependent-indexes</code>.
+ To select only indexes, consider using something like
+ <code class="literal">--index=SCHEMAPAT.*</code>.
+ </p><p>
+ A schema pattern may be database-qualified. For example, you may
+ write <code class="literal">--schema=mydb*.myschema*</code> to select
+ schemas matching <code class="literal">myschema*</code> in databases matching
+ <code class="literal">mydb*</code>.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-schema=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Exclude tables and indexes in schemas matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>.
+ This option can be specified more than once.
+ </p><p>
+ As with <code class="option">--schema</code>, the pattern may be
+ database-qualified.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Check tables matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>,
+ unless they are otherwise excluded.
+ This option can be specified more than once.
+ </p><p>
+ This is similar to the <code class="option">--relation</code> option, except that
+ it applies only to tables, materialized views, and sequences, not to
+ indexes.
+ </p></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-table=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Exclude tables matching the specified
+ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a>.
+ This option can be specified more than once.
+ </p><p>
+ This is similar to the <code class="option">--exclude-relation</code> option,
+ except that it applies only to tables, materialized views, and
+ sequences, not to indexes.
+ </p></dd><dt><span class="term"><code class="option">--no-dependent-indexes</code></span></dt><dd><p>
+ By default, if a table is checked, any btree indexes of that table
+ will also be checked, even if they are not explicitly selected by
+ an option such as <code class="literal">--index</code> or
+ <code class="literal">--relation</code>. This option suppresses that behavior.
+ </p></dd><dt><span class="term"><code class="option">--no-dependent-toast</code></span></dt><dd><p>
+ By default, if a table is checked, its toast table, if any, will also
+ be checked, even if it is not explicitly selected by an option
+ such as <code class="literal">--table</code> or <code class="literal">--relation</code>.
+ This option suppresses that behavior.
+ </p></dd><dt><span class="term"><code class="option">--no-strict-names</code></span></dt><dd><p>
+ By default, if an argument to <code class="literal">--database</code>,
+ <code class="literal">--table</code>, <code class="literal">--index</code>,
+ or <code class="literal">--relation</code> matches no objects, it is a fatal
+ error. This option downgrades that error to a warning.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control checking of tables:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--exclude-toast-pointers</code></span></dt><dd><p>
+ By default, whenever a toast pointer is encountered in a table,
+ a lookup is performed to ensure that it references apparently-valid
+ entries in the toast table. These checks can be quite slow, and this
+ option can be used to skip them.
+ </p></dd><dt><span class="term"><code class="option">--on-error-stop</code></span></dt><dd><p>
+ After reporting all corruptions on the first page of a table where
+ corruption is found, stop processing that table relation and move on
+ to the next table or index.
+ </p><p>
+ Note that index checking always stops after the first corrupt page.
+ This option only has meaning relative to table relations.
+ </p></dd><dt><span class="term"><code class="option">--skip=<em class="replaceable"><code>option</code></em></code></span></dt><dd><p>
+ If <code class="literal">all-frozen</code> is given, table corruption checks
+ will skip over pages in all tables that are marked as all frozen.
+ </p><p>
+ If <code class="literal">all-visible</code> is given, table corruption checks
+ will skip over pages in all tables that are marked as all visible.
+ </p><p>
+ By default, no pages are skipped. This can be specified as
+ <code class="literal">none</code>, but since this is the default, it need not be
+ mentioned.
+ </p></dd><dt><span class="term"><code class="option">--startblock=<em class="replaceable"><code>block</code></em></code></span></dt><dd><p>
+ Start checking at the specified block number. An error will occur if
+ the table relation being checked has fewer than this number of blocks.
+ This option does not apply to indexes, and is probably only useful
+ when checking a single table relation. See <code class="literal">--endblock</code>
+ for further caveats.
+ </p></dd><dt><span class="term"><code class="option">--endblock=<em class="replaceable"><code>block</code></em></code></span></dt><dd><p>
+ End checking at the specified block number. An error will occur if the
+ table relation being checked has fewer than this number of blocks.
+ This option does not apply to indexes, and is probably only useful when
+ checking a single table relation. If both a regular table and a toast
+ table are checked, this option will apply to both, but higher-numbered
+ toast blocks may still be accessed while validating toast pointers,
+ unless that is suppressed using
+ <code class="option">--exclude-toast-pointers</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control checking of B-tree indexes:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--heapallindexed</code></span></dt><dd><p>
+ For each index checked, verify the presence of all heap tuples as index
+ tuples in the index using <a class="xref" href="amcheck.html" title="F.2. amcheck">amcheck</a>'s
+ <code class="option">heapallindexed</code> option.
+ </p></dd><dt><span class="term"><code class="option">--parent-check</code></span></dt><dd><p>
+ For each btree index checked, use <a class="xref" href="amcheck.html" title="F.2. amcheck">amcheck</a>'s
+ <code class="function">bt_index_parent_check</code> function, which performs
+ additional checks of parent/child relationships during index checking.
+ </p><p>
+ The default is to use <span class="application">amcheck</span>'s
+ <code class="function">bt_index_check</code> function, but note that use of the
+ <code class="option">--rootdescend</code> option implicitly selects
+ <code class="function">bt_index_parent_check</code>.
+ </p></dd><dt><span class="term"><code class="option">--rootdescend</code></span></dt><dd><p>
+ For each index checked, re-find tuples on the leaf level by performing a
+ new search from the root page for each tuple using
+ <a class="xref" href="amcheck.html" title="F.2. amcheck">amcheck</a>'s <code class="option">rootdescend</code> option.
+ </p><p>
+ Use of this option implicitly also selects the
+ <code class="option">--parent-check</code> option.
+ </p><p>
+ This form of verification was originally written to help in the
+ development of btree index features. It may be of limited use or even
+ of no use in helping detect the kinds of corruption that occur in
+ practice. It may also cause corruption checking to take considerably
+ longer and consume considerably more resources on the server.
+ </p></dd></dl></div><p>
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ The extra checks performed against B-tree indexes when the
+ <code class="option">--parent-check</code> option or the
+ <code class="option">--rootdescend</code> option is specified require
+ relatively strong relation-level locks. These checks are the only
+ checks that will block concurrent data modification from
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> commands.
+ </p></div><p>
+ The following command-line options control the connection to the server:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>hostname</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>hostname</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is running.
+ If the value begins with a slash, it is used as the directory for the
+ Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file extension on
+ which the server is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U</code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires password
+ authentication and a password is not available by other means such as
+ a <code class="filename">.pgpass</code> file, the connection attempt will fail.
+ This option can be useful in batch jobs and scripts where no user is
+ present to enter a password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">pg_amcheck</span> to prompt for a password
+ before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_amcheck</span> will automatically prompt for a
+ password if the server demands password authentication. However,
+ <span class="application">pg_amcheck</span> will waste a connection attempt
+ finding out that the server wants a password. In some cases it is
+ worth typing <code class="option">-W</code> to avoid the extra connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--maintenance-db=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies a database or
+ <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a> to be
+ used to discover the list of databases to be checked. If neither
+ <code class="option">--all</code> nor any option including a database pattern is
+ used, no such connection is required and this option does nothing.
+ Otherwise, any connection string parameters other than
+ the database name which are included in the value for this option
+ will also be used when connecting to the databases
+ being checked. If this option is omitted, the default is
+ <code class="literal">postgres</code> or, if that fails,
+ <code class="literal">template1</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ Other options are also available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo to stdout all SQL sent to the server.
+ </p></dd><dt><span class="term"><code class="option">-j <em class="replaceable"><code>num</code></em></code><br /></span><span class="term"><code class="option">--jobs=<em class="replaceable"><code>num</code></em></code></span></dt><dd><p>
+ Use <em class="replaceable"><code>num</code></em> concurrent connections to the server,
+ or one per object to be checked, whichever is less.
+ </p><p>
+ The default is to use a single connection.
+ </p></dd><dt><span class="term"><code class="option">-P</code><br /></span><span class="term"><code class="option">--progress</code></span></dt><dd><p>
+ Show progress information. Progress information includes the number
+ of relations for which checking has been completed, and the total
+ size of those relations. It also includes the total number of relations
+ that will eventually be checked, and the estimated size of those
+ relations.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Print more messages. In particular, this will print a message for
+ each relation being checked, and will increase the level of detail
+ shown for server errors.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_amcheck</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">--install-missing</code><br /></span><span class="term"><code class="option">--install-missing=<em class="replaceable"><code>schema</code></em></code></span></dt><dd><p>
+ Install any missing extensions that are required to check the
+ database(s). If not yet installed, each extension's objects will be
+ installed into the given
+ <em class="replaceable"><code>schema</code></em>, or if not specified
+ into schema <code class="literal">pg_catalog</code>.
+ </p><p>
+ At present, the only required extension is <a class="xref" href="amcheck.html" title="F.2. amcheck">amcheck</a>.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_amcheck</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.9.7"><h2>Notes</h2><p>
+ <span class="application">pg_amcheck</span> is designed to work with
+ <span class="productname">PostgreSQL</span> 14.0 and later.
+ </p></div><div class="refsect1" id="id-1.9.4.9.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="amcheck.html" title="F.2. amcheck">amcheck</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-ecpg.html" title="ecpg">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgbasebackup.html" title="pg_basebackup">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">ecpg</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_basebackup</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgbasebackup.html b/doc/src/sgml/html/app-pgbasebackup.html
new file mode 100644
index 0000000..ea2594a
--- /dev/null
+++ b/doc/src/sgml/html/app-pgbasebackup.html
@@ -0,0 +1,550 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_basebackup</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgamcheck.html" title="pg_amcheck" /><link rel="next" href="pgbench.html" title="pgbench" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_basebackup</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgamcheck.html" title="pg_amcheck">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgbench.html" title="pgbench">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGBASEBACKUP"><div class="titlepage"></div><a id="id-1.9.4.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_basebackup</span></span></h2><p>pg_basebackup — take a base backup of a <span class="productname">PostgreSQL</span> cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.10.4.1"><code class="command">pg_basebackup</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.4.10.5"><h2>Description</h2><p>
+ <span class="application">pg_basebackup</span> is used to take a base backup of
+ a running <span class="productname">PostgreSQL</span> database cluster. The backup
+ is taken without affecting other clients of the database, and can be used
+ both for point-in-time recovery (see <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>)
+ and as the starting point for a log-shipping or streaming-replication standby
+ server (see <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>).
+ </p><p>
+ <span class="application">pg_basebackup</span> makes an exact copy of the database
+ cluster's files, while making sure the server is put into and
+ out of backup mode automatically. Backups are always taken of the entire
+ database cluster; it is not possible to back up individual databases or
+ database objects. For selective backups, another tool such as
+ <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> must be used.
+ </p><p>
+ The backup is made over a regular <span class="productname">PostgreSQL</span>
+ connection that uses the replication protocol. The connection must be made
+ with a user ID that has <code class="literal">REPLICATION</code> permissions
+ (see <a class="xref" href="role-attributes.html" title="22.2. Role Attributes">Section 22.2</a>) or is a superuser,
+ and <a class="link" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File"><code class="filename">pg_hba.conf</code></a>
+ must permit the replication connection. The server must also be configured
+ with <a class="xref" href="runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</a> set high enough to provide at
+ least one walsender for the backup plus one for WAL streaming (if used).
+ </p><p>
+ There can be multiple <code class="command">pg_basebackup</code>s running at the same time, but it is usually
+ better from a performance point of view to take only one backup, and copy
+ the result.
+ </p><p>
+ <span class="application">pg_basebackup</span> can make a base backup from
+ not only a primary server but also a standby. To take a backup from a standby,
+ set up the standby so that it can accept replication connections (that is, set
+ <code class="varname">max_wal_senders</code> and <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY">hot_standby</a>,
+ and configure its <code class="filename">pg_hba.conf</code> appropriately).
+ You will also need to enable <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a> on the primary.
+ </p><p>
+ Note that there are some limitations in taking a backup from a standby:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The backup history file is not created in the database cluster backed up.
+ </p></li><li class="listitem"><p>
+ <span class="application">pg_basebackup</span> cannot force the standby
+ to switch to a new WAL file at the end of backup.
+ When you are using <code class="literal">-X none</code>, if write activity on
+ the primary is low, <span class="application">pg_basebackup</span> may
+ need to wait a long time for the last WAL file required for the backup
+ to be switched and archived. In this case, it may be useful to run
+ <code class="function">pg_switch_wal</code> on the primary in order to
+ trigger an immediate WAL file switch.
+ </p></li><li class="listitem"><p>
+ If the standby is promoted to be primary during backup, the backup fails.
+ </p></li><li class="listitem"><p>
+ All WAL records required for the backup must contain sufficient full-page writes,
+ which requires you to enable <code class="varname">full_page_writes</code> on the primary.
+ </p></li></ul></div><p>
+ </p><p>
+ Whenever <span class="application">pg_basebackup</span> is taking a base
+ backup, the server's <code class="structname">pg_stat_progress_basebackup</code>
+ view will report the progress of the backup.
+ See <a class="xref" href="progress-reporting.html#BASEBACKUP-PROGRESS-REPORTING" title="28.4.5. Base Backup Progress Reporting">Section 28.4.5</a> for details.
+ </p></div><div class="refsect1" id="id-1.9.4.10.6"><h2>Options</h2><p>
+ The following command-line options control the location and format of the
+ output:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-D <em class="replaceable"><code>directory</code></em></code><br /></span><span class="term"><code class="option">--pgdata=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Sets the target directory to write the output to.
+ <span class="application">pg_basebackup</span> will create this directory
+ (and any missing parent directories) if it does not exist. If it
+ already exists, it must be empty.
+ </p><p>
+ When the backup is in tar format, the target directory may be
+ specified as <code class="literal">-</code> (dash), causing the tar file to be
+ written to <code class="literal">stdout</code>.
+ </p><p>
+ This option is required.
+ </p></dd><dt><span class="term"><code class="option">-F <em class="replaceable"><code>format</code></em></code><br /></span><span class="term"><code class="option">--format=<em class="replaceable"><code>format</code></em></code></span></dt><dd><p>
+ Selects the format for the output. <em class="replaceable"><code>format</code></em>
+ can be one of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">p</code><br /></span><span class="term"><code class="literal">plain</code></span></dt><dd><p>
+ Write the output as plain files, with the same layout as the
+ source server's data directory and tablespaces. When the cluster has
+ no additional tablespaces, the whole database will be placed in
+ the target directory. If the cluster contains additional
+ tablespaces, the main data directory will be placed in the
+ target directory, but all other tablespaces will be placed
+ in the same absolute path as they have on the source server.
+ (See <code class="option">--tablespace-mapping</code> to change that.)
+ </p><p>
+ This is the default format.
+ </p></dd><dt><span class="term"><code class="literal">t</code><br /></span><span class="term"><code class="literal">tar</code></span></dt><dd><p>
+ Write the output as tar files in the target directory. The main
+ data directory's contents will be written to a file named
+ <code class="filename">base.tar</code>, and each other tablespace will be
+ written to a separate tar file named after that tablespace's OID.
+ </p><p>
+ If the target directory is specified as <code class="literal">-</code>
+ (dash), the tar contents will be written to
+ standard output, suitable for piping to (for example)
+ <span class="productname">gzip</span>. This is only allowed if
+ the cluster has no additional tablespaces and WAL
+ streaming is not used.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="option">-R</code><br /></span><span class="term"><code class="option">--write-recovery-conf</code></span></dt><dd><p>
+ Creates a
+ <a class="link" href="warm-standby.html#FILE-STANDBY-SIGNAL"><code class="filename">standby.signal</code></a>
+ <a id="id-1.9.4.10.6.2.1.3.3.1.2" class="indexterm"></a>
+ file and appends
+ connection settings to the <code class="filename">postgresql.auto.conf</code>
+ file in the target directory (or within the base archive file when
+ using tar format). This eases setting up a standby server using the
+ results of the backup.
+ </p><p>
+ The <code class="filename">postgresql.auto.conf</code> file will record the connection
+ settings and, if specified, the replication slot
+ that <span class="application">pg_basebackup</span> is using, so that
+ streaming replication will use the same settings later on.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>target</code></em></code><br /></span><span class="term"><code class="option">--target=<em class="replaceable"><code>target</code></em></code></span></dt><dd><p>
+ Instructs the server where to place the base backup. The default target
+ is <code class="literal">client</code>, which specifies that the backup should
+ be sent to the machine where <span class="application">pg_basebackup</span>
+ is running. If the target is instead set to
+ <code class="literal">server:/some/path</code>, the backup will be stored on
+ the machine where the server is running in the
+ <code class="literal">/some/path</code> directory. Storing a backup on the
+ server requires superuser privileges or having privileges of the
+ <code class="literal">pg_write_server_files</code> role. If the target is set to
+ <code class="literal">blackhole</code>, the contents are discarded and not
+ stored anywhere. This should only be used for testing purposes, as you
+ will not end up with an actual backup.
+ </p><p>
+ Since WAL streaming is implemented by
+ <span class="application">pg_basebackup</span> rather than by the server,
+ this option cannot be used together with <code class="literal">-Xstream</code>.
+ Since that is the default, when this option is specified, you must also
+ specify either <code class="literal">-Xfetch</code> or <code class="literal">-Xnone</code>.
+ </p></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>olddir</code></em>=<em class="replaceable"><code>newdir</code></em></code><br /></span><span class="term"><code class="option">--tablespace-mapping=<em class="replaceable"><code>olddir</code></em>=<em class="replaceable"><code>newdir</code></em></code></span></dt><dd><p>
+ Relocates the tablespace in directory <em class="replaceable"><code>olddir</code></em>
+ to <em class="replaceable"><code>newdir</code></em> during the backup. To be
+ effective, <em class="replaceable"><code>olddir</code></em> must exactly match the
+ path specification of the tablespace as it is defined on the source
+ server. (But it is not an error if there is no tablespace
+ in <em class="replaceable"><code>olddir</code></em> on the source server.)
+ Meanwhile <em class="replaceable"><code>newdir</code></em> is a directory in the
+ receiving host's filesystem. As with the main target directory,
+ <em class="replaceable"><code>newdir</code></em> need not exist already, but if
+ it does exist it must be empty.
+ Both <em class="replaceable"><code>olddir</code></em>
+ and <em class="replaceable"><code>newdir</code></em> must be absolute paths. If
+ either path needs to contain an equal sign (<code class="literal">=</code>),
+ precede that with a backslash. This option can be specified multiple
+ times for multiple tablespaces.
+ </p><p>
+ If a tablespace is relocated in this way, the symbolic links inside
+ the main data directory are updated to point to the new location. So
+ the new data directory is ready to be used for a new server instance
+ with all tablespaces in the updated locations.
+ </p><p>
+ Currently, this option only works with plain output format; it is
+ ignored if tar format is selected.
+ </p></dd><dt><span class="term"><code class="option">--waldir=<em class="replaceable"><code>waldir</code></em></code></span></dt><dd><p>
+ Sets the directory to write WAL (write-ahead log) files to.
+ By default WAL files will be placed in
+ the <code class="filename">pg_wal</code> subdirectory of the target
+ directory, but this option can be used to place them elsewhere.
+ <em class="replaceable"><code>waldir</code></em> must be an absolute path.
+ As with the main target directory,
+ <em class="replaceable"><code>waldir</code></em> need not exist already, but if
+ it does exist it must be empty.
+ This option can only be specified when
+ the backup is in plain format.
+ </p></dd><dt><span class="term"><code class="option">-X <em class="replaceable"><code>method</code></em></code><br /></span><span class="term"><code class="option">--wal-method=<em class="replaceable"><code>method</code></em></code></span></dt><dd><p>
+ Includes the required WAL (write-ahead log) files in the
+ backup. This will include all write-ahead logs generated during
+ the backup. Unless the method <code class="literal">none</code> is specified,
+ it is possible to start a postmaster in the target
+ directory without the need to consult the log archive, thus
+ making the output a completely standalone backup.
+ </p><p>
+ The following <em class="replaceable"><code>method</code></em>s for collecting the
+ write-ahead logs are supported:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">n</code><br /></span><span class="term"><code class="literal">none</code></span></dt><dd><p>
+ Don't include write-ahead logs in the backup.
+ </p></dd><dt><span class="term"><code class="literal">f</code><br /></span><span class="term"><code class="literal">fetch</code></span></dt><dd><p>
+ The write-ahead log files are collected at the end of the backup.
+ Therefore, it is necessary for the source server's
+ <a class="xref" href="runtime-config-replication.html#GUC-WAL-KEEP-SIZE">wal_keep_size</a> parameter to be set high
+ enough that the required log data is not removed before the end
+ of the backup. If the required log data has been recycled
+ before it's time to transfer it, the backup will fail and be
+ unusable.
+ </p><p>
+ When tar format is used, the write-ahead log files will be
+ included in the <code class="filename">base.tar</code> file.
+ </p></dd><dt><span class="term"><code class="literal">s</code><br /></span><span class="term"><code class="literal">stream</code></span></dt><dd><p>
+ Stream write-ahead log data while the backup is being taken.
+ This method will open a second connection to the server and
+ start streaming the write-ahead log in parallel while running
+ the backup. Therefore, it will require two replication
+ connections not just one. As long as the client can keep up
+ with the write-ahead log data, using this method requires no
+ extra write-ahead logs to be saved on the source server.
+ </p><p>
+ When tar format is used, the write-ahead log files will be
+ written to a separate file named <code class="filename">pg_wal.tar</code>
+ (if the server is a version earlier than 10, the file will be named
+ <code class="filename">pg_xlog.tar</code>).
+ </p><p>
+ This value is the default.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="option">-z</code><br /></span><span class="term"><code class="option">--gzip</code></span></dt><dd><p>
+ Enables gzip compression of tar file output, with the default
+ compression level. Compression is only available when using
+ the tar format, and the suffix <code class="filename">.gz</code> will
+ automatically be added to all tar filenames.
+ </p></dd><dt><span class="term"><code class="option">-Z <em class="replaceable"><code>level</code></em></code><br /></span><span class="term"><code class="option">-Z [{client|server}-]<em class="replaceable"><code>method</code></em>[:<em class="replaceable"><code>detail</code></em>]</code><br /></span><span class="term"><code class="option">--compress=<em class="replaceable"><code>level</code></em></code><br /></span><span class="term"><code class="option">--compress=[{client|server}-]<em class="replaceable"><code>method</code></em>[:<em class="replaceable"><code>detail</code></em>]</code></span></dt><dd><p>
+ Requests compression of the backup. If <code class="literal">client</code> or
+ <code class="literal">server</code> is included, it specifies where the
+ compression is to be performed. Compressing on the server will reduce
+ transfer bandwidth but will increase server CPU consumption. The
+ default is <code class="literal">client</code> except when
+ <code class="literal">--target</code> is used. In that case, the backup is not
+ being sent to the client, so only server compression is sensible.
+ When <code class="literal">-Xstream</code>, which is the default, is used,
+ server-side compression will not be applied to the WAL. To compress
+ the WAL, use client-side compression, or
+ specify <code class="literal">-Xfetch</code>.
+ </p><p>
+ The compression method can be set to <code class="literal">gzip</code>,
+ <code class="literal">lz4</code>, <code class="literal">zstd</code>, or
+ <code class="literal">none</code> for no compression. A compression detail
+ string can optionally be specified. If the detail string is an
+ integer, it specifies the compression level. Otherwise, it should be
+ a comma-separated list of items, each of the form
+ <code class="literal">keyword</code> or <code class="literal">keyword=value</code>.
+ Currently, the supported keywords are <code class="literal">level</code>
+ and <code class="literal">workers</code>.
+ </p><p>
+ If no compression level is specified, the default compression level
+ will be used. If only a level is specified without mentioning an
+ algorithm, <code class="literal">gzip</code> compression will be used if the
+ level is greater than 0, and no compression will be used if the level
+ is 0.
+ </p><p>
+ When the tar format is used with <code class="literal">gzip</code>,
+ <code class="literal">lz4</code>, or <code class="literal">zstd</code>, the suffix
+ <code class="filename">.gz</code>, <code class="filename">.lz4</code>, or
+ <code class="filename">.zst</code>, respectively, will be automatically added to
+ all tar filenames. When the plain format is used, client-side
+ compression may not be specified, but it is still possible to request
+ server-side compression. If this is done, the server will compress the
+ backup for transmission, and the client will decompress and extract it.
+ </p><p>
+ When this option is used in combination with
+ <code class="literal">-Xstream</code>, <code class="literal">pg_wal.tar</code> will
+ be compressed using <code class="literal">gzip</code> if client-side gzip
+ compression is selected, but will not be compressed if any other
+ compression algorithm is selected, or if server-side compression
+ is selected.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control the generation of the
+ backup and the invocation of the program:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-c {fast|spread}</code><br /></span><span class="term"><code class="option">--checkpoint={fast|spread}</code></span></dt><dd><p>
+ Sets checkpoint mode to fast (immediate) or spread (the default)
+ (see <a class="xref" href="continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP" title="26.3.3. Making a Base Backup Using the Low Level API">Section 26.3.3</a>).
+ </p></dd><dt><span class="term"><code class="option">-C</code><br /></span><span class="term"><code class="option">--create-slot</code></span></dt><dd><p>
+ Specifies that the replication slot named by the
+ <code class="literal">--slot</code> option should be created before starting
+ the backup. An error is raised if the slot already exists.
+ </p></dd><dt><span class="term"><code class="option">-l <em class="replaceable"><code>label</code></em></code><br /></span><span class="term"><code class="option">--label=<em class="replaceable"><code>label</code></em></code></span></dt><dd><p>
+ Sets the label for the backup. If none is specified, a default value of
+ <span class="quote">“<span class="quote"><code class="literal">pg_basebackup base backup</code></span>”</span> will be used.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-clean</code></span></dt><dd><p>
+ By default, when <code class="command">pg_basebackup</code> aborts with an
+ error, it removes any directories it might have created before
+ discovering that it cannot finish the job (for example, the target
+ directory and write-ahead log directory). This option inhibits
+ tidying-up and is thus useful for debugging.
+ </p><p>
+ Note that tablespace directories are not cleaned up either way.
+ </p></dd><dt><span class="term"><code class="option">-N</code><br /></span><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">pg_basebackup</code> will wait for all files
+ to be written safely to disk. This option causes
+ <code class="command">pg_basebackup</code> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the base backup corrupt. Generally, this option is useful for testing
+ but should not be used when creating a production installation.
+ </p></dd><dt><span class="term"><code class="option">-P</code><br /></span><span class="term"><code class="option">--progress</code></span></dt><dd><p>
+ Enables progress reporting. Turning this on will deliver an approximate
+ progress report during the backup. Since the database may change during
+ the backup, this is only an approximation and may not end at exactly
+ <code class="literal">100%</code>. In particular, when WAL log is included in the
+ backup, the total amount of data cannot be estimated in advance, and
+ in this case the estimated target size will increase once it passes the
+ total estimate without WAL.
+ </p></dd><dt><span class="term"><code class="option">-r <em class="replaceable"><code>rate</code></em></code><br /></span><span class="term"><code class="option">--max-rate=<em class="replaceable"><code>rate</code></em></code></span></dt><dd><p>
+ Sets the maximum transfer rate at which data is collected from the
+ source server. This can be useful to limit the impact
+ of <span class="application">pg_basebackup</span> on the server. Values
+ are in kilobytes per second. Use a suffix of <code class="literal">M</code>
+ to indicate megabytes per second. A suffix of <code class="literal">k</code>
+ is also accepted, and has no effect. Valid values are between 32
+ kilobytes per second and 1024 megabytes per second.
+ </p><p>
+ This option always affects transfer of the data directory. Transfer of
+ WAL files is only affected if the collection method
+ is <code class="literal">fetch</code>.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>slotname</code></em></code><br /></span><span class="term"><code class="option">--slot=<em class="replaceable"><code>slotname</code></em></code></span></dt><dd><p>
+ This option can only be used together with <code class="literal">-X
+ stream</code>. It causes WAL streaming to use the specified
+ replication slot. If the base backup is intended to be used as a
+ streaming-replication standby using a replication slot, the standby
+ should then use the same replication slot name as
+ <a class="xref" href="runtime-config-replication.html#GUC-PRIMARY-SLOT-NAME">primary_slot_name</a>. This ensures that the
+ primary server does not remove any necessary WAL data in the time
+ between the end of the base backup and the start of streaming
+ replication on the new standby.
+ </p><p>
+ The specified replication slot has to exist unless the
+ option <code class="option">-C</code> is also used.
+ </p><p>
+ If this option is not specified and the server supports temporary
+ replication slots (version 10 and later), then a temporary replication
+ slot is automatically used for WAL streaming.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Enables verbose mode. Will output some extra steps during startup and
+ shutdown, as well as show the exact file name that is currently being
+ processed if progress reporting is also enabled.
+ </p></dd><dt><span class="term"><code class="option">--manifest-checksums=<em class="replaceable"><code>algorithm</code></em></code></span></dt><dd><p>
+ Specifies the checksum algorithm that should be applied to each file
+ included in the backup manifest. Currently, the available
+ algorithms are <code class="literal">NONE</code>, <code class="literal">CRC32C</code>,
+ <code class="literal">SHA224</code>, <code class="literal">SHA256</code>,
+ <code class="literal">SHA384</code>, and <code class="literal">SHA512</code>.
+ The default is <code class="literal">CRC32C</code>.
+ </p><p>
+ If <code class="literal">NONE</code> is selected, the backup manifest will
+ not contain any checksums. Otherwise, it will contain a checksum
+ of each file in the backup using the specified algorithm. In addition,
+ the manifest will always contain a <code class="literal">SHA256</code>
+ checksum of its own contents. The <code class="literal">SHA</code> algorithms
+ are significantly more CPU-intensive than <code class="literal">CRC32C</code>,
+ so selecting one of them may increase the time required to complete
+ the backup.
+ </p><p>
+ Using a SHA hash function provides a cryptographically secure digest
+ of each file for users who wish to verify that the backup has not been
+ tampered with, while the CRC32C algorithm provides a checksum that is
+ much faster to calculate; it is good at catching errors due to accidental
+ changes but is not resistant to malicious modifications. Note that, to
+ be useful against an adversary who has access to the backup, the backup
+ manifest would need to be stored securely elsewhere or otherwise
+ verified not to have been modified since the backup was taken.
+ </p><p>
+ <a class="xref" href="app-pgverifybackup.html" title="pg_verifybackup"><span class="refentrytitle"><span class="application">pg_verifybackup</span></span></a> can be used to check the
+ integrity of a backup against the backup manifest.
+ </p></dd><dt><span class="term"><code class="option">--manifest-force-encode</code></span></dt><dd><p>
+ Forces all filenames in the backup manifest to be hex-encoded.
+ If this option is not specified, only non-UTF8 filenames are
+ hex-encoded. This option is mostly intended to test that tools which
+ read a backup manifest file properly handle this case.
+ </p></dd><dt><span class="term"><code class="option">--no-estimate-size</code></span></dt><dd><p>
+ Prevents the server from estimating the total
+ amount of backup data that will be streamed, resulting in the
+ <code class="structfield">backup_total</code> column in the
+ <code class="structname">pg_stat_progress_basebackup</code> view
+ always being <code class="literal">NULL</code>.
+ </p><p>
+ Without this option, the backup will start by enumerating
+ the size of the entire database, and then go back and send
+ the actual contents. This may make the backup take slightly
+ longer, and in particular it will take longer before the first
+ data is sent. This option is useful to avoid such estimation
+ time if it's too long.
+ </p><p>
+ This option is not allowed when using <code class="option">--progress</code>.
+ </p></dd><dt><span class="term"><code class="option">--no-manifest</code></span></dt><dd><p>
+ Disables generation of a backup manifest. If this option is not
+ specified, the server will generate and send a backup manifest
+ which can be verified using <a class="xref" href="app-pgverifybackup.html" title="pg_verifybackup"><span class="refentrytitle"><span class="application">pg_verifybackup</span></span></a>.
+ The manifest is a list of every file present in the backup with the
+ exception of any WAL files that may be included. It also stores the
+ size, last modification time, and an optional checksum for each file.
+ </p></dd><dt><span class="term"><code class="option">--no-slot</code></span></dt><dd><p>
+ Prevents the creation of a temporary replication slot
+ for the backup.
+ </p><p>
+ By default, if log streaming is selected but no slot name is given
+ with the <code class="option">-S</code> option, then a temporary replication
+ slot is created (if supported by the source server).
+ </p><p>
+ The main purpose of this option is to allow taking a base backup when
+ the server has no free replication slots. Using a replication slot
+ is almost always preferred, because it prevents needed WAL from being
+ removed by the server during the backup.
+ </p></dd><dt><span class="term"><code class="option">--no-verify-checksums</code></span></dt><dd><p>
+ Disables verification of checksums, if they are enabled on the server
+ the base backup is taken from.
+ </p><p>
+ By default, checksums are verified and checksum failures will result
+ in a non-zero exit status. However, the base backup will not be
+ removed in such a case, as if the <code class="option">--no-clean</code> option
+ had been used. Checksum verification failures will also be reported
+ in the <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW" title="28.2.15. pg_stat_database">
+ <code class="structname">pg_stat_database</code></a> view.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control the connection to the source
+ server:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>connstr</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>connstr</code></em></code></span></dt><dd><p>
+ Specifies parameters used to connect to the server, as a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>; these
+ will override any conflicting command line options.
+ </p><p>
+ The option is called <code class="literal">--dbname</code> for consistency with other
+ client applications, but because <span class="application">pg_basebackup</span>
+ doesn't connect to any particular database in the cluster, any database
+ name in the connection string will be ignored.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for a Unix domain socket. The default is taken
+ from the <code class="envar">PGHOST</code> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <code class="envar">PGPORT</code> environment variable, if
+ set, or a compiled-in default.
+ </p></dd><dt><span class="term"><code class="option">-s <em class="replaceable"><code>interval</code></em></code><br /></span><span class="term"><code class="option">--status-interval=<em class="replaceable"><code>interval</code></em></code></span></dt><dd><p>
+ Specifies the number of seconds between status packets sent back to
+ the source server. Smaller values allow more accurate monitoring of
+ backup progress from the server.
+ A value of zero disables periodic status updates completely,
+ although an update will still be sent when requested by the server, to
+ avoid timeout-based disconnects. The default value is 10 seconds.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Specifies the user name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Prevents issuing a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Forces <span class="application">pg_basebackup</span> to prompt for a
+ password before connecting to the source server.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_basebackup</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">pg_basebackup</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd></dl></div><p>
+ </p><p>
+ Other options are also available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Prints the <span class="application">pg_basebackup</span> version and exits.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Shows help about <span class="application">pg_basebackup</span> command line
+ arguments, and exits.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.10.7"><h2>Environment</h2><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.4.10.8"><h2>Notes</h2><p>
+ At the beginning of the backup, a checkpoint needs to be performed on the
+ source server. This can take some time (especially if the option
+ <code class="literal">--checkpoint=fast</code> is not used), during
+ which <span class="application">pg_basebackup</span> will appear to be idle.
+ </p><p>
+ The backup will include all files in the data directory and tablespaces,
+ including the configuration files and any additional files placed in the
+ directory by third parties, except certain temporary files managed by
+ PostgreSQL. But only regular files and directories are copied, except that
+ symbolic links used for tablespaces are preserved. Symbolic links pointing
+ to certain directories known to PostgreSQL are copied as empty directories.
+ Other symbolic links and special device files are skipped.
+ See <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a> for the precise details.
+ </p><p>
+ In plain format, tablespaces will be backed up to the same path
+ they have on the source server, unless the
+ option <code class="literal">--tablespace-mapping</code> is used. Without
+ this option, running a plain format base backup on the same host as the
+ server will not work if tablespaces are in use, because the backup would
+ have to be written to the same directory locations as the original
+ tablespaces.
+ </p><p>
+ When tar format is used, it is the user's responsibility to unpack each
+ tar file before starting a PostgreSQL server that uses the data. If there
+ are additional tablespaces, the
+ tar files for them need to be unpacked in the correct locations. In this
+ case the symbolic links for those tablespaces will be created by the server
+ according to the contents of the <code class="filename">tablespace_map</code> file that is
+ included in the <code class="filename">base.tar</code> file.
+ </p><p>
+ <span class="application">pg_basebackup</span> works with servers of the same
+ or an older major version, down to 9.1. However, WAL streaming mode (<code class="literal">-X
+ stream</code>) only works with server version 9.3 and later, and tar format
+ (<code class="literal">--format=tar</code>) only works with server version 9.5
+ and later.
+ </p><p>
+ <span class="application">pg_basebackup</span> will preserve group permissions
+ for data files if group permissions are enabled on the source cluster.
+ </p></div><div class="refsect1" id="id-1.9.4.10.9"><h2>Examples</h2><p>
+ To create a base backup of the server at <code class="literal">mydbserver</code>
+ and store it in the local directory
+ <code class="filename">/usr/local/pgsql/data</code>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -h mydbserver -D /usr/local/pgsql/data</code></strong>
+</pre><p>
+ </p><p>
+ To create a backup of the local server with one compressed
+ tar file for each tablespace, and store it in the directory
+ <code class="filename">backup</code>, showing a progress report while running:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -D backup -Ft -z -P</code></strong>
+</pre><p>
+ </p><p>
+ To create a backup of a single-tablespace local database and compress
+ this with <span class="productname">bzip2</span>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -D - -Ft -X fetch | bzip2 &gt; backup.tar.bz2</code></strong>
+</pre><p>
+ (This command will fail if there are multiple tablespaces in the
+ database.)
+ </p><p>
+ To create a backup of a local database where the tablespace in
+ <code class="filename">/opt/ts</code> is relocated
+ to <code class="filename">./backup/ts</code>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -D backup/data -T /opt/ts=$(pwd)/backup/ts</code></strong>
+</pre><p>
+ To create a backup of a local server with one tar file for each tablespace
+ compressed with <span class="application">gzip</span> at level 9, stored in the
+ directory <code class="filename">backup</code>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -D backup -Ft --compress=gzip:9</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.10.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a>, <a class="xref" href="progress-reporting.html#BASEBACKUP-PROGRESS-REPORTING" title="28.4.5. Base Backup Progress Reporting">Section 28.4.5</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgamcheck.html" title="pg_amcheck">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgbench.html" title="pgbench">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_amcheck</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pgbench</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgchecksums.html b/doc/src/sgml/html/app-pgchecksums.html
new file mode 100644
index 0000000..3e08a4d
--- /dev/null
+++ b/doc/src/sgml/html/app-pgchecksums.html
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_checksums</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgarchivecleanup.html" title="pg_archivecleanup" /><link rel="next" href="app-pgcontroldata.html" title="pg_controldata" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_checksums</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgarchivecleanup.html" title="pg_archivecleanup">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgcontroldata.html" title="pg_controldata">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGCHECKSUMS"><div class="titlepage"></div><a id="id-1.9.5.5.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_checksums</span></span></h2><p>pg_checksums — enable, disable or check data checksums in a <span class="productname">PostgreSQL</span> database cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.5.4.1"><code class="command">pg_checksums</code> [<em class="replaceable"><code>option</code></em>...] [[ <code class="option">-D</code> | <code class="option">--pgdata</code> ]<em class="replaceable"><code>datadir</code></em>]</p></div></div><div class="refsect1" id="R1-APP-PG_CHECKSUMS-1"><h2>Description</h2><p>
+ <span class="application">pg_checksums</span> checks, enables or disables data
+ checksums in a <span class="productname">PostgreSQL</span> cluster. The server
+ must be shut down cleanly before running
+ <span class="application">pg_checksums</span>. When verifying checksums, the exit
+ status is zero if there are no checksum errors, and nonzero if at least one
+ checksum failure is detected. When enabling or disabling checksums, the
+ exit status is nonzero if the operation failed.
+ </p><p>
+ When verifying checksums, every file in the cluster is scanned. When
+ enabling checksums, each relation file block with a changed checksum is
+ rewritten in-place.
+ Disabling checksums only updates the file <code class="filename">pg_control</code>.
+ </p></div><div class="refsect1" id="id-1.9.5.5.6"><h2>Options</h2><p>
+ The following command-line options are available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-D <em class="replaceable"><code>directory</code></em></code><br /></span><span class="term"><code class="option">--pgdata=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Specifies the directory where the database cluster is stored.
+ </p></dd><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--check</code></span></dt><dd><p>
+ Checks checksums. This is the default mode if nothing else is
+ specified.
+ </p></dd><dt><span class="term"><code class="option">-d</code><br /></span><span class="term"><code class="option">--disable</code></span></dt><dd><p>
+ Disables checksums.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--enable</code></span></dt><dd><p>
+ Enables checksums.
+ </p></dd><dt><span class="term"><code class="option">-f <em class="replaceable"><code>filenode</code></em></code><br /></span><span class="term"><code class="option">--filenode=<em class="replaceable"><code>filenode</code></em></code></span></dt><dd><p>
+ Only validate checksums in the relation with filenode
+ <em class="replaceable"><code>filenode</code></em>.
+ </p></dd><dt><span class="term"><code class="option">-N</code><br /></span><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">pg_checksums</code> will wait for all files
+ to be written safely to disk. This option causes
+ <code class="command">pg_checksums</code> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the updated data directory corrupt. Generally, this option is useful
+ for testing but should not be used on a production installation.
+ This option has no effect when using <code class="literal">--check</code>.
+ </p></dd><dt><span class="term"><code class="option">-P</code><br /></span><span class="term"><code class="option">--progress</code></span></dt><dd><p>
+ Enable progress reporting. Turning this on will deliver a progress
+ report while checking or enabling checksums.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Enable verbose output. Lists all checked files.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_checksums</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_checksums</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.5.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATA</code></span></dt><dd><p>
+ Specifies the directory where the database cluster is
+ stored; can be overridden using the <code class="option">-D</code> option.
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.5.5.8"><h2>Notes</h2><p>
+ Enabling checksums in a large cluster can potentially take a long time.
+ During this operation, the cluster or other programs that write to the
+ data directory must not be started or else data loss may occur.
+ </p><p>
+ When using a replication setup with tools which perform direct copies
+ of relation file blocks (for example <a class="xref" href="app-pgrewind.html" title="pg_rewind"><span class="refentrytitle"><span class="application">pg_rewind</span></span></a>),
+ enabling or disabling checksums can lead to page corruptions in the
+ shape of incorrect checksums if the operation is not done consistently
+ across all nodes. When enabling or disabling checksums in a replication
+ setup, it is thus recommended to stop all the clusters before switching
+ them all consistently. Destroying all standbys, performing the operation
+ on the primary and finally recreating the standbys from scratch is also
+ safe.
+ </p><p>
+ If <span class="application">pg_checksums</span> is aborted or killed while
+ enabling or disabling checksums, the cluster's data checksum configuration
+ remains unchanged, and <span class="application">pg_checksums</span> can be
+ re-run to perform the same operation.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgarchivecleanup.html" title="pg_archivecleanup">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgcontroldata.html" title="pg_controldata">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_archivecleanup</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_controldata</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgconfig.html b/doc/src/sgml/html/app-pgconfig.html
new file mode 100644
index 0000000..91b59ab
--- /dev/null
+++ b/doc/src/sgml/html/app-pgconfig.html
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_config</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgbench.html" title="pgbench" /><link rel="next" href="app-pgdump.html" title="pg_dump" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_config</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgbench.html" title="pgbench">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgdump.html" title="pg_dump">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGCONFIG"><div class="titlepage"></div><a id="id-1.9.4.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_config</span></span></h2><p>pg_config — retrieve information about the installed version of <span class="productname">PostgreSQL</span></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.12.4.1"><code class="command">pg_config</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.4.12.5"><h2>Description</h2><p>
+ The <span class="application">pg_config</span> utility prints configuration parameters
+ of the currently installed version of <span class="productname">PostgreSQL</span>. It is
+ intended, for example, to be used by software packages that want to interface
+ to <span class="productname">PostgreSQL</span> to facilitate finding the required header files
+ and libraries.
+ </p></div><div class="refsect1" id="id-1.9.4.12.6"><h2>Options</h2><p>
+ To use <span class="application">pg_config</span>, supply one or more of the following
+ options:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--bindir</code></span></dt><dd><p>
+ Print the location of user executables. Use this, for example, to find
+ the <code class="command">psql</code> program. This is normally also the location
+ where the <code class="filename">pg_config</code> program resides.
+ </p></dd><dt><span class="term"><code class="option">--docdir</code></span></dt><dd><p>
+ Print the location of documentation files.
+ </p></dd><dt><span class="term"><code class="option">--htmldir</code></span></dt><dd><p>
+ Print the location of HTML documentation files.
+ </p></dd><dt><span class="term"><code class="option">--includedir</code></span></dt><dd><p>
+ Print the location of C header files of the client interfaces.
+ </p></dd><dt><span class="term"><code class="option">--pkgincludedir</code></span></dt><dd><p>
+ Print the location of other C header files.
+ </p></dd><dt><span class="term"><code class="option">--includedir-server</code></span></dt><dd><p>
+ Print the location of C header files for server programming.
+ </p></dd><dt><span class="term"><code class="option">--libdir</code></span></dt><dd><p>
+ Print the location of object code libraries.
+ </p></dd><dt><span class="term"><code class="option">--pkglibdir</code></span></dt><dd><p>
+ Print the location of dynamically loadable modules, or where
+ the server would search for them. (Other
+ architecture-dependent data files might also be installed in this
+ directory.)
+ </p></dd><dt><span class="term"><code class="option">--localedir</code></span></dt><dd><p>
+ Print the location of locale support files. (This will be an empty
+ string if locale support was not configured when
+ <span class="productname">PostgreSQL</span> was built.)
+ </p></dd><dt><span class="term"><code class="option">--mandir</code></span></dt><dd><p>
+ Print the location of manual pages.
+ </p></dd><dt><span class="term"><code class="option">--sharedir</code></span></dt><dd><p>
+ Print the location of architecture-independent support files.
+ </p></dd><dt><span class="term"><code class="option">--sysconfdir</code></span></dt><dd><p>
+ Print the location of system-wide configuration files.
+ </p></dd><dt><span class="term"><code class="option">--pgxs</code></span></dt><dd><p>
+ Print the location of extension makefiles.
+ </p></dd><dt><span class="term"><code class="option">--configure</code></span></dt><dd><p>
+ Print the options that were given to the <code class="filename">configure</code>
+ script when <span class="productname">PostgreSQL</span> was configured for building.
+ This can be used to reproduce the identical configuration, or
+ to find out with what options a binary package was built. (Note
+ however that binary packages often contain vendor-specific custom
+ patches.) See also the examples below.
+ </p></dd><dt><span class="term"><code class="option">--cc</code></span></dt><dd><p>
+ Print the value of the <code class="varname">CC</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows the C compiler used.
+ </p></dd><dt><span class="term"><code class="option">--cppflags</code></span></dt><dd><p>
+ Print the value of the <code class="varname">CPPFLAGS</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows C compiler switches needed
+ at preprocessing time (typically, <code class="literal">-I</code> switches).
+ </p></dd><dt><span class="term"><code class="option">--cflags</code></span></dt><dd><p>
+ Print the value of the <code class="varname">CFLAGS</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows C compiler switches.
+ </p></dd><dt><span class="term"><code class="option">--cflags_sl</code></span></dt><dd><p>
+ Print the value of the <code class="varname">CFLAGS_SL</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows extra C compiler switches
+ used for building shared libraries.
+ </p></dd><dt><span class="term"><code class="option">--ldflags</code></span></dt><dd><p>
+ Print the value of the <code class="varname">LDFLAGS</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows linker switches.
+ </p></dd><dt><span class="term"><code class="option">--ldflags_ex</code></span></dt><dd><p>
+ Print the value of the <code class="varname">LDFLAGS_EX</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows linker switches
+ used for building executables only.
+ </p></dd><dt><span class="term"><code class="option">--ldflags_sl</code></span></dt><dd><p>
+ Print the value of the <code class="varname">LDFLAGS_SL</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This shows linker switches
+ used for building shared libraries only.
+ </p></dd><dt><span class="term"><code class="option">--libs</code></span></dt><dd><p>
+ Print the value of the <code class="varname">LIBS</code> variable that was used for building
+ <span class="productname">PostgreSQL</span>. This normally contains <code class="literal">-l</code>
+ switches for external libraries linked into <span class="productname">PostgreSQL</span>.
+ </p></dd><dt><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the version of <span class="productname">PostgreSQL</span>.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_config</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+
+ If more than one option is given, the information is printed in that order,
+ one item per line. If no options are given, all available information
+ is printed, with labels.
+ </p></div><div class="refsect1" id="id-1.9.4.12.7"><h2>Notes</h2><p>
+ The options <code class="option">--docdir</code>, <code class="option">--pkgincludedir</code>,
+ <code class="option">--localedir</code>, <code class="option">--mandir</code>,
+ <code class="option">--sharedir</code>, <code class="option">--sysconfdir</code>,
+ <code class="option">--cc</code>, <code class="option">--cppflags</code>,
+ <code class="option">--cflags</code>, <code class="option">--cflags_sl</code>,
+ <code class="option">--ldflags</code>, <code class="option">--ldflags_sl</code>,
+ and <code class="option">--libs</code> were added in <span class="productname">PostgreSQL</span> 8.1.
+ The option <code class="option">--htmldir</code> was added in <span class="productname">PostgreSQL</span> 8.4.
+ The option <code class="option">--ldflags_ex</code> was added in <span class="productname">PostgreSQL</span> 9.0.
+ </p></div><div class="refsect1" id="id-1.9.4.12.8"><h2>Example</h2><p>
+ To reproduce the build configuration of the current PostgreSQL
+ installation, run the following command:
+</p><pre class="programlisting">
+eval ./configure `pg_config --configure`
+</pre><p>
+ The output of <code class="literal">pg_config --configure</code> contains
+ shell quotation marks so arguments with spaces are represented
+ correctly. Therefore, using <code class="literal">eval</code> is required
+ for proper results.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgbench.html" title="pgbench">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgdump.html" title="pg_dump">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pgbench</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_dump</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgcontroldata.html b/doc/src/sgml/html/app-pgcontroldata.html
new file mode 100644
index 0000000..d6b8241
--- /dev/null
+++ b/doc/src/sgml/html/app-pgcontroldata.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_controldata</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgchecksums.html" title="pg_checksums" /><link rel="next" href="app-pg-ctl.html" title="pg_ctl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_controldata</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgchecksums.html" title="pg_checksums">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pg-ctl.html" title="pg_ctl">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGCONTROLDATA"><div class="titlepage"></div><a id="id-1.9.5.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_controldata</span></span></h2><p>pg_controldata — display control information of a <span class="productname">PostgreSQL</span> database cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.6.4.1"><code class="command">pg_controldata</code> [<em class="replaceable"><code>option</code></em>] [[ <code class="option">-D</code> | <code class="option">--pgdata</code> ]<em class="replaceable"><code>datadir</code></em>]</p></div></div><div class="refsect1" id="R1-APP-PGCONTROLDATA-1"><h2>Description</h2><p>
+ <code class="command">pg_controldata</code> prints information initialized during
+ <code class="command">initdb</code>, such as the catalog version.
+ It also shows information about write-ahead logging and checkpoint
+ processing. This information is cluster-wide, and not specific to any one
+ database.
+ </p><p>
+ This utility can only be run by the user who initialized the cluster because
+ it requires read access to the data directory.
+ You can specify the data directory on the command line, or use
+ the environment variable <code class="envar">PGDATA</code>. This utility supports the options
+ <code class="option">-V</code> and <code class="option">--version</code>, which print the
+ <span class="application">pg_controldata</span> version and exit. It also
+ supports options <code class="option">-?</code> and <code class="option">--help</code>, which output the
+ supported arguments.
+ </p></div><div class="refsect1" id="id-1.9.5.6.6"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATA</code></span></dt><dd><p>
+ Default data directory location
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgchecksums.html" title="pg_checksums">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pg-ctl.html" title="pg_ctl">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_checksums</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_ctl</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgdump.html b/doc/src/sgml/html/app-pgdump.html
new file mode 100644
index 0000000..4fbf8e1
--- /dev/null
+++ b/doc/src/sgml/html/app-pgdump.html
@@ -0,0 +1,821 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_dump</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgconfig.html" title="pg_config" /><link rel="next" href="app-pg-dumpall.html" title="pg_dumpall" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_dump</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgconfig.html" title="pg_config">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pg-dumpall.html" title="pg_dumpall">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGDUMP"><div class="titlepage"></div><a id="id-1.9.4.13.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_dump</span></span></h2><p>pg_dump —
+ extract a <span class="productname">PostgreSQL</span> database into a script file or other archive file
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.13.4.1"><code class="command">pg_dump</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>dbname</code></em>]</p></div></div><div class="refsect1" id="PG-DUMP-DESCRIPTION"><h2>Description</h2><p>
+ <span class="application">pg_dump</span> is a utility for backing up a
+ <span class="productname">PostgreSQL</span> database. It makes consistent
+ backups even if the database is being used concurrently.
+ <span class="application">pg_dump</span> does not block other users
+ accessing the database (readers or writers).
+ </p><p>
+ <span class="application">pg_dump</span> only dumps a single database.
+ To back up an entire cluster, or to back up global objects that are
+ common to all databases in a cluster (such as roles and tablespaces),
+ use <a class="xref" href="app-pg-dumpall.html" title="pg_dumpall"><span class="refentrytitle"><span class="application">pg_dumpall</span></span></a>.
+ </p><p>
+ Dumps can be output in script or archive file formats. Script
+ dumps are plain-text files containing the SQL commands required
+ to reconstruct the database to the state it was in at the time it was
+ saved. To restore from such a script, feed it to <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>. Script files
+ can be used to reconstruct the database even on other machines and
+ other architectures; with some modifications, even on other SQL
+ database products.
+ </p><p>
+ The alternative archive file formats must be used with
+ <a class="xref" href="app-pgrestore.html" title="pg_restore"><span class="refentrytitle"><span class="application">pg_restore</span></span></a> to rebuild the database. They
+ allow <span class="application">pg_restore</span> to be selective about
+ what is restored, or even to reorder the items prior to being
+ restored.
+ The archive file formats are designed to be portable across
+ architectures.
+ </p><p>
+ When used with one of the archive file formats and combined with
+ <span class="application">pg_restore</span>,
+ <span class="application">pg_dump</span> provides a flexible archival and
+ transfer mechanism. <span class="application">pg_dump</span> can be used to
+ backup an entire database, then <span class="application">pg_restore</span>
+ can be used to examine the archive and/or select which parts of the
+ database are to be restored. The most flexible output file formats are
+ the <span class="quote">“<span class="quote">custom</span>”</span> format (<code class="option">-Fc</code>) and the
+ <span class="quote">“<span class="quote">directory</span>”</span> format (<code class="option">-Fd</code>). They allow
+ for selection and reordering of all archived items, support parallel
+ restoration, and are compressed by default. The <span class="quote">“<span class="quote">directory</span>”</span>
+ format is the only format that supports parallel dumps.
+ </p><p>
+ While running <span class="application">pg_dump</span>, one should examine the
+ output for any warnings (printed on standard error), especially in
+ light of the limitations listed below.
+ </p></div><div class="refsect1" id="PG-DUMP-OPTIONS"><h2>Options</h2><p>
+ The following command-line options control the content and
+ format of the output.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>dbname</code></em></span></dt><dd><p>
+ Specifies the name of the database to be dumped. If this is
+ not specified, the environment variable
+ <code class="envar">PGDATABASE</code> is used. If that is not set, the
+ user name specified for the connection is used.
+ </p></dd><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--data-only</code></span></dt><dd><p>
+ Dump only the data, not the schema (data definitions).
+ Table data, large objects, and sequence values are dumped.
+ </p><p>
+ This option is similar to, but for historical reasons not identical
+ to, specifying <code class="option">--section=data</code>.
+ </p></dd><dt><span class="term"><code class="option">-b</code><br /></span><span class="term"><code class="option">--blobs</code></span></dt><dd><p>
+ Include large objects in the dump. This is the default behavior
+ except when <code class="option">--schema</code>, <code class="option">--table</code>, or
+ <code class="option">--schema-only</code> is specified. The <code class="option">-b</code>
+ switch is therefore only useful to add large objects to dumps
+ where a specific schema or table has been requested. Note that
+ blobs are considered data and therefore will be included when
+ <code class="option">--data-only</code> is used, but not
+ when <code class="option">--schema-only</code> is.
+ </p></dd><dt><span class="term"><code class="option">-B</code><br /></span><span class="term"><code class="option">--no-blobs</code></span></dt><dd><p>
+ Exclude large objects in the dump.
+ </p><p>
+ When both <code class="option">-b</code> and <code class="option">-B</code> are given, the behavior
+ is to output large objects, when data is being dumped, see the
+ <code class="option">-b</code> documentation.
+ </p></dd><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--clean</code></span></dt><dd><p>
+ Output commands to clean (drop)
+ database objects prior to outputting the commands for creating them.
+ (Unless <code class="option">--if-exists</code> is also specified,
+ restore might generate some harmless error messages, if any objects
+ were not present in the destination database.)
+ </p><p>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <code class="command">pg_restore</code>.
+ </p></dd><dt><span class="term"><code class="option">-C</code><br /></span><span class="term"><code class="option">--create</code></span></dt><dd><p>
+ Begin the output with a command to create the
+ database itself and reconnect to the created database. (With a
+ script of this form, it doesn't matter which database in the
+ destination installation you connect to before running the script.)
+ If <code class="option">--clean</code> is also specified, the script drops and
+ recreates the target database before reconnecting to it.
+ </p><p>
+ With <code class="option">--create</code>, the output also includes the
+ database's comment if any, and any configuration variable settings
+ that are specific to this database, that is,
+ any <code class="command">ALTER DATABASE ... SET ...</code>
+ and <code class="command">ALTER ROLE ... IN DATABASE ... SET ...</code>
+ commands that mention this database.
+ Access privileges for the database itself are also dumped,
+ unless <code class="option">--no-acl</code> is specified.
+ </p><p>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <code class="command">pg_restore</code>.
+ </p></dd><dt><span class="term"><code class="option">-e <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--extension=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Dump only extensions matching <em class="replaceable"><code>pattern</code></em>. When this option is not
+ specified, all non-system extensions in the target database will be
+ dumped. Multiple extensions can be selected by writing multiple
+ <code class="option">-e</code> switches. The <em class="replaceable"><code>pattern</code></em> parameter is interpreted as a
+ pattern according to the same rules used by
+ <span class="application">psql</span>'s <code class="literal">\d</code> commands (see
+ <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a>), so multiple extensions can also
+ be selected by writing wildcard characters in the pattern. When using
+ wildcards, be careful to quote the pattern if needed to prevent the
+ shell from expanding the wildcards.
+ </p><p>
+ Any configuration relation registered by
+ <code class="function">pg_extension_config_dump</code> is included in the
+ dump if its extension is specified by <code class="option">--extension</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When <code class="option">-e</code> is specified,
+ <span class="application">pg_dump</span> makes no attempt to dump any other
+ database objects that the selected extension(s) might depend upon.
+ Therefore, there is no guarantee that the results of a
+ specific-extension dump can be successfully restored by themselves
+ into a clean database.
+ </p></div></dd><dt><span class="term"><code class="option">-E <em class="replaceable"><code>encoding</code></em></code><br /></span><span class="term"><code class="option">--encoding=<em class="replaceable"><code>encoding</code></em></code></span></dt><dd><p>
+ Create the dump in the specified character set encoding. By default,
+ the dump is created in the database encoding. (Another way to get the
+ same result is to set the <code class="envar">PGCLIENTENCODING</code> environment
+ variable to the desired dump encoding.) The supported encodings are
+ described in <a class="xref" href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED" title="24.3.1. Supported Character Sets">Section 24.3.1</a>.
+ </p></dd><dt><span class="term"><code class="option">-f <em class="replaceable"><code>file</code></em></code><br /></span><span class="term"><code class="option">--file=<em class="replaceable"><code>file</code></em></code></span></dt><dd><p>
+ Send output to the specified file. This parameter can be omitted for
+ file based output formats, in which case the standard output is used.
+ It must be given for the directory output format however, where it
+ specifies the target directory instead of a file. In this case the
+ directory is created by <code class="command">pg_dump</code> and must not exist
+ before.
+ </p></dd><dt><span class="term"><code class="option">-F <em class="replaceable"><code>format</code></em></code><br /></span><span class="term"><code class="option">--format=<em class="replaceable"><code>format</code></em></code></span></dt><dd><p>
+ Selects the format of the output.
+ <em class="replaceable"><code>format</code></em> can be one of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">p</code><br /></span><span class="term"><code class="literal">plain</code></span></dt><dd><p>
+ Output a plain-text <acronym class="acronym">SQL</acronym> script file (the default).
+ </p></dd><dt><span class="term"><code class="literal">c</code><br /></span><span class="term"><code class="literal">custom</code></span></dt><dd><p>
+ Output a custom-format archive suitable for input into
+ <span class="application">pg_restore</span>.
+ Together with the directory output format, this is the most flexible
+ output format in that it allows manual selection and reordering of
+ archived items during restore. This format is also compressed by
+ default.
+ </p></dd><dt><span class="term"><code class="literal">d</code><br /></span><span class="term"><code class="literal">directory</code></span></dt><dd><p>
+ Output a directory-format archive suitable for input into
+ <span class="application">pg_restore</span>. This will create a directory
+ with one file for each table and blob being dumped, plus a
+ so-called Table of Contents file describing the dumped objects in a
+ machine-readable format that <span class="application">pg_restore</span>
+ can read. A directory format archive can be manipulated with
+ standard Unix tools; for example, files in an uncompressed archive
+ can be compressed with the <span class="application">gzip</span> tool.
+ This format is compressed by default and also supports parallel
+ dumps.
+ </p></dd><dt><span class="term"><code class="literal">t</code><br /></span><span class="term"><code class="literal">tar</code></span></dt><dd><p>
+ Output a <code class="command">tar</code>-format archive suitable for input
+ into <span class="application">pg_restore</span>. The tar format is
+ compatible with the directory format: extracting a tar-format
+ archive produces a valid directory-format archive.
+ However, the tar format does not support compression. Also, when
+ using tar format the relative order of table data items cannot be
+ changed during restore.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="option">-j <em class="replaceable"><code>njobs</code></em></code><br /></span><span class="term"><code class="option">--jobs=<em class="replaceable"><code>njobs</code></em></code></span></dt><dd><p>
+ Run the dump in parallel by dumping <em class="replaceable"><code>njobs</code></em>
+ tables simultaneously. This option may reduce the time needed to perform the dump but it also
+ increases the load on the database server. You can only use this option with the
+ directory output format because this is the only output format where multiple processes
+ can write their data at the same time.
+ </p><p><span class="application">pg_dump</span> will open <em class="replaceable"><code>njobs</code></em>
+ + 1 connections to the database, so make sure your <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>
+ setting is high enough to accommodate all connections.
+ </p><p>
+ Requesting exclusive locks on database objects while running a parallel dump could
+ cause the dump to fail. The reason is that the <span class="application">pg_dump</span> leader process
+ requests shared locks (<a class="link" href="explicit-locking.html#LOCKING-TABLES" title="13.3.1. Table-Level Locks">ACCESS SHARE</a>) on the
+ objects that the worker processes are going to dump later in order to
+ make sure that nobody deletes them and makes them go away while the dump is running.
+ If another client then requests an exclusive lock on a table, that lock will not be
+ granted but will be queued waiting for the shared lock of the leader process to be
+ released. Consequently any other access to the table will not be granted either and
+ will queue after the exclusive lock request. This includes the worker process trying
+ to dump the table. Without any precautions this would be a classic deadlock situation.
+ To detect this conflict, the <span class="application">pg_dump</span> worker process requests another
+ shared lock using the <code class="literal">NOWAIT</code> option. If the worker process is not granted
+ this shared lock, somebody else must have requested an exclusive lock in the meantime
+ and there is no way to continue with the dump, so <span class="application">pg_dump</span> has no choice
+ but to abort the dump.
+ </p><p>
+ To perform a parallel dump, the database server needs to support
+ synchronized snapshots, a feature that was introduced in
+ <span class="productname">PostgreSQL</span> 9.2 for primary servers and 10
+ for standbys. With this feature, database clients can ensure they see
+ the same data set even though they use different connections.
+ <code class="command">pg_dump -j</code> uses multiple database connections; it
+ connects to the database once with the leader process and once again
+ for each worker job. Without the synchronized snapshot feature, the
+ different worker jobs wouldn't be guaranteed to see the same data in
+ each connection, which could lead to an inconsistent backup.
+ </p></dd><dt><span class="term"><code class="option">-n <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--schema=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Dump only schemas matching <em class="replaceable"><code>pattern</code></em>; this selects both the
+ schema itself, and all its contained objects. When this option is
+ not specified, all non-system schemas in the target database will be
+ dumped. Multiple schemas can be
+ selected by writing multiple <code class="option">-n</code> switches. The
+ <em class="replaceable"><code>pattern</code></em> parameter is
+ interpreted as a pattern according to the same rules used by
+ <span class="application">psql</span>'s <code class="literal">\d</code> commands
+ (see <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a> below),
+ so multiple schemas can also be selected by writing wildcard characters
+ in the pattern. When using wildcards, be careful to quote the pattern
+ if needed to prevent the shell from expanding the wildcards; see
+ <a class="xref" href="app-pgdump.html#PG-DUMP-EXAMPLES" title="Examples">Examples</a> below.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When <code class="option">-n</code> is specified, <span class="application">pg_dump</span>
+ makes no attempt to dump any other database objects that the selected
+ schema(s) might depend upon. Therefore, there is no guarantee
+ that the results of a specific-schema dump can be successfully
+ restored by themselves into a clean database.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Non-schema objects such as blobs are not dumped when <code class="option">-n</code> is
+ specified. You can add blobs back to the dump with the
+ <code class="option">--blobs</code> switch.
+ </p></div></dd><dt><span class="term"><code class="option">-N <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-schema=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Do not dump any schemas matching <em class="replaceable"><code>pattern</code></em>. The pattern is
+ interpreted according to the same rules as for <code class="option">-n</code>.
+ <code class="option">-N</code> can be given more than once to exclude schemas
+ matching any of several patterns.
+ </p><p>
+ When both <code class="option">-n</code> and <code class="option">-N</code> are given, the behavior
+ is to dump just the schemas that match at least one <code class="option">-n</code>
+ switch but no <code class="option">-N</code> switches. If <code class="option">-N</code> appears
+ without <code class="option">-n</code>, then schemas matching <code class="option">-N</code> are
+ excluded from what is otherwise a normal dump.
+ </p></dd><dt><span class="term"><code class="option">-O</code><br /></span><span class="term"><code class="option">--no-owner</code></span></dt><dd><p>
+ Do not output commands to set
+ ownership of objects to match the original database.
+ By default, <span class="application">pg_dump</span> issues
+ <code class="command">ALTER OWNER</code> or
+ <code class="command">SET SESSION AUTHORIZATION</code>
+ statements to set ownership of created database objects.
+ These statements
+ will fail when the script is run unless it is started by a superuser
+ (or the same user that owns all of the objects in the script).
+ To make a script that can be restored by any user, but will give
+ that user ownership of all the objects, specify <code class="option">-O</code>.
+ </p><p>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <code class="command">pg_restore</code>.
+ </p></dd><dt><span class="term"><code class="option">-R</code><br /></span><span class="term"><code class="option">--no-reconnect</code></span></dt><dd><p>
+ This option is obsolete but still accepted for backwards
+ compatibility.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--schema-only</code></span></dt><dd><p>
+ Dump only the object definitions (schema), not data.
+ </p><p>
+ This option is the inverse of <code class="option">--data-only</code>.
+ It is similar to, but for historical reasons not identical to,
+ specifying
+ <code class="option">--section=pre-data --section=post-data</code>.
+ </p><p>
+ (Do not confuse this with the <code class="option">--schema</code> option, which
+ uses the word <span class="quote">“<span class="quote">schema</span>”</span> in a different meaning.)
+ </p><p>
+ To exclude table data for only a subset of tables in the database,
+ see <code class="option">--exclude-table-data</code>.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--superuser=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Specify the superuser user name to use when disabling triggers.
+ This is relevant only if <code class="option">--disable-triggers</code> is used.
+ (Usually, it's better to leave this out, and instead start the
+ resulting script as superuser.)
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Dump only tables with names matching
+ <em class="replaceable"><code>pattern</code></em>. Multiple tables
+ can be selected by writing multiple <code class="option">-t</code> switches. The
+ <em class="replaceable"><code>pattern</code></em> parameter is
+ interpreted as a pattern according to the same rules used by
+ <span class="application">psql</span>'s <code class="literal">\d</code> commands
+ (see <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a> below),
+ so multiple tables can also be selected by writing wildcard characters
+ in the pattern. When using wildcards, be careful to quote the pattern
+ if needed to prevent the shell from expanding the wildcards; see
+ <a class="xref" href="app-pgdump.html#PG-DUMP-EXAMPLES" title="Examples">Examples</a> below.
+ </p><p>
+ As well as tables, this option can be used to dump the definition of matching
+ views, materialized views, foreign tables, and sequences. It will not dump the
+ contents of views or materialized views, and the contents of foreign tables will
+ only be dumped if the corresponding foreign server is specified with
+ <code class="option">--include-foreign-data</code>.
+ </p><p>
+ The <code class="option">-n</code> and <code class="option">-N</code> switches have no effect when
+ <code class="option">-t</code> is used, because tables selected by <code class="option">-t</code> will
+ be dumped regardless of those switches, and non-table objects will not
+ be dumped.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When <code class="option">-t</code> is specified, <span class="application">pg_dump</span>
+ makes no attempt to dump any other database objects that the selected
+ table(s) might depend upon. Therefore, there is no guarantee
+ that the results of a specific-table dump can be successfully
+ restored by themselves into a clean database.
+ </p></div></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>pattern</code></em></code><br /></span><span class="term"><code class="option">--exclude-table=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Do not dump any tables matching <em class="replaceable"><code>pattern</code></em>. The pattern is
+ interpreted according to the same rules as for <code class="option">-t</code>.
+ <code class="option">-T</code> can be given more than once to exclude tables
+ matching any of several patterns.
+ </p><p>
+ When both <code class="option">-t</code> and <code class="option">-T</code> are given, the behavior
+ is to dump just the tables that match at least one <code class="option">-t</code>
+ switch but no <code class="option">-T</code> switches. If <code class="option">-T</code> appears
+ without <code class="option">-t</code>, then tables matching <code class="option">-T</code> are
+ excluded from what is otherwise a normal dump.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Specifies verbose mode. This will cause
+ <span class="application">pg_dump</span> to output detailed object
+ comments and start/stop times to the dump file, and progress
+ messages to standard error.
+ Repeating the option causes additional debug-level messages
+ to appear on standard error.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_dump</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-x</code><br /></span><span class="term"><code class="option">--no-privileges</code><br /></span><span class="term"><code class="option">--no-acl</code></span></dt><dd><p>
+ Prevent dumping of access privileges (grant/revoke commands).
+ </p></dd><dt><span class="term"><code class="option">-Z <em class="replaceable"><code>0..9</code></em></code><br /></span><span class="term"><code class="option">--compress=<em class="replaceable"><code>0..9</code></em></code></span></dt><dd><p>
+ Specify the compression level to use. Zero means no compression.
+ For the custom and directory archive formats, this specifies compression of
+ individual table-data segments, and the default is to compress
+ at a moderate level.
+ For plain text output, setting a nonzero compression level causes
+ the entire output file to be compressed, as though it had been
+ fed through <span class="application">gzip</span>; but the default is not to compress.
+ The tar archive format currently does not support compression at all.
+ </p></dd><dt><span class="term"><code class="option">--binary-upgrade</code></span></dt><dd><p>
+ This option is for use by in-place upgrade utilities. Its use
+ for other purposes is not recommended or supported. The
+ behavior of the option may change in future releases without
+ notice.
+ </p></dd><dt><span class="term"><code class="option">--column-inserts</code><br /></span><span class="term"><code class="option">--attribute-inserts</code></span></dt><dd><p>
+ Dump data as <code class="command">INSERT</code> commands with explicit
+ column names (<code class="literal">INSERT INTO
+ <em class="replaceable"><code>table</code></em>
+ (<em class="replaceable"><code>column</code></em>, ...) VALUES
+ ...</code>). This will make restoration very slow; it is mainly
+ useful for making dumps that can be loaded into
+ non-<span class="productname">PostgreSQL</span> databases.
+ Any error during restoring will cause only rows that are part of the
+ problematic <code class="command">INSERT</code> to be lost, rather than the
+ entire table contents.
+ </p></dd><dt><span class="term"><code class="option">--disable-dollar-quoting</code></span></dt><dd><p>
+ This option disables the use of dollar quoting for function bodies,
+ and forces them to be quoted using SQL standard string syntax.
+ </p></dd><dt><span class="term"><code class="option">--disable-triggers</code></span></dt><dd><p>
+ This option is relevant only when creating a data-only dump.
+ It instructs <span class="application">pg_dump</span> to include commands
+ to temporarily disable triggers on the target tables while
+ the data is restored. Use this if you have referential
+ integrity checks or other triggers on the tables that you
+ do not want to invoke during data restore.
+ </p><p>
+ Presently, the commands emitted for <code class="option">--disable-triggers</code>
+ must be done as superuser. So, you should also specify
+ a superuser name with <code class="option">-S</code>, or preferably be careful to
+ start the resulting script as a superuser.
+ </p><p>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <code class="command">pg_restore</code>.
+ </p></dd><dt><span class="term"><code class="option">--enable-row-security</code></span></dt><dd><p>
+ This option is relevant only when dumping the contents of a table
+ which has row security. By default, <span class="application">pg_dump</span> will set
+ <a class="xref" href="runtime-config-client.html#GUC-ROW-SECURITY">row_security</a> to off, to ensure
+ that all data is dumped from the table. If the user does not have
+ sufficient privileges to bypass row security, then an error is thrown.
+ This parameter instructs <span class="application">pg_dump</span> to set
+ <a class="xref" href="runtime-config-client.html#GUC-ROW-SECURITY">row_security</a> to on instead, allowing the user
+ to dump the parts of the contents of the table that they have access to.
+ </p><p>
+ Note that if you use this option currently, you probably also want
+ the dump be in <code class="command">INSERT</code> format, as the
+ <code class="command">COPY FROM</code> during restore does not support row security.
+ </p></dd><dt><span class="term"><code class="option">--exclude-table-data=<em class="replaceable"><code>pattern</code></em></code></span></dt><dd><p>
+ Do not dump data for any tables matching <em class="replaceable"><code>pattern</code></em>. The pattern is
+ interpreted according to the same rules as for <code class="option">-t</code>.
+ <code class="option">--exclude-table-data</code> can be given more than once to
+ exclude tables matching any of several patterns. This option is
+ useful when you need the definition of a particular table even
+ though you do not need the data in it.
+ </p><p>
+ To exclude data for all tables in the database, see <code class="option">--schema-only</code>.
+ </p></dd><dt><span class="term"><code class="option">--extra-float-digits=<em class="replaceable"><code>ndigits</code></em></code></span></dt><dd><p>
+ Use the specified value of <code class="option">extra_float_digits</code> when dumping
+ floating-point data, instead of the maximum available precision.
+ Routine dumps made for backup purposes should not use this option.
+ </p></dd><dt><span class="term"><code class="option">--if-exists</code></span></dt><dd><p>
+ Use conditional commands (i.e., add an <code class="literal">IF EXISTS</code>
+ clause) when cleaning database objects. This option is not valid
+ unless <code class="option">--clean</code> is also specified.
+ </p></dd><dt><span class="term"><code class="option">--include-foreign-data=<em class="replaceable"><code>foreignserver</code></em></code></span></dt><dd><p>
+ Dump the data for any foreign table with a foreign server
+ matching <em class="replaceable"><code>foreignserver</code></em>
+ pattern. Multiple foreign servers can be selected by writing multiple
+ <code class="option">--include-foreign-data</code> switches.
+ Also, the <em class="replaceable"><code>foreignserver</code></em> parameter is
+ interpreted as a pattern according to the same rules used by
+ <span class="application">psql</span>'s <code class="literal">\d</code> commands
+ (see <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a> below),
+ so multiple foreign servers can also be selected by writing wildcard characters
+ in the pattern. When using wildcards, be careful to quote the pattern
+ if needed to prevent the shell from expanding the wildcards; see
+ <a class="xref" href="app-pgdump.html#PG-DUMP-EXAMPLES" title="Examples">Examples</a> below.
+ The only exception is that an empty pattern is disallowed.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When <code class="option">--include-foreign-data</code> is specified,
+ <span class="application">pg_dump</span> does not check that the foreign
+ table is writable. Therefore, there is no guarantee that the
+ results of a foreign table dump can be successfully restored.
+ </p></div></dd><dt><span class="term"><code class="option">--inserts</code></span></dt><dd><p>
+ Dump data as <code class="command">INSERT</code> commands (rather
+ than <code class="command">COPY</code>). This will make restoration very slow;
+ it is mainly useful for making dumps that can be loaded into
+ non-<span class="productname">PostgreSQL</span> databases.
+ Any error during restoring will cause only rows that are part of the
+ problematic <code class="command">INSERT</code> to be lost, rather than the
+ entire table contents. Note that the restore might fail altogether if
+ you have rearranged column order. The
+ <code class="option">--column-inserts</code> option is safe against column order
+ changes, though even slower.
+ </p></dd><dt><span class="term"><code class="option">--load-via-partition-root</code></span></dt><dd><p>
+ When dumping data for a table partition, make
+ the <code class="command">COPY</code> or <code class="command">INSERT</code> statements
+ target the root of the partitioning hierarchy that contains it, rather
+ than the partition itself. This causes the appropriate partition to
+ be re-determined for each row when the data is loaded. This may be
+ useful when restoring data on a server where rows do not always fall
+ into the same partitions as they did on the original server. That
+ could happen, for example, if the partitioning column is of type text
+ and the two systems have different definitions of the collation used
+ to sort the partitioning column.
+ </p></dd><dt><span class="term"><code class="option">--lock-wait-timeout=<em class="replaceable"><code>timeout</code></em></code></span></dt><dd><p>
+ Do not wait forever to acquire shared table locks at the beginning of
+ the dump. Instead fail if unable to lock a table within the specified
+ <em class="replaceable"><code>timeout</code></em>. The timeout may be
+ specified in any of the formats accepted by <code class="command">SET
+ statement_timeout</code>. (Allowed formats vary depending on the server
+ version you are dumping from, but an integer number of milliseconds
+ is accepted by all versions.)
+ </p></dd><dt><span class="term"><code class="option">--no-comments</code></span></dt><dd><p>
+ Do not dump comments.
+ </p></dd><dt><span class="term"><code class="option">--no-publications</code></span></dt><dd><p>
+ Do not dump publications.
+ </p></dd><dt><span class="term"><code class="option">--no-security-labels</code></span></dt><dd><p>
+ Do not dump security labels.
+ </p></dd><dt><span class="term"><code class="option">--no-subscriptions</code></span></dt><dd><p>
+ Do not dump subscriptions.
+ </p></dd><dt><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">pg_dump</code> will wait for all files
+ to be written safely to disk. This option causes
+ <code class="command">pg_dump</code> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the dump corrupt. Generally, this option is useful for testing
+ but should not be used when dumping data from production installation.
+ </p></dd><dt><span class="term"><code class="option">--no-table-access-method</code></span></dt><dd><p>
+ Do not output commands to select table access methods.
+ With this option, all objects will be created with whichever
+ table access method is the default during restore.
+ </p><p>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <code class="command">pg_restore</code>.
+ </p></dd><dt><span class="term"><code class="option">--no-tablespaces</code></span></dt><dd><p>
+ Do not output commands to select tablespaces.
+ With this option, all objects will be created in whichever
+ tablespace is the default during restore.
+ </p><p>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <code class="command">pg_restore</code>.
+ </p></dd><dt><span class="term"><code class="option">--no-toast-compression</code></span></dt><dd><p>
+ Do not output commands to set <acronym class="acronym">TOAST</acronym> compression
+ methods.
+ With this option, all columns will be restored with the default
+ compression setting.
+ </p></dd><dt><span class="term"><code class="option">--no-unlogged-table-data</code></span></dt><dd><p>
+ Do not dump the contents of unlogged tables and sequences. This
+ option has no effect on whether or not the table and sequence
+ definitions (schema) are dumped; it only suppresses dumping the table
+ and sequence data. Data in unlogged tables and sequences
+ is always excluded when dumping from a standby server.
+ </p></dd><dt><span class="term"><code class="option">--on-conflict-do-nothing</code></span></dt><dd><p>
+ Add <code class="literal">ON CONFLICT DO NOTHING</code> to
+ <code class="command">INSERT</code> commands.
+ This option is not valid unless <code class="option">--inserts</code>,
+ <code class="option">--column-inserts</code> or
+ <code class="option">--rows-per-insert</code> is also specified.
+ </p></dd><dt><span class="term"><code class="option">--quote-all-identifiers</code></span></dt><dd><p>
+ Force quoting of all identifiers. This option is recommended when
+ dumping a database from a server whose <span class="productname">PostgreSQL</span>
+ major version is different from <span class="application">pg_dump</span>'s, or when
+ the output is intended to be loaded into a server of a different
+ major version. By default, <span class="application">pg_dump</span> quotes only
+ identifiers that are reserved words in its own major version.
+ This sometimes results in compatibility issues when dealing with
+ servers of other versions that may have slightly different sets
+ of reserved words. Using <code class="option">--quote-all-identifiers</code> prevents
+ such issues, at the price of a harder-to-read dump script.
+ </p></dd><dt><span class="term"><code class="option">--rows-per-insert=<em class="replaceable"><code>nrows</code></em></code></span></dt><dd><p>
+ Dump data as <code class="command">INSERT</code> commands (rather than
+ <code class="command">COPY</code>). Controls the maximum number of rows per
+ <code class="command">INSERT</code> command. The value specified must be a
+ number greater than zero. Any error during restoring will cause only
+ rows that are part of the problematic <code class="command">INSERT</code> to be
+ lost, rather than the entire table contents.
+ </p></dd><dt><span class="term"><code class="option">--section=<em class="replaceable"><code>sectionname</code></em></code></span></dt><dd><p>
+ Only dump the named section. The section name can be
+ <code class="option">pre-data</code>, <code class="option">data</code>, or <code class="option">post-data</code>.
+ This option can be specified more than once to select multiple
+ sections. The default is to dump all sections.
+ </p><p>
+ The data section contains actual table data, large-object
+ contents, and sequence values.
+ Post-data items include definitions of indexes, triggers, rules,
+ and constraints other than validated check constraints.
+ Pre-data items include all other data definition items.
+ </p></dd><dt><span class="term"><code class="option">--serializable-deferrable</code></span></dt><dd><p>
+ Use a <code class="literal">serializable</code> transaction for the dump, to
+ ensure that the snapshot used is consistent with later database
+ states; but do this by waiting for a point in the transaction stream
+ at which no anomalies can be present, so that there isn't a risk of
+ the dump failing or causing other transactions to roll back with a
+ <code class="literal">serialization_failure</code>. See <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>
+ for more information about transaction isolation and concurrency
+ control.
+ </p><p>
+ This option is not beneficial for a dump which is intended only for
+ disaster recovery. It could be useful for a dump used to load a
+ copy of the database for reporting or other read-only load sharing
+ while the original database continues to be updated. Without it the
+ dump may reflect a state which is not consistent with any serial
+ execution of the transactions eventually committed. For example, if
+ batch processing techniques are used, a batch may show as closed in
+ the dump without all of the items which are in the batch appearing.
+ </p><p>
+ This option will make no difference if there are no read-write
+ transactions active when pg_dump is started. If read-write
+ transactions are active, the start of the dump may be delayed for an
+ indeterminate length of time. Once running, performance with or
+ without the switch is the same.
+ </p></dd><dt><span class="term"><code class="option">--snapshot=<em class="replaceable"><code>snapshotname</code></em></code></span></dt><dd><p>
+ Use the specified synchronized snapshot when making a dump of the
+ database (see
+ <a class="xref" href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION-TABLE" title="Table 9.92. Snapshot Synchronization Functions">Table 9.92</a> for more
+ details).
+ </p><p>
+ This option is useful when needing to synchronize the dump with
+ a logical replication slot (see <a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>)
+ or with a concurrent session.
+ </p><p>
+ In the case of a parallel dump, the snapshot name defined by this
+ option is used rather than taking a new snapshot.
+ </p></dd><dt><span class="term"><code class="option">--strict-names</code></span></dt><dd><p>
+ Require that each
+ extension (<code class="option">-e</code>/<code class="option">--extension</code>),
+ schema (<code class="option">-n</code>/<code class="option">--schema</code>) and
+ table (<code class="option">-t</code>/<code class="option">--table</code>) qualifier
+ match at least one extension/schema/table in the database to be dumped.
+ Note that if none of the extension/schema/table qualifiers find
+ matches, <span class="application">pg_dump</span> will generate an error
+ even without <code class="option">--strict-names</code>.
+ </p><p>
+ This option has no effect
+ on <code class="option">-N</code>/<code class="option">--exclude-schema</code>,
+ <code class="option">-T</code>/<code class="option">--exclude-table</code>,
+ or <code class="option">--exclude-table-data</code>. An exclude pattern failing
+ to match any objects is not considered an error.
+ </p></dd><dt><span class="term"><code class="option">--use-set-session-authorization</code></span></dt><dd><p>
+ Output SQL-standard <code class="command">SET SESSION AUTHORIZATION</code> commands
+ instead of <code class="command">ALTER OWNER</code> commands to determine object
+ ownership. This makes the dump more standards-compatible, but
+ depending on the history of the objects in the dump, might not restore
+ properly. Also, a dump using <code class="command">SET SESSION AUTHORIZATION</code>
+ will certainly require superuser privileges to restore correctly,
+ whereas <code class="command">ALTER OWNER</code> requires lesser privileges.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_dump</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control the database connection parameters.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to. This is
+ equivalent to specifying <em class="replaceable"><code>dbname</code></em> as the first non-option
+ argument on the command line. The <em class="replaceable"><code>dbname</code></em>
+ can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>.
+ If so, connection string parameters will override any conflicting
+ command line options.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <code class="envar">PGHOST</code> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <code class="envar">PGPORT</code> environment variable, if
+ set, or a compiled-in default.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">pg_dump</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_dump</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">pg_dump</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--role=<em class="replaceable"><code>rolename</code></em></code></span></dt><dd><p>
+ Specifies a role name to be used to create the dump.
+ This option causes <span class="application">pg_dump</span> to issue a
+ <code class="command">SET ROLE</code> <em class="replaceable"><code>rolename</code></em>
+ command after connecting to the database. It is useful when the
+ authenticated user (specified by <code class="option">-U</code>) lacks privileges
+ needed by <span class="application">pg_dump</span>, but can switch to a role with
+ the required rights. Some installations have a policy against
+ logging in directly as a superuser, and use of this option allows
+ dumps to be made without violating the policy.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.13.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATABASE</code><br /></span><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGOPTIONS</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters.
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="APP-PGDUMP-DIAGNOSTICS"><h2>Diagnostics</h2><p>
+ <span class="application">pg_dump</span> internally executes
+ <code class="command">SELECT</code> statements. If you have problems running
+ <span class="application">pg_dump</span>, make sure you are able to
+ select information from the database using, for example, <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p><p>
+ The database activity of <span class="application">pg_dump</span> is
+ normally collected by the cumulative statistics system. If this is
+ undesirable, you can set parameter <code class="varname">track_counts</code>
+ to false via <code class="envar">PGOPTIONS</code> or the <code class="literal">ALTER
+ USER</code> command.
+ </p></div><div class="refsect1" id="PG-DUMP-NOTES"><h2>Notes</h2><p>
+ If your database cluster has any local additions to the <code class="literal">template1</code> database,
+ be careful to restore the output of <span class="application">pg_dump</span> into a
+ truly empty database; otherwise you are likely to get errors due to
+ duplicate definitions of the added objects. To make an empty database
+ without any local additions, copy from <code class="literal">template0</code> not <code class="literal">template1</code>,
+ for example:
+</p><pre class="programlisting">
+CREATE DATABASE foo WITH TEMPLATE template0;
+</pre><p>
+ </p><p>
+ When a data-only dump is chosen and the option <code class="option">--disable-triggers</code>
+ is used, <span class="application">pg_dump</span> emits commands
+ to disable triggers on user tables before inserting the data,
+ and then commands to re-enable them after the data has been
+ inserted. If the restore is stopped in the middle, the system
+ catalogs might be left in the wrong state.
+ </p><p>
+ The dump file produced by <span class="application">pg_dump</span>
+ does not contain the statistics used by the optimizer to make
+ query planning decisions. Therefore, it is wise to run
+ <code class="command">ANALYZE</code> after restoring from a dump file
+ to ensure optimal performance; see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a>
+ and <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ </p><p>
+ Because <span class="application">pg_dump</span> is used to transfer data
+ to newer versions of <span class="productname">PostgreSQL</span>, the output of
+ <span class="application">pg_dump</span> can be expected to load into
+ <span class="productname">PostgreSQL</span> server versions newer than
+ <span class="application">pg_dump</span>'s version. <span class="application">pg_dump</span> can also
+ dump from <span class="productname">PostgreSQL</span> servers older than its own version.
+ (Currently, servers back to version 9.2 are supported.)
+ However, <span class="application">pg_dump</span> cannot dump from
+ <span class="productname">PostgreSQL</span> servers newer than its own major version;
+ it will refuse to even try, rather than risk making an invalid dump.
+ Also, it is not guaranteed that <span class="application">pg_dump</span>'s output can
+ be loaded into a server of an older major version — not even if the
+ dump was taken from a server of that version. Loading a dump file
+ into an older server may require manual editing of the dump file
+ to remove syntax not understood by the older server.
+ Use of the <code class="option">--quote-all-identifiers</code> option is recommended
+ in cross-version cases, as it can prevent problems arising from varying
+ reserved-word lists in different <span class="productname">PostgreSQL</span> versions.
+ </p><p>
+ When dumping logical replication subscriptions,
+ <span class="application">pg_dump</span> will generate <code class="command">CREATE
+ SUBSCRIPTION</code> commands that use the <code class="literal">connect = false</code>
+ option, so that restoring the subscription does not make remote connections
+ for creating a replication slot or for initial table copy. That way, the
+ dump can be restored without requiring network access to the remote
+ servers. It is then up to the user to reactivate the subscriptions in a
+ suitable way. If the involved hosts have changed, the connection
+ information might have to be changed. It might also be appropriate to
+ truncate the target tables before initiating a new full table copy. If users
+ intend to copy initial data during refresh they must create the slot with
+ <code class="literal">two_phase = false</code>. After the initial sync, the
+ <code class="literal">two_phase</code> option will be automatically enabled by the
+ subscriber if the subscription had been originally created with
+ <code class="literal">two_phase = true</code> option.
+ </p></div><div class="refsect1" id="PG-DUMP-EXAMPLES"><h2>Examples</h2><p>
+ To dump a database called <code class="literal">mydb</code> into an SQL-script file:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump mydb &gt; db.sql</code></strong>
+</pre><p>
+ </p><p>
+ To reload such a script into a (freshly created) database named
+ <code class="literal">newdb</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>psql -d newdb -f db.sql</code></strong>
+</pre><p>
+ </p><p>
+ To dump a database into a custom-format archive file:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -Fc mydb &gt; db.dump</code></strong>
+</pre><p>
+ </p><p>
+ To dump a database into a directory-format archive:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -Fd mydb -f dumpdir</code></strong>
+</pre><p>
+ </p><p>
+ To dump a database into a directory-format archive in parallel with
+ 5 worker jobs:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -Fd mydb -j 5 -f dumpdir</code></strong>
+</pre><p>
+ </p><p>
+ To reload an archive file into a (freshly created) database named
+ <code class="literal">newdb</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_restore -d newdb db.dump</code></strong>
+</pre><p>
+ </p><p>
+ To reload an archive file into the same database it was dumped from,
+ discarding the current contents of that database:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_restore -d postgres --clean --create db.dump</code></strong>
+</pre><p>
+ </p><p>
+ To dump a single table named <code class="literal">mytab</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -t mytab mydb &gt; db.sql</code></strong>
+</pre><p>
+ </p><p>
+ To dump all tables whose names start with <code class="literal">emp</code> in the
+ <code class="literal">detroit</code> schema, except for the table named
+ <code class="literal">employee_log</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -t 'detroit.emp*' -T detroit.employee_log mydb &gt; db.sql</code></strong>
+</pre><p>
+ </p><p>
+ To dump all schemas whose names start with <code class="literal">east</code> or
+ <code class="literal">west</code> and end in <code class="literal">gsm</code>, excluding any schemas whose
+ names contain the word <code class="literal">test</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -n 'east*gsm' -n 'west*gsm' -N '*test*' mydb &gt; db.sql</code></strong>
+</pre><p>
+ </p><p>
+ The same, using regular expression notation to consolidate the switches:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -n '(east|west)*gsm' -N '*test*' mydb &gt; db.sql</code></strong>
+</pre><p>
+ </p><p>
+ To dump all database objects except for tables whose names begin with
+ <code class="literal">ts_</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -T 'ts_*' mydb &gt; db.sql</code></strong>
+</pre><p>
+ </p><p>
+ To specify an upper-case or mixed-case name in <code class="option">-t</code> and related
+ switches, you need to double-quote the name; else it will be folded to
+ lower case (see <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a> below). But
+ double quotes are special to the shell, so in turn they must be quoted.
+ Thus, to dump a single table with a mixed-case name, you need something
+ like
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -t "\"MixedCaseName\"" mydb &gt; mytab.sql</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.13.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pg-dumpall.html" title="pg_dumpall"><span class="refentrytitle"><span class="application">pg_dumpall</span></span></a>, <a class="xref" href="app-pgrestore.html" title="pg_restore"><span class="refentrytitle"><span class="application">pg_restore</span></span></a>, <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgconfig.html" title="pg_config">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pg-dumpall.html" title="pg_dumpall">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_config</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_dumpall</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgreceivewal.html b/doc/src/sgml/html/app-pgreceivewal.html
new file mode 100644
index 0000000..f810e08
--- /dev/null
+++ b/doc/src/sgml/html/app-pgreceivewal.html
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_receivewal</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pg-isready.html" title="pg_isready" /><link rel="next" href="app-pgrecvlogical.html" title="pg_recvlogical" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_receivewal</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pg-isready.html" title="pg_isready">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgrecvlogical.html" title="pg_recvlogical">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGRECEIVEWAL"><div class="titlepage"></div><a id="id-1.9.4.16.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_receivewal</span></span></h2><p>pg_receivewal — stream write-ahead logs from a <span class="productname">PostgreSQL</span> server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.16.4.1"><code class="command">pg_receivewal</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.4.16.5"><h2>Description</h2><p>
+ <span class="application">pg_receivewal</span> is used to stream the write-ahead log
+ from a running <span class="productname">PostgreSQL</span> cluster. The write-ahead
+ log is streamed using the streaming replication protocol, and is written
+ to a local directory of files. This directory can be used as the archive
+ location for doing a restore using point-in-time recovery (see
+ <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>).
+ </p><p>
+ <span class="application">pg_receivewal</span> streams the write-ahead
+ log in real time as it's being generated on the server, and does not wait
+ for segments to complete like <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> and
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> do.
+ For this reason, it is not necessary to set
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-TIMEOUT">archive_timeout</a> when using
+ <span class="application">pg_receivewal</span>.
+ </p><p>
+ Unlike the WAL receiver of a PostgreSQL standby server, <span class="application">pg_receivewal</span>
+ by default flushes WAL data only when a WAL file is closed.
+ The option <code class="option">--synchronous</code> must be specified to flush WAL data
+ in real time. Since <span class="application">pg_receivewal</span> does not
+ apply WAL, you should not allow it to become a synchronous standby when
+ <a class="xref" href="runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT">synchronous_commit</a> equals
+ <code class="literal">remote_apply</code>. If it does, it will appear to be a
+ standby that never catches up, and will cause transaction commits to
+ block. To avoid this, you should either configure an appropriate value
+ for <a class="xref" href="runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES">synchronous_standby_names</a>, or specify
+ <code class="varname">application_name</code> for
+ <span class="application">pg_receivewal</span> that does not match it, or
+ change the value of <code class="varname">synchronous_commit</code> to
+ something other than <code class="literal">remote_apply</code>.
+ </p><p>
+ The write-ahead log is streamed over a regular
+ <span class="productname">PostgreSQL</span> connection and uses the replication
+ protocol. The connection must be made with a user having
+ <code class="literal">REPLICATION</code> permissions (see
+ <a class="xref" href="role-attributes.html" title="22.2. Role Attributes">Section 22.2</a>) or a superuser, and
+ <code class="filename">pg_hba.conf</code> must permit the replication connection.
+ The server must also be configured with
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</a> set high enough to leave at least
+ one session available for the stream.
+ </p><p>
+ The starting point of the write-ahead log streaming is calculated when
+ <span class="application">pg_receivewal</span> starts:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ First, scan the directory where the WAL segment files are written and
+ find the newest completed segment file, using as the starting point the
+ beginning of the next WAL segment file.
+ </p></li><li class="listitem"><p>
+ If a starting point cannot be calculated with the previous method,
+ and if a replication slot is used, an extra
+ <code class="command">READ_REPLICATION_SLOT</code> command is issued to retrieve
+ the slot's <code class="literal">restart_lsn</code> to use as the starting point.
+ This option is only available when streaming write-ahead logs from
+ <span class="productname">PostgreSQL</span> 15 and up.
+ </p></li><li class="listitem"><p>
+ If a starting point cannot be calculated with the previous method,
+ the latest WAL flush location is used as reported by the server from
+ an <code class="literal">IDENTIFY_SYSTEM</code> command.
+ </p></li></ol></div><p>
+ </p><p>
+ If the connection is lost, or if it cannot be initially established,
+ with a non-fatal error, <span class="application">pg_receivewal</span> will
+ retry the connection indefinitely, and reestablish streaming as soon
+ as possible. To avoid this behavior, use the <code class="literal">-n</code>
+ parameter.
+ </p><p>
+ In the absence of fatal errors, <span class="application">pg_receivewal</span>
+ will run until terminated by the <span class="systemitem">SIGINT</span> signal
+ (<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>C</strong></span>).
+ </p></div><div class="refsect1" id="id-1.9.4.16.6"><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-D <em class="replaceable"><code>directory</code></em></code><br /></span><span class="term"><code class="option">--directory=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Directory to write the output to.
+ </p><p>
+ This parameter is required.
+ </p></dd><dt><span class="term"><code class="option">-E <em class="replaceable"><code>lsn</code></em></code><br /></span><span class="term"><code class="option">--endpos=<em class="replaceable"><code>lsn</code></em></code></span></dt><dd><p>
+ Automatically stop replication and exit with normal exit status 0 when
+ receiving reaches the specified LSN.
+ </p><p>
+ If there is a record with LSN exactly equal to <em class="replaceable"><code>lsn</code></em>,
+ the record will be processed.
+ </p></dd><dt><span class="term"><code class="option">--if-not-exists</code></span></dt><dd><p>
+ Do not error out when <code class="option">--create-slot</code> is specified
+ and a slot with the specified name already exists.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-loop</code></span></dt><dd><p>
+ Don't loop on connection errors. Instead, exit right away with
+ an error.
+ </p></dd><dt><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ This option causes <code class="command">pg_receivewal</code> to not force WAL
+ data to be flushed to disk. This is faster, but means that a
+ subsequent operating system crash can leave the WAL segments corrupt.
+ Generally, this option is useful for testing but should not be used
+ when doing WAL archiving on a production deployment.
+ </p><p>
+ This option is incompatible with <code class="literal">--synchronous</code>.
+ </p></dd><dt><span class="term"><code class="option">-s <em class="replaceable"><code>interval</code></em></code><br /></span><span class="term"><code class="option">--status-interval=<em class="replaceable"><code>interval</code></em></code></span></dt><dd><p>
+ Specifies the number of seconds between status packets sent back to the
+ server. This allows for easier monitoring of the progress from server.
+ A value of zero disables the periodic status updates completely,
+ although an update will still be sent when requested by the server, to
+ avoid timeout disconnect. The default value is 10 seconds.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>slotname</code></em></code><br /></span><span class="term"><code class="option">--slot=<em class="replaceable"><code>slotname</code></em></code></span></dt><dd><p>
+ Require <span class="application">pg_receivewal</span> to use an existing
+ replication slot (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a>).
+ When this option is used, <span class="application">pg_receivewal</span> will report
+ a flush position to the server, indicating when each segment has been
+ synchronized to disk so that the server can remove that segment if it
+ is not otherwise needed.
+ </p><p>
+ When the replication client
+ of <span class="application">pg_receivewal</span> is configured on the
+ server as a synchronous standby, then using a replication slot will
+ report the flush position to the server, but only when a WAL file is
+ closed. Therefore, that configuration will cause transactions on the
+ primary to wait for a long time and effectively not work
+ satisfactorily. The option <code class="literal">--synchronous</code> (see
+ below) must be specified in addition to make this work correctly.
+ </p></dd><dt><span class="term"><code class="option">--synchronous</code></span></dt><dd><p>
+ Flush the WAL data to disk immediately after it has been received. Also
+ send a status packet back to the server immediately after flushing,
+ regardless of <code class="literal">--status-interval</code>.
+ </p><p>
+ This option should be specified if the replication client
+ of <span class="application">pg_receivewal</span> is configured on the
+ server as a synchronous standby, to ensure that timely feedback is
+ sent to the server.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Enables verbose mode.
+ </p></dd><dt><span class="term"><code class="option">-Z <em class="replaceable"><code>level</code></em></code><br /></span><span class="term"><code class="option">-Z <em class="replaceable"><code>method</code></em>[:<em class="replaceable"><code>detail</code></em>]</code><br /></span><span class="term"><code class="option">--compress=<em class="replaceable"><code>level</code></em></code><br /></span><span class="term"><code class="option">--compress=<em class="replaceable"><code>method</code></em>[:<em class="replaceable"><code>detail</code></em>]</code></span></dt><dd><p>
+ Enables compression of write-ahead logs.
+ </p><p>
+ The compression method can be set to <code class="literal">gzip</code>,
+ <code class="literal">lz4</code> (if <span class="productname">PostgreSQL</span>
+ was compiled with <code class="option">--with-lz4</code>) or
+ <code class="literal">none</code> for no compression.
+ A compression detail string can optionally be specified. If the
+ detail string is an integer, it specifies the compression level.
+ Otherwise, it should be a comma-separated list of items, each of the
+ form <code class="literal">keyword</code> or <code class="literal">keyword=value</code>.
+ Currently, the only supported keyword is <code class="literal">level</code>.
+ </p><p>
+ If no compression level is specified, the default compression level
+ will be used. If only a level is specified without mentioning an
+ algorithm, <code class="literal">gzip</code> compression will be used if the
+ level is greater than 0, and no compression will be used if the level
+ is 0.
+ </p><p>
+ The suffix <code class="filename">.gz</code> will automatically be added to
+ all filenames when using <code class="literal">gzip</code>, and the suffix
+ <code class="filename">.lz4</code> is added when using <code class="literal">lz4</code>.
+ </p></dd></dl></div><p>
+ The following command-line options control the database connection parameters.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>connstr</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>connstr</code></em></code></span></dt><dd><p>
+ Specifies parameters used to connect to the server, as a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>; these
+ will override any conflicting command line options.
+ </p><p>
+ The option is called <code class="literal">--dbname</code> for consistency with other
+ client applications, but because <span class="application">pg_receivewal</span>
+ doesn't connect to any particular database in the cluster, database
+ name in the connection string will be ignored.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <code class="envar">PGHOST</code> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <code class="envar">PGPORT</code> environment variable, if
+ set, or a compiled-in default.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">pg_receivewal</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_receivewal</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">pg_receivewal</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">pg_receivewal</span> can perform one of the two
+ following actions in order to control physical replication slots:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--create-slot</code></span></dt><dd><p>
+ Create a new physical replication slot with the name specified in
+ <code class="option">--slot</code>, then exit.
+ </p></dd><dt><span class="term"><code class="option">--drop-slot</code></span></dt><dd><p>
+ Drop the replication slot with the name specified in
+ <code class="option">--slot</code>, then exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ Other options are also available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_receivewal</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_receivewal</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.16.7"><h2>Exit Status</h2><p>
+ <span class="application">pg_receivewal</span> will exit with status 0 when
+ terminated by the <span class="systemitem">SIGINT</span> signal. (That is the
+ normal way to end it. Hence it is not an error.) For fatal errors or
+ other signals, the exit status will be nonzero.
+ </p></div><div class="refsect1" id="id-1.9.4.16.8"><h2>Environment</h2><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.4.16.9"><h2>Notes</h2><p>
+ When using <span class="application">pg_receivewal</span> instead of
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> or
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> as the main WAL backup method, it is
+ strongly recommended to use replication slots. Otherwise, the server is
+ free to recycle or remove write-ahead log files before they are backed up,
+ because it does not have any information, either
+ from <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> or
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> or the replication slots, about
+ how far the WAL stream has been archived. Note, however, that a
+ replication slot will fill up the server's disk space if the receiver does
+ not keep up with fetching the WAL data.
+ </p><p>
+ <span class="application">pg_receivewal</span> will preserve group permissions on
+ the received WAL files if group permissions are enabled on the source
+ cluster.
+ </p></div><div class="refsect1" id="id-1.9.4.16.10"><h2>Examples</h2><p>
+ To stream the write-ahead log from the server at
+ <code class="literal">mydbserver</code> and store it in the local directory
+ <code class="filename">/usr/local/pgsql/archive</code>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_receivewal -h mydbserver -D /usr/local/pgsql/archive</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.16.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pg-isready.html" title="pg_isready">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgrecvlogical.html" title="pg_recvlogical">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_isready</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_recvlogical</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgreceivexlog.html b/doc/src/sgml/html/app-pgreceivexlog.html
new file mode 100644
index 0000000..1ba71c8
--- /dev/null
+++ b/doc/src/sgml/html/app-pgreceivexlog.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>O.5. pg_receivexlog renamed to pg_receivewal</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgresetxlog.html" title="O.4. pg_resetxlog renamed to pg_resetwal" /><link rel="next" href="biblio.html" title="Bibliography" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">O.5. <code class="command">pg_receivexlog</code> renamed to <code class="command">pg_receivewal</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgresetxlog.html" title="O.4. pg_resetxlog renamed to pg_resetwal">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><th width="60%" align="center">Appendix O. Obsolete or Renamed Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="biblio.html" title="Bibliography">Next</a></td></tr></table><hr /></div><div class="sect1" id="APP-PGRECEIVEXLOG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">O.5. <code class="command">pg_receivexlog</code> renamed to <code class="command">pg_receivewal</code></h2></div></div></div><a id="id-1.11.16.7.2" class="indexterm"></a><p>
+ PostgreSQL 9.6 and below provided a command named
+ <code class="command">pg_receivexlog</code>
+ <a id="id-1.11.16.7.3.2" class="indexterm"></a>
+ to fetch write-ahead-log (WAL) files. This command was renamed to <code class="command">pg_receivewal</code>, see
+ <a class="xref" href="app-pgreceivewal.html" title="pg_receivewal"><span class="refentrytitle"><span class="application">pg_receivewal</span></span></a> for documentation of <code class="command">pg_receivewal</code> and see
+ <a class="link" href="release-prior.html" title="E.6. Prior Releases">the release notes for PostgreSQL 10</a> for details
+ on this change.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgresetxlog.html" title="O.4. pg_resetxlog renamed to pg_resetwal">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="biblio.html" title="Bibliography">Next</a></td></tr><tr><td width="40%" align="left" valign="top">O.4. <code class="command">pg_resetxlog</code> renamed to <code class="command">pg_resetwal</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Bibliography</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgrecvlogical.html b/doc/src/sgml/html/app-pgrecvlogical.html
new file mode 100644
index 0000000..7e6d7e2
--- /dev/null
+++ b/doc/src/sgml/html/app-pgrecvlogical.html
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_recvlogical</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgreceivewal.html" title="pg_receivewal" /><link rel="next" href="app-pgrestore.html" title="pg_restore" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_recvlogical</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgreceivewal.html" title="pg_receivewal">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgrestore.html" title="pg_restore">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGRECVLOGICAL"><div class="titlepage"></div><a id="id-1.9.4.17.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_recvlogical</span></span></h2><p>pg_recvlogical — control <span class="productname">PostgreSQL</span> logical decoding streams</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.17.4.1"><code class="command">pg_recvlogical</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.4.17.5"><h2>Description</h2><p>
+ <code class="command">pg_recvlogical</code> controls logical decoding replication
+ slots and streams data from such replication slots.
+ </p><p>
+ It creates a replication-mode connection, so it is subject to the same
+ constraints as <a class="xref" href="app-pgreceivewal.html" title="pg_receivewal"><span class="refentrytitle"><span class="application">pg_receivewal</span></span></a>, plus those for logical
+ replication (see <a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>).
+ </p><p>
+ <code class="command">pg_recvlogical</code> has no equivalent to the logical decoding
+ SQL interface's peek and get modes. It sends replay confirmations for
+ data lazily as it receives it and on clean exit. To examine pending data on
+ a slot without consuming it, use
+ <a class="link" href="functions-admin.html#FUNCTIONS-REPLICATION" title="9.27.6. Replication Management Functions"><code class="function">pg_logical_slot_peek_changes</code></a>.
+ </p></div><div class="refsect1" id="id-1.9.4.17.6"><h2>Options</h2><p>
+ At least one of the following options must be specified to select an action:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--create-slot</code></span></dt><dd><p>
+ Create a new logical replication slot with the name specified by
+ <code class="option">--slot</code>, using the output plugin specified by
+ <code class="option">--plugin</code>, for the database specified
+ by <code class="option">--dbname</code>.
+ </p><p>
+ The <code class="option">--two-phase</code> can be specified with
+ <code class="option">--create-slot</code> to enable decoding of prepared transactions.
+ </p></dd><dt><span class="term"><code class="option">--drop-slot</code></span></dt><dd><p>
+ Drop the replication slot with the name specified
+ by <code class="option">--slot</code>, then exit.
+ </p></dd><dt><span class="term"><code class="option">--start</code></span></dt><dd><p>
+ Begin streaming changes from the logical replication slot specified
+ by <code class="option">--slot</code>, continuing until terminated by a
+ signal. If the server side change stream ends with a server shutdown
+ or disconnect, retry in a loop unless
+ <code class="option">--no-loop</code> is specified.
+ </p><p>
+ The stream format is determined by the output plugin specified when
+ the slot was created.
+ </p><p>
+ The connection must be to the same database used to create the slot.
+ </p></dd></dl></div><p>
+ </p><p>
+ <code class="option">--create-slot</code> and <code class="option">--start</code> can be
+ specified together. <code class="option">--drop-slot</code> cannot be combined with
+ another action.
+ </p><p>
+ The following command-line options control the location and format of the
+ output and other replication behavior:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-E <em class="replaceable"><code>lsn</code></em></code><br /></span><span class="term"><code class="option">--endpos=<em class="replaceable"><code>lsn</code></em></code></span></dt><dd><p>
+ In <code class="option">--start</code> mode, automatically stop replication
+ and exit with normal exit status 0 when receiving reaches the
+ specified LSN. If specified when not in <code class="option">--start</code>
+ mode, an error is raised.
+ </p><p>
+ If there's a record with LSN exactly equal to <em class="replaceable"><code>lsn</code></em>,
+ the record will be output.
+ </p><p>
+ The <code class="option">--endpos</code> option is not aware of transaction
+ boundaries and may truncate output partway through a transaction.
+ Any partially output transaction will not be consumed and will be
+ replayed again when the slot is next read from. Individual messages
+ are never truncated.
+ </p></dd><dt><span class="term"><code class="option">-f <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--file=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Write received and decoded transaction data into this
+ file. Use <code class="literal">-</code> for <span class="systemitem">stdout</span>.
+ </p></dd><dt><span class="term"><code class="option">-F <em class="replaceable"><code>interval_seconds</code></em></code><br /></span><span class="term"><code class="option">--fsync-interval=<em class="replaceable"><code>interval_seconds</code></em></code></span></dt><dd><p>
+ Specifies how often <span class="application">pg_recvlogical</span> should
+ issue <code class="function">fsync()</code> calls to ensure the output file is
+ safely flushed to disk.
+ </p><p>
+ The server will occasionally request the client to perform a flush and
+ report the flush position to the server. This setting is in addition
+ to that, to perform flushes more frequently.
+ </p><p>
+ Specifying an interval of <code class="literal">0</code> disables
+ issuing <code class="function">fsync()</code> calls altogether, while still
+ reporting progress to the server. In this case, data could be lost in
+ the event of a crash.
+ </p></dd><dt><span class="term"><code class="option">-I <em class="replaceable"><code>lsn</code></em></code><br /></span><span class="term"><code class="option">--startpos=<em class="replaceable"><code>lsn</code></em></code></span></dt><dd><p>
+ In <code class="option">--start</code> mode, start replication from the given
+ LSN. For details on the effect of this, see the documentation
+ in <a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>
+ and <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>. Ignored in other modes.
+ </p></dd><dt><span class="term"><code class="option">--if-not-exists</code></span></dt><dd><p>
+ Do not error out when <code class="option">--create-slot</code> is specified
+ and a slot with the specified name already exists.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-loop</code></span></dt><dd><p>
+ When the connection to the server is lost, do not retry in a loop, just exit.
+ </p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>name</code></em>[=<em class="replaceable"><code>value</code></em>]</code><br /></span><span class="term"><code class="option">--option=<em class="replaceable"><code>name</code></em>[=<em class="replaceable"><code>value</code></em>]</code></span></dt><dd><p>
+ Pass the option <em class="replaceable"><code>name</code></em> to the output plugin with,
+ if specified, the option value <em class="replaceable"><code>value</code></em>. Which
+ options exist and their effects depends on the used output plugin.
+ </p></dd><dt><span class="term"><code class="option">-P <em class="replaceable"><code>plugin</code></em></code><br /></span><span class="term"><code class="option">--plugin=<em class="replaceable"><code>plugin</code></em></code></span></dt><dd><p>
+ When creating a slot, use the specified logical decoding output
+ plugin. See <a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>. This option has no
+ effect if the slot already exists.
+ </p></dd><dt><span class="term"><code class="option">-s <em class="replaceable"><code>interval_seconds</code></em></code><br /></span><span class="term"><code class="option">--status-interval=<em class="replaceable"><code>interval_seconds</code></em></code></span></dt><dd><p>
+ This option has the same effect as the option of the same name
+ in <a class="xref" href="app-pgreceivewal.html" title="pg_receivewal"><span class="refentrytitle"><span class="application">pg_receivewal</span></span></a>. See the description there.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>slot_name</code></em></code><br /></span><span class="term"><code class="option">--slot=<em class="replaceable"><code>slot_name</code></em></code></span></dt><dd><p>
+ In <code class="option">--start</code> mode, use the existing logical replication slot named
+ <em class="replaceable"><code>slot_name</code></em>. In <code class="option">--create-slot</code>
+ mode, create the slot with this name. In <code class="option">--drop-slot</code>
+ mode, delete the slot with this name.
+ </p></dd><dt><span class="term"><code class="option">-t</code><br /></span><span class="term"><code class="option">--two-phase</code></span></dt><dd><p>
+ Enables decoding of prepared transactions. This option may only be specified with
+ <code class="option">--create-slot</code>
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Enables verbose mode.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following command-line options control the database connection parameters.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ The database to connect to. See the description
+ of the actions for what this means in detail.
+ The <em class="replaceable"><code>dbname</code></em> can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>. If so,
+ connection string parameters will override any conflicting
+ command line options. Defaults to the user name.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>hostname-or-ip</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>hostname-or-ip</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <code class="envar">PGHOST</code> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <code class="envar">PGPORT</code> environment variable, if
+ set, or a compiled-in default.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>user</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>user</code></em></code></span></dt><dd><p>
+ User name to connect as. Defaults to current operating system user
+ name.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">pg_recvlogical</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_recvlogical</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">pg_recvlogical</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following additional options are available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_recvlogical</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_recvlogical</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.17.7"><h2>Environment</h2><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.4.17.8"><h2>Notes</h2><p>
+ <span class="application">pg_recvlogical</span> will preserve group permissions on
+ the received WAL files if group permissions are enabled on the source
+ cluster.
+ </p></div><div class="refsect1" id="id-1.9.4.17.9"><h2>Examples</h2><p>
+ See <a class="xref" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples">Section 49.1</a> for an example.
+ </p></div><div class="refsect1" id="id-1.9.4.17.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pgreceivewal.html" title="pg_receivewal"><span class="refentrytitle"><span class="application">pg_receivewal</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgreceivewal.html" title="pg_receivewal">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgrestore.html" title="pg_restore">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_receivewal</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_restore</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgresetwal.html b/doc/src/sgml/html/app-pgresetwal.html
new file mode 100644
index 0000000..24c243b
--- /dev/null
+++ b/doc/src/sgml/html/app-pgresetwal.html
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_resetwal</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pg-ctl.html" title="pg_ctl" /><link rel="next" href="app-pgrewind.html" title="pg_rewind" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_resetwal</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pg-ctl.html" title="pg_ctl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgrewind.html" title="pg_rewind">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGRESETWAL"><div class="titlepage"></div><a id="id-1.9.5.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_resetwal</span></span></h2><p>pg_resetwal — reset the write-ahead log and other control information of a <span class="productname">PostgreSQL</span> database cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.8.4.1"><code class="command">pg_resetwal</code> [ <code class="option">-f</code> | <code class="option">--force</code> ] [ <code class="option">-n</code> | <code class="option">--dry-run</code> ] [<em class="replaceable"><code>option</code></em>...] [ <code class="option">-D</code> | <code class="option">--pgdata</code> ]<em class="replaceable"><code>datadir</code></em> </p></div></div><div class="refsect1" id="R1-APP-PGRESETWAL-1"><h2>Description</h2><p>
+ <code class="command">pg_resetwal</code> clears the write-ahead log (WAL) and
+ optionally resets some other control information stored in the
+ <code class="filename">pg_control</code> file. This function is sometimes needed
+ if these files have become corrupted. It should be used only as a
+ last resort, when the server will not start due to such corruption.
+ </p><p>
+ After running this command, it should be possible to start the server,
+ but bear in mind that the database might contain inconsistent data due to
+ partially-committed transactions. You should immediately dump your data,
+ run <code class="command">initdb</code>, and restore. After restore, check for
+ inconsistencies and repair as needed.
+ </p><p>
+ This utility can only be run by the user who installed the server, because
+ it requires read/write access to the data directory.
+ For safety reasons, you must specify the data directory on the command line.
+ <code class="command">pg_resetwal</code> does not use the environment variable
+ <code class="envar">PGDATA</code>.
+ </p><p>
+ If <code class="command">pg_resetwal</code> complains that it cannot determine
+ valid data for <code class="filename">pg_control</code>, you can force it to proceed anyway
+ by specifying the <code class="option">-f</code> (force) option. In this case plausible
+ values will be substituted for the missing data. Most of the fields can be
+ expected to match, but manual assistance might be needed for the next OID,
+ next transaction ID and epoch, next multitransaction ID and offset, and
+ WAL starting location fields. These fields can be set using the options
+ discussed below. If you are not able to determine correct values for all
+ these fields, <code class="option">-f</code> can still be used, but
+ the recovered database must be treated with even more suspicion than
+ usual: an immediate dump and restore is imperative. <span class="emphasis"><em>Do not</em></span>
+ execute any data-modifying operations in the database before you dump,
+ as any such action is likely to make the corruption worse.
+ </p></div><div class="refsect1" id="id-1.9.5.8.6"><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-f</code><br /></span><span class="term"><code class="option">--force</code></span></dt><dd><p>
+ Force <code class="command">pg_resetwal</code> to proceed even if it cannot determine
+ valid data for <code class="filename">pg_control</code>, as explained above.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--dry-run</code></span></dt><dd><p>
+ The <code class="option">-n</code>/<code class="option">--dry-run</code> option instructs
+ <code class="command">pg_resetwal</code> to print the values reconstructed from
+ <code class="filename">pg_control</code> and values about to be changed, and then exit
+ without modifying anything. This is mainly a debugging tool, but can be
+ useful as a sanity check before allowing <code class="command">pg_resetwal</code>
+ to proceed for real.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>Display version information, then exit.</p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>Show help, then exit.</p></dd></dl></div><p>
+ The following options are only needed when
+ <code class="command">pg_resetwal</code> is unable to determine appropriate values
+ by reading <code class="filename">pg_control</code>. Safe values can be determined as
+ described below. For values that take numeric arguments, hexadecimal
+ values can be specified by using the prefix <code class="literal">0x</code>.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-c <em class="replaceable"><code>xid</code></em>,<em class="replaceable"><code>xid</code></em></code><br /></span><span class="term"><code class="option">--commit-timestamp-ids=<em class="replaceable"><code>xid</code></em>,<em class="replaceable"><code>xid</code></em></code></span></dt><dd><p>
+ Manually set the oldest and newest transaction IDs for which the commit
+ time can be retrieved.
+ </p><p>
+ A safe value for the oldest transaction ID for which the commit time can
+ be retrieved (first part) can be determined by looking
+ for the numerically smallest file name in the directory
+ <code class="filename">pg_commit_ts</code> under the data directory. Conversely, a safe
+ value for the newest transaction ID for which the commit time can be
+ retrieved (second part) can be determined by looking for the numerically
+ greatest file name in the same directory. The file names are in
+ hexadecimal.
+ </p></dd><dt><span class="term"><code class="option">-e <em class="replaceable"><code>xid_epoch</code></em></code><br /></span><span class="term"><code class="option">--epoch=<em class="replaceable"><code>xid_epoch</code></em></code></span></dt><dd><p>
+ Manually set the next transaction ID's epoch.
+ </p><p>
+ The transaction ID epoch is not actually stored anywhere in the database
+ except in the field that is set by <code class="command">pg_resetwal</code>,
+ so any value will work so far as the database itself is concerned.
+ You might need to adjust this value to ensure that replication
+ systems such as <span class="application">Slony-I</span> and
+ <span class="application">Skytools</span> work correctly —
+ if so, an appropriate value should be obtainable from the state of
+ the downstream replicated database.
+ </p></dd><dt><span class="term"><code class="option">-l <em class="replaceable"><code>walfile</code></em></code><br /></span><span class="term"><code class="option">--next-wal-file=<em class="replaceable"><code>walfile</code></em></code></span></dt><dd><p>
+ Manually set the WAL starting location by specifying the name of the
+ next WAL segment file.
+ </p><p>
+ The name of next WAL segment file should be
+ larger than any WAL segment file name currently existing in
+ the directory <code class="filename">pg_wal</code> under the data directory.
+ These names are also in hexadecimal and have three parts. The first
+ part is the <span class="quote">“<span class="quote">timeline ID</span>”</span> and should usually be kept the same.
+ For example, if <code class="filename">00000001000000320000004A</code> is the
+ largest entry in <code class="filename">pg_wal</code>, use <code class="literal">-l 00000001000000320000004B</code> or higher.
+ </p><p>
+ Note that when using nondefault WAL segment sizes, the numbers in the WAL
+ file names are different from the LSNs that are reported by system
+ functions and system views. This option takes a WAL file name, not an
+ LSN.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="command">pg_resetwal</code> itself looks at the files in
+ <code class="filename">pg_wal</code> and chooses a default <code class="option">-l</code> setting
+ beyond the last existing file name. Therefore, manual adjustment of
+ <code class="option">-l</code> should only be needed if you are aware of WAL segment
+ files that are not currently present in <code class="filename">pg_wal</code>, such as
+ entries in an offline archive; or if the contents of
+ <code class="filename">pg_wal</code> have been lost entirely.
+ </p></div></dd><dt><span class="term"><code class="option">-m <em class="replaceable"><code>mxid</code></em>,<em class="replaceable"><code>mxid</code></em></code><br /></span><span class="term"><code class="option">--multixact-ids=<em class="replaceable"><code>mxid</code></em>,<em class="replaceable"><code>mxid</code></em></code></span></dt><dd><p>
+ Manually set the next and oldest multitransaction ID.
+ </p><p>
+ A safe value for the next multitransaction ID (first part) can be
+ determined by looking for the numerically largest file name in the
+ directory <code class="filename">pg_multixact/offsets</code> under the data directory,
+ adding one, and then multiplying by 65536 (0x10000). Conversely, a safe
+ value for the oldest multitransaction ID (second part of
+ <code class="option">-m</code>) can be determined by looking for the numerically smallest
+ file name in the same directory and multiplying by 65536. The file
+ names are in hexadecimal, so the easiest way to do this is to specify
+ the option value in hexadecimal and append four zeroes.
+ </p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>oid</code></em></code><br /></span><span class="term"><code class="option">--next-oid=<em class="replaceable"><code>oid</code></em></code></span></dt><dd><p>
+ Manually set the next OID.
+ </p><p>
+ There is no comparably easy way to determine a next OID that's beyond
+ the largest one in the database, but fortunately it is not critical to
+ get the next-OID setting right.
+ </p></dd><dt><span class="term"><code class="option">-O <em class="replaceable"><code>mxoff</code></em></code><br /></span><span class="term"><code class="option">--multixact-offset=<em class="replaceable"><code>mxoff</code></em></code></span></dt><dd><p>
+ Manually set the next multitransaction offset.
+ </p><p>
+ A safe value can be determined by looking for the numerically largest
+ file name in the directory <code class="filename">pg_multixact/members</code> under the
+ data directory, adding one, and then multiplying by 52352 (0xCC80).
+ The file names are in hexadecimal. There is no simple recipe such as
+ the ones for other options of appending zeroes.
+ </p></dd><dt><span class="term"><code class="option">--wal-segsize=<em class="replaceable"><code>wal_segment_size</code></em></code></span></dt><dd><p>
+ Set the new WAL segment size, in megabytes. The value must be set to a
+ power of 2 between 1 and 1024 (megabytes). See the same option of <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a> for more information.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ While <code class="command">pg_resetwal</code> will set the WAL starting address
+ beyond the latest existing WAL segment file, some segment size changes
+ can cause previous WAL file names to be reused. It is recommended to
+ use <code class="option">-l</code> together with this option to manually set the
+ WAL starting address if WAL file name overlap will cause problems with
+ your archiving strategy.
+ </p></div></dd><dt><span class="term"><code class="option">-u <em class="replaceable"><code>xid</code></em></code><br /></span><span class="term"><code class="option">--oldest-transaction-id=<em class="replaceable"><code>xid</code></em></code></span></dt><dd><p>
+ Manually set the oldest unfrozen transaction ID.
+ </p><p>
+ A safe value can be determined by looking for the numerically smallest
+ file name in the directory <code class="filename">pg_xact</code> under the data directory
+ and then multiplying by 1048576 (0x100000). Note that the file names are in
+ hexadecimal. It is usually easiest to specify the option value in
+ hexadecimal too. For example, if <code class="filename">0007</code> is the smallest entry
+ in <code class="filename">pg_xact</code>, <code class="literal">-u 0x700000</code> will work (five
+ trailing zeroes provide the proper multiplier).
+ </p></dd><dt><span class="term"><code class="option">-x <em class="replaceable"><code>xid</code></em></code><br /></span><span class="term"><code class="option">--next-transaction-id=<em class="replaceable"><code>xid</code></em></code></span></dt><dd><p>
+ Manually set the next transaction ID.
+ </p><p>
+ A safe value can be determined by looking for the numerically largest
+ file name in the directory <code class="filename">pg_xact</code> under the data directory,
+ adding one,
+ and then multiplying by 1048576 (0x100000). Note that the file names are in
+ hexadecimal. It is usually easiest to specify the option value in
+ hexadecimal too. For example, if <code class="filename">0011</code> is the largest entry
+ in <code class="filename">pg_xact</code>, <code class="literal">-x 0x1200000</code> will work (five
+ trailing zeroes provide the proper multiplier).
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.5.8.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.5.8.8"><h2>Notes</h2><p>
+ This command must not be used when the server is
+ running. <code class="command">pg_resetwal</code> will refuse to start up if
+ it finds a server lock file in the data directory. If the
+ server crashed then a lock file might have been left
+ behind; in that case you can remove the lock file to allow
+ <code class="command">pg_resetwal</code> to run. But before you do
+ so, make doubly certain that there is no server process still alive.
+ </p><p>
+ <code class="command">pg_resetwal</code> works only with servers of the same
+ major version.
+ </p></div><div class="refsect1" id="id-1.9.5.8.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pgcontroldata.html" title="pg_controldata"><span class="refentrytitle"><span class="application">pg_controldata</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pg-ctl.html" title="pg_ctl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgrewind.html" title="pg_rewind">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_ctl</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_rewind</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgresetxlog.html b/doc/src/sgml/html/app-pgresetxlog.html
new file mode 100644
index 0000000..c19d7e1
--- /dev/null
+++ b/doc/src/sgml/html/app-pgresetxlog.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>O.4. pg_resetxlog renamed to pg_resetwal</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgxlogdump.html" title="O.3. pg_xlogdump renamed to pg_waldump" /><link rel="next" href="app-pgreceivexlog.html" title="O.5. pg_receivexlog renamed to pg_receivewal" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">O.4. <code class="command">pg_resetxlog</code> renamed to <code class="command">pg_resetwal</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgxlogdump.html" title="O.3. pg_xlogdump renamed to pg_waldump">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><th width="60%" align="center">Appendix O. Obsolete or Renamed Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgreceivexlog.html" title="O.5. pg_receivexlog renamed to pg_receivewal">Next</a></td></tr></table><hr /></div><div class="sect1" id="APP-PGRESETXLOG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">O.4. <code class="command">pg_resetxlog</code> renamed to <code class="command">pg_resetwal</code></h2></div></div></div><a id="id-1.11.16.6.2" class="indexterm"></a><p>
+ PostgreSQL 9.6 and below provided a command named
+ <code class="command">pg_resetxlog</code>
+ <a id="id-1.11.16.6.3.2" class="indexterm"></a>
+ to reset the write-ahead-log (WAL) files. This command was renamed to <code class="command">pg_resetwal</code>, see
+ <a class="xref" href="app-pgresetwal.html" title="pg_resetwal"><span class="refentrytitle"><span class="application">pg_resetwal</span></span></a> for documentation of <code class="command">pg_resetwal</code> and see
+ <a class="link" href="release-prior.html" title="E.6. Prior Releases">the release notes for PostgreSQL 10</a> for details
+ on this change.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgxlogdump.html" title="O.3. pg_xlogdump renamed to pg_waldump">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgreceivexlog.html" title="O.5. pg_receivexlog renamed to pg_receivewal">Next</a></td></tr><tr><td width="40%" align="left" valign="top">O.3. <code class="command">pg_xlogdump</code> renamed to <code class="command">pg_waldump</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> O.5. <code class="command">pg_receivexlog</code> renamed to <code class="command">pg_receivewal</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgrestore.html b/doc/src/sgml/html/app-pgrestore.html
new file mode 100644
index 0000000..7462129
--- /dev/null
+++ b/doc/src/sgml/html/app-pgrestore.html
@@ -0,0 +1,500 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_restore</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgrecvlogical.html" title="pg_recvlogical" /><link rel="next" href="app-pgverifybackup.html" title="pg_verifybackup" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_restore</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgrecvlogical.html" title="pg_recvlogical">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgverifybackup.html" title="pg_verifybackup">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGRESTORE"><div class="titlepage"></div><a id="id-1.9.4.18.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_restore</span></span></h2><p>pg_restore —
+ restore a <span class="productname">PostgreSQL</span> database from an
+ archive file created by <span class="application">pg_dump</span>
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.18.4.1"><code class="command">pg_restore</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>filename</code></em>]</p></div></div><div class="refsect1" id="APP-PGRESTORE-DESCRIPTION"><h2>Description</h2><p>
+ <span class="application">pg_restore</span> is a utility for restoring a
+ <span class="productname">PostgreSQL</span> database from an archive
+ created by <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> in one of the non-plain-text
+ formats. It will issue the commands necessary to reconstruct the
+ database to the state it was in at the time it was saved. The
+ archive files also allow <span class="application">pg_restore</span> to
+ be selective about what is restored, or even to reorder the items
+ prior to being restored. The archive files are designed to be
+ portable across architectures.
+ </p><p>
+ <span class="application">pg_restore</span> can operate in two modes.
+ If a database name is specified, <span class="application">pg_restore</span>
+ connects to that database and restores archive contents directly into
+ the database. Otherwise, a script containing the SQL
+ commands necessary to rebuild the database is created and written
+ to a file or standard output. This script output is equivalent to
+ the plain text output format of <span class="application">pg_dump</span>.
+ Some of the options controlling the output are therefore analogous to
+ <span class="application">pg_dump</span> options.
+ </p><p>
+ Obviously, <span class="application">pg_restore</span> cannot restore information
+ that is not present in the archive file. For instance, if the
+ archive was made using the <span class="quote">“<span class="quote">dump data as
+ <code class="command">INSERT</code> commands</span>”</span> option,
+ <span class="application">pg_restore</span> will not be able to load the data
+ using <code class="command">COPY</code> statements.
+ </p></div><div class="refsect1" id="APP-PGRESTORE-OPTIONS"><h2>Options</h2><p>
+ <span class="application">pg_restore</span> accepts the following command
+ line arguments.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>filename</code></em></span></dt><dd><p>
+ Specifies the location of the archive file (or directory, for a
+ directory-format archive) to be restored.
+ If not specified, the standard input is used.
+ </p></dd><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--data-only</code></span></dt><dd><p>
+ Restore only the data, not the schema (data definitions).
+ Table data, large objects, and sequence values are restored,
+ if present in the archive.
+ </p><p>
+ This option is similar to, but for historical reasons not identical
+ to, specifying <code class="option">--section=data</code>.
+ </p></dd><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--clean</code></span></dt><dd><p>
+ Clean (drop) database objects before recreating them.
+ (Unless <code class="option">--if-exists</code> is used,
+ this might generate some harmless error messages, if any objects
+ were not present in the destination database.)
+ </p></dd><dt><span class="term"><code class="option">-C</code><br /></span><span class="term"><code class="option">--create</code></span></dt><dd><p>
+ Create the database before restoring into it.
+ If <code class="option">--clean</code> is also specified, drop and
+ recreate the target database before connecting to it.
+ </p><p>
+ With <code class="option">--create</code>, <span class="application">pg_restore</span>
+ also restores the database's comment if any, and any configuration
+ variable settings that are specific to this database, that is,
+ any <code class="command">ALTER DATABASE ... SET ...</code>
+ and <code class="command">ALTER ROLE ... IN DATABASE ... SET ...</code>
+ commands that mention this database.
+ Access privileges for the database itself are also restored,
+ unless <code class="option">--no-acl</code> is specified.
+ </p><p>
+ When this option is used, the database named with <code class="option">-d</code>
+ is used only to issue the initial <code class="command">DROP DATABASE</code> and
+ <code class="command">CREATE DATABASE</code> commands. All data is restored into the
+ database name that appears in the archive.
+ </p></dd><dt><span class="term"><code class="option">-d <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Connect to database <em class="replaceable"><code>dbname</code></em> and restore directly
+ into the database. The <em class="replaceable"><code>dbname</code></em> can
+ be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>.
+ If so, connection string parameters will override any conflicting
+ command line options.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--exit-on-error</code></span></dt><dd><p>
+ Exit if an error is encountered while sending SQL commands to
+ the database. The default is to continue and to display a count of
+ errors at the end of the restoration.
+ </p></dd><dt><span class="term"><code class="option">-f <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--file=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Specify output file for generated script, or for the listing
+ when used with <code class="option">-l</code>. Use <code class="literal">-</code>
+ for <span class="systemitem">stdout</span>.
+ </p></dd><dt><span class="term"><code class="option">-F <em class="replaceable"><code>format</code></em></code><br /></span><span class="term"><code class="option">--format=<em class="replaceable"><code>format</code></em></code></span></dt><dd><p>
+ Specify format of the archive. It is not necessary to specify
+ the format, since <span class="application">pg_restore</span> will
+ determine the format automatically. If specified, it can be
+ one of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">c</code><br /></span><span class="term"><code class="literal">custom</code></span></dt><dd><p>
+ The archive is in the custom format of
+ <span class="application">pg_dump</span>.
+ </p></dd><dt><span class="term"><code class="literal">d</code><br /></span><span class="term"><code class="literal">directory</code></span></dt><dd><p>
+ The archive is a directory archive.
+ </p></dd><dt><span class="term"><code class="literal">t</code><br /></span><span class="term"><code class="literal">tar</code></span></dt><dd><p>
+ The archive is a <code class="command">tar</code> archive.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="option">-I <em class="replaceable"><code>index</code></em></code><br /></span><span class="term"><code class="option">--index=<em class="replaceable"><code>index</code></em></code></span></dt><dd><p>
+ Restore definition of named index only. Multiple indexes
+ may be specified with multiple <code class="option">-I</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-j <em class="replaceable"><code>number-of-jobs</code></em></code><br /></span><span class="term"><code class="option">--jobs=<em class="replaceable"><code>number-of-jobs</code></em></code></span></dt><dd><p>
+ Run the most time-consuming steps
+ of <span class="application">pg_restore</span> — those that load data,
+ create indexes, or create constraints — concurrently, using up
+ to <em class="replaceable"><code>number-of-jobs</code></em>
+ concurrent sessions. This option can dramatically reduce the time
+ to restore a large database to a server running on a
+ multiprocessor machine. This option is ignored when emitting a script
+ rather than connecting directly to a database server.
+ </p><p>
+ Each job is one process or one thread, depending on the
+ operating system, and uses a separate connection to the
+ server.
+ </p><p>
+ The optimal value for this option depends on the hardware
+ setup of the server, of the client, and of the network.
+ Factors include the number of CPU cores and the disk setup. A
+ good place to start is the number of CPU cores on the server,
+ but values larger than that can also lead to faster restore
+ times in many cases. Of course, values that are too high will
+ lead to decreased performance because of thrashing.
+ </p><p>
+ Only the custom and directory archive formats are supported
+ with this option.
+ The input must be a regular file or directory (not, for example, a
+ pipe or standard input). Also, multiple
+ jobs cannot be used together with the
+ option <code class="option">--single-transaction</code>.
+ </p></dd><dt><span class="term"><code class="option">-l</code><br /></span><span class="term"><code class="option">--list</code></span></dt><dd><p>
+ List the table of contents of the archive. The output of this operation
+ can be used as input to the <code class="option">-L</code> option. Note that
+ if filtering switches such as <code class="option">-n</code> or <code class="option">-t</code> are
+ used with <code class="option">-l</code>, they will restrict the items listed.
+ </p></dd><dt><span class="term"><code class="option">-L <em class="replaceable"><code>list-file</code></em></code><br /></span><span class="term"><code class="option">--use-list=<em class="replaceable"><code>list-file</code></em></code></span></dt><dd><p>
+ Restore only those archive elements that are listed in <em class="replaceable"><code>list-file</code></em>, and restore them in the
+ order they appear in the file. Note that
+ if filtering switches such as <code class="option">-n</code> or <code class="option">-t</code> are
+ used with <code class="option">-L</code>, they will further restrict the items restored.
+ </p><p><em class="replaceable"><code>list-file</code></em> is normally created by
+ editing the output of a previous <code class="option">-l</code> operation.
+ Lines can be moved or removed, and can also
+ be commented out by placing a semicolon (<code class="literal">;</code>) at the
+ start of the line. See below for examples.
+ </p></dd><dt><span class="term"><code class="option">-n <em class="replaceable"><code>schema</code></em></code><br /></span><span class="term"><code class="option">--schema=<em class="replaceable"><code>schema</code></em></code></span></dt><dd><p>
+ Restore only objects that are in the named schema. Multiple schemas
+ may be specified with multiple <code class="option">-n</code> switches. This can be
+ combined with the <code class="option">-t</code> option to restore just a
+ specific table.
+ </p></dd><dt><span class="term"><code class="option">-N <em class="replaceable"><code>schema</code></em></code><br /></span><span class="term"><code class="option">--exclude-schema=<em class="replaceable"><code>schema</code></em></code></span></dt><dd><p>
+ Do not restore objects that are in the named schema. Multiple schemas
+ to be excluded may be specified with multiple <code class="option">-N</code> switches.
+ </p><p>
+ When both <code class="option">-n</code> and <code class="option">-N</code> are given for the same
+ schema name, the <code class="option">-N</code> switch wins and the schema is excluded.
+ </p></dd><dt><span class="term"><code class="option">-O</code><br /></span><span class="term"><code class="option">--no-owner</code></span></dt><dd><p>
+ Do not output commands to set
+ ownership of objects to match the original database.
+ By default, <span class="application">pg_restore</span> issues
+ <code class="command">ALTER OWNER</code> or
+ <code class="command">SET SESSION AUTHORIZATION</code>
+ statements to set ownership of created schema elements.
+ These statements will fail unless the initial connection to the
+ database is made by a superuser
+ (or the same user that owns all of the objects in the script).
+ With <code class="option">-O</code>, any user name can be used for the
+ initial connection, and this user will own all the created objects.
+ </p></dd><dt><span class="term"><code class="option">-P <em class="replaceable"><code>function-name(argtype [, ...])</code></em></code><br /></span><span class="term"><code class="option">--function=<em class="replaceable"><code>function-name(argtype [, ...])</code></em></code></span></dt><dd><p>
+ Restore the named function only. Be careful to spell the function
+ name and arguments exactly as they appear in the dump file's table
+ of contents. Multiple functions may be specified with multiple
+ <code class="option">-P</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-R</code><br /></span><span class="term"><code class="option">--no-reconnect</code></span></dt><dd><p>
+ This option is obsolete but still accepted for backwards
+ compatibility.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--schema-only</code></span></dt><dd><p>
+ Restore only the schema (data definitions), not data,
+ to the extent that schema entries are present in the archive.
+ </p><p>
+ This option is the inverse of <code class="option">--data-only</code>.
+ It is similar to, but for historical reasons not identical to,
+ specifying
+ <code class="option">--section=pre-data --section=post-data</code>.
+ </p><p>
+ (Do not confuse this with the <code class="option">--schema</code> option, which
+ uses the word <span class="quote">“<span class="quote">schema</span>”</span> in a different meaning.)
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--superuser=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Specify the superuser user name to use when disabling triggers.
+ This is relevant only if <code class="option">--disable-triggers</code> is used.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>table</code></em></code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>table</code></em></code></span></dt><dd><p>
+ Restore definition and/or data of only the named table.
+ For this purpose, <span class="quote">“<span class="quote">table</span>”</span> includes views, materialized views,
+ sequences, and foreign tables. Multiple tables
+ can be selected by writing multiple <code class="option">-t</code> switches.
+ This option can be combined with the <code class="option">-n</code> option to
+ specify table(s) in a particular schema.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When <code class="option">-t</code> is specified, <span class="application">pg_restore</span>
+ makes no attempt to restore any other database objects that the
+ selected table(s) might depend upon. Therefore, there is no
+ guarantee that a specific-table restore into a clean database will
+ succeed.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ This flag does not behave identically to the <code class="option">-t</code>
+ flag of <span class="application">pg_dump</span>. There is not currently
+ any provision for wild-card matching in <span class="application">pg_restore</span>,
+ nor can you include a schema name within its <code class="option">-t</code>.
+ And, while <span class="application">pg_dump</span>'s <code class="option">-t</code>
+ flag will also dump subsidiary objects (such as indexes) of the
+ selected table(s),
+ <span class="application">pg_restore</span>'s <code class="option">-t</code>
+ flag does not include such subsidiary objects.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ In versions prior to <span class="productname">PostgreSQL</span> 9.6, this flag
+ matched only tables, not any other type of relation.
+ </p></div></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>trigger</code></em></code><br /></span><span class="term"><code class="option">--trigger=<em class="replaceable"><code>trigger</code></em></code></span></dt><dd><p>
+ Restore named trigger only. Multiple triggers may be specified with
+ multiple <code class="option">-T</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Specifies verbose mode. This will cause
+ <span class="application">pg_restore</span> to output detailed object
+ comments and start/stop times to the output file, and progress
+ messages to standard error.
+ Repeating the option causes additional debug-level messages
+ to appear on standard error.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_restore</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-x</code><br /></span><span class="term"><code class="option">--no-privileges</code><br /></span><span class="term"><code class="option">--no-acl</code></span></dt><dd><p>
+ Prevent restoration of access privileges (grant/revoke commands).
+ </p></dd><dt><span class="term"><code class="option">-1</code><br /></span><span class="term"><code class="option">--single-transaction</code></span></dt><dd><p>
+ Execute the restore as a single transaction (that is, wrap the
+ emitted commands in <code class="command">BEGIN</code>/<code class="command">COMMIT</code>). This
+ ensures that either all the commands complete successfully, or no
+ changes are applied. This option implies
+ <code class="option">--exit-on-error</code>.
+ </p></dd><dt><span class="term"><code class="option">--disable-triggers</code></span></dt><dd><p>
+ This option is relevant only when performing a data-only restore.
+ It instructs <span class="application">pg_restore</span> to execute commands
+ to temporarily disable triggers on the target tables while
+ the data is restored. Use this if you have referential
+ integrity checks or other triggers on the tables that you
+ do not want to invoke during data restore.
+ </p><p>
+ Presently, the commands emitted for
+ <code class="option">--disable-triggers</code> must be done as superuser. So you
+ should also specify a superuser name with <code class="option">-S</code> or,
+ preferably, run <span class="application">pg_restore</span> as a
+ <span class="productname">PostgreSQL</span> superuser.
+ </p></dd><dt><span class="term"><code class="option">--enable-row-security</code></span></dt><dd><p>
+ This option is relevant only when restoring the contents of a table
+ which has row security. By default, <span class="application">pg_restore</span> will set
+ <a class="xref" href="runtime-config-client.html#GUC-ROW-SECURITY">row_security</a> to off, to ensure
+ that all data is restored in to the table. If the user does not have
+ sufficient privileges to bypass row security, then an error is thrown.
+ This parameter instructs <span class="application">pg_restore</span> to set
+ <a class="xref" href="runtime-config-client.html#GUC-ROW-SECURITY">row_security</a> to on instead, allowing the user to attempt to restore
+ the contents of the table with row security enabled. This might still
+ fail if the user does not have the right to insert the rows from the
+ dump into the table.
+ </p><p>
+ Note that this option currently also requires the dump be in <code class="command">INSERT</code>
+ format, as <code class="command">COPY FROM</code> does not support row security.
+ </p></dd><dt><span class="term"><code class="option">--if-exists</code></span></dt><dd><p>
+ Use conditional commands (i.e., add an <code class="literal">IF EXISTS</code>
+ clause) to drop database objects. This option is not valid
+ unless <code class="option">--clean</code> is also specified.
+ </p></dd><dt><span class="term"><code class="option">--no-comments</code></span></dt><dd><p>
+ Do not output commands to restore comments, even if the archive
+ contains them.
+ </p></dd><dt><span class="term"><code class="option">--no-data-for-failed-tables</code></span></dt><dd><p>
+ By default, table data is restored even if the creation command
+ for the table failed (e.g., because it already exists).
+ With this option, data for such a table is skipped.
+ This behavior is useful if the target database already
+ contains the desired table contents. For example,
+ auxiliary tables for <span class="productname">PostgreSQL</span> extensions
+ such as <span class="productname">PostGIS</span> might already be loaded in
+ the target database; specifying this option prevents duplicate
+ or obsolete data from being loaded into them.
+ </p><p>
+ This option is effective only when restoring directly into a
+ database, not when producing SQL script output.
+ </p></dd><dt><span class="term"><code class="option">--no-publications</code></span></dt><dd><p>
+ Do not output commands to restore publications, even if the archive
+ contains them.
+ </p></dd><dt><span class="term"><code class="option">--no-security-labels</code></span></dt><dd><p>
+ Do not output commands to restore security labels,
+ even if the archive contains them.
+ </p></dd><dt><span class="term"><code class="option">--no-subscriptions</code></span></dt><dd><p>
+ Do not output commands to restore subscriptions, even if the archive
+ contains them.
+ </p></dd><dt><span class="term"><code class="option">--no-table-access-method</code></span></dt><dd><p>
+ Do not output commands to select table access methods.
+ With this option, all objects will be created with whichever
+ access method is the default during restore.
+ </p></dd><dt><span class="term"><code class="option">--no-tablespaces</code></span></dt><dd><p>
+ Do not output commands to select tablespaces.
+ With this option, all objects will be created in whichever
+ tablespace is the default during restore.
+ </p></dd><dt><span class="term"><code class="option">--section=<em class="replaceable"><code>sectionname</code></em></code></span></dt><dd><p>
+ Only restore the named section. The section name can be
+ <code class="option">pre-data</code>, <code class="option">data</code>, or <code class="option">post-data</code>.
+ This option can be specified more than once to select multiple
+ sections. The default is to restore all sections.
+ </p><p>
+ The data section contains actual table data as well as large-object
+ definitions.
+ Post-data items consist of definitions of indexes, triggers, rules
+ and constraints other than validated check constraints.
+ Pre-data items consist of all other data definition items.
+ </p></dd><dt><span class="term"><code class="option">--strict-names</code></span></dt><dd><p>
+ Require that each schema
+ (<code class="option">-n</code>/<code class="option">--schema</code>) and table
+ (<code class="option">-t</code>/<code class="option">--table</code>) qualifier match at
+ least one schema/table in the backup file.
+ </p></dd><dt><span class="term"><code class="option">--use-set-session-authorization</code></span></dt><dd><p>
+ Output SQL-standard <code class="command">SET SESSION AUTHORIZATION</code> commands
+ instead of <code class="command">ALTER OWNER</code> commands to determine object
+ ownership. This makes the dump more standards-compatible, but
+ depending on the history of the objects in the dump, might not restore
+ properly.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_restore</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">pg_restore</span> also accepts
+ the following command line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <code class="envar">PGHOST</code> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <code class="envar">PGPORT</code> environment variable, if
+ set, or a compiled-in default.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">pg_restore</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">pg_restore</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">pg_restore</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--role=<em class="replaceable"><code>rolename</code></em></code></span></dt><dd><p>
+ Specifies a role name to be used to perform the restore.
+ This option causes <span class="application">pg_restore</span> to issue a
+ <code class="command">SET ROLE</code> <em class="replaceable"><code>rolename</code></em>
+ command after connecting to the database. It is useful when the
+ authenticated user (specified by <code class="option">-U</code>) lacks privileges
+ needed by <span class="application">pg_restore</span>, but can switch to a role with
+ the required rights. Some installations have a policy against
+ logging in directly as a superuser, and use of this option allows
+ restores to be performed without violating the policy.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.18.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGOPTIONS</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>). However, it does not read
+ <code class="envar">PGDATABASE</code> when a database name is not supplied.
+ </p></div><div class="refsect1" id="APP-PGRESTORE-DIAGNOSTICS"><h2>Diagnostics</h2><p>
+ When a direct database connection is specified using the
+ <code class="option">-d</code> option, <span class="application">pg_restore</span>
+ internally executes <acronym class="acronym">SQL</acronym> statements. If you have
+ problems running <span class="application">pg_restore</span>, make sure
+ you are able to select information from the database using, for
+ example, <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>. Also, any default connection
+ settings and environment variables used by the
+ <span class="application">libpq</span> front-end library will apply.
+ </p></div><div class="refsect1" id="APP-PGRESTORE-NOTES"><h2>Notes</h2><p>
+ If your installation has any local additions to the
+ <code class="literal">template1</code> database, be careful to load the output of
+ <span class="application">pg_restore</span> into a truly empty database;
+ otherwise you are likely to get errors due to duplicate definitions
+ of the added objects. To make an empty database without any local
+ additions, copy from <code class="literal">template0</code> not <code class="literal">template1</code>, for example:
+</p><pre class="programlisting">
+CREATE DATABASE foo WITH TEMPLATE template0;
+</pre><p>
+ </p><p>
+ The limitations of <span class="application">pg_restore</span> are detailed below.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ When restoring data to a pre-existing table and the option
+ <code class="option">--disable-triggers</code> is used,
+ <span class="application">pg_restore</span> emits commands
+ to disable triggers on user tables before inserting the data, then emits commands to
+ re-enable them after the data has been inserted. If the restore is stopped in the
+ middle, the system catalogs might be left in the wrong state.
+ </p></li><li class="listitem"><p><span class="application">pg_restore</span> cannot restore large objects
+ selectively; for instance, only those for a specific table. If
+ an archive contains large objects, then all large objects will be
+ restored, or none of them if they are excluded via <code class="option">-L</code>,
+ <code class="option">-t</code>, or other options.
+ </p></li></ul></div><p>
+ </p><p>
+ See also the <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> documentation for details on
+ limitations of <span class="application">pg_dump</span>.
+ </p><p>
+ Once restored, it is wise to run <code class="command">ANALYZE</code> on each
+ restored table so the optimizer has useful statistics; see
+ <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a> and
+ <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ </p></div><div class="refsect1" id="APP-PGRESTORE-EXAMPLES"><h2>Examples</h2><p>
+ Assume we have dumped a database called <code class="literal">mydb</code> into a
+ custom-format dump file:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_dump -Fc mydb &gt; db.dump</code></strong>
+</pre><p>
+ </p><p>
+ To drop the database and recreate it from the dump:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>dropdb mydb</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>pg_restore -C -d postgres db.dump</code></strong>
+</pre><p>
+
+ The database named in the <code class="option">-d</code> switch can be any database existing
+ in the cluster; <span class="application">pg_restore</span> only uses it to issue the
+ <code class="command">CREATE DATABASE</code> command for <code class="literal">mydb</code>. With
+ <code class="option">-C</code>, data is always restored into the database name that appears
+ in the dump file.
+ </p><p>
+ To restore the dump into a new database called <code class="literal">newdb</code>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>createdb -T template0 newdb</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>pg_restore -d newdb db.dump</code></strong>
+</pre><p>
+
+ Notice we don't use <code class="option">-C</code>, and instead connect directly to the
+ database to be restored into. Also note that we clone the new database
+ from <code class="literal">template0</code> not <code class="literal">template1</code>, to ensure it is
+ initially empty.
+ </p><p>
+ To reorder database items, it is first necessary to dump the table of
+ contents of the archive:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_restore -l db.dump &gt; db.list</code></strong>
+</pre><p>
+ The listing file consists of a header and one line for each item, e.g.:
+</p><pre class="programlisting">
+;
+; Archive created at Mon Sep 14 13:55:39 2009
+; dbname: DBDEMOS
+; TOC Entries: 81
+; Compression: 9
+; Dump Version: 1.10-0
+; Format: CUSTOM
+; Integer: 4 bytes
+; Offset: 8 bytes
+; Dumped from database version: 8.3.5
+; Dumped by pg_dump version: 8.3.8
+;
+;
+; Selected TOC Entries:
+;
+3; 2615 2200 SCHEMA - public pasha
+1861; 0 0 COMMENT - SCHEMA public pasha
+1862; 0 0 ACL - public pasha
+317; 1247 17715 TYPE public composite pasha
+319; 1247 25899 DOMAIN public domain0 pasha
+</pre><p>
+ Semicolons start a comment, and the numbers at the start of lines refer to the
+ internal archive ID assigned to each item.
+ </p><p>
+ Lines in the file can be commented out, deleted, and reordered. For example:
+</p><pre class="programlisting">
+10; 145433 TABLE map_resolutions postgres
+;2; 145344 TABLE species postgres
+;4; 145359 TABLE nt_header postgres
+6; 145402 TABLE species_records postgres
+;8; 145416 TABLE ss_old postgres
+</pre><p>
+ could be used as input to <span class="application">pg_restore</span> and would only restore
+ items 10 and 6, in that order:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_restore -L db.list db.dump</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.18.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a>, <a class="xref" href="app-pg-dumpall.html" title="pg_dumpall"><span class="refentrytitle"><span class="application">pg_dumpall</span></span></a>, <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgrecvlogical.html" title="pg_recvlogical">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgverifybackup.html" title="pg_verifybackup">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_recvlogical</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_verifybackup</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgrewind.html b/doc/src/sgml/html/app-pgrewind.html
new file mode 100644
index 0000000..fe317f2
--- /dev/null
+++ b/doc/src/sgml/html/app-pgrewind.html
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_rewind</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgresetwal.html" title="pg_resetwal" /><link rel="next" href="pgtestfsync.html" title="pg_test_fsync" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_rewind</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgresetwal.html" title="pg_resetwal">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgtestfsync.html" title="pg_test_fsync">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGREWIND"><div class="titlepage"></div><a id="id-1.9.5.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_rewind</span></span></h2><p>pg_rewind — synchronize a <span class="productname">PostgreSQL</span> data directory with another data directory that was forked from it</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.9.4.1"><code class="command">pg_rewind</code> [<em class="replaceable"><code>option</code></em>...] { <code class="option">-D</code> | <code class="option">--target-pgdata</code> }<em class="replaceable"><code> directory</code></em> { <code class="option">--source-pgdata=<em class="replaceable"><code>directory</code></em></code> | <code class="option">--source-server=<em class="replaceable"><code>connstr</code></em></code> } </p></div></div><div class="refsect1" id="id-1.9.5.9.5"><h2>Description</h2><p>
+ <span class="application">pg_rewind</span> is a tool for synchronizing a PostgreSQL cluster
+ with another copy of the same cluster, after the clusters' timelines have
+ diverged. A typical scenario is to bring an old primary server back online
+ after failover as a standby that follows the new primary.
+ </p><p>
+ After a successful rewind, the state of the target data directory is
+ analogous to a base backup of the source data directory. Unlike taking
+ a new base backup or using a tool like <span class="application">rsync</span>,
+ <span class="application">pg_rewind</span> does not require comparing or copying
+ unchanged relation blocks in the cluster. Only changed blocks from existing
+ relation files are copied; all other files, including new relation files,
+ configuration files, and WAL segments, are copied in full. As such the
+ rewind operation is significantly faster than other approaches when the
+ database is large and only a small fraction of blocks differ between the
+ clusters.
+ </p><p>
+ <span class="application">pg_rewind</span> examines the timeline histories of the source
+ and target clusters to determine the point where they diverged, and
+ expects to find WAL in the target cluster's <code class="filename">pg_wal</code> directory
+ reaching all the way back to the point of divergence. The point of divergence
+ can be found either on the target timeline, the source timeline, or their common
+ ancestor. In the typical failover scenario where the target cluster was
+ shut down soon after the divergence, this is not a problem, but if the
+ target cluster ran for a long time after the divergence, its old WAL
+ files might no longer be present. In this case, you can manually copy them
+ from the WAL archive to the <code class="filename">pg_wal</code> directory, or run
+ <span class="application">pg_rewind</span> with the <code class="literal">-c</code> option to
+ automatically retrieve them from the WAL archive. The use of
+ <span class="application">pg_rewind</span> is not limited to failover, e.g., a standby
+ server can be promoted, run some write transactions, and then rewound
+ to become a standby again.
+ </p><p>
+ After running <span class="application">pg_rewind</span>, WAL replay needs to
+ complete for the data directory to be in a consistent state. When the
+ target server is started again it will enter archive recovery and replay
+ all WAL generated in the source server from the last checkpoint before
+ the point of divergence. If some of the WAL was no longer available in the
+ source server when <span class="application">pg_rewind</span> was run, and
+ therefore could not be copied by the <span class="application">pg_rewind</span>
+ session, it must be made available when the target server is started.
+ This can be done by creating a <code class="filename">recovery.signal</code> file
+ in the target data directory and by configuring a suitable
+ <a class="xref" href="runtime-config-wal.html#GUC-RESTORE-COMMAND">restore_command</a> in
+ <code class="filename">postgresql.conf</code>.
+ </p><p>
+ <span class="application">pg_rewind</span> requires that the target server either has
+ the <a class="xref" href="runtime-config-wal.html#GUC-WAL-LOG-HINTS">wal_log_hints</a> option enabled
+ in <code class="filename">postgresql.conf</code> or data checksums enabled when
+ the cluster was initialized with <span class="application">initdb</span>. Neither of these
+ are currently on by default. <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a>
+ must also be set to <code class="literal">on</code>, but is enabled by default.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ If <span class="application">pg_rewind</span> fails while processing, then
+ the data folder of the target is likely not in a state that can be
+ recovered. In such a case, taking a new fresh backup is recommended.
+ </p><p>
+ As <span class="application">pg_rewind</span> copies configuration files
+ entirely from the source, it may be required to correct the configuration
+ used for recovery before restarting the target server, especially if
+ the target is reintroduced as a standby of the source. If you restart
+ the server after the rewind operation has finished but without configuring
+ recovery, the target may again diverge from the primary.
+ </p><p>
+ <span class="application">pg_rewind</span> will fail immediately if it finds
+ files it cannot write directly to. This can happen for example when
+ the source and the target server use the same file mapping for read-only
+ SSL keys and certificates. If such files are present on the target server
+ it is recommended to remove them before running
+ <span class="application">pg_rewind</span>. After doing the rewind, some of
+ those files may have been copied from the source, in which case it may
+ be necessary to remove the data copied and restore back the set of links
+ used before the rewind.
+ </p></div></div><div class="refsect1" id="id-1.9.5.9.6"><h2>Options</h2><p>
+ <span class="application">pg_rewind</span> accepts the following command-line
+ arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-D <em class="replaceable"><code>directory</code></em></code><br /></span><span class="term"><code class="option">--target-pgdata=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ This option specifies the target data directory that is synchronized
+ with the source. The target server must be shut down cleanly before
+ running <span class="application">pg_rewind</span>
+ </p></dd><dt><span class="term"><code class="option">--source-pgdata=<em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Specifies the file system path to the data directory of the source
+ server to synchronize the target with. This option requires the
+ source server to be cleanly shut down.
+ </p></dd><dt><span class="term"><code class="option">--source-server=<em class="replaceable"><code>connstr</code></em></code></span></dt><dd><p>
+ Specifies a libpq connection string to connect to the source
+ <span class="productname">PostgreSQL</span> server to synchronize the target
+ with. The connection must be a normal (non-replication) connection
+ with a role having sufficient permissions to execute the functions
+ used by <span class="application">pg_rewind</span> on the source server
+ (see Notes section for details) or a superuser role. This option
+ requires the source server to be running and accepting connections.
+ </p></dd><dt><span class="term"><code class="option">-R</code><br /></span><span class="term"><code class="option">--write-recovery-conf</code></span></dt><dd><p>
+ Create <code class="filename">standby.signal</code> and append connection
+ settings to <code class="filename">postgresql.auto.conf</code> in the output
+ directory. <code class="literal">--source-server</code> is mandatory with
+ this option.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--dry-run</code></span></dt><dd><p>
+ Do everything except actually modifying the target directory.
+ </p></dd><dt><span class="term"><code class="option">-N</code><br /></span><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">pg_rewind</code> will wait for all files
+ to be written safely to disk. This option causes
+ <code class="command">pg_rewind</code> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the data directory corrupt. Generally, this option is useful for
+ testing but should not be used on a production
+ installation.
+ </p></dd><dt><span class="term"><code class="option">-P</code><br /></span><span class="term"><code class="option">--progress</code></span></dt><dd><p>
+ Enables progress reporting. Turning this on will deliver an approximate
+ progress report while copying data from the source cluster.
+ </p></dd><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--restore-target-wal</code></span></dt><dd><p>
+ Use <code class="varname">restore_command</code> defined in the target cluster
+ configuration to retrieve WAL files from the WAL archive if these
+ files are no longer available in the <code class="filename">pg_wal</code>
+ directory.
+ </p></dd><dt><span class="term"><code class="option">--config-file=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Use the specified main server configuration file for the target
+ cluster. This affects <span class="application">pg_rewind</span> when
+ it uses internally the <span class="application">postgres</span> command
+ for the rewind operation on this cluster (when retrieving
+ <code class="varname">restore_command</code> with the option
+ <code class="option">-c/--restore-target-wal</code> and when forcing a
+ completion of crash recovery).
+ </p></dd><dt><span class="term"><code class="option">--debug</code></span></dt><dd><p>
+ Print verbose debugging output that is mostly useful for developers
+ debugging <span class="application">pg_rewind</span>.
+ </p></dd><dt><span class="term"><code class="option">--no-ensure-shutdown</code></span></dt><dd><p>
+ <span class="application">pg_rewind</span> requires that the target server
+ is cleanly shut down before rewinding. By default, if the target server
+ is not shut down cleanly, <span class="application">pg_rewind</span> starts
+ the target server in single-user mode to complete crash recovery first,
+ and stops it.
+ By passing this option, <span class="application">pg_rewind</span> skips
+ this and errors out immediately if the server is not cleanly shut
+ down. Users are expected to handle the situation themselves in that
+ case.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>Display version information, then exit.</p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>Show help, then exit.</p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.9.7"><h2>Environment</h2><p>
+ When <code class="option">--source-server</code> option is used,
+ <span class="application">pg_rewind</span> also uses the environment variables
+ supported by <span class="application">libpq</span> (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.5.9.8"><h2>Notes</h2><p>
+ When executing <span class="application">pg_rewind</span> using an online
+ cluster as source, a role having sufficient permissions to execute the
+ functions used by <span class="application">pg_rewind</span> on the source
+ cluster can be used instead of a superuser. Here is how to create such
+ a role, named <code class="literal">rewind_user</code> here:
+</p><pre class="programlisting">
+CREATE USER rewind_user LOGIN;
+GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;
+</pre><p>
+ </p><p>
+ When executing <span class="application">pg_rewind</span> using an online
+ cluster as source which has been recently promoted, it is necessary
+ to execute a <code class="command">CHECKPOINT</code> after promotion such that its
+ control file reflects up-to-date timeline information, which is used by
+ <span class="application">pg_rewind</span> to check if the target cluster
+ can be rewound using the designated source cluster.
+ </p><div class="refsect2" id="id-1.9.5.9.8.4"><h3>How It Works</h3><p>
+ The basic idea is to copy all file system-level changes from the source
+ cluster to the target cluster:
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p>
+ Scan the WAL log of the target cluster, starting from the last
+ checkpoint before the point where the source cluster's timeline
+ history forked off from the target cluster. For each WAL record,
+ record each data block that was touched. This yields a list of all
+ the data blocks that were changed in the target cluster, after the
+ source cluster forked off. If some of the WAL files are no longer
+ available, try re-running <span class="application">pg_rewind</span> with
+ the <code class="option">-c</code> option to search for the missing files in
+ the WAL archive.
+ </p></li><li class="step"><p>
+ Copy all those changed blocks from the source cluster to
+ the target cluster, either using direct file system access
+ (<code class="option">--source-pgdata</code>) or SQL (<code class="option">--source-server</code>).
+ Relation files are now in a state equivalent to the moment of the last
+ completed checkpoint prior to the point at which the WAL timelines of the
+ source and target diverged plus the current state on the source of any
+ blocks changed on the target after that divergence.
+ </p></li><li class="step"><p>
+ Copy all other files, including new relation files, WAL segments,
+ <code class="filename">pg_xact</code>, and configuration files from the source
+ cluster to the target cluster. Similarly to base backups, the contents
+ of the directories <code class="filename">pg_dynshmem/</code>,
+ <code class="filename">pg_notify/</code>, <code class="filename">pg_replslot/</code>,
+ <code class="filename">pg_serial/</code>, <code class="filename">pg_snapshots/</code>,
+ <code class="filename">pg_stat_tmp/</code>, and <code class="filename">pg_subtrans/</code>
+ are omitted from the data copied from the source cluster. The files
+ <code class="filename">backup_label</code>,
+ <code class="filename">tablespace_map</code>,
+ <code class="filename">pg_internal.init</code>,
+ <code class="filename">postmaster.opts</code>, and
+ <code class="filename">postmaster.pid</code>, as well as any file or directory
+ beginning with <code class="filename">pgsql_tmp</code>, are omitted.
+ </p></li><li class="step"><p>
+ Create a <code class="filename">backup_label</code> file to begin WAL replay at
+ the checkpoint created at failover and configure the
+ <code class="filename">pg_control</code> file with a minimum consistency LSN
+ defined as the result of <code class="literal">pg_current_wal_insert_lsn()</code>
+ when rewinding from a live source or the last checkpoint LSN when
+ rewinding from a stopped source.
+ </p></li><li class="step"><p>
+ When starting the target, <span class="productname">PostgreSQL</span> replays
+ all the required WAL, resulting in a data directory in a consistent
+ state.
+ </p></li></ol></div></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgresetwal.html" title="pg_resetwal">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgtestfsync.html" title="pg_test_fsync">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_resetwal</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_test_fsync</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-pgverifybackup.html b/doc/src/sgml/html/app-pgverifybackup.html
new file mode 100644
index 0000000..3312eb8
--- /dev/null
+++ b/doc/src/sgml/html/app-pgverifybackup.html
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_verifybackup</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgrestore.html" title="pg_restore" /><link rel="next" href="app-psql.html" title="psql" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_verifybackup</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgrestore.html" title="pg_restore">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-psql.html" title="psql">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PGVERIFYBACKUP"><div class="titlepage"></div><a id="id-1.9.4.19.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_verifybackup</span></span></h2><p>pg_verifybackup — verify the integrity of a base backup of a
+ <span class="productname">PostgreSQL</span> cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.19.4.1"><code class="command">pg_verifybackup</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.4.19.5"><h2>Description</h2><p>
+ <span class="application">pg_verifybackup</span> is used to check the
+ integrity of a database cluster backup taken using
+ <code class="command">pg_basebackup</code> against a
+ <code class="literal">backup_manifest</code> generated by the server at the time
+ of the backup. The backup must be stored in the "plain"
+ format; a "tar" format backup can be checked after extracting it.
+ </p><p>
+ It is important to note that the validation which is performed by
+ <span class="application">pg_verifybackup</span> does not and cannot include
+ every check which will be performed by a running server when attempting
+ to make use of the backup. Even if you use this tool, you should still
+ perform test restores and verify that the resulting databases work as
+ expected and that they appear to contain the correct data. However,
+ <span class="application">pg_verifybackup</span> can detect many problems
+ that commonly occur due to storage problems or user error.
+ </p><p>
+ Backup verification proceeds in four stages. First,
+ <code class="literal">pg_verifybackup</code> reads the
+ <code class="literal">backup_manifest</code> file. If that file
+ does not exist, cannot be read, is malformed, or fails verification
+ against its own internal checksum, <code class="literal">pg_verifybackup</code>
+ will terminate with a fatal error.
+ </p><p>
+ Second, <code class="literal">pg_verifybackup</code> will attempt to verify that
+ the data files currently stored on disk are exactly the same as the data
+ files which the server intended to send, with some exceptions that are
+ described below. Extra and missing files will be detected, with a few
+ exceptions. This step will ignore the presence or absence of, or any
+ modifications to, <code class="literal">postgresql.auto.conf</code>,
+ <code class="literal">standby.signal</code>, and <code class="literal">recovery.signal</code>,
+ because it is expected that these files may have been created or modified
+ as part of the process of taking the backup. It also won't complain about
+ a <code class="literal">backup_manifest</code> file in the target directory or
+ about anything inside <code class="literal">pg_wal</code>, even though these
+ files won't be listed in the backup manifest. Only files are checked;
+ the presence or absence of directories is not verified, except
+ indirectly: if a directory is missing, any files it should have contained
+ will necessarily also be missing.
+ </p><p>
+ Next, <code class="literal">pg_verifybackup</code> will checksum all the files,
+ compare the checksums against the values in the manifest, and emit errors
+ for any files for which the computed checksum does not match the
+ checksum stored in the manifest. This step is not performed for any files
+ which produced errors in the previous step, since they are already known
+ to have problems. Files which were ignored in the previous step are also
+ ignored in this step.
+ </p><p>
+ Finally, <code class="literal">pg_verifybackup</code> will use the manifest to
+ verify that the write-ahead log records which will be needed to recover
+ the backup are present and that they can be read and parsed. The
+ <code class="literal">backup_manifest</code> contains information about which
+ write-ahead log records will be needed, and
+ <code class="literal">pg_verifybackup</code> will use that information to
+ invoke <code class="literal">pg_waldump</code> to parse those write-ahead log
+ records. The <code class="literal">--quiet</code> flag will be used, so that
+ <code class="literal">pg_waldump</code> will only report errors, without producing
+ any other output. While this level of verification is sufficient to
+ detect obvious problems such as a missing file or one whose internal
+ checksums do not match, they aren't extensive enough to detect every
+ possible problem that might occur when attempting to recover. For
+ instance, a server bug that produces write-ahead log records that have
+ the correct checksums but specify nonsensical actions can't be detected
+ by this method.
+ </p><p>
+ Note that if extra WAL files which are not required to recover the backup
+ are present, they will not be checked by this tool, although
+ a separate invocation of <code class="literal">pg_waldump</code> could be used for
+ that purpose. Also note that WAL verification is version-specific: you
+ must use the version of <code class="literal">pg_verifybackup</code>, and thus of
+ <code class="literal">pg_waldump</code>, which pertains to the backup being checked.
+ In contrast, the data file integrity checks should work with any version
+ of the server that generates a <code class="literal">backup_manifest</code> file.
+ </p></div><div class="refsect1" id="id-1.9.4.19.6"><h2>Options</h2><p>
+ <span class="application">pg_verifybackup</span> accepts the following
+ command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--exit-on-error</code></span></dt><dd><p>
+ Exit as soon as a problem with the backup is detected. If this option
+ is not specified, <code class="literal">pg_verifybackup</code> will continue
+ checking the backup even after a problem has been detected, and will
+ report all problems detected as errors.
+ </p></dd><dt><span class="term"><code class="option">-i <em class="replaceable"><code>path</code></em></code><br /></span><span class="term"><code class="option">--ignore=<em class="replaceable"><code>path</code></em></code></span></dt><dd><p>
+ Ignore the specified file or directory, which should be expressed
+ as a relative path name, when comparing the list of data files
+ actually present in the backup to those listed in the
+ <code class="literal">backup_manifest</code> file. If a directory is
+ specified, this option affects the entire subtree rooted at that
+ location. Complaints about extra files, missing files, file size
+ differences, or checksum mismatches will be suppressed if the
+ relative path name matches the specified path name. This option
+ can be specified multiple times.
+ </p></dd><dt><span class="term"><code class="option">-m <em class="replaceable"><code>path</code></em></code><br /></span><span class="term"><code class="option">--manifest-path=<em class="replaceable"><code>path</code></em></code></span></dt><dd><p>
+ Use the manifest file at the specified path, rather than one located
+ in the root of the backup directory.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-parse-wal</code></span></dt><dd><p>
+ Don't attempt to parse write-ahead log data that will be needed
+ to recover from this backup.
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Don't print anything when a backup is successfully verified.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--skip-checksums</code></span></dt><dd><p>
+ Do not verify data file checksums. The presence or absence of
+ files and the sizes of those files will still be checked. This is
+ much faster, because the files themselves do not need to be read.
+ </p></dd><dt><span class="term"><code class="option">-w <em class="replaceable"><code>path</code></em></code><br /></span><span class="term"><code class="option">--wal-directory=<em class="replaceable"><code>path</code></em></code></span></dt><dd><p>
+ Try to parse WAL files stored in the specified directory, rather than
+ in <code class="literal">pg_wal</code>. This may be useful if the backup is
+ stored in a separate location from the WAL archive.
+ </p></dd></dl></div><p>
+ </p><p>
+ Other options are also available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_verifybackup</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_verifybackup</span> command
+ line arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.19.7"><h2>Examples</h2><p>
+ To create a base backup of the server at <code class="literal">mydbserver</code> and
+ verify the integrity of the backup:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -h mydbserver -D /usr/local/pgsql/data</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>pg_verifybackup /usr/local/pgsql/data</code></strong>
+</pre><p>
+ </p><p>
+ To create a base backup of the server at <code class="literal">mydbserver</code>, move
+ the manifest somewhere outside the backup directory, and verify the
+ backup:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>mv /usr/local/pgsql/backup1234/backup_manifest /my/secure/location/backup_manifest.1234</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>pg_verifybackup -m /my/secure/location/backup_manifest.1234 /usr/local/pgsql/backup1234</code></strong>
+</pre><p>
+ </p><p>
+ To verify a backup while ignoring a file that was added manually to the
+ backup directory, and also skipping checksum verification:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_basebackup -h mydbserver -D /usr/local/pgsql/data</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>edit /usr/local/pgsql/data/note.to.self</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>pg_verifybackup --ignore=note.to.self --skip-checksums /usr/local/pgsql/data</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.19.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgrestore.html" title="pg_restore">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-psql.html" title="psql">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_restore</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">psql</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-postgres.html b/doc/src/sgml/html/app-postgres.html
new file mode 100644
index 0000000..4c07f37
--- /dev/null
+++ b/doc/src/sgml/html/app-postgres.html
@@ -0,0 +1,432 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>postgres</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgwaldump.html" title="pg_waldump" /><link rel="next" href="app-postmaster.html" title="postmaster" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">postgres</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgwaldump.html" title="pg_waldump">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-postmaster.html" title="postmaster">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-POSTGRES"><div class="titlepage"></div><a id="id-1.9.5.14.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">postgres</span></span></h2><p>postgres — <span class="productname">PostgreSQL</span> database server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.14.4.1"><code class="command">postgres</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.5.14.5"><h2>Description</h2><p>
+ <code class="command">postgres</code> is the
+ <span class="productname">PostgreSQL</span> database server. In order
+ for a client application to access a database it connects (over a
+ network or locally) to a running <code class="command">postgres</code> instance.
+ The <code class="command">postgres</code> instance then starts a separate server
+ process to handle the connection.
+ </p><p>
+ One <code class="command">postgres</code> instance always manages the data of
+ exactly one database cluster. A database cluster is a collection
+ of databases that is stored at a common file system location (the
+ <span class="quote">“<span class="quote">data area</span>”</span>). More than one
+ <code class="command">postgres</code> instance can run on a system at one
+ time, so long as they use different data areas and different
+ communication ports (see below). When
+ <code class="command">postgres</code> starts it needs to know the location
+ of the data area. The location must be specified by the
+ <code class="option">-D</code> option or the <code class="envar">PGDATA</code> environment
+ variable; there is no default. Typically, <code class="option">-D</code> or
+ <code class="envar">PGDATA</code> points directly to the data area directory
+ created by <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a>. Other possible file layouts are
+ discussed in <a class="xref" href="runtime-config-file-locations.html" title="20.2. File Locations">Section 20.2</a>.
+ </p><p>
+ By default <code class="command">postgres</code> starts in the
+ foreground and prints log messages to the standard error stream. In
+ practical applications <code class="command">postgres</code>
+ should be started as a background process, perhaps at boot time.
+ </p><p>
+ The <code class="command">postgres</code> command can also be called in
+ single-user mode. The primary use for this mode is during
+ bootstrapping by <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a>. Sometimes it is used
+ for debugging or disaster recovery; note that running a single-user
+ server is not truly suitable for debugging the server, since no
+ realistic interprocess communication and locking will happen.
+ When invoked in single-user
+ mode from the shell, the user can enter queries and the results
+ will be printed to the screen, but in a form that is more useful
+ for developers than end users. In the single-user mode,
+ the session user will be set to the user with ID 1, and implicit
+ superuser powers are granted to this user.
+ This user does not actually have to exist, so the single-user mode
+ can be used to manually recover from certain
+ kinds of accidental damage to the system catalogs.
+ </p></div><div class="refsect1" id="APP-POSTGRES-OPTIONS"><h2>Options</h2><p>
+ <code class="command">postgres</code> accepts the following command-line
+ arguments. For a detailed discussion of the options consult <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>. You can save typing most of these
+ options by setting up a configuration file. Some (safe) options
+ can also be set from the connecting client in an
+ application-dependent way to apply only for that session. For
+ example, if the environment variable <code class="envar">PGOPTIONS</code> is
+ set, then <span class="application">libpq</span>-based clients will pass that
+ string to the server, which will interpret it as
+ <code class="command">postgres</code> command-line options.
+ </p><div class="refsect2" id="id-1.9.5.14.6.3"><h3>General Purpose</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-B <em class="replaceable"><code>nbuffers</code></em></code></span></dt><dd><p>
+ Sets the number of shared buffers for use by the server
+ processes. The default value of this parameter is chosen
+ automatically by <span class="application">initdb</span>.
+ Specifying this option is equivalent to setting the
+ <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a> configuration parameter.
+ </p></dd><dt><span class="term"><code class="option">-c <em class="replaceable"><code>name</code></em>=<em class="replaceable"><code>value</code></em></code></span></dt><dd><p>
+ Sets a named run-time parameter. The configuration parameters
+ supported by <span class="productname">PostgreSQL</span> are
+ described in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>. Most of the
+ other command line options are in fact short forms of such a
+ parameter assignment. <code class="option">-c</code> can appear multiple times
+ to set multiple parameters.
+ </p></dd><dt><span class="term"><code class="option">-C <em class="replaceable"><code>name</code></em></code></span></dt><dd><p>
+ Prints the value of the named run-time parameter, and exits.
+ (See the <code class="option">-c</code> option above for details.) This
+ returns values from
+ <code class="filename">postgresql.conf</code>, modified by any parameters
+ supplied in this invocation. It does not reflect parameters
+ supplied when the cluster was started.
+ </p><p>
+ This can be used on a running server for most parameters. However,
+ the server must be shut down for some runtime-computed parameters
+ (e.g., <a class="xref" href="runtime-config-preset.html#GUC-SHARED-MEMORY-SIZE">shared_memory_size</a>,
+ <a class="xref" href="runtime-config-preset.html#GUC-SHARED-MEMORY-SIZE-IN-HUGE-PAGES">shared_memory_size_in_huge_pages</a>, and
+ <a class="xref" href="runtime-config-preset.html#GUC-WAL-SEGMENT-SIZE">wal_segment_size</a>).
+ </p><p>
+ This option is meant for other programs that interact with a server
+ instance, such as <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a>, to query configuration
+ parameter values. User-facing applications should instead use <a class="link" href="sql-show.html" title="SHOW"><code class="command">SHOW</code></a> or the <code class="structname">pg_settings</code> view.
+ </p></dd><dt><span class="term"><code class="option">-d <em class="replaceable"><code>debug-level</code></em></code></span></dt><dd><p>
+ Sets the debug level. The higher this value is set, the more
+ debugging output is written to the server log. Values are
+ from 1 to 5. It is also possible to pass <code class="literal">-d
+ 0</code> for a specific session, which will prevent the
+ server log level of the parent <code class="command">postgres</code> process from being
+ propagated to this session.
+ </p></dd><dt><span class="term"><code class="option">-D <em class="replaceable"><code>datadir</code></em></code></span></dt><dd><p>
+ Specifies the file system location of the database
+ configuration files. See
+ <a class="xref" href="runtime-config-file-locations.html" title="20.2. File Locations">Section 20.2</a> for details.
+ </p></dd><dt><span class="term"><code class="option">-e</code></span></dt><dd><p>
+ Sets the default date style to <span class="quote">“<span class="quote">European</span>”</span>, that is
+ <code class="literal">DMY</code> ordering of input date fields. This also causes
+ the day to be printed before the month in certain date output formats.
+ See <a class="xref" href="datatype-datetime.html" title="8.5. Date/Time Types">Section 8.5</a> for more information.
+ </p></dd><dt><span class="term"><code class="option">-F</code></span></dt><dd><p>
+ Disables <code class="function">fsync</code> calls for improved
+ performance, at the risk of data corruption in the event of a
+ system crash. Specifying this option is equivalent to
+ disabling the <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a> configuration
+ parameter. Read the detailed documentation before using this!
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>hostname</code></em></code></span></dt><dd><p>
+ Specifies the IP host name or address on which
+ <code class="command">postgres</code> is to listen for TCP/IP
+ connections from client applications. The value can also be a
+ comma-separated list of addresses, or <code class="literal">*</code> to specify
+ listening on all available interfaces. An empty value
+ specifies not listening on any IP addresses, in which case
+ only Unix-domain sockets can be used to connect to the
+ server. Defaults to listening only on
+ <span class="systemitem">localhost</span>.
+ Specifying this option is equivalent to setting the <a class="xref" href="runtime-config-connection.html#GUC-LISTEN-ADDRESSES">listen_addresses</a> configuration parameter.
+ </p></dd><dt><span class="term"><code class="option">-i</code></span></dt><dd><p>
+ Allows remote clients to connect via TCP/IP (Internet domain)
+ connections. Without this option, only local connections are
+ accepted. This option is equivalent to setting
+ <code class="varname">listen_addresses</code> to <code class="literal">*</code> in
+ <code class="filename">postgresql.conf</code> or via <code class="option">-h</code>.
+ </p><p>
+ This option is deprecated since it does not allow access to the
+ full functionality of <a class="xref" href="runtime-config-connection.html#GUC-LISTEN-ADDRESSES">listen_addresses</a>.
+ It's usually better to set <code class="varname">listen_addresses</code> directly.
+ </p></dd><dt><span class="term"><code class="option">-k <em class="replaceable"><code>directory</code></em></code></span></dt><dd><p>
+ Specifies the directory of the Unix-domain socket on which
+ <code class="command">postgres</code> is to listen for
+ connections from client applications. The value can also be a
+ comma-separated list of directories. An empty value
+ specifies not listening on any Unix-domain sockets, in which case
+ only TCP/IP sockets can be used to connect to the server.
+ The default value is normally
+ <code class="filename">/tmp</code>, but that can be changed at build time.
+ Specifying this option is equivalent to setting the <a class="xref" href="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES">unix_socket_directories</a> configuration parameter.
+ </p></dd><dt><span class="term"><code class="option">-l</code></span></dt><dd><p>
+ Enables secure connections using <acronym class="acronym">SSL</acronym>.
+ <span class="productname">PostgreSQL</span> must have been compiled with
+ support for <acronym class="acronym">SSL</acronym> for this option to be
+ available. For more information on using <acronym class="acronym">SSL</acronym>,
+ refer to <a class="xref" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Section 19.9</a>.
+ </p></dd><dt><span class="term"><code class="option">-N <em class="replaceable"><code>max-connections</code></em></code></span></dt><dd><p>
+ Sets the maximum number of client connections that this
+ server will accept. The default value of this parameter is chosen
+ automatically by <span class="application">initdb</span>.
+ Specifying this option is equivalent to setting the
+ <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a> configuration parameter.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP/IP port or local Unix domain socket file
+ extension on which <code class="command">postgres</code>
+ is to listen for connections from client applications.
+ Defaults to the value of the <code class="envar">PGPORT</code> environment
+ variable, or if <code class="envar">PGPORT</code> is not set, then
+ defaults to the value established during compilation (normally
+ 5432). If you specify a port other than the default port,
+ then all client applications must specify the same port using
+ either command-line options or <code class="envar">PGPORT</code>.
+ </p></dd><dt><span class="term"><code class="option">-s</code></span></dt><dd><p>
+ Print time information and other statistics at the end of each command.
+ This is useful for benchmarking or for use in tuning the number of
+ buffers.
+ </p></dd><dt><span class="term"><code class="option">-S</code> <em class="replaceable"><code>work-mem</code></em></span></dt><dd><p>
+ Specifies the base amount of memory to be used by sorts and
+ hash tables before resorting to temporary disk files. See the
+ description of the <code class="varname">work_mem</code> configuration
+ parameter in <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY" title="20.4.1. Memory">Section 20.4.1</a>.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">postgres</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">--<em class="replaceable"><code>name</code></em>=<em class="replaceable"><code>value</code></em></code></span></dt><dd><p>
+ Sets a named run-time parameter; a shorter form of
+ <code class="option">-c</code>.
+ </p></dd><dt><span class="term"><code class="option">--describe-config</code></span></dt><dd><p>
+ This option dumps out the server's internal configuration variables,
+ descriptions, and defaults in tab-delimited <code class="command">COPY</code> format.
+ It is designed primarily for use by administration tools.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">postgres</span> command line
+ arguments, and exit.
+ </p></dd></dl></div></div><div class="refsect2" id="id-1.9.5.14.6.4"><h3>Semi-Internal Options</h3><p>
+ The options described here are used
+ mainly for debugging purposes, and in some cases to assist with
+ recovery of severely damaged databases. There should be no reason
+ to use them in a production database setup. They are listed
+ here only for use by <span class="productname">PostgreSQL</span>
+ system developers. Furthermore, these options might
+ change or be removed in a future release without notice.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-f</code> <code class="literal">{ s | i | o | b | t | n | m | h }</code></span></dt><dd><p>
+ Forbids the use of particular scan and join methods:
+ <code class="literal">s</code> and <code class="literal">i</code>
+ disable sequential and index scans respectively,
+ <code class="literal">o</code>, <code class="literal">b</code> and <code class="literal">t</code>
+ disable index-only scans, bitmap index scans, and TID scans
+ respectively, while
+ <code class="literal">n</code>, <code class="literal">m</code>, and <code class="literal">h</code>
+ disable nested-loop, merge and hash joins respectively.
+ </p><p>
+ Neither sequential scans nor nested-loop joins can be disabled
+ completely; the <code class="literal">-fs</code> and
+ <code class="literal">-fn</code> options simply discourage the optimizer
+ from using those plan types if it has any other alternative.
+ </p></dd><dt><span class="term"><code class="option">-n</code></span></dt><dd><p>
+ This option is for debugging problems that cause a server
+ process to die abnormally. The ordinary strategy in this
+ situation is to notify all other server processes that they
+ must terminate and then reinitialize the shared memory and
+ semaphores. This is because an errant server process could
+ have corrupted some shared state before terminating. This
+ option specifies that <code class="command">postgres</code> will
+ not reinitialize shared data structures. A knowledgeable
+ system programmer can then use a debugger to examine shared
+ memory and semaphore state.
+ </p></dd><dt><span class="term"><code class="option">-O</code></span></dt><dd><p>
+ Allows the structure of system tables to be modified. This is
+ used by <code class="command">initdb</code>.
+ </p></dd><dt><span class="term"><code class="option">-P</code></span></dt><dd><p>
+ Ignore system indexes when reading system tables, but still update
+ the indexes when modifying the tables. This is useful when
+ recovering from damaged system indexes.
+ </p></dd><dt><span class="term"><code class="option">-t</code> <code class="literal">pa[rser] | pl[anner] | e[xecutor]</code></span></dt><dd><p>
+ Print timing statistics for each query relating to each of the
+ major system modules. This option cannot be used together
+ with the <code class="option">-s</code> option.
+ </p></dd><dt><span class="term"><code class="option">-T</code></span></dt><dd><p>
+ This option is for debugging problems that cause a server
+ process to die abnormally. The ordinary strategy in this
+ situation is to notify all other server processes that they
+ must terminate and then reinitialize the shared memory and
+ semaphores. This is because an errant server process could
+ have corrupted some shared state before terminating. This
+ option specifies that <code class="command">postgres</code> will
+ stop all other server processes by sending the signal
+ <code class="literal">SIGSTOP</code>, but will not cause them to
+ terminate. This permits system programmers to collect core
+ dumps from all server processes by hand.
+ </p></dd><dt><span class="term"><code class="option">-v</code> <em class="replaceable"><code>protocol</code></em></span></dt><dd><p>
+ Specifies the version number of the frontend/backend protocol
+ to be used for a particular session. This option is for
+ internal use only.
+ </p></dd><dt><span class="term"><code class="option">-W</code> <em class="replaceable"><code>seconds</code></em></span></dt><dd><p>
+ A delay of this many seconds occurs when a new server process
+ is started, after it conducts the authentication procedure.
+ This is intended to give an opportunity to attach to the
+ server process with a debugger.
+ </p></dd></dl></div></div><div class="refsect2" id="id-1.9.5.14.6.5"><h3>Options for Single-User Mode</h3><a id="id-1.9.5.14.6.5.2" class="indexterm"></a><p>
+ The following options only apply to the single-user mode
+ (see <a class="xref" href="app-postgres.html#APP-POSTGRES-SINGLE-USER" title="Single-User Mode">Single-User Mode</a> below).
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--single</code></span></dt><dd><p>
+ Selects the single-user mode. This must be the first argument
+ on the command line.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>database</code></em></span></dt><dd><p>
+ Specifies the name of the database to be accessed. This must be
+ the last argument on the command line. If it is
+ omitted it defaults to the user name.
+ </p></dd><dt><span class="term"><code class="option">-E</code></span></dt><dd><p>
+ Echo all commands to standard output before executing them.
+ </p></dd><dt><span class="term"><code class="option">-j</code></span></dt><dd><p>
+ Use semicolon followed by two newlines, rather than just newline,
+ as the command entry terminator.
+ </p></dd><dt><span class="term"><code class="option">-r</code> <em class="replaceable"><code>filename</code></em></span></dt><dd><p>
+ Send all server log output to <em class="replaceable"><code>filename</code></em>. This option is only
+ honored when supplied as a command-line option.
+ </p></dd></dl></div></div></div><div class="refsect1" id="id-1.9.5.14.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGCLIENTENCODING</code></span></dt><dd><p>
+ Default character encoding used by clients. (The clients can
+ override this individually.) This value can also be set in the
+ configuration file.
+ </p></dd><dt><span class="term"><code class="envar">PGDATA</code></span></dt><dd><p>
+ Default data directory location
+ </p></dd><dt><span class="term"><code class="envar">PGDATESTYLE</code></span></dt><dd><p>
+ Default value of the <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a> run-time
+ parameter. (The use of this environment variable is deprecated.)
+ </p></dd><dt><span class="term"><code class="envar">PGPORT</code></span></dt><dd><p>
+ Default port number (preferably set in the configuration file)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.5.14.8"><h2>Diagnostics</h2><p>
+ A failure message mentioning <code class="literal">semget</code> or
+ <code class="literal">shmget</code> probably indicates you need to configure your
+ kernel to provide adequate shared memory and semaphores. For more
+ discussion see <a class="xref" href="kernel-resources.html" title="19.4. Managing Kernel Resources">Section 19.4</a>. You might be able
+ to postpone reconfiguring your kernel by decreasing <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a> to reduce the shared memory
+ consumption of <span class="productname">PostgreSQL</span>, and/or by reducing
+ <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a> to reduce the semaphore
+ consumption.
+ </p><p>
+ A failure message suggesting that another server is already running
+ should be checked carefully, for example by using the command
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>ps ax | grep postgres</code></strong>
+</pre><p>
+ or
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>ps -ef | grep postgres</code></strong>
+</pre><p>
+ depending on your system. If you are certain that no conflicting
+ server is running, you can remove the lock file mentioned in the
+ message and try again.
+ </p><p>
+ A failure message indicating inability to bind to a port might
+ indicate that that port is already in use by some
+ non-<span class="productname">PostgreSQL</span> process. You might also
+ get this error if you terminate <code class="command">postgres</code>
+ and immediately restart it using the same port; in this case, you
+ must simply wait a few seconds until the operating system closes
+ the port before trying again. Finally, you might get this error if
+ you specify a port number that your operating system considers to
+ be reserved. For example, many versions of Unix consider port
+ numbers under 1024 to be <span class="quote">“<span class="quote">trusted</span>”</span> and only permit
+ the Unix superuser to access them.
+ </p></div><div class="refsect1" id="id-1.9.5.14.9"><h2>Notes</h2><p>
+ The utility command <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a> can be used to
+ start and shut down the <code class="command">postgres</code> server
+ safely and comfortably.
+ </p><p>
+ If at all possible, <span class="emphasis"><em>do not</em></span> use
+ <code class="literal">SIGKILL</code> to kill the main
+ <code class="command">postgres</code> server. Doing so will prevent
+ <code class="command">postgres</code> from freeing the system
+ resources (e.g., shared memory and semaphores) that it holds before
+ terminating. This might cause problems for starting a fresh
+ <code class="command">postgres</code> run.
+ </p><p>
+ To terminate the <code class="command">postgres</code> server normally, the
+ signals <code class="literal">SIGTERM</code>, <code class="literal">SIGINT</code>, or
+ <code class="literal">SIGQUIT</code> can be used. The first will wait for
+ all clients to terminate before quitting, the second will
+ forcefully disconnect all clients, and the third will quit
+ immediately without proper shutdown, resulting in a recovery run
+ during restart.
+ </p><p>
+ The <code class="literal">SIGHUP</code> signal will reload
+ the server configuration files. It is also possible to send
+ <code class="literal">SIGHUP</code> to an individual server process, but that
+ is usually not sensible.
+ </p><p>
+ To cancel a running query, send the <code class="literal">SIGINT</code> signal
+ to the process running that command. To terminate a backend process
+ cleanly, send <code class="literal">SIGTERM</code> to that process. See
+ also <code class="function">pg_cancel_backend</code> and <code class="function">pg_terminate_backend</code>
+ in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL" title="9.27.2. Server Signaling Functions">Section 9.27.2</a> for the SQL-callable equivalents
+ of these two actions.
+ </p><p>
+ The <code class="command">postgres</code> server uses <code class="literal">SIGQUIT</code>
+ to tell subordinate server processes to terminate without normal
+ cleanup.
+ This signal <span class="emphasis"><em>should not</em></span> be used by users. It
+ is also unwise to send <code class="literal">SIGKILL</code> to a server
+ process — the main <code class="command">postgres</code> process will
+ interpret this as a crash and will force all the sibling processes
+ to quit as part of its standard crash-recovery procedure.
+ </p></div><div class="refsect1" id="APP-POSTGRES-BUGS"><h2>Bugs</h2><p>
+ The <code class="option">--</code> options will not work on <span class="systemitem">FreeBSD</span> or <span class="systemitem">OpenBSD</span>.
+ Use <code class="option">-c</code> instead. This is a bug in the affected operating
+ systems; a future release of <span class="productname">PostgreSQL</span>
+ will provide a workaround if this is not fixed.
+ </p></div><div class="refsect1" id="APP-POSTGRES-SINGLE-USER"><h2>Single-User Mode</h2><p>
+ To start a single-user mode server, use a command like
+</p><pre class="screen">
+<strong class="userinput"><code>postgres --single -D /usr/local/pgsql/data <em class="replaceable"><code>other-options</code></em> my_database</code></strong>
+</pre><p>
+ Provide the correct path to the database directory with <code class="option">-D</code>, or
+ make sure that the environment variable <code class="envar">PGDATA</code> is set.
+ Also specify the name of the particular database you want to work in.
+ </p><p>
+ Normally, the single-user mode server treats newline as the command
+ entry terminator; there is no intelligence about semicolons,
+ as there is in <span class="application">psql</span>. To continue a command
+ across multiple lines, you must type backslash just before each
+ newline except the last one. The backslash and adjacent newline are
+ both dropped from the input command. Note that this will happen even
+ when within a string literal or comment.
+ </p><p>
+ But if you use the <code class="option">-j</code> command line switch, a single newline
+ does not terminate command entry; instead, the sequence
+ semicolon-newline-newline does. That is, type a semicolon immediately
+ followed by a completely empty line. Backslash-newline is not
+ treated specially in this mode. Again, there is no intelligence about
+ such a sequence appearing within a string literal or comment.
+ </p><p>
+ In either input mode, if you type a semicolon that is not just before or
+ part of a command entry terminator, it is considered a command separator.
+ When you do type a command entry terminator, the multiple statements
+ you've entered will be executed as a single transaction.
+ </p><p>
+ To quit the session, type <acronym class="acronym">EOF</acronym>
+ (<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>D</strong></span>, usually).
+ If you've entered any text since the last command entry terminator,
+ then <acronym class="acronym">EOF</acronym> will be taken as a command entry terminator,
+ and another <acronym class="acronym">EOF</acronym> will be needed to exit.
+ </p><p>
+ Note that the single-user mode server does not provide sophisticated
+ line-editing features (no command history, for example).
+ Single-user mode also does not do any background processing, such as
+ automatic checkpoints or replication.
+ </p></div><div class="refsect1" id="APP-POSTGRES-EXAMPLES"><h2>Examples</h2><p>
+ To start <code class="command">postgres</code> in the background
+ using default values, type:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>nohup postgres &gt;logfile 2&gt;&amp;1 &lt;/dev/null &amp;</code></strong>
+</pre><p>
+ </p><p>
+ To start <code class="command">postgres</code> with a specific
+ port, e.g., 1234:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>postgres -p 1234</code></strong>
+</pre><p>
+ To connect to this server using <span class="application">psql</span>, specify this port with the -p option:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>psql -p 1234</code></strong>
+</pre><p>
+ or set the environment variable <code class="envar">PGPORT</code>:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>export PGPORT=1234</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>psql</code></strong>
+</pre><p>
+ </p><p>
+ Named run-time parameters can be set in either of these styles:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>postgres -c work_mem=1234</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>postgres --work-mem=1234</code></strong>
+</pre><p>
+ Either form overrides whatever setting might exist for
+ <code class="varname">work_mem</code> in <code class="filename">postgresql.conf</code>. Notice that
+ underscores in parameter names can be written as either underscore
+ or dash on the command line. Except for short-term experiments,
+ it's probably better practice to edit the setting in
+ <code class="filename">postgresql.conf</code> than to rely on a command-line switch
+ to set a parameter.
+ </p></div><div class="refsect1" id="id-1.9.5.14.13"><h2>See Also</h2><p>
+ <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a>,
+ <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgwaldump.html" title="pg_waldump">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-postmaster.html" title="postmaster">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_waldump</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">postmaster</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-postmaster.html b/doc/src/sgml/html/app-postmaster.html
new file mode 100644
index 0000000..3fe25ef
--- /dev/null
+++ b/doc/src/sgml/html/app-postmaster.html
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>postmaster</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-postgres.html" title="postgres" /><link rel="next" href="internals.html" title="Part VII. Internals" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">postmaster</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-postgres.html" title="postgres">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="internals.html" title="Part VII. Internals">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-POSTMASTER"><div class="titlepage"></div><a id="id-1.9.5.15.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">postmaster</span></span></h2><p>postmaster — <span class="productname">PostgreSQL</span> database server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.15.4.1"><code class="command">postmaster</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.5.15.5"><h2>Description</h2><p>
+ <code class="command">postmaster</code> is a deprecated alias of <code class="command">postgres</code>.
+ </p></div><div class="refsect1" id="id-1.9.5.15.6"><h2>See Also</h2><p>
+ <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-postgres.html" title="postgres">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="internals.html" title="Part VII. Internals">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">postgres</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part VII. Internals</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-psql.html b/doc/src/sgml/html/app-psql.html
new file mode 100644
index 0000000..26e145c
--- /dev/null
+++ b/doc/src/sgml/html/app-psql.html
@@ -0,0 +1,2955 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>psql</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgverifybackup.html" title="pg_verifybackup" /><link rel="next" href="app-reindexdb.html" title="reindexdb" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">psql</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgverifybackup.html" title="pg_verifybackup">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-reindexdb.html" title="reindexdb">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-PSQL"><div class="titlepage"></div><a id="id-1.9.4.20.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">psql</span></span></h2><p><span class="application">psql</span> —
+ <span class="productname">PostgreSQL</span> interactive terminal
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.20.4.1"><code class="command">psql</code> [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>dbname</code></em>
+ [<em class="replaceable"><code>username</code></em>]]</p></div></div><div class="refsect1" id="id-1.9.4.20.5"><h2>Description</h2><p>
+ <span class="application">psql</span> is a terminal-based front-end to
+ <span class="productname">PostgreSQL</span>. It enables you to type in
+ queries interactively, issue them to
+ <span class="productname">PostgreSQL</span>, and see the query results.
+ Alternatively, input can be from a file or from command line
+ arguments. In addition, <span class="application">psql</span> provides a
+ number of meta-commands and various shell-like features to
+ facilitate writing scripts and automating a wide variety of tasks.
+ </p></div><div class="refsect1" id="R1-APP-PSQL-3"><h2>Options</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--echo-all</code></span></dt><dd><p>
+ Print all nonempty input lines to standard output as they are read.
+ (This does not apply to lines read interactively.) This is
+ equivalent to setting the variable <code class="varname">ECHO</code> to
+ <code class="literal">all</code>.
+ </p></dd><dt><span class="term"><code class="option">-A</code><br /></span><span class="term"><code class="option">--no-align</code></span></dt><dd><p>
+ Switches to unaligned output mode. (The default output mode is
+ <code class="literal">aligned</code>.) This is equivalent to
+ <code class="command">\pset format unaligned</code>.
+ </p></dd><dt><span class="term"><code class="option">-b</code><br /></span><span class="term"><code class="option">--echo-errors</code></span></dt><dd><p>
+ Print failed SQL commands to standard error output. This is
+ equivalent to setting the variable <code class="varname">ECHO</code> to
+ <code class="literal">errors</code>.
+ </p></dd><dt><span class="term"><code class="option">-c <em class="replaceable"><code>command</code></em></code><br /></span><span class="term"><code class="option">--command=<em class="replaceable"><code>command</code></em></code></span></dt><dd><p>
+ Specifies that <span class="application">psql</span> is to execute the given
+ command string, <em class="replaceable"><code>command</code></em>.
+ This option can be repeated and combined in any order with
+ the <code class="option">-f</code> option. When either <code class="option">-c</code>
+ or <code class="option">-f</code> is specified, <span class="application">psql</span>
+ does not read commands from standard input; instead it terminates
+ after processing all the <code class="option">-c</code> and <code class="option">-f</code>
+ options in sequence.
+ </p><p>
+ <em class="replaceable"><code>command</code></em> must be either
+ a command string that is completely parsable by the server (i.e.,
+ it contains no <span class="application">psql</span>-specific features),
+ or a single backslash command. Thus you cannot mix
+ <acronym class="acronym">SQL</acronym> and <span class="application">psql</span>
+ meta-commands within a <code class="option">-c</code> option. To achieve that,
+ you could use repeated <code class="option">-c</code> options or pipe the string
+ into <span class="application">psql</span>, for example:
+</p><pre class="programlisting">
+psql -c '\x' -c 'SELECT * FROM foo;'
+</pre><p>
+ or
+</p><pre class="programlisting">
+echo '\x \\ SELECT * FROM foo;' | psql
+</pre><p>
+ (<code class="literal">\\</code> is the separator meta-command.)
+ </p><p>
+ Each <acronym class="acronym">SQL</acronym> command string passed
+ to <code class="option">-c</code> is sent to the server as a single request.
+ Because of this, the server executes it as a single transaction even
+ if the string contains multiple <acronym class="acronym">SQL</acronym> commands,
+ unless there are explicit <code class="command">BEGIN</code>/<code class="command">COMMIT</code>
+ commands included in the string to divide it into multiple
+ transactions. (See <a class="xref" href="protocol-flow.html#PROTOCOL-FLOW-MULTI-STATEMENT" title="55.2.2.1. Multiple Statements in a Simple Query">Section 55.2.2.1</a>
+ for more details about how the server handles multi-query strings.)
+ </p><p>
+ If having several commands executed in one transaction is not desired,
+ use repeated <code class="option">-c</code> commands or feed multiple commands to
+ <span class="application">psql</span>'s standard input,
+ either using <span class="application">echo</span> as illustrated above, or
+ via a shell here-document, for example:
+</p><pre class="programlisting">
+psql &lt;&lt;EOF
+\x
+SELECT * FROM foo;
+EOF
+</pre></dd><dt><span class="term"><code class="option">--csv</code></span></dt><dd><p>
+ Switches to <acronym class="acronym">CSV</acronym> (Comma-Separated Values) output
+ mode. This is equivalent to <code class="command">\pset format csv</code>.
+ </p></dd><dt><span class="term"><code class="option">-d <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to. This is
+ equivalent to specifying <em class="replaceable"><code>dbname</code></em> as the first non-option
+ argument on the command line. The <em class="replaceable"><code>dbname</code></em>
+ can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>.
+ If so, connection string parameters will override any conflicting
+ command line options.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo-queries</code></span></dt><dd><p>
+ Copy all SQL commands sent to the server to standard output as well.
+ This is equivalent
+ to setting the variable <code class="varname">ECHO</code> to
+ <code class="literal">queries</code>.
+ </p></dd><dt><span class="term"><code class="option">-E</code><br /></span><span class="term"><code class="option">--echo-hidden</code></span></dt><dd><p>
+ Echo the actual queries generated by <code class="command">\d</code> and other backslash
+ commands. You can use this to study <span class="application">psql</span>'s
+ internal operations. This is equivalent to
+ setting the variable <code class="varname">ECHO_HIDDEN</code> to <code class="literal">on</code>.
+ </p></dd><dt><span class="term"><code class="option">-f <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--file=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Read commands from the
+ file <em class="replaceable"><code>filename</code></em>,
+ rather than standard input.
+ This option can be repeated and combined in any order with
+ the <code class="option">-c</code> option. When either <code class="option">-c</code>
+ or <code class="option">-f</code> is specified, <span class="application">psql</span>
+ does not read commands from standard input; instead it terminates
+ after processing all the <code class="option">-c</code> and <code class="option">-f</code>
+ options in sequence.
+ Except for that, this option is largely equivalent to the
+ meta-command <code class="command">\i</code>.
+ </p><p>
+ If <em class="replaceable"><code>filename</code></em> is <code class="literal">-</code>
+ (hyphen), then standard input is read until an EOF indication
+ or <code class="command">\q</code> meta-command. This can be used to intersperse
+ interactive input with input from files. Note however that Readline
+ is not used in this case (much as if <code class="option">-n</code> had been
+ specified).
+ </p><p>
+ Using this option is subtly different from writing <code class="literal">psql
+ &lt; <em class="replaceable"><code>filename</code></em></code>. In general,
+ both will do what you expect, but using <code class="literal">-f</code>
+ enables some nice features such as error messages with line
+ numbers. There is also a slight chance that using this option will
+ reduce the start-up overhead. On the other hand, the variant using
+ the shell's input redirection is (in theory) guaranteed to yield
+ exactly the same output you would have received had you entered
+ everything by hand.
+ </p></dd><dt><span class="term"><code class="option">-F <em class="replaceable"><code>separator</code></em></code><br /></span><span class="term"><code class="option">--field-separator=<em class="replaceable"><code>separator</code></em></code></span></dt><dd><p>
+ Use <em class="replaceable"><code>separator</code></em> as the
+ field separator for unaligned output. This is equivalent to
+ <code class="command">\pset fieldsep</code> or <code class="command">\f</code>.
+ </p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>hostname</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>hostname</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the
+ server is running. If the value begins
+ with a slash, it is used as the directory for the Unix-domain
+ socket.
+ </p></dd><dt><span class="term"><code class="option">-H</code><br /></span><span class="term"><code class="option">--html</code></span></dt><dd><p>
+ Switches to <acronym class="acronym">HTML</acronym> output mode. This is
+ equivalent to <code class="command">\pset format html</code> or the
+ <code class="command">\H</code> command.
+ </p></dd><dt><span class="term"><code class="option">-l</code><br /></span><span class="term"><code class="option">--list</code></span></dt><dd><p>
+ List all available databases, then exit. Other non-connection
+ options are ignored. This is similar to the meta-command
+ <code class="command">\list</code>.
+ </p><p>
+ When this option is used, <span class="application">psql</span> will connect
+ to the database <code class="literal">postgres</code>, unless a different database
+ is named on the command line (option <code class="option">-d</code> or non-option
+ argument, possibly via a service entry, but not via an environment
+ variable).
+ </p></dd><dt><span class="term"><code class="option">-L <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--log-file=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Write all query output into file <em class="replaceable"><code>filename</code></em>, in addition to the
+ normal output destination.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-readline</code></span></dt><dd><p>
+ Do not use <span class="application">Readline</span> for line editing and
+ do not use the command history (see
+ <a class="xref" href="app-psql.html#APP-PSQL-READLINE" title="Command-Line Editing">the section called “Command-Line Editing”</a> below).
+ </p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>filename</code></em></code><br /></span><span class="term"><code class="option">--output=<em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Put all query output into file <em class="replaceable"><code>filename</code></em>. This is equivalent to
+ the command <code class="command">\o</code>.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or the local Unix-domain
+ socket file extension on which the server is listening for
+ connections. Defaults to the value of the <code class="envar">PGPORT</code>
+ environment variable or, if not set, to the port specified at
+ compile time, usually 5432.
+ </p></dd><dt><span class="term"><code class="option">-P <em class="replaceable"><code>assignment</code></em></code><br /></span><span class="term"><code class="option">--pset=<em class="replaceable"><code>assignment</code></em></code></span></dt><dd><p>
+ Specifies printing options, in the style of
+ <code class="command">\pset</code>. Note that here you
+ have to separate name and value with an equal sign instead of a
+ space. For example, to set the output format to <span class="application">LaTeX</span>, you could write
+ <code class="literal">-P format=latex</code>.
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Specifies that <span class="application">psql</span> should do its work
+ quietly. By default, it prints welcome messages and various
+ informational output. If this option is used, none of this
+ happens. This is useful with the <code class="option">-c</code> option.
+ This is equivalent to setting the variable <code class="varname">QUIET</code>
+ to <code class="literal">on</code>.
+ </p></dd><dt><span class="term"><code class="option">-R <em class="replaceable"><code>separator</code></em></code><br /></span><span class="term"><code class="option">--record-separator=<em class="replaceable"><code>separator</code></em></code></span></dt><dd><p>
+ Use <em class="replaceable"><code>separator</code></em> as the
+ record separator for unaligned output. This is equivalent to
+ <code class="command">\pset recordsep</code>.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--single-step</code></span></dt><dd><p>
+ Run in single-step mode. That means the user is prompted before
+ each command is sent to the server, with the option to cancel
+ execution as well. Use this to debug scripts.
+ </p></dd><dt><span class="term"><code class="option">-S</code><br /></span><span class="term"><code class="option">--single-line</code></span></dt><dd><p>
+ Runs in single-line mode where a newline terminates an SQL command, as a
+ semicolon does.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This mode is provided for those who insist on it, but you are not
+ necessarily encouraged to use it. In particular, if you mix
+ <acronym class="acronym">SQL</acronym> and meta-commands on a line the order of
+ execution might not always be clear to the inexperienced user.
+ </p></div></dd><dt><span class="term"><code class="option">-t</code><br /></span><span class="term"><code class="option">--tuples-only</code></span></dt><dd><p>
+ Turn off printing of column names and result row count footers,
+ etc. This is equivalent to <code class="command">\t</code> or
+ <code class="command">\pset tuples_only</code>.
+ </p></dd><dt><span class="term"><code class="option">-T <em class="replaceable"><code>table_options</code></em></code><br /></span><span class="term"><code class="option">--table-attr=<em class="replaceable"><code>table_options</code></em></code></span></dt><dd><p>
+ Specifies options to be placed within the
+ <acronym class="acronym">HTML</acronym> <code class="sgmltag-element">table</code> tag. See
+ <code class="command">\pset tableattr</code> for details.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ Connect to the database as the user <em class="replaceable"><code>username</code></em> instead of the default.
+ (You must have permission to do so, of course.)
+ </p></dd><dt><span class="term"><code class="option">-v <em class="replaceable"><code>assignment</code></em></code><br /></span><span class="term"><code class="option">--set=<em class="replaceable"><code>assignment</code></em></code><br /></span><span class="term"><code class="option">--variable=<em class="replaceable"><code>assignment</code></em></code></span></dt><dd><p>
+ Perform a variable assignment, like the <code class="command">\set</code>
+ meta-command. Note that you must separate name and value, if
+ any, by an equal sign on the command line. To unset a variable,
+ leave off the equal sign. To set a variable with an empty value,
+ use the equal sign but leave off the value. These assignments are
+ done during command line processing, so variables that reflect
+ connection state will get overwritten later.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">psql</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires password
+ authentication and a password is not available from other sources
+ such as a <code class="filename">.pgpass</code> file, the connection
+ attempt will fail. This option can be useful in batch jobs and
+ scripts where no user is present to enter a password.
+ </p><p>
+ Note that this option will remain set for the entire session,
+ and so it affects uses of the meta-command
+ <code class="command">\connect</code> as well as the initial connection attempt.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">psql</span> to prompt for a
+ password before connecting to a database, even if the password will
+ not be used.
+ </p><p>
+ If the server requires password authentication and a password is not
+ available from other sources such as a <code class="filename">.pgpass</code>
+ file, <span class="application">psql</span> will prompt for a
+ password in any case. However, <span class="application">psql</span>
+ will waste a connection attempt finding out that the server wants a
+ password. In some cases it is worth typing <code class="option">-W</code> to avoid
+ the extra connection attempt.
+ </p><p>
+ Note that this option will remain set for the entire session,
+ and so it affects uses of the meta-command
+ <code class="command">\connect</code> as well as the initial connection attempt.
+ </p></dd><dt><span class="term"><code class="option">-x</code><br /></span><span class="term"><code class="option">--expanded</code></span></dt><dd><p>
+ Turn on the expanded table formatting mode. This is equivalent to
+ <code class="command">\x</code> or <code class="command">\pset expanded</code>.
+ </p></dd><dt><span class="term"><code class="option">-X,</code><br /></span><span class="term"><code class="option">--no-psqlrc</code></span></dt><dd><p>
+ Do not read the start-up file (neither the system-wide
+ <code class="filename">psqlrc</code> file nor the user's
+ <code class="filename">~/.psqlrc</code> file).
+ </p></dd><dt><span class="term"><code class="option">-z</code><br /></span><span class="term"><code class="option">--field-separator-zero</code></span></dt><dd><p>
+ Set the field separator for unaligned output to a zero byte. This is
+ equivalent to <code class="command">\pset fieldsep_zero</code>.
+ </p></dd><dt><span class="term"><code class="option">-0</code><br /></span><span class="term"><code class="option">--record-separator-zero</code></span></dt><dd><p>
+ Set the record separator for unaligned output to a zero byte. This is
+ useful for interfacing, for example, with <code class="literal">xargs -0</code>.
+ This is equivalent to <code class="command">\pset recordsep_zero</code>.
+ </p></dd><dt><span class="term"><code class="option">-1</code><br /></span><span class="term"><code class="option">--single-transaction</code></span></dt><dd><p>
+ This option can only be used in combination with one or more
+ <code class="option">-c</code> and/or <code class="option">-f</code> options. It causes
+ <span class="application">psql</span> to issue a <code class="command">BEGIN</code> command
+ before the first such option and a <code class="command">COMMIT</code> command after
+ the last one, thereby wrapping all the commands into a single
+ transaction. If any of the commands fails and the variable
+ <code class="varname">ON_ERROR_STOP</code> was set, a
+ <code class="command">ROLLBACK</code> command is sent instead. This ensures that
+ either all the commands complete successfully, or no changes are
+ applied.
+ </p><p>
+ If the commands themselves
+ contain <code class="command">BEGIN</code>, <code class="command">COMMIT</code>,
+ or <code class="command">ROLLBACK</code>, this option will not have the desired
+ effects. Also, if an individual command cannot be executed inside a
+ transaction block, specifying this option will cause the whole
+ transaction to fail.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help[=<em class="replaceable"><code>topic</code></em>]</code></span></dt><dd><p>
+ Show help about <span class="application">psql</span> and exit. The optional
+ <em class="replaceable"><code>topic</code></em> parameter (defaulting
+ to <code class="literal">options</code>) selects which part of <span class="application">psql</span> is
+ explained: <code class="literal">commands</code> describes <span class="application">psql</span>'s
+ backslash commands; <code class="literal">options</code> describes the command-line
+ options that can be passed to <span class="application">psql</span>;
+ and <code class="literal">variables</code> shows help about <span class="application">psql</span> configuration
+ variables.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.4.20.7"><h2>Exit Status</h2><p>
+ <span class="application">psql</span> returns 0 to the shell if it
+ finished normally, 1 if a fatal error of its own occurs (e.g., out of memory,
+ file not found), 2 if the connection to the server went bad
+ and the session was not interactive, and 3 if an error occurred in a
+ script and the variable <code class="varname">ON_ERROR_STOP</code> was set.
+ </p></div><div class="refsect1" id="id-1.9.4.20.8"><h2>Usage</h2><div class="refsect2" id="R2-APP-PSQL-CONNECTING"><h3>Connecting to a Database</h3><p>
+ <span class="application">psql</span> is a regular
+ <span class="productname">PostgreSQL</span> client application. In order
+ to connect to a database you need to know the name of your target
+ database, the host name and port number of the server, and what user
+ name you want to connect as. <span class="application">psql</span> can be
+ told about those parameters via command line options, namely
+ <code class="option">-d</code>, <code class="option">-h</code>, <code class="option">-p</code>, and
+ <code class="option">-U</code> respectively. If an argument is found that does
+ not belong to any option it will be interpreted as the database name
+ (or the user name, if the database name is already given). Not all
+ of these options are required; there are useful defaults. If you omit the host
+ name, <span class="application">psql</span> will connect via a Unix-domain socket
+ to a server on the local host, or via TCP/IP to <code class="literal">localhost</code> on
+ machines that don't have Unix-domain sockets. The default port number is
+ determined at compile time.
+ Since the database server uses the same default, you will not have
+ to specify the port in most cases. The default user name is your
+ operating-system user name, as is the default database name.
+ Note that you cannot
+ just connect to any database under any user name. Your database
+ administrator should have informed you about your access rights.
+ </p><p>
+ When the defaults aren't quite right, you can save yourself
+ some typing by setting the environment variables
+ <code class="envar">PGDATABASE</code>, <code class="envar">PGHOST</code>,
+ <code class="envar">PGPORT</code> and/or <code class="envar">PGUSER</code> to appropriate
+ values. (For additional environment variables, see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>.) It is also convenient to have a
+ <code class="filename">~/.pgpass</code> file to avoid regularly having to type in
+ passwords. See <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a> for more information.
+ </p><p>
+ An alternative way to specify connection parameters is in a
+ <em class="parameter"><code>conninfo</code></em> string or
+ a <acronym class="acronym">URI</acronym>, which is used instead of a database
+ name. This mechanism give you very wide control over the
+ connection. For example:
+</p><pre class="programlisting">
+$ <strong class="userinput"><code>psql "service=myservice sslmode=require"</code></strong>
+$ <strong class="userinput"><code>psql postgresql://dbmaster:5433/mydb?sslmode=require</code></strong>
+</pre><p>
+ This way you can also use <acronym class="acronym">LDAP</acronym> for connection
+ parameter lookup as described in <a class="xref" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters">Section 34.18</a>.
+ See <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a> for more information on all the
+ available connection options.
+ </p><p>
+ If the connection could not be made for any reason (e.g., insufficient
+ privileges, server is not running on the targeted host, etc.),
+ <span class="application">psql</span> will return an error and terminate.
+ </p><p>
+ If both standard input and standard output are a
+ terminal, then <span class="application">psql</span> sets the client
+ encoding to <span class="quote">“<span class="quote">auto</span>”</span>, which will detect the
+ appropriate client encoding from the locale settings
+ (<code class="envar">LC_CTYPE</code> environment variable on Unix systems).
+ If this doesn't work out as expected, the client encoding can be
+ overridden using the environment
+ variable <code class="envar">PGCLIENTENCODING</code>.
+ </p></div><div class="refsect2" id="R2-APP-PSQL-4"><h3>Entering SQL Commands</h3><p>
+ In normal operation, <span class="application">psql</span> provides a
+ prompt with the name of the database to which
+ <span class="application">psql</span> is currently connected, followed by
+ the string <code class="literal">=&gt;</code>. For example:
+</p><pre class="programlisting">
+$ <strong class="userinput"><code>psql testdb</code></strong>
+psql (15.4)
+Type "help" for help.
+
+testdb=&gt;
+</pre><p>
+ </p><p>
+ At the prompt, the user can type in <acronym class="acronym">SQL</acronym> commands.
+ Ordinarily, input lines are sent to the server when a
+ command-terminating semicolon is reached. An end of line does not
+ terminate a command. Thus commands can be spread over several lines for
+ clarity. If the command was sent and executed without error, the results
+ of the command are displayed on the screen.
+ </p><p>
+ If untrusted users have access to a database that has not adopted a
+ <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage pattern</a>,
+ begin your session by removing publicly-writable schemas
+ from <code class="varname">search_path</code>. One can
+ add <code class="literal">options=-csearch_path=</code> to the connection string or
+ issue <code class="literal">SELECT pg_catalog.set_config('search_path', '',
+ false)</code> before other SQL commands. This consideration is not
+ specific to <span class="application">psql</span>; it applies to every interface
+ for executing arbitrary SQL commands.
+ </p><p>
+ Whenever a command is executed, <span class="application">psql</span> also polls
+ for asynchronous notification events generated by
+ <a class="link" href="sql-listen.html" title="LISTEN"><code class="command">LISTEN</code></a> and
+ <a class="link" href="sql-notify.html" title="NOTIFY"><code class="command">NOTIFY</code></a>.
+ </p><p>
+ While C-style block comments are passed to the server for
+ processing and removal, SQL-standard comments are removed by
+ <span class="application">psql</span>.
+ </p></div><div class="refsect2" id="APP-PSQL-META-COMMANDS"><h3>Meta-Commands</h3><p>
+ Anything you enter in <span class="application">psql</span> that begins
+ with an unquoted backslash is a <span class="application">psql</span>
+ meta-command that is processed by <span class="application">psql</span>
+ itself. These commands make
+ <span class="application">psql</span> more useful for administration or
+ scripting. Meta-commands are often called slash or backslash commands.
+ </p><p>
+ The format of a <span class="application">psql</span> command is the backslash,
+ followed immediately by a command verb, then any arguments. The arguments
+ are separated from the command verb and each other by any number of
+ whitespace characters.
+ </p><p>
+ To include whitespace in an argument you can quote it with
+ single quotes. To include a single quote in an argument,
+ write two single quotes within single-quoted text.
+ Anything contained in single quotes is
+ furthermore subject to C-like substitutions for
+ <code class="literal">\n</code> (new line), <code class="literal">\t</code> (tab),
+ <code class="literal">\b</code> (backspace), <code class="literal">\r</code> (carriage return),
+ <code class="literal">\f</code> (form feed),
+ <code class="literal">\</code><em class="replaceable"><code>digits</code></em> (octal), and
+ <code class="literal">\x</code><em class="replaceable"><code>digits</code></em> (hexadecimal).
+ A backslash preceding any other character within single-quoted text
+ quotes that single character, whatever it is.
+ </p><p>
+ If an unquoted colon (<code class="literal">:</code>) followed by a
+ <span class="application">psql</span> variable name appears within an argument, it is
+ replaced by the variable's value, as described in <a class="xref" href="app-psql.html#APP-PSQL-INTERPOLATION" title="SQL Interpolation">SQL Interpolation</a> below.
+ The forms <code class="literal">:'<em class="replaceable"><code>variable_name</code></em>'</code> and
+ <code class="literal">:"<em class="replaceable"><code>variable_name</code></em>"</code> described there
+ work as well.
+ The <code class="literal">:{?<em class="replaceable"><code>variable_name</code></em>}</code> syntax allows
+ testing whether a variable is defined. It is substituted by
+ TRUE or FALSE.
+ Escaping the colon with a backslash protects it from substitution.
+ </p><p>
+ Within an argument, text that is enclosed in backquotes
+ (<code class="literal">`</code>) is taken as a command line that is passed to the
+ shell. The output of the command (with any trailing newline removed)
+ replaces the backquoted text. Within the text enclosed in backquotes,
+ no special quoting or other processing occurs, except that appearances
+ of <code class="literal">:<em class="replaceable"><code>variable_name</code></em></code> where
+ <em class="replaceable"><code>variable_name</code></em> is a <span class="application">psql</span> variable name
+ are replaced by the variable's value. Also, appearances of
+ <code class="literal">:'<em class="replaceable"><code>variable_name</code></em>'</code> are replaced by the
+ variable's value suitably quoted to become a single shell command
+ argument. (The latter form is almost always preferable, unless you are
+ very sure of what is in the variable.) Because carriage return and line
+ feed characters cannot be safely quoted on all platforms, the
+ <code class="literal">:'<em class="replaceable"><code>variable_name</code></em>'</code> form prints an
+ error message and does not substitute the variable value when such
+ characters appear in the value.
+ </p><p>
+ Some commands take an <acronym class="acronym">SQL</acronym> identifier (such as a
+ table name) as argument. These arguments follow the syntax rules
+ of <acronym class="acronym">SQL</acronym>: Unquoted letters are forced to
+ lowercase, while double quotes (<code class="literal">"</code>) protect letters
+ from case conversion and allow incorporation of whitespace into
+ the identifier. Within double quotes, paired double quotes reduce
+ to a single double quote in the resulting name. For example,
+ <code class="literal">FOO"BAR"BAZ</code> is interpreted as <code class="literal">fooBARbaz</code>,
+ and <code class="literal">"A weird"" name"</code> becomes <code class="literal">A weird"
+ name</code>.
+ </p><p>
+ Parsing for arguments stops at the end of the line, or when another
+ unquoted backslash is found. An unquoted backslash
+ is taken as the beginning of a new meta-command. The special
+ sequence <code class="literal">\\</code> (two backslashes) marks the end of
+ arguments and continues parsing <acronym class="acronym">SQL</acronym> commands, if
+ any. That way <acronym class="acronym">SQL</acronym> and
+ <span class="application">psql</span> commands can be freely mixed on a
+ line. But in any case, the arguments of a meta-command cannot
+ continue beyond the end of the line.
+ </p><p>
+ Many of the meta-commands act on the <em class="firstterm">current query buffer</em>.
+ This is simply a buffer holding whatever SQL command text has been typed
+ but not yet sent to the server for execution. This will include previous
+ input lines as well as any text appearing before the meta-command on the
+ same line.
+ </p><p>
+ The following meta-commands are defined:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">\a</code></span></dt><dd><p>
+ If the current table output format is unaligned, it is switched to aligned.
+ If it is not unaligned, it is set to unaligned. This command is
+ kept for backwards compatibility. See <code class="command">\pset</code> for a
+ more general solution.
+ </p></dd><dt><span class="term"><code class="literal">\c</code> or <code class="literal">\connect [ -reuse-previous=<em class="replaceable"><code>on|off</code></em> ] [ <em class="replaceable"><code>dbname</code></em> [ <em class="replaceable"><code>username</code></em> ] [ <em class="replaceable"><code>host</code></em> ] [ <em class="replaceable"><code>port</code></em> ] | <em class="replaceable"><code>conninfo</code></em> ]</code></span></dt><dd><p>
+ Establishes a new connection to a <span class="productname">PostgreSQL</span>
+ server. The connection parameters to use can be specified either
+ using a positional syntax (one or more of database name, user,
+ host, and port), or using a <em class="replaceable"><code>conninfo</code></em>
+ connection string as detailed in
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a>. If no arguments are given, a
+ new connection is made using the same parameters as before.
+ </p><p>
+ Specifying any
+ of <em class="replaceable"><code>dbname</code></em>,
+ <em class="replaceable"><code>username</code></em>,
+ <em class="replaceable"><code>host</code></em> or
+ <em class="replaceable"><code>port</code></em>
+ as <code class="literal">-</code> is equivalent to omitting that parameter.
+ </p><p>
+ The new connection can re-use connection parameters from the previous
+ connection; not only database name, user, host, and port, but other
+ settings such as <em class="replaceable"><code>sslmode</code></em>. By default,
+ parameters are re-used in the positional syntax, but not when
+ a <em class="replaceable"><code>conninfo</code></em> string is given. Passing a
+ first argument of <code class="literal">-reuse-previous=on</code>
+ or <code class="literal">-reuse-previous=off</code> overrides that default. If
+ parameters are re-used, then any parameter not explicitly specified as
+ a positional parameter or in the <em class="replaceable"><code>conninfo</code></em>
+ string is taken from the existing connection's parameters. An
+ exception is that if the <em class="replaceable"><code>host</code></em> setting
+ is changed from its previous value using the positional syntax,
+ any <em class="replaceable"><code>hostaddr</code></em> setting present in the
+ existing connection's parameters is dropped.
+ Also, any password used for the existing connection will be re-used
+ only if the user, host, and port settings are not changed.
+ When the command neither specifies nor reuses a particular parameter,
+ the <span class="application">libpq</span> default is used.
+ </p><p>
+ If the new connection is successfully made, the previous
+ connection is closed.
+ If the connection attempt fails (wrong user name, access
+ denied, etc.), the previous connection will be kept if
+ <span class="application">psql</span> is in interactive mode. But when
+ executing a non-interactive script, the old connection is closed
+ and an error is reported. That may or may not terminate the
+ script; if it does not, all database-accessing commands will fail
+ until another <code class="literal">\connect</code> command is successfully
+ executed. This distinction was chosen as
+ a user convenience against typos on the one hand, and a safety
+ mechanism that scripts are not accidentally acting on the
+ wrong database on the other hand.
+ Note that whenever a <code class="literal">\connect</code> command attempts
+ to re-use parameters, the values re-used are those of the last
+ successful connection, not of any failed attempts made subsequently.
+ However, in the case of a
+ non-interactive <code class="literal">\connect</code> failure, no parameters
+ are allowed to be re-used later, since the script would likely be
+ expecting the values from the failed <code class="literal">\connect</code>
+ to be re-used.
+ </p><p>
+ Examples:
+ </p><pre class="programlisting">
+=&gt; \c mydb myuser host.dom 6432
+=&gt; \c service=foo
+=&gt; \c "host=localhost port=5432 dbname=mydb connect_timeout=10 sslmode=disable"
+=&gt; \c -reuse-previous=on sslmode=require -- changes only sslmode
+=&gt; \c postgresql://tom@localhost/mydb?application_name=myapp
+</pre></dd><dt><span class="term"><code class="literal">\C [ <em class="replaceable"><code>title</code></em> ]</code></span></dt><dd><p>
+ Sets the title of any tables being printed as the result of a
+ query or unset any such title. This command is equivalent to
+ <code class="literal">\pset title <em class="replaceable"><code>title</code></em></code>. (The name of
+ this command derives from <span class="quote">“<span class="quote">caption</span>”</span>, as it was
+ previously only used to set the caption in an
+ <acronym class="acronym">HTML</acronym> table.)
+ </p></dd><dt><span class="term"><code class="literal">\cd [ <em class="replaceable"><code>directory</code></em> ]</code></span></dt><dd><p>
+ Changes the current working directory to
+ <em class="replaceable"><code>directory</code></em>. Without argument, changes
+ to the current user's home directory.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ To print your current working directory, use <code class="literal">\! pwd</code>.
+ </p></div></dd><dt><span class="term"><code class="literal">\conninfo</code></span></dt><dd><p>
+ Outputs information about the current database connection.
+ </p></dd><dt id="APP-PSQL-META-COMMANDS-COPY"><span class="term"><code class="literal">\copy { <em class="replaceable"><code>table</code></em> [ ( <em class="replaceable"><code>column_list</code></em> ) ] }
+ <code class="literal">from</code>
+ { <em class="replaceable"><code>'filename'</code></em> | program <em class="replaceable"><code>'command'</code></em> | stdin | pstdin }
+ [ [ with ] ( <em class="replaceable"><code>option</code></em> [, ...] ) ]
+ [ where <em class="replaceable"><code>condition</code></em> ]</code><br /></span><span class="term"><code class="literal">\copy { <em class="replaceable"><code>table</code></em> [ ( <em class="replaceable"><code>column_list</code></em> ) ] | ( <em class="replaceable"><code>query</code></em> ) }
+ <code class="literal">to</code>
+ { <em class="replaceable"><code>'filename'</code></em> | program <em class="replaceable"><code>'command'</code></em> | stdout | pstdout }
+ [ [ with ] ( <em class="replaceable"><code>option</code></em> [, ...] ) ]</code></span></dt><dd><p>
+ Performs a frontend (client) copy. This is an operation that
+ runs an <acronym class="acronym">SQL</acronym> <a class="link" href="sql-copy.html" title="COPY"><code class="command">COPY</code></a>
+ command, but instead of the server
+ reading or writing the specified file,
+ <span class="application">psql</span> reads or writes the file and
+ routes the data between the server and the local file system.
+ This means that file accessibility and privileges are those of
+ the local user, not the server, and no SQL superuser
+ privileges are required.
+ </p><p>
+ When <code class="literal">program</code> is specified,
+ <em class="replaceable"><code>command</code></em> is
+ executed by <span class="application">psql</span> and the data passed from
+ or to <em class="replaceable"><code>command</code></em> is
+ routed between the server and the client.
+ Again, the execution privileges are those of
+ the local user, not the server, and no SQL superuser
+ privileges are required.
+ </p><p>
+ For <code class="literal">\copy ... from stdin</code>, data rows are read from the same
+ source that issued the command, continuing until <code class="literal">\.</code>
+ is read or the stream reaches <acronym class="acronym">EOF</acronym>. This option is useful
+ for populating tables in-line within an SQL script file.
+ For <code class="literal">\copy ... to stdout</code>, output is sent to the same place
+ as <span class="application">psql</span> command output, and
+ the <code class="literal">COPY <em class="replaceable"><code>count</code></em></code> command status is
+ not printed (since it might be confused with a data row).
+ To read/write <span class="application">psql</span>'s standard input or
+ output regardless of the current command source or <code class="literal">\o</code>
+ option, write <code class="literal">from pstdin</code> or <code class="literal">to pstdout</code>.
+ </p><p>
+ The syntax of this command is similar to that of the
+ <acronym class="acronym">SQL</acronym> <a class="link" href="sql-copy.html" title="COPY"><code class="command">COPY</code></a>
+ command. All options other than the data source/destination are
+ as specified for <code class="command">COPY</code>.
+ Because of this, special parsing rules apply to the <code class="command">\copy</code>
+ meta-command. Unlike most other meta-commands, the entire remainder
+ of the line is always taken to be the arguments of <code class="command">\copy</code>,
+ and neither variable interpolation nor backquote expansion are
+ performed in the arguments.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Another way to obtain the same result as <code class="literal">\copy
+ ... to</code> is to use the <acronym class="acronym">SQL</acronym> <code class="literal">COPY
+ ... TO STDOUT</code> command and terminate it
+ with <code class="literal">\g <em class="replaceable"><code>filename</code></em></code>
+ or <code class="literal">\g |<em class="replaceable"><code>program</code></em></code>.
+ Unlike <code class="literal">\copy</code>, this method allows the command to
+ span multiple lines; also, variable interpolation and backquote
+ expansion can be used.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ These operations are not as efficient as the <acronym class="acronym">SQL</acronym>
+ <code class="command">COPY</code> command with a file or program data source or
+ destination, because all data must pass through the client/server
+ connection. For large amounts of data the <acronym class="acronym">SQL</acronym>
+ command might be preferable.
+ </p></div></dd><dt><span class="term"><code class="literal">\copyright</code></span></dt><dd><p>
+ Shows the copyright and distribution terms of
+ <span class="productname">PostgreSQL</span>.
+ </p></dd><dt id="APP-PSQL-META-COMMANDS-CROSSTABVIEW"><span class="term"><code class="literal">\crosstabview [
+ <em class="replaceable"><code>colV</code></em>
+ [ <em class="replaceable"><code>colH</code></em>
+ [ <em class="replaceable"><code>colD</code></em>
+ [ <em class="replaceable"><code>sortcolH</code></em>
+ ] ] ] ] </code></span></dt><dd><p>
+ Executes the current query buffer (like <code class="literal">\g</code>) and
+ shows the results in a crosstab grid.
+ The query must return at least three columns.
+ The output column identified by <em class="replaceable"><code>colV</code></em>
+ becomes a vertical header and the output column identified by
+ <em class="replaceable"><code>colH</code></em>
+ becomes a horizontal header.
+ <em class="replaceable"><code>colD</code></em> identifies
+ the output column to display within the grid.
+ <em class="replaceable"><code>sortcolH</code></em> identifies
+ an optional sort column for the horizontal header.
+ </p><p>
+ Each column specification can be a column number (starting at 1) or
+ a column name. The usual SQL case folding and quoting rules apply to
+ column names. If omitted,
+ <em class="replaceable"><code>colV</code></em> is taken as column 1
+ and <em class="replaceable"><code>colH</code></em> as column 2.
+ <em class="replaceable"><code>colH</code></em> must differ from
+ <em class="replaceable"><code>colV</code></em>.
+ If <em class="replaceable"><code>colD</code></em> is not
+ specified, then there must be exactly three columns in the query
+ result, and the column that is neither
+ <em class="replaceable"><code>colV</code></em> nor
+ <em class="replaceable"><code>colH</code></em>
+ is taken to be <em class="replaceable"><code>colD</code></em>.
+ </p><p>
+ The vertical header, displayed as the leftmost column, contains the
+ values found in column <em class="replaceable"><code>colV</code></em>, in the
+ same order as in the query results, but with duplicates removed.
+ </p><p>
+ The horizontal header, displayed as the first row, contains the values
+ found in column <em class="replaceable"><code>colH</code></em>,
+ with duplicates removed. By default, these appear in the same order
+ as in the query results. But if the
+ optional <em class="replaceable"><code>sortcolH</code></em> argument is given,
+ it identifies a column whose values must be integer numbers, and the
+ values from <em class="replaceable"><code>colH</code></em> will
+ appear in the horizontal header sorted according to the
+ corresponding <em class="replaceable"><code>sortcolH</code></em> values.
+ </p><p>
+ Inside the crosstab grid, for each distinct value <code class="literal">x</code>
+ of <em class="replaceable"><code>colH</code></em> and each distinct
+ value <code class="literal">y</code>
+ of <em class="replaceable"><code>colV</code></em>, the cell located
+ at the intersection <code class="literal">(x,y)</code> contains the value of
+ the <code class="literal">colD</code> column in the query result row for which
+ the value of <em class="replaceable"><code>colH</code></em>
+ is <code class="literal">x</code> and the value
+ of <em class="replaceable"><code>colV</code></em>
+ is <code class="literal">y</code>. If there is no such row, the cell is empty. If
+ there are multiple such rows, an error is reported.
+ </p></dd><dt><span class="term"><code class="literal">\d[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ For each relation (table, view, materialized view, index, sequence,
+ or foreign table)
+ or composite type matching the
+ <em class="replaceable"><code>pattern</code></em>, show all
+ columns, their types, the tablespace (if not the default) and any
+ special attributes such as <code class="literal">NOT NULL</code> or defaults.
+ Associated indexes, constraints, rules, and triggers are
+ also shown. For foreign tables, the associated foreign
+ server is shown as well.
+ (<span class="quote">“<span class="quote">Matching the pattern</span>”</span> is defined in
+ <a class="xref" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns">Patterns</a> below.)
+ </p><p>
+ For some types of relation, <code class="literal">\d</code> shows additional information
+ for each column: column values for sequences, indexed expressions for
+ indexes, and foreign data wrapper options for foreign tables.
+ </p><p>
+ The command form <code class="literal">\d+</code> is identical, except that
+ more information is displayed: any comments associated with the
+ columns of the table are shown, as is the presence of OIDs in the
+ table, the view definition if the relation is a view, a non-default
+ <a class="link" href="sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY">replica
+ identity</a> setting and the
+ <a class="link" href="sql-create-access-method.html" title="CREATE ACCESS METHOD">access method</a> name
+ if the relation has an access method.
+ </p><p>
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If <code class="command">\d</code> is used without a
+ <em class="replaceable"><code>pattern</code></em> argument, it is
+ equivalent to <code class="command">\dtvmsE</code> which will show a list of
+ all visible tables, views, materialized views, sequences and
+ foreign tables.
+ This is purely a convenience measure.
+ </p></div></dd><dt><span class="term"><code class="literal">\da[S] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists aggregate functions, together with their
+ return type and the data types they operate on. If <em class="replaceable"><code>pattern</code></em>
+ is specified, only aggregates whose names match the pattern are shown.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ </p></dd><dt><span class="term"><code class="literal">\dA[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists access methods. If <em class="replaceable"><code>pattern</code></em> is specified, only access
+ methods whose names match the pattern are shown. If
+ <code class="literal">+</code> is appended to the command name, each access
+ method is listed with its associated handler function and description.
+ </p></dd><dt><span class="term">
+ <code class="literal">\dAc[+]
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>access-method-pattern</code></em></a>
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>input-type-pattern</code></em></a>]]
+ </code>
+ </span></dt><dd><p>
+ Lists operator classes
+ (see <a class="xref" href="xindex.html#XINDEX-OPCLASS" title="38.16.1. Index Methods and Operator Classes">Section 38.16.1</a>).
+ If <em class="replaceable"><code>access-method-pattern</code></em>
+ is specified, only operator classes associated with access methods whose
+ names match that pattern are listed.
+ If <em class="replaceable"><code>input-type-pattern</code></em>
+ is specified, only operator classes associated with input types whose
+ names match that pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, each operator
+ class is listed with its associated operator family and owner.
+ </p></dd><dt><span class="term">
+ <code class="literal">\dAf[+]
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>access-method-pattern</code></em></a>
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>input-type-pattern</code></em></a>]]
+ </code>
+ </span></dt><dd><p>
+ Lists operator families
+ (see <a class="xref" href="xindex.html#XINDEX-OPFAMILY" title="38.16.5. Operator Classes and Operator Families">Section 38.16.5</a>).
+ If <em class="replaceable"><code>access-method-pattern</code></em>
+ is specified, only operator families associated with access methods whose
+ names match that pattern are listed.
+ If <em class="replaceable"><code>input-type-pattern</code></em>
+ is specified, only operator families associated with input types whose
+ names match that pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, each operator
+ family is listed with its owner.
+ </p></dd><dt><span class="term">
+ <code class="literal">\dAo[+]
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>access-method-pattern</code></em></a>
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>operator-family-pattern</code></em></a>]]
+ </code>
+ </span></dt><dd><p>
+ Lists operators associated with operator families
+ (see <a class="xref" href="xindex.html#XINDEX-STRATEGIES" title="38.16.2. Index Method Strategies">Section 38.16.2</a>).
+ If <em class="replaceable"><code>access-method-pattern</code></em>
+ is specified, only members of operator families associated with access
+ methods whose names match that pattern are listed.
+ If <em class="replaceable"><code>operator-family-pattern</code></em>
+ is specified, only members of operator families whose names match that
+ pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, each operator
+ is listed with its sort operator family (if it is an ordering operator).
+ </p></dd><dt><span class="term">
+ <code class="literal">\dAp[+]
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>access-method-pattern</code></em></a>
+ [<a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>operator-family-pattern</code></em></a>]]
+ </code>
+ </span></dt><dd><p>
+ Lists support functions associated with operator families
+ (see <a class="xref" href="xindex.html#XINDEX-SUPPORT" title="38.16.3. Index Method Support Routines">Section 38.16.3</a>).
+ If <em class="replaceable"><code>access-method-pattern</code></em>
+ is specified, only functions of operator families associated with
+ access methods whose names match that pattern are listed.
+ If <em class="replaceable"><code>operator-family-pattern</code></em>
+ is specified, only functions of operator families whose names match
+ that pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, functions are
+ displayed verbosely, with their actual parameter lists.
+ </p></dd><dt><span class="term"><code class="literal">\db[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists tablespaces. If <em class="replaceable"><code>pattern</code></em>
+ is specified, only tablespaces whose names match the pattern are shown.
+ If <code class="literal">+</code> is appended to the command name, each tablespace
+ is listed with its associated options, on-disk size, permissions and
+ description.
+ </p></dd><dt><span class="term"><code class="literal">\dc[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists conversions between character-set encodings.
+ If <em class="replaceable"><code>pattern</code></em>
+ is specified, only conversions whose names match the pattern are
+ listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ If <code class="literal">+</code> is appended to the command name, each object
+ is listed with its associated description.
+ </p></dd><dt><span class="term"><code class="literal">\dconfig[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists server configuration parameters and their values.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only parameters whose names match the pattern are listed. Without
+ a <em class="replaceable"><code>pattern</code></em>, only
+ parameters that are set to non-default values are listed.
+ (Use <code class="literal">\dconfig *</code> to see all parameters.)
+ If <code class="literal">+</code> is appended to the command name, each
+ parameter is listed with its data type, context in which the
+ parameter can be set, and access privileges (if non-default access
+ privileges have been granted).
+ </p></dd><dt><span class="term"><code class="literal">\dC[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists type casts.
+ If <em class="replaceable"><code>pattern</code></em>
+ is specified, only casts whose source or target types match the
+ pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, each object
+ is listed with its associated description.
+ </p></dd><dt><span class="term"><code class="literal">\dd[S] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Shows the descriptions of objects of type <code class="literal">constraint</code>,
+ <code class="literal">operator class</code>, <code class="literal">operator family</code>,
+ <code class="literal">rule</code>, and <code class="literal">trigger</code>. All
+ other comments may be viewed by the respective backslash commands for
+ those object types.
+ </p><p><code class="literal">\dd</code> displays descriptions for objects matching the
+ <em class="replaceable"><code>pattern</code></em>, or of visible
+ objects of the appropriate type if no argument is given. But in either
+ case, only objects that have a description are listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ </p><p>
+ Descriptions for objects can be created with the <a class="link" href="sql-comment.html" title="COMMENT"><code class="command">COMMENT</code></a>
+ <acronym class="acronym">SQL</acronym> command.
+ </p></dd><dt><span class="term"><code class="literal">\dD[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists domains. If <em class="replaceable"><code>pattern</code></em>
+ is specified, only domains whose names match the pattern are shown.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ If <code class="literal">+</code> is appended to the command name, each object
+ is listed with its associated permissions and description.
+ </p></dd><dt><span class="term"><code class="literal">\ddp [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists default access privilege settings. An entry is shown for
+ each role (and schema, if applicable) for which the default
+ privilege settings have been changed from the built-in defaults.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only entries whose role name or schema name matches
+ the pattern are listed.
+ </p><p>
+ The <a class="link" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES"><code class="command">ALTER DEFAULT
+ PRIVILEGES</code></a> command is used to set default access
+ privileges. The meaning of the privilege display is explained in
+ <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>.
+ </p></dd><dt><span class="term"><code class="literal">\dE[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code><br /></span><span class="term"><code class="literal">\di[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code><br /></span><span class="term"><code class="literal">\dm[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code><br /></span><span class="term"><code class="literal">\ds[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code><br /></span><span class="term"><code class="literal">\dt[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code><br /></span><span class="term"><code class="literal">\dv[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ In this group of commands, the letters <code class="literal">E</code>,
+ <code class="literal">i</code>, <code class="literal">m</code>, <code class="literal">s</code>,
+ <code class="literal">t</code>, and <code class="literal">v</code>
+ stand for foreign table, index, materialized view,
+ sequence, table, and view,
+ respectively.
+ You can specify any or all of
+ these letters, in any order, to obtain a listing of objects
+ of these types. For example, <code class="literal">\dti</code> lists
+ tables and indexes. If <code class="literal">+</code> is
+ appended to the command name, each object is listed with its
+ persistence status (permanent, temporary, or unlogged),
+ physical size on disk, and associated description if any.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only objects whose names match the pattern are listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ </p></dd><dt><span class="term"><code class="literal">\des[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists foreign servers (mnemonic: <span class="quote">“<span class="quote">external
+ servers</span>”</span>).
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only those servers whose name matches the pattern
+ are listed. If the form <code class="literal">\des+</code> is used, a
+ full description of each server is shown, including the
+ server's access privileges, type, version, options, and description.
+ </p></dd><dt><span class="term"><code class="literal">\det[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists foreign tables (mnemonic: <span class="quote">“<span class="quote">external tables</span>”</span>).
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only entries whose table name or schema name matches
+ the pattern are listed. If the form <code class="literal">\det+</code>
+ is used, generic options and the foreign table description
+ are also displayed.
+ </p></dd><dt><span class="term"><code class="literal">\deu[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists user mappings (mnemonic: <span class="quote">“<span class="quote">external
+ users</span>”</span>).
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only those mappings whose user names match the
+ pattern are listed. If the form <code class="literal">\deu+</code> is
+ used, additional information about each mapping is shown.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ <code class="literal">\deu+</code> might also display the user name and
+ password of the remote user, so care should be taken not to
+ disclose them.
+ </p></div></dd><dt><span class="term"><code class="literal">\dew[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists foreign-data wrappers (mnemonic: <span class="quote">“<span class="quote">external
+ wrappers</span>”</span>).
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only those foreign-data wrappers whose name matches
+ the pattern are listed. If the form <code class="literal">\dew+</code>
+ is used, the access privileges, options, and description of the
+ foreign-data wrapper are also shown.
+ </p></dd><dt><span class="term"><code class="literal">\df[anptwS+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> [ <em class="replaceable"><code>arg_pattern</code></em> ... ] ]</code></span></dt><dd><p>
+ Lists functions, together with their result data types, argument data
+ types, and function types, which are classified as <span class="quote">“<span class="quote">agg</span>”</span>
+ (aggregate), <span class="quote">“<span class="quote">normal</span>”</span>, <span class="quote">“<span class="quote">procedure</span>”</span>, <span class="quote">“<span class="quote">trigger</span>”</span>, or <span class="quote">“<span class="quote">window</span>”</span>.
+ To display only functions
+ of specific type(s), add the corresponding letters <code class="literal">a</code>,
+ <code class="literal">n</code>, <code class="literal">p</code>, <code class="literal">t</code>, or <code class="literal">w</code> to the command.
+ If <em class="replaceable"><code>pattern</code></em> is specified, only
+ functions whose names match the pattern are shown.
+ Any additional arguments are type-name patterns, which are matched
+ to the type names of the first, second, and so on arguments of the
+ function. (Matching functions can have more arguments than what
+ you specify. To prevent that, write a dash <code class="literal">-</code> as
+ the last <em class="replaceable"><code>arg_pattern</code></em>.)
+ By default, only user-created
+ objects are shown; supply a pattern or the <code class="literal">S</code>
+ modifier to include system objects.
+ If the form <code class="literal">\df+</code> is used, additional information
+ about each function is shown, including volatility,
+ parallel safety, owner, security classification, access privileges,
+ language, source code and description.
+ </p></dd><dt><span class="term"><code class="literal">\dF[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists text search configurations.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only configurations whose names match the pattern are shown.
+ If the form <code class="literal">\dF+</code> is used, a full description of
+ each configuration is shown, including the underlying text search
+ parser and the dictionary list for each parser token type.
+ </p></dd><dt><span class="term"><code class="literal">\dFd[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists text search dictionaries.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only dictionaries whose names match the pattern are shown.
+ If the form <code class="literal">\dFd+</code> is used, additional information
+ is shown about each selected dictionary, including the underlying
+ text search template and the option values.
+ </p></dd><dt><span class="term"><code class="literal">\dFp[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists text search parsers.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only parsers whose names match the pattern are shown.
+ If the form <code class="literal">\dFp+</code> is used, a full description of
+ each parser is shown, including the underlying functions and the
+ list of recognized token types.
+ </p></dd><dt><span class="term"><code class="literal">\dFt[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists text search templates.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only templates whose names match the pattern are shown.
+ If the form <code class="literal">\dFt+</code> is used, additional information
+ is shown about each template, including the underlying function names.
+ </p></dd><dt><span class="term"><code class="literal">\dg[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists database roles.
+ (Since the concepts of <span class="quote">“<span class="quote">users</span>”</span> and <span class="quote">“<span class="quote">groups</span>”</span> have been
+ unified into <span class="quote">“<span class="quote">roles</span>”</span>, this command is now equivalent to
+ <code class="literal">\du</code>.)
+ By default, only user-created roles are shown; supply the
+ <code class="literal">S</code> modifier to include system roles.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only those roles whose names match the pattern are listed.
+ If the form <code class="literal">\dg+</code> is used, additional information
+ is shown about each role; currently this adds the comment for each
+ role.
+ </p></dd><dt><span class="term"><code class="literal">\dl[+]</code></span></dt><dd><p>
+ This is an alias for <code class="command">\lo_list</code>, which shows a
+ list of large objects.
+ If <code class="literal">+</code> is appended to the command name,
+ each large object is listed with its associated permissions,
+ if any.
+ </p></dd><dt><span class="term"><code class="literal">\dL[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists procedural languages. If <em class="replaceable"><code>pattern</code></em>
+ is specified, only languages whose names match the pattern are listed.
+ By default, only user-created languages
+ are shown; supply the <code class="literal">S</code> modifier to include system
+ objects. If <code class="literal">+</code> is appended to the command name, each
+ language is listed with its call handler, validator, access privileges,
+ and whether it is a system object.
+ </p></dd><dt><span class="term"><code class="literal">\dn[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists schemas (namespaces). If <em class="replaceable"><code>pattern</code></em>
+ is specified, only schemas whose names match the pattern are listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system objects.
+ If <code class="literal">+</code> is appended to the command name, each object
+ is listed with its associated permissions and description, if any.
+ </p></dd><dt><span class="term"><code class="literal">\do[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> [ <em class="replaceable"><code>arg_pattern</code></em> [ <em class="replaceable"><code>arg_pattern</code></em> ] ] ]</code></span></dt><dd><p>
+ Lists operators with their operand and result types.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only operators whose names match the pattern are listed.
+ If one <em class="replaceable"><code>arg_pattern</code></em> is
+ specified, only prefix operators whose right argument's type name
+ matches that pattern are listed.
+ If two <em class="replaceable"><code>arg_pattern</code></em>s
+ are specified, only binary operators whose argument type names match
+ those patterns are listed. (Alternatively, write <code class="literal">-</code>
+ for the unused argument of a unary operator.)
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ If <code class="literal">+</code> is appended to the command name,
+ additional information about each operator is shown, currently just
+ the name of the underlying function.
+ </p></dd><dt><span class="term"><code class="literal">\dO[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists collations.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only collations whose names match the pattern are
+ listed. By default, only user-created objects are shown;
+ supply a pattern or the <code class="literal">S</code> modifier to
+ include system objects. If <code class="literal">+</code> is appended
+ to the command name, each collation is listed with its associated
+ description, if any.
+ Note that only collations usable with the current database's encoding
+ are shown, so the results may vary in different databases of the
+ same installation.
+ </p></dd><dt><span class="term"><code class="literal">\dp [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists tables, views and sequences with their
+ associated access privileges.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only tables, views and sequences whose names match the
+ pattern are listed.
+ </p><p>
+ The <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> and
+ <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a>
+ commands are used to set access privileges. The meaning of the
+ privilege display is explained in
+ <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>.
+ </p></dd><dt><span class="term"><code class="literal">\dP[itn+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists partitioned relations.
+ If <em class="replaceable"><code>pattern</code></em>
+ is specified, only entries whose name matches the pattern are listed.
+ The modifiers <code class="literal">t</code> (tables) and <code class="literal">i</code>
+ (indexes) can be appended to the command, filtering the kind of
+ relations to list. By default, partitioned tables and indexes are
+ listed.
+ </p><p>
+ If the modifier <code class="literal">n</code> (<span class="quote">“<span class="quote">nested</span>”</span>) is used,
+ or a pattern is specified, then non-root partitioned relations are
+ included, and a column is shown displaying the parent of each
+ partitioned relation.
+ </p><p>
+ If <code class="literal">+</code> is appended to the command name, the sum of the
+ sizes of each relation's partitions is also displayed, along with the
+ relation's description.
+ If <code class="literal">n</code> is combined with <code class="literal">+</code>, two
+ sizes are shown: one including the total size of directly-attached
+ leaf partitions, and another showing the total size of all partitions,
+ including indirectly attached sub-partitions.
+ </p></dd><dt><span class="term"><code class="literal">\drds [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>role-pattern</code></em></a> [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>database-pattern</code></em></a> ] ]</code></span></dt><dd><p>
+ Lists defined configuration settings. These settings can be
+ role-specific, database-specific, or both.
+ <em class="replaceable"><code>role-pattern</code></em> and
+ <em class="replaceable"><code>database-pattern</code></em> are used to select
+ specific roles and databases to list, respectively. If omitted, or if
+ <code class="literal">*</code> is specified, all settings are listed, including those
+ not role-specific or database-specific, respectively.
+ </p><p>
+ The <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a> and
+ <a class="link" href="sql-alterdatabase.html" title="ALTER DATABASE"><code class="command">ALTER DATABASE</code></a>
+ commands are used to define per-role and per-database configuration
+ settings.
+ </p></dd><dt><span class="term"><code class="literal">\dRp[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists replication publications.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only those publications whose names match the pattern are
+ listed.
+ If <code class="literal">+</code> is appended to the command name, the tables and
+ schemas associated with each publication are shown as well.
+ </p></dd><dt><span class="term"><code class="literal">\dRs[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists replication subscriptions.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only those subscriptions whose names match the pattern are
+ listed.
+ If <code class="literal">+</code> is appended to the command name, additional
+ properties of the subscriptions are shown.
+ </p></dd><dt><span class="term"><code class="literal">\dT[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists data types.
+ If <em class="replaceable"><code>pattern</code></em> is
+ specified, only types whose names match the pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, each type is
+ listed with its internal name and size, its allowed values
+ if it is an <code class="type">enum</code> type, and its associated permissions.
+ By default, only user-created objects are shown; supply a
+ pattern or the <code class="literal">S</code> modifier to include system
+ objects.
+ </p></dd><dt><span class="term"><code class="literal">\du[S+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists database roles.
+ (Since the concepts of <span class="quote">“<span class="quote">users</span>”</span> and <span class="quote">“<span class="quote">groups</span>”</span> have been
+ unified into <span class="quote">“<span class="quote">roles</span>”</span>, this command is now equivalent to
+ <code class="literal">\dg</code>.)
+ By default, only user-created roles are shown; supply the
+ <code class="literal">S</code> modifier to include system roles.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only those roles whose names match the pattern are listed.
+ If the form <code class="literal">\du+</code> is used, additional information
+ is shown about each role; currently this adds the comment for each
+ role.
+ </p></dd><dt><span class="term"><code class="literal">\dx[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists installed extensions.
+ If <em class="replaceable"><code>pattern</code></em>
+ is specified, only those extensions whose names match the pattern
+ are listed.
+ If the form <code class="literal">\dx+</code> is used, all the objects belonging
+ to each matching extension are listed.
+ </p></dd><dt><span class="term"><code class="literal">\dX [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists extended statistics.
+ If <em class="replaceable"><code>pattern</code></em>
+ is specified, only those extended statistics whose names match the
+ pattern are listed.
+ </p><p>
+ The status of each kind of extended statistics is shown in a column
+ named after its statistic kind (e.g. Ndistinct).
+ <code class="literal">defined</code> means that it was requested when creating
+ the statistics, and NULL means it wasn't requested.
+ You can use <code class="structname">pg_stats_ext</code> if you'd like to
+ know whether <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>
+ was run and statistics are available to the planner.
+ </p></dd><dt><span class="term"><code class="literal">\dy[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists event triggers.
+ If <em class="replaceable"><code>pattern</code></em>
+ is specified, only those event triggers whose names match the pattern
+ are listed.
+ If <code class="literal">+</code> is appended to the command name, each object
+ is listed with its associated description.
+ </p></dd><dt><span class="term"><code class="literal">\e</code> or <code class="literal">\edit</code> <code class="literal"> [<span class="optional"> <em class="replaceable"><code>filename</code></em> </span>] [<span class="optional"> <em class="replaceable"><code>line_number</code></em> </span>] </code></span></dt><dd><p>
+ If <em class="replaceable"><code>filename</code></em> is
+ specified, the file is edited; after the editor exits, the file's
+ content is copied into the current query buffer. If no <em class="replaceable"><code>filename</code></em> is given, the current query
+ buffer is copied to a temporary file which is then edited in the same
+ fashion. Or, if the current query buffer is empty, the most recently
+ executed query is copied to a temporary file and edited in the same
+ fashion.
+ </p><p>
+ If you edit a file or the previous query, and you quit the editor without
+ modifying the file, the query buffer is cleared.
+ Otherwise, the new contents of the query buffer are re-parsed according to
+ the normal rules of <span class="application">psql</span>, treating the
+ whole buffer as a single line. Any complete queries are immediately
+ executed; that is, if the query buffer contains or ends with a
+ semicolon, everything up to that point is executed and removed from
+ the query buffer. Whatever remains in the query buffer is
+ redisplayed. Type semicolon or <code class="literal">\g</code> to send it,
+ or <code class="literal">\r</code> to cancel it by clearing the query buffer.
+ </p><p>
+ Treating the buffer as a single line primarily affects meta-commands:
+ whatever is in the buffer after a meta-command will be taken as
+ argument(s) to the meta-command, even if it spans multiple lines.
+ (Thus you cannot make meta-command-using scripts this way.
+ Use <code class="command">\i</code> for that.)
+ </p><p>
+ If a line number is specified, <span class="application">psql</span> will
+ position the cursor on the specified line of the file or query buffer.
+ Note that if a single all-digits argument is given,
+ <span class="application">psql</span> assumes it is a line number,
+ not a file name.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ See <a class="xref" href="app-psql.html#APP-PSQL-ENVIRONMENT" title="Environment">Environment</a>, below, for how to
+ configure and customize your editor.
+ </p></div></dd><dt><span class="term"><code class="literal">\echo <em class="replaceable"><code>text</code></em> [ ... ]</code></span></dt><dd><p>
+ Prints the evaluated arguments to standard output, separated by
+ spaces and followed by a newline. This can be useful to
+ intersperse information in the output of scripts. For example:
+</p><pre class="programlisting">
+=&gt; <strong class="userinput"><code>\echo `date`</code></strong>
+Tue Oct 26 21:40:57 CEST 1999
+</pre><p>
+ If the first argument is an unquoted <code class="literal">-n</code> the trailing
+ newline is not written (nor is the first argument).
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If you use the <code class="command">\o</code> command to redirect your
+ query output you might wish to use <code class="command">\qecho</code>
+ instead of this command. See also <code class="command">\warn</code>.
+ </p></div></dd><dt><span class="term"><code class="literal">\ef [<span class="optional"> <em class="replaceable"><code>function_description</code></em> [<span class="optional"> <em class="replaceable"><code>line_number</code></em> </span>] </span>] </code></span></dt><dd><p>
+ This command fetches and edits the definition of the named function or procedure,
+ in the form of a <code class="command">CREATE OR REPLACE FUNCTION</code> or
+ <code class="command">CREATE OR REPLACE PROCEDURE</code> command.
+ Editing is done in the same way as for <code class="literal">\edit</code>.
+ If you quit the editor without saving, the statement is discarded.
+ If you save and exit the editor, the updated command is executed immediately
+ if you added a semicolon to it. Otherwise it is redisplayed;
+ type semicolon or <code class="literal">\g</code> to send it, or <code class="literal">\r</code>
+ to cancel.
+ </p><p>
+ The target function can be specified by name alone, or by name
+ and arguments, for example <code class="literal">foo(integer, text)</code>.
+ The argument types must be given if there is more
+ than one function of the same name.
+ </p><p>
+ If no function is specified, a blank <code class="command">CREATE FUNCTION</code>
+ template is presented for editing.
+ </p><p>
+ If a line number is specified, <span class="application">psql</span> will
+ position the cursor on the specified line of the function body.
+ (Note that the function body typically does not begin on the first
+ line of the file.)
+ </p><p>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <code class="command">\ef</code>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ See <a class="xref" href="app-psql.html#APP-PSQL-ENVIRONMENT" title="Environment">Environment</a>, below, for how to
+ configure and customize your editor.
+ </p></div></dd><dt><span class="term"><code class="literal">\encoding [ <em class="replaceable"><code>encoding</code></em> ]</code></span></dt><dd><p>
+ Sets the client character set encoding. Without an argument, this command
+ shows the current encoding.
+ </p></dd><dt><span class="term"><code class="literal">\errverbose</code></span></dt><dd><p>
+ Repeats the most recent server error message at maximum
+ verbosity, as though <code class="varname">VERBOSITY</code> were set
+ to <code class="literal">verbose</code> and <code class="varname">SHOW_CONTEXT</code> were
+ set to <code class="literal">always</code>.
+ </p></dd><dt><span class="term"><code class="literal">\ev [<span class="optional"> <em class="replaceable"><code>view_name</code></em> [<span class="optional"> <em class="replaceable"><code>line_number</code></em> </span>] </span>] </code></span></dt><dd><p>
+ This command fetches and edits the definition of the named view,
+ in the form of a <code class="command">CREATE OR REPLACE VIEW</code> command.
+ Editing is done in the same way as for <code class="literal">\edit</code>.
+ If you quit the editor without saving, the statement is discarded.
+ If you save and exit the editor, the updated command is executed immediately
+ if you added a semicolon to it. Otherwise it is redisplayed;
+ type semicolon or <code class="literal">\g</code> to send it, or <code class="literal">\r</code>
+ to cancel.
+ </p><p>
+ If no view is specified, a blank <code class="command">CREATE VIEW</code>
+ template is presented for editing.
+ </p><p>
+ If a line number is specified, <span class="application">psql</span> will
+ position the cursor on the specified line of the view definition.
+ </p><p>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <code class="command">\ev</code>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </p></dd><dt><span class="term"><code class="literal">\f [ <em class="replaceable"><code>string</code></em> ]</code></span></dt><dd><p>
+ Sets the field separator for unaligned query output. The default
+ is the vertical bar (<code class="literal">|</code>). It is equivalent to
+ <code class="command">\pset fieldsep</code>.
+ </p></dd><dt><span class="term"><code class="literal">\g [ (<em class="replaceable"><code>option</code></em>=<em class="replaceable"><code>value</code></em> [...]) ] [ <em class="replaceable"><code>filename</code></em> ]</code><br /></span><span class="term"><code class="literal">\g [ (<em class="replaceable"><code>option</code></em>=<em class="replaceable"><code>value</code></em> [...]) ] [ |<em class="replaceable"><code>command</code></em> ]</code></span></dt><dd><p>
+ Sends the current query buffer to the server for execution.
+ </p><p>
+ If parentheses appear after <code class="literal">\g</code>, they surround a
+ space-separated list
+ of <em class="replaceable"><code>option</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em>
+ formatting-option clauses, which are interpreted in the same way
+ as <code class="literal">\pset</code>
+ <em class="replaceable"><code>option</code></em>
+ <em class="replaceable"><code>value</code></em> commands, but take
+ effect only for the duration of this query. In this list, spaces are
+ not allowed around <code class="literal">=</code> signs, but are required
+ between option clauses.
+ If <code class="literal">=</code><em class="replaceable"><code>value</code></em>
+ is omitted, the
+ named <em class="replaceable"><code>option</code></em> is changed
+ in the same way as for
+ <code class="literal">\pset</code> <em class="replaceable"><code>option</code></em>
+ with no explicit <em class="replaceable"><code>value</code></em>.
+ </p><p>
+ If a <em class="replaceable"><code>filename</code></em>
+ or <code class="literal">|</code><em class="replaceable"><code>command</code></em>
+ argument is given, the query's output is written to the named
+ file or piped to the given shell command, instead of displaying it as
+ usual. The file or command is written to only if the query
+ successfully returns zero or more tuples, not if the query fails or
+ is a non-data-returning SQL command.
+ </p><p>
+ If the current query buffer is empty, the most recently sent query is
+ re-executed instead. Except for that behavior, <code class="literal">\g</code>
+ without any arguments is essentially equivalent to a semicolon.
+ With arguments, <code class="literal">\g</code> provides
+ a <span class="quote">“<span class="quote">one-shot</span>”</span> alternative to the <code class="command">\o</code>
+ command, and additionally allows one-shot adjustments of the
+ output formatting options normally set by <code class="literal">\pset</code>.
+ </p><p>
+ When the last argument begins with <code class="literal">|</code>, the entire
+ remainder of the line is taken to be
+ the <em class="replaceable"><code>command</code></em> to execute,
+ and neither variable interpolation nor backquote expansion are
+ performed in it. The rest of the line is simply passed literally to
+ the shell.
+ </p></dd><dt><span class="term"><code class="literal">\gdesc</code></span></dt><dd><p>
+ Shows the description (that is, the column names and data types)
+ of the result of the current query buffer. The query is not
+ actually executed; however, if it contains some type of syntax
+ error, that error will be reported in the normal way.
+ </p><p>
+ If the current query buffer is empty, the most recently sent query
+ is described instead.
+ </p></dd><dt><span class="term"><code class="literal">\getenv <em class="replaceable"><code>psql_var</code></em> <em class="replaceable"><code>env_var</code></em></code></span></dt><dd><p>
+ Gets the value of the environment
+ variable <em class="replaceable"><code>env_var</code></em>
+ and assigns it to the <span class="application">psql</span>
+ variable <em class="replaceable"><code>psql_var</code></em>.
+ If <em class="replaceable"><code>env_var</code></em> is
+ not defined in the <span class="application">psql</span> process's
+ environment, <em class="replaceable"><code>psql_var</code></em>
+ is not changed. Example:
+</p><pre class="programlisting">
+=&gt; <strong class="userinput"><code>\getenv home HOME</code></strong>
+=&gt; <strong class="userinput"><code>\echo :home</code></strong>
+/home/postgres
+</pre></dd><dt><span class="term"><code class="literal">\gexec</code></span></dt><dd><p>
+ Sends the current query buffer to the server, then treats
+ each column of each row of the query's output (if any) as an SQL
+ statement to be executed. For example, to create an index on each
+ column of <code class="structname">my_table</code>:
+</p><pre class="programlisting">
+=&gt; <strong class="userinput"><code>SELECT format('create index on my_table(%I)', attname)</code></strong>
+-&gt; <strong class="userinput"><code>FROM pg_attribute</code></strong>
+-&gt; <strong class="userinput"><code>WHERE attrelid = 'my_table'::regclass AND attnum &gt; 0</code></strong>
+-&gt; <strong class="userinput"><code>ORDER BY attnum</code></strong>
+-&gt; <strong class="userinput"><code>\gexec</code></strong>
+CREATE INDEX
+CREATE INDEX
+CREATE INDEX
+CREATE INDEX
+</pre><p>
+ </p><p>
+ The generated queries are executed in the order in which the rows
+ are returned, and left-to-right within each row if there is more
+ than one column. NULL fields are ignored. The generated queries
+ are sent literally to the server for processing, so they cannot be
+ <span class="application">psql</span> meta-commands nor contain <span class="application">psql</span>
+ variable references. If any individual query fails, execution of
+ the remaining queries continues
+ unless <code class="varname">ON_ERROR_STOP</code> is set. Execution of each
+ query is subject to <code class="varname">ECHO</code> processing.
+ (Setting <code class="varname">ECHO</code> to <code class="literal">all</code>
+ or <code class="literal">queries</code> is often advisable when
+ using <code class="command">\gexec</code>.) Query logging, single-step mode,
+ timing, and other query execution features apply to each generated
+ query as well.
+ </p><p>
+ If the current query buffer is empty, the most recently sent query
+ is re-executed instead.
+ </p></dd><dt><span class="term"><code class="literal">\gset [ <em class="replaceable"><code>prefix</code></em> ]</code></span></dt><dd><p>
+ Sends the current query buffer to the server and stores the
+ query's output into <span class="application">psql</span> variables
+ (see <a class="xref" href="app-psql.html#APP-PSQL-VARIABLES" title="Variables">Variables</a> below).
+ The query to be executed must return exactly one row. Each column of
+ the row is stored into a separate variable, named the same as the
+ column. For example:
+</p><pre class="programlisting">
+=&gt; <strong class="userinput"><code>SELECT 'hello' AS var1, 10 AS var2</code></strong>
+-&gt; <strong class="userinput"><code>\gset</code></strong>
+=&gt; <strong class="userinput"><code>\echo :var1 :var2</code></strong>
+hello 10
+</pre><p>
+ </p><p>
+ If you specify a <em class="replaceable"><code>prefix</code></em>,
+ that string is prepended to the query's column names to create the
+ variable names to use:
+</p><pre class="programlisting">
+=&gt; <strong class="userinput"><code>SELECT 'hello' AS var1, 10 AS var2</code></strong>
+-&gt; <strong class="userinput"><code>\gset result_</code></strong>
+=&gt; <strong class="userinput"><code>\echo :result_var1 :result_var2</code></strong>
+hello 10
+</pre><p>
+ </p><p>
+ If a column result is NULL, the corresponding variable is unset
+ rather than being set.
+ </p><p>
+ If the query fails or does not return one row,
+ no variables are changed.
+ </p><p>
+ If the current query buffer is empty, the most recently sent query
+ is re-executed instead.
+ </p></dd><dt><span class="term"><code class="literal">\gx [ (<em class="replaceable"><code>option</code></em>=<em class="replaceable"><code>value</code></em> [...]) ] [ <em class="replaceable"><code>filename</code></em> ]</code><br /></span><span class="term"><code class="literal">\gx [ (<em class="replaceable"><code>option</code></em>=<em class="replaceable"><code>value</code></em> [...]) ] [ |<em class="replaceable"><code>command</code></em> ]</code></span></dt><dd><p>
+ <code class="literal">\gx</code> is equivalent to <code class="literal">\g</code>, except
+ that it forces expanded output mode for this query, as
+ if <code class="literal">expanded=on</code> were included in the list of
+ <code class="literal">\pset</code> options. See also <code class="literal">\x</code>.
+ </p></dd><dt><span class="term"><code class="literal">\h</code> or <code class="literal">\help</code> <code class="literal">[ <em class="replaceable"><code>command</code></em> ]</code></span></dt><dd><p>
+ Gives syntax help on the specified <acronym class="acronym">SQL</acronym>
+ command. If <em class="replaceable"><code>command</code></em>
+ is not specified, then <span class="application">psql</span> will list
+ all the commands for which syntax help is available. If
+ <em class="replaceable"><code>command</code></em> is an
+ asterisk (<code class="literal">*</code>), then syntax help on all
+ <acronym class="acronym">SQL</acronym> commands is shown.
+ </p><p>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <code class="command">\help</code>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ To simplify typing, commands that consists of several words do
+ not have to be quoted. Thus it is fine to type <strong class="userinput"><code>\help
+ alter table</code></strong>.
+ </p></div></dd><dt><span class="term"><code class="literal">\H</code> or <code class="literal">\html</code></span></dt><dd><p>
+ Turns on <acronym class="acronym">HTML</acronym> query output format. If the
+ <acronym class="acronym">HTML</acronym> format is already on, it is switched
+ back to the default aligned text format. This command is for
+ compatibility and convenience, but see <code class="command">\pset</code>
+ about setting other output options.
+ </p></dd><dt><span class="term"><code class="literal">\i</code> or <code class="literal">\include</code> <em class="replaceable"><code>filename</code></em></span></dt><dd><p>
+ Reads input from the file <em class="replaceable"><code>filename</code></em> and executes it as
+ though it had been typed on the keyboard.
+ </p><p>
+ If <em class="replaceable"><code>filename</code></em> is <code class="literal">-</code>
+ (hyphen), then standard input is read until an EOF indication
+ or <code class="command">\q</code> meta-command. This can be used to intersperse
+ interactive input with input from files. Note that Readline behavior
+ will be used only if it is active at the outermost level.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If you want to see the lines on the screen as they are read you
+ must set the variable <code class="varname">ECHO</code> to
+ <code class="literal">all</code>.
+ </p></div></dd><dt id="PSQL-METACOMMAND-IF"><span class="term"><code class="literal">\if</code> <em class="replaceable"><code>expression</code></em><br /></span><span class="term"><code class="literal">\elif</code> <em class="replaceable"><code>expression</code></em><br /></span><span class="term"><code class="literal">\else</code><br /></span><span class="term"><code class="literal">\endif</code></span></dt><dd><p>
+ This group of commands implements nestable conditional blocks.
+ A conditional block must begin with an <code class="command">\if</code> and end
+ with an <code class="command">\endif</code>. In between there may be any number
+ of <code class="command">\elif</code> clauses, which may optionally be followed
+ by a single <code class="command">\else</code> clause. Ordinary queries and
+ other types of backslash commands may (and usually do) appear between
+ the commands forming a conditional block.
+ </p><p>
+ The <code class="command">\if</code> and <code class="command">\elif</code> commands read
+ their argument(s) and evaluate them as a Boolean expression. If the
+ expression yields <code class="literal">true</code> then processing continues
+ normally; otherwise, lines are skipped until a
+ matching <code class="command">\elif</code>, <code class="command">\else</code>,
+ or <code class="command">\endif</code> is reached. Once
+ an <code class="command">\if</code> or <code class="command">\elif</code> test has
+ succeeded, the arguments of later <code class="command">\elif</code> commands in
+ the same block are not evaluated but are treated as false. Lines
+ following an <code class="command">\else</code> are processed only if no earlier
+ matching <code class="command">\if</code> or <code class="command">\elif</code> succeeded.
+ </p><p>
+ The <em class="replaceable"><code>expression</code></em> argument
+ of an <code class="command">\if</code> or <code class="command">\elif</code> command
+ is subject to variable interpolation and backquote expansion, just
+ like any other backslash command argument. After that it is evaluated
+ like the value of an on/off option variable. So a valid value
+ is any unambiguous case-insensitive match for one of:
+ <code class="literal">true</code>, <code class="literal">false</code>, <code class="literal">1</code>,
+ <code class="literal">0</code>, <code class="literal">on</code>, <code class="literal">off</code>,
+ <code class="literal">yes</code>, <code class="literal">no</code>. For example,
+ <code class="literal">t</code>, <code class="literal">T</code>, and <code class="literal">tR</code>
+ will all be considered to be <code class="literal">true</code>.
+ </p><p>
+ Expressions that do not properly evaluate to true or false will
+ generate a warning and be treated as false.
+ </p><p>
+ Lines being skipped are parsed normally to identify queries and
+ backslash commands, but queries are not sent to the server, and
+ backslash commands other than conditionals
+ (<code class="command">\if</code>, <code class="command">\elif</code>,
+ <code class="command">\else</code>, <code class="command">\endif</code>) are
+ ignored. Conditional commands are checked only for valid nesting.
+ Variable references in skipped lines are not expanded, and backquote
+ expansion is not performed either.
+ </p><p>
+ All the backslash commands of a given conditional block must appear in
+ the same source file. If EOF is reached on the main input file or an
+ <code class="command">\include</code>-ed file before all local
+ <code class="command">\if</code>-blocks have been closed,
+ then <span class="application">psql</span> will raise an error.
+ </p><p>
+ Here is an example:
+ </p><pre class="programlisting">
+-- check for the existence of two separate records in the database and store
+-- the results in separate psql variables
+SELECT
+ EXISTS(SELECT 1 FROM customer WHERE customer_id = 123) as is_customer,
+ EXISTS(SELECT 1 FROM employee WHERE employee_id = 456) as is_employee
+\gset
+\if :is_customer
+ SELECT * FROM customer WHERE customer_id = 123;
+\elif :is_employee
+ \echo 'is not a customer but is an employee'
+ SELECT * FROM employee WHERE employee_id = 456;
+\else
+ \if yes
+ \echo 'not a customer or employee'
+ \else
+ \echo 'this will never print'
+ \endif
+\endif
+</pre></dd><dt><span class="term"><code class="literal">\ir</code> or <code class="literal">\include_relative</code> <em class="replaceable"><code>filename</code></em></span></dt><dd><p>
+ The <code class="literal">\ir</code> command is similar to <code class="literal">\i</code>, but resolves
+ relative file names differently. When executing in interactive mode,
+ the two commands behave identically. However, when invoked from a
+ script, <code class="literal">\ir</code> interprets file names relative to the
+ directory in which the script is located, rather than the current
+ working directory.
+ </p></dd><dt><span class="term"><code class="literal">\l[+]</code> or <code class="literal">\list[+] [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ List the databases in the server and show their names, owners,
+ character set encodings, and access privileges.
+ If <em class="replaceable"><code>pattern</code></em> is specified,
+ only databases whose names match the pattern are listed.
+ If <code class="literal">+</code> is appended to the command name, database
+ sizes, default tablespaces, and descriptions are also displayed.
+ (Size information is only available for databases that the current
+ user can connect to.)
+ </p></dd><dt><span class="term"><code class="literal">\lo_export <em class="replaceable"><code>loid</code></em> <em class="replaceable"><code>filename</code></em></code></span></dt><dd><p>
+ Reads the large object with <acronym class="acronym">OID</acronym> <em class="replaceable"><code>loid</code></em> from the database and
+ writes it to <em class="replaceable"><code>filename</code></em>. Note that this is
+ subtly different from the server function
+ <code class="function">lo_export</code>, which acts with the permissions
+ of the user that the database server runs as and on the server's
+ file system.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Use <code class="command">\lo_list</code> to find out the large object's
+ <acronym class="acronym">OID</acronym>.
+ </p></div></dd><dt><span class="term"><code class="literal">\lo_import <em class="replaceable"><code>filename</code></em> [ <em class="replaceable"><code>comment</code></em> ]</code></span></dt><dd><p>
+ Stores the file into a <span class="productname">PostgreSQL</span>
+ large object. Optionally, it associates the given
+ comment with the object. Example:
+</p><pre class="programlisting">
+foo=&gt; <strong class="userinput"><code>\lo_import '/home/peter/pictures/photo.xcf' 'a picture of me'</code></strong>
+lo_import 152801
+</pre><p>
+ The response indicates that the large object received object
+ ID 152801, which can be used to access the newly-created large
+ object in the future. For the sake of readability, it is
+ recommended to always associate a human-readable comment with
+ every object. Both OIDs and comments can be viewed with the
+ <code class="command">\lo_list</code> command.
+ </p><p>
+ Note that this command is subtly different from the server-side
+ <code class="function">lo_import</code> because it acts as the local user
+ on the local file system, rather than the server's user and file
+ system.
+ </p></dd><dt><span class="term"><code class="literal">\lo_list[+]</code></span></dt><dd><p>
+ Shows a list of all <span class="productname">PostgreSQL</span>
+ large objects currently stored in the database,
+ along with any comments provided for them.
+ If <code class="literal">+</code> is appended to the command name,
+ each large object is listed with its associated permissions,
+ if any.
+ </p></dd><dt><span class="term"><code class="literal">\lo_unlink <em class="replaceable"><code>loid</code></em></code></span></dt><dd><p>
+ Deletes the large object with <acronym class="acronym">OID</acronym>
+ <em class="replaceable"><code>loid</code></em> from the
+ database.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Use <code class="command">\lo_list</code> to find out the large object's
+ <acronym class="acronym">OID</acronym>.
+ </p></div></dd><dt><span class="term"><code class="literal">\o</code> or <code class="literal">\out [ <em class="replaceable"><code>filename</code></em> ]</code><br /></span><span class="term"><code class="literal">\o</code> or <code class="literal">\out [ |<em class="replaceable"><code>command</code></em> ]</code></span></dt><dd><p>
+ Arranges to save future query results to the file <em class="replaceable"><code>filename</code></em> or pipe future results
+ to the shell command <em class="replaceable"><code>command</code></em>. If no argument is
+ specified, the query output is reset to the standard output.
+ </p><p>
+ If the argument begins with <code class="literal">|</code>, then the entire remainder
+ of the line is taken to be
+ the <em class="replaceable"><code>command</code></em> to execute,
+ and neither variable interpolation nor backquote expansion are
+ performed in it. The rest of the line is simply passed literally to
+ the shell.
+ </p><p>
+ <span class="quote">“<span class="quote">Query results</span>”</span> includes all tables, command
+ responses, and notices obtained from the database server, as
+ well as output of various backslash commands that query the
+ database (such as <code class="command">\d</code>); but not error
+ messages.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ To intersperse text output in between query results, use
+ <code class="command">\qecho</code>.
+ </p></div></dd><dt><span class="term"><code class="literal">\p</code> or <code class="literal">\print</code></span></dt><dd><p>
+ Print the current query buffer to the standard output.
+ If the current query buffer is empty, the most recently executed query
+ is printed instead.
+ </p></dd><dt><span class="term"><code class="literal">\password [ <em class="replaceable"><code>username</code></em> ]</code></span></dt><dd><p>
+ Changes the password of the specified user (by default, the current
+ user). This command prompts for the new password, encrypts it, and
+ sends it to the server as an <code class="command">ALTER ROLE</code> command. This
+ makes sure that the new password does not appear in cleartext in the
+ command history, the server log, or elsewhere.
+ </p></dd><dt><span class="term"><code class="literal">\prompt [ <em class="replaceable"><code>text</code></em> ] <em class="replaceable"><code>name</code></em></code></span></dt><dd><p>
+ Prompts the user to supply text, which is assigned to the variable
+ <em class="replaceable"><code>name</code></em>.
+ An optional prompt string, <em class="replaceable"><code>text</code></em>, can be specified. (For multiword
+ prompts, surround the text with single quotes.)
+ </p><p>
+ By default, <code class="literal">\prompt</code> uses the terminal for input and
+ output. However, if the <code class="option">-f</code> command line switch was
+ used, <code class="literal">\prompt</code> uses standard input and standard output.
+ </p></dd><dt><span class="term"><code class="literal">\pset [ <em class="replaceable"><code>option</code></em> [ <em class="replaceable"><code>value</code></em> ] ]</code></span></dt><dd><p>
+ This command sets options affecting the output of query result tables.
+ <em class="replaceable"><code>option</code></em>
+ indicates which option is to be set. The semantics of
+ <em class="replaceable"><code>value</code></em> vary depending
+ on the selected option. For some options, omitting <em class="replaceable"><code>value</code></em> causes the option to be toggled
+ or unset, as described under the particular option. If no such
+ behavior is mentioned, then omitting
+ <em class="replaceable"><code>value</code></em> just results in
+ the current setting being displayed.
+ </p><p>
+ <code class="command">\pset</code> without any arguments displays the current status
+ of all printing options.
+ </p><p>
+ Adjustable printing options are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">border</code></span></dt><dd><p>
+ The <em class="replaceable"><code>value</code></em> must be a
+ number. In general, the higher
+ the number the more borders and lines the tables will have,
+ but details depend on the particular format.
+ In <acronym class="acronym">HTML</acronym> format, this will translate directly
+ into the <code class="literal">border=...</code> attribute.
+ In most other formats only values 0 (no border), 1 (internal
+ dividing lines), and 2 (table frame) make sense, and values above 2
+ will be treated the same as <code class="literal">border = 2</code>.
+ The <code class="literal">latex</code> and <code class="literal">latex-longtable</code>
+ formats additionally allow a value of 3 to add dividing lines
+ between data rows.
+ </p></dd><dt><span class="term"><code class="literal">columns</code></span></dt><dd><p>
+ Sets the target width for the <code class="literal">wrapped</code> format, and also
+ the width limit for determining whether output is wide enough to
+ require the pager or switch to the vertical display in expanded auto
+ mode.
+ Zero (the default) causes the target width to be controlled by the
+ environment variable <code class="envar">COLUMNS</code>, or the detected screen width
+ if <code class="envar">COLUMNS</code> is not set.
+ In addition, if <code class="literal">columns</code> is zero then the
+ <code class="literal">wrapped</code> format only affects screen output.
+ If <code class="literal">columns</code> is nonzero then file and pipe output is
+ wrapped to that width as well.
+ </p></dd><dt><span class="term"><code class="literal">csv_fieldsep</code></span></dt><dd><p>
+ Specifies the field separator to be used in
+ <acronym class="acronym">CSV</acronym> output format. If the separator character
+ appears in a field's value, that field is output within double
+ quotes, following standard <acronym class="acronym">CSV</acronym> rules.
+ The default is a comma.
+ </p></dd><dt><span class="term"><code class="literal">expanded</code> (or <code class="literal">x</code>)</span></dt><dd><p>
+ If <em class="replaceable"><code>value</code></em> is specified it
+ must be either <code class="literal">on</code> or <code class="literal">off</code>, which
+ will enable or disable expanded mode, or <code class="literal">auto</code>.
+ If <em class="replaceable"><code>value</code></em> is omitted the
+ command toggles between the on and off settings. When expanded mode
+ is enabled, query results are displayed in two columns, with the
+ column name on the left and the data on the right. This mode is
+ useful if the data wouldn't fit on the screen in the
+ normal <span class="quote">“<span class="quote">horizontal</span>”</span> mode. In the auto setting, the
+ expanded mode is used whenever the query output has more than one
+ column and is wider than the screen; otherwise, the regular mode is
+ used. The auto setting is only
+ effective in the aligned and wrapped formats. In other formats, it
+ always behaves as if the expanded mode is off.
+ </p></dd><dt><span class="term"><code class="literal">fieldsep</code></span></dt><dd><p>
+ Specifies the field separator to be used in unaligned output
+ format. That way one can create, for example, tab-separated
+ output, which other programs might prefer. To
+ set a tab as field separator, type <code class="literal">\pset fieldsep
+ '\t'</code>. The default field separator is
+ <code class="literal">'|'</code> (a vertical bar).
+ </p></dd><dt><span class="term"><code class="literal">fieldsep_zero</code></span></dt><dd><p>
+ Sets the field separator to use in unaligned output format to a zero
+ byte.
+ </p></dd><dt><span class="term"><code class="literal">footer</code></span></dt><dd><p>
+ If <em class="replaceable"><code>value</code></em> is specified
+ it must be either <code class="literal">on</code> or <code class="literal">off</code>
+ which will enable or disable display of the table footer
+ (the <code class="literal">(<em class="replaceable"><code>n</code></em> rows)</code> count).
+ If <em class="replaceable"><code>value</code></em> is omitted the
+ command toggles footer display on or off.
+ </p></dd><dt><span class="term"><code class="literal">format</code></span></dt><dd><p>
+ Sets the output format to one of <code class="literal">aligned</code>,
+ <code class="literal">asciidoc</code>,
+ <code class="literal">csv</code>,
+ <code class="literal">html</code>,
+ <code class="literal">latex</code>,
+ <code class="literal">latex-longtable</code>, <code class="literal">troff-ms</code>,
+ <code class="literal">unaligned</code>, or <code class="literal">wrapped</code>.
+ Unique abbreviations are allowed.
+ </p><p><code class="literal">aligned</code> format is the standard,
+ human-readable, nicely formatted text output; this is the default.
+ </p><p><code class="literal">unaligned</code> format writes all columns of a row on one
+ line, separated by the currently active field separator. This
+ is useful for creating output that might be intended to be read
+ in by other programs, for example, tab-separated or comma-separated
+ format. However, the field separator character is not treated
+ specially if it appears in a column's value;
+ so <acronym class="acronym">CSV</acronym> format may be better suited for such
+ purposes.
+ </p><p><code class="literal">csv</code> format
+ <a id="id-1.9.4.20.8.4.10.1.76.2.3.1.8.2.4.2" class="indexterm"></a>
+ writes column values separated by commas, applying the quoting
+ rules described in
+ <a class="ulink" href="https://tools.ietf.org/html/rfc4180" target="_top">RFC 4180</a>.
+ This output is compatible with the CSV format of the server's
+ <code class="command">COPY</code> command.
+ A header line with column names is generated unless
+ the <code class="literal">tuples_only</code> parameter is
+ <code class="literal">on</code>. Titles and footers are not printed.
+ Each row is terminated by the system-dependent end-of-line character,
+ which is typically a single newline (<code class="literal">\n</code>) for
+ Unix-like systems or a carriage return and newline sequence
+ (<code class="literal">\r\n</code>) for Microsoft Windows.
+ Field separator characters other than comma can be selected with
+ <code class="command">\pset csv_fieldsep</code>.
+ </p><p><code class="literal">wrapped</code> format is like <code class="literal">aligned</code> but wraps
+ wide data values across lines to make the output fit in the target
+ column width. The target width is determined as described under
+ the <code class="literal">columns</code> option. Note that <span class="application">psql</span> will
+ not attempt to wrap column header titles; therefore,
+ <code class="literal">wrapped</code> format behaves the same as <code class="literal">aligned</code>
+ if the total width needed for column headers exceeds the target.
+ </p><p>
+ The <code class="literal">asciidoc</code>, <code class="literal">html</code>,
+ <code class="literal">latex</code>, <code class="literal">latex-longtable</code>, and
+ <code class="literal">troff-ms</code> formats put out tables that are intended
+ to be included in documents using the respective mark-up
+ language. They are not complete documents! This might not be
+ necessary in <acronym class="acronym">HTML</acronym>, but in
+ <span class="application">LaTeX</span> you must have a complete
+ document wrapper.
+ The <code class="literal">latex</code> format
+ uses <span class="application">LaTeX</span>'s <code class="literal">tabular</code>
+ environment.
+ The <code class="literal">latex-longtable</code> format
+ requires the <span class="application">LaTeX</span>
+ <code class="literal">longtable</code> and <code class="literal">booktabs</code> packages.
+ </p></dd><dt><span class="term"><code class="literal">linestyle</code></span></dt><dd><p>
+ Sets the border line drawing style to one
+ of <code class="literal">ascii</code>, <code class="literal">old-ascii</code>,
+ or <code class="literal">unicode</code>.
+ Unique abbreviations are allowed. (That would mean one
+ letter is enough.)
+ The default setting is <code class="literal">ascii</code>.
+ This option only affects the <code class="literal">aligned</code> and
+ <code class="literal">wrapped</code> output formats.
+ </p><p><code class="literal">ascii</code> style uses plain <acronym class="acronym">ASCII</acronym>
+ characters. Newlines in data are shown using
+ a <code class="literal">+</code> symbol in the right-hand margin.
+ When the <code class="literal">wrapped</code> format wraps data from
+ one line to the next without a newline character, a dot
+ (<code class="literal">.</code>) is shown in the right-hand margin of the first line,
+ and again in the left-hand margin of the following line.
+ </p><p><code class="literal">old-ascii</code> style uses plain <acronym class="acronym">ASCII</acronym>
+ characters, using the formatting style used
+ in <span class="productname">PostgreSQL</span> 8.4 and earlier.
+ Newlines in data are shown using a <code class="literal">:</code>
+ symbol in place of the left-hand column separator.
+ When the data is wrapped from one line
+ to the next without a newline character, a <code class="literal">;</code>
+ symbol is used in place of the left-hand column separator.
+ </p><p><code class="literal">unicode</code> style uses Unicode box-drawing characters.
+ Newlines in data are shown using a carriage return symbol
+ in the right-hand margin. When the data is wrapped from one line
+ to the next without a newline character, an ellipsis symbol
+ is shown in the right-hand margin of the first line, and
+ again in the left-hand margin of the following line.
+ </p><p>
+ When the <code class="literal">border</code> setting is greater than zero,
+ the <code class="literal">linestyle</code> option also determines the
+ characters with which the border lines are drawn.
+ Plain <acronym class="acronym">ASCII</acronym> characters work everywhere, but
+ Unicode characters look nicer on displays that recognize them.
+ </p></dd><dt><span class="term"><code class="literal">null</code></span></dt><dd><p>
+ Sets the string to be printed in place of a null value.
+ The default is to print nothing, which can easily be mistaken for
+ an empty string. For example, one might prefer <code class="literal">\pset null
+ '(null)'</code>.
+ </p></dd><dt><span class="term"><code class="literal">numericlocale</code></span></dt><dd><p>
+ If <em class="replaceable"><code>value</code></em> is specified
+ it must be either <code class="literal">on</code> or <code class="literal">off</code>
+ which will enable or disable display of a locale-specific character
+ to separate groups of digits to the left of the decimal marker.
+ If <em class="replaceable"><code>value</code></em> is omitted the
+ command toggles between regular and locale-specific numeric output.
+ </p></dd><dt><span class="term"><code class="literal">pager</code></span></dt><dd><p>
+ Controls use of a pager program for query and <span class="application">psql</span>
+ help output.
+ When the <code class="literal">pager</code> option is <code class="literal">off</code>, the pager
+ program is not used. When the <code class="literal">pager</code> option is
+ <code class="literal">on</code>, the pager is used when appropriate, i.e., when the
+ output is to a terminal and will not fit on the screen.
+ The <code class="literal">pager</code> option can also be set to <code class="literal">always</code>,
+ which causes the pager to be used for all terminal output regardless
+ of whether it fits on the screen. <code class="literal">\pset pager</code>
+ without a <em class="replaceable"><code>value</code></em>
+ toggles pager use on and off.
+ </p><p>
+ If the environment variable <code class="envar">PSQL_PAGER</code>
+ or <code class="envar">PAGER</code> is set, output to be paged is piped to the
+ specified program. Otherwise a platform-dependent default program
+ (such as <code class="filename">more</code>) is used.
+ </p><p>
+ When using the <code class="literal">\watch</code> command to execute a query
+ repeatedly, the environment variable <code class="envar">PSQL_WATCH_PAGER</code>
+ is used to find the pager program instead, on Unix systems. This is
+ configured separately because it may confuse traditional pagers, but
+ can be used to send output to tools that understand
+ <span class="application">psql</span>'s output format (such as
+ <code class="filename">pspg --stream</code>).
+ </p></dd><dt><span class="term"><code class="literal">pager_min_lines</code></span></dt><dd><p>
+ If <code class="literal">pager_min_lines</code> is set to a number greater than the
+ page height, the pager program will not be called unless there are
+ at least this many lines of output to show. The default setting
+ is 0.
+ </p></dd><dt><span class="term"><code class="literal">recordsep</code></span></dt><dd><p>
+ Specifies the record (line) separator to use in unaligned
+ output format. The default is a newline character.
+ </p></dd><dt><span class="term"><code class="literal">recordsep_zero</code></span></dt><dd><p>
+ Sets the record separator to use in unaligned output format to a zero
+ byte.
+ </p></dd><dt><span class="term"><code class="literal">tableattr</code> (or <code class="literal">T</code>)</span></dt><dd><p>
+ In <acronym class="acronym">HTML</acronym> format, this specifies attributes
+ to be placed inside the <code class="sgmltag-element">table</code> tag. This
+ could for example be <code class="literal">cellpadding</code> or
+ <code class="literal">bgcolor</code>. Note that you probably don't want
+ to specify <code class="literal">border</code> here, as that is already
+ taken care of by <code class="literal">\pset border</code>.
+ If no
+ <em class="replaceable"><code>value</code></em> is given,
+ the table attributes are unset.
+ </p><p>
+ In <code class="literal">latex-longtable</code> format, this controls
+ the proportional width of each column containing a left-aligned
+ data type. It is specified as a whitespace-separated list of values,
+ e.g., <code class="literal">'0.2 0.2 0.6'</code>. Unspecified output columns
+ use the last specified value.
+ </p></dd><dt><span class="term"><code class="literal">title</code> (or <code class="literal">C</code>)</span></dt><dd><p>
+ Sets the table title for any subsequently printed tables. This
+ can be used to give your output descriptive tags. If no
+ <em class="replaceable"><code>value</code></em> is given,
+ the title is unset.
+ </p></dd><dt><span class="term"><code class="literal">tuples_only</code> (or <code class="literal">t</code>)</span></dt><dd><p>
+ If <em class="replaceable"><code>value</code></em> is specified
+ it must be either <code class="literal">on</code> or <code class="literal">off</code>
+ which will enable or disable tuples-only mode.
+ If <em class="replaceable"><code>value</code></em> is omitted the
+ command toggles between regular and tuples-only output.
+ Regular output includes extra information such
+ as column headers, titles, and various footers. In tuples-only
+ mode, only actual table data is shown.
+ </p></dd><dt><span class="term"><code class="literal">unicode_border_linestyle</code></span></dt><dd><p>
+ Sets the border drawing style for the <code class="literal">unicode</code>
+ line style to one of <code class="literal">single</code>
+ or <code class="literal">double</code>.
+ </p></dd><dt><span class="term"><code class="literal">unicode_column_linestyle</code></span></dt><dd><p>
+ Sets the column drawing style for the <code class="literal">unicode</code>
+ line style to one of <code class="literal">single</code>
+ or <code class="literal">double</code>.
+ </p></dd><dt><span class="term"><code class="literal">unicode_header_linestyle</code></span></dt><dd><p>
+ Sets the header drawing style for the <code class="literal">unicode</code>
+ line style to one of <code class="literal">single</code>
+ or <code class="literal">double</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ Illustrations of how these different formats look can be seen in
+ <a class="xref" href="app-psql.html#APP-PSQL-EXAMPLES" title="Examples">Examples</a>, below.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ There are various shortcut commands for <code class="command">\pset</code>. See
+ <code class="command">\a</code>, <code class="command">\C</code>, <code class="command">\f</code>,
+ <code class="command">\H</code>, <code class="command">\t</code>, <code class="command">\T</code>,
+ and <code class="command">\x</code>.
+ </p></div></dd><dt><span class="term"><code class="literal">\q</code> or <code class="literal">\quit</code></span></dt><dd><p>
+ Quits the <span class="application">psql</span> program.
+ In a script file, only execution of that script is terminated.
+ </p></dd><dt><span class="term"><code class="literal">\qecho <em class="replaceable"><code>text</code></em> [ ... ] </code></span></dt><dd><p>
+ This command is identical to <code class="command">\echo</code> except
+ that the output will be written to the query output channel, as
+ set by <code class="command">\o</code>.
+ </p></dd><dt><span class="term"><code class="literal">\r</code> or <code class="literal">\reset</code></span></dt><dd><p>
+ Resets (clears) the query buffer.
+ </p></dd><dt><span class="term"><code class="literal">\s [ <em class="replaceable"><code>filename</code></em> ]</code></span></dt><dd><p>
+ Print <span class="application">psql</span>'s command line history
+ to <em class="replaceable"><code>filename</code></em>.
+ If <em class="replaceable"><code>filename</code></em> is omitted,
+ the history is written to the standard output (using the pager if
+ appropriate). This command is not available
+ if <span class="application">psql</span> was built
+ without <span class="application">Readline</span> support.
+ </p></dd><dt><span class="term"><code class="literal">\set [ <em class="replaceable"><code>name</code></em> [ <em class="replaceable"><code>value</code></em> [ ... ] ] ]</code></span></dt><dd><p>
+ Sets the <span class="application">psql</span> variable <em class="replaceable"><code>name</code></em> to <em class="replaceable"><code>value</code></em>, or if more than one value
+ is given, to the concatenation of all of them. If only one
+ argument is given, the variable is set to an empty-string value. To
+ unset a variable, use the <code class="command">\unset</code> command.
+ </p><p><code class="command">\set</code> without any arguments displays the names and values
+ of all currently-set <span class="application">psql</span> variables.
+ </p><p>
+ Valid variable names can contain letters, digits, and
+ underscores. See <a class="xref" href="app-psql.html#APP-PSQL-VARIABLES" title="Variables">Variables</a> below for details.
+ Variable names are case-sensitive.
+ </p><p>
+ Certain variables are special, in that they
+ control <span class="application">psql</span>'s behavior or are
+ automatically set to reflect connection state. These variables are
+ documented in <a class="xref" href="app-psql.html#APP-PSQL-VARIABLES" title="Variables">Variables</a>, below.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This command is unrelated to the <acronym class="acronym">SQL</acronym>
+ command <a class="link" href="sql-set.html" title="SET"><code class="command">SET</code></a>.
+ </p></div></dd><dt><span class="term"><code class="literal">\setenv <em class="replaceable"><code>name</code></em> [ <em class="replaceable"><code>value</code></em> ]</code></span></dt><dd><p>
+ Sets the environment variable <em class="replaceable"><code>name</code></em> to <em class="replaceable"><code>value</code></em>, or if the
+ <em class="replaceable"><code>value</code></em> is
+ not supplied, unsets the environment variable. Example:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\setenv PAGER less</code></strong>
+testdb=&gt; <strong class="userinput"><code>\setenv LESS -imx4F</code></strong>
+</pre></dd><dt><span class="term"><code class="literal">\sf[+] <em class="replaceable"><code>function_description</code></em> </code></span></dt><dd><p>
+ This command fetches and shows the definition of the named function or procedure,
+ in the form of a <code class="command">CREATE OR REPLACE FUNCTION</code> or
+ <code class="command">CREATE OR REPLACE PROCEDURE</code> command.
+ The definition is printed to the current query output channel,
+ as set by <code class="command">\o</code>.
+ </p><p>
+ The target function can be specified by name alone, or by name
+ and arguments, for example <code class="literal">foo(integer, text)</code>.
+ The argument types must be given if there is more
+ than one function of the same name.
+ </p><p>
+ If <code class="literal">+</code> is appended to the command name, then the
+ output lines are numbered, with the first line of the function body
+ being line 1.
+ </p><p>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <code class="command">\sf</code>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </p></dd><dt><span class="term"><code class="literal">\sv[+] <em class="replaceable"><code>view_name</code></em> </code></span></dt><dd><p>
+ This command fetches and shows the definition of the named view,
+ in the form of a <code class="command">CREATE OR REPLACE VIEW</code> command.
+ The definition is printed to the current query output channel,
+ as set by <code class="command">\o</code>.
+ </p><p>
+ If <code class="literal">+</code> is appended to the command name, then the
+ output lines are numbered from 1.
+ </p><p>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <code class="command">\sv</code>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </p></dd><dt><span class="term"><code class="literal">\t</code></span></dt><dd><p>
+ Toggles the display of output column name headings and row count
+ footer. This command is equivalent to <code class="literal">\pset
+ tuples_only</code> and is provided for convenience.
+ </p></dd><dt><span class="term"><code class="literal">\T <em class="replaceable"><code>table_options</code></em></code></span></dt><dd><p>
+ Specifies attributes to be placed within the
+ <code class="sgmltag-element">table</code> tag in <acronym class="acronym">HTML</acronym>
+ output format. This command is equivalent to <code class="literal">\pset
+ tableattr <em class="replaceable"><code>table_options</code></em></code>.
+ </p></dd><dt><span class="term"><code class="literal">\timing [ <em class="replaceable"><code>on</code></em> | <em class="replaceable"><code>off</code></em> ]</code></span></dt><dd><p>
+ With a parameter, turns displaying of how long each SQL statement
+ takes on or off. Without a parameter, toggles the display between
+ on and off. The display is in milliseconds; intervals longer than
+ 1 second are also shown in minutes:seconds format, with hours and
+ days fields added if needed.
+ </p></dd><dt><span class="term"><code class="literal">\unset <em class="replaceable"><code>name</code></em></code></span></dt><dd><p>
+ Unsets (deletes) the <span class="application">psql</span> variable <em class="replaceable"><code>name</code></em>.
+ </p><p>
+ Most variables that control <span class="application">psql</span>'s behavior
+ cannot be unset; instead, an <code class="literal">\unset</code> command is interpreted
+ as setting them to their default values.
+ See <a class="xref" href="app-psql.html#APP-PSQL-VARIABLES" title="Variables">Variables</a> below.
+ </p></dd><dt><span class="term"><code class="literal">\w</code> or <code class="literal">\write</code> <em class="replaceable"><code>filename</code></em><br /></span><span class="term"><code class="literal">\w</code> or <code class="literal">\write</code> <code class="literal">|</code><em class="replaceable"><code>command</code></em></span></dt><dd><p>
+ Writes the current query buffer to the file <em class="replaceable"><code>filename</code></em> or pipes it to the shell
+ command <em class="replaceable"><code>command</code></em>.
+ If the current query buffer is empty, the most recently executed query
+ is written instead.
+ </p><p>
+ If the argument begins with <code class="literal">|</code>, then the entire remainder
+ of the line is taken to be
+ the <em class="replaceable"><code>command</code></em> to execute,
+ and neither variable interpolation nor backquote expansion are
+ performed in it. The rest of the line is simply passed literally to
+ the shell.
+ </p></dd><dt><span class="term"><code class="literal">\warn <em class="replaceable"><code>text</code></em> [ ... ]</code></span></dt><dd><p>
+ This command is identical to <code class="command">\echo</code> except
+ that the output will be written to <span class="application">psql</span>'s
+ standard error channel, rather than standard output.
+ </p></dd><dt><span class="term"><code class="literal">\watch [ <em class="replaceable"><code>seconds</code></em> ]</code></span></dt><dd><p>
+ Repeatedly execute the current query buffer (as <code class="literal">\g</code> does)
+ until interrupted or the query fails. Wait the specified number of
+ seconds (default 2) between executions. Each query result is
+ displayed with a header that includes the <code class="literal">\pset title</code>
+ string (if any), the time as of query start, and the delay interval.
+ </p><p>
+ If the current query buffer is empty, the most recently sent query
+ is re-executed instead.
+ </p></dd><dt><span class="term"><code class="literal">\x [ <em class="replaceable"><code>on</code></em> | <em class="replaceable"><code>off</code></em> | <em class="replaceable"><code>auto</code></em> ]</code></span></dt><dd><p>
+ Sets or toggles expanded table formatting mode. As such it is equivalent to
+ <code class="literal">\pset expanded</code>.
+ </p></dd><dt><span class="term"><code class="literal">\z [ <a class="link" href="app-psql.html#APP-PSQL-PATTERNS" title="Patterns"><em class="replaceable"><code>pattern</code></em></a> ]</code></span></dt><dd><p>
+ Lists tables, views and sequences with their
+ associated access privileges.
+ If a <em class="replaceable"><code>pattern</code></em> is
+ specified, only tables, views and sequences whose names match the
+ pattern are listed.
+ </p><p>
+ This is an alias for <code class="command">\dp</code> (<span class="quote">“<span class="quote">display
+ privileges</span>”</span>).
+ </p></dd><dt><span class="term"><code class="literal">\! [ <em class="replaceable"><code>command</code></em> ]</code></span></dt><dd><p>
+ With no argument, escapes to a sub-shell; <span class="application">psql</span>
+ resumes when the sub-shell exits. With an argument, executes the
+ shell command <em class="replaceable"><code>command</code></em>.
+ </p><p>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <code class="command">\!</code>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments. The rest of the line is simply passed literally to the
+ shell.
+ </p></dd><dt><span class="term"><code class="literal">\? [ <em class="replaceable"><code>topic</code></em> ]</code></span></dt><dd><p>
+ Shows help information. The optional
+ <em class="replaceable"><code>topic</code></em> parameter
+ (defaulting to <code class="literal">commands</code>) selects which part of <span class="application">psql</span> is
+ explained: <code class="literal">commands</code> describes <span class="application">psql</span>'s
+ backslash commands; <code class="literal">options</code> describes the command-line
+ options that can be passed to <span class="application">psql</span>;
+ and <code class="literal">variables</code> shows help about <span class="application">psql</span> configuration
+ variables.
+ </p></dd><dt><span class="term"><code class="literal">\;</code></span></dt><dd><p>
+ Backslash-semicolon is not a meta-command in the same way as the
+ preceding commands; rather, it simply causes a semicolon to be
+ added to the query buffer without any further processing.
+ </p><p>
+ Normally, <span class="application">psql</span> will dispatch an SQL command to the
+ server as soon as it reaches the command-ending semicolon, even if
+ more input remains on the current line. Thus for example entering
+</p><pre class="programlisting">
+select 1; select 2; select 3;
+</pre><p>
+ will result in the three SQL commands being individually sent to
+ the server, with each one's results being displayed before
+ continuing to the next command. However, a semicolon entered
+ as <code class="literal">\;</code> will not trigger command processing, so that the
+ command before it and the one after are effectively combined and
+ sent to the server in one request. So for example
+</p><pre class="programlisting">
+select 1\; select 2\; select 3;
+</pre><p>
+ results in sending the three SQL commands to the server in a single
+ request, when the non-backslashed semicolon is reached.
+ The server executes such a request as a single transaction,
+ unless there are explicit <code class="command">BEGIN</code>/<code class="command">COMMIT</code>
+ commands included in the string to divide it into multiple
+ transactions. (See <a class="xref" href="protocol-flow.html#PROTOCOL-FLOW-MULTI-STATEMENT" title="55.2.2.1. Multiple Statements in a Simple Query">Section 55.2.2.1</a>
+ for more details about how the server handles multi-query strings.)
+ </p></dd></dl></div><p>
+ </p><div class="refsect3" id="APP-PSQL-PATTERNS"><h4>Patterns</h4><a id="id-1.9.4.20.8.4.11.2" class="indexterm"></a><p>
+ The various <code class="literal">\d</code> commands accept a <em class="replaceable"><code>pattern</code></em> parameter to specify the
+ object name(s) to be displayed. In the simplest case, a pattern
+ is just the exact name of the object. The characters within a
+ pattern are normally folded to lower case, just as in SQL names;
+ for example, <code class="literal">\dt FOO</code> will display the table named
+ <code class="literal">foo</code>. As in SQL names, placing double quotes around
+ a pattern stops folding to lower case. Should you need to include
+ an actual double quote character in a pattern, write it as a pair
+ of double quotes within a double-quote sequence; again this is in
+ accord with the rules for SQL quoted identifiers. For example,
+ <code class="literal">\dt "FOO""BAR"</code> will display the table named
+ <code class="literal">FOO"BAR</code> (not <code class="literal">foo"bar</code>). Unlike the normal
+ rules for SQL names, you can put double quotes around just part
+ of a pattern, for instance <code class="literal">\dt FOO"FOO"BAR</code> will display
+ the table named <code class="literal">fooFOObar</code>.
+ </p><p>
+ Whenever the <em class="replaceable"><code>pattern</code></em> parameter
+ is omitted completely, the <code class="literal">\d</code> commands display all objects
+ that are visible in the current schema search path — this is
+ equivalent to using <code class="literal">*</code> as the pattern.
+ (An object is said to be <em class="firstterm">visible</em> if its
+ containing schema is in the search path and no object of the same
+ kind and name appears earlier in the search path. This is equivalent to the
+ statement that the object can be referenced by name without explicit
+ schema qualification.)
+ To see all objects in the database regardless of visibility,
+ use <code class="literal">*.*</code> as the pattern.
+ </p><p>
+ Within a pattern, <code class="literal">*</code> matches any sequence of characters
+ (including no characters) and <code class="literal">?</code> matches any single character.
+ (This notation is comparable to Unix shell file name patterns.)
+ For example, <code class="literal">\dt int*</code> displays tables whose names
+ begin with <code class="literal">int</code>. But within double quotes, <code class="literal">*</code>
+ and <code class="literal">?</code> lose these special meanings and are just matched
+ literally.
+ </p><p>
+ A relation pattern that contains a dot (<code class="literal">.</code>) is interpreted as a schema
+ name pattern followed by an object name pattern. For example,
+ <code class="literal">\dt foo*.*bar*</code> displays all tables whose table name
+ includes <code class="literal">bar</code> that are in schemas whose schema name
+ starts with <code class="literal">foo</code>. When no dot appears, then the pattern
+ matches only objects that are visible in the current schema search path.
+ Again, a dot within double quotes loses its special meaning and is matched
+ literally. A relation pattern that contains two dots (<code class="literal">.</code>)
+ is interpreted as a database name followed by a schema name pattern followed
+ by an object name pattern. The database name portion will not be treated as
+ a pattern and must match the name of the currently connected database, else
+ an error will be raised.
+ </p><p>
+ A schema pattern that contains a dot (<code class="literal">.</code>) is interpreted
+ as a database name followed by a schema name pattern. For example,
+ <code class="literal">\dn mydb.*foo*</code> displays all schemas whose schema name
+ includes <code class="literal">foo</code>. The database name portion will not be
+ treated as a pattern and must match the name of the currently connected
+ database, else an error will be raised.
+ </p><p>
+ Advanced users can use regular-expression notations such as character
+ classes, for example <code class="literal">[0-9]</code> to match any digit. All regular
+ expression special characters work as specified in
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>, except for <code class="literal">.</code> which
+ is taken as a separator as mentioned above, <code class="literal">*</code> which is
+ translated to the regular-expression notation <code class="literal">.*</code>,
+ <code class="literal">?</code> which is translated to <code class="literal">.</code>, and
+ <code class="literal">$</code> which is matched literally. You can emulate
+ these pattern characters at need by writing
+ <code class="literal">?</code> for <code class="literal">.</code>,
+ <code class="literal">(<em class="replaceable"><code>R</code></em>+|)</code> for
+ <code class="literal"><em class="replaceable"><code>R</code></em>*</code>, or
+ <code class="literal">(<em class="replaceable"><code>R</code></em>|)</code> for
+ <code class="literal"><em class="replaceable"><code>R</code></em>?</code>.
+ <code class="literal">$</code> is not needed as a regular-expression character since
+ the pattern must match the whole name, unlike the usual
+ interpretation of regular expressions (in other words, <code class="literal">$</code>
+ is automatically appended to your pattern). Write <code class="literal">*</code> at the
+ beginning and/or end if you don't wish the pattern to be anchored.
+ Note that within double quotes, all regular expression special characters
+ lose their special meanings and are matched literally. Also, the regular
+ expression special characters are matched literally in operator name
+ patterns (i.e., the argument of <code class="literal">\do</code>).
+ </p></div></div><div class="refsect2" id="id-1.9.4.20.8.5"><h3>Advanced Features</h3><div class="refsect3" id="APP-PSQL-VARIABLES"><h4>Variables</h4><p>
+ <span class="application">psql</span> provides variable substitution
+ features similar to common Unix command shells.
+ Variables are simply name/value pairs, where the value
+ can be any string of any length. The name must consist of letters
+ (including non-Latin letters), digits, and underscores.
+ </p><p>
+ To set a variable, use the <span class="application">psql</span> meta-command
+ <code class="command">\set</code>. For example,
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\set foo bar</code></strong>
+</pre><p>
+ sets the variable <code class="literal">foo</code> to the value
+ <code class="literal">bar</code>. To retrieve the content of the variable, precede
+ the name with a colon, for example:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\echo :foo</code></strong>
+bar
+</pre><p>
+ This works in both regular SQL commands and meta-commands; there is
+ more detail in <a class="xref" href="app-psql.html#APP-PSQL-INTERPOLATION" title="SQL Interpolation">SQL Interpolation</a>, below.
+ </p><p>
+ If you call <code class="command">\set</code> without a second argument, the
+ variable is set to an empty-string value. To unset (i.e., delete)
+ a variable, use the command <code class="command">\unset</code>. To show the
+ values of all variables, call <code class="command">\set</code> without any argument.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The arguments of <code class="command">\set</code> are subject to the same
+ substitution rules as with other commands. Thus you can construct
+ interesting references such as <code class="literal">\set :foo
+ 'something'</code> and get <span class="quote">“<span class="quote">soft links</span>”</span> or
+ <span class="quote">“<span class="quote">variable variables</span>”</span> of <span class="productname">Perl</span>
+ or <span class="productname"><acronym class="acronym">PHP</acronym></span> fame,
+ respectively. Unfortunately (or fortunately?), there is no way to do
+ anything useful with these constructs. On the other hand,
+ <code class="literal">\set bar :foo</code> is a perfectly valid way to copy a
+ variable.
+ </p></div><p>
+ A number of these variables are treated specially
+ by <span class="application">psql</span>. They represent certain option
+ settings that can be changed at run time by altering the value of
+ the variable, or in some cases represent changeable state of
+ <span class="application">psql</span>.
+ By convention, all specially treated variables' names
+ consist of all upper-case ASCII letters (and possibly digits and
+ underscores). To ensure maximum compatibility in the future, avoid
+ using such variable names for your own purposes.
+ </p><p>
+ Variables that control <span class="application">psql</span>'s behavior
+ generally cannot be unset or set to invalid values. An <code class="literal">\unset</code>
+ command is allowed but is interpreted as setting the variable to its
+ default value. A <code class="literal">\set</code> command without a second argument is
+ interpreted as setting the variable to <code class="literal">on</code>, for control
+ variables that accept that value, and is rejected for others. Also,
+ control variables that accept the values <code class="literal">on</code>
+ and <code class="literal">off</code> will also accept other common spellings of Boolean
+ values, such as <code class="literal">true</code> and <code class="literal">false</code>.
+ </p><p>
+ The specially treated variables are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">AUTOCOMMIT</code>
+ <a id="id-1.9.4.20.8.5.2.9.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="literal">on</code> (the default), each SQL command is automatically
+ committed upon successful completion. To postpone commit in this
+ mode, you must enter a <code class="command">BEGIN</code> or <code class="command">START
+ TRANSACTION</code> SQL command. When <code class="literal">off</code> or unset, SQL
+ commands are not committed until you explicitly issue
+ <code class="command">COMMIT</code> or <code class="command">END</code>. The autocommit-off
+ mode works by issuing an implicit <code class="command">BEGIN</code> for you, just
+ before any command that is not already in a transaction block and
+ is not itself a <code class="command">BEGIN</code> or other transaction-control
+ command, nor a command that cannot be executed inside a transaction
+ block (such as <code class="command">VACUUM</code>).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In autocommit-off mode, you must explicitly abandon any failed
+ transaction by entering <code class="command">ABORT</code> or <code class="command">ROLLBACK</code>.
+ Also keep in mind that if you exit the session
+ without committing, your work will be lost.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ The autocommit-on mode is <span class="productname">PostgreSQL</span>'s traditional
+ behavior, but autocommit-off is closer to the SQL spec. If you
+ prefer autocommit-off, you might wish to set it in the system-wide
+ <code class="filename">psqlrc</code> file or your
+ <code class="filename">~/.psqlrc</code> file.
+ </p></div></dd><dt><span class="term"><code class="varname">COMP_KEYWORD_CASE</code></span></dt><dd><p>
+ Determines which letter case to use when completing an SQL key word.
+ If set to <code class="literal">lower</code> or <code class="literal">upper</code>, the
+ completed word will be in lower or upper case, respectively. If set
+ to <code class="literal">preserve-lower</code>
+ or <code class="literal">preserve-upper</code> (the default), the completed word
+ will be in the case of the word already entered, but words being
+ completed without anything entered will be in lower or upper case,
+ respectively.
+ </p></dd><dt><span class="term"><code class="varname">DBNAME</code></span></dt><dd><p>
+ The name of the database you are currently connected to. This is
+ set every time you connect to a database (including program
+ start-up), but can be changed or unset.
+ </p></dd><dt><span class="term"><code class="varname">ECHO</code></span></dt><dd><p>
+ If set to <code class="literal">all</code>, all nonempty input lines are printed
+ to standard output as they are read. (This does not apply to lines
+ read interactively.) To select this behavior on program
+ start-up, use the switch <code class="option">-a</code>. If set to
+ <code class="literal">queries</code>,
+ <span class="application">psql</span> prints each query to standard output
+ as it is sent to the server. The switch to select this behavior is
+ <code class="option">-e</code>. If set to <code class="literal">errors</code>, then only
+ failed queries are displayed on standard error output. The switch
+ for this behavior is <code class="option">-b</code>. If set to
+ <code class="literal">none</code> (the default), then no queries are displayed.
+ </p></dd><dt><span class="term"><code class="varname">ECHO_HIDDEN</code></span></dt><dd><p>
+ When this variable is set to <code class="literal">on</code> and a backslash command
+ queries the database, the query is first shown.
+ This feature helps you to study
+ <span class="productname">PostgreSQL</span> internals and provide
+ similar functionality in your own programs. (To select this behavior
+ on program start-up, use the switch <code class="option">-E</code>.) If you set
+ this variable to the value <code class="literal">noexec</code>, the queries are
+ just shown but are not actually sent to the server and executed.
+ The default value is <code class="literal">off</code>.
+ </p></dd><dt><span class="term"><code class="varname">ENCODING</code></span></dt><dd><p>
+ The current client character set encoding.
+ This is set every time you connect to a database (including
+ program start-up), and when you change the encoding
+ with <code class="literal">\encoding</code>, but it can be changed or unset.
+ </p></dd><dt><span class="term"><code class="varname">ERROR</code></span></dt><dd><p>
+ <code class="literal">true</code> if the last SQL query failed, <code class="literal">false</code> if
+ it succeeded. See also <code class="varname">SQLSTATE</code>.
+ </p></dd><dt><span class="term"><code class="varname">FETCH_COUNT</code></span></dt><dd><p>
+ If this variable is set to an integer value greater than zero,
+ the results of <code class="command">SELECT</code> queries are fetched
+ and displayed in groups of that many rows, rather than the
+ default behavior of collecting the entire result set before
+ display. Therefore only a
+ limited amount of memory is used, regardless of the size of
+ the result set. Settings of 100 to 1000 are commonly used
+ when enabling this feature.
+ Keep in mind that when using this feature, a query might
+ fail after having already displayed some rows.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Although you can use any output format with this feature,
+ the default <code class="literal">aligned</code> format tends to look bad
+ because each group of <code class="varname">FETCH_COUNT</code> rows
+ will be formatted separately, leading to varying column
+ widths across the row groups. The other output formats work better.
+ </p></div></dd><dt><span class="term"><code class="varname">HIDE_TABLEAM</code></span></dt><dd><p>
+ If this variable is set to <code class="literal">true</code>, a table's access
+ method details are not displayed. This is mainly useful for
+ regression tests.
+ </p></dd><dt><span class="term"><code class="varname">HIDE_TOAST_COMPRESSION</code></span></dt><dd><p>
+ If this variable is set to <code class="literal">true</code>, column
+ compression method details are not displayed. This is mainly
+ useful for regression tests.
+ </p></dd><dt><span class="term"><code class="varname">HISTCONTROL</code></span></dt><dd><p>
+ If this variable is set to <code class="literal">ignorespace</code>,
+ lines which begin with a space are not entered into the history
+ list. If set to a value of <code class="literal">ignoredups</code>, lines
+ matching the previous history line are not entered. A value of
+ <code class="literal">ignoreboth</code> combines the two options. If
+ set to <code class="literal">none</code> (the default), all lines
+ read in interactive mode are saved on the history list.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This feature was shamelessly plagiarized from
+ <span class="application">Bash</span>.
+ </p></div></dd><dt><span class="term"><code class="varname">HISTFILE</code></span></dt><dd><p>
+ The file name that will be used to store the history list. If unset,
+ the file name is taken from the <code class="envar">PSQL_HISTORY</code>
+ environment variable. If that is not set either, the default
+ is <code class="filename">~/.psql_history</code>,
+ or <code class="filename">%APPDATA%\postgresql\psql_history</code> on Windows.
+ For example, putting:
+</p><pre class="programlisting">
+\set HISTFILE ~/.psql_history-:DBNAME
+</pre><p>
+ in <code class="filename">~/.psqlrc</code> will cause
+ <span class="application">psql</span> to maintain a separate history for
+ each database.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This feature was shamelessly plagiarized from
+ <span class="application">Bash</span>.
+ </p></div></dd><dt><span class="term"><code class="varname">HISTSIZE</code></span></dt><dd><p>
+ The maximum number of commands to store in the command history
+ (default 500). If set to a negative value, no limit is applied.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This feature was shamelessly plagiarized from
+ <span class="application">Bash</span>.
+ </p></div></dd><dt><span class="term"><code class="varname">HOST</code></span></dt><dd><p>
+ The database server host you are currently connected to. This is
+ set every time you connect to a database (including program
+ start-up), but can be changed or unset.
+ </p></dd><dt><span class="term"><code class="varname">IGNOREEOF</code></span></dt><dd><p>
+ If set to 1 or less, sending an <acronym class="acronym">EOF</acronym> character (usually
+ <span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>D</strong></span>)
+ to an interactive session of <span class="application">psql</span>
+ will terminate the application. If set to a larger numeric value,
+ that many consecutive <acronym class="acronym">EOF</acronym> characters must be typed to
+ make an interactive session terminate. If the variable is set to a
+ non-numeric value, it is interpreted as 10. The default is 0.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This feature was shamelessly plagiarized from
+ <span class="application">Bash</span>.
+ </p></div></dd><dt><span class="term"><code class="varname">LASTOID</code></span></dt><dd><p>
+ The value of the last affected OID, as returned from an
+ <code class="command">INSERT</code> or <code class="command">\lo_import</code>
+ command. This variable is only guaranteed to be valid until
+ after the result of the next <acronym class="acronym">SQL</acronym> command has
+ been displayed.
+ <span class="productname">PostgreSQL</span> servers since version 12 do not
+ support OID system columns anymore, thus LASTOID will always be 0
+ following <code class="command">INSERT</code> when targeting such servers.
+ </p></dd><dt><span class="term"><code class="varname">LAST_ERROR_MESSAGE</code><br /></span><span class="term"><code class="varname">LAST_ERROR_SQLSTATE</code></span></dt><dd><p>
+ The primary error message and associated SQLSTATE code for the most
+ recent failed query in the current <span class="application">psql</span> session, or
+ an empty string and <code class="literal">00000</code> if no error has occurred in
+ the current session.
+ </p></dd><dt><span class="term">
+ <code class="varname">ON_ERROR_ROLLBACK</code>
+ <a id="id-1.9.4.20.8.5.2.9.18.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set to <code class="literal">on</code>, if a statement in a transaction block
+ generates an error, the error is ignored and the transaction
+ continues. When set to <code class="literal">interactive</code>, such errors are only
+ ignored in interactive sessions, and not when reading script
+ files. When set to <code class="literal">off</code> (the default), a statement in a
+ transaction block that generates an error aborts the entire
+ transaction. The error rollback mode works by issuing an
+ implicit <code class="command">SAVEPOINT</code> for you, just before each command
+ that is in a transaction block, and then rolling back to the
+ savepoint if the command fails.
+ </p></dd><dt><span class="term"><code class="varname">ON_ERROR_STOP</code></span></dt><dd><p>
+ By default, command processing continues after an error. When this
+ variable is set to <code class="literal">on</code>, processing will instead stop
+ immediately. In interactive mode,
+ <span class="application">psql</span> will return to the command prompt;
+ otherwise, <span class="application">psql</span> will exit, returning
+ error code 3 to distinguish this case from fatal error
+ conditions, which are reported using error code 1. In either case,
+ any currently running scripts (the top-level script, if any, and any
+ other scripts which it may have in invoked) will be terminated
+ immediately. If the top-level command string contained multiple SQL
+ commands, processing will stop with the current command.
+ </p></dd><dt><span class="term"><code class="varname">PORT</code></span></dt><dd><p>
+ The database server port to which you are currently connected.
+ This is set every time you connect to a database (including
+ program start-up), but can be changed or unset.
+ </p></dd><dt><span class="term"><code class="varname">PROMPT1</code><br /></span><span class="term"><code class="varname">PROMPT2</code><br /></span><span class="term"><code class="varname">PROMPT3</code></span></dt><dd><p>
+ These specify what the prompts <span class="application">psql</span>
+ issues should look like. See <a class="xref" href="app-psql.html#APP-PSQL-PROMPTING" title="Prompting">Prompting</a> below.
+ </p></dd><dt><span class="term"><code class="varname">QUIET</code></span></dt><dd><p>
+ Setting this variable to <code class="literal">on</code> is equivalent to the command
+ line option <code class="option">-q</code>. It is probably not too useful in
+ interactive mode.
+ </p></dd><dt><span class="term"><code class="varname">ROW_COUNT</code></span></dt><dd><p>
+ The number of rows returned or affected by the last SQL query, or 0
+ if the query failed or did not report a row count.
+ </p></dd><dt><span class="term"><code class="varname">SERVER_VERSION_NAME</code><br /></span><span class="term"><code class="varname">SERVER_VERSION_NUM</code></span></dt><dd><p>
+ The server's version number as a string, for
+ example <code class="literal">9.6.2</code>, <code class="literal">10.1</code> or <code class="literal">11beta1</code>,
+ and in numeric form, for
+ example <code class="literal">90602</code> or <code class="literal">100001</code>.
+ These are set every time you connect to a database
+ (including program start-up), but can be changed or unset.
+ </p></dd><dt><span class="term"><code class="varname">SHOW_ALL_RESULTS</code></span></dt><dd><p>
+ When this variable is set to <code class="literal">off</code>, only the last
+ result of a combined query (<code class="literal">\;</code>) is shown instead of
+ all of them. The default is <code class="literal">on</code>. The off behavior
+ is for compatibility with older versions of psql.
+ </p></dd><dt><span class="term"><code class="varname">SHOW_CONTEXT</code></span></dt><dd><p>
+ This variable can be set to the
+ values <code class="literal">never</code>, <code class="literal">errors</code>, or <code class="literal">always</code>
+ to control whether <code class="literal">CONTEXT</code> fields are displayed in
+ messages from the server. The default is <code class="literal">errors</code> (meaning
+ that context will be shown in error messages, but not in notice or
+ warning messages). This setting has no effect
+ when <code class="varname">VERBOSITY</code> is set to <code class="literal">terse</code>
+ or <code class="literal">sqlstate</code>.
+ (See also <code class="command">\errverbose</code>, for use when you want a verbose
+ version of the error you just got.)
+ </p></dd><dt><span class="term"><code class="varname">SINGLELINE</code></span></dt><dd><p>
+ Setting this variable to <code class="literal">on</code> is equivalent to the command
+ line option <code class="option">-S</code>.
+ </p></dd><dt><span class="term"><code class="varname">SINGLESTEP</code></span></dt><dd><p>
+ Setting this variable to <code class="literal">on</code> is equivalent to the command
+ line option <code class="option">-s</code>.
+ </p></dd><dt><span class="term"><code class="varname">SQLSTATE</code></span></dt><dd><p>
+ The error code (see <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>) associated
+ with the last SQL query's failure, or <code class="literal">00000</code> if it
+ succeeded.
+ </p></dd><dt><span class="term"><code class="varname">USER</code></span></dt><dd><p>
+ The database user you are currently connected as. This is set
+ every time you connect to a database (including program
+ start-up), but can be changed or unset.
+ </p></dd><dt><span class="term"><code class="varname">VERBOSITY</code></span></dt><dd><p>
+ This variable can be set to the values <code class="literal">default</code>,
+ <code class="literal">verbose</code>, <code class="literal">terse</code>,
+ or <code class="literal">sqlstate</code> to control the verbosity of error
+ reports.
+ (See also <code class="command">\errverbose</code>, for use when you want a verbose
+ version of the error you just got.)
+ </p></dd><dt><span class="term"><code class="varname">VERSION</code><br /></span><span class="term"><code class="varname">VERSION_NAME</code><br /></span><span class="term"><code class="varname">VERSION_NUM</code></span></dt><dd><p>
+ These variables are set at program start-up to reflect
+ <span class="application">psql</span>'s version, respectively as a verbose string,
+ a short string (e.g., <code class="literal">9.6.2</code>, <code class="literal">10.1</code>,
+ or <code class="literal">11beta1</code>), and a number (e.g., <code class="literal">90602</code>
+ or <code class="literal">100001</code>). They can be changed or unset.
+ </p></dd></dl></div></div><div class="refsect3" id="APP-PSQL-INTERPOLATION"><h4><acronym class="acronym">SQL</acronym> Interpolation</h4><p>
+ A key feature of <span class="application">psql</span>
+ variables is that you can substitute (<span class="quote">“<span class="quote">interpolate</span>”</span>)
+ them into regular <acronym class="acronym">SQL</acronym> statements, as well as the
+ arguments of meta-commands. Furthermore,
+ <span class="application">psql</span> provides facilities for
+ ensuring that variable values used as SQL literals and identifiers are
+ properly quoted. The syntax for interpolating a value without
+ any quoting is to prepend the variable name with a colon
+ (<code class="literal">:</code>). For example,
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\set foo 'my_table'</code></strong>
+testdb=&gt; <strong class="userinput"><code>SELECT * FROM :foo;</code></strong>
+</pre><p>
+ would query the table <code class="literal">my_table</code>. Note that this
+ may be unsafe: the value of the variable is copied literally, so it can
+ contain unbalanced quotes, or even backslash commands. You must make sure
+ that it makes sense where you put it.
+ </p><p>
+ When a value is to be used as an SQL literal or identifier, it is
+ safest to arrange for it to be quoted. To quote the value of
+ a variable as an SQL literal, write a colon followed by the variable
+ name in single quotes. To quote the value as an SQL identifier, write
+ a colon followed by the variable name in double quotes.
+ These constructs deal correctly with quotes and other special
+ characters embedded within the variable value.
+ The previous example would be more safely written this way:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\set foo 'my_table'</code></strong>
+testdb=&gt; <strong class="userinput"><code>SELECT * FROM :"foo";</code></strong>
+</pre><p>
+ </p><p>
+ Variable interpolation will not be performed within quoted
+ <acronym class="acronym">SQL</acronym> literals and identifiers. Therefore, a
+ construction such as <code class="literal">':foo'</code> doesn't work to produce a quoted
+ literal from a variable's value (and it would be unsafe if it did work,
+ since it wouldn't correctly handle quotes embedded in the value).
+ </p><p>
+ One example use of this mechanism is to
+ copy the contents of a file into a table column.
+ First load the file into a variable and then interpolate the variable's
+ value as a quoted string:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\set content `cat my_file.txt`</code></strong>
+testdb=&gt; <strong class="userinput"><code>INSERT INTO my_table VALUES (:'content');</code></strong>
+</pre><p>
+ (Note that this still won't work if <code class="filename">my_file.txt</code> contains NUL bytes.
+ <span class="application">psql</span> does not support embedded NUL bytes in variable values.)
+ </p><p>
+ Since colons can legally appear in SQL commands, an apparent attempt
+ at interpolation (that is, <code class="literal">:name</code>,
+ <code class="literal">:'name'</code>, or <code class="literal">:"name"</code>) is not
+ replaced unless the named variable is currently set. In any case, you
+ can escape a colon with a backslash to protect it from substitution.
+ </p><p>
+ The <code class="literal">:{?<em class="replaceable"><code>name</code></em>}</code> special syntax returns TRUE
+ or FALSE depending on whether the variable exists or not, and is thus
+ always substituted, unless the colon is backslash-escaped.
+ </p><p>
+ The colon syntax for variables is standard <acronym class="acronym">SQL</acronym> for
+ embedded query languages, such as <span class="application">ECPG</span>.
+ The colon syntaxes for array slices and type casts are
+ <span class="productname">PostgreSQL</span> extensions, which can sometimes
+ conflict with the standard usage. The colon-quote syntax for escaping a
+ variable's value as an SQL literal or identifier is a
+ <span class="application">psql</span> extension.
+ </p></div><div class="refsect3" id="APP-PSQL-PROMPTING"><h4>Prompting</h4><p>
+ The prompts <span class="application">psql</span> issues can be customized
+ to your preference. The three variables <code class="varname">PROMPT1</code>,
+ <code class="varname">PROMPT2</code>, and <code class="varname">PROMPT3</code> contain strings
+ and special escape sequences that describe the appearance of the
+ prompt. Prompt 1 is the normal prompt that is issued when
+ <span class="application">psql</span> requests a new command. Prompt 2 is
+ issued when more input is expected during command entry, for example
+ because the command was not terminated with a semicolon or a quote
+ was not closed.
+ Prompt 3 is issued when you are running an <acronym class="acronym">SQL</acronym>
+ <code class="command">COPY FROM STDIN</code> command and you need to type in
+ a row value on the terminal.
+ </p><p>
+ The value of the selected prompt variable is printed literally,
+ except where a percent sign (<code class="literal">%</code>) is encountered.
+ Depending on the next character, certain other text is substituted
+ instead. Defined substitutions are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">%M</code></span></dt><dd><p>
+ The full host name (with domain name) of the database server,
+ or <code class="literal">[local]</code> if the connection is over a Unix
+ domain socket, or
+ <code class="literal">[local:<em class="replaceable"><code>/dir/name</code></em>]</code>,
+ if the Unix domain socket is not at the compiled in default
+ location.
+ </p></dd><dt><span class="term"><code class="literal">%m</code></span></dt><dd><p>
+ The host name of the database server, truncated at the
+ first dot, or <code class="literal">[local]</code> if the connection is
+ over a Unix domain socket.
+ </p></dd><dt><span class="term"><code class="literal">%&gt;</code></span></dt><dd><p>The port number at which the database server is listening.</p></dd><dt><span class="term"><code class="literal">%n</code></span></dt><dd><p>
+ The database session user name. (The expansion of this
+ value might change during a database session as the result
+ of the command <code class="command">SET SESSION
+ AUTHORIZATION</code>.)
+ </p></dd><dt><span class="term"><code class="literal">%/</code></span></dt><dd><p>The name of the current database.</p></dd><dt><span class="term"><code class="literal">%~</code></span></dt><dd><p>Like <code class="literal">%/</code>, but the output is <code class="literal">~</code>
+ (tilde) if the database is your default database.</p></dd><dt><span class="term"><code class="literal">%#</code></span></dt><dd><p>
+ If the session user is a database superuser, then a
+ <code class="literal">#</code>, otherwise a <code class="literal">&gt;</code>.
+ (The expansion of this value might change during a database
+ session as the result of the command <code class="command">SET SESSION
+ AUTHORIZATION</code>.)
+ </p></dd><dt><span class="term"><code class="literal">%p</code></span></dt><dd><p>The process ID of the backend currently connected to.</p></dd><dt><span class="term"><code class="literal">%R</code></span></dt><dd><p>
+ In prompt 1 normally <code class="literal">=</code>,
+ but <code class="literal">@</code> if the session is in an inactive branch of a
+ conditional block, or <code class="literal">^</code> if in single-line mode,
+ or <code class="literal">!</code> if the session is disconnected from the
+ database (which can happen if <code class="command">\connect</code> fails).
+ In prompt 2 <code class="literal">%R</code> is replaced by a character that
+ depends on why <span class="application">psql</span> expects more input:
+ <code class="literal">-</code> if the command simply wasn't terminated yet,
+ but <code class="literal">*</code> if there is an unfinished
+ <code class="literal">/* ... */</code> comment,
+ a single quote if there is an unfinished quoted string,
+ a double quote if there is an unfinished quoted identifier,
+ a dollar sign if there is an unfinished dollar-quoted string,
+ or <code class="literal">(</code> if there is an unmatched left parenthesis.
+ In prompt 3 <code class="literal">%R</code> doesn't produce anything.
+ </p></dd><dt><span class="term"><code class="literal">%x</code></span></dt><dd><p>
+ Transaction status: an empty string when not in a transaction
+ block, or <code class="literal">*</code> when in a transaction block, or
+ <code class="literal">!</code> when in a failed transaction block, or <code class="literal">?</code>
+ when the transaction state is indeterminate (for example, because
+ there is no connection).
+ </p></dd><dt><span class="term"><code class="literal">%l</code></span></dt><dd><p>
+ The line number inside the current statement, starting from <code class="literal">1</code>.
+ </p></dd><dt><span class="term"><code class="literal">%</code><em class="replaceable"><code>digits</code></em></span></dt><dd><p>
+ The character with the indicated octal code is substituted.
+ </p></dd><dt><span class="term"><code class="literal">%:</code><em class="replaceable"><code>name</code></em><code class="literal">:</code></span></dt><dd><p>
+ The value of the <span class="application">psql</span> variable
+ <em class="replaceable"><code>name</code></em>. See
+ <a class="xref" href="app-psql.html#APP-PSQL-VARIABLES" title="Variables">Variables</a>, above, for details.
+ </p></dd><dt><span class="term"><code class="literal">%`</code><em class="replaceable"><code>command</code></em><code class="literal">`</code></span></dt><dd><p>
+ The output of <em class="replaceable"><code>command</code></em>, similar to ordinary
+ <span class="quote">“<span class="quote">back-tick</span>”</span> substitution.
+ </p></dd><dt><span class="term"><code class="literal">%[</code> ... <code class="literal">%]</code></span></dt><dd><p>
+ Prompts can contain terminal control characters which, for
+ example, change the color, background, or style of the prompt
+ text, or change the title of the terminal window. In order for
+ the line editing features of <span class="application">Readline</span> to work properly, these
+ non-printing control characters must be designated as invisible
+ by surrounding them with <code class="literal">%[</code> and
+ <code class="literal">%]</code>. Multiple pairs of these can occur within
+ the prompt. For example:
+</p><pre class="programlisting">
+testdb=&gt; \set PROMPT1 '%[%033[1;33;40m%]%n@%/%R%[%033[0m%]%# '
+</pre><p>
+ results in a boldfaced (<code class="literal">1;</code>) yellow-on-black
+ (<code class="literal">33;40</code>) prompt on VT100-compatible, color-capable
+ terminals.
+ </p></dd><dt><span class="term"><code class="literal">%w</code></span></dt><dd><p>
+ Whitespace of the same width as the most recent output of
+ <code class="varname">PROMPT1</code>. This can be used as a
+ <code class="varname">PROMPT2</code> setting, so that multi-line statements are
+ aligned with the first line, but there is no visible secondary prompt.
+ </p></dd></dl></div><p>
+
+ To insert a percent sign into your prompt, write
+ <code class="literal">%%</code>. The default prompts are
+ <code class="literal">'%/%R%x%# '</code> for prompts 1 and 2, and
+ <code class="literal">'&gt;&gt; '</code> for prompt 3.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This feature was shamelessly plagiarized from
+ <span class="application">tcsh</span>.
+ </p></div></div><div class="refsect3" id="APP-PSQL-READLINE"><h4>Command-Line Editing</h4><a id="id-1.9.4.20.8.5.5.2" class="indexterm"></a><a id="id-1.9.4.20.8.5.5.3" class="indexterm"></a><p>
+ <span class="application">psql</span> uses
+ the <span class="application">Readline</span>
+ or <span class="application">libedit</span> library, if available, for
+ convenient line editing and retrieval. The command history is
+ automatically saved when <span class="application">psql</span> exits and is
+ reloaded when <span class="application">psql</span> starts up. Type
+ up-arrow or control-P to retrieve previous lines.
+ </p><p>
+ You can also use tab completion to fill in partially-typed keywords
+ and SQL object names in many (by no means all) contexts. For example,
+ at the start of a command, typing <code class="literal">ins</code> and pressing
+ TAB will fill in <code class="literal">insert into </code>. Then, typing a few
+ characters of a table or schema name and pressing <code class="literal">TAB</code>
+ will fill in the unfinished name, or offer a menu of possible completions
+ when there's more than one. (Depending on the library in use, you may need to
+ press <code class="literal">TAB</code> more than once to get a menu.)
+ </p><p>
+ Tab completion for SQL object names requires sending queries to the
+ server to find possible matches. In some contexts this can interfere
+ with other operations. For example, after <code class="command">BEGIN</code>
+ it will be too late to issue <code class="command">SET TRANSACTION ISOLATION
+ LEVEL</code> if a tab-completion query is issued in between.
+ If you do not want tab completion at all, you
+ can turn it off permanently by putting this in a file named
+ <code class="filename">.inputrc</code> in your home directory:
+</p><pre class="programlisting">
+$if psql
+set disable-completion on
+$endif
+</pre><p>
+ (This is not a <span class="application">psql</span> but a
+ <span class="application">Readline</span> feature. Read its documentation
+ for further details.)
+ </p><p>
+ The <code class="option">-n</code> (<code class="option">--no-readline</code>) command line
+ option can also be useful to disable use
+ of <span class="application">Readline</span> for a single run
+ of <span class="application">psql</span>. This prevents tab completion,
+ use or recording of command line history, and editing of multi-line
+ commands. It is particularly useful when you need to copy-and-paste
+ text that contains <code class="literal">TAB</code> characters.
+ </p></div></div></div><div class="refsect1" id="APP-PSQL-ENVIRONMENT"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">COLUMNS</code></span></dt><dd><p>
+ If <code class="literal">\pset columns</code> is zero, controls the
+ width for the <code class="literal">wrapped</code> format and width for determining
+ if wide output requires the pager or should be switched to the
+ vertical format in expanded auto mode.
+ </p></dd><dt><span class="term"><code class="envar">PGDATABASE</code><br /></span><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd><dt><span class="term"><code class="envar">PSQL_EDITOR</code><br /></span><span class="term"><code class="envar">EDITOR</code><br /></span><span class="term"><code class="envar">VISUAL</code></span></dt><dd><p>
+ Editor used by the <code class="command">\e</code>, <code class="command">\ef</code>,
+ and <code class="command">\ev</code> commands.
+ These variables are examined in the order listed;
+ the first that is set is used.
+ If none of them is set, the default is to use <code class="filename">vi</code>
+ on Unix systems or <code class="filename">notepad.exe</code> on Windows systems.
+ </p></dd><dt><span class="term"><code class="envar">PSQL_EDITOR_LINENUMBER_ARG</code></span></dt><dd><p>
+ When <code class="command">\e</code>, <code class="command">\ef</code>, or
+ <code class="command">\ev</code> is used
+ with a line number argument, this variable specifies the
+ command-line argument used to pass the starting line number to
+ the user's editor. For editors such as <span class="productname">Emacs</span> or
+ <span class="productname">vi</span>, this is a plus sign. Include a trailing
+ space in the value of the variable if there needs to be space
+ between the option name and the line number. Examples:
+</p><pre class="programlisting">
+PSQL_EDITOR_LINENUMBER_ARG='+'
+PSQL_EDITOR_LINENUMBER_ARG='--line '
+</pre><p>
+ </p><p>
+ The default is <code class="literal">+</code> on Unix systems
+ (corresponding to the default editor <code class="filename">vi</code>,
+ and useful for many other common editors); but there is no
+ default on Windows systems.
+ </p></dd><dt><span class="term"><code class="envar">PSQL_HISTORY</code></span></dt><dd><p>
+ Alternative location for the command history file. Tilde (<code class="literal">~</code>) expansion is performed.
+ </p></dd><dt><span class="term"><code class="envar">PSQL_PAGER</code><br /></span><span class="term"><code class="envar">PAGER</code></span></dt><dd><p>
+ If a query's results do not fit on the screen, they are piped
+ through this command. Typical values are <code class="literal">more</code>
+ or <code class="literal">less</code>.
+ Use of the pager can be disabled by setting <code class="envar">PSQL_PAGER</code>
+ or <code class="envar">PAGER</code> to an empty string, or by adjusting the
+ pager-related options of the <code class="command">\pset</code> command.
+ These variables are examined in the order listed;
+ the first that is set is used.
+ If neither of them is set, the default is to use <code class="literal">more</code> on most
+ platforms, but <code class="literal">less</code> on Cygwin.
+ </p></dd><dt><span class="term"><code class="envar">PSQL_WATCH_PAGER</code></span></dt><dd><p>
+ When a query is executed repeatedly with the <code class="command">\watch</code>
+ command, a pager is not used by default. This behavior can be changed
+ by setting <code class="envar">PSQL_WATCH_PAGER</code> to a pager command, on Unix
+ systems. The <code class="literal">pspg</code> pager (not part of
+ <span class="productname">PostgreSQL</span> but available in many open source
+ software distributions) can display the output of
+ <code class="command">\watch</code> if started with the option
+ <code class="literal">--stream</code>.
+ </p></dd><dt><span class="term"><code class="envar">PSQLRC</code></span></dt><dd><p>
+ Alternative location of the user's <code class="filename">.psqlrc</code> file. Tilde (<code class="literal">~</code>) expansion is performed.
+ </p></dd><dt><span class="term"><code class="envar">SHELL</code></span></dt><dd><p>
+ Command executed by the <code class="command">\!</code> command.
+ </p></dd><dt><span class="term"><code class="envar">TMPDIR</code></span></dt><dd><p>
+ Directory for storing temporary files. The default is
+ <code class="filename">/tmp</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.20.10"><h2>Files</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="filename">psqlrc</code> and <code class="filename">~/.psqlrc</code></span></dt><dd><p>
+ Unless it is passed an <code class="option">-X</code> option,
+ <span class="application">psql</span> attempts to read and execute commands
+ from the system-wide startup file (<code class="filename">psqlrc</code>) and then
+ the user's personal startup file (<code class="filename">~/.psqlrc</code>), after
+ connecting to the database but before accepting normal commands.
+ These files can be used to set up the client and/or the server to taste,
+ typically with <code class="command">\set</code> and <code class="command">SET</code>
+ commands.
+ </p><p>
+ The system-wide startup file is named <code class="filename">psqlrc</code>.
+ By default it is
+ sought in the installation's <span class="quote">“<span class="quote">system configuration</span>”</span> directory,
+ which is most reliably identified by running <code class="literal">pg_config
+ --sysconfdir</code>.
+ Typically this directory will be <code class="filename">../etc/</code>
+ relative to the directory containing
+ the <span class="productname">PostgreSQL</span> executables.
+ The directory to look in can be set explicitly via
+ the <code class="envar">PGSYSCONFDIR</code> environment variable.
+ </p><p>
+ The user's personal startup file is named <code class="filename">.psqlrc</code>
+ and is sought in the invoking user's home directory.
+ On Windows the personal startup file is instead named
+ <code class="filename">%APPDATA%\postgresql\psqlrc.conf</code>.
+ In either case, this default file path can be overridden by setting
+ the <code class="envar">PSQLRC</code> environment variable.
+ </p><p>
+ Both the system-wide startup file and the user's personal startup file
+ can be made <span class="application">psql</span>-version-specific
+ by appending a dash and the <span class="productname">PostgreSQL</span>
+ major or minor release identifier to the file name,
+ for example <code class="filename">~/.psqlrc-15</code> or
+ <code class="filename">~/.psqlrc-15.4</code>.
+ The most specific version-matching file will be read in preference
+ to a non-version-specific file.
+ These version suffixes are added after determining the file path
+ as explained above.
+ </p></dd><dt><span class="term"><code class="filename">.psql_history</code></span></dt><dd><p>
+ The command-line history is stored in the file
+ <code class="filename">~/.psql_history</code>, or
+ <code class="filename">%APPDATA%\postgresql\psql_history</code> on Windows.
+ </p><p>
+ The location of the history file can be set explicitly via
+ the <code class="varname">HISTFILE</code> <span class="application">psql</span> variable or
+ the <code class="envar">PSQL_HISTORY</code> environment variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.4.20.11"><h2>Notes</h2><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><span class="application">psql</span> works best with servers of the same
+ or an older major version. Backslash commands are particularly likely
+ to fail if the server is of a newer version than <span class="application">psql</span>
+ itself. However, backslash commands of the <code class="literal">\d</code> family should
+ work with servers of versions back to 9.2, though not necessarily with
+ servers newer than <span class="application">psql</span> itself. The general
+ functionality of running SQL commands and displaying query results
+ should also work with servers of a newer major version, but this cannot
+ be guaranteed in all cases.
+ </p><p>
+ If you want to use <span class="application">psql</span> to connect to several
+ servers of different major versions, it is recommended that you use the
+ newest version of <span class="application">psql</span>. Alternatively, you
+ can keep around a copy of <span class="application">psql</span> from each
+ major version and be sure to use the version that matches the
+ respective server. But in practice, this additional complication should
+ not be necessary.
+ </p></li><li class="listitem"><p>
+ Before <span class="productname">PostgreSQL</span> 9.6,
+ the <code class="option">-c</code> option implied <code class="option">-X</code>
+ (<code class="option">--no-psqlrc</code>); this is no longer the case.
+ </p></li><li class="listitem"><p>
+ Before <span class="productname">PostgreSQL</span> 8.4,
+ <span class="application">psql</span> allowed the
+ first argument of a single-letter backslash command to start
+ directly after the command, without intervening whitespace.
+ Now, some whitespace is required.
+ </p></li></ul></div></div><div class="refsect1" id="id-1.9.4.20.12"><h2>Notes for Windows Users</h2><p>
+ <span class="application">psql</span> is built as a <span class="quote">“<span class="quote">console
+ application</span>”</span>. Since the Windows console windows use a different
+ encoding than the rest of the system, you must take special care
+ when using 8-bit characters within <span class="application">psql</span>.
+ If <span class="application">psql</span> detects a problematic
+ console code page, it will warn you at startup. To change the
+ console code page, two things are necessary:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Set the code page by entering <strong class="userinput"><code>cmd.exe /c chcp
+ 1252</code></strong>. (1252 is a code page that is appropriate for
+ German; replace it with your value.) If you are using Cygwin,
+ you can put this command in <code class="filename">/etc/profile</code>.
+ </p></li><li class="listitem"><p>
+ Set the console font to <code class="literal">Lucida Console</code>, because the
+ raster font does not work with the ANSI code page.
+ </p></li></ul></div></div><div class="refsect1" id="APP-PSQL-EXAMPLES"><h2>Examples</h2><p>
+ The first example shows how to spread a command over several lines of
+ input. Notice the changing prompt:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>CREATE TABLE my_table (</code></strong>
+testdb(&gt; <strong class="userinput"><code> first integer not null default 0,</code></strong>
+testdb(&gt; <strong class="userinput"><code> second text)</code></strong>
+testdb-&gt; <strong class="userinput"><code>;</code></strong>
+CREATE TABLE
+</pre><p>
+ Now look at the table definition again:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\d my_table</code></strong>
+ Table "public.my_table"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ first | integer | | not null | 0
+ second | text | | |
+</pre><p>
+ Now we change the prompt to something more interesting:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\set PROMPT1 '%n@%m %~%R%# '</code></strong>
+peter@localhost testdb=&gt;
+</pre><p>
+ Let's assume you have filled the table with data and want to take a
+ look at it:
+</p><pre class="programlisting">
+peter@localhost testdb=&gt; SELECT * FROM my_table;
+ first | second
+-------+--------
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+(4 rows)
+</pre><p>
+ You can display tables in different ways by using the
+ <code class="command">\pset</code> command:
+</p><pre class="programlisting">
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset border 2</code></strong>
+Border style is 2.
+peter@localhost testdb=&gt; <strong class="userinput"><code>SELECT * FROM my_table;</code></strong>
++-------+--------+
+| first | second |
++-------+--------+
+| 1 | one |
+| 2 | two |
+| 3 | three |
+| 4 | four |
++-------+--------+
+(4 rows)
+
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset border 0</code></strong>
+Border style is 0.
+peter@localhost testdb=&gt; <strong class="userinput"><code>SELECT * FROM my_table;</code></strong>
+first second
+----- ------
+ 1 one
+ 2 two
+ 3 three
+ 4 four
+(4 rows)
+
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset border 1</code></strong>
+Border style is 1.
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset format csv</code></strong>
+Output format is csv.
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset tuples_only</code></strong>
+Tuples only is on.
+peter@localhost testdb=&gt; <strong class="userinput"><code>SELECT second, first FROM my_table;</code></strong>
+one,1
+two,2
+three,3
+four,4
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset format unaligned</code></strong>
+Output format is unaligned.
+peter@localhost testdb=&gt; <strong class="userinput"><code>\pset fieldsep '\t'</code></strong>
+Field separator is " ".
+peter@localhost testdb=&gt; <strong class="userinput"><code>SELECT second, first FROM my_table;</code></strong>
+one 1
+two 2
+three 3
+four 4
+</pre><p>
+ Alternatively, use the short commands:
+</p><pre class="programlisting">
+peter@localhost testdb=&gt; <strong class="userinput"><code>\a \t \x</code></strong>
+Output format is aligned.
+Tuples only is off.
+Expanded display is on.
+peter@localhost testdb=&gt; <strong class="userinput"><code>SELECT * FROM my_table;</code></strong>
+-[ RECORD 1 ]-
+first | 1
+second | one
+-[ RECORD 2 ]-
+first | 2
+second | two
+-[ RECORD 3 ]-
+first | 3
+second | three
+-[ RECORD 4 ]-
+first | 4
+second | four
+</pre><p>
+ </p><p>
+ Also, these output format options can be set for just one query by using
+ <code class="literal">\g</code>:
+</p><pre class="programlisting">
+peter@localhost testdb=&gt; <strong class="userinput"><code>SELECT * FROM my_table</code></strong>
+peter@localhost testdb-&gt; <strong class="userinput"><code>\g (format=aligned tuples_only=off expanded=on)</code></strong>
+-[ RECORD 1 ]-
+first | 1
+second | one
+-[ RECORD 2 ]-
+first | 2
+second | two
+-[ RECORD 3 ]-
+first | 3
+second | three
+-[ RECORD 4 ]-
+first | 4
+second | four
+</pre><p>
+ </p><p>
+ Here is an example of using the <code class="command">\df</code> command to
+ find only functions with names matching <code class="literal">int*pl</code>
+ and whose second argument is of type <code class="type">bigint</code>:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>\df int*pl * bigint</code></strong>
+ List of functions
+ Schema | Name | Result data type | Argument data types | Type
+------------+---------+------------------+---------------------+------
+ pg_catalog | int28pl | bigint | smallint, bigint | func
+ pg_catalog | int48pl | bigint | integer, bigint | func
+ pg_catalog | int8pl | bigint | bigint, bigint | func
+(3 rows)
+</pre><p>
+ </p><p>
+ When suitable, query results can be shown in a crosstab representation
+ with the <code class="command">\crosstabview</code> command:
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>SELECT first, second, first &gt; 2 AS gt2 FROM my_table;</code></strong>
+ first | second | gt2
+-------+--------+-----
+ 1 | one | f
+ 2 | two | f
+ 3 | three | t
+ 4 | four | t
+(4 rows)
+
+testdb=&gt; <strong class="userinput"><code>\crosstabview first second</code></strong>
+ first | one | two | three | four
+-------+-----+-----+-------+------
+ 1 | f | | |
+ 2 | | f | |
+ 3 | | | t |
+ 4 | | | | t
+(4 rows)
+</pre><p>
+
+This second example shows a multiplication table with rows sorted in reverse
+numerical order and columns with an independent, ascending numerical order.
+</p><pre class="programlisting">
+testdb=&gt; <strong class="userinput"><code>SELECT t1.first as "A", t2.first+100 AS "B", t1.first*(t2.first+100) as "AxB",</code></strong>
+testdb(&gt; <strong class="userinput"><code>row_number() over(order by t2.first) AS ord</code></strong>
+testdb(&gt; <strong class="userinput"><code>FROM my_table t1 CROSS JOIN my_table t2 ORDER BY 1 DESC</code></strong>
+testdb(&gt; <strong class="userinput"><code>\crosstabview "A" "B" "AxB" ord</code></strong>
+ A | 101 | 102 | 103 | 104
+---+-----+-----+-----+-----
+ 4 | 404 | 408 | 412 | 416
+ 3 | 303 | 306 | 309 | 312
+ 2 | 202 | 204 | 206 | 208
+ 1 | 101 | 102 | 103 | 104
+(4 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgverifybackup.html" title="pg_verifybackup">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-reindexdb.html" title="reindexdb">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_verifybackup</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">reindexdb</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-reindexdb.html b/doc/src/sgml/html/app-reindexdb.html
new file mode 100644
index 0000000..2c60bdc
--- /dev/null
+++ b/doc/src/sgml/html/app-reindexdb.html
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>reindexdb</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-psql.html" title="psql" /><link rel="next" href="app-vacuumdb.html" title="vacuumdb" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">reindexdb</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-psql.html" title="psql">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-vacuumdb.html" title="vacuumdb">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-REINDEXDB"><div class="titlepage"></div><a id="id-1.9.4.21.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">reindexdb</span></span></h2><p>reindexdb — reindex a <span class="productname">PostgreSQL</span> database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.21.4.1"><code class="command">reindexdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...]
+ [
+ <code class="option">-S</code> | <code class="option">--schema</code>
+ <em class="replaceable"><code>schema</code></em>
+ ]
+ ...
+ [
+ <code class="option">-t</code> | <code class="option">--table</code>
+ <em class="replaceable"><code>table</code></em>
+ ]
+ ...
+ [
+ <code class="option">-i</code> | <code class="option">--index</code>
+ <em class="replaceable"><code>index</code></em>
+ ]
+ ... [<em class="replaceable"><code>dbname</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.4.21.4.2"><code class="command">reindexdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] <code class="option">-a</code> | <code class="option">--all</code> </p></div><div class="cmdsynopsis"><p id="id-1.9.4.21.4.3"><code class="command">reindexdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] <code class="option">-s</code> | <code class="option">--system</code> [<em class="replaceable"><code>dbname</code></em>]</p></div></div><div class="refsect1" id="id-1.9.4.21.5"><h2>Description</h2><p>
+ <span class="application">reindexdb</span> is a utility for rebuilding indexes
+ in a <span class="productname">PostgreSQL</span> database.
+ </p><p>
+ <span class="application">reindexdb</span> is a wrapper around the SQL
+ command <a class="link" href="sql-reindex.html" title="REINDEX"><code class="command">REINDEX</code></a>.
+ There is no effective difference between reindexing databases via
+ this utility and via other methods for accessing the server.
+ </p></div><div class="refsect1" id="id-1.9.4.21.6"><h2>Options</h2><p>
+ <span class="application">reindexdb</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--all</code></span></dt><dd><p>
+ Reindex all databases.
+ </p></dd><dt><span class="term"><code class="option">--concurrently</code></span></dt><dd><p>
+ Use the <code class="literal">CONCURRENTLY</code> option. See
+ <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a>, where all the caveats of this option
+ are explained in detail.
+ </p></dd><dt><span class="term"><code class="option">[<span class="optional">-d</span>] <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">[<span class="optional">--dbname=</span>]<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to be reindexed,
+ when <code class="option">-a</code>/<code class="option">--all</code> is not used.
+ If this is not specified, the database name is read
+ from the environment variable <code class="envar">PGDATABASE</code>. If
+ that is not set, the user name specified for the connection is
+ used. The <em class="replaceable"><code>dbname</code></em> can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </p></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">reindexdb</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-i <em class="replaceable"><code>index</code></em></code><br /></span><span class="term"><code class="option">--index=<em class="replaceable"><code>index</code></em></code></span></dt><dd><p>
+ Recreate <em class="replaceable"><code>index</code></em> only.
+ Multiple indexes can be recreated by writing multiple
+ <code class="option">-i</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-j <em class="replaceable"><code>njobs</code></em></code><br /></span><span class="term"><code class="option">--jobs=<em class="replaceable"><code>njobs</code></em></code></span></dt><dd><p>
+ Execute the reindex commands in parallel by running
+ <em class="replaceable"><code>njobs</code></em>
+ commands simultaneously. This option may reduce the processing time
+ but it also increases the load on the database server.
+ </p><p>
+ <span class="application">reindexdb</span> will open
+ <em class="replaceable"><code>njobs</code></em> connections to the
+ database, so make sure your <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>
+ setting is high enough to accommodate all connections.
+ </p><p>
+ Note that this option is incompatible with the <code class="option">--index</code>
+ and <code class="option">--system</code> options.
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Do not display progress messages.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--system</code></span></dt><dd><p>
+ Reindex database's system catalogs only.
+ </p></dd><dt><span class="term"><code class="option">-S <em class="replaceable"><code>schema</code></em></code><br /></span><span class="term"><code class="option">--schema=<em class="replaceable"><code>schema</code></em></code></span></dt><dd><p>
+ Reindex <em class="replaceable"><code>schema</code></em> only.
+ Multiple schemas can be reindexed by writing multiple
+ <code class="option">-S</code> switches.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>table</code></em></code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>table</code></em></code></span></dt><dd><p>
+ Reindex <em class="replaceable"><code>table</code></em> only.
+ Multiple tables can be reindexed by writing multiple
+ <code class="option">-t</code> switches.
+ </p></dd><dt><span class="term"><code class="option">--tablespace=<em class="replaceable"><code>tablespace</code></em></code></span></dt><dd><p>
+ Specifies the tablespace where indexes are rebuilt. (This name is
+ processed as a double-quoted identifier.)
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Print detailed information during processing.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">reindexdb</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">reindexdb</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+
+ </p><p>
+ <span class="application">reindexdb</span> also accepts
+ the following command-line arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">reindexdb</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">reindexdb</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">reindexdb</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--maintenance-db=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to to discover which
+ databases should be reindexed,
+ when <code class="option">-a</code>/<code class="option">--all</code> is used.
+ If not specified, the <code class="literal">postgres</code> database will be used,
+ or if that does not exist, <code class="literal">template1</code> will be used.
+ This can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection
+ string</a>. If so, connection string parameters will override any
+ conflicting command line options. Also, connection string parameters
+ other than the database name itself will be re-used when connecting
+ to other databases.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.21.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATABASE</code><br /></span><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.21.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.21.9"><h2>Notes</h2><p>
+ <span class="application">reindexdb</span> might need to connect several
+ times to the <span class="productname">PostgreSQL</span> server, asking
+ for a password each time. It is convenient to have a
+ <code class="filename">~/.pgpass</code> file in such cases. See <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a> for more information.
+ </p></div><div class="refsect1" id="id-1.9.4.21.10"><h2>Examples</h2><p>
+ To reindex the database <code class="literal">test</code>:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>reindexdb test</code></strong>
+</pre><p>
+ </p><p>
+ To reindex the table <code class="literal">foo</code> and the index
+ <code class="literal">bar</code> in a database named <code class="literal">abcd</code>:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>reindexdb --table=foo --index=bar abcd</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.21.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-psql.html" title="psql">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-vacuumdb.html" title="vacuumdb">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">psql</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">vacuumdb</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/app-vacuumdb.html b/doc/src/sgml/html/app-vacuumdb.html
new file mode 100644
index 0000000..71b5d59
--- /dev/null
+++ b/doc/src/sgml/html/app-vacuumdb.html
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>vacuumdb</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-reindexdb.html" title="reindexdb" /><link rel="next" href="reference-server.html" title="PostgreSQL Server Applications" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">vacuumdb</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-reindexdb.html" title="reindexdb">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="reference-server.html" title="PostgreSQL Server Applications">Next</a></td></tr></table><hr /></div><div class="refentry" id="APP-VACUUMDB"><div class="titlepage"></div><a id="id-1.9.4.22.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">vacuumdb</span></span></h2><p>vacuumdb — garbage-collect and analyze a <span class="productname">PostgreSQL</span> database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.22.4.1"><code class="command">vacuumdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...]
+ [
+ <code class="option">-t</code> | <code class="option">--table</code>
+ <em class="replaceable"><code>table</code></em>
+ [( <em class="replaceable"><code>column</code></em> [,...] )]
+ ]
+ ... [<em class="replaceable"><code>dbname</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.4.22.4.2"><code class="command">vacuumdb</code> [<em class="replaceable"><code>connection-option</code></em>...] [<em class="replaceable"><code>option</code></em>...] <code class="option">-a</code> | <code class="option">--all</code> </p></div></div><div class="refsect1" id="id-1.9.4.22.5"><h2>Description</h2><p>
+ <span class="application">vacuumdb</span> is a utility for cleaning a
+ <span class="productname">PostgreSQL</span> database.
+ <span class="application">vacuumdb</span> will also generate internal statistics
+ used by the <span class="productname">PostgreSQL</span> query optimizer.
+ </p><p>
+ <span class="application">vacuumdb</span> is a wrapper around the SQL
+ command <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>.
+ There is no effective difference between vacuuming and analyzing
+ databases via this utility and via other methods for accessing the
+ server.
+ </p></div><div class="refsect1" id="id-1.9.4.22.6"><h2>Options</h2><p>
+ <span class="application">vacuumdb</span> accepts the following command-line arguments:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-a</code><br /></span><span class="term"><code class="option">--all</code></span></dt><dd><p>
+ Vacuum all databases.
+ </p></dd><dt><span class="term"><code class="option">[<span class="optional">-d</span>] <em class="replaceable"><code>dbname</code></em></code><br /></span><span class="term"><code class="option">[<span class="optional">--dbname=</span>]<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to be cleaned or analyzed,
+ when <code class="option">-a</code>/<code class="option">--all</code> is not used.
+ If this is not specified, the database name is read
+ from the environment variable <code class="envar">PGDATABASE</code>. If
+ that is not set, the user name specified for the connection is
+ used. The <em class="replaceable"><code>dbname</code></em> can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection string</a>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </p></dd><dt><span class="term"><code class="option">--disable-page-skipping</code></span></dt><dd><p>
+ Disable skipping pages based on the contents of the visibility map.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 9.6 and later.
+ </p></div></dd><dt><span class="term"><code class="option">-e</code><br /></span><span class="term"><code class="option">--echo</code></span></dt><dd><p>
+ Echo the commands that <span class="application">vacuumdb</span> generates
+ and sends to the server.
+ </p></dd><dt><span class="term"><code class="option">-f</code><br /></span><span class="term"><code class="option">--full</code></span></dt><dd><p>
+ Perform <span class="quote">“<span class="quote">full</span>”</span> vacuuming.
+ </p></dd><dt><span class="term"><code class="option">-F</code><br /></span><span class="term"><code class="option">--freeze</code></span></dt><dd><p>
+ Aggressively <span class="quote">“<span class="quote">freeze</span>”</span> tuples.
+ </p></dd><dt><span class="term"><code class="option">--force-index-cleanup</code></span></dt><dd><p>
+ Always remove index entries pointing to dead tuples.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 12 and later.
+ </p></div></dd><dt><span class="term"><code class="option">-j <em class="replaceable"><code>njobs</code></em></code><br /></span><span class="term"><code class="option">--jobs=<em class="replaceable"><code>njobs</code></em></code></span></dt><dd><p>
+ Execute the vacuum or analyze commands in parallel by running
+ <em class="replaceable"><code>njobs</code></em>
+ commands simultaneously. This option may reduce the processing time
+ but it also increases the load on the database server.
+ </p><p>
+ <span class="application">vacuumdb</span> will open
+ <em class="replaceable"><code>njobs</code></em> connections to the
+ database, so make sure your <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>
+ setting is high enough to accommodate all connections.
+ </p><p>
+ Note that using this mode together with the <code class="option">-f</code>
+ (<code class="literal">FULL</code>) option might cause deadlock failures if
+ certain system catalogs are processed in parallel.
+ </p></dd><dt><span class="term"><code class="option">--min-mxid-age <em class="replaceable"><code>mxid_age</code></em></code></span></dt><dd><p>
+ Only execute the vacuum or analyze commands on tables with a multixact
+ ID age of at least <em class="replaceable"><code>mxid_age</code></em>.
+ This setting is useful for prioritizing tables to process to prevent
+ multixact ID wraparound (see
+ <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND" title="25.1.5.1. Multixacts and Wraparound">Section 25.1.5.1</a>).
+ </p><p>
+ For the purposes of this option, the multixact ID age of a relation is
+ the greatest of the ages of the main relation and its associated
+ <acronym class="acronym">TOAST</acronym> table, if one exists. Since the commands
+ issued by <span class="application">vacuumdb</span> will also process the
+ <acronym class="acronym">TOAST</acronym> table for the relation if necessary, it does
+ not need to be considered separately.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 9.6 and later.
+ </p></div></dd><dt><span class="term"><code class="option">--min-xid-age <em class="replaceable"><code>xid_age</code></em></code></span></dt><dd><p>
+ Only execute the vacuum or analyze commands on tables with a
+ transaction ID age of at least
+ <em class="replaceable"><code>xid_age</code></em>. This setting
+ is useful for prioritizing tables to process to prevent transaction
+ ID wraparound (see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>).
+ </p><p>
+ For the purposes of this option, the transaction ID age of a relation
+ is the greatest of the ages of the main relation and its associated
+ <acronym class="acronym">TOAST</acronym> table, if one exists. Since the commands
+ issued by <span class="application">vacuumdb</span> will also process the
+ <acronym class="acronym">TOAST</acronym> table for the relation if necessary, it does
+ not need to be considered separately.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 9.6 and later.
+ </p></div></dd><dt><span class="term"><code class="option">--no-index-cleanup</code></span></dt><dd><p>
+ Do not remove index entries pointing to dead tuples.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 12 and later.
+ </p></div></dd><dt><span class="term"><code class="option">--no-process-toast</code></span></dt><dd><p>
+ Skip the TOAST table associated with the table to vacuum, if any.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 14 and later.
+ </p></div></dd><dt><span class="term"><code class="option">--no-truncate</code></span></dt><dd><p>
+ Do not truncate empty pages at the end of the table.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 12 and later.
+ </p></div></dd><dt><span class="term"><code class="option">-P <em class="replaceable"><code>parallel_workers</code></em></code><br /></span><span class="term"><code class="option">--parallel=<em class="replaceable"><code>parallel_workers</code></em></code></span></dt><dd><p>
+ Specify the number of parallel workers for <em class="firstterm">parallel vacuum</em>.
+ This allows the vacuum to leverage multiple CPUs to process indexes.
+ See <a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 13 and later.
+ </p></div></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Do not display progress messages.
+ </p></dd><dt><span class="term"><code class="option">--skip-locked</code></span></dt><dd><p>
+ Skip relations that cannot be immediately locked for processing.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This option is only available for servers running
+ <span class="productname">PostgreSQL</span> 12 and later.
+ </p></div></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>table</code></em> [ (<em class="replaceable"><code>column</code></em> [,...]) ]</code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>table</code></em> [ (<em class="replaceable"><code>column</code></em> [,...]) ]</code></span></dt><dd><p>
+ Clean or analyze <em class="replaceable"><code>table</code></em> only.
+ Column names can be specified only in conjunction with
+ the <code class="option">--analyze</code> or <code class="option">--analyze-only</code> options.
+ Multiple tables can be vacuumed by writing multiple
+ <code class="option">-t</code> switches.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If you specify columns, you probably have to escape the parentheses
+ from the shell. (See examples below.)
+ </p></div></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>
+ Print detailed information during processing.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">vacuumdb</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-z</code><br /></span><span class="term"><code class="option">--analyze</code></span></dt><dd><p>
+ Also calculate statistics for use by the optimizer.
+ </p></dd><dt><span class="term"><code class="option">-Z</code><br /></span><span class="term"><code class="option">--analyze-only</code></span></dt><dd><p>
+ Only calculate statistics for use by the optimizer (no vacuum).
+ </p></dd><dt><span class="term"><code class="option">--analyze-in-stages</code></span></dt><dd><p>
+ Only calculate statistics for use by the optimizer (no vacuum),
+ like <code class="option">--analyze-only</code>. Run three
+ stages of analyze; the first stage uses the lowest possible statistics
+ target (see <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a>)
+ to produce usable statistics faster, and subsequent stages build the
+ full statistics.
+ </p><p>
+ This option is only useful to analyze a database that currently has
+ no statistics or has wholly incorrect ones, such as if it is newly
+ populated from a restored dump or by <code class="command">pg_upgrade</code>.
+ Be aware that running with this option in a database with existing
+ statistics may cause the query optimizer choices to become
+ transiently worse due to the low statistics targets of the early
+ stages.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">vacuumdb</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">vacuumdb</span> also accepts
+ the following command-line arguments for connection parameters:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>
+ Specifies the host name of the machine on which the server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>
+ User name to connect as.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <code class="filename">.pgpass</code> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">vacuumdb</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">vacuumdb</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">vacuumdb</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd><dt><span class="term"><code class="option">--maintenance-db=<em class="replaceable"><code>dbname</code></em></code></span></dt><dd><p>
+ Specifies the name of the database to connect to to discover which
+ databases should be vacuumed,
+ when <code class="option">-a</code>/<code class="option">--all</code> is used.
+ If not specified, the <code class="literal">postgres</code> database will be used,
+ or if that does not exist, <code class="literal">template1</code> will be used.
+ This can be a <a class="link" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">connection
+ string</a>. If so, connection string parameters will override any
+ conflicting command line options. Also, connection string parameters
+ other than the database name itself will be re-used when connecting
+ to other databases.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.4.22.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATABASE</code><br /></span><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p></div><div class="refsect1" id="id-1.9.4.22.8"><h2>Diagnostics</h2><p>
+ In case of difficulty, see <a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a>
+ and <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <span class="application">libpq</span> front-end
+ library will apply.
+ </p></div><div class="refsect1" id="id-1.9.4.22.9"><h2>Notes</h2><p>
+ <span class="application">vacuumdb</span> might need to connect several
+ times to the <span class="productname">PostgreSQL</span> server, asking
+ for a password each time. It is convenient to have a
+ <code class="filename">~/.pgpass</code> file in such cases. See <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a> for more information.
+ </p></div><div class="refsect1" id="id-1.9.4.22.10"><h2>Examples</h2><p>
+ To clean the database <code class="literal">test</code>:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>vacuumdb test</code></strong>
+</pre><p>
+ </p><p>
+ To clean and analyze for the optimizer a database named
+ <code class="literal">bigdb</code>:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>vacuumdb --analyze bigdb</code></strong>
+</pre><p>
+ </p><p>
+ To clean a single table
+ <code class="literal">foo</code> in a database named
+ <code class="literal">xyzzy</code>, and analyze a single column
+ <code class="literal">bar</code> of the table for the optimizer:
+</p><pre class="screen">
+<code class="prompt">$ </code><strong class="userinput"><code>vacuumdb --analyze --verbose --table='foo(bar)' xyzzy</code></strong>
+</pre></div><div class="refsect1" id="id-1.9.4.22.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-reindexdb.html" title="reindexdb">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="reference-server.html" title="PostgreSQL Server Applications">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">reindexdb</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> PostgreSQL Server Applications</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/appendix-obsolete.html b/doc/src/sgml/html/appendix-obsolete.html
new file mode 100644
index 0000000..2373e24
--- /dev/null
+++ b/doc/src/sgml/html/appendix-obsolete.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix O. Obsolete or Renamed Features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="color-which.html" title="N.2. Configuring the Colors" /><link rel="next" href="recovery-config.html" title="O.1. recovery.conf file merged into postgresql.conf" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix O. Obsolete or Renamed Features</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="color-which.html" title="N.2. Configuring the Colors">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="recovery-config.html" title="O.1. recovery.conf file merged into postgresql.conf">Next</a></td></tr></table><hr /></div><div class="appendix" id="APPENDIX-OBSOLETE"><div class="titlepage"><div><div><h2 class="title">Appendix O. Obsolete or Renamed Features</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="recovery-config.html">O.1. <code class="filename">recovery.conf</code> file merged into <code class="filename">postgresql.conf</code></a></span></dt><dt><span class="sect1"><a href="default-roles.html">O.2. Default Roles Renamed to Predefined Roles</a></span></dt><dt><span class="sect1"><a href="pgxlogdump.html">O.3. <code class="command">pg_xlogdump</code> renamed to <code class="command">pg_waldump</code></a></span></dt><dt><span class="sect1"><a href="app-pgresetxlog.html">O.4. <code class="command">pg_resetxlog</code> renamed to <code class="command">pg_resetwal</code></a></span></dt><dt><span class="sect1"><a href="app-pgreceivexlog.html">O.5. <code class="command">pg_receivexlog</code> renamed to <code class="command">pg_receivewal</code></a></span></dt></dl></div><p>
+ Functionality is sometimes removed from PostgreSQL, feature, setting
+ and file names sometimes change, or documentation moves to different
+ places. This section directs users coming from old versions of the
+ documentation or from external links to the appropriate new location
+ for the information they need.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="color-which.html" title="N.2. Configuring the Colors">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="recovery-config.html" title="O.1. recovery.conf file merged into postgresql.conf">Next</a></td></tr><tr><td width="40%" align="left" valign="top">N.2. Configuring the Colors </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> O.1. <code class="filename">recovery.conf</code> file merged into <code class="filename">postgresql.conf</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/appendixes.html b/doc/src/sgml/html/appendixes.html
new file mode 100644
index 0000000..1a2dd91
--- /dev/null
+++ b/doc/src/sgml/html/appendixes.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part VIII. Appendixes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object" /><link rel="next" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part VIII. Appendixes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Next</a></td></tr></table><hr /></div><div class="part" id="APPENDIXES"><div class="titlepage"><div><div><h1 class="title">Part VIII. Appendixes</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="appendix"><a href="errcodes-appendix.html">A. <span class="productname">PostgreSQL</span> Error Codes</a></span></dt><dt><span class="appendix"><a href="datetime-appendix.html">B. Date/Time Support</a></span></dt><dd><dl><dt><span class="sect1"><a href="datetime-input-rules.html">B.1. Date/Time Input Interpretation</a></span></dt><dt><span class="sect1"><a href="datetime-invalid-input.html">B.2. Handling of Invalid or Ambiguous Timestamps</a></span></dt><dt><span class="sect1"><a href="datetime-keywords.html">B.3. Date/Time Key Words</a></span></dt><dt><span class="sect1"><a href="datetime-config-files.html">B.4. Date/Time Configuration Files</a></span></dt><dt><span class="sect1"><a href="datetime-posix-timezone-specs.html">B.5. <acronym class="acronym">POSIX</acronym> Time Zone Specifications</a></span></dt><dt><span class="sect1"><a href="datetime-units-history.html">B.6. History of Units</a></span></dt><dt><span class="sect1"><a href="datetime-julian-dates.html">B.7. Julian Dates</a></span></dt></dl></dd><dt><span class="appendix"><a href="sql-keywords-appendix.html">C. <acronym class="acronym">SQL</acronym> Key Words</a></span></dt><dt><span class="appendix"><a href="features.html">D. SQL Conformance</a></span></dt><dd><dl><dt><span class="sect1"><a href="features-sql-standard.html">D.1. Supported Features</a></span></dt><dt><span class="sect1"><a href="unsupported-features-sql-standard.html">D.2. Unsupported Features</a></span></dt><dt><span class="sect1"><a href="xml-limits-conformance.html">D.3. XML Limits and Conformance to SQL/XML</a></span></dt></dl></dd><dt><span class="appendix"><a href="release.html">E. Release Notes</a></span></dt><dd><dl><dt><span class="sect1"><a href="release-15-4.html">E.1. Release 15.4</a></span></dt><dt><span class="sect1"><a href="release-15-3.html">E.2. Release 15.3</a></span></dt><dt><span class="sect1"><a href="release-15-2.html">E.3. Release 15.2</a></span></dt><dt><span class="sect1"><a href="release-15-1.html">E.4. Release 15.1</a></span></dt><dt><span class="sect1"><a href="release-15.html">E.5. Release 15</a></span></dt><dt><span class="sect1"><a href="release-prior.html">E.6. Prior Releases</a></span></dt></dl></dd><dt><span class="appendix"><a href="contrib.html">F. Additional Supplied Modules</a></span></dt><dd><dl><dt><span class="sect1"><a href="adminpack.html">F.1. adminpack</a></span></dt><dt><span class="sect1"><a href="amcheck.html">F.2. amcheck</a></span></dt><dt><span class="sect1"><a href="auth-delay.html">F.3. auth_delay</a></span></dt><dt><span class="sect1"><a href="auto-explain.html">F.4. auto_explain</a></span></dt><dt><span class="sect1"><a href="basebackup-to-shell.html">F.5. basebackup_to_shell</a></span></dt><dt><span class="sect1"><a href="basic-archive.html">F.6. basic_archive</a></span></dt><dt><span class="sect1"><a href="bloom.html">F.7. bloom</a></span></dt><dt><span class="sect1"><a href="btree-gin.html">F.8. btree_gin</a></span></dt><dt><span class="sect1"><a href="btree-gist.html">F.9. btree_gist</a></span></dt><dt><span class="sect1"><a href="citext.html">F.10. citext</a></span></dt><dt><span class="sect1"><a href="cube.html">F.11. cube</a></span></dt><dt><span class="sect1"><a href="dblink.html">F.12. dblink</a></span></dt><dt><span class="sect1"><a href="dict-int.html">F.13. dict_int</a></span></dt><dt><span class="sect1"><a href="dict-xsyn.html">F.14. dict_xsyn</a></span></dt><dt><span class="sect1"><a href="earthdistance.html">F.15. earthdistance</a></span></dt><dt><span class="sect1"><a href="file-fdw.html">F.16. file_fdw</a></span></dt><dt><span class="sect1"><a href="fuzzystrmatch.html">F.17. fuzzystrmatch</a></span></dt><dt><span class="sect1"><a href="hstore.html">F.18. hstore</a></span></dt><dt><span class="sect1"><a href="intagg.html">F.19. intagg</a></span></dt><dt><span class="sect1"><a href="intarray.html">F.20. intarray</a></span></dt><dt><span class="sect1"><a href="isn.html">F.21. isn</a></span></dt><dt><span class="sect1"><a href="lo.html">F.22. lo</a></span></dt><dt><span class="sect1"><a href="ltree.html">F.23. ltree</a></span></dt><dt><span class="sect1"><a href="oldsnapshot.html">F.24. old_snapshot</a></span></dt><dt><span class="sect1"><a href="pageinspect.html">F.25. pageinspect</a></span></dt><dt><span class="sect1"><a href="passwordcheck.html">F.26. passwordcheck</a></span></dt><dt><span class="sect1"><a href="pgbuffercache.html">F.27. pg_buffercache</a></span></dt><dt><span class="sect1"><a href="pgcrypto.html">F.28. pgcrypto</a></span></dt><dt><span class="sect1"><a href="pgfreespacemap.html">F.29. pg_freespacemap</a></span></dt><dt><span class="sect1"><a href="pgprewarm.html">F.30. pg_prewarm</a></span></dt><dt><span class="sect1"><a href="pgrowlocks.html">F.31. pgrowlocks</a></span></dt><dt><span class="sect1"><a href="pgstatstatements.html">F.32. pg_stat_statements</a></span></dt><dt><span class="sect1"><a href="pgstattuple.html">F.33. pgstattuple</a></span></dt><dt><span class="sect1"><a href="pgsurgery.html">F.34. pg_surgery</a></span></dt><dt><span class="sect1"><a href="pgtrgm.html">F.35. pg_trgm</a></span></dt><dt><span class="sect1"><a href="pgvisibility.html">F.36. pg_visibility</a></span></dt><dt><span class="sect1"><a href="pgwalinspect.html">F.37. pg_walinspect</a></span></dt><dt><span class="sect1"><a href="postgres-fdw.html">F.38. postgres_fdw</a></span></dt><dt><span class="sect1"><a href="seg.html">F.39. seg</a></span></dt><dt><span class="sect1"><a href="sepgsql.html">F.40. sepgsql</a></span></dt><dt><span class="sect1"><a href="contrib-spi.html">F.41. spi</a></span></dt><dt><span class="sect1"><a href="sslinfo.html">F.42. sslinfo</a></span></dt><dt><span class="sect1"><a href="tablefunc.html">F.43. tablefunc</a></span></dt><dt><span class="sect1"><a href="tcn.html">F.44. tcn</a></span></dt><dt><span class="sect1"><a href="test-decoding.html">F.45. test_decoding</a></span></dt><dt><span class="sect1"><a href="tsm-system-rows.html">F.46. tsm_system_rows</a></span></dt><dt><span class="sect1"><a href="tsm-system-time.html">F.47. tsm_system_time</a></span></dt><dt><span class="sect1"><a href="unaccent.html">F.48. unaccent</a></span></dt><dt><span class="sect1"><a href="uuid-ossp.html">F.49. uuid-ossp</a></span></dt><dt><span class="sect1"><a href="xml2.html">F.50. xml2</a></span></dt></dl></dd><dt><span class="appendix"><a href="contrib-prog.html">G. Additional Supplied Programs</a></span></dt><dd><dl><dt><span class="sect1"><a href="contrib-prog-client.html">G.1. Client Applications</a></span></dt><dt><span class="sect1"><a href="contrib-prog-server.html">G.2. Server Applications</a></span></dt></dl></dd><dt><span class="appendix"><a href="external-projects.html">H. External Projects</a></span></dt><dd><dl><dt><span class="sect1"><a href="external-interfaces.html">H.1. Client Interfaces</a></span></dt><dt><span class="sect1"><a href="external-admin-tools.html">H.2. Administration Tools</a></span></dt><dt><span class="sect1"><a href="external-pl.html">H.3. Procedural Languages</a></span></dt><dt><span class="sect1"><a href="external-extensions.html">H.4. Extensions</a></span></dt></dl></dd><dt><span class="appendix"><a href="sourcerepo.html">I. The Source Code Repository</a></span></dt><dd><dl><dt><span class="sect1"><a href="git.html">I.1. Getting the Source via <span class="productname">Git</span></a></span></dt></dl></dd><dt><span class="appendix"><a href="docguide.html">J. Documentation</a></span></dt><dd><dl><dt><span class="sect1"><a href="docguide-docbook.html">J.1. DocBook</a></span></dt><dt><span class="sect1"><a href="docguide-toolsets.html">J.2. Tool Sets</a></span></dt><dt><span class="sect1"><a href="docguide-build.html">J.3. Building the Documentation</a></span></dt><dt><span class="sect1"><a href="docguide-authoring.html">J.4. Documentation Authoring</a></span></dt><dt><span class="sect1"><a href="docguide-style.html">J.5. Style Guide</a></span></dt></dl></dd><dt><span class="appendix"><a href="limits.html">K. <span class="productname">PostgreSQL</span> Limits</a></span></dt><dt><span class="appendix"><a href="acronyms.html">L. Acronyms</a></span></dt><dt><span class="appendix"><a href="glossary.html">M. Glossary</a></span></dt><dt><span class="appendix"><a href="color.html">N. Color Support</a></span></dt><dd><dl><dt><span class="sect1"><a href="color-when.html">N.1. When Color is Used</a></span></dt><dt><span class="sect1"><a href="color-which.html">N.2. Configuring the Colors</a></span></dt></dl></dd><dt><span class="appendix"><a href="appendix-obsolete.html">O. Obsolete or Renamed Features</a></span></dt><dd><dl><dt><span class="sect1"><a href="recovery-config.html">O.1. <code class="filename">recovery.conf</code> file merged into <code class="filename">postgresql.conf</code></a></span></dt><dt><span class="sect1"><a href="default-roles.html">O.2. Default Roles Renamed to Predefined Roles</a></span></dt><dt><span class="sect1"><a href="pgxlogdump.html">O.3. <code class="command">pg_xlogdump</code> renamed to <code class="command">pg_waldump</code></a></span></dt><dt><span class="sect1"><a href="app-pgresetxlog.html">O.4. <code class="command">pg_resetxlog</code> renamed to <code class="command">pg_resetwal</code></a></span></dt><dt><span class="sect1"><a href="app-pgreceivexlog.html">O.5. <code class="command">pg_receivexlog</code> renamed to <code class="command">pg_receivewal</code></a></span></dt></dl></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">76.3. Backup Manifest WAL Range Object </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix A. <span class="productname">PostgreSQL</span> Error Codes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/applevel-consistency.html b/doc/src/sgml/html/applevel-consistency.html
new file mode 100644
index 0000000..1e43f83
--- /dev/null
+++ b/doc/src/sgml/html/applevel-consistency.html
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.4. Data Consistency Checks at the Application Level</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="explicit-locking.html" title="13.3. Explicit Locking" /><link rel="next" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.4. Data Consistency Checks at the Application Level</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="explicit-locking.html" title="13.3. Explicit Locking">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling">Next</a></td></tr></table><hr /></div><div class="sect1" id="APPLEVEL-CONSISTENCY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.4. Data Consistency Checks at the Application Level</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="applevel-consistency.html#SERIALIZABLE-CONSISTENCY">13.4.1. Enforcing Consistency with Serializable Transactions</a></span></dt><dt><span class="sect2"><a href="applevel-consistency.html#NON-SERIALIZABLE-CONSISTENCY">13.4.2. Enforcing Consistency with Explicit Blocking Locks</a></span></dt></dl></div><p>
+ It is very difficult to enforce business rules regarding data integrity
+ using Read Committed transactions because the view of the data is
+ shifting with each statement, and even a single statement may not
+ restrict itself to the statement's snapshot if a write conflict occurs.
+ </p><p>
+ While a Repeatable Read transaction has a stable view of the data
+ throughout its execution, there is a subtle issue with using
+ <acronym class="acronym">MVCC</acronym> snapshots for data consistency checks, involving
+ something known as <em class="firstterm">read/write conflicts</em>.
+ If one transaction writes data and a concurrent transaction attempts
+ to read the same data (whether before or after the write), it cannot
+ see the work of the other transaction. The reader then appears to have
+ executed first regardless of which started first or which committed
+ first. If that is as far as it goes, there is no problem, but
+ if the reader also writes data which is read by a concurrent transaction
+ there is now a transaction which appears to have run before either of
+ the previously mentioned transactions. If the transaction which appears
+ to have executed last actually commits first, it is very easy for a
+ cycle to appear in a graph of the order of execution of the transactions.
+ When such a cycle appears, integrity checks will not work correctly
+ without some help.
+ </p><p>
+ As mentioned in <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a>, Serializable
+ transactions are just Repeatable Read transactions which add
+ nonblocking monitoring for dangerous patterns of read/write conflicts.
+ When a pattern is detected which could cause a cycle in the apparent
+ order of execution, one of the transactions involved is rolled back to
+ break the cycle.
+ </p><div class="sect2" id="SERIALIZABLE-CONSISTENCY"><div class="titlepage"><div><div><h3 class="title">13.4.1. Enforcing Consistency with Serializable Transactions</h3></div></div></div><p>
+ If the Serializable transaction isolation level is used for all writes
+ and for all reads which need a consistent view of the data, no other
+ effort is required to ensure consistency. Software from other
+ environments which is written to use serializable transactions to
+ ensure consistency should <span class="quote">“<span class="quote">just work</span>”</span> in this regard in
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ When using this technique, it will avoid creating an unnecessary burden
+ for application programmers if the application software goes through a
+ framework which automatically retries transactions which are rolled
+ back with a serialization failure. It may be a good idea to set
+ <code class="literal">default_transaction_isolation</code> to <code class="literal">serializable</code>.
+ It would also be wise to take some action to ensure that no other
+ transaction isolation level is used, either inadvertently or to
+ subvert integrity checks, through checks of the transaction isolation
+ level in triggers.
+ </p><p>
+ See <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a> for performance suggestions.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ This level of integrity protection using Serializable transactions
+ does not yet extend to hot standby mode (<a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a>).
+ Because of that, those using hot standby may want to use Repeatable
+ Read and explicit locking on the primary.
+ </p></div></div><div class="sect2" id="NON-SERIALIZABLE-CONSISTENCY"><div class="titlepage"><div><div><h3 class="title">13.4.2. Enforcing Consistency with Explicit Blocking Locks</h3></div></div></div><p>
+ When non-serializable writes are possible,
+ to ensure the current validity of a row and protect it against
+ concurrent updates one must use <code class="command">SELECT FOR UPDATE</code>,
+ <code class="command">SELECT FOR SHARE</code>, or an appropriate <code class="command">LOCK
+ TABLE</code> statement. (<code class="command">SELECT FOR UPDATE</code>
+ and <code class="command">SELECT FOR SHARE</code> lock just the
+ returned rows against concurrent updates, while <code class="command">LOCK
+ TABLE</code> locks the whole table.) This should be taken into
+ account when porting applications to
+ <span class="productname">PostgreSQL</span> from other environments.
+ </p><p>
+ Also of note to those converting from other environments is the fact
+ that <code class="command">SELECT FOR UPDATE</code> does not ensure that a
+ concurrent transaction will not update or delete a selected row.
+ To do that in <span class="productname">PostgreSQL</span> you must actually
+ update the row, even if no values need to be changed.
+ <code class="command">SELECT FOR UPDATE</code> <span class="emphasis"><em>temporarily blocks</em></span>
+ other transactions from acquiring the same lock or executing an
+ <code class="command">UPDATE</code> or <code class="command">DELETE</code> which would
+ affect the locked row, but once the transaction holding this lock
+ commits or rolls back, a blocked transaction will proceed with the
+ conflicting operation unless an actual <code class="command">UPDATE</code> of
+ the row was performed while the lock was held.
+ </p><p>
+ Global validity checks require extra thought under
+ non-serializable <acronym class="acronym">MVCC</acronym>.
+ For example, a banking application might wish to check that the sum of
+ all credits in one table equals the sum of debits in another table,
+ when both tables are being actively updated. Comparing the results of two
+ successive <code class="literal">SELECT sum(...)</code> commands will not work reliably in
+ Read Committed mode, since the second query will likely include the results
+ of transactions not counted by the first. Doing the two sums in a
+ single repeatable read transaction will give an accurate picture of only the
+ effects of transactions that committed before the repeatable read transaction
+ started — but one might legitimately wonder whether the answer is still
+ relevant by the time it is delivered. If the repeatable read transaction
+ itself applied some changes before trying to make the consistency check,
+ the usefulness of the check becomes even more debatable, since now it
+ includes some but not all post-transaction-start changes. In such cases
+ a careful person might wish to lock all tables needed for the check,
+ in order to get an indisputable picture of current reality. A
+ <code class="literal">SHARE</code> mode (or higher) lock guarantees that there are no
+ uncommitted changes in the locked table, other than those of the current
+ transaction.
+ </p><p>
+ Note also that if one is relying on explicit locking to prevent concurrent
+ changes, one should either use Read Committed mode, or in Repeatable Read
+ mode be careful to obtain
+ locks before performing queries. A lock obtained by a
+ repeatable read transaction guarantees that no other transactions modifying
+ the table are still running, but if the snapshot seen by the
+ transaction predates obtaining the lock, it might predate some now-committed
+ changes in the table. A repeatable read transaction's snapshot is actually
+ frozen at the start of its first query or data-modification command
+ (<code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>, or
+ <code class="literal">MERGE</code>), so it is possible to obtain locks explicitly
+ before the snapshot is frozen.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="explicit-locking.html" title="13.3. Explicit Locking">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.3. Explicit Locking </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.5. Serialization Failure Handling</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/archive-module-callbacks.html b/doc/src/sgml/html/archive-module-callbacks.html
new file mode 100644
index 0000000..7a78b17
--- /dev/null
+++ b/doc/src/sgml/html/archive-module-callbacks.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>51.2. Archive Module Callbacks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="archive-module-init.html" title="51.1. Initialization Functions" /><link rel="next" href="reference.html" title="Part VI. Reference" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">51.2. Archive Module Callbacks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="archive-module-init.html" title="51.1. Initialization Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="archive-modules.html" title="Chapter 51. Archive Modules">Up</a></td><th width="60%" align="center">Chapter 51. Archive Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="reference.html" title="Part VI. Reference">Next</a></td></tr></table><hr /></div><div class="sect1" id="ARCHIVE-MODULE-CALLBACKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">51.2. Archive Module Callbacks</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="archive-module-callbacks.html#ARCHIVE-MODULE-CHECK">51.2.1. Check Callback</a></span></dt><dt><span class="sect2"><a href="archive-module-callbacks.html#ARCHIVE-MODULE-ARCHIVE">51.2.2. Archive Callback</a></span></dt><dt><span class="sect2"><a href="archive-module-callbacks.html#ARCHIVE-MODULE-SHUTDOWN">51.2.3. Shutdown Callback</a></span></dt></dl></div><p>
+ The archive callbacks define the actual archiving behavior of the module.
+ The server will call them as required to process each individual WAL file.
+ </p><div class="sect2" id="ARCHIVE-MODULE-CHECK"><div class="titlepage"><div><div><h3 class="title">51.2.1. Check Callback</h3></div></div></div><p>
+ The <code class="function">check_configured_cb</code> callback is called to determine
+ whether the module is fully configured and ready to accept WAL files (e.g.,
+ its configuration parameters are set to valid values). If no
+ <code class="function">check_configured_cb</code> is defined, the server always
+ assumes the module is configured.
+
+</p><pre class="programlisting">
+typedef bool (*ArchiveCheckConfiguredCB) (void);
+</pre><p>
+
+ If <code class="literal">true</code> is returned, the server will proceed with
+ archiving the file by calling the <code class="function">archive_file_cb</code>
+ callback. If <code class="literal">false</code> is returned, archiving will not
+ proceed, and the archiver will emit the following message to the server log:
+</p><pre class="screen">
+WARNING: archive_mode enabled, yet archiving is not configured
+</pre><p>
+ In the latter case, the server will periodically call this function, and
+ archiving will proceed only when it returns <code class="literal">true</code>.
+ </p></div><div class="sect2" id="ARCHIVE-MODULE-ARCHIVE"><div class="titlepage"><div><div><h3 class="title">51.2.2. Archive Callback</h3></div></div></div><p>
+ The <code class="function">archive_file_cb</code> callback is called to archive a
+ single WAL file.
+
+</p><pre class="programlisting">
+typedef bool (*ArchiveFileCB) (const char *file, const char *path);
+</pre><p>
+
+ If <code class="literal">true</code> is returned, the server proceeds as if the file
+ was successfully archived, which may include recycling or removing the
+ original WAL file. If <code class="literal">false</code> is returned, the server will
+ keep the original WAL file and retry archiving later.
+ <em class="replaceable"><code>file</code></em> will contain just the file name of the WAL
+ file to archive, while <em class="replaceable"><code>path</code></em> contains the full
+ path of the WAL file (including the file name).
+ </p></div><div class="sect2" id="ARCHIVE-MODULE-SHUTDOWN"><div class="titlepage"><div><div><h3 class="title">51.2.3. Shutdown Callback</h3></div></div></div><p>
+ The <code class="function">shutdown_cb</code> callback is called when the archiver
+ process exits (e.g., after an error) or the value of
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> changes. If no
+ <code class="function">shutdown_cb</code> is defined, no special action is taken in
+ these situations.
+
+</p><pre class="programlisting">
+typedef void (*ArchiveShutdownCB) (void);
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="archive-module-init.html" title="51.1. Initialization Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="archive-modules.html" title="Chapter 51. Archive Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="reference.html" title="Part VI. Reference">Next</a></td></tr><tr><td width="40%" align="left" valign="top">51.1. Initialization Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part VI. Reference</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/archive-module-init.html b/doc/src/sgml/html/archive-module-init.html
new file mode 100644
index 0000000..ca01972
--- /dev/null
+++ b/doc/src/sgml/html/archive-module-init.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>51.1. Initialization Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="archive-modules.html" title="Chapter 51. Archive Modules" /><link rel="next" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">51.1. Initialization Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="archive-modules.html" title="Chapter 51. Archive Modules">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="archive-modules.html" title="Chapter 51. Archive Modules">Up</a></td><th width="60%" align="center">Chapter 51. Archive Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks">Next</a></td></tr></table><hr /></div><div class="sect1" id="ARCHIVE-MODULE-INIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">51.1. Initialization Functions</h2></div></div></div><a id="id-1.8.16.7.2" class="indexterm"></a><p>
+ An archive library is loaded by dynamically loading a shared library with the
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a>'s name as the library base name. The
+ normal library search path is used to locate the library. To provide the
+ required archive module callbacks and to indicate that the library is
+ actually an archive module, it needs to provide a function named
+ <code class="function">_PG_archive_module_init</code>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions.
+
+</p><pre class="programlisting">
+typedef struct ArchiveModuleCallbacks
+{
+ ArchiveCheckConfiguredCB check_configured_cb;
+ ArchiveFileCB archive_file_cb;
+ ArchiveShutdownCB shutdown_cb;
+} ArchiveModuleCallbacks;
+typedef void (*ArchiveModuleInit) (struct ArchiveModuleCallbacks *cb);
+</pre><p>
+
+ Only the <code class="function">archive_file_cb</code> callback is required. The
+ others are optional.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="archive-modules.html" title="Chapter 51. Archive Modules">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="archive-modules.html" title="Chapter 51. Archive Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 51. Archive Modules </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 51.2. Archive Module Callbacks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/archive-modules.html b/doc/src/sgml/html/archive-modules.html
new file mode 100644
index 0000000..4c0bbc4
--- /dev/null
+++ b/doc/src/sgml/html/archive-modules.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 51. Archive Modules</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking" /><link rel="next" href="archive-module-init.html" title="51.1. Initialization Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 51. Archive Modules</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="archive-module-init.html" title="51.1. Initialization Functions">Next</a></td></tr></table><hr /></div><div class="chapter" id="ARCHIVE-MODULES"><div class="titlepage"><div><div><h2 class="title">Chapter 51. Archive Modules</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="archive-module-init.html">51.1. Initialization Functions</a></span></dt><dt><span class="sect1"><a href="archive-module-callbacks.html">51.2. Archive Module Callbacks</a></span></dt><dd><dl><dt><span class="sect2"><a href="archive-module-callbacks.html#ARCHIVE-MODULE-CHECK">51.2.1. Check Callback</a></span></dt><dt><span class="sect2"><a href="archive-module-callbacks.html#ARCHIVE-MODULE-ARCHIVE">51.2.2. Archive Callback</a></span></dt><dt><span class="sect2"><a href="archive-module-callbacks.html#ARCHIVE-MODULE-SHUTDOWN">51.2.3. Shutdown Callback</a></span></dt></dl></dd></dl></div><a id="id-1.8.16.2" class="indexterm"></a><p>
+ PostgreSQL provides infrastructure to create custom modules for continuous
+ archiving (see <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>). While archiving via
+ a shell command (i.e., <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a>) is much
+ simpler, a custom archive module will often be considerably more robust and
+ performant.
+ </p><p>
+ When a custom <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> is configured, PostgreSQL
+ will submit completed WAL files to the module, and the server will avoid
+ recycling or removing these WAL files until the module indicates that the files
+ were successfully archived. It is ultimately up to the module to decide what
+ to do with each WAL file, but many recommendations are listed at
+ <a class="xref" href="continuous-archiving.html#BACKUP-ARCHIVING-WAL" title="26.3.1. Setting Up WAL Archiving">Section 26.3.1</a>.
+ </p><p>
+ Archiving modules must at least consist of an initialization function (see
+ <a class="xref" href="archive-module-init.html" title="51.1. Initialization Functions">Section 51.1</a>) and the required callbacks (see
+ <a class="xref" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks">Section 51.2</a>). However, archive modules are
+ also permitted to do much more (e.g., declare GUCs and register background
+ workers).
+ </p><p>
+ The <code class="filename">contrib/basic_archive</code> module contains a working
+ example, which demonstrates some useful techniques.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="archive-module-init.html" title="51.1. Initialization Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 50. Replication Progress Tracking </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 51.1. Initialization Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/arrays.html b/doc/src/sgml/html/arrays.html
new file mode 100644
index 0000000..948fbeb
--- /dev/null
+++ b/doc/src/sgml/html/arrays.html
@@ -0,0 +1,647 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.15. Arrays</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-json.html" title="8.14. JSON Types" /><link rel="next" href="rowtypes.html" title="8.16. Composite Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.15. Arrays</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-json.html" title="8.14. JSON Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rowtypes.html" title="8.16. Composite Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="ARRAYS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.15. Arrays</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="arrays.html#ARRAYS-DECLARATION">8.15.1. Declaration of Array Types</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-INPUT">8.15.2. Array Value Input</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-ACCESSING">8.15.3. Accessing Arrays</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-MODIFYING">8.15.4. Modifying Arrays</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-SEARCHING">8.15.5. Searching in Arrays</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-IO">8.15.6. Array Input and Output Syntax</a></span></dt></dl></div><a id="id-1.5.7.23.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> allows columns of a table to be
+ defined as variable-length multidimensional arrays. Arrays of any
+ built-in or user-defined base type, enum type, composite type, range type,
+ or domain can be created.
+ </p><div class="sect2" id="ARRAYS-DECLARATION"><div class="titlepage"><div><div><h3 class="title">8.15.1. Declaration of Array Types</h3></div></div></div><a id="id-1.5.7.23.4.2" class="indexterm"></a><p>
+ To illustrate the use of array types, we create this table:
+</p><pre class="programlisting">
+CREATE TABLE sal_emp (
+ name text,
+ pay_by_quarter integer[],
+ schedule text[][]
+);
+</pre><p>
+ As shown, an array data type is named by appending square brackets
+ (<code class="literal">[]</code>) to the data type name of the array elements. The
+ above command will create a table named
+ <code class="structname">sal_emp</code> with a column of type
+ <code class="type">text</code> (<code class="structfield">name</code>), a
+ one-dimensional array of type <code class="type">integer</code>
+ (<code class="structfield">pay_by_quarter</code>), which represents the
+ employee's salary by quarter, and a two-dimensional array of
+ <code class="type">text</code> (<code class="structfield">schedule</code>), which
+ represents the employee's weekly schedule.
+ </p><p>
+ The syntax for <code class="command">CREATE TABLE</code> allows the exact size of
+ arrays to be specified, for example:
+
+</p><pre class="programlisting">
+CREATE TABLE tictactoe (
+ squares integer[3][3]
+);
+</pre><p>
+
+ However, the current implementation ignores any supplied array size
+ limits, i.e., the behavior is the same as for arrays of unspecified
+ length.
+ </p><p>
+ The current implementation does not enforce the declared
+ number of dimensions either. Arrays of a particular element type are
+ all considered to be of the same type, regardless of size or number
+ of dimensions. So, declaring the array size or number of dimensions in
+ <code class="command">CREATE TABLE</code> is simply documentation; it does not
+ affect run-time behavior.
+ </p><p>
+ An alternative syntax, which conforms to the SQL standard by using
+ the keyword <code class="literal">ARRAY</code>, can be used for one-dimensional arrays.
+ <code class="structfield">pay_by_quarter</code> could have been defined
+ as:
+</p><pre class="programlisting">
+ pay_by_quarter integer ARRAY[4],
+</pre><p>
+ Or, if no array size is to be specified:
+</p><pre class="programlisting">
+ pay_by_quarter integer ARRAY,
+</pre><p>
+ As before, however, <span class="productname">PostgreSQL</span> does not enforce the
+ size restriction in any case.
+ </p></div><div class="sect2" id="ARRAYS-INPUT"><div class="titlepage"><div><div><h3 class="title">8.15.2. Array Value Input</h3></div></div></div><a id="id-1.5.7.23.5.2" class="indexterm"></a><p>
+ To write an array value as a literal constant, enclose the element
+ values within curly braces and separate them by commas. (If you
+ know C, this is not unlike the C syntax for initializing
+ structures.) You can put double quotes around any element value,
+ and must do so if it contains commas or curly braces. (More
+ details appear below.) Thus, the general format of an array
+ constant is the following:
+</p><pre class="synopsis">
+'{ <em class="replaceable"><code>val1</code></em> <em class="replaceable"><code>delim</code></em> <em class="replaceable"><code>val2</code></em> <em class="replaceable"><code>delim</code></em> ... }'
+</pre><p>
+ where <em class="replaceable"><code>delim</code></em> is the delimiter character
+ for the type, as recorded in its <code class="literal">pg_type</code> entry.
+ Among the standard data types provided in the
+ <span class="productname">PostgreSQL</span> distribution, all use a comma
+ (<code class="literal">,</code>), except for type <code class="type">box</code> which uses a semicolon
+ (<code class="literal">;</code>). Each <em class="replaceable"><code>val</code></em> is
+ either a constant of the array element type, or a subarray. An example
+ of an array constant is:
+</p><pre class="programlisting">
+'{{1,2,3},{4,5,6},{7,8,9}}'
+</pre><p>
+ This constant is a two-dimensional, 3-by-3 array consisting of
+ three subarrays of integers.
+ </p><p>
+ To set an element of an array constant to NULL, write <code class="literal">NULL</code>
+ for the element value. (Any upper- or lower-case variant of
+ <code class="literal">NULL</code> will do.) If you want an actual string value
+ <span class="quote">“<span class="quote">NULL</span>”</span>, you must put double quotes around it.
+ </p><p>
+ (These kinds of array constants are actually only a special case of
+ the generic type constants discussed in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC" title="4.1.2.7. Constants of Other Types">Section 4.1.2.7</a>. The constant is initially
+ treated as a string and passed to the array input conversion
+ routine. An explicit type specification might be necessary.)
+ </p><p>
+ Now we can show some <code class="command">INSERT</code> statements:
+
+</p><pre class="programlisting">
+INSERT INTO sal_emp
+ VALUES ('Bill',
+ '{10000, 10000, 10000, 10000}',
+ '{{"meeting", "lunch"}, {"training", "presentation"}}');
+
+INSERT INTO sal_emp
+ VALUES ('Carol',
+ '{20000, 25000, 25000, 25000}',
+ '{{"breakfast", "consulting"}, {"meeting", "lunch"}}');
+</pre><p>
+ </p><p>
+ The result of the previous two inserts looks like this:
+
+</p><pre class="programlisting">
+SELECT * FROM sal_emp;
+ name | pay_by_quarter | schedule
+-------+---------------------------+-------------------------------------------
+ Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}}
+ Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}}
+(2 rows)
+</pre><p>
+ </p><p>
+ Multidimensional arrays must have matching extents for each
+ dimension. A mismatch causes an error, for example:
+
+</p><pre class="programlisting">
+INSERT INTO sal_emp
+ VALUES ('Bill',
+ '{10000, 10000, 10000, 10000}',
+ '{{"meeting", "lunch"}, {"meeting"}}');
+ERROR: multidimensional arrays must have array expressions with matching dimensions
+</pre><p>
+ </p><p>
+ The <code class="literal">ARRAY</code> constructor syntax can also be used:
+</p><pre class="programlisting">
+INSERT INTO sal_emp
+ VALUES ('Bill',
+ ARRAY[10000, 10000, 10000, 10000],
+ ARRAY[['meeting', 'lunch'], ['training', 'presentation']]);
+
+INSERT INTO sal_emp
+ VALUES ('Carol',
+ ARRAY[20000, 25000, 25000, 25000],
+ ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]);
+</pre><p>
+ Notice that the array elements are ordinary SQL constants or
+ expressions; for instance, string literals are single quoted, instead of
+ double quoted as they would be in an array literal. The <code class="literal">ARRAY</code>
+ constructor syntax is discussed in more detail in
+ <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS" title="4.2.12. Array Constructors">Section 4.2.12</a>.
+ </p></div><div class="sect2" id="ARRAYS-ACCESSING"><div class="titlepage"><div><div><h3 class="title">8.15.3. Accessing Arrays</h3></div></div></div><a id="id-1.5.7.23.6.2" class="indexterm"></a><p>
+ Now, we can run some queries on the table.
+ First, we show how to access a single element of an array.
+ This query retrieves the names of the employees whose pay changed in
+ the second quarter:
+
+</p><pre class="programlisting">
+SELECT name FROM sal_emp WHERE pay_by_quarter[1] &lt;&gt; pay_by_quarter[2];
+
+ name
+-------
+ Carol
+(1 row)
+</pre><p>
+
+ The array subscript numbers are written within square brackets.
+ By default <span class="productname">PostgreSQL</span> uses a
+ one-based numbering convention for arrays, that is,
+ an array of <em class="replaceable"><code>n</code></em> elements starts with <code class="literal">array[1]</code> and
+ ends with <code class="literal">array[<em class="replaceable"><code>n</code></em>]</code>.
+ </p><p>
+ This query retrieves the third quarter pay of all employees:
+
+</p><pre class="programlisting">
+SELECT pay_by_quarter[3] FROM sal_emp;
+
+ pay_by_quarter
+----------------
+ 10000
+ 25000
+(2 rows)
+</pre><p>
+ </p><p>
+ We can also access arbitrary rectangular slices of an array, or
+ subarrays. An array slice is denoted by writing
+ <code class="literal"><em class="replaceable"><code>lower-bound</code></em>:<em class="replaceable"><code>upper-bound</code></em></code>
+ for one or more array dimensions. For example, this query retrieves the first
+ item on Bill's schedule for the first two days of the week:
+
+</p><pre class="programlisting">
+SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+------------------------
+ {{meeting},{training}}
+(1 row)
+</pre><p>
+
+ If any dimension is written as a slice, i.e., contains a colon, then all
+ dimensions are treated as slices. Any dimension that has only a single
+ number (no colon) is treated as being from 1
+ to the number specified. For example, <code class="literal">[2]</code> is treated as
+ <code class="literal">[1:2]</code>, as in this example:
+
+</p><pre class="programlisting">
+SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+-------------------------------------------
+ {{meeting,lunch},{training,presentation}}
+(1 row)
+</pre><p>
+
+ To avoid confusion with the non-slice case, it's best to use slice syntax
+ for all dimensions, e.g., <code class="literal">[1:2][1:1]</code>, not <code class="literal">[2][1:1]</code>.
+ </p><p>
+ It is possible to omit the <em class="replaceable"><code>lower-bound</code></em> and/or
+ <em class="replaceable"><code>upper-bound</code></em> of a slice specifier; the missing
+ bound is replaced by the lower or upper limit of the array's subscripts.
+ For example:
+
+</p><pre class="programlisting">
+SELECT schedule[:2][2:] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+------------------------
+ {{lunch},{presentation}}
+(1 row)
+
+SELECT schedule[:][1:1] FROM sal_emp WHERE name = 'Bill';
+
+ schedule
+------------------------
+ {{meeting},{training}}
+(1 row)
+</pre><p>
+ </p><p>
+ An array subscript expression will return null if either the array itself or
+ any of the subscript expressions are null. Also, null is returned if a
+ subscript is outside the array bounds (this case does not raise an error).
+ For example, if <code class="literal">schedule</code>
+ currently has the dimensions <code class="literal">[1:3][1:2]</code> then referencing
+ <code class="literal">schedule[3][3]</code> yields NULL. Similarly, an array reference
+ with the wrong number of subscripts yields a null rather than an error.
+ </p><p>
+ An array slice expression likewise yields null if the array itself or
+ any of the subscript expressions are null. However, in other
+ cases such as selecting an array slice that
+ is completely outside the current array bounds, a slice expression
+ yields an empty (zero-dimensional) array instead of null. (This
+ does not match non-slice behavior and is done for historical reasons.)
+ If the requested slice partially overlaps the array bounds, then it
+ is silently reduced to just the overlapping region instead of
+ returning null.
+ </p><p>
+ The current dimensions of any array value can be retrieved with the
+ <code class="function">array_dims</code> function:
+
+</p><pre class="programlisting">
+SELECT array_dims(schedule) FROM sal_emp WHERE name = 'Carol';
+
+ array_dims
+------------
+ [1:2][1:2]
+(1 row)
+</pre><p>
+
+ <code class="function">array_dims</code> produces a <code class="type">text</code> result,
+ which is convenient for people to read but perhaps inconvenient
+ for programs. Dimensions can also be retrieved with
+ <code class="function">array_upper</code> and <code class="function">array_lower</code>,
+ which return the upper and lower bound of a
+ specified array dimension, respectively:
+
+</p><pre class="programlisting">
+SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol';
+
+ array_upper
+-------------
+ 2
+(1 row)
+</pre><p>
+
+ <code class="function">array_length</code> will return the length of a specified
+ array dimension:
+
+</p><pre class="programlisting">
+SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol';
+
+ array_length
+--------------
+ 2
+(1 row)
+</pre><p>
+
+ <code class="function">cardinality</code> returns the total number of elements in an
+ array across all dimensions. It is effectively the number of rows a call to
+ <code class="function">unnest</code> would yield:
+
+</p><pre class="programlisting">
+SELECT cardinality(schedule) FROM sal_emp WHERE name = 'Carol';
+
+ cardinality
+-------------
+ 4
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="ARRAYS-MODIFYING"><div class="titlepage"><div><div><h3 class="title">8.15.4. Modifying Arrays</h3></div></div></div><a id="id-1.5.7.23.7.2" class="indexterm"></a><p>
+ An array value can be replaced completely:
+
+</p><pre class="programlisting">
+UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}'
+ WHERE name = 'Carol';
+</pre><p>
+
+ or using the <code class="literal">ARRAY</code> expression syntax:
+
+</p><pre class="programlisting">
+UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000]
+ WHERE name = 'Carol';
+</pre><p>
+
+ An array can also be updated at a single element:
+
+</p><pre class="programlisting">
+UPDATE sal_emp SET pay_by_quarter[4] = 15000
+ WHERE name = 'Bill';
+</pre><p>
+
+ or updated in a slice:
+
+</p><pre class="programlisting">
+UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
+ WHERE name = 'Carol';
+</pre><p>
+
+ The slice syntaxes with omitted <em class="replaceable"><code>lower-bound</code></em> and/or
+ <em class="replaceable"><code>upper-bound</code></em> can be used too, but only when
+ updating an array value that is not NULL or zero-dimensional (otherwise,
+ there is no existing subscript limit to substitute).
+ </p><p>
+ A stored array value can be enlarged by assigning to elements not already
+ present. Any positions between those previously present and the newly
+ assigned elements will be filled with nulls. For example, if array
+ <code class="literal">myarray</code> currently has 4 elements, it will have six
+ elements after an update that assigns to <code class="literal">myarray[6]</code>;
+ <code class="literal">myarray[5]</code> will contain null.
+ Currently, enlargement in this fashion is only allowed for one-dimensional
+ arrays, not multidimensional arrays.
+ </p><p>
+ Subscripted assignment allows creation of arrays that do not use one-based
+ subscripts. For example one might assign to <code class="literal">myarray[-2:7]</code> to
+ create an array with subscript values from -2 to 7.
+ </p><p>
+ New array values can also be constructed using the concatenation operator,
+ <code class="literal">||</code>:
+</p><pre class="programlisting">
+SELECT ARRAY[1,2] || ARRAY[3,4];
+ ?column?
+-----------
+ {1,2,3,4}
+(1 row)
+
+SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
+ ?column?
+---------------------
+ {{5,6},{1,2},{3,4}}
+(1 row)
+</pre><p>
+ </p><p>
+ The concatenation operator allows a single element to be pushed onto the
+ beginning or end of a one-dimensional array. It also accepts two
+ <em class="replaceable"><code>N</code></em>-dimensional arrays, or an <em class="replaceable"><code>N</code></em>-dimensional
+ and an <em class="replaceable"><code>N+1</code></em>-dimensional array.
+ </p><p>
+ When a single element is pushed onto either the beginning or end of a
+ one-dimensional array, the result is an array with the same lower bound
+ subscript as the array operand. For example:
+</p><pre class="programlisting">
+SELECT array_dims(1 || '[0:1]={2,3}'::int[]);
+ array_dims
+------------
+ [0:2]
+(1 row)
+
+SELECT array_dims(ARRAY[1,2] || 3);
+ array_dims
+------------
+ [1:3]
+(1 row)
+</pre><p>
+ </p><p>
+ When two arrays with an equal number of dimensions are concatenated, the
+ result retains the lower bound subscript of the left-hand operand's outer
+ dimension. The result is an array comprising every element of the left-hand
+ operand followed by every element of the right-hand operand. For example:
+</p><pre class="programlisting">
+SELECT array_dims(ARRAY[1,2] || ARRAY[3,4,5]);
+ array_dims
+------------
+ [1:5]
+(1 row)
+
+SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
+ array_dims
+------------
+ [1:5][1:2]
+(1 row)
+</pre><p>
+ </p><p>
+ When an <em class="replaceable"><code>N</code></em>-dimensional array is pushed onto the beginning
+ or end of an <em class="replaceable"><code>N+1</code></em>-dimensional array, the result is
+ analogous to the element-array case above. Each <em class="replaceable"><code>N</code></em>-dimensional
+ sub-array is essentially an element of the <em class="replaceable"><code>N+1</code></em>-dimensional
+ array's outer dimension. For example:
+</p><pre class="programlisting">
+SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]);
+ array_dims
+------------
+ [1:3][1:2]
+(1 row)
+</pre><p>
+ </p><p>
+ An array can also be constructed by using the functions
+ <code class="function">array_prepend</code>, <code class="function">array_append</code>,
+ or <code class="function">array_cat</code>. The first two only support one-dimensional
+ arrays, but <code class="function">array_cat</code> supports multidimensional arrays.
+ Some examples:
+
+</p><pre class="programlisting">
+SELECT array_prepend(1, ARRAY[2,3]);
+ array_prepend
+---------------
+ {1,2,3}
+(1 row)
+
+SELECT array_append(ARRAY[1,2], 3);
+ array_append
+--------------
+ {1,2,3}
+(1 row)
+
+SELECT array_cat(ARRAY[1,2], ARRAY[3,4]);
+ array_cat
+-----------
+ {1,2,3,4}
+(1 row)
+
+SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);
+ array_cat
+---------------------
+ {{1,2},{3,4},{5,6}}
+(1 row)
+
+SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]);
+ array_cat
+---------------------
+ {{5,6},{1,2},{3,4}}
+</pre><p>
+ </p><p>
+ In simple cases, the concatenation operator discussed above is preferred
+ over direct use of these functions. However, because the concatenation
+ operator is overloaded to serve all three cases, there are situations where
+ use of one of the functions is helpful to avoid ambiguity. For example
+ consider:
+
+</p><pre class="programlisting">
+SELECT ARRAY[1, 2] || '{3, 4}'; -- the untyped literal is taken as an array
+ ?column?
+-----------
+ {1,2,3,4}
+
+SELECT ARRAY[1, 2] || '7'; -- so is this one
+ERROR: malformed array literal: "7"
+
+SELECT ARRAY[1, 2] || NULL; -- so is an undecorated NULL
+ ?column?
+----------
+ {1,2}
+(1 row)
+
+SELECT array_append(ARRAY[1, 2], NULL); -- this might have been meant
+ array_append
+--------------
+ {1,2,NULL}
+</pre><p>
+
+ In the examples above, the parser sees an integer array on one side of the
+ concatenation operator, and a constant of undetermined type on the other.
+ The heuristic it uses to resolve the constant's type is to assume it's of
+ the same type as the operator's other input — in this case,
+ integer array. So the concatenation operator is presumed to
+ represent <code class="function">array_cat</code>, not <code class="function">array_append</code>. When
+ that's the wrong choice, it could be fixed by casting the constant to the
+ array's element type; but explicit use of <code class="function">array_append</code> might
+ be a preferable solution.
+ </p></div><div class="sect2" id="ARRAYS-SEARCHING"><div class="titlepage"><div><div><h3 class="title">8.15.5. Searching in Arrays</h3></div></div></div><a id="id-1.5.7.23.8.2" class="indexterm"></a><p>
+ To search for a value in an array, each value must be checked.
+ This can be done manually, if you know the size of the array.
+ For example:
+
+</p><pre class="programlisting">
+SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR
+ pay_by_quarter[2] = 10000 OR
+ pay_by_quarter[3] = 10000 OR
+ pay_by_quarter[4] = 10000;
+</pre><p>
+
+ However, this quickly becomes tedious for large arrays, and is not
+ helpful if the size of the array is unknown. An alternative method is
+ described in <a class="xref" href="functions-comparisons.html" title="9.24. Row and Array Comparisons">Section 9.24</a>. The above
+ query could be replaced by:
+
+</p><pre class="programlisting">
+SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter);
+</pre><p>
+
+ In addition, you can find rows where the array has all values
+ equal to 10000 with:
+
+</p><pre class="programlisting">
+SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter);
+</pre><p>
+
+ </p><p>
+ Alternatively, the <code class="function">generate_subscripts</code> function can be used.
+ For example:
+
+</p><pre class="programlisting">
+SELECT * FROM
+ (SELECT pay_by_quarter,
+ generate_subscripts(pay_by_quarter, 1) AS s
+ FROM sal_emp) AS foo
+ WHERE pay_by_quarter[s] = 10000;
+</pre><p>
+
+ This function is described in <a class="xref" href="functions-srf.html#FUNCTIONS-SRF-SUBSCRIPTS" title="Table 9.65. Subscript Generating Functions">Table 9.65</a>.
+ </p><p>
+ You can also search an array using the <code class="literal">&amp;&amp;</code> operator,
+ which checks whether the left operand overlaps with the right operand.
+ For instance:
+
+</p><pre class="programlisting">
+SELECT * FROM sal_emp WHERE pay_by_quarter &amp;&amp; ARRAY[10000];
+</pre><p>
+
+ This and other array operators are further described in
+ <a class="xref" href="functions-array.html" title="9.19. Array Functions and Operators">Section 9.19</a>. It can be accelerated by an appropriate
+ index, as described in <a class="xref" href="indexes-types.html" title="11.2. Index Types">Section 11.2</a>.
+ </p><p>
+ You can also search for specific values in an array using the <code class="function">array_position</code>
+ and <code class="function">array_positions</code> functions. The former returns the subscript of
+ the first occurrence of a value in an array; the latter returns an array with the
+ subscripts of all occurrences of the value in the array. For example:
+
+</p><pre class="programlisting">
+SELECT array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon');
+ array_position
+----------------
+ 2
+(1 row)
+
+SELECT array_positions(ARRAY[1, 4, 3, 1, 3, 4, 2, 1], 1);
+ array_positions
+-----------------
+ {1,4,8}
+(1 row)
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Arrays are not sets; searching for specific array elements
+ can be a sign of database misdesign. Consider
+ using a separate table with a row for each item that would be an
+ array element. This will be easier to search, and is likely to
+ scale better for a large number of elements.
+ </p></div></div><div class="sect2" id="ARRAYS-IO"><div class="titlepage"><div><div><h3 class="title">8.15.6. Array Input and Output Syntax</h3></div></div></div><a id="id-1.5.7.23.9.2" class="indexterm"></a><p>
+ The external text representation of an array value consists of items that
+ are interpreted according to the I/O conversion rules for the array's
+ element type, plus decoration that indicates the array structure.
+ The decoration consists of curly braces (<code class="literal">{</code> and <code class="literal">}</code>)
+ around the array value plus delimiter characters between adjacent items.
+ The delimiter character is usually a comma (<code class="literal">,</code>) but can be
+ something else: it is determined by the <code class="literal">typdelim</code> setting
+ for the array's element type. Among the standard data types provided
+ in the <span class="productname">PostgreSQL</span> distribution, all use a comma,
+ except for type <code class="type">box</code>, which uses a semicolon (<code class="literal">;</code>).
+ In a multidimensional array, each dimension (row, plane,
+ cube, etc.) gets its own level of curly braces, and delimiters
+ must be written between adjacent curly-braced entities of the same level.
+ </p><p>
+ The array output routine will put double quotes around element values
+ if they are empty strings, contain curly braces, delimiter characters,
+ double quotes, backslashes, or white space, or match the word
+ <code class="literal">NULL</code>. Double quotes and backslashes
+ embedded in element values will be backslash-escaped. For numeric
+ data types it is safe to assume that double quotes will never appear, but
+ for textual data types one should be prepared to cope with either the presence
+ or absence of quotes.
+ </p><p>
+ By default, the lower bound index value of an array's dimensions is
+ set to one. To represent arrays with other lower bounds, the array
+ subscript ranges can be specified explicitly before writing the
+ array contents.
+ This decoration consists of square brackets (<code class="literal">[]</code>)
+ around each array dimension's lower and upper bounds, with
+ a colon (<code class="literal">:</code>) delimiter character in between. The
+ array dimension decoration is followed by an equal sign (<code class="literal">=</code>).
+ For example:
+</p><pre class="programlisting">
+SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2
+ FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss;
+
+ e1 | e2
+----+----
+ 1 | 6
+(1 row)
+</pre><p>
+ The array output routine will include explicit dimensions in its result
+ only when there are one or more lower bounds different from one.
+ </p><p>
+ If the value written for an element is <code class="literal">NULL</code> (in any case
+ variant), the element is taken to be NULL. The presence of any quotes
+ or backslashes disables this and allows the literal string value
+ <span class="quote">“<span class="quote">NULL</span>”</span> to be entered. Also, for backward compatibility with
+ pre-8.2 versions of <span class="productname">PostgreSQL</span>, the <a class="xref" href="runtime-config-compatible.html#GUC-ARRAY-NULLS">array_nulls</a> configuration parameter can be turned
+ <code class="literal">off</code> to suppress recognition of <code class="literal">NULL</code> as a NULL.
+ </p><p>
+ As shown previously, when writing an array value you can use double
+ quotes around any individual array element. You <span class="emphasis"><em>must</em></span> do so
+ if the element value would otherwise confuse the array-value parser.
+ For example, elements containing curly braces, commas (or the data type's
+ delimiter character), double quotes, backslashes, or leading or trailing
+ whitespace must be double-quoted. Empty strings and strings matching the
+ word <code class="literal">NULL</code> must be quoted, too. To put a double
+ quote or backslash in a quoted array element value, precede it
+ with a backslash. Alternatively, you can avoid quotes and use
+ backslash-escaping to protect all data characters that would otherwise
+ be taken as array syntax.
+ </p><p>
+ You can add whitespace before a left brace or after a right
+ brace. You can also add whitespace before or after any individual item
+ string. In all of these cases the whitespace will be ignored. However,
+ whitespace within double-quoted elements, or surrounded on both sides by
+ non-whitespace characters of an element, is not ignored.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The <code class="literal">ARRAY</code> constructor syntax (see
+ <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS" title="4.2.12. Array Constructors">Section 4.2.12</a>) is often easier to work
+ with than the array-literal syntax when writing array values in SQL
+ commands. In <code class="literal">ARRAY</code>, individual element values are written the
+ same way they would be written when not members of an array.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-json.html" title="8.14. JSON Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rowtypes.html" title="8.16. Composite Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.14. <acronym class="acronym">JSON</acronym> Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.16. Composite Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-bsd.html b/doc/src/sgml/html/auth-bsd.html
new file mode 100644
index 0000000..0360211
--- /dev/null
+++ b/doc/src/sgml/html/auth-bsd.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.14. BSD Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-pam.html" title="21.13. PAM Authentication" /><link rel="next" href="client-authentication-problems.html" title="21.15. Authentication Problems" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.14. BSD Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-pam.html" title="21.13. PAM Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="client-authentication-problems.html" title="21.15. Authentication Problems">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-BSD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.14. BSD Authentication</h2></div></div></div><a id="id-1.6.8.21.2" class="indexterm"></a><p>
+ This authentication method operates similarly to
+ <code class="literal">password</code> except that it uses BSD Authentication
+ to verify the password. BSD Authentication is used only
+ to validate user name/password pairs. Therefore the user's role must
+ already exist in the database before BSD Authentication can be used
+ for authentication. The BSD Authentication framework is currently
+ only available on OpenBSD.
+ </p><p>
+ BSD Authentication in <span class="productname">PostgreSQL</span> uses
+ the <code class="literal">auth-postgresql</code> login type and authenticates with
+ the <code class="literal">postgresql</code> login class if that's defined
+ in <code class="filename">login.conf</code>. By default that login class does not
+ exist, and <span class="productname">PostgreSQL</span> will use the default login class.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ To use BSD Authentication, the PostgreSQL user account (that is, the
+ operating system user running the server) must first be added to
+ the <code class="literal">auth</code> group. The <code class="literal">auth</code> group
+ exists by default on OpenBSD systems.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-pam.html" title="21.13. PAM Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="client-authentication-problems.html" title="21.15. Authentication Problems">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.13. PAM Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.15. Authentication Problems</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-cert.html b/doc/src/sgml/html/auth-cert.html
new file mode 100644
index 0000000..839908b
--- /dev/null
+++ b/doc/src/sgml/html/auth-cert.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.12. Certificate Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-radius.html" title="21.11. RADIUS Authentication" /><link rel="next" href="auth-pam.html" title="21.13. PAM Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.12. Certificate Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-radius.html" title="21.11. RADIUS Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-pam.html" title="21.13. PAM Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-CERT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.12. Certificate Authentication</h2></div></div></div><a id="id-1.6.8.19.2" class="indexterm"></a><p>
+ This authentication method uses SSL client certificates to perform
+ authentication. It is therefore only available for SSL connections.
+ When using this authentication method, the server will require that
+ the client provide a valid, trusted certificate. No password prompt
+ will be sent to the client. The <code class="literal">cn</code> (Common Name)
+ attribute of the certificate
+ will be compared to the requested database user name, and if they match
+ the login will be allowed. User name mapping can be used to allow
+ <code class="literal">cn</code> to be different from the database user name.
+ </p><p>
+ The following configuration options are supported for SSL certificate
+ authentication:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">map</code></span></dt><dd><p>
+ Allows for mapping between system and database user names. See
+ <a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a> for details.
+ </p></dd></dl></div><p>
+ </p><p>
+ It is redundant to use the <code class="literal">clientcert</code> option with
+ <code class="literal">cert</code> authentication because <code class="literal">cert</code>
+ authentication is effectively <code class="literal">trust</code> authentication
+ with <code class="literal">clientcert=verify-full</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-radius.html" title="21.11. RADIUS Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-pam.html" title="21.13. PAM Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.11. RADIUS Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.13. PAM Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-delay.html b/doc/src/sgml/html/auth-delay.html
new file mode 100644
index 0000000..b09e445
--- /dev/null
+++ b/doc/src/sgml/html/auth-delay.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.3. auth_delay</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="amcheck.html" title="F.2. amcheck" /><link rel="next" href="auto-explain.html" title="F.4. auto_explain" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.3. auth_delay</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="amcheck.html" title="F.2. amcheck">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auto-explain.html" title="F.4. auto_explain">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-DELAY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.3. auth_delay</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="auth-delay.html#id-1.11.7.12.5">F.3.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="auth-delay.html#id-1.11.7.12.6">F.3.2. Author</a></span></dt></dl></div><a id="id-1.11.7.12.2" class="indexterm"></a><p>
+ <code class="filename">auth_delay</code> causes the server to pause briefly before
+ reporting authentication failure, to make brute-force attacks on database
+ passwords more difficult. Note that it does nothing to prevent
+ denial-of-service attacks, and may even exacerbate them, since processes
+ that are waiting before reporting authentication failure will still consume
+ connection slots.
+ </p><p>
+ In order to function, this module must be loaded via
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> in <code class="filename">postgresql.conf</code>.
+ </p><div class="sect2" id="id-1.11.7.12.5"><div class="titlepage"><div><div><h3 class="title">F.3.1. Configuration Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">auth_delay.milliseconds</code> (<code class="type">integer</code>)
+ <a id="id-1.11.7.12.5.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The number of milliseconds to wait before reporting an authentication
+ failure. The default is 0.
+ </p></dd></dl></div><p>
+ These parameters must be set in <code class="filename">postgresql.conf</code>.
+ Typical usage might be:
+ </p><pre class="programlisting">
+# postgresql.conf
+shared_preload_libraries = 'auth_delay'
+
+auth_delay.milliseconds = '500'
+</pre></div><div class="sect2" id="id-1.11.7.12.6"><div class="titlepage"><div><div><h3 class="title">F.3.2. Author</h3></div></div></div><p>
+ KaiGai Kohei <code class="email">&lt;<a class="email" href="mailto:kaigai@ak.jp.nec.com">kaigai@ak.jp.nec.com</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="amcheck.html" title="F.2. amcheck">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auto-explain.html" title="F.4. auto_explain">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.2. amcheck </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.4. auto_explain</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-ident.html b/doc/src/sgml/html/auth-ident.html
new file mode 100644
index 0000000..396859f
--- /dev/null
+++ b/doc/src/sgml/html/auth-ident.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.8. Ident Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sspi-auth.html" title="21.7. SSPI Authentication" /><link rel="next" href="auth-peer.html" title="21.9. Peer Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.8. Ident Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sspi-auth.html" title="21.7. SSPI Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-peer.html" title="21.9. Peer Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-IDENT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.8. Ident Authentication</h2></div></div></div><a id="id-1.6.8.15.2" class="indexterm"></a><p>
+ The ident authentication method works by obtaining the client's
+ operating system user name from an ident server and using it as
+ the allowed database user name (with an optional user name mapping).
+ This is only supported on TCP/IP connections.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When ident is specified for a local (non-TCP/IP) connection,
+ peer authentication (see <a class="xref" href="auth-peer.html" title="21.9. Peer Authentication">Section 21.9</a>) will be
+ used instead.
+ </p></div><p>
+ The following configuration options are supported for <code class="literal">ident</code>:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">map</code></span></dt><dd><p>
+ Allows for mapping between system and database user names. See
+ <a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a> for details.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <span class="quote">“<span class="quote">Identification Protocol</span>”</span> is described in
+ <a class="ulink" href="https://tools.ietf.org/html/rfc1413" target="_top">RFC 1413</a>.
+ Virtually every Unix-like
+ operating system ships with an ident server that listens on TCP
+ port 113 by default. The basic functionality of an ident server
+ is to answer questions like <span class="quote">“<span class="quote">What user initiated the
+ connection that goes out of your port <em class="replaceable"><code>X</code></em>
+ and connects to my port <em class="replaceable"><code>Y</code></em>?</span>”</span>.
+ Since <span class="productname">PostgreSQL</span> knows both <em class="replaceable"><code>X</code></em> and
+ <em class="replaceable"><code>Y</code></em> when a physical connection is established, it
+ can interrogate the ident server on the host of the connecting
+ client and can theoretically determine the operating system user
+ for any given connection.
+ </p><p>
+ The drawback of this procedure is that it depends on the integrity
+ of the client: if the client machine is untrusted or compromised,
+ an attacker could run just about any program on port 113 and
+ return any user name they choose. This authentication method is
+ therefore only appropriate for closed networks where each client
+ machine is under tight control and where the database and system
+ administrators operate in close contact. In other words, you must
+ trust the machine running the ident server.
+ Heed the warning:
+ </p><div class="blockquote"><table border="0" class="blockquote" style="width: 100%; cellspacing: 0; cellpadding: 0;" summary="Block quote"><tr><td width="10%" valign="top"> </td><td width="80%" valign="top"><p>
+ The Identification Protocol is not intended as an authorization
+ or access control protocol.
+ </p></td><td width="10%" valign="top"> </td></tr><tr><td width="10%" valign="top"> </td><td colspan="2" align="right" valign="top">--<span class="attribution">RFC 1413</span></td></tr></table></div><p>
+ </p><p>
+ Some ident servers have a nonstandard option that causes the returned
+ user name to be encrypted, using a key that only the originating
+ machine's administrator knows. This option <span class="emphasis"><em>must not</em></span> be
+ used when using the ident server with <span class="productname">PostgreSQL</span>,
+ since <span class="productname">PostgreSQL</span> does not have any way to decrypt the
+ returned string to determine the actual user name.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sspi-auth.html" title="21.7. SSPI Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-peer.html" title="21.9. Peer Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.7. SSPI Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.9. Peer Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-ldap.html b/doc/src/sgml/html/auth-ldap.html
new file mode 100644
index 0000000..0da6070
--- /dev/null
+++ b/doc/src/sgml/html/auth-ldap.html
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.10. LDAP Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-peer.html" title="21.9. Peer Authentication" /><link rel="next" href="auth-radius.html" title="21.11. RADIUS Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.10. LDAP Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-peer.html" title="21.9. Peer Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-radius.html" title="21.11. RADIUS Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-LDAP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.10. LDAP Authentication</h2></div></div></div><a id="id-1.6.8.17.2" class="indexterm"></a><p>
+ This authentication method operates similarly to
+ <code class="literal">password</code> except that it uses LDAP
+ as the password verification method. LDAP is used only to validate
+ the user name/password pairs. Therefore the user must already
+ exist in the database before LDAP can be used for
+ authentication.
+ </p><p>
+ LDAP authentication can operate in two modes. In the first mode,
+ which we will call the simple bind mode,
+ the server will bind to the distinguished name constructed as
+ <em class="replaceable"><code>prefix</code></em> <em class="replaceable"><code>username</code></em> <em class="replaceable"><code>suffix</code></em>.
+ Typically, the <em class="replaceable"><code>prefix</code></em> parameter is used to specify
+ <code class="literal">cn=</code>, or <em class="replaceable"><code>DOMAIN</code></em><code class="literal">\</code> in an Active
+ Directory environment. <em class="replaceable"><code>suffix</code></em> is used to specify the
+ remaining part of the DN in a non-Active Directory environment.
+ </p><p>
+ In the second mode, which we will call the search+bind mode,
+ the server first binds to the LDAP directory with
+ a fixed user name and password, specified with <em class="replaceable"><code>ldapbinddn</code></em>
+ and <em class="replaceable"><code>ldapbindpasswd</code></em>, and performs a search for the user trying
+ to log in to the database. If no user and password is configured, an
+ anonymous bind will be attempted to the directory. The search will be
+ performed over the subtree at <em class="replaceable"><code>ldapbasedn</code></em>, and will try to
+ do an exact match of the attribute specified in
+ <em class="replaceable"><code>ldapsearchattribute</code></em>.
+ Once the user has been found in
+ this search, the server disconnects and re-binds to the directory as
+ this user, using the password specified by the client, to verify that the
+ login is correct. This mode is the same as that used by LDAP authentication
+ schemes in other software, such as Apache <code class="literal">mod_authnz_ldap</code> and <code class="literal">pam_ldap</code>.
+ This method allows for significantly more flexibility
+ in where the user objects are located in the directory, but will cause
+ two separate connections to the LDAP server to be made.
+ </p><p>
+ The following configuration options are used in both modes:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ldapserver</code></span></dt><dd><p>
+ Names or IP addresses of LDAP servers to connect to. Multiple
+ servers may be specified, separated by spaces.
+ </p></dd><dt><span class="term"><code class="literal">ldapport</code></span></dt><dd><p>
+ Port number on LDAP server to connect to. If no port is specified,
+ the LDAP library's default port setting will be used.
+ </p></dd><dt><span class="term"><code class="literal">ldapscheme</code></span></dt><dd><p>
+ Set to <code class="literal">ldaps</code> to use LDAPS. This is a non-standard
+ way of using LDAP over SSL, supported by some LDAP server
+ implementations. See also the <code class="literal">ldaptls</code> option for
+ an alternative.
+ </p></dd><dt><span class="term"><code class="literal">ldaptls</code></span></dt><dd><p>
+ Set to 1 to make the connection between PostgreSQL and the LDAP server
+ use TLS encryption. This uses the <code class="literal">StartTLS</code>
+ operation per <a class="ulink" href="https://tools.ietf.org/html/rfc4513" target="_top">RFC 4513</a>.
+ See also the <code class="literal">ldapscheme</code> option for an alternative.
+ </p></dd></dl></div><p>
+ </p><p>
+ Note that using <code class="literal">ldapscheme</code> or
+ <code class="literal">ldaptls</code> only encrypts the traffic between the
+ PostgreSQL server and the LDAP server. The connection between the
+ PostgreSQL server and the PostgreSQL client will still be unencrypted
+ unless SSL is used there as well.
+ </p><p>
+ The following options are used in simple bind mode only:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ldapprefix</code></span></dt><dd><p>
+ String to prepend to the user name when forming the DN to bind as,
+ when doing simple bind authentication.
+ </p></dd><dt><span class="term"><code class="literal">ldapsuffix</code></span></dt><dd><p>
+ String to append to the user name when forming the DN to bind as,
+ when doing simple bind authentication.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following options are used in search+bind mode only:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ldapbasedn</code></span></dt><dd><p>
+ Root DN to begin the search for the user in, when doing search+bind
+ authentication.
+ </p></dd><dt><span class="term"><code class="literal">ldapbinddn</code></span></dt><dd><p>
+ DN of user to bind to the directory with to perform the search when
+ doing search+bind authentication.
+ </p></dd><dt><span class="term"><code class="literal">ldapbindpasswd</code></span></dt><dd><p>
+ Password for user to bind to the directory with to perform the search
+ when doing search+bind authentication.
+ </p></dd><dt><span class="term"><code class="literal">ldapsearchattribute</code></span></dt><dd><p>
+ Attribute to match against the user name in the search when doing
+ search+bind authentication. If no attribute is specified, the
+ <code class="literal">uid</code> attribute will be used.
+ </p></dd><dt><span class="term"><code class="literal">ldapsearchfilter</code></span></dt><dd><p>
+ The search filter to use when doing search+bind authentication.
+ Occurrences of <code class="literal">$username</code> will be replaced with the
+ user name. This allows for more flexible search filters than
+ <code class="literal">ldapsearchattribute</code>.
+ </p></dd><dt><span class="term"><code class="literal">ldapurl</code></span></dt><dd><p>
+ An <a class="ulink" href="https://tools.ietf.org/html/rfc4516" target="_top">RFC 4516</a>
+ LDAP URL. This is an alternative way to write some of the
+ other LDAP options in a more compact and standard form. The format is
+</p><pre class="synopsis">
+ldap[s]://<em class="replaceable"><code>host</code></em>[:<em class="replaceable"><code>port</code></em>]/<em class="replaceable"><code>basedn</code></em>[?[<em class="replaceable"><code>attribute</code></em>][?[<em class="replaceable"><code>scope</code></em>][?[<em class="replaceable"><code>filter</code></em>]]]]
+</pre><p>
+ <em class="replaceable"><code>scope</code></em> must be one
+ of <code class="literal">base</code>, <code class="literal">one</code>, <code class="literal">sub</code>,
+ typically the last. (The default is <code class="literal">base</code>, which
+ is normally not useful in this application.) <em class="replaceable"><code>attribute</code></em> can
+ nominate a single attribute, in which case it is used as a value for
+ <code class="literal">ldapsearchattribute</code>. If
+ <em class="replaceable"><code>attribute</code></em> is empty then
+ <em class="replaceable"><code>filter</code></em> can be used as a value for
+ <code class="literal">ldapsearchfilter</code>.
+ </p><p>
+ The URL scheme <code class="literal">ldaps</code> chooses the LDAPS method for
+ making LDAP connections over SSL, equivalent to using
+ <code class="literal">ldapscheme=ldaps</code>. To use encrypted LDAP
+ connections using the <code class="literal">StartTLS</code> operation, use the
+ normal URL scheme <code class="literal">ldap</code> and specify the
+ <code class="literal">ldaptls</code> option in addition to
+ <code class="literal">ldapurl</code>.
+ </p><p>
+ For non-anonymous binds, <code class="literal">ldapbinddn</code>
+ and <code class="literal">ldapbindpasswd</code> must be specified as separate
+ options.
+ </p><p>
+ LDAP URLs are currently only supported with
+ <span class="productname">OpenLDAP</span>, not on Windows.
+ </p></dd></dl></div><p>
+ </p><p>
+ It is an error to mix configuration options for simple bind with options
+ for search+bind.
+ </p><p>
+ When using search+bind mode, the search can be performed using a single
+ attribute specified with <code class="literal">ldapsearchattribute</code>, or using
+ a custom search filter specified with
+ <code class="literal">ldapsearchfilter</code>.
+ Specifying <code class="literal">ldapsearchattribute=foo</code> is equivalent to
+ specifying <code class="literal">ldapsearchfilter="(foo=$username)"</code>. If neither
+ option is specified the default is
+ <code class="literal">ldapsearchattribute=uid</code>.
+ </p><p>
+ If <span class="productname">PostgreSQL</span> was compiled with
+ <span class="productname">OpenLDAP</span> as the LDAP client library, the
+ <code class="literal">ldapserver</code> setting may be omitted. In that case, a
+ list of host names and ports is looked up via
+ <a class="ulink" href="https://tools.ietf.org/html/rfc2782" target="_top">RFC 2782</a> DNS SRV records.
+ The name <code class="literal">_ldap._tcp.DOMAIN</code> is looked up, where
+ <code class="literal">DOMAIN</code> is extracted from <code class="literal">ldapbasedn</code>.
+ </p><p>
+ Here is an example for a simple-bind LDAP configuration:
+</p><pre class="programlisting">
+host ... ldap ldapserver=ldap.example.net ldapprefix="cn=" ldapsuffix=", dc=example, dc=net"
+</pre><p>
+ When a connection to the database server as database
+ user <code class="literal">someuser</code> is requested, PostgreSQL will attempt to
+ bind to the LDAP server using the DN <code class="literal">cn=someuser, dc=example,
+ dc=net</code> and the password provided by the client. If that connection
+ succeeds, the database access is granted.
+ </p><p>
+ Here is an example for a search+bind configuration:
+</p><pre class="programlisting">
+host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchattribute=uid
+</pre><p>
+ When a connection to the database server as database
+ user <code class="literal">someuser</code> is requested, PostgreSQL will attempt to
+ bind anonymously (since <code class="literal">ldapbinddn</code> was not specified) to
+ the LDAP server, perform a search for <code class="literal">(uid=someuser)</code>
+ under the specified base DN. If an entry is found, it will then attempt to
+ bind using that found information and the password supplied by the client.
+ If that second connection succeeds, the database access is granted.
+ </p><p>
+ Here is the same search+bind configuration written as a URL:
+</p><pre class="programlisting">
+host ... ldap ldapurl="ldap://ldap.example.net/dc=example,dc=net?uid?sub"
+</pre><p>
+ Some other software that supports authentication against LDAP uses the
+ same URL format, so it will be easier to share the configuration.
+ </p><p>
+ Here is an example for a search+bind configuration that uses
+ <code class="literal">ldapsearchfilter</code> instead of
+ <code class="literal">ldapsearchattribute</code> to allow authentication by
+ user ID or email address:
+</p><pre class="programlisting">
+host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapsearchfilter="(|(uid=$username)(mail=$username))"
+</pre><p>
+ </p><p>
+ Here is an example for a search+bind configuration that uses DNS SRV
+ discovery to find the host name(s) and port(s) for the LDAP service for the
+ domain name <code class="literal">example.net</code>:
+</p><pre class="programlisting">
+host ... ldap ldapbasedn="dc=example,dc=net"
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Since LDAP often uses commas and spaces to separate the different
+ parts of a DN, it is often necessary to use double-quoted parameter
+ values when configuring LDAP options, as shown in the examples.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-peer.html" title="21.9. Peer Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-radius.html" title="21.11. RADIUS Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.9. Peer Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.11. RADIUS Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-methods.html b/doc/src/sgml/html/auth-methods.html
new file mode 100644
index 0000000..e50cc95
--- /dev/null
+++ b/doc/src/sgml/html/auth-methods.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.3. Authentication Methods</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-username-maps.html" title="21.2. User Name Maps" /><link rel="next" href="auth-trust.html" title="21.4. Trust Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.3. Authentication Methods</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-username-maps.html" title="21.2. User Name Maps">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-trust.html" title="21.4. Trust Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-METHODS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.3. Authentication Methods</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> provides various methods for
+ authenticating users:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="link" href="auth-trust.html" title="21.4. Trust Authentication">Trust authentication</a>, which
+ simply trusts that users are who they say they are.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-password.html" title="21.5. Password Authentication">Password authentication</a>, which
+ requires that users send a password.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">GSSAPI authentication</a>, which
+ relies on a GSSAPI-compatible security library. Typically this is
+ used to access an authentication server such as a Kerberos or
+ Microsoft Active Directory server.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="sspi-auth.html" title="21.7. SSPI Authentication">SSPI authentication</a>, which
+ uses a Windows-specific protocol similar to GSSAPI.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-ident.html" title="21.8. Ident Authentication">Ident authentication</a>, which
+ relies on an <span class="quote">“<span class="quote">Identification Protocol</span>”</span>
+ (<a class="ulink" href="https://tools.ietf.org/html/rfc1413" target="_top">RFC 1413</a>)
+ service on the client's machine. (On local Unix-socket connections,
+ this is treated as peer authentication.)
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-peer.html" title="21.9. Peer Authentication">Peer authentication</a>, which
+ relies on operating system facilities to identify the process at the
+ other end of a local connection. This is not supported for remote
+ connections.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-ldap.html" title="21.10. LDAP Authentication">LDAP authentication</a>, which
+ relies on an LDAP authentication server.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-radius.html" title="21.11. RADIUS Authentication">RADIUS authentication</a>, which
+ relies on a RADIUS authentication server.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-cert.html" title="21.12. Certificate Authentication">Certificate authentication</a>, which
+ requires an SSL connection and authenticates users by checking the
+ SSL certificate they send.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-pam.html" title="21.13. PAM Authentication">PAM authentication</a>, which
+ relies on a PAM (Pluggable Authentication Modules) library.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="auth-bsd.html" title="21.14. BSD Authentication">BSD authentication</a>, which
+ relies on the BSD Authentication framework (currently available
+ only on OpenBSD).
+ </p></li></ul></div><p>
+ </p><p>
+ Peer authentication is usually recommendable for local connections,
+ though trust authentication might be sufficient in some circumstances.
+ Password authentication is the easiest choice for remote connections.
+ All the other options require some kind of external security
+ infrastructure (usually an authentication server or a certificate
+ authority for issuing SSL certificates), or are platform-specific.
+ </p><p>
+ The following sections describe each of these authentication methods
+ in more detail.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-username-maps.html" title="21.2. User Name Maps">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-trust.html" title="21.4. Trust Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.2. User Name Maps </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.4. Trust Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-pam.html b/doc/src/sgml/html/auth-pam.html
new file mode 100644
index 0000000..945b788
--- /dev/null
+++ b/doc/src/sgml/html/auth-pam.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.13. PAM Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-cert.html" title="21.12. Certificate Authentication" /><link rel="next" href="auth-bsd.html" title="21.14. BSD Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.13. PAM Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-cert.html" title="21.12. Certificate Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-bsd.html" title="21.14. BSD Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-PAM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.13. PAM Authentication</h2></div></div></div><a id="id-1.6.8.20.2" class="indexterm"></a><p>
+ This authentication method operates similarly to
+ <code class="literal">password</code> except that it uses PAM (Pluggable
+ Authentication Modules) as the authentication mechanism. The
+ default PAM service name is <code class="literal">postgresql</code>.
+ PAM is used only to validate user name/password pairs and optionally the
+ connected remote host name or IP address. Therefore the user must already
+ exist in the database before PAM can be used for authentication. For more
+ information about PAM, please read the
+ <a class="ulink" href="https://www.kernel.org/pub/linux/libs/pam/" target="_top">
+ <span class="productname">Linux-PAM</span> Page</a>.
+ </p><p>
+ The following configuration options are supported for PAM:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">pamservice</code></span></dt><dd><p>
+ PAM service name.
+ </p></dd><dt><span class="term"><code class="literal">pam_use_hostname</code></span></dt><dd><p>
+ Determines whether the remote IP address or the host name is provided
+ to PAM modules through the <code class="symbol">PAM_RHOST</code> item. By
+ default, the IP address is used. Set this option to 1 to use the
+ resolved host name instead. Host name resolution can lead to login
+ delays. (Most PAM configurations don't use this information, so it is
+ only necessary to consider this setting if a PAM configuration was
+ specifically created to make use of it.)
+ </p></dd></dl></div><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If PAM is set up to read <code class="filename">/etc/shadow</code>, authentication
+ will fail because the PostgreSQL server is started by a non-root
+ user. However, this is not an issue when PAM is configured to use
+ LDAP or other authentication methods.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-cert.html" title="21.12. Certificate Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-bsd.html" title="21.14. BSD Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.12. Certificate Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.14. BSD Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-password.html b/doc/src/sgml/html/auth-password.html
new file mode 100644
index 0000000..ae91f84
--- /dev/null
+++ b/doc/src/sgml/html/auth-password.html
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.5. Password Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-trust.html" title="21.4. Trust Authentication" /><link rel="next" href="gssapi-auth.html" title="21.6. GSSAPI Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.5. Password Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-trust.html" title="21.4. Trust Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-PASSWORD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.5. Password Authentication</h2></div></div></div><a id="id-1.6.8.12.2" class="indexterm"></a><a id="id-1.6.8.12.3" class="indexterm"></a><a id="id-1.6.8.12.4" class="indexterm"></a><p>
+ There are several password-based authentication methods. These methods
+ operate similarly but differ in how the users' passwords are stored on the
+ server and how the password provided by a client is sent across the
+ connection.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">scram-sha-256</code></span></dt><dd><p>
+ The method <code class="literal">scram-sha-256</code> performs SCRAM-SHA-256
+ authentication, as described in
+ <a class="ulink" href="https://tools.ietf.org/html/rfc7677" target="_top">RFC 7677</a>. It
+ is a challenge-response scheme that prevents password sniffing on
+ untrusted connections and supports storing passwords on the server in a
+ cryptographically hashed form that is thought to be secure.
+ </p><p>
+ This is the most secure of the currently provided methods, but it is
+ not supported by older client libraries.
+ </p></dd><dt><span class="term"><code class="literal">md5</code></span></dt><dd><p>
+ The method <code class="literal">md5</code> uses a custom less secure challenge-response
+ mechanism. It prevents password sniffing and avoids storing passwords
+ on the server in plain text but provides no protection if an attacker
+ manages to steal the password hash from the server. Also, the MD5 hash
+ algorithm is nowadays no longer considered secure against determined
+ attacks.
+ </p><p>
+ The <code class="literal">md5</code> method cannot be used with
+ the <a class="xref" href="runtime-config-connection.html#GUC-DB-USER-NAMESPACE">db_user_namespace</a> feature.
+ </p><p>
+ To ease transition from the <code class="literal">md5</code> method to the newer
+ SCRAM method, if <code class="literal">md5</code> is specified as a method
+ in <code class="filename">pg_hba.conf</code> but the user's password on the
+ server is encrypted for SCRAM (see below), then SCRAM-based
+ authentication will automatically be chosen instead.
+ </p></dd><dt><span class="term"><code class="literal">password</code></span></dt><dd><p>
+ The method <code class="literal">password</code> sends the password in clear-text and is
+ therefore vulnerable to password <span class="quote">“<span class="quote">sniffing</span>”</span> attacks. It should
+ always be avoided if possible. If the connection is protected by SSL
+ encryption then <code class="literal">password</code> can be used safely, though.
+ (Though SSL certificate authentication might be a better choice if one
+ is depending on using SSL).
+ </p></dd></dl></div><p>
+ <span class="productname">PostgreSQL</span> database passwords are
+ separate from operating system user passwords. The password for
+ each database user is stored in the <code class="literal">pg_authid</code> system
+ catalog. Passwords can be managed with the SQL commands
+ <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a> and
+ <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>,
+ e.g., <strong class="userinput"><code>CREATE ROLE foo WITH LOGIN PASSWORD 'secret'</code></strong>,
+ or the <span class="application">psql</span>
+ command <code class="literal">\password</code>.
+ If no password has been set up for a user, the stored password
+ is null and password authentication will always fail for that user.
+ </p><p>
+ The availability of the different password-based authentication methods
+ depends on how a user's password on the server is encrypted (or hashed,
+ more accurately). This is controlled by the configuration
+ parameter <a class="xref" href="runtime-config-connection.html#GUC-PASSWORD-ENCRYPTION">password_encryption</a> at the time the
+ password is set. If a password was encrypted using
+ the <code class="literal">scram-sha-256</code> setting, then it can be used for the
+ authentication methods <code class="literal">scram-sha-256</code>
+ and <code class="literal">password</code> (but password transmission will be in
+ plain text in the latter case). The authentication method
+ specification <code class="literal">md5</code> will automatically switch to using
+ the <code class="literal">scram-sha-256</code> method in this case, as explained
+ above, so it will also work. If a password was encrypted using
+ the <code class="literal">md5</code> setting, then it can be used only for
+ the <code class="literal">md5</code> and <code class="literal">password</code> authentication
+ method specifications (again, with the password transmitted in plain text
+ in the latter case). (Previous PostgreSQL releases supported storing the
+ password on the server in plain text. This is no longer possible.) To
+ check the currently stored password hashes, see the system
+ catalog <code class="literal">pg_authid</code>.
+ </p><p>
+ To upgrade an existing installation from <code class="literal">md5</code>
+ to <code class="literal">scram-sha-256</code>, after having ensured that all client
+ libraries in use are new enough to support SCRAM,
+ set <code class="literal">password_encryption = 'scram-sha-256'</code>
+ in <code class="filename">postgresql.conf</code>, make all users set new passwords,
+ and change the authentication method specifications
+ in <code class="filename">pg_hba.conf</code> to <code class="literal">scram-sha-256</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-trust.html" title="21.4. Trust Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.4. Trust Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.6. GSSAPI Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-peer.html b/doc/src/sgml/html/auth-peer.html
new file mode 100644
index 0000000..b5a6b42
--- /dev/null
+++ b/doc/src/sgml/html/auth-peer.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.9. Peer Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-ident.html" title="21.8. Ident Authentication" /><link rel="next" href="auth-ldap.html" title="21.10. LDAP Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.9. Peer Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-ident.html" title="21.8. Ident Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-ldap.html" title="21.10. LDAP Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-PEER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.9. Peer Authentication</h2></div></div></div><a id="id-1.6.8.16.2" class="indexterm"></a><p>
+ The peer authentication method works by obtaining the client's
+ operating system user name from the kernel and using it as the
+ allowed database user name (with optional user name mapping). This
+ method is only supported on local connections.
+ </p><p>
+ The following configuration options are supported for <code class="literal">peer</code>:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">map</code></span></dt><dd><p>
+ Allows for mapping between system and database user names. See
+ <a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a> for details.
+ </p></dd></dl></div><p>
+ </p><p>
+ Peer authentication is only available on operating systems providing
+ the <code class="function">getpeereid()</code> function, the <code class="symbol">SO_PEERCRED</code>
+ socket parameter, or similar mechanisms. Currently that includes
+ <span class="systemitem">Linux</span>,
+ most flavors of <span class="systemitem">BSD</span> including
+ <span class="systemitem">macOS</span>,
+ and <span class="systemitem">Solaris</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-ident.html" title="21.8. Ident Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-ldap.html" title="21.10. LDAP Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.8. Ident Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.10. LDAP Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-pg-hba-conf.html b/doc/src/sgml/html/auth-pg-hba-conf.html
new file mode 100644
index 0000000..04903d2
--- /dev/null
+++ b/doc/src/sgml/html/auth-pg-hba-conf.html
@@ -0,0 +1,492 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.1. The pg_hba.conf File</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="client-authentication.html" title="Chapter 21. Client Authentication" /><link rel="next" href="auth-username-maps.html" title="21.2. User Name Maps" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.1. The <code class="filename">pg_hba.conf</code> File</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="client-authentication.html" title="Chapter 21. Client Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-username-maps.html" title="21.2. User Name Maps">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-PG-HBA-CONF"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.1. The <code class="filename">pg_hba.conf</code> File</h2></div></div></div><a id="id-1.6.8.8.2" class="indexterm"></a><p>
+ Client authentication is controlled by a configuration file,
+ which traditionally is named
+ <code class="filename">pg_hba.conf</code> and is stored in the database
+ cluster's data directory.
+ (<acronym class="acronym">HBA</acronym> stands for host-based authentication.) A default
+ <code class="filename">pg_hba.conf</code> file is installed when the data
+ directory is initialized by <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a>. It is
+ possible to place the authentication configuration file elsewhere,
+ however; see the <a class="xref" href="runtime-config-file-locations.html#GUC-HBA-FILE">hba_file</a> configuration parameter.
+ </p><p>
+ The general format of the <code class="filename">pg_hba.conf</code> file is
+ a set of records, one per line. Blank lines are ignored, as is any
+ text after the <code class="literal">#</code> comment character.
+ A record can be continued onto the next line by ending the line with
+ a backslash. (Backslashes are not special except at the end of a line.)
+ A record is made
+ up of a number of fields which are separated by spaces and/or tabs.
+ Fields can contain white space if the field value is double-quoted.
+ Quoting one of the keywords in a database, user, or address field (e.g.,
+ <code class="literal">all</code> or <code class="literal">replication</code>) makes the word lose its special
+ meaning, and just match a database, user, or host with that name.
+ Backslash line continuation applies even within quoted text or comments.
+ </p><p>
+ Each record specifies a connection type, a client IP address range
+ (if relevant for the connection type), a database name, a user name,
+ and the authentication method to be used for connections matching
+ these parameters. The first record with a matching connection type,
+ client address, requested database, and user name is used to perform
+ authentication. There is no <span class="quote">“<span class="quote">fall-through</span>”</span> or
+ <span class="quote">“<span class="quote">backup</span>”</span>: if one record is chosen and the authentication
+ fails, subsequent records are not considered. If no record matches,
+ access is denied.
+ </p><p>
+ A record can have several formats:
+</p><pre class="synopsis">
+local <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+host <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>address</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostssl <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>address</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostnossl <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>address</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostgssenc <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>address</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostnogssenc <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>address</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+host <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>IP-address</code></em> <em class="replaceable"><code>IP-mask</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostssl <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>IP-address</code></em> <em class="replaceable"><code>IP-mask</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostnossl <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>IP-address</code></em> <em class="replaceable"><code>IP-mask</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostgssenc <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>IP-address</code></em> <em class="replaceable"><code>IP-mask</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+hostnogssenc <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>IP-address</code></em> <em class="replaceable"><code>IP-mask</code></em> <em class="replaceable"><code>auth-method</code></em> [<span class="optional"><em class="replaceable"><code>auth-options</code></em></span>]
+</pre><p>
+ The meaning of the fields is as follows:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">local</code></span></dt><dd><p>
+ This record matches connection attempts using Unix-domain
+ sockets. Without a record of this type, Unix-domain socket
+ connections are disallowed.
+ </p></dd><dt><span class="term"><code class="literal">host</code></span></dt><dd><p>
+ This record matches connection attempts made using TCP/IP.
+ <code class="literal">host</code> records match
+ <acronym class="acronym">SSL</acronym> or non-<acronym class="acronym">SSL</acronym> connection
+ attempts as well as <acronym class="acronym">GSSAPI</acronym> encrypted or
+ non-<acronym class="acronym">GSSAPI</acronym> encrypted connection attempts.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Remote TCP/IP connections will not be possible unless
+ the server is started with an appropriate value for the
+ <a class="xref" href="runtime-config-connection.html#GUC-LISTEN-ADDRESSES">listen_addresses</a> configuration parameter,
+ since the default behavior is to listen for TCP/IP connections
+ only on the local loopback address <code class="literal">localhost</code>.
+ </p></div></dd><dt><span class="term"><code class="literal">hostssl</code></span></dt><dd><p>
+ This record matches connection attempts made using TCP/IP,
+ but only when the connection is made with <acronym class="acronym">SSL</acronym>
+ encryption.
+ </p><p>
+ To make use of this option the server must be built with
+ <acronym class="acronym">SSL</acronym> support. Furthermore,
+ <acronym class="acronym">SSL</acronym> must be enabled
+ by setting the <a class="xref" href="runtime-config-connection.html#GUC-SSL">ssl</a> configuration parameter (see
+ <a class="xref" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Section 19.9</a> for more information).
+ Otherwise, the <code class="literal">hostssl</code> record is ignored except for
+ logging a warning that it cannot match any connections.
+ </p></dd><dt><span class="term"><code class="literal">hostnossl</code></span></dt><dd><p>
+ This record type has the opposite behavior of <code class="literal">hostssl</code>;
+ it only matches connection attempts made over
+ TCP/IP that do not use <acronym class="acronym">SSL</acronym>.
+ </p></dd><dt><span class="term"><code class="literal">hostgssenc</code></span></dt><dd><p>
+ This record matches connection attempts made using TCP/IP,
+ but only when the connection is made with <acronym class="acronym">GSSAPI</acronym>
+ encryption.
+ </p><p>
+ To make use of this option the server must be built with
+ <acronym class="acronym">GSSAPI</acronym> support. Otherwise,
+ the <code class="literal">hostgssenc</code> record is ignored except for logging
+ a warning that it cannot match any connections.
+ </p></dd><dt><span class="term"><code class="literal">hostnogssenc</code></span></dt><dd><p>
+ This record type has the opposite behavior of <code class="literal">hostgssenc</code>;
+ it only matches connection attempts made over
+ TCP/IP that do not use <acronym class="acronym">GSSAPI</acronym> encryption.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>database</code></em></span></dt><dd><p>
+ Specifies which database name(s) this record matches. The value
+ <code class="literal">all</code> specifies that it matches all databases.
+ The value <code class="literal">sameuser</code> specifies that the record
+ matches if the requested database has the same name as the
+ requested user. The value <code class="literal">samerole</code> specifies that
+ the requested user must be a member of the role with the same
+ name as the requested database. (<code class="literal">samegroup</code> is an
+ obsolete but still accepted spelling of <code class="literal">samerole</code>.)
+ Superusers are not considered to be members of a role for the
+ purposes of <code class="literal">samerole</code> unless they are explicitly
+ members of the role, directly or indirectly, and not just by
+ virtue of being a superuser.
+ The value <code class="literal">replication</code> specifies that the record
+ matches if a physical replication connection is requested, however, it
+ doesn't match with logical replication connections. Note that physical
+ replication connections do not specify any particular database whereas
+ logical replication connections do specify it.
+ Otherwise, this is the name of
+ a specific <span class="productname">PostgreSQL</span> database.
+ Multiple database names can be supplied by separating them with
+ commas. A separate file containing database names can be specified by
+ preceding the file name with <code class="literal">@</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user</code></em></span></dt><dd><p>
+ Specifies which database user name(s) this record
+ matches. The value <code class="literal">all</code> specifies that it
+ matches all users. Otherwise, this is either the name of a specific
+ database user, or a group name preceded by <code class="literal">+</code>.
+ (Recall that there is no real distinction between users and groups
+ in <span class="productname">PostgreSQL</span>; a <code class="literal">+</code> mark really means
+ <span class="quote">“<span class="quote">match any of the roles that are directly or indirectly members
+ of this role</span>”</span>, while a name without a <code class="literal">+</code> mark matches
+ only that specific role.) For this purpose, a superuser is only
+ considered to be a member of a role if they are explicitly a member
+ of the role, directly or indirectly, and not just by virtue of
+ being a superuser.
+ Multiple user names can be supplied by separating them with commas.
+ A separate file containing user names can be specified by preceding the
+ file name with <code class="literal">@</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>address</code></em></span></dt><dd><p>
+ Specifies the client machine address(es) that this record
+ matches. This field can contain either a host name, an IP
+ address range, or one of the special key words mentioned below.
+ </p><p>
+ An IP address range is specified using standard numeric notation
+ for the range's starting address, then a slash (<code class="literal">/</code>)
+ and a <acronym class="acronym">CIDR</acronym> mask length. The mask
+ length indicates the number of high-order bits of the client
+ IP address that must match. Bits to the right of this should
+ be zero in the given IP address.
+ There must not be any white space between the IP address, the
+ <code class="literal">/</code>, and the CIDR mask length.
+ </p><p>
+ Typical examples of an IPv4 address range specified this way are
+ <code class="literal">172.20.143.89/32</code> for a single host, or
+ <code class="literal">172.20.143.0/24</code> for a small network, or
+ <code class="literal">10.6.0.0/16</code> for a larger one.
+ An IPv6 address range might look like <code class="literal">::1/128</code>
+ for a single host (in this case the IPv6 loopback address) or
+ <code class="literal">fe80::7a31:c1ff:0000:0000/96</code> for a small
+ network.
+ <code class="literal">0.0.0.0/0</code> represents all
+ IPv4 addresses, and <code class="literal">::0/0</code> represents
+ all IPv6 addresses.
+ To specify a single host, use a mask length of 32 for IPv4 or
+ 128 for IPv6. In a network address, do not omit trailing zeroes.
+ </p><p>
+ An entry given in IPv4 format will match only IPv4 connections,
+ and an entry given in IPv6 format will match only IPv6 connections,
+ even if the represented address is in the IPv4-in-IPv6 range.
+ Note that entries in IPv6 format will be rejected if the system's
+ C library does not have support for IPv6 addresses.
+ </p><p>
+ You can also write <code class="literal">all</code> to match any IP address,
+ <code class="literal">samehost</code> to match any of the server's own IP
+ addresses, or <code class="literal">samenet</code> to match any address in any
+ subnet that the server is directly connected to.
+ </p><p>
+ If a host name is specified (anything that is not an IP address
+ range or a special key word is treated as a host name),
+ that name is compared with the result of a reverse name
+ resolution of the client's IP address (e.g., reverse DNS
+ lookup, if DNS is used). Host name comparisons are case
+ insensitive. If there is a match, then a forward name
+ resolution (e.g., forward DNS lookup) is performed on the host
+ name to check whether any of the addresses it resolves to are
+ equal to the client's IP address. If both directions match,
+ then the entry is considered to match. (The host name that is
+ used in <code class="filename">pg_hba.conf</code> should be the one that
+ address-to-name resolution of the client's IP address returns,
+ otherwise the line won't be matched. Some host name databases
+ allow associating an IP address with multiple host names, but
+ the operating system will only return one host name when asked
+ to resolve an IP address.)
+ </p><p>
+ A host name specification that starts with a dot
+ (<code class="literal">.</code>) matches a suffix of the actual host
+ name. So <code class="literal">.example.com</code> would match
+ <code class="literal">foo.example.com</code> (but not just
+ <code class="literal">example.com</code>).
+ </p><p>
+ When host names are specified
+ in <code class="filename">pg_hba.conf</code>, you should make sure that
+ name resolution is reasonably fast. It can be of advantage to
+ set up a local name resolution cache such
+ as <code class="command">nscd</code>. Also, you may wish to enable the
+ configuration parameter <code class="varname">log_hostname</code> to see
+ the client's host name instead of the IP address in the log.
+ </p><p>
+ These fields do not apply to <code class="literal">local</code> records.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Users sometimes wonder why host names are handled
+ in this seemingly complicated way, with two name resolutions
+ including a reverse lookup of the client's IP address. This
+ complicates use of the feature in case the client's reverse DNS
+ entry is not set up or yields some undesirable host name.
+ It is done primarily for efficiency: this way, a connection attempt
+ requires at most two resolver lookups, one reverse and one forward.
+ If there is a resolver problem with some address, it becomes only
+ that client's problem. A hypothetical alternative
+ implementation that only did forward lookups would have to
+ resolve every host name mentioned in
+ <code class="filename">pg_hba.conf</code> during every connection attempt.
+ That could be quite slow if many names are listed.
+ And if there is a resolver problem with one of the host names,
+ it becomes everyone's problem.
+ </p><p>
+ Also, a reverse lookup is necessary to implement the suffix
+ matching feature, because the actual client host name needs to
+ be known in order to match it against the pattern.
+ </p><p>
+ Note that this behavior is consistent with other popular
+ implementations of host name-based access control, such as the
+ Apache HTTP Server and TCP Wrappers.
+ </p></div></dd><dt><span class="term"><em class="replaceable"><code>IP-address</code></em><br /></span><span class="term"><em class="replaceable"><code>IP-mask</code></em></span></dt><dd><p>
+ These two fields can be used as an alternative to the
+ <em class="replaceable"><code>IP-address</code></em><code class="literal">/</code><em class="replaceable"><code>mask-length</code></em>
+ notation. Instead of
+ specifying the mask length, the actual mask is specified in a
+ separate column. For example, <code class="literal">255.0.0.0</code> represents an IPv4
+ CIDR mask length of 8, and <code class="literal">255.255.255.255</code> represents a
+ CIDR mask length of 32.
+ </p><p>
+ These fields do not apply to <code class="literal">local</code> records.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>auth-method</code></em></span></dt><dd><p>
+ Specifies the authentication method to use when a connection matches
+ this record. The possible choices are summarized here; details
+ are in <a class="xref" href="auth-methods.html" title="21.3. Authentication Methods">Section 21.3</a>. All the options
+ are lower case and treated case sensitively, so even acronyms like
+ <code class="literal">ldap</code> must be specified as lower case.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">trust</code></span></dt><dd><p>
+ Allow the connection unconditionally. This method
+ allows anyone that can connect to the
+ <span class="productname">PostgreSQL</span> database server to login as
+ any <span class="productname">PostgreSQL</span> user they wish,
+ without the need for a password or any other authentication. See <a class="xref" href="auth-trust.html" title="21.4. Trust Authentication">Section 21.4</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">reject</code></span></dt><dd><p>
+ Reject the connection unconditionally. This is useful for
+ <span class="quote">“<span class="quote">filtering out</span>”</span> certain hosts from a group, for example a
+ <code class="literal">reject</code> line could block a specific host from connecting,
+ while a later line allows the remaining hosts in a specific
+ network to connect.
+ </p></dd><dt><span class="term"><code class="literal">scram-sha-256</code></span></dt><dd><p>
+ Perform SCRAM-SHA-256 authentication to verify the user's
+ password. See <a class="xref" href="auth-password.html" title="21.5. Password Authentication">Section 21.5</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">md5</code></span></dt><dd><p>
+ Perform SCRAM-SHA-256 or MD5 authentication to verify the
+ user's password. See <a class="xref" href="auth-password.html" title="21.5. Password Authentication">Section 21.5</a>
+ for details.
+ </p></dd><dt><span class="term"><code class="literal">password</code></span></dt><dd><p>
+ Require the client to supply an unencrypted password for
+ authentication.
+ Since the password is sent in clear text over the
+ network, this should not be used on untrusted networks.
+ See <a class="xref" href="auth-password.html" title="21.5. Password Authentication">Section 21.5</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">gss</code></span></dt><dd><p>
+ Use GSSAPI to authenticate the user. This is only
+ available for TCP/IP connections. See <a class="xref" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Section 21.6</a> for details. It can be used in conjunction
+ with GSSAPI encryption.
+ </p></dd><dt><span class="term"><code class="literal">sspi</code></span></dt><dd><p>
+ Use SSPI to authenticate the user. This is only
+ available on Windows. See <a class="xref" href="sspi-auth.html" title="21.7. SSPI Authentication">Section 21.7</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">ident</code></span></dt><dd><p>
+ Obtain the operating system user name of the client
+ by contacting the ident server on the client
+ and check if it matches the requested database user name.
+ Ident authentication can only be used on TCP/IP
+ connections. When specified for local connections, peer
+ authentication will be used instead.
+ See <a class="xref" href="auth-ident.html" title="21.8. Ident Authentication">Section 21.8</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">peer</code></span></dt><dd><p>
+ Obtain the client's operating system user name from the operating
+ system and check if it matches the requested database user name.
+ This is only available for local connections.
+ See <a class="xref" href="auth-peer.html" title="21.9. Peer Authentication">Section 21.9</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">ldap</code></span></dt><dd><p>
+ Authenticate using an <acronym class="acronym">LDAP</acronym> server. See <a class="xref" href="auth-ldap.html" title="21.10. LDAP Authentication">Section 21.10</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">radius</code></span></dt><dd><p>
+ Authenticate using a RADIUS server. See <a class="xref" href="auth-radius.html" title="21.11. RADIUS Authentication">Section 21.11</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">cert</code></span></dt><dd><p>
+ Authenticate using SSL client certificates. See
+ <a class="xref" href="auth-cert.html" title="21.12. Certificate Authentication">Section 21.12</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">pam</code></span></dt><dd><p>
+ Authenticate using the Pluggable Authentication Modules
+ (PAM) service provided by the operating system. See <a class="xref" href="auth-pam.html" title="21.13. PAM Authentication">Section 21.13</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">bsd</code></span></dt><dd><p>
+ Authenticate using the BSD Authentication service provided by the
+ operating system. See <a class="xref" href="auth-bsd.html" title="21.14. BSD Authentication">Section 21.14</a> for details.
+ </p></dd></dl></div><p>
+
+ </p></dd><dt><span class="term"><em class="replaceable"><code>auth-options</code></em></span></dt><dd><p>
+ After the <em class="replaceable"><code>auth-method</code></em> field, there can be field(s) of
+ the form <em class="replaceable"><code>name</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em> that
+ specify options for the authentication method. Details about which
+ options are available for which authentication methods appear below.
+ </p><p>
+ In addition to the method-specific options listed below, there is a
+ method-independent authentication option <code class="literal">clientcert</code>, which
+ can be specified in any <code class="literal">hostssl</code> record.
+ This option can be set to <code class="literal">verify-ca</code> or
+ <code class="literal">verify-full</code>. Both options require the client
+ to present a valid (trusted) SSL certificate, while
+ <code class="literal">verify-full</code> additionally enforces that the
+ <code class="literal">cn</code> (Common Name) in the certificate matches
+ the username or an applicable mapping.
+ This behavior is similar to the <code class="literal">cert</code> authentication
+ method (see <a class="xref" href="auth-cert.html" title="21.12. Certificate Authentication">Section 21.12</a>) but enables pairing
+ the verification of client certificates with any authentication
+ method that supports <code class="literal">hostssl</code> entries.
+ </p><p>
+ On any record using client certificate authentication (i.e. one
+ using the <code class="literal">cert</code> authentication method or one
+ using the <code class="literal">clientcert</code> option), you can specify
+ which part of the client certificate credentials to match using
+ the <code class="literal">clientname</code> option. This option can have one
+ of two values. If you specify <code class="literal">clientname=CN</code>, which
+ is the default, the username is matched against the certificate's
+ <code class="literal">Common Name (CN)</code>. If instead you specify
+ <code class="literal">clientname=DN</code> the username is matched against the
+ entire <code class="literal">Distinguished Name (DN)</code> of the certificate.
+ This option is probably best used in conjunction with a username map.
+ The comparison is done with the <code class="literal">DN</code> in
+ <a class="ulink" href="https://tools.ietf.org/html/rfc2253" target="_top">RFC 2253</a>
+ format. To see the <code class="literal">DN</code> of a client certificate
+ in this format, do
+</p><pre class="programlisting">
+openssl x509 -in myclient.crt -noout --subject -nameopt RFC2253 | sed "s/^subject=//"
+</pre><p>
+ Care needs to be taken when using this option, especially when using
+ regular expression matching against the <code class="literal">DN</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ Files included by <code class="literal">@</code> constructs are read as lists of names,
+ which can be separated by either whitespace or commas. Comments are
+ introduced by <code class="literal">#</code>, just as in
+ <code class="filename">pg_hba.conf</code>, and nested <code class="literal">@</code> constructs are
+ allowed. Unless the file name following <code class="literal">@</code> is an absolute
+ path, it is taken to be relative to the directory containing the
+ referencing file.
+ </p><p>
+ Since the <code class="filename">pg_hba.conf</code> records are examined
+ sequentially for each connection attempt, the order of the records is
+ significant. Typically, earlier records will have tight connection
+ match parameters and weaker authentication methods, while later
+ records will have looser match parameters and stronger authentication
+ methods. For example, one might wish to use <code class="literal">trust</code>
+ authentication for local TCP/IP connections but require a password for
+ remote TCP/IP connections. In this case a record specifying
+ <code class="literal">trust</code> authentication for connections from 127.0.0.1 would
+ appear before a record specifying password authentication for a wider
+ range of allowed client IP addresses.
+ </p><p>
+ The <code class="filename">pg_hba.conf</code> file is read on start-up and when
+ the main server process receives a
+ <span class="systemitem">SIGHUP</span><a id="id-1.6.8.8.9.3" class="indexterm"></a>
+ signal. If you edit the file on an
+ active system, you will need to signal the postmaster
+ (using <code class="literal">pg_ctl reload</code>, calling the SQL function
+ <code class="function">pg_reload_conf()</code>, or using <code class="literal">kill
+ -HUP</code>) to make it re-read the file.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The preceding statement is not true on Microsoft Windows: there, any
+ changes in the <code class="filename">pg_hba.conf</code> file are immediately
+ applied by subsequent new connections.
+ </p></div><p>
+ The system view
+ <a class="link" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules"><code class="structname">pg_hba_file_rules</code></a>
+ can be helpful for pre-testing changes to the <code class="filename">pg_hba.conf</code>
+ file, or for diagnosing problems if loading of the file did not have the
+ desired effects. Rows in the view with
+ non-null <code class="structfield">error</code> fields indicate problems in the
+ corresponding lines of the file.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ To connect to a particular database, a user must not only pass the
+ <code class="filename">pg_hba.conf</code> checks, but must have the
+ <code class="literal">CONNECT</code> privilege for the database. If you wish to
+ restrict which users can connect to which databases, it's usually
+ easier to control this by granting/revoking <code class="literal">CONNECT</code> privilege
+ than to put the rules in <code class="filename">pg_hba.conf</code> entries.
+ </p></div><p>
+ Some examples of <code class="filename">pg_hba.conf</code> entries are shown in
+ <a class="xref" href="auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF" title="Example 21.1. Example pg_hba.conf Entries">Example 21.1</a>. See the next section for details on the
+ different authentication methods.
+ </p><div class="example" id="EXAMPLE-PG-HBA.CONF"><p class="title"><strong>Example 21.1. Example <code class="filename">pg_hba.conf</code> Entries</strong></p><div class="example-contents"><pre class="programlisting">
+# Allow any user on the local system to connect to any database with
+# any database user name using Unix-domain sockets (the default for local
+# connections).
+#
+# TYPE DATABASE USER ADDRESS METHOD
+local all all trust
+
+# The same using local loopback TCP/IP connections.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all 127.0.0.1/32 trust
+
+# The same as the previous line, but using a separate netmask column
+#
+# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
+host all all 127.0.0.1 255.255.255.255 trust
+
+# The same over IPv6.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all ::1/128 trust
+
+# The same using a host name (would typically cover both IPv4 and IPv6).
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all localhost trust
+
+# Allow any user from any host with IP address 192.168.93.x to connect
+# to database "postgres" as the same user name that ident reports for
+# the connection (typically the operating system user name).
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host postgres all 192.168.93.0/24 ident
+
+# Allow any user from host 192.168.12.10 to connect to database
+# "postgres" if the user's password is correctly supplied.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host postgres all 192.168.12.10/32 scram-sha-256
+
+# Allow any user from hosts in the example.com domain to connect to
+# any database if the user's password is correctly supplied.
+#
+# Require SCRAM authentication for most users, but make an exception
+# for user 'mike', who uses an older client that doesn't support SCRAM
+# authentication.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all mike .example.com md5
+host all all .example.com scram-sha-256
+
+# In the absence of preceding "host" lines, these three lines will
+# reject all connections from 192.168.54.1 (since that entry will be
+# matched first), but allow GSSAPI-encrypted connections from anywhere else
+# on the Internet. The zero mask causes no bits of the host IP address to
+# be considered, so it matches any host. Unencrypted GSSAPI connections
+# (which "fall through" to the third line since "hostgssenc" only matches
+# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all 192.168.54.1/32 reject
+hostgssenc all all 0.0.0.0/0 gss
+host all all 192.168.12.10/32 gss
+
+# Allow users from 192.168.x.x hosts to connect to any database, if
+# they pass the ident check. If, for example, ident says the user is
+# "bryanh" and he requests to connect as PostgreSQL user "guest1", the
+# connection is allowed if there is an entry in pg_ident.conf for map
+# "omicron" that says "bryanh" is allowed to connect as "guest1".
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host all all 192.168.0.0/16 ident map=omicron
+
+# If these are the only three lines for local connections, they will
+# allow local users to connect only to their own databases (databases
+# with the same name as their database user name) except for administrators
+# and members of role "support", who can connect to all databases. The file
+# $PGDATA/admins contains a list of names of administrators. Passwords
+# are required in all cases.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+local sameuser all md5
+local all @admins md5
+local all +support md5
+
+# The last two lines above can be combined into a single line:
+local all @admins,+support md5
+
+# The database column can also use lists and file names:
+local db1,db2,@demodbs all md5
+</pre></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="client-authentication.html" title="Chapter 21. Client Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-username-maps.html" title="21.2. User Name Maps">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 21. Client Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.2. User Name Maps</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-radius.html b/doc/src/sgml/html/auth-radius.html
new file mode 100644
index 0000000..4fd5143
--- /dev/null
+++ b/doc/src/sgml/html/auth-radius.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.11. RADIUS Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-ldap.html" title="21.10. LDAP Authentication" /><link rel="next" href="auth-cert.html" title="21.12. Certificate Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.11. RADIUS Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-ldap.html" title="21.10. LDAP Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-cert.html" title="21.12. Certificate Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-RADIUS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.11. RADIUS Authentication</h2></div></div></div><a id="id-1.6.8.18.2" class="indexterm"></a><p>
+ This authentication method operates similarly to
+ <code class="literal">password</code> except that it uses RADIUS
+ as the password verification method. RADIUS is used only to validate
+ the user name/password pairs. Therefore the user must already
+ exist in the database before RADIUS can be used for
+ authentication.
+ </p><p>
+ When using RADIUS authentication, an Access Request message will be sent
+ to the configured RADIUS server. This request will be of type
+ <code class="literal">Authenticate Only</code>, and include parameters for
+ <code class="literal">user name</code>, <code class="literal">password</code> (encrypted) and
+ <code class="literal">NAS Identifier</code>. The request will be encrypted using
+ a secret shared with the server. The RADIUS server will respond to
+ this request with either <code class="literal">Access Accept</code> or
+ <code class="literal">Access Reject</code>. There is no support for RADIUS accounting.
+ </p><p>
+ Multiple RADIUS servers can be specified, in which case they will
+ be tried sequentially. If a negative response is received from
+ a server, the authentication will fail. If no response is received,
+ the next server in the list will be tried. To specify multiple
+ servers, separate the server names with commas and surround the list
+ with double quotes. If multiple servers are specified, the other
+ RADIUS options can also be given as comma-separated lists, to provide
+ individual values for each server. They can also be specified as
+ a single value, in which case that value will apply to all servers.
+ </p><p>
+ The following configuration options are supported for RADIUS:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">radiusservers</code></span></dt><dd><p>
+ The DNS names or IP addresses of the RADIUS servers to connect to.
+ This parameter is required.
+ </p></dd><dt><span class="term"><code class="literal">radiussecrets</code></span></dt><dd><p>
+ The shared secrets used when talking securely to the RADIUS
+ servers. This must have exactly the same value on the PostgreSQL
+ and RADIUS servers. It is recommended that this be a string of
+ at least 16 characters. This parameter is required.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The encryption vector used will only be cryptographically
+ strong if <span class="productname">PostgreSQL</span> is built with support for
+ <span class="productname">OpenSSL</span>. In other cases, the transmission to the
+ RADIUS server should only be considered obfuscated, not secured, and
+ external security measures should be applied if necessary.
+ </p></div><p>
+ </p></dd><dt><span class="term"><code class="literal">radiusports</code></span></dt><dd><p>
+ The port numbers to connect to on the RADIUS servers. If no port
+ is specified, the default RADIUS port (<code class="literal">1812</code>)
+ will be used.
+ </p></dd><dt><span class="term"><code class="literal">radiusidentifiers</code></span></dt><dd><p>
+ The strings to be used as <code class="literal">NAS Identifier</code> in the
+ RADIUS requests. This parameter can be used, for example, to
+ identify which database cluster the user is attempting to connect
+ to, which can be useful for policy matching on
+ the RADIUS server. If no identifier is specified, the default
+ <code class="literal">postgresql</code> will be used.
+ </p></dd></dl></div><p>
+ </p><p>
+ If it is necessary to have a comma or whitespace in a RADIUS parameter
+ value, that can be done by putting double quotes around the value, but
+ it is tedious because two layers of double-quoting are now required.
+ An example of putting whitespace into RADIUS secret strings is:
+</p><pre class="programlisting">
+host ... radius radiusservers="server1,server2" radiussecrets="""secret one"",""secret two"""
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-ldap.html" title="21.10. LDAP Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-cert.html" title="21.12. Certificate Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.10. LDAP Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.12. Certificate Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-trust.html b/doc/src/sgml/html/auth-trust.html
new file mode 100644
index 0000000..639a91b
--- /dev/null
+++ b/doc/src/sgml/html/auth-trust.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.4. Trust Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-methods.html" title="21.3. Authentication Methods" /><link rel="next" href="auth-password.html" title="21.5. Password Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.4. Trust Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-methods.html" title="21.3. Authentication Methods">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-password.html" title="21.5. Password Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-TRUST"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.4. Trust Authentication</h2></div></div></div><p>
+ When <code class="literal">trust</code> authentication is specified,
+ <span class="productname">PostgreSQL</span> assumes that anyone who can
+ connect to the server is authorized to access the database with
+ whatever database user name they specify (even superuser names).
+ Of course, restrictions made in the <code class="literal">database</code> and
+ <code class="literal">user</code> columns still apply.
+ This method should only be used when there is adequate
+ operating-system-level protection on connections to the server.
+ </p><p>
+ <code class="literal">trust</code> authentication is appropriate and very
+ convenient for local connections on a single-user workstation. It
+ is usually <span class="emphasis"><em>not</em></span> appropriate by itself on a multiuser
+ machine. However, you might be able to use <code class="literal">trust</code> even
+ on a multiuser machine, if you restrict access to the server's
+ Unix-domain socket file using file-system permissions. To do this, set the
+ <code class="varname">unix_socket_permissions</code> (and possibly
+ <code class="varname">unix_socket_group</code>) configuration parameters as
+ described in <a class="xref" href="runtime-config-connection.html" title="20.3. Connections and Authentication">Section 20.3</a>. Or you
+ could set the <code class="varname">unix_socket_directories</code>
+ configuration parameter to place the socket file in a suitably
+ restricted directory.
+ </p><p>
+ Setting file-system permissions only helps for Unix-socket connections.
+ Local TCP/IP connections are not restricted by file-system permissions.
+ Therefore, if you want to use file-system permissions for local security,
+ remove the <code class="literal">host ... 127.0.0.1 ...</code> line from
+ <code class="filename">pg_hba.conf</code>, or change it to a
+ non-<code class="literal">trust</code> authentication method.
+ </p><p>
+ <code class="literal">trust</code> authentication is only suitable for TCP/IP connections
+ if you trust every user on every machine that is allowed to connect
+ to the server by the <code class="filename">pg_hba.conf</code> lines that specify
+ <code class="literal">trust</code>. It is seldom reasonable to use <code class="literal">trust</code>
+ for any TCP/IP connections other than those from <span class="systemitem">localhost</span> (127.0.0.1).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-methods.html" title="21.3. Authentication Methods">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-password.html" title="21.5. Password Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.3. Authentication Methods </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.5. Password Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auth-username-maps.html b/doc/src/sgml/html/auth-username-maps.html
new file mode 100644
index 0000000..08a293e
--- /dev/null
+++ b/doc/src/sgml/html/auth-username-maps.html
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.2. User Name Maps</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File" /><link rel="next" href="auth-methods.html" title="21.3. Authentication Methods" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.2. User Name Maps</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-methods.html" title="21.3. Authentication Methods">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTH-USERNAME-MAPS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.2. User Name Maps</h2></div></div></div><a id="id-1.6.8.9.2" class="indexterm"></a><p>
+ When using an external authentication system such as Ident or GSSAPI,
+ the name of the operating system user that initiated the connection
+ might not be the same as the database user (role) that is to be used.
+ In this case, a user name map can be applied to map the operating system
+ user name to a database user. To use user name mapping, specify
+ <code class="literal">map</code>=<em class="replaceable"><code>map-name</code></em>
+ in the options field in <code class="filename">pg_hba.conf</code>. This option is
+ supported for all authentication methods that receive external user names.
+ Since different mappings might be needed for different connections,
+ the name of the map to be used is specified in the
+ <em class="replaceable"><code>map-name</code></em> parameter in <code class="filename">pg_hba.conf</code>
+ to indicate which map to use for each individual connection.
+ </p><p>
+ User name maps are defined in the ident map file, which by default is named
+ <code class="filename">pg_ident.conf</code><a id="id-1.6.8.9.4.2" class="indexterm"></a>
+ and is stored in the
+ cluster's data directory. (It is possible to place the map file
+ elsewhere, however; see the <a class="xref" href="runtime-config-file-locations.html#GUC-IDENT-FILE">ident_file</a>
+ configuration parameter.)
+ The ident map file contains lines of the general form:
+</p><pre class="synopsis">
+<em class="replaceable"><code>map-name</code></em> <em class="replaceable"><code>system-username</code></em> <em class="replaceable"><code>database-username</code></em>
+</pre><p>
+ Comments, whitespace and line continuations are handled in the same way as in
+ <code class="filename">pg_hba.conf</code>. The
+ <em class="replaceable"><code>map-name</code></em> is an arbitrary name that will be used to
+ refer to this mapping in <code class="filename">pg_hba.conf</code>. The other
+ two fields specify an operating system user name and a matching
+ database user name. The same <em class="replaceable"><code>map-name</code></em> can be
+ used repeatedly to specify multiple user-mappings within a single map.
+ </p><p>
+ There is no restriction regarding how many database users a given
+ operating system user can correspond to, nor vice versa. Thus, entries
+ in a map should be thought of as meaning <span class="quote">“<span class="quote">this operating system
+ user is allowed to connect as this database user</span>”</span>, rather than
+ implying that they are equivalent. The connection will be allowed if
+ there is any map entry that pairs the user name obtained from the
+ external authentication system with the database user name that the
+ user has requested to connect as.
+ </p><p>
+ If the <em class="replaceable"><code>system-username</code></em> field starts with a slash (<code class="literal">/</code>),
+ the remainder of the field is treated as a regular expression.
+ (See <a class="xref" href="functions-matching.html#POSIX-SYNTAX-DETAILS" title="9.7.3.1. Regular Expression Details">Section 9.7.3.1</a> for details of
+ <span class="productname">PostgreSQL</span>'s regular expression syntax.) The regular
+ expression can include a single capture, or parenthesized subexpression,
+ which can then be referenced in the <em class="replaceable"><code>database-username</code></em>
+ field as <code class="literal">\1</code> (backslash-one). This allows the mapping of
+ multiple user names in a single line, which is particularly useful for
+ simple syntax substitutions. For example, these entries
+</p><pre class="programlisting">
+mymap /^(.*)@mydomain\.com$ \1
+mymap /^(.*)@otherdomain\.com$ guest
+</pre><p>
+ will remove the domain part for users with system user names that end with
+ <code class="literal">@mydomain.com</code>, and allow any user whose system name ends with
+ <code class="literal">@otherdomain.com</code> to log in as <code class="literal">guest</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Keep in mind that by default, a regular expression can match just part of
+ a string. It's usually wise to use <code class="literal">^</code> and <code class="literal">$</code>, as
+ shown in the above example, to force the match to be to the entire
+ system user name.
+ </p></div><p>
+ The <code class="filename">pg_ident.conf</code> file is read on start-up and
+ when the main server process receives a
+ <span class="systemitem">SIGHUP</span><a id="id-1.6.8.9.8.3" class="indexterm"></a>
+ signal. If you edit the file on an
+ active system, you will need to signal the postmaster
+ (using <code class="literal">pg_ctl reload</code>, calling the SQL function
+ <code class="function">pg_reload_conf()</code>, or using <code class="literal">kill
+ -HUP</code>) to make it re-read the file.
+ </p><p>
+ The system view
+ <a class="link" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings"><code class="structname">pg_ident_file_mappings</code></a>
+ can be helpful for pre-testing changes to the
+ <code class="filename">pg_ident.conf</code> file, or for diagnosing problems if
+ loading of the file did not have the desired effects. Rows in the view with
+ non-null <code class="structfield">error</code> fields indicate problems in the
+ corresponding lines of the file.
+ </p><p>
+ A <code class="filename">pg_ident.conf</code> file that could be used in
+ conjunction with the <code class="filename">pg_hba.conf</code> file in <a class="xref" href="auth-pg-hba-conf.html#EXAMPLE-PG-HBA.CONF" title="Example 21.1. Example pg_hba.conf Entries">Example 21.1</a> is shown in <a class="xref" href="auth-username-maps.html#EXAMPLE-PG-IDENT.CONF" title="Example 21.2. An Example pg_ident.conf File">Example 21.2</a>. In this example, anyone
+ logged in to a machine on the 192.168 network that does not have the
+ operating system user name <code class="literal">bryanh</code>, <code class="literal">ann</code>, or
+ <code class="literal">robert</code> would not be granted access. Unix user
+ <code class="literal">robert</code> would only be allowed access when he tries to
+ connect as <span class="productname">PostgreSQL</span> user <code class="literal">bob</code>, not
+ as <code class="literal">robert</code> or anyone else. <code class="literal">ann</code> would
+ only be allowed to connect as <code class="literal">ann</code>. User
+ <code class="literal">bryanh</code> would be allowed to connect as either
+ <code class="literal">bryanh</code> or as <code class="literal">guest1</code>.
+ </p><div class="example" id="EXAMPLE-PG-IDENT.CONF"><p class="title"><strong>Example 21.2. An Example <code class="filename">pg_ident.conf</code> File</strong></p><div class="example-contents"><pre class="programlisting">
+# MAPNAME SYSTEM-USERNAME PG-USERNAME
+
+omicron bryanh bryanh
+omicron ann ann
+# bob has user name robert on these machines
+omicron robert bob
+# bryanh can also connect as guest1
+omicron bryanh guest1
+</pre></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-methods.html" title="21.3. Authentication Methods">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.1. The <code class="filename">pg_hba.conf</code> File </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.3. Authentication Methods</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/auto-explain.html b/doc/src/sgml/html/auto-explain.html
new file mode 100644
index 0000000..8527d17
--- /dev/null
+++ b/doc/src/sgml/html/auto-explain.html
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.4. auto_explain</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-delay.html" title="F.3. auth_delay" /><link rel="next" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.4. auto_explain</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-delay.html" title="F.3. auth_delay">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell">Next</a></td></tr></table><hr /></div><div class="sect1" id="AUTO-EXPLAIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.4. auto_explain</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="auto-explain.html#id-1.11.7.13.5">F.4.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="auto-explain.html#id-1.11.7.13.6">F.4.2. Example</a></span></dt><dt><span class="sect2"><a href="auto-explain.html#id-1.11.7.13.7">F.4.3. Author</a></span></dt></dl></div><a id="id-1.11.7.13.2" class="indexterm"></a><p>
+ The <code class="filename">auto_explain</code> module provides a means for
+ logging execution plans of slow statements automatically, without
+ having to run <a class="xref" href="sql-explain.html" title="EXPLAIN"><span class="refentrytitle">EXPLAIN</span></a>
+ by hand. This is especially helpful for tracking down un-optimized queries
+ in large applications.
+ </p><p>
+ The module provides no SQL-accessible functions. To use it, simply
+ load it into the server. You can load it into an individual session:
+
+</p><pre class="programlisting">
+LOAD 'auto_explain';
+</pre><p>
+
+ (You must be superuser to do that.) More typical usage is to preload
+ it into some or all sessions by including <code class="literal">auto_explain</code> in
+ <a class="xref" href="runtime-config-client.html#GUC-SESSION-PRELOAD-LIBRARIES">session_preload_libraries</a> or
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> in
+ <code class="filename">postgresql.conf</code>. Then you can track unexpectedly slow queries
+ no matter when they happen. Of course there is a price in overhead for
+ that.
+ </p><div class="sect2" id="id-1.11.7.13.5"><div class="titlepage"><div><div><h3 class="title">F.4.1. Configuration Parameters</h3></div></div></div><p>
+ There are several configuration parameters that control the behavior of
+ <code class="filename">auto_explain</code>. Note that the default behavior is
+ to do nothing, so you must set at least
+ <code class="varname">auto_explain.log_min_duration</code> if you want any results.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">auto_explain.log_min_duration</code> (<code class="type">integer</code>)
+ <a id="id-1.11.7.13.5.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_min_duration</code> is the minimum statement
+ execution time, in milliseconds, that will cause the statement's plan to
+ be logged. Setting this to <code class="literal">0</code> logs all plans.
+ <code class="literal">-1</code> (the default) disables logging of plans. For
+ example, if you set it to <code class="literal">250ms</code> then all statements
+ that run 250ms or longer will be logged. Only superusers can change this
+ setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_analyze</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_analyze</code> causes <code class="command">EXPLAIN ANALYZE</code>
+ output, rather than just <code class="command">EXPLAIN</code> output, to be printed
+ when an execution plan is logged. This parameter is off by default.
+ Only superusers can change this setting.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When this parameter is on, per-plan-node timing occurs for all
+ statements executed, whether or not they run long enough to actually
+ get logged. This can have an extremely negative impact on performance.
+ Turning off <code class="varname">auto_explain.log_timing</code> ameliorates the
+ performance cost, at the price of obtaining less information.
+ </p></div></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_buffers</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_buffers</code> controls whether buffer
+ usage statistics are printed when an execution plan is logged; it's
+ equivalent to the <code class="literal">BUFFERS</code> option of <code class="command">EXPLAIN</code>.
+ This parameter has no effect
+ unless <code class="varname">auto_explain.log_analyze</code> is enabled.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_wal</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_wal</code> controls whether WAL
+ usage statistics are printed when an execution plan is logged; it's
+ equivalent to the <code class="literal">WAL</code> option of <code class="command">EXPLAIN</code>.
+ This parameter has no effect
+ unless <code class="varname">auto_explain.log_analyze</code> is enabled.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_timing</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_timing</code> controls whether per-node
+ timing information is printed when an execution plan is logged; it's
+ equivalent to the <code class="literal">TIMING</code> option of <code class="command">EXPLAIN</code>.
+ The overhead of repeatedly reading the system clock can slow down
+ queries significantly on some systems, so it may be useful to set this
+ parameter to off when only actual row counts, and not exact times, are
+ needed.
+ This parameter has no effect
+ unless <code class="varname">auto_explain.log_analyze</code> is enabled.
+ This parameter is on by default.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_triggers</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_triggers</code> causes trigger
+ execution statistics to be included when an execution plan is logged.
+ This parameter has no effect
+ unless <code class="varname">auto_explain.log_analyze</code> is enabled.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_verbose</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_verbose</code> controls whether verbose
+ details are printed when an execution plan is logged; it's
+ equivalent to the <code class="literal">VERBOSE</code> option of <code class="command">EXPLAIN</code>.
+ This parameter is off by default.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_settings</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_settings</code> controls whether information
+ about modified configuration options is printed when an execution plan is logged.
+ Only options affecting query planning with value different from the built-in
+ default value are included in the output. This parameter is off by default.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_format</code> (<code class="type">enum</code>)
+ <a id="id-1.11.7.13.5.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_format</code> selects the
+ <code class="command">EXPLAIN</code> output format to be used.
+ The allowed values are <code class="literal">text</code>, <code class="literal">xml</code>,
+ <code class="literal">json</code>, and <code class="literal">yaml</code>. The default is text.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_level</code> (<code class="type">enum</code>)
+ <a id="id-1.11.7.13.5.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_level</code> selects the log level at which
+ auto_explain will log the query plan.
+ Valid values are <code class="literal">DEBUG5</code>, <code class="literal">DEBUG4</code>,
+ <code class="literal">DEBUG3</code>, <code class="literal">DEBUG2</code>,
+ <code class="literal">DEBUG1</code>, <code class="literal">INFO</code>,
+ <code class="literal">NOTICE</code>, <code class="literal">WARNING</code>,
+ and <code class="literal">LOG</code>. The default is <code class="literal">LOG</code>.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.log_nested_statements</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.13.5.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.log_nested_statements</code> causes nested
+ statements (statements executed inside a function) to be considered
+ for logging. When it is off, only top-level query plans are logged. This
+ parameter is off by default. Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">auto_explain.sample_rate</code> (<code class="type">real</code>)
+ <a id="id-1.11.7.13.5.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">auto_explain.sample_rate</code> causes auto_explain to only
+ explain a fraction of the statements in each session. The default is 1,
+ meaning explain all the queries. In case of nested statements, either all
+ will be explained or none. Only superusers can change this setting.
+ </p></dd></dl></div><p>
+ In ordinary usage, these parameters are set
+ in <code class="filename">postgresql.conf</code>, although superusers can alter them
+ on-the-fly within their own sessions.
+ Typical usage might be:
+ </p><pre class="programlisting">
+# postgresql.conf
+session_preload_libraries = 'auto_explain'
+
+auto_explain.log_min_duration = '3s'
+</pre></div><div class="sect2" id="id-1.11.7.13.6"><div class="titlepage"><div><div><h3 class="title">F.4.2. Example</h3></div></div></div><pre class="programlisting">
+postgres=# LOAD 'auto_explain';
+postgres=# SET auto_explain.log_min_duration = 0;
+postgres=# SET auto_explain.log_analyze = true;
+postgres=# SELECT count(*)
+ FROM pg_class, pg_index
+ WHERE oid = indrelid AND indisunique;
+</pre><p>
+ This might produce log output such as:
+ </p><pre class="screen">
+LOG: duration: 3.651 ms plan:
+ Query Text: SELECT count(*)
+ FROM pg_class, pg_index
+ WHERE oid = indrelid AND indisunique;
+ Aggregate (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1 loops=1)
+ -&gt; Hash Join (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 loops=1)
+ Hash Cond: (pg_class.oid = pg_index.indrelid)
+ -&gt; Seq Scan on pg_class (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255 loops=1)
+ -&gt; Hash (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 loops=1)
+ Buckets: 1024 Batches: 1 Memory Usage: 4kB
+ -&gt; Seq Scan on pg_index (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92 loops=1)
+ Filter: indisunique
+</pre></div><div class="sect2" id="id-1.11.7.13.7"><div class="titlepage"><div><div><h3 class="title">F.4.3. Author</h3></div></div></div><p>
+ Takahiro Itagaki <code class="email">&lt;<a class="email" href="mailto:itagaki.takahiro@oss.ntt.co.jp">itagaki.takahiro@oss.ntt.co.jp</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-delay.html" title="F.3. auth_delay">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.3. auth_delay </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.5. basebackup_to_shell</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup-dump.html b/doc/src/sgml/html/backup-dump.html
new file mode 100644
index 0000000..23d8f8f
--- /dev/null
+++ b/doc/src/sgml/html/backup-dump.html
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>26.1. SQL Dump</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup.html" title="Chapter 26. Backup and Restore" /><link rel="next" href="backup-file.html" title="26.2. File System Level Backup" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">26.1. <acronym class="acronym">SQL</acronym> Dump</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup.html" title="Chapter 26. Backup and Restore">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="backup.html" title="Chapter 26. Backup and Restore">Up</a></td><th width="60%" align="center">Chapter 26. Backup and Restore</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup-file.html" title="26.2. File System Level Backup">Next</a></td></tr></table><hr /></div><div class="sect1" id="BACKUP-DUMP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">26.1. <acronym class="acronym">SQL</acronym> Dump</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="backup-dump.html#BACKUP-DUMP-RESTORE">26.1.1. Restoring the Dump</a></span></dt><dt><span class="sect2"><a href="backup-dump.html#BACKUP-DUMP-ALL">26.1.2. Using <span class="application">pg_dumpall</span></a></span></dt><dt><span class="sect2"><a href="backup-dump.html#BACKUP-DUMP-LARGE">26.1.3. Handling Large Databases</a></span></dt></dl></div><p>
+ The idea behind this dump method is to generate a file with SQL
+ commands that, when fed back to the server, will recreate the
+ database in the same state as it was at the time of the dump.
+ <span class="productname">PostgreSQL</span> provides the utility program
+ <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> for this purpose. The basic usage of this
+ command is:
+</p><pre class="synopsis">
+pg_dump <em class="replaceable"><code>dbname</code></em> &gt; <em class="replaceable"><code>dumpfile</code></em>
+</pre><p>
+ As you see, <span class="application">pg_dump</span> writes its result to the
+ standard output. We will see below how this can be useful.
+ While the above command creates a text file, <span class="application">pg_dump</span>
+ can create files in other formats that allow for parallelism and more
+ fine-grained control of object restoration.
+ </p><p>
+ <span class="application">pg_dump</span> is a regular <span class="productname">PostgreSQL</span>
+ client application (albeit a particularly clever one). This means
+ that you can perform this backup procedure from any remote host that has
+ access to the database. But remember that <span class="application">pg_dump</span>
+ does not operate with special permissions. In particular, it must
+ have read access to all tables that you want to back up, so in order
+ to back up the entire database you almost always have to run it as a
+ database superuser. (If you do not have sufficient privileges to back up
+ the entire database, you can still back up portions of the database to which
+ you do have access using options such as
+ <code class="option">-n <em class="replaceable"><code>schema</code></em></code>
+ or <code class="option">-t <em class="replaceable"><code>table</code></em></code>.)
+ </p><p>
+ To specify which database server <span class="application">pg_dump</span> should
+ contact, use the command line options <code class="option">-h
+ <em class="replaceable"><code>host</code></em></code> and <code class="option">-p <em class="replaceable"><code>port</code></em></code>. The
+ default host is the local host or whatever your
+ <code class="envar">PGHOST</code> environment variable specifies. Similarly,
+ the default port is indicated by the <code class="envar">PGPORT</code>
+ environment variable or, failing that, by the compiled-in default.
+ (Conveniently, the server will normally have the same compiled-in
+ default.)
+ </p><p>
+ Like any other <span class="productname">PostgreSQL</span> client application,
+ <span class="application">pg_dump</span> will by default connect with the database
+ user name that is equal to the current operating system user name. To override
+ this, either specify the <code class="option">-U</code> option or set the
+ environment variable <code class="envar">PGUSER</code>. Remember that
+ <span class="application">pg_dump</span> connections are subject to the normal
+ client authentication mechanisms (which are described in <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a>).
+ </p><p>
+ An important advantage of <span class="application">pg_dump</span> over the other backup
+ methods described later is that <span class="application">pg_dump</span>'s output can
+ generally be re-loaded into newer versions of <span class="productname">PostgreSQL</span>,
+ whereas file-level backups and continuous archiving are both extremely
+ server-version-specific. <span class="application">pg_dump</span> is also the only method
+ that will work when transferring a database to a different machine
+ architecture, such as going from a 32-bit to a 64-bit server.
+ </p><p>
+ Dumps created by <span class="application">pg_dump</span> are internally consistent,
+ meaning, the dump represents a snapshot of the database at the time
+ <span class="application">pg_dump</span> began running. <span class="application">pg_dump</span> does not
+ block other operations on the database while it is working.
+ (Exceptions are those operations that need to operate with an
+ exclusive lock, such as most forms of <code class="command">ALTER TABLE</code>.)
+ </p><div class="sect2" id="BACKUP-DUMP-RESTORE"><div class="titlepage"><div><div><h3 class="title">26.1.1. Restoring the Dump</h3></div></div></div><p>
+ Text files created by <span class="application">pg_dump</span> are intended to
+ be read in by the <span class="application">psql</span> program. The
+ general command form to restore a dump is
+</p><pre class="synopsis">
+psql <em class="replaceable"><code>dbname</code></em> &lt; <em class="replaceable"><code>dumpfile</code></em>
+</pre><p>
+ where <em class="replaceable"><code>dumpfile</code></em> is the
+ file output by the <span class="application">pg_dump</span> command. The database <em class="replaceable"><code>dbname</code></em> will not be created by this
+ command, so you must create it yourself from <code class="literal">template0</code>
+ before executing <span class="application">psql</span> (e.g., with
+ <code class="literal">createdb -T template0 <em class="replaceable"><code>dbname</code></em></code>). <span class="application">psql</span>
+ supports options similar to <span class="application">pg_dump</span> for specifying
+ the database server to connect to and the user name to use. See
+ the <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> reference page for more information.
+ Non-text file dumps are restored using the <a class="xref" href="app-pgrestore.html" title="pg_restore"><span class="refentrytitle"><span class="application">pg_restore</span></span></a> utility.
+ </p><p>
+ Before restoring an SQL dump, all the users who own objects or were
+ granted permissions on objects in the dumped database must already
+ exist. If they do not, the restore will fail to recreate the
+ objects with the original ownership and/or permissions.
+ (Sometimes this is what you want, but usually it is not.)
+ </p><p>
+ By default, the <span class="application">psql</span> script will continue to
+ execute after an SQL error is encountered. You might wish to run
+ <span class="application">psql</span> with
+ the <code class="literal">ON_ERROR_STOP</code> variable set to alter that
+ behavior and have <span class="application">psql</span> exit with an
+ exit status of 3 if an SQL error occurs:
+</p><pre class="programlisting">
+psql --set ON_ERROR_STOP=on <em class="replaceable"><code>dbname</code></em> &lt; <em class="replaceable"><code>dumpfile</code></em>
+</pre><p>
+ Either way, you will only have a partially restored database.
+ Alternatively, you can specify that the whole dump should be
+ restored as a single transaction, so the restore is either fully
+ completed or fully rolled back. This mode can be specified by
+ passing the <code class="option">-1</code> or <code class="option">--single-transaction</code>
+ command-line options to <span class="application">psql</span>. When using this
+ mode, be aware that even a minor error can rollback a
+ restore that has already run for many hours. However, that might
+ still be preferable to manually cleaning up a complex database
+ after a partially restored dump.
+ </p><p>
+ The ability of <span class="application">pg_dump</span> and <span class="application">psql</span> to
+ write to or read from pipes makes it possible to dump a database
+ directly from one server to another, for example:
+</p><pre class="programlisting">
+pg_dump -h <em class="replaceable"><code>host1</code></em> <em class="replaceable"><code>dbname</code></em> | psql -h <em class="replaceable"><code>host2</code></em> <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+ </p><div class="important"><h3 class="title">Important</h3><p>
+ The dumps produced by <span class="application">pg_dump</span> are relative to
+ <code class="literal">template0</code>. This means that any languages, procedures,
+ etc. added via <code class="literal">template1</code> will also be dumped by
+ <span class="application">pg_dump</span>. As a result, when restoring, if you are
+ using a customized <code class="literal">template1</code>, you must create the
+ empty database from <code class="literal">template0</code>, as in the example
+ above.
+ </p></div><p>
+ After restoring a backup, it is wise to run <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> on each
+ database so the query optimizer has useful statistics;
+ see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a>
+ and <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ For more advice on how to load large amounts of data
+ into <span class="productname">PostgreSQL</span> efficiently, refer to <a class="xref" href="populate.html" title="14.4. Populating a Database">Section 14.4</a>.
+ </p></div><div class="sect2" id="BACKUP-DUMP-ALL"><div class="titlepage"><div><div><h3 class="title">26.1.2. Using <span class="application">pg_dumpall</span></h3></div></div></div><p>
+ <span class="application">pg_dump</span> dumps only a single database at a time,
+ and it does not dump information about roles or tablespaces
+ (because those are cluster-wide rather than per-database).
+ To support convenient dumping of the entire contents of a database
+ cluster, the <a class="xref" href="app-pg-dumpall.html" title="pg_dumpall"><span class="refentrytitle"><span class="application">pg_dumpall</span></span></a> program is provided.
+ <span class="application">pg_dumpall</span> backs up each database in a given
+ cluster, and also preserves cluster-wide data such as role and
+ tablespace definitions. The basic usage of this command is:
+</p><pre class="synopsis">
+pg_dumpall &gt; <em class="replaceable"><code>dumpfile</code></em>
+</pre><p>
+ The resulting dump can be restored with <span class="application">psql</span>:
+</p><pre class="synopsis">
+psql -f <em class="replaceable"><code>dumpfile</code></em> postgres
+</pre><p>
+ (Actually, you can specify any existing database name to start from,
+ but if you are loading into an empty cluster then <code class="literal">postgres</code>
+ should usually be used.) It is always necessary to have
+ database superuser access when restoring a <span class="application">pg_dumpall</span>
+ dump, as that is required to restore the role and tablespace information.
+ If you use tablespaces, make sure that the tablespace paths in the
+ dump are appropriate for the new installation.
+ </p><p>
+ <span class="application">pg_dumpall</span> works by emitting commands to re-create
+ roles, tablespaces, and empty databases, then invoking
+ <span class="application">pg_dump</span> for each database. This means that while
+ each database will be internally consistent, the snapshots of
+ different databases are not synchronized.
+ </p><p>
+ Cluster-wide data can be dumped alone using the
+ <span class="application">pg_dumpall</span> <code class="option">--globals-only</code> option.
+ This is necessary to fully backup the cluster if running the
+ <span class="application">pg_dump</span> command on individual databases.
+ </p></div><div class="sect2" id="BACKUP-DUMP-LARGE"><div class="titlepage"><div><div><h3 class="title">26.1.3. Handling Large Databases</h3></div></div></div><p>
+ Some operating systems have maximum file size limits that cause
+ problems when creating large <span class="application">pg_dump</span> output files.
+ Fortunately, <span class="application">pg_dump</span> can write to the standard
+ output, so you can use standard Unix tools to work around this
+ potential problem. There are several possible methods:
+ </p><p><strong>Use compressed dumps. </strong>
+ You can use your favorite compression program, for example
+ <span class="application">gzip</span>:
+
+</p><pre class="programlisting">
+pg_dump <em class="replaceable"><code>dbname</code></em> | gzip &gt; <em class="replaceable"><code>filename</code></em>.gz
+</pre><p>
+
+ Reload with:
+
+</p><pre class="programlisting">
+gunzip -c <em class="replaceable"><code>filename</code></em>.gz | psql <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+
+ or:
+
+</p><pre class="programlisting">
+cat <em class="replaceable"><code>filename</code></em>.gz | gunzip | psql <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+ </p><p><strong>Use <code class="command">split</code>. </strong>
+ The <code class="command">split</code> command
+ allows you to split the output into smaller files that are
+ acceptable in size to the underlying file system. For example, to
+ make 2 gigabyte chunks:
+
+</p><pre class="programlisting">
+pg_dump <em class="replaceable"><code>dbname</code></em> | split -b 2G - <em class="replaceable"><code>filename</code></em>
+</pre><p>
+
+ Reload with:
+
+</p><pre class="programlisting">
+cat <em class="replaceable"><code>filename</code></em>* | psql <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+
+ If using GNU <span class="application">split</span>, it is possible to
+ use it and <span class="application">gzip</span> together:
+
+</p><pre class="programlisting">
+pg_dump <em class="replaceable"><code>dbname</code></em> | split -b 2G --filter='gzip &gt; $FILE.gz'
+</pre><p>
+
+ It can be restored using <code class="command">zcat</code>.
+ </p><p><strong>Use <span class="application">pg_dump</span>'s custom dump format. </strong>
+ If <span class="productname">PostgreSQL</span> was built on a system with the
+ <span class="application">zlib</span> compression library installed, the custom dump
+ format will compress data as it writes it to the output file. This will
+ produce dump file sizes similar to using <code class="command">gzip</code>, but it
+ has the added advantage that tables can be restored selectively. The
+ following command dumps a database using the custom dump format:
+
+</p><pre class="programlisting">
+pg_dump -Fc <em class="replaceable"><code>dbname</code></em> &gt; <em class="replaceable"><code>filename</code></em>
+</pre><p>
+
+ A custom-format dump is not a script for <span class="application">psql</span>, but
+ instead must be restored with <span class="application">pg_restore</span>, for example:
+
+</p><pre class="programlisting">
+pg_restore -d <em class="replaceable"><code>dbname</code></em> <em class="replaceable"><code>filename</code></em>
+</pre><p>
+
+ See the <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> and <a class="xref" href="app-pgrestore.html" title="pg_restore"><span class="refentrytitle"><span class="application">pg_restore</span></span></a> reference pages for details.
+ </p><p>
+ For very large databases, you might need to combine <code class="command">split</code>
+ with one of the other two approaches.
+ </p><p><strong>Use <span class="application">pg_dump</span>'s parallel dump feature. </strong>
+ To speed up the dump of a large database, you can use
+ <span class="application">pg_dump</span>'s parallel mode. This will dump
+ multiple tables at the same time. You can control the degree of
+ parallelism with the <code class="command">-j</code> parameter. Parallel dumps
+ are only supported for the "directory" archive format.
+
+</p><pre class="programlisting">
+pg_dump -j <em class="replaceable"><code>num</code></em> -F d -f <em class="replaceable"><code>out.dir</code></em> <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+
+ You can use <code class="command">pg_restore -j</code> to restore a dump in parallel.
+ This will work for any archive of either the "custom" or the "directory"
+ archive mode, whether or not it has been created with <code class="command">pg_dump -j</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup.html" title="Chapter 26. Backup and Restore">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="backup.html" title="Chapter 26. Backup and Restore">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup-file.html" title="26.2. File System Level Backup">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 26. Backup and Restore </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 26.2. File System Level Backup</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup-file.html b/doc/src/sgml/html/backup-file.html
new file mode 100644
index 0000000..862f4ae
--- /dev/null
+++ b/doc/src/sgml/html/backup-file.html
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>26.2. File System Level Backup</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup-dump.html" title="26.1. SQL Dump" /><link rel="next" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">26.2. File System Level Backup</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup-dump.html" title="26.1. SQL Dump">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="backup.html" title="Chapter 26. Backup and Restore">Up</a></td><th width="60%" align="center">Chapter 26. Backup and Restore</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Next</a></td></tr></table><hr /></div><div class="sect1" id="BACKUP-FILE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">26.2. File System Level Backup</h2></div></div></div><p>
+ An alternative backup strategy is to directly copy the files that
+ <span class="productname">PostgreSQL</span> uses to store the data in the database;
+ <a class="xref" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Section 19.2</a> explains where these files
+ are located. You can use whatever method you prefer
+ for doing file system backups; for example:
+
+</p><pre class="programlisting">
+tar -cf backup.tar /usr/local/pgsql/data
+</pre><p>
+ </p><p>
+ There are two restrictions, however, which make this method
+ impractical, or at least inferior to the <span class="application">pg_dump</span>
+ method:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ The database server <span class="emphasis"><em>must</em></span> be shut down in order to
+ get a usable backup. Half-way measures such as disallowing all
+ connections will <span class="emphasis"><em>not</em></span> work
+ (in part because <code class="command">tar</code> and similar tools do not take
+ an atomic snapshot of the state of the file system,
+ but also because of internal buffering within the server).
+ Information about stopping the server can be found in
+ <a class="xref" href="server-shutdown.html" title="19.5. Shutting Down the Server">Section 19.5</a>. Needless to say, you
+ also need to shut down the server before restoring the data.
+ </p></li><li class="listitem"><p>
+ If you have dug into the details of the file system layout of the
+ database, you might be tempted to try to back up or restore only certain
+ individual tables or databases from their respective files or
+ directories. This will <span class="emphasis"><em>not</em></span> work because the
+ information contained in these files is not usable without
+ the commit log files,
+ <code class="filename">pg_xact/*</code>, which contain the commit status of
+ all transactions. A table file is only usable with this
+ information. Of course it is also impossible to restore only a
+ table and the associated <code class="filename">pg_xact</code> data
+ because that would render all other tables in the database
+ cluster useless. So file system backups only work for complete
+ backup and restoration of an entire database cluster.
+ </p></li></ol></div><p>
+ </p><p>
+ An alternative file-system backup approach is to make a
+ <span class="quote">“<span class="quote">consistent snapshot</span>”</span> of the data directory, if the
+ file system supports that functionality (and you are willing to
+ trust that it is implemented correctly). The typical procedure is
+ to make a <span class="quote">“<span class="quote">frozen snapshot</span>”</span> of the volume containing the
+ database, then copy the whole data directory (not just parts, see
+ above) from the snapshot to a backup device, then release the frozen
+ snapshot. This will work even while the database server is running.
+ However, a backup created in this way saves
+ the database files in a state as if the database server was not
+ properly shut down; therefore, when you start the database server
+ on the backed-up data, it will think the previous server instance
+ crashed and will replay the WAL log. This is not a problem; just
+ be aware of it (and be sure to include the WAL files in your backup).
+ You can perform a <code class="command">CHECKPOINT</code> before taking the
+ snapshot to reduce recovery time.
+ </p><p>
+ If your database is spread across multiple file systems, there might not
+ be any way to obtain exactly-simultaneous frozen snapshots of all
+ the volumes. For example, if your data files and WAL log are on different
+ disks, or if tablespaces are on different file systems, it might
+ not be possible to use snapshot backup because the snapshots
+ <span class="emphasis"><em>must</em></span> be simultaneous.
+ Read your file system documentation very carefully before trusting
+ the consistent-snapshot technique in such situations.
+ </p><p>
+ If simultaneous snapshots are not possible, one option is to shut down
+ the database server long enough to establish all the frozen snapshots.
+ Another option is to perform a continuous archiving base backup (<a class="xref" href="continuous-archiving.html#BACKUP-BASE-BACKUP" title="26.3.2. Making a Base Backup">Section 26.3.2</a>) because such backups are immune to file
+ system changes during the backup. This requires enabling continuous
+ archiving just during the backup process; restore is done using
+ continuous archive recovery (<a class="xref" href="continuous-archiving.html#BACKUP-PITR-RECOVERY" title="26.3.4. Recovering Using a Continuous Archive Backup">Section 26.3.4</a>).
+ </p><p>
+ Another option is to use <span class="application">rsync</span> to perform a file
+ system backup. This is done by first running <span class="application">rsync</span>
+ while the database server is running, then shutting down the database
+ server long enough to do an <code class="command">rsync --checksum</code>.
+ (<code class="option">--checksum</code> is necessary because <code class="command">rsync</code> only
+ has file modification-time granularity of one second.) The
+ second <span class="application">rsync</span> will be quicker than the first,
+ because it has relatively little data to transfer, and the end result
+ will be consistent because the server was down. This method
+ allows a file system backup to be performed with minimal downtime.
+ </p><p>
+ Note that a file system backup will typically be larger
+ than an SQL dump. (<span class="application">pg_dump</span> does not need to dump
+ the contents of indexes for example, just the commands to recreate
+ them.) However, taking a file system backup might be faster.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup-dump.html" title="26.1. SQL Dump">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="backup.html" title="Chapter 26. Backup and Restore">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">26.1. <acronym class="acronym">SQL</acronym> Dump </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 26.3. Continuous Archiving and Point-in-Time Recovery (PITR)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup-manifest-files.html b/doc/src/sgml/html/backup-manifest-files.html
new file mode 100644
index 0000000..1852b74
--- /dev/null
+++ b/doc/src/sgml/html/backup-manifest-files.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>76.2. Backup Manifest File Object</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup-manifest-toplevel.html" title="76.1. Backup Manifest Top-level Object" /><link rel="next" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">76.2. Backup Manifest File Object</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup-manifest-toplevel.html" title="76.1. Backup Manifest Top-level Object">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Up</a></td><th width="60%" align="center">Chapter 76. Backup Manifest Format</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object">Next</a></td></tr></table><hr /></div><div class="sect1" id="BACKUP-MANIFEST-FILES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">76.2. Backup Manifest File Object</h2></div></div></div><p>
+ The object which describes a single file contains either a
+ <code class="literal">Path</code> key or an <code class="literal">Encoded-Path</code> key.
+ Normally, the <code class="literal">Path</code> key will be present. The
+ associated string value is the path of the file relative to the root
+ of the backup directory. Files located in a user-defined tablespace
+ will have paths whose first two components are <code class="filename">pg_tblspc</code> and the OID
+ of the tablespace. If the path is not a string that is legal in UTF-8,
+ or if the user requests that encoded paths be used for all files, then
+ the <code class="literal">Encoded-Path</code> key will be present instead. This
+ stores the same data, but it is encoded as a string of hexadecimal
+ digits. Each pair of hexadecimal digits in the string represents a
+ single octet.
+ </p><p>
+ The following two keys are always present:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Size</code></span></dt><dd><p>
+ The expected size of this file, as an integer.
+ </p></dd><dt><span class="term"><code class="literal">Last-Modified</code></span></dt><dd><p>
+ The last modification time of the file as reported by the server at
+ the time of the backup. Unlike the other fields stored in the backup,
+ this field is not used by <a class="xref" href="app-pgverifybackup.html" title="pg_verifybackup"><span class="refentrytitle"><span class="application">pg_verifybackup</span></span></a>.
+ It is included only for informational purposes.
+ </p></dd></dl></div><p>
+ If the backup was taken with file checksums enabled, the following
+ keys will be present:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Checksum-Algorithm</code></span></dt><dd><p>
+ The checksum algorithm used to compute a checksum for this file.
+ Currently, this will be the same for every file in the backup
+ manifest, but this may change in future releases. At present, the
+ supported checksum algorithms are <code class="literal">CRC32C</code>,
+ <code class="literal">SHA224</code>,
+ <code class="literal">SHA256</code>,
+ <code class="literal">SHA384</code>, and
+ <code class="literal">SHA512</code>.
+ </p></dd><dt><span class="term"><code class="literal">Checksum</code></span></dt><dd><p>
+ The checksum computed for this file, stored as a series of
+ hexadecimal characters, two for each byte of the checksum.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup-manifest-toplevel.html" title="76.1. Backup Manifest Top-level Object">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object">Next</a></td></tr><tr><td width="40%" align="left" valign="top">76.1. Backup Manifest Top-level Object </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 76.3. Backup Manifest WAL Range Object</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup-manifest-format.html b/doc/src/sgml/html/backup-manifest-format.html
new file mode 100644
index 0000000..18b1430
--- /dev/null
+++ b/doc/src/sgml/html/backup-manifest-format.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 76. Backup Manifest Format</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="planner-stats-security.html" title="75.3. Planner Statistics and Security" /><link rel="next" href="backup-manifest-toplevel.html" title="76.1. Backup Manifest Top-level Object" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 76. Backup Manifest Format</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="planner-stats-security.html" title="75.3. Planner Statistics and Security">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup-manifest-toplevel.html" title="76.1. Backup Manifest Top-level Object">Next</a></td></tr></table><hr /></div><div class="chapter" id="BACKUP-MANIFEST-FORMAT"><div class="titlepage"><div><div><h2 class="title">Chapter 76. Backup Manifest Format</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="backup-manifest-toplevel.html">76.1. Backup Manifest Top-level Object</a></span></dt><dt><span class="sect1"><a href="backup-manifest-files.html">76.2. Backup Manifest File Object</a></span></dt><dt><span class="sect1"><a href="backup-manifest-wal-ranges.html">76.3. Backup Manifest WAL Range Object</a></span></dt></dl></div><a id="id-1.10.27.2" class="indexterm"></a><p>
+ The backup manifest generated by <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a> is
+ primarily intended to permit the backup to be verified using
+ <a class="xref" href="app-pgverifybackup.html" title="pg_verifybackup"><span class="refentrytitle"><span class="application">pg_verifybackup</span></span></a>. However, it is
+ also possible for other tools to read the backup manifest file and use
+ the information contained therein for their own purposes. To that end,
+ this chapter describes the format of the backup manifest file.
+ </p><p>
+ A backup manifest is a JSON document encoded as UTF-8. (Although in
+ general JSON documents are required to be Unicode, PostgreSQL permits
+ the <code class="type">json</code> and <code class="type">jsonb</code> data types to be used with any
+ supported server encoding. There is no similar exception for backup
+ manifests.) The JSON document is always an object; the keys that are present
+ in this object are described in the next section.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="planner-stats-security.html" title="75.3. Planner Statistics and Security">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup-manifest-toplevel.html" title="76.1. Backup Manifest Top-level Object">Next</a></td></tr><tr><td width="40%" align="left" valign="top">75.3. Planner Statistics and Security </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 76.1. Backup Manifest Top-level Object</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup-manifest-toplevel.html b/doc/src/sgml/html/backup-manifest-toplevel.html
new file mode 100644
index 0000000..f9dd399
--- /dev/null
+++ b/doc/src/sgml/html/backup-manifest-toplevel.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>76.1. Backup Manifest Top-level Object</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format" /><link rel="next" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">76.1. Backup Manifest Top-level Object</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Up</a></td><th width="60%" align="center">Chapter 76. Backup Manifest Format</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object">Next</a></td></tr></table><hr /></div><div class="sect1" id="BACKUP-MANIFEST-TOPLEVEL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">76.1. Backup Manifest Top-level Object</h2></div></div></div><p>
+ The backup manifest JSON document contains the following keys.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">PostgreSQL-Backup-Manifest-Version</code></span></dt><dd><p>
+ The associated value is always the integer 1.
+ </p></dd><dt><span class="term"><code class="literal">Files</code></span></dt><dd><p>
+ The associated value is always a list of objects, each describing one
+ file that is present in the backup. No entries are present in this
+ list for the WAL files that are needed in order to use the backup,
+ or for the backup manifest itself. The structure of each object in the
+ list is described in <a class="xref" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object">Section 76.2</a>.
+ </p></dd><dt><span class="term"><code class="literal">WAL-Ranges</code></span></dt><dd><p>
+ The associated value is always a list of objects, each describing a
+ range of WAL records that must be readable from a particular timeline
+ in order to make use of the backup. The structure of these objects is
+ further described in <a class="xref" href="backup-manifest-wal-ranges.html" title="76.3. Backup Manifest WAL Range Object">Section 76.3</a>.
+ </p></dd><dt><span class="term"><code class="literal">Manifest-Checksum</code></span></dt><dd><p>
+ This key is always present on the last line of the backup manifest file.
+ The associated value is a SHA256 checksum of all the preceding lines.
+ We use a fixed checksum method here to make it possible for clients
+ to do incremental parsing of the manifest. While a SHA256 checksum
+ is significantly more expensive than a CRC32C checksum, the manifest
+ should normally be small enough that the extra computation won't matter
+ very much.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 76. Backup Manifest Format </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 76.2. Backup Manifest File Object</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup-manifest-wal-ranges.html b/doc/src/sgml/html/backup-manifest-wal-ranges.html
new file mode 100644
index 0000000..7fedb62
--- /dev/null
+++ b/doc/src/sgml/html/backup-manifest-wal-ranges.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>76.3. Backup Manifest WAL Range Object</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object" /><link rel="next" href="appendixes.html" title="Part VIII. Appendixes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">76.3. Backup Manifest WAL Range Object</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Up</a></td><th width="60%" align="center">Chapter 76. Backup Manifest Format</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="appendixes.html" title="Part VIII. Appendixes">Next</a></td></tr></table><hr /></div><div class="sect1" id="BACKUP-MANIFEST-WAL-RANGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">76.3. Backup Manifest WAL Range Object</h2></div></div></div><p>
+ The object which describes a WAL range always has three keys:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Timeline</code></span></dt><dd><p>
+ The timeline for this range of WAL records, as an integer.
+ </p></dd><dt><span class="term"><code class="literal">Start-LSN</code></span></dt><dd><p>
+ The LSN at which replay must begin on the indicated timeline in order to
+ make use of this backup. The LSN is stored in the format normally used
+ by <span class="productname">PostgreSQL</span>; that is, it is a string
+ consisting of two strings of hexadecimal characters, each with a length
+ of between 1 and 8, separated by a slash.
+ </p></dd><dt><span class="term"><code class="literal">End-LSN</code></span></dt><dd><p>
+ The earliest LSN at which replay on the indicated timeline may end when
+ making use of this backup. This is stored in the same format as
+ <code class="literal">Start-LSN</code>.
+ </p></dd></dl></div><p>
+ Ordinarily, there will be only a single WAL range. However, if a backup is
+ taken from a standby which switches timelines during the backup due to an
+ upstream promotion, it is possible for multiple ranges to be present, each
+ with a different timeline. There will never be multiple WAL ranges present
+ for the same timeline.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup-manifest-files.html" title="76.2. Backup Manifest File Object">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="appendixes.html" title="Part VIII. Appendixes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">76.2. Backup Manifest File Object </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part VIII. Appendixes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/backup.html b/doc/src/sgml/html/backup.html
new file mode 100644
index 0000000..5ccc37f
--- /dev/null
+++ b/doc/src/sgml/html/backup.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 26. Backup and Restore</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logfile-maintenance.html" title="25.3. Log File Maintenance" /><link rel="next" href="backup-dump.html" title="26.1. SQL Dump" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 26. Backup and Restore</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup-dump.html" title="26.1. SQL Dump">Next</a></td></tr></table><hr /></div><div class="chapter" id="BACKUP"><div class="titlepage"><div><div><h2 class="title">Chapter 26. Backup and Restore</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="backup-dump.html">26.1. <acronym class="acronym">SQL</acronym> Dump</a></span></dt><dd><dl><dt><span class="sect2"><a href="backup-dump.html#BACKUP-DUMP-RESTORE">26.1.1. Restoring the Dump</a></span></dt><dt><span class="sect2"><a href="backup-dump.html#BACKUP-DUMP-ALL">26.1.2. Using <span class="application">pg_dumpall</span></a></span></dt><dt><span class="sect2"><a href="backup-dump.html#BACKUP-DUMP-LARGE">26.1.3. Handling Large Databases</a></span></dt></dl></dd><dt><span class="sect1"><a href="backup-file.html">26.2. File System Level Backup</a></span></dt><dt><span class="sect1"><a href="continuous-archiving.html">26.3. Continuous Archiving and Point-in-Time Recovery (PITR)</a></span></dt><dd><dl><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-ARCHIVING-WAL">26.3.1. Setting Up WAL Archiving</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-BASE-BACKUP">26.3.2. Making a Base Backup</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP">26.3.3. Making a Base Backup Using the Low Level API</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-PITR-RECOVERY">26.3.4. Recovering Using a Continuous Archive Backup</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-TIMELINES">26.3.5. Timelines</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-TIPS">26.3.6. Tips and Examples</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#CONTINUOUS-ARCHIVING-CAVEATS">26.3.7. Caveats</a></span></dt></dl></dd></dl></div><a id="id-1.6.13.2" class="indexterm"></a><p>
+ As with everything that contains valuable data, <span class="productname">PostgreSQL</span>
+ databases should be backed up regularly. While the procedure is
+ essentially simple, it is important to have a clear understanding of
+ the underlying techniques and assumptions.
+ </p><p>
+ There are three fundamentally different approaches to backing up
+ <span class="productname">PostgreSQL</span> data:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><acronym class="acronym">SQL</acronym> dump</p></li><li class="listitem"><p>File system level backup</p></li><li class="listitem"><p>Continuous archiving</p></li></ul></div><p>
+ Each has its own strengths and weaknesses; each is discussed in turn
+ in the following sections.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup-dump.html" title="26.1. SQL Dump">Next</a></td></tr><tr><td width="40%" align="left" valign="top">25.3. Log File Maintenance </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 26.1. <acronym class="acronym">SQL</acronym> Dump</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/basebackup-to-shell.html b/doc/src/sgml/html/basebackup-to-shell.html
new file mode 100644
index 0000000..f33158d
--- /dev/null
+++ b/doc/src/sgml/html/basebackup-to-shell.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.5. basebackup_to_shell</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auto-explain.html" title="F.4. auto_explain" /><link rel="next" href="basic-archive.html" title="F.6. basic_archive" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.5. basebackup_to_shell</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auto-explain.html" title="F.4. auto_explain">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="basic-archive.html" title="F.6. basic_archive">Next</a></td></tr></table><hr /></div><div class="sect1" id="BASEBACKUP-TO-SHELL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.5. basebackup_to_shell</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="basebackup-to-shell.html#id-1.11.7.14.5">F.5.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="basebackup-to-shell.html#id-1.11.7.14.6">F.5.2. Author</a></span></dt></dl></div><a id="id-1.11.7.14.2" class="indexterm"></a><p>
+ <code class="filename">basebackup_to_shell</code> adds a custom basebackup target
+ called <code class="literal">shell</code>. This makes it possible to run
+ <code class="command">pg_basebackup --target=shell</code> or, depending on how this
+ module is configured,
+ <code class="command">pg_basebackup --target=shell:<em class="replaceable"><code>DETAIL_STRING</code></em></code>,
+ and cause a server command chosen by the server administrator to be executed
+ for each tar archive generated by the backup process. The command will receive
+ the contents of the archive via standard input.
+ </p><p>
+ This module is primarily intended as an example of how to create a new
+ backup targets via an extension module, but in some scenarios it may be
+ useful for its own sake.
+ In order to function, this module must be loaded via
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> or
+ <a class="xref" href="runtime-config-client.html#GUC-LOCAL-PRELOAD-LIBRARIES">local_preload_libraries</a>.
+ </p><div class="sect2" id="id-1.11.7.14.5"><div class="titlepage"><div><div><h3 class="title">F.5.1. Configuration Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">basebackup_to_shell.command</code> (<code class="type">string</code>)
+ <a id="id-1.11.7.14.5.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The command which the server should execute for each archive generated
+ by the backup process. If <code class="literal">%f</code> occurs in the command
+ string, it will be replaced by the name of the archive (e.g.
+ <code class="literal">base.tar</code>). If <code class="literal">%d</code> occurs in the
+ command string, it will be replaced by the target detail provided by
+ the user. A target detail is required if <code class="literal">%d</code> is
+ used in the command string, and prohibited otherwise. For security
+ reasons, it may contain only alphanumeric characters. If
+ <code class="literal">%%</code> occurs in the command string, it will be replaced
+ by a single <code class="literal">%</code>. If <code class="literal">%</code> occurs in
+ the command string followed by any other character or at the end of the
+ string, an error occurs.
+ </p></dd><dt><span class="term">
+ <code class="varname">basebackup_to_shell.required_role</code> (<code class="type">string</code>)
+ <a id="id-1.11.7.14.5.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The role required in order to make use of the <code class="literal">shell</code>
+ backup target. If this is not set, any replication user may make use of
+ the <code class="literal">shell</code> backup target.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.14.6"><div class="titlepage"><div><div><h3 class="title">F.5.2. Author</h3></div></div></div><p>
+ Robert Haas <code class="email">&lt;<a class="email" href="mailto:rhaas@postgresql.org">rhaas@postgresql.org</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auto-explain.html" title="F.4. auto_explain">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="basic-archive.html" title="F.6. basic_archive">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.4. auto_explain </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.6. basic_archive</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/basic-archive.html b/doc/src/sgml/html/basic-archive.html
new file mode 100644
index 0000000..ce335ce
--- /dev/null
+++ b/doc/src/sgml/html/basic-archive.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.6. basic_archive</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell" /><link rel="next" href="bloom.html" title="F.7. bloom" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.6. basic_archive</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bloom.html" title="F.7. bloom">Next</a></td></tr></table><hr /></div><div class="sect1" id="BASIC-ARCHIVE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.6. basic_archive</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="basic-archive.html#id-1.11.7.15.5">F.6.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="basic-archive.html#id-1.11.7.15.6">F.6.2. Notes</a></span></dt><dt><span class="sect2"><a href="basic-archive.html#id-1.11.7.15.7">F.6.3. Author</a></span></dt></dl></div><a id="id-1.11.7.15.2" class="indexterm"></a><p>
+ <code class="filename">basic_archive</code> is an example of an archive module. This
+ module copies completed WAL segment files to the specified directory. This
+ may not be especially useful, but it can serve as a starting point for
+ developing your own archive module. For more information about archive
+ modules, see <a class="xref" href="archive-modules.html" title="Chapter 51. Archive Modules">Chapter 51</a>.
+ </p><p>
+ In order to function, this module must be loaded via
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a>, and <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-MODE">archive_mode</a>
+ must be enabled.
+ </p><div class="sect2" id="id-1.11.7.15.5"><div class="titlepage"><div><div><h3 class="title">F.6.1. Configuration Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">basic_archive.archive_directory</code> (<code class="type">string</code>)
+ <a id="id-1.11.7.15.5.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The directory where the server should copy WAL segment files. This
+ directory must already exist. The default is an empty string, which
+ effectively halts WAL archiving, but if <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-MODE">archive_mode</a>
+ is enabled, the server will accumulate WAL segment files in the
+ expectation that a value will soon be provided.
+ </p></dd></dl></div><p>
+ These parameters must be set in <code class="filename">postgresql.conf</code>.
+ Typical usage might be:
+ </p><pre class="programlisting">
+# postgresql.conf
+archive_mode = 'on'
+archive_library = 'basic_archive'
+basic_archive.archive_directory = '/path/to/archive/directory'
+</pre></div><div class="sect2" id="id-1.11.7.15.6"><div class="titlepage"><div><div><h3 class="title">F.6.2. Notes</h3></div></div></div><p>
+ Server crashes may leave temporary files with the prefix
+ <code class="filename">archtemp</code> in the archive directory. It is recommended to
+ delete such files before restarting the server after a crash. It is safe to
+ remove such files while the server is running as long as they are unrelated
+ to any archiving still in progress, but users should use extra caution when
+ doing so.
+ </p></div><div class="sect2" id="id-1.11.7.15.7"><div class="titlepage"><div><div><h3 class="title">F.6.3. Author</h3></div></div></div><p>
+ Nathan Bossart
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bloom.html" title="F.7. bloom">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.5. basebackup_to_shell </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.7. bloom</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bgworker.html b/doc/src/sgml/html/bgworker.html
new file mode 100644
index 0000000..746a13e
--- /dev/null
+++ b/doc/src/sgml/html/bgworker.html
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 48. Background Worker Processes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-start-transaction.html" title="SPI_start_transaction" /><link rel="next" href="logicaldecoding.html" title="Chapter 49. Logical Decoding" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 48. Background Worker Processes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Next</a></td></tr></table><hr /></div><div class="chapter" id="BGWORKER"><div class="titlepage"><div><div><h2 class="title">Chapter 48. Background Worker Processes</h2></div></div></div><a id="id-1.8.13.2" class="indexterm"></a><p>
+ PostgreSQL can be extended to run user-supplied code in separate processes.
+ Such processes are started, stopped and monitored by <code class="command">postgres</code>,
+ which permits them to have a lifetime closely linked to the server's status.
+ These processes are attached to <span class="productname">PostgreSQL</span>'s
+ shared memory area and have the option to connect to databases internally; they can also run
+ multiple transactions serially, just like a regular client-connected server
+ process. Also, by linking to <span class="application">libpq</span> they can connect to the
+ server and behave like a regular client application.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ There are considerable robustness and security risks in using background
+ worker processes because, being written in the <code class="literal">C</code> language,
+ they have unrestricted access to data. Administrators wishing to enable
+ modules that include background worker processes should exercise extreme
+ caution. Only carefully audited modules should be permitted to run
+ background worker processes.
+ </p></div><p>
+ Background workers can be initialized at the time that
+ <span class="productname">PostgreSQL</span> is started by including the module name in
+ <code class="varname">shared_preload_libraries</code>. A module wishing to run a background
+ worker can register it by calling
+ <code class="function">RegisterBackgroundWorker(<code class="type">BackgroundWorker</code>
+ *<em class="parameter"><code>worker</code></em>)</code>
+ from its <code class="function">_PG_init()</code> function.
+ Background workers can also be started
+ after the system is up and running by calling
+ <code class="function">RegisterDynamicBackgroundWorker(<code class="type">BackgroundWorker</code>
+ *<em class="parameter"><code>worker</code></em>, <code class="type">BackgroundWorkerHandle</code>
+ **<em class="parameter"><code>handle</code></em>)</code>. Unlike
+ <code class="function">RegisterBackgroundWorker</code>, which can only be called from
+ within the postmaster process,
+ <code class="function">RegisterDynamicBackgroundWorker</code> must be called
+ from a regular backend or another background worker.
+ </p><p>
+ The structure <code class="structname">BackgroundWorker</code> is defined thus:
+</p><pre class="programlisting">
+typedef void (*bgworker_main_type)(Datum main_arg);
+typedef struct BackgroundWorker
+{
+ char bgw_name[BGW_MAXLEN];
+ char bgw_type[BGW_MAXLEN];
+ int bgw_flags;
+ BgWorkerStartTime bgw_start_time;
+ int bgw_restart_time; /* in seconds, or BGW_NEVER_RESTART */
+ char bgw_library_name[BGW_MAXLEN];
+ char bgw_function_name[BGW_MAXLEN];
+ Datum bgw_main_arg;
+ char bgw_extra[BGW_EXTRALEN];
+ int bgw_notify_pid;
+} BackgroundWorker;
+</pre><p>
+ </p><p>
+ <code class="structfield">bgw_name</code> and <code class="structfield">bgw_type</code> are
+ strings to be used in log messages, process listings and similar contexts.
+ <code class="structfield">bgw_type</code> should be the same for all background
+ workers of the same type, so that it is possible to group such workers in a
+ process listing, for example. <code class="structfield">bgw_name</code> on the
+ other hand can contain additional information about the specific process.
+ (Typically, the string for <code class="structfield">bgw_name</code> will contain
+ the type somehow, but that is not strictly required.)
+ </p><p>
+ <code class="structfield">bgw_flags</code> is a bitwise-or'd bit mask indicating the
+ capabilities that the module wants. Possible values are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">BGWORKER_SHMEM_ACCESS</code></span></dt><dd><p>
+ <a id="id-1.8.13.8.2.1.2.1.1" class="indexterm"></a>
+ Requests shared memory access. This flag is required.
+ </p></dd><dt><span class="term"><code class="literal">BGWORKER_BACKEND_DATABASE_CONNECTION</code></span></dt><dd><p>
+ <a id="id-1.8.13.8.2.2.2.1.1" class="indexterm"></a>
+ Requests the ability to establish a database connection through which it
+ can later run transactions and queries. A background worker using
+ <code class="literal">BGWORKER_BACKEND_DATABASE_CONNECTION</code> to connect to a
+ database must also attach shared memory using
+ <code class="literal">BGWORKER_SHMEM_ACCESS</code>, or worker start-up will fail.
+ </p></dd></dl></div><p>
+
+ </p><p>
+ <code class="structfield">bgw_start_time</code> is the server state during which
+ <code class="command">postgres</code> should start the process; it can be one of
+ <code class="literal">BgWorkerStart_PostmasterStart</code> (start as soon as
+ <code class="command">postgres</code> itself has finished its own initialization; processes
+ requesting this are not eligible for database connections),
+ <code class="literal">BgWorkerStart_ConsistentState</code> (start as soon as a consistent state
+ has been reached in a hot standby, allowing processes to connect to
+ databases and run read-only queries), and
+ <code class="literal">BgWorkerStart_RecoveryFinished</code> (start as soon as the system has
+ entered normal read-write state). Note the last two values are equivalent
+ in a server that's not a hot standby. Note that this setting only indicates
+ when the processes are to be started; they do not stop when a different state
+ is reached.
+ </p><p>
+ <code class="structfield">bgw_restart_time</code> is the interval, in seconds, that
+ <code class="command">postgres</code> should wait before restarting the process in
+ the event that it crashes. It can be any positive value,
+ or <code class="literal">BGW_NEVER_RESTART</code>, indicating not to restart the
+ process in case of a crash.
+ </p><p>
+ <code class="structfield">bgw_library_name</code> is the name of a library in
+ which the initial entry point for the background worker should be sought.
+ The named library will be dynamically loaded by the worker process and
+ <code class="structfield">bgw_function_name</code> will be used to identify the
+ function to be called. If loading a function from the core code, this must
+ be set to "postgres".
+ </p><p>
+ <code class="structfield">bgw_function_name</code> is the name of a function in
+ a dynamically loaded library which should be used as the initial entry point
+ for a new background worker.
+ </p><p>
+ <code class="structfield">bgw_main_arg</code> is the <code class="type">Datum</code> argument
+ to the background worker main function. This main function should take a
+ single argument of type <code class="type">Datum</code> and return <code class="type">void</code>.
+ <code class="structfield">bgw_main_arg</code> will be passed as the argument.
+ In addition, the global variable <code class="literal">MyBgworkerEntry</code>
+ points to a copy of the <code class="structname">BackgroundWorker</code> structure
+ passed at registration time; the worker may find it helpful to examine
+ this structure.
+ </p><p>
+ On Windows (and anywhere else where <code class="literal">EXEC_BACKEND</code> is
+ defined) or in dynamic background workers it is not safe to pass a
+ <code class="type">Datum</code> by reference, only by value. If an argument is required, it
+ is safest to pass an int32 or other small value and use that as an index
+ into an array allocated in shared memory. If a value like a <code class="type">cstring</code>
+ or <code class="type">text</code> is passed then the pointer won't be valid from the
+ new background worker process.
+ </p><p>
+ <code class="structfield">bgw_extra</code> can contain extra data to be passed
+ to the background worker. Unlike <code class="structfield">bgw_main_arg</code>, this data
+ is not passed as an argument to the worker's main function, but it can be
+ accessed via <code class="literal">MyBgworkerEntry</code>, as discussed above.
+ </p><p>
+ <code class="structfield">bgw_notify_pid</code> is the PID of a PostgreSQL
+ backend process to which the postmaster should send <code class="literal">SIGUSR1</code>
+ when the process is started or exits. It should be 0 for workers registered
+ at postmaster startup time, or when the backend registering the worker does
+ not wish to wait for the worker to start up. Otherwise, it should be
+ initialized to <code class="literal">MyProcPid</code>.
+ </p><p>Once running, the process can connect to a database by calling
+ <code class="function">BackgroundWorkerInitializeConnection(<em class="parameter"><code>char *dbname</code></em>, <em class="parameter"><code>char *username</code></em>, <em class="parameter"><code>uint32 flags</code></em>)</code> or
+ <code class="function">BackgroundWorkerInitializeConnectionByOid(<em class="parameter"><code>Oid dboid</code></em>, <em class="parameter"><code>Oid useroid</code></em>, <em class="parameter"><code>uint32 flags</code></em>)</code>.
+ This allows the process to run transactions and queries using the
+ <code class="literal">SPI</code> interface. If <code class="varname">dbname</code> is NULL or
+ <code class="varname">dboid</code> is <code class="literal">InvalidOid</code>, the session is not connected
+ to any particular database, but shared catalogs can be accessed.
+ If <code class="varname">username</code> is NULL or <code class="varname">useroid</code> is
+ <code class="literal">InvalidOid</code>, the process will run as the superuser created
+ during <code class="command">initdb</code>. If <code class="literal">BGWORKER_BYPASS_ALLOWCONN</code>
+ is specified as <code class="varname">flags</code> it is possible to bypass the restriction
+ to connect to databases not allowing user connections.
+ A background worker can only call one of these two functions, and only
+ once. It is not possible to switch databases.
+ </p><p>
+ Signals are initially blocked when control reaches the
+ background worker's main function, and must be unblocked by it; this is to
+ allow the process to customize its signal handlers, if necessary.
+ Signals can be unblocked in the new process by calling
+ <code class="function">BackgroundWorkerUnblockSignals</code> and blocked by calling
+ <code class="function">BackgroundWorkerBlockSignals</code>.
+ </p><p>
+ If <code class="structfield">bgw_restart_time</code> for a background worker is
+ configured as <code class="literal">BGW_NEVER_RESTART</code>, or if it exits with an exit
+ code of 0 or is terminated by <code class="function">TerminateBackgroundWorker</code>,
+ it will be automatically unregistered by the postmaster on exit.
+ Otherwise, it will be restarted after the time period configured via
+ <code class="structfield">bgw_restart_time</code>, or immediately if the postmaster
+ reinitializes the cluster due to a backend failure. Backends which need
+ to suspend execution only temporarily should use an interruptible sleep
+ rather than exiting; this can be achieved by calling
+ <code class="function">WaitLatch()</code>. Make sure the
+ <code class="literal">WL_POSTMASTER_DEATH</code> flag is set when calling that function, and
+ verify the return code for a prompt exit in the emergency case that
+ <code class="command">postgres</code> itself has terminated.
+ </p><p>
+ When a background worker is registered using the
+ <code class="function">RegisterDynamicBackgroundWorker</code> function, it is
+ possible for the backend performing the registration to obtain information
+ regarding the status of the worker. Backends wishing to do this should
+ pass the address of a <code class="type">BackgroundWorkerHandle *</code> as the second
+ argument to <code class="function">RegisterDynamicBackgroundWorker</code>. If the
+ worker is successfully registered, this pointer will be initialized with an
+ opaque handle that can subsequently be passed to
+ <code class="function">GetBackgroundWorkerPid(<em class="parameter"><code>BackgroundWorkerHandle *</code></em>, <em class="parameter"><code>pid_t *</code></em>)</code> or
+ <code class="function">TerminateBackgroundWorker(<em class="parameter"><code>BackgroundWorkerHandle *</code></em>)</code>.
+ <code class="function">GetBackgroundWorkerPid</code> can be used to poll the status of the
+ worker: a return value of <code class="literal">BGWH_NOT_YET_STARTED</code> indicates that
+ the worker has not yet been started by the postmaster;
+ <code class="literal">BGWH_STOPPED</code> indicates that it has been started but is
+ no longer running; and <code class="literal">BGWH_STARTED</code> indicates that it is
+ currently running. In this last case, the PID will also be returned via the
+ second argument.
+ <code class="function">TerminateBackgroundWorker</code> causes the postmaster to send
+ <code class="literal">SIGTERM</code> to the worker if it is running, and to unregister it
+ as soon as it is not.
+ </p><p>
+ In some cases, a process which registers a background worker may wish to
+ wait for the worker to start up. This can be accomplished by initializing
+ <code class="structfield">bgw_notify_pid</code> to <code class="literal">MyProcPid</code> and
+ then passing the <code class="type">BackgroundWorkerHandle *</code> obtained at
+ registration time to
+ <code class="function">WaitForBackgroundWorkerStartup(<em class="parameter"><code>BackgroundWorkerHandle
+ *handle</code></em>, <em class="parameter"><code>pid_t *</code></em>)</code> function.
+ This function will block until the postmaster has attempted to start the
+ background worker, or until the postmaster dies. If the background worker
+ is running, the return value will be <code class="literal">BGWH_STARTED</code>, and
+ the PID will be written to the provided address. Otherwise, the return
+ value will be <code class="literal">BGWH_STOPPED</code> or
+ <code class="literal">BGWH_POSTMASTER_DIED</code>.
+ </p><p>
+ A process can also wait for a background worker to shut down, by using the
+ <code class="function">WaitForBackgroundWorkerShutdown(<em class="parameter"><code>BackgroundWorkerHandle
+ *handle</code></em>)</code> function and passing the
+ <code class="type">BackgroundWorkerHandle *</code> obtained at registration. This
+ function will block until the background worker exits, or postmaster dies.
+ When the background worker exits, the return value is
+ <code class="literal">BGWH_STOPPED</code>, if postmaster dies it will return
+ <code class="literal">BGWH_POSTMASTER_DIED</code>.
+ </p><p>
+ Background workers can send asynchronous notification messages, either by
+ using the <code class="command">NOTIFY</code> command via <acronym class="acronym">SPI</acronym>,
+ or directly via <code class="function">Async_Notify()</code>. Such notifications
+ will be sent at transaction commit.
+ Background workers should not register to receive asynchronous
+ notifications with the <code class="command">LISTEN</code> command, as there is no
+ infrastructure for a worker to consume such notifications.
+ </p><p>
+ The <code class="filename">src/test/modules/worker_spi</code> module
+ contains a working example,
+ which demonstrates some useful techniques.
+ </p><p>
+ The maximum number of registered background workers is limited by
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_start_transaction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 49. Logical Decoding</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/biblio.html b/doc/src/sgml/html/biblio.html
new file mode 100644
index 0000000..8dc0210
--- /dev/null
+++ b/doc/src/sgml/html/biblio.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Bibliography</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgreceivexlog.html" title="O.5. pg_receivexlog renamed to pg_receivewal" /><link rel="next" href="bookindex.html" title="Index" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Bibliography</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgreceivexlog.html" title="O.5. pg_receivexlog renamed to pg_receivewal">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bookindex.html" title="Index">Next</a></td></tr></table><hr /></div><div class="bibliography" id="BIBLIO"><div class="titlepage"><div><div><h1 class="title">Bibliography</h1></div></div></div><p>
+ Selected references and readings for <acronym class="acronym">SQL</acronym>
+ and <span class="productname">PostgreSQL</span>.
+ </p><p>
+ Some white papers and technical reports from the original
+ <span class="productname">POSTGRES</span> development team
+ are available at the University of California, Berkeley, Computer Science
+ Department <a class="ulink" href="https://dsf.berkeley.edu/papers/" target="_top">web site</a>.
+ </p><div class="bibliodiv" id="id-1.12.4"><h3 class="title"><acronym class="acronym">SQL</acronym> Reference Books</h3><div class="biblioentry" id="BOWMAN01"><p>[bowman01] <span class="title"><em>The Practical <acronym class="acronym">SQL</acronym> Handbook</em>. </span><span class="subtitle">Using SQL Variants. </span><span class="edition">Fourth Edition. </span><span class="authorgroup"><span class="firstname">Judith</span> <span class="surname">Bowman</span>, <span class="firstname">Sandra</span> <span class="surname">Emerson</span>, and <span class="firstname">Marcy</span> <span class="surname">Darnovsky</span>. </span><span class="isbn">ISBN 0-201-70309-2. </span><span class="publisher"><span class="publishername">Addison-Wesley Professional. </span></span><span class="pubdate">2001. </span></p></div><div class="biblioentry" id="DATE97"><p>[date97] <span class="title"><em>A Guide to the <acronym class="acronym">SQL</acronym> Standard</em>. </span><span class="subtitle">A user's guide to the standard database language <acronym class="acronym">SQL</acronym>. </span><span class="edition">Fourth Edition. </span><span class="authorgroup"><span class="firstname">C. J.</span> <span class="surname">Date</span> and <span class="firstname">Hugh</span> <span class="surname">Darwen</span>. </span><span class="isbn">ISBN 0-201-96426-0. </span><span class="publisher"><span class="publishername">Addison-Wesley. </span></span><span class="pubdate">1997. </span></p></div><div class="biblioentry" id="DATE04"><p>[date04] <span class="title"><em>An Introduction to Database Systems</em>. </span><span class="edition">Eighth Edition. </span><span class="authorgroup"><span class="firstname">C. J.</span> <span class="surname">Date</span>. </span><span class="isbn">ISBN 0-321-19784-4. </span><span class="publisher"><span class="publishername">Addison-Wesley. </span></span><span class="pubdate">2003. </span></p></div><div class="biblioentry" id="ELMA04"><p>[elma04] <span class="title"><em>Fundamentals of Database Systems</em>. </span><span class="edition">Fourth Edition. </span><span class="authorgroup"><span class="firstname">Ramez</span> <span class="surname">Elmasri</span> and <span class="firstname">Shamkant</span> <span class="surname">Navathe</span>. </span><span class="isbn">ISBN 0-321-12226-7. </span><span class="publisher"><span class="publishername">Addison-Wesley. </span></span><span class="pubdate">2003. </span></p></div><div class="biblioentry" id="MELT93"><p>[melt93] <span class="title"><em>Understanding the New <acronym class="acronym">SQL</acronym></em>. </span><span class="subtitle">A complete guide. </span><span class="authorgroup"><span class="firstname">Jim</span> <span class="surname">Melton</span> and <span class="firstname">Alan R.</span> <span class="surname">Simon</span>. </span><span class="isbn">ISBN 1-55860-245-3. </span><span class="publisher"><span class="publishername">Morgan Kaufmann. </span></span><span class="pubdate">1993. </span></p></div><div class="biblioentry" id="ULL88"><p>[ull88] <span class="title"><em>Principles of Database and Knowledge-Base Systems</em>. </span><span class="subtitle">Classical Database Systems. </span><span class="authorgroup"><span class="firstname">Jeffrey D.</span> <span class="surname">Ullman</span>. </span><span class="volumenum">Volume 1. </span><span class="publisher"><span class="publishername">Computer Science Press. </span></span><span class="pubdate">1988. </span></p></div><div class="biblioentry" id="SQLTR-19075-6"><p>[sqltr-19075-6] <span class="title"><em>SQL Technical Report</em>. </span><span class="subtitle">Part 6: SQL support for JavaScript Object
+ Notation (JSON). </span><span class="edition">First Edition. </span><span class="pubdate">2017. </span></p></div></div><div class="bibliodiv" id="id-1.12.5"><h3 class="title">PostgreSQL-specific Documentation</h3><div class="biblioentry" id="SIM98"><p>[sim98] <span class="title"><em>Enhancement of the ANSI SQL Implementation of PostgreSQL</em>. </span><span class="authorgroup"><span class="firstname">Stefan</span> <span class="surname">Simkovics</span>. </span><span class="publisher"><span class="publishername">Department of Information Systems, Vienna University of Technology. </span><span class="address">Vienna, Austria. </span></span><span class="pubdate">November 29, 1998. </span></p></div><div class="biblioentry" id="YU95"><p>[yu95] <span class="title"><em>The <span class="productname">Postgres95. </span> User Manual</em>. </span><span class="authorgroup"><span class="firstname">A.</span> <span class="surname">Yu</span> and <span class="firstname">J.</span> <span class="surname">Chen</span>. </span><span class="publisher"><span class="publishername">University of California. </span><span class="address">Berkeley, California. </span></span><span class="pubdate">Sept. 5, 1995. </span></p></div><div class="biblioentry" id="FONG"><p>[fong] <span class="title"><em><a class="ulink" href="https://dsf.berkeley.edu/papers/UCB-MS-zfong.pdf" target="_top">The
+ design and implementation of the <span class="productname">POSTGRES</span> query
+ optimizer</a></em>. </span><span class="author"><span class="firstname">Zelaine</span> <span class="surname">Fong</span>. </span><span class="publisher"><span class="publishername">University of California, Berkeley, Computer Science Department. </span></span></p></div></div><div class="bibliodiv" id="id-1.12.6"><h3 class="title">Proceedings and Articles</h3><div class="biblioentry" id="PORTS12"><p>[ports12] <span class="biblioset">“<a class="ulink" href="https://arxiv.org/pdf/1208.4179" target="_top">Serializable Snapshot Isolation in PostgreSQL</a>”. <span class="authorgroup"><span class="firstname">D.</span> <span class="surname">Ports</span> and <span class="firstname">K.</span> <span class="surname">Grittner</span>. </span></span><span class="confgroup">VLDB Conference, August 2012. </span></p></div><div class="biblioentry" id="BERENSON95"><p>[berenson95] <span class="biblioset">“<a class="ulink" href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/tr-95-51.pdf" target="_top">A Critique of ANSI SQL Isolation Levels</a>”. <span class="authorgroup"><span class="firstname">H.</span> <span class="surname">Berenson</span>, <span class="firstname">P.</span> <span class="surname">Bernstein</span>, <span class="firstname">J.</span> <span class="surname">Gray</span>, <span class="firstname">J.</span> <span class="surname">Melton</span>, <span class="firstname">E.</span> <span class="surname">O'Neil</span>, and <span class="firstname">P.</span> <span class="surname">O'Neil</span>. </span></span><span class="confgroup">ACM-SIGMOD Conference on Management of Data, June 1995. </span></p></div><div class="biblioentry" id="OLSON93"><p>[olson93] <span class="title"><em>Partial indexing in POSTGRES: research project</em>. </span><span class="authorgroup"><span class="firstname">Nels</span> <span class="surname">Olson</span>. </span><span class="pubsnumber">UCB Engin T7.49.1993 O676. </span><span class="publisher"><span class="publishername">University of California. </span><span class="address">Berkeley, California. </span></span><span class="pubdate">1993. </span></p></div><div class="biblioentry" id="ONG90"><p>[ong90] <span class="biblioset">“A Unified Framework for Version Modeling Using Production Rules in a Database System”. <span class="authorgroup"><span class="firstname">L.</span> <span class="surname">Ong</span> and <span class="firstname">J.</span> <span class="surname">Goh</span>. </span></span><span class="biblioset"><em>ERL Technical Memorandum M90/33</em>. <span class="publisher"><span class="publishername">University of California. </span><span class="address">Berkeley, California. </span></span><span class="pubdate">April, 1990. </span></span></p></div><div class="biblioentry" id="ROWE87"><p>[rowe87] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M87-13.pdf" target="_top">The <span class="productname">POSTGRES</span>
+ data model</a>”. <span class="authorgroup"><span class="firstname">L.</span> <span class="surname">Rowe</span> and <span class="firstname">M.</span> <span class="surname">Stonebraker</span>. </span></span><span class="confgroup">VLDB Conference, Sept. 1987. </span></p></div><div class="biblioentry" id="SESHADRI95"><p>[seshadri95] <span class="biblioset">“<a class="ulink" href="https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.40.5740" target="_top">Generalized
+ Partial Indexes</a>”. <span class="authorgroup"><span class="firstname">P.</span> <span class="surname">Seshadri</span> and <span class="firstname">A.</span> <span class="surname">Swami</span>. </span></span><span class="confgroup">Eleventh International Conference on Data Engineering, 6–10 March 1995. </span><span class="pubsnumber">Cat. No.95CH35724. </span><span class="publisher"><span class="publishername">IEEE Computer Society Press. </span><span class="address">Los Alamitos, California. </span></span><span class="pubdate">1995. </span><span class="pagenums">420–7. </span></p></div><div class="biblioentry" id="STON86"><p>[ston86] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M85-95.pdf" target="_top">The
+ design of <span class="productname">POSTGRES</span></a>”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span> and <span class="firstname">L.</span> <span class="surname">Rowe</span>. </span></span><span class="confgroup">ACM-SIGMOD Conference on Management of Data, May 1986. </span></p></div><div class="biblioentry" id="STON87A"><p>[ston87a] <span class="biblioset">“The design of the <span class="productname">POSTGRES</span> rules system”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span>, <span class="firstname">E.</span> <span class="surname">Hanson</span>, and <span class="firstname">C. H.</span> <span class="surname">Hong</span>. </span></span><span class="confgroup">IEEE Conference on Data Engineering, Feb. 1987. </span></p></div><div class="biblioentry" id="STON87B"><p>[ston87b] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M87-06.pdf" target="_top">The
+ design of the <span class="productname">POSTGRES</span> storage
+ system</a>”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span>. </span></span><span class="confgroup">VLDB Conference, Sept. 1987. </span></p></div><div class="biblioentry" id="STON89"><p>[ston89] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M89-82.pdf" target="_top">A
+ commentary on the <span class="productname">POSTGRES</span> rules
+ system</a>”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span>, <span class="firstname">M.</span> <span class="surname">Hearst</span>, and <span class="firstname">S.</span> <span class="surname">Potamianos</span>. </span></span><span class="biblioset"><em>SIGMOD Record 18(3)</em>. <span class="date">Sept. 1989. </span></span></p></div><div class="biblioentry" id="STON89B"><p>[ston89b] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M89-17.pdf" target="_top">The
+ case for partial indexes</a>”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span>. </span></span><span class="biblioset"><em>SIGMOD Record 18(4)</em>. <span class="date">Dec. 1989. </span><span class="pagenums">4–11. </span></span></p></div><div class="biblioentry" id="STON90A"><p>[ston90a] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M90-34.pdf" target="_top">The
+ implementation of <span class="productname">POSTGRES</span></a>”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span>, <span class="firstname">L. A.</span> <span class="surname">Rowe</span>, and <span class="firstname">M.</span> <span class="surname">Hirohama</span>. </span></span><span class="biblioset"><em>Transactions on Knowledge and Data Engineering 2(1)</em>. <span class="publisher"><span class="publishername">IEEE. </span></span><span class="date">March 1990. </span></span></p></div><div class="biblioentry" id="STON90B"><p>[ston90b] <span class="biblioset">“<a class="ulink" href="https://dsf.berkeley.edu/papers/ERL-M90-36.pdf" target="_top">On
+ Rules, Procedures, Caching and Views in Database Systems</a>”. <span class="authorgroup"><span class="firstname">M.</span> <span class="surname">Stonebraker</span>, <span class="firstname">A.</span> <span class="surname">Jhingran</span>, <span class="firstname">J.</span> <span class="surname">Goh</span>, and <span class="firstname">S.</span> <span class="surname">Potamianos</span>. </span></span><span class="confgroup">ACM-SIGMOD Conference on Management of Data, June 1990. </span></p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgreceivexlog.html" title="O.5. pg_receivexlog renamed to pg_receivewal">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bookindex.html" title="Index">Next</a></td></tr><tr><td width="40%" align="left" valign="top">O.5. <code class="command">pg_receivexlog</code> renamed to <code class="command">pg_receivewal</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Index</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bki-commands.html b/doc/src/sgml/html/bki-commands.html
new file mode 100644
index 0000000..c833bd2
--- /dev/null
+++ b/doc/src/sgml/html/bki-commands.html
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>74.4. BKI Commands</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bki-format.html" title="74.3. BKI File Format" /><link rel="next" href="bki-structure.html" title="74.5. Structure of the Bootstrap BKI File" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">74.4. <acronym class="acronym">BKI</acronym> Commands</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bki-format.html" title="74.3. BKI File Format">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><th width="60%" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bki-structure.html" title="74.5. Structure of the Bootstrap BKI File">Next</a></td></tr></table><hr /></div><div class="sect1" id="BKI-COMMANDS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">74.4. <acronym class="acronym">BKI</acronym> Commands</h2></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal">create</code>
+ <em class="replaceable"><code>tablename</code></em>
+ <em class="replaceable"><code>tableoid</code></em>
+ [<span class="optional"><code class="literal">bootstrap</code></span>]
+ [<span class="optional"><code class="literal">shared_relation</code></span>]
+ [<span class="optional"><code class="literal">rowtype_oid</code> <em class="replaceable"><code>oid</code></em></span>]
+ (<em class="replaceable"><code>name1</code></em> =
+ <em class="replaceable"><code>type1</code></em>
+ [<span class="optional"><code class="literal">FORCE NOT NULL</code> | <code class="literal">FORCE NULL</code> </span>] [<span class="optional">,
+ <em class="replaceable"><code>name2</code></em> =
+ <em class="replaceable"><code>type2</code></em>
+ [<span class="optional"><code class="literal">FORCE NOT NULL</code> | <code class="literal">FORCE NULL</code> </span>],
+ ...</span>])
+ </span></dt><dd><p>
+ Create a table named <em class="replaceable"><code>tablename</code></em>, and having the OID
+ <em class="replaceable"><code>tableoid</code></em>,
+ with the columns given in parentheses.
+ </p><p>
+ The following column types are supported directly by
+ <code class="filename">bootstrap.c</code>: <code class="type">bool</code>,
+ <code class="type">bytea</code>, <code class="type">char</code> (1 byte),
+ <code class="type">name</code>, <code class="type">int2</code>,
+ <code class="type">int4</code>, <code class="type">regproc</code>, <code class="type">regclass</code>,
+ <code class="type">regtype</code>, <code class="type">text</code>,
+ <code class="type">oid</code>, <code class="type">tid</code>, <code class="type">xid</code>,
+ <code class="type">cid</code>, <code class="type">int2vector</code>, <code class="type">oidvector</code>,
+ <code class="type">_int4</code> (array), <code class="type">_text</code> (array),
+ <code class="type">_oid</code> (array), <code class="type">_char</code> (array),
+ <code class="type">_aclitem</code> (array). Although it is possible to create
+ tables containing columns of other types, this cannot be done until
+ after <code class="structname">pg_type</code> has been created and filled with
+ appropriate entries. (That effectively means that only these
+ column types can be used in bootstrap catalogs, but non-bootstrap
+ catalogs can contain any built-in type.)
+ </p><p>
+ When <code class="literal">bootstrap</code> is specified,
+ the table will only be created on disk; nothing is entered into
+ <code class="structname">pg_class</code>,
+ <code class="structname">pg_attribute</code>, etc., for it. Thus the
+ table will not be accessible by ordinary SQL operations until
+ such entries are made the hard way (with <code class="literal">insert</code>
+ commands). This option is used for creating
+ <code class="structname">pg_class</code> etc. themselves.
+ </p><p>
+ The table is created as shared if <code class="literal">shared_relation</code> is
+ specified.
+ The table's row type OID (<code class="structname">pg_type</code> OID) can optionally
+ be specified via the <code class="literal">rowtype_oid</code> clause; if not specified,
+ an OID is automatically generated for it. (The <code class="literal">rowtype_oid</code>
+ clause is useless if <code class="literal">bootstrap</code> is specified, but it can be
+ provided anyway for documentation.)
+ </p></dd><dt><span class="term">
+ <code class="literal">open</code> <em class="replaceable"><code>tablename</code></em>
+ </span></dt><dd><p>
+ Open the table named
+ <em class="replaceable"><code>tablename</code></em>
+ for insertion of data. Any currently open table is closed.
+ </p></dd><dt><span class="term">
+ <code class="literal">close</code> <em class="replaceable"><code>tablename</code></em>
+ </span></dt><dd><p>
+ Close the open table. The name of the table must be given as a
+ cross-check.
+ </p></dd><dt><span class="term">
+ <code class="literal">insert</code> <code class="literal">(</code> [<span class="optional"><em class="replaceable"><code>oid_value</code></em></span>] <em class="replaceable"><code>value1</code></em> <em class="replaceable"><code>value2</code></em> ... <code class="literal">)</code>
+ </span></dt><dd><p>
+ Insert a new row into the open table using <em class="replaceable"><code>value1</code></em>, <em class="replaceable"><code>value2</code></em>, etc., for its column
+ values.
+ </p><p>
+ NULL values can be specified using the special key word
+ <code class="literal">_null_</code>. Values that do not look like
+ identifiers or digit strings must be single-quoted.
+ (To include a single quote in a value, write it twice.
+ Escape-string-style backslash escapes are allowed in the string, too.)
+ </p></dd><dt><span class="term">
+ <code class="literal">declare</code> [<span class="optional"><code class="literal">unique</code></span>]
+ <code class="literal">index</code> <em class="replaceable"><code>indexname</code></em>
+ <em class="replaceable"><code>indexoid</code></em>
+ <code class="literal">on</code> <em class="replaceable"><code>tablename</code></em>
+ <code class="literal">using</code> <em class="replaceable"><code>amname</code></em>
+ <code class="literal">(</code> <em class="replaceable"><code>opclass1</code></em>
+ <em class="replaceable"><code>name1</code></em>
+ [<span class="optional">, ...</span>] <code class="literal">)</code>
+ </span></dt><dd><p>
+ Create an index named <em class="replaceable"><code>indexname</code></em>, having OID
+ <em class="replaceable"><code>indexoid</code></em>,
+ on the table named
+ <em class="replaceable"><code>tablename</code></em>, using the
+ <em class="replaceable"><code>amname</code></em> access
+ method. The fields to index are called <em class="replaceable"><code>name1</code></em>, <em class="replaceable"><code>name2</code></em> etc., and the operator
+ classes to use are <em class="replaceable"><code>opclass1</code></em>, <em class="replaceable"><code>opclass2</code></em> etc., respectively.
+ The index file is created and appropriate catalog entries are
+ made for it, but the index contents are not initialized by this command.
+ </p></dd><dt><span class="term">
+ <code class="literal">declare toast</code>
+ <em class="replaceable"><code>toasttableoid</code></em>
+ <em class="replaceable"><code>toastindexoid</code></em>
+ <code class="literal">on</code> <em class="replaceable"><code>tablename</code></em>
+ </span></dt><dd><p>
+ Create a TOAST table for the table named
+ <em class="replaceable"><code>tablename</code></em>.
+ The TOAST table is assigned OID
+ <em class="replaceable"><code>toasttableoid</code></em>
+ and its index is assigned OID
+ <em class="replaceable"><code>toastindexoid</code></em>.
+ As with <code class="literal">declare index</code>, filling of the index
+ is postponed.
+ </p></dd><dt><span class="term"><code class="literal">build indices</code></span></dt><dd><p>
+ Fill in the indices that have previously been declared.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bki-format.html" title="74.3. BKI File Format">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bki-structure.html" title="74.5. Structure of the Bootstrap BKI File">Next</a></td></tr><tr><td width="40%" align="left" valign="top">74.3. <acronym class="acronym">BKI</acronym> File Format </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 74.5. Structure of the Bootstrap <acronym class="acronym">BKI</acronym> File</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bki-example.html b/doc/src/sgml/html/bki-example.html
new file mode 100644
index 0000000..e7b6d66
--- /dev/null
+++ b/doc/src/sgml/html/bki-example.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>74.6. BKI Example</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bki-structure.html" title="74.5. Structure of the Bootstrap BKI File" /><link rel="next" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">74.6. BKI Example</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bki-structure.html" title="74.5. Structure of the Bootstrap BKI File">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><th width="60%" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Next</a></td></tr></table><hr /></div><div class="sect1" id="BKI-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">74.6. BKI Example</h2></div></div></div><p>
+ The following sequence of commands will create the table
+ <code class="literal">test_table</code> with OID 420, having three columns
+ <code class="literal">oid</code>, <code class="literal">cola</code> and <code class="literal">colb</code>
+ of type <code class="type">oid</code>, <code class="type">int4</code> and <code class="type">text</code>,
+ respectively, and insert two rows into the table:
+</p><pre class="programlisting">
+create test_table 420 (oid = oid, cola = int4, colb = text)
+open test_table
+insert ( 421 1 'value 1' )
+insert ( 422 2 _null_ )
+close test_table
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bki-structure.html" title="74.5. Structure of the Bootstrap BKI File">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Next</a></td></tr><tr><td width="40%" align="left" valign="top">74.5. Structure of the Bootstrap <acronym class="acronym">BKI</acronym> File </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 75. How the Planner Uses Statistics</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bki-format.html b/doc/src/sgml/html/bki-format.html
new file mode 100644
index 0000000..d9b3e82
--- /dev/null
+++ b/doc/src/sgml/html/bki-format.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>74.3. BKI File Format</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="system-catalog-initial-data.html" title="74.2. System Catalog Initial Data" /><link rel="next" href="bki-commands.html" title="74.4. BKI Commands" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">74.3. <acronym class="acronym">BKI</acronym> File Format</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="system-catalog-initial-data.html" title="74.2. System Catalog Initial Data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><th width="60%" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bki-commands.html" title="74.4. BKI Commands">Next</a></td></tr></table><hr /></div><div class="sect1" id="BKI-FORMAT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">74.3. <acronym class="acronym">BKI</acronym> File Format</h2></div></div></div><p>
+ This section describes how the <span class="productname">PostgreSQL</span>
+ backend interprets <acronym class="acronym">BKI</acronym> files. This description
+ will be easier to understand if the <code class="filename">postgres.bki</code>
+ file is at hand as an example.
+ </p><p>
+ <acronym class="acronym">BKI</acronym> input consists of a sequence of commands. Commands are made up
+ of a number of tokens, depending on the syntax of the command.
+ Tokens are usually separated by whitespace, but need not be if
+ there is no ambiguity. There is no special command separator; the
+ next token that syntactically cannot belong to the preceding
+ command starts a new one. (Usually you would put a new command on
+ a new line, for clarity.) Tokens can be certain key words, special
+ characters (parentheses, commas, etc.), identifiers, numbers, or
+ single-quoted strings. Everything is case sensitive.
+ </p><p>
+ Lines starting with <code class="literal">#</code> are ignored.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="system-catalog-initial-data.html" title="74.2. System Catalog Initial Data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bki-commands.html" title="74.4. BKI Commands">Next</a></td></tr><tr><td width="40%" align="left" valign="top">74.2. System Catalog Initial Data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 74.4. <acronym class="acronym">BKI</acronym> Commands</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bki-structure.html b/doc/src/sgml/html/bki-structure.html
new file mode 100644
index 0000000..9e36242
--- /dev/null
+++ b/doc/src/sgml/html/bki-structure.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>74.5. Structure of the Bootstrap BKI File</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bki-commands.html" title="74.4. BKI Commands" /><link rel="next" href="bki-example.html" title="74.6. BKI Example" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">74.5. Structure of the Bootstrap <acronym class="acronym">BKI</acronym> File</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bki-commands.html" title="74.4. BKI Commands">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><th width="60%" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bki-example.html" title="74.6. BKI Example">Next</a></td></tr></table><hr /></div><div class="sect1" id="BKI-STRUCTURE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">74.5. Structure of the Bootstrap <acronym class="acronym">BKI</acronym> File</h2></div></div></div><p>
+ The <code class="literal">open</code> command cannot be used until the tables it uses
+ exist and have entries for the table that is to be opened.
+ (These minimum tables are <code class="structname">pg_class</code>,
+ <code class="structname">pg_attribute</code>, <code class="structname">pg_proc</code>, and
+ <code class="structname">pg_type</code>.) To allow those tables themselves to be filled,
+ <code class="literal">create</code> with the <code class="literal">bootstrap</code> option implicitly opens
+ the created table for data insertion.
+ </p><p>
+ Also, the <code class="literal">declare index</code> and <code class="literal">declare toast</code>
+ commands cannot be used until the system catalogs they need have been
+ created and filled in.
+ </p><p>
+ Thus, the structure of the <code class="filename">postgres.bki</code> file has to
+ be:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ <code class="literal">create bootstrap</code> one of the critical tables
+ </p></li><li class="listitem"><p>
+ <code class="literal">insert</code> data describing at least the critical tables
+ </p></li><li class="listitem"><p>
+ <code class="literal">close</code>
+ </p></li><li class="listitem"><p>
+ Repeat for the other critical tables.
+ </p></li><li class="listitem"><p>
+ <code class="literal">create</code> (without <code class="literal">bootstrap</code>) a noncritical table
+ </p></li><li class="listitem"><p>
+ <code class="literal">open</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">insert</code> desired data
+ </p></li><li class="listitem"><p>
+ <code class="literal">close</code>
+ </p></li><li class="listitem"><p>
+ Repeat for the other noncritical tables.
+ </p></li><li class="listitem"><p>
+ Define indexes and toast tables.
+ </p></li><li class="listitem"><p>
+ <code class="literal">build indices</code>
+ </p></li></ol></div><p>
+ </p><p>
+ There are doubtless other, undocumented ordering dependencies.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bki-commands.html" title="74.4. BKI Commands">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bki-example.html" title="74.6. BKI Example">Next</a></td></tr><tr><td width="40%" align="left" valign="top">74.4. <acronym class="acronym">BKI</acronym> Commands </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 74.6. BKI Example</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bki.html b/doc/src/sgml/html/bki.html
new file mode 100644
index 0000000..2eaa2b6
--- /dev/null
+++ b/doc/src/sgml/html/bki.html
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 74. System Catalog Declarations and Initial Contents</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)" /><link rel="next" href="system-catalog-declarations.html" title="74.1. System Catalog Declaration Rules" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="system-catalog-declarations.html" title="74.1. System Catalog Declaration Rules">Next</a></td></tr></table><hr /></div><div class="chapter" id="BKI"><div class="titlepage"><div><div><h2 class="title">Chapter 74. System Catalog Declarations and Initial Contents</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="system-catalog-declarations.html">74.1. System Catalog Declaration Rules</a></span></dt><dt><span class="sect1"><a href="system-catalog-initial-data.html">74.2. System Catalog Initial Data</a></span></dt><dd><dl><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-INITIAL-DATA-FORMAT">74.2.1. Data File Format</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-OID-ASSIGNMENT">74.2.2. OID Assignment</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-OID-REFERENCES">74.2.3. OID Reference Lookup</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-AUTO-ARRAY-TYPES">74.2.4. Automatic Creation of Array Types</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-RECIPES">74.2.5. Recipes for Editing Data Files</a></span></dt></dl></dd><dt><span class="sect1"><a href="bki-format.html">74.3. <acronym class="acronym">BKI</acronym> File Format</a></span></dt><dt><span class="sect1"><a href="bki-commands.html">74.4. <acronym class="acronym">BKI</acronym> Commands</a></span></dt><dt><span class="sect1"><a href="bki-structure.html">74.5. Structure of the Bootstrap <acronym class="acronym">BKI</acronym> File</a></span></dt><dt><span class="sect1"><a href="bki-example.html">74.6. BKI Example</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> uses many different system catalogs
+ to keep track of the existence and properties of database objects, such as
+ tables and functions. Physically there is no difference between a system
+ catalog and a plain user table, but the backend C code knows the structure
+ and properties of each catalog, and can manipulate it directly at a low
+ level. Thus, for example, it is inadvisable to attempt to alter the
+ structure of a catalog on-the-fly; that would break assumptions built into
+ the C code about how rows of the catalog are laid out. But the structure
+ of the catalogs can change between major versions.
+ </p><p>
+ The structures of the catalogs are declared in specially formatted C
+ header files in the <code class="filename">src/include/catalog/</code> directory of
+ the source tree. For each catalog there is a header file
+ named after the catalog (e.g., <code class="filename">pg_class.h</code>
+ for <code class="structname">pg_class</code>), which defines the set of columns
+ the catalog has, as well as some other basic properties such as its OID.
+ </p><p>
+ Many of the catalogs have initial data that must be loaded into them
+ during the <span class="quote">“<span class="quote">bootstrap</span>”</span> phase
+ of <span class="application">initdb</span>, to bring the system up to a point
+ where it is capable of executing SQL commands. (For
+ example, <code class="filename">pg_class.h</code> must contain an entry for itself,
+ as well as one for each other system catalog and index.) This
+ initial data is kept in editable form in data files that are also stored
+ in the <code class="filename">src/include/catalog/</code> directory. For example,
+ <code class="filename">pg_proc.dat</code> describes all the initial rows that must
+ be inserted into the <code class="structname">pg_proc</code> catalog.
+ </p><p>
+ To create the catalog files and load this initial data into them, a
+ backend running in bootstrap mode reads a <acronym class="acronym">BKI</acronym>
+ (Backend Interface) file containing commands and initial data.
+ The <code class="filename">postgres.bki</code> file used in this mode is prepared
+ from the aforementioned header and data files, while building
+ a <span class="productname">PostgreSQL</span> distribution, by a Perl script
+ named <code class="filename">genbki.pl</code>.
+ Although it's specific to a particular <span class="productname">PostgreSQL</span>
+ release, <code class="filename">postgres.bki</code> is platform-independent and is
+ installed in the <code class="filename">share</code> subdirectory of the
+ installation tree.
+ </p><p>
+ <code class="filename">genbki.pl</code> also produces a derived header file for
+ each catalog, for example <code class="filename">pg_class_d.h</code> for
+ the <code class="structname">pg_class</code> catalog. This file contains
+ automatically-generated macro definitions, and may contain other macros,
+ enum declarations, and so on that can be useful for client C code that
+ reads a particular catalog.
+ </p><p>
+ Most PostgreSQL developers don't need to be directly concerned with
+ the <acronym class="acronym">BKI</acronym> file, but almost any nontrivial feature
+ addition in the backend will require modifying the catalog header files
+ and/or initial data files. The rest of this chapter gives some
+ information about that, and for completeness describes
+ the <acronym class="acronym">BKI</acronym> file format.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="system-catalog-declarations.html" title="74.1. System Catalog Declaration Rules">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.7. Heap-Only Tuples (<acronym class="acronym">HOT</acronym>) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 74.1. System Catalog Declaration Rules</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bloom.html b/doc/src/sgml/html/bloom.html
new file mode 100644
index 0000000..1c1a264
--- /dev/null
+++ b/doc/src/sgml/html/bloom.html
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.7. bloom</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="basic-archive.html" title="F.6. basic_archive" /><link rel="next" href="btree-gin.html" title="F.8. btree_gin" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.7. bloom</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="basic-archive.html" title="F.6. basic_archive">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree-gin.html" title="F.8. btree_gin">Next</a></td></tr></table><hr /></div><div class="sect1" id="BLOOM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.7. bloom</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.7">F.7.1. Parameters</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.8">F.7.2. Examples</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.9">F.7.3. Operator Class Interface</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.10">F.7.4. Limitations</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.11">F.7.5. Authors</a></span></dt></dl></div><a id="id-1.11.7.16.2" class="indexterm"></a><p>
+ <code class="literal">bloom</code> provides an index access method based on
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Bloom_filter" target="_top">Bloom filters</a>.
+ </p><p>
+ A Bloom filter is a space-efficient data structure that is used to test
+ whether an element is a member of a set. In the case of an index access
+ method, it allows fast exclusion of non-matching tuples via signatures
+ whose size is determined at index creation.
+ </p><p>
+ A signature is a lossy representation of the indexed attribute(s), and as
+ such is prone to reporting false positives; that is, it may be reported
+ that an element is in the set, when it is not. So index search results
+ must always be rechecked using the actual attribute values from the heap
+ entry. Larger signatures reduce the odds of a false positive and thus
+ reduce the number of useless heap visits, but of course also make the index
+ larger and hence slower to scan.
+ </p><p>
+ This type of index is most useful when a table has many attributes and
+ queries test arbitrary combinations of them. A traditional btree index is
+ faster than a bloom index, but it can require many btree indexes to support
+ all possible queries where one needs only a single bloom index. Note
+ however that bloom indexes only support equality queries, whereas btree
+ indexes can also perform inequality and range searches.
+ </p><div class="sect2" id="id-1.11.7.16.7"><div class="titlepage"><div><div><h3 class="title">F.7.1. Parameters</h3></div></div></div><p>
+ A <code class="literal">bloom</code> index accepts the following parameters in its
+ <code class="literal">WITH</code> clause:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">length</code></span></dt><dd><p>
+ Length of each signature (index entry) in bits. It is rounded up to the
+ nearest multiple of <code class="literal">16</code>. The default is
+ <code class="literal">80</code> bits and the maximum is <code class="literal">4096</code>.
+ </p></dd></dl></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">col1 — col32</code></span></dt><dd><p>
+ Number of bits generated for each index column. Each parameter's name
+ refers to the number of the index column that it controls. The default
+ is <code class="literal">2</code> bits and the maximum is <code class="literal">4095</code>.
+ Parameters for index columns not actually used are ignored.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.16.8"><div class="titlepage"><div><div><h3 class="title">F.7.2. Examples</h3></div></div></div><p>
+ This is an example of creating a bloom index:
+ </p><pre class="programlisting">
+CREATE INDEX bloomidx ON tbloom USING bloom (i1,i2,i3)
+ WITH (length=80, col1=2, col2=2, col3=4);
+</pre><p>
+ The index is created with a signature length of 80 bits, with attributes
+ i1 and i2 mapped to 2 bits, and attribute i3 mapped to 4 bits. We could
+ have omitted the <code class="literal">length</code>, <code class="literal">col1</code>,
+ and <code class="literal">col2</code> specifications since those have the default values.
+ </p><p>
+ Here is a more complete example of bloom index definition and usage, as
+ well as a comparison with equivalent btree indexes. The bloom index is
+ considerably smaller than the btree index, and can perform better.
+ </p><pre class="programlisting">
+=# CREATE TABLE tbloom AS
+ SELECT
+ (random() * 1000000)::int as i1,
+ (random() * 1000000)::int as i2,
+ (random() * 1000000)::int as i3,
+ (random() * 1000000)::int as i4,
+ (random() * 1000000)::int as i5,
+ (random() * 1000000)::int as i6
+ FROM
+ generate_series(1,10000000);
+SELECT 10000000
+</pre><p>
+ A sequential scan over this large table takes a long time:
+</p><pre class="programlisting">
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------------------
+ Seq Scan on tbloom (cost=0.00..2137.14 rows=3 width=24) (actual time=16.971..16.971 rows=0 loops=1)
+ Filter: ((i2 = 898732) AND (i5 = 123451))
+ Rows Removed by Filter: 100000
+ Planning Time: 0.346 ms
+ Execution Time: 16.988 ms
+(5 rows)
+</pre><p>
+ </p><p>
+ Even with the btree index defined the result will still be a
+ sequential scan:
+</p><pre class="programlisting">
+=# CREATE INDEX btreeidx ON tbloom (i1, i2, i3, i4, i5, i6);
+CREATE INDEX
+=# SELECT pg_size_pretty(pg_relation_size('btreeidx'));
+ pg_size_pretty
+----------------
+ 3976 kB
+(1 row)
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------------------
+ Seq Scan on tbloom (cost=0.00..2137.00 rows=2 width=24) (actual time=12.805..12.805 rows=0 loops=1)
+ Filter: ((i2 = 898732) AND (i5 = 123451))
+ Rows Removed by Filter: 100000
+ Planning Time: 0.138 ms
+ Execution Time: 12.817 ms
+(5 rows)
+</pre><p>
+ </p><p>
+ Having the bloom index defined on the table is better than btree in
+ handling this type of search:
+</p><pre class="programlisting">
+=# CREATE INDEX bloomidx ON tbloom USING bloom (i1, i2, i3, i4, i5, i6);
+CREATE INDEX
+=# SELECT pg_size_pretty(pg_relation_size('bloomidx'));
+ pg_size_pretty
+----------------
+ 1584 kB
+(1 row)
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------​--------------------------------------------------
+ Bitmap Heap Scan on tbloom (cost=1792.00..1799.69 rows=2 width=24) (actual time=0.388..0.388 rows=0 loops=1)
+ Recheck Cond: ((i2 = 898732) AND (i5 = 123451))
+ Rows Removed by Index Recheck: 29
+ Heap Blocks: exact=28
+ -&gt; Bitmap Index Scan on bloomidx (cost=0.00..1792.00 rows=2 width=0) (actual time=0.356..0.356 rows=29 loops=1)
+ Index Cond: ((i2 = 898732) AND (i5 = 123451))
+ Planning Time: 0.099 ms
+ Execution Time: 0.408 ms
+(8 rows)
+</pre><p>
+ </p><p>
+ Now, the main problem with the btree search is that btree is inefficient
+ when the search conditions do not constrain the leading index column(s).
+ A better strategy for btree is to create a separate index on each column.
+ Then the planner will choose something like this:
+</p><pre class="programlisting">
+=# CREATE INDEX btreeidx1 ON tbloom (i1);
+CREATE INDEX
+=# CREATE INDEX btreeidx2 ON tbloom (i2);
+CREATE INDEX
+=# CREATE INDEX btreeidx3 ON tbloom (i3);
+CREATE INDEX
+=# CREATE INDEX btreeidx4 ON tbloom (i4);
+CREATE INDEX
+=# CREATE INDEX btreeidx5 ON tbloom (i5);
+CREATE INDEX
+=# CREATE INDEX btreeidx6 ON tbloom (i6);
+CREATE INDEX
+=# EXPLAIN ANALYZE SELECT * FROM tbloom WHERE i2 = 898732 AND i5 = 123451;
+ QUERY PLAN
+-------------------------------------------------------------------​--------------------------------------------------------
+ Bitmap Heap Scan on tbloom (cost=24.34..32.03 rows=2 width=24) (actual time=0.028..0.029 rows=0 loops=1)
+ Recheck Cond: ((i5 = 123451) AND (i2 = 898732))
+ -&gt; BitmapAnd (cost=24.34..24.34 rows=2 width=0) (actual time=0.027..0.027 rows=0 loops=1)
+ -&gt; Bitmap Index Scan on btreeidx5 (cost=0.00..12.04 rows=500 width=0) (actual time=0.026..0.026 rows=0 loops=1)
+ Index Cond: (i5 = 123451)
+ -&gt; Bitmap Index Scan on btreeidx2 (cost=0.00..12.04 rows=500 width=0) (never executed)
+ Index Cond: (i2 = 898732)
+ Planning Time: 0.491 ms
+ Execution Time: 0.055 ms
+(9 rows)
+</pre><p>
+ Although this query runs much faster than with either of the single
+ indexes, we pay a penalty in index size. Each of the single-column
+ btree indexes occupies 2 MB, so the total space needed is 12 MB,
+ eight times the space used by the bloom index.
+ </p></div><div class="sect2" id="id-1.11.7.16.9"><div class="titlepage"><div><div><h3 class="title">F.7.3. Operator Class Interface</h3></div></div></div><p>
+ An operator class for bloom indexes requires only a hash function for the
+ indexed data type and an equality operator for searching. This example
+ shows the operator class definition for the <code class="type">text</code> data type:
+ </p><pre class="programlisting">
+CREATE OPERATOR CLASS text_ops
+DEFAULT FOR TYPE text USING bloom AS
+ OPERATOR 1 =(text, text),
+ FUNCTION 1 hashtext(text);
+</pre></div><div class="sect2" id="id-1.11.7.16.10"><div class="titlepage"><div><div><h3 class="title">F.7.4. Limitations</h3></div></div></div><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Only operator classes for <code class="type">int4</code> and <code class="type">text</code> are
+ included with the module.
+ </p></li><li class="listitem"><p>
+ Only the <code class="literal">=</code> operator is supported for search. But
+ it is possible to add support for arrays with union and intersection
+ operations in the future.
+ </p></li><li class="listitem"><p>
+ <code class="literal">bloom</code> access method doesn't support
+ <code class="literal">UNIQUE</code> indexes.
+ </p></li><li class="listitem"><p>
+ <code class="literal">bloom</code> access method doesn't support searching for
+ <code class="literal">NULL</code> values.
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="id-1.11.7.16.11"><div class="titlepage"><div><div><h3 class="title">F.7.5. Authors</h3></div></div></div><p>
+ Teodor Sigaev <code class="email">&lt;<a class="email" href="mailto:teodor@postgrespro.ru">teodor@postgrespro.ru</a>&gt;</code>,
+ Postgres Professional, Moscow, Russia
+ </p><p>
+ Alexander Korotkov <code class="email">&lt;<a class="email" href="mailto:a.korotkov@postgrespro.ru">a.korotkov@postgrespro.ru</a>&gt;</code>,
+ Postgres Professional, Moscow, Russia
+ </p><p>
+ Oleg Bartunov <code class="email">&lt;<a class="email" href="mailto:obartunov@postgrespro.ru">obartunov@postgrespro.ru</a>&gt;</code>,
+ Postgres Professional, Moscow, Russia
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="basic-archive.html" title="F.6. basic_archive">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree-gin.html" title="F.8. btree_gin">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.6. basic_archive </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.8. btree_gin</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bookindex.html b/doc/src/sgml/html/bookindex.html
new file mode 100644
index 0000000..3b24b7f
--- /dev/null
+++ b/doc/src/sgml/html/bookindex.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Index</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="biblio.html" title="Bibliography" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Index</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="biblio.html" title="Bibliography">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> </td></tr></table><hr /></div><div class="index" id="BOOKINDEX"><div class="titlepage"><div><div><h1 class="title">Index</h1></div></div></div><div xmlns:xlink="http://www.w3.org/1999/xlink" class="index"><p class="indexdiv-quicklinks"><a href="#indexdiv-Symbols">Symbols</a>
+ |
+ <a href="#indexdiv-A">A</a>
+ |
+ <a href="#indexdiv-B">B</a>
+ |
+ <a href="#indexdiv-C">C</a>
+ |
+ <a href="#indexdiv-D">D</a>
+ |
+ <a href="#indexdiv-E">E</a>
+ |
+ <a href="#indexdiv-F">F</a>
+ |
+ <a href="#indexdiv-G">G</a>
+ |
+ <a href="#indexdiv-H">H</a>
+ |
+ <a href="#indexdiv-I">I</a>
+ |
+ <a href="#indexdiv-J">J</a>
+ |
+ <a href="#indexdiv-K">K</a>
+ |
+ <a href="#indexdiv-L">L</a>
+ |
+ <a href="#indexdiv-M">M</a>
+ |
+ <a href="#indexdiv-N">N</a>
+ |
+ <a href="#indexdiv-O">O</a>
+ |
+ <a href="#indexdiv-P">P</a>
+ |
+ <a href="#indexdiv-Q">Q</a>
+ |
+ <a href="#indexdiv-R">R</a>
+ |
+ <a href="#indexdiv-S">S</a>
+ |
+ <a href="#indexdiv-T">T</a>
+ |
+ <a href="#indexdiv-U">U</a>
+ |
+ <a href="#indexdiv-V">V</a>
+ |
+ <a href="#indexdiv-W">W</a>
+ |
+ <a href="#indexdiv-X">X</a>
+ |
+ <a href="#indexdiv-Y">Y</a>
+ |
+ <a href="#indexdiv-Z">Z</a></p><div class="indexdiv" id="indexdiv-Symbols"><h3>Symbols</h3><dl><dt id="ientry-idm1813">$, <a class="indexterm" href="sql-expressions.html#SQL-EXPRESSIONS-PARAMETERS-POSITIONAL">Positional Parameters</a></dt><dt id="ientry-idm73988">$libdir, <a class="indexterm" href="xfunc-c.html#XFUNC-C-DYNLOAD">Dynamic Loading</a></dt><dt id="ientry-idm43691">$libdir/plugins, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">Shared Library Preloading</a>, <a class="indexterm" href="sql-load.html#SQL-LOAD-DESCRIPTION">Description</a></dt><dt id="ientry-idm5260">*, <a class="indexterm" href="queries-select-lists.html#QUERIES-SELECT-LIST-ITEMS">Select-List Items</a></dt><dt id="ientry-idm61889">.pgpass, <a class="indexterm" href="libpq-pgpass.html">The Password File</a></dt><dt id="ientry-idm61924">.pg_service.conf, <a class="indexterm" href="libpq-pgservice.html">The Connection Service File</a></dt><dt id="ientry-idm2213">::, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS">Type Casts</a></dt><dt id="ientry-idm87770">_PG_archive_module_init, <a class="indexterm" href="archive-module-init.html">Initialization Functions</a></dt><dt id="ientry-idm74021">_PG_init, <a class="indexterm" href="xfunc-c.html#XFUNC-C-DYNLOAD">Dynamic Loading</a></dt><dt id="ientry-idm87333">_PG_output_plugin_init, <a class="indexterm" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-INIT">Initialization Function</a></dt></dl></div><div class="indexdiv" id="indexdiv-A"><h3>A</h3><dl><dt id="ientry-idm19566">abbrev, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm87822">ABORT, <a class="indexterm" href="sql-abort.html">ABORT</a></dt><dt id="ientry-idm11175">abs, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm3034">ACL, <a class="indexterm" href="ddl-priv.html">Privileges</a></dt><dt id="ientry-idm26894">aclcontains, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26933">acldefault, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26965">aclexplode, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm3465">aclitem, <a class="indexterm" href="ddl-priv.html">Privileges</a></dt><dt id="ientry-idm26878">aclitemeq, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm11732">acos, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11744">acosd, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm12001">acosh, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm173167">administration tools</dt><dd><dl><dt>externally maintained, <a class="indexterm" href="external-admin-tools.html">Administration Tools</a></dt></dl></dd><dt id="ientry-idm162941">adminpack, <a class="indexterm" href="adminpack.html">adminpack</a></dt><dt id="ientry-idm34237">advisory lock, <a class="indexterm" href="explicit-locking.html#ADVISORY-LOCKS">Advisory Locks</a></dt><dt id="ientry-idm17142">age, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm828">aggregate function, <a class="indexterm" href="tutorial-agg.html">Aggregate Functions</a>, <a class="indexterm" href="sql-expressions.html#SYNTAX-AGGREGATES">Aggregate Expressions</a>, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a>, <a class="indexterm" href="xaggr.html">User-Defined Aggregates</a></dt><dd><dl><dt>built-in, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt>invocation, <a class="indexterm" href="sql-expressions.html#SYNTAX-AGGREGATES">Aggregate Expressions</a></dt><dt>moving aggregate, <a class="indexterm" href="xaggr.html#XAGGR-MOVING-AGGREGATES">Moving-Aggregate Mode</a></dt><dt>ordered set, <a class="indexterm" href="xaggr.html#XAGGR-ORDERED-SET-AGGREGATES">Ordered-Set Aggregates</a></dt><dt>partial aggregation, <a class="indexterm" href="xaggr.html#XAGGR-PARTIAL-AGGREGATES">Partial Aggregation</a></dt><dt>polymorphic, <a class="indexterm" href="xaggr.html#XAGGR-POLYMORPHIC-AGGREGATES">Polymorphic and Variadic Aggregates</a></dt><dt>support functions for, <a class="indexterm" href="xaggr.html#XAGGR-SUPPORT-FUNCTIONS">Support Functions for Aggregates</a></dt><dt>user-defined, <a class="indexterm" href="xaggr.html">User-Defined Aggregates</a></dt><dt>variadic, <a class="indexterm" href="xaggr.html#XAGGR-POLYMORPHIC-AGGREGATES">Polymorphic and Variadic Aggregates</a></dt></dl></dd><dt id="ientry-idm36418">AIX, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-AIX">AIX</a></dt><dd><dl><dt>installation on, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-AIX">AIX</a></dt><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt></dl></dd><dt id="ientry-idm165956">akeys, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm810">alias, <a class="indexterm" href="queries-table-expressions.html#QUERIES-TABLE-ALIASES">Table and Column Aliases</a>, <a class="indexterm" href="queries-select-lists.html#QUERIES-COLUMN-LABELS">Column Labels</a></dt><dd><dl><dt>for table name in query, <a class="indexterm" href="tutorial-join.html">Joins Between Tables</a></dt><dt>in the FROM clause, <a class="indexterm" href="queries-table-expressions.html#QUERIES-TABLE-ALIASES">Table and Column Aliases</a></dt><dt>in the select list, <a class="indexterm" href="queries-select-lists.html#QUERIES-COLUMN-LABELS">Column Labels</a></dt></dl></dd><dt id="ientry-idm5202">ALL, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a>, <a class="indexterm" href="queries-select-lists.html#QUERIES-DISTINCT">DISTINCT</a>, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dd><dl><dt>GROUP BY ALL, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a></dt><dt>SELECT ALL, <a class="indexterm" href="queries-select-lists.html#QUERIES-DISTINCT">DISTINCT</a></dt></dl></dd><dt id="ientry-idm44343">allow_in_place_tablespaces configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44355">allow_system_table_mods configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm87884">ALTER AGGREGATE, <a class="indexterm" href="sql-alteraggregate.html">ALTER AGGREGATE</a></dt><dt id="ientry-idm88007">ALTER COLLATION, <a class="indexterm" href="sql-altercollation.html">ALTER COLLATION</a></dt><dt id="ientry-idm88100">ALTER CONVERSION, <a class="indexterm" href="sql-alterconversion.html">ALTER CONVERSION</a></dt><dt id="ientry-idm88169">ALTER DATABASE, <a class="indexterm" href="sql-alterdatabase.html">ALTER DATABASE</a></dt><dt id="ientry-idm88303">ALTER DEFAULT PRIVILEGES, <a class="indexterm" href="sql-alterdefaultprivileges.html">ALTER DEFAULT PRIVILEGES</a></dt><dt id="ientry-idm88405">ALTER DOMAIN, <a class="indexterm" href="sql-alterdomain.html">ALTER DOMAIN</a></dt><dt id="ientry-idm88604">ALTER EVENT TRIGGER, <a class="indexterm" href="sql-altereventtrigger.html">ALTER EVENT TRIGGER</a></dt><dt id="ientry-idm88663">ALTER EXTENSION, <a class="indexterm" href="sql-alterextension.html">ALTER EXTENSION</a></dt><dt id="ientry-idm88891">ALTER FOREIGN DATA WRAPPER, <a class="indexterm" href="sql-alterforeigndatawrapper.html">ALTER FOREIGN DATA WRAPPER</a></dt><dt id="ientry-idm88998">ALTER FOREIGN TABLE, <a class="indexterm" href="sql-alterforeigntable.html">ALTER FOREIGN TABLE</a></dt><dt id="ientry-idm89332">ALTER FUNCTION, <a class="indexterm" href="sql-alterfunction.html">ALTER FUNCTION</a></dt><dt id="ientry-idm89581">ALTER GROUP, <a class="indexterm" href="sql-altergroup.html">ALTER GROUP</a></dt><dt id="ientry-idm89654">ALTER INDEX, <a class="indexterm" href="sql-alterindex.html">ALTER INDEX</a></dt><dt id="ientry-idm89836">ALTER LANGUAGE, <a class="indexterm" href="sql-alterlanguage.html">ALTER LANGUAGE</a></dt><dt id="ientry-idm89886">ALTER LARGE OBJECT, <a class="indexterm" href="sql-alterlargeobject.html">ALTER LARGE OBJECT</a></dt><dt id="ientry-idm89928">ALTER MATERIALIZED VIEW, <a class="indexterm" href="sql-altermaterializedview.html">ALTER MATERIALIZED VIEW</a></dt><dt id="ientry-idm90045">ALTER OPERATOR, <a class="indexterm" href="sql-alteroperator.html">ALTER OPERATOR</a></dt><dt id="ientry-idm90137">ALTER OPERATOR CLASS, <a class="indexterm" href="sql-alteropclass.html">ALTER OPERATOR CLASS</a></dt><dt id="ientry-idm90206">ALTER OPERATOR FAMILY, <a class="indexterm" href="sql-alteropfamily.html">ALTER OPERATOR FAMILY</a></dt><dt id="ientry-idm90379">ALTER POLICY, <a class="indexterm" href="sql-alterpolicy.html">ALTER POLICY</a></dt><dt id="ientry-idm90462">ALTER PROCEDURE, <a class="indexterm" href="sql-alterprocedure.html">ALTER PROCEDURE</a></dt><dt id="ientry-idm90640">ALTER PUBLICATION, <a class="indexterm" href="sql-alterpublication.html">ALTER PUBLICATION</a></dt><dt id="ientry-idm46159">ALTER ROLE, <a class="indexterm" href="role-attributes.html">Role Attributes</a>, <a class="indexterm" href="sql-alterrole.html">ALTER ROLE</a></dt><dt id="ientry-idm90998">ALTER ROUTINE, <a class="indexterm" href="sql-alterroutine.html">ALTER ROUTINE</a></dt><dt id="ientry-idm91078">ALTER RULE, <a class="indexterm" href="sql-alterrule.html">ALTER RULE</a></dt><dt id="ientry-idm91133">ALTER SCHEMA, <a class="indexterm" href="sql-alterschema.html">ALTER SCHEMA</a></dt><dt id="ientry-idm91187">ALTER SEQUENCE, <a class="indexterm" href="sql-altersequence.html">ALTER SEQUENCE</a></dt><dt id="ientry-idm91409">ALTER SERVER, <a class="indexterm" href="sql-alterserver.html">ALTER SERVER</a></dt><dt id="ientry-idm91491">ALTER STATISTICS, <a class="indexterm" href="sql-alterstatistics.html">ALTER STATISTICS</a></dt><dt id="ientry-idm91565">ALTER SUBSCRIPTION, <a class="indexterm" href="sql-altersubscription.html">ALTER SUBSCRIPTION</a></dt><dt id="ientry-idm91770">ALTER SYSTEM, <a class="indexterm" href="sql-altersystem.html">ALTER SYSTEM</a></dt><dt id="ientry-idm91850">ALTER TABLE, <a class="indexterm" href="sql-altertable.html">ALTER TABLE</a></dt><dt id="ientry-idm92788">ALTER TABLESPACE, <a class="indexterm" href="sql-altertablespace.html">ALTER TABLESPACE</a></dt><dt id="ientry-idm92866">ALTER TEXT SEARCH CONFIGURATION, <a class="indexterm" href="sql-altertsconfig.html">ALTER TEXT SEARCH CONFIGURATION</a></dt><dt id="ientry-idm92977">ALTER TEXT SEARCH DICTIONARY, <a class="indexterm" href="sql-altertsdictionary.html">ALTER TEXT SEARCH DICTIONARY</a></dt><dt id="ientry-idm93060">ALTER TEXT SEARCH PARSER, <a class="indexterm" href="sql-altertsparser.html">ALTER TEXT SEARCH PARSER</a></dt><dt id="ientry-idm93111">ALTER TEXT SEARCH TEMPLATE, <a class="indexterm" href="sql-altertstemplate.html">ALTER TEXT SEARCH TEMPLATE</a></dt><dt id="ientry-idm93162">ALTER TRIGGER, <a class="indexterm" href="sql-altertrigger.html">ALTER TRIGGER</a></dt><dt id="ientry-idm93236">ALTER TYPE, <a class="indexterm" href="sql-altertype.html">ALTER TYPE</a></dt><dt id="ientry-idm93498">ALTER USER, <a class="indexterm" href="sql-alteruser.html">ALTER USER</a></dt><dt id="ientry-idm93550">ALTER USER MAPPING, <a class="indexterm" href="sql-alterusermapping.html">ALTER USER MAPPING</a></dt><dt id="ientry-idm93622">ALTER VIEW, <a class="indexterm" href="sql-alterview.html">ALTER VIEW</a></dt><dt id="ientry-idm163052">amcheck, <a class="indexterm" href="amcheck.html">amcheck</a></dt><dt id="ientry-idm49023">ANALYZE, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS">Updating Planner Statistics</a>, <a class="indexterm" href="sql-analyze.html">ANALYZE</a></dt><dt id="ientry-idm10360">AND (operator), <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt id="ientry-idm104233">anonymous code blocks, <a class="indexterm" href="sql-do.html">DO</a></dt><dt id="ientry-idm10126">any, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm24941">ANY, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a>, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm10130">anyarray, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10140">anycompatible, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10142">anycompatiblearray, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10148">anycompatiblemultirange, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10144">anycompatiblenonarray, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10146">anycompatiblerange, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10128">anyelement, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10134">anyenum, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10138">anymultirange, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10132">anynonarray, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm10136">anyrange, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm67572">applicable role, <a class="indexterm" href="infoschema-applicable-roles.html">applicable_roles</a></dt><dt id="ientry-idm41950">application_name configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm6262">arbitrary precision numbers, <a class="indexterm" href="datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL">Arbitrary Precision Numbers</a></dt><dt id="ientry-idm87755">Archive Modules, <a class="indexterm" href="archive-modules.html">Archive Modules</a></dt><dt id="ientry-idm40277">archive_cleanup_command configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">Archive Recovery</a></dt><dt id="ientry-idm40142">archive_command configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING">Archiving</a></dt><dt id="ientry-idm40166">archive_library configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING">Archiving</a></dt><dt id="ientry-idm40115">archive_mode configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING">Archiving</a></dt><dt id="ientry-idm40180">archive_timeout configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING">Archiving</a></dt><dt id="ientry-idm18951">area, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm168480">armor, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.16">armor(), dearmor()</a></dt><dt id="ientry-idm2281">array, <a class="indexterm" href="arrays.html">Arrays</a></dt><dd><dl><dt>accessing, <a class="indexterm" href="arrays.html#ARRAYS-ACCESSING">Accessing Arrays</a></dt><dt>constant, <a class="indexterm" href="arrays.html#ARRAYS-INPUT">Array Value Input</a></dt><dt>constructor, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS">Array Constructors</a></dt><dt>declaration, <a class="indexterm" href="arrays.html#ARRAYS-DECLARATION">Declaration of Array Types</a></dt><dt>I/O, <a class="indexterm" href="arrays.html#ARRAYS-IO">Array Input and Output Syntax</a></dt><dt>modifying, <a class="indexterm" href="arrays.html#ARRAYS-MODIFYING">Modifying Arrays</a></dt><dt>of user-defined type, <a class="indexterm" href="xtypes.html">User-Defined Types</a></dt><dt>searching, <a class="indexterm" href="arrays.html#ARRAYS-SEARCHING">Searching in Arrays</a></dt></dl></dd><dt id="ientry-idm2284">ARRAY, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS">Array Constructors</a>, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt></dl></dd><dt id="ientry-idm24578">array_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a>, <a class="indexterm" href="intagg.html#id-1.11.7.28.4">Functions</a></dt><dt id="ientry-idm23518">array_append, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23534">array_cat, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23550">array_dims, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23562">array_fill, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23581">array_length, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23600">array_lower, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23613">array_ndims, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm43881">array_nulls configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm23625">array_position, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23643">array_positions, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23660">array_prepend, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23676">array_remove, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm23691">array_replace, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm21720">array_to_json, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm23705">array_to_string, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm19974">array_to_tsvector, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm23729">array_upper, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm12423">ascii, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm11756">asin, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11768">asind, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11989">asinh, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm81404">ASSERT</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-ASSERT">Checking Assertions</a></dt></dl></dd><dt id="ientry-idm81407">assertions</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-ASSERT">Checking Assertions</a></dt></dl></dd><dt id="ientry-idm56324">asynchronous commit, <a class="indexterm" href="wal-async-commit.html">Asynchronous Commit</a></dt><dt id="ientry-idm18115">AT TIME ZONE, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT">AT TIME ZONE</a></dt><dt id="ientry-idm11780">atan, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11804">atan2, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11821">atan2d, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11792">atand, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm12013">atanh, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm38781">authentication_timeout configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt><dt id="ientry-idm163280">auth_delay, <a class="indexterm" href="auth-delay.html">auth_delay</a></dt><dt id="ientry-idm163294">auth_delay.milliseconds configuration parameter, <a class="indexterm" href="auth-delay.html#id-1.11.7.12.5">Configuration Parameters</a></dt><dt id="ientry-idm6468">auto-increment (see <a href="#ientry-idm6458">serial</a>)</dt><dt id="ientry-idm34807">autocommit</dt><dd><dl><dt>bulk-loading data, <a class="indexterm" href="populate.html#DISABLE-AUTOCOMMIT">Disable Autocommit</a></dt><dt>psql, <a class="indexterm" href="app-psql.html#APP-PSQL-VARIABLES">Variables</a></dt></dl></dd><dt id="ientry-idm97764">autosummarize storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a></dt><dt id="ientry-idm42780">autovacuum</dt><dd><dl><dt>configuration parameters, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>general information, <a class="indexterm" href="routine-vacuuming.html#AUTOVACUUM">The Autovacuum Daemon</a></dt></dl></dd><dt id="ientry-idm42792">autovacuum configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt id="ientry-idm42890">autovacuum_analyze_scale_factor</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm42852">autovacuum_analyze_threshold</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm101349">autovacuum_enabled storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm42903">autovacuum_freeze_max_age</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm101498">autovacuum_freeze_min_age storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm101524">autovacuum_freeze_table_age storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm42805">autovacuum_max_workers configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt id="ientry-idm42919">autovacuum_multixact_freeze_max_age</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm101535">autovacuum_multixact_freeze_min_age storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm101561">autovacuum_multixact_freeze_table_age storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm42814">autovacuum_naptime configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt id="ientry-idm42936">autovacuum_vacuum_cost_delay</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm42949">autovacuum_vacuum_cost_limit</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm42877">autovacuum_vacuum_insert_scale_factor</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm42839">autovacuum_vacuum_insert_threshold</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm42864">autovacuum_vacuum_scale_factor</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm42827">autovacuum_vacuum_threshold</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-autovacuum.html">Automatic Vacuuming</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm39264">autovacuum_work_mem configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm163308">auto_explain, <a class="indexterm" href="auto-explain.html">auto_explain</a></dt><dt id="ientry-idm163342">auto_explain.log_analyze configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163357">auto_explain.log_buffers configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163429">auto_explain.log_format configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163444">auto_explain.log_level configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163329">auto_explain.log_min_duration configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163464">auto_explain.log_nested_statements configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163419">auto_explain.log_settings configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163383">auto_explain.log_timing configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163396">auto_explain.log_triggers configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163407">auto_explain.log_verbose configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163370">auto_explain.log_wal configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm163474">auto_explain.sample_rate configuration parameter, <a class="indexterm" href="auto-explain.html#id-1.11.7.13.5">Configuration Parameters</a></dt><dt id="ientry-idm165983">avals, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm24596">average, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm24598">avg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></div><div class="indexdiv" id="indexdiv-B"><h3>B</h3><dl><dt id="ientry-idm31180">B-Tree (see <a href="#ientry-idm31128">index</a>)</dt><dt id="ientry-idm39520">backend_flush_after configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm87037">Background workers, <a class="indexterm" href="bgworker.html">Background Worker Processes</a></dt><dt id="ientry-idm1308">backslash escapes, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE">String Constants with C-Style Escapes</a></dt><dt id="ientry-idm43901">backslash_quote configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm44365">backtrace_functions configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm28729">backup, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a>, <a class="indexterm" href="backup.html">Backup and Restore</a></dt><dt id="ientry-idm148628">Backup Manifest, <a class="indexterm" href="backup-manifest-format.html">Backup Manifest Format</a></dt><dt id="ientry-idm73119">base type, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a></dt><dt id="ientry-idm14035">base64 format, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm163494">basebackup_to_shell, <a class="indexterm" href="basebackup-to-shell.html">basebackup_to_shell</a></dt><dt id="ientry-idm163512">basebackup_to_shell.command configuration parameter, <a class="indexterm" href="basebackup-to-shell.html#id-1.11.7.14.5">Configuration Parameters</a></dt><dt id="ientry-idm163528">basebackup_to_shell.required_role configuration parameter, <a class="indexterm" href="basebackup-to-shell.html#id-1.11.7.14.5">Configuration Parameters</a></dt><dt id="ientry-idm138604">BASE_BACKUP, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm163541">basic_archive, <a class="indexterm" href="basic-archive.html">basic_archive</a></dt><dt id="ientry-idm163556">basic_archive.archive_directory configuration parameter, <a class="indexterm" href="basic-archive.html#id-1.11.7.15.5">Configuration Parameters</a></dt><dt id="ientry-idm60312">batch mode, <a class="indexterm" href="libpq-pipeline-mode.html">Pipeline Mode</a></dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-pipeline-mode.html">Pipeline Mode</a></dt></dl></dd><dt id="ientry-idm93923">BEGIN, <a class="indexterm" href="sql-begin.html">BEGIN</a></dt><dt id="ientry-idm10757">BETWEEN, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10759">BETWEEN SYMMETRIC, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm87084">BGWORKER_BACKEND_​DATABASE_CONNECTION, <a class="indexterm" href="bgworker.html">Background Worker Processes</a></dt><dt id="ientry-idm87077">BGWORKER_SHMEM_ACCESS, <a class="indexterm" href="bgworker.html">Background Worker Processes</a></dt><dt id="ientry-idm39459">bgwriter_delay configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER">Background Writer</a></dt><dt id="ientry-idm39496">bgwriter_flush_after configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER">Background Writer</a></dt><dt id="ientry-idm39473">bgwriter_lru_maxpages configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER">Background Writer</a></dt><dt id="ientry-idm39483">bgwriter_lru_multiplier configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER">Background Writer</a></dt><dt id="ientry-idm1483">bigint, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC">Numeric Constants</a>, <a class="indexterm" href="datatype-numeric.html#DATATYPE-INT">Integer Types</a></dt><dt id="ientry-idm6460">bigserial, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt><dt id="ientry-idm6732">binary data, <a class="indexterm" href="datatype-binary.html">Binary Data Types</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dd><dl><dt>functions, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt></dl></dd><dt id="ientry-idm13471">binary string</dt><dd><dl><dt>concatenation, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt>converting to character string, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt>length, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt></dl></dd><dt id="ientry-idm35393">bison, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm1441">bit string, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-BIT-STRINGS">Bit-String Constants</a>, <a class="indexterm" href="datatype-bit.html">Bit String Types</a></dt><dd><dl><dt>constant, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-BIT-STRINGS">Bit-String Constants</a></dt><dt>data type, <a class="indexterm" href="datatype-bit.html">Bit String Types</a></dt><dt>length, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt></dl></dd><dt id="ientry-idm14077">bit strings, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dd><dl><dt>functions, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt></dl></dd><dt id="ientry-idm31364">bitmap scan, <a class="indexterm" href="indexes-bitmap-scans.html">Combining Multiple Indexes</a>, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm24632">bit_and, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm13640">bit_count, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm12114">bit_length, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm24654">bit_or, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm24676">bit_xor, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm62400">BLOB (see <a href="#ientry-idm62398">large object</a>)</dt><dt id="ientry-idm44104">block_size configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm163574">bloom, <a class="indexterm" href="bloom.html">bloom</a></dt><dt id="ientry-idm38685">bonjour configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm38695">bonjour_name configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm7853">Boolean, <a class="indexterm" href="datatype-boolean.html">Boolean Type</a></dt><dd><dl><dt>data type, <a class="indexterm" href="datatype-boolean.html">Boolean Type</a></dt><dt>operators (see operators, logical)</dt></dl></dd><dt id="ientry-idm24698">bool_and, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm24708">bool_or, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm37128">booting</dt><dd><dl><dt>starting the server during, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt></dl></dd><dt id="ientry-idm19185">bound_box, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm19142">box, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm8129">box (data type), <a class="indexterm" href="datatype-geometric.html#id-1.5.7.16.8">Boxes</a></dt><dt id="ientry-idm31272">BRIN (see <a href="#ientry-idm31128">index</a>)</dt><dt id="ientry-idm29815">brin_desummarize_range, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-INDEX">Index Maintenance Functions</a></dt><dt id="ientry-idm167796">brin_metapage_info, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.7">BRIN Functions</a></dt><dt id="ientry-idm167816">brin_page_items, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.7">BRIN Functions</a></dt><dt id="ientry-idm167785">brin_page_type, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.7">BRIN Functions</a></dt><dt id="ientry-idm167806">brin_revmap_data, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.7">BRIN Functions</a></dt><dt id="ientry-idm29792">brin_summarize_new_values, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-INDEX">Index Maintenance Functions</a></dt><dt id="ientry-idm29802">brin_summarize_range, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-INDEX">Index Maintenance Functions</a></dt><dt id="ientry-idm19592">broadcast, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm45950">BSD Authentication, <a class="indexterm" href="auth-bsd.html">BSD Authentication</a></dt><dt id="ientry-idm163656">btree_gin, <a class="indexterm" href="btree-gin.html">btree_gin</a></dt><dt id="ientry-idm163703">btree_gist, <a class="indexterm" href="btree-gist.html">btree_gist</a></dt><dt id="ientry-idm12437">btrim, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm163073">bt_index_check, <a class="indexterm" href="amcheck.html#id-1.11.7.11.8">Functions</a></dt><dt id="ientry-idm163092">bt_index_parent_check, <a class="indexterm" href="amcheck.html#id-1.11.7.11.8">Functions</a></dt><dt id="ientry-idm167720">bt_metap, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.6">B-Tree Functions</a></dt><dt id="ientry-idm167738">bt_page_items, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.6">B-Tree Functions</a></dt><dt id="ientry-idm167729">bt_page_stats, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.6">B-Tree Functions</a></dt><dt id="ientry-idm97700">buffering storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a></dt><dt id="ientry-idm6734">bytea, <a class="indexterm" href="datatype-binary.html">Binary Data Types</a></dt><dt id="ientry-idm43417">bytea_output configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt></dl></div><div class="indexdiv" id="indexdiv-C"><h3>C</h3><dl><dt id="ientry-idm57619">C, <a class="indexterm" href="libpq.html">libpq — C Library</a>, <a class="indexterm" href="ecpg.html">ECPG — Embedded SQL in C</a></dt><dt id="ientry-idm74781">C++, <a class="indexterm" href="xfunc-c.html#EXTEND-CPP">Using C++ for Extensibility</a></dt><dt id="ientry-idm94010">CALL, <a class="indexterm" href="sql-call.html">CALL</a></dt><dt id="ientry-idm60569">canceling, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt><dd><dl><dt>SQL command, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt></dl></dd><dt id="ientry-idm23742">cardinality, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm2770">CASCADE, <a class="indexterm" href="ddl-depend.html">Dependency Tracking</a></dt><dd><dl><dt>with DROP, <a class="indexterm" href="ddl-depend.html">Dependency Tracking</a></dt><dt>foreign key action, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-FK">Foreign Keys</a></dt></dl></dd><dt id="ientry-idm50440">Cascading Replication, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm23255">CASE, <a class="indexterm" href="functions-conditional.html">Conditional Expressions</a>, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt></dl></dd><dt id="ientry-idm1227">case sensitivity</dt><dd><dl><dt>of SQL commands, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt></dl></dd><dt id="ientry-idm95851">cast, <a class="indexterm" href="sql-createcast.html">CREATE CAST</a></dt><dd><dl><dt>I/O conversion, <a class="indexterm" href="sql-createcast.html">CREATE CAST</a></dt></dl></dd><dt id="ientry-idm11188">cbrt, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11200">ceil, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11219">ceiling, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm18968">center, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm45904">Certificate, <a class="indexterm" href="auth-cert.html">Certificate Authentication</a></dt><dt id="ientry-idm81235">chained transactions, <a class="indexterm" href="plpgsql-transactions.html#PLPGSQL-TRANSACTION-CHAIN">Transaction Management</a>, <a class="indexterm" href="sql-commit.html#SQL-COMMIT-CHAIN">Parameters</a>, <a class="indexterm" href="sql-rollback.html#SQL-ROLLBACK-CHAIN">Parameters</a></dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-transactions.html#PLPGSQL-TRANSACTION-CHAIN">Transaction Management</a></dt></dl></dd><dt id="ientry-idm6592">char, <a class="indexterm" href="datatype-character.html">Character Types</a></dt><dt id="ientry-idm6586">character, <a class="indexterm" href="datatype-character.html">Character Types</a></dt><dt id="ientry-idm43600">character set, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a>, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a>, <a class="indexterm" href="multibyte.html">Character Set Support</a></dt><dt id="ientry-idm1285">character string, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS">String Constants</a>, <a class="indexterm" href="datatype-character.html">Character Types</a></dt><dd><dl><dt>concatenation, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt>constant, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS">String Constants</a></dt><dt>converting to binary string, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt>data types, <a class="indexterm" href="datatype-character.html">Character Types</a></dt><dt>length, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt>prefix test, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt></dl></dd><dt id="ientry-idm6588">character varying, <a class="indexterm" href="datatype-character.html">Character Types</a></dt><dt id="ientry-idm12140">character_length, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm12127">char_length, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm2605">check constraint, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS">Check Constraints</a></dt><dt id="ientry-idm103571">CHECK OPTION, <a class="indexterm" href="sql-createview.html">CREATE VIEW</a></dt><dt id="ientry-idm56370">checkpoint, <a class="indexterm" href="wal-configuration.html">WAL Configuration</a></dt><dt id="ientry-idm94078">CHECKPOINT, <a class="indexterm" href="sql-checkpoint.html">CHECKPOINT</a></dt><dt id="ientry-idm40046">checkpoint_completion_target configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">Checkpoints</a></dt><dt id="ientry-idm40056">checkpoint_flush_after configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">Checkpoints</a></dt><dt id="ientry-idm40035">checkpoint_timeout configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">Checkpoints</a></dt><dt id="ientry-idm40074">checkpoint_warning configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">Checkpoints</a></dt><dt id="ientry-idm56281">checksums, <a class="indexterm" href="checksums.html">Data Checksums</a></dt><dt id="ientry-idm43130">check_function_bodies configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm12455">chr, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm9895">cid, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm8301">cidr, <a class="indexterm" href="datatype-net-types.html#DATATYPE-CIDR">cidr</a></dt><dt id="ientry-idm8216">circle, <a class="indexterm" href="datatype-geometric.html#DATATYPE-CIRCLE">Circles</a>, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm163777">citext, <a class="indexterm" href="citext.html">citext</a></dt><dt id="ientry-idm38778">client authentication, <a class="indexterm" href="client-authentication.html">Client Authentication</a></dt><dd><dl><dt>timeout during, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt></dl></dd><dt id="ientry-idm38755">client_connection_check_interval configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm43597">client_encoding configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm42967">client_min_messages configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm17167">clock_timestamp, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm94110">CLOSE, <a class="indexterm" href="sql-close.html">CLOSE</a></dt><dt id="ientry-idm622">cluster</dt><dd><dl><dt>of databases (see <a href="#ientry-idm620">database cluster</a>)</dt></dl></dd><dt id="ientry-idm94180">CLUSTER, <a class="indexterm" href="sql-cluster.html">CLUSTER</a></dt><dt id="ientry-idm113305">clusterdb, <a class="indexterm" href="app-clusterdb.html">clusterdb</a></dt><dt id="ientry-idm50017">clustering, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm42588">cluster_name configuration parameter, <a class="indexterm" href="runtime-config-logging.html#id-1.6.7.11.8">Process Title</a></dt><dt id="ientry-idm2885">cmax, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt><dt id="ientry-idm2871">cmin, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt><dt id="ientry-idm23332">COALESCE, <a class="indexterm" href="functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL">COALESCE</a></dt><dt id="ientry-idm2244">COLLATE, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS">Collation Expressions</a></dt><dt id="ientry-idm46845">collation, <a class="indexterm" href="collation.html">Collation Support</a></dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-declarations.html#PLPGSQL-DECLARATION-COLLATION">Collation of PL/pgSQL Variables</a></dt><dt>in SQL functions, <a class="indexterm" href="xfunc-sql.html#id-1.8.3.8.21">SQL Functions with Collations</a></dt></dl></dd><dt id="ientry-idm27565">COLLATION FOR, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm175182">color, <a class="indexterm" href="color.html">Color Support</a></dt><dt id="ientry-idm615">column, <a class="indexterm" href="tutorial-concepts.html">Concepts</a>, <a class="indexterm" href="ddl-basics.html">Table Basics</a></dt><dd><dl><dt>adding, <a class="indexterm" href="ddl-alter.html#DDL-ALTER-ADDING-A-COLUMN">Adding a Column</a></dt><dt>removing, <a class="indexterm" href="ddl-alter.html#DDL-ALTER-REMOVING-A-COLUMN">Removing a Column</a></dt><dt>renaming, <a class="indexterm" href="ddl-alter.html#id-1.5.4.8.11">Renaming a Column</a></dt><dt>system column, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt></dl></dd><dt id="ientry-idm2999">column data type</dt><dd><dl><dt>changing, <a class="indexterm" href="ddl-alter.html#id-1.5.4.8.10">Changing a Column's Data Type</a></dt></dl></dd><dt id="ientry-idm1798">column reference, <a class="indexterm" href="sql-expressions.html#SQL-EXPRESSIONS-COLUMN-REFS">Column References</a></dt><dt id="ientry-idm27955">col_description, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm1599">comment, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-COMMENTS">Comments</a></dt><dd><dl><dt>about database objects, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt>in SQL, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-COMMENTS">Comments</a></dt></dl></dd><dt id="ientry-idm94307">COMMENT, <a class="indexterm" href="sql-comment.html">COMMENT</a></dt><dt id="ientry-idm94543">COMMIT, <a class="indexterm" href="sql-commit.html">COMMIT</a></dt><dt id="ientry-idm94601">COMMIT PREPARED, <a class="indexterm" href="sql-commit-prepared.html">COMMIT PREPARED</a></dt><dt id="ientry-idm40003">commit_delay configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm40022">commit_siblings configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm5567">common table expression (see <a href="#ientry-idm5564">WITH</a>)</dt><dt id="ientry-idm10456">comparison, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a>, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a></dt><dd><dl><dt>composite type, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt>operators, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt>row constructor, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt>subquery result row, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a></dt></dl></dd><dt id="ientry-idm62317">compiling, <a class="indexterm" href="libpq-build.html">Building libpq Programs</a></dt><dd><dl><dt>libpq applications, <a class="indexterm" href="libpq-build.html">Building libpq Programs</a></dt></dl></dd><dt id="ientry-idm2313">composite type, <a class="indexterm" href="rowtypes.html">Composite Types</a>, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a></dt><dd><dl><dt>comparison, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt>constant, <a class="indexterm" href="rowtypes.html#id-1.5.7.24.6">Constructing Composite Values</a></dt><dt>constructor, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">Row Constructors</a></dt></dl></dd><dt id="ientry-idm9579">computed field, <a class="indexterm" href="rowtypes.html#ROWTYPES-USAGE">Using Composite Types in Queries</a></dt><dt id="ientry-idm42727">compute_query_id configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">Statistics Monitoring</a></dt><dt id="ientry-idm12470">concat, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm12485">concat_ws, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm33500">concurrency, <a class="indexterm" href="mvcc.html">Concurrency Control</a></dt><dt id="ientry-idm23257">conditional expression, <a class="indexterm" href="functions-conditional.html">Conditional Expressions</a></dt><dt id="ientry-idm28559">configuration</dt><dd><dl><dt>of recovery</dt><dd><dl><dt>general settings, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY">Recovery</a></dt><dt>of a standby server, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">Archive Recovery</a></dt></dl></dd><dt>of the server, <a class="indexterm" href="runtime-config.html">Server Configuration</a></dt><dt>of the server</dt><dd><dl><dt>functions, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SET">Configuration Settings Functions</a></dt></dl></dd></dl></dd><dt id="ientry-idm35439">configure, <a class="indexterm" href="install-procedure.html#CONFIGURE">Installation Procedure</a></dt><dt id="ientry-idm36147">configure environment variables, <a class="indexterm" href="install-procedure.html#CONFIGURE-ENVVARS">configure Environment Variables</a></dt><dt id="ientry-idm35543">configure options, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS">configure Options</a></dt><dt id="ientry-idm38508">config_file configuration parameter, <a class="indexterm" href="runtime-config-file-locations.html">File Locations</a></dt><dt id="ientry-idm10366">conjunction, <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt id="ientry-idm171856">connectby, <a class="indexterm" href="tablefunc.html#id-1.11.7.52.5">Functions Provided</a>, <a class="indexterm" href="tablefunc.html#id-1.11.7.52.5.8">connectby</a></dt><dt id="ientry-idm61920">connection service file, <a class="indexterm" href="libpq-pgservice.html">The Connection Service File</a></dt><dt id="ientry-idm58080">conninfo, <a class="indexterm" href="libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</a></dt><dt id="ientry-idm1278">constant, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS">Constants</a></dt><dt id="ientry-idm2599">constraint, <a class="indexterm" href="ddl-constraints.html">Constraints</a></dt><dd><dl><dt>adding, <a class="indexterm" href="ddl-alter.html#DDL-ALTER-ADDING-A-CONSTRAINT">Adding a Constraint</a></dt><dt>check, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS">Check Constraints</a></dt><dt>exclusion, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION">Exclusion Constraints</a></dt><dt>foreign key, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-FK">Foreign Keys</a></dt><dt>name, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS">Check Constraints</a></dt><dt>NOT NULL, <a class="indexterm" href="ddl-constraints.html#id-1.5.4.6.6">Not-Null Constraints</a></dt><dt>primary key, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-PRIMARY-KEYS">Primary Keys</a></dt><dt>removing, <a class="indexterm" href="ddl-alter.html#DDL-ALTER-REMOVING-A-CONSTRAINT">Removing a Constraint</a></dt><dt>unique, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS">Unique Constraints</a></dt></dl></dd><dt id="ientry-idm4265">constraint exclusion, <a class="indexterm" href="ddl-partitioning.html#DDL-PARTITIONING-CONSTRAINT-EXCLUSION">Partitioning and Constraint Exclusion</a>, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm41322">constraint_exclusion configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm73129">container type, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a></dt><dt id="ientry-idm80634">CONTINUE</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#id-1.8.8.8.7.6">CONTINUE</a></dt></dl></dd><dt id="ientry-idm49629">continuous archiving, <a class="indexterm" href="backup.html">Backup and Restore</a></dt><dd><dl><dt>in standby, <a class="indexterm" href="warm-standby.html#CONTINUOUS-ARCHIVING-IN-STANDBY">Continuous Archiving in Standby</a></dt></dl></dd><dt id="ientry-idm76084">control file, <a class="indexterm" href="extend-extensions.html#id-1.8.3.20.11">Extension Files</a></dt><dt id="ientry-idm13937">convert, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm13957">convert_from, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm13975">convert_to, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm689">COPY, <a class="indexterm" href="tutorial-populate.html">Populating a Table With Rows</a>, <a class="indexterm" href="libpq-copy.html">Functions Associated with the COPY Command</a>, <a class="indexterm" href="sql-copy.html">COPY</a></dt><dd><dl><dt>with libpq, <a class="indexterm" href="libpq-copy.html">Functions Associated with the COPY Command</a></dt></dl></dd><dt id="ientry-idm24994">corr, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm24992">correlation, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dd><dl><dt>in the query planner, <a class="indexterm" href="planner-stats.html#PLANNER-STATS-EXTENDED">Extended Statistics</a></dt></dl></dd><dt id="ientry-idm11838">cos, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11850">cosd, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11965">cosh, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11862">cot, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11874">cotd, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm24718">count, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25007">covariance</dt><dd><dl><dt>population, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt>sample, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm25010">covar_pop, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25026">covar_samp, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm31520">covering index, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a></dt><dt id="ientry-idm41111">cpu_index_tuple_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm41120">cpu_operator_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm41102">cpu_tuple_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm95230">CREATE ACCESS METHOD, <a class="indexterm" href="sql-create-access-method.html">CREATE ACCESS METHOD</a></dt><dt id="ientry-idm95299">CREATE AGGREGATE, <a class="indexterm" href="sql-createaggregate.html">CREATE AGGREGATE</a></dt><dt id="ientry-idm95700">CREATE CAST, <a class="indexterm" href="sql-createcast.html">CREATE CAST</a></dt><dt id="ientry-idm95897">CREATE COLLATION, <a class="indexterm" href="sql-createcollation.html">CREATE COLLATION</a></dt><dt id="ientry-idm96023">CREATE CONVERSION, <a class="indexterm" href="sql-createconversion.html">CREATE CONVERSION</a></dt><dt id="ientry-idm46414">CREATE DATABASE, <a class="indexterm" href="manage-ag-createdb.html">Creating a Database</a>, <a class="indexterm" href="sql-createdatabase.html">CREATE DATABASE</a></dt><dt id="ientry-idm96345">CREATE DOMAIN, <a class="indexterm" href="sql-createdomain.html">CREATE DOMAIN</a></dt><dt id="ientry-idm96468">CREATE EVENT TRIGGER, <a class="indexterm" href="sql-createeventtrigger.html">CREATE EVENT TRIGGER</a></dt><dt id="ientry-idm96554">CREATE EXTENSION, <a class="indexterm" href="sql-createextension.html">CREATE EXTENSION</a></dt><dt id="ientry-idm96662">CREATE FOREIGN DATA WRAPPER, <a class="indexterm" href="sql-createforeigndatawrapper.html">CREATE FOREIGN DATA WRAPPER</a></dt><dt id="ientry-idm96759">CREATE FOREIGN TABLE, <a class="indexterm" href="sql-createforeigntable.html">CREATE FOREIGN TABLE</a></dt><dt id="ientry-idm96989">CREATE FUNCTION, <a class="indexterm" href="sql-createfunction.html">CREATE FUNCTION</a></dt><dt id="ientry-idm97421">CREATE GROUP, <a class="indexterm" href="sql-creategroup.html">CREATE GROUP</a></dt><dt id="ientry-idm97460">CREATE INDEX, <a class="indexterm" href="sql-createindex.html">CREATE INDEX</a></dt><dt id="ientry-idm97934">CREATE LANGUAGE, <a class="indexterm" href="sql-createlanguage.html">CREATE LANGUAGE</a></dt><dt id="ientry-idm98058">CREATE MATERIALIZED VIEW, <a class="indexterm" href="sql-creatematerializedview.html">CREATE MATERIALIZED VIEW</a></dt><dt id="ientry-idm98171">CREATE OPERATOR, <a class="indexterm" href="sql-createoperator.html">CREATE OPERATOR</a></dt><dt id="ientry-idm98330">CREATE OPERATOR CLASS, <a class="indexterm" href="sql-createopclass.html">CREATE OPERATOR CLASS</a></dt><dt id="ientry-idm98493">CREATE OPERATOR FAMILY, <a class="indexterm" href="sql-createopfamily.html">CREATE OPERATOR FAMILY</a></dt><dt id="ientry-idm98552">CREATE POLICY, <a class="indexterm" href="sql-createpolicy.html">CREATE POLICY</a></dt><dt id="ientry-idm98956">CREATE PROCEDURE, <a class="indexterm" href="sql-createprocedure.html">CREATE PROCEDURE</a></dt><dt id="ientry-idm99162">CREATE PUBLICATION, <a class="indexterm" href="sql-createpublication.html">CREATE PUBLICATION</a></dt><dt id="ientry-idm45997">CREATE ROLE, <a class="indexterm" href="database-roles.html">Database Roles</a>, <a class="indexterm" href="sql-createrole.html">CREATE ROLE</a></dt><dt id="ientry-idm99642">CREATE RULE, <a class="indexterm" href="sql-createrule.html">CREATE RULE</a></dt><dt id="ientry-idm99818">CREATE SCHEMA, <a class="indexterm" href="sql-createschema.html">CREATE SCHEMA</a></dt><dt id="ientry-idm99929">CREATE SEQUENCE, <a class="indexterm" href="sql-createsequence.html">CREATE SEQUENCE</a></dt><dt id="ientry-idm100139">CREATE SERVER, <a class="indexterm" href="sql-createserver.html">CREATE SERVER</a></dt><dt id="ientry-idm100230">CREATE STATISTICS, <a class="indexterm" href="sql-createstatistics.html">CREATE STATISTICS</a></dt><dt id="ientry-idm100331">CREATE SUBSCRIPTION, <a class="indexterm" href="sql-createsubscription.html">CREATE SUBSCRIPTION</a></dt><dt id="ientry-idm630">CREATE TABLE, <a class="indexterm" href="tutorial-table.html">Creating a New Table</a>, <a class="indexterm" href="sql-createtable.html">CREATE TABLE</a></dt><dt id="ientry-idm101805">CREATE TABLE AS, <a class="indexterm" href="sql-createtableas.html">CREATE TABLE AS</a></dt><dt id="ientry-idm46590">CREATE TABLESPACE, <a class="indexterm" href="manage-ag-tablespaces.html">Tablespaces</a>, <a class="indexterm" href="sql-createtablespace.html">CREATE TABLESPACE</a></dt><dt id="ientry-idm102114">CREATE TEXT SEARCH CONFIGURATION, <a class="indexterm" href="sql-createtsconfig.html">CREATE TEXT SEARCH CONFIGURATION</a></dt><dt id="ientry-idm102173">CREATE TEXT SEARCH DICTIONARY, <a class="indexterm" href="sql-createtsdictionary.html">CREATE TEXT SEARCH DICTIONARY</a></dt><dt id="ientry-idm102236">CREATE TEXT SEARCH PARSER, <a class="indexterm" href="sql-createtsparser.html">CREATE TEXT SEARCH PARSER</a></dt><dt id="ientry-idm102309">CREATE TEXT SEARCH TEMPLATE, <a class="indexterm" href="sql-createtstemplate.html">CREATE TEXT SEARCH TEMPLATE</a></dt><dt id="ientry-idm102365">CREATE TRANSFORM, <a class="indexterm" href="sql-createtransform.html">CREATE TRANSFORM</a></dt><dt id="ientry-idm102465">CREATE TRIGGER, <a class="indexterm" href="sql-createtrigger.html">CREATE TRIGGER</a></dt><dt id="ientry-idm102869">CREATE TYPE, <a class="indexterm" href="sql-createtype.html">CREATE TYPE</a></dt><dt id="ientry-idm103344">CREATE USER, <a class="indexterm" href="sql-createuser.html">CREATE USER</a></dt><dt id="ientry-idm103389">CREATE USER MAPPING, <a class="indexterm" href="sql-createusermapping.html">CREATE USER MAPPING</a></dt><dt id="ientry-idm103461">CREATE VIEW, <a class="indexterm" href="sql-createview.html">CREATE VIEW</a></dt><dt id="ientry-idm432">createdb, <a class="indexterm" href="tutorial-createdb.html">Creating a Database</a>, <a class="indexterm" href="manage-ag-createdb.html">Creating a Database</a>, <a class="indexterm" href="app-createdb.html">createdb</a></dt><dt id="ientry-idm46012">createuser, <a class="indexterm" href="database-roles.html">Database Roles</a>, <a class="indexterm" href="app-createuser.html">createuser</a></dt><dt id="ientry-idm138278">CREATE_REPLICATION_SLOT, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm36008">cross compilation, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-BUILD-PROCESS">Build Process Details</a></dt><dt id="ientry-idm4629">cross join, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt id="ientry-idm171894">crosstab, <a class="indexterm" href="tablefunc.html#id-1.11.7.52.5.5">crosstab(text)</a>, <a class="indexterm" href="tablefunc.html#id-1.11.7.52.5.6">crosstabN(text)</a>, <a class="indexterm" href="tablefunc.html#id-1.11.7.52.5.7">crosstab(text, text)</a></dt><dt id="ientry-idm168204">crypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.8.7">crypt()</a></dt><dt id="ientry-idm10168">cstring, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm122454">CSV (Comma-Separated Values) format</dt><dd><dl><dt>in psql, <a class="indexterm" href="app-psql.html#APP-PSQL-META-COMMANDS">Meta-Commands</a></dt></dl></dd><dt id="ientry-idm2892">ctid, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt><dt id="ientry-idm78924">CTID, <a class="indexterm" href="rules-views.html#id-1.8.6.7.6">View Rules in Non-SELECT Statements</a></dt><dt id="ientry-idm5146">CUBE, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a></dt><dt id="ientry-idm163927">cube (extension), <a class="indexterm" href="cube.html">cube</a></dt><dt id="ientry-idm25470">cume_dist, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dd><dl><dt>hypothetical, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm26239">current_catalog, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26244">current_database, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm17179">current_date, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm26381">current_logfiles</dt><dd><dl><dt>and the log_destination configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt>and the pg_current_logfile function, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt></dl></dd><dt id="ientry-idm26254">current_query, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26262">current_role, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26271">current_schema, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26285">current_schemas, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28578">current_setting, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SET">Configuration Settings Functions</a></dt><dt id="ientry-idm17191">current_time, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17214">current_timestamp, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm26301">current_user, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm23204">currval, <a class="indexterm" href="functions-sequence.html">Sequence Manipulation Functions</a></dt><dt id="ientry-idm80969">cursor, <a class="indexterm" href="plpgsql-cursors.html">Cursors</a>, <a class="indexterm" href="sql-close.html">CLOSE</a>, <a class="indexterm" href="sql-declare.html">DECLARE</a>, <a class="indexterm" href="sql-explain.html">EXPLAIN</a>, <a class="indexterm" href="sql-fetch.html">FETCH</a>, <a class="indexterm" href="sql-move.html">MOVE</a></dt><dd><dl><dt>CLOSE, <a class="indexterm" href="sql-close.html">CLOSE</a></dt><dt>DECLARE, <a class="indexterm" href="sql-declare.html">DECLARE</a></dt><dt>FETCH, <a class="indexterm" href="sql-fetch.html">FETCH</a></dt><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-cursors.html">Cursors</a></dt><dt>MOVE, <a class="indexterm" href="sql-move.html">MOVE</a></dt><dt>showing the query plan, <a class="indexterm" href="sql-explain.html">EXPLAIN</a></dt></dl></dd><dt id="ientry-idm41346">cursor_tuple_fraction configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm142610">custom scan provider, <a class="indexterm" href="custom-scan.html">Writing a Custom Scan Provider</a></dt><dd><dl><dt>handler for, <a class="indexterm" href="custom-scan.html">Writing a Custom Scan Provider</a></dt></dl></dd><dt id="ientry-idm36462">Cygwin, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-CYGWIN">Cygwin</a></dt><dd><dl><dt>installation on, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-CYGWIN">Cygwin</a></dt></dl></dd></dl></div><div class="indexdiv" id="indexdiv-D"><h3>D</h3><dl><dt id="ientry-idm36954">data area (see <a href="#ientry-idm620">database cluster</a>)</dt><dt id="ientry-idm50019">data partitioning, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm1501">data type, <a class="indexterm" href="datatype.html">Data Types</a>, <a class="indexterm" href="datatype-numeric.html">Numeric Types</a>, <a class="indexterm" href="datatype-enum.html">Enumerated Types</a>, <a class="indexterm" href="domains.html">Domain Types</a>, <a class="indexterm" href="typeconv.html">Type Conversion</a>, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a>, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a>, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a>, <a class="indexterm" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">Polymorphic Types</a>, <a class="indexterm" href="xfunc-c.html#XFUNC-C-BASETYPE">Base Types in C-Language Functions</a>, <a class="indexterm" href="xtypes.html">User-Defined Types</a></dt><dd><dl><dt>base, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a></dt><dt>category, <a class="indexterm" href="typeconv-overview.html">Overview</a></dt><dt>composite, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a></dt><dt>constant, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC">Constants of Other Types</a></dt><dt>container, <a class="indexterm" href="extend-type-system.html">The PostgreSQL Type System</a></dt><dt>conversion, <a class="indexterm" href="typeconv.html">Type Conversion</a></dt><dt>domain, <a class="indexterm" href="domains.html">Domain Types</a></dt><dt>enumerated (enum), <a class="indexterm" href="datatype-enum.html">Enumerated Types</a></dt><dt>internal organization, <a class="indexterm" href="xfunc-c.html#XFUNC-C-BASETYPE">Base Types in C-Language Functions</a></dt><dt>numeric, <a class="indexterm" href="datatype-numeric.html">Numeric Types</a></dt><dt>polymorphic, <a class="indexterm" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">Polymorphic Types</a></dt><dt>type cast, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS">Type Casts</a></dt><dt>user-defined, <a class="indexterm" href="xtypes.html">User-Defined Types</a></dt></dl></dd><dt id="ientry-idm429">database, <a class="indexterm" href="tutorial-createdb.html">Creating a Database</a>, <a class="indexterm" href="managing-databases.html">Managing Databases</a></dt><dd><dl><dt>creating, <a class="indexterm" href="tutorial-createdb.html">Creating a Database</a></dt><dt>privilege to create, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt></dl></dd><dt id="ientry-idm50939">database activity, <a class="indexterm" href="monitoring.html">Monitoring Database Activity</a></dt><dd><dl><dt>monitoring, <a class="indexterm" href="monitoring.html">Monitoring Database Activity</a></dt></dl></dd><dt id="ientry-idm620">database cluster, <a class="indexterm" href="tutorial-concepts.html">Concepts</a>, <a class="indexterm" href="creating-cluster.html">Creating a Database Cluster</a></dt><dt id="ientry-idm44117">data_checksums configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm38499">data_directory configuration parameter, <a class="indexterm" href="runtime-config-file-locations.html">File Locations</a></dt><dt id="ientry-idm44127">data_directory_mode configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44065">data_sync_retry configuration parameter, <a class="indexterm" href="runtime-config-error-handling.html">Error Handling</a></dt><dt id="ientry-idm6919">date, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.5">Dates</a></dt><dd><dl><dt>constants, <a class="indexterm" href="datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-VALUES">Special Values</a></dt><dt>current, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT">Current Date/Time</a></dt><dt>output format, <a class="indexterm" href="datatype-datetime.html#DATATYPE-DATETIME-OUTPUT">Date/Time Output</a></dt><dd><dl><dt>(see also <a href="#ientry-idm15924">formatting</a>)</dt></dl></dd></dl></dd><dt id="ientry-idm43487">DateStyle configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm18077">date_bin, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-BIN">date_bin</a></dt><dt id="ientry-idm17250">date_part, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a>, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT">EXTRACT, date_part</a></dt><dt id="ientry-idm17278">date_trunc, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a>, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-TRUNC">date_trunc</a></dt><dt id="ientry-idm164352">dblink, <a class="indexterm" href="dblink.html">dblink</a>, <a class="indexterm" href="contrib-dblink-function.html">dblink</a></dt><dt id="ientry-idm165097">dblink_build_sql_delete, <a class="indexterm" href="contrib-dblink-build-sql-delete.html">dblink_build_sql_delete</a></dt><dt id="ientry-idm165036">dblink_build_sql_insert, <a class="indexterm" href="contrib-dblink-build-sql-insert.html">dblink_build_sql_insert</a></dt><dt id="ientry-idm165153">dblink_build_sql_update, <a class="indexterm" href="contrib-dblink-build-sql-update.html">dblink_build_sql_update</a></dt><dt id="ientry-idm164970">dblink_cancel_query, <a class="indexterm" href="contrib-dblink-cancel-query.html">dblink_cancel_query</a></dt><dt id="ientry-idm164709">dblink_close, <a class="indexterm" href="contrib-dblink-close.html">dblink_close</a></dt><dt id="ientry-idm164360">dblink_connect, <a class="indexterm" href="contrib-dblink-connect.html">dblink_connect</a></dt><dt id="ientry-idm164417">dblink_connect_u, <a class="indexterm" href="contrib-dblink-connect-u.html">dblink_connect_u</a></dt><dt id="ientry-idm164444">dblink_disconnect, <a class="indexterm" href="contrib-dblink-disconnect.html">dblink_disconnect</a></dt><dt id="ientry-idm164780">dblink_error_message, <a class="indexterm" href="contrib-dblink-error-message.html">dblink_error_message</a></dt><dt id="ientry-idm164543">dblink_exec, <a class="indexterm" href="contrib-dblink-exec.html">dblink_exec</a></dt><dt id="ientry-idm164657">dblink_fetch, <a class="indexterm" href="contrib-dblink-fetch.html">dblink_fetch</a></dt><dt id="ientry-idm164758">dblink_get_connections, <a class="indexterm" href="contrib-dblink-get-connections.html">dblink_get_connections</a></dt><dt id="ientry-idm164886">dblink_get_notify, <a class="indexterm" href="contrib-dblink-get-notify.html">dblink_get_notify</a></dt><dt id="ientry-idm165001">dblink_get_pkey, <a class="indexterm" href="contrib-dblink-get-pkey.html">dblink_get_pkey</a></dt><dt id="ientry-idm164920">dblink_get_result, <a class="indexterm" href="contrib-dblink-get-result.html">dblink_get_result</a></dt><dt id="ientry-idm164856">dblink_is_busy, <a class="indexterm" href="contrib-dblink-is-busy.html">dblink_is_busy</a></dt><dt id="ientry-idm164594">dblink_open, <a class="indexterm" href="contrib-dblink-open.html">dblink_open</a></dt><dt id="ientry-idm164817">dblink_send_query, <a class="indexterm" href="contrib-dblink-send-query.html">dblink_send_query</a></dt><dt id="ientry-idm38833">db_user_namespace configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt><dt id="ientry-idm34221">deadlock, <a class="indexterm" href="explicit-locking.html#LOCKING-DEADLOCKS">Deadlocks</a></dt><dd><dl><dt>timeout during, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt></dl></dd><dt id="ientry-idm43813">deadlock_timeout configuration parameter, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt><dt id="ientry-idm103760">DEALLOCATE, <a class="indexterm" href="sql-deallocate.html">DEALLOCATE</a></dt><dt id="ientry-idm168482">dearmor, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.16">armor(), dearmor()</a></dt><dt id="ientry-idm44139">debug_assertions configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44559">debug_deadlocks configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44377">debug_discard_caches configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm41989">debug_pretty_print configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41965">debug_print_parse configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41977">debug_print_plan configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41971">debug_print_rewritten configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm6264">decimal (see <a href="#ientry-idm1485">numeric</a>)</dt><dt id="ientry-idm103811">DECLARE, <a class="indexterm" href="sql-declare.html">DECLARE</a></dt><dt id="ientry-idm14015">decode, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm82998">decode_bytea</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm168606">decrypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.10">Raw Encryption Functions</a></dt><dt id="ientry-idm168610">decrypt_iv, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.10">Raw Encryption Functions</a></dt><dt id="ientry-idm97678">deduplicate_items storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a></dt><dt id="ientry-idm2518">default value, <a class="indexterm" href="ddl-default.html">Default Values</a></dt><dd><dl><dt>changing, <a class="indexterm" href="ddl-alter.html#id-1.5.4.8.9">Changing a Column's Default Value</a></dt></dl></dd><dt id="ientry-idm175283">default-roles, <a class="indexterm" href="default-roles.html">Default Roles Renamed to Predefined Roles</a></dt><dt id="ientry-idm41307">default_statistics_target configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm43065">default_tablespace configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43053">default_table_access_method configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43656">default_text_search_config configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm43088">default_toast_compression configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43182">default_transaction_deferrable configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43147">default_transaction_isolation configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43167">default_transaction_read_only configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43179">deferrable transaction, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dd><dl><dt>setting, <a class="indexterm" href="sql-set-transaction.html">SET TRANSACTION</a></dt><dt>setting default, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt></dl></dd><dt id="ientry-idm166144">defined, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm11236">degrees, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm18275">delay, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">Delaying Execution</a></dt><dt id="ientry-idm910">DELETE, <a class="indexterm" href="tutorial-delete.html">Deletions</a>, <a class="indexterm" href="dml-delete.html">Deleting Data</a>, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a>, <a class="indexterm" href="sql-delete.html">DELETE</a></dt><dd><dl><dt>RETURNING, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a></dt></dl></dd><dt id="ientry-idm166159">delete, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm4471">deleting, <a class="indexterm" href="dml-delete.html">Deleting Data</a></dt><dt id="ientry-idm25441">dense_rank, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dd><dl><dt>hypothetical, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm18982">diagonal, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm18995">diameter, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm165217">dict_int, <a class="indexterm" href="dict-int.html">dict_int</a></dt><dt id="ientry-idm165262">dict_xsyn, <a class="indexterm" href="dict-xsyn.html">dict_xsyn</a></dt><dt id="ientry-idm165616">difference, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.6">Soundex</a></dt><dt id="ientry-idm168104">digest, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.7.2">digest()</a></dt><dt id="ientry-idm33539">dirty read, <a class="indexterm" href="transaction-iso.html">Transaction Isolation</a></dt><dt id="ientry-idm104176">DISCARD, <a class="indexterm" href="sql-discard.html">DISCARD</a></dt><dt id="ientry-idm10368">disjunction, <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt id="ientry-idm56545">disk drive, <a class="indexterm" href="wal-internals.html">WAL Internals</a></dt><dt id="ientry-idm48974">disk space, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-SPACE-RECOVERY">Recovering Disk Space</a></dt><dt id="ientry-idm56146">disk usage, <a class="indexterm" href="disk-usage.html">Determining Disk Usage</a></dt><dt id="ientry-idm737">DISTINCT, <a class="indexterm" href="tutorial-select.html">Querying a Table</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a>, <a class="indexterm" href="queries-select-lists.html#QUERIES-DISTINCT">DISTINCT</a></dt><dd><dl><dt>GROUP BY DISTINCT, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a></dt><dt>SELECT DISTINCT, <a class="indexterm" href="queries-select-lists.html#QUERIES-DISTINCT">DISTINCT</a></dt></dl></dd><dt id="ientry-idm11248">div, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm165663">dmetaphone, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.9">Double Metaphone</a></dt><dt id="ientry-idm165665">dmetaphone_alt, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.9">Double Metaphone</a></dt><dt id="ientry-idm104231">DO, <a class="indexterm" href="sql-do.html">DO</a></dt><dt id="ientry-idm31800">document, <a class="indexterm" href="textsearch-intro.html#TEXTSEARCH-DOCUMENT">What Is a Document?</a></dt><dd><dl><dt>text search, <a class="indexterm" href="textsearch-intro.html#TEXTSEARCH-DOCUMENT">What Is a Document?</a></dt></dl></dd><dt id="ientry-idm1419">dollar quoting, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING">Dollar-Quoted String Constants</a></dt><dt id="ientry-idm9845">domain, <a class="indexterm" href="domains.html">Domain Types</a></dt><dt id="ientry-idm6371">double precision, <a class="indexterm" href="datatype-numeric.html#DATATYPE-FLOAT">Floating-Point Types</a></dt><dt id="ientry-idm104295">DROP ACCESS METHOD, <a class="indexterm" href="sql-drop-access-method.html">DROP ACCESS METHOD</a></dt><dt id="ientry-idm104351">DROP AGGREGATE, <a class="indexterm" href="sql-dropaggregate.html">DROP AGGREGATE</a></dt><dt id="ientry-idm104451">DROP CAST, <a class="indexterm" href="sql-dropcast.html">DROP CAST</a></dt><dt id="ientry-idm104510">DROP COLLATION, <a class="indexterm" href="sql-dropcollation.html">DROP COLLATION</a></dt><dt id="ientry-idm104570">DROP CONVERSION, <a class="indexterm" href="sql-dropconversion.html">DROP CONVERSION</a></dt><dt id="ientry-idm46561">DROP DATABASE, <a class="indexterm" href="manage-ag-dropdb.html">Destroying a Database</a>, <a class="indexterm" href="sql-dropdatabase.html">DROP DATABASE</a></dt><dt id="ientry-idm104686">DROP DOMAIN, <a class="indexterm" href="sql-dropdomain.html">DROP DOMAIN</a></dt><dt id="ientry-idm104744">DROP EVENT TRIGGER, <a class="indexterm" href="sql-dropeventtrigger.html">DROP EVENT TRIGGER</a></dt><dt id="ientry-idm104801">DROP EXTENSION, <a class="indexterm" href="sql-dropextension.html">DROP EXTENSION</a></dt><dt id="ientry-idm104867">DROP FOREIGN DATA WRAPPER, <a class="indexterm" href="sql-dropforeigndatawrapper.html">DROP FOREIGN DATA WRAPPER</a></dt><dt id="ientry-idm104926">DROP FOREIGN TABLE, <a class="indexterm" href="sql-dropforeigntable.html">DROP FOREIGN TABLE</a></dt><dt id="ientry-idm104985">DROP FUNCTION, <a class="indexterm" href="sql-dropfunction.html">DROP FUNCTION</a></dt><dt id="ientry-idm105087">DROP GROUP, <a class="indexterm" href="sql-dropgroup.html">DROP GROUP</a></dt><dt id="ientry-idm105115">DROP INDEX, <a class="indexterm" href="sql-dropindex.html">DROP INDEX</a></dt><dt id="ientry-idm105186">DROP LANGUAGE, <a class="indexterm" href="sql-droplanguage.html">DROP LANGUAGE</a></dt><dt id="ientry-idm105251">DROP MATERIALIZED VIEW, <a class="indexterm" href="sql-dropmaterializedview.html">DROP MATERIALIZED VIEW</a></dt><dt id="ientry-idm105311">DROP OPERATOR, <a class="indexterm" href="sql-dropoperator.html">DROP OPERATOR</a></dt><dt id="ientry-idm105388">DROP OPERATOR CLASS, <a class="indexterm" href="sql-dropopclass.html">DROP OPERATOR CLASS</a></dt><dt id="ientry-idm105464">DROP OPERATOR FAMILY, <a class="indexterm" href="sql-dropopfamily.html">DROP OPERATOR FAMILY</a></dt><dt id="ientry-idm105537">DROP OWNED, <a class="indexterm" href="sql-drop-owned.html">DROP OWNED</a></dt><dt id="ientry-idm105599">DROP POLICY, <a class="indexterm" href="sql-droppolicy.html">DROP POLICY</a></dt><dt id="ientry-idm105662">DROP PROCEDURE, <a class="indexterm" href="sql-dropprocedure.html">DROP PROCEDURE</a></dt><dt id="ientry-idm105781">DROP PUBLICATION, <a class="indexterm" href="sql-droppublication.html">DROP PUBLICATION</a></dt><dt id="ientry-idm45999">DROP ROLE, <a class="indexterm" href="database-roles.html">Database Roles</a>, <a class="indexterm" href="sql-droprole.html">DROP ROLE</a></dt><dt id="ientry-idm105897">DROP ROUTINE, <a class="indexterm" href="sql-droproutine.html">DROP ROUTINE</a></dt><dt id="ientry-idm105971">DROP RULE, <a class="indexterm" href="sql-droprule.html">DROP RULE</a></dt><dt id="ientry-idm106035">DROP SCHEMA, <a class="indexterm" href="sql-dropschema.html">DROP SCHEMA</a></dt><dt id="ientry-idm106099">DROP SEQUENCE, <a class="indexterm" href="sql-dropsequence.html">DROP SEQUENCE</a></dt><dt id="ientry-idm106159">DROP SERVER, <a class="indexterm" href="sql-dropserver.html">DROP SERVER</a></dt><dt id="ientry-idm106218">DROP STATISTICS, <a class="indexterm" href="sql-dropstatistics.html">DROP STATISTICS</a></dt><dt id="ientry-idm106270">DROP SUBSCRIPTION, <a class="indexterm" href="sql-dropsubscription.html">DROP SUBSCRIPTION</a></dt><dt id="ientry-idm668">DROP TABLE, <a class="indexterm" href="tutorial-table.html">Creating a New Table</a>, <a class="indexterm" href="sql-droptable.html">DROP TABLE</a></dt><dt id="ientry-idm106400">DROP TABLESPACE, <a class="indexterm" href="sql-droptablespace.html">DROP TABLESPACE</a></dt><dt id="ientry-idm106454">DROP TEXT SEARCH CONFIGURATION, <a class="indexterm" href="sql-droptsconfig.html">DROP TEXT SEARCH CONFIGURATION</a></dt><dt id="ientry-idm106513">DROP TEXT SEARCH DICTIONARY, <a class="indexterm" href="sql-droptsdictionary.html">DROP TEXT SEARCH DICTIONARY</a></dt><dt id="ientry-idm106571">DROP TEXT SEARCH PARSER, <a class="indexterm" href="sql-droptsparser.html">DROP TEXT SEARCH PARSER</a></dt><dt id="ientry-idm106629">DROP TEXT SEARCH TEMPLATE, <a class="indexterm" href="sql-droptstemplate.html">DROP TEXT SEARCH TEMPLATE</a></dt><dt id="ientry-idm106687">DROP TRANSFORM, <a class="indexterm" href="sql-droptransform.html">DROP TRANSFORM</a></dt><dt id="ientry-idm106752">DROP TRIGGER, <a class="indexterm" href="sql-droptrigger.html">DROP TRIGGER</a></dt><dt id="ientry-idm106817">DROP TYPE, <a class="indexterm" href="sql-droptype.html">DROP TYPE</a></dt><dt id="ientry-idm106877">DROP USER, <a class="indexterm" href="sql-dropuser.html">DROP USER</a></dt><dt id="ientry-idm106906">DROP USER MAPPING, <a class="indexterm" href="sql-dropusermapping.html">DROP USER MAPPING</a></dt><dt id="ientry-idm106967">DROP VIEW, <a class="indexterm" href="sql-dropview.html">DROP VIEW</a></dt><dt id="ientry-idm46571">dropdb, <a class="indexterm" href="manage-ag-dropdb.html">Destroying a Database</a>, <a class="indexterm" href="app-dropdb.html">dropdb</a></dt><dt id="ientry-idm46014">dropuser, <a class="indexterm" href="database-roles.html">Database Roles</a>, <a class="indexterm" href="app-dropuser.html">dropuser</a></dt><dt id="ientry-idm138585">DROP_REPLICATION_SLOT, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm8657">DTD, <a class="indexterm" href="datatype-xml.html#id-1.5.7.21.6">Creating XML Values</a></dt><dt id="ientry-idm36127">DTrace, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-DEVEL">Developer Options</a>, <a class="indexterm" href="dynamic-trace.html">Dynamic Tracing</a></dt><dt id="ientry-idm739">duplicate, <a class="indexterm" href="tutorial-select.html">Querying a Table</a></dt><dt id="ientry-idm5314">duplicates, <a class="indexterm" href="queries-select-lists.html#QUERIES-DISTINCT">DISTINCT</a></dt><dt id="ientry-idm43770">dynamic loading, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-OTHER">Other Defaults</a>, <a class="indexterm" href="xfunc-c.html#XFUNC-C-DYNLOAD">Dynamic Loading</a></dt><dt id="ientry-idm73993">dynamic_library_path, <a class="indexterm" href="xfunc-c.html#XFUNC-C-DYNLOAD">Dynamic Loading</a></dt><dt id="ientry-idm43767">dynamic_library_path configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-OTHER">Other Defaults</a></dt><dt id="ientry-idm39323">dynamic_shared_memory_type configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt></dl></div><div class="indexdiv" id="indexdiv-E"><h3>E</h3><dl><dt id="ientry-idm166112">each, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm165365">earth, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm165319">earthdistance, <a class="indexterm" href="earthdistance.html">earthdistance</a></dt><dt id="ientry-idm165429">earth_box, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm165419">earth_distance, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm62804">ECPG, <a class="indexterm" href="ecpg.html">ECPG — Embedded SQL in C</a></dt><dt id="ientry-idm114544">ecpg, <a class="indexterm" href="app-ecpg.html">ecpg</a></dt><dt id="ientry-idm41170">effective_cache_size configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm39536">effective_io_concurrency configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm82386">elog, <a class="indexterm" href="error-message-reporting.html">Reporting Errors Within the Server</a></dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt><dt>in PL/Python, <a class="indexterm" href="plpython-util.html">Utility Functions</a></dt><dt>in PL/Tcl, <a class="indexterm" href="pltcl-dbaccess.html">Database Access from PL/Tcl</a></dt></dl></dd><dt id="ientry-idm62799">embedded SQL, <a class="indexterm" href="ecpg.html">ECPG — Embedded SQL in C</a></dt><dd><dl><dt>in C, <a class="indexterm" href="ecpg.html">ECPG — Embedded SQL in C</a></dt></dl></dd><dt id="ientry-idm69430">enabled role, <a class="indexterm" href="infoschema-enabled-roles.html">enabled_roles</a></dt><dt id="ientry-idm40854">enable_async_append configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40866">enable_bitmapscan configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40876">enable_gathermerge configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40886">enable_hashagg configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40896">enable_hashjoin configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40906">enable_incremental_sort configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40928">enable_indexonlyscan configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40918">enable_indexscan configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40939">enable_material configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40949">enable_memoize configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40959">enable_mergejoin configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40969">enable_nestloop configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40979">enable_parallel_append configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40989">enable_parallel_hash configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm41020">enable_partitionwise_aggregate configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm41010">enable_partitionwise_join configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm40999">enable_partition_pruning configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm41033">enable_seqscan configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm41043">enable_sort configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm41053">enable_tidscan configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm13993">encode, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm83048">encode_array_constructor</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm83020">encode_array_literal</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm83009">encode_bytea</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm83038">encode_typed_literal</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm168604">encrypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.10">Raw Encryption Functions</a></dt><dt id="ientry-idm37938">encryption, <a class="indexterm" href="encryption-options.html">Encryption Options</a>, <a class="indexterm" href="pgcrypto.html">pgcrypto</a></dt><dd><dl><dt>for specific columns, <a class="indexterm" href="pgcrypto.html">pgcrypto</a></dt></dl></dd><dt id="ientry-idm168608">encrypt_iv, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.10">Raw Encryption Functions</a></dt><dt id="ientry-idm107025">END, <a class="indexterm" href="sql-end.html">END</a></dt><dt id="ientry-idm7941">enumerated types, <a class="indexterm" href="datatype-enum.html">Enumerated Types</a></dt><dt id="ientry-idm18312">enum_first, <a class="indexterm" href="functions-enum.html">Enum Support Functions</a></dt><dt id="ientry-idm18324">enum_last, <a class="indexterm" href="functions-enum.html">Enum Support Functions</a></dt><dt id="ientry-idm18336">enum_range, <a class="indexterm" href="functions-enum.html">Enum Support Functions</a></dt><dt id="ientry-idm61617">environment variable, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm85970">ephemeral named relation</dt><dd><dl><dt>registering with SPI, <a class="indexterm" href="spi-spi-register-relation.html">SPI_register_relation</a>, <a class="indexterm" href="spi-spi-register-trigger-data.html">SPI_register_trigger_data</a></dt><dt>unregistering from SPI, <a class="indexterm" href="spi-spi-unregister-relation.html">SPI_unregister_relation</a></dt></dl></dd><dt id="ientry-idm140874">ereport, <a class="indexterm" href="error-message-reporting.html">Reporting Errors Within the Server</a></dt><dt id="ientry-idm59471">error codes, <a class="indexterm" href="errcodes-appendix.html">PostgreSQL Error Codes</a></dt><dd><dl><dt>libpq, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt>list of, <a class="indexterm" href="errcodes-appendix.html">PostgreSQL Error Codes</a></dt></dl></dd><dt id="ientry-idm58918">error message, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm14046">escape format, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm1306">escape string syntax, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE">String Constants with C-Style Escapes</a></dt><dt id="ientry-idm43930">escape_string_warning configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm59867">escaping strings, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt></dl></dd><dt id="ientry-idm38243">event log, <a class="indexterm" href="event-log-registration.html">Registering Event Log on Windows</a></dt><dd><dl><dt>event log, <a class="indexterm" href="event-log-registration.html">Registering Event Log on Windows</a></dt></dl></dd><dt id="ientry-idm77187">event trigger, <a class="indexterm" href="event-triggers.html">Event Triggers</a>, <a class="indexterm" href="event-trigger-interface.html">Writing Event Trigger Functions in C</a></dt><dd><dl><dt>in C, <a class="indexterm" href="event-trigger-interface.html">Writing Event Trigger Functions in C</a></dt><dt>in PL/Tcl, <a class="indexterm" href="pltcl-event-trigger.html">Event Trigger Functions in PL/Tcl</a></dt></dl></dd><dt id="ientry-idm41707">event_source configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm10154">event_trigger, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm24736">every, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm5351">EXCEPT, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a></dt><dt id="ientry-idm80784">exceptions</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING">Trapping Errors</a></dt><dt>in PL/Tcl, <a class="indexterm" href="pltcl-error-handling.html">Error Handling in PL/Tcl</a></dt></dl></dd><dt id="ientry-idm2829">exclusion constraint, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION">Exclusion Constraints</a></dt><dt id="ientry-idm107088">EXECUTE, <a class="indexterm" href="sql-execute.html">EXECUTE</a></dt><dt id="ientry-idm166130">exist, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm25725">EXISTS, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a></dt><dt id="ientry-idm80602">EXIT</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#id-1.8.8.8.7.5">EXIT</a></dt></dl></dd><dt id="ientry-idm44043">exit_on_error configuration parameter, <a class="indexterm" href="runtime-config-error-handling.html">Error Handling</a></dt><dt id="ientry-idm11265">exp, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm34378">EXPLAIN, <a class="indexterm" href="using-explain.html">Using EXPLAIN</a>, <a class="indexterm" href="sql-explain.html">EXPLAIN</a></dt><dt id="ientry-idm1742">expression, <a class="indexterm" href="sql-expressions.html">Value Expressions</a></dt><dd><dl><dt>order of evaluation, <a class="indexterm" href="sql-expressions.html#SYNTAX-EXPRESS-EVAL">Expression Evaluation Rules</a></dt><dt>syntax, <a class="indexterm" href="sql-expressions.html">Value Expressions</a></dt></dl></dd><dt id="ientry-idm73076">extending SQL, <a class="indexterm" href="extend.html">Extending SQL</a></dt><dt id="ientry-idm76035">extension, <a class="indexterm" href="extend-extensions.html">Packaging Related Objects into an Extension</a></dt><dd><dl><dt>externally maintained, <a class="indexterm" href="external-extensions.html">Extensions</a></dt></dl></dd><dt id="ientry-idm38540">external_pid_file configuration parameter, <a class="indexterm" href="runtime-config-file-locations.html">File Locations</a></dt><dt id="ientry-idm17317">extract, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a>, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT">EXTRACT, date_part</a></dt><dt id="ientry-idm43573">extra_float_digits configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt></dl></div><div class="indexdiv" id="indexdiv-F"><h3>F</h3><dl><dt id="ientry-idm11282">factorial, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm50011">failover, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm7858">false, <a class="indexterm" href="datatype-boolean.html">Boolean Type</a></dt><dt id="ientry-idm19604">family, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm60643">fast path, <a class="indexterm" href="libpq-fastpath.html">The Fast-Path Interface</a></dt><dt id="ientry-idm97718">fastupdate storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a></dt><dt id="ientry-idm10160">fdw_handler, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm107351">FETCH, <a class="indexterm" href="sql-fetch.html">FETCH</a></dt><dt id="ientry-idm9581">field</dt><dd><dl><dt>computed, <a class="indexterm" href="rowtypes.html#ROWTYPES-USAGE">Using Composite Types in Queries</a></dt></dl></dd><dt id="ientry-idm1843">field selection, <a class="indexterm" href="sql-expressions.html#FIELD-SELECTION">Field Selection</a></dt><dt id="ientry-idm37053">file system mount points, <a class="indexterm" href="creating-cluster.html#CREATING-CLUSTER-MOUNT-POINTS">Use of Secondary File Systems</a></dt><dt id="ientry-idm165469">file_fdw, <a class="indexterm" href="file-fdw.html">file_fdw</a></dt><dt id="ientry-idm97656">fillfactor storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a>, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm1921">FILTER, <a class="indexterm" href="sql-expressions.html#SYNTAX-AGGREGATES">Aggregate Expressions</a></dt><dt id="ientry-idm25649">first_value, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm35389">flex, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm6373">float4 (see <a href="#ientry-idm6369">real</a>)</dt><dt id="ientry-idm6376">float8 (see <a href="#ientry-idm6371">double precision</a>)</dt><dt id="ientry-idm6379">floating point, <a class="indexterm" href="datatype-numeric.html#DATATYPE-FLOAT">Floating-Point Types</a></dt><dt id="ientry-idm43570">floating-point</dt><dd><dl><dt>display, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt></dl></dd><dt id="ientry-idm11294">floor, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm44396">force_parallel_mode configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm4309">foreign data, <a class="indexterm" href="ddl-foreign-data.html">Foreign Data</a></dt><dt id="ientry-idm141495">foreign data wrapper, <a class="indexterm" href="fdwhandler.html">Writing a Foreign Data Wrapper</a></dt><dd><dl><dt>handler for, <a class="indexterm" href="fdwhandler.html">Writing a Foreign Data Wrapper</a></dt></dl></dd><dt id="ientry-idm947">foreign key, <a class="indexterm" href="tutorial-fk.html">Foreign Keys</a>, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-FK">Foreign Keys</a></dt><dd><dl><dt>self-referential, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-FK">Foreign Keys</a></dt></dl></dd><dt id="ientry-idm4311">foreign table, <a class="indexterm" href="ddl-foreign-data.html">Foreign Data</a></dt><dt id="ientry-idm12502">format, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-string.html#FUNCTIONS-STRING-FORMAT">format</a></dt><dd><dl><dt>use in PL/pgSQL, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN">Executing Dynamic Commands</a></dt></dl></dd><dt id="ientry-idm15924">formatting, <a class="indexterm" href="functions-formatting.html">Data Type Formatting Functions</a></dt><dt id="ientry-idm27170">format_type, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm147622">Free Space Map, <a class="indexterm" href="storage-fsm.html">Free Space Map</a></dt><dt id="ientry-idm37149">FreeBSD</dt><dd><dl><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt>start script, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt></dl></dd><dt id="ientry-idm41356">from_collapse_limit configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm147624">FSM (see <a href="#ientry-idm147622">Free Space Map</a>)</dt><dt id="ientry-idm167639">fsm_page_contents, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.4">General Functions</a></dt><dt id="ientry-idm39711">fsync configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm8515">full text search, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a>, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a>, <a class="indexterm" href="textsearch.html">Full Text Search</a></dt><dd><dl><dt>data types, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a></dt><dt>functions and operators, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a></dt></dl></dd><dt id="ientry-idm39870">full_page_writes configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm1887">function, <a class="indexterm" href="queries-table-expressions.html#QUERIES-TABLEFUNCTIONS">Table Functions</a>, <a class="indexterm" href="functions.html">Functions and Operators</a>, <a class="indexterm" href="functions-statistics.html">Statistics Information Functions</a>, <a class="indexterm" href="typeconv-func.html">Functions</a>, <a class="indexterm" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">Polymorphic Types</a>, <a class="indexterm" href="xfunc.html">User-Defined Functions</a>, <a class="indexterm" href="xfunc-sql.html">Query Language (SQL) Functions</a>, <a class="indexterm" href="xfunc-internal.html">Internal Functions</a>, <a class="indexterm" href="xfunc-c.html">C-Language Functions</a></dt><dd><dl><dt>default values for arguments, <a class="indexterm" href="xfunc-sql.html#XFUNC-SQL-PARAMETER-DEFAULTS">SQL Functions with Default Values for Arguments</a></dt><dt>in the FROM clause, <a class="indexterm" href="queries-table-expressions.html#QUERIES-TABLEFUNCTIONS">Table Functions</a></dt><dt>internal, <a class="indexterm" href="xfunc-internal.html">Internal Functions</a></dt><dt>invocation, <a class="indexterm" href="sql-expressions.html#SQL-EXPRESSIONS-FUNCTION-CALLS">Function Calls</a></dt><dt>mixed notation, <a class="indexterm" href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-MIXED">Using Mixed Notation</a></dt><dt>named argument, <a class="indexterm" href="xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS">Arguments for SQL Functions</a></dt><dt>named notation, <a class="indexterm" href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-NAMED">Using Named Notation</a></dt><dt>output parameter, <a class="indexterm" href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS">SQL Functions with Output Parameters</a></dt><dt>polymorphic, <a class="indexterm" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">Polymorphic Types</a></dt><dt>positional notation, <a class="indexterm" href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-POSITIONAL">Using Positional Notation</a></dt><dt>RETURNS TABLE, <a class="indexterm" href="xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-TABLE">SQL Functions Returning TABLE</a></dt><dt>statistics, <a class="indexterm" href="functions-statistics.html">Statistics Information Functions</a></dt><dt>type resolution in an invocation, <a class="indexterm" href="typeconv-func.html">Functions</a></dt><dt>user-defined, <a class="indexterm" href="xfunc.html">User-Defined Functions</a>, <a class="indexterm" href="xfunc-sql.html">Query Language (SQL) Functions</a>, <a class="indexterm" href="xfunc-c.html">C-Language Functions</a></dt><dd><dl><dt>in C, <a class="indexterm" href="xfunc-c.html">C-Language Functions</a></dt><dt>in SQL, <a class="indexterm" href="xfunc-sql.html">Query Language (SQL) Functions</a></dt></dl></dd><dt>variadic, <a class="indexterm" href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS">SQL Functions with Variable Numbers of Arguments</a></dt><dt>with SETOF, <a class="indexterm" href="xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-SET">SQL Functions Returning Sets</a></dt></dl></dd><dt id="ientry-idm5103">functional dependency, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUP">The GROUP BY and HAVING Clauses</a></dt><dt id="ientry-idm165596">fuzzystrmatch, <a class="indexterm" href="fuzzystrmatch.html">fuzzystrmatch</a></dt></dl></div><div class="indexdiv" id="indexdiv-G"><h3>G</h3><dl><dt id="ientry-idm11313">gcd, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm165382">gc_to_sec, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm2546">generated column, <a class="indexterm" href="ddl-generated-columns.html">Generated Columns</a>, <a class="indexterm" href="sql-createforeigntable.html#id-1.9.3.66.6">Parameters</a>, <a class="indexterm" href="sql-createtable.html#id-1.9.3.85.6">Parameters</a></dt><dd><dl><dt>in
+ triggers, <a class="indexterm" href="trigger-definition.html">Overview of Trigger Behavior</a></dt></dl></dd><dt id="ientry-idm26103">generate_series, <a class="indexterm" href="functions-srf.html">Set Returning Functions</a></dt><dt id="ientry-idm26185">generate_subscripts, <a class="indexterm" href="functions-srf.html">Set Returning Functions</a></dt><dt id="ientry-idm41228">genetic query optimization, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm168656">gen_random_bytes, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.11">Random-Data Functions</a></dt><dt id="ientry-idm20691">gen_random_uuid, <a class="indexterm" href="functions-uuid.html">UUID Functions</a>, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.11">Random-Data Functions</a></dt><dt id="ientry-idm168220">gen_salt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.8.8">gen_salt()</a></dt><dt id="ientry-idm41230">GEQO (see <a href="#ientry-idm41228">genetic query optimization</a>)</dt><dt id="ientry-idm41233">geqo configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm41255">geqo_effort configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm41276">geqo_generations configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm41266">geqo_pool_size configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm41295">geqo_seed configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm41286">geqo_selection_bias configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm41243">geqo_threshold configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">Genetic Query Optimizer</a></dt><dt id="ientry-idm13674">get_bit, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm13690">get_byte, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm19988">get_current_ts_config, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm167586">get_raw_page, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.4">General Functions</a></dt><dt id="ientry-idm31255">GIN (see <a href="#ientry-idm31128">index</a>)</dt><dt id="ientry-idm29827">gin_clean_pending_list, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-INDEX">Index Maintenance Functions</a></dt><dt id="ientry-idm43794">gin_fuzzy_search_limit configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-OTHER">Other Defaults</a></dt><dt id="ientry-idm167852">gin_leafpage_items, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.8">GIN Functions</a></dt><dt id="ientry-idm167832">gin_metapage_info, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.8">GIN Functions</a></dt><dt id="ientry-idm167842">gin_page_opaque_info, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.8">GIN Functions</a></dt><dt id="ientry-idm43470">gin_pending_list_limit</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a></dt></dl></dd><dt id="ientry-idm31216">GiST (see <a href="#ientry-idm31128">index</a>)</dt><dt id="ientry-idm167875">gist_page_items, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.9">GiST Functions</a></dt><dt id="ientry-idm167885">gist_page_items_bytea, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.9">GiST Functions</a></dt><dt id="ientry-idm167865">gist_page_opaque_info, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.9">GiST Functions</a></dt><dt id="ientry-idm82231">global data, <a class="indexterm" href="pltcl-global.html">Global Data in PL/Tcl</a></dt><dd><dl><dt>in PL/Python, <a class="indexterm" href="plpython-sharing.html">Sharing Data</a></dt><dt>in PL/Tcl, <a class="indexterm" href="pltcl-global.html">Global Data in PL/Tcl</a></dt></dl></dd><dt id="ientry-idm3030">GRANT, <a class="indexterm" href="ddl-priv.html">Privileges</a>, <a class="indexterm" href="sql-grant.html">GRANT</a></dt><dt id="ientry-idm23393">GREATEST, <a class="indexterm" href="functions-conditional.html#FUNCTIONS-GREATEST-LEAST">GREATEST and LEAST</a>, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt></dl></dd><dt id="ientry-idm150575">Gregorian calendar, <a class="indexterm" href="datetime-units-history.html">History of Units</a></dt><dt id="ientry-idm853">GROUP BY, <a class="indexterm" href="tutorial-agg.html">Aggregate Functions</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUP">The GROUP BY and HAVING Clauses</a></dt><dt id="ientry-idm5060">grouping, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUP">The GROUP BY and HAVING Clauses</a></dt><dt id="ientry-idm25494">GROUPING, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm5144">GROUPING SETS, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a></dt><dt id="ientry-idm38177">gssapi, <a class="indexterm" href="gssapi-enc.html">Secure TCP/IP Connections with GSSAPI Encryption</a></dt><dt id="ientry-idm45482">GSSAPI, <a class="indexterm" href="gssapi-auth.html">GSSAPI Authentication</a></dt><dd><dl><dt>with
+ libpq, <a class="indexterm" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">Parameter Key Words</a></dt></dl></dd><dt id="ientry-idm8613">GUID, <a class="indexterm" href="datatype-uuid.html">UUID Type</a></dt></dl></div><div class="indexdiv" id="indexdiv-H"><h3>H</h3><dl><dt id="ientry-idm31206">hash (see <a href="#ientry-idm31128">index</a>)</dt><dt id="ientry-idm167928">hash_bitmap_info, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.10">Hash Functions</a></dt><dt id="ientry-idm39228">hash_mem_multiplier configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm167938">hash_metapage_info, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.10">Hash Functions</a></dt><dt id="ientry-idm167918">hash_page_items, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.10">Hash Functions</a></dt><dt id="ientry-idm167908">hash_page_stats, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.10">Hash Functions</a></dt><dt id="ientry-idm167898">hash_page_type, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.10">Hash Functions</a></dt><dt id="ientry-idm26563">has_any_column_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26584">has_column_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26610">has_database_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26632">has_foreign_data_wrapper_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26650">has_function_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26672">has_language_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26690">has_parameter_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26708">has_schema_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26727">has_sequence_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26747">has_server_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26789">has_tablespace_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26765">has_table_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26807">has_type_privilege, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm855">HAVING, <a class="indexterm" href="tutorial-agg.html">Aggregate Functions</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUP">The GROUP BY and HAVING Clauses</a></dt><dt id="ientry-idm38519">hba_file configuration parameter, <a class="indexterm" href="runtime-config-file-locations.html">File Locations</a></dt><dt id="ientry-idm167655">heap_page_items, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.5">Heap Functions</a></dt><dt id="ientry-idm167686">heap_page_item_attrs, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.5">Heap Functions</a></dt><dt id="ientry-idm167700">heap_tuple_infomask_flags, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.5">Heap Functions</a></dt><dt id="ientry-idm19007">height, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm14056">hex format, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm599">hierarchical database, <a class="indexterm" href="tutorial-concepts.html">Concepts</a></dt><dt id="ientry-idm50009">high availability, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm100">history, <a class="indexterm" href="history.html">A Brief History of PostgreSQL</a></dt><dd><dl><dt>of PostgreSQL, <a class="indexterm" href="history.html">A Brief History of PostgreSQL</a></dt></dl></dd><dt id="ientry-idm168123">hmac, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.7.3">hmac()</a></dt><dt id="ientry-idm19618">host, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm58184">host
+ name, <a class="indexterm" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">Parameter Key Words</a></dt><dt id="ientry-idm19630">hostmask, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm50600">hot standby, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm40682">hot_standby configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40746">hot_standby_feedback configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm37474">HP-UX</dt><dd><dl><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt></dl></dd><dt id="ientry-idm165673">hstore, <a class="indexterm" href="hstore.html">hstore</a>, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm166010">hstore_to_array, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm166036">hstore_to_json, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm166053">hstore_to_jsonb, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm166084">hstore_to_jsonb_loose, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm166070">hstore_to_json_loose, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm166023">hstore_to_matrix, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm39120">huge_pages configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm39156">huge_page_size configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm25399">hypothetical-set aggregate</dt><dd><dl><dt>built-in, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd></dl></div><div class="indexdiv" id="indexdiv-I"><h3>I</h3><dl><dt id="ientry-idm166376">icount, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm35733">ICU, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a>, <a class="indexterm" href="locale.html#id-1.6.11.3.7">Locale Providers</a>, <a class="indexterm" href="collation.html#COLLATION-MANAGING">Managing Collations</a>, <a class="indexterm" href="sql-createcollation.html#id-1.9.3.59.6">Parameters</a>, <a class="indexterm" href="sql-createdatabase.html#id-1.9.3.61.6">Parameters</a></dt><dt id="ientry-idm45640">ident, <a class="indexterm" href="auth-ident.html">Ident Authentication</a></dt><dt id="ientry-idm1192">identifier, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt><dd><dl><dt>length, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt><dt>syntax of, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt></dl></dd><dt id="ientry-idm138200">IDENTIFY_SYSTEM, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm38529">ident_file configuration parameter, <a class="indexterm" href="runtime-config-file-locations.html">File Locations</a></dt><dt id="ientry-idm43298">idle_in_transaction_session_timeout configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43309">idle_session_timeout configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm166449">idx, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm23336">IFNULL, <a class="indexterm" href="functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL">COALESCE</a></dt><dt id="ientry-idm44616">ignore_checksum_failure configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44646">ignore_invalid_pages configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44422">ignore_system_indexes configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm73860">IMMUTABLE, <a class="indexterm" href="xfunc-volatility.html">Function Volatility Categories</a></dt><dt id="ientry-idm107839">IMPORT FOREIGN SCHEMA, <a class="indexterm" href="sql-importforeignschema.html">IMPORT FOREIGN SCHEMA</a></dt><dt id="ientry-idm25727">IN, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm31550">INCLUDE</dt><dd><dl><dt>in index definitions, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a></dt></dl></dd><dt id="ientry-idm38445">include</dt><dd><dl><dt>in configuration file, <a class="indexterm" href="config-setting.html#CONFIG-INCLUDES">Managing Configuration File Contents</a></dt></dl></dd><dt id="ientry-idm38462">include_dir</dt><dd><dl><dt>in configuration file, <a class="indexterm" href="config-setting.html#CONFIG-INCLUDES">Managing Configuration File Contents</a></dt></dl></dd><dt id="ientry-idm38453">include_if_exists</dt><dd><dl><dt>in configuration file, <a class="indexterm" href="config-setting.html#CONFIG-INCLUDES">Managing Configuration File Contents</a></dt></dl></dd><dt id="ientry-idm31128">index, <a class="indexterm" href="indexes.html">Indexes</a>, <a class="indexterm" href="indexes-multicolumn.html">Multicolumn Indexes</a>, <a class="indexterm" href="indexes-ordering.html">Indexes and ORDER BY</a>, <a class="indexterm" href="indexes-bitmap-scans.html">Combining Multiple Indexes</a>, <a class="indexterm" href="indexes-unique.html">Unique Indexes</a>, <a class="indexterm" href="indexes-expressional.html">Indexes on Expressions</a>, <a class="indexterm" href="indexes-partial.html">Partial Indexes</a>, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a>, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a>, <a class="indexterm" href="indexes-examine.html">Examining Index Usage</a>, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a>, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a>, <a class="indexterm" href="locking-indexes.html">Locking and Indexes</a>, <a class="indexterm" href="xindex.html">Interfacing Extensions to Indexes</a>, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY">Building Indexes Concurrently</a>, <a class="indexterm" href="sql-reindex.html#SQL-REINDEX-CONCURRENTLY">Rebuilding Indexes Concurrently</a>, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dd><dl><dt>and ORDER BY, <a class="indexterm" href="indexes-ordering.html">Indexes and ORDER BY</a></dt><dt>B-Tree, <a class="indexterm" href="indexes-types.html#INDEXES-TYPES-BTREE">B-Tree</a>, <a class="indexterm" href="btree.html">B-Tree Indexes</a></dt><dt>BRIN, <a class="indexterm" href="indexes-types.html#INDEXES-TYPES-BRIN">BRIN</a>, <a class="indexterm" href="brin.html">BRIN Indexes</a></dt><dt>building concurrently, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY">Building Indexes Concurrently</a></dt><dt>combining multiple indexes, <a class="indexterm" href="indexes-bitmap-scans.html">Combining Multiple Indexes</a></dt><dt>covering, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a></dt><dt>examining usage, <a class="indexterm" href="indexes-examine.html">Examining Index Usage</a></dt><dt>on expressions, <a class="indexterm" href="indexes-expressional.html">Indexes on Expressions</a></dt><dt>for user-defined data type, <a class="indexterm" href="xindex.html">Interfacing Extensions to Indexes</a></dt><dt>GIN, <a class="indexterm" href="indexes-types.html#INDEXES-TYPES-GIN">GIN</a>, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a>, <a class="indexterm" href="gin.html">GIN Indexes</a></dt><dd><dl><dt>text search, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a></dt></dl></dd><dt>GiST, <a class="indexterm" href="indexes-types.html#INDEXES-TYPE-GIST">GiST</a>, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a>, <a class="indexterm" href="gist.html">GiST Indexes</a></dt><dd><dl><dt>text search, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a></dt></dl></dd><dt>hash, <a class="indexterm" href="indexes-types.html#INDEXES-TYPES-HASH">Hash</a></dt><dt>Hash, <a class="indexterm" href="hash-index.html">Hash Indexes</a></dt><dt>index-only scans, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a></dt><dt>locks, <a class="indexterm" href="locking-indexes.html">Locking and Indexes</a></dt><dt>multicolumn, <a class="indexterm" href="indexes-multicolumn.html">Multicolumn Indexes</a></dt><dt>partial, <a class="indexterm" href="indexes-partial.html">Partial Indexes</a></dt><dt>rebuilding concurrently, <a class="indexterm" href="sql-reindex.html#SQL-REINDEX-CONCURRENTLY">Rebuilding Indexes Concurrently</a></dt><dt>SP-GiST, <a class="indexterm" href="indexes-types.html#INDEXES-TYPE-SPGIST">SP-GiST</a>, <a class="indexterm" href="spgist.html">SP-GiST Indexes</a></dt><dt>unique, <a class="indexterm" href="indexes-unique.html">Unique Indexes</a></dt></dl></dd><dt id="ientry-idm142929">Index Access Method, <a class="indexterm" href="indexam.html">Index Access Method Interface Definition</a></dt><dt id="ientry-idm40916">index scan, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm31515">index-only scan, <a class="indexterm" href="indexes-index-only-scans.html">Index-Only Scans and Covering Indexes</a></dt><dt id="ientry-idm142931">indexam</dt><dd><dl><dt>Index Access Method, <a class="indexterm" href="indexam.html">Index Access Method Interface Definition</a></dt></dl></dd><dt id="ientry-idm10164">index_am_handler, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm8285">inet (data type), <a class="indexterm" href="datatype-net-types.html#DATATYPE-INET">inet</a></dt><dt id="ientry-idm26312">inet_client_addr, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26321">inet_client_port, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm19642">inet_merge, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm19655">inet_same_family, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm26330">inet_server_addr, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm26339">inet_server_port, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm6312">infinity</dt><dd><dl><dt>floating point, <a class="indexterm" href="datatype-numeric.html#DATATYPE-FLOAT">Floating-Point Types</a></dt><dt>numeric (data type), <a class="indexterm" href="datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL">Arbitrary Precision Numbers</a></dt></dl></dd><dt id="ientry-idm67454">information schema, <a class="indexterm" href="information-schema.html">The Information Schema</a></dt><dt id="ientry-idm1091">inheritance, <a class="indexterm" href="tutorial-inheritance.html">Inheritance</a>, <a class="indexterm" href="ddl-inherit.html">Inheritance</a></dt><dt id="ientry-idm12519">initcap, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm36971">initdb, <a class="indexterm" href="creating-cluster.html">Creating a Database Cluster</a>, <a class="indexterm" href="app-initdb.html">initdb</a></dt><dt id="ientry-idm147660">Initialization Fork, <a class="indexterm" href="storage-init.html">The Initialization Fork</a></dt><dt id="ientry-idm75072">input function, <a class="indexterm" href="xtypes.html">User-Defined Types</a></dt><dt id="ientry-idm674">INSERT, <a class="indexterm" href="tutorial-populate.html">Populating a Table With Rows</a>, <a class="indexterm" href="dml-insert.html">Inserting Data</a>, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a>, <a class="indexterm" href="sql-insert.html">INSERT</a></dt><dd><dl><dt>RETURNING, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a></dt></dl></dd><dt id="ientry-idm4408">inserting, <a class="indexterm" href="dml-insert.html">Inserting Data</a></dt><dt id="ientry-idm35211">installation, <a class="indexterm" href="installation.html">Installation from Source Code</a></dt><dd><dl><dt>binaries, <a class="indexterm" href="install-binaries.html">Installation from Binaries</a></dt><dt>on Windows, <a class="indexterm" href="install-windows.html">Installation from Source Code on Windows</a></dt></dl></dd><dt id="ientry-idm82145">instr function, <a class="indexterm" href="plpgsql-porting.html#PLPGSQL-PORTING-APPENDIX">Appendix</a></dt><dt id="ientry-idm6233">int2 (see <a href="#ientry-idm6226">smallint</a>)</dt><dt id="ientry-idm6230">int4 (see <a href="#ientry-idm1481">integer</a>)</dt><dt id="ientry-idm6236">int8 (see <a href="#ientry-idm1483">bigint</a>)</dt><dt id="ientry-idm166304">intagg, <a class="indexterm" href="intagg.html">intagg</a></dt><dt id="ientry-idm166346">intarray, <a class="indexterm" href="intarray.html">intarray</a></dt><dt id="ientry-idm1481">integer, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC">Numeric Constants</a>, <a class="indexterm" href="datatype-numeric.html#DATATYPE-INT">Integer Types</a></dt><dt id="ientry-idm44154">integer_datetimes configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm173080">interfaces</dt><dd><dl><dt>externally maintained, <a class="indexterm" href="external-interfaces.html">Client Interfaces</a></dt></dl></dd><dt id="ientry-idm10170">internal, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm5349">INTERSECT, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a></dt><dt id="ientry-idm6935">interval, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#DATATYPE-INTERVAL-INPUT">Interval Input</a></dt><dd><dl><dt>output format, <a class="indexterm" href="datatype-datetime.html#DATATYPE-INTERVAL-OUTPUT">Interval Output</a></dt><dd><dl><dt>(see also <a href="#ientry-idm15924">formatting</a>)</dt></dl></dd></dl></dd><dt id="ientry-idm43514">IntervalStyle configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm166495">intset, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm166311">int_array_aggregate, <a class="indexterm" href="intagg.html#id-1.11.7.28.4">Functions</a></dt><dt id="ientry-idm166318">int_array_enum, <a class="indexterm" href="intagg.html#id-1.11.7.28.4">Functions</a></dt><dt id="ientry-idm25295">inverse distribution, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm44166">in_hot_standby configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm143756">in_range support functions, <a class="indexterm" href="btree-support-funcs.html">B-Tree Support Functions</a></dt><dt id="ientry-idm10785">IS DISTINCT FROM, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm20897">IS DOCUMENT, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.6.3">IS DOCUMENT</a></dt><dt id="ientry-idm10853">IS FALSE, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10787">IS NOT DISTINCT FROM, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm20909">IS NOT DOCUMENT, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.6.4">IS NOT DOCUMENT</a></dt><dt id="ientry-idm10855">IS NOT FALSE, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10807">IS NOT NULL, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10851">IS NOT TRUE, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10859">IS NOT UNKNOWN, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10805">IS NULL, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a>, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-CLIENTS">Platform and Client Compatibility</a></dt><dt id="ientry-idm10849">IS TRUE, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10857">IS UNKNOWN, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm19019">isclosed, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm24338">isempty, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm17345">isfinite, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm166685">isn, <a class="indexterm" href="isn.html">isn</a></dt><dt id="ientry-idm10809">ISNULL, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm166812">isn_weak, <a class="indexterm" href="isn.html#id-1.11.7.30.7">Functions and Operators</a></dt><dt id="ientry-idm19031">isopen, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm83073">is_array_ref</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm166836">is_valid, <a class="indexterm" href="isn.html#id-1.11.7.30.7">Functions and Operators</a></dt></dl></div><div class="indexdiv" id="indexdiv-J"><h3>J</h3><dl><dt id="ientry-idm57110">JIT, <a class="indexterm" href="jit.html">Just-in-Time Compilation (JIT)</a></dt><dt id="ientry-idm41370">jit configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm41185">jit_above_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm44660">jit_debugging_support configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44671">jit_dump_bitcode configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44684">jit_expressions configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm41198">jit_inline_above_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm41210">jit_optimize_above_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm44695">jit_profiling_support configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm43750">jit_provider configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">Shared Library Preloading</a></dt><dt id="ientry-idm44707">jit_tuple_deforming configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm755">join, <a class="indexterm" href="tutorial-join.html">Joins Between Tables</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a>, <a class="indexterm" href="explicit-joins.html">Controlling the Planner with Explicit JOIN Clauses</a></dt><dd><dl><dt>controlling the order, <a class="indexterm" href="explicit-joins.html">Controlling the Planner with Explicit JOIN Clauses</a></dt><dt>cross, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt>left, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt>natural, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt>outer, <a class="indexterm" href="tutorial-join.html">Joins Between Tables</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt>right, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt>self, <a class="indexterm" href="tutorial-join.html">Joins Between Tables</a></dt></dl></dd><dt id="ientry-idm41383">join_collapse_limit configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm8708">JSON, <a class="indexterm" href="datatype-json.html">JSON Types</a>, <a class="indexterm" href="functions-json.html">JSON Functions and Operators</a></dt><dd><dl><dt>functions and operators, <a class="indexterm" href="functions-json.html">JSON Functions and Operators</a></dt></dl></dd><dt id="ientry-idm8710">JSONB, <a class="indexterm" href="datatype-json.html">JSON Types</a></dt><dt id="ientry-idm8841">jsonb</dt><dd><dl><dt>containment, <a class="indexterm" href="datatype-json.html#JSON-CONTAINMENT">jsonb Containment and Existence</a></dt><dt>existence, <a class="indexterm" href="datatype-json.html#JSON-CONTAINMENT">jsonb Containment and Existence</a></dt><dt>indexes on, <a class="indexterm" href="datatype-json.html#JSON-INDEXING">jsonb Indexing</a></dt></dl></dd><dt id="ientry-idm24753">jsonb_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm21856">jsonb_array_elements, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21875">jsonb_array_elements_text, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21895">jsonb_array_length, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21757">jsonb_build_array, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21779">jsonb_build_object, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21920">jsonb_each, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21947">jsonb_each_text, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21976">jsonb_extract_path, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22003">jsonb_extract_path_text, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22239">jsonb_insert, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21800">jsonb_object, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm24774">jsonb_object_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm22027">jsonb_object_keys, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22290">jsonb_path_exists, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22416">jsonb_path_exists_tz, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22317">jsonb_path_match, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22431">jsonb_path_match_tz, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22342">jsonb_path_query, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22367">jsonb_path_query_array, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22461">jsonb_path_query_array_tz, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22391">jsonb_path_query_first, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22476">jsonb_path_query_first_tz, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22446">jsonb_path_query_tz, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22049">jsonb_populate_record, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22104">jsonb_populate_recordset, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22500">jsonb_pretty, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22172">jsonb_set, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22204">jsonb_set_lax, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22278">jsonb_strip_nulls, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22130">jsonb_to_record, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22155">jsonb_to_recordset, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm20223">jsonb_to_tsvector, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm22519">jsonb_typeof, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm9047">jsonpath, <a class="indexterm" href="datatype-json.html#DATATYPE-JSONPATH">jsonpath Type</a></dt><dt id="ientry-idm24747">json_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm21850">json_array_elements, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21869">json_array_elements_text, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21889">json_array_length, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21750">json_build_array, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21772">json_build_object, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21910">json_each, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21937">json_each_text, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21966">json_extract_path, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21993">json_extract_path_text, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21794">json_object, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm24765">json_object_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm22021">json_object_keys, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22040">json_populate_record, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22095">json_populate_recordset, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22272">json_strip_nulls, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22124">json_to_record, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm22149">json_to_recordset, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm20211">json_to_tsvector, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm22513">json_typeof, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm150598">Julian date, <a class="indexterm" href="datetime-julian-dates.html">Julian Dates</a></dt><dt id="ientry-idm57113">Just-In-Time compilation (see <a href="#ientry-idm57110">JIT</a>)</dt><dt id="ientry-idm17377">justify_days, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17389">justify_hours, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17401">justify_interval, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt></dl></div><div class="indexdiv" id="indexdiv-K"><h3>K</h3><dl><dt id="ientry-idm1198">key word, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a>, <a class="indexterm" href="sql-keywords-appendix.html">SQL Key Words</a></dt><dd><dl><dt>list of, <a class="indexterm" href="sql-keywords-appendix.html">SQL Key Words</a></dt><dt>syntax of, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt></dl></dd><dt id="ientry-idm38822">krb_caseins_users configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt><dt id="ientry-idm38808">krb_server_keyfile configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt></dl></div><div class="indexdiv" id="indexdiv-L"><h3>L</h3><dl><dt id="ientry-idm4813">label (see <a href="#ientry-idm810">alias</a>)</dt><dt id="ientry-idm25599">lag, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm10158">language_handler, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm62398">large object, <a class="indexterm" href="largeobjects.html">Large Objects</a></dt><dt id="ientry-idm23219">lastval, <a class="indexterm" href="functions-sequence.html">Sequence Manipulation Functions</a></dt><dt id="ientry-idm25660">last_value, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm4973">LATERAL, <a class="indexterm" href="queries-table-expressions.html#QUERIES-LATERAL">LATERAL Subqueries</a></dt><dd><dl><dt>in the FROM clause, <a class="indexterm" href="queries-table-expressions.html#QUERIES-LATERAL">LATERAL Subqueries</a></dt></dl></dd><dt id="ientry-idm165401">latitude, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm167450">lca, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dt id="ientry-idm11331">lcm, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm44177">lc_collate configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44187">lc_ctype configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm43610">lc_messages configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm43623">lc_monetary configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm43634">lc_numeric configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm43645">lc_time configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm35827">LDAP, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a>, <a class="indexterm" href="auth-ldap.html">LDAP Authentication</a></dt><dt id="ientry-idm61951">LDAP connection parameter lookup, <a class="indexterm" href="libpq-ldap.html">LDAP Lookup of Connection Parameters</a></dt><dt id="ientry-idm36355">ldconfig, <a class="indexterm" href="install-post.html#INSTALL-POST-SHLIBS">Shared Libraries</a></dt><dt id="ientry-idm25624">lead, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm23395">LEAST, <a class="indexterm" href="functions-conditional.html#FUNCTIONS-GREATEST-LEAST">GREATEST and LEAST</a>, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt></dl></dd><dt id="ientry-idm12531">left, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm4714">left join, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt id="ientry-idm12132">length, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a>, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a>, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dd><dl><dt>of a binary string (see binary strings, length)</dt><dt>of a character string (see <a href="#ientry-idm1285">character string, length</a>)</dt></dl></dd><dt id="ientry-idm32413">length(tsvector), <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR">Manipulating Documents</a></dt><dt id="ientry-idm165628">levenshtein, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.7">Levenshtein</a></dt><dt id="ientry-idm165630">levenshtein_less_equal, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.7">Levenshtein</a></dt><dt id="ientry-idm35391">lex, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm35277">libedit, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dd><dl><dt>in psql, <a class="indexterm" href="app-psql.html#APP-PSQL-READLINE">Command-Line Editing</a></dt></dl></dd><dt id="ientry-idm35311">libperl, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm57617">libpq, <a class="indexterm" href="libpq.html">libpq — C Library</a>, <a class="indexterm" href="libpq-pipeline-mode.html">Pipeline Mode</a>, <a class="indexterm" href="libpq-single-row-mode.html">Retrieving Query Results Row-by-Row</a></dt><dd><dl><dt>pipeline mode, <a class="indexterm" href="libpq-pipeline-mode.html">Pipeline Mode</a></dt><dt>single-row mode, <a class="indexterm" href="libpq-single-row-mode.html">Retrieving Query Results Row-by-Row</a></dt></dl></dd><dt id="ientry-idm57644">libpq-fe.h, <a class="indexterm" href="libpq.html">libpq — C Library</a>, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58691">libpq-int.h, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm35334">libpython, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm74023">library initialization function, <a class="indexterm" href="xfunc-c.html#XFUNC-C-DYNLOAD">Dynamic Loading</a></dt><dt id="ientry-idm14381">LIKE, <a class="indexterm" href="functions-matching.html#FUNCTIONS-LIKE">LIKE</a></dt><dd><dl><dt>and locales, <a class="indexterm" href="locale.html#id-1.6.11.3.5">Behavior</a></dt></dl></dd><dt id="ientry-idm15764">LIKE_REGEX, <a class="indexterm" href="functions-matching.html#POSIX-VS-XQUERY">Differences from SQL Standard and XQuery</a>, <a class="indexterm" href="functions-json.html#JSONPATH-REGULAR-EXPRESSIONS">SQL/JSON Regular Expressions</a></dt><dd><dl><dt>in SQL/JSON, <a class="indexterm" href="functions-json.html#JSONPATH-REGULAR-EXPRESSIONS">SQL/JSON Regular Expressions</a></dt></dl></dd><dt id="ientry-idm5481">LIMIT, <a class="indexterm" href="queries-limit.html">LIMIT and OFFSET</a></dt><dt id="ientry-idm8059">line, <a class="indexterm" href="datatype-geometric.html#DATATYPE-LINE">Lines</a>, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm8099">line segment, <a class="indexterm" href="datatype-geometric.html#DATATYPE-LSEG">Line Segments</a></dt><dt id="ientry-idm24975">linear regression, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm37163">Linux</dt><dd><dl><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt>start script, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt></dl></dd><dt id="ientry-idm108345">LISTEN, <a class="indexterm" href="sql-listen.html">LISTEN</a></dt><dt id="ientry-idm38577">listen_addresses configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm35765">llvm-config, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a></dt><dt id="ientry-idm165391">ll_to_earth, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm11349">ln, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm166896">lo, <a class="indexterm" href="lo.html">lo</a></dt><dt id="ientry-idm108415">LOAD, <a class="indexterm" href="sql-load.html">LOAD</a></dt><dt id="ientry-idm50015">load balancing, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm37039">locale, <a class="indexterm" href="creating-cluster.html">Creating a Database Cluster</a>, <a class="indexterm" href="locale.html">Locale Support</a></dt><dt id="ientry-idm17415">localtime, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17438">localtimestamp, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm43688">local_preload_libraries configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">Shared Library Preloading</a></dt><dt id="ientry-idm33809">lock, <a class="indexterm" href="explicit-locking.html">Explicit Locking</a>, <a class="indexterm" href="explicit-locking.html#ADVISORY-LOCKS">Advisory Locks</a>, <a class="indexterm" href="monitoring-locks.html">Viewing Locks</a></dt><dd><dl><dt>advisory, <a class="indexterm" href="explicit-locking.html#ADVISORY-LOCKS">Advisory Locks</a></dt><dt>monitoring, <a class="indexterm" href="monitoring-locks.html">Viewing Locks</a></dt></dl></dd><dt id="ientry-idm33823">LOCK, <a class="indexterm" href="explicit-locking.html#LOCKING-TABLES">Table-Level Locks</a>, <a class="indexterm" href="sql-lock.html">LOCK</a></dt><dt id="ientry-idm43277">lock_timeout configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm11365">log, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm50259">log shipping, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm11381">log10, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm26378">Logging</dt><dd><dl><dt>current_logfiles file and the pg_current_logfile
+ function, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt>pg_current_logfile function, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt></dl></dd><dt id="ientry-idm41500">logging_collector configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm87197">Logical Decoding, <a class="indexterm" href="logicaldecoding.html">Logical Decoding</a>, <a class="indexterm" href="logicaldecoding-explanation.html#id-1.8.14.8.2">Logical Decoding</a></dt><dt id="ientry-idm39279">logical_decoding_work_mem configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm46044">login privilege, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dt id="ientry-idm42003">log_autovacuum_min_duration</dt><dd><dl><dt>configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt>storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt></dl></dd><dt id="ientry-idm44571">log_btree_build_stats configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm42018">log_checkpoints configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42028">log_connections configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41441">log_destination configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41521">log_directory configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm42043">log_disconnections configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42055">log_duration configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42075">log_error_verbosity configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42769">log_executor_stats configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">Statistics Monitoring</a></dt><dt id="ientry-idm41533">log_filename configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41566">log_file_mode configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm42096">log_hostname configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42106">log_line_prefix configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42261">log_lock_waits configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41795">log_min_duration_sample configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm41774">log_min_duration_statement configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm41749">log_min_error_statement configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm41723">log_min_messages configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm42286">log_parameter_max_length configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42300">log_parameter_max_length_on_error configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42757">log_parser_stats configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">Statistics Monitoring</a></dt><dt id="ientry-idm42763">log_planner_stats configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">Statistics Monitoring</a></dt><dt id="ientry-idm42273">log_recovery_conflict_waits configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42349">log_replication_commands configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41585">log_rotation_age configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41596">log_rotation_size configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41845">log_startup_progress_interval configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm42312">log_statement configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41814">log_statement_sample_rate configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm42751">log_statement_stats configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">Statistics Monitoring</a></dt><dt id="ientry-idm42361">log_temp_files configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm42371">log_timezone configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">What to Log</a></dt><dt id="ientry-idm41829">log_transaction_sample_rate configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">When to Log</a></dt><dt id="ientry-idm41607">log_truncate_on_rotation configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm165410">longitude, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm83061">looks_like_number</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt></dl></dd><dt id="ientry-idm80572">loop, <a class="indexterm" href="plpgsql-control-structures.html#PLPGSQL-CONTROL-STRUCTURES-LOOPS">Simple Loops</a></dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#PLPGSQL-CONTROL-STRUCTURES-LOOPS">Simple Loops</a></dt></dl></dd><dt id="ientry-idm12152">lower, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dd><dl><dt>and locales, <a class="indexterm" href="locale.html#id-1.6.11.3.5">Behavior</a></dt></dl></dd><dt id="ientry-idm24350">lower_inc, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm24374">lower_inf, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm62673">lo_close, <a class="indexterm" href="lo-interfaces.html#LO-CLOSE">Closing a Large Object Descriptor</a></dt><dt id="ientry-idm43945">lo_compat_privileges configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm62474">lo_creat, <a class="indexterm" href="lo-interfaces.html#LO-CREATE">Creating a Large Object</a>, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62463">lo_create, <a class="indexterm" href="lo-interfaces.html#LO-CREATE">Creating a Large Object</a></dt><dt id="ientry-idm62521">lo_export, <a class="indexterm" href="lo-interfaces.html#LO-EXPORT">Exporting a Large Object</a>, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62704">lo_from_bytea, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62739">lo_get, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62498">lo_import, <a class="indexterm" href="lo-interfaces.html#LO-IMPORT">Importing a Large Object</a>, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62504">lo_import_with_oid, <a class="indexterm" href="lo-interfaces.html#LO-IMPORT">Importing a Large Object</a></dt><dt id="ientry-idm62605">lo_lseek, <a class="indexterm" href="lo-interfaces.html#LO-SEEK">Seeking in a Large Object</a></dt><dt id="ientry-idm62615">lo_lseek64, <a class="indexterm" href="lo-interfaces.html#LO-SEEK">Seeking in a Large Object</a></dt><dt id="ientry-idm62529">lo_open, <a class="indexterm" href="lo-interfaces.html#LO-OPEN">Opening an Existing Large Object</a></dt><dt id="ientry-idm62721">lo_put, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62588">lo_read, <a class="indexterm" href="lo-interfaces.html#LO-READ">Reading Data from a Large Object</a></dt><dt id="ientry-idm62627">lo_tell, <a class="indexterm" href="lo-interfaces.html#LO-TELL">Obtaining the Seek Position of a Large Object</a></dt><dt id="ientry-idm62631">lo_tell64, <a class="indexterm" href="lo-interfaces.html#LO-TELL">Obtaining the Seek Position of a Large Object</a></dt><dt id="ientry-idm62642">lo_truncate, <a class="indexterm" href="lo-interfaces.html#LO-TRUNCATE">Truncating a Large Object</a></dt><dt id="ientry-idm62659">lo_truncate64, <a class="indexterm" href="lo-interfaces.html#LO-TRUNCATE">Truncating a Large Object</a></dt><dt id="ientry-idm62683">lo_unlink, <a class="indexterm" href="lo-interfaces.html#LO-UNLINK">Removing a Large Object</a>, <a class="indexterm" href="lo-funcs.html">Server-Side Functions</a></dt><dt id="ientry-idm62571">lo_write, <a class="indexterm" href="lo-interfaces.html#LO-WRITE">Writing Data to a Large Object</a></dt><dt id="ientry-idm12561">lpad, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm8097">lseg, <a class="indexterm" href="datatype-geometric.html#DATATYPE-LSEG">Line Segments</a>, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm56519">LSN, <a class="indexterm" href="wal-internals.html">WAL Internals</a></dt><dt id="ientry-idm166952">ltree, <a class="indexterm" href="ltree.html">ltree</a></dt><dt id="ientry-idm167439">ltree2text, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dt id="ientry-idm12584">ltrim, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt></dl></div><div class="indexdiv" id="indexdiv-M"><h3>M</h3><dl><dt id="ientry-idm8414">MAC address (see macaddr)</dt><dt id="ientry-idm8443">MAC address (EUI-64 format) (see macaddr)</dt><dt id="ientry-idm8412">macaddr (data type), <a class="indexterm" href="datatype-net-types.html#DATATYPE-MACADDR">macaddr</a></dt><dt id="ientry-idm8441">macaddr8 (data type), <a class="indexterm" href="datatype-net-types.html#DATATYPE-MACADDR8">macaddr8</a></dt><dt id="ientry-idm19791">macaddr8_set7bit, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm36504">macOS, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-MACOS">macOS</a></dt><dd><dl><dt>installation on, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-MACOS">macOS</a></dt><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt></dl></dd><dt id="ientry-idm74012">magic block, <a class="indexterm" href="xfunc-c.html#XFUNC-C-DYNLOAD">Dynamic Loading</a></dt><dt id="ientry-idm48898">maintenance, <a class="indexterm" href="maintenance.html">Routine Database Maintenance Tasks</a></dt><dt id="ientry-idm39552">maintenance_io_concurrency configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm39244">maintenance_work_mem configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm35247">make, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm26987">makeaclitem, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm17461">make_date, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17478">make_interval, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17510">make_time, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17527">make_timestamp, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm17550">make_timestamptz, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm166827">make_valid, <a class="indexterm" href="isn.html#id-1.11.7.30.7">Functions and Operators</a></dt><dt id="ientry-idm36385">MANPATH, <a class="indexterm" href="install-post.html#id-1.6.4.9.3">Environment Variables</a></dt><dt id="ientry-idm19668">masklen, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm78998">materialized view, <a class="indexterm" href="rules-materializedviews.html">Materialized Views</a></dt><dd><dl><dt>implementation through rules, <a class="indexterm" href="rules-materializedviews.html">Materialized Views</a></dt></dl></dd><dt id="ientry-idm135557">materialized views, <a class="indexterm" href="view-pg-matviews.html">pg_matviews</a></dt><dt id="ientry-idm24789">max, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm38602">max_connections configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm39373">max_files_per_process configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-KERNEL">Kernel Resource Usage</a></dt><dt id="ientry-idm44198">max_function_args configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44208">max_identifier_length configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44220">max_index_keys configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm43827">max_locks_per_transaction configuration parameter, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt><dt id="ientry-idm40816">max_logical_replication_workers configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SUBSCRIBER">Subscribers</a></dt><dt id="ientry-idm39596">max_parallel_maintenance_workers configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm39612">max_parallel_workers configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm39578">max_parallel_workers_per_gather configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm43866">max_pred_locks_per_page configuration parameter, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt><dt id="ientry-idm43854">max_pred_locks_per_relation configuration parameter, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt><dt id="ientry-idm43841">max_pred_locks_per_transaction configuration parameter, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt><dt id="ientry-idm39195">max_prepared_transactions configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm40467">max_replication_slots configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">Sending Servers</a></dt><dt id="ientry-idm40498">max_slot_wal_keep_size configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">Sending Servers</a></dt><dt id="ientry-idm39291">max_stack_depth configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm40693">max_standby_archive_delay configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40707">max_standby_streaming_delay configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40828">max_sync_workers_per_subscription configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SUBSCRIBER">Subscribers</a></dt><dt id="ientry-idm40453">max_wal_senders configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">Sending Servers</a></dt><dt id="ientry-idm40088">max_wal_size configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">Checkpoints</a></dt><dt id="ientry-idm39564">max_worker_processes configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm12602">md5, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm45416">MD5, <a class="indexterm" href="auth-password.html">Password Authentication</a></dt><dt id="ientry-idm2004">median, <a class="indexterm" href="sql-expressions.html#SYNTAX-AGGREGATES">Aggregate Expressions</a></dt><dd><dl><dt>(see also <a href="#ientry-idm25326">percentile</a>)</dt></dl></dd><dt id="ientry-idm86509">memory context</dt><dd><dl><dt>in SPI, <a class="indexterm" href="spi-memory.html">Memory Management</a></dt></dl></dd><dt id="ientry-idm37630">memory overcommit, <a class="indexterm" href="kernel-resources.html#LINUX-MEMORY-OVERCOMMIT">Linux Memory Overcommit</a></dt><dt id="ientry-idm108595">MERGE, <a class="indexterm" href="sql-merge.html">MERGE</a></dt><dt id="ientry-idm165649">metaphone, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.8">Metaphone</a></dt><dt id="ientry-idm24807">min, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm36537">MinGW, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-MINGW">MinGW/Native Windows</a></dt><dd><dl><dt>installation on, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-MINGW">MinGW/Native Windows</a></dt></dl></dd><dt id="ientry-idm39340">min_dynamic_shared_memory configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm41158">min_parallel_index_scan_size configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm41147">min_parallel_table_scan_size configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm11413">min_scale, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm40102">min_wal_size configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">Checkpoints</a></dt><dt id="ientry-idm11425">mod, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm25312">mode</dt><dd><dl><dt>statistical, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm50936">monitoring, <a class="indexterm" href="monitoring.html">Monitoring Database Activity</a></dt><dd><dl><dt>database activity, <a class="indexterm" href="monitoring.html">Monitoring Database Activity</a></dt></dl></dd><dt id="ientry-idm108956">MOVE, <a class="indexterm" href="sql-move.html">MOVE</a></dt><dt id="ientry-idm74900">moving-aggregate mode, <a class="indexterm" href="xaggr.html#XAGGR-MOVING-AGGREGATES">Moving-Aggregate Mode</a></dt><dt id="ientry-idm24519">multirange (function), <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm9621">multirange type, <a class="indexterm" href="rangetypes.html">Range Types</a></dt><dt id="ientry-idm33506">Multiversion Concurrency Control, <a class="indexterm" href="mvcc-intro.html">Introduction</a></dt><dt id="ientry-idm49203">MultiXactId, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND">Multixacts and Wraparound</a></dt><dt id="ientry-idm33508">MVCC, <a class="indexterm" href="mvcc-intro.html">Introduction</a></dt></dl></div><div class="indexdiv" id="indexdiv-N"><h3>N</h3><dl><dt id="ientry-idm1195">name, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt><dd><dl><dt>qualified, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CREATE">Creating a Schema</a></dt><dt>syntax of, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt><dt>unqualified, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PATH">The Schema Search Path</a></dt></dl></dd><dt id="ientry-idm6315">NaN (see <a href="#ientry-idm6318">not a number</a>)</dt><dt id="ientry-idm4761">natural join, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt id="ientry-idm10370">negation, <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt id="ientry-idm37188">NetBSD</dt><dd><dl><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt>start script, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt></dl></dd><dt id="ientry-idm19680">netmask, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm8240">network, <a class="indexterm" href="datatype-net-types.html">Network Address Types</a>, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dd><dl><dt>data types, <a class="indexterm" href="datatype-net-types.html">Network Address Types</a></dt></dl></dd><dt id="ientry-idm23154">nextval, <a class="indexterm" href="functions-sequence.html">Sequence Manipulation Functions</a></dt><dt id="ientry-idm37064">NFS, <a class="indexterm" href="creating-cluster.html#CREATING-CLUSTER-NFS">NFS</a></dt><dt id="ientry-idm167379">nlevel, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dt id="ientry-idm34950">non-durable, <a class="indexterm" href="non-durability.html">Non-Durable Settings</a></dt><dt id="ientry-idm57772">nonblocking connection, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a>, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm33545">nonrepeatable read, <a class="indexterm" href="transaction-iso.html">Transaction Isolation</a></dt><dt id="ientry-idm12164">normalize, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm12089">normalized, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm171880">normal_rand, <a class="indexterm" href="tablefunc.html#id-1.11.7.52.5.4">normal_rand</a></dt><dt id="ientry-idm10364">NOT (operator), <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt id="ientry-idm6318">not a number</dt><dd><dl><dt>floating point, <a class="indexterm" href="datatype-numeric.html#DATATYPE-FLOAT">Floating-Point Types</a></dt><dt>numeric (data type), <a class="indexterm" href="datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL">Arbitrary Precision Numbers</a></dt></dl></dd><dt id="ientry-idm25729">NOT IN, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm2660">not-null constraint, <a class="indexterm" href="ddl-constraints.html#id-1.5.4.6.6">Not-Null Constraints</a></dt><dt id="ientry-idm2403">notation, <a class="indexterm" href="sql-syntax-calling-funcs.html">Calling Functions</a></dt><dd><dl><dt>functions, <a class="indexterm" href="sql-syntax-calling-funcs.html">Calling Functions</a></dt></dl></dd><dt id="ientry-idm61352">notice processing, <a class="indexterm" href="libpq-notice-processing.html">Notice Processing</a></dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-notice-processing.html">Notice Processing</a></dt></dl></dd><dt id="ientry-idm61365">notice processor, <a class="indexterm" href="libpq-notice-processing.html">Notice Processing</a></dt><dt id="ientry-idm61360">notice receiver, <a class="indexterm" href="libpq-notice-processing.html">Notice Processing</a></dt><dt id="ientry-idm60694">NOTIFY, <a class="indexterm" href="libpq-notify.html">Asynchronous Notification</a>, <a class="indexterm" href="sql-notify.html">NOTIFY</a></dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-notify.html">Asynchronous Notification</a></dt></dl></dd><dt id="ientry-idm10811">NOTNULL, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm17581">now, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm19057">npoints, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm25671">nth_value, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm25589">ntile, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm2523">null value</dt><dd><dl><dt>with check constraints, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS">Check Constraints</a></dt><dt>comparing, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt>default value, <a class="indexterm" href="ddl-default.html">Default Values</a></dt><dt>in DISTINCT, <a class="indexterm" href="queries-select-lists.html#QUERIES-DISTINCT">DISTINCT</a></dt><dt>in libpq, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt>in PL/Perl, <a class="indexterm" href="plperl-funcs.html">PL/Perl Functions and Arguments</a></dt><dt>in PL/Python, <a class="indexterm" href="plpython-data.html#id-1.8.11.10.4">Null, None</a></dt><dt>with unique constraints, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS">Unique Constraints</a></dt></dl></dd><dt id="ientry-idm23358">NULLIF, <a class="indexterm" href="functions-conditional.html#FUNCTIONS-NULLIF">NULLIF</a></dt><dt id="ientry-idm1455">number</dt><dd><dl><dt>constant, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC">Numeric Constants</a></dt></dl></dd><dt id="ientry-idm1485">numeric, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC">Numeric Constants</a></dt><dt id="ientry-idm6260">numeric (data type), <a class="indexterm" href="datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL">Arbitrary Precision Numbers</a></dt><dt id="ientry-idm20013">numnode, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY">Manipulating Queries</a></dt><dt id="ientry-idm10888">num_nonnulls, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm10901">num_nulls, <a class="indexterm" href="functions-comparison.html">Comparison Functions and Operators</a></dt><dt id="ientry-idm23334">NVL, <a class="indexterm" href="functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL">COALESCE</a></dt></dl></div><div class="indexdiv" id="indexdiv-O"><h3>O</h3><dl><dt id="ientry-idm9866">object identifier, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dd><dl><dt>data type, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt></dl></dd><dt id="ientry-idm601">object-oriented database, <a class="indexterm" href="tutorial-concepts.html">Concepts</a></dt><dt id="ientry-idm27968">obj_description, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm15766">OCCURRENCES_REGEX, <a class="indexterm" href="functions-matching.html#POSIX-VS-XQUERY">Differences from SQL Standard and XQuery</a></dt><dt id="ientry-idm12186">octet_length, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm5483">OFFSET, <a class="indexterm" href="queries-limit.html">LIMIT and OFFSET</a></dt><dt id="ientry-idm9869">oid, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm59844">OID</dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">Retrieving Other Result Information</a></dt></dl></dd><dt id="ientry-idm172692">oid2name, <a class="indexterm" href="oid2name.html">oid2name</a></dt><dt id="ientry-idm167561">old_snapshot, <a class="indexterm" href="oldsnapshot.html">old_snapshot</a></dt><dt id="ientry-idm39637">old_snapshot_threshold configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm108121">ON CONFLICT, <a class="indexterm" href="sql-insert.html">INSERT</a></dt><dt id="ientry-idm4600">ONLY, <a class="indexterm" href="queries-table-expressions.html#QUERIES-FROM">The FROM Clause</a></dt><dt id="ientry-idm37632">OOM, <a class="indexterm" href="kernel-resources.html#LINUX-MEMORY-OVERCOMMIT">Linux Memory Overcommit</a></dt><dt id="ientry-idm37156">OpenBSD</dt><dd><dl><dt>IPC configuration, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt>start script, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt></dl></dd><dt id="ientry-idm35794">OpenSSL, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a></dt><dd><dl><dt>(see also <a href="#ientry-idm37985">SSL</a>)</dt></dl></dd><dt id="ientry-idm1542">operator, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS">Operators</a>, <a class="indexterm" href="sql-syntax-lexical.html#SQL-PRECEDENCE">Operator Precedence</a>, <a class="indexterm" href="functions.html">Functions and Operators</a>, <a class="indexterm" href="functions-logical.html">Logical Operators</a>, <a class="indexterm" href="typeconv-oper.html">Operators</a>, <a class="indexterm" href="xoper.html">User-Defined Operators</a></dt><dd><dl><dt>invocation, <a class="indexterm" href="sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS">Operator Invocations</a></dt><dt>logical, <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt>precedence, <a class="indexterm" href="sql-syntax-lexical.html#SQL-PRECEDENCE">Operator Precedence</a></dt><dt>syntax, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS">Operators</a></dt><dt>type resolution in an invocation, <a class="indexterm" href="typeconv-oper.html">Operators</a></dt><dt>user-defined, <a class="indexterm" href="xoper.html">User-Defined Operators</a></dt></dl></dd><dt id="ientry-idm31609">operator class, <a class="indexterm" href="indexes-opclass.html">Operator Classes and Operator Families</a>, <a class="indexterm" href="xindex.html#XINDEX-OPCLASS">Index Methods and Operator Classes</a></dt><dt id="ientry-idm31611">operator family, <a class="indexterm" href="indexes-opclass.html">Operator Classes and Operator Families</a>, <a class="indexterm" href="xindex.html#XINDEX-OPFAMILY">Operator Classes and Operator Families</a></dt><dt id="ientry-idm74807">optimization information, <a class="indexterm" href="xfunc-optimization.html">Function Optimization Information</a>, <a class="indexterm" href="xoper-optimization.html">Operator Optimization Information</a></dt><dd><dl><dt>for functions, <a class="indexterm" href="xfunc-optimization.html">Function Optimization Information</a></dt><dt>for operators, <a class="indexterm" href="xoper-optimization.html">Operator Optimization Information</a></dt></dl></dd><dt id="ientry-idm10362">OR (operator), <a class="indexterm" href="functions-logical.html">Logical Operators</a></dt><dt id="ientry-idm81935">Oracle, <a class="indexterm" href="plpgsql-porting.html">Porting from Oracle PL/SQL</a></dt><dd><dl><dt>porting from PL/SQL to PL/pgSQL, <a class="indexterm" href="plpgsql-porting.html">Porting from Oracle PL/SQL</a></dt></dl></dd><dt id="ientry-idm731">ORDER BY, <a class="indexterm" href="tutorial-select.html">Querying a Table</a>, <a class="indexterm" href="queries-order.html">Sorting Rows (ORDER BY)</a></dt><dd><dl><dt>and locales, <a class="indexterm" href="locale.html#id-1.6.11.3.5">Behavior</a></dt></dl></dd><dt id="ientry-idm1917">ordered-set aggregate, <a class="indexterm" href="sql-expressions.html#SYNTAX-AGGREGATES">Aggregate Expressions</a></dt><dd><dl><dt>built-in, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm75938">ordering operator, <a class="indexterm" href="xindex.html#XINDEX-OPCLASS-DEPENDENCIES">System Dependencies on Operator Classes</a></dt><dt id="ientry-idm26213">ordinality, <a class="indexterm" href="functions-srf.html">Set Returning Functions</a></dt><dt id="ientry-idm4670">outer join, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt id="ientry-idm75074">output function, <a class="indexterm" href="xtypes.html">User-Defined Types</a></dt><dt id="ientry-idm2031">OVER clause, <a class="indexterm" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS">Window Function Calls</a></dt><dt id="ientry-idm37634">overcommit, <a class="indexterm" href="kernel-resources.html#LINUX-MEMORY-OVERCOMMIT">Linux Memory Overcommit</a></dt><dt id="ientry-idm17641">OVERLAPS, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm12211">overlay, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm73820">overloading, <a class="indexterm" href="xfunc-overload.html">Function Overloading</a></dt><dd><dl><dt>functions, <a class="indexterm" href="xfunc-overload.html">Function Overloading</a></dt><dt>operators, <a class="indexterm" href="xoper.html">User-Defined Operators</a></dt></dl></dd><dt id="ientry-idm3028">owner, <a class="indexterm" href="ddl-priv.html">Privileges</a></dt></dl></div><div class="indexdiv" id="indexdiv-P"><h3>P</h3><dl><dt id="ientry-idm167576">pageinspect, <a class="indexterm" href="pageinspect.html">pageinspect</a></dt><dt id="ientry-idm97752">pages_per_range storage parameter, <a class="indexterm" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS">Index Storage Parameters</a></dt><dt id="ientry-idm167625">page_checksum, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.4">General Functions</a></dt><dt id="ientry-idm167609">page_header, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.4">General Functions</a></dt><dt id="ientry-idm74412">palloc, <a class="indexterm" href="xfunc-c.html#id-1.8.3.13.8">Writing Code</a></dt><dt id="ientry-idm35842">PAM, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a>, <a class="indexterm" href="auth-pam.html">PAM Authentication</a></dt><dt id="ientry-idm34980">parallel query, <a class="indexterm" href="parallel-query.html">Parallel Query</a></dt><dt id="ientry-idm39624">parallel_leader_participation configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">Asynchronous Behavior</a></dt><dt id="ientry-idm41129">parallel_setup_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm41138">parallel_tuple_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm101338">parallel_workers storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm1810">parameter</dt><dd><dl><dt>syntax, <a class="indexterm" href="sql-expressions.html#SQL-EXPRESSIONS-PARAMETERS-POSITIONAL">Positional Parameters</a></dt></dl></dd><dt id="ientry-idm1789">parenthesis, <a class="indexterm" href="sql-expressions.html">Value Expressions</a></dt><dt id="ientry-idm12615">parse_ident, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm4234">partition pruning, <a class="indexterm" href="ddl-partitioning.html#DDL-PARTITION-PRUNING">Partition Pruning</a></dt><dt id="ientry-idm3950">partitioned table, <a class="indexterm" href="ddl-partitioning.html">Table Partitioning</a></dt><dt id="ientry-idm3945">partitioning, <a class="indexterm" href="ddl-partitioning.html">Table Partitioning</a></dt><dt id="ientry-idm37027">password, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dd><dl><dt>authentication, <a class="indexterm" href="auth-password.html">Password Authentication</a></dt><dt>of the superuser, <a class="indexterm" href="creating-cluster.html">Creating a Database Cluster</a></dt></dl></dd><dt id="ientry-idm61887">password file, <a class="indexterm" href="libpq-pgpass.html">The Password File</a></dt><dt id="ientry-idm167947">passwordcheck, <a class="indexterm" href="passwordcheck.html">passwordcheck</a></dt><dt id="ientry-idm38792">password_encryption configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt><dt id="ientry-idm19267">path, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dd><dl><dt>for schemas, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt></dl></dd><dt id="ientry-idm36366">PATH, <a class="indexterm" href="install-post.html#id-1.6.4.9.3">Environment Variables</a></dt><dt id="ientry-idm8158">path (data type), <a class="indexterm" href="datatype-geometric.html#id-1.5.7.16.9">Paths</a></dt><dt id="ientry-idm14358">pattern matching, <a class="indexterm" href="functions-matching.html">Pattern Matching</a></dt><dt id="ientry-idm122863">patterns</dt><dd><dl><dt>in psql and pg_dump, <a class="indexterm" href="app-psql.html#APP-PSQL-PATTERNS">Patterns</a></dt></dl></dd><dt id="ientry-idm19071">pclose, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm45674">peer, <a class="indexterm" href="auth-peer.html">Peer Authentication</a></dt><dt id="ientry-idm25326">percentile</dt><dd><dl><dt>continuous, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt>discrete, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm25455">percent_rank, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dd><dl><dt>hypothetical, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm34371">performance, <a class="indexterm" href="performance-tips.html">Performance Tips</a></dt><dt id="ientry-idm35405">perl, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm82655">Perl, <a class="indexterm" href="plperl.html">PL/Perl — Perl Procedural Language</a></dt><dt id="ientry-idm3025">permission (see <a href="#ientry-idm3023">privilege</a>)</dt><dt id="ientry-idm74415">pfree, <a class="indexterm" href="xfunc-c.html#id-1.8.3.13.8">Writing Code</a></dt><dt id="ientry-idm61708">PGAPPNAME, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm115705">pgbench, <a class="indexterm" href="pgbench.html">pgbench</a></dt><dt id="ientry-idm60585">PGcancel, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt><dt id="ientry-idm61678">PGCHANNELBINDING, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61828">PGCLIENTENCODING, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm57652">PGconn, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm61821">PGCONNECT_TIMEOUT, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm168086">pgcrypto, <a class="indexterm" href="pgcrypto.html">pgcrypto</a></dt><dt id="ientry-idm36988">PGDATA, <a class="indexterm" href="creating-cluster.html">Creating a Database Cluster</a></dt><dt id="ientry-idm61648">PGDATABASE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61847">PGDATESTYLE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61519">PGEventProc, <a class="indexterm" href="libpq-events.html#LIBPQ-EVENTS-PROC">Event Callback Procedure</a></dt><dt id="ientry-idm61861">PGGEQO, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61800">PGGSSENCMODE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61814">PGGSSLIB, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61626">PGHOST, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61633">PGHOSTADDR, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61807">PGKRBSRVNAME, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61880">PGLOCALEDIR, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61701">PGOPTIONS, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61671">PGPASSFILE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61662">PGPASSWORD, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61641">PGPORT, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm168493">pgp_armor_headers, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.17">pgp_armor_headers</a></dt><dt id="ientry-idm168458">pgp_key_id, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.15">pgp_key_id()</a></dt><dt id="ientry-idm168441">pgp_pub_decrypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.14">pgp_pub_decrypt()</a></dt><dt id="ientry-idm168443">pgp_pub_decrypt_bytea, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.14">pgp_pub_decrypt()</a></dt><dt id="ientry-idm168428">pgp_pub_encrypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.13">pgp_pub_encrypt()</a></dt><dt id="ientry-idm168430">pgp_pub_encrypt_bytea, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.13">pgp_pub_encrypt()</a></dt><dt id="ientry-idm168413">pgp_sym_decrypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.12">pgp_sym_decrypt()</a></dt><dt id="ientry-idm168415">pgp_sym_decrypt_bytea, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.12">pgp_sym_decrypt()</a></dt><dt id="ientry-idm168401">pgp_sym_encrypt, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.11">pgp_sym_encrypt()</a></dt><dt id="ientry-idm168403">pgp_sym_encrypt_bytea, <a class="indexterm" href="pgcrypto.html#id-1.11.7.37.9.11">pgp_sym_encrypt()</a></dt><dt id="ientry-idm61779">PGREQUIREPEER, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61722">PGREQUIRESSL, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm59279">PGresult, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm168886">pgrowlocks, <a class="indexterm" href="pgrowlocks.html">pgrowlocks</a>, <a class="indexterm" href="pgrowlocks.html#id-1.11.7.40.5">Overview</a></dt><dt id="ientry-idm61685">PGSERVICE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61692">PGSERVICEFILE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61737">PGSSLCERT, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61730">PGSSLCOMPRESSION, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61758">PGSSLCRL, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61765">PGSSLCRLDIR, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61744">PGSSLKEY, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61793">PGSSLMAXPROTOCOLVERSION, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61786">PGSSLMINPROTOCOLVERSION, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61715">PGSSLMODE, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61751">PGSSLROOTCERT, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61772">PGSSLSNI, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm169693">pgstatginindex, <a class="indexterm" href="pgstattuple.html#id-1.11.7.42.5">Functions</a></dt><dt id="ientry-idm169729">pgstathashindex, <a class="indexterm" href="pgstattuple.html#id-1.11.7.42.5">Functions</a></dt><dt id="ientry-idm169603">pgstatindex, <a class="indexterm" href="pgstattuple.html#id-1.11.7.42.5">Functions</a></dt><dt id="ientry-idm169496">pgstattuple, <a class="indexterm" href="pgstattuple.html">pgstattuple</a>, <a class="indexterm" href="pgstattuple.html#id-1.11.7.42.5">Functions</a></dt><dt id="ientry-idm169809">pgstattuple_approx, <a class="indexterm" href="pgstattuple.html#id-1.11.7.42.5">Functions</a></dt><dt id="ientry-idm61873">PGSYSCONFDIR, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61835">PGTARGETSESSIONATTRS, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61854">PGTZ, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm61655">PGUSER, <a class="indexterm" href="libpq-envars.html">Environment Variables</a></dt><dt id="ientry-idm76439">pgxs, <a class="indexterm" href="extend-pgxs.html">Extension Building Infrastructure</a></dt><dt id="ientry-idm30104">pg_advisory_lock, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30121">pg_advisory_lock_shared, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30138">pg_advisory_unlock, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30157">pg_advisory_unlock_all, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30165">pg_advisory_unlock_shared, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30184">pg_advisory_xact_lock, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30201">pg_advisory_xact_lock_shared, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm128161">pg_aggregate, <a class="indexterm" href="catalog-pg-aggregate.html">pg_aggregate</a></dt><dt id="ientry-idm128375">pg_am, <a class="indexterm" href="catalog-pg-am.html">pg_am</a></dt><dt id="ientry-idm114706">pg_amcheck, <a class="indexterm" href="app-pgamcheck.html">pg_amcheck</a></dt><dt id="ientry-idm128429">pg_amop, <a class="indexterm" href="catalog-pg-amop.html">pg_amop</a></dt><dt id="ientry-idm128550">pg_amproc, <a class="indexterm" href="catalog-pg-amproc.html">pg_amproc</a></dt><dt id="ientry-idm124849">pg_archivecleanup, <a class="indexterm" href="pgarchivecleanup.html">pg_archivecleanup</a></dt><dt id="ientry-idm128622">pg_attrdef, <a class="indexterm" href="catalog-pg-attrdef.html">pg_attrdef</a></dt><dt id="ientry-idm128673">pg_attribute, <a class="indexterm" href="catalog-pg-attribute.html">pg_attribute</a></dt><dt id="ientry-idm128901">pg_authid, <a class="indexterm" href="catalog-pg-authid.html">pg_authid</a></dt><dt id="ientry-idm129024">pg_auth_members, <a class="indexterm" href="catalog-pg-auth-members.html">pg_auth_members</a></dt><dt id="ientry-idm134716">pg_available_extensions, <a class="indexterm" href="view-pg-available-extensions.html">pg_available_extensions</a></dt><dt id="ientry-idm134763">pg_available_extension_versions, <a class="indexterm" href="view-pg-available-extension-versions.html">pg_available_extension_versions</a></dt><dt id="ientry-idm134841">pg_backend_memory_contexts, <a class="indexterm" href="view-pg-backend-memory-contexts.html">pg_backend_memory_contexts</a></dt><dt id="ientry-idm26348">pg_backend_pid, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28786">pg_backup_start, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm28802">pg_backup_stop, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm115126">pg_basebackup, <a class="indexterm" href="app-pgbasebackup.html">pg_basebackup</a></dt><dt id="ientry-idm26356">pg_blocking_pids, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm167973">pg_buffercache, <a class="indexterm" href="pgbuffercache.html">pg_buffercache</a></dt><dt id="ientry-idm167977">pg_buffercache_pages, <a class="indexterm" href="pgbuffercache.html">pg_buffercache</a></dt><dt id="ientry-idm28643">pg_cancel_backend, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">Server Signaling Functions</a></dt><dt id="ientry-idm129080">pg_cast, <a class="indexterm" href="catalog-pg-cast.html">pg_cast</a></dt><dt id="ientry-idm27182">pg_char_to_encoding, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm124968">pg_checksums, <a class="indexterm" href="app-pgchecksums.html">pg_checksums</a></dt><dt id="ientry-idm129168">pg_class, <a class="indexterm" href="catalog-pg-class.html">pg_class</a></dt><dt id="ientry-idm12635">pg_client_encoding, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm129491">pg_collation, <a class="indexterm" href="catalog-pg-collation.html">pg_collation</a></dt><dt id="ientry-idm29689">pg_collation_actual_version, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm27021">pg_collation_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm175189">PG_COLOR, <a class="indexterm" href="color-when.html">When Color is Used</a></dt><dt id="ientry-idm175204">PG_COLORS, <a class="indexterm" href="color-which.html">Configuring the Colors</a></dt><dt id="ientry-idm29496">pg_column_compression, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29487">pg_column_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm62338">pg_config, <a class="indexterm" href="app-pgconfig.html">pg_config</a>, <a class="indexterm" href="view-pg-config.html">pg_config</a></dt><dd><dl><dt>with
+ ecpg, <a class="indexterm" href="ecpg-process.html">Processing Embedded SQL Programs</a></dt><dt>with libpq, <a class="indexterm" href="libpq-build.html">Building libpq Programs</a></dt><dt>with user-defined C functions, <a class="indexterm" href="xfunc-c.html#id-1.8.3.13.8">Writing Code</a></dt></dl></dd><dt id="ientry-idm26368">pg_conf_load_time, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm129601">pg_constraint, <a class="indexterm" href="catalog-pg-constraint.html">pg_constraint</a></dt><dt id="ientry-idm125109">pg_controldata, <a class="indexterm" href="app-pgcontroldata.html">pg_controldata</a></dt><dt id="ientry-idm28290">pg_control_checkpoint, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28308">pg_control_init, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28317">pg_control_recovery, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28299">pg_control_system, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm129851">pg_conversion, <a class="indexterm" href="catalog-pg-conversion.html">pg_conversion</a></dt><dt id="ientry-idm27031">pg_conversion_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm29182">pg_copy_logical_replication_slot, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29158">pg_copy_physical_replication_slot, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29132">pg_create_logical_replication_slot, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29094">pg_create_physical_replication_slot, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm28750">pg_create_restore_point, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm36994">pg_ctl, <a class="indexterm" href="creating-cluster.html">Creating a Database Cluster</a>, <a class="indexterm" href="server-start.html">Starting the Database Server</a>, <a class="indexterm" href="app-pg-ctl.html">pg_ctl</a></dt><dt id="ientry-idm26376">pg_current_logfile, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28048">pg_current_snapshot, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28762">pg_current_wal_flush_lsn, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm28770">pg_current_wal_insert_lsn, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm28778">pg_current_wal_lsn, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm28014">pg_current_xact_id, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28022">pg_current_xact_id_if_assigned, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm134952">pg_cursors, <a class="indexterm" href="view-pg-cursors.html">pg_cursors</a></dt><dt id="ientry-idm46517">pg_database, <a class="indexterm" href="manage-ag-templatedbs.html">Template Databases</a>, <a class="indexterm" href="catalog-pg-database.html">pg_database</a></dt><dt id="ientry-idm29701">pg_database_collation_actual_version, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29506">pg_database_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm130074">pg_db_role_setting, <a class="indexterm" href="catalog-pg-db-role-setting.html">pg_db_role_setting</a></dt><dt id="ientry-idm10156">pg_ddl_command, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm130118">pg_default_acl, <a class="indexterm" href="catalog-pg-default-acl.html">pg_default_acl</a></dt><dt id="ientry-idm130187">pg_depend, <a class="indexterm" href="catalog-pg-depend.html">pg_depend</a></dt><dt id="ientry-idm27843">pg_describe_object, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm130340">pg_description, <a class="indexterm" href="catalog-pg-description.html">pg_description</a></dt><dt id="ientry-idm29120">pg_drop_replication_slot, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm117728">pg_dump, <a class="indexterm" href="app-pgdump.html">pg_dump</a></dt><dt id="ientry-idm37836">pg_dumpall, <a class="indexterm" href="app-pg-dumpall.html">pg_dumpall</a></dt><dd><dl><dt>use during upgrade, <a class="indexterm" href="upgrading.html#UPGRADING-VIA-PGDUMPALL">Upgrading Data via pg_dumpall</a></dt></dl></dd><dt id="ientry-idm27193">pg_encoding_to_char, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm130394">pg_enum, <a class="indexterm" href="catalog-pg-enum.html">pg_enum</a></dt><dt id="ientry-idm130447">pg_event_trigger, <a class="indexterm" href="catalog-pg-event-trigger.html">pg_event_trigger</a></dt><dt id="ientry-idm30360">pg_event_trigger_ddl_commands, <a class="indexterm" href="functions-event-triggers.html#PG-EVENT-TRIGGER-DDL-COMMAND-END-FUNCTIONS">Capturing Changes at Command End</a></dt><dt id="ientry-idm30435">pg_event_trigger_dropped_objects, <a class="indexterm" href="functions-event-triggers.html#PG-EVENT-TRIGGER-SQL-DROP-FUNCTIONS">Processing Objects Dropped by a DDL Command</a></dt><dt id="ientry-idm30549">pg_event_trigger_table_rewrite_oid, <a class="indexterm" href="functions-event-triggers.html#PG-EVENT-TRIGGER-TABLE-REWRITE-FUNCTIONS">Handling a Table Rewrite Event</a></dt><dt id="ientry-idm30557">pg_event_trigger_table_rewrite_reason, <a class="indexterm" href="functions-event-triggers.html#PG-EVENT-TRIGGER-TABLE-REWRITE-FUNCTIONS">Handling a Table Rewrite Event</a></dt><dt id="ientry-idm29057">pg_export_snapshot, <a class="indexterm" href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION">Snapshot Synchronization Functions</a></dt><dt id="ientry-idm130521">pg_extension, <a class="indexterm" href="catalog-pg-extension.html">pg_extension</a></dt><dt id="ientry-idm76272">pg_extension_config_dump, <a class="indexterm" href="extend-extensions.html#EXTEND-EXTENSIONS-CONFIG-TABLES">Extension Configuration Tables</a></dt><dt id="ientry-idm29664">pg_filenode_relation, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm163024">pg_file_rename, <a class="indexterm" href="adminpack.html">adminpack</a></dt><dt id="ientry-idm135031">pg_file_settings, <a class="indexterm" href="view-pg-file-settings.html">pg_file_settings</a></dt><dt id="ientry-idm163018">pg_file_sync, <a class="indexterm" href="adminpack.html">adminpack</a></dt><dt id="ientry-idm163038">pg_file_unlink, <a class="indexterm" href="adminpack.html">adminpack</a></dt><dt id="ientry-idm163010">pg_file_write, <a class="indexterm" href="adminpack.html">adminpack</a></dt><dt id="ientry-idm130605">pg_foreign_data_wrapper, <a class="indexterm" href="catalog-pg-foreign-data-wrapper.html">pg_foreign_data_wrapper</a></dt><dt id="ientry-idm130675">pg_foreign_server, <a class="indexterm" href="catalog-pg-foreign-server.html">pg_foreign_server</a></dt><dt id="ientry-idm130748">pg_foreign_table, <a class="indexterm" href="catalog-pg-foreign-table.html">pg_foreign_table</a></dt><dt id="ientry-idm168794">pg_freespace, <a class="indexterm" href="pgfreespacemap.html#id-1.11.7.38.5">Functions</a></dt><dt id="ientry-idm168778">pg_freespacemap, <a class="indexterm" href="pgfreespacemap.html">pg_freespacemap</a></dt><dt id="ientry-idm27041">pg_function_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27203">pg_get_catalog_foreign_keys, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27230">pg_get_constraintdef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27243">pg_get_expr, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27258">pg_get_functiondef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27270">pg_get_function_arguments, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27281">pg_get_function_identity_arguments, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27292">pg_get_function_result, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27305">pg_get_indexdef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27321">pg_get_keywords, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27912">pg_get_object_address, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27353">pg_get_ruledef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27366">pg_get_serial_sequence, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27386">pg_get_statisticsobjdef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27396">pg_get_triggerdef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27409">pg_get_userbyid, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27419">pg_get_viewdef, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28973">pg_get_wal_replay_pause_state, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm28939">pg_get_wal_resource_managers, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm135107">pg_group, <a class="indexterm" href="view-pg-group.html">pg_group</a></dt><dt id="ientry-idm26827">pg_has_role, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm44883">pg_hba.conf, <a class="indexterm" href="auth-pg-hba-conf.html">The pg_hba.conf File</a></dt><dt id="ientry-idm135153">pg_hba_file_rules, <a class="indexterm" href="view-pg-hba-file-rules.html">pg_hba_file_rules</a></dt><dt id="ientry-idm45285">pg_ident.conf, <a class="indexterm" href="auth-username-maps.html">User Name Maps</a></dt><dt id="ientry-idm27859">pg_identify_object, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27888">pg_identify_object_as_address, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm135239">pg_ident_file_mappings, <a class="indexterm" href="view-pg-ident-file-mappings.html">pg_ident_file_mappings</a></dt><dt id="ientry-idm29713">pg_import_system_collations, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm130795">pg_index, <a class="indexterm" href="catalog-pg-index.html">pg_index</a></dt><dt id="ientry-idm27486">pg_indexam_has_property, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm135299">pg_indexes, <a class="indexterm" href="view-pg-indexes.html">pg_indexes</a></dt><dt id="ientry-idm29521">pg_indexes_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm27456">pg_index_column_has_property, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27472">pg_index_has_property, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm130989">pg_inherits, <a class="indexterm" href="catalog-pg-inherits.html">pg_inherits</a></dt><dt id="ientry-idm131039">pg_init_privs, <a class="indexterm" href="catalog-pg-init-privs.html">pg_init_privs</a></dt><dt id="ientry-idm119099">pg_isready, <a class="indexterm" href="app-pg-isready.html">pg_isready</a></dt><dt id="ientry-idm28903">pg_is_in_recovery, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm26416">pg_is_other_temp_schema, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28965">pg_is_wal_replay_paused, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm26425">pg_jit_available, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm131110">pg_language, <a class="indexterm" href="catalog-pg-language.html">pg_language</a></dt><dt id="ientry-idm131200">pg_largeobject, <a class="indexterm" href="catalog-pg-largeobject.html">pg_largeobject</a></dt><dt id="ientry-idm131253">pg_largeobject_metadata, <a class="indexterm" href="catalog-pg-largeobject-metadata.html">pg_largeobject_metadata</a></dt><dt id="ientry-idm28263">pg_last_committed_xact, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28911">pg_last_wal_receive_lsn, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm28920">pg_last_wal_replay_lsn, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm28929">pg_last_xact_replay_timestamp, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm26437">pg_listening_channels, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm135359">pg_locks, <a class="indexterm" href="view-pg-locks.html">pg_locks</a></dt><dt id="ientry-idm163043">pg_logdir_ls, <a class="indexterm" href="adminpack.html">adminpack</a></dt><dt id="ientry-idm29446">pg_logical_emit_message, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29261">pg_logical_slot_get_binary_changes, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29209">pg_logical_slot_get_changes, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29286">pg_logical_slot_peek_binary_changes, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29237">pg_logical_slot_peek_changes, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm28654">pg_log_backend_memory_contexts, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">Server Signaling Functions</a></dt><dt id="ientry-idm10105">pg_lsn, <a class="indexterm" href="datatype-pg-lsn.html">pg_lsn Type</a></dt><dt id="ientry-idm29974">pg_ls_archive_statusdir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29867">pg_ls_dir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29888">pg_ls_logdir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29920">pg_ls_logicalmapdir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29937">pg_ls_logicalsnapdir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29954">pg_ls_replslotdir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29991">pg_ls_tmpdir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm29904">pg_ls_waldir, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm135555">pg_matviews, <a class="indexterm" href="view-pg-matviews.html">pg_matviews</a></dt><dt id="ientry-idm30574">pg_mcv_list_items, <a class="indexterm" href="functions-statistics.html#FUNCTIONS-STATISTICS-MCV">Inspecting MCV Lists</a></dt><dt id="ientry-idm26408">pg_my_temp_schema, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm131294">pg_namespace, <a class="indexterm" href="catalog-pg-namespace.html">pg_namespace</a></dt><dt id="ientry-idm26445">pg_notification_queue_usage, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm109085">pg_notify, <a class="indexterm" href="sql-notify.html#id-1.9.3.158.7.5">pg_notify</a></dt><dt id="ientry-idm131339">pg_opclass, <a class="indexterm" href="catalog-pg-opclass.html">pg_opclass</a></dt><dt id="ientry-idm27051">pg_opclass_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm131439">pg_operator, <a class="indexterm" href="catalog-pg-operator.html">pg_operator</a></dt><dt id="ientry-idm27061">pg_operator_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm131584">pg_opfamily, <a class="indexterm" href="catalog-pg-opfamily.html">pg_opfamily</a></dt><dt id="ientry-idm27071">pg_opfamily_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27500">pg_options_to_table, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm131651">pg_parameter_acl, <a class="indexterm" href="catalog-pg-parameter-acl.html">pg_parameter_acl</a></dt><dt id="ientry-idm131690">pg_partitioned_table, <a class="indexterm" href="catalog-pg-partitioned-table.html">pg_partitioned_table</a></dt><dt id="ientry-idm29757">pg_partition_ancestors, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29766">pg_partition_root, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29740">pg_partition_tree, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm135629">pg_policies, <a class="indexterm" href="view-pg-policies.html">pg_policies</a></dt><dt id="ientry-idm131783">pg_policy, <a class="indexterm" href="catalog-pg-policy.html">pg_policy</a></dt><dt id="ientry-idm26455">pg_postmaster_start_time, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm135703">pg_prepared_statements, <a class="indexterm" href="view-pg-prepared-statements.html">pg_prepared_statements</a></dt><dt id="ientry-idm135776">pg_prepared_xacts, <a class="indexterm" href="view-pg-prepared-xacts.html">pg_prepared_xacts</a></dt><dt id="ientry-idm168822">pg_prewarm, <a class="indexterm" href="pgprewarm.html">pg_prewarm</a></dt><dt id="ientry-idm168861">pg_prewarm.autoprewarm configuration parameter, <a class="indexterm" href="pgprewarm.html#id-1.11.7.39.5">Configuration Parameters</a></dt><dt id="ientry-idm168871">pg_prewarm.autoprewarm_interval configuration parameter, <a class="indexterm" href="pgprewarm.html#id-1.11.7.39.5">Configuration Parameters</a></dt><dt id="ientry-idm131871">pg_proc, <a class="indexterm" href="catalog-pg-proc.html">pg_proc</a></dt><dt id="ientry-idm28984">pg_promote, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm132160">pg_publication, <a class="indexterm" href="catalog-pg-publication.html">pg_publication</a></dt><dt id="ientry-idm132239">pg_publication_namespace, <a class="indexterm" href="catalog-pg-publication-namespace.html">pg_publication_namespace</a></dt><dt id="ientry-idm132280">pg_publication_rel, <a class="indexterm" href="catalog-pg-publication-rel.html">pg_publication_rel</a></dt><dt id="ientry-idm135834">pg_publication_tables, <a class="indexterm" href="view-pg-publication-tables.html">pg_publication_tables</a></dt><dt id="ientry-idm132339">pg_range, <a class="indexterm" href="catalog-pg-range.html">pg_range</a></dt><dt id="ientry-idm30037">pg_read_binary_file, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm30013">pg_read_file, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm119249">pg_receivewal, <a class="indexterm" href="app-pgreceivewal.html">pg_receivewal</a></dt><dt id="ientry-idm175324">pg_receivexlog, <a class="indexterm" href="app-pgreceivexlog.html">pg_receivexlog renamed to pg_receivewal</a> (see <a href="#ientry-idm119249">pg_receivewal</a>)</dt><dt id="ientry-idm119570">pg_recvlogical, <a class="indexterm" href="app-pgrecvlogical.html">pg_recvlogical</a></dt><dt id="ientry-idm29638">pg_relation_filenode, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29653">pg_relation_filepath, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29530">pg_relation_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm28667">pg_reload_conf, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">Server Signaling Functions</a></dt><dt id="ientry-idm169795">pg_relpages, <a class="indexterm" href="pgstattuple.html#id-1.11.7.42.5">Functions</a></dt><dt id="ientry-idm132427">pg_replication_origin, <a class="indexterm" href="catalog-pg-replication-origin.html">pg_replication_origin</a></dt><dt id="ientry-idm29421">pg_replication_origin_advance, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29328">pg_replication_origin_create, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29338">pg_replication_origin_drop, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29348">pg_replication_origin_oid, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29433">pg_replication_origin_progress, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29379">pg_replication_origin_session_is_setup, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29387">pg_replication_origin_session_progress, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29370">pg_replication_origin_session_reset, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29359">pg_replication_origin_session_setup, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm135897">pg_replication_origin_status, <a class="indexterm" href="view-pg-replication-origin-status.html">pg_replication_origin_status</a></dt><dt id="ientry-idm29412">pg_replication_origin_xact_reset, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm29398">pg_replication_origin_xact_setup, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm135946">pg_replication_slots, <a class="indexterm" href="view-pg-replication-slots.html">pg_replication_slots</a></dt><dt id="ientry-idm29311">pg_replication_slot_advance, <a class="indexterm" href="functions-admin.html#FUNCTIONS-REPLICATION">Replication Management Functions</a></dt><dt id="ientry-idm125711">pg_resetwal, <a class="indexterm" href="app-pgresetwal.html">pg_resetwal</a></dt><dt id="ientry-idm175309">pg_resetxlog, <a class="indexterm" href="app-pgresetxlog.html">pg_resetxlog renamed to pg_resetwal</a> (see <a href="#ientry-idm125711">pg_resetwal</a>)</dt><dt id="ientry-idm119865">pg_restore, <a class="indexterm" href="app-pgrestore.html">pg_restore</a></dt><dt id="ientry-idm125951">pg_rewind, <a class="indexterm" href="app-pgrewind.html">pg_rewind</a></dt><dt id="ientry-idm132460">pg_rewrite, <a class="indexterm" href="catalog-pg-rewrite.html">pg_rewrite</a></dt><dt id="ientry-idm136095">pg_roles, <a class="indexterm" href="view-pg-roles.html">pg_roles</a></dt><dt id="ientry-idm28684">pg_rotate_logfile, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">Server Signaling Functions</a></dt><dt id="ientry-idm136197">pg_rules, <a class="indexterm" href="view-pg-rules.html">pg_rules</a></dt><dt id="ientry-idm26463">pg_safe_snapshot_blocking_pids, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm132546">pg_seclabel, <a class="indexterm" href="catalog-pg-seclabel.html">pg_seclabel</a></dt><dt id="ientry-idm136254">pg_seclabels, <a class="indexterm" href="view-pg-seclabels.html">pg_seclabels</a></dt><dt id="ientry-idm132604">pg_sequence, <a class="indexterm" href="catalog-pg-sequence.html">pg_sequence</a></dt><dt id="ientry-idm136335">pg_sequences, <a class="indexterm" href="view-pg-sequences.html">pg_sequences</a></dt><dt id="ientry-idm61922">pg_service.conf, <a class="indexterm" href="libpq-pgservice.html">The Connection Service File</a></dt><dt id="ientry-idm136432">pg_settings, <a class="indexterm" href="view-pg-settings.html">pg_settings</a></dt><dt id="ientry-idm27518">pg_settings_get_flags, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm136653">pg_shadow, <a class="indexterm" href="view-pg-shadow.html">pg_shadow</a></dt><dt id="ientry-idm132679">pg_shdepend, <a class="indexterm" href="catalog-pg-shdepend.html">pg_shdepend</a></dt><dt id="ientry-idm132791">pg_shdescription, <a class="indexterm" href="catalog-pg-shdescription.html">pg_shdescription</a></dt><dt id="ientry-idm136741">pg_shmem_allocations, <a class="indexterm" href="view-pg-shmem-allocations.html">pg_shmem_allocations</a></dt><dt id="ientry-idm132839">pg_shseclabel, <a class="indexterm" href="catalog-pg-shseclabel.html">pg_shseclabel</a></dt><dt id="ientry-idm29561">pg_size_bytes, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm29571">pg_size_pretty, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm18267">pg_sleep, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">Delaying Execution</a></dt><dt id="ientry-idm18269">pg_sleep_for, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">Delaying Execution</a></dt><dt id="ientry-idm18271">pg_sleep_until, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">Delaying Execution</a></dt><dt id="ientry-idm28057">pg_snapshot_xip, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28066">pg_snapshot_xmax, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28076">pg_snapshot_xmin, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm51302">pg_statio_all_indexes, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-INDEXES-VIEW">pg_statio_all_indexes</a></dt><dt id="ientry-idm51324">pg_statio_all_sequences, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-SEQUENCES-VIEW">pg_statio_all_sequences</a></dt><dt id="ientry-idm51280">pg_statio_all_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-TABLES-VIEW">pg_statio_all_tables</a></dt><dt id="ientry-idm51310">pg_statio_sys_indexes, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51332">pg_statio_sys_sequences, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51288">pg_statio_sys_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51317">pg_statio_user_indexes, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51339">pg_statio_user_sequences, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51295">pg_statio_user_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm34624">pg_statistic, <a class="indexterm" href="planner-stats.html#id-1.5.13.5.3">Single-Column Statistics</a>, <a class="indexterm" href="catalog-pg-statistic.html">pg_statistic</a></dt><dt id="ientry-idm27081">pg_statistics_obj_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm34671">pg_statistic_ext, <a class="indexterm" href="planner-stats.html#PLANNER-STATS-EXTENDED">Extended Statistics</a>, <a class="indexterm" href="catalog-pg-statistic-ext.html">pg_statistic_ext</a></dt><dt id="ientry-idm34673">pg_statistic_ext_data, <a class="indexterm" href="planner-stats.html#PLANNER-STATS-EXTENDED">Extended Statistics</a>, <a class="indexterm" href="catalog-pg-statistic-ext.html">pg_statistic_ext</a></dt><dt id="ientry-idm34636">pg_stats, <a class="indexterm" href="planner-stats.html#id-1.5.13.5.3">Single-Column Statistics</a>, <a class="indexterm" href="view-pg-stats.html">pg_stats</a></dt><dt id="ientry-idm136924">pg_stats_ext, <a class="indexterm" href="view-pg-stats-ext.html">pg_stats_ext</a></dt><dt id="ientry-idm137072">pg_stats_ext_exprs, <a class="indexterm" href="view-pg-stats-ext-exprs.html">pg_stats_ext_exprs</a></dt><dt id="ientry-idm51060">pg_stat_activity, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW">pg_stat_activity</a></dt><dt id="ientry-idm51258">pg_stat_all_indexes, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW">pg_stat_all_indexes</a></dt><dt id="ientry-idm51213">pg_stat_all_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW">pg_stat_all_tables</a></dt><dt id="ientry-idm51173">pg_stat_archiver, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-ARCHIVER-VIEW">pg_stat_archiver</a></dt><dt id="ientry-idm51181">pg_stat_bgwriter, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-BGWRITER-VIEW">pg_stat_bgwriter</a></dt><dt id="ientry-idm54554">pg_stat_clear_snapshot, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm51197">pg_stat_database, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW">pg_stat_database</a></dt><dt id="ientry-idm51205">pg_stat_database_conflicts, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-CONFLICTS-VIEW">pg_stat_database_conflicts</a></dt><dt id="ientry-idm30062">pg_stat_file, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">Generic File Access Functions</a></dt><dt id="ientry-idm54512">pg_stat_get_activity, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54679">pg_stat_get_backend_activity, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54688">pg_stat_get_backend_activity_start, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54697">pg_stat_get_backend_client_addr, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54706">pg_stat_get_backend_client_port, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54715">pg_stat_get_backend_dbid, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54671">pg_stat_get_backend_idset, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54724">pg_stat_get_backend_pid, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54733">pg_stat_get_backend_start, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54742">pg_stat_get_backend_userid, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54761">pg_stat_get_backend_wait_event, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54751">pg_stat_get_backend_wait_event_type, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54772">pg_stat_get_backend_xact_start, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54523">pg_stat_get_snapshot_timestamp, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54533">pg_stat_get_xact_blocks_fetched, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54544">pg_stat_get_xact_blocks_hit, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm51108">pg_stat_gssapi, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-GSSAPI-VIEW">pg_stat_gssapi</a></dt><dt id="ientry-idm51116">pg_stat_progress_analyze, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="progress-reporting.html#ANALYZE-PROGRESS-REPORTING">ANALYZE Progress Reporting</a></dt><dt id="ientry-idm51150">pg_stat_progress_basebackup, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="progress-reporting.html#BASEBACKUP-PROGRESS-REPORTING">Base Backup Progress Reporting</a></dt><dt id="ientry-idm51141">pg_stat_progress_cluster, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING">CLUSTER Progress Reporting</a></dt><dt id="ientry-idm51157">pg_stat_progress_copy, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="progress-reporting.html#COPY-PROGRESS-REPORTING">COPY Progress Reporting</a></dt><dt id="ientry-idm51124">pg_stat_progress_create_index, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING">CREATE INDEX Progress Reporting</a></dt><dt id="ientry-idm51133">pg_stat_progress_vacuum, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="progress-reporting.html#VACUUM-PROGRESS-REPORTING">VACUUM Progress Reporting</a></dt><dt id="ientry-idm51084">pg_stat_recovery_prefetch, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-RECOVERY-PREFETCH">pg_stat_recovery_prefetch</a></dt><dt id="ientry-idm51068">pg_stat_replication, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW">pg_stat_replication</a></dt><dt id="ientry-idm51371">pg_stat_replication_slots, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-SLOTS-VIEW">pg_stat_replication_slots</a></dt><dt id="ientry-idm54562">pg_stat_reset, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54628">pg_stat_reset_replication_slot, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54571">pg_stat_reset_shared, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54599">pg_stat_reset_single_function_counters, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54589">pg_stat_reset_single_table_counters, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54609">pg_stat_reset_slru, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm54639">pg_stat_reset_subscription_stats, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">Statistics Functions</a></dt><dt id="ientry-idm51363">pg_stat_slru, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-SLRU-VIEW">pg_stat_slru</a></dt><dt id="ientry-idm51100">pg_stat_ssl, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-SSL-VIEW">pg_stat_ssl</a></dt><dt id="ientry-idm168974">pg_stat_statements, <a class="indexterm" href="pgstatstatements.html">pg_stat_statements</a></dt><dd><dl><dt>function, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.8">Functions</a></dt></dl></dd><dt id="ientry-idm169416">pg_stat_statements.max configuration parameter, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.9">Configuration Parameters</a></dt><dt id="ientry-idm169470">pg_stat_statements.save configuration parameter, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.9">Configuration Parameters</a></dt><dt id="ientry-idm169428">pg_stat_statements.track configuration parameter, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.9">Configuration Parameters</a></dt><dt id="ientry-idm169458">pg_stat_statements.track_planning configuration parameter, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.9">Configuration Parameters</a></dt><dt id="ientry-idm169442">pg_stat_statements.track_utility configuration parameter, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.9">Configuration Parameters</a></dt><dt id="ientry-idm169342">pg_stat_statements_info, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.7">The pg_stat_statements_info View</a></dt><dt id="ientry-idm169379">pg_stat_statements_reset, <a class="indexterm" href="pgstatstatements.html#id-1.11.7.41.8">Functions</a></dt><dt id="ientry-idm51092">pg_stat_subscription, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION">pg_stat_subscription</a></dt><dt id="ientry-idm51379">pg_stat_subscription_stats, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS">pg_stat_subscription_stats</a></dt><dt id="ientry-idm51266">pg_stat_sys_indexes, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51221">pg_stat_sys_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51346">pg_stat_user_functions, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-USER-FUNCTIONS-VIEW">pg_stat_user_functions</a></dt><dt id="ientry-idm51273">pg_stat_user_indexes, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51228">pg_stat_user_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51189">pg_stat_wal, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-WAL-VIEW">pg_stat_wal</a></dt><dt id="ientry-idm51076">pg_stat_wal_receiver, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a>, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-WAL-RECEIVER-VIEW">pg_stat_wal_receiver</a></dt><dt id="ientry-idm51235">pg_stat_xact_all_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51244">pg_stat_xact_sys_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51354">pg_stat_xact_user_functions, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm51251">pg_stat_xact_user_tables, <a class="indexterm" href="monitoring-stats.html#MONITORING-STATS-VIEWS">Viewing Statistics</a></dt><dt id="ientry-idm133226">pg_subscription, <a class="indexterm" href="catalog-pg-subscription.html">pg_subscription</a></dt><dt id="ientry-idm133346">pg_subscription_rel, <a class="indexterm" href="catalog-pg-subscription-rel.html">pg_subscription_rel</a></dt><dt id="ientry-idm169900">pg_surgery, <a class="indexterm" href="pgsurgery.html">pg_surgery</a></dt><dt id="ientry-idm28830">pg_switch_wal, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm137231">pg_tables, <a class="indexterm" href="view-pg-tables.html">pg_tables</a></dt><dt id="ientry-idm133405">pg_tablespace, <a class="indexterm" href="catalog-pg-tablespace.html">pg_tablespace</a></dt><dt id="ientry-idm27530">pg_tablespace_databases, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27542">pg_tablespace_location, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm29594">pg_tablespace_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm27091">pg_table_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm29585">pg_table_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm43015">pg_temp, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dd><dl><dt>securing functions, <a class="indexterm" href="sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY">Writing SECURITY DEFINER Functions Safely</a></dt></dl></dd><dt id="ientry-idm28692">pg_terminate_backend, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">Server Signaling Functions</a></dt><dt id="ientry-idm126186">pg_test_fsync, <a class="indexterm" href="pgtestfsync.html">pg_test_fsync</a></dt><dt id="ientry-idm126264">pg_test_timing, <a class="indexterm" href="pgtesttiming.html">pg_test_timing</a></dt><dt id="ientry-idm137320">pg_timezone_abbrevs, <a class="indexterm" href="view-pg-timezone-abbrevs.html">pg_timezone_abbrevs</a></dt><dt id="ientry-idm137358">pg_timezone_names, <a class="indexterm" href="view-pg-timezone-names.html">pg_timezone_names</a></dt><dt id="ientry-idm29609">pg_total_relation_size, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">Database Object Management Functions</a></dt><dt id="ientry-idm133460">pg_transform, <a class="indexterm" href="catalog-pg-transform.html">pg_transform</a></dt><dt id="ientry-idm169931">pg_trgm, <a class="indexterm" href="pgtrgm.html">pg_trgm</a></dt><dt id="ientry-idm170182">pg_trgm.similarity_threshold configuration parameter, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.7">GUC Parameters</a></dt><dt id="ientry-idm170203">pg_trgm.strict_word_similarity_threshold configuration parameter, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.7">GUC Parameters</a></dt><dt id="ientry-idm170192">pg_trgm.word_similarity_threshold configuration parameter, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.7">GUC Parameters</a></dt><dt id="ientry-idm133520">pg_trigger, <a class="indexterm" href="catalog-pg-trigger.html">pg_trigger</a></dt><dt id="ientry-idm26477">pg_trigger_depth, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm30218">pg_try_advisory_lock, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30237">pg_try_advisory_lock_shared, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30256">pg_try_advisory_xact_lock, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm30275">pg_try_advisory_xact_lock_shared, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">Advisory Lock Functions</a></dt><dt id="ientry-idm133707">pg_ts_config, <a class="indexterm" href="catalog-pg-ts-config.html">pg_ts_config</a></dt><dt id="ientry-idm27101">pg_ts_config_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm133769">pg_ts_config_map, <a class="indexterm" href="catalog-pg-ts-config-map.html">pg_ts_config_map</a></dt><dt id="ientry-idm133822">pg_ts_dict, <a class="indexterm" href="catalog-pg-ts-dict.html">pg_ts_dict</a></dt><dt id="ientry-idm27111">pg_ts_dict_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm133888">pg_ts_parser, <a class="indexterm" href="catalog-pg-ts-parser.html">pg_ts_parser</a></dt><dt id="ientry-idm27121">pg_ts_parser_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm133974">pg_ts_template, <a class="indexterm" href="catalog-pg-ts-template.html">pg_ts_template</a></dt><dt id="ientry-idm27131">pg_ts_template_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm134033">pg_type, <a class="indexterm" href="catalog-pg-type.html">pg_type</a></dt><dt id="ientry-idm27552">pg_typeof, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27141">pg_type_is_visible, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm126355">pg_upgrade, <a class="indexterm" href="pgupgrade.html">pg_upgrade</a></dt><dt id="ientry-idm137404">pg_user, <a class="indexterm" href="view-pg-user.html">pg_user</a></dt><dt id="ientry-idm134474">pg_user_mapping, <a class="indexterm" href="catalog-pg-user-mapping.html">pg_user_mapping</a></dt><dt id="ientry-idm137479">pg_user_mappings, <a class="indexterm" href="view-pg-user-mappings.html">pg_user_mappings</a></dt><dt id="ientry-idm120494">pg_verifybackup, <a class="indexterm" href="app-pgverifybackup.html">pg_verifybackup</a></dt><dt id="ientry-idm137558">pg_views, <a class="indexterm" href="view-pg-views.html">pg_views</a></dt><dt id="ientry-idm170296">pg_visibility, <a class="indexterm" href="pgvisibility.html">pg_visibility</a></dt><dt id="ientry-idm28086">pg_visible_in_snapshot, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm126848">pg_waldump, <a class="indexterm" href="pgwaldump.html">pg_waldump</a></dt><dt id="ientry-idm28840">pg_walfile_name, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm28850">pg_walfile_name_offset, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm170360">pg_walinspect, <a class="indexterm" href="pgwalinspect.html">pg_walinspect</a></dt><dt id="ientry-idm28864">pg_wal_lsn_diff, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">Backup Control Functions</a></dt><dt id="ientry-idm29010">pg_wal_replay_pause, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm29021">pg_wal_replay_resume, <a class="indexterm" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">Recovery Control Functions</a></dt><dt id="ientry-idm28241">pg_xact_commit_timestamp, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28250">pg_xact_commit_timestamp_origin, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28031">pg_xact_status, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm175294">pg_xlogdump, <a class="indexterm" href="pgxlogdump.html">pg_xlogdump renamed to pg_waldump</a> (see <a href="#ientry-idm126848">pg_waldump</a>)</dt><dt id="ientry-idm33551">phantom read, <a class="indexterm" href="transaction-iso.html">Transaction Isolation</a></dt><dt id="ientry-idm20043">phraseto_tsquery, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES">Parsing Queries</a></dt><dt id="ientry-idm11447">pi, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm74454">PIC, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt id="ientry-idm58945">PID</dt><dd><dl><dt>determining PID of server process</dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt></dl></dd></dl></dd><dt id="ientry-idm60309">pipelining, <a class="indexterm" href="libpq-pipeline-mode.html">Pipeline Mode</a>, <a class="indexterm" href="protocol-flow.html#PROTOCOL-FLOW-PIPELINING">Pipelining</a></dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-pipeline-mode.html">Pipeline Mode</a></dt><dt>protocol specification, <a class="indexterm" href="protocol-flow.html#PROTOCOL-FLOW-PIPELINING">Pipelining</a></dt></dl></dd><dt id="ientry-idm49633">PITR, <a class="indexterm" href="backup.html">Backup and Restore</a></dt><dt id="ientry-idm50255">PITR standby, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm35741">pkg-config, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a></dt><dd><dl><dt>with
+ ecpg, <a class="indexterm" href="ecpg-process.html">Processing Embedded SQL Programs</a></dt><dt>with
+ libpq, <a class="indexterm" href="libpq-build.html">Building libpq Programs</a></dt></dl></dd><dt id="ientry-idm82653">PL/Perl, <a class="indexterm" href="plperl.html">PL/Perl — Perl Procedural Language</a></dt><dt id="ientry-idm83111">PL/PerlU, <a class="indexterm" href="plperl-trusted.html">Trusted and Untrusted PL/Perl</a></dt><dt id="ientry-idm79526">PL/pgSQL, <a class="indexterm" href="plpgsql.html">PL/pgSQL — SQL Procedural Language</a></dt><dt id="ientry-idm83348">PL/Python, <a class="indexterm" href="plpython.html">PL/Python — Python Procedural Language</a></dt><dt id="ientry-idm81938">PL/SQL (Oracle), <a class="indexterm" href="plpgsql-porting.html">Porting from Oracle PL/SQL</a></dt><dd><dl><dt>porting to PL/pgSQL, <a class="indexterm" href="plpgsql-porting.html">Porting from Oracle PL/SQL</a></dt></dl></dd><dt id="ientry-idm82151">PL/Tcl, <a class="indexterm" href="pltcl.html">PL/Tcl — Tcl Procedural Language</a></dt><dt id="ientry-idm20026">plainto_tsquery, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES">Parsing Queries</a></dt><dt id="ientry-idm41402">plan_cache_mode configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm83274">plperl.on_init configuration parameter, <a class="indexterm" href="plperl-under-the-hood.html#PLPERL-CONFIG">Configuration</a></dt><dt id="ientry-idm83305">plperl.on_plperlu_init configuration parameter, <a class="indexterm" href="plperl-under-the-hood.html#PLPERL-CONFIG">Configuration</a></dt><dt id="ientry-idm83299">plperl.on_plperl_init configuration parameter, <a class="indexterm" href="plperl-under-the-hood.html#PLPERL-CONFIG">Configuration</a></dt><dt id="ientry-idm83321">plperl.use_strict configuration parameter, <a class="indexterm" href="plperl-under-the-hood.html#PLPERL-CONFIG">Configuration</a></dt><dt id="ientry-idm81410">plpgsql.check_asserts configuration parameter, <a class="indexterm" href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-ASSERT">Checking Assertions</a></dt><dt id="ientry-idm81712">plpgsql.variable_conflict configuration parameter, <a class="indexterm" href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST">Variable Substitution</a></dt><dt id="ientry-idm82624">pltcl.start_proc configuration parameter, <a class="indexterm" href="pltcl-config.html">PL/Tcl Configuration</a></dt><dt id="ientry-idm82638">pltclu.start_proc configuration parameter, <a class="indexterm" href="pltcl-config.html">PL/Tcl Configuration</a></dt><dt id="ientry-idm8045">point, <a class="indexterm" href="datatype-geometric.html#id-1.5.7.16.5">Points</a>, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm49631">point-in-time recovery, <a class="indexterm" href="backup.html">Backup and Restore</a></dt><dt id="ientry-idm3505">policy, <a class="indexterm" href="ddl-rowsecurity.html">Row Security Policies</a></dt><dt id="ientry-idm8191">polygon, <a class="indexterm" href="datatype-geometric.html#DATATYPE-POLYGON">Polygons</a>, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm73174">polymorphic function, <a class="indexterm" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">Polymorphic Types</a></dt><dt id="ientry-idm73172">polymorphic type, <a class="indexterm" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">Polymorphic Types</a></dt><dt id="ientry-idm13642">popcount (see <a href="#ientry-idm13640">bit_count</a>)</dt><dt id="ientry-idm19083">popen, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm166194">populate_record, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm58242">port, <a class="indexterm" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">Parameter Key Words</a></dt><dt id="ientry-idm38593">port configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm12240">position, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm15768">POSITION_REGEX, <a class="indexterm" href="functions-matching.html#POSIX-VS-XQUERY">Differences from SQL Standard and XQuery</a></dt><dt id="ientry-idm110">POSTGRES, <a class="indexterm" href="history.html#HISTORY-BERKELEY">The Berkeley POSTGRES Project</a></dt><dt id="ientry-idm417">postgres, <a class="indexterm" href="tutorial-arch.html">Architectural Fundamentals</a>, <a class="indexterm" href="server-start.html">Starting the Database Server</a>, <a class="indexterm" href="manage-ag-createdb.html">Creating a Database</a>, <a class="indexterm" href="app-postgres.html">postgres</a></dt><dt id="ientry-idm36938">postgres user, <a class="indexterm" href="postgres-user.html">The PostgreSQL User Account</a></dt><dt id="ientry-idm143">Postgres95, <a class="indexterm" href="history.html#HISTORY-POSTGRES95">Postgres95</a></dt><dt id="ientry-idm38353">postgresql.auto.conf, <a class="indexterm" href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE">Parameter Interaction via the Configuration File</a></dt><dt id="ientry-idm38337">postgresql.conf, <a class="indexterm" href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE">Parameter Interaction via the Configuration File</a></dt><dt id="ientry-idm170435">postgres_fdw, <a class="indexterm" href="postgres-fdw.html">postgres_fdw</a></dt><dt id="ientry-idm170909">postgres_fdw.application_name configuration parameter, <a class="indexterm" href="postgres-fdw.html#id-1.11.7.47.18">Configuration Parameters</a></dt><dt id="ientry-idm127544">postmaster, <a class="indexterm" href="app-postmaster.html">postmaster</a></dt><dt id="ientry-idm44431">post_auth_delay configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm11459">power, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm58940">PQbackendPID, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm59703">PQbinaryTuples, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dd><dl><dt>with COPY, <a class="indexterm" href="libpq-copy.html">Functions Associated with the COPY Command</a></dt></dl></dd><dt id="ientry-idm60609">PQcancel, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt><dt id="ientry-idm59567">PQclear, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm61026">PQclientEncoding, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm59799">PQcmdStatus, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">Retrieving Other Result Information</a></dt><dt id="ientry-idm59811">PQcmdTuples, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">Retrieving Other Result Information</a></dt><dt id="ientry-idm57890">PQconndefaults, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57715">PQconnectdb, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57675">PQconnectdbParams, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm58958">PQconnectionNeedsPassword, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58967">PQconnectionUsedPassword, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm57768">PQconnectPoll, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57764">PQconnectStart, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57760">PQconnectStartParams, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57906">PQconninfo, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm61156">PQconninfoFree, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm57920">PQconninfoParse, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm60209">PQconsumeInput, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm61255">PQcopyResult, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm58708">PQdb, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm59258">PQdescribePortal, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm59236">PQdescribePrepared, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm61199">PQencryptPassword, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm61168">PQencryptPasswordConn, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm60990">PQendcopy, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">Obsolete Functions for COPY</a></dt><dt id="ientry-idm60463">PQenterPipelineMode, <a class="indexterm" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">Functions Associated with Pipeline Mode</a></dt><dt id="ientry-idm58914">PQerrorMessage, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm60014">PQescapeBytea, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm59985">PQescapeByteaConn, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm59905">PQescapeIdentifier, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm59874">PQescapeLiteral, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm59964">PQescapeString, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm59930">PQescapeStringConn, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm59082">PQexec, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm59103">PQexecParams, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm59222">PQexecPrepared, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm60473">PQexitPipelineMode, <a class="indexterm" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">Functions Associated with Pipeline Mode</a></dt><dt id="ientry-idm59660">PQfformat, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dd><dl><dt>with COPY, <a class="indexterm" href="libpq-copy.html">Functions Associated with the COPY Command</a></dt></dl></dd><dt id="ientry-idm57952">PQfinish, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm61235">PQfireResultCreateEvents, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm60291">PQflush, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm59683">PQfmod, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm60651">PQfn, <a class="indexterm" href="libpq-fastpath.html">The Fast-Path Interface</a></dt><dt id="ientry-idm59606">PQfname, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59618">PQfnumber, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm60597">PQfreeCancel, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt><dt id="ientry-idm61139">PQfreemem, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm59693">PQfsize, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59636">PQftable, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59651">PQftablecol, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59669">PQftype, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm60577">PQgetCancel, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt><dt id="ientry-idm60872">PQgetCopyData, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-RECEIVE">Functions for Receiving COPY Data</a></dt><dt id="ientry-idm59738">PQgetisnull, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59751">PQgetlength, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm60913">PQgetline, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">Obsolete Functions for COPY</a></dt><dt id="ientry-idm60931">PQgetlineAsync, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">Obsolete Functions for COPY</a></dt><dt id="ientry-idm60164">PQgetResult, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm59058">PQgetssl, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58071">PQgetSSLKeyPassHook_OpenSSL, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm59717">PQgetvalue, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm58737">PQhost, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58761">PQhostaddr, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm62236">PQinitOpenSSL, <a class="indexterm" href="libpq-ssl.html#LIBPQ-SSL-INITIALIZE">SSL Library Initialization</a></dt><dt id="ientry-idm62255">PQinitSSL, <a class="indexterm" href="libpq-ssl.html#LIBPQ-SSL-INITIALIZE">SSL Library Initialization</a></dt><dt id="ientry-idm61575">PQinstanceData, <a class="indexterm" href="libpq-events.html#LIBPQ-EVENTS-FUNCS">Event Support Functions</a></dt><dt id="ientry-idm60229">PQisBusy, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm60282">PQisnonblocking, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm62286">PQisthreadsafe, <a class="indexterm" href="libpq-threading.html">Behavior in Threaded Programs</a></dt><dt id="ientry-idm61332">PQlibVersion, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dd><dl><dt>(see also <a href="#ientry-idm58900">PQserverVersion</a>)</dt></dl></dd><dt id="ientry-idm61212">PQmakeEmptyPGresult, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm59598">PQnfields, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dd><dl><dt>with COPY, <a class="indexterm" href="libpq-copy.html">Functions Associated with the COPY Command</a></dt></dl></dd><dt id="ientry-idm60712">PQnotifies, <a class="indexterm" href="libpq-notify.html">Asynchronous Notification</a></dt><dt id="ientry-idm59764">PQnparams, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59587">PQntuples, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm59858">PQoidStatus, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">Retrieving Other Result Information</a></dt><dt id="ientry-idm59840">PQoidValue, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">Retrieving Other Result Information</a></dt><dt id="ientry-idm58804">PQoptions, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58849">PQparameterStatus, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm59774">PQparamtype, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm58724">PQpass, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58028">PQping, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57997">PQpingParams, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm60430">PQpipelineStatus, <a class="indexterm" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">Functions Associated with Pipeline Mode</a></dt><dt id="ientry-idm60484">PQpipelineSync, <a class="indexterm" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">Functions Associated with Pipeline Mode</a></dt><dt id="ientry-idm58775">PQport, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm59184">PQprepare, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm59784">PQprint, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">Retrieving Query Result Information</a></dt><dt id="ientry-idm58891">PQprotocolVersion, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm60821">PQputCopyData, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-SEND">Functions for Sending COPY Data</a></dt><dt id="ientry-idm60839">PQputCopyEnd, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-SEND">Functions for Sending COPY Data</a></dt><dt id="ientry-idm60958">PQputline, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">Obsolete Functions for COPY</a></dt><dt id="ientry-idm60979">PQputnbytes, <a class="indexterm" href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">Obsolete Functions for COPY</a></dt><dt id="ientry-idm61542">PQregisterEventProc, <a class="indexterm" href="libpq-events.html#LIBPQ-EVENTS-FUNCS">Event Support Functions</a></dt><dt id="ientry-idm60629">PQrequestCancel, <a class="indexterm" href="libpq-cancel.html">Canceling Queries in Progress</a></dt><dt id="ientry-idm57967">PQreset, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57980">PQresetPoll, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57976">PQresetStart, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm59382">PQresStatus, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm61306">PQresultAlloc, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm59428">PQresultErrorField, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm59391">PQresultErrorMessage, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm61603">PQresultInstanceData, <a class="indexterm" href="libpq-events.html#LIBPQ-EVENTS-FUNCS">Event Support Functions</a></dt><dt id="ientry-idm61319">PQresultMemorySize, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm61587">PQresultSetInstanceData, <a class="indexterm" href="libpq-events.html#LIBPQ-EVENTS-FUNCS">Event Support Functions</a></dt><dt id="ientry-idm59289">PQresultStatus, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm59410">PQresultVerboseErrorMessage, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-MAIN">Main Functions</a></dt><dt id="ientry-idm60153">PQsendDescribePortal, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm60142">PQsendDescribePrepared, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm60496">PQsendFlushRequest, <a class="indexterm" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">Functions Associated with Pipeline Mode</a></dt><dt id="ientry-idm60121">PQsendPrepare, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm60096">PQsendQuery, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm60110">PQsendQueryParams, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm60132">PQsendQueryPrepared, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm58900">PQserverVersion, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm61038">PQsetClientEncoding, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm57748">PQsetdb, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm57728">PQsetdbLogin, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm61071">PQsetErrorContextVisibility, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm61051">PQsetErrorVerbosity, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm61561">PQsetInstanceData, <a class="indexterm" href="libpq-events.html#LIBPQ-EVENTS-FUNCS">Event Support Functions</a></dt><dt id="ientry-idm60263">PQsetnonblocking, <a class="indexterm" href="libpq-async.html">Asynchronous Command Processing</a></dt><dt id="ientry-idm61367">PQsetNoticeProcessor, <a class="indexterm" href="libpq-notice-processing.html">Notice Processing</a></dt><dt id="ientry-idm61362">PQsetNoticeReceiver, <a class="indexterm" href="libpq-notice-processing.html">Notice Processing</a></dt><dt id="ientry-idm61274">PQsetResultAttrs, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm60552">PQsetSingleRowMode, <a class="indexterm" href="libpq-single-row-mode.html">Retrieving Query Results Row-by-Row</a></dt><dt id="ientry-idm58040">PQsetSSLKeyPassHook_OpenSSL, <a class="indexterm" href="libpq-connect.html">Database Connection Control Functions</a></dt><dt id="ientry-idm61111">PQsetTraceFlags, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm61289">PQsetvalue, <a class="indexterm" href="libpq-misc.html">Miscellaneous Functions</a></dt><dt id="ientry-idm58932">PQsocket, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58986">PQsslAttribute, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm59034">PQsslAttributeNames, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58978">PQsslInUse, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm59042">PQsslStruct, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58815">PQstatus, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm61095">PQtrace, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm58835">PQtransactionStatus, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm58793">PQtty, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm60033">PQunescapeBytea, <a class="indexterm" href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">Escaping Strings for Inclusion in SQL Commands</a></dt><dt id="ientry-idm61126">PQuntrace, <a class="indexterm" href="libpq-control.html">Control Functions</a></dt><dt id="ientry-idm58716">PQuser, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt id="ientry-idm33735">predicate locking, <a class="indexterm" href="transaction-iso.html#XACT-SERIALIZABLE">Serializable Isolation Level</a></dt><dt id="ientry-idm109110">PREPARE, <a class="indexterm" href="sql-prepare.html">PREPARE</a></dt><dt id="ientry-idm109225">PREPARE TRANSACTION, <a class="indexterm" href="sql-prepare-transaction.html">PREPARE TRANSACTION</a></dt><dt id="ientry-idm103762">prepared statements, <a class="indexterm" href="sql-deallocate.html">DEALLOCATE</a>, <a class="indexterm" href="sql-execute.html">EXECUTE</a>, <a class="indexterm" href="sql-explain.html">EXPLAIN</a>, <a class="indexterm" href="sql-prepare.html">PREPARE</a></dt><dd><dl><dt>creating, <a class="indexterm" href="sql-prepare.html">PREPARE</a></dt><dt>executing, <a class="indexterm" href="sql-execute.html">EXECUTE</a></dt><dt>removing, <a class="indexterm" href="sql-deallocate.html">DEALLOCATE</a></dt><dt>showing the query plan, <a class="indexterm" href="sql-explain.html">EXPLAIN</a></dt></dl></dd><dt id="ientry-idm81759">preparing a query</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING">Plan Caching</a></dt><dt>in PL/Python, <a class="indexterm" href="plpython-database.html#id-1.8.11.14.3">Database Access Functions</a></dt><dt>in PL/Tcl, <a class="indexterm" href="pltcl-dbaccess.html">Database Access from PL/Tcl</a></dt></dl></dd><dt id="ientry-idm44440">pre_auth_delay configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm2716">primary key, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-PRIMARY-KEYS">Primary Keys</a></dt><dt id="ientry-idm40638">primary_conninfo configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40658">primary_slot_name configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm3023">privilege, <a class="indexterm" href="ddl-priv.html">Privileges</a>, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PRIV">Schemas and Privileges</a>, <a class="indexterm" href="rules-privileges.html">Rules and Privileges</a>, <a class="indexterm" href="rules-privileges.html">Rules and Privileges</a></dt><dd><dl><dt>querying, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt>with rules, <a class="indexterm" href="rules-privileges.html">Rules and Privileges</a></dt><dt>for schemas, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PRIV">Schemas and Privileges</a></dt><dt>with views, <a class="indexterm" href="rules-privileges.html">Rules and Privileges</a></dt></dl></dd><dt id="ientry-idm79416">procedural language, <a class="indexterm" href="xplang.html">Procedural Languages</a>, <a class="indexterm" href="plhandler.html">Writing a Procedural Language Handler</a></dt><dd><dl><dt>externally maintained, <a class="indexterm" href="external-pl.html">Procedural Languages</a></dt><dt>handler for, <a class="indexterm" href="plhandler.html">Writing a Procedural Language Handler</a></dt></dl></dd><dt id="ientry-idm73378">procedure, <a class="indexterm" href="xproc.html">User-Defined Procedures</a></dt><dd><dl><dt>user-defined, <a class="indexterm" href="xproc.html">User-Defined Procedures</a></dt></dl></dd><dt id="ientry-idm73607">procedures</dt><dd><dl><dt>output parameter, <a class="indexterm" href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS-PROC">SQL Procedures with Output Parameters</a></dt></dl></dd><dt id="ientry-idm40670">promote_trigger_file configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm137608">protocol, <a class="indexterm" href="protocol.html">Frontend/Backend Protocol</a></dt><dd><dl><dt>frontend-backend, <a class="indexterm" href="protocol.html">Frontend/Backend Protocol</a></dt></dl></dd><dt id="ientry-idm50957">ps, <a class="indexterm" href="monitoring-ps.html">Standard Unix Tools</a></dt><dd><dl><dt>to monitor activity, <a class="indexterm" href="monitoring-ps.html">Standard Unix Tools</a></dt></dl></dd><dt id="ientry-idm490">psql, <a class="indexterm" href="tutorial-accessdb.html">Accessing a Database</a>, <a class="indexterm" href="app-psql.html">psql</a></dt><dt id="ientry-idm83350">Python, <a class="indexterm" href="plpython.html">PL/Python — Python Procedural Language</a></dt></dl></div><div class="indexdiv" id="indexdiv-Q"><h3>Q</h3><dl><dt id="ientry-idm3648">qualified name, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CREATE">Creating a Schema</a></dt><dt id="ientry-idm700">query, <a class="indexterm" href="tutorial-select.html">Querying a Table</a>, <a class="indexterm" href="queries.html">Queries</a></dt><dt id="ientry-idm34380">query plan, <a class="indexterm" href="using-explain.html">Using EXPLAIN</a></dt><dt id="ientry-idm78691">query tree, <a class="indexterm" href="querytree.html">The Query Tree</a></dt><dt id="ientry-idm20081">querytree, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY">Manipulating Queries</a></dt><dt id="ientry-idm1234">quotation marks</dt><dd><dl><dt>and identifiers, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt><dt>escaping, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS">String Constants</a></dt></dl></dd><dt id="ientry-idm43960">quote_all_identifiers configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm12646">quote_ident, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt><dt>use in PL/pgSQL, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN">Executing Dynamic Commands</a></dt></dl></dd><dt id="ientry-idm12660">quote_literal, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt><dt>use in PL/pgSQL, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN">Executing Dynamic Commands</a></dt></dl></dd><dt id="ientry-idm12686">quote_nullable, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">Utility Functions in PL/Perl</a></dt><dt>use in PL/pgSQL, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN">Executing Dynamic Commands</a></dt></dl></dd></dl></div><div class="indexdiv" id="indexdiv-R"><h3>R</h3><dl><dt id="ientry-idm11483">radians, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm19095">radius, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm45859">RADIUS, <a class="indexterm" href="auth-radius.html">RADIUS Authentication</a></dt><dt id="ientry-idm81266">RAISE</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-RAISE">Reporting Errors and Messages</a></dt></dl></dd><dt id="ientry-idm11689">random, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm41083">random_page_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm78717">range table, <a class="indexterm" href="querytree.html">The Query Tree</a></dt><dt id="ientry-idm9619">range type, <a class="indexterm" href="rangetypes.html">Range Types</a></dt><dd><dl><dt>exclude, <a class="indexterm" href="rangetypes.html#RANGETYPES-CONSTRAINT">Constraints on Ranges</a></dt><dt>indexes on, <a class="indexterm" href="rangetypes.html#RANGETYPES-INDEXING">Indexing</a></dt></dl></dd><dt id="ientry-idm24825">range_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm24841">range_intersect_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm24398">range_merge, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm25427">rank, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dd><dl><dt>hypothetical, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm33617">read committed, <a class="indexterm" href="transaction-iso.html#XACT-READ-COMMITTED">Read Committed Isolation Level</a></dt><dt id="ientry-idm43164">read-only transaction, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dd><dl><dt>setting, <a class="indexterm" href="sql-set-transaction.html">SET TRANSACTION</a></dt><dt>setting default, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt></dl></dd><dt id="ientry-idm35275">readline, <a class="indexterm" href="install-requirements.html">Requirements</a></dt><dt id="ientry-idm123454">Readline</dt><dd><dl><dt>in psql, <a class="indexterm" href="app-psql.html#APP-PSQL-READLINE">Command-Line Editing</a></dt></dl></dd><dt id="ientry-idm138376">READ_REPLICATION_SLOT, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm6369">real, <a class="indexterm" href="datatype-numeric.html#DATATYPE-FLOAT">Floating-Point Types</a></dt><dt id="ientry-idm109312">REASSIGN OWNED, <a class="indexterm" href="sql-reassign-owned.html">REASSIGN OWNED</a></dt><dt id="ientry-idm10124">record, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm175253">recovery.conf, <a class="indexterm" href="recovery-config.html">recovery.conf file merged into postgresql.conf</a></dt><dt id="ientry-idm40244">recovery.signal, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">Archive Recovery</a></dt><dt id="ientry-idm40300">recovery_end_command configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">Archive Recovery</a></dt><dt id="ientry-idm44078">recovery_init_sync_method configuration parameter, <a class="indexterm" href="runtime-config-error-handling.html">Error Handling</a></dt><dt id="ientry-idm40784">recovery_min_apply_delay configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40203">recovery_prefetch configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY">Recovery</a></dt><dt id="ientry-idm40324">recovery_target configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40413">recovery_target_action configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40384">recovery_target_inclusive configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40370">recovery_target_lsn configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40335">recovery_target_name configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40345">recovery_target_time configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40399">recovery_target_timeline configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm40360">recovery_target_xid configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">Recovery Target</a></dt><dt id="ientry-idm8131">rectangle, <a class="indexterm" href="datatype-geometric.html#id-1.5.7.16.8">Boxes</a></dt><dt id="ientry-idm5604">RECURSIVE, <a class="indexterm" href="sql-createview.html">CREATE VIEW</a></dt><dd><dl><dt>in common table expressions, <a class="indexterm" href="queries-with.html#QUERIES-WITH-RECURSIVE">Recursive Queries</a></dt><dt>in views, <a class="indexterm" href="sql-createview.html">CREATE VIEW</a></dt></dl></dd><dt id="ientry-idm41416">recursive_worktable_factor configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">Other Planner Options</a></dt><dt id="ientry-idm949">referential integrity, <a class="indexterm" href="tutorial-fk.html">Foreign Keys</a>, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-FK">Foreign Keys</a></dt><dt id="ientry-idm109377">REFRESH MATERIALIZED VIEW, <a class="indexterm" href="sql-refreshmaterializedview.html">REFRESH MATERIALIZED VIEW</a></dt><dt id="ientry-idm9871">regclass, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9873">regcollation, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9875">regconfig, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9877">regdictionary, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm12712">regexp_count, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12734">regexp_instr, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12766">regexp_like, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12786">regexp_match, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12806">regexp_matches, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12828">regexp_replace, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12877">regexp_split_to_array, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12896">regexp_split_to_table, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm12916">regexp_substr, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm9879">regnamespace, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9881">regoper, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9883">regoperator, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9885">regproc, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9887">regprocedure, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm25084">regression intercept, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25114">regression slope, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm35485">regression test, <a class="indexterm" href="install-procedure.html">Installation Procedure</a></dt><dt id="ientry-idm57252">regression tests, <a class="indexterm" href="regress.html">Regression Tests</a></dt><dt id="ientry-idm9889">regrole, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm25039">regr_avgx, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25055">regr_avgy, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25071">regr_count, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25086">regr_intercept, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25101">regr_r2, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25116">regr_slope, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25131">regr_sxx, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25149">regr_sxy, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25169">regr_syy, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm9891">regtype, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm14461">regular expression, <a class="indexterm" href="functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP">SIMILAR TO Regular Expressions</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dd><dl><dt>(see also <a href="#ientry-idm14358">pattern matching</a>)</dt></dl></dd><dt id="ientry-idm46766">regular expressions</dt><dd><dl><dt>and locales, <a class="indexterm" href="locale.html#id-1.6.11.3.5">Behavior</a></dt></dl></dd><dt id="ientry-idm49306">reindex, <a class="indexterm" href="routine-reindex.html">Routine Reindexing</a></dt><dt id="ientry-idm109445">REINDEX, <a class="indexterm" href="sql-reindex.html">REINDEX</a></dt><dt id="ientry-idm123727">reindexdb, <a class="indexterm" href="app-reindexdb.html">reindexdb</a></dt><dt id="ientry-idm603">relation, <a class="indexterm" href="tutorial-concepts.html">Concepts</a></dt><dt id="ientry-idm597">relational database, <a class="indexterm" href="tutorial-concepts.html">Concepts</a></dt><dt id="ientry-idm109705">RELEASE SAVEPOINT, <a class="indexterm" href="sql-release-savepoint.html">RELEASE SAVEPOINT</a></dt><dt id="ientry-idm44718">remove_temp_files_after_crash configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm12947">repeat, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm33698">repeatable read, <a class="indexterm" href="transaction-iso.html#XACT-REPEATABLE-READ">Repeatable Read Isolation Level</a></dt><dt id="ientry-idm12964">replace, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm50013">replication, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm87718">Replication Origins, <a class="indexterm" href="replication-origins.html">Replication Progress Tracking</a></dt><dt id="ientry-idm87716">Replication Progress Tracking, <a class="indexterm" href="replication-origins.html">Replication Progress Tracking</a></dt><dt id="ientry-idm50409">replication slot</dt><dd><dl><dt>logical replication, <a class="indexterm" href="logicaldecoding-explanation.html#LOGICALDECODING-REPLICATION-SLOTS">Replication Slots</a></dt><dt>streaming replication, <a class="indexterm" href="warm-standby.html#STREAMING-REPLICATION-SLOTS">Replication Slots</a></dt></dl></dd><dt id="ientry-idm81269">reporting errors</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-RAISE">Reporting Errors and Messages</a></dt></dl></dd><dt id="ientry-idm109765">RESET, <a class="indexterm" href="sql-reset.html">RESET</a></dt><dt id="ientry-idm56419">restartpoint, <a class="indexterm" href="wal-configuration.html">WAL Configuration</a></dt><dt id="ientry-idm44052">restart_after_crash configuration parameter, <a class="indexterm" href="runtime-config-error-handling.html">Error Handling</a></dt><dt id="ientry-idm40255">restore_command configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">Archive Recovery</a></dt><dt id="ientry-idm2773">RESTRICT, <a class="indexterm" href="ddl-depend.html">Dependency Tracking</a></dt><dd><dl><dt>with DROP, <a class="indexterm" href="ddl-depend.html">Dependency Tracking</a></dt><dt>foreign key action, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-FK">Foreign Keys</a></dt></dl></dd><dt id="ientry-idm34315">retryable error, <a class="indexterm" href="mvcc-serialization-failure-handling.html">Serialization Failure Handling</a></dt><dt id="ientry-idm80350">RETURN NEXT</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#id-1.8.8.8.3.4">RETURN NEXT and RETURN QUERY</a></dt></dl></dd><dt id="ientry-idm80353">RETURN QUERY</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#id-1.8.8.8.3.4">RETURN NEXT and RETURN QUERY</a></dt></dl></dd><dt id="ientry-idm4484">RETURNING, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a></dt><dt id="ientry-idm79986">RETURNING INTO, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW">Executing a Command with a Single-Row Result</a></dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW">Executing a Command with a Single-Row Result</a></dt></dl></dd><dt id="ientry-idm12984">reverse, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm3032">REVOKE, <a class="indexterm" href="ddl-priv.html">Privileges</a>, <a class="indexterm" href="sql-revoke.html">REVOKE</a></dt><dt id="ientry-idm12996">right, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm4724">right join, <a class="indexterm" href="queries-table-expressions.html#QUERIES-JOIN">Joined Tables</a></dt><dt id="ientry-idm45993">role, <a class="indexterm" href="database-roles.html">Database Roles</a>, <a class="indexterm" href="role-membership.html">Role Membership</a>, <a class="indexterm" href="predefined-roles.html">Predefined Roles</a></dt><dd><dl><dt>applicable, <a class="indexterm" href="infoschema-applicable-roles.html">applicable_roles</a></dt><dt>enabled, <a class="indexterm" href="infoschema-enabled-roles.html">enabled_roles</a></dt><dt>membership in, <a class="indexterm" href="role-membership.html">Role Membership</a></dt><dt>privilege to bypass, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dt>privilege to create, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dt>privilege to inherit, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dt>privilege to initiate replication, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dt>privilege to limit connection, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt></dl></dd><dt id="ientry-idm109982">ROLLBACK, <a class="indexterm" href="sql-rollback.html">ROLLBACK</a></dt><dt id="ientry-idm123140">rollback</dt><dd><dl><dt>psql, <a class="indexterm" href="app-psql.html#APP-PSQL-VARIABLES">Variables</a></dt></dl></dd><dt id="ientry-idm110043">ROLLBACK PREPARED, <a class="indexterm" href="sql-rollback-prepared.html">ROLLBACK PREPARED</a></dt><dt id="ientry-idm110092">ROLLBACK TO SAVEPOINT, <a class="indexterm" href="sql-rollback-to.html">ROLLBACK TO SAVEPOINT</a></dt><dt id="ientry-idm5148">ROLLUP, <a class="indexterm" href="queries-table-expressions.html#QUERIES-GROUPING-SETS">GROUPING SETS, CUBE, and ROLLUP</a></dt><dt id="ientry-idm11495">round, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm73404">routine, <a class="indexterm" href="xproc.html">User-Defined Procedures</a></dt><dt id="ientry-idm48900">routine maintenance, <a class="indexterm" href="maintenance.html">Routine Database Maintenance Tasks</a></dt><dt id="ientry-idm613">row, <a class="indexterm" href="tutorial-concepts.html">Concepts</a>, <a class="indexterm" href="ddl-basics.html">Table Basics</a></dt><dt id="ientry-idm2319">ROW, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">Row Constructors</a></dt><dt id="ientry-idm148440">row estimation, <a class="indexterm" href="row-estimation-examples.html">Row Estimation Examples</a></dt><dd><dl><dt>multivariate, <a class="indexterm" href="multivariate-statistics-examples.html">Multivariate Statistics Examples</a></dt><dt>planner, <a class="indexterm" href="row-estimation-examples.html">Row Estimation Examples</a></dt></dl></dd><dt id="ientry-idm2316">row type, <a class="indexterm" href="rowtypes.html">Composite Types</a></dt><dd><dl><dt>constructor, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">Row Constructors</a></dt></dl></dd><dt id="ientry-idm3503">row-level security, <a class="indexterm" href="ddl-rowsecurity.html">Row Security Policies</a></dt><dt id="ientry-idm25915">row-wise comparison, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm25546">row_number, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt id="ientry-idm43036">row_security configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm26852">row_security_active, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm21735">row_to_json, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm13014">rpad, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm13037">rtrim, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm78680">rule, <a class="indexterm" href="rules.html">The Rule System</a>, <a class="indexterm" href="rules-views.html">Views and the Rule System</a>, <a class="indexterm" href="rules-views.html#RULES-SELECT">How SELECT Rules Work</a>, <a class="indexterm" href="rules-materializedviews.html">Materialized Views</a>, <a class="indexterm" href="rules-update.html">Rules on INSERT, UPDATE, and DELETE</a>, <a class="indexterm" href="rules-update.html">Rules on INSERT, UPDATE, and DELETE</a>, <a class="indexterm" href="rules-update.html">Rules on INSERT, UPDATE, and DELETE</a>, <a class="indexterm" href="rules-triggers.html">Rules Versus Triggers</a></dt><dd><dl><dt>and materialized views, <a class="indexterm" href="rules-materializedviews.html">Materialized Views</a></dt><dt>and views, <a class="indexterm" href="rules-views.html">Views and the Rule System</a></dt><dt>for DELETE, <a class="indexterm" href="rules-update.html">Rules on INSERT, UPDATE, and DELETE</a></dt><dt>for INSERT, <a class="indexterm" href="rules-update.html">Rules on INSERT, UPDATE, and DELETE</a></dt><dt>for SELECT, <a class="indexterm" href="rules-views.html#RULES-SELECT">How SELECT Rules Work</a></dt><dt>compared with triggers, <a class="indexterm" href="rules-triggers.html">Rules Versus Triggers</a></dt><dt>for UPDATE, <a class="indexterm" href="rules-update.html">Rules on INSERT, UPDATE, and DELETE</a></dt></dl></dd></dl></div><div class="indexdiv" id="indexdiv-S"><h3>S</h3><dl><dt id="ientry-idm110166">SAVEPOINT, <a class="indexterm" href="sql-savepoint.html">SAVEPOINT</a></dt><dt id="ientry-idm109707">savepoints, <a class="indexterm" href="sql-release-savepoint.html">RELEASE SAVEPOINT</a>, <a class="indexterm" href="sql-rollback-to.html">ROLLBACK TO SAVEPOINT</a>, <a class="indexterm" href="sql-savepoint.html">SAVEPOINT</a></dt><dd><dl><dt>defining, <a class="indexterm" href="sql-savepoint.html">SAVEPOINT</a></dt><dt>releasing, <a class="indexterm" href="sql-release-savepoint.html">RELEASE SAVEPOINT</a></dt><dt>rolling back, <a class="indexterm" href="sql-rollback-to.html">ROLLBACK TO SAVEPOINT</a></dt></dl></dd><dt id="ientry-idm1747">scalar (see <a href="#ientry-idm1742">expression</a>)</dt><dt id="ientry-idm11532">scale, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm3619">schema, <a class="indexterm" href="ddl-schemas.html">Schemas</a>, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CREATE">Creating a Schema</a>, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PUBLIC">The Public Schema</a>, <a class="indexterm" href="manage-ag-overview.html">Overview</a></dt><dd><dl><dt>creating, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CREATE">Creating a Schema</a></dt><dt>current, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PATH">The Schema Search Path</a>, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt>public, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PUBLIC">The Public Schema</a></dt><dt>removing, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CREATE">Creating a Schema</a></dt></dl></dd><dt id="ientry-idm45418">SCRAM, <a class="indexterm" href="auth-password.html">Password Authentication</a></dt><dt id="ientry-idm3693">search path, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PATH">The Schema Search Path</a></dt><dd><dl><dt>current, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt>object visibility, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt></dl></dd><dt id="ientry-idm3712">search_path configuration parameter, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PATH">The Schema Search Path</a>, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dd><dl><dt>use in securing functions, <a class="indexterm" href="sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY">Writing SECURITY DEFINER Functions Safely</a></dt></dl></dd><dt id="ientry-idm110232">SECURITY LABEL, <a class="indexterm" href="sql-security-label.html">SECURITY LABEL</a></dt><dt id="ientry-idm165373">sec_to_gc, <a class="indexterm" href="earthdistance.html#id-1.11.7.24.7">Cube-Based Earth Distances</a></dt><dt id="ientry-idm171001">seg, <a class="indexterm" href="seg.html">seg</a></dt><dt id="ientry-idm44230">segment_size configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm702">SELECT, <a class="indexterm" href="tutorial-select.html">Querying a Table</a>, <a class="indexterm" href="queries.html">Queries</a>, <a class="indexterm" href="typeconv-select.html">SELECT Output Columns</a>, <a class="indexterm" href="sql-select.html">SELECT</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-select.html">SELECT Output Columns</a></dt><dt>select list, <a class="indexterm" href="queries-select-lists.html">Select Lists</a></dt></dl></dd><dt id="ientry-idm79983">SELECT INTO, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW">Executing a Command with a Single-Row Result</a>, <a class="indexterm" href="sql-selectinto.html">SELECT INTO</a></dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW">Executing a Command with a Single-Row Result</a></dt></dl></dd><dt id="ientry-idm37254">semaphores, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt id="ientry-idm171254">sepgsql, <a class="indexterm" href="sepgsql.html">sepgsql</a></dt><dt id="ientry-idm171371">sepgsql.debug_audit configuration parameter, <a class="indexterm" href="sepgsql.html#SEPGSQL-PARAMETERS">GUC Parameters</a></dt><dt id="ientry-idm171358">sepgsql.permissive configuration parameter, <a class="indexterm" href="sepgsql.html#SEPGSQL-PARAMETERS">GUC Parameters</a></dt><dt id="ientry-idm6471">sequence, <a class="indexterm" href="functions-sequence.html">Sequence Manipulation Functions</a></dt><dd><dl><dt>and serial type, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt></dl></dd><dt id="ientry-idm41031">sequential scan, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">Planner Method Configuration</a></dt><dt id="ientry-idm41073">seq_page_cost configuration parameter, <a class="indexterm" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">Planner Cost Constants</a></dt><dt id="ientry-idm6458">serial, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt><dt id="ientry-idm6462">serial2, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt><dt id="ientry-idm6464">serial4, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt><dt id="ientry-idm6466">serial8, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt><dt id="ientry-idm33733">serializable, <a class="indexterm" href="transaction-iso.html#XACT-SERIALIZABLE">Serializable Isolation Level</a></dt><dt id="ientry-idm33510">Serializable Snapshot Isolation, <a class="indexterm" href="mvcc-intro.html">Introduction</a></dt><dt id="ientry-idm33557">serialization anomaly, <a class="indexterm" href="transaction-iso.html">Transaction Isolation</a>, <a class="indexterm" href="transaction-iso.html#XACT-SERIALIZABLE">Serializable Isolation Level</a></dt><dt id="ientry-idm34313">serialization failure, <a class="indexterm" href="mvcc-serialization-failure-handling.html">Serialization Failure Handling</a></dt><dt id="ientry-idm41427">server log, <a class="indexterm" href="runtime-config-logging.html">Error Reporting and Logging</a>, <a class="indexterm" href="logfile-maintenance.html">Log File Maintenance</a></dt><dd><dl><dt>log file maintenance, <a class="indexterm" href="logfile-maintenance.html">Log File Maintenance</a></dt></dl></dd><dt id="ientry-idm58583">Server Name Indication, <a class="indexterm" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">Parameter Key Words</a></dt><dt id="ientry-idm37909">server spoofing, <a class="indexterm" href="preventing-server-spoofing.html">Preventing Server Spoofing</a></dt><dt id="ientry-idm44242">server_encoding configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44254">server_version configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44264">server_version_num configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm43715">session_preload_libraries configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">Shared Library Preloading</a></dt><dt id="ientry-idm43236">session_replication_role configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm26486">session_user, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28555">SET, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SET">Configuration Settings Functions</a>, <a class="indexterm" href="sql-set.html">SET</a></dt><dt id="ientry-idm112001">SET CONSTRAINTS, <a class="indexterm" href="sql-set-constraints.html">SET CONSTRAINTS</a></dt><dt id="ientry-idm5357">set difference, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a></dt><dt id="ientry-idm5355">set intersection, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a></dt><dt id="ientry-idm5359">set operation, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a></dt><dt id="ientry-idm26084">set returning functions, <a class="indexterm" href="functions-srf.html">Set Returning Functions</a></dt><dd><dl><dt>functions, <a class="indexterm" href="functions-srf.html">Set Returning Functions</a></dt></dl></dd><dt id="ientry-idm112063">SET ROLE, <a class="indexterm" href="sql-set-role.html">SET ROLE</a></dt><dt id="ientry-idm112142">SET SESSION AUTHORIZATION, <a class="indexterm" href="sql-set-session-authorization.html">SET SESSION AUTHORIZATION</a></dt><dt id="ientry-idm112199">SET TRANSACTION, <a class="indexterm" href="sql-set-transaction.html">SET TRANSACTION</a></dt><dt id="ientry-idm5353">set union, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a></dt><dt id="ientry-idm43451">SET XML OPTION, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm11700">setseed, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm23169">setval, <a class="indexterm" href="functions-sequence.html">Sequence Manipulation Functions</a></dt><dt id="ientry-idm20095">setweight, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR">Manipulating Documents</a></dt><dd><dl><dt>setweight for specific lexeme(s), <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt></dl></dd><dt id="ientry-idm13786">set_bit, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a></dt><dt id="ientry-idm13805">set_byte, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm28600">set_config, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SET">Configuration Settings Functions</a></dt><dt id="ientry-idm170043">set_limit, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.6">Functions and Operators</a></dt><dt id="ientry-idm19705">set_masklen, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm13824">sha224, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm13837">sha256, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm13850">sha384, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm13863">sha512, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm36315">shared library, <a class="indexterm" href="install-post.html#INSTALL-POST-SHLIBS">Shared Libraries</a>, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt id="ientry-idm37252">shared memory, <a class="indexterm" href="kernel-resources.html#SYSVIPC">Shared Memory and Semaphores</a></dt><dt id="ientry-idm39099">shared_buffers configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm44274">shared_memory_size configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm44283">shared_memory_size_in_huge_pages configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm39306">shared_memory_type configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm74759">shared_preload_libraries, <a class="indexterm" href="xfunc-c.html#XFUNC-SHARED-ADDIN">Shared Memory and LWLocks</a></dt><dt id="ientry-idm43733">shared_preload_libraries configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">Shared Library Preloading</a></dt><dt id="ientry-idm27990">shobj_description, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28557">SHOW, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SET">Configuration Settings Functions</a>, <a class="indexterm" href="sql-show.html">SHOW</a>, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm170031">show_limit, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.6">Functions and Operators</a></dt><dt id="ientry-idm170001">show_trgm, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.6">Functions and Operators</a></dt><dt id="ientry-idm37714">shutdown, <a class="indexterm" href="server-shutdown.html">Shutting Down the Server</a></dt><dt id="ientry-idm38343">SIGHUP, <a class="indexterm" href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE">Parameter Interaction via the Configuration File</a>, <a class="indexterm" href="auth-pg-hba-conf.html">The pg_hba.conf File</a>, <a class="indexterm" href="auth-username-maps.html">User Name Maps</a></dt><dt id="ientry-idm37735">SIGINT, <a class="indexterm" href="server-shutdown.html">Shutting Down the Server</a></dt><dt id="ientry-idm11544">sign, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm28622">signal</dt><dd><dl><dt>backend processes, <a class="indexterm" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">Server Signaling Functions</a></dt></dl></dd><dt id="ientry-idm43568">significant digits, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm37744">SIGQUIT, <a class="indexterm" href="server-shutdown.html">Shutting Down the Server</a></dt><dt id="ientry-idm37726">SIGTERM, <a class="indexterm" href="server-shutdown.html">Shutting Down the Server</a></dt><dt id="ientry-idm14463">SIMILAR TO, <a class="indexterm" href="functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP">SIMILAR TO Regular Expressions</a></dt><dt id="ientry-idm169991">similarity, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.6">Functions and Operators</a></dt><dt id="ientry-idm11886">sin, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11898">sind, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm127371">single-user mode, <a class="indexterm" href="app-postgres.html#id-1.9.5.14.6.5">Options for Single-User Mode</a></dt><dt id="ientry-idm11953">sinh, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm165969">skeys, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm18273">sleep, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">Delaying Execution</a></dt><dt id="ientry-idm166098">slice, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm147487">sliced bread (see <a href="#ientry-idm62412">TOAST</a>)</dt><dt id="ientry-idm19107">slope, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm54415">SLRU, <a class="indexterm" href="monitoring-stats.html#MONITORING-PG-STAT-SLRU-VIEW">pg_stat_slru</a></dt><dt id="ientry-idm6226">smallint, <a class="indexterm" href="datatype-numeric.html#DATATYPE-INT">Integer Types</a></dt><dt id="ientry-idm6456">smallserial, <a class="indexterm" href="datatype-numeric.html#DATATYPE-SERIAL">Serial Types</a></dt><dt id="ientry-idm36563">Solaris, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-SOLARIS">Solaris</a></dt><dd><dl><dt>installation on, <a class="indexterm" href="installation-platform-notes.html#INSTALLATION-NOTES-SOLARIS">Solaris</a></dt><dt>shared library, <a class="indexterm" href="xfunc-c.html#DFUNC">Compiling and Linking Dynamically-Loaded Functions</a></dt><dt>start script, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt></dl></dd><dt id="ientry-idm24943">SOME, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a>, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a>, <a class="indexterm" href="functions-comparisons.html">Row and Array Comparisons</a></dt><dt id="ientry-idm166388">sort, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm5423">sorting, <a class="indexterm" href="queries-order.html">Sorting Rows (ORDER BY)</a></dt><dt id="ientry-idm166409">sort_asc, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm166421">sort_desc, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm165614">soundex, <a class="indexterm" href="fuzzystrmatch.html#id-1.11.7.26.6">Soundex</a></dt><dt id="ientry-idm31237">SP-GiST (see <a href="#ientry-idm31128">index</a>)</dt><dt id="ientry-idm83962">SPI, <a class="indexterm" href="spi.html">Server Programming Interface</a>, <a class="indexterm" href="contrib-spi.html">spi</a></dt><dd><dl><dt>examples, <a class="indexterm" href="contrib-spi.html">spi</a></dt></dl></dd><dt id="ientry-idm82919">spi_commit</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm86923">SPI_commit, <a class="indexterm" href="spi-spi-commit.html">SPI_commit</a></dt><dt id="ientry-idm86925">SPI_commit_and_chain, <a class="indexterm" href="spi-spi-commit.html">SPI_commit</a></dt><dt id="ientry-idm83983">SPI_connect, <a class="indexterm" href="spi-spi-connect.html">SPI_connect</a></dt><dt id="ientry-idm83985">SPI_connect_ext, <a class="indexterm" href="spi-spi-connect.html">SPI_connect</a></dt><dt id="ientry-idm86630">SPI_copytuple, <a class="indexterm" href="spi-spi-copytuple.html">SPI_copytuple</a></dt><dt id="ientry-idm82840">spi_cursor_close</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm85852">SPI_cursor_close, <a class="indexterm" href="spi-spi-cursor-close.html">SPI_cursor_close</a></dt><dt id="ientry-idm85629">SPI_cursor_fetch, <a class="indexterm" href="spi-spi-cursor-fetch.html">SPI_cursor_fetch</a></dt><dt id="ientry-idm85600">SPI_cursor_find, <a class="indexterm" href="spi-spi-cursor-find.html">SPI_cursor_find</a></dt><dt id="ientry-idm85680">SPI_cursor_move, <a class="indexterm" href="spi-spi-cursor-move.html">SPI_cursor_move</a></dt><dt id="ientry-idm85286">SPI_cursor_open, <a class="indexterm" href="spi-spi-cursor-open.html">SPI_cursor_open</a></dt><dt id="ientry-idm85361">SPI_cursor_open_with_args, <a class="indexterm" href="spi-spi-cursor-open-with-args.html">SPI_cursor_open_with_args</a></dt><dt id="ientry-idm85465">SPI_cursor_open_with_paramlist, <a class="indexterm" href="spi-spi-cursor-open-with-paramlist.html">SPI_cursor_open_with_paramlist</a></dt><dt id="ientry-idm85523">SPI_cursor_parse_open, <a class="indexterm" href="spi-spi-cursor-parse-open.html">SPI_cursor_parse_open</a></dt><dt id="ientry-idm84278">SPI_exec, <a class="indexterm" href="spi-spi-exec.html">SPI_exec</a></dt><dt id="ientry-idm85217">SPI_execp, <a class="indexterm" href="spi-spi-execp.html">SPI_execp</a></dt><dt id="ientry-idm84059">SPI_execute, <a class="indexterm" href="spi-spi-execute.html">SPI_execute</a></dt><dt id="ientry-idm84318">SPI_execute_extended, <a class="indexterm" href="spi-spi-execute-extended.html">SPI_execute_extended</a></dt><dt id="ientry-idm84949">SPI_execute_plan, <a class="indexterm" href="spi-spi-execute-plan.html">SPI_execute_plan</a></dt><dt id="ientry-idm85045">SPI_execute_plan_extended, <a class="indexterm" href="spi-spi-execute-plan-extended.html">SPI_execute_plan_extended</a></dt><dt id="ientry-idm85153">SPI_execute_plan_with_paramlist, <a class="indexterm" href="spi-spi-execute-plan-with-paramlist.html">SPI_execute_plan_with_paramlist</a></dt><dt id="ientry-idm84429">SPI_execute_with_args, <a class="indexterm" href="spi-spi-execute-with-args.html">SPI_execute_with_args</a></dt><dt id="ientry-idm82881">spi_exec_prepared</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm82792">spi_exec_query</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm82833">spi_fetchrow</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm84030">SPI_finish, <a class="indexterm" href="spi-spi-finish.html">SPI_finish</a></dt><dt id="ientry-idm86153">SPI_fname, <a class="indexterm" href="spi-spi-fname.html">SPI_fname</a></dt><dt id="ientry-idm86193">SPI_fnumber, <a class="indexterm" href="spi-spi-fnumber.html">SPI_fnumber</a></dt><dt id="ientry-idm82888">spi_freeplan</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm86880">SPI_freeplan, <a class="indexterm" href="spi-spi-freeplan.html">SPI_freeplan</a></dt><dt id="ientry-idm86820">SPI_freetuple, <a class="indexterm" href="spi-spi-freetuple.html">SPI_freetuple</a></dt><dt id="ientry-idm86847">SPI_freetuptable, <a class="indexterm" href="spi-spi-freetupletable.html">SPI_freetuptable</a></dt><dt id="ientry-idm84818">SPI_getargcount, <a class="indexterm" href="spi-spi-getargcount.html">SPI_getargcount</a></dt><dt id="ientry-idm84854">SPI_getargtypeid, <a class="indexterm" href="spi-spi-getargtypeid.html">SPI_getargtypeid</a></dt><dt id="ientry-idm86284">SPI_getbinval, <a class="indexterm" href="spi-spi-getbinval.html">SPI_getbinval</a></dt><dt id="ientry-idm86448">SPI_getnspname, <a class="indexterm" href="spi-spi-getnspname.html">SPI_getnspname</a></dt><dt id="ientry-idm86419">SPI_getrelname, <a class="indexterm" href="spi-spi-getrelname.html">SPI_getrelname</a></dt><dt id="ientry-idm86339">SPI_gettype, <a class="indexterm" href="spi-spi-gettype.html">SPI_gettype</a></dt><dt id="ientry-idm86378">SPI_gettypeid, <a class="indexterm" href="spi-spi-gettypeid.html">SPI_gettypeid</a></dt><dt id="ientry-idm86233">SPI_getvalue, <a class="indexterm" href="spi-spi-getvalue.html">SPI_getvalue</a></dt><dt id="ientry-idm84900">SPI_is_cursor_plan, <a class="indexterm" href="spi-spi-is-cursor-plan.html">SPI_is_cursor_plan</a></dt><dt id="ientry-idm85879">SPI_keepplan, <a class="indexterm" href="spi-spi-keepplan.html">SPI_keepplan</a></dt><dt id="ientry-idm86710">SPI_modifytuple, <a class="indexterm" href="spi-spi-modifytuple.html">SPI_modifytuple</a></dt><dt id="ientry-idm86534">SPI_palloc, <a class="indexterm" href="spi-spi-palloc.html">SPI_palloc</a></dt><dt id="ientry-idm86601">SPI_pfree, <a class="indexterm" href="spi-spi-pfree.html">SPI_pfree</a></dt><dt id="ientry-idm82864">spi_prepare</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm84532">SPI_prepare, <a class="indexterm" href="spi-spi-prepare.html">SPI_prepare</a></dt><dt id="ientry-idm84623">SPI_prepare_cursor, <a class="indexterm" href="spi-spi-prepare-cursor.html">SPI_prepare_cursor</a></dt><dt id="ientry-idm84695">SPI_prepare_extended, <a class="indexterm" href="spi-spi-prepare-extended.html">SPI_prepare_extended</a></dt><dt id="ientry-idm84763">SPI_prepare_params, <a class="indexterm" href="spi-spi-prepare-params.html">SPI_prepare_params</a></dt><dt id="ientry-idm82826">spi_query</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm82872">spi_query_prepared</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm85968">SPI_register_relation, <a class="indexterm" href="spi-spi-register-relation.html">SPI_register_relation</a></dt><dt id="ientry-idm86085">SPI_register_trigger_data, <a class="indexterm" href="spi-spi-register-trigger-data.html">SPI_register_trigger_data</a></dt><dt id="ientry-idm86563">SPI_repalloc, <a class="indexterm" href="spi-realloc.html">SPI_repalloc</a></dt><dt id="ientry-idm86478">SPI_result_code_string, <a class="indexterm" href="spi-spi-result-code-string.html">SPI_result_code_string</a></dt><dt id="ientry-idm86664">SPI_returntuple, <a class="indexterm" href="spi-spi-returntuple.html">SPI_returntuple</a></dt><dt id="ientry-idm82925">spi_rollback</dt><dd><dl><dt>in PL/Perl, <a class="indexterm" href="plperl-builtins.html#PLPERL-DATABASE">Database Access from PL/Perl</a></dt></dl></dd><dt id="ientry-idm86948">SPI_rollback, <a class="indexterm" href="spi-spi-rollback.html">SPI_rollback</a></dt><dt id="ientry-idm86950">SPI_rollback_and_chain, <a class="indexterm" href="spi-spi-rollback.html">SPI_rollback</a></dt><dt id="ientry-idm85916">SPI_saveplan, <a class="indexterm" href="spi-spi-saveplan.html">SPI_saveplan</a></dt><dt id="ientry-idm85725">SPI_scroll_cursor_fetch, <a class="indexterm" href="spi-spi-scroll-cursor-fetch.html">SPI_scroll_cursor_fetch</a></dt><dt id="ientry-idm85788">SPI_scroll_cursor_move, <a class="indexterm" href="spi-spi-scroll-cursor-move.html">SPI_scroll_cursor_move</a></dt><dt id="ientry-idm86973">SPI_start_transaction, <a class="indexterm" href="spi-spi-start-transaction.html">SPI_start_transaction</a></dt><dt id="ientry-idm86028">SPI_unregister_relation, <a class="indexterm" href="spi-spi-unregister-relation.html">SPI_unregister_relation</a></dt><dt id="ientry-idm13055">split_part, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm156546">SQL/CLI, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156542">SQL/Foundation, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156538">SQL/Framework, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156566">SQL/JRT, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm22543">SQL/JSON path language, <a class="indexterm" href="functions-json.html#FUNCTIONS-SQLJSON-PATH">The SQL/JSON Path Language</a></dt><dt id="ientry-idm156574">SQL/MDA, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156554">SQL/MED, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156558">SQL/OLB, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156550">SQL/PSM, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156562">SQL/Schemata, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dt id="ientry-idm156570">SQL/XML, <a class="indexterm" href="features.html">SQL Conformance</a></dt><dd><dl><dt>limits and conformance, <a class="indexterm" href="xml-limits-conformance.html">XML Limits and Conformance to SQL/XML</a></dt></dl></dd><dt id="ientry-idm11560">sqrt, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm38204">ssh, <a class="indexterm" href="ssh-tunnels.html">Secure TCP/IP Connections with SSH Tunnels</a></dt><dt id="ientry-idm33512">SSI, <a class="indexterm" href="mvcc-intro.html">Introduction</a></dt><dt id="ientry-idm37985">SSL, <a class="indexterm" href="ssl-tcp.html">Secure TCP/IP Connections with SSL</a>, <a class="indexterm" href="libpq-ssl.html">SSL Support</a></dt><dd><dl><dt>in libpq, <a class="indexterm" href="libpq-status.html">Connection Status Functions</a></dt><dt>with libpq, <a class="indexterm" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">Parameter Key Words</a></dt><dt>TLS, <a class="indexterm" href="ssl-tcp.html">Secure TCP/IP Connections with SSL</a>, <a class="indexterm" href="libpq-ssl.html">SSL Support</a></dt></dl></dd><dt id="ientry-idm38870">ssl configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm171664">sslinfo, <a class="indexterm" href="sslinfo.html">sslinfo</a></dt><dt id="ientry-idm38882">ssl_ca_file configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm38892">ssl_cert_file configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm171694">ssl_cipher, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm38942">ssl_ciphers configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm171701">ssl_client_cert_present, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm171716">ssl_client_dn, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm171735">ssl_client_dn_field, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm171708">ssl_client_serial, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm38914">ssl_crl_dir configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm38903">ssl_crl_file configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm39053">ssl_dh_params_file configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm39004">ssl_ecdh_curve configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm171754">ssl_extension_info, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm171725">ssl_issuer_dn, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm171746">ssl_issuer_field, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm171680">ssl_is_used, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm38931">ssl_key_file configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm44299">ssl_library configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm39041">ssl_max_protocol_version configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm39023">ssl_min_protocol_version configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm39065">ssl_passphrase_command configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm39081">ssl_passphrase_command_supports_reload configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm38992">ssl_prefer_server_ciphers configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">SSL</a></dt><dt id="ientry-idm171687">ssl_version, <a class="indexterm" href="sslinfo.html#id-1.11.7.51.6">Functions Provided</a></dt><dt id="ientry-idm45574">SSPI, <a class="indexterm" href="sspi-auth.html">SSPI Authentication</a></dt><dt id="ientry-idm73858">STABLE, <a class="indexterm" href="xfunc-volatility.html">Function Volatility Categories</a></dt><dt id="ientry-idm25187">standard deviation, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dd><dl><dt>population, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt>sample, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm43977">standard_conforming_strings configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm50257">standby server, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm40236">standby.signal, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">Archive Recovery</a>, <a class="indexterm" href="warm-standby.html#STANDBY-SERVER-OPERATION">Standby Server Operation</a>, <a class="indexterm" href="warm-standby.html#STANDBY-SERVER-SETUP">Setting Up a Standby Server</a></dt><dd><dl><dt>for hot standby, <a class="indexterm" href="hot-standby.html#HOT-STANDBY-ADMIN">Administrator's Overview</a></dt><dt>pg_basebackup --write-recovery-conf, <a class="indexterm" href="app-pgbasebackup.html#id-1.9.4.10.6">Options</a></dt></dl></dd><dt id="ientry-idm175276">standby_mode (see <a href="#ientry-idm40236">standby.signal</a>)</dt><dt id="ientry-idm112443">START TRANSACTION, <a class="indexterm" href="sql-start-transaction.html">START TRANSACTION</a></dt><dt id="ientry-idm13080">starts_with, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm138414">START_REPLICATION, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm43261">statement_timeout configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm17593">statement_timestamp, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm24973">statistics, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a>, <a class="indexterm" href="planner-stats.html">Statistics Used by the Planner</a>, <a class="indexterm" href="planner-stats.html#PLANNER-STATS-EXTENDED">Extended Statistics</a>, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS">Updating Planner Statistics</a>, <a class="indexterm" href="monitoring-stats.html">The Cumulative Statistics System</a></dt><dd><dl><dt>of the planner, <a class="indexterm" href="planner-stats.html">Statistics Used by the Planner</a>, <a class="indexterm" href="planner-stats.html#PLANNER-STATS-EXTENDED">Extended Statistics</a>, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS">Updating Planner Statistics</a></dt></dl></dd><dt id="ientry-idm42704">stats_fetch_consistency configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm25189">stddev, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25207">stddev_pop, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25224">stddev_samp, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm50263">STONITH, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm101299">storage parameters, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm50334">Streaming Replication, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm170020">strict_word_similarity, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.6">Functions and Operators</a></dt><dt id="ientry-idm6583">string (see <a href="#ientry-idm1285">character string</a>)</dt><dt id="ientry-idm43898">strings</dt><dd><dl><dt>backslash quotes, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt>escape warning, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt>standard conforming, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt></dl></dd><dt id="ientry-idm24857">string_agg, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm13097">string_to_array, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm13128">string_to_table, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm20135">strip, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR">Manipulating Documents</a></dt><dt id="ientry-idm13158">strpos, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm166464">subarray, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm167324">subltree, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dt id="ientry-idm167343">subpath, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dt id="ientry-idm842">subquery, <a class="indexterm" href="tutorial-agg.html">Aggregate Functions</a>, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES">Scalar Subqueries</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-SUBQUERIES">Subqueries</a>, <a class="indexterm" href="functions-subquery.html">Subquery Expressions</a></dt><dt id="ientry-idm1824">subscript, <a class="indexterm" href="sql-expressions.html#SQL-EXPRESSIONS-SUBSCRIPTS">Subscripts</a></dt><dt id="ientry-idm13178">substr, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm12258">substring, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a>, <a class="indexterm" href="functions-bitstring.html">Bit String Functions and Operators</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP">SIMILAR TO Regular Expressions</a>, <a class="indexterm" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">POSIX Regular Expressions</a></dt><dt id="ientry-idm15770">SUBSTRING_REGEX, <a class="indexterm" href="functions-matching.html#POSIX-VS-XQUERY">Differences from SQL Standard and XQuery</a></dt><dt id="ientry-idm82584">subtransactions</dt><dd><dl><dt>in PL/Tcl, <a class="indexterm" href="pltcl-subtransactions.html">Explicit Subtransactions in PL/Tcl</a></dt></dl></dd><dt id="ientry-idm24878">sum, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm517">superuser, <a class="indexterm" href="tutorial-accessdb.html">Accessing a Database</a>, <a class="indexterm" href="role-attributes.html">Role Attributes</a></dt><dt id="ientry-idm38613">superuser_reserved_connections configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm143758">support functions</dt><dd><dl><dt>in_range, <a class="indexterm" href="btree-support-funcs.html">B-Tree Support Functions</a></dt></dl></dd><dt id="ientry-idm30311">suppress_redundant_updates_trigger, <a class="indexterm" href="functions-trigger.html">Trigger Functions</a></dt><dt id="ientry-idm165996">svals, <a class="indexterm" href="hstore.html#id-1.11.7.27.6">hstore Operators and Functions</a></dt><dt id="ientry-idm43992">synchronize_seqscans configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">Previous PostgreSQL Versions</a></dt><dt id="ientry-idm56322">synchronous commit, <a class="indexterm" href="wal-async-commit.html">Asynchronous Commit</a></dt><dt id="ientry-idm50458">Synchronous Replication, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm39741">synchronous_commit configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm40539">synchronous_standby_names configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-PRIMARY">Primary Server</a></dt><dt id="ientry-idm1158">syntax, <a class="indexterm" href="sql-syntax.html">SQL Syntax</a></dt><dd><dl><dt>SQL, <a class="indexterm" href="sql-syntax.html">SQL Syntax</a></dt></dl></dd><dt id="ientry-idm41641">syslog_facility configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41664">syslog_ident configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41678">syslog_sequence_numbers configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm41694">syslog_split_messages configuration parameter, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm3756">system catalog, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CATALOG">The System Catalog Schema</a></dt><dd><dl><dt>schema, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-CATALOG">The System Catalog Schema</a></dt></dl></dd><dt id="ientry-idm35855">systemd, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a>, <a class="indexterm" href="server-start.html">Starting the Database Server</a></dt><dd><dl><dt>RemoveIPC, <a class="indexterm" href="kernel-resources.html#SYSTEMD-REMOVEIPC">systemd RemoveIPC</a></dt></dl></dd></dl></div><div class="indexdiv" id="indexdiv-T"><h3>T</h3><dl><dt id="ientry-idm605">table, <a class="indexterm" href="tutorial-concepts.html">Concepts</a>, <a class="indexterm" href="ddl-basics.html">Table Basics</a>, <a class="indexterm" href="ddl-alter.html">Modifying Tables</a></dt><dd><dl><dt>creating, <a class="indexterm" href="ddl-basics.html">Table Basics</a></dt><dt>inheritance, <a class="indexterm" href="ddl-inherit.html">Inheritance</a></dt><dt>modifying, <a class="indexterm" href="ddl-alter.html">Modifying Tables</a></dt><dt>partitioning, <a class="indexterm" href="ddl-partitioning.html">Table Partitioning</a></dt><dt>removing, <a class="indexterm" href="ddl-basics.html">Table Basics</a></dt><dt>renaming, <a class="indexterm" href="ddl-alter.html#id-1.5.4.8.12">Renaming a Table</a></dt></dl></dd><dt id="ientry-idm142879">Table Access Method, <a class="indexterm" href="tableam.html">Table Access Method Interface Definition</a></dt><dt id="ientry-idm110388">TABLE command, <a class="indexterm" href="sql-select.html">SELECT</a></dt><dt id="ientry-idm4570">table expression, <a class="indexterm" href="queries-table-expressions.html">Table Expressions</a></dt><dt id="ientry-idm4871">table function, <a class="indexterm" href="queries-table-expressions.html#QUERIES-TABLEFUNCTIONS">Table Functions</a>, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-PROCESSING-XMLTABLE">xmltable</a></dt><dd><dl><dt>XMLTABLE, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-PROCESSING-XMLTABLE">xmltable</a></dt></dl></dd><dt id="ientry-idm142482">table sampling method, <a class="indexterm" href="tablesample-method.html">Writing a Table Sampling Method</a></dt><dt id="ientry-idm142881">tableam</dt><dd><dl><dt>Table Access Method, <a class="indexterm" href="tableam.html">Table Access Method Interface Definition</a></dt></dl></dd><dt id="ientry-idm171768">tablefunc, <a class="indexterm" href="tablefunc.html">tablefunc</a></dt><dt id="ientry-idm2852">tableoid, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt><dt id="ientry-idm142484">TABLESAMPLE method, <a class="indexterm" href="tablesample-method.html">Writing a Table Sampling Method</a></dt><dt id="ientry-idm43068">tablespace, <a class="indexterm" href="manage-ag-tablespaces.html">Tablespaces</a></dt><dd><dl><dt>default, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt>temporary, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt></dl></dd><dt id="ientry-idm10162">table_am_handler, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm11910">tan, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11922">tand, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm11977">tanh, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm78740">target list, <a class="indexterm" href="querytree.html">The Query Tree</a></dt><dt id="ientry-idm82153">Tcl, <a class="indexterm" href="pltcl.html">PL/Tcl — Tcl Procedural Language</a></dt><dt id="ientry-idm172136">tcn, <a class="indexterm" href="tcn.html">tcn</a></dt><dt id="ientry-idm38731">tcp_keepalives_count configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm38707">tcp_keepalives_idle configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm38719">tcp_keepalives_interval configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm38743">tcp_user_timeout configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm46442">template0, <a class="indexterm" href="manage-ag-createdb.html">Creating a Database</a>, <a class="indexterm" href="manage-ag-templatedbs.html">Template Databases</a></dt><dt id="ientry-idm46439">template1, <a class="indexterm" href="manage-ag-createdb.html">Creating a Database</a>, <a class="indexterm" href="manage-ag-templatedbs.html">Template Databases</a></dt><dt id="ientry-idm39179">temp_buffers configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm39356">temp_file_limit configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK">Disk</a></dt><dt id="ientry-idm43106">temp_tablespaces configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm57254">test, <a class="indexterm" href="regress.html">Regression Tests</a></dt><dt id="ientry-idm172155">test_decoding, <a class="indexterm" href="test-decoding.html">test_decoding</a></dt><dt id="ientry-idm6590">text, <a class="indexterm" href="datatype-character.html">Character Types</a>, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm8518">text search, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a>, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a>, <a class="indexterm" href="textsearch.html">Full Text Search</a>, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a></dt><dd><dl><dt>data types, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a></dt><dt>functions and operators, <a class="indexterm" href="datatype-textsearch.html">Text Search Types</a></dt><dt>indexes, <a class="indexterm" href="textsearch-indexes.html">Preferred Index Types for Text Search</a></dt></dl></dd><dt id="ientry-idm167428">text2ltree, <a class="indexterm" href="ltree.html#id-1.11.7.32.6">Operators and Functions</a></dt><dt id="ientry-idm62273">threads, <a class="indexterm" href="libpq-threading.html">Behavior in Threaded Programs</a></dt><dd><dl><dt>with libpq, <a class="indexterm" href="libpq-threading.html">Behavior in Threaded Programs</a></dt></dl></dd><dt id="ientry-idm9897">tid, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm6921">time, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.6">Times</a></dt><dd><dl><dt>constants, <a class="indexterm" href="datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-VALUES">Special Values</a></dt><dt>current, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT">Current Date/Time</a></dt><dt>output format, <a class="indexterm" href="datatype-datetime.html#DATATYPE-DATETIME-OUTPUT">Date/Time Output</a></dt><dd><dl><dt>(see also <a href="#ientry-idm15924">formatting</a>)</dt></dl></dd></dl></dd><dt id="ientry-idm6937">time span, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a></dt><dt id="ientry-idm6925">time with time zone, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.6">Times</a></dt><dt id="ientry-idm6923">time without time zone, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.6">Times</a></dt><dt id="ientry-idm7548">time zone, <a class="indexterm" href="datatype-datetime.html#DATATYPE-TIMEZONES">Time Zones</a>, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a>, <a class="indexterm" href="datetime-posix-timezone-specs.html">POSIX Time Zone Specifications</a></dt><dd><dl><dt>conversion, <a class="indexterm" href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT">AT TIME ZONE</a></dt><dt>input abbreviations, <a class="indexterm" href="datetime-config-files.html">Date/Time Configuration Files</a></dt><dt>POSIX-style specification, <a class="indexterm" href="datetime-posix-timezone-specs.html">POSIX Time Zone Specifications</a></dt></dl></dd><dt id="ientry-idm35999">time zone data, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-BUILD-PROCESS">Build Process Details</a></dt><dt id="ientry-idm43556">time zone names, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm49932">timelines, <a class="indexterm" href="backup.html">Backup and Restore</a></dt><dt id="ientry-idm138249">TIMELINE_HISTORY, <a class="indexterm" href="protocol-replication.html">Streaming Replication Protocol</a></dt><dt id="ientry-idm17605">timeofday, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm38775">timeout</dt><dd><dl><dt>client authentication, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">Authentication</a></dt><dt>deadlock, <a class="indexterm" href="runtime-config-locks.html">Lock Management</a></dt></dl></dd><dt id="ientry-idm6927">timestamp, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.7">Time Stamps</a></dt><dt id="ientry-idm6931">timestamp with time zone, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.7">Time Stamps</a></dt><dt id="ientry-idm6933">timestamp without time zone, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a>, <a class="indexterm" href="datatype-datetime.html#id-1.5.7.13.18.7">Time Stamps</a></dt><dt id="ientry-idm6929">timestamptz, <a class="indexterm" href="datatype-datetime.html">Date/Time Types</a></dt><dt id="ientry-idm43538">TimeZone configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm43553">timezone_abbreviations configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">Locale and Formatting</a></dt><dt id="ientry-idm62412">TOAST, <a class="indexterm" href="storage-toast.html">TOAST</a></dt><dd><dl><dt>and user-defined types, <a class="indexterm" href="xtypes.html#XTYPES-TOAST">TOAST Considerations</a></dt><dt>per-column storage settings, <a class="indexterm" href="sql-altertable.html#id-1.9.3.35.5">Description</a></dt><dt>per-type storage settings, <a class="indexterm" href="sql-altertype.html#id-1.9.3.42.5">Description</a></dt><dt>versus large objects, <a class="indexterm" href="lo-intro.html">Introduction</a></dt></dl></dd><dt id="ientry-idm101329">toast_tuple_target storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm1166">token, <a class="indexterm" href="sql-syntax-lexical.html">Lexical Structure</a></dt><dt id="ientry-idm13206">to_ascii, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm15942">to_char, <a class="indexterm" href="functions-formatting.html">Data Type Formatting Functions</a></dt><dd><dl><dt>and locales, <a class="indexterm" href="locale.html#id-1.6.11.3.5">Behavior</a></dt></dl></dd><dt id="ientry-idm15993">to_date, <a class="indexterm" href="functions-formatting.html">Data Type Formatting Functions</a></dt><dt id="ientry-idm13241">to_hex, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm21690">to_json, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm21696">to_jsonb, <a class="indexterm" href="functions-json.html#FUNCTIONS-JSON-PROCESSING">Processing and Creating JSON Data</a></dt><dt id="ientry-idm16006">to_number, <a class="indexterm" href="functions-formatting.html">Data Type Formatting Functions</a></dt><dt id="ientry-idm27577">to_regclass, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27589">to_regcollation, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27601">to_regnamespace, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27613">to_regoper, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27625">to_regoperator, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27637">to_regproc, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27649">to_regprocedure, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27661">to_regrole, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm27673">to_regtype, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm16019">to_timestamp, <a class="indexterm" href="functions-formatting.html">Data Type Formatting Functions</a>, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm20148">to_tsquery, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES">Parsing Queries</a></dt><dt id="ientry-idm20166">to_tsvector, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS">Parsing Documents</a></dt><dt id="ientry-idm44496">trace_locks configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44535">trace_lock_oidmin configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44547">trace_lock_table configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44510">trace_lwlocks configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44450">trace_notify configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44464">trace_recovery_messages configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44484">trace_sort configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44522">trace_userlocks configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm42624">track_activities configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm42635">track_activity_query_size configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm40522">track_commit_timestamp configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">Sending Servers</a></dt><dt id="ientry-idm42646">track_counts configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm42688">track_functions configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm42656">track_io_timing configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm42675">track_wal_io_timing configuration parameter, <a class="indexterm" href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">Cumulative Query and Index Statistics</a></dt><dt id="ientry-idm969">transaction, <a class="indexterm" href="tutorial-transactions.html">Transactions</a></dt><dt id="ientry-idm49069">transaction ID, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND">Preventing Transaction ID Wraparound Failures</a></dt><dd><dl><dt>wraparound, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND">Preventing Transaction ID Wraparound Failures</a></dt></dl></dd><dt id="ientry-idm33531">transaction isolation, <a class="indexterm" href="transaction-iso.html">Transaction Isolation</a></dt><dt id="ientry-idm33562">transaction isolation level, <a class="indexterm" href="transaction-iso.html">Transaction Isolation</a>, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dd><dl><dt>read committed, <a class="indexterm" href="transaction-iso.html#XACT-READ-COMMITTED">Read Committed Isolation Level</a></dt><dt>repeatable read, <a class="indexterm" href="transaction-iso.html#XACT-REPEATABLE-READ">Repeatable Read Isolation Level</a></dt><dt>serializable, <a class="indexterm" href="transaction-iso.html#XACT-SERIALIZABLE">Serializable Isolation Level</a></dt><dt>setting, <a class="indexterm" href="sql-set-transaction.html">SET TRANSACTION</a></dt><dt>setting default, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt></dl></dd><dt id="ientry-idm56302">transaction log (see <a href="#ientry-idm56300">WAL</a>)</dt><dt id="ientry-idm43225">transaction_deferrable configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43199">transaction_isolation configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43212">transaction_read_only configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm17619">transaction_timestamp, <a class="indexterm" href="functions-datetime.html">Date/Time Functions and Operators</a></dt><dt id="ientry-idm44010">transform_null_equals configuration parameter, <a class="indexterm" href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-CLIENTS">Platform and Client Compatibility</a></dt><dt id="ientry-idm76986">transition tables, <a class="indexterm" href="sql-createtrigger.html">CREATE TRIGGER</a></dt><dd><dl><dt>(see also <a href="#ientry-idm85970">ephemeral named relation</a>)</dt><dt>implementation in PLs, <a class="indexterm" href="spi-spi-register-trigger-data.html">SPI_register_trigger_data</a></dt><dt>referencing from C trigger, <a class="indexterm" href="trigger-interface.html">Writing Trigger Functions in C</a></dt></dl></dd><dt id="ientry-idm13257">translate, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm15772">TRANSLATE_REGEX, <a class="indexterm" href="functions-matching.html#POSIX-VS-XQUERY">Differences from SQL Standard and XQuery</a></dt><dt id="ientry-idm39148">transparent
+ huge pages, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm10152">trigger, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a>, <a class="indexterm" href="triggers.html">Triggers</a>, <a class="indexterm" href="trigger-interface.html">Writing Trigger Functions in C</a>, <a class="indexterm" href="rules-triggers.html">Rules Versus Triggers</a>, <a class="indexterm" href="plpgsql-trigger.html">Trigger Functions</a>, <a class="indexterm" href="plpython-trigger.html">Trigger Functions</a></dt><dd><dl><dt>arguments for trigger functions, <a class="indexterm" href="trigger-definition.html">Overview of Trigger Behavior</a></dt><dt>constraint trigger, <a class="indexterm" href="sql-createtrigger.html#id-1.9.3.93.6">Description</a></dt><dt>for updating a derived tsvector column, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS">Triggers for Automatic Updates</a></dt><dt>in C, <a class="indexterm" href="trigger-interface.html">Writing Trigger Functions in C</a></dt><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-trigger.html">Trigger Functions</a></dt><dt>in PL/Python, <a class="indexterm" href="plpython-trigger.html">Trigger Functions</a></dt><dt>in PL/Tcl, <a class="indexterm" href="pltcl-trigger.html">Trigger Functions in PL/Tcl</a></dt><dt>compared with rules, <a class="indexterm" href="rules-triggers.html">Rules Versus Triggers</a></dt></dl></dd><dt id="ientry-idm172138">triggered_change_notification, <a class="indexterm" href="tcn.html">tcn</a></dt><dt id="ientry-idm175270">trigger_file (see promote_trigger_file)</dt><dt id="ientry-idm12335">trim, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-binarystring.html">Binary String Functions and Operators</a></dt><dt id="ientry-idm23754">trim_array, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dt id="ientry-idm11576">trim_scale, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm7856">true, <a class="indexterm" href="datatype-boolean.html">Boolean Type</a></dt><dt id="ientry-idm11588">trunc, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a>, <a class="indexterm" href="functions-net.html">Network Address Functions and Operators</a></dt><dt id="ientry-idm112500">TRUNCATE, <a class="indexterm" href="sql-truncate.html">TRUNCATE</a></dt><dt id="ientry-idm83098">trusted, <a class="indexterm" href="plperl-trusted.html">Trusted and Untrusted PL/Perl</a></dt><dd><dl><dt>PL/Perl, <a class="indexterm" href="plperl-trusted.html">Trusted and Untrusted PL/Perl</a></dt></dl></dd><dt id="ientry-idm10166">tsm_handler, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm172167">tsm_system_rows, <a class="indexterm" href="tsm-system-rows.html">tsm_system_rows</a></dt><dt id="ientry-idm172197">tsm_system_time, <a class="indexterm" href="tsm-system-time.html">tsm_system_time</a></dt><dt id="ientry-idm8563">tsquery (data type), <a class="indexterm" href="datatype-textsearch.html#DATATYPE-TSQUERY">tsquery</a></dt><dt id="ientry-idm20454">tsquery_phrase, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY">Manipulating Queries</a></dt><dt id="ientry-idm8532">tsvector (data type), <a class="indexterm" href="datatype-textsearch.html#DATATYPE-TSVECTOR">tsvector</a></dt><dt id="ientry-idm32375">tsvector concatenation, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR">Manipulating Documents</a></dt><dt id="ientry-idm20490">tsvector_to_array, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm30321">tsvector_update_trigger, <a class="indexterm" href="functions-trigger.html">Trigger Functions</a></dt><dt id="ientry-idm30333">tsvector_update_trigger_column, <a class="indexterm" href="functions-trigger.html">Trigger Functions</a></dt><dt id="ientry-idm20540">ts_debug, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-debugging.html#TEXTSEARCH-CONFIGURATION-TESTING">Configuration Testing</a></dt><dt id="ientry-idm20256">ts_delete, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm20291">ts_filter, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm20308">ts_headline, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-HEADLINE">Highlighting Results</a></dt><dt id="ientry-idm20570">ts_lexize, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-debugging.html#TEXTSEARCH-DICTIONARY-TESTING">Dictionary Testing</a></dt><dt id="ientry-idm20586">ts_parse, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING">Parser Testing</a></dt><dt id="ientry-idm20369">ts_rank, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-RANKING">Ranking Search Results</a></dt><dt id="ientry-idm20393">ts_rank_cd, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-controls.html#TEXTSEARCH-RANKING">Ranking Search Results</a></dt><dt id="ientry-idm20417">ts_rewrite, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-QUERY-REWRITING">Query Rewriting</a></dt><dt id="ientry-idm20664">ts_stat, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-features.html#TEXTSEARCH-STATISTICS">Gathering Document Statistics</a></dt><dt id="ientry-idm20626">ts_token_type, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a>, <a class="indexterm" href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING">Parser Testing</a></dt><dt id="ientry-idm167672">tuple_data_split, <a class="indexterm" href="pageinspect.html#id-1.11.7.34.5">Heap Functions</a></dt><dt id="ientry-idm28151">txid_current, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28160">txid_current_if_assigned, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28169">txid_current_snapshot, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28178">txid_snapshot_xip, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28188">txid_snapshot_xmax, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28198">txid_snapshot_xmin, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28219">txid_status, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm28208">txid_visible_in_snapshot, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt><dt id="ientry-idm5839">type (see <a href="#ientry-idm1501">data type</a>)</dt><dt id="ientry-idm1494">type cast, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC">Numeric Constants</a>, <a class="indexterm" href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS">Type Casts</a></dt></dl></div><div class="indexdiv" id="indexdiv-U"><h3>U</h3><dl><dt id="ientry-idm1269">UESCAPE, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a>, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE">String Constants with Unicode Escapes</a></dt><dt id="ientry-idm172227">unaccent, <a class="indexterm" href="unaccent.html">unaccent</a>, <a class="indexterm" href="unaccent.html#id-1.11.7.57.8">Functions</a></dt><dt id="ientry-idm1256">Unicode escape, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE">String Constants with Unicode Escapes</a></dt><dd><dl><dt>in identifiers, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">Identifiers and Key Words</a></dt><dt>in string constants, <a class="indexterm" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE">String Constants with Unicode Escapes</a></dt></dl></dd><dt id="ientry-idm12091">Unicode normalization, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm5347">UNION, <a class="indexterm" href="queries-union.html">Combining Queries (UNION, INTERSECT, EXCEPT)</a>, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt></dl></dd><dt id="ientry-idm166433">uniq, <a class="indexterm" href="intarray.html#id-1.11.7.29.7">intarray Functions and Operators</a></dt><dt id="ientry-idm2686">unique constraint, <a class="indexterm" href="ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS">Unique Constraints</a></dt><dt id="ientry-idm13280">unistr, <a class="indexterm" href="functions-string.html">String Functions and Operators</a></dt><dt id="ientry-idm58188">Unix domain socket, <a class="indexterm" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">Parameter Key Words</a></dt><dt id="ientry-idm38629">unix_socket_directories configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm38651">unix_socket_group configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm38662">unix_socket_permissions configuration parameter, <a class="indexterm" href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">Connection Settings</a></dt><dt id="ientry-idm10172">unknown, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm112609">UNLISTEN, <a class="indexterm" href="sql-unlisten.html">UNLISTEN</a></dt><dt id="ientry-idm20503">unnest, <a class="indexterm" href="functions-array.html">Array Functions and Operators</a></dt><dd><dl><dt>for multirange, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt>for tsvector, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt></dl></dd><dt id="ientry-idm3695">unqualified name, <a class="indexterm" href="ddl-schemas.html#DDL-SCHEMAS-PATH">The Schema Search Path</a></dt><dt id="ientry-idm103651">updatable views, <a class="indexterm" href="sql-createview.html#SQL-CREATEVIEW-UPDATABLE-VIEWS">Updatable Views</a></dt><dt id="ientry-idm901">UPDATE, <a class="indexterm" href="tutorial-update.html">Updates</a>, <a class="indexterm" href="dml-update.html">Updating Data</a>, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a>, <a class="indexterm" href="sql-update.html">UPDATE</a></dt><dd><dl><dt>RETURNING, <a class="indexterm" href="dml-returning.html">Returning Data from Modified Rows</a></dt></dl></dd><dt id="ientry-idm42603">update_process_title configuration parameter, <a class="indexterm" href="runtime-config-logging.html#id-1.6.7.11.8">Process Title</a></dt><dt id="ientry-idm4437">updating, <a class="indexterm" href="dml-update.html">Updating Data</a></dt><dt id="ientry-idm37772">upgrading, <a class="indexterm" href="upgrading.html">Upgrading a PostgreSQL Cluster</a></dt><dt id="ientry-idm12380">upper, <a class="indexterm" href="functions-string.html">String Functions and Operators</a>, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dd><dl><dt>and locales, <a class="indexterm" href="locale.html#id-1.6.11.3.5">Behavior</a></dt></dl></dd><dt id="ientry-idm24362">upper_inc, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm24386">upper_inf, <a class="indexterm" href="functions-range.html">Range/Multirange Functions and Operators</a></dt><dt id="ientry-idm108119">UPSERT, <a class="indexterm" href="sql-insert.html">INSERT</a></dt><dt id="ientry-idm58083">URI, <a class="indexterm" href="libpq-connect.html#LIBPQ-CONNSTRING">Connection Strings</a></dt><dt id="ientry-idm26303">user, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a>, <a class="indexterm" href="database-roles.html">Database Roles</a></dt><dd><dl><dt>current, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a></dt></dl></dd><dt id="ientry-idm4313">user mapping, <a class="indexterm" href="ddl-foreign-data.html">Foreign Data</a></dt><dt id="ientry-idm45275">User name maps, <a class="indexterm" href="auth-username-maps.html">User Name Maps</a></dt><dt id="ientry-idm101583">user_catalog_table storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm8608">UUID, <a class="indexterm" href="datatype-uuid.html">UUID Type</a>, <a class="indexterm" href="datatype-uuid.html">UUID Type</a>, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES">PostgreSQL Features</a></dt><dd><dl><dt>generating, <a class="indexterm" href="datatype-uuid.html">UUID Type</a></dt></dl></dd><dt id="ientry-idm172305">uuid-ossp, <a class="indexterm" href="uuid-ossp.html">uuid-ossp</a></dt><dt id="ientry-idm172332">uuid_generate_v1, <a class="indexterm" href="uuid-ossp.html#id-1.11.7.58.5">uuid-ossp Functions</a></dt><dt id="ientry-idm172340">uuid_generate_v1mc, <a class="indexterm" href="uuid-ossp.html#id-1.11.7.58.5">uuid-ossp Functions</a></dt><dt id="ientry-idm172348">uuid_generate_v3, <a class="indexterm" href="uuid-ossp.html#id-1.11.7.58.5">uuid-ossp Functions</a></dt></dl></div><div class="indexdiv" id="indexdiv-V"><h3>V</h3><dl><dt id="ientry-idm48924">vacuum, <a class="indexterm" href="routine-vacuuming.html">Routine Vacuuming</a></dt><dt id="ientry-idm112908">VACUUM, <a class="indexterm" href="sql-vacuum.html">VACUUM</a></dt><dt id="ientry-idm124060">vacuumdb, <a class="indexterm" href="app-vacuumdb.html">vacuumdb</a></dt><dt id="ientry-idm172907">vacuumlo, <a class="indexterm" href="vacuumlo.html">vacuumlo</a></dt><dt id="ientry-idm39397">vacuum_cost_delay configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">Cost-based Vacuum Delay</a></dt><dt id="ientry-idm39438">vacuum_cost_limit configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">Cost-based Vacuum Delay</a></dt><dt id="ientry-idm39429">vacuum_cost_page_dirty configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">Cost-based Vacuum Delay</a></dt><dt id="ientry-idm39411">vacuum_cost_page_hit configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">Cost-based Vacuum Delay</a></dt><dt id="ientry-idm39420">vacuum_cost_page_miss configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">Cost-based Vacuum Delay</a></dt><dt id="ientry-idm40615">vacuum_defer_cleanup_age configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-PRIMARY">Primary Server</a></dt><dt id="ientry-idm43351">vacuum_failsafe_age configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43338">vacuum_freeze_min_age configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43321">vacuum_freeze_table_age configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm101366">vacuum_index_cleanup storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm43399">vacuum_multixact_failsafe_age configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43386">vacuum_multixact_freeze_min_age configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm43369">vacuum_multixact_freeze_table_age configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm101387">vacuum_truncate storage parameter, <a class="indexterm" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS">Storage Parameters</a></dt><dt id="ientry-idm1745">value expression, <a class="indexterm" href="sql-expressions.html">Value Expressions</a></dt><dt id="ientry-idm5529">VALUES, <a class="indexterm" href="queries-values.html">VALUES Lists</a>, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a>, <a class="indexterm" href="sql-values.html">VALUES</a></dt><dd><dl><dt>determination of result type, <a class="indexterm" href="typeconv-union-case.html">UNION, CASE, and Related Constructs</a></dt></dl></dd><dt id="ientry-idm6594">varchar, <a class="indexterm" href="datatype-character.html">Character Types</a></dt><dt id="ientry-idm73626">variadic function, <a class="indexterm" href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS">SQL Functions with Variable Numbers of Arguments</a></dt><dt id="ientry-idm25238">variance, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dd><dl><dt>population, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt>sample, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt></dl></dd><dt id="ientry-idm25256">var_pop, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm25273">var_samp, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm530">version, <a class="indexterm" href="tutorial-accessdb.html">Accessing a Database</a>, <a class="indexterm" href="functions-info.html">System Information Functions and Operators</a>, <a class="indexterm" href="upgrading.html">Upgrading a PostgreSQL Cluster</a></dt><dd><dl><dt>compatibility, <a class="indexterm" href="upgrading.html">Upgrading a PostgreSQL Cluster</a></dt></dl></dd><dt id="ientry-idm937">view, <a class="indexterm" href="tutorial-views.html">Views</a>, <a class="indexterm" href="rules-views.html">Views and the Rule System</a>, <a class="indexterm" href="rules-materializedviews.html">Materialized Views</a>, <a class="indexterm" href="rules-update.html#RULES-UPDATE-VIEWS">Cooperation with Views</a></dt><dd><dl><dt>implementation through rules, <a class="indexterm" href="rules-views.html">Views and the Rule System</a></dt><dt>materialized, <a class="indexterm" href="rules-materializedviews.html">Materialized Views</a></dt><dt>updating, <a class="indexterm" href="rules-update.html#RULES-UPDATE-VIEWS">Cooperation with Views</a></dt></dl></dd><dt id="ientry-idm147644">Visibility Map, <a class="indexterm" href="storage-vm.html">Visibility Map</a></dt><dt id="ientry-idm147646">VM (see <a href="#ientry-idm147644">Visibility Map</a>)</dt><dt id="ientry-idm10150">void, <a class="indexterm" href="datatype-pseudo.html">Pseudo-Types</a></dt><dt id="ientry-idm73856">VOLATILE, <a class="indexterm" href="xfunc-volatility.html">Function Volatility Categories</a></dt><dt id="ientry-idm73853">volatility, <a class="indexterm" href="xfunc-volatility.html">Function Volatility Categories</a></dt><dd><dl><dt>functions, <a class="indexterm" href="xfunc-volatility.html">Function Volatility Categories</a></dt></dl></dd><dt id="ientry-idm35447">VPATH, <a class="indexterm" href="install-procedure.html">Installation Procedure</a>, <a class="indexterm" href="extend-pgxs.html">Extension Building Infrastructure</a></dt></dl></div><div class="indexdiv" id="indexdiv-W"><h3>W</h3><dl><dt id="ientry-idm56300">WAL, <a class="indexterm" href="wal.html">Reliability and the Write-Ahead Log</a></dt><dt id="ientry-idm44310">wal_block_size configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm39944">wal_buffers configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm39901">wal_compression configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm44583">wal_consistency_checking configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm44605">wal_debug configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm40220">wal_decode_buffer_size configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY">Recovery</a></dt><dt id="ientry-idm39922">wal_init_zero configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm40483">wal_keep_size configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">Sending Servers</a></dt><dt id="ientry-idm39665">wal_level configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm39887">wal_log_hints configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm40721">wal_receiver_create_temp_slot configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40732">wal_receiver_status_interval configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm40762">wal_receiver_timeout configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm39934">wal_recycle configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm40772">wal_retrieve_retry_interval configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">Standby Servers</a></dt><dt id="ientry-idm44320">wal_segment_size configuration parameter, <a class="indexterm" href="runtime-config-preset.html">Preset Options</a></dt><dt id="ientry-idm40512">wal_sender_timeout configuration parameter, <a class="indexterm" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">Sending Servers</a></dt><dt id="ientry-idm39991">wal_skip_threshold configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm39831">wal_sync_method configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm39960">wal_writer_delay configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm39975">wal_writer_flush_after configuration parameter, <a class="indexterm" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">Settings</a></dt><dt id="ientry-idm50253">warm standby, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm20063">websearch_to_tsquery, <a class="indexterm" href="functions-textsearch.html">Text Search Functions and Operators</a></dt><dt id="ientry-idm5015">WHERE, <a class="indexterm" href="queries-table-expressions.html#QUERIES-WHERE">The WHERE Clause</a></dt><dt id="ientry-idm41431">where to log, <a class="indexterm" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">Where to Log</a></dt><dt id="ientry-idm80656">WHILE</dt><dd><dl><dt>in PL/pgSQL, <a class="indexterm" href="plpgsql-control-structures.html#id-1.8.8.8.7.7">WHILE</a></dt></dl></dd><dt id="ientry-idm19120">width, <a class="indexterm" href="functions-geometry.html">Geometric Functions and Operators</a></dt><dt id="ientry-idm11622">width_bucket, <a class="indexterm" href="functions-math.html">Mathematical Functions and Operators</a></dt><dt id="ientry-idm1012">window function, <a class="indexterm" href="tutorial-window.html">Window Functions</a>, <a class="indexterm" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS">Window Function Calls</a>, <a class="indexterm" href="queries-table-expressions.html#QUERIES-WINDOW">Window Function Processing</a>, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dd><dl><dt>built-in, <a class="indexterm" href="functions-window.html">Window Functions</a></dt><dt>invocation, <a class="indexterm" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS">Window Function Calls</a></dt><dt>order of execution, <a class="indexterm" href="queries-table-expressions.html#QUERIES-WINDOW">Window Function Processing</a></dt></dl></dd><dt id="ientry-idm5564">WITH, <a class="indexterm" href="queries-with.html">WITH Queries (Common Table Expressions)</a>, <a class="indexterm" href="sql-select.html">SELECT</a></dt><dd><dl><dt>in SELECT, <a class="indexterm" href="queries-with.html">WITH Queries (Common Table Expressions)</a>, <a class="indexterm" href="sql-select.html">SELECT</a></dt></dl></dd><dt id="ientry-idm103573">WITH CHECK OPTION, <a class="indexterm" href="sql-createview.html">CREATE VIEW</a></dt><dt id="ientry-idm1919">WITHIN GROUP, <a class="indexterm" href="sql-expressions.html#SYNTAX-AGGREGATES">Aggregate Expressions</a></dt><dt id="ientry-idm50261">witness server, <a class="indexterm" href="high-availability.html">High Availability, Load Balancing, and Replication</a></dt><dt id="ientry-idm170010">word_similarity, <a class="indexterm" href="pgtrgm.html#id-1.11.7.44.6">Functions and Operators</a></dt><dt id="ientry-idm39210">work_mem configuration parameter, <a class="indexterm" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">Memory</a></dt><dt id="ientry-idm49072">wraparound</dt><dd><dl><dt>of multixact IDs, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND">Multixacts and Wraparound</a></dt><dt>of transaction IDs, <a class="indexterm" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND">Preventing Transaction ID Wraparound Failures</a></dt></dl></dd></dl></div><div class="indexdiv" id="indexdiv-X"><h3>X</h3><dl><dt id="ientry-idm9899">xid, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm9893">xid8, <a class="indexterm" href="datatype-oid.html">Object Identifier Types</a></dt><dt id="ientry-idm2878">xmax, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt><dt id="ientry-idm2864">xmin, <a class="indexterm" href="ddl-system-columns.html">System Columns</a></dt><dt id="ientry-idm8625">XML, <a class="indexterm" href="datatype-xml.html">XML Type</a></dt><dt id="ientry-idm21163">XML export, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-MAPPING">Mapping Tables to XML</a></dt><dt id="ientry-idm20705">XML Functions, <a class="indexterm" href="functions-xml.html">XML Functions</a></dt><dt id="ientry-idm8679">XML option, <a class="indexterm" href="datatype-xml.html#id-1.5.7.21.6">Creating XML Values</a>, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm172441">xml2, <a class="indexterm" href="xml2.html">xml2</a></dt><dt id="ientry-idm20872">xmlagg, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-XMLAGG">xmlagg</a>, <a class="indexterm" href="functions-aggregate.html">Aggregate Functions</a></dt><dt id="ientry-idm43431">xmlbinary configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm20723">xmlcomment, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.5.3">xmlcomment</a></dt><dt id="ientry-idm20740">xmlconcat, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.5.4">xmlconcat</a></dt><dt id="ientry-idm20759">xmlelement, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.5.5">xmlelement</a></dt><dt id="ientry-idm20920">XMLEXISTS, <a class="indexterm" href="functions-xml.html#XML-EXISTS">XMLEXISTS</a></dt><dt id="ientry-idm20804">xmlforest, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.5.6">xmlforest</a></dt><dt id="ientry-idm43448">xmloption configuration parameter, <a class="indexterm" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">Statement Behavior</a></dt><dt id="ientry-idm8649">xmlparse, <a class="indexterm" href="datatype-xml.html#id-1.5.7.21.6">Creating XML Values</a></dt><dt id="ientry-idm20830">xmlpi, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.5.7">xmlpi</a></dt><dt id="ientry-idm20851">xmlroot, <a class="indexterm" href="functions-xml.html#id-1.5.8.21.5.8">xmlroot</a></dt><dt id="ientry-idm8662">xmlserialize, <a class="indexterm" href="datatype-xml.html#id-1.5.7.21.6">Creating XML Values</a></dt><dt id="ientry-idm21040">xmltable, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-PROCESSING-XMLTABLE">xmltable</a></dt><dt id="ientry-idm20952">xml_is_well_formed, <a class="indexterm" href="functions-xml.html#XML-IS-WELL-FORMED">xml_is_well_formed</a></dt><dt id="ientry-idm20956">xml_is_well_formed_content, <a class="indexterm" href="functions-xml.html#XML-IS-WELL-FORMED">xml_is_well_formed</a></dt><dt id="ientry-idm20954">xml_is_well_formed_document, <a class="indexterm" href="functions-xml.html#XML-IS-WELL-FORMED">xml_is_well_formed</a></dt><dt id="ientry-idm20991">XPath, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-PROCESSING-XPATH">xpath</a></dt><dt id="ientry-idm21019">xpath_exists, <a class="indexterm" href="functions-xml.html#FUNCTIONS-XML-PROCESSING-XPATH-EXISTS">xpath_exists</a></dt><dt id="ientry-idm172578">xpath_table, <a class="indexterm" href="xml2.html#id-1.11.7.59.6">xpath_table</a></dt><dt id="ientry-idm15774">XQuery regular expressions, <a class="indexterm" href="functions-matching.html#POSIX-VS-XQUERY">Differences from SQL Standard and XQuery</a></dt><dt id="ientry-idm172659">xslt_process, <a class="indexterm" href="xml2.html#id-1.11.7.59.7.3">xslt_process</a></dt></dl></div><div class="indexdiv" id="indexdiv-Y"><h3>Y</h3><dl><dt id="ientry-idm35395">yacc, <a class="indexterm" href="install-requirements.html">Requirements</a></dt></dl></div><div class="indexdiv" id="indexdiv-Z"><h3>Z</h3><dl><dt id="ientry-idm44632">zero_damaged_pages configuration parameter, <a class="indexterm" href="runtime-config-developer.html">Developer Options</a></dt><dt id="ientry-idm35295">zlib, <a class="indexterm" href="install-requirements.html">Requirements</a>, <a class="indexterm" href="install-procedure.html#CONFIGURE-OPTIONS-ANTI-FEATURES">Anti-Features</a></dt></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="biblio.html" title="Bibliography">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> </td></tr><tr><td width="40%" align="left" valign="top">Bibliography </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> </td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/brin-builtin-opclasses.html b/doc/src/sgml/html/brin-builtin-opclasses.html
new file mode 100644
index 0000000..c8843f7
--- /dev/null
+++ b/doc/src/sgml/html/brin-builtin-opclasses.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>71.2. Built-in Operator Classes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="brin-intro.html" title="71.1. Introduction" /><link rel="next" href="brin-extensibility.html" title="71.3. Extensibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">71.2. Built-in Operator Classes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="brin-intro.html" title="71.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="brin.html" title="Chapter 71. BRIN Indexes">Up</a></td><th width="60%" align="center">Chapter 71. BRIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="brin-extensibility.html" title="71.3. Extensibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="BRIN-BUILTIN-OPCLASSES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">71.2. Built-in Operator Classes</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="brin-builtin-opclasses.html#BRIN-BUILTIN-OPCLASSES--PARAMETERS">71.2.1. Operator Class Parameters</a></span></dt></dl></div><p>
+ The core <span class="productname">PostgreSQL</span> distribution
+ includes the <acronym class="acronym">BRIN</acronym> operator classes shown in
+ <a class="xref" href="brin-builtin-opclasses.html#BRIN-BUILTIN-OPCLASSES-TABLE" title="Table 71.1. Built-in BRIN Operator Classes">Table 71.1</a>.
+ </p><p>
+ The <em class="firstterm">minmax</em>
+ operator classes store the minimum and the maximum values appearing
+ in the indexed column within the range. The <em class="firstterm">inclusion</em>
+ operator classes store a value which includes the values in the indexed
+ column within the range. The <em class="firstterm">bloom</em> operator
+ classes build a Bloom filter for all values in the range. The
+ <em class="firstterm">minmax-multi</em> operator classes store multiple
+ minimum and maximum values, representing values appearing in the indexed
+ column within the range.
+ </p><div class="table" id="BRIN-BUILTIN-OPCLASSES-TABLE"><p class="title"><strong>Table 71.1. Built-in <acronym class="acronym">BRIN</acronym> Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Built-in BRIN Operator Classes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Indexable Operators</th></tr></thead><tbody><tr><td rowspan="5" valign="middle"><code class="literal">bit_minmax_ops</code></td><td><code class="literal">= (bit,bit)</code></td></tr><tr><td><code class="literal">&lt; (bit,bit)</code></td></tr><tr><td><code class="literal">&gt; (bit,bit)</code></td></tr><tr><td><code class="literal">&lt;= (bit,bit)</code></td></tr><tr><td><code class="literal">&gt;= (bit,bit)</code></td></tr><tr><td rowspan="13" valign="middle"><code class="literal">box_inclusion_ops</code></td><td><code class="literal">@&gt; (box,point)</code></td></tr><tr><td><code class="literal">&lt;&lt; (box,box)</code></td></tr><tr><td><code class="literal">&amp;&lt; (box,box)</code></td></tr><tr><td><code class="literal">&amp;&gt; (box,box)</code></td></tr><tr><td><code class="literal">&gt;&gt; (box,box)</code></td></tr><tr><td><code class="literal">&lt;@ (box,box)</code></td></tr><tr><td><code class="literal">@&gt; (box,box)</code></td></tr><tr><td><code class="literal">~= (box,box)</code></td></tr><tr><td><code class="literal">&amp;&amp; (box,box)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (box,box)</code></td></tr><tr><td><code class="literal">&amp;&lt;| (box,box)</code></td></tr><tr><td><code class="literal">|&amp;&gt; (box,box)</code></td></tr><tr><td><code class="literal">|&gt;&gt; (box,box)</code></td></tr><tr><td valign="middle"><code class="literal">bpchar_bloom_ops</code></td><td><code class="literal">= (character,character)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">bpchar_minmax_ops</code></td><td><code class="literal">= (character,character)</code></td></tr><tr><td><code class="literal">&lt; (character,character)</code></td></tr><tr><td><code class="literal">&lt;= (character,character)</code></td></tr><tr><td><code class="literal">&gt; (character,character)</code></td></tr><tr><td><code class="literal">&gt;= (character,character)</code></td></tr><tr><td valign="middle"><code class="literal">bytea_bloom_ops</code></td><td><code class="literal">= (bytea,bytea)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">bytea_minmax_ops</code></td><td><code class="literal">= (bytea,bytea)</code></td></tr><tr><td><code class="literal">&lt; (bytea,bytea)</code></td></tr><tr><td><code class="literal">&lt;= (bytea,bytea)</code></td></tr><tr><td><code class="literal">&gt; (bytea,bytea)</code></td></tr><tr><td><code class="literal">&gt;= (bytea,bytea)</code></td></tr><tr><td valign="middle"><code class="literal">char_bloom_ops</code></td><td><code class="literal">= ("char","char")</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">char_minmax_ops</code></td><td><code class="literal">= ("char","char")</code></td></tr><tr><td><code class="literal">&lt; ("char","char")</code></td></tr><tr><td><code class="literal">&lt;= ("char","char")</code></td></tr><tr><td><code class="literal">&gt; ("char","char")</code></td></tr><tr><td><code class="literal">&gt;= ("char","char")</code></td></tr><tr><td valign="middle"><code class="literal">date_bloom_ops</code></td><td><code class="literal">= (date,date)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">date_minmax_ops</code></td><td><code class="literal">= (date,date)</code></td></tr><tr><td><code class="literal">&lt; (date,date)</code></td></tr><tr><td><code class="literal">&lt;= (date,date)</code></td></tr><tr><td><code class="literal">&gt; (date,date)</code></td></tr><tr><td><code class="literal">&gt;= (date,date)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">date_minmax_multi_ops</code></td><td><code class="literal">= (date,date)</code></td></tr><tr><td><code class="literal">&lt; (date,date)</code></td></tr><tr><td><code class="literal">&lt;= (date,date)</code></td></tr><tr><td><code class="literal">&gt; (date,date)</code></td></tr><tr><td><code class="literal">&gt;= (date,date)</code></td></tr><tr><td valign="middle"><code class="literal">float4_bloom_ops</code></td><td><code class="literal">= (float4,float4)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">float4_minmax_ops</code></td><td><code class="literal">= (float4,float4)</code></td></tr><tr><td><code class="literal">&lt; (float4,float4)</code></td></tr><tr><td><code class="literal">&gt; (float4,float4)</code></td></tr><tr><td><code class="literal">&lt;= (float4,float4)</code></td></tr><tr><td><code class="literal">&gt;= (float4,float4)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">float4_minmax_multi_ops</code></td><td><code class="literal">= (float4,float4)</code></td></tr><tr><td><code class="literal">&lt; (float4,float4)</code></td></tr><tr><td><code class="literal">&gt; (float4,float4)</code></td></tr><tr><td><code class="literal">&lt;= (float4,float4)</code></td></tr><tr><td><code class="literal">&gt;= (float4,float4)</code></td></tr><tr><td valign="middle"><code class="literal">float8_bloom_ops</code></td><td><code class="literal">= (float8,float8)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">float8_minmax_ops</code></td><td><code class="literal">= (float8,float8)</code></td></tr><tr><td><code class="literal">&lt; (float8,float8)</code></td></tr><tr><td><code class="literal">&lt;= (float8,float8)</code></td></tr><tr><td><code class="literal">&gt; (float8,float8)</code></td></tr><tr><td><code class="literal">&gt;= (float8,float8)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">float8_minmax_multi_ops</code></td><td><code class="literal">= (float8,float8)</code></td></tr><tr><td><code class="literal">&lt; (float8,float8)</code></td></tr><tr><td><code class="literal">&lt;= (float8,float8)</code></td></tr><tr><td><code class="literal">&gt; (float8,float8)</code></td></tr><tr><td><code class="literal">&gt;= (float8,float8)</code></td></tr><tr><td rowspan="6" valign="middle"><code class="literal">inet_inclusion_ops</code></td><td><code class="literal">&lt;&lt; (inet,inet)</code></td></tr><tr><td><code class="literal">&lt;&lt;= (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;&gt; (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;&gt;= (inet,inet)</code></td></tr><tr><td><code class="literal">= (inet,inet)</code></td></tr><tr><td><code class="literal">&amp;&amp; (inet,inet)</code></td></tr><tr><td valign="middle"><code class="literal">inet_bloom_ops</code></td><td><code class="literal">= (inet,inet)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">inet_minmax_ops</code></td><td><code class="literal">= (inet,inet)</code></td></tr><tr><td><code class="literal">&lt; (inet,inet)</code></td></tr><tr><td><code class="literal">&lt;= (inet,inet)</code></td></tr><tr><td><code class="literal">&gt; (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;= (inet,inet)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">inet_minmax_multi_ops</code></td><td><code class="literal">= (inet,inet)</code></td></tr><tr><td><code class="literal">&lt; (inet,inet)</code></td></tr><tr><td><code class="literal">&lt;= (inet,inet)</code></td></tr><tr><td><code class="literal">&gt; (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;= (inet,inet)</code></td></tr><tr><td valign="middle"><code class="literal">int2_bloom_ops</code></td><td><code class="literal">= (int2,int2)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">int2_minmax_ops</code></td><td><code class="literal">= (int2,int2)</code></td></tr><tr><td><code class="literal">&lt; (int2,int2)</code></td></tr><tr><td><code class="literal">&gt; (int2,int2)</code></td></tr><tr><td><code class="literal">&lt;= (int2,int2)</code></td></tr><tr><td><code class="literal">&gt;= (int2,int2)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">int2_minmax_multi_ops</code></td><td><code class="literal">= (int2,int2)</code></td></tr><tr><td><code class="literal">&lt; (int2,int2)</code></td></tr><tr><td><code class="literal">&gt; (int2,int2)</code></td></tr><tr><td><code class="literal">&lt;= (int2,int2)</code></td></tr><tr><td><code class="literal">&gt;= (int2,int2)</code></td></tr><tr><td valign="middle"><code class="literal">int4_bloom_ops</code></td><td><code class="literal">= (int4,int4)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">int4_minmax_ops</code></td><td><code class="literal">= (int4,int4)</code></td></tr><tr><td><code class="literal">&lt; (int4,int4)</code></td></tr><tr><td><code class="literal">&gt; (int4,int4)</code></td></tr><tr><td><code class="literal">&lt;= (int4,int4)</code></td></tr><tr><td><code class="literal">&gt;= (int4,int4)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">int4_minmax_multi_ops</code></td><td><code class="literal">= (int4,int4)</code></td></tr><tr><td><code class="literal">&lt; (int4,int4)</code></td></tr><tr><td><code class="literal">&gt; (int4,int4)</code></td></tr><tr><td><code class="literal">&lt;= (int4,int4)</code></td></tr><tr><td><code class="literal">&gt;= (int4,int4)</code></td></tr><tr><td valign="middle"><code class="literal">int8_bloom_ops</code></td><td><code class="literal">= (bigint,bigint)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">int8_minmax_ops</code></td><td><code class="literal">= (bigint,bigint)</code></td></tr><tr><td><code class="literal">&lt; (bigint,bigint)</code></td></tr><tr><td><code class="literal">&gt; (bigint,bigint)</code></td></tr><tr><td><code class="literal">&lt;= (bigint,bigint)</code></td></tr><tr><td><code class="literal">&gt;= (bigint,bigint)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">int8_minmax_multi_ops</code></td><td><code class="literal">= (bigint,bigint)</code></td></tr><tr><td><code class="literal">&lt; (bigint,bigint)</code></td></tr><tr><td><code class="literal">&gt; (bigint,bigint)</code></td></tr><tr><td><code class="literal">&lt;= (bigint,bigint)</code></td></tr><tr><td><code class="literal">&gt;= (bigint,bigint)</code></td></tr><tr><td valign="middle"><code class="literal">interval_bloom_ops</code></td><td><code class="literal">= (interval,interval)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">interval_minmax_ops</code></td><td><code class="literal">= (interval,interval)</code></td></tr><tr><td><code class="literal">&lt; (interval,interval)</code></td></tr><tr><td><code class="literal">&lt;= (interval,interval)</code></td></tr><tr><td><code class="literal">&gt; (interval,interval)</code></td></tr><tr><td><code class="literal">&gt;= (interval,interval)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">interval_minmax_multi_ops</code></td><td><code class="literal">= (interval,interval)</code></td></tr><tr><td><code class="literal">&lt; (interval,interval)</code></td></tr><tr><td><code class="literal">&lt;= (interval,interval)</code></td></tr><tr><td><code class="literal">&gt; (interval,interval)</code></td></tr><tr><td><code class="literal">&gt;= (interval,interval)</code></td></tr><tr><td valign="middle"><code class="literal">macaddr_bloom_ops</code></td><td><code class="literal">= (macaddr,macaddr)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">macaddr_minmax_ops</code></td><td><code class="literal">= (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&lt; (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&lt;= (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&gt; (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&gt;= (macaddr,macaddr)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">macaddr_minmax_multi_ops</code></td><td><code class="literal">= (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&lt; (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&lt;= (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&gt; (macaddr,macaddr)</code></td></tr><tr><td><code class="literal">&gt;= (macaddr,macaddr)</code></td></tr><tr><td valign="middle"><code class="literal">macaddr8_bloom_ops</code></td><td><code class="literal">= (macaddr8,macaddr8)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">macaddr8_minmax_ops</code></td><td><code class="literal">= (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&lt; (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&lt;= (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&gt; (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&gt;= (macaddr8,macaddr8)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">macaddr8_minmax_multi_ops</code></td><td><code class="literal">= (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&lt; (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&lt;= (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&gt; (macaddr8,macaddr8)</code></td></tr><tr><td><code class="literal">&gt;= (macaddr8,macaddr8)</code></td></tr><tr><td valign="middle"><code class="literal">name_bloom_ops</code></td><td><code class="literal">= (name,name)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">name_minmax_ops</code></td><td><code class="literal">= (name,name)</code></td></tr><tr><td><code class="literal">&lt; (name,name)</code></td></tr><tr><td><code class="literal">&lt;= (name,name)</code></td></tr><tr><td><code class="literal">&gt; (name,name)</code></td></tr><tr><td><code class="literal">&gt;= (name,name)</code></td></tr><tr><td valign="middle"><code class="literal">numeric_bloom_ops</code></td><td><code class="literal">= (numeric,numeric)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">numeric_minmax_ops</code></td><td><code class="literal">= (numeric,numeric)</code></td></tr><tr><td><code class="literal">&lt; (numeric,numeric)</code></td></tr><tr><td><code class="literal">&lt;= (numeric,numeric)</code></td></tr><tr><td><code class="literal">&gt; (numeric,numeric)</code></td></tr><tr><td><code class="literal">&gt;= (numeric,numeric)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">numeric_minmax_multi_ops</code></td><td><code class="literal">= (numeric,numeric)</code></td></tr><tr><td><code class="literal">&lt; (numeric,numeric)</code></td></tr><tr><td><code class="literal">&lt;= (numeric,numeric)</code></td></tr><tr><td><code class="literal">&gt; (numeric,numeric)</code></td></tr><tr><td><code class="literal">&gt;= (numeric,numeric)</code></td></tr><tr><td valign="middle"><code class="literal">oid_bloom_ops</code></td><td><code class="literal">= (oid,oid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">oid_minmax_ops</code></td><td><code class="literal">= (oid,oid)</code></td></tr><tr><td><code class="literal">&lt; (oid,oid)</code></td></tr><tr><td><code class="literal">&gt; (oid,oid)</code></td></tr><tr><td><code class="literal">&lt;= (oid,oid)</code></td></tr><tr><td><code class="literal">&gt;= (oid,oid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">oid_minmax_multi_ops</code></td><td><code class="literal">= (oid,oid)</code></td></tr><tr><td><code class="literal">&lt; (oid,oid)</code></td></tr><tr><td><code class="literal">&gt; (oid,oid)</code></td></tr><tr><td><code class="literal">&lt;= (oid,oid)</code></td></tr><tr><td><code class="literal">&gt;= (oid,oid)</code></td></tr><tr><td valign="middle"><code class="literal">pg_lsn_bloom_ops</code></td><td><code class="literal">= (pg_lsn,pg_lsn)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">pg_lsn_minmax_ops</code></td><td><code class="literal">= (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&lt; (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&gt; (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&lt;= (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&gt;= (pg_lsn,pg_lsn)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">pg_lsn_minmax_multi_ops</code></td><td><code class="literal">= (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&lt; (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&gt; (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&lt;= (pg_lsn,pg_lsn)</code></td></tr><tr><td><code class="literal">&gt;= (pg_lsn,pg_lsn)</code></td></tr><tr><td rowspan="14" valign="middle"><code class="literal">range_inclusion_ops</code></td><td><code class="literal">= (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&lt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&lt;= (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&gt;= (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&amp;&amp; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange,anyelement)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&lt;@ (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&lt;&lt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&gt;&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&amp;&lt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&amp;&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">-|- (anyrange,anyrange)</code></td></tr><tr><td valign="middle"><code class="literal">text_bloom_ops</code></td><td><code class="literal">= (text,text)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">text_minmax_ops</code></td><td><code class="literal">= (text,text)</code></td></tr><tr><td><code class="literal">&lt; (text,text)</code></td></tr><tr><td><code class="literal">&lt;= (text,text)</code></td></tr><tr><td><code class="literal">&gt; (text,text)</code></td></tr><tr><td><code class="literal">&gt;= (text,text)</code></td></tr><tr><td valign="middle"><code class="literal">tid_bloom_ops</code></td><td><code class="literal">= (tid,tid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">tid_minmax_ops</code></td><td><code class="literal">= (tid,tid)</code></td></tr><tr><td><code class="literal">&lt; (tid,tid)</code></td></tr><tr><td><code class="literal">&gt; (tid,tid)</code></td></tr><tr><td><code class="literal">&lt;= (tid,tid)</code></td></tr><tr><td><code class="literal">&gt;= (tid,tid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">tid_minmax_multi_ops</code></td><td><code class="literal">= (tid,tid)</code></td></tr><tr><td><code class="literal">&lt; (tid,tid)</code></td></tr><tr><td><code class="literal">&gt; (tid,tid)</code></td></tr><tr><td><code class="literal">&lt;= (tid,tid)</code></td></tr><tr><td><code class="literal">&gt;= (tid,tid)</code></td></tr><tr><td valign="middle"><code class="literal">timestamp_bloom_ops</code></td><td><code class="literal">= (timestamp,timestamp)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">timestamp_minmax_ops</code></td><td><code class="literal">= (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&lt; (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&lt;= (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&gt; (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&gt;= (timestamp,timestamp)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">timestamp_minmax_multi_ops</code></td><td><code class="literal">= (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&lt; (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&lt;= (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&gt; (timestamp,timestamp)</code></td></tr><tr><td><code class="literal">&gt;= (timestamp,timestamp)</code></td></tr><tr><td valign="middle"><code class="literal">timestamptz_bloom_ops</code></td><td><code class="literal">= (timestamptz,timestamptz)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">timestamptz_minmax_ops</code></td><td><code class="literal">= (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&lt; (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&lt;= (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&gt; (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&gt;= (timestamptz,timestamptz)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">timestamptz_minmax_multi_ops</code></td><td><code class="literal">= (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&lt; (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&lt;= (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&gt; (timestamptz,timestamptz)</code></td></tr><tr><td><code class="literal">&gt;= (timestamptz,timestamptz)</code></td></tr><tr><td valign="middle"><code class="literal">time_bloom_ops</code></td><td><code class="literal">= (time,time)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">time_minmax_ops</code></td><td><code class="literal">= (time,time)</code></td></tr><tr><td><code class="literal">&lt; (time,time)</code></td></tr><tr><td><code class="literal">&lt;= (time,time)</code></td></tr><tr><td><code class="literal">&gt; (time,time)</code></td></tr><tr><td><code class="literal">&gt;= (time,time)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">time_minmax_multi_ops</code></td><td><code class="literal">= (time,time)</code></td></tr><tr><td><code class="literal">&lt; (time,time)</code></td></tr><tr><td><code class="literal">&lt;= (time,time)</code></td></tr><tr><td><code class="literal">&gt; (time,time)</code></td></tr><tr><td><code class="literal">&gt;= (time,time)</code></td></tr><tr><td valign="middle"><code class="literal">timetz_bloom_ops</code></td><td><code class="literal">= (timetz,timetz)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">timetz_minmax_ops</code></td><td><code class="literal">= (timetz,timetz)</code></td></tr><tr><td><code class="literal">&lt; (timetz,timetz)</code></td></tr><tr><td><code class="literal">&lt;= (timetz,timetz)</code></td></tr><tr><td><code class="literal">&gt; (timetz,timetz)</code></td></tr><tr><td><code class="literal">&gt;= (timetz,timetz)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">timetz_minmax_multi_ops</code></td><td><code class="literal">= (timetz,timetz)</code></td></tr><tr><td><code class="literal">&lt; (timetz,timetz)</code></td></tr><tr><td><code class="literal">&lt;= (timetz,timetz)</code></td></tr><tr><td><code class="literal">&gt; (timetz,timetz)</code></td></tr><tr><td><code class="literal">&gt;= (timetz,timetz)</code></td></tr><tr><td valign="middle"><code class="literal">uuid_bloom_ops</code></td><td><code class="literal">= (uuid,uuid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">uuid_minmax_ops</code></td><td><code class="literal">= (uuid,uuid)</code></td></tr><tr><td><code class="literal">&lt; (uuid,uuid)</code></td></tr><tr><td><code class="literal">&gt; (uuid,uuid)</code></td></tr><tr><td><code class="literal">&lt;= (uuid,uuid)</code></td></tr><tr><td><code class="literal">&gt;= (uuid,uuid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">uuid_minmax_multi_ops</code></td><td><code class="literal">= (uuid,uuid)</code></td></tr><tr><td><code class="literal">&lt; (uuid,uuid)</code></td></tr><tr><td><code class="literal">&gt; (uuid,uuid)</code></td></tr><tr><td><code class="literal">&lt;= (uuid,uuid)</code></td></tr><tr><td><code class="literal">&gt;= (uuid,uuid)</code></td></tr><tr><td rowspan="5" valign="middle"><code class="literal">varbit_minmax_ops</code></td><td><code class="literal">= (varbit,varbit)</code></td></tr><tr><td><code class="literal">&lt; (varbit,varbit)</code></td></tr><tr><td><code class="literal">&gt; (varbit,varbit)</code></td></tr><tr><td><code class="literal">&lt;= (varbit,varbit)</code></td></tr><tr><td><code class="literal">&gt;= (varbit,varbit)</code></td></tr></tbody></table></div></div><br class="table-break" /><div class="sect2" id="BRIN-BUILTIN-OPCLASSES--PARAMETERS"><div class="titlepage"><div><div><h3 class="title">71.2.1. Operator Class Parameters</h3></div></div></div><p>
+ Some of the built-in operator classes allow specifying parameters affecting
+ behavior of the operator class. Each operator class has its own set of
+ allowed parameters. Only the <code class="literal">bloom</code> and <code class="literal">minmax-multi</code>
+ operator classes allow specifying parameters:
+ </p><p>
+ bloom operator classes accept these parameters:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">n_distinct_per_range</code></span></dt><dd><p>
+ Defines the estimated number of distinct non-null values in the block
+ range, used by <acronym class="acronym">BRIN</acronym> bloom indexes for sizing of the
+ Bloom filter. It behaves similarly to <code class="literal">n_distinct</code> option
+ for <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>. When set to a positive value,
+ each block range is assumed to contain this number of distinct non-null
+ values. When set to a negative value, which must be greater than or
+ equal to -1, the number of distinct non-null values is assumed to grow linearly with
+ the maximum possible number of tuples in the block range (about 290
+ rows per block). The default value is <code class="literal">-0.1</code>, and
+ the minimum number of distinct non-null values is <code class="literal">16</code>.
+ </p></dd><dt><span class="term"><code class="literal">false_positive_rate</code></span></dt><dd><p>
+ Defines the desired false positive rate used by <acronym class="acronym">BRIN</acronym>
+ bloom indexes for sizing of the Bloom filter. The values must be
+ between 0.0001 and 0.25. The default value is 0.01, which is 1% false
+ positive rate.
+ </p></dd></dl></div><p>
+ minmax-multi operator classes accept these parameters:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">values_per_range</code></span></dt><dd><p>
+ Defines the maximum number of values stored by <acronym class="acronym">BRIN</acronym>
+ minmax indexes to summarize a block range. Each value may represent
+ either a point, or a boundary of an interval. Values must be between
+ 8 and 256, and the default value is 32.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="brin-intro.html" title="71.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="brin.html" title="Chapter 71. BRIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="brin-extensibility.html" title="71.3. Extensibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">71.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 71.3. Extensibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/brin-extensibility.html b/doc/src/sgml/html/brin-extensibility.html
new file mode 100644
index 0000000..5ee702c
--- /dev/null
+++ b/doc/src/sgml/html/brin-extensibility.html
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>71.3. Extensibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="brin-builtin-opclasses.html" title="71.2. Built-in Operator Classes" /><link rel="next" href="hash-index.html" title="Chapter 72. Hash Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">71.3. Extensibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="brin-builtin-opclasses.html" title="71.2. Built-in Operator Classes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="brin.html" title="Chapter 71. BRIN Indexes">Up</a></td><th width="60%" align="center">Chapter 71. BRIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="hash-index.html" title="Chapter 72. Hash Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="BRIN-EXTENSIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">71.3. Extensibility</h2></div></div></div><p>
+ The <acronym class="acronym">BRIN</acronym> interface has a high level of abstraction,
+ requiring the access method implementer only to implement the semantics
+ of the data type being accessed. The <acronym class="acronym">BRIN</acronym> layer
+ itself takes care of concurrency, logging and searching the index structure.
+ </p><p>
+ All it takes to get a <acronym class="acronym">BRIN</acronym> access method working is to
+ implement a few user-defined methods, which define the behavior of
+ summary values stored in the index and the way they interact with
+ scan keys.
+ In short, <acronym class="acronym">BRIN</acronym> combines
+ extensibility with generality, code reuse, and a clean interface.
+ </p><p>
+ There are four methods that an operator class for <acronym class="acronym">BRIN</acronym>
+ must provide:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">BrinOpcInfo *opcInfo(Oid type_oid)</code></span></dt><dd><p>
+ Returns internal information about the indexed columns' summary data.
+ The return value must point to a palloc'd <code class="structname">BrinOpcInfo</code>,
+ which has this definition:
+</p><pre class="programlisting">
+typedef struct BrinOpcInfo
+{
+ /* Number of columns stored in an index column of this opclass */
+ uint16 oi_nstored;
+
+ /* Opaque pointer for the opclass' private use */
+ void *oi_opaque;
+
+ /* Type cache entries of the stored columns */
+ TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
+} BrinOpcInfo;
+</pre><p>
+ <code class="structname">BrinOpcInfo</code>.<code class="structfield">oi_opaque</code> can be used by the
+ operator class routines to pass information between support functions
+ during an index scan.
+ </p></dd><dt><span class="term"><code class="function">bool consistent(BrinDesc *bdesc, BrinValues *column,
+ ScanKey *keys, int nkeys)</code></span></dt><dd><p>
+ Returns whether all the ScanKey entries are consistent with the given
+ indexed values for a range.
+ The attribute number to use is passed as part of the scan key.
+ Multiple scan keys for the same attribute may be passed at once; the
+ number of entries is determined by the <code class="literal">nkeys</code> parameter.
+ </p></dd><dt><span class="term"><code class="function">bool consistent(BrinDesc *bdesc, BrinValues *column,
+ ScanKey key)</code></span></dt><dd><p>
+ Returns whether the ScanKey is consistent with the given indexed
+ values for a range.
+ The attribute number to use is passed as part of the scan key.
+ This is an older backward-compatible variant of the consistent function.
+ </p></dd><dt><span class="term"><code class="function">bool addValue(BrinDesc *bdesc, BrinValues *column,
+ Datum newval, bool isnull)</code></span></dt><dd><p>
+ Given an index tuple and an indexed value, modifies the indicated
+ attribute of the tuple so that it additionally represents the new value.
+ If any modification was done to the tuple, <code class="literal">true</code> is
+ returned.
+ </p></dd><dt><span class="term"><code class="function">bool unionTuples(BrinDesc *bdesc, BrinValues *a,
+ BrinValues *b)</code></span></dt><dd><p>
+ Consolidates two index tuples. Given two index tuples, modifies the
+ indicated attribute of the first of them so that it represents both tuples.
+ The second tuple is not modified.
+ </p></dd></dl></div><p>
+
+ An operator class for <acronym class="acronym">BRIN</acronym> can optionally specify the
+ following method:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">void options(local_relopts *relopts)</code></span></dt><dd><p>
+ Defines a set of user-visible parameters that control operator class
+ behavior.
+ </p><p>
+ The <code class="function">options</code> function is passed a pointer to a
+ <code class="structname">local_relopts</code> struct, which needs to be
+ filled with a set of operator class specific options. The options
+ can be accessed from other support functions using the
+ <code class="literal">PG_HAS_OPCLASS_OPTIONS()</code> and
+ <code class="literal">PG_GET_OPCLASS_OPTIONS()</code> macros.
+ </p><p>
+ Since both key extraction of indexed values and representation of the
+ key in <acronym class="acronym">BRIN</acronym> are flexible, they may depend on
+ user-specified parameters.
+ </p></dd></dl></div><p>
+
+ The core distribution includes support for four types of operator classes:
+ minmax, minmax-multi, inclusion and bloom. Operator class definitions
+ using them are shipped for in-core data types as appropriate. Additional
+ operator classes can be defined by the user for other data types using
+ equivalent definitions, without having to write any source code;
+ appropriate catalog entries being declared is enough. Note that
+ assumptions about the semantics of operator strategies are embedded in the
+ support functions' source code.
+ </p><p>
+ Operator classes that implement completely different semantics are also
+ possible, provided implementations of the four main support functions
+ described above are written. Note that backwards compatibility across major
+ releases is not guaranteed: for example, additional support functions might
+ be required in later releases.
+ </p><p>
+ To write an operator class for a data type that implements a totally
+ ordered set, it is possible to use the minmax support functions
+ alongside the corresponding operators, as shown in
+ <a class="xref" href="brin-extensibility.html#BRIN-EXTENSIBILITY-MINMAX-TABLE" title="Table 71.2. Function and Support Numbers for Minmax Operator Classes">Table 71.2</a>.
+ All operator class members (functions and operators) are mandatory.
+ </p><div class="table" id="BRIN-EXTENSIBILITY-MINMAX-TABLE"><p class="title"><strong>Table 71.2. Function and Support Numbers for Minmax Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Function and Support Numbers for Minmax Operator Classes" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Operator class member</th><th>Object</th></tr></thead><tbody><tr><td>Support Function 1</td><td>internal function <code class="function">brin_minmax_opcinfo()</code></td></tr><tr><td>Support Function 2</td><td>internal function <code class="function">brin_minmax_add_value()</code></td></tr><tr><td>Support Function 3</td><td>internal function <code class="function">brin_minmax_consistent()</code></td></tr><tr><td>Support Function 4</td><td>internal function <code class="function">brin_minmax_union()</code></td></tr><tr><td>Operator Strategy 1</td><td>operator less-than</td></tr><tr><td>Operator Strategy 2</td><td>operator less-than-or-equal-to</td></tr><tr><td>Operator Strategy 3</td><td>operator equal-to</td></tr><tr><td>Operator Strategy 4</td><td>operator greater-than-or-equal-to</td></tr><tr><td>Operator Strategy 5</td><td>operator greater-than</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ To write an operator class for a complex data type which has values
+ included within another type, it's possible to use the inclusion support
+ functions alongside the corresponding operators, as shown
+ in <a class="xref" href="brin-extensibility.html#BRIN-EXTENSIBILITY-INCLUSION-TABLE" title="Table 71.3. Function and Support Numbers for Inclusion Operator Classes">Table 71.3</a>. It requires
+ only a single additional function, which can be written in any language.
+ More functions can be defined for additional functionality. All operators
+ are optional. Some operators require other operators, as shown as
+ dependencies on the table.
+ </p><div class="table" id="BRIN-EXTENSIBILITY-INCLUSION-TABLE"><p class="title"><strong>Table 71.3. Function and Support Numbers for Inclusion Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Function and Support Numbers for Inclusion Operator Classes" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Operator class member</th><th>Object</th><th>Dependency</th></tr></thead><tbody><tr><td>Support Function 1</td><td>internal function <code class="function">brin_inclusion_opcinfo()</code></td><td> </td></tr><tr><td>Support Function 2</td><td>internal function <code class="function">brin_inclusion_add_value()</code></td><td> </td></tr><tr><td>Support Function 3</td><td>internal function <code class="function">brin_inclusion_consistent()</code></td><td> </td></tr><tr><td>Support Function 4</td><td>internal function <code class="function">brin_inclusion_union()</code></td><td> </td></tr><tr><td>Support Function 11</td><td>function to merge two elements</td><td> </td></tr><tr><td>Support Function 12</td><td>optional function to check whether two elements are mergeable</td><td> </td></tr><tr><td>Support Function 13</td><td>optional function to check if an element is contained within another</td><td> </td></tr><tr><td>Support Function 14</td><td>optional function to check whether an element is empty</td><td> </td></tr><tr><td>Operator Strategy 1</td><td>operator left-of</td><td>Operator Strategy 4</td></tr><tr><td>Operator Strategy 2</td><td>operator does-not-extend-to-the-right-of</td><td>Operator Strategy 5</td></tr><tr><td>Operator Strategy 3</td><td>operator overlaps</td><td> </td></tr><tr><td>Operator Strategy 4</td><td>operator does-not-extend-to-the-left-of</td><td>Operator Strategy 1</td></tr><tr><td>Operator Strategy 5</td><td>operator right-of</td><td>Operator Strategy 2</td></tr><tr><td>Operator Strategy 6, 18</td><td>operator same-as-or-equal-to</td><td>Operator Strategy 7</td></tr><tr><td>Operator Strategy 7, 16, 24, 25</td><td>operator contains-or-equal-to</td><td> </td></tr><tr><td>Operator Strategy 8, 26, 27</td><td>operator is-contained-by-or-equal-to</td><td>Operator Strategy 3</td></tr><tr><td>Operator Strategy 9</td><td>operator does-not-extend-above</td><td>Operator Strategy 11</td></tr><tr><td>Operator Strategy 10</td><td>operator is-below</td><td>Operator Strategy 12</td></tr><tr><td>Operator Strategy 11</td><td>operator is-above</td><td>Operator Strategy 9</td></tr><tr><td>Operator Strategy 12</td><td>operator does-not-extend-below</td><td>Operator Strategy 10</td></tr><tr><td>Operator Strategy 20</td><td>operator less-than</td><td>Operator Strategy 5</td></tr><tr><td>Operator Strategy 21</td><td>operator less-than-or-equal-to</td><td>Operator Strategy 5</td></tr><tr><td>Operator Strategy 22</td><td>operator greater-than</td><td>Operator Strategy 1</td></tr><tr><td>Operator Strategy 23</td><td>operator greater-than-or-equal-to</td><td>Operator Strategy 1</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Support function numbers 1 through 10 are reserved for the BRIN internal
+ functions, so the SQL level functions start with number 11. Support
+ function number 11 is the main function required to build the index.
+ It should accept two arguments with the same data type as the operator class,
+ and return the union of them. The inclusion operator class can store union
+ values with different data types if it is defined with the
+ <code class="literal">STORAGE</code> parameter. The return value of the union
+ function should match the <code class="literal">STORAGE</code> data type.
+ </p><p>
+ Support function numbers 12 and 14 are provided to support
+ irregularities of built-in data types. Function number 12
+ is used to support network addresses from different families which
+ are not mergeable. Function number 14 is used to support
+ empty ranges. Function number 13 is an optional but
+ recommended one, which allows the new value to be checked before
+ it is passed to the union function. As the BRIN framework can shortcut
+ some operations when the union is not changed, using this
+ function can improve index performance.
+ </p><p>
+ To write an operator class for a data type that implements only an equality
+ operator and supports hashing, it is possible to use the bloom support procedures
+ alongside the corresponding operators, as shown in
+ <a class="xref" href="brin-extensibility.html#BRIN-EXTENSIBILITY-BLOOM-TABLE" title="Table 71.4. Procedure and Support Numbers for Bloom Operator Classes">Table 71.4</a>.
+ All operator class members (procedures and operators) are mandatory.
+ </p><div class="table" id="BRIN-EXTENSIBILITY-BLOOM-TABLE"><p class="title"><strong>Table 71.4. Procedure and Support Numbers for Bloom Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Procedure and Support Numbers for Bloom Operator Classes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operator class member</th><th>Object</th></tr></thead><tbody><tr><td>Support Procedure 1</td><td>internal function <code class="function">brin_bloom_opcinfo()</code></td></tr><tr><td>Support Procedure 2</td><td>internal function <code class="function">brin_bloom_add_value()</code></td></tr><tr><td>Support Procedure 3</td><td>internal function <code class="function">brin_bloom_consistent()</code></td></tr><tr><td>Support Procedure 4</td><td>internal function <code class="function">brin_bloom_union()</code></td></tr><tr><td>Support Procedure 5</td><td>internal function <code class="function">brin_bloom_options()</code></td></tr><tr><td>Support Procedure 11</td><td>function to compute hash of an element</td></tr><tr><td>Operator Strategy 1</td><td>operator equal-to</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Support procedure numbers 1-10 are reserved for the BRIN internal
+ functions, so the SQL level functions start with number 11. Support
+ function number 11 is the main function required to build the index.
+ It should accept one argument with the same data type as the operator class,
+ and return a hash of the value.
+ </p><p>
+ The minmax-multi operator class is also intended for data types implementing
+ a totally ordered set, and may be seen as a simple extension of the minmax
+ operator class. While minmax operator class summarizes values from each block
+ range into a single contiguous interval, minmax-multi allows summarization
+ into multiple smaller intervals to improve handling of outlier values.
+ It is possible to use the minmax-multi support procedures alongside the
+ corresponding operators, as shown in
+ <a class="xref" href="brin-extensibility.html#BRIN-EXTENSIBILITY-MINMAX-MULTI-TABLE" title="Table 71.5. Procedure and Support Numbers for minmax-multi Operator Classes">Table 71.5</a>.
+ All operator class members (procedures and operators) are mandatory.
+ </p><div class="table" id="BRIN-EXTENSIBILITY-MINMAX-MULTI-TABLE"><p class="title"><strong>Table 71.5. Procedure and Support Numbers for minmax-multi Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Procedure and Support Numbers for minmax-multi Operator Classes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operator class member</th><th>Object</th></tr></thead><tbody><tr><td>Support Procedure 1</td><td>internal function <code class="function">brin_minmax_multi_opcinfo()</code></td></tr><tr><td>Support Procedure 2</td><td>internal function <code class="function">brin_minmax_multi_add_value()</code></td></tr><tr><td>Support Procedure 3</td><td>internal function <code class="function">brin_minmax_multi_consistent()</code></td></tr><tr><td>Support Procedure 4</td><td>internal function <code class="function">brin_minmax_multi_union()</code></td></tr><tr><td>Support Procedure 5</td><td>internal function <code class="function">brin_minmax_multi_options()</code></td></tr><tr><td>Support Procedure 11</td><td>function to compute distance between two values (length of a range)</td></tr><tr><td>Operator Strategy 1</td><td>operator less-than</td></tr><tr><td>Operator Strategy 2</td><td>operator less-than-or-equal-to</td></tr><tr><td>Operator Strategy 3</td><td>operator equal-to</td></tr><tr><td>Operator Strategy 4</td><td>operator greater-than-or-equal-to</td></tr><tr><td>Operator Strategy 5</td><td>operator greater-than</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Both minmax and inclusion operator classes support cross-data-type
+ operators, though with these the dependencies become more complicated.
+ The minmax operator class requires a full set of operators to be
+ defined with both arguments having the same data type. It allows
+ additional data types to be supported by defining extra sets
+ of operators. Inclusion operator class operator strategies are dependent
+ on another operator strategy as shown in
+ <a class="xref" href="brin-extensibility.html#BRIN-EXTENSIBILITY-INCLUSION-TABLE" title="Table 71.3. Function and Support Numbers for Inclusion Operator Classes">Table 71.3</a>, or the same
+ operator strategy as themselves. They require the dependency
+ operator to be defined with the <code class="literal">STORAGE</code> data type as the
+ left-hand-side argument and the other supported data type to be the
+ right-hand-side argument of the supported operator. See
+ <code class="literal">float4_minmax_ops</code> as an example of minmax, and
+ <code class="literal">box_inclusion_ops</code> as an example of inclusion.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="brin-builtin-opclasses.html" title="71.2. Built-in Operator Classes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="brin.html" title="Chapter 71. BRIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="hash-index.html" title="Chapter 72. Hash Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">71.2. Built-in Operator Classes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 72. Hash Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/brin-intro.html b/doc/src/sgml/html/brin-intro.html
new file mode 100644
index 0000000..7b280ce
--- /dev/null
+++ b/doc/src/sgml/html/brin-intro.html
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>71.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="brin.html" title="Chapter 71. BRIN Indexes" /><link rel="next" href="brin-builtin-opclasses.html" title="71.2. Built-in Operator Classes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">71.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="brin.html" title="Chapter 71. BRIN Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="brin.html" title="Chapter 71. BRIN Indexes">Up</a></td><th width="60%" align="center">Chapter 71. BRIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="brin-builtin-opclasses.html" title="71.2. Built-in Operator Classes">Next</a></td></tr></table><hr /></div><div class="sect1" id="BRIN-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">71.1. Introduction</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="brin-intro.html#BRIN-OPERATION">71.1.1. Index Maintenance</a></span></dt></dl></div><p>
+ <acronym class="acronym">BRIN</acronym> stands for Block Range Index.
+ <acronym class="acronym">BRIN</acronym> is designed for handling very large tables
+ in which certain columns have some natural correlation with their
+ physical location within the table.
+ </p><p>
+ <acronym class="acronym">BRIN</acronym> works in terms of <em class="firstterm">block ranges</em>
+ (or <span class="quote">“<span class="quote">page ranges</span>”</span>).
+ A block range is a group of pages that are physically
+ adjacent in the table; for each block range, some summary info is stored
+ by the index.
+ For example, a table storing a store's sale orders might have
+ a date column on which each order was placed, and most of the time
+ the entries for earlier orders will appear earlier in the table as well;
+ a table storing a ZIP code column might have all codes for a city
+ grouped together naturally.
+ </p><p>
+ <acronym class="acronym">BRIN</acronym> indexes can satisfy queries via regular bitmap
+ index scans, and will return all tuples in all pages within each range if
+ the summary info stored by the index is <em class="firstterm">consistent</em> with the
+ query conditions.
+ The query executor is in charge of rechecking these tuples and discarding
+ those that do not match the query conditions — in other words, these
+ indexes are lossy.
+ Because a <acronym class="acronym">BRIN</acronym> index is very small, scanning the index
+ adds little overhead compared to a sequential scan, but may avoid scanning
+ large parts of the table that are known not to contain matching tuples.
+ </p><p>
+ The specific data that a <acronym class="acronym">BRIN</acronym> index will store,
+ as well as the specific queries that the index will be able to satisfy,
+ depend on the operator class selected for each column of the index.
+ Data types having a linear sort order can have operator classes that
+ store the minimum and maximum value within each block range, for instance;
+ geometrical types might store the bounding box for all the objects
+ in the block range.
+ </p><p>
+ The size of the block range is determined at index creation time by
+ the <code class="literal">pages_per_range</code> storage parameter. The number of index
+ entries will be equal to the size of the relation in pages divided by
+ the selected value for <code class="literal">pages_per_range</code>. Therefore, the smaller
+ the number, the larger the index becomes (because of the need to
+ store more index entries), but at the same time the summary data stored can
+ be more precise and more data blocks can be skipped during an index scan.
+ </p><div class="sect2" id="BRIN-OPERATION"><div class="titlepage"><div><div><h3 class="title">71.1.1. Index Maintenance</h3></div></div></div><p>
+ At the time of creation, all existing heap pages are scanned and a
+ summary index tuple is created for each range, including the
+ possibly-incomplete range at the end.
+ As new pages are filled with data, page ranges that are already
+ summarized will cause the summary information to be updated with data
+ from the new tuples.
+ When a new page is created that does not fall within the last
+ summarized range, the range that the new page belongs to
+ does not automatically acquire a summary tuple;
+ those tuples remain unsummarized until a summarization run is
+ invoked later, creating the initial summary for that range.
+ </p><p>
+ There are several ways to trigger the initial summarization of a page range.
+ If the table is vacuumed, either manually or by
+ <a class="link" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">autovacuum</a>, all existing unsummarized
+ page ranges are summarized.
+ Also, if the index's
+ <a class="xref" href="sql-createindex.html#INDEX-RELOPTION-AUTOSUMMARIZE">autosummarize</a> parameter is enabled,
+ which it isn't by default,
+ whenever autovacuum runs in that database, summarization will occur for all
+ unsummarized page ranges that have been filled,
+ regardless of whether the table itself is processed by autovacuum; see below.
+ </p><p>
+ Lastly, the following functions can be used:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td>
+ <code class="function">brin_summarize_new_values(regclass)</code>
+ which summarizes all unsummarized ranges;
+ </td></tr><tr><td>
+ <code class="function">brin_summarize_range(regclass, bigint)</code>
+ which summarizes only the range containing the given page,
+ if it is unsummarized.
+ </td></tr></table><p>
+ </p><p>
+ When autosummarization is enabled, a request is sent to
+ <code class="literal">autovacuum</code> to execute a targeted summarization
+ for a block range when an insertion is detected for the first item
+ of the first page of the next block range,
+ to be fulfilled the next time an autovacuum
+ worker finishes running in the
+ same database. If the request queue is full, the request is not recorded
+ and a message is sent to the server log:
+</p><pre class="screen">
+LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was not recorded
+</pre><p>
+ When this happens, the range will remain unsummarized until the next
+ regular vacuum run on the table, or one of the functions mentioned above
+ are invoked.
+ </p><p>
+ Conversely, a range can be de-summarized using the
+ <code class="function">brin_desummarize_range(regclass, bigint)</code> function,
+ which is useful when the index tuple is no longer a very good
+ representation because the existing values have changed.
+ See <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-INDEX" title="9.27.8. Index Maintenance Functions">Section 9.27.8</a> for details.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="brin.html" title="Chapter 71. BRIN Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="brin.html" title="Chapter 71. BRIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="brin-builtin-opclasses.html" title="71.2. Built-in Operator Classes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 71. BRIN Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 71.2. Built-in Operator Classes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/brin.html b/doc/src/sgml/html/brin.html
new file mode 100644
index 0000000..096b918
--- /dev/null
+++ b/doc/src/sgml/html/brin.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 71. BRIN Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-examples.html" title="70.7. Examples" /><link rel="next" href="brin-intro.html" title="71.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 71. BRIN Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-examples.html" title="70.7. Examples">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="brin-intro.html" title="71.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="BRIN"><div class="titlepage"><div><div><h2 class="title">Chapter 71. BRIN Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="brin-intro.html">71.1. Introduction</a></span></dt><dd><dl><dt><span class="sect2"><a href="brin-intro.html#BRIN-OPERATION">71.1.1. Index Maintenance</a></span></dt></dl></dd><dt><span class="sect1"><a href="brin-builtin-opclasses.html">71.2. Built-in Operator Classes</a></span></dt><dd><dl><dt><span class="sect2"><a href="brin-builtin-opclasses.html#BRIN-BUILTIN-OPCLASSES--PARAMETERS">71.2.1. Operator Class Parameters</a></span></dt></dl></dd><dt><span class="sect1"><a href="brin-extensibility.html">71.3. Extensibility</a></span></dt></dl></div><a id="id-1.10.22.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-examples.html" title="70.7. Examples">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="brin-intro.html" title="71.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.7. Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 71.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree-behavior.html b/doc/src/sgml/html/btree-behavior.html
new file mode 100644
index 0000000..f6fb8dd
--- /dev/null
+++ b/doc/src/sgml/html/btree-behavior.html
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>67.2. Behavior of B-Tree Operator Classes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree-intro.html" title="67.1. Introduction" /><link rel="next" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">67.2. Behavior of B-Tree Operator Classes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree-intro.html" title="67.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><th width="60%" align="center">Chapter 67. B-Tree Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="BTREE-BEHAVIOR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">67.2. Behavior of B-Tree Operator Classes</h2></div></div></div><p>
+ As shown in <a class="xref" href="xindex.html#XINDEX-BTREE-STRAT-TABLE" title="Table 38.3. B-Tree Strategies">Table 38.3</a>, a btree operator
+ class must provide five comparison operators,
+ <code class="literal">&lt;</code>,
+ <code class="literal">&lt;=</code>,
+ <code class="literal">=</code>,
+ <code class="literal">&gt;=</code> and
+ <code class="literal">&gt;</code>.
+ One might expect that <code class="literal">&lt;&gt;</code> should also be part of
+ the operator class, but it is not, because it would almost never be
+ useful to use a <code class="literal">&lt;&gt;</code> WHERE clause in an index
+ search. (For some purposes, the planner treats <code class="literal">&lt;&gt;</code>
+ as associated with a btree operator class; but it finds that operator via
+ the <code class="literal">=</code> operator's negator link, rather than
+ from <code class="structname">pg_amop</code>.)
+ </p><p>
+ When several data types share near-identical sorting semantics, their
+ operator classes can be grouped into an operator family. Doing so is
+ advantageous because it allows the planner to make deductions about
+ cross-type comparisons. Each operator class within the family should
+ contain the single-type operators (and associated support functions)
+ for its input data type, while cross-type comparison operators and
+ support functions are <span class="quote">“<span class="quote">loose</span>”</span> in the family. It is
+ recommendable that a complete set of cross-type operators be included
+ in the family, thus ensuring that the planner can represent any
+ comparison conditions that it deduces from transitivity.
+ </p><p>
+ There are some basic assumptions that a btree operator family must
+ satisfy:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ An <code class="literal">=</code> operator must be an equivalence relation; that
+ is, for all non-null values <em class="replaceable"><code>A</code></em>,
+ <em class="replaceable"><code>B</code></em>, <em class="replaceable"><code>C</code></em> of the
+ data type:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ <em class="replaceable"><code>A</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>A</code></em> is true
+ (<em class="firstterm">reflexive law</em>)
+ </p></li><li class="listitem"><p>
+ if <em class="replaceable"><code>A</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>B</code></em>,
+ then <em class="replaceable"><code>B</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>A</code></em>
+ (<em class="firstterm">symmetric law</em>)
+ </p></li><li class="listitem"><p>
+ if <em class="replaceable"><code>A</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>B</code></em> and <em class="replaceable"><code>B</code></em>
+ <code class="literal">=</code> <em class="replaceable"><code>C</code></em>,
+ then <em class="replaceable"><code>A</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>C</code></em>
+ (<em class="firstterm">transitive law</em>)
+ </p></li></ul></div><p>
+ </p></li><li class="listitem"><p>
+ A <code class="literal">&lt;</code> operator must be a strong ordering relation;
+ that is, for all non-null values <em class="replaceable"><code>A</code></em>,
+ <em class="replaceable"><code>B</code></em>, <em class="replaceable"><code>C</code></em>:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ <em class="replaceable"><code>A</code></em> <code class="literal">&lt;</code>
+ <em class="replaceable"><code>A</code></em> is false
+ (<em class="firstterm">irreflexive law</em>)
+ </p></li><li class="listitem"><p>
+ if <em class="replaceable"><code>A</code></em> <code class="literal">&lt;</code>
+ <em class="replaceable"><code>B</code></em>
+ and <em class="replaceable"><code>B</code></em> <code class="literal">&lt;</code>
+ <em class="replaceable"><code>C</code></em>,
+ then <em class="replaceable"><code>A</code></em> <code class="literal">&lt;</code>
+ <em class="replaceable"><code>C</code></em>
+ (<em class="firstterm">transitive law</em>)
+ </p></li></ul></div><p>
+ </p></li><li class="listitem"><p>
+ Furthermore, the ordering is total; that is, for all non-null
+ values <em class="replaceable"><code>A</code></em>, <em class="replaceable"><code>B</code></em>:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ exactly one of <em class="replaceable"><code>A</code></em> <code class="literal">&lt;</code>
+ <em class="replaceable"><code>B</code></em>, <em class="replaceable"><code>A</code></em>
+ <code class="literal">=</code> <em class="replaceable"><code>B</code></em>, and
+ <em class="replaceable"><code>B</code></em> <code class="literal">&lt;</code>
+ <em class="replaceable"><code>A</code></em> is true
+ (<em class="firstterm">trichotomy law</em>)
+ </p></li></ul></div><p>
+
+ (The trichotomy law justifies the definition of the comparison support
+ function, of course.)
+ </p></li></ul></div><p>
+ The other three operators are defined in terms of <code class="literal">=</code>
+ and <code class="literal">&lt;</code> in the obvious way, and must act consistently
+ with them.
+ </p><p>
+ For an operator family supporting multiple data types, the above laws must
+ hold when <em class="replaceable"><code>A</code></em>, <em class="replaceable"><code>B</code></em>,
+ <em class="replaceable"><code>C</code></em> are taken from any data types in the family.
+ The transitive laws are the trickiest to ensure, as in cross-type
+ situations they represent statements that the behaviors of two or three
+ different operators are consistent.
+ As an example, it would not work to put <code class="type">float8</code>
+ and <code class="type">numeric</code> into the same operator family, at least not with
+ the current semantics that <code class="type">numeric</code> values are converted
+ to <code class="type">float8</code> for comparison to a <code class="type">float8</code>. Because
+ of the limited accuracy of <code class="type">float8</code>, this means there are
+ distinct <code class="type">numeric</code> values that will compare equal to the
+ same <code class="type">float8</code> value, and thus the transitive law would fail.
+ </p><p>
+ Another requirement for a multiple-data-type family is that any implicit
+ or binary-coercion casts that are defined between data types included in
+ the operator family must not change the associated sort ordering.
+ </p><p>
+ It should be fairly clear why a btree index requires these laws to hold
+ within a single data type: without them there is no ordering to arrange
+ the keys with. Also, index searches using a comparison key of a
+ different data type require comparisons to behave sanely across two
+ data types. The extensions to three or more data types within a family
+ are not strictly required by the btree index mechanism itself, but the
+ planner relies on them for optimization purposes.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree-intro.html" title="67.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">67.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 67.3. B-Tree Support Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree-gin.html b/doc/src/sgml/html/btree-gin.html
new file mode 100644
index 0000000..826f2b2
--- /dev/null
+++ b/doc/src/sgml/html/btree-gin.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.8. btree_gin</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bloom.html" title="F.7. bloom" /><link rel="next" href="btree-gist.html" title="F.9. btree_gist" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.8. btree_gin</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bloom.html" title="F.7. bloom">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree-gist.html" title="F.9. btree_gist">Next</a></td></tr></table><hr /></div><div class="sect1" id="BTREE-GIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.8. btree_gin</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="btree-gin.html#id-1.11.7.17.6">F.8.1. Example Usage</a></span></dt><dt><span class="sect2"><a href="btree-gin.html#id-1.11.7.17.7">F.8.2. Authors</a></span></dt></dl></div><a id="id-1.11.7.17.2" class="indexterm"></a><p>
+ <code class="filename">btree_gin</code> provides sample GIN operator classes that
+ implement B-tree equivalent behavior for the data types
+ <code class="type">int2</code>, <code class="type">int4</code>, <code class="type">int8</code>, <code class="type">float4</code>,
+ <code class="type">float8</code>, <code class="type">timestamp with time zone</code>,
+ <code class="type">timestamp without time zone</code>, <code class="type">time with time zone</code>,
+ <code class="type">time without time zone</code>, <code class="type">date</code>, <code class="type">interval</code>,
+ <code class="type">oid</code>, <code class="type">money</code>, <code class="type">"char"</code>,
+ <code class="type">varchar</code>, <code class="type">text</code>, <code class="type">bytea</code>, <code class="type">bit</code>,
+ <code class="type">varbit</code>, <code class="type">macaddr</code>, <code class="type">macaddr8</code>, <code class="type">inet</code>,
+ <code class="type">cidr</code>, <code class="type">uuid</code>, <code class="type">name</code>, <code class="type">bool</code>,
+ <code class="type">bpchar</code>, and all <code class="type">enum</code> types.
+ </p><p>
+ In general, these operator classes will not outperform the equivalent
+ standard B-tree index methods, and they lack one major feature of the
+ standard B-tree code: the ability to enforce uniqueness. However,
+ they are useful for GIN testing and as a base for developing other
+ GIN operator classes. Also, for queries that test both a GIN-indexable
+ column and a B-tree-indexable column, it might be more efficient to create
+ a multicolumn GIN index that uses one of these operator classes than to create
+ two separate indexes that would have to be combined via bitmap ANDing.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.17.6"><div class="titlepage"><div><div><h3 class="title">F.8.1. Example Usage</h3></div></div></div><pre class="programlisting">
+CREATE TABLE test (a int4);
+-- create index
+CREATE INDEX testidx ON test USING GIN (a);
+-- query
+SELECT * FROM test WHERE a &lt; 10;
+</pre></div><div class="sect2" id="id-1.11.7.17.7"><div class="titlepage"><div><div><h3 class="title">F.8.2. Authors</h3></div></div></div><p>
+ Teodor Sigaev (<code class="email">&lt;<a class="email" href="mailto:teodor@stack.net">teodor@stack.net</a>&gt;</code>) and
+ Oleg Bartunov (<code class="email">&lt;<a class="email" href="mailto:oleg@sai.msu.su">oleg@sai.msu.su</a>&gt;</code>). See
+ <a class="ulink" href="http://www.sai.msu.su/~megera/oddmuse/index.cgi/Gin" target="_top">http://www.sai.msu.su/~megera/oddmuse/index.cgi/Gin</a>
+ for additional information.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bloom.html" title="F.7. bloom">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree-gist.html" title="F.9. btree_gist">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.7. bloom </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.9. btree_gist</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree-gist.html b/doc/src/sgml/html/btree-gist.html
new file mode 100644
index 0000000..12aaa60
--- /dev/null
+++ b/doc/src/sgml/html/btree-gist.html
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.9. btree_gist</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree-gin.html" title="F.8. btree_gin" /><link rel="next" href="citext.html" title="F.10. citext" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.9. btree_gist</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree-gin.html" title="F.8. btree_gin">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="citext.html" title="F.10. citext">Next</a></td></tr></table><hr /></div><div class="sect1" id="BTREE-GIST"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.9. btree_gist</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="btree-gist.html#id-1.11.7.18.8">F.9.1. Example Usage</a></span></dt><dt><span class="sect2"><a href="btree-gist.html#id-1.11.7.18.9">F.9.2. Authors</a></span></dt></dl></div><a id="id-1.11.7.18.2" class="indexterm"></a><p>
+ <code class="filename">btree_gist</code> provides GiST index operator classes that
+ implement B-tree equivalent behavior for the data types
+ <code class="type">int2</code>, <code class="type">int4</code>, <code class="type">int8</code>, <code class="type">float4</code>,
+ <code class="type">float8</code>, <code class="type">numeric</code>, <code class="type">timestamp with time zone</code>,
+ <code class="type">timestamp without time zone</code>, <code class="type">time with time zone</code>,
+ <code class="type">time without time zone</code>, <code class="type">date</code>, <code class="type">interval</code>,
+ <code class="type">oid</code>, <code class="type">money</code>, <code class="type">char</code>,
+ <code class="type">varchar</code>, <code class="type">text</code>, <code class="type">bytea</code>, <code class="type">bit</code>,
+ <code class="type">varbit</code>, <code class="type">macaddr</code>, <code class="type">macaddr8</code>, <code class="type">inet</code>,
+ <code class="type">cidr</code>, <code class="type">uuid</code>, <code class="type">bool</code> and all <code class="type">enum</code> types.
+ </p><p>
+ In general, these operator classes will not outperform the equivalent
+ standard B-tree index methods, and they lack one major feature of the
+ standard B-tree code: the ability to enforce uniqueness. However,
+ they provide some other features that are not available with a B-tree
+ index, as described below. Also, these operator classes are useful
+ when a multicolumn GiST index is needed, wherein some of the columns
+ are of data types that are only indexable with GiST but other columns
+ are just simple data types. Lastly, these operator classes are useful for
+ GiST testing and as a base for developing other GiST operator classes.
+ </p><p>
+ In addition to the typical B-tree search operators, <code class="filename">btree_gist</code>
+ also provides index support for <code class="literal">&lt;&gt;</code> (<span class="quote">“<span class="quote">not
+ equals</span>”</span>). This may be useful in combination with an
+ <a class="link" href="sql-createtable.html#SQL-CREATETABLE-EXCLUDE">exclusion constraint</a>,
+ as described below.
+ </p><p>
+ Also, for data types for which there is a natural distance metric,
+ <code class="filename">btree_gist</code> defines a distance operator <code class="literal">&lt;-&gt;</code>,
+ and provides GiST index support for nearest-neighbor searches using
+ this operator. Distance operators are provided for
+ <code class="type">int2</code>, <code class="type">int4</code>, <code class="type">int8</code>, <code class="type">float4</code>,
+ <code class="type">float8</code>, <code class="type">timestamp with time zone</code>,
+ <code class="type">timestamp without time zone</code>,
+ <code class="type">time without time zone</code>, <code class="type">date</code>, <code class="type">interval</code>,
+ <code class="type">oid</code>, and <code class="type">money</code>.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.18.8"><div class="titlepage"><div><div><h3 class="title">F.9.1. Example Usage</h3></div></div></div><p>
+ Simple example using <code class="literal">btree_gist</code> instead of <code class="literal">btree</code>:
+ </p><pre class="programlisting">
+CREATE TABLE test (a int4);
+-- create index
+CREATE INDEX testidx ON test USING GIST (a);
+-- query
+SELECT * FROM test WHERE a &lt; 10;
+-- nearest-neighbor search: find the ten entries closest to "42"
+SELECT *, a &lt;-&gt; 42 AS dist FROM test ORDER BY a &lt;-&gt; 42 LIMIT 10;
+</pre><p>
+ Use an <a class="link" href="sql-createtable.html#SQL-CREATETABLE-EXCLUDE">exclusion
+ constraint</a> to enforce the rule that a cage at a zoo
+ can contain only one kind of animal:
+ </p><pre class="programlisting">
+=&gt; CREATE TABLE zoo (
+ cage INTEGER,
+ animal TEXT,
+ EXCLUDE USING GIST (cage WITH =, animal WITH &lt;&gt;)
+);
+
+=&gt; INSERT INTO zoo VALUES(123, 'zebra');
+INSERT 0 1
+=&gt; INSERT INTO zoo VALUES(123, 'zebra');
+INSERT 0 1
+=&gt; INSERT INTO zoo VALUES(123, 'lion');
+ERROR: conflicting key value violates exclusion constraint "zoo_cage_animal_excl"
+DETAIL: Key (cage, animal)=(123, lion) conflicts with existing key (cage, animal)=(123, zebra).
+=&gt; INSERT INTO zoo VALUES(124, 'lion');
+INSERT 0 1
+</pre></div><div class="sect2" id="id-1.11.7.18.9"><div class="titlepage"><div><div><h3 class="title">F.9.2. Authors</h3></div></div></div><p>
+ Teodor Sigaev (<code class="email">&lt;<a class="email" href="mailto:teodor@stack.net">teodor@stack.net</a>&gt;</code>),
+ Oleg Bartunov (<code class="email">&lt;<a class="email" href="mailto:oleg@sai.msu.su">oleg@sai.msu.su</a>&gt;</code>),
+ Janko Richter (<code class="email">&lt;<a class="email" href="mailto:jankorichter@yahoo.de">jankorichter@yahoo.de</a>&gt;</code>), and
+ Paul Jungwirth (<code class="email">&lt;<a class="email" href="mailto:pj@illuminatedcomputing.com">pj@illuminatedcomputing.com</a>&gt;</code>). See
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/" target="_top">http://www.sai.msu.su/~megera/postgres/gist/</a>
+ for additional information.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree-gin.html" title="F.8. btree_gin">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="citext.html" title="F.10. citext">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.8. btree_gin </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.10. citext</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree-implementation.html b/doc/src/sgml/html/btree-implementation.html
new file mode 100644
index 0000000..7897849
--- /dev/null
+++ b/doc/src/sgml/html/btree-implementation.html
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>67.4. Implementation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions" /><link rel="next" href="gist.html" title="Chapter 68. GiST Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">67.4. Implementation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><th width="60%" align="center">Chapter 67. B-Tree Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gist.html" title="Chapter 68. GiST Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="BTREE-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">67.4. Implementation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="btree-implementation.html#BTREE-STRUCTURE">67.4.1. B-Tree Structure</a></span></dt><dt><span class="sect2"><a href="btree-implementation.html#BTREE-DELETION">67.4.2. Bottom-up Index Deletion</a></span></dt><dt><span class="sect2"><a href="btree-implementation.html#BTREE-DEDUPLICATION">67.4.3. Deduplication</a></span></dt></dl></div><p>
+ This section covers B-Tree index implementation details that may be
+ of use to advanced users. See
+ <code class="filename">src/backend/access/nbtree/README</code> in the source
+ distribution for a much more detailed, internals-focused description
+ of the B-Tree implementation.
+ </p><div class="sect2" id="BTREE-STRUCTURE"><div class="titlepage"><div><div><h3 class="title">67.4.1. B-Tree Structure</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> B-Tree indexes are
+ multi-level tree structures, where each level of the tree can be
+ used as a doubly-linked list of pages. A single metapage is stored
+ in a fixed position at the start of the first segment file of the
+ index. All other pages are either leaf pages or internal pages.
+ Leaf pages are the pages on the lowest level of the tree. All
+ other levels consist of internal pages. Each leaf page contains
+ tuples that point to table rows. Each internal page contains
+ tuples that point to the next level down in the tree. Typically,
+ over 99% of all pages are leaf pages. Both internal pages and leaf
+ pages use the standard page format described in <a class="xref" href="storage-page-layout.html" title="73.6. Database Page Layout">Section 73.6</a>.
+ </p><p>
+ New leaf pages are added to a B-Tree index when an existing leaf
+ page cannot fit an incoming tuple. A <em class="firstterm">page
+ split</em> operation makes room for items that originally
+ belonged on the overflowing page by moving a portion of the items
+ to a new page. Page splits must also insert a new
+ <em class="firstterm">downlink</em> to the new page in the parent page,
+ which may cause the parent to split in turn. Page splits
+ <span class="quote">“<span class="quote">cascade upwards</span>”</span> in a recursive fashion. When the
+ root page finally cannot fit a new downlink, a <em class="firstterm">root page
+ split</em> operation takes place. This adds a new level to
+ the tree structure by creating a new root page that is one level
+ above the original root page.
+ </p></div><div class="sect2" id="BTREE-DELETION"><div class="titlepage"><div><div><h3 class="title">67.4.2. Bottom-up Index Deletion</h3></div></div></div><p>
+ B-Tree indexes are not directly aware that under MVCC, there might
+ be multiple extant versions of the same logical table row; to an
+ index, each tuple is an independent object that needs its own index
+ entry. <span class="quote">“<span class="quote">Version churn</span>”</span> tuples may sometimes
+ accumulate and adversely affect query latency and throughput. This
+ typically occurs with <code class="command">UPDATE</code>-heavy workloads
+ where most individual updates cannot apply the
+ <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)"><acronym class="acronym">HOT</acronym> optimization.</a>
+ Changing the value of only
+ one column covered by one index during an <code class="command">UPDATE</code>
+ <span class="emphasis"><em>always</em></span> necessitates a new set of index tuples
+ — one for <span class="emphasis"><em>each and every</em></span> index on the
+ table. Note in particular that this includes indexes that were not
+ <span class="quote">“<span class="quote">logically modified</span>”</span> by the <code class="command">UPDATE</code>.
+ All indexes will need a successor physical index tuple that points
+ to the latest version in the table. Each new tuple within each
+ index will generally need to coexist with the original
+ <span class="quote">“<span class="quote">updated</span>”</span> tuple for a short period of time (typically
+ until shortly after the <code class="command">UPDATE</code> transaction
+ commits).
+ </p><p>
+ B-Tree indexes incrementally delete version churn index tuples by
+ performing <em class="firstterm">bottom-up index deletion</em> passes.
+ Each deletion pass is triggered in reaction to an anticipated
+ <span class="quote">“<span class="quote">version churn page split</span>”</span>. This only happens with
+ indexes that are not logically modified by
+ <code class="command">UPDATE</code> statements, where concentrated build up
+ of obsolete versions in particular pages would occur otherwise. A
+ page split will usually be avoided, though it's possible that
+ certain implementation-level heuristics will fail to identify and
+ delete even one garbage index tuple (in which case a page split or
+ deduplication pass resolves the issue of an incoming new tuple not
+ fitting on a leaf page). The worst-case number of versions that
+ any index scan must traverse (for any single logical row) is an
+ important contributor to overall system responsiveness and
+ throughput. A bottom-up index deletion pass targets suspected
+ garbage tuples in a single leaf page based on
+ <span class="emphasis"><em>qualitative</em></span> distinctions involving logical
+ rows and versions. This contrasts with the <span class="quote">“<span class="quote">top-down</span>”</span>
+ index cleanup performed by autovacuum workers, which is triggered
+ when certain <span class="emphasis"><em>quantitative</em></span> table-level
+ thresholds are exceeded (see <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Not all deletion operations that are performed within B-Tree
+ indexes are bottom-up deletion operations. There is a distinct
+ category of index tuple deletion: <em class="firstterm">simple index tuple
+ deletion</em>. This is a deferred maintenance operation
+ that deletes index tuples that are known to be safe to delete
+ (those whose item identifier's <code class="literal">LP_DEAD</code> bit is
+ already set). Like bottom-up index deletion, simple index
+ deletion takes place at the point that a page split is anticipated
+ as a way of avoiding the split.
+ </p><p>
+ Simple deletion is opportunistic in the sense that it can only
+ take place when recent index scans set the
+ <code class="literal">LP_DEAD</code> bits of affected items in passing.
+ Prior to <span class="productname">PostgreSQL</span> 14, the only
+ category of B-Tree deletion was simple deletion. The main
+ differences between it and bottom-up deletion are that only the
+ former is opportunistically driven by the activity of passing
+ index scans, while only the latter specifically targets version
+ churn from <code class="command">UPDATE</code>s that do not logically modify
+ indexed columns.
+ </p></div><p>
+ Bottom-up index deletion performs the vast majority of all garbage
+ index tuple cleanup for particular indexes with certain workloads.
+ This is expected with any B-Tree index that is subject to
+ significant version churn from <code class="command">UPDATE</code>s that
+ rarely or never logically modify the columns that the index covers.
+ The average and worst-case number of versions per logical row can
+ be kept low purely through targeted incremental deletion passes.
+ It's quite possible that the on-disk size of certain indexes will
+ never increase by even one single page/block despite
+ <span class="emphasis"><em>constant</em></span> version churn from
+ <code class="command">UPDATE</code>s. Even then, an exhaustive <span class="quote">“<span class="quote">clean
+ sweep</span>”</span> by a <code class="command">VACUUM</code> operation (typically
+ run in an autovacuum worker process) will eventually be required as
+ a part of <span class="emphasis"><em>collective</em></span> cleanup of the table and
+ each of its indexes.
+ </p><p>
+ Unlike <code class="command">VACUUM</code>, bottom-up index deletion does not
+ provide any strong guarantees about how old the oldest garbage
+ index tuple may be. No index can be permitted to retain
+ <span class="quote">“<span class="quote">floating garbage</span>”</span> index tuples that became dead prior
+ to a conservative cutoff point shared by the table and all of its
+ indexes collectively. This fundamental table-level invariant makes
+ it safe to recycle table <acronym class="acronym">TID</acronym>s. This is how it
+ is possible for distinct logical rows to reuse the same table
+ <acronym class="acronym">TID</acronym> over time (though this can never happen with
+ two logical rows whose lifetimes span the same
+ <code class="command">VACUUM</code> cycle).
+ </p></div><div class="sect2" id="BTREE-DEDUPLICATION"><div class="titlepage"><div><div><h3 class="title">67.4.3. Deduplication</h3></div></div></div><p>
+ A duplicate is a leaf page tuple (a tuple that points to a table
+ row) where <span class="emphasis"><em>all</em></span> indexed key columns have values
+ that match corresponding column values from at least one other leaf
+ page tuple in the same index. Duplicate tuples are quite common in
+ practice. B-Tree indexes can use a special, space-efficient
+ representation for duplicates when an optional technique is
+ enabled: <em class="firstterm">deduplication</em>.
+ </p><p>
+ Deduplication works by periodically merging groups of duplicate
+ tuples together, forming a single <em class="firstterm">posting list</em> tuple for each
+ group. The column key value(s) only appear once in this
+ representation. This is followed by a sorted array of
+ <acronym class="acronym">TID</acronym>s that point to rows in the table. This
+ significantly reduces the storage size of indexes where each value
+ (or each distinct combination of column values) appears several
+ times on average. The latency of queries can be reduced
+ significantly. Overall query throughput may increase
+ significantly. The overhead of routine index vacuuming may also be
+ reduced significantly.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ B-Tree deduplication is just as effective with
+ <span class="quote">“<span class="quote">duplicates</span>”</span> that contain a NULL value, even though
+ NULL values are never equal to each other according to the
+ <code class="literal">=</code> member of any B-Tree operator class. As far
+ as any part of the implementation that understands the on-disk
+ B-Tree structure is concerned, NULL is just another value from the
+ domain of indexed values.
+ </p></div><p>
+ The deduplication process occurs lazily, when a new item is
+ inserted that cannot fit on an existing leaf page, though only when
+ index tuple deletion could not free sufficient space for the new
+ item (typically deletion is briefly considered and then skipped
+ over). Unlike GIN posting list tuples, B-Tree posting list tuples
+ do not need to expand every time a new duplicate is inserted; they
+ are merely an alternative physical representation of the original
+ logical contents of the leaf page. This design prioritizes
+ consistent performance with mixed read-write workloads. Most
+ client applications will at least see a moderate performance
+ benefit from using deduplication. Deduplication is enabled by
+ default.
+ </p><p>
+ <code class="command">CREATE INDEX</code> and <code class="command">REINDEX</code>
+ apply deduplication to create posting list tuples, though the
+ strategy they use is slightly different. Each group of duplicate
+ ordinary tuples encountered in the sorted input taken from the
+ table is merged into a posting list tuple
+ <span class="emphasis"><em>before</em></span> being added to the current pending leaf
+ page. Individual posting list tuples are packed with as many
+ <acronym class="acronym">TID</acronym>s as possible. Leaf pages are written out in
+ the usual way, without any separate deduplication pass. This
+ strategy is well-suited to <code class="command">CREATE INDEX</code> and
+ <code class="command">REINDEX</code> because they are once-off batch
+ operations.
+ </p><p>
+ Write-heavy workloads that don't benefit from deduplication due to
+ having few or no duplicate values in indexes will incur a small,
+ fixed performance penalty (unless deduplication is explicitly
+ disabled). The <code class="literal">deduplicate_items</code> storage
+ parameter can be used to disable deduplication within individual
+ indexes. There is never any performance penalty with read-only
+ workloads, since reading posting list tuples is at least as
+ efficient as reading the standard tuple representation. Disabling
+ deduplication isn't usually helpful.
+ </p><p>
+ It is sometimes possible for unique indexes (as well as unique
+ constraints) to use deduplication. This allows leaf pages to
+ temporarily <span class="quote">“<span class="quote">absorb</span>”</span> extra version churn duplicates.
+ Deduplication in unique indexes augments bottom-up index deletion,
+ especially in cases where a long-running transaction holds a
+ snapshot that blocks garbage collection. The goal is to buy time
+ for the bottom-up index deletion strategy to become effective
+ again. Delaying page splits until a single long-running
+ transaction naturally goes away can allow a bottom-up deletion pass
+ to succeed where an earlier deletion pass failed.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ A special heuristic is applied to determine whether a
+ deduplication pass in a unique index should take place. It can
+ often skip straight to splitting a leaf page, avoiding a
+ performance penalty from wasting cycles on unhelpful deduplication
+ passes. If you're concerned about the overhead of deduplication,
+ consider setting <code class="literal">deduplicate_items = off</code>
+ selectively. Leaving deduplication enabled in unique indexes has
+ little downside.
+ </p></div><p>
+ Deduplication cannot be used in all cases due to
+ implementation-level restrictions. Deduplication safety is
+ determined when <code class="command">CREATE INDEX</code> or
+ <code class="command">REINDEX</code> is run.
+ </p><p>
+ Note that deduplication is deemed unsafe and cannot be used in the
+ following cases involving semantically significant differences
+ among equal datums:
+ </p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="type">text</code>, <code class="type">varchar</code>, and <code class="type">char</code>
+ cannot use deduplication when a
+ <span class="emphasis"><em>nondeterministic</em></span> collation is used. Case
+ and accent differences must be preserved among equal datums.
+ </p></li><li class="listitem"><p>
+ <code class="type">numeric</code> cannot use deduplication. Numeric display
+ scale must be preserved among equal datums.
+ </p></li><li class="listitem"><p>
+ <code class="type">jsonb</code> cannot use deduplication, since the
+ <code class="type">jsonb</code> B-Tree operator class uses
+ <code class="type">numeric</code> internally.
+ </p></li><li class="listitem"><p>
+ <code class="type">float4</code> and <code class="type">float8</code> cannot use
+ deduplication. These types have distinct representations for
+ <code class="literal">-0</code> and <code class="literal">0</code>, which are
+ nevertheless considered equal. This difference must be
+ preserved.
+ </p></li></ul></div><p>
+ </p><p>
+ There is one further implementation-level restriction that may be
+ lifted in a future version of
+ <span class="productname">PostgreSQL</span>:
+ </p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Container types (such as composite types, arrays, or range
+ types) cannot use deduplication.
+ </p></li></ul></div><p>
+ </p><p>
+ There is one further implementation-level restriction that applies
+ regardless of the operator class or collation used:
+ </p><p>
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">INCLUDE</code> indexes can never use deduplication.
+ </p></li></ul></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gist.html" title="Chapter 68. GiST Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">67.3. B-Tree Support Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 68. GiST Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree-intro.html b/doc/src/sgml/html/btree-intro.html
new file mode 100644
index 0000000..67c0c97
--- /dev/null
+++ b/doc/src/sgml/html/btree-intro.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>67.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree.html" title="Chapter 67. B-Tree Indexes" /><link rel="next" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">67.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree.html" title="Chapter 67. B-Tree Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><th width="60%" align="center">Chapter 67. B-Tree Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes">Next</a></td></tr></table><hr /></div><div class="sect1" id="BTREE-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">67.1. Introduction</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> includes an implementation of the
+ standard <acronym class="acronym">btree</acronym> (multi-way balanced tree) index data
+ structure. Any data type that can be sorted into a well-defined linear
+ order can be indexed by a btree index. The only limitation is that an
+ index entry cannot exceed approximately one-third of a page (after TOAST
+ compression, if applicable).
+ </p><p>
+ Because each btree operator class imposes a sort order on its data type,
+ btree operator classes (or, really, operator families) have come to be
+ used as <span class="productname">PostgreSQL</span>'s general representation
+ and understanding of sorting semantics. Therefore, they've acquired
+ some features that go beyond what would be needed just to support btree
+ indexes, and parts of the system that are quite distant from the
+ btree AM make use of them.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree.html" title="Chapter 67. B-Tree Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 67. B-Tree Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 67.2. Behavior of B-Tree Operator Classes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree-support-funcs.html b/doc/src/sgml/html/btree-support-funcs.html
new file mode 100644
index 0000000..b755783
--- /dev/null
+++ b/doc/src/sgml/html/btree-support-funcs.html
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>67.3. B-Tree Support Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes" /><link rel="next" href="btree-implementation.html" title="67.4. Implementation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">67.3. B-Tree Support Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><th width="60%" align="center">Chapter 67. B-Tree Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree-implementation.html" title="67.4. Implementation">Next</a></td></tr></table><hr /></div><div class="sect1" id="BTREE-SUPPORT-FUNCS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">67.3. B-Tree Support Functions</h2></div></div></div><p>
+ As shown in <a class="xref" href="xindex.html#XINDEX-BTREE-SUPPORT-TABLE" title="Table 38.9. B-Tree Support Functions">Table 38.9</a>, btree defines
+ one required and four optional support functions. The five
+ user-defined methods are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">order</code></span></dt><dd><p>
+ For each combination of data types that a btree operator family
+ provides comparison operators for, it must provide a comparison
+ support function, registered in
+ <code class="structname">pg_amproc</code> with support function number 1
+ and
+ <code class="structfield">amproclefttype</code>/<code class="structfield">amprocrighttype</code>
+ equal to the left and right data types for the comparison (i.e.,
+ the same data types that the matching operators are registered
+ with in <code class="structname">pg_amop</code>). The comparison
+ function must take two non-null values
+ <em class="replaceable"><code>A</code></em> and <em class="replaceable"><code>B</code></em> and
+ return an <code class="type">int32</code> value that is
+ <code class="literal">&lt;</code> <code class="literal">0</code>,
+ <code class="literal">0</code>, or <code class="literal">&gt;</code>
+ <code class="literal">0</code> when <em class="replaceable"><code>A</code></em>
+ <code class="literal">&lt;</code> <em class="replaceable"><code>B</code></em>,
+ <em class="replaceable"><code>A</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>B</code></em>, or <em class="replaceable"><code>A</code></em>
+ <code class="literal">&gt;</code> <em class="replaceable"><code>B</code></em>,
+ respectively. A null result is disallowed: all values of the
+ data type must be comparable. See
+ <code class="filename">src/backend/access/nbtree/nbtcompare.c</code> for
+ examples.
+ </p><p>
+ If the compared values are of a collatable data type, the
+ appropriate collation OID will be passed to the comparison
+ support function, using the standard
+ <code class="function">PG_GET_COLLATION()</code> mechanism.
+ </p></dd><dt><span class="term"><code class="function">sortsupport</code></span></dt><dd><p>
+ Optionally, a btree operator family may provide <em class="firstterm">sort
+ support</em> function(s), registered under support
+ function number 2. These functions allow implementing
+ comparisons for sorting purposes in a more efficient way than
+ naively calling the comparison support function. The APIs
+ involved in this are defined in
+ <code class="filename">src/include/utils/sortsupport.h</code>.
+ </p></dd><dt><span class="term"><code class="function">in_range</code></span></dt><dd><a id="id-1.10.18.5.3.3.2.1" class="indexterm"></a><a id="id-1.10.18.5.3.3.2.2" class="indexterm"></a><p>
+ Optionally, a btree operator family may provide
+ <em class="firstterm">in_range</em> support function(s), registered
+ under support function number 3. These are not used during btree
+ index operations; rather, they extend the semantics of the
+ operator family so that it can support window clauses containing
+ the <code class="literal">RANGE</code> <em class="replaceable"><code>offset</code></em>
+ <code class="literal">PRECEDING</code> and <code class="literal">RANGE</code>
+ <em class="replaceable"><code>offset</code></em> <code class="literal">FOLLOWING</code>
+ frame bound types (see <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a>). Fundamentally, the extra
+ information provided is how to add or subtract an
+ <em class="replaceable"><code>offset</code></em> value in a way that is
+ compatible with the family's data ordering.
+ </p><p>
+ An <code class="function">in_range</code> function must have the signature
+</p><pre class="synopsis">
+in_range(<em class="replaceable"><code>val</code></em> type1, <em class="replaceable"><code>base</code></em> type1, <em class="replaceable"><code>offset</code></em> type2, <em class="replaceable"><code>sub</code></em> bool, <em class="replaceable"><code>less</code></em> bool)
+returns bool
+</pre><p>
+ <em class="replaceable"><code>val</code></em> and
+ <em class="replaceable"><code>base</code></em> must be of the same type, which
+ is one of the types supported by the operator family (i.e., a
+ type for which it provides an ordering). However,
+ <em class="replaceable"><code>offset</code></em> could be of a different type,
+ which might be one otherwise unsupported by the family. An
+ example is that the built-in <code class="literal">time_ops</code> family
+ provides an <code class="function">in_range</code> function that has
+ <em class="replaceable"><code>offset</code></em> of type <code class="type">interval</code>.
+ A family can provide <code class="function">in_range</code> functions for
+ any of its supported types and one or more
+ <em class="replaceable"><code>offset</code></em> types. Each
+ <code class="function">in_range</code> function should be entered in
+ <code class="structname">pg_amproc</code> with
+ <code class="structfield">amproclefttype</code> equal to
+ <code class="type">type1</code> and <code class="structfield">amprocrighttype</code>
+ equal to <code class="type">type2</code>.
+ </p><p>
+ The essential semantics of an <code class="function">in_range</code>
+ function depend on the two Boolean flag parameters. It should
+ add or subtract <em class="replaceable"><code>base</code></em> and
+ <em class="replaceable"><code>offset</code></em>, then compare
+ <em class="replaceable"><code>val</code></em> to the result, as follows:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ if <code class="literal">!</code><em class="replaceable"><code>sub</code></em> and
+ <code class="literal">!</code><em class="replaceable"><code>less</code></em>, return
+ <em class="replaceable"><code>val</code></em> <code class="literal">&gt;=</code>
+ (<em class="replaceable"><code>base</code></em> <code class="literal">+</code>
+ <em class="replaceable"><code>offset</code></em>)
+ </p></li><li class="listitem"><p>
+ if <code class="literal">!</code><em class="replaceable"><code>sub</code></em> and
+ <em class="replaceable"><code>less</code></em>, return
+ <em class="replaceable"><code>val</code></em> <code class="literal">&lt;=</code>
+ (<em class="replaceable"><code>base</code></em> <code class="literal">+</code>
+ <em class="replaceable"><code>offset</code></em>)
+ </p></li><li class="listitem"><p>
+ if <em class="replaceable"><code>sub</code></em> and
+ <code class="literal">!</code><em class="replaceable"><code>less</code></em>, return
+ <em class="replaceable"><code>val</code></em> <code class="literal">&gt;=</code>
+ (<em class="replaceable"><code>base</code></em> <code class="literal">-</code>
+ <em class="replaceable"><code>offset</code></em>)
+ </p></li><li class="listitem"><p>
+ if <em class="replaceable"><code>sub</code></em> and
+ <em class="replaceable"><code>less</code></em>, return
+ <em class="replaceable"><code>val</code></em> <code class="literal">&lt;=</code>
+ (<em class="replaceable"><code>base</code></em> <code class="literal">-</code>
+ <em class="replaceable"><code>offset</code></em>)
+ </p></li></ul></div><p>
+ Before doing so, the function should check the sign of
+ <em class="replaceable"><code>offset</code></em>: if it is less than zero, raise
+ error
+ <code class="literal">ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE</code>
+ (22013) with error text like <span class="quote">“<span class="quote">invalid preceding or
+ following size in window function</span>”</span>. (This is required by
+ the SQL standard, although nonstandard operator families might
+ perhaps choose to ignore this restriction, since there seems to
+ be little semantic necessity for it.) This requirement is
+ delegated to the <code class="function">in_range</code> function so that
+ the core code needn't understand what <span class="quote">“<span class="quote">less than
+ zero</span>”</span> means for a particular data type.
+ </p><p>
+ An additional expectation is that <code class="function">in_range</code>
+ functions should, if practical, avoid throwing an error if
+ <em class="replaceable"><code>base</code></em> <code class="literal">+</code>
+ <em class="replaceable"><code>offset</code></em> or
+ <em class="replaceable"><code>base</code></em> <code class="literal">-</code>
+ <em class="replaceable"><code>offset</code></em> would overflow. The correct
+ comparison result can be determined even if that value would be
+ out of the data type's range. Note that if the data type
+ includes concepts such as <span class="quote">“<span class="quote">infinity</span>”</span> or
+ <span class="quote">“<span class="quote">NaN</span>”</span>, extra care may be needed to ensure that
+ <code class="function">in_range</code>'s results agree with the normal
+ sort order of the operator family.
+ </p><p>
+ The results of the <code class="function">in_range</code> function must be
+ consistent with the sort ordering imposed by the operator family.
+ To be precise, given any fixed values of
+ <em class="replaceable"><code>offset</code></em> and
+ <em class="replaceable"><code>sub</code></em>, then:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If <code class="function">in_range</code> with
+ <em class="replaceable"><code>less</code></em> = true is true for some
+ <em class="replaceable"><code>val1</code></em> and
+ <em class="replaceable"><code>base</code></em>, it must be true for every
+ <em class="replaceable"><code>val2</code></em> <code class="literal">&lt;=</code>
+ <em class="replaceable"><code>val1</code></em> with the same
+ <em class="replaceable"><code>base</code></em>.
+ </p></li><li class="listitem"><p>
+ If <code class="function">in_range</code> with
+ <em class="replaceable"><code>less</code></em> = true is false for some
+ <em class="replaceable"><code>val1</code></em> and
+ <em class="replaceable"><code>base</code></em>, it must be false for every
+ <em class="replaceable"><code>val2</code></em> <code class="literal">&gt;=</code>
+ <em class="replaceable"><code>val1</code></em> with the same
+ <em class="replaceable"><code>base</code></em>.
+ </p></li><li class="listitem"><p>
+ If <code class="function">in_range</code> with
+ <em class="replaceable"><code>less</code></em> = true is true for some
+ <em class="replaceable"><code>val</code></em> and
+ <em class="replaceable"><code>base1</code></em>, it must be true for every
+ <em class="replaceable"><code>base2</code></em> <code class="literal">&gt;=</code>
+ <em class="replaceable"><code>base1</code></em> with the same
+ <em class="replaceable"><code>val</code></em>.
+ </p></li><li class="listitem"><p>
+ If <code class="function">in_range</code> with
+ <em class="replaceable"><code>less</code></em> = true is false for some
+ <em class="replaceable"><code>val</code></em> and
+ <em class="replaceable"><code>base1</code></em>, it must be false for every
+ <em class="replaceable"><code>base2</code></em> <code class="literal">&lt;=</code>
+ <em class="replaceable"><code>base1</code></em> with the same
+ <em class="replaceable"><code>val</code></em>.
+ </p></li></ul></div><p>
+ Analogous statements with inverted conditions hold when
+ <em class="replaceable"><code>less</code></em> = false.
+ </p><p>
+ If the type being ordered (<code class="type">type1</code>) is collatable, the
+ appropriate collation OID will be passed to the
+ <code class="function">in_range</code> function, using the standard
+ PG_GET_COLLATION() mechanism.
+ </p><p>
+ <code class="function">in_range</code> functions need not handle NULL
+ inputs, and typically will be marked strict.
+ </p></dd><dt><span class="term"><code class="function">equalimage</code></span></dt><dd><p>
+ Optionally, a btree operator family may provide
+ <code class="function">equalimage</code> (<span class="quote">“<span class="quote">equality implies image
+ equality</span>”</span>) support functions, registered under support
+ function number 4. These functions allow the core code to
+ determine when it is safe to apply the btree deduplication
+ optimization. Currently, <code class="function">equalimage</code>
+ functions are only called when building or rebuilding an index.
+ </p><p>
+ An <code class="function">equalimage</code> function must have the
+ signature
+</p><pre class="synopsis">
+equalimage(<em class="replaceable"><code>opcintype</code></em> <code class="type">oid</code>) returns bool
+</pre><p>
+ The return value is static information about an operator class
+ and collation. Returning <code class="literal">true</code> indicates that
+ the <code class="function">order</code> function for the operator class is
+ guaranteed to only return <code class="literal">0</code> (<span class="quote">“<span class="quote">arguments
+ are equal</span>”</span>) when its <em class="replaceable"><code>A</code></em> and
+ <em class="replaceable"><code>B</code></em> arguments are also interchangeable
+ without any loss of semantic information. Not registering an
+ <code class="function">equalimage</code> function or returning
+ <code class="literal">false</code> indicates that this condition cannot be
+ assumed to hold.
+ </p><p>
+ The <em class="replaceable"><code>opcintype</code></em> argument is the
+ <code class="literal"><code class="structname">pg_type</code>.oid</code> of the
+ data type that the operator class indexes. This is a convenience
+ that allows reuse of the same underlying
+ <code class="function">equalimage</code> function across operator classes.
+ If <em class="replaceable"><code>opcintype</code></em> is a collatable data
+ type, the appropriate collation OID will be passed to the
+ <code class="function">equalimage</code> function, using the standard
+ <code class="function">PG_GET_COLLATION()</code> mechanism.
+ </p><p>
+ As far as the operator class is concerned, returning
+ <code class="literal">true</code> indicates that deduplication is safe (or
+ safe for the collation whose OID was passed to its
+ <code class="function">equalimage</code> function). However, the core
+ code will only deem deduplication safe for an index when
+ <span class="emphasis"><em>every</em></span> indexed column uses an operator class
+ that registers an <code class="function">equalimage</code> function, and
+ each function actually returns <code class="literal">true</code> when
+ called.
+ </p><p>
+ Image equality is <span class="emphasis"><em>almost</em></span> the same condition
+ as simple bitwise equality. There is one subtle difference: When
+ indexing a varlena data type, the on-disk representation of two
+ image equal datums may not be bitwise equal due to inconsistent
+ application of <acronym class="acronym">TOAST</acronym> compression on input.
+ Formally, when an operator class's
+ <code class="function">equalimage</code> function returns
+ <code class="literal">true</code>, it is safe to assume that the
+ <code class="literal">datum_image_eq()</code> C function will always agree
+ with the operator class's <code class="function">order</code> function
+ (provided that the same collation OID is passed to both the
+ <code class="function">equalimage</code> and <code class="function">order</code>
+ functions).
+ </p><p>
+ The core code is fundamentally unable to deduce anything about
+ the <span class="quote">“<span class="quote">equality implies image equality</span>”</span> status of an
+ operator class within a multiple-data-type family based on
+ details from other operator classes in the same family. Also, it
+ is not sensible for an operator family to register a cross-type
+ <code class="function">equalimage</code> function, and attempting to do so
+ will result in an error. This is because <span class="quote">“<span class="quote">equality implies
+ image equality</span>”</span> status does not just depend on
+ sorting/equality semantics, which are more or less defined at the
+ operator family level. In general, the semantics that one
+ particular data type implements must be considered separately.
+ </p><p>
+ The convention followed by the operator classes included with the
+ core <span class="productname">PostgreSQL</span> distribution is to
+ register a stock, generic <code class="function">equalimage</code>
+ function. Most operator classes register
+ <code class="function">btequalimage()</code>, which indicates that
+ deduplication is safe unconditionally. Operator classes for
+ collatable data types such as <code class="type">text</code> register
+ <code class="function">btvarstrequalimage()</code>, which indicates that
+ deduplication is safe with deterministic collations. Best
+ practice for third-party extensions is to register their own
+ custom function to retain control.
+ </p></dd><dt><span class="term"><code class="function">options</code></span></dt><dd><p>
+ Optionally, a B-tree operator family may provide
+ <code class="function">options</code> (<span class="quote">“<span class="quote">operator class specific
+ options</span>”</span>) support functions, registered under support
+ function number 5. These functions define a set of user-visible
+ parameters that control operator class behavior.
+ </p><p>
+ An <code class="function">options</code> support function must have the
+ signature
+</p><pre class="synopsis">
+options(<em class="replaceable"><code>relopts</code></em> <code class="type">local_relopts *</code>) returns void
+</pre><p>
+ The function is passed a pointer to a <code class="structname">local_relopts</code>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using the <code class="literal">PG_HAS_OPCLASS_OPTIONS()</code> and
+ <code class="literal">PG_GET_OPCLASS_OPTIONS()</code> macros.
+ </p><p>
+ Currently, no B-Tree operator class has an <code class="function">options</code>
+ support function. B-tree doesn't allow flexible representation of keys
+ like GiST, SP-GiST, GIN and BRIN do. So, <code class="function">options</code>
+ probably doesn't have much application in the current B-tree index
+ access method. Nevertheless, this support function was added to B-tree
+ for uniformity, and will probably find uses during further
+ evolution of B-tree in <span class="productname">PostgreSQL</span>.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="btree.html" title="Chapter 67. B-Tree Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree-implementation.html" title="67.4. Implementation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">67.2. Behavior of B-Tree Operator Classes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 67.4. Implementation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/btree.html b/doc/src/sgml/html/btree.html
new file mode 100644
index 0000000..3a076cc
--- /dev/null
+++ b/doc/src/sgml/html/btree.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 67. B-Tree Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers" /><link rel="next" href="btree-intro.html" title="67.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 67. B-Tree Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree-intro.html" title="67.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="BTREE"><div class="titlepage"><div><div><h2 class="title">Chapter 67. B-Tree Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="btree-intro.html">67.1. Introduction</a></span></dt><dt><span class="sect1"><a href="btree-behavior.html">67.2. Behavior of B-Tree Operator Classes</a></span></dt><dt><span class="sect1"><a href="btree-support-funcs.html">67.3. B-Tree Support Functions</a></span></dt><dt><span class="sect1"><a href="btree-implementation.html">67.4. Implementation</a></span></dt><dd><dl><dt><span class="sect2"><a href="btree-implementation.html#BTREE-STRUCTURE">67.4.1. B-Tree Structure</a></span></dt><dt><span class="sect2"><a href="btree-implementation.html#BTREE-DELETION">67.4.2. Bottom-up Index Deletion</a></span></dt><dt><span class="sect2"><a href="btree-implementation.html#BTREE-DEDUPLICATION">67.4.3. Deduplication</a></span></dt></dl></dd></dl></div><a id="id-1.10.18.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree-intro.html" title="67.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 66. Custom WAL Resource Managers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 67.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/bug-reporting.html b/doc/src/sgml/html/bug-reporting.html
new file mode 100644
index 0000000..e5eaa4d
--- /dev/null
+++ b/doc/src/sgml/html/bug-reporting.html
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5. Bug Reporting Guidelines</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="resources.html" title="4. Further Information" /><link rel="next" href="tutorial.html" title="Part I. Tutorial" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5. Bug Reporting Guidelines</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="resources.html" title="4. Further Information">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><th width="60%" align="center">Preface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial.html" title="Part I. Tutorial">Next</a></td></tr></table><hr /></div><div class="sect1" id="BUG-REPORTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5. Bug Reporting Guidelines</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="bug-reporting.html#id-1.3.8.5">5.1. Identifying Bugs</a></span></dt><dt><span class="sect2"><a href="bug-reporting.html#id-1.3.8.6">5.2. What to Report</a></span></dt><dt><span class="sect2"><a href="bug-reporting.html#id-1.3.8.7">5.3. Where to Report Bugs</a></span></dt></dl></div><p>
+ When you find a bug in <span class="productname">PostgreSQL</span> we want to
+ hear about it. Your bug reports play an important part in making
+ <span class="productname">PostgreSQL</span> more reliable because even the utmost
+ care cannot guarantee that every part of
+ <span class="productname">PostgreSQL</span>
+ will work on every platform under every circumstance.
+ </p><p>
+ The following suggestions are intended to assist you in forming bug reports
+ that can be handled in an effective fashion. No one is required to follow
+ them but doing so tends to be to everyone's advantage.
+ </p><p>
+ We cannot promise to fix every bug right away. If the bug is obvious, critical,
+ or affects a lot of users, chances are good that someone will look into it. It
+ could also happen that we tell you to update to a newer version to see if the
+ bug happens there. Or we might decide that the bug
+ cannot be fixed before some major rewrite we might be planning is done. Or
+ perhaps it is simply too hard and there are more important things on the agenda.
+ If you need help immediately, consider obtaining a commercial support contract.
+ </p><div class="sect2" id="id-1.3.8.5"><div class="titlepage"><div><div><h3 class="title">5.1. Identifying Bugs</h3></div></div></div><p>
+ Before you report a bug, please read and re-read the
+ documentation to verify that you can really do whatever it is you are
+ trying. If it is not clear from the documentation whether you can do
+ something or not, please report that too; it is a bug in the documentation.
+ If it turns out that a program does something different from what the
+ documentation says, that is a bug. That might include, but is not limited to,
+ the following circumstances:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A program terminates with a fatal signal or an operating system
+ error message that would point to a problem in the program. (A
+ counterexample might be a <span class="quote">“<span class="quote">disk full</span>”</span> message,
+ since you have to fix that yourself.)
+ </p></li><li class="listitem"><p>
+ A program produces the wrong output for any given input.
+ </p></li><li class="listitem"><p>
+ A program refuses to accept valid input (as defined in the documentation).
+ </p></li><li class="listitem"><p>
+ A program accepts invalid input without a notice or error message.
+ But keep in mind that your idea of invalid input might be our idea of
+ an extension or compatibility with traditional practice.
+ </p></li><li class="listitem"><p>
+ <span class="productname">PostgreSQL</span> fails to compile, build, or
+ install according to the instructions on supported platforms.
+ </p></li></ul></div><p>
+
+ Here <span class="quote">“<span class="quote">program</span>”</span> refers to any executable, not only the backend process.
+ </p><p>
+ Being slow or resource-hogging is not necessarily a bug. Read the
+ documentation or ask on one of the mailing lists for help in tuning your
+ applications. Failing to comply to the <acronym class="acronym">SQL</acronym> standard is
+ not necessarily a bug either, unless compliance for the
+ specific feature is explicitly claimed.
+ </p><p>
+ Before you continue, check on the TODO list and in the FAQ to see if your bug is
+ already known. If you cannot decode the information on the TODO list, report your
+ problem. The least we can do is make the TODO list clearer.
+ </p></div><div class="sect2" id="id-1.3.8.6"><div class="titlepage"><div><div><h3 class="title">5.2. What to Report</h3></div></div></div><p>
+ The most important thing to remember about bug reporting is to state all
+ the facts and only facts. Do not speculate what you think went wrong, what
+ <span class="quote">“<span class="quote">it seemed to do</span>”</span>, or which part of the program has a fault.
+ If you are not familiar with the implementation you would probably guess
+ wrong and not help us a bit. And even if you are, educated explanations are
+ a great supplement to but no substitute for facts. If we are going to fix
+ the bug we still have to see it happen for ourselves first.
+ Reporting the bare facts
+ is relatively straightforward (you can probably copy and paste them from the
+ screen) but all too often important details are left out because someone
+ thought it does not matter or the report would be understood
+ anyway.
+ </p><p>
+ The following items should be contained in every bug report:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The exact sequence of steps <span class="emphasis"><em>from program
+ start-up</em></span> necessary to reproduce the problem. This
+ should be self-contained; it is not enough to send in a bare
+ <code class="command">SELECT</code> statement without the preceding
+ <code class="command">CREATE TABLE</code> and <code class="command">INSERT</code>
+ statements, if the output should depend on the data in the
+ tables. We do not have the time to reverse-engineer your
+ database schema, and if we are supposed to make up our own data
+ we would probably miss the problem.
+ </p><p>
+ The best format for a test case for SQL-related problems is a
+ file that can be run through the <span class="application">psql</span>
+ frontend that shows the problem. (Be sure to not have anything
+ in your <code class="filename">~/.psqlrc</code> start-up file.) An easy
+ way to create this file is to use <span class="application">pg_dump</span>
+ to dump out the table declarations and data needed to set the
+ scene, then add the problem query. You are encouraged to
+ minimize the size of your example, but this is not absolutely
+ necessary. If the bug is reproducible, we will find it either
+ way.
+ </p><p>
+ If your application uses some other client interface, such as <span class="application">PHP</span>, then
+ please try to isolate the offending queries. We will probably not set up a
+ web server to reproduce your problem. In any case remember to provide
+ the exact input files; do not guess that the problem happens for
+ <span class="quote">“<span class="quote">large files</span>”</span> or <span class="quote">“<span class="quote">midsize databases</span>”</span>, etc. since this
+ information is too inexact to be of use.
+ </p></li><li class="listitem"><p>
+ The output you got. Please do not say that it <span class="quote">“<span class="quote">didn't work</span>”</span> or
+ <span class="quote">“<span class="quote">crashed</span>”</span>. If there is an error message,
+ show it, even if you do not understand it. If the program terminates with
+ an operating system error, say which. If nothing at all happens, say so.
+ Even if the result of your test case is a program crash or otherwise obvious
+ it might not happen on our platform. The easiest thing is to copy the output
+ from the terminal, if possible.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If you are reporting an error message, please obtain the most verbose
+ form of the message. In <span class="application">psql</span>, say <code class="literal">\set
+ VERBOSITY verbose</code> beforehand. If you are extracting the message
+ from the server log, set the run-time parameter
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-ERROR-VERBOSITY">log_error_verbosity</a> to <code class="literal">verbose</code> so that all
+ details are logged.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ In case of fatal errors, the error message reported by the client might
+ not contain all the information available. Please also look at the
+ log output of the database server. If you do not keep your server's log
+ output, this would be a good time to start doing so.
+ </p></div></li><li class="listitem"><p>
+ The output you expected is very important to state. If you just write
+ <span class="quote">“<span class="quote">This command gives me that output.</span>”</span> or <span class="quote">“<span class="quote">This is not
+ what I expected.</span>”</span>, we might run it ourselves, scan the output, and
+ think it looks OK and is exactly what we expected. We should not have to
+ spend the time to decode the exact semantics behind your commands.
+ Especially refrain from merely saying that <span class="quote">“<span class="quote">This is not what SQL says/Oracle
+ does.</span>”</span> Digging out the correct behavior from <acronym class="acronym">SQL</acronym>
+ is not a fun undertaking, nor do we all know how all the other relational
+ databases out there behave. (If your problem is a program crash, you can
+ obviously omit this item.)
+ </p></li><li class="listitem"><p>
+ Any command line options and other start-up options, including
+ any relevant environment variables or configuration files that
+ you changed from the default. Again, please provide exact
+ information. If you are using a prepackaged distribution that
+ starts the database server at boot time, you should try to find
+ out how that is done.
+ </p></li><li class="listitem"><p>
+ Anything you did at all differently from the installation
+ instructions.
+ </p></li><li class="listitem"><p>
+ The <span class="productname">PostgreSQL</span> version. You can run the command
+ <code class="literal">SELECT version();</code> to
+ find out the version of the server you are connected to. Most executable
+ programs also support a <code class="option">--version</code> option; at least
+ <code class="literal">postgres --version</code> and <code class="literal">psql --version</code>
+ should work.
+ If the function or the options do not exist then your version is
+ more than old enough to warrant an upgrade.
+ If you run a prepackaged version, such as RPMs, say so, including any
+ subversion the package might have. If you are talking about a Git
+ snapshot, mention that, including the commit hash.
+ </p><p>
+ If your version is older than 15.4 we will almost certainly
+ tell you to upgrade. There are many bug fixes and improvements
+ in each new release, so it is quite possible that a bug you have
+ encountered in an older release of <span class="productname">PostgreSQL</span>
+ has already been fixed. We can only provide limited support for
+ sites using older releases of <span class="productname">PostgreSQL</span>; if you
+ require more than we can provide, consider acquiring a
+ commercial support contract.
+ </p><p>
+ </p></li><li class="listitem"><p>
+ Platform information. This includes the kernel name and version,
+ C library, processor, memory information, and so on. In most
+ cases it is sufficient to report the vendor and version, but do
+ not assume everyone knows what exactly <span class="quote">“<span class="quote">Debian</span>”</span>
+ contains or that everyone runs on x86_64. If you have
+ installation problems then information about the toolchain on
+ your machine (compiler, <span class="application">make</span>, and so
+ on) is also necessary.
+ </p></li></ul></div><p>
+
+ Do not be afraid if your bug report becomes rather lengthy. That is a fact of life.
+ It is better to report everything the first time than us having to squeeze the
+ facts out of you. On the other hand, if your input files are huge, it is
+ fair to ask first whether somebody is interested in looking into it. Here is
+ an <a class="ulink" href="https://www.chiark.greenend.org.uk/~sgtatham/bugs.html" target="_top">article</a>
+ that outlines some more tips on reporting bugs.
+ </p><p>
+ Do not spend all your time to figure out which changes in the input make
+ the problem go away. This will probably not help solving it. If it turns
+ out that the bug cannot be fixed right away, you will still have time to
+ find and share your work-around. Also, once again, do not waste your time
+ guessing why the bug exists. We will find that out soon enough.
+ </p><p>
+ When writing a bug report, please avoid confusing terminology.
+ The software package in total is called <span class="quote">“<span class="quote">PostgreSQL</span>”</span>,
+ sometimes <span class="quote">“<span class="quote">Postgres</span>”</span> for short. If you
+ are specifically talking about the backend process, mention that, do not
+ just say <span class="quote">“<span class="quote">PostgreSQL crashes</span>”</span>. A crash of a single
+ backend process is quite different from crash of the parent
+ <span class="quote">“<span class="quote">postgres</span>”</span> process; please don't say <span class="quote">“<span class="quote">the server
+ crashed</span>”</span> when you mean a single backend process went down, nor vice versa.
+ Also, client programs such as the interactive frontend <span class="quote">“<span class="quote"><span class="application">psql</span></span>”</span>
+ are completely separate from the backend. Please try to be specific
+ about whether the problem is on the client or server side.
+ </p></div><div class="sect2" id="id-1.3.8.7"><div class="titlepage"><div><div><h3 class="title">5.3. Where to Report Bugs</h3></div></div></div><p>
+ In general, send bug reports to the bug report mailing list at
+ <code class="email">&lt;<a class="email" href="mailto:pgsql-bugs@lists.postgresql.org">pgsql-bugs@lists.postgresql.org</a>&gt;</code>.
+ You are requested to use a descriptive subject for your email
+ message, perhaps parts of the error message.
+ </p><p>
+ Another method is to fill in the bug report web-form available
+ at the project's
+ <a class="ulink" href="https://www.postgresql.org/" target="_top">web site</a>.
+ Entering a bug report this way causes it to be mailed to the
+ <code class="email">&lt;<a class="email" href="mailto:pgsql-bugs@lists.postgresql.org">pgsql-bugs@lists.postgresql.org</a>&gt;</code> mailing list.
+ </p><p>
+ If your bug report has security implications and you'd prefer that it
+ not become immediately visible in public archives, don't send it to
+ <code class="literal">pgsql-bugs</code>. Security issues can be
+ reported privately to <code class="email">&lt;<a class="email" href="mailto:security@postgresql.org">security@postgresql.org</a>&gt;</code>.
+ </p><p>
+ Do not send bug reports to any of the user mailing lists, such as
+ <code class="email">&lt;<a class="email" href="mailto:pgsql-sql@lists.postgresql.org">pgsql-sql@lists.postgresql.org</a>&gt;</code> or
+ <code class="email">&lt;<a class="email" href="mailto:pgsql-general@lists.postgresql.org">pgsql-general@lists.postgresql.org</a>&gt;</code>.
+ These mailing lists are for answering
+ user questions, and their subscribers normally do not wish to receive
+ bug reports. More importantly, they are unlikely to fix them.
+ </p><p>
+ Also, please do <span class="emphasis"><em>not</em></span> send reports to
+ the developers' mailing list <code class="email">&lt;<a class="email" href="mailto:pgsql-hackers@lists.postgresql.org">pgsql-hackers@lists.postgresql.org</a>&gt;</code>.
+ This list is for discussing the
+ development of <span class="productname">PostgreSQL</span>, and it would be nice
+ if we could keep the bug reports separate. We might choose to take up a
+ discussion about your bug report on <code class="literal">pgsql-hackers</code>,
+ if the problem needs more review.
+ </p><p>
+ If you have a problem with the documentation, the best place to report it
+ is the documentation mailing list <code class="email">&lt;<a class="email" href="mailto:pgsql-docs@lists.postgresql.org">pgsql-docs@lists.postgresql.org</a>&gt;</code>.
+ Please be specific about what part of the documentation you are unhappy
+ with.
+ </p><p>
+ If your bug is a portability problem on a non-supported platform,
+ send mail to <code class="email">&lt;<a class="email" href="mailto:pgsql-hackers@lists.postgresql.org">pgsql-hackers@lists.postgresql.org</a>&gt;</code>,
+ so we (and you) can work on
+ porting <span class="productname">PostgreSQL</span> to your platform.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Due to the unfortunate amount of spam going around, all of the above
+ lists will be moderated unless you are subscribed. That means there
+ will be some delay before the email is delivered. If you wish to subscribe
+ to the lists, please visit
+ <a class="ulink" href="https://lists.postgresql.org/" target="_top">https://lists.postgresql.org/</a> for instructions.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="resources.html" title="4. Further Information">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial.html" title="Part I. Tutorial">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4. Further Information </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part I. Tutorial</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-aggregate.html b/doc/src/sgml/html/catalog-pg-aggregate.html
new file mode 100644
index 0000000..13c4fc1
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-aggregate.html
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.2. pg_aggregate</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalogs-overview.html" title="53.1. Overview" /><link rel="next" href="catalog-pg-am.html" title="53.3. pg_am" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.2. <code class="structname">pg_aggregate</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalogs-overview.html" title="53.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-am.html" title="53.3. pg_am">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-AGGREGATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.2. <code class="structname">pg_aggregate</code></h2></div></div></div><a id="id-1.10.4.4.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_aggregate</code> stores information about
+ aggregate functions. An aggregate function is a function that
+ operates on a set of values (typically one column from each row
+ that matches a query condition) and returns a single value computed
+ from all these values. Typical aggregate functions are
+ <code class="function">sum</code>, <code class="function">count</code>, and
+ <code class="function">max</code>. Each entry in
+ <code class="structname">pg_aggregate</code> is an extension of an entry
+ in <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.
+ The <code class="structname">pg_proc</code> entry carries the aggregate's name,
+ input and output data types, and other information that is similar to
+ ordinary functions.
+ </p><div class="table" id="id-1.10.4.4.4"><p class="title"><strong>Table 53.2. <code class="structname">pg_aggregate</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_aggregate Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggfnoid</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ <code class="structname">pg_proc</code> OID of the aggregate function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggkind</code> <code class="type">char</code>
+ </p>
+ <p>
+ Aggregate kind:
+ <code class="literal">n</code> for <span class="quote">“<span class="quote">normal</span>”</span> aggregates,
+ <code class="literal">o</code> for <span class="quote">“<span class="quote">ordered-set</span>”</span> aggregates, or
+ <code class="literal">h</code> for <span class="quote">“<span class="quote">hypothetical-set</span>”</span> aggregates
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggnumdirectargs</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Number of direct (non-aggregated) arguments of an ordered-set or
+ hypothetical-set aggregate, counting a variadic array as one argument.
+ If equal to <code class="structfield">pronargs</code>, the aggregate must be variadic
+ and the variadic array describes the aggregated arguments as well as
+ the final direct arguments.
+ Always zero for normal aggregates.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggtransfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Transition function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggfinalfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Final function (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggcombinefn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Combine function (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggserialfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Serialization function (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggdeserialfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Deserialization function (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggmtransfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Forward transition function for moving-aggregate mode (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggminvtransfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Inverse transition function for moving-aggregate mode (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggmfinalfn</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Final function for moving-aggregate mode (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggfinalextra</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True to pass extra dummy arguments to <code class="structfield">aggfinalfn</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggmfinalextra</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True to pass extra dummy arguments to <code class="structfield">aggmfinalfn</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggfinalmodify</code> <code class="type">char</code>
+ </p>
+ <p>
+ Whether <code class="structfield">aggfinalfn</code> modifies the
+ transition state value:
+ <code class="literal">r</code> if it is read-only,
+ <code class="literal">s</code> if the <code class="structfield">aggtransfn</code>
+ cannot be applied after the <code class="structfield">aggfinalfn</code>, or
+ <code class="literal">w</code> if it writes on the value
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggmfinalmodify</code> <code class="type">char</code>
+ </p>
+ <p>
+ Like <code class="structfield">aggfinalmodify</code>, but for
+ the <code class="structfield">aggmfinalfn</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggsortop</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Associated sort operator (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggtranstype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type of the aggregate function's internal transition (state) data
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggtransspace</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Approximate average size (in bytes) of the transition state
+ data, or zero to use a default estimate
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggmtranstype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type of the aggregate function's internal transition (state)
+ data for moving-aggregate mode (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggmtransspace</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Approximate average size (in bytes) of the transition state data
+ for moving-aggregate mode, or zero to use a default estimate
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">agginitval</code> <code class="type">text</code>
+ </p>
+ <p>
+ The initial value of the transition state. This is a text
+ field containing the initial value in its external string
+ representation. If this field is null, the transition state
+ value starts out null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">aggminitval</code> <code class="type">text</code>
+ </p>
+ <p>
+ The initial value of the transition state for moving-aggregate mode.
+ This is a text field containing the initial value in its external
+ string representation. If this field is null, the transition state
+ value starts out null.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ New aggregate functions are registered with the <a class="link" href="sql-createaggregate.html" title="CREATE AGGREGATE"><code class="command">CREATE AGGREGATE</code></a>
+ command. See <a class="xref" href="xaggr.html" title="38.12. User-Defined Aggregates">Section 38.12</a> for more information about
+ writing aggregate functions and the meaning of the transition
+ functions, etc.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalogs-overview.html" title="53.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-am.html" title="53.3. pg_am">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.3. <code class="structname">pg_am</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-am.html b/doc/src/sgml/html/catalog-pg-am.html
new file mode 100644
index 0000000..a7f5b47
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-am.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.3. pg_am</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate" /><link rel="next" href="catalog-pg-amop.html" title="53.4. pg_amop" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.3. <code class="structname">pg_am</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-amop.html" title="53.4. pg_amop">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-AM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.3. <code class="structname">pg_am</code></h2></div></div></div><a id="id-1.10.4.5.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_am</code> stores information about
+ relation access methods. There is one row for each access method supported
+ by the system.
+ Currently, only tables and indexes have access methods. The requirements for table
+ and index access methods are discussed in detail in <a class="xref" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Chapter 63</a> and
+ <a class="xref" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Chapter 64</a> respectively.
+ </p><div class="table" id="id-1.10.4.5.4"><p class="title"><strong>Table 53.3. <code class="structname">pg_am</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_am Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the access method
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amhandler</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of a handler function that is responsible for supplying information
+ about the access method
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amtype</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="literal">t</code> = table (including materialized views),
+ <code class="literal">i</code> = index.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> 9.6, <code class="structname">pg_am</code>
+ contained many additional columns representing properties of index access
+ methods. That data is now only directly visible at the C code level.
+ However, <code class="function">pg_index_column_has_property()</code> and related
+ functions have been added to allow SQL queries to inspect index access
+ method properties; see <a class="xref" href="functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE" title="Table 9.71. System Catalog Information Functions">Table 9.71</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-amop.html" title="53.4. pg_amop">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.2. <code class="structname">pg_aggregate</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.4. <code class="structname">pg_amop</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-amop.html b/doc/src/sgml/html/catalog-pg-amop.html
new file mode 100644
index 0000000..2ddfef2
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-amop.html
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.4. pg_amop</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-am.html" title="53.3. pg_am" /><link rel="next" href="catalog-pg-amproc.html" title="53.5. pg_amproc" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.4. <code class="structname">pg_amop</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-am.html" title="53.3. pg_am">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-amproc.html" title="53.5. pg_amproc">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-AMOP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.4. <code class="structname">pg_amop</code></h2></div></div></div><a id="id-1.10.4.6.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_amop</code> stores information about
+ operators associated with access method operator families. There is one
+ row for each operator that is a member of an operator family. A family
+ member can be either a <em class="firstterm">search</em> operator or an
+ <em class="firstterm">ordering</em> operator. An operator
+ can appear in more than one family, but cannot appear in more than one
+ search position nor more than one ordering position within a family.
+ (It is allowed, though unlikely, for an operator to be used for both
+ search and ordering purposes.)
+ </p><div class="table" id="id-1.10.4.6.4"><p class="title"><strong>Table 53.4. <code class="structname">pg_amop</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_amop Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amopfamily</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily"><code class="structname">pg_opfamily</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The operator family this entry is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amoplefttype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Left-hand input data type of operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amoprighttype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Right-hand input data type of operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amopstrategy</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Operator strategy number
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amoppurpose</code> <code class="type">char</code>
+ </p>
+ <p>
+ Operator purpose, either <code class="literal">s</code> for search or
+ <code class="literal">o</code> for ordering
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amopopr</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amopmethod</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Index access method operator family is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amopsortfamily</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily"><code class="structname">pg_opfamily</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The B-tree operator family this entry sorts according to, if an
+ ordering operator; zero if a search operator
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ A <span class="quote">“<span class="quote">search</span>”</span> operator entry indicates that an index of this operator
+ family can be searched to find all rows satisfying
+ <code class="literal">WHERE</code>
+ <em class="replaceable"><code>indexed_column</code></em>
+ <em class="replaceable"><code>operator</code></em>
+ <em class="replaceable"><code>constant</code></em>.
+ Obviously, such an operator must return <code class="type">boolean</code>, and its left-hand input
+ type must match the index's column data type.
+ </p><p>
+ An <span class="quote">“<span class="quote">ordering</span>”</span> operator entry indicates that an index of this
+ operator family can be scanned to return rows in the order represented by
+ <code class="literal">ORDER BY</code>
+ <em class="replaceable"><code>indexed_column</code></em>
+ <em class="replaceable"><code>operator</code></em>
+ <em class="replaceable"><code>constant</code></em>.
+ Such an operator could return any sortable data type, though again
+ its left-hand input type must match the index's column data type.
+ The exact semantics of the <code class="literal">ORDER BY</code> are specified by the
+ <code class="structfield">amopsortfamily</code> column, which must reference
+ a B-tree operator family for the operator's result type.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ At present, it's assumed that the sort order for an ordering operator
+ is the default for the referenced operator family, i.e., <code class="literal">ASC NULLS
+ LAST</code>. This might someday be relaxed by adding additional columns
+ to specify sort options explicitly.
+ </p></div><p>
+ An entry's <code class="structfield">amopmethod</code> must match the
+ <code class="structfield">opfmethod</code> of its containing operator family (including
+ <code class="structfield">amopmethod</code> here is an intentional denormalization of the
+ catalog structure for performance reasons). Also,
+ <code class="structfield">amoplefttype</code> and <code class="structfield">amoprighttype</code> must match
+ the <code class="structfield">oprleft</code> and <code class="structfield">oprright</code> fields of the
+ referenced <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a> entry.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-am.html" title="53.3. pg_am">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-amproc.html" title="53.5. pg_amproc">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.3. <code class="structname">pg_am</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.5. <code class="structname">pg_amproc</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-amproc.html b/doc/src/sgml/html/catalog-pg-amproc.html
new file mode 100644
index 0000000..1411777
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-amproc.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.5. pg_amproc</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-amop.html" title="53.4. pg_amop" /><link rel="next" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.5. <code class="structname">pg_amproc</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-amop.html" title="53.4. pg_amop">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-AMPROC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.5. <code class="structname">pg_amproc</code></h2></div></div></div><a id="id-1.10.4.7.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_amproc</code> stores information about
+ support functions associated with access method operator families. There
+ is one row for each support function belonging to an operator family.
+ </p><div class="table" id="id-1.10.4.7.4"><p class="title"><strong>Table 53.5. <code class="structname">pg_amproc</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_amproc Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amprocfamily</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily"><code class="structname">pg_opfamily</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The operator family this entry is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amproclefttype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Left-hand input data type of associated operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amprocrighttype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Right-hand input data type of associated operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amprocnum</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Support function number
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">amproc</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the function
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The usual interpretation of the
+ <code class="structfield">amproclefttype</code> and <code class="structfield">amprocrighttype</code> fields
+ is that they identify the left and right input types of the operator(s)
+ that a particular support function supports. For some access methods
+ these match the input data type(s) of the support function itself, for
+ others not. There is a notion of <span class="quote">“<span class="quote">default</span>”</span> support functions for
+ an index, which are those with <code class="structfield">amproclefttype</code> and
+ <code class="structfield">amprocrighttype</code> both equal to the index operator class's
+ <code class="structfield">opcintype</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-amop.html" title="53.4. pg_amop">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.4. <code class="structname">pg_amop</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.6. <code class="structname">pg_attrdef</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-attrdef.html b/doc/src/sgml/html/catalog-pg-attrdef.html
new file mode 100644
index 0000000..8f30390
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-attrdef.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.6. pg_attrdef</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-amproc.html" title="53.5. pg_amproc" /><link rel="next" href="catalog-pg-attribute.html" title="53.7. pg_attribute" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.6. <code class="structname">pg_attrdef</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-amproc.html" title="53.5. pg_amproc">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-attribute.html" title="53.7. pg_attribute">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-ATTRDEF"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.6. <code class="structname">pg_attrdef</code></h2></div></div></div><a id="id-1.10.4.8.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_attrdef</code> stores column default
+ values. The main information about columns is stored in
+ <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.
+ Only columns for which a default value has been explicitly set will have
+ an entry here.
+ </p><div class="table" id="id-1.10.4.8.4"><p class="title"><strong>Table 53.6. <code class="structname">pg_attrdef</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_attrdef Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">adrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table this column belongs to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">adnum</code> <code class="type">int2</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ The number of the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">adbin</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ The column default value, in <code class="function">nodeToString()</code>
+ representation. Use <code class="literal">pg_get_expr(adbin, adrelid)</code> to
+ convert it to an SQL expression.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-amproc.html" title="53.5. pg_amproc">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-attribute.html" title="53.7. pg_attribute">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.5. <code class="structname">pg_amproc</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.7. <code class="structname">pg_attribute</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-attribute.html b/doc/src/sgml/html/catalog-pg-attribute.html
new file mode 100644
index 0000000..e4980b7
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-attribute.html
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.7. pg_attribute</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef" /><link rel="next" href="catalog-pg-authid.html" title="53.8. pg_authid" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.7. <code class="structname">pg_attribute</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-authid.html" title="53.8. pg_authid">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-ATTRIBUTE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.7. <code class="structname">pg_attribute</code></h2></div></div></div><a id="id-1.10.4.9.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_attribute</code> stores information about
+ table columns. There will be exactly one
+ <code class="structname">pg_attribute</code> row for every column in every
+ table in the database. (There will also be attribute entries for
+ indexes, and indeed all objects that have
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>
+ entries.)
+ </p><p>
+ The term attribute is equivalent to column and is used for
+ historical reasons.
+ </p><div class="table" id="id-1.10.4.9.5"><p class="title"><strong>Table 53.7. <code class="structname">pg_attribute</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_attribute Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table this column belongs to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attname</code> <code class="type">name</code>
+ </p>
+ <p>
+ The column name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">atttypid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The data type of this column (zero for a dropped column)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attstattarget</code> <code class="type">int4</code>
+ </p>
+ <p>
+ <code class="structfield">attstattarget</code> controls the level of detail
+ of statistics accumulated for this column by
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>.
+ A zero value indicates that no statistics should be collected.
+ A negative value says to use the system default statistics target.
+ The exact meaning of positive values is data type-dependent.
+ For scalar data types, <code class="structfield">attstattarget</code>
+ is both the target number of <span class="quote">“<span class="quote">most common values</span>”</span>
+ to collect, and the target number of histogram bins to create.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attlen</code> <code class="type">int2</code>
+ </p>
+ <p>
+ A copy of <code class="literal">pg_type.typlen</code> of this column's
+ type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attnum</code> <code class="type">int2</code>
+ </p>
+ <p>
+ The number of the column. Ordinary columns are numbered from 1
+ up. System columns, such as <code class="structfield">ctid</code>,
+ have (arbitrary) negative numbers.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attndims</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Number of dimensions, if the column is an array type; otherwise 0.
+ (Presently, the number of dimensions of an array is not enforced,
+ so any nonzero value effectively means <span class="quote">“<span class="quote">it's an array</span>”</span>.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attcacheoff</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Always -1 in storage, but when loaded into a row descriptor
+ in memory this might be updated to cache the offset of the attribute
+ within the row
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">atttypmod</code> <code class="type">int4</code>
+ </p>
+ <p>
+ <code class="structfield">atttypmod</code> records type-specific data
+ supplied at table creation time (for example, the maximum
+ length of a <code class="type">varchar</code> column). It is passed to
+ type-specific input functions and length coercion functions.
+ The value will generally be -1 for types that do not need <code class="structfield">atttypmod</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attbyval</code> <code class="type">bool</code>
+ </p>
+ <p>
+ A copy of <code class="literal">pg_type.typbyval</code> of this column's type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attalign</code> <code class="type">char</code>
+ </p>
+ <p>
+ A copy of <code class="literal">pg_type.typalign</code> of this column's type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attstorage</code> <code class="type">char</code>
+ </p>
+ <p>
+ Normally a copy of <code class="literal">pg_type.typstorage</code> of this
+ column's type. For TOAST-able data types, this can be altered
+ after column creation to control storage policy.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attcompression</code> <code class="type">char</code>
+ </p>
+ <p>
+ The current compression method of the column. Typically this is
+ <code class="literal">'\0'</code> to specify use of the current default setting
+ (see <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TOAST-COMPRESSION">default_toast_compression</a>). Otherwise,
+ <code class="literal">'p'</code> selects pglz compression, while
+ <code class="literal">'l'</code> selects <span class="productname">LZ4</span>
+ compression. However, this field is ignored
+ whenever <code class="structfield">attstorage</code> does not allow
+ compression.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attnotnull</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This represents a not-null constraint.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">atthasdef</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This column has a default expression or generation expression, in which
+ case there will be a corresponding entry in the
+ <a class="link" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef"><code class="structname">pg_attrdef</code></a> catalog that actually defines the
+ expression. (Check <code class="structfield">attgenerated</code> to
+ determine whether this is a default or a generation expression.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">atthasmissing</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This column has a value which is used where the column is entirely
+ missing from the row, as happens when a column is added with a
+ non-volatile <code class="literal">DEFAULT</code> value after the row is created.
+ The actual value used is stored in the
+ <code class="structfield">attmissingval</code> column.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attidentity</code> <code class="type">char</code>
+ </p>
+ <p>
+ If a zero byte (<code class="literal">''</code>), then not an identity column.
+ Otherwise, <code class="literal">a</code> = generated
+ always, <code class="literal">d</code> = generated by default.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attgenerated</code> <code class="type">char</code>
+ </p>
+ <p>
+ If a zero byte (<code class="literal">''</code>), then not a generated column.
+ Otherwise, <code class="literal">s</code> = stored. (Other values might be added
+ in the future.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attisdropped</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This column has been dropped and is no longer valid. A dropped
+ column is still physically present in the table, but is
+ ignored by the parser and so cannot be accessed via SQL.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attislocal</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This column is defined locally in the relation. Note that a column can
+ be locally defined and inherited simultaneously.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attinhcount</code> <code class="type">int4</code>
+ </p>
+ <p>
+ The number of direct ancestors this column has. A column with a
+ nonzero number of ancestors cannot be dropped nor renamed.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attcollation</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The defined collation of the column, or zero if the column is
+ not of a collatable data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Column-level access privileges, if any have been granted specifically
+ on this column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Attribute-level options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attfdwoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Attribute-level foreign data wrapper options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attmissingval</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ This column has a one element array containing the value used when the
+ column is entirely missing from the row, as happens when the column is
+ added with a non-volatile <code class="literal">DEFAULT</code> value after the
+ row is created. The value is only used when
+ <code class="structfield">atthasmissing</code> is true. If there is no value
+ the column is null.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In a dropped column's <code class="structname">pg_attribute</code> entry,
+ <code class="structfield">atttypid</code> is reset to zero, but
+ <code class="structfield">attlen</code> and the other fields copied from
+ <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a> are still valid. This arrangement is needed
+ to cope with the situation where the dropped column's data type was
+ later dropped, and so there is no <code class="structname">pg_type</code> row anymore.
+ <code class="structfield">attlen</code> and the other fields can be used
+ to interpret the contents of a row of the table.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-authid.html" title="53.8. pg_authid">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.6. <code class="structname">pg_attrdef</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.8. <code class="structname">pg_authid</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-auth-members.html b/doc/src/sgml/html/catalog-pg-auth-members.html
new file mode 100644
index 0000000..4a3fc84
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-auth-members.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.9. pg_auth_members</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-authid.html" title="53.8. pg_authid" /><link rel="next" href="catalog-pg-cast.html" title="53.10. pg_cast" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.9. <code class="structname">pg_auth_members</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-authid.html" title="53.8. pg_authid">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-cast.html" title="53.10. pg_cast">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-AUTH-MEMBERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.9. <code class="structname">pg_auth_members</code></h2></div></div></div><a id="id-1.10.4.11.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_auth_members</code> shows the membership
+ relations between roles. Any non-circular set of relationships is allowed.
+ </p><p>
+ Because user identities are cluster-wide,
+ <code class="structname">pg_auth_members</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_auth_members</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.11.5"><p class="title"><strong>Table 53.9. <code class="structname">pg_auth_members</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_auth_members Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">roleid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ ID of a role that has a member
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">member</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ ID of a role that is a member of <code class="structfield">roleid</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ ID of the role that granted this membership
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">admin_option</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if <code class="structfield">member</code> can grant membership in
+ <code class="structfield">roleid</code> to others
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-authid.html" title="53.8. pg_authid">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-cast.html" title="53.10. pg_cast">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.8. <code class="structname">pg_authid</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.10. <code class="structname">pg_cast</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-authid.html b/doc/src/sgml/html/catalog-pg-authid.html
new file mode 100644
index 0000000..9a932d0
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-authid.html
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.8. pg_authid</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-attribute.html" title="53.7. pg_attribute" /><link rel="next" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.8. <code class="structname">pg_authid</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-attribute.html" title="53.7. pg_attribute">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-AUTHID"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.8. <code class="structname">pg_authid</code></h2></div></div></div><a id="id-1.10.4.10.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_authid</code> contains information about
+ database authorization identifiers (roles). A role subsumes the concepts
+ of <span class="quote">“<span class="quote">users</span>”</span> and <span class="quote">“<span class="quote">groups</span>”</span>. A user is essentially just a
+ role with the <code class="structfield">rolcanlogin</code> flag set. Any role (with or
+ without <code class="structfield">rolcanlogin</code>) can have other roles as members; see
+ <a class="link" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members"><code class="structname">pg_auth_members</code></a>.
+ </p><p>
+ Since this catalog contains passwords, it must not be publicly readable.
+ <a class="link" href="view-pg-roles.html" title="54.20. pg_roles"><code class="structname">pg_roles</code></a>
+ is a publicly readable view on
+ <code class="structname">pg_authid</code> that blanks out the password field.
+ </p><p>
+ <a class="xref" href="user-manag.html" title="Chapter 22. Database Roles">Chapter 22</a> contains detailed information about user and
+ privilege management.
+ </p><p>
+ Because user identities are cluster-wide,
+ <code class="structname">pg_authid</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_authid</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.10.7"><p class="title"><strong>Table 53.8. <code class="structname">pg_authid</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_authid Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Role name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolsuper</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role has superuser privileges
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolinherit</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role automatically inherits privileges of roles it is a
+ member of
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolcreaterole</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role can create more roles
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolcreatedb</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role can create databases
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolcanlogin</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role can log in. That is, this role can be given as the initial
+ session authorization identifier.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolreplication</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role is a replication role. A replication role can initiate replication
+ connections and create and drop replication slots.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolbypassrls</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role bypasses every row-level security policy, see
+ <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolconnlimit</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For roles that can log in, this sets maximum number of concurrent
+ connections this role can make. -1 means no limit.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolpassword</code> <code class="type">text</code>
+ </p>
+ <p>
+ Password (possibly encrypted); null if none. The format depends
+ on the form of encryption used.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolvaliduntil</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ Password expiry time (only used for password authentication);
+ null if no expiration
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For an MD5 encrypted password, <code class="structfield">rolpassword</code>
+ column will begin with the string <code class="literal">md5</code> followed by a
+ 32-character hexadecimal MD5 hash. The MD5 hash will be of the user's
+ password concatenated to their user name. For example, if user
+ <code class="literal">joe</code> has password <code class="literal">xyzzy</code>, <span class="productname">PostgreSQL</span>
+ will store the md5 hash of <code class="literal">xyzzyjoe</code>.
+ </p><p>
+ If the password is encrypted with SCRAM-SHA-256, it has the format:
+</p><pre class="synopsis">
+SCRAM-SHA-256$<em class="replaceable"><code>&lt;iteration count&gt;</code></em>:<em class="replaceable"><code>&lt;salt&gt;</code></em>$<em class="replaceable"><code>&lt;StoredKey&gt;</code></em>:<em class="replaceable"><code>&lt;ServerKey&gt;</code></em>
+</pre><p>
+ where <em class="replaceable"><code>salt</code></em>, <em class="replaceable"><code>StoredKey</code></em> and
+ <em class="replaceable"><code>ServerKey</code></em> are in Base64 encoded format. This format is
+ the same as that specified by <a class="ulink" href="https://tools.ietf.org/html/rfc5803" target="_top">RFC 5803</a>.
+ </p><p>
+ A password that does not follow either of those formats is assumed to be
+ unencrypted.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-attribute.html" title="53.7. pg_attribute">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.7. <code class="structname">pg_attribute</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.9. <code class="structname">pg_auth_members</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-cast.html b/doc/src/sgml/html/catalog-pg-cast.html
new file mode 100644
index 0000000..49382f7
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-cast.html
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.10. pg_cast</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members" /><link rel="next" href="catalog-pg-class.html" title="53.11. pg_class" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.10. <code class="structname">pg_cast</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-class.html" title="53.11. pg_class">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-CAST"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.10. <code class="structname">pg_cast</code></h2></div></div></div><a id="id-1.10.4.12.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_cast</code> stores data type conversion
+ paths, both built-in and user-defined.
+ </p><p>
+ It should be noted that <code class="structname">pg_cast</code> does not represent
+ every type conversion that the system knows how to perform; only those that
+ cannot be deduced from some generic rule. For example, casting between a
+ domain and its base type is not explicitly represented in
+ <code class="structname">pg_cast</code>. Another important exception is that
+ <span class="quote">“<span class="quote">automatic I/O conversion casts</span>”</span>, those performed using a data
+ type's own I/O functions to convert to or from <code class="type">text</code> or other
+ string types, are not explicitly represented in
+ <code class="structname">pg_cast</code>.
+ </p><div class="table" id="id-1.10.4.12.5"><p class="title"><strong>Table 53.10. <code class="structname">pg_cast</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_cast Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">castsource</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the source data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">casttarget</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the target data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">castfunc</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the function to use to perform this cast. Zero is
+ stored if the cast method doesn't require a function.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">castcontext</code> <code class="type">char</code>
+ </p>
+ <p>
+ Indicates what contexts the cast can be invoked in.
+ <code class="literal">e</code> means only as an explicit cast (using
+ <code class="literal">CAST</code> or <code class="literal">::</code> syntax).
+ <code class="literal">a</code> means implicitly in assignment
+ to a target column, as well as explicitly.
+ <code class="literal">i</code> means implicitly in expressions, as well as the
+ other cases.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">castmethod</code> <code class="type">char</code>
+ </p>
+ <p>
+ Indicates how the cast is performed.
+ <code class="literal">f</code> means that the function specified in the <code class="structfield">castfunc</code> field is used.
+ <code class="literal">i</code> means that the input/output functions are used.
+ <code class="literal">b</code> means that the types are binary-coercible, thus no conversion is required.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The cast functions listed in <code class="structname">pg_cast</code> must
+ always take the cast source type as their first argument type, and
+ return the cast destination type as their result type. A cast
+ function can have up to three arguments. The second argument,
+ if present, must be type <code class="type">integer</code>; it receives the type
+ modifier associated with the destination type, or -1
+ if there is none. The third argument,
+ if present, must be type <code class="type">boolean</code>; it receives <code class="literal">true</code>
+ if the cast is an explicit cast, <code class="literal">false</code> otherwise.
+ </p><p>
+ It is legitimate to create a <code class="structname">pg_cast</code> entry
+ in which the source and target types are the same, if the associated
+ function takes more than one argument. Such entries represent
+ <span class="quote">“<span class="quote">length coercion functions</span>”</span> that coerce values of the type
+ to be legal for a particular type modifier value.
+ </p><p>
+ When a <code class="structname">pg_cast</code> entry has different source and
+ target types and a function that takes more than one argument, it
+ represents converting from one type to another and applying a length
+ coercion in a single step. When no such entry is available, coercion
+ to a type that uses a type modifier involves two steps, one to
+ convert between data types and a second to apply the modifier.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-class.html" title="53.11. pg_class">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.9. <code class="structname">pg_auth_members</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.11. <code class="structname">pg_class</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-class.html b/doc/src/sgml/html/catalog-pg-class.html
new file mode 100644
index 0000000..6c11f69
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-class.html
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.11. pg_class</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-cast.html" title="53.10. pg_cast" /><link rel="next" href="catalog-pg-collation.html" title="53.12. pg_collation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.11. <code class="structname">pg_class</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-cast.html" title="53.10. pg_cast">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-collation.html" title="53.12. pg_collation">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-CLASS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.11. <code class="structname">pg_class</code></h2></div></div></div><a id="id-1.10.4.13.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_class</code> catalogs tables and most
+ everything else that has columns or is otherwise similar to a
+ table. This includes indexes (but see also <a class="link" href="catalog-pg-index.html" title="53.26. pg_index"><code class="structname">pg_index</code></a>),
+ sequences (but see also <a class="link" href="catalog-pg-sequence.html" title="53.47. pg_sequence"><code class="structname">pg_sequence</code></a>),
+ views, materialized views, composite types, and TOAST tables;
+ see <code class="structfield">relkind</code>.
+ Below, when we mean all of these kinds of objects we speak of
+ <span class="quote">“<span class="quote">relations</span>”</span>. Not all columns are meaningful for all relation
+ types.
+ </p><div class="table" id="id-1.10.4.13.4"><p class="title"><strong>Table 53.11. <code class="structname">pg_class</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_class Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the table, index, view, etc.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reltype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the data type that corresponds to this table's row type,
+ if any; zero for indexes, sequences, and toast tables, which have
+ no <code class="structname">pg_type</code> entry
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reloftype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For typed tables, the OID of the underlying composite type;
+ zero for all other relations
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relam</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If this is a table or an index, the access method used (heap,
+ B-tree, hash, etc.); otherwise zero (zero occurs for sequences,
+ as well as relations without storage, such as views)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relfilenode</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Name of the on-disk file of this relation; zero means this
+ is a <span class="quote">“<span class="quote">mapped</span>”</span> relation whose disk file name is determined
+ by low-level state
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reltablespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The tablespace in which this relation is stored. If zero,
+ the database's default tablespace is implied. (Not meaningful
+ if the relation has no on-disk file.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relpages</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Size of the on-disk representation of this table in pages (of size
+ <code class="symbol">BLCKSZ</code>). This is only an estimate used by the
+ planner. It is updated by <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>,
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>, and a few DDL commands such as
+ <a class="link" href="sql-createindex.html" title="CREATE INDEX"><code class="command">CREATE INDEX</code></a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reltuples</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Number of live rows in the table. This is only an estimate used by
+ the planner. It is updated by <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>,
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>, and a few DDL commands such as
+ <a class="link" href="sql-createindex.html" title="CREATE INDEX"><code class="command">CREATE INDEX</code></a>.
+ If the table has never yet been vacuumed or
+ analyzed, <code class="structfield">reltuples</code>
+ contains <code class="literal">-1</code> indicating that the row count is
+ unknown.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relallvisible</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Number of pages that are marked all-visible in the table's
+ visibility map. This is only an estimate used by the
+ planner. It is updated by <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>,
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>, and a few DDL commands such as
+ <a class="link" href="sql-createindex.html" title="CREATE INDEX"><code class="command">CREATE INDEX</code></a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reltoastrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the TOAST table associated with this table, zero if none. The
+ TOAST table stores large attributes <span class="quote">“<span class="quote">out of line</span>”</span> in a
+ secondary table.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relhasindex</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this is a table and it has (or recently had) any indexes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relisshared</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this table is shared across all databases in the cluster. Only
+ certain system catalogs (such as <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>)
+ are shared.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relpersistence</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="literal">p</code> = permanent table/sequence, <code class="literal">u</code> = unlogged table/sequence,
+ <code class="literal">t</code> = temporary table/sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relkind</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="literal">r</code> = ordinary table,
+ <code class="literal">i</code> = index,
+ <code class="literal">S</code> = sequence,
+ <code class="literal">t</code> = TOAST table,
+ <code class="literal">v</code> = view,
+ <code class="literal">m</code> = materialized view,
+ <code class="literal">c</code> = composite type,
+ <code class="literal">f</code> = foreign table,
+ <code class="literal">p</code> = partitioned table,
+ <code class="literal">I</code> = partitioned index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relnatts</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Number of user columns in the relation (system columns not
+ counted). There must be this many corresponding entries in
+ <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>. See also
+ <code class="structname">pg_attribute</code>.<code class="structfield">attnum</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relchecks</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Number of <code class="literal">CHECK</code> constraints on the table; see
+ <a class="link" href="catalog-pg-constraint.html" title="53.13. pg_constraint"><code class="structname">pg_constraint</code></a> catalog
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relhasrules</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if table has (or once had) rules; see
+ <a class="link" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite"><code class="structname">pg_rewrite</code></a> catalog
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relhastriggers</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if table has (or once had) triggers; see
+ <a class="link" href="catalog-pg-trigger.html" title="53.58. pg_trigger"><code class="structname">pg_trigger</code></a> catalog
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relhassubclass</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if table or index has (or once had) any inheritance children or partitions
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relrowsecurity</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if table has row-level security enabled; see
+ <a class="link" href="catalog-pg-policy.html" title="53.38. pg_policy"><code class="structname">pg_policy</code></a> catalog
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relforcerowsecurity</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if row-level security (when enabled) will also apply to table owner; see
+ <a class="link" href="catalog-pg-policy.html" title="53.38. pg_policy"><code class="structname">pg_policy</code></a> catalog
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relispopulated</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if relation is populated (this is true for all
+ relations other than some materialized views)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relreplident</code> <code class="type">char</code>
+ </p>
+ <p>
+ Columns used to form <span class="quote">“<span class="quote">replica identity</span>”</span> for rows:
+ <code class="literal">d</code> = default (primary key, if any),
+ <code class="literal">n</code> = nothing,
+ <code class="literal">f</code> = all columns,
+ <code class="literal">i</code> = index with
+ <code class="structfield">indisreplident</code> set (same as nothing if the
+ index used has been dropped)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relispartition</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if table or index is a partition
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relrewrite</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For new relations being written during a DDL operation that requires a
+ table rewrite, this contains the OID of the original relation;
+ otherwise zero. That state is only visible internally; this field should
+ never contain anything other than zero for a user-visible relation.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relfrozenxid</code> <code class="type">xid</code>
+ </p>
+ <p>
+ All transaction IDs before this one have been replaced with a permanent
+ (<span class="quote">“<span class="quote">frozen</span>”</span>) transaction ID in this table. This is used to track
+ whether the table needs to be vacuumed in order to prevent transaction
+ ID wraparound or to allow <code class="literal">pg_xact</code> to be shrunk. Zero
+ (<code class="symbol">InvalidTransactionId</code>) if the relation is not a table.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relminmxid</code> <code class="type">xid</code>
+ </p>
+ <p>
+ All multixact IDs before this one have been replaced by a
+ transaction ID in this table. This is used to track
+ whether the table needs to be vacuumed in order to prevent multixact ID
+ wraparound or to allow <code class="literal">pg_multixact</code> to be shrunk. Zero
+ (<code class="symbol">InvalidMultiXactId</code>) if the relation is not a table.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reloptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Access-method-specific options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relpartbound</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ If table is a partition (see <code class="structfield">relispartition</code>),
+ internal representation of the partition bound
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Several of the Boolean flags in <code class="structname">pg_class</code> are maintained
+ lazily: they are guaranteed to be true if that's the correct state, but
+ may not be reset to false immediately when the condition is no longer
+ true. For example, <code class="structfield">relhasindex</code> is set by
+ <a class="link" href="sql-createindex.html" title="CREATE INDEX"><code class="command">CREATE INDEX</code></a>, but it is never cleared by
+ <a class="link" href="sql-dropindex.html" title="DROP INDEX"><code class="command">DROP INDEX</code></a>. Instead, <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a> clears
+ <code class="structfield">relhasindex</code> if it finds the table has no indexes. This
+ arrangement avoids race conditions and improves concurrency.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-cast.html" title="53.10. pg_cast">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-collation.html" title="53.12. pg_collation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.10. <code class="structname">pg_cast</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.12. <code class="structname">pg_collation</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-collation.html b/doc/src/sgml/html/catalog-pg-collation.html
new file mode 100644
index 0000000..46f7e2d
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-collation.html
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.12. pg_collation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-class.html" title="53.11. pg_class" /><link rel="next" href="catalog-pg-constraint.html" title="53.13. pg_constraint" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.12. <code class="structname">pg_collation</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-class.html" title="53.11. pg_class">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-constraint.html" title="53.13. pg_constraint">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-COLLATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.12. <code class="structname">pg_collation</code></h2></div></div></div><a id="id-1.10.4.14.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_collation</code> describes the
+ available collations, which are essentially mappings from an SQL
+ name to operating system locale categories.
+ See <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a> for more information.
+ </p><div class="table" id="id-1.10.4.14.4"><p class="title"><strong>Table 53.12. <code class="structname">pg_collation</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_collation Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Collation name (unique per namespace and encoding)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collprovider</code> <code class="type">char</code>
+ </p>
+ <p>
+ Provider of the collation: <code class="literal">d</code> = database
+ default, <code class="literal">c</code> = libc, <code class="literal">i</code> = icu
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collisdeterministic</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Is the collation deterministic?
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collencoding</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Encoding in which the collation is applicable, or -1 if it
+ works for any encoding
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collcollate</code> <code class="type">text</code>
+ </p>
+ <p>
+ <code class="symbol">LC_COLLATE</code> for this collation object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collctype</code> <code class="type">text</code>
+ </p>
+ <p>
+ <code class="symbol">LC_CTYPE</code> for this collation object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">colliculocale</code> <code class="type">text</code>
+ </p>
+ <p>
+ ICU locale ID for this collation object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collversion</code> <code class="type">text</code>
+ </p>
+ <p>
+ Provider-specific version of the collation. This is recorded when the
+ collation is created and then checked when it is used, to detect
+ changes in the collation definition that could lead to data corruption.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Note that the unique key on this catalog is (<code class="structfield">collname</code>,
+ <code class="structfield">collencoding</code>, <code class="structfield">collnamespace</code>) not just
+ (<code class="structfield">collname</code>, <code class="structfield">collnamespace</code>).
+ <span class="productname">PostgreSQL</span> generally ignores all
+ collations that do not have <code class="structfield">collencoding</code> equal to
+ either the current database's encoding or -1, and creation of new entries
+ with the same name as an entry with <code class="structfield">collencoding</code> = -1
+ is forbidden. Therefore it is sufficient to use a qualified SQL name
+ (<em class="replaceable"><code>schema</code></em>.<em class="replaceable"><code>name</code></em>) to identify a collation,
+ even though this is not unique according to the catalog definition.
+ The reason for defining the catalog this way is that
+ <span class="application">initdb</span> fills it in at cluster initialization time with
+ entries for all locales available on the system, so it must be able to
+ hold entries for all encodings that might ever be used in the cluster.
+ </p><p>
+ In the <code class="literal">template0</code> database, it could be useful to create
+ collations whose encoding does not match the database encoding,
+ since they could match the encodings of databases later cloned from
+ <code class="literal">template0</code>. This would currently have to be done manually.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-class.html" title="53.11. pg_class">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-constraint.html" title="53.13. pg_constraint">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.11. <code class="structname">pg_class</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.13. <code class="structname">pg_constraint</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-constraint.html b/doc/src/sgml/html/catalog-pg-constraint.html
new file mode 100644
index 0000000..8d6737a
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-constraint.html
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.13. pg_constraint</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-collation.html" title="53.12. pg_collation" /><link rel="next" href="catalog-pg-conversion.html" title="53.14. pg_conversion" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.13. <code class="structname">pg_constraint</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-collation.html" title="53.12. pg_collation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-conversion.html" title="53.14. pg_conversion">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-CONSTRAINT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.13. <code class="structname">pg_constraint</code></h2></div></div></div><a id="id-1.10.4.15.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_constraint</code> stores check, primary
+ key, unique, foreign key, and exclusion constraints on tables.
+ (Column constraints are not treated specially. Every column constraint is
+ equivalent to some table constraint.)
+ Not-null constraints are represented in the
+ <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>
+ catalog, not here.
+ </p><p>
+ User-defined constraint triggers (created with <a class="link" href="sql-createtrigger.html" title="CREATE TRIGGER">
+ <code class="command">CREATE CONSTRAINT TRIGGER</code></a>) also give rise to an entry in this table.
+ </p><p>
+ Check constraints on domains are stored here, too.
+ </p><div class="table" id="id-1.10.4.15.6"><p class="title"><strong>Table 53.13. <code class="structname">pg_constraint</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_constraint Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Constraint name (not necessarily unique!)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">connamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">contype</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="literal">c</code> = check constraint,
+ <code class="literal">f</code> = foreign key constraint,
+ <code class="literal">p</code> = primary key constraint,
+ <code class="literal">u</code> = unique constraint,
+ <code class="literal">t</code> = constraint trigger,
+ <code class="literal">x</code> = exclusion constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">condeferrable</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Is the constraint deferrable?
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">condeferred</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Is the constraint deferred by default?
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">convalidated</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Has the constraint been validated?
+ Currently, can be false only for foreign keys and CHECK constraints
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table this constraint is on; zero if not a table constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">contypid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The domain this constraint is on; zero if not a domain constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conindid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The index supporting this constraint, if it's a unique, primary
+ key, foreign key, or exclusion constraint; else zero
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conparentid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-constraint.html" title="53.13. pg_constraint"><code class="structname">pg_constraint</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The corresponding constraint of the parent partitioned table,
+ if this is a constraint on a partition; else zero
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If a foreign key, the referenced table; else zero
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confupdtype</code> <code class="type">char</code>
+ </p>
+ <p>
+ Foreign key update action code:
+ <code class="literal">a</code> = no action,
+ <code class="literal">r</code> = restrict,
+ <code class="literal">c</code> = cascade,
+ <code class="literal">n</code> = set null,
+ <code class="literal">d</code> = set default
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confdeltype</code> <code class="type">char</code>
+ </p>
+ <p>
+ Foreign key deletion action code:
+ <code class="literal">a</code> = no action,
+ <code class="literal">r</code> = restrict,
+ <code class="literal">c</code> = cascade,
+ <code class="literal">n</code> = set null,
+ <code class="literal">d</code> = set default
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confmatchtype</code> <code class="type">char</code>
+ </p>
+ <p>
+ Foreign key match type:
+ <code class="literal">f</code> = full,
+ <code class="literal">p</code> = partial,
+ <code class="literal">s</code> = simple
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conislocal</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This constraint is defined locally for the relation. Note that a
+ constraint can be locally defined and inherited simultaneously.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">coninhcount</code> <code class="type">int4</code>
+ </p>
+ <p>
+ The number of direct inheritance ancestors this constraint has.
+ A constraint with
+ a nonzero number of ancestors cannot be dropped nor renamed.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">connoinherit</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This constraint is defined locally for the relation. It is a
+ non-inheritable constraint.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conkey</code> <code class="type">int2[]</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ If a table constraint (including foreign keys, but not constraint
+ triggers), list of the constrained columns
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confkey</code> <code class="type">int2[]</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ If a foreign key, list of the referenced columns
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conpfeqop</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If a foreign key, list of the equality operators for PK = FK comparisons
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conppeqop</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If a foreign key, list of the equality operators for PK = PK comparisons
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conffeqop</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If a foreign key, list of the equality operators for FK = FK comparisons
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confdelsetcols</code> <code class="type">int2[]</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ If a foreign key with a <code class="literal">SET NULL</code> or <code class="literal">SET
+ DEFAULT</code> delete action, the columns that will be updated.
+ If null, all of the referencing columns will be updated.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conexclop</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If an exclusion constraint, list of the per-column exclusion operators
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conbin</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ If a check constraint, an internal representation of the
+ expression. (It's recommended to use
+ <code class="function">pg_get_constraintdef()</code> to extract the definition of
+ a check constraint.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In the case of an exclusion constraint, <code class="structfield">conkey</code>
+ is only useful for constraint elements that are simple column references.
+ For other cases, a zero appears in <code class="structfield">conkey</code>
+ and the associated index must be consulted to discover the expression
+ that is constrained. (<code class="structfield">conkey</code> thus has the
+ same contents as <a class="link" href="catalog-pg-index.html" title="53.26. pg_index"><code class="structname">pg_index</code></a>.<code class="structfield">indkey</code> for the
+ index.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">pg_class.relchecks</code> needs to agree with the
+ number of check-constraint entries found in this table for each
+ relation.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-collation.html" title="53.12. pg_collation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-conversion.html" title="53.14. pg_conversion">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.12. <code class="structname">pg_collation</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.14. <code class="structname">pg_conversion</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-conversion.html b/doc/src/sgml/html/catalog-pg-conversion.html
new file mode 100644
index 0000000..31564a5
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-conversion.html
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.14. pg_conversion</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-constraint.html" title="53.13. pg_constraint" /><link rel="next" href="catalog-pg-database.html" title="53.15. pg_database" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.14. <code class="structname">pg_conversion</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-constraint.html" title="53.13. pg_constraint">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-database.html" title="53.15. pg_database">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-CONVERSION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.14. <code class="structname">pg_conversion</code></h2></div></div></div><a id="id-1.10.4.16.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_conversion</code> describes
+ encoding conversion functions. See <a class="xref" href="sql-createconversion.html" title="CREATE CONVERSION"><span class="refentrytitle">CREATE CONVERSION</span></a>
+ for more information.
+ </p><div class="table" id="id-1.10.4.16.4"><p class="title"><strong>Table 53.14. <code class="structname">pg_conversion</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_conversion Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Conversion name (unique within a namespace)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">connamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this conversion
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the conversion
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conforencoding</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Source encoding ID (<a class="link" href="functions-info.html#PG-ENCODING-TO-CHAR"><code class="function">pg_encoding_to_char()</code></a>
+ can translate this number to the encoding name)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">contoencoding</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Destination encoding ID (<a class="link" href="functions-info.html#PG-ENCODING-TO-CHAR"><code class="function">pg_encoding_to_char()</code></a>
+ can translate this number to the encoding name)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conproc</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Conversion function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">condefault</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this is the default conversion
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-constraint.html" title="53.13. pg_constraint">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-database.html" title="53.15. pg_database">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.13. <code class="structname">pg_constraint</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.15. <code class="structname">pg_database</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-database.html b/doc/src/sgml/html/catalog-pg-database.html
new file mode 100644
index 0000000..e9c175c
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-database.html
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.15. pg_database</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-conversion.html" title="53.14. pg_conversion" /><link rel="next" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.15. <code class="structname">pg_database</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-conversion.html" title="53.14. pg_conversion">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-DATABASE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.15. <code class="structname">pg_database</code></h2></div></div></div><a id="id-1.10.4.17.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_database</code> stores information about
+ the available databases. Databases are created with the <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE"><code class="command">CREATE DATABASE</code></a> command.
+ Consult <a class="xref" href="managing-databases.html" title="Chapter 23. Managing Databases">Chapter 23</a> for details about the meaning
+ of some of the parameters.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_database</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_database</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.17.5"><p class="title"><strong>Table 53.15. <code class="structname">pg_database</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_database Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Database name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datdba</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the database, usually the user who created it
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">encoding</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Character encoding for this database
+ (<a class="link" href="functions-info.html#PG-ENCODING-TO-CHAR"><code class="function">pg_encoding_to_char()</code></a> can translate
+ this number to the encoding name)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datlocprovider</code> <code class="type">char</code>
+ </p>
+ <p>
+ Locale provider for this database: <code class="literal">c</code> = libc,
+ <code class="literal">i</code> = icu
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datistemplate</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, then this database can be cloned by
+ any user with <code class="literal">CREATEDB</code> privileges;
+ if false, then only superusers or the owner of
+ the database can clone it.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datallowconn</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If false then no one can connect to this database. This is
+ used to protect the <code class="literal">template0</code> database from being altered.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datconnlimit</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Sets maximum number of concurrent connections that can be made
+ to this database. -1 means no limit, -2 indicates the database is
+ invalid.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datfrozenxid</code> <code class="type">xid</code>
+ </p>
+ <p>
+ All transaction IDs before this one have been replaced with a permanent
+ (<span class="quote">“<span class="quote">frozen</span>”</span>) transaction ID in this database. This is used to
+ track whether the database needs to be vacuumed in order to prevent
+ transaction ID wraparound or to allow <code class="literal">pg_xact</code> to be shrunk.
+ It is the minimum of the per-table
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relfrozenxid</code> values.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datminmxid</code> <code class="type">xid</code>
+ </p>
+ <p>
+ All multixact IDs before this one have been replaced with a
+ transaction ID in this database. This is used to
+ track whether the database needs to be vacuumed in order to prevent
+ multixact ID wraparound or to allow <code class="literal">pg_multixact</code> to be shrunk.
+ It is the minimum of the per-table
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relminmxid</code> values.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dattablespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The default tablespace for the database.
+ Within this database, all tables for which
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">reltablespace</code> is zero
+ will be stored in this tablespace; in particular, all the non-shared
+ system catalogs will be there.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datcollate</code> <code class="type">text</code>
+ </p>
+ <p>
+ LC_COLLATE for this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datctype</code> <code class="type">text</code>
+ </p>
+ <p>
+ LC_CTYPE for this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">daticulocale</code> <code class="type">text</code>
+ </p>
+ <p>
+ ICU locale ID for this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datcollversion</code> <code class="type">text</code>
+ </p>
+ <p>
+ Provider-specific version of the collation. This is recorded when the
+ database is created and then checked when it is used, to detect
+ changes in the collation definition that could lead to data corruption.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-conversion.html" title="53.14. pg_conversion">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.14. <code class="structname">pg_conversion</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.16. <code class="structname">pg_db_role_setting</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-db-role-setting.html b/doc/src/sgml/html/catalog-pg-db-role-setting.html
new file mode 100644
index 0000000..c6585b4
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-db-role-setting.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.16. pg_db_role_setting</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-database.html" title="53.15. pg_database" /><link rel="next" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.16. <code class="structname">pg_db_role_setting</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-database.html" title="53.15. pg_database">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-DB-ROLE-SETTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.16. <code class="structname">pg_db_role_setting</code></h2></div></div></div><a id="id-1.10.4.18.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_db_role_setting</code> records the default
+ values that have been set for run-time configuration variables,
+ for each role and database combination.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_db_role_setting</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_db_role_setting</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.18.5"><p class="title"><strong>Table 53.16. <code class="structname">pg_db_role_setting</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_db_role_setting Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">setdatabase</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the database the setting is applicable to, or zero if not database-specific
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">setrole</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the role the setting is applicable to, or zero if not role-specific
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">setconfig</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Defaults for run-time configuration variables
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-database.html" title="53.15. pg_database">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.15. <code class="structname">pg_database</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.17. <code class="structname">pg_default_acl</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-default-acl.html b/doc/src/sgml/html/catalog-pg-default-acl.html
new file mode 100644
index 0000000..e123eff
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-default-acl.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.17. pg_default_acl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting" /><link rel="next" href="catalog-pg-depend.html" title="53.18. pg_depend" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.17. <code class="structname">pg_default_acl</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-depend.html" title="53.18. pg_depend">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-DEFAULT-ACL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.17. <code class="structname">pg_default_acl</code></h2></div></div></div><a id="id-1.10.4.19.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_default_acl</code> stores initial
+ privileges to be assigned to newly created objects.
+ </p><div class="table" id="id-1.10.4.19.4"><p class="title"><strong>Table 53.17. <code class="structname">pg_default_acl</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_default_acl Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">defaclrole</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the role associated with this entry
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">defaclnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace associated with this entry,
+ or zero if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">defaclobjtype</code> <code class="type">char</code>
+ </p>
+ <p>
+ Type of object this entry is for:
+ <code class="literal">r</code> = relation (table, view),
+ <code class="literal">S</code> = sequence,
+ <code class="literal">f</code> = function,
+ <code class="literal">T</code> = type,
+ <code class="literal">n</code> = schema
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">defaclacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges that this type of object should have on creation
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ A <code class="structname">pg_default_acl</code> entry shows the initial privileges to
+ be assigned to an object belonging to the indicated user. There are
+ currently two types of entry: <span class="quote">“<span class="quote">global</span>”</span> entries with
+ <code class="structfield">defaclnamespace</code> = zero, and <span class="quote">“<span class="quote">per-schema</span>”</span> entries
+ that reference a particular schema. If a global entry is present then
+ it <span class="emphasis"><em>overrides</em></span> the normal hard-wired default privileges
+ for the object type. A per-schema entry, if present, represents privileges
+ to be <span class="emphasis"><em>added to</em></span> the global or hard-wired default privileges.
+ </p><p>
+ Note that when an ACL entry in another catalog is null, it is taken
+ to represent the hard-wired default privileges for its object,
+ <span class="emphasis"><em>not</em></span> whatever might be in <code class="structname">pg_default_acl</code>
+ at the moment. <code class="structname">pg_default_acl</code> is only consulted during
+ object creation.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-depend.html" title="53.18. pg_depend">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.16. <code class="structname">pg_db_role_setting</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.18. <code class="structname">pg_depend</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-depend.html b/doc/src/sgml/html/catalog-pg-depend.html
new file mode 100644
index 0000000..8a1c088
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-depend.html
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.18. pg_depend</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl" /><link rel="next" href="catalog-pg-description.html" title="53.19. pg_description" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.18. <code class="structname">pg_depend</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-description.html" title="53.19. pg_description">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-DEPEND"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.18. <code class="structname">pg_depend</code></h2></div></div></div><a id="id-1.10.4.20.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_depend</code> records the dependency
+ relationships between database objects. This information allows
+ <code class="command">DROP</code> commands to find which other objects must be dropped
+ by <code class="command">DROP CASCADE</code> or prevent dropping in the <code class="command">DROP
+ RESTRICT</code> case.
+ </p><p>
+ See also <a class="link" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend"><code class="structname">pg_shdepend</code></a>,
+ which performs a similar function for dependencies involving objects
+ that are shared across a database cluster.
+ </p><div class="table" id="id-1.10.4.20.5"><p class="title"><strong>Table 53.18. <code class="structname">pg_depend</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_depend Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog the dependent object is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the specific dependent object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a table column, this is the column number (the
+ <code class="structfield">objid</code> and <code class="structfield">classid</code> refer to the
+ table itself). For all other object types, this column is
+ zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">refclassid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog the referenced object is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">refobjid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the specific referenced object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">refobjsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a table column, this is the column number (the
+ <code class="structfield">refobjid</code> and <code class="structfield">refclassid</code> refer
+ to the table itself). For all other object types, this column
+ is zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">deptype</code> <code class="type">char</code>
+ </p>
+ <p>
+ A code defining the specific semantics of this dependency relationship; see text
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In all cases, a <code class="structname">pg_depend</code> entry indicates that the
+ referenced object cannot be dropped without also dropping the dependent
+ object. However, there are several subflavors identified by
+ <code class="structfield">deptype</code>:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">DEPENDENCY_NORMAL</code> (<code class="literal">n</code>)</span></dt><dd><p>
+ A normal relationship between separately-created objects. The
+ dependent object can be dropped without affecting the
+ referenced object. The referenced object can only be dropped
+ by specifying <code class="literal">CASCADE</code>, in which case the dependent
+ object is dropped, too. Example: a table column has a normal
+ dependency on its data type.
+ </p></dd><dt><span class="term"><code class="symbol">DEPENDENCY_AUTO</code> (<code class="literal">a</code>)</span></dt><dd><p>
+ The dependent object can be dropped separately from the
+ referenced object, and should be automatically dropped
+ (regardless of <code class="literal">RESTRICT</code> or <code class="literal">CASCADE</code>
+ mode) if the referenced object is dropped. Example: a named
+ constraint on a table is made auto-dependent on the table, so
+ that it will go away if the table is dropped.
+ </p></dd><dt><span class="term"><code class="symbol">DEPENDENCY_INTERNAL</code> (<code class="literal">i</code>)</span></dt><dd><p>
+ The dependent object was created as part of creation of the
+ referenced object, and is really just a part of its internal
+ implementation. A direct <code class="command">DROP</code> of the dependent
+ object will be disallowed outright (we'll tell the user to issue
+ a <code class="command">DROP</code> against the referenced object, instead).
+ A <code class="command">DROP</code> of the referenced object will result in
+ automatically dropping the dependent object
+ whether <code class="literal">CASCADE</code> is specified or not. If the
+ dependent object has to be dropped due to a dependency on some other
+ object being removed, its drop is converted to a drop of the referenced
+ object, so that <code class="literal">NORMAL</code> and <code class="literal">AUTO</code>
+ dependencies of the dependent object behave much like they were
+ dependencies of the referenced object.
+ Example: a view's <code class="literal">ON SELECT</code> rule is made
+ internally dependent on the view, preventing it from being dropped
+ while the view remains. Dependencies of the rule (such as tables it
+ refers to) act as if they were dependencies of the view.
+ </p></dd><dt><span class="term"><code class="symbol">DEPENDENCY_PARTITION_PRI</code> (<code class="literal">P</code>)<br /></span><span class="term"><code class="symbol">DEPENDENCY_PARTITION_SEC</code> (<code class="literal">S</code>)</span></dt><dd><p>
+ The dependent object was created as part of creation of the
+ referenced object, and is really just a part of its internal
+ implementation; however, unlike <code class="literal">INTERNAL</code>,
+ there is more than one such referenced object. The dependent object
+ must not be dropped unless at least one of these referenced objects
+ is dropped; if any one is, the dependent object should be dropped
+ whether or not <code class="literal">CASCADE</code> is specified. Also
+ unlike <code class="literal">INTERNAL</code>, a drop of some other object
+ that the dependent object depends on does not result in automatic
+ deletion of any partition-referenced object. Hence, if the drop
+ does not cascade to at least one of these objects via some other
+ path, it will be refused. (In most cases, the dependent object
+ shares all its non-partition dependencies with at least one
+ partition-referenced object, so that this restriction does not
+ result in blocking any cascaded delete.)
+ Primary and secondary partition dependencies behave identically
+ except that the primary dependency is preferred for use in error
+ messages; hence, a partition-dependent object should have one
+ primary partition dependency and one or more secondary partition
+ dependencies.
+ Note that partition dependencies are made in addition to, not
+ instead of, any dependencies the object would normally have. This
+ simplifies <code class="command">ATTACH/DETACH PARTITION</code> operations:
+ the partition dependencies need only be added or removed.
+ Example: a child partitioned index is made partition-dependent
+ on both the partition table it is on and the parent partitioned
+ index, so that it goes away if either of those is dropped, but
+ not otherwise. The dependency on the parent index is primary,
+ so that if the user tries to drop the child partitioned index,
+ the error message will suggest dropping the parent index instead
+ (not the table).
+ </p></dd><dt><span class="term"><code class="symbol">DEPENDENCY_EXTENSION</code> (<code class="literal">e</code>)</span></dt><dd><p>
+ The dependent object is a member of the <em class="firstterm">extension</em> that is
+ the referenced object (see
+ <a class="link" href="catalog-pg-extension.html" title="53.22. pg_extension"><code class="structname">pg_extension</code></a>).
+ The dependent object can be dropped only via
+ <a class="link" href="sql-dropextension.html" title="DROP EXTENSION"><code class="command">DROP EXTENSION</code></a> on the referenced object.
+ Functionally this dependency type acts the same as
+ an <code class="literal">INTERNAL</code> dependency, but it's kept separate for
+ clarity and to simplify <span class="application">pg_dump</span>.
+ </p></dd><dt><span class="term"><code class="symbol">DEPENDENCY_AUTO_EXTENSION</code> (<code class="literal">x</code>)</span></dt><dd><p>
+ The dependent object is not a member of the extension that is the
+ referenced object (and so it should not be ignored
+ by <span class="application">pg_dump</span>), but it cannot function
+ without the extension and should be auto-dropped if the extension is.
+ The dependent object may be dropped on its own as well.
+ Functionally this dependency type acts the same as
+ an <code class="literal">AUTO</code> dependency, but it's kept separate for
+ clarity and to simplify <span class="application">pg_dump</span>.
+ </p></dd></dl></div><p>
+
+ Other dependency flavors might be needed in future.
+ </p><p>
+ Note that it's quite possible for two objects to be linked by more than
+ one <code class="structname">pg_depend</code> entry. For example, a child
+ partitioned index would have both a partition-type dependency on its
+ associated partition table, and an auto dependency on each column of
+ that table that it indexes. This sort of situation expresses the union
+ of multiple dependency semantics. A dependent object can be dropped
+ without <code class="literal">CASCADE</code> if any of its dependencies satisfies
+ its condition for automatic dropping. Conversely, all the
+ dependencies' restrictions about which objects must be dropped together
+ must be satisfied.
+ </p><p>
+ Most objects created during <span class="application">initdb</span> are
+ considered <span class="quote">“<span class="quote">pinned</span>”</span>, which means that the system itself
+ depends on them. Therefore, they are never allowed to be dropped.
+ Also, knowing that pinned objects will not be dropped, the dependency
+ mechanism doesn't bother to make <code class="structname">pg_depend</code>
+ entries showing dependencies on them. Thus, for example, a table
+ column of type <code class="type">numeric</code> notionally has
+ a <code class="literal">NORMAL</code> dependency on the <code class="type">numeric</code>
+ data type, but no such entry actually appears
+ in <code class="structname">pg_depend</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-description.html" title="53.19. pg_description">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.17. <code class="structname">pg_default_acl</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.19. <code class="structname">pg_description</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-description.html b/doc/src/sgml/html/catalog-pg-description.html
new file mode 100644
index 0000000..5eccdbd
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-description.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.19. pg_description</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-depend.html" title="53.18. pg_depend" /><link rel="next" href="catalog-pg-enum.html" title="53.20. pg_enum" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.19. <code class="structname">pg_description</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-depend.html" title="53.18. pg_depend">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-enum.html" title="53.20. pg_enum">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-DESCRIPTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.19. <code class="structname">pg_description</code></h2></div></div></div><a id="id-1.10.4.21.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_description</code> stores optional descriptions
+ (comments) for each database object. Descriptions can be manipulated
+ with the <a class="link" href="sql-comment.html" title="COMMENT"><code class="command">COMMENT</code></a> command and viewed with
+ <span class="application">psql</span>'s <code class="literal">\d</code> commands.
+ Descriptions of many built-in system objects are provided in the initial
+ contents of <code class="structname">pg_description</code>.
+ </p><p>
+ See also <a class="link" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription"><code class="structname">pg_shdescription</code></a>,
+ which performs a similar function for descriptions involving objects that
+ are shared across a database cluster.
+ </p><div class="table" id="id-1.10.4.21.5"><p class="title"><strong>Table 53.19. <code class="structname">pg_description</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_description Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objoid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the object this description pertains to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog this object appears in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a comment on a table column, this is the column number (the
+ <code class="structfield">objoid</code> and <code class="structfield">classoid</code> refer to
+ the table itself). For all other object types, this column is
+ zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">description</code> <code class="type">text</code>
+ </p>
+ <p>
+ Arbitrary text that serves as the description of this object
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-depend.html" title="53.18. pg_depend">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-enum.html" title="53.20. pg_enum">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.18. <code class="structname">pg_depend</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.20. <code class="structname">pg_enum</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-enum.html b/doc/src/sgml/html/catalog-pg-enum.html
new file mode 100644
index 0000000..4d298cc
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-enum.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.20. pg_enum</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-description.html" title="53.19. pg_description" /><link rel="next" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.20. <code class="structname">pg_enum</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-description.html" title="53.19. pg_description">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-ENUM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.20. <code class="structname">pg_enum</code></h2></div></div></div><a id="id-1.10.4.22.2" class="indexterm"></a><p>
+ The <code class="structname">pg_enum</code> catalog contains entries
+ showing the values and labels for each enum type. The
+ internal representation of a given enum value is actually the OID
+ of its associated row in <code class="structname">pg_enum</code>.
+ </p><div class="table" id="id-1.10.4.22.4"><p class="title"><strong>Table 53.20. <code class="structname">pg_enum</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_enum Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">enumtypid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a> entry owning this enum value
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">enumsortorder</code> <code class="type">float4</code>
+ </p>
+ <p>
+ The sort position of this enum value within its enum type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">enumlabel</code> <code class="type">name</code>
+ </p>
+ <p>
+ The textual label for this enum value
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The OIDs for <code class="structname">pg_enum</code> rows follow a special
+ rule: even-numbered OIDs are guaranteed to be ordered in the same way
+ as the sort ordering of their enum type. That is, if two even OIDs
+ belong to the same enum type, the smaller OID must have the smaller
+ <code class="structfield">enumsortorder</code> value. Odd-numbered OID values
+ need bear no relationship to the sort order. This rule allows the
+ enum comparison routines to avoid catalog lookups in many common cases.
+ The routines that create and alter enum types attempt to assign even
+ OIDs to enum values whenever possible.
+ </p><p>
+ When an enum type is created, its members are assigned sort-order
+ positions 1..<em class="replaceable"><code>n</code></em>. But members added later might be given
+ negative or fractional values of <code class="structfield">enumsortorder</code>.
+ The only requirement on these values is that they be correctly
+ ordered and unique within each enum type.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-description.html" title="53.19. pg_description">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.19. <code class="structname">pg_description</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.21. <code class="structname">pg_event_trigger</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-event-trigger.html b/doc/src/sgml/html/catalog-pg-event-trigger.html
new file mode 100644
index 0000000..2748e0b
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-event-trigger.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.21. pg_event_trigger</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-enum.html" title="53.20. pg_enum" /><link rel="next" href="catalog-pg-extension.html" title="53.22. pg_extension" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.21. <code class="structname">pg_event_trigger</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-enum.html" title="53.20. pg_enum">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-extension.html" title="53.22. pg_extension">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-EVENT-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.21. <code class="structname">pg_event_trigger</code></h2></div></div></div><a id="id-1.10.4.23.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_event_trigger</code> stores event triggers.
+ See <a class="xref" href="event-triggers.html" title="Chapter 40. Event Triggers">Chapter 40</a> for more information.
+ </p><div class="table" id="id-1.10.4.23.4"><p class="title"><strong>Table 53.21. <code class="structname">pg_event_trigger</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_event_trigger Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">evtname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Trigger name (must be unique)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">evtevent</code> <code class="type">name</code>
+ </p>
+ <p>
+ Identifies the event for which this trigger fires
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">evtowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the event trigger
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">evtfoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The function to be called
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">evtenabled</code> <code class="type">char</code>
+ </p>
+ <p>
+ Controls in which <a class="xref" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE">session_replication_role</a> modes
+ the event trigger fires.
+ <code class="literal">O</code> = trigger fires in <span class="quote">“<span class="quote">origin</span>”</span> and <span class="quote">“<span class="quote">local</span>”</span> modes,
+ <code class="literal">D</code> = trigger is disabled,
+ <code class="literal">R</code> = trigger fires in <span class="quote">“<span class="quote">replica</span>”</span> mode,
+ <code class="literal">A</code> = trigger fires always.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">evttags</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Command tags for which this trigger will fire. If NULL, the firing
+ of this trigger is not restricted on the basis of the command tag.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-enum.html" title="53.20. pg_enum">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-extension.html" title="53.22. pg_extension">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.20. <code class="structname">pg_enum</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.22. <code class="structname">pg_extension</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-extension.html b/doc/src/sgml/html/catalog-pg-extension.html
new file mode 100644
index 0000000..cf0f025
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-extension.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.22. pg_extension</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger" /><link rel="next" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.22. <code class="structname">pg_extension</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-EXTENSION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.22. <code class="structname">pg_extension</code></h2></div></div></div><a id="id-1.10.4.24.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_extension</code> stores information
+ about the installed extensions. See <a class="xref" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Section 38.17</a>
+ for details about extensions.
+ </p><div class="table" id="id-1.10.4.24.4"><p class="title"><strong>Table 53.22. <code class="structname">pg_extension</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_extension Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the extension
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the extension
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Schema containing the extension's exported objects
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extrelocatable</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if extension can be relocated to another schema
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extversion</code> <code class="type">text</code>
+ </p>
+ <p>
+ Version name for the extension
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extconfig</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Array of <code class="type">regclass</code> OIDs for the extension's configuration
+ table(s), or <code class="literal">NULL</code> if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extcondition</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Array of <code class="literal">WHERE</code>-clause filter conditions for the
+ extension's configuration table(s), or <code class="literal">NULL</code> if none
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Note that unlike most catalogs with a <span class="quote">“<span class="quote">namespace</span>”</span> column,
+ <code class="structfield">extnamespace</code> is not meant to imply
+ that the extension belongs to that schema. Extension names are never
+ schema-qualified. Rather, <code class="structfield">extnamespace</code>
+ indicates the schema that contains most or all of the extension's
+ objects. If <code class="structfield">extrelocatable</code> is true, then
+ this schema must in fact contain all schema-qualifiable objects
+ belonging to the extension.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.21. <code class="structname">pg_event_trigger</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.23. <code class="structname">pg_foreign_data_wrapper</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-foreign-data-wrapper.html b/doc/src/sgml/html/catalog-pg-foreign-data-wrapper.html
new file mode 100644
index 0000000..8cedeb4
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-foreign-data-wrapper.html
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.23. pg_foreign_data_wrapper</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-extension.html" title="53.22. pg_extension" /><link rel="next" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.23. <code class="structname">pg_foreign_data_wrapper</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-extension.html" title="53.22. pg_extension">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-FOREIGN-DATA-WRAPPER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.23. <code class="structname">pg_foreign_data_wrapper</code></h2></div></div></div><a id="id-1.10.4.25.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_foreign_data_wrapper</code> stores
+ foreign-data wrapper definitions. A foreign-data wrapper is the
+ mechanism by which external data, residing on foreign servers, is
+ accessed.
+ </p><div class="table" id="id-1.10.4.25.4"><p class="title"><strong>Table 53.23. <code class="structname">pg_foreign_data_wrapper</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_foreign_data_wrapper Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fdwname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the foreign-data wrapper
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fdwowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the foreign-data wrapper
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fdwhandler</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ References a handler function that is responsible for
+ supplying execution routines for the foreign-data wrapper.
+ Zero if no handler is provided
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fdwvalidator</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ References a validator function that is responsible for
+ checking the validity of the options given to the
+ foreign-data wrapper, as well as options for foreign servers and user
+ mappings using the foreign-data wrapper. Zero if no validator
+ is provided
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fdwacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fdwoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Foreign-data wrapper specific options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-extension.html" title="53.22. pg_extension">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.22. <code class="structname">pg_extension</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.24. <code class="structname">pg_foreign_server</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-foreign-server.html b/doc/src/sgml/html/catalog-pg-foreign-server.html
new file mode 100644
index 0000000..b3e9a10
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-foreign-server.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.24. pg_foreign_server</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper" /><link rel="next" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.24. <code class="structname">pg_foreign_server</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-FOREIGN-SERVER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.24. <code class="structname">pg_foreign_server</code></h2></div></div></div><a id="id-1.10.4.26.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_foreign_server</code> stores
+ foreign server definitions. A foreign server describes a source
+ of external data, such as a remote server. Foreign
+ servers are accessed via foreign-data wrappers.
+ </p><div class="table" id="id-1.10.4.26.4"><p class="title"><strong>Table 53.24. <code class="structname">pg_foreign_server</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_foreign_server Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvfdw</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper"><code class="structname">pg_foreign_data_wrapper</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the foreign-data wrapper of this foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvtype</code> <code class="type">text</code>
+ </p>
+ <p>
+ Type of the server (optional)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvversion</code> <code class="type">text</code>
+ </p>
+ <p>
+ Version of the server (optional)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Foreign server specific options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.23. <code class="structname">pg_foreign_data_wrapper</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.25. <code class="structname">pg_foreign_table</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-foreign-table.html b/doc/src/sgml/html/catalog-pg-foreign-table.html
new file mode 100644
index 0000000..38a2419
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-foreign-table.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.25. pg_foreign_table</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server" /><link rel="next" href="catalog-pg-index.html" title="53.26. pg_index" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.25. <code class="structname">pg_foreign_table</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-index.html" title="53.26. pg_index">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-FOREIGN-TABLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.25. <code class="structname">pg_foreign_table</code></h2></div></div></div><a id="id-1.10.4.27.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_foreign_table</code> contains
+ auxiliary information about foreign tables. A foreign table is
+ primarily represented by a
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>
+ entry, just like a regular table. Its <code class="structname">pg_foreign_table</code>
+ entry contains the information that is pertinent only to foreign tables
+ and not any other kind of relation.
+ </p><div class="table" id="id-1.10.4.27.4"><p class="title"><strong>Table 53.25. <code class="structname">pg_foreign_table</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_foreign_table Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ftrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry for this foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ftserver</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server"><code class="structname">pg_foreign_server</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the foreign server for this foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ftoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Foreign table options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-index.html" title="53.26. pg_index">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.24. <code class="structname">pg_foreign_server</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.26. <code class="structname">pg_index</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-index.html b/doc/src/sgml/html/catalog-pg-index.html
new file mode 100644
index 0000000..0220a4f
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-index.html
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.26. pg_index</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table" /><link rel="next" href="catalog-pg-inherits.html" title="53.27. pg_inherits" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.26. <code class="structname">pg_index</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-inherits.html" title="53.27. pg_inherits">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-INDEX"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.26. <code class="structname">pg_index</code></h2></div></div></div><a id="id-1.10.4.28.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_index</code> contains part of the information
+ about indexes. The rest is mostly in
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.
+ </p><div class="table" id="id-1.10.4.28.4"><p class="title"><strong>Table 53.26. <code class="structname">pg_index</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_index Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry for this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry for the table this index is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indnatts</code> <code class="type">int2</code>
+ </p>
+ <p>
+ The total number of columns in the index (duplicates
+ <code class="literal">pg_class.relnatts</code>); this number includes both key and included attributes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indnkeyatts</code> <code class="type">int2</code>
+ </p>
+ <p>
+ The number of <em class="firstterm">key columns</em> in the index,
+ not counting any <em class="firstterm">included columns</em>, which are
+ merely stored and do not participate in the index semantics
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisunique</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, this is a unique index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indnullsnotdistinct</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This value is only used for unique indexes. If false, this unique
+ index will consider null values distinct (so the index can contain
+ multiple null values in a column, the default PostgreSQL behavior). If
+ it is true, it will consider null values to be equal (so the index can
+ only contain one null value in a column).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisprimary</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, this index represents the primary key of the table
+ (<code class="structfield">indisunique</code> should always be true when this is true)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisexclusion</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, this index supports an exclusion constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indimmediate</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the uniqueness check is enforced immediately on
+ insertion
+ (irrelevant if <code class="structfield">indisunique</code> is not true)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisclustered</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the table was last clustered on this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisvalid</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the index is currently valid for queries. False means the
+ index is possibly incomplete: it must still be modified by
+ <a class="link" href="sql-insert.html" title="INSERT"><code class="command">INSERT</code></a>/<a class="link" href="sql-update.html" title="UPDATE"><code class="command">UPDATE</code></a> operations, but it cannot safely
+ be used for queries. If it is unique, the uniqueness property is not
+ guaranteed true either.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indcheckxmin</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, queries must not use the index until the <code class="structfield">xmin</code>
+ of this <code class="structname">pg_index</code> row is below their <code class="symbol">TransactionXmin</code>
+ event horizon, because the table may contain broken <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">HOT chains</a> with
+ incompatible rows that they can see
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisready</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the index is currently ready for inserts. False means the
+ index must be ignored by <a class="link" href="sql-insert.html" title="INSERT"><code class="command">INSERT</code></a>/<a class="link" href="sql-update.html" title="UPDATE"><code class="command">UPDATE</code></a>
+ operations.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indislive</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If false, the index is in process of being dropped, and should be
+ ignored for all purposes (including HOT-safety decisions)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indisreplident</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true this index has been chosen as <span class="quote">“<span class="quote">replica identity</span>”</span>
+ using <a class="link" href="sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY"><code class="command">ALTER TABLE ...
+ REPLICA IDENTITY USING INDEX ...</code></a>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indkey</code> <code class="type">int2vector</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ This is an array of <code class="structfield">indnatts</code> values that
+ indicate which table columns this index indexes. For example, a value
+ of <code class="literal">1 3</code> would mean that the first and the third table
+ columns make up the index entries. Key columns come before non-key
+ (included) columns. A zero in this array indicates that the
+ corresponding index attribute is an expression over the table columns,
+ rather than a simple column reference.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indcollation</code> <code class="type">oidvector</code>
+ (references <a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For each column in the index key
+ (<code class="structfield">indnkeyatts</code> values), this contains the OID
+ of the collation to use for the index, or zero if the column is not of
+ a collatable data type.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indclass</code> <code class="type">oidvector</code>
+ (references <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For each column in the index key
+ (<code class="structfield">indnkeyatts</code> values), this contains the OID
+ of the operator class to use. See
+ <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a> for details.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indoption</code> <code class="type">int2vector</code>
+ </p>
+ <p>
+ This is an array of <code class="structfield">indnkeyatts</code> values that
+ store per-column flag bits. The meaning of the bits is defined by
+ the index's access method.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexprs</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression trees (in <code class="function">nodeToString()</code>
+ representation) for index attributes that are not simple column
+ references. This is a list with one element for each zero
+ entry in <code class="structfield">indkey</code>. Null if all index attributes
+ are simple references.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indpred</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression tree (in <code class="function">nodeToString()</code>
+ representation) for partial index predicate. Null if not a
+ partial index.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-inherits.html" title="53.27. pg_inherits">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.25. <code class="structname">pg_foreign_table</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.27. <code class="structname">pg_inherits</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-inherits.html b/doc/src/sgml/html/catalog-pg-inherits.html
new file mode 100644
index 0000000..31f5b8d
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-inherits.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.27. pg_inherits</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-index.html" title="53.26. pg_index" /><link rel="next" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.27. <code class="structname">pg_inherits</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-index.html" title="53.26. pg_index">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-INHERITS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.27. <code class="structname">pg_inherits</code></h2></div></div></div><a id="id-1.10.4.29.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_inherits</code> records information about
+ table and index inheritance hierarchies. There is one entry for each direct
+ parent-child table or index relationship in the database. (Indirect
+ inheritance can be determined by following chains of entries.)
+ </p><div class="table" id="id-1.10.4.29.4"><p class="title"><strong>Table 53.27. <code class="structname">pg_inherits</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_inherits Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inhrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the child table or index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inhparent</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the parent table or index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inhseqno</code> <code class="type">int4</code>
+ </p>
+ <p>
+ If there is more than one direct parent for a child table (multiple
+ inheritance), this number tells the order in which the
+ inherited columns are to be arranged. The count starts at 1.
+ </p>
+ <p>
+ Indexes cannot have multiple inheritance, since they can only inherit
+ when using declarative partitioning.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inhdetachpending</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="literal">true</code> for a partition that is in the process of
+ being detached; <code class="literal">false</code> otherwise.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-index.html" title="53.26. pg_index">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.26. <code class="structname">pg_index</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.28. <code class="structname">pg_init_privs</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-init-privs.html b/doc/src/sgml/html/catalog-pg-init-privs.html
new file mode 100644
index 0000000..136357b
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-init-privs.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.28. pg_init_privs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-inherits.html" title="53.27. pg_inherits" /><link rel="next" href="catalog-pg-language.html" title="53.29. pg_language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.28. <code class="structname">pg_init_privs</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-inherits.html" title="53.27. pg_inherits">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-language.html" title="53.29. pg_language">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-INIT-PRIVS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.28. <code class="structname">pg_init_privs</code></h2></div></div></div><a id="id-1.10.4.30.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_init_privs</code> records information about
+ the initial privileges of objects in the system. There is one entry
+ for each object in the database which has a non-default (non-NULL)
+ initial set of privileges.
+ </p><p>
+ Objects can have initial privileges either by having those privileges set
+ when the system is initialized (by <span class="application">initdb</span>) or when the
+ object is created during a <a class="link" href="sql-createextension.html" title="CREATE EXTENSION"><code class="command">CREATE EXTENSION</code></a> and the
+ extension script sets initial privileges using the <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a>
+ system. Note that the system will automatically handle recording of the
+ privileges during the extension script and that extension authors need
+ only use the <code class="command">GRANT</code> and <code class="command">REVOKE</code>
+ statements in their script to have the privileges recorded. The
+ <code class="literal">privtype</code> column indicates if the initial privilege was
+ set by <span class="application">initdb</span> or during a
+ <code class="command">CREATE EXTENSION</code> command.
+ </p><p>
+ Objects which have initial privileges set by <span class="application">initdb</span> will
+ have entries where <code class="literal">privtype</code> is
+ <code class="literal">'i'</code>, while objects which have initial privileges set
+ by <code class="command">CREATE EXTENSION</code> will have entries where
+ <code class="literal">privtype</code> is <code class="literal">'e'</code>.
+ </p><div class="table" id="id-1.10.4.30.6"><p class="title"><strong>Table 53.28. <code class="structname">pg_init_privs</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_init_privs Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objoid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the specific object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog the object is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a table column, this is the column number (the
+ <code class="structfield">objoid</code> and <code class="structfield">classoid</code> refer to the
+ table itself). For all other object types, this column is
+ zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privtype</code> <code class="type">char</code>
+ </p>
+ <p>
+ A code defining the type of initial privilege of this object; see text
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">initprivs</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ The initial access privileges; see
+ <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-inherits.html" title="53.27. pg_inherits">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-language.html" title="53.29. pg_language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.27. <code class="structname">pg_inherits</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.29. <code class="structname">pg_language</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-language.html b/doc/src/sgml/html/catalog-pg-language.html
new file mode 100644
index 0000000..a9ded71
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-language.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.29. pg_language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs" /><link rel="next" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.29. <code class="structname">pg_language</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-LANGUAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.29. <code class="structname">pg_language</code></h2></div></div></div><a id="id-1.10.4.31.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_language</code> registers
+ languages in which you can write functions or stored procedures.
+ See <a class="xref" href="sql-createlanguage.html" title="CREATE LANGUAGE"><span class="refentrytitle">CREATE LANGUAGE</span></a>
+ and <a class="xref" href="xplang.html" title="Chapter 42. Procedural Languages">Chapter 42</a> for more information about language handlers.
+ </p><div class="table" id="id-1.10.4.31.4"><p class="title"><strong>Table 53.29. <code class="structname">pg_language</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_language Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the language
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the language
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanispl</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This is false for internal languages (such as
+ <acronym class="acronym">SQL</acronym>) and true for user-defined languages.
+ Currently, <span class="application">pg_dump</span> still uses this
+ to determine which languages need to be dumped, but this might be
+ replaced by a different mechanism in the future.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanpltrusted</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this is a trusted language, which means that it is believed
+ not to grant access to anything outside the normal SQL execution
+ environment. Only superusers can create functions in untrusted
+ languages.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanplcallfoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For noninternal languages this references the language
+ handler, which is a special function that is responsible for
+ executing all functions that are written in the particular
+ language. Zero for internal languages.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">laninline</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ This references a function that is responsible for executing
+ <span class="quote">“<span class="quote">inline</span>”</span> anonymous code blocks
+ (<a class="xref" href="sql-do.html" title="DO"><span class="refentrytitle">DO</span></a> blocks).
+ Zero if inline blocks are not supported.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanvalidator</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ This references a language validator function that is responsible
+ for checking the syntax and validity of new functions when they
+ are created. Zero if no validator is provided.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lanacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.28. <code class="structname">pg_init_privs</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.30. <code class="structname">pg_largeobject</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-largeobject-metadata.html b/doc/src/sgml/html/catalog-pg-largeobject-metadata.html
new file mode 100644
index 0000000..6f27753
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-largeobject-metadata.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.31. pg_largeobject_metadata</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject" /><link rel="next" href="catalog-pg-namespace.html" title="53.32. pg_namespace" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.31. <code class="structname">pg_largeobject_metadata</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-namespace.html" title="53.32. pg_namespace">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-LARGEOBJECT-METADATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.31. <code class="structname">pg_largeobject_metadata</code></h2></div></div></div><a id="id-1.10.4.33.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_largeobject_metadata</code>
+ holds metadata associated with large objects. The actual large object
+ data is stored in
+ <a class="link" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject"><code class="structname">pg_largeobject</code></a>.
+ </p><div class="table" id="id-1.10.4.33.4"><p class="title"><strong>Table 53.31. <code class="structname">pg_largeobject_metadata</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_largeobject_metadata Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lomowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the large object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lomacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-namespace.html" title="53.32. pg_namespace">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.30. <code class="structname">pg_largeobject</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.32. <code class="structname">pg_namespace</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-largeobject.html b/doc/src/sgml/html/catalog-pg-largeobject.html
new file mode 100644
index 0000000..66466b9
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-largeobject.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.30. pg_largeobject</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-language.html" title="53.29. pg_language" /><link rel="next" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.30. <code class="structname">pg_largeobject</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-language.html" title="53.29. pg_language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-LARGEOBJECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.30. <code class="structname">pg_largeobject</code></h2></div></div></div><a id="id-1.10.4.32.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_largeobject</code> holds the data making up
+ <span class="quote">“<span class="quote">large objects</span>”</span>. A large object is identified by an OID
+ assigned when it is created. Each large object is broken into
+ segments or <span class="quote">“<span class="quote">pages</span>”</span> small enough to be conveniently stored as rows
+ in <code class="structname">pg_largeobject</code>.
+ The amount of data per page is defined to be <code class="symbol">LOBLKSIZE</code> (which is currently
+ <code class="literal">BLCKSZ/4</code>, or typically 2 kB).
+ </p><p>
+ Prior to <span class="productname">PostgreSQL</span> 9.0, there was no permission structure
+ associated with large objects. As a result,
+ <code class="structname">pg_largeobject</code> was publicly readable and could be
+ used to obtain the OIDs (and contents) of all large objects in the system.
+ This is no longer the case; use
+ <a class="link" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata"><code class="structname">pg_largeobject_metadata</code></a>
+ to obtain a list of large object OIDs.
+ </p><div class="table" id="id-1.10.4.32.5"><p class="title"><strong>Table 53.30. <code class="structname">pg_largeobject</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_largeobject Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">loid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata"><code class="structname">pg_largeobject_metadata</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Identifier of the large object that includes this page
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pageno</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Page number of this page within its large object
+ (counting from zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data</code> <code class="type">bytea</code>
+ </p>
+ <p>
+ Actual data stored in the large object.
+ This will never be more than <code class="symbol">LOBLKSIZE</code> bytes and might be less.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Each row of <code class="structname">pg_largeobject</code> holds data
+ for one page of a large object, beginning at
+ byte offset (<code class="literal">pageno * LOBLKSIZE</code>) within the object. The implementation
+ allows sparse storage: pages might be missing, and might be shorter than
+ <code class="literal">LOBLKSIZE</code> bytes even if they are not the last page of the object.
+ Missing regions within a large object read as zeroes.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-language.html" title="53.29. pg_language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.29. <code class="structname">pg_language</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.31. <code class="structname">pg_largeobject_metadata</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-namespace.html b/doc/src/sgml/html/catalog-pg-namespace.html
new file mode 100644
index 0000000..82c852f
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-namespace.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.32. pg_namespace</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata" /><link rel="next" href="catalog-pg-opclass.html" title="53.33. pg_opclass" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.32. <code class="structname">pg_namespace</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-opclass.html" title="53.33. pg_opclass">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-NAMESPACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.32. <code class="structname">pg_namespace</code></h2></div></div></div><a id="id-1.10.4.34.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_namespace</code> stores namespaces.
+ A namespace is the structure underlying SQL schemas: each namespace
+ can have a separate collection of relations, types, etc. without name
+ conflicts.
+ </p><div class="table" id="id-1.10.4.34.4"><p class="title"><strong>Table 53.32. <code class="structname">pg_namespace</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_namespace Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">nspname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the namespace
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">nspowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the namespace
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">nspacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-opclass.html" title="53.33. pg_opclass">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.31. <code class="structname">pg_largeobject_metadata</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.33. <code class="structname">pg_opclass</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-opclass.html b/doc/src/sgml/html/catalog-pg-opclass.html
new file mode 100644
index 0000000..99fdfd4
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-opclass.html
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.33. pg_opclass</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-namespace.html" title="53.32. pg_namespace" /><link rel="next" href="catalog-pg-operator.html" title="53.34. pg_operator" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.33. <code class="structname">pg_opclass</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-namespace.html" title="53.32. pg_namespace">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-operator.html" title="53.34. pg_operator">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-OPCLASS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.33. <code class="structname">pg_opclass</code></h2></div></div></div><a id="id-1.10.4.35.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_opclass</code> defines
+ index access method operator classes. Each operator class defines
+ semantics for index columns of a particular data type and a particular
+ index access method. An operator class essentially specifies that a
+ particular operator family is applicable to a particular indexable column
+ data type. The set of operators from the family that are actually usable
+ with the indexed column are whichever ones accept the column's data type
+ as their left-hand input.
+ </p><p>
+ Operator classes are described at length in <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a>.
+ </p><div class="table" id="id-1.10.4.35.5"><p class="title"><strong>Table 53.33. <code class="structname">pg_opclass</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_opclass Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcmethod</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Index access method operator class is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this operator class
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Namespace of this operator class
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the operator class
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcfamily</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily"><code class="structname">pg_opfamily</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Operator family containing the operator class
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcintype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type that the operator class indexes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opcdefault</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this operator class is the default for <code class="structfield">opcintype</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opckeytype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Type of data stored in index, or zero if same as <code class="structfield">opcintype</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ An operator class's <code class="structfield">opcmethod</code> must match the
+ <code class="structfield">opfmethod</code> of its containing operator family.
+ Also, there must be no more than one <code class="structname">pg_opclass</code>
+ row having <code class="structfield">opcdefault</code> true for any given combination of
+ <code class="structfield">opcmethod</code> and <code class="structfield">opcintype</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-namespace.html" title="53.32. pg_namespace">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-operator.html" title="53.34. pg_operator">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.32. <code class="structname">pg_namespace</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.34. <code class="structname">pg_operator</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-operator.html b/doc/src/sgml/html/catalog-pg-operator.html
new file mode 100644
index 0000000..2008175
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-operator.html
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.34. pg_operator</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-opclass.html" title="53.33. pg_opclass" /><link rel="next" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.34. <code class="structname">pg_operator</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-opclass.html" title="53.33. pg_opclass">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-OPERATOR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.34. <code class="structname">pg_operator</code></h2></div></div></div><a id="id-1.10.4.36.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_operator</code> stores information about operators.
+ See <a class="xref" href="sql-createoperator.html" title="CREATE OPERATOR"><span class="refentrytitle">CREATE OPERATOR</span></a>
+ and <a class="xref" href="xoper.html" title="38.14. User-Defined Operators">Section 38.14</a> for more information.
+ </p><div class="table" id="id-1.10.4.36.4"><p class="title"><strong>Table 53.34. <code class="structname">pg_operator</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_operator Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the operator
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprkind</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="literal">b</code> = infix operator (<span class="quote">“<span class="quote">both</span>”</span>),
+ or <code class="literal">l</code> = prefix operator (<span class="quote">“<span class="quote">left</span>”</span>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprcanmerge</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This operator supports merge joins
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprcanhash</code> <code class="type">bool</code>
+ </p>
+ <p>
+ This operator supports hash joins
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprleft</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Type of the left operand (zero for a prefix operator)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprright</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Type of the right operand
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprresult</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Type of the result
+ (zero for a not-yet-defined <span class="quote">“<span class="quote">shell</span>”</span> operator)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprcom</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Commutator of this operator (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprnegate</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Negator of this operator (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprcode</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Function that implements this operator
+ (zero for a not-yet-defined <span class="quote">“<span class="quote">shell</span>”</span> operator)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprrest</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Restriction selectivity estimation function for this operator
+ (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oprjoin</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Join selectivity estimation function for this operator
+ (zero if none)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-opclass.html" title="53.33. pg_opclass">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.33. <code class="structname">pg_opclass</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.35. <code class="structname">pg_opfamily</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-opfamily.html b/doc/src/sgml/html/catalog-pg-opfamily.html
new file mode 100644
index 0000000..b868ca6
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-opfamily.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.35. pg_opfamily</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-operator.html" title="53.34. pg_operator" /><link rel="next" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.35. <code class="structname">pg_opfamily</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-operator.html" title="53.34. pg_operator">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-OPFAMILY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.35. <code class="structname">pg_opfamily</code></h2></div></div></div><a id="id-1.10.4.37.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_opfamily</code> defines operator families.
+ Each operator family is a collection of operators and associated
+ support routines that implement the semantics specified for a particular
+ index access method. Furthermore, the operators in a family are all
+ <span class="quote">“<span class="quote">compatible</span>”</span>, in a way that is specified by the access method.
+ The operator family concept allows cross-data-type operators to be used
+ with indexes and to be reasoned about using knowledge of access method
+ semantics.
+ </p><p>
+ Operator families are described at length in <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a>.
+ </p><div class="table" id="id-1.10.4.37.5"><p class="title"><strong>Table 53.35. <code class="structname">pg_opfamily</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_opfamily Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opfmethod</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Index access method operator family is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opfname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this operator family
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opfnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Namespace of this operator family
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">opfowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the operator family
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The majority of the information defining an operator family is not in its
+ <code class="structname">pg_opfamily</code> row, but in the associated rows in
+ <a class="link" href="catalog-pg-amop.html" title="53.4. pg_amop"><code class="structname">pg_amop</code></a>,
+ <a class="link" href="catalog-pg-amproc.html" title="53.5. pg_amproc"><code class="structname">pg_amproc</code></a>,
+ and
+ <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-operator.html" title="53.34. pg_operator">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.34. <code class="structname">pg_operator</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.36. <code class="structname">pg_parameter_acl</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-parameter-acl.html b/doc/src/sgml/html/catalog-pg-parameter-acl.html
new file mode 100644
index 0000000..094a794
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-parameter-acl.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.36. pg_parameter_acl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily" /><link rel="next" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.36. <code class="structname">pg_parameter_acl</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-PARAMETER-ACL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.36. <code class="structname">pg_parameter_acl</code></h2></div></div></div><a id="id-1.10.4.38.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_parameter_acl</code> records configuration
+ parameters for which privileges have been granted to one or more roles.
+ No entry is made for parameters that have default privileges.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_parameter_acl</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_parameter_acl</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.38.5"><p class="title"><strong>Table 53.36. <code class="structname">pg_parameter_acl</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_parameter_acl Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parname</code> <code class="type">text</code>
+ </p>
+ <p>
+ The name of a configuration parameter for which privileges are granted
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">paracl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.35. <code class="structname">pg_opfamily</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.37. <code class="structname">pg_partitioned_table</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-partitioned-table.html b/doc/src/sgml/html/catalog-pg-partitioned-table.html
new file mode 100644
index 0000000..951adbb
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-partitioned-table.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.37. pg_partitioned_table</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl" /><link rel="next" href="catalog-pg-policy.html" title="53.38. pg_policy" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.37. <code class="structname">pg_partitioned_table</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-policy.html" title="53.38. pg_policy">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-PARTITIONED-TABLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.37. <code class="structname">pg_partitioned_table</code></h2></div></div></div><a id="id-1.10.4.39.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_partitioned_table</code> stores
+ information about how tables are partitioned.
+ </p><div class="table" id="id-1.10.4.39.4"><p class="title"><strong>Table 53.37. <code class="structname">pg_partitioned_table</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_partitioned_table Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry for this partitioned table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partstrat</code> <code class="type">char</code>
+ </p>
+ <p>
+ Partitioning strategy; <code class="literal">h</code> = hash partitioned table,
+ <code class="literal">l</code> = list partitioned table, <code class="literal">r</code> = range partitioned table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partnatts</code> <code class="type">int2</code>
+ </p>
+ <p>
+ The number of columns in the partition key
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partdefid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry for the default partition
+ of this partitioned table, or zero if this partitioned table does not
+ have a default partition
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partattrs</code> <code class="type">int2vector</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ This is an array of <code class="structfield">partnatts</code> values that
+ indicate which table columns are part of the partition key. For
+ example, a value of <code class="literal">1 3</code> would mean that the first
+ and the third table columns make up the partition key. A zero in this
+ array indicates that the corresponding partition key column is an
+ expression, rather than a simple column reference.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partclass</code> <code class="type">oidvector</code>
+ (references <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For each column in the partition key, this contains the OID of the
+ operator class to use. See
+ <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a> for details.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partcollation</code> <code class="type">oidvector</code>
+ (references <a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ For each column in the partition key, this contains the OID of the
+ collation to use for partitioning, or zero if the column is not
+ of a collatable data type.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partexprs</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression trees (in <code class="function">nodeToString()</code>
+ representation) for partition key columns that are not simple column
+ references. This is a list with one element for each zero
+ entry in <code class="structfield">partattrs</code>. Null if all partition key columns
+ are simple references.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-policy.html" title="53.38. pg_policy">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.36. <code class="structname">pg_parameter_acl</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.38. <code class="structname">pg_policy</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-policy.html b/doc/src/sgml/html/catalog-pg-policy.html
new file mode 100644
index 0000000..1d819e5
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-policy.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.38. pg_policy</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table" /><link rel="next" href="catalog-pg-proc.html" title="53.39. pg_proc" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.38. <code class="structname">pg_policy</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-proc.html" title="53.39. pg_proc">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-POLICY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.38. <code class="structname">pg_policy</code></h2></div></div></div><a id="id-1.10.4.40.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_policy</code> stores row-level
+ security policies for tables. A policy includes the kind of
+ command that it applies to (possibly all commands), the roles that it
+ applies to, the expression to be added as a security-barrier
+ qualification to queries that include the table, and the expression
+ to be added as a <code class="literal">WITH CHECK</code> option for queries that attempt to
+ add new records to the table.
+ </p><div class="table" id="id-1.10.4.40.4"><p class="title"><strong>Table 53.38. <code class="structname">pg_policy</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_policy Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polname</code> <code class="type">name</code>
+ </p>
+ <p>
+ The name of the policy
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table to which the policy applies
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polcmd</code> <code class="type">char</code>
+ </p>
+ <p>
+ The command type to which the policy is applied:
+ <code class="literal">r</code> for <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>,
+ <code class="literal">a</code> for <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>,
+ <code class="literal">w</code> for <a class="xref" href="sql-update.html" title="UPDATE"><span class="refentrytitle">UPDATE</span></a>,
+ <code class="literal">d</code> for <a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a>,
+ or <code class="literal">*</code> for all
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polpermissive</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Is the policy permissive or restrictive?
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polroles</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The roles to which the policy is applied;
+ zero means <code class="literal">PUBLIC</code>
+ (and normally appears alone in the array)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polqual</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ The expression tree to be added to the security barrier qualifications for queries that use the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">polwithcheck</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ The expression tree to be added to the WITH CHECK qualifications for queries that attempt to add rows to the table
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ Policies stored in <code class="structname">pg_policy</code> are applied only when
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relrowsecurity</code> is set for
+ their table.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-proc.html" title="53.39. pg_proc">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.37. <code class="structname">pg_partitioned_table</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.39. <code class="structname">pg_proc</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-proc.html b/doc/src/sgml/html/catalog-pg-proc.html
new file mode 100644
index 0000000..795b98e
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-proc.html
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.39. pg_proc</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-policy.html" title="53.38. pg_policy" /><link rel="next" href="catalog-pg-publication.html" title="53.40. pg_publication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.39. <code class="structname">pg_proc</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-policy.html" title="53.38. pg_policy">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-publication.html" title="53.40. pg_publication">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-PROC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.39. <code class="structname">pg_proc</code></h2></div></div></div><a id="id-1.10.4.41.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_proc</code> stores information about
+ functions, procedures, aggregate functions, and window functions
+ (collectively also known as routines). See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a>, and
+ <a class="xref" href="xfunc.html" title="38.3. User-Defined Functions">Section 38.3</a> for more information.
+ </p><p>
+ If <code class="structfield">prokind</code> indicates that the entry is for an
+ aggregate function, there should be a matching row in
+ <a class="link" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate"><code class="structfield">pg_aggregate</code></a>.
+ </p><div class="table" id="id-1.10.4.41.5"><p class="title"><strong>Table 53.39. <code class="structname">pg_proc</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_proc Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pronamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prolang</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-language.html" title="53.29. pg_language"><code class="structname">pg_language</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Implementation language or call interface of this function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">procost</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Estimated execution cost (in units of
+ <a class="xref" href="runtime-config-query.html#GUC-CPU-OPERATOR-COST">cpu_operator_cost</a>); if <code class="structfield">proretset</code>,
+ this is cost per row returned
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prorows</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Estimated number of result rows (zero if not <code class="structfield">proretset</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">provariadic</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type of the variadic array parameter's elements,
+ or zero if the function does not have a variadic parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prosupport</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Planner support function for this function
+ (see <a class="xref" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Section 38.11</a>), or zero if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prokind</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="literal">f</code> for a normal function, <code class="literal">p</code>
+ for a procedure, <code class="literal">a</code> for an aggregate function, or
+ <code class="literal">w</code> for a window function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prosecdef</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Function is a security definer (i.e., a <span class="quote">“<span class="quote">setuid</span>”</span>
+ function)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proleakproof</code> <code class="type">bool</code>
+ </p>
+ <p>
+ The function has no side effects. No information about the
+ arguments is conveyed except via the return value. Any function
+ that might throw an error depending on the values of its arguments
+ is not leak-proof.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proisstrict</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Function returns null if any call argument is null. In that
+ case the function won't actually be called at all. Functions
+ that are not <span class="quote">“<span class="quote">strict</span>”</span> must be prepared to handle
+ null inputs.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proretset</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Function returns a set (i.e., multiple values of the specified
+ data type)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">provolatile</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="structfield">provolatile</code> tells whether the function's
+ result depends only on its input arguments, or is affected by outside
+ factors.
+ It is <code class="literal">i</code> for <span class="quote">“<span class="quote">immutable</span>”</span> functions,
+ which always deliver the same result for the same inputs.
+ It is <code class="literal">s</code> for <span class="quote">“<span class="quote">stable</span>”</span> functions,
+ whose results (for fixed inputs) do not change within a scan.
+ It is <code class="literal">v</code> for <span class="quote">“<span class="quote">volatile</span>”</span> functions,
+ whose results might change at any time. (Use <code class="literal">v</code> also
+ for functions with side-effects, so that calls to them cannot get
+ optimized away.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proparallel</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="structfield">proparallel</code> tells whether the function
+ can be safely run in parallel mode.
+ It is <code class="literal">s</code> for functions which are safe to run in
+ parallel mode without restriction.
+ It is <code class="literal">r</code> for functions which can be run in parallel
+ mode, but their execution is restricted to the parallel group leader;
+ parallel worker processes cannot invoke these functions.
+ It is <code class="literal">u</code> for functions which are unsafe in parallel
+ mode; the presence of such a function forces a serial execution plan.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pronargs</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Number of input arguments
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pronargdefaults</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Number of arguments that have defaults
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prorettype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type of the return value
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proargtypes</code> <code class="type">oidvector</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ An array of the data types of the function arguments. This includes
+ only input arguments (including <code class="literal">INOUT</code> and
+ <code class="literal">VARIADIC</code> arguments), and thus represents
+ the call signature of the function.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proallargtypes</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ An array of the data types of the function arguments. This includes
+ all arguments (including <code class="literal">OUT</code> and
+ <code class="literal">INOUT</code> arguments); however, if all the
+ arguments are <code class="literal">IN</code> arguments, this field will be null.
+ Note that subscripting is 1-based, whereas for historical reasons
+ <code class="structfield">proargtypes</code> is subscripted from 0.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proargmodes</code> <code class="type">char[]</code>
+ </p>
+ <p>
+ An array of the modes of the function arguments, encoded as
+ <code class="literal">i</code> for <code class="literal">IN</code> arguments,
+ <code class="literal">o</code> for <code class="literal">OUT</code> arguments,
+ <code class="literal">b</code> for <code class="literal">INOUT</code> arguments,
+ <code class="literal">v</code> for <code class="literal">VARIADIC</code> arguments,
+ <code class="literal">t</code> for <code class="literal">TABLE</code> arguments.
+ If all the arguments are <code class="literal">IN</code> arguments,
+ this field will be null.
+ Note that subscripts correspond to positions of
+ <code class="structfield">proallargtypes</code> not <code class="structfield">proargtypes</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proargnames</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ An array of the names of the function arguments.
+ Arguments without a name are set to empty strings in the array.
+ If none of the arguments have a name, this field will be null.
+ Note that subscripts correspond to positions of
+ <code class="structfield">proallargtypes</code> not <code class="structfield">proargtypes</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proargdefaults</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression trees (in <code class="function">nodeToString()</code> representation)
+ for default values. This is a list with
+ <code class="structfield">pronargdefaults</code> elements, corresponding to the last
+ <em class="replaceable"><code>N</code></em> <span class="emphasis"><em>input</em></span> arguments (i.e., the last
+ <em class="replaceable"><code>N</code></em> <code class="structfield">proargtypes</code> positions).
+ If none of the arguments have defaults, this field will be null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">protrftypes</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ An array of the argument/result data type(s) for which to apply
+ transforms (from the function's <code class="literal">TRANSFORM</code>
+ clause). Null if none.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prosrc</code> <code class="type">text</code>
+ </p>
+ <p>
+ This tells the function handler how to invoke the function. It
+ might be the actual source code of the function for interpreted
+ languages, a link symbol, a file name, or just about anything
+ else, depending on the implementation language/call convention.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">probin</code> <code class="type">text</code>
+ </p>
+ <p>
+ Additional information about how to invoke the function.
+ Again, the interpretation is language-specific.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prosqlbody</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Pre-parsed SQL function body. This is used for SQL-language
+ functions when the body is given in SQL-standard notation
+ rather than as a string literal. It's null in other cases.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proconfig</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Function's local settings for run-time configuration variables
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">proacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For compiled functions, both built-in and dynamically loaded,
+ <code class="structfield">prosrc</code> contains the function's C-language
+ name (link symbol).
+ For SQL-language functions, <code class="structfield">prosrc</code> contains
+ the function's source text if that is specified as a string literal;
+ but if the function body is specified in SQL-standard style,
+ <code class="structfield">prosrc</code> is unused (typically it's an empty
+ string) and <code class="structfield">prosqlbody</code> contains the
+ pre-parsed definition.
+ For all other currently-known language types,
+ <code class="structfield">prosrc</code> contains the function's source
+ text. <code class="structfield">probin</code> is null except for
+ dynamically-loaded C functions, for which it gives the name of the
+ shared library file containing the function.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-policy.html" title="53.38. pg_policy">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-publication.html" title="53.40. pg_publication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.38. <code class="structname">pg_policy</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.40. <code class="structname">pg_publication</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-publication-namespace.html b/doc/src/sgml/html/catalog-pg-publication-namespace.html
new file mode 100644
index 0000000..ec8b494
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-publication-namespace.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.41. pg_publication_namespace</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-publication.html" title="53.40. pg_publication" /><link rel="next" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.41. <code class="structname">pg_publication_namespace</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-publication.html" title="53.40. pg_publication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-PUBLICATION-NAMESPACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.41. <code class="structname">pg_publication_namespace</code></h2></div></div></div><a id="id-1.10.4.43.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_publication_namespace</code> contains the
+ mapping between schemas and publications in the database. This is a
+ many-to-many mapping.
+ </p><div class="table" id="id-1.10.4.43.4"><p class="title"><strong>Table 53.41. <code class="structname">pg_publication_namespace</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_publication_namespace Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pnpubid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-publication.html" title="53.40. pg_publication"><code class="structname">pg_publication</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Reference to publication
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pnnspid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Reference to schema
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-publication.html" title="53.40. pg_publication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.40. <code class="structname">pg_publication</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.42. <code class="structname">pg_publication_rel</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-publication-rel.html b/doc/src/sgml/html/catalog-pg-publication-rel.html
new file mode 100644
index 0000000..95a056a
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-publication-rel.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.42. pg_publication_rel</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace" /><link rel="next" href="catalog-pg-range.html" title="53.43. pg_range" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.42. <code class="structname">pg_publication_rel</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-range.html" title="53.43. pg_range">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-PUBLICATION-REL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.42. <code class="structname">pg_publication_rel</code></h2></div></div></div><a id="id-1.10.4.44.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_publication_rel</code> contains the
+ mapping between relations and publications in the database. This is a
+ many-to-many mapping. See also <a class="xref" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables">Section 54.17</a>
+ for a more user-friendly view of this information.
+ </p><div class="table" id="id-1.10.4.44.4"><p class="title"><strong>Table 53.42. <code class="structname">pg_publication_rel</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_publication_rel Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prpubid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-publication.html" title="53.40. pg_publication"><code class="structname">pg_publication</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Reference to publication
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Reference to relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prqual</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>Expression tree (in <code class="function">nodeToString()</code>
+ representation) for the relation's publication qualifying condition. Null
+ if there is no publication qualifying condition.</p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prattrs</code> <code class="type">int2vector</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ This is an array of values that indicates which table columns are
+ part of the publication. For example, a value of <code class="literal">1 3</code>
+ would mean that the first and the third table columns are published.
+ A null value indicates that all columns are published.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-range.html" title="53.43. pg_range">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.41. <code class="structname">pg_publication_namespace</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.43. <code class="structname">pg_range</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-publication.html b/doc/src/sgml/html/catalog-pg-publication.html
new file mode 100644
index 0000000..bdec337
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-publication.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.40. pg_publication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-proc.html" title="53.39. pg_proc" /><link rel="next" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.40. <code class="structname">pg_publication</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-proc.html" title="53.39. pg_proc">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-PUBLICATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.40. <code class="structname">pg_publication</code></h2></div></div></div><a id="id-1.10.4.42.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_publication</code> contains all
+ publications created in the database. For more on publications see
+ <a class="xref" href="logical-replication-publication.html" title="31.1. Publication">Section 31.1</a>.
+ </p><div class="table" id="id-1.10.4.42.4"><p class="title"><strong>Table 53.40. <code class="structname">pg_publication</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_publication Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the publication
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the publication
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">puballtables</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, this publication automatically includes all tables
+ in the database, including any that will be created in the future.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubinsert</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a> operations are replicated for
+ tables in the publication.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubupdate</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, <a class="xref" href="sql-update.html" title="UPDATE"><span class="refentrytitle">UPDATE</span></a> operations are replicated for
+ tables in the publication.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubdelete</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, <a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a> operations are replicated for
+ tables in the publication.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubtruncate</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> operations are replicated for
+ tables in the publication.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubviaroot</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, operations on a leaf partition are replicated using the
+ identity and schema of its topmost partitioned ancestor mentioned in the
+ publication instead of its own.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-proc.html" title="53.39. pg_proc">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.39. <code class="structname">pg_proc</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.41. <code class="structname">pg_publication_namespace</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-range.html b/doc/src/sgml/html/catalog-pg-range.html
new file mode 100644
index 0000000..1f8e651
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-range.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.43. pg_range</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel" /><link rel="next" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.43. <code class="structname">pg_range</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-RANGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.43. <code class="structname">pg_range</code></h2></div></div></div><a id="id-1.10.4.45.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_range</code> stores information about
+ range types. This is in addition to the types' entries in
+ <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.
+ </p><div class="table" id="id-1.10.4.45.4"><p class="title"><strong>Table 53.43. <code class="structname">pg_range</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_range Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngtypid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the range type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngsubtype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the element type (subtype) of this range type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngmultitypid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the multirange type for this range type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngcollation</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the collation used for range comparisons, or zero if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngsubopc</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the subtype's operator class used for range comparisons
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngcanonical</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the function to convert a range value into canonical form,
+ or zero if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rngsubdiff</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the function to return the difference between two element
+ values as <code class="type">double precision</code>, or zero if none
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="structfield">rngsubopc</code> (plus <code class="structfield">rngcollation</code>, if the
+ element type is collatable) determines the sort ordering used by the range
+ type. <code class="structfield">rngcanonical</code> is used when the element type is
+ discrete. <code class="structfield">rngsubdiff</code> is optional but should be supplied to
+ improve performance of GiST indexes on the range type.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.42. <code class="structname">pg_publication_rel</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.44. <code class="structname">pg_replication_origin</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-replication-origin.html b/doc/src/sgml/html/catalog-pg-replication-origin.html
new file mode 100644
index 0000000..9ba1b94
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-replication-origin.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.44. pg_replication_origin</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-range.html" title="53.43. pg_range" /><link rel="next" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.44. <code class="structname">pg_replication_origin</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-range.html" title="53.43. pg_range">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-REPLICATION-ORIGIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.44. <code class="structname">pg_replication_origin</code></h2></div></div></div><a id="id-1.10.4.46.2" class="indexterm"></a><p>
+ The <code class="structname">pg_replication_origin</code> catalog contains
+ all replication origins created. For more on replication origins
+ see <a class="xref" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Chapter 50</a>.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_replication_origin</code>
+ is shared across all databases of a cluster: there is only one copy
+ of <code class="structname">pg_replication_origin</code> per cluster, not one per
+ database.
+ </p><div class="table" id="id-1.10.4.46.5"><p class="title"><strong>Table 53.44. <code class="structname">pg_replication_origin</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_replication_origin Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">roident</code> <code class="type">oid</code>
+ </p>
+ <p>
+ A unique, cluster-wide identifier for the replication
+ origin. Should never leave the system.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">roname</code> <code class="type">text</code>
+ </p>
+ <p>
+ The external, user defined, name of a replication
+ origin.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-range.html" title="53.43. pg_range">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.43. <code class="structname">pg_range</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.45. <code class="structname">pg_rewrite</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-rewrite.html b/doc/src/sgml/html/catalog-pg-rewrite.html
new file mode 100644
index 0000000..60f33f5
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-rewrite.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.45. pg_rewrite</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin" /><link rel="next" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.45. <code class="structname">pg_rewrite</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-REWRITE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.45. <code class="structname">pg_rewrite</code></h2></div></div></div><a id="id-1.10.4.47.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_rewrite</code> stores rewrite rules for tables and views.
+ </p><div class="table" id="id-1.10.4.47.4"><p class="title"><strong>Table 53.45. <code class="structname">pg_rewrite</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_rewrite Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rulename</code> <code class="type">name</code>
+ </p>
+ <p>
+ Rule name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ev_class</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table this rule is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ev_type</code> <code class="type">char</code>
+ </p>
+ <p>
+ Event type that the rule is for: 1 = <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>, 2 =
+ <a class="xref" href="sql-update.html" title="UPDATE"><span class="refentrytitle">UPDATE</span></a>, 3 = <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>, 4 =
+ <a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ev_enabled</code> <code class="type">char</code>
+ </p>
+ <p>
+ Controls in which <a class="xref" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE">session_replication_role</a> modes
+ the rule fires.
+ <code class="literal">O</code> = rule fires in <span class="quote">“<span class="quote">origin</span>”</span> and <span class="quote">“<span class="quote">local</span>”</span> modes,
+ <code class="literal">D</code> = rule is disabled,
+ <code class="literal">R</code> = rule fires in <span class="quote">“<span class="quote">replica</span>”</span> mode,
+ <code class="literal">A</code> = rule fires always.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_instead</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the rule is an <code class="literal">INSTEAD</code> rule
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ev_qual</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression tree (in the form of a
+ <code class="function">nodeToString()</code> representation) for the
+ rule's qualifying condition
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ev_action</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Query tree (in the form of a
+ <code class="function">nodeToString()</code> representation) for the
+ rule's action
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">pg_class.relhasrules</code>
+ must be true if a table has any rules in this catalog.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.44. <code class="structname">pg_replication_origin</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.46. <code class="structname">pg_seclabel</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-seclabel.html b/doc/src/sgml/html/catalog-pg-seclabel.html
new file mode 100644
index 0000000..959c238
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-seclabel.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.46. pg_seclabel</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite" /><link rel="next" href="catalog-pg-sequence.html" title="53.47. pg_sequence" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.46. <code class="structname">pg_seclabel</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-sequence.html" title="53.47. pg_sequence">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SECLABEL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.46. <code class="structname">pg_seclabel</code></h2></div></div></div><a id="id-1.10.4.48.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_seclabel</code> stores security
+ labels on database objects. Security labels can be manipulated
+ with the <a class="link" href="sql-security-label.html" title="SECURITY LABEL"><code class="command">SECURITY LABEL</code></a> command. For an easier
+ way to view security labels, see <a class="xref" href="view-pg-seclabels.html" title="54.22. pg_seclabels">Section 54.22</a>.
+ </p><p>
+ See also <a class="link" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel"><code class="structname">pg_shseclabel</code></a>,
+ which performs a similar function for security labels of database objects
+ that are shared across a database cluster.
+ </p><div class="table" id="id-1.10.4.48.5"><p class="title"><strong>Table 53.46. <code class="structname">pg_seclabel</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_seclabel Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objoid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the object this security label pertains to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog this object appears in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a security label on a table column, this is the column number (the
+ <code class="structfield">objoid</code> and <code class="structfield">classoid</code> refer to
+ the table itself). For all other object types, this column is
+ zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">provider</code> <code class="type">text</code>
+ </p>
+ <p>
+ The label provider associated with this label.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">label</code> <code class="type">text</code>
+ </p>
+ <p>
+ The security label applied to this object.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-sequence.html" title="53.47. pg_sequence">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.45. <code class="structname">pg_rewrite</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.47. <code class="structname">pg_sequence</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-sequence.html b/doc/src/sgml/html/catalog-pg-sequence.html
new file mode 100644
index 0000000..45a1f2e
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-sequence.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.47. pg_sequence</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel" /><link rel="next" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.47. <code class="structname">pg_sequence</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SEQUENCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.47. <code class="structname">pg_sequence</code></h2></div></div></div><a id="id-1.10.4.49.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_sequence</code> contains information about
+ sequences. Some of the information about sequences, such as the name and
+ the schema, is in
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>
+ </p><div class="table" id="id-1.10.4.49.4"><p class="title"><strong>Table 53.47. <code class="structname">pg_sequence</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_sequence Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry for this sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqtypid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqstart</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Start value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqincrement</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Increment value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqmax</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Maximum value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqmin</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Minimum value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqcache</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Cache size of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqcycle</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Whether the sequence cycles
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.46. <code class="structname">pg_seclabel</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.48. <code class="structname">pg_shdepend</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-shdepend.html b/doc/src/sgml/html/catalog-pg-shdepend.html
new file mode 100644
index 0000000..e781f1c
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-shdepend.html
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.48. pg_shdepend</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-sequence.html" title="53.47. pg_sequence" /><link rel="next" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.48. <code class="structname">pg_shdepend</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-sequence.html" title="53.47. pg_sequence">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SHDEPEND"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.48. <code class="structname">pg_shdepend</code></h2></div></div></div><a id="id-1.10.4.50.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_shdepend</code> records the
+ dependency relationships between database objects and shared objects,
+ such as roles. This information allows
+ <span class="productname">PostgreSQL</span> to ensure that those objects are
+ unreferenced before attempting to delete them.
+ </p><p>
+ See also <a class="link" href="catalog-pg-depend.html" title="53.18. pg_depend"><code class="structname">pg_depend</code></a>,
+ which performs a similar function for dependencies involving objects
+ within a single database.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_shdepend</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_shdepend</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.50.6"><p class="title"><strong>Table 53.48. <code class="structname">pg_shdepend</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_shdepend Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dbid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the database the dependent object is in,
+ or zero for a shared object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog the dependent object is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the specific dependent object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a table column, this is the column number (the
+ <code class="structfield">objid</code> and <code class="structfield">classid</code> refer to the
+ table itself). For all other object types, this column is zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">refclassid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog the referenced object is in
+ (must be a shared catalog)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">refobjid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the specific referenced object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">deptype</code> <code class="type">char</code>
+ </p>
+ <p>
+ A code defining the specific semantics of this dependency relationship; see text
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In all cases, a <code class="structname">pg_shdepend</code> entry indicates that
+ the referenced object cannot be dropped without also dropping the dependent
+ object. However, there are several subflavors identified by
+ <code class="structfield">deptype</code>:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SHARED_DEPENDENCY_OWNER</code> (<code class="literal">o</code>)</span></dt><dd><p>
+ The referenced object (which must be a role) is the owner of the
+ dependent object.
+ </p></dd><dt><span class="term"><code class="symbol">SHARED_DEPENDENCY_ACL</code> (<code class="literal">a</code>)</span></dt><dd><p>
+ The referenced object (which must be a role) is mentioned in the
+ ACL (access control list, i.e., privileges list) of the
+ dependent object. (A <code class="symbol">SHARED_DEPENDENCY_ACL</code> entry is
+ not made for the owner of the object, since the owner will have
+ a <code class="symbol">SHARED_DEPENDENCY_OWNER</code> entry anyway.)
+ </p></dd><dt><span class="term"><code class="symbol">SHARED_DEPENDENCY_POLICY</code> (<code class="literal">r</code>)</span></dt><dd><p>
+ The referenced object (which must be a role) is mentioned as the
+ target of a dependent policy object.
+ </p></dd><dt><span class="term"><code class="symbol">SHARED_DEPENDENCY_TABLESPACE</code> (<code class="literal">t</code>)</span></dt><dd><p>
+ The referenced object (which must be a tablespace) is mentioned as
+ the tablespace for a relation that doesn't have storage.
+ </p></dd></dl></div><p>
+
+ Other dependency flavors might be needed in future. Note in particular
+ that the current definition only supports roles and tablespaces as referenced
+ objects.
+ </p><p>
+ As in the <code class="structname">pg_depend</code> catalog, most objects
+ created during <span class="application">initdb</span> are
+ considered <span class="quote">“<span class="quote">pinned</span>”</span>. No entries are made
+ in <code class="structname">pg_shdepend</code> that would have a pinned
+ object as either referenced or dependent object.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-sequence.html" title="53.47. pg_sequence">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.47. <code class="structname">pg_sequence</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.49. <code class="structname">pg_shdescription</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-shdescription.html b/doc/src/sgml/html/catalog-pg-shdescription.html
new file mode 100644
index 0000000..c066686
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-shdescription.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.49. pg_shdescription</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend" /><link rel="next" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.49. <code class="structname">pg_shdescription</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SHDESCRIPTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.49. <code class="structname">pg_shdescription</code></h2></div></div></div><a id="id-1.10.4.51.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_shdescription</code> stores optional
+ descriptions (comments) for shared database objects. Descriptions can be
+ manipulated with the <a class="link" href="sql-comment.html" title="COMMENT"><code class="command">COMMENT</code></a> command and viewed with
+ <span class="application">psql</span>'s <code class="literal">\d</code> commands.
+ </p><p>
+ See also <a class="link" href="catalog-pg-description.html" title="53.19. pg_description"><code class="structname">pg_description</code></a>,
+ which performs a similar function for descriptions involving objects
+ within a single database.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_shdescription</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_shdescription</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.51.6"><p class="title"><strong>Table 53.49. <code class="structname">pg_shdescription</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_shdescription Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objoid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the object this description pertains to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog this object appears in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">description</code> <code class="type">text</code>
+ </p>
+ <p>
+ Arbitrary text that serves as the description of this object
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.48. <code class="structname">pg_shdepend</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.50. <code class="structname">pg_shseclabel</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-shseclabel.html b/doc/src/sgml/html/catalog-pg-shseclabel.html
new file mode 100644
index 0000000..3f45650
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-shseclabel.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.50. pg_shseclabel</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription" /><link rel="next" href="catalog-pg-statistic.html" title="53.51. pg_statistic" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.50. <code class="structname">pg_shseclabel</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-statistic.html" title="53.51. pg_statistic">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SHSECLABEL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.50. <code class="structname">pg_shseclabel</code></h2></div></div></div><a id="id-1.10.4.52.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_shseclabel</code> stores security
+ labels on shared database objects. Security labels can be manipulated
+ with the <a class="link" href="sql-security-label.html" title="SECURITY LABEL"><code class="command">SECURITY LABEL</code></a> command. For an easier
+ way to view security labels, see <a class="xref" href="view-pg-seclabels.html" title="54.22. pg_seclabels">Section 54.22</a>.
+ </p><p>
+ See also <a class="link" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel"><code class="structname">pg_seclabel</code></a>,
+ which performs a similar function for security labels involving objects
+ within a single database.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_shseclabel</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_shseclabel</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.52.6"><p class="title"><strong>Table 53.50. <code class="structname">pg_shseclabel</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_shseclabel Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objoid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the object this security label pertains to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog this object appears in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">provider</code> <code class="type">text</code>
+ </p>
+ <p>
+ The label provider associated with this label.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">label</code> <code class="type">text</code>
+ </p>
+ <p>
+ The security label applied to this object.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-statistic.html" title="53.51. pg_statistic">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.49. <code class="structname">pg_shdescription</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.51. <code class="structname">pg_statistic</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-statistic-ext-data.html b/doc/src/sgml/html/catalog-pg-statistic-ext-data.html
new file mode 100644
index 0000000..8db7359
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-statistic-ext-data.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.53. pg_statistic_ext_data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext" /><link rel="next" href="catalog-pg-subscription.html" title="53.54. pg_subscription" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.53. <code class="structname">pg_statistic_ext_data</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-subscription.html" title="53.54. pg_subscription">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-STATISTIC-EXT-DATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.53. <code class="structname">pg_statistic_ext_data</code></h2></div></div></div><a id="id-1.10.4.55.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_statistic_ext_data</code>
+ holds data for extended planner statistics defined in
+ <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>.
+ Each row in this catalog corresponds to a <em class="firstterm">statistics object</em>
+ created with <a class="link" href="sql-createstatistics.html" title="CREATE STATISTICS"><code class="command">CREATE STATISTICS</code></a>.
+ </p><p>
+ Normally there is one entry, with <code class="structfield">stxdinherit</code> =
+ <code class="literal">false</code>, for each statistics object that has been analyzed.
+ If the table has inheritance children or partitions, a second entry with
+ <code class="structfield">stxdinherit</code> = <code class="literal">true</code> is also created.
+ This row represents the statistics object over the inheritance tree, i.e.,
+ statistics for the data you'd see with
+ <code class="literal">SELECT * FROM <em class="replaceable"><code>table</code></em>*</code>,
+ whereas the <code class="structfield">stxdinherit</code> = <code class="literal">false</code> row
+ represents the results of
+ <code class="literal">SELECT * FROM ONLY <em class="replaceable"><code>table</code></em></code>.
+ </p><p>
+ Like <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a>,
+ <code class="structname">pg_statistic_ext_data</code> should not be
+ readable by the public, since the contents might be considered sensitive.
+ (Example: most common combinations of values in columns might be quite
+ interesting.)
+ <a class="link" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext"><code class="structname">pg_stats_ext</code></a>
+ is a publicly readable view
+ on <code class="structname">pg_statistic_ext_data</code> (after joining
+ with <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>) that only exposes
+ information about those tables and columns that are readable by the
+ current user.
+ </p><div class="table" id="id-1.10.4.55.6"><p class="title"><strong>Table 53.53. <code class="structname">pg_statistic_ext_data</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_statistic_ext_data Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Extended statistics object containing the definition for this data
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxdinherit</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxdndistinct</code> <code class="type">pg_ndistinct</code>
+ </p>
+ <p>
+ N-distinct counts, serialized as <code class="structname">pg_ndistinct</code> type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxddependencies</code> <code class="type">pg_dependencies</code>
+ </p>
+ <p>
+ Functional dependency statistics, serialized
+ as <code class="structname">pg_dependencies</code> type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxdmcv</code> <code class="type">pg_mcv_list</code>
+ </p>
+ <p>
+ MCV (most-common values) list statistics, serialized as
+ <code class="structname">pg_mcv_list</code> type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxdexpr</code> <code class="type">pg_statistic[]</code>
+ </p>
+ <p>
+ Per-expression statistics, serialized as an array of
+ <code class="structname">pg_statistic</code> type
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-subscription.html" title="53.54. pg_subscription">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.52. <code class="structname">pg_statistic_ext</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.54. <code class="structname">pg_subscription</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-statistic-ext.html b/doc/src/sgml/html/catalog-pg-statistic-ext.html
new file mode 100644
index 0000000..1d5c062
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-statistic-ext.html
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.52. pg_statistic_ext</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-statistic.html" title="53.51. pg_statistic" /><link rel="next" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.52. <code class="structname">pg_statistic_ext</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-statistic.html" title="53.51. pg_statistic">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-STATISTIC-EXT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.52. <code class="structname">pg_statistic_ext</code></h2></div></div></div><a id="id-1.10.4.54.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_statistic_ext</code>
+ holds definitions of extended planner statistics.
+ Each row in this catalog corresponds to a <em class="firstterm">statistics object</em>
+ created with <a class="link" href="sql-createstatistics.html" title="CREATE STATISTICS"><code class="command">CREATE STATISTICS</code></a>.
+ </p><div class="table" id="id-1.10.4.54.4"><p class="title"><strong>Table 53.52. <code class="structname">pg_statistic_ext</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_statistic_ext Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Table containing the columns described by this object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxstattarget</code> <code class="type">int4</code>
+ </p>
+ <p>
+ <code class="structfield">stxstattarget</code> controls the level of detail
+ of statistics accumulated for this statistics object by
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>.
+ A zero value indicates that no statistics should be collected.
+ A negative value says to use the maximum of the statistics targets of
+ the referenced columns, if set, or the system default statistics target.
+ Positive values of <code class="structfield">stxstattarget</code>
+ determine the target number of <span class="quote">“<span class="quote">most common values</span>”</span>
+ to collect.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxkeys</code> <code class="type">int2vector</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ An array of attribute numbers, indicating which table columns are
+ covered by this statistics object;
+ for example a value of <code class="literal">1 3</code> would
+ mean that the first and the third table columns are covered
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxkind</code> <code class="type">char[]</code>
+ </p>
+ <p>
+ An array containing codes for the enabled statistics kinds;
+ valid values are:
+ <code class="literal">d</code> for n-distinct statistics,
+ <code class="literal">f</code> for functional dependency statistics,
+ <code class="literal">m</code> for most common values (MCV) list statistics, and
+ <code class="literal">e</code> for expression statistics
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stxexprs</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression trees (in <code class="function">nodeToString()</code>
+ representation) for statistics object attributes that are not simple
+ column references. This is a list with one element per expression.
+ Null if all statistics object attributes are simple references.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="structname">pg_statistic_ext</code> entry is filled in
+ completely during <a class="link" href="sql-createstatistics.html" title="CREATE STATISTICS"><code class="command">CREATE STATISTICS</code></a>, but the actual
+ statistical values are not computed then.
+ Subsequent <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> commands compute the desired values
+ and populate an entry in the
+ <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>
+ catalog.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-statistic.html" title="53.51. pg_statistic">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.51. <code class="structname">pg_statistic</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.53. <code class="structname">pg_statistic_ext_data</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-statistic.html b/doc/src/sgml/html/catalog-pg-statistic.html
new file mode 100644
index 0000000..b10e265
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-statistic.html
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.51. pg_statistic</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel" /><link rel="next" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.51. <code class="structname">pg_statistic</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-STATISTIC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.51. <code class="structname">pg_statistic</code></h2></div></div></div><a id="id-1.10.4.53.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_statistic</code> stores
+ statistical data about the contents of the database. Entries are
+ created by <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>
+ and subsequently used by the query planner. Note that all the
+ statistical data is inherently approximate, even assuming that it
+ is up-to-date.
+ </p><p>
+ Normally there is one entry, with <code class="structfield">stainherit</code> =
+ <code class="literal">false</code>, for each table column that has been analyzed.
+ If the table has inheritance children or partitions, a second entry with
+ <code class="structfield">stainherit</code> = <code class="literal">true</code> is also created. This row
+ represents the column's statistics over the inheritance tree, i.e.,
+ statistics for the data you'd see with
+ <code class="literal">SELECT <em class="replaceable"><code>column</code></em> FROM <em class="replaceable"><code>table</code></em>*</code>,
+ whereas the <code class="structfield">stainherit</code> = <code class="literal">false</code> row represents
+ the results of
+ <code class="literal">SELECT <em class="replaceable"><code>column</code></em> FROM ONLY <em class="replaceable"><code>table</code></em></code>.
+ </p><p>
+ <code class="structname">pg_statistic</code> also stores statistical data about
+ the values of index expressions. These are described as if they were
+ actual data columns; in particular, <code class="structfield">starelid</code>
+ references the index. No entry is made for an ordinary non-expression
+ index column, however, since it would be redundant with the entry
+ for the underlying table column. Currently, entries for index expressions
+ always have <code class="structfield">stainherit</code> = <code class="literal">false</code>.
+ </p><p>
+ Since different kinds of statistics might be appropriate for different
+ kinds of data, <code class="structname">pg_statistic</code> is designed not
+ to assume very much about what sort of statistics it stores. Only
+ extremely general statistics (such as nullness) are given dedicated
+ columns in <code class="structname">pg_statistic</code>. Everything else
+ is stored in <span class="quote">“<span class="quote">slots</span>”</span>, which are groups of associated columns
+ whose content is identified by a code number in one of the slot's columns.
+ For more information see
+ <code class="filename">src/include/catalog/pg_statistic.h</code>.
+ </p><p>
+ <code class="structname">pg_statistic</code> should not be readable by the
+ public, since even statistical information about a table's contents
+ might be considered sensitive. (Example: minimum and maximum values
+ of a salary column might be quite interesting.)
+ <a class="link" href="view-pg-stats.html" title="54.27. pg_stats"><code class="structname">pg_stats</code></a>
+ is a publicly readable view on
+ <code class="structname">pg_statistic</code> that only exposes information
+ about those tables that are readable by the current user.
+ </p><div class="table" id="id-1.10.4.53.8"><p class="title"><strong>Table 53.51. <code class="structname">pg_statistic</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_statistic Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">starelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table or index that the described column belongs to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">staattnum</code> <code class="type">int2</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ The number of the described column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stainherit</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stanullfrac</code> <code class="type">float4</code>
+ </p>
+ <p>
+ The fraction of the column's entries that are null
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stawidth</code> <code class="type">int4</code>
+ </p>
+ <p>
+ The average stored width, in bytes, of nonnull entries
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stadistinct</code> <code class="type">float4</code>
+ </p>
+ <p>
+ The number of distinct nonnull data values in the column.
+ A value greater than zero is the actual number of distinct values.
+ A value less than zero is the negative of a multiplier for the number
+ of rows in the table; for example, a column in which about 80% of the
+ values are nonnull and each nonnull value appears about twice on
+ average could be represented by <code class="structfield">stadistinct</code> = -0.4.
+ A zero value means the number of distinct values is unknown.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stakind<em class="replaceable"><code>N</code></em></code> <code class="type">int2</code>
+ </p>
+ <p>
+ A code number indicating the kind of statistics stored in the
+ <em class="replaceable"><code>N</code></em>th <span class="quote">“<span class="quote">slot</span>”</span> of the
+ <code class="structname">pg_statistic</code> row.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">staop<em class="replaceable"><code>N</code></em></code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ An operator used to derive the statistics stored in the
+ <em class="replaceable"><code>N</code></em>th <span class="quote">“<span class="quote">slot</span>”</span>. For example, a
+ histogram slot would show the <code class="literal">&lt;</code> operator
+ that defines the sort order of the data.
+ Zero if the statistics kind does not require an operator.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stacoll<em class="replaceable"><code>N</code></em></code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The collation used to derive the statistics stored in the
+ <em class="replaceable"><code>N</code></em>th <span class="quote">“<span class="quote">slot</span>”</span>. For example, a
+ histogram slot for a collatable column would show the collation that
+ defines the sort order of the data. Zero for noncollatable data.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stanumbers<em class="replaceable"><code>N</code></em></code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ Numerical statistics of the appropriate kind for the
+ <em class="replaceable"><code>N</code></em>th <span class="quote">“<span class="quote">slot</span>”</span>, or null if the slot
+ kind does not involve numerical values
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stavalues<em class="replaceable"><code>N</code></em></code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ Column data values of the appropriate kind for the
+ <em class="replaceable"><code>N</code></em>th <span class="quote">“<span class="quote">slot</span>”</span>, or null if the slot
+ kind does not store any data values. Each array's element
+ values are actually of the specific column's data type, or a related
+ type such as an array's element type, so there is no way to define
+ these columns' type more specifically than <code class="type">anyarray</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.50. <code class="structname">pg_shseclabel</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.52. <code class="structname">pg_statistic_ext</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-subscription-rel.html b/doc/src/sgml/html/catalog-pg-subscription-rel.html
new file mode 100644
index 0000000..bfffb25
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-subscription-rel.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.55. pg_subscription_rel</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-subscription.html" title="53.54. pg_subscription" /><link rel="next" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.55. <code class="structname">pg_subscription_rel</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-subscription.html" title="53.54. pg_subscription">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SUBSCRIPTION-REL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.55. <code class="structname">pg_subscription_rel</code></h2></div></div></div><a id="id-1.10.4.57.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_subscription_rel</code> contains the
+ state for each replicated relation in each subscription. This is a
+ many-to-many mapping.
+ </p><p>
+ This catalog only contains tables known to the subscription after running
+ either <a class="link" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><code class="command">CREATE SUBSCRIPTION</code></a> or
+ <a class="link" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><code class="command">ALTER SUBSCRIPTION ... REFRESH
+ PUBLICATION</code></a>.
+ </p><div class="table" id="id-1.10.4.57.5"><p class="title"><strong>Table 53.55. <code class="structname">pg_subscription_rel</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_subscription_rel Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srsubid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-subscription.html" title="53.54. pg_subscription"><code class="structname">pg_subscription</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Reference to subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Reference to relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srsubstate</code> <code class="type">char</code>
+ </p>
+ <p>
+ State code:
+ <code class="literal">i</code> = initialize,
+ <code class="literal">d</code> = data is being copied,
+ <code class="literal">f</code> = finished table copy,
+ <code class="literal">s</code> = synchronized,
+ <code class="literal">r</code> = ready (normal replication)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srsublsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Remote LSN of the state change used for synchronization coordination
+ when in <code class="literal">s</code> or <code class="literal">r</code> states,
+ otherwise null
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-subscription.html" title="53.54. pg_subscription">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.54. <code class="structname">pg_subscription</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.56. <code class="structname">pg_tablespace</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-subscription.html b/doc/src/sgml/html/catalog-pg-subscription.html
new file mode 100644
index 0000000..79e4048
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-subscription.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.54. pg_subscription</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data" /><link rel="next" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.54. <code class="structname">pg_subscription</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-SUBSCRIPTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.54. <code class="structname">pg_subscription</code></h2></div></div></div><a id="id-1.10.4.56.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_subscription</code> contains all existing
+ logical replication subscriptions. For more information about logical
+ replication see <a class="xref" href="logical-replication.html" title="Chapter 31. Logical Replication">Chapter 31</a>.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_subscription</code> is
+ shared across all databases of a cluster: there is only one copy
+ of <code class="structname">pg_subscription</code> per cluster, not one per
+ database.
+ </p><p>
+ Access to the column <code class="structfield">subconninfo</code> is revoked from
+ normal users, because it could contain plain-text passwords.
+ </p><div class="table" id="id-1.10.4.56.6"><p class="title"><strong>Table 53.54. <code class="structname">pg_subscription</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_subscription Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subdbid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the database that the subscription resides in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subskiplsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Finish LSN of the transaction whose changes are to be skipped, if a valid
+ LSN; otherwise <code class="literal">0/0</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subenabled</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the subscription is enabled and should be replicating
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subbinary</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the subscription will request that the publisher send data
+ in binary format
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">substream</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the subscription will allow streaming of in-progress
+ transactions
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subtwophasestate</code> <code class="type">char</code>
+ </p>
+ <p>
+ State codes for two-phase mode:
+ <code class="literal">d</code> = disabled,
+ <code class="literal">p</code> = pending enablement,
+ <code class="literal">e</code> = enabled
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subdisableonerr</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, the subscription will be disabled if one of its workers
+ detects an error
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subconninfo</code> <code class="type">text</code>
+ </p>
+ <p>
+ Connection string to the upstream database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subslotname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the replication slot in the upstream database (also used
+ for the local replication origin name);
+ null represents <code class="literal">NONE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subsynccommit</code> <code class="type">text</code>
+ </p>
+ <p>
+ The <code class="varname">synchronous_commit</code>
+ setting for the subscription's workers to use
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subpublications</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Array of subscribed publication names. These reference
+ publications defined in the upstream database. For more on publications
+ see <a class="xref" href="logical-replication-publication.html" title="31.1. Publication">Section 31.1</a>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.53. <code class="structname">pg_statistic_ext_data</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.55. <code class="structname">pg_subscription_rel</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-tablespace.html b/doc/src/sgml/html/catalog-pg-tablespace.html
new file mode 100644
index 0000000..20cc43b
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-tablespace.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.56. pg_tablespace</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel" /><link rel="next" href="catalog-pg-transform.html" title="53.57. pg_transform" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.56. <code class="structname">pg_tablespace</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-transform.html" title="53.57. pg_transform">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TABLESPACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.56. <code class="structname">pg_tablespace</code></h2></div></div></div><a id="id-1.10.4.58.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_tablespace</code> stores information
+ about the available tablespaces. Tables can be placed in particular
+ tablespaces to aid administration of disk layout.
+ </p><p>
+ Unlike most system catalogs, <code class="structname">pg_tablespace</code>
+ is shared across all databases of a cluster: there is only one
+ copy of <code class="structname">pg_tablespace</code> per cluster, not
+ one per database.
+ </p><div class="table" id="id-1.10.4.58.5"><p class="title"><strong>Table 53.56. <code class="structname">pg_tablespace</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_tablespace Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spcname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Tablespace name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spcowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the tablespace, usually the user who created it
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spcacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spcoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Tablespace-level options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-transform.html" title="53.57. pg_transform">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.55. <code class="structname">pg_subscription_rel</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.57. <code class="structname">pg_transform</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-transform.html b/doc/src/sgml/html/catalog-pg-transform.html
new file mode 100644
index 0000000..83cca18
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-transform.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.57. pg_transform</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace" /><link rel="next" href="catalog-pg-trigger.html" title="53.58. pg_trigger" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.57. <code class="structname">pg_transform</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-trigger.html" title="53.58. pg_trigger">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TRANSFORM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.57. <code class="structname">pg_transform</code></h2></div></div></div><a id="id-1.10.4.59.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_transform</code> stores information about
+ transforms, which are a mechanism to adapt data types to procedural
+ languages. See <a class="xref" href="sql-createtransform.html" title="CREATE TRANSFORM"><span class="refentrytitle">CREATE TRANSFORM</span></a> for more information.
+ </p><div class="table" id="id-1.10.4.59.4"><p class="title"><strong>Table 53.57. <code class="structname">pg_transform</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_transform Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trftype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the data type this transform is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trflang</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-language.html" title="53.29. pg_language"><code class="structname">pg_language</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the language this transform is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trffromsql</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the function to use when converting the data type for input
+ to the procedural language (e.g., function parameters). Zero is stored
+ if the default behavior should be used.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trftosql</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the function to use when converting output from the
+ procedural language (e.g., return values) to the data type. Zero is
+ stored if the default behavior should be used.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-trigger.html" title="53.58. pg_trigger">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.56. <code class="structname">pg_tablespace</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.58. <code class="structname">pg_trigger</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-trigger.html b/doc/src/sgml/html/catalog-pg-trigger.html
new file mode 100644
index 0000000..375e1fe
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-trigger.html
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.58. pg_trigger</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-transform.html" title="53.57. pg_transform" /><link rel="next" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.58. <code class="structname">pg_trigger</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-transform.html" title="53.57. pg_transform">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.58. <code class="structname">pg_trigger</code></h2></div></div></div><a id="id-1.10.4.60.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_trigger</code> stores triggers on tables
+ and views.
+ See <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>
+ for more information.
+ </p><div class="table" id="id-1.10.4.60.4"><p class="title"><strong>Table 53.58. <code class="structname">pg_trigger</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_trigger Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table this trigger is on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgparentid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-trigger.html" title="53.58. pg_trigger"><code class="structname">pg_trigger</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Parent trigger that this trigger is cloned from (this happens when
+ partitions are created or attached to a partitioned table);
+ zero if not a clone
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Trigger name (must be unique among triggers of same table)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgfoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The function to be called
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgtype</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Bit mask identifying trigger firing conditions
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgenabled</code> <code class="type">char</code>
+ </p>
+ <p>
+ Controls in which <a class="xref" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE">session_replication_role</a> modes
+ the trigger fires.
+ <code class="literal">O</code> = trigger fires in <span class="quote">“<span class="quote">origin</span>”</span> and <span class="quote">“<span class="quote">local</span>”</span> modes,
+ <code class="literal">D</code> = trigger is disabled,
+ <code class="literal">R</code> = trigger fires in <span class="quote">“<span class="quote">replica</span>”</span> mode,
+ <code class="literal">A</code> = trigger fires always.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgisinternal</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if trigger is internally generated (usually, to enforce
+ the constraint identified by <code class="structfield">tgconstraint</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgconstrrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The table referenced by a referential integrity constraint
+ (zero if trigger is not for a referential integrity constraint)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgconstrindid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The index supporting a unique, primary key, referential integrity,
+ or exclusion constraint
+ (zero if trigger is not for one of these types of constraint)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgconstraint</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-constraint.html" title="53.13. pg_constraint"><code class="structname">pg_constraint</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The <a class="link" href="catalog-pg-constraint.html" title="53.13. pg_constraint"><code class="structname">pg_constraint</code></a> entry associated with the trigger
+ (zero if trigger is not for a constraint)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgdeferrable</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if constraint trigger is deferrable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tginitdeferred</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if constraint trigger is initially deferred
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgnargs</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Number of argument strings passed to trigger function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgattr</code> <code class="type">int2vector</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attnum</code>)
+ </p>
+ <p>
+ Column numbers, if trigger is column-specific; otherwise an
+ empty array
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgargs</code> <code class="type">bytea</code>
+ </p>
+ <p>
+ Argument strings to pass to trigger, each NULL-terminated
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgqual</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ Expression tree (in <code class="function">nodeToString()</code>
+ representation) for the trigger's <code class="literal">WHEN</code> condition, or null
+ if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgoldtable</code> <code class="type">name</code>
+ </p>
+ <p>
+ <code class="literal">REFERENCING</code> clause name for <code class="literal">OLD TABLE</code>,
+ or null if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tgnewtable</code> <code class="type">name</code>
+ </p>
+ <p>
+ <code class="literal">REFERENCING</code> clause name for <code class="literal">NEW TABLE</code>,
+ or null if none
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Currently, column-specific triggering is supported only for
+ <code class="literal">UPDATE</code> events, and so <code class="structfield">tgattr</code> is relevant
+ only for that event type. <code class="structfield">tgtype</code> might
+ contain bits for other event types as well, but those are presumed
+ to be table-wide regardless of what is in <code class="structfield">tgattr</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When <code class="structfield">tgconstraint</code> is nonzero,
+ <code class="structfield">tgconstrrelid</code>, <code class="structfield">tgconstrindid</code>,
+ <code class="structfield">tgdeferrable</code>, and <code class="structfield">tginitdeferred</code> are
+ largely redundant with the referenced <a class="link" href="catalog-pg-constraint.html" title="53.13. pg_constraint"><code class="structname">pg_constraint</code></a> entry.
+ However, it is possible for a non-deferrable trigger to be associated
+ with a deferrable constraint: foreign key constraints can have some
+ deferrable and some non-deferrable triggers.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">pg_class.relhastriggers</code>
+ must be true if a relation has any triggers in this catalog.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-transform.html" title="53.57. pg_transform">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.57. <code class="structname">pg_transform</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.59. <code class="structname">pg_ts_config</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-ts-config-map.html b/doc/src/sgml/html/catalog-pg-ts-config-map.html
new file mode 100644
index 0000000..467691d
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-ts-config-map.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.60. pg_ts_config_map</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config" /><link rel="next" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.60. <code class="structname">pg_ts_config_map</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TS-CONFIG-MAP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.60. <code class="structname">pg_ts_config_map</code></h2></div></div></div><a id="id-1.10.4.62.2" class="indexterm"></a><p>
+ The <code class="structname">pg_ts_config_map</code> catalog contains entries
+ showing which text search dictionaries should be consulted, and in
+ what order, for each output token type of each text search configuration's
+ parser.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s text search features are
+ described at length in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ </p><div class="table" id="id-1.10.4.62.5"><p class="title"><strong>Table 53.60. <code class="structname">pg_ts_config_map</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_ts_config_map Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">mapcfg</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config"><code class="structname">pg_ts_config</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the <a class="link" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config"><code class="structname">pg_ts_config</code></a> entry owning this map entry
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maptokentype</code> <code class="type">int4</code>
+ </p>
+ <p>
+ A token type emitted by the configuration's parser
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">mapseqno</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Order in which to consult this entry (lower
+ <code class="structfield">mapseqno</code>s first)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">mapdict</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict"><code class="structname">pg_ts_dict</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the text search dictionary to consult
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.59. <code class="structname">pg_ts_config</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.61. <code class="structname">pg_ts_dict</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-ts-config.html b/doc/src/sgml/html/catalog-pg-ts-config.html
new file mode 100644
index 0000000..2a11fca
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-ts-config.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.59. pg_ts_config</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-trigger.html" title="53.58. pg_trigger" /><link rel="next" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.59. <code class="structname">pg_ts_config</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-trigger.html" title="53.58. pg_trigger">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TS-CONFIG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.59. <code class="structname">pg_ts_config</code></h2></div></div></div><a id="id-1.10.4.61.2" class="indexterm"></a><p>
+ The <code class="structname">pg_ts_config</code> catalog contains entries
+ representing text search configurations. A configuration specifies
+ a particular text search parser and a list of dictionaries to use
+ for each of the parser's output token types. The parser is shown
+ in the <code class="structname">pg_ts_config</code> entry, but the
+ token-to-dictionary mapping is defined by subsidiary entries in <a class="link" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map"><code class="structname">pg_ts_config_map</code></a>.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s text search features are
+ described at length in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ </p><div class="table" id="id-1.10.4.61.5"><p class="title"><strong>Table 53.59. <code class="structname">pg_ts_config</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_ts_config Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cfgname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Text search configuration name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cfgnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this configuration
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cfgowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the configuration
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cfgparser</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser"><code class="structname">pg_ts_parser</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the text search parser for this configuration
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-trigger.html" title="53.58. pg_trigger">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.58. <code class="structname">pg_trigger</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.60. <code class="structname">pg_ts_config_map</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-ts-dict.html b/doc/src/sgml/html/catalog-pg-ts-dict.html
new file mode 100644
index 0000000..b9bd21f
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-ts-dict.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.61. pg_ts_dict</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map" /><link rel="next" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.61. <code class="structname">pg_ts_dict</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TS-DICT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.61. <code class="structname">pg_ts_dict</code></h2></div></div></div><a id="id-1.10.4.63.2" class="indexterm"></a><p>
+ The <code class="structname">pg_ts_dict</code> catalog contains entries
+ defining text search dictionaries. A dictionary depends on a text
+ search template, which specifies all the implementation functions
+ needed; the dictionary itself provides values for the user-settable
+ parameters supported by the template. This division of labor allows
+ dictionaries to be created by unprivileged users. The parameters
+ are specified by a text string <code class="structfield">dictinitoption</code>,
+ whose format and meaning vary depending on the template.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s text search features are
+ described at length in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ </p><div class="table" id="id-1.10.4.63.5"><p class="title"><strong>Table 53.61. <code class="structname">pg_ts_dict</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_ts_dict Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dictname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Text search dictionary name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dictnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this dictionary
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dictowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the dictionary
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dicttemplate</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template"><code class="structname">pg_ts_template</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the text search template for this dictionary
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dictinitoption</code> <code class="type">text</code>
+ </p>
+ <p>
+ Initialization option string for the template
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.60. <code class="structname">pg_ts_config_map</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.62. <code class="structname">pg_ts_parser</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-ts-parser.html b/doc/src/sgml/html/catalog-pg-ts-parser.html
new file mode 100644
index 0000000..88b28f5
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-ts-parser.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.62. pg_ts_parser</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict" /><link rel="next" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.62. <code class="structname">pg_ts_parser</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TS-PARSER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.62. <code class="structname">pg_ts_parser</code></h2></div></div></div><a id="id-1.10.4.64.2" class="indexterm"></a><p>
+ The <code class="structname">pg_ts_parser</code> catalog contains entries
+ defining text search parsers. A parser is responsible for splitting
+ input text into lexemes and assigning a token type to each lexeme.
+ Since a parser must be implemented by C-language-level functions,
+ creation of new parsers is restricted to database superusers.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s text search features are
+ described at length in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ </p><div class="table" id="id-1.10.4.64.5"><p class="title"><strong>Table 53.62. <code class="structname">pg_ts_parser</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_ts_parser Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prsname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Text search parser name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prsnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this parser
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prsstart</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the parser's startup function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prstoken</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the parser's next-token function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prsend</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the parser's shutdown function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prsheadline</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the parser's headline function (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prslextype</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the parser's lextype function
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.61. <code class="structname">pg_ts_dict</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.63. <code class="structname">pg_ts_template</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-ts-template.html b/doc/src/sgml/html/catalog-pg-ts-template.html
new file mode 100644
index 0000000..f8fec2e
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-ts-template.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.63. pg_ts_template</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser" /><link rel="next" href="catalog-pg-type.html" title="53.64. pg_type" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.63. <code class="structname">pg_ts_template</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-type.html" title="53.64. pg_type">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TS-TEMPLATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.63. <code class="structname">pg_ts_template</code></h2></div></div></div><a id="id-1.10.4.65.2" class="indexterm"></a><p>
+ The <code class="structname">pg_ts_template</code> catalog contains entries
+ defining text search templates. A template is the implementation
+ skeleton for a class of text search dictionaries.
+ Since a template must be implemented by C-language-level functions,
+ creation of new templates is restricted to database superusers.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s text search features are
+ described at length in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ </p><div class="table" id="id-1.10.4.65.5"><p class="title"><strong>Table 53.63. <code class="structname">pg_ts_template</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_ts_template Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tmplname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Text search template name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tmplnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this template
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tmplinit</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the template's initialization function (zero if none)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tmpllexize</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the template's lexize function
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-type.html" title="53.64. pg_type">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.62. <code class="structname">pg_ts_parser</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.64. <code class="structname">pg_type</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-type.html b/doc/src/sgml/html/catalog-pg-type.html
new file mode 100644
index 0000000..4ed6f0b
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-type.html
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.64. pg_type</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template" /><link rel="next" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.64. <code class="structname">pg_type</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-TYPE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.64. <code class="structname">pg_type</code></h2></div></div></div><a id="id-1.10.4.66.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_type</code> stores information about data
+ types. Base types and enum types (scalar types) are created with
+ <a class="link" href="sql-createtype.html" title="CREATE TYPE"><code class="command">CREATE TYPE</code></a>, and
+ domains with
+ <a class="link" href="sql-createdomain.html" title="CREATE DOMAIN"><code class="command">CREATE DOMAIN</code></a>.
+ A composite type is automatically created for each table in the database, to
+ represent the row structure of the table. It is also possible to create
+ composite types with <code class="command">CREATE TYPE AS</code>.
+ </p><div class="table" id="id-1.10.4.66.4"><p class="title"><strong>Table 53.64. <code class="structname">pg_type</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_type Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Data type name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace that contains this type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typowner</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Owner of the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typlen</code> <code class="type">int2</code>
+ </p>
+ <p>
+ For a fixed-size type, <code class="structfield">typlen</code> is the number
+ of bytes in the internal representation of the type. But for a
+ variable-length type, <code class="structfield">typlen</code> is negative.
+ -1 indicates a <span class="quote">“<span class="quote">varlena</span>”</span> type (one that has a length word),
+ -2 indicates a null-terminated C string.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typbyval</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="structfield">typbyval</code> determines whether internal
+ routines pass a value of this type by value or by reference.
+ <code class="structfield">typbyval</code> had better be false if
+ <code class="structfield">typlen</code> is not 1, 2, or 4 (or 8 on machines
+ where Datum is 8 bytes).
+ Variable-length types are always passed by reference. Note that
+ <code class="structfield">typbyval</code> can be false even if the
+ length would allow pass-by-value.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typtype</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="structfield">typtype</code> is
+ <code class="literal">b</code> for a base type,
+ <code class="literal">c</code> for a composite type (e.g., a table's row type),
+ <code class="literal">d</code> for a domain,
+ <code class="literal">e</code> for an enum type,
+ <code class="literal">p</code> for a pseudo-type,
+ <code class="literal">r</code> for a range type, or
+ <code class="literal">m</code> for a multirange type.
+ See also <code class="structfield">typrelid</code> and
+ <code class="structfield">typbasetype</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typcategory</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="structfield">typcategory</code> is an arbitrary classification
+ of data types that is used by the parser to determine which implicit
+ casts should be <span class="quote">“<span class="quote">preferred</span>”</span>.
+ See <a class="xref" href="catalog-pg-type.html#CATALOG-TYPCATEGORY-TABLE" title="Table 53.65. typcategory Codes">Table 53.65</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typispreferred</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the type is a preferred cast target within its
+ <code class="structfield">typcategory</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typisdefined</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the type is defined, false if this is a placeholder
+ entry for a not-yet-defined type. When
+ <code class="structfield">typisdefined</code> is false, nothing
+ except the type name, namespace, and OID can be relied on.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typdelim</code> <code class="type">char</code>
+ </p>
+ <p>
+ Character that separates two values of this type when parsing
+ array input. Note that the delimiter is associated with the array
+ element data type, not the array data type.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typrelid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If this is a composite type (see
+ <code class="structfield">typtype</code>), then this column points to
+ the <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry that defines the
+ corresponding table. (For a free-standing composite type, the
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a> entry doesn't really represent
+ a table, but it is needed anyway for the type's
+ <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a> entries to link to.)
+ Zero for non-composite types.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typsubscript</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Subscripting handler function's OID, or zero if this type doesn't
+ support subscripting. Types that are <span class="quote">“<span class="quote">true</span>”</span> array
+ types have <code class="structfield">typsubscript</code>
+ = <code class="function">array_subscript_handler</code>, but other types may
+ have other handler functions to implement specialized subscripting
+ behavior.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typelem</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If <code class="structfield">typelem</code> is not zero then it
+ identifies another row in <code class="structname">pg_type</code>,
+ defining the type yielded by subscripting. This should be zero
+ if <code class="structfield">typsubscript</code> is zero. However, it can
+ be zero when <code class="structfield">typsubscript</code> isn't zero, if the
+ handler doesn't need <code class="structfield">typelem</code> to
+ determine the subscripting result type.
+ Note that a <code class="structfield">typelem</code> dependency is
+ considered to imply physical containment of the element type in
+ this type; so DDL changes on the element type might be restricted
+ by the presence of this type.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typarray</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If <code class="structfield">typarray</code> is not zero then it
+ identifies another row in <code class="structname">pg_type</code>, which
+ is the <span class="quote">“<span class="quote">true</span>”</span> array type having this type as element
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typinput</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Input conversion function (text format)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typoutput</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Output conversion function (text format)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typreceive</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Input conversion function (binary format), or zero if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typsend</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Output conversion function (binary format), or zero if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typmodin</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Type modifier input function, or zero if type does not support modifiers
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typmodout</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Type modifier output function, or zero to use the standard format
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typanalyze</code> <code class="type">regproc</code>
+ (references <a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Custom <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a> function,
+ or zero to use the standard function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typalign</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="structfield">typalign</code> is the alignment required
+ when storing a value of this type. It applies to storage on
+ disk as well as most representations of the value inside
+ <span class="productname">PostgreSQL</span>.
+ When multiple values are stored consecutively, such
+ as in the representation of a complete row on disk, padding is
+ inserted before a datum of this type so that it begins on the
+ specified boundary. The alignment reference is the beginning
+ of the first datum in the sequence.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">c</code> = <code class="type">char</code> alignment, i.e., no alignment needed.</p></li><li class="listitem"><p><code class="literal">s</code> = <code class="type">short</code> alignment (2 bytes on most machines).</p></li><li class="listitem"><p><code class="literal">i</code> = <code class="type">int</code> alignment (4 bytes on most machines).</p></li><li class="listitem"><p><code class="literal">d</code> = <code class="type">double</code> alignment (8 bytes on many machines, but by no means all).</p></li></ul></div><p>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typstorage</code> <code class="type">char</code>
+ </p>
+ <p>
+ <code class="structfield">typstorage</code> tells for varlena
+ types (those with <code class="structfield">typlen</code> = -1) if
+ the type is prepared for toasting and what the default strategy
+ for attributes of this type should be.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">p</code> (plain): Values must always be stored plain
+ (non-varlena types always use this value).
+ </p></li><li class="listitem"><p>
+ <code class="literal">e</code> (external): Values can be stored in a
+ secondary <span class="quote">“<span class="quote">TOAST</span>”</span> relation (if relation has one, see
+ <code class="literal">pg_class.reltoastrelid</code>).
+ </p></li><li class="listitem"><p>
+ <code class="literal">m</code> (main): Values can be compressed and stored
+ inline.
+ </p></li><li class="listitem"><p>
+ <code class="literal">x</code> (extended): Values can be compressed and/or
+ moved to a secondary relation.
+ </p></li></ul></div><p>
+ <code class="literal">x</code> is the usual choice for toast-able types.
+ Note that <code class="literal">m</code> values can also be moved out to
+ secondary storage, but only as a last resort (<code class="literal">e</code>
+ and <code class="literal">x</code> values are moved first).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typnotnull</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="structfield">typnotnull</code> represents a not-null
+ constraint on a type. Used for domains only.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typbasetype</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ If this is a domain (see <code class="structfield">typtype</code>), then
+ <code class="structfield">typbasetype</code> identifies the type that this
+ one is based on. Zero if this type is not a domain.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typtypmod</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Domains use <code class="structfield">typtypmod</code> to record the <code class="literal">typmod</code>
+ to be applied to their base type (-1 if base type does not use a
+ <code class="literal">typmod</code>). -1 if this type is not a domain.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typndims</code> <code class="type">int4</code>
+ </p>
+ <p>
+ <code class="structfield">typndims</code> is the number of array dimensions
+ for a domain over an array (that is, <code class="structfield">typbasetype</code> is
+ an array type).
+ Zero for types other than domains over array types.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typcollation</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ <code class="structfield">typcollation</code> specifies the collation
+ of the type. If the type does not support collations, this will
+ be zero. A base type that supports collations will have a nonzero
+ value here, typically <code class="symbol">DEFAULT_COLLATION_OID</code>.
+ A domain over a collatable type can have a collation OID different
+ from its base type's, if one was specified for the domain.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typdefaultbin</code> <code class="type">pg_node_tree</code>
+ </p>
+ <p>
+ If <code class="structfield">typdefaultbin</code> is not null, it is the
+ <code class="function">nodeToString()</code>
+ representation of a default expression for the type. This is
+ only used for domains.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typdefault</code> <code class="type">text</code>
+ </p>
+ <p>
+ <code class="structfield">typdefault</code> is null if the type has no associated
+ default value. If <code class="structfield">typdefaultbin</code> is not null,
+ <code class="structfield">typdefault</code> must contain a human-readable version of the
+ default expression represented by <code class="structfield">typdefaultbin</code>. If
+ <code class="structfield">typdefaultbin</code> is null and <code class="structfield">typdefault</code> is
+ not, then <code class="structfield">typdefault</code> is the external representation of
+ the type's default value, which can be fed to the type's input
+ converter to produce a constant.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">typacl</code> <code class="type">aclitem[]</code>
+ </p>
+ <p>
+ Access privileges; see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for details
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ For fixed-width types used in system tables, it is critical that the size
+ and alignment defined in <code class="structname">pg_type</code>
+ agree with the way that the compiler will lay out the column in
+ a structure representing a table row.
+ </p></div><p>
+ <a class="xref" href="catalog-pg-type.html#CATALOG-TYPCATEGORY-TABLE" title="Table 53.65. typcategory Codes">Table 53.65</a> lists the system-defined values
+ of <code class="structfield">typcategory</code>. Any future additions to this list will
+ also be upper-case ASCII letters. All other ASCII characters are reserved
+ for user-defined categories.
+ </p><div class="table" id="CATALOG-TYPCATEGORY-TABLE"><p class="title"><strong>Table 53.65. <code class="structfield">typcategory</code> Codes</strong></p><div class="table-contents"><table class="table" summary="typcategory Codes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Code</th><th>Category</th></tr></thead><tbody><tr><td><code class="literal">A</code></td><td>Array types</td></tr><tr><td><code class="literal">B</code></td><td>Boolean types</td></tr><tr><td><code class="literal">C</code></td><td>Composite types</td></tr><tr><td><code class="literal">D</code></td><td>Date/time types</td></tr><tr><td><code class="literal">E</code></td><td>Enum types</td></tr><tr><td><code class="literal">G</code></td><td>Geometric types</td></tr><tr><td><code class="literal">I</code></td><td>Network address types</td></tr><tr><td><code class="literal">N</code></td><td>Numeric types</td></tr><tr><td><code class="literal">P</code></td><td>Pseudo-types</td></tr><tr><td><code class="literal">R</code></td><td>Range types</td></tr><tr><td><code class="literal">S</code></td><td>String types</td></tr><tr><td><code class="literal">T</code></td><td>Timespan types</td></tr><tr><td><code class="literal">U</code></td><td>User-defined types</td></tr><tr><td><code class="literal">V</code></td><td>Bit-string types</td></tr><tr><td><code class="literal">X</code></td><td><code class="type">unknown</code> type</td></tr><tr><td><code class="literal">Z</code></td><td>Internal-use types</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.63. <code class="structname">pg_ts_template</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.65. <code class="structname">pg_user_mapping</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalog-pg-user-mapping.html b/doc/src/sgml/html/catalog-pg-user-mapping.html
new file mode 100644
index 0000000..a3a4065
--- /dev/null
+++ b/doc/src/sgml/html/catalog-pg-user-mapping.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.65. pg_user_mapping</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-type.html" title="53.64. pg_type" /><link rel="next" href="views.html" title="Chapter 54. System Views" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.65. <code class="structname">pg_user_mapping</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-type.html" title="53.64. pg_type">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="views.html" title="Chapter 54. System Views">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOG-PG-USER-MAPPING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.65. <code class="structname">pg_user_mapping</code></h2></div></div></div><a id="id-1.10.4.67.2" class="indexterm"></a><p>
+ The catalog <code class="structname">pg_user_mapping</code> stores
+ the mappings from local user to remote. Access to this catalog is
+ restricted from normal users, use the view
+ <a class="link" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings"><code class="structname">pg_user_mappings</code></a>
+ instead.
+ </p><div class="table" id="id-1.10.4.67.4"><p class="title"><strong>Table 53.66. <code class="structname">pg_user_mapping</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_user_mapping Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ Row identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">umuser</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the local role being mapped, or zero if the user mapping is public
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">umserver</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server"><code class="structname">pg_foreign_server</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the foreign server that contains this mapping
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">umoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ User mapping specific options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-type.html" title="53.64. pg_type">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="views.html" title="Chapter 54. System Views">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.64. <code class="structname">pg_type</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 54. System Views</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalogs-overview.html b/doc/src/sgml/html/catalogs-overview.html
new file mode 100644
index 0000000..e4c9d67
--- /dev/null
+++ b/doc/src/sgml/html/catalogs-overview.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>53.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalogs.html" title="Chapter 53. System Catalogs" /><link rel="next" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">53.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalogs.html" title="Chapter 53. System Catalogs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><th width="60%" align="center">Chapter 53. System Catalogs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate">Next</a></td></tr></table><hr /></div><div class="sect1" id="CATALOGS-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">53.1. Overview</h2></div></div></div><p>
+ <a class="xref" href="catalogs-overview.html#CATALOG-TABLE" title="Table 53.1. System Catalogs">Table 53.1</a> lists the system catalogs.
+ More detailed documentation of each catalog follows below.
+ </p><p>
+ Most system catalogs are copied from the template database during
+ database creation and are thereafter database-specific. A few
+ catalogs are physically shared across all databases in a cluster;
+ these are noted in the descriptions of the individual catalogs.
+ </p><div class="table" id="CATALOG-TABLE"><p class="title"><strong>Table 53.1. System Catalogs</strong></p><div class="table-contents"><table class="table" summary="System Catalogs" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Catalog Name</th><th>Purpose</th></tr></thead><tbody><tr><td><a class="link" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate"><code class="structname">pg_aggregate</code></a></td><td>aggregate functions</td></tr><tr><td><a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a></td><td>relation access methods</td></tr><tr><td><a class="link" href="catalog-pg-amop.html" title="53.4. pg_amop"><code class="structname">pg_amop</code></a></td><td>access method operators</td></tr><tr><td><a class="link" href="catalog-pg-amproc.html" title="53.5. pg_amproc"><code class="structname">pg_amproc</code></a></td><td>access method support functions</td></tr><tr><td><a class="link" href="catalog-pg-attrdef.html" title="53.6. pg_attrdef"><code class="structname">pg_attrdef</code></a></td><td>column default values</td></tr><tr><td><a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a></td><td>table columns (<span class="quote">“<span class="quote">attributes</span>”</span>)</td></tr><tr><td><a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a></td><td>authorization identifiers (roles)</td></tr><tr><td><a class="link" href="catalog-pg-auth-members.html" title="53.9. pg_auth_members"><code class="structname">pg_auth_members</code></a></td><td>authorization identifier membership relationships</td></tr><tr><td><a class="link" href="catalog-pg-cast.html" title="53.10. pg_cast"><code class="structname">pg_cast</code></a></td><td>casts (data type conversions)</td></tr><tr><td><a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a></td><td>tables, indexes, sequences, views (<span class="quote">“<span class="quote">relations</span>”</span>)</td></tr><tr><td><a class="link" href="catalog-pg-collation.html" title="53.12. pg_collation"><code class="structname">pg_collation</code></a></td><td>collations (locale information)</td></tr><tr><td><a class="link" href="catalog-pg-constraint.html" title="53.13. pg_constraint"><code class="structname">pg_constraint</code></a></td><td>check constraints, unique constraints, primary key constraints, foreign key constraints</td></tr><tr><td><a class="link" href="catalog-pg-conversion.html" title="53.14. pg_conversion"><code class="structname">pg_conversion</code></a></td><td>encoding conversion information</td></tr><tr><td><a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a></td><td>databases within this database cluster</td></tr><tr><td><a class="link" href="catalog-pg-db-role-setting.html" title="53.16. pg_db_role_setting"><code class="structname">pg_db_role_setting</code></a></td><td>per-role and per-database settings</td></tr><tr><td><a class="link" href="catalog-pg-default-acl.html" title="53.17. pg_default_acl"><code class="structname">pg_default_acl</code></a></td><td>default privileges for object types</td></tr><tr><td><a class="link" href="catalog-pg-depend.html" title="53.18. pg_depend"><code class="structname">pg_depend</code></a></td><td>dependencies between database objects</td></tr><tr><td><a class="link" href="catalog-pg-description.html" title="53.19. pg_description"><code class="structname">pg_description</code></a></td><td>descriptions or comments on database objects</td></tr><tr><td><a class="link" href="catalog-pg-enum.html" title="53.20. pg_enum"><code class="structname">pg_enum</code></a></td><td>enum label and value definitions</td></tr><tr><td><a class="link" href="catalog-pg-event-trigger.html" title="53.21. pg_event_trigger"><code class="structname">pg_event_trigger</code></a></td><td>event triggers</td></tr><tr><td><a class="link" href="catalog-pg-extension.html" title="53.22. pg_extension"><code class="structname">pg_extension</code></a></td><td>installed extensions</td></tr><tr><td><a class="link" href="catalog-pg-foreign-data-wrapper.html" title="53.23. pg_foreign_data_wrapper"><code class="structname">pg_foreign_data_wrapper</code></a></td><td>foreign-data wrapper definitions</td></tr><tr><td><a class="link" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server"><code class="structname">pg_foreign_server</code></a></td><td>foreign server definitions</td></tr><tr><td><a class="link" href="catalog-pg-foreign-table.html" title="53.25. pg_foreign_table"><code class="structname">pg_foreign_table</code></a></td><td>additional foreign table information</td></tr><tr><td><a class="link" href="catalog-pg-index.html" title="53.26. pg_index"><code class="structname">pg_index</code></a></td><td>additional index information</td></tr><tr><td><a class="link" href="catalog-pg-inherits.html" title="53.27. pg_inherits"><code class="structname">pg_inherits</code></a></td><td>table inheritance hierarchy</td></tr><tr><td><a class="link" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs"><code class="structname">pg_init_privs</code></a></td><td>object initial privileges</td></tr><tr><td><a class="link" href="catalog-pg-language.html" title="53.29. pg_language"><code class="structname">pg_language</code></a></td><td>languages for writing functions</td></tr><tr><td><a class="link" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject"><code class="structname">pg_largeobject</code></a></td><td>data pages for large objects</td></tr><tr><td><a class="link" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata"><code class="structname">pg_largeobject_metadata</code></a></td><td>metadata for large objects</td></tr><tr><td><a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a></td><td>schemas</td></tr><tr><td><a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a></td><td>access method operator classes</td></tr><tr><td><a class="link" href="catalog-pg-operator.html" title="53.34. pg_operator"><code class="structname">pg_operator</code></a></td><td>operators</td></tr><tr><td><a class="link" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily"><code class="structname">pg_opfamily</code></a></td><td>access method operator families</td></tr><tr><td><a class="link" href="catalog-pg-parameter-acl.html" title="53.36. pg_parameter_acl"><code class="structname">pg_parameter_acl</code></a></td><td>configuration parameters for which privileges have been granted</td></tr><tr><td><a class="link" href="catalog-pg-partitioned-table.html" title="53.37. pg_partitioned_table"><code class="structname">pg_partitioned_table</code></a></td><td>information about partition key of tables</td></tr><tr><td><a class="link" href="catalog-pg-policy.html" title="53.38. pg_policy"><code class="structname">pg_policy</code></a></td><td>row-security policies</td></tr><tr><td><a class="link" href="catalog-pg-proc.html" title="53.39. pg_proc"><code class="structname">pg_proc</code></a></td><td>functions and procedures</td></tr><tr><td><a class="link" href="catalog-pg-publication.html" title="53.40. pg_publication"><code class="structname">pg_publication</code></a></td><td>publications for logical replication</td></tr><tr><td><a class="link" href="catalog-pg-publication-namespace.html" title="53.41. pg_publication_namespace"><code class="structname">pg_publication_namespace</code></a></td><td>schema to publication mapping</td></tr><tr><td><a class="link" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel"><code class="structname">pg_publication_rel</code></a></td><td>relation to publication mapping</td></tr><tr><td><a class="link" href="catalog-pg-range.html" title="53.43. pg_range"><code class="structname">pg_range</code></a></td><td>information about range types</td></tr><tr><td><a class="link" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin"><code class="structname">pg_replication_origin</code></a></td><td>registered replication origins</td></tr><tr><td><a class="link" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite"><code class="structname">pg_rewrite</code></a></td><td>query rewrite rules</td></tr><tr><td><a class="link" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel"><code class="structname">pg_seclabel</code></a></td><td>security labels on database objects</td></tr><tr><td><a class="link" href="catalog-pg-sequence.html" title="53.47. pg_sequence"><code class="structname">pg_sequence</code></a></td><td>information about sequences</td></tr><tr><td><a class="link" href="catalog-pg-shdepend.html" title="53.48. pg_shdepend"><code class="structname">pg_shdepend</code></a></td><td>dependencies on shared objects</td></tr><tr><td><a class="link" href="catalog-pg-shdescription.html" title="53.49. pg_shdescription"><code class="structname">pg_shdescription</code></a></td><td>comments on shared objects</td></tr><tr><td><a class="link" href="catalog-pg-shseclabel.html" title="53.50. pg_shseclabel"><code class="structname">pg_shseclabel</code></a></td><td>security labels on shared database objects</td></tr><tr><td><a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a></td><td>planner statistics</td></tr><tr><td><a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a></td><td>extended planner statistics (definition)</td></tr><tr><td><a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a></td><td>extended planner statistics (built statistics)</td></tr><tr><td><a class="link" href="catalog-pg-subscription.html" title="53.54. pg_subscription"><code class="structname">pg_subscription</code></a></td><td>logical replication subscriptions</td></tr><tr><td><a class="link" href="catalog-pg-subscription-rel.html" title="53.55. pg_subscription_rel"><code class="structname">pg_subscription_rel</code></a></td><td>relation state for subscriptions</td></tr><tr><td><a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a></td><td>tablespaces within this database cluster</td></tr><tr><td><a class="link" href="catalog-pg-transform.html" title="53.57. pg_transform"><code class="structname">pg_transform</code></a></td><td>transforms (data type to procedural language conversions)</td></tr><tr><td><a class="link" href="catalog-pg-trigger.html" title="53.58. pg_trigger"><code class="structname">pg_trigger</code></a></td><td>triggers</td></tr><tr><td><a class="link" href="catalog-pg-ts-config.html" title="53.59. pg_ts_config"><code class="structname">pg_ts_config</code></a></td><td>text search configurations</td></tr><tr><td><a class="link" href="catalog-pg-ts-config-map.html" title="53.60. pg_ts_config_map"><code class="structname">pg_ts_config_map</code></a></td><td>text search configurations' token mappings</td></tr><tr><td><a class="link" href="catalog-pg-ts-dict.html" title="53.61. pg_ts_dict"><code class="structname">pg_ts_dict</code></a></td><td>text search dictionaries</td></tr><tr><td><a class="link" href="catalog-pg-ts-parser.html" title="53.62. pg_ts_parser"><code class="structname">pg_ts_parser</code></a></td><td>text search parsers</td></tr><tr><td><a class="link" href="catalog-pg-ts-template.html" title="53.63. pg_ts_template"><code class="structname">pg_ts_template</code></a></td><td>text search templates</td></tr><tr><td><a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a></td><td>data types</td></tr><tr><td><a class="link" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping"><code class="structname">pg_user_mapping</code></a></td><td>mappings of users to foreign servers</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalogs.html" title="Chapter 53. System Catalogs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="catalogs.html" title="Chapter 53. System Catalogs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalog-pg-aggregate.html" title="53.2. pg_aggregate">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 53. System Catalogs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.2. <code class="structname">pg_aggregate</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/catalogs.html b/doc/src/sgml/html/catalogs.html
new file mode 100644
index 0000000..791d7f0
--- /dev/null
+++ b/doc/src/sgml/html/catalogs.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 53. System Catalogs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="executor.html" title="52.6. Executor" /><link rel="next" href="catalogs-overview.html" title="53.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 53. System Catalogs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="executor.html" title="52.6. Executor">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalogs-overview.html" title="53.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="CATALOGS"><div class="titlepage"><div><div><h2 class="title">Chapter 53. System Catalogs</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="catalogs-overview.html">53.1. Overview</a></span></dt><dt><span class="sect1"><a href="catalog-pg-aggregate.html">53.2. <code class="structname">pg_aggregate</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-am.html">53.3. <code class="structname">pg_am</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-amop.html">53.4. <code class="structname">pg_amop</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-amproc.html">53.5. <code class="structname">pg_amproc</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-attrdef.html">53.6. <code class="structname">pg_attrdef</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-attribute.html">53.7. <code class="structname">pg_attribute</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-authid.html">53.8. <code class="structname">pg_authid</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-auth-members.html">53.9. <code class="structname">pg_auth_members</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-cast.html">53.10. <code class="structname">pg_cast</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-class.html">53.11. <code class="structname">pg_class</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-collation.html">53.12. <code class="structname">pg_collation</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-constraint.html">53.13. <code class="structname">pg_constraint</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-conversion.html">53.14. <code class="structname">pg_conversion</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-database.html">53.15. <code class="structname">pg_database</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-db-role-setting.html">53.16. <code class="structname">pg_db_role_setting</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-default-acl.html">53.17. <code class="structname">pg_default_acl</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-depend.html">53.18. <code class="structname">pg_depend</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-description.html">53.19. <code class="structname">pg_description</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-enum.html">53.20. <code class="structname">pg_enum</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-event-trigger.html">53.21. <code class="structname">pg_event_trigger</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-extension.html">53.22. <code class="structname">pg_extension</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-foreign-data-wrapper.html">53.23. <code class="structname">pg_foreign_data_wrapper</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-foreign-server.html">53.24. <code class="structname">pg_foreign_server</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-foreign-table.html">53.25. <code class="structname">pg_foreign_table</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-index.html">53.26. <code class="structname">pg_index</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-inherits.html">53.27. <code class="structname">pg_inherits</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-init-privs.html">53.28. <code class="structname">pg_init_privs</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-language.html">53.29. <code class="structname">pg_language</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-largeobject.html">53.30. <code class="structname">pg_largeobject</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-largeobject-metadata.html">53.31. <code class="structname">pg_largeobject_metadata</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-namespace.html">53.32. <code class="structname">pg_namespace</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-opclass.html">53.33. <code class="structname">pg_opclass</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-operator.html">53.34. <code class="structname">pg_operator</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-opfamily.html">53.35. <code class="structname">pg_opfamily</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-parameter-acl.html">53.36. <code class="structname">pg_parameter_acl</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-partitioned-table.html">53.37. <code class="structname">pg_partitioned_table</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-policy.html">53.38. <code class="structname">pg_policy</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-proc.html">53.39. <code class="structname">pg_proc</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-publication.html">53.40. <code class="structname">pg_publication</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-publication-namespace.html">53.41. <code class="structname">pg_publication_namespace</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-publication-rel.html">53.42. <code class="structname">pg_publication_rel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-range.html">53.43. <code class="structname">pg_range</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-replication-origin.html">53.44. <code class="structname">pg_replication_origin</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-rewrite.html">53.45. <code class="structname">pg_rewrite</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-seclabel.html">53.46. <code class="structname">pg_seclabel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-sequence.html">53.47. <code class="structname">pg_sequence</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-shdepend.html">53.48. <code class="structname">pg_shdepend</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-shdescription.html">53.49. <code class="structname">pg_shdescription</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-shseclabel.html">53.50. <code class="structname">pg_shseclabel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-statistic.html">53.51. <code class="structname">pg_statistic</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-statistic-ext.html">53.52. <code class="structname">pg_statistic_ext</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-statistic-ext-data.html">53.53. <code class="structname">pg_statistic_ext_data</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-subscription.html">53.54. <code class="structname">pg_subscription</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-subscription-rel.html">53.55. <code class="structname">pg_subscription_rel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-tablespace.html">53.56. <code class="structname">pg_tablespace</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-transform.html">53.57. <code class="structname">pg_transform</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-trigger.html">53.58. <code class="structname">pg_trigger</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-config.html">53.59. <code class="structname">pg_ts_config</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-config-map.html">53.60. <code class="structname">pg_ts_config_map</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-dict.html">53.61. <code class="structname">pg_ts_dict</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-parser.html">53.62. <code class="structname">pg_ts_parser</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-template.html">53.63. <code class="structname">pg_ts_template</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-type.html">53.64. <code class="structname">pg_type</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-user-mapping.html">53.65. <code class="structname">pg_user_mapping</code></a></span></dt></dl></div><p>
+ The system catalogs are the place where a relational database
+ management system stores schema metadata, such as information about
+ tables and columns, and internal bookkeeping information.
+ <span class="productname">PostgreSQL</span>'s system catalogs are regular
+ tables. You can drop and recreate the tables, add columns, insert
+ and update values, and severely mess up your system that way.
+ Normally, one should not change the system catalogs by hand, there
+ are normally SQL commands to do that. (For example, <code class="command">CREATE
+ DATABASE</code> inserts a row into the
+ <code class="structname">pg_database</code> catalog — and actually
+ creates the database on disk.) There are some exceptions for
+ particularly esoteric operations, but many of those have been made
+ available as SQL commands over time, and so the need for direct manipulation
+ of the system catalogs is ever decreasing.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="executor.html" title="52.6. Executor">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalogs-overview.html" title="53.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">52.6. Executor </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 53.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/charset.html b/doc/src/sgml/html/charset.html
new file mode 100644
index 0000000..1cf4234
--- /dev/null
+++ b/doc/src/sgml/html/charset.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 24. Localization</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="manage-ag-tablespaces.html" title="23.6. Tablespaces" /><link rel="next" href="locale.html" title="24.1. Locale Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 24. Localization</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="locale.html" title="24.1. Locale Support">Next</a></td></tr></table><hr /></div><div class="chapter" id="CHARSET"><div class="titlepage"><div><div><h2 class="title">Chapter 24. Localization</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="locale.html">24.1. Locale Support</a></span></dt><dd><dl><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.4">24.1.1. Overview</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.5">24.1.2. Behavior</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.6">24.1.3. Selecting Locales</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.7">24.1.4. Locale Providers</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.8">24.1.5. Problems</a></span></dt></dl></dd><dt><span class="sect1"><a href="collation.html">24.2. Collation Support</a></span></dt><dd><dl><dt><span class="sect2"><a href="collation.html#id-1.6.11.4.4">24.2.1. Concepts</a></span></dt><dt><span class="sect2"><a href="collation.html#COLLATION-MANAGING">24.2.2. Managing Collations</a></span></dt></dl></dd><dt><span class="sect1"><a href="multibyte.html">24.3. Character Set Support</a></span></dt><dd><dl><dt><span class="sect2"><a href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED">24.3.1. Supported Character Sets</a></span></dt><dt><span class="sect2"><a href="multibyte.html#id-1.6.11.5.6">24.3.2. Setting the Character Set</a></span></dt><dt><span class="sect2"><a href="multibyte.html#id-1.6.11.5.7">24.3.3. Automatic Character Set Conversion Between Server and Client</a></span></dt><dt><span class="sect2"><a href="multibyte.html#MULTIBYTE-CONVERSIONS-SUPPORTED">24.3.4. Available Character Set Conversions</a></span></dt><dt><span class="sect2"><a href="multibyte.html#id-1.6.11.5.9">24.3.5. Further Reading</a></span></dt></dl></dd></dl></div><p>
+ This chapter describes the available localization features from the
+ point of view of the administrator.
+ <span class="productname">PostgreSQL</span> supports two localization
+ facilities:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Using the locale features of the operating system to provide
+ locale-specific collation order, number formatting, translated
+ messages, and other aspects.
+ This is covered in <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> and
+ <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>.
+ </p></li><li class="listitem"><p>
+ Providing a number of different character sets to support storing text
+ in all kinds of languages, and providing character set translation
+ between client and server.
+ This is covered in <a class="xref" href="multibyte.html" title="24.3. Character Set Support">Section 24.3</a>.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="locale.html" title="24.1. Locale Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">23.6. Tablespaces </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 24.1. Locale Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/checksums.html b/doc/src/sgml/html/checksums.html
new file mode 100644
index 0000000..187ff8b
--- /dev/null
+++ b/doc/src/sgml/html/checksums.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>30.2. Data Checksums</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="wal-reliability.html" title="30.1. Reliability" /><link rel="next" href="wal-intro.html" title="30.3. Write-Ahead Logging (WAL)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">30.2. Data Checksums</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="wal-reliability.html" title="30.1. Reliability">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><th width="60%" align="center">Chapter 30. Reliability and the Write-Ahead Log</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="wal-intro.html" title="30.3. Write-Ahead Logging (WAL)">Next</a></td></tr></table><hr /></div><div class="sect1" id="CHECKSUMS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">30.2. Data Checksums</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="checksums.html#CHECKSUMS-OFFLINE-ENABLE-DISABLE">30.2.1. Off-line Enabling of Checksums</a></span></dt></dl></div><a id="id-1.6.17.4.2" class="indexterm"></a><p>
+ By default, data pages are not protected by checksums, but this can
+ optionally be enabled for a cluster. When enabled, each data page includes
+ a checksum that is updated when the page is written and verified each time
+ the page is read. Only data pages are protected by checksums; internal data
+ structures and temporary files are not.
+ </p><p>
+ Checksums are normally enabled when the cluster is initialized using <a class="link" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS"><span class="application">initdb</span></a>.
+ They can also be enabled or disabled at a later time as an offline
+ operation. Data checksums are enabled or disabled at the full cluster
+ level, and cannot be specified individually for databases or tables.
+ </p><p>
+ The current state of checksums in the cluster can be verified by viewing the
+ value of the read-only configuration variable <a class="xref" href="runtime-config-preset.html#GUC-DATA-CHECKSUMS">data_checksums</a> by issuing the command <code class="command">SHOW
+ data_checksums</code>.
+ </p><p>
+ When attempting to recover from page corruptions, it may be necessary to
+ bypass the checksum protection. To do this, temporarily set the
+ configuration parameter <a class="xref" href="runtime-config-developer.html#GUC-IGNORE-CHECKSUM-FAILURE">ignore_checksum_failure</a>.
+ </p><div class="sect2" id="CHECKSUMS-OFFLINE-ENABLE-DISABLE"><div class="titlepage"><div><div><h3 class="title">30.2.1. Off-line Enabling of Checksums</h3></div></div></div><p>
+ The <a class="link" href="app-pgchecksums.html" title="pg_checksums"><span class="application">pg_checksums</span></a>
+ application can be used to enable or disable data checksums, as well as
+ verify checksums, on an offline cluster.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="wal-reliability.html" title="30.1. Reliability">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="wal-intro.html" title="30.3. Write-Ahead Logging (WAL)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">30.1. Reliability </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 30.3. Write-Ahead Logging (<acronym class="acronym">WAL</acronym>)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/citext.html b/doc/src/sgml/html/citext.html
new file mode 100644
index 0000000..c32f0a1
--- /dev/null
+++ b/doc/src/sgml/html/citext.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.10. citext</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree-gist.html" title="F.9. btree_gist" /><link rel="next" href="cube.html" title="F.11. cube" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.10. citext</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree-gist.html" title="F.9. btree_gist">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="cube.html" title="F.11. cube">Next</a></td></tr></table><hr /></div><div class="sect1" id="CITEXT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.10. citext</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.6">F.10.1. Rationale</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.7">F.10.2. How to Use It</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.8">F.10.3. String Comparison Behavior</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.9">F.10.4. Limitations</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.10">F.10.5. Author</a></span></dt></dl></div><a id="id-1.11.7.19.2" class="indexterm"></a><p>
+ The <code class="filename">citext</code> module provides a case-insensitive
+ character string type, <code class="type">citext</code>. Essentially, it internally calls
+ <code class="function">lower</code> when comparing values. Otherwise, it behaves almost
+ exactly like <code class="type">text</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Consider using <em class="firstterm">nondeterministic collations</em> (see
+ <a class="xref" href="collation.html#COLLATION-NONDETERMINISTIC" title="24.2.2.4. Nondeterministic Collations">Section 24.2.2.4</a>) instead of this module. They
+ can be used for case-insensitive comparisons, accent-insensitive
+ comparisons, and other combinations, and they handle more Unicode special
+ cases correctly.
+ </p></div><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.19.6"><div class="titlepage"><div><div><h3 class="title">F.10.1. Rationale</h3></div></div></div><p>
+ The standard approach to doing case-insensitive matches
+ in <span class="productname">PostgreSQL</span> has been to use the <code class="function">lower</code>
+ function when comparing values, for example
+
+</p><pre class="programlisting">
+SELECT * FROM tab WHERE lower(col) = LOWER(?);
+</pre><p>
+ </p><p>
+ This works reasonably well, but has a number of drawbacks:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ It makes your SQL statements verbose, and you always have to remember to
+ use <code class="function">lower</code> on both the column and the query value.
+ </p></li><li class="listitem"><p>
+ It won't use an index, unless you create a functional index using
+ <code class="function">lower</code>.
+ </p></li><li class="listitem"><p>
+ If you declare a column as <code class="literal">UNIQUE</code> or <code class="literal">PRIMARY
+ KEY</code>, the implicitly generated index is case-sensitive. So it's
+ useless for case-insensitive searches, and it won't enforce
+ uniqueness case-insensitively.
+ </p></li></ul></div><p>
+ The <code class="type">citext</code> data type allows you to eliminate calls
+ to <code class="function">lower</code> in SQL queries, and allows a primary key to
+ be case-insensitive. <code class="type">citext</code> is locale-aware, just
+ like <code class="type">text</code>, which means that the matching of upper case and
+ lower case characters is dependent on the rules of
+ the database's <code class="literal">LC_CTYPE</code> setting. Again, this behavior is
+ identical to the use of <code class="function">lower</code> in queries. But because it's
+ done transparently by the data type, you don't have to remember to do
+ anything special in your queries.
+ </p></div><div class="sect2" id="id-1.11.7.19.7"><div class="titlepage"><div><div><h3 class="title">F.10.2. How to Use It</h3></div></div></div><p>
+ Here's a simple example of usage:
+
+</p><pre class="programlisting">
+CREATE TABLE users (
+ nick CITEXT PRIMARY KEY,
+ pass TEXT NOT NULL
+);
+
+INSERT INTO users VALUES ( 'larry', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'Tom', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'Damian', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'NEAL', sha256(random()::text::bytea) );
+INSERT INTO users VALUES ( 'Bjørn', sha256(random()::text::bytea) );
+
+SELECT * FROM users WHERE nick = 'Larry';
+</pre><p>
+
+ The <code class="command">SELECT</code> statement will return one tuple, even though
+ the <code class="structfield">nick</code> column was set to <code class="literal">larry</code> and the query
+ was for <code class="literal">Larry</code>.
+ </p></div><div class="sect2" id="id-1.11.7.19.8"><div class="titlepage"><div><div><h3 class="title">F.10.3. String Comparison Behavior</h3></div></div></div><p>
+ <code class="type">citext</code> performs comparisons by converting each string to lower
+ case (as though <code class="function">lower</code> were called) and then comparing the
+ results normally. Thus, for example, two strings are considered equal
+ if <code class="function">lower</code> would produce identical results for them.
+ </p><p>
+ In order to emulate a case-insensitive collation as closely as possible,
+ there are <code class="type">citext</code>-specific versions of a number of string-processing
+ operators and functions. So, for example, the regular expression
+ operators <code class="literal">~</code> and <code class="literal">~*</code> exhibit the same behavior when
+ applied to <code class="type">citext</code>: they both match case-insensitively.
+ The same is true
+ for <code class="literal">!~</code> and <code class="literal">!~*</code>, as well as for the
+ <code class="literal">LIKE</code> operators <code class="literal">~~</code> and <code class="literal">~~*</code>, and
+ <code class="literal">!~~</code> and <code class="literal">!~~*</code>. If you'd like to match
+ case-sensitively, you can cast the operator's arguments to <code class="type">text</code>.
+ </p><p>
+ Similarly, all of the following functions perform matching
+ case-insensitively if their arguments are <code class="type">citext</code>:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="function">regexp_match()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">regexp_matches()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">regexp_replace()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">regexp_split_to_array()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">regexp_split_to_table()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">replace()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">split_part()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">strpos()</code>
+ </p></li><li class="listitem"><p>
+ <code class="function">translate()</code>
+ </p></li></ul></div><p>
+ For the regexp functions, if you want to match case-sensitively, you can
+ specify the <span class="quote">“<span class="quote">c</span>”</span> flag to force a case-sensitive match. Otherwise,
+ you must cast to <code class="type">text</code> before using one of these functions if
+ you want case-sensitive behavior.
+ </p></div><div class="sect2" id="id-1.11.7.19.9"><div class="titlepage"><div><div><h3 class="title">F.10.4. Limitations</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="type">citext</code>'s case-folding behavior depends on
+ the <code class="literal">LC_CTYPE</code> setting of your database. How it compares
+ values is therefore determined when the database is created.
+ It is not truly
+ case-insensitive in the terms defined by the Unicode standard.
+ Effectively, what this means is that, as long as you're happy with your
+ collation, you should be happy with <code class="type">citext</code>'s comparisons. But
+ if you have data in different languages stored in your database, users
+ of one language may find their query results are not as expected if the
+ collation is for another language.
+ </p></li><li class="listitem"><p>
+ As of <span class="productname">PostgreSQL</span> 9.1, you can attach a
+ <code class="literal">COLLATE</code> specification to <code class="type">citext</code> columns or data
+ values. Currently, <code class="type">citext</code> operators will honor a non-default
+ <code class="literal">COLLATE</code> specification while comparing case-folded strings,
+ but the initial folding to lower case is always done according to the
+ database's <code class="literal">LC_CTYPE</code> setting (that is, as though
+ <code class="literal">COLLATE "default"</code> were given). This may be changed in a
+ future release so that both steps follow the input <code class="literal">COLLATE</code>
+ specification.
+ </p></li><li class="listitem"><p>
+ <code class="type">citext</code> is not as efficient as <code class="type">text</code> because the
+ operator functions and the B-tree comparison functions must make copies
+ of the data and convert it to lower case for comparisons. Also, only
+ <code class="type">text</code> can support B-Tree deduplication. However,
+ <code class="type">citext</code> is slightly more efficient than using
+ <code class="function">lower</code> to get case-insensitive matching.
+ </p></li><li class="listitem"><p>
+ <code class="type">citext</code> doesn't help much if you need data to compare
+ case-sensitively in some contexts and case-insensitively in other
+ contexts. The standard answer is to use the <code class="type">text</code> type and
+ manually use the <code class="function">lower</code> function when you need to compare
+ case-insensitively; this works all right if case-insensitive comparison
+ is needed only infrequently. If you need case-insensitive behavior most
+ of the time and case-sensitive infrequently, consider storing the data
+ as <code class="type">citext</code> and explicitly casting the column to <code class="type">text</code>
+ when you want case-sensitive comparison. In either situation, you will
+ need two indexes if you want both types of searches to be fast.
+ </p></li><li class="listitem"><p>
+ The schema containing the <code class="type">citext</code> operators must be
+ in the current <code class="varname">search_path</code> (typically <code class="literal">public</code>);
+ if it is not, the normal case-sensitive <code class="type">text</code> operators
+ will be invoked instead.
+ </p></li><li class="listitem"><p>
+ The approach of lower-casing strings for comparison does not handle some
+ Unicode special cases correctly, for example when one upper-case letter
+ has two lower-case letter equivalents. Unicode distinguishes between
+ <em class="firstterm">case mapping</em> and <em class="firstterm">case
+ folding</em> for this reason. Use nondeterministic collations
+ instead of <code class="type">citext</code> to handle that correctly.
+ </p></li></ul></div></div><div class="sect2" id="id-1.11.7.19.10"><div class="titlepage"><div><div><h3 class="title">F.10.5. Author</h3></div></div></div><p>
+ David E. Wheeler <code class="email">&lt;<a class="email" href="mailto:david@kineticode.com">david@kineticode.com</a>&gt;</code>
+ </p><p>
+ Inspired by the original <code class="type">citext</code> module by Donald Fraser.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree-gist.html" title="F.9. btree_gist">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="cube.html" title="F.11. cube">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.9. btree_gist </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.11. cube</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/client-authentication-problems.html b/doc/src/sgml/html/client-authentication-problems.html
new file mode 100644
index 0000000..db82850
--- /dev/null
+++ b/doc/src/sgml/html/client-authentication-problems.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.15. Authentication Problems</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-bsd.html" title="21.14. BSD Authentication" /><link rel="next" href="user-manag.html" title="Chapter 22. Database Roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.15. Authentication Problems</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-bsd.html" title="21.14. BSD Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="user-manag.html" title="Chapter 22. Database Roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="CLIENT-AUTHENTICATION-PROBLEMS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.15. Authentication Problems</h2></div></div></div><p>
+ Authentication failures and related problems generally
+ manifest themselves through error messages like the following:
+ </p><p>
+</p><pre class="programlisting">
+FATAL: no pg_hba.conf entry for host "123.123.123.123", user "andym", database "testdb"
+</pre><p>
+ This is what you are most likely to get if you succeed in contacting
+ the server, but it does not want to talk to you. As the message
+ suggests, the server refused the connection request because it found
+ no matching entry in its <code class="filename">pg_hba.conf</code>
+ configuration file.
+ </p><p>
+</p><pre class="programlisting">
+FATAL: password authentication failed for user "andym"
+</pre><p>
+ Messages like this indicate that you contacted the server, and it is
+ willing to talk to you, but not until you pass the authorization
+ method specified in the <code class="filename">pg_hba.conf</code> file. Check
+ the password you are providing, or check your Kerberos or ident
+ software if the complaint mentions one of those authentication
+ types.
+ </p><p>
+</p><pre class="programlisting">
+FATAL: user "andym" does not exist
+</pre><p>
+ The indicated database user name was not found.
+ </p><p>
+</p><pre class="programlisting">
+FATAL: database "testdb" does not exist
+</pre><p>
+ The database you are trying to connect to does not exist. Note that
+ if you do not specify a database name, it defaults to the database
+ user name, which might or might not be the right thing.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The server log might contain more information about an
+ authentication failure than is reported to the client. If you are
+ confused about the reason for a failure, check the server log.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-bsd.html" title="21.14. BSD Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="user-manag.html" title="Chapter 22. Database Roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.14. BSD Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 22. Database Roles</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/client-authentication.html b/doc/src/sgml/html/client-authentication.html
new file mode 100644
index 0000000..db1d989
--- /dev/null
+++ b/doc/src/sgml/html/client-authentication.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 21. Client Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-short.html" title="20.18. Short Options" /><link rel="next" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 21. Client Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-short.html" title="20.18. Short Options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Next</a></td></tr></table><hr /></div><div class="chapter" id="CLIENT-AUTHENTICATION"><div class="titlepage"><div><div><h2 class="title">Chapter 21. Client Authentication</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="auth-pg-hba-conf.html">21.1. The <code class="filename">pg_hba.conf</code> File</a></span></dt><dt><span class="sect1"><a href="auth-username-maps.html">21.2. User Name Maps</a></span></dt><dt><span class="sect1"><a href="auth-methods.html">21.3. Authentication Methods</a></span></dt><dt><span class="sect1"><a href="auth-trust.html">21.4. Trust Authentication</a></span></dt><dt><span class="sect1"><a href="auth-password.html">21.5. Password Authentication</a></span></dt><dt><span class="sect1"><a href="gssapi-auth.html">21.6. GSSAPI Authentication</a></span></dt><dt><span class="sect1"><a href="sspi-auth.html">21.7. SSPI Authentication</a></span></dt><dt><span class="sect1"><a href="auth-ident.html">21.8. Ident Authentication</a></span></dt><dt><span class="sect1"><a href="auth-peer.html">21.9. Peer Authentication</a></span></dt><dt><span class="sect1"><a href="auth-ldap.html">21.10. LDAP Authentication</a></span></dt><dt><span class="sect1"><a href="auth-radius.html">21.11. RADIUS Authentication</a></span></dt><dt><span class="sect1"><a href="auth-cert.html">21.12. Certificate Authentication</a></span></dt><dt><span class="sect1"><a href="auth-pam.html">21.13. PAM Authentication</a></span></dt><dt><span class="sect1"><a href="auth-bsd.html">21.14. BSD Authentication</a></span></dt><dt><span class="sect1"><a href="client-authentication-problems.html">21.15. Authentication Problems</a></span></dt></dl></div><a id="id-1.6.8.2" class="indexterm"></a><p>
+ When a client application connects to the database server, it
+ specifies which <span class="productname">PostgreSQL</span> database user name it
+ wants to connect as, much the same way one logs into a Unix computer
+ as a particular user. Within the SQL environment the active database
+ user name determines access privileges to database objects — see
+ <a class="xref" href="user-manag.html" title="Chapter 22. Database Roles">Chapter 22</a> for more information. Therefore, it is
+ essential to restrict which database users can connect.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ As explained in <a class="xref" href="user-manag.html" title="Chapter 22. Database Roles">Chapter 22</a>,
+ <span class="productname">PostgreSQL</span> actually does privilege
+ management in terms of <span class="quote">“<span class="quote">roles</span>”</span>. In this chapter, we
+ consistently use <em class="firstterm">database user</em> to mean <span class="quote">“<span class="quote">role with the
+ <code class="literal">LOGIN</code> privilege</span>”</span>.
+ </p></div><p>
+ <em class="firstterm">Authentication</em> is the process by which the
+ database server establishes the identity of the client, and by
+ extension determines whether the client application (or the user
+ who runs the client application) is permitted to connect with the
+ database user name that was requested.
+ </p><p>
+ <span class="productname">PostgreSQL</span> offers a number of different
+ client authentication methods. The method used to authenticate a
+ particular client connection can be selected on the basis of
+ (client) host address, database, and user.
+ </p><p>
+ <span class="productname">PostgreSQL</span> database user names are logically
+ separate from user names of the operating system in which the server
+ runs. If all the users of a particular server also have accounts on
+ the server's machine, it makes sense to assign database user names
+ that match their operating system user names. However, a server that
+ accepts remote connections might have many database users who have no local
+ operating system
+ account, and in such cases there need be no connection between
+ database user names and OS user names.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-short.html" title="20.18. Short Options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.18. Short Options </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.1. The <code class="filename">pg_hba.conf</code> File</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/client-interfaces.html b/doc/src/sgml/html/client-interfaces.html
new file mode 100644
index 0000000..f249f20
--- /dev/null
+++ b/doc/src/sgml/html/client-interfaces.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part IV. Client Interfaces</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="regress-coverage.html" title="33.5. Test Coverage Examination" /><link rel="next" href="libpq.html" title="Chapter 34. libpq — C Library" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part IV. Client Interfaces</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="regress-coverage.html" title="33.5. Test Coverage Examination">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq.html" title="Chapter 34. libpq — C Library">Next</a></td></tr></table><hr /></div><div class="part" id="CLIENT-INTERFACES"><div class="titlepage"><div><div><h1 class="title">Part IV. Client Interfaces</h1></div></div></div><div class="partintro" id="id-1.7.2"><div></div><p>
+ This part describes the client programming interfaces distributed
+ with <span class="productname">PostgreSQL</span>. Each of these chapters can be
+ read independently. Note that there are many other programming
+ interfaces for client programs that are distributed separately and
+ contain their own documentation (<a class="xref" href="external-projects.html" title="Appendix H. External Projects">Appendix H</a>
+ lists some of the more popular ones). Readers of this part should be
+ familiar with using <acronym class="acronym">SQL</acronym> commands to manipulate
+ and query the database (see <a class="xref" href="sql.html" title="Part II. The SQL Language">Part II</a>) and of course
+ with the programming language that the interface uses.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="libpq.html">34. <span class="application">libpq</span> — C Library</a></span></dt><dd><dl><dt><span class="sect1"><a href="libpq-connect.html">34.1. Database Connection Control Functions</a></span></dt><dt><span class="sect1"><a href="libpq-status.html">34.2. Connection Status Functions</a></span></dt><dt><span class="sect1"><a href="libpq-exec.html">34.3. Command Execution Functions</a></span></dt><dt><span class="sect1"><a href="libpq-async.html">34.4. Asynchronous Command Processing</a></span></dt><dt><span class="sect1"><a href="libpq-pipeline-mode.html">34.5. Pipeline Mode</a></span></dt><dt><span class="sect1"><a href="libpq-single-row-mode.html">34.6. Retrieving Query Results Row-by-Row</a></span></dt><dt><span class="sect1"><a href="libpq-cancel.html">34.7. Canceling Queries in Progress</a></span></dt><dt><span class="sect1"><a href="libpq-fastpath.html">34.8. The Fast-Path Interface</a></span></dt><dt><span class="sect1"><a href="libpq-notify.html">34.9. Asynchronous Notification</a></span></dt><dt><span class="sect1"><a href="libpq-copy.html">34.10. Functions Associated with the <code class="command">COPY</code> Command</a></span></dt><dt><span class="sect1"><a href="libpq-control.html">34.11. Control Functions</a></span></dt><dt><span class="sect1"><a href="libpq-misc.html">34.12. Miscellaneous Functions</a></span></dt><dt><span class="sect1"><a href="libpq-notice-processing.html">34.13. Notice Processing</a></span></dt><dt><span class="sect1"><a href="libpq-events.html">34.14. Event System</a></span></dt><dt><span class="sect1"><a href="libpq-envars.html">34.15. Environment Variables</a></span></dt><dt><span class="sect1"><a href="libpq-pgpass.html">34.16. The Password File</a></span></dt><dt><span class="sect1"><a href="libpq-pgservice.html">34.17. The Connection Service File</a></span></dt><dt><span class="sect1"><a href="libpq-ldap.html">34.18. LDAP Lookup of Connection Parameters</a></span></dt><dt><span class="sect1"><a href="libpq-ssl.html">34.19. SSL Support</a></span></dt><dt><span class="sect1"><a href="libpq-threading.html">34.20. Behavior in Threaded Programs</a></span></dt><dt><span class="sect1"><a href="libpq-build.html">34.21. Building <span class="application">libpq</span> Programs</a></span></dt><dt><span class="sect1"><a href="libpq-example.html">34.22. Example Programs</a></span></dt></dl></dd><dt><span class="chapter"><a href="largeobjects.html">35. Large Objects</a></span></dt><dd><dl><dt><span class="sect1"><a href="lo-intro.html">35.1. Introduction</a></span></dt><dt><span class="sect1"><a href="lo-implementation.html">35.2. Implementation Features</a></span></dt><dt><span class="sect1"><a href="lo-interfaces.html">35.3. Client Interfaces</a></span></dt><dt><span class="sect1"><a href="lo-funcs.html">35.4. Server-Side Functions</a></span></dt><dt><span class="sect1"><a href="lo-examplesect.html">35.5. Example Program</a></span></dt></dl></dd><dt><span class="chapter"><a href="ecpg.html">36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</a></span></dt><dd><dl><dt><span class="sect1"><a href="ecpg-concept.html">36.1. The Concept</a></span></dt><dt><span class="sect1"><a href="ecpg-connect.html">36.2. Managing Database Connections</a></span></dt><dt><span class="sect1"><a href="ecpg-commands.html">36.3. Running SQL Commands</a></span></dt><dt><span class="sect1"><a href="ecpg-variables.html">36.4. Using Host Variables</a></span></dt><dt><span class="sect1"><a href="ecpg-dynamic.html">36.5. Dynamic SQL</a></span></dt><dt><span class="sect1"><a href="ecpg-pgtypes.html">36.6. pgtypes Library</a></span></dt><dt><span class="sect1"><a href="ecpg-descriptors.html">36.7. Using Descriptor Areas</a></span></dt><dt><span class="sect1"><a href="ecpg-errors.html">36.8. Error Handling</a></span></dt><dt><span class="sect1"><a href="ecpg-preproc.html">36.9. Preprocessor Directives</a></span></dt><dt><span class="sect1"><a href="ecpg-process.html">36.10. Processing Embedded SQL Programs</a></span></dt><dt><span class="sect1"><a href="ecpg-library.html">36.11. Library Functions</a></span></dt><dt><span class="sect1"><a href="ecpg-lo.html">36.12. Large Objects</a></span></dt><dt><span class="sect1"><a href="ecpg-cpp.html">36.13. <acronym class="acronym">C++</acronym> Applications</a></span></dt><dt><span class="sect1"><a href="ecpg-sql-commands.html">36.14. Embedded SQL Commands</a></span></dt><dt><span class="sect1"><a href="ecpg-informix-compat.html">36.15. <span class="productname">Informix</span> Compatibility Mode</a></span></dt><dt><span class="sect1"><a href="ecpg-oracle-compat.html">36.16. <span class="productname">Oracle</span> Compatibility Mode</a></span></dt><dt><span class="sect1"><a href="ecpg-develop.html">36.17. Internals</a></span></dt></dl></dd><dt><span class="chapter"><a href="information-schema.html">37. The Information Schema</a></span></dt><dd><dl><dt><span class="sect1"><a href="infoschema-schema.html">37.1. The Schema</a></span></dt><dt><span class="sect1"><a href="infoschema-datatypes.html">37.2. Data Types</a></span></dt><dt><span class="sect1"><a href="infoschema-information-schema-catalog-name.html">37.3. <code class="literal">information_schema_catalog_name</code></a></span></dt><dt><span class="sect1"><a href="infoschema-administrable-role-authorizations.html">37.4. <code class="literal">administrable_role_​authorizations</code></a></span></dt><dt><span class="sect1"><a href="infoschema-applicable-roles.html">37.5. <code class="literal">applicable_roles</code></a></span></dt><dt><span class="sect1"><a href="infoschema-attributes.html">37.6. <code class="literal">attributes</code></a></span></dt><dt><span class="sect1"><a href="infoschema-character-sets.html">37.7. <code class="literal">character_sets</code></a></span></dt><dt><span class="sect1"><a href="infoschema-check-constraint-routine-usage.html">37.8. <code class="literal">check_constraint_routine_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-check-constraints.html">37.9. <code class="literal">check_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-collations.html">37.10. <code class="literal">collations</code></a></span></dt><dt><span class="sect1"><a href="infoschema-collation-character-set-applicab.html">37.11. <code class="literal">collation_character_set_​applicability</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-column-usage.html">37.12. <code class="literal">column_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-domain-usage.html">37.13. <code class="literal">column_domain_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-options.html">37.14. <code class="literal">column_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-privileges.html">37.15. <code class="literal">column_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-udt-usage.html">37.16. <code class="literal">column_udt_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-columns.html">37.17. <code class="literal">columns</code></a></span></dt><dt><span class="sect1"><a href="infoschema-constraint-column-usage.html">37.18. <code class="literal">constraint_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-constraint-table-usage.html">37.19. <code class="literal">constraint_table_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-data-type-privileges.html">37.20. <code class="literal">data_type_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-domain-constraints.html">37.21. <code class="literal">domain_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-domain-udt-usage.html">37.22. <code class="literal">domain_udt_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-domains.html">37.23. <code class="literal">domains</code></a></span></dt><dt><span class="sect1"><a href="infoschema-element-types.html">37.24. <code class="literal">element_types</code></a></span></dt><dt><span class="sect1"><a href="infoschema-enabled-roles.html">37.25. <code class="literal">enabled_roles</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-data-wrapper-options.html">37.26. <code class="literal">foreign_data_wrapper_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-data-wrappers.html">37.27. <code class="literal">foreign_data_wrappers</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-server-options.html">37.28. <code class="literal">foreign_server_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-servers.html">37.29. <code class="literal">foreign_servers</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-table-options.html">37.30. <code class="literal">foreign_table_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-tables.html">37.31. <code class="literal">foreign_tables</code></a></span></dt><dt><span class="sect1"><a href="infoschema-key-column-usage.html">37.32. <code class="literal">key_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-parameters.html">37.33. <code class="literal">parameters</code></a></span></dt><dt><span class="sect1"><a href="infoschema-referential-constraints.html">37.34. <code class="literal">referential_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-column-grants.html">37.35. <code class="literal">role_column_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-routine-grants.html">37.36. <code class="literal">role_routine_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-table-grants.html">37.37. <code class="literal">role_table_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-udt-grants.html">37.38. <code class="literal">role_udt_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-usage-grants.html">37.39. <code class="literal">role_usage_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-column-usage.html">37.40. <code class="literal">routine_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-privileges.html">37.41. <code class="literal">routine_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-routine-usage.html">37.42. <code class="literal">routine_routine_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-sequence-usage.html">37.43. <code class="literal">routine_sequence_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-table-usage.html">37.44. <code class="literal">routine_table_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routines.html">37.45. <code class="literal">routines</code></a></span></dt><dt><span class="sect1"><a href="infoschema-schemata.html">37.46. <code class="literal">schemata</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sequences.html">37.47. <code class="literal">sequences</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-features.html">37.48. <code class="literal">sql_features</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-implementation-info.html">37.49. <code class="literal">sql_implementation_info</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-parts.html">37.50. <code class="literal">sql_parts</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-sizing.html">37.51. <code class="literal">sql_sizing</code></a></span></dt><dt><span class="sect1"><a href="infoschema-table-constraints.html">37.52. <code class="literal">table_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-table-privileges.html">37.53. <code class="literal">table_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-tables.html">37.54. <code class="literal">tables</code></a></span></dt><dt><span class="sect1"><a href="infoschema-transforms.html">37.55. <code class="literal">transforms</code></a></span></dt><dt><span class="sect1"><a href="infoschema-triggered-update-columns.html">37.56. <code class="literal">triggered_update_columns</code></a></span></dt><dt><span class="sect1"><a href="infoschema-triggers.html">37.57. <code class="literal">triggers</code></a></span></dt><dt><span class="sect1"><a href="infoschema-udt-privileges.html">37.58. <code class="literal">udt_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-usage-privileges.html">37.59. <code class="literal">usage_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-user-defined-types.html">37.60. <code class="literal">user_defined_types</code></a></span></dt><dt><span class="sect1"><a href="infoschema-user-mapping-options.html">37.61. <code class="literal">user_mapping_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-user-mappings.html">37.62. <code class="literal">user_mappings</code></a></span></dt><dt><span class="sect1"><a href="infoschema-view-column-usage.html">37.63. <code class="literal">view_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-view-routine-usage.html">37.64. <code class="literal">view_routine_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-view-table-usage.html">37.65. <code class="literal">view_table_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-views.html">37.66. <code class="literal">views</code></a></span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="regress-coverage.html" title="33.5. Test Coverage Examination">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq.html" title="Chapter 34. libpq — C Library">Next</a></td></tr><tr><td width="40%" align="left" valign="top">33.5. Test Coverage Examination </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 34. <span class="application">libpq</span> — C Library</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/collation.html b/doc/src/sgml/html/collation.html
new file mode 100644
index 0000000..f84a7e9
--- /dev/null
+++ b/doc/src/sgml/html/collation.html
@@ -0,0 +1,417 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>24.2. Collation Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="locale.html" title="24.1. Locale Support" /><link rel="next" href="multibyte.html" title="24.3. Character Set Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">24.2. Collation Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="locale.html" title="24.1. Locale Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="charset.html" title="Chapter 24. Localization">Up</a></td><th width="60%" align="center">Chapter 24. Localization</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="multibyte.html" title="24.3. Character Set Support">Next</a></td></tr></table><hr /></div><div class="sect1" id="COLLATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">24.2. Collation Support</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="collation.html#id-1.6.11.4.4">24.2.1. Concepts</a></span></dt><dt><span class="sect2"><a href="collation.html#COLLATION-MANAGING">24.2.2. Managing Collations</a></span></dt></dl></div><a id="id-1.6.11.4.2" class="indexterm"></a><p>
+ The collation feature allows specifying the sort order and character
+ classification behavior of data per-column, or even per-operation.
+ This alleviates the restriction that the
+ <code class="symbol">LC_COLLATE</code> and <code class="symbol">LC_CTYPE</code> settings
+ of a database cannot be changed after its creation.
+ </p><div class="sect2" id="id-1.6.11.4.4"><div class="titlepage"><div><div><h3 class="title">24.2.1. Concepts</h3></div></div></div><p>
+ Conceptually, every expression of a collatable data type has a
+ collation. (The built-in collatable data types are
+ <code class="type">text</code>, <code class="type">varchar</code>, and <code class="type">char</code>.
+ User-defined base types can also be marked collatable, and of course
+ a <a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN" title="Domain">domain</a></em></a> over a
+ collatable data type is collatable.) If the
+ expression is a column reference, the collation of the expression is the
+ defined collation of the column. If the expression is a constant, the
+ collation is the default collation of the data type of the
+ constant. The collation of a more complex expression is derived
+ from the collations of its inputs, as described below.
+ </p><p>
+ The collation of an expression can be the <span class="quote">“<span class="quote">default</span>”</span>
+ collation, which means the locale settings defined for the
+ database. It is also possible for an expression's collation to be
+ indeterminate. In such cases, ordering operations and other
+ operations that need to know the collation will fail.
+ </p><p>
+ When the database system has to perform an ordering or a character
+ classification, it uses the collation of the input expression. This
+ happens, for example, with <code class="literal">ORDER BY</code> clauses
+ and function or operator calls such as <code class="literal">&lt;</code>.
+ The collation to apply for an <code class="literal">ORDER BY</code> clause
+ is simply the collation of the sort key. The collation to apply for a
+ function or operator call is derived from the arguments, as described
+ below. In addition to comparison operators, collations are taken into
+ account by functions that convert between lower and upper case
+ letters, such as <code class="function">lower</code>, <code class="function">upper</code>, and
+ <code class="function">initcap</code>; by pattern matching operators; and by
+ <code class="function">to_char</code> and related functions.
+ </p><p>
+ For a function or operator call, the collation that is derived by
+ examining the argument collations is used at run time for performing
+ the specified operation. If the result of the function or operator
+ call is of a collatable data type, the collation is also used at parse
+ time as the defined collation of the function or operator expression,
+ in case there is a surrounding expression that requires knowledge of
+ its collation.
+ </p><p>
+ The <em class="firstterm">collation derivation</em> of an expression can be
+ implicit or explicit. This distinction affects how collations are
+ combined when multiple different collations appear in an
+ expression. An explicit collation derivation occurs when a
+ <code class="literal">COLLATE</code> clause is used; all other collation
+ derivations are implicit. When multiple collations need to be
+ combined, for example in a function call, the following rules are
+ used:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ If any input expression has an explicit collation derivation, then
+ all explicitly derived collations among the input expressions must be
+ the same, otherwise an error is raised. If any explicitly
+ derived collation is present, that is the result of the
+ collation combination.
+ </p></li><li class="listitem"><p>
+ Otherwise, all input expressions must have the same implicit
+ collation derivation or the default collation. If any non-default
+ collation is present, that is the result of the collation combination.
+ Otherwise, the result is the default collation.
+ </p></li><li class="listitem"><p>
+ If there are conflicting non-default implicit collations among the
+ input expressions, then the combination is deemed to have indeterminate
+ collation. This is not an error condition unless the particular
+ function being invoked requires knowledge of the collation it should
+ apply. If it does, an error will be raised at run-time.
+ </p></li></ol></div><p>
+
+ For example, consider this table definition:
+</p><pre class="programlisting">
+CREATE TABLE test1 (
+ a text COLLATE "de_DE",
+ b text COLLATE "es_ES",
+ ...
+);
+</pre><p>
+
+ Then in
+</p><pre class="programlisting">
+SELECT a &lt; 'foo' FROM test1;
+</pre><p>
+ the <code class="literal">&lt;</code> comparison is performed according to
+ <code class="literal">de_DE</code> rules, because the expression combines an
+ implicitly derived collation with the default collation. But in
+</p><pre class="programlisting">
+SELECT a &lt; ('foo' COLLATE "fr_FR") FROM test1;
+</pre><p>
+ the comparison is performed using <code class="literal">fr_FR</code> rules,
+ because the explicit collation derivation overrides the implicit one.
+ Furthermore, given
+</p><pre class="programlisting">
+SELECT a &lt; b FROM test1;
+</pre><p>
+ the parser cannot determine which collation to apply, since the
+ <code class="structfield">a</code> and <code class="structfield">b</code> columns have conflicting
+ implicit collations. Since the <code class="literal">&lt;</code> operator
+ does need to know which collation to use, this will result in an
+ error. The error can be resolved by attaching an explicit collation
+ specifier to either input expression, thus:
+</p><pre class="programlisting">
+SELECT a &lt; b COLLATE "de_DE" FROM test1;
+</pre><p>
+ or equivalently
+</p><pre class="programlisting">
+SELECT a COLLATE "de_DE" &lt; b FROM test1;
+</pre><p>
+ On the other hand, the structurally similar case
+</p><pre class="programlisting">
+SELECT a || b FROM test1;
+</pre><p>
+ does not result in an error, because the <code class="literal">||</code> operator
+ does not care about collations: its result is the same regardless
+ of the collation.
+ </p><p>
+ The collation assigned to a function or operator's combined input
+ expressions is also considered to apply to the function or operator's
+ result, if the function or operator delivers a result of a collatable
+ data type. So, in
+</p><pre class="programlisting">
+SELECT * FROM test1 ORDER BY a || 'foo';
+</pre><p>
+ the ordering will be done according to <code class="literal">de_DE</code> rules.
+ But this query:
+</p><pre class="programlisting">
+SELECT * FROM test1 ORDER BY a || b;
+</pre><p>
+ results in an error, because even though the <code class="literal">||</code> operator
+ doesn't need to know a collation, the <code class="literal">ORDER BY</code> clause does.
+ As before, the conflict can be resolved with an explicit collation
+ specifier:
+</p><pre class="programlisting">
+SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
+</pre><p>
+ </p></div><div class="sect2" id="COLLATION-MANAGING"><div class="titlepage"><div><div><h3 class="title">24.2.2. Managing Collations</h3></div></div></div><p>
+ A collation is an SQL schema object that maps an SQL name to locales
+ provided by libraries installed in the operating system. A collation
+ definition has a <em class="firstterm">provider</em> that specifies which
+ library supplies the locale data. One standard provider name
+ is <code class="literal">libc</code>, which uses the locales provided by the
+ operating system C library. These are the locales used by most tools
+ provided by the operating system. Another provider
+ is <code class="literal">icu</code>, which uses the external
+ ICU<a id="id-1.6.11.4.5.2.4" class="indexterm"></a> library. ICU locales can only be
+ used if support for ICU was configured when PostgreSQL was built.
+ </p><p>
+ A collation object provided by <code class="literal">libc</code> maps to a
+ combination of <code class="symbol">LC_COLLATE</code> and <code class="symbol">LC_CTYPE</code>
+ settings, as accepted by the <code class="literal">setlocale()</code> system library call. (As
+ the name would suggest, the main purpose of a collation is to set
+ <code class="symbol">LC_COLLATE</code>, which controls the sort order. But
+ it is rarely necessary in practice to have an
+ <code class="symbol">LC_CTYPE</code> setting that is different from
+ <code class="symbol">LC_COLLATE</code>, so it is more convenient to collect
+ these under one concept than to create another infrastructure for
+ setting <code class="symbol">LC_CTYPE</code> per expression.) Also,
+ a <code class="literal">libc</code> collation
+ is tied to a character set encoding (see <a class="xref" href="multibyte.html" title="24.3. Character Set Support">Section 24.3</a>).
+ The same collation name may exist for different encodings.
+ </p><p>
+ A collation object provided by <code class="literal">icu</code> maps to a named
+ collator provided by the ICU library. ICU does not support
+ separate <span class="quote">“<span class="quote">collate</span>”</span> and <span class="quote">“<span class="quote">ctype</span>”</span> settings, so
+ they are always the same. Also, ICU collations are independent of the
+ encoding, so there is always only one ICU collation of a given name in
+ a database.
+ </p><div class="sect3" id="id-1.6.11.4.5.5"><div class="titlepage"><div><div><h4 class="title">24.2.2.1. Standard Collations</h4></div></div></div><p>
+ On all platforms, the collations named <code class="literal">default</code>,
+ <code class="literal">C</code>, and <code class="literal">POSIX</code> are available. Additional
+ collations may be available depending on operating system support.
+ The <code class="literal">default</code> collation selects the <code class="symbol">LC_COLLATE</code>
+ and <code class="symbol">LC_CTYPE</code> values specified at database creation time.
+ The <code class="literal">C</code> and <code class="literal">POSIX</code> collations both specify
+ <span class="quote">“<span class="quote">traditional C</span>”</span> behavior, in which only the ASCII letters
+ <span class="quote">“<span class="quote"><code class="literal">A</code></span>”</span> through <span class="quote">“<span class="quote"><code class="literal">Z</code></span>”</span>
+ are treated as letters, and sorting is done strictly by character
+ code byte values.
+ </p><p>
+ Additionally, the SQL standard collation name <code class="literal">ucs_basic</code>
+ is available for encoding <code class="literal">UTF8</code>. It is equivalent
+ to <code class="literal">C</code> and sorts by Unicode code point.
+ </p></div><div class="sect3" id="id-1.6.11.4.5.6"><div class="titlepage"><div><div><h4 class="title">24.2.2.2. Predefined Collations</h4></div></div></div><p>
+ If the operating system provides support for using multiple locales
+ within a single program (<code class="function">newlocale</code> and related functions),
+ or if support for ICU is configured,
+ then when a database cluster is initialized, <code class="command">initdb</code>
+ populates the system catalog <code class="literal">pg_collation</code> with
+ collations based on all the locales it finds in the operating
+ system at the time.
+ </p><p>
+ To inspect the currently available locales, use the query <code class="literal">SELECT
+ * FROM pg_collation</code>, or the command <code class="command">\dOS+</code>
+ in <span class="application">psql</span>.
+ </p><div class="sect4" id="id-1.6.11.4.5.6.4"><div class="titlepage"><div><div><h5 class="title">24.2.2.2.1. libc Collations</h5></div></div></div><p>
+ For example, the operating system might
+ provide a locale named <code class="literal">de_DE.utf8</code>.
+ <code class="command">initdb</code> would then create a collation named
+ <code class="literal">de_DE.utf8</code> for encoding <code class="literal">UTF8</code>
+ that has both <code class="symbol">LC_COLLATE</code> and
+ <code class="symbol">LC_CTYPE</code> set to <code class="literal">de_DE.utf8</code>.
+ It will also create a collation with the <code class="literal">.utf8</code>
+ tag stripped off the name. So you could also use the collation
+ under the name <code class="literal">de_DE</code>, which is less cumbersome
+ to write and makes the name less encoding-dependent. Note that,
+ nevertheless, the initial set of collation names is
+ platform-dependent.
+ </p><p>
+ The default set of collations provided by <code class="literal">libc</code> map
+ directly to the locales installed in the operating system, which can be
+ listed using the command <code class="literal">locale -a</code>. In case
+ a <code class="literal">libc</code> collation is needed that has different values
+ for <code class="symbol">LC_COLLATE</code> and <code class="symbol">LC_CTYPE</code>, or if new
+ locales are installed in the operating system after the database system
+ was initialized, then a new collation may be created using
+ the <a class="xref" href="sql-createcollation.html" title="CREATE COLLATION"><span class="refentrytitle">CREATE COLLATION</span></a> command.
+ New operating system locales can also be imported en masse using
+ the <a class="link" href="functions-admin.html#FUNCTIONS-ADMIN-COLLATION" title="Table 9.96. Collation Management Functions"><code class="function">pg_import_system_collations()</code></a> function.
+ </p><p>
+ Within any particular database, only collations that use that
+ database's encoding are of interest. Other entries in
+ <code class="literal">pg_collation</code> are ignored. Thus, a stripped collation
+ name such as <code class="literal">de_DE</code> can be considered unique
+ within a given database even though it would not be unique globally.
+ Use of the stripped collation names is recommended, since it will
+ make one fewer thing you need to change if you decide to change to
+ another database encoding. Note however that the <code class="literal">default</code>,
+ <code class="literal">C</code>, and <code class="literal">POSIX</code> collations can be used regardless of
+ the database encoding.
+ </p><p>
+ <span class="productname">PostgreSQL</span> considers distinct collation
+ objects to be incompatible even when they have identical properties.
+ Thus for example,
+</p><pre class="programlisting">
+SELECT a COLLATE "C" &lt; b COLLATE "POSIX" FROM test1;
+</pre><p>
+ will draw an error even though the <code class="literal">C</code> and <code class="literal">POSIX</code>
+ collations have identical behaviors. Mixing stripped and non-stripped
+ collation names is therefore not recommended.
+ </p></div><div class="sect4" id="id-1.6.11.4.5.6.5"><div class="titlepage"><div><div><h5 class="title">24.2.2.2.2. ICU Collations</h5></div></div></div><p>
+ With ICU, it is not sensible to enumerate all possible locale names. ICU
+ uses a particular naming system for locales, but there are many more ways
+ to name a locale than there are actually distinct locales.
+ <code class="command">initdb</code> uses the ICU APIs to extract a set of distinct
+ locales to populate the initial set of collations. Collations provided by
+ ICU are created in the SQL environment with names in BCP 47 language tag
+ format, with a <span class="quote">“<span class="quote">private use</span>”</span>
+ extension <code class="literal">-x-icu</code> appended, to distinguish them from
+ libc locales.
+ </p><p>
+ Here are some example collations that might be created:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">de-x-icu</code></span></dt><dd><p>German collation, default variant</p></dd><dt><span class="term"><code class="literal">de-AT-x-icu</code></span></dt><dd><p>German collation for Austria, default variant</p><p>
+ (There are also, say, <code class="literal">de-DE-x-icu</code>
+ or <code class="literal">de-CH-x-icu</code>, but as of this writing, they are
+ equivalent to <code class="literal">de-x-icu</code>.)
+ </p></dd><dt><span class="term"><code class="literal">und-x-icu</code> (for <span class="quote">“<span class="quote">undefined</span>”</span>)</span></dt><dd><p>
+ ICU <span class="quote">“<span class="quote">root</span>”</span> collation. Use this to get a reasonable
+ language-agnostic sort order.
+ </p></dd></dl></div><p>
+ </p><p>
+ Some (less frequently used) encodings are not supported by ICU. When the
+ database encoding is one of these, ICU collation entries
+ in <code class="literal">pg_collation</code> are ignored. Attempting to use one
+ will draw an error along the lines of <span class="quote">“<span class="quote">collation "de-x-icu" for
+ encoding "WIN874" does not exist</span>”</span>.
+ </p></div></div><div class="sect3" id="COLLATION-CREATE"><div class="titlepage"><div><div><h4 class="title">24.2.2.3. Creating New Collation Objects</h4></div></div></div><p>
+ If the standard and predefined collations are not sufficient, users can
+ create their own collation objects using the SQL
+ command <a class="xref" href="sql-createcollation.html" title="CREATE COLLATION"><span class="refentrytitle">CREATE COLLATION</span></a>.
+ </p><p>
+ The standard and predefined collations are in the
+ schema <code class="literal">pg_catalog</code>, like all predefined objects.
+ User-defined collations should be created in user schemas. This also
+ ensures that they are saved by <code class="command">pg_dump</code>.
+ </p><div class="sect4" id="id-1.6.11.4.5.7.4"><div class="titlepage"><div><div><h5 class="title">24.2.2.3.1. libc Collations</h5></div></div></div><p>
+ New libc collations can be created like this:
+</p><pre class="programlisting">
+CREATE COLLATION german (provider = libc, locale = 'de_DE');
+</pre><p>
+ The exact values that are acceptable for the <code class="literal">locale</code>
+ clause in this command depend on the operating system. On Unix-like
+ systems, the command <code class="literal">locale -a</code> will show a list.
+ </p><p>
+ Since the predefined libc collations already include all collations
+ defined in the operating system when the database instance is
+ initialized, it is not often necessary to manually create new ones.
+ Reasons might be if a different naming system is desired (in which case
+ see also <a class="xref" href="collation.html#COLLATION-COPY" title="24.2.2.3.3. Copying Collations">Section 24.2.2.3.3</a>) or if the operating system has
+ been upgraded to provide new locale definitions (in which case see
+ also <a class="link" href="functions-admin.html#FUNCTIONS-ADMIN-COLLATION" title="Table 9.96. Collation Management Functions"><code class="function">pg_import_system_collations()</code></a>).
+ </p></div><div class="sect4" id="id-1.6.11.4.5.7.5"><div class="titlepage"><div><div><h5 class="title">24.2.2.3.2. ICU Collations</h5></div></div></div><p>
+ ICU allows collations to be customized beyond the basic language+country
+ set that is preloaded by <code class="command">initdb</code>. Users are encouraged
+ to define their own collation objects that make use of these facilities to
+ suit the sorting behavior to their requirements.
+ See <a class="ulink" href="https://unicode-org.github.io/icu/userguide/locale/" target="_top">https://unicode-org.github.io/icu/userguide/locale/</a>
+ and <a class="ulink" href="https://unicode-org.github.io/icu/userguide/collation/api.html" target="_top">https://unicode-org.github.io/icu/userguide/collation/api.html</a> for
+ information on ICU locale naming. The set of acceptable names and
+ attributes depends on the particular ICU version.
+ </p><p>
+ Here are some examples:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk');</code><br /></span><span class="term"><code class="literal">CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook');</code></span></dt><dd><p>German collation with phone book collation type</p><p>
+ The first example selects the ICU locale using a <span class="quote">“<span class="quote">language
+ tag</span>”</span> per BCP 47. The second example uses the traditional
+ ICU-specific locale syntax. The first style is preferred going
+ forward, but it is not supported by older ICU versions.
+ </p><p>
+ Note that you can name the collation objects in the SQL environment
+ anything you want. In this example, we follow the naming style that
+ the predefined collations use, which in turn also follow BCP 47, but
+ that is not required for user-defined collations.
+ </p></dd><dt><span class="term"><code class="literal">CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji');</code><br /></span><span class="term"><code class="literal">CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji');</code></span></dt><dd><p>
+ Root collation with Emoji collation type, per Unicode Technical Standard #51
+ </p><p>
+ Observe how in the traditional ICU locale naming system, the root
+ locale is selected by an empty string.
+ </p></dd><dt><span class="term"><code class="literal">CREATE COLLATION latinlast (provider = icu, locale = 'en-u-kr-grek-latn');</code><br /></span><span class="term"><code class="literal">CREATE COLLATION latinlast (provider = icu, locale = 'en@colReorder=grek-latn');</code></span></dt><dd><p>
+ Sort Greek letters before Latin ones. (The default is Latin before Greek.)
+ </p></dd><dt><span class="term"><code class="literal">CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper');</code><br /></span><span class="term"><code class="literal">CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper');</code></span></dt><dd><p>
+ Sort upper-case letters before lower-case letters. (The default is
+ lower-case letters first.)
+ </p></dd><dt><span class="term"><code class="literal">CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-grek-latn');</code><br /></span><span class="term"><code class="literal">CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=grek-latn');</code></span></dt><dd><p>
+ Combines both of the above options.
+ </p></dd><dt><span class="term"><code class="literal">CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true');</code><br /></span><span class="term"><code class="literal">CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes');</code></span></dt><dd><p>
+ Numeric ordering, sorts sequences of digits by their numeric value,
+ for example: <code class="literal">A-21</code> &lt; <code class="literal">A-123</code>
+ (also known as natural sort).
+ </p></dd></dl></div><p>
+
+ See <a class="ulink" href="https://www.unicode.org/reports/tr35/tr35-collation.html" target="_top">Unicode
+ Technical Standard #35</a>
+ and <a class="ulink" href="https://tools.ietf.org/html/bcp47" target="_top">BCP 47</a> for
+ details. The list of possible collation types (<code class="literal">co</code>
+ subtag) can be found in
+ the <a class="ulink" href="https://github.com/unicode-org/cldr/blob/master/common/bcp47/collation.xml" target="_top">CLDR
+ repository</a>.
+ </p><p>
+ Note that while this system allows creating collations that <span class="quote">“<span class="quote">ignore
+ case</span>”</span> or <span class="quote">“<span class="quote">ignore accents</span>”</span> or similar (using the
+ <code class="literal">ks</code> key), in order for such collations to act in a
+ truly case- or accent-insensitive manner, they also need to be declared as not
+ <em class="firstterm">deterministic</em> in <code class="command">CREATE COLLATION</code>;
+ see <a class="xref" href="collation.html#COLLATION-NONDETERMINISTIC" title="24.2.2.4. Nondeterministic Collations">Section 24.2.2.4</a>.
+ Otherwise, any strings that compare equal according to the collation but
+ are not byte-wise equal will be sorted according to their byte values.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ By design, ICU will accept almost any string as a locale name and match
+ it to the closest locale it can provide, using the fallback procedure
+ described in its documentation. Thus, there will be no direct feedback
+ if a collation specification is composed using features that the given
+ ICU installation does not actually support. It is therefore recommended
+ to create application-level test cases to check that the collation
+ definitions satisfy one's requirements.
+ </p></div></div><div class="sect4" id="COLLATION-COPY"><div class="titlepage"><div><div><h5 class="title">24.2.2.3.3. Copying Collations</h5></div></div></div><p>
+ The command <a class="xref" href="sql-createcollation.html" title="CREATE COLLATION"><span class="refentrytitle">CREATE COLLATION</span></a> can also be used to
+ create a new collation from an existing collation, which can be useful to
+ be able to use operating-system-independent collation names in
+ applications, create compatibility names, or use an ICU-provided collation
+ under a more readable name. For example:
+</p><pre class="programlisting">
+CREATE COLLATION german FROM "de_DE";
+CREATE COLLATION french FROM "fr-x-icu";
+</pre><p>
+ </p></div></div><div class="sect3" id="COLLATION-NONDETERMINISTIC"><div class="titlepage"><div><div><h4 class="title">24.2.2.4. Nondeterministic Collations</h4></div></div></div><p>
+ A collation is either <em class="firstterm">deterministic</em> or
+ <em class="firstterm">nondeterministic</em>. A deterministic collation uses
+ deterministic comparisons, which means that it considers strings to be
+ equal only if they consist of the same byte sequence. Nondeterministic
+ comparison may determine strings to be equal even if they consist of
+ different bytes. Typical situations include case-insensitive comparison,
+ accent-insensitive comparison, as well as comparison of strings in
+ different Unicode normal forms. It is up to the collation provider to
+ actually implement such insensitive comparisons; the deterministic flag
+ only determines whether ties are to be broken using bytewise comparison.
+ See also <a class="ulink" href="https://www.unicode.org/reports/tr10" target="_top">Unicode Technical
+ Standard 10</a> for more information on the terminology.
+ </p><p>
+ To create a nondeterministic collation, specify the property
+ <code class="literal">deterministic = false</code> to <code class="command">CREATE
+ COLLATION</code>, for example:
+</p><pre class="programlisting">
+CREATE COLLATION ndcoll (provider = icu, locale = 'und', deterministic = false);
+</pre><p>
+ This example would use the standard Unicode collation in a
+ nondeterministic way. In particular, this would allow strings in
+ different normal forms to be compared correctly. More interesting
+ examples make use of the ICU customization facilities explained above.
+ For example:
+</p><pre class="programlisting">
+CREATE COLLATION case_insensitive (provider = icu, locale = 'und-u-ks-level2', deterministic = false);
+CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-true', deterministic = false);
+</pre><p>
+ </p><p>
+ All standard and predefined collations are deterministic, all
+ user-defined collations are deterministic by default. While
+ nondeterministic collations give a more <span class="quote">“<span class="quote">correct</span>”</span> behavior,
+ especially when considering the full power of Unicode and its many
+ special cases, they also have some drawbacks. Foremost, their use leads
+ to a performance penalty. Note, in particular, that B-tree cannot use
+ deduplication with indexes that use a nondeterministic collation. Also,
+ certain operations are not possible with nondeterministic collations,
+ such as pattern matching operations. Therefore, they should be used
+ only in cases where they are specifically wanted.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ To deal with text in different Unicode normalization forms, it is also
+ an option to use the functions/expressions
+ <code class="function">normalize</code> and <code class="literal">is normalized</code> to
+ preprocess or check the strings, instead of using nondeterministic
+ collations. There are different trade-offs for each approach.
+ </p></div></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="locale.html" title="24.1. Locale Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="charset.html" title="Chapter 24. Localization">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="multibyte.html" title="24.3. Character Set Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">24.1. Locale Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 24.3. Character Set Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/color-when.html b/doc/src/sgml/html/color-when.html
new file mode 100644
index 0000000..030e19b
--- /dev/null
+++ b/doc/src/sgml/html/color-when.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>N.1. When Color is Used</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="color.html" title="Appendix N. Color Support" /><link rel="next" href="color-which.html" title="N.2. Configuring the Colors" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">N.1. When Color is Used</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="color.html" title="Appendix N. Color Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="color.html" title="Appendix N. Color Support">Up</a></td><th width="60%" align="center">Appendix N. Color Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="color-which.html" title="N.2. Configuring the Colors">Next</a></td></tr></table><hr /></div><div class="sect1" id="COLOR-WHEN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">N.1. When Color is Used</h2></div></div></div><p>
+ To use colorized output, set the environment variable
+ <code class="envar">PG_COLOR</code><a id="id-1.11.15.4.2.2" class="indexterm"></a>
+ as follows:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ If the value is <code class="literal">always</code>, then color is used.
+ </p></li><li class="listitem"><p>
+ If the value is <code class="literal">auto</code> and the standard error stream
+ is associated with a terminal device, then color is used.
+ </p></li><li class="listitem"><p>
+ Otherwise, color is not used.
+ </p></li></ol></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="color.html" title="Appendix N. Color Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="color.html" title="Appendix N. Color Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="color-which.html" title="N.2. Configuring the Colors">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix N. Color Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> N.2. Configuring the Colors</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/color-which.html b/doc/src/sgml/html/color-which.html
new file mode 100644
index 0000000..9fde271
--- /dev/null
+++ b/doc/src/sgml/html/color-which.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>N.2. Configuring the Colors</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="color-when.html" title="N.1. When Color is Used" /><link rel="next" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">N.2. Configuring the Colors</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="color-when.html" title="N.1. When Color is Used">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="color.html" title="Appendix N. Color Support">Up</a></td><th width="60%" align="center">Appendix N. Color Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Next</a></td></tr></table><hr /></div><div class="sect1" id="COLOR-WHICH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">N.2. Configuring the Colors</h2></div></div></div><p>
+ The actual colors to be used are configured using the environment variable
+ <code class="envar">PG_COLORS</code><a id="id-1.11.15.5.2.2" class="indexterm"></a>
+ (note plural). The value is a colon-separated list of
+ <code class="literal"><em class="replaceable"><code>key</code></em>=<em class="replaceable"><code>value</code></em></code>
+ pairs. The keys specify what the color is to be used for. The values are
+ SGR (Select Graphic Rendition) specifications, which are interpreted by the
+ terminal.
+ </p><p>
+ The following keys are currently in use:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">error</code></span></dt><dd><p>used to highlight the text <span class="quote">“<span class="quote">error</span>”</span> in error messages</p></dd><dt><span class="term"><code class="literal">warning</code></span></dt><dd><p>used to highlight the text <span class="quote">“<span class="quote">warning</span>”</span> in warning
+ messages</p></dd><dt><span class="term"><code class="literal">note</code></span></dt><dd><p>used to highlight the text <span class="quote">“<span class="quote">detail</span>”</span> and
+ <span class="quote">“<span class="quote">hint</span>”</span> in such messages</p></dd><dt><span class="term"><code class="literal">locus</code></span></dt><dd><p>used to highlight location information (e.g., program name and
+ file name) in messages</p></dd></dl></div><p>
+ </p><p>
+ The default value is
+ <code class="literal">error=01;31:warning=01;35:note=01;36:locus=01</code>
+ (<code class="literal">01;31</code> = bold red, <code class="literal">01;35</code> = bold
+ magenta, <code class="literal">01;36</code> = bold cyan, <code class="literal">01</code> = bold
+ default color).
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ This color specification format is also used by other software packages
+ such as <span class="productname">GCC</span>, <span class="productname">GNU
+ coreutils</span>, and <span class="productname">GNU grep</span>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="color-when.html" title="N.1. When Color is Used">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="color.html" title="Appendix N. Color Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">N.1. When Color is Used </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix O. Obsolete or Renamed Features</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/color.html b/doc/src/sgml/html/color.html
new file mode 100644
index 0000000..e40a4b6
--- /dev/null
+++ b/doc/src/sgml/html/color.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix N. Color Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="glossary.html" title="Appendix M. Glossary" /><link rel="next" href="color-when.html" title="N.1. When Color is Used" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix N. Color Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="glossary.html" title="Appendix M. Glossary">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="color-when.html" title="N.1. When Color is Used">Next</a></td></tr></table><hr /></div><div class="appendix" id="COLOR"><div class="titlepage"><div><div><h2 class="title">Appendix N. Color Support</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="color-when.html">N.1. When Color is Used</a></span></dt><dt><span class="sect1"><a href="color-which.html">N.2. Configuring the Colors</a></span></dt></dl></div><a id="id-1.11.15.2" class="indexterm"></a><p>
+ Most programs in the PostgreSQL package can produce colorized console
+ output. This appendix describes how that is configured.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="glossary.html" title="Appendix M. Glossary">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="color-when.html" title="N.1. When Color is Used">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix M. Glossary </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> N.1. When Color is Used</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/config-setting.html b/doc/src/sgml/html/config-setting.html
new file mode 100644
index 0000000..fdb47f1
--- /dev/null
+++ b/doc/src/sgml/html/config-setting.html
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.1. Setting Parameters</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config.html" title="Chapter 20. Server Configuration" /><link rel="next" href="runtime-config-file-locations.html" title="20.2. File Locations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.1. Setting Parameters</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config.html" title="Chapter 20. Server Configuration">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-file-locations.html" title="20.2. File Locations">Next</a></td></tr></table><hr /></div><div class="sect1" id="CONFIG-SETTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.1. Setting Parameters</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="config-setting.html#CONFIG-SETTING-NAMES-VALUES">20.1.1. Parameter Names and Values</a></span></dt><dt><span class="sect2"><a href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE">20.1.2. Parameter Interaction via the Configuration File</a></span></dt><dt><span class="sect2"><a href="config-setting.html#CONFIG-SETTING-SQL-COMMAND-INTERACTION">20.1.3. Parameter Interaction via SQL</a></span></dt><dt><span class="sect2"><a href="config-setting.html#id-1.6.7.4.5">20.1.4. Parameter Interaction via the Shell</a></span></dt><dt><span class="sect2"><a href="config-setting.html#CONFIG-INCLUDES">20.1.5. Managing Configuration File Contents</a></span></dt></dl></div><div class="sect2" id="CONFIG-SETTING-NAMES-VALUES"><div class="titlepage"><div><div><h3 class="title">20.1.1. Parameter Names and Values</h3></div></div></div><p>
+ All parameter names are case-insensitive. Every parameter takes a
+ value of one of five types: boolean, string, integer, floating point,
+ or enumerated (enum). The type determines the syntax for setting the
+ parameter:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <span class="emphasis"><em>Boolean:</em></span>
+ Values can be written as
+ <code class="literal">on</code>,
+ <code class="literal">off</code>,
+ <code class="literal">true</code>,
+ <code class="literal">false</code>,
+ <code class="literal">yes</code>,
+ <code class="literal">no</code>,
+ <code class="literal">1</code>,
+ <code class="literal">0</code>
+ (all case-insensitive) or any unambiguous prefix of one of these.
+ </p></li><li class="listitem"><p>
+ <span class="emphasis"><em>String:</em></span>
+ In general, enclose the value in single quotes, doubling any single
+ quotes within the value. Quotes can usually be omitted if the value
+ is a simple number or identifier, however.
+ (Values that match an SQL keyword require quoting in some contexts.)
+ </p></li><li class="listitem"><p>
+ <span class="emphasis"><em>Numeric (integer and floating point):</em></span>
+ Numeric parameters can be specified in the customary integer and
+ floating-point formats; fractional values are rounded to the nearest
+ integer if the parameter is of integer type. Integer parameters
+ additionally accept hexadecimal input (beginning
+ with <code class="literal">0x</code>) and octal input (beginning
+ with <code class="literal">0</code>), but these formats cannot have a fraction.
+ Do not use thousands separators.
+ Quotes are not required, except for hexadecimal input.
+ </p></li><li class="listitem"><p>
+ <span class="emphasis"><em>Numeric with Unit:</em></span>
+ Some numeric parameters have an implicit unit, because they describe
+ quantities of memory or time. The unit might be bytes, kilobytes, blocks
+ (typically eight kilobytes), milliseconds, seconds, or minutes.
+ An unadorned numeric value for one of these settings will use the
+ setting's default unit, which can be learned from
+ <code class="structname">pg_settings</code>.<code class="structfield">unit</code>.
+ For convenience, settings can be given with a unit specified explicitly,
+ for example <code class="literal">'120 ms'</code> for a time value, and they will be
+ converted to whatever the parameter's actual unit is. Note that the
+ value must be written as a string (with quotes) to use this feature.
+ The unit name is case-sensitive, and there can be whitespace between
+ the numeric value and the unit.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ Valid memory units are <code class="literal">B</code> (bytes),
+ <code class="literal">kB</code> (kilobytes),
+ <code class="literal">MB</code> (megabytes), <code class="literal">GB</code>
+ (gigabytes), and <code class="literal">TB</code> (terabytes).
+ The multiplier for memory units is 1024, not 1000.
+ </p></li><li class="listitem"><p>
+ Valid time units are
+ <code class="literal">us</code> (microseconds),
+ <code class="literal">ms</code> (milliseconds),
+ <code class="literal">s</code> (seconds), <code class="literal">min</code> (minutes),
+ <code class="literal">h</code> (hours), and <code class="literal">d</code> (days).
+ </p></li></ul></div><p>
+
+ If a fractional value is specified with a unit, it will be rounded
+ to a multiple of the next smaller unit if there is one.
+ For example, <code class="literal">30.1 GB</code> will be converted
+ to <code class="literal">30822 MB</code> not <code class="literal">32319628902 B</code>.
+ If the parameter is of integer type, a final rounding to integer
+ occurs after any unit conversion.
+ </p></li><li class="listitem"><p>
+ <span class="emphasis"><em>Enumerated:</em></span>
+ Enumerated-type parameters are written in the same way as string
+ parameters, but are restricted to have one of a limited set of
+ values. The values allowable for such a parameter can be found from
+ <code class="structname">pg_settings</code>.<code class="structfield">enumvals</code>.
+ Enum parameter values are case-insensitive.
+ </p></li></ul></div></div><div class="sect2" id="CONFIG-SETTING-CONFIGURATION-FILE"><div class="titlepage"><div><div><h3 class="title">20.1.2. Parameter Interaction via the Configuration File</h3></div></div></div><p>
+ The most fundamental way to set these parameters is to edit the file
+ <code class="filename">postgresql.conf</code><a id="id-1.6.7.4.3.2.2" class="indexterm"></a>,
+ which is normally kept in the data directory. A default copy is
+ installed when the database cluster directory is initialized.
+ An example of what this file might look like is:
+</p><pre class="programlisting">
+# This is a comment
+log_connections = yes
+log_destination = 'syslog'
+search_path = '"$user", public'
+shared_buffers = 128MB
+</pre><p>
+ One parameter is specified per line. The equal sign between name and
+ value is optional. Whitespace is insignificant (except within a quoted
+ parameter value) and blank lines are
+ ignored. Hash marks (<code class="literal">#</code>) designate the remainder
+ of the line as a comment. Parameter values that are not simple
+ identifiers or numbers must be single-quoted. To embed a single
+ quote in a parameter value, write either two quotes (preferred)
+ or backslash-quote.
+ If the file contains multiple entries for the same parameter,
+ all but the last one are ignored.
+ </p><p>
+ Parameters set in this way provide default values for the cluster.
+ The settings seen by active sessions will be these values unless they
+ are overridden. The following sections describe ways in which the
+ administrator or user can override these defaults.
+ </p><p>
+ <a id="id-1.6.7.4.3.4.1" class="indexterm"></a>
+ The configuration file is reread whenever the main server process
+ receives a <span class="systemitem">SIGHUP</span> signal; this signal is most easily
+ sent by running <code class="literal">pg_ctl reload</code> from the command line or by
+ calling the SQL function <code class="function">pg_reload_conf()</code>. The main
+ server process also propagates this signal to all currently running
+ server processes, so that existing sessions also adopt the new values
+ (this will happen after they complete any currently-executing client
+ command). Alternatively, you can
+ send the signal to a single server process directly. Some parameters
+ can only be set at server start; any changes to their entries in the
+ configuration file will be ignored until the server is restarted.
+ Invalid parameter settings in the configuration file are likewise
+ ignored (but logged) during <span class="systemitem">SIGHUP</span> processing.
+ </p><p>
+ In addition to <code class="filename">postgresql.conf</code>,
+ a <span class="productname">PostgreSQL</span> data directory contains a file
+ <code class="filename">postgresql.auto.conf</code><a id="id-1.6.7.4.3.5.4" class="indexterm"></a>,
+ which has the same format as <code class="filename">postgresql.conf</code> but
+ is intended to be edited automatically, not manually. This file holds
+ settings provided through the <a class="link" href="sql-altersystem.html" title="ALTER SYSTEM"><code class="command">ALTER SYSTEM</code></a> command.
+ This file is read whenever <code class="filename">postgresql.conf</code> is,
+ and its settings take effect in the same way. Settings
+ in <code class="filename">postgresql.auto.conf</code> override those
+ in <code class="filename">postgresql.conf</code>.
+ </p><p>
+ External tools may also
+ modify <code class="filename">postgresql.auto.conf</code>. It is not
+ recommended to do this while the server is running, since a
+ concurrent <code class="command">ALTER SYSTEM</code> command could overwrite
+ such changes. Such tools might simply append new settings to the end,
+ or they might choose to remove duplicate settings and/or comments
+ (as <code class="command">ALTER SYSTEM</code> will).
+ </p><p>
+ The system view
+ <a class="link" href="view-pg-file-settings.html" title="54.7. pg_file_settings"><code class="structname">pg_file_settings</code></a>
+ can be helpful for pre-testing changes to the configuration files, or for
+ diagnosing problems if a <span class="systemitem">SIGHUP</span> signal did not have the
+ desired effects.
+ </p></div><div class="sect2" id="CONFIG-SETTING-SQL-COMMAND-INTERACTION"><div class="titlepage"><div><div><h3 class="title">20.1.3. Parameter Interaction via SQL</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> provides three SQL
+ commands to establish configuration defaults.
+ The already-mentioned <code class="command">ALTER SYSTEM</code> command
+ provides an SQL-accessible means of changing global defaults; it is
+ functionally equivalent to editing <code class="filename">postgresql.conf</code>.
+ In addition, there are two commands that allow setting of defaults
+ on a per-database or per-role basis:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The <a class="link" href="sql-alterdatabase.html" title="ALTER DATABASE"><code class="command">ALTER DATABASE</code></a> command allows global
+ settings to be overridden on a per-database basis.
+ </p></li><li class="listitem"><p>
+ The <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a> command allows both global and
+ per-database settings to be overridden with user-specific values.
+ </p></li></ul></div><p>
+ Values set with <code class="command">ALTER DATABASE</code> and <code class="command">ALTER ROLE</code>
+ are applied only when starting a fresh database session. They
+ override values obtained from the configuration files or server
+ command line, and constitute defaults for the rest of the session.
+ Note that some settings cannot be changed after server start, and
+ so cannot be set with these commands (or the ones listed below).
+ </p><p>
+ Once a client is connected to the database, <span class="productname">PostgreSQL</span>
+ provides two additional SQL commands (and equivalent functions) to
+ interact with session-local configuration settings:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The <a class="link" href="sql-show.html" title="SHOW"><code class="command">SHOW</code></a> command allows inspection of the
+ current value of any parameter. The corresponding SQL function is
+ <code class="function">current_setting(setting_name text)</code>
+ (see <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SET" title="9.27.1. Configuration Settings Functions">Section 9.27.1</a>).
+ </p></li><li class="listitem"><p>
+ The <a class="link" href="sql-set.html" title="SET"><code class="command">SET</code></a> command allows modification of the
+ current value of those parameters that can be set locally to a
+ session; it has no effect on other sessions.
+ Many parameters can be set this way by any user, but some can
+ only be set by superusers and users who have been
+ granted <code class="literal">SET</code> privilege on that parameter.
+ The corresponding SQL function is
+ <code class="function">set_config(setting_name, new_value, is_local)</code>
+ (see <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SET" title="9.27.1. Configuration Settings Functions">Section 9.27.1</a>).
+ </p></li></ul></div><p>
+ In addition, the system view <a class="link" href="view-pg-settings.html" title="54.24. pg_settings"><code class="structname">pg_settings</code></a> can be
+ used to view and change session-local values:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Querying this view is similar to using <code class="command">SHOW ALL</code> but
+ provides more detail. It is also more flexible, since it's possible
+ to specify filter conditions or join against other relations.
+ </p></li><li class="listitem"><p>
+ Using <code class="command">UPDATE</code> on this view, specifically
+ updating the <code class="structname">setting</code> column, is the equivalent
+ of issuing <code class="command">SET</code> commands. For example, the equivalent of
+</p><pre class="programlisting">
+SET configuration_parameter TO DEFAULT;
+</pre><p>
+ is:
+</p><pre class="programlisting">
+UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter';
+</pre><p>
+ </p></li></ul></div></div><div class="sect2" id="id-1.6.7.4.5"><div class="titlepage"><div><div><h3 class="title">20.1.4. Parameter Interaction via the Shell</h3></div></div></div><p>
+ In addition to setting global defaults or attaching
+ overrides at the database or role level, you can pass settings to
+ <span class="productname">PostgreSQL</span> via shell facilities.
+ Both the server and <span class="application">libpq</span> client library
+ accept parameter values via the shell.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ During server startup, parameter settings can be
+ passed to the <code class="command">postgres</code> command via the
+ <code class="option">-c</code> command-line parameter. For example,
+</p><pre class="programlisting">
+postgres -c log_connections=yes -c log_destination='syslog'
+</pre><p>
+ Settings provided in this way override those set via
+ <code class="filename">postgresql.conf</code> or <code class="command">ALTER SYSTEM</code>,
+ so they cannot be changed globally without restarting the server.
+ </p></li><li class="listitem"><p>
+ When starting a client session via <span class="application">libpq</span>,
+ parameter settings can be
+ specified using the <code class="envar">PGOPTIONS</code> environment variable.
+ Settings established in this way constitute defaults for the life
+ of the session, but do not affect other sessions.
+ For historical reasons, the format of <code class="envar">PGOPTIONS</code> is
+ similar to that used when launching the <code class="command">postgres</code>
+ command; specifically, the <code class="option">-c</code> flag must be specified.
+ For example,
+</p><pre class="programlisting">
+env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql
+</pre><p>
+ </p><p>
+ Other clients and libraries might provide their own mechanisms,
+ via the shell or otherwise, that allow the user to alter session
+ settings without direct use of SQL commands.
+ </p></li></ul></div></div><div class="sect2" id="CONFIG-INCLUDES"><div class="titlepage"><div><div><h3 class="title">20.1.5. Managing Configuration File Contents</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> provides several features for breaking
+ down complex <code class="filename">postgresql.conf</code> files into sub-files.
+ These features are especially useful when managing multiple servers
+ with related, but not identical, configurations.
+ </p><p>
+ <a id="id-1.6.7.4.6.3.1" class="indexterm"></a>
+ In addition to individual parameter settings,
+ the <code class="filename">postgresql.conf</code> file can contain <em class="firstterm">include
+ directives</em>, which specify another file to read and process as if
+ it were inserted into the configuration file at this point. This
+ feature allows a configuration file to be divided into physically
+ separate parts. Include directives simply look like:
+</p><pre class="programlisting">
+include 'filename'
+</pre><p>
+ If the file name is not an absolute path, it is taken as relative to
+ the directory containing the referencing configuration file.
+ Inclusions can be nested.
+ </p><p>
+ <a id="id-1.6.7.4.6.4.1" class="indexterm"></a>
+ There is also an <code class="literal">include_if_exists</code> directive, which acts
+ the same as the <code class="literal">include</code> directive, except
+ when the referenced file does not exist or cannot be read. A regular
+ <code class="literal">include</code> will consider this an error condition, but
+ <code class="literal">include_if_exists</code> merely logs a message and continues
+ processing the referencing configuration file.
+ </p><p>
+ <a id="id-1.6.7.4.6.5.1" class="indexterm"></a>
+ The <code class="filename">postgresql.conf</code> file can also contain
+ <code class="literal">include_dir</code> directives, which specify an entire
+ directory of configuration files to include. These look like
+</p><pre class="programlisting">
+include_dir 'directory'
+</pre><p>
+ Non-absolute directory names are taken as relative to the directory
+ containing the referencing configuration file. Within the specified
+ directory, only non-directory files whose names end with the
+ suffix <code class="literal">.conf</code> will be included. File names that
+ start with the <code class="literal">.</code> character are also ignored, to
+ prevent mistakes since such files are hidden on some platforms. Multiple
+ files within an include directory are processed in file name order
+ (according to C locale rules, i.e., numbers before letters, and
+ uppercase letters before lowercase ones).
+ </p><p>
+ Include files or directories can be used to logically separate portions
+ of the database configuration, rather than having a single large
+ <code class="filename">postgresql.conf</code> file. Consider a company that has two
+ database servers, each with a different amount of memory. There are
+ likely elements of the configuration both will share, for things such
+ as logging. But memory-related parameters on the server will vary
+ between the two. And there might be server specific customizations,
+ too. One way to manage this situation is to break the custom
+ configuration changes for your site into three files. You could add
+ this to the end of your <code class="filename">postgresql.conf</code> file to include
+ them:
+</p><pre class="programlisting">
+include 'shared.conf'
+include 'memory.conf'
+include 'server.conf'
+</pre><p>
+ All systems would have the same <code class="filename">shared.conf</code>. Each
+ server with a particular amount of memory could share the
+ same <code class="filename">memory.conf</code>; you might have one for all servers
+ with 8GB of RAM, another for those having 16GB. And
+ finally <code class="filename">server.conf</code> could have truly server-specific
+ configuration information in it.
+ </p><p>
+ Another possibility is to create a configuration file directory and
+ put this information into files there. For example, a <code class="filename">conf.d</code>
+ directory could be referenced at the end of <code class="filename">postgresql.conf</code>:
+</p><pre class="programlisting">
+include_dir 'conf.d'
+</pre><p>
+ Then you could name the files in the <code class="filename">conf.d</code> directory
+ like this:
+</p><pre class="programlisting">
+00shared.conf
+01memory.conf
+02server.conf
+</pre><p>
+ This naming convention establishes a clear order in which these
+ files will be loaded. This is important because only the last
+ setting encountered for a particular parameter while the server is
+ reading configuration files will be used. In this example,
+ something set in <code class="filename">conf.d/02server.conf</code> would override a
+ value set in <code class="filename">conf.d/01memory.conf</code>.
+ </p><p>
+ You might instead use this approach to naming the files
+ descriptively:
+</p><pre class="programlisting">
+00shared.conf
+01memory-8GB.conf
+02server-foo.conf
+</pre><p>
+ This sort of arrangement gives a unique name for each configuration file
+ variation. This can help eliminate ambiguity when several servers have
+ their configurations all stored in one place, such as in a version
+ control repository. (Storing database configuration files under version
+ control is another good practice to consider.)
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config.html" title="Chapter 20. Server Configuration">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-file-locations.html" title="20.2. File Locations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 20. Server Configuration </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.2. File Locations</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/connect-estab.html b/doc/src/sgml/html/connect-estab.html
new file mode 100644
index 0000000..0bb1324
--- /dev/null
+++ b/doc/src/sgml/html/connect-estab.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>52.2. How Connections Are Established</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="query-path.html" title="52.1. The Path of a Query" /><link rel="next" href="parser-stage.html" title="52.3. The Parser Stage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">52.2. How Connections Are Established</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="query-path.html" title="52.1. The Path of a Query">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><th width="60%" align="center">Chapter 52. Overview of PostgreSQL Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="parser-stage.html" title="52.3. The Parser Stage">Next</a></td></tr></table><hr /></div><div class="sect1" id="CONNECT-ESTAB"><div class="titlepage"><div><div><h2 class="title" style="clear: both">52.2. How Connections Are Established</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> implements a
+ <span class="quote">“<span class="quote">process per user</span>”</span> client/server model.
+ In this model, every
+ <a class="glossterm" href="glossary.html#GLOSSARY-CLIENT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CLIENT" title="Client (process)">client process</a></em></a>
+ connects to exactly one
+ <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend process</a></em></a>.
+ As we do not know ahead of time how many connections will be made,
+ we have to use a <span class="quote">“<span class="quote">supervisor process</span>”</span> that spawns a new
+ backend process every time a connection is requested. This supervisor
+ process is called
+ <a class="glossterm" href="glossary.html#GLOSSARY-POSTMASTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-POSTMASTER" title="Postmaster (process)">postmaster</a></em></a>
+ and listens at a specified TCP/IP port for incoming connections.
+ Whenever it detects a request for a connection, it spawns a new
+ backend process. Those backend processes communicate with each
+ other and with other processes of the
+ <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>
+ using <em class="firstterm">semaphores</em> and
+ <a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY" title="Shared memory">shared memory</a></em></a>
+ to ensure data integrity throughout concurrent data access.
+ </p><p>
+ The client process can be any program that understands the
+ <span class="productname">PostgreSQL</span> protocol described in
+ <a class="xref" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Chapter 55</a>. Many clients are based on the
+ C-language library <span class="application">libpq</span>, but several independent
+ implementations of the protocol exist, such as the Java
+ <span class="application">JDBC</span> driver.
+ </p><p>
+ Once a connection is established, the client process can send a query
+ to the backend process it's connected to. The query is transmitted using
+ plain text, i.e., there is no parsing done in the client. The backend
+ process parses the query, creates an <em class="firstterm">execution plan</em>,
+ executes the plan, and returns the retrieved rows to the client
+ by transmitting them over the established connection.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="query-path.html" title="52.1. The Path of a Query">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="parser-stage.html" title="52.3. The Parser Stage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">52.1. The Path of a Query </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 52.3. The Parser Stage</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/continuous-archiving.html b/doc/src/sgml/html/continuous-archiving.html
new file mode 100644
index 0000000..8032240
--- /dev/null
+++ b/doc/src/sgml/html/continuous-archiving.html
@@ -0,0 +1,757 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>26.3. Continuous Archiving and Point-in-Time Recovery (PITR)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="backup-file.html" title="26.2. File System Level Backup" /><link rel="next" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">26.3. Continuous Archiving and Point-in-Time Recovery (PITR)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="backup-file.html" title="26.2. File System Level Backup">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="backup.html" title="Chapter 26. Backup and Restore">Up</a></td><th width="60%" align="center">Chapter 26. Backup and Restore</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Next</a></td></tr></table><hr /></div><div class="sect1" id="CONTINUOUS-ARCHIVING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">26.3. Continuous Archiving and Point-in-Time Recovery (PITR)</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-ARCHIVING-WAL">26.3.1. Setting Up WAL Archiving</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-BASE-BACKUP">26.3.2. Making a Base Backup</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP">26.3.3. Making a Base Backup Using the Low Level API</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-PITR-RECOVERY">26.3.4. Recovering Using a Continuous Archive Backup</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-TIMELINES">26.3.5. Timelines</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#BACKUP-TIPS">26.3.6. Tips and Examples</a></span></dt><dt><span class="sect2"><a href="continuous-archiving.html#CONTINUOUS-ARCHIVING-CAVEATS">26.3.7. Caveats</a></span></dt></dl></div><a id="id-1.6.13.7.2" class="indexterm"></a><a id="id-1.6.13.7.3" class="indexterm"></a><a id="id-1.6.13.7.4" class="indexterm"></a><p>
+ At all times, <span class="productname">PostgreSQL</span> maintains a
+ <em class="firstterm">write ahead log</em> (WAL) in the <code class="filename">pg_wal/</code>
+ subdirectory of the cluster's data directory. The log records
+ every change made to the database's data files. This log exists
+ primarily for crash-safety purposes: if the system crashes, the
+ database can be restored to consistency by <span class="quote">“<span class="quote">replaying</span>”</span> the
+ log entries made since the last checkpoint. However, the existence
+ of the log makes it possible to use a third strategy for backing up
+ databases: we can combine a file-system-level backup with backup of
+ the WAL files. If recovery is needed, we restore the file system backup and
+ then replay from the backed-up WAL files to bring the system to a
+ current state. This approach is more complex to administer than
+ either of the previous approaches, but it has some significant
+ benefits:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ We do not need a perfectly consistent file system backup as the starting point.
+ Any internal inconsistency in the backup will be corrected by log
+ replay (this is not significantly different from what happens during
+ crash recovery). So we do not need a file system snapshot capability,
+ just <span class="application">tar</span> or a similar archiving tool.
+ </p></li><li class="listitem"><p>
+ Since we can combine an indefinitely long sequence of WAL files
+ for replay, continuous backup can be achieved simply by continuing to archive
+ the WAL files. This is particularly valuable for large databases, where
+ it might not be convenient to take a full backup frequently.
+ </p></li><li class="listitem"><p>
+ It is not necessary to replay the WAL entries all the
+ way to the end. We could stop the replay at any point and have a
+ consistent snapshot of the database as it was at that time. Thus,
+ this technique supports <em class="firstterm">point-in-time recovery</em>: it is
+ possible to restore the database to its state at any time since your base
+ backup was taken.
+ </p></li><li class="listitem"><p>
+ If we continuously feed the series of WAL files to another
+ machine that has been loaded with the same base backup file, we
+ have a <em class="firstterm">warm standby</em> system: at any point we can bring up
+ the second machine and it will have a nearly-current copy of the
+ database.
+ </p></li></ul></div><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="application">pg_dump</span> and
+ <span class="application">pg_dumpall</span> do not produce file-system-level
+ backups and cannot be used as part of a continuous-archiving solution.
+ Such dumps are <span class="emphasis"><em>logical</em></span> and do not contain enough
+ information to be used by WAL replay.
+ </p></div><p>
+ As with the plain file-system-backup technique, this method can only
+ support restoration of an entire database cluster, not a subset.
+ Also, it requires a lot of archival storage: the base backup might be bulky,
+ and a busy system will generate many megabytes of WAL traffic that
+ have to be archived. Still, it is the preferred backup technique in
+ many situations where high reliability is needed.
+ </p><p>
+ To recover successfully using continuous archiving (also called
+ <span class="quote">“<span class="quote">online backup</span>”</span> by many database vendors), you need a continuous
+ sequence of archived WAL files that extends back at least as far as the
+ start time of your backup. So to get started, you should set up and test
+ your procedure for archiving WAL files <span class="emphasis"><em>before</em></span> you take your
+ first base backup. Accordingly, we first discuss the mechanics of
+ archiving WAL files.
+ </p><div class="sect2" id="BACKUP-ARCHIVING-WAL"><div class="titlepage"><div><div><h3 class="title">26.3.1. Setting Up WAL Archiving</h3></div></div></div><p>
+ In an abstract sense, a running <span class="productname">PostgreSQL</span> system
+ produces an indefinitely long sequence of WAL records. The system
+ physically divides this sequence into WAL <em class="firstterm">segment
+ files</em>, which are normally 16MB apiece (although the segment size
+ can be altered during <span class="application">initdb</span>). The segment
+ files are given numeric names that reflect their position in the
+ abstract WAL sequence. When not using WAL archiving, the system
+ normally creates just a few segment files and then
+ <span class="quote">“<span class="quote">recycles</span>”</span> them by renaming no-longer-needed segment files
+ to higher segment numbers. It's assumed that segment files whose
+ contents precede the last checkpoint are no longer of
+ interest and can be recycled.
+ </p><p>
+ When archiving WAL data, we need to capture the contents of each segment
+ file once it is filled, and save that data somewhere before the segment
+ file is recycled for reuse. Depending on the application and the
+ available hardware, there could be many different ways of <span class="quote">“<span class="quote">saving
+ the data somewhere</span>”</span>: we could copy the segment files to an NFS-mounted
+ directory on another machine, write them onto a tape drive (ensuring that
+ you have a way of identifying the original name of each file), or batch
+ them together and burn them onto CDs, or something else entirely. To
+ provide the database administrator with flexibility,
+ <span class="productname">PostgreSQL</span> tries not to make any assumptions about how
+ the archiving will be done. Instead, <span class="productname">PostgreSQL</span> lets
+ the administrator specify a shell command or an archive library to be executed to copy a
+ completed segment file to wherever it needs to go. This could be as simple
+ as a shell command that uses <code class="literal">cp</code>, or it could invoke a
+ complex C function — it's all up to you.
+ </p><p>
+ To enable WAL archiving, set the <a class="xref" href="runtime-config-wal.html#GUC-WAL-LEVEL">wal_level</a>
+ configuration parameter to <code class="literal">replica</code> or higher,
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-MODE">archive_mode</a> to <code class="literal">on</code>,
+ specify the shell command to use in the <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> configuration parameter
+ or specify the library to use in the <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> configuration parameter. In practice
+ these settings will always be placed in the
+ <code class="filename">postgresql.conf</code> file.
+ </p><p>
+ In <code class="varname">archive_command</code>,
+ <code class="literal">%p</code> is replaced by the path name of the file to
+ archive, while <code class="literal">%f</code> is replaced by only the file name.
+ (The path name is relative to the current working directory,
+ i.e., the cluster's data directory.)
+ Use <code class="literal">%%</code> if you need to embed an actual <code class="literal">%</code>
+ character in the command. The simplest useful command is something
+ like:
+</p><pre class="programlisting">
+archive_command = 'test ! -f /mnt/server/archivedir/%f &amp;&amp; cp %p /mnt/server/archivedir/%f' # Unix
+archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"' # Windows
+</pre><p>
+ which will copy archivable WAL segments to the directory
+ <code class="filename">/mnt/server/archivedir</code>. (This is an example, not a
+ recommendation, and might not work on all platforms.) After the
+ <code class="literal">%p</code> and <code class="literal">%f</code> parameters have been replaced,
+ the actual command executed might look like this:
+</p><pre class="programlisting">
+test ! -f /mnt/server/archivedir/00000001000000A900000065 &amp;&amp; cp pg_wal/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065
+</pre><p>
+ A similar command will be generated for each new file to be archived.
+ </p><p>
+ The archive command will be executed under the ownership of the same
+ user that the <span class="productname">PostgreSQL</span> server is running as. Since
+ the series of WAL files being archived contains effectively everything
+ in your database, you will want to be sure that the archived data is
+ protected from prying eyes; for example, archive into a directory that
+ does not have group or world read access.
+ </p><p>
+ It is important that the archive command return zero exit status if and
+ only if it succeeds. Upon getting a zero result,
+ <span class="productname">PostgreSQL</span> will assume that the file has been
+ successfully archived, and will remove or recycle it. However, a nonzero
+ status tells <span class="productname">PostgreSQL</span> that the file was not archived;
+ it will try again periodically until it succeeds.
+ </p><p>
+ Another way to archive is to use a custom archive module as the
+ <code class="varname">archive_library</code>. Since such modules are written in
+ <code class="literal">C</code>, creating your own may require considerably more effort
+ than writing a shell command. However, archive modules can be more
+ performant than archiving via shell, and they will have access to many
+ useful server resources. For more information about archive modules, see
+ <a class="xref" href="archive-modules.html" title="Chapter 51. Archive Modules">Chapter 51</a>.
+ </p><p>
+ When the archive command is terminated by a signal (other than
+ <span class="systemitem">SIGTERM</span> that is used as part of a server
+ shutdown) or an error by the shell with an exit status greater than
+ 125 (such as command not found), or if the archive function emits an
+ <code class="literal">ERROR</code> or <code class="literal">FATAL</code>, the archiver process
+ aborts and gets restarted by the postmaster. In such cases, the failure is
+ not reported in <a class="xref" href="monitoring-stats.html#PG-STAT-ARCHIVER-VIEW" title="Table 28.22. pg_stat_archiver View">pg_stat_archiver</a>.
+ </p><p>
+ Archive commands and libraries should generally be designed to refuse to overwrite
+ any pre-existing archive file. This is an important safety feature to
+ preserve the integrity of your archive in case of administrator error
+ (such as sending the output of two different servers to the same archive
+ directory).
+ </p><p>
+ It is advisable to test your proposed archive command or library to ensure that it
+ indeed does not overwrite an existing file, <span class="emphasis"><em>and that it returns
+ nonzero status or <code class="literal">false</code>, respectively, in this case</em></span>.
+ The example command above for Unix ensures this by including a separate
+ <code class="command">test</code> step. On some Unix platforms, <code class="command">cp</code> has
+ switches such as <code class="option">-i</code> that can be used to do the same thing
+ less verbosely, but you should not rely on these without verifying that
+ the right exit status is returned. (In particular, GNU <code class="command">cp</code>
+ will return status zero when <code class="option">-i</code> is used and the target file
+ already exists, which is <span class="emphasis"><em>not</em></span> the desired behavior.)
+ </p><p>
+ While designing your archiving setup, consider what will happen if
+ the archive command or library fails repeatedly because some aspect requires
+ operator intervention or the archive runs out of space. For example, this
+ could occur if you write to tape without an autochanger; when the tape
+ fills, nothing further can be archived until the tape is swapped.
+ You should ensure that any error condition or request to a human operator
+ is reported appropriately so that the situation can be
+ resolved reasonably quickly. The <code class="filename">pg_wal/</code> directory will
+ continue to fill with WAL segment files until the situation is resolved.
+ (If the file system containing <code class="filename">pg_wal/</code> fills up,
+ <span class="productname">PostgreSQL</span> will do a PANIC shutdown. No committed
+ transactions will be lost, but the database will remain offline until
+ you free some space.)
+ </p><p>
+ The speed of the archive command or library is unimportant as long as it can keep up
+ with the average rate at which your server generates WAL data. Normal
+ operation continues even if the archiving process falls a little behind.
+ If archiving falls significantly behind, this will increase the amount of
+ data that would be lost in the event of a disaster. It will also mean that
+ the <code class="filename">pg_wal/</code> directory will contain large numbers of
+ not-yet-archived segment files, which could eventually exceed available
+ disk space. You are advised to monitor the archiving process to ensure that
+ it is working as you intend.
+ </p><p>
+ In writing your archive command or library, you should assume that the file names to
+ be archived can be up to 64 characters long and can contain any
+ combination of ASCII letters, digits, and dots. It is not necessary to
+ preserve the original relative path (<code class="literal">%p</code>) but it is necessary to
+ preserve the file name (<code class="literal">%f</code>).
+ </p><p>
+ Note that although WAL archiving will allow you to restore any
+ modifications made to the data in your <span class="productname">PostgreSQL</span> database,
+ it will not restore changes made to configuration files (that is,
+ <code class="filename">postgresql.conf</code>, <code class="filename">pg_hba.conf</code> and
+ <code class="filename">pg_ident.conf</code>), since those are edited manually rather
+ than through SQL operations.
+ You might wish to keep the configuration files in a location that will
+ be backed up by your regular file system backup procedures. See
+ <a class="xref" href="runtime-config-file-locations.html" title="20.2. File Locations">Section 20.2</a> for how to relocate the
+ configuration files.
+ </p><p>
+ The archive command or function is only invoked on completed WAL segments. Hence,
+ if your server generates only little WAL traffic (or has slack periods
+ where it does so), there could be a long delay between the completion
+ of a transaction and its safe recording in archive storage. To put
+ a limit on how old unarchived data can be, you can set
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-TIMEOUT">archive_timeout</a> to force the server to switch
+ to a new WAL segment file at least that often. Note that archived
+ files that are archived early due to a forced switch are still the same
+ length as completely full files. It is therefore unwise to set a very
+ short <code class="varname">archive_timeout</code> — it will bloat your archive
+ storage. <code class="varname">archive_timeout</code> settings of a minute or so are
+ usually reasonable.
+ </p><p>
+ Also, you can force a segment switch manually with
+ <code class="function">pg_switch_wal</code> if you want to ensure that a
+ just-finished transaction is archived as soon as possible. Other utility
+ functions related to WAL management are listed in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP-TABLE" title="Table 9.89. Backup Control Functions">Table 9.89</a>.
+ </p><p>
+ When <code class="varname">wal_level</code> is <code class="literal">minimal</code> some SQL commands
+ are optimized to avoid WAL logging, as described in <a class="xref" href="populate.html#POPULATE-PITR" title="14.4.7. Disable WAL Archival and Streaming Replication">Section 14.4.7</a>. If archiving or streaming replication were
+ turned on during execution of one of these statements, WAL would not
+ contain enough information for archive recovery. (Crash recovery is
+ unaffected.) For this reason, <code class="varname">wal_level</code> can only be changed at
+ server start. However, <code class="varname">archive_command</code> and <code class="varname">archive_library</code> can be changed with a
+ configuration file reload. If you are archiving via shell and wish to
+ temporarily stop archiving,
+ one way to do it is to set <code class="varname">archive_command</code> to the empty
+ string (<code class="literal">''</code>).
+ This will cause WAL files to accumulate in <code class="filename">pg_wal/</code> until a
+ working <code class="varname">archive_command</code> is re-established.
+ </p></div><div class="sect2" id="BACKUP-BASE-BACKUP"><div class="titlepage"><div><div><h3 class="title">26.3.2. Making a Base Backup</h3></div></div></div><p>
+ The easiest way to perform a base backup is to use the
+ <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a> tool. It can create
+ a base backup either as regular files or as a tar archive. If more
+ flexibility than <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a> can provide is
+ required, you can also make a base backup using the low level API
+ (see <a class="xref" href="continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP" title="26.3.3. Making a Base Backup Using the Low Level API">Section 26.3.3</a>).
+ </p><p>
+ It is not necessary to be concerned about the amount of time it takes
+ to make a base backup. However, if you normally run the
+ server with <code class="varname">full_page_writes</code> disabled, you might notice a drop
+ in performance while the backup runs since <code class="varname">full_page_writes</code> is
+ effectively forced on during backup mode.
+ </p><p>
+ To make use of the backup, you will need to keep all the WAL
+ segment files generated during and after the file system backup.
+ To aid you in doing this, the base backup process
+ creates a <em class="firstterm">backup history file</em> that is immediately
+ stored into the WAL archive area. This file is named after the first
+ WAL segment file that you need for the file system backup.
+ For example, if the starting WAL file is
+ <code class="literal">0000000100001234000055CD</code> the backup history file will be
+ named something like
+ <code class="literal">0000000100001234000055CD.007C9330.backup</code>. (The second
+ part of the file name stands for an exact position within the WAL
+ file, and can ordinarily be ignored.) Once you have safely archived
+ the file system backup and the WAL segment files used during the
+ backup (as specified in the backup history file), all archived WAL
+ segments with names numerically less are no longer needed to recover
+ the file system backup and can be deleted. However, you should
+ consider keeping several backup sets to be absolutely certain that
+ you can recover your data.
+ </p><p>
+ The backup history file is just a small text file. It contains the
+ label string you gave to <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a>, as well as
+ the starting and ending times and WAL segments of the backup.
+ If you used the label to identify the associated dump file,
+ then the archived history file is enough to tell you which dump file to
+ restore.
+ </p><p>
+ Since you have to keep around all the archived WAL files back to your
+ last base backup, the interval between base backups should usually be
+ chosen based on how much storage you want to expend on archived WAL
+ files. You should also consider how long you are prepared to spend
+ recovering, if recovery should be necessary — the system will have to
+ replay all those WAL segments, and that could take awhile if it has
+ been a long time since the last base backup.
+ </p></div><div class="sect2" id="BACKUP-LOWLEVEL-BASE-BACKUP"><div class="titlepage"><div><div><h3 class="title">26.3.3. Making a Base Backup Using the Low Level API</h3></div></div></div><p>
+ The procedure for making a base backup using the low level
+ APIs contains a few more steps than
+ the <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a> method, but is relatively
+ simple. It is very important that these steps are executed in
+ sequence, and that the success of a step is verified before
+ proceeding to the next step.
+ </p><p>
+ Multiple backups are able to be run concurrently (both those
+ started using this backup API and those started using
+ <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a>).
+ </p><p>
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ Ensure that WAL archiving is enabled and working.
+ </p></li><li class="listitem"><p>
+ Connect to the server (it does not matter which database) as a user with
+ rights to run <code class="function">pg_backup_start</code> (superuser,
+ or a user who has been granted <code class="literal">EXECUTE</code> on the
+ function) and issue the command:
+</p><pre class="programlisting">
+SELECT pg_backup_start(label =&gt; 'label', fast =&gt; false);
+</pre><p>
+ where <code class="literal">label</code> is any string you want to use to uniquely
+ identify this backup operation. The connection
+ calling <code class="function">pg_backup_start</code> must be maintained until the end of
+ the backup, or the backup will be automatically aborted.
+ </p><p>
+ Online backups are always started at the beginning of a checkpoint.
+ By default, <code class="function">pg_backup_start</code> will wait for the next
+ regularly scheduled checkpoint to complete, which may take a long time (see the
+ configuration parameters <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-TIMEOUT">checkpoint_timeout</a> and
+ <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-COMPLETION-TARGET">checkpoint_completion_target</a>). This is
+ usually preferable as it minimizes the impact on the running system. If you
+ want to start the backup as soon as possible, pass <code class="literal">true</code> as
+ the second parameter to <code class="function">pg_backup_start</code> and it will
+ request an immediate checkpoint, which will finish as fast as possible using
+ as much I/O as possible.
+ </p></li><li class="listitem"><p>
+ Perform the backup, using any convenient file-system-backup tool
+ such as <span class="application">tar</span> or <span class="application">cpio</span> (not
+ <span class="application">pg_dump</span> or
+ <span class="application">pg_dumpall</span>). It is neither
+ necessary nor desirable to stop normal operation of the database
+ while you do this. See
+ <a class="xref" href="continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP-DATA" title="26.3.3.1. Backing Up the Data Directory">Section 26.3.3.1</a> for things to
+ consider during this backup.
+ </p></li><li class="listitem"><p>
+ In the same connection as before, issue the command:
+</p><pre class="programlisting">
+SELECT * FROM pg_backup_stop(wait_for_archive =&gt; true);
+</pre><p>
+ This terminates backup mode. On a primary, it also performs an automatic
+ switch to the next WAL segment. On a standby, it is not possible to
+ automatically switch WAL segments, so you may wish to run
+ <code class="function">pg_switch_wal</code> on the primary to perform a manual
+ switch. The reason for the switch is to arrange for
+ the last WAL segment file written during the backup interval to be
+ ready to archive.
+ </p><p>
+ <code class="function">pg_backup_stop</code> will return one row with three
+ values. The second of these fields should be written to a file named
+ <code class="filename">backup_label</code> in the root directory of the backup. The
+ third field should be written to a file named
+ <code class="filename">tablespace_map</code> unless the field is empty. These files are
+ vital to the backup working and must be written byte for byte without
+ modification, which may require opening the file in binary mode.
+ </p></li><li class="listitem"><p>
+ Once the WAL segment files active during the backup are archived, you are
+ done. The file identified by <code class="function">pg_backup_stop</code>'s first return
+ value is the last segment that is required to form a complete set of
+ backup files. On a primary, if <code class="varname">archive_mode</code> is enabled and the
+ <code class="literal">wait_for_archive</code> parameter is <code class="literal">true</code>,
+ <code class="function">pg_backup_stop</code> does not return until the last segment has
+ been archived.
+ On a standby, <code class="varname">archive_mode</code> must be <code class="literal">always</code> in order
+ for <code class="function">pg_backup_stop</code> to wait.
+ Archiving of these files happens automatically since you have
+ already configured <code class="varname">archive_command</code> or <code class="varname">archive_library</code>.
+ In most cases this happens quickly, but you are advised to monitor your
+ archive system to ensure there are no delays.
+ If the archive process has fallen behind because of failures of the
+ archive command or library, it will keep retrying
+ until the archive succeeds and the backup is complete.
+ If you wish to place a time limit on the execution of
+ <code class="function">pg_backup_stop</code>, set an appropriate
+ <code class="varname">statement_timeout</code> value, but make note that if
+ <code class="function">pg_backup_stop</code> terminates because of this your backup
+ may not be valid.
+ </p><p>
+ If the backup process monitors and ensures that all WAL segment files
+ required for the backup are successfully archived then the
+ <code class="literal">wait_for_archive</code> parameter (which defaults to true) can be set
+ to false to have
+ <code class="function">pg_backup_stop</code> return as soon as the stop backup record is
+ written to the WAL. By default, <code class="function">pg_backup_stop</code> will wait
+ until all WAL has been archived, which can take some time. This option
+ must be used with caution: if WAL archiving is not monitored correctly
+ then the backup might not include all of the WAL files and will
+ therefore be incomplete and not able to be restored.
+ </p></li></ol></div><p>
+ </p><div class="sect3" id="BACKUP-LOWLEVEL-BASE-BACKUP-DATA"><div class="titlepage"><div><div><h4 class="title">26.3.3.1. Backing Up the Data Directory</h4></div></div></div><p>
+ Some file system backup tools emit warnings or errors
+ if the files they are trying to copy change while the copy proceeds.
+ When taking a base backup of an active database, this situation is normal
+ and not an error. However, you need to ensure that you can distinguish
+ complaints of this sort from real errors. For example, some versions
+ of <span class="application">rsync</span> return a separate exit code for
+ <span class="quote">“<span class="quote">vanished source files</span>”</span>, and you can write a driver script to
+ accept this exit code as a non-error case. Also, some versions of
+ GNU <span class="application">tar</span> return an error code indistinguishable from
+ a fatal error if a file was truncated while <span class="application">tar</span> was
+ copying it. Fortunately, GNU <span class="application">tar</span> versions 1.16 and
+ later exit with 1 if a file was changed during the backup,
+ and 2 for other errors. With GNU <span class="application">tar</span> version 1.23 and
+ later, you can use the warning options <code class="literal">--warning=no-file-changed
+ --warning=no-file-removed</code> to hide the related warning messages.
+ </p><p>
+ Be certain that your backup includes all of the files under
+ the database cluster directory (e.g., <code class="filename">/usr/local/pgsql/data</code>).
+ If you are using tablespaces that do not reside underneath this directory,
+ be careful to include them as well (and be sure that your backup
+ archives symbolic links as links, otherwise the restore will corrupt
+ your tablespaces).
+ </p><p>
+ You should, however, omit from the backup the files within the
+ cluster's <code class="filename">pg_wal/</code> subdirectory. This
+ slight adjustment is worthwhile because it reduces the risk
+ of mistakes when restoring. This is easy to arrange if
+ <code class="filename">pg_wal/</code> is a symbolic link pointing to someplace outside
+ the cluster directory, which is a common setup anyway for performance
+ reasons. You might also want to exclude <code class="filename">postmaster.pid</code>
+ and <code class="filename">postmaster.opts</code>, which record information
+ about the running <span class="application">postmaster</span>, not about the
+ <span class="application">postmaster</span> which will eventually use this backup.
+ (These files can confuse <span class="application">pg_ctl</span>.)
+ </p><p>
+ It is often a good idea to also omit from the backup the files
+ within the cluster's <code class="filename">pg_replslot/</code> directory, so that
+ replication slots that exist on the primary do not become part of the
+ backup. Otherwise, the subsequent use of the backup to create a standby
+ may result in indefinite retention of WAL files on the standby, and
+ possibly bloat on the primary if hot standby feedback is enabled, because
+ the clients that are using those replication slots will still be connecting
+ to and updating the slots on the primary, not the standby. Even if the
+ backup is only intended for use in creating a new primary, copying the
+ replication slots isn't expected to be particularly useful, since the
+ contents of those slots will likely be badly out of date by the time
+ the new primary comes on line.
+ </p><p>
+ The contents of the directories <code class="filename">pg_dynshmem/</code>,
+ <code class="filename">pg_notify/</code>, <code class="filename">pg_serial/</code>,
+ <code class="filename">pg_snapshots/</code>, <code class="filename">pg_stat_tmp/</code>,
+ and <code class="filename">pg_subtrans/</code> (but not the directories themselves) can be
+ omitted from the backup as they will be initialized on postmaster startup.
+ </p><p>
+ Any file or directory beginning with <code class="filename">pgsql_tmp</code> can be
+ omitted from the backup. These files are removed on postmaster start and
+ the directories will be recreated as needed.
+ </p><p>
+ <code class="filename">pg_internal.init</code> files can be omitted from the
+ backup whenever a file of that name is found. These files contain
+ relation cache data that is always rebuilt when recovering.
+ </p><p>
+ The backup label
+ file includes the label string you gave to <code class="function">pg_backup_start</code>,
+ as well as the time at which <code class="function">pg_backup_start</code> was run, and
+ the name of the starting WAL file. In case of confusion it is therefore
+ possible to look inside a backup file and determine exactly which
+ backup session the dump file came from. The tablespace map file includes
+ the symbolic link names as they exist in the directory
+ <code class="filename">pg_tblspc/</code> and the full path of each symbolic link.
+ These files are not merely for your information; their presence and
+ contents are critical to the proper operation of the system's recovery
+ process.
+ </p><p>
+ It is also possible to make a backup while the server is
+ stopped. In this case, you obviously cannot use
+ <code class="function">pg_backup_start</code> or <code class="function">pg_backup_stop</code>, and
+ you will therefore be left to your own devices to keep track of which
+ backup is which and how far back the associated WAL files go.
+ It is generally better to follow the continuous archiving procedure above.
+ </p></div></div><div class="sect2" id="BACKUP-PITR-RECOVERY"><div class="titlepage"><div><div><h3 class="title">26.3.4. Recovering Using a Continuous Archive Backup</h3></div></div></div><p>
+ Okay, the worst has happened and you need to recover from your backup.
+ Here is the procedure:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ Stop the server, if it's running.
+ </p></li><li class="listitem"><p>
+ If you have the space to do so,
+ copy the whole cluster data directory and any tablespaces to a temporary
+ location in case you need them later. Note that this precaution will
+ require that you have enough free space on your system to hold two
+ copies of your existing database. If you do not have enough space,
+ you should at least save the contents of the cluster's <code class="filename">pg_wal</code>
+ subdirectory, as it might contain logs which
+ were not archived before the system went down.
+ </p></li><li class="listitem"><p>
+ Remove all existing files and subdirectories under the cluster data
+ directory and under the root directories of any tablespaces you are using.
+ </p></li><li class="listitem"><p>
+ Restore the database files from your file system backup. Be sure that they
+ are restored with the right ownership (the database system user, not
+ <code class="literal">root</code>!) and with the right permissions. If you are using
+ tablespaces,
+ you should verify that the symbolic links in <code class="filename">pg_tblspc/</code>
+ were correctly restored.
+ </p></li><li class="listitem"><p>
+ Remove any files present in <code class="filename">pg_wal/</code>; these came from the
+ file system backup and are therefore probably obsolete rather than current.
+ If you didn't archive <code class="filename">pg_wal/</code> at all, then recreate
+ it with proper permissions,
+ being careful to ensure that you re-establish it as a symbolic link
+ if you had it set up that way before.
+ </p></li><li class="listitem"><p>
+ If you have unarchived WAL segment files that you saved in step 2,
+ copy them into <code class="filename">pg_wal/</code>. (It is best to copy them,
+ not move them, so you still have the unmodified files if a
+ problem occurs and you have to start over.)
+ </p></li><li class="listitem"><p>
+ Set recovery configuration settings in
+ <code class="filename">postgresql.conf</code> (see <a class="xref" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY" title="20.5.5. Archive Recovery">Section 20.5.5</a>) and create a file
+ <code class="filename">recovery.signal</code> in the cluster
+ data directory. You might
+ also want to temporarily modify <code class="filename">pg_hba.conf</code> to prevent
+ ordinary users from connecting until you are sure the recovery was successful.
+ </p></li><li class="listitem"><p>
+ Start the server. The server will go into recovery mode and
+ proceed to read through the archived WAL files it needs. Should the
+ recovery be terminated because of an external error, the server can
+ simply be restarted and it will continue recovery. Upon completion
+ of the recovery process, the server will remove
+ <code class="filename">recovery.signal</code> (to prevent
+ accidentally re-entering recovery mode later) and then
+ commence normal database operations.
+ </p></li><li class="listitem"><p>
+ Inspect the contents of the database to ensure you have recovered to
+ the desired state. If not, return to step 1. If all is well,
+ allow your users to connect by restoring <code class="filename">pg_hba.conf</code> to normal.
+ </p></li></ol></div><p>
+ </p><p>
+ The key part of all this is to set up a recovery configuration that
+ describes how you want to recover and how far the recovery should
+ run. The one thing that you absolutely must specify is the <code class="varname">restore_command</code>,
+ which tells <span class="productname">PostgreSQL</span> how to retrieve archived
+ WAL file segments. Like the <code class="varname">archive_command</code>, this is
+ a shell command string. It can contain <code class="literal">%f</code>, which is
+ replaced by the name of the desired log file, and <code class="literal">%p</code>,
+ which is replaced by the path name to copy the log file to.
+ (The path name is relative to the current working directory,
+ i.e., the cluster's data directory.)
+ Write <code class="literal">%%</code> if you need to embed an actual <code class="literal">%</code>
+ character in the command. The simplest useful command is
+ something like:
+</p><pre class="programlisting">
+restore_command = 'cp /mnt/server/archivedir/%f %p'
+</pre><p>
+ which will copy previously archived WAL segments from the directory
+ <code class="filename">/mnt/server/archivedir</code>. Of course, you can use something
+ much more complicated, perhaps even a shell script that requests the
+ operator to mount an appropriate tape.
+ </p><p>
+ It is important that the command return nonzero exit status on failure.
+ The command <span class="emphasis"><em>will</em></span> be called requesting files that are not
+ present in the archive; it must return nonzero when so asked. This is not
+ an error condition. An exception is that if the command was terminated by
+ a signal (other than <span class="systemitem">SIGTERM</span>, which is used as
+ part of a database server shutdown) or an error by the shell (such as
+ command not found), then recovery will abort and the server will not start
+ up.
+ </p><p>
+ Not all of the requested files will be WAL segment
+ files; you should also expect requests for files with a suffix of
+ <code class="literal">.history</code>. Also be aware that
+ the base name of the <code class="literal">%p</code> path will be different from
+ <code class="literal">%f</code>; do not expect them to be interchangeable.
+ </p><p>
+ WAL segments that cannot be found in the archive will be sought in
+ <code class="filename">pg_wal/</code>; this allows use of recent un-archived segments.
+ However, segments that are available from the archive will be used in
+ preference to files in <code class="filename">pg_wal/</code>.
+ </p><p>
+ Normally, recovery will proceed through all available WAL segments,
+ thereby restoring the database to the current point in time (or as
+ close as possible given the available WAL segments). Therefore, a normal
+ recovery will end with a <span class="quote">“<span class="quote">file not found</span>”</span> message, the exact text
+ of the error message depending upon your choice of
+ <code class="varname">restore_command</code>. You may also see an error message
+ at the start of recovery for a file named something like
+ <code class="filename">00000001.history</code>. This is also normal and does not
+ indicate a problem in simple recovery situations; see
+ <a class="xref" href="continuous-archiving.html#BACKUP-TIMELINES" title="26.3.5. Timelines">Section 26.3.5</a> for discussion.
+ </p><p>
+ If you want to recover to some previous point in time (say, right before
+ the junior DBA dropped your main transaction table), just specify the
+ required <a class="link" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET" title="20.5.6. Recovery Target">stopping point</a>. You can specify
+ the stop point, known as the <span class="quote">“<span class="quote">recovery target</span>”</span>, either by
+ date/time, named restore point or by completion of a specific transaction
+ ID. As of this writing only the date/time and named restore point options
+ are very usable, since there are no tools to help you identify with any
+ accuracy which transaction ID to use.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The stop point must be after the ending time of the base backup, i.e.,
+ the end time of <code class="function">pg_backup_stop</code>. You cannot use a base backup
+ to recover to a time when that backup was in progress. (To
+ recover to such a time, you must go back to your previous base backup
+ and roll forward from there.)
+ </p></div><p>
+ If recovery finds corrupted WAL data, recovery will
+ halt at that point and the server will not start. In such a case the
+ recovery process could be re-run from the beginning, specifying a
+ <span class="quote">“<span class="quote">recovery target</span>”</span> before the point of corruption so that recovery
+ can complete normally.
+ If recovery fails for an external reason, such as a system crash or
+ if the WAL archive has become inaccessible, then the recovery can simply
+ be restarted and it will restart almost from where it failed.
+ Recovery restart works much like checkpointing in normal operation:
+ the server periodically forces all its state to disk, and then updates
+ the <code class="filename">pg_control</code> file to indicate that the already-processed
+ WAL data need not be scanned again.
+ </p></div><div class="sect2" id="BACKUP-TIMELINES"><div class="titlepage"><div><div><h3 class="title">26.3.5. Timelines</h3></div></div></div><a id="id-1.6.13.7.13.2" class="indexterm"></a><p>
+ The ability to restore the database to a previous point in time creates
+ some complexities that are akin to science-fiction stories about time
+ travel and parallel universes. For example, in the original history of the database,
+ suppose you dropped a critical table at 5:15PM on Tuesday evening, but
+ didn't realize your mistake until Wednesday noon.
+ Unfazed, you get out your backup, restore to the point-in-time 5:14PM
+ Tuesday evening, and are up and running. In <span class="emphasis"><em>this</em></span> history of
+ the database universe, you never dropped the table. But suppose
+ you later realize this wasn't such a great idea, and would like
+ to return to sometime Wednesday morning in the original history.
+ You won't be able
+ to if, while your database was up-and-running, it overwrote some of the
+ WAL segment files that led up to the time you now wish you
+ could get back to. Thus, to avoid this, you need to distinguish the series of
+ WAL records generated after you've done a point-in-time recovery from
+ those that were generated in the original database history.
+ </p><p>
+ To deal with this problem, <span class="productname">PostgreSQL</span> has a notion
+ of <em class="firstterm">timelines</em>. Whenever an archive recovery completes,
+ a new timeline is created to identify the series of WAL records
+ generated after that recovery. The timeline
+ ID number is part of WAL segment file names so a new timeline does
+ not overwrite the WAL data generated by previous timelines. It is
+ in fact possible to archive many different timelines. While that might
+ seem like a useless feature, it's often a lifesaver. Consider the
+ situation where you aren't quite sure what point-in-time to recover to,
+ and so have to do several point-in-time recoveries by trial and error
+ until you find the best place to branch off from the old history. Without
+ timelines this process would soon generate an unmanageable mess. With
+ timelines, you can recover to <span class="emphasis"><em>any</em></span> prior state, including
+ states in timeline branches that you abandoned earlier.
+ </p><p>
+ Every time a new timeline is created, <span class="productname">PostgreSQL</span> creates
+ a <span class="quote">“<span class="quote">timeline history</span>”</span> file that shows which timeline it branched
+ off from and when. These history files are necessary to allow the system
+ to pick the right WAL segment files when recovering from an archive that
+ contains multiple timelines. Therefore, they are archived into the WAL
+ archive area just like WAL segment files. The history files are just
+ small text files, so it's cheap and appropriate to keep them around
+ indefinitely (unlike the segment files which are large). You can, if
+ you like, add comments to a history file to record your own notes about
+ how and why this particular timeline was created. Such comments will be
+ especially valuable when you have a thicket of different timelines as
+ a result of experimentation.
+ </p><p>
+ The default behavior of recovery is to recover to the latest timeline found
+ in the archive. If you wish to recover to the timeline that was current
+ when the base backup was taken or into a specific child timeline (that
+ is, you want to return to some state that was itself generated after a
+ recovery attempt), you need to specify <code class="literal">current</code> or the
+ target timeline ID in <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-TIMELINE">recovery_target_timeline</a>. You
+ cannot recover into timelines that branched off earlier than the base backup.
+ </p></div><div class="sect2" id="BACKUP-TIPS"><div class="titlepage"><div><div><h3 class="title">26.3.6. Tips and Examples</h3></div></div></div><p>
+ Some tips for configuring continuous archiving are given here.
+ </p><div class="sect3" id="BACKUP-STANDALONE"><div class="titlepage"><div><div><h4 class="title">26.3.6.1. Standalone Hot Backups</h4></div></div></div><p>
+ It is possible to use <span class="productname">PostgreSQL</span>'s backup facilities to
+ produce standalone hot backups. These are backups that cannot be used
+ for point-in-time recovery, yet are typically much faster to backup and
+ restore than <span class="application">pg_dump</span> dumps. (They are also much larger
+ than <span class="application">pg_dump</span> dumps, so in some cases the speed advantage
+ might be negated.)
+ </p><p>
+ As with base backups, the easiest way to produce a standalone
+ hot backup is to use the <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a>
+ tool. If you include the <code class="literal">-X</code> parameter when calling
+ it, all the write-ahead log required to use the backup will be
+ included in the backup automatically, and no special action is
+ required to restore the backup.
+ </p></div><div class="sect3" id="COMPRESSED-ARCHIVE-LOGS"><div class="titlepage"><div><div><h4 class="title">26.3.6.2. Compressed Archive Logs</h4></div></div></div><p>
+ If archive storage size is a concern, you can use
+ <span class="application">gzip</span> to compress the archive files:
+</p><pre class="programlisting">
+archive_command = 'gzip &lt; %p &gt; /mnt/server/archivedir/%f.gz'
+</pre><p>
+ You will then need to use <span class="application">gunzip</span> during recovery:
+</p><pre class="programlisting">
+restore_command = 'gunzip &lt; /mnt/server/archivedir/%f.gz &gt; %p'
+</pre><p>
+ </p></div><div class="sect3" id="BACKUP-SCRIPTS"><div class="titlepage"><div><div><h4 class="title">26.3.6.3. <code class="varname">archive_command</code> Scripts</h4></div></div></div><p>
+ Many people choose to use scripts to define their
+ <code class="varname">archive_command</code>, so that their
+ <code class="filename">postgresql.conf</code> entry looks very simple:
+</p><pre class="programlisting">
+archive_command = 'local_backup_script.sh "%p" "%f"'
+</pre><p>
+ Using a separate script file is advisable any time you want to use
+ more than a single command in the archiving process.
+ This allows all complexity to be managed within the script, which
+ can be written in a popular scripting language such as
+ <span class="application">bash</span> or <span class="application">perl</span>.
+ </p><p>
+ Examples of requirements that might be solved within a script include:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Copying data to secure off-site data storage
+ </p></li><li class="listitem"><p>
+ Batching WAL files so that they are transferred every three hours,
+ rather than one at a time
+ </p></li><li class="listitem"><p>
+ Interfacing with other backup and recovery software
+ </p></li><li class="listitem"><p>
+ Interfacing with monitoring software to report errors
+ </p></li></ul></div><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ When using an <code class="varname">archive_command</code> script, it's desirable
+ to enable <a class="xref" href="runtime-config-logging.html#GUC-LOGGING-COLLECTOR">logging_collector</a>.
+ Any messages written to <span class="systemitem">stderr</span> from the script will then
+ appear in the database server log, allowing complex configurations to
+ be diagnosed easily if they fail.
+ </p></div></div></div><div class="sect2" id="CONTINUOUS-ARCHIVING-CAVEATS"><div class="titlepage"><div><div><h3 class="title">26.3.7. Caveats</h3></div></div></div><p>
+ At this writing, there are several limitations of the continuous archiving
+ technique. These will probably be fixed in future releases:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If a <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE"><code class="command">CREATE DATABASE</code></a>
+ command is executed while a base backup is being taken, and then
+ the template database that the <code class="command">CREATE DATABASE</code> copied
+ is modified while the base backup is still in progress, it is
+ possible that recovery will cause those modifications to be
+ propagated into the created database as well. This is of course
+ undesirable. To avoid this risk, it is best not to modify any
+ template databases while taking a base backup.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="sql-createtablespace.html" title="CREATE TABLESPACE"><code class="command">CREATE TABLESPACE</code></a>
+ commands are WAL-logged with the literal absolute path, and will
+ therefore be replayed as tablespace creations with the same
+ absolute path. This might be undesirable if the log is being
+ replayed on a different machine. It can be dangerous even if the
+ log is being replayed on the same machine, but into a new data
+ directory: the replay will still overwrite the contents of the
+ original tablespace. To avoid potential gotchas of this sort,
+ the best practice is to take a new base backup after creating or
+ dropping tablespaces.
+ </p></li></ul></div><p>
+ </p><p>
+ It should also be noted that the default <acronym class="acronym">WAL</acronym>
+ format is fairly bulky since it includes many disk page snapshots.
+ These page snapshots are designed to support crash recovery, since
+ we might need to fix partially-written disk pages. Depending on
+ your system hardware and software, the risk of partial writes might
+ be small enough to ignore, in which case you can significantly
+ reduce the total volume of archived logs by turning off page
+ snapshots using the <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a>
+ parameter. (Read the notes and warnings in <a class="xref" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Chapter 30</a>
+ before you do so.) Turning off page snapshots does not prevent
+ use of the logs for PITR operations. An area for future
+ development is to compress archived WAL data by removing
+ unnecessary page copies even when <code class="varname">full_page_writes</code> is
+ on. In the meantime, administrators might wish to reduce the number
+ of page snapshots included in WAL by increasing the checkpoint
+ interval parameters as much as feasible.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="backup-file.html" title="26.2. File System Level Backup">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="backup.html" title="Chapter 26. Backup and Restore">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">26.2. File System Level Backup </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 27. High Availability, Load Balancing, and Replication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-build-sql-delete.html b/doc/src/sgml/html/contrib-dblink-build-sql-delete.html
new file mode 100644
index 0000000..f280b23
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-build-sql-delete.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_build_sql_delete</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-build-sql-insert.html" title="dblink_build_sql_insert" /><link rel="next" href="contrib-dblink-build-sql-update.html" title="dblink_build_sql_update" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_build_sql_delete</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-build-sql-insert.html" title="dblink_build_sql_insert">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-build-sql-update.html" title="dblink_build_sql_update">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-BUILD-SQL-DELETE"><div class="titlepage"></div><a id="id-1.11.7.21.22.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_build_sql_delete</span></h2><p>dblink_build_sql_delete — builds a DELETE statement using supplied values for primary
+ key field values
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_build_sql_delete(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] tgt_pk_att_vals_array) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.22.5"><h2>Description</h2><p>
+ <code class="function">dblink_build_sql_delete</code> can be useful in doing selective
+ replication of a local table to a remote database. It builds an SQL
+ <code class="command">DELETE</code> command that will delete the row with the given
+ primary key values.
+ </p></div><div class="refsect1" id="id-1.11.7.21.22.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>relname</code></em></span></dt><dd><p>
+ Name of a local relation, for example <code class="literal">foo</code> or
+ <code class="literal">myschema.mytab</code>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <code class="literal">"FooBar"</code>; without quotes, the string
+ will be folded to lower case.
+ </p></dd><dt><span class="term"><em class="parameter"><code>primary_key_attnums</code></em></span></dt><dd><p>
+ Attribute numbers (1-based) of the primary key fields,
+ for example <code class="literal">1 2</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>num_primary_key_atts</code></em></span></dt><dd><p>
+ The number of primary key fields.
+ </p></dd><dt><span class="term"><em class="parameter"><code>tgt_pk_att_vals_array</code></em></span></dt><dd><p>
+ Values of the primary key fields to be used in the resulting
+ <code class="command">DELETE</code> command. Each field is represented in text form.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.22.7"><h2>Return Value</h2><p>Returns the requested SQL statement as text.</p></div><div class="refsect1" id="id-1.11.7.21.22.8"><h2>Notes</h2><p>
+ As of <span class="productname">PostgreSQL</span> 9.0, the attribute numbers in
+ <em class="parameter"><code>primary_key_attnums</code></em> are interpreted as logical
+ column numbers, corresponding to the column's position in
+ <code class="literal">SELECT * FROM relname</code>. Previous versions interpreted the
+ numbers as physical column positions. There is a difference if any
+ column(s) to the left of the indicated column have been dropped during
+ the lifetime of the table.
+ </p></div><div class="refsect1" id="id-1.11.7.21.22.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_build_sql_delete('"MyFoo"', '1 2', 2, '{"1", "b"}');
+ dblink_build_sql_delete
+---------------------------------------------
+ DELETE FROM "MyFoo" WHERE f1='1' AND f2='b'
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-build-sql-insert.html" title="dblink_build_sql_insert">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-build-sql-update.html" title="dblink_build_sql_update">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_build_sql_insert </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_build_sql_update</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-build-sql-insert.html b/doc/src/sgml/html/contrib-dblink-build-sql-insert.html
new file mode 100644
index 0000000..0cc6291
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-build-sql-insert.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_build_sql_insert</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-get-pkey.html" title="dblink_get_pkey" /><link rel="next" href="contrib-dblink-build-sql-delete.html" title="dblink_build_sql_delete" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_build_sql_insert</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-get-pkey.html" title="dblink_get_pkey">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-build-sql-delete.html" title="dblink_build_sql_delete">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-BUILD-SQL-INSERT"><div class="titlepage"></div><a id="id-1.11.7.21.21.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_build_sql_insert</span></h2><p>dblink_build_sql_insert —
+ builds an INSERT statement using a local tuple, replacing the
+ primary key field values with alternative supplied values
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_build_sql_insert(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] src_pk_att_vals_array,
+ text[] tgt_pk_att_vals_array) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.21.5"><h2>Description</h2><p>
+ <code class="function">dblink_build_sql_insert</code> can be useful in doing selective
+ replication of a local table to a remote database. It selects a row
+ from the local table based on primary key, and then builds an SQL
+ <code class="command">INSERT</code> command that will duplicate that row, but with
+ the primary key values replaced by the values in the last argument.
+ (To make an exact copy of the row, just specify the same values for
+ the last two arguments.)
+ </p></div><div class="refsect1" id="id-1.11.7.21.21.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>relname</code></em></span></dt><dd><p>
+ Name of a local relation, for example <code class="literal">foo</code> or
+ <code class="literal">myschema.mytab</code>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <code class="literal">"FooBar"</code>; without quotes, the string
+ will be folded to lower case.
+ </p></dd><dt><span class="term"><em class="parameter"><code>primary_key_attnums</code></em></span></dt><dd><p>
+ Attribute numbers (1-based) of the primary key fields,
+ for example <code class="literal">1 2</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>num_primary_key_atts</code></em></span></dt><dd><p>
+ The number of primary key fields.
+ </p></dd><dt><span class="term"><em class="parameter"><code>src_pk_att_vals_array</code></em></span></dt><dd><p>
+ Values of the primary key fields to be used to look up the
+ local tuple. Each field is represented in text form.
+ An error is thrown if there is no local row with these
+ primary key values.
+ </p></dd><dt><span class="term"><em class="parameter"><code>tgt_pk_att_vals_array</code></em></span></dt><dd><p>
+ Values of the primary key fields to be placed in the resulting
+ <code class="command">INSERT</code> command. Each field is represented in text form.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.21.7"><h2>Return Value</h2><p>Returns the requested SQL statement as text.</p></div><div class="refsect1" id="id-1.11.7.21.21.8"><h2>Notes</h2><p>
+ As of <span class="productname">PostgreSQL</span> 9.0, the attribute numbers in
+ <em class="parameter"><code>primary_key_attnums</code></em> are interpreted as logical
+ column numbers, corresponding to the column's position in
+ <code class="literal">SELECT * FROM relname</code>. Previous versions interpreted the
+ numbers as physical column positions. There is a difference if any
+ column(s) to the left of the indicated column have been dropped during
+ the lifetime of the table.
+ </p></div><div class="refsect1" id="id-1.11.7.21.21.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_build_sql_insert('foo', '1 2', 2, '{"1", "a"}', '{"1", "b''a"}');
+ dblink_build_sql_insert
+--------------------------------------------------
+ INSERT INTO foo(f1,f2,f3) VALUES('1','b''a','1')
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-get-pkey.html" title="dblink_get_pkey">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-build-sql-delete.html" title="dblink_build_sql_delete">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_get_pkey </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_build_sql_delete</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-build-sql-update.html b/doc/src/sgml/html/contrib-dblink-build-sql-update.html
new file mode 100644
index 0000000..4b04116
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-build-sql-update.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_build_sql_update</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-build-sql-delete.html" title="dblink_build_sql_delete" /><link rel="next" href="dict-int.html" title="F.13. dict_int" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_build_sql_update</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-build-sql-delete.html" title="dblink_build_sql_delete">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dict-int.html" title="F.13. dict_int">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-BUILD-SQL-UPDATE"><div class="titlepage"></div><a id="id-1.11.7.21.23.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_build_sql_update</span></h2><p>dblink_build_sql_update — builds an UPDATE statement using a local tuple, replacing
+ the primary key field values with alternative supplied values
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_build_sql_update(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] src_pk_att_vals_array,
+ text[] tgt_pk_att_vals_array) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.23.5"><h2>Description</h2><p>
+ <code class="function">dblink_build_sql_update</code> can be useful in doing selective
+ replication of a local table to a remote database. It selects a row
+ from the local table based on primary key, and then builds an SQL
+ <code class="command">UPDATE</code> command that will duplicate that row, but with
+ the primary key values replaced by the values in the last argument.
+ (To make an exact copy of the row, just specify the same values for
+ the last two arguments.) The <code class="command">UPDATE</code> command always assigns
+ all fields of the row — the main difference between this and
+ <code class="function">dblink_build_sql_insert</code> is that it's assumed that
+ the target row already exists in the remote table.
+ </p></div><div class="refsect1" id="id-1.11.7.21.23.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>relname</code></em></span></dt><dd><p>
+ Name of a local relation, for example <code class="literal">foo</code> or
+ <code class="literal">myschema.mytab</code>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <code class="literal">"FooBar"</code>; without quotes, the string
+ will be folded to lower case.
+ </p></dd><dt><span class="term"><em class="parameter"><code>primary_key_attnums</code></em></span></dt><dd><p>
+ Attribute numbers (1-based) of the primary key fields,
+ for example <code class="literal">1 2</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>num_primary_key_atts</code></em></span></dt><dd><p>
+ The number of primary key fields.
+ </p></dd><dt><span class="term"><em class="parameter"><code>src_pk_att_vals_array</code></em></span></dt><dd><p>
+ Values of the primary key fields to be used to look up the
+ local tuple. Each field is represented in text form.
+ An error is thrown if there is no local row with these
+ primary key values.
+ </p></dd><dt><span class="term"><em class="parameter"><code>tgt_pk_att_vals_array</code></em></span></dt><dd><p>
+ Values of the primary key fields to be placed in the resulting
+ <code class="command">UPDATE</code> command. Each field is represented in text form.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.23.7"><h2>Return Value</h2><p>Returns the requested SQL statement as text.</p></div><div class="refsect1" id="id-1.11.7.21.23.8"><h2>Notes</h2><p>
+ As of <span class="productname">PostgreSQL</span> 9.0, the attribute numbers in
+ <em class="parameter"><code>primary_key_attnums</code></em> are interpreted as logical
+ column numbers, corresponding to the column's position in
+ <code class="literal">SELECT * FROM relname</code>. Previous versions interpreted the
+ numbers as physical column positions. There is a difference if any
+ column(s) to the left of the indicated column have been dropped during
+ the lifetime of the table.
+ </p></div><div class="refsect1" id="id-1.11.7.21.23.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_build_sql_update('foo', '1 2', 2, '{"1", "a"}', '{"1", "b"}');
+ dblink_build_sql_update
+-------------------------------------------------------------
+ UPDATE foo SET f1='1',f2='b',f3='1' WHERE f1='1' AND f2='b'
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-build-sql-delete.html" title="dblink_build_sql_delete">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dict-int.html" title="F.13. dict_int">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_build_sql_delete </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.13. dict_int</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-cancel-query.html b/doc/src/sgml/html/contrib-dblink-cancel-query.html
new file mode 100644
index 0000000..706e782
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-cancel-query.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_cancel_query</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-get-result.html" title="dblink_get_result" /><link rel="next" href="contrib-dblink-get-pkey.html" title="dblink_get_pkey" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_cancel_query</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-get-result.html" title="dblink_get_result">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-get-pkey.html" title="dblink_get_pkey">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-CANCEL-QUERY"><div class="titlepage"></div><a id="id-1.11.7.21.19.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_cancel_query</span></h2><p>dblink_cancel_query — cancels any active query on the named connection</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_cancel_query(text connname) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.19.5"><h2>Description</h2><p>
+ <code class="function">dblink_cancel_query</code> attempts to cancel any query that
+ is in progress on the named connection. Note that this is not
+ certain to succeed (since, for example, the remote query might
+ already have finished). A cancel request simply improves the
+ odds that the query will fail soon. You must still complete the
+ normal query protocol, for example by calling
+ <code class="function">dblink_get_result</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.19.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.19.7"><h2>Return Value</h2><p>
+ Returns <code class="literal">OK</code> if the cancel request has been sent, or
+ the text of an error message on failure.
+ </p></div><div class="refsect1" id="id-1.11.7.21.19.8"><h2>Examples</h2><pre class="programlisting">
+SELECT dblink_cancel_query('dtest1');
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-get-result.html" title="dblink_get_result">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-get-pkey.html" title="dblink_get_pkey">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_get_result </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_get_pkey</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-close.html b/doc/src/sgml/html/contrib-dblink-close.html
new file mode 100644
index 0000000..1ab562e
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-close.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_close</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-fetch.html" title="dblink_fetch" /><link rel="next" href="contrib-dblink-get-connections.html" title="dblink_get_connections" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_close</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-fetch.html" title="dblink_fetch">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-get-connections.html" title="dblink_get_connections">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-CLOSE"><div class="titlepage"></div><a id="id-1.11.7.21.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_close</span></h2><p>dblink_close — closes a cursor in a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_close(text cursorname [, bool fail_on_error]) returns text
+dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.12.5"><h2>Description</h2><p>
+ <code class="function">dblink_close</code> closes a cursor previously opened with
+ <code class="function">dblink_open</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.12.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </p></dd><dt><span class="term"><em class="parameter"><code>cursorname</code></em></span></dt><dd><p>
+ The name of the cursor to close.
+ </p></dd><dt><span class="term"><em class="parameter"><code>fail_on_error</code></em></span></dt><dd><p>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function's return value is set to <code class="literal">ERROR</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.12.7"><h2>Return Value</h2><p>
+ Returns status, either <code class="literal">OK</code> or <code class="literal">ERROR</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.12.8"><h2>Notes</h2><p>
+ If <code class="function">dblink_open</code> started an explicit transaction block,
+ and this is the last remaining open cursor in this connection,
+ <code class="function">dblink_close</code> will issue the matching <code class="command">COMMIT</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.12.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_open('foo', 'select proname, prosrc from pg_proc');
+ dblink_open
+-------------
+ OK
+(1 row)
+
+SELECT dblink_close('foo');
+ dblink_close
+--------------
+ OK
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-fetch.html" title="dblink_fetch">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-get-connections.html" title="dblink_get_connections">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_fetch </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_get_connections</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-connect-u.html b/doc/src/sgml/html/contrib-dblink-connect-u.html
new file mode 100644
index 0000000..76b22bf
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-connect-u.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_connect_u</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-connect.html" title="dblink_connect" /><link rel="next" href="contrib-dblink-disconnect.html" title="dblink_disconnect" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_connect_u</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-connect.html" title="dblink_connect">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-disconnect.html" title="dblink_disconnect">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-CONNECT-U"><div class="titlepage"></div><a id="id-1.11.7.21.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_connect_u</span></h2><p>dblink_connect_u — opens a persistent connection to a remote database, insecurely</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_connect_u(text connstr) returns text
+dblink_connect_u(text connname, text connstr) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.6.5"><h2>Description</h2><p>
+ <code class="function">dblink_connect_u()</code> is identical to
+ <code class="function">dblink_connect()</code>, except that it will allow non-superusers
+ to connect using any authentication method.
+ </p><p>
+ If the remote server selects an authentication method that does not
+ involve a password, then impersonation and subsequent escalation of
+ privileges can occur, because the session will appear to have
+ originated from the user as which the local <span class="productname">PostgreSQL</span>
+ server runs. Also, even if the remote server does demand a password,
+ it is possible for the password to be supplied from the server
+ environment, such as a <code class="filename">~/.pgpass</code> file belonging to the
+ server's user. This opens not only a risk of impersonation, but the
+ possibility of exposing a password to an untrustworthy remote server.
+ Therefore, <code class="function">dblink_connect_u()</code> is initially
+ installed with all privileges revoked from <code class="literal">PUBLIC</code>,
+ making it un-callable except by superusers. In some situations
+ it may be appropriate to grant <code class="literal">EXECUTE</code> permission for
+ <code class="function">dblink_connect_u()</code> to specific users who are considered
+ trustworthy, but this should be done with care. It is also recommended
+ that any <code class="filename">~/.pgpass</code> file belonging to the server's user
+ <span class="emphasis"><em>not</em></span> contain any records specifying a wildcard host name.
+ </p><p>
+ For further details see <code class="function">dblink_connect()</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-connect.html" title="dblink_connect">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-disconnect.html" title="dblink_disconnect">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_connect </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_disconnect</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-connect.html b/doc/src/sgml/html/contrib-dblink-connect.html
new file mode 100644
index 0000000..b476980
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-connect.html
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_connect</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dblink.html" title="F.12. dblink" /><link rel="next" href="contrib-dblink-connect-u.html" title="dblink_connect_u" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_connect</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dblink.html" title="F.12. dblink">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-connect-u.html" title="dblink_connect_u">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-CONNECT"><div class="titlepage"></div><a id="id-1.11.7.21.5.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_connect</span></h2><p>dblink_connect — opens a persistent connection to a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_connect(text connstr) returns text
+dblink_connect(text connname, text connstr) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.5.5"><h2>Description</h2><p>
+ <code class="function">dblink_connect()</code> establishes a connection to a remote
+ <span class="productname">PostgreSQL</span> database. The server and database to
+ be contacted are identified through a standard <span class="application">libpq</span>
+ connection string. Optionally, a name can be assigned to the
+ connection. Multiple named connections can be open at once, but
+ only one unnamed connection is permitted at a time. The connection
+ will persist until closed or until the database session is ended.
+ </p><p>
+ The connection string may also be the name of an existing foreign
+ server. It is recommended to use the foreign-data wrapper
+ <code class="literal">dblink_fdw</code> when defining the foreign
+ server. See the example below, as well as
+ <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a> and
+ <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.5.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ The name to use for this connection; if omitted, an unnamed
+ connection is opened, replacing any existing unnamed connection.
+ </p></dd><dt><span class="term"><em class="parameter"><code>connstr</code></em></span></dt><dd><p><span class="application">libpq</span>-style connection info string, for example
+ <code class="literal">hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres
+ password=mypasswd options=-csearch_path=</code>.
+ For details see <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a>.
+ Alternatively, the name of a foreign server.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.5.7"><h2>Return Value</h2><p>
+ Returns status, which is always <code class="literal">OK</code> (since any error
+ causes the function to throw an error instead of returning).
+ </p></div><div class="refsect1" id="id-1.11.7.21.5.8"><h2>Notes</h2><p>
+ If untrusted users have access to a database that has not adopted a
+ <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage pattern</a>,
+ begin each session by removing publicly-writable schemas from
+ <code class="varname">search_path</code>. One could, for example,
+ add <code class="literal">options=-csearch_path=</code> to
+ <em class="parameter"><code>connstr</code></em>. This consideration is not specific
+ to <code class="filename">dblink</code>; it applies to every interface for
+ executing arbitrary SQL commands.
+ </p><p>
+ Only superusers may use <code class="function">dblink_connect</code> to create
+ non-password-authenticated connections. If non-superusers need this
+ capability, use <code class="function">dblink_connect_u</code> instead.
+ </p><p>
+ It is unwise to choose connection names that contain equal signs,
+ as this opens a risk of confusion with connection info strings
+ in other <code class="filename">dblink</code> functions.
+ </p></div><div class="refsect1" id="id-1.11.7.21.5.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_connect('myconn', 'dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+-- FOREIGN DATA WRAPPER functionality
+-- Note: local connection must require password authentication for this to work properly
+-- Otherwise, you will receive the following error from dblink_connect():
+-- ERROR: password is required
+-- DETAIL: Non-superuser cannot connect if the server does not request a password.
+-- HINT: Target server's authentication method must be changed.
+
+CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw OPTIONS (hostaddr '127.0.0.1', dbname 'contrib_regression');
+
+CREATE USER regress_dblink_user WITH PASSWORD 'secret';
+CREATE USER MAPPING FOR regress_dblink_user SERVER fdtest OPTIONS (user 'regress_dblink_user', password 'secret');
+GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
+GRANT SELECT ON TABLE foo TO regress_dblink_user;
+
+\set ORIGINAL_USER :USER
+\c - regress_dblink_user
+SELECT dblink_connect('myconn', 'fdtest');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT * FROM dblink('myconn', 'SELECT * FROM foo') AS t(a int, b text, c text[]);
+ a | b | c
+----+---+---------------
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+ 3 | d | {a3,b3,c3}
+ 4 | e | {a4,b4,c4}
+ 5 | f | {a5,b5,c5}
+ 6 | g | {a6,b6,c6}
+ 7 | h | {a7,b7,c7}
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ 10 | k | {a10,b10,c10}
+(11 rows)
+
+\c - :ORIGINAL_USER
+REVOKE USAGE ON FOREIGN SERVER fdtest FROM regress_dblink_user;
+REVOKE SELECT ON TABLE foo FROM regress_dblink_user;
+DROP USER MAPPING FOR regress_dblink_user SERVER fdtest;
+DROP USER regress_dblink_user;
+DROP SERVER fdtest;
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dblink.html" title="F.12. dblink">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-connect-u.html" title="dblink_connect_u">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.12. dblink </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_connect_u</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-disconnect.html b/doc/src/sgml/html/contrib-dblink-disconnect.html
new file mode 100644
index 0000000..e3de579
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-disconnect.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_disconnect</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-connect-u.html" title="dblink_connect_u" /><link rel="next" href="contrib-dblink-function.html" title="dblink" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_disconnect</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-connect-u.html" title="dblink_connect_u">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-function.html" title="dblink">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-DISCONNECT"><div class="titlepage"></div><a id="id-1.11.7.21.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_disconnect</span></h2><p>dblink_disconnect — closes a persistent connection to a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_disconnect() returns text
+dblink_disconnect(text connname) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.7.5"><h2>Description</h2><p>
+ <code class="function">dblink_disconnect()</code> closes a connection previously opened
+ by <code class="function">dblink_connect()</code>. The form with no arguments closes
+ an unnamed connection.
+ </p></div><div class="refsect1" id="id-1.11.7.21.7.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ The name of a named connection to be closed.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.7.7"><h2>Return Value</h2><p>
+ Returns status, which is always <code class="literal">OK</code> (since any error
+ causes the function to throw an error instead of returning).
+ </p></div><div class="refsect1" id="id-1.11.7.21.7.8"><h2>Examples</h2><pre class="screen">
+SELECT dblink_disconnect();
+ dblink_disconnect
+-------------------
+ OK
+(1 row)
+
+SELECT dblink_disconnect('myconn');
+ dblink_disconnect
+-------------------
+ OK
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-connect-u.html" title="dblink_connect_u">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-function.html" title="dblink">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_connect_u </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-error-message.html b/doc/src/sgml/html/contrib-dblink-error-message.html
new file mode 100644
index 0000000..d0d2aad
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-error-message.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_error_message</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-get-connections.html" title="dblink_get_connections" /><link rel="next" href="contrib-dblink-send-query.html" title="dblink_send_query" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_error_message</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-get-connections.html" title="dblink_get_connections">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-send-query.html" title="dblink_send_query">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-ERROR-MESSAGE"><div class="titlepage"></div><a id="id-1.11.7.21.14.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_error_message</span></h2><p>dblink_error_message — gets last error message on the named connection</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_error_message(text connname) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.14.5"><h2>Description</h2><p>
+ <code class="function">dblink_error_message</code> fetches the most recent remote
+ error message for a given connection.
+ </p></div><div class="refsect1" id="id-1.11.7.21.14.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.14.7"><h2>Return Value</h2><p>
+ Returns last error message, or <code class="literal">OK</code> if there has been
+ no error in this connection.
+ </p></div><div class="refsect1" id="id-1.11.7.21.14.8"><h2>Notes</h2><p>
+ When asynchronous queries are initiated by
+ <code class="function">dblink_send_query</code>, the error message associated with
+ the connection might not get updated until the server's response message
+ is consumed. This typically means that <code class="function">dblink_is_busy</code>
+ or <code class="function">dblink_get_result</code> should be called prior to
+ <code class="function">dblink_error_message</code>, so that any error generated by
+ the asynchronous query will be visible.
+ </p></div><div class="refsect1" id="id-1.11.7.21.14.9"><h2>Examples</h2><pre class="programlisting">
+SELECT dblink_error_message('dtest1');
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-get-connections.html" title="dblink_get_connections">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-send-query.html" title="dblink_send_query">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_get_connections </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_send_query</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-exec.html b/doc/src/sgml/html/contrib-dblink-exec.html
new file mode 100644
index 0000000..e72222f
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-exec.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_exec</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-function.html" title="dblink" /><link rel="next" href="contrib-dblink-open.html" title="dblink_open" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_exec</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-function.html" title="dblink">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-open.html" title="dblink_open">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-EXEC"><div class="titlepage"></div><a id="id-1.11.7.21.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_exec</span></h2><p>dblink_exec — executes a command in a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_exec(text connname, text sql [, bool fail_on_error]) returns text
+dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text
+dblink_exec(text sql [, bool fail_on_error]) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.9.5"><h2>Description</h2><p>
+ <code class="function">dblink_exec</code> executes a command (that is, any SQL statement
+ that doesn't return rows) in a remote database.
+ </p><p>
+ When two <code class="type">text</code> arguments are given, the first one is first
+ looked up as a persistent connection's name; if found, the command
+ is executed on that connection. If not found, the first argument
+ is treated as a connection info string as for <code class="function">dblink_connect</code>,
+ and the indicated connection is made just for the duration of this command.
+ </p></div><div class="refsect1" id="id-1.11.7.21.9.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </p></dd><dt><span class="term"><em class="parameter"><code>connstr</code></em></span></dt><dd><p>
+ A connection info string, as previously described for
+ <code class="function">dblink_connect</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>sql</code></em></span></dt><dd><p>
+ The SQL command that you wish to execute in the remote database,
+ for example
+ <code class="literal">insert into foo values(0, 'a', '{"a0","b0","c0"}')</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>fail_on_error</code></em></span></dt><dd><p>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function's return value is set to <code class="literal">ERROR</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.9.7"><h2>Return Value</h2><p>
+ Returns status, either the command's status string or <code class="literal">ERROR</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.9.8"><h2>Examples</h2><pre class="screen">
+SELECT dblink_connect('dbname=dblink_test_standby');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_exec('insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');');
+ dblink_exec
+-----------------
+ INSERT 943366 1
+(1 row)
+
+SELECT dblink_connect('myconn', 'dbname=regression');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_exec('myconn', 'insert into foo values(21, ''z'', ''{"a0","b0","c0"}'');');
+ dblink_exec
+------------------
+ INSERT 6432584 1
+(1 row)
+
+SELECT dblink_exec('myconn', 'insert into pg_class values (''foo'')',false);
+NOTICE: sql error
+DETAIL: ERROR: null value in column "relnamespace" violates not-null constraint
+
+ dblink_exec
+-------------
+ ERROR
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-function.html" title="dblink">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-open.html" title="dblink_open">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_open</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-fetch.html b/doc/src/sgml/html/contrib-dblink-fetch.html
new file mode 100644
index 0000000..edae456
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-fetch.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_fetch</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-open.html" title="dblink_open" /><link rel="next" href="contrib-dblink-close.html" title="dblink_close" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_fetch</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-open.html" title="dblink_open">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-close.html" title="dblink_close">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-FETCH"><div class="titlepage"></div><a id="id-1.11.7.21.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_fetch</span></h2><p>dblink_fetch — returns rows from an open cursor in a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record
+dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record
+</pre></div><div class="refsect1" id="id-1.11.7.21.11.5"><h2>Description</h2><p>
+ <code class="function">dblink_fetch</code> fetches rows from a cursor previously
+ established by <code class="function">dblink_open</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.11.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </p></dd><dt><span class="term"><em class="parameter"><code>cursorname</code></em></span></dt><dd><p>
+ The name of the cursor to fetch from.
+ </p></dd><dt><span class="term"><em class="parameter"><code>howmany</code></em></span></dt><dd><p>
+ The maximum number of rows to retrieve. The next <em class="parameter"><code>howmany</code></em>
+ rows are fetched, starting at the current cursor position, moving
+ forward. Once the cursor has reached its end, no more rows are produced.
+ </p></dd><dt><span class="term"><em class="parameter"><code>fail_on_error</code></em></span></dt><dd><p>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function returns no rows.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.11.7"><h2>Return Value</h2><p>
+ The function returns the row(s) fetched from the cursor. To use this
+ function, you will need to specify the expected set of columns,
+ as previously discussed for <code class="function">dblink</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.11.8"><h2>Notes</h2><p>
+ On a mismatch between the number of return columns specified in the
+ <code class="literal">FROM</code> clause, and the actual number of columns returned by the
+ remote cursor, an error will be thrown. In this event, the remote cursor
+ is still advanced by as many rows as it would have been if the error had
+ not occurred. The same is true for any other error occurring in the local
+ query after the remote <code class="command">FETCH</code> has been done.
+ </p></div><div class="refsect1" id="id-1.11.7.21.11.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_open('foo', 'select proname, prosrc from pg_proc where proname like ''bytea%''');
+ dblink_open
+-------------
+ OK
+(1 row)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+----------+----------
+ byteacat | byteacat
+ byteacmp | byteacmp
+ byteaeq | byteaeq
+ byteage | byteage
+ byteagt | byteagt
+(5 rows)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+-----------+-----------
+ byteain | byteain
+ byteale | byteale
+ bytealike | bytealike
+ bytealt | bytealt
+ byteane | byteane
+(5 rows)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+------------+------------
+ byteanlike | byteanlike
+ byteaout | byteaout
+(2 rows)
+
+SELECT * FROM dblink_fetch('foo', 5) AS (funcname name, source text);
+ funcname | source
+----------+--------
+(0 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-open.html" title="dblink_open">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-close.html" title="dblink_close">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_open </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_close</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-function.html b/doc/src/sgml/html/contrib-dblink-function.html
new file mode 100644
index 0000000..483bfdc
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-function.html
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-disconnect.html" title="dblink_disconnect" /><link rel="next" href="contrib-dblink-exec.html" title="dblink_exec" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-disconnect.html" title="dblink_disconnect">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-exec.html" title="dblink_exec">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-FUNCTION"><div class="titlepage"></div><a id="id-1.11.7.21.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink</span></h2><p>dblink — executes a query in a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink(text connname, text sql [, bool fail_on_error]) returns setof record
+dblink(text connstr, text sql [, bool fail_on_error]) returns setof record
+dblink(text sql [, bool fail_on_error]) returns setof record
+</pre></div><div class="refsect1" id="id-1.11.7.21.8.5"><h2>Description</h2><p>
+ <code class="function">dblink</code> executes a query (usually a <code class="command">SELECT</code>,
+ but it can be any SQL statement that returns rows) in a remote database.
+ </p><p>
+ When two <code class="type">text</code> arguments are given, the first one is first
+ looked up as a persistent connection's name; if found, the command
+ is executed on that connection. If not found, the first argument
+ is treated as a connection info string as for <code class="function">dblink_connect</code>,
+ and the indicated connection is made just for the duration of this command.
+ </p></div><div class="refsect1" id="id-1.11.7.21.8.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </p></dd><dt><span class="term"><em class="parameter"><code>connstr</code></em></span></dt><dd><p>
+ A connection info string, as previously described for
+ <code class="function">dblink_connect</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>sql</code></em></span></dt><dd><p>
+ The SQL query that you wish to execute in the remote database,
+ for example <code class="literal">select * from foo</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>fail_on_error</code></em></span></dt><dd><p>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function returns no rows.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.8.7"><h2>Return Value</h2><p>
+ The function returns the row(s) produced by the query. Since
+ <code class="function">dblink</code> can be used with any query, it is declared
+ to return <code class="type">record</code>, rather than specifying any particular
+ set of columns. This means that you must specify the expected
+ set of columns in the calling query — otherwise
+ <span class="productname">PostgreSQL</span> would not know what to expect.
+ Here is an example:
+
+</p><pre class="programlisting">
+SELECT *
+ FROM dblink('dbname=mydb options=-csearch_path=',
+ 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text)
+ WHERE proname LIKE 'bytea%';
+</pre><p>
+
+ The <span class="quote">“<span class="quote">alias</span>”</span> part of the <code class="literal">FROM</code> clause must
+ specify the column names and types that the function will return.
+ (Specifying column names in an alias is actually standard SQL
+ syntax, but specifying column types is a <span class="productname">PostgreSQL</span>
+ extension.) This allows the system to understand what
+ <code class="literal">*</code> should expand to, and what <code class="structname">proname</code>
+ in the <code class="literal">WHERE</code> clause refers to, in advance of trying
+ to execute the function. At run time, an error will be thrown
+ if the actual query result from the remote database does not
+ have the same number of columns shown in the <code class="literal">FROM</code> clause.
+ The column names need not match, however, and <code class="function">dblink</code>
+ does not insist on exact type matches either. It will succeed
+ so long as the returned data strings are valid input for the
+ column type declared in the <code class="literal">FROM</code> clause.
+ </p></div><div class="refsect1" id="id-1.11.7.21.8.8"><h2>Notes</h2><p>
+ A convenient way to use <code class="function">dblink</code> with predetermined
+ queries is to create a view.
+ This allows the column type information to be buried in the view,
+ instead of having to spell it out in every query. For example,
+
+</p><pre class="programlisting">
+CREATE VIEW myremote_pg_proc AS
+ SELECT *
+ FROM dblink('dbname=postgres options=-csearch_path=',
+ 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text);
+
+SELECT * FROM myremote_pg_proc WHERE proname LIKE 'bytea%';
+</pre></div><div class="refsect1" id="id-1.11.7.21.8.9"><h2>Examples</h2><pre class="screen">
+SELECT * FROM dblink('dbname=postgres options=-csearch_path=',
+ 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
+ proname | prosrc
+------------+------------
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteain | byteain
+ byteaout | byteaout
+(12 rows)
+
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT * FROM dblink('select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
+ proname | prosrc
+------------+------------
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteain | byteain
+ byteaout | byteaout
+(12 rows)
+
+SELECT dblink_connect('myconn', 'dbname=regression options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT * FROM dblink('myconn', 'select proname, prosrc from pg_proc')
+ AS t1(proname name, prosrc text) WHERE proname LIKE 'bytea%';
+ proname | prosrc
+------------+------------
+ bytearecv | bytearecv
+ byteasend | byteasend
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteain | byteain
+ byteaout | byteaout
+(14 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-disconnect.html" title="dblink_disconnect">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-exec.html" title="dblink_exec">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_disconnect </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_exec</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-get-connections.html b/doc/src/sgml/html/contrib-dblink-get-connections.html
new file mode 100644
index 0000000..90536bc
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-get-connections.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_get_connections</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-close.html" title="dblink_close" /><link rel="next" href="contrib-dblink-error-message.html" title="dblink_error_message" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_get_connections</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-close.html" title="dblink_close">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-error-message.html" title="dblink_error_message">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-GET-CONNECTIONS"><div class="titlepage"></div><a id="id-1.11.7.21.13.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_get_connections</span></h2><p>dblink_get_connections — returns the names of all open named dblink connections</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_get_connections() returns text[]
+</pre></div><div class="refsect1" id="id-1.11.7.21.13.5"><h2>Description</h2><p>
+ <code class="function">dblink_get_connections</code> returns an array of the names
+ of all open named <code class="filename">dblink</code> connections.
+ </p></div><div class="refsect1" id="id-1.11.7.21.13.6"><h2>Return Value</h2><p>Returns a text array of connection names, or NULL if none.</p></div><div class="refsect1" id="id-1.11.7.21.13.7"><h2>Examples</h2><pre class="programlisting">
+SELECT dblink_get_connections();
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-close.html" title="dblink_close">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-error-message.html" title="dblink_error_message">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_close </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_error_message</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-get-notify.html b/doc/src/sgml/html/contrib-dblink-get-notify.html
new file mode 100644
index 0000000..f9424bc
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-get-notify.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_get_notify</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-is-busy.html" title="dblink_is_busy" /><link rel="next" href="contrib-dblink-get-result.html" title="dblink_get_result" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_get_notify</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-is-busy.html" title="dblink_is_busy">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-get-result.html" title="dblink_get_result">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-GET-NOTIFY"><div class="titlepage"></div><a id="id-1.11.7.21.17.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_get_notify</span></h2><p>dblink_get_notify — retrieve async notifications on a connection</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_get_notify() returns setof (notify_name text, be_pid int, extra text)
+dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text)
+</pre></div><div class="refsect1" id="id-1.11.7.21.17.5"><h2>Description</h2><p>
+ <code class="function">dblink_get_notify</code> retrieves notifications on either
+ the unnamed connection, or on a named connection if specified.
+ To receive notifications via dblink, <code class="function">LISTEN</code> must
+ first be issued, using <code class="function">dblink_exec</code>.
+ For details see <a class="xref" href="sql-listen.html" title="LISTEN"><span class="refentrytitle">LISTEN</span></a> and <a class="xref" href="sql-notify.html" title="NOTIFY"><span class="refentrytitle">NOTIFY</span></a>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.17.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ The name of a named connection to get notifications on.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.17.7"><h2>Return Value</h2><p>Returns <code class="type">setof (notify_name text, be_pid int, extra text)</code>, or an empty set if none.</p></div><div class="refsect1" id="id-1.11.7.21.17.8"><h2>Examples</h2><pre class="screen">
+SELECT dblink_exec('LISTEN virtual');
+ dblink_exec
+-------------
+ LISTEN
+(1 row)
+
+SELECT * FROM dblink_get_notify();
+ notify_name | be_pid | extra
+-------------+--------+-------
+(0 rows)
+
+NOTIFY virtual;
+NOTIFY
+
+SELECT * FROM dblink_get_notify();
+ notify_name | be_pid | extra
+-------------+--------+-------
+ virtual | 1229 |
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-is-busy.html" title="dblink_is_busy">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-get-result.html" title="dblink_get_result">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_is_busy </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_get_result</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-get-pkey.html b/doc/src/sgml/html/contrib-dblink-get-pkey.html
new file mode 100644
index 0000000..910955c
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-get-pkey.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_get_pkey</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-cancel-query.html" title="dblink_cancel_query" /><link rel="next" href="contrib-dblink-build-sql-insert.html" title="dblink_build_sql_insert" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_get_pkey</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-cancel-query.html" title="dblink_cancel_query">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-build-sql-insert.html" title="dblink_build_sql_insert">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-GET-PKEY"><div class="titlepage"></div><a id="id-1.11.7.21.20.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_get_pkey</span></h2><p>dblink_get_pkey — returns the positions and field names of a relation's
+ primary key fields
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_get_pkey(text relname) returns setof dblink_pkey_results
+</pre></div><div class="refsect1" id="id-1.11.7.21.20.5"><h2>Description</h2><p>
+ <code class="function">dblink_get_pkey</code> provides information about the primary
+ key of a relation in the local database. This is sometimes useful
+ in generating queries to be sent to remote databases.
+ </p></div><div class="refsect1" id="id-1.11.7.21.20.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>relname</code></em></span></dt><dd><p>
+ Name of a local relation, for example <code class="literal">foo</code> or
+ <code class="literal">myschema.mytab</code>. Include double quotes if the
+ name is mixed-case or contains special characters, for
+ example <code class="literal">"FooBar"</code>; without quotes, the string
+ will be folded to lower case.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.20.7"><h2>Return Value</h2><p>
+ Returns one row for each primary key field, or no rows if the relation
+ has no primary key. The result row type is defined as
+
+</p><pre class="programlisting">
+CREATE TYPE dblink_pkey_results AS (position int, colname text);
+</pre><p>
+
+ The <code class="literal">position</code> column simply runs from 1 to <em class="replaceable"><code>N</code></em>;
+ it is the number of the field within the primary key, not the number
+ within the table's columns.
+ </p></div><div class="refsect1" id="id-1.11.7.21.20.8"><h2>Examples</h2><pre class="screen">
+CREATE TABLE foobar (
+ f1 int,
+ f2 int,
+ f3 int,
+ PRIMARY KEY (f1, f2, f3)
+);
+CREATE TABLE
+
+SELECT * FROM dblink_get_pkey('foobar');
+ position | colname
+----------+---------
+ 1 | f1
+ 2 | f2
+ 3 | f3
+(3 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-cancel-query.html" title="dblink_cancel_query">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-build-sql-insert.html" title="dblink_build_sql_insert">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_cancel_query </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_build_sql_insert</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-get-result.html b/doc/src/sgml/html/contrib-dblink-get-result.html
new file mode 100644
index 0000000..36a3477
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-get-result.html
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_get_result</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-get-notify.html" title="dblink_get_notify" /><link rel="next" href="contrib-dblink-cancel-query.html" title="dblink_cancel_query" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_get_result</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-get-notify.html" title="dblink_get_notify">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-cancel-query.html" title="dblink_cancel_query">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-GET-RESULT"><div class="titlepage"></div><a id="id-1.11.7.21.18.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_get_result</span></h2><p>dblink_get_result — gets an async query result</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_get_result(text connname [, bool fail_on_error]) returns setof record
+</pre></div><div class="refsect1" id="id-1.11.7.21.18.5"><h2>Description</h2><p>
+ <code class="function">dblink_get_result</code> collects the results of an
+ asynchronous query previously sent with <code class="function">dblink_send_query</code>.
+ If the query is not already completed, <code class="function">dblink_get_result</code>
+ will wait until it is.
+ </p></div><div class="refsect1" id="id-1.11.7.21.18.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use.
+ </p></dd><dt><span class="term"><em class="parameter"><code>fail_on_error</code></em></span></dt><dd><p>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function returns no rows.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.18.7"><h2>Return Value</h2><p>
+ For an async query (that is, an SQL statement returning rows),
+ the function returns the row(s) produced by the query. To use this
+ function, you will need to specify the expected set of columns,
+ as previously discussed for <code class="function">dblink</code>.
+ </p><p>
+ For an async command (that is, an SQL statement not returning rows),
+ the function returns a single row with a single text column containing
+ the command's status string. It is still necessary to specify that
+ the result will have a single text column in the calling <code class="literal">FROM</code>
+ clause.
+ </p></div><div class="refsect1" id="id-1.11.7.21.18.8"><h2>Notes</h2><p>
+ This function <span class="emphasis"><em>must</em></span> be called if
+ <code class="function">dblink_send_query</code> returned 1.
+ It must be called once for each query
+ sent, and one additional time to obtain an empty set result,
+ before the connection can be used again.
+ </p><p>
+ When using <code class="function">dblink_send_query</code> and
+ <code class="function">dblink_get_result</code>, <span class="application">dblink</span> fetches the entire
+ remote query result before returning any of it to the local query
+ processor. If the query returns a large number of rows, this can result
+ in transient memory bloat in the local session. It may be better to open
+ such a query as a cursor with <code class="function">dblink_open</code> and then fetch a
+ manageable number of rows at a time. Alternatively, use plain
+ <code class="function">dblink()</code>, which avoids memory bloat by spooling large result
+ sets to disk.
+ </p></div><div class="refsect1" id="id-1.11.7.21.18.9"><h2>Examples</h2><pre class="screen">
+contrib_regression=# SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+contrib_regression=# SELECT * FROM
+contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 &lt; 3') AS t1;
+ t1
+----
+ 1
+(1 row)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+------------
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+(3 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+----
+(0 rows)
+
+contrib_regression=# SELECT * FROM
+contrib_regression-# dblink_send_query('dtest1', 'select * from foo where f1 &lt; 3; select * from foo where f1 &gt; 6') AS t1;
+ t1
+----
+ 1
+(1 row)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+------------
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+(3 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+---------------
+ 7 | h | {a7,b7,c7}
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ 10 | k | {a10,b10,c10}
+(4 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result('dtest1') AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+----+----+----
+(0 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-get-notify.html" title="dblink_get_notify">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-cancel-query.html" title="dblink_cancel_query">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_get_notify </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_cancel_query</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-is-busy.html b/doc/src/sgml/html/contrib-dblink-is-busy.html
new file mode 100644
index 0000000..84abe77
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-is-busy.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_is_busy</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-send-query.html" title="dblink_send_query" /><link rel="next" href="contrib-dblink-get-notify.html" title="dblink_get_notify" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_is_busy</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-send-query.html" title="dblink_send_query">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-get-notify.html" title="dblink_get_notify">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-IS-BUSY"><div class="titlepage"></div><a id="id-1.11.7.21.16.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_is_busy</span></h2><p>dblink_is_busy — checks if connection is busy with an async query</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_is_busy(text connname) returns int
+</pre></div><div class="refsect1" id="id-1.11.7.21.16.5"><h2>Description</h2><p>
+ <code class="function">dblink_is_busy</code> tests whether an async query is in progress.
+ </p></div><div class="refsect1" id="id-1.11.7.21.16.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to check.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.16.7"><h2>Return Value</h2><p>
+ Returns 1 if connection is busy, 0 if it is not busy.
+ If this function returns 0, it is guaranteed that
+ <code class="function">dblink_get_result</code> will not block.
+ </p></div><div class="refsect1" id="id-1.11.7.21.16.8"><h2>Examples</h2><pre class="programlisting">
+SELECT dblink_is_busy('dtest1');
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-send-query.html" title="dblink_send_query">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-get-notify.html" title="dblink_get_notify">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_send_query </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_get_notify</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-open.html b/doc/src/sgml/html/contrib-dblink-open.html
new file mode 100644
index 0000000..070628e
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-open.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_open</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-exec.html" title="dblink_exec" /><link rel="next" href="contrib-dblink-fetch.html" title="dblink_fetch" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_open</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-exec.html" title="dblink_exec">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-fetch.html" title="dblink_fetch">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-OPEN"><div class="titlepage"></div><a id="id-1.11.7.21.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_open</span></h2><p>dblink_open — opens a cursor in a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text
+dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text
+</pre></div><div class="refsect1" id="id-1.11.7.21.10.5"><h2>Description</h2><p>
+ <code class="function">dblink_open()</code> opens a cursor in a remote database.
+ The cursor can subsequently be manipulated with
+ <code class="function">dblink_fetch()</code> and <code class="function">dblink_close()</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.10.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use; omit this parameter to use the
+ unnamed connection.
+ </p></dd><dt><span class="term"><em class="parameter"><code>cursorname</code></em></span></dt><dd><p>
+ The name to assign to this cursor.
+ </p></dd><dt><span class="term"><em class="parameter"><code>sql</code></em></span></dt><dd><p>
+ The <code class="command">SELECT</code> statement that you wish to execute in the remote
+ database, for example <code class="literal">select * from pg_class</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>fail_on_error</code></em></span></dt><dd><p>
+ If true (the default when omitted) then an error thrown on the
+ remote side of the connection causes an error to also be thrown
+ locally. If false, the remote error is locally reported as a NOTICE,
+ and the function's return value is set to <code class="literal">ERROR</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.10.7"><h2>Return Value</h2><p>
+ Returns status, either <code class="literal">OK</code> or <code class="literal">ERROR</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.10.8"><h2>Notes</h2><p>
+ Since a cursor can only persist within a transaction,
+ <code class="function">dblink_open</code> starts an explicit transaction block
+ (<code class="command">BEGIN</code>) on the remote side, if the remote side was
+ not already within a transaction. This transaction will be
+ closed again when the matching <code class="function">dblink_close</code> is
+ executed. Note that if
+ you use <code class="function">dblink_exec</code> to change data between
+ <code class="function">dblink_open</code> and <code class="function">dblink_close</code>,
+ and then an error occurs or you use <code class="function">dblink_disconnect</code> before
+ <code class="function">dblink_close</code>, your change <span class="emphasis"><em>will be
+ lost</em></span> because the transaction will be aborted.
+ </p></div><div class="refsect1" id="id-1.11.7.21.10.9"><h2>Examples</h2><pre class="screen">
+SELECT dblink_connect('dbname=postgres options=-csearch_path=');
+ dblink_connect
+----------------
+ OK
+(1 row)
+
+SELECT dblink_open('foo', 'select proname, prosrc from pg_proc');
+ dblink_open
+-------------
+ OK
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-exec.html" title="dblink_exec">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-fetch.html" title="dblink_fetch">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_exec </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_fetch</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-dblink-send-query.html b/doc/src/sgml/html/contrib-dblink-send-query.html
new file mode 100644
index 0000000..6542711
--- /dev/null
+++ b/doc/src/sgml/html/contrib-dblink-send-query.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>dblink_send_query</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-error-message.html" title="dblink_error_message" /><link rel="next" href="contrib-dblink-is-busy.html" title="dblink_is_busy" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">dblink_send_query</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-error-message.html" title="dblink_error_message">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><th width="60%" align="center">F.12. dblink</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-is-busy.html" title="dblink_is_busy">Next</a></td></tr></table><hr /></div><div class="refentry" id="CONTRIB-DBLINK-SEND-QUERY"><div class="titlepage"></div><a id="id-1.11.7.21.15.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">dblink_send_query</span></h2><p>dblink_send_query — sends an async query to a remote database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+dblink_send_query(text connname, text sql) returns int
+</pre></div><div class="refsect1" id="id-1.11.7.21.15.5"><h2>Description</h2><p>
+ <code class="function">dblink_send_query</code> sends a query to be executed
+ asynchronously, that is, without immediately waiting for the result.
+ There must not be an async query already in progress on the
+ connection.
+ </p><p>
+ After successfully dispatching an async query, completion status
+ can be checked with <code class="function">dblink_is_busy</code>, and the results
+ are ultimately collected with <code class="function">dblink_get_result</code>.
+ It is also possible to attempt to cancel an active async query
+ using <code class="function">dblink_cancel_query</code>.
+ </p></div><div class="refsect1" id="id-1.11.7.21.15.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>connname</code></em></span></dt><dd><p>
+ Name of the connection to use.
+ </p></dd><dt><span class="term"><em class="parameter"><code>sql</code></em></span></dt><dd><p>
+ The SQL statement that you wish to execute in the remote database,
+ for example <code class="literal">select * from pg_class</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.11.7.21.15.7"><h2>Return Value</h2><p>
+ Returns 1 if the query was successfully dispatched, 0 otherwise.
+ </p></div><div class="refsect1" id="id-1.11.7.21.15.8"><h2>Examples</h2><pre class="programlisting">
+SELECT dblink_send_query('dtest1', 'SELECT * FROM foo WHERE f1 &lt; 3');
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-error-message.html" title="dblink_error_message">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dblink.html" title="F.12. dblink">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-is-busy.html" title="dblink_is_busy">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_error_message </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_is_busy</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-prog-client.html b/doc/src/sgml/html/contrib-prog-client.html
new file mode 100644
index 0000000..b22c2b1
--- /dev/null
+++ b/doc/src/sgml/html/contrib-prog-client.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>G.1. Client Applications</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs" /><link rel="next" href="oid2name.html" title="oid2name" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">G.1. Client Applications</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Up</a></td><th width="60%" align="center">Appendix G. Additional Supplied Programs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="oid2name.html" title="oid2name">Next</a></td></tr></table><hr /></div><div class="sect1" id="CONTRIB-PROG-CLIENT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">G.1. Client Applications</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="oid2name.html">oid2name</a></span><span class="refpurpose"> — resolve OIDs and file nodes in a <span class="productname">PostgreSQL</span> data directory</span></dt><dt><span class="refentrytitle"><a href="vacuumlo.html"><span class="application">vacuumlo</span></a></span><span class="refpurpose"> — remove orphaned large objects from a <span class="productname">PostgreSQL</span> database</span></dt></dl></div><p>
+ This section covers <span class="productname">PostgreSQL</span> client
+ applications in <code class="literal">contrib</code>. They can be run from anywhere,
+ independent of where the database server resides. See
+ also <a class="xref" href="reference-client.html" title="PostgreSQL Client Applications">PostgreSQL Client Applications</a> for information about client
+ applications that are part of the core <span class="productname">PostgreSQL</span>
+ distribution.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="oid2name.html" title="oid2name">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix G. Additional Supplied Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> oid2name</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-prog-server.html b/doc/src/sgml/html/contrib-prog-server.html
new file mode 100644
index 0000000..b979bc8
--- /dev/null
+++ b/doc/src/sgml/html/contrib-prog-server.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>G.2. Server Applications</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="vacuumlo.html" title="vacuumlo" /><link rel="next" href="external-projects.html" title="Appendix H. External Projects" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">G.2. Server Applications</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="vacuumlo.html" title="vacuumlo">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Up</a></td><th width="60%" align="center">Appendix G. Additional Supplied Programs</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="external-projects.html" title="Appendix H. External Projects">Next</a></td></tr></table><hr /></div><div class="sect1" id="CONTRIB-PROG-SERVER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">G.2. Server Applications</h2></div></div></div><p>
+ Some applications run on the <span class="productname">PostgreSQL</span> server
+ itself. Currently, no such applications are included in the
+ <code class="literal">contrib</code> directory. See also <a class="xref" href="reference-server.html" title="PostgreSQL Server Applications">PostgreSQL Server Applications</a> for information about server applications that
+ are part of the core <span class="productname">PostgreSQL</span> distribution.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="vacuumlo.html" title="vacuumlo">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="external-projects.html" title="Appendix H. External Projects">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">vacuumlo</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix H. External Projects</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-prog.html b/doc/src/sgml/html/contrib-prog.html
new file mode 100644
index 0000000..99b1c7d
--- /dev/null
+++ b/doc/src/sgml/html/contrib-prog.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix G. Additional Supplied Programs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xml2.html" title="F.50. xml2" /><link rel="next" href="contrib-prog-client.html" title="G.1. Client Applications" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix G. Additional Supplied Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xml2.html" title="F.50. xml2">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-prog-client.html" title="G.1. Client Applications">Next</a></td></tr></table><hr /></div><div class="appendix" id="CONTRIB-PROG"><div class="titlepage"><div><div><h2 class="title">Appendix G. Additional Supplied Programs</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="contrib-prog-client.html">G.1. Client Applications</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="oid2name.html">oid2name</a></span><span class="refpurpose"> — resolve OIDs and file nodes in a <span class="productname">PostgreSQL</span> data directory</span></dt><dt><span class="refentrytitle"><a href="vacuumlo.html"><span class="application">vacuumlo</span></a></span><span class="refpurpose"> — remove orphaned large objects from a <span class="productname">PostgreSQL</span> database</span></dt></dl></dd><dt><span class="sect1"><a href="contrib-prog-server.html">G.2. Server Applications</a></span></dt></dl></div><p>
+ This appendix and the previous one contain information regarding the modules that
+ can be found in the <code class="literal">contrib</code> directory of the
+ <span class="productname">PostgreSQL</span> distribution. See <a class="xref" href="contrib.html" title="Appendix F. Additional Supplied Modules">Appendix F</a> for
+ more information about the <code class="literal">contrib</code> section in general and
+ server extensions and plug-ins found in <code class="literal">contrib</code>
+ specifically.
+ </p><p>
+ This appendix covers utility programs found in <code class="literal">contrib</code>.
+ Once installed, either from source or a packaging system, they are found in
+ the <code class="filename">bin</code> directory of the
+ <span class="productname">PostgreSQL</span> installation and can be used like any
+ other program.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xml2.html" title="F.50. xml2">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-prog-client.html" title="G.1. Client Applications">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.50. xml2 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> G.1. Client Applications</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib-spi.html b/doc/src/sgml/html/contrib-spi.html
new file mode 100644
index 0000000..67566a3
--- /dev/null
+++ b/doc/src/sgml/html/contrib-spi.html
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.41. spi</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sepgsql.html" title="F.40. sepgsql" /><link rel="next" href="sslinfo.html" title="F.42. sslinfo" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.41. spi</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sepgsql.html" title="F.40. sepgsql">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sslinfo.html" title="F.42. sslinfo">Next</a></td></tr></table><hr /></div><div class="sect1" id="CONTRIB-SPI"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.41. spi</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.5">F.41.1. refint — Functions for Implementing Referential Integrity</a></span></dt><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.6">F.41.2. autoinc — Functions for Autoincrementing Fields</a></span></dt><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.7">F.41.3. insert_username — Functions for Tracking Who Changed a Table</a></span></dt><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.8">F.41.4. moddatetime — Functions for Tracking Last Modification Time</a></span></dt></dl></div><a id="id-1.11.7.50.2" class="indexterm"></a><p>
+ The <span class="application">spi</span> module provides several workable examples
+ of using the <a class="link" href="spi.html" title="Chapter 47. Server Programming Interface">Server Programming Interface</a>
+ (<acronym class="acronym">SPI</acronym>) and triggers. While these functions are of
+ some value in
+ their own right, they are even more useful as examples to modify for
+ your own purposes. The functions are general enough to be used
+ with any table, but you have to specify table and field names (as described
+ below) while creating a trigger.
+ </p><p>
+ Each of the groups of functions described below is provided as a
+ separately-installable extension.
+ </p><div class="sect2" id="id-1.11.7.50.5"><div class="titlepage"><div><div><h3 class="title">F.41.1. refint — Functions for Implementing Referential Integrity</h3></div></div></div><p>
+ <code class="function">check_primary_key()</code> and
+ <code class="function">check_foreign_key()</code> are used to check foreign key constraints.
+ (This functionality is long since superseded by the built-in foreign
+ key mechanism, of course, but the module is still useful as an example.)
+ </p><p>
+ <code class="function">check_primary_key()</code> checks the referencing table.
+ To use, create a <code class="literal">BEFORE INSERT OR UPDATE</code> trigger using this
+ function on a table referencing another table. Specify as the trigger
+ arguments: the referencing table's column name(s) which form the foreign
+ key, the referenced table name, and the column names in the referenced table
+ which form the primary/unique key. To handle multiple foreign
+ keys, create a trigger for each reference.
+ </p><p>
+ <code class="function">check_foreign_key()</code> checks the referenced table.
+ To use, create a <code class="literal">BEFORE DELETE OR UPDATE</code> trigger using this
+ function on a table referenced by other table(s). Specify as the trigger
+ arguments: the number of referencing tables for which the function has to
+ perform checking, the action if a referencing key is found
+ (<code class="literal">cascade</code> — to delete the referencing row,
+ <code class="literal">restrict</code> — to abort transaction if referencing keys
+ exist, <code class="literal">setnull</code> — to set referencing key fields to null),
+ the triggered table's column names which form the primary/unique key, then
+ the referencing table name and column names (repeated for as many
+ referencing tables as were specified by first argument). Note that the
+ primary/unique key columns should be marked NOT NULL and should have a
+ unique index.
+ </p><p>
+ There are examples in <code class="filename">refint.example</code>.
+ </p></div><div class="sect2" id="id-1.11.7.50.6"><div class="titlepage"><div><div><h3 class="title">F.41.2. autoinc — Functions for Autoincrementing Fields</h3></div></div></div><p>
+ <code class="function">autoinc()</code> is a trigger that stores the next value of
+ a sequence into an integer field. This has some overlap with the
+ built-in <span class="quote">“<span class="quote">serial column</span>”</span> feature, but it is not the same:
+ <code class="function">autoinc()</code> will override attempts to substitute a
+ different field value during inserts, and optionally it can be
+ used to increment the field during updates, too.
+ </p><p>
+ To use, create a <code class="literal">BEFORE INSERT</code> (or optionally <code class="literal">BEFORE
+ INSERT OR UPDATE</code>) trigger using this function. Specify two
+ trigger arguments: the name of the integer column to be modified,
+ and the name of the sequence object that will supply values.
+ (Actually, you can specify any number of pairs of such names, if
+ you'd like to update more than one autoincrementing column.)
+ </p><p>
+ There is an example in <code class="filename">autoinc.example</code>.
+ </p></div><div class="sect2" id="id-1.11.7.50.7"><div class="titlepage"><div><div><h3 class="title">F.41.3. insert_username — Functions for Tracking Who Changed a Table</h3></div></div></div><p>
+ <code class="function">insert_username()</code> is a trigger that stores the current
+ user's name into a text field. This can be useful for tracking
+ who last modified a particular row within a table.
+ </p><p>
+ To use, create a <code class="literal">BEFORE INSERT</code> and/or <code class="literal">UPDATE</code>
+ trigger using this function. Specify a single trigger
+ argument: the name of the text column to be modified.
+ </p><p>
+ There is an example in <code class="filename">insert_username.example</code>.
+ </p></div><div class="sect2" id="id-1.11.7.50.8"><div class="titlepage"><div><div><h3 class="title">F.41.4. moddatetime — Functions for Tracking Last Modification Time</h3></div></div></div><p>
+ <code class="function">moddatetime()</code> is a trigger that stores the current
+ time into a <code class="type">timestamp</code> field. This can be useful for tracking
+ the last modification time of a particular row within a table.
+ </p><p>
+ To use, create a <code class="literal">BEFORE UPDATE</code>
+ trigger using this function. Specify a single trigger
+ argument: the name of the column to be modified.
+ The column must be of type <code class="type">timestamp</code> or <code class="type">timestamp with
+ time zone</code>.
+ </p><p>
+ There is an example in <code class="filename">moddatetime.example</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sepgsql.html" title="F.40. sepgsql">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sslinfo.html" title="F.42. sslinfo">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.40. sepgsql </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.42. sslinfo</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/contrib.html b/doc/src/sgml/html/contrib.html
new file mode 100644
index 0000000..b215107
--- /dev/null
+++ b/doc/src/sgml/html/contrib.html
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix F. Additional Supplied Modules</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release-prior.html" title="E.6. Prior Releases" /><link rel="next" href="adminpack.html" title="F.1. adminpack" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix F. Additional Supplied Modules</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release-prior.html" title="E.6. Prior Releases">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="adminpack.html" title="F.1. adminpack">Next</a></td></tr></table><hr /></div><div class="appendix" id="CONTRIB"><div class="titlepage"><div><div><h2 class="title">Appendix F. Additional Supplied Modules</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="adminpack.html">F.1. adminpack</a></span></dt><dt><span class="sect1"><a href="amcheck.html">F.2. amcheck</a></span></dt><dd><dl><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.8">F.2.1. Functions</a></span></dt><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.9">F.2.2. Optional <em class="parameter"><code>heapallindexed</code></em> Verification</a></span></dt><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.10">F.2.3. Using <code class="filename">amcheck</code> Effectively</a></span></dt><dt><span class="sect2"><a href="amcheck.html#id-1.11.7.11.11">F.2.4. Repairing Corruption</a></span></dt></dl></dd><dt><span class="sect1"><a href="auth-delay.html">F.3. auth_delay</a></span></dt><dd><dl><dt><span class="sect2"><a href="auth-delay.html#id-1.11.7.12.5">F.3.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="auth-delay.html#id-1.11.7.12.6">F.3.2. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="auto-explain.html">F.4. auto_explain</a></span></dt><dd><dl><dt><span class="sect2"><a href="auto-explain.html#id-1.11.7.13.5">F.4.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="auto-explain.html#id-1.11.7.13.6">F.4.2. Example</a></span></dt><dt><span class="sect2"><a href="auto-explain.html#id-1.11.7.13.7">F.4.3. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="basebackup-to-shell.html">F.5. basebackup_to_shell</a></span></dt><dd><dl><dt><span class="sect2"><a href="basebackup-to-shell.html#id-1.11.7.14.5">F.5.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="basebackup-to-shell.html#id-1.11.7.14.6">F.5.2. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="basic-archive.html">F.6. basic_archive</a></span></dt><dd><dl><dt><span class="sect2"><a href="basic-archive.html#id-1.11.7.15.5">F.6.1. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="basic-archive.html#id-1.11.7.15.6">F.6.2. Notes</a></span></dt><dt><span class="sect2"><a href="basic-archive.html#id-1.11.7.15.7">F.6.3. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="bloom.html">F.7. bloom</a></span></dt><dd><dl><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.7">F.7.1. Parameters</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.8">F.7.2. Examples</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.9">F.7.3. Operator Class Interface</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.10">F.7.4. Limitations</a></span></dt><dt><span class="sect2"><a href="bloom.html#id-1.11.7.16.11">F.7.5. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="btree-gin.html">F.8. btree_gin</a></span></dt><dd><dl><dt><span class="sect2"><a href="btree-gin.html#id-1.11.7.17.6">F.8.1. Example Usage</a></span></dt><dt><span class="sect2"><a href="btree-gin.html#id-1.11.7.17.7">F.8.2. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="btree-gist.html">F.9. btree_gist</a></span></dt><dd><dl><dt><span class="sect2"><a href="btree-gist.html#id-1.11.7.18.8">F.9.1. Example Usage</a></span></dt><dt><span class="sect2"><a href="btree-gist.html#id-1.11.7.18.9">F.9.2. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="citext.html">F.10. citext</a></span></dt><dd><dl><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.6">F.10.1. Rationale</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.7">F.10.2. How to Use It</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.8">F.10.3. String Comparison Behavior</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.9">F.10.4. Limitations</a></span></dt><dt><span class="sect2"><a href="citext.html#id-1.11.7.19.10">F.10.5. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="cube.html">F.11. cube</a></span></dt><dd><dl><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.5">F.11.1. Syntax</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.6">F.11.2. Precision</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.7">F.11.3. Usage</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.8">F.11.4. Defaults</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.9">F.11.5. Notes</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.10">F.11.6. Credits</a></span></dt></dl></dd><dt><span class="sect1"><a href="dblink.html">F.12. dblink</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="contrib-dblink-connect.html">dblink_connect</a></span><span class="refpurpose"> — opens a persistent connection to a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-connect-u.html">dblink_connect_u</a></span><span class="refpurpose"> — opens a persistent connection to a remote database, insecurely</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-disconnect.html">dblink_disconnect</a></span><span class="refpurpose"> — closes a persistent connection to a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-function.html">dblink</a></span><span class="refpurpose"> — executes a query in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-exec.html">dblink_exec</a></span><span class="refpurpose"> — executes a command in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-open.html">dblink_open</a></span><span class="refpurpose"> — opens a cursor in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-fetch.html">dblink_fetch</a></span><span class="refpurpose"> — returns rows from an open cursor in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-close.html">dblink_close</a></span><span class="refpurpose"> — closes a cursor in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-connections.html">dblink_get_connections</a></span><span class="refpurpose"> — returns the names of all open named dblink connections</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-error-message.html">dblink_error_message</a></span><span class="refpurpose"> — gets last error message on the named connection</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-send-query.html">dblink_send_query</a></span><span class="refpurpose"> — sends an async query to a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-is-busy.html">dblink_is_busy</a></span><span class="refpurpose"> — checks if connection is busy with an async query</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-notify.html">dblink_get_notify</a></span><span class="refpurpose"> — retrieve async notifications on a connection</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-result.html">dblink_get_result</a></span><span class="refpurpose"> — gets an async query result</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-cancel-query.html">dblink_cancel_query</a></span><span class="refpurpose"> — cancels any active query on the named connection</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-pkey.html">dblink_get_pkey</a></span><span class="refpurpose"> — returns the positions and field names of a relation's
+ primary key fields
+ </span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-build-sql-insert.html">dblink_build_sql_insert</a></span><span class="refpurpose"> —
+ builds an INSERT statement using a local tuple, replacing the
+ primary key field values with alternative supplied values
+ </span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-build-sql-delete.html">dblink_build_sql_delete</a></span><span class="refpurpose"> — builds a DELETE statement using supplied values for primary
+ key field values
+ </span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-build-sql-update.html">dblink_build_sql_update</a></span><span class="refpurpose"> — builds an UPDATE statement using a local tuple, replacing
+ the primary key field values with alternative supplied values
+ </span></dt></dl></dd><dt><span class="sect1"><a href="dict-int.html">F.13. dict_int</a></span></dt><dd><dl><dt><span class="sect2"><a href="dict-int.html#id-1.11.7.22.5">F.13.1. Configuration</a></span></dt><dt><span class="sect2"><a href="dict-int.html#id-1.11.7.22.6">F.13.2. Usage</a></span></dt></dl></dd><dt><span class="sect1"><a href="dict-xsyn.html">F.14. dict_xsyn</a></span></dt><dd><dl><dt><span class="sect2"><a href="dict-xsyn.html#id-1.11.7.23.4">F.14.1. Configuration</a></span></dt><dt><span class="sect2"><a href="dict-xsyn.html#id-1.11.7.23.5">F.14.2. Usage</a></span></dt></dl></dd><dt><span class="sect1"><a href="earthdistance.html">F.15. earthdistance</a></span></dt><dd><dl><dt><span class="sect2"><a href="earthdistance.html#id-1.11.7.24.7">F.15.1. Cube-Based Earth Distances</a></span></dt><dt><span class="sect2"><a href="earthdistance.html#id-1.11.7.24.8">F.15.2. Point-Based Earth Distances</a></span></dt></dl></dd><dt><span class="sect1"><a href="file-fdw.html">F.16. file_fdw</a></span></dt><dt><span class="sect1"><a href="fuzzystrmatch.html">F.17. fuzzystrmatch</a></span></dt><dd><dl><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.6">F.17.1. Soundex</a></span></dt><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.7">F.17.2. Levenshtein</a></span></dt><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.8">F.17.3. Metaphone</a></span></dt><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.9">F.17.4. Double Metaphone</a></span></dt></dl></dd><dt><span class="sect1"><a href="hstore.html">F.18. hstore</a></span></dt><dd><dl><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.5">F.18.1. <code class="type">hstore</code> External Representation</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.6">F.18.2. <code class="type">hstore</code> Operators and Functions</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.7">F.18.3. Indexes</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.8">F.18.4. Examples</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.9">F.18.5. Statistics</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.10">F.18.6. Compatibility</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.11">F.18.7. Transforms</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.12">F.18.8. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="intagg.html">F.19. intagg</a></span></dt><dd><dl><dt><span class="sect2"><a href="intagg.html#id-1.11.7.28.4">F.19.1. Functions</a></span></dt><dt><span class="sect2"><a href="intagg.html#id-1.11.7.28.5">F.19.2. Sample Uses</a></span></dt></dl></dd><dt><span class="sect1"><a href="intarray.html">F.20. intarray</a></span></dt><dd><dl><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.7">F.20.1. <code class="filename">intarray</code> Functions and Operators</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.8">F.20.2. Index Support</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.9">F.20.3. Example</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.10">F.20.4. Benchmark</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.11">F.20.5. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="isn.html">F.21. isn</a></span></dt><dd><dl><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.5">F.21.1. Data Types</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.6">F.21.2. Casts</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.7">F.21.3. Functions and Operators</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.8">F.21.4. Examples</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.9">F.21.5. Bibliography</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.10">F.21.6. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="lo.html">F.22. lo</a></span></dt><dd><dl><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.5">F.22.1. Rationale</a></span></dt><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.6">F.22.2. How to Use It</a></span></dt><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.7">F.22.3. Limitations</a></span></dt><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.8">F.22.4. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="ltree.html">F.23. ltree</a></span></dt><dd><dl><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.5">F.23.1. Definitions</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.6">F.23.2. Operators and Functions</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.7">F.23.3. Indexes</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.8">F.23.4. Example</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.9">F.23.5. Transforms</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.10">F.23.6. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="oldsnapshot.html">F.24. old_snapshot</a></span></dt><dd><dl><dt><span class="sect2"><a href="oldsnapshot.html#id-1.11.7.33.4">F.24.1. Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="pageinspect.html">F.25. pageinspect</a></span></dt><dd><dl><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.4">F.25.1. General Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.5">F.25.2. Heap Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.6">F.25.3. B-Tree Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.7">F.25.4. BRIN Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.8">F.25.5. GIN Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.9">F.25.6. GiST Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.10">F.25.7. Hash Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="passwordcheck.html">F.26. passwordcheck</a></span></dt><dt><span class="sect1"><a href="pgbuffercache.html">F.27. pg_buffercache</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgbuffercache.html#id-1.11.7.36.7">F.27.1. The <code class="structname">pg_buffercache</code> View</a></span></dt><dt><span class="sect2"><a href="pgbuffercache.html#id-1.11.7.36.8">F.27.2. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgbuffercache.html#id-1.11.7.36.9">F.27.3. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgcrypto.html">F.28. pgcrypto</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.7">F.28.1. General Hashing Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.8">F.28.2. Password Hashing Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.9">F.28.3. PGP Encryption Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.10">F.28.4. Raw Encryption Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.11">F.28.5. Random-Data Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.12">F.28.6. Notes</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.13">F.28.7. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgfreespacemap.html">F.29. pg_freespacemap</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgfreespacemap.html#id-1.11.7.38.5">F.29.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgfreespacemap.html#id-1.11.7.38.6">F.29.2. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgfreespacemap.html#id-1.11.7.38.7">F.29.3. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgprewarm.html">F.30. pg_prewarm</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgprewarm.html#id-1.11.7.39.4">F.30.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgprewarm.html#id-1.11.7.39.5">F.30.2. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="pgprewarm.html#id-1.11.7.39.6">F.30.3. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgrowlocks.html">F.31. pgrowlocks</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgrowlocks.html#id-1.11.7.40.5">F.31.1. Overview</a></span></dt><dt><span class="sect2"><a href="pgrowlocks.html#id-1.11.7.40.6">F.31.2. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgrowlocks.html#id-1.11.7.40.7">F.31.3. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgstatstatements.html">F.32. pg_stat_statements</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.6">F.32.1. The <code class="structname">pg_stat_statements</code> View</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.7">F.32.2. The <code class="structname">pg_stat_statements_info</code> View</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.8">F.32.3. Functions</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.9">F.32.4. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.10">F.32.5. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.11">F.32.6. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgstattuple.html">F.33. pgstattuple</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgstattuple.html#id-1.11.7.42.5">F.33.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgstattuple.html#id-1.11.7.42.6">F.33.2. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgsurgery.html">F.34. pg_surgery</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgsurgery.html#id-1.11.7.43.4">F.34.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgsurgery.html#id-1.11.7.43.5">F.34.2. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgtrgm.html">F.35. pg_trgm</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.5">F.35.1. Trigram (or Trigraph) Concepts</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.6">F.35.2. Functions and Operators</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.7">F.35.3. GUC Parameters</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.8">F.35.4. Index Support</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.9">F.35.5. Text Search Integration</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.10">F.35.6. References</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.11">F.35.7. Authors</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgvisibility.html">F.36. pg_visibility</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgvisibility.html#id-1.11.7.45.6">F.36.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgvisibility.html#id-1.11.7.45.7">F.36.2. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="pgwalinspect.html">F.37. pg_walinspect</a></span></dt><dd><dl><dt><span class="sect2"><a href="pgwalinspect.html#id-1.11.7.46.8">F.37.1. General Functions</a></span></dt><dt><span class="sect2"><a href="pgwalinspect.html#id-1.11.7.46.9">F.37.2. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="postgres-fdw.html">F.38. postgres_fdw</a></span></dt><dd><dl><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.11">F.38.1. FDW Options of postgres_fdw</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.12">F.38.2. Functions</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.13">F.38.3. Connection Management</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.14">F.38.4. Transaction Management</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.15">F.38.5. Remote Query Optimization</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.16">F.38.6. Remote Query Execution Environment</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.17">F.38.7. Cross-Version Compatibility</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.18">F.38.8. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.19">F.38.9. Examples</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.20">F.38.10. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="seg.html">F.39. seg</a></span></dt><dd><dl><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.5">F.39.1. Rationale</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.6">F.39.2. Syntax</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.7">F.39.3. Precision</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.8">F.39.4. Usage</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.9">F.39.5. Notes</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.10">F.39.6. Credits</a></span></dt></dl></dd><dt><span class="sect1"><a href="sepgsql.html">F.40. sepgsql</a></span></dt><dd><dl><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-OVERVIEW">F.40.1. Overview</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-INSTALLATION">F.40.2. Installation</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-REGRESSION">F.40.3. Regression Tests</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-PARAMETERS">F.40.4. GUC Parameters</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-FEATURES">F.40.5. Features</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-FUNCTIONS">F.40.6. Sepgsql Functions</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-LIMITATIONS">F.40.7. Limitations</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-RESOURCES">F.40.8. External Resources</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-AUTHOR">F.40.9. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="contrib-spi.html">F.41. spi</a></span></dt><dd><dl><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.5">F.41.1. refint — Functions for Implementing Referential Integrity</a></span></dt><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.6">F.41.2. autoinc — Functions for Autoincrementing Fields</a></span></dt><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.7">F.41.3. insert_username — Functions for Tracking Who Changed a Table</a></span></dt><dt><span class="sect2"><a href="contrib-spi.html#id-1.11.7.50.8">F.41.4. moddatetime — Functions for Tracking Last Modification Time</a></span></dt></dl></dd><dt><span class="sect1"><a href="sslinfo.html">F.42. sslinfo</a></span></dt><dd><dl><dt><span class="sect2"><a href="sslinfo.html#id-1.11.7.51.6">F.42.1. Functions Provided</a></span></dt><dt><span class="sect2"><a href="sslinfo.html#id-1.11.7.51.7">F.42.2. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="tablefunc.html">F.43. tablefunc</a></span></dt><dd><dl><dt><span class="sect2"><a href="tablefunc.html#id-1.11.7.52.5">F.43.1. Functions Provided</a></span></dt><dt><span class="sect2"><a href="tablefunc.html#id-1.11.7.52.6">F.43.2. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="tcn.html">F.44. tcn</a></span></dt><dt><span class="sect1"><a href="test-decoding.html">F.45. test_decoding</a></span></dt><dt><span class="sect1"><a href="tsm-system-rows.html">F.46. tsm_system_rows</a></span></dt><dd><dl><dt><span class="sect2"><a href="tsm-system-rows.html#id-1.11.7.55.8">F.46.1. Examples</a></span></dt></dl></dd><dt><span class="sect1"><a href="tsm-system-time.html">F.47. tsm_system_time</a></span></dt><dd><dl><dt><span class="sect2"><a href="tsm-system-time.html#id-1.11.7.56.8">F.47.1. Examples</a></span></dt></dl></dd><dt><span class="sect1"><a href="unaccent.html">F.48. unaccent</a></span></dt><dd><dl><dt><span class="sect2"><a href="unaccent.html#id-1.11.7.57.6">F.48.1. Configuration</a></span></dt><dt><span class="sect2"><a href="unaccent.html#id-1.11.7.57.7">F.48.2. Usage</a></span></dt><dt><span class="sect2"><a href="unaccent.html#id-1.11.7.57.8">F.48.3. Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="uuid-ossp.html">F.49. uuid-ossp</a></span></dt><dd><dl><dt><span class="sect2"><a href="uuid-ossp.html#id-1.11.7.58.5">F.49.1. <code class="literal">uuid-ossp</code> Functions</a></span></dt><dt><span class="sect2"><a href="uuid-ossp.html#id-1.11.7.58.6">F.49.2. Building <code class="filename">uuid-ossp</code></a></span></dt><dt><span class="sect2"><a href="uuid-ossp.html#id-1.11.7.58.7">F.49.3. Author</a></span></dt></dl></dd><dt><span class="sect1"><a href="xml2.html">F.50. xml2</a></span></dt><dd><dl><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.4">F.50.1. Deprecation Notice</a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.5">F.50.2. Description of Functions</a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.6">F.50.3. <code class="literal">xpath_table</code></a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.7">F.50.4. XSLT Functions</a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.8">F.50.5. Author</a></span></dt></dl></dd></dl></div><p>
+ This appendix and the next one contain information regarding the modules that
+ can be found in the <code class="literal">contrib</code> directory of the
+ <span class="productname">PostgreSQL</span> distribution.
+ These include porting tools, analysis utilities,
+ and plug-in features that are not part of the core PostgreSQL system,
+ mainly because they address a limited audience or are too experimental
+ to be part of the main source tree. This does not preclude their
+ usefulness.
+ </p><p>
+ This appendix covers extensions and other server plug-in modules found in
+ <code class="literal">contrib</code>. <a class="xref" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Appendix G</a> covers utility
+ programs.
+ </p><p>
+ When building from the source distribution, these components are not built
+ automatically, unless you build the "world" target
+ (see <a class="xref" href="install-procedure.html#BUILD" title="Build">Step 2</a>).
+ You can build and install all of them by running:
+</p><pre class="screen">
+<strong class="userinput"><code>make</code></strong>
+<strong class="userinput"><code>make install</code></strong>
+</pre><p>
+ in the <code class="literal">contrib</code> directory of a configured source tree;
+ or to build and install
+ just one selected module, do the same in that module's subdirectory.
+ Many of the modules have regression tests, which can be executed by
+ running:
+</p><pre class="screen">
+<strong class="userinput"><code>make check</code></strong>
+</pre><p>
+ before installation or
+</p><pre class="screen">
+<strong class="userinput"><code>make installcheck</code></strong>
+</pre><p>
+ once you have a <span class="productname">PostgreSQL</span> server running.
+ </p><p>
+ If you are using a pre-packaged version of <span class="productname">PostgreSQL</span>,
+ these modules are typically made available as a separate subpackage,
+ such as <code class="literal">postgresql-contrib</code>.
+ </p><p>
+ Many modules supply new user-defined functions, operators, or types.
+ To make use of one of these modules, after you have installed the code
+ you need to register the new SQL objects in the database system.
+ This is done by executing
+ a <a class="xref" href="sql-createextension.html" title="CREATE EXTENSION"><span class="refentrytitle">CREATE EXTENSION</span></a> command. In a fresh database,
+ you can simply do
+
+</p><pre class="programlisting">
+CREATE EXTENSION <em class="replaceable"><code>module_name</code></em>;
+</pre><p>
+
+ This command registers the new SQL objects in the current database only,
+ so you need to run it in each database that you want
+ the module's facilities to be available in. Alternatively, run it in
+ database <code class="literal">template1</code> so that the extension will be copied into
+ subsequently-created databases by default.
+ </p><p>
+ For all these modules, <code class="command">CREATE EXTENSION</code> must be run
+ by a database superuser, unless the module is
+ considered <span class="quote">“<span class="quote">trusted</span>”</span>, in which case it can be run by any
+ user who has <code class="literal">CREATE</code> privilege on the current
+ database. Modules that are trusted are identified as such in the
+ sections that follow. Generally, trusted modules are ones that cannot
+ provide access to outside-the-database functionality.
+ </p><p>
+ Many modules allow you to install their objects in a schema of your
+ choice. To do that, add <code class="literal">SCHEMA
+ <em class="replaceable"><code>schema_name</code></em></code> to the <code class="command">CREATE EXTENSION</code>
+ command. By default, the objects will be placed in your current creation
+ target schema, which in turn defaults to <code class="literal">public</code>.
+ </p><p>
+ Note, however, that some of these modules are not <span class="quote">“<span class="quote">extensions</span>”</span>
+ in this sense, but are loaded into the server in some other way, for instance
+ by way of
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a>. See the documentation of each
+ module for details.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release-prior.html" title="E.6. Prior Releases">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="adminpack.html" title="F.1. adminpack">Next</a></td></tr><tr><td width="40%" align="left" valign="top">E.6. Prior Releases </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.1. adminpack</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/creating-cluster.html b/doc/src/sgml/html/creating-cluster.html
new file mode 100644
index 0000000..dd4aeea
--- /dev/null
+++ b/doc/src/sgml/html/creating-cluster.html
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.2. Creating a Database Cluster</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="postgres-user.html" title="19.1. The PostgreSQL User Account" /><link rel="next" href="server-start.html" title="19.3. Starting the Database Server" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.2. Creating a Database Cluster</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="postgres-user.html" title="19.1. The PostgreSQL User Account">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="server-start.html" title="19.3. Starting the Database Server">Next</a></td></tr></table><hr /></div><div class="sect1" id="CREATING-CLUSTER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.2. Creating a Database Cluster</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="creating-cluster.html#CREATING-CLUSTER-MOUNT-POINTS">19.2.1. Use of Secondary File Systems</a></span></dt><dt><span class="sect2"><a href="creating-cluster.html#CREATING-CLUSTER-FILESYSTEM">19.2.2. File Systems</a></span></dt></dl></div><a id="id-1.6.6.5.2" class="indexterm"></a><a id="id-1.6.6.5.3" class="indexterm"></a><p>
+ Before you can do anything, you must initialize a database storage
+ area on disk. We call this a <em class="firstterm">database cluster</em>.
+ (The <acronym class="acronym">SQL</acronym> standard uses the term catalog cluster.) A
+ database cluster is a collection of databases that is managed by a
+ single instance of a running database server. After initialization, a
+ database cluster will contain a database named <code class="literal">postgres</code>,
+ which is meant as a default database for use by utilities, users and third
+ party applications. The database server itself does not require the
+ <code class="literal">postgres</code> database to exist, but many external utility
+ programs assume it exists. There are two more databases created within
+ each cluster during initialization, named <code class="literal">template1</code>
+ and <code class="literal">template0</code>. As the names suggest, these will be
+ used as templates for subsequently-created databases; they should not be
+ used for actual work. (See <a class="xref" href="managing-databases.html" title="Chapter 23. Managing Databases">Chapter 23</a> for
+ information about creating new databases within a cluster.)
+ </p><p>
+ In file system terms, a database cluster is a single directory
+ under which all data will be stored. We call this the <em class="firstterm">data
+ directory</em> or <em class="firstterm">data area</em>. It is
+ completely up to you where you choose to store your data. There is no
+ default, although locations such as
+ <code class="filename">/usr/local/pgsql/data</code> or
+ <code class="filename">/var/lib/pgsql/data</code> are popular.
+ The data directory must be initialized before being used, using the program
+ <a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a><a id="id-1.6.6.5.5.6" class="indexterm"></a>
+ which is installed with <span class="productname">PostgreSQL</span>.
+ </p><p>
+ If you are using a pre-packaged version
+ of <span class="productname">PostgreSQL</span>, it may well have a specific
+ convention for where to place the data directory, and it may also
+ provide a script for creating the data directory. In that case you
+ should use that script in preference to
+ running <code class="command">initdb</code> directly.
+ Consult the package-level documentation for details.
+ </p><p>
+ To initialize a database cluster manually,
+ run <code class="command">initdb</code> and specify the desired
+ file system location of the database cluster with the
+ <code class="option">-D</code> option, for example:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>initdb -D /usr/local/pgsql/data</code></strong>
+</pre><p>
+ Note that you must execute this command while logged into the
+ <span class="productname">PostgreSQL</span> user account, which is
+ described in the previous section.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ As an alternative to the <code class="option">-D</code> option, you can set
+ the environment variable <code class="envar">PGDATA</code>.
+ <a id="id-1.6.6.5.8.1.3" class="indexterm"></a>
+ </p></div><p>
+ Alternatively, you can run <code class="command">initdb</code> via
+ the <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a>
+ program<a id="id-1.6.6.5.9.3" class="indexterm"></a> like so:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>pg_ctl -D /usr/local/pgsql/data initdb</code></strong>
+</pre><p>
+ This may be more intuitive if you are
+ using <code class="command">pg_ctl</code> for starting and stopping the
+ server (see <a class="xref" href="server-start.html" title="19.3. Starting the Database Server">Section 19.3</a>), so
+ that <code class="command">pg_ctl</code> would be the sole command you use
+ for managing the database server instance.
+ </p><p>
+ <code class="command">initdb</code> will attempt to create the directory you
+ specify if it does not already exist. Of course, this will fail if
+ <code class="command">initdb</code> does not have permissions to write in the
+ parent directory. It's generally recommendable that the
+ <span class="productname">PostgreSQL</span> user own not just the data
+ directory but its parent directory as well, so that this should not
+ be a problem. If the desired parent directory doesn't exist either,
+ you will need to create it first, using root privileges if the
+ grandparent directory isn't writable. So the process might look
+ like this:
+</p><pre class="screen">
+root# <strong class="userinput"><code>mkdir /usr/local/pgsql</code></strong>
+root# <strong class="userinput"><code>chown postgres /usr/local/pgsql</code></strong>
+root# <strong class="userinput"><code>su postgres</code></strong>
+postgres$ <strong class="userinput"><code>initdb -D /usr/local/pgsql/data</code></strong>
+</pre><p>
+ </p><p>
+ <code class="command">initdb</code> will refuse to run if the data directory
+ exists and already contains files; this is to prevent accidentally
+ overwriting an existing installation.
+ </p><p>
+ Because the data directory contains all the data stored in the
+ database, it is essential that it be secured from unauthorized
+ access. <code class="command">initdb</code> therefore revokes access
+ permissions from everyone but the
+ <span class="productname">PostgreSQL</span> user, and optionally, group.
+ Group access, when enabled, is read-only. This allows an unprivileged
+ user in the same group as the cluster owner to take a backup of the
+ cluster data or perform other operations that only require read access.
+ </p><p>
+ Note that enabling or disabling group access on an existing cluster requires
+ the cluster to be shut down and the appropriate mode to be set on all
+ directories and files before restarting
+ <span class="productname">PostgreSQL</span>. Otherwise, a mix of modes might
+ exist in the data directory. For clusters that allow access only by the
+ owner, the appropriate modes are <code class="literal">0700</code> for directories
+ and <code class="literal">0600</code> for files. For clusters that also allow
+ reads by the group, the appropriate modes are <code class="literal">0750</code>
+ for directories and <code class="literal">0640</code> for files.
+ </p><p>
+ However, while the directory contents are secure, the default
+ client authentication setup allows any local user to connect to the
+ database and even become the database superuser. If you do not
+ trust other local users, we recommend you use one of
+ <code class="command">initdb</code>'s <code class="option">-W</code>, <code class="option">--pwprompt</code>
+ or <code class="option">--pwfile</code> options to assign a password to the
+ database superuser.<a id="id-1.6.6.5.14.5" class="indexterm"></a>
+ Also, specify <code class="option">-A scram-sha-256</code>
+ so that the default <code class="literal">trust</code> authentication
+ mode is not used; or modify the generated <code class="filename">pg_hba.conf</code>
+ file after running <code class="command">initdb</code>, but
+ <span class="emphasis"><em>before</em></span> you start the server for the first time. (Other
+ reasonable approaches include using <code class="literal">peer</code> authentication
+ or file system permissions to restrict connections. See <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a> for more information.)
+ </p><p>
+ <code class="command">initdb</code> also initializes the default
+ locale<a id="id-1.6.6.5.15.2" class="indexterm"></a> for the database cluster.
+ Normally, it will just take the locale settings in the environment
+ and apply them to the initialized database. It is possible to
+ specify a different locale for the database; more information about
+ that can be found in <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a>. The default sort order used
+ within the particular database cluster is set by
+ <code class="command">initdb</code>, and while you can create new databases using
+ different sort order, the order used in the template databases that initdb
+ creates cannot be changed without dropping and recreating them.
+ There is also a performance impact for using locales
+ other than <code class="literal">C</code> or <code class="literal">POSIX</code>. Therefore, it is
+ important to make this choice correctly the first time.
+ </p><p>
+ <code class="command">initdb</code> also sets the default character set encoding
+ for the database cluster. Normally this should be chosen to match the
+ locale setting. For details see <a class="xref" href="multibyte.html" title="24.3. Character Set Support">Section 24.3</a>.
+ </p><p>
+ Non-<code class="literal">C</code> and non-<code class="literal">POSIX</code> locales rely on the
+ operating system's collation library for character set ordering.
+ This controls the ordering of keys stored in indexes. For this reason,
+ a cluster cannot switch to an incompatible collation library version,
+ either through snapshot restore, binary streaming replication, a
+ different operating system, or an operating system upgrade.
+ </p><div class="sect2" id="CREATING-CLUSTER-MOUNT-POINTS"><div class="titlepage"><div><div><h3 class="title">19.2.1. Use of Secondary File Systems</h3></div></div></div><a id="id-1.6.6.5.18.2" class="indexterm"></a><p>
+ Many installations create their database clusters on file systems
+ (volumes) other than the machine's <span class="quote">“<span class="quote">root</span>”</span> volume. If you
+ choose to do this, it is not advisable to try to use the secondary
+ volume's topmost directory (mount point) as the data directory.
+ Best practice is to create a directory within the mount-point
+ directory that is owned by the <span class="productname">PostgreSQL</span>
+ user, and then create the data directory within that. This avoids
+ permissions problems, particularly for operations such
+ as <span class="application">pg_upgrade</span>, and it also ensures clean failures if
+ the secondary volume is taken offline.
+ </p></div><div class="sect2" id="CREATING-CLUSTER-FILESYSTEM"><div class="titlepage"><div><div><h3 class="title">19.2.2. File Systems</h3></div></div></div><p>
+ Generally, any file system with POSIX semantics can be used for
+ PostgreSQL. Users prefer different file systems for a variety of reasons,
+ including vendor support, performance, and familiarity. Experience
+ suggests that, all other things being equal, one should not expect major
+ performance or behavior changes merely from switching file systems or
+ making minor file system configuration changes.
+ </p><div class="sect3" id="CREATING-CLUSTER-NFS"><div class="titlepage"><div><div><h4 class="title">19.2.2.1. NFS</h4></div></div></div><a id="id-1.6.6.5.19.3.2" class="indexterm"></a><p>
+ It is possible to use an <acronym class="acronym">NFS</acronym> file system for storing
+ the <span class="productname">PostgreSQL</span> data directory.
+ <span class="productname">PostgreSQL</span> does nothing special for
+ <acronym class="acronym">NFS</acronym> file systems, meaning it assumes
+ <acronym class="acronym">NFS</acronym> behaves exactly like locally-connected drives.
+ <span class="productname">PostgreSQL</span> does not use any functionality that
+ is known to have nonstandard behavior on <acronym class="acronym">NFS</acronym>, such as
+ file locking.
+ </p><p>
+ The only firm requirement for using <acronym class="acronym">NFS</acronym> with
+ <span class="productname">PostgreSQL</span> is that the file system is mounted
+ using the <code class="literal">hard</code> option. With the
+ <code class="literal">hard</code> option, processes can <span class="quote">“<span class="quote">hang</span>”</span>
+ indefinitely if there are network problems, so this configuration will
+ require a careful monitoring setup. The <code class="literal">soft</code> option
+ will interrupt system calls in case of network problems, but
+ <span class="productname">PostgreSQL</span> will not repeat system calls
+ interrupted in this way, so any such interruption will result in an I/O
+ error being reported.
+ </p><p>
+ It is not necessary to use the <code class="literal">sync</code> mount option. The
+ behavior of the <code class="literal">async</code> option is sufficient, since
+ <span class="productname">PostgreSQL</span> issues <code class="literal">fsync</code>
+ calls at appropriate times to flush the write caches. (This is analogous
+ to how it works on a local file system.) However, it is strongly
+ recommended to use the <code class="literal">sync</code> export option on the NFS
+ <span class="emphasis"><em>server</em></span> on systems where it exists (mainly Linux).
+ Otherwise, an <code class="literal">fsync</code> or equivalent on the NFS client is
+ not actually guaranteed to reach permanent storage on the server, which
+ could cause corruption similar to running with the parameter <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a> off. The defaults of these mount and export
+ options differ between vendors and versions, so it is recommended to
+ check and perhaps specify them explicitly in any case to avoid any
+ ambiguity.
+ </p><p>
+ In some cases, an external storage product can be accessed either via NFS
+ or a lower-level protocol such as iSCSI. In the latter case, the storage
+ appears as a block device and any available file system can be created on
+ it. That approach might relieve the DBA from having to deal with some of
+ the idiosyncrasies of NFS, but of course the complexity of managing
+ remote storage then happens at other levels.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="postgres-user.html" title="19.1. The PostgreSQL User Account">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="server-start.html" title="19.3. Starting the Database Server">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.1. The <span class="productname">PostgreSQL</span> User Account </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.3. Starting the Database Server</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/cube.html b/doc/src/sgml/html/cube.html
new file mode 100644
index 0000000..e4b2a17
--- /dev/null
+++ b/doc/src/sgml/html/cube.html
@@ -0,0 +1,391 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.11. cube</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="citext.html" title="F.10. citext" /><link rel="next" href="dblink.html" title="F.12. dblink" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.11. cube</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="citext.html" title="F.10. citext">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dblink.html" title="F.12. dblink">Next</a></td></tr></table><hr /></div><div class="sect1" id="CUBE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.11. cube</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.5">F.11.1. Syntax</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.6">F.11.2. Precision</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.7">F.11.3. Usage</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.8">F.11.4. Defaults</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.9">F.11.5. Notes</a></span></dt><dt><span class="sect2"><a href="cube.html#id-1.11.7.20.10">F.11.6. Credits</a></span></dt></dl></div><a id="id-1.11.7.20.2" class="indexterm"></a><p>
+ This module implements a data type <code class="type">cube</code> for
+ representing multidimensional cubes.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.20.5"><div class="titlepage"><div><div><h3 class="title">F.11.1. Syntax</h3></div></div></div><p>
+ <a class="xref" href="cube.html#CUBE-REPR-TABLE" title="Table F.2. Cube External Representations">Table F.2</a> shows the valid external
+ representations for the <code class="type">cube</code>
+ type. <em class="replaceable"><code>x</code></em>, <em class="replaceable"><code>y</code></em>, etc. denote
+ floating-point numbers.
+ </p><div class="table" id="CUBE-REPR-TABLE"><p class="title"><strong>Table F.2. Cube External Representations</strong></p><div class="table-contents"><table class="table" summary="Cube External Representations" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>External Syntax</th><th>Meaning</th></tr></thead><tbody><tr><td><code class="literal"><em class="replaceable"><code>x</code></em></code></td><td>A one-dimensional point
+ (or, zero-length one-dimensional interval)
+ </td></tr><tr><td><code class="literal">(<em class="replaceable"><code>x</code></em>)</code></td><td>Same as above</td></tr><tr><td><code class="literal"><em class="replaceable"><code>x1</code></em>,<em class="replaceable"><code>x2</code></em>,...,<em class="replaceable"><code>xn</code></em></code></td><td>A point in n-dimensional space, represented internally as a
+ zero-volume cube
+ </td></tr><tr><td><code class="literal">(<em class="replaceable"><code>x1</code></em>,<em class="replaceable"><code>x2</code></em>,...,<em class="replaceable"><code>xn</code></em>)</code></td><td>Same as above</td></tr><tr><td><code class="literal">(<em class="replaceable"><code>x</code></em>),(<em class="replaceable"><code>y</code></em>)</code></td><td>A one-dimensional interval starting at <em class="replaceable"><code>x</code></em> and ending at <em class="replaceable"><code>y</code></em> or vice versa; the
+ order does not matter
+ </td></tr><tr><td><code class="literal">[(<em class="replaceable"><code>x</code></em>),(<em class="replaceable"><code>y</code></em>)]</code></td><td>Same as above</td></tr><tr><td><code class="literal">(<em class="replaceable"><code>x1</code></em>,...,<em class="replaceable"><code>xn</code></em>),(<em class="replaceable"><code>y1</code></em>,...,<em class="replaceable"><code>yn</code></em>)</code></td><td>An n-dimensional cube represented by a pair of its diagonally
+ opposite corners
+ </td></tr><tr><td><code class="literal">[(<em class="replaceable"><code>x1</code></em>,...,<em class="replaceable"><code>xn</code></em>),(<em class="replaceable"><code>y1</code></em>,...,<em class="replaceable"><code>yn</code></em>)]</code></td><td>Same as above</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ It does not matter which order the opposite corners of a cube are
+ entered in. The <code class="type">cube</code> functions
+ automatically swap values if needed to create a uniform
+ <span class="quote">“<span class="quote">lower left — upper right</span>”</span> internal representation.
+ When the corners coincide, <code class="type">cube</code> stores only one corner
+ along with an <span class="quote">“<span class="quote">is point</span>”</span> flag to avoid wasting space.
+ </p><p>
+ White space is ignored on input, so
+ <code class="literal">[(<em class="replaceable"><code>x</code></em>),(<em class="replaceable"><code>y</code></em>)]</code> is the same as
+ <code class="literal">[ ( <em class="replaceable"><code>x</code></em> ), ( <em class="replaceable"><code>y</code></em> ) ]</code>.
+ </p></div><div class="sect2" id="id-1.11.7.20.6"><div class="titlepage"><div><div><h3 class="title">F.11.2. Precision</h3></div></div></div><p>
+ Values are stored internally as 64-bit floating point numbers. This means
+ that numbers with more than about 16 significant digits will be truncated.
+ </p></div><div class="sect2" id="id-1.11.7.20.7"><div class="titlepage"><div><div><h3 class="title">F.11.3. Usage</h3></div></div></div><p>
+ <a class="xref" href="cube.html#CUBE-OPERATORS-TABLE" title="Table F.3. Cube Operators">Table F.3</a> shows the specialized operators
+ provided for type <code class="type">cube</code>.
+ </p><div class="table" id="CUBE-OPERATORS-TABLE"><p class="title"><strong>Table F.3. Cube Operators</strong></p><div class="table-contents"><table class="table" summary="Cube Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">&amp;&amp;</code> <code class="type">cube</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do the cubes overlap?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">@&gt;</code> <code class="type">cube</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first cube contain the second?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">&lt;@</code> <code class="type">cube</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first cube contained in the second?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">-&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Extracts the <em class="parameter"><code>n</code></em>-th coordinate of the cube
+ (counting from 1).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">~&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Extracts the <em class="parameter"><code>n</code></em>-th coordinate of the cube,
+ counting in the following way: <em class="parameter"><code>n</code></em> = 2
+ * <em class="parameter"><code>k</code></em> - 1 means lower bound
+ of <em class="parameter"><code>k</code></em>-th dimension, <em class="parameter"><code>n</code></em> = 2
+ * <em class="parameter"><code>k</code></em> means upper bound of
+ <em class="parameter"><code>k</code></em>-th dimension. Negative
+ <em class="parameter"><code>n</code></em> denotes the inverse value of the corresponding
+ positive coordinate. This operator is designed for KNN-GiST support.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">&lt;-&gt;</code> <code class="type">cube</code>
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Computes the Euclidean distance between the two cubes.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">&lt;#&gt;</code> <code class="type">cube</code>
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Computes the taxicab (L-1 metric) distance between the two cubes.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">cube</code> <code class="literal">&lt;=&gt;</code> <code class="type">cube</code>
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Computes the Chebyshev (L-inf metric) distance between the two cubes.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In addition to the above operators, the usual comparison
+ operators shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are
+ available for type <code class="type">cube</code>. These
+ operators first compare the first coordinates, and if those are equal,
+ compare the second coordinates, etc. They exist mainly to support the
+ b-tree index operator class for <code class="type">cube</code>, which can be useful for
+ example if you would like a UNIQUE constraint on a <code class="type">cube</code> column.
+ Otherwise, this ordering is not of much practical use.
+ </p><p>
+ The <code class="filename">cube</code> module also provides a GiST index operator class for
+ <code class="type">cube</code> values.
+ A <code class="type">cube</code> GiST index can be used to search for values using the
+ <code class="literal">=</code>, <code class="literal">&amp;&amp;</code>, <code class="literal">@&gt;</code>, and
+ <code class="literal">&lt;@</code> operators in <code class="literal">WHERE</code> clauses.
+ </p><p>
+ In addition, a <code class="type">cube</code> GiST index can be used to find nearest
+ neighbors using the metric operators
+ <code class="literal">&lt;-&gt;</code>, <code class="literal">&lt;#&gt;</code>, and
+ <code class="literal">&lt;=&gt;</code> in <code class="literal">ORDER BY</code> clauses.
+ For example, the nearest neighbor of the 3-D point (0.5, 0.5, 0.5)
+ could be found efficiently with:
+</p><pre class="programlisting">
+SELECT c FROM test ORDER BY c &lt;-&gt; cube(array[0.5,0.5,0.5]) LIMIT 1;
+</pre><p>
+ </p><p>
+ The <code class="literal">~&gt;</code> operator can also be used in this way to
+ efficiently retrieve the first few values sorted by a selected coordinate.
+ For example, to get the first few cubes ordered by the first coordinate
+ (lower left corner) ascending one could use the following query:
+</p><pre class="programlisting">
+SELECT c FROM test ORDER BY c ~&gt; 1 LIMIT 5;
+</pre><p>
+ And to get 2-D cubes ordered by the first coordinate of the upper right
+ corner descending:
+</p><pre class="programlisting">
+SELECT c FROM test ORDER BY c ~&gt; 3 DESC LIMIT 5;
+</pre><p>
+ </p><p>
+ <a class="xref" href="cube.html#CUBE-FUNCTIONS-TABLE" title="Table F.4. Cube Functions">Table F.4</a> shows the available functions.
+ </p><div class="table" id="CUBE-FUNCTIONS-TABLE"><p class="title"><strong>Table F.4. Cube Functions</strong></p><div class="table-contents"><table class="table" summary="Cube Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube</code> ( <code class="type">float8</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a one dimensional cube with both coordinates the same.
+ </p>
+ <p>
+ <code class="literal">cube(1)</code>
+ → <code class="returnvalue">(1)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube</code> ( <code class="type">float8</code>, <code class="type">float8</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a one dimensional cube.
+ </p>
+ <p>
+ <code class="literal">cube(1, 2)</code>
+ → <code class="returnvalue">(1),(2)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube</code> ( <code class="type">float8[]</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a zero-volume cube using the coordinates defined by the array.
+ </p>
+ <p>
+ <code class="literal">cube(ARRAY[1,2,3])</code>
+ → <code class="returnvalue">(1, 2, 3)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube</code> ( <code class="type">float8[]</code>, <code class="type">float8[]</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a cube with upper right and lower left coordinates as defined by
+ the two arrays, which must be of the same length.
+ </p>
+ <p>
+ <code class="literal">cube(ARRAY[1,2], ARRAY[3,4])</code>
+ → <code class="returnvalue">(1, 2),(3, 4)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube</code> ( <code class="type">cube</code>, <code class="type">float8</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a new cube by adding a dimension on to an existing cube,
+ with the same values for both endpoints of the new coordinate. This
+ is useful for building cubes piece by piece from calculated values.
+ </p>
+ <p>
+ <code class="literal">cube('(1,2),(3,4)'::cube, 5)</code>
+ → <code class="returnvalue">(1, 2, 5),(3, 4, 5)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube</code> ( <code class="type">cube</code>, <code class="type">float8</code>, <code class="type">float8</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a new cube by adding a dimension on to an existing cube. This is
+ useful for building cubes piece by piece from calculated values.
+ </p>
+ <p>
+ <code class="literal">cube('(1,2),(3,4)'::cube, 5, 6)</code>
+ → <code class="returnvalue">(1, 2, 5),(3, 4, 6)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_dim</code> ( <code class="type">cube</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of dimensions of the cube.
+ </p>
+ <p>
+ <code class="literal">cube_dim('(1,2),(3,4)')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_ll_coord</code> ( <code class="type">cube</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the <em class="parameter"><code>n</code></em>-th coordinate value for the lower
+ left corner of the cube.
+ </p>
+ <p>
+ <code class="literal">cube_ll_coord('(1,2),(3,4)', 2)</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_ur_coord</code> ( <code class="type">cube</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the <em class="parameter"><code>n</code></em>-th coordinate value for the
+ upper right corner of the cube.
+ </p>
+ <p>
+ <code class="literal">cube_ur_coord('(1,2),(3,4)', 2)</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_is_point</code> ( <code class="type">cube</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if the cube is a point, that is,
+ the two defining corners are the same.
+ </p>
+ <p>
+ <code class="literal">cube_is_point(cube(1,1))</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_distance</code> ( <code class="type">cube</code>, <code class="type">cube</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the distance between two cubes. If both
+ cubes are points, this is the normal distance function.
+ </p>
+ <p>
+ <code class="literal">cube_distance('(1,2)', '(3,4)')</code>
+ → <code class="returnvalue">2.8284271247461903</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_subset</code> ( <code class="type">cube</code>, <code class="type">integer[]</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Makes a new cube from an existing cube, using a list of
+ dimension indexes from an array. Can be used to extract the endpoints
+ of a single dimension, or to drop dimensions, or to reorder them as
+ desired.
+ </p>
+ <p>
+ <code class="literal">cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2])</code>
+ → <code class="returnvalue">(3),(7)</code>
+ </p>
+ <p>
+ <code class="literal">cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1])</code>
+ → <code class="returnvalue">(5, 3, 1, 1),(8, 7, 6, 6)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_union</code> ( <code class="type">cube</code>, <code class="type">cube</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Produces the union of two cubes.
+ </p>
+ <p>
+ <code class="literal">cube_union('(1,2)', '(3,4)')</code>
+ → <code class="returnvalue">(1, 2),(3, 4)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_inter</code> ( <code class="type">cube</code>, <code class="type">cube</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Produces the intersection of two cubes.
+ </p>
+ <p>
+ <code class="literal">cube_inter('(1,2)', '(3,4)')</code>
+ → <code class="returnvalue">(3, 4),(1, 2)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">cube_enlarge</code> ( <em class="parameter"><code>c</code></em> <code class="type">cube</code>, <em class="parameter"><code>r</code></em> <code class="type">double</code>, <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Increases the size of the cube by the specified
+ radius <em class="parameter"><code>r</code></em> in at least <em class="parameter"><code>n</code></em>
+ dimensions. If the radius is negative the cube is shrunk instead.
+ All defined dimensions are changed by the
+ radius <em class="parameter"><code>r</code></em>. Lower-left coordinates are decreased
+ by <em class="parameter"><code>r</code></em> and upper-right coordinates are increased
+ by <em class="parameter"><code>r</code></em>. If a lower-left coordinate is increased
+ to more than the corresponding upper-right coordinate (this can only
+ happen when <em class="parameter"><code>r</code></em> &lt; 0) than both coordinates are
+ set to their average. If <em class="parameter"><code>n</code></em> is greater than the
+ number of defined dimensions and the cube is being enlarged
+ (<em class="parameter"><code>r</code></em> &gt; 0), then extra dimensions are added to
+ make <em class="parameter"><code>n</code></em> altogether; 0 is used as the initial
+ value for the extra coordinates. This function is useful for creating
+ bounding boxes around a point for searching for nearby points.
+ </p>
+ <p>
+ <code class="literal">cube_enlarge('(1,2),(3,4)', 0.5, 3)</code>
+ → <code class="returnvalue">(0.5, 1.5, -0.5),(3.5, 4.5, 0.5)</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.20.8"><div class="titlepage"><div><div><h3 class="title">F.11.4. Defaults</h3></div></div></div><p>
+ I believe this union:
+ </p><pre class="programlisting">
+select cube_union('(0,5,2),(2,3,1)', '0');
+cube_union
+-------------------
+(0, 0, 0),(2, 5, 2)
+(1 row)
+</pre><p>
+ does not contradict common sense, neither does the intersection
+ </p><pre class="programlisting">
+select cube_inter('(0,-1),(1,1)', '(-2),(2)');
+cube_inter
+-------------
+(0, 0),(1, 0)
+(1 row)
+</pre><p>
+ In all binary operations on differently-dimensioned cubes, I assume the
+ lower-dimensional one to be a Cartesian projection, i. e., having zeroes
+ in place of coordinates omitted in the string representation. The above
+ examples are equivalent to:
+ </p><pre class="programlisting">
+cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
+cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');
+</pre><p>
+ The following containment predicate uses the point syntax,
+ while in fact the second argument is internally represented by a box.
+ This syntax makes it unnecessary to define a separate point type
+ and functions for (box,point) predicates.
+ </p><pre class="programlisting">
+select cube_contains('(0,0),(1,1)', '0.5,0.5');
+cube_contains
+--------------
+t
+(1 row)
+</pre></div><div class="sect2" id="id-1.11.7.20.9"><div class="titlepage"><div><div><h3 class="title">F.11.5. Notes</h3></div></div></div><p>
+ For examples of usage, see the regression test <code class="filename">sql/cube.sql</code>.
+ </p><p>
+ To make it harder for people to break things, there
+ is a limit of 100 on the number of dimensions of cubes. This is set
+ in <code class="filename">cubedata.h</code> if you need something bigger.
+ </p></div><div class="sect2" id="id-1.11.7.20.10"><div class="titlepage"><div><div><h3 class="title">F.11.6. Credits</h3></div></div></div><p>
+ Original author: Gene Selkov, Jr. <code class="email">&lt;<a class="email" href="mailto:selkovjr@mcs.anl.gov">selkovjr@mcs.anl.gov</a>&gt;</code>,
+ Mathematics and Computer Science Division, Argonne National Laboratory.
+ </p><p>
+ My thanks are primarily to Prof. Joe Hellerstein
+ (<a class="ulink" href="https://dsf.berkeley.edu/jmh/" target="_top">https://dsf.berkeley.edu/jmh/</a>) for elucidating the
+ gist of the GiST (<a class="ulink" href="http://gist.cs.berkeley.edu/" target="_top">http://gist.cs.berkeley.edu/</a>), and
+ to his former student Andy Dong for his example written for Illustra.
+ I am also grateful to all Postgres developers, present and past, for
+ enabling myself to create my own world and live undisturbed in it. And I
+ would like to acknowledge my gratitude to Argonne Lab and to the
+ U.S. Department of Energy for the years of faithful support of my database
+ research.
+ </p><p>
+ Minor updates to this package were made by Bruno Wolff III
+ <code class="email">&lt;<a class="email" href="mailto:bruno@wolff.to">bruno@wolff.to</a>&gt;</code> in August/September of 2002. These include
+ changing the precision from single precision to double precision and adding
+ some new functions.
+ </p><p>
+ Additional updates were made by Joshua Reich <code class="email">&lt;<a class="email" href="mailto:josh@root.net">josh@root.net</a>&gt;</code> in
+ July 2006. These include <code class="literal">cube(float8[], float8[])</code> and
+ cleaning up the code to use the V1 call protocol instead of the deprecated
+ V0 protocol.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="citext.html" title="F.10. citext">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dblink.html" title="F.12. dblink">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.10. citext </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.12. dblink</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/custom-rmgr.html b/doc/src/sgml/html/custom-rmgr.html
new file mode 100644
index 0000000..78f328b
--- /dev/null
+++ b/doc/src/sgml/html/custom-rmgr.html
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 66. Custom WAL Resource Managers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="generic-wal.html" title="Chapter 65. Generic WAL Records" /><link rel="next" href="btree.html" title="Chapter 67. B-Tree Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 66. Custom WAL Resource Managers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="generic-wal.html" title="Chapter 65. Generic WAL Records">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="btree.html" title="Chapter 67. B-Tree Indexes">Next</a></td></tr></table><hr /></div><div class="chapter" id="CUSTOM-RMGR"><div class="titlepage"><div><div><h2 class="title">Chapter 66. Custom WAL Resource Managers</h2></div></div></div><p>
+ This chapter explains the interface between the core
+ <span class="productname">PostgreSQL</span> system and custom WAL resource
+ managers, which enable extensions to integrate directly with the <a class="link" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log"><acronym class="acronym">WAL</acronym></a>.
+ </p><p>
+ An extension, especially a <a class="link" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Table Access
+ Method</a> or <a class="link" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Index Access Method</a>, may
+ need to use WAL for recovery, replication, and/or <a class="link" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Logical Decoding</a>. Custom resource managers
+ are a more flexible alternative to <a class="link" href="generic-wal.html" title="Chapter 65. Generic WAL Records">Generic
+ WAL</a> (which does not support logical decoding), but more complex for
+ an extension to implement.
+ </p><p>
+ To create a new custom WAL resource manager, first define an
+ <code class="structname">RmgrData</code> structure with implementations for the
+ resource manager methods. Refer to
+ <code class="filename">src/backend/access/transam/README</code> and
+ <code class="filename">src/include/access/xlog_internal.h</code> in the
+ <span class="productname">PostgreSQL</span> source.
+</p><pre class="programlisting">
+/*
+ * Method table for resource managers.
+ *
+ * This struct must be kept in sync with the PG_RMGR definition in
+ * rmgr.c.
+ *
+ * rm_identify must return a name for the record based on xl_info (without
+ * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named
+ * "VACUUM". rm_desc can then be called to obtain additional detail for the
+ * record, if available (e.g. the last block).
+ *
+ * rm_mask takes as input a page modified by the resource manager and masks
+ * out bits that shouldn't be flagged by wal_consistency_checking.
+ *
+ * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). If rm_name is
+ * NULL, the corresponding RmgrTable entry is considered invalid.
+ */
+typedef struct RmgrData
+{
+ const char *rm_name;
+ void (*rm_redo) (XLogReaderState *record);
+ void (*rm_desc) (StringInfo buf, XLogReaderState *record);
+ const char *(*rm_identify) (uint8 info);
+ void (*rm_startup) (void);
+ void (*rm_cleanup) (void);
+ void (*rm_mask) (char *pagedata, BlockNumber blkno);
+ void (*rm_decode) (struct LogicalDecodingContext *ctx,
+ struct XLogRecordBuffer *buf);
+} RmgrData;
+</pre><p>
+ </p><p>
+ Then, register your new resource
+ manager.
+
+</p><pre class="programlisting">
+/*
+ * Register a new custom WAL resource manager.
+ *
+ * Resource manager IDs must be globally unique across all extensions. Refer
+ * to https://wiki.postgresql.org/wiki/CustomWALResourceManagers to reserve a
+ * unique RmgrId for your extension, to avoid conflicts with other extension
+ * developers. During development, use RM_EXPERIMENTAL_ID to avoid needlessly
+ * reserving a new ID.
+ */
+extern void RegisterCustomRmgr(RmgrId rmid, RmgrData *rmgr);
+</pre><p>
+ <code class="function">RegisterCustomRmgr</code> must be called from the
+ extension module's <a class="link" href="xfunc-c.html#XFUNC-C-DYNLOAD" title="38.10.1. Dynamic Loading">_PG_init</a> function.
+ While developing a new extension, use <code class="literal">RM_EXPERIMENTAL_ID</code>
+ for <em class="parameter"><code>rmid</code></em>. When you are ready to release the extension
+ to users, reserve a new resource manager ID at the <a class="ulink" href="https://wiki.postgresql.org/wiki/CustomWALResourceManagers" target="_top">Custom WAL
+ Resource Manager</a> page.
+ </p><p>
+ Place the extension module implementing the custom resource manager in <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> so that it will be loaded early
+ during <span class="productname">PostgreSQL</span> startup.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The extension must remain in shared_preload_libraries as long as any
+ custom WAL records may exist in the system. Otherwise
+ <span class="productname">PostgreSQL</span> will not be able to apply or decode
+ the custom WAL records, which may prevent the server from starting.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="generic-wal.html" title="Chapter 65. Generic WAL Records">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="btree.html" title="Chapter 67. B-Tree Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 65. Generic WAL Records </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 67. B-Tree Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/custom-scan-execution.html b/doc/src/sgml/html/custom-scan-execution.html
new file mode 100644
index 0000000..8f4540f
--- /dev/null
+++ b/doc/src/sgml/html/custom-scan-execution.html
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>61.3. Executing Custom Scans</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans" /><link rel="next" href="geqo.html" title="Chapter 62. Genetic Query Optimizer" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">61.3. Executing Custom Scans</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Up</a></td><th width="60%" align="center">Chapter 61. Writing a Custom Scan Provider</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Next</a></td></tr></table><hr /></div><div class="sect1" id="CUSTOM-SCAN-EXECUTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">61.3. Executing Custom Scans</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="custom-scan-execution.html#CUSTOM-SCAN-EXECUTION-CALLBACKS">61.3.1. Custom Scan Execution Callbacks</a></span></dt></dl></div><p>
+ When a <code class="structfield">CustomScan</code> is executed, its execution state is
+ represented by a <code class="structfield">CustomScanState</code>, which is declared as
+ follows:
+</p><pre class="programlisting">
+typedef struct CustomScanState
+{
+ ScanState ss;
+ uint32 flags;
+ const CustomExecMethods *methods;
+} CustomScanState;
+</pre><p>
+ </p><p>
+ <code class="structfield">ss</code> is initialized as for any other scan state,
+ except that if the scan is for a join rather than a base relation,
+ <code class="literal">ss.ss_currentRelation</code> is left NULL.
+ <code class="structfield">flags</code> is a bit mask with the same meaning as in
+ <code class="structname">CustomPath</code> and <code class="structname">CustomScan</code>.
+ <code class="structfield">methods</code> must point to a (usually statically allocated)
+ object implementing the required custom scan state methods, which are
+ further detailed below. Typically, a <code class="structname">CustomScanState</code>, which
+ need not support <code class="function">copyObject</code>, will actually be a larger
+ structure embedding the above as its first member.
+ </p><div class="sect2" id="CUSTOM-SCAN-EXECUTION-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">61.3.1. Custom Scan Execution Callbacks</h3></div></div></div><p>
+</p><pre class="programlisting">
+void (*BeginCustomScan) (CustomScanState *node,
+ EState *estate,
+ int eflags);
+</pre><p>
+ Complete initialization of the supplied <code class="structname">CustomScanState</code>.
+ Standard fields have been initialized by <code class="function">ExecInitCustomScan</code>,
+ but any private fields should be initialized here.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot *(*ExecCustomScan) (CustomScanState *node);
+</pre><p>
+ Fetch the next scan tuple. If any tuples remain, it should fill
+ <code class="literal">ps_ResultTupleSlot</code> with the next tuple in the current scan
+ direction, and then return the tuple slot. If not,
+ <code class="literal">NULL</code> or an empty slot should be returned.
+ </p><p>
+</p><pre class="programlisting">
+void (*EndCustomScan) (CustomScanState *node);
+</pre><p>
+ Clean up any private data associated with the <code class="literal">CustomScanState</code>.
+ This method is required, but it does not need to do anything if there is
+ no associated data or it will be cleaned up automatically.
+ </p><p>
+</p><pre class="programlisting">
+void (*ReScanCustomScan) (CustomScanState *node);
+</pre><p>
+ Rewind the current scan to the beginning and prepare to rescan the
+ relation.
+ </p><p>
+</p><pre class="programlisting">
+void (*MarkPosCustomScan) (CustomScanState *node);
+</pre><p>
+ Save the current scan position so that it can subsequently be restored
+ by the <code class="function">RestrPosCustomScan</code> callback. This callback is
+ optional, and need only be supplied if the
+ <code class="literal">CUSTOMPATH_SUPPORT_MARK_RESTORE</code> flag is set.
+ </p><p>
+</p><pre class="programlisting">
+void (*RestrPosCustomScan) (CustomScanState *node);
+</pre><p>
+ Restore the previous scan position as saved by the
+ <code class="function">MarkPosCustomScan</code> callback. This callback is optional,
+ and need only be supplied if the
+ <code class="literal">CUSTOMPATH_SUPPORT_MARK_RESTORE</code> flag is set.
+ </p><p>
+</p><pre class="programlisting">
+Size (*EstimateDSMCustomScan) (CustomScanState *node,
+ ParallelContext *pcxt);
+</pre><p>
+ Estimate the amount of dynamic shared memory that will be required
+ for parallel operation. This may be higher than the amount that will
+ actually be used, but it must not be lower. The return value is in bytes.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ </p><p>
+</p><pre class="programlisting">
+void (*InitializeDSMCustomScan) (CustomScanState *node,
+ ParallelContext *pcxt,
+ void *coordinate);
+</pre><p>
+ Initialize the dynamic shared memory that will be required for parallel
+ operation. <code class="literal">coordinate</code> points to a shared memory area of
+ size equal to the return value of <code class="function">EstimateDSMCustomScan</code>.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ </p><p>
+</p><pre class="programlisting">
+void (*ReInitializeDSMCustomScan) (CustomScanState *node,
+ ParallelContext *pcxt,
+ void *coordinate);
+</pre><p>
+ Re-initialize the dynamic shared memory required for parallel operation
+ when the custom-scan plan node is about to be re-scanned.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ Recommended practice is that this callback reset only shared state,
+ while the <code class="function">ReScanCustomScan</code> callback resets only local
+ state. Currently, this callback will be called
+ before <code class="function">ReScanCustomScan</code>, but it's best not to rely on
+ that ordering.
+ </p><p>
+</p><pre class="programlisting">
+void (*InitializeWorkerCustomScan) (CustomScanState *node,
+ shm_toc *toc,
+ void *coordinate);
+</pre><p>
+ Initialize a parallel worker's local state based on the shared state
+ set up by the leader during <code class="function">InitializeDSMCustomScan</code>.
+ This callback is optional, and need only be supplied if this custom
+ scan provider supports parallel execution.
+ </p><p>
+</p><pre class="programlisting">
+void (*ShutdownCustomScan) (CustomScanState *node);
+</pre><p>
+ Release resources when it is anticipated the node will not be executed
+ to completion. This is not called in all cases; sometimes,
+ <code class="literal">EndCustomScan</code> may be called without this function having
+ been called first. Since the DSM segment used by parallel query is
+ destroyed just after this callback is invoked, custom scan providers that
+ wish to take some action before the DSM segment goes away should implement
+ this method.
+ </p><p>
+</p><pre class="programlisting">
+void (*ExplainCustomScan) (CustomScanState *node,
+ List *ancestors,
+ ExplainState *es);
+</pre><p>
+ Output additional information for <code class="command">EXPLAIN</code> of a custom-scan
+ plan node. This callback is optional. Common data stored in the
+ <code class="structname">ScanState</code>, such as the target list and scan relation, will
+ be shown even without this callback, but the callback allows the display
+ of additional, private state.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Next</a></td></tr><tr><td width="40%" align="left" valign="top">61.2. Creating Custom Scan Plans </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 62. Genetic Query Optimizer</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/custom-scan-path.html b/doc/src/sgml/html/custom-scan-path.html
new file mode 100644
index 0000000..7e13d4e
--- /dev/null
+++ b/doc/src/sgml/html/custom-scan-path.html
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>61.1. Creating Custom Scan Paths</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider" /><link rel="next" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">61.1. Creating Custom Scan Paths</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Up</a></td><th width="60%" align="center">Chapter 61. Writing a Custom Scan Provider</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans">Next</a></td></tr></table><hr /></div><div class="sect1" id="CUSTOM-SCAN-PATH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">61.1. Creating Custom Scan Paths</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="custom-scan-path.html#CUSTOM-SCAN-PATH-CALLBACKS">61.1.1. Custom Scan Path Callbacks</a></span></dt></dl></div><p>
+ A custom scan provider will typically add paths for a base relation by
+ setting the following hook, which is called after the core code has
+ generated all the access paths it can for the relation (except for
+ Gather paths, which are made after this call so that they can use
+ partial paths added by the hook):
+</p><pre class="programlisting">
+typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
+ RelOptInfo *rel,
+ Index rti,
+ RangeTblEntry *rte);
+extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook;
+</pre><p>
+ </p><p>
+ Although this hook function can be used to examine, modify, or remove
+ paths generated by the core system, a custom scan provider will typically
+ confine itself to generating <code class="structname">CustomPath</code> objects and adding
+ them to <code class="literal">rel</code> using <code class="function">add_path</code>. The custom scan
+ provider is responsible for initializing the <code class="structname">CustomPath</code>
+ object, which is declared like this:
+</p><pre class="programlisting">
+typedef struct CustomPath
+{
+ Path path;
+ uint32 flags;
+ List *custom_paths;
+ List *custom_private;
+ const CustomPathMethods *methods;
+} CustomPath;
+</pre><p>
+ </p><p>
+ <code class="structfield">path</code> must be initialized as for any other path, including
+ the row-count estimate, start and total cost, and sort ordering provided
+ by this path. <code class="structfield">flags</code> is a bit mask, which
+ specifies whether the scan provider can support certain optional
+ capabilities. <code class="structfield">flags</code> should include
+ <code class="literal">CUSTOMPATH_SUPPORT_BACKWARD_SCAN</code> if the custom path can support
+ a backward scan, <code class="literal">CUSTOMPATH_SUPPORT_MARK_RESTORE</code> if it
+ can support mark and restore,
+ and <code class="literal">CUSTOMPATH_SUPPORT_PROJECTION</code> if it can perform
+ projections. (If <code class="literal">CUSTOMPATH_SUPPORT_PROJECTION</code> is not
+ set, the scan node will only be asked to produce Vars of the scanned
+ relation; while if that flag is set, the scan node must be able to
+ evaluate scalar expressions over these Vars.)
+ An optional <code class="structfield">custom_paths</code> is a list of <code class="structname">Path</code>
+ nodes used by this custom-path node; these will be transformed into
+ <code class="structname">Plan</code> nodes by planner.
+ <code class="structfield">custom_private</code> can be used to store the custom path's
+ private data. Private data should be stored in a form that can be handled
+ by <code class="literal">nodeToString</code>, so that debugging routines that attempt to
+ print the custom path will work as designed. <code class="structfield">methods</code> must
+ point to a (usually statically allocated) object implementing the required
+ custom path methods, which are further detailed below.
+ </p><p>
+ A custom scan provider can also provide join paths. Just as for base
+ relations, such a path must produce the same output as would normally be
+ produced by the join it replaces. To do this, the join provider should
+ set the following hook, and then within the hook function,
+ create <code class="structname">CustomPath</code> path(s) for the join relation.
+</p><pre class="programlisting">
+typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root,
+ RelOptInfo *joinrel,
+ RelOptInfo *outerrel,
+ RelOptInfo *innerrel,
+ JoinType jointype,
+ JoinPathExtraData *extra);
+extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook;
+</pre><p>
+
+ This hook will be invoked repeatedly for the same join relation, with
+ different combinations of inner and outer relations; it is the
+ responsibility of the hook to minimize duplicated work.
+ </p><div class="sect2" id="CUSTOM-SCAN-PATH-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">61.1.1. Custom Scan Path Callbacks</h3></div></div></div><p>
+</p><pre class="programlisting">
+Plan *(*PlanCustomPath) (PlannerInfo *root,
+ RelOptInfo *rel,
+ CustomPath *best_path,
+ List *tlist,
+ List *clauses,
+ List *custom_plans);
+</pre><p>
+ Convert a custom path to a finished plan. The return value will generally
+ be a <code class="literal">CustomScan</code> object, which the callback must allocate and
+ initialize. See <a class="xref" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans">Section 61.2</a> for more details.
+ </p><p>
+</p><pre class="programlisting">
+List *(*ReparameterizeCustomPathByChild) (PlannerInfo *root,
+ List *custom_private,
+ RelOptInfo *child_rel);
+</pre><p>
+ This callback is called while converting a path parameterized by the
+ top-most parent of the given child relation <code class="literal">child_rel</code>
+ to be parameterized by the child relation. The callback is used to
+ reparameterize any paths or translate any expression nodes saved in the
+ given <code class="literal">custom_private</code> member of a
+ <code class="structname">CustomPath</code>. The callback may use
+ <code class="literal">reparameterize_path_by_child</code>,
+ <code class="literal">adjust_appendrel_attrs</code> or
+ <code class="literal">adjust_appendrel_attrs_multilevel</code> as required.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="custom-scan-plan.html" title="61.2. Creating Custom Scan Plans">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 61. Writing a Custom Scan Provider </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 61.2. Creating Custom Scan Plans</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/custom-scan-plan.html b/doc/src/sgml/html/custom-scan-plan.html
new file mode 100644
index 0000000..cf37532
--- /dev/null
+++ b/doc/src/sgml/html/custom-scan-plan.html
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>61.2. Creating Custom Scan Plans</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="custom-scan-path.html" title="61.1. Creating Custom Scan Paths" /><link rel="next" href="custom-scan-execution.html" title="61.3. Executing Custom Scans" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">61.2. Creating Custom Scan Plans</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="custom-scan-path.html" title="61.1. Creating Custom Scan Paths">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Up</a></td><th width="60%" align="center">Chapter 61. Writing a Custom Scan Provider</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="custom-scan-execution.html" title="61.3. Executing Custom Scans">Next</a></td></tr></table><hr /></div><div class="sect1" id="CUSTOM-SCAN-PLAN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">61.2. Creating Custom Scan Plans</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="custom-scan-plan.html#CUSTOM-SCAN-PLAN-CALLBACKS">61.2.1. Custom Scan Plan Callbacks</a></span></dt></dl></div><p>
+ A custom scan is represented in a finished plan tree using the following
+ structure:
+</p><pre class="programlisting">
+typedef struct CustomScan
+{
+ Scan scan;
+ uint32 flags;
+ List *custom_plans;
+ List *custom_exprs;
+ List *custom_private;
+ List *custom_scan_tlist;
+ Bitmapset *custom_relids;
+ const CustomScanMethods *methods;
+} CustomScan;
+</pre><p>
+ </p><p>
+ <code class="structfield">scan</code> must be initialized as for any other scan, including
+ estimated costs, target lists, qualifications, and so on.
+ <code class="structfield">flags</code> is a bit mask with the same meaning as in
+ <code class="structname">CustomPath</code>.
+ <code class="structfield">custom_plans</code> can be used to store child
+ <code class="structname">Plan</code> nodes.
+ <code class="structfield">custom_exprs</code> should be used to
+ store expression trees that will need to be fixed up by
+ <code class="filename">setrefs.c</code> and <code class="filename">subselect.c</code>, while
+ <code class="structfield">custom_private</code> should be used to store other private data
+ that is only used by the custom scan provider itself.
+ <code class="structfield">custom_scan_tlist</code> can be NIL when scanning a base
+ relation, indicating that the custom scan returns scan tuples that match
+ the base relation's row type. Otherwise it is a target list describing
+ the actual scan tuples. <code class="structfield">custom_scan_tlist</code> must be
+ provided for joins, and could be provided for scans if the custom scan
+ provider can compute some non-Var expressions.
+ <code class="structfield">custom_relids</code> is set by the core code to the set of
+ relations (range table indexes) that this scan node handles; except when
+ this scan is replacing a join, it will have only one member.
+ <code class="structfield">methods</code> must point to a (usually statically allocated)
+ object implementing the required custom scan methods, which are further
+ detailed below.
+ </p><p>
+ When a <code class="structname">CustomScan</code> scans a single relation,
+ <code class="structfield">scan.scanrelid</code> must be the range table index of the table
+ to be scanned. When it replaces a join, <code class="structfield">scan.scanrelid</code>
+ should be zero.
+ </p><p>
+ Plan trees must be able to be duplicated using <code class="function">copyObject</code>,
+ so all the data stored within the <span class="quote">“<span class="quote">custom</span>”</span> fields must consist of
+ nodes that that function can handle. Furthermore, custom scan providers
+ cannot substitute a larger structure that embeds
+ a <code class="structname">CustomScan</code> for the structure itself, as would be possible
+ for a <code class="structname">CustomPath</code> or <code class="structname">CustomScanState</code>.
+ </p><div class="sect2" id="CUSTOM-SCAN-PLAN-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">61.2.1. Custom Scan Plan Callbacks</h3></div></div></div><p>
+</p><pre class="programlisting">
+Node *(*CreateCustomScanState) (CustomScan *cscan);
+</pre><p>
+ Allocate a <code class="structname">CustomScanState</code> for this
+ <code class="structname">CustomScan</code>. The actual allocation will often be larger than
+ required for an ordinary <code class="structname">CustomScanState</code>, because many
+ providers will wish to embed that as the first field of a larger structure.
+ The value returned must have the node tag and <code class="structfield">methods</code>
+ set appropriately, but other fields should be left as zeroes at this
+ stage; after <code class="function">ExecInitCustomScan</code> performs basic initialization,
+ the <code class="function">BeginCustomScan</code> callback will be invoked to give the
+ custom scan provider a chance to do whatever else is needed.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="custom-scan-path.html" title="61.1. Creating Custom Scan Paths">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="custom-scan-execution.html" title="61.3. Executing Custom Scans">Next</a></td></tr><tr><td width="40%" align="left" valign="top">61.1. Creating Custom Scan Paths </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 61.3. Executing Custom Scans</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/custom-scan.html b/doc/src/sgml/html/custom-scan.html
new file mode 100644
index 0000000..e59165b
--- /dev/null
+++ b/doc/src/sgml/html/custom-scan.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 61. Writing a Custom Scan Provider</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions" /><link rel="next" href="custom-scan-path.html" title="61.1. Creating Custom Scan Paths" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 61. Writing a Custom Scan Provider</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="custom-scan-path.html" title="61.1. Creating Custom Scan Paths">Next</a></td></tr></table><hr /></div><div class="chapter" id="CUSTOM-SCAN"><div class="titlepage"><div><div><h2 class="title">Chapter 61. Writing a Custom Scan Provider</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="custom-scan-path.html">61.1. Creating Custom Scan Paths</a></span></dt><dd><dl><dt><span class="sect2"><a href="custom-scan-path.html#CUSTOM-SCAN-PATH-CALLBACKS">61.1.1. Custom Scan Path Callbacks</a></span></dt></dl></dd><dt><span class="sect1"><a href="custom-scan-plan.html">61.2. Creating Custom Scan Plans</a></span></dt><dd><dl><dt><span class="sect2"><a href="custom-scan-plan.html#CUSTOM-SCAN-PLAN-CALLBACKS">61.2.1. Custom Scan Plan Callbacks</a></span></dt></dl></dd><dt><span class="sect1"><a href="custom-scan-execution.html">61.3. Executing Custom Scans</a></span></dt><dd><dl><dt><span class="sect2"><a href="custom-scan-execution.html#CUSTOM-SCAN-EXECUTION-CALLBACKS">61.3.1. Custom Scan Execution Callbacks</a></span></dt></dl></dd></dl></div><a id="id-1.10.12.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> supports a set of experimental facilities which
+ are intended to allow extension modules to add new scan types to the system.
+ Unlike a <a class="link" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">foreign data wrapper</a>, which is only
+ responsible for knowing how to scan its own foreign tables, a custom scan
+ provider can provide an alternative method of scanning any relation in the
+ system. Typically, the motivation for writing a custom scan provider will
+ be to allow the use of some optimization not supported by the core
+ system, such as caching or some form of hardware acceleration. This chapter
+ outlines how to write a new custom scan provider.
+ </p><p>
+ Implementing a new type of custom scan is a three-step process. First,
+ during planning, it is necessary to generate access paths representing a
+ scan using the proposed strategy. Second, if one of those access paths
+ is selected by the planner as the optimal strategy for scanning a
+ particular relation, the access path must be converted to a plan.
+ Finally, it must be possible to execute the plan and generate the same
+ results that would have been generated for any other access path targeting
+ the same relation.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="custom-scan-path.html" title="61.1. Creating Custom Scan Paths">Next</a></td></tr><tr><td width="40%" align="left" valign="top">60.1. Sampling Method Support Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 61.1. Creating Custom Scan Paths</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/database-roles.html b/doc/src/sgml/html/database-roles.html
new file mode 100644
index 0000000..16adcb9
--- /dev/null
+++ b/doc/src/sgml/html/database-roles.html
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>22.1. Database Roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="user-manag.html" title="Chapter 22. Database Roles" /><link rel="next" href="role-attributes.html" title="22.2. Role Attributes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">22.1. Database Roles</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="user-manag.html" title="Chapter 22. Database Roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><th width="60%" align="center">Chapter 22. Database Roles</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="role-attributes.html" title="22.2. Role Attributes">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATABASE-ROLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">22.1. Database Roles</h2></div></div></div><a id="id-1.6.9.5.2" class="indexterm"></a><a id="id-1.6.9.5.3" class="indexterm"></a><a id="id-1.6.9.5.4" class="indexterm"></a><a id="id-1.6.9.5.5" class="indexterm"></a><p>
+ Database roles are conceptually completely separate from
+ operating system users. In practice it might be convenient to
+ maintain a correspondence, but this is not required. Database roles
+ are global across a database cluster installation (and not
+ per individual database). To create a role use the <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="command">CREATE ROLE</code></a> SQL command:
+</p><pre class="synopsis">
+CREATE ROLE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ <em class="replaceable"><code>name</code></em> follows the rules for SQL
+ identifiers: either unadorned without special characters, or
+ double-quoted. (In practice, you will usually want to add additional
+ options, such as <code class="literal">LOGIN</code>, to the command. More details appear
+ below.) To remove an existing role, use the analogous
+ <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a> command:
+</p><pre class="synopsis">
+DROP ROLE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ </p><a id="id-1.6.9.5.7" class="indexterm"></a><a id="id-1.6.9.5.8" class="indexterm"></a><p>
+ For convenience, the programs <a class="xref" href="app-createuser.html" title="createuser"><span class="refentrytitle"><span class="application">createuser</span></span></a>
+ and <a class="xref" href="app-dropuser.html" title="dropuser"><span class="refentrytitle"><span class="application">dropuser</span></span></a> are provided as wrappers
+ around these SQL commands that can be called from the shell command
+ line:
+</p><pre class="synopsis">
+createuser <em class="replaceable"><code>name</code></em>
+dropuser <em class="replaceable"><code>name</code></em>
+</pre><p>
+ </p><p>
+ To determine the set of existing roles, examine the <code class="structname">pg_roles</code>
+ system catalog, for example
+</p><pre class="synopsis">
+SELECT rolname FROM pg_roles;
+</pre><p>
+ The <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> program's <code class="literal">\du</code> meta-command
+ is also useful for listing the existing roles.
+ </p><p>
+ In order to bootstrap the database system, a freshly initialized
+ system always contains one predefined role. This role is always
+ a <span class="quote">“<span class="quote">superuser</span>”</span>, and by default (unless altered when running
+ <code class="command">initdb</code>) it will have the same name as the
+ operating system user that initialized the database
+ cluster. Customarily, this role will be named
+ <code class="literal">postgres</code>. In order to create more roles you
+ first have to connect as this initial role.
+ </p><p>
+ Every connection to the database server is made using the name of some
+ particular role, and this role determines the initial access privileges for
+ commands issued in that connection.
+ The role name to use for a particular database
+ connection is indicated by the client that is initiating the
+ connection request in an application-specific fashion. For example,
+ the <code class="command">psql</code> program uses the
+ <code class="option">-U</code> command line option to indicate the role to
+ connect as. Many applications assume the name of the current
+ operating system user by default (including
+ <code class="command">createuser</code> and <code class="command">psql</code>). Therefore it
+ is often convenient to maintain a naming correspondence between
+ roles and operating system users.
+ </p><p>
+ The set of database roles a given client connection can connect as
+ is determined by the client authentication setup, as explained in
+ <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a>. (Thus, a client is not
+ limited to connect as the role matching
+ its operating system user, just as a person's login name
+ need not match his or her real name.) Since the role
+ identity determines the set of privileges available to a connected
+ client, it is important to carefully configure privileges when setting up
+ a multiuser environment.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="user-manag.html" title="Chapter 22. Database Roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="role-attributes.html" title="22.2. Role Attributes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 22. Database Roles </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 22.2. Role Attributes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-binary.html b/doc/src/sgml/html/datatype-binary.html
new file mode 100644
index 0000000..90d4946
--- /dev/null
+++ b/doc/src/sgml/html/datatype-binary.html
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.4. Binary Data Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-character.html" title="8.3. Character Types" /><link rel="next" href="datatype-datetime.html" title="8.5. Date/Time Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.4. Binary Data Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-character.html" title="8.3. Character Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-datetime.html" title="8.5. Date/Time Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-BINARY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.4. Binary Data Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-binary.html#id-1.5.7.12.9">8.4.1. <code class="type">bytea</code> Hex Format</a></span></dt><dt><span class="sect2"><a href="datatype-binary.html#id-1.5.7.12.10">8.4.2. <code class="type">bytea</code> Escape Format</a></span></dt></dl></div><a id="id-1.5.7.12.2" class="indexterm"></a><a id="id-1.5.7.12.3" class="indexterm"></a><p>
+ The <code class="type">bytea</code> data type allows storage of binary strings;
+ see <a class="xref" href="datatype-binary.html#DATATYPE-BINARY-TABLE" title="Table 8.6. Binary Data Types">Table 8.6</a>.
+ </p><div class="table" id="DATATYPE-BINARY-TABLE"><p class="title"><strong>Table 8.6. Binary Data Types</strong></p><div class="table-contents"><table class="table" summary="Binary Data Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">bytea</code></td><td>1 or 4 bytes plus the actual binary string</td><td>variable-length binary string</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ A binary string is a sequence of octets (or bytes). Binary
+ strings are distinguished from character strings in two
+ ways. First, binary strings specifically allow storing
+ octets of value zero and other <span class="quote">“<span class="quote">non-printable</span>”</span>
+ octets (usually, octets outside the decimal range 32 to 126).
+ Character strings disallow zero octets, and also disallow any
+ other octet values and sequences of octet values that are invalid
+ according to the database's selected character set encoding.
+ Second, operations on binary strings process the actual bytes,
+ whereas the processing of character strings depends on locale settings.
+ In short, binary strings are appropriate for storing data that the
+ programmer thinks of as <span class="quote">“<span class="quote">raw bytes</span>”</span>, whereas character
+ strings are appropriate for storing text.
+ </p><p>
+ The <code class="type">bytea</code> type supports two
+ formats for input and output: <span class="quote">“<span class="quote">hex</span>”</span> format
+ and <span class="productname">PostgreSQL</span>'s historical
+ <span class="quote">“<span class="quote">escape</span>”</span> format. Both
+ of these are always accepted on input. The output format depends
+ on the configuration parameter <a class="xref" href="runtime-config-client.html#GUC-BYTEA-OUTPUT">bytea_output</a>;
+ the default is hex. (Note that the hex format was introduced in
+ <span class="productname">PostgreSQL</span> 9.0; earlier versions and some
+ tools don't understand it.)
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> standard defines a different binary
+ string type, called <code class="type">BLOB</code> or <code class="type">BINARY LARGE
+ OBJECT</code>. The input format is different from
+ <code class="type">bytea</code>, but the provided functions and operators are
+ mostly the same.
+ </p><div class="sect2" id="id-1.5.7.12.9"><div class="titlepage"><div><div><h3 class="title">8.4.1. <code class="type">bytea</code> Hex Format</h3></div></div></div><p>
+ The <span class="quote">“<span class="quote">hex</span>”</span> format encodes binary data as 2 hexadecimal digits
+ per byte, most significant nibble first. The entire string is
+ preceded by the sequence <code class="literal">\x</code> (to distinguish it
+ from the escape format). In some contexts, the initial backslash may
+ need to be escaped by doubling it
+ (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a>).
+ For input, the hexadecimal digits can
+ be either upper or lower case, and whitespace is permitted between
+ digit pairs (but not within a digit pair nor in the starting
+ <code class="literal">\x</code> sequence).
+ The hex format is compatible with a wide
+ range of external applications and protocols, and it tends to be
+ faster to convert than the escape format, so its use is preferred.
+ </p><p>
+ Example:
+</p><pre class="programlisting">
+SET bytea_output = 'hex';
+
+SELECT '\xDEADBEEF'::bytea;
+ bytea
+------------
+ \xdeadbeef
+</pre><p>
+ </p></div><div class="sect2" id="id-1.5.7.12.10"><div class="titlepage"><div><div><h3 class="title">8.4.2. <code class="type">bytea</code> Escape Format</h3></div></div></div><p>
+ The <span class="quote">“<span class="quote">escape</span>”</span> format is the traditional
+ <span class="productname">PostgreSQL</span> format for the <code class="type">bytea</code>
+ type. It
+ takes the approach of representing a binary string as a sequence
+ of ASCII characters, while converting those bytes that cannot be
+ represented as an ASCII character into special escape sequences.
+ If, from the point of view of the application, representing bytes
+ as characters makes sense, then this representation can be
+ convenient. But in practice it is usually confusing because it
+ fuzzes up the distinction between binary strings and character
+ strings, and also the particular escape mechanism that was chosen is
+ somewhat unwieldy. Therefore, this format should probably be avoided
+ for most new applications.
+ </p><p>
+ When entering <code class="type">bytea</code> values in escape format,
+ octets of certain
+ values <span class="emphasis"><em>must</em></span> be escaped, while all octet
+ values <span class="emphasis"><em>can</em></span> be escaped. In
+ general, to escape an octet, convert it into its three-digit
+ octal value and precede it by a backslash.
+ Backslash itself (octet decimal value 92) can alternatively be represented by
+ double backslashes.
+ <a class="xref" href="datatype-binary.html#DATATYPE-BINARY-SQLESC" title="Table 8.7. bytea Literal Escaped Octets">Table 8.7</a>
+ shows the characters that must be escaped, and gives the alternative
+ escape sequences where applicable.
+ </p><div class="table" id="DATATYPE-BINARY-SQLESC"><p class="title"><strong>Table 8.7. <code class="type">bytea</code> Literal Escaped Octets</strong></p><div class="table-contents"><table class="table" summary="bytea Literal Escaped Octets" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /></colgroup><thead><tr><th>Decimal Octet Value</th><th>Description</th><th>Escaped Input Representation</th><th>Example</th><th>Hex Representation</th></tr></thead><tbody><tr><td>0</td><td>zero octet</td><td><code class="literal">'\000'</code></td><td><code class="literal">'\000'::bytea</code></td><td><code class="literal">\x00</code></td></tr><tr><td>39</td><td>single quote</td><td><code class="literal">''''</code> or <code class="literal">'\047'</code></td><td><code class="literal">''''::bytea</code></td><td><code class="literal">\x27</code></td></tr><tr><td>92</td><td>backslash</td><td><code class="literal">'\\'</code> or <code class="literal">'\134'</code></td><td><code class="literal">'\\'::bytea</code></td><td><code class="literal">\x5c</code></td></tr><tr><td>0 to 31 and 127 to 255</td><td><span class="quote">“<span class="quote">non-printable</span>”</span> octets</td><td><code class="literal">'\<em class="replaceable"><code>xxx'</code></em></code> (octal value)</td><td><code class="literal">'\001'::bytea</code></td><td><code class="literal">\x01</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The requirement to escape <span class="emphasis"><em>non-printable</em></span> octets
+ varies depending on locale settings. In some instances you can get away
+ with leaving them unescaped.
+ </p><p>
+ The reason that single quotes must be doubled, as shown
+ in <a class="xref" href="datatype-binary.html#DATATYPE-BINARY-SQLESC" title="Table 8.7. bytea Literal Escaped Octets">Table 8.7</a>, is that this
+ is true for any string literal in an SQL command. The generic
+ string-literal parser consumes the outermost single quotes
+ and reduces any pair of single quotes to one data character.
+ What the <code class="type">bytea</code> input function sees is just one
+ single quote, which it treats as a plain data character.
+ However, the <code class="type">bytea</code> input function treats
+ backslashes as special, and the other behaviors shown in
+ <a class="xref" href="datatype-binary.html#DATATYPE-BINARY-SQLESC" title="Table 8.7. bytea Literal Escaped Octets">Table 8.7</a> are implemented by
+ that function.
+ </p><p>
+ In some contexts, backslashes must be doubled compared to what is
+ shown above, because the generic string-literal parser will also
+ reduce pairs of backslashes to one data character;
+ see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a>.
+ </p><p>
+ <code class="type">Bytea</code> octets are output in <code class="literal">hex</code>
+ format by default. If you change <a class="xref" href="runtime-config-client.html#GUC-BYTEA-OUTPUT">bytea_output</a>
+ to <code class="literal">escape</code>,
+ <span class="quote">“<span class="quote">non-printable</span>”</span> octets are converted to their
+ equivalent three-digit octal value and preceded by one backslash.
+ Most <span class="quote">“<span class="quote">printable</span>”</span> octets are output by their standard
+ representation in the client character set, e.g.:
+
+</p><pre class="programlisting">
+SET bytea_output = 'escape';
+
+SELECT 'abc \153\154\155 \052\251\124'::bytea;
+ bytea
+----------------
+ abc klm *\251T
+</pre><p>
+
+ The octet with decimal value 92 (backslash) is doubled in the output.
+ Details are in <a class="xref" href="datatype-binary.html#DATATYPE-BINARY-RESESC" title="Table 8.8. bytea Output Escaped Octets">Table 8.8</a>.
+ </p><div class="table" id="DATATYPE-BINARY-RESESC"><p class="title"><strong>Table 8.8. <code class="type">bytea</code> Output Escaped Octets</strong></p><div class="table-contents"><table class="table" summary="bytea Output Escaped Octets" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /></colgroup><thead><tr><th>Decimal Octet Value</th><th>Description</th><th>Escaped Output Representation</th><th>Example</th><th>Output Result</th></tr></thead><tbody><tr><td>92</td><td>backslash</td><td><code class="literal">\\</code></td><td><code class="literal">'\134'::bytea</code></td><td><code class="literal">\\</code></td></tr><tr><td>0 to 31 and 127 to 255</td><td><span class="quote">“<span class="quote">non-printable</span>”</span> octets</td><td><code class="literal">\<em class="replaceable"><code>xxx</code></em></code> (octal value)</td><td><code class="literal">'\001'::bytea</code></td><td><code class="literal">\001</code></td></tr><tr><td>32 to 126</td><td><span class="quote">“<span class="quote">printable</span>”</span> octets</td><td>client character set representation</td><td><code class="literal">'\176'::bytea</code></td><td><code class="literal">~</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Depending on the front end to <span class="productname">PostgreSQL</span> you use,
+ you might have additional work to do in terms of escaping and
+ unescaping <code class="type">bytea</code> strings. For example, you might also
+ have to escape line feeds and carriage returns if your interface
+ automatically translates these.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-character.html" title="8.3. Character Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-datetime.html" title="8.5. Date/Time Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.3. Character Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.5. Date/Time Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-bit.html b/doc/src/sgml/html/datatype-bit.html
new file mode 100644
index 0000000..339eafd
--- /dev/null
+++ b/doc/src/sgml/html/datatype-bit.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.10. Bit String Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-net-types.html" title="8.9. Network Address Types" /><link rel="next" href="datatype-textsearch.html" title="8.11. Text Search Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.10. Bit String Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-net-types.html" title="8.9. Network Address Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-textsearch.html" title="8.11. Text Search Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-BIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.10. Bit String Types</h2></div></div></div><a id="id-1.5.7.18.2" class="indexterm"></a><p>
+ Bit strings are strings of 1's and 0's. They can be used to store
+ or visualize bit masks. There are two SQL bit types:
+ <code class="type">bit(<em class="replaceable"><code>n</code></em>)</code> and <code class="type">bit
+ varying(<em class="replaceable"><code>n</code></em>)</code>, where
+ <em class="replaceable"><code>n</code></em> is a positive integer.
+ </p><p>
+ <code class="type">bit</code> type data must match the length
+ <em class="replaceable"><code>n</code></em> exactly; it is an error to attempt to
+ store shorter or longer bit strings. <code class="type">bit varying</code> data is
+ of variable length up to the maximum length
+ <em class="replaceable"><code>n</code></em>; longer strings will be rejected.
+ Writing <code class="type">bit</code> without a length is equivalent to
+ <code class="literal">bit(1)</code>, while <code class="type">bit varying</code> without a length
+ specification means unlimited length.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If one explicitly casts a bit-string value to
+ <code class="type">bit(<em class="replaceable"><code>n</code></em>)</code>, it will be truncated or
+ zero-padded on the right to be exactly <em class="replaceable"><code>n</code></em> bits,
+ without raising an error. Similarly,
+ if one explicitly casts a bit-string value to
+ <code class="type">bit varying(<em class="replaceable"><code>n</code></em>)</code>, it will be truncated
+ on the right if it is more than <em class="replaceable"><code>n</code></em> bits.
+ </p></div><p>
+ Refer to <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-BIT-STRINGS" title="4.1.2.5. Bit-String Constants">Section 4.1.2.5</a> for information about the syntax
+ of bit string constants. Bit-logical operators and string
+ manipulation functions are available; see <a class="xref" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators">Section 9.6</a>.
+ </p><div class="example" id="id-1.5.7.18.7"><p class="title"><strong>Example 8.3. Using the Bit String Types</strong></p><div class="example-contents"><pre class="programlisting">
+CREATE TABLE test (a BIT(3), b BIT VARYING(5));
+INSERT INTO test VALUES (B'101', B'00');
+INSERT INTO test VALUES (B'10', B'101');
+<code class="computeroutput">
+ERROR: bit string length 2 does not match type bit(3)
+</code>
+INSERT INTO test VALUES (B'10'::bit(3), B'101');
+SELECT * FROM test;
+<code class="computeroutput">
+ a | b
+-----+-----
+ 101 | 00
+ 100 | 101
+</code>
+</pre></div></div><br class="example-break" /><p>
+ A bit string value requires 1 byte for each group of 8 bits, plus
+ 5 or 8 bytes overhead depending on the length of the string
+ (but long values may be compressed or moved out-of-line, as explained
+ in <a class="xref" href="datatype-character.html" title="8.3. Character Types">Section 8.3</a> for character strings).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-net-types.html" title="8.9. Network Address Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-textsearch.html" title="8.11. Text Search Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.9. Network Address Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.11. Text Search Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-boolean.html b/doc/src/sgml/html/datatype-boolean.html
new file mode 100644
index 0000000..845d92a
--- /dev/null
+++ b/doc/src/sgml/html/datatype-boolean.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.6. Boolean Type</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-datetime.html" title="8.5. Date/Time Types" /><link rel="next" href="datatype-enum.html" title="8.7. Enumerated Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.6. Boolean Type</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-datetime.html" title="8.5. Date/Time Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-enum.html" title="8.7. Enumerated Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-BOOLEAN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.6. Boolean Type</h2></div></div></div><a id="id-1.5.7.14.2" class="indexterm"></a><a id="id-1.5.7.14.3" class="indexterm"></a><a id="id-1.5.7.14.4" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides the
+ standard <acronym class="acronym">SQL</acronym> type <code class="type">boolean</code>;
+ see <a class="xref" href="datatype-boolean.html#DATATYPE-BOOLEAN-TABLE" title="Table 8.19. Boolean Data Type">Table 8.19</a>.
+ The <code class="type">boolean</code> type can have several states:
+ <span class="quote">“<span class="quote">true</span>”</span>, <span class="quote">“<span class="quote">false</span>”</span>, and a third state,
+ <span class="quote">“<span class="quote">unknown</span>”</span>, which is represented by the
+ <acronym class="acronym">SQL</acronym> null value.
+ </p><div class="table" id="DATATYPE-BOOLEAN-TABLE"><p class="title"><strong>Table 8.19. Boolean Data Type</strong></p><div class="table-contents"><table class="table" summary="Boolean Data Type" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">boolean</code></td><td>1 byte</td><td>state of true or false</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Boolean constants can be represented in SQL queries by the SQL
+ key words <code class="literal">TRUE</code>, <code class="literal">FALSE</code>,
+ and <code class="literal">NULL</code>.
+ </p><p>
+ The datatype input function for type <code class="type">boolean</code> accepts these
+ string representations for the <span class="quote">“<span class="quote">true</span>”</span> state:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">true</code></td></tr><tr><td><code class="literal">yes</code></td></tr><tr><td><code class="literal">on</code></td></tr><tr><td><code class="literal">1</code></td></tr></table><p>
+ and these representations for the <span class="quote">“<span class="quote">false</span>”</span> state:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">false</code></td></tr><tr><td><code class="literal">no</code></td></tr><tr><td><code class="literal">off</code></td></tr><tr><td><code class="literal">0</code></td></tr></table><p>
+ Unique prefixes of these strings are also accepted, for
+ example <code class="literal">t</code> or <code class="literal">n</code>.
+ Leading or trailing whitespace is ignored, and case does not matter.
+ </p><p>
+ The datatype output function for type <code class="type">boolean</code> always emits
+ either <code class="literal">t</code> or <code class="literal">f</code>, as shown in
+ <a class="xref" href="datatype-boolean.html#DATATYPE-BOOLEAN-EXAMPLE" title="Example 8.2. Using the boolean Type">Example 8.2</a>.
+ </p><div class="example" id="DATATYPE-BOOLEAN-EXAMPLE"><p class="title"><strong>Example 8.2. Using the <code class="type">boolean</code> Type</strong></p><div class="example-contents"><pre class="programlisting">
+CREATE TABLE test1 (a boolean, b text);
+INSERT INTO test1 VALUES (TRUE, 'sic est');
+INSERT INTO test1 VALUES (FALSE, 'non est');
+SELECT * FROM test1;
+ a | b
+---+---------
+ t | sic est
+ f | non est
+
+SELECT * FROM test1 WHERE a;
+ a | b
+---+---------
+ t | sic est
+</pre></div></div><br class="example-break" /><p>
+ The key words <code class="literal">TRUE</code> and <code class="literal">FALSE</code> are
+ the preferred (<acronym class="acronym">SQL</acronym>-compliant) method for writing
+ Boolean constants in SQL queries. But you can also use the string
+ representations by following the generic string-literal constant syntax
+ described in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC" title="4.1.2.7. Constants of Other Types">Section 4.1.2.7</a>, for
+ example <code class="literal">'yes'::boolean</code>.
+ </p><p>
+ Note that the parser automatically understands
+ that <code class="literal">TRUE</code> and <code class="literal">FALSE</code> are of
+ type <code class="type">boolean</code>, but this is not so
+ for <code class="literal">NULL</code> because that can have any type.
+ So in some contexts you might have to cast <code class="literal">NULL</code>
+ to <code class="type">boolean</code> explicitly, for
+ example <code class="literal">NULL::boolean</code>. Conversely, the cast can be
+ omitted from a string-literal Boolean value in contexts where the parser
+ can deduce that the literal must be of type <code class="type">boolean</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-datetime.html" title="8.5. Date/Time Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-enum.html" title="8.7. Enumerated Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.5. Date/Time Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.7. Enumerated Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-character.html b/doc/src/sgml/html/datatype-character.html
new file mode 100644
index 0000000..4be4502
--- /dev/null
+++ b/doc/src/sgml/html/datatype-character.html
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.3. Character Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-money.html" title="8.2. Monetary Types" /><link rel="next" href="datatype-binary.html" title="8.4. Binary Data Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.3. Character Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-money.html" title="8.2. Monetary Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-binary.html" title="8.4. Binary Data Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-CHARACTER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.3. Character Types</h2></div></div></div><a id="id-1.5.7.11.2" class="indexterm"></a><a id="id-1.5.7.11.3" class="indexterm"></a><a id="id-1.5.7.11.4" class="indexterm"></a><a id="id-1.5.7.11.5" class="indexterm"></a><a id="id-1.5.7.11.6" class="indexterm"></a><a id="id-1.5.7.11.7" class="indexterm"></a><a id="id-1.5.7.11.8" class="indexterm"></a><div class="table" id="DATATYPE-CHARACTER-TABLE"><p class="title"><strong>Table 8.4. Character Types</strong></p><div class="table-contents"><table class="table" summary="Character Types" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">character varying(<em class="replaceable"><code>n</code></em>)</code>, <code class="type">varchar(<em class="replaceable"><code>n</code></em>)</code></td><td>variable-length with limit</td></tr><tr><td><code class="type">character(<em class="replaceable"><code>n</code></em>)</code>, <code class="type">char(<em class="replaceable"><code>n</code></em>)</code></td><td>fixed-length, blank padded</td></tr><tr><td><code class="type">text</code></td><td>variable unlimited length</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="datatype-character.html#DATATYPE-CHARACTER-TABLE" title="Table 8.4. Character Types">Table 8.4</a> shows the
+ general-purpose character types available in
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ <acronym class="acronym">SQL</acronym> defines two primary character types:
+ <code class="type">character varying(<em class="replaceable"><code>n</code></em>)</code> and
+ <code class="type">character(<em class="replaceable"><code>n</code></em>)</code>, where <em class="replaceable"><code>n</code></em>
+ is a positive integer. Both of these types can store strings up to
+ <em class="replaceable"><code>n</code></em> characters (not bytes) in length. An attempt to store a
+ longer string into a column of these types will result in an
+ error, unless the excess characters are all spaces, in which case
+ the string will be truncated to the maximum length. (This somewhat
+ bizarre exception is required by the <acronym class="acronym">SQL</acronym>
+ standard.) If the string to be stored is shorter than the declared
+ length, values of type <code class="type">character</code> will be space-padded;
+ values of type <code class="type">character varying</code> will simply store the
+ shorter
+ string.
+ </p><p>
+ If one explicitly casts a value to <code class="type">character
+ varying(<em class="replaceable"><code>n</code></em>)</code> or
+ <code class="type">character(<em class="replaceable"><code>n</code></em>)</code>, then an over-length
+ value will be truncated to <em class="replaceable"><code>n</code></em> characters without
+ raising an error. (This too is required by the
+ <acronym class="acronym">SQL</acronym> standard.)
+ </p><p>
+ The notations <code class="type">varchar(<em class="replaceable"><code>n</code></em>)</code> and
+ <code class="type">char(<em class="replaceable"><code>n</code></em>)</code> are aliases for <code class="type">character
+ varying(<em class="replaceable"><code>n</code></em>)</code> and
+ <code class="type">character(<em class="replaceable"><code>n</code></em>)</code>, respectively.
+ If specified, the length must be greater than zero and cannot exceed
+ 10485760.
+ <code class="type">character</code> without length specifier is equivalent to
+ <code class="type">character(1)</code>. If <code class="type">character varying</code> is used
+ without length specifier, the type accepts strings of any size. The
+ latter is a <span class="productname">PostgreSQL</span> extension.
+ </p><p>
+ In addition, <span class="productname">PostgreSQL</span> provides the
+ <code class="type">text</code> type, which stores strings of any length.
+ Although the type <code class="type">text</code> is not in the
+ <acronym class="acronym">SQL</acronym> standard, several other SQL database
+ management systems have it as well.
+ </p><p>
+ Values of type <code class="type">character</code> are physically padded
+ with spaces to the specified width <em class="replaceable"><code>n</code></em>, and are
+ stored and displayed that way. However, trailing spaces are treated as
+ semantically insignificant and disregarded when comparing two values
+ of type <code class="type">character</code>. In collations where whitespace
+ is significant, this behavior can produce unexpected results;
+ for example <code class="command">SELECT 'a '::CHAR(2) collate "C" &lt;
+ E'a\n'::CHAR(2)</code> returns true, even though <code class="literal">C</code>
+ locale would consider a space to be greater than a newline.
+ Trailing spaces are removed when converting a <code class="type">character</code> value
+ to one of the other string types. Note that trailing spaces
+ <span class="emphasis"><em>are</em></span> semantically significant in
+ <code class="type">character varying</code> and <code class="type">text</code> values, and
+ when using pattern matching, that is <code class="literal">LIKE</code> and
+ regular expressions.
+ </p><p>
+ The characters that can be stored in any of these data types are
+ determined by the database character set, which is selected when
+ the database is created. Regardless of the specific character set,
+ the character with code zero (sometimes called NUL) cannot be stored.
+ For more information refer to <a class="xref" href="multibyte.html" title="24.3. Character Set Support">Section 24.3</a>.
+ </p><p>
+ The storage requirement for a short string (up to 126 bytes) is 1 byte
+ plus the actual string, which includes the space padding in the case of
+ <code class="type">character</code>. Longer strings have 4 bytes of overhead instead
+ of 1. Long strings are compressed by the system automatically, so
+ the physical requirement on disk might be less. Very long values are also
+ stored in background tables so that they do not interfere with rapid
+ access to shorter column values. In any case, the longest
+ possible character string that can be stored is about 1 GB. (The
+ maximum value that will be allowed for <em class="replaceable"><code>n</code></em> in the data
+ type declaration is less than that. It wouldn't be useful to
+ change this because with multibyte character encodings the number of
+ characters and bytes can be quite different. If you desire to
+ store long strings with no specific upper limit, use
+ <code class="type">text</code> or <code class="type">character varying</code> without a length
+ specifier, rather than making up an arbitrary length limit.)
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ There is no performance difference among these three types,
+ apart from increased storage space when using the blank-padded
+ type, and a few extra CPU cycles to check the length when storing into
+ a length-constrained column. While
+ <code class="type">character(<em class="replaceable"><code>n</code></em>)</code> has performance
+ advantages in some other database systems, there is no such advantage in
+ <span class="productname">PostgreSQL</span>; in fact
+ <code class="type">character(<em class="replaceable"><code>n</code></em>)</code> is usually the slowest of
+ the three because of its additional storage costs. In most situations
+ <code class="type">text</code> or <code class="type">character varying</code> should be used
+ instead.
+ </p></div><p>
+ Refer to <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a> for information about
+ the syntax of string literals, and to <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a>
+ for information about available operators and functions.
+ </p><div class="example" id="id-1.5.7.11.20"><p class="title"><strong>Example 8.1. Using the Character Types</strong></p><div class="example-contents"><pre class="programlisting">
+CREATE TABLE test1 (a character(4));
+INSERT INTO test1 VALUES ('ok');
+SELECT a, char_length(a) FROM test1; -- <span id="co.datatype-char"></span>(1)
+<code class="computeroutput">
+ a | char_length
+------+-------------
+ ok | 2
+</code>
+
+CREATE TABLE test2 (b varchar(5));
+INSERT INTO test2 VALUES ('ok');
+INSERT INTO test2 VALUES ('good ');
+INSERT INTO test2 VALUES ('too long');
+<code class="computeroutput">ERROR: value too long for type character varying(5)</code>
+INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation
+SELECT b, char_length(b) FROM test2;
+<code class="computeroutput">
+ b | char_length
+-------+-------------
+ ok | 2
+ good | 5
+ too l | 5
+</code>
+</pre><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><p><a href="#co.datatype-char">(1)</a> </p></td><td valign="top" align="left"><p>
+ The <code class="function">char_length</code> function is discussed in
+ <a class="xref" href="functions-string.html" title="9.4. String Functions and Operators">Section 9.4</a>.
+ </p></td></tr></table></div></div></div><br class="example-break" /><p>
+ There are two other fixed-length character types in
+ <span class="productname">PostgreSQL</span>, shown in <a class="xref" href="datatype-character.html#DATATYPE-CHARACTER-SPECIAL-TABLE" title="Table 8.5. Special Character Types">Table 8.5</a>.
+ These are not intended for general-purpose use, only for use
+ in the internal system catalogs.
+ The <code class="type">name</code> type is used to store identifiers. Its
+ length is currently defined as 64 bytes (63 usable characters plus
+ terminator) but should be referenced using the constant
+ <code class="symbol">NAMEDATALEN</code> in <code class="literal">C</code> source code.
+ The length is set at compile time (and
+ is therefore adjustable for special uses); the default maximum
+ length might change in a future release. The type <code class="type">"char"</code>
+ (note the quotes) is different from <code class="type">char(1)</code> in that it
+ only uses one byte of storage, and therefore can store only a single
+ ASCII character. It is used in the system
+ catalogs as a simplistic enumeration type.
+ </p><div class="table" id="DATATYPE-CHARACTER-SPECIAL-TABLE"><p class="title"><strong>Table 8.5. Special Character Types</strong></p><div class="table-contents"><table class="table" summary="Special Character Types" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">"char"</code></td><td>1 byte</td><td>single-byte internal type</td></tr><tr><td><code class="type">name</code></td><td>64 bytes</td><td>internal type for object names</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-money.html" title="8.2. Monetary Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-binary.html" title="8.4. Binary Data Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.2. Monetary Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.4. Binary Data Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-datetime.html b/doc/src/sgml/html/datatype-datetime.html
new file mode 100644
index 0000000..e78783c
--- /dev/null
+++ b/doc/src/sgml/html/datatype-datetime.html
@@ -0,0 +1,549 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.5. Date/Time Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-binary.html" title="8.4. Binary Data Types" /><link rel="next" href="datatype-boolean.html" title="8.6. Boolean Type" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.5. Date/Time Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-binary.html" title="8.4. Binary Data Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-boolean.html" title="8.6. Boolean Type">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-DATETIME"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.5. Date/Time Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-DATETIME-INPUT">8.5.1. Date/Time Input</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-DATETIME-OUTPUT">8.5.2. Date/Time Output</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-TIMEZONES">8.5.3. Time Zones</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-INTERVAL-INPUT">8.5.4. Interval Input</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-INTERVAL-OUTPUT">8.5.5. Interval Output</a></span></dt></dl></div><a id="id-1.5.7.13.2" class="indexterm"></a><a id="id-1.5.7.13.3" class="indexterm"></a><a id="id-1.5.7.13.4" class="indexterm"></a><a id="id-1.5.7.13.5" class="indexterm"></a><a id="id-1.5.7.13.6" class="indexterm"></a><a id="id-1.5.7.13.7" class="indexterm"></a><a id="id-1.5.7.13.8" class="indexterm"></a><a id="id-1.5.7.13.9" class="indexterm"></a><a id="id-1.5.7.13.10" class="indexterm"></a><a id="id-1.5.7.13.11" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> supports the full set of
+ <acronym class="acronym">SQL</acronym> date and time types, shown in <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-TABLE" title="Table 8.9. Date/Time Types">Table 8.9</a>. The operations available
+ on these data types are described in
+ <a class="xref" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators">Section 9.9</a>.
+ Dates are counted according to the Gregorian calendar, even in
+ years before that calendar was introduced (see <a class="xref" href="datetime-units-history.html" title="B.6. History of Units">Section B.6</a> for more information).
+ </p><div class="table" id="DATATYPE-DATETIME-TABLE"><p class="title"><strong>Table 8.9. Date/Time Types</strong></p><div class="table-contents"><table class="table" summary="Date/Time Types" border="1"><colgroup><col /><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th><th>Low Value</th><th>High Value</th><th>Resolution</th></tr></thead><tbody><tr><td><code class="type">timestamp [ (<em class="replaceable"><code>p</code></em>) ] [ without time zone ]</code></td><td>8 bytes</td><td>both date and time (no time zone)</td><td>4713 BC</td><td>294276 AD</td><td>1 microsecond</td></tr><tr><td><code class="type">timestamp [ (<em class="replaceable"><code>p</code></em>) ] with time zone</code></td><td>8 bytes</td><td>both date and time, with time zone</td><td>4713 BC</td><td>294276 AD</td><td>1 microsecond</td></tr><tr><td><code class="type">date</code></td><td>4 bytes</td><td>date (no time of day)</td><td>4713 BC</td><td>5874897 AD</td><td>1 day</td></tr><tr><td><code class="type">time [ (<em class="replaceable"><code>p</code></em>) ] [ without time zone ]</code></td><td>8 bytes</td><td>time of day (no date)</td><td>00:00:00</td><td>24:00:00</td><td>1 microsecond</td></tr><tr><td><code class="type">time [ (<em class="replaceable"><code>p</code></em>) ] with time zone</code></td><td>12 bytes</td><td>time of day (no date), with time zone</td><td>00:00:00+1559</td><td>24:00:00-1559</td><td>1 microsecond</td></tr><tr><td><code class="type">interval [ <em class="replaceable"><code>fields</code></em> ] [ (<em class="replaceable"><code>p</code></em>) ]</code></td><td>16 bytes</td><td>time interval</td><td>-178000000 years</td><td>178000000 years</td><td>1 microsecond</td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The SQL standard requires that writing just <code class="type">timestamp</code>
+ be equivalent to <code class="type">timestamp without time
+ zone</code>, and <span class="productname">PostgreSQL</span> honors that
+ behavior. <code class="type">timestamptz</code> is accepted as an
+ abbreviation for <code class="type">timestamp with time zone</code>; this is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><p>
+ <code class="type">time</code>, <code class="type">timestamp</code>, and
+ <code class="type">interval</code> accept an optional precision value
+ <em class="replaceable"><code>p</code></em> which specifies the number of
+ fractional digits retained in the seconds field. By default, there
+ is no explicit bound on precision. The allowed range of
+ <em class="replaceable"><code>p</code></em> is from 0 to 6.
+ </p><p>
+ The <code class="type">interval</code> type has an additional option, which is
+ to restrict the set of stored fields by writing one of these phrases:
+</p><pre class="literallayout">
+YEAR
+MONTH
+DAY
+HOUR
+MINUTE
+SECOND
+YEAR TO MONTH
+DAY TO HOUR
+DAY TO MINUTE
+DAY TO SECOND
+HOUR TO MINUTE
+HOUR TO SECOND
+MINUTE TO SECOND
+</pre><p>
+ Note that if both <em class="replaceable"><code>fields</code></em> and
+ <em class="replaceable"><code>p</code></em> are specified, the
+ <em class="replaceable"><code>fields</code></em> must include <code class="literal">SECOND</code>,
+ since the precision applies only to the seconds.
+ </p><p>
+ The type <code class="type">time with time zone</code> is defined by the SQL
+ standard, but the definition exhibits properties which lead to
+ questionable usefulness. In most cases, a combination of
+ <code class="type">date</code>, <code class="type">time</code>, <code class="type">timestamp without time
+ zone</code>, and <code class="type">timestamp with time zone</code> should
+ provide a complete range of date/time functionality required by
+ any application.
+ </p><div class="sect2" id="DATATYPE-DATETIME-INPUT"><div class="titlepage"><div><div><h3 class="title">8.5.1. Date/Time Input</h3></div></div></div><p>
+ Date and time input is accepted in almost any reasonable format, including
+ ISO 8601, <acronym class="acronym">SQL</acronym>-compatible,
+ traditional <span class="productname">POSTGRES</span>, and others.
+ For some formats, ordering of day, month, and year in date input is
+ ambiguous and there is support for specifying the expected
+ ordering of these fields. Set the <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a> parameter
+ to <code class="literal">MDY</code> to select month-day-year interpretation,
+ <code class="literal">DMY</code> to select day-month-year interpretation, or
+ <code class="literal">YMD</code> to select year-month-day interpretation.
+ </p><p>
+ <span class="productname">PostgreSQL</span> is more flexible in
+ handling date/time input than the
+ <acronym class="acronym">SQL</acronym> standard requires.
+ See <a class="xref" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Appendix B</a>
+ for the exact parsing rules of date/time input and for the
+ recognized text fields including months, days of the week, and
+ time zones.
+ </p><p>
+ Remember that any date or time literal input needs to be enclosed
+ in single quotes, like text strings. Refer to
+ <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC" title="4.1.2.7. Constants of Other Types">Section 4.1.2.7</a> for more
+ information.
+ <acronym class="acronym">SQL</acronym> requires the following syntax
+</p><pre class="synopsis">
+<em class="replaceable"><code>type</code></em> [ (<em class="replaceable"><code>p</code></em>) ] '<em class="replaceable"><code>value</code></em>'
+</pre><p>
+ where <em class="replaceable"><code>p</code></em> is an optional precision
+ specification giving the number of
+ fractional digits in the seconds field. Precision can be
+ specified for <code class="type">time</code>, <code class="type">timestamp</code>, and
+ <code class="type">interval</code> types, and can range from 0 to 6.
+ If no precision is specified in a constant specification,
+ it defaults to the precision of the literal value (but not
+ more than 6 digits).
+ </p><div class="sect3" id="id-1.5.7.13.18.5"><div class="titlepage"><div><div><h4 class="title">8.5.1.1. Dates</h4></div></div></div><a id="id-1.5.7.13.18.5.2" class="indexterm"></a><p>
+ <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-DATE-TABLE" title="Table 8.10. Date Input">Table 8.10</a> shows some possible
+ inputs for the <code class="type">date</code> type.
+ </p><div class="table" id="DATATYPE-DATETIME-DATE-TABLE"><p class="title"><strong>Table 8.10. Date Input</strong></p><div class="table-contents"><table class="table" summary="Date Input" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Example</th><th>Description</th></tr></thead><tbody><tr><td>1999-01-08</td><td>ISO 8601; January 8 in any mode
+ (recommended format)</td></tr><tr><td>January 8, 1999</td><td>unambiguous in any <code class="varname">datestyle</code> input mode</td></tr><tr><td>1/8/1999</td><td>January 8 in <code class="literal">MDY</code> mode;
+ August 1 in <code class="literal">DMY</code> mode</td></tr><tr><td>1/18/1999</td><td>January 18 in <code class="literal">MDY</code> mode;
+ rejected in other modes</td></tr><tr><td>01/02/03</td><td>January 2, 2003 in <code class="literal">MDY</code> mode;
+ February 1, 2003 in <code class="literal">DMY</code> mode;
+ February 3, 2001 in <code class="literal">YMD</code> mode
+ </td></tr><tr><td>1999-Jan-08</td><td>January 8 in any mode</td></tr><tr><td>Jan-08-1999</td><td>January 8 in any mode</td></tr><tr><td>08-Jan-1999</td><td>January 8 in any mode</td></tr><tr><td>99-Jan-08</td><td>January 8 in <code class="literal">YMD</code> mode, else error</td></tr><tr><td>08-Jan-99</td><td>January 8, except error in <code class="literal">YMD</code> mode</td></tr><tr><td>Jan-08-99</td><td>January 8, except error in <code class="literal">YMD</code> mode</td></tr><tr><td>19990108</td><td>ISO 8601; January 8, 1999 in any mode</td></tr><tr><td>990108</td><td>ISO 8601; January 8, 1999 in any mode</td></tr><tr><td>1999.008</td><td>year and day of year</td></tr><tr><td>J2451187</td><td>Julian date</td></tr><tr><td>January 8, 99 BC</td><td>year 99 BC</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect3" id="id-1.5.7.13.18.6"><div class="titlepage"><div><div><h4 class="title">8.5.1.2. Times</h4></div></div></div><a id="id-1.5.7.13.18.6.2" class="indexterm"></a><a id="id-1.5.7.13.18.6.3" class="indexterm"></a><a id="id-1.5.7.13.18.6.4" class="indexterm"></a><p>
+ The time-of-day types are <code class="type">time [
+ (<em class="replaceable"><code>p</code></em>) ] without time zone</code> and
+ <code class="type">time [ (<em class="replaceable"><code>p</code></em>) ] with time
+ zone</code>. <code class="type">time</code> alone is equivalent to
+ <code class="type">time without time zone</code>.
+ </p><p>
+ Valid input for these types consists of a time of day followed
+ by an optional time zone. (See <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-TIME-TABLE" title="Table 8.11. Time Input">Table 8.11</a>
+ and <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONE-TABLE" title="Table 8.12. Time Zone Input">Table 8.12</a>.) If a time zone is
+ specified in the input for <code class="type">time without time zone</code>,
+ it is silently ignored. You can also specify a date but it will
+ be ignored, except when you use a time zone name that involves a
+ daylight-savings rule, such as
+ <code class="literal">America/New_York</code>. In this case specifying the date
+ is required in order to determine whether standard or daylight-savings
+ time applies. The appropriate time zone offset is recorded in the
+ <code class="type">time with time zone</code> value.
+ </p><div class="table" id="DATATYPE-DATETIME-TIME-TABLE"><p class="title"><strong>Table 8.11. Time Input</strong></p><div class="table-contents"><table class="table" summary="Time Input" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Example</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">04:05:06.789</code></td><td>ISO 8601</td></tr><tr><td><code class="literal">04:05:06</code></td><td>ISO 8601</td></tr><tr><td><code class="literal">04:05</code></td><td>ISO 8601</td></tr><tr><td><code class="literal">040506</code></td><td>ISO 8601</td></tr><tr><td><code class="literal">04:05 AM</code></td><td>same as 04:05; AM does not affect value</td></tr><tr><td><code class="literal">04:05 PM</code></td><td>same as 16:05; input hour must be &lt;= 12</td></tr><tr><td><code class="literal">04:05:06.789-8</code></td><td>ISO 8601, with time zone as UTC offset</td></tr><tr><td><code class="literal">04:05:06-08:00</code></td><td>ISO 8601, with time zone as UTC offset</td></tr><tr><td><code class="literal">04:05-08:00</code></td><td>ISO 8601, with time zone as UTC offset</td></tr><tr><td><code class="literal">040506-08</code></td><td>ISO 8601, with time zone as UTC offset</td></tr><tr><td><code class="literal">040506+0730</code></td><td>ISO 8601, with fractional-hour time zone as UTC offset</td></tr><tr><td><code class="literal">040506+07:30:00</code></td><td>UTC offset specified to seconds (not allowed in ISO 8601)</td></tr><tr><td><code class="literal">04:05:06 PST</code></td><td>time zone specified by abbreviation</td></tr><tr><td><code class="literal">2003-04-12 04:05:06 America/New_York</code></td><td>time zone specified by full name</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="DATATYPE-TIMEZONE-TABLE"><p class="title"><strong>Table 8.12. Time Zone Input</strong></p><div class="table-contents"><table class="table" summary="Time Zone Input" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Example</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">PST</code></td><td>Abbreviation (for Pacific Standard Time)</td></tr><tr><td><code class="literal">America/New_York</code></td><td>Full time zone name</td></tr><tr><td><code class="literal">PST8PDT</code></td><td>POSIX-style time zone specification</td></tr><tr><td><code class="literal">-8:00:00</code></td><td>UTC offset for PST</td></tr><tr><td><code class="literal">-8:00</code></td><td>UTC offset for PST (ISO 8601 extended format)</td></tr><tr><td><code class="literal">-800</code></td><td>UTC offset for PST (ISO 8601 basic format)</td></tr><tr><td><code class="literal">-8</code></td><td>UTC offset for PST (ISO 8601 basic format)</td></tr><tr><td><code class="literal">zulu</code></td><td>Military abbreviation for UTC</td></tr><tr><td><code class="literal">z</code></td><td>Short form of <code class="literal">zulu</code> (also in ISO 8601)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Refer to <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a> for more information on how
+ to specify time zones.
+ </p></div><div class="sect3" id="id-1.5.7.13.18.7"><div class="titlepage"><div><div><h4 class="title">8.5.1.3. Time Stamps</h4></div></div></div><a id="id-1.5.7.13.18.7.2" class="indexterm"></a><a id="id-1.5.7.13.18.7.3" class="indexterm"></a><a id="id-1.5.7.13.18.7.4" class="indexterm"></a><p>
+ Valid input for the time stamp types consists of the concatenation
+ of a date and a time, followed by an optional time zone,
+ followed by an optional <code class="literal">AD</code> or <code class="literal">BC</code>.
+ (Alternatively, <code class="literal">AD</code>/<code class="literal">BC</code> can appear
+ before the time zone, but this is not the preferred ordering.)
+ Thus:
+
+</p><pre class="programlisting">
+1999-01-08 04:05:06
+</pre><p>
+ and:
+</p><pre class="programlisting">
+1999-01-08 04:05:06 -8:00
+</pre><p>
+
+ are valid values, which follow the <acronym class="acronym">ISO</acronym> 8601
+ standard. In addition, the common format:
+</p><pre class="programlisting">
+January 8 04:05:06 1999 PST
+</pre><p>
+ is supported.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> standard differentiates
+ <code class="type">timestamp without time zone</code>
+ and <code class="type">timestamp with time zone</code> literals by the presence of a
+ <span class="quote">“<span class="quote">+</span>”</span> or <span class="quote">“<span class="quote">-</span>”</span> symbol and time zone offset after
+ the time. Hence, according to the standard,
+
+</p><pre class="programlisting">
+TIMESTAMP '2004-10-19 10:23:54'
+</pre><p>
+
+ is a <code class="type">timestamp without time zone</code>, while
+
+</p><pre class="programlisting">
+TIMESTAMP '2004-10-19 10:23:54+02'
+</pre><p>
+
+ is a <code class="type">timestamp with time zone</code>.
+ <span class="productname">PostgreSQL</span> never examines the content of a
+ literal string before determining its type, and therefore will treat
+ both of the above as <code class="type">timestamp without time zone</code>. To
+ ensure that a literal is treated as <code class="type">timestamp with time
+ zone</code>, give it the correct explicit type:
+
+</p><pre class="programlisting">
+TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'
+</pre><p>
+
+ In a literal that has been determined to be <code class="type">timestamp without time
+ zone</code>, <span class="productname">PostgreSQL</span> will silently ignore
+ any time zone indication.
+ That is, the resulting value is derived from the date/time
+ fields in the input value, and is not adjusted for time zone.
+ </p><p>
+ For <code class="type">timestamp with time zone</code>, the internally stored
+ value is always in UTC (Universal
+ Coordinated Time, traditionally known as Greenwich Mean Time,
+ <acronym class="acronym">GMT</acronym>). An input value that has an explicit
+ time zone specified is converted to UTC using the appropriate offset
+ for that time zone. If no time zone is stated in the input string,
+ then it is assumed to be in the time zone indicated by the system's
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> parameter, and is converted to UTC using the
+ offset for the <code class="varname">timezone</code> zone.
+ </p><p>
+ When a <code class="type">timestamp with time
+ zone</code> value is output, it is always converted from UTC to the
+ current <code class="varname">timezone</code> zone, and displayed as local time in that
+ zone. To see the time in another time zone, either change
+ <code class="varname">timezone</code> or use the <code class="literal">AT TIME ZONE</code> construct
+ (see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT" title="9.9.4. AT TIME ZONE">Section 9.9.4</a>).
+ </p><p>
+ Conversions between <code class="type">timestamp without time zone</code> and
+ <code class="type">timestamp with time zone</code> normally assume that the
+ <code class="type">timestamp without time zone</code> value should be taken or given
+ as <code class="varname">timezone</code> local time. A different time zone can
+ be specified for the conversion using <code class="literal">AT TIME ZONE</code>.
+ </p></div><div class="sect3" id="DATATYPE-DATETIME-SPECIAL-VALUES"><div class="titlepage"><div><div><h4 class="title">8.5.1.4. Special Values</h4></div></div></div><a id="id-1.5.7.13.18.8.2" class="indexterm"></a><a id="id-1.5.7.13.18.8.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> supports several
+ special date/time input values for convenience, as shown in <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE" title="Table 8.13. Special Date/Time Inputs">Table 8.13</a>. The values
+ <code class="literal">infinity</code> and <code class="literal">-infinity</code>
+ are specially represented inside the system and will be displayed
+ unchanged; but the others are simply notational shorthands
+ that will be converted to ordinary date/time values when read.
+ (In particular, <code class="literal">now</code> and related strings are converted
+ to a specific time value as soon as they are read.)
+ All of these values need to be enclosed in single quotes when used
+ as constants in SQL commands.
+ </p><div class="table" id="DATATYPE-DATETIME-SPECIAL-TABLE"><p class="title"><strong>Table 8.13. Special Date/Time Inputs</strong></p><div class="table-contents"><table class="table" summary="Special Date/Time Inputs" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Input String</th><th>Valid Types</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">epoch</code></td><td><code class="type">date</code>, <code class="type">timestamp</code></td><td>1970-01-01 00:00:00+00 (Unix system time zero)</td></tr><tr><td><code class="literal">infinity</code></td><td><code class="type">date</code>, <code class="type">timestamp</code></td><td>later than all other time stamps</td></tr><tr><td><code class="literal">-infinity</code></td><td><code class="type">date</code>, <code class="type">timestamp</code></td><td>earlier than all other time stamps</td></tr><tr><td><code class="literal">now</code></td><td><code class="type">date</code>, <code class="type">time</code>, <code class="type">timestamp</code></td><td>current transaction's start time</td></tr><tr><td><code class="literal">today</code></td><td><code class="type">date</code>, <code class="type">timestamp</code></td><td>midnight (<code class="literal">00:00</code>) today</td></tr><tr><td><code class="literal">tomorrow</code></td><td><code class="type">date</code>, <code class="type">timestamp</code></td><td>midnight (<code class="literal">00:00</code>) tomorrow</td></tr><tr><td><code class="literal">yesterday</code></td><td><code class="type">date</code>, <code class="type">timestamp</code></td><td>midnight (<code class="literal">00:00</code>) yesterday</td></tr><tr><td><code class="literal">allballs</code></td><td><code class="type">time</code></td><td>00:00:00.00 UTC</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The following <acronym class="acronym">SQL</acronym>-compatible functions can also
+ be used to obtain the current time value for the corresponding data
+ type:
+ <code class="literal">CURRENT_DATE</code>, <code class="literal">CURRENT_TIME</code>,
+ <code class="literal">CURRENT_TIMESTAMP</code>, <code class="literal">LOCALTIME</code>,
+ <code class="literal">LOCALTIMESTAMP</code>. (See <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>.) Note that these are
+ SQL functions and are <span class="emphasis"><em>not</em></span> recognized in data input strings.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ While the input strings <code class="literal">now</code>,
+ <code class="literal">today</code>, <code class="literal">tomorrow</code>,
+ and <code class="literal">yesterday</code> are fine to use in interactive SQL
+ commands, they can have surprising behavior when the command is
+ saved to be executed later, for example in prepared statements,
+ views, and function definitions. The string can be converted to a
+ specific time value that continues to be used long after it becomes
+ stale. Use one of the SQL functions instead in such contexts.
+ For example, <code class="literal">CURRENT_DATE + 1</code> is safer than
+ <code class="literal">'tomorrow'::date</code>.
+ </p></div></div></div><div class="sect2" id="DATATYPE-DATETIME-OUTPUT"><div class="titlepage"><div><div><h3 class="title">8.5.2. Date/Time Output</h3></div></div></div><a id="id-1.5.7.13.19.2" class="indexterm"></a><a id="id-1.5.7.13.19.3" class="indexterm"></a><p>
+ The output format of the date/time types can be set to one of the four
+ styles ISO 8601,
+ <acronym class="acronym">SQL</acronym> (Ingres), traditional <span class="productname">POSTGRES</span>
+ (Unix <span class="application">date</span> format), or
+ German. The default
+ is the <acronym class="acronym">ISO</acronym> format. (The
+ <acronym class="acronym">SQL</acronym> standard requires the use of the ISO 8601
+ format. The name of the <span class="quote">“<span class="quote">SQL</span>”</span> output format is a
+ historical accident.) <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-OUTPUT-TABLE" title="Table 8.14. Date/Time Output Styles">Table 8.14</a> shows examples of each
+ output style. The output of the <code class="type">date</code> and
+ <code class="type">time</code> types is generally only the date or time part
+ in accordance with the given examples. However, the
+ <span class="productname">POSTGRES</span> style outputs date-only values in
+ <acronym class="acronym">ISO</acronym> format.
+ </p><div class="table" id="DATATYPE-DATETIME-OUTPUT-TABLE"><p class="title"><strong>Table 8.14. Date/Time Output Styles</strong></p><div class="table-contents"><table class="table" summary="Date/Time Output Styles" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Style Specification</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><code class="literal">ISO</code></td><td>ISO 8601, SQL standard</td><td><code class="literal">1997-12-17 07:37:16-08</code></td></tr><tr><td><code class="literal">SQL</code></td><td>traditional style</td><td><code class="literal">12/17/1997 07:37:16.00 PST</code></td></tr><tr><td><code class="literal">Postgres</code></td><td>original style</td><td><code class="literal">Wed Dec 17 07:37:16 1997 PST</code></td></tr><tr><td><code class="literal">German</code></td><td>regional style</td><td><code class="literal">17.12.1997 07:37:16.00 PST</code></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ ISO 8601 specifies the use of uppercase letter <code class="literal">T</code> to separate
+ the date and time. <span class="productname">PostgreSQL</span> accepts that format on
+ input, but on output it uses a space rather than <code class="literal">T</code>, as shown
+ above. This is for readability and for consistency with
+ <a class="ulink" href="https://tools.ietf.org/html/rfc3339" target="_top">RFC 3339</a> as
+ well as some other database systems.
+ </p></div><p>
+ In the <acronym class="acronym">SQL</acronym> and POSTGRES styles, day appears before
+ month if DMY field ordering has been specified, otherwise month appears
+ before day.
+ (See <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-INPUT" title="8.5.1. Date/Time Input">Section 8.5.1</a>
+ for how this setting also affects interpretation of input values.)
+ <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-OUTPUT2-TABLE" title="Table 8.15. Date Order Conventions">Table 8.15</a> shows examples.
+ </p><div class="table" id="DATATYPE-DATETIME-OUTPUT2-TABLE"><p class="title"><strong>Table 8.15. Date Order Conventions</strong></p><div class="table-contents"><table class="table" summary="Date Order Conventions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th><code class="varname">datestyle</code> Setting</th><th>Input Ordering</th><th>Example Output</th></tr></thead><tbody><tr><td><code class="literal">SQL, DMY</code></td><td><em class="replaceable"><code>day</code></em>/<em class="replaceable"><code>month</code></em>/<em class="replaceable"><code>year</code></em></td><td><code class="literal">17/12/1997 15:37:16.00 CET</code></td></tr><tr><td><code class="literal">SQL, MDY</code></td><td><em class="replaceable"><code>month</code></em>/<em class="replaceable"><code>day</code></em>/<em class="replaceable"><code>year</code></em></td><td><code class="literal">12/17/1997 07:37:16.00 PST</code></td></tr><tr><td><code class="literal">Postgres, DMY</code></td><td><em class="replaceable"><code>day</code></em>/<em class="replaceable"><code>month</code></em>/<em class="replaceable"><code>year</code></em></td><td><code class="literal">Wed 17 Dec 07:37:16 1997 PST</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In the <acronym class="acronym">ISO</acronym> style, the time zone is always shown as
+ a signed numeric offset from UTC, with positive sign used for zones
+ east of Greenwich. The offset will be shown
+ as <em class="replaceable"><code>hh</code></em> (hours only) if it is an integral
+ number of hours, else
+ as <em class="replaceable"><code>hh</code></em>:<em class="replaceable"><code>mm</code></em> if it
+ is an integral number of minutes, else as
+ <em class="replaceable"><code>hh</code></em>:<em class="replaceable"><code>mm</code></em>:<em class="replaceable"><code>ss</code></em>.
+ (The third case is not possible with any modern time zone standard,
+ but it can appear when working with timestamps that predate the
+ adoption of standardized time zones.)
+ In the other date styles, the time zone is shown as an alphabetic
+ abbreviation if one is in common use in the current zone. Otherwise
+ it appears as a signed numeric offset in ISO 8601 basic format
+ (<em class="replaceable"><code>hh</code></em> or <em class="replaceable"><code>hhmm</code></em>).
+ </p><p>
+ The date/time style can be selected by the user using the
+ <code class="command">SET datestyle</code> command, the <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a> parameter in the
+ <code class="filename">postgresql.conf</code> configuration file, or the
+ <code class="envar">PGDATESTYLE</code> environment variable on the server or
+ client.
+ </p><p>
+ The formatting function <code class="function">to_char</code>
+ (see <a class="xref" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Section 9.8</a>) is also available as
+ a more flexible way to format date/time output.
+ </p></div><div class="sect2" id="DATATYPE-TIMEZONES"><div class="titlepage"><div><div><h3 class="title">8.5.3. Time Zones</h3></div></div></div><a id="id-1.5.7.13.20.2" class="indexterm"></a><p>
+ Time zones, and time-zone conventions, are influenced by
+ political decisions, not just earth geometry. Time zones around the
+ world became somewhat standardized during the 1900s,
+ but continue to be prone to arbitrary changes, particularly with
+ respect to daylight-savings rules.
+ <span class="productname">PostgreSQL</span> uses the widely-used
+ IANA (Olson) time zone database for information about
+ historical time zone rules. For times in the future, the assumption
+ is that the latest known rules for a given time zone will
+ continue to be observed indefinitely far into the future.
+ </p><p>
+ <span class="productname">PostgreSQL</span> endeavors to be compatible with
+ the <acronym class="acronym">SQL</acronym> standard definitions for typical usage.
+ However, the <acronym class="acronym">SQL</acronym> standard has an odd mix of date and
+ time types and capabilities. Two obvious problems are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Although the <code class="type">date</code> type
+ cannot have an associated time zone, the
+ <code class="type">time</code> type can.
+ Time zones in the real world have little meaning unless
+ associated with a date as well as a time,
+ since the offset can vary through the year with daylight-saving
+ time boundaries.
+ </p></li><li class="listitem"><p>
+ The default time zone is specified as a constant numeric offset
+ from <acronym class="acronym">UTC</acronym>. It is therefore impossible to adapt to
+ daylight-saving time when doing date/time arithmetic across
+ <acronym class="acronym">DST</acronym> boundaries.
+ </p></li></ul></div><p>
+ </p><p>
+ To address these difficulties, we recommend using date/time types
+ that contain both date and time when using time zones. We
+ do <span class="emphasis"><em>not</em></span> recommend using the type <code class="type">time with
+ time zone</code> (though it is supported by
+ <span class="productname">PostgreSQL</span> for legacy applications and
+ for compliance with the <acronym class="acronym">SQL</acronym> standard).
+ <span class="productname">PostgreSQL</span> assumes
+ your local time zone for any type containing only date or time.
+ </p><p>
+ All timezone-aware dates and times are stored internally in
+ <acronym class="acronym">UTC</acronym>. They are converted to local time
+ in the zone specified by the <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> configuration
+ parameter before being displayed to the client.
+ </p><p>
+ <span class="productname">PostgreSQL</span> allows you to specify time zones in
+ three different forms:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A full time zone name, for example <code class="literal">America/New_York</code>.
+ The recognized time zone names are listed in the
+ <code class="literal">pg_timezone_names</code> view (see <a class="xref" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names">Section 54.32</a>).
+ <span class="productname">PostgreSQL</span> uses the widely-used IANA
+ time zone data for this purpose, so the same time zone
+ names are also recognized by other software.
+ </p></li><li class="listitem"><p>
+ A time zone abbreviation, for example <code class="literal">PST</code>. Such a
+ specification merely defines a particular offset from UTC, in
+ contrast to full time zone names which can imply a set of daylight
+ savings transition rules as well. The recognized abbreviations
+ are listed in the <code class="literal">pg_timezone_abbrevs</code> view (see <a class="xref" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs">Section 54.31</a>). You cannot set the
+ configuration parameters <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> or
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-TIMEZONE">log_timezone</a> to a time
+ zone abbreviation, but you can use abbreviations in
+ date/time input values and with the <code class="literal">AT TIME ZONE</code>
+ operator.
+ </p></li><li class="listitem"><p>
+ In addition to the timezone names and abbreviations,
+ <span class="productname">PostgreSQL</span> will accept POSIX-style time zone
+ specifications, as described in
+ <a class="xref" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications">Section B.5</a>. This option is not
+ normally preferable to using a named time zone, but it may be
+ necessary if no suitable IANA time zone entry is available.
+ </p></li></ul></div><p>
+
+ In short, this is the difference between abbreviations
+ and full names: abbreviations represent a specific offset from UTC,
+ whereas many of the full names imply a local daylight-savings time
+ rule, and so have two possible UTC offsets. As an example,
+ <code class="literal">2014-06-04 12:00 America/New_York</code> represents noon local
+ time in New York, which for this particular date was Eastern Daylight
+ Time (UTC-4). So <code class="literal">2014-06-04 12:00 EDT</code> specifies that
+ same time instant. But <code class="literal">2014-06-04 12:00 EST</code> specifies
+ noon Eastern Standard Time (UTC-5), regardless of whether daylight
+ savings was nominally in effect on that date.
+ </p><p>
+ To complicate matters, some jurisdictions have used the same timezone
+ abbreviation to mean different UTC offsets at different times; for
+ example, in Moscow <code class="literal">MSK</code> has meant UTC+3 in some years and
+ UTC+4 in others. <span class="application">PostgreSQL</span> interprets such
+ abbreviations according to whatever they meant (or had most recently
+ meant) on the specified date; but, as with the <code class="literal">EST</code> example
+ above, this is not necessarily the same as local civil time on that date.
+ </p><p>
+ In all cases, timezone names and abbreviations are recognized
+ case-insensitively. (This is a change from <span class="productname">PostgreSQL</span>
+ versions prior to 8.2, which were case-sensitive in some contexts but
+ not others.)
+ </p><p>
+ Neither timezone names nor abbreviations are hard-wired into the server;
+ they are obtained from configuration files stored under
+ <code class="filename">.../share/timezone/</code> and <code class="filename">.../share/timezonesets/</code>
+ of the installation directory
+ (see <a class="xref" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Section B.4</a>).
+ </p><p>
+ The <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> configuration parameter can
+ be set in the file <code class="filename">postgresql.conf</code>, or in any of the
+ other standard ways described in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>.
+ There are also some special ways to set it:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The <acronym class="acronym">SQL</acronym> command <code class="command">SET TIME ZONE</code>
+ sets the time zone for the session. This is an alternative spelling
+ of <code class="command">SET TIMEZONE TO</code> with a more SQL-spec-compatible syntax.
+ </p></li><li class="listitem"><p>
+ The <code class="envar">PGTZ</code> environment variable is used by
+ <span class="application">libpq</span> clients
+ to send a <code class="command">SET TIME ZONE</code>
+ command to the server upon connection.
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="DATATYPE-INTERVAL-INPUT"><div class="titlepage"><div><div><h3 class="title">8.5.4. Interval Input</h3></div></div></div><a id="id-1.5.7.13.21.2" class="indexterm"></a><p>
+ <code class="type">interval</code> values can be written using the following
+ verbose syntax:
+
+</p><pre class="synopsis">
+[<span class="optional">@</span>] <em class="replaceable"><code>quantity</code></em> <em class="replaceable"><code>unit</code></em> [<span class="optional"><em class="replaceable"><code>quantity</code></em> <em class="replaceable"><code>unit</code></em>...</span>] [<span class="optional"><em class="replaceable"><code>direction</code></em></span>]
+</pre><p>
+
+ where <em class="replaceable"><code>quantity</code></em> is a number (possibly signed);
+ <em class="replaceable"><code>unit</code></em> is <code class="literal">microsecond</code>,
+ <code class="literal">millisecond</code>, <code class="literal">second</code>,
+ <code class="literal">minute</code>, <code class="literal">hour</code>, <code class="literal">day</code>,
+ <code class="literal">week</code>, <code class="literal">month</code>, <code class="literal">year</code>,
+ <code class="literal">decade</code>, <code class="literal">century</code>, <code class="literal">millennium</code>,
+ or abbreviations or plurals of these units;
+ <em class="replaceable"><code>direction</code></em> can be <code class="literal">ago</code> or
+ empty. The at sign (<code class="literal">@</code>) is optional noise. The amounts
+ of the different units are implicitly added with appropriate
+ sign accounting. <code class="literal">ago</code> negates all the fields.
+ This syntax is also used for interval output, if
+ <a class="xref" href="runtime-config-client.html#GUC-INTERVALSTYLE">IntervalStyle</a> is set to
+ <code class="literal">postgres_verbose</code>.
+ </p><p>
+ Quantities of days, hours, minutes, and seconds can be specified without
+ explicit unit markings. For example, <code class="literal">'1 12:59:10'</code> is read
+ the same as <code class="literal">'1 day 12 hours 59 min 10 sec'</code>. Also,
+ a combination of years and months can be specified with a dash;
+ for example <code class="literal">'200-10'</code> is read the same as <code class="literal">'200 years
+ 10 months'</code>. (These shorter forms are in fact the only ones allowed
+ by the <acronym class="acronym">SQL</acronym> standard, and are used for output when
+ <code class="varname">IntervalStyle</code> is set to <code class="literal">sql_standard</code>.)
+ </p><p>
+ Interval values can also be written as ISO 8601 time intervals, using
+ either the <span class="quote">“<span class="quote">format with designators</span>”</span> of the standard's section
+ 4.4.3.2 or the <span class="quote">“<span class="quote">alternative format</span>”</span> of section 4.4.3.3. The
+ format with designators looks like this:
+</p><pre class="synopsis">
+P <em class="replaceable"><code>quantity</code></em> <em class="replaceable"><code>unit</code></em> [<span class="optional"> <em class="replaceable"><code>quantity</code></em> <em class="replaceable"><code>unit</code></em> ...</span>] [<span class="optional"> T [<span class="optional"> <em class="replaceable"><code>quantity</code></em> <em class="replaceable"><code>unit</code></em> ...</span>]</span>]
+</pre><p>
+ The string must start with a <code class="literal">P</code>, and may include a
+ <code class="literal">T</code> that introduces the time-of-day units. The
+ available unit abbreviations are given in <a class="xref" href="datatype-datetime.html#DATATYPE-INTERVAL-ISO8601-UNITS" title="Table 8.16. ISO 8601 Interval Unit Abbreviations">Table 8.16</a>. Units may be
+ omitted, and may be specified in any order, but units smaller than
+ a day must appear after <code class="literal">T</code>. In particular, the meaning of
+ <code class="literal">M</code> depends on whether it is before or after
+ <code class="literal">T</code>.
+ </p><div class="table" id="DATATYPE-INTERVAL-ISO8601-UNITS"><p class="title"><strong>Table 8.16. ISO 8601 Interval Unit Abbreviations</strong></p><div class="table-contents"><table class="table" summary="ISO 8601 Interval Unit Abbreviations" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Abbreviation</th><th>Meaning</th></tr></thead><tbody><tr><td>Y</td><td>Years</td></tr><tr><td>M</td><td>Months (in the date part)</td></tr><tr><td>W</td><td>Weeks</td></tr><tr><td>D</td><td>Days</td></tr><tr><td>H</td><td>Hours</td></tr><tr><td>M</td><td>Minutes (in the time part)</td></tr><tr><td>S</td><td>Seconds</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In the alternative format:
+</p><pre class="synopsis">
+P [<span class="optional"> <em class="replaceable"><code>years</code></em>-<em class="replaceable"><code>months</code></em>-<em class="replaceable"><code>days</code></em> </span>] [<span class="optional"> T <em class="replaceable"><code>hours</code></em>:<em class="replaceable"><code>minutes</code></em>:<em class="replaceable"><code>seconds</code></em> </span>]
+</pre><p>
+ the string must begin with <code class="literal">P</code>, and a
+ <code class="literal">T</code> separates the date and time parts of the interval.
+ The values are given as numbers similar to ISO 8601 dates.
+ </p><p>
+ When writing an interval constant with a <em class="replaceable"><code>fields</code></em>
+ specification, or when assigning a string to an interval column that was
+ defined with a <em class="replaceable"><code>fields</code></em> specification, the interpretation of
+ unmarked quantities depends on the <em class="replaceable"><code>fields</code></em>. For
+ example <code class="literal">INTERVAL '1' YEAR</code> is read as 1 year, whereas
+ <code class="literal">INTERVAL '1'</code> means 1 second. Also, field values
+ <span class="quote">“<span class="quote">to the right</span>”</span> of the least significant field allowed by the
+ <em class="replaceable"><code>fields</code></em> specification are silently discarded. For
+ example, writing <code class="literal">INTERVAL '1 day 2:03:04' HOUR TO MINUTE</code>
+ results in dropping the seconds field, but not the day field.
+ </p><p>
+ According to the <acronym class="acronym">SQL</acronym> standard all fields of an interval
+ value must have the same sign, so a leading negative sign applies to all
+ fields; for example the negative sign in the interval literal
+ <code class="literal">'-1 2:03:04'</code> applies to both the days and hour/minute/second
+ parts. <span class="productname">PostgreSQL</span> allows the fields to have different
+ signs, and traditionally treats each field in the textual representation
+ as independently signed, so that the hour/minute/second part is
+ considered positive in this example. If <code class="varname">IntervalStyle</code> is
+ set to <code class="literal">sql_standard</code> then a leading sign is considered
+ to apply to all fields (but only if no additional signs appear).
+ Otherwise the traditional <span class="productname">PostgreSQL</span> interpretation is
+ used. To avoid ambiguity, it's recommended to attach an explicit sign
+ to each field if any field is negative.
+ </p><p>
+ Field values can have fractional parts: for example, <code class="literal">'1.5
+ weeks'</code> or <code class="literal">'01:02:03.45'</code>. However,
+ because interval internally stores only three integer units (months,
+ days, microseconds), fractional units must be spilled to smaller
+ units. Fractional parts of units greater than months are rounded to
+ be an integer number of months, e.g. <code class="literal">'1.5 years'</code>
+ becomes <code class="literal">'1 year 6 mons'</code>. Fractional parts of
+ weeks and days are computed to be an integer number of days and
+ microseconds, assuming 30 days per month and 24 hours per day, e.g.,
+ <code class="literal">'1.75 months'</code> becomes <code class="literal">1 mon 22 days
+ 12:00:00</code>. Only seconds will ever be shown as fractional
+ on output.
+ </p><p>
+ <a class="xref" href="datatype-datetime.html#DATATYPE-INTERVAL-INPUT-EXAMPLES" title="Table 8.17. Interval Input">Table 8.17</a> shows some examples
+ of valid <code class="type">interval</code> input.
+ </p><div class="table" id="DATATYPE-INTERVAL-INPUT-EXAMPLES"><p class="title"><strong>Table 8.17. Interval Input</strong></p><div class="table-contents"><table class="table" summary="Interval Input" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Example</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">1-2</code></td><td>SQL standard format: 1 year 2 months</td></tr><tr><td><code class="literal">3 4:05:06</code></td><td>SQL standard format: 3 days 4 hours 5 minutes 6 seconds</td></tr><tr><td><code class="literal">1 year 2 months 3 days 4 hours 5 minutes 6 seconds</code></td><td>Traditional Postgres format: 1 year 2 months 3 days 4 hours 5 minutes 6 seconds</td></tr><tr><td><code class="literal">P1Y2M3DT4H5M6S</code></td><td>ISO 8601 <span class="quote">“<span class="quote">format with designators</span>”</span>: same meaning as above</td></tr><tr><td><code class="literal">P0001-02-03T04:05:06</code></td><td>ISO 8601 <span class="quote">“<span class="quote">alternative format</span>”</span>: same meaning as above</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Internally <code class="type">interval</code> values are stored as months, days,
+ and microseconds. This is done because the number of days in a month
+ varies, and a day can have 23 or 25 hours if a daylight savings
+ time adjustment is involved. The months and days fields are integers
+ while the microseconds field can store fractional seconds. Because intervals are
+ usually created from constant strings or <code class="type">timestamp</code> subtraction,
+ this storage method works well in most cases, but can cause unexpected
+ results:
+
+</p><pre class="programlisting">
+SELECT EXTRACT(hours from '80 minutes'::interval);
+ date_part
+-----------
+ 1
+
+SELECT EXTRACT(days from '80 hours'::interval);
+ date_part
+-----------
+ 0
+</pre><p>
+
+ Functions <code class="function">justify_days</code> and
+ <code class="function">justify_hours</code> are available for adjusting days
+ and hours that overflow their normal ranges.
+ </p></div><div class="sect2" id="DATATYPE-INTERVAL-OUTPUT"><div class="titlepage"><div><div><h3 class="title">8.5.5. Interval Output</h3></div></div></div><a id="id-1.5.7.13.22.2" class="indexterm"></a><p>
+ The output format of the interval type can be set to one of the
+ four styles <code class="literal">sql_standard</code>, <code class="literal">postgres</code>,
+ <code class="literal">postgres_verbose</code>, or <code class="literal">iso_8601</code>,
+ using the command <code class="literal">SET intervalstyle</code>.
+ The default is the <code class="literal">postgres</code> format.
+ <a class="xref" href="datatype-datetime.html#INTERVAL-STYLE-OUTPUT-TABLE" title="Table 8.18. Interval Output Style Examples">Table 8.18</a> shows examples of each
+ output style.
+ </p><p>
+ The <code class="literal">sql_standard</code> style produces output that conforms to
+ the SQL standard's specification for interval literal strings, if
+ the interval value meets the standard's restrictions (either year-month
+ only or day-time only, with no mixing of positive
+ and negative components). Otherwise the output looks like a standard
+ year-month literal string followed by a day-time literal string,
+ with explicit signs added to disambiguate mixed-sign intervals.
+ </p><p>
+ The output of the <code class="literal">postgres</code> style matches the output of
+ <span class="productname">PostgreSQL</span> releases prior to 8.4 when the
+ <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a> parameter was set to <code class="literal">ISO</code>.
+ </p><p>
+ The output of the <code class="literal">postgres_verbose</code> style matches the output of
+ <span class="productname">PostgreSQL</span> releases prior to 8.4 when the
+ <code class="varname">DateStyle</code> parameter was set to non-<code class="literal">ISO</code> output.
+ </p><p>
+ The output of the <code class="literal">iso_8601</code> style matches the <span class="quote">“<span class="quote">format
+ with designators</span>”</span> described in section 4.4.3.2 of the
+ ISO 8601 standard.
+ </p><div class="table" id="INTERVAL-STYLE-OUTPUT-TABLE"><p class="title"><strong>Table 8.18. Interval Output Style Examples</strong></p><div class="table-contents"><table class="table" summary="Interval Output Style Examples" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Style Specification</th><th>Year-Month Interval</th><th>Day-Time Interval</th><th>Mixed Interval</th></tr></thead><tbody><tr><td><code class="literal">sql_standard</code></td><td>1-2</td><td>3 4:05:06</td><td>-1-2 +3 -4:05:06</td></tr><tr><td><code class="literal">postgres</code></td><td>1 year 2 mons</td><td>3 days 04:05:06</td><td>-1 year -2 mons +3 days -04:05:06</td></tr><tr><td><code class="literal">postgres_verbose</code></td><td>@ 1 year 2 mons</td><td>@ 3 days 4 hours 5 mins 6 secs</td><td>@ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago</td></tr><tr><td><code class="literal">iso_8601</code></td><td>P1Y2M</td><td>P3DT4H5M6S</td><td>P-1Y-2M3D​T-4H-5M-6S</td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-binary.html" title="8.4. Binary Data Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-boolean.html" title="8.6. Boolean Type">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.4. Binary Data Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.6. Boolean Type</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-enum.html b/doc/src/sgml/html/datatype-enum.html
new file mode 100644
index 0000000..b65f049
--- /dev/null
+++ b/doc/src/sgml/html/datatype-enum.html
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.7. Enumerated Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-boolean.html" title="8.6. Boolean Type" /><link rel="next" href="datatype-geometric.html" title="8.8. Geometric Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.7. Enumerated Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-boolean.html" title="8.6. Boolean Type">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-geometric.html" title="8.8. Geometric Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-ENUM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.7. Enumerated Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.5">8.7.1. Declaration of Enumerated Types</a></span></dt><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.6">8.7.2. Ordering</a></span></dt><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.7">8.7.3. Type Safety</a></span></dt><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.8">8.7.4. Implementation Details</a></span></dt></dl></div><a id="id-1.5.7.15.2" class="indexterm"></a><a id="id-1.5.7.15.3" class="indexterm"></a><p>
+ Enumerated (enum) types are data types that
+ comprise a static, ordered set of values.
+ They are equivalent to the <code class="type">enum</code>
+ types supported in a number of programming languages. An example of an enum
+ type might be the days of the week, or a set of status values for
+ a piece of data.
+ </p><div class="sect2" id="id-1.5.7.15.5"><div class="titlepage"><div><div><h3 class="title">8.7.1. Declaration of Enumerated Types</h3></div></div></div><p>
+ Enum types are created using the <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> command,
+ for example:
+
+</p><pre class="programlisting">
+CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
+</pre><p>
+
+ Once created, the enum type can be used in table and function
+ definitions much like any other type:
+</p><pre class="programlisting">
+CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
+CREATE TABLE person (
+ name text,
+ current_mood mood
+);
+INSERT INTO person VALUES ('Moe', 'happy');
+SELECT * FROM person WHERE current_mood = 'happy';
+ name | current_mood
+------+--------------
+ Moe | happy
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.5.7.15.6"><div class="titlepage"><div><div><h3 class="title">8.7.2. Ordering</h3></div></div></div><p>
+ The ordering of the values in an enum type is the
+ order in which the values were listed when the type was created.
+ All standard comparison operators and related
+ aggregate functions are supported for enums. For example:
+
+</p><pre class="programlisting">
+INSERT INTO person VALUES ('Larry', 'sad');
+INSERT INTO person VALUES ('Curly', 'ok');
+SELECT * FROM person WHERE current_mood &gt; 'sad';
+ name | current_mood
+-------+--------------
+ Moe | happy
+ Curly | ok
+(2 rows)
+
+SELECT * FROM person WHERE current_mood &gt; 'sad' ORDER BY current_mood;
+ name | current_mood
+-------+--------------
+ Curly | ok
+ Moe | happy
+(2 rows)
+
+SELECT name
+FROM person
+WHERE current_mood = (SELECT MIN(current_mood) FROM person);
+ name
+-------
+ Larry
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.5.7.15.7"><div class="titlepage"><div><div><h3 class="title">8.7.3. Type Safety</h3></div></div></div><p>
+ Each enumerated data type is separate and cannot
+ be compared with other enumerated types. See this example:
+
+</p><pre class="programlisting">
+CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
+CREATE TABLE holidays (
+ num_weeks integer,
+ happiness happiness
+);
+INSERT INTO holidays(num_weeks,happiness) VALUES (4, 'happy');
+INSERT INTO holidays(num_weeks,happiness) VALUES (6, 'very happy');
+INSERT INTO holidays(num_weeks,happiness) VALUES (8, 'ecstatic');
+INSERT INTO holidays(num_weeks,happiness) VALUES (2, 'sad');
+ERROR: invalid input value for enum happiness: "sad"
+SELECT person.name, holidays.num_weeks FROM person, holidays
+ WHERE person.current_mood = holidays.happiness;
+ERROR: operator does not exist: mood = happiness
+</pre><p>
+ </p><p>
+ If you really need to do something like that, you can either
+ write a custom operator or add explicit casts to your query:
+
+</p><pre class="programlisting">
+SELECT person.name, holidays.num_weeks FROM person, holidays
+ WHERE person.current_mood::text = holidays.happiness::text;
+ name | num_weeks
+------+-----------
+ Moe | 4
+(1 row)
+
+</pre><p>
+ </p></div><div class="sect2" id="id-1.5.7.15.8"><div class="titlepage"><div><div><h3 class="title">8.7.4. Implementation Details</h3></div></div></div><p>
+ Enum labels are case sensitive, so
+ <code class="type">'happy'</code> is not the same as <code class="type">'HAPPY'</code>.
+ White space in the labels is significant too.
+ </p><p>
+ Although enum types are primarily intended for static sets of values,
+ there is support for adding new values to an existing enum type, and for
+ renaming values (see <a class="xref" href="sql-altertype.html" title="ALTER TYPE"><span class="refentrytitle">ALTER TYPE</span></a>). Existing values
+ cannot be removed from an enum type, nor can the sort ordering of such
+ values be changed, short of dropping and re-creating the enum type.
+ </p><p>
+ An enum value occupies four bytes on disk. The length of an enum
+ value's textual label is limited by the <code class="symbol">NAMEDATALEN</code>
+ setting compiled into <span class="productname">PostgreSQL</span>; in standard
+ builds this means at most 63 bytes.
+ </p><p>
+ The translations from internal enum values to textual labels are
+ kept in the system catalog
+ <a class="link" href="catalog-pg-enum.html" title="53.20. pg_enum"><code class="structname">pg_enum</code></a>.
+ Querying this catalog directly can be useful.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-boolean.html" title="8.6. Boolean Type">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-geometric.html" title="8.8. Geometric Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.6. Boolean Type </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.8. Geometric Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-geometric.html b/doc/src/sgml/html/datatype-geometric.html
new file mode 100644
index 0000000..691078a
--- /dev/null
+++ b/doc/src/sgml/html/datatype-geometric.html
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.8. Geometric Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-enum.html" title="8.7. Enumerated Types" /><link rel="next" href="datatype-net-types.html" title="8.9. Network Address Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.8. Geometric Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-enum.html" title="8.7. Enumerated Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-net-types.html" title="8.9. Network Address Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-GEOMETRIC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.8. Geometric Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-geometric.html#id-1.5.7.16.5">8.8.1. Points</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-LINE">8.8.2. Lines</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-LSEG">8.8.3. Line Segments</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#id-1.5.7.16.8">8.8.4. Boxes</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#id-1.5.7.16.9">8.8.5. Paths</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-POLYGON">8.8.6. Polygons</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-CIRCLE">8.8.7. Circles</a></span></dt></dl></div><p>
+ Geometric data types represent two-dimensional spatial
+ objects. <a class="xref" href="datatype-geometric.html#DATATYPE-GEO-TABLE" title="Table 8.20. Geometric Types">Table 8.20</a> shows the geometric
+ types available in <span class="productname">PostgreSQL</span>.
+ </p><div class="table" id="DATATYPE-GEO-TABLE"><p class="title"><strong>Table 8.20. Geometric Types</strong></p><div class="table-contents"><table class="table" summary="Geometric Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th><th>Representation</th></tr></thead><tbody><tr><td><code class="type">point</code></td><td>16 bytes</td><td>Point on a plane</td><td>(x,y)</td></tr><tr><td><code class="type">line</code></td><td>32 bytes</td><td>Infinite line</td><td>{A,B,C}</td></tr><tr><td><code class="type">lseg</code></td><td>32 bytes</td><td>Finite line segment</td><td>((x1,y1),(x2,y2))</td></tr><tr><td><code class="type">box</code></td><td>32 bytes</td><td>Rectangular box</td><td>((x1,y1),(x2,y2))</td></tr><tr><td><code class="type">path</code></td><td>16+16n bytes</td><td>Closed path (similar to polygon)</td><td>((x1,y1),...)</td></tr><tr><td><code class="type">path</code></td><td>16+16n bytes</td><td>Open path</td><td>[(x1,y1),...]</td></tr><tr><td><code class="type">polygon</code></td><td>40+16n bytes</td><td>Polygon (similar to closed path)</td><td>((x1,y1),...)</td></tr><tr><td><code class="type">circle</code></td><td>24 bytes</td><td>Circle</td><td>&lt;(x,y),r&gt; (center point and radius)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ A rich set of functions and operators is available to perform various geometric
+ operations such as scaling, translation, rotation, and determining
+ intersections. They are explained in <a class="xref" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Section 9.11</a>.
+ </p><div class="sect2" id="id-1.5.7.16.5"><div class="titlepage"><div><div><h3 class="title">8.8.1. Points</h3></div></div></div><a id="id-1.5.7.16.5.2" class="indexterm"></a><p>
+ Points are the fundamental two-dimensional building block for geometric
+ types. Values of type <code class="type">point</code> are specified using either of
+ the following syntaxes:
+
+</p><pre class="synopsis">
+( <em class="replaceable"><code>x</code></em> , <em class="replaceable"><code>y</code></em> )
+ <em class="replaceable"><code>x</code></em> , <em class="replaceable"><code>y</code></em>
+</pre><p>
+
+ where <em class="replaceable"><code>x</code></em> and <em class="replaceable"><code>y</code></em> are the respective
+ coordinates, as floating-point numbers.
+ </p><p>
+ Points are output using the first syntax.
+ </p></div><div class="sect2" id="DATATYPE-LINE"><div class="titlepage"><div><div><h3 class="title">8.8.2. Lines</h3></div></div></div><a id="id-1.5.7.16.6.2" class="indexterm"></a><p>
+ Lines are represented by the linear
+ equation <em class="replaceable"><code>A</code></em>x + <em class="replaceable"><code>B</code></em>y + <em class="replaceable"><code>C</code></em> = 0,
+ where <em class="replaceable"><code>A</code></em> and <em class="replaceable"><code>B</code></em> are not both zero. Values
+ of type <code class="type">line</code> are input and output in the following form:
+</p><pre class="synopsis">
+{ <em class="replaceable"><code>A</code></em>, <em class="replaceable"><code>B</code></em>, <em class="replaceable"><code>C</code></em> }
+</pre><p>
+
+ Alternatively, any of the following forms can be used for input:
+
+</p><pre class="synopsis">
+[ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> ) ]
+( ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> ) )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> )
+ <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em>
+</pre><p>
+
+ where
+ <code class="literal">(<em class="replaceable"><code>x1</code></em>,<em class="replaceable"><code>y1</code></em>)</code>
+ and
+ <code class="literal">(<em class="replaceable"><code>x2</code></em>,<em class="replaceable"><code>y2</code></em>)</code>
+ are two different points on the line.
+ </p></div><div class="sect2" id="DATATYPE-LSEG"><div class="titlepage"><div><div><h3 class="title">8.8.3. Line Segments</h3></div></div></div><a id="id-1.5.7.16.7.2" class="indexterm"></a><a id="id-1.5.7.16.7.3" class="indexterm"></a><p>
+ Line segments are represented by pairs of points that are the endpoints
+ of the segment. Values of type <code class="type">lseg</code> are specified using any
+ of the following syntaxes:
+
+</p><pre class="synopsis">
+[ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> ) ]
+( ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> ) )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> )
+ <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em>
+</pre><p>
+
+ where
+ <code class="literal">(<em class="replaceable"><code>x1</code></em>,<em class="replaceable"><code>y1</code></em>)</code>
+ and
+ <code class="literal">(<em class="replaceable"><code>x2</code></em>,<em class="replaceable"><code>y2</code></em>)</code>
+ are the end points of the line segment.
+ </p><p>
+ Line segments are output using the first syntax.
+ </p></div><div class="sect2" id="id-1.5.7.16.8"><div class="titlepage"><div><div><h3 class="title">8.8.4. Boxes</h3></div></div></div><a id="id-1.5.7.16.8.2" class="indexterm"></a><a id="id-1.5.7.16.8.3" class="indexterm"></a><p>
+ Boxes are represented by pairs of points that are opposite
+ corners of the box.
+ Values of type <code class="type">box</code> are specified using any of the following
+ syntaxes:
+
+</p><pre class="synopsis">
+( ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> ) )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ( <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em> )
+ <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , <em class="replaceable"><code>x2</code></em> , <em class="replaceable"><code>y2</code></em>
+</pre><p>
+
+ where
+ <code class="literal">(<em class="replaceable"><code>x1</code></em>,<em class="replaceable"><code>y1</code></em>)</code>
+ and
+ <code class="literal">(<em class="replaceable"><code>x2</code></em>,<em class="replaceable"><code>y2</code></em>)</code>
+ are any two opposite corners of the box.
+ </p><p>
+ Boxes are output using the second syntax.
+ </p><p>
+ Any two opposite corners can be supplied on input, but the values
+ will be reordered as needed to store the
+ upper right and lower left corners, in that order.
+ </p></div><div class="sect2" id="id-1.5.7.16.9"><div class="titlepage"><div><div><h3 class="title">8.8.5. Paths</h3></div></div></div><a id="id-1.5.7.16.9.2" class="indexterm"></a><p>
+ Paths are represented by lists of connected points. Paths can be
+ <em class="firstterm">open</em>, where
+ the first and last points in the list are considered not connected, or
+ <em class="firstterm">closed</em>,
+ where the first and last points are considered connected.
+ </p><p>
+ Values of type <code class="type">path</code> are specified using any of the following
+ syntaxes:
+
+</p><pre class="synopsis">
+[ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ... , ( <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> ) ]
+( ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ... , ( <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> ) )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ... , ( <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , ... , <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> )
+ <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , ... , <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em>
+</pre><p>
+
+ where the points are the end points of the line segments
+ comprising the path. Square brackets (<code class="literal">[]</code>) indicate
+ an open path, while parentheses (<code class="literal">()</code>) indicate a
+ closed path. When the outermost parentheses are omitted, as
+ in the third through fifth syntaxes, a closed path is assumed.
+ </p><p>
+ Paths are output using the first or second syntax, as appropriate.
+ </p></div><div class="sect2" id="DATATYPE-POLYGON"><div class="titlepage"><div><div><h3 class="title">8.8.6. Polygons</h3></div></div></div><a id="id-1.5.7.16.10.2" class="indexterm"></a><p>
+ Polygons are represented by lists of points (the vertexes of the
+ polygon). Polygons are very similar to closed paths; the essential
+ difference is that a polygon is considered to include the area
+ within it, while a path is not.
+ </p><p>
+ Values of type <code class="type">polygon</code> are specified using any of the
+ following syntaxes:
+
+</p><pre class="synopsis">
+( ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ... , ( <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> ) )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> ) , ... , ( <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> )
+ ( <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , ... , <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em> )
+ <em class="replaceable"><code>x1</code></em> , <em class="replaceable"><code>y1</code></em> , ... , <em class="replaceable"><code>xn</code></em> , <em class="replaceable"><code>yn</code></em>
+</pre><p>
+
+ where the points are the end points of the line segments
+ comprising the boundary of the polygon.
+ </p><p>
+ Polygons are output using the first syntax.
+ </p></div><div class="sect2" id="DATATYPE-CIRCLE"><div class="titlepage"><div><div><h3 class="title">8.8.7. Circles</h3></div></div></div><a id="id-1.5.7.16.11.2" class="indexterm"></a><p>
+ Circles are represented by a center point and radius.
+ Values of type <code class="type">circle</code> are specified using any of the
+ following syntaxes:
+
+</p><pre class="synopsis">
+&lt; ( <em class="replaceable"><code>x</code></em> , <em class="replaceable"><code>y</code></em> ) , <em class="replaceable"><code>r</code></em> &gt;
+( ( <em class="replaceable"><code>x</code></em> , <em class="replaceable"><code>y</code></em> ) , <em class="replaceable"><code>r</code></em> )
+ ( <em class="replaceable"><code>x</code></em> , <em class="replaceable"><code>y</code></em> ) , <em class="replaceable"><code>r</code></em>
+ <em class="replaceable"><code>x</code></em> , <em class="replaceable"><code>y</code></em> , <em class="replaceable"><code>r</code></em>
+</pre><p>
+
+ where
+ <code class="literal">(<em class="replaceable"><code>x</code></em>,<em class="replaceable"><code>y</code></em>)</code>
+ is the center point and <em class="replaceable"><code>r</code></em> is the radius of the
+ circle.
+ </p><p>
+ Circles are output using the first syntax.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-enum.html" title="8.7. Enumerated Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-net-types.html" title="8.9. Network Address Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.7. Enumerated Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.9. Network Address Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-json.html b/doc/src/sgml/html/datatype-json.html
new file mode 100644
index 0000000..8744845
--- /dev/null
+++ b/doc/src/sgml/html/datatype-json.html
@@ -0,0 +1,730 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.14. JSON Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-xml.html" title="8.13. XML Type" /><link rel="next" href="arrays.html" title="8.15. Arrays" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.14. <acronym class="acronym">JSON</acronym> Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-xml.html" title="8.13. XML Type">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="arrays.html" title="8.15. Arrays">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-JSON"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.14. <acronym class="acronym">JSON</acronym> Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-json.html#JSON-KEYS-ELEMENTS">8.14.1. JSON Input and Output Syntax</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSON-DOC-DESIGN">8.14.2. Designing JSON Documents</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSON-CONTAINMENT">8.14.3. <code class="type">jsonb</code> Containment and Existence</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSON-INDEXING">8.14.4. <code class="type">jsonb</code> Indexing</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSONB-SUBSCRIPTING">8.14.5. <code class="type">jsonb</code> Subscripting</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#id-1.5.7.22.20">8.14.6. Transforms</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#DATATYPE-JSONPATH">8.14.7. jsonpath Type</a></span></dt></dl></div><a id="id-1.5.7.22.2" class="indexterm"></a><a id="id-1.5.7.22.3" class="indexterm"></a><p>
+ JSON data types are for storing JSON (JavaScript Object Notation)
+ data, as specified in <a class="ulink" href="https://tools.ietf.org/html/rfc7159" target="_top">RFC
+ 7159</a>. Such data can also be stored as <code class="type">text</code>, but
+ the JSON data types have the advantage of enforcing that each
+ stored value is valid according to the JSON rules. There are also
+ assorted JSON-specific functions and operators available for data stored
+ in these data types; see <a class="xref" href="functions-json.html" title="9.16. JSON Functions and Operators">Section 9.16</a>.
+ </p><p>
+ <span class="productname">PostgreSQL</span> offers two types for storing JSON
+ data: <code class="type">json</code> and <code class="type">jsonb</code>. To implement efficient query
+ mechanisms for these data types, <span class="productname">PostgreSQL</span>
+ also provides the <code class="type">jsonpath</code> data type described in
+ <a class="xref" href="datatype-json.html#DATATYPE-JSONPATH" title="8.14.7. jsonpath Type">Section 8.14.7</a>.
+ </p><p>
+ The <code class="type">json</code> and <code class="type">jsonb</code> data types
+ accept <span class="emphasis"><em>almost</em></span> identical sets of values as
+ input. The major practical difference is one of efficiency. The
+ <code class="type">json</code> data type stores an exact copy of the input text,
+ which processing functions must reparse on each execution; while
+ <code class="type">jsonb</code> data is stored in a decomposed binary format that
+ makes it slightly slower to input due to added conversion
+ overhead, but significantly faster to process, since no reparsing
+ is needed. <code class="type">jsonb</code> also supports indexing, which can be a
+ significant advantage.
+ </p><p>
+ Because the <code class="type">json</code> type stores an exact copy of the input text, it
+ will preserve semantically-insignificant white space between tokens, as
+ well as the order of keys within JSON objects. Also, if a JSON object
+ within the value contains the same key more than once, all the key/value
+ pairs are kept. (The processing functions consider the last value as the
+ operative one.) By contrast, <code class="type">jsonb</code> does not preserve white
+ space, does not preserve the order of object keys, and does not keep
+ duplicate object keys. If duplicate keys are specified in the input,
+ only the last value is kept.
+ </p><p>
+ In general, most applications should prefer to store JSON data as
+ <code class="type">jsonb</code>, unless there are quite specialized needs, such as
+ legacy assumptions about ordering of object keys.
+ </p><p>
+ <acronym class="acronym">RFC</acronym> 7159 specifies that JSON strings should be encoded in UTF8.
+ It is therefore not possible for the JSON
+ types to conform rigidly to the JSON specification unless the database
+ encoding is UTF8. Attempts to directly include characters that
+ cannot be represented in the database encoding will fail; conversely,
+ characters that can be represented in the database encoding but not
+ in UTF8 will be allowed.
+ </p><p>
+ <acronym class="acronym">RFC</acronym> 7159 permits JSON strings to contain Unicode escape sequences
+ denoted by <code class="literal">\u<em class="replaceable"><code>XXXX</code></em></code>. In the input
+ function for the <code class="type">json</code> type, Unicode escapes are allowed
+ regardless of the database encoding, and are checked only for syntactic
+ correctness (that is, that four hex digits follow <code class="literal">\u</code>).
+ However, the input function for <code class="type">jsonb</code> is stricter: it disallows
+ Unicode escapes for characters that cannot be represented in the database
+ encoding. The <code class="type">jsonb</code> type also
+ rejects <code class="literal">\u0000</code> (because that cannot be represented in
+ <span class="productname">PostgreSQL</span>'s <code class="type">text</code> type), and it insists
+ that any use of Unicode surrogate pairs to designate characters outside
+ the Unicode Basic Multilingual Plane be correct. Valid Unicode escapes
+ are converted to the equivalent single character for storage;
+ this includes folding surrogate pairs into a single character.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Many of the JSON processing functions described
+ in <a class="xref" href="functions-json.html" title="9.16. JSON Functions and Operators">Section 9.16</a> will convert Unicode escapes to
+ regular characters, and will therefore throw the same types of errors
+ just described even if their input is of type <code class="type">json</code>
+ not <code class="type">jsonb</code>. The fact that the <code class="type">json</code> input function does
+ not make these checks may be considered a historical artifact, although
+ it does allow for simple storage (without processing) of JSON Unicode
+ escapes in a database encoding that does not support the represented
+ characters.
+ </p></div><p>
+ When converting textual JSON input into <code class="type">jsonb</code>, the primitive
+ types described by <acronym class="acronym">RFC</acronym> 7159 are effectively mapped onto
+ native <span class="productname">PostgreSQL</span> types, as shown
+ in <a class="xref" href="datatype-json.html#JSON-TYPE-MAPPING-TABLE" title="Table 8.23. JSON Primitive Types and Corresponding PostgreSQL Types">Table 8.23</a>.
+ Therefore, there are some minor additional constraints on what
+ constitutes valid <code class="type">jsonb</code> data that do not apply to
+ the <code class="type">json</code> type, nor to JSON in the abstract, corresponding
+ to limits on what can be represented by the underlying data type.
+ Notably, <code class="type">jsonb</code> will reject numbers that are outside the
+ range of the <span class="productname">PostgreSQL</span> <code class="type">numeric</code> data
+ type, while <code class="type">json</code> will not. Such implementation-defined
+ restrictions are permitted by <acronym class="acronym">RFC</acronym> 7159. However, in
+ practice such problems are far more likely to occur in other
+ implementations, as it is common to represent JSON's <code class="type">number</code>
+ primitive type as IEEE 754 double precision floating point
+ (which <acronym class="acronym">RFC</acronym> 7159 explicitly anticipates and allows for).
+ When using JSON as an interchange format with such systems, the danger
+ of losing numeric precision compared to data originally stored
+ by <span class="productname">PostgreSQL</span> should be considered.
+ </p><p>
+ Conversely, as noted in the table there are some minor restrictions on
+ the input format of JSON primitive types that do not apply to
+ the corresponding <span class="productname">PostgreSQL</span> types.
+ </p><div class="table" id="JSON-TYPE-MAPPING-TABLE"><p class="title"><strong>Table 8.23. JSON Primitive Types and Corresponding <span class="productname">PostgreSQL</span> Types</strong></p><div class="table-contents"><table class="table" summary="JSON Primitive Types and Corresponding PostgreSQL Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>JSON primitive type</th><th><span class="productname">PostgreSQL</span> type</th><th>Notes</th></tr></thead><tbody><tr><td><code class="type">string</code></td><td><code class="type">text</code></td><td><code class="literal">\u0000</code> is disallowed, as are Unicode escapes
+ representing characters not available in the database encoding</td></tr><tr><td><code class="type">number</code></td><td><code class="type">numeric</code></td><td><code class="literal">NaN</code> and <code class="literal">infinity</code> values are disallowed</td></tr><tr><td><code class="type">boolean</code></td><td><code class="type">boolean</code></td><td>Only lowercase <code class="literal">true</code> and <code class="literal">false</code> spellings are accepted</td></tr><tr><td><code class="type">null</code></td><td>(none)</td><td>SQL <code class="literal">NULL</code> is a different concept</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect2" id="JSON-KEYS-ELEMENTS"><div class="titlepage"><div><div><h3 class="title">8.14.1. JSON Input and Output Syntax</h3></div></div></div><p>
+ The input/output syntax for the JSON data types is as specified in
+ <acronym class="acronym">RFC</acronym> 7159.
+ </p><p>
+ The following are all valid <code class="type">json</code> (or <code class="type">jsonb</code>) expressions:
+</p><pre class="programlisting">
+-- Simple scalar/primitive value
+-- Primitive values can be numbers, quoted strings, true, false, or null
+SELECT '5'::json;
+
+-- Array of zero or more elements (elements need not be of same type)
+SELECT '[1, 2, "foo", null]'::json;
+
+-- Object containing pairs of keys and values
+-- Note that object keys must always be quoted strings
+SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;
+
+-- Arrays and objects can be nested arbitrarily
+SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
+</pre><p>
+ </p><p>
+ As previously stated, when a JSON value is input and then printed without
+ any additional processing, <code class="type">json</code> outputs the same text that was
+ input, while <code class="type">jsonb</code> does not preserve semantically-insignificant
+ details such as whitespace. For example, note the differences here:
+</p><pre class="programlisting">
+SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
+ json
+-------------------------------------------------
+ {"bar": "baz", "balance": 7.77, "active":false}
+(1 row)
+
+SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
+ jsonb
+--------------------------------------------------
+ {"bar": "baz", "active": false, "balance": 7.77}
+(1 row)
+</pre><p>
+ One semantically-insignificant detail worth noting is that
+ in <code class="type">jsonb</code>, numbers will be printed according to the behavior of the
+ underlying <code class="type">numeric</code> type. In practice this means that numbers
+ entered with <code class="literal">E</code> notation will be printed without it, for
+ example:
+</p><pre class="programlisting">
+SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
+ json | jsonb
+-----------------------+-------------------------
+ {"reading": 1.230e-5} | {"reading": 0.00001230}
+(1 row)
+</pre><p>
+ However, <code class="type">jsonb</code> will preserve trailing fractional zeroes, as seen
+ in this example, even though those are semantically insignificant for
+ purposes such as equality checks.
+ </p><p>
+ For the list of built-in functions and operators available for
+ constructing and processing JSON values, see <a class="xref" href="functions-json.html" title="9.16. JSON Functions and Operators">Section 9.16</a>.
+ </p></div><div class="sect2" id="JSON-DOC-DESIGN"><div class="titlepage"><div><div><h3 class="title">8.14.2. Designing JSON Documents</h3></div></div></div><p>
+ Representing data as JSON can be considerably more flexible than
+ the traditional relational data model, which is compelling in
+ environments where requirements are fluid. It is quite possible
+ for both approaches to co-exist and complement each other within
+ the same application. However, even for applications where maximal
+ flexibility is desired, it is still recommended that JSON documents
+ have a somewhat fixed structure. The structure is typically
+ unenforced (though enforcing some business rules declaratively is
+ possible), but having a predictable structure makes it easier to write
+ queries that usefully summarize a set of <span class="quote">“<span class="quote">documents</span>”</span> (datums)
+ in a table.
+ </p><p>
+ JSON data is subject to the same concurrency-control
+ considerations as any other data type when stored in a table.
+ Although storing large documents is practicable, keep in mind that
+ any update acquires a row-level lock on the whole row.
+ Consider limiting JSON documents to a
+ manageable size in order to decrease lock contention among updating
+ transactions. Ideally, JSON documents should each
+ represent an atomic datum that business rules dictate cannot
+ reasonably be further subdivided into smaller datums that
+ could be modified independently.
+ </p></div><div class="sect2" id="JSON-CONTAINMENT"><div class="titlepage"><div><div><h3 class="title">8.14.3. <code class="type">jsonb</code> Containment and Existence</h3></div></div></div><a id="id-1.5.7.22.17.2" class="indexterm"></a><a id="id-1.5.7.22.17.3" class="indexterm"></a><p>
+ Testing <em class="firstterm">containment</em> is an important capability of
+ <code class="type">jsonb</code>. There is no parallel set of facilities for the
+ <code class="type">json</code> type. Containment tests whether
+ one <code class="type">jsonb</code> document has contained within it another one.
+ These examples return true except as noted:
+ </p><pre class="programlisting">
+-- Simple scalar/primitive values contain only the identical value:
+SELECT '"foo"'::jsonb @&gt; '"foo"'::jsonb;
+
+-- The array on the right side is contained within the one on the left:
+SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 3]'::jsonb;
+
+-- Order of array elements is not significant, so this is also true:
+SELECT '[1, 2, 3]'::jsonb @&gt; '[3, 1]'::jsonb;
+
+-- Duplicate array elements don't matter either:
+SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 2, 2]'::jsonb;
+
+-- The object with a single pair on the right side is contained
+-- within the object on the left side:
+SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @&gt; '{"version": 9.4}'::jsonb;
+
+-- The array on the right side is <span class="emphasis"><strong>not</strong></span> considered contained within the
+-- array on the left, even though a similar array is nested within it:
+SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[1, 3]'::jsonb; -- yields false
+
+-- But with a layer of nesting, it is contained:
+SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[[1, 3]]'::jsonb;
+
+-- Similarly, containment is not reported here:
+SELECT '{"foo": {"bar": "baz"}}'::jsonb @&gt; '{"bar": "baz"}'::jsonb; -- yields false
+
+-- A top-level key and an empty object is contained:
+SELECT '{"foo": {"bar": "baz"}}'::jsonb @&gt; '{"foo": {}}'::jsonb;
+</pre><p>
+ The general principle is that the contained object must match the
+ containing object as to structure and data contents, possibly after
+ discarding some non-matching array elements or object key/value pairs
+ from the containing object.
+ But remember that the order of array elements is not significant when
+ doing a containment match, and duplicate array elements are effectively
+ considered only once.
+ </p><p>
+ As a special exception to the general principle that the structures
+ must match, an array may contain a primitive value:
+ </p><pre class="programlisting">
+-- This array contains the primitive string value:
+SELECT '["foo", "bar"]'::jsonb @&gt; '"bar"'::jsonb;
+
+-- This exception is not reciprocal -- non-containment is reported here:
+SELECT '"bar"'::jsonb @&gt; '["bar"]'::jsonb; -- yields false
+</pre><p>
+ <code class="type">jsonb</code> also has an <em class="firstterm">existence</em> operator, which is
+ a variation on the theme of containment: it tests whether a string
+ (given as a <code class="type">text</code> value) appears as an object key or array
+ element at the top level of the <code class="type">jsonb</code> value.
+ These examples return true except as noted:
+ </p><pre class="programlisting">
+-- String exists as array element:
+SELECT '["foo", "bar", "baz"]'::jsonb ? 'bar';
+
+-- String exists as object key:
+SELECT '{"foo": "bar"}'::jsonb ? 'foo';
+
+-- Object values are not considered:
+SELECT '{"foo": "bar"}'::jsonb ? 'bar'; -- yields false
+
+-- As with containment, existence must match at the top level:
+SELECT '{"foo": {"bar": "baz"}}'::jsonb ? 'bar'; -- yields false
+
+-- A string is considered to exist if it matches a primitive JSON string:
+SELECT '"foo"'::jsonb ? 'foo';
+</pre><p>
+ JSON objects are better suited than arrays for testing containment or
+ existence when there are many keys or elements involved, because
+ unlike arrays they are internally optimized for searching, and do not
+ need to be searched linearly.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Because JSON containment is nested, an appropriate query can skip
+ explicit selection of sub-objects. As an example, suppose that we have
+ a <code class="structfield">doc</code> column containing objects at the top level, with
+ most objects containing <code class="literal">tags</code> fields that contain arrays of
+ sub-objects. This query finds entries in which sub-objects containing
+ both <code class="literal">"term":"paris"</code> and <code class="literal">"term":"food"</code> appear,
+ while ignoring any such keys outside the <code class="literal">tags</code> array:
+</p><pre class="programlisting">
+SELECT doc-&gt;'site_name' FROM websites
+ WHERE doc @&gt; '{"tags":[{"term":"paris"}, {"term":"food"}]}';
+</pre><p>
+ One could accomplish the same thing with, say,
+</p><pre class="programlisting">
+SELECT doc-&gt;'site_name' FROM websites
+ WHERE doc-&gt;'tags' @&gt; '[{"term":"paris"}, {"term":"food"}]';
+</pre><p>
+ but that approach is less flexible, and often less efficient as well.
+ </p><p>
+ On the other hand, the JSON existence operator is not nested: it will
+ only look for the specified key or array element at top level of the
+ JSON value.
+ </p></div><p>
+ The various containment and existence operators, along with all other
+ JSON operators and functions are documented
+ in <a class="xref" href="functions-json.html" title="9.16. JSON Functions and Operators">Section 9.16</a>.
+ </p></div><div class="sect2" id="JSON-INDEXING"><div class="titlepage"><div><div><h3 class="title">8.14.4. <code class="type">jsonb</code> Indexing</h3></div></div></div><a id="id-1.5.7.22.18.2" class="indexterm"></a><p>
+ GIN indexes can be used to efficiently search for
+ keys or key/value pairs occurring within a large number of
+ <code class="type">jsonb</code> documents (datums).
+ Two GIN <span class="quote">“<span class="quote">operator classes</span>”</span> are provided, offering different
+ performance and flexibility trade-offs.
+ </p><p>
+ The default GIN operator class for <code class="type">jsonb</code> supports queries with
+ the key-exists operators <code class="literal">?</code>, <code class="literal">?|</code>
+ and <code class="literal">?&amp;</code>, the containment operator
+ <code class="literal">@&gt;</code>, and the <code class="type">jsonpath</code> match
+ operators <code class="literal">@?</code> and <code class="literal">@@</code>.
+ (For details of the semantics that these operators
+ implement, see <a class="xref" href="functions-json.html#FUNCTIONS-JSONB-OP-TABLE" title="Table 9.46. Additional jsonb Operators">Table 9.46</a>.)
+ An example of creating an index with this operator class is:
+</p><pre class="programlisting">
+CREATE INDEX idxgin ON api USING GIN (jdoc);
+</pre><p>
+ The non-default GIN operator class <code class="literal">jsonb_path_ops</code>
+ does not support the key-exists operators, but it does support
+ <code class="literal">@&gt;</code>, <code class="literal">@?</code> and <code class="literal">@@</code>.
+ An example of creating an index with this operator class is:
+</p><pre class="programlisting">
+CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops);
+</pre><p>
+ </p><p>
+ Consider the example of a table that stores JSON documents
+ retrieved from a third-party web service, with a documented schema
+ definition. A typical document is:
+</p><pre class="programlisting">
+{
+ "guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
+ "name": "Angela Barton",
+ "is_active": true,
+ "company": "Magnafone",
+ "address": "178 Howard Place, Gulf, Washington, 702",
+ "registered": "2009-11-07T08:53:22 +08:00",
+ "latitude": 19.793713,
+ "longitude": 86.513373,
+ "tags": [
+ "enim",
+ "aliquip",
+ "qui"
+ ]
+}
+</pre><p>
+ We store these documents in a table named <code class="structname">api</code>,
+ in a <code class="type">jsonb</code> column named <code class="structfield">jdoc</code>.
+ If a GIN index is created on this column,
+ queries like the following can make use of the index:
+</p><pre class="programlisting">
+-- Find documents in which the key "company" has value "Magnafone"
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"company": "Magnafone"}';
+</pre><p>
+ However, the index could not be used for queries like the
+ following, because though the operator <code class="literal">?</code> is indexable,
+ it is not applied directly to the indexed column <code class="structfield">jdoc</code>:
+</p><pre class="programlisting">
+-- Find documents in which the key "tags" contains key or array element "qui"
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc -&gt; 'tags' ? 'qui';
+</pre><p>
+ Still, with appropriate use of expression indexes, the above
+ query can use an index. If querying for particular items within
+ the <code class="literal">"tags"</code> key is common, defining an index like this
+ may be worthwhile:
+</p><pre class="programlisting">
+CREATE INDEX idxgintags ON api USING GIN ((jdoc -&gt; 'tags'));
+</pre><p>
+ Now, the <code class="literal">WHERE</code> clause <code class="literal">jdoc -&gt; 'tags' ? 'qui'</code>
+ will be recognized as an application of the indexable
+ operator <code class="literal">?</code> to the indexed
+ expression <code class="literal">jdoc -&gt; 'tags'</code>.
+ (More information on expression indexes can be found in <a class="xref" href="indexes-expressional.html" title="11.7. Indexes on Expressions">Section 11.7</a>.)
+ </p><p>
+ Another approach to querying is to exploit containment, for example:
+</p><pre class="programlisting">
+-- Find documents in which the key "tags" contains array element "qui"
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qui"]}';
+</pre><p>
+ A simple GIN index on the <code class="structfield">jdoc</code> column can support this
+ query. But note that such an index will store copies of every key and
+ value in the <code class="structfield">jdoc</code> column, whereas the expression index
+ of the previous example stores only data found under
+ the <code class="literal">tags</code> key. While the simple-index approach is far more
+ flexible (since it supports queries about any key), targeted expression
+ indexes are likely to be smaller and faster to search than a simple
+ index.
+ </p><p>
+ GIN indexes also support the <code class="literal">@?</code>
+ and <code class="literal">@@</code> operators, which
+ perform <code class="type">jsonpath</code> matching. Examples are
+</p><pre class="programlisting">
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @? '$.tags[*] ? (@ == "qui")';
+</pre><p>
+</p><pre class="programlisting">
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @@ '$.tags[*] == "qui"';
+</pre><p>
+ For these operators, a GIN index extracts clauses of the form
+ <code class="literal"><em class="replaceable"><code>accessors_chain</code></em>
+ = <em class="replaceable"><code>constant</code></em></code> out of
+ the <code class="type">jsonpath</code> pattern, and does the index search based on
+ the keys and values mentioned in these clauses. The accessors chain
+ may include <code class="literal">.<em class="replaceable"><code>key</code></em></code>,
+ <code class="literal">[*]</code>,
+ and <code class="literal">[<em class="replaceable"><code>index</code></em>]</code> accessors.
+ The <code class="literal">jsonb_ops</code> operator class also
+ supports <code class="literal">.*</code> and <code class="literal">.**</code> accessors,
+ but the <code class="literal">jsonb_path_ops</code> operator class does not.
+ </p><p>
+ Although the <code class="literal">jsonb_path_ops</code> operator class supports
+ only queries with the <code class="literal">@&gt;</code>, <code class="literal">@?</code>
+ and <code class="literal">@@</code> operators, it has notable
+ performance advantages over the default operator
+ class <code class="literal">jsonb_ops</code>. A <code class="literal">jsonb_path_ops</code>
+ index is usually much smaller than a <code class="literal">jsonb_ops</code>
+ index over the same data, and the specificity of searches is better,
+ particularly when queries contain keys that appear frequently in the
+ data. Therefore search operations typically perform better
+ than with the default operator class.
+ </p><p>
+ The technical difference between a <code class="literal">jsonb_ops</code>
+ and a <code class="literal">jsonb_path_ops</code> GIN index is that the former
+ creates independent index items for each key and value in the data,
+ while the latter creates index items only for each value in the
+ data.
+ <a href="#ftn.id-1.5.7.22.18.9.3" class="footnote"><sup class="footnote" id="id-1.5.7.22.18.9.3">[7]</sup></a>
+ Basically, each <code class="literal">jsonb_path_ops</code> index item is
+ a hash of the value and the key(s) leading to it; for example to index
+ <code class="literal">{"foo": {"bar": "baz"}}</code>, a single index item would
+ be created incorporating all three of <code class="literal">foo</code>, <code class="literal">bar</code>,
+ and <code class="literal">baz</code> into the hash value. Thus a containment query
+ looking for this structure would result in an extremely specific index
+ search; but there is no way at all to find out whether <code class="literal">foo</code>
+ appears as a key. On the other hand, a <code class="literal">jsonb_ops</code>
+ index would create three index items representing <code class="literal">foo</code>,
+ <code class="literal">bar</code>, and <code class="literal">baz</code> separately; then to do the
+ containment query, it would look for rows containing all three of
+ these items. While GIN indexes can perform such an AND search fairly
+ efficiently, it will still be less specific and slower than the
+ equivalent <code class="literal">jsonb_path_ops</code> search, especially if
+ there are a very large number of rows containing any single one of the
+ three index items.
+ </p><p>
+ A disadvantage of the <code class="literal">jsonb_path_ops</code> approach is
+ that it produces no index entries for JSON structures not containing
+ any values, such as <code class="literal">{"a": {}}</code>. If a search for
+ documents containing such a structure is requested, it will require a
+ full-index scan, which is quite slow. <code class="literal">jsonb_path_ops</code> is
+ therefore ill-suited for applications that often perform such searches.
+ </p><p>
+ <code class="type">jsonb</code> also supports <code class="literal">btree</code> and <code class="literal">hash</code>
+ indexes. These are usually useful only if it's important to check
+ equality of complete JSON documents.
+ The <code class="literal">btree</code> ordering for <code class="type">jsonb</code> datums is seldom
+ of great interest, but for completeness it is:
+</p><pre class="synopsis">
+<em class="replaceable"><code>Object</code></em> &gt; <em class="replaceable"><code>Array</code></em> &gt; <em class="replaceable"><code>Boolean</code></em> &gt; <em class="replaceable"><code>Number</code></em> &gt; <em class="replaceable"><code>String</code></em> &gt; <em class="replaceable"><code>Null</code></em>
+
+<em class="replaceable"><code>Object with n pairs</code></em> &gt; <em class="replaceable"><code>object with n - 1 pairs</code></em>
+
+<em class="replaceable"><code>Array with n elements</code></em> &gt; <em class="replaceable"><code>array with n - 1 elements</code></em>
+</pre><p>
+ Objects with equal numbers of pairs are compared in the order:
+</p><pre class="synopsis">
+<em class="replaceable"><code>key-1</code></em>, <em class="replaceable"><code>value-1</code></em>, <em class="replaceable"><code>key-2</code></em> ...
+</pre><p>
+ Note that object keys are compared in their storage order;
+ in particular, since shorter keys are stored before longer keys, this
+ can lead to results that might be unintuitive, such as:
+</p><pre class="programlisting">
+{ "aa": 1, "c": 1} &gt; {"b": 1, "d": 1}
+</pre><p>
+ Similarly, arrays with equal numbers of elements are compared in the
+ order:
+</p><pre class="synopsis">
+<em class="replaceable"><code>element-1</code></em>, <em class="replaceable"><code>element-2</code></em> ...
+</pre><p>
+ Primitive JSON values are compared using the same
+ comparison rules as for the underlying
+ <span class="productname">PostgreSQL</span> data type. Strings are
+ compared using the default database collation.
+ </p></div><div class="sect2" id="JSONB-SUBSCRIPTING"><div class="titlepage"><div><div><h3 class="title">8.14.5. <code class="type">jsonb</code> Subscripting</h3></div></div></div><p>
+ The <code class="type">jsonb</code> data type supports array-style subscripting expressions
+ to extract and modify elements. Nested values can be indicated by chaining
+ subscripting expressions, following the same rules as the <code class="literal">path</code>
+ argument in the <code class="literal">jsonb_set</code> function. If a <code class="type">jsonb</code>
+ value is an array, numeric subscripts start at zero, and negative integers count
+ backwards from the last element of the array. Slice expressions are not supported.
+ The result of a subscripting expression is always of the jsonb data type.
+ </p><p>
+ <code class="command">UPDATE</code> statements may use subscripting in the
+ <code class="literal">SET</code> clause to modify <code class="type">jsonb</code> values. Subscript
+ paths must be traversable for all affected values insofar as they exist. For
+ instance, the path <code class="literal">val['a']['b']['c']</code> can be traversed all
+ the way to <code class="literal">c</code> if every <code class="literal">val</code>,
+ <code class="literal">val['a']</code>, and <code class="literal">val['a']['b']</code> is an
+ object. If any <code class="literal">val['a']</code> or <code class="literal">val['a']['b']</code>
+ is not defined, it will be created as an empty object and filled as
+ necessary. However, if any <code class="literal">val</code> itself or one of the
+ intermediary values is defined as a non-object such as a string, number, or
+ <code class="literal">jsonb</code> <code class="literal">null</code>, traversal cannot proceed so
+ an error is raised and the transaction aborted.
+ </p><p>
+ An example of subscripting syntax:
+
+</p><pre class="programlisting">
+
+-- Extract object value by key
+SELECT ('{"a": 1}'::jsonb)['a'];
+
+-- Extract nested object value by key path
+SELECT ('{"a": {"b": {"c": 1}}}'::jsonb)['a']['b']['c'];
+
+-- Extract array element by index
+SELECT ('[1, "2", null]'::jsonb)[1];
+
+-- Update object value by key. Note the quotes around '1': the assigned
+-- value must be of the jsonb type as well
+UPDATE table_name SET jsonb_field['key'] = '1';
+
+-- This will raise an error if any record's jsonb_field['a']['b'] is something
+-- other than an object. For example, the value {"a": 1} has a numeric value
+-- of the key 'a'.
+UPDATE table_name SET jsonb_field['a']['b']['c'] = '1';
+
+-- Filter records using a WHERE clause with subscripting. Since the result of
+-- subscripting is jsonb, the value we compare it against must also be jsonb.
+-- The double quotes make "value" also a valid jsonb string.
+SELECT * FROM table_name WHERE jsonb_field['key'] = '"value"';
+</pre><p>
+
+ <code class="type">jsonb</code> assignment via subscripting handles a few edge cases
+ differently from <code class="literal">jsonb_set</code>. When a source <code class="type">jsonb</code>
+ value is <code class="literal">NULL</code>, assignment via subscripting will proceed
+ as if it was an empty JSON value of the type (object or array) implied by the
+ subscript key:
+
+</p><pre class="programlisting">
+-- Where jsonb_field was NULL, it is now {"a": 1}
+UPDATE table_name SET jsonb_field['a'] = '1';
+
+-- Where jsonb_field was NULL, it is now [1]
+UPDATE table_name SET jsonb_field[0] = '1';
+</pre><p>
+
+ If an index is specified for an array containing too few elements,
+ <code class="literal">NULL</code> elements will be appended until the index is reachable
+ and the value can be set.
+
+</p><pre class="programlisting">
+-- Where jsonb_field was [], it is now [null, null, 2];
+-- where jsonb_field was [0], it is now [0, null, 2]
+UPDATE table_name SET jsonb_field[2] = '2';
+</pre><p>
+
+ A <code class="type">jsonb</code> value will accept assignments to nonexistent subscript
+ paths as long as the last existing element to be traversed is an object or
+ array, as implied by the corresponding subscript (the element indicated by
+ the last subscript in the path is not traversed and may be anything). Nested
+ array and object structures will be created, and in the former case
+ <code class="literal">null</code>-padded, as specified by the subscript path until the
+ assigned value can be placed.
+
+</p><pre class="programlisting">
+-- Where jsonb_field was {}, it is now {"a": [{"b": 1}]}
+UPDATE table_name SET jsonb_field['a'][0]['b'] = '1';
+
+-- Where jsonb_field was [], it is now [null, {"a": 1}]
+UPDATE table_name SET jsonb_field[1]['a'] = '1';
+</pre><p>
+
+ </p></div><div class="sect2" id="id-1.5.7.22.20"><div class="titlepage"><div><div><h3 class="title">8.14.6. Transforms</h3></div></div></div><p>
+ Additional extensions are available that implement transforms for the
+ <code class="type">jsonb</code> type for different procedural languages.
+ </p><p>
+ The extensions for PL/Perl are called <code class="literal">jsonb_plperl</code> and
+ <code class="literal">jsonb_plperlu</code>. If you use them, <code class="type">jsonb</code>
+ values are mapped to Perl arrays, hashes, and scalars, as appropriate.
+ </p><p>
+ The extension for PL/Python is called <code class="literal">jsonb_plpython3u</code>.
+ If you use it, <code class="type">jsonb</code> values are mapped to Python
+ dictionaries, lists, and scalars, as appropriate.
+ </p><p>
+ Of these extensions, <code class="literal">jsonb_plperl</code> is
+ considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be installed by
+ non-superusers who have <code class="literal">CREATE</code> privilege on the
+ current database. The rest require superuser privilege to install.
+ </p></div><div class="sect2" id="DATATYPE-JSONPATH"><div class="titlepage"><div><div><h3 class="title">8.14.7. jsonpath Type</h3></div></div></div><a id="id-1.5.7.22.21.2" class="indexterm"></a><p>
+ The <code class="type">jsonpath</code> type implements support for the SQL/JSON path language
+ in <span class="productname">PostgreSQL</span> to efficiently query JSON data.
+ It provides a binary representation of the parsed SQL/JSON path
+ expression that specifies the items to be retrieved by the path
+ engine from the JSON data for further processing with the
+ SQL/JSON query functions.
+ </p><p>
+ The semantics of SQL/JSON path predicates and operators generally follow SQL.
+ At the same time, to provide a natural way of working with JSON data,
+ SQL/JSON path syntax uses some JavaScript conventions:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Dot (<code class="literal">.</code>) is used for member access.
+ </p></li><li class="listitem"><p>
+ Square brackets (<code class="literal">[]</code>) are used for array access.
+ </p></li><li class="listitem"><p>
+ SQL/JSON arrays are 0-relative, unlike regular SQL arrays that start from 1.
+ </p></li></ul></div><p>
+ An SQL/JSON path expression is typically written in an SQL query as an
+ SQL character string literal, so it must be enclosed in single quotes,
+ and any single quotes desired within the value must be doubled
+ (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a>).
+ Some forms of path expressions require string literals within them.
+ These embedded string literals follow JavaScript/ECMAScript conventions:
+ they must be surrounded by double quotes, and backslash escapes may be
+ used within them to represent otherwise-hard-to-type characters.
+ In particular, the way to write a double quote within an embedded string
+ literal is <code class="literal">\"</code>, and to write a backslash itself, you
+ must write <code class="literal">\\</code>. Other special backslash sequences
+ include those recognized in JSON strings:
+ <code class="literal">\b</code>,
+ <code class="literal">\f</code>,
+ <code class="literal">\n</code>,
+ <code class="literal">\r</code>,
+ <code class="literal">\t</code>,
+ <code class="literal">\v</code>
+ for various ASCII control characters, and
+ <code class="literal">\u<em class="replaceable"><code>NNNN</code></em></code> for a Unicode
+ character identified by its 4-hex-digit code point. The backslash
+ syntax also includes two cases not allowed by JSON:
+ <code class="literal">\x<em class="replaceable"><code>NN</code></em></code> for a character code
+ written with only two hex digits, and
+ <code class="literal">\u{<em class="replaceable"><code>N...</code></em>}</code> for a character
+ code written with 1 to 6 hex digits.
+ </p><p>
+ A path expression consists of a sequence of path elements,
+ which can be any of the following:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Path literals of JSON primitive types:
+ Unicode text, numeric, true, false, or null.
+ </p></li><li class="listitem"><p>
+ Path variables listed in <a class="xref" href="datatype-json.html#TYPE-JSONPATH-VARIABLES" title="Table 8.24. jsonpath Variables">Table 8.24</a>.
+ </p></li><li class="listitem"><p>
+ Accessor operators listed in <a class="xref" href="datatype-json.html#TYPE-JSONPATH-ACCESSORS" title="Table 8.25. jsonpath Accessors">Table 8.25</a>.
+ </p></li><li class="listitem"><p>
+ <code class="type">jsonpath</code> operators and methods listed
+ in <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-PATH-OPERATORS" title="9.16.2.2. SQL/JSON Path Operators and Methods">Section 9.16.2.2</a>.
+ </p></li><li class="listitem"><p>
+ Parentheses, which can be used to provide filter expressions
+ or define the order of path evaluation.
+ </p></li></ul></div><p>
+ </p><p>
+ For details on using <code class="type">jsonpath</code> expressions with SQL/JSON
+ query functions, see <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-PATH" title="9.16.2. The SQL/JSON Path Language">Section 9.16.2</a>.
+ </p><div class="table" id="TYPE-JSONPATH-VARIABLES"><p class="title"><strong>Table 8.24. <code class="type">jsonpath</code> Variables</strong></p><div class="table-contents"><table class="table" summary="jsonpath Variables" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">$</code></td><td>A variable representing the JSON value being queried
+ (the <em class="firstterm">context item</em>).
+ </td></tr><tr><td><code class="literal">$varname</code></td><td>
+ A named variable. Its value can be set by the parameter
+ <em class="parameter"><code>vars</code></em> of several JSON processing functions;
+ see <a class="xref" href="functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE" title="Table 9.48. JSON Processing Functions">Table 9.48</a> for details.
+
+ </td></tr><tr><td><code class="literal">@</code></td><td>A variable representing the result of path evaluation
+ in filter expressions.
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="TYPE-JSONPATH-ACCESSORS"><p class="title"><strong>Table 8.25. <code class="type">jsonpath</code> Accessors</strong></p><div class="table-contents"><table class="table" summary="jsonpath Accessors" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Accessor Operator</th><th>Description</th></tr></thead><tbody><tr><td>
+ <p>
+ <code class="literal">.<em class="replaceable"><code>key</code></em></code>
+ </p>
+ <p>
+ <code class="literal">."$<em class="replaceable"><code>varname</code></em>"</code>
+ </p>
+ </td><td>
+ <p>
+ Member accessor that returns an object member with
+ the specified key. If the key name matches some named variable
+ starting with <code class="literal">$</code> or does not meet the
+ JavaScript rules for an identifier, it must be enclosed in
+ double quotes to make it a string literal.
+ </p>
+ </td></tr><tr><td>
+ <p>
+ <code class="literal">.*</code>
+ </p>
+ </td><td>
+ <p>
+ Wildcard member accessor that returns the values of all
+ members located at the top level of the current object.
+ </p>
+ </td></tr><tr><td>
+ <p>
+ <code class="literal">.**</code>
+ </p>
+ </td><td>
+ <p>
+ Recursive wildcard member accessor that processes all levels
+ of the JSON hierarchy of the current object and returns all
+ the member values, regardless of their nesting level. This
+ is a <span class="productname">PostgreSQL</span> extension of
+ the SQL/JSON standard.
+ </p>
+ </td></tr><tr><td>
+ <p>
+ <code class="literal">.**{<em class="replaceable"><code>level</code></em>}</code>
+ </p>
+ <p>
+ <code class="literal">.**{<em class="replaceable"><code>start_level</code></em> to
+ <em class="replaceable"><code>end_level</code></em>}</code>
+ </p>
+ </td><td>
+ <p>
+ Like <code class="literal">.**</code>, but selects only the specified
+ levels of the JSON hierarchy. Nesting levels are specified as integers.
+ Level zero corresponds to the current object. To access the lowest
+ nesting level, you can use the <code class="literal">last</code> keyword.
+ This is a <span class="productname">PostgreSQL</span> extension of
+ the SQL/JSON standard.
+ </p>
+ </td></tr><tr><td>
+ <p>
+ <code class="literal">[<em class="replaceable"><code>subscript</code></em>, ...]</code>
+ </p>
+ </td><td>
+ <p>
+ Array element accessor.
+ <code class="literal"><em class="replaceable"><code>subscript</code></em></code> can be
+ given in two forms: <code class="literal"><em class="replaceable"><code>index</code></em></code>
+ or <code class="literal"><em class="replaceable"><code>start_index</code></em> to <em class="replaceable"><code>end_index</code></em></code>.
+ The first form returns a single array element by its index. The second
+ form returns an array slice by the range of indexes, including the
+ elements that correspond to the provided
+ <em class="replaceable"><code>start_index</code></em> and <em class="replaceable"><code>end_index</code></em>.
+ </p>
+ <p>
+ The specified <em class="replaceable"><code>index</code></em> can be an integer, as
+ well as an expression returning a single numeric value, which is
+ automatically cast to integer. Index zero corresponds to the first
+ array element. You can also use the <code class="literal">last</code> keyword
+ to denote the last array element, which is useful for handling arrays
+ of unknown length.
+ </p>
+ </td></tr><tr><td>
+ <p>
+ <code class="literal">[*]</code>
+ </p>
+ </td><td>
+ <p>
+ Wildcard array element accessor that returns all array elements.
+ </p>
+ </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.5.7.22.18.9.3" class="footnote"><p><a href="#id-1.5.7.22.18.9.3" class="para"><sup class="para">[7] </sup></a>
+ For this purpose, the term <span class="quote">“<span class="quote">value</span>”</span> includes array elements,
+ though JSON terminology sometimes considers array elements distinct
+ from values within objects.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-xml.html" title="8.13. XML Type">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="arrays.html" title="8.15. Arrays">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.13. <acronym class="acronym">XML</acronym> Type </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.15. Arrays</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-money.html b/doc/src/sgml/html/datatype-money.html
new file mode 100644
index 0000000..a753b33
--- /dev/null
+++ b/doc/src/sgml/html/datatype-money.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.2. Monetary Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-numeric.html" title="8.1. Numeric Types" /><link rel="next" href="datatype-character.html" title="8.3. Character Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.2. Monetary Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-numeric.html" title="8.1. Numeric Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-character.html" title="8.3. Character Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-MONEY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.2. Monetary Types</h2></div></div></div><p>
+ The <code class="type">money</code> type stores a currency amount with a fixed
+ fractional precision; see <a class="xref" href="datatype-money.html#DATATYPE-MONEY-TABLE" title="Table 8.3. Monetary Types">Table 8.3</a>. The fractional precision is
+ determined by the database's <a class="xref" href="runtime-config-client.html#GUC-LC-MONETARY">lc_monetary</a> setting.
+ The range shown in the table assumes there are two fractional digits.
+ Input is accepted in a variety of formats, including integer and
+ floating-point literals, as well as typical
+ currency formatting, such as <code class="literal">'$1,000.00'</code>.
+ Output is generally in the latter form but depends on the locale.
+ </p><div class="table" id="DATATYPE-MONEY-TABLE"><p class="title"><strong>Table 8.3. Monetary Types</strong></p><div class="table-contents"><table class="table" summary="Monetary Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th><th>Range</th></tr></thead><tbody><tr><td><code class="type">money</code></td><td>8 bytes</td><td>currency amount</td><td>-92233720368547758.08 to +92233720368547758.07</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Since the output of this data type is locale-sensitive, it might not
+ work to load <code class="type">money</code> data into a database that has a different
+ setting of <code class="varname">lc_monetary</code>. To avoid problems, before
+ restoring a dump into a new database make sure <code class="varname">lc_monetary</code> has
+ the same or equivalent value as in the database that was dumped.
+ </p><p>
+ Values of the <code class="type">numeric</code>, <code class="type">int</code>, and
+ <code class="type">bigint</code> data types can be cast to <code class="type">money</code>.
+ Conversion from the <code class="type">real</code> and <code class="type">double precision</code>
+ data types can be done by casting to <code class="type">numeric</code> first, for
+ example:
+</p><pre class="programlisting">
+SELECT '12.34'::float8::numeric::money;
+</pre><p>
+ However, this is not recommended. Floating point numbers should not be
+ used to handle money due to the potential for rounding errors.
+ </p><p>
+ A <code class="type">money</code> value can be cast to <code class="type">numeric</code> without
+ loss of precision. Conversion to other types could potentially lose
+ precision, and must also be done in two stages:
+</p><pre class="programlisting">
+SELECT '52093.89'::money::numeric::float8;
+</pre><p>
+ </p><p>
+ Division of a <code class="type">money</code> value by an integer value is performed
+ with truncation of the fractional part towards zero. To get a rounded
+ result, divide by a floating-point value, or cast the <code class="type">money</code>
+ value to <code class="type">numeric</code> before dividing and back to <code class="type">money</code>
+ afterwards. (The latter is preferable to avoid risking precision loss.)
+ When a <code class="type">money</code> value is divided by another <code class="type">money</code>
+ value, the result is <code class="type">double precision</code> (i.e., a pure number,
+ not money); the currency units cancel each other out in the division.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-numeric.html" title="8.1. Numeric Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-character.html" title="8.3. Character Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.1. Numeric Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.3. Character Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-net-types.html b/doc/src/sgml/html/datatype-net-types.html
new file mode 100644
index 0000000..7c98ab4
--- /dev/null
+++ b/doc/src/sgml/html/datatype-net-types.html
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.9. Network Address Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-geometric.html" title="8.8. Geometric Types" /><link rel="next" href="datatype-bit.html" title="8.10. Bit String Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.9. Network Address Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-geometric.html" title="8.8. Geometric Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-bit.html" title="8.10. Bit String Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-NET-TYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.9. Network Address Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-INET">8.9.1. <code class="type">inet</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-CIDR">8.9.2. <code class="type">cidr</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-INET-VS-CIDR">8.9.3. <code class="type">inet</code> vs. <code class="type">cidr</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-MACADDR">8.9.4. <code class="type">macaddr</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-MACADDR8">8.9.5. <code class="type">macaddr8</code></a></span></dt></dl></div><a id="id-1.5.7.17.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> offers data types to store IPv4, IPv6, and MAC
+ addresses, as shown in <a class="xref" href="datatype-net-types.html#DATATYPE-NET-TYPES-TABLE" title="Table 8.21. Network Address Types">Table 8.21</a>. It
+ is better to use these types instead of plain text types to store
+ network addresses, because
+ these types offer input error checking and specialized
+ operators and functions (see <a class="xref" href="functions-net.html" title="9.12. Network Address Functions and Operators">Section 9.12</a>).
+ </p><div class="table" id="DATATYPE-NET-TYPES-TABLE"><p class="title"><strong>Table 8.21. Network Address Types</strong></p><div class="table-contents"><table class="table" summary="Network Address Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">cidr</code></td><td>7 or 19 bytes</td><td>IPv4 and IPv6 networks</td></tr><tr><td><code class="type">inet</code></td><td>7 or 19 bytes</td><td>IPv4 and IPv6 hosts and networks</td></tr><tr><td><code class="type">macaddr</code></td><td>6 bytes</td><td>MAC addresses</td></tr><tr><td><code class="type">macaddr8</code></td><td>8 bytes</td><td>MAC addresses (EUI-64 format)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ When sorting <code class="type">inet</code> or <code class="type">cidr</code> data types,
+ IPv4 addresses will always sort before IPv6 addresses, including
+ IPv4 addresses encapsulated or mapped to IPv6 addresses, such as
+ ::10.2.3.4 or ::ffff:10.4.3.2.
+ </p><div class="sect2" id="DATATYPE-INET"><div class="titlepage"><div><div><h3 class="title">8.9.1. <code class="type">inet</code></h3></div></div></div><a id="id-1.5.7.17.6.2" class="indexterm"></a><p>
+ The <code class="type">inet</code> type holds an IPv4 or IPv6 host address, and
+ optionally its subnet, all in one field.
+ The subnet is represented by the number of network address bits
+ present in the host address (the
+ <span class="quote">“<span class="quote">netmask</span>”</span>). If the netmask is 32 and the address is IPv4,
+ then the value does not indicate a subnet, only a single host.
+ In IPv6, the address length is 128 bits, so 128 bits specify a
+ unique host address. Note that if you
+ want to accept only networks, you should use the
+ <code class="type">cidr</code> type rather than <code class="type">inet</code>.
+ </p><p>
+ The input format for this type is
+ <em class="replaceable"><code>address/y</code></em>
+ where
+ <em class="replaceable"><code>address</code></em>
+ is an IPv4 or IPv6 address and
+ <em class="replaceable"><code>y</code></em>
+ is the number of bits in the netmask. If the
+ <em class="replaceable"><code>/y</code></em>
+ portion is omitted, the
+ netmask is taken to be 32 for IPv4 or 128 for IPv6,
+ so the value represents
+ just a single host. On display, the
+ <em class="replaceable"><code>/y</code></em>
+ portion is suppressed if the netmask specifies a single host.
+ </p></div><div class="sect2" id="DATATYPE-CIDR"><div class="titlepage"><div><div><h3 class="title">8.9.2. <code class="type">cidr</code></h3></div></div></div><a id="id-1.5.7.17.7.2" class="indexterm"></a><p>
+ The <code class="type">cidr</code> type holds an IPv4 or IPv6 network specification.
+ Input and output formats follow Classless Internet Domain Routing
+ conventions.
+ The format for specifying networks is <em class="replaceable"><code>address/y</code></em> where <em class="replaceable"><code>address</code></em> is the network's lowest
+ address represented as an
+ IPv4 or IPv6 address, and <em class="replaceable"><code>y</code></em> is the number of bits in the netmask. If
+ <em class="replaceable"><code>y</code></em> is omitted, it is calculated
+ using assumptions from the older classful network numbering system, except
+ it will be at least large enough to include all of the octets
+ written in the input. It is an error to specify a network address
+ that has bits set to the right of the specified netmask.
+ </p><p>
+ <a class="xref" href="datatype-net-types.html#DATATYPE-NET-CIDR-TABLE" title="Table 8.22. cidr Type Input Examples">Table 8.22</a> shows some examples.
+ </p><div class="table" id="DATATYPE-NET-CIDR-TABLE"><p class="title"><strong>Table 8.22. <code class="type">cidr</code> Type Input Examples</strong></p><div class="table-contents"><table class="table" summary="cidr Type Input Examples" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th><code class="type">cidr</code> Input</th><th><code class="type">cidr</code> Output</th><th><code class="literal"><code class="function">abbrev(<code class="type">cidr</code>)</code></code></th></tr></thead><tbody><tr><td>192.168.100.128/25</td><td>192.168.100.128/25</td><td>192.168.100.128/25</td></tr><tr><td>192.168/24</td><td>192.168.0.0/24</td><td>192.168.0/24</td></tr><tr><td>192.168/25</td><td>192.168.0.0/25</td><td>192.168.0.0/25</td></tr><tr><td>192.168.1</td><td>192.168.1.0/24</td><td>192.168.1/24</td></tr><tr><td>192.168</td><td>192.168.0.0/24</td><td>192.168.0/24</td></tr><tr><td>128.1</td><td>128.1.0.0/16</td><td>128.1/16</td></tr><tr><td>128</td><td>128.0.0.0/16</td><td>128.0/16</td></tr><tr><td>128.1.2</td><td>128.1.2.0/24</td><td>128.1.2/24</td></tr><tr><td>10.1.2</td><td>10.1.2.0/24</td><td>10.1.2/24</td></tr><tr><td>10.1</td><td>10.1.0.0/16</td><td>10.1/16</td></tr><tr><td>10</td><td>10.0.0.0/8</td><td>10/8</td></tr><tr><td>10.1.2.3/32</td><td>10.1.2.3/32</td><td>10.1.2.3/32</td></tr><tr><td>2001:4f8:3:ba::/64</td><td>2001:4f8:3:ba::/64</td><td>2001:4f8:3:ba/64</td></tr><tr><td>2001:4f8:3:ba:​2e0:81ff:fe22:d1f1/128</td><td>2001:4f8:3:ba:​2e0:81ff:fe22:d1f1/128</td><td>2001:4f8:3:ba:​2e0:81ff:fe22:d1f1/128</td></tr><tr><td>::ffff:1.2.3.0/120</td><td>::ffff:1.2.3.0/120</td><td>::ffff:1.2.3/120</td></tr><tr><td>::ffff:1.2.3.0/128</td><td>::ffff:1.2.3.0/128</td><td>::ffff:1.2.3.0/128</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="DATATYPE-INET-VS-CIDR"><div class="titlepage"><div><div><h3 class="title">8.9.3. <code class="type">inet</code> vs. <code class="type">cidr</code></h3></div></div></div><p>
+ The essential difference between <code class="type">inet</code> and <code class="type">cidr</code>
+ data types is that <code class="type">inet</code> accepts values with nonzero bits to
+ the right of the netmask, whereas <code class="type">cidr</code> does not. For
+ example, <code class="literal">192.168.0.1/24</code> is valid for <code class="type">inet</code>
+ but not for <code class="type">cidr</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If you do not like the output format for <code class="type">inet</code> or
+ <code class="type">cidr</code> values, try the functions <code class="function">host</code>,
+ <code class="function">text</code>, and <code class="function">abbrev</code>.
+ </p></div></div><div class="sect2" id="DATATYPE-MACADDR"><div class="titlepage"><div><div><h3 class="title">8.9.4. <code class="type">macaddr</code></h3></div></div></div><a id="id-1.5.7.17.9.2" class="indexterm"></a><a id="id-1.5.7.17.9.3" class="indexterm"></a><p>
+ The <code class="type">macaddr</code> type stores MAC addresses, known for example
+ from Ethernet card hardware addresses (although MAC addresses are
+ used for other purposes as well). Input is accepted in the
+ following formats:
+
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">'08:00:2b:01:02:03'</code></td></tr><tr><td><code class="literal">'08-00-2b-01-02-03'</code></td></tr><tr><td><code class="literal">'08002b:010203'</code></td></tr><tr><td><code class="literal">'08002b-010203'</code></td></tr><tr><td><code class="literal">'0800.2b01.0203'</code></td></tr><tr><td><code class="literal">'0800-2b01-0203'</code></td></tr><tr><td><code class="literal">'08002b010203'</code></td></tr></table><p>
+
+ These examples all specify the same address. Upper and
+ lower case is accepted for the digits
+ <code class="literal">a</code> through <code class="literal">f</code>. Output is always in the
+ first of the forms shown.
+ </p><p>
+ IEEE Standard 802-2001 specifies the second form shown (with hyphens)
+ as the canonical form for MAC addresses, and specifies the first
+ form (with colons) as used with bit-reversed, MSB-first notation, so that
+ 08-00-2b-01-02-03 = 10:00:D4:80:40:C0. This convention is widely
+ ignored nowadays, and it is relevant only for obsolete network
+ protocols (such as Token Ring). PostgreSQL makes no provisions
+ for bit reversal; all accepted formats use the canonical LSB
+ order.
+ </p><p>
+ The remaining five input formats are not part of any standard.
+ </p></div><div class="sect2" id="DATATYPE-MACADDR8"><div class="titlepage"><div><div><h3 class="title">8.9.5. <code class="type">macaddr8</code></h3></div></div></div><a id="id-1.5.7.17.10.2" class="indexterm"></a><a id="id-1.5.7.17.10.3" class="indexterm"></a><p>
+ The <code class="type">macaddr8</code> type stores MAC addresses in EUI-64
+ format, known for example from Ethernet card hardware addresses
+ (although MAC addresses are used for other purposes as well).
+ This type can accept both 6 and 8 byte length MAC addresses
+ and stores them in 8 byte length format. MAC addresses given
+ in 6 byte format will be stored in 8 byte length format with the
+ 4th and 5th bytes set to FF and FE, respectively.
+
+ Note that IPv6 uses a modified EUI-64 format where the 7th bit
+ should be set to one after the conversion from EUI-48. The
+ function <code class="function">macaddr8_set7bit</code> is provided to make this
+ change.
+
+ Generally speaking, any input which is comprised of pairs of hex
+ digits (on byte boundaries), optionally separated consistently by
+ one of <code class="literal">':'</code>, <code class="literal">'-'</code> or <code class="literal">'.'</code>, is
+ accepted. The number of hex digits must be either 16 (8 bytes) or
+ 12 (6 bytes). Leading and trailing whitespace is ignored.
+
+ The following are examples of input formats that are accepted:
+
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">'08:00:2b:01:02:03:04:05'</code></td></tr><tr><td><code class="literal">'08-00-2b-01-02-03-04-05'</code></td></tr><tr><td><code class="literal">'08002b:0102030405'</code></td></tr><tr><td><code class="literal">'08002b-0102030405'</code></td></tr><tr><td><code class="literal">'0800.2b01.0203.0405'</code></td></tr><tr><td><code class="literal">'0800-2b01-0203-0405'</code></td></tr><tr><td><code class="literal">'08002b01:02030405'</code></td></tr><tr><td><code class="literal">'08002b0102030405'</code></td></tr></table><p>
+
+ These examples all specify the same address. Upper and
+ lower case is accepted for the digits
+ <code class="literal">a</code> through <code class="literal">f</code>. Output is always in the
+ first of the forms shown.
+ </p><p>
+ The last six input formats shown above are not part of any standard.
+ </p><p>
+ To convert a traditional 48 bit MAC address in EUI-48 format to
+ modified EUI-64 format to be included as the host portion of an
+ IPv6 address, use <code class="function">macaddr8_set7bit</code> as shown:
+
+</p><pre class="programlisting">
+SELECT macaddr8_set7bit('08:00:2b:01:02:03');
+<code class="computeroutput">
+ macaddr8_set7bit
+-------------------------
+ 0a:00:2b:ff:fe:01:02:03
+(1 row)
+</code>
+</pre><p>
+
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-geometric.html" title="8.8. Geometric Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-bit.html" title="8.10. Bit String Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.8. Geometric Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.10. Bit String Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-numeric.html b/doc/src/sgml/html/datatype-numeric.html
new file mode 100644
index 0000000..6418f0a
--- /dev/null
+++ b/doc/src/sgml/html/datatype-numeric.html
@@ -0,0 +1,370 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.1. Numeric Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype.html" title="Chapter 8. Data Types" /><link rel="next" href="datatype-money.html" title="8.2. Monetary Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.1. Numeric Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype.html" title="Chapter 8. Data Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-money.html" title="8.2. Monetary Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-NUMERIC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.1. Numeric Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-INT">8.1.1. Integer Types</a></span></dt><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL">8.1.2. Arbitrary Precision Numbers</a></span></dt><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-FLOAT">8.1.3. Floating-Point Types</a></span></dt><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-SERIAL">8.1.4. Serial Types</a></span></dt></dl></div><a id="id-1.5.7.9.2" class="indexterm"></a><p>
+ Numeric types consist of two-, four-, and eight-byte integers,
+ four- and eight-byte floating-point numbers, and selectable-precision
+ decimals. <a class="xref" href="datatype-numeric.html#DATATYPE-NUMERIC-TABLE" title="Table 8.2. Numeric Types">Table 8.2</a> lists the
+ available types.
+ </p><div class="table" id="DATATYPE-NUMERIC-TABLE"><p class="title"><strong>Table 8.2. Numeric Types</strong></p><div class="table-contents"><table class="table" summary="Numeric Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Name</th><th>Storage Size</th><th>Description</th><th>Range</th></tr></thead><tbody><tr><td><code class="type">smallint</code></td><td>2 bytes</td><td>small-range integer</td><td>-32768 to +32767</td></tr><tr><td><code class="type">integer</code></td><td>4 bytes</td><td>typical choice for integer</td><td>-2147483648 to +2147483647</td></tr><tr><td><code class="type">bigint</code></td><td>8 bytes</td><td>large-range integer</td><td>-9223372036854775808 to +9223372036854775807</td></tr><tr><td><code class="type">decimal</code></td><td>variable</td><td>user-specified precision, exact</td><td>up to 131072 digits before the decimal point; up to 16383 digits after the decimal point</td></tr><tr><td><code class="type">numeric</code></td><td>variable</td><td>user-specified precision, exact</td><td>up to 131072 digits before the decimal point; up to 16383 digits after the decimal point</td></tr><tr><td><code class="type">real</code></td><td>4 bytes</td><td>variable-precision, inexact</td><td>6 decimal digits precision</td></tr><tr><td><code class="type">double precision</code></td><td>8 bytes</td><td>variable-precision, inexact</td><td>15 decimal digits precision</td></tr><tr><td><code class="type">smallserial</code></td><td>2 bytes</td><td>small autoincrementing integer</td><td>1 to 32767</td></tr><tr><td><code class="type">serial</code></td><td>4 bytes</td><td>autoincrementing integer</td><td>1 to 2147483647</td></tr><tr><td><code class="type">bigserial</code></td><td>8 bytes</td><td>large autoincrementing integer</td><td>1 to 9223372036854775807</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The syntax of constants for the numeric types is described in
+ <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS" title="4.1.2. Constants">Section 4.1.2</a>. The numeric types have a
+ full set of corresponding arithmetic operators and
+ functions. Refer to <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a> for more
+ information. The following sections describe the types in detail.
+ </p><div class="sect2" id="DATATYPE-INT"><div class="titlepage"><div><div><h3 class="title">8.1.1. Integer Types</h3></div></div></div><a id="id-1.5.7.9.6.2" class="indexterm"></a><a id="id-1.5.7.9.6.3" class="indexterm"></a><a id="id-1.5.7.9.6.4" class="indexterm"></a><a id="id-1.5.7.9.6.5" class="indexterm"></a><a id="id-1.5.7.9.6.6" class="indexterm"></a><a id="id-1.5.7.9.6.7" class="indexterm"></a><p>
+ The types <code class="type">smallint</code>, <code class="type">integer</code>, and
+ <code class="type">bigint</code> store whole numbers, that is, numbers without
+ fractional components, of various ranges. Attempts to store
+ values outside of the allowed range will result in an error.
+ </p><p>
+ The type <code class="type">integer</code> is the common choice, as it offers
+ the best balance between range, storage size, and performance.
+ The <code class="type">smallint</code> type is generally only used if disk
+ space is at a premium. The <code class="type">bigint</code> type is designed to be
+ used when the range of the <code class="type">integer</code> type is insufficient.
+ </p><p>
+ <acronym class="acronym">SQL</acronym> only specifies the integer types
+ <code class="type">integer</code> (or <code class="type">int</code>),
+ <code class="type">smallint</code>, and <code class="type">bigint</code>. The
+ type names <code class="type">int2</code>, <code class="type">int4</code>, and
+ <code class="type">int8</code> are extensions, which are also used by some
+ other <acronym class="acronym">SQL</acronym> database systems.
+ </p></div><div class="sect2" id="DATATYPE-NUMERIC-DECIMAL"><div class="titlepage"><div><div><h3 class="title">8.1.2. Arbitrary Precision Numbers</h3></div></div></div><a id="id-1.5.7.9.7.2" class="indexterm"></a><a id="id-1.5.7.9.7.3" class="indexterm"></a><a id="id-1.5.7.9.7.4" class="indexterm"></a><p>
+ The type <code class="type">numeric</code> can store numbers with a
+ very large number of digits. It is especially recommended for
+ storing monetary amounts and other quantities where exactness is
+ required. Calculations with <code class="type">numeric</code> values yield exact
+ results where possible, e.g., addition, subtraction, multiplication.
+ However, calculations on <code class="type">numeric</code> values are very slow
+ compared to the integer types, or to the floating-point types
+ described in the next section.
+ </p><p>
+ We use the following terms below: The
+ <em class="firstterm">precision</em> of a <code class="type">numeric</code>
+ is the total count of significant digits in the whole number,
+ that is, the number of digits to both sides of the decimal point.
+ The <em class="firstterm">scale</em> of a <code class="type">numeric</code> is the
+ count of decimal digits in the fractional part, to the right of the
+ decimal point. So the number 23.5141 has a precision of 6 and a
+ scale of 4. Integers can be considered to have a scale of zero.
+ </p><p>
+ Both the maximum precision and the maximum scale of a
+ <code class="type">numeric</code> column can be
+ configured. To declare a column of type <code class="type">numeric</code> use
+ the syntax:
+</p><pre class="programlisting">
+NUMERIC(<em class="replaceable"><code>precision</code></em>, <em class="replaceable"><code>scale</code></em>)
+</pre><p>
+ The precision must be positive, while the scale may be positive or
+ negative (see below). Alternatively:
+</p><pre class="programlisting">
+NUMERIC(<em class="replaceable"><code>precision</code></em>)
+</pre><p>
+ selects a scale of 0. Specifying:
+</p><pre class="programlisting">
+NUMERIC
+</pre><p>
+ without any precision or scale creates an <span class="quote">“<span class="quote">unconstrained
+ numeric</span>”</span> column in which numeric values of any length can be
+ stored, up to the implementation limits. A column of this kind will
+ not coerce input values to any particular scale, whereas
+ <code class="type">numeric</code> columns with a declared scale will coerce
+ input values to that scale. (The <acronym class="acronym">SQL</acronym> standard
+ requires a default scale of 0, i.e., coercion to integer
+ precision. We find this a bit useless. If you're concerned
+ about portability, always specify the precision and scale
+ explicitly.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The maximum precision that can be explicitly specified in
+ a <code class="type">numeric</code> type declaration is 1000. An
+ unconstrained <code class="type">numeric</code> column is subject to the limits
+ described in <a class="xref" href="datatype-numeric.html#DATATYPE-NUMERIC-TABLE" title="Table 8.2. Numeric Types">Table 8.2</a>.
+ </p></div><p>
+ If the scale of a value to be stored is greater than the declared
+ scale of the column, the system will round the value to the specified
+ number of fractional digits. Then, if the number of digits to the
+ left of the decimal point exceeds the declared precision minus the
+ declared scale, an error is raised.
+ For example, a column declared as
+</p><pre class="programlisting">
+NUMERIC(3, 1)
+</pre><p>
+ will round values to 1 decimal place and can store values between
+ -99.9 and 99.9, inclusive.
+ </p><p>
+ Beginning in <span class="productname">PostgreSQL</span> 15, it is allowed
+ to declare a <code class="type">numeric</code> column with a negative scale. Then
+ values will be rounded to the left of the decimal point. The
+ precision still represents the maximum number of non-rounded digits.
+ Thus, a column declared as
+</p><pre class="programlisting">
+NUMERIC(2, -3)
+</pre><p>
+ will round values to the nearest thousand and can store values
+ between -99000 and 99000, inclusive.
+ It is also allowed to declare a scale larger than the declared
+ precision. Such a column can only hold fractional values, and it
+ requires the number of zero digits just to the right of the decimal
+ point to be at least the declared scale minus the declared precision.
+ For example, a column declared as
+</p><pre class="programlisting">
+NUMERIC(3, 5)
+</pre><p>
+ will round values to 5 decimal places and can store values between
+ -0.00999 and 0.00999, inclusive.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> permits the scale in a
+ <code class="type">numeric</code> type declaration to be any value in the range
+ -1000 to 1000. However, the <acronym class="acronym">SQL</acronym> standard requires
+ the scale to be in the range 0 to <em class="replaceable"><code>precision</code></em>.
+ Using scales outside that range may not be portable to other database
+ systems.
+ </p></div><p>
+ Numeric values are physically stored without any extra leading or
+ trailing zeroes. Thus, the declared precision and scale of a column
+ are maximums, not fixed allocations. (In this sense the <code class="type">numeric</code>
+ type is more akin to <code class="type">varchar(<em class="replaceable"><code>n</code></em>)</code>
+ than to <code class="type">char(<em class="replaceable"><code>n</code></em>)</code>.) The actual storage
+ requirement is two bytes for each group of four decimal digits,
+ plus three to eight bytes overhead.
+ </p><a id="id-1.5.7.9.7.13" class="indexterm"></a><a id="id-1.5.7.9.7.14" class="indexterm"></a><a id="id-1.5.7.9.7.15" class="indexterm"></a><p>
+ In addition to ordinary numeric values, the <code class="type">numeric</code> type
+ has several special values:
+</p><div class="literallayout"><p><br />
+<code class="literal">Infinity</code><br />
+<code class="literal">-Infinity</code><br />
+<code class="literal">NaN</code><br />
+</p></div><p>
+ These are adapted from the IEEE 754 standard, and represent
+ <span class="quote">“<span class="quote">infinity</span>”</span>, <span class="quote">“<span class="quote">negative infinity</span>”</span>, and
+ <span class="quote">“<span class="quote">not-a-number</span>”</span>, respectively. When writing these values
+ as constants in an SQL command, you must put quotes around them,
+ for example <code class="literal">UPDATE table SET x = '-Infinity'</code>.
+ On input, these strings are recognized in a case-insensitive manner.
+ The infinity values can alternatively be spelled <code class="literal">inf</code>
+ and <code class="literal">-inf</code>.
+ </p><p>
+ The infinity values behave as per mathematical expectations. For
+ example, <code class="literal">Infinity</code> plus any finite value equals
+ <code class="literal">Infinity</code>, as does <code class="literal">Infinity</code>
+ plus <code class="literal">Infinity</code>; but <code class="literal">Infinity</code>
+ minus <code class="literal">Infinity</code> yields <code class="literal">NaN</code> (not a
+ number), because it has no well-defined interpretation. Note that an
+ infinity can only be stored in an unconstrained <code class="type">numeric</code>
+ column, because it notionally exceeds any finite precision limit.
+ </p><p>
+ The <code class="literal">NaN</code> (not a number) value is used to represent
+ undefined calculational results. In general, any operation with
+ a <code class="literal">NaN</code> input yields another <code class="literal">NaN</code>.
+ The only exception is when the operation's other inputs are such that
+ the same output would be obtained if the <code class="literal">NaN</code> were to
+ be replaced by any finite or infinite numeric value; then, that output
+ value is used for <code class="literal">NaN</code> too. (An example of this
+ principle is that <code class="literal">NaN</code> raised to the zero power
+ yields one.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In most implementations of the <span class="quote">“<span class="quote">not-a-number</span>”</span> concept,
+ <code class="literal">NaN</code> is not considered equal to any other numeric
+ value (including <code class="literal">NaN</code>). In order to allow
+ <code class="type">numeric</code> values to be sorted and used in tree-based
+ indexes, <span class="productname">PostgreSQL</span> treats <code class="literal">NaN</code>
+ values as equal, and greater than all non-<code class="literal">NaN</code>
+ values.
+ </p></div><p>
+ The types <code class="type">decimal</code> and <code class="type">numeric</code> are
+ equivalent. Both types are part of the <acronym class="acronym">SQL</acronym>
+ standard.
+ </p><p>
+ When rounding values, the <code class="type">numeric</code> type rounds ties away
+ from zero, while (on most machines) the <code class="type">real</code>
+ and <code class="type">double precision</code> types round ties to the nearest even
+ number. For example:
+
+</p><pre class="programlisting">
+SELECT x,
+ round(x::numeric) AS num_round,
+ round(x::double precision) AS dbl_round
+FROM generate_series(-3.5, 3.5, 1) as x;
+ x | num_round | dbl_round
+------+-----------+-----------
+ -3.5 | -4 | -4
+ -2.5 | -3 | -2
+ -1.5 | -2 | -2
+ -0.5 | -1 | -0
+ 0.5 | 1 | 0
+ 1.5 | 2 | 2
+ 2.5 | 3 | 2
+ 3.5 | 4 | 4
+(8 rows)
+</pre><p>
+ </p></div><div class="sect2" id="DATATYPE-FLOAT"><div class="titlepage"><div><div><h3 class="title">8.1.3. Floating-Point Types</h3></div></div></div><a id="id-1.5.7.9.8.2" class="indexterm"></a><a id="id-1.5.7.9.8.3" class="indexterm"></a><a id="id-1.5.7.9.8.4" class="indexterm"></a><a id="id-1.5.7.9.8.5" class="indexterm"></a><a id="id-1.5.7.9.8.6" class="indexterm"></a><p>
+ The data types <code class="type">real</code> and <code class="type">double precision</code> are
+ inexact, variable-precision numeric types. On all currently supported
+ platforms, these types are implementations of <acronym class="acronym">IEEE</acronym>
+ Standard 754 for Binary Floating-Point Arithmetic (single and double
+ precision, respectively), to the extent that the underlying processor,
+ operating system, and compiler support it.
+ </p><p>
+ Inexact means that some values cannot be converted exactly to the
+ internal format and are stored as approximations, so that storing
+ and retrieving a value might show slight discrepancies.
+ Managing these errors and how they propagate through calculations
+ is the subject of an entire branch of mathematics and computer
+ science and will not be discussed here, except for the
+ following points:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If you require exact storage and calculations (such as for
+ monetary amounts), use the <code class="type">numeric</code> type instead.
+ </p></li><li class="listitem"><p>
+ If you want to do complicated calculations with these types
+ for anything important, especially if you rely on certain
+ behavior in boundary cases (infinity, underflow), you should
+ evaluate the implementation carefully.
+ </p></li><li class="listitem"><p>
+ Comparing two floating-point values for equality might not
+ always work as expected.
+ </p></li></ul></div><p>
+ </p><p>
+ On all currently supported platforms, the <code class="type">real</code> type has a
+ range of around 1E-37 to 1E+37 with a precision of at least 6 decimal
+ digits. The <code class="type">double precision</code> type has a range of around
+ 1E-307 to 1E+308 with a precision of at least 15 digits. Values that are
+ too large or too small will cause an error. Rounding might take place if
+ the precision of an input number is too high. Numbers too close to zero
+ that are not representable as distinct from zero will cause an underflow
+ error.
+ </p><p>
+ By default, floating point values are output in text form in their
+ shortest precise decimal representation; the decimal value produced is
+ closer to the true stored binary value than to any other value
+ representable in the same binary precision. (However, the output value is
+ currently never <span class="emphasis"><em>exactly</em></span> midway between two
+ representable values, in order to avoid a widespread bug where input
+ routines do not properly respect the round-to-nearest-even rule.) This value will
+ use at most 17 significant decimal digits for <code class="type">float8</code>
+ values, and at most 9 digits for <code class="type">float4</code> values.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This shortest-precise output format is much faster to generate than the
+ historical rounded format.
+ </p></div><p>
+ For compatibility with output generated by older versions
+ of <span class="productname">PostgreSQL</span>, and to allow the output
+ precision to be reduced, the <a class="xref" href="runtime-config-client.html#GUC-EXTRA-FLOAT-DIGITS">extra_float_digits</a>
+ parameter can be used to select rounded decimal output instead. Setting a
+ value of 0 restores the previous default of rounding the value to 6
+ (for <code class="type">float4</code>) or 15 (for <code class="type">float8</code>)
+ significant decimal digits. Setting a negative value reduces the number
+ of digits further; for example -2 would round output to 4 or 13 digits
+ respectively.
+ </p><p>
+ Any value of <a class="xref" href="runtime-config-client.html#GUC-EXTRA-FLOAT-DIGITS">extra_float_digits</a> greater than 0
+ selects the shortest-precise format.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Applications that wanted precise values have historically had to set
+ <a class="xref" href="runtime-config-client.html#GUC-EXTRA-FLOAT-DIGITS">extra_float_digits</a> to 3 to obtain them. For
+ maximum compatibility between versions, they should continue to do so.
+ </p></div><a id="id-1.5.7.9.8.15" class="indexterm"></a><a id="id-1.5.7.9.8.16" class="indexterm"></a><p>
+ In addition to ordinary numeric values, the floating-point types
+ have several special values:
+</p><div class="literallayout"><p><br />
+<code class="literal">Infinity</code><br />
+<code class="literal">-Infinity</code><br />
+<code class="literal">NaN</code><br />
+</p></div><p>
+ These represent the IEEE 754 special values
+ <span class="quote">“<span class="quote">infinity</span>”</span>, <span class="quote">“<span class="quote">negative infinity</span>”</span>, and
+ <span class="quote">“<span class="quote">not-a-number</span>”</span>, respectively. When writing these values
+ as constants in an SQL command, you must put quotes around them,
+ for example <code class="literal">UPDATE table SET x = '-Infinity'</code>. On input,
+ these strings are recognized in a case-insensitive manner.
+ The infinity values can alternatively be spelled <code class="literal">inf</code>
+ and <code class="literal">-inf</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ IEEE 754 specifies that <code class="literal">NaN</code> should not compare equal
+ to any other floating-point value (including <code class="literal">NaN</code>).
+ In order to allow floating-point values to be sorted and used
+ in tree-based indexes, <span class="productname">PostgreSQL</span> treats
+ <code class="literal">NaN</code> values as equal, and greater than all
+ non-<code class="literal">NaN</code> values.
+ </p></div><p>
+ <span class="productname">PostgreSQL</span> also supports the SQL-standard
+ notations <code class="type">float</code> and
+ <code class="type">float(<em class="replaceable"><code>p</code></em>)</code> for specifying
+ inexact numeric types. Here, <em class="replaceable"><code>p</code></em> specifies
+ the minimum acceptable precision in <span class="emphasis"><em>binary</em></span> digits.
+ <span class="productname">PostgreSQL</span> accepts
+ <code class="type">float(1)</code> to <code class="type">float(24)</code> as selecting the
+ <code class="type">real</code> type, while
+ <code class="type">float(25)</code> to <code class="type">float(53)</code> select
+ <code class="type">double precision</code>. Values of <em class="replaceable"><code>p</code></em>
+ outside the allowed range draw an error.
+ <code class="type">float</code> with no precision specified is taken to mean
+ <code class="type">double precision</code>.
+ </p></div><div class="sect2" id="DATATYPE-SERIAL"><div class="titlepage"><div><div><h3 class="title">8.1.4. Serial Types</h3></div></div></div><a id="id-1.5.7.9.9.2" class="indexterm"></a><a id="id-1.5.7.9.9.3" class="indexterm"></a><a id="id-1.5.7.9.9.4" class="indexterm"></a><a id="id-1.5.7.9.9.5" class="indexterm"></a><a id="id-1.5.7.9.9.6" class="indexterm"></a><a id="id-1.5.7.9.9.7" class="indexterm"></a><a id="id-1.5.7.9.9.8" class="indexterm"></a><a id="id-1.5.7.9.9.9" class="indexterm"></a><div class="note"><h3 class="title">Note</h3><p>
+ This section describes a PostgreSQL-specific way to create an
+ autoincrementing column. Another way is to use the SQL-standard
+ identity column feature, described at <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>.
+ </p></div><p>
+ The data types <code class="type">smallserial</code>, <code class="type">serial</code> and
+ <code class="type">bigserial</code> are not true types, but merely
+ a notational convenience for creating unique identifier columns
+ (similar to the <code class="literal">AUTO_INCREMENT</code> property
+ supported by some other databases). In the current
+ implementation, specifying:
+
+</p><pre class="programlisting">
+CREATE TABLE <em class="replaceable"><code>tablename</code></em> (
+ <em class="replaceable"><code>colname</code></em> SERIAL
+);
+</pre><p>
+
+ is equivalent to specifying:
+
+</p><pre class="programlisting">
+CREATE SEQUENCE <em class="replaceable"><code>tablename</code></em>_<em class="replaceable"><code>colname</code></em>_seq AS integer;
+CREATE TABLE <em class="replaceable"><code>tablename</code></em> (
+ <em class="replaceable"><code>colname</code></em> integer NOT NULL DEFAULT nextval('<em class="replaceable"><code>tablename</code></em>_<em class="replaceable"><code>colname</code></em>_seq')
+);
+ALTER SEQUENCE <em class="replaceable"><code>tablename</code></em>_<em class="replaceable"><code>colname</code></em>_seq OWNED BY <em class="replaceable"><code>tablename</code></em>.<em class="replaceable"><code>colname</code></em>;
+</pre><p>
+
+ Thus, we have created an integer column and arranged for its default
+ values to be assigned from a sequence generator. A <code class="literal">NOT NULL</code>
+ constraint is applied to ensure that a null value cannot be
+ inserted. (In most cases you would also want to attach a
+ <code class="literal">UNIQUE</code> or <code class="literal">PRIMARY KEY</code> constraint to prevent
+ duplicate values from being inserted by accident, but this is
+ not automatic.) Lastly, the sequence is marked as <span class="quote">“<span class="quote">owned by</span>”</span>
+ the column, so that it will be dropped if the column or table is dropped.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Because <code class="type">smallserial</code>, <code class="type">serial</code> and
+ <code class="type">bigserial</code> are implemented using sequences, there may
+ be "holes" or gaps in the sequence of values which appears in the
+ column, even if no rows are ever deleted. A value allocated
+ from the sequence is still "used up" even if a row containing that
+ value is never successfully inserted into the table column. This
+ may happen, for example, if the inserting transaction rolls back.
+ See <code class="literal">nextval()</code> in <a class="xref" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Section 9.17</a>
+ for details.
+ </p></div><p>
+ To insert the next value of the sequence into the <code class="type">serial</code>
+ column, specify that the <code class="type">serial</code>
+ column should be assigned its default value. This can be done
+ either by excluding the column from the list of columns in
+ the <code class="command">INSERT</code> statement, or through the use of
+ the <code class="literal">DEFAULT</code> key word.
+ </p><p>
+ The type names <code class="type">serial</code> and <code class="type">serial4</code> are
+ equivalent: both create <code class="type">integer</code> columns. The type
+ names <code class="type">bigserial</code> and <code class="type">serial8</code> work
+ the same way, except that they create a <code class="type">bigint</code>
+ column. <code class="type">bigserial</code> should be used if you anticipate
+ the use of more than 2<sup>31</sup> identifiers over the
+ lifetime of the table. The type names <code class="type">smallserial</code> and
+ <code class="type">serial2</code> also work the same way, except that they
+ create a <code class="type">smallint</code> column.
+ </p><p>
+ The sequence created for a <code class="type">serial</code> column is
+ automatically dropped when the owning column is dropped.
+ You can drop the sequence without dropping the column, but this
+ will force removal of the column default expression.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype.html" title="Chapter 8. Data Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-money.html" title="8.2. Monetary Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 8. Data Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.2. Monetary Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-oid.html b/doc/src/sgml/html/datatype-oid.html
new file mode 100644
index 0000000..b658e82
--- /dev/null
+++ b/doc/src/sgml/html/datatype-oid.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.19. Object Identifier Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="domains.html" title="8.18. Domain Types" /><link rel="next" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.19. Object Identifier Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="domains.html" title="8.18. Domain Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-OID"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.19. Object Identifier Types</h2></div></div></div><a id="id-1.5.7.27.2" class="indexterm"></a><a id="id-1.5.7.27.3" class="indexterm"></a><a id="id-1.5.7.27.4" class="indexterm"></a><a id="id-1.5.7.27.5" class="indexterm"></a><a id="id-1.5.7.27.6" class="indexterm"></a><a id="id-1.5.7.27.7" class="indexterm"></a><a id="id-1.5.7.27.8" class="indexterm"></a><a id="id-1.5.7.27.9" class="indexterm"></a><a id="id-1.5.7.27.10" class="indexterm"></a><a id="id-1.5.7.27.11" class="indexterm"></a><a id="id-1.5.7.27.12" class="indexterm"></a><a id="id-1.5.7.27.13" class="indexterm"></a><a id="id-1.5.7.27.14" class="indexterm"></a><a id="id-1.5.7.27.15" class="indexterm"></a><a id="id-1.5.7.27.16" class="indexterm"></a><a id="id-1.5.7.27.17" class="indexterm"></a><a id="id-1.5.7.27.18" class="indexterm"></a><p>
+ Object identifiers (OIDs) are used internally by
+ <span class="productname">PostgreSQL</span> as primary keys for various
+ system tables.
+ Type <code class="type">oid</code> represents an object identifier. There are also
+ several alias types for <code class="type">oid</code>, each
+ named <code class="type">reg<em class="replaceable"><code>something</code></em></code>.
+ <a class="xref" href="datatype-oid.html#DATATYPE-OID-TABLE" title="Table 8.26. Object Identifier Types">Table 8.26</a> shows an
+ overview.
+ </p><p>
+ The <code class="type">oid</code> type is currently implemented as an unsigned
+ four-byte integer. Therefore, it is not large enough to provide
+ database-wide uniqueness in large databases, or even in large
+ individual tables.
+ </p><p>
+ The <code class="type">oid</code> type itself has few operations beyond comparison.
+ It can be cast to integer, however, and then manipulated using the
+ standard integer operators. (Beware of possible
+ signed-versus-unsigned confusion if you do this.)
+ </p><p>
+ The OID alias types have no operations of their own except
+ for specialized input and output routines. These routines are able
+ to accept and display symbolic names for system objects, rather than
+ the raw numeric value that type <code class="type">oid</code> would use. The alias
+ types allow simplified lookup of OID values for objects. For example,
+ to examine the <code class="structname">pg_attribute</code> rows related to a table
+ <code class="literal">mytable</code>, one could write:
+</p><pre class="programlisting">
+SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;
+</pre><p>
+ rather than:
+</p><pre class="programlisting">
+SELECT * FROM pg_attribute
+ WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');
+</pre><p>
+ While that doesn't look all that bad by itself, it's still oversimplified.
+ A far more complicated sub-select would be needed to
+ select the right OID if there are multiple tables named
+ <code class="literal">mytable</code> in different schemas.
+ The <code class="type">regclass</code> input converter handles the table lookup according
+ to the schema path setting, and so it does the <span class="quote">“<span class="quote">right thing</span>”</span>
+ automatically. Similarly, casting a table's OID to
+ <code class="type">regclass</code> is handy for symbolic display of a numeric OID.
+ </p><div class="table" id="DATATYPE-OID-TABLE"><p class="title"><strong>Table 8.26. Object Identifier Types</strong></p><div class="table-contents"><table class="table" summary="Object Identifier Types" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>References</th><th>Description</th><th>Value Example</th></tr></thead><tbody><tr><td><code class="type">oid</code></td><td>any</td><td>numeric object identifier</td><td><code class="literal">564182</code></td></tr><tr><td><code class="type">regclass</code></td><td><code class="structname">pg_class</code></td><td>relation name</td><td><code class="literal">pg_type</code></td></tr><tr><td><code class="type">regcollation</code></td><td><code class="structname">pg_collation</code></td><td>collation name</td><td><code class="literal">"POSIX"</code></td></tr><tr><td><code class="type">regconfig</code></td><td><code class="structname">pg_ts_config</code></td><td>text search configuration</td><td><code class="literal">english</code></td></tr><tr><td><code class="type">regdictionary</code></td><td><code class="structname">pg_ts_dict</code></td><td>text search dictionary</td><td><code class="literal">simple</code></td></tr><tr><td><code class="type">regnamespace</code></td><td><code class="structname">pg_namespace</code></td><td>namespace name</td><td><code class="literal">pg_catalog</code></td></tr><tr><td><code class="type">regoper</code></td><td><code class="structname">pg_operator</code></td><td>operator name</td><td><code class="literal">+</code></td></tr><tr><td><code class="type">regoperator</code></td><td><code class="structname">pg_operator</code></td><td>operator with argument types</td><td><code class="literal">*(integer,​integer)</code>
+ or <code class="literal">-(NONE,​integer)</code></td></tr><tr><td><code class="type">regproc</code></td><td><code class="structname">pg_proc</code></td><td>function name</td><td><code class="literal">sum</code></td></tr><tr><td><code class="type">regprocedure</code></td><td><code class="structname">pg_proc</code></td><td>function with argument types</td><td><code class="literal">sum(int4)</code></td></tr><tr><td><code class="type">regrole</code></td><td><code class="structname">pg_authid</code></td><td>role name</td><td><code class="literal">smithee</code></td></tr><tr><td><code class="type">regtype</code></td><td><code class="structname">pg_type</code></td><td>data type name</td><td><code class="literal">integer</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ All of the OID alias types for objects that are grouped by namespace
+ accept schema-qualified names, and will
+ display schema-qualified names on output if the object would not
+ be found in the current search path without being qualified.
+ For example, <code class="literal">myschema.mytable</code> is acceptable input
+ for <code class="type">regclass</code> (if there is such a table). That value
+ might be output as <code class="literal">myschema.mytable</code>, or
+ just <code class="literal">mytable</code>, depending on the current search path.
+ The <code class="type">regproc</code> and <code class="type">regoper</code> alias types will only
+ accept input names that are unique (not overloaded), so they are
+ of limited use; for most uses <code class="type">regprocedure</code> or
+ <code class="type">regoperator</code> are more appropriate. For <code class="type">regoperator</code>,
+ unary operators are identified by writing <code class="literal">NONE</code> for the unused
+ operand.
+ </p><p>
+ The input functions for these types allow whitespace between tokens,
+ and will fold upper-case letters to lower case, except within double
+ quotes; this is done to make the syntax rules similar to the way
+ object names are written in SQL. Conversely, the output functions
+ will use double quotes if needed to make the output be a valid SQL
+ identifier. For example, the OID of a function
+ named <code class="literal">Foo</code> (with upper case <code class="literal">F</code>)
+ taking two integer arguments could be entered as
+ <code class="literal">' "Foo" ( int, integer ) '::regprocedure</code>. The
+ output would look like <code class="literal">"Foo"(integer,integer)</code>.
+ Both the function name and the argument type names could be
+ schema-qualified, too.
+ </p><p>
+ Many built-in <span class="productname">PostgreSQL</span> functions accept
+ the OID of a table, or another kind of database object, and for
+ convenience are declared as taking <code class="type">regclass</code> (or the
+ appropriate OID alias type). This means you do not have to look up
+ the object's OID by hand, but can just enter its name as a string
+ literal. For example, the <code class="function">nextval(regclass)</code> function
+ takes a sequence relation's OID, so you could call it like this:
+</p><pre class="programlisting">
+nextval('foo') <em class="lineannotation"><span class="lineannotation">operates on sequence <code class="literal">foo</code></span></em>
+nextval('FOO') <em class="lineannotation"><span class="lineannotation">same as above</span></em>
+nextval('"Foo"') <em class="lineannotation"><span class="lineannotation">operates on sequence <code class="literal">Foo</code></span></em>
+nextval('myschema.foo') <em class="lineannotation"><span class="lineannotation">operates on <code class="literal">myschema.foo</code></span></em>
+nextval('"myschema".foo') <em class="lineannotation"><span class="lineannotation">same as above</span></em>
+nextval('foo') <em class="lineannotation"><span class="lineannotation">searches search path for <code class="literal">foo</code></span></em>
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When you write the argument of such a function as an unadorned
+ literal string, it becomes a constant of type <code class="type">regclass</code>
+ (or the appropriate type).
+ Since this is really just an OID, it will track the originally
+ identified object despite later renaming, schema reassignment,
+ etc. This <span class="quote">“<span class="quote">early binding</span>”</span> behavior is usually desirable for
+ object references in column defaults and views. But sometimes you might
+ want <span class="quote">“<span class="quote">late binding</span>”</span> where the object reference is resolved
+ at run time. To get late-binding behavior, force the constant to be
+ stored as a <code class="type">text</code> constant instead of <code class="type">regclass</code>:
+</p><pre class="programlisting">
+nextval('foo'::text) <em class="lineannotation"><span class="lineannotation"><code class="literal">foo</code> is looked up at runtime</span></em>
+</pre><p>
+ The <code class="function">to_regclass()</code> function and its siblings
+ can also be used to perform run-time lookups. See
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE" title="Table 9.71. System Catalog Information Functions">Table 9.71</a>.
+ </p></div><p>
+ Another practical example of use of <code class="type">regclass</code>
+ is to look up the OID of a table listed in
+ the <code class="literal">information_schema</code> views, which don't supply
+ such OIDs directly. One might for example wish to call
+ the <code class="function">pg_relation_size()</code> function, which requires
+ the table OID. Taking the above rules into account, the correct way
+ to do that is
+</p><pre class="programlisting">
+SELECT table_schema, table_name,
+ pg_relation_size((quote_ident(table_schema) || '.' ||
+ quote_ident(table_name))::regclass)
+FROM information_schema.tables
+WHERE ...
+</pre><p>
+ The <code class="function">quote_ident()</code> function will take care of
+ double-quoting the identifiers where needed. The seemingly easier
+</p><pre class="programlisting">
+SELECT pg_relation_size(table_name)
+FROM information_schema.tables
+WHERE ...
+</pre><p>
+ is <span class="emphasis"><em>not recommended</em></span>, because it will fail for
+ tables that are outside your search path or have names that require
+ quoting.
+ </p><p>
+ An additional property of most of the OID alias types is the creation of
+ dependencies. If a
+ constant of one of these types appears in a stored expression
+ (such as a column default expression or view), it creates a dependency
+ on the referenced object. For example, if a column has a default
+ expression <code class="literal">nextval('my_seq'::regclass)</code>,
+ <span class="productname">PostgreSQL</span>
+ understands that the default expression depends on the sequence
+ <code class="literal">my_seq</code>, so the system will not let the sequence
+ be dropped without first removing the default expression. The
+ alternative of <code class="literal">nextval('my_seq'::text)</code> does not
+ create a dependency.
+ (<code class="type">regrole</code> is an exception to this property. Constants of this
+ type are not allowed in stored expressions.)
+ </p><p>
+ Another identifier type used by the system is <code class="type">xid</code>, or transaction
+ (abbreviated <abbr class="abbrev">xact</abbr>) identifier. This is the data type of the system columns
+ <code class="structfield">xmin</code> and <code class="structfield">xmax</code>. Transaction identifiers are 32-bit quantities.
+ In some contexts, a 64-bit variant <code class="type">xid8</code> is used. Unlike
+ <code class="type">xid</code> values, <code class="type">xid8</code> values increase strictly
+ monotonically and cannot be reused in the lifetime of a database cluster.
+ </p><p>
+ A third identifier type used by the system is <code class="type">cid</code>, or
+ command identifier. This is the data type of the system columns
+ <code class="structfield">cmin</code> and <code class="structfield">cmax</code>. Command identifiers are also 32-bit quantities.
+ </p><p>
+ A final identifier type used by the system is <code class="type">tid</code>, or tuple
+ identifier (row identifier). This is the data type of the system column
+ <code class="structfield">ctid</code>. A tuple ID is a pair
+ (block number, tuple index within block) that identifies the
+ physical location of the row within its table.
+ </p><p>
+ (The system columns are further explained in <a class="xref" href="ddl-system-columns.html" title="5.5. System Columns">Section 5.5</a>.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="domains.html" title="8.18. Domain Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.18. Domain Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.20. <code class="type">pg_lsn</code> Type</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-pg-lsn.html b/doc/src/sgml/html/datatype-pg-lsn.html
new file mode 100644
index 0000000..bb158d0
--- /dev/null
+++ b/doc/src/sgml/html/datatype-pg-lsn.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.20. pg_lsn Type</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-oid.html" title="8.19. Object Identifier Types" /><link rel="next" href="datatype-pseudo.html" title="8.21. Pseudo-Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.20. <code class="type">pg_lsn</code> Type</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-oid.html" title="8.19. Object Identifier Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-pseudo.html" title="8.21. Pseudo-Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-PG-LSN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.20. <code class="type">pg_lsn</code> Type</h2></div></div></div><a id="id-1.5.7.28.2" class="indexterm"></a><p>
+ The <code class="type">pg_lsn</code> data type can be used to store LSN (Log Sequence
+ Number) data which is a pointer to a location in the WAL. This type is a
+ representation of <code class="type">XLogRecPtr</code> and an internal system type of
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ Internally, an LSN is a 64-bit integer, representing a byte position in
+ the write-ahead log stream. It is printed as two hexadecimal numbers of
+ up to 8 digits each, separated by a slash; for example,
+ <code class="literal">16/B374D848</code>. The <code class="type">pg_lsn</code> type supports the
+ standard comparison operators, like <code class="literal">=</code> and
+ <code class="literal">&gt;</code>. Two LSNs can be subtracted using the
+ <code class="literal">-</code> operator; the result is the number of bytes separating
+ those write-ahead log locations. Also the number of bytes can be
+ added into and subtracted from LSN using the
+ <code class="literal">+(pg_lsn,numeric)</code> and
+ <code class="literal">-(pg_lsn,numeric)</code> operators, respectively. Note that
+ the calculated LSN should be in the range of <code class="type">pg_lsn</code> type,
+ i.e., between <code class="literal">0/0</code> and
+ <code class="literal">FFFFFFFF/FFFFFFFF</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-oid.html" title="8.19. Object Identifier Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-pseudo.html" title="8.21. Pseudo-Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.19. Object Identifier Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.21. Pseudo-Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-pseudo.html b/doc/src/sgml/html/datatype-pseudo.html
new file mode 100644
index 0000000..768215b
--- /dev/null
+++ b/doc/src/sgml/html/datatype-pseudo.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.21. Pseudo-Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type" /><link rel="next" href="functions.html" title="Chapter 9. Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.21. Pseudo-Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions.html" title="Chapter 9. Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-PSEUDO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.21. Pseudo-Types</h2></div></div></div><a id="id-1.5.7.29.2" class="indexterm"></a><a id="id-1.5.7.29.3" class="indexterm"></a><a id="id-1.5.7.29.4" class="indexterm"></a><a id="id-1.5.7.29.5" class="indexterm"></a><a id="id-1.5.7.29.6" class="indexterm"></a><a id="id-1.5.7.29.7" class="indexterm"></a><a id="id-1.5.7.29.8" class="indexterm"></a><a id="id-1.5.7.29.9" class="indexterm"></a><a id="id-1.5.7.29.10" class="indexterm"></a><a id="id-1.5.7.29.11" class="indexterm"></a><a id="id-1.5.7.29.12" class="indexterm"></a><a id="id-1.5.7.29.13" class="indexterm"></a><a id="id-1.5.7.29.14" class="indexterm"></a><a id="id-1.5.7.29.15" class="indexterm"></a><a id="id-1.5.7.29.16" class="indexterm"></a><a id="id-1.5.7.29.17" class="indexterm"></a><a id="id-1.5.7.29.18" class="indexterm"></a><a id="id-1.5.7.29.19" class="indexterm"></a><a id="id-1.5.7.29.20" class="indexterm"></a><a id="id-1.5.7.29.21" class="indexterm"></a><a id="id-1.5.7.29.22" class="indexterm"></a><a id="id-1.5.7.29.23" class="indexterm"></a><a id="id-1.5.7.29.24" class="indexterm"></a><a id="id-1.5.7.29.25" class="indexterm"></a><a id="id-1.5.7.29.26" class="indexterm"></a><p>
+ The <span class="productname">PostgreSQL</span> type system contains a
+ number of special-purpose entries that are collectively called
+ <em class="firstterm">pseudo-types</em>. A pseudo-type cannot be used as a
+ column data type, but it can be used to declare a function's
+ argument or result type. Each of the available pseudo-types is
+ useful in situations where a function's behavior does not
+ correspond to simply taking or returning a value of a specific
+ <acronym class="acronym">SQL</acronym> data type. <a class="xref" href="datatype-pseudo.html#DATATYPE-PSEUDOTYPES-TABLE" title="Table 8.27. Pseudo-Types">Table 8.27</a> lists the existing
+ pseudo-types.
+ </p><div class="table" id="DATATYPE-PSEUDOTYPES-TABLE"><p class="title"><strong>Table 8.27. Pseudo-Types</strong></p><div class="table-contents"><table class="table" summary="Pseudo-Types" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">any</code></td><td>Indicates that a function accepts any input data type.</td></tr><tr><td><code class="type">anyelement</code></td><td>Indicates that a function accepts any data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>).</td></tr><tr><td><code class="type">anyarray</code></td><td>Indicates that a function accepts any array data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>).</td></tr><tr><td><code class="type">anynonarray</code></td><td>Indicates that a function accepts any non-array data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>).</td></tr><tr><td><code class="type">anyenum</code></td><td>Indicates that a function accepts any enum data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a> and
+ <a class="xref" href="datatype-enum.html" title="8.7. Enumerated Types">Section 8.7</a>).</td></tr><tr><td><code class="type">anyrange</code></td><td>Indicates that a function accepts any range data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a> and
+ <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>).</td></tr><tr><td><code class="type">anymultirange</code></td><td>Indicates that a function accepts any multirange data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a> and
+ <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>).</td></tr><tr><td><code class="type">anycompatible</code></td><td>Indicates that a function accepts any data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>).</td></tr><tr><td><code class="type">anycompatiblearray</code></td><td>Indicates that a function accepts any array data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>).</td></tr><tr><td><code class="type">anycompatiblenonarray</code></td><td>Indicates that a function accepts any non-array data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>).</td></tr><tr><td><code class="type">anycompatiblerange</code></td><td>Indicates that a function accepts any range data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a> and
+ <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>).</td></tr><tr><td><code class="type">anycompatiblemultirange</code></td><td>Indicates that a function accepts any multirange data type,
+ with automatic promotion of multiple arguments to a common data type
+ (see <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a> and
+ <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>).</td></tr><tr><td><code class="type">cstring</code></td><td>Indicates that a function accepts or returns a null-terminated C string.</td></tr><tr><td><code class="type">internal</code></td><td>Indicates that a function accepts or returns a server-internal
+ data type.</td></tr><tr><td><code class="type">language_handler</code></td><td>A procedural language call handler is declared to return <code class="type">language_handler</code>.</td></tr><tr><td><code class="type">fdw_handler</code></td><td>A foreign-data wrapper handler is declared to return <code class="type">fdw_handler</code>.</td></tr><tr><td><code class="type">table_am_handler</code></td><td>A table access method handler is declared to return <code class="type">table_am_handler</code>.</td></tr><tr><td><code class="type">index_am_handler</code></td><td>An index access method handler is declared to return <code class="type">index_am_handler</code>.</td></tr><tr><td><code class="type">tsm_handler</code></td><td>A tablesample method handler is declared to return <code class="type">tsm_handler</code>.</td></tr><tr><td><code class="type">record</code></td><td>Identifies a function taking or returning an unspecified row type.</td></tr><tr><td><code class="type">trigger</code></td><td>A trigger function is declared to return <code class="type">trigger.</code></td></tr><tr><td><code class="type">event_trigger</code></td><td>An event trigger function is declared to return <code class="type">event_trigger.</code></td></tr><tr><td><code class="type">pg_ddl_command</code></td><td>Identifies a representation of DDL commands that is available to event triggers.</td></tr><tr><td><code class="type">void</code></td><td>Indicates that a function returns no value.</td></tr><tr><td><code class="type">unknown</code></td><td>Identifies a not-yet-resolved type, e.g., of an undecorated
+ string literal.</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Functions coded in C (whether built-in or dynamically loaded) can be
+ declared to accept or return any of these pseudo-types. It is up to
+ the function author to ensure that the function will behave safely
+ when a pseudo-type is used as an argument type.
+ </p><p>
+ Functions coded in procedural languages can use pseudo-types only as
+ allowed by their implementation languages. At present most procedural
+ languages forbid use of a pseudo-type as an argument type, and allow
+ only <code class="type">void</code> and <code class="type">record</code> as a result type (plus
+ <code class="type">trigger</code> or <code class="type">event_trigger</code> when the function is used
+ as a trigger or event trigger). Some also support polymorphic functions
+ using the polymorphic pseudo-types, which are shown above and discussed
+ in detail in <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>.
+ </p><p>
+ The <code class="type">internal</code> pseudo-type is used to declare functions
+ that are meant only to be called internally by the database
+ system, and not by direct invocation in an <acronym class="acronym">SQL</acronym>
+ query. If a function has at least one <code class="type">internal</code>-type
+ argument then it cannot be called from <acronym class="acronym">SQL</acronym>. To
+ preserve the type safety of this restriction it is important to
+ follow this coding rule: do not create any function that is
+ declared to return <code class="type">internal</code> unless it has at least one
+ <code class="type">internal</code> argument.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions.html" title="Chapter 9. Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.20. <code class="type">pg_lsn</code> Type </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 9. Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-textsearch.html b/doc/src/sgml/html/datatype-textsearch.html
new file mode 100644
index 0000000..4b9a4b3
--- /dev/null
+++ b/doc/src/sgml/html/datatype-textsearch.html
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.11. Text Search Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-bit.html" title="8.10. Bit String Types" /><link rel="next" href="datatype-uuid.html" title="8.12. UUID Type" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.11. Text Search Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-bit.html" title="8.10. Bit String Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-uuid.html" title="8.12. UUID Type">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-TEXTSEARCH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.11. Text Search Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-textsearch.html#DATATYPE-TSVECTOR">8.11.1. <code class="type">tsvector</code></a></span></dt><dt><span class="sect2"><a href="datatype-textsearch.html#DATATYPE-TSQUERY">8.11.2. <code class="type">tsquery</code></a></span></dt></dl></div><a id="id-1.5.7.19.2" class="indexterm"></a><a id="id-1.5.7.19.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides two data types that
+ are designed to support full text search, which is the activity of
+ searching through a collection of natural-language <em class="firstterm">documents</em>
+ to locate those that best match a <em class="firstterm">query</em>.
+ The <code class="type">tsvector</code> type represents a document in a form optimized
+ for text search; the <code class="type">tsquery</code> type similarly represents
+ a text query.
+ <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> provides a detailed explanation of this
+ facility, and <a class="xref" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators">Section 9.13</a> summarizes the
+ related functions and operators.
+ </p><div class="sect2" id="DATATYPE-TSVECTOR"><div class="titlepage"><div><div><h3 class="title">8.11.1. <code class="type">tsvector</code></h3></div></div></div><a id="id-1.5.7.19.5.2" class="indexterm"></a><p>
+ A <code class="type">tsvector</code> value is a sorted list of distinct
+ <em class="firstterm">lexemes</em>, which are words that have been
+ <em class="firstterm">normalized</em> to merge different variants of the same word
+ (see <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for details). Sorting and
+ duplicate-elimination are done automatically during input, as shown in
+ this example:
+
+</p><pre class="programlisting">
+SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector;
+ tsvector
+----------------------------------------------------
+ 'a' 'and' 'ate' 'cat' 'fat' 'mat' 'on' 'rat' 'sat'
+</pre><p>
+
+ To represent
+ lexemes containing whitespace or punctuation, surround them with quotes:
+
+</p><pre class="programlisting">
+SELECT $$the lexeme ' ' contains spaces$$::tsvector;
+ tsvector
+-------------------------------------------
+ ' ' 'contains' 'lexeme' 'spaces' 'the'
+</pre><p>
+
+ (We use dollar-quoted string literals in this example and the next one
+ to avoid the confusion of having to double quote marks within the
+ literals.) Embedded quotes and backslashes must be doubled:
+
+</p><pre class="programlisting">
+SELECT $$the lexeme 'Joe''s' contains a quote$$::tsvector;
+ tsvector
+------------------------------------------------
+ 'Joe''s' 'a' 'contains' 'lexeme' 'quote' 'the'
+</pre><p>
+
+ Optionally, integer <em class="firstterm">positions</em>
+ can be attached to lexemes:
+
+</p><pre class="programlisting">
+SELECT 'a:1 fat:2 cat:3 sat:4 on:5 a:6 mat:7 and:8 ate:9 a:10 fat:11 rat:12'::tsvector;
+ tsvector
+-------------------------------------------------------------------​------------
+ 'a':1,6,10 'and':8 'ate':9 'cat':3 'fat':2,11 'mat':7 'on':5 'rat':12 'sat':4
+</pre><p>
+
+ A position normally indicates the source word's location in the
+ document. Positional information can be used for
+ <em class="firstterm">proximity ranking</em>. Position values can
+ range from 1 to 16383; larger numbers are silently set to 16383.
+ Duplicate positions for the same lexeme are discarded.
+ </p><p>
+ Lexemes that have positions can further be labeled with a
+ <em class="firstterm">weight</em>, which can be <code class="literal">A</code>,
+ <code class="literal">B</code>, <code class="literal">C</code>, or <code class="literal">D</code>.
+ <code class="literal">D</code> is the default and hence is not shown on output:
+
+</p><pre class="programlisting">
+SELECT 'a:1A fat:2B,4C cat:5D'::tsvector;
+ tsvector
+----------------------------
+ 'a':1A 'cat':5 'fat':2B,4C
+</pre><p>
+
+ Weights are typically used to reflect document structure, for example
+ by marking title words differently from body words. Text search
+ ranking functions can assign different priorities to the different
+ weight markers.
+ </p><p>
+ It is important to understand that the
+ <code class="type">tsvector</code> type itself does not perform any word
+ normalization; it assumes the words it is given are normalized
+ appropriately for the application. For example,
+
+</p><pre class="programlisting">
+SELECT 'The Fat Rats'::tsvector;
+ tsvector
+--------------------
+ 'Fat' 'Rats' 'The'
+</pre><p>
+
+ For most English-text-searching applications the above words would
+ be considered non-normalized, but <code class="type">tsvector</code> doesn't care.
+ Raw document text should usually be passed through
+ <code class="function">to_tsvector</code> to normalize the words appropriately
+ for searching:
+
+</p><pre class="programlisting">
+SELECT to_tsvector('english', 'The Fat Rats');
+ to_tsvector
+-----------------
+ 'fat':2 'rat':3
+</pre><p>
+
+ Again, see <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for more detail.
+ </p></div><div class="sect2" id="DATATYPE-TSQUERY"><div class="titlepage"><div><div><h3 class="title">8.11.2. <code class="type">tsquery</code></h3></div></div></div><a id="id-1.5.7.19.6.2" class="indexterm"></a><p>
+ A <code class="type">tsquery</code> value stores lexemes that are to be
+ searched for, and can combine them using the Boolean operators
+ <code class="literal">&amp;</code> (AND), <code class="literal">|</code> (OR), and
+ <code class="literal">!</code> (NOT), as well as the phrase search operator
+ <code class="literal">&lt;-&gt;</code> (FOLLOWED BY). There is also a variant
+ <code class="literal">&lt;<em class="replaceable"><code>N</code></em>&gt;</code> of the FOLLOWED BY
+ operator, where <em class="replaceable"><code>N</code></em> is an integer constant that
+ specifies the distance between the two lexemes being searched
+ for. <code class="literal">&lt;-&gt;</code> is equivalent to <code class="literal">&lt;1&gt;</code>.
+ </p><p>
+ Parentheses can be used to enforce grouping of these operators.
+ In the absence of parentheses, <code class="literal">!</code> (NOT) binds most tightly,
+ <code class="literal">&lt;-&gt;</code> (FOLLOWED BY) next most tightly, then
+ <code class="literal">&amp;</code> (AND), with <code class="literal">|</code> (OR) binding
+ the least tightly.
+ </p><p>
+ Here are some examples:
+
+</p><pre class="programlisting">
+SELECT 'fat &amp; rat'::tsquery;
+ tsquery
+---------------
+ 'fat' &amp; 'rat'
+
+SELECT 'fat &amp; (rat | cat)'::tsquery;
+ tsquery
+---------------------------
+ 'fat' &amp; ( 'rat' | 'cat' )
+
+SELECT 'fat &amp; rat &amp; ! cat'::tsquery;
+ tsquery
+------------------------
+ 'fat' &amp; 'rat' &amp; !'cat'
+</pre><p>
+ </p><p>
+ Optionally, lexemes in a <code class="type">tsquery</code> can be labeled with
+ one or more weight letters, which restricts them to match only
+ <code class="type">tsvector</code> lexemes with one of those weights:
+
+</p><pre class="programlisting">
+SELECT 'fat:ab &amp; cat'::tsquery;
+ tsquery
+------------------
+ 'fat':AB &amp; 'cat'
+</pre><p>
+ </p><p>
+ Also, lexemes in a <code class="type">tsquery</code> can be labeled with <code class="literal">*</code>
+ to specify prefix matching:
+</p><pre class="programlisting">
+SELECT 'super:*'::tsquery;
+ tsquery
+-----------
+ 'super':*
+</pre><p>
+ This query will match any word in a <code class="type">tsvector</code> that begins
+ with <span class="quote">“<span class="quote">super</span>”</span>.
+ </p><p>
+ Quoting rules for lexemes are the same as described previously for
+ lexemes in <code class="type">tsvector</code>; and, as with <code class="type">tsvector</code>,
+ any required normalization of words must be done before converting
+ to the <code class="type">tsquery</code> type. The <code class="function">to_tsquery</code>
+ function is convenient for performing such normalization:
+
+</p><pre class="programlisting">
+SELECT to_tsquery('Fat:ab &amp; Cats');
+ to_tsquery
+------------------
+ 'fat':AB &amp; 'cat'
+</pre><p>
+
+ Note that <code class="function">to_tsquery</code> will process prefixes in the same way
+ as other words, which means this comparison returns true:
+
+</p><pre class="programlisting">
+SELECT to_tsvector( 'postgraduate' ) @@ to_tsquery( 'postgres:*' );
+ ?column?
+----------
+ t
+</pre><p>
+ because <code class="literal">postgres</code> gets stemmed to <code class="literal">postgr</code>:
+</p><pre class="programlisting">
+SELECT to_tsvector( 'postgraduate' ), to_tsquery( 'postgres:*' );
+ to_tsvector | to_tsquery
+---------------+------------
+ 'postgradu':1 | 'postgr':*
+</pre><p>
+ which will match the stemmed form of <code class="literal">postgraduate</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-bit.html" title="8.10. Bit String Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-uuid.html" title="8.12. UUID Type">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.10. Bit String Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.12. <acronym class="acronym">UUID</acronym> Type</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-uuid.html b/doc/src/sgml/html/datatype-uuid.html
new file mode 100644
index 0000000..54b62ec
--- /dev/null
+++ b/doc/src/sgml/html/datatype-uuid.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.12. UUID Type</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-textsearch.html" title="8.11. Text Search Types" /><link rel="next" href="datatype-xml.html" title="8.13. XML Type" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.12. <acronym class="acronym">UUID</acronym> Type</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-textsearch.html" title="8.11. Text Search Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-xml.html" title="8.13. XML Type">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-UUID"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.12. <acronym class="acronym">UUID</acronym> Type</h2></div></div></div><a id="id-1.5.7.20.2" class="indexterm"></a><p>
+ The data type <code class="type">uuid</code> stores Universally Unique Identifiers
+ (UUID) as defined by <a class="ulink" href="https://tools.ietf.org/html/rfc4122" target="_top">RFC 4122</a>,
+ ISO/IEC 9834-8:2005, and related standards.
+ (Some systems refer to this data type as a globally unique identifier, or
+ GUID,<a id="id-1.5.7.20.3.3" class="indexterm"></a> instead.) This
+ identifier is a 128-bit quantity that is generated by an algorithm chosen
+ to make it very unlikely that the same identifier will be generated by
+ anyone else in the known universe using the same algorithm. Therefore,
+ for distributed systems, these identifiers provide a better uniqueness
+ guarantee than sequence generators, which
+ are only unique within a single database.
+ </p><p>
+ A UUID is written as a sequence of lower-case hexadecimal digits,
+ in several groups separated by hyphens, specifically a group of 8
+ digits followed by three groups of 4 digits followed by a group of
+ 12 digits, for a total of 32 digits representing the 128 bits. An
+ example of a UUID in this standard form is:
+</p><pre class="programlisting">
+a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11
+</pre><p>
+ <span class="productname">PostgreSQL</span> also accepts the following
+ alternative forms for input:
+ use of upper-case digits, the standard format surrounded by
+ braces, omitting some or all hyphens, adding a hyphen after any
+ group of four digits. Examples are:
+</p><pre class="programlisting">
+A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
+{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
+a0eebc999c0b4ef8bb6d6bb9bd380a11
+a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
+{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
+</pre><p>
+ Output is always in the standard form.
+ </p><p>
+ See <a class="xref" href="functions-uuid.html" title="9.14. UUID Functions">Section 9.14</a> for how to generate a UUID in
+ <span class="productname">PostgreSQL</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-textsearch.html" title="8.11. Text Search Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-xml.html" title="8.13. XML Type">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.11. Text Search Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.13. <acronym class="acronym">XML</acronym> Type</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype-xml.html b/doc/src/sgml/html/datatype-xml.html
new file mode 100644
index 0000000..c4cbfad
--- /dev/null
+++ b/doc/src/sgml/html/datatype-xml.html
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.13. XML Type</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-uuid.html" title="8.12. UUID Type" /><link rel="next" href="datatype-json.html" title="8.14. JSON Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.13. <acronym class="acronym">XML</acronym> Type</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-uuid.html" title="8.12. UUID Type">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-json.html" title="8.14. JSON Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATATYPE-XML"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.13. <acronym class="acronym">XML</acronym> Type</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="datatype-xml.html#id-1.5.7.21.6">8.13.1. Creating XML Values</a></span></dt><dt><span class="sect2"><a href="datatype-xml.html#id-1.5.7.21.7">8.13.2. Encoding Handling</a></span></dt><dt><span class="sect2"><a href="datatype-xml.html#id-1.5.7.21.8">8.13.3. Accessing XML Values</a></span></dt></dl></div><a id="id-1.5.7.21.2" class="indexterm"></a><p>
+ The <code class="type">xml</code> data type can be used to store XML data. Its
+ advantage over storing XML data in a <code class="type">text</code> field is that it
+ checks the input values for well-formedness, and there are support
+ functions to perform type-safe operations on it; see <a class="xref" href="functions-xml.html" title="9.15. XML Functions">Section 9.15</a>. Use of this data type requires the
+ installation to have been built with <code class="command">configure
+ --with-libxml</code>.
+ </p><p>
+ The <code class="type">xml</code> type can store well-formed
+ <span class="quote">“<span class="quote">documents</span>”</span>, as defined by the XML standard, as well
+ as <span class="quote">“<span class="quote">content</span>”</span> fragments, which are defined by reference
+ to the more permissive
+ <a class="ulink" href="https://www.w3.org/TR/2010/REC-xpath-datamodel-20101214/#DocumentNode" target="_top"><span class="quote">“<span class="quote">document node</span>”</span></a>
+ of the XQuery and XPath data model.
+ Roughly, this means that content fragments can have
+ more than one top-level element or character node. The expression
+ <code class="literal"><em class="replaceable"><code>xmlvalue</code></em> IS DOCUMENT</code>
+ can be used to evaluate whether a particular <code class="type">xml</code>
+ value is a full document or only a content fragment.
+ </p><p>
+ Limits and compatibility notes for the <code class="type">xml</code> data type
+ can be found in <a class="xref" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML">Section D.3</a>.
+ </p><div class="sect2" id="id-1.5.7.21.6"><div class="titlepage"><div><div><h3 class="title">8.13.1. Creating XML Values</h3></div></div></div><p>
+ To produce a value of type <code class="type">xml</code> from character data,
+ use the function
+ <code class="function">xmlparse</code>:<a id="id-1.5.7.21.6.2.3" class="indexterm"></a>
+</p><pre class="synopsis">
+XMLPARSE ( { DOCUMENT | CONTENT } <em class="replaceable"><code>value</code></em>)
+</pre><p>
+ Examples:
+</p><pre class="programlisting">
+XMLPARSE (DOCUMENT '&lt;?xml version="1.0"?&gt;&lt;book&gt;&lt;title&gt;Manual&lt;/title&gt;&lt;chapter&gt;...&lt;/chapter&gt;&lt;/book&gt;')
+XMLPARSE (CONTENT 'abc&lt;foo&gt;bar&lt;/foo&gt;&lt;bar&gt;foo&lt;/bar&gt;')
+</pre><p>
+ While this is the only way to convert character strings into XML
+ values according to the SQL standard, the PostgreSQL-specific
+ syntaxes:
+</p><pre class="programlisting">
+xml '&lt;foo&gt;bar&lt;/foo&gt;'
+'&lt;foo&gt;bar&lt;/foo&gt;'::xml
+</pre><p>
+ can also be used.
+ </p><p>
+ The <code class="type">xml</code> type does not validate input values
+ against a document type declaration
+ (DTD),<a id="id-1.5.7.21.6.3.2" class="indexterm"></a>
+ even when the input value specifies a DTD.
+ There is also currently no built-in support for validating against
+ other XML schema languages such as XML Schema.
+ </p><p>
+ The inverse operation, producing a character string value from
+ <code class="type">xml</code>, uses the function
+ <code class="function">xmlserialize</code>:<a id="id-1.5.7.21.6.4.3" class="indexterm"></a>
+</p><pre class="synopsis">
+XMLSERIALIZE ( { DOCUMENT | CONTENT } <em class="replaceable"><code>value</code></em> AS <em class="replaceable"><code>type</code></em> )
+</pre><p>
+ <em class="replaceable"><code>type</code></em> can be
+ <code class="type">character</code>, <code class="type">character varying</code>, or
+ <code class="type">text</code> (or an alias for one of those). Again, according
+ to the SQL standard, this is the only way to convert between type
+ <code class="type">xml</code> and character types, but PostgreSQL also allows
+ you to simply cast the value.
+ </p><p>
+ When a character string value is cast to or from type
+ <code class="type">xml</code> without going through <code class="type">XMLPARSE</code> or
+ <code class="type">XMLSERIALIZE</code>, respectively, the choice of
+ <code class="literal">DOCUMENT</code> versus <code class="literal">CONTENT</code> is
+ determined by the <span class="quote">“<span class="quote">XML option</span>”</span>
+ <a id="id-1.5.7.21.6.5.7" class="indexterm"></a>
+ session configuration parameter, which can be set using the
+ standard command:
+</p><pre class="synopsis">
+SET XML OPTION { DOCUMENT | CONTENT };
+</pre><p>
+ or the more PostgreSQL-like syntax
+</p><pre class="synopsis">
+SET xmloption TO { DOCUMENT | CONTENT };
+</pre><p>
+ The default is <code class="literal">CONTENT</code>, so all forms of XML
+ data are allowed.
+ </p></div><div class="sect2" id="id-1.5.7.21.7"><div class="titlepage"><div><div><h3 class="title">8.13.2. Encoding Handling</h3></div></div></div><p>
+ Care must be taken when dealing with multiple character encodings
+ on the client, server, and in the XML data passed through them.
+ When using the text mode to pass queries to the server and query
+ results to the client (which is the normal mode), PostgreSQL
+ converts all character data passed between the client and the
+ server and vice versa to the character encoding of the respective
+ end; see <a class="xref" href="multibyte.html" title="24.3. Character Set Support">Section 24.3</a>. This includes string
+ representations of XML values, such as in the above examples.
+ This would ordinarily mean that encoding declarations contained in
+ XML data can become invalid as the character data is converted
+ to other encodings while traveling between client and server,
+ because the embedded encoding declaration is not changed. To cope
+ with this behavior, encoding declarations contained in
+ character strings presented for input to the <code class="type">xml</code> type
+ are <span class="emphasis"><em>ignored</em></span>, and content is assumed
+ to be in the current server encoding. Consequently, for correct
+ processing, character strings of XML data must be sent
+ from the client in the current client encoding. It is the
+ responsibility of the client to either convert documents to the
+ current client encoding before sending them to the server, or to
+ adjust the client encoding appropriately. On output, values of
+ type <code class="type">xml</code> will not have an encoding declaration, and
+ clients should assume all data is in the current client
+ encoding.
+ </p><p>
+ When using binary mode to pass query parameters to the server
+ and query results back to the client, no encoding conversion
+ is performed, so the situation is different. In this case, an
+ encoding declaration in the XML data will be observed, and if it
+ is absent, the data will be assumed to be in UTF-8 (as required by
+ the XML standard; note that PostgreSQL does not support UTF-16).
+ On output, data will have an encoding declaration
+ specifying the client encoding, unless the client encoding is
+ UTF-8, in which case it will be omitted.
+ </p><p>
+ Needless to say, processing XML data with PostgreSQL will be less
+ error-prone and more efficient if the XML data encoding, client encoding,
+ and server encoding are the same. Since XML data is internally
+ processed in UTF-8, computations will be most efficient if the
+ server encoding is also UTF-8.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ Some XML-related functions may not work at all on non-ASCII data
+ when the server encoding is not UTF-8. This is known to be an
+ issue for <code class="function">xmltable()</code> and <code class="function">xpath()</code> in particular.
+ </p></div></div><div class="sect2" id="id-1.5.7.21.8"><div class="titlepage"><div><div><h3 class="title">8.13.3. Accessing XML Values</h3></div></div></div><p>
+ The <code class="type">xml</code> data type is unusual in that it does not
+ provide any comparison operators. This is because there is no
+ well-defined and universally useful comparison algorithm for XML
+ data. One consequence of this is that you cannot retrieve rows by
+ comparing an <code class="type">xml</code> column against a search value. XML
+ values should therefore typically be accompanied by a separate key
+ field such as an ID. An alternative solution for comparing XML
+ values is to convert them to character strings first, but note
+ that character string comparison has little to do with a useful
+ XML comparison method.
+ </p><p>
+ Since there are no comparison operators for the <code class="type">xml</code>
+ data type, it is not possible to create an index directly on a
+ column of this type. If speedy searches in XML data are desired,
+ possible workarounds include casting the expression to a
+ character string type and indexing that, or indexing an XPath
+ expression. Of course, the actual query would have to be adjusted
+ to search by the indexed expression.
+ </p><p>
+ The text-search functionality in PostgreSQL can also be used to speed
+ up full-document searches of XML data. The necessary
+ preprocessing support is, however, not yet available in the PostgreSQL
+ distribution.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-uuid.html" title="8.12. UUID Type">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-json.html" title="8.14. JSON Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.12. <acronym class="acronym">UUID</acronym> Type </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.14. <acronym class="acronym">JSON</acronym> Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datatype.html b/doc/src/sgml/html/datatype.html
new file mode 100644
index 0000000..c39bde9
--- /dev/null
+++ b/doc/src/sgml/html/datatype.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 8. Data Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)" /><link rel="next" href="datatype-numeric.html" title="8.1. Numeric Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 8. Data Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-numeric.html" title="8.1. Numeric Types">Next</a></td></tr></table><hr /></div><div class="chapter" id="DATATYPE"><div class="titlepage"><div><div><h2 class="title">Chapter 8. Data Types</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="datatype-numeric.html">8.1. Numeric Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-INT">8.1.1. Integer Types</a></span></dt><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL">8.1.2. Arbitrary Precision Numbers</a></span></dt><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-FLOAT">8.1.3. Floating-Point Types</a></span></dt><dt><span class="sect2"><a href="datatype-numeric.html#DATATYPE-SERIAL">8.1.4. Serial Types</a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-money.html">8.2. Monetary Types</a></span></dt><dt><span class="sect1"><a href="datatype-character.html">8.3. Character Types</a></span></dt><dt><span class="sect1"><a href="datatype-binary.html">8.4. Binary Data Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-binary.html#id-1.5.7.12.9">8.4.1. <code class="type">bytea</code> Hex Format</a></span></dt><dt><span class="sect2"><a href="datatype-binary.html#id-1.5.7.12.10">8.4.2. <code class="type">bytea</code> Escape Format</a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-datetime.html">8.5. Date/Time Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-DATETIME-INPUT">8.5.1. Date/Time Input</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-DATETIME-OUTPUT">8.5.2. Date/Time Output</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-TIMEZONES">8.5.3. Time Zones</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-INTERVAL-INPUT">8.5.4. Interval Input</a></span></dt><dt><span class="sect2"><a href="datatype-datetime.html#DATATYPE-INTERVAL-OUTPUT">8.5.5. Interval Output</a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-boolean.html">8.6. Boolean Type</a></span></dt><dt><span class="sect1"><a href="datatype-enum.html">8.7. Enumerated Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.5">8.7.1. Declaration of Enumerated Types</a></span></dt><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.6">8.7.2. Ordering</a></span></dt><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.7">8.7.3. Type Safety</a></span></dt><dt><span class="sect2"><a href="datatype-enum.html#id-1.5.7.15.8">8.7.4. Implementation Details</a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-geometric.html">8.8. Geometric Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-geometric.html#id-1.5.7.16.5">8.8.1. Points</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-LINE">8.8.2. Lines</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-LSEG">8.8.3. Line Segments</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#id-1.5.7.16.8">8.8.4. Boxes</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#id-1.5.7.16.9">8.8.5. Paths</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-POLYGON">8.8.6. Polygons</a></span></dt><dt><span class="sect2"><a href="datatype-geometric.html#DATATYPE-CIRCLE">8.8.7. Circles</a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-net-types.html">8.9. Network Address Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-INET">8.9.1. <code class="type">inet</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-CIDR">8.9.2. <code class="type">cidr</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-INET-VS-CIDR">8.9.3. <code class="type">inet</code> vs. <code class="type">cidr</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-MACADDR">8.9.4. <code class="type">macaddr</code></a></span></dt><dt><span class="sect2"><a href="datatype-net-types.html#DATATYPE-MACADDR8">8.9.5. <code class="type">macaddr8</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-bit.html">8.10. Bit String Types</a></span></dt><dt><span class="sect1"><a href="datatype-textsearch.html">8.11. Text Search Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-textsearch.html#DATATYPE-TSVECTOR">8.11.1. <code class="type">tsvector</code></a></span></dt><dt><span class="sect2"><a href="datatype-textsearch.html#DATATYPE-TSQUERY">8.11.2. <code class="type">tsquery</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-uuid.html">8.12. <acronym class="acronym">UUID</acronym> Type</a></span></dt><dt><span class="sect1"><a href="datatype-xml.html">8.13. <acronym class="acronym">XML</acronym> Type</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-xml.html#id-1.5.7.21.6">8.13.1. Creating XML Values</a></span></dt><dt><span class="sect2"><a href="datatype-xml.html#id-1.5.7.21.7">8.13.2. Encoding Handling</a></span></dt><dt><span class="sect2"><a href="datatype-xml.html#id-1.5.7.21.8">8.13.3. Accessing XML Values</a></span></dt></dl></dd><dt><span class="sect1"><a href="datatype-json.html">8.14. <acronym class="acronym">JSON</acronym> Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="datatype-json.html#JSON-KEYS-ELEMENTS">8.14.1. JSON Input and Output Syntax</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSON-DOC-DESIGN">8.14.2. Designing JSON Documents</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSON-CONTAINMENT">8.14.3. <code class="type">jsonb</code> Containment and Existence</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSON-INDEXING">8.14.4. <code class="type">jsonb</code> Indexing</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#JSONB-SUBSCRIPTING">8.14.5. <code class="type">jsonb</code> Subscripting</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#id-1.5.7.22.20">8.14.6. Transforms</a></span></dt><dt><span class="sect2"><a href="datatype-json.html#DATATYPE-JSONPATH">8.14.7. jsonpath Type</a></span></dt></dl></dd><dt><span class="sect1"><a href="arrays.html">8.15. Arrays</a></span></dt><dd><dl><dt><span class="sect2"><a href="arrays.html#ARRAYS-DECLARATION">8.15.1. Declaration of Array Types</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-INPUT">8.15.2. Array Value Input</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-ACCESSING">8.15.3. Accessing Arrays</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-MODIFYING">8.15.4. Modifying Arrays</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-SEARCHING">8.15.5. Searching in Arrays</a></span></dt><dt><span class="sect2"><a href="arrays.html#ARRAYS-IO">8.15.6. Array Input and Output Syntax</a></span></dt></dl></dd><dt><span class="sect1"><a href="rowtypes.html">8.16. Composite Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-DECLARING">8.16.1. Declaration of Composite Types</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#id-1.5.7.24.6">8.16.2. Constructing Composite Values</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-ACCESSING">8.16.3. Accessing Composite Types</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#id-1.5.7.24.8">8.16.4. Modifying Composite Types</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-USAGE">8.16.5. Using Composite Types in Queries</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-IO-SYNTAX">8.16.6. Composite Type Input and Output Syntax</a></span></dt></dl></dd><dt><span class="sect1"><a href="rangetypes.html">8.17. Range Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-BUILTIN">8.17.1. Built-in Range and Multirange Types</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-EXAMPLES">8.17.2. Examples</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-INCLUSIVITY">8.17.3. Inclusive and Exclusive Bounds</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-INFINITE">8.17.4. Infinite (Unbounded) Ranges</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-IO">8.17.5. Range Input/Output</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-CONSTRUCT">8.17.6. Constructing Ranges and Multiranges</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-DISCRETE">8.17.7. Discrete Range Types</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-DEFINING">8.17.8. Defining New Range Types</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-INDEXING">8.17.9. Indexing</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-CONSTRAINT">8.17.10. Constraints on Ranges</a></span></dt></dl></dd><dt><span class="sect1"><a href="domains.html">8.18. Domain Types</a></span></dt><dt><span class="sect1"><a href="datatype-oid.html">8.19. Object Identifier Types</a></span></dt><dt><span class="sect1"><a href="datatype-pg-lsn.html">8.20. <code class="type">pg_lsn</code> Type</a></span></dt><dt><span class="sect1"><a href="datatype-pseudo.html">8.21. Pseudo-Types</a></span></dt></dl></div><a id="id-1.5.7.2" class="indexterm"></a><a id="id-1.5.7.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> has a rich set of native data
+ types available to users. Users can add new types to
+ <span class="productname">PostgreSQL</span> using the <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> command.
+ </p><p>
+ <a class="xref" href="datatype.html#DATATYPE-TABLE" title="Table 8.1. Data Types">Table 8.1</a> shows all the built-in general-purpose data
+ types. Most of the alternative names listed in the
+ <span class="quote">“<span class="quote">Aliases</span>”</span> column are the names used internally by
+ <span class="productname">PostgreSQL</span> for historical reasons. In
+ addition, some internally used or deprecated types are available,
+ but are not listed here.
+ </p><div class="table" id="DATATYPE-TABLE"><p class="title"><strong>Table 8.1. Data Types</strong></p><div class="table-contents"><table class="table" summary="Data Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Aliases</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">bigint</code></td><td><code class="type">int8</code></td><td>signed eight-byte integer</td></tr><tr><td><code class="type">bigserial</code></td><td><code class="type">serial8</code></td><td>autoincrementing eight-byte integer</td></tr><tr><td><code class="type">bit [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td> </td><td>fixed-length bit string</td></tr><tr><td><code class="type">bit varying [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td><code class="type">varbit [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td>variable-length bit string</td></tr><tr><td><code class="type">boolean</code></td><td><code class="type">bool</code></td><td>logical Boolean (true/false)</td></tr><tr><td><code class="type">box</code></td><td> </td><td>rectangular box on a plane</td></tr><tr><td><code class="type">bytea</code></td><td> </td><td>binary data (<span class="quote">“<span class="quote">byte array</span>”</span>)</td></tr><tr><td><code class="type">character [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td><code class="type">char [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td>fixed-length character string</td></tr><tr><td><code class="type">character varying [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td><code class="type">varchar [ (<em class="replaceable"><code>n</code></em>) ]</code></td><td>variable-length character string</td></tr><tr><td><code class="type">cidr</code></td><td> </td><td>IPv4 or IPv6 network address</td></tr><tr><td><code class="type">circle</code></td><td> </td><td>circle on a plane</td></tr><tr><td><code class="type">date</code></td><td> </td><td>calendar date (year, month, day)</td></tr><tr><td><code class="type">double precision</code></td><td><code class="type">float8</code></td><td>double precision floating-point number (8 bytes)</td></tr><tr><td><code class="type">inet</code></td><td> </td><td>IPv4 or IPv6 host address</td></tr><tr><td><code class="type">integer</code></td><td><code class="type">int</code>, <code class="type">int4</code></td><td>signed four-byte integer</td></tr><tr><td><code class="type">interval [ <em class="replaceable"><code>fields</code></em> ] [ (<em class="replaceable"><code>p</code></em>) ]</code></td><td> </td><td>time span</td></tr><tr><td><code class="type">json</code></td><td> </td><td>textual JSON data</td></tr><tr><td><code class="type">jsonb</code></td><td> </td><td>binary JSON data, decomposed</td></tr><tr><td><code class="type">line</code></td><td> </td><td>infinite line on a plane</td></tr><tr><td><code class="type">lseg</code></td><td> </td><td>line segment on a plane</td></tr><tr><td><code class="type">macaddr</code></td><td> </td><td>MAC (Media Access Control) address</td></tr><tr><td><code class="type">macaddr8</code></td><td> </td><td>MAC (Media Access Control) address (EUI-64 format)</td></tr><tr><td><code class="type">money</code></td><td> </td><td>currency amount</td></tr><tr><td><code class="type">numeric [ (<em class="replaceable"><code>p</code></em>,
+ <em class="replaceable"><code>s</code></em>) ]</code></td><td><code class="type">decimal [ (<em class="replaceable"><code>p</code></em>,
+ <em class="replaceable"><code>s</code></em>) ]</code></td><td>exact numeric of selectable precision</td></tr><tr><td><code class="type">path</code></td><td> </td><td>geometric path on a plane</td></tr><tr><td><code class="type">pg_lsn</code></td><td> </td><td><span class="productname">PostgreSQL</span> Log Sequence Number</td></tr><tr><td><code class="type">pg_snapshot</code></td><td> </td><td>user-level transaction ID snapshot</td></tr><tr><td><code class="type">point</code></td><td> </td><td>geometric point on a plane</td></tr><tr><td><code class="type">polygon</code></td><td> </td><td>closed geometric path on a plane</td></tr><tr><td><code class="type">real</code></td><td><code class="type">float4</code></td><td>single precision floating-point number (4 bytes)</td></tr><tr><td><code class="type">smallint</code></td><td><code class="type">int2</code></td><td>signed two-byte integer</td></tr><tr><td><code class="type">smallserial</code></td><td><code class="type">serial2</code></td><td>autoincrementing two-byte integer</td></tr><tr><td><code class="type">serial</code></td><td><code class="type">serial4</code></td><td>autoincrementing four-byte integer</td></tr><tr><td><code class="type">text</code></td><td> </td><td>variable-length character string</td></tr><tr><td><code class="type">time [ (<em class="replaceable"><code>p</code></em>) ] [ without time zone ]</code></td><td> </td><td>time of day (no time zone)</td></tr><tr><td><code class="type">time [ (<em class="replaceable"><code>p</code></em>) ] with time zone</code></td><td><code class="type">timetz</code></td><td>time of day, including time zone</td></tr><tr><td><code class="type">timestamp [ (<em class="replaceable"><code>p</code></em>) ] [ without time zone ]</code></td><td> </td><td>date and time (no time zone)</td></tr><tr><td><code class="type">timestamp [ (<em class="replaceable"><code>p</code></em>) ] with time zone</code></td><td><code class="type">timestamptz</code></td><td>date and time, including time zone</td></tr><tr><td><code class="type">tsquery</code></td><td> </td><td>text search query</td></tr><tr><td><code class="type">tsvector</code></td><td> </td><td>text search document</td></tr><tr><td><code class="type">txid_snapshot</code></td><td> </td><td>user-level transaction ID snapshot (deprecated; see <code class="type">pg_snapshot</code>)</td></tr><tr><td><code class="type">uuid</code></td><td> </td><td>universally unique identifier</td></tr><tr><td><code class="type">xml</code></td><td> </td><td>XML data</td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Compatibility</h3><p>
+ The following types (or spellings thereof) are specified by
+ <acronym class="acronym">SQL</acronym>: <code class="type">bigint</code>, <code class="type">bit</code>, <code class="type">bit
+ varying</code>, <code class="type">boolean</code>, <code class="type">char</code>,
+ <code class="type">character varying</code>, <code class="type">character</code>,
+ <code class="type">varchar</code>, <code class="type">date</code>, <code class="type">double
+ precision</code>, <code class="type">integer</code>, <code class="type">interval</code>,
+ <code class="type">numeric</code>, <code class="type">decimal</code>, <code class="type">real</code>,
+ <code class="type">smallint</code>, <code class="type">time</code> (with or without time zone),
+ <code class="type">timestamp</code> (with or without time zone),
+ <code class="type">xml</code>.
+ </p></div><p>
+ Each data type has an external representation determined by its input
+ and output functions. Many of the built-in types have
+ obvious external formats. However, several types are either unique
+ to <span class="productname">PostgreSQL</span>, such as geometric
+ paths, or have several possible formats, such as the date
+ and time types.
+ Some of the input and output functions are not invertible, i.e.,
+ the result of an output function might lose accuracy when compared to
+ the original input.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-numeric.html" title="8.1. Numeric Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.1. Numeric Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-appendix.html b/doc/src/sgml/html/datetime-appendix.html
new file mode 100644
index 0000000..942ed95
--- /dev/null
+++ b/doc/src/sgml/html/datetime-appendix.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix B. Date/Time Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes" /><link rel="next" href="datetime-input-rules.html" title="B.1. Date/Time Input Interpretation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix B. Date/Time Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-input-rules.html" title="B.1. Date/Time Input Interpretation">Next</a></td></tr></table><hr /></div><div class="appendix" id="DATETIME-APPENDIX"><div class="titlepage"><div><div><h2 class="title">Appendix B. Date/Time Support</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="datetime-input-rules.html">B.1. Date/Time Input Interpretation</a></span></dt><dt><span class="sect1"><a href="datetime-invalid-input.html">B.2. Handling of Invalid or Ambiguous Timestamps</a></span></dt><dt><span class="sect1"><a href="datetime-keywords.html">B.3. Date/Time Key Words</a></span></dt><dt><span class="sect1"><a href="datetime-config-files.html">B.4. Date/Time Configuration Files</a></span></dt><dt><span class="sect1"><a href="datetime-posix-timezone-specs.html">B.5. <acronym class="acronym">POSIX</acronym> Time Zone Specifications</a></span></dt><dt><span class="sect1"><a href="datetime-units-history.html">B.6. History of Units</a></span></dt><dt><span class="sect1"><a href="datetime-julian-dates.html">B.7. Julian Dates</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> uses an internal heuristic
+ parser for all date/time input support. Dates and times are input as
+ strings, and are broken up into distinct fields with a preliminary
+ determination of what kind of information can be in the
+ field. Each field is interpreted and either assigned a numeric
+ value, ignored, or rejected.
+ The parser contains internal lookup tables for all textual fields,
+ including months, days of the week, and time zones.
+ </p><p>
+ This appendix includes information on the content of these
+ lookup tables and describes the steps used by the parser to decode
+ dates and times.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-input-rules.html" title="B.1. Date/Time Input Interpretation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix A. <span class="productname">PostgreSQL</span> Error Codes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.1. Date/Time Input Interpretation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-config-files.html b/doc/src/sgml/html/datetime-config-files.html
new file mode 100644
index 0000000..28fde0d
--- /dev/null
+++ b/doc/src/sgml/html/datetime-config-files.html
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.4. Date/Time Configuration Files</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-keywords.html" title="B.3. Date/Time Key Words" /><link rel="next" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.4. Date/Time Configuration Files</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-keywords.html" title="B.3. Date/Time Key Words">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-CONFIG-FILES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.4. Date/Time Configuration Files</h2></div></div></div><a id="id-1.11.3.7.2" class="indexterm"></a><p>
+ Since timezone abbreviations are not well standardized,
+ <span class="productname">PostgreSQL</span> provides a means to customize
+ the set of abbreviations accepted by the server. The
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE-ABBREVIATIONS">timezone_abbreviations</a> run-time parameter
+ determines the active set of abbreviations. While this parameter
+ can be altered by any database user, the possible values for it
+ are under the control of the database administrator — they
+ are in fact names of configuration files stored in
+ <code class="filename">.../share/timezonesets/</code> of the installation directory.
+ By adding or altering files in that directory, the administrator
+ can set local policy for timezone abbreviations.
+ </p><p>
+ <code class="varname">timezone_abbreviations</code> can be set to any file name
+ found in <code class="filename">.../share/timezonesets/</code>, if the file's name
+ is entirely alphabetic. (The prohibition against non-alphabetic
+ characters in <code class="varname">timezone_abbreviations</code> prevents reading
+ files outside the intended directory, as well as reading editor
+ backup files and other extraneous files.)
+ </p><p>
+ A timezone abbreviation file can contain blank lines and comments
+ beginning with <code class="literal">#</code>. Non-comment lines must have one of
+ these formats:
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>zone_abbreviation</code></em> <em class="replaceable"><code>offset</code></em>
+<em class="replaceable"><code>zone_abbreviation</code></em> <em class="replaceable"><code>offset</code></em> D
+<em class="replaceable"><code>zone_abbreviation</code></em> <em class="replaceable"><code>time_zone_name</code></em>
+@INCLUDE <em class="replaceable"><code>file_name</code></em>
+@OVERRIDE
+</pre><p>
+ </p><p>
+ A <em class="replaceable"><code>zone_abbreviation</code></em> is just the abbreviation
+ being defined. An <em class="replaceable"><code>offset</code></em> is an integer giving
+ the equivalent offset in seconds from UTC, positive being east from
+ Greenwich and negative being west. For example, -18000 would be five
+ hours west of Greenwich, or North American east coast standard time.
+ <code class="literal">D</code> indicates that the zone name represents local
+ daylight-savings time rather than standard time.
+ </p><p>
+ Alternatively, a <em class="replaceable"><code>time_zone_name</code></em> can be given, referencing
+ a zone name defined in the IANA timezone database. The zone's definition
+ is consulted to see whether the abbreviation is or has been in use in
+ that zone, and if so, the appropriate meaning is used — that is,
+ the meaning that was currently in use at the timestamp whose value is
+ being determined, or the meaning in use immediately before that if it
+ wasn't current at that time, or the oldest meaning if it was used only
+ after that time. This behavior is essential for dealing with
+ abbreviations whose meaning has historically varied. It is also allowed
+ to define an abbreviation in terms of a zone name in which that
+ abbreviation does not appear; then using the abbreviation is just
+ equivalent to writing out the zone name.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Using a simple integer <em class="replaceable"><code>offset</code></em> is preferred
+ when defining an abbreviation whose offset from UTC has never changed,
+ as such abbreviations are much cheaper to process than those that
+ require consulting a time zone definition.
+ </p></div><p>
+ The <code class="literal">@INCLUDE</code> syntax allows inclusion of another file in the
+ <code class="filename">.../share/timezonesets/</code> directory. Inclusion can be nested,
+ to a limited depth.
+ </p><p>
+ The <code class="literal">@OVERRIDE</code> syntax indicates that subsequent entries in the
+ file can override previous entries (typically, entries obtained from
+ included files). Without this, conflicting definitions of the same
+ timezone abbreviation are considered an error.
+ </p><p>
+ In an unmodified installation, the file <code class="filename">Default</code> contains
+ all the non-conflicting time zone abbreviations for most of the world.
+ Additional files <code class="filename">Australia</code> and <code class="filename">India</code> are
+ provided for those regions: these files first include the
+ <code class="literal">Default</code> file and then add or modify abbreviations as needed.
+ </p><p>
+ For reference purposes, a standard installation also contains files
+ <code class="filename">Africa.txt</code>, <code class="filename">America.txt</code>, etc., containing
+ information about every time zone abbreviation known to be in use
+ according to the IANA timezone database. The zone name
+ definitions found in these files can be copied and pasted into a custom
+ configuration file as needed. Note that these files cannot be directly
+ referenced as <code class="varname">timezone_abbreviations</code> settings, because of
+ the dot embedded in their names.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If an error occurs while reading the time zone abbreviation set, no new
+ value is applied and the old set is kept. If the error occurs while
+ starting the database, startup fails.
+ </p></div><div class="caution"><h3 class="title">Caution</h3><p>
+ Time zone abbreviations defined in the configuration file override
+ non-timezone meanings built into <span class="productname">PostgreSQL</span>.
+ For example, the <code class="filename">Australia</code> configuration file defines
+ <code class="literal">SAT</code> (for South Australian Standard Time). When this
+ file is active, <code class="literal">SAT</code> will not be recognized as an abbreviation
+ for Saturday.
+ </p></div><div class="caution"><h3 class="title">Caution</h3><p>
+ If you modify files in <code class="filename">.../share/timezonesets/</code>,
+ it is up to you to make backups — a normal database dump
+ will not include this directory.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-keywords.html" title="B.3. Date/Time Key Words">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.3. Date/Time Key Words </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.5. <acronym class="acronym">POSIX</acronym> Time Zone Specifications</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-input-rules.html b/doc/src/sgml/html/datetime-input-rules.html
new file mode 100644
index 0000000..76b4365
--- /dev/null
+++ b/doc/src/sgml/html/datetime-input-rules.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.1. Date/Time Input Interpretation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-appendix.html" title="Appendix B. Date/Time Support" /><link rel="next" href="datetime-invalid-input.html" title="B.2. Handling of Invalid or Ambiguous Timestamps" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.1. Date/Time Input Interpretation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-invalid-input.html" title="B.2. Handling of Invalid or Ambiguous Timestamps">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-INPUT-RULES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.1. Date/Time Input Interpretation</h2></div></div></div><p>
+ Date/time input strings are decoded using the following procedure.
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p>
+ Break the input string into tokens and categorize each token as
+ a string, time, time zone, or number.
+ </p><ol type="a" class="substeps"><li class="step"><p>
+ If the numeric token contains a colon (<code class="literal">:</code>), this is
+ a time string. Include all subsequent digits and colons.
+ </p></li><li class="step"><p>
+ If the numeric token contains a dash (<code class="literal">-</code>), slash
+ (<code class="literal">/</code>), or two or more dots (<code class="literal">.</code>), this is
+ a date string which might have a text month. If a date token has
+ already been seen, it is instead interpreted as a time zone
+ name (e.g., <code class="literal">America/New_York</code>).
+ </p></li><li class="step"><p>
+ If the token is numeric only, then it is either a single field
+ or an ISO 8601 concatenated date (e.g.,
+ <code class="literal">19990113</code> for January 13, 1999) or time
+ (e.g., <code class="literal">141516</code> for 14:15:16).
+ </p></li><li class="step"><p>
+ If the token starts with a plus (<code class="literal">+</code>) or minus
+ (<code class="literal">-</code>), then it is either a numeric time zone or a special
+ field.
+ </p></li></ol></li><li class="step"><p>
+ If the token is an alphabetic string, match up with possible strings:
+ </p><ol type="a" class="substeps"><li class="step"><p>
+ See if the token matches any known time zone abbreviation.
+ These abbreviations are supplied by the configuration file
+ described in <a class="xref" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Section B.4</a>.
+ </p></li><li class="step"><p>
+ If not found, search an internal table to match
+ the token as either a special string (e.g., <code class="literal">today</code>),
+ day (e.g., <code class="literal">Thursday</code>),
+ month (e.g., <code class="literal">January</code>),
+ or noise word (e.g., <code class="literal">at</code>, <code class="literal">on</code>).
+ </p></li><li class="step"><p>
+ If still not found, throw an error.
+ </p></li></ol></li><li class="step"><p>
+ When the token is a number or number field:
+ </p><ol type="a" class="substeps"><li class="step"><p>
+ If there are eight or six digits,
+ and if no other date fields have been previously read, then interpret
+ as a <span class="quote">“<span class="quote">concatenated date</span>”</span> (e.g.,
+ <code class="literal">19990118</code> or <code class="literal">990118</code>).
+ The interpretation is <code class="literal">YYYYMMDD</code> or <code class="literal">YYMMDD</code>.
+ </p></li><li class="step"><p>
+ If the token is three digits
+ and a year has already been read, then interpret as day of year.
+ </p></li><li class="step"><p>
+ If four or six digits and a year has already been read, then
+ interpret as a time (<code class="literal">HHMM</code> or <code class="literal">HHMMSS</code>).
+ </p></li><li class="step"><p>
+ If three or more digits and no date fields have yet been found,
+ interpret as a year (this forces yy-mm-dd ordering of the remaining
+ date fields).
+ </p></li><li class="step"><p>
+ Otherwise the date field ordering is assumed to follow the
+ <code class="varname">DateStyle</code> setting: mm-dd-yy, dd-mm-yy, or yy-mm-dd.
+ Throw an error if a month or day field is found to be out of range.
+ </p></li></ol></li><li class="step"><p>
+ If BC has been specified, negate the year and add one for
+ internal storage. (There is no year zero in the Gregorian
+ calendar, so numerically 1 BC becomes year zero.)
+ </p></li><li class="step"><p>
+ If BC was not specified, and if the year field was two digits in length,
+ then adjust the year to four digits. If the field is less than 70, then
+ add 2000, otherwise add 1900.
+
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Gregorian years AD 1–99 can be entered by using 4 digits with leading
+ zeros (e.g., <code class="literal">0099</code> is AD 99).
+ </p></div><p>
+ </p></li></ol></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-invalid-input.html" title="B.2. Handling of Invalid or Ambiguous Timestamps">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix B. Date/Time Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.2. Handling of Invalid or Ambiguous Timestamps</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-invalid-input.html b/doc/src/sgml/html/datetime-invalid-input.html
new file mode 100644
index 0000000..c11bdd8
--- /dev/null
+++ b/doc/src/sgml/html/datetime-invalid-input.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.2. Handling of Invalid or Ambiguous Timestamps</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-input-rules.html" title="B.1. Date/Time Input Interpretation" /><link rel="next" href="datetime-keywords.html" title="B.3. Date/Time Key Words" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.2. Handling of Invalid or Ambiguous Timestamps</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-input-rules.html" title="B.1. Date/Time Input Interpretation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-keywords.html" title="B.3. Date/Time Key Words">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-INVALID-INPUT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.2. Handling of Invalid or Ambiguous Timestamps</h2></div></div></div><p>
+ Ordinarily, if a date/time string is syntactically valid but contains
+ out-of-range field values, an error will be thrown. For example, input
+ specifying the 31st of February will be rejected.
+ </p><p>
+ During a daylight-savings-time transition, it is possible for a
+ seemingly valid timestamp string to represent a nonexistent or ambiguous
+ timestamp. Such cases are not rejected; the ambiguity is resolved by
+ determining which UTC offset to apply. For example, supposing that the
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> parameter is set
+ to <code class="literal">America/New_York</code>, consider
+</p><pre class="programlisting">
+=&gt; SELECT '2018-03-11 02:30'::timestamptz;
+ timestamptz
+------------------------
+ 2018-03-11 03:30:00-04
+(1 row)
+</pre><p>
+ Because that day was a spring-forward transition date in that time zone,
+ there was no civil time instant 2:30AM; clocks jumped forward from 2AM
+ EST to 3AM EDT. <span class="productname">PostgreSQL</span> interprets the
+ given time as if it were standard time (UTC-5), which then renders as
+ 3:30AM EDT (UTC-4).
+ </p><p>
+ Conversely, consider the behavior during a fall-back transition:
+</p><pre class="programlisting">
+=&gt; SELECT '2018-11-04 01:30'::timestamptz;
+ timestamptz
+------------------------
+ 2018-11-04 01:30:00-05
+(1 row)
+</pre><p>
+ On that date, there were two possible interpretations of 1:30AM; there
+ was 1:30AM EDT, and then an hour later after clocks jumped back from
+ 2AM EDT to 1AM EST, there was 1:30AM EST.
+ Again, <span class="productname">PostgreSQL</span> interprets the given time
+ as if it were standard time (UTC-5). We can force the other
+ interpretation by specifying daylight-savings time:
+</p><pre class="programlisting">
+=&gt; SELECT '2018-11-04 01:30 EDT'::timestamptz;
+ timestamptz
+------------------------
+ 2018-11-04 01:30:00-04
+(1 row)
+</pre><p>
+ </p><p>
+ The precise rule that is applied in such cases is that an invalid
+ timestamp that appears to fall within a jump-forward daylight savings
+ transition is assigned the UTC offset that prevailed in the time zone
+ just before the transition, while an ambiguous timestamp that could fall
+ on either side of a jump-back transition is assigned the UTC offset that
+ prevailed just after the transition. In most time zones this is
+ equivalent to saying that <span class="quote">“<span class="quote">the standard-time interpretation is
+ preferred when in doubt</span>”</span>.
+ </p><p>
+ In all cases, the UTC offset associated with a timestamp can be
+ specified explicitly, using either a numeric UTC offset or a time zone
+ abbreviation that corresponds to a fixed UTC offset. The rule just
+ given applies only when it is necessary to infer a UTC offset for a time
+ zone in which the offset varies.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-input-rules.html" title="B.1. Date/Time Input Interpretation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-keywords.html" title="B.3. Date/Time Key Words">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.1. Date/Time Input Interpretation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.3. Date/Time Key Words</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-julian-dates.html b/doc/src/sgml/html/datetime-julian-dates.html
new file mode 100644
index 0000000..8fdd4df
--- /dev/null
+++ b/doc/src/sgml/html/datetime-julian-dates.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.7. Julian Dates</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-units-history.html" title="B.6. History of Units" /><link rel="next" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.7. Julian Dates</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-units-history.html" title="B.6. History of Units">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-JULIAN-DATES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.7. Julian Dates</h2></div></div></div><a id="id-1.11.3.10.2" class="indexterm"></a><p>
+ The <em class="firstterm">Julian Date</em> system is a method for
+ numbering days. It is
+ unrelated to the Julian calendar, though it is confusingly
+ named similarly to that calendar.
+ The Julian Date system was invented by the French scholar
+ Joseph Justus Scaliger (1540–1609)
+ and probably takes its name from Scaliger's father,
+ the Italian scholar Julius Caesar Scaliger (1484–1558).
+ </p><p>
+ In the Julian Date system, each day has a sequential number, starting
+ from JD 0 (which is sometimes called <span class="emphasis"><em>the</em></span> Julian Date).
+ JD 0 corresponds to 1 January 4713 BC in the Julian calendar, or
+ 24 November 4714 BC in the Gregorian calendar. Julian Date counting
+ is most often used by astronomers for labeling their nightly observations,
+ and therefore a date runs from noon UTC to the next noon UTC, rather than
+ from midnight to midnight: JD 0 designates the 24 hours from noon UTC on
+ 24 November 4714 BC to noon UTC on 25 November 4714 BC.
+ </p><p>
+ Although <span class="productname">PostgreSQL</span> supports Julian Date notation for
+ input and output of dates (and also uses Julian dates for some internal
+ datetime calculations), it does not observe the nicety of having dates
+ run from noon to noon. <span class="productname">PostgreSQL</span> treats a Julian Date
+ as running from local midnight to local midnight, the same as a normal
+ date.
+ </p><p>
+ This definition does, however, provide a way to obtain the astronomical
+ definition when you need it: do the arithmetic in time
+ zone <code class="literal">UTC+12</code>. For example,
+</p><pre class="programlisting">
+=&gt; SELECT extract(julian from '2021-06-23 7:00:00-04'::timestamptz at time zone 'UTC+12');
+ extract
+------------------------------
+ 2459388.95833333333333333333
+(1 row)
+=&gt; SELECT extract(julian from '2021-06-23 8:00:00-04'::timestamptz at time zone 'UTC+12');
+ extract
+--------------------------------------
+ 2459389.0000000000000000000000000000
+(1 row)
+=&gt; SELECT extract(julian from date '2021-06-23');
+ extract
+---------
+ 2459389
+(1 row)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-units-history.html" title="B.6. History of Units">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.6. History of Units </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix C. <acronym class="acronym">SQL</acronym> Key Words</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-keywords.html b/doc/src/sgml/html/datetime-keywords.html
new file mode 100644
index 0000000..070f0a5
--- /dev/null
+++ b/doc/src/sgml/html/datetime-keywords.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.3. Date/Time Key Words</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-invalid-input.html" title="B.2. Handling of Invalid or Ambiguous Timestamps" /><link rel="next" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.3. Date/Time Key Words</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-invalid-input.html" title="B.2. Handling of Invalid or Ambiguous Timestamps">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-KEYWORDS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.3. Date/Time Key Words</h2></div></div></div><p>
+ <a class="xref" href="datetime-keywords.html#DATETIME-MONTH-TABLE" title="Table B.1. Month Names">Table B.1</a> shows the tokens that are
+ recognized as names of months.
+ </p><div class="table" id="DATETIME-MONTH-TABLE"><p class="title"><strong>Table B.1. Month Names</strong></p><div class="table-contents"><table class="table" summary="Month Names" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Month</th><th>Abbreviations</th></tr></thead><tbody><tr><td>January</td><td>Jan</td></tr><tr><td>February</td><td>Feb</td></tr><tr><td>March</td><td>Mar</td></tr><tr><td>April</td><td>Apr</td></tr><tr><td>May</td><td> </td></tr><tr><td>June</td><td>Jun</td></tr><tr><td>July</td><td>Jul</td></tr><tr><td>August</td><td>Aug</td></tr><tr><td>September</td><td>Sep, Sept</td></tr><tr><td>October</td><td>Oct</td></tr><tr><td>November</td><td>Nov</td></tr><tr><td>December</td><td>Dec</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="datetime-keywords.html#DATETIME-DOW-TABLE" title="Table B.2. Day of the Week Names">Table B.2</a> shows the tokens that are
+ recognized as names of days of the week.
+ </p><div class="table" id="DATETIME-DOW-TABLE"><p class="title"><strong>Table B.2. Day of the Week Names</strong></p><div class="table-contents"><table class="table" summary="Day of the Week Names" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Day</th><th>Abbreviations</th></tr></thead><tbody><tr><td>Sunday</td><td>Sun</td></tr><tr><td>Monday</td><td>Mon</td></tr><tr><td>Tuesday</td><td>Tue, Tues</td></tr><tr><td>Wednesday</td><td>Wed, Weds</td></tr><tr><td>Thursday</td><td>Thu, Thur, Thurs</td></tr><tr><td>Friday</td><td>Fri</td></tr><tr><td>Saturday</td><td>Sat</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="datetime-keywords.html#DATETIME-MOD-TABLE" title="Table B.3. Date/Time Field Modifiers">Table B.3</a> shows the tokens that serve
+ various modifier purposes.
+ </p><div class="table" id="DATETIME-MOD-TABLE"><p class="title"><strong>Table B.3. Date/Time Field Modifiers</strong></p><div class="table-contents"><table class="table" summary="Date/Time Field Modifiers" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Identifier</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">AM</code></td><td>Time is before 12:00</td></tr><tr><td><code class="literal">AT</code></td><td>Ignored</td></tr><tr><td><code class="literal">JULIAN</code>, <code class="literal">JD</code>, <code class="literal">J</code></td><td>Next field is Julian Date</td></tr><tr><td><code class="literal">ON</code></td><td>Ignored</td></tr><tr><td><code class="literal">PM</code></td><td>Time is on or after 12:00</td></tr><tr><td><code class="literal">T</code></td><td>Next field is time</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-invalid-input.html" title="B.2. Handling of Invalid or Ambiguous Timestamps">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.2. Handling of Invalid or Ambiguous Timestamps </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.4. Date/Time Configuration Files</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-posix-timezone-specs.html b/doc/src/sgml/html/datetime-posix-timezone-specs.html
new file mode 100644
index 0000000..9d6a088
--- /dev/null
+++ b/doc/src/sgml/html/datetime-posix-timezone-specs.html
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.5. POSIX Time Zone Specifications</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files" /><link rel="next" href="datetime-units-history.html" title="B.6. History of Units" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.5. <acronym class="acronym">POSIX</acronym> Time Zone Specifications</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-units-history.html" title="B.6. History of Units">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-POSIX-TIMEZONE-SPECS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.5. <acronym class="acronym">POSIX</acronym> Time Zone Specifications</h2></div></div></div><a id="id-1.11.3.8.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> can accept time zone specifications
+ that are written according to the <acronym class="acronym">POSIX</acronym> standard's rules
+ for the <code class="varname">TZ</code> environment
+ variable. <acronym class="acronym">POSIX</acronym> time zone specifications are
+ inadequate to deal with the complexity of real-world time zone history,
+ but there are sometimes reasons to use them.
+ </p><p>
+ A POSIX time zone specification has the form
+</p><pre class="synopsis">
+<em class="replaceable"><code>STD</code></em> <em class="replaceable"><code>offset</code></em> [<span class="optional"> <em class="replaceable"><code>DST</code></em> [<span class="optional"> <em class="replaceable"><code>dstoffset</code></em> </span>] [<span class="optional"> , <em class="replaceable"><code>rule</code></em> </span>] </span>]
+</pre><p>
+ (For readability, we show spaces between the fields, but spaces should
+ not be used in practice.) The fields are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <em class="replaceable"><code>STD</code></em> is the zone abbreviation to be used
+ for standard time.
+ </p></li><li class="listitem"><p>
+ <em class="replaceable"><code>offset</code></em> is the zone's standard-time offset
+ from UTC.
+ </p></li><li class="listitem"><p>
+ <em class="replaceable"><code>DST</code></em> is the zone abbreviation to be used
+ for daylight-savings time. If this field and the following ones are
+ omitted, the zone uses a fixed UTC offset with no daylight-savings
+ rule.
+ </p></li><li class="listitem"><p>
+ <em class="replaceable"><code>dstoffset</code></em> is the daylight-savings offset
+ from UTC. This field is typically omitted, since it defaults to one
+ hour less than the standard-time <em class="replaceable"><code>offset</code></em>,
+ which is usually the right thing.
+ </p></li><li class="listitem"><p>
+ <em class="replaceable"><code>rule</code></em> defines the rule for when daylight
+ savings is in effect, as described below.
+ </p></li></ul></div><p>
+ </p><p>
+ In this syntax, a zone abbreviation can be a string of letters, such
+ as <code class="literal">EST</code>, or an arbitrary string surrounded by angle
+ brackets, such as <code class="literal">&lt;UTC-05&gt;</code>.
+ Note that the zone abbreviations given here are only used for output,
+ and even then only in some timestamp output formats. The zone
+ abbreviations recognized in timestamp input are determined as explained
+ in <a class="xref" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Section B.4</a>.
+ </p><p>
+ The offset fields specify the hours, and optionally minutes and seconds,
+ difference from UTC. They have the format
+ <em class="replaceable"><code>hh</code></em>[<span class="optional"><code class="literal">:</code><em class="replaceable"><code>mm</code></em>[<span class="optional"><code class="literal">:</code><em class="replaceable"><code>ss</code></em></span>]</span>]
+ optionally with a leading sign (<code class="literal">+</code>
+ or <code class="literal">-</code>). The positive sign is used for
+ zones <span class="emphasis"><em>west</em></span> of Greenwich. (Note that this is the
+ opposite of the ISO-8601 sign convention used elsewhere in
+ <span class="productname">PostgreSQL</span>.) <em class="replaceable"><code>hh</code></em>
+ can have one or two digits; <em class="replaceable"><code>mm</code></em>
+ and <em class="replaceable"><code>ss</code></em> (if used) must have two.
+ </p><p>
+ The daylight-savings transition <em class="replaceable"><code>rule</code></em> has the
+ format
+</p><pre class="synopsis">
+<em class="replaceable"><code>dstdate</code></em> [<span class="optional"> <code class="literal">/</code> <em class="replaceable"><code>dsttime</code></em> </span>] <code class="literal">,</code> <em class="replaceable"><code>stddate</code></em> [<span class="optional"> <code class="literal">/</code> <em class="replaceable"><code>stdtime</code></em> </span>]
+</pre><p>
+ (As before, spaces should not be included in practice.)
+ The <em class="replaceable"><code>dstdate</code></em>
+ and <em class="replaceable"><code>dsttime</code></em> fields define when daylight-savings
+ time starts, while <em class="replaceable"><code>stddate</code></em>
+ and <em class="replaceable"><code>stdtime</code></em> define when standard time
+ starts. (In some cases, notably in zones south of the equator, the
+ former might be later in the year than the latter.) The date fields
+ have one of these formats:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ A plain integer denotes a day of the year, counting from zero to
+ 364, or to 365 in leap years.
+ </p></dd><dt><span class="term"><code class="literal">J</code><em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ In this form, <em class="replaceable"><code>n</code></em> counts from 1 to 365,
+ and February 29 is not counted even if it is present. (Thus, a
+ transition occurring on February 29 could not be specified this
+ way. However, days after February have the same numbers whether
+ it's a leap year or not, so that this form is usually more useful
+ than the plain-integer form for transitions on fixed dates.)
+ </p></dd><dt><span class="term"><code class="literal">M</code><em class="replaceable"><code>m</code></em><code class="literal">.</code><em class="replaceable"><code>n</code></em><code class="literal">.</code><em class="replaceable"><code>d</code></em></span></dt><dd><p>
+ This form specifies a transition that always happens during the same
+ month and on the same day of the week. <em class="replaceable"><code>m</code></em>
+ identifies the month, from 1 to 12. <em class="replaceable"><code>n</code></em>
+ specifies the <em class="replaceable"><code>n</code></em>'th occurrence of the
+ weekday identified by <em class="replaceable"><code>d</code></em>.
+ <em class="replaceable"><code>n</code></em> is a number between 1 and 4, or 5
+ meaning the last occurrence of that weekday in the month (which
+ could be the fourth or the fifth). <em class="replaceable"><code>d</code></em> is
+ a number between 0 and 6, with 0 indicating Sunday.
+ For example, <code class="literal">M3.2.0</code> means <span class="quote">“<span class="quote">the second
+ Sunday in March</span>”</span>.
+ </p></dd></dl></div><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="literal">M</code> format is sufficient to describe many common
+ daylight-savings transition laws. But note that none of these variants
+ can deal with daylight-savings law changes, so in practice the
+ historical data stored for named time zones (in the IANA time zone
+ database) is necessary to interpret past time stamps correctly.
+ </p></div><p>
+ The time fields in a transition rule have the same format as the offset
+ fields described previously, except that they cannot contain signs.
+ They define the current local time at which the change to the other
+ time occurs. If omitted, they default to <code class="literal">02:00:00</code>.
+ </p><p>
+ If a daylight-savings abbreviation is given but the
+ transition <em class="replaceable"><code>rule</code></em> field is omitted,
+ the fallback behavior is to use the
+ rule <code class="literal">M3.2.0,M11.1.0</code>, which corresponds to USA
+ practice as of 2020 (that is, spring forward on the second Sunday of
+ March, fall back on the first Sunday of November, both transitions
+ occurring at 2AM prevailing time). Note that this rule does not
+ give correct USA transition dates for years before 2007.
+ </p><p>
+ As an example, <code class="literal">CET-1CEST,M3.5.0,M10.5.0/3</code> describes
+ current (as of 2020) timekeeping practice in Paris. This specification
+ says that standard time has the abbreviation <code class="literal">CET</code> and
+ is one hour ahead (east) of UTC; daylight savings time has the
+ abbreviation <code class="literal">CEST</code> and is implicitly two hours ahead
+ of UTC; daylight savings time begins on the last Sunday in March at 2AM
+ CET and ends on the last Sunday in October at 3AM CEST.
+ </p><p>
+ The four timezone names <code class="literal">EST5EDT</code>,
+ <code class="literal">CST6CDT</code>, <code class="literal">MST7MDT</code>,
+ and <code class="literal">PST8PDT</code> look like they are POSIX zone
+ specifications. However, they actually are treated as named time zones
+ because (for historical reasons) there are files by those names in the
+ IANA time zone database. The practical implication of this is that
+ these zone names will produce valid historical USA daylight-savings
+ transitions, even when a plain POSIX specification would not.
+ </p><p>
+ One should be wary that it is easy to misspell a POSIX-style time zone
+ specification, since there is no check on the reasonableness of the
+ zone abbreviation(s). For example, <code class="literal">SET TIMEZONE TO
+ FOOBAR0</code> will work, leaving the system effectively using a
+ rather peculiar abbreviation for UTC.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-units-history.html" title="B.6. History of Units">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.4. Date/Time Configuration Files </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.6. History of Units</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/datetime-units-history.html b/doc/src/sgml/html/datetime-units-history.html
new file mode 100644
index 0000000..19b0a3c
--- /dev/null
+++ b/doc/src/sgml/html/datetime-units-history.html
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>B.6. History of Units</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications" /><link rel="next" href="datetime-julian-dates.html" title="B.7. Julian Dates" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">B.6. History of Units</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><th width="60%" align="center">Appendix B. Date/Time Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-julian-dates.html" title="B.7. Julian Dates">Next</a></td></tr></table><hr /></div><div class="sect1" id="DATETIME-UNITS-HISTORY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">B.6. History of Units</h2></div></div></div><a id="id-1.11.3.9.2" class="indexterm"></a><p>
+ The SQL standard states that <span class="quote">“<span class="quote">Within the definition of a
+ <span class="quote">‘<span class="quote">datetime literal</span>’</span>, the <span class="quote">‘<span class="quote">datetime
+ values</span>’</span> are constrained by the natural rules for dates and
+ times according to the Gregorian calendar</span>”</span>.
+ <span class="productname">PostgreSQL</span> follows the SQL
+ standard's lead by counting dates exclusively in the Gregorian
+ calendar, even for years before that calendar was in use.
+ This rule is known as the <em class="firstterm">proleptic Gregorian calendar</em>.
+ </p><p>
+ The Julian calendar was introduced by Julius Caesar in 45 BC.
+ It was in common use in the Western world
+ until the year 1582, when countries started changing to the Gregorian
+ calendar. In the Julian calendar, the tropical year is
+ approximated as 365 1/4 days = 365.25 days. This gives an error of
+ about 1 day in 128 years.
+ </p><p>
+ The accumulating calendar error prompted
+ Pope Gregory XIII to reform the calendar in accordance with
+ instructions from the Council of Trent.
+ In the Gregorian calendar, the tropical year is approximated as
+ 365 + 97 / 400 days = 365.2425 days. Thus it takes approximately 3300
+ years for the tropical year to shift one day with respect to the
+ Gregorian calendar.
+ </p><p>
+ The approximation 365+97/400 is achieved by having 97 leap years
+ every 400 years, using the following rules:
+
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td>
+ Every year divisible by 4 is a leap year.
+ </td></tr><tr><td>
+ However, every year divisible by 100 is not a leap year.
+ </td></tr><tr><td>
+ However, every year divisible by 400 is a leap year after all.
+ </td></tr></table><p>
+
+ So, 1700, 1800, 1900, 2100, and 2200 are not leap years. But 1600,
+ 2000, and 2400 are leap years.
+
+ By contrast, in the older Julian calendar all years divisible by 4 are leap
+ years.
+ </p><p>
+ The papal bull of February 1582 decreed that 10 days should be dropped
+ from October 1582 so that 15 October should follow immediately after
+ 4 October.
+ This was observed in Italy, Poland, Portugal, and Spain. Other Catholic
+ countries followed shortly after, but Protestant countries were
+ reluctant to change, and the Greek Orthodox countries didn't change
+ until the start of the 20th century.
+
+ The reform was observed by Great Britain and its dominions (including what
+ is now the USA) in 1752.
+ Thus 2 September 1752 was followed by 14 September 1752.
+
+ This is why Unix systems that have the <code class="command">cal</code> program
+ produce the following:
+
+</p><pre class="screen">
+$ <strong class="userinput"><code>cal 9 1752</code></strong>
+ September 1752
+ S M Tu W Th F S
+ 1 2 14 15 16
+17 18 19 20 21 22 23
+24 25 26 27 28 29 30
+</pre><p>
+
+ But, of course, this calendar is only valid for Great Britain and
+ dominions, not other places.
+ Since it would be difficult and confusing to try to track the actual
+ calendars that were in use in various places at various times,
+ <span class="productname">PostgreSQL</span> does not try, but rather follows the Gregorian
+ calendar rules for all dates, even though this method is not historically
+ accurate.
+ </p><p>
+ Different calendars have been developed in various parts of the
+ world, many predating the Gregorian system.
+
+ For example,
+ the beginnings of the Chinese calendar can be traced back to the 14th
+ century BC. Legend has it that the Emperor Huangdi invented that
+ calendar in 2637 BC.
+
+ The People's Republic of China uses the Gregorian calendar
+ for civil purposes. The Chinese calendar is used for determining
+ festivals.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-posix-timezone-specs.html" title="B.5. POSIX Time Zone Specifications">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-julian-dates.html" title="B.7. Julian Dates">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.5. <acronym class="acronym">POSIX</acronym> Time Zone Specifications </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> B.7. Julian Dates</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dblink.html b/doc/src/sgml/html/dblink.html
new file mode 100644
index 0000000..071f01d
--- /dev/null
+++ b/doc/src/sgml/html/dblink.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.12. dblink</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="cube.html" title="F.11. cube" /><link rel="next" href="contrib-dblink-connect.html" title="dblink_connect" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.12. dblink</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="cube.html" title="F.11. cube">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-dblink-connect.html" title="dblink_connect">Next</a></td></tr></table><hr /></div><div class="sect1" id="DBLINK"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.12. dblink</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="contrib-dblink-connect.html">dblink_connect</a></span><span class="refpurpose"> — opens a persistent connection to a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-connect-u.html">dblink_connect_u</a></span><span class="refpurpose"> — opens a persistent connection to a remote database, insecurely</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-disconnect.html">dblink_disconnect</a></span><span class="refpurpose"> — closes a persistent connection to a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-function.html">dblink</a></span><span class="refpurpose"> — executes a query in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-exec.html">dblink_exec</a></span><span class="refpurpose"> — executes a command in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-open.html">dblink_open</a></span><span class="refpurpose"> — opens a cursor in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-fetch.html">dblink_fetch</a></span><span class="refpurpose"> — returns rows from an open cursor in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-close.html">dblink_close</a></span><span class="refpurpose"> — closes a cursor in a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-connections.html">dblink_get_connections</a></span><span class="refpurpose"> — returns the names of all open named dblink connections</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-error-message.html">dblink_error_message</a></span><span class="refpurpose"> — gets last error message on the named connection</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-send-query.html">dblink_send_query</a></span><span class="refpurpose"> — sends an async query to a remote database</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-is-busy.html">dblink_is_busy</a></span><span class="refpurpose"> — checks if connection is busy with an async query</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-notify.html">dblink_get_notify</a></span><span class="refpurpose"> — retrieve async notifications on a connection</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-result.html">dblink_get_result</a></span><span class="refpurpose"> — gets an async query result</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-cancel-query.html">dblink_cancel_query</a></span><span class="refpurpose"> — cancels any active query on the named connection</span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-get-pkey.html">dblink_get_pkey</a></span><span class="refpurpose"> — returns the positions and field names of a relation's
+ primary key fields
+ </span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-build-sql-insert.html">dblink_build_sql_insert</a></span><span class="refpurpose"> —
+ builds an INSERT statement using a local tuple, replacing the
+ primary key field values with alternative supplied values
+ </span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-build-sql-delete.html">dblink_build_sql_delete</a></span><span class="refpurpose"> — builds a DELETE statement using supplied values for primary
+ key field values
+ </span></dt><dt><span class="refentrytitle"><a href="contrib-dblink-build-sql-update.html">dblink_build_sql_update</a></span><span class="refpurpose"> — builds an UPDATE statement using a local tuple, replacing
+ the primary key field values with alternative supplied values
+ </span></dt></dl></div><a id="id-1.11.7.21.2" class="indexterm"></a><p>
+ <code class="filename">dblink</code> is a module that supports connections to
+ other <span class="productname">PostgreSQL</span> databases from within a database
+ session.
+ </p><p>
+ See also <a class="xref" href="postgres-fdw.html" title="F.38. postgres_fdw">postgres_fdw</a>, which provides roughly the same
+ functionality using a more modern and standards-compliant infrastructure.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="cube.html" title="F.11. cube">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-dblink-connect.html" title="dblink_connect">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.11. cube </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> dblink_connect</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-alter.html b/doc/src/sgml/html/ddl-alter.html
new file mode 100644
index 0000000..57613f0
--- /dev/null
+++ b/doc/src/sgml/html/ddl-alter.html
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.6. Modifying Tables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-system-columns.html" title="5.5. System Columns" /><link rel="next" href="ddl-priv.html" title="5.7. Privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.6. Modifying Tables</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-system-columns.html" title="5.5. System Columns">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-priv.html" title="5.7. Privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-ALTER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.6. Modifying Tables</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-ADDING-A-COLUMN">5.6.1. Adding a Column</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-REMOVING-A-COLUMN">5.6.2. Removing a Column</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-ADDING-A-CONSTRAINT">5.6.3. Adding a Constraint</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-REMOVING-A-CONSTRAINT">5.6.4. Removing a Constraint</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.9">5.6.5. Changing a Column's Default Value</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.10">5.6.6. Changing a Column's Data Type</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.11">5.6.7. Renaming a Column</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.12">5.6.8. Renaming a Table</a></span></dt></dl></div><a id="id-1.5.4.8.2" class="indexterm"></a><p>
+ When you create a table and you realize that you made a mistake, or
+ the requirements of the application change, you can drop the
+ table and create it again. But this is not a convenient option if
+ the table is already filled with data, or if the table is
+ referenced by other database objects (for instance a foreign key
+ constraint). Therefore <span class="productname">PostgreSQL</span>
+ provides a family of commands to make modifications to existing
+ tables. Note that this is conceptually distinct from altering
+ the data contained in the table: here we are interested in altering
+ the definition, or structure, of the table.
+ </p><p>
+ You can:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>Add columns</p></li><li class="listitem"><p>Remove columns</p></li><li class="listitem"><p>Add constraints</p></li><li class="listitem"><p>Remove constraints</p></li><li class="listitem"><p>Change default values</p></li><li class="listitem"><p>Change column data types</p></li><li class="listitem"><p>Rename columns</p></li><li class="listitem"><p>Rename tables</p></li></ul></div><p>
+
+ All these actions are performed using the
+ <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>
+ command, whose reference page contains details beyond those given
+ here.
+ </p><div class="sect2" id="DDL-ALTER-ADDING-A-COLUMN"><div class="titlepage"><div><div><h3 class="title">5.6.1. Adding a Column</h3></div></div></div><a id="id-1.5.4.8.5.2" class="indexterm"></a><p>
+ To add a column, use a command like:
+</p><pre class="programlisting">
+ALTER TABLE products ADD COLUMN description text;
+</pre><p>
+ The new column is initially filled with whatever default
+ value is given (null if you don't specify a <code class="literal">DEFAULT</code> clause).
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ From <span class="productname">PostgreSQL</span> 11, adding a column with
+ a constant default value no longer means that each row of the table
+ needs to be updated when the <code class="command">ALTER TABLE</code> statement
+ is executed. Instead, the default value will be returned the next time
+ the row is accessed, and applied when the table is rewritten, making
+ the <code class="command">ALTER TABLE</code> very fast even on large tables.
+ </p><p>
+ However, if the default value is volatile (e.g.,
+ <code class="function">clock_timestamp()</code>)
+ each row will need to be updated with the value calculated at the time
+ <code class="command">ALTER TABLE</code> is executed. To avoid a potentially
+ lengthy update operation, particularly if you intend to fill the column
+ with mostly nondefault values anyway, it may be preferable to add the
+ column with no default, insert the correct values using
+ <code class="command">UPDATE</code>, and then add any desired default as described
+ below.
+ </p></div><p>
+ You can also define constraints on the column at the same time,
+ using the usual syntax:
+</p><pre class="programlisting">
+ALTER TABLE products ADD COLUMN description text CHECK (description &lt;&gt; '');
+</pre><p>
+ In fact all the options that can be applied to a column description
+ in <code class="command">CREATE TABLE</code> can be used here. Keep in mind however
+ that the default value must satisfy the given constraints, or the
+ <code class="literal">ADD</code> will fail. Alternatively, you can add
+ constraints later (see below) after you've filled in the new column
+ correctly.
+ </p></div><div class="sect2" id="DDL-ALTER-REMOVING-A-COLUMN"><div class="titlepage"><div><div><h3 class="title">5.6.2. Removing a Column</h3></div></div></div><a id="id-1.5.4.8.6.2" class="indexterm"></a><p>
+ To remove a column, use a command like:
+</p><pre class="programlisting">
+ALTER TABLE products DROP COLUMN description;
+</pre><p>
+ Whatever data was in the column disappears. Table constraints involving
+ the column are dropped, too. However, if the column is referenced by a
+ foreign key constraint of another table,
+ <span class="productname">PostgreSQL</span> will not silently drop that
+ constraint. You can authorize dropping everything that depends on
+ the column by adding <code class="literal">CASCADE</code>:
+</p><pre class="programlisting">
+ALTER TABLE products DROP COLUMN description CASCADE;
+</pre><p>
+ See <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a> for a description of the general
+ mechanism behind this.
+ </p></div><div class="sect2" id="DDL-ALTER-ADDING-A-CONSTRAINT"><div class="titlepage"><div><div><h3 class="title">5.6.3. Adding a Constraint</h3></div></div></div><a id="id-1.5.4.8.7.2" class="indexterm"></a><p>
+ To add a constraint, the table constraint syntax is used. For example:
+</p><pre class="programlisting">
+ALTER TABLE products ADD CHECK (name &lt;&gt; '');
+ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no);
+ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;
+</pre><p>
+ To add a not-null constraint, which cannot be written as a table
+ constraint, use this syntax:
+</p><pre class="programlisting">
+ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;
+</pre><p>
+ </p><p>
+ The constraint will be checked immediately, so the table data must
+ satisfy the constraint before it can be added.
+ </p></div><div class="sect2" id="DDL-ALTER-REMOVING-A-CONSTRAINT"><div class="titlepage"><div><div><h3 class="title">5.6.4. Removing a Constraint</h3></div></div></div><a id="id-1.5.4.8.8.2" class="indexterm"></a><p>
+ To remove a constraint you need to know its name. If you gave it
+ a name then that's easy. Otherwise the system assigned a
+ generated name, which you need to find out. The
+ <span class="application">psql</span> command <code class="literal">\d
+ <em class="replaceable"><code>tablename</code></em></code> can be helpful
+ here; other interfaces might also provide a way to inspect table
+ details. Then the command is:
+</p><pre class="programlisting">
+ALTER TABLE products DROP CONSTRAINT some_name;
+</pre><p>
+ (If you are dealing with a generated constraint name like <code class="literal">$2</code>,
+ don't forget that you'll need to double-quote it to make it a valid
+ identifier.)
+ </p><p>
+ As with dropping a column, you need to add <code class="literal">CASCADE</code> if you
+ want to drop a constraint that something else depends on. An example
+ is that a foreign key constraint depends on a unique or primary key
+ constraint on the referenced column(s).
+ </p><p>
+ This works the same for all constraint types except not-null
+ constraints. To drop a not null constraint use:
+</p><pre class="programlisting">
+ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
+</pre><p>
+ (Recall that not-null constraints do not have names.)
+ </p></div><div class="sect2" id="id-1.5.4.8.9"><div class="titlepage"><div><div><h3 class="title">5.6.5. Changing a Column's Default Value</h3></div></div></div><a id="id-1.5.4.8.9.2" class="indexterm"></a><p>
+ To set a new default for a column, use a command like:
+</p><pre class="programlisting">
+ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
+</pre><p>
+ Note that this doesn't affect any existing rows in the table, it
+ just changes the default for future <code class="command">INSERT</code> commands.
+ </p><p>
+ To remove any default value, use:
+</p><pre class="programlisting">
+ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
+</pre><p>
+ This is effectively the same as setting the default to null.
+ As a consequence, it is not an error
+ to drop a default where one hadn't been defined, because the
+ default is implicitly the null value.
+ </p></div><div class="sect2" id="id-1.5.4.8.10"><div class="titlepage"><div><div><h3 class="title">5.6.6. Changing a Column's Data Type</h3></div></div></div><a id="id-1.5.4.8.10.2" class="indexterm"></a><p>
+ To convert a column to a different data type, use a command like:
+</p><pre class="programlisting">
+ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
+</pre><p>
+ This will succeed only if each existing entry in the column can be
+ converted to the new type by an implicit cast. If a more complex
+ conversion is needed, you can add a <code class="literal">USING</code> clause that
+ specifies how to compute the new values from the old.
+ </p><p>
+ <span class="productname">PostgreSQL</span> will attempt to convert the column's
+ default value (if any) to the new type, as well as any constraints
+ that involve the column. But these conversions might fail, or might
+ produce surprising results. It's often best to drop any constraints
+ on the column before altering its type, and then add back suitably
+ modified constraints afterwards.
+ </p></div><div class="sect2" id="id-1.5.4.8.11"><div class="titlepage"><div><div><h3 class="title">5.6.7. Renaming a Column</h3></div></div></div><a id="id-1.5.4.8.11.2" class="indexterm"></a><p>
+ To rename a column:
+</p><pre class="programlisting">
+ALTER TABLE products RENAME COLUMN product_no TO product_number;
+</pre><p>
+ </p></div><div class="sect2" id="id-1.5.4.8.12"><div class="titlepage"><div><div><h3 class="title">5.6.8. Renaming a Table</h3></div></div></div><a id="id-1.5.4.8.12.2" class="indexterm"></a><p>
+ To rename a table:
+</p><pre class="programlisting">
+ALTER TABLE products RENAME TO items;
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-system-columns.html" title="5.5. System Columns">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-priv.html" title="5.7. Privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.5. System Columns </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.7. Privileges</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-basics.html b/doc/src/sgml/html/ddl-basics.html
new file mode 100644
index 0000000..33d00e7
--- /dev/null
+++ b/doc/src/sgml/html/ddl-basics.html
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.1. Table Basics</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl.html" title="Chapter 5. Data Definition" /><link rel="next" href="ddl-default.html" title="5.2. Default Values" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.1. Table Basics</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl.html" title="Chapter 5. Data Definition">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-default.html" title="5.2. Default Values">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-BASICS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.1. Table Basics</h2></div></div></div><a id="id-1.5.4.3.2" class="indexterm"></a><a id="id-1.5.4.3.3" class="indexterm"></a><a id="id-1.5.4.3.4" class="indexterm"></a><p>
+ A table in a relational database is much like a table on paper: It
+ consists of rows and columns. The number and order of the columns
+ is fixed, and each column has a name. The number of rows is
+ variable — it reflects how much data is stored at a given moment.
+ SQL does not make any guarantees about the order of the rows in a
+ table. When a table is read, the rows will appear in an unspecified order,
+ unless sorting is explicitly requested. This is covered in <a class="xref" href="queries.html" title="Chapter 7. Queries">Chapter 7</a>. Furthermore, SQL does not assign unique
+ identifiers to rows, so it is possible to have several completely
+ identical rows in a table. This is a consequence of the
+ mathematical model that underlies SQL but is usually not desirable.
+ Later in this chapter we will see how to deal with this issue.
+ </p><p>
+ Each column has a data type. The data type constrains the set of
+ possible values that can be assigned to a column and assigns
+ semantics to the data stored in the column so that it can be used
+ for computations. For instance, a column declared to be of a
+ numerical type will not accept arbitrary text strings, and the data
+ stored in such a column can be used for mathematical computations.
+ By contrast, a column declared to be of a character string type
+ will accept almost any kind of data but it does not lend itself to
+ mathematical calculations, although other operations such as string
+ concatenation are available.
+ </p><p>
+ <span class="productname">PostgreSQL</span> includes a sizable set of
+ built-in data types that fit many applications. Users can also
+ define their own data types. Most built-in data types have obvious
+ names and semantics, so we defer a detailed explanation to <a class="xref" href="datatype.html" title="Chapter 8. Data Types">Chapter 8</a>. Some of the frequently used data types are
+ <code class="type">integer</code> for whole numbers, <code class="type">numeric</code> for
+ possibly fractional numbers, <code class="type">text</code> for character
+ strings, <code class="type">date</code> for dates, <code class="type">time</code> for
+ time-of-day values, and <code class="type">timestamp</code> for values
+ containing both date and time.
+ </p><a id="id-1.5.4.3.8" class="indexterm"></a><p>
+ To create a table, you use the aptly named <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> command.
+ In this command you specify at least a name for the new table, the
+ names of the columns and the data type of each column. For
+ example:
+</p><pre class="programlisting">
+CREATE TABLE my_first_table (
+ first_column text,
+ second_column integer
+);
+</pre><p>
+ This creates a table named <code class="literal">my_first_table</code> with
+ two columns. The first column is named
+ <code class="literal">first_column</code> and has a data type of
+ <code class="type">text</code>; the second column has the name
+ <code class="literal">second_column</code> and the type <code class="type">integer</code>.
+ The table and column names follow the identifier syntax explained
+ in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS" title="4.1.1. Identifiers and Key Words">Section 4.1.1</a>. The type names are
+ usually also identifiers, but there are some exceptions. Note that the
+ column list is comma-separated and surrounded by parentheses.
+ </p><p>
+ Of course, the previous example was heavily contrived. Normally,
+ you would give names to your tables and columns that convey what
+ kind of data they store. So let's look at a more realistic
+ example:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric
+);
+</pre><p>
+ (The <code class="type">numeric</code> type can store fractional components, as
+ would be typical of monetary amounts.)
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ When you create many interrelated tables it is wise to choose a
+ consistent naming pattern for the tables and columns. For
+ instance, there is a choice of using singular or plural nouns for
+ table names, both of which are favored by some theorist or other.
+ </p></div><p>
+ There is a limit on how many columns a table can contain.
+ Depending on the column types, it is between 250 and 1600.
+ However, defining a table with anywhere near this many columns is
+ highly unusual and often a questionable design.
+ </p><a id="id-1.5.4.3.13" class="indexterm"></a><p>
+ If you no longer need a table, you can remove it using the <a class="xref" href="sql-droptable.html" title="DROP TABLE"><span class="refentrytitle">DROP TABLE</span></a> command.
+ For example:
+</p><pre class="programlisting">
+DROP TABLE my_first_table;
+DROP TABLE products;
+</pre><p>
+ Attempting to drop a table that does not exist is an error.
+ Nevertheless, it is common in SQL script files to unconditionally
+ try to drop each table before creating it, ignoring any error
+ messages, so that the script works whether or not the table exists.
+ (If you like, you can use the <code class="literal">DROP TABLE IF EXISTS</code> variant
+ to avoid the error messages, but this is not standard SQL.)
+ </p><p>
+ If you need to modify a table that already exists, see <a class="xref" href="ddl-alter.html" title="5.6. Modifying Tables">Section 5.6</a> later in this chapter.
+ </p><p>
+ With the tools discussed so far you can create fully functional
+ tables. The remainder of this chapter is concerned with adding
+ features to the table definition to ensure data integrity,
+ security, or convenience. If you are eager to fill your tables with
+ data now you can skip ahead to <a class="xref" href="dml.html" title="Chapter 6. Data Manipulation">Chapter 6</a> and read the
+ rest of this chapter later.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl.html" title="Chapter 5. Data Definition">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-default.html" title="5.2. Default Values">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 5. Data Definition </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.2. Default Values</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-constraints.html b/doc/src/sgml/html/ddl-constraints.html
new file mode 100644
index 0000000..6e51ee4
--- /dev/null
+++ b/doc/src/sgml/html/ddl-constraints.html
@@ -0,0 +1,607 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.4. Constraints</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-generated-columns.html" title="5.3. Generated Columns" /><link rel="next" href="ddl-system-columns.html" title="5.5. System Columns" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.4. Constraints</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-generated-columns.html" title="5.3. Generated Columns">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-system-columns.html" title="5.5. System Columns">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-CONSTRAINTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.4. Constraints</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS">5.4.1. Check Constraints</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#id-1.5.4.6.6">5.4.2. Not-Null Constraints</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS">5.4.3. Unique Constraints</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-PRIMARY-KEYS">5.4.4. Primary Keys</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-FK">5.4.5. Foreign Keys</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION">5.4.6. Exclusion Constraints</a></span></dt></dl></div><a id="id-1.5.4.6.2" class="indexterm"></a><p>
+ Data types are a way to limit the kind of data that can be stored
+ in a table. For many applications, however, the constraint they
+ provide is too coarse. For example, a column containing a product
+ price should probably only accept positive values. But there is no
+ standard data type that accepts only positive numbers. Another issue is
+ that you might want to constrain column data with respect to other
+ columns or rows. For example, in a table containing product
+ information, there should be only one row for each product number.
+ </p><p>
+ To that end, SQL allows you to define constraints on columns and
+ tables. Constraints give you as much control over the data in your
+ tables as you wish. If a user attempts to store data in a column
+ that would violate a constraint, an error is raised. This applies
+ even if the value came from the default value definition.
+ </p><div class="sect2" id="DDL-CONSTRAINTS-CHECK-CONSTRAINTS"><div class="titlepage"><div><div><h3 class="title">5.4.1. Check Constraints</h3></div></div></div><a id="id-1.5.4.6.5.2" class="indexterm"></a><a id="id-1.5.4.6.5.3" class="indexterm"></a><p>
+ A check constraint is the most generic constraint type. It allows
+ you to specify that the value in a certain column must satisfy a
+ Boolean (truth-value) expression. For instance, to require positive
+ product prices, you could use:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric <span class="emphasis"><strong>CHECK (price &gt; 0)</strong></span>
+);
+</pre><p>
+ </p><p>
+ As you see, the constraint definition comes after the data type,
+ just like default value definitions. Default values and
+ constraints can be listed in any order. A check constraint
+ consists of the key word <code class="literal">CHECK</code> followed by an
+ expression in parentheses. The check constraint expression should
+ involve the column thus constrained, otherwise the constraint
+ would not make too much sense.
+ </p><a id="id-1.5.4.6.5.6" class="indexterm"></a><p>
+ You can also give the constraint a separate name. This clarifies
+ error messages and allows you to refer to the constraint when you
+ need to change it. The syntax is:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric <span class="emphasis"><strong>CONSTRAINT positive_price</strong></span> CHECK (price &gt; 0)
+);
+</pre><p>
+ So, to specify a named constraint, use the key word
+ <code class="literal">CONSTRAINT</code> followed by an identifier followed
+ by the constraint definition. (If you don't specify a constraint
+ name in this way, the system chooses a name for you.)
+ </p><p>
+ A check constraint can also refer to several columns. Say you
+ store a regular price and a discounted price, and you want to
+ ensure that the discounted price is lower than the regular price:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric CHECK (price &gt; 0),
+ discounted_price numeric CHECK (discounted_price &gt; 0),
+ <span class="emphasis"><strong>CHECK (price &gt; discounted_price)</strong></span>
+);
+</pre><p>
+ </p><p>
+ The first two constraints should look familiar. The third one
+ uses a new syntax. It is not attached to a particular column,
+ instead it appears as a separate item in the comma-separated
+ column list. Column definitions and these constraint
+ definitions can be listed in mixed order.
+ </p><p>
+ We say that the first two constraints are column constraints, whereas the
+ third one is a table constraint because it is written separately
+ from any one column definition. Column constraints can also be
+ written as table constraints, while the reverse is not necessarily
+ possible, since a column constraint is supposed to refer to only the
+ column it is attached to. (<span class="productname">PostgreSQL</span> doesn't
+ enforce that rule, but you should follow it if you want your table
+ definitions to work with other database systems.) The above example could
+ also be written as:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ CHECK (price &gt; 0),
+ discounted_price numeric,
+ CHECK (discounted_price &gt; 0),
+ CHECK (price &gt; discounted_price)
+);
+</pre><p>
+ or even:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric CHECK (price &gt; 0),
+ discounted_price numeric,
+ CHECK (discounted_price &gt; 0 AND price &gt; discounted_price)
+);
+</pre><p>
+ It's a matter of taste.
+ </p><p>
+ Names can be assigned to table constraints in the same way as
+ column constraints:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ CHECK (price &gt; 0),
+ discounted_price numeric,
+ CHECK (discounted_price &gt; 0),
+ <span class="emphasis"><strong>CONSTRAINT valid_discount</strong></span> CHECK (price &gt; discounted_price)
+);
+</pre><p>
+ </p><a id="id-1.5.4.6.5.12" class="indexterm"></a><p>
+ It should be noted that a check constraint is satisfied if the
+ check expression evaluates to true or the null value. Since most
+ expressions will evaluate to the null value if any operand is null,
+ they will not prevent null values in the constrained columns. To
+ ensure that a column does not contain null values, the not-null
+ constraint described in the next section can be used.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> does not support
+ <code class="literal">CHECK</code> constraints that reference table data other than
+ the new or updated row being checked. While a <code class="literal">CHECK</code>
+ constraint that violates this rule may appear to work in simple
+ tests, it cannot guarantee that the database will not reach a state
+ in which the constraint condition is false (due to subsequent changes
+ of the other row(s) involved). This would cause a database dump and
+ restore to fail. The restore could fail even when the complete
+ database state is consistent with the constraint, due to rows not
+ being loaded in an order that will satisfy the constraint. If
+ possible, use <code class="literal">UNIQUE</code>, <code class="literal">EXCLUDE</code>,
+ or <code class="literal">FOREIGN KEY</code> constraints to express
+ cross-row and cross-table restrictions.
+ </p><p>
+ If what you desire is a one-time check against other rows at row
+ insertion, rather than a continuously-maintained consistency
+ guarantee, a custom <a class="link" href="triggers.html" title="Chapter 39. Triggers">trigger</a> can be used
+ to implement that. (This approach avoids the dump/restore problem because
+ <span class="application">pg_dump</span> does not reinstall triggers until after
+ restoring data, so that the check will not be enforced during a
+ dump/restore.)
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> assumes that
+ <code class="literal">CHECK</code> constraints' conditions are immutable, that
+ is, they will always give the same result for the same input row.
+ This assumption is what justifies examining <code class="literal">CHECK</code>
+ constraints only when rows are inserted or updated, and not at other
+ times. (The warning above about not referencing other table data is
+ really a special case of this restriction.)
+ </p><p>
+ An example of a common way to break this assumption is to reference a
+ user-defined function in a <code class="literal">CHECK</code> expression, and
+ then change the behavior of that
+ function. <span class="productname">PostgreSQL</span> does not disallow
+ that, but it will not notice if there are rows in the table that now
+ violate the <code class="literal">CHECK</code> constraint. That would cause a
+ subsequent database dump and restore to fail.
+ The recommended way to handle such a change is to drop the constraint
+ (using <code class="command">ALTER TABLE</code>), adjust the function definition,
+ and re-add the constraint, thereby rechecking it against all table rows.
+ </p></div></div><div class="sect2" id="id-1.5.4.6.6"><div class="titlepage"><div><div><h3 class="title">5.4.2. Not-Null Constraints</h3></div></div></div><a id="id-1.5.4.6.6.2" class="indexterm"></a><a id="id-1.5.4.6.6.3" class="indexterm"></a><p>
+ A not-null constraint simply specifies that a column must not
+ assume the null value. A syntax example:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer <span class="emphasis"><strong>NOT NULL</strong></span>,
+ name text <span class="emphasis"><strong>NOT NULL</strong></span>,
+ price numeric
+);
+</pre><p>
+ </p><p>
+ A not-null constraint is always written as a column constraint. A
+ not-null constraint is functionally equivalent to creating a check
+ constraint <code class="literal">CHECK (<em class="replaceable"><code>column_name</code></em>
+ IS NOT NULL)</code>, but in
+ <span class="productname">PostgreSQL</span> creating an explicit
+ not-null constraint is more efficient. The drawback is that you
+ cannot give explicit names to not-null constraints created this
+ way.
+ </p><p>
+ Of course, a column can have more than one constraint. Just write
+ the constraints one after another:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer NOT NULL,
+ name text NOT NULL,
+ price numeric NOT NULL CHECK (price &gt; 0)
+);
+</pre><p>
+ The order doesn't matter. It does not necessarily determine in which
+ order the constraints are checked.
+ </p><p>
+ The <code class="literal">NOT NULL</code> constraint has an inverse: the
+ <code class="literal">NULL</code> constraint. This does not mean that the
+ column must be null, which would surely be useless. Instead, this
+ simply selects the default behavior that the column might be null.
+ The <code class="literal">NULL</code> constraint is not present in the SQL
+ standard and should not be used in portable applications. (It was
+ only added to <span class="productname">PostgreSQL</span> to be
+ compatible with some other database systems.) Some users, however,
+ like it because it makes it easy to toggle the constraint in a
+ script file. For example, you could start with:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer NULL,
+ name text NULL,
+ price numeric NULL
+);
+</pre><p>
+ and then insert the <code class="literal">NOT</code> key word where desired.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ In most database designs the majority of columns should be marked
+ not null.
+ </p></div></div><div class="sect2" id="DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS"><div class="titlepage"><div><div><h3 class="title">5.4.3. Unique Constraints</h3></div></div></div><a id="id-1.5.4.6.7.2" class="indexterm"></a><a id="id-1.5.4.6.7.3" class="indexterm"></a><p>
+ Unique constraints ensure that the data contained in a column, or a
+ group of columns, is unique among all the rows in the
+ table. The syntax is:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer <span class="emphasis"><strong>UNIQUE</strong></span>,
+ name text,
+ price numeric
+);
+</pre><p>
+ when written as a column constraint, and:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ <span class="emphasis"><strong>UNIQUE (product_no)</strong></span>
+);
+</pre><p>
+ when written as a table constraint.
+ </p><p>
+ To define a unique constraint for a group of columns, write it as a
+ table constraint with the column names separated by commas:
+</p><pre class="programlisting">
+CREATE TABLE example (
+ a integer,
+ b integer,
+ c integer,
+ <span class="emphasis"><strong>UNIQUE (a, c)</strong></span>
+);
+</pre><p>
+ This specifies that the combination of values in the indicated columns
+ is unique across the whole table, though any one of the columns
+ need not be (and ordinarily isn't) unique.
+ </p><p>
+ You can assign your own name for a unique constraint, in the usual way:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer <span class="emphasis"><strong>CONSTRAINT must_be_different</strong></span> UNIQUE,
+ name text,
+ price numeric
+);
+</pre><p>
+ </p><p>
+ Adding a unique constraint will automatically create a unique B-tree
+ index on the column or group of columns listed in the constraint.
+ A uniqueness restriction covering only some rows cannot be written as
+ a unique constraint, but it is possible to enforce such a restriction by
+ creating a unique <a class="link" href="indexes-partial.html" title="11.8. Partial Indexes">partial index</a>.
+ </p><a id="id-1.5.4.6.7.8" class="indexterm"></a><p>
+ In general, a unique constraint is violated if there is more than
+ one row in the table where the values of all of the
+ columns included in the constraint are equal.
+ By default, two null values are not considered equal in this
+ comparison. That means even in the presence of a
+ unique constraint it is possible to store duplicate
+ rows that contain a null value in at least one of the constrained
+ columns. This behavior can be changed by adding the clause <code class="literal">NULLS
+ NOT DISTINCT</code>, like
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer UNIQUE <span class="emphasis"><strong>NULLS NOT DISTINCT</strong></span>,
+ name text,
+ price numeric
+);
+</pre><p>
+ or
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric,
+ UNIQUE <span class="emphasis"><strong>NULLS NOT DISTINCT</strong></span> (product_no)
+);
+</pre><p>
+ The default behavior can be specified explicitly using <code class="literal">NULLS
+ DISTINCT</code>. The default null treatment in unique constraints is
+ implementation-defined according to the SQL standard, and other
+ implementations have a different behavior. So be careful when developing
+ applications that are intended to be portable.
+ </p></div><div class="sect2" id="DDL-CONSTRAINTS-PRIMARY-KEYS"><div class="titlepage"><div><div><h3 class="title">5.4.4. Primary Keys</h3></div></div></div><a id="id-1.5.4.6.8.2" class="indexterm"></a><a id="id-1.5.4.6.8.3" class="indexterm"></a><p>
+ A primary key constraint indicates that a column, or group of columns,
+ can be used as a unique identifier for rows in the table. This
+ requires that the values be both unique and not null. So, the following
+ two table definitions accept the same data:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer UNIQUE NOT NULL,
+ name text,
+ price numeric
+);
+</pre><p>
+
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer <span class="emphasis"><strong>PRIMARY KEY</strong></span>,
+ name text,
+ price numeric
+);
+</pre><p>
+ </p><p>
+ Primary keys can span more than one column; the syntax
+ is similar to unique constraints:
+</p><pre class="programlisting">
+CREATE TABLE example (
+ a integer,
+ b integer,
+ c integer,
+ <span class="emphasis"><strong>PRIMARY KEY (a, c)</strong></span>
+);
+</pre><p>
+ </p><p>
+ Adding a primary key will automatically create a unique B-tree index
+ on the column or group of columns listed in the primary key, and will
+ force the column(s) to be marked <code class="literal">NOT NULL</code>.
+ </p><p>
+ A table can have at most one primary key. (There can be any number
+ of unique and not-null constraints, which are functionally almost the
+ same thing, but only one can be identified as the primary key.)
+ Relational database theory
+ dictates that every table must have a primary key. This rule is
+ not enforced by <span class="productname">PostgreSQL</span>, but it is
+ usually best to follow it.
+ </p><p>
+ Primary keys are useful both for
+ documentation purposes and for client applications. For example,
+ a GUI application that allows modifying row values probably needs
+ to know the primary key of a table to be able to identify rows
+ uniquely. There are also various ways in which the database system
+ makes use of a primary key if one has been declared; for example,
+ the primary key defines the default target column(s) for foreign keys
+ referencing its table.
+ </p></div><div class="sect2" id="DDL-CONSTRAINTS-FK"><div class="titlepage"><div><div><h3 class="title">5.4.5. Foreign Keys</h3></div></div></div><a id="id-1.5.4.6.9.2" class="indexterm"></a><a id="id-1.5.4.6.9.3" class="indexterm"></a><a id="id-1.5.4.6.9.4" class="indexterm"></a><p>
+ A foreign key constraint specifies that the values in a column (or
+ a group of columns) must match the values appearing in some row
+ of another table.
+ We say this maintains the <em class="firstterm">referential
+ integrity</em> between two related tables.
+ </p><p>
+ Say you have the product table that we have used several times already:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+</pre><p>
+ Let's also assume you have a table storing orders of those
+ products. We want to ensure that the orders table only contains
+ orders of products that actually exist. So we define a foreign
+ key constraint in the orders table that references the products
+ table:
+</p><pre class="programlisting">
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ product_no integer <span class="emphasis"><strong>REFERENCES products (product_no)</strong></span>,
+ quantity integer
+);
+</pre><p>
+ Now it is impossible to create orders with non-NULL
+ <code class="structfield">product_no</code> entries that do not appear in the
+ products table.
+ </p><p>
+ We say that in this situation the orders table is the
+ <em class="firstterm">referencing</em> table and the products table is
+ the <em class="firstterm">referenced</em> table. Similarly, there are
+ referencing and referenced columns.
+ </p><p>
+ You can also shorten the above command to:
+</p><pre class="programlisting">
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ product_no integer <span class="emphasis"><strong>REFERENCES products</strong></span>,
+ quantity integer
+);
+</pre><p>
+ because in absence of a column list the primary key of the
+ referenced table is used as the referenced column(s).
+ </p><p>
+ You can assign your own name for a foreign key constraint,
+ in the usual way.
+ </p><p>
+ A foreign key can also constrain and reference a group of columns.
+ As usual, it then needs to be written in table constraint form.
+ Here is a contrived syntax example:
+</p><pre class="programlisting">
+CREATE TABLE t1 (
+ a integer PRIMARY KEY,
+ b integer,
+ c integer,
+ <span class="emphasis"><strong>FOREIGN KEY (b, c) REFERENCES other_table (c1, c2)</strong></span>
+);
+</pre><p>
+ Of course, the number and type of the constrained columns need to
+ match the number and type of the referenced columns.
+ </p><a id="id-1.5.4.6.9.11" class="indexterm"></a><p>
+ Sometimes it is useful for the <span class="quote">“<span class="quote">other table</span>”</span> of a
+ foreign key constraint to be the same table; this is called
+ a <em class="firstterm">self-referential</em> foreign key. For
+ example, if you want rows of a table to represent nodes of a tree
+ structure, you could write
+</p><pre class="programlisting">
+CREATE TABLE tree (
+ node_id integer PRIMARY KEY,
+ parent_id integer REFERENCES tree,
+ name text,
+ ...
+);
+</pre><p>
+ A top-level node would have NULL <code class="structfield">parent_id</code>,
+ while non-NULL <code class="structfield">parent_id</code> entries would be
+ constrained to reference valid rows of the table.
+ </p><p>
+ A table can have more than one foreign key constraint. This is
+ used to implement many-to-many relationships between tables. Say
+ you have tables about products and orders, but now you want to
+ allow one order to contain possibly many products (which the
+ structure above did not allow). You could use this table structure:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ shipping_address text,
+ ...
+);
+
+CREATE TABLE order_items (
+ product_no integer REFERENCES products,
+ order_id integer REFERENCES orders,
+ quantity integer,
+ PRIMARY KEY (product_no, order_id)
+);
+</pre><p>
+ Notice that the primary key overlaps with the foreign keys in
+ the last table.
+ </p><a id="id-1.5.4.6.9.14" class="indexterm"></a><a id="id-1.5.4.6.9.15" class="indexterm"></a><p>
+ We know that the foreign keys disallow creation of orders that
+ do not relate to any products. But what if a product is removed
+ after an order is created that references it? SQL allows you to
+ handle that as well. Intuitively, we have a few options:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>Disallow deleting a referenced product</p></li><li class="listitem"><p>Delete the orders as well</p></li><li class="listitem"><p>Something else?</p></li></ul></div><p>
+ </p><p>
+ To illustrate this, let's implement the following policy on the
+ many-to-many relationship example above: when someone wants to
+ remove a product that is still referenced by an order (via
+ <code class="literal">order_items</code>), we disallow it. If someone
+ removes an order, the order items are removed as well:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer PRIMARY KEY,
+ name text,
+ price numeric
+);
+
+CREATE TABLE orders (
+ order_id integer PRIMARY KEY,
+ shipping_address text,
+ ...
+);
+
+CREATE TABLE order_items (
+ product_no integer REFERENCES products <span class="emphasis"><strong>ON DELETE RESTRICT</strong></span>,
+ order_id integer REFERENCES orders <span class="emphasis"><strong>ON DELETE CASCADE</strong></span>,
+ quantity integer,
+ PRIMARY KEY (product_no, order_id)
+);
+</pre><p>
+ </p><p>
+ Restricting and cascading deletes are the two most common options.
+ <code class="literal">RESTRICT</code> prevents deletion of a
+ referenced row. <code class="literal">NO ACTION</code> means that if any
+ referencing rows still exist when the constraint is checked, an error
+ is raised; this is the default behavior if you do not specify anything.
+ (The essential difference between these two choices is that
+ <code class="literal">NO ACTION</code> allows the check to be deferred until
+ later in the transaction, whereas <code class="literal">RESTRICT</code> does not.)
+ <code class="literal">CASCADE</code> specifies that when a referenced row is deleted,
+ row(s) referencing it should be automatically deleted as well.
+ There are two other options:
+ <code class="literal">SET NULL</code> and <code class="literal">SET DEFAULT</code>.
+ These cause the referencing column(s) in the referencing row(s)
+ to be set to nulls or their default
+ values, respectively, when the referenced row is deleted.
+ Note that these do not excuse you from observing any constraints.
+ For example, if an action specifies <code class="literal">SET DEFAULT</code>
+ but the default value would not satisfy the foreign key constraint, the
+ operation will fail.
+ </p><p>
+ The appropriate choice of <code class="literal">ON DELETE</code> action depends on
+ what kinds of objects the related tables represent. When the referencing
+ table represents something that is a component of what is represented by
+ the referenced table and cannot exist independently, then
+ <code class="literal">CASCADE</code> could be appropriate. If the two tables
+ represent independent objects, then <code class="literal">RESTRICT</code> or
+ <code class="literal">NO ACTION</code> is more appropriate; an application that
+ actually wants to delete both objects would then have to be explicit about
+ this and run two delete commands. In the above example, order items are
+ part of an order, and it is convenient if they are deleted automatically
+ if an order is deleted. But products and orders are different things, and
+ so making a deletion of a product automatically cause the deletion of some
+ order items could be considered problematic. The actions <code class="literal">SET
+ NULL</code> or <code class="literal">SET DEFAULT</code> can be appropriate if a
+ foreign-key relationship represents optional information. For example, if
+ the products table contained a reference to a product manager, and the
+ product manager entry gets deleted, then setting the product's product
+ manager to null or a default might be useful.
+ </p><p>
+ The actions <code class="literal">SET NULL</code> and <code class="literal">SET DEFAULT</code>
+ can take a column list to specify which columns to set. Normally, all
+ columns of the foreign-key constraint are set; setting only a subset is
+ useful in some special cases. Consider the following example:
+</p><pre class="programlisting">
+CREATE TABLE tenants (
+ tenant_id integer PRIMARY KEY
+);
+
+CREATE TABLE users (
+ tenant_id integer REFERENCES tenants ON DELETE CASCADE,
+ user_id integer NOT NULL,
+ PRIMARY KEY (tenant_id, user_id)
+);
+
+CREATE TABLE posts (
+ tenant_id integer REFERENCES tenants ON DELETE CASCADE,
+ post_id integer NOT NULL,
+ author_id integer,
+ PRIMARY KEY (tenant_id, post_id),
+ FOREIGN KEY (tenant_id, author_id) REFERENCES users ON DELETE SET NULL <span class="emphasis"><strong>(author_id)</strong></span>
+);
+</pre><p>
+ Without the specification of the column, the foreign key would also set
+ the column <code class="literal">tenant_id</code> to null, but that column is still
+ required as part of the primary key.
+ </p><p>
+ Analogous to <code class="literal">ON DELETE</code> there is also
+ <code class="literal">ON UPDATE</code> which is invoked when a referenced
+ column is changed (updated). The possible actions are the same,
+ except that column lists cannot be specified for <code class="literal">SET
+ NULL</code> and <code class="literal">SET DEFAULT</code>.
+ In this case, <code class="literal">CASCADE</code> means that the updated values of the
+ referenced column(s) should be copied into the referencing row(s).
+ </p><p>
+ Normally, a referencing row need not satisfy the foreign key constraint
+ if any of its referencing columns are null. If <code class="literal">MATCH FULL</code>
+ is added to the foreign key declaration, a referencing row escapes
+ satisfying the constraint only if all its referencing columns are null
+ (so a mix of null and non-null values is guaranteed to fail a
+ <code class="literal">MATCH FULL</code> constraint). If you don't want referencing rows
+ to be able to avoid satisfying the foreign key constraint, declare the
+ referencing column(s) as <code class="literal">NOT NULL</code>.
+ </p><p>
+ A foreign key must reference columns that either are a primary key or
+ form a unique constraint. This means that the referenced columns always
+ have an index (the one underlying the primary key or unique constraint);
+ so checks on whether a referencing row has a match will be efficient.
+ Since a <code class="command">DELETE</code> of a row from the referenced table
+ or an <code class="command">UPDATE</code> of a referenced column will require
+ a scan of the referencing table for rows matching the old value, it
+ is often a good idea to index the referencing columns too. Because this
+ is not always needed, and there are many choices available on how
+ to index, declaration of a foreign key constraint does not
+ automatically create an index on the referencing columns.
+ </p><p>
+ More information about updating and deleting data is in <a class="xref" href="dml.html" title="Chapter 6. Data Manipulation">Chapter 6</a>. Also see the description of foreign key constraint
+ syntax in the reference documentation for
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>.
+ </p></div><div class="sect2" id="DDL-CONSTRAINTS-EXCLUSION"><div class="titlepage"><div><div><h3 class="title">5.4.6. Exclusion Constraints</h3></div></div></div><a id="id-1.5.4.6.10.2" class="indexterm"></a><a id="id-1.5.4.6.10.3" class="indexterm"></a><p>
+ Exclusion constraints ensure that if any two rows are compared on
+ the specified columns or expressions using the specified operators,
+ at least one of these operator comparisons will return false or null.
+ The syntax is:
+</p><pre class="programlisting">
+CREATE TABLE circles (
+ c circle,
+ EXCLUDE USING gist (c WITH &amp;&amp;)
+);
+</pre><p>
+ </p><p>
+ See also <a class="link" href="sql-createtable.html#SQL-CREATETABLE-EXCLUDE"><code class="command">CREATE
+ TABLE ... CONSTRAINT ... EXCLUDE</code></a> for details.
+ </p><p>
+ Adding an exclusion constraint will automatically create an index
+ of the type specified in the constraint declaration.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-generated-columns.html" title="5.3. Generated Columns">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-system-columns.html" title="5.5. System Columns">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.3. Generated Columns </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.5. System Columns</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-default.html b/doc/src/sgml/html/ddl-default.html
new file mode 100644
index 0000000..7bf3b0e
--- /dev/null
+++ b/doc/src/sgml/html/ddl-default.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.2. Default Values</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-basics.html" title="5.1. Table Basics" /><link rel="next" href="ddl-generated-columns.html" title="5.3. Generated Columns" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.2. Default Values</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-basics.html" title="5.1. Table Basics">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-generated-columns.html" title="5.3. Generated Columns">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-DEFAULT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.2. Default Values</h2></div></div></div><a id="id-1.5.4.4.2" class="indexterm"></a><p>
+ A column can be assigned a default value. When a new row is
+ created and no values are specified for some of the columns, those
+ columns will be filled with their respective default values. A
+ data manipulation command can also request explicitly that a column
+ be set to its default value, without having to know what that value is.
+ (Details about data manipulation commands are in <a class="xref" href="dml.html" title="Chapter 6. Data Manipulation">Chapter 6</a>.)
+ </p><p>
+ <a id="id-1.5.4.4.4.1" class="indexterm"></a>
+ If no default value is declared explicitly, the default value is the
+ null value. This usually makes sense because a null value can
+ be considered to represent unknown data.
+ </p><p>
+ In a table definition, default values are listed after the column
+ data type. For example:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric <span class="emphasis"><strong>DEFAULT 9.99</strong></span>
+);
+</pre><p>
+ </p><p>
+ The default value can be an expression, which will be
+ evaluated whenever the default value is inserted
+ (<span class="emphasis"><em>not</em></span> when the table is created). A common example
+ is for a <code class="type">timestamp</code> column to have a default of <code class="literal">CURRENT_TIMESTAMP</code>,
+ so that it gets set to the time of row insertion. Another common
+ example is generating a <span class="quote">“<span class="quote">serial number</span>”</span> for each row.
+ In <span class="productname">PostgreSQL</span> this is typically done by
+ something like:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer <span class="emphasis"><strong>DEFAULT nextval('products_product_no_seq')</strong></span>,
+ ...
+);
+</pre><p>
+ where the <code class="literal">nextval()</code> function supplies successive values
+ from a <em class="firstterm">sequence object</em> (see <a class="xref" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Section 9.17</a>). This arrangement is sufficiently common
+ that there's a special shorthand for it:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no <span class="emphasis"><strong>SERIAL</strong></span>,
+ ...
+);
+</pre><p>
+ The <code class="literal">SERIAL</code> shorthand is discussed further in <a class="xref" href="datatype-numeric.html#DATATYPE-SERIAL" title="8.1.4. Serial Types">Section 8.1.4</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-basics.html" title="5.1. Table Basics">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-generated-columns.html" title="5.3. Generated Columns">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.1. Table Basics </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.3. Generated Columns</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-depend.html b/doc/src/sgml/html/ddl-depend.html
new file mode 100644
index 0000000..f692c71
--- /dev/null
+++ b/doc/src/sgml/html/ddl-depend.html
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.14. Dependency Tracking</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-others.html" title="5.13. Other Database Objects" /><link rel="next" href="dml.html" title="Chapter 6. Data Manipulation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.14. Dependency Tracking</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-others.html" title="5.13. Other Database Objects">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dml.html" title="Chapter 6. Data Manipulation">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-DEPEND"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.14. Dependency Tracking</h2></div></div></div><a id="id-1.5.4.16.2" class="indexterm"></a><a id="id-1.5.4.16.3" class="indexterm"></a><p>
+ When you create complex database structures involving many tables
+ with foreign key constraints, views, triggers, functions, etc. you
+ implicitly create a net of dependencies between the objects.
+ For instance, a table with a foreign key constraint depends on the
+ table it references.
+ </p><p>
+ To ensure the integrity of the entire database structure,
+ <span class="productname">PostgreSQL</span> makes sure that you cannot
+ drop objects that other objects still depend on. For example,
+ attempting to drop the products table we considered in <a class="xref" href="ddl-constraints.html#DDL-CONSTRAINTS-FK" title="5.4.5. Foreign Keys">Section 5.4.5</a>, with the orders table depending on
+ it, would result in an error message like this:
+</p><pre class="screen">
+DROP TABLE products;
+
+ERROR: cannot drop table products because other objects depend on it
+DETAIL: constraint orders_product_no_fkey on table orders depends on table products
+HINT: Use DROP ... CASCADE to drop the dependent objects too.
+</pre><p>
+ The error message contains a useful hint: if you do not want to
+ bother deleting all the dependent objects individually, you can run:
+</p><pre class="screen">
+DROP TABLE products CASCADE;
+</pre><p>
+ and all the dependent objects will be removed, as will any objects
+ that depend on them, recursively. In this case, it doesn't remove
+ the orders table, it only removes the foreign key constraint.
+ It stops there because nothing depends on the foreign key constraint.
+ (If you want to check what <code class="command">DROP ... CASCADE</code> will do,
+ run <code class="command">DROP</code> without <code class="literal">CASCADE</code> and read the
+ <code class="literal">DETAIL</code> output.)
+ </p><p>
+ Almost all <code class="command">DROP</code> commands in <span class="productname">PostgreSQL</span> support
+ specifying <code class="literal">CASCADE</code>. Of course, the nature of
+ the possible dependencies varies with the type of the object. You
+ can also write <code class="literal">RESTRICT</code> instead of
+ <code class="literal">CASCADE</code> to get the default behavior, which is to
+ prevent dropping objects that any other objects depend on.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ According to the SQL standard, specifying either
+ <code class="literal">RESTRICT</code> or <code class="literal">CASCADE</code> is
+ required in a <code class="command">DROP</code> command. No database system actually
+ enforces that rule, but whether the default behavior
+ is <code class="literal">RESTRICT</code> or <code class="literal">CASCADE</code> varies
+ across systems.
+ </p></div><p>
+ If a <code class="command">DROP</code> command lists multiple
+ objects, <code class="literal">CASCADE</code> is only required when there are
+ dependencies outside the specified group. For example, when saying
+ <code class="literal">DROP TABLE tab1, tab2</code> the existence of a foreign
+ key referencing <code class="literal">tab1</code> from <code class="literal">tab2</code> would not mean
+ that <code class="literal">CASCADE</code> is needed to succeed.
+ </p><p>
+ For a user-defined function or procedure whose body is defined as a string
+ literal, <span class="productname">PostgreSQL</span> tracks
+ dependencies associated with the function's externally-visible properties,
+ such as its argument and result types, but <span class="emphasis"><em>not</em></span> dependencies
+ that could only be known by examining the function body. As an example,
+ consider this situation:
+
+</p><pre class="programlisting">
+CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow',
+ 'green', 'blue', 'purple');
+
+CREATE TABLE my_colors (color rainbow, note text);
+
+CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
+ 'SELECT note FROM my_colors WHERE color = $1'
+ LANGUAGE SQL;
+</pre><p>
+
+ (See <a class="xref" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions">Section 38.5</a> for an explanation of SQL-language
+ functions.) <span class="productname">PostgreSQL</span> will be aware that
+ the <code class="function">get_color_note</code> function depends on the <code class="type">rainbow</code>
+ type: dropping the type would force dropping the function, because its
+ argument type would no longer be defined. But <span class="productname">PostgreSQL</span>
+ will not consider <code class="function">get_color_note</code> to depend on
+ the <code class="structname">my_colors</code> table, and so will not drop the function if
+ the table is dropped. While there are disadvantages to this approach,
+ there are also benefits. The function is still valid in some sense if the
+ table is missing, though executing it would cause an error; creating a new
+ table of the same name would allow the function to work again.
+ </p><p>
+ On the other hand, for a SQL-language function or procedure whose body
+ is written in SQL-standard style, the body is parsed at function
+ definition time and all dependencies recognized by the parser are
+ stored. Thus, if we write the function above as
+
+</p><pre class="programlisting">
+CREATE FUNCTION get_color_note (rainbow) RETURNS text
+BEGIN ATOMIC
+ SELECT note FROM my_colors WHERE color = $1;
+END;
+</pre><p>
+
+ then the function's dependency on the <code class="structname">my_colors</code>
+ table will be known and enforced by <code class="command">DROP</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-others.html" title="5.13. Other Database Objects">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dml.html" title="Chapter 6. Data Manipulation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.13. Other Database Objects </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 6. Data Manipulation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-foreign-data.html b/doc/src/sgml/html/ddl-foreign-data.html
new file mode 100644
index 0000000..fce572f
--- /dev/null
+++ b/doc/src/sgml/html/ddl-foreign-data.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.12. Foreign Data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-partitioning.html" title="5.11. Table Partitioning" /><link rel="next" href="ddl-others.html" title="5.13. Other Database Objects" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.12. Foreign Data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-partitioning.html" title="5.11. Table Partitioning">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-others.html" title="5.13. Other Database Objects">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-FOREIGN-DATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.12. Foreign Data</h2></div></div></div><a id="id-1.5.4.14.2" class="indexterm"></a><a id="id-1.5.4.14.3" class="indexterm"></a><a id="id-1.5.4.14.4" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> implements portions of the SQL/MED
+ specification, allowing you to access data that resides outside
+ PostgreSQL using regular SQL queries. Such data is referred to as
+ <em class="firstterm">foreign data</em>. (Note that this usage is not to be confused
+ with foreign keys, which are a type of constraint within the database.)
+ </p><p>
+ Foreign data is accessed with help from a
+ <em class="firstterm">foreign data wrapper</em>. A foreign data wrapper is a
+ library that can communicate with an external data source, hiding the
+ details of connecting to the data source and obtaining data from it.
+ There are some foreign data wrappers available as <code class="filename">contrib</code>
+ modules; see <a class="xref" href="contrib.html" title="Appendix F. Additional Supplied Modules">Appendix F</a>. Other kinds of foreign data
+ wrappers might be found as third party products. If none of the existing
+ foreign data wrappers suit your needs, you can write your own; see <a class="xref" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Chapter 59</a>.
+ </p><p>
+ To access foreign data, you need to create a <em class="firstterm">foreign server</em>
+ object, which defines how to connect to a particular external data source
+ according to the set of options used by its supporting foreign data
+ wrapper. Then you need to create one or more <em class="firstterm">foreign
+ tables</em>, which define the structure of the remote data. A
+ foreign table can be used in queries just like a normal table, but a
+ foreign table has no storage in the PostgreSQL server. Whenever it is
+ used, <span class="productname">PostgreSQL</span> asks the foreign data wrapper
+ to fetch data from the external source, or transmit data to the external
+ source in the case of update commands.
+ </p><p>
+ Accessing remote data may require authenticating to the external
+ data source. This information can be provided by a
+ <em class="firstterm">user mapping</em>, which can provide additional data
+ such as user names and passwords based
+ on the current <span class="productname">PostgreSQL</span> role.
+ </p><p>
+ For additional information, see
+ <a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a>,
+ <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>,
+ <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>,
+ <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>, and
+ <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-partitioning.html" title="5.11. Table Partitioning">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-others.html" title="5.13. Other Database Objects">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.11. Table Partitioning </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.13. Other Database Objects</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-generated-columns.html b/doc/src/sgml/html/ddl-generated-columns.html
new file mode 100644
index 0000000..5b67354
--- /dev/null
+++ b/doc/src/sgml/html/ddl-generated-columns.html
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.3. Generated Columns</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-default.html" title="5.2. Default Values" /><link rel="next" href="ddl-constraints.html" title="5.4. Constraints" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.3. Generated Columns</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-default.html" title="5.2. Default Values">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-constraints.html" title="5.4. Constraints">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-GENERATED-COLUMNS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.3. Generated Columns</h2></div></div></div><a id="id-1.5.4.5.2" class="indexterm"></a><p>
+ A generated column is a special column that is always computed from other
+ columns. Thus, it is for columns what a view is for tables. There are two
+ kinds of generated columns: stored and virtual. A stored generated column
+ is computed when it is written (inserted or updated) and occupies storage
+ as if it were a normal column. A virtual generated column occupies no
+ storage and is computed when it is read. Thus, a virtual generated column
+ is similar to a view and a stored generated column is similar to a
+ materialized view (except that it is always updated automatically).
+ PostgreSQL currently implements only stored generated columns.
+ </p><p>
+ To create a generated column, use the <code class="literal">GENERATED ALWAYS
+ AS</code> clause in <code class="command">CREATE TABLE</code>, for example:
+</p><pre class="programlisting">
+CREATE TABLE people (
+ ...,
+ height_cm numeric,
+ height_in numeric <span class="emphasis"><strong>GENERATED ALWAYS AS (height_cm / 2.54) STORED</strong></span>
+);
+</pre><p>
+ The keyword <code class="literal">STORED</code> must be specified to choose the
+ stored kind of generated column. See <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for
+ more details.
+ </p><p>
+ A generated column cannot be written to directly. In
+ <code class="command">INSERT</code> or <code class="command">UPDATE</code> commands, a value
+ cannot be specified for a generated column, but the keyword
+ <code class="literal">DEFAULT</code> may be specified.
+ </p><p>
+ Consider the differences between a column with a default and a generated
+ column. The column default is evaluated once when the row is first
+ inserted if no other value was provided; a generated column is updated
+ whenever the row changes and cannot be overridden. A column default may
+ not refer to other columns of the table; a generation expression would
+ normally do so. A column default can use volatile functions, for example
+ <code class="literal">random()</code> or functions referring to the current time;
+ this is not allowed for generated columns.
+ </p><p>
+ Several restrictions apply to the definition of generated columns and
+ tables involving generated columns:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The generation expression can only use immutable functions and cannot
+ use subqueries or reference anything other than the current row in any
+ way.
+ </p></li><li class="listitem"><p>
+ A generation expression cannot reference another generated column.
+ </p></li><li class="listitem"><p>
+ A generation expression cannot reference a system column, except
+ <code class="varname">tableoid</code>.
+ </p></li><li class="listitem"><p>
+ A generated column cannot have a column default or an identity definition.
+ </p></li><li class="listitem"><p>
+ A generated column cannot be part of a partition key.
+ </p></li><li class="listitem"><p>
+ Foreign tables can have generated columns. See <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a> for details.
+ </p></li><li class="listitem"><p>For inheritance:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ If a parent column is a generated column, a child column must also be
+ a generated column using the same expression. In the definition of
+ the child column, leave off the <code class="literal">GENERATED</code> clause,
+ as it will be copied from the parent.
+ </p></li><li class="listitem"><p>
+ In case of multiple inheritance, if one parent column is a generated
+ column, then all parent columns must be generated columns and with the
+ same expression.
+ </p></li><li class="listitem"><p>
+ If a parent column is not a generated column, a child column may be
+ defined to be a generated column or not.
+ </p></li></ul></div></li></ul></div><p>
+ </p><p>
+ Additional considerations apply to the use of generated columns.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Generated columns maintain access privileges separately from their
+ underlying base columns. So, it is possible to arrange it so that a
+ particular role can read from a generated column but not from the
+ underlying base columns.
+ </p></li><li class="listitem"><p>
+ Generated columns are, conceptually, updated after
+ <code class="literal">BEFORE</code> triggers have run. Therefore, changes made to
+ base columns in a <code class="literal">BEFORE</code> trigger will be reflected in
+ generated columns. But conversely, it is not allowed to access
+ generated columns in <code class="literal">BEFORE</code> triggers.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-default.html" title="5.2. Default Values">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-constraints.html" title="5.4. Constraints">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.2. Default Values </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.4. Constraints</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-inherit.html b/doc/src/sgml/html/ddl-inherit.html
new file mode 100644
index 0000000..ec21492
--- /dev/null
+++ b/doc/src/sgml/html/ddl-inherit.html
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.10. Inheritance</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-schemas.html" title="5.9. Schemas" /><link rel="next" href="ddl-partitioning.html" title="5.11. Table Partitioning" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.10. Inheritance</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-schemas.html" title="5.9. Schemas">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-partitioning.html" title="5.11. Table Partitioning">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-INHERIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.10. Inheritance</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-inherit.html#DDL-INHERIT-CAVEATS">5.10.1. Caveats</a></span></dt></dl></div><a id="id-1.5.4.12.2" class="indexterm"></a><a id="id-1.5.4.12.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> implements table inheritance,
+ which can be a useful tool for database designers. (SQL:1999 and
+ later define a type inheritance feature, which differs in many
+ respects from the features described here.)
+ </p><p>
+ Let's start with an example: suppose we are trying to build a data
+ model for cities. Each state has many cities, but only one
+ capital. We want to be able to quickly retrieve the capital city
+ for any particular state. This can be done by creating two tables,
+ one for state capitals and one for cities that are not
+ capitals. However, what happens when we want to ask for data about
+ a city, regardless of whether it is a capital or not? The
+ inheritance feature can help to resolve this problem. We define the
+ <code class="structname">capitals</code> table so that it inherits from
+ <code class="structname">cities</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE cities (
+ name text,
+ population float,
+ elevation int -- in feet
+);
+
+CREATE TABLE capitals (
+ state char(2)
+) INHERITS (cities);
+</pre><p>
+
+ In this case, the <code class="structname">capitals</code> table <em class="firstterm">inherits</em>
+ all the columns of its parent table, <code class="structname">cities</code>. State
+ capitals also have an extra column, <code class="structfield">state</code>, that shows
+ their state.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, a table can inherit from
+ zero or more other tables, and a query can reference either all
+ rows of a table or all rows of a table plus all of its descendant tables.
+ The latter behavior is the default.
+ For example, the following query finds the names of all cities,
+ including state capitals, that are located at an elevation over
+ 500 feet:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM cities
+ WHERE elevation &gt; 500;
+</pre><p>
+
+ Given the sample data from the <span class="productname">PostgreSQL</span>
+ tutorial (see <a class="xref" href="tutorial-sql-intro.html" title="2.1. Introduction">Section 2.1</a>), this returns:
+
+</p><pre class="programlisting">
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+ Madison | 845
+</pre><p>
+ </p><p>
+ On the other hand, the following query finds all the cities that
+ are not state capitals and are situated at an elevation over 500 feet:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM ONLY cities
+ WHERE elevation &gt; 500;
+
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+</pre><p>
+ </p><p>
+ Here the <code class="literal">ONLY</code> keyword indicates that the query
+ should apply only to <code class="structname">cities</code>, and not any tables
+ below <code class="structname">cities</code> in the inheritance hierarchy. Many
+ of the commands that we have already discussed —
+ <code class="command">SELECT</code>, <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code> — support the
+ <code class="literal">ONLY</code> keyword.
+ </p><p>
+ You can also write the table name with a trailing <code class="literal">*</code>
+ to explicitly specify that descendant tables are included:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM cities*
+ WHERE elevation &gt; 500;
+</pre><p>
+
+ Writing <code class="literal">*</code> is not necessary, since this behavior is always
+ the default. However, this syntax is still supported for
+ compatibility with older releases where the default could be changed.
+ </p><p>
+ In some cases you might wish to know which table a particular row
+ originated from. There is a system column called
+ <code class="structfield">tableoid</code> in each table which can tell you the
+ originating table:
+
+</p><pre class="programlisting">
+SELECT c.tableoid, c.name, c.elevation
+FROM cities c
+WHERE c.elevation &gt; 500;
+</pre><p>
+
+ which returns:
+
+</p><pre class="programlisting">
+ tableoid | name | elevation
+----------+-----------+-----------
+ 139793 | Las Vegas | 2174
+ 139793 | Mariposa | 1953
+ 139798 | Madison | 845
+</pre><p>
+
+ (If you try to reproduce this example, you will probably get
+ different numeric OIDs.) By doing a join with
+ <code class="structname">pg_class</code> you can see the actual table names:
+
+</p><pre class="programlisting">
+SELECT p.relname, c.name, c.elevation
+FROM cities c, pg_class p
+WHERE c.elevation &gt; 500 AND c.tableoid = p.oid;
+</pre><p>
+
+ which returns:
+
+</p><pre class="programlisting">
+ relname | name | elevation
+----------+-----------+-----------
+ cities | Las Vegas | 2174
+ cities | Mariposa | 1953
+ capitals | Madison | 845
+</pre><p>
+ </p><p>
+ Another way to get the same effect is to use the <code class="type">regclass</code>
+ alias type, which will print the table OID symbolically:
+
+</p><pre class="programlisting">
+SELECT c.tableoid::regclass, c.name, c.elevation
+FROM cities c
+WHERE c.elevation &gt; 500;
+</pre><p>
+ </p><p>
+ Inheritance does not automatically propagate data from
+ <code class="command">INSERT</code> or <code class="command">COPY</code> commands to
+ other tables in the inheritance hierarchy. In our example, the
+ following <code class="command">INSERT</code> statement will fail:
+</p><pre class="programlisting">
+INSERT INTO cities (name, population, elevation, state)
+VALUES ('Albany', NULL, NULL, 'NY');
+</pre><p>
+ We might hope that the data would somehow be routed to the
+ <code class="structname">capitals</code> table, but this does not happen:
+ <code class="command">INSERT</code> always inserts into exactly the table
+ specified. In some cases it is possible to redirect the insertion
+ using a rule (see <a class="xref" href="rules.html" title="Chapter 41. The Rule System">Chapter 41</a>). However that does not
+ help for the above case because the <code class="structname">cities</code> table
+ does not contain the column <code class="structfield">state</code>, and so the
+ command will be rejected before the rule can be applied.
+ </p><p>
+ All check constraints and not-null constraints on a parent table are
+ automatically inherited by its children, unless explicitly specified
+ otherwise with <code class="literal">NO INHERIT</code> clauses. Other types of constraints
+ (unique, primary key, and foreign key constraints) are not inherited.
+ </p><p>
+ A table can inherit from more than one parent table, in which case it has
+ the union of the columns defined by the parent tables. Any columns
+ declared in the child table's definition are added to these. If the
+ same column name appears in multiple parent tables, or in both a parent
+ table and the child's definition, then these columns are <span class="quote">“<span class="quote">merged</span>”</span>
+ so that there is only one such column in the child table. To be merged,
+ columns must have the same data types, else an error is raised.
+ Inheritable check constraints and not-null constraints are merged in a
+ similar fashion. Thus, for example, a merged column will be marked
+ not-null if any one of the column definitions it came from is marked
+ not-null. Check constraints are merged if they have the same name,
+ and the merge will fail if their conditions are different.
+ </p><p>
+ Table inheritance is typically established when the child table is
+ created, using the <code class="literal">INHERITS</code> clause of the
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>
+ statement.
+ Alternatively, a table which is already defined in a compatible way can
+ have a new parent relationship added, using the <code class="literal">INHERIT</code>
+ variant of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>.
+ To do this the new child table must already include columns with
+ the same names and types as the columns of the parent. It must also include
+ check constraints with the same names and check expressions as those of the
+ parent. Similarly an inheritance link can be removed from a child using the
+ <code class="literal">NO INHERIT</code> variant of <code class="command">ALTER TABLE</code>.
+ Dynamically adding and removing inheritance links like this can be useful
+ when the inheritance relationship is being used for table
+ partitioning (see <a class="xref" href="ddl-partitioning.html" title="5.11. Table Partitioning">Section 5.11</a>).
+ </p><p>
+ One convenient way to create a compatible table that will later be made
+ a new child is to use the <code class="literal">LIKE</code> clause in <code class="command">CREATE
+ TABLE</code>. This creates a new table with the same columns as
+ the source table. If there are any <code class="literal">CHECK</code>
+ constraints defined on the source table, the <code class="literal">INCLUDING
+ CONSTRAINTS</code> option to <code class="literal">LIKE</code> should be
+ specified, as the new child must have constraints matching the parent
+ to be considered compatible.
+ </p><p>
+ A parent table cannot be dropped while any of its children remain. Neither
+ can columns or check constraints of child tables be dropped or altered
+ if they are inherited
+ from any parent tables. If you wish to remove a table and all of its
+ descendants, one easy way is to drop the parent table with the
+ <code class="literal">CASCADE</code> option (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p><p>
+ <code class="command">ALTER TABLE</code> will
+ propagate any changes in column data definitions and check
+ constraints down the inheritance hierarchy. Again, dropping
+ columns that are depended on by other tables is only possible when using
+ the <code class="literal">CASCADE</code> option. <code class="command">ALTER
+ TABLE</code> follows the same rules for duplicate column merging
+ and rejection that apply during <code class="command">CREATE TABLE</code>.
+ </p><p>
+ Inherited queries perform access permission checks on the parent table
+ only. Thus, for example, granting <code class="literal">UPDATE</code> permission on
+ the <code class="structname">cities</code> table implies permission to update rows in
+ the <code class="structname">capitals</code> table as well, when they are
+ accessed through <code class="structname">cities</code>. This preserves the appearance
+ that the data is (also) in the parent table. But
+ the <code class="structname">capitals</code> table could not be updated directly
+ without an additional grant. In a similar way, the parent table's row
+ security policies (see <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a>) are applied to
+ rows coming from child tables during an inherited query. A child table's
+ policies, if any, are applied only when it is the table explicitly named
+ in the query; and in that case, any policies attached to its parent(s) are
+ ignored.
+ </p><p>
+ Foreign tables (see <a class="xref" href="ddl-foreign-data.html" title="5.12. Foreign Data">Section 5.12</a>) can also
+ be part of inheritance hierarchies, either as parent or child
+ tables, just as regular tables can be. If a foreign table is part
+ of an inheritance hierarchy then any operations not supported by
+ the foreign table are not supported on the whole hierarchy either.
+ </p><div class="sect2" id="DDL-INHERIT-CAVEATS"><div class="titlepage"><div><div><h3 class="title">5.10.1. Caveats</h3></div></div></div><p>
+ Note that not all SQL commands are able to work on
+ inheritance hierarchies. Commands that are used for data querying,
+ data modification, or schema modification
+ (e.g., <code class="literal">SELECT</code>, <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
+ most variants of <code class="literal">ALTER TABLE</code>, but
+ not <code class="literal">INSERT</code> or <code class="literal">ALTER TABLE ...
+ RENAME</code>) typically default to including child tables and
+ support the <code class="literal">ONLY</code> notation to exclude them.
+ Commands that do database maintenance and tuning
+ (e.g., <code class="literal">REINDEX</code>, <code class="literal">VACUUM</code>)
+ typically only work on individual, physical tables and do not
+ support recursing over inheritance hierarchies. The respective
+ behavior of each individual command is documented in its reference
+ page (<a class="xref" href="sql-commands.html" title="SQL Commands">SQL Commands</a>).
+ </p><p>
+ A serious limitation of the inheritance feature is that indexes (including
+ unique constraints) and foreign key constraints only apply to single
+ tables, not to their inheritance children. This is true on both the
+ referencing and referenced sides of a foreign key constraint. Thus,
+ in the terms of the above example:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If we declared <code class="structname">cities</code>.<code class="structfield">name</code> to be
+ <code class="literal">UNIQUE</code> or a <code class="literal">PRIMARY KEY</code>, this would not stop the
+ <code class="structname">capitals</code> table from having rows with names duplicating
+ rows in <code class="structname">cities</code>. And those duplicate rows would by
+ default show up in queries from <code class="structname">cities</code>. In fact, by
+ default <code class="structname">capitals</code> would have no unique constraint at all,
+ and so could contain multiple rows with the same name.
+ You could add a unique constraint to <code class="structname">capitals</code>, but this
+ would not prevent duplication compared to <code class="structname">cities</code>.
+ </p></li><li class="listitem"><p>
+ Similarly, if we were to specify that
+ <code class="structname">cities</code>.<code class="structfield">name</code> <code class="literal">REFERENCES</code> some
+ other table, this constraint would not automatically propagate to
+ <code class="structname">capitals</code>. In this case you could work around it by
+ manually adding the same <code class="literal">REFERENCES</code> constraint to
+ <code class="structname">capitals</code>.
+ </p></li><li class="listitem"><p>
+ Specifying that another table's column <code class="literal">REFERENCES
+ cities(name)</code> would allow the other table to contain city names, but
+ not capital names. There is no good workaround for this case.
+ </p></li></ul></div><p>
+
+ Some functionality not implemented for inheritance hierarchies is
+ implemented for declarative partitioning.
+ Considerable care is needed in deciding whether partitioning with legacy
+ inheritance is useful for your application.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-schemas.html" title="5.9. Schemas">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-partitioning.html" title="5.11. Table Partitioning">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.9. Schemas </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.11. Table Partitioning</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-others.html b/doc/src/sgml/html/ddl-others.html
new file mode 100644
index 0000000..31c312b
--- /dev/null
+++ b/doc/src/sgml/html/ddl-others.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.13. Other Database Objects</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-foreign-data.html" title="5.12. Foreign Data" /><link rel="next" href="ddl-depend.html" title="5.14. Dependency Tracking" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.13. Other Database Objects</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-foreign-data.html" title="5.12. Foreign Data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-depend.html" title="5.14. Dependency Tracking">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-OTHERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.13. Other Database Objects</h2></div></div></div><p>
+ Tables are the central objects in a relational database structure,
+ because they hold your data. But they are not the only objects
+ that exist in a database. Many other kinds of objects can be
+ created to make the use and management of the data more efficient
+ or convenient. They are not discussed in this chapter, but we give
+ you a list here so that you are aware of what is possible:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Views
+ </p></li><li class="listitem"><p>
+ Functions, procedures, and operators
+ </p></li><li class="listitem"><p>
+ Data types and domains
+ </p></li><li class="listitem"><p>
+ Triggers and rewrite rules
+ </p></li></ul></div><p>
+ Detailed information on
+ these topics appears in <a class="xref" href="server-programming.html" title="Part V. Server Programming">Part V</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-foreign-data.html" title="5.12. Foreign Data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-depend.html" title="5.14. Dependency Tracking">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.12. Foreign Data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.14. Dependency Tracking</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-partitioning.html b/doc/src/sgml/html/ddl-partitioning.html
new file mode 100644
index 0000000..f3ecb9a
--- /dev/null
+++ b/doc/src/sgml/html/ddl-partitioning.html
@@ -0,0 +1,992 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.11. Table Partitioning</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-inherit.html" title="5.10. Inheritance" /><link rel="next" href="ddl-foreign-data.html" title="5.12. Foreign Data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.11. Table Partitioning</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-inherit.html" title="5.10. Inheritance">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-foreign-data.html" title="5.12. Foreign Data">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-PARTITIONING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.11. Table Partitioning</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-OVERVIEW">5.11.1. Overview</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE">5.11.2. Declarative Partitioning</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-USING-INHERITANCE">5.11.3. Partitioning Using Inheritance</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITION-PRUNING">5.11.4. Partition Pruning</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-CONSTRAINT-EXCLUSION">5.11.5. Partitioning and Constraint Exclusion</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE-BEST-PRACTICES">5.11.6. Best Practices for Declarative Partitioning</a></span></dt></dl></div><a id="id-1.5.4.13.2" class="indexterm"></a><a id="id-1.5.4.13.3" class="indexterm"></a><a id="id-1.5.4.13.4" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> supports basic table
+ partitioning. This section describes why and how to implement
+ partitioning as part of your database design.
+ </p><div class="sect2" id="DDL-PARTITIONING-OVERVIEW"><div class="titlepage"><div><div><h3 class="title">5.11.1. Overview</h3></div></div></div><p>
+ Partitioning refers to splitting what is logically one large table into
+ smaller physical pieces. Partitioning can provide several benefits:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Query performance can be improved dramatically in certain situations,
+ particularly when most of the heavily accessed rows of the table are in a
+ single partition or a small number of partitions. Partitioning
+ effectively substitutes for the upper tree levels of indexes,
+ making it more likely that the heavily-used parts of the indexes
+ fit in memory.
+ </p></li><li class="listitem"><p>
+ When queries or updates access a large percentage of a single
+ partition, performance can be improved by using a
+ sequential scan of that partition instead of using an
+ index, which would require random-access reads scattered across the
+ whole table.
+ </p></li><li class="listitem"><p>
+ Bulk loads and deletes can be accomplished by adding or removing
+ partitions, if the usage pattern is accounted for in the
+ partitioning design. Dropping an individual partition
+ using <code class="command">DROP TABLE</code>, or doing <code class="command">ALTER TABLE
+ DETACH PARTITION</code>, is far faster than a bulk
+ operation. These commands also entirely avoid the
+ <code class="command">VACUUM</code> overhead caused by a bulk <code class="command">DELETE</code>.
+ </p></li><li class="listitem"><p>
+ Seldom-used data can be migrated to cheaper and slower storage media.
+ </p></li></ul></div><p>
+
+ These benefits will normally be worthwhile only when a table would
+ otherwise be very large. The exact point at which a table will
+ benefit from partitioning depends on the application, although a
+ rule of thumb is that the size of the table should exceed the physical
+ memory of the database server.
+ </p><p>
+ <span class="productname">PostgreSQL</span> offers built-in support for the
+ following forms of partitioning:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Range Partitioning</span></dt><dd><p>
+ The table is partitioned into <span class="quote">“<span class="quote">ranges</span>”</span> defined
+ by a key column or set of columns, with no overlap between
+ the ranges of values assigned to different partitions. For
+ example, one might partition by date ranges, or by ranges of
+ identifiers for particular business objects.
+ Each range's bounds are understood as being inclusive at the
+ lower end and exclusive at the upper end. For example, if one
+ partition's range is from <code class="literal">1</code>
+ to <code class="literal">10</code>, and the next one's range is
+ from <code class="literal">10</code> to <code class="literal">20</code>, then
+ value <code class="literal">10</code> belongs to the second partition not
+ the first.
+ </p></dd><dt><span class="term">List Partitioning</span></dt><dd><p>
+ The table is partitioned by explicitly listing which key value(s)
+ appear in each partition.
+ </p></dd><dt><span class="term">Hash Partitioning</span></dt><dd><p>
+ The table is partitioned by specifying a modulus and a remainder for
+ each partition. Each partition will hold the rows for which the hash
+ value of the partition key divided by the specified modulus will
+ produce the specified remainder.
+ </p></dd></dl></div><p>
+
+ If your application needs to use other forms of partitioning not listed
+ above, alternative methods such as inheritance and
+ <code class="literal">UNION ALL</code> views can be used instead. Such methods
+ offer flexibility but do not have some of the performance benefits
+ of built-in declarative partitioning.
+ </p></div><div class="sect2" id="DDL-PARTITIONING-DECLARATIVE"><div class="titlepage"><div><div><h3 class="title">5.11.2. Declarative Partitioning</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> allows you to declare
+ that a table is divided into partitions. The table that is divided
+ is referred to as a <em class="firstterm">partitioned table</em>. The
+ declaration includes the <em class="firstterm">partitioning method</em>
+ as described above, plus a list of columns or expressions to be used
+ as the <em class="firstterm">partition key</em>.
+ </p><p>
+ The partitioned table itself is a <span class="quote">“<span class="quote">virtual</span>”</span> table having
+ no storage of its own. Instead, the storage belongs
+ to <em class="firstterm">partitions</em>, which are otherwise-ordinary
+ tables associated with the partitioned table.
+ Each partition stores a subset of the data as defined by its
+ <em class="firstterm">partition bounds</em>.
+ All rows inserted into a partitioned table will be routed to the
+ appropriate one of the partitions based on the values of the partition
+ key column(s).
+ Updating the partition key of a row will cause it to be moved into a
+ different partition if it no longer satisfies the partition bounds
+ of its original partition.
+ </p><p>
+ Partitions may themselves be defined as partitioned tables, resulting
+ in <em class="firstterm">sub-partitioning</em>. Although all partitions
+ must have the same columns as their partitioned parent, partitions may
+ have their
+ own indexes, constraints and default values, distinct from those of other
+ partitions. See <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for more details on
+ creating partitioned tables and partitions.
+ </p><p>
+ It is not possible to turn a regular table into a partitioned table or
+ vice versa. However, it is possible to add an existing regular or
+ partitioned table as a partition of a partitioned table, or remove a
+ partition from a partitioned table turning it into a standalone table;
+ this can simplify and speed up many maintenance processes.
+ See <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a> to learn more about the
+ <code class="command">ATTACH PARTITION</code> and <code class="command">DETACH PARTITION</code>
+ sub-commands.
+ </p><p>
+ Partitions can also be <a class="link" href="ddl-foreign-data.html" title="5.12. Foreign Data">foreign
+ tables</a>, although considerable care is needed because it is then
+ the user's responsibility that the contents of the foreign table
+ satisfy the partitioning rule. There are some other restrictions as
+ well. See <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a> for more
+ information.
+ </p><div class="sect3" id="DDL-PARTITIONING-DECLARATIVE-EXAMPLE"><div class="titlepage"><div><div><h4 class="title">5.11.2.1. Example</h4></div></div></div><p>
+ Suppose we are constructing a database for a large ice cream company.
+ The company measures peak temperatures every day as well as ice cream
+ sales in each region. Conceptually, we want a table like:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement (
+ city_id int not null,
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+);
+</pre><p>
+
+ We know that most queries will access just the last week's, month's or
+ quarter's data, since the main use of this table will be to prepare
+ online reports for management. To reduce the amount of old data that
+ needs to be stored, we decide to keep only the most recent 3 years
+ worth of data. At the beginning of each month we will remove the oldest
+ month's data. In this situation we can use partitioning to help us meet
+ all of our different requirements for the measurements table.
+ </p><p>
+ To use declarative partitioning in this case, use the following steps:
+
+ </p><div class="orderedlist"><ol class="orderedlist compact" type="1"><li class="listitem"><p>
+ Create the <code class="structname">measurement</code> table as a partitioned
+ table by specifying the <code class="literal">PARTITION BY</code> clause, which
+ includes the partitioning method (<code class="literal">RANGE</code> in this
+ case) and the list of column(s) to use as the partition key.
+
+</p><pre class="programlisting">
+CREATE TABLE measurement (
+ city_id int not null,
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (logdate);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Create partitions. Each partition's definition must specify bounds
+ that correspond to the partitioning method and partition key of the
+ parent. Note that specifying bounds such that the new partition's
+ values would overlap with those in one or more existing partitions will
+ cause an error.
+ </p><p>
+ Partitions thus created are in every way normal
+ <span class="productname">PostgreSQL</span>
+ tables (or, possibly, foreign tables). It is possible to specify a
+ tablespace and storage parameters for each partition separately.
+ </p><p>
+ For our example, each partition should hold one month's worth of
+ data, to match the requirement of deleting one month's data at a
+ time. So the commands might look like:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2006m02 PARTITION OF measurement
+ FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
+
+CREATE TABLE measurement_y2006m03 PARTITION OF measurement
+ FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
+
+...
+CREATE TABLE measurement_y2007m11 PARTITION OF measurement
+ FOR VALUES FROM ('2007-11-01') TO ('2007-12-01');
+
+CREATE TABLE measurement_y2007m12 PARTITION OF measurement
+ FOR VALUES FROM ('2007-12-01') TO ('2008-01-01')
+ TABLESPACE fasttablespace;
+
+CREATE TABLE measurement_y2008m01 PARTITION OF measurement
+ FOR VALUES FROM ('2008-01-01') TO ('2008-02-01')
+ WITH (parallel_workers = 4)
+ TABLESPACE fasttablespace;
+</pre><p>
+
+ (Recall that adjacent partitions can share a bound value, since
+ range upper bounds are treated as exclusive bounds.)
+ </p><p>
+ If you wish to implement sub-partitioning, again specify the
+ <code class="literal">PARTITION BY</code> clause in the commands used to create
+ individual partitions, for example:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2006m02 PARTITION OF measurement
+ FOR VALUES FROM ('2006-02-01') TO ('2006-03-01')
+ PARTITION BY RANGE (peaktemp);
+</pre><p>
+
+ After creating partitions of <code class="structname">measurement_y2006m02</code>,
+ any data inserted into <code class="structname">measurement</code> that is mapped to
+ <code class="structname">measurement_y2006m02</code> (or data that is
+ directly inserted into <code class="structname">measurement_y2006m02</code>,
+ which is allowed provided its partition constraint is satisfied)
+ will be further redirected to one of its
+ partitions based on the <code class="structfield">peaktemp</code> column. The partition
+ key specified may overlap with the parent's partition key, although
+ care should be taken when specifying the bounds of a sub-partition
+ such that the set of data it accepts constitutes a subset of what
+ the partition's own bounds allow; the system does not try to check
+ whether that's really the case.
+ </p><p>
+ Inserting data into the parent table that does not map
+ to one of the existing partitions will cause an error; an appropriate
+ partition must be added manually.
+ </p><p>
+ It is not necessary to manually create table constraints describing
+ the partition boundary conditions for partitions. Such constraints
+ will be created automatically.
+ </p></li><li class="listitem"><p>
+ Create an index on the key column(s), as well as any other indexes you
+ might want, on the partitioned table. (The key index is not strictly
+ necessary, but in most scenarios it is helpful.)
+ This automatically creates a matching index on each partition, and
+ any partitions you create or attach later will also have such an
+ index.
+ An index or unique constraint declared on a partitioned table
+ is <span class="quote">“<span class="quote">virtual</span>”</span> in the same way that the partitioned table
+ is: the actual data is in child indexes on the individual partition
+ tables.
+
+</p><pre class="programlisting">
+CREATE INDEX ON measurement (logdate);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Ensure that the <a class="xref" href="runtime-config-query.html#GUC-ENABLE-PARTITION-PRUNING">enable_partition_pruning</a>
+ configuration parameter is not disabled in <code class="filename">postgresql.conf</code>.
+ If it is, queries will not be optimized as desired.
+ </p></li></ol></div><p>
+ </p><p>
+ In the above example we would be creating a new partition each month, so
+ it might be wise to write a script that generates the required DDL
+ automatically.
+ </p></div><div class="sect3" id="DDL-PARTITIONING-DECLARATIVE-MAINTENANCE"><div class="titlepage"><div><div><h4 class="title">5.11.2.2. Partition Maintenance</h4></div></div></div><p>
+ Normally the set of partitions established when initially defining the
+ table is not intended to remain static. It is common to want to
+ remove partitions holding old data and periodically add new partitions for
+ new data. One of the most important advantages of partitioning is
+ precisely that it allows this otherwise painful task to be executed
+ nearly instantaneously by manipulating the partition structure, rather
+ than physically moving large amounts of data around.
+ </p><p>
+ The simplest option for removing old data is to drop the partition that
+ is no longer necessary:
+</p><pre class="programlisting">
+DROP TABLE measurement_y2006m02;
+</pre><p>
+ This can very quickly delete millions of records because it doesn't have
+ to individually delete every record. Note however that the above command
+ requires taking an <code class="literal">ACCESS EXCLUSIVE</code> lock on the parent
+ table.
+ </p><p>
+ Another option that is often preferable is to remove the partition from
+ the partitioned table but retain access to it as a table in its own
+ right. This has two forms:
+
+</p><pre class="programlisting">
+ALTER TABLE measurement DETACH PARTITION measurement_y2006m02;
+ALTER TABLE measurement DETACH PARTITION measurement_y2006m02 CONCURRENTLY;
+</pre><p>
+
+ These allow further operations to be performed on the data before
+ it is dropped. For example, this is often a useful time to back up
+ the data using <code class="command">COPY</code>, <span class="application">pg_dump</span>, or
+ similar tools. It might also be a useful time to aggregate data
+ into smaller formats, perform other data manipulations, or run
+ reports. The first form of the command requires an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the parent table.
+ Adding the <code class="literal">CONCURRENTLY</code> qualifier as in the second
+ form allows the detach operation to require only
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock on the parent table, but see
+ <a class="link" href="sql-altertable.html#SQL-ALTERTABLE-DETACH-PARTITION"><code class="literal">ALTER TABLE ... DETACH PARTITION</code></a>
+ for details on the restrictions.
+ </p><p>
+ Similarly we can add a new partition to handle new data. We can create an
+ empty partition in the partitioned table just as the original partitions
+ were created above:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2008m02 PARTITION OF measurement
+ FOR VALUES FROM ('2008-02-01') TO ('2008-03-01')
+ TABLESPACE fasttablespace;
+</pre><p>
+
+ As an alternative, it is sometimes more convenient to create the
+ new table outside the partition structure, and attach it as a
+ partition later. This allows new data to be loaded, checked, and
+ transformed prior to it appearing in the partitioned table.
+ Moreover, the <code class="literal">ATTACH PARTITION</code> operation requires
+ only <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock on the
+ partitioned table, as opposed to the <code class="literal">ACCESS
+ EXCLUSIVE</code> lock that is required by <code class="command">CREATE TABLE
+ ... PARTITION OF</code>, so it is more friendly to concurrent
+ operations on the partitioned table.
+ The <code class="literal">CREATE TABLE ... LIKE</code> option is helpful
+ to avoid tediously repeating the parent table's definition:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2008m02
+ (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS)
+ TABLESPACE fasttablespace;
+
+ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02
+ CHECK ( logdate &gt;= DATE '2008-02-01' AND logdate &lt; DATE '2008-03-01' );
+
+\copy measurement_y2008m02 from 'measurement_y2008m02'
+-- possibly some other data preparation work
+
+ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02
+ FOR VALUES FROM ('2008-02-01') TO ('2008-03-01' );
+</pre><p>
+ </p><p>
+ Before running the <code class="command">ATTACH PARTITION</code> command, it is
+ recommended to create a <code class="literal">CHECK</code> constraint on the table to
+ be attached that matches the expected partition constraint, as
+ illustrated above. That way, the system will be able to skip the scan
+ which is otherwise needed to validate the implicit
+ partition constraint. Without the <code class="literal">CHECK</code> constraint,
+ the table will be scanned to validate the partition constraint while
+ holding an <code class="literal">ACCESS EXCLUSIVE</code> lock on that partition.
+ It is recommended to drop the now-redundant <code class="literal">CHECK</code>
+ constraint after the <code class="command">ATTACH PARTITION</code> is complete. If
+ the table being attached is itself a partitioned table, then each of its
+ sub-partitions will be recursively locked and scanned until either a
+ suitable <code class="literal">CHECK</code> constraint is encountered or the leaf
+ partitions are reached.
+ </p><p>
+ Similarly, if the partitioned table has a <code class="literal">DEFAULT</code>
+ partition, it is recommended to create a <code class="literal">CHECK</code>
+ constraint which excludes the to-be-attached partition's constraint. If
+ this is not done then the <code class="literal">DEFAULT</code> partition will be
+ scanned to verify that it contains no records which should be located in
+ the partition being attached. This operation will be performed whilst
+ holding an <code class="literal">ACCESS EXCLUSIVE</code> lock on the <code class="literal">
+ DEFAULT</code> partition. If the <code class="literal">DEFAULT</code> partition
+ is itself a partitioned table, then each of its partitions will be
+ recursively checked in the same way as the table being attached, as
+ mentioned above.
+ </p><p>
+ As explained above, it is possible to create indexes on partitioned tables
+ so that they are applied automatically to the entire hierarchy.
+ This is very
+ convenient, as not only will the existing partitions become indexed, but
+ also any partitions that are created in the future will. One limitation is
+ that it's not possible to use the <code class="literal">CONCURRENTLY</code>
+ qualifier when creating such a partitioned index. To avoid long lock
+ times, it is possible to use <code class="command">CREATE INDEX ON ONLY</code>
+ the partitioned table; such an index is marked invalid, and the partitions
+ do not get the index applied automatically. The indexes on partitions can
+ be created individually using <code class="literal">CONCURRENTLY</code>, and then
+ <em class="firstterm">attached</em> to the index on the parent using
+ <code class="command">ALTER INDEX .. ATTACH PARTITION</code>. Once indexes for all
+ partitions are attached to the parent index, the parent index is marked
+ valid automatically. Example:
+</p><pre class="programlisting">
+CREATE INDEX measurement_usls_idx ON ONLY measurement (unitsales);
+
+CREATE INDEX measurement_usls_200602_idx
+ ON measurement_y2006m02 (unitsales);
+ALTER INDEX measurement_usls_idx
+ ATTACH PARTITION measurement_usls_200602_idx;
+...
+</pre><p>
+
+ This technique can be used with <code class="literal">UNIQUE</code> and
+ <code class="literal">PRIMARY KEY</code> constraints too; the indexes are created
+ implicitly when the constraint is created. Example:
+</p><pre class="programlisting">
+ALTER TABLE ONLY measurement ADD UNIQUE (city_id, logdate);
+
+ALTER TABLE measurement_y2006m02 ADD UNIQUE (city_id, logdate);
+ALTER INDEX measurement_city_id_logdate_key
+ ATTACH PARTITION measurement_y2006m02_city_id_logdate_key;
+...
+</pre><p>
+ </p></div><div class="sect3" id="DDL-PARTITIONING-DECLARATIVE-LIMITATIONS"><div class="titlepage"><div><div><h4 class="title">5.11.2.3. Limitations</h4></div></div></div><p>
+ The following limitations apply to partitioned tables:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ To create a unique or primary key constraint on a partitioned table,
+ the partition keys must not include any expressions or function calls
+ and the constraint's columns must include all of the partition key
+ columns. This limitation exists because the individual indexes making
+ up the constraint can only directly enforce uniqueness within their own
+ partitions; therefore, the partition structure itself must guarantee
+ that there are not duplicates in different partitions.
+ </p></li><li class="listitem"><p>
+ There is no way to create an exclusion constraint spanning the
+ whole partitioned table. It is only possible to put such a
+ constraint on each leaf partition individually. Again, this
+ limitation stems from not being able to enforce cross-partition
+ restrictions.
+ </p></li><li class="listitem"><p>
+ <code class="literal">BEFORE ROW</code> triggers on <code class="literal">INSERT</code>
+ cannot change which partition is the final destination for a new row.
+ </p></li><li class="listitem"><p>
+ Mixing temporary and permanent relations in the same partition tree is
+ not allowed. Hence, if the partitioned table is permanent, so must be
+ its partitions and likewise if the partitioned table is temporary. When
+ using temporary relations, all members of the partition tree have to be
+ from the same session.
+ </p></li></ul></div><p>
+ </p><p>
+ Individual partitions are linked to their partitioned table using
+ inheritance behind-the-scenes. However, it is not possible to use
+ all of the generic features of inheritance with declaratively
+ partitioned tables or their partitions, as discussed below. Notably,
+ a partition cannot have any parents other than the partitioned table
+ it is a partition of, nor can a table inherit from both a partitioned
+ table and a regular table. That means partitioned tables and their
+ partitions never share an inheritance hierarchy with regular tables.
+ </p><p>
+ Since a partition hierarchy consisting of the partitioned table and its
+ partitions is still an inheritance hierarchy,
+ <code class="structfield">tableoid</code> and all the normal rules of
+ inheritance apply as described in <a class="xref" href="ddl-inherit.html" title="5.10. Inheritance">Section 5.10</a>, with
+ a few exceptions:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Partitions cannot have columns that are not present in the parent. It
+ is not possible to specify columns when creating partitions with
+ <code class="command">CREATE TABLE</code>, nor is it possible to add columns to
+ partitions after-the-fact using <code class="command">ALTER TABLE</code>.
+ Tables may be added as a partition with <code class="command">ALTER TABLE
+ ... ATTACH PARTITION</code> only if their columns exactly match
+ the parent.
+ </p></li><li class="listitem"><p>
+ Both <code class="literal">CHECK</code> and <code class="literal">NOT NULL</code>
+ constraints of a partitioned table are always inherited by all its
+ partitions. <code class="literal">CHECK</code> constraints that are marked
+ <code class="literal">NO INHERIT</code> are not allowed to be created on
+ partitioned tables.
+ You cannot drop a <code class="literal">NOT NULL</code> constraint on a
+ partition's column if the same constraint is present in the parent
+ table.
+ </p></li><li class="listitem"><p>
+ Using <code class="literal">ONLY</code> to add or drop a constraint on only
+ the partitioned table is supported as long as there are no
+ partitions. Once partitions exist, using <code class="literal">ONLY</code>
+ will result in an error. Instead, constraints on the partitions
+ themselves can be added and (if they are not present in the parent
+ table) dropped.
+ </p></li><li class="listitem"><p>
+ As a partitioned table does not have any data itself, attempts to use
+ <code class="command">TRUNCATE</code> <code class="literal">ONLY</code> on a partitioned
+ table will always return an error.
+ </p></li></ul></div><p>
+ </p></div></div><div class="sect2" id="DDL-PARTITIONING-USING-INHERITANCE"><div class="titlepage"><div><div><h3 class="title">5.11.3. Partitioning Using Inheritance</h3></div></div></div><p>
+ While the built-in declarative partitioning is suitable for most
+ common use cases, there are some circumstances where a more flexible
+ approach may be useful. Partitioning can be implemented using table
+ inheritance, which allows for several features not supported
+ by declarative partitioning, such as:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ For declarative partitioning, partitions must have exactly the same set
+ of columns as the partitioned table, whereas with table inheritance,
+ child tables may have extra columns not present in the parent.
+ </p></li><li class="listitem"><p>
+ Table inheritance allows for multiple inheritance.
+ </p></li><li class="listitem"><p>
+ Declarative partitioning only supports range, list and hash
+ partitioning, whereas table inheritance allows data to be divided in a
+ manner of the user's choosing. (Note, however, that if constraint
+ exclusion is unable to prune child tables effectively, query performance
+ might be poor.)
+ </p></li></ul></div><p>
+ </p><div class="sect3" id="DDL-PARTITIONING-INHERITANCE-EXAMPLE"><div class="titlepage"><div><div><h4 class="title">5.11.3.1. Example</h4></div></div></div><p>
+ This example builds a partitioning structure equivalent to the
+ declarative partitioning example above. Use
+ the following steps:
+
+ </p><div class="orderedlist"><ol class="orderedlist compact" type="1"><li class="listitem"><p>
+ Create the <span class="quote">“<span class="quote">root</span>”</span> table, from which all of the
+ <span class="quote">“<span class="quote">child</span>”</span> tables will inherit. This table will contain no data. Do not
+ define any check constraints on this table, unless you intend them
+ to be applied equally to all child tables. There is no point in
+ defining any indexes or unique constraints on it, either. For our
+ example, the root table is the <code class="structname">measurement</code>
+ table as originally defined:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement (
+ city_id int not null,
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Create several <span class="quote">“<span class="quote">child</span>”</span> tables that each inherit from
+ the root table. Normally, these tables will not add any columns
+ to the set inherited from the root. Just as with declarative
+ partitioning, these tables are in every way normal
+ <span class="productname">PostgreSQL</span> tables (or foreign tables).
+ </p><p>
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2006m02 () INHERITS (measurement);
+CREATE TABLE measurement_y2006m03 () INHERITS (measurement);
+...
+CREATE TABLE measurement_y2007m11 () INHERITS (measurement);
+CREATE TABLE measurement_y2007m12 () INHERITS (measurement);
+CREATE TABLE measurement_y2008m01 () INHERITS (measurement);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Add non-overlapping table constraints to the child tables to
+ define the allowed key values in each.
+ </p><p>
+ Typical examples would be:
+</p><pre class="programlisting">
+CHECK ( x = 1 )
+CHECK ( county IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' ))
+CHECK ( outletID &gt;= 100 AND outletID &lt; 200 )
+</pre><p>
+ Ensure that the constraints guarantee that there is no overlap
+ between the key values permitted in different child tables. A common
+ mistake is to set up range constraints like:
+</p><pre class="programlisting">
+CHECK ( outletID BETWEEN 100 AND 200 )
+CHECK ( outletID BETWEEN 200 AND 300 )
+</pre><p>
+ This is wrong since it is not clear which child table the key
+ value 200 belongs in.
+ Instead, ranges should be defined in this style:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2006m02 (
+ CHECK ( logdate &gt;= DATE '2006-02-01' AND logdate &lt; DATE '2006-03-01' )
+) INHERITS (measurement);
+
+CREATE TABLE measurement_y2006m03 (
+ CHECK ( logdate &gt;= DATE '2006-03-01' AND logdate &lt; DATE '2006-04-01' )
+) INHERITS (measurement);
+
+...
+CREATE TABLE measurement_y2007m11 (
+ CHECK ( logdate &gt;= DATE '2007-11-01' AND logdate &lt; DATE '2007-12-01' )
+) INHERITS (measurement);
+
+CREATE TABLE measurement_y2007m12 (
+ CHECK ( logdate &gt;= DATE '2007-12-01' AND logdate &lt; DATE '2008-01-01' )
+) INHERITS (measurement);
+
+CREATE TABLE measurement_y2008m01 (
+ CHECK ( logdate &gt;= DATE '2008-01-01' AND logdate &lt; DATE '2008-02-01' )
+) INHERITS (measurement);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ For each child table, create an index on the key column(s),
+ as well as any other indexes you might want.
+</p><pre class="programlisting">
+CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate);
+CREATE INDEX measurement_y2006m03_logdate ON measurement_y2006m03 (logdate);
+CREATE INDEX measurement_y2007m11_logdate ON measurement_y2007m11 (logdate);
+CREATE INDEX measurement_y2007m12_logdate ON measurement_y2007m12 (logdate);
+CREATE INDEX measurement_y2008m01_logdate ON measurement_y2008m01 (logdate);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ We want our application to be able to say <code class="literal">INSERT INTO
+ measurement ...</code> and have the data be redirected into the
+ appropriate child table. We can arrange that by attaching
+ a suitable trigger function to the root table.
+ If data will be added only to the latest child, we can
+ use a very simple trigger function:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION measurement_insert_trigger()
+RETURNS TRIGGER AS $$
+BEGIN
+ INSERT INTO measurement_y2008m01 VALUES (NEW.*);
+ RETURN NULL;
+END;
+$$
+LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ After creating the function, we create a trigger which
+ calls the trigger function:
+
+</p><pre class="programlisting">
+CREATE TRIGGER insert_measurement_trigger
+ BEFORE INSERT ON measurement
+ FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger();
+</pre><p>
+
+ We must redefine the trigger function each month so that it always
+ inserts into the current child table. The trigger definition does
+ not need to be updated, however.
+ </p><p>
+ We might want to insert data and have the server automatically
+ locate the child table into which the row should be added. We
+ could do this with a more complex trigger function, for example:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION measurement_insert_trigger()
+RETURNS TRIGGER AS $$
+BEGIN
+ IF ( NEW.logdate &gt;= DATE '2006-02-01' AND
+ NEW.logdate &lt; DATE '2006-03-01' ) THEN
+ INSERT INTO measurement_y2006m02 VALUES (NEW.*);
+ ELSIF ( NEW.logdate &gt;= DATE '2006-03-01' AND
+ NEW.logdate &lt; DATE '2006-04-01' ) THEN
+ INSERT INTO measurement_y2006m03 VALUES (NEW.*);
+ ...
+ ELSIF ( NEW.logdate &gt;= DATE '2008-01-01' AND
+ NEW.logdate &lt; DATE '2008-02-01' ) THEN
+ INSERT INTO measurement_y2008m01 VALUES (NEW.*);
+ ELSE
+ RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!';
+ END IF;
+ RETURN NULL;
+END;
+$$
+LANGUAGE plpgsql;
+</pre><p>
+
+ The trigger definition is the same as before.
+ Note that each <code class="literal">IF</code> test must exactly match the
+ <code class="literal">CHECK</code> constraint for its child table.
+ </p><p>
+ While this function is more complex than the single-month case,
+ it doesn't need to be updated as often, since branches can be
+ added in advance of being needed.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In practice, it might be best to check the newest child first,
+ if most inserts go into that child. For simplicity, we have
+ shown the trigger's tests in the same order as in other parts
+ of this example.
+ </p></div><p>
+ A different approach to redirecting inserts into the appropriate
+ child table is to set up rules, instead of a trigger, on the
+ root table. For example:
+
+</p><pre class="programlisting">
+CREATE RULE measurement_insert_y2006m02 AS
+ON INSERT TO measurement WHERE
+ ( logdate &gt;= DATE '2006-02-01' AND logdate &lt; DATE '2006-03-01' )
+DO INSTEAD
+ INSERT INTO measurement_y2006m02 VALUES (NEW.*);
+...
+CREATE RULE measurement_insert_y2008m01 AS
+ON INSERT TO measurement WHERE
+ ( logdate &gt;= DATE '2008-01-01' AND logdate &lt; DATE '2008-02-01' )
+DO INSTEAD
+ INSERT INTO measurement_y2008m01 VALUES (NEW.*);
+</pre><p>
+
+ A rule has significantly more overhead than a trigger, but the
+ overhead is paid once per query rather than once per row, so this
+ method might be advantageous for bulk-insert situations. In most
+ cases, however, the trigger method will offer better performance.
+ </p><p>
+ Be aware that <code class="command">COPY</code> ignores rules. If you want to
+ use <code class="command">COPY</code> to insert data, you'll need to copy into the
+ correct child table rather than directly into the root. <code class="command">COPY</code>
+ does fire triggers, so you can use it normally if you use the trigger
+ approach.
+ </p><p>
+ Another disadvantage of the rule approach is that there is no simple
+ way to force an error if the set of rules doesn't cover the insertion
+ date; the data will silently go into the root table instead.
+ </p></li><li class="listitem"><p>
+ Ensure that the <a class="xref" href="runtime-config-query.html#GUC-CONSTRAINT-EXCLUSION">constraint_exclusion</a>
+ configuration parameter is not disabled in
+ <code class="filename">postgresql.conf</code>; otherwise
+ child tables may be accessed unnecessarily.
+ </p></li></ol></div><p>
+ </p><p>
+ As we can see, a complex table hierarchy could require a
+ substantial amount of DDL. In the above example we would be creating
+ a new child table each month, so it might be wise to write a script that
+ generates the required DDL automatically.
+ </p></div><div class="sect3" id="DDL-PARTITIONING-INHERITANCE-MAINTENANCE"><div class="titlepage"><div><div><h4 class="title">5.11.3.2. Maintenance for Inheritance Partitioning</h4></div></div></div><p>
+ To remove old data quickly, simply drop the child table that is no longer
+ necessary:
+</p><pre class="programlisting">
+DROP TABLE measurement_y2006m02;
+</pre><p>
+ </p><p>
+ To remove the child table from the inheritance hierarchy table but retain access to
+ it as a table in its own right:
+
+</p><pre class="programlisting">
+ALTER TABLE measurement_y2006m02 NO INHERIT measurement;
+</pre><p>
+ </p><p>
+ To add a new child table to handle new data, create an empty child table
+ just as the original children were created above:
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2008m02 (
+ CHECK ( logdate &gt;= DATE '2008-02-01' AND logdate &lt; DATE '2008-03-01' )
+) INHERITS (measurement);
+</pre><p>
+
+ Alternatively, one may want to create and populate the new child table
+ before adding it to the table hierarchy. This could allow data to be
+ loaded, checked, and transformed before being made visible to queries on
+ the parent table.
+
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2008m02
+ (LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
+ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02
+ CHECK ( logdate &gt;= DATE '2008-02-01' AND logdate &lt; DATE '2008-03-01' );
+\copy measurement_y2008m02 from 'measurement_y2008m02'
+-- possibly some other data preparation work
+ALTER TABLE measurement_y2008m02 INHERIT measurement;
+</pre><p>
+ </p></div><div class="sect3" id="DDL-PARTITIONING-INHERITANCE-CAVEATS"><div class="titlepage"><div><div><h4 class="title">5.11.3.3. Caveats</h4></div></div></div><p>
+ The following caveats apply to partitioning implemented using
+ inheritance:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ There is no automatic way to verify that all of the
+ <code class="literal">CHECK</code> constraints are mutually
+ exclusive. It is safer to create code that generates
+ child tables and creates and/or modifies associated objects than
+ to write each by hand.
+ </p></li><li class="listitem"><p>
+ Indexes and foreign key constraints apply to single tables and not
+ to their inheritance children, hence they have some
+ <a class="link" href="ddl-inherit.html#DDL-INHERIT-CAVEATS" title="5.10.1. Caveats">caveats</a> to be aware of.
+ </p></li><li class="listitem"><p>
+ The schemes shown here assume that the values of a row's key column(s)
+ never change, or at least do not change enough to require it to move to another partition.
+ An <code class="command">UPDATE</code> that attempts
+ to do that will fail because of the <code class="literal">CHECK</code> constraints.
+ If you need to handle such cases, you can put suitable update triggers
+ on the child tables, but it makes management of the structure
+ much more complicated.
+ </p></li><li class="listitem"><p>
+ If you are using manual <code class="command">VACUUM</code> or
+ <code class="command">ANALYZE</code> commands, don't forget that
+ you need to run them on each child table individually. A command like:
+</p><pre class="programlisting">
+ANALYZE measurement;
+</pre><p>
+ will only process the root table.
+ </p></li><li class="listitem"><p>
+ <code class="command">INSERT</code> statements with <code class="literal">ON CONFLICT</code>
+ clauses are unlikely to work as expected, as the <code class="literal">ON CONFLICT</code>
+ action is only taken in case of unique violations on the specified
+ target relation, not its child relations.
+ </p></li><li class="listitem"><p>
+ Triggers or rules will be needed to route rows to the desired
+ child table, unless the application is explicitly aware of the
+ partitioning scheme. Triggers may be complicated to write, and will
+ be much slower than the tuple routing performed internally by
+ declarative partitioning.
+ </p></li></ul></div><p>
+ </p></div></div><div class="sect2" id="DDL-PARTITION-PRUNING"><div class="titlepage"><div><div><h3 class="title">5.11.4. Partition Pruning</h3></div></div></div><a id="id-1.5.4.13.9.2" class="indexterm"></a><p>
+ <em class="firstterm">Partition pruning</em> is a query optimization technique
+ that improves performance for declaratively partitioned tables.
+ As an example:
+
+</p><pre class="programlisting">
+SET enable_partition_pruning = on; -- the default
+SELECT count(*) FROM measurement WHERE logdate &gt;= DATE '2008-01-01';
+</pre><p>
+
+ Without partition pruning, the above query would scan each of the
+ partitions of the <code class="structname">measurement</code> table. With
+ partition pruning enabled, the planner will examine the definition
+ of each partition and prove that the partition need not
+ be scanned because it could not contain any rows meeting the query's
+ <code class="literal">WHERE</code> clause. When the planner can prove this, it
+ excludes (<em class="firstterm">prunes</em>) the partition from the query
+ plan.
+ </p><p>
+ By using the EXPLAIN command and the <a class="xref" href="runtime-config-query.html#GUC-ENABLE-PARTITION-PRUNING">enable_partition_pruning</a> configuration parameter, it's
+ possible to show the difference between a plan for which partitions have
+ been pruned and one for which they have not. A typical unoptimized
+ plan for this type of table setup is:
+</p><pre class="programlisting">
+SET enable_partition_pruning = off;
+EXPLAIN SELECT count(*) FROM measurement WHERE logdate &gt;= DATE '2008-01-01';
+ QUERY PLAN
+-------------------------------------------------------------------​----------------
+ Aggregate (cost=188.76..188.77 rows=1 width=8)
+ -&gt; Append (cost=0.00..181.05 rows=3085 width=0)
+ -&gt; Seq Scan on measurement_y2006m02 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+ -&gt; Seq Scan on measurement_y2006m03 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+...
+ -&gt; Seq Scan on measurement_y2007m11 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+ -&gt; Seq Scan on measurement_y2007m12 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+ -&gt; Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+</pre><p>
+
+ Some or all of the partitions might use index scans instead of
+ full-table sequential scans, but the point here is that there
+ is no need to scan the older partitions at all to answer this query.
+ When we enable partition pruning, we get a significantly
+ cheaper plan that will deliver the same answer:
+</p><pre class="programlisting">
+SET enable_partition_pruning = on;
+EXPLAIN SELECT count(*) FROM measurement WHERE logdate &gt;= DATE '2008-01-01';
+ QUERY PLAN
+-------------------------------------------------------------------​----------------
+ Aggregate (cost=37.75..37.76 rows=1 width=8)
+ -&gt; Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0)
+ Filter: (logdate &gt;= '2008-01-01'::date)
+</pre><p>
+ </p><p>
+ Note that partition pruning is driven only by the constraints defined
+ implicitly by the partition keys, not by the presence of indexes.
+ Therefore it isn't necessary to define indexes on the key columns.
+ Whether an index needs to be created for a given partition depends on
+ whether you expect that queries that scan the partition will
+ generally scan a large part of the partition or just a small part.
+ An index will be helpful in the latter case but not the former.
+ </p><p>
+ Partition pruning can be performed not only during the planning of a
+ given query, but also during its execution. This is useful as it can
+ allow more partitions to be pruned when clauses contain expressions
+ whose values are not known at query planning time, for example,
+ parameters defined in a <code class="command">PREPARE</code> statement, using a
+ value obtained from a subquery, or using a parameterized value on the
+ inner side of a nested loop join. Partition pruning during execution
+ can be performed at any of the following times:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ During initialization of the query plan. Partition pruning can be
+ performed here for parameter values which are known during the
+ initialization phase of execution. Partitions which are pruned
+ during this stage will not show up in the query's
+ <code class="command">EXPLAIN</code> or <code class="command">EXPLAIN ANALYZE</code>.
+ It is possible to determine the number of partitions which were
+ removed during this phase by observing the
+ <span class="quote">“<span class="quote">Subplans Removed</span>”</span> property in the
+ <code class="command">EXPLAIN</code> output.
+ </p></li><li class="listitem"><p>
+ During actual execution of the query plan. Partition pruning may
+ also be performed here to remove partitions using values which are
+ only known during actual query execution. This includes values
+ from subqueries and values from execution-time parameters such as
+ those from parameterized nested loop joins. Since the value of
+ these parameters may change many times during the execution of the
+ query, partition pruning is performed whenever one of the
+ execution parameters being used by partition pruning changes.
+ Determining if partitions were pruned during this phase requires
+ careful inspection of the <code class="literal">loops</code> property in
+ the <code class="command">EXPLAIN ANALYZE</code> output. Subplans
+ corresponding to different partitions may have different values
+ for it depending on how many times each of them was pruned during
+ execution. Some may be shown as <code class="literal">(never executed)</code>
+ if they were pruned every time.
+ </p></li></ul></div><p>
+ </p><p>
+ Partition pruning can be disabled using the
+ <a class="xref" href="runtime-config-query.html#GUC-ENABLE-PARTITION-PRUNING">enable_partition_pruning</a> setting.
+ </p></div><div class="sect2" id="DDL-PARTITIONING-CONSTRAINT-EXCLUSION"><div class="titlepage"><div><div><h3 class="title">5.11.5. Partitioning and Constraint Exclusion</h3></div></div></div><a id="id-1.5.4.13.10.2" class="indexterm"></a><p>
+ <em class="firstterm">Constraint exclusion</em> is a query optimization
+ technique similar to partition pruning. While it is primarily used
+ for partitioning implemented using the legacy inheritance method, it can be
+ used for other purposes, including with declarative partitioning.
+ </p><p>
+ Constraint exclusion works in a very similar way to partition
+ pruning, except that it uses each table's <code class="literal">CHECK</code>
+ constraints — which gives it its name — whereas partition
+ pruning uses the table's partition bounds, which exist only in the
+ case of declarative partitioning. Another difference is that
+ constraint exclusion is only applied at plan time; there is no attempt
+ to remove partitions at execution time.
+ </p><p>
+ The fact that constraint exclusion uses <code class="literal">CHECK</code>
+ constraints, which makes it slow compared to partition pruning, can
+ sometimes be used as an advantage: because constraints can be defined
+ even on declaratively-partitioned tables, in addition to their internal
+ partition bounds, constraint exclusion may be able
+ to elide additional partitions from the query plan.
+ </p><p>
+ The default (and recommended) setting of
+ <a class="xref" href="runtime-config-query.html#GUC-CONSTRAINT-EXCLUSION">constraint_exclusion</a> is neither
+ <code class="literal">on</code> nor <code class="literal">off</code>, but an intermediate setting
+ called <code class="literal">partition</code>, which causes the technique to be
+ applied only to queries that are likely to be working on inheritance partitioned
+ tables. The <code class="literal">on</code> setting causes the planner to examine
+ <code class="literal">CHECK</code> constraints in all queries, even simple ones that
+ are unlikely to benefit.
+ </p><p>
+ The following caveats apply to constraint exclusion:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Constraint exclusion is only applied during query planning, unlike
+ partition pruning, which can also be applied during query execution.
+ </p></li><li class="listitem"><p>
+ Constraint exclusion only works when the query's <code class="literal">WHERE</code>
+ clause contains constants (or externally supplied parameters).
+ For example, a comparison against a non-immutable function such as
+ <code class="function">CURRENT_TIMESTAMP</code> cannot be optimized, since the
+ planner cannot know which child table the function's value might fall
+ into at run time.
+ </p></li><li class="listitem"><p>
+ Keep the partitioning constraints simple, else the planner may not be
+ able to prove that child tables might not need to be visited. Use simple
+ equality conditions for list partitioning, or simple
+ range tests for range partitioning, as illustrated in the preceding
+ examples. A good rule of thumb is that partitioning constraints should
+ contain only comparisons of the partitioning column(s) to constants
+ using B-tree-indexable operators, because only B-tree-indexable
+ column(s) are allowed in the partition key.
+ </p></li><li class="listitem"><p>
+ All constraints on all children of the parent table are examined
+ during constraint exclusion, so large numbers of children are likely
+ to increase query planning time considerably. So the legacy
+ inheritance based partitioning will work well with up to perhaps a
+ hundred child tables; don't try to use many thousands of children.
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="DDL-PARTITIONING-DECLARATIVE-BEST-PRACTICES"><div class="titlepage"><div><div><h3 class="title">5.11.6. Best Practices for Declarative Partitioning</h3></div></div></div><p>
+ The choice of how to partition a table should be made carefully, as the
+ performance of query planning and execution can be negatively affected by
+ poor design.
+ </p><p>
+ One of the most critical design decisions will be the column or columns
+ by which you partition your data. Often the best choice will be to
+ partition by the column or set of columns which most commonly appear in
+ <code class="literal">WHERE</code> clauses of queries being executed on the
+ partitioned table. <code class="literal">WHERE</code> clauses that are compatible
+ with the partition bound constraints can be used to prune unneeded
+ partitions. However, you may be forced into making other decisions by
+ requirements for the <code class="literal">PRIMARY KEY</code> or a
+ <code class="literal">UNIQUE</code> constraint. Removal of unwanted data is also a
+ factor to consider when planning your partitioning strategy. An entire
+ partition can be detached fairly quickly, so it may be beneficial to
+ design the partition strategy in such a way that all data to be removed
+ at once is located in a single partition.
+ </p><p>
+ Choosing the target number of partitions that the table should be divided
+ into is also a critical decision to make. Not having enough partitions
+ may mean that indexes remain too large and that data locality remains poor
+ which could result in low cache hit ratios. However, dividing the table
+ into too many partitions can also cause issues. Too many partitions can
+ mean longer query planning times and higher memory consumption during both
+ query planning and execution, as further described below.
+ When choosing how to partition your table,
+ it's also important to consider what changes may occur in the future. For
+ example, if you choose to have one partition per customer and you
+ currently have a small number of large customers, consider the
+ implications if in several years you instead find yourself with a large
+ number of small customers. In this case, it may be better to choose to
+ partition by <code class="literal">HASH</code> and choose a reasonable number of
+ partitions rather than trying to partition by <code class="literal">LIST</code> and
+ hoping that the number of customers does not increase beyond what it is
+ practical to partition the data by.
+ </p><p>
+ Sub-partitioning can be useful to further divide partitions that are
+ expected to become larger than other partitions.
+ Another option is to use range partitioning with multiple columns in
+ the partition key.
+ Either of these can easily lead to excessive numbers of partitions,
+ so restraint is advisable.
+ </p><p>
+ It is important to consider the overhead of partitioning during
+ query planning and execution. The query planner is generally able to
+ handle partition hierarchies with up to a few thousand partitions fairly
+ well, provided that typical queries allow the query planner to prune all
+ but a small number of partitions. Planning times become longer and memory
+ consumption becomes higher when more partitions remain after the planner
+ performs partition pruning. Another
+ reason to be concerned about having a large number of partitions is that
+ the server's memory consumption may grow significantly over
+ time, especially if many sessions touch large numbers of partitions.
+ That's because each partition requires its metadata to be loaded into the
+ local memory of each session that touches it.
+ </p><p>
+ With data warehouse type workloads, it can make sense to use a larger
+ number of partitions than with an <acronym class="acronym">OLTP</acronym> type workload.
+ Generally, in data warehouses, query planning time is less of a concern as
+ the majority of processing time is spent during query execution. With
+ either of these two types of workload, it is important to make the right
+ decisions early, as re-partitioning large quantities of data can be
+ painfully slow. Simulations of the intended workload are often beneficial
+ for optimizing the partitioning strategy. Never just assume that more
+ partitions are better than fewer partitions, nor vice-versa.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-inherit.html" title="5.10. Inheritance">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-foreign-data.html" title="5.12. Foreign Data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.10. Inheritance </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.12. Foreign Data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-priv.html b/doc/src/sgml/html/ddl-priv.html
new file mode 100644
index 0000000..02fd289
--- /dev/null
+++ b/doc/src/sgml/html/ddl-priv.html
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.7. Privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-alter.html" title="5.6. Modifying Tables" /><link rel="next" href="ddl-rowsecurity.html" title="5.8. Row Security Policies" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.7. Privileges</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-alter.html" title="5.6. Modifying Tables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-PRIV"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.7. Privileges</h2></div></div></div><a id="id-1.5.4.9.2" class="indexterm"></a><a id="id-1.5.4.9.3" class="indexterm"></a><a id="id-1.5.4.9.4" class="indexterm"></a><a id="id-1.5.4.9.5" class="indexterm"></a><a id="id-1.5.4.9.6" class="indexterm"></a><a id="id-1.5.4.9.7" class="indexterm"></a><p>
+ When an object is created, it is assigned an owner. The
+ owner is normally the role that executed the creation statement.
+ For most kinds of objects, the initial state is that only the owner
+ (or a superuser) can do anything with the object. To allow
+ other roles to use it, <em class="firstterm">privileges</em> must be
+ granted.
+ </p><p>
+ There are different kinds of privileges: <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
+ <code class="literal">TRUNCATE</code>, <code class="literal">REFERENCES</code>, <code class="literal">TRIGGER</code>,
+ <code class="literal">CREATE</code>, <code class="literal">CONNECT</code>, <code class="literal">TEMPORARY</code>,
+ <code class="literal">EXECUTE</code>, <code class="literal">USAGE</code>, <code class="literal">SET</code>
+ and <code class="literal">ALTER SYSTEM</code>.
+ The privileges applicable to a particular
+ object vary depending on the object's type (table, function, etc.).
+ More detail about the meanings of these privileges appears below.
+ The following sections and chapters will also show you how
+ these privileges are used.
+ </p><p>
+ The right to modify or destroy an object is inherent in being the
+ object's owner, and cannot be granted or revoked in itself.
+ (However, like all privileges, that right can be inherited by
+ members of the owning role; see <a class="xref" href="role-membership.html" title="22.3. Role Membership">Section 22.3</a>.)
+ </p><p>
+ An object can be assigned to a new owner with an <code class="command">ALTER</code>
+ command of the appropriate kind for the object, for example
+</p><pre class="programlisting">
+ALTER TABLE <em class="replaceable"><code>table_name</code></em> OWNER TO <em class="replaceable"><code>new_owner</code></em>;
+</pre><p>
+ Superusers can always do this; ordinary roles can only do it if they are
+ both the current owner of the object (or a member of the owning role) and
+ a member of the new owning role.
+ </p><p>
+ To assign privileges, the <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a> command is
+ used. For example, if <code class="literal">joe</code> is an existing role, and
+ <code class="literal">accounts</code> is an existing table, the privilege to
+ update the table can be granted with:
+</p><pre class="programlisting">
+GRANT UPDATE ON accounts TO joe;
+</pre><p>
+ Writing <code class="literal">ALL</code> in place of a specific privilege grants all
+ privileges that are relevant for the object type.
+ </p><p>
+ The special <span class="quote">“<span class="quote">role</span>”</span> name <code class="literal">PUBLIC</code> can
+ be used to grant a privilege to every role on the system. Also,
+ <span class="quote">“<span class="quote">group</span>”</span> roles can be set up to help manage privileges when
+ there are many users of a database — for details see
+ <a class="xref" href="user-manag.html" title="Chapter 22. Database Roles">Chapter 22</a>.
+ </p><p>
+ To revoke a previously-granted privilege, use the fittingly named
+ <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a> command:
+</p><pre class="programlisting">
+REVOKE ALL ON accounts FROM PUBLIC;
+</pre><p>
+ </p><p>
+ Ordinarily, only the object's owner (or a superuser) can grant or
+ revoke privileges on an object. However, it is possible to grant a
+ privilege <span class="quote">“<span class="quote">with grant option</span>”</span>, which gives the recipient
+ the right to grant it in turn to others. If the grant option is
+ subsequently revoked then all who received the privilege from that
+ recipient (directly or through a chain of grants) will lose the
+ privilege. For details see the <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a> and
+ <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a> reference pages.
+ </p><p>
+ An object's owner can choose to revoke their own ordinary privileges,
+ for example to make a table read-only for themselves as well as others.
+ But owners are always treated as holding all grant options, so they
+ can always re-grant their own privileges.
+ </p><p>
+ The available privileges are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SELECT</code></span></dt><dd><p>
+ Allows <code class="command">SELECT</code> from
+ any column, or specific column(s), of a table, view, materialized
+ view, or other table-like object.
+ Also allows use of <code class="command">COPY TO</code>.
+ This privilege is also needed to reference existing column values in
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ or <code class="command">MERGE</code>.
+ For sequences, this privilege also allows use of the
+ <code class="function">currval</code> function.
+ For large objects, this privilege allows the object to be read.
+ </p></dd><dt><span class="term"><code class="literal">INSERT</code></span></dt><dd><p>
+ Allows <code class="command">INSERT</code> of a new row into a table, view,
+ etc. Can be granted on specific column(s), in which case
+ only those columns may be assigned to in the <code class="command">INSERT</code>
+ command (other columns will therefore receive default values).
+ Also allows use of <code class="command">COPY FROM</code>.
+ </p></dd><dt><span class="term"><code class="literal">UPDATE</code></span></dt><dd><p>
+ Allows <code class="command">UPDATE</code> of any
+ column, or specific column(s), of a table, view, etc.
+ (In practice, any nontrivial <code class="command">UPDATE</code> command will
+ require <code class="literal">SELECT</code> privilege as well, since it must
+ reference table columns to determine which rows to update, and/or to
+ compute new values for columns.)
+ <code class="literal">SELECT ... FOR UPDATE</code>
+ and <code class="literal">SELECT ... FOR SHARE</code>
+ also require this privilege on at least one column, in addition to the
+ <code class="literal">SELECT</code> privilege. For sequences, this
+ privilege allows use of the <code class="function">nextval</code> and
+ <code class="function">setval</code> functions.
+ For large objects, this privilege allows writing or truncating the
+ object.
+ </p></dd><dt><span class="term"><code class="literal">DELETE</code></span></dt><dd><p>
+ Allows <code class="command">DELETE</code> of a row from a table, view, etc.
+ (In practice, any nontrivial <code class="command">DELETE</code> command will
+ require <code class="literal">SELECT</code> privilege as well, since it must
+ reference table columns to determine which rows to delete.)
+ </p></dd><dt><span class="term"><code class="literal">TRUNCATE</code></span></dt><dd><p>
+ Allows <code class="command">TRUNCATE</code> on a table.
+ </p></dd><dt><span class="term"><code class="literal">REFERENCES</code></span></dt><dd><p>
+ Allows creation of a foreign key constraint referencing a
+ table, or specific column(s) of a table.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER</code></span></dt><dd><p>
+ Allows creation of a trigger on a table, view, etc.
+ </p></dd><dt><span class="term"><code class="literal">CREATE</code></span></dt><dd><p>
+ For databases, allows new schemas and publications to be created within
+ the database, and allows trusted extensions to be installed within
+ the database.
+ </p><p>
+ For schemas, allows new objects to be created within the schema.
+ To rename an existing object, you must own the
+ object <span class="emphasis"><em>and</em></span> have this privilege for the containing
+ schema.
+ </p><p>
+ For tablespaces, allows tables, indexes, and temporary files to be
+ created within the tablespace, and allows databases to be created that
+ have the tablespace as their default tablespace.
+ </p><p>
+ Note that revoking this privilege will not alter the existence or
+ location of existing objects.
+ </p></dd><dt><span class="term"><code class="literal">CONNECT</code></span></dt><dd><p>
+ Allows the grantee to connect to the database. This
+ privilege is checked at connection startup (in addition to checking
+ any restrictions imposed by <code class="filename">pg_hba.conf</code>).
+ </p></dd><dt><span class="term"><code class="literal">TEMPORARY</code></span></dt><dd><p>
+ Allows temporary tables to be created while using the database.
+ </p></dd><dt><span class="term"><code class="literal">EXECUTE</code></span></dt><dd><p>
+ Allows calling a function or procedure, including use of
+ any operators that are implemented on top of the function. This is the
+ only type of privilege that is applicable to functions and procedures.
+ </p></dd><dt><span class="term"><code class="literal">USAGE</code></span></dt><dd><p>
+ For procedural languages, allows use of the language for
+ the creation of functions in that language. This is the only type
+ of privilege that is applicable to procedural languages.
+ </p><p>
+ For schemas, allows access to objects contained in the
+ schema (assuming that the objects' own privilege requirements are
+ also met). Essentially this allows the grantee to <span class="quote">“<span class="quote">look up</span>”</span>
+ objects within the schema. Without this permission, it is still
+ possible to see the object names, e.g., by querying system catalogs.
+ Also, after revoking this permission, existing sessions might have
+ statements that have previously performed this lookup, so this is not
+ a completely secure way to prevent object access.
+ </p><p>
+ For sequences, allows use of the
+ <code class="function">currval</code> and <code class="function">nextval</code> functions.
+ </p><p>
+ For types and domains, allows use of the type or domain in the
+ creation of tables, functions, and other schema objects. (Note that
+ this privilege does not control all <span class="quote">“<span class="quote">usage</span>”</span> of the
+ type, such as values of the type appearing in queries. It only
+ prevents objects from being created that depend on the type. The
+ main purpose of this privilege is controlling which users can create
+ dependencies on a type, which could prevent the owner from changing
+ the type later.)
+ </p><p>
+ For foreign-data wrappers, allows creation of new servers using the
+ foreign-data wrapper.
+ </p><p>
+ For foreign servers, allows creation of foreign tables using the
+ server. Grantees may also create, alter, or drop their own user
+ mappings associated with that server.
+ </p></dd><dt><span class="term"><code class="literal">SET</code></span></dt><dd><p>
+ Allows a server configuration parameter to be set to a new value
+ within the current session. (While this privilege can be granted
+ on any parameter, it is meaningless except for parameters that would
+ normally require superuser privilege to set.)
+ </p></dd><dt><span class="term"><code class="literal">ALTER SYSTEM</code></span></dt><dd><p>
+ Allows a server configuration parameter to be configured to a new
+ value using the <a class="xref" href="sql-altersystem.html" title="ALTER SYSTEM"><span class="refentrytitle">ALTER SYSTEM</span></a> command.
+ </p></dd></dl></div><p>
+
+ The privileges required by other commands are listed on the
+ reference page of the respective command.
+ </p><p>
+ PostgreSQL grants privileges on some types of objects to
+ <code class="literal">PUBLIC</code> by default when the objects are created.
+ No privileges are granted to <code class="literal">PUBLIC</code> by default on
+ tables,
+ table columns,
+ sequences,
+ foreign data wrappers,
+ foreign servers,
+ large objects,
+ schemas,
+ tablespaces,
+ or configuration parameters.
+ For other types of objects, the default privileges
+ granted to <code class="literal">PUBLIC</code> are as follows:
+ <code class="literal">CONNECT</code> and <code class="literal">TEMPORARY</code> (create
+ temporary tables) privileges for databases;
+ <code class="literal">EXECUTE</code> privilege for functions and procedures; and
+ <code class="literal">USAGE</code> privilege for languages and data types
+ (including domains).
+ The object owner can, of course, <code class="command">REVOKE</code>
+ both default and expressly granted privileges. (For maximum
+ security, issue the <code class="command">REVOKE</code> in the same transaction that
+ creates the object; then there is no window in which another user
+ can use the object.)
+ Also, these default privilege settings can be overridden using the
+ <a class="xref" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES"><span class="refentrytitle">ALTER DEFAULT PRIVILEGES</span></a> command.
+ </p><p>
+ <a class="xref" href="ddl-priv.html#PRIVILEGE-ABBREVS-TABLE" title="Table 5.1. ACL Privilege Abbreviations">Table 5.1</a> shows the one-letter
+ abbreviations that are used for these privilege types in
+ <em class="firstterm">ACL</em> (Access Control List) values.
+ You will see these letters in the output of the <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>
+ commands listed below, or when looking at ACL columns of system catalogs.
+ </p><div class="table" id="PRIVILEGE-ABBREVS-TABLE"><p class="title"><strong>Table 5.1. ACL Privilege Abbreviations</strong></p><div class="table-contents"><table class="table" summary="ACL Privilege Abbreviations" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Privilege</th><th>Abbreviation</th><th>Applicable Object Types</th></tr></thead><tbody><tr><td><code class="literal">SELECT</code></td><td><code class="literal">r</code> (<span class="quote">“<span class="quote">read</span>”</span>)</td><td>
+ <code class="literal">LARGE OBJECT</code>,
+ <code class="literal">SEQUENCE</code>,
+ <code class="literal">TABLE</code> (and table-like objects),
+ table column
+ </td></tr><tr><td><code class="literal">INSERT</code></td><td><code class="literal">a</code> (<span class="quote">“<span class="quote">append</span>”</span>)</td><td><code class="literal">TABLE</code>, table column</td></tr><tr><td><code class="literal">UPDATE</code></td><td><code class="literal">w</code> (<span class="quote">“<span class="quote">write</span>”</span>)</td><td>
+ <code class="literal">LARGE OBJECT</code>,
+ <code class="literal">SEQUENCE</code>,
+ <code class="literal">TABLE</code>,
+ table column
+ </td></tr><tr><td><code class="literal">DELETE</code></td><td><code class="literal">d</code></td><td><code class="literal">TABLE</code></td></tr><tr><td><code class="literal">TRUNCATE</code></td><td><code class="literal">D</code></td><td><code class="literal">TABLE</code></td></tr><tr><td><code class="literal">REFERENCES</code></td><td><code class="literal">x</code></td><td><code class="literal">TABLE</code>, table column</td></tr><tr><td><code class="literal">TRIGGER</code></td><td><code class="literal">t</code></td><td><code class="literal">TABLE</code></td></tr><tr><td><code class="literal">CREATE</code></td><td><code class="literal">C</code></td><td>
+ <code class="literal">DATABASE</code>,
+ <code class="literal">SCHEMA</code>,
+ <code class="literal">TABLESPACE</code>
+ </td></tr><tr><td><code class="literal">CONNECT</code></td><td><code class="literal">c</code></td><td><code class="literal">DATABASE</code></td></tr><tr><td><code class="literal">TEMPORARY</code></td><td><code class="literal">T</code></td><td><code class="literal">DATABASE</code></td></tr><tr><td><code class="literal">EXECUTE</code></td><td><code class="literal">X</code></td><td><code class="literal">FUNCTION</code>, <code class="literal">PROCEDURE</code></td></tr><tr><td><code class="literal">USAGE</code></td><td><code class="literal">U</code></td><td>
+ <code class="literal">DOMAIN</code>,
+ <code class="literal">FOREIGN DATA WRAPPER</code>,
+ <code class="literal">FOREIGN SERVER</code>,
+ <code class="literal">LANGUAGE</code>,
+ <code class="literal">SCHEMA</code>,
+ <code class="literal">SEQUENCE</code>,
+ <code class="literal">TYPE</code>
+ </td></tr><tr><td><code class="literal">SET</code></td><td><code class="literal">s</code></td><td><code class="literal">PARAMETER</code></td></tr><tr><td><code class="literal">ALTER SYSTEM</code></td><td><code class="literal">A</code></td><td><code class="literal">PARAMETER</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="ddl-priv.html#PRIVILEGES-SUMMARY-TABLE" title="Table 5.2. Summary of Access Privileges">Table 5.2</a> summarizes the privileges
+ available for each type of SQL object, using the abbreviations shown
+ above.
+ It also shows the <span class="application">psql</span> command
+ that can be used to examine privilege settings for each object type.
+ </p><div class="table" id="PRIVILEGES-SUMMARY-TABLE"><p class="title"><strong>Table 5.2. Summary of Access Privileges</strong></p><div class="table-contents"><table class="table" summary="Summary of Access Privileges" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Object Type</th><th>All Privileges</th><th>Default <code class="literal">PUBLIC</code> Privileges</th><th><span class="application">psql</span> Command</th></tr></thead><tbody><tr><td><code class="literal">DATABASE</code></td><td><code class="literal">CTc</code></td><td><code class="literal">Tc</code></td><td><code class="literal">\l</code></td></tr><tr><td><code class="literal">DOMAIN</code></td><td><code class="literal">U</code></td><td><code class="literal">U</code></td><td><code class="literal">\dD+</code></td></tr><tr><td><code class="literal">FUNCTION</code> or <code class="literal">PROCEDURE</code></td><td><code class="literal">X</code></td><td><code class="literal">X</code></td><td><code class="literal">\df+</code></td></tr><tr><td><code class="literal">FOREIGN DATA WRAPPER</code></td><td><code class="literal">U</code></td><td>none</td><td><code class="literal">\dew+</code></td></tr><tr><td><code class="literal">FOREIGN SERVER</code></td><td><code class="literal">U</code></td><td>none</td><td><code class="literal">\des+</code></td></tr><tr><td><code class="literal">LANGUAGE</code></td><td><code class="literal">U</code></td><td><code class="literal">U</code></td><td><code class="literal">\dL+</code></td></tr><tr><td><code class="literal">LARGE OBJECT</code></td><td><code class="literal">rw</code></td><td>none</td><td><code class="literal">\dl+</code></td></tr><tr><td><code class="literal">PARAMETER</code></td><td><code class="literal">sA</code></td><td>none</td><td><code class="literal">\dconfig+</code></td></tr><tr><td><code class="literal">SCHEMA</code></td><td><code class="literal">UC</code></td><td>none</td><td><code class="literal">\dn+</code></td></tr><tr><td><code class="literal">SEQUENCE</code></td><td><code class="literal">rwU</code></td><td>none</td><td><code class="literal">\dp</code></td></tr><tr><td><code class="literal">TABLE</code> (and table-like objects)</td><td><code class="literal">arwdDxt</code></td><td>none</td><td><code class="literal">\dp</code></td></tr><tr><td>Table column</td><td><code class="literal">arwx</code></td><td>none</td><td><code class="literal">\dp</code></td></tr><tr><td><code class="literal">TABLESPACE</code></td><td><code class="literal">C</code></td><td>none</td><td><code class="literal">\db+</code></td></tr><tr><td><code class="literal">TYPE</code></td><td><code class="literal">U</code></td><td><code class="literal">U</code></td><td><code class="literal">\dT+</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a id="id-1.5.4.9.23.1" class="indexterm"></a>
+ The privileges that have been granted for a particular object are
+ displayed as a list of <code class="type">aclitem</code> entries, where each
+ <code class="type">aclitem</code> describes the permissions of one grantee that
+ have been granted by a particular grantor. For example,
+ <code class="literal">calvin=r*w/hobbes</code> specifies that the role
+ <code class="literal">calvin</code> has the privilege
+ <code class="literal">SELECT</code> (<code class="literal">r</code>) with grant option
+ (<code class="literal">*</code>) as well as the non-grantable
+ privilege <code class="literal">UPDATE</code> (<code class="literal">w</code>), both granted
+ by the role <code class="literal">hobbes</code>. If <code class="literal">calvin</code>
+ also has some privileges on the same object granted by a different
+ grantor, those would appear as a separate <code class="type">aclitem</code> entry.
+ An empty grantee field in an <code class="type">aclitem</code> stands
+ for <code class="literal">PUBLIC</code>.
+ </p><p>
+ As an example, suppose that user <code class="literal">miriam</code> creates
+ table <code class="literal">mytable</code> and does:
+</p><pre class="programlisting">
+GRANT SELECT ON mytable TO PUBLIC;
+GRANT SELECT, UPDATE, INSERT ON mytable TO admin;
+GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw;
+</pre><p>
+ Then <span class="application">psql</span>'s <code class="literal">\dp</code> command
+ would show:
+</p><pre class="programlisting">
+=&gt; \dp mytable
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+--------+---------+-------+-----------------------+-----------------------+----------
+ public | mytable | table | miriam=arwdDxt/miriam+| col1: +|
+ | | | =r/miriam +| miriam_rw=rw/miriam |
+ | | | admin=arw/miriam | |
+(1 row)
+</pre><p>
+ </p><p>
+ If the <span class="quote">“<span class="quote">Access privileges</span>”</span> column is empty for a given
+ object, it means the object has default privileges (that is, its
+ privileges entry in the relevant system catalog is null). Default
+ privileges always include all privileges for the owner, and can include
+ some privileges for <code class="literal">PUBLIC</code> depending on the object
+ type, as explained above. The first <code class="command">GRANT</code>
+ or <code class="command">REVOKE</code> on an object will instantiate the default
+ privileges (producing, for
+ example, <code class="literal">miriam=arwdDxt/miriam</code>) and then modify them
+ per the specified request. Similarly, entries are shown in <span class="quote">“<span class="quote">Column
+ privileges</span>”</span> only for columns with nondefault privileges.
+ (Note: for this purpose, <span class="quote">“<span class="quote">default privileges</span>”</span> always means
+ the built-in default privileges for the object's type. An object whose
+ privileges have been affected by an <code class="command">ALTER DEFAULT
+ PRIVILEGES</code> command will always be shown with an explicit
+ privilege entry that includes the effects of
+ the <code class="command">ALTER</code>.)
+ </p><p>
+ Notice that the owner's implicit grant options are not marked in the
+ access privileges display. A <code class="literal">*</code> will appear only when
+ grant options have been explicitly granted to someone.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-alter.html" title="5.6. Modifying Tables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.6. Modifying Tables </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.8. Row Security Policies</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-rowsecurity.html b/doc/src/sgml/html/ddl-rowsecurity.html
new file mode 100644
index 0000000..edddf17
--- /dev/null
+++ b/doc/src/sgml/html/ddl-rowsecurity.html
@@ -0,0 +1,382 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.8. Row Security Policies</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-priv.html" title="5.7. Privileges" /><link rel="next" href="ddl-schemas.html" title="5.9. Schemas" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.8. Row Security Policies</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-priv.html" title="5.7. Privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-schemas.html" title="5.9. Schemas">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-ROWSECURITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.8. Row Security Policies</h2></div></div></div><a id="id-1.5.4.10.2" class="indexterm"></a><a id="id-1.5.4.10.3" class="indexterm"></a><p>
+ In addition to the SQL-standard <a class="link" href="ddl-priv.html" title="5.7. Privileges">privilege
+ system</a> available through <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>,
+ tables can have <em class="firstterm">row security policies</em> that restrict,
+ on a per-user basis, which rows can be returned by normal queries
+ or inserted, updated, or deleted by data modification commands.
+ This feature is also known as <em class="firstterm">Row-Level Security</em>.
+ By default, tables do not have any policies, so that if a user has
+ access privileges to a table according to the SQL privilege system,
+ all rows within it are equally available for querying or updating.
+ </p><p>
+ When row security is enabled on a table (with
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE">ALTER TABLE ... ENABLE ROW LEVEL
+ SECURITY</a>), all normal access to the table for selecting rows or
+ modifying rows must be allowed by a row security policy. (However, the
+ table's owner is typically not subject to row security policies.) If no
+ policy exists for the table, a default-deny policy is used, meaning that
+ no rows are visible or can be modified. Operations that apply to the
+ whole table, such as <code class="command">TRUNCATE</code> and <code class="literal">REFERENCES</code>,
+ are not subject to row security.
+ </p><p>
+ Row security policies can be specific to commands, or to roles, or to
+ both. A policy can be specified to apply to <code class="literal">ALL</code>
+ commands, or to <code class="literal">SELECT</code>, <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ or <code class="literal">DELETE</code>. Multiple roles can be assigned to a given
+ policy, and normal role membership and inheritance rules apply.
+ </p><p>
+ To specify which rows are visible or modifiable according to a policy,
+ an expression is required that returns a Boolean result. This
+ expression will be evaluated for each row prior to any conditions or
+ functions coming from the user's query. (The only exceptions to this
+ rule are <code class="literal">leakproof</code> functions, which are guaranteed to
+ not leak information; the optimizer may choose to apply such functions
+ ahead of the row-security check.) Rows for which the expression does
+ not return <code class="literal">true</code> will not be processed. Separate expressions
+ may be specified to provide independent control over the rows which are
+ visible and the rows which are allowed to be modified. Policy
+ expressions are run as part of the query and with the privileges of the
+ user running the query, although security-definer functions can be used
+ to access data not available to the calling user.
+ </p><p>
+ Superusers and roles with the <code class="literal">BYPASSRLS</code> attribute always
+ bypass the row security system when accessing a table. Table owners
+ normally bypass row security as well, though a table owner can choose to
+ be subject to row security with <a class="link" href="sql-altertable.html" title="ALTER TABLE">ALTER
+ TABLE ... FORCE ROW LEVEL SECURITY</a>.
+ </p><p>
+ Enabling and disabling row security, as well as adding policies to a
+ table, is always the privilege of the table owner only.
+ </p><p>
+ Policies are created using the <a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a>
+ command, altered using the <a class="xref" href="sql-alterpolicy.html" title="ALTER POLICY"><span class="refentrytitle">ALTER POLICY</span></a> command,
+ and dropped using the <a class="xref" href="sql-droppolicy.html" title="DROP POLICY"><span class="refentrytitle">DROP POLICY</span></a> command. To
+ enable and disable row security for a given table, use the
+ <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a> command.
+ </p><p>
+ Each policy has a name and multiple policies can be defined for a
+ table. As policies are table-specific, each policy for a table must
+ have a unique name. Different tables may have policies with the
+ same name.
+ </p><p>
+ When multiple policies apply to a given query, they are combined using
+ either <code class="literal">OR</code> (for permissive policies, which are the
+ default) or using <code class="literal">AND</code> (for restrictive policies).
+ This is similar to the rule that a given role has the privileges
+ of all roles that they are a member of. Permissive vs. restrictive
+ policies are discussed further below.
+ </p><p>
+ As a simple example, here is how to create a policy on
+ the <code class="literal">account</code> relation to allow only members of
+ the <code class="literal">managers</code> role to access rows, and only rows of their
+ accounts:
+ </p><pre class="programlisting">
+CREATE TABLE accounts (manager text, company text, contact_email text);
+
+ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;
+
+CREATE POLICY account_managers ON accounts TO managers
+ USING (manager = current_user);
+</pre><p>
+ The policy above implicitly provides a <code class="literal">WITH CHECK</code>
+ clause identical to its <code class="literal">USING</code> clause, so that the
+ constraint applies both to rows selected by a command (so a manager
+ cannot <code class="command">SELECT</code>, <code class="command">UPDATE</code>,
+ or <code class="command">DELETE</code> existing rows belonging to a different
+ manager) and to rows modified by a command (so rows belonging to a
+ different manager cannot be created via <code class="command">INSERT</code>
+ or <code class="command">UPDATE</code>).
+ </p><p>
+ If no role is specified, or the special user name
+ <code class="literal">PUBLIC</code> is used, then the policy applies to all
+ users on the system. To allow all users to access only their own row in
+ a <code class="literal">users</code> table, a simple policy can be used:
+ </p><pre class="programlisting">
+CREATE POLICY user_policy ON users
+ USING (user_name = current_user);
+</pre><p>
+ This works similarly to the previous example.
+ </p><p>
+ To use a different policy for rows that are being added to the table
+ compared to those rows that are visible, multiple policies can be
+ combined. This pair of policies would allow all users to view all rows
+ in the <code class="literal">users</code> table, but only modify their own:
+ </p><pre class="programlisting">
+CREATE POLICY user_sel_policy ON users
+ FOR SELECT
+ USING (true);
+CREATE POLICY user_mod_policy ON users
+ USING (user_name = current_user);
+</pre><p>
+ In a <code class="command">SELECT</code> command, these two policies are combined
+ using <code class="literal">OR</code>, with the net effect being that all rows
+ can be selected. In other command types, only the second policy applies,
+ so that the effects are the same as before.
+ </p><p>
+ Row security can also be disabled with the <code class="command">ALTER TABLE</code>
+ command. Disabling row security does not remove any policies that are
+ defined on the table; they are simply ignored. Then all rows in the
+ table are visible and modifiable, subject to the standard SQL privileges
+ system.
+ </p><p>
+ Below is a larger example of how this feature can be used in production
+ environments. The table <code class="literal">passwd</code> emulates a Unix password
+ file:
+ </p><pre class="programlisting">
+-- Simple passwd-file based example
+CREATE TABLE passwd (
+ user_name text UNIQUE NOT NULL,
+ pwhash text,
+ uid int PRIMARY KEY,
+ gid int NOT NULL,
+ real_name text NOT NULL,
+ home_phone text,
+ extra_info text,
+ home_dir text NOT NULL,
+ shell text NOT NULL
+);
+
+CREATE ROLE admin; -- Administrator
+CREATE ROLE bob; -- Normal user
+CREATE ROLE alice; -- Normal user
+
+-- Populate the table
+INSERT INTO passwd VALUES
+ ('admin','xxx',0,0,'Admin','111-222-3333',null,'/root','/bin/dash');
+INSERT INTO passwd VALUES
+ ('bob','xxx',1,1,'Bob','123-456-7890',null,'/home/bob','/bin/zsh');
+INSERT INTO passwd VALUES
+ ('alice','xxx',2,1,'Alice','098-765-4321',null,'/home/alice','/bin/zsh');
+
+-- Be sure to enable row-level security on the table
+ALTER TABLE passwd ENABLE ROW LEVEL SECURITY;
+
+-- Create policies
+-- Administrator can see all rows and add any rows
+CREATE POLICY admin_all ON passwd TO admin USING (true) WITH CHECK (true);
+-- Normal users can view all rows
+CREATE POLICY all_view ON passwd FOR SELECT USING (true);
+-- Normal users can update their own records, but
+-- limit which shells a normal user is allowed to set
+CREATE POLICY user_mod ON passwd FOR UPDATE
+ USING (current_user = user_name)
+ WITH CHECK (
+ current_user = user_name AND
+ shell IN ('/bin/bash','/bin/sh','/bin/dash','/bin/zsh','/bin/tcsh')
+ );
+
+-- Allow admin all normal rights
+GRANT SELECT, INSERT, UPDATE, DELETE ON passwd TO admin;
+-- Users only get select access on public columns
+GRANT SELECT
+ (user_name, uid, gid, real_name, home_phone, extra_info, home_dir, shell)
+ ON passwd TO public;
+-- Allow users to update certain columns
+GRANT UPDATE
+ (pwhash, real_name, home_phone, extra_info, shell)
+ ON passwd TO public;
+</pre><p>
+ As with any security settings, it's important to test and ensure that
+ the system is behaving as expected. Using the example above, this
+ demonstrates that the permission system is working properly.
+ </p><pre class="programlisting">
+-- admin can view all rows and fields
+postgres=&gt; set role admin;
+SET
+postgres=&gt; table passwd;
+ user_name | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell
+-----------+--------+-----+-----+-----------+--------------+------------+-------------+-----------
+ admin | xxx | 0 | 0 | Admin | 111-222-3333 | | /root | /bin/dash
+ bob | xxx | 1 | 1 | Bob | 123-456-7890 | | /home/bob | /bin/zsh
+ alice | xxx | 2 | 1 | Alice | 098-765-4321 | | /home/alice | /bin/zsh
+(3 rows)
+
+-- Test what Alice is able to do
+postgres=&gt; set role alice;
+SET
+postgres=&gt; table passwd;
+ERROR: permission denied for table passwd
+postgres=&gt; select user_name,real_name,home_phone,extra_info,home_dir,shell from passwd;
+ user_name | real_name | home_phone | extra_info | home_dir | shell
+-----------+-----------+--------------+------------+-------------+-----------
+ admin | Admin | 111-222-3333 | | /root | /bin/dash
+ bob | Bob | 123-456-7890 | | /home/bob | /bin/zsh
+ alice | Alice | 098-765-4321 | | /home/alice | /bin/zsh
+(3 rows)
+
+postgres=&gt; update passwd set user_name = 'joe';
+ERROR: permission denied for table passwd
+-- Alice is allowed to change her own real_name, but no others
+postgres=&gt; update passwd set real_name = 'Alice Doe';
+UPDATE 1
+postgres=&gt; update passwd set real_name = 'John Doe' where user_name = 'admin';
+UPDATE 0
+postgres=&gt; update passwd set shell = '/bin/xx';
+ERROR: new row violates WITH CHECK OPTION for "passwd"
+postgres=&gt; delete from passwd;
+ERROR: permission denied for table passwd
+postgres=&gt; insert into passwd (user_name) values ('xxx');
+ERROR: permission denied for table passwd
+-- Alice can change her own password; RLS silently prevents updating other rows
+postgres=&gt; update passwd set pwhash = 'abc';
+UPDATE 1
+</pre><p>
+ All of the policies constructed thus far have been permissive policies,
+ meaning that when multiple policies are applied they are combined using
+ the <span class="quote">“<span class="quote">OR</span>”</span> Boolean operator. While permissive policies can be constructed
+ to only allow access to rows in the intended cases, it can be simpler to
+ combine permissive policies with restrictive policies (which the records
+ must pass and which are combined using the <span class="quote">“<span class="quote">AND</span>”</span> Boolean operator).
+ Building on the example above, we add a restrictive policy to require
+ the administrator to be connected over a local Unix socket to access the
+ records of the <code class="literal">passwd</code> table:
+ </p><pre class="programlisting">
+CREATE POLICY admin_local_only ON passwd AS RESTRICTIVE TO admin
+ USING (pg_catalog.inet_client_addr() IS NULL);
+</pre><p>
+ We can then see that an administrator connecting over a network will not
+ see any records, due to the restrictive policy:
+ </p><pre class="programlisting">
+=&gt; SELECT current_user;
+ current_user
+--------------
+ admin
+(1 row)
+
+=&gt; select inet_client_addr();
+ inet_client_addr
+------------------
+ 127.0.0.1
+(1 row)
+
+=&gt; TABLE passwd;
+ user_name | pwhash | uid | gid | real_name | home_phone | extra_info | home_dir | shell
+-----------+--------+-----+-----+-----------+------------+------------+----------+-------
+(0 rows)
+
+=&gt; UPDATE passwd set pwhash = NULL;
+UPDATE 0
+</pre><p>
+ Referential integrity checks, such as unique or primary key constraints
+ and foreign key references, always bypass row security to ensure that
+ data integrity is maintained. Care must be taken when developing
+ schemas and row level policies to avoid <span class="quote">“<span class="quote">covert channel</span>”</span> leaks of
+ information through such referential integrity checks.
+ </p><p>
+ In some contexts it is important to be sure that row security is
+ not being applied. For example, when taking a backup, it could be
+ disastrous if row security silently caused some rows to be omitted
+ from the backup. In such a situation, you can set the
+ <a class="xref" href="runtime-config-client.html#GUC-ROW-SECURITY">row_security</a> configuration parameter
+ to <code class="literal">off</code>. This does not in itself bypass row security;
+ what it does is throw an error if any query's results would get filtered
+ by a policy. The reason for the error can then be investigated and
+ fixed.
+ </p><p>
+ In the examples above, the policy expressions consider only the current
+ values in the row to be accessed or updated. This is the simplest and
+ best-performing case; when possible, it's best to design row security
+ applications to work this way. If it is necessary to consult other rows
+ or other tables to make a policy decision, that can be accomplished using
+ sub-<code class="command">SELECT</code>s, or functions that contain <code class="command">SELECT</code>s,
+ in the policy expressions. Be aware however that such accesses can
+ create race conditions that could allow information leakage if care is
+ not taken. As an example, consider the following table design:
+ </p><pre class="programlisting">
+-- definition of privilege groups
+CREATE TABLE groups (group_id int PRIMARY KEY,
+ group_name text NOT NULL);
+
+INSERT INTO groups VALUES
+ (1, 'low'),
+ (2, 'medium'),
+ (5, 'high');
+
+GRANT ALL ON groups TO alice; -- alice is the administrator
+GRANT SELECT ON groups TO public;
+
+-- definition of users' privilege levels
+CREATE TABLE users (user_name text PRIMARY KEY,
+ group_id int NOT NULL REFERENCES groups);
+
+INSERT INTO users VALUES
+ ('alice', 5),
+ ('bob', 2),
+ ('mallory', 2);
+
+GRANT ALL ON users TO alice;
+GRANT SELECT ON users TO public;
+
+-- table holding the information to be protected
+CREATE TABLE information (info text,
+ group_id int NOT NULL REFERENCES groups);
+
+INSERT INTO information VALUES
+ ('barely secret', 1),
+ ('slightly secret', 2),
+ ('very secret', 5);
+
+ALTER TABLE information ENABLE ROW LEVEL SECURITY;
+
+-- a row should be visible to/updatable by users whose security group_id is
+-- greater than or equal to the row's group_id
+CREATE POLICY fp_s ON information FOR SELECT
+ USING (group_id &lt;= (SELECT group_id FROM users WHERE user_name = current_user));
+CREATE POLICY fp_u ON information FOR UPDATE
+ USING (group_id &lt;= (SELECT group_id FROM users WHERE user_name = current_user));
+
+-- we rely only on RLS to protect the information table
+GRANT ALL ON information TO public;
+</pre><p>
+ Now suppose that <code class="literal">alice</code> wishes to change the <span class="quote">“<span class="quote">slightly
+ secret</span>”</span> information, but decides that <code class="literal">mallory</code> should not
+ be trusted with the new content of that row, so she does:
+ </p><pre class="programlisting">
+BEGIN;
+UPDATE users SET group_id = 1 WHERE user_name = 'mallory';
+UPDATE information SET info = 'secret from mallory' WHERE group_id = 2;
+COMMIT;
+</pre><p>
+ That looks safe; there is no window wherein <code class="literal">mallory</code> should be
+ able to see the <span class="quote">“<span class="quote">secret from mallory</span>”</span> string. However, there is
+ a race condition here. If <code class="literal">mallory</code> is concurrently doing,
+ say,
+</p><pre class="programlisting">
+SELECT * FROM information WHERE group_id = 2 FOR UPDATE;
+</pre><p>
+ and her transaction is in <code class="literal">READ COMMITTED</code> mode, it is possible
+ for her to see <span class="quote">“<span class="quote">secret from mallory</span>”</span>. That happens if her
+ transaction reaches the <code class="structname">information</code> row just
+ after <code class="literal">alice</code>'s does. It blocks waiting
+ for <code class="literal">alice</code>'s transaction to commit, then fetches the updated
+ row contents thanks to the <code class="literal">FOR UPDATE</code> clause. However, it
+ does <span class="emphasis"><em>not</em></span> fetch an updated row for the
+ implicit <code class="command">SELECT</code> from <code class="structname">users</code>, because that
+ sub-<code class="command">SELECT</code> did not have <code class="literal">FOR UPDATE</code>; instead
+ the <code class="structname">users</code> row is read with the snapshot taken at the start
+ of the query. Therefore, the policy expression tests the old value
+ of <code class="literal">mallory</code>'s privilege level and allows her to see the
+ updated row.
+ </p><p>
+ There are several ways around this problem. One simple answer is to use
+ <code class="literal">SELECT ... FOR SHARE</code> in sub-<code class="command">SELECT</code>s in row
+ security policies. However, that requires granting <code class="literal">UPDATE</code>
+ privilege on the referenced table (here <code class="structname">users</code>) to the
+ affected users, which might be undesirable. (But another row security
+ policy could be applied to prevent them from actually exercising that
+ privilege; or the sub-<code class="command">SELECT</code> could be embedded into a security
+ definer function.) Also, heavy concurrent use of row share locks on the
+ referenced table could pose a performance problem, especially if updates
+ of it are frequent. Another solution, practical if updates of the
+ referenced table are infrequent, is to take an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the
+ referenced table when updating it, so that no concurrent transactions
+ could be examining old row values. Or one could just wait for all
+ concurrent transactions to end after committing an update of the
+ referenced table and before making changes that rely on the new security
+ situation.
+ </p><p>
+ For additional details see <a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a>
+ and <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-priv.html" title="5.7. Privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-schemas.html" title="5.9. Schemas">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.7. Privileges </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.9. Schemas</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-schemas.html b/doc/src/sgml/html/ddl-schemas.html
new file mode 100644
index 0000000..4ba6dc6
--- /dev/null
+++ b/doc/src/sgml/html/ddl-schemas.html
@@ -0,0 +1,329 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.9. Schemas</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-rowsecurity.html" title="5.8. Row Security Policies" /><link rel="next" href="ddl-inherit.html" title="5.10. Inheritance" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.9. Schemas</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-inherit.html" title="5.10. Inheritance">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-SCHEMAS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.9. Schemas</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-CREATE">5.9.1. Creating a Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PUBLIC">5.9.2. The Public Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PATH">5.9.3. The Schema Search Path</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PRIV">5.9.4. Schemas and Privileges</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-CATALOG">5.9.5. The System Catalog Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS">5.9.6. Usage Patterns</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PORTABILITY">5.9.7. Portability</a></span></dt></dl></div><a id="id-1.5.4.11.2" class="indexterm"></a><p>
+ A <span class="productname">PostgreSQL</span> database cluster contains
+ one or more named databases. Roles and a few other object types are
+ shared across the entire cluster. A client connection to the server
+ can only access data in a single database, the one specified in the
+ connection request.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Users of a cluster do not necessarily have the privilege to access every
+ database in the cluster. Sharing of role names means that there
+ cannot be different roles named, say, <code class="literal">joe</code> in two databases
+ in the same cluster; but the system can be configured to allow
+ <code class="literal">joe</code> access to only some of the databases.
+ </p></div><p>
+ A database contains one or more named <em class="firstterm">schemas</em>, which
+ in turn contain tables. Schemas also contain other kinds of named
+ objects, including data types, functions, and operators. The same
+ object name can be used in different schemas without conflict; for
+ example, both <code class="literal">schema1</code> and <code class="literal">myschema</code> can
+ contain tables named <code class="literal">mytable</code>. Unlike databases,
+ schemas are not rigidly separated: a user can access objects in any
+ of the schemas in the database they are connected to, if they have
+ privileges to do so.
+ </p><p>
+ There are several reasons why one might want to use schemas:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ To allow many users to use one database without interfering with
+ each other.
+ </p></li><li class="listitem"><p>
+ To organize database objects into logical groups to make them
+ more manageable.
+ </p></li><li class="listitem"><p>
+ Third-party applications can be put into separate schemas so
+ they do not collide with the names of other objects.
+ </p></li></ul></div><p>
+
+ Schemas are analogous to directories at the operating system level,
+ except that schemas cannot be nested.
+ </p><div class="sect2" id="DDL-SCHEMAS-CREATE"><div class="titlepage"><div><div><h3 class="title">5.9.1. Creating a Schema</h3></div></div></div><a id="id-1.5.4.11.7.2" class="indexterm"></a><p>
+ To create a schema, use the <a class="xref" href="sql-createschema.html" title="CREATE SCHEMA"><span class="refentrytitle">CREATE SCHEMA</span></a>
+ command. Give the schema a name
+ of your choice. For example:
+</p><pre class="programlisting">
+CREATE SCHEMA myschema;
+</pre><p>
+ </p><a id="id-1.5.4.11.7.4" class="indexterm"></a><a id="id-1.5.4.11.7.5" class="indexterm"></a><p>
+ To create or access objects in a schema, write a
+ <em class="firstterm">qualified name</em> consisting of the schema name and
+ table name separated by a dot:
+</p><pre class="synopsis">
+<em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>table</code></em>
+</pre><p>
+ This works anywhere a table name is expected, including the table
+ modification commands and the data access commands discussed in
+ the following chapters.
+ (For brevity we will speak of tables only, but the same ideas apply
+ to other kinds of named objects, such as types and functions.)
+ </p><p>
+ Actually, the even more general syntax
+</p><pre class="synopsis">
+<em class="replaceable"><code>database</code></em><code class="literal">.</code><em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>table</code></em>
+</pre><p>
+ can be used too, but at present this is just for pro forma
+ compliance with the SQL standard. If you write a database name,
+ it must be the same as the database you are connected to.
+ </p><p>
+ So to create a table in the new schema, use:
+</p><pre class="programlisting">
+CREATE TABLE myschema.mytable (
+ ...
+);
+</pre><p>
+ </p><a id="id-1.5.4.11.7.9" class="indexterm"></a><p>
+ To drop a schema if it's empty (all objects in it have been
+ dropped), use:
+</p><pre class="programlisting">
+DROP SCHEMA myschema;
+</pre><p>
+ To drop a schema including all contained objects, use:
+</p><pre class="programlisting">
+DROP SCHEMA myschema CASCADE;
+</pre><p>
+ See <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a> for a description of the general
+ mechanism behind this.
+ </p><p>
+ Often you will want to create a schema owned by someone else
+ (since this is one of the ways to restrict the activities of your
+ users to well-defined namespaces). The syntax for that is:
+</p><pre class="programlisting">
+CREATE SCHEMA <em class="replaceable"><code>schema_name</code></em> AUTHORIZATION <em class="replaceable"><code>user_name</code></em>;
+</pre><p>
+ You can even omit the schema name, in which case the schema name
+ will be the same as the user name. See <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">Section 5.9.6</a> for how this can be useful.
+ </p><p>
+ Schema names beginning with <code class="literal">pg_</code> are reserved for
+ system purposes and cannot be created by users.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PUBLIC"><div class="titlepage"><div><div><h3 class="title">5.9.2. The Public Schema</h3></div></div></div><a id="id-1.5.4.11.8.2" class="indexterm"></a><p>
+ In the previous sections we created tables without specifying any
+ schema names. By default such tables (and other objects) are
+ automatically put into a schema named <span class="quote">“<span class="quote">public</span>”</span>. Every new
+ database contains such a schema. Thus, the following are equivalent:
+</p><pre class="programlisting">
+CREATE TABLE products ( ... );
+</pre><p>
+ and:
+</p><pre class="programlisting">
+CREATE TABLE public.products ( ... );
+</pre><p>
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PATH"><div class="titlepage"><div><div><h3 class="title">5.9.3. The Schema Search Path</h3></div></div></div><a id="id-1.5.4.11.9.2" class="indexterm"></a><a id="id-1.5.4.11.9.3" class="indexterm"></a><a id="id-1.5.4.11.9.4" class="indexterm"></a><p>
+ Qualified names are tedious to write, and it's often best not to
+ wire a particular schema name into applications anyway. Therefore
+ tables are often referred to by <em class="firstterm">unqualified names</em>,
+ which consist of just the table name. The system determines which table
+ is meant by following a <em class="firstterm">search path</em>, which is a list
+ of schemas to look in. The first matching table in the search path
+ is taken to be the one wanted. If there is no match in the search
+ path, an error is reported, even if matching table names exist
+ in other schemas in the database.
+ </p><p>
+ The ability to create like-named objects in different schemas complicates
+ writing a query that references precisely the same objects every time. It
+ also opens up the potential for users to change the behavior of other
+ users' queries, maliciously or accidentally. Due to the prevalence of
+ unqualified names in queries and their use
+ in <span class="productname">PostgreSQL</span> internals, adding a schema
+ to <code class="varname">search_path</code> effectively trusts all users having
+ <code class="literal">CREATE</code> privilege on that schema. When you run an
+ ordinary query, a malicious user able to create objects in a schema of
+ your search path can take control and execute arbitrary SQL functions as
+ though you executed them.
+ </p><a id="id-1.5.4.11.9.7" class="indexterm"></a><p>
+ The first schema named in the search path is called the current schema.
+ Aside from being the first schema searched, it is also the schema in
+ which new tables will be created if the <code class="command">CREATE TABLE</code>
+ command does not specify a schema name.
+ </p><a id="id-1.5.4.11.9.9" class="indexterm"></a><p>
+ To show the current search path, use the following command:
+</p><pre class="programlisting">
+SHOW search_path;
+</pre><p>
+ In the default setup this returns:
+</p><pre class="screen">
+ search_path
+--------------
+ "$user", public
+</pre><p>
+ The first element specifies that a schema with the same name as
+ the current user is to be searched. If no such schema exists,
+ the entry is ignored. The second element refers to the
+ public schema that we have seen already.
+ </p><p>
+ The first schema in the search path that exists is the default
+ location for creating new objects. That is the reason that by
+ default objects are created in the public schema. When objects
+ are referenced in any other context without schema qualification
+ (table modification, data modification, or query commands) the
+ search path is traversed until a matching object is found.
+ Therefore, in the default configuration, any unqualified access
+ again can only refer to the public schema.
+ </p><p>
+ To put our new schema in the path, we use:
+</p><pre class="programlisting">
+SET search_path TO myschema,public;
+</pre><p>
+ (We omit the <code class="literal">$user</code> here because we have no
+ immediate need for it.) And then we can access the table without
+ schema qualification:
+</p><pre class="programlisting">
+DROP TABLE mytable;
+</pre><p>
+ Also, since <code class="literal">myschema</code> is the first element in
+ the path, new objects would by default be created in it.
+ </p><p>
+ We could also have written:
+</p><pre class="programlisting">
+SET search_path TO myschema;
+</pre><p>
+ Then we no longer have access to the public schema without
+ explicit qualification. There is nothing special about the public
+ schema except that it exists by default. It can be dropped, too.
+ </p><p>
+ See also <a class="xref" href="functions-info.html" title="9.26. System Information Functions and Operators">Section 9.26</a> for other ways to manipulate
+ the schema search path.
+ </p><p>
+ The search path works in the same way for data type names, function names,
+ and operator names as it does for table names. Data type and function
+ names can be qualified in exactly the same way as table names. If you
+ need to write a qualified operator name in an expression, there is a
+ special provision: you must write
+</p><pre class="synopsis">
+<code class="literal">OPERATOR(</code><em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>operator</code></em><code class="literal">)</code>
+</pre><p>
+ This is needed to avoid syntactic ambiguity. An example is:
+</p><pre class="programlisting">
+SELECT 3 OPERATOR(pg_catalog.+) 4;
+</pre><p>
+ In practice one usually relies on the search path for operators,
+ so as not to have to write anything so ugly as that.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PRIV"><div class="titlepage"><div><div><h3 class="title">5.9.4. Schemas and Privileges</h3></div></div></div><a id="id-1.5.4.11.10.2" class="indexterm"></a><p>
+ By default, users cannot access any objects in schemas they do not
+ own. To allow that, the owner of the schema must grant the
+ <code class="literal">USAGE</code> privilege on the schema. By default, everyone
+ has that privilege on the schema <code class="literal">public</code>. To allow
+ users to make use of the objects in a schema, additional privileges might
+ need to be granted, as appropriate for the object.
+ </p><p>
+ A user can also be allowed to create objects in someone else's schema. To
+ allow that, the <code class="literal">CREATE</code> privilege on the schema needs to
+ be granted. In databases upgraded from
+ <span class="productname">PostgreSQL</span> 14 or earlier, everyone has that
+ privilege on the schema <code class="literal">public</code>.
+ Some <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">usage patterns</a> call for
+ revoking that privilege:
+</p><pre class="programlisting">
+REVOKE CREATE ON SCHEMA public FROM PUBLIC;
+</pre><p>
+ (The first <span class="quote">“<span class="quote">public</span>”</span> is the schema, the second
+ <span class="quote">“<span class="quote">public</span>”</span> means <span class="quote">“<span class="quote">every user</span>”</span>. In the
+ first sense it is an identifier, in the second sense it is a
+ key word, hence the different capitalization; recall the
+ guidelines from <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS" title="4.1.1. Identifiers and Key Words">Section 4.1.1</a>.)
+ </p></div><div class="sect2" id="DDL-SCHEMAS-CATALOG"><div class="titlepage"><div><div><h3 class="title">5.9.5. The System Catalog Schema</h3></div></div></div><a id="id-1.5.4.11.11.2" class="indexterm"></a><p>
+ In addition to <code class="literal">public</code> and user-created schemas, each
+ database contains a <code class="literal">pg_catalog</code> schema, which contains
+ the system tables and all the built-in data types, functions, and
+ operators. <code class="literal">pg_catalog</code> is always effectively part of
+ the search path. If it is not named explicitly in the path then
+ it is implicitly searched <span class="emphasis"><em>before</em></span> searching the path's
+ schemas. This ensures that built-in names will always be
+ findable. However, you can explicitly place
+ <code class="literal">pg_catalog</code> at the end of your search path if you
+ prefer to have user-defined names override built-in names.
+ </p><p>
+ Since system table names begin with <code class="literal">pg_</code>, it is best to
+ avoid such names to ensure that you won't suffer a conflict if some
+ future version defines a system table named the same as your
+ table. (With the default search path, an unqualified reference to
+ your table name would then be resolved as the system table instead.)
+ System tables will continue to follow the convention of having
+ names beginning with <code class="literal">pg_</code>, so that they will not
+ conflict with unqualified user-table names so long as users avoid
+ the <code class="literal">pg_</code> prefix.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PATTERNS"><div class="titlepage"><div><div><h3 class="title">5.9.6. Usage Patterns</h3></div></div></div><p>
+ Schemas can be used to organize your data in many ways.
+ A <em class="firstterm">secure schema usage pattern</em> prevents untrusted
+ users from changing the behavior of other users' queries. When a database
+ does not use a secure schema usage pattern, users wishing to securely
+ query that database would take protective action at the beginning of each
+ session. Specifically, they would begin each session by
+ setting <code class="varname">search_path</code> to the empty string or otherwise
+ removing schemas that are writable by non-superusers
+ from <code class="varname">search_path</code>. There are a few usage patterns
+ easily supported by the default configuration:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Constrain ordinary users to user-private schemas.
+ To implement this pattern, first ensure that no schemas have
+ public <code class="literal">CREATE</code> privileges. Then, for every user
+ needing to create non-temporary objects, create a schema with the
+ same name as that user, for example
+ <code class="literal">CREATE SCHEMA alice AUTHORIZATION alice</code>.
+ (Recall that the default search path starts
+ with <code class="literal">$user</code>, which resolves to the user
+ name. Therefore, if each user has a separate schema, they access
+ their own schemas by default.) This pattern is a secure schema
+ usage pattern unless an untrusted user is the database owner or
+ holds the <code class="literal">CREATEROLE</code> privilege, in which case no
+ secure schema usage pattern exists.
+ </p><p>
+ In <span class="productname">PostgreSQL</span> 15 and later, the default
+ configuration supports this usage pattern. In prior versions, or
+ when using a database that has been upgraded from a prior version,
+ you will need to remove the public <code class="literal">CREATE</code>
+ privilege from the <code class="literal">public</code> schema (issue
+ <code class="literal">REVOKE CREATE ON SCHEMA public FROM PUBLIC</code>).
+ Then consider auditing the <code class="literal">public</code> schema for
+ objects named like objects in schema <code class="literal">pg_catalog</code>.
+ </p></li><li class="listitem"><p>
+ Remove the public schema from the default search path, by modifying
+ <a class="link" href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE" title="20.1.2. Parameter Interaction via the Configuration File"><code class="filename">postgresql.conf</code></a>
+ or by issuing <code class="literal">ALTER ROLE ALL SET search_path =
+ "$user"</code>. Then, grant privileges to create in the public
+ schema. Only qualified names will choose public schema objects. While
+ qualified table references are fine, calls to functions in the public
+ schema <a class="link" href="typeconv-func.html" title="10.3. Functions">will be unsafe or
+ unreliable</a>. If you create functions or extensions in the public
+ schema, use the first pattern instead. Otherwise, like the first
+ pattern, this is secure unless an untrusted user is the database owner
+ or holds the <code class="literal">CREATEROLE</code> privilege.
+ </p></li><li class="listitem"><p>
+ Keep the default search path, and grant privileges to create in the
+ public schema. All users access the public schema implicitly. This
+ simulates the situation where schemas are not available at all, giving
+ a smooth transition from the non-schema-aware world. However, this is
+ never a secure pattern. It is acceptable only when the database has a
+ single user or a few mutually-trusting users. In databases upgraded
+ from <span class="productname">PostgreSQL</span> 14 or earlier, this is the
+ default.
+ </p></li></ul></div><p>
+ </p><p>
+ For any pattern, to install shared applications (tables to be used by
+ everyone, additional functions provided by third parties, etc.), put them
+ into separate schemas. Remember to grant appropriate privileges to allow
+ the other users to access them. Users can then refer to these additional
+ objects by qualifying the names with a schema name, or they can put the
+ additional schemas into their search path, as they choose.
+ </p></div><div class="sect2" id="DDL-SCHEMAS-PORTABILITY"><div class="titlepage"><div><div><h3 class="title">5.9.7. Portability</h3></div></div></div><p>
+ In the SQL standard, the notion of objects in the same schema
+ being owned by different users does not exist. Moreover, some
+ implementations do not allow you to create schemas that have a
+ different name than their owner. In fact, the concepts of schema
+ and user are nearly equivalent in a database system that
+ implements only the basic schema support specified in the
+ standard. Therefore, many users consider qualified names to
+ really consist of
+ <code class="literal"><em class="replaceable"><code>user_name</code></em>.<em class="replaceable"><code>table_name</code></em></code>.
+ This is how <span class="productname">PostgreSQL</span> will effectively
+ behave if you create a per-user schema for every user.
+ </p><p>
+ Also, there is no concept of a <code class="literal">public</code> schema in the
+ SQL standard. For maximum conformance to the standard, you should
+ not use the <code class="literal">public</code> schema.
+ </p><p>
+ Of course, some SQL database systems might not implement schemas
+ at all, or provide namespace support by allowing (possibly
+ limited) cross-database access. If you need to work with those
+ systems, then maximum portability would be achieved by not using
+ schemas at all.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-inherit.html" title="5.10. Inheritance">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.8. Row Security Policies </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.10. Inheritance</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl-system-columns.html b/doc/src/sgml/html/ddl-system-columns.html
new file mode 100644
index 0000000..67292b6
--- /dev/null
+++ b/doc/src/sgml/html/ddl-system-columns.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>5.5. System Columns</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-constraints.html" title="5.4. Constraints" /><link rel="next" href="ddl-alter.html" title="5.6. Modifying Tables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">5.5. System Columns</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-constraints.html" title="5.4. Constraints">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><th width="60%" align="center">Chapter 5. Data Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-alter.html" title="5.6. Modifying Tables">Next</a></td></tr></table><hr /></div><div class="sect1" id="DDL-SYSTEM-COLUMNS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">5.5. System Columns</h2></div></div></div><p>
+ Every table has several <em class="firstterm">system columns</em> that are
+ implicitly defined by the system. Therefore, these names cannot be
+ used as names of user-defined columns. (Note that these
+ restrictions are separate from whether the name is a key word or
+ not; quoting a name will not allow you to escape these
+ restrictions.) You do not really need to be concerned about these
+ columns; just know they exist.
+ </p><a id="id-1.5.4.7.3" class="indexterm"></a><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="structfield">tableoid</code></span></dt><dd><a id="id-1.5.4.7.4.1.2.1" class="indexterm"></a><p>
+ The OID of the table containing this row. This column is
+ particularly handy for queries that select from partitioned
+ tables (see <a class="xref" href="ddl-partitioning.html" title="5.11. Table Partitioning">Section 5.11</a>) or inheritance
+ hierarchies (see <a class="xref" href="ddl-inherit.html" title="5.10. Inheritance">Section 5.10</a>), since without it,
+ it's difficult to tell which individual table a row came from. The
+ <code class="structfield">tableoid</code> can be joined against the
+ <code class="structfield">oid</code> column of
+ <code class="structname">pg_class</code> to obtain the table name.
+ </p></dd><dt><span class="term"><code class="structfield">xmin</code></span></dt><dd><a id="id-1.5.4.7.4.2.2.1" class="indexterm"></a><p>
+ The identity (transaction ID) of the inserting transaction for
+ this row version. (A row version is an individual state of a
+ row; each update of a row creates a new row version for the same
+ logical row.)
+ </p></dd><dt><span class="term"><code class="structfield">cmin</code></span></dt><dd><a id="id-1.5.4.7.4.3.2.1" class="indexterm"></a><p>
+ The command identifier (starting at zero) within the inserting
+ transaction.
+ </p></dd><dt><span class="term"><code class="structfield">xmax</code></span></dt><dd><a id="id-1.5.4.7.4.4.2.1" class="indexterm"></a><p>
+ The identity (transaction ID) of the deleting transaction, or
+ zero for an undeleted row version. It is possible for this column to
+ be nonzero in a visible row version. That usually indicates that the
+ deleting transaction hasn't committed yet, or that an attempted
+ deletion was rolled back.
+ </p></dd><dt><span class="term"><code class="structfield">cmax</code></span></dt><dd><a id="id-1.5.4.7.4.5.2.1" class="indexterm"></a><p>
+ The command identifier within the deleting transaction, or zero.
+ </p></dd><dt><span class="term"><code class="structfield">ctid</code></span></dt><dd><a id="id-1.5.4.7.4.6.2.1" class="indexterm"></a><p>
+ The physical location of the row version within its table. Note that
+ although the <code class="structfield">ctid</code> can be used to
+ locate the row version very quickly, a row's
+ <code class="structfield">ctid</code> will change if it is
+ updated or moved by <code class="command">VACUUM FULL</code>. Therefore
+ <code class="structfield">ctid</code> is useless as a long-term row
+ identifier. A primary key should be used to identify logical rows.
+ </p></dd></dl></div><p>
+ Transaction identifiers are also 32-bit quantities. In a
+ long-lived database it is possible for transaction IDs to wrap
+ around. This is not a fatal problem given appropriate maintenance
+ procedures; see <a class="xref" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Chapter 25</a> for details. It is
+ unwise, however, to depend on the uniqueness of transaction IDs
+ over the long term (more than one billion transactions).
+ </p><p>
+ Command identifiers are also 32-bit quantities. This creates a hard limit
+ of 2<sup>32</sup> (4 billion) <acronym class="acronym">SQL</acronym> commands
+ within a single transaction. In practice this limit is not a
+ problem — note that the limit is on the number of
+ <acronym class="acronym">SQL</acronym> commands, not the number of rows processed.
+ Also, only commands that actually modify the database contents will
+ consume a command identifier.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-constraints.html" title="5.4. Constraints">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ddl.html" title="Chapter 5. Data Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-alter.html" title="5.6. Modifying Tables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.4. Constraints </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.6. Modifying Tables</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ddl.html b/doc/src/sgml/html/ddl.html
new file mode 100644
index 0000000..5a7ed05
--- /dev/null
+++ b/doc/src/sgml/html/ddl.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 5. Data Definition</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions" /><link rel="next" href="ddl-basics.html" title="5.1. Table Basics" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 5. Data Definition</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl-basics.html" title="5.1. Table Basics">Next</a></td></tr></table><hr /></div><div class="chapter" id="DDL"><div class="titlepage"><div><div><h2 class="title">Chapter 5. Data Definition</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="ddl-basics.html">5.1. Table Basics</a></span></dt><dt><span class="sect1"><a href="ddl-default.html">5.2. Default Values</a></span></dt><dt><span class="sect1"><a href="ddl-generated-columns.html">5.3. Generated Columns</a></span></dt><dt><span class="sect1"><a href="ddl-constraints.html">5.4. Constraints</a></span></dt><dd><dl><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS">5.4.1. Check Constraints</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#id-1.5.4.6.6">5.4.2. Not-Null Constraints</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS">5.4.3. Unique Constraints</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-PRIMARY-KEYS">5.4.4. Primary Keys</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-FK">5.4.5. Foreign Keys</a></span></dt><dt><span class="sect2"><a href="ddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION">5.4.6. Exclusion Constraints</a></span></dt></dl></dd><dt><span class="sect1"><a href="ddl-system-columns.html">5.5. System Columns</a></span></dt><dt><span class="sect1"><a href="ddl-alter.html">5.6. Modifying Tables</a></span></dt><dd><dl><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-ADDING-A-COLUMN">5.6.1. Adding a Column</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-REMOVING-A-COLUMN">5.6.2. Removing a Column</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-ADDING-A-CONSTRAINT">5.6.3. Adding a Constraint</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#DDL-ALTER-REMOVING-A-CONSTRAINT">5.6.4. Removing a Constraint</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.9">5.6.5. Changing a Column's Default Value</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.10">5.6.6. Changing a Column's Data Type</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.11">5.6.7. Renaming a Column</a></span></dt><dt><span class="sect2"><a href="ddl-alter.html#id-1.5.4.8.12">5.6.8. Renaming a Table</a></span></dt></dl></dd><dt><span class="sect1"><a href="ddl-priv.html">5.7. Privileges</a></span></dt><dt><span class="sect1"><a href="ddl-rowsecurity.html">5.8. Row Security Policies</a></span></dt><dt><span class="sect1"><a href="ddl-schemas.html">5.9. Schemas</a></span></dt><dd><dl><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-CREATE">5.9.1. Creating a Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PUBLIC">5.9.2. The Public Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PATH">5.9.3. The Schema Search Path</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PRIV">5.9.4. Schemas and Privileges</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-CATALOG">5.9.5. The System Catalog Schema</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS">5.9.6. Usage Patterns</a></span></dt><dt><span class="sect2"><a href="ddl-schemas.html#DDL-SCHEMAS-PORTABILITY">5.9.7. Portability</a></span></dt></dl></dd><dt><span class="sect1"><a href="ddl-inherit.html">5.10. Inheritance</a></span></dt><dd><dl><dt><span class="sect2"><a href="ddl-inherit.html#DDL-INHERIT-CAVEATS">5.10.1. Caveats</a></span></dt></dl></dd><dt><span class="sect1"><a href="ddl-partitioning.html">5.11. Table Partitioning</a></span></dt><dd><dl><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-OVERVIEW">5.11.1. Overview</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE">5.11.2. Declarative Partitioning</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-USING-INHERITANCE">5.11.3. Partitioning Using Inheritance</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITION-PRUNING">5.11.4. Partition Pruning</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-CONSTRAINT-EXCLUSION">5.11.5. Partitioning and Constraint Exclusion</a></span></dt><dt><span class="sect2"><a href="ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE-BEST-PRACTICES">5.11.6. Best Practices for Declarative Partitioning</a></span></dt></dl></dd><dt><span class="sect1"><a href="ddl-foreign-data.html">5.12. Foreign Data</a></span></dt><dt><span class="sect1"><a href="ddl-others.html">5.13. Other Database Objects</a></span></dt><dt><span class="sect1"><a href="ddl-depend.html">5.14. Dependency Tracking</a></span></dt></dl></div><p>
+ This chapter covers how one creates the database structures that
+ will hold one's data. In a relational database, the raw data is
+ stored in tables, so the majority of this chapter is devoted to
+ explaining how tables are created and modified and what features are
+ available to control what data is stored in the tables.
+ Subsequently, we discuss how tables can be organized into
+ schemas, and how privileges can be assigned to tables. Finally,
+ we will briefly look at other features that affect the data storage,
+ such as inheritance, table partitioning, views, functions, and
+ triggers.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl-basics.html" title="5.1. Table Basics">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.3. Calling Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5.1. Table Basics</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/default-roles.html b/doc/src/sgml/html/default-roles.html
new file mode 100644
index 0000000..392be11
--- /dev/null
+++ b/doc/src/sgml/html/default-roles.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>O.2. Default Roles Renamed to Predefined Roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="recovery-config.html" title="O.1. recovery.conf file merged into postgresql.conf" /><link rel="next" href="pgxlogdump.html" title="O.3. pg_xlogdump renamed to pg_waldump" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">O.2. Default Roles Renamed to Predefined Roles</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="recovery-config.html" title="O.1. recovery.conf file merged into postgresql.conf">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><th width="60%" align="center">Appendix O. Obsolete or Renamed Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgxlogdump.html" title="O.3. pg_xlogdump renamed to pg_waldump">Next</a></td></tr></table><hr /></div><div class="sect1" id="DEFAULT-ROLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">O.2. Default Roles Renamed to Predefined Roles</h2></div></div></div><a id="id-1.11.16.4.2" class="indexterm"></a><p>
+ PostgreSQL 13 and below used the term <span class="quote">“<span class="quote">Default Roles</span>”</span>. However, as these
+ roles are not able to actually be changed and are installed as part of the
+ system at initialization time, the more appropriate term to use is <span class="quote">“<span class="quote">Predefined Roles</span>”</span>.
+ See <a class="xref" href="predefined-roles.html" title="22.5. Predefined Roles">Section 22.5</a> for current documentation regarding
+ Predefined Roles, and <a class="link" href="release-prior.html" title="E.6. Prior Releases">the release notes for
+ PostgreSQL 14</a> for details on this change.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="recovery-config.html" title="O.1. recovery.conf file merged into postgresql.conf">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgxlogdump.html" title="O.3. pg_xlogdump renamed to pg_waldump">Next</a></td></tr><tr><td width="40%" align="left" valign="top">O.1. <code class="filename">recovery.conf</code> file merged into <code class="filename">postgresql.conf</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> O.3. <code class="command">pg_xlogdump</code> renamed to <code class="command">pg_waldump</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dict-int.html b/doc/src/sgml/html/dict-int.html
new file mode 100644
index 0000000..cc2ba91
--- /dev/null
+++ b/doc/src/sgml/html/dict-int.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.13. dict_int</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-dblink-build-sql-update.html" title="dblink_build_sql_update" /><link rel="next" href="dict-xsyn.html" title="F.14. dict_xsyn" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.13. dict_int</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-dblink-build-sql-update.html" title="dblink_build_sql_update">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dict-xsyn.html" title="F.14. dict_xsyn">Next</a></td></tr></table><hr /></div><div class="sect1" id="DICT-INT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.13. dict_int</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="dict-int.html#id-1.11.7.22.5">F.13.1. Configuration</a></span></dt><dt><span class="sect2"><a href="dict-int.html#id-1.11.7.22.6">F.13.2. Usage</a></span></dt></dl></div><a id="id-1.11.7.22.2" class="indexterm"></a><p>
+ <code class="filename">dict_int</code> is an example of an add-on dictionary template
+ for full-text search. The motivation for this example dictionary is to
+ control the indexing of integers (signed and unsigned), allowing such
+ numbers to be indexed while preventing excessive growth in the number of
+ unique words, which greatly affects the performance of searching.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.22.5"><div class="titlepage"><div><div><h3 class="title">F.13.1. Configuration</h3></div></div></div><p>
+ The dictionary accepts three options:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The <code class="literal">maxlen</code> parameter specifies the maximum number of
+ digits allowed in an integer word. The default value is 6.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">rejectlong</code> parameter specifies whether an overlength
+ integer should be truncated or ignored. If <code class="literal">rejectlong</code> is
+ <code class="literal">false</code> (the default), the dictionary returns the first
+ <code class="literal">maxlen</code> digits of the integer. If <code class="literal">rejectlong</code> is
+ <code class="literal">true</code>, the dictionary treats an overlength integer as a stop
+ word, so that it will not be indexed. Note that this also means that
+ such an integer cannot be searched for.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">absval</code> parameter specifies whether leading
+ <span class="quote">“<span class="quote"><code class="literal">+</code></span>”</span> or <span class="quote">“<span class="quote"><code class="literal">-</code></span>”</span>
+ signs should be removed from integer words. The default
+ is <code class="literal">false</code>. When <code class="literal">true</code>, the sign is
+ removed before <code class="literal">maxlen</code> is applied.
+ </p></li></ul></div></div><div class="sect2" id="id-1.11.7.22.6"><div class="titlepage"><div><div><h3 class="title">F.13.2. Usage</h3></div></div></div><p>
+ Installing the <code class="literal">dict_int</code> extension creates a text search
+ template <code class="literal">intdict_template</code> and a dictionary <code class="literal">intdict</code>
+ based on it, with the default parameters. You can alter the
+ parameters, for example
+
+</p><pre class="programlisting">
+mydb# ALTER TEXT SEARCH DICTIONARY intdict (MAXLEN = 4, REJECTLONG = true);
+ALTER TEXT SEARCH DICTIONARY
+</pre><p>
+
+ or create new dictionaries based on the template.
+ </p><p>
+ To test the dictionary, you can try
+
+</p><pre class="programlisting">
+mydb# select ts_lexize('intdict', '12345678');
+ ts_lexize
+-----------
+ {123456}
+</pre><p>
+
+ but real-world usage will involve including it in a text search
+ configuration as described in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ That might look like this:
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION english
+ ALTER MAPPING FOR int, uint WITH intdict;
+</pre><p>
+
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-dblink-build-sql-update.html" title="dblink_build_sql_update">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dict-xsyn.html" title="F.14. dict_xsyn">Next</a></td></tr><tr><td width="40%" align="left" valign="top">dblink_build_sql_update </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.14. dict_xsyn</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dict-xsyn.html b/doc/src/sgml/html/dict-xsyn.html
new file mode 100644
index 0000000..f84e7dd
--- /dev/null
+++ b/doc/src/sgml/html/dict-xsyn.html
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.14. dict_xsyn</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dict-int.html" title="F.13. dict_int" /><link rel="next" href="earthdistance.html" title="F.15. earthdistance" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.14. dict_xsyn</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dict-int.html" title="F.13. dict_int">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="earthdistance.html" title="F.15. earthdistance">Next</a></td></tr></table><hr /></div><div class="sect1" id="DICT-XSYN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.14. dict_xsyn</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="dict-xsyn.html#id-1.11.7.23.4">F.14.1. Configuration</a></span></dt><dt><span class="sect2"><a href="dict-xsyn.html#id-1.11.7.23.5">F.14.2. Usage</a></span></dt></dl></div><a id="id-1.11.7.23.2" class="indexterm"></a><p>
+ <code class="filename">dict_xsyn</code> (Extended Synonym Dictionary) is an example of an
+ add-on dictionary template for full-text search. This dictionary type
+ replaces words with groups of their synonyms, and so makes it possible to
+ search for a word using any of its synonyms.
+ </p><div class="sect2" id="id-1.11.7.23.4"><div class="titlepage"><div><div><h3 class="title">F.14.1. Configuration</h3></div></div></div><p>
+ A <code class="literal">dict_xsyn</code> dictionary accepts the following options:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">matchorig</code> controls whether the original word is accepted by
+ the dictionary. Default is <code class="literal">true</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">matchsynonyms</code> controls whether the synonyms are
+ accepted by the dictionary. Default is <code class="literal">false</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">keeporig</code> controls whether the original word is included in
+ the dictionary's output. Default is <code class="literal">true</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">keepsynonyms</code> controls whether the synonyms are included in
+ the dictionary's output. Default is <code class="literal">true</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">rules</code> is the base name of the file containing the list of
+ synonyms. This file must be stored in
+ <code class="filename">$SHAREDIR/tsearch_data/</code> (where <code class="literal">$SHAREDIR</code> means
+ the <span class="productname">PostgreSQL</span> installation's shared-data directory).
+ Its name must end in <code class="literal">.rules</code> (which is not to be included in
+ the <code class="literal">rules</code> parameter).
+ </p></li></ul></div><p>
+ The rules file has the following format:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Each line represents a group of synonyms for a single word, which is
+ given first on the line. Synonyms are separated by whitespace, thus:
+</p><pre class="programlisting">
+word syn1 syn2 syn3
+</pre><p>
+ </p></li><li class="listitem"><p>
+ The sharp (<code class="literal">#</code>) sign is a comment delimiter. It may appear at
+ any position in a line. The rest of the line will be skipped.
+ </p></li></ul></div><p>
+ Look at <code class="filename">xsyn_sample.rules</code>, which is installed in
+ <code class="filename">$SHAREDIR/tsearch_data/</code>, for an example.
+ </p></div><div class="sect2" id="id-1.11.7.23.5"><div class="titlepage"><div><div><h3 class="title">F.14.2. Usage</h3></div></div></div><p>
+ Installing the <code class="literal">dict_xsyn</code> extension creates a text search
+ template <code class="literal">xsyn_template</code> and a dictionary <code class="literal">xsyn</code>
+ based on it, with default parameters. You can alter the
+ parameters, for example
+
+</p><pre class="programlisting">
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=false);
+ALTER TEXT SEARCH DICTIONARY
+</pre><p>
+
+ or create new dictionaries based on the template.
+ </p><p>
+ To test the dictionary, you can try
+
+</p><pre class="programlisting">
+mydb=# SELECT ts_lexize('xsyn', 'word');
+ ts_lexize
+-----------------------
+ {syn1,syn2,syn3}
+
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=true);
+ALTER TEXT SEARCH DICTIONARY
+
+mydb=# SELECT ts_lexize('xsyn', 'word');
+ ts_lexize
+-----------------------
+ {word,syn1,syn2,syn3}
+
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=false, MATCHSYNONYMS=true);
+ALTER TEXT SEARCH DICTIONARY
+
+mydb=# SELECT ts_lexize('xsyn', 'syn1');
+ ts_lexize
+-----------------------
+ {syn1,syn2,syn3}
+
+mydb# ALTER TEXT SEARCH DICTIONARY xsyn (RULES='my_rules', KEEPORIG=true, MATCHORIG=false, KEEPSYNONYMS=false);
+ALTER TEXT SEARCH DICTIONARY
+
+mydb=# SELECT ts_lexize('xsyn', 'syn1');
+ ts_lexize
+-----------------------
+ {word}
+</pre><p>
+
+ Real-world usage will involve including it in a text search
+ configuration as described in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ That might look like this:
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION english
+ ALTER MAPPING FOR word, asciiword WITH xsyn, english_stem;
+</pre><p>
+
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dict-int.html" title="F.13. dict_int">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="earthdistance.html" title="F.15. earthdistance">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.13. dict_int </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.15. earthdistance</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/different-replication-solutions.html b/doc/src/sgml/html/different-replication-solutions.html
new file mode 100644
index 0000000..502a180
--- /dev/null
+++ b/doc/src/sgml/html/different-replication-solutions.html
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>27.1. Comparison of Different Solutions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication" /><link rel="next" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">27.1. Comparison of Different Solutions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><th width="60%" align="center">Chapter 27. High Availability, Load Balancing, and Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Next</a></td></tr></table><hr /></div><div class="sect1" id="DIFFERENT-REPLICATION-SOLUTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">27.1. Comparison of Different Solutions</h2></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">Shared Disk Failover</span></dt><dd><p>
+ Shared disk failover avoids synchronization overhead by having only one
+ copy of the database. It uses a single disk array that is shared by
+ multiple servers. If the main database server fails, the standby server
+ is able to mount and start the database as though it were recovering from
+ a database crash. This allows rapid failover with no data loss.
+ </p><p>
+ Shared hardware functionality is common in network storage devices.
+ Using a network file system is also possible, though care must be
+ taken that the file system has full <acronym class="acronym">POSIX</acronym> behavior (see <a class="xref" href="creating-cluster.html#CREATING-CLUSTER-NFS" title="19.2.2.1. NFS">Section 19.2.2.1</a>). One significant limitation of this
+ method is that if the shared disk array fails or becomes corrupt, the
+ primary and standby servers are both nonfunctional. Another issue is
+ that the standby server should never access the shared storage while
+ the primary server is running.
+ </p></dd><dt><span class="term">File System (Block Device) Replication</span></dt><dd><p>
+ A modified version of shared hardware functionality is file system
+ replication, where all changes to a file system are mirrored to a file
+ system residing on another computer. The only restriction is that
+ the mirroring must be done in a way that ensures the standby server
+ has a consistent copy of the file system — specifically, writes
+ to the standby must be done in the same order as those on the primary.
+ <span class="productname">DRBD</span> is a popular file system replication solution
+ for Linux.
+ </p></dd><dt><span class="term">Write-Ahead Log Shipping</span></dt><dd><p>
+ Warm and hot standby servers can be kept current by reading a
+ stream of write-ahead log (<acronym class="acronym">WAL</acronym>)
+ records. If the main server fails, the standby contains
+ almost all of the data of the main server, and can be quickly
+ made the new primary database server. This can be synchronous or
+ asynchronous and can only be done for the entire database server.
+ </p><p>
+ A standby server can be implemented using file-based log shipping
+ (<a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>) or streaming replication (see
+ <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>), or a combination of both. For
+ information on hot standby, see <a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a>.
+ </p></dd><dt><span class="term">Logical Replication</span></dt><dd><p>
+ Logical replication allows a database server to send a stream of data
+ modifications to another server. <span class="productname">PostgreSQL</span>
+ logical replication constructs a stream of logical data modifications
+ from the WAL. Logical replication allows replication of data changes on
+ a per-table basis. In addition, a server that is publishing its own
+ changes can also subscribe to changes from another server, allowing data
+ to flow in multiple directions. For more information on logical
+ replication, see <a class="xref" href="logical-replication.html" title="Chapter 31. Logical Replication">Chapter 31</a>. Through the
+ logical decoding interface (<a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>),
+ third-party extensions can also provide similar functionality.
+ </p></dd><dt><span class="term">Trigger-Based Primary-Standby Replication</span></dt><dd><p>
+ A trigger-based replication setup typically funnels data modification
+ queries to a designated primary server. Operating on a per-table basis,
+ the primary server sends data changes (typically) asynchronously to the
+ standby servers. Standby servers can answer queries while the primary is
+ running, and may allow some local data changes or write activity. This
+ form of replication is often used for offloading large analytical or data
+ warehouse queries.
+ </p><p>
+ <span class="productname">Slony-I</span> is an example of this type of
+ replication, with per-table granularity, and support for multiple standby
+ servers. Because it updates the standby server asynchronously (in
+ batches), there is possible data loss during fail over.
+ </p></dd><dt><span class="term">SQL-Based Replication Middleware</span></dt><dd><p>
+ With SQL-based replication middleware, a program intercepts
+ every SQL query and sends it to one or all servers. Each server
+ operates independently. Read-write queries must be sent to all servers,
+ so that every server receives any changes. But read-only queries can be
+ sent to just one server, allowing the read workload to be distributed
+ among them.
+ </p><p>
+ If queries are simply broadcast unmodified, functions like
+ <code class="function">random()</code>, <code class="function">CURRENT_TIMESTAMP</code>, and
+ sequences can have different values on different servers.
+ This is because each server operates independently, and because
+ SQL queries are broadcast rather than actual data changes. If
+ this is unacceptable, either the middleware or the application
+ must determine such values from a single source and then use those
+ values in write queries. Care must also be taken that all
+ transactions either commit or abort on all servers, perhaps
+ using two-phase commit (<a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a>
+ and <a class="xref" href="sql-commit-prepared.html" title="COMMIT PREPARED"><span class="refentrytitle">COMMIT PREPARED</span></a>).
+ <span class="productname">Pgpool-II</span> and <span class="productname">Continuent Tungsten</span>
+ are examples of this type of replication.
+ </p></dd><dt><span class="term">Asynchronous Multimaster Replication</span></dt><dd><p>
+ For servers that are not regularly connected or have slow
+ communication links, like laptops or
+ remote servers, keeping data consistent among servers is a
+ challenge. Using asynchronous multimaster replication, each
+ server works independently, and periodically communicates with
+ the other servers to identify conflicting transactions. The
+ conflicts can be resolved by users or conflict resolution rules.
+ Bucardo is an example of this type of replication.
+ </p></dd><dt><span class="term">Synchronous Multimaster Replication</span></dt><dd><p>
+ In synchronous multimaster replication, each server can accept
+ write requests, and modified data is transmitted from the
+ original server to every other server before each transaction
+ commits. Heavy write activity can cause excessive locking and
+ commit delays, leading to poor performance. Read requests can
+ be sent to any server. Some implementations use shared disk
+ to reduce the communication overhead. Synchronous multimaster
+ replication is best for mostly read workloads, though its big
+ advantage is that any server can accept write requests —
+ there is no need to partition workloads between primary and
+ standby servers, and because the data changes are sent from one
+ server to another, there is no problem with non-deterministic
+ functions like <code class="function">random()</code>.
+ </p><p>
+ <span class="productname">PostgreSQL</span> does not offer this type of replication,
+ though <span class="productname">PostgreSQL</span> two-phase commit (<a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a> and <a class="xref" href="sql-commit-prepared.html" title="COMMIT PREPARED"><span class="refentrytitle">COMMIT PREPARED</span></a>)
+ can be used to implement this in application code or middleware.
+ </p></dd></dl></div><p>
+ <a class="xref" href="different-replication-solutions.html#HIGH-AVAILABILITY-MATRIX" title="Table 27.1. High Availability, Load Balancing, and Replication Feature Matrix">Table 27.1</a> summarizes
+ the capabilities of the various solutions listed above.
+ </p><div class="table" id="HIGH-AVAILABILITY-MATRIX"><p class="title"><strong>Table 27.1. High Availability, Load Balancing, and Replication Feature Matrix</strong></p><div class="table-contents"><table class="table" summary="High Availability, Load Balancing, and Replication Feature Matrix" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /><col class="col6" /><col class="col7" /><col class="col8" /><col class="col9" /></colgroup><thead><tr><th>Feature</th><th>Shared Disk</th><th>File System Repl.</th><th>Write-Ahead Log Shipping</th><th>Logical Repl.</th><th>Trigger-​Based Repl.</th><th>SQL Repl. Middle-ware</th><th>Async. MM Repl.</th><th>Sync. MM Repl.</th></tr></thead><tbody><tr><td>Popular examples</td><td align="center">NAS</td><td align="center">DRBD</td><td align="center">built-in streaming repl.</td><td align="center">built-in logical repl., pglogical</td><td align="center">Londiste, Slony</td><td align="center">pgpool-II</td><td align="center">Bucardo</td><td align="center"> </td></tr><tr><td>Comm. method</td><td align="center">shared disk</td><td align="center">disk blocks</td><td align="center">WAL</td><td align="center">logical decoding</td><td align="center">table rows</td><td align="center">SQL</td><td align="center">table rows</td><td align="center">table rows and row locks</td></tr><tr><td>No special hardware required</td><td align="center"> </td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td></tr><tr><td>Allows multiple primary servers</td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">•</td><td align="center"> </td><td align="center">•</td><td align="center">•</td><td align="center">•</td></tr><tr><td>No overhead on primary</td><td align="center">•</td><td align="center"> </td><td align="center">•</td><td align="center">•</td><td align="center"> </td><td align="center">•</td><td align="center"> </td><td align="center"> </td></tr><tr><td>No waiting for multiple servers</td><td align="center">•</td><td align="center"> </td><td align="center">with sync off</td><td align="center">with sync off</td><td align="center">•</td><td align="center"> </td><td align="center">•</td><td align="center"> </td></tr><tr><td>Primary failure will never lose data</td><td align="center">•</td><td align="center">•</td><td align="center">with sync on</td><td align="center">with sync on</td><td align="center"> </td><td align="center">•</td><td align="center"> </td><td align="center">•</td></tr><tr><td>Replicas accept read-only queries</td><td align="center"> </td><td align="center"> </td><td align="center">with hot standby</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td></tr><tr><td>Per-table granularity</td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">•</td><td align="center">•</td><td align="center"> </td><td align="center">•</td><td align="center">•</td></tr><tr><td>No conflict resolution necessary</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center"> </td><td align="center">•</td><td align="center">•</td><td align="center"> </td><td align="center">•</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ There are a few solutions that do not fit into the above categories:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Data Partitioning</span></dt><dd><p>
+ Data partitioning splits tables into data sets. Each set can
+ be modified by only one server. For example, data can be
+ partitioned by offices, e.g., London and Paris, with a server
+ in each office. If queries combining London and Paris data
+ are necessary, an application can query both servers, or
+ primary/standby replication can be used to keep a read-only copy
+ of the other office's data on each server.
+ </p></dd><dt><span class="term">Multiple-Server Parallel Query Execution</span></dt><dd><p>
+ Many of the above solutions allow multiple servers to handle multiple
+ queries, but none allow a single query to use multiple servers to
+ complete faster. This solution allows multiple servers to work
+ concurrently on a single query. It is usually accomplished by
+ splitting the data among servers and having each server execute its
+ part of the query and return results to a central server where they
+ are combined and returned to the user. This can be implemented using the
+ <span class="productname">PL/Proxy</span> tool set.
+ </p></dd></dl></div><p>
+ It should also be noted that because <span class="productname">PostgreSQL</span>
+ is open source and easily extended, a number of companies have
+ taken <span class="productname">PostgreSQL</span> and created commercial
+ closed-source solutions with unique failover, replication, and load
+ balancing capabilities. These are not discussed here.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 27. High Availability, Load Balancing, and Replication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 27.2. Log-Shipping Standby Servers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/disk-full.html b/doc/src/sgml/html/disk-full.html
new file mode 100644
index 0000000..12f1479
--- /dev/null
+++ b/doc/src/sgml/html/disk-full.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>29.2. Disk Full Failure</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="disk-usage.html" title="29.1. Determining Disk Usage" /><link rel="next" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">29.2. Disk Full Failure</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="disk-usage.html" title="29.1. Determining Disk Usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Up</a></td><th width="60%" align="center">Chapter 29. Monitoring Disk Usage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Next</a></td></tr></table><hr /></div><div class="sect1" id="DISK-FULL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">29.2. Disk Full Failure</h2></div></div></div><p>
+ The most important disk monitoring task of a database administrator
+ is to make sure the disk doesn't become full. A filled data disk will
+ not result in data corruption, but it might prevent useful activity
+ from occurring. If the disk holding the WAL files grows full, database
+ server panic and consequent shutdown might occur.
+ </p><p>
+ If you cannot free up additional space on the disk by deleting
+ other things, you can move some of the database files to other file
+ systems by making use of tablespaces. See <a class="xref" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Section 23.6</a> for more information about that.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Some file systems perform badly when they are almost full, so do
+ not wait until the disk is completely full to take action.
+ </p></div><p>
+ If your system supports per-user disk quotas, then the database
+ will naturally be subject to whatever quota is placed on the user
+ the server runs as. Exceeding the quota will have the same bad
+ effects as running out of disk space entirely.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="disk-usage.html" title="29.1. Determining Disk Usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Next</a></td></tr><tr><td width="40%" align="left" valign="top">29.1. Determining Disk Usage </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 30. Reliability and the Write-Ahead Log</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/disk-usage.html b/doc/src/sgml/html/disk-usage.html
new file mode 100644
index 0000000..45fba94
--- /dev/null
+++ b/doc/src/sgml/html/disk-usage.html
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>29.1. Determining Disk Usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage" /><link rel="next" href="disk-full.html" title="29.2. Disk Full Failure" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">29.1. Determining Disk Usage</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Up</a></td><th width="60%" align="center">Chapter 29. Monitoring Disk Usage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="disk-full.html" title="29.2. Disk Full Failure">Next</a></td></tr></table><hr /></div><div class="sect1" id="DISK-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">29.1. Determining Disk Usage</h2></div></div></div><a id="id-1.6.16.3.2" class="indexterm"></a><p>
+ Each table has a primary heap disk file where most of the data is
+ stored. If the table has any columns with potentially-wide values,
+ there also might be a <acronym class="acronym">TOAST</acronym> file associated with the table,
+ which is used to store values too wide to fit comfortably in the main
+ table (see <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a>). There will be one valid index
+ on the <acronym class="acronym">TOAST</acronym> table, if present. There also might be indexes
+ associated with the base table. Each table and index is stored in a
+ separate disk file — possibly more than one file, if the file would
+ exceed one gigabyte. Naming conventions for these files are described
+ in <a class="xref" href="storage-file-layout.html" title="73.1. Database File Layout">Section 73.1</a>.
+ </p><p>
+ You can monitor disk space in three ways:
+ using the SQL functions listed in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-DBSIZE" title="Table 9.94. Database Object Size Functions">Table 9.94</a>,
+ using the <a class="xref" href="oid2name.html" title="oid2name"><span class="refentrytitle">oid2name</span></a> module, or
+ using manual inspection of the system catalogs.
+ The SQL functions are the easiest to use and are generally recommended.
+ The remainder of this section shows how to do it by inspection of the
+ system catalogs.
+ </p><p>
+ Using <span class="application">psql</span> on a recently vacuumed or analyzed database,
+ you can issue queries to see the disk usage of any table:
+</p><pre class="programlisting">
+SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
+
+ pg_relation_filepath | relpages
+----------------------+----------
+ base/16384/16806 | 60
+(1 row)
+</pre><p>
+ Each page is typically 8 kilobytes. (Remember, <code class="structfield">relpages</code>
+ is only updated by <code class="command">VACUUM</code>, <code class="command">ANALYZE</code>, and
+ a few DDL commands such as <code class="command">CREATE INDEX</code>.) The file path name
+ is of interest if you want to examine the table's disk file directly.
+ </p><p>
+ To show the space used by <acronym class="acronym">TOAST</acronym> tables, use a query
+ like the following:
+</p><pre class="programlisting">
+SELECT relname, relpages
+FROM pg_class,
+ (SELECT reltoastrelid
+ FROM pg_class
+ WHERE relname = 'customer') AS ss
+WHERE oid = ss.reltoastrelid OR
+ oid = (SELECT indexrelid
+ FROM pg_index
+ WHERE indrelid = ss.reltoastrelid)
+ORDER BY relname;
+
+ relname | relpages
+----------------------+----------
+ pg_toast_16806 | 0
+ pg_toast_16806_index | 1
+</pre><p>
+ </p><p>
+ You can easily display index sizes, too:
+</p><pre class="programlisting">
+SELECT c2.relname, c2.relpages
+FROM pg_class c, pg_class c2, pg_index i
+WHERE c.relname = 'customer' AND
+ c.oid = i.indrelid AND
+ c2.oid = i.indexrelid
+ORDER BY c2.relname;
+
+ relname | relpages
+-------------------+----------
+ customer_id_index | 26
+</pre><p>
+ </p><p>
+ It is easy to find your largest tables and indexes using this
+ information:
+</p><pre class="programlisting">
+SELECT relname, relpages
+FROM pg_class
+ORDER BY relpages DESC;
+
+ relname | relpages
+----------------------+----------
+ bigtable | 3290
+ customer | 3144
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="disk-full.html" title="29.2. Disk Full Failure">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 29. Monitoring Disk Usage </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 29.2. Disk Full Failure</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/diskusage.html b/doc/src/sgml/html/diskusage.html
new file mode 100644
index 0000000..75f25b7
--- /dev/null
+++ b/doc/src/sgml/html/diskusage.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 29. Monitoring Disk Usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dynamic-trace.html" title="28.5. Dynamic Tracing" /><link rel="next" href="disk-usage.html" title="29.1. Determining Disk Usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 29. Monitoring Disk Usage</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dynamic-trace.html" title="28.5. Dynamic Tracing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="disk-usage.html" title="29.1. Determining Disk Usage">Next</a></td></tr></table><hr /></div><div class="chapter" id="DISKUSAGE"><div class="titlepage"><div><div><h2 class="title">Chapter 29. Monitoring Disk Usage</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="disk-usage.html">29.1. Determining Disk Usage</a></span></dt><dt><span class="sect1"><a href="disk-full.html">29.2. Disk Full Failure</a></span></dt></dl></div><p>
+ This chapter discusses how to monitor the disk usage of a
+ <span class="productname">PostgreSQL</span> database system.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dynamic-trace.html" title="28.5. Dynamic Tracing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="disk-usage.html" title="29.1. Determining Disk Usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">28.5. Dynamic Tracing </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 29.1. Determining Disk Usage</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dml-delete.html b/doc/src/sgml/html/dml-delete.html
new file mode 100644
index 0000000..d6a430b
--- /dev/null
+++ b/doc/src/sgml/html/dml-delete.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>6.3. Deleting Data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dml-update.html" title="6.2. Updating Data" /><link rel="next" href="dml-returning.html" title="6.4. Returning Data from Modified Rows" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">6.3. Deleting Data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dml-update.html" title="6.2. Updating Data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><th width="60%" align="center">Chapter 6. Data Manipulation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dml-returning.html" title="6.4. Returning Data from Modified Rows">Next</a></td></tr></table><hr /></div><div class="sect1" id="DML-DELETE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">6.3. Deleting Data</h2></div></div></div><a id="id-1.5.5.5.2" class="indexterm"></a><a id="id-1.5.5.5.3" class="indexterm"></a><p>
+ So far we have explained how to add data to tables and how to
+ change data. What remains is to discuss how to remove data that is
+ no longer needed. Just as adding data is only possible in whole
+ rows, you can only remove entire rows from a table. In the
+ previous section we explained that SQL does not provide a way to
+ directly address individual rows. Therefore, removing rows can
+ only be done by specifying conditions that the rows to be removed
+ have to match. If you have a primary key in the table then you can
+ specify the exact row. But you can also remove groups of rows
+ matching a condition, or you can remove all rows in the table at
+ once.
+ </p><p>
+ You use the <a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a>
+ command to remove rows; the syntax is very similar to the
+ <a class="xref" href="sql-update.html" title="UPDATE"><span class="refentrytitle">UPDATE</span></a> command. For instance, to remove all
+ rows from the products table that have a price of 10, use:
+</p><pre class="programlisting">
+DELETE FROM products WHERE price = 10;
+</pre><p>
+ </p><p>
+ If you simply write:
+</p><pre class="programlisting">
+DELETE FROM products;
+</pre><p>
+ then all rows in the table will be deleted! Caveat programmer.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dml-update.html" title="6.2. Updating Data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dml-returning.html" title="6.4. Returning Data from Modified Rows">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.2. Updating Data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 6.4. Returning Data from Modified Rows</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dml-insert.html b/doc/src/sgml/html/dml-insert.html
new file mode 100644
index 0000000..5182205
--- /dev/null
+++ b/doc/src/sgml/html/dml-insert.html
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>6.1. Inserting Data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dml.html" title="Chapter 6. Data Manipulation" /><link rel="next" href="dml-update.html" title="6.2. Updating Data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">6.1. Inserting Data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dml.html" title="Chapter 6. Data Manipulation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><th width="60%" align="center">Chapter 6. Data Manipulation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dml-update.html" title="6.2. Updating Data">Next</a></td></tr></table><hr /></div><div class="sect1" id="DML-INSERT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">6.1. Inserting Data</h2></div></div></div><a id="id-1.5.5.3.2" class="indexterm"></a><a id="id-1.5.5.3.3" class="indexterm"></a><p>
+ When a table is created, it contains no data. The first thing to
+ do before a database can be of much use is to insert data. Data is
+ inserted one row at a time. You can also insert more than one row
+ in a single command, but it is not possible to insert something that
+ is not a complete row. Even if you know only some column values, a
+ complete row must be created.
+ </p><p>
+ To create a new row, use the <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>
+ command. The command requires the
+ table name and column values. For
+ example, consider the products table from <a class="xref" href="ddl.html" title="Chapter 5. Data Definition">Chapter 5</a>:
+</p><pre class="programlisting">
+CREATE TABLE products (
+ product_no integer,
+ name text,
+ price numeric
+);
+</pre><p>
+ An example command to insert a row would be:
+</p><pre class="programlisting">
+INSERT INTO products VALUES (1, 'Cheese', 9.99);
+</pre><p>
+ The data values are listed in the order in which the columns appear
+ in the table, separated by commas. Usually, the data values will
+ be literals (constants), but scalar expressions are also allowed.
+ </p><p>
+ The above syntax has the drawback that you need to know the order
+ of the columns in the table. To avoid this you can also list the
+ columns explicitly. For example, both of the following commands
+ have the same effect as the one above:
+</p><pre class="programlisting">
+INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', 9.99);
+INSERT INTO products (name, price, product_no) VALUES ('Cheese', 9.99, 1);
+</pre><p>
+ Many users consider it good practice to always list the column
+ names.
+ </p><p>
+ If you don't have values for all the columns, you can omit some of
+ them. In that case, the columns will be filled with their default
+ values. For example:
+</p><pre class="programlisting">
+INSERT INTO products (product_no, name) VALUES (1, 'Cheese');
+INSERT INTO products VALUES (1, 'Cheese');
+</pre><p>
+ The second form is a <span class="productname">PostgreSQL</span>
+ extension. It fills the columns from the left with as many values
+ as are given, and the rest will be defaulted.
+ </p><p>
+ For clarity, you can also request default values explicitly, for
+ individual columns or for the entire row:
+</p><pre class="programlisting">
+INSERT INTO products (product_no, name, price) VALUES (1, 'Cheese', DEFAULT);
+INSERT INTO products DEFAULT VALUES;
+</pre><p>
+ </p><p>
+ You can insert multiple rows in a single command:
+</p><pre class="programlisting">
+INSERT INTO products (product_no, name, price) VALUES
+ (1, 'Cheese', 9.99),
+ (2, 'Bread', 1.99),
+ (3, 'Milk', 2.99);
+</pre><p>
+ </p><p>
+ It is also possible to insert the result of a query (which might be no
+ rows, one row, or many rows):
+</p><pre class="programlisting">
+INSERT INTO products (product_no, name, price)
+ SELECT product_no, name, price FROM new_products
+ WHERE release_date = 'today';
+</pre><p>
+ This provides the full power of the SQL query mechanism (<a class="xref" href="queries.html" title="Chapter 7. Queries">Chapter 7</a>) for computing the rows to be inserted.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ When inserting a lot of data at the same time, consider using
+ the <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> command.
+ It is not as flexible as the <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>
+ command, but is more efficient. Refer
+ to <a class="xref" href="populate.html" title="14.4. Populating a Database">Section 14.4</a> for more information on improving
+ bulk loading performance.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dml.html" title="Chapter 6. Data Manipulation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dml-update.html" title="6.2. Updating Data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 6. Data Manipulation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 6.2. Updating Data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dml-returning.html b/doc/src/sgml/html/dml-returning.html
new file mode 100644
index 0000000..63ee027
--- /dev/null
+++ b/doc/src/sgml/html/dml-returning.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>6.4. Returning Data from Modified Rows</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dml-delete.html" title="6.3. Deleting Data" /><link rel="next" href="queries.html" title="Chapter 7. Queries" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">6.4. Returning Data from Modified Rows</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dml-delete.html" title="6.3. Deleting Data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><th width="60%" align="center">Chapter 6. Data Manipulation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries.html" title="Chapter 7. Queries">Next</a></td></tr></table><hr /></div><div class="sect1" id="DML-RETURNING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">6.4. Returning Data from Modified Rows</h2></div></div></div><a id="id-1.5.5.6.2" class="indexterm"></a><a id="id-1.5.5.6.3" class="indexterm"></a><a id="id-1.5.5.6.4" class="indexterm"></a><a id="id-1.5.5.6.5" class="indexterm"></a><p>
+ Sometimes it is useful to obtain data from modified rows while they are
+ being manipulated. The <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ and <code class="command">DELETE</code> commands all have an
+ optional <code class="literal">RETURNING</code> clause that supports this. Use
+ of <code class="literal">RETURNING</code> avoids performing an extra database query to
+ collect the data, and is especially valuable when it would otherwise be
+ difficult to identify the modified rows reliably.
+ </p><p>
+ The allowed contents of a <code class="literal">RETURNING</code> clause are the same as
+ a <code class="command">SELECT</code> command's output list
+ (see <a class="xref" href="queries-select-lists.html" title="7.3. Select Lists">Section 7.3</a>). It can contain column
+ names of the command's target table, or value expressions using those
+ columns. A common shorthand is <code class="literal">RETURNING *</code>, which selects
+ all columns of the target table in order.
+ </p><p>
+ In an <code class="command">INSERT</code>, the data available to <code class="literal">RETURNING</code> is
+ the row as it was inserted. This is not so useful in trivial inserts,
+ since it would just repeat the data provided by the client. But it can
+ be very handy when relying on computed default values. For example,
+ when using a <a class="link" href="datatype-numeric.html#DATATYPE-SERIAL" title="8.1.4. Serial Types"><code class="type">serial</code></a>
+ column to provide unique identifiers, <code class="literal">RETURNING</code> can return
+ the ID assigned to a new row:
+</p><pre class="programlisting">
+CREATE TABLE users (firstname text, lastname text, id serial primary key);
+
+INSERT INTO users (firstname, lastname) VALUES ('Joe', 'Cool') RETURNING id;
+</pre><p>
+ The <code class="literal">RETURNING</code> clause is also very useful
+ with <code class="literal">INSERT ... SELECT</code>.
+ </p><p>
+ In an <code class="command">UPDATE</code>, the data available to <code class="literal">RETURNING</code> is
+ the new content of the modified row. For example:
+</p><pre class="programlisting">
+UPDATE products SET price = price * 1.10
+ WHERE price &lt;= 99.99
+ RETURNING name, price AS new_price;
+</pre><p>
+ </p><p>
+ In a <code class="command">DELETE</code>, the data available to <code class="literal">RETURNING</code> is
+ the content of the deleted row. For example:
+</p><pre class="programlisting">
+DELETE FROM products
+ WHERE obsoletion_date = 'today'
+ RETURNING *;
+</pre><p>
+ </p><p>
+ If there are triggers (<a class="xref" href="triggers.html" title="Chapter 39. Triggers">Chapter 39</a>) on the target table,
+ the data available to <code class="literal">RETURNING</code> is the row as modified by
+ the triggers. Thus, inspecting columns computed by triggers is another
+ common use-case for <code class="literal">RETURNING</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dml-delete.html" title="6.3. Deleting Data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries.html" title="Chapter 7. Queries">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.3. Deleting Data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 7. Queries</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dml-update.html b/doc/src/sgml/html/dml-update.html
new file mode 100644
index 0000000..a6939f4
--- /dev/null
+++ b/doc/src/sgml/html/dml-update.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>6.2. Updating Data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dml-insert.html" title="6.1. Inserting Data" /><link rel="next" href="dml-delete.html" title="6.3. Deleting Data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">6.2. Updating Data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dml-insert.html" title="6.1. Inserting Data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><th width="60%" align="center">Chapter 6. Data Manipulation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dml-delete.html" title="6.3. Deleting Data">Next</a></td></tr></table><hr /></div><div class="sect1" id="DML-UPDATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">6.2. Updating Data</h2></div></div></div><a id="id-1.5.5.4.2" class="indexterm"></a><a id="id-1.5.5.4.3" class="indexterm"></a><p>
+ The modification of data that is already in the database is
+ referred to as updating. You can update individual rows, all the
+ rows in a table, or a subset of all rows. Each column can be
+ updated separately; the other columns are not affected.
+ </p><p>
+ To update existing rows, use the <a class="xref" href="sql-update.html" title="UPDATE"><span class="refentrytitle">UPDATE</span></a>
+ command. This requires
+ three pieces of information:
+ </p><div class="orderedlist"><ol class="orderedlist compact" type="1"><li class="listitem"><p>The name of the table and column to update</p></li><li class="listitem"><p>The new value of the column</p></li><li class="listitem"><p>Which row(s) to update</p></li></ol></div><p>
+ </p><p>
+ Recall from <a class="xref" href="ddl.html" title="Chapter 5. Data Definition">Chapter 5</a> that SQL does not, in general,
+ provide a unique identifier for rows. Therefore it is not
+ always possible to directly specify which row to update.
+ Instead, you specify which conditions a row must meet in order to
+ be updated. Only if you have a primary key in the table (independent of
+ whether you declared it or not) can you reliably address individual rows
+ by choosing a condition that matches the primary key.
+ Graphical database access tools rely on this fact to allow you to
+ update rows individually.
+ </p><p>
+ For example, this command updates all products that have a price of
+ 5 to have a price of 10:
+</p><pre class="programlisting">
+UPDATE products SET price = 10 WHERE price = 5;
+</pre><p>
+ This might cause zero, one, or many rows to be updated. It is not
+ an error to attempt an update that does not match any rows.
+ </p><p>
+ Let's look at that command in detail. First is the key word
+ <code class="literal">UPDATE</code> followed by the table name. As usual,
+ the table name can be schema-qualified, otherwise it is looked up
+ in the path. Next is the key word <code class="literal">SET</code> followed
+ by the column name, an equal sign, and the new column value. The
+ new column value can be any scalar expression, not just a constant.
+ For example, if you want to raise the price of all products by 10%
+ you could use:
+</p><pre class="programlisting">
+UPDATE products SET price = price * 1.10;
+</pre><p>
+ As you see, the expression for the new value can refer to the existing
+ value(s) in the row. We also left out the <code class="literal">WHERE</code> clause.
+ If it is omitted, it means that all rows in the table are updated.
+ If it is present, only those rows that match the
+ <code class="literal">WHERE</code> condition are updated. Note that the equals
+ sign in the <code class="literal">SET</code> clause is an assignment while
+ the one in the <code class="literal">WHERE</code> clause is a comparison, but
+ this does not create any ambiguity. Of course, the
+ <code class="literal">WHERE</code> condition does
+ not have to be an equality test. Many other operators are
+ available (see <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a>). But the expression
+ needs to evaluate to a Boolean result.
+ </p><p>
+ You can update more than one column in an
+ <code class="command">UPDATE</code> command by listing more than one
+ assignment in the <code class="literal">SET</code> clause. For example:
+</p><pre class="programlisting">
+UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a &gt; 0;
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dml-insert.html" title="6.1. Inserting Data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="dml.html" title="Chapter 6. Data Manipulation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dml-delete.html" title="6.3. Deleting Data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.1. Inserting Data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 6.3. Deleting Data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dml.html b/doc/src/sgml/html/dml.html
new file mode 100644
index 0000000..b0fb1dc
--- /dev/null
+++ b/doc/src/sgml/html/dml.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 6. Data Manipulation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ddl-depend.html" title="5.14. Dependency Tracking" /><link rel="next" href="dml-insert.html" title="6.1. Inserting Data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 6. Data Manipulation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ddl-depend.html" title="5.14. Dependency Tracking">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dml-insert.html" title="6.1. Inserting Data">Next</a></td></tr></table><hr /></div><div class="chapter" id="DML"><div class="titlepage"><div><div><h2 class="title">Chapter 6. Data Manipulation</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="dml-insert.html">6.1. Inserting Data</a></span></dt><dt><span class="sect1"><a href="dml-update.html">6.2. Updating Data</a></span></dt><dt><span class="sect1"><a href="dml-delete.html">6.3. Deleting Data</a></span></dt><dt><span class="sect1"><a href="dml-returning.html">6.4. Returning Data from Modified Rows</a></span></dt></dl></div><p>
+ The previous chapter discussed how to create tables and other
+ structures to hold your data. Now it is time to fill the tables
+ with data. This chapter covers how to insert, update, and delete
+ table data. The chapter
+ after this will finally explain how to extract your long-lost data
+ from the database.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ddl-depend.html" title="5.14. Dependency Tracking">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dml-insert.html" title="6.1. Inserting Data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5.14. Dependency Tracking </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 6.1. Inserting Data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/docguide-authoring.html b/doc/src/sgml/html/docguide-authoring.html
new file mode 100644
index 0000000..80e6af2
--- /dev/null
+++ b/doc/src/sgml/html/docguide-authoring.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>J.4. Documentation Authoring</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="docguide-build.html" title="J.3. Building the Documentation" /><link rel="next" href="docguide-style.html" title="J.5. Style Guide" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">J.4. Documentation Authoring</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="docguide-build.html" title="J.3. Building the Documentation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><th width="60%" align="center">Appendix J. Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="docguide-style.html" title="J.5. Style Guide">Next</a></td></tr></table><hr /></div><div class="sect1" id="DOCGUIDE-AUTHORING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">J.4. Documentation Authoring</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="docguide-authoring.html#id-1.11.11.7.4">J.4.1. Emacs</a></span></dt></dl></div><p>
+ The documentation sources are most conveniently modified with an editor
+ that has a mode for editing XML, and even more so if it has some awareness
+ of XML schema languages so that it can know about
+ <span class="productname">DocBook</span> syntax specifically.
+ </p><p>
+ Note that for historical reasons the documentation source files are named
+ with an extension <code class="filename">.sgml</code> even though they are now XML
+ files. So you might need to adjust your editor configuration to set the
+ correct mode.
+ </p><div class="sect2" id="id-1.11.11.7.4"><div class="titlepage"><div><div><h3 class="title">J.4.1. Emacs</h3></div></div></div><p>
+ <span class="productname">nXML Mode</span>, which ships with
+ <span class="productname">Emacs</span>, is the most common mode for editing
+ <acronym class="acronym">XML</acronym> documents with <span class="productname">Emacs</span>.
+ It will allow you to use <span class="application">Emacs</span> to insert tags
+ and check markup consistency, and it supports
+ <span class="productname">DocBook</span> out of the box. Check the <a class="ulink" href="https://www.gnu.org/software/emacs/manual/html_mono/nxml-mode.html" target="_top">
+ nXML manual</a> for detailed documentation.
+ </p><p>
+ <code class="filename">src/tools/editors/emacs.samples</code> contains
+ recommended settings for this mode.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="docguide-build.html" title="J.3. Building the Documentation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="docguide-style.html" title="J.5. Style Guide">Next</a></td></tr><tr><td width="40%" align="left" valign="top">J.3. Building the Documentation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> J.5. Style Guide</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/docguide-build.html b/doc/src/sgml/html/docguide-build.html
new file mode 100644
index 0000000..97362b4
--- /dev/null
+++ b/doc/src/sgml/html/docguide-build.html
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>J.3. Building the Documentation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="docguide-toolsets.html" title="J.2. Tool Sets" /><link rel="next" href="docguide-authoring.html" title="J.4. Documentation Authoring" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">J.3. Building the Documentation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="docguide-toolsets.html" title="J.2. Tool Sets">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><th width="60%" align="center">Appendix J. Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="docguide-authoring.html" title="J.4. Documentation Authoring">Next</a></td></tr></table><hr /></div><div class="sect1" id="DOCGUIDE-BUILD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">J.3. Building the Documentation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.3">J.3.1. HTML</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.4">J.3.2. Manpages</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.5">J.3.3. PDF</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.6">J.3.4. Plain Text Files</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.7">J.3.5. Syntax Check</a></span></dt></dl></div><p>
+ Once you have everything set up, change to the directory
+ <code class="filename">doc/src/sgml</code> and run one of the commands
+ described in the following subsections to build the
+ documentation. (Remember to use GNU make.)
+ </p><div class="sect2" id="id-1.11.11.6.3"><div class="titlepage"><div><div><h3 class="title">J.3.1. HTML</h3></div></div></div><p>
+ To build the <acronym class="acronym">HTML</acronym> version of the documentation:
+</p><pre class="screen">
+<code class="prompt">doc/src/sgml$ </code><strong class="userinput"><code>make html</code></strong>
+</pre><p>
+ This is also the default target. The output appears in the
+ subdirectory <code class="filename">html</code>.
+ </p><p>
+ To produce HTML documentation with the stylesheet used on <a class="ulink" href="https://www.postgresql.org/docs/current/" target="_top">postgresql.org</a> instead of the
+ default simple style use:
+</p><pre class="screen">
+<code class="prompt">doc/src/sgml$ </code><strong class="userinput"><code>make STYLE=website html</code></strong>
+</pre><p>
+ </p><p>
+ If the <code class="literal">STYLE=website</code> option is used, the generated HTML
+ files include references to stylesheets hosted on <a class="ulink" href="https://www.postgresql.org/docs/current/" target="_top">postgresql.org</a> and
+ require network access to view.
+ </p></div><div class="sect2" id="id-1.11.11.6.4"><div class="titlepage"><div><div><h3 class="title">J.3.2. Manpages</h3></div></div></div><p>
+ We use the DocBook XSL stylesheets to
+ convert <span class="productname">DocBook</span>
+ <code class="sgmltag-element">refentry</code> pages to *roff output suitable for man
+ pages. To create the man pages, use the command:
+</p><pre class="screen">
+<code class="prompt">doc/src/sgml$ </code><strong class="userinput"><code>make man</code></strong>
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.11.6.5"><div class="titlepage"><div><div><h3 class="title">J.3.3. PDF</h3></div></div></div><p>
+ To produce a PDF rendition of the documentation
+ using <span class="productname">FOP</span>, you can use one of the following
+ commands, depending on the preferred paper format:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ For A4 format:
+</p><pre class="screen">
+<code class="prompt">doc/src/sgml$ </code><strong class="userinput"><code>make postgres-A4.pdf</code></strong>
+</pre><p>
+ </p></li><li class="listitem"><p>
+ For U.S. letter format:
+</p><pre class="screen">
+<code class="prompt">doc/src/sgml$ </code><strong class="userinput"><code>make postgres-US.pdf</code></strong>
+</pre><p>
+ </p></li></ul></div><p>
+ </p><p>
+ Because the PostgreSQL documentation is fairly
+ big, <span class="productname">FOP</span> will require a significant amount of
+ memory. Because of that, on some systems, the build will fail with a
+ memory-related error message. This can usually be fixed by configuring
+ Java heap settings in the configuration
+ file <code class="filename">~/.foprc</code>, for example:
+</p><pre class="programlisting">
+# FOP binary distribution
+FOP_OPTS='-Xmx1500m'
+# Debian
+JAVA_ARGS='-Xmx1500m'
+# Red Hat
+ADDITIONAL_FLAGS='-Xmx1500m'
+</pre><p>
+ There is a minimum amount of memory that is required, and to some extent
+ more memory appears to make things a bit faster. On systems with very
+ little memory (less than 1 GB), the build will either be very slow due to
+ swapping or will not work at all.
+ </p><p>
+ Other XSL-FO processors can also be used manually, but the automated build
+ process only supports FOP.
+ </p></div><div class="sect2" id="id-1.11.11.6.6"><div class="titlepage"><div><div><h3 class="title">J.3.4. Plain Text Files</h3></div></div></div><p>
+ The installation instructions are also distributed as plain text,
+ in case they are needed in a situation where better reading tools
+ are not available. The <code class="filename">INSTALL</code> file
+ corresponds to <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a>, with some minor
+ changes to account for the different context. To recreate the
+ file, change to the directory <code class="filename">doc/src/sgml</code>
+ and enter <strong class="userinput"><code>make INSTALL</code></strong>. Building text output
+ requires <span class="productname">Pandoc</span> version 1.13 or newer as an
+ additional build tool.
+ </p><p>
+ In the past, the release notes and regression testing instructions
+ were also distributed as plain text, but this practice has been
+ discontinued.
+ </p></div><div class="sect2" id="id-1.11.11.6.7"><div class="titlepage"><div><div><h3 class="title">J.3.5. Syntax Check</h3></div></div></div><p>
+ Building the documentation can take very long. But there is a
+ method to just check the correct syntax of the documentation
+ files, which only takes a few seconds:
+</p><pre class="screen">
+<code class="prompt">doc/src/sgml$ </code><strong class="userinput"><code>make check</code></strong>
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="docguide-toolsets.html" title="J.2. Tool Sets">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="docguide-authoring.html" title="J.4. Documentation Authoring">Next</a></td></tr><tr><td width="40%" align="left" valign="top">J.2. Tool Sets </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> J.4. Documentation Authoring</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/docguide-docbook.html b/doc/src/sgml/html/docguide-docbook.html
new file mode 100644
index 0000000..0a10307
--- /dev/null
+++ b/doc/src/sgml/html/docguide-docbook.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>J.1. DocBook</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="docguide.html" title="Appendix J. Documentation" /><link rel="next" href="docguide-toolsets.html" title="J.2. Tool Sets" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">J.1. DocBook</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="docguide.html" title="Appendix J. Documentation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><th width="60%" align="center">Appendix J. Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="docguide-toolsets.html" title="J.2. Tool Sets">Next</a></td></tr></table><hr /></div><div class="sect1" id="DOCGUIDE-DOCBOOK"><div class="titlepage"><div><div><h2 class="title" style="clear: both">J.1. DocBook</h2></div></div></div><p>
+ The documentation sources are written in
+ <em class="firstterm">DocBook</em>, which is a markup language
+ defined in <acronym class="acronym">XML</acronym>. In what
+ follows, the terms DocBook and <acronym class="acronym">XML</acronym> are both
+ used, but technically they are not interchangeable.
+ </p><p>
+ <span class="productname">DocBook</span> allows an author to specify the
+ structure and content of a technical document without worrying
+ about presentation details. A document style defines how that
+ content is rendered into one of several final forms. DocBook is
+ maintained by the <a class="ulink" href="https://www.oasis-open.org" target="_top">
+ OASIS group</a>. The <a class="ulink" href="https://www.oasis-open.org/docbook/" target="_top">
+ official DocBook site</a> has good introductory and reference documentation and
+ a complete O'Reilly book for your online reading pleasure. The
+ <a class="ulink" href="http://newbiedoc.sourceforge.net/metadoc/docbook-guide.html" target="_top">
+ NewbieDoc Docbook Guide</a> is very helpful for beginners.
+ The <a class="ulink" href="https://www.freebsd.org/docproj/" target="_top">
+ FreeBSD Documentation Project</a> also uses DocBook and has some good
+ information, including a number of style guidelines that might be
+ worth considering.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="docguide.html" title="Appendix J. Documentation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="docguide-toolsets.html" title="J.2. Tool Sets">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix J. Documentation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> J.2. Tool Sets</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/docguide-style.html b/doc/src/sgml/html/docguide-style.html
new file mode 100644
index 0000000..7489e2d
--- /dev/null
+++ b/doc/src/sgml/html/docguide-style.html
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>J.5. Style Guide</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="docguide-authoring.html" title="J.4. Documentation Authoring" /><link rel="next" href="limits.html" title="Appendix K. PostgreSQL Limits" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">J.5. Style Guide</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="docguide-authoring.html" title="J.4. Documentation Authoring">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><th width="60%" align="center">Appendix J. Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="limits.html" title="Appendix K. PostgreSQL Limits">Next</a></td></tr></table><hr /></div><div class="sect1" id="DOCGUIDE-STYLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">J.5. Style Guide</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="docguide-style.html#id-1.11.11.8.2">J.5.1. Reference Pages</a></span></dt></dl></div><div class="sect2" id="id-1.11.11.8.2"><div class="titlepage"><div><div><h3 class="title">J.5.1. Reference Pages</h3></div></div></div><p>
+ Reference pages should follow a standard layout. This allows
+ users to find the desired information more quickly, and it also
+ encourages writers to document all relevant aspects of a command.
+ Consistency is not only desired among
+ <span class="productname">PostgreSQL</span> reference pages, but also
+ with reference pages provided by the operating system and other
+ packages. Hence the following guidelines have been developed.
+ They are for the most part consistent with similar guidelines
+ established by various operating systems.
+ </p><p>
+ Reference pages that describe executable commands should contain
+ the following sections, in this order. Sections that do not apply
+ can be omitted. Additional top-level sections should only be used
+ in special circumstances; often that information belongs in the
+ <span class="quote">“<span class="quote">Usage</span>”</span> section.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Name</span></dt><dd><p>
+ This section is generated automatically. It contains the
+ command name and a half-sentence summary of its functionality.
+ </p></dd><dt><span class="term">Synopsis</span></dt><dd><p>
+ This section contains the syntax diagram of the command. The
+ synopsis should normally not list each command-line option;
+ that is done below. Instead, list the major components of the
+ command line, such as where input and output files go.
+ </p></dd><dt><span class="term">Description</span></dt><dd><p>
+ Several paragraphs explaining what the command does.
+ </p></dd><dt><span class="term">Options</span></dt><dd><p>
+ A list describing each command-line option. If there are a
+ lot of options, subsections can be used.
+ </p></dd><dt><span class="term">Exit Status</span></dt><dd><p>
+ If the program uses 0 for success and non-zero for failure,
+ then you do not need to document it. If there is a meaning
+ behind the different non-zero exit codes, list them here.
+ </p></dd><dt><span class="term">Usage</span></dt><dd><p>
+ Describe any sublanguage or run-time interface of the program.
+ If the program is not interactive, this section can usually be
+ omitted. Otherwise, this section is a catch-all for
+ describing run-time features. Use subsections if appropriate.
+ </p></dd><dt><span class="term">Environment</span></dt><dd><p>
+ List all environment variables that the program might use.
+ Try to be complete; even seemingly trivial variables like
+ <code class="envar">SHELL</code> might be of interest to the user.
+ </p></dd><dt><span class="term">Files</span></dt><dd><p>
+ List any files that the program might access implicitly. That
+ is, do not list input and output files that were specified on
+ the command line, but list configuration files, etc.
+ </p></dd><dt><span class="term">Diagnostics</span></dt><dd><p>
+ Explain any unusual output that the program might create.
+ Refrain from listing every possible error message. This is a
+ lot of work and has little use in practice. But if, say, the
+ error messages have a standard format that the user can parse,
+ this would be the place to explain it.
+ </p></dd><dt><span class="term">Notes</span></dt><dd><p>
+ Anything that doesn't fit elsewhere, but in particular bugs,
+ implementation flaws, security considerations, compatibility
+ issues.
+ </p></dd><dt><span class="term">Examples</span></dt><dd><p>
+ Examples
+ </p></dd><dt><span class="term">History</span></dt><dd><p>
+ If there were some major milestones in the history of the
+ program, they might be listed here. Usually, this section can
+ be omitted.
+ </p></dd><dt><span class="term">Author</span></dt><dd><p>
+ Author (only used in the contrib section)
+ </p></dd><dt><span class="term">See Also</span></dt><dd><p>
+ Cross-references, listed in the following order: other
+ <span class="productname">PostgreSQL</span> command reference pages,
+ <span class="productname">PostgreSQL</span> SQL command reference
+ pages, citation of <span class="productname">PostgreSQL</span>
+ manuals, other reference pages (e.g., operating system, other
+ packages), other documentation. Items in the same group are
+ listed alphabetically.
+ </p></dd></dl></div><p>
+ </p><p>
+ Reference pages describing SQL commands should contain the
+ following sections: Name, Synopsis, Description, Parameters,
+ Outputs, Notes, Examples, Compatibility, History, See
+ Also. The Parameters section is like the Options section, but
+ there is more freedom about which clauses of the command can be
+ listed. The Outputs section is only needed if the command returns
+ something other than a default command-completion tag. The Compatibility
+ section should explain to what extent
+ this command conforms to the SQL standard(s), or to which other
+ database system it is compatible. The See Also section of SQL
+ commands should list SQL commands before cross-references to
+ programs.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="docguide-authoring.html" title="J.4. Documentation Authoring">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="limits.html" title="Appendix K. PostgreSQL Limits">Next</a></td></tr><tr><td width="40%" align="left" valign="top">J.4. Documentation Authoring </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix K. <span class="productname">PostgreSQL</span> Limits</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/docguide-toolsets.html b/doc/src/sgml/html/docguide-toolsets.html
new file mode 100644
index 0000000..a173fa5
--- /dev/null
+++ b/doc/src/sgml/html/docguide-toolsets.html
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>J.2. Tool Sets</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="docguide-docbook.html" title="J.1. DocBook" /><link rel="next" href="docguide-build.html" title="J.3. Building the Documentation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">J.2. Tool Sets</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="docguide-docbook.html" title="J.1. DocBook">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><th width="60%" align="center">Appendix J. Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="docguide-build.html" title="J.3. Building the Documentation">Next</a></td></tr></table><hr /></div><div class="sect1" id="DOCGUIDE-TOOLSETS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">J.2. Tool Sets</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.4">J.2.1. Installation on Fedora, RHEL, and Derivatives</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.5">J.2.2. Installation on FreeBSD</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.6">J.2.3. Debian Packages</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.7">J.2.4. macOS</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#DOCGUIDE-TOOLSETS-CONFIGURE">J.2.5. Detection by <code class="command">configure</code></a></span></dt></dl></div><p>
+ The following tools are used to process the documentation. Some
+ might be optional, as noted.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><a class="ulink" href="https://www.oasis-open.org/docbook/" target="_top">DocBook DTD</a></span></dt><dd><p>
+ This is the definition of DocBook itself. We currently use version
+ 4.5; you cannot use later or earlier versions. You need
+ the <acronym class="acronym">XML</acronym> variant of the DocBook DTD, not
+ the <acronym class="acronym">SGML</acronym> variant.
+ </p></dd><dt><span class="term"><a class="ulink" href="https://github.com/docbook/wiki/wiki/DocBookXslStylesheets" target="_top">DocBook XSL Stylesheets</a></span></dt><dd><p>
+ These contain the processing instructions for converting the
+ DocBook sources to other formats, such as
+ <acronym class="acronym">HTML</acronym>.
+ </p><p>
+ The minimum required version is currently 1.77.0, but it is recommended
+ to use the latest available version for best results.
+ </p></dd><dt><span class="term"><a class="ulink" href="http://xmlsoft.org/" target="_top">Libxml2</a> for <code class="command">xmllint</code></span></dt><dd><p>
+ This library and the <code class="command">xmllint</code> tool it contains are
+ used for processing XML. Many developers will already
+ have <span class="application">Libxml2</span> installed, because it is also
+ used when building the PostgreSQL code. Note, however,
+ that <code class="command">xmllint</code> might need to be installed from a
+ separate subpackage.
+ </p></dd><dt><span class="term"><a class="ulink" href="http://xmlsoft.org/XSLT/" target="_top">Libxslt</a> for <code class="command">xsltproc</code></span></dt><dd><p>
+ <code class="command">xsltproc</code> is an XSLT processor, that is, a program to
+ convert XML to other formats using XSLT stylesheets.
+ </p></dd><dt><span class="term"><a class="ulink" href="https://xmlgraphics.apache.org/fop/" target="_top">FOP</a></span></dt><dd><p>
+ This is a program for converting, among other things, XML to PDF.
+ It is needed only if you want to build the documentation in PDF format.
+ </p></dd></dl></div><p>
+ </p><p>
+ We have documented experience with several installation methods for
+ the various tools that are needed to process the documentation.
+ These will be described below. There might be some other packaged
+ distributions for these tools. Please report package status to the
+ documentation mailing list, and we will include that information
+ here.
+ </p><div class="sect2" id="id-1.11.11.5.4"><div class="titlepage"><div><div><h3 class="title">J.2.1. Installation on Fedora, RHEL, and Derivatives</h3></div></div></div><p>
+ To install the required packages, use:
+</p><pre class="programlisting">
+yum install docbook-dtds docbook-style-xsl libxslt fop
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.11.5.5"><div class="titlepage"><div><div><h3 class="title">J.2.2. Installation on FreeBSD</h3></div></div></div><p>
+ To install the required packages with <code class="command">pkg</code>, use:
+</p><pre class="programlisting">
+pkg install docbook-xml docbook-xsl libxslt fop
+</pre><p>
+ </p><p>
+ When building the documentation from the <code class="filename">doc</code>
+ directory you'll need to use <code class="command">gmake</code>, because the
+ makefile provided is not suitable for FreeBSD's <code class="command">make</code>.
+ </p></div><div class="sect2" id="id-1.11.11.5.6"><div class="titlepage"><div><div><h3 class="title">J.2.3. Debian Packages</h3></div></div></div><p>
+ There is a full set of packages of the documentation tools
+ available for <span class="productname">Debian GNU/Linux</span>.
+ To install, simply use:
+</p><pre class="programlisting">
+apt-get install docbook-xml docbook-xsl libxml2-utils xsltproc fop
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.11.5.7"><div class="titlepage"><div><div><h3 class="title">J.2.4. macOS</h3></div></div></div><p>
+ If you use MacPorts, the following will get you set up:
+</p><pre class="programlisting">
+sudo port install docbook-xml docbook-xsl-nons libxslt fop
+</pre><p>
+ If you use Homebrew, use this:
+</p><pre class="programlisting">
+brew install docbook docbook-xsl libxslt fop
+</pre><p>
+ </p><p>
+ The Homebrew-supplied programs require the following environment variable
+ to be set. For Intel based machines, use this:
+</p><pre class="programlisting">
+export XML_CATALOG_FILES=/usr/local/etc/xml/catalog
+</pre><p>
+ On Apple Silicon based machines, use this:
+</p><pre class="programlisting">
+export XML_CATALOG_FILES=/opt/homebrew/etc/xml/catalog
+</pre><p>
+ Without it, <code class="command">xsltproc</code> will throw errors like this:
+</p><pre class="programlisting">
+I/O error : Attempt to load network entity http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd
+postgres.sgml:21: warning: failed to load external entity "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
+...
+</pre><p>
+ </p><p>
+ While it is possible to use the Apple-provided versions
+ of <code class="command">xmllint</code> and <code class="command">xsltproc</code>
+ instead of those from MacPorts or Homebrew, you'll still need
+ to install the DocBook DTD and stylesheets, and set up a catalog
+ file that points to them.
+ </p></div><div class="sect2" id="DOCGUIDE-TOOLSETS-CONFIGURE"><div class="titlepage"><div><div><h3 class="title">J.2.5. Detection by <code class="command">configure</code></h3></div></div></div><p>
+ Before you can build the documentation you need to run the
+ <code class="filename">configure</code> script, as you would when building
+ the <span class="productname">PostgreSQL</span> programs themselves.
+ Check the output near the end of the run; it should look something
+ like this:
+</p><pre class="screen">
+checking for xmllint... xmllint
+checking for xsltproc... xsltproc
+checking for fop... fop
+checking for dbtoepub... dbtoepub
+</pre><p>
+ If <code class="filename">xmllint</code> or <code class="filename">xsltproc</code> is not
+ found, you will not be able to build any of the documentation.
+ <code class="filename">fop</code> is only needed to build the documentation in
+ PDF format.
+ <code class="filename">dbtoepub</code> is only needed to build the documentation
+ in EPUB format.
+ </p><p>
+ If necessary, you can tell <code class="filename">configure</code> where to find
+ these programs, for example
+</p><pre class="screen">
+./configure ... XMLLINT=/opt/local/bin/xmllint ...
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="docguide-docbook.html" title="J.1. DocBook">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="docguide.html" title="Appendix J. Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="docguide-build.html" title="J.3. Building the Documentation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">J.1. DocBook </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> J.3. Building the Documentation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/docguide.html b/doc/src/sgml/html/docguide.html
new file mode 100644
index 0000000..3197237
--- /dev/null
+++ b/doc/src/sgml/html/docguide.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix J. Documentation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="git.html" title="I.1. Getting the Source via Git" /><link rel="next" href="docguide-docbook.html" title="J.1. DocBook" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix J. Documentation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="git.html" title="I.1. Getting the Source via Git">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="docguide-docbook.html" title="J.1. DocBook">Next</a></td></tr></table><hr /></div><div class="appendix" id="DOCGUIDE"><div class="titlepage"><div><div><h2 class="title">Appendix J. Documentation</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="docguide-docbook.html">J.1. DocBook</a></span></dt><dt><span class="sect1"><a href="docguide-toolsets.html">J.2. Tool Sets</a></span></dt><dd><dl><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.4">J.2.1. Installation on Fedora, RHEL, and Derivatives</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.5">J.2.2. Installation on FreeBSD</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.6">J.2.3. Debian Packages</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#id-1.11.11.5.7">J.2.4. macOS</a></span></dt><dt><span class="sect2"><a href="docguide-toolsets.html#DOCGUIDE-TOOLSETS-CONFIGURE">J.2.5. Detection by <code class="command">configure</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="docguide-build.html">J.3. Building the Documentation</a></span></dt><dd><dl><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.3">J.3.1. HTML</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.4">J.3.2. Manpages</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.5">J.3.3. PDF</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.6">J.3.4. Plain Text Files</a></span></dt><dt><span class="sect2"><a href="docguide-build.html#id-1.11.11.6.7">J.3.5. Syntax Check</a></span></dt></dl></dd><dt><span class="sect1"><a href="docguide-authoring.html">J.4. Documentation Authoring</a></span></dt><dd><dl><dt><span class="sect2"><a href="docguide-authoring.html#id-1.11.11.7.4">J.4.1. Emacs</a></span></dt></dl></dd><dt><span class="sect1"><a href="docguide-style.html">J.5. Style Guide</a></span></dt><dd><dl><dt><span class="sect2"><a href="docguide-style.html#id-1.11.11.8.2">J.5.1. Reference Pages</a></span></dt></dl></dd></dl></div><p>
+ <span class="productname">PostgreSQL</span> has four primary documentation
+ formats:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Plain text, for pre-installation information
+ </p></li><li class="listitem"><p>
+ <acronym class="acronym">HTML</acronym>, for on-line browsing and reference
+ </p></li><li class="listitem"><p>
+ PDF, for printing
+ </p></li><li class="listitem"><p>
+ man pages, for quick reference.
+ </p></li></ul></div><p>
+
+ Additionally, a number of plain-text <code class="filename">README</code> files can
+ be found throughout the <span class="productname">PostgreSQL</span> source tree,
+ documenting various implementation issues.
+ </p><p>
+ <acronym class="acronym">HTML</acronym> documentation and man pages are part of a
+ standard distribution and are installed by default. PDF
+ format documentation is available separately for
+ download.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="git.html" title="I.1. Getting the Source via Git">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="docguide-docbook.html" title="J.1. DocBook">Next</a></td></tr><tr><td width="40%" align="left" valign="top">I.1. Getting the Source via <span class="productname">Git</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> J.1. DocBook</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/domains.html b/doc/src/sgml/html/domains.html
new file mode 100644
index 0000000..b247c04
--- /dev/null
+++ b/doc/src/sgml/html/domains.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.18. Domain Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rangetypes.html" title="8.17. Range Types" /><link rel="next" href="datatype-oid.html" title="8.19. Object Identifier Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.18. Domain Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rangetypes.html" title="8.17. Range Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype-oid.html" title="8.19. Object Identifier Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="DOMAINS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.18. Domain Types</h2></div></div></div><a id="id-1.5.7.26.2" class="indexterm"></a><a id="id-1.5.7.26.3" class="indexterm"></a><p>
+ A <em class="firstterm">domain</em> is a user-defined data type that is
+ based on another <em class="firstterm">underlying type</em>. Optionally,
+ it can have constraints that restrict its valid values to a subset of
+ what the underlying type would allow. Otherwise it behaves like the
+ underlying type — for example, any operator or function that
+ can be applied to the underlying type will work on the domain type.
+ The underlying type can be any built-in or user-defined base type,
+ enum type, array type, composite type, range type, or another domain.
+ </p><p>
+ For example, we could create a domain over integers that accepts only
+ positive integers:
+</p><pre class="programlisting">
+CREATE DOMAIN posint AS integer CHECK (VALUE &gt; 0);
+CREATE TABLE mytable (id posint);
+INSERT INTO mytable VALUES(1); -- works
+INSERT INTO mytable VALUES(-1); -- fails
+</pre><p>
+ </p><p>
+ When an operator or function of the underlying type is applied to a
+ domain value, the domain is automatically down-cast to the underlying
+ type. Thus, for example, the result of <code class="literal">mytable.id - 1</code>
+ is considered to be of type <code class="type">integer</code> not <code class="type">posint</code>.
+ We could write <code class="literal">(mytable.id - 1)::posint</code> to cast the
+ result back to <code class="type">posint</code>, causing the domain's constraints
+ to be rechecked. In this case, that would result in an error if the
+ expression had been applied to an <code class="structfield">id</code> value of
+ 1. Assigning a value of the underlying type to a field or variable of
+ the domain type is allowed without writing an explicit cast, but the
+ domain's constraints will be checked.
+ </p><p>
+ For additional information see <a class="xref" href="sql-createdomain.html" title="CREATE DOMAIN"><span class="refentrytitle">CREATE DOMAIN</span></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rangetypes.html" title="8.17. Range Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype-oid.html" title="8.19. Object Identifier Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.17. Range Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.19. Object Identifier Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/dynamic-trace.html b/doc/src/sgml/html/dynamic-trace.html
new file mode 100644
index 0000000..2063f7f
--- /dev/null
+++ b/doc/src/sgml/html/dynamic-trace.html
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>28.5. Dynamic Tracing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="progress-reporting.html" title="28.4. Progress Reporting" /><link rel="next" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">28.5. Dynamic Tracing</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="progress-reporting.html" title="28.4. Progress Reporting">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><th width="60%" align="center">Chapter 28. Monitoring Database Activity</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="DYNAMIC-TRACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">28.5. Dynamic Tracing</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="dynamic-trace.html#COMPILING-FOR-TRACE">28.5.1. Compiling for Dynamic Tracing</a></span></dt><dt><span class="sect2"><a href="dynamic-trace.html#TRACE-POINTS">28.5.2. Built-in Probes</a></span></dt><dt><span class="sect2"><a href="dynamic-trace.html#USING-TRACE-POINTS">28.5.3. Using Probes</a></span></dt><dt><span class="sect2"><a href="dynamic-trace.html#DEFINING-TRACE-POINTS">28.5.4. Defining New Probes</a></span></dt></dl></div><a id="id-1.6.15.10.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides facilities to support
+ dynamic tracing of the database server. This allows an external
+ utility to be called at specific points in the code and thereby trace
+ execution.
+ </p><p>
+ A number of probes or trace points are already inserted into the source
+ code. These probes are intended to be used by database developers and
+ administrators. By default the probes are not compiled into
+ <span class="productname">PostgreSQL</span>; the user needs to explicitly tell
+ the configure script to make the probes available.
+ </p><p>
+ Currently, the
+ <a class="ulink" href="https://en.wikipedia.org/wiki/DTrace" target="_top">DTrace</a>
+ utility is supported, which, at the time of this writing, is available
+ on Solaris, macOS, FreeBSD, NetBSD, and Oracle Linux. The
+ <a class="ulink" href="https://sourceware.org/systemtap/" target="_top">SystemTap</a> project
+ for Linux provides a DTrace equivalent and can also be used. Supporting other dynamic
+ tracing utilities is theoretically possible by changing the definitions for
+ the macros in <code class="filename">src/include/utils/probes.h</code>.
+ </p><div class="sect2" id="COMPILING-FOR-TRACE"><div class="titlepage"><div><div><h3 class="title">28.5.1. Compiling for Dynamic Tracing</h3></div></div></div><p>
+ By default, probes are not available, so you will need to
+ explicitly tell the configure script to make the probes available
+ in <span class="productname">PostgreSQL</span>. To include DTrace support
+ specify <code class="option">--enable-dtrace</code> to configure. See <a class="xref" href="install-procedure.html" title="17.4. Installation Procedure">Section 17.4</a> for further information.
+ </p></div><div class="sect2" id="TRACE-POINTS"><div class="titlepage"><div><div><h3 class="title">28.5.2. Built-in Probes</h3></div></div></div><p>
+ A number of standard probes are provided in the source code,
+ as shown in <a class="xref" href="dynamic-trace.html#DTRACE-PROBE-POINT-TABLE" title="Table 28.47. Built-in DTrace Probes">Table 28.47</a>;
+ <a class="xref" href="dynamic-trace.html#TYPEDEFS-TABLE" title="Table 28.48. Defined Types Used in Probe Parameters">Table 28.48</a>
+ shows the types used in the probes. More probes can certainly be
+ added to enhance <span class="productname">PostgreSQL</span>'s observability.
+ </p><div class="table" id="DTRACE-PROBE-POINT-TABLE"><p class="title"><strong>Table 28.47. Built-in DTrace Probes</strong></p><div class="table-contents"><table class="table" summary="Built-in DTrace Probes" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Parameters</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">transaction-start</code></td><td><code class="literal">(LocalTransactionId)</code></td><td>Probe that fires at the start of a new transaction.
+ arg0 is the transaction ID.</td></tr><tr><td><code class="literal">transaction-commit</code></td><td><code class="literal">(LocalTransactionId)</code></td><td>Probe that fires when a transaction completes successfully.
+ arg0 is the transaction ID.</td></tr><tr><td><code class="literal">transaction-abort</code></td><td><code class="literal">(LocalTransactionId)</code></td><td>Probe that fires when a transaction completes unsuccessfully.
+ arg0 is the transaction ID.</td></tr><tr><td><code class="literal">query-start</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires when the processing of a query is started.
+ arg0 is the query string.</td></tr><tr><td><code class="literal">query-done</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires when the processing of a query is complete.
+ arg0 is the query string.</td></tr><tr><td><code class="literal">query-parse-start</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires when the parsing of a query is started.
+ arg0 is the query string.</td></tr><tr><td><code class="literal">query-parse-done</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires when the parsing of a query is complete.
+ arg0 is the query string.</td></tr><tr><td><code class="literal">query-rewrite-start</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires when the rewriting of a query is started.
+ arg0 is the query string.</td></tr><tr><td><code class="literal">query-rewrite-done</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires when the rewriting of a query is complete.
+ arg0 is the query string.</td></tr><tr><td><code class="literal">query-plan-start</code></td><td><code class="literal">()</code></td><td>Probe that fires when the planning of a query is started.</td></tr><tr><td><code class="literal">query-plan-done</code></td><td><code class="literal">()</code></td><td>Probe that fires when the planning of a query is complete.</td></tr><tr><td><code class="literal">query-execute-start</code></td><td><code class="literal">()</code></td><td>Probe that fires when the execution of a query is started.</td></tr><tr><td><code class="literal">query-execute-done</code></td><td><code class="literal">()</code></td><td>Probe that fires when the execution of a query is complete.</td></tr><tr><td><code class="literal">statement-status</code></td><td><code class="literal">(const char *)</code></td><td>Probe that fires anytime the server process updates its
+ <code class="structname">pg_stat_activity</code>.<code class="structfield">status</code>.
+ arg0 is the new status string.</td></tr><tr><td><code class="literal">checkpoint-start</code></td><td><code class="literal">(int)</code></td><td>Probe that fires when a checkpoint is started.
+ arg0 holds the bitwise flags used to distinguish different checkpoint
+ types, such as shutdown, immediate or force.</td></tr><tr><td><code class="literal">checkpoint-done</code></td><td><code class="literal">(int, int, int, int, int)</code></td><td>Probe that fires when a checkpoint is complete.
+ (The probes listed next fire in sequence during checkpoint processing.)
+ arg0 is the number of buffers written. arg1 is the total number of
+ buffers. arg2, arg3 and arg4 contain the number of WAL files added,
+ removed and recycled respectively.</td></tr><tr><td><code class="literal">clog-checkpoint-start</code></td><td><code class="literal">(bool)</code></td><td>Probe that fires when the CLOG portion of a checkpoint is started.
+ arg0 is true for normal checkpoint, false for shutdown
+ checkpoint.</td></tr><tr><td><code class="literal">clog-checkpoint-done</code></td><td><code class="literal">(bool)</code></td><td>Probe that fires when the CLOG portion of a checkpoint is
+ complete. arg0 has the same meaning as for <code class="literal">clog-checkpoint-start</code>.</td></tr><tr><td><code class="literal">subtrans-checkpoint-start</code></td><td><code class="literal">(bool)</code></td><td>Probe that fires when the SUBTRANS portion of a checkpoint is
+ started.
+ arg0 is true for normal checkpoint, false for shutdown
+ checkpoint.</td></tr><tr><td><code class="literal">subtrans-checkpoint-done</code></td><td><code class="literal">(bool)</code></td><td>Probe that fires when the SUBTRANS portion of a checkpoint is
+ complete. arg0 has the same meaning as for
+ <code class="literal">subtrans-checkpoint-start</code>.</td></tr><tr><td><code class="literal">multixact-checkpoint-start</code></td><td><code class="literal">(bool)</code></td><td>Probe that fires when the MultiXact portion of a checkpoint is
+ started.
+ arg0 is true for normal checkpoint, false for shutdown
+ checkpoint.</td></tr><tr><td><code class="literal">multixact-checkpoint-done</code></td><td><code class="literal">(bool)</code></td><td>Probe that fires when the MultiXact portion of a checkpoint is
+ complete. arg0 has the same meaning as for
+ <code class="literal">multixact-checkpoint-start</code>.</td></tr><tr><td><code class="literal">buffer-checkpoint-start</code></td><td><code class="literal">(int)</code></td><td>Probe that fires when the buffer-writing portion of a checkpoint
+ is started.
+ arg0 holds the bitwise flags used to distinguish different checkpoint
+ types, such as shutdown, immediate or force.</td></tr><tr><td><code class="literal">buffer-sync-start</code></td><td><code class="literal">(int, int)</code></td><td>Probe that fires when we begin to write dirty buffers during
+ checkpoint (after identifying which buffers must be written).
+ arg0 is the total number of buffers.
+ arg1 is the number that are currently dirty and need to be written.</td></tr><tr><td><code class="literal">buffer-sync-written</code></td><td><code class="literal">(int)</code></td><td>Probe that fires after each buffer is written during checkpoint.
+ arg0 is the ID number of the buffer.</td></tr><tr><td><code class="literal">buffer-sync-done</code></td><td><code class="literal">(int, int, int)</code></td><td>Probe that fires when all dirty buffers have been written.
+ arg0 is the total number of buffers.
+ arg1 is the number of buffers actually written by the checkpoint process.
+ arg2 is the number that were expected to be written (arg1 of
+ <code class="literal">buffer-sync-start</code>); any difference reflects other processes flushing
+ buffers during the checkpoint.</td></tr><tr><td><code class="literal">buffer-checkpoint-sync-start</code></td><td><code class="literal">()</code></td><td>Probe that fires after dirty buffers have been written to the
+ kernel, and before starting to issue fsync requests.</td></tr><tr><td><code class="literal">buffer-checkpoint-done</code></td><td><code class="literal">()</code></td><td>Probe that fires when syncing of buffers to disk is
+ complete.</td></tr><tr><td><code class="literal">twophase-checkpoint-start</code></td><td><code class="literal">()</code></td><td>Probe that fires when the two-phase portion of a checkpoint is
+ started.</td></tr><tr><td><code class="literal">twophase-checkpoint-done</code></td><td><code class="literal">()</code></td><td>Probe that fires when the two-phase portion of a checkpoint is
+ complete.</td></tr><tr><td><code class="literal">buffer-read-start</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool)</code></td><td>Probe that fires when a buffer read is started.
+ arg0 and arg1 contain the fork and block numbers of the page (but
+ arg1 will be -1 if this is a relation extension request).
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <code class="symbol">InvalidBackendId</code> (-1) for a shared buffer.
+ arg6 is true for a relation extension request, false for normal
+ read.</td></tr><tr><td><code class="literal">buffer-read-done</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool)</code></td><td>Probe that fires when a buffer read is complete.
+ arg0 and arg1 contain the fork and block numbers of the page (if this
+ is a relation extension request, arg1 now contains the block number
+ of the newly added block).
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <code class="symbol">InvalidBackendId</code> (-1) for a shared buffer.
+ arg6 is true for a relation extension request, false for normal
+ read.
+ arg7 is true if the buffer was found in the pool, false if not.</td></tr><tr><td><code class="literal">buffer-flush-start</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid)</code></td><td>Probe that fires before issuing any write request for a shared
+ buffer.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.</td></tr><tr><td><code class="literal">buffer-flush-done</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid)</code></td><td>Probe that fires when a write request is complete. (Note
+ that this just reflects the time to pass the data to the kernel;
+ it's typically not actually been written to disk yet.)
+ The arguments are the same as for <code class="literal">buffer-flush-start</code>.</td></tr><tr><td><code class="literal">buffer-write-dirty-start</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid)</code></td><td>Probe that fires when a server process begins to write a dirty
+ buffer. (If this happens often, it implies that
+ <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a> is too
+ small or the background writer control parameters need adjustment.)
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.</td></tr><tr><td><code class="literal">buffer-write-dirty-done</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid)</code></td><td>Probe that fires when a dirty-buffer write is complete.
+ The arguments are the same as for <code class="literal">buffer-write-dirty-start</code>.</td></tr><tr><td><code class="literal">wal-buffer-write-dirty-start</code></td><td><code class="literal">()</code></td><td>Probe that fires when a server process begins to write a
+ dirty WAL buffer because no more WAL buffer space is available.
+ (If this happens often, it implies that
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-BUFFERS">wal_buffers</a> is too small.)</td></tr><tr><td><code class="literal">wal-buffer-write-dirty-done</code></td><td><code class="literal">()</code></td><td>Probe that fires when a dirty WAL buffer write is complete.</td></tr><tr><td><code class="literal">wal-insert</code></td><td><code class="literal">(unsigned char, unsigned char)</code></td><td>Probe that fires when a WAL record is inserted.
+ arg0 is the resource manager (rmid) for the record.
+ arg1 contains the info flags.</td></tr><tr><td><code class="literal">wal-switch</code></td><td><code class="literal">()</code></td><td>Probe that fires when a WAL segment switch is requested.</td></tr><tr><td><code class="literal">smgr-md-read-start</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid, int)</code></td><td>Probe that fires when beginning to read a block from a relation.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <code class="symbol">InvalidBackendId</code> (-1) for a shared buffer.</td></tr><tr><td><code class="literal">smgr-md-read-done</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int)</code></td><td>Probe that fires when a block read is complete.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <code class="symbol">InvalidBackendId</code> (-1) for a shared buffer.
+ arg6 is the number of bytes actually read, while arg7 is the number
+ requested (if these are different it indicates trouble).</td></tr><tr><td><code class="literal">smgr-md-write-start</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid, int)</code></td><td>Probe that fires when beginning to write a block to a relation.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <code class="symbol">InvalidBackendId</code> (-1) for a shared buffer.</td></tr><tr><td><code class="literal">smgr-md-write-done</code></td><td><code class="literal">(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int)</code></td><td>Probe that fires when a block write is complete.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <code class="symbol">InvalidBackendId</code> (-1) for a shared buffer.
+ arg6 is the number of bytes actually written, while arg7 is the number
+ requested (if these are different it indicates trouble).</td></tr><tr><td><code class="literal">sort-start</code></td><td><code class="literal">(int, bool, int, int, bool, int)</code></td><td>Probe that fires when a sort operation is started.
+ arg0 indicates heap, index or datum sort.
+ arg1 is true for unique-value enforcement.
+ arg2 is the number of key columns.
+ arg3 is the number of kilobytes of work memory allowed.
+ arg4 is true if random access to the sort result is required.
+ arg5 indicates serial when <code class="literal">0</code>, parallel worker when
+ <code class="literal">1</code>, or parallel leader when <code class="literal">2</code>.</td></tr><tr><td><code class="literal">sort-done</code></td><td><code class="literal">(bool, long)</code></td><td>Probe that fires when a sort is complete.
+ arg0 is true for external sort, false for internal sort.
+ arg1 is the number of disk blocks used for an external sort,
+ or kilobytes of memory used for an internal sort.</td></tr><tr><td><code class="literal">lwlock-acquire</code></td><td><code class="literal">(char *, LWLockMode)</code></td><td>Probe that fires when an LWLock has been acquired.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</td></tr><tr><td><code class="literal">lwlock-release</code></td><td><code class="literal">(char *)</code></td><td>Probe that fires when an LWLock has been released (but note
+ that any released waiters have not yet been awakened).
+ arg0 is the LWLock's tranche.</td></tr><tr><td><code class="literal">lwlock-wait-start</code></td><td><code class="literal">(char *, LWLockMode)</code></td><td>Probe that fires when an LWLock was not immediately available and
+ a server process has begun to wait for the lock to become available.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</td></tr><tr><td><code class="literal">lwlock-wait-done</code></td><td><code class="literal">(char *, LWLockMode)</code></td><td>Probe that fires when a server process has been released from its
+ wait for an LWLock (it does not actually have the lock yet).
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</td></tr><tr><td><code class="literal">lwlock-condacquire</code></td><td><code class="literal">(char *, LWLockMode)</code></td><td>Probe that fires when an LWLock was successfully acquired when the
+ caller specified no waiting.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</td></tr><tr><td><code class="literal">lwlock-condacquire-fail</code></td><td><code class="literal">(char *, LWLockMode)</code></td><td>Probe that fires when an LWLock was not successfully acquired when
+ the caller specified no waiting.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</td></tr><tr><td><code class="literal">lock-wait-start</code></td><td><code class="literal">(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE)</code></td><td>Probe that fires when a request for a heavyweight lock (lmgr lock)
+ has begun to wait because the lock is not available.
+ arg0 through arg3 are the tag fields identifying the object being
+ locked. arg4 indicates the type of object being locked.
+ arg5 indicates the lock type being requested.</td></tr><tr><td><code class="literal">lock-wait-done</code></td><td><code class="literal">(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE)</code></td><td>Probe that fires when a request for a heavyweight lock (lmgr lock)
+ has finished waiting (i.e., has acquired the lock).
+ The arguments are the same as for <code class="literal">lock-wait-start</code>.</td></tr><tr><td><code class="literal">deadlock-found</code></td><td><code class="literal">()</code></td><td>Probe that fires when a deadlock is found by the deadlock
+ detector.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="TYPEDEFS-TABLE"><p class="title"><strong>Table 28.48. Defined Types Used in Probe Parameters</strong></p><div class="table-contents"><table class="table" summary="Defined Types Used in Probe Parameters" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Type</th><th>Definition</th></tr></thead><tbody><tr><td><code class="type">LocalTransactionId</code></td><td><code class="type">unsigned int</code></td></tr><tr><td><code class="type">LWLockMode</code></td><td><code class="type">int</code></td></tr><tr><td><code class="type">LOCKMODE</code></td><td><code class="type">int</code></td></tr><tr><td><code class="type">BlockNumber</code></td><td><code class="type">unsigned int</code></td></tr><tr><td><code class="type">Oid</code></td><td><code class="type">unsigned int</code></td></tr><tr><td><code class="type">ForkNumber</code></td><td><code class="type">int</code></td></tr><tr><td><code class="type">bool</code></td><td><code class="type">unsigned char</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="USING-TRACE-POINTS"><div class="titlepage"><div><div><h3 class="title">28.5.3. Using Probes</h3></div></div></div><p>
+ The example below shows a DTrace script for analyzing transaction
+ counts in the system, as an alternative to snapshotting
+ <code class="structname">pg_stat_database</code> before and after a performance test:
+</p><pre class="programlisting">
+#!/usr/sbin/dtrace -qs
+
+postgresql$1:::transaction-start
+{
+ @start["Start"] = count();
+ self-&gt;ts = timestamp;
+}
+
+postgresql$1:::transaction-abort
+{
+ @abort["Abort"] = count();
+}
+
+postgresql$1:::transaction-commit
+/self-&gt;ts/
+{
+ @commit["Commit"] = count();
+ @time["Total time (ns)"] = sum(timestamp - self-&gt;ts);
+ self-&gt;ts=0;
+}
+</pre><p>
+ When executed, the example D script gives output such as:
+</p><pre class="screen">
+# ./txn_count.d `pgrep -n postgres` or ./txn_count.d &lt;PID&gt;
+^C
+
+Start 71
+Commit 70
+Total time (ns) 2312105013
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ SystemTap uses a different notation for trace scripts than DTrace does,
+ even though the underlying trace points are compatible. One point worth
+ noting is that at this writing, SystemTap scripts must reference probe
+ names using double underscores in place of hyphens. This is expected to
+ be fixed in future SystemTap releases.
+ </p></div><p>
+ You should remember that DTrace scripts need to be carefully written and
+ debugged, otherwise the trace information collected might
+ be meaningless. In most cases where problems are found it is the
+ instrumentation that is at fault, not the underlying system. When
+ discussing information found using dynamic tracing, be sure to enclose
+ the script used to allow that too to be checked and discussed.
+ </p></div><div class="sect2" id="DEFINING-TRACE-POINTS"><div class="titlepage"><div><div><h3 class="title">28.5.4. Defining New Probes</h3></div></div></div><p>
+ New probes can be defined within the code wherever the developer
+ desires, though this will require a recompilation. Below are the steps
+ for inserting new probes:
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p>
+ Decide on probe names and data to be made available through the probes
+ </p></li><li class="step"><p>
+ Add the probe definitions to <code class="filename">src/backend/utils/probes.d</code>
+ </p></li><li class="step"><p>
+ Include <code class="filename">pg_trace.h</code> if it is not already present in the
+ module(s) containing the probe points, and insert
+ <code class="literal">TRACE_POSTGRESQL</code> probe macros at the desired locations
+ in the source code
+ </p></li><li class="step"><p>
+ Recompile and verify that the new probes are available
+ </p></li></ol></div><p><strong>Example: </strong>
+ Here is an example of how you would add a probe to trace all new
+ transactions by transaction ID.
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p>
+ Decide that the probe will be named <code class="literal">transaction-start</code> and
+ requires a parameter of type <code class="type">LocalTransactionId</code>
+ </p></li><li class="step"><p>
+ Add the probe definition to <code class="filename">src/backend/utils/probes.d</code>:
+</p><pre class="programlisting">
+probe transaction__start(LocalTransactionId);
+</pre><p>
+ Note the use of the double underline in the probe name. In a DTrace
+ script using the probe, the double underline needs to be replaced with a
+ hyphen, so <code class="literal">transaction-start</code> is the name to document for
+ users.
+ </p></li><li class="step"><p>
+ At compile time, <code class="literal">transaction__start</code> is converted to a macro
+ called <code class="literal">TRACE_POSTGRESQL_TRANSACTION_START</code> (notice the
+ underscores are single here), which is available by including
+ <code class="filename">pg_trace.h</code>. Add the macro call to the appropriate location
+ in the source code. In this case, it looks like the following:
+
+</p><pre class="programlisting">
+TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
+</pre><p>
+ </p></li><li class="step"><p>
+ After recompiling and running the new binary, check that your newly added
+ probe is available by executing the following DTrace command. You
+ should see similar output:
+</p><pre class="screen">
+# dtrace -ln transaction-start
+ ID PROVIDER MODULE FUNCTION NAME
+18705 postgresql49878 postgres StartTransactionCommand transaction-start
+18755 postgresql49877 postgres StartTransactionCommand transaction-start
+18805 postgresql49876 postgres StartTransactionCommand transaction-start
+18855 postgresql49875 postgres StartTransactionCommand transaction-start
+18986 postgresql49873 postgres StartTransactionCommand transaction-start
+</pre><p>
+ </p></li></ol></div><p>
+ There are a few things to be careful about when adding trace macros
+ to the C code:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ You should take care that the data types specified for a probe's
+ parameters match the data types of the variables used in the macro.
+ Otherwise, you will get compilation errors.
+ </p></li><li class="listitem"><p>
+ On most platforms, if <span class="productname">PostgreSQL</span> is
+ built with <code class="option">--enable-dtrace</code>, the arguments to a trace
+ macro will be evaluated whenever control passes through the
+ macro, <span class="emphasis"><em>even if no tracing is being done</em></span>. This is
+ usually not worth worrying about if you are just reporting the
+ values of a few local variables. But beware of putting expensive
+ function calls into the arguments. If you need to do that,
+ consider protecting the macro with a check to see if the trace
+ is actually enabled:
+
+</p><pre class="programlisting">
+if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED())
+ TRACE_POSTGRESQL_TRANSACTION_START(some_function(...));
+</pre><p>
+
+ Each trace macro has a corresponding <code class="literal">ENABLED</code> macro.
+ </p></li></ul></div><p>
+
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="progress-reporting.html" title="28.4. Progress Reporting">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="diskusage.html" title="Chapter 29. Monitoring Disk Usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">28.4. Progress Reporting </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 29. Monitoring Disk Usage</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/earthdistance.html b/doc/src/sgml/html/earthdistance.html
new file mode 100644
index 0000000..bfe2962
--- /dev/null
+++ b/doc/src/sgml/html/earthdistance.html
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.15. earthdistance</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dict-xsyn.html" title="F.14. dict_xsyn" /><link rel="next" href="file-fdw.html" title="F.16. file_fdw" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.15. earthdistance</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dict-xsyn.html" title="F.14. dict_xsyn">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="file-fdw.html" title="F.16. file_fdw">Next</a></td></tr></table><hr /></div><div class="sect1" id="EARTHDISTANCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.15. earthdistance</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="earthdistance.html#id-1.11.7.24.7">F.15.1. Cube-Based Earth Distances</a></span></dt><dt><span class="sect2"><a href="earthdistance.html#id-1.11.7.24.8">F.15.2. Point-Based Earth Distances</a></span></dt></dl></div><a id="id-1.11.7.24.2" class="indexterm"></a><p>
+ The <code class="filename">earthdistance</code> module provides two different approaches to
+ calculating great circle distances on the surface of the Earth. The one
+ described first depends on the <code class="filename">cube</code> module.
+ The second one is based on the built-in <code class="type">point</code> data type,
+ using longitude and latitude for the coordinates.
+ </p><p>
+ In this module, the Earth is assumed to be perfectly spherical.
+ (If that's too inaccurate for you, you might want to look at the
+ <span class="application"><a class="ulink" href="https://postgis.net/" target="_top">PostGIS</a></span>
+ project.)
+ </p><p>
+ The <code class="filename">cube</code> module must be installed
+ before <code class="filename">earthdistance</code> can be installed
+ (although you can use the <code class="literal">CASCADE</code> option
+ of <code class="command">CREATE EXTENSION</code> to install both in one command).
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is strongly recommended that <code class="filename">earthdistance</code>
+ and <code class="filename">cube</code> be installed in the same schema, and that
+ that schema be one for which CREATE privilege has not been and will not
+ be granted to any untrusted users.
+ Otherwise there are installation-time security hazards
+ if <code class="filename">earthdistance</code>'s schema contains objects defined
+ by a hostile user.
+ Furthermore, when using <code class="filename">earthdistance</code>'s functions
+ after installation, the entire search path should contain only trusted
+ schemas.
+ </p></div><div class="sect2" id="id-1.11.7.24.7"><div class="titlepage"><div><div><h3 class="title">F.15.1. Cube-Based Earth Distances</h3></div></div></div><p>
+ Data is stored in cubes that are points (both corners are the same) using 3
+ coordinates representing the x, y, and z distance from the center of the
+ Earth. A <a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN" title="Domain">domain</a></em></a>
+ <code class="type">earth</code> over type <code class="type">cube</code> is provided, which
+ includes constraint checks that the value meets these restrictions and
+ is reasonably close to the actual surface of the Earth.
+ </p><p>
+ The radius of the Earth is obtained from the <code class="function">earth()</code>
+ function. It is given in meters. But by changing this one function you can
+ change the module to use some other units, or to use a different value of
+ the radius that you feel is more appropriate.
+ </p><p>
+ This package has applications to astronomical databases as well.
+ Astronomers will probably want to change <code class="function">earth()</code> to return a
+ radius of <code class="literal">180/pi()</code> so that distances are in degrees.
+ </p><p>
+ Functions are provided to support input in latitude and longitude (in
+ degrees), to support output of latitude and longitude, to calculate
+ the great circle distance between two points and to easily specify a
+ bounding box usable for index searches.
+ </p><p>
+ The provided functions are shown
+ in <a class="xref" href="earthdistance.html#EARTHDISTANCE-CUBE-FUNCTIONS" title="Table F.5. Cube-Based Earthdistance Functions">Table F.5</a>.
+ </p><div class="table" id="EARTHDISTANCE-CUBE-FUNCTIONS"><p class="title"><strong>Table F.5. Cube-Based Earthdistance Functions</strong></p><div class="table-contents"><table class="table" summary="Cube-Based Earthdistance Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">earth</code> ()
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the assumed radius of the Earth.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">sec_to_gc</code> ( <code class="type">float8</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Converts the normal straight line
+ (secant) distance between two points on the surface of the Earth
+ to the great circle distance between them.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">gc_to_sec</code> ( <code class="type">float8</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Converts the great circle distance between two points on the
+ surface of the Earth to the normal straight line (secant) distance
+ between them.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">ll_to_earth</code> ( <code class="type">float8</code>, <code class="type">float8</code> )
+ → <code class="returnvalue">earth</code>
+ </p>
+ <p>
+ Returns the location of a point on the surface of the Earth given
+ its latitude (argument 1) and longitude (argument 2) in degrees.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">latitude</code> ( <code class="type">earth</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the latitude in degrees of a point on the surface of the
+ Earth.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">longitude</code> ( <code class="type">earth</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the longitude in degrees of a point on the surface of the
+ Earth.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">earth_distance</code> ( <code class="type">earth</code>, <code class="type">earth</code> )
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Returns the great circle distance between two points on the
+ surface of the Earth.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.24.7.7.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">earth_box</code> ( <code class="type">earth</code>, <code class="type">float8</code> )
+ → <code class="returnvalue">cube</code>
+ </p>
+ <p>
+ Returns a box suitable for an indexed search using the <code class="type">cube</code>
+ <code class="literal">@&gt;</code>
+ operator for points within a given great circle distance of a location.
+ Some points in this box are further than the specified great circle
+ distance from the location, so a second check using
+ <code class="function">earth_distance</code> should be included in the query.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.24.8"><div class="titlepage"><div><div><h3 class="title">F.15.2. Point-Based Earth Distances</h3></div></div></div><p>
+ The second part of the module relies on representing Earth locations as
+ values of type <code class="type">point</code>, in which the first component is taken to
+ represent longitude in degrees, and the second component is taken to
+ represent latitude in degrees. Points are taken as (longitude, latitude)
+ and not vice versa because longitude is closer to the intuitive idea of
+ x-axis and latitude to y-axis.
+ </p><p>
+ A single operator is provided, shown
+ in <a class="xref" href="earthdistance.html#EARTHDISTANCE-POINT-OPERATORS" title="Table F.6. Point-Based Earthdistance Operators">Table F.6</a>.
+ </p><div class="table" id="EARTHDISTANCE-POINT-OPERATORS"><p class="title"><strong>Table F.6. Point-Based Earthdistance Operators</strong></p><div class="table-contents"><table class="table" summary="Point-Based Earthdistance Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">point</code> <code class="literal">&lt;@&gt;</code> <code class="type">point</code>
+ → <code class="returnvalue">float8</code>
+ </p>
+ <p>
+ Computes the distance in statute miles between
+ two points on the Earth's surface.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Note that unlike the <code class="type">cube</code>-based part of the module, units
+ are hardwired here: changing the <code class="function">earth()</code> function will
+ not affect the results of this operator.
+ </p><p>
+ One disadvantage of the longitude/latitude representation is that
+ you need to be careful about the edge conditions near the poles
+ and near +/- 180 degrees of longitude. The <code class="type">cube</code>-based
+ representation avoids these discontinuities.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dict-xsyn.html" title="F.14. dict_xsyn">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="file-fdw.html" title="F.16. file_fdw">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.14. dict_xsyn </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.16. file_fdw</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-commands.html b/doc/src/sgml/html/ecpg-commands.html
new file mode 100644
index 0000000..f70a5fa
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-commands.html
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.3. Running SQL Commands</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-connect.html" title="36.2. Managing Database Connections" /><link rel="next" href="ecpg-variables.html" title="36.4. Using Host Variables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.3. Running SQL Commands</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-connect.html" title="36.2. Managing Database Connections">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-variables.html" title="36.4. Using Host Variables">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-COMMANDS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.3. Running SQL Commands</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-EXECUTING">36.3.1. Executing SQL Statements</a></span></dt><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-CURSORS">36.3.2. Using Cursors</a></span></dt><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-TRANSACTIONS">36.3.3. Managing Transactions</a></span></dt><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-PREPARED">36.3.4. Prepared Statements</a></span></dt></dl></div><p>
+ Any SQL command can be run from within an embedded SQL application.
+ Below are some examples of how to do that.
+ </p><div class="sect2" id="ECPG-EXECUTING"><div class="titlepage"><div><div><h3 class="title">36.3.1. Executing SQL Statements</h3></div></div></div><p>
+ Creating a table:
+</p><pre class="programlisting">
+EXEC SQL CREATE TABLE foo (number integer, ascii char(16));
+EXEC SQL CREATE UNIQUE INDEX num1 ON foo(number);
+EXEC SQL COMMIT;
+</pre><p>
+ </p><p>
+ Inserting rows:
+</p><pre class="programlisting">
+EXEC SQL INSERT INTO foo (number, ascii) VALUES (9999, 'doodad');
+EXEC SQL COMMIT;
+</pre><p>
+ </p><p>
+ Deleting rows:
+</p><pre class="programlisting">
+EXEC SQL DELETE FROM foo WHERE number = 9999;
+EXEC SQL COMMIT;
+</pre><p>
+ </p><p>
+ Updates:
+</p><pre class="programlisting">
+EXEC SQL UPDATE foo
+ SET ascii = 'foobar'
+ WHERE number = 9999;
+EXEC SQL COMMIT;
+</pre><p>
+ </p><p>
+ <code class="literal">SELECT</code> statements that return a single result
+ row can also be executed using
+ <code class="literal">EXEC SQL</code> directly. To handle result sets with
+ multiple rows, an application has to use a cursor;
+ see <a class="xref" href="ecpg-commands.html#ECPG-CURSORS" title="36.3.2. Using Cursors">Section 36.3.2</a> below. (As a special case, an
+ application can fetch multiple rows at once into an array host
+ variable; see <a class="xref" href="ecpg-variables.html#ECPG-VARIABLES-ARRAYS" title="36.4.4.3.1. Arrays">Section 36.4.4.3.1</a>.)
+ </p><p>
+ Single-row select:
+</p><pre class="programlisting">
+EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad';
+</pre><p>
+ </p><p>
+ Also, a configuration parameter can be retrieved with the
+ <code class="literal">SHOW</code> command:
+</p><pre class="programlisting">
+EXEC SQL SHOW search_path INTO :var;
+</pre><p>
+ </p><p>
+ The tokens of the form
+ <code class="literal">:<em class="replaceable"><code>something</code></em></code> are
+ <em class="firstterm">host variables</em>, that is, they refer to
+ variables in the C program. They are explained in <a class="xref" href="ecpg-variables.html" title="36.4. Using Host Variables">Section 36.4</a>.
+ </p></div><div class="sect2" id="ECPG-CURSORS"><div class="titlepage"><div><div><h3 class="title">36.3.2. Using Cursors</h3></div></div></div><p>
+ To retrieve a result set holding multiple rows, an application has
+ to declare a cursor and fetch each row from the cursor. The steps
+ to use a cursor are the following: declare a cursor, open it, fetch
+ a row from the cursor, repeat, and finally close it.
+ </p><p>
+ Select using cursors:
+</p><pre class="programlisting">
+EXEC SQL DECLARE foo_bar CURSOR FOR
+ SELECT number, ascii FROM foo
+ ORDER BY ascii;
+EXEC SQL OPEN foo_bar;
+EXEC SQL FETCH foo_bar INTO :FooBar, DooDad;
+...
+EXEC SQL CLOSE foo_bar;
+EXEC SQL COMMIT;
+</pre><p>
+ </p><p>
+ For more details about declaring a cursor, see <a class="xref" href="ecpg-sql-declare.html" title="DECLARE">DECLARE</a>; for more details about fetching rows from a
+ cursor, see <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The ECPG <code class="command">DECLARE</code> command does not actually
+ cause a statement to be sent to the PostgreSQL backend. The
+ cursor is opened in the backend (using the
+ backend's <code class="command">DECLARE</code> command) at the point when
+ the <code class="command">OPEN</code> command is executed.
+ </p></div></div><div class="sect2" id="ECPG-TRANSACTIONS"><div class="titlepage"><div><div><h3 class="title">36.3.3. Managing Transactions</h3></div></div></div><p>
+ In the default mode, statements are committed only when
+ <code class="command">EXEC SQL COMMIT</code> is issued. The embedded SQL
+ interface also supports autocommit of transactions (similar to
+ <span class="application">psql</span>'s default behavior) via the <code class="option">-t</code>
+ command-line option to <code class="command">ecpg</code> (see <a class="xref" href="app-ecpg.html" title="ecpg"><span class="refentrytitle"><span class="application">ecpg</span></span></a>) or via the <code class="literal">EXEC SQL SET AUTOCOMMIT TO
+ ON</code> statement. In autocommit mode, each command is
+ automatically committed unless it is inside an explicit transaction
+ block. This mode can be explicitly turned off using <code class="literal">EXEC
+ SQL SET AUTOCOMMIT TO OFF</code>.
+ </p><p>
+ The following transaction management commands are available:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">EXEC SQL COMMIT</code></span></dt><dd><p>
+ Commit an in-progress transaction.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL ROLLBACK</code></span></dt><dd><p>
+ Roll back an in-progress transaction.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL PREPARE TRANSACTION </code><em class="replaceable"><code>transaction_id</code></em></span></dt><dd><p>
+ Prepare the current transaction for two-phase commit.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL COMMIT PREPARED </code><em class="replaceable"><code>transaction_id</code></em></span></dt><dd><p>
+ Commit a transaction that is in prepared state.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL ROLLBACK PREPARED </code><em class="replaceable"><code>transaction_id</code></em></span></dt><dd><p>
+ Roll back a transaction that is in prepared state.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL SET AUTOCOMMIT TO ON</code></span></dt><dd><p>
+ Enable autocommit mode.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL SET AUTOCOMMIT TO OFF</code></span></dt><dd><p>
+ Disable autocommit mode. This is the default.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PREPARED"><div class="titlepage"><div><div><h3 class="title">36.3.4. Prepared Statements</h3></div></div></div><p>
+ When the values to be passed to an SQL statement are not known at
+ compile time, or the same statement is going to be used many
+ times, then prepared statements can be useful.
+ </p><p>
+ The statement is prepared using the
+ command <code class="literal">PREPARE</code>. For the values that are not
+ known yet, use the
+ placeholder <span class="quote">“<span class="quote"><code class="literal">?</code></span>”</span>:
+</p><pre class="programlisting">
+EXEC SQL PREPARE stmt1 FROM "SELECT oid, datname FROM pg_database WHERE oid = ?";
+</pre><p>
+ </p><p>
+ If a statement returns a single row, the application can
+ call <code class="literal">EXECUTE</code> after
+ <code class="literal">PREPARE</code> to execute the statement, supplying the
+ actual values for the placeholders with a <code class="literal">USING</code>
+ clause:
+</p><pre class="programlisting">
+EXEC SQL EXECUTE stmt1 INTO :dboid, :dbname USING 1;
+</pre><p>
+ </p><p>
+ If a statement returns multiple rows, the application can use a
+ cursor declared based on the prepared statement. To bind input
+ parameters, the cursor must be opened with
+ a <code class="literal">USING</code> clause:
+</p><pre class="programlisting">
+EXEC SQL PREPARE stmt1 FROM "SELECT oid,datname FROM pg_database WHERE oid &gt; ?";
+EXEC SQL DECLARE foo_bar CURSOR FOR stmt1;
+
+/* when end of result set reached, break out of while loop */
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+EXEC SQL OPEN foo_bar USING 100;
+...
+while (1)
+{
+ EXEC SQL FETCH NEXT FROM foo_bar INTO :dboid, :dbname;
+ ...
+}
+EXEC SQL CLOSE foo_bar;
+</pre><p>
+ </p><p>
+ When you don't need the prepared statement anymore, you should
+ deallocate it:
+</p><pre class="programlisting">
+EXEC SQL DEALLOCATE PREPARE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ </p><p>
+ For more details about <code class="literal">PREPARE</code>,
+ see <a class="xref" href="ecpg-sql-prepare.html" title="PREPARE">PREPARE</a>. Also
+ see <a class="xref" href="ecpg-dynamic.html" title="36.5. Dynamic SQL">Section 36.5</a> for more details about using
+ placeholders and input parameters.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-connect.html" title="36.2. Managing Database Connections">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-variables.html" title="36.4. Using Host Variables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.2. Managing Database Connections </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.4. Using Host Variables</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-concept.html b/doc/src/sgml/html/ecpg-concept.html
new file mode 100644
index 0000000..ca4ad6b
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-concept.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.1. The Concept</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C" /><link rel="next" href="ecpg-connect.html" title="36.2. Managing Database Connections" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.1. The Concept</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-connect.html" title="36.2. Managing Database Connections">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-CONCEPT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.1. The Concept</h2></div></div></div><p>
+ An embedded SQL program consists of code written in an ordinary
+ programming language, in this case C, mixed with SQL commands in
+ specially marked sections. To build the program, the source code (<code class="filename">*.pgc</code>)
+ is first passed through the embedded SQL preprocessor, which converts it
+ to an ordinary C program (<code class="filename">*.c</code>), and afterwards it can be processed by a C
+ compiler. (For details about the compiling and linking see <a class="xref" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs">Section 36.10</a>.)
+ Converted ECPG applications call functions in the libpq library
+ through the embedded SQL library (ecpglib), and communicate with
+ the PostgreSQL server using the normal frontend-backend protocol.
+ </p><p>
+ Embedded <acronym class="acronym">SQL</acronym> has advantages over other methods
+ for handling <acronym class="acronym">SQL</acronym> commands from C code. First, it
+ takes care of the tedious passing of information to and from
+ variables in your <acronym class="acronym">C</acronym> program. Second, the SQL
+ code in the program is checked at build time for syntactical
+ correctness. Third, embedded <acronym class="acronym">SQL</acronym> in C is
+ specified in the <acronym class="acronym">SQL</acronym> standard and supported by
+ many other <acronym class="acronym">SQL</acronym> database systems. The
+ <span class="productname">PostgreSQL</span> implementation is designed to match this
+ standard as much as possible, and it is usually possible to port
+ embedded <acronym class="acronym">SQL</acronym> programs written for other SQL
+ databases to <span class="productname">PostgreSQL</span> with relative
+ ease.
+ </p><p>
+ As already stated, programs written for the embedded
+ <acronym class="acronym">SQL</acronym> interface are normal C programs with special
+ code inserted to perform database-related actions. This special
+ code always has the form:
+</p><pre class="programlisting">
+EXEC SQL ...;
+</pre><p>
+ These statements syntactically take the place of a C statement.
+ Depending on the particular statement, they can appear at the
+ global level or within a function.
+ </p><p>
+ Embedded
+ <acronym class="acronym">SQL</acronym> statements follow the case-sensitivity rules of
+ normal <acronym class="acronym">SQL</acronym> code, and not those of C. Also they allow nested
+ C-style comments as per the SQL standard. The C part of the
+ program, however, follows the C standard of not accepting nested comments.
+ Embedded <acronym class="acronym">SQL</acronym> statements likewise use SQL rules, not
+ C rules, for parsing quoted strings and identifiers.
+ (See <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a> and
+ <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS" title="4.1.1. Identifiers and Key Words">Section 4.1.1</a> respectively. Note that
+ ECPG assumes that <code class="varname">standard_conforming_strings</code>
+ is <code class="literal">on</code>.)
+ Of course, the C part of the program follows C quoting rules.
+ </p><p>
+ The following sections explain all the embedded SQL statements.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-connect.html" title="36.2. Managing Database Connections">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.2. Managing Database Connections</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-connect.html b/doc/src/sgml/html/ecpg-connect.html
new file mode 100644
index 0000000..3ddae6f
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-connect.html
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.2. Managing Database Connections</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-concept.html" title="36.1. The Concept" /><link rel="next" href="ecpg-commands.html" title="36.3. Running SQL Commands" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.2. Managing Database Connections</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-concept.html" title="36.1. The Concept">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-commands.html" title="36.3. Running SQL Commands">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-CONNECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.2. Managing Database Connections</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-connect.html#ECPG-CONNECTING">36.2.1. Connecting to the Database Server</a></span></dt><dt><span class="sect2"><a href="ecpg-connect.html#ECPG-SET-CONNECTION">36.2.2. Choosing a Connection</a></span></dt><dt><span class="sect2"><a href="ecpg-connect.html#ECPG-DISCONNECT">36.2.3. Closing a Connection</a></span></dt></dl></div><p>
+ This section describes how to open, close, and switch database
+ connections.
+ </p><div class="sect2" id="ECPG-CONNECTING"><div class="titlepage"><div><div><h3 class="title">36.2.1. Connecting to the Database Server</h3></div></div></div><p>
+ One connects to a database using the following statement:
+</p><pre class="programlisting">
+EXEC SQL CONNECT TO <em class="replaceable"><code>target</code></em> [<span class="optional">AS <em class="replaceable"><code>connection-name</code></em></span>] [<span class="optional">USER <em class="replaceable"><code>user-name</code></em></span>];
+</pre><p>
+ The <em class="replaceable"><code>target</code></em> can be specified in the
+ following ways:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
+ <code class="literal"><em class="replaceable"><code>dbname</code></em>[<span class="optional">@<em class="replaceable"><code>hostname</code></em></span>][<span class="optional">:<em class="replaceable"><code>port</code></em></span>]</code>
+ </li><li class="listitem">
+ <code class="literal">tcp:postgresql://<em class="replaceable"><code>hostname</code></em>[<span class="optional">:<em class="replaceable"><code>port</code></em></span>][<span class="optional">/<em class="replaceable"><code>dbname</code></em></span>][<span class="optional">?<em class="replaceable"><code>options</code></em></span>]</code>
+ </li><li class="listitem">
+ <code class="literal">unix:postgresql://localhost[<span class="optional">:<em class="replaceable"><code>port</code></em></span>][<span class="optional">/<em class="replaceable"><code>dbname</code></em></span>][<span class="optional">?<em class="replaceable"><code>options</code></em></span>]</code>
+ </li><li class="listitem">
+ an SQL string literal containing one of the above forms
+ </li><li class="listitem">
+ a reference to a character variable containing one of the above forms (see examples)
+ </li><li class="listitem">
+ <code class="literal">DEFAULT</code>
+ </li></ul></div><p>
+
+ The connection target <code class="literal">DEFAULT</code> initiates a connection
+ to the default database under the default user name. No separate
+ user name or connection name can be specified in that case.
+ </p><p>
+ If you specify the connection target directly (that is, not as a string
+ literal or variable reference), then the components of the target are
+ passed through normal SQL parsing; this means that, for example,
+ the <em class="replaceable"><code>hostname</code></em> must look like one or more SQL
+ identifiers separated by dots, and those identifiers will be
+ case-folded unless double-quoted. Values of
+ any <em class="replaceable"><code>options</code></em> must be SQL identifiers,
+ integers, or variable references. Of course, you can put nearly
+ anything into an SQL identifier by double-quoting it.
+ In practice, it is probably less error-prone to use a (single-quoted)
+ string literal or a variable reference than to write the connection
+ target directly.
+ </p><p>
+ There are also different ways to specify the user name:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
+ <code class="literal"><em class="replaceable"><code>username</code></em></code>
+ </li><li class="listitem">
+ <code class="literal"><em class="replaceable"><code>username</code></em>/<em class="replaceable"><code>password</code></em></code>
+ </li><li class="listitem">
+ <code class="literal"><em class="replaceable"><code>username</code></em> IDENTIFIED BY <em class="replaceable"><code>password</code></em></code>
+ </li><li class="listitem">
+ <code class="literal"><em class="replaceable"><code>username</code></em> USING <em class="replaceable"><code>password</code></em></code>
+ </li></ul></div><p>
+
+ As above, the parameters <em class="replaceable"><code>username</code></em> and
+ <em class="replaceable"><code>password</code></em> can be an SQL identifier, an
+ SQL string literal, or a reference to a character variable.
+ </p><p>
+ If the connection target includes any <em class="replaceable"><code>options</code></em>,
+ those consist of
+ <code class="literal"><em class="replaceable"><code>keyword</code></em>=<em class="replaceable"><code>value</code></em></code>
+ specifications separated by ampersands (<code class="literal">&amp;</code>).
+ The allowed key words are the same ones recognized
+ by <span class="application">libpq</span> (see
+ <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a>). Spaces are ignored before
+ any <em class="replaceable"><code>keyword</code></em> or <em class="replaceable"><code>value</code></em>,
+ though not within or after one. Note that there is no way to
+ write <code class="literal">&amp;</code> within a <em class="replaceable"><code>value</code></em>.
+ </p><p>
+ Notice that when specifying a socket connection
+ (with the <code class="literal">unix:</code> prefix), the host name must be
+ exactly <code class="literal">localhost</code>. To select a non-default
+ socket directory, write the directory's pathname as the value of
+ a <code class="varname">host</code> option in
+ the <em class="replaceable"><code>options</code></em> part of the target.
+ </p><p>
+ The <em class="replaceable"><code>connection-name</code></em> is used to handle
+ multiple connections in one program. It can be omitted if a
+ program uses only one connection. The most recently opened
+ connection becomes the current connection, which is used by default
+ when an SQL statement is to be executed (see later in this
+ chapter).
+ </p><p>
+ Here are some examples of <code class="command">CONNECT</code> statements:
+</p><pre class="programlisting">
+EXEC SQL CONNECT TO mydb@sql.mydomain.com;
+
+EXEC SQL CONNECT TO tcp:postgresql://sql.mydomain.com/mydb AS myconnection USER john;
+
+EXEC SQL BEGIN DECLARE SECTION;
+const char *target = "mydb@sql.mydomain.com";
+const char *user = "john";
+const char *passwd = "secret";
+EXEC SQL END DECLARE SECTION;
+ ...
+EXEC SQL CONNECT TO :target USER :user USING :passwd;
+/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */
+</pre><p>
+ The last example makes use of the feature referred to above as
+ character variable references. You will see in later sections how C
+ variables can be used in SQL statements when you prefix them with a
+ colon.
+ </p><p>
+ Be advised that the format of the connection target is not
+ specified in the SQL standard. So if you want to develop portable
+ applications, you might want to use something based on the last
+ example above to encapsulate the connection target string
+ somewhere.
+ </p><p>
+ If untrusted users have access to a database that has not adopted a
+ <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage pattern</a>,
+ begin each session by removing publicly-writable schemas
+ from <code class="varname">search_path</code>. For example,
+ add <code class="literal">options=-c search_path=</code>
+ to <code class="literal"><em class="replaceable"><code>options</code></em></code>, or
+ issue <code class="literal">EXEC SQL SELECT pg_catalog.set_config('search_path', '',
+ false);</code> after connecting. This consideration is not specific to
+ ECPG; it applies to every interface for executing arbitrary SQL commands.
+ </p></div><div class="sect2" id="ECPG-SET-CONNECTION"><div class="titlepage"><div><div><h3 class="title">36.2.2. Choosing a Connection</h3></div></div></div><p>
+ SQL statements in embedded SQL programs are by default executed on
+ the current connection, that is, the most recently opened one. If
+ an application needs to manage multiple connections, then there are
+ three ways to handle this.
+ </p><p>
+ The first option is to explicitly choose a connection for each SQL
+ statement, for example:
+</p><pre class="programlisting">
+EXEC SQL AT <em class="replaceable"><code>connection-name</code></em> SELECT ...;
+</pre><p>
+ This option is particularly suitable if the application needs to
+ use several connections in mixed order.
+ </p><p>
+ If your application uses multiple threads of execution, they cannot share a
+ connection concurrently. You must either explicitly control access to the connection
+ (using mutexes) or use a connection for each thread.
+ </p><p>
+ The second option is to execute a statement to switch the current
+ connection. That statement is:
+</p><pre class="programlisting">
+EXEC SQL SET CONNECTION <em class="replaceable"><code>connection-name</code></em>;
+</pre><p>
+ This option is particularly convenient if many statements are to be
+ executed on the same connection.
+ </p><p>
+ Here is an example program managing multiple database connections:
+</p><pre class="programlisting">
+#include &lt;stdio.h&gt;
+
+EXEC SQL BEGIN DECLARE SECTION;
+ char dbname[1024];
+EXEC SQL END DECLARE SECTION;
+
+int
+main()
+{
+ EXEC SQL CONNECT TO testdb1 AS con1 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL CONNECT TO testdb2 AS con2 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL CONNECT TO testdb3 AS con3 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ /* This query would be executed in the last opened database "testdb3". */
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current=%s (should be testdb3)\n", dbname);
+
+ /* Using "AT" to run a query in "testdb2" */
+ EXEC SQL AT con2 SELECT current_database() INTO :dbname;
+ printf("current=%s (should be testdb2)\n", dbname);
+
+ /* Switch the current connection to "testdb1". */
+ EXEC SQL SET CONNECTION con1;
+
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current=%s (should be testdb1)\n", dbname);
+
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</pre><p>
+
+ This example would produce this output:
+</p><pre class="screen">
+current=testdb3 (should be testdb3)
+current=testdb2 (should be testdb2)
+current=testdb1 (should be testdb1)
+</pre><p>
+ </p><p>
+ The third option is to declare an SQL identifier linked to
+ the connection, for example:
+</p><pre class="programlisting">
+EXEC SQL AT <em class="replaceable"><code>connection-name</code></em> DECLARE <em class="replaceable"><code>statement-name</code></em> STATEMENT;
+EXEC SQL PREPARE <em class="replaceable"><code>statement-name</code></em> FROM :<em class="replaceable"><code>dyn-string</code></em>;
+</pre><p>
+ Once you link an SQL identifier to a connection, you execute dynamic SQL
+ without an AT clause. Note that this option behaves like preprocessor
+ directives, therefore the link is enabled only in the file.
+ </p><p>
+ Here is an example program using this option:
+</p><pre class="programlisting">
+#include &lt;stdio.h&gt;
+
+EXEC SQL BEGIN DECLARE SECTION;
+char dbname[128];
+char *dyn_sql = "SELECT current_database()";
+EXEC SQL END DECLARE SECTION;
+
+int main(){
+ EXEC SQL CONNECT TO postgres AS con1;
+ EXEC SQL CONNECT TO testdb AS con2;
+ EXEC SQL AT con1 DECLARE stmt STATEMENT;
+ EXEC SQL PREPARE stmt FROM :dyn_sql;
+ EXEC SQL EXECUTE stmt INTO :dbname;
+ printf("%s\n", dbname);
+
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</pre><p>
+
+ This example would produce this output, even if the default connection is testdb:
+</p><pre class="screen">
+postgres
+</pre><p>
+ </p></div><div class="sect2" id="ECPG-DISCONNECT"><div class="titlepage"><div><div><h3 class="title">36.2.3. Closing a Connection</h3></div></div></div><p>
+ To close a connection, use the following statement:
+</p><pre class="programlisting">
+EXEC SQL DISCONNECT [<span class="optional"><em class="replaceable"><code>connection</code></em></span>];
+</pre><p>
+ The <em class="replaceable"><code>connection</code></em> can be specified
+ in the following ways:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
+ <code class="literal"><em class="replaceable"><code>connection-name</code></em></code>
+ </li><li class="listitem">
+ <code class="literal">DEFAULT</code>
+ </li><li class="listitem">
+ <code class="literal">CURRENT</code>
+ </li><li class="listitem">
+ <code class="literal">ALL</code>
+ </li></ul></div><p>
+
+ If no connection name is specified, the current connection is
+ closed.
+ </p><p>
+ It is good style that an application always explicitly disconnect
+ from every connection it opened.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-concept.html" title="36.1. The Concept">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-commands.html" title="36.3. Running SQL Commands">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.1. The Concept </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.3. Running SQL Commands</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-cpp.html b/doc/src/sgml/html/ecpg-cpp.html
new file mode 100644
index 0000000..5060b90
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-cpp.html
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.13. C++ Applications</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-lo.html" title="36.12. Large Objects" /><link rel="next" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.13. <acronym class="acronym">C++</acronym> Applications</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-lo.html" title="36.12. Large Objects">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-CPP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.13. <acronym class="acronym">C++</acronym> Applications</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-cpp.html#ECPG-CPP-SCOPE">36.13.1. Scope for Host Variables</a></span></dt><dt><span class="sect2"><a href="ecpg-cpp.html#ECPG-CPP-AND-C">36.13.2. C++ Application Development with External C Module</a></span></dt></dl></div><p>
+ ECPG has some limited support for C++ applications. This section
+ describes some caveats.
+ </p><p>
+ The <code class="command">ecpg</code> preprocessor takes an input file
+ written in C (or something like C) and embedded SQL commands,
+ converts the embedded SQL commands into C language chunks, and
+ finally generates a <code class="filename">.c</code> file. The header file
+ declarations of the library functions used by the C language chunks
+ that <code class="command">ecpg</code> generates are wrapped
+ in <code class="literal">extern "C" { ... }</code> blocks when used under
+ C++, so they should work seamlessly in C++.
+ </p><p>
+ In general, however, the <code class="command">ecpg</code> preprocessor only
+ understands C; it does not handle the special syntax and reserved
+ words of the C++ language. So, some embedded SQL code written in
+ C++ application code that uses complicated features specific to C++
+ might fail to be preprocessed correctly or might not work as
+ expected.
+ </p><p>
+ A safe way to use the embedded SQL code in a C++ application is
+ hiding the ECPG calls in a C module, which the C++ application code
+ calls into to access the database, and linking that together with
+ the rest of the C++ code. See <a class="xref" href="ecpg-cpp.html#ECPG-CPP-AND-C" title="36.13.2. C++ Application Development with External C Module">Section 36.13.2</a>
+ about that.
+ </p><div class="sect2" id="ECPG-CPP-SCOPE"><div class="titlepage"><div><div><h3 class="title">36.13.1. Scope for Host Variables</h3></div></div></div><p>
+ The <code class="command">ecpg</code> preprocessor understands the scope of
+ variables in C. In the C language, this is rather simple because
+ the scopes of variables is based on their code blocks. In C++,
+ however, the class member variables are referenced in a different
+ code block from the declared position, so
+ the <code class="command">ecpg</code> preprocessor will not understand the
+ scope of the class member variables.
+ </p><p>
+ For example, in the following case, the <code class="command">ecpg</code>
+ preprocessor cannot find any declaration for the
+ variable <code class="literal">dbname</code> in the <code class="literal">test</code>
+ method, so an error will occur.
+
+</p><pre class="programlisting">
+class TestCpp
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char dbname[1024];
+ EXEC SQL END DECLARE SECTION;
+
+ public:
+ TestCpp();
+ void test();
+ ~TestCpp();
+};
+
+TestCpp::TestCpp()
+{
+ EXEC SQL CONNECT TO testdb1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+}
+
+void Test::test()
+{
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current_database = %s\n", dbname);
+}
+
+TestCpp::~TestCpp()
+{
+ EXEC SQL DISCONNECT ALL;
+}
+</pre><p>
+
+ This code will result in an error like this:
+</p><pre class="screen">
+<strong class="userinput"><code>ecpg test_cpp.pgc</code></strong>
+test_cpp.pgc:28: ERROR: variable "dbname" is not declared
+</pre><p>
+ </p><p>
+ To avoid this scope issue, the <code class="literal">test</code> method
+ could be modified to use a local variable as intermediate storage.
+ But this approach is only a poor workaround, because it uglifies
+ the code and reduces performance.
+
+</p><pre class="programlisting">
+void TestCpp::test()
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char tmp[1024];
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL SELECT current_database() INTO :tmp;
+ strlcpy(dbname, tmp, sizeof(tmp));
+
+ printf("current_database = %s\n", dbname);
+}
+</pre><p>
+ </p></div><div class="sect2" id="ECPG-CPP-AND-C"><div class="titlepage"><div><div><h3 class="title">36.13.2. C++ Application Development with External C Module</h3></div></div></div><p>
+ If you understand these technical limitations of
+ the <code class="command">ecpg</code> preprocessor in C++, you might come to
+ the conclusion that linking C objects and C++ objects at the link
+ stage to enable C++ applications to use ECPG features could be
+ better than writing some embedded SQL commands in C++ code
+ directly. This section describes a way to separate some embedded
+ SQL commands from C++ application code with a simple example. In
+ this example, the application is implemented in C++, while C and
+ ECPG is used to connect to the PostgreSQL server.
+ </p><p>
+ Three kinds of files have to be created: a C file
+ (<code class="filename">*.pgc</code>), a header file, and a C++ file:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="filename">test_mod.pgc</code></span></dt><dd><p>
+ A sub-routine module to execute SQL commands embedded in C.
+ It is going to be converted
+ into <code class="filename">test_mod.c</code> by the preprocessor.
+
+</p><pre class="programlisting">
+#include "test_mod.h"
+#include &lt;stdio.h&gt;
+
+void
+db_connect()
+{
+ EXEC SQL CONNECT TO testdb1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+}
+
+void
+db_test()
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char dbname[1024];
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL SELECT current_database() INTO :dbname;
+ printf("current_database = %s\n", dbname);
+}
+
+void
+db_disconnect()
+{
+ EXEC SQL DISCONNECT ALL;
+}
+</pre><p>
+ </p></dd><dt><span class="term"><code class="filename">test_mod.h</code></span></dt><dd><p>
+ A header file with declarations of the functions in the C
+ module (<code class="filename">test_mod.pgc</code>). It is included by
+ <code class="filename">test_cpp.cpp</code>. This file has to have an
+ <code class="literal">extern "C"</code> block around the declarations,
+ because it will be linked from the C++ module.
+
+</p><pre class="programlisting">
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void db_connect();
+void db_test();
+void db_disconnect();
+
+#ifdef __cplusplus
+}
+#endif
+</pre><p>
+ </p></dd><dt><span class="term"><code class="filename">test_cpp.cpp</code></span></dt><dd><p>
+ The main code for the application, including
+ the <code class="function">main</code> routine, and in this example a
+ C++ class.
+
+</p><pre class="programlisting">
+#include "test_mod.h"
+
+class TestCpp
+{
+ public:
+ TestCpp();
+ void test();
+ ~TestCpp();
+};
+
+TestCpp::TestCpp()
+{
+ db_connect();
+}
+
+void
+TestCpp::test()
+{
+ db_test();
+}
+
+TestCpp::~TestCpp()
+{
+ db_disconnect();
+}
+
+int
+main(void)
+{
+ TestCpp *t = new TestCpp();
+
+ t-&gt;test();
+ return 0;
+}
+</pre><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ To build the application, proceed as follows. Convert
+ <code class="filename">test_mod.pgc</code> into <code class="filename">test_mod.c</code> by
+ running <code class="command">ecpg</code>, and generate
+ <code class="filename">test_mod.o</code> by compiling
+ <code class="filename">test_mod.c</code> with the C compiler:
+</p><pre class="programlisting">
+ecpg -o test_mod.c test_mod.pgc
+cc -c test_mod.c -o test_mod.o
+</pre><p>
+ </p><p>
+ Next, generate <code class="filename">test_cpp.o</code> by compiling
+ <code class="filename">test_cpp.cpp</code> with the C++ compiler:
+</p><pre class="programlisting">
+c++ -c test_cpp.cpp -o test_cpp.o
+</pre><p>
+ </p><p>
+ Finally, link these object files, <code class="filename">test_cpp.o</code>
+ and <code class="filename">test_mod.o</code>, into one executable, using the C++
+ compiler driver:
+</p><pre class="programlisting">
+c++ test_cpp.o test_mod.o -lecpg -o test_cpp
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-lo.html" title="36.12. Large Objects">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.12. Large Objects </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.14. Embedded SQL Commands</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-descriptors.html b/doc/src/sgml/html/ecpg-descriptors.html
new file mode 100644
index 0000000..469ac39
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-descriptors.html
@@ -0,0 +1,710 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.7. Using Descriptor Areas</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-pgtypes.html" title="36.6. pgtypes Library" /><link rel="next" href="ecpg-errors.html" title="36.8. Error Handling" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.7. Using Descriptor Areas</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-errors.html" title="36.8. Error Handling">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-DESCRIPTORS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.7. Using Descriptor Areas</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-descriptors.html#ECPG-NAMED-DESCRIPTORS">36.7.1. Named SQL Descriptor Areas</a></span></dt><dt><span class="sect2"><a href="ecpg-descriptors.html#ECPG-SQLDA-DESCRIPTORS">36.7.2. SQLDA Descriptor Areas</a></span></dt></dl></div><p>
+ An SQL descriptor area is a more sophisticated method for processing
+ the result of a <code class="command">SELECT</code>, <code class="command">FETCH</code> or
+ a <code class="command">DESCRIBE</code> statement. An SQL descriptor area groups
+ the data of one row of data together with metadata items into one
+ data structure. The metadata is particularly useful when executing
+ dynamic SQL statements, where the nature of the result columns might
+ not be known ahead of time. PostgreSQL provides two ways to use
+ Descriptor Areas: the named SQL Descriptor Areas and the C-structure
+ SQLDAs.
+ </p><div class="sect2" id="ECPG-NAMED-DESCRIPTORS"><div class="titlepage"><div><div><h3 class="title">36.7.1. Named SQL Descriptor Areas</h3></div></div></div><p>
+ A named SQL descriptor area consists of a header, which contains
+ information concerning the entire descriptor, and one or more item
+ descriptor areas, which basically each describe one column in the
+ result row.
+ </p><p>
+ Before you can use an SQL descriptor area, you need to allocate one:
+</p><pre class="programlisting">
+EXEC SQL ALLOCATE DESCRIPTOR <em class="replaceable"><code>identifier</code></em>;
+</pre><p>
+ The identifier serves as the <span class="quote">“<span class="quote">variable name</span>”</span> of the
+ descriptor area.
+ When you don't need the descriptor anymore, you should deallocate
+ it:
+</p><pre class="programlisting">
+EXEC SQL DEALLOCATE DESCRIPTOR <em class="replaceable"><code>identifier</code></em>;
+</pre><p>
+ </p><p>
+ To use a descriptor area, specify it as the storage target in an
+ <code class="literal">INTO</code> clause, instead of listing host variables:
+</p><pre class="programlisting">
+EXEC SQL FETCH NEXT FROM mycursor INTO SQL DESCRIPTOR mydesc;
+</pre><p>
+ If the result set is empty, the Descriptor Area will still contain
+ the metadata from the query, i.e., the field names.
+ </p><p>
+ For not yet executed prepared queries, the <code class="command">DESCRIBE</code>
+ statement can be used to get the metadata of the result set:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+char *sql_stmt = "SELECT * FROM table1";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE stmt1 FROM :sql_stmt;
+EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
+</pre><p>
+ </p><p>
+ Before PostgreSQL 9.0, the <code class="literal">SQL</code> keyword was optional,
+ so using <code class="literal">DESCRIPTOR</code> and <code class="literal">SQL DESCRIPTOR</code>
+ produced named SQL Descriptor Areas. Now it is mandatory, omitting
+ the <code class="literal">SQL</code> keyword produces SQLDA Descriptor Areas,
+ see <a class="xref" href="ecpg-descriptors.html#ECPG-SQLDA-DESCRIPTORS" title="36.7.2. SQLDA Descriptor Areas">Section 36.7.2</a>.
+ </p><p>
+ In <code class="command">DESCRIBE</code> and <code class="command">FETCH</code> statements,
+ the <code class="literal">INTO</code> and <code class="literal">USING</code> keywords can be
+ used to similarly: they produce the result set and the metadata in a
+ Descriptor Area.
+ </p><p>
+ Now how do you get the data out of the descriptor area? You can
+ think of the descriptor area as a structure with named fields. To
+ retrieve the value of a field from the header and store it into a
+ host variable, use the following command:
+</p><pre class="programlisting">
+EXEC SQL GET DESCRIPTOR <em class="replaceable"><code>name</code></em> :<em class="replaceable"><code>hostvar</code></em> = <em class="replaceable"><code>field</code></em>;
+</pre><p>
+ Currently, there is only one header field defined:
+ <em class="replaceable"><code>COUNT</code></em>, which tells how many item
+ descriptor areas exist (that is, how many columns are contained in
+ the result). The host variable needs to be of an integer type. To
+ get a field from the item descriptor area, use the following
+ command:
+</p><pre class="programlisting">
+EXEC SQL GET DESCRIPTOR <em class="replaceable"><code>name</code></em> VALUE <em class="replaceable"><code>num</code></em> :<em class="replaceable"><code>hostvar</code></em> = <em class="replaceable"><code>field</code></em>;
+</pre><p>
+ <em class="replaceable"><code>num</code></em> can be a literal integer or a host
+ variable containing an integer. Possible fields are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">CARDINALITY</code> (integer)</span></dt><dd><p>
+ number of rows in the result set
+ </p></dd><dt><span class="term"><code class="literal">DATA</code></span></dt><dd><p>
+ actual data item (therefore, the data type of this field
+ depends on the query)
+ </p></dd><dt><span class="term"><code class="literal">DATETIME_INTERVAL_CODE</code> (integer)</span></dt><dd><p>
+ When <code class="literal">TYPE</code> is <code class="literal">9</code>,
+ <code class="literal">DATETIME_INTERVAL_CODE</code> will have a value of
+ <code class="literal">1</code> for <code class="literal">DATE</code>,
+ <code class="literal">2</code> for <code class="literal">TIME</code>,
+ <code class="literal">3</code> for <code class="literal">TIMESTAMP</code>,
+ <code class="literal">4</code> for <code class="literal">TIME WITH TIME ZONE</code>, or
+ <code class="literal">5</code> for <code class="literal">TIMESTAMP WITH TIME ZONE</code>.
+ </p></dd><dt><span class="term"><code class="literal">DATETIME_INTERVAL_PRECISION</code> (integer)</span></dt><dd><p>
+ not implemented
+ </p></dd><dt><span class="term"><code class="literal">INDICATOR</code> (integer)</span></dt><dd><p>
+ the indicator (indicating a null value or a value truncation)
+ </p></dd><dt><span class="term"><code class="literal">KEY_MEMBER</code> (integer)</span></dt><dd><p>
+ not implemented
+ </p></dd><dt><span class="term"><code class="literal">LENGTH</code> (integer)</span></dt><dd><p>
+ length of the datum in characters
+ </p></dd><dt><span class="term"><code class="literal">NAME</code> (string)</span></dt><dd><p>
+ name of the column
+ </p></dd><dt><span class="term"><code class="literal">NULLABLE</code> (integer)</span></dt><dd><p>
+ not implemented
+ </p></dd><dt><span class="term"><code class="literal">OCTET_LENGTH</code> (integer)</span></dt><dd><p>
+ length of the character representation of the datum in bytes
+ </p></dd><dt><span class="term"><code class="literal">PRECISION</code> (integer)</span></dt><dd><p>
+ precision (for type <code class="type">numeric</code>)
+ </p></dd><dt><span class="term"><code class="literal">RETURNED_LENGTH</code> (integer)</span></dt><dd><p>
+ length of the datum in characters
+ </p></dd><dt><span class="term"><code class="literal">RETURNED_OCTET_LENGTH</code> (integer)</span></dt><dd><p>
+ length of the character representation of the datum in bytes
+ </p></dd><dt><span class="term"><code class="literal">SCALE</code> (integer)</span></dt><dd><p>
+ scale (for type <code class="type">numeric</code>)
+ </p></dd><dt><span class="term"><code class="literal">TYPE</code> (integer)</span></dt><dd><p>
+ numeric code of the data type of the column
+ </p></dd></dl></div><p>
+ </p><p>
+ In <code class="command">EXECUTE</code>, <code class="command">DECLARE</code> and <code class="command">OPEN</code>
+ statements, the effect of the <code class="literal">INTO</code> and <code class="literal">USING</code>
+ keywords are different. A Descriptor Area can also be manually built to
+ provide the input parameters for a query or a cursor and
+ <code class="literal">USING SQL DESCRIPTOR <em class="replaceable"><code>name</code></em></code>
+ is the way to pass the input parameters into a parameterized query. The statement
+ to build a named SQL Descriptor Area is below:
+</p><pre class="programlisting">
+EXEC SQL SET DESCRIPTOR <em class="replaceable"><code>name</code></em> VALUE <em class="replaceable"><code>num</code></em> <em class="replaceable"><code>field</code></em> = :<em class="replaceable"><code>hostvar</code></em>;
+</pre><p>
+ </p><p>
+ PostgreSQL supports retrieving more that one record in one <code class="command">FETCH</code>
+ statement and storing the data in host variables in this case assumes that the
+ variable is an array. E.g.:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int id[5];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc;
+
+EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA;
+</pre><p>
+
+ </p></div><div class="sect2" id="ECPG-SQLDA-DESCRIPTORS"><div class="titlepage"><div><div><h3 class="title">36.7.2. SQLDA Descriptor Areas</h3></div></div></div><p>
+ An SQLDA Descriptor Area is a C language structure which can be also used
+ to get the result set and the metadata of a query. One structure stores one
+ record from the result set.
+</p><pre class="programlisting">
+EXEC SQL include sqlda.h;
+sqlda_t *mysqlda;
+
+EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda;
+</pre><p>
+ Note that the <code class="literal">SQL</code> keyword is omitted. The paragraphs about
+ the use cases of the <code class="literal">INTO</code> and <code class="literal">USING</code>
+ keywords in <a class="xref" href="ecpg-descriptors.html#ECPG-NAMED-DESCRIPTORS" title="36.7.1. Named SQL Descriptor Areas">Section 36.7.1</a> also apply here with an addition.
+ In a <code class="command">DESCRIBE</code> statement the <code class="literal">DESCRIPTOR</code>
+ keyword can be completely omitted if the <code class="literal">INTO</code> keyword is used:
+</p><pre class="programlisting">
+EXEC SQL DESCRIBE prepared_statement INTO mysqlda;
+</pre><p>
+ </p><div class="procedure"><p>
+ The general flow of a program that uses SQLDA is:
+ </p><ol class="procedure" type="1"><li class="step"><p>Prepare a query, and declare a cursor for it.</p></li><li class="step"><p>Declare an SQLDA for the result rows.</p></li><li class="step"><p>Declare an SQLDA for the input parameters, and initialize them (memory allocation, parameter settings).</p></li><li class="step"><p>Open a cursor with the input SQLDA.</p></li><li class="step"><p>Fetch rows from the cursor, and store them into an output SQLDA.</p></li><li class="step"><p>Read values from the output SQLDA into the host variables (with conversion if necessary).</p></li><li class="step"><p>Close the cursor.</p></li><li class="step"><p>Free the memory area allocated for the input SQLDA.</p></li></ol></div><div class="sect3" id="id-1.7.5.13.4.4"><div class="titlepage"><div><div><h4 class="title">36.7.2.1. SQLDA Data Structure</h4></div></div></div><p>
+ SQLDA uses three data structure
+ types: <code class="type">sqlda_t</code>, <code class="type">sqlvar_t</code>,
+ and <code class="type">struct sqlname</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ PostgreSQL's SQLDA has a similar data structure to the one in
+ IBM DB2 Universal Database, so some technical information on
+ DB2's SQLDA could help understanding PostgreSQL's one better.
+ </p></div><div class="sect4" id="ECPG-SQLDA-SQLDA"><div class="titlepage"><div><div><h5 class="title">36.7.2.1.1. sqlda_t Structure</h5></div></div></div><p>
+ The structure type <code class="type">sqlda_t</code> is the type of the
+ actual SQLDA. It holds one record. And two or
+ more <code class="type">sqlda_t</code> structures can be connected in a
+ linked list with the pointer in
+ the <code class="structfield">desc_next</code> field, thus
+ representing an ordered collection of rows. So, when two or
+ more rows are fetched, the application can read them by
+ following the <code class="structfield">desc_next</code> pointer in
+ each <code class="type">sqlda_t</code> node.
+ </p><p>
+ The definition of <code class="type">sqlda_t</code> is:
+</p><pre class="programlisting">
+struct sqlda_struct
+{
+ char sqldaid[8];
+ long sqldabc;
+ short sqln;
+ short sqld;
+ struct sqlda_struct *desc_next;
+ struct sqlvar_struct sqlvar[1];
+};
+
+typedef struct sqlda_struct sqlda_t;
+</pre><p>
+
+ The meaning of the fields is:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">sqldaid</code></span></dt><dd><p>
+ It contains the literal string <code class="literal">"SQLDA "</code>.
+ </p></dd><dt><span class="term"><code class="literal">sqldabc</code></span></dt><dd><p>
+ It contains the size of the allocated space in bytes.
+ </p></dd><dt><span class="term"><code class="literal">sqln</code></span></dt><dd><p>
+ It contains the number of input parameters for a parameterized query in
+ case it's passed into <code class="command">OPEN</code>, <code class="command">DECLARE</code> or
+ <code class="command">EXECUTE</code> statements using the <code class="literal">USING</code>
+ keyword. In case it's used as output of <code class="command">SELECT</code>,
+ <code class="command">EXECUTE</code> or <code class="command">FETCH</code> statements,
+ its value is the same as <code class="literal">sqld</code>
+ statement
+ </p></dd><dt><span class="term"><code class="literal">sqld</code></span></dt><dd><p>
+ It contains the number of fields in a result set.
+ </p></dd><dt><span class="term"><code class="literal">desc_next</code></span></dt><dd><p>
+ If the query returns more than one record, multiple linked
+ SQLDA structures are returned, and <code class="literal">desc_next</code> holds
+ a pointer to the next entry in the list.
+ </p></dd><dt><span class="term"><code class="literal">sqlvar</code></span></dt><dd><p>
+ This is the array of the columns in the result set.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect4" id="ECPG-SQLDA-SQLVAR"><div class="titlepage"><div><div><h5 class="title">36.7.2.1.2. sqlvar_t Structure</h5></div></div></div><p>
+ The structure type <code class="type">sqlvar_t</code> holds a column value
+ and metadata such as type and length. The definition of the type
+ is:
+
+</p><pre class="programlisting">
+struct sqlvar_struct
+{
+ short sqltype;
+ short sqllen;
+ char *sqldata;
+ short *sqlind;
+ struct sqlname sqlname;
+};
+
+typedef struct sqlvar_struct sqlvar_t;
+</pre><p>
+
+ The meaning of the fields is:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">sqltype</code></span></dt><dd><p>
+ Contains the type identifier of the field. For values,
+ see <code class="literal">enum ECPGttype</code> in <code class="literal">ecpgtype.h</code>.
+ </p></dd><dt><span class="term"><code class="literal">sqllen</code></span></dt><dd><p>
+ Contains the binary length of the field. e.g., 4 bytes for <code class="type">ECPGt_int</code>.
+ </p></dd><dt><span class="term"><code class="literal">sqldata</code></span></dt><dd><p>
+ Points to the data. The format of the data is described
+ in <a class="xref" href="ecpg-variables.html#ECPG-VARIABLES-TYPE-MAPPING" title="36.4.4. Type Mapping">Section 36.4.4</a>.
+ </p></dd><dt><span class="term"><code class="literal">sqlind</code></span></dt><dd><p>
+ Points to the null indicator. 0 means not null, -1 means
+ null.
+ </p></dd><dt><span class="term"><code class="literal">sqlname</code></span></dt><dd><p>
+ The name of the field.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect4" id="ECPG-SQLDA-SQLNAME"><div class="titlepage"><div><div><h5 class="title">36.7.2.1.3. struct sqlname Structure</h5></div></div></div><p>
+ A <code class="type">struct sqlname</code> structure holds a column name. It
+ is used as a member of the <code class="type">sqlvar_t</code> structure. The
+ definition of the structure is:
+</p><pre class="programlisting">
+#define NAMEDATALEN 64
+
+struct sqlname
+{
+ short length;
+ char data[NAMEDATALEN];
+};
+</pre><p>
+ The meaning of the fields is:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">length</code></span></dt><dd><p>
+ Contains the length of the field name.
+ </p></dd><dt><span class="term"><code class="literal">data</code></span></dt><dd><p>
+ Contains the actual field name.
+ </p></dd></dl></div><p>
+ </p></div></div><div class="sect3" id="ECPG-SQLDA-OUTPUT"><div class="titlepage"><div><div><h4 class="title">36.7.2.2. Retrieving a Result Set Using an SQLDA</h4></div></div></div><div class="procedure"><p>
+ The general steps to retrieve a query result set through an
+ SQLDA are:
+ </p><ol class="procedure" type="1"><li class="step"><p>Declare an <code class="type">sqlda_t</code> structure to receive the result set.</p></li><li class="step"><p>Execute <code class="command">FETCH</code>/<code class="command">EXECUTE</code>/<code class="command">DESCRIBE</code> commands to process a query specifying the declared SQLDA.</p></li><li class="step"><p>Check the number of records in the result set by looking at <code class="structfield">sqln</code>, a member of the <code class="type">sqlda_t</code> structure.</p></li><li class="step"><p>Get the values of each column from <code class="literal">sqlvar[0]</code>, <code class="literal">sqlvar[1]</code>, etc., members of the <code class="type">sqlda_t</code> structure.</p></li><li class="step"><p>Go to next row (<code class="type">sqlda_t</code> structure) by following the <code class="structfield">desc_next</code> pointer, a member of the <code class="type">sqlda_t</code> structure.</p></li><li class="step"><p>Repeat above as you need.</p></li></ol></div><p>
+ Here is an example retrieving a result set through an SQLDA.
+ </p><p>
+ First, declare a <code class="type">sqlda_t</code> structure to receive the result set.
+</p><pre class="programlisting">
+sqlda_t *sqlda1;
+</pre><p>
+ </p><p>
+ Next, specify the SQLDA in a command. This is
+ a <code class="command">FETCH</code> command example.
+</p><pre class="programlisting">
+EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
+</pre><p>
+ </p><p>
+ Run a loop following the linked list to retrieve the rows.
+</p><pre class="programlisting">
+sqlda_t *cur_sqlda;
+
+for (cur_sqlda = sqlda1;
+ cur_sqlda != NULL;
+ cur_sqlda = cur_sqlda-&gt;desc_next)
+{
+ ...
+}
+</pre><p>
+ </p><p>
+ Inside the loop, run another loop to retrieve each column data
+ (<code class="type">sqlvar_t</code> structure) of the row.
+</p><pre class="programlisting">
+for (i = 0; i &lt; cur_sqlda-&gt;sqld; i++)
+{
+ sqlvar_t v = cur_sqlda-&gt;sqlvar[i];
+ char *sqldata = v.sqldata;
+ short sqllen = v.sqllen;
+ ...
+}
+</pre><p>
+ </p><p>
+ To get a column value, check the <code class="structfield">sqltype</code> value,
+ a member of the <code class="type">sqlvar_t</code> structure. Then, switch
+ to an appropriate way, depending on the column type, to copy
+ data from the <code class="structfield">sqlvar</code> field to a host variable.
+</p><pre class="programlisting">
+char var_buf[1024];
+
+switch (v.sqltype)
+{
+ case ECPGt_char:
+ memset(&amp;var_buf, 0, sizeof(var_buf));
+ memcpy(&amp;var_buf, sqldata, (sizeof(var_buf) &lt;= sqllen ? sizeof(var_buf) - 1 : sqllen));
+ break;
+
+ case ECPGt_int: /* integer */
+ memcpy(&amp;intval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%d", intval);
+ break;
+
+ ...
+}
+</pre><p>
+ </p></div><div class="sect3" id="ECPG-SQLDA-INPUT"><div class="titlepage"><div><div><h4 class="title">36.7.2.3. Passing Query Parameters Using an SQLDA</h4></div></div></div><div class="procedure"><p>
+ The general steps to use an SQLDA to pass input
+ parameters to a prepared query are:
+ </p><ol class="procedure" type="1"><li class="step"><p>Create a prepared query (prepared statement)</p></li><li class="step"><p>Declare an sqlda_t structure as an input SQLDA.</p></li><li class="step"><p>Allocate memory area (as sqlda_t structure) for the input SQLDA.</p></li><li class="step"><p>Set (copy) input values in the allocated memory.</p></li><li class="step"><p>Open a cursor with specifying the input SQLDA.</p></li></ol></div><p>
+ Here is an example.
+ </p><p>
+ First, create a prepared statement.
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+char query[1024] = "SELECT d.oid, * FROM pg_database d, pg_stat_database s WHERE d.oid = s.datid AND (d.datname = ? OR d.oid = ?)";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE stmt1 FROM :query;
+</pre><p>
+ </p><p>
+ Next, allocate memory for an SQLDA, and set the number of input
+ parameters in <code class="structfield">sqln</code>, a member variable of
+ the <code class="type">sqlda_t</code> structure. When two or more input
+ parameters are required for the prepared query, the application
+ has to allocate additional memory space which is calculated by
+ (nr. of params - 1) * sizeof(sqlvar_t). The example shown here
+ allocates memory space for two input parameters.
+</p><pre class="programlisting">
+sqlda_t *sqlda2;
+
+sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
+memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
+
+sqlda2-&gt;sqln = 2; /* number of input variables */
+</pre><p>
+ </p><p>
+ After memory allocation, store the parameter values into the
+ <code class="literal">sqlvar[]</code> array. (This is same array used for
+ retrieving column values when the SQLDA is receiving a result
+ set.) In this example, the input parameters
+ are <code class="literal">"postgres"</code>, having a string type,
+ and <code class="literal">1</code>, having an integer type.
+</p><pre class="programlisting">
+sqlda2-&gt;sqlvar[0].sqltype = ECPGt_char;
+sqlda2-&gt;sqlvar[0].sqldata = "postgres";
+sqlda2-&gt;sqlvar[0].sqllen = 8;
+
+int intval = 1;
+sqlda2-&gt;sqlvar[1].sqltype = ECPGt_int;
+sqlda2-&gt;sqlvar[1].sqldata = (char *) &amp;intval;
+sqlda2-&gt;sqlvar[1].sqllen = sizeof(intval);
+</pre><p>
+ </p><p>
+ By opening a cursor and specifying the SQLDA that was set up
+ beforehand, the input parameters are passed to the prepared
+ statement.
+</p><pre class="programlisting">
+EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
+</pre><p>
+ </p><p>
+ Finally, after using input SQLDAs, the allocated memory space
+ must be freed explicitly, unlike SQLDAs used for receiving query
+ results.
+</p><pre class="programlisting">
+free(sqlda2);
+</pre><p>
+ </p></div><div class="sect3" id="ECPG-SQLDA-EXAMPLE"><div class="titlepage"><div><div><h4 class="title">36.7.2.4. A Sample Application Using SQLDA</h4></div></div></div><p>
+ Here is an example program, which describes how to fetch access
+ statistics of the databases, specified by the input parameters,
+ from the system catalogs.
+ </p><p>
+ This application joins two system tables, pg_database and
+ pg_stat_database on the database OID, and also fetches and shows
+ the database statistics which are retrieved by two input
+ parameters (a database <code class="literal">postgres</code>, and OID <code class="literal">1</code>).
+ </p><p>
+ First, declare an SQLDA for input and an SQLDA for output.
+</p><pre class="programlisting">
+EXEC SQL include sqlda.h;
+
+sqlda_t *sqlda1; /* an output descriptor */
+sqlda_t *sqlda2; /* an input descriptor */
+</pre><p>
+ </p><p>
+ Next, connect to the database, prepare a statement, and declare a
+ cursor for the prepared statement.
+</p><pre class="programlisting">
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ EXEC SQL PREPARE stmt1 FROM :query;
+ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+</pre><p>
+ </p><p>
+ Next, put some values in the input SQLDA for the input
+ parameters. Allocate memory for the input SQLDA, and set the
+ number of input parameters to <code class="literal">sqln</code>. Store
+ type, value, and value length into <code class="literal">sqltype</code>,
+ <code class="literal">sqldata</code>, and <code class="literal">sqllen</code> in the
+ <code class="literal">sqlvar</code> structure.
+
+</p><pre class="programlisting">
+ /* Create SQLDA structure for input parameters. */
+ sqlda2 = (sqlda_t *) malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
+ memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
+ sqlda2-&gt;sqln = 2; /* number of input variables */
+
+ sqlda2-&gt;sqlvar[0].sqltype = ECPGt_char;
+ sqlda2-&gt;sqlvar[0].sqldata = "postgres";
+ sqlda2-&gt;sqlvar[0].sqllen = 8;
+
+ intval = 1;
+ sqlda2-&gt;sqlvar[1].sqltype = ECPGt_int;
+ sqlda2-&gt;sqlvar[1].sqldata = (char *)&amp;intval;
+ sqlda2-&gt;sqlvar[1].sqllen = sizeof(intval);
+</pre><p>
+ </p><p>
+ After setting up the input SQLDA, open a cursor with the input
+ SQLDA.
+
+</p><pre class="programlisting">
+ /* Open a cursor with input parameters. */
+ EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
+</pre><p>
+ </p><p>
+ Fetch rows into the output SQLDA from the opened cursor.
+ (Generally, you have to call <code class="command">FETCH</code> repeatedly
+ in the loop, to fetch all rows in the result set.)
+</p><pre class="programlisting">
+ while (1)
+ {
+ sqlda_t *cur_sqlda;
+
+ /* Assign descriptor to the cursor */
+ EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
+</pre><p>
+ </p><p>
+ Next, retrieve the fetched records from the SQLDA, by following
+ the linked list of the <code class="type">sqlda_t</code> structure.
+</p><pre class="programlisting">
+ for (cur_sqlda = sqlda1 ;
+ cur_sqlda != NULL ;
+ cur_sqlda = cur_sqlda-&gt;desc_next)
+ {
+ ...
+</pre><p>
+ </p><p>
+ Read each columns in the first record. The number of columns is
+ stored in <code class="structfield">sqld</code>, the actual data of the first
+ column is stored in <code class="literal">sqlvar[0]</code>, both members of
+ the <code class="type">sqlda_t</code> structure.
+
+</p><pre class="programlisting">
+ /* Print every column in a row. */
+ for (i = 0; i &lt; sqlda1-&gt;sqld; i++)
+ {
+ sqlvar_t v = sqlda1-&gt;sqlvar[i];
+ char *sqldata = v.sqldata;
+ short sqllen = v.sqllen;
+
+ strncpy(name_buf, v.sqlname.data, v.sqlname.length);
+ name_buf[v.sqlname.length] = '\0';
+</pre><p>
+ </p><p>
+ Now, the column data is stored in the variable <code class="varname">v</code>.
+ Copy every datum into host variables, looking
+ at <code class="literal">v.sqltype</code> for the type of the column.
+</p><pre class="programlisting">
+ switch (v.sqltype) {
+ int intval;
+ double doubleval;
+ unsigned long long int longlongval;
+
+ case ECPGt_char:
+ memset(&amp;var_buf, 0, sizeof(var_buf));
+ memcpy(&amp;var_buf, sqldata, (sizeof(var_buf) &lt;= sqllen ? sizeof(var_buf)-1 : sqllen));
+ break;
+
+ case ECPGt_int: /* integer */
+ memcpy(&amp;intval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%d", intval);
+ break;
+
+ ...
+
+ default:
+ ...
+ }
+
+ printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
+ }
+</pre><p>
+ </p><p>
+ Close the cursor after processing all of records, and disconnect
+ from the database.
+</p><pre class="programlisting">
+ EXEC SQL CLOSE cur1;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DISCONNECT ALL;
+</pre><p>
+ </p><p>
+ The whole program is shown
+ in <a class="xref" href="ecpg-descriptors.html#ECPG-SQLDA-EXAMPLE-EXAMPLE" title="Example 36.1. Example SQLDA Program">Example 36.1</a>.
+ </p><div class="example" id="ECPG-SQLDA-EXAMPLE-EXAMPLE"><p class="title"><strong>Example 36.1. Example SQLDA Program</strong></p><div class="example-contents"><pre class="programlisting">
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;unistd.h&gt;
+
+EXEC SQL include sqlda.h;
+
+sqlda_t *sqlda1; /* descriptor for output */
+sqlda_t *sqlda2; /* descriptor for input */
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+main(void)
+{
+ EXEC SQL BEGIN DECLARE SECTION;
+ char query[1024] = "SELECT d.oid,* FROM pg_database d, pg_stat_database s WHERE d.oid=s.datid AND ( d.datname=? OR d.oid=? )";
+
+ int intval;
+ unsigned long long int longlongval;
+ EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO uptimedb AS con1 USER uptime;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ EXEC SQL PREPARE stmt1 FROM :query;
+ EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+
+ /* Create an SQLDA structure for an input parameter */
+ sqlda2 = (sqlda_t *)malloc(sizeof(sqlda_t) + sizeof(sqlvar_t));
+ memset(sqlda2, 0, sizeof(sqlda_t) + sizeof(sqlvar_t));
+ sqlda2-&gt;sqln = 2; /* a number of input variables */
+
+ sqlda2-&gt;sqlvar[0].sqltype = ECPGt_char;
+ sqlda2-&gt;sqlvar[0].sqldata = "postgres";
+ sqlda2-&gt;sqlvar[0].sqllen = 8;
+
+ intval = 1;
+ sqlda2-&gt;sqlvar[1].sqltype = ECPGt_int;
+ sqlda2-&gt;sqlvar[1].sqldata = (char *) &amp;intval;
+ sqlda2-&gt;sqlvar[1].sqllen = sizeof(intval);
+
+ /* Open a cursor with input parameters. */
+ EXEC SQL OPEN cur1 USING DESCRIPTOR sqlda2;
+
+ while (1)
+ {
+ sqlda_t *cur_sqlda;
+
+ /* Assign descriptor to the cursor */
+ EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda1;
+
+ for (cur_sqlda = sqlda1 ;
+ cur_sqlda != NULL ;
+ cur_sqlda = cur_sqlda-&gt;desc_next)
+ {
+ int i;
+ char name_buf[1024];
+ char var_buf[1024];
+
+ /* Print every column in a row. */
+ for (i=0 ; i&lt;cur_sqlda-&gt;sqld ; i++)
+ {
+ sqlvar_t v = cur_sqlda-&gt;sqlvar[i];
+ char *sqldata = v.sqldata;
+ short sqllen = v.sqllen;
+
+ strncpy(name_buf, v.sqlname.data, v.sqlname.length);
+ name_buf[v.sqlname.length] = '\0';
+
+ switch (v.sqltype)
+ {
+ case ECPGt_char:
+ memset(&amp;var_buf, 0, sizeof(var_buf));
+ memcpy(&amp;var_buf, sqldata, (sizeof(var_buf)&lt;=sqllen ? sizeof(var_buf)-1 : sqllen) );
+ break;
+
+ case ECPGt_int: /* integer */
+ memcpy(&amp;intval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%d", intval);
+ break;
+
+ case ECPGt_long_long: /* bigint */
+ memcpy(&amp;longlongval, sqldata, sqllen);
+ snprintf(var_buf, sizeof(var_buf), "%lld", longlongval);
+ break;
+
+ default:
+ {
+ int i;
+ memset(var_buf, 0, sizeof(var_buf));
+ for (i = 0; i &lt; sqllen; i++)
+ {
+ char tmpbuf[16];
+ snprintf(tmpbuf, sizeof(tmpbuf), "%02x ", (unsigned char) sqldata[i]);
+ strncat(var_buf, tmpbuf, sizeof(var_buf));
+ }
+ }
+ break;
+ }
+
+ printf("%s = %s (type: %d)\n", name_buf, var_buf, v.sqltype);
+ }
+
+ printf("\n");
+ }
+ }
+
+ EXEC SQL CLOSE cur1;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+</pre><p>
+ The output of this example should look something like the
+ following (some numbers will vary).
+ </p><pre class="screen">
+oid = 1 (type: 1)
+datname = template1 (type: 1)
+datdba = 10 (type: 1)
+encoding = 0 (type: 5)
+datistemplate = t (type: 1)
+datallowconn = t (type: 1)
+datconnlimit = -1 (type: 5)
+datfrozenxid = 379 (type: 1)
+dattablespace = 1663 (type: 1)
+datconfig = (type: 1)
+datacl = {=c/uptime,uptime=CTc/uptime} (type: 1)
+datid = 1 (type: 1)
+datname = template1 (type: 1)
+numbackends = 0 (type: 5)
+xact_commit = 113606 (type: 9)
+xact_rollback = 0 (type: 9)
+blks_read = 130 (type: 9)
+blks_hit = 7341714 (type: 9)
+tup_returned = 38262679 (type: 9)
+tup_fetched = 1836281 (type: 9)
+tup_inserted = 0 (type: 9)
+tup_updated = 0 (type: 9)
+tup_deleted = 0 (type: 9)
+
+oid = 11511 (type: 1)
+datname = postgres (type: 1)
+datdba = 10 (type: 1)
+encoding = 0 (type: 5)
+datistemplate = f (type: 1)
+datallowconn = t (type: 1)
+datconnlimit = -1 (type: 5)
+datfrozenxid = 379 (type: 1)
+dattablespace = 1663 (type: 1)
+datconfig = (type: 1)
+datacl = (type: 1)
+datid = 11511 (type: 1)
+datname = postgres (type: 1)
+numbackends = 0 (type: 5)
+xact_commit = 221069 (type: 9)
+xact_rollback = 18 (type: 9)
+blks_read = 1176 (type: 9)
+blks_hit = 13943750 (type: 9)
+tup_returned = 77410091 (type: 9)
+tup_fetched = 3253694 (type: 9)
+tup_inserted = 0 (type: 9)
+tup_updated = 0 (type: 9)
+tup_deleted = 0 (type: 9)
+</pre></div></div><br class="example-break" /></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-errors.html" title="36.8. Error Handling">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.6. pgtypes Library </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.8. Error Handling</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-develop.html b/doc/src/sgml/html/ecpg-develop.html
new file mode 100644
index 0000000..fc039cf
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-develop.html
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.17. Internals</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode" /><link rel="next" href="information-schema.html" title="Chapter 37. The Information Schema" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.17. Internals</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="information-schema.html" title="Chapter 37. The Information Schema">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-DEVELOP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.17. Internals</h2></div></div></div><p>
+ This section explains how <span class="application">ECPG</span> works
+ internally. This information can occasionally be useful to help
+ users understand how to use <span class="application">ECPG</span>.
+ </p><p>
+ The first four lines written by <code class="command">ecpg</code> to the
+ output are fixed lines. Two are comments and two are include
+ lines necessary to interface to the library. Then the
+ preprocessor reads through the file and writes output. Normally
+ it just echoes everything to the output.
+ </p><p>
+ When it sees an <code class="command">EXEC SQL</code> statement, it
+ intervenes and changes it. The command starts with <code class="command">EXEC
+ SQL</code> and ends with <code class="command">;</code>. Everything in
+ between is treated as an <acronym class="acronym">SQL</acronym> statement and
+ parsed for variable substitution.
+ </p><p>
+ Variable substitution occurs when a symbol starts with a colon
+ (<code class="literal">:</code>). The variable with that name is looked up
+ among the variables that were previously declared within a
+ <code class="literal">EXEC SQL DECLARE</code> section.
+ </p><p>
+ The most important function in the library is
+ <code class="function">ECPGdo</code>, which takes care of executing most
+ commands. It takes a variable number of arguments. This can easily
+ add up to 50 or so arguments, and we hope this will not be a
+ problem on any platform.
+ </p><p>
+ The arguments are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">A line number</span></dt><dd><p>
+ This is the line number of the original line; used in error
+ messages only.
+ </p></dd><dt><span class="term">A string</span></dt><dd><p>
+ This is the <acronym class="acronym">SQL</acronym> command that is to be issued.
+ It is modified by the input variables, i.e., the variables that
+ where not known at compile time but are to be entered in the
+ command. Where the variables should go the string contains
+ <code class="literal">?</code>.
+ </p></dd><dt><span class="term">Input variables</span></dt><dd><p>
+ Every input variable causes ten arguments to be created. (See below.)
+ </p></dd><dt><span class="term"><em class="parameter"><code>ECPGt_EOIT</code></em></span></dt><dd><p>
+ An <code class="type">enum</code> telling that there are no more input
+ variables.
+ </p></dd><dt><span class="term">Output variables</span></dt><dd><p>
+ Every output variable causes ten arguments to be created.
+ (See below.) These variables are filled by the function.
+ </p></dd><dt><span class="term"><em class="parameter"><code>ECPGt_EORT</code></em></span></dt><dd><p>
+ An <code class="type">enum</code> telling that there are no more variables.
+ </p></dd></dl></div><p>
+ </p><p>
+ For every variable that is part of the <acronym class="acronym">SQL</acronym>
+ command, the function gets ten arguments:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ The type as a special symbol.
+ </p></li><li class="listitem"><p>
+ A pointer to the value or a pointer to the pointer.
+ </p></li><li class="listitem"><p>
+ The size of the variable if it is a <code class="type">char</code> or <code class="type">varchar</code>.
+ </p></li><li class="listitem"><p>
+ The number of elements in the array (for array fetches).
+ </p></li><li class="listitem"><p>
+ The offset to the next element in the array (for array fetches).
+ </p></li><li class="listitem"><p>
+ The type of the indicator variable as a special symbol.
+ </p></li><li class="listitem"><p>
+ A pointer to the indicator variable.
+ </p></li><li class="listitem"><p>
+ 0
+ </p></li><li class="listitem"><p>
+ The number of elements in the indicator array (for array fetches).
+ </p></li><li class="listitem"><p>
+ The offset to the next element in the indicator array (for
+ array fetches).
+ </p></li></ol></div><p>
+ </p><p>
+ Note that not all SQL commands are treated in this way. For
+ instance, an open cursor statement like:
+</p><pre class="programlisting">
+EXEC SQL OPEN <em class="replaceable"><code>cursor</code></em>;
+</pre><p>
+ is not copied to the output. Instead, the cursor's
+ <code class="command">DECLARE</code> command is used at the position of the <code class="command">OPEN</code> command
+ because it indeed opens the cursor.
+ </p><p>
+ Here is a complete example describing the output of the
+ preprocessor of a file <code class="filename">foo.pgc</code> (details might
+ change with each particular version of the preprocessor):
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int index;
+int result;
+EXEC SQL END DECLARE SECTION;
+...
+EXEC SQL SELECT res INTO :result FROM mytable WHERE index = :index;
+</pre><p>
+ is translated into:
+</p><pre class="programlisting">
+/* Processed by ecpg (2.6.0) */
+/* These two include files are added by the preprocessor */
+#include &lt;ecpgtype.h&gt;;
+#include &lt;ecpglib.h&gt;;
+
+/* exec sql begin declare section */
+
+#line 1 "foo.pgc"
+
+ int index;
+ int result;
+/* exec sql end declare section */
+...
+ECPGdo(__LINE__, NULL, "SELECT res FROM mytable WHERE index = ? ",
+ ECPGt_int,&amp;(index),1L,1L,sizeof(int),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
+ ECPGt_int,&amp;(result),1L,1L,sizeof(int),
+ ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 147 "foo.pgc"
+
+</pre><p>
+ (The indentation here is added for readability and not
+ something the preprocessor does.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="information-schema.html" title="Chapter 37. The Information Schema">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.16. <span class="productname">Oracle</span> Compatibility Mode </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 37. The Information Schema</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-dynamic.html b/doc/src/sgml/html/ecpg-dynamic.html
new file mode 100644
index 0000000..0cced04
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-dynamic.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.5. Dynamic SQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-variables.html" title="36.4. Using Host Variables" /><link rel="next" href="ecpg-pgtypes.html" title="36.6. pgtypes Library" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.5. Dynamic SQL</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-variables.html" title="36.4. Using Host Variables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-DYNAMIC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.5. Dynamic SQL</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-dynamic.html#ECPG-DYNAMIC-WITHOUT-RESULT">36.5.1. Executing Statements without a Result Set</a></span></dt><dt><span class="sect2"><a href="ecpg-dynamic.html#ECPG-DYNAMIC-INPUT">36.5.2. Executing a Statement with Input Parameters</a></span></dt><dt><span class="sect2"><a href="ecpg-dynamic.html#ECPG-DYNAMIC-WITH-RESULT">36.5.3. Executing a Statement with a Result Set</a></span></dt></dl></div><p>
+ In many cases, the particular SQL statements that an application
+ has to execute are known at the time the application is written.
+ In some cases, however, the SQL statements are composed at run time
+ or provided by an external source. In these cases you cannot embed
+ the SQL statements directly into the C source code, but there is a
+ facility that allows you to call arbitrary SQL statements that you
+ provide in a string variable.
+ </p><div class="sect2" id="ECPG-DYNAMIC-WITHOUT-RESULT"><div class="titlepage"><div><div><h3 class="title">36.5.1. Executing Statements without a Result Set</h3></div></div></div><p>
+ The simplest way to execute an arbitrary SQL statement is to use
+ the command <code class="command">EXECUTE IMMEDIATE</code>. For example:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+const char *stmt = "CREATE TABLE test1 (...);";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL EXECUTE IMMEDIATE :stmt;
+</pre><p>
+ <code class="command">EXECUTE IMMEDIATE</code> can be used for SQL
+ statements that do not return a result set (e.g.,
+ DDL, <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>). You cannot execute statements that
+ retrieve data (e.g., <code class="command">SELECT</code>) this way. The
+ next section describes how to do that.
+ </p></div><div class="sect2" id="ECPG-DYNAMIC-INPUT"><div class="titlepage"><div><div><h3 class="title">36.5.2. Executing a Statement with Input Parameters</h3></div></div></div><p>
+ A more powerful way to execute arbitrary SQL statements is to
+ prepare them once and execute the prepared statement as often as
+ you like. It is also possible to prepare a generalized version of
+ a statement and then execute specific versions of it by
+ substituting parameters. When preparing the statement, write
+ question marks where you want to substitute parameters later. For
+ example:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+const char *stmt = "INSERT INTO test1 VALUES(?, ?);";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE mystmt FROM :stmt;
+ ...
+EXEC SQL EXECUTE mystmt USING 42, 'foobar';
+</pre><p>
+ </p><p>
+ When you don't need the prepared statement anymore, you should
+ deallocate it:
+</p><pre class="programlisting">
+EXEC SQL DEALLOCATE PREPARE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ </p></div><div class="sect2" id="ECPG-DYNAMIC-WITH-RESULT"><div class="titlepage"><div><div><h3 class="title">36.5.3. Executing a Statement with a Result Set</h3></div></div></div><p>
+ To execute an SQL statement with a single result row,
+ <code class="command">EXECUTE</code> can be used. To save the result, add
+ an <code class="literal">INTO</code> clause.
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+const char *stmt = "SELECT a, b, c FROM test1 WHERE a &gt; ?";
+int v1, v2;
+VARCHAR v3[50];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL PREPARE mystmt FROM :stmt;
+ ...
+EXEC SQL EXECUTE mystmt INTO :v1, :v2, :v3 USING 37;
+
+</pre><p>
+ An <code class="command">EXECUTE</code> command can have an
+ <code class="literal">INTO</code> clause, a <code class="literal">USING</code> clause,
+ both, or neither.
+ </p><p>
+ If a query is expected to return more than one result row, a
+ cursor should be used, as in the following example.
+ (See <a class="xref" href="ecpg-commands.html#ECPG-CURSORS" title="36.3.2. Using Cursors">Section 36.3.2</a> for more details about the
+ cursor.)
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+char dbaname[128];
+char datname[128];
+char *stmt = "SELECT u.usename as dbaname, d.datname "
+ " FROM pg_database d, pg_user u "
+ " WHERE d.datdba = u.usesysid";
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+EXEC SQL PREPARE stmt1 FROM :stmt;
+
+EXEC SQL DECLARE cursor1 CURSOR FOR stmt1;
+EXEC SQL OPEN cursor1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ EXEC SQL FETCH cursor1 INTO :dbaname,:datname;
+ printf("dbaname=%s, datname=%s\n", dbaname, datname);
+}
+
+EXEC SQL CLOSE cursor1;
+
+EXEC SQL COMMIT;
+EXEC SQL DISCONNECT ALL;
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-variables.html" title="36.4. Using Host Variables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.4. Using Host Variables </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.6. pgtypes Library</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-errors.html b/doc/src/sgml/html/ecpg-errors.html
new file mode 100644
index 0000000..bac8d22
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-errors.html
@@ -0,0 +1,441 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.8. Error Handling</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas" /><link rel="next" href="ecpg-preproc.html" title="36.9. Preprocessor Directives" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.8. Error Handling</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-preproc.html" title="36.9. Preprocessor Directives">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-ERRORS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.8. Error Handling</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-errors.html#ECPG-WHENEVER">36.8.1. Setting Callbacks</a></span></dt><dt><span class="sect2"><a href="ecpg-errors.html#ECPG-SQLCA">36.8.2. sqlca</a></span></dt><dt><span class="sect2"><a href="ecpg-errors.html#ECPG-SQLSTATE-SQLCODE">36.8.3. <code class="literal">SQLSTATE</code> vs. <code class="literal">SQLCODE</code></a></span></dt></dl></div><p>
+ This section describes how you can handle exceptional conditions
+ and warnings in an embedded SQL program. There are two
+ nonexclusive facilities for this.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
+ Callbacks can be configured to handle warning and error
+ conditions using the <code class="literal">WHENEVER</code> command.
+ </li><li class="listitem">
+ Detailed information about the error or warning can be obtained
+ from the <code class="varname">sqlca</code> variable.
+ </li></ul></div><p>
+ </p><div class="sect2" id="ECPG-WHENEVER"><div class="titlepage"><div><div><h3 class="title">36.8.1. Setting Callbacks</h3></div></div></div><p>
+ One simple method to catch errors and warnings is to set a
+ specific action to be executed whenever a particular condition
+ occurs. In general:
+</p><pre class="programlisting">
+EXEC SQL WHENEVER <em class="replaceable"><code>condition</code></em> <em class="replaceable"><code>action</code></em>;
+</pre><p>
+ </p><p>
+ <em class="replaceable"><code>condition</code></em> can be one of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SQLERROR</code></span></dt><dd><p>
+ The specified action is called whenever an error occurs during
+ the execution of an SQL statement.
+ </p></dd><dt><span class="term"><code class="literal">SQLWARNING</code></span></dt><dd><p>
+ The specified action is called whenever a warning occurs
+ during the execution of an SQL statement.
+ </p></dd><dt><span class="term"><code class="literal">NOT FOUND</code></span></dt><dd><p>
+ The specified action is called whenever an SQL statement
+ retrieves or affects zero rows. (This condition is not an
+ error, but you might be interested in handling it specially.)
+ </p></dd></dl></div><p>
+ </p><p>
+ <em class="replaceable"><code>action</code></em> can be one of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">CONTINUE</code></span></dt><dd><p>
+ This effectively means that the condition is ignored. This is
+ the default.
+ </p></dd><dt><span class="term"><code class="literal">GOTO <em class="replaceable"><code>label</code></em></code><br /></span><span class="term"><code class="literal">GO TO <em class="replaceable"><code>label</code></em></code></span></dt><dd><p>
+ Jump to the specified label (using a C <code class="literal">goto</code>
+ statement).
+ </p></dd><dt><span class="term"><code class="literal">SQLPRINT</code></span></dt><dd><p>
+ Print a message to standard error. This is useful for simple
+ programs or during prototyping. The details of the message
+ cannot be configured.
+ </p></dd><dt><span class="term"><code class="literal">STOP</code></span></dt><dd><p>
+ Call <code class="literal">exit(1)</code>, which will terminate the
+ program.
+ </p></dd><dt><span class="term"><code class="literal">DO BREAK</code></span></dt><dd><p>
+ Execute the C statement <code class="literal">break</code>. This should
+ only be used in loops or <code class="literal">switch</code> statements.
+ </p></dd><dt><span class="term"><code class="literal">DO CONTINUE</code></span></dt><dd><p>
+ Execute the C statement <code class="literal">continue</code>. This should
+ only be used in loops statements. if executed, will cause the flow
+ of control to return to the top of the loop.
+ </p></dd><dt><span class="term"><code class="literal">CALL <em class="replaceable"><code>name</code></em> (<em class="replaceable"><code>args</code></em>)</code><br /></span><span class="term"><code class="literal">DO <em class="replaceable"><code>name</code></em> (<em class="replaceable"><code>args</code></em>)</code></span></dt><dd><p>
+ Call the specified C functions with the specified arguments. (This
+ use is different from the meaning of <code class="literal">CALL</code>
+ and <code class="literal">DO</code> in the normal PostgreSQL grammar.)
+ </p></dd></dl></div><p>
+
+ The SQL standard only provides for the actions
+ <code class="literal">CONTINUE</code> and <code class="literal">GOTO</code> (and
+ <code class="literal">GO TO</code>).
+ </p><p>
+ Here is an example that you might want to use in a simple program.
+ It prints a simple message when a warning occurs and aborts the
+ program when an error happens:
+</p><pre class="programlisting">
+EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+EXEC SQL WHENEVER SQLERROR STOP;
+</pre><p>
+ </p><p>
+ The statement <code class="literal">EXEC SQL WHENEVER</code> is a directive
+ of the SQL preprocessor, not a C statement. The error or warning
+ actions that it sets apply to all embedded SQL statements that
+ appear below the point where the handler is set, unless a
+ different action was set for the same condition between the first
+ <code class="literal">EXEC SQL WHENEVER</code> and the SQL statement causing
+ the condition, regardless of the flow of control in the C program.
+ So neither of the two following C program excerpts will have the
+ desired effect:
+</p><pre class="programlisting">
+/*
+ * WRONG
+ */
+int main(int argc, char *argv[])
+{
+ ...
+ if (verbose) {
+ EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+ }
+ ...
+ EXEC SQL SELECT ...;
+ ...
+}
+</pre><p>
+
+</p><pre class="programlisting">
+/*
+ * WRONG
+ */
+int main(int argc, char *argv[])
+{
+ ...
+ set_error_handler();
+ ...
+ EXEC SQL SELECT ...;
+ ...
+}
+
+static void set_error_handler(void)
+{
+ EXEC SQL WHENEVER SQLERROR STOP;
+}
+</pre><p>
+ </p></div><div class="sect2" id="ECPG-SQLCA"><div class="titlepage"><div><div><h3 class="title">36.8.2. sqlca</h3></div></div></div><p>
+ For more powerful error handling, the embedded SQL interface
+ provides a global variable with the name <code class="varname">sqlca</code>
+ (SQL communication area)
+ that has the following structure:
+</p><pre class="programlisting">
+struct
+{
+ char sqlcaid[8];
+ long sqlabc;
+ long sqlcode;
+ struct
+ {
+ int sqlerrml;
+ char sqlerrmc[SQLERRMC_LEN];
+ } sqlerrm;
+ char sqlerrp[8];
+ long sqlerrd[6];
+ char sqlwarn[8];
+ char sqlstate[5];
+} sqlca;
+</pre><p>
+ (In a multithreaded program, every thread automatically gets its
+ own copy of <code class="varname">sqlca</code>. This works similarly to the
+ handling of the standard C global variable
+ <code class="varname">errno</code>.)
+ </p><p>
+ <code class="varname">sqlca</code> covers both warnings and errors. If
+ multiple warnings or errors occur during the execution of a
+ statement, then <code class="varname">sqlca</code> will only contain
+ information about the last one.
+ </p><p>
+ If no error occurred in the last <acronym class="acronym">SQL</acronym> statement,
+ <code class="literal">sqlca.sqlcode</code> will be 0 and
+ <code class="literal">sqlca.sqlstate</code> will be
+ <code class="literal">"00000"</code>. If a warning or error occurred, then
+ <code class="literal">sqlca.sqlcode</code> will be negative and
+ <code class="literal">sqlca.sqlstate</code> will be different from
+ <code class="literal">"00000"</code>. A positive
+ <code class="literal">sqlca.sqlcode</code> indicates a harmless condition,
+ such as that the last query returned zero rows.
+ <code class="literal">sqlcode</code> and <code class="literal">sqlstate</code> are two
+ different error code schemes; details appear below.
+ </p><p>
+ If the last SQL statement was successful, then
+ <code class="literal">sqlca.sqlerrd[1]</code> contains the OID of the
+ processed row, if applicable, and
+ <code class="literal">sqlca.sqlerrd[2]</code> contains the number of
+ processed or returned rows, if applicable to the command.
+ </p><p>
+ In case of an error or warning,
+ <code class="literal">sqlca.sqlerrm.sqlerrmc</code> will contain a string
+ that describes the error. The field
+ <code class="literal">sqlca.sqlerrm.sqlerrml</code> contains the length of
+ the error message that is stored in
+ <code class="literal">sqlca.sqlerrm.sqlerrmc</code> (the result of
+ <code class="function">strlen()</code>, not really interesting for a C
+ programmer). Note that some messages are too long to fit in the
+ fixed-size <code class="literal">sqlerrmc</code> array; they will be truncated.
+ </p><p>
+ In case of a warning, <code class="literal">sqlca.sqlwarn[2]</code> is set
+ to <code class="literal">W</code>. (In all other cases, it is set to
+ something different from <code class="literal">W</code>.) If
+ <code class="literal">sqlca.sqlwarn[1]</code> is set to
+ <code class="literal">W</code>, then a value was truncated when it was
+ stored in a host variable. <code class="literal">sqlca.sqlwarn[0]</code> is
+ set to <code class="literal">W</code> if any of the other elements are set
+ to indicate a warning.
+ </p><p>
+ The fields <code class="structfield">sqlcaid</code>,
+ <code class="structfield">sqlabc</code>,
+ <code class="structfield">sqlerrp</code>, and the remaining elements of
+ <code class="structfield">sqlerrd</code> and
+ <code class="structfield">sqlwarn</code> currently contain no useful
+ information.
+ </p><p>
+ The structure <code class="varname">sqlca</code> is not defined in the SQL
+ standard, but is implemented in several other SQL database
+ systems. The definitions are similar at the core, but if you want
+ to write portable applications, then you should investigate the
+ different implementations carefully.
+ </p><p>
+ Here is one example that combines the use of <code class="literal">WHENEVER</code>
+ and <code class="varname">sqlca</code>, printing out the contents
+ of <code class="varname">sqlca</code> when an error occurs. This is perhaps
+ useful for debugging or prototyping applications, before
+ installing a more <span class="quote">“<span class="quote">user-friendly</span>”</span> error handler.
+
+</p><pre class="programlisting">
+EXEC SQL WHENEVER SQLERROR CALL print_sqlca();
+
+void
+print_sqlca()
+{
+ fprintf(stderr, "==== sqlca ====\n");
+ fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
+ fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
+ fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
+ fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2],
+ sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]);
+ fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2],
+ sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5],
+ sqlca.sqlwarn[6], sqlca.sqlwarn[7]);
+ fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
+ fprintf(stderr, "===============\n");
+}
+</pre><p>
+
+ The result could look as follows (here an error due to a
+ misspelled table name):
+
+</p><pre class="screen">
+==== sqlca ====
+sqlcode: -400
+sqlerrm.sqlerrml: 49
+sqlerrm.sqlerrmc: relation "pg_databasep" does not exist on line 38
+sqlerrd: 0 0 0 0 0 0
+sqlwarn: 0 0 0 0 0 0 0 0
+sqlstate: 42P01
+===============
+</pre><p>
+ </p></div><div class="sect2" id="ECPG-SQLSTATE-SQLCODE"><div class="titlepage"><div><div><h3 class="title">36.8.3. <code class="literal">SQLSTATE</code> vs. <code class="literal">SQLCODE</code></h3></div></div></div><p>
+ The fields <code class="literal">sqlca.sqlstate</code> and
+ <code class="literal">sqlca.sqlcode</code> are two different schemes that
+ provide error codes. Both are derived from the SQL standard, but
+ <code class="literal">SQLCODE</code> has been marked deprecated in the SQL-92
+ edition of the standard and has been dropped in later editions.
+ Therefore, new applications are strongly encouraged to use
+ <code class="literal">SQLSTATE</code>.
+ </p><p>
+ <code class="literal">SQLSTATE</code> is a five-character array. The five
+ characters contain digits or upper-case letters that represent
+ codes of various error and warning conditions.
+ <code class="literal">SQLSTATE</code> has a hierarchical scheme: the first
+ two characters indicate the general class of the condition, the
+ last three characters indicate a subclass of the general
+ condition. A successful state is indicated by the code
+ <code class="literal">00000</code>. The <code class="literal">SQLSTATE</code> codes are for
+ the most part defined in the SQL standard. The
+ <span class="productname">PostgreSQL</span> server natively supports
+ <code class="literal">SQLSTATE</code> error codes; therefore a high degree
+ of consistency can be achieved by using this error code scheme
+ throughout all applications. For further information see
+ <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>.
+ </p><p>
+ <code class="literal">SQLCODE</code>, the deprecated error code scheme, is a
+ simple integer. A value of 0 indicates success, a positive value
+ indicates success with additional information, a negative value
+ indicates an error. The SQL standard only defines the positive
+ value +100, which indicates that the last command returned or
+ affected zero rows, and no specific negative values. Therefore,
+ this scheme can only achieve poor portability and does not have a
+ hierarchical code assignment. Historically, the embedded SQL
+ processor for <span class="productname">PostgreSQL</span> has assigned
+ some specific <code class="literal">SQLCODE</code> values for its use, which
+ are listed below with their numeric value and their symbolic name.
+ Remember that these are not portable to other SQL implementations.
+ To simplify the porting of applications to the
+ <code class="literal">SQLSTATE</code> scheme, the corresponding
+ <code class="literal">SQLSTATE</code> is also listed. There is, however, no
+ one-to-one or one-to-many mapping between the two schemes (indeed
+ it is many-to-many), so you should consult the global
+ <code class="literal">SQLSTATE</code> listing in <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>
+ in each case.
+ </p><p>
+ These are the assigned <code class="literal">SQLCODE</code> values:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">0 (<code class="symbol">ECPG_NO_ERROR</code>)</span></dt><dd><p>
+ Indicates no error. (SQLSTATE 00000)
+ </p></dd><dt><span class="term">100 (<code class="symbol">ECPG_NOT_FOUND</code>)</span></dt><dd><p>
+ This is a harmless condition indicating that the last command
+ retrieved or processed zero rows, or that you are at the end of
+ the cursor. (SQLSTATE 02000)
+ </p><p>
+ When processing a cursor in a loop, you could use this code as
+ a way to detect when to abort the loop, like this:
+</p><pre class="programlisting">
+while (1)
+{
+ EXEC SQL FETCH ... ;
+ if (sqlca.sqlcode == ECPG_NOT_FOUND)
+ break;
+}
+</pre><p>
+ But <code class="literal">WHENEVER NOT FOUND DO BREAK</code> effectively
+ does this internally, so there is usually no advantage in
+ writing this out explicitly.
+ </p></dd><dt><span class="term">-12 (<code class="symbol">ECPG_OUT_OF_MEMORY</code>)</span></dt><dd><p>
+ Indicates that your virtual memory is exhausted. The numeric
+ value is defined as <code class="literal">-ENOMEM</code>. (SQLSTATE
+ YE001)
+ </p></dd><dt><span class="term">-200 (<code class="symbol">ECPG_UNSUPPORTED</code>)</span></dt><dd><p>
+ Indicates the preprocessor has generated something that the
+ library does not know about. Perhaps you are running
+ incompatible versions of the preprocessor and the
+ library. (SQLSTATE YE002)
+ </p></dd><dt><span class="term">-201 (<code class="symbol">ECPG_TOO_MANY_ARGUMENTS</code>)</span></dt><dd><p>
+ This means that the command specified more host variables than
+ the command expected. (SQLSTATE 07001 or 07002)
+ </p></dd><dt><span class="term">-202 (<code class="symbol">ECPG_TOO_FEW_ARGUMENTS</code>)</span></dt><dd><p>
+ This means that the command specified fewer host variables than
+ the command expected. (SQLSTATE 07001 or 07002)
+ </p></dd><dt><span class="term">-203 (<code class="symbol">ECPG_TOO_MANY_MATCHES</code>)</span></dt><dd><p>
+ This means a query has returned multiple rows but the statement
+ was only prepared to store one result row (for example, because
+ the specified variables are not arrays). (SQLSTATE 21000)
+ </p></dd><dt><span class="term">-204 (<code class="symbol">ECPG_INT_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">int</code> and the datum in
+ the database is of a different type and contains a value that
+ cannot be interpreted as an <code class="type">int</code>. The library uses
+ <code class="function">strtol()</code> for this conversion. (SQLSTATE
+ 42804)
+ </p></dd><dt><span class="term">-205 (<code class="symbol">ECPG_UINT_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">unsigned int</code> and the
+ datum in the database is of a different type and contains a
+ value that cannot be interpreted as an <code class="type">unsigned
+ int</code>. The library uses <code class="function">strtoul()</code>
+ for this conversion. (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-206 (<code class="symbol">ECPG_FLOAT_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">float</code> and the datum
+ in the database is of another type and contains a value that
+ cannot be interpreted as a <code class="type">float</code>. The library
+ uses <code class="function">strtod()</code> for this conversion.
+ (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-207 (<code class="symbol">ECPG_NUMERIC_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">numeric</code> and the datum
+ in the database is of another type and contains a value that
+ cannot be interpreted as a <code class="type">numeric</code> value.
+ (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-208 (<code class="symbol">ECPG_INTERVAL_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">interval</code> and the datum
+ in the database is of another type and contains a value that
+ cannot be interpreted as an <code class="type">interval</code> value.
+ (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-209 (<code class="symbol">ECPG_DATE_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">date</code> and the datum in
+ the database is of another type and contains a value that
+ cannot be interpreted as a <code class="type">date</code> value.
+ (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-210 (<code class="symbol">ECPG_TIMESTAMP_FORMAT</code>)</span></dt><dd><p>
+ The host variable is of type <code class="type">timestamp</code> and the
+ datum in the database is of another type and contains a value
+ that cannot be interpreted as a <code class="type">timestamp</code> value.
+ (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-211 (<code class="symbol">ECPG_CONVERT_BOOL</code>)</span></dt><dd><p>
+ This means the host variable is of type <code class="type">bool</code> and
+ the datum in the database is neither <code class="literal">'t'</code> nor
+ <code class="literal">'f'</code>. (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-212 (<code class="symbol">ECPG_EMPTY</code>)</span></dt><dd><p>
+ The statement sent to the <span class="productname">PostgreSQL</span>
+ server was empty. (This cannot normally happen in an embedded
+ SQL program, so it might point to an internal error.) (SQLSTATE
+ YE002)
+ </p></dd><dt><span class="term">-213 (<code class="symbol">ECPG_MISSING_INDICATOR</code>)</span></dt><dd><p>
+ A null value was returned and no null indicator variable was
+ supplied. (SQLSTATE 22002)
+ </p></dd><dt><span class="term">-214 (<code class="symbol">ECPG_NO_ARRAY</code>)</span></dt><dd><p>
+ An ordinary variable was used in a place that requires an
+ array. (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-215 (<code class="symbol">ECPG_DATA_NOT_ARRAY</code>)</span></dt><dd><p>
+ The database returned an ordinary variable in a place that
+ requires array value. (SQLSTATE 42804)
+ </p></dd><dt><span class="term">-216 (<code class="symbol">ECPG_ARRAY_INSERT</code>)</span></dt><dd><p>
+ The value could not be inserted into the array. (SQLSTATE
+ 42804)
+ </p></dd><dt><span class="term">-220 (<code class="symbol">ECPG_NO_CONN</code>)</span></dt><dd><p>
+ The program tried to access a connection that does not exist.
+ (SQLSTATE 08003)
+ </p></dd><dt><span class="term">-221 (<code class="symbol">ECPG_NOT_CONN</code>)</span></dt><dd><p>
+ The program tried to access a connection that does exist but is
+ not open. (This is an internal error.) (SQLSTATE YE002)
+ </p></dd><dt><span class="term">-230 (<code class="symbol">ECPG_INVALID_STMT</code>)</span></dt><dd><p>
+ The statement you are trying to use has not been prepared.
+ (SQLSTATE 26000)
+ </p></dd><dt><span class="term">-239 (<code class="symbol">ECPG_INFORMIX_DUPLICATE_KEY</code>)</span></dt><dd><p>
+ Duplicate key error, violation of unique constraint (Informix
+ compatibility mode). (SQLSTATE 23505)
+ </p></dd><dt><span class="term">-240 (<code class="symbol">ECPG_UNKNOWN_DESCRIPTOR</code>)</span></dt><dd><p>
+ The descriptor specified was not found. The statement you are
+ trying to use has not been prepared. (SQLSTATE 33000)
+ </p></dd><dt><span class="term">-241 (<code class="symbol">ECPG_INVALID_DESCRIPTOR_INDEX</code>)</span></dt><dd><p>
+ The descriptor index specified was out of range. (SQLSTATE
+ 07009)
+ </p></dd><dt><span class="term">-242 (<code class="symbol">ECPG_UNKNOWN_DESCRIPTOR_ITEM</code>)</span></dt><dd><p>
+ An invalid descriptor item was requested. (This is an internal
+ error.) (SQLSTATE YE002)
+ </p></dd><dt><span class="term">-243 (<code class="symbol">ECPG_VAR_NOT_NUMERIC</code>)</span></dt><dd><p>
+ During the execution of a dynamic statement, the database
+ returned a numeric value and the host variable was not numeric.
+ (SQLSTATE 07006)
+ </p></dd><dt><span class="term">-244 (<code class="symbol">ECPG_VAR_NOT_CHAR</code>)</span></dt><dd><p>
+ During the execution of a dynamic statement, the database
+ returned a non-numeric value and the host variable was numeric.
+ (SQLSTATE 07006)
+ </p></dd><dt><span class="term">-284 (<code class="symbol">ECPG_INFORMIX_SUBSELECT_NOT_ONE</code>)</span></dt><dd><p>
+ A result of the subquery is not single row (Informix
+ compatibility mode). (SQLSTATE 21000)
+ </p></dd><dt><span class="term">-400 (<code class="symbol">ECPG_PGSQL</code>)</span></dt><dd><p>
+ Some error caused by the <span class="productname">PostgreSQL</span>
+ server. The message contains the error message from the
+ <span class="productname">PostgreSQL</span> server.
+ </p></dd><dt><span class="term">-401 (<code class="symbol">ECPG_TRANS</code>)</span></dt><dd><p>
+ The <span class="productname">PostgreSQL</span> server signaled that
+ we cannot start, commit, or rollback the transaction.
+ (SQLSTATE 08007)
+ </p></dd><dt><span class="term">-402 (<code class="symbol">ECPG_CONNECT</code>)</span></dt><dd><p>
+ The connection attempt to the database did not succeed.
+ (SQLSTATE 08001)
+ </p></dd><dt><span class="term">-403 (<code class="symbol">ECPG_DUPLICATE_KEY</code>)</span></dt><dd><p>
+ Duplicate key error, violation of unique constraint. (SQLSTATE
+ 23505)
+ </p></dd><dt><span class="term">-404 (<code class="symbol">ECPG_SUBSELECT_NOT_ONE</code>)</span></dt><dd><p>
+ A result for the subquery is not single row. (SQLSTATE 21000)
+ </p></dd><dt><span class="term">-602 (<code class="symbol">ECPG_WARNING_UNKNOWN_PORTAL</code>)</span></dt><dd><p>
+ An invalid cursor name was specified. (SQLSTATE 34000)
+ </p></dd><dt><span class="term">-603 (<code class="symbol">ECPG_WARNING_IN_TRANSACTION</code>)</span></dt><dd><p>
+ Transaction is in progress. (SQLSTATE 25001)
+ </p></dd><dt><span class="term">-604 (<code class="symbol">ECPG_WARNING_NO_TRANSACTION</code>)</span></dt><dd><p>
+ There is no active (in-progress) transaction. (SQLSTATE 25P01)
+ </p></dd><dt><span class="term">-605 (<code class="symbol">ECPG_WARNING_PORTAL_EXISTS</code>)</span></dt><dd><p>
+ An existing cursor name was specified. (SQLSTATE 42P03)
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-preproc.html" title="36.9. Preprocessor Directives">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.7. Using Descriptor Areas </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.9. Preprocessor Directives</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-informix-compat.html b/doc/src/sgml/html/ecpg-informix-compat.html
new file mode 100644
index 0000000..2e08eb0
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-informix-compat.html
@@ -0,0 +1,892 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.15. Informix Compatibility Mode</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-whenever.html" title="WHENEVER" /><link rel="next" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.15. <span class="productname">Informix</span> Compatibility Mode</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-whenever.html" title="WHENEVER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-INFORMIX-COMPAT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.15. <span class="productname">Informix</span> Compatibility Mode</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-TYPES">36.15.1. Additional Types</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-STATEMENTS">36.15.2. Additional/Missing Embedded SQL Statements</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-SQLDA">36.15.3. Informix-compatible SQLDA Descriptor Areas</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-FUNCTIONS">36.15.4. Additional Functions</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-CONSTANTS">36.15.5. Additional Constants</a></span></dt></dl></div><p>
+ <code class="command">ecpg</code> can be run in a so-called <em class="firstterm">Informix compatibility mode</em>. If
+ this mode is active, it tries to behave as if it were the <span class="productname">Informix</span>
+ precompiler for <span class="productname">Informix</span> E/SQL. Generally spoken this will allow you to use
+ the dollar sign instead of the <code class="literal">EXEC SQL</code> primitive to introduce
+ embedded SQL commands:
+</p><pre class="programlisting">
+$int j = 3;
+$CONNECT TO :dbname;
+$CREATE TABLE test(i INT PRIMARY KEY, j INT);
+$INSERT INTO test(i, j) VALUES (7, :j);
+$COMMIT;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ There must not be any white space between the <code class="literal">$</code>
+ and a following preprocessor directive, that is,
+ <code class="literal">include</code>, <code class="literal">define</code>, <code class="literal">ifdef</code>,
+ etc. Otherwise, the preprocessor will parse the token as a host
+ variable.
+ </p></div><p>
+ There are two compatibility modes: <code class="literal">INFORMIX</code>, <code class="literal">INFORMIX_SE</code>
+ </p><p>
+ When linking programs that use this compatibility mode, remember to link
+ against <code class="literal">libcompat</code> that is shipped with ECPG.
+ </p><p>
+ Besides the previously explained syntactic sugar, the <span class="productname">Informix</span> compatibility
+ mode ports some functions for input, output and transformation of data as
+ well as embedded SQL statements known from E/SQL to ECPG.
+ </p><p>
+ <span class="productname">Informix</span> compatibility mode is closely connected to the pgtypeslib library
+ of ECPG. pgtypeslib maps SQL data types to data types within the C host
+ program and most of the additional functions of the <span class="productname">Informix</span> compatibility
+ mode allow you to operate on those C host program types. Note however that
+ the extent of the compatibility is limited. It does not try to copy <span class="productname">Informix</span>
+ behavior; it allows you to do more or less the same operations and gives
+ you functions that have the same name and the same basic behavior but it is
+ no drop-in replacement if you are using <span class="productname">Informix</span> at the moment. Moreover,
+ some of the data types are different. For example,
+ <span class="productname">PostgreSQL</span>'s datetime and interval types do not
+ know about ranges like for example <code class="literal">YEAR TO MINUTE</code> so you won't
+ find support in ECPG for that either.
+ </p><div class="sect2" id="ECPG-INFORMIX-TYPES"><div class="titlepage"><div><div><h3 class="title">36.15.1. Additional Types</h3></div></div></div><p>
+ The Informix-special "string" pseudo-type for storing right-trimmed character string data is now
+ supported in Informix-mode without using <code class="literal">typedef</code>. In fact, in Informix-mode,
+ ECPG refuses to process source files that contain <code class="literal">typedef sometype string;</code>
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+string userid; /* this variable will contain trimmed data */
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL FETCH MYCUR INTO :userid;
+</pre><p>
+ </p></div><div class="sect2" id="ECPG-INFORMIX-STATEMENTS"><div class="titlepage"><div><div><h3 class="title">36.15.2. Additional/Missing Embedded SQL Statements</h3></div></div></div><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">CLOSE DATABASE</code></span></dt><dd><p>
+ This statement closes the current connection. In fact, this is a
+ synonym for ECPG's <code class="literal">DISCONNECT CURRENT</code>:
+</p><pre class="programlisting">
+$CLOSE DATABASE; /* close the current connection */
+EXEC SQL CLOSE DATABASE;
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">FREE cursor_name</code></span></dt><dd><p>
+ Due to differences in how ECPG works compared to Informix's ESQL/C (namely, which steps
+ are purely grammar transformations and which steps rely on the underlying run-time library)
+ there is no <code class="literal">FREE cursor_name</code> statement in ECPG. This is because in ECPG,
+ <code class="literal">DECLARE CURSOR</code> doesn't translate to a function call into
+ the run-time library that uses to the cursor name. This means that there's no run-time
+ bookkeeping of SQL cursors in the ECPG run-time library, only in the PostgreSQL server.
+ </p></dd><dt><span class="term"><code class="literal">FREE statement_name</code></span></dt><dd><p>
+ <code class="literal">FREE statement_name</code> is a synonym for <code class="literal">DEALLOCATE PREPARE statement_name</code>.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-INFORMIX-SQLDA"><div class="titlepage"><div><div><h3 class="title">36.15.3. Informix-compatible SQLDA Descriptor Areas</h3></div></div></div><p>
+ Informix-compatible mode supports a different structure than the one described in
+ <a class="xref" href="ecpg-descriptors.html#ECPG-SQLDA-DESCRIPTORS" title="36.7.2. SQLDA Descriptor Areas">Section 36.7.2</a>. See below:
+</p><pre class="programlisting">
+struct sqlvar_compat
+{
+ short sqltype;
+ int sqllen;
+ char *sqldata;
+ short *sqlind;
+ char *sqlname;
+ char *sqlformat;
+ short sqlitype;
+ short sqlilen;
+ char *sqlidata;
+ int sqlxid;
+ char *sqltypename;
+ short sqltypelen;
+ short sqlownerlen;
+ short sqlsourcetype;
+ char *sqlownername;
+ int sqlsourceid;
+ char *sqlilongdata;
+ int sqlflags;
+ void *sqlreserved;
+};
+
+struct sqlda_compat
+{
+ short sqld;
+ struct sqlvar_compat *sqlvar;
+ char desc_name[19];
+ short desc_occ;
+ struct sqlda_compat *desc_next;
+ void *reserved;
+};
+
+typedef struct sqlvar_compat sqlvar_t;
+typedef struct sqlda_compat sqlda_t;
+</pre><p>
+ </p><p>
+ The global properties are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">sqld</code></span></dt><dd><p>
+ The number of fields in the <code class="literal">SQLDA</code> descriptor.
+ </p></dd><dt><span class="term"><code class="literal">sqlvar</code></span></dt><dd><p>
+ Pointer to the per-field properties.
+ </p></dd><dt><span class="term"><code class="literal">desc_name</code></span></dt><dd><p>
+ Unused, filled with zero-bytes.
+ </p></dd><dt><span class="term"><code class="literal">desc_occ</code></span></dt><dd><p>
+ Size of the allocated structure.
+ </p></dd><dt><span class="term"><code class="literal">desc_next</code></span></dt><dd><p>
+ Pointer to the next SQLDA structure if the result set contains more than one record.
+ </p></dd><dt><span class="term"><code class="literal">reserved</code></span></dt><dd><p>
+ Unused pointer, contains NULL. Kept for Informix-compatibility.
+ </p></dd></dl></div><p>
+
+ The per-field properties are below, they are stored in the <code class="literal">sqlvar</code> array:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">sqltype</code></span></dt><dd><p>
+ Type of the field. Constants are in <code class="literal">sqltypes.h</code>
+ </p></dd><dt><span class="term"><code class="literal">sqllen</code></span></dt><dd><p>
+ Length of the field data.
+ </p></dd><dt><span class="term"><code class="literal">sqldata</code></span></dt><dd><p>
+ Pointer to the field data. The pointer is of <code class="literal">char *</code> type,
+ the data pointed by it is in a binary format. Example:
+</p><pre class="programlisting">
+int intval;
+
+switch (sqldata-&gt;sqlvar[i].sqltype)
+{
+ case SQLINTEGER:
+ intval = *(int *)sqldata-&gt;sqlvar[i].sqldata;
+ break;
+ ...
+}
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">sqlind</code></span></dt><dd><p>
+ Pointer to the NULL indicator. If returned by DESCRIBE or FETCH then it's always a valid pointer.
+ If used as input for <code class="literal">EXECUTE ... USING sqlda;</code> then NULL-pointer value means
+ that the value for this field is non-NULL. Otherwise a valid pointer and <code class="literal">sqlitype</code>
+ has to be properly set. Example:
+</p><pre class="programlisting">
+if (*(int2 *)sqldata-&gt;sqlvar[i].sqlind != 0)
+ printf("value is NULL\n");
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">sqlname</code></span></dt><dd><p>
+ Name of the field. 0-terminated string.
+ </p></dd><dt><span class="term"><code class="literal">sqlformat</code></span></dt><dd><p>
+ Reserved in Informix, value of <a class="xref" href="libpq-exec.html#LIBPQ-PQFFORMAT"><code class="function">PQfformat</code></a> for the field.
+ </p></dd><dt><span class="term"><code class="literal">sqlitype</code></span></dt><dd><p>
+ Type of the NULL indicator data. It's always SQLSMINT when returning data from the server.
+ When the <code class="literal">SQLDA</code> is used for a parameterized query, the data is treated
+ according to the set type.
+ </p></dd><dt><span class="term"><code class="literal">sqlilen</code></span></dt><dd><p>
+ Length of the NULL indicator data.
+ </p></dd><dt><span class="term"><code class="literal">sqlxid</code></span></dt><dd><p>
+ Extended type of the field, result of <a class="xref" href="libpq-exec.html#LIBPQ-PQFTYPE"><code class="function">PQftype</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">sqltypename</code><br /></span><span class="term"><code class="literal">sqltypelen</code><br /></span><span class="term"><code class="literal">sqlownerlen</code><br /></span><span class="term"><code class="literal">sqlsourcetype</code><br /></span><span class="term"><code class="literal">sqlownername</code><br /></span><span class="term"><code class="literal">sqlsourceid</code><br /></span><span class="term"><code class="literal">sqlflags</code><br /></span><span class="term"><code class="literal">sqlreserved</code></span></dt><dd><p>
+ Unused.
+ </p></dd><dt><span class="term"><code class="literal">sqlilongdata</code></span></dt><dd><p>
+ It equals to <code class="literal">sqldata</code> if <code class="literal">sqllen</code> is larger than 32kB.
+ </p></dd></dl></div><p>
+
+ Example:
+</p><pre class="programlisting">
+EXEC SQL INCLUDE sqlda.h;
+
+ sqlda_t *sqlda; /* This doesn't need to be under embedded DECLARE SECTION */
+
+ EXEC SQL BEGIN DECLARE SECTION;
+ char *prep_stmt = "select * from table1";
+ int i;
+ EXEC SQL END DECLARE SECTION;
+
+ ...
+
+ EXEC SQL PREPARE mystmt FROM :prep_stmt;
+
+ EXEC SQL DESCRIBE mystmt INTO sqlda;
+
+ printf("# of fields: %d\n", sqlda-&gt;sqld);
+ for (i = 0; i &lt; sqlda-&gt;sqld; i++)
+ printf("field %d: \"%s\"\n", sqlda-&gt;sqlvar[i]-&gt;sqlname);
+
+ EXEC SQL DECLARE mycursor CURSOR FOR mystmt;
+ EXEC SQL OPEN mycursor;
+ EXEC SQL WHENEVER NOT FOUND GOTO out;
+
+ while (1)
+ {
+ EXEC SQL FETCH mycursor USING sqlda;
+ }
+
+ EXEC SQL CLOSE mycursor;
+
+ free(sqlda); /* The main structure is all to be free(),
+ * sqlda and sqlda-&gt;sqlvar is in one allocated area */
+</pre><p>
+ For more information, see the <code class="literal">sqlda.h</code> header and the
+ <code class="literal">src/interfaces/ecpg/test/compat_informix/sqlda.pgc</code> regression test.
+ </p></div><div class="sect2" id="ECPG-INFORMIX-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">36.15.4. Additional Functions</h3></div></div></div><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">decadd</code></span></dt><dd><p>
+ Add two decimal type values.
+</p><pre class="synopsis">
+int decadd(decimal *arg1, decimal *arg2, decimal *sum);
+</pre><p>
+ The function receives a pointer to the first operand of type decimal
+ (<code class="literal">arg1</code>), a pointer to the second operand of type decimal
+ (<code class="literal">arg2</code>) and a pointer to a value of type decimal that will
+ contain the sum (<code class="literal">sum</code>). On success, the function returns 0.
+ <code class="symbol">ECPG_INFORMIX_NUM_OVERFLOW</code> is returned in case of overflow and
+ <code class="symbol">ECPG_INFORMIX_NUM_UNDERFLOW</code> in case of underflow. -1 is returned for
+ other failures and <code class="varname">errno</code> is set to the respective <code class="varname">errno</code> number of the
+ pgtypeslib.
+ </p></dd><dt><span class="term"><code class="function">deccmp</code></span></dt><dd><p>
+ Compare two variables of type decimal.
+</p><pre class="synopsis">
+int deccmp(decimal *arg1, decimal *arg2);
+</pre><p>
+ The function receives a pointer to the first decimal value
+ (<code class="literal">arg1</code>), a pointer to the second decimal value
+ (<code class="literal">arg2</code>) and returns an integer value that indicates which is
+ the bigger value.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ 1, if the value that <code class="literal">arg1</code> points to is bigger than the
+ value that <code class="literal">var2</code> points to
+ </p></li><li class="listitem"><p>
+ -1, if the value that <code class="literal">arg1</code> points to is smaller than the
+ value that <code class="literal">arg2</code> points to </p></li><li class="listitem"><p>
+ 0, if the value that <code class="literal">arg1</code> points to and the value that
+ <code class="literal">arg2</code> points to are equal
+ </p></li></ul></div><p>
+ </p></dd><dt><span class="term"><code class="function">deccopy</code></span></dt><dd><p>
+ Copy a decimal value.
+</p><pre class="synopsis">
+void deccopy(decimal *src, decimal *target);
+</pre><p>
+ The function receives a pointer to the decimal value that should be
+ copied as the first argument (<code class="literal">src</code>) and a pointer to the
+ target structure of type decimal (<code class="literal">target</code>) as the second
+ argument.
+ </p></dd><dt><span class="term"><code class="function">deccvasc</code></span></dt><dd><p>
+ Convert a value from its ASCII representation into a decimal type.
+</p><pre class="synopsis">
+int deccvasc(char *cp, int len, decimal *np);
+</pre><p>
+ The function receives a pointer to string that contains the string
+ representation of the number to be converted (<code class="literal">cp</code>) as well
+ as its length <code class="literal">len</code>. <code class="literal">np</code> is a pointer to the
+ decimal value that saves the result of the operation.
+ </p><p>
+ Valid formats are for example:
+ <code class="literal">-2</code>,
+ <code class="literal">.794</code>,
+ <code class="literal">+3.44</code>,
+ <code class="literal">592.49E07</code> or
+ <code class="literal">-32.84e-4</code>.
+ </p><p>
+ The function returns 0 on success. If overflow or underflow occurred,
+ <code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code> or
+ <code class="literal">ECPG_INFORMIX_NUM_UNDERFLOW</code> is returned. If the ASCII
+ representation could not be parsed,
+ <code class="literal">ECPG_INFORMIX_BAD_NUMERIC</code> is returned or
+ <code class="literal">ECPG_INFORMIX_BAD_EXPONENT</code> if this problem occurred while
+ parsing the exponent.
+ </p></dd><dt><span class="term"><code class="function">deccvdbl</code></span></dt><dd><p>
+ Convert a value of type double to a value of type decimal.
+</p><pre class="synopsis">
+int deccvdbl(double dbl, decimal *np);
+</pre><p>
+ The function receives the variable of type double that should be
+ converted as its first argument (<code class="literal">dbl</code>). As the second
+ argument (<code class="literal">np</code>), the function receives a pointer to the
+ decimal variable that should hold the result of the operation.
+ </p><p>
+ The function returns 0 on success and a negative value if the
+ conversion failed.
+ </p></dd><dt><span class="term"><code class="function">deccvint</code></span></dt><dd><p>
+ Convert a value of type int to a value of type decimal.
+</p><pre class="synopsis">
+int deccvint(int in, decimal *np);
+</pre><p>
+ The function receives the variable of type int that should be
+ converted as its first argument (<code class="literal">in</code>). As the second
+ argument (<code class="literal">np</code>), the function receives a pointer to the
+ decimal variable that should hold the result of the operation.
+ </p><p>
+ The function returns 0 on success and a negative value if the
+ conversion failed.
+ </p></dd><dt><span class="term"><code class="function">deccvlong</code></span></dt><dd><p>
+ Convert a value of type long to a value of type decimal.
+</p><pre class="synopsis">
+int deccvlong(long lng, decimal *np);
+</pre><p>
+ The function receives the variable of type long that should be
+ converted as its first argument (<code class="literal">lng</code>). As the second
+ argument (<code class="literal">np</code>), the function receives a pointer to the
+ decimal variable that should hold the result of the operation.
+ </p><p>
+ The function returns 0 on success and a negative value if the
+ conversion failed.
+ </p></dd><dt><span class="term"><code class="function">decdiv</code></span></dt><dd><p>
+ Divide two variables of type decimal.
+</p><pre class="synopsis">
+int decdiv(decimal *n1, decimal *n2, decimal *result);
+</pre><p>
+ The function receives pointers to the variables that are the first
+ (<code class="literal">n1</code>) and the second (<code class="literal">n2</code>) operands and
+ calculates <code class="literal">n1</code>/<code class="literal">n2</code>. <code class="literal">result</code> is a
+ pointer to the variable that should hold the result of the operation.
+ </p><p>
+ On success, 0 is returned and a negative value if the division fails.
+ If overflow or underflow occurred, the function returns
+ <code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code> or
+ <code class="literal">ECPG_INFORMIX_NUM_UNDERFLOW</code> respectively. If an attempt to
+ divide by zero is observed, the function returns
+ <code class="literal">ECPG_INFORMIX_DIVIDE_ZERO</code>.
+ </p></dd><dt><span class="term"><code class="function">decmul</code></span></dt><dd><p>
+ Multiply two decimal values.
+</p><pre class="synopsis">
+int decmul(decimal *n1, decimal *n2, decimal *result);
+</pre><p>
+ The function receives pointers to the variables that are the first
+ (<code class="literal">n1</code>) and the second (<code class="literal">n2</code>) operands and
+ calculates <code class="literal">n1</code>*<code class="literal">n2</code>. <code class="literal">result</code> is a
+ pointer to the variable that should hold the result of the operation.
+ </p><p>
+ On success, 0 is returned and a negative value if the multiplication
+ fails. If overflow or underflow occurred, the function returns
+ <code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code> or
+ <code class="literal">ECPG_INFORMIX_NUM_UNDERFLOW</code> respectively.
+ </p></dd><dt><span class="term"><code class="function">decsub</code></span></dt><dd><p>
+ Subtract one decimal value from another.
+</p><pre class="synopsis">
+int decsub(decimal *n1, decimal *n2, decimal *result);
+</pre><p>
+ The function receives pointers to the variables that are the first
+ (<code class="literal">n1</code>) and the second (<code class="literal">n2</code>) operands and
+ calculates <code class="literal">n1</code>-<code class="literal">n2</code>. <code class="literal">result</code> is a
+ pointer to the variable that should hold the result of the operation.
+ </p><p>
+ On success, 0 is returned and a negative value if the subtraction
+ fails. If overflow or underflow occurred, the function returns
+ <code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code> or
+ <code class="literal">ECPG_INFORMIX_NUM_UNDERFLOW</code> respectively.
+ </p></dd><dt><span class="term"><code class="function">dectoasc</code></span></dt><dd><p>
+ Convert a variable of type decimal to its ASCII representation in a C
+ char* string.
+</p><pre class="synopsis">
+int dectoasc(decimal *np, char *cp, int len, int right)
+</pre><p>
+ The function receives a pointer to a variable of type decimal
+ (<code class="literal">np</code>) that it converts to its textual representation.
+ <code class="literal">cp</code> is the buffer that should hold the result of the
+ operation. The parameter <code class="literal">right</code> specifies, how many digits
+ right of the decimal point should be included in the output. The result
+ will be rounded to this number of decimal digits. Setting
+ <code class="literal">right</code> to -1 indicates that all available decimal digits
+ should be included in the output. If the length of the output buffer,
+ which is indicated by <code class="literal">len</code> is not sufficient to hold the
+ textual representation including the trailing zero byte, only a
+ single <code class="literal">*</code> character is stored in the result and -1 is
+ returned.
+ </p><p>
+ The function returns either -1 if the buffer <code class="literal">cp</code> was too
+ small or <code class="literal">ECPG_INFORMIX_OUT_OF_MEMORY</code> if memory was
+ exhausted.
+ </p></dd><dt><span class="term"><code class="function">dectodbl</code></span></dt><dd><p>
+ Convert a variable of type decimal to a double.
+</p><pre class="synopsis">
+int dectodbl(decimal *np, double *dblp);
+</pre><p>
+ The function receives a pointer to the decimal value to convert
+ (<code class="literal">np</code>) and a pointer to the double variable that
+ should hold the result of the operation (<code class="literal">dblp</code>).
+ </p><p>
+ On success, 0 is returned and a negative value if the conversion
+ failed.
+ </p></dd><dt><span class="term"><code class="function">dectoint</code></span></dt><dd><p>
+ Convert a variable to type decimal to an integer.
+</p><pre class="synopsis">
+int dectoint(decimal *np, int *ip);
+</pre><p>
+ The function receives a pointer to the decimal value to convert
+ (<code class="literal">np</code>) and a pointer to the integer variable that
+ should hold the result of the operation (<code class="literal">ip</code>).
+ </p><p>
+ On success, 0 is returned and a negative value if the conversion
+ failed. If an overflow occurred, <code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code>
+ is returned.
+ </p><p>
+ Note that the ECPG implementation differs from the <span class="productname">Informix</span>
+ implementation. <span class="productname">Informix</span> limits an integer to the range from -32767 to
+ 32767, while the limits in the ECPG implementation depend on the
+ architecture (<code class="literal">INT_MIN .. INT_MAX</code>).
+ </p></dd><dt><span class="term"><code class="function">dectolong</code></span></dt><dd><p>
+ Convert a variable to type decimal to a long integer.
+</p><pre class="synopsis">
+int dectolong(decimal *np, long *lngp);
+</pre><p>
+ The function receives a pointer to the decimal value to convert
+ (<code class="literal">np</code>) and a pointer to the long variable that
+ should hold the result of the operation (<code class="literal">lngp</code>).
+ </p><p>
+ On success, 0 is returned and a negative value if the conversion
+ failed. If an overflow occurred, <code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code>
+ is returned.
+ </p><p>
+ Note that the ECPG implementation differs from the <span class="productname">Informix</span>
+ implementation. <span class="productname">Informix</span> limits a long integer to the range from
+ -2,147,483,647 to 2,147,483,647, while the limits in the ECPG
+ implementation depend on the architecture (<code class="literal">-LONG_MAX ..
+ LONG_MAX</code>).
+ </p></dd><dt><span class="term"><code class="function">rdatestr</code></span></dt><dd><p>
+ Converts a date to a C char* string.
+</p><pre class="synopsis">
+int rdatestr(date d, char *str);
+</pre><p>
+ The function receives two arguments, the first one is the date to
+ convert (<code class="literal">d</code>) and the second one is a pointer to the target
+ string. The output format is always <code class="literal">yyyy-mm-dd</code>, so you need
+ to allocate at least 11 bytes (including the zero-byte terminator) for the
+ string.
+ </p><p>
+ The function returns 0 on success and a negative value in case of
+ error.
+ </p><p>
+ Note that ECPG's implementation differs from the <span class="productname">Informix</span>
+ implementation. In <span class="productname">Informix</span> the format can be influenced by setting
+ environment variables. In ECPG however, you cannot change the output
+ format.
+ </p></dd><dt><span class="term"><code class="function">rstrdate</code></span></dt><dd><p>
+ Parse the textual representation of a date.
+</p><pre class="synopsis">
+int rstrdate(char *str, date *d);
+</pre><p>
+ The function receives the textual representation of the date to convert
+ (<code class="literal">str</code>) and a pointer to a variable of type date
+ (<code class="literal">d</code>). This function does not allow you to specify a format
+ mask. It uses the default format mask of <span class="productname">Informix</span> which is
+ <code class="literal">mm/dd/yyyy</code>. Internally, this function is implemented by
+ means of <code class="function">rdefmtdate</code>. Therefore, <code class="function">rstrdate</code> is
+ not faster and if you have the choice you should opt for
+ <code class="function">rdefmtdate</code> which allows you to specify the format mask
+ explicitly.
+ </p><p>
+ The function returns the same values as <code class="function">rdefmtdate</code>.
+ </p></dd><dt><span class="term"><code class="function">rtoday</code></span></dt><dd><p>
+ Get the current date.
+</p><pre class="synopsis">
+void rtoday(date *d);
+</pre><p>
+ The function receives a pointer to a date variable (<code class="literal">d</code>)
+ that it sets to the current date.
+ </p><p>
+ Internally this function uses the <a class="xref" href="ecpg-pgtypes.html#PGTYPESDATETODAY"><code class="function">PGTYPESdate_today</code></a>
+ function.
+ </p></dd><dt><span class="term"><code class="function">rjulmdy</code></span></dt><dd><p>
+ Extract the values for the day, the month and the year from a variable
+ of type date.
+</p><pre class="synopsis">
+int rjulmdy(date d, short mdy[3]);
+</pre><p>
+ The function receives the date <code class="literal">d</code> and a pointer to an array
+ of 3 short integer values <code class="literal">mdy</code>. The variable name indicates
+ the sequential order: <code class="literal">mdy[0]</code> will be set to contain the
+ number of the month, <code class="literal">mdy[1]</code> will be set to the value of the
+ day and <code class="literal">mdy[2]</code> will contain the year.
+ </p><p>
+ The function always returns 0 at the moment.
+ </p><p>
+ Internally the function uses the <a class="xref" href="ecpg-pgtypes.html#PGTYPESDATEJULMDY"><code class="function">PGTYPESdate_julmdy</code></a>
+ function.
+ </p></dd><dt><span class="term"><code class="function">rdefmtdate</code></span></dt><dd><p>
+ Use a format mask to convert a character string to a value of type
+ date.
+</p><pre class="synopsis">
+int rdefmtdate(date *d, char *fmt, char *str);
+</pre><p>
+ The function receives a pointer to the date value that should hold the
+ result of the operation (<code class="literal">d</code>), the format mask to use for
+ parsing the date (<code class="literal">fmt</code>) and the C char* string containing
+ the textual representation of the date (<code class="literal">str</code>). The textual
+ representation is expected to match the format mask. However you do not
+ need to have a 1:1 mapping of the string to the format mask. The
+ function only analyzes the sequential order and looks for the literals
+ <code class="literal">yy</code> or <code class="literal">yyyy</code> that indicate the
+ position of the year, <code class="literal">mm</code> to indicate the position of
+ the month and <code class="literal">dd</code> to indicate the position of the
+ day.
+ </p><p>
+ The function returns the following values:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ 0 - The function terminated successfully.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ECPG_INFORMIX_ENOSHORTDATE</code> - The date does not contain
+ delimiters between day, month and year. In this case the input
+ string must be exactly 6 or 8 bytes long but isn't.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ECPG_INFORMIX_ENOTDMY</code> - The format string did not
+ correctly indicate the sequential order of year, month and day.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ECPG_INFORMIX_BAD_DAY</code> - The input string does not
+ contain a valid day.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ECPG_INFORMIX_BAD_MONTH</code> - The input string does not
+ contain a valid month.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ECPG_INFORMIX_BAD_YEAR</code> - The input string does not
+ contain a valid year.
+ </p></li></ul></div><p>
+ </p><p>
+ Internally this function is implemented to use the <a class="xref" href="ecpg-pgtypes.html#PGTYPESDATEDEFMTASC"><code class="function">PGTYPESdate_defmt_asc</code></a> function. See the reference there for a
+ table of example input.
+ </p></dd><dt><span class="term"><code class="function">rfmtdate</code></span></dt><dd><p>
+ Convert a variable of type date to its textual representation using a
+ format mask.
+</p><pre class="synopsis">
+int rfmtdate(date d, char *fmt, char *str);
+</pre><p>
+ The function receives the date to convert (<code class="literal">d</code>), the format
+ mask (<code class="literal">fmt</code>) and the string that will hold the textual
+ representation of the date (<code class="literal">str</code>).
+ </p><p>
+ On success, 0 is returned and a negative value if an error occurred.
+ </p><p>
+ Internally this function uses the <a class="xref" href="ecpg-pgtypes.html#PGTYPESDATEFMTASC"><code class="function">PGTYPESdate_fmt_asc</code></a>
+ function, see the reference there for examples.
+ </p></dd><dt><span class="term"><code class="function">rmdyjul</code></span></dt><dd><p>
+ Create a date value from an array of 3 short integers that specify the
+ day, the month and the year of the date.
+</p><pre class="synopsis">
+int rmdyjul(short mdy[3], date *d);
+</pre><p>
+ The function receives the array of the 3 short integers
+ (<code class="literal">mdy</code>) and a pointer to a variable of type date that should
+ hold the result of the operation.
+ </p><p>
+ Currently the function returns always 0.
+ </p><p>
+ Internally the function is implemented to use the function <a class="xref" href="ecpg-pgtypes.html#PGTYPESDATEMDYJUL"><code class="function">PGTYPESdate_mdyjul</code></a>.
+ </p></dd><dt><span class="term"><code class="function">rdayofweek</code></span></dt><dd><p>
+ Return a number representing the day of the week for a date value.
+</p><pre class="synopsis">
+int rdayofweek(date d);
+</pre><p>
+ The function receives the date variable <code class="literal">d</code> as its only
+ argument and returns an integer that indicates the day of the week for
+ this date.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ 0 - Sunday
+ </p></li><li class="listitem"><p>
+ 1 - Monday
+ </p></li><li class="listitem"><p>
+ 2 - Tuesday
+ </p></li><li class="listitem"><p>
+ 3 - Wednesday
+ </p></li><li class="listitem"><p>
+ 4 - Thursday
+ </p></li><li class="listitem"><p>
+ 5 - Friday
+ </p></li><li class="listitem"><p>
+ 6 - Saturday
+ </p></li></ul></div><p>
+ </p><p>
+ Internally the function is implemented to use the function <a class="xref" href="ecpg-pgtypes.html#PGTYPESDATEDAYOFWEEK"><code class="function">PGTYPESdate_dayofweek</code></a>.
+ </p></dd><dt><span class="term"><code class="function">dtcurrent</code></span></dt><dd><p>
+ Retrieve the current timestamp.
+</p><pre class="synopsis">
+void dtcurrent(timestamp *ts);
+</pre><p>
+ The function retrieves the current timestamp and saves it into the
+ timestamp variable that <code class="literal">ts</code> points to.
+ </p></dd><dt><span class="term"><code class="function">dtcvasc</code></span></dt><dd><p>
+ Parses a timestamp from its textual representation
+ into a timestamp variable.
+</p><pre class="synopsis">
+int dtcvasc(char *str, timestamp *ts);
+</pre><p>
+ The function receives the string to parse (<code class="literal">str</code>) and a
+ pointer to the timestamp variable that should hold the result of the
+ operation (<code class="literal">ts</code>).
+ </p><p>
+ The function returns 0 on success and a negative value in case of
+ error.
+ </p><p>
+ Internally this function uses the <a class="xref" href="ecpg-pgtypes.html#PGTYPESTIMESTAMPFROMASC"><code class="function">PGTYPEStimestamp_from_asc</code></a> function. See the reference there
+ for a table with example inputs.
+ </p></dd><dt><span class="term"><code class="function">dtcvfmtasc</code></span></dt><dd><p>
+ Parses a timestamp from its textual representation
+ using a format mask into a timestamp variable.
+</p><pre class="synopsis">
+dtcvfmtasc(char *inbuf, char *fmtstr, timestamp *dtvalue)
+</pre><p>
+ The function receives the string to parse (<code class="literal">inbuf</code>), the
+ format mask to use (<code class="literal">fmtstr</code>) and a pointer to the timestamp
+ variable that should hold the result of the operation
+ (<code class="literal">dtvalue</code>).
+ </p><p>
+ This function is implemented by means of the <a class="xref" href="ecpg-pgtypes.html#PGTYPESTIMESTAMPDEFMTASC"><code class="function">PGTYPEStimestamp_defmt_asc</code></a> function. See the documentation
+ there for a list of format specifiers that can be used.
+ </p><p>
+ The function returns 0 on success and a negative value in case of
+ error.
+ </p></dd><dt><span class="term"><code class="function">dtsub</code></span></dt><dd><p>
+ Subtract one timestamp from another and return a variable of type
+ interval.
+</p><pre class="synopsis">
+int dtsub(timestamp *ts1, timestamp *ts2, interval *iv);
+</pre><p>
+ The function will subtract the timestamp variable that <code class="literal">ts2</code>
+ points to from the timestamp variable that <code class="literal">ts1</code> points to
+ and will store the result in the interval variable that <code class="literal">iv</code>
+ points to.
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p></dd><dt><span class="term"><code class="function">dttoasc</code></span></dt><dd><p>
+ Convert a timestamp variable to a C char* string.
+</p><pre class="synopsis">
+int dttoasc(timestamp *ts, char *output);
+</pre><p>
+ The function receives a pointer to the timestamp variable to convert
+ (<code class="literal">ts</code>) and the string that should hold the result of the
+ operation (<code class="literal">output</code>). It converts <code class="literal">ts</code> to its
+ textual representation according to the SQL standard, which is
+ be <code class="literal">YYYY-MM-DD HH:MM:SS</code>.
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p></dd><dt><span class="term"><code class="function">dttofmtasc</code></span></dt><dd><p>
+ Convert a timestamp variable to a C char* using a format mask.
+</p><pre class="synopsis">
+int dttofmtasc(timestamp *ts, char *output, int str_len, char *fmtstr);
+</pre><p>
+ The function receives a pointer to the timestamp to convert as its
+ first argument (<code class="literal">ts</code>), a pointer to the output buffer
+ (<code class="literal">output</code>), the maximal length that has been allocated for
+ the output buffer (<code class="literal">str_len</code>) and the format mask to
+ use for the conversion (<code class="literal">fmtstr</code>).
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p><p>
+ Internally, this function uses the <a class="xref" href="ecpg-pgtypes.html#PGTYPESTIMESTAMPFMTASC"><code class="function">PGTYPEStimestamp_fmt_asc</code></a> function. See the reference there for
+ information on what format mask specifiers can be used.
+ </p></dd><dt><span class="term"><code class="function">intoasc</code></span></dt><dd><p>
+ Convert an interval variable to a C char* string.
+</p><pre class="synopsis">
+int intoasc(interval *i, char *str);
+</pre><p>
+ The function receives a pointer to the interval variable to convert
+ (<code class="literal">i</code>) and the string that should hold the result of the
+ operation (<code class="literal">str</code>). It converts <code class="literal">i</code> to its
+ textual representation according to the SQL standard, which is
+ be <code class="literal">YYYY-MM-DD HH:MM:SS</code>.
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p></dd><dt><span class="term"><code class="function">rfmtlong</code></span></dt><dd><p>
+ Convert a long integer value to its textual representation using a
+ format mask.
+</p><pre class="synopsis">
+int rfmtlong(long lng_val, char *fmt, char *outbuf);
+</pre><p>
+ The function receives the long value <code class="literal">lng_val</code>, the format
+ mask <code class="literal">fmt</code> and a pointer to the output buffer
+ <code class="literal">outbuf</code>. It converts the long value according to the format
+ mask to its textual representation.
+ </p><p>
+ The format mask can be composed of the following format specifying
+ characters:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">*</code> (asterisk) - if this position would be blank
+ otherwise, fill it with an asterisk.
+ </p></li><li class="listitem"><p>
+ <code class="literal">&amp;</code> (ampersand) - if this position would be
+ blank otherwise, fill it with a zero.
+ </p></li><li class="listitem"><p>
+ <code class="literal">#</code> - turn leading zeroes into blanks.
+ </p></li><li class="listitem"><p>
+ <code class="literal">&lt;</code> - left-justify the number in the string.
+ </p></li><li class="listitem"><p>
+ <code class="literal">,</code> (comma) - group numbers of four or more digits
+ into groups of three digits separated by a comma.
+ </p></li><li class="listitem"><p>
+ <code class="literal">.</code> (period) - this character separates the
+ whole-number part of the number from the fractional part.
+ </p></li><li class="listitem"><p>
+ <code class="literal">-</code> (minus) - the minus sign appears if the number
+ is a negative value.
+ </p></li><li class="listitem"><p>
+ <code class="literal">+</code> (plus) - the plus sign appears if the number is
+ a positive value.
+ </p></li><li class="listitem"><p>
+ <code class="literal">(</code> - this replaces the minus sign in front of the
+ negative number. The minus sign will not appear.
+ </p></li><li class="listitem"><p>
+ <code class="literal">)</code> - this character replaces the minus and is
+ printed behind the negative value.
+ </p></li><li class="listitem"><p>
+ <code class="literal">$</code> - the currency symbol.
+ </p></li></ul></div><p>
+ </p></dd><dt><span class="term"><code class="function">rupshift</code></span></dt><dd><p>
+ Convert a string to upper case.
+</p><pre class="synopsis">
+void rupshift(char *str);
+</pre><p>
+ The function receives a pointer to the string and transforms every
+ lower case character to upper case.
+ </p></dd><dt><span class="term"><code class="function">byleng</code></span></dt><dd><p>
+ Return the number of characters in a string without counting trailing
+ blanks.
+</p><pre class="synopsis">
+int byleng(char *str, int len);
+</pre><p>
+ The function expects a fixed-length string as its first argument
+ (<code class="literal">str</code>) and its length as its second argument
+ (<code class="literal">len</code>). It returns the number of significant characters,
+ that is the length of the string without trailing blanks.
+ </p></dd><dt><span class="term"><code class="function">ldchar</code></span></dt><dd><p>
+ Copy a fixed-length string into a null-terminated string.
+</p><pre class="synopsis">
+void ldchar(char *src, int len, char *dest);
+</pre><p>
+ The function receives the fixed-length string to copy
+ (<code class="literal">src</code>), its length (<code class="literal">len</code>) and a pointer to the
+ destination memory (<code class="literal">dest</code>). Note that you need to reserve at
+ least <code class="literal">len+1</code> bytes for the string that <code class="literal">dest</code>
+ points to. The function copies at most <code class="literal">len</code> bytes to the new
+ location (less if the source string has trailing blanks) and adds the
+ null-terminator.
+ </p></dd><dt><span class="term"><code class="function">rgetmsg</code></span></dt><dd><p>
+</p><pre class="synopsis">
+int rgetmsg(int msgnum, char *s, int maxsize);
+</pre><p>
+ This function exists but is not implemented at the moment!
+ </p></dd><dt><span class="term"><code class="function">rtypalign</code></span></dt><dd><p>
+</p><pre class="synopsis">
+int rtypalign(int offset, int type);
+</pre><p>
+ This function exists but is not implemented at the moment!
+ </p></dd><dt><span class="term"><code class="function">rtypmsize</code></span></dt><dd><p>
+</p><pre class="synopsis">
+int rtypmsize(int type, int len);
+</pre><p>
+ This function exists but is not implemented at the moment!
+ </p></dd><dt><span class="term"><code class="function">rtypwidth</code></span></dt><dd><p>
+</p><pre class="synopsis">
+int rtypwidth(int sqltype, int sqllen);
+</pre><p>
+ This function exists but is not implemented at the moment!
+ </p></dd><dt id="RSETNULL"><span class="term"><code class="function">rsetnull</code></span></dt><dd><p>
+ Set a variable to NULL.
+</p><pre class="synopsis">
+int rsetnull(int t, char *ptr);
+</pre><p>
+ The function receives an integer that indicates the type of the
+ variable and a pointer to the variable itself that is cast to a C
+ char* pointer.
+ </p><p>
+ The following types exist:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">CCHARTYPE</code> - For a variable of type <code class="type">char</code> or <code class="type">char*</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CSHORTTYPE</code> - For a variable of type <code class="type">short int</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CINTTYPE</code> - For a variable of type <code class="type">int</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CBOOLTYPE</code> - For a variable of type <code class="type">boolean</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CFLOATTYPE</code> - For a variable of type <code class="type">float</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CLONGTYPE</code> - For a variable of type <code class="type">long</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CDOUBLETYPE</code> - For a variable of type <code class="type">double</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CDECIMALTYPE</code> - For a variable of type <code class="type">decimal</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CDATETYPE</code> - For a variable of type <code class="type">date</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">CDTIMETYPE</code> - For a variable of type <code class="type">timestamp</code>
+ </p></li></ul></div><p>
+ </p><p>
+ Here is an example of a call to this function:
+</p><pre class="programlisting">
+$char c[] = "abc ";
+$short s = 17;
+$int i = -74874;
+
+rsetnull(CCHARTYPE, (char *) c);
+rsetnull(CSHORTTYPE, (char *) &amp;s);
+rsetnull(CINTTYPE, (char *) &amp;i);
+
+</pre><p>
+ </p></dd><dt><span class="term"><code class="function">risnull</code></span></dt><dd><p>
+ Test if a variable is NULL.
+</p><pre class="synopsis">
+int risnull(int t, char *ptr);
+</pre><p>
+ The function receives the type of the variable to test (<code class="literal">t</code>)
+ as well a pointer to this variable (<code class="literal">ptr</code>). Note that the
+ latter needs to be cast to a char*. See the function <a class="xref" href="ecpg-informix-compat.html#RSETNULL"><code class="function">rsetnull</code></a> for a list of possible variable types.
+ </p><p>
+ Here is an example of how to use this function:
+</p><pre class="programlisting">
+$char c[] = "abc ";
+$short s = 17;
+$int i = -74874;
+
+risnull(CCHARTYPE, (char *) c);
+risnull(CSHORTTYPE, (char *) &amp;s);
+risnull(CINTTYPE, (char *) &amp;i);
+
+</pre><p>
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-INFORMIX-CONSTANTS"><div class="titlepage"><div><div><h3 class="title">36.15.5. Additional Constants</h3></div></div></div><p>
+ Note that all constants here describe errors and all of them are defined
+ to represent negative values. In the descriptions of the different
+ constants you can also find the value that the constants represent in the
+ current implementation. However you should not rely on this number. You can
+ however rely on the fact all of them are defined to represent negative
+ values.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ECPG_INFORMIX_NUM_OVERFLOW</code></span></dt><dd><p>
+ Functions return this value if an overflow occurred in a
+ calculation. Internally it is defined as -1200 (the <span class="productname">Informix</span>
+ definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_NUM_UNDERFLOW</code></span></dt><dd><p>
+ Functions return this value if an underflow occurred in a calculation.
+ Internally it is defined as -1201 (the <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_DIVIDE_ZERO</code></span></dt><dd><p>
+ Functions return this value if an attempt to divide by zero is
+ observed. Internally it is defined as -1202 (the <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_BAD_YEAR</code></span></dt><dd><p>
+ Functions return this value if a bad value for a year was found while
+ parsing a date. Internally it is defined as -1204 (the <span class="productname">Informix</span>
+ definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_BAD_MONTH</code></span></dt><dd><p>
+ Functions return this value if a bad value for a month was found while
+ parsing a date. Internally it is defined as -1205 (the <span class="productname">Informix</span>
+ definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_BAD_DAY</code></span></dt><dd><p>
+ Functions return this value if a bad value for a day was found while
+ parsing a date. Internally it is defined as -1206 (the <span class="productname">Informix</span>
+ definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_ENOSHORTDATE</code></span></dt><dd><p>
+ Functions return this value if a parsing routine needs a short date
+ representation but did not get the date string in the right length.
+ Internally it is defined as -1209 (the <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_DATE_CONVERT</code></span></dt><dd><p>
+ Functions return this value if an error occurred during date
+ formatting. Internally it is defined as -1210 (the
+ <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_OUT_OF_MEMORY</code></span></dt><dd><p>
+ Functions return this value if memory was exhausted during
+ their operation. Internally it is defined as -1211 (the
+ <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_ENOTDMY</code></span></dt><dd><p>
+ Functions return this value if a parsing routine was supposed to get a
+ format mask (like <code class="literal">mmddyy</code>) but not all fields were listed
+ correctly. Internally it is defined as -1212 (the <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_BAD_NUMERIC</code></span></dt><dd><p>
+ Functions return this value either if a parsing routine cannot parse
+ the textual representation for a numeric value because it contains
+ errors or if a routine cannot complete a calculation involving numeric
+ variables because at least one of the numeric variables is invalid.
+ Internally it is defined as -1213 (the <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_BAD_EXPONENT</code></span></dt><dd><p>
+ Functions return this value if a parsing routine cannot parse
+ an exponent. Internally it is defined as -1216 (the
+ <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_BAD_DATE</code></span></dt><dd><p>
+ Functions return this value if a parsing routine cannot parse
+ a date. Internally it is defined as -1218 (the
+ <span class="productname">Informix</span> definition).
+ </p></dd><dt><span class="term"><code class="literal">ECPG_INFORMIX_EXTRA_CHARS</code></span></dt><dd><p>
+ Functions return this value if a parsing routine is passed extra
+ characters it cannot parse. Internally it is defined as -1264 (the
+ <span class="productname">Informix</span> definition).
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-whenever.html" title="WHENEVER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode">Next</a></td></tr><tr><td width="40%" align="left" valign="top">WHENEVER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.16. <span class="productname">Oracle</span> Compatibility Mode</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-library.html b/doc/src/sgml/html/ecpg-library.html
new file mode 100644
index 0000000..6e849dc
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-library.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.11. Library Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs" /><link rel="next" href="ecpg-lo.html" title="36.12. Large Objects" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.11. Library Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-lo.html" title="36.12. Large Objects">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-LIBRARY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.11. Library Functions</h2></div></div></div><p>
+ The <code class="filename">libecpg</code> library primarily contains
+ <span class="quote">“<span class="quote">hidden</span>”</span> functions that are used to implement the
+ functionality expressed by the embedded SQL commands. But there
+ are some functions that can usefully be called directly. Note that
+ this makes your code unportable.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="function">ECPGdebug(int <em class="replaceable"><code>on</code></em>, FILE
+ *<em class="replaceable"><code>stream</code></em>)</code> turns on debug
+ logging if called with the first argument non-zero. Debug logging
+ is done on <em class="replaceable"><code>stream</code></em>. The log contains
+ all <acronym class="acronym">SQL</acronym> statements with all the input
+ variables inserted, and the results from the
+ <span class="productname">PostgreSQL</span> server. This can be very
+ useful when searching for errors in your <acronym class="acronym">SQL</acronym>
+ statements.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ On Windows, if the <span class="application">ecpg</span> libraries and an application are
+ compiled with different flags, this function call will crash the
+ application because the internal representation of the
+ <code class="literal">FILE</code> pointers differ. Specifically,
+ multithreaded/single-threaded, release/debug, and static/dynamic
+ flags should be the same for the library and all applications using
+ that library.
+ </p></div></li><li class="listitem"><p>
+ <code class="function">ECPGget_PGconn(const char *<em class="replaceable"><code>connection_name</code></em>)
+ </code> returns the library database connection handle identified by the given name.
+ If <em class="replaceable"><code>connection_name</code></em> is set to <code class="literal">NULL</code>, the current
+ connection handle is returned. If no connection handle can be identified, the function returns
+ <code class="literal">NULL</code>. The returned connection handle can be used to call any other functions
+ from <span class="application">libpq</span>, if necessary.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ It is a bad idea to manipulate database connection handles made from <span class="application">ecpg</span> directly
+ with <span class="application">libpq</span> routines.
+ </p></div></li><li class="listitem"><p>
+ <code class="function">ECPGtransactionStatus(const char *<em class="replaceable"><code>connection_name</code></em>)</code>
+ returns the current transaction status of the given connection identified by <em class="replaceable"><code>connection_name</code></em>.
+ See <a class="xref" href="libpq-status.html" title="34.2. Connection Status Functions">Section 34.2</a> and libpq's <a class="xref" href="libpq-status.html#LIBPQ-PQTRANSACTIONSTATUS"><code class="function">PQtransactionStatus</code></a> for details about the returned status codes.
+ </p></li><li class="listitem"><p>
+ <code class="function">ECPGstatus(int <em class="replaceable"><code>lineno</code></em>,
+ const char* <em class="replaceable"><code>connection_name</code></em>)</code>
+ returns true if you are connected to a database and false if not.
+ <em class="replaceable"><code>connection_name</code></em> can be <code class="literal">NULL</code>
+ if a single connection is being used.
+ </p></li></ul></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-lo.html" title="36.12. Large Objects">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.10. Processing Embedded SQL Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.12. Large Objects</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-lo.html b/doc/src/sgml/html/ecpg-lo.html
new file mode 100644
index 0000000..6f94365
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-lo.html
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.12. Large Objects</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-library.html" title="36.11. Library Functions" /><link rel="next" href="ecpg-cpp.html" title="36.13. C++ Applications" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.12. Large Objects</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-library.html" title="36.11. Library Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-cpp.html" title="36.13. C++ Applications">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-LO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.12. Large Objects</h2></div></div></div><p>
+ Large objects are not directly supported by ECPG, but ECPG
+ application can manipulate large objects through the libpq large
+ object functions, obtaining the necessary <code class="type">PGconn</code>
+ object by calling the <code class="function">ECPGget_PGconn()</code>
+ function. (However, use of
+ the <code class="function">ECPGget_PGconn()</code> function and touching
+ <code class="type">PGconn</code> objects directly should be done very carefully
+ and ideally not mixed with other ECPG database access calls.)
+ </p><p>
+ For more details about the <code class="function">ECPGget_PGconn()</code>, see
+ <a class="xref" href="ecpg-library.html" title="36.11. Library Functions">Section 36.11</a>. For information about the large
+ object function interface, see <a class="xref" href="largeobjects.html" title="Chapter 35. Large Objects">Chapter 35</a>.
+ </p><p>
+ Large object functions have to be called in a transaction block, so
+ when autocommit is off, <code class="command">BEGIN</code> commands have to
+ be issued explicitly.
+ </p><p>
+ <a class="xref" href="ecpg-lo.html#ECPG-LO-EXAMPLE" title="Example 36.2. ECPG Program Accessing Large Objects">Example 36.2</a> shows an example program that
+ illustrates how to create, write, and read a large object in an
+ ECPG application.
+ </p><div class="example" id="ECPG-LO-EXAMPLE"><p class="title"><strong>Example 36.2. ECPG Program Accessing Large Objects</strong></p><div class="example-contents"><pre class="programlisting">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;libpq-fe.h&gt;
+#include &lt;libpq/libpq-fs.h&gt;
+
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+main(void)
+{
+ PGconn *conn;
+ Oid loid;
+ int fd;
+ char buf[256];
+ int buflen = 256;
+ char buf2[256];
+ int rc;
+
+ memset(buf, 1, buflen);
+
+ EXEC SQL CONNECT TO testdb AS con1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ conn = ECPGget_PGconn("con1");
+ printf("conn = %p\n", conn);
+
+ /* create */
+ loid = lo_create(conn, 0);
+ if (loid &amp;lt; 0)
+ printf("lo_create() failed: %s", PQerrorMessage(conn));
+
+ printf("loid = %d\n", loid);
+
+ /* write test */
+ fd = lo_open(conn, loid, INV_READ|INV_WRITE);
+ if (fd &amp;lt; 0)
+ printf("lo_open() failed: %s", PQerrorMessage(conn));
+
+ printf("fd = %d\n", fd);
+
+ rc = lo_write(conn, fd, buf, buflen);
+ if (rc &amp;lt; 0)
+ printf("lo_write() failed\n");
+
+ rc = lo_close(conn, fd);
+ if (rc &amp;lt; 0)
+ printf("lo_close() failed: %s", PQerrorMessage(conn));
+
+ /* read test */
+ fd = lo_open(conn, loid, INV_READ);
+ if (fd &amp;lt; 0)
+ printf("lo_open() failed: %s", PQerrorMessage(conn));
+
+ printf("fd = %d\n", fd);
+
+ rc = lo_read(conn, fd, buf2, buflen);
+ if (rc &amp;lt; 0)
+ printf("lo_read() failed\n");
+
+ rc = lo_close(conn, fd);
+ if (rc &amp;lt; 0)
+ printf("lo_close() failed: %s", PQerrorMessage(conn));
+
+ /* check */
+ rc = memcmp(buf, buf2, buflen);
+ printf("memcmp() = %d\n", rc);
+
+ /* cleanup */
+ rc = lo_unlink(conn, loid);
+ if (rc &amp;lt; 0)
+ printf("lo_unlink() failed: %s", PQerrorMessage(conn));
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</pre></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-library.html" title="36.11. Library Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-cpp.html" title="36.13. C++ Applications">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.11. Library Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.13. <acronym class="acronym">C++</acronym> Applications</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-oracle-compat.html b/doc/src/sgml/html/ecpg-oracle-compat.html
new file mode 100644
index 0000000..a735839
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-oracle-compat.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.16. Oracle Compatibility Mode</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode" /><link rel="next" href="ecpg-develop.html" title="36.17. Internals" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.16. <span class="productname">Oracle</span> Compatibility Mode</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-develop.html" title="36.17. Internals">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-ORACLE-COMPAT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.16. <span class="productname">Oracle</span> Compatibility Mode</h2></div></div></div><p>
+ <code class="command">ecpg</code> can be run in a so-called <em class="firstterm">Oracle
+ compatibility mode</em>. If this mode is active, it tries to
+ behave as if it were Oracle <span class="productname">Pro*C</span>.
+ </p><p>
+ Specifically, this mode changes <code class="command">ecpg</code> in three ways:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Pad character arrays receiving character string types with
+ trailing spaces to the specified length
+ </p></li><li class="listitem"><p>
+ Zero byte terminate these character arrays, and set the indicator
+ variable if truncation occurs
+ </p></li><li class="listitem"><p>
+ Set the null indicator to <code class="literal">-1</code> when character
+ arrays receive empty character string types
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-develop.html" title="36.17. Internals">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.15. <span class="productname">Informix</span> Compatibility Mode </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.17. Internals</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-pgtypes.html b/doc/src/sgml/html/ecpg-pgtypes.html
new file mode 100644
index 0000000..9591a0d
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-pgtypes.html
@@ -0,0 +1,765 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.6. pgtypes Library</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-dynamic.html" title="36.5. Dynamic SQL" /><link rel="next" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.6. pgtypes Library</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-dynamic.html" title="36.5. Dynamic SQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-PGTYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.6. pgtypes Library</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-CSTRINGS">36.6.1. Character Strings</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-NUMERIC">36.6.2. The numeric Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-DATE">36.6.3. The date Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-TIMESTAMP">36.6.4. The timestamp Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-INTERVAL">36.6.5. The interval Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-DECIMAL">36.6.6. The decimal Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-ERRNO">36.6.7. errno Values of pgtypeslib</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-CONSTANTS">36.6.8. Special Constants of pgtypeslib</a></span></dt></dl></div><p>
+ The pgtypes library maps <span class="productname">PostgreSQL</span> database
+ types to C equivalents that can be used in C programs. It also offers
+ functions to do basic calculations with those types within C, i.e., without
+ the help of the <span class="productname">PostgreSQL</span> server. See the
+ following example:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ date date1;
+ timestamp ts1, tsout;
+ interval iv1;
+ char *out;
+EXEC SQL END DECLARE SECTION;
+
+PGTYPESdate_today(&amp;date1);
+EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1;
+PGTYPEStimestamp_add_interval(&amp;ts1, &amp;iv1, &amp;tsout);
+out = PGTYPEStimestamp_to_asc(&amp;tsout);
+printf("Started + duration: %s\n", out);
+PGTYPESchar_free(out);
+
+</pre><p>
+ </p><div class="sect2" id="ECPG-PGTYPES-CSTRINGS"><div class="titlepage"><div><div><h3 class="title">36.6.1. Character Strings</h3></div></div></div><p>
+ Some functions such as <code class="function">PGTYPESnumeric_to_asc</code> return
+ a pointer to a freshly allocated character string. These results should be
+ freed with <code class="function">PGTYPESchar_free</code> instead of
+ <code class="function">free</code>. (This is important only on Windows, where
+ memory allocation and release sometimes need to be done by the same
+ library.)
+ </p></div><div class="sect2" id="ECPG-PGTYPES-NUMERIC"><div class="titlepage"><div><div><h3 class="title">36.6.2. The numeric Type</h3></div></div></div><p>
+ The numeric type offers to do calculations with arbitrary precision. See
+ <a class="xref" href="datatype-numeric.html" title="8.1. Numeric Types">Section 8.1</a> for the equivalent type in the
+ <span class="productname">PostgreSQL</span> server. Because of the arbitrary precision this
+ variable needs to be able to expand and shrink dynamically. That's why you
+ can only create numeric variables on the heap, by means of the
+ <code class="function">PGTYPESnumeric_new</code> and <code class="function">PGTYPESnumeric_free</code>
+ functions. The decimal type, which is similar but limited in precision,
+ can be created on the stack as well as on the heap.
+ </p><p>
+ The following functions can be used to work with the numeric type:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">PGTYPESnumeric_new</code></span></dt><dd><p>
+ Request a pointer to a newly allocated numeric variable.
+</p><pre class="synopsis">
+numeric *PGTYPESnumeric_new(void);
+</pre><p>
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_free</code></span></dt><dd><p>
+ Free a numeric type, release all of its memory.
+</p><pre class="synopsis">
+void PGTYPESnumeric_free(numeric *var);
+</pre><p>
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_from_asc</code></span></dt><dd><p>
+ Parse a numeric type from its string notation.
+</p><pre class="synopsis">
+numeric *PGTYPESnumeric_from_asc(char *str, char **endptr);
+</pre><p>
+ Valid formats are for example:
+ <code class="literal">-2</code>,
+ <code class="literal">.794</code>,
+ <code class="literal">+3.44</code>,
+ <code class="literal">592.49E07</code> or
+ <code class="literal">-32.84e-4</code>.
+ If the value could be parsed successfully, a valid pointer is returned,
+ else the NULL pointer. At the moment ECPG always parses the complete
+ string and so it currently does not support to store the address of the
+ first invalid character in <code class="literal">*endptr</code>. You can safely
+ set <code class="literal">endptr</code> to NULL.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_to_asc</code></span></dt><dd><p>
+ Returns a pointer to a string allocated by <code class="function">malloc</code> that contains the string
+ representation of the numeric type <code class="literal">num</code>.
+</p><pre class="synopsis">
+char *PGTYPESnumeric_to_asc(numeric *num, int dscale);
+</pre><p>
+ The numeric value will be printed with <code class="literal">dscale</code> decimal
+ digits, with rounding applied if necessary.
+ The result must be freed with <code class="function">PGTYPESchar_free()</code>.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_add</code></span></dt><dd><p>
+ Add two numeric variables into a third one.
+</p><pre class="synopsis">
+int PGTYPESnumeric_add(numeric *var1, numeric *var2, numeric *result);
+</pre><p>
+ The function adds the variables <code class="literal">var1</code> and
+ <code class="literal">var2</code> into the result variable
+ <code class="literal">result</code>.
+ The function returns 0 on success and -1 in case of error.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_sub</code></span></dt><dd><p>
+ Subtract two numeric variables and return the result in a third one.
+</p><pre class="synopsis">
+int PGTYPESnumeric_sub(numeric *var1, numeric *var2, numeric *result);
+</pre><p>
+ The function subtracts the variable <code class="literal">var2</code> from
+ the variable <code class="literal">var1</code>. The result of the operation is
+ stored in the variable <code class="literal">result</code>.
+ The function returns 0 on success and -1 in case of error.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_mul</code></span></dt><dd><p>
+ Multiply two numeric variables and return the result in a third one.
+</p><pre class="synopsis">
+int PGTYPESnumeric_mul(numeric *var1, numeric *var2, numeric *result);
+</pre><p>
+ The function multiplies the variables <code class="literal">var1</code> and
+ <code class="literal">var2</code>. The result of the operation is stored in the
+ variable <code class="literal">result</code>.
+ The function returns 0 on success and -1 in case of error.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_div</code></span></dt><dd><p>
+ Divide two numeric variables and return the result in a third one.
+</p><pre class="synopsis">
+int PGTYPESnumeric_div(numeric *var1, numeric *var2, numeric *result);
+</pre><p>
+ The function divides the variables <code class="literal">var1</code> by
+ <code class="literal">var2</code>. The result of the operation is stored in the
+ variable <code class="literal">result</code>.
+ The function returns 0 on success and -1 in case of error.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_cmp</code></span></dt><dd><p>
+ Compare two numeric variables.
+</p><pre class="synopsis">
+int PGTYPESnumeric_cmp(numeric *var1, numeric *var2)
+</pre><p>
+ This function compares two numeric variables. In case of error,
+ <code class="literal">INT_MAX</code> is returned. On success, the function
+ returns one of three possible results:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ 1, if <code class="literal">var1</code> is bigger than <code class="literal">var2</code>
+ </p></li><li class="listitem"><p>
+ -1, if <code class="literal">var1</code> is smaller than <code class="literal">var2</code>
+ </p></li><li class="listitem"><p>
+ 0, if <code class="literal">var1</code> and <code class="literal">var2</code> are equal
+ </p></li></ul></div><p>
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_from_int</code></span></dt><dd><p>
+ Convert an int variable to a numeric variable.
+</p><pre class="synopsis">
+int PGTYPESnumeric_from_int(signed int int_val, numeric *var);
+</pre><p>
+ This function accepts a variable of type signed int and stores it
+ in the numeric variable <code class="literal">var</code>. Upon success, 0 is returned and
+ -1 in case of a failure.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_from_long</code></span></dt><dd><p>
+ Convert a long int variable to a numeric variable.
+</p><pre class="synopsis">
+int PGTYPESnumeric_from_long(signed long int long_val, numeric *var);
+</pre><p>
+ This function accepts a variable of type signed long int and stores it
+ in the numeric variable <code class="literal">var</code>. Upon success, 0 is returned and
+ -1 in case of a failure.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_copy</code></span></dt><dd><p>
+ Copy over one numeric variable into another one.
+</p><pre class="synopsis">
+int PGTYPESnumeric_copy(numeric *src, numeric *dst);
+</pre><p>
+ This function copies over the value of the variable that
+ <code class="literal">src</code> points to into the variable that <code class="literal">dst</code>
+ points to. It returns 0 on success and -1 if an error occurs.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_from_double</code></span></dt><dd><p>
+ Convert a variable of type double to a numeric.
+</p><pre class="synopsis">
+int PGTYPESnumeric_from_double(double d, numeric *dst);
+</pre><p>
+ This function accepts a variable of type double and stores the result
+ in the variable that <code class="literal">dst</code> points to. It returns 0 on success
+ and -1 if an error occurs.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_to_double</code></span></dt><dd><p>
+ Convert a variable of type numeric to double.
+</p><pre class="synopsis">
+int PGTYPESnumeric_to_double(numeric *nv, double *dp)
+</pre><p>
+ The function converts the numeric value from the variable that
+ <code class="literal">nv</code> points to into the double variable that <code class="literal">dp</code> points
+ to. It returns 0 on success and -1 if an error occurs, including
+ overflow. On overflow, the global variable <code class="literal">errno</code> will be set
+ to <code class="literal">PGTYPES_NUM_OVERFLOW</code> additionally.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_to_int</code></span></dt><dd><p>
+ Convert a variable of type numeric to int.
+</p><pre class="synopsis">
+int PGTYPESnumeric_to_int(numeric *nv, int *ip);
+</pre><p>
+ The function converts the numeric value from the variable that
+ <code class="literal">nv</code> points to into the integer variable that <code class="literal">ip</code>
+ points to. It returns 0 on success and -1 if an error occurs, including
+ overflow. On overflow, the global variable <code class="literal">errno</code> will be set
+ to <code class="literal">PGTYPES_NUM_OVERFLOW</code> additionally.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_to_long</code></span></dt><dd><p>
+ Convert a variable of type numeric to long.
+</p><pre class="synopsis">
+int PGTYPESnumeric_to_long(numeric *nv, long *lp);
+</pre><p>
+ The function converts the numeric value from the variable that
+ <code class="literal">nv</code> points to into the long integer variable that
+ <code class="literal">lp</code> points to. It returns 0 on success and -1 if an error
+ occurs, including overflow. On overflow, the global variable
+ <code class="literal">errno</code> will be set to <code class="literal">PGTYPES_NUM_OVERFLOW</code>
+ additionally.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_to_decimal</code></span></dt><dd><p>
+ Convert a variable of type numeric to decimal.
+</p><pre class="synopsis">
+int PGTYPESnumeric_to_decimal(numeric *src, decimal *dst);
+</pre><p>
+ The function converts the numeric value from the variable that
+ <code class="literal">src</code> points to into the decimal variable that
+ <code class="literal">dst</code> points to. It returns 0 on success and -1 if an error
+ occurs, including overflow. On overflow, the global variable
+ <code class="literal">errno</code> will be set to <code class="literal">PGTYPES_NUM_OVERFLOW</code>
+ additionally.
+ </p></dd><dt><span class="term"><code class="function">PGTYPESnumeric_from_decimal</code></span></dt><dd><p>
+ Convert a variable of type decimal to numeric.
+</p><pre class="synopsis">
+int PGTYPESnumeric_from_decimal(decimal *src, numeric *dst);
+</pre><p>
+ The function converts the decimal value from the variable that
+ <code class="literal">src</code> points to into the numeric variable that
+ <code class="literal">dst</code> points to. It returns 0 on success and -1 if an error
+ occurs. Since the decimal type is implemented as a limited version of
+ the numeric type, overflow cannot occur with this conversion.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PGTYPES-DATE"><div class="titlepage"><div><div><h3 class="title">36.6.3. The date Type</h3></div></div></div><p>
+ The date type in C enables your programs to deal with data of the SQL type
+ date. See <a class="xref" href="datatype-datetime.html" title="8.5. Date/Time Types">Section 8.5</a> for the equivalent type in the
+ <span class="productname">PostgreSQL</span> server.
+ </p><p>
+ The following functions can be used to work with the date type:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PGTYPESDATEFROMTIMESTAMP"><span class="term"><code class="function">PGTYPESdate_from_timestamp</code></span></dt><dd><p>
+ Extract the date part from a timestamp.
+</p><pre class="synopsis">
+date PGTYPESdate_from_timestamp(timestamp dt);
+</pre><p>
+ The function receives a timestamp as its only argument and returns the
+ extracted date part from this timestamp.
+ </p></dd><dt id="PGTYPESDATEFROMASC"><span class="term"><code class="function">PGTYPESdate_from_asc</code></span></dt><dd><p>
+ Parse a date from its textual representation.
+</p><pre class="synopsis">
+date PGTYPESdate_from_asc(char *str, char **endptr);
+</pre><p>
+ The function receives a C char* string <code class="literal">str</code> and a pointer to
+ a C char* string <code class="literal">endptr</code>. At the moment ECPG always parses
+ the complete string and so it currently does not support to store the
+ address of the first invalid character in <code class="literal">*endptr</code>.
+ You can safely set <code class="literal">endptr</code> to NULL.
+ </p><p>
+ Note that the function always assumes MDY-formatted dates and there is
+ currently no variable to change that within ECPG.
+ </p><p>
+ <a class="xref" href="ecpg-pgtypes.html#ECPG-PGTYPESDATE-FROM-ASC-TABLE" title="Table 36.2. Valid Input Formats for PGTYPESdate_from_asc">Table 36.2</a> shows the allowed input formats.
+ </p><div class="table" id="ECPG-PGTYPESDATE-FROM-ASC-TABLE"><p class="title"><strong>Table 36.2. Valid Input Formats for <code class="function">PGTYPESdate_from_asc</code></strong></p><div class="table-contents"><table class="table" summary="Valid Input Formats for PGTYPESdate_from_asc" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Input</th><th>Result</th></tr></thead><tbody><tr><td><code class="literal">January 8, 1999</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">1999-01-08</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">1/8/1999</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">1/18/1999</code></td><td><code class="literal">January 18, 1999</code></td></tr><tr><td><code class="literal">01/02/03</code></td><td><code class="literal">February 1, 2003</code></td></tr><tr><td><code class="literal">1999-Jan-08</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">Jan-08-1999</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">08-Jan-1999</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">99-Jan-08</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">08-Jan-99</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">08-Jan-06</code></td><td><code class="literal">January 8, 2006</code></td></tr><tr><td><code class="literal">Jan-08-99</code></td><td><code class="literal">January 8, 1999</code></td></tr><tr><td><code class="literal">19990108</code></td><td><code class="literal">ISO 8601; January 8, 1999</code></td></tr><tr><td><code class="literal">990108</code></td><td><code class="literal">ISO 8601; January 8, 1999</code></td></tr><tr><td><code class="literal">1999.008</code></td><td><code class="literal">year and day of year</code></td></tr><tr><td><code class="literal">J2451187</code></td><td><code class="literal">Julian day</code></td></tr><tr><td><code class="literal">January 8, 99 BC</code></td><td><code class="literal">year 99 before the Common Era</code></td></tr></tbody></table></div></div><br class="table-break" /></dd><dt id="PGTYPESDATETOASC"><span class="term"><code class="function">PGTYPESdate_to_asc</code></span></dt><dd><p>
+ Return the textual representation of a date variable.
+</p><pre class="synopsis">
+char *PGTYPESdate_to_asc(date dDate);
+</pre><p>
+ The function receives the date <code class="literal">dDate</code> as its only parameter.
+ It will output the date in the form <code class="literal">1999-01-18</code>, i.e., in the
+ <code class="literal">YYYY-MM-DD</code> format.
+ The result must be freed with <code class="function">PGTYPESchar_free()</code>.
+ </p></dd><dt id="PGTYPESDATEJULMDY"><span class="term"><code class="function">PGTYPESdate_julmdy</code></span></dt><dd><p>
+ Extract the values for the day, the month and the year from a variable
+ of type date.
+</p><pre class="synopsis">
+void PGTYPESdate_julmdy(date d, int *mdy);
+</pre><p>
+
+ The function receives the date <code class="literal">d</code> and a pointer to an array
+ of 3 integer values <code class="literal">mdy</code>. The variable name indicates
+ the sequential order: <code class="literal">mdy[0]</code> will be set to contain the
+ number of the month, <code class="literal">mdy[1]</code> will be set to the value of the
+ day and <code class="literal">mdy[2]</code> will contain the year.
+ </p></dd><dt id="PGTYPESDATEMDYJUL"><span class="term"><code class="function">PGTYPESdate_mdyjul</code></span></dt><dd><p>
+ Create a date value from an array of 3 integers that specify the
+ day, the month and the year of the date.
+</p><pre class="synopsis">
+void PGTYPESdate_mdyjul(int *mdy, date *jdate);
+</pre><p>
+ The function receives the array of the 3 integers (<code class="literal">mdy</code>) as
+ its first argument and as its second argument a pointer to a variable
+ of type date that should hold the result of the operation.
+ </p></dd><dt id="PGTYPESDATEDAYOFWEEK"><span class="term"><code class="function">PGTYPESdate_dayofweek</code></span></dt><dd><p>
+ Return a number representing the day of the week for a date value.
+</p><pre class="synopsis">
+int PGTYPESdate_dayofweek(date d);
+</pre><p>
+ The function receives the date variable <code class="literal">d</code> as its only
+ argument and returns an integer that indicates the day of the week for
+ this date.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ 0 - Sunday
+ </p></li><li class="listitem"><p>
+ 1 - Monday
+ </p></li><li class="listitem"><p>
+ 2 - Tuesday
+ </p></li><li class="listitem"><p>
+ 3 - Wednesday
+ </p></li><li class="listitem"><p>
+ 4 - Thursday
+ </p></li><li class="listitem"><p>
+ 5 - Friday
+ </p></li><li class="listitem"><p>
+ 6 - Saturday
+ </p></li></ul></div><p>
+ </p></dd><dt id="PGTYPESDATETODAY"><span class="term"><code class="function">PGTYPESdate_today</code></span></dt><dd><p>
+ Get the current date.
+</p><pre class="synopsis">
+void PGTYPESdate_today(date *d);
+</pre><p>
+ The function receives a pointer to a date variable (<code class="literal">d</code>)
+ that it sets to the current date.
+ </p></dd><dt id="PGTYPESDATEFMTASC"><span class="term"><code class="function">PGTYPESdate_fmt_asc</code></span></dt><dd><p>
+ Convert a variable of type date to its textual representation using a
+ format mask.
+</p><pre class="synopsis">
+int PGTYPESdate_fmt_asc(date dDate, char *fmtstring, char *outbuf);
+</pre><p>
+ The function receives the date to convert (<code class="literal">dDate</code>), the
+ format mask (<code class="literal">fmtstring</code>) and the string that will hold the
+ textual representation of the date (<code class="literal">outbuf</code>).
+ </p><p>
+ On success, 0 is returned and a negative value if an error occurred.
+ </p><p>
+ The following literals are the field specifiers you can use:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">dd</code> - The number of the day of the month.
+ </p></li><li class="listitem"><p>
+ <code class="literal">mm</code> - The number of the month of the year.
+ </p></li><li class="listitem"><p>
+ <code class="literal">yy</code> - The number of the year as a two digit number.
+ </p></li><li class="listitem"><p>
+ <code class="literal">yyyy</code> - The number of the year as a four digit number.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ddd</code> - The name of the day (abbreviated).
+ </p></li><li class="listitem"><p>
+ <code class="literal">mmm</code> - The name of the month (abbreviated).
+ </p></li></ul></div><p>
+ All other characters are copied 1:1 to the output string.
+ </p><p>
+ <a class="xref" href="ecpg-pgtypes.html#ECPG-PGTYPESDATE-FMT-ASC-EXAMPLE-TABLE" title="Table 36.3. Valid Input Formats for PGTYPESdate_fmt_asc">Table 36.3</a> indicates a few possible formats. This will give
+ you an idea of how to use this function. All output lines are based on
+ the same date: November 23, 1959.
+ </p><div class="table" id="ECPG-PGTYPESDATE-FMT-ASC-EXAMPLE-TABLE"><p class="title"><strong>Table 36.3. Valid Input Formats for <code class="function">PGTYPESdate_fmt_asc</code></strong></p><div class="table-contents"><table class="table" summary="Valid Input Formats for PGTYPESdate_fmt_asc" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Format</th><th>Result</th></tr></thead><tbody><tr><td><code class="literal">mmddyy</code></td><td><code class="literal">112359</code></td></tr><tr><td><code class="literal">ddmmyy</code></td><td><code class="literal">231159</code></td></tr><tr><td><code class="literal">yymmdd</code></td><td><code class="literal">591123</code></td></tr><tr><td><code class="literal">yy/mm/dd</code></td><td><code class="literal">59/11/23</code></td></tr><tr><td><code class="literal">yy mm dd</code></td><td><code class="literal">59 11 23</code></td></tr><tr><td><code class="literal">yy.mm.dd</code></td><td><code class="literal">59.11.23</code></td></tr><tr><td><code class="literal">.mm.yyyy.dd.</code></td><td><code class="literal">.11.1959.23.</code></td></tr><tr><td><code class="literal">mmm. dd, yyyy</code></td><td><code class="literal">Nov. 23, 1959</code></td></tr><tr><td><code class="literal">mmm dd yyyy</code></td><td><code class="literal">Nov 23 1959</code></td></tr><tr><td><code class="literal">yyyy dd mm</code></td><td><code class="literal">1959 23 11</code></td></tr><tr><td><code class="literal">ddd, mmm. dd, yyyy</code></td><td><code class="literal">Mon, Nov. 23, 1959</code></td></tr><tr><td><code class="literal">(ddd) mmm. dd, yyyy</code></td><td><code class="literal">(Mon) Nov. 23, 1959</code></td></tr></tbody></table></div></div><br class="table-break" /></dd><dt id="PGTYPESDATEDEFMTASC"><span class="term"><code class="function">PGTYPESdate_defmt_asc</code></span></dt><dd><p>
+ Use a format mask to convert a C <code class="type">char*</code> string to a value of type
+ date.
+</p><pre class="synopsis">
+int PGTYPESdate_defmt_asc(date *d, char *fmt, char *str);
+</pre><p>
+
+ The function receives a pointer to the date value that should hold the
+ result of the operation (<code class="literal">d</code>), the format mask to use for
+ parsing the date (<code class="literal">fmt</code>) and the C char* string containing
+ the textual representation of the date (<code class="literal">str</code>). The textual
+ representation is expected to match the format mask. However you do not
+ need to have a 1:1 mapping of the string to the format mask. The
+ function only analyzes the sequential order and looks for the literals
+ <code class="literal">yy</code> or <code class="literal">yyyy</code> that indicate the
+ position of the year, <code class="literal">mm</code> to indicate the position of
+ the month and <code class="literal">dd</code> to indicate the position of the
+ day.
+ </p><p>
+ <a class="xref" href="ecpg-pgtypes.html#ECPG-RDEFMTDATE-EXAMPLE-TABLE" title="Table 36.4. Valid Input Formats for rdefmtdate">Table 36.4</a> indicates a few possible formats. This will give
+ you an idea of how to use this function.
+ </p><div class="table" id="ECPG-RDEFMTDATE-EXAMPLE-TABLE"><p class="title"><strong>Table 36.4. Valid Input Formats for <code class="function">rdefmtdate</code></strong></p><div class="table-contents"><table class="table" summary="Valid Input Formats for rdefmtdate" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Format</th><th>String</th><th>Result</th></tr></thead><tbody><tr><td><code class="literal">ddmmyy</code></td><td><code class="literal">21-2-54</code></td><td><code class="literal">1954-02-21</code></td></tr><tr><td><code class="literal">ddmmyy</code></td><td><code class="literal">2-12-54</code></td><td><code class="literal">1954-12-02</code></td></tr><tr><td><code class="literal">ddmmyy</code></td><td><code class="literal">20111954</code></td><td><code class="literal">1954-11-20</code></td></tr><tr><td><code class="literal">ddmmyy</code></td><td><code class="literal">130464</code></td><td><code class="literal">1964-04-13</code></td></tr><tr><td><code class="literal">mmm.dd.yyyy</code></td><td><code class="literal">MAR-12-1967</code></td><td><code class="literal">1967-03-12</code></td></tr><tr><td><code class="literal">yy/mm/dd</code></td><td><code class="literal">1954, February 3rd</code></td><td><code class="literal">1954-02-03</code></td></tr><tr><td><code class="literal">mmm.dd.yyyy</code></td><td><code class="literal">041269</code></td><td><code class="literal">1969-04-12</code></td></tr><tr><td><code class="literal">yy/mm/dd</code></td><td><code class="literal">In the year 2525, in the month of July, mankind will be alive on the 28th day</code></td><td><code class="literal">2525-07-28</code></td></tr><tr><td><code class="literal">dd-mm-yy</code></td><td><code class="literal">I said on the 28th of July in the year 2525</code></td><td><code class="literal">2525-07-28</code></td></tr><tr><td><code class="literal">mmm.dd.yyyy</code></td><td><code class="literal">9/14/58</code></td><td><code class="literal">1958-09-14</code></td></tr><tr><td><code class="literal">yy/mm/dd</code></td><td><code class="literal">47/03/29</code></td><td><code class="literal">1947-03-29</code></td></tr><tr><td><code class="literal">mmm.dd.yyyy</code></td><td><code class="literal">oct 28 1975</code></td><td><code class="literal">1975-10-28</code></td></tr><tr><td><code class="literal">mmddyy</code></td><td><code class="literal">Nov 14th, 1985</code></td><td><code class="literal">1985-11-14</code></td></tr></tbody></table></div></div><br class="table-break" /></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PGTYPES-TIMESTAMP"><div class="titlepage"><div><div><h3 class="title">36.6.4. The timestamp Type</h3></div></div></div><p>
+ The timestamp type in C enables your programs to deal with data of the SQL
+ type timestamp. See <a class="xref" href="datatype-datetime.html" title="8.5. Date/Time Types">Section 8.5</a> for the equivalent
+ type in the <span class="productname">PostgreSQL</span> server.
+ </p><p>
+ The following functions can be used to work with the timestamp type:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PGTYPESTIMESTAMPFROMASC"><span class="term"><code class="function">PGTYPEStimestamp_from_asc</code></span></dt><dd><p>
+ Parse a timestamp from its textual representation into a timestamp
+ variable.
+</p><pre class="synopsis">
+timestamp PGTYPEStimestamp_from_asc(char *str, char **endptr);
+</pre><p>
+ The function receives the string to parse (<code class="literal">str</code>) and a
+ pointer to a C char* (<code class="literal">endptr</code>).
+ At the moment ECPG always parses
+ the complete string and so it currently does not support to store the
+ address of the first invalid character in <code class="literal">*endptr</code>.
+ You can safely set <code class="literal">endptr</code> to NULL.
+ </p><p>
+ The function returns the parsed timestamp on success. On error,
+ <code class="literal">PGTYPESInvalidTimestamp</code> is returned and <code class="varname">errno</code> is
+ set to <code class="literal">PGTYPES_TS_BAD_TIMESTAMP</code>. See <a class="xref" href="ecpg-pgtypes.html#PGTYPESINVALIDTIMESTAMP"><code class="literal">PGTYPESInvalidTimestamp</code></a> for important notes on this value.
+ </p><p>
+ In general, the input string can contain any combination of an allowed
+ date specification, a whitespace character and an allowed time
+ specification. Note that time zones are not supported by ECPG. It can
+ parse them but does not apply any calculation as the
+ <span class="productname">PostgreSQL</span> server does for example. Timezone
+ specifiers are silently discarded.
+ </p><p>
+ <a class="xref" href="ecpg-pgtypes.html#ECPG-PGTYPESTIMESTAMP-FROM-ASC-EXAMPLE-TABLE" title="Table 36.5. Valid Input Formats for PGTYPEStimestamp_from_asc">Table 36.5</a> contains a few examples for input strings.
+ </p><div class="table" id="ECPG-PGTYPESTIMESTAMP-FROM-ASC-EXAMPLE-TABLE"><p class="title"><strong>Table 36.5. Valid Input Formats for <code class="function">PGTYPEStimestamp_from_asc</code></strong></p><div class="table-contents"><table class="table" summary="Valid Input Formats for PGTYPEStimestamp_from_asc" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Input</th><th>Result</th></tr></thead><tbody><tr><td><code class="literal">1999-01-08 04:05:06</code></td><td><code class="literal">1999-01-08 04:05:06</code></td></tr><tr><td><code class="literal">January 8 04:05:06 1999 PST</code></td><td><code class="literal">1999-01-08 04:05:06</code></td></tr><tr><td><code class="literal">1999-Jan-08 04:05:06.789-8</code></td><td><code class="literal">1999-01-08 04:05:06.789 (time zone specifier ignored)</code></td></tr><tr><td><code class="literal">J2451187 04:05-08:00</code></td><td><code class="literal">1999-01-08 04:05:00 (time zone specifier ignored)</code></td></tr></tbody></table></div></div><br class="table-break" /></dd><dt id="PGTYPESTIMESTAMPTOASC"><span class="term"><code class="function">PGTYPEStimestamp_to_asc</code></span></dt><dd><p>
+ Converts a date to a C char* string.
+</p><pre class="synopsis">
+char *PGTYPEStimestamp_to_asc(timestamp tstamp);
+</pre><p>
+ The function receives the timestamp <code class="literal">tstamp</code> as
+ its only argument and returns an allocated string that contains the
+ textual representation of the timestamp.
+ The result must be freed with <code class="function">PGTYPESchar_free()</code>.
+ </p></dd><dt id="PGTYPESTIMESTAMPCURRENT"><span class="term"><code class="function">PGTYPEStimestamp_current</code></span></dt><dd><p>
+ Retrieve the current timestamp.
+</p><pre class="synopsis">
+void PGTYPEStimestamp_current(timestamp *ts);
+</pre><p>
+ The function retrieves the current timestamp and saves it into the
+ timestamp variable that <code class="literal">ts</code> points to.
+ </p></dd><dt id="PGTYPESTIMESTAMPFMTASC"><span class="term"><code class="function">PGTYPEStimestamp_fmt_asc</code></span></dt><dd><p>
+ Convert a timestamp variable to a C char* using a format mask.
+</p><pre class="synopsis">
+int PGTYPEStimestamp_fmt_asc(timestamp *ts, char *output, int str_len, char *fmtstr);
+</pre><p>
+ The function receives a pointer to the timestamp to convert as its
+ first argument (<code class="literal">ts</code>), a pointer to the output buffer
+ (<code class="literal">output</code>), the maximal length that has been allocated for
+ the output buffer (<code class="literal">str_len</code>) and the format mask to
+ use for the conversion (<code class="literal">fmtstr</code>).
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p><p>
+ You can use the following format specifiers for the format mask. The
+ format specifiers are the same ones that are used in the
+ <code class="function">strftime</code> function in <span class="productname">libc</span>. Any
+ non-format specifier will be copied into the output buffer.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">%A</code> - is replaced by national representation of
+ the full weekday name.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%a</code> - is replaced by national representation of
+ the abbreviated weekday name.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%B</code> - is replaced by national representation of
+ the full month name.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%b</code> - is replaced by national representation of
+ the abbreviated month name.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%C</code> - is replaced by (year / 100) as decimal
+ number; single digits are preceded by a zero.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%c</code> - is replaced by national representation of
+ time and date.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%D</code> - is equivalent to
+ <code class="literal">%m/%d/%y</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%d</code> - is replaced by the day of the month as a
+ decimal number (01–31).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%E*</code> <code class="literal">%O*</code> - POSIX locale
+ extensions. The sequences
+ <code class="literal">%Ec</code>
+ <code class="literal">%EC</code>
+ <code class="literal">%Ex</code>
+ <code class="literal">%EX</code>
+ <code class="literal">%Ey</code>
+ <code class="literal">%EY</code>
+ <code class="literal">%Od</code>
+ <code class="literal">%Oe</code>
+ <code class="literal">%OH</code>
+ <code class="literal">%OI</code>
+ <code class="literal">%Om</code>
+ <code class="literal">%OM</code>
+ <code class="literal">%OS</code>
+ <code class="literal">%Ou</code>
+ <code class="literal">%OU</code>
+ <code class="literal">%OV</code>
+ <code class="literal">%Ow</code>
+ <code class="literal">%OW</code>
+ <code class="literal">%Oy</code>
+ are supposed to provide alternative representations.
+ </p><p>
+ Additionally <code class="literal">%OB</code> implemented to represent
+ alternative months names (used standalone, without day mentioned).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%e</code> - is replaced by the day of month as a decimal
+ number (1–31); single digits are preceded by a blank.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%F</code> - is equivalent to <code class="literal">%Y-%m-%d</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%G</code> - is replaced by a year as a decimal number
+ with century. This year is the one that contains the greater part of
+ the week (Monday as the first day of the week).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%g</code> - is replaced by the same year as in
+ <code class="literal">%G</code>, but as a decimal number without century
+ (00–99).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%H</code> - is replaced by the hour (24-hour clock) as a
+ decimal number (00–23).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%h</code> - the same as <code class="literal">%b</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%I</code> - is replaced by the hour (12-hour clock) as a
+ decimal number (01–12).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%j</code> - is replaced by the day of the year as a
+ decimal number (001–366).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%k</code> - is replaced by the hour (24-hour clock) as a
+ decimal number (0–23); single digits are preceded by a blank.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%l</code> - is replaced by the hour (12-hour clock) as a
+ decimal number (1–12); single digits are preceded by a blank.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%M</code> - is replaced by the minute as a decimal
+ number (00–59).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%m</code> - is replaced by the month as a decimal number
+ (01–12).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%n</code> - is replaced by a newline.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%O*</code> - the same as <code class="literal">%E*</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%p</code> - is replaced by national representation of
+ either <span class="quote">“<span class="quote">ante meridiem</span>”</span> or <span class="quote">“<span class="quote">post meridiem</span>”</span> as appropriate.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%R</code> - is equivalent to <code class="literal">%H:%M</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%r</code> - is equivalent to <code class="literal">%I:%M:%S
+ %p</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%S</code> - is replaced by the second as a decimal
+ number (00–60).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%s</code> - is replaced by the number of seconds since
+ the Epoch, UTC.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%T</code> - is equivalent to <code class="literal">%H:%M:%S</code>
+ </p></li><li class="listitem"><p>
+ <code class="literal">%t</code> - is replaced by a tab.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%U</code> - is replaced by the week number of the year
+ (Sunday as the first day of the week) as a decimal number (00–53).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%u</code> - is replaced by the weekday (Monday as the
+ first day of the week) as a decimal number (1–7).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%V</code> - is replaced by the week number of the year
+ (Monday as the first day of the week) as a decimal number (01–53).
+ If the week containing January 1 has four or more days in the new
+ year, then it is week 1; otherwise it is the last week of the
+ previous year, and the next week is week 1.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%v</code> - is equivalent to
+ <code class="literal">%e-%b-%Y</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%W</code> - is replaced by the week number of the year
+ (Monday as the first day of the week) as a decimal number (00–53).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%w</code> - is replaced by the weekday (Sunday as the
+ first day of the week) as a decimal number (0–6).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%X</code> - is replaced by national representation of
+ the time.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%x</code> - is replaced by national representation of
+ the date.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%Y</code> - is replaced by the year with century as a
+ decimal number.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%y</code> - is replaced by the year without century as a
+ decimal number (00–99).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%Z</code> - is replaced by the time zone name.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%z</code> - is replaced by the time zone offset from
+ UTC; a leading plus sign stands for east of UTC, a minus sign for
+ west of UTC, hours and minutes follow with two digits each and no
+ delimiter between them (common form for <a class="ulink" href="https://tools.ietf.org/html/rfc822" target="_top">RFC 822</a> date headers).
+ </p></li><li class="listitem"><p>
+ <code class="literal">%+</code> - is replaced by national representation of
+ the date and time.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%-*</code> - GNU libc extension. Do not do any padding
+ when performing numerical outputs.
+ </p></li><li class="listitem"><p>
+ $_* - GNU libc extension. Explicitly specify space for padding.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%0*</code> - GNU libc extension. Explicitly specify zero
+ for padding.
+ </p></li><li class="listitem"><p>
+ <code class="literal">%%</code> - is replaced by <code class="literal">%</code>.
+ </p></li></ul></div><p>
+ </p></dd><dt id="PGTYPESTIMESTAMPSUB"><span class="term"><code class="function">PGTYPEStimestamp_sub</code></span></dt><dd><p>
+ Subtract one timestamp from another one and save the result in a
+ variable of type interval.
+</p><pre class="synopsis">
+int PGTYPEStimestamp_sub(timestamp *ts1, timestamp *ts2, interval *iv);
+</pre><p>
+ The function will subtract the timestamp variable that <code class="literal">ts2</code>
+ points to from the timestamp variable that <code class="literal">ts1</code> points to
+ and will store the result in the interval variable that <code class="literal">iv</code>
+ points to.
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p></dd><dt id="PGTYPESTIMESTAMPDEFMTASC"><span class="term"><code class="function">PGTYPEStimestamp_defmt_asc</code></span></dt><dd><p>
+ Parse a timestamp value from its textual representation using a
+ formatting mask.
+</p><pre class="synopsis">
+int PGTYPEStimestamp_defmt_asc(char *str, char *fmt, timestamp *d);
+</pre><p>
+ The function receives the textual representation of a timestamp in the
+ variable <code class="literal">str</code> as well as the formatting mask to use in the
+ variable <code class="literal">fmt</code>. The result will be stored in the variable
+ that <code class="literal">d</code> points to.
+ </p><p>
+ If the formatting mask <code class="literal">fmt</code> is NULL, the function will fall
+ back to the default formatting mask which is <code class="literal">%Y-%m-%d
+ %H:%M:%S</code>.
+ </p><p>
+ This is the reverse function to <a class="xref" href="ecpg-pgtypes.html#PGTYPESTIMESTAMPFMTASC"><code class="function">PGTYPEStimestamp_fmt_asc</code></a>. See the documentation there in
+ order to find out about the possible formatting mask entries.
+ </p></dd><dt id="PGTYPESTIMESTAMPADDINTERVAL"><span class="term"><code class="function">PGTYPEStimestamp_add_interval</code></span></dt><dd><p>
+ Add an interval variable to a timestamp variable.
+</p><pre class="synopsis">
+int PGTYPEStimestamp_add_interval(timestamp *tin, interval *span, timestamp *tout);
+</pre><p>
+ The function receives a pointer to a timestamp variable <code class="literal">tin</code>
+ and a pointer to an interval variable <code class="literal">span</code>. It adds the
+ interval to the timestamp and saves the resulting timestamp in the
+ variable that <code class="literal">tout</code> points to.
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p></dd><dt id="PGTYPESTIMESTAMPSUBINTERVAL"><span class="term"><code class="function">PGTYPEStimestamp_sub_interval</code></span></dt><dd><p>
+ Subtract an interval variable from a timestamp variable.
+</p><pre class="synopsis">
+int PGTYPEStimestamp_sub_interval(timestamp *tin, interval *span, timestamp *tout);
+</pre><p>
+ The function subtracts the interval variable that <code class="literal">span</code>
+ points to from the timestamp variable that <code class="literal">tin</code> points to
+ and saves the result into the variable that <code class="literal">tout</code> points
+ to.
+ </p><p>
+ Upon success, the function returns 0 and a negative value if an
+ error occurred.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PGTYPES-INTERVAL"><div class="titlepage"><div><div><h3 class="title">36.6.5. The interval Type</h3></div></div></div><p>
+ The interval type in C enables your programs to deal with data of the SQL
+ type interval. See <a class="xref" href="datatype-datetime.html" title="8.5. Date/Time Types">Section 8.5</a> for the equivalent
+ type in the <span class="productname">PostgreSQL</span> server.
+ </p><p>
+ The following functions can be used to work with the interval type:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PGTYPESINTERVALNEW"><span class="term"><code class="function">PGTYPESinterval_new</code></span></dt><dd><p>
+ Return a pointer to a newly allocated interval variable.
+</p><pre class="synopsis">
+interval *PGTYPESinterval_new(void);
+</pre><p>
+ </p></dd><dt id="PGTYPESINTERVALFREE"><span class="term"><code class="function">PGTYPESinterval_free</code></span></dt><dd><p>
+ Release the memory of a previously allocated interval variable.
+</p><pre class="synopsis">
+void PGTYPESinterval_free(interval *intvl);
+</pre><p>
+ </p></dd><dt id="PGTYPESINTERVALFROMASC"><span class="term"><code class="function">PGTYPESinterval_from_asc</code></span></dt><dd><p>
+ Parse an interval from its textual representation.
+</p><pre class="synopsis">
+interval *PGTYPESinterval_from_asc(char *str, char **endptr);
+</pre><p>
+ The function parses the input string <code class="literal">str</code> and returns a
+ pointer to an allocated interval variable.
+ At the moment ECPG always parses
+ the complete string and so it currently does not support to store the
+ address of the first invalid character in <code class="literal">*endptr</code>.
+ You can safely set <code class="literal">endptr</code> to NULL.
+ </p></dd><dt id="PGTYPESINTERVALTOASC"><span class="term"><code class="function">PGTYPESinterval_to_asc</code></span></dt><dd><p>
+ Convert a variable of type interval to its textual representation.
+</p><pre class="synopsis">
+char *PGTYPESinterval_to_asc(interval *span);
+</pre><p>
+ The function converts the interval variable that <code class="literal">span</code>
+ points to into a C char*. The output looks like this example:
+ <code class="literal">@ 1 day 12 hours 59 mins 10 secs</code>.
+ The result must be freed with <code class="function">PGTYPESchar_free()</code>.
+ </p></dd><dt id="PGTYPESINTERVALCOPY"><span class="term"><code class="function">PGTYPESinterval_copy</code></span></dt><dd><p>
+ Copy a variable of type interval.
+</p><pre class="synopsis">
+int PGTYPESinterval_copy(interval *intvlsrc, interval *intvldest);
+</pre><p>
+ The function copies the interval variable that <code class="literal">intvlsrc</code>
+ points to into the variable that <code class="literal">intvldest</code> points to. Note
+ that you need to allocate the memory for the destination variable
+ before.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PGTYPES-DECIMAL"><div class="titlepage"><div><div><h3 class="title">36.6.6. The decimal Type</h3></div></div></div><p>
+ The decimal type is similar to the numeric type. However it is limited to
+ a maximum precision of 30 significant digits. In contrast to the numeric
+ type which can be created on the heap only, the decimal type can be
+ created either on the stack or on the heap (by means of the functions
+ <code class="function">PGTYPESdecimal_new</code> and
+ <code class="function">PGTYPESdecimal_free</code>).
+ There are a lot of other functions that deal with the decimal type in the
+ <span class="productname">Informix</span> compatibility mode described in <a class="xref" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode">Section 36.15</a>.
+ </p><p>
+ The following functions can be used to work with the decimal type and are
+ not only contained in the <code class="literal">libcompat</code> library.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">PGTYPESdecimal_new</code></span></dt><dd><p>
+ Request a pointer to a newly allocated decimal variable.
+</p><pre class="synopsis">
+decimal *PGTYPESdecimal_new(void);
+</pre><p>
+ </p></dd><dt><span class="term"><code class="function">PGTYPESdecimal_free</code></span></dt><dd><p>
+ Free a decimal type, release all of its memory.
+</p><pre class="synopsis">
+void PGTYPESdecimal_free(decimal *var);
+</pre><p>
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PGTYPES-ERRNO"><div class="titlepage"><div><div><h3 class="title">36.6.7. errno Values of pgtypeslib</h3></div></div></div><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">PGTYPES_NUM_BAD_NUMERIC</code></span></dt><dd><p>
+ An argument should contain a numeric variable (or point to a numeric
+ variable) but in fact its in-memory representation was invalid.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_NUM_OVERFLOW</code></span></dt><dd><p>
+ An overflow occurred. Since the numeric type can deal with almost
+ arbitrary precision, converting a numeric variable into other types
+ might cause overflow.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_NUM_UNDERFLOW</code></span></dt><dd><p>
+ An underflow occurred. Since the numeric type can deal with almost
+ arbitrary precision, converting a numeric variable into other types
+ might cause underflow.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_NUM_DIVIDE_ZERO</code></span></dt><dd><p>
+ A division by zero has been attempted.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_DATE_BAD_DATE</code></span></dt><dd><p>
+ An invalid date string was passed to
+ the <code class="function">PGTYPESdate_from_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_DATE_ERR_EARGS</code></span></dt><dd><p>
+ Invalid arguments were passed to the
+ <code class="function">PGTYPESdate_defmt_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_DATE_ERR_ENOSHORTDATE</code></span></dt><dd><p>
+ An invalid token in the input string was found by the
+ <code class="function">PGTYPESdate_defmt_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_INTVL_BAD_INTERVAL</code></span></dt><dd><p>
+ An invalid interval string was passed to the
+ <code class="function">PGTYPESinterval_from_asc</code> function, or an
+ invalid interval value was passed to the
+ <code class="function">PGTYPESinterval_to_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_DATE_ERR_ENOTDMY</code></span></dt><dd><p>
+ There was a mismatch in the day/month/year assignment in the
+ <code class="function">PGTYPESdate_defmt_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_DATE_BAD_DAY</code></span></dt><dd><p>
+ An invalid day of the month value was found by
+ the <code class="function">PGTYPESdate_defmt_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_DATE_BAD_MONTH</code></span></dt><dd><p>
+ An invalid month value was found by
+ the <code class="function">PGTYPESdate_defmt_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_TS_BAD_TIMESTAMP</code></span></dt><dd><p>
+ An invalid timestamp string pass passed to
+ the <code class="function">PGTYPEStimestamp_from_asc</code> function,
+ or an invalid timestamp value was passed to
+ the <code class="function">PGTYPEStimestamp_to_asc</code> function.
+ </p></dd><dt><span class="term"><code class="literal">PGTYPES_TS_ERR_EINFTIME</code></span></dt><dd><p>
+ An infinite timestamp value was encountered in a context that
+ cannot handle it.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="ECPG-PGTYPES-CONSTANTS"><div class="titlepage"><div><div><h3 class="title">36.6.8. Special Constants of pgtypeslib</h3></div></div></div><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PGTYPESINVALIDTIMESTAMP"><span class="term"><code class="literal">PGTYPESInvalidTimestamp</code></span></dt><dd><p>
+ A value of type timestamp representing an invalid time stamp. This is
+ returned by the function <code class="function">PGTYPEStimestamp_from_asc</code> on
+ parse error.
+ Note that due to the internal representation of the <code class="type">timestamp</code> data type,
+ <code class="literal">PGTYPESInvalidTimestamp</code> is also a valid timestamp at
+ the same time. It is set to <code class="literal">1899-12-31 23:59:59</code>. In order
+ to detect errors, make sure that your application does not only test
+ for <code class="literal">PGTYPESInvalidTimestamp</code> but also for
+ <code class="literal">errno != 0</code> after each call to
+ <code class="function">PGTYPEStimestamp_from_asc</code>.
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-dynamic.html" title="36.5. Dynamic SQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.5. Dynamic SQL </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.7. Using Descriptor Areas</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-preproc.html b/doc/src/sgml/html/ecpg-preproc.html
new file mode 100644
index 0000000..d0087e5
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-preproc.html
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.9. Preprocessor Directives</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-errors.html" title="36.8. Error Handling" /><link rel="next" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.9. Preprocessor Directives</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-errors.html" title="36.8. Error Handling">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-PREPROC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.9. Preprocessor Directives</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-preproc.html#ECPG-INCLUDE">36.9.1. Including Files</a></span></dt><dt><span class="sect2"><a href="ecpg-preproc.html#ECPG-DEFINE">36.9.2. The define and undef Directives</a></span></dt><dt><span class="sect2"><a href="ecpg-preproc.html#ECPG-IFDEF">36.9.3. ifdef, ifndef, elif, else, and endif Directives</a></span></dt></dl></div><p>
+ Several preprocessor directives are available that modify how
+ the <code class="command">ecpg</code> preprocessor parses and processes a
+ file.
+ </p><div class="sect2" id="ECPG-INCLUDE"><div class="titlepage"><div><div><h3 class="title">36.9.1. Including Files</h3></div></div></div><p>
+ To include an external file into your embedded SQL program, use:
+</p><pre class="programlisting">
+EXEC SQL INCLUDE <em class="replaceable"><code>filename</code></em>;
+EXEC SQL INCLUDE &lt;<em class="replaceable"><code>filename</code></em>&gt;;
+EXEC SQL INCLUDE "<em class="replaceable"><code>filename</code></em>";
+</pre><p>
+ The embedded SQL preprocessor will look for a file named
+ <code class="literal"><em class="replaceable"><code>filename</code></em>.h</code>,
+ preprocess it, and include it in the resulting C output. Thus,
+ embedded SQL statements in the included file are handled correctly.
+ </p><p>
+ The <code class="command">ecpg</code> preprocessor will search a file at
+ several directories in following order:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">current directory</li><li class="listitem"><code class="filename">/usr/local/include</code></li><li class="listitem">PostgreSQL include directory, defined at build time (e.g., <code class="filename">/usr/local/pgsql/include</code>)</li><li class="listitem"><code class="filename">/usr/include</code></li></ul></div><p>
+
+ But when <code class="literal">EXEC SQL INCLUDE
+ "<em class="replaceable"><code>filename</code></em>"</code> is used, only the
+ current directory is searched.
+ </p><p>
+ In each directory, the preprocessor will first look for the file
+ name as given, and if not found will append <code class="literal">.h</code>
+ to the file name and try again (unless the specified file name
+ already has that suffix).
+ </p><p>
+ Note that <code class="command">EXEC SQL INCLUDE</code> is <span class="emphasis"><em>not</em></span> the same as:
+</p><pre class="programlisting">
+#include &lt;<em class="replaceable"><code>filename</code></em>.h&gt;
+</pre><p>
+ because this file would not be subject to SQL command preprocessing.
+ Naturally, you can continue to use the C
+ <code class="literal">#include</code> directive to include other header
+ files.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The include file name is case-sensitive, even though the rest of
+ the <code class="literal">EXEC SQL INCLUDE</code> command follows the normal
+ SQL case-sensitivity rules.
+ </p></div></div><div class="sect2" id="ECPG-DEFINE"><div class="titlepage"><div><div><h3 class="title">36.9.2. The define and undef Directives</h3></div></div></div><p>
+ Similar to the directive <code class="literal">#define</code> that is known from C,
+ embedded SQL has a similar concept:
+</p><pre class="programlisting">
+EXEC SQL DEFINE <em class="replaceable"><code>name</code></em>;
+EXEC SQL DEFINE <em class="replaceable"><code>name</code></em> <em class="replaceable"><code>value</code></em>;
+</pre><p>
+ So you can define a name:
+</p><pre class="programlisting">
+EXEC SQL DEFINE HAVE_FEATURE;
+</pre><p>
+ And you can also define constants:
+</p><pre class="programlisting">
+EXEC SQL DEFINE MYNUMBER 12;
+EXEC SQL DEFINE MYSTRING 'abc';
+</pre><p>
+ Use <code class="literal">undef</code> to remove a previous definition:
+</p><pre class="programlisting">
+EXEC SQL UNDEF MYNUMBER;
+</pre><p>
+ </p><p>
+ Of course you can continue to use the C versions <code class="literal">#define</code>
+ and <code class="literal">#undef</code> in your embedded SQL program. The difference
+ is where your defined values get evaluated. If you use <code class="literal">EXEC SQL
+ DEFINE</code> then the <code class="command">ecpg</code> preprocessor evaluates the defines and substitutes
+ the values. For example if you write:
+</p><pre class="programlisting">
+EXEC SQL DEFINE MYNUMBER 12;
+...
+EXEC SQL UPDATE Tbl SET col = MYNUMBER;
+</pre><p>
+ then <code class="command">ecpg</code> will already do the substitution and your C compiler will never
+ see any name or identifier <code class="literal">MYNUMBER</code>. Note that you cannot use
+ <code class="literal">#define</code> for a constant that you are going to use in an
+ embedded SQL query because in this case the embedded SQL precompiler is not
+ able to see this declaration.
+ </p></div><div class="sect2" id="ECPG-IFDEF"><div class="titlepage"><div><div><h3 class="title">36.9.3. ifdef, ifndef, elif, else, and endif Directives</h3></div></div></div><p>
+ You can use the following directives to compile code sections conditionally:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">EXEC SQL ifdef <em class="replaceable"><code>name</code></em>;</code></span></dt><dd><p>
+ Checks a <em class="replaceable"><code>name</code></em> and processes subsequent lines if
+ <em class="replaceable"><code>name</code></em> has been defined via <code class="literal">EXEC SQL define
+ <em class="replaceable"><code>name</code></em></code>.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL ifndef <em class="replaceable"><code>name</code></em>;</code></span></dt><dd><p>
+ Checks a <em class="replaceable"><code>name</code></em> and processes subsequent lines if
+ <em class="replaceable"><code>name</code></em> has <span class="emphasis"><em>not</em></span> been defined via
+ <code class="literal">EXEC SQL define <em class="replaceable"><code>name</code></em></code>.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL elif <em class="replaceable"><code>name</code></em>;</code></span></dt><dd><p>
+ Begins an optional alternative section after an
+ <code class="literal">EXEC SQL ifdef <em class="replaceable"><code>name</code></em></code> or
+ <code class="literal">EXEC SQL ifndef <em class="replaceable"><code>name</code></em></code>
+ directive. Any number of <code class="literal">elif</code> sections can appear.
+ Lines following an <code class="literal">elif</code> will be processed
+ if <em class="replaceable"><code>name</code></em> has been
+ defined <span class="emphasis"><em>and</em></span> no previous section of the same
+ <code class="literal">ifdef</code>/<code class="literal">ifndef</code>...<code class="literal">endif</code>
+ construct has been processed.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL else;</code></span></dt><dd><p>
+ Begins an optional, final alternative section after an
+ <code class="literal">EXEC SQL ifdef <em class="replaceable"><code>name</code></em></code> or
+ <code class="literal">EXEC SQL ifndef <em class="replaceable"><code>name</code></em></code>
+ directive. Subsequent lines will be processed if no previous section
+ of the same
+ <code class="literal">ifdef</code>/<code class="literal">ifndef</code>...<code class="literal">endif</code>
+ construct has been processed.
+ </p></dd><dt><span class="term"><code class="literal">EXEC SQL endif;</code></span></dt><dd><p>
+ Ends an
+ <code class="literal">ifdef</code>/<code class="literal">ifndef</code>...<code class="literal">endif</code>
+ construct. Subsequent lines are processed normally.
+ </p></dd></dl></div><p>
+ </p><p>
+ <code class="literal">ifdef</code>/<code class="literal">ifndef</code>...<code class="literal">endif</code>
+ constructs can be nested, up to 127 levels deep.
+ </p><p>
+ This example will compile exactly one of the three <code class="literal">SET
+ TIMEZONE</code> commands:
+</p><pre class="programlisting">
+EXEC SQL ifdef TZVAR;
+EXEC SQL SET TIMEZONE TO TZVAR;
+EXEC SQL elif TZNAME;
+EXEC SQL SET TIMEZONE TO TZNAME;
+EXEC SQL else;
+EXEC SQL SET TIMEZONE TO 'GMT';
+EXEC SQL endif;
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-errors.html" title="36.8. Error Handling">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-process.html" title="36.10. Processing Embedded SQL Programs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.8. Error Handling </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.10. Processing Embedded SQL Programs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-process.html b/doc/src/sgml/html/ecpg-process.html
new file mode 100644
index 0000000..6bcd046
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-process.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.10. Processing Embedded SQL Programs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-preproc.html" title="36.9. Preprocessor Directives" /><link rel="next" href="ecpg-library.html" title="36.11. Library Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.10. Processing Embedded SQL Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-preproc.html" title="36.9. Preprocessor Directives">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-library.html" title="36.11. Library Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-PROCESS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.10. Processing Embedded SQL Programs</h2></div></div></div><p>
+ Now that you have an idea how to form embedded SQL C programs, you
+ probably want to know how to compile them. Before compiling you
+ run the file through the embedded <acronym class="acronym">SQL</acronym>
+ <acronym class="acronym">C</acronym> preprocessor, which converts the
+ <acronym class="acronym">SQL</acronym> statements you used to special function
+ calls. After compiling, you must link with a special library that
+ contains the needed functions. These functions fetch information
+ from the arguments, perform the <acronym class="acronym">SQL</acronym> command using
+ the <span class="application">libpq</span> interface, and put the result
+ in the arguments specified for output.
+ </p><p>
+ The preprocessor program is called <code class="filename">ecpg</code> and is
+ included in a normal <span class="productname">PostgreSQL</span> installation.
+ Embedded SQL programs are typically named with an extension
+ <code class="filename">.pgc</code>. If you have a program file called
+ <code class="filename">prog1.pgc</code>, you can preprocess it by simply
+ calling:
+</p><pre class="programlisting">
+ecpg prog1.pgc
+</pre><p>
+ This will create a file called <code class="filename">prog1.c</code>. If
+ your input files do not follow the suggested naming pattern, you
+ can specify the output file explicitly using the
+ <code class="option">-o</code> option.
+ </p><p>
+ The preprocessed file can be compiled normally, for example:
+</p><pre class="programlisting">
+cc -c prog1.c
+</pre><p>
+ The generated C source files include header files from the
+ <span class="productname">PostgreSQL</span> installation, so if you installed
+ <span class="productname">PostgreSQL</span> in a location that is not searched by
+ default, you have to add an option such as
+ <code class="literal">-I/usr/local/pgsql/include</code> to the compilation
+ command line.
+ </p><p>
+ To link an embedded SQL program, you need to include the
+ <code class="filename">libecpg</code> library, like so:
+</p><pre class="programlisting">
+cc -o myprog prog1.o prog2.o ... -lecpg
+</pre><p>
+ Again, you might have to add an option like
+ <code class="literal">-L/usr/local/pgsql/lib</code> to that command line.
+ </p><p>
+ You can
+ use <code class="command">pg_config</code><a id="id-1.7.5.16.6.2" class="indexterm"></a>
+ or <code class="command">pkg-config</code><a id="id-1.7.5.16.6.4" class="indexterm"></a> with package name <code class="literal">libecpg</code> to
+ get the paths for your installation.
+ </p><p>
+ If you manage the build process of a larger project using
+ <span class="application">make</span>, it might be convenient to include
+ the following implicit rule to your makefiles:
+</p><pre class="programlisting">
+ECPG = ecpg
+
+%.c: %.pgc
+ $(ECPG) $&lt;
+</pre><p>
+ </p><p>
+ The complete syntax of the <code class="command">ecpg</code> command is
+ detailed in <a class="xref" href="app-ecpg.html" title="ecpg"><span class="refentrytitle"><span class="application">ecpg</span></span></a>.
+ </p><p>
+ The <span class="application">ecpg</span> library is thread-safe by
+ default. However, you might need to use some threading
+ command-line options to compile your client code.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-preproc.html" title="36.9. Preprocessor Directives">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-library.html" title="36.11. Library Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.9. Preprocessor Directives </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.11. Library Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-allocate-descriptor.html b/doc/src/sgml/html/ecpg-sql-allocate-descriptor.html
new file mode 100644
index 0000000..0052872
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-allocate-descriptor.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALLOCATE DESCRIPTOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands" /><link rel="next" href="ecpg-sql-connect.html" title="CONNECT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALLOCATE DESCRIPTOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-connect.html" title="CONNECT">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-ALLOCATE-DESCRIPTOR"><div class="titlepage"></div><div class="refnamediv"><h2>ALLOCATE DESCRIPTOR</h2><p>ALLOCATE DESCRIPTOR — allocate an SQL descriptor area</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALLOCATE DESCRIPTOR <em class="replaceable"><code>name</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.3.3"><h2>Description</h2><p>
+ <code class="command">ALLOCATE DESCRIPTOR</code> allocates a new named SQL
+ descriptor area, which can be used to exchange data between the
+ PostgreSQL server and the host program.
+ </p><p>
+ Descriptor areas should be freed after use using
+ the <code class="command">DEALLOCATE DESCRIPTOR</code> command.
+ </p></div><div class="refsect1" id="id-1.7.5.20.3.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ A name of SQL descriptor, case sensitive. This can be an SQL
+ identifier or a host variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.3.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL ALLOCATE DESCRIPTOR mydesc;
+</pre></div><div class="refsect1" id="id-1.7.5.20.3.6"><h2>Compatibility</h2><p>
+ <code class="command">ALLOCATE DESCRIPTOR</code> is specified in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.3.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR">DEALLOCATE DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">GET DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">SET DESCRIPTOR</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-connect.html" title="CONNECT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.14. Embedded SQL Commands </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CONNECT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-commands.html b/doc/src/sgml/html/ecpg-sql-commands.html
new file mode 100644
index 0000000..63a290f
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-commands.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.14. Embedded SQL Commands</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-cpp.html" title="36.13. C++ Applications" /><link rel="next" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.14. Embedded SQL Commands</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-cpp.html" title="36.13. C++ Applications">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-SQL-COMMANDS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.14. Embedded SQL Commands</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="ecpg-sql-allocate-descriptor.html">ALLOCATE DESCRIPTOR</a></span><span class="refpurpose"> — allocate an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-connect.html">CONNECT</a></span><span class="refpurpose"> — establish a database connection</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-deallocate-descriptor.html">DEALLOCATE DESCRIPTOR</a></span><span class="refpurpose"> — deallocate an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-declare.html">DECLARE</a></span><span class="refpurpose"> — define a cursor</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-declare-statement.html">DECLARE STATEMENT</a></span><span class="refpurpose"> — declare SQL statement identifier</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-describe.html">DESCRIBE</a></span><span class="refpurpose"> — obtain information about a prepared statement or result set</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-disconnect.html">DISCONNECT</a></span><span class="refpurpose"> — terminate a database connection</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-execute-immediate.html">EXECUTE IMMEDIATE</a></span><span class="refpurpose"> — dynamically prepare and execute a statement</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-get-descriptor.html">GET DESCRIPTOR</a></span><span class="refpurpose"> — get information from an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-open.html">OPEN</a></span><span class="refpurpose"> — open a dynamic cursor</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-prepare.html">PREPARE</a></span><span class="refpurpose"> — prepare a statement for execution</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-set-autocommit.html">SET AUTOCOMMIT</a></span><span class="refpurpose"> — set the autocommit behavior of the current session</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-set-connection.html">SET CONNECTION</a></span><span class="refpurpose"> — select a database connection</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-set-descriptor.html">SET DESCRIPTOR</a></span><span class="refpurpose"> — set information in an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-type.html">TYPE</a></span><span class="refpurpose"> — define a new data type</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-var.html">VAR</a></span><span class="refpurpose"> — define a variable</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-whenever.html">WHENEVER</a></span><span class="refpurpose"> — specify the action to be taken when an SQL statement causes a specific class condition to be raised</span></dt></dl></div><p>
+ This section describes all SQL commands that are specific to
+ embedded SQL. Also refer to the SQL commands listed
+ in <a class="xref" href="sql-commands.html" title="SQL Commands">SQL Commands</a>, which can also be used in
+ embedded SQL, unless stated otherwise.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-cpp.html" title="36.13. C++ Applications">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.13. <acronym class="acronym">C++</acronym> Applications </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALLOCATE DESCRIPTOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-connect.html b/doc/src/sgml/html/ecpg-sql-connect.html
new file mode 100644
index 0000000..59f2ffc
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-connect.html
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CONNECT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR" /><link rel="next" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CONNECT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-CONNECT"><div class="titlepage"></div><div class="refnamediv"><h2>CONNECT</h2><p>CONNECT — establish a database connection</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CONNECT TO <em class="replaceable"><code>connection_target</code></em> [ AS <em class="replaceable"><code>connection_name</code></em> ] [ USER <em class="replaceable"><code>connection_user</code></em> ]
+CONNECT TO DEFAULT
+CONNECT <em class="replaceable"><code>connection_user</code></em>
+DATABASE <em class="replaceable"><code>connection_target</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.4.3"><h2>Description</h2><p>
+ The <code class="command">CONNECT</code> command establishes a connection
+ between the client and the PostgreSQL server.
+ </p></div><div class="refsect1" id="id-1.7.5.20.4.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>connection_target</code></em></span></dt><dd><p>
+ <em class="replaceable"><code>connection_target</code></em>
+ specifies the target server of the connection on one of
+ several forms.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">[ <em class="replaceable"><code>database_name</code></em> ] [ <code class="literal">@</code><em class="replaceable"><code>host</code></em> ] [ <code class="literal">:</code><em class="replaceable"><code>port</code></em> ]</span></dt><dd><p>
+ Connect over TCP/IP
+ </p></dd><dt><span class="term"><code class="literal">unix:postgresql://</code><em class="replaceable"><code>host</code></em> [ <code class="literal">:</code><em class="replaceable"><code>port</code></em> ] <code class="literal">/</code> [ <em class="replaceable"><code>database_name</code></em> ] [ <code class="literal">?</code><em class="replaceable"><code>connection_option</code></em> ]</span></dt><dd><p>
+ Connect over Unix-domain sockets
+ </p></dd><dt><span class="term"><code class="literal">tcp:postgresql://</code><em class="replaceable"><code>host</code></em> [ <code class="literal">:</code><em class="replaceable"><code>port</code></em> ] <code class="literal">/</code> [ <em class="replaceable"><code>database_name</code></em> ] [ <code class="literal">?</code><em class="replaceable"><code>connection_option</code></em> ]</span></dt><dd><p>
+ Connect over TCP/IP
+ </p></dd><dt><span class="term">SQL string constant</span></dt><dd><p>
+ containing a value in one of the above forms
+ </p></dd><dt><span class="term">host variable</span></dt><dd><p>
+ host variable of type <code class="type">char[]</code>
+ or <code class="type">VARCHAR[]</code> containing a value in one of the
+ above forms
+ </p></dd></dl></div><p>
+ </p></dd><dt><span class="term"><em class="replaceable"><code>connection_name</code></em></span></dt><dd><p>
+ An optional identifier for the connection, so that it can be
+ referred to in other commands. This can be an SQL identifier
+ or a host variable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>connection_user</code></em></span></dt><dd><p>
+ The user name for the database connection.
+ </p><p>
+ This parameter can also specify user name and password, using one the forms
+ <code class="literal"><em class="replaceable"><code>user_name</code></em>/<em class="replaceable"><code>password</code></em></code>,
+ <code class="literal"><em class="replaceable"><code>user_name</code></em> IDENTIFIED BY <em class="replaceable"><code>password</code></em></code>, or
+ <code class="literal"><em class="replaceable"><code>user_name</code></em> USING <em class="replaceable"><code>password</code></em></code>.
+ </p><p>
+ User name and password can be SQL identifiers, string
+ constants, or host variables.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Use all default connection parameters, as defined by libpq.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.4.5"><h2>Examples</h2><p>
+ Here a several variants for specifying connection parameters:
+</p><pre class="programlisting">
+EXEC SQL CONNECT TO "connectdb" AS main;
+EXEC SQL CONNECT TO "connectdb" AS second;
+EXEC SQL CONNECT TO "unix:postgresql://200.46.204.71/connectdb" AS main USER connectuser;
+EXEC SQL CONNECT TO "unix:postgresql://localhost/connectdb" AS main USER connectuser;
+EXEC SQL CONNECT TO 'connectdb' AS main;
+EXEC SQL CONNECT TO 'unix:postgresql://localhost/connectdb' AS main USER :user;
+EXEC SQL CONNECT TO :db AS :id;
+EXEC SQL CONNECT TO :db USER connectuser USING :pw;
+EXEC SQL CONNECT TO @localhost AS main USER connectdb;
+EXEC SQL CONNECT TO REGRESSDB1 as main;
+EXEC SQL CONNECT TO AS main USER connectdb;
+EXEC SQL CONNECT TO connectdb AS :id;
+EXEC SQL CONNECT TO connectdb AS main USER connectuser/connectdb;
+EXEC SQL CONNECT TO connectdb AS main;
+EXEC SQL CONNECT TO connectdb@localhost AS main;
+EXEC SQL CONNECT TO tcp:postgresql://localhost/ USER connectdb;
+EXEC SQL CONNECT TO tcp:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY connectpw;
+EXEC SQL CONNECT TO tcp:postgresql://localhost:20/connectdb USER connectuser IDENTIFIED BY connectpw;
+EXEC SQL CONNECT TO unix:postgresql://localhost/ AS main USER connectdb;
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb AS main USER connectuser;
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb USER connectuser IDENTIFIED BY "connectpw";
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb USER connectuser USING "connectpw";
+EXEC SQL CONNECT TO unix:postgresql://localhost/connectdb?connect_timeout=14 USER connectuser;
+</pre><p>
+ </p><p>
+ Here is an example program that illustrates the use of host
+ variables to specify connection parameters:
+</p><pre class="programlisting">
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ char *dbname = "testdb"; /* database name */
+ char *user = "testuser"; /* connection user name */
+ char *connection = "tcp:postgresql://localhost:5432/testdb";
+ /* connection string */
+ char ver[256]; /* buffer to store the version string */
+EXEC SQL END DECLARE SECTION;
+
+ ECPGdebug(1, stderr);
+
+ EXEC SQL CONNECT TO :dbname USER :user;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL SELECT version() INTO :ver;
+ EXEC SQL DISCONNECT;
+
+ printf("version: %s\n", ver);
+
+ EXEC SQL CONNECT TO :connection USER :user;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL SELECT version() INTO :ver;
+ EXEC SQL DISCONNECT;
+
+ printf("version: %s\n", ver);
+
+ return 0;
+}
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.7.5.20.4.6"><h2>Compatibility</h2><p>
+ <code class="command">CONNECT</code> is specified in the SQL standard, but
+ the format of the connection parameters is
+ implementation-specific.
+ </p></div><div class="refsect1" id="id-1.7.5.20.4.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-disconnect.html" title="DISCONNECT">DISCONNECT</a>, <a class="xref" href="ecpg-sql-set-connection.html" title="SET CONNECTION">SET CONNECTION</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALLOCATE DESCRIPTOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DEALLOCATE DESCRIPTOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-deallocate-descriptor.html b/doc/src/sgml/html/ecpg-sql-deallocate-descriptor.html
new file mode 100644
index 0000000..b3d370c
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-deallocate-descriptor.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DEALLOCATE DESCRIPTOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-connect.html" title="CONNECT" /><link rel="next" href="ecpg-sql-declare.html" title="DECLARE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DEALLOCATE DESCRIPTOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-connect.html" title="CONNECT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-declare.html" title="DECLARE">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-DEALLOCATE-DESCRIPTOR"><div class="titlepage"></div><div class="refnamediv"><h2>DEALLOCATE DESCRIPTOR</h2><p>DEALLOCATE DESCRIPTOR — deallocate an SQL descriptor area</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DEALLOCATE DESCRIPTOR <em class="replaceable"><code>name</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.5.3"><h2>Description</h2><p>
+ <code class="command">DEALLOCATE DESCRIPTOR</code> deallocates a named SQL
+ descriptor area.
+ </p></div><div class="refsect1" id="id-1.7.5.20.5.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the descriptor which is going to be deallocated.
+ It is case sensitive. This can be an SQL identifier or a host
+ variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.5.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL DEALLOCATE DESCRIPTOR mydesc;
+</pre></div><div class="refsect1" id="id-1.7.5.20.5.6"><h2>Compatibility</h2><p>
+ <code class="command">DEALLOCATE DESCRIPTOR</code> is specified in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.5.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">ALLOCATE DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">GET DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">SET DESCRIPTOR</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-connect.html" title="CONNECT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-declare.html" title="DECLARE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CONNECT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DECLARE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-declare-statement.html b/doc/src/sgml/html/ecpg-sql-declare-statement.html
new file mode 100644
index 0000000..be3c3bd
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-declare-statement.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DECLARE STATEMENT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-declare.html" title="DECLARE" /><link rel="next" href="ecpg-sql-describe.html" title="DESCRIBE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DECLARE STATEMENT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-declare.html" title="DECLARE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-describe.html" title="DESCRIBE">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-DECLARE-STATEMENT"><div class="titlepage"></div><div class="refnamediv"><h2>DECLARE STATEMENT</h2><p>DECLARE STATEMENT — declare SQL statement identifier</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+EXEC SQL [ AT <em class="replaceable"><code>connection_name</code></em> ] DECLARE <em class="replaceable"><code>statement_name</code></em> STATEMENT
+</pre></div><div class="refsect1" id="id-1.7.5.20.7.3"><h2>Description</h2><p>
+ <code class="command">DECLARE STATEMENT</code> declares an SQL statement identifier.
+ SQL statement identifier can be associated with the connection.
+ When the identifier is used by dynamic SQL statements, the statements
+ are executed using the associated connection.
+ The namespace of the declaration is the precompile unit, and multiple
+ declarations to the same SQL statement identifier are not allowed.
+ Note that if the precompiler runs in Informix compatibility mode and
+ some SQL statement is declared, "database" can not be used as a cursor
+ name.
+ </p></div><div class="refsect1" id="id-1.7.5.20.7.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>connection_name</code></em></span></dt><dd><p>
+ A database connection name established by the <code class="command">CONNECT</code> command.
+ </p><p>
+ AT clause can be omitted, but such statement has no meaning.
+ </p></dd></dl></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>statement_name</code></em></span></dt><dd><p>
+ The name of an SQL statement identifier, either as an SQL identifier or a host variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.7.5"><h2>Notes</h2><p>
+ This association is valid only if the declaration is physically placed on top of a dynamic statement.
+ </p></div><div class="refsect1" id="id-1.7.5.20.7.6"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL CONNECT TO postgres AS con1;
+EXEC SQL AT con1 DECLARE sql_stmt STATEMENT;
+EXEC SQL DECLARE cursor_name CURSOR FOR sql_stmt;
+EXEC SQL PREPARE sql_stmt FROM :dyn_string;
+EXEC SQL OPEN cursor_name;
+EXEC SQL FETCH cursor_name INTO :column1;
+EXEC SQL CLOSE cursor_name;
+</pre></div><div class="refsect1" id="id-1.7.5.20.7.7"><h2>Compatibility</h2><p>
+ <code class="command">DECLARE STATEMENT</code> is an extension of the SQL standard,
+ but can be used in famous DBMSs.
+ </p></div><div class="refsect1" id="id-1.7.5.20.7.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-connect.html" title="CONNECT">CONNECT</a>, <a class="xref" href="ecpg-sql-declare.html" title="DECLARE">DECLARE</a>, <a class="xref" href="ecpg-sql-open.html" title="OPEN">OPEN</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-declare.html" title="DECLARE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-describe.html" title="DESCRIBE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DECLARE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DESCRIBE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-declare.html b/doc/src/sgml/html/ecpg-sql-declare.html
new file mode 100644
index 0000000..03ec0a4
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-declare.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DECLARE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR" /><link rel="next" href="ecpg-sql-declare-statement.html" title="DECLARE STATEMENT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DECLARE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-declare-statement.html" title="DECLARE STATEMENT">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-DECLARE"><div class="titlepage"></div><div class="refnamediv"><h2>DECLARE</h2><p>DECLARE — define a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DECLARE <em class="replaceable"><code>cursor_name</code></em> [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <em class="replaceable"><code>prepared_name</code></em>
+DECLARE <em class="replaceable"><code>cursor_name</code></em> [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ] FOR <em class="replaceable"><code>query</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.6.3"><h2>Description</h2><p>
+ <code class="command">DECLARE</code> declares a cursor for iterating over
+ the result set of a prepared statement. This command has
+ slightly different semantics from the direct SQL
+ command <code class="command">DECLARE</code>: Whereas the latter executes a
+ query and prepares the result set for retrieval, this embedded
+ SQL command merely declares a name as a <span class="quote">“<span class="quote">loop
+ variable</span>”</span> for iterating over the result set of a query;
+ the actual execution happens when the cursor is opened with
+ the <code class="command">OPEN</code> command.
+ </p></div><div class="refsect1" id="id-1.7.5.20.6.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>cursor_name</code></em></span></dt><dd><p>
+ A cursor name, case sensitive. This can be an SQL identifier
+ or a host variable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>prepared_name</code></em></span></dt><dd><p>
+ The name of a prepared query, either as an SQL identifier or a
+ host variable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> or
+ <a class="xref" href="sql-values.html" title="VALUES"><span class="refentrytitle">VALUES</span></a> command which will provide the
+ rows to be returned by the cursor.
+ </p></dd></dl></div><p>
+ For the meaning of the cursor options,
+ see <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>.
+ </p></div><div class="refsect1" id="id-1.7.5.20.6.5"><h2>Examples</h2><p>
+ Examples declaring a cursor for a query:
+</p><pre class="programlisting">
+EXEC SQL DECLARE C CURSOR FOR SELECT * FROM My_Table;
+EXEC SQL DECLARE C CURSOR FOR SELECT Item1 FROM T;
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT version();
+</pre><p>
+ </p><p>
+ An example declaring a cursor for a prepared statement:
+</p><pre class="programlisting">
+EXEC SQL PREPARE stmt1 AS SELECT version();
+EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.7.5.20.6.6"><h2>Compatibility</h2><p>
+ <code class="command">DECLARE</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.6.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-open.html" title="OPEN">OPEN</a>, <a class="xref" href="sql-close.html" title="CLOSE"><span class="refentrytitle">CLOSE</span></a>, <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-deallocate-descriptor.html" title="DEALLOCATE DESCRIPTOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-declare-statement.html" title="DECLARE STATEMENT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DEALLOCATE DESCRIPTOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DECLARE STATEMENT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-describe.html b/doc/src/sgml/html/ecpg-sql-describe.html
new file mode 100644
index 0000000..a9b98ff
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-describe.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DESCRIBE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-declare-statement.html" title="DECLARE STATEMENT" /><link rel="next" href="ecpg-sql-disconnect.html" title="DISCONNECT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DESCRIBE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-declare-statement.html" title="DECLARE STATEMENT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-disconnect.html" title="DISCONNECT">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-DESCRIBE"><div class="titlepage"></div><div class="refnamediv"><h2>DESCRIBE</h2><p>DESCRIBE — obtain information about a prepared statement or result set</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DESCRIBE [ OUTPUT ] <em class="replaceable"><code>prepared_name</code></em> USING [ SQL ] DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em>
+DESCRIBE [ OUTPUT ] <em class="replaceable"><code>prepared_name</code></em> INTO [ SQL ] DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em>
+DESCRIBE [ OUTPUT ] <em class="replaceable"><code>prepared_name</code></em> INTO <em class="replaceable"><code>sqlda_name</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.8.3"><h2>Description</h2><p>
+ <code class="command">DESCRIBE</code> retrieves metadata information about
+ the result columns contained in a prepared statement, without
+ actually fetching a row.
+ </p></div><div class="refsect1" id="id-1.7.5.20.8.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>prepared_name</code></em></span></dt><dd><p>
+ The name of a prepared statement. This can be an SQL
+ identifier or a host variable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>descriptor_name</code></em></span></dt><dd><p>
+ A descriptor name. It is case sensitive. It can be an SQL
+ identifier or a host variable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sqlda_name</code></em></span></dt><dd><p>
+ The name of an SQLDA variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.8.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL ALLOCATE DESCRIPTOR mydesc;
+EXEC SQL PREPARE stmt1 FROM :sql_stmt;
+EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc;
+EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :charvar = NAME;
+EXEC SQL DEALLOCATE DESCRIPTOR mydesc;
+</pre></div><div class="refsect1" id="id-1.7.5.20.8.6"><h2>Compatibility</h2><p>
+ <code class="command">DESCRIBE</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.8.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">ALLOCATE DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">GET DESCRIPTOR</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-declare-statement.html" title="DECLARE STATEMENT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-disconnect.html" title="DISCONNECT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DECLARE STATEMENT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DISCONNECT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-disconnect.html b/doc/src/sgml/html/ecpg-sql-disconnect.html
new file mode 100644
index 0000000..83e0e6a
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-disconnect.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DISCONNECT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-describe.html" title="DESCRIBE" /><link rel="next" href="ecpg-sql-execute-immediate.html" title="EXECUTE IMMEDIATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DISCONNECT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-describe.html" title="DESCRIBE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-execute-immediate.html" title="EXECUTE IMMEDIATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-DISCONNECT"><div class="titlepage"></div><div class="refnamediv"><h2>DISCONNECT</h2><p>DISCONNECT — terminate a database connection</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DISCONNECT <em class="replaceable"><code>connection_name</code></em>
+DISCONNECT [ CURRENT ]
+DISCONNECT DEFAULT
+DISCONNECT ALL
+</pre></div><div class="refsect1" id="id-1.7.5.20.9.3"><h2>Description</h2><p>
+ <code class="command">DISCONNECT</code> closes a connection (or all
+ connections) to the database.
+ </p></div><div class="refsect1" id="id-1.7.5.20.9.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>connection_name</code></em></span></dt><dd><p>
+ A database connection name established by
+ the <code class="command">CONNECT</code> command.
+ </p></dd><dt><span class="term"><code class="literal">CURRENT</code></span></dt><dd><p>
+ Close the <span class="quote">“<span class="quote">current</span>”</span> connection, which is either
+ the most recently opened connection, or the connection set by
+ the <code class="command">SET CONNECTION</code> command. This is also
+ the default if no argument is given to
+ the <code class="command">DISCONNECT</code> command.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Close the default connection.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Close all open connections.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.9.5"><h2>Examples</h2><pre class="programlisting">
+int
+main(void)
+{
+ EXEC SQL CONNECT TO testdb AS DEFAULT USER testuser;
+ EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+ EXEC SQL CONNECT TO testdb AS con2 USER testuser;
+ EXEC SQL CONNECT TO testdb AS con3 USER testuser;
+
+ EXEC SQL DISCONNECT CURRENT; /* close con3 */
+ EXEC SQL DISCONNECT DEFAULT; /* close DEFAULT */
+ EXEC SQL DISCONNECT ALL; /* close con2 and con1 */
+
+ return 0;
+}
+</pre></div><div class="refsect1" id="id-1.7.5.20.9.6"><h2>Compatibility</h2><p>
+ <code class="command">DISCONNECT</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.9.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-connect.html" title="CONNECT">CONNECT</a>, <a class="xref" href="ecpg-sql-set-connection.html" title="SET CONNECTION">SET CONNECTION</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-describe.html" title="DESCRIBE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-execute-immediate.html" title="EXECUTE IMMEDIATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DESCRIBE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> EXECUTE IMMEDIATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-execute-immediate.html b/doc/src/sgml/html/ecpg-sql-execute-immediate.html
new file mode 100644
index 0000000..9d29402
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-execute-immediate.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>EXECUTE IMMEDIATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-disconnect.html" title="DISCONNECT" /><link rel="next" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">EXECUTE IMMEDIATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-disconnect.html" title="DISCONNECT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-EXECUTE-IMMEDIATE"><div class="titlepage"></div><div class="refnamediv"><h2>EXECUTE IMMEDIATE</h2><p>EXECUTE IMMEDIATE — dynamically prepare and execute a statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+EXECUTE IMMEDIATE <em class="replaceable"><code>string</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.10.3"><h2>Description</h2><p>
+ <code class="command">EXECUTE IMMEDIATE</code> immediately prepares and
+ executes a dynamically specified SQL statement, without
+ retrieving result rows.
+ </p></div><div class="refsect1" id="id-1.7.5.20.10.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>string</code></em></span></dt><dd><p>
+ A literal string or a host variable containing the SQL
+ statement to be executed.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.10.5"><h2>Notes</h2><p>
+ In typical usage, the <em class="replaceable"><code>string</code></em> is a host
+ variable reference to a string containing a dynamically-constructed
+ SQL statement. The case of a literal string is not very useful;
+ you might as well just write the SQL statement directly, without
+ the extra typing of <code class="command">EXECUTE IMMEDIATE</code>.
+ </p><p>
+ If you do use a literal string, keep in mind that any double quotes
+ you might wish to include in the SQL statement must be written as
+ octal escapes (<code class="literal">\042</code>) not the usual C
+ idiom <code class="literal">\"</code>. This is because the string is inside
+ an <code class="literal">EXEC SQL</code> section, so the ECPG lexer parses it
+ according to SQL rules not C rules. Any embedded backslashes will
+ later be handled according to C rules; but <code class="literal">\"</code>
+ causes an immediate syntax error because it is seen as ending the
+ literal.
+ </p></div><div class="refsect1" id="id-1.7.5.20.10.6"><h2>Examples</h2><p>
+ Here is an example that executes an <code class="command">INSERT</code>
+ statement using <code class="command">EXECUTE IMMEDIATE</code> and a host
+ variable named <code class="varname">command</code>:
+</p><pre class="programlisting">
+sprintf(command, "INSERT INTO test (name, amount, letter) VALUES ('db: ''r1''', 1, 'f')");
+EXEC SQL EXECUTE IMMEDIATE :command;
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.7.5.20.10.7"><h2>Compatibility</h2><p>
+ <code class="command">EXECUTE IMMEDIATE</code> is specified in the SQL standard.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-disconnect.html" title="DISCONNECT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DISCONNECT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> GET DESCRIPTOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-get-descriptor.html b/doc/src/sgml/html/ecpg-sql-get-descriptor.html
new file mode 100644
index 0000000..5f2cbaf
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-get-descriptor.html
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>GET DESCRIPTOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-execute-immediate.html" title="EXECUTE IMMEDIATE" /><link rel="next" href="ecpg-sql-open.html" title="OPEN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">GET DESCRIPTOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-execute-immediate.html" title="EXECUTE IMMEDIATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-open.html" title="OPEN">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-GET-DESCRIPTOR"><div class="titlepage"></div><div class="refnamediv"><h2>GET DESCRIPTOR</h2><p>GET DESCRIPTOR — get information from an SQL descriptor area</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+GET DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em> <em class="replaceable"><code>:cvariable</code></em> = <em class="replaceable"><code>descriptor_header_item</code></em> [, ... ]
+GET DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em> VALUE <em class="replaceable"><code>column_number</code></em> <em class="replaceable"><code>:cvariable</code></em> = <em class="replaceable"><code>descriptor_item</code></em> [, ... ]
+</pre></div><div class="refsect1" id="id-1.7.5.20.11.3"><h2>Description</h2><p>
+ <code class="command">GET DESCRIPTOR</code> retrieves information about a
+ query result set from an SQL descriptor area and stores it into
+ host variables. A descriptor area is typically populated
+ using <code class="command">FETCH</code> or <code class="command">SELECT</code>
+ before using this command to transfer the information into host
+ language variables.
+ </p><p>
+ This command has two forms: The first form retrieves
+ descriptor <span class="quote">“<span class="quote">header</span>”</span> items, which apply to the result
+ set in its entirety. One example is the row count. The second
+ form, which requires the column number as additional parameter,
+ retrieves information about a particular column. Examples are
+ the column name and the actual column value.
+ </p></div><div class="refsect1" id="id-1.7.5.20.11.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>descriptor_name</code></em></span></dt><dd><p>
+ A descriptor name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>descriptor_header_item</code></em></span></dt><dd><p>
+ A token identifying which header information item to retrieve.
+ Only <code class="literal">COUNT</code>, to get the number of columns in the
+ result set, is currently supported.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_number</code></em></span></dt><dd><p>
+ The number of the column about which information is to be
+ retrieved. The count starts at 1.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>descriptor_item</code></em></span></dt><dd><p>
+ A token identifying which item of information about a column
+ to retrieve. See <a class="xref" href="ecpg-descriptors.html#ECPG-NAMED-DESCRIPTORS" title="36.7.1. Named SQL Descriptor Areas">Section 36.7.1</a> for
+ a list of supported items.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>cvariable</code></em></span></dt><dd><p>
+ A host variable that will receive the data retrieved from the
+ descriptor area.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.11.5"><h2>Examples</h2><p>
+ An example to retrieve the number of columns in a result set:
+</p><pre class="programlisting">
+EXEC SQL GET DESCRIPTOR d :d_count = COUNT;
+</pre><p>
+ </p><p>
+ An example to retrieve a data length in the first column:
+</p><pre class="programlisting">
+EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH;
+</pre><p>
+ </p><p>
+ An example to retrieve the data body of the second column as a
+ string:
+</p><pre class="programlisting">
+EXEC SQL GET DESCRIPTOR d VALUE 2 :d_data = DATA;
+</pre><p>
+ </p><p>
+ Here is an example for a whole procedure of
+ executing <code class="literal">SELECT current_database();</code> and showing the number of
+ columns, the column data length, and the column data:
+</p><pre class="programlisting">
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ int d_count;
+ char d_data[1024];
+ int d_returned_octet_length;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb AS con1 USER testuser;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL ALLOCATE DESCRIPTOR d;
+
+ /* Declare, open a cursor, and assign a descriptor to the cursor */
+ EXEC SQL DECLARE cur CURSOR FOR SELECT current_database();
+ EXEC SQL OPEN cur;
+ EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d;
+
+ /* Get a number of total columns */
+ EXEC SQL GET DESCRIPTOR d :d_count = COUNT;
+ printf("d_count = %d\n", d_count);
+
+ /* Get length of a returned column */
+ EXEC SQL GET DESCRIPTOR d VALUE 1 :d_returned_octet_length = RETURNED_OCTET_LENGTH;
+ printf("d_returned_octet_length = %d\n", d_returned_octet_length);
+
+ /* Fetch the returned column as a string */
+ EXEC SQL GET DESCRIPTOR d VALUE 1 :d_data = DATA;
+ printf("d_data = %s\n", d_data);
+
+ /* Closing */
+ EXEC SQL CLOSE cur;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DEALLOCATE DESCRIPTOR d;
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+</pre><p>
+ When the example is executed, the result will look like this:
+</p><pre class="screen">
+d_count = 1
+d_returned_octet_length = 6
+d_data = testdb
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.7.5.20.11.6"><h2>Compatibility</h2><p>
+ <code class="command">GET DESCRIPTOR</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.11.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">ALLOCATE DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">SET DESCRIPTOR</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-execute-immediate.html" title="EXECUTE IMMEDIATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-open.html" title="OPEN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">EXECUTE IMMEDIATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> OPEN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-open.html b/doc/src/sgml/html/ecpg-sql-open.html
new file mode 100644
index 0000000..be377a9
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-open.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>OPEN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR" /><link rel="next" href="ecpg-sql-prepare.html" title="PREPARE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">OPEN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-prepare.html" title="PREPARE">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-OPEN"><div class="titlepage"></div><div class="refnamediv"><h2>OPEN</h2><p>OPEN — open a dynamic cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+OPEN <em class="replaceable"><code>cursor_name</code></em>
+OPEN <em class="replaceable"><code>cursor_name</code></em> USING <em class="replaceable"><code>value</code></em> [, ... ]
+OPEN <em class="replaceable"><code>cursor_name</code></em> USING SQL DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.12.3"><h2>Description</h2><p>
+ <code class="command">OPEN</code> opens a cursor and optionally binds
+ actual values to the placeholders in the cursor's declaration.
+ The cursor must previously have been declared with
+ the <code class="command">DECLARE</code> command. The execution
+ of <code class="command">OPEN</code> causes the query to start executing on
+ the server.
+ </p></div><div class="refsect1" id="id-1.7.5.20.12.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>cursor_name</code></em></span></dt><dd><p>
+ The name of the cursor to be opened. This can be an SQL
+ identifier or a host variable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ A value to be bound to a placeholder in the cursor. This can
+ be an SQL constant, a host variable, or a host variable with
+ indicator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>descriptor_name</code></em></span></dt><dd><p>
+ The name of a descriptor containing values to be bound to the
+ placeholders in the cursor. This can be an SQL identifier or
+ a host variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.12.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL OPEN a;
+EXEC SQL OPEN d USING 1, 'test';
+EXEC SQL OPEN c1 USING SQL DESCRIPTOR mydesc;
+EXEC SQL OPEN :curname1;
+</pre></div><div class="refsect1" id="id-1.7.5.20.12.6"><h2>Compatibility</h2><p>
+ <code class="command">OPEN</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.12.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-declare.html" title="DECLARE">DECLARE</a>, <a class="xref" href="sql-close.html" title="CLOSE"><span class="refentrytitle">CLOSE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-prepare.html" title="PREPARE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">GET DESCRIPTOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> PREPARE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-prepare.html b/doc/src/sgml/html/ecpg-sql-prepare.html
new file mode 100644
index 0000000..15106d7
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-prepare.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PREPARE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-open.html" title="OPEN" /><link rel="next" href="ecpg-sql-set-autocommit.html" title="SET AUTOCOMMIT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">PREPARE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-open.html" title="OPEN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-set-autocommit.html" title="SET AUTOCOMMIT">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-PREPARE"><div class="titlepage"></div><div class="refnamediv"><h2>PREPARE</h2><p>PREPARE — prepare a statement for execution</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+PREPARE <em class="replaceable"><code>prepared_name</code></em> FROM <em class="replaceable"><code>string</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.13.3"><h2>Description</h2><p>
+ <code class="command">PREPARE</code> prepares a statement dynamically
+ specified as a string for execution. This is different from the
+ direct SQL statement <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a>, which can also
+ be used in embedded programs. The <a class="xref" href="sql-execute.html" title="EXECUTE"><span class="refentrytitle">EXECUTE</span></a>
+ command is used to execute either kind of prepared statement.
+ </p></div><div class="refsect1" id="id-1.7.5.20.13.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>prepared_name</code></em></span></dt><dd><p>
+ An identifier for the prepared query.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>string</code></em></span></dt><dd><p>
+ A literal string or a host variable containing a preparable
+ SQL statement, one of SELECT, INSERT, UPDATE, or DELETE.
+ Use question marks (<code class="literal">?</code>) for parameter values
+ to be supplied at execution.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.13.5"><h2>Notes</h2><p>
+ In typical usage, the <em class="replaceable"><code>string</code></em> is a host
+ variable reference to a string containing a dynamically-constructed
+ SQL statement. The case of a literal string is not very useful;
+ you might as well just write a direct SQL <code class="command">PREPARE</code>
+ statement.
+ </p><p>
+ If you do use a literal string, keep in mind that any double quotes
+ you might wish to include in the SQL statement must be written as
+ octal escapes (<code class="literal">\042</code>) not the usual C
+ idiom <code class="literal">\"</code>. This is because the string is inside
+ an <code class="literal">EXEC SQL</code> section, so the ECPG lexer parses it
+ according to SQL rules not C rules. Any embedded backslashes will
+ later be handled according to C rules; but <code class="literal">\"</code>
+ causes an immediate syntax error because it is seen as ending the
+ literal.
+ </p></div><div class="refsect1" id="id-1.7.5.20.13.6"><h2>Examples</h2><pre class="programlisting">
+char *stmt = "SELECT * FROM test1 WHERE a = ? AND b = ?";
+
+EXEC SQL ALLOCATE DESCRIPTOR outdesc;
+EXEC SQL PREPARE foo FROM :stmt;
+
+EXEC SQL EXECUTE foo USING SQL DESCRIPTOR indesc INTO SQL DESCRIPTOR outdesc;
+</pre></div><div class="refsect1" id="id-1.7.5.20.13.7"><h2>Compatibility</h2><p>
+ <code class="command">PREPARE</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.13.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-execute.html" title="EXECUTE"><span class="refentrytitle">EXECUTE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-open.html" title="OPEN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-set-autocommit.html" title="SET AUTOCOMMIT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">OPEN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET AUTOCOMMIT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-set-autocommit.html b/doc/src/sgml/html/ecpg-sql-set-autocommit.html
new file mode 100644
index 0000000..ca088a1
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-set-autocommit.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET AUTOCOMMIT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-prepare.html" title="PREPARE" /><link rel="next" href="ecpg-sql-set-connection.html" title="SET CONNECTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET AUTOCOMMIT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-prepare.html" title="PREPARE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-set-connection.html" title="SET CONNECTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-SET-AUTOCOMMIT"><div class="titlepage"></div><div class="refnamediv"><h2>SET AUTOCOMMIT</h2><p>SET AUTOCOMMIT — set the autocommit behavior of the current session</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET AUTOCOMMIT { = | TO } { ON | OFF }
+</pre></div><div class="refsect1" id="id-1.7.5.20.14.3"><h2>Description</h2><p>
+ <code class="command">SET AUTOCOMMIT</code> sets the autocommit behavior of
+ the current database session. By default, embedded SQL programs
+ are <span class="emphasis"><em>not</em></span> in autocommit mode,
+ so <code class="command">COMMIT</code> needs to be issued explicitly when
+ desired. This command can change the session to autocommit mode,
+ where each individual statement is committed implicitly.
+ </p></div><div class="refsect1" id="id-1.7.5.20.14.4"><h2>Compatibility</h2><p>
+ <code class="command">SET AUTOCOMMIT</code> is an extension of PostgreSQL ECPG.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-prepare.html" title="PREPARE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-set-connection.html" title="SET CONNECTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PREPARE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET CONNECTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-set-connection.html b/doc/src/sgml/html/ecpg-sql-set-connection.html
new file mode 100644
index 0000000..caafb81
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-set-connection.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET CONNECTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-set-autocommit.html" title="SET AUTOCOMMIT" /><link rel="next" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET CONNECTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-set-autocommit.html" title="SET AUTOCOMMIT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-SET-CONNECTION"><div class="titlepage"></div><div class="refnamediv"><h2>SET CONNECTION</h2><p>SET CONNECTION — select a database connection</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET CONNECTION [ TO | = ] <em class="replaceable"><code>connection_name</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.15.3"><h2>Description</h2><p>
+ <code class="command">SET CONNECTION</code> sets the <span class="quote">“<span class="quote">current</span>”</span>
+ database connection, which is the one that all commands use
+ unless overridden.
+ </p></div><div class="refsect1" id="id-1.7.5.20.15.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>connection_name</code></em></span></dt><dd><p>
+ A database connection name established by
+ the <code class="command">CONNECT</code> command.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Set the connection to the default connection.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.15.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL SET CONNECTION TO con2;
+EXEC SQL SET CONNECTION = con1;
+</pre></div><div class="refsect1" id="id-1.7.5.20.15.6"><h2>Compatibility</h2><p>
+ <code class="command">SET CONNECTION</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.15.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-connect.html" title="CONNECT">CONNECT</a>, <a class="xref" href="ecpg-sql-disconnect.html" title="DISCONNECT">DISCONNECT</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-set-autocommit.html" title="SET AUTOCOMMIT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET AUTOCOMMIT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET DESCRIPTOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-set-descriptor.html b/doc/src/sgml/html/ecpg-sql-set-descriptor.html
new file mode 100644
index 0000000..0800bcf
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-set-descriptor.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET DESCRIPTOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-set-connection.html" title="SET CONNECTION" /><link rel="next" href="ecpg-sql-type.html" title="TYPE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET DESCRIPTOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-set-connection.html" title="SET CONNECTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-type.html" title="TYPE">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-SET-DESCRIPTOR"><div class="titlepage"></div><div class="refnamediv"><h2>SET DESCRIPTOR</h2><p>SET DESCRIPTOR — set information in an SQL descriptor area</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em> <em class="replaceable"><code>descriptor_header_item</code></em> = <em class="replaceable"><code>value</code></em> [, ... ]
+SET DESCRIPTOR <em class="replaceable"><code>descriptor_name</code></em> VALUE <em class="replaceable"><code>number</code></em> <em class="replaceable"><code>descriptor_item</code></em> = <em class="replaceable"><code>value</code></em> [, ...]
+</pre></div><div class="refsect1" id="id-1.7.5.20.16.3"><h2>Description</h2><p>
+ <code class="command">SET DESCRIPTOR</code> populates an SQL descriptor
+ area with values. The descriptor area is then typically used to
+ bind parameters in a prepared query execution.
+ </p><p>
+ This command has two forms: The first form applies to the
+ descriptor <span class="quote">“<span class="quote">header</span>”</span>, which is independent of a
+ particular datum. The second form assigns values to particular
+ datums, identified by number.
+ </p></div><div class="refsect1" id="id-1.7.5.20.16.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>descriptor_name</code></em></span></dt><dd><p>
+ A descriptor name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>descriptor_header_item</code></em></span></dt><dd><p>
+ A token identifying which header information item to set.
+ Only <code class="literal">COUNT</code>, to set the number of descriptor
+ items, is currently supported.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>number</code></em></span></dt><dd><p>
+ The number of the descriptor item to set. The count starts at
+ 1.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>descriptor_item</code></em></span></dt><dd><p>
+ A token identifying which item of information to set in the
+ descriptor. See <a class="xref" href="ecpg-descriptors.html#ECPG-NAMED-DESCRIPTORS" title="36.7.1. Named SQL Descriptor Areas">Section 36.7.1</a> for a
+ list of supported items.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ A value to store into the descriptor item. This can be an SQL
+ constant or a host variable.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.16.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL SET DESCRIPTOR indesc COUNT = 1;
+EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = 2;
+EXEC SQL SET DESCRIPTOR indesc VALUE 1 DATA = :val1;
+EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val1, DATA = 'some string';
+EXEC SQL SET DESCRIPTOR indesc VALUE 2 INDICATOR = :val2null, DATA = :val2;
+</pre></div><div class="refsect1" id="id-1.7.5.20.16.6"><h2>Compatibility</h2><p>
+ <code class="command">SET DESCRIPTOR</code> is specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.7.5.20.16.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="ecpg-sql-allocate-descriptor.html" title="ALLOCATE DESCRIPTOR">ALLOCATE DESCRIPTOR</a>, <a class="xref" href="ecpg-sql-get-descriptor.html" title="GET DESCRIPTOR">GET DESCRIPTOR</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-set-connection.html" title="SET CONNECTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-type.html" title="TYPE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET CONNECTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> TYPE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-type.html b/doc/src/sgml/html/ecpg-sql-type.html
new file mode 100644
index 0000000..1bd40de
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-type.html
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>TYPE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR" /><link rel="next" href="ecpg-sql-var.html" title="VAR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">TYPE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-var.html" title="VAR">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-TYPE"><div class="titlepage"></div><div class="refnamediv"><h2>TYPE</h2><p>TYPE — define a new data type</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+TYPE <em class="replaceable"><code>type_name</code></em> IS <em class="replaceable"><code>ctype</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.17.3"><h2>Description</h2><p>
+ The <code class="command">TYPE</code> command defines a new C type. It is
+ equivalent to putting a <code class="literal">typedef</code> into a declare
+ section.
+ </p><p>
+ This command is only recognized when <code class="command">ecpg</code> is
+ run with the <code class="option">-c</code> option.
+ </p></div><div class="refsect1" id="id-1.7.5.20.17.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>type_name</code></em></span></dt><dd><p>
+ The name for the new type. It must be a valid C type name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>ctype</code></em></span></dt><dd><p>
+ A C type specification.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.17.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL TYPE customer IS
+ struct
+ {
+ varchar name[50];
+ int phone;
+ };
+
+EXEC SQL TYPE cust_ind IS
+ struct ind
+ {
+ short name_ind;
+ short phone_ind;
+ };
+
+EXEC SQL TYPE c IS char reference;
+EXEC SQL TYPE ind IS union { int integer; short smallint; };
+EXEC SQL TYPE intarray IS int[AMOUNT];
+EXEC SQL TYPE str IS varchar[BUFFERSIZ];
+EXEC SQL TYPE string IS char[11];
+</pre><p>
+ Here is an example program that uses <code class="command">EXEC SQL
+ TYPE</code>:
+</p><pre class="programlisting">
+EXEC SQL WHENEVER SQLERROR SQLPRINT;
+
+EXEC SQL TYPE tt IS
+ struct
+ {
+ varchar v[256];
+ int i;
+ };
+
+EXEC SQL TYPE tt_ind IS
+ struct ind {
+ short v_ind;
+ short i_ind;
+ };
+
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ tt t;
+ tt_ind t_ind;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb AS con1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ EXEC SQL SELECT current_database(), 256 INTO :t:t_ind LIMIT 1;
+
+ printf("t.v = %s\n", t.v.arr);
+ printf("t.i = %d\n", t.i);
+
+ printf("t_ind.v_ind = %d\n", t_ind.v_ind);
+ printf("t_ind.i_ind = %d\n", t_ind.i_ind);
+
+ EXEC SQL DISCONNECT con1;
+
+ return 0;
+}
+</pre><p>
+
+ The output from this program looks like this:
+</p><pre class="screen">
+t.v = testdb
+t.i = 256
+t_ind.v_ind = 0
+t_ind.i_ind = 0
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.7.5.20.17.6"><h2>Compatibility</h2><p>
+ The <code class="command">TYPE</code> command is a PostgreSQL extension.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-set-descriptor.html" title="SET DESCRIPTOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-var.html" title="VAR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET DESCRIPTOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> VAR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-var.html b/doc/src/sgml/html/ecpg-sql-var.html
new file mode 100644
index 0000000..a01e32e
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-var.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>VAR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-type.html" title="TYPE" /><link rel="next" href="ecpg-sql-whenever.html" title="WHENEVER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">VAR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-type.html" title="TYPE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-sql-whenever.html" title="WHENEVER">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-VAR"><div class="titlepage"></div><div class="refnamediv"><h2>VAR</h2><p>VAR — define a variable</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+VAR <em class="replaceable"><code>varname</code></em> IS <em class="replaceable"><code>ctype</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.18.3"><h2>Description</h2><p>
+ The <code class="command">VAR</code> command assigns a new C data type
+ to a host variable. The host variable must be previously
+ declared in a declare section.
+ </p></div><div class="refsect1" id="id-1.7.5.20.18.4"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>varname</code></em></span></dt><dd><p>
+ A C variable name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>ctype</code></em></span></dt><dd><p>
+ A C type specification.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.7.5.20.18.5"><h2>Examples</h2><pre class="programlisting">
+Exec sql begin declare section;
+short a;
+exec sql end declare section;
+EXEC SQL VAR a IS int;
+</pre></div><div class="refsect1" id="id-1.7.5.20.18.6"><h2>Compatibility</h2><p>
+ The <code class="command">VAR</code> command is a PostgreSQL extension.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-type.html" title="TYPE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-sql-whenever.html" title="WHENEVER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">TYPE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> WHENEVER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-sql-whenever.html b/doc/src/sgml/html/ecpg-sql-whenever.html
new file mode 100644
index 0000000..ff1e0a6
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-sql-whenever.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>WHENEVER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-sql-var.html" title="VAR" /><link rel="next" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">WHENEVER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-sql-var.html" title="VAR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><th width="60%" align="center">36.14. Embedded SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode">Next</a></td></tr></table><hr /></div><div class="refentry" id="ECPG-SQL-WHENEVER"><div class="titlepage"></div><div class="refnamediv"><h2>WHENEVER</h2><p>WHENEVER — specify the action to be taken when an SQL statement causes a specific class condition to be raised</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+WHENEVER { NOT FOUND | SQLERROR | SQLWARNING } <em class="replaceable"><code>action</code></em>
+</pre></div><div class="refsect1" id="id-1.7.5.20.19.3"><h2>Description</h2><p>
+ Define a behavior which is called on the special cases (Rows not
+ found, SQL warnings or errors) in the result of SQL execution.
+ </p></div><div class="refsect1" id="id-1.7.5.20.19.4"><h2>Parameters</h2><p>
+ See <a class="xref" href="ecpg-errors.html#ECPG-WHENEVER" title="36.8.1. Setting Callbacks">Section 36.8.1</a> for a description of the
+ parameters.
+ </p></div><div class="refsect1" id="id-1.7.5.20.19.5"><h2>Examples</h2><pre class="programlisting">
+EXEC SQL WHENEVER NOT FOUND CONTINUE;
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+EXEC SQL WHENEVER NOT FOUND DO CONTINUE;
+EXEC SQL WHENEVER SQLWARNING SQLPRINT;
+EXEC SQL WHENEVER SQLWARNING DO warn();
+EXEC SQL WHENEVER SQLERROR sqlprint;
+EXEC SQL WHENEVER SQLERROR CALL print2();
+EXEC SQL WHENEVER SQLERROR DO handle_error("select");
+EXEC SQL WHENEVER SQLERROR DO sqlnotice(NULL, NONO);
+EXEC SQL WHENEVER SQLERROR DO sqlprint();
+EXEC SQL WHENEVER SQLERROR GOTO error_label;
+EXEC SQL WHENEVER SQLERROR STOP;
+</pre><p>
+ A typical application is the use of <code class="literal">WHENEVER NOT FOUND
+ BREAK</code> to handle looping through result sets:
+</p><pre class="programlisting">
+int
+main(void)
+{
+ EXEC SQL CONNECT TO testdb AS con1;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+ EXEC SQL ALLOCATE DESCRIPTOR d;
+ EXEC SQL DECLARE cur CURSOR FOR SELECT current_database(), 'hoge', 256;
+ EXEC SQL OPEN cur;
+
+ /* when end of result set reached, break out of while loop */
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ EXEC SQL FETCH NEXT FROM cur INTO SQL DESCRIPTOR d;
+ ...
+ }
+
+ EXEC SQL CLOSE cur;
+ EXEC SQL COMMIT;
+
+ EXEC SQL DEALLOCATE DESCRIPTOR d;
+ EXEC SQL DISCONNECT ALL;
+
+ return 0;
+}
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.7.5.20.19.6"><h2>Compatibility</h2><p>
+ <code class="command">WHENEVER</code> is specified in the SQL standard, but
+ most of the actions are PostgreSQL extensions.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-sql-var.html" title="VAR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg-sql-commands.html" title="36.14. Embedded SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-informix-compat.html" title="36.15. Informix Compatibility Mode">Next</a></td></tr><tr><td width="40%" align="left" valign="top">VAR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.15. <span class="productname">Informix</span> Compatibility Mode</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg-variables.html b/doc/src/sgml/html/ecpg-variables.html
new file mode 100644
index 0000000..8f21809
--- /dev/null
+++ b/doc/src/sgml/html/ecpg-variables.html
@@ -0,0 +1,881 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>36.4. Using Host Variables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-commands.html" title="36.3. Running SQL Commands" /><link rel="next" href="ecpg-dynamic.html" title="36.5. Dynamic SQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">36.4. Using Host Variables</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-commands.html" title="36.3. Running SQL Commands">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><th width="60%" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-dynamic.html" title="36.5. Dynamic SQL">Next</a></td></tr></table><hr /></div><div class="sect1" id="ECPG-VARIABLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">36.4. Using Host Variables</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-VARIABLES-OVERVIEW">36.4.1. Overview</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-DECLARE-SECTIONS">36.4.2. Declare Sections</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-RETRIEVING">36.4.3. Retrieving Query Results</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-VARIABLES-TYPE-MAPPING">36.4.4. Type Mapping</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-VARIABLES-NONPRIMITIVE-SQL">36.4.5. Handling Nonprimitive SQL Data Types</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-INDICATORS">36.4.6. Indicators</a></span></dt></dl></div><p>
+ In <a class="xref" href="ecpg-commands.html" title="36.3. Running SQL Commands">Section 36.3</a> you saw how you can execute SQL
+ statements from an embedded SQL program. Some of those statements
+ only used fixed values and did not provide a way to insert
+ user-supplied values into statements or have the program process
+ the values returned by the query. Those kinds of statements are
+ not really useful in real applications. This section explains in
+ detail how you can pass data between your C program and the
+ embedded SQL statements using a simple mechanism called
+ <em class="firstterm">host variables</em>. In an embedded SQL program we
+ consider the SQL statements to be <em class="firstterm">guests</em> in the C
+ program code which is the <em class="firstterm">host language</em>. Therefore
+ the variables of the C program are called <em class="firstterm">host
+ variables</em>.
+ </p><p>
+ Another way to exchange values between PostgreSQL backends and ECPG
+ applications is the use of SQL descriptors, described
+ in <a class="xref" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas">Section 36.7</a>.
+ </p><div class="sect2" id="ECPG-VARIABLES-OVERVIEW"><div class="titlepage"><div><div><h3 class="title">36.4.1. Overview</h3></div></div></div><p>
+ Passing data between the C program and the SQL statements is
+ particularly simple in embedded SQL. Instead of having the
+ program paste the data into the statement, which entails various
+ complications, such as properly quoting the value, you can simply
+ write the name of a C variable into the SQL statement, prefixed by
+ a colon. For example:
+</p><pre class="programlisting">
+EXEC SQL INSERT INTO sometable VALUES (:v1, 'foo', :v2);
+</pre><p>
+ This statement refers to two C variables named
+ <code class="varname">v1</code> and <code class="varname">v2</code> and also uses a
+ regular SQL string literal, to illustrate that you are not
+ restricted to use one kind of data or the other.
+ </p><p>
+ This style of inserting C variables in SQL statements works
+ anywhere a value expression is expected in an SQL statement.
+ </p></div><div class="sect2" id="ECPG-DECLARE-SECTIONS"><div class="titlepage"><div><div><h3 class="title">36.4.2. Declare Sections</h3></div></div></div><p>
+ To pass data from the program to the database, for example as
+ parameters in a query, or to pass data from the database back to
+ the program, the C variables that are intended to contain this
+ data need to be declared in specially marked sections, so the
+ embedded SQL preprocessor is made aware of them.
+ </p><p>
+ This section starts with:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+</pre><p>
+ and ends with:
+</p><pre class="programlisting">
+EXEC SQL END DECLARE SECTION;
+</pre><p>
+ Between those lines, there must be normal C variable declarations,
+ such as:
+</p><pre class="programlisting">
+int x = 4;
+char foo[16], bar[16];
+</pre><p>
+ As you can see, you can optionally assign an initial value to the variable.
+ The variable's scope is determined by the location of its declaring
+ section within the program.
+ You can also declare variables with the following syntax which implicitly
+ creates a declare section:
+</p><pre class="programlisting">
+EXEC SQL int i = 4;
+</pre><p>
+ You can have as many declare sections in a program as you like.
+ </p><p>
+ The declarations are also echoed to the output file as normal C
+ variables, so there's no need to declare them again. Variables
+ that are not intended to be used in SQL commands can be declared
+ normally outside these special sections.
+ </p><p>
+ The definition of a structure or union also must be listed inside
+ a <code class="literal">DECLARE</code> section. Otherwise the preprocessor cannot
+ handle these types since it does not know the definition.
+ </p></div><div class="sect2" id="ECPG-RETRIEVING"><div class="titlepage"><div><div><h3 class="title">36.4.3. Retrieving Query Results</h3></div></div></div><p>
+ Now you should be able to pass data generated by your program into
+ an SQL command. But how do you retrieve the results of a query?
+ For that purpose, embedded SQL provides special variants of the
+ usual commands <code class="command">SELECT</code> and
+ <code class="command">FETCH</code>. These commands have a special
+ <code class="literal">INTO</code> clause that specifies which host variables
+ the retrieved values are to be stored in.
+ <code class="command">SELECT</code> is used for a query that returns only
+ single row, and <code class="command">FETCH</code> is used for a query that
+ returns multiple rows, using a cursor.
+ </p><p>
+ Here is an example:
+</p><pre class="programlisting">
+/*
+ * assume this table:
+ * CREATE TABLE test1 (a int, b varchar(50));
+ */
+
+EXEC SQL BEGIN DECLARE SECTION;
+int v1;
+VARCHAR v2;
+EXEC SQL END DECLARE SECTION;
+
+ ...
+
+EXEC SQL SELECT a, b INTO :v1, :v2 FROM test;
+</pre><p>
+ So the <code class="literal">INTO</code> clause appears between the select
+ list and the <code class="literal">FROM</code> clause. The number of
+ elements in the select list and the list after
+ <code class="literal">INTO</code> (also called the target list) must be
+ equal.
+ </p><p>
+ Here is an example using the command <code class="command">FETCH</code>:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int v1;
+VARCHAR v2;
+EXEC SQL END DECLARE SECTION;
+
+ ...
+
+EXEC SQL DECLARE foo CURSOR FOR SELECT a, b FROM test;
+
+ ...
+
+do
+{
+ ...
+ EXEC SQL FETCH NEXT FROM foo INTO :v1, :v2;
+ ...
+} while (...);
+</pre><p>
+ Here the <code class="literal">INTO</code> clause appears after all the
+ normal clauses.
+ </p></div><div class="sect2" id="ECPG-VARIABLES-TYPE-MAPPING"><div class="titlepage"><div><div><h3 class="title">36.4.4. Type Mapping</h3></div></div></div><p>
+ When ECPG applications exchange values between the PostgreSQL
+ server and the C application, such as when retrieving query
+ results from the server or executing SQL statements with input
+ parameters, the values need to be converted between PostgreSQL
+ data types and host language variable types (C language data
+ types, concretely). One of the main points of ECPG is that it
+ takes care of this automatically in most cases.
+ </p><p>
+ In this respect, there are two kinds of data types: Some simple
+ PostgreSQL data types, such as <code class="type">integer</code>
+ and <code class="type">text</code>, can be read and written by the application
+ directly. Other PostgreSQL data types, such
+ as <code class="type">timestamp</code> and <code class="type">numeric</code> can only be
+ accessed through special library functions; see
+ <a class="xref" href="ecpg-variables.html#ECPG-SPECIAL-TYPES" title="36.4.4.2. Accessing Special Data Types">Section 36.4.4.2</a>.
+ </p><p>
+ <a class="xref" href="ecpg-variables.html#ECPG-DATATYPE-HOSTVARS-TABLE" title="Table 36.1. Mapping Between PostgreSQL Data Types and C Variable Types">Table 36.1</a> shows which PostgreSQL
+ data types correspond to which C data types. When you wish to
+ send or receive a value of a given PostgreSQL data type, you
+ should declare a C variable of the corresponding C data type in
+ the declare section.
+ </p><div class="table" id="ECPG-DATATYPE-HOSTVARS-TABLE"><p class="title"><strong>Table 36.1. Mapping Between PostgreSQL Data Types and C Variable Types</strong></p><div class="table-contents"><table class="table" summary="Mapping Between PostgreSQL Data Types and C Variable Types" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>PostgreSQL data type</th><th>Host variable type</th></tr></thead><tbody><tr><td><code class="type">smallint</code></td><td><code class="type">short</code></td></tr><tr><td><code class="type">integer</code></td><td><code class="type">int</code></td></tr><tr><td><code class="type">bigint</code></td><td><code class="type">long long int</code></td></tr><tr><td><code class="type">decimal</code></td><td><code class="type">decimal</code><a href="#ftn.ECPG-DATATYPE-TABLE-FN" class="footnote"><sup class="footnote" id="ECPG-DATATYPE-TABLE-FN">[a]</sup></a></td></tr><tr><td><code class="type">numeric</code></td><td><code class="type">numeric</code><a href="ecpg-variables.html#ftn.ECPG-DATATYPE-TABLE-FN" class="footnoteref"><sup class="footnoteref">[a]</sup></a></td></tr><tr><td><code class="type">real</code></td><td><code class="type">float</code></td></tr><tr><td><code class="type">double precision</code></td><td><code class="type">double</code></td></tr><tr><td><code class="type">smallserial</code></td><td><code class="type">short</code></td></tr><tr><td><code class="type">serial</code></td><td><code class="type">int</code></td></tr><tr><td><code class="type">bigserial</code></td><td><code class="type">long long int</code></td></tr><tr><td><code class="type">oid</code></td><td><code class="type">unsigned int</code></td></tr><tr><td><code class="type">character(<em class="replaceable"><code>n</code></em>)</code>, <code class="type">varchar(<em class="replaceable"><code>n</code></em>)</code>, <code class="type">text</code></td><td><code class="type">char[<em class="replaceable"><code>n</code></em>+1]</code>, <code class="type">VARCHAR[<em class="replaceable"><code>n</code></em>+1]</code></td></tr><tr><td><code class="type">name</code></td><td><code class="type">char[NAMEDATALEN]</code></td></tr><tr><td><code class="type">timestamp</code></td><td><code class="type">timestamp</code><a href="ecpg-variables.html#ftn.ECPG-DATATYPE-TABLE-FN" class="footnoteref"><sup class="footnoteref">[a]</sup></a></td></tr><tr><td><code class="type">interval</code></td><td><code class="type">interval</code><a href="ecpg-variables.html#ftn.ECPG-DATATYPE-TABLE-FN" class="footnoteref"><sup class="footnoteref">[a]</sup></a></td></tr><tr><td><code class="type">date</code></td><td><code class="type">date</code><a href="ecpg-variables.html#ftn.ECPG-DATATYPE-TABLE-FN" class="footnoteref"><sup class="footnoteref">[a]</sup></a></td></tr><tr><td><code class="type">boolean</code></td><td><code class="type">bool</code><a href="#ftn.id-1.7.5.10.7.5.2.2.17.2.2" class="footnote"><sup class="footnote" id="id-1.7.5.10.7.5.2.2.17.2.2">[b]</sup></a></td></tr><tr><td><code class="type">bytea</code></td><td><code class="type">char *</code>, <code class="type">bytea[<em class="replaceable"><code>n</code></em>]</code></td></tr></tbody><tbody class="footnotes"><tr><td colspan="2"><div id="ftn.ECPG-DATATYPE-TABLE-FN" class="footnote"><p><a href="#ECPG-DATATYPE-TABLE-FN" class="para"><sup class="para">[a] </sup></a>This type can only be accessed through special library functions; see <a class="xref" href="ecpg-variables.html#ECPG-SPECIAL-TYPES" title="36.4.4.2. Accessing Special Data Types">Section 36.4.4.2</a>.</p></div><div id="ftn.id-1.7.5.10.7.5.2.2.17.2.2" class="footnote"><p><a href="#id-1.7.5.10.7.5.2.2.17.2.2" class="para"><sup class="para">[b] </sup></a>declared in <code class="filename">ecpglib.h</code> if not native</p></div></td></tr></tbody></table></div></div><br class="table-break" /><div class="sect3" id="ECPG-CHAR"><div class="titlepage"><div><div><h4 class="title">36.4.4.1. Handling Character Strings</h4></div></div></div><p>
+ To handle SQL character string data types, such
+ as <code class="type">varchar</code> and <code class="type">text</code>, there are two
+ possible ways to declare the host variables.
+ </p><p>
+ One way is using <code class="type">char[]</code>, an array
+ of <code class="type">char</code>, which is the most common way to handle
+ character data in C.
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ char str[50];
+EXEC SQL END DECLARE SECTION;
+</pre><p>
+ Note that you have to take care of the length yourself. If you
+ use this host variable as the target variable of a query which
+ returns a string with more than 49 characters, a buffer overflow
+ occurs.
+ </p><p>
+ The other way is using the <code class="type">VARCHAR</code> type, which is a
+ special type provided by ECPG. The definition on an array of
+ type <code class="type">VARCHAR</code> is converted into a
+ named <code class="type">struct</code> for every variable. A declaration like:
+</p><pre class="programlisting">
+VARCHAR var[180];
+</pre><p>
+ is converted into:
+</p><pre class="programlisting">
+struct varchar_var { int len; char arr[180]; } var;
+</pre><p>
+ The member <code class="structfield">arr</code> hosts the string
+ including a terminating zero byte. Thus, to store a string in
+ a <code class="type">VARCHAR</code> host variable, the host variable has to be
+ declared with the length including the zero byte terminator. The
+ member <code class="structfield">len</code> holds the length of the
+ string stored in the <code class="structfield">arr</code> without the
+ terminating zero byte. When a host variable is used as input for
+ a query, if <code class="literal">strlen(arr)</code>
+ and <code class="structfield">len</code> are different, the shorter one
+ is used.
+ </p><p>
+ <code class="type">VARCHAR</code> can be written in upper or lower case, but
+ not in mixed case.
+ </p><p>
+ <code class="type">char</code> and <code class="type">VARCHAR</code> host variables can
+ also hold values of other SQL types, which will be stored in
+ their string forms.
+ </p></div><div class="sect3" id="ECPG-SPECIAL-TYPES"><div class="titlepage"><div><div><h4 class="title">36.4.4.2. Accessing Special Data Types</h4></div></div></div><p>
+ ECPG contains some special types that help you to interact easily
+ with some special data types from the PostgreSQL server. In
+ particular, it has implemented support for the
+ <code class="type">numeric</code>, <code class="type">decimal</code>, <code class="type">date</code>, <code class="type">timestamp</code>,
+ and <code class="type">interval</code> types. These data types cannot usefully be
+ mapped to primitive host variable types (such
+ as <code class="type">int</code>, <code class="type">long long int</code>,
+ or <code class="type">char[]</code>), because they have a complex internal
+ structure. Applications deal with these types by declaring host
+ variables in special types and accessing them using functions in
+ the pgtypes library. The pgtypes library, described in detail
+ in <a class="xref" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Section 36.6</a> contains basic functions to deal
+ with those types, such that you do not need to send a query to
+ the SQL server just for adding an interval to a time stamp for
+ example.
+ </p><p>
+ The follow subsections describe these special data types. For
+ more details about pgtypes library functions,
+ see <a class="xref" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Section 36.6</a>.
+ </p><div class="sect4" id="id-1.7.5.10.7.7.4"><div class="titlepage"><div><div><h5 class="title">36.4.4.2.1. timestamp, date</h5></div></div></div><p>
+ Here is a pattern for handling <code class="type">timestamp</code> variables
+ in the ECPG host application.
+ </p><p>
+ First, the program has to include the header file for the
+ <code class="type">timestamp</code> type:
+</p><pre class="programlisting">
+#include &lt;pgtypes_timestamp.h&gt;
+</pre><p>
+ </p><p>
+ Next, declare a host variable as type <code class="type">timestamp</code> in
+ the declare section:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+timestamp ts;
+EXEC SQL END DECLARE SECTION;
+</pre><p>
+ </p><p>
+ And after reading a value into the host variable, process it
+ using pgtypes library functions. In following example, the
+ <code class="type">timestamp</code> value is converted into text (ASCII) form
+ with the <code class="function">PGTYPEStimestamp_to_asc()</code>
+ function:
+</p><pre class="programlisting">
+EXEC SQL SELECT now()::timestamp INTO :ts;
+
+printf("ts = %s\n", PGTYPEStimestamp_to_asc(ts));
+</pre><p>
+ This example will show some result like following:
+</p><pre class="screen">
+ts = 2010-06-27 18:03:56.949343
+</pre><p>
+ </p><p>
+ In addition, the DATE type can be handled in the same way. The
+ program has to include <code class="filename">pgtypes_date.h</code>, declare a host variable
+ as the date type and convert a DATE value into a text form using
+ <code class="function">PGTYPESdate_to_asc()</code> function. For more details about the
+ pgtypes library functions, see <a class="xref" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Section 36.6</a>.
+ </p></div><div class="sect4" id="ECPG-TYPE-INTERVAL"><div class="titlepage"><div><div><h5 class="title">36.4.4.2.2. interval</h5></div></div></div><p>
+ The handling of the <code class="type">interval</code> type is also similar
+ to the <code class="type">timestamp</code> and <code class="type">date</code> types. It
+ is required, however, to allocate memory for
+ an <code class="type">interval</code> type value explicitly. In other words,
+ the memory space for the variable has to be allocated in the
+ heap memory, not in the stack memory.
+ </p><p>
+ Here is an example program:
+</p><pre class="programlisting">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;pgtypes_interval.h&gt;
+
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ interval *in;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ in = PGTYPESinterval_new();
+ EXEC SQL SELECT '1 min'::interval INTO :in;
+ printf("interval = %s\n", PGTYPESinterval_to_asc(in));
+ PGTYPESinterval_free(in);
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</pre><p>
+ </p></div><div class="sect4" id="ECPG-TYPE-NUMERIC-DECIMAL"><div class="titlepage"><div><div><h5 class="title">36.4.4.2.3. numeric, decimal</h5></div></div></div><p>
+ The handling of the <code class="type">numeric</code>
+ and <code class="type">decimal</code> types is similar to the
+ <code class="type">interval</code> type: It requires defining a pointer,
+ allocating some memory space on the heap, and accessing the
+ variable using the pgtypes library functions. For more details
+ about the pgtypes library functions,
+ see <a class="xref" href="ecpg-pgtypes.html" title="36.6. pgtypes Library">Section 36.6</a>.
+ </p><p>
+ No functions are provided specifically for
+ the <code class="type">decimal</code> type. An application has to convert it
+ to a <code class="type">numeric</code> variable using a pgtypes library
+ function to do further processing.
+ </p><p>
+ Here is an example program handling <code class="type">numeric</code>
+ and <code class="type">decimal</code> type variables.
+</p><pre class="programlisting">
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;pgtypes_numeric.h&gt;
+
+EXEC SQL WHENEVER SQLERROR STOP;
+
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ numeric *num;
+ numeric *num2;
+ decimal *dec;
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL CONNECT TO testdb;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ num = PGTYPESnumeric_new();
+ dec = PGTYPESdecimal_new();
+
+ EXEC SQL SELECT 12.345::numeric(4,2), 23.456::decimal(4,2) INTO :num, :dec;
+
+ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 0));
+ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 1));
+ printf("numeric = %s\n", PGTYPESnumeric_to_asc(num, 2));
+
+ /* Convert decimal to numeric to show a decimal value. */
+ num2 = PGTYPESnumeric_new();
+ PGTYPESnumeric_from_decimal(dec, num2);
+
+ printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 0));
+ printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 1));
+ printf("decimal = %s\n", PGTYPESnumeric_to_asc(num2, 2));
+
+ PGTYPESnumeric_free(num2);
+ PGTYPESdecimal_free(dec);
+ PGTYPESnumeric_free(num);
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</pre><p>
+ </p></div><div class="sect4" id="id-1.7.5.10.7.7.7"><div class="titlepage"><div><div><h5 class="title">36.4.4.2.4. bytea</h5></div></div></div><p>
+ The handling of the <code class="type">bytea</code> type is similar to
+ that of <code class="type">VARCHAR</code>. The definition on an array of type
+ <code class="type">bytea</code> is converted into a named struct for every
+ variable. A declaration like:
+</p><pre class="programlisting">
+bytea var[180];
+</pre><p>
+ is converted into:
+</p><pre class="programlisting">
+struct bytea_var { int len; char arr[180]; } var;
+</pre><p>
+ The member <code class="structfield">arr</code> hosts binary format
+ data. It can also handle <code class="literal">'\0'</code> as part of
+ data, unlike <code class="type">VARCHAR</code>.
+ The data is converted from/to hex format and sent/received by
+ ecpglib.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="type">bytea</code> variable can be used only when
+ <a class="xref" href="runtime-config-client.html#GUC-BYTEA-OUTPUT">bytea_output</a> is set to <code class="literal">hex</code>.
+ </p></div></div></div><div class="sect3" id="ECPG-VARIABLES-NONPRIMITIVE-C"><div class="titlepage"><div><div><h4 class="title">36.4.4.3. Host Variables with Nonprimitive Types</h4></div></div></div><p>
+ As a host variable you can also use arrays, typedefs, structs, and
+ pointers.
+ </p><div class="sect4" id="ECPG-VARIABLES-ARRAYS"><div class="titlepage"><div><div><h5 class="title">36.4.4.3.1. Arrays</h5></div></div></div><p>
+ There are two use cases for arrays as host variables. The first
+ is a way to store some text string in <code class="type">char[]</code>
+ or <code class="type">VARCHAR[]</code>, as
+ explained in <a class="xref" href="ecpg-variables.html#ECPG-CHAR" title="36.4.4.1. Handling Character Strings">Section 36.4.4.1</a>. The second use case is to
+ retrieve multiple rows from a query result without using a
+ cursor. Without an array, to process a query result consisting
+ of multiple rows, it is required to use a cursor and
+ the <code class="command">FETCH</code> command. But with array host
+ variables, multiple rows can be received at once. The length of
+ the array has to be defined to be able to accommodate all rows,
+ otherwise a buffer overflow will likely occur.
+ </p><p>
+ Following example scans the <code class="literal">pg_database</code>
+ system table and shows all OIDs and names of the available
+ databases:
+</p><pre class="programlisting">
+int
+main(void)
+{
+EXEC SQL BEGIN DECLARE SECTION;
+ int dbid[8];
+ char dbname[8][16];
+ int i;
+EXEC SQL END DECLARE SECTION;
+
+ memset(dbname, 0, sizeof(char)* 16 * 8);
+ memset(dbid, 0, sizeof(int) * 8);
+
+ EXEC SQL CONNECT TO testdb;
+ EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
+
+ /* Retrieve multiple rows into arrays at once. */
+ EXEC SQL SELECT oid,datname INTO :dbid, :dbname FROM pg_database;
+
+ for (i = 0; i &lt; 8; i++)
+ printf("oid=%d, dbname=%s\n", dbid[i], dbname[i]);
+
+ EXEC SQL COMMIT;
+ EXEC SQL DISCONNECT ALL;
+ return 0;
+}
+</pre><p>
+
+ This example shows following result. (The exact values depend on
+ local circumstances.)
+</p><pre class="screen">
+oid=1, dbname=template1
+oid=11510, dbname=template0
+oid=11511, dbname=postgres
+oid=313780, dbname=testdb
+oid=0, dbname=
+oid=0, dbname=
+oid=0, dbname=
+</pre><p>
+ </p></div><div class="sect4" id="ECPG-VARIABLES-STRUCT"><div class="titlepage"><div><div><h5 class="title">36.4.4.3.2. Structures</h5></div></div></div><p>
+ A structure whose member names match the column names of a query
+ result, can be used to retrieve multiple columns at once. The
+ structure enables handling multiple column values in a single
+ host variable.
+ </p><p>
+ The following example retrieves OIDs, names, and sizes of the
+ available databases from the <code class="literal">pg_database</code>
+ system table and using
+ the <code class="function">pg_database_size()</code> function. In this
+ example, a structure variable <code class="varname">dbinfo_t</code> with
+ members whose names match each column in
+ the <code class="literal">SELECT</code> result is used to retrieve one
+ result row without putting multiple host variables in
+ the <code class="literal">FETCH</code> statement.
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ typedef struct
+ {
+ int oid;
+ char datname[65];
+ long long int size;
+ } dbinfo_t;
+
+ dbinfo_t dbval;
+EXEC SQL END DECLARE SECTION;
+
+ memset(&amp;dbval, 0, sizeof(dbinfo_t));
+
+ EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size FROM pg_database;
+ EXEC SQL OPEN cur1;
+
+ /* when end of result set reached, break out of while loop */
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ /* Fetch multiple columns into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :dbval;
+
+ /* Print members of the structure. */
+ printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, dbval.size);
+ }
+
+ EXEC SQL CLOSE cur1;
+</pre><p>
+ </p><p>
+ This example shows following result. (The exact values depend on
+ local circumstances.)
+</p><pre class="screen">
+oid=1, datname=template1, size=4324580
+oid=11510, datname=template0, size=4243460
+oid=11511, datname=postgres, size=4324580
+oid=313780, datname=testdb, size=8183012
+</pre><p>
+ </p><p>
+ Structure host variables <span class="quote">“<span class="quote">absorb</span>”</span> as many columns
+ as the structure as fields. Additional columns can be assigned
+ to other host variables. For example, the above program could
+ also be restructured like this, with the <code class="varname">size</code>
+ variable outside the structure:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ typedef struct
+ {
+ int oid;
+ char datname[65];
+ } dbinfo_t;
+
+ dbinfo_t dbval;
+ long long int size;
+EXEC SQL END DECLARE SECTION;
+
+ memset(&amp;dbval, 0, sizeof(dbinfo_t));
+
+ EXEC SQL DECLARE cur1 CURSOR FOR SELECT oid, datname, pg_database_size(oid) AS size FROM pg_database;
+ EXEC SQL OPEN cur1;
+
+ /* when end of result set reached, break out of while loop */
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ /* Fetch multiple columns into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :dbval, :size;
+
+ /* Print members of the structure. */
+ printf("oid=%d, datname=%s, size=%lld\n", dbval.oid, dbval.datname, size);
+ }
+
+ EXEC SQL CLOSE cur1;
+</pre><p>
+ </p></div><div class="sect4" id="id-1.7.5.10.7.8.5"><div class="titlepage"><div><div><h5 class="title">36.4.4.3.3. Typedefs</h5></div></div></div><p>
+ Use the <code class="literal">typedef</code> keyword to map new types to already
+ existing types.
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ typedef char mychartype[40];
+ typedef long serial_t;
+EXEC SQL END DECLARE SECTION;
+</pre><p>
+ Note that you could also use:
+</p><pre class="programlisting">
+EXEC SQL TYPE serial_t IS long;
+</pre><p>
+ This declaration does not need to be part of a declare section.
+ </p></div><div class="sect4" id="id-1.7.5.10.7.8.6"><div class="titlepage"><div><div><h5 class="title">36.4.4.3.4. Pointers</h5></div></div></div><p>
+ You can declare pointers to the most common types. Note however
+ that you cannot use pointers as target variables of queries
+ without auto-allocation. See <a class="xref" href="ecpg-descriptors.html" title="36.7. Using Descriptor Areas">Section 36.7</a>
+ for more information on auto-allocation.
+ </p><p>
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ int *intp;
+ char **charp;
+EXEC SQL END DECLARE SECTION;
+</pre><p>
+ </p></div></div></div><div class="sect2" id="ECPG-VARIABLES-NONPRIMITIVE-SQL"><div class="titlepage"><div><div><h3 class="title">36.4.5. Handling Nonprimitive SQL Data Types</h3></div></div></div><p>
+ This section contains information on how to handle nonscalar and
+ user-defined SQL-level data types in ECPG applications. Note that
+ this is distinct from the handling of host variables of
+ nonprimitive types, described in the previous section.
+ </p><div class="sect3" id="id-1.7.5.10.8.3"><div class="titlepage"><div><div><h4 class="title">36.4.5.1. Arrays</h4></div></div></div><p>
+ Multi-dimensional SQL-level arrays are not directly supported in ECPG.
+ One-dimensional SQL-level arrays can be mapped into C array host
+ variables and vice-versa. However, when creating a statement ecpg does
+ not know the types of the columns, so that it cannot check if a C array
+ is input into a corresponding SQL-level array. When processing the
+ output of an SQL statement, ecpg has the necessary information and thus
+ checks if both are arrays.
+ </p><p>
+ If a query accesses <span class="emphasis"><em>elements</em></span> of an array
+ separately, then this avoids the use of arrays in ECPG. Then, a
+ host variable with a type that can be mapped to the element type
+ should be used. For example, if a column type is array of
+ <code class="type">integer</code>, a host variable of type <code class="type">int</code>
+ can be used. Also if the element type is <code class="type">varchar</code>
+ or <code class="type">text</code>, a host variable of type <code class="type">char[]</code>
+ or <code class="type">VARCHAR[]</code> can be used.
+ </p><p>
+ Here is an example. Assume the following table:
+</p><pre class="programlisting">
+CREATE TABLE t3 (
+ ii integer[]
+);
+
+testdb=&gt; SELECT * FROM t3;
+ ii
+-------------
+ {1,2,3,4,5}
+(1 row)
+</pre><p>
+
+ The following example program retrieves the 4th element of the
+ array and stores it into a host variable of
+ type <code class="type">int</code>:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int ii;
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[4] FROM t3;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ EXEC SQL FETCH FROM cur1 INTO :ii ;
+ printf("ii=%d\n", ii);
+}
+
+EXEC SQL CLOSE cur1;
+</pre><p>
+
+ This example shows the following result:
+</p><pre class="screen">
+ii=4
+</pre><p>
+ </p><p>
+ To map multiple array elements to the multiple elements in an
+ array type host variables each element of array column and each
+ element of the host variable array have to be managed separately,
+ for example:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int ii_a[8];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii[1], ii[2], ii[3], ii[4] FROM t3;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ EXEC SQL FETCH FROM cur1 INTO :ii_a[0], :ii_a[1], :ii_a[2], :ii_a[3];
+ ...
+}
+</pre><p>
+ </p><p>
+ Note again that
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int ii_a[8];
+EXEC SQL END DECLARE SECTION;
+
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT ii FROM t3;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* WRONG */
+ EXEC SQL FETCH FROM cur1 INTO :ii_a;
+ ...
+}
+</pre><p>
+ would not work correctly in this case, because you cannot map an
+ array type column to an array host variable directly.
+ </p><p>
+ Another workaround is to store arrays in their external string
+ representation in host variables of type <code class="type">char[]</code>
+ or <code class="type">VARCHAR[]</code>. For more details about this
+ representation, see <a class="xref" href="arrays.html#ARRAYS-INPUT" title="8.15.2. Array Value Input">Section 8.15.2</a>. Note that
+ this means that the array cannot be accessed naturally as an
+ array in the host program (without further processing that parses
+ the text representation).
+ </p></div><div class="sect3" id="id-1.7.5.10.8.4"><div class="titlepage"><div><div><h4 class="title">36.4.5.2. Composite Types</h4></div></div></div><p>
+ Composite types are not directly supported in ECPG, but an easy workaround is possible.
+ The
+ available workarounds are similar to the ones described for
+ arrays above: Either access each attribute separately or use the
+ external string representation.
+ </p><p>
+ For the following examples, assume the following type and table:
+</p><pre class="programlisting">
+CREATE TYPE comp_t AS (intval integer, textval varchar(32));
+CREATE TABLE t4 (compval comp_t);
+INSERT INTO t4 VALUES ( (256, 'PostgreSQL') );
+</pre><p>
+
+ The most obvious solution is to access each attribute separately.
+ The following program retrieves data from the example table by
+ selecting each attribute of the type <code class="type">comp_t</code>
+ separately:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+int intval;
+varchar textval[33];
+EXEC SQL END DECLARE SECTION;
+
+/* Put each element of the composite type column in the SELECT list. */
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* Fetch each element of the composite type column into host variables. */
+ EXEC SQL FETCH FROM cur1 INTO :intval, :textval;
+
+ printf("intval=%d, textval=%s\n", intval, textval.arr);
+}
+
+EXEC SQL CLOSE cur1;
+</pre><p>
+ </p><p>
+ To enhance this example, the host variables to store values in
+ the <code class="command">FETCH</code> command can be gathered into one
+ structure. For more details about the host variable in the
+ structure form, see <a class="xref" href="ecpg-variables.html#ECPG-VARIABLES-STRUCT" title="36.4.4.3.2. Structures">Section 36.4.4.3.2</a>.
+ To switch to the structure, the example can be modified as below.
+ The two host variables, <code class="varname">intval</code>
+ and <code class="varname">textval</code>, become members of
+ the <code class="structname">comp_t</code> structure, and the structure
+ is specified on the <code class="command">FETCH</code> command.
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+typedef struct
+{
+ int intval;
+ varchar textval[33];
+} comp_t;
+
+comp_t compval;
+EXEC SQL END DECLARE SECTION;
+
+/* Put each element of the composite type column in the SELECT list. */
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).intval, (compval).textval FROM t4;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* Put all values in the SELECT list into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :compval;
+
+ printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
+}
+
+EXEC SQL CLOSE cur1;
+</pre><p>
+
+ Although a structure is used in the <code class="command">FETCH</code>
+ command, the attribute names in the <code class="command">SELECT</code>
+ clause are specified one by one. This can be enhanced by using
+ a <code class="literal">*</code> to ask for all attributes of the composite
+ type value.
+</p><pre class="programlisting">
+...
+EXEC SQL DECLARE cur1 CURSOR FOR SELECT (compval).* FROM t4;
+EXEC SQL OPEN cur1;
+
+EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+while (1)
+{
+ /* Put all values in the SELECT list into one structure. */
+ EXEC SQL FETCH FROM cur1 INTO :compval;
+
+ printf("intval=%d, textval=%s\n", compval.intval, compval.textval.arr);
+}
+...
+</pre><p>
+ This way, composite types can be mapped into structures almost
+ seamlessly, even though ECPG does not understand the composite
+ type itself.
+ </p><p>
+ Finally, it is also possible to store composite type values in
+ their external string representation in host variables of
+ type <code class="type">char[]</code> or <code class="type">VARCHAR[]</code>. But that
+ way, it is not easily possible to access the fields of the value
+ from the host program.
+ </p></div><div class="sect3" id="id-1.7.5.10.8.5"><div class="titlepage"><div><div><h4 class="title">36.4.5.3. User-Defined Base Types</h4></div></div></div><p>
+ New user-defined base types are not directly supported by ECPG.
+ You can use the external string representation and host variables
+ of type <code class="type">char[]</code> or <code class="type">VARCHAR[]</code>, and this
+ solution is indeed appropriate and sufficient for many types.
+ </p><p>
+ Here is an example using the data type <code class="type">complex</code> from
+ the example in <a class="xref" href="xtypes.html" title="38.13. User-Defined Types">Section 38.13</a>. The external string
+ representation of that type is <code class="literal">(%f,%f)</code>,
+ which is defined in the
+ functions <code class="function">complex_in()</code>
+ and <code class="function">complex_out()</code> functions
+ in <a class="xref" href="xtypes.html" title="38.13. User-Defined Types">Section 38.13</a>. The following example inserts the
+ complex type values <code class="literal">(1,1)</code>
+ and <code class="literal">(3,3)</code> into the
+ columns <code class="literal">a</code> and <code class="literal">b</code>, and select
+ them from the table after that.
+
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+ varchar a[64];
+ varchar b[64];
+EXEC SQL END DECLARE SECTION;
+
+ EXEC SQL INSERT INTO test_complex VALUES ('(1,1)', '(3,3)');
+
+ EXEC SQL DECLARE cur1 CURSOR FOR SELECT a, b FROM test_complex;
+ EXEC SQL OPEN cur1;
+
+ EXEC SQL WHENEVER NOT FOUND DO BREAK;
+
+ while (1)
+ {
+ EXEC SQL FETCH FROM cur1 INTO :a, :b;
+ printf("a=%s, b=%s\n", a.arr, b.arr);
+ }
+
+ EXEC SQL CLOSE cur1;
+</pre><p>
+
+ This example shows following result:
+</p><pre class="screen">
+a=(1,1), b=(3,3)
+</pre><p>
+ </p><p>
+ Another workaround is avoiding the direct use of the user-defined
+ types in ECPG and instead create a function or cast that converts
+ between the user-defined type and a primitive type that ECPG can
+ handle. Note, however, that type casts, especially implicit
+ ones, should be introduced into the type system very carefully.
+ </p><p>
+ For example,
+</p><pre class="programlisting">
+CREATE FUNCTION create_complex(r double, i double) RETURNS complex
+LANGUAGE SQL
+IMMUTABLE
+AS $$ SELECT $1 * complex '(1,0')' + $2 * complex '(0,1)' $$;
+</pre><p>
+ After this definition, the following
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+double a, b, c, d;
+EXEC SQL END DECLARE SECTION;
+
+a = 1;
+b = 2;
+c = 3;
+d = 4;
+
+EXEC SQL INSERT INTO test_complex VALUES (create_complex(:a, :b), create_complex(:c, :d));
+</pre><p>
+ has the same effect as
+</p><pre class="programlisting">
+EXEC SQL INSERT INTO test_complex VALUES ('(1,2)', '(3,4)');
+</pre><p>
+ </p></div></div><div class="sect2" id="ECPG-INDICATORS"><div class="titlepage"><div><div><h3 class="title">36.4.6. Indicators</h3></div></div></div><p>
+ The examples above do not handle null values. In fact, the
+ retrieval examples will raise an error if they fetch a null value
+ from the database. To be able to pass null values to the database
+ or retrieve null values from the database, you need to append a
+ second host variable specification to each host variable that
+ contains data. This second host variable is called the
+ <em class="firstterm">indicator</em> and contains a flag that tells
+ whether the datum is null, in which case the value of the real
+ host variable is ignored. Here is an example that handles the
+ retrieval of null values correctly:
+</p><pre class="programlisting">
+EXEC SQL BEGIN DECLARE SECTION;
+VARCHAR val;
+int val_ind;
+EXEC SQL END DECLARE SECTION:
+
+ ...
+
+EXEC SQL SELECT b INTO :val :val_ind FROM test1;
+</pre><p>
+ The indicator variable <code class="varname">val_ind</code> will be zero if
+ the value was not null, and it will be negative if the value was
+ null. (See <a class="xref" href="ecpg-oracle-compat.html" title="36.16. Oracle Compatibility Mode">Section 36.16</a> to enable
+ Oracle-specific behavior.)
+ </p><p>
+ The indicator has another function: if the indicator value is
+ positive, it means that the value is not null, but it was
+ truncated when it was stored in the host variable.
+ </p><p>
+ If the argument <code class="literal">-r no_indicator</code> is passed to
+ the preprocessor <code class="command">ecpg</code>, it works in
+ <span class="quote">“<span class="quote">no-indicator</span>”</span> mode. In no-indicator mode, if no
+ indicator variable is specified, null values are signaled (on
+ input and output) for character string types as empty string and
+ for integer types as the lowest possible value for type (for
+ example, <code class="symbol">INT_MIN</code> for <code class="type">int</code>).
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-commands.html" title="36.3. Running SQL Commands">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-dynamic.html" title="36.5. Dynamic SQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.3. Running SQL Commands </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.5. Dynamic SQL</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ecpg.html b/doc/src/sgml/html/ecpg.html
new file mode 100644
index 0000000..0606fa9
--- /dev/null
+++ b/doc/src/sgml/html/ecpg.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 36. ECPG — Embedded SQL in C</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="lo-examplesect.html" title="35.5. Example Program" /><link rel="next" href="ecpg-concept.html" title="36.1. The Concept" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="lo-examplesect.html" title="35.5. Example Program">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><th width="60%" align="center">Part IV. Client Interfaces</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg-concept.html" title="36.1. The Concept">Next</a></td></tr></table><hr /></div><div class="chapter" id="ECPG"><div class="titlepage"><div><div><h2 class="title">Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="ecpg-concept.html">36.1. The Concept</a></span></dt><dt><span class="sect1"><a href="ecpg-connect.html">36.2. Managing Database Connections</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-connect.html#ECPG-CONNECTING">36.2.1. Connecting to the Database Server</a></span></dt><dt><span class="sect2"><a href="ecpg-connect.html#ECPG-SET-CONNECTION">36.2.2. Choosing a Connection</a></span></dt><dt><span class="sect2"><a href="ecpg-connect.html#ECPG-DISCONNECT">36.2.3. Closing a Connection</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-commands.html">36.3. Running SQL Commands</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-EXECUTING">36.3.1. Executing SQL Statements</a></span></dt><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-CURSORS">36.3.2. Using Cursors</a></span></dt><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-TRANSACTIONS">36.3.3. Managing Transactions</a></span></dt><dt><span class="sect2"><a href="ecpg-commands.html#ECPG-PREPARED">36.3.4. Prepared Statements</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-variables.html">36.4. Using Host Variables</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-VARIABLES-OVERVIEW">36.4.1. Overview</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-DECLARE-SECTIONS">36.4.2. Declare Sections</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-RETRIEVING">36.4.3. Retrieving Query Results</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-VARIABLES-TYPE-MAPPING">36.4.4. Type Mapping</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-VARIABLES-NONPRIMITIVE-SQL">36.4.5. Handling Nonprimitive SQL Data Types</a></span></dt><dt><span class="sect2"><a href="ecpg-variables.html#ECPG-INDICATORS">36.4.6. Indicators</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-dynamic.html">36.5. Dynamic SQL</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-dynamic.html#ECPG-DYNAMIC-WITHOUT-RESULT">36.5.1. Executing Statements without a Result Set</a></span></dt><dt><span class="sect2"><a href="ecpg-dynamic.html#ECPG-DYNAMIC-INPUT">36.5.2. Executing a Statement with Input Parameters</a></span></dt><dt><span class="sect2"><a href="ecpg-dynamic.html#ECPG-DYNAMIC-WITH-RESULT">36.5.3. Executing a Statement with a Result Set</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-pgtypes.html">36.6. pgtypes Library</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-CSTRINGS">36.6.1. Character Strings</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-NUMERIC">36.6.2. The numeric Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-DATE">36.6.3. The date Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-TIMESTAMP">36.6.4. The timestamp Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-INTERVAL">36.6.5. The interval Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-DECIMAL">36.6.6. The decimal Type</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-ERRNO">36.6.7. errno Values of pgtypeslib</a></span></dt><dt><span class="sect2"><a href="ecpg-pgtypes.html#ECPG-PGTYPES-CONSTANTS">36.6.8. Special Constants of pgtypeslib</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-descriptors.html">36.7. Using Descriptor Areas</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-descriptors.html#ECPG-NAMED-DESCRIPTORS">36.7.1. Named SQL Descriptor Areas</a></span></dt><dt><span class="sect2"><a href="ecpg-descriptors.html#ECPG-SQLDA-DESCRIPTORS">36.7.2. SQLDA Descriptor Areas</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-errors.html">36.8. Error Handling</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-errors.html#ECPG-WHENEVER">36.8.1. Setting Callbacks</a></span></dt><dt><span class="sect2"><a href="ecpg-errors.html#ECPG-SQLCA">36.8.2. sqlca</a></span></dt><dt><span class="sect2"><a href="ecpg-errors.html#ECPG-SQLSTATE-SQLCODE">36.8.3. <code class="literal">SQLSTATE</code> vs. <code class="literal">SQLCODE</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-preproc.html">36.9. Preprocessor Directives</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-preproc.html#ECPG-INCLUDE">36.9.1. Including Files</a></span></dt><dt><span class="sect2"><a href="ecpg-preproc.html#ECPG-DEFINE">36.9.2. The define and undef Directives</a></span></dt><dt><span class="sect2"><a href="ecpg-preproc.html#ECPG-IFDEF">36.9.3. ifdef, ifndef, elif, else, and endif Directives</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-process.html">36.10. Processing Embedded SQL Programs</a></span></dt><dt><span class="sect1"><a href="ecpg-library.html">36.11. Library Functions</a></span></dt><dt><span class="sect1"><a href="ecpg-lo.html">36.12. Large Objects</a></span></dt><dt><span class="sect1"><a href="ecpg-cpp.html">36.13. <acronym class="acronym">C++</acronym> Applications</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-cpp.html#ECPG-CPP-SCOPE">36.13.1. Scope for Host Variables</a></span></dt><dt><span class="sect2"><a href="ecpg-cpp.html#ECPG-CPP-AND-C">36.13.2. C++ Application Development with External C Module</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-sql-commands.html">36.14. Embedded SQL Commands</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="ecpg-sql-allocate-descriptor.html">ALLOCATE DESCRIPTOR</a></span><span class="refpurpose"> — allocate an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-connect.html">CONNECT</a></span><span class="refpurpose"> — establish a database connection</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-deallocate-descriptor.html">DEALLOCATE DESCRIPTOR</a></span><span class="refpurpose"> — deallocate an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-declare.html">DECLARE</a></span><span class="refpurpose"> — define a cursor</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-declare-statement.html">DECLARE STATEMENT</a></span><span class="refpurpose"> — declare SQL statement identifier</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-describe.html">DESCRIBE</a></span><span class="refpurpose"> — obtain information about a prepared statement or result set</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-disconnect.html">DISCONNECT</a></span><span class="refpurpose"> — terminate a database connection</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-execute-immediate.html">EXECUTE IMMEDIATE</a></span><span class="refpurpose"> — dynamically prepare and execute a statement</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-get-descriptor.html">GET DESCRIPTOR</a></span><span class="refpurpose"> — get information from an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-open.html">OPEN</a></span><span class="refpurpose"> — open a dynamic cursor</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-prepare.html">PREPARE</a></span><span class="refpurpose"> — prepare a statement for execution</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-set-autocommit.html">SET AUTOCOMMIT</a></span><span class="refpurpose"> — set the autocommit behavior of the current session</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-set-connection.html">SET CONNECTION</a></span><span class="refpurpose"> — select a database connection</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-set-descriptor.html">SET DESCRIPTOR</a></span><span class="refpurpose"> — set information in an SQL descriptor area</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-type.html">TYPE</a></span><span class="refpurpose"> — define a new data type</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-var.html">VAR</a></span><span class="refpurpose"> — define a variable</span></dt><dt><span class="refentrytitle"><a href="ecpg-sql-whenever.html">WHENEVER</a></span><span class="refpurpose"> — specify the action to be taken when an SQL statement causes a specific class condition to be raised</span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-informix-compat.html">36.15. <span class="productname">Informix</span> Compatibility Mode</a></span></dt><dd><dl><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-TYPES">36.15.1. Additional Types</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-STATEMENTS">36.15.2. Additional/Missing Embedded SQL Statements</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-SQLDA">36.15.3. Informix-compatible SQLDA Descriptor Areas</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-FUNCTIONS">36.15.4. Additional Functions</a></span></dt><dt><span class="sect2"><a href="ecpg-informix-compat.html#ECPG-INFORMIX-CONSTANTS">36.15.5. Additional Constants</a></span></dt></dl></dd><dt><span class="sect1"><a href="ecpg-oracle-compat.html">36.16. <span class="productname">Oracle</span> Compatibility Mode</a></span></dt><dt><span class="sect1"><a href="ecpg-develop.html">36.17. Internals</a></span></dt></dl></div><a id="id-1.7.5.2" class="indexterm"></a><a id="id-1.7.5.3" class="indexterm"></a><a id="id-1.7.5.4" class="indexterm"></a><p>
+ This chapter describes the embedded <acronym class="acronym">SQL</acronym> package
+ for <span class="productname">PostgreSQL</span>. It was written by
+ Linus Tolke (<code class="email">&lt;<a class="email" href="mailto:linus@epact.se">linus@epact.se</a>&gt;</code>) and Michael Meskes
+ (<code class="email">&lt;<a class="email" href="mailto:meskes@postgresql.org">meskes@postgresql.org</a>&gt;</code>). Originally it was written to work with
+ <acronym class="acronym">C</acronym>. It also works with <acronym class="acronym">C++</acronym>, but
+ it does not recognize all <acronym class="acronym">C++</acronym> constructs yet.
+ </p><p>
+ This documentation is quite incomplete. But since this
+ interface is standardized, additional information can be found in
+ many resources about SQL.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lo-examplesect.html" title="35.5. Example Program">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg-concept.html" title="36.1. The Concept">Next</a></td></tr><tr><td width="40%" align="left" valign="top">35.5. Example Program </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 36.1. The Concept</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/encryption-options.html b/doc/src/sgml/html/encryption-options.html
new file mode 100644
index 0000000..6344810
--- /dev/null
+++ b/doc/src/sgml/html/encryption-options.html
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.8. Encryption Options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="preventing-server-spoofing.html" title="19.7. Preventing Server Spoofing" /><link rel="next" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.8. Encryption Options</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="preventing-server-spoofing.html" title="19.7. Preventing Server Spoofing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Next</a></td></tr></table><hr /></div><div class="sect1" id="ENCRYPTION-OPTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.8. Encryption Options</h2></div></div></div><a id="id-1.6.6.11.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> offers encryption at several
+ levels, and provides flexibility in protecting data from disclosure
+ due to database server theft, unscrupulous administrators, and
+ insecure networks. Encryption might also be required to secure
+ sensitive data such as medical records or financial transactions.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Password Encryption</span></dt><dd><p>
+ Database user passwords are stored as hashes (determined by the setting
+ <a class="xref" href="runtime-config-connection.html#GUC-PASSWORD-ENCRYPTION">password_encryption</a>), so the administrator cannot
+ determine the actual password assigned to the user. If SCRAM or MD5
+ encryption is used for client authentication, the unencrypted password is
+ never even temporarily present on the server because the client encrypts
+ it before being sent across the network. SCRAM is preferred, because it
+ is an Internet standard and is more secure than the PostgreSQL-specific
+ MD5 authentication protocol.
+ </p></dd><dt><span class="term">Encryption For Specific Columns</span></dt><dd><p>
+ The <a class="xref" href="pgcrypto.html" title="F.28. pgcrypto">pgcrypto</a> module allows certain fields to be
+ stored encrypted.
+ This is useful if only some of the data is sensitive.
+ The client supplies the decryption key and the data is decrypted
+ on the server and then sent to the client.
+ </p><p>
+ The decrypted data and the decryption key are present on the
+ server for a brief time while it is being decrypted and
+ communicated between the client and server. This presents a brief
+ moment where the data and keys can be intercepted by someone with
+ complete access to the database server, such as the system
+ administrator.
+ </p></dd><dt><span class="term">Data Partition Encryption</span></dt><dd><p>
+ Storage encryption can be performed at the file system level or the
+ block level. Linux file system encryption options include eCryptfs
+ and EncFS, while FreeBSD uses PEFS. Block level or full disk
+ encryption options include dm-crypt + LUKS on Linux and GEOM
+ modules geli and gbde on FreeBSD. Many other operating systems
+ support this functionality, including Windows.
+ </p><p>
+ This mechanism prevents unencrypted data from being read from the
+ drives if the drives or the entire computer is stolen. This does
+ not protect against attacks while the file system is mounted,
+ because when mounted, the operating system provides an unencrypted
+ view of the data. However, to mount the file system, you need some
+ way for the encryption key to be passed to the operating system,
+ and sometimes the key is stored somewhere on the host that mounts
+ the disk.
+ </p></dd><dt><span class="term">Encrypting Data Across A Network</span></dt><dd><p>
+ SSL connections encrypt all data sent across the network: the
+ password, the queries, and the data returned. The
+ <code class="filename">pg_hba.conf</code> file allows administrators to specify
+ which hosts can use non-encrypted connections (<code class="literal">host</code>)
+ and which require SSL-encrypted connections
+ (<code class="literal">hostssl</code>). Also, clients can specify that they
+ connect to servers only via SSL.
+ </p><p>
+ GSSAPI-encrypted connections encrypt all data sent across the network,
+ including queries and data returned. (No password is sent across the
+ network.) The <code class="filename">pg_hba.conf</code> file allows
+ administrators to specify which hosts can use non-encrypted connections
+ (<code class="literal">host</code>) and which require GSSAPI-encrypted connections
+ (<code class="literal">hostgssenc</code>). Also, clients can specify that they
+ connect to servers only on GSSAPI-encrypted connections
+ (<code class="literal">gssencmode=require</code>).
+ </p><p>
+ <span class="application">Stunnel</span> or
+ <span class="application">SSH</span> can also be used to encrypt
+ transmissions.
+ </p></dd><dt><span class="term">SSL Host Authentication</span></dt><dd><p>
+ It is possible for both the client and server to provide SSL
+ certificates to each other. It takes some extra configuration
+ on each side, but this provides stronger verification of identity
+ than the mere use of passwords. It prevents a computer from
+ pretending to be the server just long enough to read the password
+ sent by the client. It also helps prevent <span class="quote">“<span class="quote">man in the middle</span>”</span>
+ attacks where a computer between the client and server pretends to
+ be the server and reads and passes all data between the client and
+ server.
+ </p></dd><dt><span class="term">Client-Side Encryption</span></dt><dd><p>
+ If the system administrator for the server's machine cannot be trusted,
+ it is necessary
+ for the client to encrypt the data; this way, unencrypted data
+ never appears on the database server. Data is encrypted on the
+ client before being sent to the server, and database results have
+ to be decrypted on the client before being used.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="preventing-server-spoofing.html" title="19.7. Preventing Server Spoofing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.7. Preventing Server Spoofing </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.9. Secure TCP/IP Connections with SSL</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/errcodes-appendix.html b/doc/src/sgml/html/errcodes-appendix.html
new file mode 100644
index 0000000..6f7a168
--- /dev/null
+++ b/doc/src/sgml/html/errcodes-appendix.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix A. PostgreSQL Error Codes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="appendixes.html" title="Part VIII. Appendixes" /><link rel="next" href="datetime-appendix.html" title="Appendix B. Date/Time Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix A. <span class="productname">PostgreSQL</span> Error Codes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="appendixes.html" title="Part VIII. Appendixes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Next</a></td></tr></table><hr /></div><div class="appendix" id="ERRCODES-APPENDIX"><div class="titlepage"><div><div><h2 class="title">Appendix A. <span class="productname">PostgreSQL</span> Error Codes</h2></div></div></div><a id="id-1.11.2.2" class="indexterm"></a><p>
+ All messages emitted by the <span class="productname">PostgreSQL</span>
+ server are assigned five-character error codes that follow the SQL
+ standard's conventions for <span class="quote">“<span class="quote">SQLSTATE</span>”</span> codes. Applications
+ that need to know which error condition has occurred should usually
+ test the error code, rather than looking at the textual error
+ message. The error codes are less likely to change across
+ <span class="productname">PostgreSQL</span> releases, and also are not subject to
+ change due to localization of error messages. Note that some, but
+ not all, of the error codes produced by <span class="productname">PostgreSQL</span>
+ are defined by the SQL standard; some additional error codes for
+ conditions not defined by the standard have been invented or
+ borrowed from other databases.
+ </p><p>
+ According to the standard, the first two characters of an error code
+ denote a class of errors, while the last three characters indicate
+ a specific condition within that class. Thus, an application that
+ does not recognize the specific error code might still be able to infer
+ what to do from the error class.
+ </p><p>
+ <a class="xref" href="errcodes-appendix.html#ERRCODES-TABLE" title="Table A.1. PostgreSQL Error Codes">Table A.1</a> lists all the error codes defined in
+ <span class="productname">PostgreSQL</span> 15.4. (Some are not actually
+ used at present, but are defined by the SQL standard.)
+ The error classes are also shown. For each error class there is a
+ <span class="quote">“<span class="quote">standard</span>”</span> error code having the last three characters
+ <code class="literal">000</code>. This code is used only for error conditions that fall
+ within the class but do not have any more-specific code assigned.
+ </p><p>
+ The symbol shown in the column <span class="quote">“<span class="quote">Condition Name</span>”</span> is
+ the condition name to use in <span class="application">PL/pgSQL</span>. Condition
+ names can be written in either upper or lower case. (Note that
+ <span class="application">PL/pgSQL</span> does not recognize warning, as opposed to error,
+ condition names; those are classes 00, 01, and 02.)
+ </p><p>
+ For some types of errors, the server reports the name of a database object
+ (a table, table column, data type, or constraint) associated with the error;
+ for example, the name of the unique constraint that caused a
+ <code class="symbol">unique_violation</code> error. Such names are supplied in separate
+ fields of the error report message so that applications need not try to
+ extract them from the possibly-localized human-readable text of the message.
+ As of <span class="productname">PostgreSQL</span> 9.3, complete coverage for this feature
+ exists only for errors in SQLSTATE class 23 (integrity constraint
+ violation), but this is likely to be expanded in future.
+ </p><div class="table" id="ERRCODES-TABLE"><p class="title"><strong>Table A.1. <span class="productname">PostgreSQL</span> Error Codes</strong></p><div class="table-contents"><table class="table" summary="PostgreSQL Error Codes" border="1"><colgroup><col class="errorcode" /><col class="condname" /></colgroup><thead><tr><th>Error Code</th><th>Condition Name</th></tr></thead><tbody><tr><td colspan="2"><span class="bold"><strong>Class 00 — Successful Completion</strong></span></td></tr><tr><td><code class="literal">00000</code></td><td><code class="symbol">successful_completion</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 01 — Warning</strong></span></td></tr><tr><td><code class="literal">01000</code></td><td><code class="symbol">warning</code></td></tr><tr><td><code class="literal">0100C</code></td><td><code class="symbol">dynamic_result_sets_returned</code></td></tr><tr><td><code class="literal">01008</code></td><td><code class="symbol">implicit_zero_bit_padding</code></td></tr><tr><td><code class="literal">01003</code></td><td><code class="symbol">null_value_eliminated_in_set_function</code></td></tr><tr><td><code class="literal">01007</code></td><td><code class="symbol">privilege_not_granted</code></td></tr><tr><td><code class="literal">01006</code></td><td><code class="symbol">privilege_not_revoked</code></td></tr><tr><td><code class="literal">01004</code></td><td><code class="symbol">string_data_right_truncation</code></td></tr><tr><td><code class="literal">01P01</code></td><td><code class="symbol">deprecated_feature</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 02 — No Data (this is also a warning class per the SQL standard)</strong></span></td></tr><tr><td><code class="literal">02000</code></td><td><code class="symbol">no_data</code></td></tr><tr><td><code class="literal">02001</code></td><td><code class="symbol">no_additional_dynamic_result_sets_returned</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 03 — SQL Statement Not Yet Complete</strong></span></td></tr><tr><td><code class="literal">03000</code></td><td><code class="symbol">sql_statement_not_yet_complete</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 08 — Connection Exception</strong></span></td></tr><tr><td><code class="literal">08000</code></td><td><code class="symbol">connection_exception</code></td></tr><tr><td><code class="literal">08003</code></td><td><code class="symbol">connection_does_not_exist</code></td></tr><tr><td><code class="literal">08006</code></td><td><code class="symbol">connection_failure</code></td></tr><tr><td><code class="literal">08001</code></td><td><code class="symbol">sqlclient_unable_to_establish_sqlconnection</code></td></tr><tr><td><code class="literal">08004</code></td><td><code class="symbol">sqlserver_rejected_establishment_of_sqlconnection</code></td></tr><tr><td><code class="literal">08007</code></td><td><code class="symbol">transaction_resolution_unknown</code></td></tr><tr><td><code class="literal">08P01</code></td><td><code class="symbol">protocol_violation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 09 — Triggered Action Exception</strong></span></td></tr><tr><td><code class="literal">09000</code></td><td><code class="symbol">triggered_action_exception</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 0A — Feature Not Supported</strong></span></td></tr><tr><td><code class="literal">0A000</code></td><td><code class="symbol">feature_not_supported</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 0B — Invalid Transaction Initiation</strong></span></td></tr><tr><td><code class="literal">0B000</code></td><td><code class="symbol">invalid_transaction_initiation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 0F — Locator Exception</strong></span></td></tr><tr><td><code class="literal">0F000</code></td><td><code class="symbol">locator_exception</code></td></tr><tr><td><code class="literal">0F001</code></td><td><code class="symbol">invalid_locator_specification</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 0L — Invalid Grantor</strong></span></td></tr><tr><td><code class="literal">0L000</code></td><td><code class="symbol">invalid_grantor</code></td></tr><tr><td><code class="literal">0LP01</code></td><td><code class="symbol">invalid_grant_operation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 0P — Invalid Role Specification</strong></span></td></tr><tr><td><code class="literal">0P000</code></td><td><code class="symbol">invalid_role_specification</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 0Z — Diagnostics Exception</strong></span></td></tr><tr><td><code class="literal">0Z000</code></td><td><code class="symbol">diagnostics_exception</code></td></tr><tr><td><code class="literal">0Z002</code></td><td><code class="symbol">stacked_diagnostics_accessed_without_active_handler</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 20 — Case Not Found</strong></span></td></tr><tr><td><code class="literal">20000</code></td><td><code class="symbol">case_not_found</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 21 — Cardinality Violation</strong></span></td></tr><tr><td><code class="literal">21000</code></td><td><code class="symbol">cardinality_violation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 22 — Data Exception</strong></span></td></tr><tr><td><code class="literal">22000</code></td><td><code class="symbol">data_exception</code></td></tr><tr><td><code class="literal">2202E</code></td><td><code class="symbol">array_subscript_error</code></td></tr><tr><td><code class="literal">22021</code></td><td><code class="symbol">character_not_in_repertoire</code></td></tr><tr><td><code class="literal">22008</code></td><td><code class="symbol">datetime_field_overflow</code></td></tr><tr><td><code class="literal">22012</code></td><td><code class="symbol">division_by_zero</code></td></tr><tr><td><code class="literal">22005</code></td><td><code class="symbol">error_in_assignment</code></td></tr><tr><td><code class="literal">2200B</code></td><td><code class="symbol">escape_character_conflict</code></td></tr><tr><td><code class="literal">22022</code></td><td><code class="symbol">indicator_overflow</code></td></tr><tr><td><code class="literal">22015</code></td><td><code class="symbol">interval_field_overflow</code></td></tr><tr><td><code class="literal">2201E</code></td><td><code class="symbol">invalid_argument_for_logarithm</code></td></tr><tr><td><code class="literal">22014</code></td><td><code class="symbol">invalid_argument_for_ntile_function</code></td></tr><tr><td><code class="literal">22016</code></td><td><code class="symbol">invalid_argument_for_nth_value_function</code></td></tr><tr><td><code class="literal">2201F</code></td><td><code class="symbol">invalid_argument_for_power_function</code></td></tr><tr><td><code class="literal">2201G</code></td><td><code class="symbol">invalid_argument_for_width_bucket_function</code></td></tr><tr><td><code class="literal">22018</code></td><td><code class="symbol">invalid_character_value_for_cast</code></td></tr><tr><td><code class="literal">22007</code></td><td><code class="symbol">invalid_datetime_format</code></td></tr><tr><td><code class="literal">22019</code></td><td><code class="symbol">invalid_escape_character</code></td></tr><tr><td><code class="literal">2200D</code></td><td><code class="symbol">invalid_escape_octet</code></td></tr><tr><td><code class="literal">22025</code></td><td><code class="symbol">invalid_escape_sequence</code></td></tr><tr><td><code class="literal">22P06</code></td><td><code class="symbol">nonstandard_use_of_escape_character</code></td></tr><tr><td><code class="literal">22010</code></td><td><code class="symbol">invalid_indicator_parameter_value</code></td></tr><tr><td><code class="literal">22023</code></td><td><code class="symbol">invalid_parameter_value</code></td></tr><tr><td><code class="literal">22013</code></td><td><code class="symbol">invalid_preceding_or_following_size</code></td></tr><tr><td><code class="literal">2201B</code></td><td><code class="symbol">invalid_regular_expression</code></td></tr><tr><td><code class="literal">2201W</code></td><td><code class="symbol">invalid_row_count_in_limit_clause</code></td></tr><tr><td><code class="literal">2201X</code></td><td><code class="symbol">invalid_row_count_in_result_offset_clause</code></td></tr><tr><td><code class="literal">2202H</code></td><td><code class="symbol">invalid_tablesample_argument</code></td></tr><tr><td><code class="literal">2202G</code></td><td><code class="symbol">invalid_tablesample_repeat</code></td></tr><tr><td><code class="literal">22009</code></td><td><code class="symbol">invalid_time_zone_displacement_value</code></td></tr><tr><td><code class="literal">2200C</code></td><td><code class="symbol">invalid_use_of_escape_character</code></td></tr><tr><td><code class="literal">2200G</code></td><td><code class="symbol">most_specific_type_mismatch</code></td></tr><tr><td><code class="literal">22004</code></td><td><code class="symbol">null_value_not_allowed</code></td></tr><tr><td><code class="literal">22002</code></td><td><code class="symbol">null_value_no_indicator_parameter</code></td></tr><tr><td><code class="literal">22003</code></td><td><code class="symbol">numeric_value_out_of_range</code></td></tr><tr><td><code class="literal">2200H</code></td><td><code class="symbol">sequence_generator_limit_exceeded</code></td></tr><tr><td><code class="literal">22026</code></td><td><code class="symbol">string_data_length_mismatch</code></td></tr><tr><td><code class="literal">22001</code></td><td><code class="symbol">string_data_right_truncation</code></td></tr><tr><td><code class="literal">22011</code></td><td><code class="symbol">substring_error</code></td></tr><tr><td><code class="literal">22027</code></td><td><code class="symbol">trim_error</code></td></tr><tr><td><code class="literal">22024</code></td><td><code class="symbol">unterminated_c_string</code></td></tr><tr><td><code class="literal">2200F</code></td><td><code class="symbol">zero_length_character_string</code></td></tr><tr><td><code class="literal">22P01</code></td><td><code class="symbol">floating_point_exception</code></td></tr><tr><td><code class="literal">22P02</code></td><td><code class="symbol">invalid_text_representation</code></td></tr><tr><td><code class="literal">22P03</code></td><td><code class="symbol">invalid_binary_representation</code></td></tr><tr><td><code class="literal">22P04</code></td><td><code class="symbol">bad_copy_file_format</code></td></tr><tr><td><code class="literal">22P05</code></td><td><code class="symbol">untranslatable_character</code></td></tr><tr><td><code class="literal">2200L</code></td><td><code class="symbol">not_an_xml_document</code></td></tr><tr><td><code class="literal">2200M</code></td><td><code class="symbol">invalid_xml_document</code></td></tr><tr><td><code class="literal">2200N</code></td><td><code class="symbol">invalid_xml_content</code></td></tr><tr><td><code class="literal">2200S</code></td><td><code class="symbol">invalid_xml_comment</code></td></tr><tr><td><code class="literal">2200T</code></td><td><code class="symbol">invalid_xml_processing_instruction</code></td></tr><tr><td><code class="literal">22030</code></td><td><code class="symbol">duplicate_json_object_key_value</code></td></tr><tr><td><code class="literal">22031</code></td><td><code class="symbol">invalid_argument_for_sql_json_datetime_function</code></td></tr><tr><td><code class="literal">22032</code></td><td><code class="symbol">invalid_json_text</code></td></tr><tr><td><code class="literal">22033</code></td><td><code class="symbol">invalid_sql_json_subscript</code></td></tr><tr><td><code class="literal">22034</code></td><td><code class="symbol">more_than_one_sql_json_item</code></td></tr><tr><td><code class="literal">22035</code></td><td><code class="symbol">no_sql_json_item</code></td></tr><tr><td><code class="literal">22036</code></td><td><code class="symbol">non_numeric_sql_json_item</code></td></tr><tr><td><code class="literal">22037</code></td><td><code class="symbol">non_unique_keys_in_a_json_object</code></td></tr><tr><td><code class="literal">22038</code></td><td><code class="symbol">singleton_sql_json_item_required</code></td></tr><tr><td><code class="literal">22039</code></td><td><code class="symbol">sql_json_array_not_found</code></td></tr><tr><td><code class="literal">2203A</code></td><td><code class="symbol">sql_json_member_not_found</code></td></tr><tr><td><code class="literal">2203B</code></td><td><code class="symbol">sql_json_number_not_found</code></td></tr><tr><td><code class="literal">2203C</code></td><td><code class="symbol">sql_json_object_not_found</code></td></tr><tr><td><code class="literal">2203D</code></td><td><code class="symbol">too_many_json_array_elements</code></td></tr><tr><td><code class="literal">2203E</code></td><td><code class="symbol">too_many_json_object_members</code></td></tr><tr><td><code class="literal">2203F</code></td><td><code class="symbol">sql_json_scalar_required</code></td></tr><tr><td><code class="literal">2203G</code></td><td><code class="symbol">sql_json_item_cannot_be_cast_to_target_type</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 23 — Integrity Constraint Violation</strong></span></td></tr><tr><td><code class="literal">23000</code></td><td><code class="symbol">integrity_constraint_violation</code></td></tr><tr><td><code class="literal">23001</code></td><td><code class="symbol">restrict_violation</code></td></tr><tr><td><code class="literal">23502</code></td><td><code class="symbol">not_null_violation</code></td></tr><tr><td><code class="literal">23503</code></td><td><code class="symbol">foreign_key_violation</code></td></tr><tr><td><code class="literal">23505</code></td><td><code class="symbol">unique_violation</code></td></tr><tr><td><code class="literal">23514</code></td><td><code class="symbol">check_violation</code></td></tr><tr><td><code class="literal">23P01</code></td><td><code class="symbol">exclusion_violation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 24 — Invalid Cursor State</strong></span></td></tr><tr><td><code class="literal">24000</code></td><td><code class="symbol">invalid_cursor_state</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 25 — Invalid Transaction State</strong></span></td></tr><tr><td><code class="literal">25000</code></td><td><code class="symbol">invalid_transaction_state</code></td></tr><tr><td><code class="literal">25001</code></td><td><code class="symbol">active_sql_transaction</code></td></tr><tr><td><code class="literal">25002</code></td><td><code class="symbol">branch_transaction_already_active</code></td></tr><tr><td><code class="literal">25008</code></td><td><code class="symbol">held_cursor_requires_same_isolation_level</code></td></tr><tr><td><code class="literal">25003</code></td><td><code class="symbol">inappropriate_access_mode_for_branch_transaction</code></td></tr><tr><td><code class="literal">25004</code></td><td><code class="symbol">inappropriate_isolation_level_for_branch_transaction</code></td></tr><tr><td><code class="literal">25005</code></td><td><code class="symbol">no_active_sql_transaction_for_branch_transaction</code></td></tr><tr><td><code class="literal">25006</code></td><td><code class="symbol">read_only_sql_transaction</code></td></tr><tr><td><code class="literal">25007</code></td><td><code class="symbol">schema_and_data_statement_mixing_not_supported</code></td></tr><tr><td><code class="literal">25P01</code></td><td><code class="symbol">no_active_sql_transaction</code></td></tr><tr><td><code class="literal">25P02</code></td><td><code class="symbol">in_failed_sql_transaction</code></td></tr><tr><td><code class="literal">25P03</code></td><td><code class="symbol">idle_in_transaction_session_timeout</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 26 — Invalid SQL Statement Name</strong></span></td></tr><tr><td><code class="literal">26000</code></td><td><code class="symbol">invalid_sql_statement_name</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 27 — Triggered Data Change Violation</strong></span></td></tr><tr><td><code class="literal">27000</code></td><td><code class="symbol">triggered_data_change_violation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 28 — Invalid Authorization Specification</strong></span></td></tr><tr><td><code class="literal">28000</code></td><td><code class="symbol">invalid_authorization_specification</code></td></tr><tr><td><code class="literal">28P01</code></td><td><code class="symbol">invalid_password</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 2B — Dependent Privilege Descriptors Still Exist</strong></span></td></tr><tr><td><code class="literal">2B000</code></td><td><code class="symbol">dependent_privilege_descriptors_still_exist</code></td></tr><tr><td><code class="literal">2BP01</code></td><td><code class="symbol">dependent_objects_still_exist</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 2D — Invalid Transaction Termination</strong></span></td></tr><tr><td><code class="literal">2D000</code></td><td><code class="symbol">invalid_transaction_termination</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 2F — SQL Routine Exception</strong></span></td></tr><tr><td><code class="literal">2F000</code></td><td><code class="symbol">sql_routine_exception</code></td></tr><tr><td><code class="literal">2F005</code></td><td><code class="symbol">function_executed_no_return_statement</code></td></tr><tr><td><code class="literal">2F002</code></td><td><code class="symbol">modifying_sql_data_not_permitted</code></td></tr><tr><td><code class="literal">2F003</code></td><td><code class="symbol">prohibited_sql_statement_attempted</code></td></tr><tr><td><code class="literal">2F004</code></td><td><code class="symbol">reading_sql_data_not_permitted</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 34 — Invalid Cursor Name</strong></span></td></tr><tr><td><code class="literal">34000</code></td><td><code class="symbol">invalid_cursor_name</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 38 — External Routine Exception</strong></span></td></tr><tr><td><code class="literal">38000</code></td><td><code class="symbol">external_routine_exception</code></td></tr><tr><td><code class="literal">38001</code></td><td><code class="symbol">containing_sql_not_permitted</code></td></tr><tr><td><code class="literal">38002</code></td><td><code class="symbol">modifying_sql_data_not_permitted</code></td></tr><tr><td><code class="literal">38003</code></td><td><code class="symbol">prohibited_sql_statement_attempted</code></td></tr><tr><td><code class="literal">38004</code></td><td><code class="symbol">reading_sql_data_not_permitted</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 39 — External Routine Invocation Exception</strong></span></td></tr><tr><td><code class="literal">39000</code></td><td><code class="symbol">external_routine_invocation_exception</code></td></tr><tr><td><code class="literal">39001</code></td><td><code class="symbol">invalid_sqlstate_returned</code></td></tr><tr><td><code class="literal">39004</code></td><td><code class="symbol">null_value_not_allowed</code></td></tr><tr><td><code class="literal">39P01</code></td><td><code class="symbol">trigger_protocol_violated</code></td></tr><tr><td><code class="literal">39P02</code></td><td><code class="symbol">srf_protocol_violated</code></td></tr><tr><td><code class="literal">39P03</code></td><td><code class="symbol">event_trigger_protocol_violated</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 3B — Savepoint Exception</strong></span></td></tr><tr><td><code class="literal">3B000</code></td><td><code class="symbol">savepoint_exception</code></td></tr><tr><td><code class="literal">3B001</code></td><td><code class="symbol">invalid_savepoint_specification</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 3D — Invalid Catalog Name</strong></span></td></tr><tr><td><code class="literal">3D000</code></td><td><code class="symbol">invalid_catalog_name</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 3F — Invalid Schema Name</strong></span></td></tr><tr><td><code class="literal">3F000</code></td><td><code class="symbol">invalid_schema_name</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 40 — Transaction Rollback</strong></span></td></tr><tr><td><code class="literal">40000</code></td><td><code class="symbol">transaction_rollback</code></td></tr><tr><td><code class="literal">40002</code></td><td><code class="symbol">transaction_integrity_constraint_violation</code></td></tr><tr><td><code class="literal">40001</code></td><td><code class="symbol">serialization_failure</code></td></tr><tr><td><code class="literal">40003</code></td><td><code class="symbol">statement_completion_unknown</code></td></tr><tr><td><code class="literal">40P01</code></td><td><code class="symbol">deadlock_detected</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 42 — Syntax Error or Access Rule Violation</strong></span></td></tr><tr><td><code class="literal">42000</code></td><td><code class="symbol">syntax_error_or_access_rule_violation</code></td></tr><tr><td><code class="literal">42601</code></td><td><code class="symbol">syntax_error</code></td></tr><tr><td><code class="literal">42501</code></td><td><code class="symbol">insufficient_privilege</code></td></tr><tr><td><code class="literal">42846</code></td><td><code class="symbol">cannot_coerce</code></td></tr><tr><td><code class="literal">42803</code></td><td><code class="symbol">grouping_error</code></td></tr><tr><td><code class="literal">42P20</code></td><td><code class="symbol">windowing_error</code></td></tr><tr><td><code class="literal">42P19</code></td><td><code class="symbol">invalid_recursion</code></td></tr><tr><td><code class="literal">42830</code></td><td><code class="symbol">invalid_foreign_key</code></td></tr><tr><td><code class="literal">42602</code></td><td><code class="symbol">invalid_name</code></td></tr><tr><td><code class="literal">42622</code></td><td><code class="symbol">name_too_long</code></td></tr><tr><td><code class="literal">42939</code></td><td><code class="symbol">reserved_name</code></td></tr><tr><td><code class="literal">42804</code></td><td><code class="symbol">datatype_mismatch</code></td></tr><tr><td><code class="literal">42P18</code></td><td><code class="symbol">indeterminate_datatype</code></td></tr><tr><td><code class="literal">42P21</code></td><td><code class="symbol">collation_mismatch</code></td></tr><tr><td><code class="literal">42P22</code></td><td><code class="symbol">indeterminate_collation</code></td></tr><tr><td><code class="literal">42809</code></td><td><code class="symbol">wrong_object_type</code></td></tr><tr><td><code class="literal">428C9</code></td><td><code class="symbol">generated_always</code></td></tr><tr><td><code class="literal">42703</code></td><td><code class="symbol">undefined_column</code></td></tr><tr><td><code class="literal">42883</code></td><td><code class="symbol">undefined_function</code></td></tr><tr><td><code class="literal">42P01</code></td><td><code class="symbol">undefined_table</code></td></tr><tr><td><code class="literal">42P02</code></td><td><code class="symbol">undefined_parameter</code></td></tr><tr><td><code class="literal">42704</code></td><td><code class="symbol">undefined_object</code></td></tr><tr><td><code class="literal">42701</code></td><td><code class="symbol">duplicate_column</code></td></tr><tr><td><code class="literal">42P03</code></td><td><code class="symbol">duplicate_cursor</code></td></tr><tr><td><code class="literal">42P04</code></td><td><code class="symbol">duplicate_database</code></td></tr><tr><td><code class="literal">42723</code></td><td><code class="symbol">duplicate_function</code></td></tr><tr><td><code class="literal">42P05</code></td><td><code class="symbol">duplicate_prepared_statement</code></td></tr><tr><td><code class="literal">42P06</code></td><td><code class="symbol">duplicate_schema</code></td></tr><tr><td><code class="literal">42P07</code></td><td><code class="symbol">duplicate_table</code></td></tr><tr><td><code class="literal">42712</code></td><td><code class="symbol">duplicate_alias</code></td></tr><tr><td><code class="literal">42710</code></td><td><code class="symbol">duplicate_object</code></td></tr><tr><td><code class="literal">42702</code></td><td><code class="symbol">ambiguous_column</code></td></tr><tr><td><code class="literal">42725</code></td><td><code class="symbol">ambiguous_function</code></td></tr><tr><td><code class="literal">42P08</code></td><td><code class="symbol">ambiguous_parameter</code></td></tr><tr><td><code class="literal">42P09</code></td><td><code class="symbol">ambiguous_alias</code></td></tr><tr><td><code class="literal">42P10</code></td><td><code class="symbol">invalid_column_reference</code></td></tr><tr><td><code class="literal">42611</code></td><td><code class="symbol">invalid_column_definition</code></td></tr><tr><td><code class="literal">42P11</code></td><td><code class="symbol">invalid_cursor_definition</code></td></tr><tr><td><code class="literal">42P12</code></td><td><code class="symbol">invalid_database_definition</code></td></tr><tr><td><code class="literal">42P13</code></td><td><code class="symbol">invalid_function_definition</code></td></tr><tr><td><code class="literal">42P14</code></td><td><code class="symbol">invalid_prepared_statement_definition</code></td></tr><tr><td><code class="literal">42P15</code></td><td><code class="symbol">invalid_schema_definition</code></td></tr><tr><td><code class="literal">42P16</code></td><td><code class="symbol">invalid_table_definition</code></td></tr><tr><td><code class="literal">42P17</code></td><td><code class="symbol">invalid_object_definition</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 44 — WITH CHECK OPTION Violation</strong></span></td></tr><tr><td><code class="literal">44000</code></td><td><code class="symbol">with_check_option_violation</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 53 — Insufficient Resources</strong></span></td></tr><tr><td><code class="literal">53000</code></td><td><code class="symbol">insufficient_resources</code></td></tr><tr><td><code class="literal">53100</code></td><td><code class="symbol">disk_full</code></td></tr><tr><td><code class="literal">53200</code></td><td><code class="symbol">out_of_memory</code></td></tr><tr><td><code class="literal">53300</code></td><td><code class="symbol">too_many_connections</code></td></tr><tr><td><code class="literal">53400</code></td><td><code class="symbol">configuration_limit_exceeded</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 54 — Program Limit Exceeded</strong></span></td></tr><tr><td><code class="literal">54000</code></td><td><code class="symbol">program_limit_exceeded</code></td></tr><tr><td><code class="literal">54001</code></td><td><code class="symbol">statement_too_complex</code></td></tr><tr><td><code class="literal">54011</code></td><td><code class="symbol">too_many_columns</code></td></tr><tr><td><code class="literal">54023</code></td><td><code class="symbol">too_many_arguments</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 55 — Object Not In Prerequisite State</strong></span></td></tr><tr><td><code class="literal">55000</code></td><td><code class="symbol">object_not_in_prerequisite_state</code></td></tr><tr><td><code class="literal">55006</code></td><td><code class="symbol">object_in_use</code></td></tr><tr><td><code class="literal">55P02</code></td><td><code class="symbol">cant_change_runtime_param</code></td></tr><tr><td><code class="literal">55P03</code></td><td><code class="symbol">lock_not_available</code></td></tr><tr><td><code class="literal">55P04</code></td><td><code class="symbol">unsafe_new_enum_value_usage</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 57 — Operator Intervention</strong></span></td></tr><tr><td><code class="literal">57000</code></td><td><code class="symbol">operator_intervention</code></td></tr><tr><td><code class="literal">57014</code></td><td><code class="symbol">query_canceled</code></td></tr><tr><td><code class="literal">57P01</code></td><td><code class="symbol">admin_shutdown</code></td></tr><tr><td><code class="literal">57P02</code></td><td><code class="symbol">crash_shutdown</code></td></tr><tr><td><code class="literal">57P03</code></td><td><code class="symbol">cannot_connect_now</code></td></tr><tr><td><code class="literal">57P04</code></td><td><code class="symbol">database_dropped</code></td></tr><tr><td><code class="literal">57P05</code></td><td><code class="symbol">idle_session_timeout</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 58 — System Error (errors external to <span class="productname">PostgreSQL</span> itself)</strong></span></td></tr><tr><td><code class="literal">58000</code></td><td><code class="symbol">system_error</code></td></tr><tr><td><code class="literal">58030</code></td><td><code class="symbol">io_error</code></td></tr><tr><td><code class="literal">58P01</code></td><td><code class="symbol">undefined_file</code></td></tr><tr><td><code class="literal">58P02</code></td><td><code class="symbol">duplicate_file</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class 72 — Snapshot Failure</strong></span></td></tr><tr><td><code class="literal">72000</code></td><td><code class="symbol">snapshot_too_old</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class F0 — Configuration File Error</strong></span></td></tr><tr><td><code class="literal">F0000</code></td><td><code class="symbol">config_file_error</code></td></tr><tr><td><code class="literal">F0001</code></td><td><code class="symbol">lock_file_exists</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class HV — Foreign Data Wrapper Error (SQL/MED)</strong></span></td></tr><tr><td><code class="literal">HV000</code></td><td><code class="symbol">fdw_error</code></td></tr><tr><td><code class="literal">HV005</code></td><td><code class="symbol">fdw_column_name_not_found</code></td></tr><tr><td><code class="literal">HV002</code></td><td><code class="symbol">fdw_dynamic_parameter_value_needed</code></td></tr><tr><td><code class="literal">HV010</code></td><td><code class="symbol">fdw_function_sequence_error</code></td></tr><tr><td><code class="literal">HV021</code></td><td><code class="symbol">fdw_inconsistent_descriptor_information</code></td></tr><tr><td><code class="literal">HV024</code></td><td><code class="symbol">fdw_invalid_attribute_value</code></td></tr><tr><td><code class="literal">HV007</code></td><td><code class="symbol">fdw_invalid_column_name</code></td></tr><tr><td><code class="literal">HV008</code></td><td><code class="symbol">fdw_invalid_column_number</code></td></tr><tr><td><code class="literal">HV004</code></td><td><code class="symbol">fdw_invalid_data_type</code></td></tr><tr><td><code class="literal">HV006</code></td><td><code class="symbol">fdw_invalid_data_type_descriptors</code></td></tr><tr><td><code class="literal">HV091</code></td><td><code class="symbol">fdw_invalid_descriptor_field_identifier</code></td></tr><tr><td><code class="literal">HV00B</code></td><td><code class="symbol">fdw_invalid_handle</code></td></tr><tr><td><code class="literal">HV00C</code></td><td><code class="symbol">fdw_invalid_option_index</code></td></tr><tr><td><code class="literal">HV00D</code></td><td><code class="symbol">fdw_invalid_option_name</code></td></tr><tr><td><code class="literal">HV090</code></td><td><code class="symbol">fdw_invalid_string_length_or_buffer_length</code></td></tr><tr><td><code class="literal">HV00A</code></td><td><code class="symbol">fdw_invalid_string_format</code></td></tr><tr><td><code class="literal">HV009</code></td><td><code class="symbol">fdw_invalid_use_of_null_pointer</code></td></tr><tr><td><code class="literal">HV014</code></td><td><code class="symbol">fdw_too_many_handles</code></td></tr><tr><td><code class="literal">HV001</code></td><td><code class="symbol">fdw_out_of_memory</code></td></tr><tr><td><code class="literal">HV00P</code></td><td><code class="symbol">fdw_no_schemas</code></td></tr><tr><td><code class="literal">HV00J</code></td><td><code class="symbol">fdw_option_name_not_found</code></td></tr><tr><td><code class="literal">HV00K</code></td><td><code class="symbol">fdw_reply_handle</code></td></tr><tr><td><code class="literal">HV00Q</code></td><td><code class="symbol">fdw_schema_not_found</code></td></tr><tr><td><code class="literal">HV00R</code></td><td><code class="symbol">fdw_table_not_found</code></td></tr><tr><td><code class="literal">HV00L</code></td><td><code class="symbol">fdw_unable_to_create_execution</code></td></tr><tr><td><code class="literal">HV00M</code></td><td><code class="symbol">fdw_unable_to_create_reply</code></td></tr><tr><td><code class="literal">HV00N</code></td><td><code class="symbol">fdw_unable_to_establish_connection</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class P0 — PL/pgSQL Error</strong></span></td></tr><tr><td><code class="literal">P0000</code></td><td><code class="symbol">plpgsql_error</code></td></tr><tr><td><code class="literal">P0001</code></td><td><code class="symbol">raise_exception</code></td></tr><tr><td><code class="literal">P0002</code></td><td><code class="symbol">no_data_found</code></td></tr><tr><td><code class="literal">P0003</code></td><td><code class="symbol">too_many_rows</code></td></tr><tr><td><code class="literal">P0004</code></td><td><code class="symbol">assert_failure</code></td></tr><tr><td colspan="2"><span class="bold"><strong>Class XX — Internal Error</strong></span></td></tr><tr><td><code class="literal">XX000</code></td><td><code class="symbol">internal_error</code></td></tr><tr><td><code class="literal">XX001</code></td><td><code class="symbol">data_corrupted</code></td></tr><tr><td><code class="literal">XX002</code></td><td><code class="symbol">index_corrupted</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="appendixes.html" title="Part VIII. Appendixes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datetime-appendix.html" title="Appendix B. Date/Time Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part VIII. Appendixes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix B. Date/Time Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/error-message-reporting.html b/doc/src/sgml/html/error-message-reporting.html
new file mode 100644
index 0000000..21a90ac
--- /dev/null
+++ b/doc/src/sgml/html/error-message-reporting.html
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>56.2. Reporting Errors Within the Server</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="source-format.html" title="56.1. Formatting" /><link rel="next" href="error-style-guide.html" title="56.3. Error Message Style Guide" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">56.2. Reporting Errors Within the Server</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="source-format.html" title="56.1. Formatting">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><th width="60%" align="center">Chapter 56. PostgreSQL Coding Conventions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="error-style-guide.html" title="56.3. Error Message Style Guide">Next</a></td></tr></table><hr /></div><div class="sect1" id="ERROR-MESSAGE-REPORTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">56.2. Reporting Errors Within the Server</h2></div></div></div><a id="id-1.10.7.3.2" class="indexterm"></a><a id="id-1.10.7.3.3" class="indexterm"></a><p>
+ Error, warning, and log messages generated within the server code
+ should be created using <code class="function">ereport</code>, or its older cousin
+ <code class="function">elog</code>. The use of this function is complex enough to
+ require some explanation.
+ </p><p>
+ There are two required elements for every message: a severity level
+ (ranging from <code class="literal">DEBUG</code> to <code class="literal">PANIC</code>) and a primary
+ message text. In addition there are optional elements, the most
+ common of which is an error identifier code that follows the SQL spec's
+ SQLSTATE conventions.
+ <code class="function">ereport</code> itself is just a shell macro that exists
+ mainly for the syntactic convenience of making message generation
+ look like a single function call in the C source code. The only parameter
+ accepted directly by <code class="function">ereport</code> is the severity level.
+ The primary message text and any optional message elements are
+ generated by calling auxiliary functions, such as <code class="function">errmsg</code>,
+ within the <code class="function">ereport</code> call.
+ </p><p>
+ A typical call to <code class="function">ereport</code> might look like this:
+</p><pre class="programlisting">
+ereport(ERROR,
+ errcode(ERRCODE_DIVISION_BY_ZERO),
+ errmsg("division by zero"));
+</pre><p>
+ This specifies error severity level <code class="literal">ERROR</code> (a run-of-the-mill
+ error). The <code class="function">errcode</code> call specifies the SQLSTATE error code
+ using a macro defined in <code class="filename">src/include/utils/errcodes.h</code>. The
+ <code class="function">errmsg</code> call provides the primary message text.
+ </p><p>
+ You will also frequently see this older style, with an extra set of
+ parentheses surrounding the auxiliary function calls:
+</p><pre class="programlisting">
+ereport(ERROR,
+ (errcode(ERRCODE_DIVISION_BY_ZERO),
+ errmsg("division by zero")));
+</pre><p>
+ The extra parentheses were required
+ before <span class="productname">PostgreSQL</span> version 12, but are now
+ optional.
+ </p><p>
+ Here is a more complex example:
+</p><pre class="programlisting">
+ereport(ERROR,
+ errcode(ERRCODE_AMBIGUOUS_FUNCTION),
+ errmsg("function %s is not unique",
+ func_signature_string(funcname, nargs,
+ NIL, actual_arg_types)),
+ errhint("Unable to choose a best candidate function. "
+ "You might need to add explicit typecasts."));
+</pre><p>
+ This illustrates the use of format codes to embed run-time values into
+ a message text. Also, an optional <span class="quote">“<span class="quote">hint</span>”</span> message is provided.
+ The auxiliary function calls can be written in any order, but
+ conventionally <code class="function">errcode</code>
+ and <code class="function">errmsg</code> appear first.
+ </p><p>
+ If the severity level is <code class="literal">ERROR</code> or higher,
+ <code class="function">ereport</code> aborts execution of the current query
+ and does not return to the caller. If the severity level is
+ lower than <code class="literal">ERROR</code>, <code class="function">ereport</code> returns normally.
+ </p><p>
+ The available auxiliary routines for <code class="function">ereport</code> are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="function">errcode(sqlerrcode)</code> specifies the SQLSTATE error identifier
+ code for the condition. If this routine is not called, the error
+ identifier defaults to
+ <code class="literal">ERRCODE_INTERNAL_ERROR</code> when the error severity level is
+ <code class="literal">ERROR</code> or higher, <code class="literal">ERRCODE_WARNING</code> when the
+ error level is <code class="literal">WARNING</code>, otherwise (for <code class="literal">NOTICE</code>
+ and below) <code class="literal">ERRCODE_SUCCESSFUL_COMPLETION</code>.
+ While these defaults are often convenient, always think whether they
+ are appropriate before omitting the <code class="function">errcode()</code> call.
+ </p></li><li class="listitem"><p>
+ <code class="function">errmsg(const char *msg, ...)</code> specifies the primary error
+ message text, and possibly run-time values to insert into it. Insertions
+ are specified by <code class="function">sprintf</code>-style format codes. In addition to
+ the standard format codes accepted by <code class="function">sprintf</code>, the format
+ code <code class="literal">%m</code> can be used to insert the error message returned
+ by <code class="function">strerror</code> for the current value of <code class="literal">errno</code>.
+ <a href="#ftn.id-1.10.7.3.10.2.2.1.7" class="footnote"><sup class="footnote" id="id-1.10.7.3.10.2.2.1.7">[16]</sup></a>
+ <code class="literal">%m</code> does not require any
+ corresponding entry in the parameter list for <code class="function">errmsg</code>.
+ Note that the message string will be run through <code class="function">gettext</code>
+ for possible localization before format codes are processed.
+ </p></li><li class="listitem"><p>
+ <code class="function">errmsg_internal(const char *msg, ...)</code> is the same as
+ <code class="function">errmsg</code>, except that the message string will not be
+ translated nor included in the internationalization message dictionary.
+ This should be used for <span class="quote">“<span class="quote">cannot happen</span>”</span> cases that are probably
+ not worth expending translation effort on.
+ </p></li><li class="listitem"><p>
+ <code class="function">errmsg_plural(const char *fmt_singular, const char *fmt_plural,
+ unsigned long n, ...)</code> is like <code class="function">errmsg</code>, but with
+ support for various plural forms of the message.
+ <em class="replaceable"><code>fmt_singular</code></em> is the English singular format,
+ <em class="replaceable"><code>fmt_plural</code></em> is the English plural format,
+ <em class="replaceable"><code>n</code></em> is the integer value that determines which plural
+ form is needed, and the remaining arguments are formatted according
+ to the selected format string. For more information see
+ <a class="xref" href="nls-programmer.html#NLS-GUIDELINES" title="57.2.2. Message-Writing Guidelines">Section 57.2.2</a>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdetail(const char *msg, ...)</code> supplies an optional
+ <span class="quote">“<span class="quote">detail</span>”</span> message; this is to be used when there is additional
+ information that seems inappropriate to put in the primary message.
+ The message string is processed in just the same way as for
+ <code class="function">errmsg</code>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdetail_internal(const char *msg, ...)</code> is the same
+ as <code class="function">errdetail</code>, except that the message string will not be
+ translated nor included in the internationalization message dictionary.
+ This should be used for detail messages that are not worth expending
+ translation effort on, for instance because they are too technical to be
+ useful to most users.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdetail_plural(const char *fmt_singular, const char *fmt_plural,
+ unsigned long n, ...)</code> is like <code class="function">errdetail</code>, but with
+ support for various plural forms of the message.
+ For more information see <a class="xref" href="nls-programmer.html#NLS-GUIDELINES" title="57.2.2. Message-Writing Guidelines">Section 57.2.2</a>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdetail_log(const char *msg, ...)</code> is the same as
+ <code class="function">errdetail</code> except that this string goes only to the server
+ log, never to the client. If both <code class="function">errdetail</code> (or one of
+ its equivalents above) and
+ <code class="function">errdetail_log</code> are used then one string goes to the client
+ and the other to the log. This is useful for error details that are
+ too security-sensitive or too bulky to include in the report
+ sent to the client.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdetail_log_plural(const char *fmt_singular, const char
+ *fmt_plural, unsigned long n, ...)</code> is like
+ <code class="function">errdetail_log</code>, but with support for various plural forms of
+ the message.
+ For more information see <a class="xref" href="nls-programmer.html#NLS-GUIDELINES" title="57.2.2. Message-Writing Guidelines">Section 57.2.2</a>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errhint(const char *msg, ...)</code> supplies an optional
+ <span class="quote">“<span class="quote">hint</span>”</span> message; this is to be used when offering suggestions
+ about how to fix the problem, as opposed to factual details about
+ what went wrong.
+ The message string is processed in just the same way as for
+ <code class="function">errmsg</code>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errhint_plural(const char *fmt_singular, const char *fmt_plural,
+ unsigned long n, ...)</code> is like <code class="function">errhint</code>, but with
+ support for various plural forms of the message.
+ For more information see <a class="xref" href="nls-programmer.html#NLS-GUIDELINES" title="57.2.2. Message-Writing Guidelines">Section 57.2.2</a>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errcontext(const char *msg, ...)</code> is not normally called
+ directly from an <code class="function">ereport</code> message site; rather it is used
+ in <code class="literal">error_context_stack</code> callback functions to provide
+ information about the context in which an error occurred, such as the
+ current location in a PL function.
+ The message string is processed in just the same way as for
+ <code class="function">errmsg</code>. Unlike the other auxiliary functions, this can
+ be called more than once per <code class="function">ereport</code> call; the successive
+ strings thus supplied are concatenated with separating newlines.
+ </p></li><li class="listitem"><p>
+ <code class="function">errposition(int cursorpos)</code> specifies the textual location
+ of an error within a query string. Currently it is only useful for
+ errors detected in the lexical and syntactic analysis phases of
+ query processing.
+ </p></li><li class="listitem"><p>
+ <code class="function">errtable(Relation rel)</code> specifies a relation whose
+ name and schema name should be included as auxiliary fields in the error
+ report.
+ </p></li><li class="listitem"><p>
+ <code class="function">errtablecol(Relation rel, int attnum)</code> specifies
+ a column whose name, table name, and schema name should be included as
+ auxiliary fields in the error report.
+ </p></li><li class="listitem"><p>
+ <code class="function">errtableconstraint(Relation rel, const char *conname)</code>
+ specifies a table constraint whose name, table name, and schema name
+ should be included as auxiliary fields in the error report. Indexes
+ should be considered to be constraints for this purpose, whether or
+ not they have an associated <code class="structname">pg_constraint</code> entry. Be
+ careful to pass the underlying heap relation, not the index itself, as
+ <code class="literal">rel</code>.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdatatype(Oid datatypeOid)</code> specifies a data
+ type whose name and schema name should be included as auxiliary fields
+ in the error report.
+ </p></li><li class="listitem"><p>
+ <code class="function">errdomainconstraint(Oid datatypeOid, const char *conname)</code>
+ specifies a domain constraint whose name, domain name, and schema name
+ should be included as auxiliary fields in the error report.
+ </p></li><li class="listitem"><p>
+ <code class="function">errcode_for_file_access()</code> is a convenience function that
+ selects an appropriate SQLSTATE error identifier for a failure in a
+ file-access-related system call. It uses the saved
+ <code class="literal">errno</code> to determine which error code to generate.
+ Usually this should be used in combination with <code class="literal">%m</code> in the
+ primary error message text.
+ </p></li><li class="listitem"><p>
+ <code class="function">errcode_for_socket_access()</code> is a convenience function that
+ selects an appropriate SQLSTATE error identifier for a failure in a
+ socket-related system call.
+ </p></li><li class="listitem"><p>
+ <code class="function">errhidestmt(bool hide_stmt)</code> can be called to specify
+ suppression of the <code class="literal">STATEMENT:</code> portion of a message in the
+ postmaster log. Generally this is appropriate if the message text
+ includes the current statement already.
+ </p></li><li class="listitem"><p>
+ <code class="function">errhidecontext(bool hide_ctx)</code> can be called to
+ specify suppression of the <code class="literal">CONTEXT:</code> portion of a message in
+ the postmaster log. This should only be used for verbose debugging
+ messages where the repeated inclusion of context would bloat the log
+ too much.
+ </p></li></ul></div><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ At most one of the functions <code class="function">errtable</code>,
+ <code class="function">errtablecol</code>, <code class="function">errtableconstraint</code>,
+ <code class="function">errdatatype</code>, or <code class="function">errdomainconstraint</code> should
+ be used in an <code class="function">ereport</code> call. These functions exist to
+ allow applications to extract the name of a database object associated
+ with the error condition without having to examine the
+ potentially-localized error message text.
+ These functions should be used in error reports for which it's likely
+ that applications would wish to have automatic error handling. As of
+ <span class="productname">PostgreSQL</span> 9.3, complete coverage exists only for
+ errors in SQLSTATE class 23 (integrity constraint violation), but this
+ is likely to be expanded in future.
+ </p></div><p>
+ There is an older function <code class="function">elog</code> that is still heavily used.
+ An <code class="function">elog</code> call:
+</p><pre class="programlisting">
+elog(level, "format string", ...);
+</pre><p>
+ is exactly equivalent to:
+</p><pre class="programlisting">
+ereport(level, errmsg_internal("format string", ...));
+</pre><p>
+ Notice that the SQLSTATE error code is always defaulted, and the message
+ string is not subject to translation.
+ Therefore, <code class="function">elog</code> should be used only for internal errors and
+ low-level debug logging. Any message that is likely to be of interest to
+ ordinary users should go through <code class="function">ereport</code>. Nonetheless,
+ there are enough internal <span class="quote">“<span class="quote">cannot happen</span>”</span> error checks in the
+ system that <code class="function">elog</code> is still widely used; it is preferred for
+ those messages for its notational simplicity.
+ </p><p>
+ Advice about writing good error messages can be found in
+ <a class="xref" href="error-style-guide.html" title="56.3. Error Message Style Guide">Section 56.3</a>.
+ </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.10.7.3.10.2.2.1.7" class="footnote"><p><a href="#id-1.10.7.3.10.2.2.1.7" class="para"><sup class="para">[16] </sup></a>
+ That is, the value that was current when the <code class="function">ereport</code> call
+ was reached; changes of <code class="literal">errno</code> within the auxiliary reporting
+ routines will not affect it. That would not be true if you were to
+ write <code class="literal">strerror(errno)</code> explicitly in <code class="function">errmsg</code>'s
+ parameter list; accordingly, do not do so.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="source-format.html" title="56.1. Formatting">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="error-style-guide.html" title="56.3. Error Message Style Guide">Next</a></td></tr><tr><td width="40%" align="left" valign="top">56.1. Formatting </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 56.3. Error Message Style Guide</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/error-style-guide.html b/doc/src/sgml/html/error-style-guide.html
new file mode 100644
index 0000000..617c9e0
--- /dev/null
+++ b/doc/src/sgml/html/error-style-guide.html
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>56.3. Error Message Style Guide</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="error-message-reporting.html" title="56.2. Reporting Errors Within the Server" /><link rel="next" href="source-conventions.html" title="56.4. Miscellaneous Coding Conventions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">56.3. Error Message Style Guide</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="error-message-reporting.html" title="56.2. Reporting Errors Within the Server">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><th width="60%" align="center">Chapter 56. PostgreSQL Coding Conventions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="source-conventions.html" title="56.4. Miscellaneous Coding Conventions">Next</a></td></tr></table><hr /></div><div class="sect1" id="ERROR-STYLE-GUIDE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">56.3. Error Message Style Guide</h2></div></div></div><p>
+ This style guide is offered in the hope of maintaining a consistent,
+ user-friendly style throughout all the messages generated by
+ <span class="productname">PostgreSQL</span>.
+ </p><div class="simplesect" id="id-1.10.7.4.3"><div class="titlepage"><div><div><h3 class="title">What Goes Where</h3></div></div></div><p>
+ The primary message should be short, factual, and avoid reference to
+ implementation details such as specific function names.
+ <span class="quote">“<span class="quote">Short</span>”</span> means <span class="quote">“<span class="quote">should fit on one line under normal
+ conditions</span>”</span>. Use a detail message if needed to keep the primary
+ message short, or if you feel a need to mention implementation details
+ such as the particular system call that failed. Both primary and detail
+ messages should be factual. Use a hint message for suggestions about what
+ to do to fix the problem, especially if the suggestion might not always be
+ applicable.
+ </p><p>
+ For example, instead of:
+</p><pre class="programlisting">
+IpcMemoryCreate: shmget(key=%d, size=%u, 0%o) failed: %m
+(plus a long addendum that is basically a hint)
+</pre><p>
+ write:
+</p><pre class="programlisting">
+Primary: could not create shared memory segment: %m
+Detail: Failed syscall was shmget(key=%d, size=%u, 0%o).
+Hint: the addendum
+</pre><p>
+ </p><p>
+ Rationale: keeping the primary message short helps keep it to the point,
+ and lets clients lay out screen space on the assumption that one line is
+ enough for error messages. Detail and hint messages can be relegated to a
+ verbose mode, or perhaps a pop-up error-details window. Also, details and
+ hints would normally be suppressed from the server log to save
+ space. Reference to implementation details is best avoided since users
+ aren't expected to know the details.
+ </p></div><div class="simplesect" id="id-1.10.7.4.4"><div class="titlepage"><div><div><h3 class="title">Formatting</h3></div></div></div><p>
+ Don't put any specific assumptions about formatting into the message
+ texts. Expect clients and the server log to wrap lines to fit their own
+ needs. In long messages, newline characters (\n) can be used to indicate
+ suggested paragraph breaks. Don't end a message with a newline. Don't
+ use tabs or other formatting characters. (In error context displays,
+ newlines are automatically added to separate levels of context such as
+ function calls.)
+ </p><p>
+ Rationale: Messages are not necessarily displayed on terminal-type
+ displays. In GUI displays or browsers these formatting instructions are
+ at best ignored.
+ </p></div><div class="simplesect" id="id-1.10.7.4.5"><div class="titlepage"><div><div><h3 class="title">Quotation Marks</h3></div></div></div><p>
+ English text should use double quotes when quoting is appropriate.
+ Text in other languages should consistently use one kind of quotes that is
+ consistent with publishing customs and computer output of other programs.
+ </p><p>
+ Rationale: The choice of double quotes over single quotes is somewhat
+ arbitrary, but tends to be the preferred use. Some have suggested
+ choosing the kind of quotes depending on the type of object according to
+ SQL conventions (namely, strings single quoted, identifiers double
+ quoted). But this is a language-internal technical issue that many users
+ aren't even familiar with, it won't scale to other kinds of quoted terms,
+ it doesn't translate to other languages, and it's pretty pointless, too.
+ </p></div><div class="simplesect" id="id-1.10.7.4.6"><div class="titlepage"><div><div><h3 class="title">Use of Quotes</h3></div></div></div><p>
+ Always use quotes to delimit file names, user-supplied identifiers, and
+ other variables that might contain words. Do not use them to mark up
+ variables that will not contain words (for example, operator names).
+ </p><p>
+ There are functions in the backend that will double-quote their own output
+ as needed (for example, <code class="function">format_type_be()</code>). Do not put
+ additional quotes around the output of such functions.
+ </p><p>
+ Rationale: Objects can have names that create ambiguity when embedded in a
+ message. Be consistent about denoting where a plugged-in name starts and
+ ends. But don't clutter messages with unnecessary or duplicate quote
+ marks.
+ </p></div><div class="simplesect" id="id-1.10.7.4.7"><div class="titlepage"><div><div><h3 class="title">Grammar and Punctuation</h3></div></div></div><p>
+ The rules are different for primary error messages and for detail/hint
+ messages:
+ </p><p>
+ Primary error messages: Do not capitalize the first letter. Do not end a
+ message with a period. Do not even think about ending a message with an
+ exclamation point.
+ </p><p>
+ Detail and hint messages: Use complete sentences, and end each with
+ a period. Capitalize the first word of sentences. Put two spaces after
+ the period if another sentence follows (for English text; might be
+ inappropriate in other languages).
+ </p><p>
+ Error context strings: Do not capitalize the first letter and do
+ not end the string with a period. Context strings should normally
+ not be complete sentences.
+ </p><p>
+ Rationale: Avoiding punctuation makes it easier for client applications to
+ embed the message into a variety of grammatical contexts. Often, primary
+ messages are not grammatically complete sentences anyway. (And if they're
+ long enough to be more than one sentence, they should be split into
+ primary and detail parts.) However, detail and hint messages are longer
+ and might need to include multiple sentences. For consistency, they should
+ follow complete-sentence style even when there's only one sentence.
+ </p></div><div class="simplesect" id="id-1.10.7.4.8"><div class="titlepage"><div><div><h3 class="title">Upper Case vs. Lower Case</h3></div></div></div><p>
+ Use lower case for message wording, including the first letter of a
+ primary error message. Use upper case for SQL commands and key words if
+ they appear in the message.
+ </p><p>
+ Rationale: It's easier to make everything look more consistent this
+ way, since some messages are complete sentences and some not.
+ </p></div><div class="simplesect" id="id-1.10.7.4.9"><div class="titlepage"><div><div><h3 class="title">Avoid Passive Voice</h3></div></div></div><p>
+ Use the active voice. Use complete sentences when there is an acting
+ subject (<span class="quote">“<span class="quote">A could not do B</span>”</span>). Use telegram style without
+ subject if the subject would be the program itself; do not use
+ <span class="quote">“<span class="quote">I</span>”</span> for the program.
+ </p><p>
+ Rationale: The program is not human. Don't pretend otherwise.
+ </p></div><div class="simplesect" id="id-1.10.7.4.10"><div class="titlepage"><div><div><h3 class="title">Present vs. Past Tense</h3></div></div></div><p>
+ Use past tense if an attempt to do something failed, but could perhaps
+ succeed next time (perhaps after fixing some problem). Use present tense
+ if the failure is certainly permanent.
+ </p><p>
+ There is a nontrivial semantic difference between sentences of the form:
+</p><pre class="programlisting">
+could not open file "%s": %m
+</pre><p>
+and:
+</p><pre class="programlisting">
+cannot open file "%s"
+</pre><p>
+ The first one means that the attempt to open the file failed. The
+ message should give a reason, such as <span class="quote">“<span class="quote">disk full</span>”</span> or
+ <span class="quote">“<span class="quote">file doesn't exist</span>”</span>. The past tense is appropriate because
+ next time the disk might not be full anymore or the file in question might
+ exist.
+ </p><p>
+ The second form indicates that the functionality of opening the named file
+ does not exist at all in the program, or that it's conceptually
+ impossible. The present tense is appropriate because the condition will
+ persist indefinitely.
+ </p><p>
+ Rationale: Granted, the average user will not be able to draw great
+ conclusions merely from the tense of the message, but since the language
+ provides us with a grammar we should use it correctly.
+ </p></div><div class="simplesect" id="id-1.10.7.4.11"><div class="titlepage"><div><div><h3 class="title">Type of the Object</h3></div></div></div><p>
+ When citing the name of an object, state what kind of object it is.
+ </p><p>
+ Rationale: Otherwise no one will know what <span class="quote">“<span class="quote">foo.bar.baz</span>”</span>
+ refers to.
+ </p></div><div class="simplesect" id="id-1.10.7.4.12"><div class="titlepage"><div><div><h3 class="title">Brackets</h3></div></div></div><p>
+ Square brackets are only to be used (1) in command synopses to denote
+ optional arguments, or (2) to denote an array subscript.
+ </p><p>
+ Rationale: Anything else does not correspond to widely-known customary
+ usage and will confuse people.
+ </p></div><div class="simplesect" id="id-1.10.7.4.13"><div class="titlepage"><div><div><h3 class="title">Assembling Error Messages</h3></div></div></div><p>
+ When a message includes text that is generated elsewhere, embed it in
+ this style:
+</p><pre class="programlisting">
+could not open file %s: %m
+</pre><p>
+ </p><p>
+ Rationale: It would be difficult to account for all possible error codes
+ to paste this into a single smooth sentence, so some sort of punctuation
+ is needed. Putting the embedded text in parentheses has also been
+ suggested, but it's unnatural if the embedded text is likely to be the
+ most important part of the message, as is often the case.
+ </p></div><div class="simplesect" id="id-1.10.7.4.14"><div class="titlepage"><div><div><h3 class="title">Reasons for Errors</h3></div></div></div><p>
+ Messages should always state the reason why an error occurred.
+ For example:
+</p><pre class="programlisting">
+BAD: could not open file %s
+BETTER: could not open file %s (I/O failure)
+</pre><p>
+ If no reason is known you better fix the code.
+ </p></div><div class="simplesect" id="id-1.10.7.4.15"><div class="titlepage"><div><div><h3 class="title">Function Names</h3></div></div></div><p>
+ Don't include the name of the reporting routine in the error text. We have
+ other mechanisms for finding that out when needed, and for most users it's
+ not helpful information. If the error text doesn't make as much sense
+ without the function name, reword it.
+</p><pre class="programlisting">
+BAD: pg_strtoint32: error in "z": cannot parse "z"
+BETTER: invalid input syntax for type integer: "z"
+</pre><p>
+ </p><p>
+ Avoid mentioning called function names, either; instead say what the code
+ was trying to do:
+</p><pre class="programlisting">
+BAD: open() failed: %m
+BETTER: could not open file %s: %m
+</pre><p>
+ If it really seems necessary, mention the system call in the detail
+ message. (In some cases, providing the actual values passed to the
+ system call might be appropriate information for the detail message.)
+ </p><p>
+ Rationale: Users don't know what all those functions do.
+ </p></div><div class="simplesect" id="id-1.10.7.4.16"><div class="titlepage"><div><div><h3 class="title">Tricky Words to Avoid</h3></div></div></div><p><strong>Unable. </strong>
+ <span class="quote">“<span class="quote">Unable</span>”</span> is nearly the passive voice. Better use
+ <span class="quote">“<span class="quote">cannot</span>”</span> or <span class="quote">“<span class="quote">could not</span>”</span>, as appropriate.
+ </p><p><strong>Bad. </strong>
+ Error messages like <span class="quote">“<span class="quote">bad result</span>”</span> are really hard to interpret
+ intelligently. It's better to write why the result is <span class="quote">“<span class="quote">bad</span>”</span>,
+ e.g., <span class="quote">“<span class="quote">invalid format</span>”</span>.
+ </p><p><strong>Illegal. </strong>
+ <span class="quote">“<span class="quote">Illegal</span>”</span> stands for a violation of the law, the rest is
+ <span class="quote">“<span class="quote">invalid</span>”</span>. Better yet, say why it's invalid.
+ </p><p><strong>Unknown. </strong>
+ Try to avoid <span class="quote">“<span class="quote">unknown</span>”</span>. Consider <span class="quote">“<span class="quote">error: unknown
+ response</span>”</span>. If you don't know what the response is, how do you know
+ it's erroneous? <span class="quote">“<span class="quote">Unrecognized</span>”</span> is often a better choice.
+ Also, be sure to include the value being complained of.
+</p><pre class="programlisting">
+BAD: unknown node type
+BETTER: unrecognized node type: 42
+</pre><p>
+ </p><p><strong>Find vs. Exists. </strong>
+ If the program uses a nontrivial algorithm to locate a resource (e.g., a
+ path search) and that algorithm fails, it is fair to say that the program
+ couldn't <span class="quote">“<span class="quote">find</span>”</span> the resource. If, on the other hand, the
+ expected location of the resource is known but the program cannot access
+ it there then say that the resource doesn't <span class="quote">“<span class="quote">exist</span>”</span>. Using
+ <span class="quote">“<span class="quote">find</span>”</span> in this case sounds weak and confuses the issue.
+ </p><p><strong>May vs. Can vs. Might. </strong>
+ <span class="quote">“<span class="quote">May</span>”</span> suggests permission (e.g., "You may borrow my rake."),
+ and has little use in documentation or error messages.
+ <span class="quote">“<span class="quote">Can</span>”</span> suggests ability (e.g., "I can lift that log."),
+ and <span class="quote">“<span class="quote">might</span>”</span> suggests possibility (e.g., "It might rain
+ today."). Using the proper word clarifies meaning and assists
+ translation.
+ </p><p><strong>Contractions. </strong>
+ Avoid contractions, like <span class="quote">“<span class="quote">can't</span>”</span>; use
+ <span class="quote">“<span class="quote">cannot</span>”</span> instead.
+ </p><p><strong>Non-negative. </strong>
+ Avoid <span class="quote">“<span class="quote">non-negative</span>”</span> as it is ambiguous
+ about whether it accepts zero. It's better to use
+ <span class="quote">“<span class="quote">greater than zero</span>”</span> or
+ <span class="quote">“<span class="quote">greater than or equal to zero</span>”</span>.
+ </p></div><div class="simplesect" id="id-1.10.7.4.17"><div class="titlepage"><div><div><h3 class="title">Proper Spelling</h3></div></div></div><p>
+ Spell out words in full. For instance, avoid:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ spec
+ </p></li><li class="listitem"><p>
+ stats
+ </p></li><li class="listitem"><p>
+ parens
+ </p></li><li class="listitem"><p>
+ auth
+ </p></li><li class="listitem"><p>
+ xact
+ </p></li></ul></div><p>
+ </p><p>
+ Rationale: This will improve consistency.
+ </p></div><div class="simplesect" id="id-1.10.7.4.18"><div class="titlepage"><div><div><h3 class="title">Localization</h3></div></div></div><p>
+ Keep in mind that error message texts need to be translated into other
+ languages. Follow the guidelines in <a class="xref" href="nls-programmer.html#NLS-GUIDELINES" title="57.2.2. Message-Writing Guidelines">Section 57.2.2</a>
+ to avoid making life difficult for translators.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="error-message-reporting.html" title="56.2. Reporting Errors Within the Server">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="source-conventions.html" title="56.4. Miscellaneous Coding Conventions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">56.2. Reporting Errors Within the Server </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 56.4. Miscellaneous Coding Conventions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-log-registration.html b/doc/src/sgml/html/event-log-registration.html
new file mode 100644
index 0000000..1a41eb1
--- /dev/null
+++ b/doc/src/sgml/html/event-log-registration.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.12. Registering Event Log on Windows</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ssh-tunnels.html" title="19.11. Secure TCP/IP Connections with SSH Tunnels" /><link rel="next" href="runtime-config.html" title="Chapter 20. Server Configuration" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.12. Registering <span class="application">Event Log</span> on <span class="systemitem">Windows</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ssh-tunnels.html" title="19.11. Secure TCP/IP Connections with SSH Tunnels">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config.html" title="Chapter 20. Server Configuration">Next</a></td></tr></table><hr /></div><div class="sect1" id="EVENT-LOG-REGISTRATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.12. Registering <span class="application">Event Log</span> on <span class="systemitem">Windows</span></h2></div></div></div><a id="id-1.6.6.15.2" class="indexterm"></a><p>
+ To register a <span class="systemitem">Windows</span>
+ <span class="application">event log</span> library with the operating system,
+ issue this command:
+</p><pre class="screen">
+<strong class="userinput"><code>regsvr32 <em class="replaceable"><code>pgsql_library_directory</code></em>/pgevent.dll</code></strong>
+</pre><p>
+ This creates registry entries used by the event viewer, under the default
+ event source named <code class="literal">PostgreSQL</code>.
+ </p><p>
+ To specify a different event source name (see
+ <a class="xref" href="runtime-config-logging.html#GUC-EVENT-SOURCE">event_source</a>), use the <code class="literal">/n</code>
+ and <code class="literal">/i</code> options:
+</p><pre class="screen">
+<strong class="userinput"><code>regsvr32 /n /i:<em class="replaceable"><code>event_source_name</code></em> <em class="replaceable"><code>pgsql_library_directory</code></em>/pgevent.dll</code></strong>
+</pre><p>
+ </p><p>
+ To unregister the <span class="application">event log</span> library from
+ the operating system, issue this command:
+</p><pre class="screen">
+<strong class="userinput"><code>regsvr32 /u [/i:<em class="replaceable"><code>event_source_name</code></em>] <em class="replaceable"><code>pgsql_library_directory</code></em>/pgevent.dll</code></strong>
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ To enable event logging in the database server, modify
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-DESTINATION">log_destination</a> to include
+ <code class="literal">eventlog</code> in <code class="filename">postgresql.conf</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ssh-tunnels.html" title="19.11. Secure TCP/IP Connections with SSH Tunnels">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config.html" title="Chapter 20. Server Configuration">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.11. Secure TCP/IP Connections with <span class="application">SSH</span> Tunnels </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 20. Server Configuration</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-trigger-definition.html b/doc/src/sgml/html/event-trigger-definition.html
new file mode 100644
index 0000000..e5b1562
--- /dev/null
+++ b/doc/src/sgml/html/event-trigger-definition.html
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>40.1. Overview of Event Trigger Behavior</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-triggers.html" title="Chapter 40. Event Triggers" /><link rel="next" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">40.1. Overview of Event Trigger Behavior</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-triggers.html" title="Chapter 40. Event Triggers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><th width="60%" align="center">Chapter 40. Event Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix">Next</a></td></tr></table><hr /></div><div class="sect1" id="EVENT-TRIGGER-DEFINITION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">40.1. Overview of Event Trigger Behavior</h2></div></div></div><p>
+ An event trigger fires whenever the event with which it is associated
+ occurs in the database in which it is defined. Currently, the only
+ supported events are
+ <code class="literal">ddl_command_start</code>,
+ <code class="literal">ddl_command_end</code>,
+ <code class="literal">table_rewrite</code>
+ and <code class="literal">sql_drop</code>.
+ Support for additional events may be added in future releases.
+ </p><p>
+ The <code class="literal">ddl_command_start</code> event occurs just before the
+ execution of a <code class="literal">CREATE</code>, <code class="literal">ALTER</code>, <code class="literal">DROP</code>,
+ <code class="literal">SECURITY LABEL</code>,
+ <code class="literal">COMMENT</code>, <code class="literal">GRANT</code> or <code class="literal">REVOKE</code>
+ command. No check whether the affected object exists or doesn't exist is
+ performed before the event trigger fires.
+ As an exception, however, this event does not occur for
+ DDL commands targeting shared objects — databases, roles, and tablespaces
+ — or for commands targeting event triggers themselves. The event trigger
+ mechanism does not support these object types.
+ <code class="literal">ddl_command_start</code> also occurs just before the execution of a
+ <code class="literal">SELECT INTO</code> command, since this is equivalent to
+ <code class="literal">CREATE TABLE AS</code>.
+ </p><p>
+ The <code class="literal">ddl_command_end</code> event occurs just after the execution of
+ this same set of commands. To obtain more details on the <acronym class="acronym">DDL</acronym>
+ operations that took place, use the set-returning function
+ <code class="literal">pg_event_trigger_ddl_commands()</code> from the
+ <code class="literal">ddl_command_end</code> event trigger code (see
+ <a class="xref" href="functions-event-triggers.html" title="9.29. Event Trigger Functions">Section 9.29</a>). Note that the trigger fires
+ after the actions have taken place (but before the transaction commits),
+ and thus the system catalogs can be read as already changed.
+ </p><p>
+ The <code class="literal">sql_drop</code> event occurs just before the
+ <code class="literal">ddl_command_end</code> event trigger for any operation that drops
+ database objects. To list the objects that have been dropped, use the
+ set-returning function <code class="literal">pg_event_trigger_dropped_objects()</code> from the
+ <code class="literal">sql_drop</code> event trigger code (see
+ <a class="xref" href="functions-event-triggers.html" title="9.29. Event Trigger Functions">Section 9.29</a>). Note that
+ the trigger is executed after the objects have been deleted from the
+ system catalogs, so it's not possible to look them up anymore.
+ </p><p>
+ The <code class="literal">table_rewrite</code> event occurs just before a table is
+ rewritten by some actions of the commands <code class="literal">ALTER TABLE</code> and
+ <code class="literal">ALTER TYPE</code>. While other
+ control statements are available to rewrite a table,
+ like <code class="literal">CLUSTER</code> and <code class="literal">VACUUM</code>,
+ the <code class="literal">table_rewrite</code> event is not triggered by them.
+ </p><p>
+ Event triggers (like other functions) cannot be executed in an aborted
+ transaction. Thus, if a DDL command fails with an error, any associated
+ <code class="literal">ddl_command_end</code> triggers will not be executed. Conversely,
+ if a <code class="literal">ddl_command_start</code> trigger fails with an error, no
+ further event triggers will fire, and no attempt will be made to execute
+ the command itself. Similarly, if a <code class="literal">ddl_command_end</code> trigger
+ fails with an error, the effects of the DDL statement will be rolled
+ back, just as they would be in any other case where the containing
+ transaction aborts.
+ </p><p>
+ For a complete list of commands supported by the event trigger mechanism,
+ see <a class="xref" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix">Section 40.2</a>.
+ </p><p>
+ Event triggers are created using the command <a class="xref" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER"><span class="refentrytitle">CREATE EVENT TRIGGER</span></a>.
+ In order to create an event trigger, you must first create a function with
+ the special return type <code class="literal">event_trigger</code>. This function
+ need not (and may not) return a value; the return type serves merely as
+ a signal that the function is to be invoked as an event trigger.
+ </p><p>
+ If more than one event trigger is defined for a particular event, they will
+ fire in alphabetical order by trigger name.
+ </p><p>
+ A trigger definition can also specify a <code class="literal">WHEN</code>
+ condition so that, for example, a <code class="literal">ddl_command_start</code>
+ trigger can be fired only for particular commands which the user wishes
+ to intercept. A common use of such triggers is to restrict the range of
+ DDL operations which users may perform.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-triggers.html" title="Chapter 40. Event Triggers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 40. Event Triggers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 40.2. Event Trigger Firing Matrix</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-trigger-example.html b/doc/src/sgml/html/event-trigger-example.html
new file mode 100644
index 0000000..6f863fe
--- /dev/null
+++ b/doc/src/sgml/html/event-trigger-example.html
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>40.4. A Complete Event Trigger Example</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-trigger-interface.html" title="40.3. Writing Event Trigger Functions in C" /><link rel="next" href="event-trigger-table-rewrite-example.html" title="40.5. A Table Rewrite Event Trigger Example" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">40.4. A Complete Event Trigger Example</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-trigger-interface.html" title="40.3. Writing Event Trigger Functions in C">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><th width="60%" align="center">Chapter 40. Event Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-trigger-table-rewrite-example.html" title="40.5. A Table Rewrite Event Trigger Example">Next</a></td></tr></table><hr /></div><div class="sect1" id="EVENT-TRIGGER-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">40.4. A Complete Event Trigger Example</h2></div></div></div><p>
+ Here is a very simple example of an event trigger function written in C.
+ (Examples of triggers written in procedural languages can be found in
+ the documentation of the procedural languages.)
+ </p><p>
+ The function <code class="function">noddl</code> raises an exception each time it is called.
+ The event trigger definition associated the function with
+ the <code class="literal">ddl_command_start</code> event. The effect is that all DDL
+ commands (with the exceptions mentioned
+ in <a class="xref" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Section 40.1</a>) are prevented from running.
+ </p><p>
+ This is the source code of the trigger function:
+</p><pre class="programlisting">
+#include "postgres.h"
+#include "commands/event_trigger.h"
+
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(noddl);
+
+Datum
+noddl(PG_FUNCTION_ARGS)
+{
+ EventTriggerData *trigdata;
+
+ if (!CALLED_AS_EVENT_TRIGGER(fcinfo)) /* internal error */
+ elog(ERROR, "not fired by event trigger manager");
+
+ trigdata = (EventTriggerData *) fcinfo-&gt;context;
+
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("command \"%s\" denied",
+ GetCommandTagName(trigdata-&gt;tag))));
+
+ PG_RETURN_NULL();
+}
+</pre><p>
+ </p><p>
+ After you have compiled the source code (see <a class="xref" href="xfunc-c.html#DFUNC" title="38.10.5. Compiling and Linking Dynamically-Loaded Functions">Section 38.10.5</a>),
+ declare the function and the triggers:
+</p><pre class="programlisting">
+CREATE FUNCTION noddl() RETURNS event_trigger
+ AS 'noddl' LANGUAGE C;
+
+CREATE EVENT TRIGGER noddl ON ddl_command_start
+ EXECUTE FUNCTION noddl();
+</pre><p>
+ </p><p>
+ Now you can test the operation of the trigger:
+</p><pre class="screen">
+=# \dy
+ List of event triggers
+ Name | Event | Owner | Enabled | Function | Tags
+-------+-------------------+-------+---------+----------+------
+ noddl | ddl_command_start | dim | enabled | noddl |
+(1 row)
+
+=# CREATE TABLE foo(id serial);
+ERROR: command "CREATE TABLE" denied
+</pre><p>
+ </p><p>
+ In this situation, in order to be able to run some DDL commands when you
+ need to do so, you have to either drop the event trigger or disable it. It
+ can be convenient to disable the trigger for only the duration of a
+ transaction:
+</p><pre class="programlisting">
+BEGIN;
+ALTER EVENT TRIGGER noddl DISABLE;
+CREATE TABLE foo (id serial);
+ALTER EVENT TRIGGER noddl ENABLE;
+COMMIT;
+</pre><p>
+ (Recall that DDL commands on event triggers themselves are not affected by
+ event triggers.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-trigger-interface.html" title="40.3. Writing Event Trigger Functions in C">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-trigger-table-rewrite-example.html" title="40.5. A Table Rewrite Event Trigger Example">Next</a></td></tr><tr><td width="40%" align="left" valign="top">40.3. Writing Event Trigger Functions in C </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 40.5. A Table Rewrite Event Trigger Example</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-trigger-interface.html b/doc/src/sgml/html/event-trigger-interface.html
new file mode 100644
index 0000000..a99e3eb
--- /dev/null
+++ b/doc/src/sgml/html/event-trigger-interface.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>40.3. Writing Event Trigger Functions in C</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix" /><link rel="next" href="event-trigger-example.html" title="40.4. A Complete Event Trigger Example" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">40.3. Writing Event Trigger Functions in C</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><th width="60%" align="center">Chapter 40. Event Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-trigger-example.html" title="40.4. A Complete Event Trigger Example">Next</a></td></tr></table><hr /></div><div class="sect1" id="EVENT-TRIGGER-INTERFACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">40.3. Writing Event Trigger Functions in C</h2></div></div></div><a id="id-1.8.5.7.2" class="indexterm"></a><p>
+ This section describes the low-level details of the interface to an
+ event trigger function. This information is only needed when writing
+ event trigger functions in C. If you are using a higher-level language
+ then these details are handled for you. In most cases you should
+ consider using a procedural language before writing your event triggers
+ in C. The documentation of each procedural language explains how to
+ write an event trigger in that language.
+ </p><p>
+ Event trigger functions must use the <span class="quote">“<span class="quote">version 1</span>”</span> function
+ manager interface.
+ </p><p>
+ When a function is called by the event trigger manager, it is not passed
+ any normal arguments, but it is passed a <span class="quote">“<span class="quote">context</span>”</span> pointer
+ pointing to a <code class="structname">EventTriggerData</code> structure. C functions can
+ check whether they were called from the event trigger manager or not by
+ executing the macro:
+</p><pre class="programlisting">
+CALLED_AS_EVENT_TRIGGER(fcinfo)
+</pre><p>
+ which expands to:
+</p><pre class="programlisting">
+((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, EventTriggerData))
+</pre><p>
+ If this returns true, then it is safe to cast
+ <code class="literal">fcinfo-&gt;context</code> to type <code class="literal">EventTriggerData
+ *</code> and make use of the pointed-to
+ <code class="structname">EventTriggerData</code> structure. The function must
+ <span class="emphasis"><em>not</em></span> alter the <code class="structname">EventTriggerData</code>
+ structure or any of the data it points to.
+ </p><p>
+ <code class="structname">struct EventTriggerData</code> is defined in
+ <code class="filename">commands/event_trigger.h</code>:
+
+</p><pre class="programlisting">
+typedef struct EventTriggerData
+{
+ NodeTag type;
+ const char *event; /* event name */
+ Node *parsetree; /* parse tree */
+ CommandTag tag; /* command tag */
+} EventTriggerData;
+</pre><p>
+
+ where the members are defined as follows:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="structfield">type</code></span></dt><dd><p>
+ Always <code class="literal">T_EventTriggerData</code>.
+ </p></dd><dt><span class="term"><code class="structfield">event</code></span></dt><dd><p>
+ Describes the event for which the function is called, one of
+ <code class="literal">"ddl_command_start"</code>, <code class="literal">"ddl_command_end"</code>,
+ <code class="literal">"sql_drop"</code>, <code class="literal">"table_rewrite"</code>.
+ See <a class="xref" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Section 40.1</a> for the meaning of these
+ events.
+ </p></dd><dt><span class="term"><code class="structfield">parsetree</code></span></dt><dd><p>
+ A pointer to the parse tree of the command. Check the PostgreSQL
+ source code for details. The parse tree structure is subject to change
+ without notice.
+ </p></dd><dt><span class="term"><code class="structfield">tag</code></span></dt><dd><p>
+ The command tag associated with the event for which the event trigger
+ is run, for example <code class="literal">"CREATE FUNCTION"</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ An event trigger function must return a <code class="symbol">NULL</code> pointer
+ (<span class="emphasis"><em>not</em></span> an SQL null value, that is, do not
+ set <em class="parameter"><code>isNull</code></em> true).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-trigger-matrix.html" title="40.2. Event Trigger Firing Matrix">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-trigger-example.html" title="40.4. A Complete Event Trigger Example">Next</a></td></tr><tr><td width="40%" align="left" valign="top">40.2. Event Trigger Firing Matrix </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 40.4. A Complete Event Trigger Example</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-trigger-matrix.html b/doc/src/sgml/html/event-trigger-matrix.html
new file mode 100644
index 0000000..3e07479
--- /dev/null
+++ b/doc/src/sgml/html/event-trigger-matrix.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>40.2. Event Trigger Firing Matrix</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior" /><link rel="next" href="event-trigger-interface.html" title="40.3. Writing Event Trigger Functions in C" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">40.2. Event Trigger Firing Matrix</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><th width="60%" align="center">Chapter 40. Event Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-trigger-interface.html" title="40.3. Writing Event Trigger Functions in C">Next</a></td></tr></table><hr /></div><div class="sect1" id="EVENT-TRIGGER-MATRIX"><div class="titlepage"><div><div><h2 class="title" style="clear: both">40.2. Event Trigger Firing Matrix</h2></div></div></div><p>
+ <a class="xref" href="event-trigger-matrix.html#EVENT-TRIGGER-BY-COMMAND-TAG" title="Table 40.1. Event Trigger Support by Command Tag">Table 40.1</a> lists all commands
+ for which event triggers are supported.
+ </p><div class="table" id="EVENT-TRIGGER-BY-COMMAND-TAG"><p class="title"><strong>Table 40.1. Event Trigger Support by Command Tag</strong></p><div class="table-contents"><table class="table" summary="Event Trigger Support by Command Tag" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /><col class="col6" /></colgroup><thead><tr><th>Command Tag</th><th><code class="literal">ddl_​command_​start</code></th><th><code class="literal">ddl_​command_​end</code></th><th><code class="literal">sql_​drop</code></th><th><code class="literal">table_​rewrite</code></th><th>Notes</th></tr></thead><tbody><tr><td align="left"><code class="literal">ALTER AGGREGATE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER COLLATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER CONVERSION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER DOMAIN</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER DEFAULT PRIVILEGES</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER EXTENSION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER FOREIGN DATA WRAPPER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER FOREIGN TABLE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER FUNCTION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER LANGUAGE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER LARGE OBJECT</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER MATERIALIZED VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">X</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER OPERATOR</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER OPERATOR CLASS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER OPERATOR FAMILY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER POLICY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER PROCEDURE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER PUBLICATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER ROUTINE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER SCHEMA</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER SEQUENCE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER SERVER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER STATISTICS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER SUBSCRIPTION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TABLE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TEXT SEARCH CONFIGURATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TEXT SEARCH DICTIONARY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TEXT SEARCH PARSER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TEXT SEARCH TEMPLATE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TRIGGER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER TYPE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">X</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER USER MAPPING</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">ALTER VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">COMMENT</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left">Only for local objects</td></tr><tr><td align="left"><code class="literal">CREATE ACCESS METHOD</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE AGGREGATE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE CAST</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE COLLATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE CONVERSION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE DOMAIN</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE EXTENSION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE FOREIGN DATA WRAPPER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE FOREIGN TABLE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE FUNCTION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE INDEX</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE LANGUAGE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE MATERIALIZED VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE OPERATOR</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE OPERATOR CLASS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE OPERATOR FAMILY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE POLICY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE PROCEDURE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE PUBLICATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE RULE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE SCHEMA</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE SEQUENCE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE SERVER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE STATISTICS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE SUBSCRIPTION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TABLE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TABLE AS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TEXT SEARCH CONFIGURATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TEXT SEARCH DICTIONARY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TEXT SEARCH PARSER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TEXT SEARCH TEMPLATE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TRIGGER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE TYPE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE USER MAPPING</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">CREATE VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP ACCESS METHOD</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP AGGREGATE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP CAST</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP COLLATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP CONVERSION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP DOMAIN</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP EXTENSION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP FOREIGN DATA WRAPPER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP FOREIGN TABLE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP FUNCTION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP INDEX</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP LANGUAGE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP MATERIALIZED VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP OPERATOR</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP OPERATOR CLASS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP OPERATOR FAMILY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP OWNED</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP POLICY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP PROCEDURE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP PUBLICATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP ROUTINE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP RULE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP SCHEMA</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP SEQUENCE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP SERVER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP STATISTICS</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP SUBSCRIPTION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TABLE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TEXT SEARCH CONFIGURATION</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TEXT SEARCH DICTIONARY</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TEXT SEARCH PARSER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TEXT SEARCH TEMPLATE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TRIGGER</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP TYPE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP USER MAPPING</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">DROP VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">GRANT</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left">Only for local objects</td></tr><tr><td align="left"><code class="literal">IMPORT FOREIGN SCHEMA</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">REFRESH MATERIALIZED VIEW</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr><tr><td align="left"><code class="literal">REVOKE</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left">Only for local objects</td></tr><tr><td align="left"><code class="literal">SECURITY LABEL</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left">Only for local objects</td></tr><tr><td align="left"><code class="literal">SELECT INTO</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">X</code></td><td align="center"><code class="literal">-</code></td><td align="center"><code class="literal">-</code></td><td align="left"> </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-trigger-interface.html" title="40.3. Writing Event Trigger Functions in C">Next</a></td></tr><tr><td width="40%" align="left" valign="top">40.1. Overview of Event Trigger Behavior </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 40.3. Writing Event Trigger Functions in C</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-trigger-table-rewrite-example.html b/doc/src/sgml/html/event-trigger-table-rewrite-example.html
new file mode 100644
index 0000000..642696a
--- /dev/null
+++ b/doc/src/sgml/html/event-trigger-table-rewrite-example.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>40.5. A Table Rewrite Event Trigger Example</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-trigger-example.html" title="40.4. A Complete Event Trigger Example" /><link rel="next" href="rules.html" title="Chapter 41. The Rule System" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">40.5. A Table Rewrite Event Trigger Example</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-trigger-example.html" title="40.4. A Complete Event Trigger Example">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><th width="60%" align="center">Chapter 40. Event Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules.html" title="Chapter 41. The Rule System">Next</a></td></tr></table><hr /></div><div class="sect1" id="EVENT-TRIGGER-TABLE-REWRITE-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">40.5. A Table Rewrite Event Trigger Example</h2></div></div></div><p>
+ Thanks to the <code class="literal">table_rewrite</code> event, it is possible to implement
+ a table rewriting policy only allowing the rewrite in maintenance windows.
+ </p><p>
+ Here's an example implementing such a policy.
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION no_rewrite()
+ RETURNS event_trigger
+ LANGUAGE plpgsql AS
+$$
+---
+--- Implement local Table Rewriting policy:
+--- public.foo is not allowed rewriting, ever
+--- other tables are only allowed rewriting between 1am and 6am
+--- unless they have more than 100 blocks
+---
+DECLARE
+ table_oid oid := pg_event_trigger_table_rewrite_oid();
+ current_hour integer := extract('hour' from current_time);
+ pages integer;
+ max_pages integer := 100;
+BEGIN
+ IF pg_event_trigger_table_rewrite_oid() = 'public.foo'::regclass
+ THEN
+ RAISE EXCEPTION 'you''re not allowed to rewrite the table %',
+ table_oid::regclass;
+ END IF;
+
+ SELECT INTO pages relpages FROM pg_class WHERE oid = table_oid;
+ IF pages &gt; max_pages
+ THEN
+ RAISE EXCEPTION 'rewrites only allowed for table with less than % pages',
+ max_pages;
+ END IF;
+
+ IF current_hour NOT BETWEEN 1 AND 6
+ THEN
+ RAISE EXCEPTION 'rewrites only allowed between 1am and 6am';
+ END IF;
+END;
+$$;
+
+CREATE EVENT TRIGGER no_rewrite_allowed
+ ON table_rewrite
+ EXECUTE FUNCTION no_rewrite();
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-trigger-example.html" title="40.4. A Complete Event Trigger Example">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="event-triggers.html" title="Chapter 40. Event Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules.html" title="Chapter 41. The Rule System">Next</a></td></tr><tr><td width="40%" align="left" valign="top">40.4. A Complete Event Trigger Example </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 41. The Rule System</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/event-triggers.html b/doc/src/sgml/html/event-triggers.html
new file mode 100644
index 0000000..0255947
--- /dev/null
+++ b/doc/src/sgml/html/event-triggers.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 40. Event Triggers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="trigger-example.html" title="39.4. A Complete Trigger Example" /><link rel="next" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 40. Event Triggers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="trigger-example.html" title="39.4. A Complete Trigger Example">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Next</a></td></tr></table><hr /></div><div class="chapter" id="EVENT-TRIGGERS"><div class="titlepage"><div><div><h2 class="title">Chapter 40. Event Triggers</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="event-trigger-definition.html">40.1. Overview of Event Trigger Behavior</a></span></dt><dt><span class="sect1"><a href="event-trigger-matrix.html">40.2. Event Trigger Firing Matrix</a></span></dt><dt><span class="sect1"><a href="event-trigger-interface.html">40.3. Writing Event Trigger Functions in C</a></span></dt><dt><span class="sect1"><a href="event-trigger-example.html">40.4. A Complete Event Trigger Example</a></span></dt><dt><span class="sect1"><a href="event-trigger-table-rewrite-example.html">40.5. A Table Rewrite Event Trigger Example</a></span></dt></dl></div><a id="id-1.8.5.2" class="indexterm"></a><p>
+ To supplement the trigger mechanism discussed in <a class="xref" href="triggers.html" title="Chapter 39. Triggers">Chapter 39</a>,
+ <span class="productname">PostgreSQL</span> also provides event triggers. Unlike regular
+ triggers, which are attached to a single table and capture only DML events,
+ event triggers are global to a particular database and are capable of
+ capturing DDL events.
+ </p><p>
+ Like regular triggers, event triggers can be written in any procedural
+ language that includes event trigger support, or in C, but not in plain
+ SQL.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="trigger-example.html" title="39.4. A Complete Trigger Example">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Next</a></td></tr><tr><td width="40%" align="left" valign="top">39.4. A Complete Trigger Example </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 40.1. Overview of Event Trigger Behavior</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/executor.html b/doc/src/sgml/html/executor.html
new file mode 100644
index 0000000..bd8ea65
--- /dev/null
+++ b/doc/src/sgml/html/executor.html
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>52.6. Executor</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="planner-optimizer.html" title="52.5. Planner/Optimizer" /><link rel="next" href="catalogs.html" title="Chapter 53. System Catalogs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">52.6. Executor</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="planner-optimizer.html" title="52.5. Planner/Optimizer">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><th width="60%" align="center">Chapter 52. Overview of PostgreSQL Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="catalogs.html" title="Chapter 53. System Catalogs">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXECUTOR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">52.6. Executor</h2></div></div></div><p>
+ The <em class="firstterm">executor</em> takes the plan created by the
+ planner/optimizer and recursively processes it to extract the required set
+ of rows. This is essentially a demand-pull pipeline mechanism.
+ Each time a plan node is called, it must deliver one more row, or
+ report that it is done delivering rows.
+ </p><p>
+ To provide a concrete example, assume that the top
+ node is a <code class="literal">MergeJoin</code> node.
+ Before any merge can be done two rows have to be fetched (one from
+ each subplan). So the executor recursively calls itself to
+ process the subplans (it starts with the subplan attached to
+ <code class="literal">lefttree</code>). The new top node (the top node of the left
+ subplan) is, let's say, a
+ <code class="literal">Sort</code> node and again recursion is needed to obtain
+ an input row. The child node of the <code class="literal">Sort</code> might
+ be a <code class="literal">SeqScan</code> node, representing actual reading of a table.
+ Execution of this node causes the executor to fetch a row from the
+ table and return it up to the calling node. The <code class="literal">Sort</code>
+ node will repeatedly call its child to obtain all the rows to be sorted.
+ When the input is exhausted (as indicated by the child node returning
+ a NULL instead of a row), the <code class="literal">Sort</code> code performs
+ the sort, and finally is able to return its first output row, namely
+ the first one in sorted order. It keeps the remaining rows stored so
+ that it can deliver them in sorted order in response to later demands.
+ </p><p>
+ The <code class="literal">MergeJoin</code> node similarly demands the first row
+ from its right subplan. Then it compares the two rows to see if they
+ can be joined; if so, it returns a join row to its caller. On the next
+ call, or immediately if it cannot join the current pair of inputs,
+ it advances to the next row of one table
+ or the other (depending on how the comparison came out), and again
+ checks for a match. Eventually, one subplan or the other is exhausted,
+ and the <code class="literal">MergeJoin</code> node returns NULL to indicate that
+ no more join rows can be formed.
+ </p><p>
+ Complex queries can involve many levels of plan nodes, but the general
+ approach is the same: each node computes and returns its next output
+ row each time it is called. Each node is also responsible for applying
+ any selection or projection expressions that were assigned to it by
+ the planner.
+ </p><p>
+ The executor mechanism is used to evaluate all five basic SQL query
+ types: <code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, and
+ <code class="command">MERGE</code>.
+ For <code class="command">SELECT</code>, the top-level executor code
+ only needs to send each row returned by the query plan tree
+ off to the client. <code class="command">INSERT ... SELECT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, and
+ <code class="command">MERGE</code>
+ are effectively <code class="command">SELECT</code>s under a special
+ top-level plan node called <code class="literal">ModifyTable</code>.
+ </p><p>
+ <code class="command">INSERT ... SELECT</code> feeds the rows up
+ to <code class="literal">ModifyTable</code> for insertion. For
+ <code class="command">UPDATE</code>, the planner arranges that each
+ computed row includes all the updated column values, plus the
+ <em class="firstterm">TID</em> (tuple ID, or row ID) of the original
+ target row; this data is fed up to the <code class="literal">ModifyTable</code>
+ node, which uses the information to create a new updated row and
+ mark the old row deleted. For <code class="command">DELETE</code>, the only
+ column that is actually returned by the plan is the TID, and the
+ <code class="literal">ModifyTable</code> node simply uses the TID to visit each
+ target row and mark it deleted. For <code class="command">MERGE</code>, the
+ planner joins the source and target relations, and includes all
+ column values required by any of the <code class="literal">WHEN</code> clauses,
+ plus the TID of the target row; this data is fed up to the
+ <code class="literal">ModifyTable</code> node, which uses the information to
+ work out which <code class="literal">WHEN</code> clause to execute, and then
+ inserts, updates or deletes the target row, as required.
+ </p><p>
+ A simple <code class="command">INSERT ... VALUES</code> command creates a
+ trivial plan tree consisting of a single <code class="literal">Result</code>
+ node, which computes just one result row, feeding that up
+ to <code class="literal">ModifyTable</code> to perform the insertion.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="planner-optimizer.html" title="52.5. Planner/Optimizer">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="catalogs.html" title="Chapter 53. System Catalogs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">52.5. Planner/Optimizer </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 53. System Catalogs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/explicit-joins.html b/doc/src/sgml/html/explicit-joins.html
new file mode 100644
index 0000000..705da1a
--- /dev/null
+++ b/doc/src/sgml/html/explicit-joins.html
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>14.3. Controlling the Planner with Explicit JOIN Clauses</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="planner-stats.html" title="14.2. Statistics Used by the Planner" /><link rel="next" href="populate.html" title="14.4. Populating a Database" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">14.3. Controlling the Planner with Explicit <code class="literal">JOIN</code> Clauses</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><th width="60%" align="center">Chapter 14. Performance Tips</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="populate.html" title="14.4. Populating a Database">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXPLICIT-JOINS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">14.3. Controlling the Planner with Explicit <code class="literal">JOIN</code> Clauses</h2></div></div></div><a id="id-1.5.13.6.2" class="indexterm"></a><p>
+ It is possible
+ to control the query planner to some extent by using the explicit <code class="literal">JOIN</code>
+ syntax. To see why this matters, we first need some background.
+ </p><p>
+ In a simple join query, such as:
+</p><pre class="programlisting">
+SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
+</pre><p>
+ the planner is free to join the given tables in any order. For
+ example, it could generate a query plan that joins A to B, using
+ the <code class="literal">WHERE</code> condition <code class="literal">a.id = b.id</code>, and then
+ joins C to this joined table, using the other <code class="literal">WHERE</code>
+ condition. Or it could join B to C and then join A to that result.
+ Or it could join A to C and then join them with B — but that
+ would be inefficient, since the full Cartesian product of A and C
+ would have to be formed, there being no applicable condition in the
+ <code class="literal">WHERE</code> clause to allow optimization of the join. (All
+ joins in the <span class="productname">PostgreSQL</span> executor happen
+ between two input tables, so it's necessary to build up the result
+ in one or another of these fashions.) The important point is that
+ these different join possibilities give semantically equivalent
+ results but might have hugely different execution costs. Therefore,
+ the planner will explore all of them to try to find the most
+ efficient query plan.
+ </p><p>
+ When a query only involves two or three tables, there aren't many join
+ orders to worry about. But the number of possible join orders grows
+ exponentially as the number of tables expands. Beyond ten or so input
+ tables it's no longer practical to do an exhaustive search of all the
+ possibilities, and even for six or seven tables planning might take an
+ annoyingly long time. When there are too many input tables, the
+ <span class="productname">PostgreSQL</span> planner will switch from exhaustive
+ search to a <em class="firstterm">genetic</em> probabilistic search
+ through a limited number of possibilities. (The switch-over threshold is
+ set by the <a class="xref" href="runtime-config-query.html#GUC-GEQO-THRESHOLD">geqo_threshold</a> run-time
+ parameter.)
+ The genetic search takes less time, but it won't
+ necessarily find the best possible plan.
+ </p><p>
+ When the query involves outer joins, the planner has less freedom
+ than it does for plain (inner) joins. For example, consider:
+</p><pre class="programlisting">
+SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
+</pre><p>
+ Although this query's restrictions are superficially similar to the
+ previous example, the semantics are different because a row must be
+ emitted for each row of A that has no matching row in the join of B and C.
+ Therefore the planner has no choice of join order here: it must join
+ B to C and then join A to that result. Accordingly, this query takes
+ less time to plan than the previous query. In other cases, the planner
+ might be able to determine that more than one join order is safe.
+ For example, given:
+</p><pre class="programlisting">
+SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id);
+</pre><p>
+ it is valid to join A to either B or C first. Currently, only
+ <code class="literal">FULL JOIN</code> completely constrains the join order. Most
+ practical cases involving <code class="literal">LEFT JOIN</code> or <code class="literal">RIGHT JOIN</code>
+ can be rearranged to some extent.
+ </p><p>
+ Explicit inner join syntax (<code class="literal">INNER JOIN</code>, <code class="literal">CROSS
+ JOIN</code>, or unadorned <code class="literal">JOIN</code>) is semantically the same as
+ listing the input relations in <code class="literal">FROM</code>, so it does not
+ constrain the join order.
+ </p><p>
+ Even though most kinds of <code class="literal">JOIN</code> don't completely constrain
+ the join order, it is possible to instruct the
+ <span class="productname">PostgreSQL</span> query planner to treat all
+ <code class="literal">JOIN</code> clauses as constraining the join order anyway.
+ For example, these three queries are logically equivalent:
+</p><pre class="programlisting">
+SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
+SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id;
+SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
+</pre><p>
+ But if we tell the planner to honor the <code class="literal">JOIN</code> order,
+ the second and third take less time to plan than the first. This effect
+ is not worth worrying about for only three tables, but it can be a
+ lifesaver with many tables.
+ </p><p>
+ To force the planner to follow the join order laid out by explicit
+ <code class="literal">JOIN</code>s,
+ set the <a class="xref" href="runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT">join_collapse_limit</a> run-time parameter to 1.
+ (Other possible values are discussed below.)
+ </p><p>
+ You do not need to constrain the join order completely in order to
+ cut search time, because it's OK to use <code class="literal">JOIN</code> operators
+ within items of a plain <code class="literal">FROM</code> list. For example, consider:
+</p><pre class="programlisting">
+SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
+</pre><p>
+ With <code class="varname">join_collapse_limit</code> = 1, this
+ forces the planner to join A to B before joining them to other tables,
+ but doesn't constrain its choices otherwise. In this example, the
+ number of possible join orders is reduced by a factor of 5.
+ </p><p>
+ Constraining the planner's search in this way is a useful technique
+ both for reducing planning time and for directing the planner to a
+ good query plan. If the planner chooses a bad join order by default,
+ you can force it to choose a better order via <code class="literal">JOIN</code> syntax
+ — assuming that you know of a better order, that is. Experimentation
+ is recommended.
+ </p><p>
+ A closely related issue that affects planning time is collapsing of
+ subqueries into their parent query. For example, consider:
+</p><pre class="programlisting">
+SELECT *
+FROM x, y,
+ (SELECT * FROM a, b, c WHERE something) AS ss
+WHERE somethingelse;
+</pre><p>
+ This situation might arise from use of a view that contains a join;
+ the view's <code class="literal">SELECT</code> rule will be inserted in place of the view
+ reference, yielding a query much like the above. Normally, the planner
+ will try to collapse the subquery into the parent, yielding:
+</p><pre class="programlisting">
+SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
+</pre><p>
+ This usually results in a better plan than planning the subquery
+ separately. (For example, the outer <code class="literal">WHERE</code> conditions might be such that
+ joining X to A first eliminates many rows of A, thus avoiding the need to
+ form the full logical output of the subquery.) But at the same time,
+ we have increased the planning time; here, we have a five-way join
+ problem replacing two separate three-way join problems. Because of the
+ exponential growth of the number of possibilities, this makes a big
+ difference. The planner tries to avoid getting stuck in huge join search
+ problems by not collapsing a subquery if more than <code class="varname">from_collapse_limit</code>
+ <code class="literal">FROM</code> items would result in the parent
+ query. You can trade off planning time against quality of plan by
+ adjusting this run-time parameter up or down.
+ </p><p>
+ <a class="xref" href="runtime-config-query.html#GUC-FROM-COLLAPSE-LIMIT">from_collapse_limit</a> and <a class="xref" href="runtime-config-query.html#GUC-JOIN-COLLAPSE-LIMIT">join_collapse_limit</a>
+ are similarly named because they do almost the same thing: one controls
+ when the planner will <span class="quote">“<span class="quote">flatten out</span>”</span> subqueries, and the
+ other controls when it will flatten out explicit joins. Typically
+ you would either set <code class="varname">join_collapse_limit</code> equal to
+ <code class="varname">from_collapse_limit</code> (so that explicit joins and subqueries
+ act similarly) or set <code class="varname">join_collapse_limit</code> to 1 (if you want
+ to control join order with explicit joins). But you might set them
+ differently if you are trying to fine-tune the trade-off between planning
+ time and run time.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="populate.html" title="14.4. Populating a Database">Next</a></td></tr><tr><td width="40%" align="left" valign="top">14.2. Statistics Used by the Planner </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 14.4. Populating a Database</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/explicit-locking.html b/doc/src/sgml/html/explicit-locking.html
new file mode 100644
index 0000000..7f029b7
--- /dev/null
+++ b/doc/src/sgml/html/explicit-locking.html
@@ -0,0 +1,396 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.3. Explicit Locking</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="transaction-iso.html" title="13.2. Transaction Isolation" /><link rel="next" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.3. Explicit Locking</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="transaction-iso.html" title="13.2. Transaction Isolation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXPLICIT-LOCKING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.3. Explicit Locking</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-TABLES">13.3.1. Table-Level Locks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-ROWS">13.3.2. Row-Level Locks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-PAGES">13.3.3. Page-Level Locks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-DEADLOCKS">13.3.4. Deadlocks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#ADVISORY-LOCKS">13.3.5. Advisory Locks</a></span></dt></dl></div><a id="id-1.5.12.6.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides various lock modes
+ to control concurrent access to data in tables. These modes can
+ be used for application-controlled locking in situations where
+ <acronym class="acronym">MVCC</acronym> does not give the desired behavior. Also,
+ most <span class="productname">PostgreSQL</span> commands automatically
+ acquire locks of appropriate modes to ensure that referenced
+ tables are not dropped or modified in incompatible ways while the
+ command executes. (For example, <code class="command">TRUNCATE</code> cannot safely be
+ executed concurrently with other operations on the same table, so it
+ obtains an <code class="literal">ACCESS EXCLUSIVE</code> lock on the table to
+ enforce that.)
+ </p><p>
+ To examine a list of the currently outstanding locks in a database
+ server, use the
+ <a class="link" href="view-pg-locks.html" title="54.12. pg_locks"><code class="structname">pg_locks</code></a>
+ system view. For more information on monitoring the status of the lock
+ manager subsystem, refer to <a class="xref" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Chapter 28</a>.
+ </p><div class="sect2" id="LOCKING-TABLES"><div class="titlepage"><div><div><h3 class="title">13.3.1. Table-Level Locks</h3></div></div></div><a id="id-1.5.12.6.5.2" class="indexterm"></a><p>
+ The list below shows the available lock modes and the contexts in
+ which they are used automatically by
+ <span class="productname">PostgreSQL</span>. You can also acquire any
+ of these locks explicitly with the command <a class="xref" href="sql-lock.html" title="LOCK"><span class="refentrytitle">LOCK</span></a>.
+ Remember that all of these lock modes are table-level locks,
+ even if the name contains the word
+ <span class="quote">“<span class="quote">row</span>”</span>; the names of the lock modes are historical.
+ To some extent the names reflect the typical usage of each lock
+ mode — but the semantics are all the same. The only real difference
+ between one lock mode and another is the set of lock modes with
+ which each conflicts (see <a class="xref" href="explicit-locking.html#TABLE-LOCK-COMPATIBILITY" title="Table 13.2. Conflicting Lock Modes">Table 13.2</a>).
+ Two transactions cannot hold locks of conflicting
+ modes on the same table at the same time. (However, a transaction
+ never conflicts with itself. For example, it might acquire
+ <code class="literal">ACCESS EXCLUSIVE</code> lock and later acquire
+ <code class="literal">ACCESS SHARE</code> lock on the same table.) Non-conflicting
+ lock modes can be held concurrently by many transactions. Notice in
+ particular that some lock modes are self-conflicting (for example,
+ an <code class="literal">ACCESS EXCLUSIVE</code> lock cannot be held by more than one
+ transaction at a time) while others are not self-conflicting (for example,
+ an <code class="literal">ACCESS SHARE</code> lock can be held by multiple transactions).
+ </p><div class="variablelist"><p class="title"><strong>Table-Level Lock Modes</strong></p><dl class="variablelist"><dt><span class="term">
+ <code class="literal">ACCESS SHARE</code> (<code class="literal">AccessShareLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">ACCESS EXCLUSIVE</code> lock
+ mode only.
+ </p><p>
+ The <code class="command">SELECT</code> command acquires a lock of this mode on
+ referenced tables. In general, any query that only <span class="emphasis"><em>reads</em></span> a table
+ and does not modify it will acquire this lock mode.
+ </p></dd><dt><span class="term">
+ <code class="literal">ROW SHARE</code> (<code class="literal">RowShareLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">EXCLUSIVE</code> and
+ <code class="literal">ACCESS EXCLUSIVE</code> lock modes.
+ </p><p>
+ The <code class="command">SELECT</code> command acquires a lock of this mode
+ on all tables on which one of the <code class="option">FOR UPDATE</code>,
+ <code class="option">FOR NO KEY UPDATE</code>,
+ <code class="option">FOR SHARE</code>, or
+ <code class="option">FOR KEY SHARE</code> options is specified
+ (in addition to <code class="literal">ACCESS SHARE</code> locks on any other
+ tables that are referenced without any explicit
+ <code class="option">FOR ...</code> locking option).
+ </p></dd><dt><span class="term">
+ <code class="literal">ROW EXCLUSIVE</code> (<code class="literal">RowExclusiveLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">SHARE</code>, <code class="literal">SHARE ROW
+ EXCLUSIVE</code>, <code class="literal">EXCLUSIVE</code>, and
+ <code class="literal">ACCESS EXCLUSIVE</code> lock modes.
+ </p><p>
+ The commands <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">INSERT</code>, and
+ <code class="command">MERGE</code>
+ acquire this lock mode on the target table (in addition to
+ <code class="literal">ACCESS SHARE</code> locks on any other referenced
+ tables). In general, this lock mode will be acquired by any
+ command that <span class="emphasis"><em>modifies data</em></span> in a table.
+ </p></dd><dt><span class="term">
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> (<code class="literal">ShareUpdateExclusiveLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">SHARE UPDATE EXCLUSIVE</code>,
+ <code class="literal">SHARE</code>, <code class="literal">SHARE ROW
+ EXCLUSIVE</code>, <code class="literal">EXCLUSIVE</code>, and
+ <code class="literal">ACCESS EXCLUSIVE</code> lock modes.
+ This mode protects a table against
+ concurrent schema changes and <code class="command">VACUUM</code> runs.
+ </p><p>
+ Acquired by <code class="command">VACUUM</code> (without <code class="option">FULL</code>),
+ <code class="command">ANALYZE</code>, <code class="command">CREATE INDEX CONCURRENTLY</code>,
+ <code class="command">CREATE STATISTICS</code>, <code class="command">COMMENT ON</code>,
+ <code class="command">REINDEX CONCURRENTLY</code>,
+ and certain <a class="link" href="sql-alterindex.html" title="ALTER INDEX"><code class="command">ALTER INDEX</code></a>
+ and <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a> variants
+ (for full details see the documentation of these commands).
+ </p></dd><dt><span class="term">
+ <code class="literal">SHARE</code> (<code class="literal">ShareLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">ROW EXCLUSIVE</code>,
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code>, <code class="literal">SHARE ROW
+ EXCLUSIVE</code>, <code class="literal">EXCLUSIVE</code>, and
+ <code class="literal">ACCESS EXCLUSIVE</code> lock modes.
+ This mode protects a table against concurrent data changes.
+ </p><p>
+ Acquired by <code class="command">CREATE INDEX</code>
+ (without <code class="option">CONCURRENTLY</code>).
+ </p></dd><dt><span class="term">
+ <code class="literal">SHARE ROW EXCLUSIVE</code> (<code class="literal">ShareRowExclusiveLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">ROW EXCLUSIVE</code>,
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code>,
+ <code class="literal">SHARE</code>, <code class="literal">SHARE ROW
+ EXCLUSIVE</code>, <code class="literal">EXCLUSIVE</code>, and
+ <code class="literal">ACCESS EXCLUSIVE</code> lock modes.
+ This mode protects a table against concurrent data changes, and
+ is self-exclusive so that only one session can hold it at a time.
+ </p><p>
+ Acquired by <code class="command">CREATE TRIGGER</code> and some forms of
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>.
+ </p></dd><dt><span class="term">
+ <code class="literal">EXCLUSIVE</code> (<code class="literal">ExclusiveLock</code>)
+ </span></dt><dd><p>
+ Conflicts with the <code class="literal">ROW SHARE</code>, <code class="literal">ROW
+ EXCLUSIVE</code>, <code class="literal">SHARE UPDATE
+ EXCLUSIVE</code>, <code class="literal">SHARE</code>, <code class="literal">SHARE
+ ROW EXCLUSIVE</code>, <code class="literal">EXCLUSIVE</code>, and
+ <code class="literal">ACCESS EXCLUSIVE</code> lock modes.
+ This mode allows only concurrent <code class="literal">ACCESS SHARE</code> locks,
+ i.e., only reads from the table can proceed in parallel with a
+ transaction holding this lock mode.
+ </p><p>
+ Acquired by <code class="command">REFRESH MATERIALIZED VIEW CONCURRENTLY</code>.
+ </p></dd><dt><span class="term">
+ <code class="literal">ACCESS EXCLUSIVE</code> (<code class="literal">AccessExclusiveLock</code>)
+ </span></dt><dd><p>
+ Conflicts with locks of all modes (<code class="literal">ACCESS
+ SHARE</code>, <code class="literal">ROW SHARE</code>, <code class="literal">ROW
+ EXCLUSIVE</code>, <code class="literal">SHARE UPDATE
+ EXCLUSIVE</code>, <code class="literal">SHARE</code>, <code class="literal">SHARE
+ ROW EXCLUSIVE</code>, <code class="literal">EXCLUSIVE</code>, and
+ <code class="literal">ACCESS EXCLUSIVE</code>).
+ This mode guarantees that the
+ holder is the only transaction accessing the table in any way.
+ </p><p>
+ Acquired by the <code class="command">DROP TABLE</code>,
+ <code class="command">TRUNCATE</code>, <code class="command">REINDEX</code>,
+ <code class="command">CLUSTER</code>, <code class="command">VACUUM FULL</code>,
+ and <code class="command">REFRESH MATERIALIZED VIEW</code> (without
+ <code class="option">CONCURRENTLY</code>)
+ commands. Many forms of <code class="command">ALTER INDEX</code> and <code class="command">ALTER TABLE</code> also acquire
+ a lock at this level. This is also the default lock mode for
+ <code class="command">LOCK TABLE</code> statements that do not specify
+ a mode explicitly.
+ </p></dd></dl></div><div class="tip"><h3 class="title">Tip</h3><p>
+ Only an <code class="literal">ACCESS EXCLUSIVE</code> lock blocks a
+ <code class="command">SELECT</code> (without <code class="option">FOR UPDATE/SHARE</code>)
+ statement.
+ </p></div><p>
+ Once acquired, a lock is normally held until the end of the transaction. But if a
+ lock is acquired after establishing a savepoint, the lock is released
+ immediately if the savepoint is rolled back to. This is consistent with
+ the principle that <code class="command">ROLLBACK</code> cancels all effects of the
+ commands since the savepoint. The same holds for locks acquired within a
+ <span class="application">PL/pgSQL</span> exception block: an error escape from the block
+ releases locks acquired within it.
+ </p><div class="table" id="TABLE-LOCK-COMPATIBILITY"><p class="title"><strong>Table 13.2. Conflicting Lock Modes</strong></p><div class="table-contents"><table class="table" summary="Conflicting Lock Modes" border="1"><colgroup><col /><col class="lockst" /><col /><col /><col /><col /><col /><col /><col class="lockend" /></colgroup><thead><tr><th rowspan="2">Requested Lock Mode</th><th colspan="8" align="center">Existing Lock Mode</th></tr><tr><th><code class="literal">ACCESS SHARE</code></th><th><code class="literal">ROW SHARE</code></th><th><code class="literal">ROW EXCL.</code></th><th><code class="literal">SHARE UPDATE EXCL.</code></th><th><code class="literal">SHARE</code></th><th><code class="literal">SHARE ROW EXCL.</code></th><th><code class="literal">EXCL.</code></th><th><code class="literal">ACCESS EXCL.</code></th></tr></thead><tbody><tr><td><code class="literal">ACCESS SHARE</code></td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">X</td></tr><tr><td><code class="literal">ROW SHARE</code></td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">X</td><td align="center">X</td></tr><tr><td><code class="literal">ROW EXCL.</code></td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr><tr><td><code class="literal">SHARE UPDATE EXCL.</code></td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr><tr><td><code class="literal">SHARE</code></td><td align="center"> </td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr><tr><td><code class="literal">SHARE ROW EXCL.</code></td><td align="center"> </td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr><tr><td><code class="literal">EXCL.</code></td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr><tr><td><code class="literal">ACCESS EXCL.</code></td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="LOCKING-ROWS"><div class="titlepage"><div><div><h3 class="title">13.3.2. Row-Level Locks</h3></div></div></div><p>
+ In addition to table-level locks, there are row-level locks, which
+ are listed as below with the contexts in which they are used
+ automatically by <span class="productname">PostgreSQL</span>. See
+ <a class="xref" href="explicit-locking.html#ROW-LOCK-COMPATIBILITY" title="Table 13.3. Conflicting Row-Level Locks">Table 13.3</a> for a complete table of
+ row-level lock conflicts. Note that a transaction can hold
+ conflicting locks on the same row, even in different subtransactions;
+ but other than that, two transactions can never hold conflicting locks
+ on the same row. Row-level locks do not affect data querying; they
+ block only <span class="emphasis"><em>writers and lockers</em></span> to the same
+ row. Row-level locks are released at transaction end or during
+ savepoint rollback, just like table-level locks.
+
+ </p><div class="variablelist"><p class="title"><strong>Row-Level Lock Modes</strong></p><dl class="variablelist"><dt><span class="term">
+ <code class="literal">FOR UPDATE</code>
+ </span></dt><dd><p>
+ <code class="literal">FOR UPDATE</code> causes the rows retrieved by the
+ <code class="command">SELECT</code> statement to be locked as though for
+ update. This prevents them from being locked, modified or deleted by
+ other transactions until the current transaction ends. That is,
+ other transactions that attempt <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>,
+ <code class="command">SELECT FOR UPDATE</code>,
+ <code class="command">SELECT FOR NO KEY UPDATE</code>,
+ <code class="command">SELECT FOR SHARE</code> or
+ <code class="command">SELECT FOR KEY SHARE</code>
+ of these rows will be blocked until the current transaction ends;
+ conversely, <code class="command">SELECT FOR UPDATE</code> will wait for a
+ concurrent transaction that has run any of those commands on the
+ same row,
+ and will then lock and return the updated row (or no row, if the
+ row was deleted). Within a <code class="literal">REPEATABLE READ</code> or
+ <code class="literal">SERIALIZABLE</code> transaction,
+ however, an error will be thrown if a row to be locked has changed
+ since the transaction started. For further discussion see
+ <a class="xref" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level">Section 13.4</a>.
+ </p><p>
+ The <code class="literal">FOR UPDATE</code> lock mode
+ is also acquired by any <code class="command">DELETE</code> on a row, and also by an
+ <code class="command">UPDATE</code> that modifies the values of certain columns. Currently,
+ the set of columns considered for the <code class="command">UPDATE</code> case are those that
+ have a unique index on them that can be used in a foreign key (so partial
+ indexes and expressional indexes are not considered), but this may change
+ in the future.
+ </p></dd><dt><span class="term">
+ <code class="literal">FOR NO KEY UPDATE</code>
+ </span></dt><dd><p>
+ Behaves similarly to <code class="literal">FOR UPDATE</code>, except that the lock
+ acquired is weaker: this lock will not block
+ <code class="literal">SELECT FOR KEY SHARE</code> commands that attempt to acquire
+ a lock on the same rows. This lock mode is also acquired by any
+ <code class="command">UPDATE</code> that does not acquire a <code class="literal">FOR UPDATE</code> lock.
+ </p></dd><dt><span class="term">
+ <code class="literal">FOR SHARE</code>
+ </span></dt><dd><p>
+ Behaves similarly to <code class="literal">FOR NO KEY UPDATE</code>, except that it
+ acquires a shared lock rather than exclusive lock on each retrieved
+ row. A shared lock blocks other transactions from performing
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ <code class="command">SELECT FOR UPDATE</code> or
+ <code class="command">SELECT FOR NO KEY UPDATE</code> on these rows, but it does not
+ prevent them from performing <code class="command">SELECT FOR SHARE</code> or
+ <code class="command">SELECT FOR KEY SHARE</code>.
+ </p></dd><dt><span class="term">
+ <code class="literal">FOR KEY SHARE</code>
+ </span></dt><dd><p>
+ Behaves similarly to <code class="literal">FOR SHARE</code>, except that the
+ lock is weaker: <code class="literal">SELECT FOR UPDATE</code> is blocked, but not
+ <code class="literal">SELECT FOR NO KEY UPDATE</code>. A key-shared lock blocks
+ other transactions from performing <code class="command">DELETE</code> or
+ any <code class="command">UPDATE</code> that changes the key values, but not
+ other <code class="command">UPDATE</code>, and neither does it prevent
+ <code class="command">SELECT FOR NO KEY UPDATE</code>, <code class="command">SELECT FOR SHARE</code>,
+ or <code class="command">SELECT FOR KEY SHARE</code>.
+ </p></dd></dl></div><p>
+ <span class="productname">PostgreSQL</span> doesn't remember any
+ information about modified rows in memory, so there is no limit on
+ the number of rows locked at one time. However, locking a row
+ might cause a disk write, e.g., <code class="command">SELECT FOR
+ UPDATE</code> modifies selected rows to mark them locked, and so
+ will result in disk writes.
+ </p><div class="table" id="ROW-LOCK-COMPATIBILITY"><p class="title"><strong>Table 13.3. Conflicting Row-Level Locks</strong></p><div class="table-contents"><table class="table" summary="Conflicting Row-Level Locks" border="1"><colgroup><col class="col1" /><col class="lockst" /><col class="col3" /><col class="col4" /><col class="lockend" /></colgroup><thead><tr><th rowspan="2">Requested Lock Mode</th><th colspan="4">Current Lock Mode</th></tr><tr><th>FOR KEY SHARE</th><th>FOR SHARE</th><th>FOR NO KEY UPDATE</th><th>FOR UPDATE</th></tr></thead><tbody><tr><td>FOR KEY SHARE</td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center">X</td></tr><tr><td>FOR SHARE</td><td align="center"> </td><td align="center"> </td><td align="center">X</td><td align="center">X</td></tr><tr><td>FOR NO KEY UPDATE</td><td align="center"> </td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr><tr><td>FOR UPDATE</td><td align="center">X</td><td align="center">X</td><td align="center">X</td><td align="center">X</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="LOCKING-PAGES"><div class="titlepage"><div><div><h3 class="title">13.3.3. Page-Level Locks</h3></div></div></div><p>
+ In addition to table and row locks, page-level share/exclusive locks are
+ used to control read/write access to table pages in the shared buffer
+ pool. These locks are released immediately after a row is fetched or
+ updated. Application developers normally need not be concerned with
+ page-level locks, but they are mentioned here for completeness.
+ </p></div><div class="sect2" id="LOCKING-DEADLOCKS"><div class="titlepage"><div><div><h3 class="title">13.3.4. Deadlocks</h3></div></div></div><a id="id-1.5.12.6.8.2" class="indexterm"></a><p>
+ The use of explicit locking can increase the likelihood of
+ <em class="firstterm">deadlocks</em>, wherein two (or more) transactions each
+ hold locks that the other wants. For example, if transaction 1
+ acquires an exclusive lock on table A and then tries to acquire
+ an exclusive lock on table B, while transaction 2 has already
+ exclusive-locked table B and now wants an exclusive lock on table
+ A, then neither one can proceed.
+ <span class="productname">PostgreSQL</span> automatically detects
+ deadlock situations and resolves them by aborting one of the
+ transactions involved, allowing the other(s) to complete.
+ (Exactly which transaction will be aborted is difficult to
+ predict and should not be relied upon.)
+ </p><p>
+ Note that deadlocks can also occur as the result of row-level
+ locks (and thus, they can occur even if explicit locking is not
+ used). Consider the case in which two concurrent
+ transactions modify a table. The first transaction executes:
+
+</p><pre class="screen">
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;
+</pre><p>
+
+ This acquires a row-level lock on the row with the specified
+ account number. Then, the second transaction executes:
+
+</p><pre class="screen">
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;
+</pre><p>
+
+ The first <code class="command">UPDATE</code> statement successfully
+ acquires a row-level lock on the specified row, so it succeeds in
+ updating that row. However, the second <code class="command">UPDATE</code>
+ statement finds that the row it is attempting to update has
+ already been locked, so it waits for the transaction that
+ acquired the lock to complete. Transaction two is now waiting on
+ transaction one to complete before it continues execution. Now,
+ transaction one executes:
+
+</p><pre class="screen">
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
+</pre><p>
+
+ Transaction one attempts to acquire a row-level lock on the
+ specified row, but it cannot: transaction two already holds such
+ a lock. So it waits for transaction two to complete. Thus,
+ transaction one is blocked on transaction two, and transaction
+ two is blocked on transaction one: a deadlock
+ condition. <span class="productname">PostgreSQL</span> will detect this
+ situation and abort one of the transactions.
+ </p><p>
+ The best defense against deadlocks is generally to avoid them by
+ being certain that all applications using a database acquire
+ locks on multiple objects in a consistent order. In the example
+ above, if both transactions
+ had updated the rows in the same order, no deadlock would have
+ occurred. One should also ensure that the first lock acquired on
+ an object in a transaction is the most restrictive mode that will be
+ needed for that object. If it is not feasible to verify this in
+ advance, then deadlocks can be handled on-the-fly by retrying
+ transactions that abort due to deadlocks.
+ </p><p>
+ So long as no deadlock situation is detected, a transaction seeking
+ either a table-level or row-level lock will wait indefinitely for
+ conflicting locks to be released. This means it is a bad idea for
+ applications to hold transactions open for long periods of time
+ (e.g., while waiting for user input).
+ </p></div><div class="sect2" id="ADVISORY-LOCKS"><div class="titlepage"><div><div><h3 class="title">13.3.5. Advisory Locks</h3></div></div></div><a id="id-1.5.12.6.9.2" class="indexterm"></a><a id="id-1.5.12.6.9.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a means for
+ creating locks that have application-defined meanings. These are
+ called <em class="firstterm">advisory locks</em>, because the system does not
+ enforce their use — it is up to the application to use them
+ correctly. Advisory locks can be useful for locking strategies
+ that are an awkward fit for the MVCC model.
+ For example, a common use of advisory locks is to emulate pessimistic
+ locking strategies typical of so-called <span class="quote">“<span class="quote">flat file</span>”</span> data
+ management systems.
+ While a flag stored in a table could be used for the same purpose,
+ advisory locks are faster, avoid table bloat, and are automatically
+ cleaned up by the server at the end of the session.
+ </p><p>
+ There are two ways to acquire an advisory lock in
+ <span class="productname">PostgreSQL</span>: at session level or at
+ transaction level.
+ Once acquired at session level, an advisory lock is held until
+ explicitly released or the session ends. Unlike standard lock requests,
+ session-level advisory lock requests do not honor transaction semantics:
+ a lock acquired during a transaction that is later rolled back will still
+ be held following the rollback, and likewise an unlock is effective even
+ if the calling transaction fails later. A lock can be acquired multiple
+ times by its owning process; for each completed lock request there must
+ be a corresponding unlock request before the lock is actually released.
+ Transaction-level lock requests, on the other hand, behave more like
+ regular lock requests: they are automatically released at the end of the
+ transaction, and there is no explicit unlock operation. This behavior
+ is often more convenient than the session-level behavior for short-term
+ usage of an advisory lock.
+ Session-level and transaction-level lock requests for the same advisory
+ lock identifier will block each other in the expected way.
+ If a session already holds a given advisory lock, additional requests by
+ it will always succeed, even if other sessions are awaiting the lock; this
+ statement is true regardless of whether the existing lock hold and new
+ request are at session level or transaction level.
+ </p><p>
+ Like all locks in
+ <span class="productname">PostgreSQL</span>, a complete list of advisory locks
+ currently held by any session can be found in the <a class="link" href="view-pg-locks.html" title="54.12. pg_locks"><code class="structname">pg_locks</code></a> system
+ view.
+ </p><p>
+ Both advisory locks and regular locks are stored in a shared memory
+ pool whose size is defined by the configuration variables
+ <a class="xref" href="runtime-config-locks.html#GUC-MAX-LOCKS-PER-TRANSACTION">max_locks_per_transaction</a> and
+ <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>.
+ Care must be taken not to exhaust this
+ memory or the server will be unable to grant any locks at all.
+ This imposes an upper limit on the number of advisory locks
+ grantable by the server, typically in the tens to hundreds of thousands
+ depending on how the server is configured.
+ </p><p>
+ In certain cases using advisory locking methods, especially in queries
+ involving explicit ordering and <code class="literal">LIMIT</code> clauses, care must be
+ taken to control the locks acquired because of the order in which SQL
+ expressions are evaluated. For example:
+</p><pre class="screen">
+SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
+SELECT pg_advisory_lock(id) FROM foo WHERE id &gt; 12345 LIMIT 100; -- danger!
+SELECT pg_advisory_lock(q.id) FROM
+(
+ SELECT id FROM foo WHERE id &gt; 12345 LIMIT 100
+) q; -- ok
+</pre><p>
+ In the above queries, the second form is dangerous because the
+ <code class="literal">LIMIT</code> is not guaranteed to be applied before the locking
+ function is executed. This might cause some locks to be acquired
+ that the application was not expecting, and hence would fail to release
+ (until it ends the session).
+ From the point of view of the application, such locks
+ would be dangling, although still viewable in
+ <code class="structname">pg_locks</code>.
+ </p><p>
+ The functions provided to manipulate advisory locks are described in
+ <a class="xref" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS" title="9.27.10. Advisory Lock Functions">Section 9.27.10</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="transaction-iso.html" title="13.2. Transaction Isolation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.2. Transaction Isolation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.4. Data Consistency Checks at the Application Level</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/extend-extensions.html b/doc/src/sgml/html/extend-extensions.html
new file mode 100644
index 0000000..15d0157
--- /dev/null
+++ b/doc/src/sgml/html/extend-extensions.html
@@ -0,0 +1,626 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.17. Packaging Related Objects into an Extension</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xindex.html" title="38.16. Interfacing Extensions to Indexes" /><link rel="next" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.17. Packaging Related Objects into an Extension</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTEND-EXTENSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.17. Packaging Related Objects into an Extension</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="extend-extensions.html#id-1.8.3.20.11">38.17.1. Extension Files</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-RELOCATION">38.17.2. Extension Relocatability</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-CONFIG-TABLES">38.17.3. Extension Configuration Tables</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#id-1.8.3.20.14">38.17.4. Extension Updates</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#id-1.8.3.20.15">38.17.5. Installing Extensions Using Update Scripts</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-SECURITY">38.17.6. Security Considerations for Extensions</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-EXAMPLE">38.17.7. Extension Example</a></span></dt></dl></div><a id="id-1.8.3.20.2" class="indexterm"></a><p>
+ A useful extension to <span class="productname">PostgreSQL</span> typically includes
+ multiple SQL objects; for example, a new data type will require new
+ functions, new operators, and probably new index operator classes.
+ It is helpful to collect all these objects into a single package
+ to simplify database management. <span class="productname">PostgreSQL</span> calls
+ such a package an <em class="firstterm">extension</em>. To define an extension,
+ you need at least a <em class="firstterm">script file</em> that contains the
+ <acronym class="acronym">SQL</acronym> commands to create the extension's objects, and a
+ <em class="firstterm">control file</em> that specifies a few basic properties
+ of the extension itself. If the extension includes C code, there
+ will typically also be a shared library file into which the C code
+ has been built. Once you have these files, a simple
+ <a class="link" href="sql-createextension.html" title="CREATE EXTENSION"><code class="command">CREATE EXTENSION</code></a> command loads the objects into
+ your database.
+ </p><p>
+ The main advantage of using an extension, rather than just running the
+ <acronym class="acronym">SQL</acronym> script to load a bunch of <span class="quote">“<span class="quote">loose</span>”</span> objects
+ into your database, is that <span class="productname">PostgreSQL</span> will then
+ understand that the objects of the extension go together. You can
+ drop all the objects with a single <a class="link" href="sql-dropextension.html" title="DROP EXTENSION"><code class="command">DROP EXTENSION</code></a>
+ command (no need to maintain a separate <span class="quote">“<span class="quote">uninstall</span>”</span> script).
+ Even more useful, <span class="application">pg_dump</span> knows that it should not
+ dump the individual member objects of the extension — it will
+ just include a <code class="command">CREATE EXTENSION</code> command in dumps, instead.
+ This vastly simplifies migration to a new version of the extension
+ that might contain more or different objects than the old version.
+ Note however that you must have the extension's control, script, and
+ other files available when loading such a dump into a new database.
+ </p><p>
+ <span class="productname">PostgreSQL</span> will not let you drop an individual object
+ contained in an extension, except by dropping the whole extension.
+ Also, while you can change the definition of an extension member object
+ (for example, via <code class="command">CREATE OR REPLACE FUNCTION</code> for a
+ function), bear in mind that the modified definition will not be dumped
+ by <span class="application">pg_dump</span>. Such a change is usually only sensible if
+ you concurrently make the same change in the extension's script file.
+ (But there are special provisions for tables containing configuration
+ data; see <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-CONFIG-TABLES" title="38.17.3. Extension Configuration Tables">Section 38.17.3</a>.)
+ In production situations, it's generally better to create an extension
+ update script to perform changes to extension member objects.
+ </p><p>
+ The extension script may set privileges on objects that are part of the
+ extension, using <code class="command">GRANT</code> and <code class="command">REVOKE</code>
+ statements. The final set of privileges for each object (if any are set)
+ will be stored in the
+ <a class="link" href="catalog-pg-init-privs.html" title="53.28. pg_init_privs"><code class="structname">pg_init_privs</code></a>
+ system catalog. When <span class="application">pg_dump</span> is used, the
+ <code class="command">CREATE EXTENSION</code> command will be included in the dump, followed
+ by the set of <code class="command">GRANT</code> and <code class="command">REVOKE</code>
+ statements necessary to set the privileges on the objects to what they were
+ at the time the dump was taken.
+ </p><p>
+ <span class="productname">PostgreSQL</span> does not currently support extension scripts
+ issuing <code class="command">CREATE POLICY</code> or <code class="command">SECURITY LABEL</code>
+ statements. These are expected to be set after the extension has been
+ created. All RLS policies and security labels on extension objects will be
+ included in dumps created by <span class="application">pg_dump</span>.
+ </p><p>
+ The extension mechanism also has provisions for packaging modification
+ scripts that adjust the definitions of the SQL objects contained in an
+ extension. For example, if version 1.1 of an extension adds one function
+ and changes the body of another function compared to 1.0, the extension
+ author can provide an <em class="firstterm">update script</em> that makes just those
+ two changes. The <code class="command">ALTER EXTENSION UPDATE</code> command can then
+ be used to apply these changes and track which version of the extension
+ is actually installed in a given database.
+ </p><p>
+ The kinds of SQL objects that can be members of an extension are shown in
+ the description of <a class="link" href="sql-alterextension.html" title="ALTER EXTENSION"><code class="command">ALTER EXTENSION</code></a>. Notably, objects
+ that are database-cluster-wide, such as databases, roles, and tablespaces,
+ cannot be extension members since an extension is only known within one
+ database. (Although an extension script is not prohibited from creating
+ such objects, if it does so they will not be tracked as part of the
+ extension.) Also notice that while a table can be a member of an
+ extension, its subsidiary objects such as indexes are not directly
+ considered members of the extension.
+ Another important point is that schemas can belong to extensions, but not
+ vice versa: an extension as such has an unqualified name and does not
+ exist <span class="quote">“<span class="quote">within</span>”</span> any schema. The extension's member objects,
+ however, will belong to schemas whenever appropriate for their object
+ types. It may or may not be appropriate for an extension to own the
+ schema(s) its member objects are within.
+ </p><p>
+ If an extension's script creates any temporary objects (such as temp
+ tables), those objects are treated as extension members for the
+ remainder of the current session, but are automatically dropped at
+ session end, as any temporary object would be. This is an exception
+ to the rule that extension member objects cannot be dropped without
+ dropping the whole extension.
+ </p><div class="sect2" id="id-1.8.3.20.11"><div class="titlepage"><div><div><h3 class="title">38.17.1. Extension Files</h3></div></div></div><a id="id-1.8.3.20.11.2" class="indexterm"></a><p>
+ The <code class="command">CREATE EXTENSION</code> command relies on a control
+ file for each extension, which must be named the same as the extension
+ with a suffix of <code class="literal">.control</code>, and must be placed in the
+ installation's <code class="literal">SHAREDIR/extension</code> directory. There
+ must also be at least one <acronym class="acronym">SQL</acronym> script file, which follows the
+ naming pattern
+ <code class="literal"><em class="replaceable"><code>extension</code></em>--<em class="replaceable"><code>version</code></em>.sql</code>
+ (for example, <code class="literal">foo--1.0.sql</code> for version <code class="literal">1.0</code> of
+ extension <code class="literal">foo</code>). By default, the script file(s) are also
+ placed in the <code class="literal">SHAREDIR/extension</code> directory; but the
+ control file can specify a different directory for the script file(s).
+ </p><p>
+ The file format for an extension control file is the same as for the
+ <code class="filename">postgresql.conf</code> file, namely a list of
+ <em class="replaceable"><code>parameter_name</code></em> <code class="literal">=</code> <em class="replaceable"><code>value</code></em>
+ assignments, one per line. Blank lines and comments introduced by
+ <code class="literal">#</code> are allowed. Be sure to quote any value that is not
+ a single word or number.
+ </p><p>
+ A control file can set the following parameters:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">directory</code> (<code class="type">string</code>)</span></dt><dd><p>
+ The directory containing the extension's <acronym class="acronym">SQL</acronym> script
+ file(s). Unless an absolute path is given, the name is relative to
+ the installation's <code class="literal">SHAREDIR</code> directory. The
+ default behavior is equivalent to specifying
+ <code class="literal">directory = 'extension'</code>.
+ </p></dd><dt><span class="term"><code class="varname">default_version</code> (<code class="type">string</code>)</span></dt><dd><p>
+ The default version of the extension (the one that will be installed
+ if no version is specified in <code class="command">CREATE EXTENSION</code>). Although
+ this can be omitted, that will result in <code class="command">CREATE EXTENSION</code>
+ failing if no <code class="literal">VERSION</code> option appears, so you generally
+ don't want to do that.
+ </p></dd><dt><span class="term"><code class="varname">comment</code> (<code class="type">string</code>)</span></dt><dd><p>
+ A comment (any string) about the extension. The comment is applied
+ when initially creating an extension, but not during extension updates
+ (since that might override user-added comments). Alternatively,
+ the extension's comment can be set by writing
+ a <a class="xref" href="sql-comment.html" title="COMMENT"><span class="refentrytitle">COMMENT</span></a> command in the script file.
+ </p></dd><dt><span class="term"><code class="varname">encoding</code> (<code class="type">string</code>)</span></dt><dd><p>
+ The character set encoding used by the script file(s). This should
+ be specified if the script files contain any non-ASCII characters.
+ Otherwise the files will be assumed to be in the database encoding.
+ </p></dd><dt><span class="term"><code class="varname">module_pathname</code> (<code class="type">string</code>)</span></dt><dd><p>
+ The value of this parameter will be substituted for each occurrence
+ of <code class="literal">MODULE_PATHNAME</code> in the script file(s). If it is not
+ set, no substitution is made. Typically, this is set to
+ <code class="literal">$libdir/<em class="replaceable"><code>shared_library_name</code></em></code> and
+ then <code class="literal">MODULE_PATHNAME</code> is used in <code class="command">CREATE
+ FUNCTION</code> commands for C-language functions, so that the script
+ files do not need to hard-wire the name of the shared library.
+ </p></dd><dt><span class="term"><code class="varname">requires</code> (<code class="type">string</code>)</span></dt><dd><p>
+ A list of names of extensions that this extension depends on,
+ for example <code class="literal">requires = 'foo, bar'</code>. Those
+ extensions must be installed before this one can be installed.
+ </p></dd><dt><span class="term"><code class="varname">superuser</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ If this parameter is <code class="literal">true</code> (which is the default),
+ only superusers can create the extension or update it to a new
+ version (but see also <code class="varname">trusted</code>, below).
+ If it is set to <code class="literal">false</code>, just the privileges
+ required to execute the commands in the installation or update script
+ are required.
+ This should normally be set to <code class="literal">true</code> if any of the
+ script commands require superuser privileges. (Such commands would
+ fail anyway, but it's more user-friendly to give the error up front.)
+ </p></dd><dt><span class="term"><code class="varname">trusted</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This parameter, if set to <code class="literal">true</code> (which is not the
+ default), allows some non-superusers to install an extension that
+ has <code class="varname">superuser</code> set to <code class="literal">true</code>.
+ Specifically, installation will be permitted for anyone who has
+ <code class="literal">CREATE</code> privilege on the current database.
+ When the user executing <code class="command">CREATE EXTENSION</code> is not
+ a superuser but is allowed to install by virtue of this parameter,
+ then the installation or update script is run as the bootstrap
+ superuser, not as the calling user.
+ This parameter is irrelevant if <code class="varname">superuser</code> is
+ <code class="literal">false</code>.
+ Generally, this should not be set true for extensions that could
+ allow access to otherwise-superuser-only abilities, such as
+ file system access.
+ Also, marking an extension trusted requires significant extra effort
+ to write the extension's installation and update script(s) securely;
+ see <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-SECURITY" title="38.17.6. Security Considerations for Extensions">Section 38.17.6</a>.
+ </p></dd><dt><span class="term"><code class="varname">relocatable</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ An extension is <em class="firstterm">relocatable</em> if it is possible to move
+ its contained objects into a different schema after initial creation
+ of the extension. The default is <code class="literal">false</code>, i.e., the
+ extension is not relocatable.
+ See <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-RELOCATION" title="38.17.2. Extension Relocatability">Section 38.17.2</a> for more information.
+ </p></dd><dt><span class="term"><code class="varname">schema</code> (<code class="type">string</code>)</span></dt><dd><p>
+ This parameter can only be set for non-relocatable extensions.
+ It forces the extension to be loaded into exactly the named schema
+ and not any other.
+ The <code class="varname">schema</code> parameter is consulted only when
+ initially creating an extension, not during extension updates.
+ See <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-RELOCATION" title="38.17.2. Extension Relocatability">Section 38.17.2</a> for more information.
+ </p></dd></dl></div><p>
+ In addition to the primary control file
+ <code class="literal"><em class="replaceable"><code>extension</code></em>.control</code>,
+ an extension can have secondary control files named in the style
+ <code class="literal"><em class="replaceable"><code>extension</code></em>--<em class="replaceable"><code>version</code></em>.control</code>.
+ If supplied, these must be located in the script file directory.
+ Secondary control files follow the same format as the primary control
+ file. Any parameters set in a secondary control file override the
+ primary control file when installing or updating to that version of
+ the extension. However, the parameters <code class="varname">directory</code> and
+ <code class="varname">default_version</code> cannot be set in a secondary control file.
+ </p><p>
+ An extension's <acronym class="acronym">SQL</acronym> script files can contain any SQL commands,
+ except for transaction control commands (<code class="command">BEGIN</code>,
+ <code class="command">COMMIT</code>, etc.) and commands that cannot be executed inside a
+ transaction block (such as <code class="command">VACUUM</code>). This is because the
+ script files are implicitly executed within a transaction block.
+ </p><p>
+ An extension's <acronym class="acronym">SQL</acronym> script files can also contain lines
+ beginning with <code class="literal">\echo</code>, which will be ignored (treated as
+ comments) by the extension mechanism. This provision is commonly used
+ to throw an error if the script file is fed to <span class="application">psql</span>
+ rather than being loaded via <code class="command">CREATE EXTENSION</code> (see example
+ script in <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-EXAMPLE" title="38.17.7. Extension Example">Section 38.17.7</a>).
+ Without that, users might accidentally load the
+ extension's contents as <span class="quote">“<span class="quote">loose</span>”</span> objects rather than as an
+ extension, a state of affairs that's a bit tedious to recover from.
+ </p><p>
+ If the extension script contains the
+ string <code class="literal">@extowner@</code>, that string is replaced with the
+ (suitably quoted) name of the user calling <code class="command">CREATE
+ EXTENSION</code> or <code class="command">ALTER EXTENSION</code>. Typically
+ this feature is used by extensions that are marked trusted to assign
+ ownership of selected objects to the calling user rather than the
+ bootstrap superuser. (One should be careful about doing so, however.
+ For example, assigning ownership of a C-language function to a
+ non-superuser would create a privilege escalation path for that user.)
+ </p><p>
+ While the script files can contain any characters allowed by the specified
+ encoding, control files should contain only plain ASCII, because there
+ is no way for <span class="productname">PostgreSQL</span> to know what encoding a
+ control file is in. In practice this is only an issue if you want to
+ use non-ASCII characters in the extension's comment. Recommended
+ practice in that case is to not use the control file <code class="varname">comment</code>
+ parameter, but instead use <code class="command">COMMENT ON EXTENSION</code>
+ within a script file to set the comment.
+ </p></div><div class="sect2" id="EXTEND-EXTENSIONS-RELOCATION"><div class="titlepage"><div><div><h3 class="title">38.17.2. Extension Relocatability</h3></div></div></div><p>
+ Users often wish to load the objects contained in an extension into a
+ different schema than the extension's author had in mind. There are
+ three supported levels of relocatability:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A fully relocatable extension can be moved into another schema
+ at any time, even after it's been loaded into a database.
+ This is done with the <code class="command">ALTER EXTENSION SET SCHEMA</code>
+ command, which automatically renames all the member objects into
+ the new schema. Normally, this is only possible if the extension
+ contains no internal assumptions about what schema any of its
+ objects are in. Also, the extension's objects must all be in one
+ schema to begin with (ignoring objects that do not belong to any
+ schema, such as procedural languages). Mark a fully relocatable
+ extension by setting <code class="literal">relocatable = true</code> in its control
+ file.
+ </p></li><li class="listitem"><p>
+ An extension might be relocatable during installation but not
+ afterwards. This is typically the case if the extension's script
+ file needs to reference the target schema explicitly, for example
+ in setting <code class="literal">search_path</code> properties for SQL functions.
+ For such an extension, set <code class="literal">relocatable = false</code> in its
+ control file, and use <code class="literal">@extschema@</code> to refer to the target
+ schema in the script file. All occurrences of this string will be
+ replaced by the actual target schema's name before the script is
+ executed. The user can set the target schema using the
+ <code class="literal">SCHEMA</code> option of <code class="command">CREATE EXTENSION</code>.
+ </p></li><li class="listitem"><p>
+ If the extension does not support relocation at all, set
+ <code class="literal">relocatable = false</code> in its control file, and also set
+ <code class="literal">schema</code> to the name of the intended target schema. This
+ will prevent use of the <code class="literal">SCHEMA</code> option of <code class="command">CREATE
+ EXTENSION</code>, unless it specifies the same schema named in the control
+ file. This choice is typically necessary if the extension contains
+ internal assumptions about schema names that can't be replaced by
+ uses of <code class="literal">@extschema@</code>. The <code class="literal">@extschema@</code>
+ substitution mechanism is available in this case too, although it is
+ of limited use since the schema name is determined by the control file.
+ </p></li></ul></div><p>
+ In all cases, the script file will be executed with
+ <a class="xref" href="runtime-config-client.html#GUC-SEARCH-PATH">search_path</a> initially set to point to the target
+ schema; that is, <code class="command">CREATE EXTENSION</code> does the equivalent of
+ this:
+</p><pre class="programlisting">
+SET LOCAL search_path TO @extschema@, pg_temp;
+</pre><p>
+ This allows the objects created by the script file to go into the target
+ schema. The script file can change <code class="varname">search_path</code> if it wishes,
+ but that is generally undesirable. <code class="varname">search_path</code> is restored
+ to its previous setting upon completion of <code class="command">CREATE EXTENSION</code>.
+ </p><p>
+ The target schema is determined by the <code class="varname">schema</code> parameter in
+ the control file if that is given, otherwise by the <code class="literal">SCHEMA</code>
+ option of <code class="command">CREATE EXTENSION</code> if that is given, otherwise the
+ current default object creation schema (the first one in the caller's
+ <code class="varname">search_path</code>). When the control file <code class="varname">schema</code>
+ parameter is used, the target schema will be created if it doesn't
+ already exist, but in the other two cases it must already exist.
+ </p><p>
+ If any prerequisite extensions are listed in <code class="varname">requires</code>
+ in the control file, their target schemas are added to the initial
+ setting of <code class="varname">search_path</code>, following the new
+ extension's target schema. This allows their objects to be visible to
+ the new extension's script file.
+ </p><p>
+ For security, <code class="literal">pg_temp</code> is automatically appended to
+ the end of <code class="varname">search_path</code> in all cases.
+ </p><p>
+ Although a non-relocatable extension can contain objects spread across
+ multiple schemas, it is usually desirable to place all the objects meant
+ for external use into a single schema, which is considered the extension's
+ target schema. Such an arrangement works conveniently with the default
+ setting of <code class="varname">search_path</code> during creation of dependent
+ extensions.
+ </p></div><div class="sect2" id="EXTEND-EXTENSIONS-CONFIG-TABLES"><div class="titlepage"><div><div><h3 class="title">38.17.3. Extension Configuration Tables</h3></div></div></div><p>
+ Some extensions include configuration tables, which contain data that
+ might be added or changed by the user after installation of the
+ extension. Ordinarily, if a table is part of an extension, neither
+ the table's definition nor its content will be dumped by
+ <span class="application">pg_dump</span>. But that behavior is undesirable for a
+ configuration table; any data changes made by the user need to be
+ included in dumps, or the extension will behave differently after a dump
+ and restore.
+ </p><a id="id-1.8.3.20.13.3" class="indexterm"></a><p>
+ To solve this problem, an extension's script file can mark a table
+ or a sequence it has created as a configuration relation, which will
+ cause <span class="application">pg_dump</span> to include the table's or the sequence's
+ contents (not its definition) in dumps. To do that, call the function
+ <code class="function">pg_extension_config_dump(regclass, text)</code> after creating the
+ table or the sequence, for example
+</p><pre class="programlisting">
+CREATE TABLE my_config (key text, value text);
+CREATE SEQUENCE my_config_seq;
+
+SELECT pg_catalog.pg_extension_config_dump('my_config', '');
+SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');
+</pre><p>
+ Any number of tables or sequences can be marked this way. Sequences
+ associated with <code class="type">serial</code> or <code class="type">bigserial</code> columns can
+ be marked as well.
+ </p><p>
+ When the second argument of <code class="function">pg_extension_config_dump</code> is
+ an empty string, the entire contents of the table are dumped by
+ <span class="application">pg_dump</span>. This is usually only correct if the table
+ is initially empty as created by the extension script. If there is
+ a mixture of initial data and user-provided data in the table,
+ the second argument of <code class="function">pg_extension_config_dump</code> provides
+ a <code class="literal">WHERE</code> condition that selects the data to be dumped.
+ For example, you might do
+</p><pre class="programlisting">
+CREATE TABLE my_config (key text, value text, standard_entry boolean);
+
+SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
+</pre><p>
+ and then make sure that <code class="structfield">standard_entry</code> is true only
+ in the rows created by the extension's script.
+ </p><p>
+ For sequences, the second argument of <code class="function">pg_extension_config_dump</code>
+ has no effect.
+ </p><p>
+ More complicated situations, such as initially-provided rows that might
+ be modified by users, can be handled by creating triggers on the
+ configuration table to ensure that modified rows are marked correctly.
+ </p><p>
+ You can alter the filter condition associated with a configuration table
+ by calling <code class="function">pg_extension_config_dump</code> again. (This would
+ typically be useful in an extension update script.) The only way to mark
+ a table as no longer a configuration table is to dissociate it from the
+ extension with <code class="command">ALTER EXTENSION ... DROP TABLE</code>.
+ </p><p>
+ Note that foreign key relationships between these tables will dictate the
+ order in which the tables are dumped out by pg_dump. Specifically, pg_dump
+ will attempt to dump the referenced-by table before the referencing table.
+ As the foreign key relationships are set up at CREATE EXTENSION time (prior
+ to data being loaded into the tables) circular dependencies are not
+ supported. When circular dependencies exist, the data will still be dumped
+ out but the dump will not be able to be restored directly and user
+ intervention will be required.
+ </p><p>
+ Sequences associated with <code class="type">serial</code> or <code class="type">bigserial</code> columns
+ need to be directly marked to dump their state. Marking their parent
+ relation is not enough for this purpose.
+ </p></div><div class="sect2" id="id-1.8.3.20.14"><div class="titlepage"><div><div><h3 class="title">38.17.4. Extension Updates</h3></div></div></div><p>
+ One advantage of the extension mechanism is that it provides convenient
+ ways to manage updates to the SQL commands that define an extension's
+ objects. This is done by associating a version name or number with
+ each released version of the extension's installation script.
+ In addition, if you want users to be able to update their databases
+ dynamically from one version to the next, you should provide
+ <em class="firstterm">update scripts</em> that make the necessary changes to go from
+ one version to the next. Update scripts have names following the pattern
+ <code class="literal"><em class="replaceable"><code>extension</code></em>--<em class="replaceable"><code>old_version</code></em>--<em class="replaceable"><code>target_version</code></em>.sql</code>
+ (for example, <code class="literal">foo--1.0--1.1.sql</code> contains the commands to modify
+ version <code class="literal">1.0</code> of extension <code class="literal">foo</code> into version
+ <code class="literal">1.1</code>).
+ </p><p>
+ Given that a suitable update script is available, the command
+ <code class="command">ALTER EXTENSION UPDATE</code> will update an installed extension
+ to the specified new version. The update script is run in the same
+ environment that <code class="command">CREATE EXTENSION</code> provides for installation
+ scripts: in particular, <code class="varname">search_path</code> is set up in the same
+ way, and any new objects created by the script are automatically added
+ to the extension. Also, if the script chooses to drop extension member
+ objects, they are automatically dissociated from the extension.
+ </p><p>
+ If an extension has secondary control files, the control parameters
+ that are used for an update script are those associated with the script's
+ target (new) version.
+ </p><p>
+ <code class="command">ALTER EXTENSION</code> is able to execute sequences of update
+ script files to achieve a requested update. For example, if only
+ <code class="literal">foo--1.0--1.1.sql</code> and <code class="literal">foo--1.1--2.0.sql</code> are
+ available, <code class="command">ALTER EXTENSION</code> will apply them in sequence if an
+ update to version <code class="literal">2.0</code> is requested when <code class="literal">1.0</code> is
+ currently installed.
+ </p><p>
+ <span class="productname">PostgreSQL</span> doesn't assume anything about the properties
+ of version names: for example, it does not know whether <code class="literal">1.1</code>
+ follows <code class="literal">1.0</code>. It just matches up the available version names
+ and follows the path that requires applying the fewest update scripts.
+ (A version name can actually be any string that doesn't contain
+ <code class="literal">--</code> or leading or trailing <code class="literal">-</code>.)
+ </p><p>
+ Sometimes it is useful to provide <span class="quote">“<span class="quote">downgrade</span>”</span> scripts, for
+ example <code class="literal">foo--1.1--1.0.sql</code> to allow reverting the changes
+ associated with version <code class="literal">1.1</code>. If you do that, be careful
+ of the possibility that a downgrade script might unexpectedly
+ get applied because it yields a shorter path. The risky case is where
+ there is a <span class="quote">“<span class="quote">fast path</span>”</span> update script that jumps ahead several
+ versions as well as a downgrade script to the fast path's start point.
+ It might take fewer steps to apply the downgrade and then the fast
+ path than to move ahead one version at a time. If the downgrade script
+ drops any irreplaceable objects, this will yield undesirable results.
+ </p><p>
+ To check for unexpected update paths, use this command:
+</p><pre class="programlisting">
+SELECT * FROM pg_extension_update_paths('<em class="replaceable"><code>extension_name</code></em>');
+</pre><p>
+ This shows each pair of distinct known version names for the specified
+ extension, together with the update path sequence that would be taken to
+ get from the source version to the target version, or <code class="literal">NULL</code> if
+ there is no available update path. The path is shown in textual form
+ with <code class="literal">--</code> separators. You can use
+ <code class="literal">regexp_split_to_array(path,'--')</code> if you prefer an array
+ format.
+ </p></div><div class="sect2" id="id-1.8.3.20.15"><div class="titlepage"><div><div><h3 class="title">38.17.5. Installing Extensions Using Update Scripts</h3></div></div></div><p>
+ An extension that has been around for awhile will probably exist in
+ several versions, for which the author will need to write update scripts.
+ For example, if you have released a <code class="literal">foo</code> extension in
+ versions <code class="literal">1.0</code>, <code class="literal">1.1</code>, and <code class="literal">1.2</code>, there
+ should be update scripts <code class="filename">foo--1.0--1.1.sql</code>
+ and <code class="filename">foo--1.1--1.2.sql</code>.
+ Before <span class="productname">PostgreSQL</span> 10, it was necessary to also create
+ new script files <code class="filename">foo--1.1.sql</code> and <code class="filename">foo--1.2.sql</code>
+ that directly build the newer extension versions, or else the newer
+ versions could not be installed directly, only by
+ installing <code class="literal">1.0</code> and then updating. That was tedious and
+ duplicative, but now it's unnecessary, because <code class="command">CREATE
+ EXTENSION</code> can follow update chains automatically.
+ For example, if only the script
+ files <code class="filename">foo--1.0.sql</code>, <code class="filename">foo--1.0--1.1.sql</code>,
+ and <code class="filename">foo--1.1--1.2.sql</code> are available then a request to
+ install version <code class="literal">1.2</code> is honored by running those three
+ scripts in sequence. The processing is the same as if you'd first
+ installed <code class="literal">1.0</code> and then updated to <code class="literal">1.2</code>.
+ (As with <code class="command">ALTER EXTENSION UPDATE</code>, if multiple pathways are
+ available then the shortest is preferred.) Arranging an extension's
+ script files in this style can reduce the amount of maintenance effort
+ needed to produce small updates.
+ </p><p>
+ If you use secondary (version-specific) control files with an extension
+ maintained in this style, keep in mind that each version needs a control
+ file even if it has no stand-alone installation script, as that control
+ file will determine how the implicit update to that version is performed.
+ For example, if <code class="filename">foo--1.0.control</code> specifies <code class="literal">requires
+ = 'bar'</code> but <code class="literal">foo</code>'s other control files do not, the
+ extension's dependency on <code class="literal">bar</code> will be dropped when updating
+ from <code class="literal">1.0</code> to another version.
+ </p></div><div class="sect2" id="EXTEND-EXTENSIONS-SECURITY"><div class="titlepage"><div><div><h3 class="title">38.17.6. Security Considerations for Extensions</h3></div></div></div><p>
+ Widely-distributed extensions should assume little about the database
+ they occupy. Therefore, it's appropriate to write functions provided
+ by an extension in a secure style that cannot be compromised by
+ search-path-based attacks.
+ </p><p>
+ An extension that has the <code class="varname">superuser</code> property set to
+ true must also consider security hazards for the actions taken within
+ its installation and update scripts. It is not terribly difficult for
+ a malicious user to create trojan-horse objects that will compromise
+ later execution of a carelessly-written extension script, allowing that
+ user to acquire superuser privileges.
+ </p><p>
+ If an extension is marked <code class="varname">trusted</code>, then its
+ installation schema can be selected by the installing user, who might
+ intentionally use an insecure schema in hopes of gaining superuser
+ privileges. Therefore, a trusted extension is extremely exposed from a
+ security standpoint, and all its script commands must be carefully
+ examined to ensure that no compromise is possible.
+ </p><p>
+ Advice about writing functions securely is provided in
+ <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-SECURITY-FUNCS" title="38.17.6.1. Security Considerations for Extension Functions">Section 38.17.6.1</a> below, and advice
+ about writing installation scripts securely is provided in
+ <a class="xref" href="extend-extensions.html#EXTEND-EXTENSIONS-SECURITY-SCRIPTS" title="38.17.6.2. Security Considerations for Extension Scripts">Section 38.17.6.2</a>.
+ </p><div class="sect3" id="EXTEND-EXTENSIONS-SECURITY-FUNCS"><div class="titlepage"><div><div><h4 class="title">38.17.6.1. Security Considerations for Extension Functions</h4></div></div></div><p>
+ SQL-language and PL-language functions provided by extensions are at
+ risk of search-path-based attacks when they are executed, since
+ parsing of these functions occurs at execution time not creation time.
+ </p><p>
+ The <a class="link" href="sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY" title="Writing SECURITY DEFINER Functions Safely"><code class="command">CREATE
+ FUNCTION</code></a> reference page contains advice about
+ writing <code class="literal">SECURITY DEFINER</code> functions safely. It's
+ good practice to apply those techniques for any function provided by
+ an extension, since the function might be called by a high-privilege
+ user.
+ </p><p>
+ If you cannot set the <code class="varname">search_path</code> to contain only
+ secure schemas, assume that each unqualified name could resolve to an
+ object that a malicious user has defined. Beware of constructs that
+ depend on <code class="varname">search_path</code> implicitly; for
+ example, <code class="token">IN</code>
+ and <code class="literal">CASE <em class="replaceable"><code>expression</code></em> WHEN</code>
+ always select an operator using the search path. In their place, use
+ <code class="literal">OPERATOR(<em class="replaceable"><code>schema</code></em>.=) ANY</code>
+ and <code class="literal">CASE WHEN <em class="replaceable"><code>expression</code></em></code>.
+ </p><p>
+ A general-purpose extension usually should not assume that it's been
+ installed into a secure schema, which means that even schema-qualified
+ references to its own objects are not entirely risk-free. For
+ example, if the extension has defined a
+ function <code class="literal">myschema.myfunc(bigint)</code> then a call such
+ as <code class="literal">myschema.myfunc(42)</code> could be captured by a
+ hostile function <code class="literal">myschema.myfunc(integer)</code>. Be
+ careful that the data types of function and operator parameters exactly
+ match the declared argument types, using explicit casts where necessary.
+ </p></div><div class="sect3" id="EXTEND-EXTENSIONS-SECURITY-SCRIPTS"><div class="titlepage"><div><div><h4 class="title">38.17.6.2. Security Considerations for Extension Scripts</h4></div></div></div><p>
+ An extension installation or update script should be written to guard
+ against search-path-based attacks occurring when the script executes.
+ If an object reference in the script can be made to resolve to some
+ other object than the script author intended, then a compromise might
+ occur immediately, or later when the mis-defined extension object is
+ used.
+ </p><p>
+ DDL commands such as <code class="command">CREATE FUNCTION</code>
+ and <code class="command">CREATE OPERATOR CLASS</code> are generally secure,
+ but beware of any command having a general-purpose expression as a
+ component. For example, <code class="command">CREATE VIEW</code> needs to be
+ vetted, as does a <code class="literal">DEFAULT</code> expression
+ in <code class="command">CREATE FUNCTION</code>.
+ </p><p>
+ Sometimes an extension script might need to execute general-purpose
+ SQL, for example to make catalog adjustments that aren't possible via
+ DDL. Be careful to execute such commands with a
+ secure <code class="varname">search_path</code>; do <span class="emphasis"><em>not</em></span>
+ trust the path provided by <code class="command">CREATE/ALTER EXTENSION</code>
+ to be secure. Best practice is to temporarily
+ set <code class="varname">search_path</code> to <code class="literal">'pg_catalog,
+ pg_temp'</code> and insert references to the extension's
+ installation schema explicitly where needed. (This practice might
+ also be helpful for creating views.) Examples can be found in
+ the <code class="filename">contrib</code> modules in
+ the <span class="productname">PostgreSQL</span> source code distribution.
+ </p><p>
+ Cross-extension references are extremely difficult to make fully
+ secure, partially because of uncertainty about which schema the other
+ extension is in. The hazards are reduced if both extensions are
+ installed in the same schema, because then a hostile object cannot be
+ placed ahead of the referenced extension in the installation-time
+ <code class="varname">search_path</code>. However, no mechanism currently exists
+ to require that. For now, best practice is to not mark an extension
+ trusted if it depends on another one, unless that other one is always
+ installed in <code class="literal">pg_catalog</code>.
+ </p></div></div><div class="sect2" id="EXTEND-EXTENSIONS-EXAMPLE"><div class="titlepage"><div><div><h3 class="title">38.17.7. Extension Example</h3></div></div></div><p>
+ Here is a complete example of an <acronym class="acronym">SQL</acronym>-only
+ extension, a two-element composite type that can store any type of value
+ in its slots, which are named <span class="quote">“<span class="quote">k</span>”</span> and <span class="quote">“<span class="quote">v</span>”</span>. Non-text
+ values are automatically coerced to text for storage.
+ </p><p>
+ The script file <code class="filename">pair--1.0.sql</code> looks like this:
+
+</p><pre class="programlisting">
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pair" to load this file. \quit
+
+CREATE TYPE pair AS ( k text, v text );
+
+CREATE FUNCTION pair(text, text)
+RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';
+
+CREATE OPERATOR ~&gt; (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);
+
+-- "SET search_path" is easy to get right, but qualified names perform better.
+CREATE FUNCTION lower(pair)
+RETURNS pair LANGUAGE SQL
+AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;'
+SET search_path = pg_temp;
+
+CREATE FUNCTION pair_concat(pair, pair)
+RETURNS pair LANGUAGE SQL
+AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k,
+ $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;';
+
+</pre><p>
+ </p><p>
+ The control file <code class="filename">pair.control</code> looks like this:
+
+</p><pre class="programlisting">
+# pair extension
+comment = 'A key/value pair data type'
+default_version = '1.0'
+# cannot be relocatable because of use of @extschema@
+relocatable = false
+</pre><p>
+ </p><p>
+ While you hardly need a makefile to install these two files into the
+ correct directory, you could use a <code class="filename">Makefile</code> containing this:
+
+</p><pre class="programlisting">
+EXTENSION = pair
+DATA = pair--1.0.sql
+
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+</pre><p>
+
+ This makefile relies on <acronym class="acronym">PGXS</acronym>, which is described
+ in <a class="xref" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure">Section 38.18</a>. The command <code class="literal">make install</code>
+ will install the control and script files into the correct
+ directory as reported by <span class="application">pg_config</span>.
+ </p><p>
+ Once the files are installed, use the
+ <code class="command">CREATE EXTENSION</code> command to load the objects into
+ any particular database.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.16. Interfacing Extensions to Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.18. Extension Building Infrastructure</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/extend-how.html b/doc/src/sgml/html/extend-how.html
new file mode 100644
index 0000000..67433e3
--- /dev/null
+++ b/doc/src/sgml/html/extend-how.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.1. How Extensibility Works</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="extend.html" title="Chapter 38. Extending SQL" /><link rel="next" href="extend-type-system.html" title="38.2. The PostgreSQL Type System" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.1. How Extensibility Works</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="extend.html" title="Chapter 38. Extending SQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="extend-type-system.html" title="38.2. The PostgreSQL Type System">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTEND-HOW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.1. How Extensibility Works</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> is extensible because its operation is
+ catalog-driven. If you are familiar with standard
+ relational database systems, you know that they store information
+ about databases, tables, columns, etc., in what are
+ commonly known as system catalogs. (Some systems call
+ this the data dictionary.) The catalogs appear to the
+ user as tables like any other, but the <acronym class="acronym">DBMS</acronym> stores
+ its internal bookkeeping in them. One key difference
+ between <span class="productname">PostgreSQL</span> and standard relational database systems is
+ that <span class="productname">PostgreSQL</span> stores much more information in its
+ catalogs: not only information about tables and columns,
+ but also information about data types, functions, access
+ methods, and so on. These tables can be modified by
+ the user, and since <span class="productname">PostgreSQL</span> bases its operation
+ on these tables, this means that <span class="productname">PostgreSQL</span> can be
+ extended by users. By comparison, conventional
+ database systems can only be extended by changing hardcoded
+ procedures in the source code or by loading modules
+ specially written by the <acronym class="acronym">DBMS</acronym> vendor.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> server can moreover
+ incorporate user-written code into itself through dynamic loading.
+ That is, the user can specify an object code file (e.g., a shared
+ library) that implements a new type or function, and
+ <span class="productname">PostgreSQL</span> will load it as required.
+ Code written in <acronym class="acronym">SQL</acronym> is even more trivial to add
+ to the server. This ability to modify its operation <span class="quote">“<span class="quote">on the
+ fly</span>”</span> makes <span class="productname">PostgreSQL</span> uniquely
+ suited for rapid prototyping of new applications and storage
+ structures.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="extend.html" title="Chapter 38. Extending SQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="extend-type-system.html" title="38.2. The PostgreSQL Type System">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 38. Extending <acronym class="acronym">SQL</acronym> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.2. The <span class="productname">PostgreSQL</span> Type System</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/extend-pgxs.html b/doc/src/sgml/html/extend-pgxs.html
new file mode 100644
index 0000000..e196ad8
--- /dev/null
+++ b/doc/src/sgml/html/extend-pgxs.html
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.18. Extension Building Infrastructure</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension" /><link rel="next" href="triggers.html" title="Chapter 39. Triggers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.18. Extension Building Infrastructure</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="triggers.html" title="Chapter 39. Triggers">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTEND-PGXS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.18. Extension Building Infrastructure</h2></div></div></div><a id="id-1.8.3.21.2" class="indexterm"></a><p>
+ If you are thinking about distributing your
+ <span class="productname">PostgreSQL</span> extension modules, setting up a
+ portable build system for them can be fairly difficult. Therefore
+ the <span class="productname">PostgreSQL</span> installation provides a build
+ infrastructure for extensions, called <acronym class="acronym">PGXS</acronym>, so
+ that simple extension modules can be built simply against an
+ already installed server. <acronym class="acronym">PGXS</acronym> is mainly intended
+ for extensions that include C code, although it can be used for
+ pure-SQL extensions too. Note that <acronym class="acronym">PGXS</acronym> is not
+ intended to be a universal build system framework that can be used
+ to build any software interfacing to <span class="productname">PostgreSQL</span>;
+ it simply automates common build rules for simple server extension
+ modules. For more complicated packages, you might need to write your
+ own build system.
+ </p><p>
+ To use the <acronym class="acronym">PGXS</acronym> infrastructure for your extension,
+ you must write a simple makefile.
+ In the makefile, you need to set some variables
+ and include the global <acronym class="acronym">PGXS</acronym> makefile.
+ Here is an example that builds an extension module named
+ <code class="literal">isbn_issn</code>, consisting of a shared library containing
+ some C code, an extension control file, an SQL script, an include file
+ (only needed if other modules might need to access the extension functions
+ without going via SQL), and a documentation text file:
+</p><pre class="programlisting">
+MODULES = isbn_issn
+EXTENSION = isbn_issn
+DATA = isbn_issn--1.0.sql
+DOCS = README.isbn_issn
+HEADERS_isbn_issn = isbn_issn.h
+
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+</pre><p>
+ The last three lines should always be the same. Earlier in the
+ file, you assign variables or add custom
+ <span class="application">make</span> rules.
+ </p><p>
+ Set one of these three variables to specify what is built:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">MODULES</code></span></dt><dd><p>
+ list of shared-library objects to be built from source files with same
+ stem (do not include library suffixes in this list)
+ </p></dd><dt><span class="term"><code class="varname">MODULE_big</code></span></dt><dd><p>
+ a shared library to build from multiple source files
+ (list object files in <code class="varname">OBJS</code>)
+ </p></dd><dt><span class="term"><code class="varname">PROGRAM</code></span></dt><dd><p>
+ an executable program to build
+ (list object files in <code class="varname">OBJS</code>)
+ </p></dd></dl></div><p>
+
+ The following variables can also be set:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">EXTENSION</code></span></dt><dd><p>
+ extension name(s); for each name you must provide an
+ <code class="literal"><em class="replaceable"><code>extension</code></em>.control</code> file,
+ which will be installed into
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/share/extension</code>
+ </p></dd><dt><span class="term"><code class="varname">MODULEDIR</code></span></dt><dd><p>
+ subdirectory of <code class="literal"><em class="replaceable"><code>prefix</code></em>/share</code>
+ into which DATA and DOCS files should be installed
+ (if not set, default is <code class="literal">extension</code> if
+ <code class="varname">EXTENSION</code> is set,
+ or <code class="literal">contrib</code> if not)
+ </p></dd><dt><span class="term"><code class="varname">DATA</code></span></dt><dd><p>
+ random files to install into <code class="literal"><em class="replaceable"><code>prefix</code></em>/share/$MODULEDIR</code>
+ </p></dd><dt><span class="term"><code class="varname">DATA_built</code></span></dt><dd><p>
+ random files to install into
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/share/$MODULEDIR</code>,
+ which need to be built first
+ </p></dd><dt><span class="term"><code class="varname">DATA_TSEARCH</code></span></dt><dd><p>
+ random files to install under
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/share/tsearch_data</code>
+ </p></dd><dt><span class="term"><code class="varname">DOCS</code></span></dt><dd><p>
+ random files to install under
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/doc/$MODULEDIR</code>
+ </p></dd><dt><span class="term"><code class="varname">HEADERS</code><br /></span><span class="term"><code class="varname">HEADERS_built</code></span></dt><dd><p>
+ Files to (optionally build and) install under
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/include/server/$MODULEDIR/$MODULE_big</code>.
+ </p><p>
+ Unlike <code class="literal">DATA_built</code>, files in <code class="literal">HEADERS_built</code>
+ are not removed by the <code class="literal">clean</code> target; if you want them removed,
+ also add them to <code class="literal">EXTRA_CLEAN</code> or add your own rules to do it.
+ </p></dd><dt><span class="term"><code class="varname">HEADERS_$MODULE</code><br /></span><span class="term"><code class="varname">HEADERS_built_$MODULE</code></span></dt><dd><p>
+ Files to install (after building if specified) under
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/include/server/$MODULEDIR/$MODULE</code>,
+ where <code class="literal">$MODULE</code> must be a module name used
+ in <code class="literal">MODULES</code> or <code class="literal">MODULE_big</code>.
+ </p><p>
+ Unlike <code class="literal">DATA_built</code>, files in <code class="literal">HEADERS_built_$MODULE</code>
+ are not removed by the <code class="literal">clean</code> target; if you want them removed,
+ also add them to <code class="literal">EXTRA_CLEAN</code> or add your own rules to do it.
+ </p><p>
+ It is legal to use both variables for the same module, or any
+ combination, unless you have two module names in the
+ <code class="literal">MODULES</code> list that differ only by the presence of a
+ prefix <code class="literal">built_</code>, which would cause ambiguity. In
+ that (hopefully unlikely) case, you should use only the
+ <code class="literal">HEADERS_built_$MODULE</code> variables.
+ </p></dd><dt><span class="term"><code class="varname">SCRIPTS</code></span></dt><dd><p>
+ script files (not binaries) to install into
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/bin</code>
+ </p></dd><dt><span class="term"><code class="varname">SCRIPTS_built</code></span></dt><dd><p>
+ script files (not binaries) to install into
+ <code class="literal"><em class="replaceable"><code>prefix</code></em>/bin</code>,
+ which need to be built first
+ </p></dd><dt><span class="term"><code class="varname">REGRESS</code></span></dt><dd><p>
+ list of regression test cases (without suffix), see below
+ </p></dd><dt><span class="term"><code class="varname">REGRESS_OPTS</code></span></dt><dd><p>
+ additional switches to pass to <span class="application">pg_regress</span>
+ </p></dd><dt><span class="term"><code class="varname">ISOLATION</code></span></dt><dd><p>
+ list of isolation test cases, see below for more details
+ </p></dd><dt><span class="term"><code class="varname">ISOLATION_OPTS</code></span></dt><dd><p>
+ additional switches to pass to
+ <span class="application">pg_isolation_regress</span>
+ </p></dd><dt><span class="term"><code class="varname">TAP_TESTS</code></span></dt><dd><p>
+ switch defining if TAP tests need to be run, see below
+ </p></dd><dt><span class="term"><code class="varname">NO_INSTALL</code></span></dt><dd><p>
+ don't define an <code class="literal">install</code> target, useful for test
+ modules that don't need their build products to be installed
+ </p></dd><dt><span class="term"><code class="varname">NO_INSTALLCHECK</code></span></dt><dd><p>
+ don't define an <code class="literal">installcheck</code> target, useful e.g., if tests require special configuration, or don't use <span class="application">pg_regress</span>
+ </p></dd><dt><span class="term"><code class="varname">EXTRA_CLEAN</code></span></dt><dd><p>
+ extra files to remove in <code class="literal">make clean</code>
+ </p></dd><dt><span class="term"><code class="varname">PG_CPPFLAGS</code></span></dt><dd><p>
+ will be prepended to <code class="varname">CPPFLAGS</code>
+ </p></dd><dt><span class="term"><code class="varname">PG_CFLAGS</code></span></dt><dd><p>
+ will be appended to <code class="varname">CFLAGS</code>
+ </p></dd><dt><span class="term"><code class="varname">PG_CXXFLAGS</code></span></dt><dd><p>
+ will be appended to <code class="varname">CXXFLAGS</code>
+ </p></dd><dt><span class="term"><code class="varname">PG_LDFLAGS</code></span></dt><dd><p>
+ will be prepended to <code class="varname">LDFLAGS</code>
+ </p></dd><dt><span class="term"><code class="varname">PG_LIBS</code></span></dt><dd><p>
+ will be added to <code class="varname">PROGRAM</code> link line
+ </p></dd><dt><span class="term"><code class="varname">SHLIB_LINK</code></span></dt><dd><p>
+ will be added to <code class="varname">MODULE_big</code> link line
+ </p></dd><dt><span class="term"><code class="varname">PG_CONFIG</code></span></dt><dd><p>
+ path to <span class="application">pg_config</span> program for the
+ <span class="productname">PostgreSQL</span> installation to build against
+ (typically just <code class="literal">pg_config</code> to use the first one in your
+ <code class="varname">PATH</code>)
+ </p></dd></dl></div><p>
+ </p><p>
+ Put this makefile as <code class="literal">Makefile</code> in the directory
+ which holds your extension. Then you can do
+ <code class="literal">make</code> to compile, and then <code class="literal">make
+ install</code> to install your module. By default, the extension is
+ compiled and installed for the
+ <span class="productname">PostgreSQL</span> installation that
+ corresponds to the first <code class="command">pg_config</code> program
+ found in your <code class="varname">PATH</code>. You can use a different installation by
+ setting <code class="varname">PG_CONFIG</code> to point to its
+ <code class="command">pg_config</code> program, either within the makefile
+ or on the <code class="literal">make</code> command line.
+ </p><p>
+ You can also run <code class="literal">make</code> in a directory outside the source
+ tree of your extension, if you want to keep the build directory separate.
+ This procedure is also called a
+ <a id="id-1.8.3.21.7.2" class="indexterm"></a><em class="firstterm">VPATH</em>
+ build. Here's how:
+</p><pre class="programlisting">
+mkdir build_dir
+cd build_dir
+make -f /path/to/extension/source/tree/Makefile
+make -f /path/to/extension/source/tree/Makefile install
+</pre><p>
+ </p><p>
+ Alternatively, you can set up a directory for a VPATH build in a similar
+ way to how it is done for the core code. One way to do this is using the
+ core script <code class="filename">config/prep_buildtree</code>. Once this has been done
+ you can build by setting the <code class="literal">make</code> variable
+ <code class="varname">VPATH</code> like this:
+</p><pre class="programlisting">
+make VPATH=/path/to/extension/source/tree
+make VPATH=/path/to/extension/source/tree install
+</pre><p>
+ This procedure can work with a greater variety of directory layouts.
+ </p><p>
+ The scripts listed in the <code class="varname">REGRESS</code> variable are used for
+ regression testing of your module, which can be invoked by <code class="literal">make
+ installcheck</code> after doing <code class="literal">make install</code>. For this to
+ work you must have a running <span class="productname">PostgreSQL</span> server.
+ The script files listed in <code class="varname">REGRESS</code> must appear in a
+ subdirectory named <code class="literal">sql/</code> in your extension's directory.
+ These files must have extension <code class="literal">.sql</code>, which must not be
+ included in the <code class="varname">REGRESS</code> list in the makefile. For each
+ test there should also be a file containing the expected output in a
+ subdirectory named <code class="literal">expected/</code>, with the same stem and
+ extension <code class="literal">.out</code>. <code class="literal">make installcheck</code>
+ executes each test script with <span class="application">psql</span>, and compares the
+ resulting output to the matching expected file. Any differences will be
+ written to the file <code class="literal">regression.diffs</code> in <code class="command">diff
+ -c</code> format. Note that trying to run a test that is missing its
+ expected file will be reported as <span class="quote">“<span class="quote">trouble</span>”</span>, so make sure you
+ have all expected files.
+ </p><p>
+ The scripts listed in the <code class="varname">ISOLATION</code> variable are used
+ for tests stressing behavior of concurrent session with your module, which
+ can be invoked by <code class="literal">make installcheck</code> after doing
+ <code class="literal">make install</code>. For this to work you must have a
+ running <span class="productname">PostgreSQL</span> server. The script files
+ listed in <code class="varname">ISOLATION</code> must appear in a subdirectory
+ named <code class="literal">specs/</code> in your extension's directory. These files
+ must have extension <code class="literal">.spec</code>, which must not be included
+ in the <code class="varname">ISOLATION</code> list in the makefile. For each test
+ there should also be a file containing the expected output in a
+ subdirectory named <code class="literal">expected/</code>, with the same stem and
+ extension <code class="literal">.out</code>. <code class="literal">make installcheck</code>
+ executes each test script, and compares the resulting output to the
+ matching expected file. Any differences will be written to the file
+ <code class="literal">output_iso/regression.diffs</code> in
+ <code class="command">diff -c</code> format. Note that trying to run a test that is
+ missing its expected file will be reported as <span class="quote">“<span class="quote">trouble</span>”</span>, so
+ make sure you have all expected files.
+ </p><p>
+ <code class="literal">TAP_TESTS</code> enables the use of TAP tests. Data from each
+ run is present in a subdirectory named <code class="literal">tmp_check/</code>.
+ See also <a class="xref" href="regress-tap.html" title="33.4. TAP Tests">Section 33.4</a> for more details.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The easiest way to create the expected files is to create empty files,
+ then do a test run (which will of course report differences). Inspect
+ the actual result files found in the <code class="literal">results/</code>
+ directory (for tests in <code class="literal">REGRESS</code>), or
+ <code class="literal">output_iso/results/</code> directory (for tests in
+ <code class="literal">ISOLATION</code>), then copy them to
+ <code class="literal">expected/</code> if they match what you expect from the test.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="triggers.html" title="Chapter 39. Triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.17. Packaging Related Objects into an Extension </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 39. Triggers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/extend-type-system.html b/doc/src/sgml/html/extend-type-system.html
new file mode 100644
index 0000000..b3ce124
--- /dev/null
+++ b/doc/src/sgml/html/extend-type-system.html
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.2. The PostgreSQL Type System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="extend-how.html" title="38.1. How Extensibility Works" /><link rel="next" href="xfunc.html" title="38.3. User-Defined Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.2. The <span class="productname">PostgreSQL</span> Type System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="extend-how.html" title="38.1. How Extensibility Works">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc.html" title="38.3. User-Defined Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTEND-TYPE-SYSTEM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.2. The <span class="productname">PostgreSQL</span> Type System</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="extend-type-system.html#id-1.8.3.5.9">38.2.1. Base Types</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#id-1.8.3.5.10">38.2.2. Container Types</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#EXTEND-TYPE-SYSTEM-DOMAINS">38.2.3. Domains</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#id-1.8.3.5.12">38.2.4. Pseudo-Types</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">38.2.5. Polymorphic Types</a></span></dt></dl></div><a id="id-1.8.3.5.2" class="indexterm"></a><a id="id-1.8.3.5.3" class="indexterm"></a><a id="id-1.8.3.5.4" class="indexterm"></a><a id="id-1.8.3.5.5" class="indexterm"></a><a id="id-1.8.3.5.6" class="indexterm"></a><a id="id-1.8.3.5.7" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> data types can be divided into base
+ types, container types, domains, and pseudo-types.
+ </p><div class="sect2" id="id-1.8.3.5.9"><div class="titlepage"><div><div><h3 class="title">38.2.1. Base Types</h3></div></div></div><p>
+ Base types are those, like <code class="type">integer</code>, that are
+ implemented below the level of the <acronym class="acronym">SQL</acronym> language
+ (typically in a low-level language such as C). They generally
+ correspond to what are often known as abstract data types.
+ <span class="productname">PostgreSQL</span> can only operate on such
+ types through functions provided by the user and only understands
+ the behavior of such types to the extent that the user describes
+ them.
+ The built-in base types are described in <a class="xref" href="datatype.html" title="Chapter 8. Data Types">Chapter 8</a>.
+ </p><p>
+ Enumerated (enum) types can be considered as a subcategory of base
+ types. The main difference is that they can be created using
+ just <acronym class="acronym">SQL</acronym> commands, without any low-level programming.
+ Refer to <a class="xref" href="datatype-enum.html" title="8.7. Enumerated Types">Section 8.7</a> for more information.
+ </p></div><div class="sect2" id="id-1.8.3.5.10"><div class="titlepage"><div><div><h3 class="title">38.2.2. Container Types</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> has three kinds
+ of <span class="quote">“<span class="quote">container</span>”</span> types, which are types that contain multiple
+ values of other types. These are arrays, composites, and ranges.
+ </p><p>
+ Arrays can hold multiple values that are all of the same type. An array
+ type is automatically created for each base type, composite type, range
+ type, and domain type. But there are no arrays of arrays. So far as
+ the type system is concerned, multi-dimensional arrays are the same as
+ one-dimensional arrays. Refer to <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a> for more
+ information.
+ </p><p>
+ Composite types, or row types, are created whenever the user
+ creates a table. It is also possible to use <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> to
+ define a <span class="quote">“<span class="quote">stand-alone</span>”</span> composite type with no associated
+ table. A composite type is simply a list of types with
+ associated field names. A value of a composite type is a row or
+ record of field values. Refer to <a class="xref" href="rowtypes.html" title="8.16. Composite Types">Section 8.16</a>
+ for more information.
+ </p><p>
+ A range type can hold two values of the same type, which are the lower
+ and upper bounds of the range. Range types are user-created, although
+ a few built-in ones exist. Refer to <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>
+ for more information.
+ </p></div><div class="sect2" id="EXTEND-TYPE-SYSTEM-DOMAINS"><div class="titlepage"><div><div><h3 class="title">38.2.3. Domains</h3></div></div></div><p>
+ A domain is based on a particular underlying type and for many purposes
+ is interchangeable with its underlying type. However, a domain can have
+ constraints that restrict its valid values to a subset of what the
+ underlying type would allow. Domains are created using
+ the <acronym class="acronym">SQL</acronym> command <a class="xref" href="sql-createdomain.html" title="CREATE DOMAIN"><span class="refentrytitle">CREATE DOMAIN</span></a>.
+ Refer to <a class="xref" href="domains.html" title="8.18. Domain Types">Section 8.18</a> for more information.
+ </p></div><div class="sect2" id="id-1.8.3.5.12"><div class="titlepage"><div><div><h3 class="title">38.2.4. Pseudo-Types</h3></div></div></div><p>
+ There are a few <span class="quote">“<span class="quote">pseudo-types</span>”</span> for special purposes.
+ Pseudo-types cannot appear as columns of tables or components of
+ container types, but they can be used to declare the argument and
+ result types of functions. This provides a mechanism within the
+ type system to identify special classes of functions. <a class="xref" href="datatype-pseudo.html#DATATYPE-PSEUDOTYPES-TABLE" title="Table 8.27. Pseudo-Types">Table 8.27</a> lists the existing
+ pseudo-types.
+ </p></div><div class="sect2" id="EXTEND-TYPES-POLYMORPHIC"><div class="titlepage"><div><div><h3 class="title">38.2.5. Polymorphic Types</h3></div></div></div><a id="id-1.8.3.5.13.2" class="indexterm"></a><a id="id-1.8.3.5.13.3" class="indexterm"></a><a id="id-1.8.3.5.13.4" class="indexterm"></a><a id="id-1.8.3.5.13.5" class="indexterm"></a><p>
+ Some pseudo-types of special interest are the <em class="firstterm">polymorphic
+ types</em>, which are used to declare <em class="firstterm">polymorphic
+ functions</em>. This powerful feature allows a single function
+ definition to operate on many different data types, with the specific
+ data type(s) being determined by the data types actually passed to it
+ in a particular call. The polymorphic types are shown in
+ <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC-TABLE" title="Table 38.1. Polymorphic Types">Table 38.1</a>. Some examples of
+ their use appear in <a class="xref" href="xfunc-sql.html#XFUNC-SQL-POLYMORPHIC-FUNCTIONS" title="38.5.11. Polymorphic SQL Functions">Section 38.5.11</a>.
+ </p><div class="table" id="EXTEND-TYPES-POLYMORPHIC-TABLE"><p class="title"><strong>Table 38.1. Polymorphic Types</strong></p><div class="table-contents"><table class="table" summary="Polymorphic Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Family</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">anyelement</code></td><td>Simple</td><td>Indicates that a function accepts any data type</td></tr><tr><td><code class="type">anyarray</code></td><td>Simple</td><td>Indicates that a function accepts any array data type</td></tr><tr><td><code class="type">anynonarray</code></td><td>Simple</td><td>Indicates that a function accepts any non-array data type</td></tr><tr><td><code class="type">anyenum</code></td><td>Simple</td><td>Indicates that a function accepts any enum data type
+ (see <a class="xref" href="datatype-enum.html" title="8.7. Enumerated Types">Section 8.7</a>)
+ </td></tr><tr><td><code class="type">anyrange</code></td><td>Simple</td><td>Indicates that a function accepts any range data type
+ (see <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>)
+ </td></tr><tr><td><code class="type">anymultirange</code></td><td>Simple</td><td>Indicates that a function accepts any multirange data type
+ (see <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>)
+ </td></tr><tr><td><code class="type">anycompatible</code></td><td>Common</td><td>Indicates that a function accepts any data type,
+ with automatic promotion of multiple arguments to a common data type
+ </td></tr><tr><td><code class="type">anycompatiblearray</code></td><td>Common</td><td>Indicates that a function accepts any array data type,
+ with automatic promotion of multiple arguments to a common data type
+ </td></tr><tr><td><code class="type">anycompatiblenonarray</code></td><td>Common</td><td>Indicates that a function accepts any non-array data type,
+ with automatic promotion of multiple arguments to a common data type
+ </td></tr><tr><td><code class="type">anycompatiblerange</code></td><td>Common</td><td>Indicates that a function accepts any range data type,
+ with automatic promotion of multiple arguments to a common data type
+ </td></tr><tr><td><code class="type">anycompatiblemultirange</code></td><td>Common</td><td>Indicates that a function accepts any multirange data type,
+ with automatic promotion of multiple arguments to a common data type
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Polymorphic arguments and results are tied to each other and are resolved
+ to specific data types when a query calling a polymorphic function is
+ parsed. When there is more than one polymorphic argument, the actual
+ data types of the input values must match up as described below. If the
+ function's result type is polymorphic, or it has output parameters of
+ polymorphic types, the types of those results are deduced from the
+ actual types of the polymorphic inputs as described below.
+ </p><p>
+ For the <span class="quote">“<span class="quote">simple</span>”</span> family of polymorphic types, the
+ matching and deduction rules work like this:
+ </p><p>
+ Each position (either argument or return value) declared as
+ <code class="type">anyelement</code> is allowed to have any specific actual
+ data type, but in any given call they must all be the
+ <span class="emphasis"><em>same</em></span> actual type. Each
+ position declared as <code class="type">anyarray</code> can have any array data type,
+ but similarly they must all be the same type. And similarly,
+ positions declared as <code class="type">anyrange</code> must all be the same range
+ type. Likewise for <code class="type">anymultirange</code>.
+ </p><p>
+ Furthermore, if there are
+ positions declared <code class="type">anyarray</code> and others declared
+ <code class="type">anyelement</code>, the actual array type in the
+ <code class="type">anyarray</code> positions must be an array whose elements are
+ the same type appearing in the <code class="type">anyelement</code> positions.
+ <code class="type">anynonarray</code> is treated exactly the same as <code class="type">anyelement</code>,
+ but adds the additional constraint that the actual type must not be
+ an array type.
+ <code class="type">anyenum</code> is treated exactly the same as <code class="type">anyelement</code>,
+ but adds the additional constraint that the actual type must
+ be an enum type.
+ </p><p>
+ Similarly, if there are positions declared <code class="type">anyrange</code>
+ and others declared <code class="type">anyelement</code> or <code class="type">anyarray</code>,
+ the actual range type in the <code class="type">anyrange</code> positions must be a
+ range whose subtype is the same type appearing in
+ the <code class="type">anyelement</code> positions and the same as the element type
+ of the <code class="type">anyarray</code> positions.
+ If there are positions declared <code class="type">anymultirange</code>,
+ their actual multirange type must contain ranges matching parameters declared
+ <code class="type">anyrange</code> and base elements matching parameters declared
+ <code class="type">anyelement</code> and <code class="type">anyarray</code>.
+ </p><p>
+ Thus, when more than one argument position is declared with a polymorphic
+ type, the net effect is that only certain combinations of actual argument
+ types are allowed. For example, a function declared as
+ <code class="literal">equal(anyelement, anyelement)</code> will take any two input values,
+ so long as they are of the same data type.
+ </p><p>
+ When the return value of a function is declared as a polymorphic type,
+ there must be at least one argument position that is also polymorphic,
+ and the actual data type(s) supplied for the polymorphic arguments
+ determine the actual
+ result type for that call. For example, if there were not already
+ an array subscripting mechanism, one could define a function that
+ implements subscripting as <code class="literal">subscript(anyarray, integer)
+ returns anyelement</code>. This declaration constrains the actual first
+ argument to be an array type, and allows the parser to infer the correct
+ result type from the actual first argument's type. Another example
+ is that a function declared as <code class="literal">f(anyarray) returns anyenum</code>
+ will only accept arrays of enum types.
+ </p><p>
+ In most cases, the parser can infer the actual data type for a
+ polymorphic result type from arguments that are of a different
+ polymorphic type in the same family; for example <code class="type">anyarray</code>
+ can be deduced from <code class="type">anyelement</code> or vice versa.
+ An exception is that a
+ polymorphic result of type <code class="type">anyrange</code> requires an argument
+ of type <code class="type">anyrange</code>; it cannot be deduced
+ from <code class="type">anyarray</code> or <code class="type">anyelement</code> arguments. This
+ is because there could be multiple range types with the same subtype.
+ </p><p>
+ Note that <code class="type">anynonarray</code> and <code class="type">anyenum</code> do not represent
+ separate type variables; they are the same type as
+ <code class="type">anyelement</code>, just with an additional constraint. For
+ example, declaring a function as <code class="literal">f(anyelement, anyenum)</code>
+ is equivalent to declaring it as <code class="literal">f(anyenum, anyenum)</code>:
+ both actual arguments have to be the same enum type.
+ </p><p>
+ For the <span class="quote">“<span class="quote">common</span>”</span> family of polymorphic types, the
+ matching and deduction rules work approximately the same as for
+ the <span class="quote">“<span class="quote">simple</span>”</span> family, with one major difference: the
+ actual types of the arguments need not be identical, so long as they
+ can be implicitly cast to a single common type. The common type is
+ selected following the same rules as for <code class="literal">UNION</code> and
+ related constructs (see <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a>).
+ Selection of the common type considers the actual types
+ of <code class="type">anycompatible</code> and <code class="type">anycompatiblenonarray</code>
+ inputs, the array element types of <code class="type">anycompatiblearray</code>
+ inputs, the range subtypes of <code class="type">anycompatiblerange</code> inputs,
+ and the multirange subtypes of <code class="type">anycompatiblemultirange</code>
+ inputs. If <code class="type">anycompatiblenonarray</code> is present then the
+ common type is required to be a non-array type. Once a common type is
+ identified, arguments in <code class="type">anycompatible</code>
+ and <code class="type">anycompatiblenonarray</code> positions are automatically
+ cast to that type, and arguments in <code class="type">anycompatiblearray</code>
+ positions are automatically cast to the array type for that type.
+ </p><p>
+ Since there is no way to select a range type knowing only its subtype,
+ use of <code class="type">anycompatiblerange</code> and/or
+ <code class="type">anycompatiblemultirange</code> requires that all arguments declared
+ with that type have the same actual range and/or multirange type, and that
+ that type's subtype agree with the selected common type, so that no casting
+ of the range values is required. As with <code class="type">anyrange</code> and
+ <code class="type">anymultirange</code>, use of <code class="type">anycompatiblerange</code> and
+ <code class="type">anymultirange</code> as a function result type requires that there be
+ an <code class="type">anycompatiblerange</code> or <code class="type">anycompatiblemultirange</code>
+ argument.
+ </p><p>
+ Notice that there is no <code class="type">anycompatibleenum</code> type. Such a
+ type would not be very useful, since there normally are not any
+ implicit casts to enum types, meaning that there would be no way to
+ resolve a common type for dissimilar enum inputs.
+ </p><p>
+ The <span class="quote">“<span class="quote">simple</span>”</span> and <span class="quote">“<span class="quote">common</span>”</span> polymorphic
+ families represent two independent sets of type variables. Consider
+ for example
+</p><pre class="programlisting">
+CREATE FUNCTION myfunc(a anyelement, b anyelement,
+ c anycompatible, d anycompatible)
+RETURNS anycompatible AS ...
+</pre><p>
+ In an actual call of this function, the first two inputs must have
+ exactly the same type. The last two inputs must be promotable to a
+ common type, but this type need not have anything to do with the type
+ of the first two inputs. The result will have the common type of the
+ last two inputs.
+ </p><p>
+ A variadic function (one taking a variable number of arguments, as in
+ <a class="xref" href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS" title="38.5.6. SQL Functions with Variable Numbers of Arguments">Section 38.5.6</a>) can be
+ polymorphic: this is accomplished by declaring its last parameter as
+ <code class="literal">VARIADIC</code> <code class="type">anyarray</code> or
+ <code class="literal">VARIADIC</code> <code class="type">anycompatiblearray</code>.
+ For purposes of argument
+ matching and determining the actual result type, such a function behaves
+ the same as if you had written the appropriate number of
+ <code class="type">anynonarray</code> or <code class="type">anycompatiblenonarray</code>
+ parameters.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="extend-how.html" title="38.1. How Extensibility Works">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc.html" title="38.3. User-Defined Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.1. How Extensibility Works </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.3. User-Defined Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/extend.html b/doc/src/sgml/html/extend.html
new file mode 100644
index 0000000..6470057
--- /dev/null
+++ b/doc/src/sgml/html/extend.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 38. Extending SQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="server-programming.html" title="Part V. Server Programming" /><link rel="next" href="extend-how.html" title="38.1. How Extensibility Works" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="server-programming.html" title="Part V. Server Programming">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="extend-how.html" title="38.1. How Extensibility Works">Next</a></td></tr></table><hr /></div><div class="chapter" id="EXTEND"><div class="titlepage"><div><div><h2 class="title">Chapter 38. Extending <acronym class="acronym">SQL</acronym></h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="extend-how.html">38.1. How Extensibility Works</a></span></dt><dt><span class="sect1"><a href="extend-type-system.html">38.2. The <span class="productname">PostgreSQL</span> Type System</a></span></dt><dd><dl><dt><span class="sect2"><a href="extend-type-system.html#id-1.8.3.5.9">38.2.1. Base Types</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#id-1.8.3.5.10">38.2.2. Container Types</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#EXTEND-TYPE-SYSTEM-DOMAINS">38.2.3. Domains</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#id-1.8.3.5.12">38.2.4. Pseudo-Types</a></span></dt><dt><span class="sect2"><a href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC">38.2.5. Polymorphic Types</a></span></dt></dl></dd><dt><span class="sect1"><a href="xfunc.html">38.3. User-Defined Functions</a></span></dt><dt><span class="sect1"><a href="xproc.html">38.4. User-Defined Procedures</a></span></dt><dt><span class="sect1"><a href="xfunc-sql.html">38.5. Query Language (<acronym class="acronym">SQL</acronym>) Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS">38.5.1. Arguments for <acronym class="acronym">SQL</acronym> Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-BASE-FUNCTIONS">38.5.2. <acronym class="acronym">SQL</acronym> Functions on Base Types</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-COMPOSITE-FUNCTIONS">38.5.3. <acronym class="acronym">SQL</acronym> Functions on Composite Types</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS">38.5.4. <acronym class="acronym">SQL</acronym> Functions with Output Parameters</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS-PROC">38.5.5. <acronym class="acronym">SQL</acronym> Procedures with Output Parameters</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS">38.5.6. <acronym class="acronym">SQL</acronym> Functions with Variable Numbers of Arguments</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-PARAMETER-DEFAULTS">38.5.7. <acronym class="acronym">SQL</acronym> Functions with Default Values for Arguments</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-TABLE-FUNCTIONS">38.5.8. <acronym class="acronym">SQL</acronym> Functions as Table Sources</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-SET">38.5.9. <acronym class="acronym">SQL</acronym> Functions Returning Sets</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-TABLE">38.5.10. <acronym class="acronym">SQL</acronym> Functions Returning <code class="literal">TABLE</code></a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-POLYMORPHIC-FUNCTIONS">38.5.11. Polymorphic <acronym class="acronym">SQL</acronym> Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#id-1.8.3.8.21">38.5.12. <acronym class="acronym">SQL</acronym> Functions with Collations</a></span></dt></dl></dd><dt><span class="sect1"><a href="xfunc-overload.html">38.6. Function Overloading</a></span></dt><dt><span class="sect1"><a href="xfunc-volatility.html">38.7. Function Volatility Categories</a></span></dt><dt><span class="sect1"><a href="xfunc-pl.html">38.8. Procedural Language Functions</a></span></dt><dt><span class="sect1"><a href="xfunc-internal.html">38.9. Internal Functions</a></span></dt><dt><span class="sect1"><a href="xfunc-c.html">38.10. C-Language Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-C-DYNLOAD">38.10.1. Dynamic Loading</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-C-BASETYPE">38.10.2. Base Types in C-Language Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.7">38.10.3. Version 1 Calling Conventions</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.8">38.10.4. Writing Code</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#DFUNC">38.10.5. Compiling and Linking Dynamically-Loaded Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.10">38.10.6. Composite-Type Arguments</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.11">38.10.7. Returning Rows (Composite Types)</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-C-RETURN-SET">38.10.8. Returning Sets</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.13">38.10.9. Polymorphic Arguments and Return Types</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-SHARED-ADDIN">38.10.10. Shared Memory and LWLocks</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#EXTEND-CPP">38.10.11. Using C++ for Extensibility</a></span></dt></dl></dd><dt><span class="sect1"><a href="xfunc-optimization.html">38.11. Function Optimization Information</a></span></dt><dt><span class="sect1"><a href="xaggr.html">38.12. User-Defined Aggregates</a></span></dt><dd><dl><dt><span class="sect2"><a href="xaggr.html#XAGGR-MOVING-AGGREGATES">38.12.1. Moving-Aggregate Mode</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-POLYMORPHIC-AGGREGATES">38.12.2. Polymorphic and Variadic Aggregates</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-ORDERED-SET-AGGREGATES">38.12.3. Ordered-Set Aggregates</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-PARTIAL-AGGREGATES">38.12.4. Partial Aggregation</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-SUPPORT-FUNCTIONS">38.12.5. Support Functions for Aggregates</a></span></dt></dl></dd><dt><span class="sect1"><a href="xtypes.html">38.13. User-Defined Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="xtypes.html#XTYPES-TOAST">38.13.1. TOAST Considerations</a></span></dt></dl></dd><dt><span class="sect1"><a href="xoper.html">38.14. User-Defined Operators</a></span></dt><dt><span class="sect1"><a href="xoper-optimization.html">38.15. Operator Optimization Information</a></span></dt><dd><dl><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.6">38.15.1. <code class="literal">COMMUTATOR</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.7">38.15.2. <code class="literal">NEGATOR</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.8">38.15.3. <code class="literal">RESTRICT</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.9">38.15.4. <code class="literal">JOIN</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.10">38.15.5. <code class="literal">HASHES</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.11">38.15.6. <code class="literal">MERGES</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="xindex.html">38.16. Interfacing Extensions to Indexes</a></span></dt><dd><dl><dt><span class="sect2"><a href="xindex.html#XINDEX-OPCLASS">38.16.1. Index Methods and Operator Classes</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-STRATEGIES">38.16.2. Index Method Strategies</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-SUPPORT">38.16.3. Index Method Support Routines</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-EXAMPLE">38.16.4. An Example</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-OPFAMILY">38.16.5. Operator Classes and Operator Families</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-OPCLASS-DEPENDENCIES">38.16.6. System Dependencies on Operator Classes</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-ORDERING-OPS">38.16.7. Ordering Operators</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-OPCLASS-FEATURES">38.16.8. Special Features of Operator Classes</a></span></dt></dl></dd><dt><span class="sect1"><a href="extend-extensions.html">38.17. Packaging Related Objects into an Extension</a></span></dt><dd><dl><dt><span class="sect2"><a href="extend-extensions.html#id-1.8.3.20.11">38.17.1. Extension Files</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-RELOCATION">38.17.2. Extension Relocatability</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-CONFIG-TABLES">38.17.3. Extension Configuration Tables</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#id-1.8.3.20.14">38.17.4. Extension Updates</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#id-1.8.3.20.15">38.17.5. Installing Extensions Using Update Scripts</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-SECURITY">38.17.6. Security Considerations for Extensions</a></span></dt><dt><span class="sect2"><a href="extend-extensions.html#EXTEND-EXTENSIONS-EXAMPLE">38.17.7. Extension Example</a></span></dt></dl></dd><dt><span class="sect1"><a href="extend-pgxs.html">38.18. Extension Building Infrastructure</a></span></dt></dl></div><a id="id-1.8.3.2" class="indexterm"></a><p>
+ In the sections that follow, we will discuss how you
+ can extend the <span class="productname">PostgreSQL</span>
+ <acronym class="acronym">SQL</acronym> query language by adding:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ functions (starting in <a class="xref" href="xfunc.html" title="38.3. User-Defined Functions">Section 38.3</a>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ aggregates (starting in <a class="xref" href="xaggr.html" title="38.12. User-Defined Aggregates">Section 38.12</a>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ data types (starting in <a class="xref" href="xtypes.html" title="38.13. User-Defined Types">Section 38.13</a>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ operators (starting in <a class="xref" href="xoper.html" title="38.14. User-Defined Operators">Section 38.14</a>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ operator classes for indexes (starting in <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ packages of related objects (starting in <a class="xref" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Section 38.17</a>)
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="server-programming.html" title="Part V. Server Programming">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="extend-how.html" title="38.1. How Extensibility Works">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part V. Server Programming </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.1. How Extensibility Works</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/external-admin-tools.html b/doc/src/sgml/html/external-admin-tools.html
new file mode 100644
index 0000000..ddbfb08
--- /dev/null
+++ b/doc/src/sgml/html/external-admin-tools.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>H.2. Administration Tools</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="external-interfaces.html" title="H.1. Client Interfaces" /><link rel="next" href="external-pl.html" title="H.3. Procedural Languages" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">H.2. Administration Tools</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="external-interfaces.html" title="H.1. Client Interfaces">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><th width="60%" align="center">Appendix H. External Projects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="external-pl.html" title="H.3. Procedural Languages">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTERNAL-ADMIN-TOOLS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">H.2. Administration Tools</h2></div></div></div><a id="id-1.11.9.4.2" class="indexterm"></a><p>
+ There are several administration tools available for
+ <span class="productname">PostgreSQL</span>. The most popular is
+ <span class="application"><a class="ulink" href="https://www.pgadmin.org/" target="_top">pgAdmin</a></span>,
+ and there are several commercially available ones as well.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="external-interfaces.html" title="H.1. Client Interfaces">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="external-pl.html" title="H.3. Procedural Languages">Next</a></td></tr><tr><td width="40%" align="left" valign="top">H.1. Client Interfaces </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> H.3. Procedural Languages</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/external-extensions.html b/doc/src/sgml/html/external-extensions.html
new file mode 100644
index 0000000..fe0568a
--- /dev/null
+++ b/doc/src/sgml/html/external-extensions.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>H.4. Extensions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="external-pl.html" title="H.3. Procedural Languages" /><link rel="next" href="sourcerepo.html" title="Appendix I. The Source Code Repository" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">H.4. Extensions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="external-pl.html" title="H.3. Procedural Languages">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><th width="60%" align="center">Appendix H. External Projects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sourcerepo.html" title="Appendix I. The Source Code Repository">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTERNAL-EXTENSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">H.4. Extensions</h2></div></div></div><a id="id-1.11.9.6.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> is designed to be easily extensible. For
+ this reason, extensions loaded into the database can function
+ just like features that are built in. The
+ <code class="filename">contrib/</code> directory shipped with the source code
+ contains several extensions, which are described in
+ <a class="xref" href="contrib.html" title="Appendix F. Additional Supplied Modules">Appendix F</a>. Other extensions are developed
+ independently, like <span class="application"><a class="ulink" href="https://postgis.net/" target="_top">PostGIS</a></span>. Even
+ <span class="productname">PostgreSQL</span> replication solutions can be developed
+ externally. For example, <span class="application"> <a class="ulink" href="https://www.slony.info" target="_top">Slony-I</a></span> is a popular
+ primary/standby replication solution that is developed independently
+ from the core project.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="external-pl.html" title="H.3. Procedural Languages">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sourcerepo.html" title="Appendix I. The Source Code Repository">Next</a></td></tr><tr><td width="40%" align="left" valign="top">H.3. Procedural Languages </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix I. The Source Code Repository</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/external-interfaces.html b/doc/src/sgml/html/external-interfaces.html
new file mode 100644
index 0000000..31aabbb
--- /dev/null
+++ b/doc/src/sgml/html/external-interfaces.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>H.1. Client Interfaces</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="external-projects.html" title="Appendix H. External Projects" /><link rel="next" href="external-admin-tools.html" title="H.2. Administration Tools" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">H.1. Client Interfaces</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="external-projects.html" title="Appendix H. External Projects">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><th width="60%" align="center">Appendix H. External Projects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="external-admin-tools.html" title="H.2. Administration Tools">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTERNAL-INTERFACES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">H.1. Client Interfaces</h2></div></div></div><a id="id-1.11.9.3.2" class="indexterm"></a><p>
+ There are only two client interfaces included in the base
+ <span class="productname">PostgreSQL</span> distribution:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="link" href="libpq.html" title="Chapter 34. libpq — C Library">libpq</a> is included because it is the
+ primary C language interface, and because many other client interfaces
+ are built on top of it.
+ </p></li><li class="listitem"><p>
+ <a class="link" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">ECPG</a> is included because it depends on the
+ server-side SQL grammar, and is therefore sensitive to changes in
+ <span class="productname">PostgreSQL</span> itself.
+ </p></li></ul></div><p>
+
+ All other language interfaces are external projects and are distributed
+ separately. <a class="xref" href="external-interfaces.html#LANGUAGE-INTERFACE-TABLE" title="Table H.1. Externally Maintained Client Interfaces">Table H.1</a> includes a list of
+ some of these projects. Note that some of these packages might not be
+ released under the same license as <span class="productname">PostgreSQL</span>. For more
+ information on each language interface, including licensing terms, refer to
+ its website and documentation.
+ </p><div class="table" id="LANGUAGE-INTERFACE-TABLE"><p class="title"><strong>Table H.1. Externally Maintained Client Interfaces</strong></p><div class="table-contents"><table class="table" summary="Externally Maintained Client Interfaces" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Language</th><th>Comments</th><th>Website</th></tr></thead><tbody><tr><td>DBD::Pg</td><td>Perl</td><td>Perl DBI driver</td><td><a class="ulink" href="https://metacpan.org/release/DBD-Pg" target="_top">https://metacpan.org/release/DBD-Pg</a></td></tr><tr><td>JDBC</td><td>Java</td><td>Type 4 JDBC driver</td><td><a class="ulink" href="https://jdbc.postgresql.org/" target="_top">https://jdbc.postgresql.org/</a></td></tr><tr><td>libpqxx</td><td>C++</td><td>C++ interface</td><td><a class="ulink" href="https://pqxx.org/" target="_top">https://pqxx.org/</a></td></tr><tr><td>node-postgres</td><td>JavaScript</td><td>Node.js driver</td><td><a class="ulink" href="https://node-postgres.com/" target="_top">https://node-postgres.com/</a></td></tr><tr><td>Npgsql</td><td>.NET</td><td>.NET data provider</td><td><a class="ulink" href="https://www.npgsql.org/" target="_top">https://www.npgsql.org/</a></td></tr><tr><td>pgtcl</td><td>Tcl</td><td> </td><td><a class="ulink" href="https://github.com/flightaware/Pgtcl" target="_top">https://github.com/flightaware/Pgtcl</a></td></tr><tr><td>pgtclng</td><td>Tcl</td><td> </td><td><a class="ulink" href="https://sourceforge.net/projects/pgtclng/" target="_top">https://sourceforge.net/projects/pgtclng/</a></td></tr><tr><td>pq</td><td>Go</td><td>Pure Go driver for Go's database/sql</td><td><a class="ulink" href="https://github.com/lib/pq" target="_top">https://github.com/lib/pq</a></td></tr><tr><td>psqlODBC</td><td>ODBC</td><td>ODBC driver</td><td><a class="ulink" href="https://odbc.postgresql.org/" target="_top">https://odbc.postgresql.org/</a></td></tr><tr><td>psycopg</td><td>Python</td><td>DB API 2.0-compliant</td><td><a class="ulink" href="https://www.psycopg.org/" target="_top">https://www.psycopg.org/</a></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="external-projects.html" title="Appendix H. External Projects">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="external-admin-tools.html" title="H.2. Administration Tools">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix H. External Projects </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> H.2. Administration Tools</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/external-pl.html b/doc/src/sgml/html/external-pl.html
new file mode 100644
index 0000000..28e6ef4
--- /dev/null
+++ b/doc/src/sgml/html/external-pl.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>H.3. Procedural Languages</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="external-admin-tools.html" title="H.2. Administration Tools" /><link rel="next" href="external-extensions.html" title="H.4. Extensions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">H.3. Procedural Languages</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="external-admin-tools.html" title="H.2. Administration Tools">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><th width="60%" align="center">Appendix H. External Projects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="external-extensions.html" title="H.4. Extensions">Next</a></td></tr></table><hr /></div><div class="sect1" id="EXTERNAL-PL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">H.3. Procedural Languages</h2></div></div></div><a id="id-1.11.9.5.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> includes several procedural
+ languages with the base distribution: <a class="link" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">PL/pgSQL</a>, <a class="link" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">PL/Tcl</a>,
+ <a class="link" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">PL/Perl</a>, and <a class="link" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">PL/Python</a>.
+ </p><p>
+ In addition, there are a number of procedural languages that are developed
+ and maintained outside the core <span class="productname">PostgreSQL</span>
+ distribution. <a class="xref" href="external-pl.html#PL-LANGUAGE-TABLE" title="Table H.2. Externally Maintained Procedural Languages">Table H.2</a> lists some of these
+ packages. Note that some of these projects might not be released under the same
+ license as <span class="productname">PostgreSQL</span>. For more information on each
+ procedural language, including licensing information, refer to its website
+ and documentation.
+ </p><div class="table" id="PL-LANGUAGE-TABLE"><p class="title"><strong>Table H.2. Externally Maintained Procedural Languages</strong></p><div class="table-contents"><table class="table" summary="Externally Maintained Procedural Languages" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Language</th><th>Website</th></tr></thead><tbody><tr><td>PL/Java</td><td>Java</td><td><a class="ulink" href="https://tada.github.io/pljava/" target="_top">https://tada.github.io/pljava/</a></td></tr><tr><td>PL/Lua</td><td>Lua</td><td><a class="ulink" href="https://github.com/pllua/pllua-ng" target="_top">https://github.com/pllua/pllua-ng</a></td></tr><tr><td>PL/R</td><td>R</td><td><a class="ulink" href="https://github.com/postgres-plr/plr" target="_top">https://github.com/postgres-plr/plr</a></td></tr><tr><td>PL/sh</td><td>Unix shell</td><td><a class="ulink" href="https://github.com/petere/plsh" target="_top">https://github.com/petere/plsh</a></td></tr><tr><td>PL/v8</td><td>JavaScript</td><td><a class="ulink" href="https://github.com/plv8/plv8" target="_top">https://github.com/plv8/plv8</a></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="external-admin-tools.html" title="H.2. Administration Tools">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="external-projects.html" title="Appendix H. External Projects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="external-extensions.html" title="H.4. Extensions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">H.2. Administration Tools </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> H.4. Extensions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/external-projects.html b/doc/src/sgml/html/external-projects.html
new file mode 100644
index 0000000..a16f6c1
--- /dev/null
+++ b/doc/src/sgml/html/external-projects.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix H. External Projects</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-prog-server.html" title="G.2. Server Applications" /><link rel="next" href="external-interfaces.html" title="H.1. Client Interfaces" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix H. External Projects</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-prog-server.html" title="G.2. Server Applications">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="external-interfaces.html" title="H.1. Client Interfaces">Next</a></td></tr></table><hr /></div><div class="appendix" id="EXTERNAL-PROJECTS"><div class="titlepage"><div><div><h2 class="title">Appendix H. External Projects</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="external-interfaces.html">H.1. Client Interfaces</a></span></dt><dt><span class="sect1"><a href="external-admin-tools.html">H.2. Administration Tools</a></span></dt><dt><span class="sect1"><a href="external-pl.html">H.3. Procedural Languages</a></span></dt><dt><span class="sect1"><a href="external-extensions.html">H.4. Extensions</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> is a complex software project,
+ and managing the project is difficult. We have found that many
+ enhancements to <span class="productname">PostgreSQL</span> can be more
+ efficiently developed separately from the core project.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-prog-server.html" title="G.2. Server Applications">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="external-interfaces.html" title="H.1. Client Interfaces">Next</a></td></tr><tr><td width="40%" align="left" valign="top">G.2. Server Applications </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> H.1. Client Interfaces</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fdw-callbacks.html b/doc/src/sgml/html/fdw-callbacks.html
new file mode 100644
index 0000000..c1b6f50
--- /dev/null
+++ b/doc/src/sgml/html/fdw-callbacks.html
@@ -0,0 +1,1257 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>59.2. Foreign Data Wrapper Callback Routines</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fdw-functions.html" title="59.1. Foreign Data Wrapper Functions" /><link rel="next" href="fdw-helpers.html" title="59.3. Foreign Data Wrapper Helper Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">59.2. Foreign Data Wrapper Callback Routines</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-functions.html" title="59.1. Foreign Data Wrapper Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 59. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdw-helpers.html" title="59.3. Foreign Data Wrapper Helper Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FDW-CALLBACKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">59.2. Foreign Data Wrapper Callback Routines</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-SCAN">59.2.1. FDW Routines for Scanning Foreign Tables</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-JOIN-SCAN">59.2.2. FDW Routines for Scanning Foreign Joins</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-UPPER-PLANNING">59.2.3. FDW Routines for Planning Post-Scan/Join Processing</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-UPDATE">59.2.4. FDW Routines for Updating Foreign Tables</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-TRUNCATE">59.2.5. FDW Routines for <code class="command">TRUNCATE</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING">59.2.6. FDW Routines for Row Locking</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-EXPLAIN">59.2.7. FDW Routines for <code class="command">EXPLAIN</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ANALYZE">59.2.8. FDW Routines for <code class="command">ANALYZE</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-IMPORT">59.2.9. FDW Routines for <code class="command">IMPORT FOREIGN SCHEMA</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-PARALLEL">59.2.10. FDW Routines for Parallel Execution</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ASYNC">59.2.11. FDW Routines for Asynchronous Execution</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-REPARAMETERIZE-PATHS">59.2.12. FDW Routines for Reparameterization of Paths</a></span></dt></dl></div><p>
+ The FDW handler function returns a palloc'd <code class="structname">FdwRoutine</code>
+ struct containing pointers to the callback functions described below.
+ The scan-related functions are required, the rest are optional.
+ </p><p>
+ The <code class="structname">FdwRoutine</code> struct type is declared in
+ <code class="filename">src/include/foreign/fdwapi.h</code>, which see for additional
+ details.
+ </p><div class="sect2" id="FDW-CALLBACKS-SCAN"><div class="titlepage"><div><div><h3 class="title">59.2.1. FDW Routines for Scanning Foreign Tables</h3></div></div></div><p>
+</p><pre class="programlisting">
+void
+GetForeignRelSize(PlannerInfo *root,
+ RelOptInfo *baserel,
+ Oid foreigntableid);
+</pre><p>
+
+ Obtain relation size estimates for a foreign table. This is called
+ at the beginning of planning for a query that scans a foreign table.
+ <code class="literal">root</code> is the planner's global information about the query;
+ <code class="literal">baserel</code> is the planner's information about this table; and
+ <code class="literal">foreigntableid</code> is the <code class="structname">pg_class</code> OID of the
+ foreign table. (<code class="literal">foreigntableid</code> could be obtained from the
+ planner data structures, but it's passed explicitly to save effort.)
+ </p><p>
+ This function should update <code class="literal">baserel-&gt;rows</code> to be the
+ expected number of rows returned by the table scan, after accounting for
+ the filtering done by the restriction quals. The initial value of
+ <code class="literal">baserel-&gt;rows</code> is just a constant default estimate, which
+ should be replaced if at all possible. The function may also choose to
+ update <code class="literal">baserel-&gt;width</code> if it can compute a better estimate
+ of the average result row width.
+ (The initial value is based on column data types and on column
+ average-width values measured by the last <code class="command">ANALYZE</code>.)
+ Also, this function may update <code class="literal">baserel-&gt;tuples</code> if
+ it can compute a better estimate of the foreign table's total row count.
+ (The initial value is
+ from <code class="structname">pg_class</code>.<code class="structfield">reltuples</code>
+ which represents the total row count seen by the
+ last <code class="command">ANALYZE</code>; it will be <code class="literal">-1</code> if
+ no <code class="command">ANALYZE</code> has been done on this foreign table.)
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p><p>
+</p><pre class="programlisting">
+void
+GetForeignPaths(PlannerInfo *root,
+ RelOptInfo *baserel,
+ Oid foreigntableid);
+</pre><p>
+
+ Create possible access paths for a scan on a foreign table.
+ This is called during query planning.
+ The parameters are the same as for <code class="function">GetForeignRelSize</code>,
+ which has already been called.
+ </p><p>
+ This function must generate at least one access path
+ (<code class="structname">ForeignPath</code> node) for a scan on the foreign table and
+ must call <code class="function">add_path</code> to add each such path to
+ <code class="literal">baserel-&gt;pathlist</code>. It's recommended to use
+ <code class="function">create_foreignscan_path</code> to build the
+ <code class="structname">ForeignPath</code> nodes. The function can generate multiple
+ access paths, e.g., a path which has valid <code class="literal">pathkeys</code> to
+ represent a pre-sorted result. Each access path must contain cost
+ estimates, and can contain any FDW-private information that is needed to
+ identify the specific scan method intended.
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p><p>
+</p><pre class="programlisting">
+ForeignScan *
+GetForeignPlan(PlannerInfo *root,
+ RelOptInfo *baserel,
+ Oid foreigntableid,
+ ForeignPath *best_path,
+ List *tlist,
+ List *scan_clauses,
+ Plan *outer_plan);
+</pre><p>
+
+ Create a <code class="structname">ForeignScan</code> plan node from the selected foreign
+ access path. This is called at the end of query planning.
+ The parameters are as for <code class="function">GetForeignRelSize</code>, plus
+ the selected <code class="structname">ForeignPath</code> (previously produced by
+ <code class="function">GetForeignPaths</code>, <code class="function">GetForeignJoinPaths</code>,
+ or <code class="function">GetForeignUpperPaths</code>),
+ the target list to be emitted by the plan node,
+ the restriction clauses to be enforced by the plan node,
+ and the outer subplan of the <code class="structname">ForeignScan</code>,
+ which is used for rechecks performed by <code class="function">RecheckForeignScan</code>.
+ (If the path is for a join rather than a base
+ relation, <code class="literal">foreigntableid</code> is <code class="literal">InvalidOid</code>.)
+ </p><p>
+ This function must create and return a <code class="structname">ForeignScan</code> plan
+ node; it's recommended to use <code class="function">make_foreignscan</code> to build the
+ <code class="structname">ForeignScan</code> node.
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p><p>
+</p><pre class="programlisting">
+void
+BeginForeignScan(ForeignScanState *node,
+ int eflags);
+</pre><p>
+
+ Begin executing a foreign scan. This is called during executor startup.
+ It should perform any initialization needed before the scan can start,
+ but not start executing the actual scan (that should be done upon the
+ first call to <code class="function">IterateForeignScan</code>).
+ The <code class="structname">ForeignScanState</code> node has already been created, but
+ its <code class="structfield">fdw_state</code> field is still NULL. Information about
+ the table to scan is accessible through the
+ <code class="structname">ForeignScanState</code> node (in particular, from the underlying
+ <code class="structname">ForeignScan</code> plan node, which contains any FDW-private
+ information provided by <code class="function">GetForeignPlan</code>).
+ <code class="literal">eflags</code> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </p><p>
+ Note that when <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is
+ true, this function should not perform any externally-visible actions;
+ it should only do the minimum required to make the node state valid
+ for <code class="function">ExplainForeignScan</code> and <code class="function">EndForeignScan</code>.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot *
+IterateForeignScan(ForeignScanState *node);
+</pre><p>
+
+ Fetch one row from the foreign source, returning it in a tuple table slot
+ (the node's <code class="structfield">ScanTupleSlot</code> should be used for this
+ purpose). Return NULL if no more rows are available. The tuple table
+ slot infrastructure allows either a physical or virtual tuple to be
+ returned; in most cases the latter choice is preferable from a
+ performance standpoint. Note that this is called in a short-lived memory
+ context that will be reset between invocations. Create a memory context
+ in <code class="function">BeginForeignScan</code> if you need longer-lived storage, or use
+ the <code class="structfield">es_query_cxt</code> of the node's <code class="structname">EState</code>.
+ </p><p>
+ The rows returned must match the <code class="structfield">fdw_scan_tlist</code> target
+ list if one was supplied, otherwise they must match the row type of the
+ foreign table being scanned. If you choose to optimize away fetching
+ columns that are not needed, you should insert nulls in those column
+ positions, or else generate a <code class="structfield">fdw_scan_tlist</code> list with
+ those columns omitted.
+ </p><p>
+ Note that <span class="productname">PostgreSQL</span>'s executor doesn't care
+ whether the rows returned violate any constraints that were defined on
+ the foreign table — but the planner does care, and may optimize
+ queries incorrectly if there are rows visible in the foreign table that
+ do not satisfy a declared constraint. If a constraint is violated when
+ the user has declared that the constraint should hold true, it may be
+ appropriate to raise an error (just as you would need to do in the case
+ of a data type mismatch).
+ </p><p>
+</p><pre class="programlisting">
+void
+ReScanForeignScan(ForeignScanState *node);
+</pre><p>
+
+ Restart the scan from the beginning. Note that any parameters the
+ scan depends on may have changed value, so the new scan does not
+ necessarily return exactly the same rows.
+ </p><p>
+</p><pre class="programlisting">
+void
+EndForeignScan(ForeignScanState *node);
+</pre><p>
+
+ End the scan and release resources. It is normally not important
+ to release palloc'd memory, but for example open files and connections
+ to remote servers should be cleaned up.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-JOIN-SCAN"><div class="titlepage"><div><div><h3 class="title">59.2.2. FDW Routines for Scanning Foreign Joins</h3></div></div></div><p>
+ If an FDW supports performing foreign joins remotely (rather than
+ by fetching both tables' data and doing the join locally), it should
+ provide this callback function:
+ </p><p>
+</p><pre class="programlisting">
+void
+GetForeignJoinPaths(PlannerInfo *root,
+ RelOptInfo *joinrel,
+ RelOptInfo *outerrel,
+ RelOptInfo *innerrel,
+ JoinType jointype,
+ JoinPathExtraData *extra);
+</pre><p>
+ Create possible access paths for a join of two (or more) foreign tables
+ that all belong to the same foreign server. This optional
+ function is called during query planning. As
+ with <code class="function">GetForeignPaths</code>, this function should
+ generate <code class="structname">ForeignPath</code> path(s) for the
+ supplied <code class="literal">joinrel</code>
+ (use <code class="function">create_foreign_join_path</code> to build them),
+ and call <code class="function">add_path</code> to add these
+ paths to the set of paths considered for the join. But unlike
+ <code class="function">GetForeignPaths</code>, it is not necessary that this function
+ succeed in creating at least one path, since paths involving local
+ joining are always possible.
+ </p><p>
+ Note that this function will be invoked repeatedly for the same join
+ relation, with different combinations of inner and outer relations; it is
+ the responsibility of the FDW to minimize duplicated work.
+ </p><p>
+ If a <code class="structname">ForeignPath</code> path is chosen for the join, it will
+ represent the entire join process; paths generated for the component
+ tables and subsidiary joins will not be used. Subsequent processing of
+ the join path proceeds much as it does for a path scanning a single
+ foreign table. One difference is that the <code class="structfield">scanrelid</code> of
+ the resulting <code class="structname">ForeignScan</code> plan node should be set to zero,
+ since there is no single relation that it represents; instead,
+ the <code class="structfield">fs_relids</code> field of the <code class="structname">ForeignScan</code>
+ node represents the set of relations that were joined. (The latter field
+ is set up automatically by the core planner code, and need not be filled
+ by the FDW.) Another difference is that, because the column list for a
+ remote join cannot be found from the system catalogs, the FDW must
+ fill <code class="structfield">fdw_scan_tlist</code> with an appropriate list
+ of <code class="structfield">TargetEntry</code> nodes, representing the set of columns
+ it will supply at run time in the tuples it returns.
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-UPPER-PLANNING"><div class="titlepage"><div><div><h3 class="title">59.2.3. FDW Routines for Planning Post-Scan/Join Processing</h3></div></div></div><p>
+ If an FDW supports performing remote post-scan/join processing, such as
+ remote aggregation, it should provide this callback function:
+ </p><p>
+</p><pre class="programlisting">
+void
+GetForeignUpperPaths(PlannerInfo *root,
+ UpperRelationKind stage,
+ RelOptInfo *input_rel,
+ RelOptInfo *output_rel,
+ void *extra);
+</pre><p>
+ Create possible access paths for <em class="firstterm">upper relation</em> processing,
+ which is the planner's term for all post-scan/join query processing, such
+ as aggregation, window functions, sorting, and table updates. This
+ optional function is called during query planning. Currently, it is
+ called only if all base relation(s) involved in the query belong to the
+ same FDW. This function should generate <code class="structname">ForeignPath</code>
+ path(s) for any post-scan/join processing that the FDW knows how to
+ perform remotely
+ (use <code class="function">create_foreign_upper_path</code> to build them),
+ and call <code class="function">add_path</code> to add these paths to
+ the indicated upper relation. As with <code class="function">GetForeignJoinPaths</code>,
+ it is not necessary that this function succeed in creating any paths,
+ since paths involving local processing are always possible.
+ </p><p>
+ The <code class="literal">stage</code> parameter identifies which post-scan/join step is
+ currently being considered. <code class="literal">output_rel</code> is the upper relation
+ that should receive paths representing computation of this step,
+ and <code class="literal">input_rel</code> is the relation representing the input to this
+ step. The <code class="literal">extra</code> parameter provides additional details,
+ currently, it is set only for <code class="literal">UPPERREL_PARTIAL_GROUP_AGG</code>
+ or <code class="literal">UPPERREL_GROUP_AGG</code>, in which case it points to a
+ <code class="literal">GroupPathExtraData</code> structure;
+ or for <code class="literal">UPPERREL_FINAL</code>, in which case it points to a
+ <code class="literal">FinalPathExtraData</code> structure.
+ (Note that <code class="structname">ForeignPath</code> paths added
+ to <code class="literal">output_rel</code> would typically not have any direct dependency
+ on paths of the <code class="literal">input_rel</code>, since their processing is expected
+ to be done externally. However, examining paths previously generated for
+ the previous processing step can be useful to avoid redundant planning
+ work.)
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-UPDATE"><div class="titlepage"><div><div><h3 class="title">59.2.4. FDW Routines for Updating Foreign Tables</h3></div></div></div><p>
+ If an FDW supports writable foreign tables, it should provide
+ some or all of the following callback functions depending on
+ the needs and capabilities of the FDW:
+ </p><p>
+</p><pre class="programlisting">
+void
+AddForeignUpdateTargets(PlannerInfo *root,
+ Index rtindex,
+ RangeTblEntry *target_rte,
+ Relation target_relation);
+</pre><p>
+
+ <code class="command">UPDATE</code> and <code class="command">DELETE</code> operations are performed
+ against rows previously fetched by the table-scanning functions. The
+ FDW may need extra information, such as a row ID or the values of
+ primary-key columns, to ensure that it can identify the exact row to
+ update or delete. To support that, this function can add extra hidden,
+ or <span class="quote">“<span class="quote">junk</span>”</span>, target columns to the list of columns that are to be
+ retrieved from the foreign table during an <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code>.
+ </p><p>
+ To do that, construct a <code class="structname">Var</code> representing
+ an extra value you need, and pass it
+ to <code class="function">add_row_identity_var</code>, along with a name for
+ the junk column. (You can do this more than once if several columns
+ are needed.) You must choose a distinct junk column name for each
+ different <code class="structname">Var</code> you need, except
+ that <code class="structname">Var</code>s that are identical except for
+ the <code class="structfield">varno</code> field can and should share a
+ column name.
+ The core system uses the junk column names
+ <code class="literal">tableoid</code> for a
+ table's <code class="structfield">tableoid</code> column,
+ <code class="literal">ctid</code>
+ or <code class="literal">ctid<em class="replaceable"><code>N</code></em></code>
+ for <code class="structfield">ctid</code>,
+ <code class="literal">wholerow</code>
+ for a whole-row <code class="structname">Var</code> marked with
+ <code class="structfield">vartype</code> = <code class="type">RECORD</code>,
+ and <code class="literal">wholerow<em class="replaceable"><code>N</code></em></code>
+ for a whole-row <code class="structname">Var</code> with
+ <code class="structfield">vartype</code> equal to the table's declared row type.
+ Re-use these names when you can (the planner will combine duplicate
+ requests for identical junk columns). If you need another kind of
+ junk column besides these, it might be wise to choose a name prefixed
+ with your extension name, to avoid conflicts against other FDWs.
+ </p><p>
+ If the <code class="function">AddForeignUpdateTargets</code> pointer is set to
+ <code class="literal">NULL</code>, no extra target expressions are added.
+ (This will make it impossible to implement <code class="command">DELETE</code>
+ operations, though <code class="command">UPDATE</code> may still be feasible if the FDW
+ relies on an unchanging primary key to identify rows.)
+ </p><p>
+</p><pre class="programlisting">
+List *
+PlanForeignModify(PlannerInfo *root,
+ ModifyTable *plan,
+ Index resultRelation,
+ int subplan_index);
+</pre><p>
+
+ Perform any additional planning actions needed for an insert, update, or
+ delete on a foreign table. This function generates the FDW-private
+ information that will be attached to the <code class="structname">ModifyTable</code> plan
+ node that performs the update action. This private information must
+ have the form of a <code class="literal">List</code>, and will be delivered to
+ <code class="function">BeginForeignModify</code> during the execution stage.
+ </p><p>
+ <code class="literal">root</code> is the planner's global information about the query.
+ <code class="literal">plan</code> is the <code class="structname">ModifyTable</code> plan node, which is
+ complete except for the <code class="structfield">fdwPrivLists</code> field.
+ <code class="literal">resultRelation</code> identifies the target foreign table by its
+ range table index. <code class="literal">subplan_index</code> identifies which target of
+ the <code class="structname">ModifyTable</code> plan node this is, counting from zero;
+ use this if you want to index into per-target-relation substructures of the
+ <code class="literal">plan</code> node.
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p><p>
+ If the <code class="function">PlanForeignModify</code> pointer is set to
+ <code class="literal">NULL</code>, no additional plan-time actions are taken, and the
+ <code class="literal">fdw_private</code> list delivered to
+ <code class="function">BeginForeignModify</code> will be NIL.
+ </p><p>
+</p><pre class="programlisting">
+void
+BeginForeignModify(ModifyTableState *mtstate,
+ ResultRelInfo *rinfo,
+ List *fdw_private,
+ int subplan_index,
+ int eflags);
+</pre><p>
+
+ Begin executing a foreign table modification operation. This routine is
+ called during executor startup. It should perform any initialization
+ needed prior to the actual table modifications. Subsequently,
+ <code class="function">ExecForeignInsert/ExecForeignBatchInsert</code>,
+ <code class="function">ExecForeignUpdate</code> or
+ <code class="function">ExecForeignDelete</code> will be called for tuple(s) to be
+ inserted, updated, or deleted.
+ </p><p>
+ <code class="literal">mtstate</code> is the overall state of the
+ <code class="structname">ModifyTable</code> plan node being executed; global data about
+ the plan and execution state is available via this structure.
+ <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
+ the target foreign table. (The <code class="structfield">ri_FdwState</code> field of
+ <code class="structname">ResultRelInfo</code> is available for the FDW to store any
+ private state it needs for this operation.)
+ <code class="literal">fdw_private</code> contains the private data generated by
+ <code class="function">PlanForeignModify</code>, if any.
+ <code class="literal">subplan_index</code> identifies which target of
+ the <code class="structname">ModifyTable</code> plan node this is.
+ <code class="literal">eflags</code> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </p><p>
+ Note that when <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is
+ true, this function should not perform any externally-visible actions;
+ it should only do the minimum required to make the node state valid
+ for <code class="function">ExplainForeignModify</code> and <code class="function">EndForeignModify</code>.
+ </p><p>
+ If the <code class="function">BeginForeignModify</code> pointer is set to
+ <code class="literal">NULL</code>, no action is taken during executor startup.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot *
+ExecForeignInsert(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot *slot,
+ TupleTableSlot *planSlot);
+</pre><p>
+
+ Insert one tuple into the foreign table.
+ <code class="literal">estate</code> is global execution state for the query.
+ <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
+ the target foreign table.
+ <code class="literal">slot</code> contains the tuple to be inserted; it will match the
+ row-type definition of the foreign table.
+ <code class="literal">planSlot</code> contains the tuple that was generated by the
+ <code class="structname">ModifyTable</code> plan node's subplan; it differs from
+ <code class="literal">slot</code> in possibly containing additional <span class="quote">“<span class="quote">junk</span>”</span>
+ columns. (The <code class="literal">planSlot</code> is typically of little interest
+ for <code class="command">INSERT</code> cases, but is provided for completeness.)
+ </p><p>
+ The return value is either a slot containing the data that was actually
+ inserted (this might differ from the data supplied, for example as a
+ result of trigger actions), or NULL if no row was actually inserted
+ (again, typically as a result of triggers). The passed-in
+ <code class="literal">slot</code> can be re-used for this purpose.
+ </p><p>
+ The data in the returned slot is used only if the <code class="command">INSERT</code>
+ statement has a <code class="literal">RETURNING</code> clause or involves a view
+ <code class="literal">WITH CHECK OPTION</code>; or if the foreign table has
+ an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns,
+ but the FDW could choose to optimize away returning some or all columns
+ depending on the contents of the <code class="literal">RETURNING</code> clause or
+ <code class="literal">WITH CHECK OPTION</code> constraints. Regardless, some slot
+ must be returned to indicate success, or the query's reported row count
+ will be wrong.
+ </p><p>
+ If the <code class="function">ExecForeignInsert</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to insert into the foreign table will fail
+ with an error message.
+ </p><p>
+ Note that this function is also called when inserting routed tuples into
+ a foreign-table partition or executing <code class="command">COPY FROM</code> on
+ a foreign table, in which case it is called in a different way than it
+ is in the <code class="command">INSERT</code> case. See the callback functions
+ described below that allow the FDW to support that.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot **
+ExecForeignBatchInsert(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot **slots,
+ TupleTableSlot **planSlots,
+ int *numSlots);
+</pre><p>
+
+ Insert multiple tuples in bulk into the foreign table.
+ The parameters are the same for <code class="function">ExecForeignInsert</code>
+ except <code class="literal">slots</code> and <code class="literal">planSlots</code> contain
+ multiple tuples and <code class="literal">*numSlots</code> specifies the number of
+ tuples in those arrays.
+ </p><p>
+ The return value is an array of slots containing the data that was
+ actually inserted (this might differ from the data supplied, for
+ example as a result of trigger actions.)
+ The passed-in <code class="literal">slots</code> can be re-used for this purpose.
+ The number of successfully inserted tuples is returned in
+ <code class="literal">*numSlots</code>.
+ </p><p>
+ The data in the returned slot is used only if the <code class="command">INSERT</code>
+ statement involves a view
+ <code class="literal">WITH CHECK OPTION</code>; or if the foreign table has
+ an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns,
+ but the FDW could choose to optimize away returning some or all columns
+ depending on the contents of the
+ <code class="literal">WITH CHECK OPTION</code> constraints.
+ </p><p>
+ If the <code class="function">ExecForeignBatchInsert</code> or
+ <code class="function">GetForeignModifyBatchSize</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to insert into the foreign table will
+ use <code class="function">ExecForeignInsert</code>.
+ This function is not used if the <code class="command">INSERT</code> has the
+ <code class="literal">RETURNING</code> clause.
+ </p><p>
+ Note that this function is also called when inserting routed tuples into
+ a foreign-table partition. See the callback functions
+ described below that allow the FDW to support that.
+ </p><p>
+</p><pre class="programlisting">
+int
+GetForeignModifyBatchSize(ResultRelInfo *rinfo);
+</pre><p>
+
+ Report the maximum number of tuples that a single
+ <code class="function">ExecForeignBatchInsert</code> call can handle for
+ the specified foreign table. The executor passes at most
+ the given number of tuples to <code class="function">ExecForeignBatchInsert</code>.
+ <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
+ the target foreign table.
+ The FDW is expected to provide a foreign server and/or foreign
+ table option for the user to set this value, or some hard-coded value.
+ </p><p>
+ If the <code class="function">ExecForeignBatchInsert</code> or
+ <code class="function">GetForeignModifyBatchSize</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to insert into the foreign table will
+ use <code class="function">ExecForeignInsert</code>.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot *
+ExecForeignUpdate(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot *slot,
+ TupleTableSlot *planSlot);
+</pre><p>
+
+ Update one tuple in the foreign table.
+ <code class="literal">estate</code> is global execution state for the query.
+ <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
+ the target foreign table.
+ <code class="literal">slot</code> contains the new data for the tuple; it will match the
+ row-type definition of the foreign table.
+ <code class="literal">planSlot</code> contains the tuple that was generated by the
+ <code class="structname">ModifyTable</code> plan node's subplan. Unlike
+ <code class="literal">slot</code>, this tuple contains only the new values for
+ columns changed by the query, so do not rely on attribute numbers of the
+ foreign table to index into <code class="literal">planSlot</code>.
+ Also, <code class="literal">planSlot</code> typically contains
+ additional <span class="quote">“<span class="quote">junk</span>”</span> columns. In particular, any junk columns
+ that were requested by <code class="function">AddForeignUpdateTargets</code> will
+ be available from this slot.
+ </p><p>
+ The return value is either a slot containing the row as it was actually
+ updated (this might differ from the data supplied, for example as a
+ result of trigger actions), or NULL if no row was actually updated
+ (again, typically as a result of triggers). The passed-in
+ <code class="literal">slot</code> can be re-used for this purpose.
+ </p><p>
+ The data in the returned slot is used only if the <code class="command">UPDATE</code>
+ statement has a <code class="literal">RETURNING</code> clause or involves a view
+ <code class="literal">WITH CHECK OPTION</code>; or if the foreign table has
+ an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns,
+ but the FDW could choose to optimize away returning some or all columns
+ depending on the contents of the <code class="literal">RETURNING</code> clause or
+ <code class="literal">WITH CHECK OPTION</code> constraints. Regardless, some slot
+ must be returned to indicate success, or the query's reported row count
+ will be wrong.
+ </p><p>
+ If the <code class="function">ExecForeignUpdate</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to update the foreign table will fail
+ with an error message.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot *
+ExecForeignDelete(EState *estate,
+ ResultRelInfo *rinfo,
+ TupleTableSlot *slot,
+ TupleTableSlot *planSlot);
+</pre><p>
+
+ Delete one tuple from the foreign table.
+ <code class="literal">estate</code> is global execution state for the query.
+ <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
+ the target foreign table.
+ <code class="literal">slot</code> contains nothing useful upon call, but can be used to
+ hold the returned tuple.
+ <code class="literal">planSlot</code> contains the tuple that was generated by the
+ <code class="structname">ModifyTable</code> plan node's subplan; in particular, it will
+ carry any junk columns that were requested by
+ <code class="function">AddForeignUpdateTargets</code>. The junk column(s) must be used
+ to identify the tuple to be deleted.
+ </p><p>
+ The return value is either a slot containing the row that was deleted,
+ or NULL if no row was deleted (typically as a result of triggers). The
+ passed-in <code class="literal">slot</code> can be used to hold the tuple to be returned.
+ </p><p>
+ The data in the returned slot is used only if the <code class="command">DELETE</code>
+ query has a <code class="literal">RETURNING</code> clause or the foreign table has
+ an <code class="literal">AFTER ROW</code> trigger. Triggers require all columns, but the
+ FDW could choose to optimize away returning some or all columns depending
+ on the contents of the <code class="literal">RETURNING</code> clause. Regardless, some
+ slot must be returned to indicate success, or the query's reported row
+ count will be wrong.
+ </p><p>
+ If the <code class="function">ExecForeignDelete</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to delete from the foreign table will fail
+ with an error message.
+ </p><p>
+</p><pre class="programlisting">
+void
+EndForeignModify(EState *estate,
+ ResultRelInfo *rinfo);
+</pre><p>
+
+ End the table update and release resources. It is normally not important
+ to release palloc'd memory, but for example open files and connections
+ to remote servers should be cleaned up.
+ </p><p>
+ If the <code class="function">EndForeignModify</code> pointer is set to
+ <code class="literal">NULL</code>, no action is taken during executor shutdown.
+ </p><p>
+ Tuples inserted into a partitioned table by <code class="command">INSERT</code> or
+ <code class="command">COPY FROM</code> are routed to partitions. If an FDW
+ supports routable foreign-table partitions, it should also provide the
+ following callback functions. These functions are also called when
+ <code class="command">COPY FROM</code> is executed on a foreign table.
+ </p><p>
+</p><pre class="programlisting">
+void
+BeginForeignInsert(ModifyTableState *mtstate,
+ ResultRelInfo *rinfo);
+</pre><p>
+
+ Begin executing an insert operation on a foreign table. This routine is
+ called right before the first tuple is inserted into the foreign table
+ in both cases when it is the partition chosen for tuple routing and the
+ target specified in a <code class="command">COPY FROM</code> command. It should
+ perform any initialization needed prior to the actual insertion.
+ Subsequently, <code class="function">ExecForeignInsert</code> or
+ <code class="function">ExecForeignBatchInsert</code> will be called for
+ tuple(s) to be inserted into the foreign table.
+ </p><p>
+ <code class="literal">mtstate</code> is the overall state of the
+ <code class="structname">ModifyTable</code> plan node being executed; global data about
+ the plan and execution state is available via this structure.
+ <code class="literal">rinfo</code> is the <code class="structname">ResultRelInfo</code> struct describing
+ the target foreign table. (The <code class="structfield">ri_FdwState</code> field of
+ <code class="structname">ResultRelInfo</code> is available for the FDW to store any
+ private state it needs for this operation.)
+ </p><p>
+ When this is called by a <code class="command">COPY FROM</code> command, the
+ plan-related global data in <code class="literal">mtstate</code> is not provided
+ and the <code class="literal">planSlot</code> parameter of
+ <code class="function">ExecForeignInsert</code> subsequently called for each
+ inserted tuple is <code class="literal">NULL</code>, whether the foreign table is
+ the partition chosen for tuple routing or the target specified in the
+ command.
+ </p><p>
+ If the <code class="function">BeginForeignInsert</code> pointer is set to
+ <code class="literal">NULL</code>, no action is taken for the initialization.
+ </p><p>
+ Note that if the FDW does not support routable foreign-table partitions
+ and/or executing <code class="command">COPY FROM</code> on foreign tables, this
+ function or <code class="function">ExecForeignInsert/ExecForeignBatchInsert</code>
+ subsequently called must throw error as needed.
+ </p><p>
+</p><pre class="programlisting">
+void
+EndForeignInsert(EState *estate,
+ ResultRelInfo *rinfo);
+</pre><p>
+
+ End the insert operation and release resources. It is normally not important
+ to release palloc'd memory, but for example open files and connections
+ to remote servers should be cleaned up.
+ </p><p>
+ If the <code class="function">EndForeignInsert</code> pointer is set to
+ <code class="literal">NULL</code>, no action is taken for the termination.
+ </p><p>
+</p><pre class="programlisting">
+int
+IsForeignRelUpdatable(Relation rel);
+</pre><p>
+
+ Report which update operations the specified foreign table supports.
+ The return value should be a bit mask of rule event numbers indicating
+ which operations are supported by the foreign table, using the
+ <code class="literal">CmdType</code> enumeration; that is,
+ <code class="literal">(1 &lt;&lt; CMD_UPDATE) = 4</code> for <code class="command">UPDATE</code>,
+ <code class="literal">(1 &lt;&lt; CMD_INSERT) = 8</code> for <code class="command">INSERT</code>, and
+ <code class="literal">(1 &lt;&lt; CMD_DELETE) = 16</code> for <code class="command">DELETE</code>.
+ </p><p>
+ If the <code class="function">IsForeignRelUpdatable</code> pointer is set to
+ <code class="literal">NULL</code>, foreign tables are assumed to be insertable, updatable,
+ or deletable if the FDW provides <code class="function">ExecForeignInsert</code>,
+ <code class="function">ExecForeignUpdate</code>, or <code class="function">ExecForeignDelete</code>
+ respectively. This function is only needed if the FDW supports some
+ tables that are updatable and some that are not. (Even then, it's
+ permissible to throw an error in the execution routine instead of
+ checking in this function. However, this function is used to determine
+ updatability for display in the <code class="literal">information_schema</code> views.)
+ </p><p>
+ Some inserts, updates, and deletes to foreign tables can be optimized
+ by implementing an alternative set of interfaces. The ordinary
+ interfaces for inserts, updates, and deletes fetch rows from the remote
+ server and then modify those rows one at a time. In some cases, this
+ row-by-row approach is necessary, but it can be inefficient. If it is
+ possible for the foreign server to determine which rows should be
+ modified without actually retrieving them, and if there are no local
+ structures which would affect the operation (row-level local triggers,
+ stored generated columns, or <code class="literal">WITH CHECK OPTION</code>
+ constraints from parent views), then it is possible to arrange things
+ so that the entire operation is performed on the remote server. The
+ interfaces described below make this possible.
+ </p><p>
+</p><pre class="programlisting">
+bool
+PlanDirectModify(PlannerInfo *root,
+ ModifyTable *plan,
+ Index resultRelation,
+ int subplan_index);
+</pre><p>
+
+ Decide whether it is safe to execute a direct modification
+ on the remote server. If so, return <code class="literal">true</code> after performing
+ planning actions needed for that. Otherwise, return <code class="literal">false</code>.
+ This optional function is called during query planning.
+ If this function succeeds, <code class="function">BeginDirectModify</code>,
+ <code class="function">IterateDirectModify</code> and <code class="function">EndDirectModify</code> will
+ be called at the execution stage, instead. Otherwise, the table
+ modification will be executed using the table-updating functions
+ described above.
+ The parameters are the same as for <code class="function">PlanForeignModify</code>.
+ </p><p>
+ To execute the direct modification on the remote server, this function
+ must rewrite the target subplan with a <code class="structname">ForeignScan</code> plan
+ node that executes the direct modification on the remote server. The
+ <code class="structfield">operation</code> and <code class="structfield">resultRelation</code> fields
+ of the <code class="structname">ForeignScan</code> must be set appropriately.
+ <code class="structfield">operation</code> must be set to the <code class="literal">CmdType</code>
+ enumeration corresponding to the statement kind (that is,
+ <code class="literal">CMD_UPDATE</code> for <code class="command">UPDATE</code>,
+ <code class="literal">CMD_INSERT</code> for <code class="command">INSERT</code>, and
+ <code class="literal">CMD_DELETE</code> for <code class="command">DELETE</code>), and the
+ <code class="literal">resultRelation</code> argument must be copied to the
+ <code class="structfield">resultRelation</code> field.
+ </p><p>
+ See <a class="xref" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Section 59.4</a> for additional information.
+ </p><p>
+ If the <code class="function">PlanDirectModify</code> pointer is set to
+ <code class="literal">NULL</code>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </p><p>
+</p><pre class="programlisting">
+void
+BeginDirectModify(ForeignScanState *node,
+ int eflags);
+</pre><p>
+
+ Prepare to execute a direct modification on the remote server.
+ This is called during executor startup. It should perform any
+ initialization needed prior to the direct modification (that should be
+ done upon the first call to <code class="function">IterateDirectModify</code>).
+ The <code class="structname">ForeignScanState</code> node has already been created, but
+ its <code class="structfield">fdw_state</code> field is still NULL. Information about
+ the table to modify is accessible through the
+ <code class="structname">ForeignScanState</code> node (in particular, from the underlying
+ <code class="structname">ForeignScan</code> plan node, which contains any FDW-private
+ information provided by <code class="function">PlanDirectModify</code>).
+ <code class="literal">eflags</code> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </p><p>
+ Note that when <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is
+ true, this function should not perform any externally-visible actions;
+ it should only do the minimum required to make the node state valid
+ for <code class="function">ExplainDirectModify</code> and <code class="function">EndDirectModify</code>.
+ </p><p>
+ If the <code class="function">BeginDirectModify</code> pointer is set to
+ <code class="literal">NULL</code>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </p><p>
+</p><pre class="programlisting">
+TupleTableSlot *
+IterateDirectModify(ForeignScanState *node);
+</pre><p>
+
+ When the <code class="command">INSERT</code>, <code class="command">UPDATE</code> or <code class="command">DELETE</code>
+ query doesn't have a <code class="literal">RETURNING</code> clause, just return NULL
+ after a direct modification on the remote server.
+ When the query has the clause, fetch one result containing the data
+ needed for the <code class="literal">RETURNING</code> calculation, returning it in a
+ tuple table slot (the node's <code class="structfield">ScanTupleSlot</code> should be
+ used for this purpose). The data that was actually inserted, updated
+ or deleted must be stored in
+ <code class="literal">node-&gt;resultRelInfo-&gt;ri_projectReturning-&gt;pi_exprContext-&gt;ecxt_scantuple</code>.
+ Return NULL if no more rows are available.
+ Note that this is called in a short-lived memory context that will be
+ reset between invocations. Create a memory context in
+ <code class="function">BeginDirectModify</code> if you need longer-lived storage, or use
+ the <code class="structfield">es_query_cxt</code> of the node's <code class="structname">EState</code>.
+ </p><p>
+ The rows returned must match the <code class="structfield">fdw_scan_tlist</code> target
+ list if one was supplied, otherwise they must match the row type of the
+ foreign table being updated. If you choose to optimize away fetching
+ columns that are not needed for the <code class="literal">RETURNING</code> calculation,
+ you should insert nulls in those column positions, or else generate a
+ <code class="structfield">fdw_scan_tlist</code> list with those columns omitted.
+ </p><p>
+ Whether the query has the clause or not, the query's reported row count
+ must be incremented by the FDW itself. When the query doesn't have the
+ clause, the FDW must also increment the row count for the
+ <code class="structname">ForeignScanState</code> node in the <code class="command">EXPLAIN ANALYZE</code>
+ case.
+ </p><p>
+ If the <code class="function">IterateDirectModify</code> pointer is set to
+ <code class="literal">NULL</code>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </p><p>
+</p><pre class="programlisting">
+void
+EndDirectModify(ForeignScanState *node);
+</pre><p>
+
+ Clean up following a direct modification on the remote server. It is
+ normally not important to release palloc'd memory, but for example open
+ files and connections to the remote server should be cleaned up.
+ </p><p>
+ If the <code class="function">EndDirectModify</code> pointer is set to
+ <code class="literal">NULL</code>, no attempts to execute a direct modification on the
+ remote server are taken.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-TRUNCATE"><div class="titlepage"><div><div><h3 class="title">59.2.5. FDW Routines for <code class="command">TRUNCATE</code></h3></div></div></div><p>
+</p><pre class="programlisting">
+void
+ExecForeignTruncate(List *rels,
+ DropBehavior behavior,
+ bool restart_seqs);
+</pre><p>
+
+ Truncate foreign tables. This function is called when
+ <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> is executed on a foreign table.
+ <code class="literal">rels</code> is a list of <code class="structname">Relation</code>
+ data structures of foreign tables to truncate.
+ </p><p>
+ <code class="literal">behavior</code> is either <code class="literal">DROP_RESTRICT</code>
+ or <code class="literal">DROP_CASCADE</code> indicating that the
+ <code class="literal">RESTRICT</code> or <code class="literal">CASCADE</code> option was
+ requested in the original <code class="command">TRUNCATE</code> command,
+ respectively.
+ </p><p>
+ If <code class="literal">restart_seqs</code> is <code class="literal">true</code>,
+ the original <code class="command">TRUNCATE</code> command requested the
+ <code class="literal">RESTART IDENTITY</code> behavior, otherwise the
+ <code class="literal">CONTINUE IDENTITY</code> behavior was requested.
+ </p><p>
+ Note that the <code class="literal">ONLY</code> options specified
+ in the original <code class="command">TRUNCATE</code> command are not passed to
+ <code class="function">ExecForeignTruncate</code>. This behavior is similar to
+ the callback functions of <code class="command">SELECT</code>,
+ <code class="command">UPDATE</code> and <code class="command">DELETE</code> on
+ a foreign table.
+ </p><p>
+ <code class="function">ExecForeignTruncate</code> is invoked once per
+ foreign server for which foreign tables are to be truncated.
+ This means that all foreign tables included in <code class="literal">rels</code>
+ must belong to the same server.
+ </p><p>
+ If the <code class="function">ExecForeignTruncate</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to truncate foreign tables will
+ fail with an error message.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-ROW-LOCKING"><div class="titlepage"><div><div><h3 class="title">59.2.6. FDW Routines for Row Locking</h3></div></div></div><p>
+ If an FDW wishes to support <em class="firstterm">late row locking</em> (as described
+ in <a class="xref" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Section 59.5</a>), it must provide the following
+ callback functions:
+ </p><p>
+</p><pre class="programlisting">
+RowMarkType
+GetForeignRowMarkType(RangeTblEntry *rte,
+ LockClauseStrength strength);
+</pre><p>
+
+ Report which row-marking option to use for a foreign table.
+ <code class="literal">rte</code> is the <code class="structname">RangeTblEntry</code> node for the table
+ and <code class="literal">strength</code> describes the lock strength requested by the
+ relevant <code class="literal">FOR UPDATE/SHARE</code> clause, if any. The result must be
+ a member of the <code class="literal">RowMarkType</code> enum type.
+ </p><p>
+ This function is called during query planning for each foreign table that
+ appears in an <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or <code class="command">SELECT
+ FOR UPDATE/SHARE</code> query and is not the target of <code class="command">UPDATE</code>
+ or <code class="command">DELETE</code>.
+ </p><p>
+ If the <code class="function">GetForeignRowMarkType</code> pointer is set to
+ <code class="literal">NULL</code>, the <code class="literal">ROW_MARK_COPY</code> option is always used.
+ (This implies that <code class="function">RefetchForeignRow</code> will never be called,
+ so it need not be provided either.)
+ </p><p>
+ See <a class="xref" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Section 59.5</a> for more information.
+ </p><p>
+</p><pre class="programlisting">
+void
+RefetchForeignRow(EState *estate,
+ ExecRowMark *erm,
+ Datum rowid,
+ TupleTableSlot *slot,
+ bool *updated);
+</pre><p>
+
+ Re-fetch one tuple slot from the foreign table, after locking it if required.
+ <code class="literal">estate</code> is global execution state for the query.
+ <code class="literal">erm</code> is the <code class="structname">ExecRowMark</code> struct describing
+ the target foreign table and the row lock type (if any) to acquire.
+ <code class="literal">rowid</code> identifies the tuple to be fetched.
+ <code class="literal">slot</code> contains nothing useful upon call, but can be used to
+ hold the returned tuple. <code class="literal">updated</code> is an output parameter.
+ </p><p>
+ This function should store the tuple into the provided slot, or clear it if
+ the row lock couldn't be obtained. The row lock type to acquire is
+ defined by <code class="literal">erm-&gt;markType</code>, which is the value
+ previously returned by <code class="function">GetForeignRowMarkType</code>.
+ (<code class="literal">ROW_MARK_REFERENCE</code> means to just re-fetch the tuple
+ without acquiring any lock, and <code class="literal">ROW_MARK_COPY</code> will
+ never be seen by this routine.)
+ </p><p>
+ In addition, <code class="literal">*updated</code> should be set to <code class="literal">true</code>
+ if what was fetched was an updated version of the tuple rather than
+ the same version previously obtained. (If the FDW cannot be sure about
+ this, always returning <code class="literal">true</code> is recommended.)
+ </p><p>
+ Note that by default, failure to acquire a row lock should result in
+ raising an error; returning with an empty slot is only appropriate if
+ the <code class="literal">SKIP LOCKED</code> option is specified
+ by <code class="literal">erm-&gt;waitPolicy</code>.
+ </p><p>
+ The <code class="literal">rowid</code> is the <code class="structfield">ctid</code> value previously read
+ for the row to be re-fetched. Although the <code class="literal">rowid</code> value is
+ passed as a <code class="type">Datum</code>, it can currently only be a <code class="type">tid</code>. The
+ function API is chosen in hopes that it may be possible to allow other
+ data types for row IDs in future.
+ </p><p>
+ If the <code class="function">RefetchForeignRow</code> pointer is set to
+ <code class="literal">NULL</code>, attempts to re-fetch rows will fail
+ with an error message.
+ </p><p>
+ See <a class="xref" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Section 59.5</a> for more information.
+ </p><p>
+</p><pre class="programlisting">
+bool
+RecheckForeignScan(ForeignScanState *node,
+ TupleTableSlot *slot);
+</pre><p>
+ Recheck that a previously-returned tuple still matches the relevant
+ scan and join qualifiers, and possibly provide a modified version of
+ the tuple. For foreign data wrappers which do not perform join pushdown,
+ it will typically be more convenient to set this to <code class="literal">NULL</code> and
+ instead set <code class="structfield">fdw_recheck_quals</code> appropriately.
+ When outer joins are pushed down, however, it isn't sufficient to
+ reapply the checks relevant to all the base tables to the result tuple,
+ even if all needed attributes are present, because failure to match some
+ qualifier might result in some attributes going to NULL, rather than in
+ no tuple being returned. <code class="literal">RecheckForeignScan</code> can recheck
+ qualifiers and return true if they are still satisfied and false
+ otherwise, but it can also store a replacement tuple into the supplied
+ slot.
+ </p><p>
+ To implement join pushdown, a foreign data wrapper will typically
+ construct an alternative local join plan which is used only for
+ rechecks; this will become the outer subplan of the
+ <code class="literal">ForeignScan</code>. When a recheck is required, this subplan
+ can be executed and the resulting tuple can be stored in the slot.
+ This plan need not be efficient since no base table will return more
+ than one row; for example, it may implement all joins as nested loops.
+ The function <code class="literal">GetExistingLocalJoinPath</code> may be used to search
+ existing paths for a suitable local join path, which can be used as the
+ alternative local join plan. <code class="literal">GetExistingLocalJoinPath</code>
+ searches for an unparameterized path in the path list of the specified
+ join relation. (If it does not find such a path, it returns NULL, in
+ which case a foreign data wrapper may build the local path by itself or
+ may choose not to create access paths for that join.)
+ </p></div><div class="sect2" id="FDW-CALLBACKS-EXPLAIN"><div class="titlepage"><div><div><h3 class="title">59.2.7. FDW Routines for <code class="command">EXPLAIN</code></h3></div></div></div><p>
+</p><pre class="programlisting">
+void
+ExplainForeignScan(ForeignScanState *node,
+ ExplainState *es);
+</pre><p>
+
+ Print additional <code class="command">EXPLAIN</code> output for a foreign table scan.
+ This function can call <code class="function">ExplainPropertyText</code> and
+ related functions to add fields to the <code class="command">EXPLAIN</code> output.
+ The flag fields in <code class="literal">es</code> can be used to determine what to
+ print, and the state of the <code class="structname">ForeignScanState</code> node
+ can be inspected to provide run-time statistics in the <code class="command">EXPLAIN
+ ANALYZE</code> case.
+ </p><p>
+ If the <code class="function">ExplainForeignScan</code> pointer is set to
+ <code class="literal">NULL</code>, no additional information is printed during
+ <code class="command">EXPLAIN</code>.
+ </p><p>
+</p><pre class="programlisting">
+void
+ExplainForeignModify(ModifyTableState *mtstate,
+ ResultRelInfo *rinfo,
+ List *fdw_private,
+ int subplan_index,
+ struct ExplainState *es);
+</pre><p>
+
+ Print additional <code class="command">EXPLAIN</code> output for a foreign table update.
+ This function can call <code class="function">ExplainPropertyText</code> and
+ related functions to add fields to the <code class="command">EXPLAIN</code> output.
+ The flag fields in <code class="literal">es</code> can be used to determine what to
+ print, and the state of the <code class="structname">ModifyTableState</code> node
+ can be inspected to provide run-time statistics in the <code class="command">EXPLAIN
+ ANALYZE</code> case. The first four arguments are the same as for
+ <code class="function">BeginForeignModify</code>.
+ </p><p>
+ If the <code class="function">ExplainForeignModify</code> pointer is set to
+ <code class="literal">NULL</code>, no additional information is printed during
+ <code class="command">EXPLAIN</code>.
+ </p><p>
+</p><pre class="programlisting">
+void
+ExplainDirectModify(ForeignScanState *node,
+ ExplainState *es);
+</pre><p>
+
+ Print additional <code class="command">EXPLAIN</code> output for a direct modification
+ on the remote server.
+ This function can call <code class="function">ExplainPropertyText</code> and
+ related functions to add fields to the <code class="command">EXPLAIN</code> output.
+ The flag fields in <code class="literal">es</code> can be used to determine what to
+ print, and the state of the <code class="structname">ForeignScanState</code> node
+ can be inspected to provide run-time statistics in the <code class="command">EXPLAIN
+ ANALYZE</code> case.
+ </p><p>
+ If the <code class="function">ExplainDirectModify</code> pointer is set to
+ <code class="literal">NULL</code>, no additional information is printed during
+ <code class="command">EXPLAIN</code>.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-ANALYZE"><div class="titlepage"><div><div><h3 class="title">59.2.8. FDW Routines for <code class="command">ANALYZE</code></h3></div></div></div><p>
+</p><pre class="programlisting">
+bool
+AnalyzeForeignTable(Relation relation,
+ AcquireSampleRowsFunc *func,
+ BlockNumber *totalpages);
+</pre><p>
+
+ This function is called when <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a> is executed on
+ a foreign table. If the FDW can collect statistics for this
+ foreign table, it should return <code class="literal">true</code>, and provide a pointer
+ to a function that will collect sample rows from the table in
+ <em class="parameter"><code>func</code></em>, plus the estimated size of the table in pages in
+ <em class="parameter"><code>totalpages</code></em>. Otherwise, return <code class="literal">false</code>.
+ </p><p>
+ If the FDW does not support collecting statistics for any tables, the
+ <code class="function">AnalyzeForeignTable</code> pointer can be set to <code class="literal">NULL</code>.
+ </p><p>
+ If provided, the sample collection function must have the signature
+</p><pre class="programlisting">
+int
+AcquireSampleRowsFunc(Relation relation,
+ int elevel,
+ HeapTuple *rows,
+ int targrows,
+ double *totalrows,
+ double *totaldeadrows);
+</pre><p>
+
+ A random sample of up to <em class="parameter"><code>targrows</code></em> rows should be collected
+ from the table and stored into the caller-provided <em class="parameter"><code>rows</code></em>
+ array. The actual number of rows collected must be returned. In
+ addition, store estimates of the total numbers of live and dead rows in
+ the table into the output parameters <em class="parameter"><code>totalrows</code></em> and
+ <em class="parameter"><code>totaldeadrows</code></em>. (Set <em class="parameter"><code>totaldeadrows</code></em> to zero
+ if the FDW does not have any concept of dead rows.)
+ </p></div><div class="sect2" id="FDW-CALLBACKS-IMPORT"><div class="titlepage"><div><div><h3 class="title">59.2.9. FDW Routines for <code class="command">IMPORT FOREIGN SCHEMA</code></h3></div></div></div><p>
+</p><pre class="programlisting">
+List *
+ImportForeignSchema(ImportForeignSchemaStmt *stmt, Oid serverOid);
+</pre><p>
+
+ Obtain a list of foreign table creation commands. This function is
+ called when executing <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a>, and is
+ passed the parse tree for that statement, as well as the OID of the
+ foreign server to use. It should return a list of C strings, each of
+ which must contain a <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a> command.
+ These strings will be parsed and executed by the core server.
+ </p><p>
+ Within the <code class="structname">ImportForeignSchemaStmt</code> struct,
+ <code class="structfield">remote_schema</code> is the name of the remote schema from
+ which tables are to be imported.
+ <code class="structfield">list_type</code> identifies how to filter table names:
+ <code class="literal">FDW_IMPORT_SCHEMA_ALL</code> means that all tables in the remote
+ schema should be imported (in this case <code class="structfield">table_list</code> is
+ empty), <code class="literal">FDW_IMPORT_SCHEMA_LIMIT_TO</code> means to include only
+ tables listed in <code class="structfield">table_list</code>,
+ and <code class="literal">FDW_IMPORT_SCHEMA_EXCEPT</code> means to exclude the tables
+ listed in <code class="structfield">table_list</code>.
+ <code class="structfield">options</code> is a list of options used for the import process.
+ The meanings of the options are up to the FDW.
+ For example, an FDW could use an option to define whether the
+ <code class="literal">NOT NULL</code> attributes of columns should be imported.
+ These options need not have anything to do with those supported by the
+ FDW as database object options.
+ </p><p>
+ The FDW may ignore the <code class="structfield">local_schema</code> field of
+ the <code class="structname">ImportForeignSchemaStmt</code>, because the core server
+ will automatically insert that name into the parsed <code class="command">CREATE
+ FOREIGN TABLE</code> commands.
+ </p><p>
+ The FDW does not have to concern itself with implementing the filtering
+ specified by <code class="structfield">list_type</code> and <code class="structfield">table_list</code>,
+ either, as the core server will automatically skip any returned commands
+ for tables excluded according to those options. However, it's often
+ useful to avoid the work of creating commands for excluded tables in the
+ first place. The function <code class="function">IsImportableForeignTable()</code> may be
+ useful to test whether a given foreign-table name will pass the filter.
+ </p><p>
+ If the FDW does not support importing table definitions, the
+ <code class="function">ImportForeignSchema</code> pointer can be set to <code class="literal">NULL</code>.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-PARALLEL"><div class="titlepage"><div><div><h3 class="title">59.2.10. FDW Routines for Parallel Execution</h3></div></div></div><p>
+ A <code class="structname">ForeignScan</code> node can, optionally, support parallel
+ execution. A parallel <code class="structname">ForeignScan</code> will be executed
+ in multiple processes and must return each row exactly once across
+ all cooperating processes. To do this, processes can coordinate through
+ fixed-size chunks of dynamic shared memory. This shared memory is not
+ guaranteed to be mapped at the same address in every process, so it
+ must not contain pointers. The following functions are all optional,
+ but most are required if parallel execution is to be supported.
+ </p><p>
+</p><pre class="programlisting">
+bool
+IsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel,
+ RangeTblEntry *rte);
+</pre><p>
+ Test whether a scan can be performed within a parallel worker. This
+ function will only be called when the planner believes that a parallel
+ plan might be possible, and should return true if it is safe for that scan
+ to run within a parallel worker. This will generally not be the case if
+ the remote data source has transaction semantics, unless the worker's
+ connection to the data can somehow be made to share the same transaction
+ context as the leader.
+ </p><p>
+ If this function is not defined, it is assumed that the scan must take
+ place within the parallel leader. Note that returning true does not mean
+ that the scan itself can be done in parallel, only that the scan can be
+ performed within a parallel worker. Therefore, it can be useful to define
+ this method even when parallel execution is not supported.
+ </p><p>
+</p><pre class="programlisting">
+Size
+EstimateDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt);
+</pre><p>
+ Estimate the amount of dynamic shared memory that will be required
+ for parallel operation. This may be higher than the amount that will
+ actually be used, but it must not be lower. The return value is in bytes.
+ This function is optional, and can be omitted if not needed; but if it
+ is omitted, the next three functions must be omitted as well, because
+ no shared memory will be allocated for the FDW's use.
+ </p><p>
+</p><pre class="programlisting">
+void
+InitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
+ void *coordinate);
+</pre><p>
+ Initialize the dynamic shared memory that will be required for parallel
+ operation. <code class="literal">coordinate</code> points to a shared memory area of
+ size equal to the return value of <code class="function">EstimateDSMForeignScan</code>.
+ This function is optional, and can be omitted if not needed.
+ </p><p>
+</p><pre class="programlisting">
+void
+ReInitializeDSMForeignScan(ForeignScanState *node, ParallelContext *pcxt,
+ void *coordinate);
+</pre><p>
+ Re-initialize the dynamic shared memory required for parallel operation
+ when the foreign-scan plan node is about to be re-scanned.
+ This function is optional, and can be omitted if not needed.
+ Recommended practice is that this function reset only shared state,
+ while the <code class="function">ReScanForeignScan</code> function resets only local
+ state. Currently, this function will be called
+ before <code class="function">ReScanForeignScan</code>, but it's best not to rely on
+ that ordering.
+ </p><p>
+</p><pre class="programlisting">
+void
+InitializeWorkerForeignScan(ForeignScanState *node, shm_toc *toc,
+ void *coordinate);
+</pre><p>
+ Initialize a parallel worker's local state based on the shared state
+ set up by the leader during <code class="function">InitializeDSMForeignScan</code>.
+ This function is optional, and can be omitted if not needed.
+ </p><p>
+</p><pre class="programlisting">
+void
+ShutdownForeignScan(ForeignScanState *node);
+</pre><p>
+ Release resources when it is anticipated the node will not be executed
+ to completion. This is not called in all cases; sometimes,
+ <code class="literal">EndForeignScan</code> may be called without this function having
+ been called first. Since the DSM segment used by parallel query is
+ destroyed just after this callback is invoked, foreign data wrappers that
+ wish to take some action before the DSM segment goes away should implement
+ this method.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-ASYNC"><div class="titlepage"><div><div><h3 class="title">59.2.11. FDW Routines for Asynchronous Execution</h3></div></div></div><p>
+ A <code class="structname">ForeignScan</code> node can, optionally, support
+ asynchronous execution as described in
+ <code class="filename">src/backend/executor/README</code>. The following
+ functions are all optional, but are all required if asynchronous
+ execution is to be supported.
+ </p><p>
+</p><pre class="programlisting">
+bool
+IsForeignPathAsyncCapable(ForeignPath *path);
+</pre><p>
+ Test whether a given <code class="structname">ForeignPath</code> path can scan
+ the underlying foreign relation asynchronously.
+ This function will only be called at the end of query planning when the
+ given path is a direct child of an <code class="structname">AppendPath</code>
+ path and when the planner believes that asynchronous execution improves
+ performance, and should return true if the given path is able to scan the
+ foreign relation asynchronously.
+ </p><p>
+ If this function is not defined, it is assumed that the given path scans
+ the foreign relation using <code class="function">IterateForeignScan</code>.
+ (This implies that the callback functions described below will never be
+ called, so they need not be provided either.)
+ </p><p>
+</p><pre class="programlisting">
+void
+ForeignAsyncRequest(AsyncRequest *areq);
+</pre><p>
+ Produce one tuple asynchronously from the
+ <code class="structname">ForeignScan</code> node. <code class="literal">areq</code> is
+ the <code class="structname">AsyncRequest</code> struct describing the
+ <code class="structname">ForeignScan</code> node and the parent
+ <code class="structname">Append</code> node that requested the tuple from it.
+ This function should store the tuple into the slot specified by
+ <code class="literal">areq-&gt;result</code>, and set
+ <code class="literal">areq-&gt;request_complete</code> to <code class="literal">true</code>;
+ or if it needs to wait on an event external to the core server such as
+ network I/O, and cannot produce any tuple immediately, set the flag to
+ <code class="literal">false</code>, and set
+ <code class="literal">areq-&gt;callback_pending</code> to <code class="literal">true</code>
+ for the <code class="structname">ForeignScan</code> node to get a callback from
+ the callback functions described below. If no more tuples are available,
+ set the slot to NULL or an empty slot, and the
+ <code class="literal">areq-&gt;request_complete</code> flag to
+ <code class="literal">true</code>. It's recommended to use
+ <code class="function">ExecAsyncRequestDone</code> or
+ <code class="function">ExecAsyncRequestPending</code> to set the output parameters
+ in the <code class="literal">areq</code>.
+ </p><p>
+</p><pre class="programlisting">
+void
+ForeignAsyncConfigureWait(AsyncRequest *areq);
+</pre><p>
+ Configure a file descriptor event for which the
+ <code class="structname">ForeignScan</code> node wishes to wait.
+ This function will only be called when the
+ <code class="structname">ForeignScan</code> node has the
+ <code class="literal">areq-&gt;callback_pending</code> flag set, and should add
+ the event to the <code class="structfield">as_eventset</code> of the parent
+ <code class="structname">Append</code> node described by the
+ <code class="literal">areq</code>. See the comments for
+ <code class="function">ExecAsyncConfigureWait</code> in
+ <code class="filename">src/backend/executor/execAsync.c</code> for additional
+ information. When the file descriptor event occurs,
+ <code class="function">ForeignAsyncNotify</code> will be called.
+ </p><p>
+</p><pre class="programlisting">
+void
+ForeignAsyncNotify(AsyncRequest *areq);
+</pre><p>
+ Process a relevant event that has occurred, then produce one tuple
+ asynchronously from the <code class="structname">ForeignScan</code> node.
+ This function should set the output parameters in the
+ <code class="literal">areq</code> in the same way as
+ <code class="function">ForeignAsyncRequest</code>.
+ </p></div><div class="sect2" id="FDW-CALLBACKS-REPARAMETERIZE-PATHS"><div class="titlepage"><div><div><h3 class="title">59.2.12. FDW Routines for Reparameterization of Paths</h3></div></div></div><p>
+</p><pre class="programlisting">
+List *
+ReparameterizeForeignPathByChild(PlannerInfo *root, List *fdw_private,
+ RelOptInfo *child_rel);
+</pre><p>
+ This function is called while converting a path parameterized by the
+ top-most parent of the given child relation <code class="literal">child_rel</code> to be
+ parameterized by the child relation. The function is used to reparameterize
+ any paths or translate any expression nodes saved in the given
+ <code class="literal">fdw_private</code> member of a <code class="structname">ForeignPath</code>. The
+ callback may use <code class="literal">reparameterize_path_by_child</code>,
+ <code class="literal">adjust_appendrel_attrs</code> or
+ <code class="literal">adjust_appendrel_attrs_multilevel</code> as required.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-functions.html" title="59.1. Foreign Data Wrapper Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdw-helpers.html" title="59.3. Foreign Data Wrapper Helper Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">59.1. Foreign Data Wrapper Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 59.3. Foreign Data Wrapper Helper Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fdw-functions.html b/doc/src/sgml/html/fdw-functions.html
new file mode 100644
index 0000000..fe0719c
--- /dev/null
+++ b/doc/src/sgml/html/fdw-functions.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>59.1. Foreign Data Wrapper Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper" /><link rel="next" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">59.1. Foreign Data Wrapper Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 59. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines">Next</a></td></tr></table><hr /></div><div class="sect1" id="FDW-FUNCTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">59.1. Foreign Data Wrapper Functions</h2></div></div></div><p>
+ The FDW author needs to implement a handler function, and optionally
+ a validator function. Both functions must be written in a compiled
+ language such as C, using the version-1 interface.
+ For details on C language calling conventions and dynamic loading,
+ see <a class="xref" href="xfunc-c.html" title="38.10. C-Language Functions">Section 38.10</a>.
+ </p><p>
+ The handler function simply returns a struct of function pointers to
+ callback functions that will be called by the planner, executor, and
+ various maintenance commands.
+ Most of the effort in writing an FDW is in implementing these callback
+ functions.
+ The handler function must be registered with
+ <span class="productname">PostgreSQL</span> as taking no arguments and
+ returning the special pseudo-type <code class="type">fdw_handler</code>. The
+ callback functions are plain C functions and are not visible or
+ callable at the SQL level. The callback functions are described in
+ <a class="xref" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines">Section 59.2</a>.
+ </p><p>
+ The validator function is responsible for validating options given in
+ <code class="command">CREATE</code> and <code class="command">ALTER</code> commands for its
+ foreign data wrapper, as well as foreign servers, user mappings, and
+ foreign tables using the wrapper.
+ The validator function must be registered as taking two arguments, a
+ text array containing the options to be validated, and an OID
+ representing the type of object the options are associated with (in
+ the form of the OID of the system catalog the object would be stored
+ in, either
+ <code class="literal">ForeignDataWrapperRelationId</code>,
+ <code class="literal">ForeignServerRelationId</code>,
+ <code class="literal">UserMappingRelationId</code>,
+ or <code class="literal">ForeignTableRelationId</code>).
+ If no validator function is supplied, options are not checked at object
+ creation time or object alteration time.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 59. Writing a Foreign Data Wrapper </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 59.2. Foreign Data Wrapper Callback Routines</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fdw-helpers.html b/doc/src/sgml/html/fdw-helpers.html
new file mode 100644
index 0000000..3da67df
--- /dev/null
+++ b/doc/src/sgml/html/fdw-helpers.html
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>59.3. Foreign Data Wrapper Helper Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines" /><link rel="next" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">59.3. Foreign Data Wrapper Helper Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 59. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Next</a></td></tr></table><hr /></div><div class="sect1" id="FDW-HELPERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">59.3. Foreign Data Wrapper Helper Functions</h2></div></div></div><p>
+ Several helper functions are exported from the core server so that
+ authors of foreign data wrappers can get easy access to attributes of
+ FDW-related objects, such as FDW options.
+ To use any of these functions, you need to include the header file
+ <code class="filename">foreign/foreign.h</code> in your source file.
+ That header also defines the struct types that are returned by
+ these functions.
+ </p><p>
+</p><pre class="programlisting">
+ForeignDataWrapper *
+GetForeignDataWrapperExtended(Oid fdwid, bits16 flags);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignDataWrapper</code>
+ object for the foreign-data wrapper with the given OID. A
+ <code class="structname">ForeignDataWrapper</code> object contains properties
+ of the FDW (see <code class="filename">foreign/foreign.h</code> for details).
+ <code class="structfield">flags</code> is a bitwise-or'd bit mask indicating
+ an extra set of options. It can take the value
+ <code class="literal">FDW_MISSING_OK</code>, in which case a <code class="literal">NULL</code>
+ result is returned to the caller instead of an error for an undefined
+ object.
+ </p><p>
+</p><pre class="programlisting">
+ForeignDataWrapper *
+GetForeignDataWrapper(Oid fdwid);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignDataWrapper</code>
+ object for the foreign-data wrapper with the given OID. A
+ <code class="structname">ForeignDataWrapper</code> object contains properties
+ of the FDW (see <code class="filename">foreign/foreign.h</code> for details).
+ </p><p>
+</p><pre class="programlisting">
+ForeignServer *
+GetForeignServerExtended(Oid serverid, bits16 flags);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignServer</code> object
+ for the foreign server with the given OID. A
+ <code class="structname">ForeignServer</code> object contains properties
+ of the server (see <code class="filename">foreign/foreign.h</code> for details).
+ <code class="structfield">flags</code> is a bitwise-or'd bit mask indicating
+ an extra set of options. It can take the value
+ <code class="literal">FSV_MISSING_OK</code>, in which case a <code class="literal">NULL</code>
+ result is returned to the caller instead of an error for an undefined
+ object.
+ </p><p>
+</p><pre class="programlisting">
+ForeignServer *
+GetForeignServer(Oid serverid);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignServer</code> object
+ for the foreign server with the given OID. A
+ <code class="structname">ForeignServer</code> object contains properties
+ of the server (see <code class="filename">foreign/foreign.h</code> for details).
+ </p><p>
+</p><pre class="programlisting">
+UserMapping *
+GetUserMapping(Oid userid, Oid serverid);
+</pre><p>
+
+ This function returns a <code class="structname">UserMapping</code> object for
+ the user mapping of the given role on the given server. (If there is no
+ mapping for the specific user, it will return the mapping for
+ <code class="literal">PUBLIC</code>, or throw error if there is none.) A
+ <code class="structname">UserMapping</code> object contains properties of the
+ user mapping (see <code class="filename">foreign/foreign.h</code> for details).
+ </p><p>
+</p><pre class="programlisting">
+ForeignTable *
+GetForeignTable(Oid relid);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignTable</code> object for
+ the foreign table with the given OID. A
+ <code class="structname">ForeignTable</code> object contains properties of the
+ foreign table (see <code class="filename">foreign/foreign.h</code> for details).
+ </p><p>
+</p><pre class="programlisting">
+List *
+GetForeignColumnOptions(Oid relid, AttrNumber attnum);
+</pre><p>
+
+ This function returns the per-column FDW options for the column with the
+ given foreign table OID and attribute number, in the form of a list of
+ <code class="structname">DefElem</code>. NIL is returned if the column has no
+ options.
+ </p><p>
+ Some object types have name-based lookup functions in addition to the
+ OID-based ones:
+ </p><p>
+</p><pre class="programlisting">
+ForeignDataWrapper *
+GetForeignDataWrapperByName(const char *name, bool missing_ok);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignDataWrapper</code>
+ object for the foreign-data wrapper with the given name. If the wrapper
+ is not found, return NULL if missing_ok is true, otherwise raise an
+ error.
+ </p><p>
+</p><pre class="programlisting">
+ForeignServer *
+GetForeignServerByName(const char *name, bool missing_ok);
+</pre><p>
+
+ This function returns a <code class="structname">ForeignServer</code> object
+ for the foreign server with the given name. If the server is not found,
+ return NULL if missing_ok is true, otherwise raise an error.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-callbacks.html" title="59.2. Foreign Data Wrapper Callback Routines">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Next</a></td></tr><tr><td width="40%" align="left" valign="top">59.2. Foreign Data Wrapper Callback Routines </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 59.4. Foreign Data Wrapper Query Planning</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fdw-planning.html b/doc/src/sgml/html/fdw-planning.html
new file mode 100644
index 0000000..29d2091
--- /dev/null
+++ b/doc/src/sgml/html/fdw-planning.html
@@ -0,0 +1,191 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>59.4. Foreign Data Wrapper Query Planning</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fdw-helpers.html" title="59.3. Foreign Data Wrapper Helper Functions" /><link rel="next" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">59.4. Foreign Data Wrapper Query Planning</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-helpers.html" title="59.3. Foreign Data Wrapper Helper Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 59. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Next</a></td></tr></table><hr /></div><div class="sect1" id="FDW-PLANNING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">59.4. Foreign Data Wrapper Query Planning</h2></div></div></div><p>
+ The FDW callback functions <code class="function">GetForeignRelSize</code>,
+ <code class="function">GetForeignPaths</code>, <code class="function">GetForeignPlan</code>,
+ <code class="function">PlanForeignModify</code>, <code class="function">GetForeignJoinPaths</code>,
+ <code class="function">GetForeignUpperPaths</code>, and <code class="function">PlanDirectModify</code>
+ must fit into the workings of the <span class="productname">PostgreSQL</span> planner.
+ Here are some notes about what they must do.
+ </p><p>
+ The information in <code class="literal">root</code> and <code class="literal">baserel</code> can be used
+ to reduce the amount of information that has to be fetched from the
+ foreign table (and therefore reduce the cost).
+ <code class="literal">baserel-&gt;baserestrictinfo</code> is particularly interesting, as
+ it contains restriction quals (<code class="literal">WHERE</code> clauses) that should be
+ used to filter the rows to be fetched. (The FDW itself is not required
+ to enforce these quals, as the core executor can check them instead.)
+ <code class="literal">baserel-&gt;reltarget-&gt;exprs</code> can be used to determine which
+ columns need to be fetched; but note that it only lists columns that
+ have to be emitted by the <code class="structname">ForeignScan</code> plan node, not
+ columns that are used in qual evaluation but not output by the query.
+ </p><p>
+ Various private fields are available for the FDW planning functions to
+ keep information in. Generally, whatever you store in FDW private fields
+ should be palloc'd, so that it will be reclaimed at the end of planning.
+ </p><p>
+ <code class="literal">baserel-&gt;fdw_private</code> is a <code class="type">void</code> pointer that is
+ available for FDW planning functions to store information relevant to
+ the particular foreign table. The core planner does not touch it except
+ to initialize it to NULL when the <code class="literal">RelOptInfo</code> node is created.
+ It is useful for passing information forward from
+ <code class="function">GetForeignRelSize</code> to <code class="function">GetForeignPaths</code> and/or
+ <code class="function">GetForeignPaths</code> to <code class="function">GetForeignPlan</code>, thereby
+ avoiding recalculation.
+ </p><p>
+ <code class="function">GetForeignPaths</code> can identify the meaning of different
+ access paths by storing private information in the
+ <code class="structfield">fdw_private</code> field of <code class="structname">ForeignPath</code> nodes.
+ <code class="structfield">fdw_private</code> is declared as a <code class="type">List</code> pointer, but
+ could actually contain anything since the core planner does not touch
+ it. However, best practice is to use a representation that's dumpable
+ by <code class="function">nodeToString</code>, for use with debugging support available
+ in the backend.
+ </p><p>
+ <code class="function">GetForeignPlan</code> can examine the <code class="structfield">fdw_private</code>
+ field of the selected <code class="structname">ForeignPath</code> node, and can generate
+ <code class="structfield">fdw_exprs</code> and <code class="structfield">fdw_private</code> lists to be
+ placed in the <code class="structname">ForeignScan</code> plan node, where they will be
+ available at execution time. Both of these lists must be
+ represented in a form that <code class="function">copyObject</code> knows how to copy.
+ The <code class="structfield">fdw_private</code> list has no other restrictions and is
+ not interpreted by the core backend in any way. The
+ <code class="structfield">fdw_exprs</code> list, if not NIL, is expected to contain
+ expression trees that are intended to be executed at run time. These
+ trees will undergo post-processing by the planner to make them fully
+ executable.
+ </p><p>
+ In <code class="function">GetForeignPlan</code>, generally the passed-in target list can
+ be copied into the plan node as-is. The passed <code class="literal">scan_clauses</code> list
+ contains the same clauses as <code class="literal">baserel-&gt;baserestrictinfo</code>,
+ but may be re-ordered for better execution efficiency. In simple cases
+ the FDW can just strip <code class="structname">RestrictInfo</code> nodes from the
+ <code class="literal">scan_clauses</code> list (using <code class="function">extract_actual_clauses</code>) and put
+ all the clauses into the plan node's qual list, which means that all the
+ clauses will be checked by the executor at run time. More complex FDWs
+ may be able to check some of the clauses internally, in which case those
+ clauses can be removed from the plan node's qual list so that the
+ executor doesn't waste time rechecking them.
+ </p><p>
+ As an example, the FDW might identify some restriction clauses of the
+ form <em class="replaceable"><code>foreign_variable</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>sub_expression</code></em>, which it determines can be executed on
+ the remote server given the locally-evaluated value of the
+ <em class="replaceable"><code>sub_expression</code></em>. The actual identification of such a
+ clause should happen during <code class="function">GetForeignPaths</code>, since it would
+ affect the cost estimate for the path. The path's
+ <code class="structfield">fdw_private</code> field would probably include a pointer to
+ the identified clause's <code class="structname">RestrictInfo</code> node. Then
+ <code class="function">GetForeignPlan</code> would remove that clause from <code class="literal">scan_clauses</code>,
+ but add the <em class="replaceable"><code>sub_expression</code></em> to <code class="structfield">fdw_exprs</code>
+ to ensure that it gets massaged into executable form. It would probably
+ also put control information into the plan node's
+ <code class="structfield">fdw_private</code> field to tell the execution functions what
+ to do at run time. The query transmitted to the remote server would
+ involve something like <code class="literal">WHERE <em class="replaceable"><code>foreign_variable</code></em> =
+ $1</code>, with the parameter value obtained at run time from
+ evaluation of the <code class="structfield">fdw_exprs</code> expression tree.
+ </p><p>
+ Any clauses removed from the plan node's qual list must instead be added
+ to <code class="literal">fdw_recheck_quals</code> or rechecked by
+ <code class="literal">RecheckForeignScan</code> in order to ensure correct behavior
+ at the <code class="literal">READ COMMITTED</code> isolation level. When a concurrent
+ update occurs for some other table involved in the query, the executor
+ may need to verify that all of the original quals are still satisfied for
+ the tuple, possibly against a different set of parameter values. Using
+ <code class="literal">fdw_recheck_quals</code> is typically easier than implementing checks
+ inside <code class="literal">RecheckForeignScan</code>, but this method will be
+ insufficient when outer joins have been pushed down, since the join tuples
+ in that case might have some fields go to NULL without rejecting the
+ tuple entirely.
+ </p><p>
+ Another <code class="structname">ForeignScan</code> field that can be filled by FDWs
+ is <code class="structfield">fdw_scan_tlist</code>, which describes the tuples returned by
+ the FDW for this plan node. For simple foreign table scans this can be
+ set to <code class="literal">NIL</code>, implying that the returned tuples have the
+ row type declared for the foreign table. A non-<code class="symbol">NIL</code> value must be a
+ target list (list of <code class="structname">TargetEntry</code>s) containing Vars and/or
+ expressions representing the returned columns. This might be used, for
+ example, to show that the FDW has omitted some columns that it noticed
+ won't be needed for the query. Also, if the FDW can compute expressions
+ used by the query more cheaply than can be done locally, it could add
+ those expressions to <code class="structfield">fdw_scan_tlist</code>. Note that join
+ plans (created from paths made by <code class="function">GetForeignJoinPaths</code>) must
+ always supply <code class="structfield">fdw_scan_tlist</code> to describe the set of
+ columns they will return.
+ </p><p>
+ The FDW should always construct at least one path that depends only on
+ the table's restriction clauses. In join queries, it might also choose
+ to construct path(s) that depend on join clauses, for example
+ <em class="replaceable"><code>foreign_variable</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>local_variable</code></em>. Such clauses will not be found in
+ <code class="literal">baserel-&gt;baserestrictinfo</code> but must be sought in the
+ relation's join lists. A path using such a clause is called a
+ <span class="quote">“<span class="quote">parameterized path</span>”</span>. It must identify the other relations
+ used in the selected join clause(s) with a suitable value of
+ <code class="literal">param_info</code>; use <code class="function">get_baserel_parampathinfo</code>
+ to compute that value. In <code class="function">GetForeignPlan</code>, the
+ <em class="replaceable"><code>local_variable</code></em> portion of the join clause would be added
+ to <code class="structfield">fdw_exprs</code>, and then at run time the case works the
+ same as for an ordinary restriction clause.
+ </p><p>
+ If an FDW supports remote joins, <code class="function">GetForeignJoinPaths</code> should
+ produce <code class="structname">ForeignPath</code>s for potential remote joins in much
+ the same way as <code class="function">GetForeignPaths</code> works for base tables.
+ Information about the intended join can be passed forward
+ to <code class="function">GetForeignPlan</code> in the same ways described above.
+ However, <code class="structfield">baserestrictinfo</code> is not relevant for join
+ relations; instead, the relevant join clauses for a particular join are
+ passed to <code class="function">GetForeignJoinPaths</code> as a separate parameter
+ (<code class="literal">extra-&gt;restrictlist</code>).
+ </p><p>
+ An FDW might additionally support direct execution of some plan actions
+ that are above the level of scans and joins, such as grouping or
+ aggregation. To offer such options, the FDW should generate paths and
+ insert them into the appropriate <em class="firstterm">upper relation</em>. For
+ example, a path representing remote aggregation should be inserted into
+ the <code class="literal">UPPERREL_GROUP_AGG</code> relation, using <code class="function">add_path</code>.
+ This path will be compared on a cost basis with local aggregation
+ performed by reading a simple scan path for the foreign relation (note
+ that such a path must also be supplied, else there will be an error at
+ plan time). If the remote-aggregation path wins, which it usually would,
+ it will be converted into a plan in the usual way, by
+ calling <code class="function">GetForeignPlan</code>. The recommended place to generate
+ such paths is in the <code class="function">GetForeignUpperPaths</code>
+ callback function, which is called for each upper relation (i.e., each
+ post-scan/join processing step), if all the base relations of the query
+ come from the same FDW.
+ </p><p>
+ <code class="function">PlanForeignModify</code> and the other callbacks described in
+ <a class="xref" href="fdw-callbacks.html#FDW-CALLBACKS-UPDATE" title="59.2.4. FDW Routines for Updating Foreign Tables">Section 59.2.4</a> are designed around the assumption
+ that the foreign relation will be scanned in the usual way and then
+ individual row updates will be driven by a local <code class="literal">ModifyTable</code>
+ plan node. This approach is necessary for the general case where an
+ update requires reading local tables as well as foreign tables.
+ However, if the operation could be executed entirely by the foreign
+ server, the FDW could generate a path representing that and insert it
+ into the <code class="literal">UPPERREL_FINAL</code> upper relation, where it would
+ compete against the <code class="literal">ModifyTable</code> approach. This approach
+ could also be used to implement remote <code class="literal">SELECT FOR UPDATE</code>,
+ rather than using the row locking callbacks described in
+ <a class="xref" href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING" title="59.2.6. FDW Routines for Row Locking">Section 59.2.6</a>. Keep in mind that a path
+ inserted into <code class="literal">UPPERREL_FINAL</code> is responsible for
+ implementing <span class="emphasis"><em>all</em></span> behavior of the query.
+ </p><p>
+ When planning an <code class="command">UPDATE</code> or <code class="command">DELETE</code>,
+ <code class="function">PlanForeignModify</code> and <code class="function">PlanDirectModify</code>
+ can look up the <code class="structname">RelOptInfo</code>
+ struct for the foreign table and make use of the
+ <code class="literal">baserel-&gt;fdw_private</code> data previously created by the
+ scan-planning functions. However, in <code class="command">INSERT</code> the target
+ table is not scanned so there is no <code class="structname">RelOptInfo</code> for it.
+ The <code class="structname">List</code> returned by <code class="function">PlanForeignModify</code> has
+ the same restrictions as the <code class="structfield">fdw_private</code> list of a
+ <code class="structname">ForeignScan</code> plan node, that is it must contain only
+ structures that <code class="function">copyObject</code> knows how to copy.
+ </p><p>
+ <code class="command">INSERT</code> with an <code class="literal">ON CONFLICT</code> clause does not
+ support specifying the conflict target, as unique constraints or
+ exclusion constraints on remote tables are not locally known. This
+ in turn implies that <code class="literal">ON CONFLICT DO UPDATE</code> is not supported,
+ since the specification is mandatory there.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-helpers.html" title="59.3. Foreign Data Wrapper Helper Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">59.3. Foreign Data Wrapper Helper Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 59.5. Row Locking in Foreign Data Wrappers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fdw-row-locking.html b/doc/src/sgml/html/fdw-row-locking.html
new file mode 100644
index 0000000..98cd9f5
--- /dev/null
+++ b/doc/src/sgml/html/fdw-row-locking.html
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>59.5. Row Locking in Foreign Data Wrappers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning" /><link rel="next" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">59.5. Row Locking in Foreign Data Wrappers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 59. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method">Next</a></td></tr></table><hr /></div><div class="sect1" id="FDW-ROW-LOCKING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">59.5. Row Locking in Foreign Data Wrappers</h2></div></div></div><p>
+ If an FDW's underlying storage mechanism has a concept of locking
+ individual rows to prevent concurrent updates of those rows, it is
+ usually worthwhile for the FDW to perform row-level locking with as
+ close an approximation as practical to the semantics used in
+ ordinary <span class="productname">PostgreSQL</span> tables. There are multiple
+ considerations involved in this.
+ </p><p>
+ One key decision to be made is whether to perform <em class="firstterm">early
+ locking</em> or <em class="firstterm">late locking</em>. In early locking, a row is
+ locked when it is first retrieved from the underlying store, while in
+ late locking, the row is locked only when it is known that it needs to
+ be locked. (The difference arises because some rows may be discarded by
+ locally-checked restriction or join conditions.) Early locking is much
+ simpler and avoids extra round trips to a remote store, but it can cause
+ locking of rows that need not have been locked, resulting in reduced
+ concurrency or even unexpected deadlocks. Also, late locking is only
+ possible if the row to be locked can be uniquely re-identified later.
+ Preferably the row identifier should identify a specific version of the
+ row, as <span class="productname">PostgreSQL</span> TIDs do.
+ </p><p>
+ By default, <span class="productname">PostgreSQL</span> ignores locking considerations
+ when interfacing to FDWs, but an FDW can perform early locking without
+ any explicit support from the core code. The API functions described
+ in <a class="xref" href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING" title="59.2.6. FDW Routines for Row Locking">Section 59.2.6</a>, which were added
+ in <span class="productname">PostgreSQL</span> 9.5, allow an FDW to use late locking if
+ it wishes.
+ </p><p>
+ An additional consideration is that in <code class="literal">READ COMMITTED</code>
+ isolation mode, <span class="productname">PostgreSQL</span> may need to re-check
+ restriction and join conditions against an updated version of some
+ target tuple. Rechecking join conditions requires re-obtaining copies
+ of the non-target rows that were previously joined to the target tuple.
+ When working with standard <span class="productname">PostgreSQL</span> tables, this is
+ done by including the TIDs of the non-target tables in the column list
+ projected through the join, and then re-fetching non-target rows when
+ required. This approach keeps the join data set compact, but it
+ requires inexpensive re-fetch capability, as well as a TID that can
+ uniquely identify the row version to be re-fetched. By default,
+ therefore, the approach used with foreign tables is to include a copy of
+ the entire row fetched from a foreign table in the column list projected
+ through the join. This puts no special demands on the FDW but can
+ result in reduced performance of merge and hash joins. An FDW that is
+ capable of meeting the re-fetch requirements can choose to do it the
+ first way.
+ </p><p>
+ For an <code class="command">UPDATE</code> or <code class="command">DELETE</code> on a foreign table, it
+ is recommended that the <code class="literal">ForeignScan</code> operation on the target
+ table perform early locking on the rows that it fetches, perhaps via the
+ equivalent of <code class="command">SELECT FOR UPDATE</code>. An FDW can detect whether
+ a table is an <code class="command">UPDATE</code>/<code class="command">DELETE</code> target at plan time
+ by comparing its relid to <code class="literal">root-&gt;parse-&gt;resultRelation</code>,
+ or at execution time by using <code class="function">ExecRelationIsTargetRelation()</code>.
+ An alternative possibility is to perform late locking within the
+ <code class="function">ExecForeignUpdate</code> or <code class="function">ExecForeignDelete</code>
+ callback, but no special support is provided for this.
+ </p><p>
+ For foreign tables that are specified to be locked by a <code class="command">SELECT
+ FOR UPDATE/SHARE</code> command, the <code class="literal">ForeignScan</code> operation can
+ again perform early locking by fetching tuples with the equivalent
+ of <code class="command">SELECT FOR UPDATE/SHARE</code>. To perform late locking
+ instead, provide the callback functions defined
+ in <a class="xref" href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING" title="59.2.6. FDW Routines for Row Locking">Section 59.2.6</a>.
+ In <code class="function">GetForeignRowMarkType</code>, select rowmark option
+ <code class="literal">ROW_MARK_EXCLUSIVE</code>, <code class="literal">ROW_MARK_NOKEYEXCLUSIVE</code>,
+ <code class="literal">ROW_MARK_SHARE</code>, or <code class="literal">ROW_MARK_KEYSHARE</code> depending
+ on the requested lock strength. (The core code will act the same
+ regardless of which of these four options you choose.)
+ Elsewhere, you can detect whether a foreign table was specified to be
+ locked by this type of command by using <code class="function">get_plan_rowmark</code> at
+ plan time, or <code class="function">ExecFindRowMark</code> at execution time; you must
+ check not only whether a non-null rowmark struct is returned, but that
+ its <code class="structfield">strength</code> field is not <code class="literal">LCS_NONE</code>.
+ </p><p>
+ Lastly, for foreign tables that are used in an <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code> or <code class="command">SELECT FOR UPDATE/SHARE</code> command but
+ are not specified to be row-locked, you can override the default choice
+ to copy entire rows by having <code class="function">GetForeignRowMarkType</code> select
+ option <code class="literal">ROW_MARK_REFERENCE</code> when it sees lock strength
+ <code class="literal">LCS_NONE</code>. This will cause <code class="function">RefetchForeignRow</code> to
+ be called with that value for <code class="structfield">markType</code>; it should then
+ re-fetch the row without acquiring any new lock. (If you have
+ a <code class="function">GetForeignRowMarkType</code> function but don't wish to re-fetch
+ unlocked rows, select option <code class="literal">ROW_MARK_COPY</code>
+ for <code class="literal">LCS_NONE</code>.)
+ </p><p>
+ See <code class="filename">src/include/nodes/lockoptions.h</code>, the comments
+ for <code class="type">RowMarkType</code> and <code class="type">PlanRowMark</code>
+ in <code class="filename">src/include/nodes/plannodes.h</code>, and the comments for
+ <code class="type">ExecRowMark</code> in <code class="filename">src/include/nodes/execnodes.h</code> for
+ additional information.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-planning.html" title="59.4. Foreign Data Wrapper Query Planning">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method">Next</a></td></tr><tr><td width="40%" align="left" valign="top">59.4. Foreign Data Wrapper Query Planning </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 60. Writing a Table Sampling Method</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fdwhandler.html b/doc/src/sgml/html/fdwhandler.html
new file mode 100644
index 0000000..314bf8b
--- /dev/null
+++ b/doc/src/sgml/html/fdwhandler.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 59. Writing a Foreign Data Wrapper</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler" /><link rel="next" href="fdw-functions.html" title="59.1. Foreign Data Wrapper Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 59. Writing a Foreign Data Wrapper</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdw-functions.html" title="59.1. Foreign Data Wrapper Functions">Next</a></td></tr></table><hr /></div><div class="chapter" id="FDWHANDLER"><div class="titlepage"><div><div><h2 class="title">Chapter 59. Writing a Foreign Data Wrapper</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="fdw-functions.html">59.1. Foreign Data Wrapper Functions</a></span></dt><dt><span class="sect1"><a href="fdw-callbacks.html">59.2. Foreign Data Wrapper Callback Routines</a></span></dt><dd><dl><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-SCAN">59.2.1. FDW Routines for Scanning Foreign Tables</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-JOIN-SCAN">59.2.2. FDW Routines for Scanning Foreign Joins</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-UPPER-PLANNING">59.2.3. FDW Routines for Planning Post-Scan/Join Processing</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-UPDATE">59.2.4. FDW Routines for Updating Foreign Tables</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-TRUNCATE">59.2.5. FDW Routines for <code class="command">TRUNCATE</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING">59.2.6. FDW Routines for Row Locking</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-EXPLAIN">59.2.7. FDW Routines for <code class="command">EXPLAIN</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ANALYZE">59.2.8. FDW Routines for <code class="command">ANALYZE</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-IMPORT">59.2.9. FDW Routines for <code class="command">IMPORT FOREIGN SCHEMA</code></a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-PARALLEL">59.2.10. FDW Routines for Parallel Execution</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-ASYNC">59.2.11. FDW Routines for Asynchronous Execution</a></span></dt><dt><span class="sect2"><a href="fdw-callbacks.html#FDW-CALLBACKS-REPARAMETERIZE-PATHS">59.2.12. FDW Routines for Reparameterization of Paths</a></span></dt></dl></dd><dt><span class="sect1"><a href="fdw-helpers.html">59.3. Foreign Data Wrapper Helper Functions</a></span></dt><dt><span class="sect1"><a href="fdw-planning.html">59.4. Foreign Data Wrapper Query Planning</a></span></dt><dt><span class="sect1"><a href="fdw-row-locking.html">59.5. Row Locking in Foreign Data Wrappers</a></span></dt></dl></div><a id="id-1.10.10.2" class="indexterm"></a><p>
+ All operations on a foreign table are handled through its foreign data
+ wrapper, which consists of a set of functions that the core server
+ calls. The foreign data wrapper is responsible for fetching
+ data from the remote data source and returning it to the
+ <span class="productname">PostgreSQL</span> executor. If updating foreign
+ tables is to be supported, the wrapper must handle that, too.
+ This chapter outlines how to write a new foreign data wrapper.
+ </p><p>
+ The foreign data wrappers included in the standard distribution are good
+ references when trying to write your own. Look into the
+ <code class="filename">contrib</code> subdirectory of the source tree.
+ The <a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a> reference page also has
+ some useful details.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The SQL standard specifies an interface for writing foreign data wrappers.
+ However, PostgreSQL does not implement that API, because the effort to
+ accommodate it into PostgreSQL would be large, and the standard API hasn't
+ gained wide adoption anyway.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdw-functions.html" title="59.1. Foreign Data Wrapper Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 58. Writing a Procedural Language Handler </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 59.1. Foreign Data Wrapper Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/features-sql-standard.html b/doc/src/sgml/html/features-sql-standard.html
new file mode 100644
index 0000000..d7f7bd5
--- /dev/null
+++ b/doc/src/sgml/html/features-sql-standard.html
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>D.1. Supported Features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="features.html" title="Appendix D. SQL Conformance" /><link rel="next" href="unsupported-features-sql-standard.html" title="D.2. Unsupported Features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">D.1. Supported Features</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="features.html" title="Appendix D. SQL Conformance">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="features.html" title="Appendix D. SQL Conformance">Up</a></td><th width="60%" align="center">Appendix D. SQL Conformance</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="unsupported-features-sql-standard.html" title="D.2. Unsupported Features">Next</a></td></tr></table><hr /></div><div class="sect1" id="FEATURES-SQL-STANDARD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">D.1. Supported Features</h2></div></div></div><p>
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Identifier</th><th>Core?</th><th>Description</th><th>Comment</th></tr></thead><tbody><tr><td>B012</td><td> </td><td>Embedded C</td><td> </td></tr><tr><td>B021</td><td> </td><td>Direct SQL</td><td> </td></tr><tr><td>B128</td><td> </td><td>Routine language SQL</td><td> </td></tr><tr><td>E011</td><td>Core</td><td>Numeric data types</td><td> </td></tr><tr><td>E011-01</td><td>Core</td><td>INTEGER and SMALLINT data types</td><td> </td></tr><tr><td>E011-02</td><td>Core</td><td>REAL, DOUBLE PRECISION, and FLOAT data types</td><td> </td></tr><tr><td>E011-03</td><td>Core</td><td>DECIMAL and NUMERIC data types</td><td> </td></tr><tr><td>E011-04</td><td>Core</td><td>Arithmetic operators</td><td> </td></tr><tr><td>E011-05</td><td>Core</td><td>Numeric comparison</td><td> </td></tr><tr><td>E011-06</td><td>Core</td><td>Implicit casting among the numeric data types</td><td> </td></tr><tr><td>E021</td><td>Core</td><td>Character data types</td><td> </td></tr><tr><td>E021-01</td><td>Core</td><td>CHARACTER data type</td><td> </td></tr><tr><td>E021-02</td><td>Core</td><td>CHARACTER VARYING data type</td><td> </td></tr><tr><td>E021-03</td><td>Core</td><td>Character literals</td><td> </td></tr><tr><td>E021-04</td><td>Core</td><td>CHARACTER_LENGTH function</td><td>trims trailing spaces from CHARACTER values before counting</td></tr><tr><td>E021-05</td><td>Core</td><td>OCTET_LENGTH function</td><td> </td></tr><tr><td>E021-06</td><td>Core</td><td>SUBSTRING function</td><td> </td></tr><tr><td>E021-07</td><td>Core</td><td>Character concatenation</td><td> </td></tr><tr><td>E021-08</td><td>Core</td><td>UPPER and LOWER functions</td><td> </td></tr><tr><td>E021-09</td><td>Core</td><td>TRIM function</td><td> </td></tr><tr><td>E021-10</td><td>Core</td><td>Implicit casting among the character string types</td><td> </td></tr><tr><td>E021-11</td><td>Core</td><td>POSITION function</td><td> </td></tr><tr><td>E021-12</td><td>Core</td><td>Character comparison</td><td> </td></tr><tr><td>E031</td><td>Core</td><td>Identifiers</td><td> </td></tr><tr><td>E031-01</td><td>Core</td><td>Delimited identifiers</td><td> </td></tr><tr><td>E031-02</td><td>Core</td><td>Lower case identifiers</td><td> </td></tr><tr><td>E031-03</td><td>Core</td><td>Trailing underscore</td><td> </td></tr><tr><td>E051</td><td>Core</td><td>Basic query specification</td><td> </td></tr><tr><td>E051-01</td><td>Core</td><td>SELECT DISTINCT</td><td> </td></tr><tr><td>E051-02</td><td>Core</td><td>GROUP BY clause</td><td> </td></tr><tr><td>E051-04</td><td>Core</td><td>GROUP BY can contain columns not in &lt;select list&gt;</td><td> </td></tr><tr><td>E051-05</td><td>Core</td><td>Select list items can be renamed</td><td> </td></tr><tr><td>E051-06</td><td>Core</td><td>HAVING clause</td><td> </td></tr><tr><td>E051-07</td><td>Core</td><td>Qualified * in select list</td><td> </td></tr><tr><td>E051-08</td><td>Core</td><td>Correlation names in the FROM clause</td><td> </td></tr><tr><td>E051-09</td><td>Core</td><td>Rename columns in the FROM clause</td><td> </td></tr><tr><td>E061</td><td>Core</td><td>Basic predicates and search conditions</td><td> </td></tr><tr><td>E061-01</td><td>Core</td><td>Comparison predicate</td><td> </td></tr><tr><td>E061-02</td><td>Core</td><td>BETWEEN predicate</td><td> </td></tr><tr><td>E061-03</td><td>Core</td><td>IN predicate with list of values</td><td> </td></tr><tr><td>E061-04</td><td>Core</td><td>LIKE predicate</td><td> </td></tr><tr><td>E061-05</td><td>Core</td><td>LIKE predicate ESCAPE clause</td><td> </td></tr><tr><td>E061-06</td><td>Core</td><td>NULL predicate</td><td> </td></tr><tr><td>E061-07</td><td>Core</td><td>Quantified comparison predicate</td><td> </td></tr><tr><td>E061-08</td><td>Core</td><td>EXISTS predicate</td><td> </td></tr><tr><td>E061-09</td><td>Core</td><td>Subqueries in comparison predicate</td><td> </td></tr><tr><td>E061-11</td><td>Core</td><td>Subqueries in IN predicate</td><td> </td></tr><tr><td>E061-12</td><td>Core</td><td>Subqueries in quantified comparison predicate</td><td> </td></tr><tr><td>E061-13</td><td>Core</td><td>Correlated subqueries</td><td> </td></tr><tr><td>E061-14</td><td>Core</td><td>Search condition</td><td> </td></tr><tr><td>E071</td><td>Core</td><td>Basic query expressions</td><td> </td></tr><tr><td>E071-01</td><td>Core</td><td>UNION DISTINCT table operator</td><td> </td></tr><tr><td>E071-02</td><td>Core</td><td>UNION ALL table operator</td><td> </td></tr><tr><td>E071-03</td><td>Core</td><td>EXCEPT DISTINCT table operator</td><td> </td></tr><tr><td>E071-05</td><td>Core</td><td>Columns combined via table operators need not have exactly the same data type</td><td> </td></tr><tr><td>E071-06</td><td>Core</td><td>Table operators in subqueries</td><td> </td></tr><tr><td>E081</td><td>Core</td><td>Basic Privileges</td><td> </td></tr><tr><td>E081-01</td><td>Core</td><td>SELECT privilege</td><td> </td></tr><tr><td>E081-02</td><td>Core</td><td>DELETE privilege</td><td> </td></tr><tr><td>E081-03</td><td>Core</td><td>INSERT privilege at the table level</td><td> </td></tr><tr><td>E081-04</td><td>Core</td><td>UPDATE privilege at the table level</td><td> </td></tr><tr><td>E081-05</td><td>Core</td><td>UPDATE privilege at the column level</td><td> </td></tr><tr><td>E081-06</td><td>Core</td><td>REFERENCES privilege at the table level</td><td> </td></tr><tr><td>E081-07</td><td>Core</td><td>REFERENCES privilege at the column level</td><td> </td></tr><tr><td>E081-08</td><td>Core</td><td>WITH GRANT OPTION</td><td> </td></tr><tr><td>E081-09</td><td>Core</td><td>USAGE privilege</td><td> </td></tr><tr><td>E081-10</td><td>Core</td><td>EXECUTE privilege</td><td> </td></tr><tr><td>E091</td><td>Core</td><td>Set functions</td><td> </td></tr><tr><td>E091-01</td><td>Core</td><td>AVG</td><td> </td></tr><tr><td>E091-02</td><td>Core</td><td>COUNT</td><td> </td></tr><tr><td>E091-03</td><td>Core</td><td>MAX</td><td> </td></tr><tr><td>E091-04</td><td>Core</td><td>MIN</td><td> </td></tr><tr><td>E091-05</td><td>Core</td><td>SUM</td><td> </td></tr><tr><td>E091-06</td><td>Core</td><td>ALL quantifier</td><td> </td></tr><tr><td>E091-07</td><td>Core</td><td>DISTINCT quantifier</td><td> </td></tr><tr><td>E101</td><td>Core</td><td>Basic data manipulation</td><td> </td></tr><tr><td>E101-01</td><td>Core</td><td>INSERT statement</td><td> </td></tr><tr><td>E101-03</td><td>Core</td><td>Searched UPDATE statement</td><td> </td></tr><tr><td>E101-04</td><td>Core</td><td>Searched DELETE statement</td><td> </td></tr><tr><td>E111</td><td>Core</td><td>Single row SELECT statement</td><td> </td></tr><tr><td>E121</td><td>Core</td><td>Basic cursor support</td><td> </td></tr><tr><td>E121-01</td><td>Core</td><td>DECLARE CURSOR</td><td> </td></tr><tr><td>E121-02</td><td>Core</td><td>ORDER BY columns need not be in select list</td><td> </td></tr><tr><td>E121-03</td><td>Core</td><td>Value expressions in ORDER BY clause</td><td> </td></tr><tr><td>E121-04</td><td>Core</td><td>OPEN statement</td><td> </td></tr><tr><td>E121-06</td><td>Core</td><td>Positioned UPDATE statement</td><td> </td></tr><tr><td>E121-07</td><td>Core</td><td>Positioned DELETE statement</td><td> </td></tr><tr><td>E121-08</td><td>Core</td><td>CLOSE statement</td><td> </td></tr><tr><td>E121-10</td><td>Core</td><td>FETCH statement implicit NEXT</td><td> </td></tr><tr><td>E121-17</td><td>Core</td><td>WITH HOLD cursors</td><td> </td></tr><tr><td>E131</td><td>Core</td><td>Null value support (nulls in lieu of values)</td><td> </td></tr><tr><td>E141</td><td>Core</td><td>Basic integrity constraints</td><td> </td></tr><tr><td>E141-01</td><td>Core</td><td>NOT NULL constraints</td><td> </td></tr><tr><td>E141-02</td><td>Core</td><td>UNIQUE constraints of NOT NULL columns</td><td> </td></tr><tr><td>E141-03</td><td>Core</td><td>PRIMARY KEY constraints</td><td> </td></tr><tr><td>E141-04</td><td>Core</td><td>Basic FOREIGN KEY constraint with the NO ACTION default for both referential delete action and referential update action</td><td> </td></tr><tr><td>E141-06</td><td>Core</td><td>CHECK constraints</td><td> </td></tr><tr><td>E141-07</td><td>Core</td><td>Column defaults</td><td> </td></tr><tr><td>E141-08</td><td>Core</td><td>NOT NULL inferred on PRIMARY KEY</td><td> </td></tr><tr><td>E141-10</td><td>Core</td><td>Names in a foreign key can be specified in any order</td><td> </td></tr><tr><td>E151</td><td>Core</td><td>Transaction support</td><td> </td></tr><tr><td>E151-01</td><td>Core</td><td>COMMIT statement</td><td> </td></tr><tr><td>E151-02</td><td>Core</td><td>ROLLBACK statement</td><td> </td></tr><tr><td>E152</td><td>Core</td><td>Basic SET TRANSACTION statement</td><td> </td></tr><tr><td>E152-01</td><td>Core</td><td>SET TRANSACTION statement: ISOLATION LEVEL SERIALIZABLE clause</td><td> </td></tr><tr><td>E152-02</td><td>Core</td><td>SET TRANSACTION statement: READ ONLY and READ WRITE clauses</td><td> </td></tr><tr><td>E153</td><td>Core</td><td>Updatable queries with subqueries</td><td> </td></tr><tr><td>E161</td><td>Core</td><td>SQL comments using leading double minus</td><td> </td></tr><tr><td>E171</td><td>Core</td><td>SQLSTATE support</td><td> </td></tr><tr><td>E182</td><td>Core</td><td>Host language binding</td><td> </td></tr><tr><td>F021</td><td>Core</td><td>Basic information schema</td><td> </td></tr><tr><td>F021-01</td><td>Core</td><td>COLUMNS view</td><td> </td></tr><tr><td>F021-02</td><td>Core</td><td>TABLES view</td><td> </td></tr><tr><td>F021-03</td><td>Core</td><td>VIEWS view</td><td> </td></tr><tr><td>F021-04</td><td>Core</td><td>TABLE_CONSTRAINTS view</td><td> </td></tr><tr><td>F021-05</td><td>Core</td><td>REFERENTIAL_CONSTRAINTS view</td><td> </td></tr><tr><td>F021-06</td><td>Core</td><td>CHECK_CONSTRAINTS view</td><td> </td></tr><tr><td>F031</td><td>Core</td><td>Basic schema manipulation</td><td> </td></tr><tr><td>F031-01</td><td>Core</td><td>CREATE TABLE statement to create persistent base tables</td><td> </td></tr><tr><td>F031-02</td><td>Core</td><td>CREATE VIEW statement</td><td> </td></tr><tr><td>F031-03</td><td>Core</td><td>GRANT statement</td><td> </td></tr><tr><td>F031-04</td><td>Core</td><td>ALTER TABLE statement: ADD COLUMN clause</td><td> </td></tr><tr><td>F031-13</td><td>Core</td><td>DROP TABLE statement: RESTRICT clause</td><td> </td></tr><tr><td>F031-16</td><td>Core</td><td>DROP VIEW statement: RESTRICT clause</td><td> </td></tr><tr><td>F031-19</td><td>Core</td><td>REVOKE statement: RESTRICT clause</td><td> </td></tr><tr><td>F032</td><td> </td><td>CASCADE drop behavior</td><td> </td></tr><tr><td>F033</td><td> </td><td>ALTER TABLE statement: DROP COLUMN clause</td><td> </td></tr><tr><td>F034</td><td> </td><td>Extended REVOKE statement</td><td> </td></tr><tr><td>F034-01</td><td> </td><td>REVOKE statement performed by other than the owner of a schema object</td><td> </td></tr><tr><td>F034-02</td><td> </td><td>REVOKE statement: GRANT OPTION FOR clause</td><td> </td></tr><tr><td>F034-03</td><td> </td><td>REVOKE statement to revoke a privilege that the grantee has WITH GRANT OPTION</td><td> </td></tr><tr><td>F041</td><td>Core</td><td>Basic joined table</td><td> </td></tr><tr><td>F041-01</td><td>Core</td><td>Inner join (but not necessarily the INNER keyword)</td><td> </td></tr><tr><td>F041-02</td><td>Core</td><td>INNER keyword</td><td> </td></tr><tr><td>F041-03</td><td>Core</td><td>LEFT OUTER JOIN</td><td> </td></tr><tr><td>F041-04</td><td>Core</td><td>RIGHT OUTER JOIN</td><td> </td></tr><tr><td>F041-05</td><td>Core</td><td>Outer joins can be nested</td><td> </td></tr><tr><td>F041-07</td><td>Core</td><td>The inner table in a left or right outer join can also be used in an inner join</td><td> </td></tr><tr><td>F041-08</td><td>Core</td><td>All comparison operators are supported (rather than just =)</td><td> </td></tr><tr><td>F051</td><td>Core</td><td>Basic date and time</td><td> </td></tr><tr><td>F051-01</td><td>Core</td><td>DATE data type (including support of DATE literal)</td><td> </td></tr><tr><td>F051-02</td><td>Core</td><td>TIME data type (including support of TIME literal) with fractional seconds precision of at least 0</td><td> </td></tr><tr><td>F051-03</td><td>Core</td><td>TIMESTAMP data type (including support of TIMESTAMP literal) with fractional seconds precision of at least 0 and 6</td><td> </td></tr><tr><td>F051-04</td><td>Core</td><td>Comparison predicate on DATE, TIME, and TIMESTAMP data types</td><td> </td></tr><tr><td>F051-05</td><td>Core</td><td>Explicit CAST between datetime types and character string types</td><td> </td></tr><tr><td>F051-06</td><td>Core</td><td>CURRENT_DATE</td><td> </td></tr><tr><td>F051-07</td><td>Core</td><td>LOCALTIME</td><td> </td></tr><tr><td>F051-08</td><td>Core</td><td>LOCALTIMESTAMP</td><td> </td></tr><tr><td>F052</td><td> </td><td>Intervals and datetime arithmetic</td><td> </td></tr><tr><td>F053</td><td> </td><td>OVERLAPS predicate</td><td> </td></tr><tr><td>F081</td><td>Core</td><td>UNION and EXCEPT in views</td><td> </td></tr><tr><td>F111</td><td> </td><td>Isolation levels other than SERIALIZABLE</td><td> </td></tr><tr><td>F111-01</td><td> </td><td>READ UNCOMMITTED isolation level</td><td> </td></tr><tr><td>F111-02</td><td> </td><td>READ COMMITTED isolation level</td><td> </td></tr><tr><td>F111-03</td><td> </td><td>REPEATABLE READ isolation level</td><td> </td></tr><tr><td>F131</td><td>Core</td><td>Grouped operations</td><td> </td></tr><tr><td>F131-01</td><td>Core</td><td>WHERE, GROUP BY, and HAVING clauses supported in queries with grouped views</td><td> </td></tr><tr><td>F131-02</td><td>Core</td><td>Multiple tables supported in queries with grouped views</td><td> </td></tr><tr><td>F131-03</td><td>Core</td><td>Set functions supported in queries with grouped views</td><td> </td></tr><tr><td>F131-04</td><td>Core</td><td>Subqueries with GROUP BY and HAVING clauses and grouped views</td><td> </td></tr><tr><td>F131-05</td><td>Core</td><td>Single row SELECT with GROUP BY and HAVING clauses and grouped views</td><td> </td></tr><tr><td>F171</td><td> </td><td>Multiple schemas per user</td><td> </td></tr><tr><td>F181</td><td>Core</td><td>Multiple module support</td><td> </td></tr><tr><td>F191</td><td> </td><td>Referential delete actions</td><td> </td></tr><tr><td>F200</td><td> </td><td>TRUNCATE TABLE statement</td><td> </td></tr><tr><td>F201</td><td>Core</td><td>CAST function</td><td> </td></tr><tr><td>F202</td><td> </td><td>TRUNCATE TABLE: identity column restart option</td><td> </td></tr><tr><td>F221</td><td>Core</td><td>Explicit defaults</td><td> </td></tr><tr><td>F222</td><td> </td><td>INSERT statement: DEFAULT VALUES clause</td><td> </td></tr><tr><td>F231</td><td> </td><td>Privilege tables</td><td> </td></tr><tr><td>F231-01</td><td> </td><td>TABLE_PRIVILEGES view</td><td> </td></tr><tr><td>F231-02</td><td> </td><td>COLUMN_PRIVILEGES view</td><td> </td></tr><tr><td>F231-03</td><td> </td><td>USAGE_PRIVILEGES view</td><td> </td></tr><tr><td>F251</td><td> </td><td>Domain support</td><td> </td></tr><tr><td>F261</td><td>Core</td><td>CASE expression</td><td> </td></tr><tr><td>F261-01</td><td>Core</td><td>Simple CASE</td><td> </td></tr><tr><td>F261-02</td><td>Core</td><td>Searched CASE</td><td> </td></tr><tr><td>F261-03</td><td>Core</td><td>NULLIF</td><td> </td></tr><tr><td>F261-04</td><td>Core</td><td>COALESCE</td><td> </td></tr><tr><td>F262</td><td> </td><td>Extended CASE expression</td><td> </td></tr><tr><td>F271</td><td> </td><td>Compound character literals</td><td> </td></tr><tr><td>F281</td><td> </td><td>LIKE enhancements</td><td> </td></tr><tr><td>F292</td><td> </td><td>UNIQUE null treatment</td><td>SQL:202x draft</td></tr><tr><td>F302</td><td> </td><td>INTERSECT table operator</td><td> </td></tr><tr><td>F302-01</td><td> </td><td>INTERSECT DISTINCT table operator</td><td> </td></tr><tr><td>F302-02</td><td> </td><td>INTERSECT ALL table operator</td><td> </td></tr><tr><td>F304</td><td> </td><td>EXCEPT ALL table operator</td><td> </td></tr><tr><td>F311</td><td>Core</td><td>Schema definition statement</td><td> </td></tr><tr><td>F311-01</td><td>Core</td><td>CREATE SCHEMA</td><td> </td></tr><tr><td>F311-02</td><td>Core</td><td>CREATE TABLE for persistent base tables</td><td> </td></tr><tr><td>F311-03</td><td>Core</td><td>CREATE VIEW</td><td> </td></tr><tr><td>F311-04</td><td>Core</td><td>CREATE VIEW: WITH CHECK OPTION</td><td> </td></tr><tr><td>F311-05</td><td>Core</td><td>GRANT statement</td><td> </td></tr><tr><td>F312</td><td> </td><td>MERGE statement</td><td> </td></tr><tr><td>F313</td><td> </td><td>Enhanced MERGE statement</td><td> </td></tr><tr><td>F314</td><td> </td><td>MERGE statement with DELETE branch</td><td> </td></tr><tr><td>F321</td><td> </td><td>User authorization</td><td> </td></tr><tr><td>F341</td><td> </td><td>Usage tables</td><td> </td></tr><tr><td>F361</td><td> </td><td>Subprogram support</td><td> </td></tr><tr><td>F381</td><td> </td><td>Extended schema manipulation</td><td> </td></tr><tr><td>F381-01</td><td> </td><td>ALTER TABLE statement: ALTER COLUMN clause</td><td> </td></tr><tr><td>F381-02</td><td> </td><td>ALTER TABLE statement: ADD CONSTRAINT clause</td><td> </td></tr><tr><td>F381-03</td><td> </td><td>ALTER TABLE statement: DROP CONSTRAINT clause</td><td> </td></tr><tr><td>F382</td><td> </td><td>Alter column data type</td><td> </td></tr><tr><td>F383</td><td> </td><td>Set column not null clause</td><td> </td></tr><tr><td>F384</td><td> </td><td>Drop identity property clause</td><td> </td></tr><tr><td>F385</td><td> </td><td>Drop column generation expression clause</td><td> </td></tr><tr><td>F386</td><td> </td><td>Set identity column generation clause</td><td> </td></tr><tr><td>F391</td><td> </td><td>Long identifiers</td><td> </td></tr><tr><td>F392</td><td> </td><td>Unicode escapes in identifiers</td><td> </td></tr><tr><td>F393</td><td> </td><td>Unicode escapes in literals</td><td> </td></tr><tr><td>F394</td><td> </td><td>Optional normal form specification</td><td> </td></tr><tr><td>F401</td><td> </td><td>Extended joined table</td><td> </td></tr><tr><td>F401-01</td><td> </td><td>NATURAL JOIN</td><td> </td></tr><tr><td>F401-02</td><td> </td><td>FULL OUTER JOIN</td><td> </td></tr><tr><td>F401-04</td><td> </td><td>CROSS JOIN</td><td> </td></tr><tr><td>F402</td><td> </td><td>Named column joins for LOBs, arrays, and multisets</td><td> </td></tr><tr><td>F404</td><td> </td><td>Range variable for common column names</td><td> </td></tr><tr><td>F411</td><td> </td><td>Time zone specification</td><td>differences regarding literal interpretation</td></tr><tr><td>F421</td><td> </td><td>National character</td><td> </td></tr><tr><td>F431</td><td> </td><td>Read-only scrollable cursors</td><td> </td></tr><tr><td>F431-01</td><td> </td><td>FETCH with explicit NEXT</td><td> </td></tr><tr><td>F431-02</td><td> </td><td>FETCH FIRST</td><td> </td></tr><tr><td>F431-03</td><td> </td><td>FETCH LAST</td><td> </td></tr><tr><td>F431-04</td><td> </td><td>FETCH PRIOR</td><td> </td></tr><tr><td>F431-05</td><td> </td><td>FETCH ABSOLUTE</td><td> </td></tr><tr><td>F431-06</td><td> </td><td>FETCH RELATIVE</td><td> </td></tr><tr><td>F441</td><td> </td><td>Extended set function support</td><td> </td></tr><tr><td>F442</td><td> </td><td>Mixed column references in set functions</td><td> </td></tr><tr><td>F471</td><td>Core</td><td>Scalar subquery values</td><td> </td></tr><tr><td>F481</td><td>Core</td><td>Expanded NULL predicate</td><td> </td></tr><tr><td>F491</td><td> </td><td>Constraint management</td><td> </td></tr><tr><td>F501</td><td>Core</td><td>Features and conformance views</td><td> </td></tr><tr><td>F501-01</td><td>Core</td><td>SQL_FEATURES view</td><td> </td></tr><tr><td>F501-02</td><td>Core</td><td>SQL_SIZING view</td><td> </td></tr><tr><td>F502</td><td> </td><td>Enhanced documentation tables</td><td> </td></tr><tr><td>F531</td><td> </td><td>Temporary tables</td><td> </td></tr><tr><td>F555</td><td> </td><td>Enhanced seconds precision</td><td> </td></tr><tr><td>F561</td><td> </td><td>Full value expressions</td><td> </td></tr><tr><td>F571</td><td> </td><td>Truth value tests</td><td> </td></tr><tr><td>F591</td><td> </td><td>Derived tables</td><td> </td></tr><tr><td>F611</td><td> </td><td>Indicator data types</td><td> </td></tr><tr><td>F641</td><td> </td><td>Row and table constructors</td><td> </td></tr><tr><td>F651</td><td> </td><td>Catalog name qualifiers</td><td> </td></tr><tr><td>F661</td><td> </td><td>Simple tables</td><td> </td></tr><tr><td>F672</td><td> </td><td>Retrospective check constraints</td><td> </td></tr><tr><td>F690</td><td> </td><td>Collation support</td><td>but no character set support</td></tr><tr><td>F692</td><td> </td><td>Extended collation support</td><td> </td></tr><tr><td>F701</td><td> </td><td>Referential update actions</td><td> </td></tr><tr><td>F711</td><td> </td><td>ALTER domain</td><td> </td></tr><tr><td>F731</td><td> </td><td>INSERT column privileges</td><td> </td></tr><tr><td>F751</td><td> </td><td>View CHECK enhancements</td><td> </td></tr><tr><td>F761</td><td> </td><td>Session management</td><td> </td></tr><tr><td>F762</td><td> </td><td>CURRENT_CATALOG</td><td> </td></tr><tr><td>F763</td><td> </td><td>CURRENT_SCHEMA</td><td> </td></tr><tr><td>F771</td><td> </td><td>Connection management</td><td> </td></tr><tr><td>F781</td><td> </td><td>Self-referencing operations</td><td> </td></tr><tr><td>F791</td><td> </td><td>Insensitive cursors</td><td> </td></tr><tr><td>F801</td><td> </td><td>Full set function</td><td> </td></tr><tr><td>F850</td><td> </td><td>Top-level &lt;order by clause&gt; in &lt;query expression&gt;</td><td> </td></tr><tr><td>F851</td><td> </td><td>&lt;order by clause&gt; in subqueries</td><td> </td></tr><tr><td>F852</td><td> </td><td>Top-level &lt;order by clause&gt; in views</td><td> </td></tr><tr><td>F855</td><td> </td><td>Nested &lt;order by clause&gt; in &lt;query expression&gt;</td><td> </td></tr><tr><td>F856</td><td> </td><td>Nested &lt;fetch first clause&gt; in &lt;query expression&gt;</td><td> </td></tr><tr><td>F857</td><td> </td><td>Top-level &lt;fetch first clause&gt; in &lt;query expression&gt;</td><td> </td></tr><tr><td>F858</td><td> </td><td>&lt;fetch first clause&gt; in subqueries</td><td> </td></tr><tr><td>F859</td><td> </td><td>Top-level &lt;fetch first clause&gt; in views</td><td> </td></tr><tr><td>F860</td><td> </td><td>&lt;fetch first row count&gt; in &lt;fetch first clause&gt;</td><td> </td></tr><tr><td>F861</td><td> </td><td>Top-level &lt;result offset clause&gt; in &lt;query expression&gt;</td><td> </td></tr><tr><td>F862</td><td> </td><td>&lt;result offset clause&gt; in subqueries</td><td> </td></tr><tr><td>F863</td><td> </td><td>Nested &lt;result offset clause&gt; in &lt;query expression&gt;</td><td> </td></tr><tr><td>F864</td><td> </td><td>Top-level &lt;result offset clause&gt; in views</td><td> </td></tr><tr><td>F865</td><td> </td><td>&lt;offset row count&gt; in &lt;result offset clause&gt;</td><td> </td></tr><tr><td>F867</td><td> </td><td>FETCH FIRST clause: WITH TIES option</td><td> </td></tr><tr><td>S071</td><td> </td><td>SQL paths in function and type name resolution</td><td> </td></tr><tr><td>S091-01</td><td> </td><td>Arrays of built-in data types</td><td> </td></tr><tr><td>S091-03</td><td> </td><td>Array expressions</td><td> </td></tr><tr><td>S092</td><td> </td><td>Arrays of user-defined types</td><td> </td></tr><tr><td>S095</td><td> </td><td>Array constructors by query</td><td> </td></tr><tr><td>S096</td><td> </td><td>Optional array bounds</td><td> </td></tr><tr><td>S098</td><td> </td><td>ARRAY_AGG</td><td> </td></tr><tr><td>S111</td><td> </td><td>ONLY in query expressions</td><td> </td></tr><tr><td>S201</td><td> </td><td>SQL-invoked routines on arrays</td><td> </td></tr><tr><td>S201-01</td><td> </td><td>Array parameters</td><td> </td></tr><tr><td>S201-02</td><td> </td><td>Array as result type of functions</td><td> </td></tr><tr><td>S211</td><td> </td><td>User-defined cast functions</td><td> </td></tr><tr><td>S301</td><td> </td><td>Enhanced UNNEST</td><td> </td></tr><tr><td>S404</td><td> </td><td>TRIM_ARRAY</td><td> </td></tr><tr><td>T031</td><td> </td><td>BOOLEAN data type</td><td> </td></tr><tr><td>T071</td><td> </td><td>BIGINT data type</td><td> </td></tr><tr><td>T121</td><td> </td><td>WITH (excluding RECURSIVE) in query expression</td><td> </td></tr><tr><td>T122</td><td> </td><td>WITH (excluding RECURSIVE) in subquery</td><td> </td></tr><tr><td>T131</td><td> </td><td>Recursive query</td><td> </td></tr><tr><td>T132</td><td> </td><td>Recursive query in subquery</td><td> </td></tr><tr><td>T133</td><td> </td><td>Enhanced cycle mark values</td><td>SQL:202x draft</td></tr><tr><td>T141</td><td> </td><td>SIMILAR predicate</td><td> </td></tr><tr><td>T151</td><td> </td><td>DISTINCT predicate</td><td> </td></tr><tr><td>T152</td><td> </td><td>DISTINCT predicate with negation</td><td> </td></tr><tr><td>T171</td><td> </td><td>LIKE clause in table definition</td><td> </td></tr><tr><td>T172</td><td> </td><td>AS subquery clause in table definition</td><td> </td></tr><tr><td>T173</td><td> </td><td>Extended LIKE clause in table definition</td><td> </td></tr><tr><td>T174</td><td> </td><td>Identity columns</td><td> </td></tr><tr><td>T177</td><td> </td><td>Sequence generator support: simple restart option</td><td> </td></tr><tr><td>T178</td><td> </td><td>Identity columns: simple restart option</td><td> </td></tr><tr><td>T191</td><td> </td><td>Referential action RESTRICT</td><td> </td></tr><tr><td>T201</td><td> </td><td>Comparable data types for referential constraints</td><td> </td></tr><tr><td>T211-01</td><td> </td><td>Triggers activated on UPDATE, INSERT, or DELETE of one base table</td><td> </td></tr><tr><td>T211-02</td><td> </td><td>BEFORE triggers</td><td> </td></tr><tr><td>T211-03</td><td> </td><td>AFTER triggers</td><td> </td></tr><tr><td>T211-04</td><td> </td><td>FOR EACH ROW triggers</td><td> </td></tr><tr><td>T211-05</td><td> </td><td>Ability to specify a search condition that must be true before the trigger is invoked</td><td> </td></tr><tr><td>T211-07</td><td> </td><td>TRIGGER privilege</td><td> </td></tr><tr><td>T212</td><td> </td><td>Enhanced trigger capability</td><td> </td></tr><tr><td>T213</td><td> </td><td>INSTEAD OF triggers</td><td> </td></tr><tr><td>T241</td><td> </td><td>START TRANSACTION statement</td><td> </td></tr><tr><td>T261</td><td> </td><td>Chained transactions</td><td> </td></tr><tr><td>T271</td><td> </td><td>Savepoints</td><td> </td></tr><tr><td>T281</td><td> </td><td>SELECT privilege with column granularity</td><td> </td></tr><tr><td>T285</td><td> </td><td>Enhanced derived column names</td><td> </td></tr><tr><td>T312</td><td> </td><td>OVERLAY function</td><td> </td></tr><tr><td>T321-01</td><td>Core</td><td>User-defined functions with no overloading</td><td> </td></tr><tr><td>T321-02</td><td>Core</td><td>User-defined stored procedures with no overloading</td><td> </td></tr><tr><td>T321-03</td><td>Core</td><td>Function invocation</td><td> </td></tr><tr><td>T321-04</td><td>Core</td><td>CALL statement</td><td> </td></tr><tr><td>T321-05</td><td>Core</td><td>RETURN statement</td><td> </td></tr><tr><td>T321-06</td><td>Core</td><td>ROUTINES view</td><td> </td></tr><tr><td>T321-07</td><td>Core</td><td>PARAMETERS view</td><td> </td></tr><tr><td>T323</td><td> </td><td>Explicit security for external routines</td><td> </td></tr><tr><td>T325</td><td> </td><td>Qualified SQL parameter references</td><td> </td></tr><tr><td>T331</td><td> </td><td>Basic roles</td><td> </td></tr><tr><td>T332</td><td> </td><td>Extended roles</td><td> </td></tr><tr><td>T341</td><td> </td><td>Overloading of SQL-invoked functions and procedures</td><td> </td></tr><tr><td>T351</td><td> </td><td>Bracketed SQL comments (/*...*/ comments)</td><td> </td></tr><tr><td>T431</td><td> </td><td>Extended grouping capabilities</td><td> </td></tr><tr><td>T432</td><td> </td><td>Nested and concatenated GROUPING SETS</td><td> </td></tr><tr><td>T433</td><td> </td><td>Multiargument GROUPING function</td><td> </td></tr><tr><td>T434</td><td> </td><td>GROUP BY DISTINCT</td><td> </td></tr><tr><td>T441</td><td> </td><td>ABS and MOD functions</td><td> </td></tr><tr><td>T461</td><td> </td><td>Symmetric BETWEEN predicate</td><td> </td></tr><tr><td>T491</td><td> </td><td>LATERAL derived table</td><td> </td></tr><tr><td>T501</td><td> </td><td>Enhanced EXISTS predicate</td><td> </td></tr><tr><td>T521</td><td> </td><td>Named arguments in CALL statement</td><td> </td></tr><tr><td>T523</td><td> </td><td>Default values for INOUT parameters of SQL-invoked procedures</td><td> </td></tr><tr><td>T524</td><td> </td><td>Named arguments in routine invocations other than a CALL statement</td><td> </td></tr><tr><td>T525</td><td> </td><td>Default values for parameters of SQL-invoked functions</td><td> </td></tr><tr><td>T551</td><td> </td><td>Optional key words for default syntax</td><td> </td></tr><tr><td>T581</td><td> </td><td>Regular expression substring function</td><td> </td></tr><tr><td>T591</td><td> </td><td>UNIQUE constraints of possibly null columns</td><td> </td></tr><tr><td>T611</td><td> </td><td>Elementary OLAP operations</td><td> </td></tr><tr><td>T612</td><td> </td><td>Advanced OLAP operations</td><td> </td></tr><tr><td>T613</td><td> </td><td>Sampling</td><td> </td></tr><tr><td>T614</td><td> </td><td>NTILE function</td><td> </td></tr><tr><td>T615</td><td> </td><td>LEAD and LAG functions</td><td> </td></tr><tr><td>T617</td><td> </td><td>FIRST_VALUE and LAST_VALUE function</td><td> </td></tr><tr><td>T620</td><td> </td><td>WINDOW clause: GROUPS option</td><td> </td></tr><tr><td>T621</td><td> </td><td>Enhanced numeric functions</td><td> </td></tr><tr><td>T622</td><td> </td><td>Trigonometric functions</td><td> </td></tr><tr><td>T623</td><td> </td><td>General logarithm functions</td><td> </td></tr><tr><td>T624</td><td> </td><td>Common logarithm functions</td><td> </td></tr><tr><td>T631</td><td>Core</td><td>IN predicate with one list element</td><td> </td></tr><tr><td>T651</td><td> </td><td>SQL-schema statements in SQL routines</td><td> </td></tr><tr><td>T653</td><td> </td><td>SQL-schema statements in external routines</td><td> </td></tr><tr><td>T655</td><td> </td><td>Cyclically dependent routines</td><td> </td></tr><tr><td>T831</td><td> </td><td>SQL/JSON path language: strict mode</td><td> </td></tr><tr><td>T832</td><td> </td><td>SQL/JSON path language: item method</td><td> </td></tr><tr><td>T833</td><td> </td><td>SQL/JSON path language: multiple subscripts</td><td> </td></tr><tr><td>T834</td><td> </td><td>SQL/JSON path language: wildcard member accessor</td><td> </td></tr><tr><td>T835</td><td> </td><td>SQL/JSON path language: filter expressions</td><td> </td></tr><tr><td>T836</td><td> </td><td>SQL/JSON path language: starts with predicate</td><td> </td></tr><tr><td>T837</td><td> </td><td>SQL/JSON path language: regex_like predicate</td><td> </td></tr><tr><td>X010</td><td> </td><td>XML type</td><td> </td></tr><tr><td>X011</td><td> </td><td>Arrays of XML type</td><td> </td></tr><tr><td>X014</td><td> </td><td>Attributes of XML type</td><td> </td></tr><tr><td>X016</td><td> </td><td>Persistent XML values</td><td> </td></tr><tr><td>X020</td><td> </td><td>XMLConcat</td><td> </td></tr><tr><td>X031</td><td> </td><td>XMLElement</td><td> </td></tr><tr><td>X032</td><td> </td><td>XMLForest</td><td> </td></tr><tr><td>X034</td><td> </td><td>XMLAgg</td><td> </td></tr><tr><td>X035</td><td> </td><td>XMLAgg: ORDER BY option</td><td> </td></tr><tr><td>X036</td><td> </td><td>XMLComment</td><td> </td></tr><tr><td>X037</td><td> </td><td>XMLPI</td><td> </td></tr><tr><td>X040</td><td> </td><td>Basic table mapping</td><td> </td></tr><tr><td>X041</td><td> </td><td>Basic table mapping: nulls absent</td><td> </td></tr><tr><td>X042</td><td> </td><td>Basic table mapping: null as nil</td><td> </td></tr><tr><td>X043</td><td> </td><td>Basic table mapping: table as forest</td><td> </td></tr><tr><td>X044</td><td> </td><td>Basic table mapping: table as element</td><td> </td></tr><tr><td>X045</td><td> </td><td>Basic table mapping: with target namespace</td><td> </td></tr><tr><td>X046</td><td> </td><td>Basic table mapping: data mapping</td><td> </td></tr><tr><td>X047</td><td> </td><td>Basic table mapping: metadata mapping</td><td> </td></tr><tr><td>X048</td><td> </td><td>Basic table mapping: base64 encoding of binary strings</td><td> </td></tr><tr><td>X049</td><td> </td><td>Basic table mapping: hex encoding of binary strings</td><td> </td></tr><tr><td>X050</td><td> </td><td>Advanced table mapping</td><td> </td></tr><tr><td>X051</td><td> </td><td>Advanced table mapping: nulls absent</td><td> </td></tr><tr><td>X052</td><td> </td><td>Advanced table mapping: null as nil</td><td> </td></tr><tr><td>X053</td><td> </td><td>Advanced table mapping: table as forest</td><td> </td></tr><tr><td>X054</td><td> </td><td>Advanced table mapping: table as element</td><td> </td></tr><tr><td>X055</td><td> </td><td>Advanced table mapping: with target namespace</td><td> </td></tr><tr><td>X056</td><td> </td><td>Advanced table mapping: data mapping</td><td> </td></tr><tr><td>X057</td><td> </td><td>Advanced table mapping: metadata mapping</td><td> </td></tr><tr><td>X058</td><td> </td><td>Advanced table mapping: base64 encoding of binary strings</td><td> </td></tr><tr><td>X059</td><td> </td><td>Advanced table mapping: hex encoding of binary strings</td><td> </td></tr><tr><td>X060</td><td> </td><td>XMLParse: character string input and CONTENT option</td><td> </td></tr><tr><td>X061</td><td> </td><td>XMLParse: character string input and DOCUMENT option</td><td> </td></tr><tr><td>X070</td><td> </td><td>XMLSerialize: character string serialization and CONTENT option</td><td> </td></tr><tr><td>X071</td><td> </td><td>XMLSerialize: character string serialization and DOCUMENT option</td><td> </td></tr><tr><td>X072</td><td> </td><td>XMLSerialize: character string serialization</td><td> </td></tr><tr><td>X090</td><td> </td><td>XML document predicate</td><td> </td></tr><tr><td>X120</td><td> </td><td>XML parameters in SQL routines</td><td> </td></tr><tr><td>X121</td><td> </td><td>XML parameters in external routines</td><td> </td></tr><tr><td>X221</td><td> </td><td>XML passing mechanism BY VALUE</td><td> </td></tr><tr><td>X301</td><td> </td><td>XMLTable: derived column list option</td><td> </td></tr><tr><td>X302</td><td> </td><td>XMLTable: ordinality column option</td><td> </td></tr><tr><td>X303</td><td> </td><td>XMLTable: column default option</td><td> </td></tr><tr><td>X304</td><td> </td><td>XMLTable: passing a context item</td><td>must be XML DOCUMENT</td></tr><tr><td>X400</td><td> </td><td>Name and identifier mapping</td><td> </td></tr><tr><td>X410</td><td> </td><td>Alter column data type: XML type</td><td> </td></tr></tbody></table></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="features.html" title="Appendix D. SQL Conformance">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="features.html" title="Appendix D. SQL Conformance">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="unsupported-features-sql-standard.html" title="D.2. Unsupported Features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix D. SQL Conformance </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> D.2. Unsupported Features</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/features.html b/doc/src/sgml/html/features.html
new file mode 100644
index 0000000..deeaaab
--- /dev/null
+++ b/doc/src/sgml/html/features.html
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix D. SQL Conformance</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words" /><link rel="next" href="features-sql-standard.html" title="D.1. Supported Features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix D. SQL Conformance</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="features-sql-standard.html" title="D.1. Supported Features">Next</a></td></tr></table><hr /></div><div class="appendix" id="FEATURES"><div class="titlepage"><div><div><h2 class="title">Appendix D. SQL Conformance</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="features-sql-standard.html">D.1. Supported Features</a></span></dt><dt><span class="sect1"><a href="unsupported-features-sql-standard.html">D.2. Unsupported Features</a></span></dt><dt><span class="sect1"><a href="xml-limits-conformance.html">D.3. XML Limits and Conformance to SQL/XML</a></span></dt><dd><dl><dt><span class="sect2"><a href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-XPATH1">D.3.1. Queries Are Restricted to XPath 1.0</a></span></dt><dt><span class="sect2"><a href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-POSTGRESQL">D.3.2. Incidental Limits of the Implementation</a></span></dt></dl></dd></dl></div><p>
+ This section attempts to outline to what extent
+ <span class="productname">PostgreSQL</span> conforms to the current SQL
+ standard. The following information is not a full statement of
+ conformance, but it presents the main topics in as much detail as is
+ both reasonable and useful for users.
+ </p><p>
+ The formal name of the SQL standard is ISO/IEC 9075 <span class="quote">“<span class="quote">Database
+ Language SQL</span>”</span>. A revised version of the standard is released
+ from time to time; the most recent update appearing in 2016.
+ The 2016 version is referred to as ISO/IEC 9075:2016, or simply as SQL:2016.
+ The versions prior to that were SQL:2011, SQL:2008, SQL:2006, SQL:2003,
+ SQL:1999, and SQL-92. Each version
+ replaces the previous one, so claims of conformance to earlier
+ versions have no official merit.
+ <span class="productname">PostgreSQL</span> development aims for
+ conformance with the latest official version of the standard where
+ such conformance does not contradict traditional features or common
+ sense. Many of the features required by the SQL
+ standard are supported, though sometimes with slightly differing
+ syntax or function. Further moves towards conformance can be
+ expected over time.
+ </p><p>
+ <acronym class="acronym">SQL-92</acronym> defined three feature sets for
+ conformance: Entry, Intermediate, and Full. Most database
+ management systems claiming <acronym class="acronym">SQL</acronym> standard
+ conformance were conforming at only the Entry level, since the
+ entire set of features in the Intermediate and Full levels was
+ either too voluminous or in conflict with legacy behaviors.
+ </p><p>
+ Starting with <acronym class="acronym">SQL:1999</acronym>, the SQL standard defines
+ a large set of individual features rather than the ineffectively
+ broad three levels found in <acronym class="acronym">SQL-92</acronym>. A large
+ subset of these features represents the <span class="quote">“<span class="quote">Core</span>”</span>
+ features, which every conforming SQL implementation must supply.
+ The rest of the features are purely optional.
+ </p><p>
+ The standard versions beginning with <acronym class="acronym">SQL:2003</acronym>
+ are also split into a number
+ of parts. Each is known by a shorthand name. Note that these parts
+ are not consecutively numbered.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>ISO/IEC 9075-1 Framework (SQL/Framework)</p><a id="id-1.11.5.6.2.1.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-2 Foundation (SQL/Foundation)</p><a id="id-1.11.5.6.2.2.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-3 Call Level Interface (SQL/CLI)</p><a id="id-1.11.5.6.2.3.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-4 Persistent Stored Modules (SQL/PSM)</p><a id="id-1.11.5.6.2.4.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-9 Management of External Data (SQL/MED)</p><a id="id-1.11.5.6.2.5.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-10 Object Language Bindings (SQL/OLB)</p><a id="id-1.11.5.6.2.6.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-11 Information and Definition Schemas (SQL/Schemata)</p><a id="id-1.11.5.6.2.7.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-13 Routines and Types using the Java Language (SQL/JRT)</p><a id="id-1.11.5.6.2.8.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-14 XML-related specifications (SQL/XML)</p><a id="id-1.11.5.6.2.9.2" class="indexterm"></a></li><li class="listitem"><p>ISO/IEC 9075-15 Multi-dimensional arrays (SQL/MDA)</p><a id="id-1.11.5.6.2.10.2" class="indexterm"></a></li></ul></div><p>
+ </p><p>
+ The <span class="productname">PostgreSQL</span> core covers parts 1, 2, 9,
+ 11, and 14. Part 3 is covered by the ODBC driver, and part 13 is
+ covered by the PL/Java plug-in, but exact conformance is currently
+ not being verified for these components. There are currently no
+ implementations of parts 4, 10, and 15
+ for <span class="productname">PostgreSQL</span>.
+ </p><p>
+ PostgreSQL supports most of the major features of SQL:2016. Out of
+ 177 mandatory features required for full Core conformance,
+ PostgreSQL conforms to at least 170. In addition, there is a long
+ list of supported optional features. It might be worth noting that at
+ the time of writing, no current version of any database management
+ system claims full conformance to Core SQL:2016.
+ </p><p>
+ In the following two sections, we provide a list of those features
+ that <span class="productname">PostgreSQL</span> supports, followed by a
+ list of the features defined in <acronym class="acronym">SQL:2016</acronym> which
+ are not yet supported in <span class="productname">PostgreSQL</span>.
+ Both of these lists are approximate: There might be minor details that
+ are nonconforming for a feature that is listed as supported, and
+ large parts of an unsupported feature might in fact be implemented.
+ The main body of the documentation always contains the most accurate
+ information about what does and does not work.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Feature codes containing a hyphen are subfeatures. Therefore, if a
+ particular subfeature is not supported, the main feature is listed
+ as unsupported even if some other subfeatures are supported.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="features-sql-standard.html" title="D.1. Supported Features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix C. <acronym class="acronym">SQL</acronym> Key Words </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> D.1. Supported Features</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/file-fdw.html b/doc/src/sgml/html/file-fdw.html
new file mode 100644
index 0000000..d50b0bd
--- /dev/null
+++ b/doc/src/sgml/html/file-fdw.html
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.16. file_fdw</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="earthdistance.html" title="F.15. earthdistance" /><link rel="next" href="fuzzystrmatch.html" title="F.17. fuzzystrmatch" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.16. file_fdw</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="earthdistance.html" title="F.15. earthdistance">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fuzzystrmatch.html" title="F.17. fuzzystrmatch">Next</a></td></tr></table><hr /></div><div class="sect1" id="FILE-FDW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.16. file_fdw</h2></div></div></div><a id="id-1.11.7.25.2" class="indexterm"></a><p>
+ The <code class="filename">file_fdw</code> module provides the foreign-data wrapper
+ <code class="function">file_fdw</code>, which can be used to access data
+ files in the server's file system, or to execute programs on the server
+ and read their output. The data file or program output must be in a format
+ that can be read by <code class="command">COPY FROM</code>;
+ see <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for details.
+ Access to data files is currently read-only.
+ </p><p>
+ A foreign table created using this wrapper can have the following options:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">filename</code></span></dt><dd><p>
+ Specifies the file to be read. Relative paths are relative to the
+ data directory.
+ Either <code class="literal">filename</code> or <code class="literal">program</code> must be
+ specified, but not both.
+ </p></dd><dt><span class="term"><code class="literal">program</code></span></dt><dd><p>
+ Specifies the command to be executed. The standard output of this
+ command will be read as though <code class="command">COPY FROM PROGRAM</code> were used.
+ Either <code class="literal">program</code> or <code class="literal">filename</code> must be
+ specified, but not both.
+ </p></dd><dt><span class="term"><code class="literal">format</code></span></dt><dd><p>
+ Specifies the data format,
+ the same as <code class="command">COPY</code>'s <code class="literal">FORMAT</code> option.
+ </p></dd><dt><span class="term"><code class="literal">header</code></span></dt><dd><p>
+ Specifies whether the data has a header line,
+ the same as <code class="command">COPY</code>'s <code class="literal">HEADER</code> option.
+ </p></dd><dt><span class="term"><code class="literal">delimiter</code></span></dt><dd><p>
+ Specifies the data delimiter character,
+ the same as <code class="command">COPY</code>'s <code class="literal">DELIMITER</code> option.
+ </p></dd><dt><span class="term"><code class="literal">quote</code></span></dt><dd><p>
+ Specifies the data quote character,
+ the same as <code class="command">COPY</code>'s <code class="literal">QUOTE</code> option.
+ </p></dd><dt><span class="term"><code class="literal">escape</code></span></dt><dd><p>
+ Specifies the data escape character,
+ the same as <code class="command">COPY</code>'s <code class="literal">ESCAPE</code> option.
+ </p></dd><dt><span class="term"><code class="literal">null</code></span></dt><dd><p>
+ Specifies the data null string,
+ the same as <code class="command">COPY</code>'s <code class="literal">NULL</code> option.
+ </p></dd><dt><span class="term"><code class="literal">encoding</code></span></dt><dd><p>
+ Specifies the data encoding,
+ the same as <code class="command">COPY</code>'s <code class="literal">ENCODING</code> option.
+ </p></dd></dl></div><p>
+ Note that while <code class="command">COPY</code> allows options such as <code class="literal">HEADER</code>
+ to be specified without a corresponding value, the foreign table option
+ syntax requires a value to be present in all cases. To activate
+ <code class="command">COPY</code> options typically written without a value, you can pass
+ the value TRUE, since all such options are Booleans.
+ </p><p>
+ A column of a foreign table created using this wrapper can have the
+ following options:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">force_not_null</code></span></dt><dd><p>
+ This is a Boolean option. If true, it specifies that values of the
+ column should not be matched against the null string (that is, the
+ table-level <code class="literal">null</code> option). This has the same effect
+ as listing the column in <code class="command">COPY</code>'s
+ <code class="literal">FORCE_NOT_NULL</code> option.
+ </p></dd><dt><span class="term"><code class="literal">force_null</code></span></dt><dd><p>
+ This is a Boolean option. If true, it specifies that values of the
+ column which match the null string are returned as <code class="literal">NULL</code>
+ even if the value is quoted. Without this option, only unquoted
+ values matching the null string are returned as <code class="literal">NULL</code>.
+ This has the same effect as listing the column in
+ <code class="command">COPY</code>'s <code class="literal">FORCE_NULL</code> option.
+ </p></dd></dl></div><p>
+ <code class="command">COPY</code>'s <code class="literal">FORCE_QUOTE</code> option is
+ currently not supported by <code class="literal">file_fdw</code>.
+ </p><p>
+ These options can only be specified for a foreign table or its columns, not
+ in the options of the <code class="literal">file_fdw</code> foreign-data wrapper, nor in the
+ options of a server or user mapping using the wrapper.
+ </p><p>
+ Changing table-level options requires being a superuser or having the privileges
+ of the role <code class="literal">pg_read_server_files</code> (to use a filename) or
+ the role <code class="literal">pg_execute_server_program</code> (to use a program),
+ for security reasons: only certain users should be able to control which file is
+ read or which program is run. In principle regular users could be allowed to
+ change the other options, but that's not supported at present.
+ </p><p>
+ When specifying the <code class="literal">program</code> option, keep in mind that the option
+ string is executed by the shell. If you need to pass any arguments to the
+ command that come from an untrusted source, you must be careful to strip or
+ escape any characters that might have special meaning to the shell.
+ For security reasons, it is best to use a fixed command string, or at least
+ avoid passing any user input in it.
+ </p><p>
+ For a foreign table using <code class="literal">file_fdw</code>, <code class="command">EXPLAIN</code> shows
+ the name of the file to be read or program to be run.
+ For a file, unless <code class="literal">COSTS OFF</code> is
+ specified, the file size (in bytes) is shown as well.
+ </p><div class="example" id="id-1.11.7.25.14"><p class="title"><strong>Example F.1. Create a Foreign Table for PostgreSQL CSV Logs</strong></p><div class="example-contents"><p>
+ One of the obvious uses for <code class="literal">file_fdw</code> is to make
+ the PostgreSQL activity log available as a table for querying. To
+ do this, first you must be <a class="link" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-CSVLOG" title="20.8.4. Using CSV-Format Log Output">logging to a CSV file,</a>
+ which here we
+ will call <code class="literal">pglog.csv</code>. First, install <code class="literal">file_fdw</code>
+ as an extension:
+ </p><pre class="programlisting">
+CREATE EXTENSION file_fdw;
+</pre><p>
+ Then create a foreign server:
+
+</p><pre class="programlisting">
+CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
+</pre><p>
+ </p><p>
+ Now you are ready to create the foreign data table. Using the
+ <code class="command">CREATE FOREIGN TABLE</code> command, you will need to define
+ the columns for the table, the CSV file name, and its format:
+
+</p><pre class="programlisting">
+CREATE FOREIGN TABLE pglog (
+ log_time timestamp(3) with time zone,
+ user_name text,
+ database_name text,
+ process_id integer,
+ connection_from text,
+ session_id text,
+ session_line_num bigint,
+ command_tag text,
+ session_start_time timestamp with time zone,
+ virtual_transaction_id text,
+ transaction_id bigint,
+ error_severity text,
+ sql_state_code text,
+ message text,
+ detail text,
+ hint text,
+ internal_query text,
+ internal_query_pos integer,
+ context text,
+ query text,
+ query_pos integer,
+ location text,
+ application_name text,
+ backend_type text,
+ leader_pid integer,
+ query_id bigint
+) SERVER pglog
+OPTIONS ( filename 'log/pglog.csv', format 'csv' );
+</pre><p>
+ </p><p>
+ That's it — now you can query your log directly. In production, of
+ course, you would need to define some way to deal with log rotation.
+ </p></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="earthdistance.html" title="F.15. earthdistance">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fuzzystrmatch.html" title="F.17. fuzzystrmatch">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.15. earthdistance </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.17. fuzzystrmatch</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-admin.html b/doc/src/sgml/html/functions-admin.html
new file mode 100644
index 0000000..252bf6d
--- /dev/null
+++ b/doc/src/sgml/html/functions-admin.html
@@ -0,0 +1,1648 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.27. System Administration Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-info.html" title="9.26. System Information Functions and Operators" /><link rel="next" href="functions-trigger.html" title="9.28. Trigger Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.27. System Administration Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-info.html" title="9.26. System Information Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-trigger.html" title="9.28. Trigger Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-ADMIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.27. System Administration Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-SET">9.27.1. Configuration Settings Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">9.27.2. Server Signaling Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">9.27.3. Backup Control Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">9.27.4. Recovery Control Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION">9.27.5. Snapshot Synchronization Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-REPLICATION">9.27.6. Replication Management Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">9.27.7. Database Object Management Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-INDEX">9.27.8. Index Maintenance Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">9.27.9. Generic File Access Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">9.27.10. Advisory Lock Functions</a></span></dt></dl></div><p>
+ The functions described in this section are used to control and
+ monitor a <span class="productname">PostgreSQL</span> installation.
+ </p><div class="sect2" id="FUNCTIONS-ADMIN-SET"><div class="titlepage"><div><div><h3 class="title">9.27.1. Configuration Settings Functions</h3></div></div></div><a id="id-1.5.8.33.3.2" class="indexterm"></a><a id="id-1.5.8.33.3.3" class="indexterm"></a><a id="id-1.5.8.33.3.4" class="indexterm"></a><p>
+ <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SET-TABLE" title="Table 9.87. Configuration Settings Functions">Table 9.87</a> shows the functions
+ available to query and alter run-time configuration parameters.
+ </p><div class="table" id="FUNCTIONS-ADMIN-SET-TABLE"><p class="title"><strong>Table 9.87. Configuration Settings Functions</strong></p><div class="table-contents"><table class="table" summary="Configuration Settings Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.3.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">current_setting</code> ( <em class="parameter"><code>setting_name</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>missing_ok</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the current value of the
+ setting <em class="parameter"><code>setting_name</code></em>. If there is no such
+ setting, <code class="function">current_setting</code> throws an error
+ unless <em class="parameter"><code>missing_ok</code></em> is supplied and
+ is <code class="literal">true</code> (in which case NULL is returned).
+ This function corresponds to
+ the <acronym class="acronym">SQL</acronym> command <a class="xref" href="sql-show.html" title="SHOW"><span class="refentrytitle">SHOW</span></a>.
+ </p>
+ <p>
+ <code class="literal">current_setting('datestyle')</code>
+ → <code class="returnvalue">ISO, MDY</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.3.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">set_config</code> (
+ <em class="parameter"><code>setting_name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>new_value</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>is_local</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Sets the parameter <em class="parameter"><code>setting_name</code></em>
+ to <em class="parameter"><code>new_value</code></em>, and returns that value.
+ If <em class="parameter"><code>is_local</code></em> is <code class="literal">true</code>, the new
+ value will only apply during the current transaction. If you want the
+ new value to apply for the rest of the current session,
+ use <code class="literal">false</code> instead. This function corresponds to
+ the SQL command <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a>.
+ </p>
+ <p>
+ <code class="literal">set_config('log_statement_stats', 'off', false)</code>
+ → <code class="returnvalue">off</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="FUNCTIONS-ADMIN-SIGNAL"><div class="titlepage"><div><div><h3 class="title">9.27.2. Server Signaling Functions</h3></div></div></div><a id="id-1.5.8.33.4.2" class="indexterm"></a><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL-TABLE" title="Table 9.88. Server Signaling Functions">Table 9.88</a> send control signals to
+ other server processes. Use of these functions is restricted to
+ superusers by default but access may be granted to others using
+ <code class="command">GRANT</code>, with noted exceptions.
+ </p><p>
+ Each of these functions returns <code class="literal">true</code> if
+ the signal was successfully sent and <code class="literal">false</code>
+ if sending the signal failed.
+ </p><div class="table" id="FUNCTIONS-ADMIN-SIGNAL-TABLE"><p class="title"><strong>Table 9.88. Server Signaling Functions</strong></p><div class="table-contents"><table class="table" summary="Server Signaling Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.4.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_cancel_backend</code> ( <em class="parameter"><code>pid</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Cancels the current query of the session whose backend process has the
+ specified process ID. This is also allowed if the
+ calling role is a member of the role whose backend is being canceled or
+ the calling role has privileges of <code class="literal">pg_signal_backend</code>,
+ however only superusers can cancel superuser backends.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.4.5.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_log_backend_memory_contexts</code> ( <em class="parameter"><code>pid</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Requests to log the memory contexts of the backend with the
+ specified process ID. This function can send the request to
+ backends and auxiliary processes except logger. These memory contexts
+ will be logged at
+ <code class="literal">LOG</code> message level. They will appear in
+ the server log based on the log configuration set
+ (see <a class="xref" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging">Section 20.8</a> for more information),
+ but will not be sent to the client regardless of
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.4.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_reload_conf</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Causes all processes of the <span class="productname">PostgreSQL</span>
+ server to reload their configuration files. (This is initiated by
+ sending a <span class="systemitem">SIGHUP</span> signal to the postmaster
+ process, which in turn sends <span class="systemitem">SIGHUP</span> to each
+ of its children.) You can use the
+ <a class="link" href="view-pg-file-settings.html" title="54.7. pg_file_settings"><code class="structname">pg_file_settings</code></a>,
+ <a class="link" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules"><code class="structname">pg_hba_file_rules</code></a> and
+ <a class="link" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules"><code class="structname">pg_ident_file_mappings</code></a> views
+ to check the configuration files for possible errors, before reloading.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.4.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_rotate_logfile</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Signals the log-file manager to switch to a new output file
+ immediately. This works only when the built-in log collector is
+ running, since otherwise there is no log-file manager subprocess.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.4.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_terminate_backend</code> ( <em class="parameter"><code>pid</code></em> <code class="type">integer</code>, <em class="parameter"><code>timeout</code></em> <code class="type">bigint</code> <code class="literal">DEFAULT</code> <code class="literal">0</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Terminates the session whose backend process has the
+ specified process ID. This is also allowed if the calling role
+ is a member of the role whose backend is being terminated or the
+ calling role has privileges of <code class="literal">pg_signal_backend</code>,
+ however only superusers can terminate superuser backends.
+ </p>
+ <p>
+ If <em class="parameter"><code>timeout</code></em> is not specified or zero, this
+ function returns <code class="literal">true</code> whether the process actually
+ terminates or not, indicating only that the sending of the signal was
+ successful. If the <em class="parameter"><code>timeout</code></em> is specified (in
+ milliseconds) and greater than zero, the function waits until the
+ process is actually terminated or until the given time has passed. If
+ the process is terminated, the function
+ returns <code class="literal">true</code>. On timeout, a warning is emitted and
+ <code class="literal">false</code> is returned.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="function">pg_cancel_backend</code> and <code class="function">pg_terminate_backend</code>
+ send signals (<span class="systemitem">SIGINT</span> or <span class="systemitem">SIGTERM</span>
+ respectively) to backend processes identified by process ID.
+ The process ID of an active backend can be found from
+ the <code class="structfield">pid</code> column of the
+ <code class="structname">pg_stat_activity</code> view, or by listing the
+ <code class="command">postgres</code> processes on the server (using
+ <span class="application">ps</span> on Unix or the <span class="application">Task
+ Manager</span> on <span class="productname">Windows</span>).
+ The role of an active backend can be found from the
+ <code class="structfield">usename</code> column of the
+ <code class="structname">pg_stat_activity</code> view.
+ </p><p>
+ <code class="function">pg_log_backend_memory_contexts</code> can be used
+ to log the memory contexts of a backend process. For example:
+</p><pre class="programlisting">
+postgres=# SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+ pg_log_backend_memory_contexts
+--------------------------------
+ t
+(1 row)
+</pre><p>
+One message for each memory context will be logged. For example:
+</p><pre class="screen">
+LOG: logging memory contexts of PID 10377
+STATEMENT: SELECT pg_log_backend_memory_contexts(pg_backend_pid());
+LOG: level: 0; TopMemoryContext: 80800 total in 6 blocks; 14432 free (5 chunks); 66368 used
+LOG: level: 1; pgstat TabStatusArray lookup hash table: 8192 total in 1 blocks; 1408 free (0 chunks); 6784 used
+LOG: level: 1; TopTransactionContext: 8192 total in 1 blocks; 7720 free (1 chunks); 472 used
+LOG: level: 1; RowDescriptionContext: 8192 total in 1 blocks; 6880 free (0 chunks); 1312 used
+LOG: level: 1; MessageContext: 16384 total in 2 blocks; 5152 free (0 chunks); 11232 used
+LOG: level: 1; Operator class cache: 8192 total in 1 blocks; 512 free (0 chunks); 7680 used
+LOG: level: 1; smgr relation table: 16384 total in 2 blocks; 4544 free (3 chunks); 11840 used
+LOG: level: 1; TransactionAbortContext: 32768 total in 1 blocks; 32504 free (0 chunks); 264 used
+...
+LOG: level: 1; ErrorContext: 8192 total in 1 blocks; 7928 free (3 chunks); 264 used
+LOG: Grand total: 1651920 bytes in 201 blocks; 622360 free (88 chunks); 1029560 used
+</pre><p>
+ If there are more than 100 child contexts under the same parent, the first
+ 100 child contexts are logged, along with a summary of the remaining contexts.
+ Note that frequent calls to this function could incur significant overhead,
+ because it may generate a large number of log messages.
+ </p></div><div class="sect2" id="FUNCTIONS-ADMIN-BACKUP"><div class="titlepage"><div><div><h3 class="title">9.27.3. Backup Control Functions</h3></div></div></div><a id="id-1.5.8.33.5.2" class="indexterm"></a><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP-TABLE" title="Table 9.89. Backup Control Functions">Table 9.89</a> assist in making on-line backups.
+ These functions cannot be executed during recovery (except
+ <code class="function">pg_backup_start</code>,
+ <code class="function">pg_backup_stop</code>,
+ and <code class="function">pg_wal_lsn_diff</code>).
+ </p><p>
+ For details about proper usage of these functions, see
+ <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>.
+ </p><div class="table" id="FUNCTIONS-ADMIN-BACKUP-TABLE"><p class="title"><strong>Table 9.89. Backup Control Functions</strong></p><div class="table-contents"><table class="table" summary="Backup Control Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_create_restore_point</code> ( <em class="parameter"><code>name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Creates a named marker record in the write-ahead log that can later be
+ used as a recovery target, and returns the corresponding write-ahead
+ log location. The given name can then be used with
+ <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-NAME">recovery_target_name</a> to specify the point up to
+ which recovery will proceed. Avoid creating multiple restore points
+ with the same name, since recovery will stop at the first one whose
+ name matches the recovery target.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_current_wal_flush_lsn</code> ()
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the current write-ahead log flush location (see notes below).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_current_wal_insert_lsn</code> ()
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the current write-ahead log insert location (see notes below).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_current_wal_lsn</code> ()
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the current write-ahead log write location (see notes below).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_backup_start</code> (
+ <em class="parameter"><code>label</code></em> <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>fast</code></em> <code class="type">boolean</code>
+ </span>] )
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Prepares the server to begin an on-line backup. The only required
+ parameter is an arbitrary user-defined label for the backup.
+ (Typically this would be the name under which the backup dump file
+ will be stored.)
+ If the optional second parameter is given as <code class="literal">true</code>,
+ it specifies executing <code class="function">pg_backup_start</code> as quickly
+ as possible. This forces an immediate checkpoint which will cause a
+ spike in I/O operations, slowing any concurrently executing queries.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_backup_stop</code> (
+ [<span class="optional"><em class="parameter"><code>wait_for_archive</code></em> <code class="type">boolean</code>
+ </span>] )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code>,
+ <em class="parameter"><code>labelfile</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>spcmapfile</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Finishes performing an on-line backup. The desired contents of the
+ backup label file and the tablespace map file are returned as part of
+ the result of the function and must be written to files in the
+ backup area. These files must not be written to the live data directory
+ (doing so will cause PostgreSQL to fail to restart in the event of a
+ crash).
+ </p>
+ <p>
+ There is an optional parameter of type <code class="type">boolean</code>.
+ If false, the function will return immediately after the backup is
+ completed, without waiting for WAL to be archived. This behavior is
+ only useful with backup software that independently monitors WAL
+ archiving. Otherwise, WAL required to make the backup consistent might
+ be missing and make the backup useless. By default or when this
+ parameter is true, <code class="function">pg_backup_stop</code> will wait for
+ WAL to be archived when archiving is enabled. (On a standby, this
+ means that it will wait only when <code class="varname">archive_mode</code> =
+ <code class="literal">always</code>. If write activity on the primary is low,
+ it may be useful to run <code class="function">pg_switch_wal</code> on the
+ primary in order to trigger an immediate segment switch.)
+ </p>
+ <p>
+ When executed on a primary, this function also creates a backup
+ history file in the write-ahead log archive area. The history file
+ includes the label given to <code class="function">pg_backup_start</code>, the
+ starting and ending write-ahead log locations for the backup, and the
+ starting and ending times of the backup. After recording the ending
+ location, the current write-ahead log insertion point is automatically
+ advanced to the next write-ahead log file, so that the ending
+ write-ahead log file can be archived immediately to complete the
+ backup.
+ </p>
+ <p>
+ The result of the function is a single record.
+ The <em class="parameter"><code>lsn</code></em> column holds the backup's ending
+ write-ahead log location (which again can be ignored). The second
+ column returns the contents of the backup label file, and the third
+ column returns the contents of the tablespace map file. These must be
+ stored as part of the backup and are required as part of the restore
+ process.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_switch_wal</code> ()
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Forces the server to switch to a new write-ahead log file, which
+ allows the current file to be archived (assuming you are using
+ continuous archiving). The result is the ending write-ahead log
+ location plus 1 within the just-completed write-ahead log file. If
+ there has been no write-ahead log activity since the last write-ahead
+ log switch, <code class="function">pg_switch_wal</code> does nothing and
+ returns the start location of the write-ahead log file currently in
+ use.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_walfile_name</code> ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts a write-ahead log location to the name of the WAL file
+ holding that location.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_walfile_name_offset</code> ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>file_name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>file_offset</code></em> <code class="type">integer</code> )
+ </p>
+ <p>
+ Converts a write-ahead log location to a WAL file name and byte offset
+ within that file.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.5.5.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_wal_lsn_diff</code> ( <em class="parameter"><code>lsn1</code></em> <code class="type">pg_lsn</code>, <em class="parameter"><code>lsn2</code></em> <code class="type">pg_lsn</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Calculates the difference in bytes (<em class="parameter"><code>lsn1</code></em> - <em class="parameter"><code>lsn2</code></em>) between two write-ahead log
+ locations. This can be used
+ with <code class="structname">pg_stat_replication</code> or some of the
+ functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP-TABLE" title="Table 9.89. Backup Control Functions">Table 9.89</a> to
+ get the replication lag.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="function">pg_current_wal_lsn</code> displays the current write-ahead
+ log write location in the same format used by the above functions.
+ Similarly, <code class="function">pg_current_wal_insert_lsn</code> displays the
+ current write-ahead log insertion location
+ and <code class="function">pg_current_wal_flush_lsn</code> displays the current
+ write-ahead log flush location. The insertion location is
+ the <span class="quote">“<span class="quote">logical</span>”</span> end of the write-ahead log at any instant,
+ while the write location is the end of what has actually been written out
+ from the server's internal buffers, and the flush location is the last
+ location known to be written to durable storage. The write location is the
+ end of what can be examined from outside the server, and is usually what
+ you want if you are interested in archiving partially-complete write-ahead
+ log files. The insertion and flush locations are made available primarily
+ for server debugging purposes. These are all read-only operations and do
+ not require superuser permissions.
+ </p><p>
+ You can use <code class="function">pg_walfile_name_offset</code> to extract the
+ corresponding write-ahead log file name and byte offset from
+ a <code class="type">pg_lsn</code> value. For example:
+</p><pre class="programlisting">
+postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn);
+ file_name | file_offset
+--------------------------+-------------
+ 00000001000000000000000D | 4039624
+(1 row)
+</pre><p>
+ Similarly, <code class="function">pg_walfile_name</code> extracts just the write-ahead log file name.
+ When the given write-ahead log location is exactly at a write-ahead log file boundary, both
+ these functions return the name of the preceding write-ahead log file.
+ This is usually the desired behavior for managing write-ahead log archiving
+ behavior, since the preceding file is the last one that currently
+ needs to be archived.
+ </p></div><div class="sect2" id="FUNCTIONS-RECOVERY-CONTROL"><div class="titlepage"><div><div><h3 class="title">9.27.4. Recovery Control Functions</h3></div></div></div><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-RECOVERY-INFO-TABLE" title="Table 9.90. Recovery Information Functions">Table 9.90</a> provide information
+ about the current status of a standby server.
+ These functions may be executed both during recovery and in normal running.
+ </p><div class="table" id="FUNCTIONS-RECOVERY-INFO-TABLE"><p class="title"><strong>Table 9.90. Recovery Information Functions</strong></p><div class="table-contents"><table class="table" summary="Recovery Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_is_in_recovery</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if recovery is still in progress.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_last_wal_receive_lsn</code> ()
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the last write-ahead log location that has been received and
+ synced to disk by streaming replication. While streaming replication
+ is in progress this will increase monotonically. If recovery has
+ completed then this will remain static at the location of the last WAL
+ record received and synced to disk during recovery. If streaming
+ replication is disabled, or if it has not yet started, the function
+ returns <code class="literal">NULL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_last_wal_replay_lsn</code> ()
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the last write-ahead log location that has been replayed
+ during recovery. If recovery is still in progress this will increase
+ monotonically. If recovery has completed then this will remain
+ static at the location of the last WAL record applied during recovery.
+ When the server has been started normally without recovery, the
+ function returns <code class="literal">NULL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.3.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_last_xact_replay_timestamp</code> ()
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the time stamp of the last transaction replayed during
+ recovery. This is the time at which the commit or abort WAL record
+ for that transaction was generated on the primary. If no transactions
+ have been replayed during recovery, the function
+ returns <code class="literal">NULL</code>. Otherwise, if recovery is still in
+ progress this will increase monotonically. If recovery has completed
+ then this will remain static at the time of the last transaction
+ applied during recovery. When the server has been started normally
+ without recovery, the function returns <code class="literal">NULL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.3.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_wal_resource_managers</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>rm_id</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>rm_name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>rm_builtin</code></em> <code class="type">boolean</code> )
+ </p>
+ <p>
+ Returns the currently-loaded WAL resource managers in the system. The
+ column <em class="parameter"><code>rm_builtin</code></em> indicates whether it's a
+ built-in resource manager, or a custom resource manager loaded by an
+ extension.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL-TABLE" title="Table 9.91. Recovery Control Functions">Table 9.91</a> control the progress of recovery.
+ These functions may be executed only during recovery.
+ </p><div class="table" id="FUNCTIONS-RECOVERY-CONTROL-TABLE"><p class="title"><strong>Table 9.91. Recovery Control Functions</strong></p><div class="table-contents"><table class="table" summary="Recovery Control Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_is_wal_replay_paused</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if recovery pause is requested.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.5.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_wal_replay_pause_state</code> ()
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns recovery pause state. The return values are <code class="literal">
+ not paused</code> if pause is not requested, <code class="literal">
+ pause requested</code> if pause is requested but recovery is
+ not yet paused, and <code class="literal">paused</code> if the recovery is
+ actually paused.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_promote</code> ( <em class="parameter"><code>wait</code></em> <code class="type">boolean</code> <code class="literal">DEFAULT</code> <code class="literal">true</code>, <em class="parameter"><code>wait_seconds</code></em> <code class="type">integer</code> <code class="literal">DEFAULT</code> <code class="literal">60</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Promotes a standby server to primary status.
+ With <em class="parameter"><code>wait</code></em> set to <code class="literal">true</code> (the
+ default), the function waits until promotion is completed
+ or <em class="parameter"><code>wait_seconds</code></em> seconds have passed, and
+ returns <code class="literal">true</code> if promotion is successful
+ and <code class="literal">false</code> otherwise.
+ If <em class="parameter"><code>wait</code></em> is set to <code class="literal">false</code>, the
+ function returns <code class="literal">true</code> immediately after sending a
+ <code class="literal">SIGUSR1</code> signal to the postmaster to trigger
+ promotion.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_wal_replay_pause</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Request to pause recovery. A request doesn't mean that recovery stops
+ right away. If you want a guarantee that recovery is actually paused,
+ you need to check for the recovery pause state returned by
+ <code class="function">pg_get_wal_replay_pause_state()</code>. Note that
+ <code class="function">pg_is_wal_replay_paused()</code> returns whether a request
+ is made. While recovery is paused, no further database changes are applied.
+ If hot standby is active, all new queries will see the same consistent
+ snapshot of the database, and no further query conflicts will be generated
+ until recovery is resumed.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.6.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_wal_replay_resume</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Restarts recovery if it was paused.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="function">pg_wal_replay_pause</code> and
+ <code class="function">pg_wal_replay_resume</code> cannot be executed while
+ a promotion is ongoing. If a promotion is triggered while recovery
+ is paused, the paused state ends and promotion continues.
+ </p><p>
+ If streaming replication is disabled, the paused state may continue
+ indefinitely without a problem. If streaming replication is in
+ progress then WAL records will continue to be received, which will
+ eventually fill available disk space, depending upon the duration of
+ the pause, the rate of WAL generation and available disk space.
+ </p></div><div class="sect2" id="FUNCTIONS-SNAPSHOT-SYNCHRONIZATION"><div class="titlepage"><div><div><h3 class="title">9.27.5. Snapshot Synchronization Functions</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> allows database sessions to synchronize their
+ snapshots. A <em class="firstterm">snapshot</em> determines which data is visible to the
+ transaction that is using the snapshot. Synchronized snapshots are
+ necessary when two or more sessions need to see identical content in the
+ database. If two sessions just start their transactions independently,
+ there is always a possibility that some third transaction commits
+ between the executions of the two <code class="command">START TRANSACTION</code> commands,
+ so that one session sees the effects of that transaction and the other
+ does not.
+ </p><p>
+ To solve this problem, <span class="productname">PostgreSQL</span> allows a transaction to
+ <em class="firstterm">export</em> the snapshot it is using. As long as the exporting
+ transaction remains open, other transactions can <em class="firstterm">import</em> its
+ snapshot, and thereby be guaranteed that they see exactly the same view
+ of the database that the first transaction sees. But note that any
+ database changes made by any one of these transactions remain invisible
+ to the other transactions, as is usual for changes made by uncommitted
+ transactions. So the transactions are synchronized with respect to
+ pre-existing data, but act normally for changes they make themselves.
+ </p><p>
+ Snapshots are exported with the <code class="function">pg_export_snapshot</code> function,
+ shown in <a class="xref" href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION-TABLE" title="Table 9.92. Snapshot Synchronization Functions">Table 9.92</a>, and
+ imported with the <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> command.
+ </p><div class="table" id="FUNCTIONS-SNAPSHOT-SYNCHRONIZATION-TABLE"><p class="title"><strong>Table 9.92. Snapshot Synchronization Functions</strong></p><div class="table-contents"><table class="table" summary="Snapshot Synchronization Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.7.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_export_snapshot</code> ()
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Saves the transaction's current snapshot and returns
+ a <code class="type">text</code> string identifying the snapshot. This string must
+ be passed (outside the database) to clients that want to import the
+ snapshot. The snapshot is available for import only until the end of
+ the transaction that exported it.
+ </p>
+ <p>
+ A transaction can export more than one snapshot, if needed. Note that
+ doing so is only useful in <code class="literal">READ COMMITTED</code>
+ transactions, since in <code class="literal">REPEATABLE READ</code> and higher
+ isolation levels, transactions use the same snapshot throughout their
+ lifetime. Once a transaction has exported any snapshots, it cannot be
+ prepared with <a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="FUNCTIONS-REPLICATION"><div class="titlepage"><div><div><h3 class="title">9.27.6. Replication Management Functions</h3></div></div></div><p>
+ The functions shown
+ in <a class="xref" href="functions-admin.html#FUNCTIONS-REPLICATION-TABLE" title="Table 9.93. Replication Management Functions">Table 9.93</a> are for
+ controlling and interacting with replication features.
+ See <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>,
+ <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a>, and
+ <a class="xref" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Chapter 50</a>
+ for information about the underlying features.
+ Use of functions for replication origin is only allowed to the
+ superuser by default, but may be allowed to other users by using the
+ <code class="literal">GRANT</code> command.
+ Use of functions for replication slots is restricted to superusers
+ and users having <code class="literal">REPLICATION</code> privilege.
+ </p><p>
+ Many of these functions have equivalent commands in the replication
+ protocol; see <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>.
+ </p><p>
+ The functions described in
+ <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP" title="9.27.3. Backup Control Functions">Section 9.27.3</a>,
+ <a class="xref" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL" title="9.27.4. Recovery Control Functions">Section 9.27.4</a>, and
+ <a class="xref" href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION" title="9.27.5. Snapshot Synchronization Functions">Section 9.27.5</a>
+ are also relevant for replication.
+ </p><div class="table" id="FUNCTIONS-REPLICATION-TABLE"><p class="title"><strong>Table 9.93. Replication Management Functions</strong></p><div class="table-contents"><table class="table" summary="Replication Management Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_create_physical_replication_slot</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code> [<span class="optional">, <em class="parameter"><code>immediately_reserve</code></em> <code class="type">boolean</code>, <em class="parameter"><code>temporary</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>,
+ <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ </p>
+ <p>
+ Creates a new physical replication slot named
+ <em class="parameter"><code>slot_name</code></em>. The optional second parameter,
+ when <code class="literal">true</code>, specifies that the <acronym class="acronym">LSN</acronym> for this
+ replication slot be reserved immediately; otherwise
+ the <acronym class="acronym">LSN</acronym> is reserved on first connection from a streaming
+ replication client. Streaming changes from a physical slot is only
+ possible with the streaming-replication protocol —
+ see <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>. The optional third
+ parameter, <em class="parameter"><code>temporary</code></em>, when set to true, specifies that
+ the slot should not be permanently stored to disk and is only meant
+ for use by the current session. Temporary slots are also
+ released upon any error. This function corresponds
+ to the replication protocol command <code class="literal">CREATE_REPLICATION_SLOT
+ ... PHYSICAL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_drop_replication_slot</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Drops the physical or logical replication slot
+ named <em class="parameter"><code>slot_name</code></em>. Same as replication protocol
+ command <code class="literal">DROP_REPLICATION_SLOT</code>. For logical slots, this must
+ be called while connected to the same database the slot was created on.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_create_logical_replication_slot</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>plugin</code></em> <code class="type">name</code> [<span class="optional">, <em class="parameter"><code>temporary</code></em> <code class="type">boolean</code>, <em class="parameter"><code>twophase</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>,
+ <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ </p>
+ <p>
+ Creates a new logical (decoding) replication slot named
+ <em class="parameter"><code>slot_name</code></em> using the output plugin
+ <em class="parameter"><code>plugin</code></em>. The optional third
+ parameter, <em class="parameter"><code>temporary</code></em>, when set to true, specifies that
+ the slot should not be permanently stored to disk and is only meant
+ for use by the current session. Temporary slots are also
+ released upon any error. The optional fourth parameter,
+ <em class="parameter"><code>twophase</code></em>, when set to true, specifies
+ that the decoding of prepared transactions is enabled for this
+ slot. A call to this function has the same effect as the replication
+ protocol command <code class="literal">CREATE_REPLICATION_SLOT ... LOGICAL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_copy_physical_replication_slot</code> ( <em class="parameter"><code>src_slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>dst_slot_name</code></em> <code class="type">name</code> [<span class="optional">, <em class="parameter"><code>temporary</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>,
+ <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ </p>
+ <p>
+ Copies an existing physical replication slot named <em class="parameter"><code>src_slot_name</code></em>
+ to a physical replication slot named <em class="parameter"><code>dst_slot_name</code></em>.
+ The copied physical slot starts to reserve WAL from the same <acronym class="acronym">LSN</acronym> as the
+ source slot.
+ <em class="parameter"><code>temporary</code></em> is optional. If <em class="parameter"><code>temporary</code></em>
+ is omitted, the same value as the source slot is used.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_copy_logical_replication_slot</code> ( <em class="parameter"><code>src_slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>dst_slot_name</code></em> <code class="type">name</code> [<span class="optional">, <em class="parameter"><code>temporary</code></em> <code class="type">boolean</code> [<span class="optional">, <em class="parameter"><code>plugin</code></em> <code class="type">name</code> </span>]</span>] )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>,
+ <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ </p>
+ <p>
+ Copies an existing logical replication slot
+ named <em class="parameter"><code>src_slot_name</code></em> to a logical replication
+ slot named <em class="parameter"><code>dst_slot_name</code></em>, optionally changing
+ the output plugin and persistence. The copied logical slot starts
+ from the same <acronym class="acronym">LSN</acronym> as the source logical slot. Both
+ <em class="parameter"><code>temporary</code></em> and <em class="parameter"><code>plugin</code></em> are
+ optional; if they are omitted, the values of the source slot are used.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_logical_slot_get_changes</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>upto_lsn</code></em> <code class="type">pg_lsn</code>, <em class="parameter"><code>upto_nchanges</code></em> <code class="type">integer</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>options</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code>,
+ <em class="parameter"><code>xid</code></em> <code class="type">xid</code>,
+ <em class="parameter"><code>data</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Returns changes in the slot <em class="parameter"><code>slot_name</code></em>, starting
+ from the point from which changes have been consumed last. If
+ <em class="parameter"><code>upto_lsn</code></em>
+ and <em class="parameter"><code>upto_nchanges</code></em> are NULL,
+ logical decoding will continue until end of WAL. If
+ <em class="parameter"><code>upto_lsn</code></em> is non-NULL, decoding will include only
+ those transactions which commit prior to the specified LSN. If
+ <em class="parameter"><code>upto_nchanges</code></em> is non-NULL, decoding will
+ stop when the number of rows produced by decoding exceeds
+ the specified value. Note, however, that the actual number of
+ rows returned may be larger, since this limit is only checked after
+ adding the rows produced when decoding each new transaction commit.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_logical_slot_peek_changes</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>upto_lsn</code></em> <code class="type">pg_lsn</code>, <em class="parameter"><code>upto_nchanges</code></em> <code class="type">integer</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>options</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code>,
+ <em class="parameter"><code>xid</code></em> <code class="type">xid</code>,
+ <em class="parameter"><code>data</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Behaves just like
+ the <code class="function">pg_logical_slot_get_changes()</code> function,
+ except that changes are not consumed; that is, they will be returned
+ again on future calls.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_logical_slot_get_binary_changes</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>upto_lsn</code></em> <code class="type">pg_lsn</code>, <em class="parameter"><code>upto_nchanges</code></em> <code class="type">integer</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>options</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code>,
+ <em class="parameter"><code>xid</code></em> <code class="type">xid</code>,
+ <em class="parameter"><code>data</code></em> <code class="type">bytea</code> )
+ </p>
+ <p>
+ Behaves just like
+ the <code class="function">pg_logical_slot_get_changes()</code> function,
+ except that changes are returned as <code class="type">bytea</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_logical_slot_peek_binary_changes</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>upto_lsn</code></em> <code class="type">pg_lsn</code>, <em class="parameter"><code>upto_nchanges</code></em> <code class="type">integer</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>options</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code>,
+ <em class="parameter"><code>xid</code></em> <code class="type">xid</code>,
+ <em class="parameter"><code>data</code></em> <code class="type">bytea</code> )
+ </p>
+ <p>
+ Behaves just like
+ the <code class="function">pg_logical_slot_peek_changes()</code> function,
+ except that changes are returned as <code class="type">bytea</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_slot_advance</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>, <em class="parameter"><code>upto_lsn</code></em> <code class="type">pg_lsn</code> )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>slot_name</code></em> <code class="type">name</code>,
+ <em class="parameter"><code>end_lsn</code></em> <code class="type">pg_lsn</code> )
+ </p>
+ <p>
+ Advances the current confirmed position of a replication slot named
+ <em class="parameter"><code>slot_name</code></em>. The slot will not be moved backwards,
+ and it will not be moved beyond the current insert location. Returns
+ the name of the slot and the actual position that it was advanced to.
+ The updated slot position information is written out at the next
+ checkpoint if any advancing is done. So in the event of a crash, the
+ slot may return to an earlier position.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-CREATE" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_create</code> ( <em class="parameter"><code>node_name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Creates a replication origin with the given external
+ name, and returns the internal ID assigned to it.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-DROP" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_drop</code> ( <em class="parameter"><code>node_name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Deletes a previously-created replication origin, including any
+ associated replay progress.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_oid</code> ( <em class="parameter"><code>node_name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Looks up a replication origin by name and returns the internal ID. If
+ no such replication origin is found, <code class="literal">NULL</code> is
+ returned.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-SESSION-SETUP" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_session_setup</code> ( <em class="parameter"><code>node_name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Marks the current session as replaying from the given
+ origin, allowing replay progress to be tracked.
+ Can only be used if no origin is currently selected.
+ Use <code class="function">pg_replication_origin_session_reset</code> to undo.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_session_reset</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Cancels the effects
+ of <code class="function">pg_replication_origin_session_setup()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_session_is_setup</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if a replication origin has been selected in the
+ current session.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-SESSION-PROGRESS" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_session_progress</code> ( <em class="parameter"><code>flush</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the replay location for the replication origin selected in
+ the current session. The parameter <em class="parameter"><code>flush</code></em>
+ determines whether the corresponding local transaction will be
+ guaranteed to have been flushed to disk or not.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-XACT-SETUP" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_xact_setup</code> ( <em class="parameter"><code>origin_lsn</code></em> <code class="type">pg_lsn</code>, <em class="parameter"><code>origin_timestamp</code></em> <code class="type">timestamp with time zone</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Marks the current transaction as replaying a transaction that has
+ committed at the given <acronym class="acronym">LSN</acronym> and timestamp. Can
+ only be called when a replication origin has been selected
+ using <code class="function">pg_replication_origin_session_setup</code>.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-XACT-RESET" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_xact_reset</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Cancels the effects of
+ <code class="function">pg_replication_origin_xact_setup()</code>.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-ADVANCE" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.20.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_advance</code> ( <em class="parameter"><code>node_name</code></em> <code class="type">text</code>, <em class="parameter"><code>lsn</code></em> <code class="type">pg_lsn</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Sets replication progress for the given node to the given
+ location. This is primarily useful for setting up the initial
+ location, or setting a new location after configuration changes and
+ similar. Be aware that careless use of this function can lead to
+ inconsistently replicated data.
+ </p></td></tr><tr><td id="PG-REPLICATION-ORIGIN-PROGRESS" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">pg_replication_origin_progress</code> ( <em class="parameter"><code>node_name</code></em> <code class="type">text</code>, <em class="parameter"><code>flush</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Returns the replay location for the given replication origin. The
+ parameter <em class="parameter"><code>flush</code></em> determines whether the
+ corresponding local transaction will be guaranteed to have been
+ flushed to disk or not.
+ </p></td></tr><tr><td id="PG-LOGICAL-EMIT-MESSAGE" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.8.5.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">pg_logical_emit_message</code> ( <em class="parameter"><code>transactional</code></em> <code class="type">boolean</code>, <em class="parameter"><code>prefix</code></em> <code class="type">text</code>, <em class="parameter"><code>content</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_logical_emit_message</code> ( <em class="parameter"><code>transactional</code></em> <code class="type">boolean</code>, <em class="parameter"><code>prefix</code></em> <code class="type">text</code>, <em class="parameter"><code>content</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">pg_lsn</code>
+ </p>
+ <p>
+ Emits a logical decoding message. This can be used to pass generic
+ messages to logical decoding plugins through
+ WAL. The <em class="parameter"><code>transactional</code></em> parameter specifies if
+ the message should be part of the current transaction, or if it should
+ be written immediately and decoded as soon as the logical decoder
+ reads the record. The <em class="parameter"><code>prefix</code></em> parameter is a
+ textual prefix that can be used by logical decoding plugins to easily
+ recognize messages that are interesting for them.
+ The <em class="parameter"><code>content</code></em> parameter is the content of the
+ message, given either in text or binary form.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="FUNCTIONS-ADMIN-DBOBJECT"><div class="titlepage"><div><div><h3 class="title">9.27.7. Database Object Management Functions</h3></div></div></div><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-DBSIZE" title="Table 9.94. Database Object Size Functions">Table 9.94</a> calculate
+ the disk space usage of database objects, or assist in presentation
+ or understanding of usage results. <code class="literal">bigint</code> results
+ are measured in bytes. If an OID that does
+ not represent an existing object is passed to one of these
+ functions, <code class="literal">NULL</code> is returned.
+ </p><div class="table" id="FUNCTIONS-ADMIN-DBSIZE"><p class="title"><strong>Table 9.94. Database Object Size Functions</strong></p><div class="table-contents"><table class="table" summary="Database Object Size Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_column_size</code> ( <code class="type">"any"</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Shows the number of bytes used to store any individual data value. If
+ applied directly to a table column value, this reflects any
+ compression that was done.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_column_compression</code> ( <code class="type">"any"</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Shows the compression algorithm that was used to compress
+ an individual variable-length value. Returns <code class="literal">NULL</code>
+ if the value is not compressed.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_database_size</code> ( <code class="type">name</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_database_size</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the total disk space used by the database with the specified
+ name or OID. To use this function, you must
+ have <code class="literal">CONNECT</code> privilege on the specified database
+ (which is granted by default) or have privileges of
+ the <code class="literal">pg_read_all_stats</code> role.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_indexes_size</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the total disk space used by indexes attached to the
+ specified table.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_relation_size</code> ( <em class="parameter"><code>relation</code></em> <code class="type">regclass</code> [<span class="optional">, <em class="parameter"><code>fork</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the disk space used by one <span class="quote">“<span class="quote">fork</span>”</span> of the
+ specified relation. (Note that for most purposes it is more
+ convenient to use the higher-level
+ functions <code class="function">pg_total_relation_size</code>
+ or <code class="function">pg_table_size</code>, which sum the sizes of all
+ forks.) With one argument, this returns the size of the main data
+ fork of the relation. The second argument can be provided to specify
+ which fork to examine:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">main</code> returns the size of the main
+ data fork of the relation.
+ </p></li><li class="listitem"><p>
+ <code class="literal">fsm</code> returns the size of the Free Space Map
+ (see <a class="xref" href="storage-fsm.html" title="73.3. Free Space Map">Section 73.3</a>) associated with the relation.
+ </p></li><li class="listitem"><p>
+ <code class="literal">vm</code> returns the size of the Visibility Map
+ (see <a class="xref" href="storage-vm.html" title="73.4. Visibility Map">Section 73.4</a>) associated with the relation.
+ </p></li><li class="listitem"><p>
+ <code class="literal">init</code> returns the size of the initialization
+ fork, if any, associated with the relation.
+ </p></li></ul></div><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_size_bytes</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Converts a size in human-readable format (as returned
+ by <code class="function">pg_size_pretty</code>) into bytes.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_size_pretty</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_size_pretty</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts a size in bytes into a more easily human-readable format with
+ size units (bytes, kB, MB, GB, TB, or PB as appropriate). Note that the
+ units are powers of 2 rather than powers of 10, so 1kB is 1024 bytes,
+ 1MB is 1024<sup>2</sup> = 1048576 bytes, and so on.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_table_size</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the disk space used by the specified table, excluding indexes
+ (but including its TOAST table if any, free space map, and visibility
+ map).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_tablespace_size</code> ( <code class="type">name</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_tablespace_size</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the total disk space used in the tablespace with the
+ specified name or OID. To use this function, you must
+ have <code class="literal">CREATE</code> privilege on the specified tablespace
+ or have privileges of the <code class="literal">pg_read_all_stats</code> role,
+ unless it is the default tablespace for the current database.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.3.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_total_relation_size</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the total disk space used by the specified table, including
+ all indexes and <acronym class="acronym">TOAST</acronym> data. The result is
+ equivalent to <code class="function">pg_table_size</code>
+ <code class="literal">+</code> <code class="function">pg_indexes_size</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The functions above that operate on tables or indexes accept a
+ <code class="type">regclass</code> argument, which is simply the OID of the table or index
+ in the <code class="structname">pg_class</code> system catalog. You do not have to look up
+ the OID by hand, however, since the <code class="type">regclass</code> data type's input
+ converter will do the work for you. See <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>
+ for details.
+ </p><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-DBLOCATION" title="Table 9.95. Database Object Location Functions">Table 9.95</a> assist
+ in identifying the specific disk files associated with database objects.
+ </p><div class="table" id="FUNCTIONS-ADMIN-DBLOCATION"><p class="title"><strong>Table 9.95. Database Object Location Functions</strong></p><div class="table-contents"><table class="table" summary="Database Object Location Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_relation_filenode</code> ( <em class="parameter"><code>relation</code></em> <code class="type">regclass</code> )
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Returns the <span class="quote">“<span class="quote">filenode</span>”</span> number currently assigned to the
+ specified relation. The filenode is the base component of the file
+ name(s) used for the relation (see
+ <a class="xref" href="storage-file-layout.html" title="73.1. Database File Layout">Section 73.1</a> for more information).
+ For most relations the result is the same as
+ <code class="structname">pg_class</code>.<code class="structfield">relfilenode</code>,
+ but for certain system catalogs <code class="structfield">relfilenode</code>
+ is zero and this function must be used to get the correct value. The
+ function returns NULL if passed a relation that does not have storage,
+ such as a view.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_relation_filepath</code> ( <em class="parameter"><code>relation</code></em> <code class="type">regclass</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the entire file path name (relative to the database cluster's
+ data directory, <code class="varname">PGDATA</code>) of the relation.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.6.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_filenode_relation</code> ( <em class="parameter"><code>tablespace</code></em> <code class="type">oid</code>, <em class="parameter"><code>filenode</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">regclass</code>
+ </p>
+ <p>
+ Returns a relation's OID given the tablespace OID and filenode it is
+ stored under. This is essentially the inverse mapping of
+ <code class="function">pg_relation_filepath</code>. For a relation in the
+ database's default tablespace, the tablespace can be specified as zero.
+ Returns <code class="literal">NULL</code> if no relation in the current database
+ is associated with the given values.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-COLLATION" title="Table 9.96. Collation Management Functions">Table 9.96</a> lists functions used to manage
+ collations.
+ </p><div class="table" id="FUNCTIONS-ADMIN-COLLATION"><p class="title"><strong>Table 9.96. Collation Management Functions</strong></p><div class="table-contents"><table class="table" summary="Collation Management Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.8.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_collation_actual_version</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the actual version of the collation object as it is currently
+ installed in the operating system. If this is different from the
+ value in
+ <code class="structname">pg_collation</code>.<code class="structfield">collversion</code>,
+ then objects depending on the collation might need to be rebuilt. See
+ also <a class="xref" href="sql-altercollation.html" title="ALTER COLLATION"><span class="refentrytitle">ALTER COLLATION</span></a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.8.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_database_collation_actual_version</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the actual version of the database's collation as it is currently
+ installed in the operating system. If this is different from the
+ value in
+ <code class="structname">pg_database</code>.<code class="structfield">datcollversion</code>,
+ then objects depending on the collation might need to be rebuilt. See
+ also <a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.8.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_import_system_collations</code> ( <em class="parameter"><code>schema</code></em> <code class="type">regnamespace</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Adds collations to the system
+ catalog <code class="structname">pg_collation</code> based on all the locales
+ it finds in the operating system. This is
+ what <code class="command">initdb</code> uses; see
+ <a class="xref" href="collation.html#COLLATION-MANAGING" title="24.2.2. Managing Collations">Section 24.2.2</a> for more details. If additional
+ locales are installed into the operating system later on, this
+ function can be run again to add collations for the new locales.
+ Locales that match existing entries
+ in <code class="structname">pg_collation</code> will be skipped. (But
+ collation objects based on locales that are no longer present in the
+ operating system are not removed by this function.)
+ The <em class="parameter"><code>schema</code></em> parameter would typically
+ be <code class="literal">pg_catalog</code>, but that is not a requirement; the
+ collations could be installed into some other schema as well. The
+ function returns the number of new collation objects it created.
+ Use of this function is restricted to superusers.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-admin.html#FUNCTIONS-INFO-PARTITION" title="Table 9.97. Partitioning Information Functions">Table 9.97</a> lists functions that provide
+ information about the structure of partitioned tables.
+ </p><div class="table" id="FUNCTIONS-INFO-PARTITION"><p class="title"><strong>Table 9.97. Partitioning Information Functions</strong></p><div class="table-contents"><table class="table" summary="Partitioning Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.10.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_partition_tree</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>relid</code></em> <code class="type">regclass</code>,
+ <em class="parameter"><code>parentrelid</code></em> <code class="type">regclass</code>,
+ <em class="parameter"><code>isleaf</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>level</code></em> <code class="type">integer</code> )
+ </p>
+ <p>
+ Lists the tables or indexes in the partition tree of the
+ given partitioned table or partitioned index, with one row for each
+ partition. Information provided includes the OID of the partition,
+ the OID of its immediate parent, a boolean value telling if the
+ partition is a leaf, and an integer telling its level in the hierarchy.
+ The level value is 0 for the input table or index, 1 for its
+ immediate child partitions, 2 for their partitions, and so on.
+ Returns no rows if the relation does not exist or is not a partition
+ or partitioned table.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.10.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_partition_ancestors</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">setof regclass</code>
+ </p>
+ <p>
+ Lists the ancestor relations of the given partition,
+ including the relation itself. Returns no rows if the relation
+ does not exist or is not a partition or partitioned table.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.9.10.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_partition_root</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">regclass</code>
+ </p>
+ <p>
+ Returns the top-most parent of the partition tree to which the given
+ relation belongs. Returns <code class="literal">NULL</code> if the relation
+ does not exist or is not a partition or partitioned table.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For example, to check the total size of the data contained in a
+ partitioned table <code class="structname">measurement</code>, one could use the
+ following query:
+</p><pre class="programlisting">
+SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size
+ FROM pg_partition_tree('measurement');
+</pre><p>
+ </p></div><div class="sect2" id="FUNCTIONS-ADMIN-INDEX"><div class="titlepage"><div><div><h3 class="title">9.27.8. Index Maintenance Functions</h3></div></div></div><p>
+ <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-INDEX-TABLE" title="Table 9.98. Index Maintenance Functions">Table 9.98</a> shows the functions
+ available for index maintenance tasks. (Note that these maintenance
+ tasks are normally done automatically by autovacuum; use of these
+ functions is only required in special cases.)
+ These functions cannot be executed during recovery.
+ Use of these functions is restricted to superusers and the owner
+ of the given index.
+ </p><div class="table" id="FUNCTIONS-ADMIN-INDEX-TABLE"><p class="title"><strong>Table 9.98. Index Maintenance Functions</strong></p><div class="table-contents"><table class="table" summary="Index Maintenance Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.10.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">brin_summarize_new_values</code> ( <em class="parameter"><code>index</code></em> <code class="type">regclass</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Scans the specified BRIN index to find page ranges in the base table
+ that are not currently summarized by the index; for any such range it
+ creates a new summary index tuple by scanning those table pages.
+ Returns the number of new page range summaries that were inserted
+ into the index.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.10.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">brin_summarize_range</code> ( <em class="parameter"><code>index</code></em> <code class="type">regclass</code>, <em class="parameter"><code>blockNumber</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Summarizes the page range covering the given block, if not already
+ summarized. This is
+ like <code class="function">brin_summarize_new_values</code> except that it
+ only processes the page range that covers the given table block number.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.10.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">brin_desummarize_range</code> ( <em class="parameter"><code>index</code></em> <code class="type">regclass</code>, <em class="parameter"><code>blockNumber</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Removes the BRIN index tuple that summarizes the page range covering
+ the given table block, if there is one.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.10.3.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">gin_clean_pending_list</code> ( <em class="parameter"><code>index</code></em> <code class="type">regclass</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Cleans up the <span class="quote">“<span class="quote">pending</span>”</span> list of the specified GIN index
+ by moving entries in it, in bulk, to the main GIN data structure.
+ Returns the number of pages removed from the pending list.
+ If the argument is a GIN index built with
+ the <code class="literal">fastupdate</code> option disabled, no cleanup happens
+ and the result is zero, because the index doesn't have a pending list.
+ See <a class="xref" href="gin-implementation.html#GIN-FAST-UPDATE" title="70.4.1. GIN Fast Update Technique">Section 70.4.1</a> and <a class="xref" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Section 70.5</a>
+ for details about the pending list and <code class="literal">fastupdate</code>
+ option.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="FUNCTIONS-ADMIN-GENFILE"><div class="titlepage"><div><div><h3 class="title">9.27.9. Generic File Access Functions</h3></div></div></div><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE-TABLE" title="Table 9.99. Generic File Access Functions">Table 9.99</a> provide native access to
+ files on the machine hosting the server. Only files within the
+ database cluster directory and the <code class="varname">log_directory</code> can be
+ accessed, unless the user is a superuser or is granted the role
+ <code class="literal">pg_read_server_files</code>. Use a relative path for files in
+ the cluster directory, and a path matching the <code class="varname">log_directory</code>
+ configuration setting for log files.
+ </p><p>
+ Note that granting users the EXECUTE privilege on
+ <code class="function">pg_read_file()</code>, or related functions, allows them the
+ ability to read any file on the server that the database server process can
+ read; these functions bypass all in-database privilege checks. This means
+ that, for example, a user with such access is able to read the contents of
+ the <code class="structname">pg_authid</code> table where authentication
+ information is stored, as well as read any table data in the database.
+ Therefore, granting access to these functions should be carefully
+ considered.
+ </p><p>
+ Some of these functions take an optional <em class="parameter"><code>missing_ok</code></em>
+ parameter, which specifies the behavior when the file or directory does
+ not exist. If <code class="literal">true</code>, the function
+ returns <code class="literal">NULL</code> or an empty result set, as appropriate.
+ If <code class="literal">false</code>, an error is raised. The default
+ is <code class="literal">false</code>.
+ </p><div class="table" id="FUNCTIONS-ADMIN-GENFILE-TABLE"><p class="title"><strong>Table 9.99. Generic File Access Functions</strong></p><div class="table-contents"><table class="table" summary="Generic File Access Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_dir</code> ( <em class="parameter"><code>dirname</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>missing_ok</code></em> <code class="type">boolean</code>, <em class="parameter"><code>include_dot_dirs</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Returns the names of all files (and directories and other special
+ files) in the specified
+ directory. The <em class="parameter"><code>include_dot_dirs</code></em> parameter
+ indicates whether <span class="quote">“<span class="quote">.</span>”</span> and <span class="quote">“<span class="quote">..</span>”</span> are to be
+ included in the result set; the default is to exclude them. Including
+ them can be useful when <em class="parameter"><code>missing_ok</code></em>
+ is <code class="literal">true</code>, to distinguish an empty directory from a
+ non-existent directory.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_logdir</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's log directory. Filenames beginning with
+ a dot, directories, and other special files are excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and roles with privileges of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_waldir</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's write-ahead log (WAL) directory.
+ Filenames beginning with a dot, directories, and other special files
+ are excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and roles with privileges of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_logicalmapdir</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's <code class="filename">pg_logical/mappings</code>
+ directory. Filenames beginning with a dot, directories, and other
+ special files are excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and members of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_logicalsnapdir</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's <code class="filename">pg_logical/snapshots</code>
+ directory. Filenames beginning with a dot, directories, and other
+ special files are excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and members of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_replslotdir</code> ( <em class="parameter"><code>slot_name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's <code class="filename">pg_replslot/slot_name</code>
+ directory, where <em class="parameter"><code>slot_name</code></em> is the name of the
+ replication slot provided as input of the function. Filenames beginning
+ with a dot, directories, and other special files are excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and members of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_archive_statusdir</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the server's WAL archive status directory
+ (<code class="filename">pg_wal/archive_status</code>). Filenames beginning
+ with a dot, directories, and other special files are excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and members of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+
+ <a id="id-1.5.8.33.11.5.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ls_tmpdir</code> ( [<span class="optional"> <em class="parameter"><code>tablespace</code></em> <code class="type">oid</code> </span>] )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code> )
+ </p>
+ <p>
+ Returns the name, size, and last modification time (mtime) of each
+ ordinary file in the temporary file directory for the
+ specified <em class="parameter"><code>tablespace</code></em>.
+ If <em class="parameter"><code>tablespace</code></em> is not provided,
+ the <code class="literal">pg_default</code> tablespace is examined. Filenames
+ beginning with a dot, directories, and other special files are
+ excluded.
+ </p>
+ <p>
+ This function is restricted to superusers and members of
+ the <code class="literal">pg_monitor</code> role by default, but other users can
+ be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_read_file</code> ( <em class="parameter"><code>filename</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>offset</code></em> <code class="type">bigint</code>, <em class="parameter"><code>length</code></em> <code class="type">bigint</code> [<span class="optional">, <em class="parameter"><code>missing_ok</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns all or part of a text file, starting at the
+ given byte <em class="parameter"><code>offset</code></em>, returning at
+ most <em class="parameter"><code>length</code></em> bytes (less if the end of file is
+ reached first). If <em class="parameter"><code>offset</code></em> is negative, it is
+ relative to the end of the file. If <em class="parameter"><code>offset</code></em>
+ and <em class="parameter"><code>length</code></em> are omitted, the entire file is
+ returned. The bytes read from the file are interpreted as a string in
+ the database's encoding; an error is thrown if they are not valid in
+ that encoding.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_read_binary_file</code> ( <em class="parameter"><code>filename</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>offset</code></em> <code class="type">bigint</code>, <em class="parameter"><code>length</code></em> <code class="type">bigint</code> [<span class="optional">, <em class="parameter"><code>missing_ok</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Returns all or part of a file. This function is identical to
+ <code class="function">pg_read_file</code> except that it can read arbitrary
+ binary data, returning the result as <code class="type">bytea</code>
+ not <code class="type">text</code>; accordingly, no encoding checks are performed.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p>
+ <p>
+ In combination with the <code class="function">convert_from</code> function,
+ this function can be used to read a text file in a specified encoding
+ and convert to the database's encoding:
+</p><pre class="programlisting">
+SELECT convert_from(pg_read_binary_file('file_in_utf8.txt'), 'UTF8');
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.11.5.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_file</code> ( <em class="parameter"><code>filename</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>missing_ok</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>size</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>access</code></em> <code class="type">timestamp with time zone</code>,
+ <em class="parameter"><code>modification</code></em> <code class="type">timestamp with time zone</code>,
+ <em class="parameter"><code>change</code></em> <code class="type">timestamp with time zone</code>,
+ <em class="parameter"><code>creation</code></em> <code class="type">timestamp with time zone</code>,
+ <em class="parameter"><code>isdir</code></em> <code class="type">boolean</code> )
+ </p>
+ <p>
+ Returns a record containing the file's size, last access time stamp,
+ last modification time stamp, last file status change time stamp (Unix
+ platforms only), file creation time stamp (Windows only), and a flag
+ indicating if it is a directory.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="FUNCTIONS-ADVISORY-LOCKS"><div class="titlepage"><div><div><h3 class="title">9.27.10. Advisory Lock Functions</h3></div></div></div><p>
+ The functions shown in <a class="xref" href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS-TABLE" title="Table 9.100. Advisory Lock Functions">Table 9.100</a>
+ manage advisory locks. For details about proper use of these functions,
+ see <a class="xref" href="explicit-locking.html#ADVISORY-LOCKS" title="13.3.5. Advisory Locks">Section 13.3.5</a>.
+ </p><p>
+ All these functions are intended to be used to lock application-defined
+ resources, which can be identified either by a single 64-bit key value or
+ two 32-bit key values (note that these two key spaces do not overlap).
+ If another session already holds a conflicting lock on the same resource
+ identifier, the functions will either wait until the resource becomes
+ available, or return a <code class="literal">false</code> result, as appropriate for
+ the function.
+ Locks can be either shared or exclusive: a shared lock does not conflict
+ with other shared locks on the same resource, only with exclusive locks.
+ Locks can be taken at session level (so that they are held until released
+ or the session ends) or at transaction level (so that they are held until
+ the current transaction ends; there is no provision for manual release).
+ Multiple session-level lock requests stack, so that if the same resource
+ identifier is locked three times there must then be three unlock requests
+ to release the resource in advance of session end.
+ </p><div class="table" id="FUNCTIONS-ADVISORY-LOCKS-TABLE"><p class="title"><strong>Table 9.100. Advisory Lock Functions</strong></p><div class="table-contents"><table class="table" summary="Advisory Lock Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_lock</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_advisory_lock</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Obtains an exclusive session-level advisory lock, waiting if necessary.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_lock_shared</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_advisory_lock_shared</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Obtains a shared session-level advisory lock, waiting if necessary.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_unlock</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_advisory_unlock</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Releases a previously-acquired exclusive session-level advisory lock.
+ Returns <code class="literal">true</code> if the lock is successfully released.
+ If the lock was not held, <code class="literal">false</code> is returned, and in
+ addition, an SQL warning will be reported by the server.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_unlock_all</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Releases all session-level advisory locks held by the current session.
+ (This function is implicitly invoked at session end, even if the
+ client disconnects ungracefully.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_unlock_shared</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_advisory_unlock_shared</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Releases a previously-acquired shared session-level advisory lock.
+ Returns <code class="literal">true</code> if the lock is successfully released.
+ If the lock was not held, <code class="literal">false</code> is returned, and in
+ addition, an SQL warning will be reported by the server.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_xact_lock</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_advisory_xact_lock</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Obtains an exclusive transaction-level advisory lock, waiting if
+ necessary.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_advisory_xact_lock_shared</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_advisory_xact_lock_shared</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Obtains a shared transaction-level advisory lock, waiting if
+ necessary.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_try_advisory_lock</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_try_advisory_lock</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Obtains an exclusive session-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <code class="literal">true</code>, or return <code class="literal">false</code>
+ without waiting if the lock cannot be acquired immediately.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_try_advisory_lock_shared</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_try_advisory_lock_shared</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Obtains a shared session-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <code class="literal">true</code>, or return <code class="literal">false</code>
+ without waiting if the lock cannot be acquired immediately.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_try_advisory_xact_lock</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_try_advisory_xact_lock</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Obtains an exclusive transaction-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <code class="literal">true</code>, or return <code class="literal">false</code>
+ without waiting if the lock cannot be acquired immediately.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.33.12.4.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_try_advisory_xact_lock_shared</code> ( <em class="parameter"><code>key</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">pg_try_advisory_xact_lock_shared</code> ( <em class="parameter"><code>key1</code></em> <code class="type">integer</code>, <em class="parameter"><code>key2</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Obtains a shared transaction-level advisory lock if available.
+ This will either obtain the lock immediately and
+ return <code class="literal">true</code>, or return <code class="literal">false</code>
+ without waiting if the lock cannot be acquired immediately.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-info.html" title="9.26. System Information Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-trigger.html" title="9.28. Trigger Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.26. System Information Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.28. Trigger Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-aggregate.html b/doc/src/sgml/html/functions-aggregate.html
new file mode 100644
index 0000000..286b08a
--- /dev/null
+++ b/doc/src/sgml/html/functions-aggregate.html
@@ -0,0 +1,729 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.21. Aggregate Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-range.html" title="9.20. Range/Multirange Functions and Operators" /><link rel="next" href="functions-window.html" title="9.22. Window Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.21. Aggregate Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-range.html" title="9.20. Range/Multirange Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-window.html" title="9.22. Window Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-AGGREGATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.21. Aggregate Functions</h2></div></div></div><a id="id-1.5.8.27.2" class="indexterm"></a><p>
+ <em class="firstterm">Aggregate functions</em> compute a single result
+ from a set of input values. The built-in general-purpose aggregate
+ functions are listed in <a class="xref" href="functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE" title="Table 9.58. General-Purpose Aggregate Functions">Table 9.58</a>
+ while statistical aggregates are in <a class="xref" href="functions-aggregate.html#FUNCTIONS-AGGREGATE-STATISTICS-TABLE" title="Table 9.59. Aggregate Functions for Statistics">Table 9.59</a>.
+ The built-in within-group ordered-set aggregate functions
+ are listed in <a class="xref" href="functions-aggregate.html#FUNCTIONS-ORDEREDSET-TABLE" title="Table 9.60. Ordered-Set Aggregate Functions">Table 9.60</a>
+ while the built-in within-group hypothetical-set ones are in <a class="xref" href="functions-aggregate.html#FUNCTIONS-HYPOTHETICAL-TABLE" title="Table 9.61. Hypothetical-Set Aggregate Functions">Table 9.61</a>. Grouping operations,
+ which are closely related to aggregate functions, are listed in
+ <a class="xref" href="functions-aggregate.html#FUNCTIONS-GROUPING-TABLE" title="Table 9.62. Grouping Operations">Table 9.62</a>.
+ The special syntax considerations for aggregate
+ functions are explained in <a class="xref" href="sql-expressions.html#SYNTAX-AGGREGATES" title="4.2.7. Aggregate Expressions">Section 4.2.7</a>.
+ Consult <a class="xref" href="tutorial-agg.html" title="2.7. Aggregate Functions">Section 2.7</a> for additional introductory
+ information.
+ </p><p>
+ Aggregate functions that support <em class="firstterm">Partial Mode</em>
+ are eligible to participate in various optimizations, such as parallel
+ aggregation.
+ </p><div class="table" id="FUNCTIONS-AGGREGATE-TABLE"><p class="title"><strong>Table 9.58. General-Purpose Aggregate Functions</strong></p><div class="table-contents"><table class="table" summary="General-Purpose Aggregate Functions" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th><th>Partial Mode</th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.1.1.1.1" class="indexterm"></a>
+ <code class="function">array_agg</code> ( <code class="type">anynonarray</code> )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Collects all the input values, including nulls, into an array.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">array_agg</code> ( <code class="type">anyarray</code> )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Concatenates all the input arrays into an array of one higher
+ dimension. (The inputs must all have the same dimensionality, and
+ cannot be empty or null.)
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.3.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.5.2.4.3.1.1.2" class="indexterm"></a>
+ <code class="function">avg</code> ( <code class="type">smallint</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">avg</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">avg</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">avg</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">avg</code> ( <code class="type">real</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">avg</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">avg</code> ( <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Computes the average (arithmetic mean) of all the non-null input
+ values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.4.1.1.1" class="indexterm"></a>
+ <code class="function">bit_and</code> ( <code class="type">smallint</code> )
+ → <code class="returnvalue">smallint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_and</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_and</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_and</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Computes the bitwise AND of all non-null input values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.5.1.1.1" class="indexterm"></a>
+ <code class="function">bit_or</code> ( <code class="type">smallint</code> )
+ → <code class="returnvalue">smallint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_or</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_or</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_or</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Computes the bitwise OR of all non-null input values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.6.1.1.1" class="indexterm"></a>
+ <code class="function">bit_xor</code> ( <code class="type">smallint</code> )
+ → <code class="returnvalue">smallint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_xor</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_xor</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">bit_xor</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Computes the bitwise exclusive OR of all non-null input values.
+ Can be useful as a checksum for an unordered set of values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.7.1.1.1" class="indexterm"></a>
+ <code class="function">bool_and</code> ( <code class="type">boolean</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if all non-null input values are true, otherwise false.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.8.1.1.1" class="indexterm"></a>
+ <code class="function">bool_or</code> ( <code class="type">boolean</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if any non-null input value is true, otherwise false.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.9.1.1.1" class="indexterm"></a>
+ <code class="function">count</code> ( <code class="literal">*</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the number of input rows.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">count</code> ( <code class="type">"any"</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the number of input rows in which the input value is not
+ null.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.11.1.1.1" class="indexterm"></a>
+ <code class="function">every</code> ( <code class="type">boolean</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ This is the SQL standard's equivalent to <code class="function">bool_and</code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.12.1.1.1" class="indexterm"></a>
+ <code class="function">json_agg</code> ( <code class="type">anyelement</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.12.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_agg</code> ( <code class="type">anyelement</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Collects all the input values, including nulls, into a JSON array.
+ Values are converted to JSON as per <code class="function">to_json</code>
+ or <code class="function">to_jsonb</code>.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.13.1.1.1" class="indexterm"></a>
+ <code class="function">json_object_agg</code> ( <em class="parameter"><code>key</code></em>
+ <code class="type">"any"</code>, <em class="parameter"><code>value</code></em>
+ <code class="type">"any"</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.13.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_object_agg</code> ( <em class="parameter"><code>key</code></em>
+ <code class="type">"any"</code>, <em class="parameter"><code>value</code></em>
+ <code class="type">"any"</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Collects all the key/value pairs into a JSON object. Key arguments
+ are coerced to text; value arguments are converted as
+ per <code class="function">to_json</code> or <code class="function">to_jsonb</code>.
+ Values can be null, but not keys.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.14.1.1.1" class="indexterm"></a>
+ <code class="function">max</code> ( <em class="replaceable"><code>see text</code></em> )
+ → <code class="returnvalue"><em class="replaceable"><code>same as input type</code></em></code>
+ </p>
+ <p>
+ Computes the maximum of the non-null input
+ values. Available for any numeric, string, date/time, or enum type,
+ as well as <code class="type">inet</code>, <code class="type">interval</code>,
+ <code class="type">money</code>, <code class="type">oid</code>, <code class="type">pg_lsn</code>,
+ <code class="type">tid</code>, <code class="type">xid8</code>,
+ and arrays of any of these types.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.15.1.1.1" class="indexterm"></a>
+ <code class="function">min</code> ( <em class="replaceable"><code>see text</code></em> )
+ → <code class="returnvalue"><em class="replaceable"><code>same as input type</code></em></code>
+ </p>
+ <p>
+ Computes the minimum of the non-null input
+ values. Available for any numeric, string, date/time, or enum type,
+ as well as <code class="type">inet</code>, <code class="type">interval</code>,
+ <code class="type">money</code>, <code class="type">oid</code>, <code class="type">pg_lsn</code>,
+ <code class="type">tid</code>, <code class="type">xid8</code>,
+ and arrays of any of these types.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.16.1.1.1" class="indexterm"></a>
+ <code class="function">range_agg</code> ( <em class="parameter"><code>value</code></em>
+ <code class="type">anyrange</code> )
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">range_agg</code> ( <em class="parameter"><code>value</code></em>
+ <code class="type">anymultirange</code> )
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p>
+ Computes the union of the non-null input values.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.17.1.1.1" class="indexterm"></a>
+ <code class="function">range_intersect_agg</code> ( <em class="parameter"><code>value</code></em>
+ <code class="type">anyrange</code> )
+ → <code class="returnvalue">anyrange</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">range_intersect_agg</code> ( <em class="parameter"><code>value</code></em>
+ <code class="type">anymultirange</code> )
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p>
+ Computes the intersection of the non-null input values.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.18.1.1.1" class="indexterm"></a>
+ <code class="function">string_agg</code> ( <em class="parameter"><code>value</code></em>
+ <code class="type">text</code>, <em class="parameter"><code>delimiter</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">string_agg</code> ( <em class="parameter"><code>value</code></em>
+ <code class="type">bytea</code>, <em class="parameter"><code>delimiter</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Concatenates the non-null input values into a string. Each value
+ after the first is preceded by the
+ corresponding <em class="parameter"><code>delimiter</code></em> (if it's not null).
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.19.1.1.1" class="indexterm"></a>
+ <code class="function">sum</code> ( <code class="type">smallint</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">real</code> )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sum</code> ( <code class="type">money</code> )
+ → <code class="returnvalue">money</code>
+ </p>
+ <p>
+ Computes the sum of the non-null input values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.5.2.4.20.1.1.1" class="indexterm"></a>
+ <code class="function">xmlagg</code> ( <code class="type">xml</code> )
+ → <code class="returnvalue">xml</code>
+ </p>
+ <p>
+ Concatenates the non-null XML input values (see
+ <a class="xref" href="functions-xml.html#FUNCTIONS-XML-XMLAGG" title="9.15.1.7. xmlagg">Section 9.15.1.7</a>).
+ </p></td><td>No</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ It should be noted that except for <code class="function">count</code>,
+ these functions return a null value when no rows are selected. In
+ particular, <code class="function">sum</code> of no rows returns null, not
+ zero as one might expect, and <code class="function">array_agg</code>
+ returns null rather than an empty array when there are no input
+ rows. The <code class="function">coalesce</code> function can be used to
+ substitute zero or an empty array for null when necessary.
+ </p><p>
+ The aggregate functions <code class="function">array_agg</code>,
+ <code class="function">json_agg</code>, <code class="function">jsonb_agg</code>,
+ <code class="function">json_object_agg</code>, <code class="function">jsonb_object_agg</code>,
+ <code class="function">string_agg</code>,
+ and <code class="function">xmlagg</code>, as well as similar user-defined
+ aggregate functions, produce meaningfully different result values
+ depending on the order of the input values. This ordering is
+ unspecified by default, but can be controlled by writing an
+ <code class="literal">ORDER BY</code> clause within the aggregate call, as shown in
+ <a class="xref" href="sql-expressions.html#SYNTAX-AGGREGATES" title="4.2.7. Aggregate Expressions">Section 4.2.7</a>.
+ Alternatively, supplying the input values from a sorted subquery
+ will usually work. For example:
+
+</p><pre class="screen">
+SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
+</pre><p>
+
+ Beware that this approach can fail if the outer query level contains
+ additional processing, such as a join, because that might cause the
+ subquery's output to be reordered before the aggregate is computed.
+ </p><div class="note"><h3 class="title">Note</h3><a id="id-1.5.8.27.8.1" class="indexterm"></a><a id="id-1.5.8.27.8.2" class="indexterm"></a><p>
+ The boolean aggregates <code class="function">bool_and</code> and
+ <code class="function">bool_or</code> correspond to the standard SQL aggregates
+ <code class="function">every</code> and <code class="function">any</code> or
+ <code class="function">some</code>.
+ <span class="productname">PostgreSQL</span>
+ supports <code class="function">every</code>, but not <code class="function">any</code>
+ or <code class="function">some</code>, because there is an ambiguity built into
+ the standard syntax:
+</p><pre class="programlisting">
+SELECT b1 = ANY((SELECT b2 FROM t2 ...)) FROM t1 ...;
+</pre><p>
+ Here <code class="function">ANY</code> can be considered either as introducing
+ a subquery, or as being an aggregate function, if the subquery
+ returns one row with a Boolean value.
+ Thus the standard name cannot be given to these aggregates.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Users accustomed to working with other SQL database management
+ systems might be disappointed by the performance of the
+ <code class="function">count</code> aggregate when it is applied to the
+ entire table. A query like:
+</p><pre class="programlisting">
+SELECT count(*) FROM sometable;
+</pre><p>
+ will require effort proportional to the size of the table:
+ <span class="productname">PostgreSQL</span> will need to scan either the
+ entire table or the entirety of an index that includes all rows in
+ the table.
+ </p></div><p>
+ <a class="xref" href="functions-aggregate.html#FUNCTIONS-AGGREGATE-STATISTICS-TABLE" title="Table 9.59. Aggregate Functions for Statistics">Table 9.59</a> shows
+ aggregate functions typically used in statistical analysis.
+ (These are separated out merely to avoid cluttering the listing
+ of more-commonly-used aggregates.) Functions shown as
+ accepting <em class="replaceable"><code>numeric_type</code></em> are available for all
+ the types <code class="type">smallint</code>, <code class="type">integer</code>,
+ <code class="type">bigint</code>, <code class="type">numeric</code>, <code class="type">real</code>,
+ and <code class="type">double precision</code>.
+ Where the description mentions
+ <em class="parameter"><code>N</code></em>, it means the
+ number of input rows for which all the input expressions are non-null.
+ In all cases, null is returned if the computation is meaningless,
+ for example when <em class="parameter"><code>N</code></em> is zero.
+ </p><a id="id-1.5.8.27.11" class="indexterm"></a><a id="id-1.5.8.27.12" class="indexterm"></a><div class="table" id="FUNCTIONS-AGGREGATE-STATISTICS-TABLE"><p class="title"><strong>Table 9.59. Aggregate Functions for Statistics</strong></p><div class="table-contents"><table class="table" summary="Aggregate Functions for Statistics" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th><th>Partial Mode</th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.1.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.1.1.1.2" class="indexterm"></a>
+ <code class="function">corr</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the correlation coefficient.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.2.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.2.1.1.2" class="indexterm"></a>
+ <code class="function">covar_pop</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the population covariance.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.3.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.3.1.1.2" class="indexterm"></a>
+ <code class="function">covar_samp</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the sample covariance.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.4.1.1.1" class="indexterm"></a>
+ <code class="function">regr_avgx</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the average of the independent variable,
+ <code class="literal">sum(<em class="parameter"><code>X</code></em>)/<em class="parameter"><code>N</code></em></code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.5.1.1.1" class="indexterm"></a>
+ <code class="function">regr_avgy</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the average of the dependent variable,
+ <code class="literal">sum(<em class="parameter"><code>Y</code></em>)/<em class="parameter"><code>N</code></em></code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.6.1.1.1" class="indexterm"></a>
+ <code class="function">regr_count</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the number of rows in which both inputs are non-null.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.7.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.7.1.1.2" class="indexterm"></a>
+ <code class="function">regr_intercept</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the y-intercept of the least-squares-fit linear equation
+ determined by the
+ (<em class="parameter"><code>X</code></em>, <em class="parameter"><code>Y</code></em>) pairs.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.8.1.1.1" class="indexterm"></a>
+ <code class="function">regr_r2</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the square of the correlation coefficient.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.9.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.9.1.1.2" class="indexterm"></a>
+ <code class="function">regr_slope</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the slope of the least-squares-fit linear equation determined
+ by the (<em class="parameter"><code>X</code></em>, <em class="parameter"><code>Y</code></em>)
+ pairs.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.10.1.1.1" class="indexterm"></a>
+ <code class="function">regr_sxx</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the <span class="quote">“<span class="quote">sum of squares</span>”</span> of the independent
+ variable,
+ <code class="literal">sum(<em class="parameter"><code>X</code></em>^2) - sum(<em class="parameter"><code>X</code></em>)^2/<em class="parameter"><code>N</code></em></code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.11.1.1.1" class="indexterm"></a>
+ <code class="function">regr_sxy</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the <span class="quote">“<span class="quote">sum of products</span>”</span> of independent times
+ dependent variables,
+ <code class="literal">sum(<em class="parameter"><code>X</code></em>*<em class="parameter"><code>Y</code></em>) - sum(<em class="parameter"><code>X</code></em>) * sum(<em class="parameter"><code>Y</code></em>)/<em class="parameter"><code>N</code></em></code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.12.1.1.1" class="indexterm"></a>
+ <code class="function">regr_syy</code> ( <em class="parameter"><code>Y</code></em> <code class="type">double precision</code>, <em class="parameter"><code>X</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the <span class="quote">“<span class="quote">sum of squares</span>”</span> of the dependent
+ variable,
+ <code class="literal">sum(<em class="parameter"><code>Y</code></em>^2) - sum(<em class="parameter"><code>Y</code></em>)^2/<em class="parameter"><code>N</code></em></code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.13.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.13.1.1.2" class="indexterm"></a>
+ <code class="function">stddev</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"></code> <code class="type">double precision</code>
+ for <code class="type">real</code> or <code class="type">double precision</code>,
+ otherwise <code class="type">numeric</code>
+ </p>
+ <p>
+ This is a historical alias for <code class="function">stddev_samp</code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.14.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.14.1.1.2" class="indexterm"></a>
+ <code class="function">stddev_pop</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"></code> <code class="type">double precision</code>
+ for <code class="type">real</code> or <code class="type">double precision</code>,
+ otherwise <code class="type">numeric</code>
+ </p>
+ <p>
+ Computes the population standard deviation of the input values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.15.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.15.1.1.2" class="indexterm"></a>
+ <code class="function">stddev_samp</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"></code> <code class="type">double precision</code>
+ for <code class="type">real</code> or <code class="type">double precision</code>,
+ otherwise <code class="type">numeric</code>
+ </p>
+ <p>
+ Computes the sample standard deviation of the input values.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.16.1.1.1" class="indexterm"></a>
+ <code class="function">variance</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"></code> <code class="type">double precision</code>
+ for <code class="type">real</code> or <code class="type">double precision</code>,
+ otherwise <code class="type">numeric</code>
+ </p>
+ <p>
+ This is a historical alias for <code class="function">var_samp</code>.
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.17.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.17.1.1.2" class="indexterm"></a>
+ <code class="function">var_pop</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"></code> <code class="type">double precision</code>
+ for <code class="type">real</code> or <code class="type">double precision</code>,
+ otherwise <code class="type">numeric</code>
+ </p>
+ <p>
+ Computes the population variance of the input values (square of the
+ population standard deviation).
+ </p></td><td>Yes</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.13.2.4.18.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.27.13.2.4.18.1.1.2" class="indexterm"></a>
+ <code class="function">var_samp</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"></code> <code class="type">double precision</code>
+ for <code class="type">real</code> or <code class="type">double precision</code>,
+ otherwise <code class="type">numeric</code>
+ </p>
+ <p>
+ Computes the sample variance of the input values (square of the sample
+ standard deviation).
+ </p></td><td>Yes</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-aggregate.html#FUNCTIONS-ORDEREDSET-TABLE" title="Table 9.60. Ordered-Set Aggregate Functions">Table 9.60</a> shows some
+ aggregate functions that use the <em class="firstterm">ordered-set aggregate</em>
+ syntax. These functions are sometimes referred to as <span class="quote">“<span class="quote">inverse
+ distribution</span>”</span> functions. Their aggregated input is introduced by
+ <code class="literal">ORDER BY</code>, and they may also take a <em class="firstterm">direct
+ argument</em> that is not aggregated, but is computed only once.
+ All these functions ignore null values in their aggregated input.
+ For those that take a <em class="parameter"><code>fraction</code></em> parameter, the
+ fraction value must be between 0 and 1; an error is thrown if not.
+ However, a null <em class="parameter"><code>fraction</code></em> value simply produces a
+ null result.
+ </p><a id="id-1.5.8.27.15" class="indexterm"></a><a id="id-1.5.8.27.16" class="indexterm"></a><div class="table" id="FUNCTIONS-ORDEREDSET-TABLE"><p class="title"><strong>Table 9.60. Ordered-Set Aggregate Functions</strong></p><div class="table-contents"><table class="table" summary="Ordered-Set Aggregate Functions" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th><th>Partial Mode</th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.17.2.4.1.1.1.1" class="indexterm"></a>
+ <code class="function">mode</code> () <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">anyelement</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Computes the <em class="firstterm">mode</em>, the most frequent
+ value of the aggregated argument (arbitrarily choosing the first one
+ if there are multiple equally-frequent values). The aggregated
+ argument must be of a sortable type.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.17.2.4.2.1.1.1" class="indexterm"></a>
+ <code class="function">percentile_cont</code> ( <em class="parameter"><code>fraction</code></em> <code class="type">double precision</code> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">percentile_cont</code> ( <em class="parameter"><code>fraction</code></em> <code class="type">double precision</code> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Computes the <em class="firstterm">continuous percentile</em>, a value
+ corresponding to the specified <em class="parameter"><code>fraction</code></em>
+ within the ordered set of aggregated argument values. This will
+ interpolate between adjacent input items if needed.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">percentile_cont</code> ( <em class="parameter"><code>fractions</code></em> <code class="type">double precision[]</code> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision[]</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">percentile_cont</code> ( <em class="parameter"><code>fractions</code></em> <code class="type">double precision[]</code> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">interval</code> )
+ → <code class="returnvalue">interval[]</code>
+ </p>
+ <p>
+ Computes multiple continuous percentiles. The result is an array of
+ the same dimensions as the <em class="parameter"><code>fractions</code></em>
+ parameter, with each non-null element replaced by the (possibly
+ interpolated) value corresponding to that percentile.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.17.2.4.4.1.1.1" class="indexterm"></a>
+ <code class="function">percentile_disc</code> ( <em class="parameter"><code>fraction</code></em> <code class="type">double precision</code> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">anyelement</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Computes the <em class="firstterm">discrete percentile</em>, the first
+ value within the ordered set of aggregated argument values whose
+ position in the ordering equals or exceeds the
+ specified <em class="parameter"><code>fraction</code></em>. The aggregated
+ argument must be of a sortable type.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">percentile_disc</code> ( <em class="parameter"><code>fractions</code></em> <code class="type">double precision[]</code> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <code class="type">anyelement</code> )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Computes multiple discrete percentiles. The result is an array of the
+ same dimensions as the <em class="parameter"><code>fractions</code></em> parameter,
+ with each non-null element replaced by the input value corresponding
+ to that percentile.
+ The aggregated argument must be of a sortable type.
+ </p></td><td>No</td></tr></tbody></table></div></div><br class="table-break" /><a id="id-1.5.8.27.18" class="indexterm"></a><p>
+ Each of the <span class="quote">“<span class="quote">hypothetical-set</span>”</span> aggregates listed in
+ <a class="xref" href="functions-aggregate.html#FUNCTIONS-HYPOTHETICAL-TABLE" title="Table 9.61. Hypothetical-Set Aggregate Functions">Table 9.61</a> is associated with a
+ window function of the same name defined in
+ <a class="xref" href="functions-window.html" title="9.22. Window Functions">Section 9.22</a>. In each case, the aggregate's result
+ is the value that the associated window function would have
+ returned for the <span class="quote">“<span class="quote">hypothetical</span>”</span> row constructed from
+ <em class="replaceable"><code>args</code></em>, if such a row had been added to the sorted
+ group of rows represented by the <em class="replaceable"><code>sorted_args</code></em>.
+ For each of these functions, the list of direct arguments
+ given in <em class="replaceable"><code>args</code></em> must match the number and types of
+ the aggregated arguments given in <em class="replaceable"><code>sorted_args</code></em>.
+ Unlike most built-in aggregates, these aggregates are not strict, that is
+ they do not drop input rows containing nulls. Null values sort according
+ to the rule specified in the <code class="literal">ORDER BY</code> clause.
+ </p><div class="table" id="FUNCTIONS-HYPOTHETICAL-TABLE"><p class="title"><strong>Table 9.61. Hypothetical-Set Aggregate Functions</strong></p><div class="table-contents"><table class="table" summary="Hypothetical-Set Aggregate Functions" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th><th>Partial Mode</th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.20.2.4.1.1.1.1" class="indexterm"></a>
+ <code class="function">rank</code> ( <em class="replaceable"><code>args</code></em> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <em class="replaceable"><code>sorted_args</code></em> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the rank of the hypothetical row, with gaps; that is, the row
+ number of the first row in its peer group.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.20.2.4.2.1.1.1" class="indexterm"></a>
+ <code class="function">dense_rank</code> ( <em class="replaceable"><code>args</code></em> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <em class="replaceable"><code>sorted_args</code></em> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the rank of the hypothetical row, without gaps; this function
+ effectively counts peer groups.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.20.2.4.3.1.1.1" class="indexterm"></a>
+ <code class="function">percent_rank</code> ( <em class="replaceable"><code>args</code></em> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <em class="replaceable"><code>sorted_args</code></em> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the relative rank of the hypothetical row, that is
+ (<code class="function">rank</code> - 1) / (total rows - 1).
+ The value thus ranges from 0 to 1 inclusive.
+ </p></td><td>No</td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.20.2.4.4.1.1.1" class="indexterm"></a>
+ <code class="function">cume_dist</code> ( <em class="replaceable"><code>args</code></em> ) <code class="literal">WITHIN GROUP</code> ( <code class="literal">ORDER BY</code> <em class="replaceable"><code>sorted_args</code></em> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the cumulative distribution, that is (number of rows
+ preceding or peers with hypothetical row) / (total rows). The value
+ thus ranges from 1/<em class="parameter"><code>N</code></em> to 1.
+ </p></td><td>No</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-GROUPING-TABLE"><p class="title"><strong>Table 9.62. Grouping Operations</strong></p><div class="table-contents"><table class="table" summary="Grouping Operations" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.27.21.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">GROUPING</code> ( <em class="replaceable"><code>group_by_expression(s)</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns a bit mask indicating which <code class="literal">GROUP BY</code>
+ expressions are not included in the current grouping set.
+ Bits are assigned with the rightmost argument corresponding to the
+ least-significant bit; each bit is 0 if the corresponding expression
+ is included in the grouping criteria of the grouping set generating
+ the current result row, and 1 if it is not included.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The grouping operations shown in
+ <a class="xref" href="functions-aggregate.html#FUNCTIONS-GROUPING-TABLE" title="Table 9.62. Grouping Operations">Table 9.62</a> are used in conjunction with
+ grouping sets (see <a class="xref" href="queries-table-expressions.html#QUERIES-GROUPING-SETS" title="7.2.4. GROUPING SETS, CUBE, and ROLLUP">Section 7.2.4</a>) to distinguish
+ result rows. The arguments to the <code class="literal">GROUPING</code> function
+ are not actually evaluated, but they must exactly match expressions given
+ in the <code class="literal">GROUP BY</code> clause of the associated query level.
+ For example:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM items_sold;</code></strong>
+ make | model | sales
+-------+-------+-------
+ Foo | GT | 10
+ Foo | Tour | 20
+ Bar | City | 15
+ Bar | Sport | 5
+(4 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT make, model, GROUPING(make,model), sum(sales) FROM items_sold GROUP BY ROLLUP(make,model);</code></strong>
+ make | model | grouping | sum
+-------+-------+----------+-----
+ Foo | GT | 0 | 10
+ Foo | Tour | 0 | 20
+ Bar | City | 0 | 15
+ Bar | Sport | 0 | 5
+ Foo | | 1 | 30
+ Bar | | 1 | 20
+ | | 3 | 50
+(7 rows)
+</pre><p>
+ Here, the <code class="literal">grouping</code> value <code class="literal">0</code> in the
+ first four rows shows that those have been grouped normally, over both the
+ grouping columns. The value <code class="literal">1</code> indicates
+ that <code class="literal">model</code> was not grouped by in the next-to-last two
+ rows, and the value <code class="literal">3</code> indicates that
+ neither <code class="literal">make</code> nor <code class="literal">model</code> was grouped
+ by in the last row (which therefore is an aggregate over all the input
+ rows).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-range.html" title="9.20. Range/Multirange Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-window.html" title="9.22. Window Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.20. Range/Multirange Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.22. Window Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-array.html b/doc/src/sgml/html/functions-array.html
new file mode 100644
index 0000000..c5ce7c6
--- /dev/null
+++ b/doc/src/sgml/html/functions-array.html
@@ -0,0 +1,385 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.19. Array Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-conditional.html" title="9.18. Conditional Expressions" /><link rel="next" href="functions-range.html" title="9.20. Range/Multirange Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.19. Array Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-conditional.html" title="9.18. Conditional Expressions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-range.html" title="9.20. Range/Multirange Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-ARRAY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.19. Array Functions and Operators</h2></div></div></div><p>
+ <a class="xref" href="functions-array.html#ARRAY-OPERATORS-TABLE" title="Table 9.52. Array Operators">Table 9.52</a> shows the specialized operators
+ available for array types.
+ In addition to those, the usual comparison operators shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are available for
+ arrays. The comparison operators compare the array contents
+ element-by-element, using the default B-tree comparison function for
+ the element data type, and sort based on the first difference.
+ In multidimensional arrays the elements are visited in row-major order
+ (last subscript varies most rapidly).
+ If the contents of two arrays are equal but the dimensionality is
+ different, the first difference in the dimensionality information
+ determines the sort order.
+ </p><div class="table" id="ARRAY-OPERATORS-TABLE"><p class="title"><strong>Table 9.52. Array Operators</strong></p><div class="table-contents"><table class="table" summary="Array Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyarray</code> <code class="literal">@&gt;</code> <code class="type">anyarray</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first array contain the second, that is, does each element
+ appearing in the second array equal some element of the first array?
+ (Duplicates are not treated specially,
+ thus <code class="literal">ARRAY[1]</code> and <code class="literal">ARRAY[1,1]</code> are
+ each considered to contain the other.)
+ </p>
+ <p>
+ <code class="literal">ARRAY[1,4,3] @&gt; ARRAY[3,1,3]</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyarray</code> <code class="literal">&lt;@</code> <code class="type">anyarray</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first array contained by the second?
+ </p>
+ <p>
+ <code class="literal">ARRAY[2,2,7] &lt;@ ARRAY[1,7,4,2,6]</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyarray</code> <code class="literal">&amp;&amp;</code> <code class="type">anyarray</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do the arrays overlap, that is, have any elements in common?
+ </p>
+ <p>
+ <code class="literal">ARRAY[1,4,3] &amp;&amp; ARRAY[2,1]</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anycompatiblearray</code> <code class="literal">||</code> <code class="type">anycompatiblearray</code>
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Concatenates the two arrays. Concatenating a null or empty array is a
+ no-op; otherwise the arrays must have the same number of dimensions
+ (as illustrated by the first example) or differ in number of
+ dimensions by one (as illustrated by the second).
+ If the arrays are not of identical element types, they will be coerced
+ to a common type (see <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a>).
+ </p>
+ <p>
+ <code class="literal">ARRAY[1,2,3] || ARRAY[4,5,6,7]</code>
+ → <code class="returnvalue">{1,2,3,4,5,6,7}</code>
+ </p>
+ <p>
+ <code class="literal">ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]]</code>
+ → <code class="returnvalue">{{1,2,3},{4,5,6},{7,8,9.9}}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anycompatible</code> <code class="literal">||</code> <code class="type">anycompatiblearray</code>
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Concatenates an element onto the front of an array (which must be
+ empty or one-dimensional).
+ </p>
+ <p>
+ <code class="literal">3 || ARRAY[4,5,6]</code>
+ → <code class="returnvalue">{3,4,5,6}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anycompatiblearray</code> <code class="literal">||</code> <code class="type">anycompatible</code>
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Concatenates an element onto the end of an array (which must be
+ empty or one-dimensional).
+ </p>
+ <p>
+ <code class="literal">ARRAY[4,5,6] || 7</code>
+ → <code class="returnvalue">{4,5,6,7}</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ See <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a> for more details about array operator
+ behavior. See <a class="xref" href="indexes-types.html" title="11.2. Index Types">Section 11.2</a> for more details about
+ which operators support indexed operations.
+ </p><p>
+ <a class="xref" href="functions-array.html#ARRAY-FUNCTIONS-TABLE" title="Table 9.53. Array Functions">Table 9.53</a> shows the functions
+ available for use with array types. See <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a>
+ for more information and examples of the use of these functions.
+ </p><div class="table" id="ARRAY-FUNCTIONS-TABLE"><p class="title"><strong>Table 9.53. Array Functions</strong></p><div class="table-contents"><table class="table" summary="Array Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">array_append</code> ( <code class="type">anycompatiblearray</code>, <code class="type">anycompatible</code> )
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Appends an element to the end of an array (same as
+ the <code class="type">anycompatiblearray</code> <code class="literal">||</code> <code class="type">anycompatible</code>
+ operator).
+ </p>
+ <p>
+ <code class="literal">array_append(ARRAY[1,2], 3)</code>
+ → <code class="returnvalue">{1,2,3}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">array_cat</code> ( <code class="type">anycompatiblearray</code>, <code class="type">anycompatiblearray</code> )
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Concatenates two arrays (same as
+ the <code class="type">anycompatiblearray</code> <code class="literal">||</code> <code class="type">anycompatiblearray</code>
+ operator).
+ </p>
+ <p>
+ <code class="literal">array_cat(ARRAY[1,2,3], ARRAY[4,5])</code>
+ → <code class="returnvalue">{1,2,3,4,5}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">array_dims</code> ( <code class="type">anyarray</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns a text representation of the array's dimensions.
+ </p>
+ <p>
+ <code class="literal">array_dims(ARRAY[[1,2,3], [4,5,6]])</code>
+ → <code class="returnvalue">[1:2][1:3]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">array_fill</code> ( <code class="type">anyelement</code>, <code class="type">integer[]</code>
+ [<span class="optional">, <code class="type">integer[]</code> </span>] )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Returns an array filled with copies of the given value, having
+ dimensions of the lengths specified by the second argument.
+ The optional third argument supplies lower-bound values for each
+ dimension (which default to all <code class="literal">1</code>).
+ </p>
+ <p>
+ <code class="literal">array_fill(11, ARRAY[2,3])</code>
+ → <code class="returnvalue">{{11,11,11},{11,11,11}}</code>
+ </p>
+ <p>
+ <code class="literal">array_fill(7, ARRAY[3], ARRAY[2])</code>
+ → <code class="returnvalue">[2:4]={7,7,7}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">array_length</code> ( <code class="type">anyarray</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the length of the requested array dimension.
+ (Produces NULL instead of 0 for empty or missing array dimensions.)
+ </p>
+ <p>
+ <code class="literal">array_length(array[1,2,3], 1)</code>
+ → <code class="returnvalue">3</code>
+ </p>
+ <p>
+ <code class="literal">array_length(array[]::int[], 1)</code>
+ → <code class="returnvalue">NULL</code>
+ </p>
+ <p>
+ <code class="literal">array_length(array['text'], 2)</code>
+ → <code class="returnvalue">NULL</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">array_lower</code> ( <code class="type">anyarray</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the lower bound of the requested array dimension.
+ </p>
+ <p>
+ <code class="literal">array_lower('[0:2]={1,2,3}'::integer[], 1)</code>
+ → <code class="returnvalue">0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">array_ndims</code> ( <code class="type">anyarray</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of dimensions of the array.
+ </p>
+ <p>
+ <code class="literal">array_ndims(ARRAY[[1,2,3], [4,5,6]])</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">array_position</code> ( <code class="type">anycompatiblearray</code>, <code class="type">anycompatible</code> [<span class="optional">, <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the subscript of the first occurrence of the second argument
+ in the array, or <code class="literal">NULL</code> if it's not present.
+ If the third argument is given, the search begins at that subscript.
+ The array must be one-dimensional.
+ Comparisons are done using <code class="literal">IS NOT DISTINCT FROM</code>
+ semantics, so it is possible to search for <code class="literal">NULL</code>.
+ </p>
+ <p>
+ <code class="literal">array_position(ARRAY['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'], 'mon')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">array_positions</code> ( <code class="type">anycompatiblearray</code>, <code class="type">anycompatible</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Returns an array of the subscripts of all occurrences of the second
+ argument in the array given as first argument.
+ The array must be one-dimensional.
+ Comparisons are done using <code class="literal">IS NOT DISTINCT FROM</code>
+ semantics, so it is possible to search for <code class="literal">NULL</code>.
+ <code class="literal">NULL</code> is returned only if the array
+ is <code class="literal">NULL</code>; if the value is not found in the array, an
+ empty array is returned.
+ </p>
+ <p>
+ <code class="literal">array_positions(ARRAY['A','A','B','A'], 'A')</code>
+ → <code class="returnvalue">{1,2,4}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">array_prepend</code> ( <code class="type">anycompatible</code>, <code class="type">anycompatiblearray</code> )
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Prepends an element to the beginning of an array (same as
+ the <code class="type">anycompatible</code> <code class="literal">||</code> <code class="type">anycompatiblearray</code>
+ operator).
+ </p>
+ <p>
+ <code class="literal">array_prepend(1, ARRAY[2,3])</code>
+ → <code class="returnvalue">{1,2,3}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">array_remove</code> ( <code class="type">anycompatiblearray</code>, <code class="type">anycompatible</code> )
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Removes all elements equal to the given value from the array.
+ The array must be one-dimensional.
+ Comparisons are done using <code class="literal">IS NOT DISTINCT FROM</code>
+ semantics, so it is possible to remove <code class="literal">NULL</code>s.
+ </p>
+ <p>
+ <code class="literal">array_remove(ARRAY[1,2,3,2], 2)</code>
+ → <code class="returnvalue">{1,3}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">array_replace</code> ( <code class="type">anycompatiblearray</code>, <code class="type">anycompatible</code>, <code class="type">anycompatible</code> )
+ → <code class="returnvalue">anycompatiblearray</code>
+ </p>
+ <p>
+ Replaces each array element equal to the second argument with the
+ third argument.
+ </p>
+ <p>
+ <code class="literal">array_replace(ARRAY[1,2,5,4], 5, 3)</code>
+ → <code class="returnvalue">{1,2,3,4}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="FUNCTION-ARRAY-TO-STRING" class="indexterm"></a>
+ <code class="function">array_to_string</code> ( <em class="parameter"><code>array</code></em> <code class="type">anyarray</code>, <em class="parameter"><code>delimiter</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>null_string</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts each array element to its text representation, and
+ concatenates those separated by
+ the <em class="parameter"><code>delimiter</code></em> string.
+ If <em class="parameter"><code>null_string</code></em> is given and is
+ not <code class="literal">NULL</code>, then <code class="literal">NULL</code> array
+ entries are represented by that string; otherwise, they are omitted.
+ See also <a class="link" href="functions-string.html#FUNCTION-STRING-TO-ARRAY"><code class="function">string_to_array</code></a>.
+ </p>
+ <p>
+ <code class="literal">array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*')</code>
+ → <code class="returnvalue">1,2,3,*,5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">array_upper</code> ( <code class="type">anyarray</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the upper bound of the requested array dimension.
+ </p>
+ <p>
+ <code class="literal">array_upper(ARRAY[1,8,3,7], 1)</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">cardinality</code> ( <code class="type">anyarray</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the total number of elements in the array, or 0 if the array
+ is empty.
+ </p>
+ <p>
+ <code class="literal">cardinality(ARRAY[[1,2],[3,4]])</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">trim_array</code> ( <em class="parameter"><code>array</code></em> <code class="type">anyarray</code>, <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Trims an array by removing the last <em class="parameter"><code>n</code></em> elements.
+ If the array is multidimensional, only the first dimension is trimmed.
+ </p>
+ <p>
+ <code class="literal">trim_array(ARRAY[1,2,3,4,5,6], 2)</code>
+ → <code class="returnvalue">{1,2,3,4}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.25.6.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">unnest</code> ( <code class="type">anyarray</code> )
+ → <code class="returnvalue">setof anyelement</code>
+ </p>
+ <p>
+ Expands an array into a set of rows.
+ The array's elements are read out in storage order.
+ </p>
+ <p>
+ <code class="literal">unnest(ARRAY[1,2])</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ 1
+ 2
+</pre><p>
+ </p>
+ <p>
+ <code class="literal">unnest(ARRAY[['foo','bar'],['baz','quux']])</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ foo
+ bar
+ baz
+ quux
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">unnest</code> ( <code class="type">anyarray</code>, <code class="type">anyarray</code> [<span class="optional">, ... </span>] )
+ → <code class="returnvalue">setof anyelement, anyelement [, ... ]</code>
+ </p>
+ <p>
+ Expands multiple arrays (possibly of different data types) into a set of
+ rows. If the arrays are not all the same length then the shorter ones
+ are padded with <code class="literal">NULL</code>s. This form is only allowed
+ in a query's FROM clause; see <a class="xref" href="queries-table-expressions.html#QUERIES-TABLEFUNCTIONS" title="7.2.1.4. Table Functions">Section 7.2.1.4</a>.
+ </p>
+ <p>
+ <code class="literal">select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b)</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ a | b
+---+-----
+ 1 | foo
+ 2 | bar
+ | baz
+</pre><p>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ See also <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a> about the aggregate
+ function <code class="function">array_agg</code> for use with arrays.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-conditional.html" title="9.18. Conditional Expressions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-range.html" title="9.20. Range/Multirange Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.18. Conditional Expressions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.20. Range/Multirange Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-binarystring.html b/doc/src/sgml/html/functions-binarystring.html
new file mode 100644
index 0000000..b0ca26b
--- /dev/null
+++ b/doc/src/sgml/html/functions-binarystring.html
@@ -0,0 +1,510 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.5. Binary String Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-string.html" title="9.4. String Functions and Operators" /><link rel="next" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.5. Binary String Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-string.html" title="9.4. String Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-BINARYSTRING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.5. Binary String Functions and Operators</h2></div></div></div><a id="id-1.5.8.11.2" class="indexterm"></a><p>
+ This section describes functions and operators for examining and
+ manipulating binary strings, that is values of type <code class="type">bytea</code>.
+ Many of these are equivalent, in purpose and syntax, to the
+ text-string functions described in the previous section.
+ </p><p>
+ <acronym class="acronym">SQL</acronym> defines some string functions that use
+ key words, rather than commas, to separate
+ arguments. Details are in
+ <a class="xref" href="functions-binarystring.html#FUNCTIONS-BINARYSTRING-SQL" title="Table 9.11. SQL Binary String Functions and Operators">Table 9.11</a>.
+ <span class="productname">PostgreSQL</span> also provides versions of these functions
+ that use the regular function invocation syntax
+ (see <a class="xref" href="functions-binarystring.html#FUNCTIONS-BINARYSTRING-OTHER" title="Table 9.12. Other Binary String Functions">Table 9.12</a>).
+ </p><div class="table" id="FUNCTIONS-BINARYSTRING-SQL"><p class="title"><strong>Table 9.11. <acronym class="acronym">SQL</acronym> Binary String Functions and Operators</strong></p><div class="table-contents"><table class="table" summary="SQL Binary String Functions and Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function/Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="type">bytea</code> <code class="literal">||</code> <code class="type">bytea</code>
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Concatenates the two binary strings.
+ </p>
+ <p>
+ <code class="literal">'\x123456'::bytea || '\x789a00bcde'::bytea</code>
+ → <code class="returnvalue">\x123456789a00bcde</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">bit_length</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bits in the binary string (8
+ times the <code class="function">octet_length</code>).
+ </p>
+ <p>
+ <code class="literal">bit_length('\x123456'::bytea)</code>
+ → <code class="returnvalue">24</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">octet_length</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bytes in the binary string.
+ </p>
+ <p>
+ <code class="literal">octet_length('\x123456'::bytea)</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">overlay</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code> <code class="literal">PLACING</code> <em class="parameter"><code>newsubstring</code></em> <code class="type">bytea</code> <code class="literal">FROM</code> <em class="parameter"><code>start</code></em> <code class="type">integer</code> [<span class="optional"> <code class="literal">FOR</code> <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Replaces the substring of <em class="parameter"><code>bytes</code></em> that starts at
+ the <em class="parameter"><code>start</code></em>'th byte and extends
+ for <em class="parameter"><code>count</code></em> bytes
+ with <em class="parameter"><code>newsubstring</code></em>.
+ If <em class="parameter"><code>count</code></em> is omitted, it defaults to the length
+ of <em class="parameter"><code>newsubstring</code></em>.
+ </p>
+ <p>
+ <code class="literal">overlay('\x1234567890'::bytea placing '\002\003'::bytea from 2 for 3)</code>
+ → <code class="returnvalue">\x12020390</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">position</code> ( <em class="parameter"><code>substring</code></em> <code class="type">bytea</code> <code class="literal">IN</code> <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns first starting index of the specified
+ <em class="parameter"><code>substring</code></em> within
+ <em class="parameter"><code>bytes</code></em>, or zero if it's not present.
+ </p>
+ <p>
+ <code class="literal">position('\x5678'::bytea in '\x1234567890'::bytea)</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">substring</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code> [<span class="optional"> <code class="literal">FROM</code> <em class="parameter"><code>start</code></em> <code class="type">integer</code> </span>] [<span class="optional"> <code class="literal">FOR</code> <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Extracts the substring of <em class="parameter"><code>bytes</code></em> starting at
+ the <em class="parameter"><code>start</code></em>'th byte if that is specified,
+ and stopping after <em class="parameter"><code>count</code></em> bytes if that is
+ specified. Provide at least one of <em class="parameter"><code>start</code></em>
+ and <em class="parameter"><code>count</code></em>.
+ </p>
+ <p>
+ <code class="literal">substring('\x1234567890'::bytea from 3 for 2)</code>
+ → <code class="returnvalue">\x5678</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.5.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">trim</code> ( [<span class="optional"> <code class="literal">LEADING</code> | <code class="literal">TRAILING</code> | <code class="literal">BOTH</code> </span>]
+ <em class="parameter"><code>bytesremoved</code></em> <code class="type">bytea</code> <code class="literal">FROM</code>
+ <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Removes the longest string containing only bytes appearing in
+ <em class="parameter"><code>bytesremoved</code></em> from the start,
+ end, or both ends (<code class="literal">BOTH</code> is the default)
+ of <em class="parameter"><code>bytes</code></em>.
+ </p>
+ <p>
+ <code class="literal">trim('\x9012'::bytea from '\x1234567890'::bytea)</code>
+ → <code class="returnvalue">\x345678</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">trim</code> ( [<span class="optional"> <code class="literal">LEADING</code> | <code class="literal">TRAILING</code> | <code class="literal">BOTH</code> </span>] [<span class="optional"> <code class="literal">FROM</code> </span>]
+ <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>bytesremoved</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ This is a non-standard syntax for <code class="function">trim()</code>.
+ </p>
+ <p>
+ <code class="literal">trim(both from '\x1234567890'::bytea, '\x9012'::bytea)</code>
+ → <code class="returnvalue">\x345678</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Additional binary string manipulation functions are available and
+ are listed in <a class="xref" href="functions-binarystring.html#FUNCTIONS-BINARYSTRING-OTHER" title="Table 9.12. Other Binary String Functions">Table 9.12</a>. Some
+ of them are used internally to implement the
+ <acronym class="acronym">SQL</acronym>-standard string functions listed in <a class="xref" href="functions-binarystring.html#FUNCTIONS-BINARYSTRING-SQL" title="Table 9.11. SQL Binary String Functions and Operators">Table 9.11</a>.
+ </p><div class="table" id="FUNCTIONS-BINARYSTRING-OTHER"><p class="title"><strong>Table 9.12. Other Binary String Functions</strong></p><div class="table-contents"><table class="table" summary="Other Binary String Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.1.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.11.7.2.2.1.1.1.2" class="indexterm"></a>
+ <code class="function">bit_count</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the number of bits set in the binary string (also known as
+ <span class="quote">“<span class="quote">popcount</span>”</span>).
+ </p>
+ <p>
+ <code class="literal">bit_count('\x1234567890'::bytea)</code>
+ → <code class="returnvalue">15</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">btrim</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>bytesremoved</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Removes the longest string containing only bytes appearing in
+ <em class="parameter"><code>bytesremoved</code></em> from the start and end of
+ <em class="parameter"><code>bytes</code></em>.
+ </p>
+ <p>
+ <code class="literal">btrim('\x1234567890'::bytea, '\x9012'::bytea)</code>
+ → <code class="returnvalue">\x345678</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">get_bit</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">bigint</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Extracts <a class="link" href="functions-binarystring.html#FUNCTIONS-ZEROBASED-NOTE">n'th</a> bit
+ from binary string.
+ </p>
+ <p>
+ <code class="literal">get_bit('\x1234567890'::bytea, 30)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">get_byte</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Extracts <a class="link" href="functions-binarystring.html#FUNCTIONS-ZEROBASED-NOTE">n'th</a> byte
+ from binary string.
+ </p>
+ <p>
+ <code class="literal">get_byte('\x1234567890'::bytea, 4)</code>
+ → <code class="returnvalue">144</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.5.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.11.7.2.2.5.1.1.2" class="indexterm"></a>
+ <a id="id-1.5.8.11.7.2.2.5.1.1.3" class="indexterm"></a>
+ <code class="function">length</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of bytes in the binary string.
+ </p>
+ <p>
+ <code class="literal">length('\x1234567890'::bytea)</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">length</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>encoding</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of characters in the binary string, assuming
+ that it is text in the given <em class="parameter"><code>encoding</code></em>.
+ </p>
+ <p>
+ <code class="literal">length('jose'::bytea, 'UTF8')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">ltrim</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>bytesremoved</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Removes the longest string containing only bytes appearing in
+ <em class="parameter"><code>bytesremoved</code></em> from the start of
+ <em class="parameter"><code>bytes</code></em>.
+ </p>
+ <p>
+ <code class="literal">ltrim('\x1234567890'::bytea, '\x9012'::bytea)</code>
+ → <code class="returnvalue">\x34567890</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">md5</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Computes the MD5 <a class="link" href="functions-binarystring.html#FUNCTIONS-HASH-NOTE">hash</a> of
+ the binary string, with the result written in hexadecimal.
+ </p>
+ <p>
+ <code class="literal">md5('Th\000omas'::bytea)</code>
+ → <code class="returnvalue">8ab2d3c9689aaf18​b4958c334c82d8b1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">rtrim</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>bytesremoved</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Removes the longest string containing only bytes appearing in
+ <em class="parameter"><code>bytesremoved</code></em> from the end of
+ <em class="parameter"><code>bytes</code></em>.
+ </p>
+ <p>
+ <code class="literal">rtrim('\x1234567890'::bytea, '\x9012'::bytea)</code>
+ → <code class="returnvalue">\x12345678</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">set_bit</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">bigint</code>,
+ <em class="parameter"><code>newvalue</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Sets <a class="link" href="functions-binarystring.html#FUNCTIONS-ZEROBASED-NOTE">n'th</a> bit in
+ binary string to <em class="parameter"><code>newvalue</code></em>.
+ </p>
+ <p>
+ <code class="literal">set_bit('\x1234567890'::bytea, 30, 0)</code>
+ → <code class="returnvalue">\x1234563890</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">set_byte</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>newvalue</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Sets <a class="link" href="functions-binarystring.html#FUNCTIONS-ZEROBASED-NOTE">n'th</a> byte in
+ binary string to <em class="parameter"><code>newvalue</code></em>.
+ </p>
+ <p>
+ <code class="literal">set_byte('\x1234567890'::bytea, 4, 64)</code>
+ → <code class="returnvalue">\x1234567840</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">sha224</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Computes the SHA-224 <a class="link" href="functions-binarystring.html#FUNCTIONS-HASH-NOTE">hash</a>
+ of the binary string.
+ </p>
+ <p>
+ <code class="literal">sha224('abc'::bytea)</code>
+ → <code class="returnvalue">\x23097d223405d8228642a477bda2​55b32aadbce4bda0b3f7e36c9da7</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">sha256</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Computes the SHA-256 <a class="link" href="functions-binarystring.html#FUNCTIONS-HASH-NOTE">hash</a>
+ of the binary string.
+ </p>
+ <p>
+ <code class="literal">sha256('abc'::bytea)</code>
+ → <code class="returnvalue">\xba7816bf8f01cfea414140de5dae2223​b00361a396177a9cb410ff61f20015ad</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">sha384</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Computes the SHA-384 <a class="link" href="functions-binarystring.html#FUNCTIONS-HASH-NOTE">hash</a>
+ of the binary string.
+ </p>
+ <p>
+ <code class="literal">sha384('abc'::bytea)</code>
+ → <code class="returnvalue">\xcb00753f45a35e8bb5a03d699ac65007​272c32ab0eded1631a8b605a43ff5bed​8086072ba1e7cc2358baeca134c825a7</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">sha512</code> ( <code class="type">bytea</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Computes the SHA-512 <a class="link" href="functions-binarystring.html#FUNCTIONS-HASH-NOTE">hash</a>
+ of the binary string.
+ </p>
+ <p>
+ <code class="literal">sha512('abc'::bytea)</code>
+ → <code class="returnvalue">\xddaf35a193617abacc417349ae204131​12e6fa4e89a97ea20a9eeee64b55d39a​2192992a274fc1a836ba3c23a3feebbd​454d4423643ce80e2a9ac94fa54ca49f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.7.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">substr</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>, <em class="parameter"><code>start</code></em> <code class="type">integer</code> [<span class="optional">, <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Extracts the substring of <em class="parameter"><code>bytes</code></em> starting at
+ the <em class="parameter"><code>start</code></em>'th byte,
+ and extending for <em class="parameter"><code>count</code></em> bytes if that is
+ specified. (Same
+ as <code class="literal">substring(<em class="parameter"><code>bytes</code></em>
+ from <em class="parameter"><code>start</code></em>
+ for <em class="parameter"><code>count</code></em>)</code>.)
+ </p>
+ <p>
+ <code class="literal">substr('\x1234567890'::bytea, 3, 2)</code>
+ → <code class="returnvalue">\x5678</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p id="FUNCTIONS-ZEROBASED-NOTE">
+ Functions <code class="function">get_byte</code> and <code class="function">set_byte</code>
+ number the first byte of a binary string as byte 0.
+ Functions <code class="function">get_bit</code> and <code class="function">set_bit</code>
+ number bits from the right within each byte; for example bit 0 is the least
+ significant bit of the first byte, and bit 15 is the most significant bit
+ of the second byte.
+ </p><p id="FUNCTIONS-HASH-NOTE">
+ For historical reasons, the function <code class="function">md5</code>
+ returns a hex-encoded value of type <code class="type">text</code> whereas the SHA-2
+ functions return type <code class="type">bytea</code>. Use the functions
+ <a class="link" href="functions-binarystring.html#FUNCTION-ENCODE"><code class="function">encode</code></a>
+ and <a class="link" href="functions-binarystring.html#FUNCTION-DECODE"><code class="function">decode</code></a> to
+ convert between the two. For example write <code class="literal">encode(sha256('abc'),
+ 'hex')</code> to get a hex-encoded text representation,
+ or <code class="literal">decode(md5('abc'), 'hex')</code> to get
+ a <code class="type">bytea</code> value.
+ </p><p>
+ <a id="id-1.5.8.11.10.1" class="indexterm"></a>
+ <a id="id-1.5.8.11.10.2" class="indexterm"></a>
+ Functions for converting strings between different character sets
+ (encodings), and for representing arbitrary binary data in textual
+ form, are shown in
+ <a class="xref" href="functions-binarystring.html#FUNCTIONS-BINARYSTRING-CONVERSIONS" title="Table 9.13. Text/Binary String Conversion Functions">Table 9.13</a>. For these
+ functions, an argument or result of type <code class="type">text</code> is expressed
+ in the database's default encoding, while arguments or results of
+ type <code class="type">bytea</code> are in an encoding named by another argument.
+ </p><div class="table" id="FUNCTIONS-BINARYSTRING-CONVERSIONS"><p class="title"><strong>Table 9.13. Text/Binary String Conversion Functions</strong></p><div class="table-contents"><table class="table" summary="Text/Binary String Conversion Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.11.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">convert</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>src_encoding</code></em> <code class="type">name</code>,
+ <em class="parameter"><code>dest_encoding</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Converts a binary string representing text in
+ encoding <em class="parameter"><code>src_encoding</code></em>
+ to a binary string in encoding <em class="parameter"><code>dest_encoding</code></em>
+ (see <a class="xref" href="multibyte.html#MULTIBYTE-CONVERSIONS-SUPPORTED" title="24.3.4. Available Character Set Conversions">Section 24.3.4</a> for
+ available conversions).
+ </p>
+ <p>
+ <code class="literal">convert('text_in_utf8', 'UTF8', 'LATIN1')</code>
+ → <code class="returnvalue">\x746578745f696e5f75746638</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.11.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">convert_from</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>src_encoding</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts a binary string representing text in
+ encoding <em class="parameter"><code>src_encoding</code></em>
+ to <code class="type">text</code> in the database encoding
+ (see <a class="xref" href="multibyte.html#MULTIBYTE-CONVERSIONS-SUPPORTED" title="24.3.4. Available Character Set Conversions">Section 24.3.4</a> for
+ available conversions).
+ </p>
+ <p>
+ <code class="literal">convert_from('text_in_utf8', 'UTF8')</code>
+ → <code class="returnvalue">text_in_utf8</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.11.11.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">convert_to</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>dest_encoding</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Converts a <code class="type">text</code> string (in the database encoding) to a
+ binary string encoded in encoding <em class="parameter"><code>dest_encoding</code></em>
+ (see <a class="xref" href="multibyte.html#MULTIBYTE-CONVERSIONS-SUPPORTED" title="24.3.4. Available Character Set Conversions">Section 24.3.4</a> for
+ available conversions).
+ </p>
+ <p>
+ <code class="literal">convert_to('some_text', 'UTF8')</code>
+ → <code class="returnvalue">\x736f6d655f74657874</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="FUNCTION-ENCODE" class="indexterm"></a>
+ <code class="function">encode</code> ( <em class="parameter"><code>bytes</code></em> <code class="type">bytea</code>,
+ <em class="parameter"><code>format</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Encodes binary data into a textual representation; supported
+ <em class="parameter"><code>format</code></em> values are:
+ <a class="link" href="functions-binarystring.html#ENCODE-FORMAT-BASE64"><code class="literal">base64</code></a>,
+ <a class="link" href="functions-binarystring.html#ENCODE-FORMAT-ESCAPE"><code class="literal">escape</code></a>,
+ <a class="link" href="functions-binarystring.html#ENCODE-FORMAT-HEX"><code class="literal">hex</code></a>.
+ </p>
+ <p>
+ <code class="literal">encode('123\000\001', 'base64')</code>
+ → <code class="returnvalue">MTIzAAE=</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="FUNCTION-DECODE" class="indexterm"></a>
+ <code class="function">decode</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>format</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Decodes binary data from a textual representation; supported
+ <em class="parameter"><code>format</code></em> values are the same as
+ for <code class="function">encode</code>.
+ </p>
+ <p>
+ <code class="literal">decode('MTIzAAE=', 'base64')</code>
+ → <code class="returnvalue">\x3132330001</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="function">encode</code> and <code class="function">decode</code>
+ functions support the following textual formats:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="ENCODE-FORMAT-BASE64"><span class="term">base64
+ <a id="id-1.5.8.11.12.3.1.1.1" class="indexterm"></a></span></dt><dd><p>
+ The <code class="literal">base64</code> format is that
+ of <a class="ulink" href="https://tools.ietf.org/html/rfc2045#section-6.8" target="_top">RFC
+ 2045 Section 6.8</a>. As per the <acronym class="acronym">RFC</acronym>, encoded lines are
+ broken at 76 characters. However instead of the MIME CRLF
+ end-of-line marker, only a newline is used for end-of-line.
+ The <code class="function">decode</code> function ignores carriage-return,
+ newline, space, and tab characters. Otherwise, an error is
+ raised when <code class="function">decode</code> is supplied invalid
+ base64 data — including when trailing padding is incorrect.
+ </p></dd><dt id="ENCODE-FORMAT-ESCAPE"><span class="term">escape
+ <a id="id-1.5.8.11.12.3.2.1.1" class="indexterm"></a></span></dt><dd><p>
+ The <code class="literal">escape</code> format converts zero bytes and
+ bytes with the high bit set into octal escape sequences
+ (<code class="literal">\</code><em class="replaceable"><code>nnn</code></em>), and it doubles
+ backslashes. Other byte values are represented literally.
+ The <code class="function">decode</code> function will raise an error if a
+ backslash is not followed by either a second backslash or three
+ octal digits; it accepts other byte values unchanged.
+ </p></dd><dt id="ENCODE-FORMAT-HEX"><span class="term">hex
+ <a id="id-1.5.8.11.12.3.3.1.1" class="indexterm"></a></span></dt><dd><p>
+ The <code class="literal">hex</code> format represents each 4 bits of
+ data as one hexadecimal digit, <code class="literal">0</code>
+ through <code class="literal">f</code>, writing the higher-order digit of
+ each byte first. The <code class="function">encode</code> function outputs
+ the <code class="literal">a</code>-<code class="literal">f</code> hex digits in lower
+ case. Because the smallest unit of data is 8 bits, there are
+ always an even number of characters returned
+ by <code class="function">encode</code>.
+ The <code class="function">decode</code> function
+ accepts the <code class="literal">a</code>-<code class="literal">f</code> characters in
+ either upper or lower case. An error is raised
+ when <code class="function">decode</code> is given invalid hex data
+ — including when given an odd number of characters.
+ </p></dd></dl></div><p>
+ </p><p>
+ See also the aggregate function <code class="function">string_agg</code> in
+ <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a> and the large object functions
+ in <a class="xref" href="lo-funcs.html" title="35.4. Server-Side Functions">Section 35.4</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-string.html" title="9.4. String Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.4. String Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.6. Bit String Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-bitstring.html b/doc/src/sgml/html/functions-bitstring.html
new file mode 100644
index 0000000..d602227
--- /dev/null
+++ b/doc/src/sgml/html/functions-bitstring.html
@@ -0,0 +1,235 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.6. Bit String Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-binarystring.html" title="9.5. Binary String Functions and Operators" /><link rel="next" href="functions-matching.html" title="9.7. Pattern Matching" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.6. Bit String Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-binarystring.html" title="9.5. Binary String Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-matching.html" title="9.7. Pattern Matching">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-BITSTRING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.6. Bit String Functions and Operators</h2></div></div></div><a id="id-1.5.8.12.2" class="indexterm"></a><p>
+ This section describes functions and operators for examining and
+ manipulating bit strings, that is values of the types
+ <code class="type">bit</code> and <code class="type">bit varying</code>. (While only
+ type <code class="type">bit</code> is mentioned in these tables, values of
+ type <code class="type">bit varying</code> can be used interchangeably.)
+ Bit strings support the usual comparison operators shown in
+ <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a>, as well as the
+ operators shown in <a class="xref" href="functions-bitstring.html#FUNCTIONS-BIT-STRING-OP-TABLE" title="Table 9.14. Bit String Operators">Table 9.14</a>.
+ </p><div class="table" id="FUNCTIONS-BIT-STRING-OP-TABLE"><p class="title"><strong>Table 9.14. Bit String Operators</strong></p><div class="table-contents"><table class="table" summary="Bit String Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bit</code> <code class="literal">||</code> <code class="type">bit</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Concatenation
+ </p>
+ <p>
+ <code class="literal">B'10001' || B'011'</code>
+ → <code class="returnvalue">10001011</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bit</code> <code class="literal">&amp;</code> <code class="type">bit</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Bitwise AND (inputs must be of equal length)
+ </p>
+ <p>
+ <code class="literal">B'10001' &amp; B'01101'</code>
+ → <code class="returnvalue">00001</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bit</code> <code class="literal">|</code> <code class="type">bit</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Bitwise OR (inputs must be of equal length)
+ </p>
+ <p>
+ <code class="literal">B'10001' | B'01101'</code>
+ → <code class="returnvalue">11101</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bit</code> <code class="literal">#</code> <code class="type">bit</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Bitwise exclusive OR (inputs must be of equal length)
+ </p>
+ <p>
+ <code class="literal">B'10001' # B'01101'</code>
+ → <code class="returnvalue">11100</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">~</code> <code class="type">bit</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Bitwise NOT
+ </p>
+ <p>
+ <code class="literal">~ B'10001'</code>
+ → <code class="returnvalue">01110</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bit</code> <code class="literal">&lt;&lt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Bitwise shift left
+ (string length is preserved)
+ </p>
+ <p>
+ <code class="literal">B'10001' &lt;&lt; 3</code>
+ → <code class="returnvalue">01000</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bit</code> <code class="literal">&gt;&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Bitwise shift right
+ (string length is preserved)
+ </p>
+ <p>
+ <code class="literal">B'10001' &gt;&gt; 2</code>
+ → <code class="returnvalue">00100</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Some of the functions available for binary strings are also available
+ for bit strings, as shown in <a class="xref" href="functions-bitstring.html#FUNCTIONS-BIT-STRING-TABLE" title="Table 9.15. Bit String Functions">Table 9.15</a>.
+ </p><div class="table" id="FUNCTIONS-BIT-STRING-TABLE"><p class="title"><strong>Table 9.15. Bit String Functions</strong></p><div class="table-contents"><table class="table" summary="Bit String Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">bit_count</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the number of bits set in the bit string (also known as
+ <span class="quote">“<span class="quote">popcount</span>”</span>).
+ </p>
+ <p>
+ <code class="literal">bit_count(B'10111')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">bit_length</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bits in the bit string.
+ </p>
+ <p>
+ <code class="literal">bit_length(B'10111')</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.3.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.12.6.2.2.3.1.1.2" class="indexterm"></a>
+ <code class="function">length</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bits in the bit string.
+ </p>
+ <p>
+ <code class="literal">length(B'10111')</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">octet_length</code> ( <code class="type">bit</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bytes in the bit string.
+ </p>
+ <p>
+ <code class="literal">octet_length(B'1011111011')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">overlay</code> ( <em class="parameter"><code>bits</code></em> <code class="type">bit</code> <code class="literal">PLACING</code> <em class="parameter"><code>newsubstring</code></em> <code class="type">bit</code> <code class="literal">FROM</code> <em class="parameter"><code>start</code></em> <code class="type">integer</code> [<span class="optional"> <code class="literal">FOR</code> <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Replaces the substring of <em class="parameter"><code>bits</code></em> that starts at
+ the <em class="parameter"><code>start</code></em>'th bit and extends
+ for <em class="parameter"><code>count</code></em> bits
+ with <em class="parameter"><code>newsubstring</code></em>.
+ If <em class="parameter"><code>count</code></em> is omitted, it defaults to the length
+ of <em class="parameter"><code>newsubstring</code></em>.
+ </p>
+ <p>
+ <code class="literal">overlay(B'01010101010101010' placing B'11111' from 2 for 3)</code>
+ → <code class="returnvalue">0111110101010101010</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">position</code> ( <em class="parameter"><code>substring</code></em> <code class="type">bit</code> <code class="literal">IN</code> <em class="parameter"><code>bits</code></em> <code class="type">bit</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns first starting index of the specified <em class="parameter"><code>substring</code></em>
+ within <em class="parameter"><code>bits</code></em>, or zero if it's not present.
+ </p>
+ <p>
+ <code class="literal">position(B'010' in B'000001101011')</code>
+ → <code class="returnvalue">8</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">substring</code> ( <em class="parameter"><code>bits</code></em> <code class="type">bit</code> [<span class="optional"> <code class="literal">FROM</code> <em class="parameter"><code>start</code></em> <code class="type">integer</code> </span>] [<span class="optional"> <code class="literal">FOR</code> <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Extracts the substring of <em class="parameter"><code>bits</code></em> starting at
+ the <em class="parameter"><code>start</code></em>'th bit if that is specified,
+ and stopping after <em class="parameter"><code>count</code></em> bits if that is
+ specified. Provide at least one of <em class="parameter"><code>start</code></em>
+ and <em class="parameter"><code>count</code></em>.
+ </p>
+ <p>
+ <code class="literal">substring(B'110010111111' from 3 for 2)</code>
+ → <code class="returnvalue">00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">get_bit</code> ( <em class="parameter"><code>bits</code></em> <code class="type">bit</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Extracts <em class="parameter"><code>n</code></em>'th bit
+ from bit string; the first (leftmost) bit is bit 0.
+ </p>
+ <p>
+ <code class="literal">get_bit(B'101010101010101010', 6)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.12.6.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">set_bit</code> ( <em class="parameter"><code>bits</code></em> <code class="type">bit</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>newvalue</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">bit</code>
+ </p>
+ <p>
+ Sets <em class="parameter"><code>n</code></em>'th bit in
+ bit string to <em class="parameter"><code>newvalue</code></em>;
+ the first (leftmost) bit is bit 0.
+ </p>
+ <p>
+ <code class="literal">set_bit(B'101010101010101010', 6, 0)</code>
+ → <code class="returnvalue">101010001010101010</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In addition, it is possible to cast integral values to and from type
+ <code class="type">bit</code>.
+ Casting an integer to <code class="type">bit(n)</code> copies the rightmost
+ <code class="literal">n</code> bits. Casting an integer to a bit string width wider
+ than the integer itself will sign-extend on the left.
+ Some examples:
+</p><pre class="programlisting">
+44::bit(10) <em class="lineannotation"><span class="lineannotation">0000101100</span></em>
+44::bit(3) <em class="lineannotation"><span class="lineannotation">100</span></em>
+cast(-44 as bit(12)) <em class="lineannotation"><span class="lineannotation">111111010100</span></em>
+'1110'::bit(4)::integer <em class="lineannotation"><span class="lineannotation">14</span></em>
+</pre><p>
+ Note that casting to just <span class="quote">“<span class="quote">bit</span>”</span> means casting to
+ <code class="literal">bit(1)</code>, and so will deliver only the least significant
+ bit of the integer.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-binarystring.html" title="9.5. Binary String Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-matching.html" title="9.7. Pattern Matching">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.5. Binary String Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.7. Pattern Matching</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-comparison.html b/doc/src/sgml/html/functions-comparison.html
new file mode 100644
index 0000000..af84ce0
--- /dev/null
+++ b/doc/src/sgml/html/functions-comparison.html
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.2. Comparison Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-logical.html" title="9.1. Logical Operators" /><link rel="next" href="functions-math.html" title="9.3. Mathematical Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.2. Comparison Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-logical.html" title="9.1. Logical Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-math.html" title="9.3. Mathematical Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-COMPARISON"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.2. Comparison Functions and Operators</h2></div></div></div><a id="id-1.5.8.8.2" class="indexterm"></a><p>
+ The usual comparison operators are available, as shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a>.
+ </p><div class="table" id="FUNCTIONS-COMPARISON-OP-TABLE"><p class="title"><strong>Table 9.1. Comparison Operators</strong></p><div class="table-contents"><table class="table" summary="Comparison Operators" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operator</th><th>Description</th></tr></thead><tbody><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">&lt;</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Less than</td></tr><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">&gt;</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Greater than</td></tr><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">&lt;=</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Less than or equal to</td></tr><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">&gt;=</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Greater than or equal to</td></tr><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">=</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Equal</td></tr><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">&lt;&gt;</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Not equal</td></tr><tr><td>
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">!=</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </td><td>Not equal</td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">&lt;&gt;</code> is the standard SQL notation for <span class="quote">“<span class="quote">not
+ equal</span>”</span>. <code class="literal">!=</code> is an alias, which is converted
+ to <code class="literal">&lt;&gt;</code> at a very early stage of parsing.
+ Hence, it is not possible to implement <code class="literal">!=</code>
+ and <code class="literal">&lt;&gt;</code> operators that do different things.
+ </p></div><p>
+ These comparison operators are available for all built-in data types
+ that have a natural ordering, including numeric, string, and date/time
+ types. In addition, arrays, composite types, and ranges can be compared
+ if their component data types are comparable.
+ </p><p>
+ It is usually possible to compare values of related data
+ types as well; for example <code class="type">integer</code> <code class="literal">&gt;</code>
+ <code class="type">bigint</code> will work. Some cases of this sort are implemented
+ directly by <span class="quote">“<span class="quote">cross-type</span>”</span> comparison operators, but if no
+ such operator is available, the parser will coerce the less-general type
+ to the more-general type and apply the latter's comparison operator.
+ </p><p>
+ As shown above, all comparison operators are binary operators that
+ return values of type <code class="type">boolean</code>. Thus, expressions like
+ <code class="literal">1 &lt; 2 &lt; 3</code> are not valid (because there is
+ no <code class="literal">&lt;</code> operator to compare a Boolean value with
+ <code class="literal">3</code>). Use the <code class="literal">BETWEEN</code> predicates
+ shown below to perform range tests.
+ </p><p>
+ There are also some comparison predicates, as shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-PRED-TABLE" title="Table 9.2. Comparison Predicates">Table 9.2</a>. These behave much like
+ operators, but have special syntax mandated by the SQL standard.
+ </p><div class="table" id="FUNCTIONS-COMPARISON-PRED-TABLE"><p class="title"><strong>Table 9.2. Comparison Predicates</strong></p><div class="table-contents"><table class="table" summary="Comparison Predicates" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Predicate
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">BETWEEN</code> <em class="replaceable"><code>datatype</code></em> <code class="literal">AND</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Between (inclusive of the range endpoints).
+ </p>
+ <p>
+ <code class="literal">2 BETWEEN 1 AND 3</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">2 BETWEEN 3 AND 1</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">NOT BETWEEN</code> <em class="replaceable"><code>datatype</code></em> <code class="literal">AND</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Not between (the negation of <code class="literal">BETWEEN</code>).
+ </p>
+ <p>
+ <code class="literal">2 NOT BETWEEN 1 AND 3</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">BETWEEN SYMMETRIC</code> <em class="replaceable"><code>datatype</code></em> <code class="literal">AND</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Between, after sorting the two endpoint values.
+ </p>
+ <p>
+ <code class="literal">2 BETWEEN SYMMETRIC 3 AND 1</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">NOT BETWEEN SYMMETRIC</code> <em class="replaceable"><code>datatype</code></em> <code class="literal">AND</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Not between, after sorting the two endpoint values.
+ </p>
+ <p>
+ <code class="literal">2 NOT BETWEEN SYMMETRIC 3 AND 1</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">IS DISTINCT FROM</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Not equal, treating null as a comparable value.
+ </p>
+ <p>
+ <code class="literal">1 IS DISTINCT FROM NULL</code>
+ → <code class="returnvalue">t</code> (rather than <code class="literal">NULL</code>)
+ </p>
+ <p>
+ <code class="literal">NULL IS DISTINCT FROM NULL</code>
+ → <code class="returnvalue">f</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">IS NOT DISTINCT FROM</code> <em class="replaceable"><code>datatype</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Equal, treating null as a comparable value.
+ </p>
+ <p>
+ <code class="literal">1 IS NOT DISTINCT FROM NULL</code>
+ → <code class="returnvalue">f</code> (rather than <code class="literal">NULL</code>)
+ </p>
+ <p>
+ <code class="literal">NULL IS NOT DISTINCT FROM NULL</code>
+ → <code class="returnvalue">t</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">IS NULL</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether value is null.
+ </p>
+ <p>
+ <code class="literal">1.5 IS NULL</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">IS NOT NULL</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether value is not null.
+ </p>
+ <p>
+ <code class="literal">'null' IS NOT NULL</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">ISNULL</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether value is null (nonstandard syntax).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>datatype</code></em> <code class="literal">NOTNULL</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether value is not null (nonstandard syntax).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">boolean</code> <code class="literal">IS TRUE</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether boolean expression yields true.
+ </p>
+ <p>
+ <code class="literal">true IS TRUE</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">NULL::boolean IS TRUE</code>
+ → <code class="returnvalue">f</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">boolean</code> <code class="literal">IS NOT TRUE</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether boolean expression yields false or unknown.
+ </p>
+ <p>
+ <code class="literal">true IS NOT TRUE</code>
+ → <code class="returnvalue">f</code>
+ </p>
+ <p>
+ <code class="literal">NULL::boolean IS NOT TRUE</code>
+ → <code class="returnvalue">t</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">boolean</code> <code class="literal">IS FALSE</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether boolean expression yields false.
+ </p>
+ <p>
+ <code class="literal">true IS FALSE</code>
+ → <code class="returnvalue">f</code>
+ </p>
+ <p>
+ <code class="literal">NULL::boolean IS FALSE</code>
+ → <code class="returnvalue">f</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">boolean</code> <code class="literal">IS NOT FALSE</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether boolean expression yields true or unknown.
+ </p>
+ <p>
+ <code class="literal">true IS NOT FALSE</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">NULL::boolean IS NOT FALSE</code>
+ → <code class="returnvalue">t</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">boolean</code> <code class="literal">IS UNKNOWN</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether boolean expression yields unknown.
+ </p>
+ <p>
+ <code class="literal">true IS UNKNOWN</code>
+ → <code class="returnvalue">f</code>
+ </p>
+ <p>
+ <code class="literal">NULL::boolean IS UNKNOWN</code>
+ → <code class="returnvalue">t</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">boolean</code> <code class="literal">IS NOT UNKNOWN</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test whether boolean expression yields true or false.
+ </p>
+ <p>
+ <code class="literal">true IS NOT UNKNOWN</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">NULL::boolean IS NOT UNKNOWN</code>
+ → <code class="returnvalue">f</code> (rather than <code class="literal">NULL</code>)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a id="id-1.5.8.8.11.1" class="indexterm"></a>
+ <a id="id-1.5.8.8.11.2" class="indexterm"></a>
+ The <code class="token">BETWEEN</code> predicate simplifies range tests:
+</p><pre class="synopsis">
+<em class="replaceable"><code>a</code></em> BETWEEN <em class="replaceable"><code>x</code></em> AND <em class="replaceable"><code>y</code></em>
+</pre><p>
+ is equivalent to
+</p><pre class="synopsis">
+<em class="replaceable"><code>a</code></em> &gt;= <em class="replaceable"><code>x</code></em> AND <em class="replaceable"><code>a</code></em> &lt;= <em class="replaceable"><code>y</code></em>
+</pre><p>
+ Notice that <code class="token">BETWEEN</code> treats the endpoint values as included
+ in the range.
+ <code class="literal">BETWEEN SYMMETRIC</code> is like <code class="literal">BETWEEN</code>
+ except there is no requirement that the argument to the left of
+ <code class="literal">AND</code> be less than or equal to the argument on the right.
+ If it is not, those two arguments are automatically swapped, so that
+ a nonempty range is always implied.
+ </p><p>
+ The various variants of <code class="literal">BETWEEN</code> are implemented in
+ terms of the ordinary comparison operators, and therefore will work for
+ any data type(s) that can be compared.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The use of <code class="literal">AND</code> in the <code class="literal">BETWEEN</code>
+ syntax creates an ambiguity with the use of <code class="literal">AND</code> as a
+ logical operator. To resolve this, only a limited set of expression
+ types are allowed as the second argument of a <code class="literal">BETWEEN</code>
+ clause. If you need to write a more complex sub-expression
+ in <code class="literal">BETWEEN</code>, write parentheses around the
+ sub-expression.
+ </p></div><p>
+ <a id="id-1.5.8.8.14.1" class="indexterm"></a>
+ <a id="id-1.5.8.8.14.2" class="indexterm"></a>
+ Ordinary comparison operators yield null (signifying <span class="quote">“<span class="quote">unknown</span>”</span>),
+ not true or false, when either input is null. For example,
+ <code class="literal">7 = NULL</code> yields null, as does <code class="literal">7 &lt;&gt; NULL</code>. When
+ this behavior is not suitable, use the
+ <code class="literal">IS [<span class="optional"> NOT </span>] DISTINCT FROM</code> predicates:
+</p><pre class="synopsis">
+<em class="replaceable"><code>a</code></em> IS DISTINCT FROM <em class="replaceable"><code>b</code></em>
+<em class="replaceable"><code>a</code></em> IS NOT DISTINCT FROM <em class="replaceable"><code>b</code></em>
+</pre><p>
+ For non-null inputs, <code class="literal">IS DISTINCT FROM</code> is
+ the same as the <code class="literal">&lt;&gt;</code> operator. However, if both
+ inputs are null it returns false, and if only one input is
+ null it returns true. Similarly, <code class="literal">IS NOT DISTINCT
+ FROM</code> is identical to <code class="literal">=</code> for non-null
+ inputs, but it returns true when both inputs are null, and false when only
+ one input is null. Thus, these predicates effectively act as though null
+ were a normal data value, rather than <span class="quote">“<span class="quote">unknown</span>”</span>.
+ </p><p>
+ <a id="id-1.5.8.8.15.1" class="indexterm"></a>
+ <a id="id-1.5.8.8.15.2" class="indexterm"></a>
+ <a id="id-1.5.8.8.15.3" class="indexterm"></a>
+ <a id="id-1.5.8.8.15.4" class="indexterm"></a>
+ To check whether a value is or is not null, use the predicates:
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> IS NULL
+<em class="replaceable"><code>expression</code></em> IS NOT NULL
+</pre><p>
+ or the equivalent, but nonstandard, predicates:
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> ISNULL
+<em class="replaceable"><code>expression</code></em> NOTNULL
+</pre><p>
+ <a id="id-1.5.8.8.15.7" class="indexterm"></a>
+ </p><p>
+ Do <span class="emphasis"><em>not</em></span> write
+ <code class="literal"><em class="replaceable"><code>expression</code></em> = NULL</code>
+ because <code class="literal">NULL</code> is not <span class="quote">“<span class="quote">equal to</span>”</span>
+ <code class="literal">NULL</code>. (The null value represents an unknown value,
+ and it is not known whether two unknown values are equal.)
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Some applications might expect that
+ <code class="literal"><em class="replaceable"><code>expression</code></em> = NULL</code>
+ returns true if <em class="replaceable"><code>expression</code></em> evaluates to
+ the null value. It is highly recommended that these applications
+ be modified to comply with the SQL standard. However, if that
+ cannot be done the <a class="xref" href="runtime-config-compatible.html#GUC-TRANSFORM-NULL-EQUALS">transform_null_equals</a>
+ configuration variable is available. If it is enabled,
+ <span class="productname">PostgreSQL</span> will convert <code class="literal">x =
+ NULL</code> clauses to <code class="literal">x IS NULL</code>.
+ </p></div><p>
+ If the <em class="replaceable"><code>expression</code></em> is row-valued, then
+ <code class="literal">IS NULL</code> is true when the row expression itself is null
+ or when all the row's fields are null, while
+ <code class="literal">IS NOT NULL</code> is true when the row expression itself is non-null
+ and all the row's fields are non-null. Because of this behavior,
+ <code class="literal">IS NULL</code> and <code class="literal">IS NOT NULL</code> do not always return
+ inverse results for row-valued expressions; in particular, a row-valued
+ expression that contains both null and non-null fields will return false
+ for both tests. In some cases, it may be preferable to
+ write <em class="replaceable"><code>row</code></em> <code class="literal">IS DISTINCT FROM NULL</code>
+ or <em class="replaceable"><code>row</code></em> <code class="literal">IS NOT DISTINCT FROM NULL</code>,
+ which will simply check whether the overall row value is null without any
+ additional tests on the row fields.
+ </p><p>
+ <a id="id-1.5.8.8.19.1" class="indexterm"></a>
+ <a id="id-1.5.8.8.19.2" class="indexterm"></a>
+ <a id="id-1.5.8.8.19.3" class="indexterm"></a>
+ <a id="id-1.5.8.8.19.4" class="indexterm"></a>
+ <a id="id-1.5.8.8.19.5" class="indexterm"></a>
+ <a id="id-1.5.8.8.19.6" class="indexterm"></a>
+ Boolean values can also be tested using the predicates
+</p><pre class="synopsis">
+<em class="replaceable"><code>boolean_expression</code></em> IS TRUE
+<em class="replaceable"><code>boolean_expression</code></em> IS NOT TRUE
+<em class="replaceable"><code>boolean_expression</code></em> IS FALSE
+<em class="replaceable"><code>boolean_expression</code></em> IS NOT FALSE
+<em class="replaceable"><code>boolean_expression</code></em> IS UNKNOWN
+<em class="replaceable"><code>boolean_expression</code></em> IS NOT UNKNOWN
+</pre><p>
+ These will always return true or false, never a null value, even when the
+ operand is null.
+ A null input is treated as the logical value <span class="quote">“<span class="quote">unknown</span>”</span>.
+ Notice that <code class="literal">IS UNKNOWN</code> and <code class="literal">IS NOT UNKNOWN</code> are
+ effectively the same as <code class="literal">IS NULL</code> and
+ <code class="literal">IS NOT NULL</code>, respectively, except that the input
+ expression must be of Boolean type.
+ </p><p>
+ Some comparison-related functions are also available, as shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-FUNC-TABLE" title="Table 9.3. Comparison Functions">Table 9.3</a>.
+ </p><div class="table" id="FUNCTIONS-COMPARISON-FUNC-TABLE"><p class="title"><strong>Table 9.3. Comparison Functions</strong></p><div class="table-contents"><table class="table" summary="Comparison Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.8.21.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">num_nonnulls</code> ( <code class="literal">VARIADIC</code> <code class="type">"any"</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of non-null arguments.
+ </p>
+ <p>
+ <code class="literal">num_nonnulls(1, NULL, 2)</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.8.21.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">num_nulls</code> ( <code class="literal">VARIADIC</code> <code class="type">"any"</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of null arguments.
+ </p>
+ <p>
+ <code class="literal">num_nulls(1, NULL, 2)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-logical.html" title="9.1. Logical Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-math.html" title="9.3. Mathematical Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.1. Logical Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.3. Mathematical Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-comparisons.html b/doc/src/sgml/html/functions-comparisons.html
new file mode 100644
index 0000000..0c8301a
--- /dev/null
+++ b/doc/src/sgml/html/functions-comparisons.html
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.24. Row and Array Comparisons</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-subquery.html" title="9.23. Subquery Expressions" /><link rel="next" href="functions-srf.html" title="9.25. Set Returning Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.24. Row and Array Comparisons</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-subquery.html" title="9.23. Subquery Expressions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-srf.html" title="9.25. Set Returning Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-COMPARISONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.24. Row and Array Comparisons</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-comparisons.html#FUNCTIONS-COMPARISONS-IN-SCALAR">9.24.1. <code class="literal">IN</code></a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#id-1.5.8.30.15">9.24.2. <code class="literal">NOT IN</code></a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#id-1.5.8.30.16">9.24.3. <code class="literal">ANY</code>/<code class="literal">SOME</code> (array)</a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#id-1.5.8.30.17">9.24.4. <code class="literal">ALL</code> (array)</a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#ROW-WISE-COMPARISON">9.24.5. Row Constructor Comparison</a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#COMPOSITE-TYPE-COMPARISON">9.24.6. Composite Type Comparison</a></span></dt></dl></div><a id="id-1.5.8.30.2" class="indexterm"></a><a id="id-1.5.8.30.3" class="indexterm"></a><a id="id-1.5.8.30.4" class="indexterm"></a><a id="id-1.5.8.30.5" class="indexterm"></a><a id="id-1.5.8.30.6" class="indexterm"></a><a id="id-1.5.8.30.7" class="indexterm"></a><a id="id-1.5.8.30.8" class="indexterm"></a><a id="id-1.5.8.30.9" class="indexterm"></a><a id="id-1.5.8.30.10" class="indexterm"></a><a id="id-1.5.8.30.11" class="indexterm"></a><a id="id-1.5.8.30.12" class="indexterm"></a><p>
+ This section describes several specialized constructs for making
+ multiple comparisons between groups of values. These forms are
+ syntactically related to the subquery forms of the previous section,
+ but do not involve subqueries.
+ The forms involving array subexpressions are
+ <span class="productname">PostgreSQL</span> extensions; the rest are
+ <acronym class="acronym">SQL</acronym>-compliant.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </p><div class="sect2" id="FUNCTIONS-COMPARISONS-IN-SCALAR"><div class="titlepage"><div><div><h3 class="title">9.24.1. <code class="literal">IN</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> IN (<em class="replaceable"><code>value</code></em> [<span class="optional">, ...</span>])
+</pre><p>
+ The right-hand side is a parenthesized list
+ of expressions. The result is <span class="quote">“<span class="quote">true</span>”</span> if the left-hand expression's
+ result is equal to any of the right-hand expressions. This is a shorthand
+ notation for
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> = <em class="replaceable"><code>value1</code></em>
+OR
+<em class="replaceable"><code>expression</code></em> = <em class="replaceable"><code>value2</code></em>
+OR
+...
+</pre><p>
+ </p><p>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand expression yields
+ null, the result of the <code class="token">IN</code> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p></div><div class="sect2" id="id-1.5.8.30.15"><div class="titlepage"><div><div><h3 class="title">9.24.2. <code class="literal">NOT IN</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> NOT IN (<em class="replaceable"><code>value</code></em> [<span class="optional">, ...</span>])
+</pre><p>
+ The right-hand side is a parenthesized list
+ of expressions. The result is <span class="quote">“<span class="quote">true</span>”</span> if the left-hand expression's
+ result is unequal to all of the right-hand expressions. This is a shorthand
+ notation for
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> &lt;&gt; <em class="replaceable"><code>value1</code></em>
+AND
+<em class="replaceable"><code>expression</code></em> &lt;&gt; <em class="replaceable"><code>value2</code></em>
+AND
+...
+</pre><p>
+ </p><p>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand expression yields
+ null, the result of the <code class="token">NOT IN</code> construct will be null, not true
+ as one might naively expect.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <code class="literal">x NOT IN y</code> is equivalent to <code class="literal">NOT (x IN y)</code> in all
+ cases. However, null values are much more likely to trip up the novice when
+ working with <code class="token">NOT IN</code> than when working with <code class="token">IN</code>.
+ It is best to express your condition positively if possible.
+ </p></div></div><div class="sect2" id="id-1.5.8.30.16"><div class="titlepage"><div><div><h3 class="title">9.24.3. <code class="literal">ANY</code>/<code class="literal">SOME</code> (array)</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> ANY (<em class="replaceable"><code>array expression</code></em>)
+<em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> SOME (<em class="replaceable"><code>array expression</code></em>)
+</pre><p>
+ The right-hand side is a parenthesized expression, which must yield an
+ array value.
+ The left-hand expression
+ is evaluated and compared to each element of the array using the
+ given <em class="replaceable"><code>operator</code></em>, which must yield a Boolean
+ result.
+ The result of <code class="token">ANY</code> is <span class="quote">“<span class="quote">true</span>”</span> if any true result is obtained.
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if no true result is found (including the
+ case where the array has zero elements).
+ </p><p>
+ If the array expression yields a null array, the result of
+ <code class="token">ANY</code> will be null. If the left-hand expression yields null,
+ the result of <code class="token">ANY</code> is ordinarily null (though a non-strict
+ comparison operator could possibly yield a different result).
+ Also, if the right-hand array contains any null elements and no true
+ comparison result is obtained, the result of <code class="token">ANY</code>
+ will be null, not false (again, assuming a strict comparison operator).
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p><p>
+ <code class="token">SOME</code> is a synonym for <code class="token">ANY</code>.
+ </p></div><div class="sect2" id="id-1.5.8.30.17"><div class="titlepage"><div><div><h3 class="title">9.24.4. <code class="literal">ALL</code> (array)</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> ALL (<em class="replaceable"><code>array expression</code></em>)
+</pre><p>
+ The right-hand side is a parenthesized expression, which must yield an
+ array value.
+ The left-hand expression
+ is evaluated and compared to each element of the array using the
+ given <em class="replaceable"><code>operator</code></em>, which must yield a Boolean
+ result.
+ The result of <code class="token">ALL</code> is <span class="quote">“<span class="quote">true</span>”</span> if all comparisons yield true
+ (including the case where the array has zero elements).
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if any false result is found.
+ </p><p>
+ If the array expression yields a null array, the result of
+ <code class="token">ALL</code> will be null. If the left-hand expression yields null,
+ the result of <code class="token">ALL</code> is ordinarily null (though a non-strict
+ comparison operator could possibly yield a different result).
+ Also, if the right-hand array contains any null elements and no false
+ comparison result is obtained, the result of <code class="token">ALL</code>
+ will be null, not true (again, assuming a strict comparison operator).
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p></div><div class="sect2" id="ROW-WISE-COMPARISON"><div class="titlepage"><div><div><h3 class="title">9.24.5. Row Constructor Comparison</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> <em class="replaceable"><code>operator</code></em> <em class="replaceable"><code>row_constructor</code></em>
+</pre><p>
+ Each side is a row constructor,
+ as described in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ The two row constructors must have the same number of fields.
+ The given <em class="replaceable"><code>operator</code></em> is applied to each pair
+ of corresponding fields. (Since the fields could be of different
+ types, this means that a different specific operator could be selected
+ for each pair.)
+ All the selected operators must be members of some B-tree operator
+ class, or be the negator of an <code class="literal">=</code> member of a B-tree
+ operator class, meaning that row constructor comparison is only
+ possible when the <em class="replaceable"><code>operator</code></em> is
+ <code class="literal">=</code>,
+ <code class="literal">&lt;&gt;</code>,
+ <code class="literal">&lt;</code>,
+ <code class="literal">&lt;=</code>,
+ <code class="literal">&gt;</code>, or
+ <code class="literal">&gt;=</code>,
+ or has semantics similar to one of these.
+ </p><p>
+ The <code class="literal">=</code> and <code class="literal">&lt;&gt;</code> cases work slightly differently
+ from the others. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of the row comparison is unknown (null).
+ </p><p>
+ For the <code class="literal">&lt;</code>, <code class="literal">&lt;=</code>, <code class="literal">&gt;</code> and
+ <code class="literal">&gt;=</code> cases, the row elements are compared left-to-right,
+ stopping as soon as an unequal or null pair of elements is found.
+ If either of this pair of elements is null, the result of the
+ row comparison is unknown (null); otherwise comparison of this pair
+ of elements determines the result. For example,
+ <code class="literal">ROW(1,2,NULL) &lt; ROW(1,3,0)</code>
+ yields true, not null, because the third pair of elements are not
+ considered.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Prior to <span class="productname">PostgreSQL</span> 8.2, the
+ <code class="literal">&lt;</code>, <code class="literal">&lt;=</code>, <code class="literal">&gt;</code> and <code class="literal">&gt;=</code>
+ cases were not handled per SQL specification. A comparison like
+ <code class="literal">ROW(a,b) &lt; ROW(c,d)</code>
+ was implemented as
+ <code class="literal">a &lt; c AND b &lt; d</code>
+ whereas the correct behavior is equivalent to
+ <code class="literal">a &lt; c OR (a = c AND b &lt; d)</code>.
+ </p></div><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> IS DISTINCT FROM <em class="replaceable"><code>row_constructor</code></em>
+</pre><p>
+ This construct is similar to a <code class="literal">&lt;&gt;</code> row comparison,
+ but it does not yield null for null inputs. Instead, any null value is
+ considered unequal to (distinct from) any non-null value, and any two
+ nulls are considered equal (not distinct). Thus the result will
+ either be true or false, never null.
+ </p><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> IS NOT DISTINCT FROM <em class="replaceable"><code>row_constructor</code></em>
+</pre><p>
+ This construct is similar to a <code class="literal">=</code> row comparison,
+ but it does not yield null for null inputs. Instead, any null value is
+ considered unequal to (distinct from) any non-null value, and any two
+ nulls are considered equal (not distinct). Thus the result will always
+ be either true or false, never null.
+ </p></div><div class="sect2" id="COMPOSITE-TYPE-COMPARISON"><div class="titlepage"><div><div><h3 class="title">9.24.6. Composite Type Comparison</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>record</code></em> <em class="replaceable"><code>operator</code></em> <em class="replaceable"><code>record</code></em>
+</pre><p>
+ The SQL specification requires row-wise comparison to return NULL if the
+ result depends on comparing two NULL values or a NULL and a non-NULL.
+ <span class="productname">PostgreSQL</span> does this only when comparing the
+ results of two row constructors (as in
+ <a class="xref" href="functions-comparisons.html#ROW-WISE-COMPARISON" title="9.24.5. Row Constructor Comparison">Section 9.24.5</a>) or comparing a row constructor
+ to the output of a subquery (as in <a class="xref" href="functions-subquery.html" title="9.23. Subquery Expressions">Section 9.23</a>).
+ In other contexts where two composite-type values are compared, two
+ NULL field values are considered equal, and a NULL is considered larger
+ than a non-NULL. This is necessary in order to have consistent sorting
+ and indexing behavior for composite types.
+ </p><p>
+ Each side is evaluated and they are compared row-wise. Composite type
+ comparisons are allowed when the <em class="replaceable"><code>operator</code></em> is
+ <code class="literal">=</code>,
+ <code class="literal">&lt;&gt;</code>,
+ <code class="literal">&lt;</code>,
+ <code class="literal">&lt;=</code>,
+ <code class="literal">&gt;</code> or
+ <code class="literal">&gt;=</code>,
+ or has semantics similar to one of these. (To be specific, an operator
+ can be a row comparison operator if it is a member of a B-tree operator
+ class, or is the negator of the <code class="literal">=</code> member of a B-tree operator
+ class.) The default behavior of the above operators is the same as for
+ <code class="literal">IS [ NOT ] DISTINCT FROM</code> for row constructors (see
+ <a class="xref" href="functions-comparisons.html#ROW-WISE-COMPARISON" title="9.24.5. Row Constructor Comparison">Section 9.24.5</a>).
+ </p><p>
+ To support matching of rows which include elements without a default
+ B-tree operator class, the following operators are defined for composite
+ type comparison:
+ <code class="literal">*=</code>,
+ <code class="literal">*&lt;&gt;</code>,
+ <code class="literal">*&lt;</code>,
+ <code class="literal">*&lt;=</code>,
+ <code class="literal">*&gt;</code>, and
+ <code class="literal">*&gt;=</code>.
+ These operators compare the internal binary representation of the two
+ rows. Two rows might have a different binary representation even
+ though comparisons of the two rows with the equality operator is true.
+ The ordering of rows under these comparison operators is deterministic
+ but not otherwise meaningful. These operators are used internally
+ for materialized views and might be useful for other specialized
+ purposes such as replication and B-Tree deduplication (see <a class="xref" href="btree-implementation.html#BTREE-DEDUPLICATION" title="67.4.3. Deduplication">Section 67.4.3</a>). They are not intended to be
+ generally useful for writing queries, though.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-subquery.html" title="9.23. Subquery Expressions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-srf.html" title="9.25. Set Returning Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.23. Subquery Expressions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.25. Set Returning Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-conditional.html b/doc/src/sgml/html/functions-conditional.html
new file mode 100644
index 0000000..d677456
--- /dev/null
+++ b/doc/src/sgml/html/functions-conditional.html
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.18. Conditional Expressions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions" /><link rel="next" href="functions-array.html" title="9.19. Array Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.18. Conditional Expressions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-array.html" title="9.19. Array Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-CONDITIONAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.18. Conditional Expressions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-CASE">9.18.1. <code class="literal">CASE</code></a></span></dt><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL">9.18.2. <code class="literal">COALESCE</code></a></span></dt><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-NULLIF">9.18.3. <code class="literal">NULLIF</code></a></span></dt><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-GREATEST-LEAST">9.18.4. <code class="literal">GREATEST</code> and <code class="literal">LEAST</code></a></span></dt></dl></div><a id="id-1.5.8.24.2" class="indexterm"></a><a id="id-1.5.8.24.3" class="indexterm"></a><p>
+ This section describes the <acronym class="acronym">SQL</acronym>-compliant conditional expressions
+ available in <span class="productname">PostgreSQL</span>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If your needs go beyond the capabilities of these conditional
+ expressions, you might want to consider writing a server-side function
+ in a more expressive programming language.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Although <code class="token">COALESCE</code>, <code class="token">GREATEST</code>, and
+ <code class="token">LEAST</code> are syntactically similar to functions, they are
+ not ordinary functions, and thus cannot be used with explicit
+ <code class="token">VARIADIC</code> array arguments.
+ </p></div><div class="sect2" id="FUNCTIONS-CASE"><div class="titlepage"><div><div><h3 class="title">9.18.1. <code class="literal">CASE</code></h3></div></div></div><p>
+ The <acronym class="acronym">SQL</acronym> <code class="token">CASE</code> expression is a
+ generic conditional expression, similar to if/else statements in
+ other programming languages:
+
+</p><pre class="synopsis">
+CASE WHEN <em class="replaceable"><code>condition</code></em> THEN <em class="replaceable"><code>result</code></em>
+ [<span class="optional">WHEN ...</span>]
+ [<span class="optional">ELSE <em class="replaceable"><code>result</code></em></span>]
+END
+</pre><p>
+
+ <code class="token">CASE</code> clauses can be used wherever
+ an expression is valid. Each <em class="replaceable"><code>condition</code></em> is an
+ expression that returns a <code class="type">boolean</code> result. If the condition's
+ result is true, the value of the <code class="token">CASE</code> expression is the
+ <em class="replaceable"><code>result</code></em> that follows the condition, and the
+ remainder of the <code class="token">CASE</code> expression is not processed. If the
+ condition's result is not true, any subsequent <code class="token">WHEN</code> clauses
+ are examined in the same manner. If no <code class="token">WHEN</code>
+ <em class="replaceable"><code>condition</code></em> yields true, the value of the
+ <code class="token">CASE</code> expression is the <em class="replaceable"><code>result</code></em> of the
+ <code class="token">ELSE</code> clause. If the <code class="token">ELSE</code> clause is
+ omitted and no condition is true, the result is null.
+ </p><p>
+ An example:
+</p><pre class="screen">
+SELECT * FROM test;
+
+ a
+---
+ 1
+ 2
+ 3
+
+
+SELECT a,
+ CASE WHEN a=1 THEN 'one'
+ WHEN a=2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
+ a | case
+---+-------
+ 1 | one
+ 2 | two
+ 3 | other
+</pre><p>
+ </p><p>
+ The data types of all the <em class="replaceable"><code>result</code></em>
+ expressions must be convertible to a single output type.
+ See <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a> for more details.
+ </p><p>
+ There is a <span class="quote">“<span class="quote">simple</span>”</span> form of <code class="token">CASE</code> expression
+ that is a variant of the general form above:
+
+</p><pre class="synopsis">
+CASE <em class="replaceable"><code>expression</code></em>
+ WHEN <em class="replaceable"><code>value</code></em> THEN <em class="replaceable"><code>result</code></em>
+ [<span class="optional">WHEN ...</span>]
+ [<span class="optional">ELSE <em class="replaceable"><code>result</code></em></span>]
+END
+</pre><p>
+
+ The first
+ <em class="replaceable"><code>expression</code></em> is computed, then compared to
+ each of the <em class="replaceable"><code>value</code></em> expressions in the
+ <code class="token">WHEN</code> clauses until one is found that is equal to it. If
+ no match is found, the <em class="replaceable"><code>result</code></em> of the
+ <code class="token">ELSE</code> clause (or a null value) is returned. This is similar
+ to the <code class="function">switch</code> statement in C.
+ </p><p>
+ The example above can be written using the simple
+ <code class="token">CASE</code> syntax:
+</p><pre class="screen">
+SELECT a,
+ CASE a WHEN 1 THEN 'one'
+ WHEN 2 THEN 'two'
+ ELSE 'other'
+ END
+ FROM test;
+
+ a | case
+---+-------
+ 1 | one
+ 2 | two
+ 3 | other
+</pre><p>
+ </p><p>
+ A <code class="token">CASE</code> expression does not evaluate any subexpressions
+ that are not needed to determine the result. For example, this is a
+ possible way of avoiding a division-by-zero failure:
+</p><pre class="programlisting">
+SELECT ... WHERE CASE WHEN x &lt;&gt; 0 THEN y/x &gt; 1.5 ELSE false END;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ As described in <a class="xref" href="sql-expressions.html#SYNTAX-EXPRESS-EVAL" title="4.2.14. Expression Evaluation Rules">Section 4.2.14</a>, there are various
+ situations in which subexpressions of an expression are evaluated at
+ different times, so that the principle that <span class="quote">“<span class="quote"><code class="token">CASE</code>
+ evaluates only necessary subexpressions</span>”</span> is not ironclad. For
+ example a constant <code class="literal">1/0</code> subexpression will usually result in
+ a division-by-zero failure at planning time, even if it's within
+ a <code class="token">CASE</code> arm that would never be entered at run time.
+ </p></div></div><div class="sect2" id="FUNCTIONS-COALESCE-NVL-IFNULL"><div class="titlepage"><div><div><h3 class="title">9.18.2. <code class="literal">COALESCE</code></h3></div></div></div><a id="id-1.5.8.24.8.2" class="indexterm"></a><a id="id-1.5.8.24.8.3" class="indexterm"></a><a id="id-1.5.8.24.8.4" class="indexterm"></a><pre class="synopsis">
+<code class="function">COALESCE</code>(<em class="replaceable"><code>value</code></em> [<span class="optional">, ...</span>])
+</pre><p>
+ The <code class="function">COALESCE</code> function returns the first of its
+ arguments that is not null. Null is returned only if all arguments
+ are null. It is often used to substitute a default value for
+ null values when data is retrieved for display, for example:
+</p><pre class="programlisting">
+SELECT COALESCE(description, short_description, '(none)') ...
+</pre><p>
+ This returns <code class="varname">description</code> if it is not null, otherwise
+ <code class="varname">short_description</code> if it is not null, otherwise <code class="literal">(none)</code>.
+ </p><p>
+ The arguments must all be convertible to a common data type, which
+ will be the type of the result (see
+ <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a> for details).
+ </p><p>
+ Like a <code class="token">CASE</code> expression, <code class="function">COALESCE</code> only
+ evaluates the arguments that are needed to determine the result;
+ that is, arguments to the right of the first non-null argument are
+ not evaluated. This SQL-standard function provides capabilities similar
+ to <code class="function">NVL</code> and <code class="function">IFNULL</code>, which are used in some other
+ database systems.
+ </p></div><div class="sect2" id="FUNCTIONS-NULLIF"><div class="titlepage"><div><div><h3 class="title">9.18.3. <code class="literal">NULLIF</code></h3></div></div></div><a id="id-1.5.8.24.9.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">NULLIF</code>(<em class="replaceable"><code>value1</code></em>, <em class="replaceable"><code>value2</code></em>)
+</pre><p>
+ The <code class="function">NULLIF</code> function returns a null value if
+ <em class="replaceable"><code>value1</code></em> equals <em class="replaceable"><code>value2</code></em>;
+ otherwise it returns <em class="replaceable"><code>value1</code></em>.
+ This can be used to perform the inverse operation of the
+ <code class="function">COALESCE</code> example given above:
+</p><pre class="programlisting">
+SELECT NULLIF(value, '(none)') ...
+</pre><p>
+ In this example, if <code class="literal">value</code> is <code class="literal">(none)</code>,
+ null is returned, otherwise the value of <code class="literal">value</code>
+ is returned.
+ </p><p>
+ The two arguments must be of comparable types.
+ To be specific, they are compared exactly as if you had
+ written <code class="literal"><em class="replaceable"><code>value1</code></em>
+ = <em class="replaceable"><code>value2</code></em></code>, so there must be a
+ suitable <code class="literal">=</code> operator available.
+ </p><p>
+ The result has the same type as the first argument — but there is
+ a subtlety. What is actually returned is the first argument of the
+ implied <code class="literal">=</code> operator, and in some cases that will have
+ been promoted to match the second argument's type. For
+ example, <code class="literal">NULLIF(1, 2.2)</code> yields <code class="type">numeric</code>,
+ because there is no <code class="type">integer</code> <code class="literal">=</code>
+ <code class="type">numeric</code> operator,
+ only <code class="type">numeric</code> <code class="literal">=</code> <code class="type">numeric</code>.
+ </p></div><div class="sect2" id="FUNCTIONS-GREATEST-LEAST"><div class="titlepage"><div><div><h3 class="title">9.18.4. <code class="literal">GREATEST</code> and <code class="literal">LEAST</code></h3></div></div></div><a id="id-1.5.8.24.10.2" class="indexterm"></a><a id="id-1.5.8.24.10.3" class="indexterm"></a><pre class="synopsis">
+<code class="function">GREATEST</code>(<em class="replaceable"><code>value</code></em> [<span class="optional">, ...</span>])
+</pre><pre class="synopsis">
+<code class="function">LEAST</code>(<em class="replaceable"><code>value</code></em> [<span class="optional">, ...</span>])
+</pre><p>
+ The <code class="function">GREATEST</code> and <code class="function">LEAST</code> functions select the
+ largest or smallest value from a list of any number of expressions.
+ The expressions must all be convertible to a common data type, which
+ will be the type of the result
+ (see <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a> for details). NULL values
+ in the list are ignored. The result will be NULL only if all the
+ expressions evaluate to NULL.
+ </p><p>
+ Note that <code class="function">GREATEST</code> and <code class="function">LEAST</code> are not in
+ the SQL standard, but are a common extension. Some other databases
+ make them return NULL if any argument is NULL, rather than only when
+ all are NULL.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-array.html" title="9.19. Array Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.17. Sequence Manipulation Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.19. Array Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-datetime.html b/doc/src/sgml/html/functions-datetime.html
new file mode 100644
index 0000000..cb17350
--- /dev/null
+++ b/doc/src/sgml/html/functions-datetime.html
@@ -0,0 +1,1316 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.9. Date/Time Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-formatting.html" title="9.8. Data Type Formatting Functions" /><link rel="next" href="functions-enum.html" title="9.10. Enum Support Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.9. Date/Time Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-enum.html" title="9.10. Enum Support Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-DATETIME"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.9. Date/Time Functions and Operators</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT">9.9.1. <code class="function">EXTRACT</code>, <code class="function">date_part</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-TRUNC">9.9.2. <code class="function">date_trunc</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-BIN">9.9.3. <code class="function">date_bin</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT">9.9.4. <code class="literal">AT TIME ZONE</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT">9.9.5. Current Date/Time</a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">9.9.6. Delaying Execution</a></span></dt></dl></div><p>
+ <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-TABLE" title="Table 9.33. Date/Time Functions">Table 9.33</a> shows the available
+ functions for date/time value processing, with details appearing in
+ the following subsections. <a class="xref" href="functions-datetime.html#OPERATORS-DATETIME-TABLE" title="Table 9.32. Date/Time Operators">Table 9.32</a> illustrates the behaviors of
+ the basic arithmetic operators (<code class="literal">+</code>,
+ <code class="literal">*</code>, etc.). For formatting functions, refer to
+ <a class="xref" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Section 9.8</a>. You should be familiar with
+ the background information on date/time data types from <a class="xref" href="datatype-datetime.html" title="8.5. Date/Time Types">Section 8.5</a>.
+ </p><p>
+ In addition, the usual comparison operators shown in
+ <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are available for the
+ date/time types. Dates and timestamps (with or without time zone) are
+ all comparable, while times (with or without time zone) and intervals
+ can only be compared to other values of the same data type. When
+ comparing a timestamp without time zone to a timestamp with time zone,
+ the former value is assumed to be given in the time zone specified by
+ the <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> configuration parameter, and is
+ rotated to UTC for comparison to the latter value (which is already
+ in UTC internally). Similarly, a date value is assumed to represent
+ midnight in the <code class="varname">TimeZone</code> zone when comparing it
+ to a timestamp.
+ </p><p>
+ All the functions and operators described below that take <code class="type">time</code> or <code class="type">timestamp</code>
+ inputs actually come in two variants: one that takes <code class="type">time with time zone</code> or <code class="type">timestamp
+ with time zone</code>, and one that takes <code class="type">time without time zone</code> or <code class="type">timestamp without time zone</code>.
+ For brevity, these variants are not shown separately. Also, the
+ <code class="literal">+</code> and <code class="literal">*</code> operators come in commutative pairs (for
+ example both <code class="type">date</code> <code class="literal">+</code> <code class="type">integer</code>
+ and <code class="type">integer</code> <code class="literal">+</code> <code class="type">date</code>); we show
+ only one of each such pair.
+ </p><div class="table" id="OPERATORS-DATETIME-TABLE"><p class="title"><strong>Table 9.32. Date/Time Operators</strong></p><div class="table-contents"><table class="table" summary="Date/Time Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">date</code> <code class="literal">+</code> <code class="type">integer</code>
+ → <code class="returnvalue">date</code>
+ </p>
+ <p>
+ Add a number of days to a date
+ </p>
+ <p>
+ <code class="literal">date '2001-09-28' + 7</code>
+ → <code class="returnvalue">2001-10-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">date</code> <code class="literal">+</code> <code class="type">interval</code>
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Add an interval to a date
+ </p>
+ <p>
+ <code class="literal">date '2001-09-28' + interval '1 hour'</code>
+ → <code class="returnvalue">2001-09-28 01:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">date</code> <code class="literal">+</code> <code class="type">time</code>
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Add a time-of-day to a date
+ </p>
+ <p>
+ <code class="literal">date '2001-09-28' + time '03:00'</code>
+ → <code class="returnvalue">2001-09-28 03:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">interval</code> <code class="literal">+</code> <code class="type">interval</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Add intervals
+ </p>
+ <p>
+ <code class="literal">interval '1 day' + interval '1 hour'</code>
+ → <code class="returnvalue">1 day 01:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">timestamp</code> <code class="literal">+</code> <code class="type">interval</code>
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Add an interval to a timestamp
+ </p>
+ <p>
+ <code class="literal">timestamp '2001-09-28 01:00' + interval '23 hours'</code>
+ → <code class="returnvalue">2001-09-29 00:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">time</code> <code class="literal">+</code> <code class="type">interval</code>
+ → <code class="returnvalue">time</code>
+ </p>
+ <p>
+ Add an interval to a time
+ </p>
+ <p>
+ <code class="literal">time '01:00' + interval '3 hours'</code>
+ → <code class="returnvalue">04:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">-</code> <code class="type">interval</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Negate an interval
+ </p>
+ <p>
+ <code class="literal">- interval '23 hours'</code>
+ → <code class="returnvalue">-23:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">date</code> <code class="literal">-</code> <code class="type">date</code>
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Subtract dates, producing the number of days elapsed
+ </p>
+ <p>
+ <code class="literal">date '2001-10-01' - date '2001-09-28'</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">date</code> <code class="literal">-</code> <code class="type">integer</code>
+ → <code class="returnvalue">date</code>
+ </p>
+ <p>
+ Subtract a number of days from a date
+ </p>
+ <p>
+ <code class="literal">date '2001-10-01' - 7</code>
+ → <code class="returnvalue">2001-09-24</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">date</code> <code class="literal">-</code> <code class="type">interval</code>
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Subtract an interval from a date
+ </p>
+ <p>
+ <code class="literal">date '2001-09-28' - interval '1 hour'</code>
+ → <code class="returnvalue">2001-09-27 23:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">time</code> <code class="literal">-</code> <code class="type">time</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Subtract times
+ </p>
+ <p>
+ <code class="literal">time '05:00' - time '03:00'</code>
+ → <code class="returnvalue">02:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">time</code> <code class="literal">-</code> <code class="type">interval</code>
+ → <code class="returnvalue">time</code>
+ </p>
+ <p>
+ Subtract an interval from a time
+ </p>
+ <p>
+ <code class="literal">time '05:00' - interval '2 hours'</code>
+ → <code class="returnvalue">03:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">timestamp</code> <code class="literal">-</code> <code class="type">interval</code>
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Subtract an interval from a timestamp
+ </p>
+ <p>
+ <code class="literal">timestamp '2001-09-28 23:00' - interval '23 hours'</code>
+ → <code class="returnvalue">2001-09-28 00:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">interval</code> <code class="literal">-</code> <code class="type">interval</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Subtract intervals
+ </p>
+ <p>
+ <code class="literal">interval '1 day' - interval '1 hour'</code>
+ → <code class="returnvalue">1 day -01:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">timestamp</code> <code class="literal">-</code> <code class="type">timestamp</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Subtract timestamps (converting 24-hour intervals into days,
+ similarly to <code class="function">justify_hours()</code>)
+ </p>
+ <p>
+ <code class="literal">timestamp '2001-09-29 03:00' - timestamp '2001-07-27 12:00'</code>
+ → <code class="returnvalue">63 days 15:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">interval</code> <code class="literal">*</code> <code class="type">double precision</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Multiply an interval by a scalar
+ </p>
+ <p>
+ <code class="literal">interval '1 second' * 900</code>
+ → <code class="returnvalue">00:15:00</code>
+ </p>
+ <p>
+ <code class="literal">interval '1 day' * 21</code>
+ → <code class="returnvalue">21 days</code>
+ </p>
+ <p>
+ <code class="literal">interval '1 hour' * 3.5</code>
+ → <code class="returnvalue">03:30:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">interval</code> <code class="literal">/</code> <code class="type">double precision</code>
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Divide an interval by a scalar
+ </p>
+ <p>
+ <code class="literal">interval '1 hour' / 1.5</code>
+ → <code class="returnvalue">00:40:00</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-DATETIME-TABLE"><p class="title"><strong>Table 9.33. Date/Time Functions</strong></p><div class="table-contents"><table class="table" summary="Date/Time Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">age</code> ( <code class="type">timestamp</code>, <code class="type">timestamp</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Subtract arguments, producing a <span class="quote">“<span class="quote">symbolic</span>”</span> result that
+ uses years and months, rather than just days
+ </p>
+ <p>
+ <code class="literal">age(timestamp '2001-04-10', timestamp '1957-06-13')</code>
+ → <code class="returnvalue">43 years 9 mons 27 days</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">age</code> ( <code class="type">timestamp</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Subtract argument from <code class="function">current_date</code> (at midnight)
+ </p>
+ <p>
+ <code class="literal">age(timestamp '1957-06-13')</code>
+ → <code class="returnvalue">62 years 6 mons 10 days</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">clock_timestamp</code> ( )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Current date and time (changes during statement execution);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">clock_timestamp()</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.662522-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">current_date</code>
+ → <code class="returnvalue">date</code>
+ </p>
+ <p>
+ Current date; see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">current_date</code>
+ → <code class="returnvalue">2019-12-23</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">current_time</code>
+ → <code class="returnvalue">time with time zone</code>
+ </p>
+ <p>
+ Current time of day; see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">current_time</code>
+ → <code class="returnvalue">14:39:53.662522-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">current_time</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">time with time zone</code>
+ </p>
+ <p>
+ Current time of day, with limited precision;
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">current_time(2)</code>
+ → <code class="returnvalue">14:39:53.66-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">current_timestamp</code>
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Current date and time (start of current transaction);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">current_timestamp</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.662522-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">current_timestamp</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Current date and time (start of current transaction), with limited precision;
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">current_timestamp(0)</code>
+ → <code class="returnvalue">2019-12-23 14:39:53-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">date_bin</code> ( <code class="type">interval</code>, <code class="type">timestamp</code>, <code class="type">timestamp</code> )
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Bin input into specified interval aligned with specified origin; see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-BIN" title="9.9.3. date_bin">Section 9.9.3</a>
+ </p>
+ <p>
+ <code class="literal">date_bin('15 minutes', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 20:05:00')</code>
+ → <code class="returnvalue">2001-02-16 20:35:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">date_part</code> ( <code class="type">text</code>, <code class="type">timestamp</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Get timestamp subfield (equivalent to <code class="function">extract</code>);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT" title="9.9.1. EXTRACT, date_part">Section 9.9.1</a>
+ </p>
+ <p>
+ <code class="literal">date_part('hour', timestamp '2001-02-16 20:38:40')</code>
+ → <code class="returnvalue">20</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">date_part</code> ( <code class="type">text</code>, <code class="type">interval</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Get interval subfield (equivalent to <code class="function">extract</code>);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT" title="9.9.1. EXTRACT, date_part">Section 9.9.1</a>
+ </p>
+ <p>
+ <code class="literal">date_part('month', interval '2 years 3 months')</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">date_trunc</code> ( <code class="type">text</code>, <code class="type">timestamp</code> )
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Truncate to specified precision; see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-TRUNC" title="9.9.2. date_trunc">Section 9.9.2</a>
+ </p>
+ <p>
+ <code class="literal">date_trunc('hour', timestamp '2001-02-16 20:38:40')</code>
+ → <code class="returnvalue">2001-02-16 20:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">date_trunc</code> ( <code class="type">text</code>, <code class="type">timestamp with time zone</code>, <code class="type">text</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Truncate to specified precision in the specified time zone; see
+ <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-TRUNC" title="9.9.2. date_trunc">Section 9.9.2</a>
+ </p>
+ <p>
+ <code class="literal">date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Australia/Sydney')</code>
+ → <code class="returnvalue">2001-02-16 13:00:00+00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">date_trunc</code> ( <code class="type">text</code>, <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Truncate to specified precision; see
+ <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-TRUNC" title="9.9.2. date_trunc">Section 9.9.2</a>
+ </p>
+ <p>
+ <code class="literal">date_trunc('hour', interval '2 days 3 hours 40 minutes')</code>
+ → <code class="returnvalue">2 days 03:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">extract</code> ( <em class="parameter"><code>field</code></em> <code class="literal">from</code> <code class="type">timestamp</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Get timestamp subfield; see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT" title="9.9.1. EXTRACT, date_part">Section 9.9.1</a>
+ </p>
+ <p>
+ <code class="literal">extract(hour from timestamp '2001-02-16 20:38:40')</code>
+ → <code class="returnvalue">20</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">extract</code> ( <em class="parameter"><code>field</code></em> <code class="literal">from</code> <code class="type">interval</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Get interval subfield; see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT" title="9.9.1. EXTRACT, date_part">Section 9.9.1</a>
+ </p>
+ <p>
+ <code class="literal">extract(month from interval '2 years 3 months')</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">isfinite</code> ( <code class="type">date</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test for finite date (not +/-infinity)
+ </p>
+ <p>
+ <code class="literal">isfinite(date '2001-02-16')</code>
+ → <code class="returnvalue">true</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">isfinite</code> ( <code class="type">timestamp</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test for finite timestamp (not +/-infinity)
+ </p>
+ <p>
+ <code class="literal">isfinite(timestamp 'infinity')</code>
+ → <code class="returnvalue">false</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">isfinite</code> ( <code class="type">interval</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Test for finite interval (currently always true)
+ </p>
+ <p>
+ <code class="literal">isfinite(interval '4 hours')</code>
+ → <code class="returnvalue">true</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.20.1.1.1" class="indexterm"></a>
+ <code class="function">justify_days</code> ( <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Adjust interval so 30-day time periods are represented as months
+ </p>
+ <p>
+ <code class="literal">justify_days(interval '35 days')</code>
+ → <code class="returnvalue">1 mon 5 days</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">justify_hours</code> ( <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Adjust interval so 24-hour time periods are represented as days
+ </p>
+ <p>
+ <code class="literal">justify_hours(interval '27 hours')</code>
+ → <code class="returnvalue">1 day 03:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">justify_interval</code> ( <code class="type">interval</code> )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Adjust interval using <code class="function">justify_days</code>
+ and <code class="function">justify_hours</code>, with additional sign
+ adjustments
+ </p>
+ <p>
+ <code class="literal">justify_interval(interval '1 mon -1 hour')</code>
+ → <code class="returnvalue">29 days 23:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">localtime</code>
+ → <code class="returnvalue">time</code>
+ </p>
+ <p>
+ Current time of day;
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">localtime</code>
+ → <code class="returnvalue">14:39:53.662522</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">localtime</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">time</code>
+ </p>
+ <p>
+ Current time of day, with limited precision;
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">localtime(0)</code>
+ → <code class="returnvalue">14:39:53</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.25.1.1.1" class="indexterm"></a>
+ <code class="function">localtimestamp</code>
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Current date and time (start of current transaction);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">localtimestamp</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.662522</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">localtimestamp</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Current date and time (start of current
+ transaction), with limited precision;
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">localtimestamp(2)</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.66</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.27.1.1.1" class="indexterm"></a>
+ <code class="function">make_date</code> ( <em class="parameter"><code>year</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>month</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>day</code></em> <code class="type">int</code> )
+ → <code class="returnvalue">date</code>
+ </p>
+ <p>
+ Create date from year, month and day fields
+ (negative years signify BC)
+ </p>
+ <p>
+ <code class="literal">make_date(2013, 7, 15)</code>
+ → <code class="returnvalue">2013-07-15</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature"><a id="id-1.5.8.15.6.2.2.28.1.1.1" class="indexterm"></a>
+ <code class="function">make_interval</code> ( [<span class="optional"> <em class="parameter"><code>years</code></em> <code class="type">int</code>
+ [<span class="optional">, <em class="parameter"><code>months</code></em> <code class="type">int</code>
+ [<span class="optional">, <em class="parameter"><code>weeks</code></em> <code class="type">int</code>
+ [<span class="optional">, <em class="parameter"><code>days</code></em> <code class="type">int</code>
+ [<span class="optional">, <em class="parameter"><code>hours</code></em> <code class="type">int</code>
+ [<span class="optional">, <em class="parameter"><code>mins</code></em> <code class="type">int</code>
+ [<span class="optional">, <em class="parameter"><code>secs</code></em> <code class="type">double precision</code>
+ </span>]</span>]</span>]</span>]</span>]</span>]</span>] )
+ → <code class="returnvalue">interval</code>
+ </p>
+ <p>
+ Create interval from years, months, weeks, days, hours, minutes and
+ seconds fields, each of which can default to zero
+ </p>
+ <p>
+ <code class="literal">make_interval(days =&gt; 10)</code>
+ → <code class="returnvalue">10 days</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.29.1.1.1" class="indexterm"></a>
+ <code class="function">make_time</code> ( <em class="parameter"><code>hour</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>min</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>sec</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">time</code>
+ </p>
+ <p>
+ Create time from hour, minute and seconds fields
+ </p>
+ <p>
+ <code class="literal">make_time(8, 15, 23.5)</code>
+ → <code class="returnvalue">08:15:23.5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.30.1.1.1" class="indexterm"></a>
+ <code class="function">make_timestamp</code> ( <em class="parameter"><code>year</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>month</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>day</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>hour</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>min</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>sec</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">timestamp</code>
+ </p>
+ <p>
+ Create timestamp from year, month, day, hour, minute and seconds fields
+ (negative years signify BC)
+ </p>
+ <p>
+ <code class="literal">make_timestamp(2013, 7, 15, 8, 15, 23.5)</code>
+ → <code class="returnvalue">2013-07-15 08:15:23.5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.31.1.1.1" class="indexterm"></a>
+ <code class="function">make_timestamptz</code> ( <em class="parameter"><code>year</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>month</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>day</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>hour</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>min</code></em> <code class="type">int</code>,
+ <em class="parameter"><code>sec</code></em> <code class="type">double precision</code>
+ [<span class="optional">, <em class="parameter"><code>timezone</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Create timestamp with time zone from year, month, day, hour, minute
+ and seconds fields (negative years signify BC).
+ If <em class="parameter"><code>timezone</code></em> is not
+ specified, the current time zone is used; the examples assume the
+ session time zone is <code class="literal">Europe/London</code>
+ </p>
+ <p>
+ <code class="literal">make_timestamptz(2013, 7, 15, 8, 15, 23.5)</code>
+ → <code class="returnvalue">2013-07-15 08:15:23.5+01</code>
+ </p>
+ <p>
+ <code class="literal">make_timestamptz(2013, 7, 15, 8, 15, 23.5, 'America/New_York')</code>
+ → <code class="returnvalue">2013-07-15 13:15:23.5+01</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.32.1.1.1" class="indexterm"></a>
+ <code class="function">now</code> ( )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Current date and time (start of current transaction);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">now()</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.662522-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.33.1.1.1" class="indexterm"></a>
+ <code class="function">statement_timestamp</code> ( )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Current date and time (start of current statement);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">statement_timestamp()</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.662522-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.34.1.1.1" class="indexterm"></a>
+ <code class="function">timeofday</code> ( )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Current date and time
+ (like <code class="function">clock_timestamp</code>, but as a <code class="type">text</code> string);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">timeofday()</code>
+ → <code class="returnvalue">Mon Dec 23 14:39:53.662522 2019 EST</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.35.1.1.1" class="indexterm"></a>
+ <code class="function">transaction_timestamp</code> ( )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Current date and time (start of current transaction);
+ see <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT" title="9.9.5. Current Date/Time">Section 9.9.5</a>
+ </p>
+ <p>
+ <code class="literal">transaction_timestamp()</code>
+ → <code class="returnvalue">2019-12-23 14:39:53.662522-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.15.6.2.2.36.1.1.1" class="indexterm"></a>
+ <code class="function">to_timestamp</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Convert Unix epoch (seconds since 1970-01-01 00:00:00+00) to
+ timestamp with time zone
+ </p>
+ <p>
+ <code class="literal">to_timestamp(1284352323)</code>
+ → <code class="returnvalue">2010-09-13 04:32:03+00</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a id="id-1.5.8.15.7.1" class="indexterm"></a>
+ In addition to these functions, the SQL <code class="literal">OVERLAPS</code> operator is
+ supported:
+</p><pre class="synopsis">
+(<em class="replaceable"><code>start1</code></em>, <em class="replaceable"><code>end1</code></em>) OVERLAPS (<em class="replaceable"><code>start2</code></em>, <em class="replaceable"><code>end2</code></em>)
+(<em class="replaceable"><code>start1</code></em>, <em class="replaceable"><code>length1</code></em>) OVERLAPS (<em class="replaceable"><code>start2</code></em>, <em class="replaceable"><code>length2</code></em>)
+</pre><p>
+ This expression yields true when two time periods (defined by their
+ endpoints) overlap, false when they do not overlap. The endpoints
+ can be specified as pairs of dates, times, or time stamps; or as
+ a date, time, or time stamp followed by an interval. When a pair
+ of values is provided, either the start or the end can be written
+ first; <code class="literal">OVERLAPS</code> automatically takes the earlier value
+ of the pair as the start. Each time period is considered to
+ represent the half-open interval <em class="replaceable"><code>start</code></em> <code class="literal">&lt;=</code>
+ <em class="replaceable"><code>time</code></em> <code class="literal">&lt;</code> <em class="replaceable"><code>end</code></em>, unless
+ <em class="replaceable"><code>start</code></em> and <em class="replaceable"><code>end</code></em> are equal in which case it
+ represents that single time instant. This means for instance that two
+ time periods with only an endpoint in common do not overlap.
+ </p><pre class="screen">
+SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS
+ (DATE '2001-10-30', DATE '2002-10-30');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">true</code>
+SELECT (DATE '2001-02-16', INTERVAL '100 days') OVERLAPS
+ (DATE '2001-10-30', DATE '2002-10-30');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">false</code>
+SELECT (DATE '2001-10-29', DATE '2001-10-30') OVERLAPS
+ (DATE '2001-10-30', DATE '2001-10-31');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">false</code>
+SELECT (DATE '2001-10-30', DATE '2001-10-30') OVERLAPS
+ (DATE '2001-10-30', DATE '2001-10-31');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">true</code>
+</pre><p>
+ When adding an <code class="type">interval</code> value to (or subtracting an
+ <code class="type">interval</code> value from) a <code class="type">timestamp with time zone</code>
+ value, the days component advances or decrements the date of the
+ <code class="type">timestamp with time zone</code> by the indicated number of days,
+ keeping the time of day the same.
+ Across daylight saving time changes (when the session time zone is set to a
+ time zone that recognizes DST), this means <code class="literal">interval '1 day'</code>
+ does not necessarily equal <code class="literal">interval '24 hours'</code>.
+ For example, with the session time zone set
+ to <code class="literal">America/Denver</code>:
+</p><pre class="screen">
+SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '1 day';
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2005-04-03 12:00:00-06</code>
+SELECT timestamp with time zone '2005-04-02 12:00:00-07' + interval '24 hours';
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2005-04-03 13:00:00-06</code>
+</pre><p>
+ This happens because an hour was skipped due to a change in daylight saving
+ time at <code class="literal">2005-04-03 02:00:00</code> in time zone
+ <code class="literal">America/Denver</code>.
+ </p><p>
+ Note there can be ambiguity in the <code class="literal">months</code> field returned by
+ <code class="function">age</code> because different months have different numbers of
+ days. <span class="productname">PostgreSQL</span>'s approach uses the month from the
+ earlier of the two dates when calculating partial months. For example,
+ <code class="literal">age('2004-06-01', '2004-04-30')</code> uses April to yield
+ <code class="literal">1 mon 1 day</code>, while using May would yield <code class="literal">1 mon 2
+ days</code> because May has 31 days, while April has only 30.
+ </p><p>
+ Subtraction of dates and timestamps can also be complex. One conceptually
+ simple way to perform subtraction is to convert each value to a number
+ of seconds using <code class="literal">EXTRACT(EPOCH FROM ...)</code>, then subtract the
+ results; this produces the
+ number of <span class="emphasis"><em>seconds</em></span> between the two values. This will adjust
+ for the number of days in each month, timezone changes, and daylight
+ saving time adjustments. Subtraction of date or timestamp
+ values with the <span class="quote">“<span class="quote"><code class="literal">-</code></span>”</span> operator
+ returns the number of days (24-hours) and hours/minutes/seconds
+ between the values, making the same adjustments. The <code class="function">age</code>
+ function returns years, months, days, and hours/minutes/seconds,
+ performing field-by-field subtraction and then adjusting for negative
+ field values. The following queries illustrate the differences in these
+ approaches. The sample results were produced with <code class="literal">timezone
+ = 'US/Eastern'</code>; there is a daylight saving time change between the
+ two dates used:
+ </p><pre class="screen">
+SELECT EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
+ EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">10537200.000000</code>
+SELECT (EXTRACT(EPOCH FROM timestamptz '2013-07-01 12:00:00') -
+ EXTRACT(EPOCH FROM timestamptz '2013-03-01 12:00:00'))
+ / 60 / 60 / 24;
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">121.9583333333333333</code>
+SELECT timestamptz '2013-07-01 12:00:00' - timestamptz '2013-03-01 12:00:00';
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">121 days 23:00:00</code>
+SELECT age(timestamptz '2013-07-01 12:00:00', timestamptz '2013-03-01 12:00:00');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">4 mons</code>
+</pre><div class="sect2" id="FUNCTIONS-DATETIME-EXTRACT"><div class="titlepage"><div><div><h3 class="title">9.9.1. <code class="function">EXTRACT</code>, <code class="function">date_part</code></h3></div></div></div><a id="id-1.5.8.15.13.2" class="indexterm"></a><a id="id-1.5.8.15.13.3" class="indexterm"></a><pre class="synopsis">
+EXTRACT(<em class="replaceable"><code>field</code></em> FROM <em class="replaceable"><code>source</code></em>)
+</pre><p>
+ The <code class="function">extract</code> function retrieves subfields
+ such as year or hour from date/time values.
+ <em class="replaceable"><code>source</code></em> must be a value expression of
+ type <code class="type">timestamp</code>, <code class="type">time</code>, or <code class="type">interval</code>.
+ (Expressions of type <code class="type">date</code> are
+ cast to <code class="type">timestamp</code> and can therefore be used as
+ well.) <em class="replaceable"><code>field</code></em> is an identifier or
+ string that selects what field to extract from the source value.
+ The <code class="function">extract</code> function returns values of type
+ <code class="type">numeric</code>.
+ The following are valid field names:
+
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">century</code></span></dt><dd><p>
+ The century
+ </p><pre class="screen">
+SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">20</code>
+SELECT EXTRACT(CENTURY FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">21</code>
+</pre><p>
+ The first century starts at 0001-01-01 00:00:00 AD, although
+ they did not know it at the time. This definition applies to all
+ Gregorian calendar countries. There is no century number 0,
+ you go from -1 century to 1 century.
+
+ If you disagree with this, please write your complaint to:
+ Pope, Cathedral Saint-Peter of Roma, Vatican.
+ </p></dd><dt><span class="term"><code class="literal">day</code></span></dt><dd><p>
+ For <code class="type">timestamp</code> values, the day (of the month) field
+ (1–31) ; for <code class="type">interval</code> values, the number of days
+ </p><pre class="screen">
+SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">16</code>
+
+SELECT EXTRACT(DAY FROM INTERVAL '40 days 1 minute');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">40</code>
+</pre></dd><dt><span class="term"><code class="literal">decade</code></span></dt><dd><p>
+ The year field divided by 10
+ </p><pre class="screen">
+SELECT EXTRACT(DECADE FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">200</code>
+</pre></dd><dt><span class="term"><code class="literal">dow</code></span></dt><dd><p>
+ The day of the week as Sunday (<code class="literal">0</code>) to
+ Saturday (<code class="literal">6</code>)
+ </p><pre class="screen">
+SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">5</code>
+</pre><p>
+ Note that <code class="function">extract</code>'s day of the week numbering
+ differs from that of the <code class="function">to_char(...,
+ 'D')</code> function.
+ </p></dd><dt><span class="term"><code class="literal">doy</code></span></dt><dd><p>
+ The day of the year (1–365/366)
+ </p><pre class="screen">
+SELECT EXTRACT(DOY FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">47</code>
+</pre></dd><dt><span class="term"><code class="literal">epoch</code></span></dt><dd><p>
+ For <code class="type">timestamp with time zone</code> values, the
+ number of seconds since 1970-01-01 00:00:00 UTC (negative for
+ timestamps before that);
+ for <code class="type">date</code> and <code class="type">timestamp</code> values, the
+ nominal number of seconds since 1970-01-01 00:00:00,
+ without regard to timezone or daylight-savings rules;
+ for <code class="type">interval</code> values, the total number
+ of seconds in the interval
+ </p><pre class="screen">
+SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40.12-08');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">982384720.120000</code>
+
+SELECT EXTRACT(EPOCH FROM TIMESTAMP '2001-02-16 20:38:40.12');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">982355920.120000</code>
+
+SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">442800.000000</code>
+</pre><p>
+ You can convert an epoch value back to a <code class="type">timestamp with time zone</code>
+ with <code class="function">to_timestamp</code>:
+ </p><pre class="screen">
+SELECT to_timestamp(982384720.12);
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-17 04:38:40.12+00</code>
+</pre><p>
+ Beware that applying <code class="function">to_timestamp</code> to an epoch
+ extracted from a <code class="type">date</code> or <code class="type">timestamp</code> value
+ could produce a misleading result: the result will effectively
+ assume that the original value had been given in UTC, which might
+ not be the case.
+ </p></dd><dt><span class="term"><code class="literal">hour</code></span></dt><dd><p>
+ The hour field (0–23)
+ </p><pre class="screen">
+SELECT EXTRACT(HOUR FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">20</code>
+</pre></dd><dt><span class="term"><code class="literal">isodow</code></span></dt><dd><p>
+ The day of the week as Monday (<code class="literal">1</code>) to
+ Sunday (<code class="literal">7</code>)
+ </p><pre class="screen">
+SELECT EXTRACT(ISODOW FROM TIMESTAMP '2001-02-18 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">7</code>
+</pre><p>
+ This is identical to <code class="literal">dow</code> except for Sunday. This
+ matches the <acronym class="acronym">ISO</acronym> 8601 day of the week numbering.
+ </p></dd><dt><span class="term"><code class="literal">isoyear</code></span></dt><dd><p>
+ The <acronym class="acronym">ISO</acronym> 8601 week-numbering year that the date
+ falls in (not applicable to intervals)
+ </p><pre class="screen">
+SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-01');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2005</code>
+SELECT EXTRACT(ISOYEAR FROM DATE '2006-01-02');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2006</code>
+</pre><p>
+ Each <acronym class="acronym">ISO</acronym> 8601 week-numbering year begins with the
+ Monday of the week containing the 4th of January, so in early
+ January or late December the <acronym class="acronym">ISO</acronym> year may be
+ different from the Gregorian year. See the <code class="literal">week</code>
+ field for more information.
+ </p><p>
+ This field is not available in PostgreSQL releases prior to 8.3.
+ </p></dd><dt><span class="term"><code class="literal">julian</code></span></dt><dd><p>
+ The <em class="firstterm">Julian Date</em> corresponding to the
+ date or timestamp (not applicable to intervals). Timestamps
+ that are not local midnight result in a fractional value. See
+ <a class="xref" href="datetime-julian-dates.html" title="B.7. Julian Dates">Section B.7</a> for more information.
+ </p><pre class="screen">
+SELECT EXTRACT(JULIAN FROM DATE '2006-01-01');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2453737</code>
+SELECT EXTRACT(JULIAN FROM TIMESTAMP '2006-01-01 12:00');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2453737.50000000000000000000</code>
+</pre></dd><dt><span class="term"><code class="literal">microseconds</code></span></dt><dd><p>
+ The seconds field, including fractional parts, multiplied by 1
+ 000 000; note that this includes full seconds
+ </p><pre class="screen">
+SELECT EXTRACT(MICROSECONDS FROM TIME '17:12:28.5');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">28500000</code>
+</pre></dd><dt><span class="term"><code class="literal">millennium</code></span></dt><dd><p>
+ The millennium
+ </p><pre class="screen">
+SELECT EXTRACT(MILLENNIUM FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">3</code>
+</pre><p>
+ Years in the 1900s are in the second millennium.
+ The third millennium started January 1, 2001.
+ </p></dd><dt><span class="term"><code class="literal">milliseconds</code></span></dt><dd><p>
+ The seconds field, including fractional parts, multiplied by
+ 1000. Note that this includes full seconds.
+ </p><pre class="screen">
+SELECT EXTRACT(MILLISECONDS FROM TIME '17:12:28.5');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">28500.000</code>
+</pre></dd><dt><span class="term"><code class="literal">minute</code></span></dt><dd><p>
+ The minutes field (0–59)
+ </p><pre class="screen">
+SELECT EXTRACT(MINUTE FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">38</code>
+</pre></dd><dt><span class="term"><code class="literal">month</code></span></dt><dd><p>
+ For <code class="type">timestamp</code> values, the number of the month
+ within the year (1–12) ; for <code class="type">interval</code> values,
+ the number of months, modulo 12 (0–11)
+ </p><pre class="screen">
+SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2</code>
+
+SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">3</code>
+
+SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">1</code>
+</pre></dd><dt><span class="term"><code class="literal">quarter</code></span></dt><dd><p>
+ The quarter of the year (1–4) that the date is in
+ </p><pre class="screen">
+SELECT EXTRACT(QUARTER FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">1</code>
+</pre></dd><dt><span class="term"><code class="literal">second</code></span></dt><dd><p>
+ The seconds field, including any fractional seconds
+ </p><pre class="screen">
+SELECT EXTRACT(SECOND FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">40.000000</code>
+
+SELECT EXTRACT(SECOND FROM TIME '17:12:28.5');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">28.500000</code>
+</pre></dd><dt><span class="term"><code class="literal">timezone</code></span></dt><dd><p>
+ The time zone offset from UTC, measured in seconds. Positive values
+ correspond to time zones east of UTC, negative values to
+ zones west of UTC. (Technically,
+ <span class="productname">PostgreSQL</span> does not use UTC because
+ leap seconds are not handled.)
+ </p></dd><dt><span class="term"><code class="literal">timezone_hour</code></span></dt><dd><p>
+ The hour component of the time zone offset
+ </p></dd><dt><span class="term"><code class="literal">timezone_minute</code></span></dt><dd><p>
+ The minute component of the time zone offset
+ </p></dd><dt><span class="term"><code class="literal">week</code></span></dt><dd><p>
+ The number of the <acronym class="acronym">ISO</acronym> 8601 week-numbering week of
+ the year. By definition, ISO weeks start on Mondays and the first
+ week of a year contains January 4 of that year. In other words, the
+ first Thursday of a year is in week 1 of that year.
+ </p><p>
+ In the ISO week-numbering system, it is possible for early-January
+ dates to be part of the 52nd or 53rd week of the previous year, and for
+ late-December dates to be part of the first week of the next year.
+ For example, <code class="literal">2005-01-01</code> is part of the 53rd week of year
+ 2004, and <code class="literal">2006-01-01</code> is part of the 52nd week of year
+ 2005, while <code class="literal">2012-12-31</code> is part of the first week of 2013.
+ It's recommended to use the <code class="literal">isoyear</code> field together with
+ <code class="literal">week</code> to get consistent results.
+ </p><pre class="screen">
+SELECT EXTRACT(WEEK FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">7</code>
+</pre></dd><dt><span class="term"><code class="literal">year</code></span></dt><dd><p>
+ The year field. Keep in mind there is no <code class="literal">0 AD</code>, so subtracting
+ <code class="literal">BC</code> years from <code class="literal">AD</code> years should be done with care.
+ </p><pre class="screen">
+SELECT EXTRACT(YEAR FROM TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001</code>
+</pre></dd></dl></div><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When the input value is +/-Infinity, <code class="function">extract</code> returns
+ +/-Infinity for monotonically-increasing fields (<code class="literal">epoch</code>,
+ <code class="literal">julian</code>, <code class="literal">year</code>, <code class="literal">isoyear</code>,
+ <code class="literal">decade</code>, <code class="literal">century</code>, and <code class="literal">millennium</code>).
+ For other fields, NULL is returned. <span class="productname">PostgreSQL</span>
+ versions before 9.6 returned zero for all cases of infinite input.
+ </p></div><p>
+ The <code class="function">extract</code> function is primarily intended
+ for computational processing. For formatting date/time values for
+ display, see <a class="xref" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Section 9.8</a>.
+ </p><p>
+ The <code class="function">date_part</code> function is modeled on the traditional
+ <span class="productname">Ingres</span> equivalent to the
+ <acronym class="acronym">SQL</acronym>-standard function <code class="function">extract</code>:
+</p><pre class="synopsis">
+date_part('<em class="replaceable"><code>field</code></em>', <em class="replaceable"><code>source</code></em>)
+</pre><p>
+ Note that here the <em class="replaceable"><code>field</code></em> parameter needs to
+ be a string value, not a name. The valid field names for
+ <code class="function">date_part</code> are the same as for
+ <code class="function">extract</code>.
+ For historical reasons, the <code class="function">date_part</code> function
+ returns values of type <code class="type">double precision</code>. This can result in
+ a loss of precision in certain uses. Using <code class="function">extract</code>
+ is recommended instead.
+ </p><pre class="screen">
+SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">16</code>
+
+SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">4</code>
+</pre></div><div class="sect2" id="FUNCTIONS-DATETIME-TRUNC"><div class="titlepage"><div><div><h3 class="title">9.9.2. <code class="function">date_trunc</code></h3></div></div></div><a id="id-1.5.8.15.14.2" class="indexterm"></a><p>
+ The function <code class="function">date_trunc</code> is conceptually
+ similar to the <code class="function">trunc</code> function for numbers.
+ </p><p>
+</p><pre class="synopsis">
+date_trunc(<em class="replaceable"><code>field</code></em>, <em class="replaceable"><code>source</code></em> [, <em class="replaceable"><code>time_zone</code></em> ])
+</pre><p>
+ <em class="replaceable"><code>source</code></em> is a value expression of type
+ <code class="type">timestamp</code>, <code class="type">timestamp with time zone</code>,
+ or <code class="type">interval</code>.
+ (Values of type <code class="type">date</code> and
+ <code class="type">time</code> are cast automatically to <code class="type">timestamp</code> or
+ <code class="type">interval</code>, respectively.)
+ <em class="replaceable"><code>field</code></em> selects to which precision to
+ truncate the input value. The return value is likewise of type
+ <code class="type">timestamp</code>, <code class="type">timestamp with time zone</code>,
+ or <code class="type">interval</code>,
+ and it has all fields that are less significant than the
+ selected one set to zero (or one, for day and month).
+ </p><p>
+ Valid values for <em class="replaceable"><code>field</code></em> are:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">microseconds</code></td></tr><tr><td><code class="literal">milliseconds</code></td></tr><tr><td><code class="literal">second</code></td></tr><tr><td><code class="literal">minute</code></td></tr><tr><td><code class="literal">hour</code></td></tr><tr><td><code class="literal">day</code></td></tr><tr><td><code class="literal">week</code></td></tr><tr><td><code class="literal">month</code></td></tr><tr><td><code class="literal">quarter</code></td></tr><tr><td><code class="literal">year</code></td></tr><tr><td><code class="literal">decade</code></td></tr><tr><td><code class="literal">century</code></td></tr><tr><td><code class="literal">millennium</code></td></tr></table><p>
+ </p><p>
+ When the input value is of type <code class="type">timestamp with time zone</code>,
+ the truncation is performed with respect to a particular time zone;
+ for example, truncation to <code class="literal">day</code> produces a value that
+ is midnight in that zone. By default, truncation is done with respect
+ to the current <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> setting, but the
+ optional <em class="replaceable"><code>time_zone</code></em> argument can be provided
+ to specify a different time zone. The time zone name can be specified
+ in any of the ways described in <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a>.
+ </p><p>
+ A time zone cannot be specified when processing <code class="type">timestamp without
+ time zone</code> or <code class="type">interval</code> inputs. These are always
+ taken at face value.
+ </p><p>
+ Examples (assuming the local time zone is <code class="literal">America/New_York</code>):
+</p><pre class="screen">
+SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-16 20:00:00</code>
+
+SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-01-01 00:00:00</code>
+
+SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-16 00:00:00-05</code>
+
+SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-16 08:00:00-05</code>
+
+SELECT date_trunc('hour', INTERVAL '3 days 02:47:33');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">3 days 02:00:00</code>
+</pre><p>
+ </p></div><div class="sect2" id="FUNCTIONS-DATETIME-BIN"><div class="titlepage"><div><div><h3 class="title">9.9.3. <code class="function">date_bin</code></h3></div></div></div><a id="id-1.5.8.15.15.2" class="indexterm"></a><p>
+ The function <code class="function">date_bin</code> <span class="quote">“<span class="quote">bins</span>”</span> the input
+ timestamp into the specified interval (the <em class="firstterm">stride</em>)
+ aligned with a specified origin.
+ </p><p>
+</p><pre class="synopsis">
+date_bin(<em class="replaceable"><code>stride</code></em>, <em class="replaceable"><code>source</code></em>, <em class="replaceable"><code>origin</code></em>)
+</pre><p>
+ <em class="replaceable"><code>source</code></em> is a value expression of type
+ <code class="type">timestamp</code> or <code class="type">timestamp with time zone</code>. (Values
+ of type <code class="type">date</code> are cast automatically to
+ <code class="type">timestamp</code>.) <em class="replaceable"><code>stride</code></em> is a value
+ expression of type <code class="type">interval</code>. The return value is likewise
+ of type <code class="type">timestamp</code> or <code class="type">timestamp with time zone</code>,
+ and it marks the beginning of the bin into which the
+ <em class="replaceable"><code>source</code></em> is placed.
+ </p><p>
+ Examples:
+</p><pre class="screen">
+SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2020-02-11 15:30:00</code>
+
+SELECT date_bin('15 minutes', TIMESTAMP '2020-02-11 15:44:17', TIMESTAMP '2001-01-01 00:02:30');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2020-02-11 15:32:30</code>
+</pre><p>
+ </p><p>
+ In the case of full units (1 minute, 1 hour, etc.), it gives the same result as
+ the analogous <code class="function">date_trunc</code> call, but the difference is
+ that <code class="function">date_bin</code> can truncate to an arbitrary interval.
+ </p><p>
+ The <em class="parameter"><code>stride</code></em> interval must be greater than zero and
+ cannot contain units of month or larger.
+ </p></div><div class="sect2" id="FUNCTIONS-DATETIME-ZONECONVERT"><div class="titlepage"><div><div><h3 class="title">9.9.4. <code class="literal">AT TIME ZONE</code></h3></div></div></div><a id="id-1.5.8.15.16.2" class="indexterm"></a><a id="id-1.5.8.15.16.3" class="indexterm"></a><p>
+ The <code class="literal">AT TIME ZONE</code> operator converts time
+ stamp <span class="emphasis"><em>without</em></span> time zone to/from
+ time stamp <span class="emphasis"><em>with</em></span> time zone, and
+ <code class="type">time with time zone</code> values to different time
+ zones. <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT-TABLE" title="Table 9.34. AT TIME ZONE Variants">Table 9.34</a> shows its
+ variants.
+ </p><div class="table" id="FUNCTIONS-DATETIME-ZONECONVERT-TABLE"><p class="title"><strong>Table 9.34. <code class="literal">AT TIME ZONE</code> Variants</strong></p><div class="table-contents"><table class="table" summary="AT TIME ZONE Variants" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">timestamp without time zone</code> <code class="literal">AT TIME ZONE</code> <em class="replaceable"><code>zone</code></em>
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Converts given time stamp <span class="emphasis"><em>without</em></span> time zone to
+ time stamp <span class="emphasis"><em>with</em></span> time zone, assuming the given
+ value is in the named time zone.
+ </p>
+ <p>
+ <code class="literal">timestamp '2001-02-16 20:38:40' at time zone 'America/Denver'</code>
+ → <code class="returnvalue">2001-02-17 03:38:40+00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">timestamp with time zone</code> <code class="literal">AT TIME ZONE</code> <em class="replaceable"><code>zone</code></em>
+ → <code class="returnvalue">timestamp without time zone</code>
+ </p>
+ <p>
+ Converts given time stamp <span class="emphasis"><em>with</em></span> time zone to
+ time stamp <span class="emphasis"><em>without</em></span> time zone, as the time would
+ appear in that zone.
+ </p>
+ <p>
+ <code class="literal">timestamp with time zone '2001-02-16 20:38:40-05' at time zone 'America/Denver'</code>
+ → <code class="returnvalue">2001-02-16 18:38:40</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">time with time zone</code> <code class="literal">AT TIME ZONE</code> <em class="replaceable"><code>zone</code></em>
+ → <code class="returnvalue">time with time zone</code>
+ </p>
+ <p>
+ Converts given time <span class="emphasis"><em>with</em></span> time zone to a new time
+ zone. Since no date is supplied, this uses the currently active UTC
+ offset for the named destination zone.
+ </p>
+ <p>
+ <code class="literal">time with time zone '05:34:17-05' at time zone 'UTC'</code>
+ → <code class="returnvalue">10:34:17+00</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In these expressions, the desired time zone <em class="replaceable"><code>zone</code></em> can be
+ specified either as a text value (e.g., <code class="literal">'America/Los_Angeles'</code>)
+ or as an interval (e.g., <code class="literal">INTERVAL '-08:00'</code>).
+ In the text case, a time zone name can be specified in any of the ways
+ described in <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a>.
+ The interval case is only useful for zones that have fixed offsets from
+ UTC, so it is not very common in practice.
+ </p><p>
+ Examples (assuming the current <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> setting
+ is <code class="literal">America/Los_Angeles</code>):
+</p><pre class="screen">
+SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver';
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-16 19:38:40-08</code>
+
+SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver';
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-16 18:38:40</code>
+
+SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago';
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2001-02-16 05:38:40</code>
+</pre><p>
+ The first example adds a time zone to a value that lacks it, and
+ displays the value using the current <code class="varname">TimeZone</code>
+ setting. The second example shifts the time stamp with time zone value
+ to the specified time zone, and returns the value without a time zone.
+ This allows storage and display of values different from the current
+ <code class="varname">TimeZone</code> setting. The third example converts
+ Tokyo time to Chicago time.
+ </p><p>
+ The function <code class="literal"><code class="function">timezone</code>(<em class="replaceable"><code>zone</code></em>,
+ <em class="replaceable"><code>timestamp</code></em>)</code> is equivalent to the SQL-conforming construct
+ <code class="literal"><em class="replaceable"><code>timestamp</code></em> AT TIME ZONE
+ <em class="replaceable"><code>zone</code></em></code>.
+ </p></div><div class="sect2" id="FUNCTIONS-DATETIME-CURRENT"><div class="titlepage"><div><div><h3 class="title">9.9.5. Current Date/Time</h3></div></div></div><a id="id-1.5.8.15.17.2" class="indexterm"></a><a id="id-1.5.8.15.17.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a number of functions
+ that return values related to the current date and time. These
+ SQL-standard functions all return values based on the start time of
+ the current transaction:
+</p><pre class="synopsis">
+CURRENT_DATE
+CURRENT_TIME
+CURRENT_TIMESTAMP
+CURRENT_TIME(<em class="replaceable"><code>precision</code></em>)
+CURRENT_TIMESTAMP(<em class="replaceable"><code>precision</code></em>)
+LOCALTIME
+LOCALTIMESTAMP
+LOCALTIME(<em class="replaceable"><code>precision</code></em>)
+LOCALTIMESTAMP(<em class="replaceable"><code>precision</code></em>)
+</pre><p>
+ </p><p>
+ <code class="function">CURRENT_TIME</code> and
+ <code class="function">CURRENT_TIMESTAMP</code> deliver values with time zone;
+ <code class="function">LOCALTIME</code> and
+ <code class="function">LOCALTIMESTAMP</code> deliver values without time zone.
+ </p><p>
+ <code class="function">CURRENT_TIME</code>,
+ <code class="function">CURRENT_TIMESTAMP</code>,
+ <code class="function">LOCALTIME</code>, and
+ <code class="function">LOCALTIMESTAMP</code>
+ can optionally take
+ a precision parameter, which causes the result to be rounded
+ to that many fractional digits in the seconds field. Without a precision parameter,
+ the result is given to the full available precision.
+ </p><p>
+ Some examples:
+</p><pre class="screen">
+SELECT CURRENT_TIME;
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">14:39:53.662522-05</code>
+
+SELECT CURRENT_DATE;
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2019-12-23</code>
+
+SELECT CURRENT_TIMESTAMP;
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2019-12-23 14:39:53.662522-05</code>
+
+SELECT CURRENT_TIMESTAMP(2);
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2019-12-23 14:39:53.66-05</code>
+
+SELECT LOCALTIMESTAMP;
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">2019-12-23 14:39:53.662522</code>
+</pre><p>
+ </p><p>
+ Since these functions return
+ the start time of the current transaction, their values do not
+ change during the transaction. This is considered a feature:
+ the intent is to allow a single transaction to have a consistent
+ notion of the <span class="quote">“<span class="quote">current</span>”</span> time, so that multiple
+ modifications within the same transaction bear the same
+ time stamp.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Other database systems might advance these values more
+ frequently.
+ </p></div><p>
+ <span class="productname">PostgreSQL</span> also provides functions that
+ return the start time of the current statement, as well as the actual
+ current time at the instant the function is called. The complete list
+ of non-SQL-standard time functions is:
+</p><pre class="synopsis">
+transaction_timestamp()
+statement_timestamp()
+clock_timestamp()
+timeofday()
+now()
+</pre><p>
+ </p><p>
+ <code class="function">transaction_timestamp()</code> is equivalent to
+ <code class="function">CURRENT_TIMESTAMP</code>, but is named to clearly reflect
+ what it returns.
+ <code class="function">statement_timestamp()</code> returns the start time of the current
+ statement (more specifically, the time of receipt of the latest command
+ message from the client).
+ <code class="function">statement_timestamp()</code> and <code class="function">transaction_timestamp()</code>
+ return the same value during the first command of a transaction, but might
+ differ during subsequent commands.
+ <code class="function">clock_timestamp()</code> returns the actual current time, and
+ therefore its value changes even within a single SQL command.
+ <code class="function">timeofday()</code> is a historical
+ <span class="productname">PostgreSQL</span> function. Like
+ <code class="function">clock_timestamp()</code>, it returns the actual current time,
+ but as a formatted <code class="type">text</code> string rather than a <code class="type">timestamp
+ with time zone</code> value.
+ <code class="function">now()</code> is a traditional <span class="productname">PostgreSQL</span>
+ equivalent to <code class="function">transaction_timestamp()</code>.
+ </p><p>
+ All the date/time data types also accept the special literal value
+ <code class="literal">now</code> to specify the current date and time (again,
+ interpreted as the transaction start time). Thus,
+ the following three all return the same result:
+</p><pre class="programlisting">
+SELECT CURRENT_TIMESTAMP;
+SELECT now();
+SELECT TIMESTAMP 'now'; -- but see tip below
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Do not use the third form when specifying a value to be evaluated later,
+ for example in a <code class="literal">DEFAULT</code> clause for a table column.
+ The system will convert <code class="literal">now</code>
+ to a <code class="type">timestamp</code> as soon as the constant is parsed, so that when
+ the default value is needed,
+ the time of the table creation would be used! The first two
+ forms will not be evaluated until the default value is used,
+ because they are function calls. Thus they will give the desired
+ behavior of defaulting to the time of row insertion.
+ (See also <a class="xref" href="datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-VALUES" title="8.5.1.4. Special Values">Section 8.5.1.4</a>.)
+ </p></div></div><div class="sect2" id="FUNCTIONS-DATETIME-DELAY"><div class="titlepage"><div><div><h3 class="title">9.9.6. Delaying Execution</h3></div></div></div><a id="id-1.5.8.15.18.2" class="indexterm"></a><a id="id-1.5.8.15.18.3" class="indexterm"></a><a id="id-1.5.8.15.18.4" class="indexterm"></a><a id="id-1.5.8.15.18.5" class="indexterm"></a><a id="id-1.5.8.15.18.6" class="indexterm"></a><p>
+ The following functions are available to delay execution of the server
+ process:
+</p><pre class="synopsis">
+pg_sleep ( <code class="type">double precision</code> )
+pg_sleep_for ( <code class="type">interval</code> )
+pg_sleep_until ( <code class="type">timestamp with time zone</code> )
+</pre><p>
+
+ <code class="function">pg_sleep</code> makes the current session's process
+ sleep until the given number of seconds have
+ elapsed. Fractional-second delays can be specified.
+ <code class="function">pg_sleep_for</code> is a convenience function to
+ allow the sleep time to be specified as an <code class="type">interval</code>.
+ <code class="function">pg_sleep_until</code> is a convenience function for when
+ a specific wake-up time is desired.
+ For example:
+
+</p><pre class="programlisting">
+SELECT pg_sleep(1.5);
+SELECT pg_sleep_for('5 minutes');
+SELECT pg_sleep_until('tomorrow 03:00');
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The effective resolution of the sleep interval is platform-specific;
+ 0.01 seconds is a common value. The sleep delay will be at least as long
+ as specified. It might be longer depending on factors such as server load.
+ In particular, <code class="function">pg_sleep_until</code> is not guaranteed to
+ wake up exactly at the specified time, but it will not wake up any earlier.
+ </p></div><div class="warning"><h3 class="title">Warning</h3><p>
+ Make sure that your session does not hold more locks than necessary
+ when calling <code class="function">pg_sleep</code> or its variants. Otherwise
+ other sessions might have to wait for your sleeping process, slowing down
+ the entire system.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-enum.html" title="9.10. Enum Support Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.8. Data Type Formatting Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.10. Enum Support Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-enum.html b/doc/src/sgml/html/functions-enum.html
new file mode 100644
index 0000000..9aaf8ae
--- /dev/null
+++ b/doc/src/sgml/html/functions-enum.html
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.10. Enum Support Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators" /><link rel="next" href="functions-geometry.html" title="9.11. Geometric Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.10. Enum Support Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-ENUM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.10. Enum Support Functions</h2></div></div></div><p>
+ For enum types (described in <a class="xref" href="datatype-enum.html" title="8.7. Enumerated Types">Section 8.7</a>),
+ there are several functions that allow cleaner programming without
+ hard-coding particular values of an enum type.
+ These are listed in <a class="xref" href="functions-enum.html#FUNCTIONS-ENUM-TABLE" title="Table 9.35. Enum Support Functions">Table 9.35</a>. The examples
+ assume an enum type created as:
+
+</p><pre class="programlisting">
+CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple');
+</pre><p>
+
+ </p><div class="table" id="FUNCTIONS-ENUM-TABLE"><p class="title"><strong>Table 9.35. Enum Support Functions</strong></p><div class="table-contents"><table class="table" summary="Enum Support Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.16.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">enum_first</code> ( <code class="type">anyenum</code> )
+ → <code class="returnvalue">anyenum</code>
+ </p>
+ <p>
+ Returns the first value of the input enum type.
+ </p>
+ <p>
+ <code class="literal">enum_first(null::rainbow)</code>
+ → <code class="returnvalue">red</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.16.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">enum_last</code> ( <code class="type">anyenum</code> )
+ → <code class="returnvalue">anyenum</code>
+ </p>
+ <p>
+ Returns the last value of the input enum type.
+ </p>
+ <p>
+ <code class="literal">enum_last(null::rainbow)</code>
+ → <code class="returnvalue">purple</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.16.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">enum_range</code> ( <code class="type">anyenum</code> )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Returns all values of the input enum type in an ordered array.
+ </p>
+ <p>
+ <code class="literal">enum_range(null::rainbow)</code>
+ → <code class="returnvalue">{red,orange,yellow,​green,blue,purple}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">enum_range</code> ( <code class="type">anyenum</code>, <code class="type">anyenum</code> )
+ → <code class="returnvalue">anyarray</code>
+ </p>
+ <p>
+ Returns the range between the two given enum values, as an ordered
+ array. The values must be from the same enum type. If the first
+ parameter is null, the result will start with the first value of
+ the enum type.
+ If the second parameter is null, the result will end with the last
+ value of the enum type.
+ </p>
+ <p>
+ <code class="literal">enum_range('orange'::rainbow, 'green'::rainbow)</code>
+ → <code class="returnvalue">{orange,yellow,green}</code>
+ </p>
+ <p>
+ <code class="literal">enum_range(NULL, 'green'::rainbow)</code>
+ → <code class="returnvalue">{red,orange,​yellow,green}</code>
+ </p>
+ <p>
+ <code class="literal">enum_range('orange'::rainbow, NULL)</code>
+ → <code class="returnvalue">{orange,yellow,green,​blue,purple}</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Notice that except for the two-argument form of <code class="function">enum_range</code>,
+ these functions disregard the specific value passed to them; they care
+ only about its declared data type. Either null or a specific value of
+ the type can be passed, with the same result. It is more common to
+ apply these functions to a table column or function argument than to
+ a hardwired type name as used in the examples.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.9. Date/Time Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.11. Geometric Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-event-triggers.html b/doc/src/sgml/html/functions-event-triggers.html
new file mode 100644
index 0000000..c5ea66e
--- /dev/null
+++ b/doc/src/sgml/html/functions-event-triggers.html
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.29. Event Trigger Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-trigger.html" title="9.28. Trigger Functions" /><link rel="next" href="functions-statistics.html" title="9.30. Statistics Information Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.29. Event Trigger Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-trigger.html" title="9.28. Trigger Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-statistics.html" title="9.30. Statistics Information Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-EVENT-TRIGGERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.29. Event Trigger Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-event-triggers.html#PG-EVENT-TRIGGER-DDL-COMMAND-END-FUNCTIONS">9.29.1. Capturing Changes at Command End</a></span></dt><dt><span class="sect2"><a href="functions-event-triggers.html#PG-EVENT-TRIGGER-SQL-DROP-FUNCTIONS">9.29.2. Processing Objects Dropped by a DDL Command</a></span></dt><dt><span class="sect2"><a href="functions-event-triggers.html#PG-EVENT-TRIGGER-TABLE-REWRITE-FUNCTIONS">9.29.3. Handling a Table Rewrite Event</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> provides these helper functions
+ to retrieve information from event triggers.
+ </p><p>
+ For more information about event triggers,
+ see <a class="xref" href="event-triggers.html" title="Chapter 40. Event Triggers">Chapter 40</a>.
+ </p><div class="sect2" id="PG-EVENT-TRIGGER-DDL-COMMAND-END-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">9.29.1. Capturing Changes at Command End</h3></div></div></div><a id="id-1.5.8.35.4.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">pg_event_trigger_ddl_commands</code> () → <code class="returnvalue">setof record</code>
+</pre><p>
+ <code class="function">pg_event_trigger_ddl_commands</code> returns a list of
+ <acronym class="acronym">DDL</acronym> commands executed by each user action,
+ when invoked in a function attached to a
+ <code class="literal">ddl_command_end</code> event trigger. If called in any other
+ context, an error is raised.
+ <code class="function">pg_event_trigger_ddl_commands</code> returns one row for each
+ base command executed; some commands that are a single SQL sentence
+ may return more than one row. This function returns the following
+ columns:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">classid</code></td><td><code class="type">oid</code></td><td>OID of catalog the object belongs in</td></tr><tr><td><code class="literal">objid</code></td><td><code class="type">oid</code></td><td>OID of the object itself</td></tr><tr><td><code class="literal">objsubid</code></td><td><code class="type">integer</code></td><td>Sub-object ID (e.g., attribute number for a column)</td></tr><tr><td><code class="literal">command_tag</code></td><td><code class="type">text</code></td><td>Command tag</td></tr><tr><td><code class="literal">object_type</code></td><td><code class="type">text</code></td><td>Type of the object</td></tr><tr><td><code class="literal">schema_name</code></td><td><code class="type">text</code></td><td>
+ Name of the schema the object belongs in, if any; otherwise <code class="literal">NULL</code>.
+ No quoting is applied.
+ </td></tr><tr><td><code class="literal">object_identity</code></td><td><code class="type">text</code></td><td>
+ Text rendering of the object identity, schema-qualified. Each
+ identifier included in the identity is quoted if necessary.
+ </td></tr><tr><td><code class="literal">in_extension</code></td><td><code class="type">boolean</code></td><td>True if the command is part of an extension script</td></tr><tr><td><code class="literal">command</code></td><td><code class="type">pg_ddl_command</code></td><td>
+ A complete representation of the command, in internal format.
+ This cannot be output directly, but it can be passed to other
+ functions to obtain different pieces of information about the
+ command.
+ </td></tr></tbody></table></div><p>
+ </p></div><div class="sect2" id="PG-EVENT-TRIGGER-SQL-DROP-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">9.29.2. Processing Objects Dropped by a DDL Command</h3></div></div></div><a id="id-1.5.8.35.5.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">pg_event_trigger_dropped_objects</code> () → <code class="returnvalue">setof record</code>
+</pre><p>
+ <code class="function">pg_event_trigger_dropped_objects</code> returns a list of all objects
+ dropped by the command in whose <code class="literal">sql_drop</code> event it is called.
+ If called in any other context, an error is raised.
+ This function returns the following columns:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">classid</code></td><td><code class="type">oid</code></td><td>OID of catalog the object belonged in</td></tr><tr><td><code class="literal">objid</code></td><td><code class="type">oid</code></td><td>OID of the object itself</td></tr><tr><td><code class="literal">objsubid</code></td><td><code class="type">integer</code></td><td>Sub-object ID (e.g., attribute number for a column)</td></tr><tr><td><code class="literal">original</code></td><td><code class="type">boolean</code></td><td>True if this was one of the root object(s) of the deletion</td></tr><tr><td><code class="literal">normal</code></td><td><code class="type">boolean</code></td><td>
+ True if there was a normal dependency relationship
+ in the dependency graph leading to this object
+ </td></tr><tr><td><code class="literal">is_temporary</code></td><td><code class="type">boolean</code></td><td>
+ True if this was a temporary object
+ </td></tr><tr><td><code class="literal">object_type</code></td><td><code class="type">text</code></td><td>Type of the object</td></tr><tr><td><code class="literal">schema_name</code></td><td><code class="type">text</code></td><td>
+ Name of the schema the object belonged in, if any; otherwise <code class="literal">NULL</code>.
+ No quoting is applied.
+ </td></tr><tr><td><code class="literal">object_name</code></td><td><code class="type">text</code></td><td>
+ Name of the object, if the combination of schema and name can be
+ used as a unique identifier for the object; otherwise <code class="literal">NULL</code>.
+ No quoting is applied, and name is never schema-qualified.
+ </td></tr><tr><td><code class="literal">object_identity</code></td><td><code class="type">text</code></td><td>
+ Text rendering of the object identity, schema-qualified. Each
+ identifier included in the identity is quoted if necessary.
+ </td></tr><tr><td><code class="literal">address_names</code></td><td><code class="type">text[]</code></td><td>
+ An array that, together with <code class="literal">object_type</code> and
+ <code class="literal">address_args</code>, can be used by
+ the <code class="function">pg_get_object_address</code> function to
+ recreate the object address in a remote server containing an
+ identically named object of the same kind.
+ </td></tr><tr><td><code class="literal">address_args</code></td><td><code class="type">text[]</code></td><td>
+ Complement for <code class="literal">address_names</code>
+ </td></tr></tbody></table></div><p>
+ </p><p>
+ The <code class="function">pg_event_trigger_dropped_objects</code> function can be used
+ in an event trigger like this:
+</p><pre class="programlisting">
+CREATE FUNCTION test_event_trigger_for_drops()
+ RETURNS event_trigger LANGUAGE plpgsql AS $$
+DECLARE
+ obj record;
+BEGIN
+ FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
+ LOOP
+ RAISE NOTICE '% dropped object: % %.% %',
+ tg_tag,
+ obj.object_type,
+ obj.schema_name,
+ obj.object_name,
+ obj.object_identity;
+ END LOOP;
+END;
+$$;
+CREATE EVENT TRIGGER test_event_trigger_for_drops
+ ON sql_drop
+ EXECUTE FUNCTION test_event_trigger_for_drops();
+</pre><p>
+ </p></div><div class="sect2" id="PG-EVENT-TRIGGER-TABLE-REWRITE-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">9.29.3. Handling a Table Rewrite Event</h3></div></div></div><p>
+ The functions shown in
+ <a class="xref" href="functions-event-triggers.html#FUNCTIONS-EVENT-TRIGGER-TABLE-REWRITE" title="Table 9.102. Table Rewrite Information Functions">Table 9.102</a>
+ provide information about a table for which a
+ <code class="literal">table_rewrite</code> event has just been called.
+ If called in any other context, an error is raised.
+ </p><div class="table" id="FUNCTIONS-EVENT-TRIGGER-TABLE-REWRITE"><p class="title"><strong>Table 9.102. Table Rewrite Information Functions</strong></p><div class="table-contents"><table class="table" summary="Table Rewrite Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.35.6.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_event_trigger_table_rewrite_oid</code> ()
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Returns the OID of the table about to be rewritten.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.35.6.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_event_trigger_table_rewrite_reason</code> ()
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns a code explaining the reason(s) for rewriting. The exact
+ meaning of the codes is release dependent.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ These functions can be used in an event trigger like this:
+</p><pre class="programlisting">
+CREATE FUNCTION test_event_trigger_table_rewrite_oid()
+ RETURNS event_trigger
+ LANGUAGE plpgsql AS
+$$
+BEGIN
+ RAISE NOTICE 'rewriting table % for reason %',
+ pg_event_trigger_table_rewrite_oid()::regclass,
+ pg_event_trigger_table_rewrite_reason();
+END;
+$$;
+
+CREATE EVENT TRIGGER test_table_rewrite_oid
+ ON table_rewrite
+ EXECUTE FUNCTION test_event_trigger_table_rewrite_oid();
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-trigger.html" title="9.28. Trigger Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-statistics.html" title="9.30. Statistics Information Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.28. Trigger Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.30. Statistics Information Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-formatting.html b/doc/src/sgml/html/functions-formatting.html
new file mode 100644
index 0000000..b447553
--- /dev/null
+++ b/doc/src/sgml/html/functions-formatting.html
@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.8. Data Type Formatting Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-matching.html" title="9.7. Pattern Matching" /><link rel="next" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.8. Data Type Formatting Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-matching.html" title="9.7. Pattern Matching">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-FORMATTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.8. Data Type Formatting Functions</h2></div></div></div><a id="id-1.5.8.14.2" class="indexterm"></a><p>
+ The <span class="productname">PostgreSQL</span> formatting functions
+ provide a powerful set of tools for converting various data types
+ (date/time, integer, floating point, numeric) to formatted strings
+ and for converting from formatted strings to specific data types.
+ <a class="xref" href="functions-formatting.html#FUNCTIONS-FORMATTING-TABLE" title="Table 9.26. Formatting Functions">Table 9.26</a> lists them.
+ These functions all follow a common calling convention: the first
+ argument is the value to be formatted and the second argument is a
+ template that defines the output or input format.
+ </p><div class="table" id="FUNCTIONS-FORMATTING-TABLE"><p class="title"><strong>Table 9.26. Formatting Functions</strong></p><div class="table-contents"><table class="table" summary="Formatting Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.14.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">to_char</code> ( <code class="type">timestamp</code>, <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">to_char</code> ( <code class="type">timestamp with time zone</code>, <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts time stamp to string according to the given format.
+ </p>
+ <p>
+ <code class="literal">to_char(timestamp '2002-04-20 17:31:12.66', 'HH12:MI:SS')</code>
+ → <code class="returnvalue">05:31:12</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">to_char</code> ( <code class="type">interval</code>, <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts interval to string according to the given format.
+ </p>
+ <p>
+ <code class="literal">to_char(interval '15h 2m 12s', 'HH24:MI:SS')</code>
+ → <code class="returnvalue">15:02:12</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">to_char</code> ( <em class="replaceable"><code>numeric_type</code></em>, <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts number to string according to the given format; available
+ for <code class="type">integer</code>, <code class="type">bigint</code>, <code class="type">numeric</code>,
+ <code class="type">real</code>, <code class="type">double precision</code>.
+ </p>
+ <p>
+ <code class="literal">to_char(125, '999')</code>
+ → <code class="returnvalue">125</code>
+ </p>
+ <p>
+ <code class="literal">to_char(125.8::real, '999D9')</code>
+ → <code class="returnvalue">125.8</code>
+ </p>
+ <p>
+ <code class="literal">to_char(-125.8, '999D99S')</code>
+ → <code class="returnvalue">125.80-</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.14.4.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">to_date</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">date</code>
+ </p>
+ <p>
+ Converts string to date according to the given format.
+ </p>
+ <p>
+ <code class="literal">to_date('05 Dec 2000', 'DD Mon YYYY')</code>
+ → <code class="returnvalue">2000-12-05</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.14.4.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">to_number</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Converts string to numeric according to the given format.
+ </p>
+ <p>
+ <code class="literal">to_number('12,454.8-', '99G999D9S')</code>
+ → <code class="returnvalue">-12454.8</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.14.4.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">to_timestamp</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Converts string to time stamp according to the given format.
+ (See also <code class="function">to_timestamp(double precision)</code> in
+ <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-TABLE" title="Table 9.33. Date/Time Functions">Table 9.33</a>.)
+ </p>
+ <p>
+ <code class="literal">to_timestamp('05 Dec 2000', 'DD Mon YYYY')</code>
+ → <code class="returnvalue">2000-12-05 00:00:00-05</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="tip"><h3 class="title">Tip</h3><p>
+ <code class="function">to_timestamp</code> and <code class="function">to_date</code>
+ exist to handle input formats that cannot be converted by
+ simple casting. For most standard date/time formats, simply casting the
+ source string to the required data type works, and is much easier.
+ Similarly, <code class="function">to_number</code> is unnecessary for standard numeric
+ representations.
+ </p></div><p>
+ In a <code class="function">to_char</code> output template string, there are certain
+ patterns that are recognized and replaced with appropriately-formatted
+ data based on the given value. Any text that is not a template pattern is
+ simply copied verbatim. Similarly, in an input template string (for the
+ other functions), template patterns identify the values to be supplied by
+ the input data string. If there are characters in the template string
+ that are not template patterns, the corresponding characters in the input
+ data string are simply skipped over (whether or not they are equal to the
+ template string characters).
+ </p><p>
+ <a class="xref" href="functions-formatting.html#FUNCTIONS-FORMATTING-DATETIME-TABLE" title="Table 9.27. Template Patterns for Date/Time Formatting">Table 9.27</a> shows the
+ template patterns available for formatting date and time values.
+ </p><div class="table" id="FUNCTIONS-FORMATTING-DATETIME-TABLE"><p class="title"><strong>Table 9.27. Template Patterns for Date/Time Formatting</strong></p><div class="table-contents"><table class="table" summary="Template Patterns for Date/Time Formatting" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Pattern</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">HH</code></td><td>hour of day (01–12)</td></tr><tr><td><code class="literal">HH12</code></td><td>hour of day (01–12)</td></tr><tr><td><code class="literal">HH24</code></td><td>hour of day (00–23)</td></tr><tr><td><code class="literal">MI</code></td><td>minute (00–59)</td></tr><tr><td><code class="literal">SS</code></td><td>second (00–59)</td></tr><tr><td><code class="literal">MS</code></td><td>millisecond (000–999)</td></tr><tr><td><code class="literal">US</code></td><td>microsecond (000000–999999)</td></tr><tr><td><code class="literal">FF1</code></td><td>tenth of second (0–9)</td></tr><tr><td><code class="literal">FF2</code></td><td>hundredth of second (00–99)</td></tr><tr><td><code class="literal">FF3</code></td><td>millisecond (000–999)</td></tr><tr><td><code class="literal">FF4</code></td><td>tenth of a millisecond (0000–9999)</td></tr><tr><td><code class="literal">FF5</code></td><td>hundredth of a millisecond (00000–99999)</td></tr><tr><td><code class="literal">FF6</code></td><td>microsecond (000000–999999)</td></tr><tr><td><code class="literal">SSSS</code>, <code class="literal">SSSSS</code></td><td>seconds past midnight (0–86399)</td></tr><tr><td><code class="literal">AM</code>, <code class="literal">am</code>,
+ <code class="literal">PM</code> or <code class="literal">pm</code></td><td>meridiem indicator (without periods)</td></tr><tr><td><code class="literal">A.M.</code>, <code class="literal">a.m.</code>,
+ <code class="literal">P.M.</code> or <code class="literal">p.m.</code></td><td>meridiem indicator (with periods)</td></tr><tr><td><code class="literal">Y,YYY</code></td><td>year (4 or more digits) with comma</td></tr><tr><td><code class="literal">YYYY</code></td><td>year (4 or more digits)</td></tr><tr><td><code class="literal">YYY</code></td><td>last 3 digits of year</td></tr><tr><td><code class="literal">YY</code></td><td>last 2 digits of year</td></tr><tr><td><code class="literal">Y</code></td><td>last digit of year</td></tr><tr><td><code class="literal">IYYY</code></td><td>ISO 8601 week-numbering year (4 or more digits)</td></tr><tr><td><code class="literal">IYY</code></td><td>last 3 digits of ISO 8601 week-numbering year</td></tr><tr><td><code class="literal">IY</code></td><td>last 2 digits of ISO 8601 week-numbering year</td></tr><tr><td><code class="literal">I</code></td><td>last digit of ISO 8601 week-numbering year</td></tr><tr><td><code class="literal">BC</code>, <code class="literal">bc</code>,
+ <code class="literal">AD</code> or <code class="literal">ad</code></td><td>era indicator (without periods)</td></tr><tr><td><code class="literal">B.C.</code>, <code class="literal">b.c.</code>,
+ <code class="literal">A.D.</code> or <code class="literal">a.d.</code></td><td>era indicator (with periods)</td></tr><tr><td><code class="literal">MONTH</code></td><td>full upper case month name (blank-padded to 9 chars)</td></tr><tr><td><code class="literal">Month</code></td><td>full capitalized month name (blank-padded to 9 chars)</td></tr><tr><td><code class="literal">month</code></td><td>full lower case month name (blank-padded to 9 chars)</td></tr><tr><td><code class="literal">MON</code></td><td>abbreviated upper case month name (3 chars in English, localized lengths vary)</td></tr><tr><td><code class="literal">Mon</code></td><td>abbreviated capitalized month name (3 chars in English, localized lengths vary)</td></tr><tr><td><code class="literal">mon</code></td><td>abbreviated lower case month name (3 chars in English, localized lengths vary)</td></tr><tr><td><code class="literal">MM</code></td><td>month number (01–12)</td></tr><tr><td><code class="literal">DAY</code></td><td>full upper case day name (blank-padded to 9 chars)</td></tr><tr><td><code class="literal">Day</code></td><td>full capitalized day name (blank-padded to 9 chars)</td></tr><tr><td><code class="literal">day</code></td><td>full lower case day name (blank-padded to 9 chars)</td></tr><tr><td><code class="literal">DY</code></td><td>abbreviated upper case day name (3 chars in English, localized lengths vary)</td></tr><tr><td><code class="literal">Dy</code></td><td>abbreviated capitalized day name (3 chars in English, localized lengths vary)</td></tr><tr><td><code class="literal">dy</code></td><td>abbreviated lower case day name (3 chars in English, localized lengths vary)</td></tr><tr><td><code class="literal">DDD</code></td><td>day of year (001–366)</td></tr><tr><td><code class="literal">IDDD</code></td><td>day of ISO 8601 week-numbering year (001–371; day 1 of the year is Monday of the first ISO week)</td></tr><tr><td><code class="literal">DD</code></td><td>day of month (01–31)</td></tr><tr><td><code class="literal">D</code></td><td>day of the week, Sunday (<code class="literal">1</code>) to Saturday (<code class="literal">7</code>)</td></tr><tr><td><code class="literal">ID</code></td><td>ISO 8601 day of the week, Monday (<code class="literal">1</code>) to Sunday (<code class="literal">7</code>)</td></tr><tr><td><code class="literal">W</code></td><td>week of month (1–5) (the first week starts on the first day of the month)</td></tr><tr><td><code class="literal">WW</code></td><td>week number of year (1–53) (the first week starts on the first day of the year)</td></tr><tr><td><code class="literal">IW</code></td><td>week number of ISO 8601 week-numbering year (01–53; the first Thursday of the year is in week 1)</td></tr><tr><td><code class="literal">CC</code></td><td>century (2 digits) (the twenty-first century starts on 2001-01-01)</td></tr><tr><td><code class="literal">J</code></td><td>Julian Date (integer days since November 24, 4714 BC at local
+ midnight; see <a class="xref" href="datetime-julian-dates.html" title="B.7. Julian Dates">Section B.7</a>)</td></tr><tr><td><code class="literal">Q</code></td><td>quarter</td></tr><tr><td><code class="literal">RM</code></td><td>month in upper case Roman numerals (I–XII; I=January)</td></tr><tr><td><code class="literal">rm</code></td><td>month in lower case Roman numerals (i–xii; i=January)</td></tr><tr><td><code class="literal">TZ</code></td><td>upper case time-zone abbreviation
+ (only supported in <code class="function">to_char</code>)</td></tr><tr><td><code class="literal">tz</code></td><td>lower case time-zone abbreviation
+ (only supported in <code class="function">to_char</code>)</td></tr><tr><td><code class="literal">TZH</code></td><td>time-zone hours</td></tr><tr><td><code class="literal">TZM</code></td><td>time-zone minutes</td></tr><tr><td><code class="literal">OF</code></td><td>time-zone offset from UTC
+ (only supported in <code class="function">to_char</code>)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Modifiers can be applied to any template pattern to alter its
+ behavior. For example, <code class="literal">FMMonth</code>
+ is the <code class="literal">Month</code> pattern with the
+ <code class="literal">FM</code> modifier.
+ <a class="xref" href="functions-formatting.html#FUNCTIONS-FORMATTING-DATETIMEMOD-TABLE" title="Table 9.28. Template Pattern Modifiers for Date/Time Formatting">Table 9.28</a> shows the
+ modifier patterns for date/time formatting.
+ </p><div class="table" id="FUNCTIONS-FORMATTING-DATETIMEMOD-TABLE"><p class="title"><strong>Table 9.28. Template Pattern Modifiers for Date/Time Formatting</strong></p><div class="table-contents"><table class="table" summary="Template Pattern Modifiers for Date/Time Formatting" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Modifier</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><code class="literal">FM</code> prefix</td><td>fill mode (suppress leading zeroes and padding blanks)</td><td><code class="literal">FMMonth</code></td></tr><tr><td><code class="literal">TH</code> suffix</td><td>upper case ordinal number suffix</td><td><code class="literal">DDTH</code>, e.g., <code class="literal">12TH</code></td></tr><tr><td><code class="literal">th</code> suffix</td><td>lower case ordinal number suffix</td><td><code class="literal">DDth</code>, e.g., <code class="literal">12th</code></td></tr><tr><td><code class="literal">FX</code> prefix</td><td>fixed format global option (see usage notes)</td><td><code class="literal">FX Month DD Day</code></td></tr><tr><td><code class="literal">TM</code> prefix</td><td>translation mode (use localized day and month names based on
+ <a class="xref" href="runtime-config-client.html#GUC-LC-TIME">lc_time</a>)</td><td><code class="literal">TMMonth</code></td></tr><tr><td><code class="literal">SP</code> suffix</td><td>spell mode (not implemented)</td><td><code class="literal">DDSP</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Usage notes for date/time formatting:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">FM</code> suppresses leading zeroes and trailing blanks
+ that would otherwise be added to make the output of a pattern be
+ fixed-width. In <span class="productname">PostgreSQL</span>,
+ <code class="literal">FM</code> modifies only the next specification, while in
+ Oracle <code class="literal">FM</code> affects all subsequent
+ specifications, and repeated <code class="literal">FM</code> modifiers
+ toggle fill mode on and off.
+ </p></li><li class="listitem"><p>
+ <code class="literal">TM</code> suppresses trailing blanks whether or
+ not <code class="literal">FM</code> is specified.
+ </p></li><li class="listitem"><p>
+ <code class="function">to_timestamp</code> and <code class="function">to_date</code>
+ ignore letter case in the input; so for
+ example <code class="literal">MON</code>, <code class="literal">Mon</code>,
+ and <code class="literal">mon</code> all accept the same strings. When using
+ the <code class="literal">TM</code> modifier, case-folding is done according to
+ the rules of the function's input collation (see
+ <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>).
+ </p></li><li class="listitem"><p>
+ <code class="function">to_timestamp</code> and <code class="function">to_date</code>
+ skip multiple blank spaces at the beginning of the input string and
+ around date and time values unless the <code class="literal">FX</code> option is used. For example,
+ <code class="literal">to_timestamp(' 2000    JUN', 'YYYY MON')</code> and
+ <code class="literal">to_timestamp('2000 - JUN', 'YYYY-MON')</code> work, but
+ <code class="literal">to_timestamp('2000    JUN', 'FXYYYY MON')</code> returns an error
+ because <code class="function">to_timestamp</code> expects only a single space.
+ <code class="literal">FX</code> must be specified as the first item in
+ the template.
+ </p></li><li class="listitem"><p>
+ A separator (a space or non-letter/non-digit character) in the template string of
+ <code class="function">to_timestamp</code> and <code class="function">to_date</code>
+ matches any single separator in the input string or is skipped,
+ unless the <code class="literal">FX</code> option is used.
+ For example, <code class="literal">to_timestamp('2000JUN', 'YYYY///MON')</code> and
+ <code class="literal">to_timestamp('2000/JUN', 'YYYY MON')</code> work, but
+ <code class="literal">to_timestamp('2000//JUN', 'YYYY/MON')</code>
+ returns an error because the number of separators in the input string
+ exceeds the number of separators in the template.
+ </p><p>
+ If <code class="literal">FX</code> is specified, a separator in the template string
+ matches exactly one character in the input string. But note that the
+ input string character is not required to be the same as the separator from the template string.
+ For example, <code class="literal">to_timestamp('2000/JUN', 'FXYYYY MON')</code>
+ works, but <code class="literal">to_timestamp('2000/JUN', 'FXYYYY  MON')</code>
+ returns an error because the second space in the template string consumes
+ the letter <code class="literal">J</code> from the input string.
+ </p></li><li class="listitem"><p>
+ A <code class="literal">TZH</code> template pattern can match a signed number.
+ Without the <code class="literal">FX</code> option, minus signs may be ambiguous,
+ and could be interpreted as a separator.
+ This ambiguity is resolved as follows: If the number of separators before
+ <code class="literal">TZH</code> in the template string is less than the number of
+ separators before the minus sign in the input string, the minus sign
+ is interpreted as part of <code class="literal">TZH</code>.
+ Otherwise, the minus sign is considered to be a separator between values.
+ For example, <code class="literal">to_timestamp('2000 -10', 'YYYY TZH')</code> matches
+ <code class="literal">-10</code> to <code class="literal">TZH</code>, but
+ <code class="literal">to_timestamp('2000 -10', 'YYYY  TZH')</code>
+ matches <code class="literal">10</code> to <code class="literal">TZH</code>.
+ </p></li><li class="listitem"><p>
+ Ordinary text is allowed in <code class="function">to_char</code>
+ templates and will be output literally. You can put a substring
+ in double quotes to force it to be interpreted as literal text
+ even if it contains template patterns. For example, in
+ <code class="literal">'"Hello Year "YYYY'</code>, the <code class="literal">YYYY</code>
+ will be replaced by the year data, but the single <code class="literal">Y</code> in <code class="literal">Year</code>
+ will not be.
+ In <code class="function">to_date</code>, <code class="function">to_number</code>,
+ and <code class="function">to_timestamp</code>, literal text and double-quoted
+ strings result in skipping the number of characters contained in the
+ string; for example <code class="literal">"XX"</code> skips two input characters
+ (whether or not they are <code class="literal">XX</code>).
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Prior to <span class="productname">PostgreSQL</span> 12, it was possible to
+ skip arbitrary text in the input string using non-letter or non-digit
+ characters. For example,
+ <code class="literal">to_timestamp('2000y6m1d', 'yyyy-MM-DD')</code> used to
+ work. Now you can only use letter characters for this purpose. For example,
+ <code class="literal">to_timestamp('2000y6m1d', 'yyyytMMtDDt')</code> and
+ <code class="literal">to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"')</code>
+ skip <code class="literal">y</code>, <code class="literal">m</code>, and
+ <code class="literal">d</code>.
+ </p></div></li><li class="listitem"><p>
+ If you want to have a double quote in the output you must
+ precede it with a backslash, for example <code class="literal">'\"YYYY
+ Month\"'</code>.
+ Backslashes are not otherwise special outside of double-quoted
+ strings. Within a double-quoted string, a backslash causes the
+ next character to be taken literally, whatever it is (but this
+ has no special effect unless the next character is a double quote
+ or another backslash).
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code> and <code class="function">to_date</code>,
+ if the year format specification is less than four digits, e.g.,
+ <code class="literal">YYY</code>, and the supplied year is less than four digits,
+ the year will be adjusted to be nearest to the year 2020, e.g.,
+ <code class="literal">95</code> becomes 1995.
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code> and <code class="function">to_date</code>,
+ negative years are treated as signifying BC. If you write both a
+ negative year and an explicit <code class="literal">BC</code> field, you get AD
+ again. An input of year zero is treated as 1 BC.
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code> and <code class="function">to_date</code>,
+ the <code class="literal">YYYY</code> conversion has a restriction when
+ processing years with more than 4 digits. You must
+ use some non-digit character or template after <code class="literal">YYYY</code>,
+ otherwise the year is always interpreted as 4 digits. For example
+ (with the year 20000):
+ <code class="literal">to_date('200001131', 'YYYYMMDD')</code> will be
+ interpreted as a 4-digit year; instead use a non-digit
+ separator after the year, like
+ <code class="literal">to_date('20000-1131', 'YYYY-MMDD')</code> or
+ <code class="literal">to_date('20000Nov31', 'YYYYMonDD')</code>.
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code> and <code class="function">to_date</code>,
+ the <code class="literal">CC</code> (century) field is accepted but ignored
+ if there is a <code class="literal">YYY</code>, <code class="literal">YYYY</code> or
+ <code class="literal">Y,YYY</code> field. If <code class="literal">CC</code> is used with
+ <code class="literal">YY</code> or <code class="literal">Y</code> then the result is
+ computed as that year in the specified century. If the century is
+ specified but the year is not, the first year of the century
+ is assumed.
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code> and <code class="function">to_date</code>,
+ weekday names or numbers (<code class="literal">DAY</code>, <code class="literal">D</code>,
+ and related field types) are accepted but are ignored for purposes of
+ computing the result. The same is true for quarter
+ (<code class="literal">Q</code>) fields.
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code> and <code class="function">to_date</code>,
+ an ISO 8601 week-numbering date (as distinct from a Gregorian date)
+ can be specified in one of two ways:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ Year, week number, and weekday: for
+ example <code class="literal">to_date('2006-42-4', 'IYYY-IW-ID')</code>
+ returns the date <code class="literal">2006-10-19</code>.
+ If you omit the weekday it is assumed to be 1 (Monday).
+ </p></li><li class="listitem"><p>
+ Year and day of year: for example <code class="literal">to_date('2006-291',
+ 'IYYY-IDDD')</code> also returns <code class="literal">2006-10-19</code>.
+ </p></li></ul></div><p>
+ </p><p>
+ Attempting to enter a date using a mixture of ISO 8601 week-numbering
+ fields and Gregorian date fields is nonsensical, and will cause an
+ error. In the context of an ISO 8601 week-numbering year, the
+ concept of a <span class="quote">“<span class="quote">month</span>”</span> or <span class="quote">“<span class="quote">day of month</span>”</span> has no
+ meaning. In the context of a Gregorian year, the ISO week has no
+ meaning.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ While <code class="function">to_date</code> will reject a mixture of
+ Gregorian and ISO week-numbering date
+ fields, <code class="function">to_char</code> will not, since output format
+ specifications like <code class="literal">YYYY-MM-DD (IYYY-IDDD)</code> can be
+ useful. But avoid writing something like <code class="literal">IYYY-MM-DD</code>;
+ that would yield surprising results near the start of the year.
+ (See <a class="xref" href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT" title="9.9.1. EXTRACT, date_part">Section 9.9.1</a> for more
+ information.)
+ </p></div></li><li class="listitem"><p>
+ In <code class="function">to_timestamp</code>, millisecond
+ (<code class="literal">MS</code>) or microsecond (<code class="literal">US</code>)
+ fields are used as the
+ seconds digits after the decimal point. For example
+ <code class="literal">to_timestamp('12.3', 'SS.MS')</code> is not 3 milliseconds,
+ but 300, because the conversion treats it as 12 + 0.3 seconds.
+ So, for the format <code class="literal">SS.MS</code>, the input values
+ <code class="literal">12.3</code>, <code class="literal">12.30</code>,
+ and <code class="literal">12.300</code> specify the
+ same number of milliseconds. To get three milliseconds, one must write
+ <code class="literal">12.003</code>, which the conversion treats as
+ 12 + 0.003 = 12.003 seconds.
+ </p><p>
+ Here is a more
+ complex example:
+ <code class="literal">to_timestamp('15:12:02.020.001230', 'HH24:MI:SS.MS.US')</code>
+ is 15 hours, 12 minutes, and 2 seconds + 20 milliseconds +
+ 1230 microseconds = 2.021230 seconds.
+ </p></li><li class="listitem"><p>
+ <code class="function">to_char(..., 'ID')</code>'s day of the week numbering
+ matches the <code class="function">extract(isodow from ...)</code> function, but
+ <code class="function">to_char(..., 'D')</code>'s does not match
+ <code class="function">extract(dow from ...)</code>'s day numbering.
+ </p></li><li class="listitem"><p>
+ <code class="function">to_char(interval)</code> formats <code class="literal">HH</code> and
+ <code class="literal">HH12</code> as shown on a 12-hour clock, for example zero hours
+ and 36 hours both output as <code class="literal">12</code>, while <code class="literal">HH24</code>
+ outputs the full hour value, which can exceed 23 in
+ an <code class="type">interval</code> value.
+ </p></li></ul></div><p>
+ </p><p>
+ <a class="xref" href="functions-formatting.html#FUNCTIONS-FORMATTING-NUMERIC-TABLE" title="Table 9.29. Template Patterns for Numeric Formatting">Table 9.29</a> shows the
+ template patterns available for formatting numeric values.
+ </p><div class="table" id="FUNCTIONS-FORMATTING-NUMERIC-TABLE"><p class="title"><strong>Table 9.29. Template Patterns for Numeric Formatting</strong></p><div class="table-contents"><table class="table" summary="Template Patterns for Numeric Formatting" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Pattern</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">9</code></td><td>digit position (can be dropped if insignificant)</td></tr><tr><td><code class="literal">0</code></td><td>digit position (will not be dropped, even if insignificant)</td></tr><tr><td><code class="literal">.</code> (period)</td><td>decimal point</td></tr><tr><td><code class="literal">,</code> (comma)</td><td>group (thousands) separator</td></tr><tr><td><code class="literal">PR</code></td><td>negative value in angle brackets</td></tr><tr><td><code class="literal">S</code></td><td>sign anchored to number (uses locale)</td></tr><tr><td><code class="literal">L</code></td><td>currency symbol (uses locale)</td></tr><tr><td><code class="literal">D</code></td><td>decimal point (uses locale)</td></tr><tr><td><code class="literal">G</code></td><td>group separator (uses locale)</td></tr><tr><td><code class="literal">MI</code></td><td>minus sign in specified position (if number &lt; 0)</td></tr><tr><td><code class="literal">PL</code></td><td>plus sign in specified position (if number &gt; 0)</td></tr><tr><td><code class="literal">SG</code></td><td>plus/minus sign in specified position</td></tr><tr><td><code class="literal">RN</code></td><td>Roman numeral (input between 1 and 3999)</td></tr><tr><td><code class="literal">TH</code> or <code class="literal">th</code></td><td>ordinal number suffix</td></tr><tr><td><code class="literal">V</code></td><td>shift specified number of digits (see notes)</td></tr><tr><td><code class="literal">EEEE</code></td><td>exponent for scientific notation</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Usage notes for numeric formatting:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">0</code> specifies a digit position that will always be printed,
+ even if it contains a leading/trailing zero. <code class="literal">9</code> also
+ specifies a digit position, but if it is a leading zero then it will
+ be replaced by a space, while if it is a trailing zero and fill mode
+ is specified then it will be deleted. (For <code class="function">to_number()</code>,
+ these two pattern characters are equivalent.)
+ </p></li><li class="listitem"><p>
+ The pattern characters <code class="literal">S</code>, <code class="literal">L</code>, <code class="literal">D</code>,
+ and <code class="literal">G</code> represent the sign, currency symbol, decimal point,
+ and thousands separator characters defined by the current locale
+ (see <a class="xref" href="runtime-config-client.html#GUC-LC-MONETARY">lc_monetary</a>
+ and <a class="xref" href="runtime-config-client.html#GUC-LC-NUMERIC">lc_numeric</a>). The pattern characters period
+ and comma represent those exact characters, with the meanings of
+ decimal point and thousands separator, regardless of locale.
+ </p></li><li class="listitem"><p>
+ If no explicit provision is made for a sign
+ in <code class="function">to_char()</code>'s pattern, one column will be reserved for
+ the sign, and it will be anchored to (appear just left of) the
+ number. If <code class="literal">S</code> appears just left of some <code class="literal">9</code>'s,
+ it will likewise be anchored to the number.
+ </p></li><li class="listitem"><p>
+ A sign formatted using <code class="literal">SG</code>, <code class="literal">PL</code>, or
+ <code class="literal">MI</code> is not anchored to
+ the number; for example,
+ <code class="literal">to_char(-12, 'MI9999')</code> produces <code class="literal">'-  12'</code>
+ but <code class="literal">to_char(-12, 'S9999')</code> produces <code class="literal">'  -12'</code>.
+ (The Oracle implementation does not allow the use of
+ <code class="literal">MI</code> before <code class="literal">9</code>, but rather
+ requires that <code class="literal">9</code> precede
+ <code class="literal">MI</code>.)
+ </p></li><li class="listitem"><p>
+ <code class="literal">TH</code> does not convert values less than zero
+ and does not convert fractional numbers.
+ </p></li><li class="listitem"><p>
+ <code class="literal">PL</code>, <code class="literal">SG</code>, and
+ <code class="literal">TH</code> are <span class="productname">PostgreSQL</span>
+ extensions.
+ </p></li><li class="listitem"><p>
+ In <code class="function">to_number</code>, if non-data template patterns such
+ as <code class="literal">L</code> or <code class="literal">TH</code> are used, the
+ corresponding number of input characters are skipped, whether or not
+ they match the template pattern, unless they are data characters
+ (that is, digits, sign, decimal point, or comma). For
+ example, <code class="literal">TH</code> would skip two non-data characters.
+ </p></li><li class="listitem"><p>
+ <code class="literal">V</code> with <code class="function">to_char</code>
+ multiplies the input values by
+ <code class="literal">10^<em class="replaceable"><code>n</code></em></code>, where
+ <em class="replaceable"><code>n</code></em> is the number of digits following
+ <code class="literal">V</code>. <code class="literal">V</code> with
+ <code class="function">to_number</code> divides in a similar manner.
+ <code class="function">to_char</code> and <code class="function">to_number</code>
+ do not support the use of
+ <code class="literal">V</code> combined with a decimal point
+ (e.g., <code class="literal">99.9V99</code> is not allowed).
+ </p></li><li class="listitem"><p>
+ <code class="literal">EEEE</code> (scientific notation) cannot be used in
+ combination with any of the other formatting patterns or
+ modifiers other than digit and decimal point patterns, and must be at the end of the format string
+ (e.g., <code class="literal">9.99EEEE</code> is a valid pattern).
+ </p></li></ul></div><p>
+ </p><p>
+ Certain modifiers can be applied to any template pattern to alter its
+ behavior. For example, <code class="literal">FM99.99</code>
+ is the <code class="literal">99.99</code> pattern with the
+ <code class="literal">FM</code> modifier.
+ <a class="xref" href="functions-formatting.html#FUNCTIONS-FORMATTING-NUMERICMOD-TABLE" title="Table 9.30. Template Pattern Modifiers for Numeric Formatting">Table 9.30</a> shows the
+ modifier patterns for numeric formatting.
+ </p><div class="table" id="FUNCTIONS-FORMATTING-NUMERICMOD-TABLE"><p class="title"><strong>Table 9.30. Template Pattern Modifiers for Numeric Formatting</strong></p><div class="table-contents"><table class="table" summary="Template Pattern Modifiers for Numeric Formatting" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Modifier</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><code class="literal">FM</code> prefix</td><td>fill mode (suppress trailing zeroes and padding blanks)</td><td><code class="literal">FM99.99</code></td></tr><tr><td><code class="literal">TH</code> suffix</td><td>upper case ordinal number suffix</td><td><code class="literal">999TH</code></td></tr><tr><td><code class="literal">th</code> suffix</td><td>lower case ordinal number suffix</td><td><code class="literal">999th</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-formatting.html#FUNCTIONS-FORMATTING-EXAMPLES-TABLE" title="Table 9.31. to_char Examples">Table 9.31</a> shows some
+ examples of the use of the <code class="function">to_char</code> function.
+ </p><div class="table" id="FUNCTIONS-FORMATTING-EXAMPLES-TABLE"><p class="title"><strong>Table 9.31. <code class="function">to_char</code> Examples</strong></p><div class="table-contents"><table class="table" summary="to_char Examples" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Expression</th><th>Result</th></tr></thead><tbody><tr><td><code class="literal">to_char(current_timestamp, 'Day, DD  HH12:MI:SS')</code></td><td><code class="literal">'Tuesday  , 06  05:39:18'</code></td></tr><tr><td><code class="literal">to_char(current_timestamp, 'FMDay, FMDD  HH12:MI:SS')</code></td><td><code class="literal">'Tuesday, 6  05:39:18'</code></td></tr><tr><td><code class="literal">to_char(-0.1, '99.99')</code></td><td><code class="literal">'  -.10'</code></td></tr><tr><td><code class="literal">to_char(-0.1, 'FM9.99')</code></td><td><code class="literal">'-.1'</code></td></tr><tr><td><code class="literal">to_char(-0.1, 'FM90.99')</code></td><td><code class="literal">'-0.1'</code></td></tr><tr><td><code class="literal">to_char(0.1, '0.9')</code></td><td><code class="literal">' 0.1'</code></td></tr><tr><td><code class="literal">to_char(12, '9990999.9')</code></td><td><code class="literal">'    0012.0'</code></td></tr><tr><td><code class="literal">to_char(12, 'FM9990999.9')</code></td><td><code class="literal">'0012.'</code></td></tr><tr><td><code class="literal">to_char(485, '999')</code></td><td><code class="literal">' 485'</code></td></tr><tr><td><code class="literal">to_char(-485, '999')</code></td><td><code class="literal">'-485'</code></td></tr><tr><td><code class="literal">to_char(485, '9 9 9')</code></td><td><code class="literal">' 4 8 5'</code></td></tr><tr><td><code class="literal">to_char(1485, '9,999')</code></td><td><code class="literal">' 1,485'</code></td></tr><tr><td><code class="literal">to_char(1485, '9G999')</code></td><td><code class="literal">' 1 485'</code></td></tr><tr><td><code class="literal">to_char(148.5, '999.999')</code></td><td><code class="literal">' 148.500'</code></td></tr><tr><td><code class="literal">to_char(148.5, 'FM999.999')</code></td><td><code class="literal">'148.5'</code></td></tr><tr><td><code class="literal">to_char(148.5, 'FM999.990')</code></td><td><code class="literal">'148.500'</code></td></tr><tr><td><code class="literal">to_char(148.5, '999D999')</code></td><td><code class="literal">' 148,500'</code></td></tr><tr><td><code class="literal">to_char(3148.5, '9G999D999')</code></td><td><code class="literal">' 3 148,500'</code></td></tr><tr><td><code class="literal">to_char(-485, '999S')</code></td><td><code class="literal">'485-'</code></td></tr><tr><td><code class="literal">to_char(-485, '999MI')</code></td><td><code class="literal">'485-'</code></td></tr><tr><td><code class="literal">to_char(485, '999MI')</code></td><td><code class="literal">'485 '</code></td></tr><tr><td><code class="literal">to_char(485, 'FM999MI')</code></td><td><code class="literal">'485'</code></td></tr><tr><td><code class="literal">to_char(485, 'PL999')</code></td><td><code class="literal">'+485'</code></td></tr><tr><td><code class="literal">to_char(485, 'SG999')</code></td><td><code class="literal">'+485'</code></td></tr><tr><td><code class="literal">to_char(-485, 'SG999')</code></td><td><code class="literal">'-485'</code></td></tr><tr><td><code class="literal">to_char(-485, '9SG99')</code></td><td><code class="literal">'4-85'</code></td></tr><tr><td><code class="literal">to_char(-485, '999PR')</code></td><td><code class="literal">'&lt;485&gt;'</code></td></tr><tr><td><code class="literal">to_char(485, 'L999')</code></td><td><code class="literal">'DM 485'</code></td></tr><tr><td><code class="literal">to_char(485, 'RN')</code></td><td><code class="literal">'        CDLXXXV'</code></td></tr><tr><td><code class="literal">to_char(485, 'FMRN')</code></td><td><code class="literal">'CDLXXXV'</code></td></tr><tr><td><code class="literal">to_char(5.2, 'FMRN')</code></td><td><code class="literal">'V'</code></td></tr><tr><td><code class="literal">to_char(482, '999th')</code></td><td><code class="literal">' 482nd'</code></td></tr><tr><td><code class="literal">to_char(485, '"Good number:"999')</code></td><td><code class="literal">'Good number: 485'</code></td></tr><tr><td><code class="literal">to_char(485.8, '"Pre:"999" Post:" .999')</code></td><td><code class="literal">'Pre: 485 Post: .800'</code></td></tr><tr><td><code class="literal">to_char(12, '99V999')</code></td><td><code class="literal">' 12000'</code></td></tr><tr><td><code class="literal">to_char(12.4, '99V999')</code></td><td><code class="literal">' 12400'</code></td></tr><tr><td><code class="literal">to_char(12.45, '99V9')</code></td><td><code class="literal">' 125'</code></td></tr><tr><td><code class="literal">to_char(0.0004859, '9.99EEEE')</code></td><td><code class="literal">' 4.86e-04'</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-matching.html" title="9.7. Pattern Matching">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-datetime.html" title="9.9. Date/Time Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.7. Pattern Matching </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.9. Date/Time Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-geometry.html b/doc/src/sgml/html/functions-geometry.html
new file mode 100644
index 0000000..45f6b81
--- /dev/null
+++ b/doc/src/sgml/html/functions-geometry.html
@@ -0,0 +1,886 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.11. Geometric Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-enum.html" title="9.10. Enum Support Functions" /><link rel="next" href="functions-net.html" title="9.12. Network Address Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.11. Geometric Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-enum.html" title="9.10. Enum Support Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-net.html" title="9.12. Network Address Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-GEOMETRY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.11. Geometric Functions and Operators</h2></div></div></div><p>
+ The geometric types <code class="type">point</code>, <code class="type">box</code>,
+ <code class="type">lseg</code>, <code class="type">line</code>, <code class="type">path</code>,
+ <code class="type">polygon</code>, and <code class="type">circle</code> have a large set of
+ native support functions and operators, shown in <a class="xref" href="functions-geometry.html#FUNCTIONS-GEOMETRY-OP-TABLE" title="Table 9.36. Geometric Operators">Table 9.36</a>, <a class="xref" href="functions-geometry.html#FUNCTIONS-GEOMETRY-FUNC-TABLE" title="Table 9.37. Geometric Functions">Table 9.37</a>, and <a class="xref" href="functions-geometry.html#FUNCTIONS-GEOMETRY-CONV-TABLE" title="Table 9.38. Geometric Type Conversion Functions">Table 9.38</a>.
+ </p><div class="table" id="FUNCTIONS-GEOMETRY-OP-TABLE"><p class="title"><strong>Table 9.36. Geometric Operators</strong></p><div class="table-contents"><table class="table" summary="Geometric Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">+</code> <code class="type">point</code>
+ → <code class="returnvalue"><em class="replaceable"><code>geometric_type</code></em></code>
+ </p>
+ <p>
+ Adds the coordinates of the second <code class="type">point</code> to those of each
+ point of the first argument, thus performing translation.
+ Available for <code class="type">point</code>, <code class="type">box</code>, <code class="type">path</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(1,1),(0,0)' + point '(2,0)'</code>
+ → <code class="returnvalue">(3,1),(2,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">path</code> <code class="literal">+</code> <code class="type">path</code>
+ → <code class="returnvalue">path</code>
+ </p>
+ <p>
+ Concatenates two open paths (returns NULL if either path is closed).
+ </p>
+ <p>
+ <code class="literal">path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]'</code>
+ → <code class="returnvalue">[(0,0),(1,1),(2,2),(3,3),(4,4)]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">-</code> <code class="type">point</code>
+ → <code class="returnvalue"><em class="replaceable"><code>geometric_type</code></em></code>
+ </p>
+ <p>
+ Subtracts the coordinates of the second <code class="type">point</code> from those
+ of each point of the first argument, thus performing translation.
+ Available for <code class="type">point</code>, <code class="type">box</code>, <code class="type">path</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(1,1),(0,0)' - point '(2,0)'</code>
+ → <code class="returnvalue">(-1,1),(-2,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">*</code> <code class="type">point</code>
+ → <code class="returnvalue"><em class="replaceable"><code>geometric_type</code></em></code>
+ </p>
+ <p>
+ Multiplies each point of the first argument by the second
+ <code class="type">point</code> (treating a point as being a complex number
+ represented by real and imaginary parts, and performing standard
+ complex multiplication). If one interprets
+ the second <code class="type">point</code> as a vector, this is equivalent to
+ scaling the object's size and distance from the origin by the length
+ of the vector, and rotating it counterclockwise around the origin by
+ the vector's angle from the <em class="replaceable"><code>x</code></em> axis.
+ Available for <code class="type">point</code>, <code class="type">box</code>,<a href="#ftn.FUNCTIONS-GEOMETRY-ROTATION-FN" class="footnote"><sup class="footnote" id="FUNCTIONS-GEOMETRY-ROTATION-FN">[a]</sup></a>
+ <code class="type">path</code>, <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">path '((0,0),(1,0),(1,1))' * point '(3.0,0)'</code>
+ → <code class="returnvalue">((0,0),(3,0),(3,3))</code>
+ </p>
+ <p>
+ <code class="literal">path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45))</code>
+ → <code class="returnvalue">((0,0),​(0.7071067811865475,0.7071067811865475),​(0,1.414213562373095))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">/</code> <code class="type">point</code>
+ → <code class="returnvalue"><em class="replaceable"><code>geometric_type</code></em></code>
+ </p>
+ <p>
+ Divides each point of the first argument by the second
+ <code class="type">point</code> (treating a point as being a complex number
+ represented by real and imaginary parts, and performing standard
+ complex division). If one interprets
+ the second <code class="type">point</code> as a vector, this is equivalent to
+ scaling the object's size and distance from the origin down by the
+ length of the vector, and rotating it clockwise around the origin by
+ the vector's angle from the <em class="replaceable"><code>x</code></em> axis.
+ Available for <code class="type">point</code>, <code class="type">box</code>,<a href="functions-geometry.html#ftn.FUNCTIONS-GEOMETRY-ROTATION-FN" class="footnoteref"><sup class="footnoteref">[a]</sup></a> <code class="type">path</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">path '((0,0),(1,0),(1,1))' / point '(2.0,0)'</code>
+ → <code class="returnvalue">((0,0),(0.5,0),(0.5,0.5))</code>
+ </p>
+ <p>
+ <code class="literal">path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45))</code>
+ → <code class="returnvalue">((0,0),​(0.7071067811865476,-0.7071067811865476),​(1.4142135623730951,0))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">@-@</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the total length.
+ Available for <code class="type">lseg</code>, <code class="type">path</code>.
+ </p>
+ <p>
+ <code class="literal">@-@ path '[(0,0),(1,0),(1,1)]'</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">@@</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes the center point.
+ Available for <code class="type">box</code>, <code class="type">lseg</code>,
+ <code class="type">polygon</code>, <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">@@ box '(2,2),(0,0)'</code>
+ → <code class="returnvalue">(1,1)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">#</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of points.
+ Available for <code class="type">path</code>, <code class="type">polygon</code>.
+ </p>
+ <p>
+ <code class="literal"># path '((1,0),(0,1),(-1,0))'</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">#</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes the point of intersection, or NULL if there is none.
+ Available for <code class="type">lseg</code>, <code class="type">line</code>.
+ </p>
+ <p>
+ <code class="literal">lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'</code>
+ → <code class="returnvalue">(0.5,0.5)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">box</code> <code class="literal">#</code> <code class="type">box</code>
+ → <code class="returnvalue">box</code>
+ </p>
+ <p>
+ Computes the intersection of two boxes, or NULL if there is none.
+ </p>
+ <p>
+ <code class="literal">box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'</code>
+ → <code class="returnvalue">(1,1),(-1,-1)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">##</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes the closest point to the first object on the second object.
+ Available for these pairs of types:
+ (<code class="type">point</code>, <code class="type">box</code>),
+ (<code class="type">point</code>, <code class="type">lseg</code>),
+ (<code class="type">point</code>, <code class="type">line</code>),
+ (<code class="type">lseg</code>, <code class="type">box</code>),
+ (<code class="type">lseg</code>, <code class="type">lseg</code>),
+ (<code class="type">line</code>, <code class="type">lseg</code>).
+ </p>
+ <p>
+ <code class="literal">point '(0,0)' ## lseg '[(2,0),(0,2)]'</code>
+ → <code class="returnvalue">(1,1)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&lt;-&gt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the distance between the objects.
+ Available for all seven geometric types, for all combinations
+ of <code class="type">point</code> with another geometric type, and for
+ these additional pairs of types:
+ (<code class="type">box</code>, <code class="type">lseg</code>),
+ (<code class="type">lseg</code>, <code class="type">line</code>),
+ (<code class="type">polygon</code>, <code class="type">circle</code>)
+ (and the commutator cases).
+ </p>
+ <p>
+ <code class="literal">circle '&lt;(0,0),1&gt;' &lt;-&gt; circle '&lt;(5,0),1&gt;'</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">@&gt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does first object contain second?
+ Available for these pairs of types:
+ (<code class="literal">box</code>, <code class="literal">point</code>),
+ (<code class="literal">box</code>, <code class="literal">box</code>),
+ (<code class="literal">path</code>, <code class="literal">point</code>),
+ (<code class="literal">polygon</code>, <code class="literal">point</code>),
+ (<code class="literal">polygon</code>, <code class="literal">polygon</code>),
+ (<code class="literal">circle</code>, <code class="literal">point</code>),
+ (<code class="literal">circle</code>, <code class="literal">circle</code>).
+ </p>
+ <p>
+ <code class="literal">circle '&lt;(0,0),2&gt;' @&gt; point '(1,1)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&lt;@</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object contained in or on second?
+ Available for these pairs of types:
+ (<code class="literal">point</code>, <code class="literal">box</code>),
+ (<code class="literal">point</code>, <code class="literal">lseg</code>),
+ (<code class="literal">point</code>, <code class="literal">line</code>),
+ (<code class="literal">point</code>, <code class="literal">path</code>),
+ (<code class="literal">point</code>, <code class="literal">polygon</code>),
+ (<code class="literal">point</code>, <code class="literal">circle</code>),
+ (<code class="literal">box</code>, <code class="literal">box</code>),
+ (<code class="literal">lseg</code>, <code class="literal">box</code>),
+ (<code class="literal">lseg</code>, <code class="literal">line</code>),
+ (<code class="literal">polygon</code>, <code class="literal">polygon</code>),
+ (<code class="literal">circle</code>, <code class="literal">circle</code>).
+ </p>
+ <p>
+ <code class="literal">point '(1,1)' &lt;@ circle '&lt;(0,0),2&gt;'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&amp;&amp;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do these objects overlap? (One point in common makes this true.)
+ Available for <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(1,1),(0,0)' &amp;&amp; box '(2,2),(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&lt;&lt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object strictly left of second?
+ Available for <code class="type">point</code>, <code class="type">box</code>,
+ <code class="type">polygon</code>, <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">circle '&lt;(0,0),1&gt;' &lt;&lt; circle '&lt;(5,0),1&gt;'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&gt;&gt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object strictly right of second?
+ Available for <code class="type">point</code>, <code class="type">box</code>,
+ <code class="type">polygon</code>, <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">circle '&lt;(5,0),1&gt;' &gt;&gt; circle '&lt;(0,0),1&gt;'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&amp;&lt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does first object not extend to the right of second?
+ Available for <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(1,1),(0,0)' &amp;&lt; box '(2,2),(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&amp;&gt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does first object not extend to the left of second?
+ Available for <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(3,3),(0,0)' &amp;&gt; box '(2,2),(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&lt;&lt;|</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object strictly below second?
+ Available for <code class="type">point</code>, <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(3,3),(0,0)' &lt;&lt;| box '(5,5),(3,4)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">|&gt;&gt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object strictly above second?
+ Available for <code class="type">point</code>, <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(5,5),(3,4)' |&gt;&gt; box '(3,3),(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">&amp;&lt;|</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does first object not extend above second?
+ Available for <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(1,1),(0,0)' &amp;&lt;| box '(2,2),(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">|&amp;&gt;</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does first object not extend below second?
+ Available for <code class="type">box</code>, <code class="type">polygon</code>,
+ <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">box '(3,3),(0,0)' |&amp;&gt; box '(2,2),(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">box</code> <code class="literal">&lt;^</code> <code class="type">box</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object below second (allows edges to touch)?
+ </p>
+ <p>
+ <code class="literal">box '((1,1),(0,0))' &lt;^ box '((2,2),(1,1))'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">box</code> <code class="literal">&gt;^</code> <code class="type">box</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first object above second (allows edges to touch)?
+ </p>
+ <p>
+ <code class="literal">box '((2,2),(1,1))' &gt;^ box '((1,1),(0,0))'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">?#</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do these objects intersect?
+ Available for these pairs of types:
+ (<code class="type">box</code>, <code class="type">box</code>),
+ (<code class="type">lseg</code>, <code class="type">box</code>),
+ (<code class="type">lseg</code>, <code class="type">lseg</code>),
+ (<code class="type">lseg</code>, <code class="type">line</code>),
+ (<code class="type">line</code>, <code class="type">box</code>),
+ (<code class="type">line</code>, <code class="type">line</code>),
+ (<code class="type">path</code>, <code class="type">path</code>).
+ </p>
+ <p>
+ <code class="literal">lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">?-</code> <code class="type">line</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="literal">?-</code> <code class="type">lseg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is line horizontal?
+ </p>
+ <p>
+ <code class="literal">?- lseg '[(-1,0),(1,0)]'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">point</code> <code class="literal">?-</code> <code class="type">point</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are points horizontally aligned (that is, have same y coordinate)?
+ </p>
+ <p>
+ <code class="literal">point '(1,0)' ?- point '(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">?|</code> <code class="type">line</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="literal">?|</code> <code class="type">lseg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is line vertical?
+ </p>
+ <p>
+ <code class="literal">?| lseg '[(-1,0),(1,0)]'</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">point</code> <code class="literal">?|</code> <code class="type">point</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are points vertically aligned (that is, have same x coordinate)?
+ </p>
+ <p>
+ <code class="literal">point '(0,1)' ?| point '(0,0)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">line</code> <code class="literal">?-|</code> <code class="type">line</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">lseg</code> <code class="literal">?-|</code> <code class="type">lseg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are lines perpendicular?
+ </p>
+ <p>
+ <code class="literal">lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">line</code> <code class="literal">?||</code> <code class="type">line</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">lseg</code> <code class="literal">?||</code> <code class="type">lseg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are lines parallel?
+ </p>
+ <p>
+ <code class="literal">lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>geometric_type</code></em> <code class="literal">~=</code> <em class="replaceable"><code>geometric_type</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are these objects the same?
+ Available for <code class="type">point</code>, <code class="type">box</code>,
+ <code class="type">polygon</code>, <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr></tbody><tbody class="footnotes"><tr><td colspan="1"><div id="ftn.FUNCTIONS-GEOMETRY-ROTATION-FN" class="footnote"><p><a href="#FUNCTIONS-GEOMETRY-ROTATION-FN" class="para"><sup class="para">[a] </sup></a><span class="quote">“<span class="quote">Rotating</span>”</span> a
+ box with these operators only moves its corner points: the box is
+ still considered to have sides parallel to the axes. Hence the box's
+ size is not preserved, as a true rotation would do.</p></div></td></tr></tbody></table></div></div><br class="table-break" /><div class="caution"><h3 class="title">Caution</h3><p>
+ Note that the <span class="quote">“<span class="quote">same as</span>”</span> operator, <code class="literal">~=</code>,
+ represents the usual notion of equality for the <code class="type">point</code>,
+ <code class="type">box</code>, <code class="type">polygon</code>, and <code class="type">circle</code> types.
+ Some of the geometric types also have an <code class="literal">=</code> operator, but
+ <code class="literal">=</code> compares for equal <span class="emphasis"><em>areas</em></span> only.
+ The other scalar comparison operators (<code class="literal">&lt;=</code> and so
+ on), where available for these types, likewise compare areas.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> 14, the point
+ is strictly below/above comparison operators <code class="type">point</code>
+ <code class="literal">&lt;&lt;|</code> <code class="type">point</code> and <code class="type">point</code>
+ <code class="literal">|&gt;&gt;</code> <code class="type">point</code> were respectively
+ called <code class="literal">&lt;^</code> and <code class="literal">&gt;^</code>. These
+ names are still available, but are deprecated and will eventually be
+ removed.
+ </p></div><div class="table" id="FUNCTIONS-GEOMETRY-FUNC-TABLE"><p class="title"><strong>Table 9.37. Geometric Functions</strong></p><div class="table-contents"><table class="table" summary="Geometric Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">area</code> ( <em class="replaceable"><code>geometric_type</code></em> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes area.
+ Available for <code class="type">box</code>, <code class="type">path</code>, <code class="type">circle</code>.
+ A <code class="type">path</code> input must be closed, else NULL is returned.
+ Also, if the <code class="type">path</code> is self-intersecting, the result may be
+ meaningless.
+ </p>
+ <p>
+ <code class="literal">area(box '(2,2),(0,0)')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">center</code> ( <em class="replaceable"><code>geometric_type</code></em> )
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes center point.
+ Available for <code class="type">box</code>, <code class="type">circle</code>.
+ </p>
+ <p>
+ <code class="literal">center(box '(1,2),(0,0)')</code>
+ → <code class="returnvalue">(0.5,1)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">diagonal</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">lseg</code>
+ </p>
+ <p>
+ Extracts box's diagonal as a line segment
+ (same as <code class="function">lseg(box)</code>).
+ </p>
+ <p>
+ <code class="literal">diagonal(box '(1,2),(0,0)')</code>
+ → <code class="returnvalue">[(1,2),(0,0)]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">diameter</code> ( <code class="type">circle</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes diameter of circle.
+ </p>
+ <p>
+ <code class="literal">diameter(circle '&lt;(0,0),2&gt;')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">height</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes vertical size of box.
+ </p>
+ <p>
+ <code class="literal">height(box '(1,2),(0,0)')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">isclosed</code> ( <code class="type">path</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is path closed?
+ </p>
+ <p>
+ <code class="literal">isclosed(path '((0,0),(1,1),(2,0))')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">isopen</code> ( <code class="type">path</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is path open?
+ </p>
+ <p>
+ <code class="literal">isopen(path '[(0,0),(1,1),(2,0)]')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">length</code> ( <em class="replaceable"><code>geometric_type</code></em> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes the total length.
+ Available for <code class="type">lseg</code>, <code class="type">path</code>.
+ </p>
+ <p>
+ <code class="literal">length(path '((-1,0),(1,0))')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">npoints</code> ( <em class="replaceable"><code>geometric_type</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of points.
+ Available for <code class="type">path</code>, <code class="type">polygon</code>.
+ </p>
+ <p>
+ <code class="literal">npoints(path '[(0,0),(1,1),(2,0)]')</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pclose</code> ( <code class="type">path</code> )
+ → <code class="returnvalue">path</code>
+ </p>
+ <p>
+ Converts path to closed form.
+ </p>
+ <p>
+ <code class="literal">pclose(path '[(0,0),(1,1),(2,0)]')</code>
+ → <code class="returnvalue">((0,0),(1,1),(2,0))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">popen</code> ( <code class="type">path</code> )
+ → <code class="returnvalue">path</code>
+ </p>
+ <p>
+ Converts path to open form.
+ </p>
+ <p>
+ <code class="literal">popen(path '((0,0),(1,1),(2,0))')</code>
+ → <code class="returnvalue">[(0,0),(1,1),(2,0)]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">radius</code> ( <code class="type">circle</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes radius of circle.
+ </p>
+ <p>
+ <code class="literal">radius(circle '&lt;(0,0),2&gt;')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">slope</code> ( <code class="type">point</code>, <code class="type">point</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes slope of a line drawn through the two points.
+ </p>
+ <p>
+ <code class="literal">slope(point '(0,0)', point '(2,1)')</code>
+ → <code class="returnvalue">0.5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.6.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">width</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Computes horizontal size of box.
+ </p>
+ <p>
+ <code class="literal">width(box '(1,2),(0,0)')</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-GEOMETRY-CONV-TABLE"><p class="title"><strong>Table 9.38. Geometric Type Conversion Functions</strong></p><div class="table-contents"><table class="table" summary="Geometric Type Conversion Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">box</code> ( <code class="type">circle</code> )
+ → <code class="returnvalue">box</code>
+ </p>
+ <p>
+ Computes box inscribed within the circle.
+ </p>
+ <p>
+ <code class="literal">box(circle '&lt;(0,0),2&gt;')</code>
+ → <code class="returnvalue">(1.414213562373095,1.414213562373095),​(-1.414213562373095,-1.414213562373095)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">box</code> ( <code class="type">point</code> )
+ → <code class="returnvalue">box</code>
+ </p>
+ <p>
+ Converts point to empty box.
+ </p>
+ <p>
+ <code class="literal">box(point '(1,0)')</code>
+ → <code class="returnvalue">(1,0),(1,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">box</code> ( <code class="type">point</code>, <code class="type">point</code> )
+ → <code class="returnvalue">box</code>
+ </p>
+ <p>
+ Converts any two corner points to box.
+ </p>
+ <p>
+ <code class="literal">box(point '(0,1)', point '(1,0)')</code>
+ → <code class="returnvalue">(1,1),(0,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">box</code> ( <code class="type">polygon</code> )
+ → <code class="returnvalue">box</code>
+ </p>
+ <p>
+ Computes bounding box of polygon.
+ </p>
+ <p>
+ <code class="literal">box(polygon '((0,0),(1,1),(2,0))')</code>
+ → <code class="returnvalue">(2,1),(0,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">bound_box</code> ( <code class="type">box</code>, <code class="type">box</code> )
+ → <code class="returnvalue">box</code>
+ </p>
+ <p>
+ Computes bounding box of two boxes.
+ </p>
+ <p>
+ <code class="literal">bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)')</code>
+ → <code class="returnvalue">(4,4),(0,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">circle</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">circle</code>
+ </p>
+ <p>
+ Computes smallest circle enclosing box.
+ </p>
+ <p>
+ <code class="literal">circle(box '(1,1),(0,0)')</code>
+ → <code class="returnvalue">&lt;(0.5,0.5),0.7071067811865476&gt;</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">circle</code> ( <code class="type">point</code>, <code class="type">double precision</code> )
+ → <code class="returnvalue">circle</code>
+ </p>
+ <p>
+ Constructs circle from center and radius.
+ </p>
+ <p>
+ <code class="literal">circle(point '(0,0)', 2.0)</code>
+ → <code class="returnvalue">&lt;(0,0),2&gt;</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">circle</code> ( <code class="type">polygon</code> )
+ → <code class="returnvalue">circle</code>
+ </p>
+ <p>
+ Converts polygon to circle. The circle's center is the mean of the
+ positions of the polygon's points, and the radius is the average
+ distance of the polygon's points from that center.
+ </p>
+ <p>
+ <code class="literal">circle(polygon '((0,0),(1,3),(2,0))')</code>
+ → <code class="returnvalue">&lt;(1,1),1.6094757082487299&gt;</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">line</code> ( <code class="type">point</code>, <code class="type">point</code> )
+ → <code class="returnvalue">line</code>
+ </p>
+ <p>
+ Converts two points to the line through them.
+ </p>
+ <p>
+ <code class="literal">line(point '(-1,0)', point '(1,0)')</code>
+ → <code class="returnvalue">{0,-1,0}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">lseg</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">lseg</code>
+ </p>
+ <p>
+ Extracts box's diagonal as a line segment.
+ </p>
+ <p>
+ <code class="literal">lseg(box '(1,0),(-1,0)')</code>
+ → <code class="returnvalue">[(1,0),(-1,0)]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">lseg</code> ( <code class="type">point</code>, <code class="type">point</code> )
+ → <code class="returnvalue">lseg</code>
+ </p>
+ <p>
+ Constructs line segment from two endpoints.
+ </p>
+ <p>
+ <code class="literal">lseg(point '(-1,0)', point '(1,0)')</code>
+ → <code class="returnvalue">[(-1,0),(1,0)]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">path</code> ( <code class="type">polygon</code> )
+ → <code class="returnvalue">path</code>
+ </p>
+ <p>
+ Converts polygon to a closed path with the same list of points.
+ </p>
+ <p>
+ <code class="literal">path(polygon '((0,0),(1,1),(2,0))')</code>
+ → <code class="returnvalue">((0,0),(1,1),(2,0))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">point</code> ( <code class="type">double precision</code>, <code class="type">double precision</code> )
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Constructs point from its coordinates.
+ </p>
+ <p>
+ <code class="literal">point(23.4, -44.5)</code>
+ → <code class="returnvalue">(23.4,-44.5)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">point</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes center of box.
+ </p>
+ <p>
+ <code class="literal">point(box '(1,0),(-1,0)')</code>
+ → <code class="returnvalue">(0,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">point</code> ( <code class="type">circle</code> )
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes center of circle.
+ </p>
+ <p>
+ <code class="literal">point(circle '&lt;(0,0),2&gt;')</code>
+ → <code class="returnvalue">(0,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">point</code> ( <code class="type">lseg</code> )
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes center of line segment.
+ </p>
+ <p>
+ <code class="literal">point(lseg '[(-1,0),(1,0)]')</code>
+ → <code class="returnvalue">(0,0)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">point</code> ( <code class="type">polygon</code> )
+ → <code class="returnvalue">point</code>
+ </p>
+ <p>
+ Computes center of polygon (the mean of the
+ positions of the polygon's points).
+ </p>
+ <p>
+ <code class="literal">point(polygon '((0,0),(1,1),(2,0))')</code>
+ → <code class="returnvalue">(1,0.3333333333333333)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.17.7.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">polygon</code> ( <code class="type">box</code> )
+ → <code class="returnvalue">polygon</code>
+ </p>
+ <p>
+ Converts box to a 4-point polygon.
+ </p>
+ <p>
+ <code class="literal">polygon(box '(1,1),(0,0)')</code>
+ → <code class="returnvalue">((0,0),(0,1),(1,1),(1,0))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">polygon</code> ( <code class="type">circle</code> )
+ → <code class="returnvalue">polygon</code>
+ </p>
+ <p>
+ Converts circle to a 12-point polygon.
+ </p>
+ <p>
+ <code class="literal">polygon(circle '&lt;(0,0),2&gt;')</code>
+ → <code class="returnvalue">((-2,0),​(-1.7320508075688774,0.9999999999999999),​(-1.0000000000000002,1.7320508075688772),​(-1.2246063538223773e-16,2),​(0.9999999999999996,1.7320508075688774),​(1.732050807568877,1.0000000000000007),​(2,2.4492127076447545e-16),​(1.7320508075688776,-0.9999999999999994),​(1.0000000000000009,-1.7320508075688767),​(3.673819061467132e-16,-2),​(-0.9999999999999987,-1.732050807568878),​(-1.7320508075688767,-1.0000000000000009))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">polygon</code> ( <code class="type">integer</code>, <code class="type">circle</code> )
+ → <code class="returnvalue">polygon</code>
+ </p>
+ <p>
+ Converts circle to an <em class="replaceable"><code>n</code></em>-point polygon.
+ </p>
+ <p>
+ <code class="literal">polygon(4, circle '&lt;(3,0),1&gt;')</code>
+ → <code class="returnvalue">((2,0),​(3,1),​(4,1.2246063538223773e-16),​(3,-1))</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">polygon</code> ( <code class="type">path</code> )
+ → <code class="returnvalue">polygon</code>
+ </p>
+ <p>
+ Converts closed path to a polygon with the same list of points.
+ </p>
+ <p>
+ <code class="literal">polygon(path '((0,0),(1,1),(2,0))')</code>
+ → <code class="returnvalue">((0,0),(1,1),(2,0))</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ It is possible to access the two component numbers of a <code class="type">point</code>
+ as though the point were an array with indexes 0 and 1. For example, if
+ <code class="literal">t.p</code> is a <code class="type">point</code> column then
+ <code class="literal">SELECT p[0] FROM t</code> retrieves the X coordinate and
+ <code class="literal">UPDATE t SET p[1] = ...</code> changes the Y coordinate.
+ In the same way, a value of type <code class="type">box</code> or <code class="type">lseg</code> can be treated
+ as an array of two <code class="type">point</code> values.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-enum.html" title="9.10. Enum Support Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-net.html" title="9.12. Network Address Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.10. Enum Support Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.12. Network Address Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-info.html b/doc/src/sgml/html/functions-info.html
new file mode 100644
index 0000000..21ba058
--- /dev/null
+++ b/doc/src/sgml/html/functions-info.html
@@ -0,0 +1,1774 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.26. System Information Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-srf.html" title="9.25. Set Returning Functions" /><link rel="next" href="functions-admin.html" title="9.27. System Administration Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.26. System Information Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-srf.html" title="9.25. Set Returning Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-admin.html" title="9.27. System Administration Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-INFO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.26. System Information Functions and Operators</h2></div></div></div><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-SESSION-TABLE" title="Table 9.66. Session Information Functions">Table 9.66</a> shows several
+ functions that extract session and system information.
+ </p><p>
+ In addition to the functions listed in this section, there are a number of
+ functions related to the statistics system that also provide system
+ information. See <a class="xref" href="monitoring-stats.html#MONITORING-STATS-VIEWS" title="28.2.2. Viewing Statistics">Section 28.2.2</a> for more
+ information.
+ </p><div class="table" id="FUNCTIONS-INFO-SESSION-TABLE"><p class="title"><strong>Table 9.66. Session Information Functions</strong></p><div class="table-contents"><table class="table" summary="Session Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">current_catalog</code>
+ → <code class="returnvalue">name</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.1.1.2.1" class="indexterm"></a>
+ <code class="function">current_database</code> ()
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Returns the name of the current database. (Databases are
+ called <span class="quote">“<span class="quote">catalogs</span>”</span> in the SQL standard,
+ so <code class="function">current_catalog</code> is the standard's
+ spelling.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">current_query</code> ()
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the text of the currently executing query, as submitted
+ by the client (which might contain more than one statement).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">current_role</code>
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ This is equivalent to <code class="function">current_user</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.4.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.32.4.2.2.4.1.1.2" class="indexterm"></a>
+ <code class="function">current_schema</code>
+ → <code class="returnvalue">name</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">current_schema</code> ()
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Returns the name of the schema that is first in the search path (or a
+ null value if the search path is empty). This is the schema that will
+ be used for any tables or other named objects that are created without
+ specifying a target schema.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.5.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.32.4.2.2.5.1.1.2" class="indexterm"></a>
+ <code class="function">current_schemas</code> ( <em class="parameter"><code>include_implicit</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">name[]</code>
+ </p>
+ <p>
+ Returns an array of the names of all schemas presently in the
+ effective search path, in their priority order. (Items in the current
+ <a class="xref" href="runtime-config-client.html#GUC-SEARCH-PATH">search_path</a> setting that do not correspond to
+ existing, searchable schemas are omitted.) If the Boolean argument
+ is <code class="literal">true</code>, then implicitly-searched system schemas
+ such as <code class="literal">pg_catalog</code> are included in the result.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.6.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.32.4.2.2.6.1.1.2" class="indexterm"></a>
+ <code class="function">current_user</code>
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Returns the user name of the current execution context.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">inet_client_addr</code> ()
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Returns the IP address of the current client,
+ or <code class="literal">NULL</code> if the current connection is via a
+ Unix-domain socket.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">inet_client_port</code> ()
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the IP port number of the current client,
+ or <code class="literal">NULL</code> if the current connection is via a
+ Unix-domain socket.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">inet_server_addr</code> ()
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Returns the IP address on which the server accepted the current
+ connection,
+ or <code class="literal">NULL</code> if the current connection is via a
+ Unix-domain socket.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">inet_server_port</code> ()
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the IP port number on which the server accepted the current
+ connection,
+ or <code class="literal">NULL</code> if the current connection is via a
+ Unix-domain socket.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_backend_pid</code> ()
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the process ID of the server process attached to the current
+ session.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">pg_blocking_pids</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Returns an array of the process ID(s) of the sessions that are
+ blocking the server process with the specified process ID from
+ acquiring a lock, or an empty array if there is no such server process
+ or it is not blocked.
+ </p>
+ <p>
+ One server process blocks another if it either holds a lock that
+ conflicts with the blocked process's lock request (hard block), or is
+ waiting for a lock that would conflict with the blocked process's lock
+ request and is ahead of it in the wait queue (soft block). When using
+ parallel queries the result always lists client-visible process IDs
+ (that is, <code class="function">pg_backend_pid</code> results) even if the
+ actual lock is held or awaited by a child worker process. As a result
+ of that, there may be duplicated PIDs in the result. Also note that
+ when a prepared transaction holds a conflicting lock, it will be
+ represented by a zero process ID.
+ </p>
+ <p>
+ Frequent calls to this function could have some impact on database
+ performance, because it needs exclusive access to the lock manager's
+ shared state for a short time.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">pg_conf_load_time</code> ()
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the time when the server configuration files were last loaded.
+ If the current session was alive at the time, this will be the time
+ when the session itself re-read the configuration files (so the
+ reading will vary a little in different sessions). Otherwise it is
+ the time when the postmaster process re-read the configuration files.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.14.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.32.4.2.2.14.1.1.2" class="indexterm"></a>
+ <a id="id-1.5.8.32.4.2.2.14.1.1.3" class="indexterm"></a>
+ <a id="id-1.5.8.32.4.2.2.14.1.1.4" class="indexterm"></a>
+ <code class="function">pg_current_logfile</code> ( [<span class="optional"> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the path name of the log file currently in use by the logging
+ collector. The path includes the <a class="xref" href="runtime-config-logging.html#GUC-LOG-DIRECTORY">log_directory</a>
+ directory and the individual log file name. The result
+ is <code class="literal">NULL</code> if the logging collector is disabled.
+ When multiple log files exist, each in a different
+ format, <code class="function">pg_current_logfile</code> without an argument
+ returns the path of the file having the first format found in the
+ ordered list: <code class="literal">stderr</code>,
+ <code class="literal">csvlog</code>, <code class="literal">jsonlog</code>.
+ <code class="literal">NULL</code> is returned if no log file has any of these
+ formats.
+ To request information about a specific log file format, supply
+ either <code class="literal">csvlog</code>, <code class="literal">jsonlog</code> or
+ <code class="literal">stderr</code> as the
+ value of the optional parameter. The result is <code class="literal">NULL</code>
+ if the log format requested is not configured in
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-DESTINATION">log_destination</a>.
+ The result reflects the contents of
+ the <code class="filename">current_logfiles</code> file.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">pg_my_temp_schema</code> ()
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Returns the OID of the current session's temporary schema, or zero if
+ it has none (because it has not created any temporary tables).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">pg_is_other_temp_schema</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if the given OID is the OID of another session's
+ temporary schema. (This can be useful, for example, to exclude other
+ sessions' temporary tables from a catalog display.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">pg_jit_available</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if a <acronym class="acronym">JIT</acronym> compiler extension is
+ available (see <a class="xref" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Chapter 32</a>) and the
+ <a class="xref" href="runtime-config-query.html#GUC-JIT">jit</a> configuration parameter is set to
+ <code class="literal">on</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">pg_listening_channels</code> ()
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Returns the set of names of asynchronous notification channels that
+ the current session is listening to.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">pg_notification_queue_usage</code> ()
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Returns the fraction (0–1) of the asynchronous notification
+ queue's maximum size that is currently occupied by notifications that
+ are waiting to be processed.
+ See <a class="xref" href="sql-listen.html" title="LISTEN"><span class="refentrytitle">LISTEN</span></a> and <a class="xref" href="sql-notify.html" title="NOTIFY"><span class="refentrytitle">NOTIFY</span></a>
+ for more information.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.20.1.1.1" class="indexterm"></a>
+ <code class="function">pg_postmaster_start_time</code> ()
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the time when the server started.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">pg_safe_snapshot_blocking_pids</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Returns an array of the process ID(s) of the sessions that are blocking
+ the server process with the specified process ID from acquiring a safe
+ snapshot, or an empty array if there is no such server process or it
+ is not blocked.
+ </p>
+ <p>
+ A session running a <code class="literal">SERIALIZABLE</code> transaction blocks
+ a <code class="literal">SERIALIZABLE READ ONLY DEFERRABLE</code> transaction
+ from acquiring a snapshot until the latter determines that it is safe
+ to avoid taking any predicate locks. See
+ <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a> for more information about
+ serializable and deferrable transactions.
+ </p>
+ <p>
+ Frequent calls to this function could have some impact on database
+ performance, because it needs access to the predicate lock manager's
+ shared state for a short time.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">pg_trigger_depth</code> ()
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the current nesting level
+ of <span class="productname">PostgreSQL</span> triggers (0 if not called,
+ directly or indirectly, from inside a trigger).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">session_user</code>
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Returns the session user's name.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.24.1.1.1" class="indexterm"></a>
+ <code class="function">user</code>
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ This is equivalent to <code class="function">current_user</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.4.2.2.25.1.1.1" class="indexterm"></a>
+ <code class="function">version</code> ()
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns a string describing the <span class="productname">PostgreSQL</span>
+ server's version. You can also get this information from
+ <a class="xref" href="runtime-config-preset.html#GUC-SERVER-VERSION">server_version</a>, or for a machine-readable
+ version use <a class="xref" href="runtime-config-preset.html#GUC-SERVER-VERSION-NUM">server_version_num</a>. Software
+ developers should use <code class="varname">server_version_num</code> (available
+ since 8.2) or <a class="xref" href="libpq-status.html#LIBPQ-PQSERVERVERSION"><code class="function">PQserverVersion</code></a> instead of
+ parsing the text version.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ <code class="function">current_catalog</code>,
+ <code class="function">current_role</code>,
+ <code class="function">current_schema</code>,
+ <code class="function">current_user</code>,
+ <code class="function">session_user</code>,
+ and <code class="function">user</code> have special syntactic status
+ in <acronym class="acronym">SQL</acronym>: they must be called without trailing
+ parentheses. In PostgreSQL, parentheses can optionally be used with
+ <code class="function">current_schema</code>, but not with the others.
+ </p></div><p>
+ The <code class="function">session_user</code> is normally the user who initiated
+ the current database connection; but superusers can change this setting
+ with <a class="xref" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION"><span class="refentrytitle">SET SESSION AUTHORIZATION</span></a>.
+ The <code class="function">current_user</code> is the user identifier
+ that is applicable for permission checking. Normally it is equal
+ to the session user, but it can be changed with
+ <a class="xref" href="sql-set-role.html" title="SET ROLE"><span class="refentrytitle">SET ROLE</span></a>.
+ It also changes during the execution of
+ functions with the attribute <code class="literal">SECURITY DEFINER</code>.
+ In Unix parlance, the session user is the <span class="quote">“<span class="quote">real user</span>”</span> and
+ the current user is the <span class="quote">“<span class="quote">effective user</span>”</span>.
+ <code class="function">current_role</code> and <code class="function">user</code> are
+ synonyms for <code class="function">current_user</code>. (The SQL standard draws
+ a distinction between <code class="function">current_role</code>
+ and <code class="function">current_user</code>, but <span class="productname">PostgreSQL</span>
+ does not, since it unifies users and roles into a single kind of entity.)
+ </p><a id="id-1.5.8.32.7" class="indexterm"></a><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-ACCESS-TABLE" title="Table 9.67. Access Privilege Inquiry Functions">Table 9.67</a> lists functions that
+ allow querying object access privileges programmatically.
+ (See <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for more information about
+ privileges.)
+ In these functions, the user whose privileges are being inquired about
+ can be specified by name or by OID
+ (<code class="structname">pg_authid</code>.<code class="structfield">oid</code>), or if
+ the name is given as <code class="literal">public</code> then the privileges of the
+ PUBLIC pseudo-role are checked. Also, the <em class="parameter"><code>user</code></em>
+ argument can be omitted entirely, in which case
+ the <code class="function">current_user</code> is assumed.
+ The object that is being inquired about can be specified either by name or
+ by OID, too. When specifying by name, a schema name can be included if
+ relevant.
+ The access privilege of interest is specified by a text string, which must
+ evaluate to one of the appropriate privilege keywords for the object's type
+ (e.g., <code class="literal">SELECT</code>). Optionally, <code class="literal">WITH GRANT
+ OPTION</code> can be added to a privilege type to test whether the
+ privilege is held with grant option. Also, multiple privilege types can be
+ listed separated by commas, in which case the result will be true if any of
+ the listed privileges is held. (Case of the privilege string is not
+ significant, and extra whitespace is allowed between but not within
+ privilege names.)
+ Some examples:
+</p><pre class="programlisting">
+SELECT has_table_privilege('myschema.mytable', 'select');
+SELECT has_table_privilege('joe', 'mytable', 'INSERT, SELECT WITH GRANT OPTION');
+</pre><p>
+ </p><div class="table" id="FUNCTIONS-INFO-ACCESS-TABLE"><p class="title"><strong>Table 9.67. Access Privilege Inquiry Functions</strong></p><div class="table-contents"><table class="table" summary="Access Privilege Inquiry Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">has_any_column_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>table</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for any column of table?
+ This succeeds either if the privilege is held for the whole table, or
+ if there is a column-level grant of the privilege for at least one
+ column.
+ Allowable privilege types are
+ <code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, and <code class="literal">REFERENCES</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">has_column_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>table</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>column</code></em> <code class="type">text</code> or <code class="type">smallint</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for the specified table column?
+ This succeeds either if the privilege is held for the whole table, or
+ if there is a column-level grant of the privilege for the column.
+ The column can be specified by name or by attribute number
+ (<code class="structname">pg_attribute</code>.<code class="structfield">attnum</code>).
+ Allowable privilege types are
+ <code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, and <code class="literal">REFERENCES</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">has_database_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>database</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for database?
+ Allowable privilege types are
+ <code class="literal">CREATE</code>,
+ <code class="literal">CONNECT</code>,
+ <code class="literal">TEMPORARY</code>, and
+ <code class="literal">TEMP</code> (which is equivalent to
+ <code class="literal">TEMPORARY</code>).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">has_foreign_data_wrapper_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>fdw</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for foreign-data wrapper?
+ The only allowable privilege type is <code class="literal">USAGE</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">has_function_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>function</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for function?
+ The only allowable privilege type is <code class="literal">EXECUTE</code>.
+ </p>
+ <p>
+ When specifying a function by name rather than by OID, the allowed
+ input is the same as for the <code class="type">regprocedure</code> data type (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>).
+ An example is:
+</p><pre class="programlisting">
+SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute');
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">has_language_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>language</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for language?
+ The only allowable privilege type is <code class="literal">USAGE</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">has_parameter_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>parameter</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for configuration parameter?
+ The parameter name is case-insensitive.
+ Allowable privilege types are <code class="literal">SET</code>
+ and <code class="literal">ALTER SYSTEM</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">has_schema_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>schema</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for schema?
+ Allowable privilege types are
+ <code class="literal">CREATE</code> and
+ <code class="literal">USAGE</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">has_sequence_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>sequence</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for sequence?
+ Allowable privilege types are
+ <code class="literal">USAGE</code>,
+ <code class="literal">SELECT</code>, and
+ <code class="literal">UPDATE</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">has_server_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>server</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for foreign server?
+ The only allowable privilege type is <code class="literal">USAGE</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">has_table_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>table</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for table?
+ Allowable privilege types
+ are <code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
+ <code class="literal">TRUNCATE</code>, <code class="literal">REFERENCES</code>,
+ and <code class="literal">TRIGGER</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">has_tablespace_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>tablespace</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for tablespace?
+ The only allowable privilege type is <code class="literal">CREATE</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">has_type_privilege</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>type</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for data type?
+ The only allowable privilege type is <code class="literal">USAGE</code>.
+ When specifying a type by name rather than by OID, the allowed input
+ is the same as for the <code class="type">regtype</code> data type (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">pg_has_role</code> (
+ [<span class="optional"> <em class="parameter"><code>user</code></em> <code class="type">name</code> or <code class="type">oid</code>, </span>]
+ <em class="parameter"><code>role</code></em> <code class="type">text</code> or <code class="type">oid</code>,
+ <em class="parameter"><code>privilege</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does user have privilege for role?
+ Allowable privilege types are
+ <code class="literal">MEMBER</code> and <code class="literal">USAGE</code>.
+ <code class="literal">MEMBER</code> denotes direct or indirect membership in
+ the role (that is, the right to do <code class="command">SET ROLE</code>), while
+ <code class="literal">USAGE</code> denotes whether the privileges of the role
+ are immediately available without doing <code class="command">SET ROLE</code>.
+ This function does not allow the special case of
+ setting <em class="parameter"><code>user</code></em> to <code class="literal">public</code>,
+ because the PUBLIC pseudo-role can never be a member of real roles.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.9.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">row_security_active</code> (
+ <em class="parameter"><code>table</code></em> <code class="type">text</code> or <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is row-level security active for the specified table in the context of
+ the current user and current environment?
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-ACLITEM-OP-TABLE" title="Table 9.68. aclitem Operators">Table 9.68</a> shows the operators
+ available for the <code class="type">aclitem</code> type, which is the catalog
+ representation of access privileges. See <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>
+ for information about how to read access privilege values.
+ </p><div class="table" id="FUNCTIONS-ACLITEM-OP-TABLE"><p class="title"><strong>Table 9.68. <code class="type">aclitem</code> Operators</strong></p><div class="table-contents"><table class="table" summary="aclitem Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.11.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="type">aclitem</code> <code class="literal">=</code> <code class="type">aclitem</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are <code class="type">aclitem</code>s equal? (Notice that
+ type <code class="type">aclitem</code> lacks the usual set of comparison
+ operators; it has only equality. In turn, <code class="type">aclitem</code>
+ arrays can only be compared for equality.)
+ </p>
+ <p>
+ <code class="literal">'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.11.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="type">aclitem[]</code> <code class="literal">@&gt;</code> <code class="type">aclitem</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array contain the specified privileges? (This is true if there
+ is an array entry that matches the <code class="type">aclitem</code>'s grantee and
+ grantor, and has at least the specified set of privileges.)
+ </p>
+ <p>
+ <code class="literal">'{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @&gt; 'calvin=r*/hobbes'::aclitem</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">aclitem[]</code> <code class="literal">~</code> <code class="type">aclitem</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ This is a deprecated alias for <code class="literal">@&gt;</code>.
+ </p>
+ <p>
+ <code class="literal">'{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] ~ 'calvin=r*/hobbes'::aclitem</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-ACLITEM-FN-TABLE" title="Table 9.69. aclitem Functions">Table 9.69</a> shows some additional
+ functions to manage the <code class="type">aclitem</code> type.
+ </p><div class="table" id="FUNCTIONS-ACLITEM-FN-TABLE"><p class="title"><strong>Table 9.69. <code class="type">aclitem</code> Functions</strong></p><div class="table-contents"><table class="table" summary="aclitem Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.13.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">acldefault</code> (
+ <em class="parameter"><code>type</code></em> <code class="type">"char"</code>,
+ <em class="parameter"><code>ownerId</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">aclitem[]</code>
+ </p>
+ <p>
+ Constructs an <code class="type">aclitem</code> array holding the default access
+ privileges for an object of type <em class="parameter"><code>type</code></em> belonging
+ to the role with OID <em class="parameter"><code>ownerId</code></em>. This represents
+ the access privileges that will be assumed when an object's ACL entry
+ is null. (The default access privileges are described in
+ <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>.)
+ The <em class="parameter"><code>type</code></em> parameter must be one of
+ 'c' for <code class="literal">COLUMN</code>,
+ 'r' for <code class="literal">TABLE</code> and table-like objects,
+ 's' for <code class="literal">SEQUENCE</code>,
+ 'd' for <code class="literal">DATABASE</code>,
+ 'f' for <code class="literal">FUNCTION</code> or <code class="literal">PROCEDURE</code>,
+ 'l' for <code class="literal">LANGUAGE</code>,
+ 'L' for <code class="literal">LARGE OBJECT</code>,
+ 'n' for <code class="literal">SCHEMA</code>,
+ 'p' for <code class="literal">PARAMETER</code>,
+ 't' for <code class="literal">TABLESPACE</code>,
+ 'F' for <code class="literal">FOREIGN DATA WRAPPER</code>,
+ 'S' for <code class="literal">FOREIGN SERVER</code>,
+ or
+ 'T' for <code class="literal">TYPE</code> or <code class="literal">DOMAIN</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.13.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">aclexplode</code> ( <code class="type">aclitem[]</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>grantor</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>grantee</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>privilege_type</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>is_grantable</code></em> <code class="type">boolean</code> )
+ </p>
+ <p>
+ Returns the <code class="type">aclitem</code> array as a set of rows.
+ If the grantee is the pseudo-role PUBLIC, it is represented by zero in
+ the <em class="parameter"><code>grantee</code></em> column. Each granted privilege is
+ represented as <code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
+ etc. Note that each privilege is broken out as a separate row, so
+ only one keyword appears in the <em class="parameter"><code>privilege_type</code></em>
+ column.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.13.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">makeaclitem</code> (
+ <em class="parameter"><code>grantee</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>grantor</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>privileges</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>is_grantable</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">aclitem</code>
+ </p>
+ <p>
+ Constructs an <code class="type">aclitem</code> with the given properties.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-SCHEMA-TABLE" title="Table 9.70. Schema Visibility Inquiry Functions">Table 9.70</a> shows functions that
+ determine whether a certain object is <em class="firstterm">visible</em> in the
+ current schema search path.
+ For example, a table is said to be visible if its
+ containing schema is in the search path and no table of the same
+ name appears earlier in the search path. This is equivalent to the
+ statement that the table can be referenced by name without explicit
+ schema qualification. Thus, to list the names of all visible tables:
+</p><pre class="programlisting">
+SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
+</pre><p>
+ For functions and operators, an object in the search path is said to be
+ visible if there is no object of the same name <span class="emphasis"><em>and argument data
+ type(s)</em></span> earlier in the path. For operator classes and families,
+ both the name and the associated index access method are considered.
+ </p><a id="id-1.5.8.32.15" class="indexterm"></a><div class="table" id="FUNCTIONS-INFO-SCHEMA-TABLE"><p class="title"><strong>Table 9.70. Schema Visibility Inquiry Functions</strong></p><div class="table-contents"><table class="table" summary="Schema Visibility Inquiry Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_collation_is_visible</code> ( <em class="parameter"><code>collation</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is collation visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_conversion_is_visible</code> ( <em class="parameter"><code>conversion</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is conversion visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_function_is_visible</code> ( <em class="parameter"><code>function</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is function visible in search path?
+ (This also works for procedures and aggregates.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_opclass_is_visible</code> ( <em class="parameter"><code>opclass</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is operator class visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_operator_is_visible</code> ( <em class="parameter"><code>operator</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is operator visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_opfamily_is_visible</code> ( <em class="parameter"><code>opclass</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is operator family visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_statistics_obj_is_visible</code> ( <em class="parameter"><code>stat</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is statistics object visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_table_is_visible</code> ( <em class="parameter"><code>table</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is table visible in search path?
+ (This works for all types of relations, including views, materialized
+ views, indexes, sequences and foreign tables.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ts_config_is_visible</code> ( <em class="parameter"><code>config</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is text search configuration visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ts_dict_is_visible</code> ( <em class="parameter"><code>dict</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is text search dictionary visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ts_parser_is_visible</code> ( <em class="parameter"><code>parser</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is text search parser visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">pg_ts_template_is_visible</code> ( <em class="parameter"><code>template</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is text search template visible in search path?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.16.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">pg_type_is_visible</code> ( <em class="parameter"><code>type</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is type (or domain) visible in search path?
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ All these functions require object OIDs to identify the object to be
+ checked. If you want to test an object by name, it is convenient to use
+ the OID alias types (<code class="type">regclass</code>, <code class="type">regtype</code>,
+ <code class="type">regprocedure</code>, <code class="type">regoperator</code>, <code class="type">regconfig</code>,
+ or <code class="type">regdictionary</code>),
+ for example:
+</p><pre class="programlisting">
+SELECT pg_type_is_visible('myschema.widget'::regtype);
+</pre><p>
+ Note that it would not make much sense to test a non-schema-qualified
+ type name in this way — if the name can be recognized at all, it must be visible.
+ </p><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE" title="Table 9.71. System Catalog Information Functions">Table 9.71</a> lists functions that
+ extract information from the system catalogs.
+ </p><div class="table" id="FUNCTIONS-INFO-CATALOG-TABLE"><p class="title"><strong>Table 9.71. System Catalog Information Functions</strong></p><div class="table-contents"><table class="table" summary="System Catalog Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">format_type</code> ( <em class="parameter"><code>type</code></em> <code class="type">oid</code>, <em class="parameter"><code>typemod</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the SQL name for a data type that is identified by its type
+ OID and possibly a type modifier. Pass NULL for the type modifier if
+ no specific modifier is known.
+ </p></td></tr><tr><td id="PG-CHAR-TO-ENCODING" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_char_to_encoding</code> ( <em class="parameter"><code>encoding</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Converts the supplied encoding name into an integer representing the
+ internal identifier used in some system catalog tables.
+ Returns <code class="literal">-1</code> if an unknown encoding name is provided.
+ </p></td></tr><tr><td id="PG-ENCODING-TO-CHAR" class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_encoding_to_char</code> ( <em class="parameter"><code>encoding</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Converts the integer used as the internal identifier of an encoding in some
+ system catalog tables into a human-readable string.
+ Returns an empty string if an invalid encoding number is provided.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_catalog_foreign_keys</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>fktable</code></em> <code class="type">regclass</code>,
+ <em class="parameter"><code>fkcols</code></em> <code class="type">text[]</code>,
+ <em class="parameter"><code>pktable</code></em> <code class="type">regclass</code>,
+ <em class="parameter"><code>pkcols</code></em> <code class="type">text[]</code>,
+ <em class="parameter"><code>is_array</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>is_opt</code></em> <code class="type">boolean</code> )
+ </p>
+ <p>
+ Returns a set of records describing the foreign key relationships
+ that exist within the <span class="productname">PostgreSQL</span> system
+ catalogs.
+ The <em class="parameter"><code>fktable</code></em> column contains the name of the
+ referencing catalog, and the <em class="parameter"><code>fkcols</code></em> column
+ contains the name(s) of the referencing column(s). Similarly,
+ the <em class="parameter"><code>pktable</code></em> column contains the name of the
+ referenced catalog, and the <em class="parameter"><code>pkcols</code></em> column
+ contains the name(s) of the referenced column(s).
+ If <em class="parameter"><code>is_array</code></em> is true, the last referencing
+ column is an array, each of whose elements should match some entry
+ in the referenced catalog.
+ If <em class="parameter"><code>is_opt</code></em> is true, the referencing column(s)
+ are allowed to contain zeroes instead of a valid reference.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_constraintdef</code> ( <em class="parameter"><code>constraint</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the creating command for a constraint.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_expr</code> ( <em class="parameter"><code>expr</code></em> <code class="type">pg_node_tree</code>, <em class="parameter"><code>relation</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Decompiles the internal form of an expression stored in the system
+ catalogs, such as the default value for a column. If the expression
+ might contain Vars, specify the OID of the relation they refer to as
+ the second parameter; if no Vars are expected, passing zero is
+ sufficient.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_functiondef</code> ( <em class="parameter"><code>func</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the creating command for a function or procedure.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ The result is a complete <code class="command">CREATE OR REPLACE FUNCTION</code>
+ or <code class="command">CREATE OR REPLACE PROCEDURE</code> statement.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_function_arguments</code> ( <em class="parameter"><code>func</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the argument list of a function or procedure, in the form
+ it would need to appear in within <code class="command">CREATE FUNCTION</code>
+ (including default values).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_function_identity_arguments</code> ( <em class="parameter"><code>func</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the argument list necessary to identify a function or
+ procedure, in the form it would need to appear in within commands such
+ as <code class="command">ALTER FUNCTION</code>. This form omits default values.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_function_result</code> ( <em class="parameter"><code>func</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the <code class="literal">RETURNS</code> clause of a function, in
+ the form it would need to appear in within <code class="command">CREATE
+ FUNCTION</code>. Returns <code class="literal">NULL</code> for a procedure.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_indexdef</code> ( <em class="parameter"><code>index</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>column</code></em> <code class="type">integer</code>, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the creating command for an index.
+ (This is a decompiled reconstruction, not the original text
+ of the command.) If <em class="parameter"><code>column</code></em> is supplied and is
+ not zero, only the definition of that column is reconstructed.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_keywords</code> ()
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>word</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>catcode</code></em> <code class="type">"char"</code>,
+ <em class="parameter"><code>barelabel</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>catdesc</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>baredesc</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Returns a set of records describing the SQL keywords recognized by the
+ server. The <em class="parameter"><code>word</code></em> column contains the
+ keyword. The <em class="parameter"><code>catcode</code></em> column contains a
+ category code: <code class="literal">U</code> for an unreserved
+ keyword, <code class="literal">C</code> for a keyword that can be a column
+ name, <code class="literal">T</code> for a keyword that can be a type or
+ function name, or <code class="literal">R</code> for a fully reserved keyword.
+ The <em class="parameter"><code>barelabel</code></em> column
+ contains <code class="literal">true</code> if the keyword can be used as
+ a <span class="quote">“<span class="quote">bare</span>”</span> column label in <code class="command">SELECT</code> lists,
+ or <code class="literal">false</code> if it can only be used
+ after <code class="literal">AS</code>.
+ The <em class="parameter"><code>catdesc</code></em> column contains a
+ possibly-localized string describing the keyword's category.
+ The <em class="parameter"><code>baredesc</code></em> column contains a
+ possibly-localized string describing the keyword's column label status.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_ruledef</code> ( <em class="parameter"><code>rule</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the creating command for a rule.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_serial_sequence</code> ( <em class="parameter"><code>table</code></em> <code class="type">text</code>, <em class="parameter"><code>column</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the name of the sequence associated with a column,
+ or NULL if no sequence is associated with the column.
+ If the column is an identity column, the associated sequence is the
+ sequence internally created for that column.
+ For columns created using one of the serial types
+ (<code class="type">serial</code>, <code class="type">smallserial</code>, <code class="type">bigserial</code>),
+ it is the sequence created for that serial column definition.
+ In the latter case, the association can be modified or removed
+ with <code class="command">ALTER SEQUENCE OWNED BY</code>.
+ (This function probably should have been
+ called <code class="function">pg_get_owned_sequence</code>; its current name
+ reflects the fact that it has historically been used with serial-type
+ columns.) The first parameter is a table name with optional
+ schema, and the second parameter is a column name. Because the first
+ parameter potentially contains both schema and table names, it is
+ parsed per usual SQL rules, meaning it is lower-cased by default.
+ The second parameter, being just a column name, is treated literally
+ and so has its case preserved. The result is suitably formatted
+ for passing to the sequence functions (see
+ <a class="xref" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Section 9.17</a>).
+ </p>
+ <p>
+ A typical use is in reading the current value of the sequence for an
+ identity or serial column, for example:
+</p><pre class="programlisting">
+SELECT currval(pg_get_serial_sequence('sometable', 'id'));
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_statisticsobjdef</code> ( <em class="parameter"><code>statobj</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the creating command for an extended statistics object.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.16.1.1.1" class="indexterm"></a>
+<code class="function">pg_get_triggerdef</code> ( <em class="parameter"><code>trigger</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the creating command for a trigger.
+ (This is a decompiled reconstruction, not the original text
+ of the command.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_userbyid</code> ( <em class="parameter"><code>role</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Returns a role's name given its OID.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_viewdef</code> ( <em class="parameter"><code>view</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the underlying <code class="command">SELECT</code> command for a
+ view or materialized view. (This is a decompiled reconstruction, not
+ the original text of the command.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_get_viewdef</code> ( <em class="parameter"><code>view</code></em> <code class="type">oid</code>, <em class="parameter"><code>wrap_column</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the underlying <code class="command">SELECT</code> command for a
+ view or materialized view. (This is a decompiled reconstruction, not
+ the original text of the command.) In this form of the function,
+ pretty-printing is always enabled, and long lines are wrapped to try
+ to keep them shorter than the specified number of columns.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_get_viewdef</code> ( <em class="parameter"><code>view</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>pretty</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reconstructs the underlying <code class="command">SELECT</code> command for a
+ view or materialized view, working from a textual name for the view
+ rather than its OID. (This is deprecated; use the OID variant
+ instead.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">pg_index_column_has_property</code> ( <em class="parameter"><code>index</code></em> <code class="type">regclass</code>, <em class="parameter"><code>column</code></em> <code class="type">integer</code>, <em class="parameter"><code>property</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether an index column has the named property.
+ Common index column properties are listed in
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-INDEX-COLUMN-PROPS" title="Table 9.72. Index Column Properties">Table 9.72</a>.
+ (Note that extension access methods can define additional property
+ names for their indexes.)
+ <code class="literal">NULL</code> is returned if the property name is not known
+ or does not apply to the particular object, or if the OID or column
+ number does not identify a valid object.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">pg_index_has_property</code> ( <em class="parameter"><code>index</code></em> <code class="type">regclass</code>, <em class="parameter"><code>property</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether an index has the named property.
+ Common index properties are listed in
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-INDEX-PROPS" title="Table 9.73. Index Properties">Table 9.73</a>.
+ (Note that extension access methods can define additional property
+ names for their indexes.)
+ <code class="literal">NULL</code> is returned if the property name is not known
+ or does not apply to the particular object, or if the OID does not
+ identify a valid object.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">pg_indexam_has_property</code> ( <em class="parameter"><code>am</code></em> <code class="type">oid</code>, <em class="parameter"><code>property</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether an index access method has the named property.
+ Access method properties are listed in
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-INDEXAM-PROPS" title="Table 9.74. Index Access Method Properties">Table 9.74</a>.
+ <code class="literal">NULL</code> is returned if the property name is not known
+ or does not apply to the particular object, or if the OID does not
+ identify a valid object.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.24.1.1.1" class="indexterm"></a>
+ <code class="function">pg_options_to_table</code> ( <em class="parameter"><code>options_array</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>option_name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>option_value</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Returns the set of storage options represented by a value from
+ <code class="structname">pg_class</code>.<code class="structfield">reloptions</code> or
+ <code class="structname">pg_attribute</code>.<code class="structfield">attoptions</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.25.1.1.1" class="indexterm"></a>
+ <code class="function">pg_settings_get_flags</code> ( <em class="parameter"><code>guc</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Returns an array of the flags associated with the given GUC, or
+ <code class="literal">NULL</code> if it does not exist. The result is
+ an empty array if the GUC exists but there are no flags to show.
+ Only the most useful flags listed in
+ <a class="xref" href="functions-info.html#FUNCTIONS-PG-SETTINGS-FLAGS" title="Table 9.75. GUC Flags">Table 9.75</a> are exposed.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.26.1.1.1" class="indexterm"></a>
+ <code class="function">pg_tablespace_databases</code> ( <em class="parameter"><code>tablespace</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">setof oid</code>
+ </p>
+ <p>
+ Returns the set of OIDs of databases that have objects stored in the
+ specified tablespace. If this function returns any rows, the
+ tablespace is not empty and cannot be dropped. To identify the specific
+ objects populating the tablespace, you will need to connect to the
+ database(s) identified by <code class="function">pg_tablespace_databases</code>
+ and query their <code class="structname">pg_class</code> catalogs.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.27.1.1.1" class="indexterm"></a>
+ <code class="function">pg_tablespace_location</code> ( <em class="parameter"><code>tablespace</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the file system path that this tablespace is located in.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.28.1.1.1" class="indexterm"></a>
+ <code class="function">pg_typeof</code> ( <code class="type">"any"</code> )
+ → <code class="returnvalue">regtype</code>
+ </p>
+ <p>
+ Returns the OID of the data type of the value that is passed to it.
+ This can be helpful for troubleshooting or dynamically constructing
+ SQL queries. The function is declared as
+ returning <code class="type">regtype</code>, which is an OID alias type (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); this means that it is the same as an
+ OID for comparison purposes but displays as a type name.
+ </p>
+ <p>
+ For example:
+</p><pre class="programlisting">
+SELECT pg_typeof(33);
+ pg_typeof
+-----------
+ integer
+
+SELECT typlen FROM pg_type WHERE oid = pg_typeof(33);
+ typlen
+--------
+ 4
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.29.1.1.1" class="indexterm"></a>
+ <code class="function">COLLATION FOR</code> ( <code class="type">"any"</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the name of the collation of the value that is passed to it.
+ The value is quoted and schema-qualified if necessary. If no
+ collation was derived for the argument expression,
+ then <code class="literal">NULL</code> is returned. If the argument is not of a
+ collatable data type, then an error is raised.
+ </p>
+ <p>
+ For example:
+</p><pre class="programlisting">
+SELECT collation for (description) FROM pg_description LIMIT 1;
+ pg_collation_for
+------------------
+ "default"
+
+SELECT collation for ('foo' COLLATE "de_DE");
+ pg_collation_for
+------------------
+ "de_DE"
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.30.1.1.1" class="indexterm"></a>
+ <code class="function">to_regclass</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regclass</code>
+ </p>
+ <p>
+ Translates a textual relation name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regclass</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.31.1.1.1" class="indexterm"></a>
+ <code class="function">to_regcollation</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regcollation</code>
+ </p>
+ <p>
+ Translates a textual collation name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regcollation</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.32.1.1.1" class="indexterm"></a>
+ <code class="function">to_regnamespace</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regnamespace</code>
+ </p>
+ <p>
+ Translates a textual schema name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regnamespace</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.33.1.1.1" class="indexterm"></a>
+ <code class="function">to_regoper</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regoper</code>
+ </p>
+ <p>
+ Translates a textual operator name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regoper</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found or is ambiguous. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.34.1.1.1" class="indexterm"></a>
+ <code class="function">to_regoperator</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regoperator</code>
+ </p>
+ <p>
+ Translates a textual operator name (with parameter types) to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regoperator</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.35.1.1.1" class="indexterm"></a>
+ <code class="function">to_regproc</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regproc</code>
+ </p>
+ <p>
+ Translates a textual function or procedure name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regproc</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found or is ambiguous. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.36.1.1.1" class="indexterm"></a>
+ <code class="function">to_regprocedure</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regprocedure</code>
+ </p>
+ <p>
+ Translates a textual function or procedure name (with argument types) to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regprocedure</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.37.1.1.1" class="indexterm"></a>
+ <code class="function">to_regrole</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regrole</code>
+ </p>
+ <p>
+ Translates a textual role name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regrole</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.19.2.2.38.1.1.1" class="indexterm"></a>
+ <code class="function">to_regtype</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">regtype</code>
+ </p>
+ <p>
+ Translates a textual type name to its OID. A similar result is
+ obtained by casting the string to type <code class="type">regtype</code> (see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>); however, this function will return
+ <code class="literal">NULL</code> rather than throwing an error if the name is
+ not found. Also unlike the cast, this does not accept
+ a numeric OID as input.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Most of the functions that reconstruct (decompile) database objects
+ have an optional <em class="parameter"><code>pretty</code></em> flag, which
+ if <code class="literal">true</code> causes the result to
+ be <span class="quote">“<span class="quote">pretty-printed</span>”</span>. Pretty-printing suppresses unnecessary
+ parentheses and adds whitespace for legibility.
+ The pretty-printed format is more readable, but the default format
+ is more likely to be interpreted the same way by future versions of
+ <span class="productname">PostgreSQL</span>; so avoid using pretty-printed output
+ for dump purposes. Passing <code class="literal">false</code> for
+ the <em class="parameter"><code>pretty</code></em> parameter yields the same result as
+ omitting the parameter.
+ </p><div class="table" id="FUNCTIONS-INFO-INDEX-COLUMN-PROPS"><p class="title"><strong>Table 9.72. Index Column Properties</strong></p><div class="table-contents"><table class="table" summary="Index Column Properties" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">asc</code></td><td>Does the column sort in ascending order on a forward scan?
+ </td></tr><tr><td><code class="literal">desc</code></td><td>Does the column sort in descending order on a forward scan?
+ </td></tr><tr><td><code class="literal">nulls_first</code></td><td>Does the column sort with nulls first on a forward scan?
+ </td></tr><tr><td><code class="literal">nulls_last</code></td><td>Does the column sort with nulls last on a forward scan?
+ </td></tr><tr><td><code class="literal">orderable</code></td><td>Does the column possess any defined sort ordering?
+ </td></tr><tr><td><code class="literal">distance_orderable</code></td><td>Can the column be scanned in order by a <span class="quote">“<span class="quote">distance</span>”</span>
+ operator, for example <code class="literal">ORDER BY col &lt;-&gt; constant</code> ?
+ </td></tr><tr><td><code class="literal">returnable</code></td><td>Can the column value be returned by an index-only scan?
+ </td></tr><tr><td><code class="literal">search_array</code></td><td>Does the column natively support <code class="literal">col = ANY(array)</code>
+ searches?
+ </td></tr><tr><td><code class="literal">search_nulls</code></td><td>Does the column support <code class="literal">IS NULL</code> and
+ <code class="literal">IS NOT NULL</code> searches?
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-INFO-INDEX-PROPS"><p class="title"><strong>Table 9.73. Index Properties</strong></p><div class="table-contents"><table class="table" summary="Index Properties" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">clusterable</code></td><td>Can the index be used in a <code class="literal">CLUSTER</code> command?
+ </td></tr><tr><td><code class="literal">index_scan</code></td><td>Does the index support plain (non-bitmap) scans?
+ </td></tr><tr><td><code class="literal">bitmap_scan</code></td><td>Does the index support bitmap scans?
+ </td></tr><tr><td><code class="literal">backward_scan</code></td><td>Can the scan direction be changed in mid-scan (to
+ support <code class="literal">FETCH BACKWARD</code> on a cursor without
+ needing materialization)?
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-INFO-INDEXAM-PROPS"><p class="title"><strong>Table 9.74. Index Access Method Properties</strong></p><div class="table-contents"><table class="table" summary="Index Access Method Properties" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">can_order</code></td><td>Does the access method support <code class="literal">ASC</code>,
+ <code class="literal">DESC</code> and related keywords in
+ <code class="literal">CREATE INDEX</code>?
+ </td></tr><tr><td><code class="literal">can_unique</code></td><td>Does the access method support unique indexes?
+ </td></tr><tr><td><code class="literal">can_multi_col</code></td><td>Does the access method support indexes with multiple columns?
+ </td></tr><tr><td><code class="literal">can_exclude</code></td><td>Does the access method support exclusion constraints?
+ </td></tr><tr><td><code class="literal">can_include</code></td><td>Does the access method support the <code class="literal">INCLUDE</code>
+ clause of <code class="literal">CREATE INDEX</code>?
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-PG-SETTINGS-FLAGS"><p class="title"><strong>Table 9.75. GUC Flags</strong></p><div class="table-contents"><table class="table" summary="GUC Flags" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Flag</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">EXPLAIN</code></td><td>Parameters with this flag are included in
+ <code class="command">EXPLAIN (SETTINGS)</code> commands.
+ </td></tr><tr><td><code class="literal">NO_SHOW_ALL</code></td><td>Parameters with this flag are excluded from
+ <code class="command">SHOW ALL</code> commands.
+ </td></tr><tr><td><code class="literal">NO_RESET_ALL</code></td><td>Parameters with this flag are excluded from
+ <code class="command">RESET ALL</code> commands.
+ </td></tr><tr><td><code class="literal">NOT_IN_SAMPLE</code></td><td>Parameters with this flag are not included in
+ <code class="filename">postgresql.conf</code> by default.
+ </td></tr><tr><td><code class="literal">RUNTIME_COMPUTED</code></td><td>Parameters with this flag are runtime-computed ones.
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-info.html#FUNCTIONS-INFO-OBJECT-TABLE" title="Table 9.76. Object Information and Addressing Functions">Table 9.76</a> lists functions related to
+ database object identification and addressing.
+ </p><div class="table" id="FUNCTIONS-INFO-OBJECT-TABLE"><p class="title"><strong>Table 9.76. Object Information and Addressing Functions</strong></p><div class="table-contents"><table class="table" summary="Object Information and Addressing Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.26.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_describe_object</code> ( <em class="parameter"><code>classid</code></em> <code class="type">oid</code>, <em class="parameter"><code>objid</code></em> <code class="type">oid</code>, <em class="parameter"><code>objsubid</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns a textual description of a database object identified by
+ catalog OID, object OID, and sub-object ID (such as a column number
+ within a table; the sub-object ID is zero when referring to a whole
+ object). This description is intended to be human-readable, and might
+ be translated, depending on server configuration. This is especially
+ useful to determine the identity of an object referenced in the
+ <code class="structname">pg_depend</code> catalog. This function returns
+ <code class="literal">NULL</code> values for undefined objects.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.26.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_identify_object</code> ( <em class="parameter"><code>classid</code></em> <code class="type">oid</code>, <em class="parameter"><code>objid</code></em> <code class="type">oid</code>, <em class="parameter"><code>objsubid</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>type</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>schema</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>identity</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Returns a row containing enough information to uniquely identify the
+ database object specified by catalog OID, object OID and sub-object
+ ID.
+ This information is intended to be machine-readable, and is never
+ translated.
+ <em class="parameter"><code>type</code></em> identifies the type of database object;
+ <em class="parameter"><code>schema</code></em> is the schema name that the object
+ belongs in, or <code class="literal">NULL</code> for object types that do not
+ belong to schemas;
+ <em class="parameter"><code>name</code></em> is the name of the object, quoted if
+ necessary, if the name (along with schema name, if pertinent) is
+ sufficient to uniquely identify the object,
+ otherwise <code class="literal">NULL</code>;
+ <em class="parameter"><code>identity</code></em> is the complete object identity, with
+ the precise format depending on object type, and each name within the
+ format being schema-qualified and quoted as necessary. Undefined
+ objects are identified with <code class="literal">NULL</code> values.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.26.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_identify_object_as_address</code> ( <em class="parameter"><code>classid</code></em> <code class="type">oid</code>, <em class="parameter"><code>objid</code></em> <code class="type">oid</code>, <em class="parameter"><code>objsubid</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>type</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>object_names</code></em> <code class="type">text[]</code>,
+ <em class="parameter"><code>object_args</code></em> <code class="type">text[]</code> )
+ </p>
+ <p>
+ Returns a row containing enough information to uniquely identify the
+ database object specified by catalog OID, object OID and sub-object
+ ID.
+ The returned information is independent of the current server, that
+ is, it could be used to identify an identically named object in
+ another server.
+ <em class="parameter"><code>type</code></em> identifies the type of database object;
+ <em class="parameter"><code>object_names</code></em> and
+ <em class="parameter"><code>object_args</code></em>
+ are text arrays that together form a reference to the object.
+ These three values can be passed
+ to <code class="function">pg_get_object_address</code> to obtain the internal
+ address of the object.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.26.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_get_object_address</code> ( <em class="parameter"><code>type</code></em> <code class="type">text</code>, <em class="parameter"><code>object_names</code></em> <code class="type">text[]</code>, <em class="parameter"><code>object_args</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>classid</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>objid</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>objsubid</code></em> <code class="type">integer</code> )
+ </p>
+ <p>
+ Returns a row containing enough information to uniquely identify the
+ database object specified by a type code and object name and argument
+ arrays.
+ The returned values are the ones that would be used in system catalogs
+ such as <code class="structname">pg_depend</code>; they can be passed to
+ other system functions such as <code class="function">pg_describe_object</code>
+ or <code class="function">pg_identify_object</code>.
+ <em class="parameter"><code>classid</code></em> is the OID of the system catalog
+ containing the object;
+ <em class="parameter"><code>objid</code></em> is the OID of the object itself, and
+ <em class="parameter"><code>objsubid</code></em> is the sub-object ID, or zero if none.
+ This function is the inverse
+ of <code class="function">pg_identify_object_as_address</code>.
+ Undefined objects are identified with <code class="literal">NULL</code> values.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><a id="id-1.5.8.32.27" class="indexterm"></a><p>
+ The functions shown in <a class="xref" href="functions-info.html#FUNCTIONS-INFO-COMMENT-TABLE" title="Table 9.77. Comment Information Functions">Table 9.77</a>
+ extract comments previously stored with the <a class="xref" href="sql-comment.html" title="COMMENT"><span class="refentrytitle">COMMENT</span></a>
+ command. A null value is returned if no
+ comment could be found for the specified parameters.
+ </p><div class="table" id="FUNCTIONS-INFO-COMMENT-TABLE"><p class="title"><strong>Table 9.77. Comment Information Functions</strong></p><div class="table-contents"><table class="table" summary="Comment Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.29.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">col_description</code> ( <em class="parameter"><code>table</code></em> <code class="type">oid</code>, <em class="parameter"><code>column</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the comment for a table column, which is specified by the OID
+ of its table and its column number.
+ (<code class="function">obj_description</code> cannot be used for table
+ columns, since columns do not have OIDs of their own.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.29.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">obj_description</code> ( <em class="parameter"><code>object</code></em> <code class="type">oid</code>, <em class="parameter"><code>catalog</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the comment for a database object specified by its OID and the
+ name of the containing system catalog. For
+ example, <code class="literal">obj_description(123456, 'pg_class')</code> would
+ retrieve the comment for the table with OID 123456.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">obj_description</code> ( <em class="parameter"><code>object</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the comment for a database object specified by its OID alone.
+ This is <span class="emphasis"><em>deprecated</em></span> since there is no guarantee
+ that OIDs are unique across different system catalogs; therefore, the
+ wrong comment might be returned.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.29.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">shobj_description</code> ( <em class="parameter"><code>object</code></em> <code class="type">oid</code>, <em class="parameter"><code>catalog</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the comment for a shared database object specified by its OID
+ and the name of the containing system catalog. This is just
+ like <code class="function">obj_description</code> except that it is used for
+ retrieving comments on shared objects (that is, databases, roles, and
+ tablespaces). Some system catalogs are global to all databases within
+ each cluster, and the descriptions for objects in them are stored
+ globally as well.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The functions shown in <a class="xref" href="functions-info.html#FUNCTIONS-PG-SNAPSHOT" title="Table 9.78. Transaction ID and Snapshot Information Functions">Table 9.78</a>
+ provide server transaction information in an exportable form. The main
+ use of these functions is to determine which transactions were committed
+ between two snapshots.
+ </p><div class="table" id="FUNCTIONS-PG-SNAPSHOT"><p class="title"><strong>Table 9.78. Transaction ID and Snapshot Information Functions</strong></p><div class="table-contents"><table class="table" summary="Transaction ID and Snapshot Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_current_xact_id</code> ()
+ → <code class="returnvalue">xid8</code>
+ </p>
+ <p>
+ Returns the current transaction's ID. It will assign a new one if the
+ current transaction does not have one already (because it has not
+ performed any database updates).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_current_xact_id_if_assigned</code> ()
+ → <code class="returnvalue">xid8</code>
+ </p>
+ <p>
+ Returns the current transaction's ID, or <code class="literal">NULL</code> if no
+ ID is assigned yet. (It's best to use this variant if the transaction
+ might otherwise be read-only, to avoid unnecessary consumption of an
+ XID.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_xact_status</code> ( <code class="type">xid8</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reports the commit status of a recent transaction.
+ The result is one of <code class="literal">in progress</code>,
+ <code class="literal">committed</code>, or <code class="literal">aborted</code>,
+ provided that the transaction is recent enough that the system retains
+ the commit status of that transaction.
+ If it is old enough that no references to the transaction survive in
+ the system and the commit status information has been discarded, the
+ result is <code class="literal">NULL</code>.
+ Applications might use this function, for example, to determine
+ whether their transaction committed or aborted after the application
+ and database server become disconnected while
+ a <code class="literal">COMMIT</code> is in progress.
+ Note that prepared transactions are reported as <code class="literal">in
+ progress</code>; applications must check <a class="link" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts"><code class="structname">pg_prepared_xacts</code></a>
+ if they need to determine whether a transaction ID belongs to a
+ prepared transaction.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_current_snapshot</code> ()
+ → <code class="returnvalue">pg_snapshot</code>
+ </p>
+ <p>
+ Returns a current <em class="firstterm">snapshot</em>, a data structure
+ showing which transaction IDs are now in-progress.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_snapshot_xip</code> ( <code class="type">pg_snapshot</code> )
+ → <code class="returnvalue">setof xid8</code>
+ </p>
+ <p>
+ Returns the set of in-progress transaction IDs contained in a snapshot.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_snapshot_xmax</code> ( <code class="type">pg_snapshot</code> )
+ → <code class="returnvalue">xid8</code>
+ </p>
+ <p>
+ Returns the <code class="structfield">xmax</code> of a snapshot.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_snapshot_xmin</code> ( <code class="type">pg_snapshot</code> )
+ → <code class="returnvalue">xid8</code>
+ </p>
+ <p>
+ Returns the <code class="structfield">xmin</code> of a snapshot.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.31.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_visible_in_snapshot</code> ( <code class="type">xid8</code>, <code class="type">pg_snapshot</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the given transaction ID <em class="firstterm">visible</em> according
+ to this snapshot (that is, was it completed before the snapshot was
+ taken)? Note that this function will not give the correct answer for
+ a subtransaction ID.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The internal transaction ID type <code class="type">xid</code> is 32 bits wide and
+ wraps around every 4 billion transactions. However,
+ the functions shown in <a class="xref" href="functions-info.html#FUNCTIONS-PG-SNAPSHOT" title="Table 9.78. Transaction ID and Snapshot Information Functions">Table 9.78</a> use a
+ 64-bit type <code class="type">xid8</code> that does not wrap around during the life
+ of an installation, and can be converted to <code class="type">xid</code> by casting if
+ required. The data type <code class="type">pg_snapshot</code> stores information about
+ transaction ID visibility at a particular moment in time. Its components
+ are described in <a class="xref" href="functions-info.html#FUNCTIONS-PG-SNAPSHOT-PARTS" title="Table 9.79. Snapshot Components">Table 9.79</a>.
+ <code class="type">pg_snapshot</code>'s textual representation is
+ <code class="literal"><em class="replaceable"><code>xmin</code></em>:<em class="replaceable"><code>xmax</code></em>:<em class="replaceable"><code>xip_list</code></em></code>.
+ For example <code class="literal">10:20:10,14,15</code> means
+ <code class="literal">xmin=10, xmax=20, xip_list=10, 14, 15</code>.
+ </p><div class="table" id="FUNCTIONS-PG-SNAPSHOT-PARTS"><p class="title"><strong>Table 9.79. Snapshot Components</strong></p><div class="table-contents"><table class="table" summary="Snapshot Components" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">xmin</code></td><td>
+ Lowest transaction ID that was still active. All transaction IDs
+ less than <code class="structfield">xmin</code> are either committed and visible,
+ or rolled back and dead.
+ </td></tr><tr><td><code class="structfield">xmax</code></td><td>
+ One past the highest completed transaction ID. All transaction IDs
+ greater than or equal to <code class="structfield">xmax</code> had not yet
+ completed as of the time of the snapshot, and thus are invisible.
+ </td></tr><tr><td><code class="structfield">xip_list</code></td><td>
+ Transactions in progress at the time of the snapshot. A transaction
+ ID that is <code class="literal">xmin &lt;= <em class="replaceable"><code>X</code></em> &lt;
+ xmax</code> and not in this list was already completed at the time
+ of the snapshot, and thus is either visible or dead according to its
+ commit status. This list does not include the transaction IDs of
+ subtransactions.
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In releases of <span class="productname">PostgreSQL</span> before 13 there was
+ no <code class="type">xid8</code> type, so variants of these functions were provided
+ that used <code class="type">bigint</code> to represent a 64-bit XID, with a
+ correspondingly distinct snapshot data type <code class="type">txid_snapshot</code>.
+ These older functions have <code class="literal">txid</code> in their names. They
+ are still supported for backward compatibility, but may be removed from a
+ future release. See <a class="xref" href="functions-info.html#FUNCTIONS-TXID-SNAPSHOT" title="Table 9.80. Deprecated Transaction ID and Snapshot Information Functions">Table 9.80</a>.
+ </p><div class="table" id="FUNCTIONS-TXID-SNAPSHOT"><p class="title"><strong>Table 9.80. Deprecated Transaction ID and Snapshot Information Functions</strong></p><div class="table-contents"><table class="table" summary="Deprecated Transaction ID and Snapshot Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">txid_current</code> ()
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ See <code class="function">pg_current_xact_id()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">txid_current_if_assigned</code> ()
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ See <code class="function">pg_current_xact_id_if_assigned()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">txid_current_snapshot</code> ()
+ → <code class="returnvalue">txid_snapshot</code>
+ </p>
+ <p>
+ See <code class="function">pg_current_snapshot()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">txid_snapshot_xip</code> ( <code class="type">txid_snapshot</code> )
+ → <code class="returnvalue">setof bigint</code>
+ </p>
+ <p>
+ See <code class="function">pg_snapshot_xip()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">txid_snapshot_xmax</code> ( <code class="type">txid_snapshot</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ See <code class="function">pg_snapshot_xmax()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">txid_snapshot_xmin</code> ( <code class="type">txid_snapshot</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ See <code class="function">pg_snapshot_xmin()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">txid_visible_in_snapshot</code> ( <code class="type">bigint</code>, <code class="type">txid_snapshot</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ See <code class="function">pg_visible_in_snapshot()</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.35.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">txid_status</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ See <code class="function">pg_xact_status()</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The functions shown in <a class="xref" href="functions-info.html#FUNCTIONS-COMMIT-TIMESTAMP" title="Table 9.81. Committed Transaction Information Functions">Table 9.81</a>
+ provide information about when past transactions were committed.
+ They only provide useful data when the
+ <a class="xref" href="runtime-config-replication.html#GUC-TRACK-COMMIT-TIMESTAMP">track_commit_timestamp</a> configuration option is
+ enabled, and only for transactions that were committed after it was
+ enabled.
+ </p><div class="table" id="FUNCTIONS-COMMIT-TIMESTAMP"><p class="title"><strong>Table 9.81. Committed Transaction Information Functions</strong></p><div class="table-contents"><table class="table" summary="Committed Transaction Information Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.37.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_xact_commit_timestamp</code> ( <code class="type">xid</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the commit timestamp of a transaction.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.37.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_xact_commit_timestamp_origin</code> ( <code class="type">xid</code> )
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>timestamp</code></em> <code class="type">timestamp with time zone</code>,
+ <em class="parameter"><code>roident</code></em> <code class="type">oid</code>)
+ </p>
+ <p>
+ Returns the commit timestamp and replication origin of a transaction.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.37.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_last_committed_xact</code> ()
+ → <code class="returnvalue">record</code>
+ ( <em class="parameter"><code>xid</code></em> <code class="type">xid</code>,
+ <em class="parameter"><code>timestamp</code></em> <code class="type">timestamp with time zone</code>,
+ <em class="parameter"><code>roident</code></em> <code class="type">oid</code> )
+ </p>
+ <p>
+ Returns the transaction ID, commit timestamp and replication origin
+ of the latest committed transaction.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The functions shown in <a class="xref" href="functions-info.html#FUNCTIONS-CONTROLDATA" title="Table 9.82. Control Data Functions">Table 9.82</a>
+ print information initialized during <code class="command">initdb</code>, such
+ as the catalog version. They also show information about write-ahead
+ logging and checkpoint processing. This information is cluster-wide,
+ not specific to any one database. These functions provide most of the same
+ information, from the same source, as the
+ <a class="xref" href="app-pgcontroldata.html" title="pg_controldata"><span class="refentrytitle"><span class="application">pg_controldata</span></span></a> application.
+ </p><div class="table" id="FUNCTIONS-CONTROLDATA"><p class="title"><strong>Table 9.82. Control Data Functions</strong></p><div class="table-contents"><table class="table" summary="Control Data Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.39.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_control_checkpoint</code> ()
+ → <code class="returnvalue">record</code>
+ </p>
+ <p>
+ Returns information about current checkpoint state, as shown in
+ <a class="xref" href="functions-info.html#FUNCTIONS-PG-CONTROL-CHECKPOINT" title="Table 9.83. pg_control_checkpoint Output Columns">Table 9.83</a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.39.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_control_system</code> ()
+ → <code class="returnvalue">record</code>
+ </p>
+ <p>
+ Returns information about current control file state, as shown in
+ <a class="xref" href="functions-info.html#FUNCTIONS-PG-CONTROL-SYSTEM" title="Table 9.84. pg_control_system Output Columns">Table 9.84</a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.39.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_control_init</code> ()
+ → <code class="returnvalue">record</code>
+ </p>
+ <p>
+ Returns information about cluster initialization state, as shown in
+ <a class="xref" href="functions-info.html#FUNCTIONS-PG-CONTROL-INIT" title="Table 9.85. pg_control_init Output Columns">Table 9.85</a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.32.39.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_control_recovery</code> ()
+ → <code class="returnvalue">record</code>
+ </p>
+ <p>
+ Returns information about recovery state, as shown in
+ <a class="xref" href="functions-info.html#FUNCTIONS-PG-CONTROL-RECOVERY" title="Table 9.86. pg_control_recovery Output Columns">Table 9.86</a>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-PG-CONTROL-CHECKPOINT"><p class="title"><strong>Table 9.83. <code class="function">pg_control_checkpoint</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pg_control_checkpoint Output Columns" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Column Name</th><th>Data Type</th></tr></thead><tbody><tr><td><code class="structfield">checkpoint_lsn</code></td><td><code class="type">pg_lsn</code></td></tr><tr><td><code class="structfield">redo_lsn</code></td><td><code class="type">pg_lsn</code></td></tr><tr><td><code class="structfield">redo_wal_file</code></td><td><code class="type">text</code></td></tr><tr><td><code class="structfield">timeline_id</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">prev_timeline_id</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">full_page_writes</code></td><td><code class="type">boolean</code></td></tr><tr><td><code class="structfield">next_xid</code></td><td><code class="type">text</code></td></tr><tr><td><code class="structfield">next_oid</code></td><td><code class="type">oid</code></td></tr><tr><td><code class="structfield">next_multixact_id</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">next_multi_offset</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">oldest_xid</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">oldest_xid_dbid</code></td><td><code class="type">oid</code></td></tr><tr><td><code class="structfield">oldest_active_xid</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">oldest_multi_xid</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">oldest_multi_dbid</code></td><td><code class="type">oid</code></td></tr><tr><td><code class="structfield">oldest_commit_ts_xid</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">newest_commit_ts_xid</code></td><td><code class="type">xid</code></td></tr><tr><td><code class="structfield">checkpoint_time</code></td><td><code class="type">timestamp with time zone</code></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-PG-CONTROL-SYSTEM"><p class="title"><strong>Table 9.84. <code class="function">pg_control_system</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pg_control_system Output Columns" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Column Name</th><th>Data Type</th></tr></thead><tbody><tr><td><code class="structfield">pg_control_version</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">catalog_version_no</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">system_identifier</code></td><td><code class="type">bigint</code></td></tr><tr><td><code class="structfield">pg_control_last_modified</code></td><td><code class="type">timestamp with time zone</code></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-PG-CONTROL-INIT"><p class="title"><strong>Table 9.85. <code class="function">pg_control_init</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pg_control_init Output Columns" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Column Name</th><th>Data Type</th></tr></thead><tbody><tr><td><code class="structfield">max_data_alignment</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">database_block_size</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">blocks_per_segment</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">wal_block_size</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">bytes_per_wal_segment</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">max_identifier_length</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">max_index_columns</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">max_toast_chunk_size</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">large_object_chunk_size</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">float8_pass_by_value</code></td><td><code class="type">boolean</code></td></tr><tr><td><code class="structfield">data_page_checksum_version</code></td><td><code class="type">integer</code></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="FUNCTIONS-PG-CONTROL-RECOVERY"><p class="title"><strong>Table 9.86. <code class="function">pg_control_recovery</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pg_control_recovery Output Columns" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Column Name</th><th>Data Type</th></tr></thead><tbody><tr><td><code class="structfield">min_recovery_end_lsn</code></td><td><code class="type">pg_lsn</code></td></tr><tr><td><code class="structfield">min_recovery_end_timeline</code></td><td><code class="type">integer</code></td></tr><tr><td><code class="structfield">backup_start_lsn</code></td><td><code class="type">pg_lsn</code></td></tr><tr><td><code class="structfield">backup_end_lsn</code></td><td><code class="type">pg_lsn</code></td></tr><tr><td><code class="structfield">end_of_backup_record_required</code></td><td><code class="type">boolean</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-srf.html" title="9.25. Set Returning Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-admin.html" title="9.27. System Administration Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.25. Set Returning Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.27. System Administration Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-json.html b/doc/src/sgml/html/functions-json.html
new file mode 100644
index 0000000..eff9140
--- /dev/null
+++ b/doc/src/sgml/html/functions-json.html
@@ -0,0 +1,1781 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.16. JSON Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-xml.html" title="9.15. XML Functions" /><link rel="next" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.16. JSON Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-xml.html" title="9.15. XML Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-JSON"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.16. JSON Functions and Operators</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-json.html#FUNCTIONS-JSON-PROCESSING">9.16.1. Processing and Creating JSON Data</a></span></dt><dt><span class="sect2"><a href="functions-json.html#FUNCTIONS-SQLJSON-PATH">9.16.2. The SQL/JSON Path Language</a></span></dt></dl></div><a id="id-1.5.8.22.2" class="indexterm"></a><p>
+ This section describes:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ functions and operators for processing and creating JSON data
+ </p></li><li class="listitem"><p>
+ the SQL/JSON path language
+ </p></li></ul></div><p>
+ </p><p>
+ To learn more about the SQL/JSON standard, see
+ <a class="xref" href="biblio.html#SQLTR-19075-6" title="SQL Technical Report">[sqltr-19075-6]</a>. For details on JSON types
+ supported in <span class="productname">PostgreSQL</span>,
+ see <a class="xref" href="datatype-json.html" title="8.14. JSON Types">Section 8.14</a>.
+ </p><div class="sect2" id="FUNCTIONS-JSON-PROCESSING"><div class="titlepage"><div><div><h3 class="title">9.16.1. Processing and Creating JSON Data</h3></div></div></div><p>
+ <a class="xref" href="functions-json.html#FUNCTIONS-JSON-OP-TABLE" title="Table 9.45. json and jsonb Operators">Table 9.45</a> shows the operators that
+ are available for use with JSON data types (see <a class="xref" href="datatype-json.html" title="8.14. JSON Types">Section 8.14</a>).
+ In addition, the usual comparison operators shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are available for
+ <code class="type">jsonb</code>, though not for <code class="type">json</code>. The comparison
+ operators follow the ordering rules for B-tree operations outlined in
+ <a class="xref" href="datatype-json.html#JSON-INDEXING" title="8.14.4. jsonb Indexing">Section 8.14.4</a>.
+ See also <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a> for the aggregate
+ function <code class="function">json_agg</code> which aggregates record
+ values as JSON, the aggregate function
+ <code class="function">json_object_agg</code> which aggregates pairs of values
+ into a JSON object, and their <code class="type">jsonb</code> equivalents,
+ <code class="function">jsonb_agg</code> and <code class="function">jsonb_object_agg</code>.
+ </p><div class="table" id="FUNCTIONS-JSON-OP-TABLE"><p class="title"><strong>Table 9.45. <code class="type">json</code> and <code class="type">jsonb</code> Operators</strong></p><div class="table-contents"><table class="table" summary="json and jsonb Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">json</code> <code class="literal">-&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Extracts <em class="parameter"><code>n</code></em>'th element of JSON array
+ (array elements are indexed from zero, but negative integers count
+ from the end).
+ </p>
+ <p>
+ <code class="literal">'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -&gt; 2</code>
+ → <code class="returnvalue">{"c":"baz"}</code>
+ </p>
+ <p>
+ <code class="literal">'[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json -&gt; -3</code>
+ → <code class="returnvalue">{"a":"foo"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">json</code> <code class="literal">-&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Extracts JSON object field with the given key.
+ </p>
+ <p>
+ <code class="literal">'{"a": {"b":"foo"}}'::json -&gt; 'a'</code>
+ → <code class="returnvalue">{"b":"foo"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">json</code> <code class="literal">-&gt;&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-&gt;&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts <em class="parameter"><code>n</code></em>'th element of JSON array,
+ as <code class="type">text</code>.
+ </p>
+ <p>
+ <code class="literal">'[1,2,3]'::json -&gt;&gt; 2</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">json</code> <code class="literal">-&gt;&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-&gt;&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts JSON object field with the given key, as <code class="type">text</code>.
+ </p>
+ <p>
+ <code class="literal">'{"a":1,"b":2}'::json -&gt;&gt; 'b'</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">json</code> <code class="literal">#&gt;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">#&gt;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Extracts JSON sub-object at the specified path, where path elements
+ can be either field keys or array indexes.
+ </p>
+ <p>
+ <code class="literal">'{"a": {"b": ["foo","bar"]}}'::json #&gt; '{a,b,1}'</code>
+ → <code class="returnvalue">"bar"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">json</code> <code class="literal">#&gt;&gt;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">#&gt;&gt;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts JSON sub-object at the specified path as <code class="type">text</code>.
+ </p>
+ <p>
+ <code class="literal">'{"a": {"b": ["foo","bar"]}}'::json #&gt;&gt; '{a,b,1}'</code>
+ → <code class="returnvalue">bar</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The field/element/path extraction operators return NULL, rather than
+ failing, if the JSON input does not have the right structure to match
+ the request; for example if no such key or array element exists.
+ </p></div><p>
+ Some further operators exist only for <code class="type">jsonb</code>, as shown
+ in <a class="xref" href="functions-json.html#FUNCTIONS-JSONB-OP-TABLE" title="Table 9.46. Additional jsonb Operators">Table 9.46</a>.
+ <a class="xref" href="datatype-json.html#JSON-INDEXING" title="8.14.4. jsonb Indexing">Section 8.14.4</a>
+ describes how these operators can be used to effectively search indexed
+ <code class="type">jsonb</code> data.
+ </p><div class="table" id="FUNCTIONS-JSONB-OP-TABLE"><p class="title"><strong>Table 9.46. Additional <code class="type">jsonb</code> Operators</strong></p><div class="table-contents"><table class="table" summary="Additional jsonb Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">@&gt;</code> <code class="type">jsonb</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first JSON value contain the second?
+ (See <a class="xref" href="datatype-json.html#JSON-CONTAINMENT" title="8.14.3. jsonb Containment and Existence">Section 8.14.3</a> for details about containment.)
+ </p>
+ <p>
+ <code class="literal">'{"a":1, "b":2}'::jsonb @&gt; '{"b":2}'::jsonb</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">&lt;@</code> <code class="type">jsonb</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first JSON value contained in the second?
+ </p>
+ <p>
+ <code class="literal">'{"b":2}'::jsonb &lt;@ '{"a":1, "b":2}'::jsonb</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">?</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the text string exist as a top-level key or array element within
+ the JSON value?
+ </p>
+ <p>
+ <code class="literal">'{"a":1, "b":2}'::jsonb ? 'b'</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">'["a", "b", "c"]'::jsonb ? 'b'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">?|</code> <code class="type">text[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do any of the strings in the text array exist as top-level keys or
+ array elements?
+ </p>
+ <p>
+ <code class="literal">'{"a":1, "b":2, "c":3}'::jsonb ?| array['b', 'd']</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">?&amp;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do all of the strings in the text array exist as top-level keys or
+ array elements?
+ </p>
+ <p>
+ <code class="literal">'["a", "b", "c"]'::jsonb ?&amp; array['a', 'b']</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">||</code> <code class="type">jsonb</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Concatenates two <code class="type">jsonb</code> values.
+ Concatenating two arrays generates an array containing all the
+ elements of each input. Concatenating two objects generates an
+ object containing the union of their
+ keys, taking the second object's value when there are duplicate keys.
+ All other cases are treated by converting a non-array input into a
+ single-element array, and then proceeding as for two arrays.
+ Does not operate recursively: only the top-level array or object
+ structure is merged.
+ </p>
+ <p>
+ <code class="literal">'["a", "b"]'::jsonb || '["a", "d"]'::jsonb</code>
+ → <code class="returnvalue">["a", "b", "a", "d"]</code>
+ </p>
+ <p>
+ <code class="literal">'{"a": "b"}'::jsonb || '{"c": "d"}'::jsonb</code>
+ → <code class="returnvalue">{"a": "b", "c": "d"}</code>
+ </p>
+ <p>
+ <code class="literal">'[1, 2]'::jsonb || '3'::jsonb</code>
+ → <code class="returnvalue">[1, 2, 3]</code>
+ </p>
+ <p>
+ <code class="literal">'{"a": "b"}'::jsonb || '42'::jsonb</code>
+ → <code class="returnvalue">[{"a": "b"}, 42]</code>
+ </p>
+ <p>
+ To append an array to another array as a single entry, wrap it
+ in an additional layer of array, for example:
+ </p>
+ <p>
+ <code class="literal">'[1, 2]'::jsonb || jsonb_build_array('[3, 4]'::jsonb)</code>
+ → <code class="returnvalue">[1, 2, [3, 4]]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-</code> <code class="type">text</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Deletes a key (and its value) from a JSON object, or matching string
+ value(s) from a JSON array.
+ </p>
+ <p>
+ <code class="literal">'{"a": "b", "c": "d"}'::jsonb - 'a'</code>
+ → <code class="returnvalue">{"c": "d"}</code>
+ </p>
+ <p>
+ <code class="literal">'["a", "b", "c", "b"]'::jsonb - 'b'</code>
+ → <code class="returnvalue">["a", "c"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-</code> <code class="type">text[]</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Deletes all matching keys or array elements from the left operand.
+ </p>
+ <p>
+ <code class="literal">'{"a": "b", "c": "d"}'::jsonb - '{a,c}'::text[]</code>
+ → <code class="returnvalue">{}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">-</code> <code class="type">integer</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Deletes the array element with specified index (negative
+ integers count from the end). Throws an error if JSON value
+ is not an array.
+ </p>
+ <p>
+ <code class="literal">'["a", "b"]'::jsonb - 1 </code>
+ → <code class="returnvalue">["a"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">#-</code> <code class="type">text[]</code>
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Deletes the field or array element at the specified path, where path
+ elements can be either field keys or array indexes.
+ </p>
+ <p>
+ <code class="literal">'["a", {"b":1}]'::jsonb #- '{1,b}'</code>
+ → <code class="returnvalue">["a", {}]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">@?</code> <code class="type">jsonpath</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does JSON path return any item for the specified JSON value?
+ </p>
+ <p>
+ <code class="literal">'{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ &gt; 2)'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">jsonb</code> <code class="literal">@@</code> <code class="type">jsonpath</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns the result of a JSON path predicate check for the
+ specified JSON value. Only the first item of the result is taken into
+ account. If the result is not Boolean, then <code class="literal">NULL</code>
+ is returned.
+ </p>
+ <p>
+ <code class="literal">'{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] &gt; 2'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="type">jsonpath</code> operators <code class="literal">@?</code>
+ and <code class="literal">@@</code> suppress the following errors: missing object
+ field or array element, unexpected JSON item type, datetime and numeric
+ errors. The <code class="type">jsonpath</code>-related functions described below can
+ also be told to suppress these types of errors. This behavior might be
+ helpful when searching JSON document collections of varying structure.
+ </p></div><p>
+ <a class="xref" href="functions-json.html#FUNCTIONS-JSON-CREATION-TABLE" title="Table 9.47. JSON Creation Functions">Table 9.47</a> shows the functions that are
+ available for constructing <code class="type">json</code> and <code class="type">jsonb</code> values.
+ </p><div class="table" id="FUNCTIONS-JSON-CREATION-TABLE"><p class="title"><strong>Table 9.47. JSON Creation Functions</strong></p><div class="table-contents"><table class="table" summary="JSON Creation Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">to_json</code> ( <code class="type">anyelement</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.1.1.2.1" class="indexterm"></a>
+ <code class="function">to_jsonb</code> ( <code class="type">anyelement</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Converts any SQL value to <code class="type">json</code> or <code class="type">jsonb</code>.
+ Arrays and composites are converted recursively to arrays and
+ objects (multidimensional arrays become arrays of arrays in JSON).
+ Otherwise, if there is a cast from the SQL data type
+ to <code class="type">json</code>, the cast function will be used to perform the
+ conversion;<a href="#ftn.id-1.5.8.22.5.9.2.2.1.1.3.4" class="footnote"><sup class="footnote" id="id-1.5.8.22.5.9.2.2.1.1.3.4">[a]</sup></a>
+ otherwise, a scalar JSON value is produced. For any scalar other than
+ a number, a Boolean, or a null value, the text representation will be
+ used, with escaping as necessary to make it a valid JSON string value.
+ </p>
+ <p>
+ <code class="literal">to_json('Fred said "Hi."'::text)</code>
+ → <code class="returnvalue">"Fred said \"Hi.\""</code>
+ </p>
+ <p>
+ <code class="literal">to_jsonb(row(42, 'Fred said "Hi."'::text))</code>
+ → <code class="returnvalue">{"f1": 42, "f2": "Fred said \"Hi.\""}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">array_to_json</code> ( <code class="type">anyarray</code> [<span class="optional">, <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p>
+ Converts an SQL array to a JSON array. The behavior is the same
+ as <code class="function">to_json</code> except that line feeds will be added
+ between top-level array elements if the optional boolean parameter is
+ true.
+ </p>
+ <p>
+ <code class="literal">array_to_json('{{1,5},{99,100}}'::int[])</code>
+ → <code class="returnvalue">[[1,5],[99,100]]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">row_to_json</code> ( <code class="type">record</code> [<span class="optional">, <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p>
+ Converts an SQL composite value to a JSON object. The behavior is the
+ same as <code class="function">to_json</code> except that line feeds will be
+ added between top-level elements if the optional boolean parameter is
+ true.
+ </p>
+ <p>
+ <code class="literal">row_to_json(row(1,'foo'))</code>
+ → <code class="returnvalue">{"f1":1,"f2":"foo"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">json_build_array</code> ( <code class="literal">VARIADIC</code> <code class="type">"any"</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.4.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_build_array</code> ( <code class="literal">VARIADIC</code> <code class="type">"any"</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Builds a possibly-heterogeneously-typed JSON array out of a variadic
+ argument list. Each argument is converted as
+ per <code class="function">to_json</code> or <code class="function">to_jsonb</code>.
+ </p>
+ <p>
+ <code class="literal">json_build_array(1, 2, 'foo', 4, 5)</code>
+ → <code class="returnvalue">[1, 2, "foo", 4, 5]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">json_build_object</code> ( <code class="literal">VARIADIC</code> <code class="type">"any"</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.5.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_build_object</code> ( <code class="literal">VARIADIC</code> <code class="type">"any"</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Builds a JSON object out of a variadic argument list. By convention,
+ the argument list consists of alternating keys and values. Key
+ arguments are coerced to text; value arguments are converted as
+ per <code class="function">to_json</code> or <code class="function">to_jsonb</code>.
+ </p>
+ <p>
+ <code class="literal">json_build_object('foo', 1, 2, row(3,'bar'))</code>
+ → <code class="returnvalue">{"foo" : 1, "2" : {"f1":3,"f2":"bar"}}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">json_object</code> ( <code class="type">text[]</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.9.2.2.6.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_object</code> ( <code class="type">text[]</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Builds a JSON object out of a text array. The array must have either
+ exactly one dimension with an even number of members, in which case
+ they are taken as alternating key/value pairs, or two dimensions
+ such that each inner array has exactly two elements, which
+ are taken as a key/value pair. All values are converted to JSON
+ strings.
+ </p>
+ <p>
+ <code class="literal">json_object('{a, 1, b, "def", c, 3.5}')</code>
+ → <code class="returnvalue">{"a" : "1", "b" : "def", "c" : "3.5"}</code>
+ </p>
+ <p><code class="literal">json_object('{{a, 1}, {b, "def"}, {c, 3.5}}')</code>
+ → <code class="returnvalue">{"a" : "1", "b" : "def", "c" : "3.5"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">json_object</code> ( <em class="parameter"><code>keys</code></em> <code class="type">text[]</code>, <em class="parameter"><code>values</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">jsonb_object</code> ( <em class="parameter"><code>keys</code></em> <code class="type">text[]</code>, <em class="parameter"><code>values</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ This form of <code class="function">json_object</code> takes keys and values
+ pairwise from separate text arrays. Otherwise it is identical to
+ the one-argument form.
+ </p>
+ <p>
+ <code class="literal">json_object('{a,b}', '{1,2}')</code>
+ → <code class="returnvalue">{"a": "1", "b": "2"}</code>
+ </p></td></tr></tbody><tbody class="footnotes"><tr><td colspan="1"><div id="ftn.id-1.5.8.22.5.9.2.2.1.1.3.4" class="footnote"><p><a href="#id-1.5.8.22.5.9.2.2.1.1.3.4" class="para"><sup class="para">[a] </sup></a>
+ For example, the <a class="xref" href="hstore.html" title="F.18. hstore">hstore</a> extension has a cast
+ from <code class="type">hstore</code> to <code class="type">json</code>, so that
+ <code class="type">hstore</code> values converted via the JSON creation functions
+ will be represented as JSON objects, not as primitive string values.
+ </p></div></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-json.html#FUNCTIONS-JSON-PROCESSING-TABLE" title="Table 9.48. JSON Processing Functions">Table 9.48</a> shows the functions that
+ are available for processing <code class="type">json</code> and <code class="type">jsonb</code> values.
+ </p><div class="table" id="FUNCTIONS-JSON-PROCESSING-TABLE"><p class="title"><strong>Table 9.48. JSON Processing Functions</strong></p><div class="table-contents"><table class="table" summary="JSON Processing Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">json_array_elements</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">setof json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.1.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_array_elements</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof jsonb</code>
+ </p>
+ <p>
+ Expands the top-level JSON array into a set of JSON values.
+ </p>
+ <p>
+ <code class="literal">select * from json_array_elements('[1,true, [2,false]]')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ value
+-----------
+ 1
+ true
+ [2,false]
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">json_array_elements_text</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.2.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_array_elements_text</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Expands the top-level JSON array into a set of <code class="type">text</code> values.
+ </p>
+ <p>
+ <code class="literal">select * from json_array_elements_text('["foo", "bar"]')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ value
+-----------
+ foo
+ bar
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">json_array_length</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.3.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_array_length</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of elements in the top-level JSON array.
+ </p>
+ <p>
+ <code class="literal">json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]')</code>
+ → <code class="returnvalue">5</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_array_length('[]')</code>
+ → <code class="returnvalue">0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">json_each</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>key</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>value</code></em> <code class="type">json</code> )
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.4.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_each</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>key</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>value</code></em> <code class="type">jsonb</code> )
+ </p>
+ <p>
+ Expands the top-level JSON object into a set of key/value pairs.
+ </p>
+ <p>
+ <code class="literal">select * from json_each('{"a":"foo", "b":"bar"}')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ key | value
+-----+-------
+ a | "foo"
+ b | "bar"
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">json_each_text</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>key</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>value</code></em> <code class="type">text</code> )
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.5.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_each_text</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>key</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>value</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Expands the top-level JSON object into a set of key/value pairs.
+ The returned <em class="parameter"><code>value</code></em>s will be of
+ type <code class="type">text</code>.
+ </p>
+ <p>
+ <code class="literal">select * from json_each_text('{"a":"foo", "b":"bar"}')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ key | value
+-----+-------
+ a | foo
+ b | bar
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">json_extract_path</code> ( <em class="parameter"><code>from_json</code></em> <code class="type">json</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>path_elems</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.6.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_extract_path</code> ( <em class="parameter"><code>from_json</code></em> <code class="type">jsonb</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>path_elems</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Extracts JSON sub-object at the specified path.
+ (This is functionally equivalent to the <code class="literal">#&gt;</code>
+ operator, but writing the path out as a variadic list can be more
+ convenient in some cases.)
+ </p>
+ <p>
+ <code class="literal">json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')</code>
+ → <code class="returnvalue">"foo"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">json_extract_path_text</code> ( <em class="parameter"><code>from_json</code></em> <code class="type">json</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>path_elems</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.7.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_extract_path_text</code> ( <em class="parameter"><code>from_json</code></em> <code class="type">jsonb</code>, <code class="literal">VARIADIC</code> <em class="parameter"><code>path_elems</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts JSON sub-object at the specified path as <code class="type">text</code>.
+ (This is functionally equivalent to the <code class="literal">#&gt;&gt;</code>
+ operator.)
+ </p>
+ <p>
+ <code class="literal">json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}', 'f4', 'f6')</code>
+ → <code class="returnvalue">foo</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">json_object_keys</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.8.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_object_keys</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Returns the set of keys in the top-level JSON object.
+ </p>
+ <p>
+ <code class="literal">select * from json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ json_object_keys
+------------------
+ f1
+ f2
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">json_populate_record</code> ( <em class="parameter"><code>base</code></em> <code class="type">anyelement</code>, <em class="parameter"><code>from_json</code></em> <code class="type">json</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.9.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_populate_record</code> ( <em class="parameter"><code>base</code></em> <code class="type">anyelement</code>, <em class="parameter"><code>from_json</code></em> <code class="type">jsonb</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Expands the top-level JSON object to a row having the composite type
+ of the <em class="parameter"><code>base</code></em> argument. The JSON object
+ is scanned for fields whose names match column names of the output row
+ type, and their values are inserted into those columns of the output.
+ (Fields that do not correspond to any output column name are ignored.)
+ In typical use, the value of <em class="parameter"><code>base</code></em> is just
+ <code class="literal">NULL</code>, which means that any output columns that do
+ not match any object field will be filled with nulls. However,
+ if <em class="parameter"><code>base</code></em> isn't <code class="literal">NULL</code> then
+ the values it contains will be used for unmatched columns.
+ </p>
+ <p>
+ To convert a JSON value to the SQL type of an output column, the
+ following rules are applied in sequence:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>
+ A JSON null value is converted to an SQL null in all cases.
+ </p></li><li class="listitem"><p>
+ If the output column is of type <code class="type">json</code>
+ or <code class="type">jsonb</code>, the JSON value is just reproduced exactly.
+ </p></li><li class="listitem"><p>
+ If the output column is a composite (row) type, and the JSON value
+ is a JSON object, the fields of the object are converted to columns
+ of the output row type by recursive application of these rules.
+ </p></li><li class="listitem"><p>
+ Likewise, if the output column is an array type and the JSON value
+ is a JSON array, the elements of the JSON array are converted to
+ elements of the output array by recursive application of these
+ rules.
+ </p></li><li class="listitem"><p>
+ Otherwise, if the JSON value is a string, the contents of the
+ string are fed to the input conversion function for the column's
+ data type.
+ </p></li><li class="listitem"><p>
+ Otherwise, the ordinary text representation of the JSON value is
+ fed to the input conversion function for the column's data type.
+ </p></li></ul></div><p>
+ </p>
+ <p>
+ While the example below uses a constant JSON value, typical use would
+ be to reference a <code class="type">json</code> or <code class="type">jsonb</code> column
+ laterally from another table in the query's <code class="literal">FROM</code>
+ clause. Writing <code class="function">json_populate_record</code> in
+ the <code class="literal">FROM</code> clause is good practice, since all of the
+ extracted columns are available for use without duplicate function
+ calls.
+ </p>
+ <p>
+ <code class="literal">create type subrowtype as (d int, e text);</code>
+ <code class="literal">create type myrowtype as (a int, b text[], c subrowtype);</code>
+ </p>
+ <p>
+ <code class="literal">select * from json_populate_record(null::myrowtype,
+ '{"a": 1, "b": ["2", "a b"], "c": {"d": 4, "e": "a b c"}, "x": "foo"}')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ a | b | c
+---+-----------+-------------
+ 1 | {2,"a b"} | (4,"a b c")
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">json_populate_recordset</code> ( <em class="parameter"><code>base</code></em> <code class="type">anyelement</code>, <em class="parameter"><code>from_json</code></em> <code class="type">json</code> )
+ → <code class="returnvalue">setof anyelement</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.10.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_populate_recordset</code> ( <em class="parameter"><code>base</code></em> <code class="type">anyelement</code>, <em class="parameter"><code>from_json</code></em> <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof anyelement</code>
+ </p>
+ <p>
+ Expands the top-level JSON array of objects to a set of rows having
+ the composite type of the <em class="parameter"><code>base</code></em> argument.
+ Each element of the JSON array is processed as described above
+ for <code class="function">json[b]_populate_record</code>.
+ </p>
+ <p>
+ <code class="literal">create type twoints as (a int, b int);</code>
+ </p>
+ <p>
+ <code class="literal">select * from json_populate_recordset(null::twoints, '[{"a":1,"b":2}, {"a":3,"b":4}]')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ a | b
+---+---
+ 1 | 2
+ 3 | 4
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">json_to_record</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">record</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.11.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_to_record</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">record</code>
+ </p>
+ <p>
+ Expands the top-level JSON object to a row having the composite type
+ defined by an <code class="literal">AS</code> clause. (As with all functions
+ returning <code class="type">record</code>, the calling query must explicitly
+ define the structure of the record with an <code class="literal">AS</code>
+ clause.) The output record is filled from fields of the JSON object,
+ in the same way as described above
+ for <code class="function">json[b]_populate_record</code>. Since there is no
+ input record value, unmatched columns are always filled with nulls.
+ </p>
+ <p>
+ <code class="literal">create type myrowtype as (a int, b text);</code>
+ </p>
+ <p>
+ <code class="literal">select * from json_to_record('{"a":1,"b":[1,2,3],"c":[1,2,3],"e":"bar","r": {"a": 123, "b": "a b c"}}') as x(a int, b text, c int[], d text, r myrowtype)</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ a | b | c | d | r
+---+---------+---------+---+---------------
+ 1 | [1,2,3] | {1,2,3} | | (123,"a b c")
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">json_to_recordset</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.12.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_to_recordset</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Expands the top-level JSON array of objects to a set of rows having
+ the composite type defined by an <code class="literal">AS</code> clause. (As
+ with all functions returning <code class="type">record</code>, the calling query
+ must explicitly define the structure of the record with
+ an <code class="literal">AS</code> clause.) Each element of the JSON array is
+ processed as described above
+ for <code class="function">json[b]_populate_record</code>.
+ </p>
+ <p>
+ <code class="literal">select * from json_to_recordset('[{"a":1,"b":"foo"}, {"a":"2","c":"bar"}]') as x(a int, b text)</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ a | b
+---+-----
+ 1 | foo
+ 2 |
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_set</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">text[]</code>, <em class="parameter"><code>new_value</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>create_if_missing</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>target</code></em>
+ with the item designated by <em class="parameter"><code>path</code></em>
+ replaced by <em class="parameter"><code>new_value</code></em>, or with
+ <em class="parameter"><code>new_value</code></em> added if
+ <em class="parameter"><code>create_if_missing</code></em> is true (which is the
+ default) and the item designated by <em class="parameter"><code>path</code></em>
+ does not exist.
+ All earlier steps in the path must exist, or
+ the <em class="parameter"><code>target</code></em> is returned unchanged.
+ As with the path oriented operators, negative integers that
+ appear in the <em class="parameter"><code>path</code></em> count from the end
+ of JSON arrays.
+ If the last path step is an array index that is out of range,
+ and <em class="parameter"><code>create_if_missing</code></em> is true, the new
+ value is added at the beginning of the array if the index is negative,
+ or at the end of the array if it is positive.
+ </p>
+ <p>
+ <code class="literal">jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', '[2,3,4]', false)</code>
+ → <code class="returnvalue">[{"f1": [2, 3, 4], "f2": null}, 2, null, 3]</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_set('[{"f1":1,"f2":null},2]', '{0,f3}', '[2,3,4]')</code>
+ → <code class="returnvalue">[{"f1": 1, "f2": null, "f3": [2, 3, 4]}, 2]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_set_lax</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">text[]</code>, <em class="parameter"><code>new_value</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>create_if_missing</code></em> <code class="type">boolean</code> [<span class="optional">, <em class="parameter"><code>null_value_treatment</code></em> <code class="type">text</code> </span>]</span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ If <em class="parameter"><code>new_value</code></em> is not <code class="literal">NULL</code>,
+ behaves identically to <code class="literal">jsonb_set</code>. Otherwise behaves
+ according to the value
+ of <em class="parameter"><code>null_value_treatment</code></em> which must be one
+ of <code class="literal">'raise_exception'</code>,
+ <code class="literal">'use_json_null'</code>, <code class="literal">'delete_key'</code>, or
+ <code class="literal">'return_target'</code>. The default is
+ <code class="literal">'use_json_null'</code>.
+ </p>
+ <p>
+ <code class="literal">jsonb_set_lax('[{"f1":1,"f2":null},2,null,3]', '{0,f1}', null)</code>
+ → <code class="returnvalue">[{"f1": null, "f2": null}, 2, null, 3]</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_set_lax('[{"f1":99,"f2":null},2]', '{0,f3}', null, true, 'return_target')</code>
+ → <code class="returnvalue">[{"f1": 99, "f2": null}, 2]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_insert</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">text[]</code>, <em class="parameter"><code>new_value</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>insert_after</code></em> <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>target</code></em>
+ with <em class="parameter"><code>new_value</code></em> inserted. If the item
+ designated by the <em class="parameter"><code>path</code></em> is an array
+ element, <em class="parameter"><code>new_value</code></em> will be inserted before
+ that item if <em class="parameter"><code>insert_after</code></em> is false (which
+ is the default), or after it
+ if <em class="parameter"><code>insert_after</code></em> is true. If the item
+ designated by the <em class="parameter"><code>path</code></em> is an object
+ field, <em class="parameter"><code>new_value</code></em> will be inserted only if
+ the object does not already contain that key.
+ All earlier steps in the path must exist, or
+ the <em class="parameter"><code>target</code></em> is returned unchanged.
+ As with the path oriented operators, negative integers that
+ appear in the <em class="parameter"><code>path</code></em> count from the end
+ of JSON arrays.
+ If the last path step is an array index that is out of range, the new
+ value is added at the beginning of the array if the index is negative,
+ or at the end of the array if it is positive.
+ </p>
+ <p>
+ <code class="literal">jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"')</code>
+ → <code class="returnvalue">{"a": [0, "new_value", 1, 2]}</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_insert('{"a": [0,1,2]}', '{a, 1}', '"new_value"', true)</code>
+ → <code class="returnvalue">{"a": [0, 1, "new_value", 2]}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">json_strip_nulls</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.16.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_strip_nulls</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Deletes all object fields that have null values from the given JSON
+ value, recursively. Null values that are not object fields are
+ untouched.
+ </p>
+ <p>
+ <code class="literal">json_strip_nulls('[{"f1":1, "f2":null}, 2, null, 3]')</code>
+ → <code class="returnvalue">[{"f1":1},2,null,3]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_path_exists</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Checks whether the JSON path returns any item for the specified JSON
+ value.
+ If the <em class="parameter"><code>vars</code></em> argument is specified, it must
+ be a JSON object, and its fields provide named values to be
+ substituted into the <code class="type">jsonpath</code> expression.
+ If the <em class="parameter"><code>silent</code></em> argument is specified and
+ is <code class="literal">true</code>, the function suppresses the same errors
+ as the <code class="literal">@?</code> and <code class="literal">@@</code> operators do.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ &gt;= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_path_match</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns the result of a JSON path predicate check for the specified
+ JSON value. Only the first item of the result is taken into account.
+ If the result is not Boolean, then <code class="literal">NULL</code> is returned.
+ The optional <em class="parameter"><code>vars</code></em>
+ and <em class="parameter"><code>silent</code></em> arguments act the same as
+ for <code class="function">jsonb_path_exists</code>.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ &gt;= $min &amp;&amp; @ &lt;= $max))', '{"min":2, "max":4}')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_path_query</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">setof jsonb</code>
+ </p>
+ <p>
+ Returns all JSON items returned by the JSON path for the specified
+ JSON value.
+ The optional <em class="parameter"><code>vars</code></em>
+ and <em class="parameter"><code>silent</code></em> arguments act the same as
+ for <code class="function">jsonb_path_exists</code>.
+ </p>
+ <p>
+ <code class="literal">select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ &gt;= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ jsonb_path_query
+------------------
+ 2
+ 3
+ 4
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.20.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_path_query_array</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Returns all JSON items returned by the JSON path for the specified
+ JSON value, as a JSON array.
+ The optional <em class="parameter"><code>vars</code></em>
+ and <em class="parameter"><code>silent</code></em> arguments act the same as
+ for <code class="function">jsonb_path_exists</code>.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ &gt;= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</code>
+ → <code class="returnvalue">[2, 3, 4]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_path_query_first</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Returns the first JSON item returned by the JSON path for the
+ specified JSON value. Returns <code class="literal">NULL</code> if there are no
+ results.
+ The optional <em class="parameter"><code>vars</code></em>
+ and <em class="parameter"><code>silent</code></em> arguments act the same as
+ for <code class="function">jsonb_path_exists</code>.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ &gt;= $min &amp;&amp; @ &lt;= $max)', '{"min":2, "max":4}')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_path_exists_tz</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.22.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_path_match_tz</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.22.1.3.1" class="indexterm"></a>
+ <code class="function">jsonb_path_query_tz</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">setof jsonb</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.22.1.4.1" class="indexterm"></a>
+ <code class="function">jsonb_path_query_array_tz</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.22.1.5.1" class="indexterm"></a>
+ <code class="function">jsonb_path_query_first_tz</code> ( <em class="parameter"><code>target</code></em> <code class="type">jsonb</code>, <em class="parameter"><code>path</code></em> <code class="type">jsonpath</code> [<span class="optional">, <em class="parameter"><code>vars</code></em> <code class="type">jsonb</code> [<span class="optional">, <em class="parameter"><code>silent</code></em> <code class="type">boolean</code> </span>]</span>] )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ These functions act like their counterparts described above without
+ the <code class="literal">_tz</code> suffix, except that these functions support
+ comparisons of date/time values that require timezone-aware
+ conversions. The example below requires interpretation of the
+ date-only value <code class="literal">2015-08-02</code> as a timestamp with time
+ zone, so the result depends on the current
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> setting. Due to this dependency, these
+ functions are marked as stable, which means these functions cannot be
+ used in indexes. Their counterparts are immutable, and so can be used
+ in indexes; but they will throw errors if asked to make such
+ comparisons.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_exists_tz('["2015-08-01 12:00:00-05"]', '$[*] ? (@.datetime() &lt; "2015-08-02".datetime())')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">jsonb_pretty</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the given JSON value to pretty-printed, indented text.
+ </p>
+ <p>
+ <code class="literal">jsonb_pretty('[{"f1":1,"f2":null}, 2]')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+[
+ {
+ "f1": 1,
+ "f2": null
+ },
+ 2
+]
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.24.1.1.1" class="indexterm"></a>
+ <code class="function">json_typeof</code> ( <code class="type">json</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.22.5.11.2.2.24.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_typeof</code> ( <code class="type">jsonb</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the type of the top-level JSON value as a text string.
+ Possible types are
+ <code class="literal">object</code>, <code class="literal">array</code>,
+ <code class="literal">string</code>, <code class="literal">number</code>,
+ <code class="literal">boolean</code>, and <code class="literal">null</code>.
+ (The <code class="literal">null</code> result should not be confused
+ with an SQL NULL; see the examples.)
+ </p>
+ <p>
+ <code class="literal">json_typeof('-123.4')</code>
+ → <code class="returnvalue">number</code>
+ </p>
+ <p>
+ <code class="literal">json_typeof('null'::json)</code>
+ → <code class="returnvalue">null</code>
+ </p>
+ <p>
+ <code class="literal">json_typeof(NULL::json) IS NULL</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="FUNCTIONS-SQLJSON-PATH"><div class="titlepage"><div><div><h3 class="title">9.16.2. The SQL/JSON Path Language</h3></div></div></div><a id="id-1.5.8.22.6.2" class="indexterm"></a><p>
+ SQL/JSON path expressions specify the items to be retrieved
+ from the JSON data, similar to XPath expressions used
+ for SQL access to XML. In <span class="productname">PostgreSQL</span>,
+ path expressions are implemented as the <code class="type">jsonpath</code>
+ data type and can use any elements described in
+ <a class="xref" href="datatype-json.html#DATATYPE-JSONPATH" title="8.14.7. jsonpath Type">Section 8.14.7</a>.
+ </p><p>
+ JSON query functions and operators
+ pass the provided path expression to the <em class="firstterm">path engine</em>
+ for evaluation. If the expression matches the queried JSON data,
+ the corresponding JSON item, or set of items, is returned.
+ Path expressions are written in the SQL/JSON path language
+ and can include arithmetic expressions and functions.
+ </p><p>
+ A path expression consists of a sequence of elements allowed
+ by the <code class="type">jsonpath</code> data type.
+ The path expression is normally evaluated from left to right, but
+ you can use parentheses to change the order of operations.
+ If the evaluation is successful, a sequence of JSON items is produced,
+ and the evaluation result is returned to the JSON query function
+ that completes the specified computation.
+ </p><p>
+ To refer to the JSON value being queried (the
+ <em class="firstterm">context item</em>), use the <code class="literal">$</code> variable
+ in the path expression. It can be followed by one or more
+ <a class="link" href="datatype-json.html#TYPE-JSONPATH-ACCESSORS" title="Table 8.25. jsonpath Accessors">accessor operators</a>,
+ which go down the JSON structure level by level to retrieve sub-items
+ of the context item. Each operator that follows deals with the
+ result of the previous evaluation step.
+ </p><p>
+ For example, suppose you have some JSON data from a GPS tracker that you
+ would like to parse, such as:
+</p><pre class="programlisting">
+{
+ "track": {
+ "segments": [
+ {
+ "location": [ 47.763, 13.4034 ],
+ "start time": "2018-10-14 10:05:14",
+ "HR": 73
+ },
+ {
+ "location": [ 47.706, 13.2635 ],
+ "start time": "2018-10-14 10:39:21",
+ "HR": 135
+ }
+ ]
+ }
+}
+</pre><p>
+ </p><p>
+ To retrieve the available track segments, you need to use the
+ <code class="literal">.<em class="replaceable"><code>key</code></em></code> accessor
+ operator to descend through surrounding JSON objects:
+</p><pre class="programlisting">
+$.track.segments
+</pre><p>
+ </p><p>
+ To retrieve the contents of an array, you typically use the
+ <code class="literal">[*]</code> operator. For example,
+ the following path will return the location coordinates for all
+ the available track segments:
+</p><pre class="programlisting">
+$.track.segments[*].location
+</pre><p>
+ </p><p>
+ To return the coordinates of the first segment only, you can
+ specify the corresponding subscript in the <code class="literal">[]</code>
+ accessor operator. Recall that JSON array indexes are 0-relative:
+</p><pre class="programlisting">
+$.track.segments[0].location
+</pre><p>
+ </p><p>
+ The result of each path evaluation step can be processed
+ by one or more <code class="type">jsonpath</code> operators and methods
+ listed in <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-PATH-OPERATORS" title="9.16.2.2. SQL/JSON Path Operators and Methods">Section 9.16.2.2</a>.
+ Each method name must be preceded by a dot. For example,
+ you can get the size of an array:
+</p><pre class="programlisting">
+$.track.segments.size()
+</pre><p>
+ More examples of using <code class="type">jsonpath</code> operators
+ and methods within path expressions appear below in
+ <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-PATH-OPERATORS" title="9.16.2.2. SQL/JSON Path Operators and Methods">Section 9.16.2.2</a>.
+ </p><p>
+ When defining a path, you can also use one or more
+ <em class="firstterm">filter expressions</em> that work similarly to the
+ <code class="literal">WHERE</code> clause in SQL. A filter expression begins with
+ a question mark and provides a condition in parentheses:
+
+</p><pre class="programlisting">
+? (<em class="replaceable"><code>condition</code></em>)
+</pre><p>
+ </p><p>
+ Filter expressions must be written just after the path evaluation step
+ to which they should apply. The result of that step is filtered to include
+ only those items that satisfy the provided condition. SQL/JSON defines
+ three-valued logic, so the condition can be <code class="literal">true</code>, <code class="literal">false</code>,
+ or <code class="literal">unknown</code>. The <code class="literal">unknown</code> value
+ plays the same role as SQL <code class="literal">NULL</code> and can be tested
+ for with the <code class="literal">is unknown</code> predicate. Further path
+ evaluation steps use only those items for which the filter expression
+ returned <code class="literal">true</code>.
+ </p><p>
+ The functions and operators that can be used in filter expressions are
+ listed in <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-FILTER-EX-TABLE" title="Table 9.50. jsonpath Filter Expression Elements">Table 9.50</a>. Within a
+ filter expression, the <code class="literal">@</code> variable denotes the value
+ being filtered (i.e., one result of the preceding path step). You can
+ write accessor operators after <code class="literal">@</code> to retrieve component
+ items.
+ </p><p>
+ For example, suppose you would like to retrieve all heart rate values higher
+ than 130. You can achieve this using the following expression:
+</p><pre class="programlisting">
+$.track.segments[*].HR ? (@ &gt; 130)
+</pre><p>
+ </p><p>
+ To get the start times of segments with such values, you have to
+ filter out irrelevant segments before returning the start times, so the
+ filter expression is applied to the previous step, and the path used
+ in the condition is different:
+</p><pre class="programlisting">
+$.track.segments[*] ? (@.HR &gt; 130)."start time"
+</pre><p>
+ </p><p>
+ You can use several filter expressions in sequence, if required. For
+ example, the following expression selects start times of all segments that
+ contain locations with relevant coordinates and high heart rate values:
+</p><pre class="programlisting">
+$.track.segments[*] ? (@.location[1] &lt; 13.4) ? (@.HR &gt; 130)."start time"
+</pre><p>
+ </p><p>
+ Using filter expressions at different nesting levels is also allowed.
+ The following example first filters all segments by location, and then
+ returns high heart rate values for these segments, if available:
+</p><pre class="programlisting">
+$.track.segments[*] ? (@.location[1] &lt; 13.4).HR ? (@ &gt; 130)
+</pre><p>
+ </p><p>
+ You can also nest filter expressions within each other:
+</p><pre class="programlisting">
+$.track ? (exists(@.segments[*] ? (@.HR &gt; 130))).segments.size()
+</pre><p>
+ This expression returns the size of the track if it contains any
+ segments with high heart rate values, or an empty sequence otherwise.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s implementation of the SQL/JSON path
+ language has the following deviations from the SQL/JSON standard:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A path expression can be a Boolean predicate, although the SQL/JSON
+ standard allows predicates only in filters. This is necessary for
+ implementation of the <code class="literal">@@</code> operator. For example,
+ the following <code class="type">jsonpath</code> expression is valid in
+ <span class="productname">PostgreSQL</span>:
+</p><pre class="programlisting">
+$.track.segments[*].HR &lt; 70
+</pre><p>
+ </p></li><li class="listitem"><p>
+ There are minor differences in the interpretation of regular
+ expression patterns used in <code class="literal">like_regex</code> filters, as
+ described in <a class="xref" href="functions-json.html#JSONPATH-REGULAR-EXPRESSIONS" title="9.16.2.3. SQL/JSON Regular Expressions">Section 9.16.2.3</a>.
+ </p></li></ul></div><div class="sect3" id="STRICT-AND-LAX-MODES"><div class="titlepage"><div><div><h4 class="title">9.16.2.1. Strict and Lax Modes</h4></div></div></div><p>
+ When you query JSON data, the path expression may not match the
+ actual JSON data structure. An attempt to access a non-existent
+ member of an object or element of an array results in a
+ structural error. SQL/JSON path expressions have two modes
+ of handling structural errors:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ lax (default) — the path engine implicitly adapts
+ the queried data to the specified path.
+ Any remaining structural errors are suppressed and converted
+ to empty SQL/JSON sequences.
+ </p></li><li class="listitem"><p>
+ strict — if a structural error occurs, an error is raised.
+ </p></li></ul></div><p>
+ The lax mode facilitates matching of a JSON document structure and path
+ expression if the JSON data does not conform to the expected schema.
+ If an operand does not match the requirements of a particular operation,
+ it can be automatically wrapped as an SQL/JSON array or unwrapped by
+ converting its elements into an SQL/JSON sequence before performing
+ this operation. Besides, comparison operators automatically unwrap their
+ operands in the lax mode, so you can compare SQL/JSON arrays
+ out-of-the-box. An array of size 1 is considered equal to its sole element.
+ Automatic unwrapping is not performed only when:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The path expression contains <code class="literal">type()</code> or
+ <code class="literal">size()</code> methods that return the type
+ and the number of elements in the array, respectively.
+ </p></li><li class="listitem"><p>
+ The queried JSON data contain nested arrays. In this case, only
+ the outermost array is unwrapped, while all the inner arrays
+ remain unchanged. Thus, implicit unwrapping can only go one
+ level down within each path evaluation step.
+ </p></li></ul></div><p>
+ </p><p>
+ For example, when querying the GPS data listed above, you can
+ abstract from the fact that it stores an array of segments
+ when using the lax mode:
+</p><pre class="programlisting">
+lax $.track.segments.location
+</pre><p>
+ </p><p>
+ In the strict mode, the specified path must exactly match the structure of
+ the queried JSON document to return an SQL/JSON item, so using this
+ path expression will cause an error. To get the same result as in
+ the lax mode, you have to explicitly unwrap the
+ <code class="literal">segments</code> array:
+</p><pre class="programlisting">
+strict $.track.segments[*].location
+</pre><p>
+ </p><p>
+ The <code class="literal">.**</code> accessor can lead to surprising results
+ when using the lax mode. For instance, the following query selects every
+ <code class="literal">HR</code> value twice:
+</p><pre class="programlisting">
+lax $.**.HR
+</pre><p>
+ This happens because the <code class="literal">.**</code> accessor selects both
+ the <code class="literal">segments</code> array and each of its elements, while
+ the <code class="literal">.HR</code> accessor automatically unwraps arrays when
+ using the lax mode. To avoid surprising results, we recommend using
+ the <code class="literal">.**</code> accessor only in the strict mode. The
+ following query selects each <code class="literal">HR</code> value just once:
+</p><pre class="programlisting">
+strict $.**.HR
+</pre><p>
+ </p></div><div class="sect3" id="FUNCTIONS-SQLJSON-PATH-OPERATORS"><div class="titlepage"><div><div><h4 class="title">9.16.2.2. SQL/JSON Path Operators and Methods</h4></div></div></div><p>
+ <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-OP-TABLE" title="Table 9.49. jsonpath Operators and Methods">Table 9.49</a> shows the operators and
+ methods available in <code class="type">jsonpath</code>. Note that while the unary
+ operators and methods can be applied to multiple values resulting from a
+ preceding path step, the binary operators (addition etc.) can only be
+ applied to single values.
+ </p><div class="table" id="FUNCTIONS-SQLJSON-OP-TABLE"><p class="title"><strong>Table 9.49. <code class="type">jsonpath</code> Operators and Methods</strong></p><div class="table-contents"><table class="table" summary="jsonpath Operators and Methods" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator/Method
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">+</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Addition
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[2]', '$[0] + 3')</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">+</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Unary plus (no operation); unlike addition, this can iterate over
+ multiple values
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('{"x": [2,3,4]}', '+ $.x')</code>
+ → <code class="returnvalue">[2, 3, 4]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">-</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Subtraction
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[2]', '7 - $[0]')</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">-</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Negation; unlike subtraction, this can iterate over
+ multiple values
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('{"x": [2,3,4]}', '- $.x')</code>
+ → <code class="returnvalue">[-2, -3, -4]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">*</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Multiplication
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[4]', '2 * $[0]')</code>
+ → <code class="returnvalue">8</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">/</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Division
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[8.5]', '$[0] / 2')</code>
+ → <code class="returnvalue">4.2500000000000000</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">%</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Modulo (remainder)
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[32]', '$[0] % 10')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">.</code> <code class="literal">type()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>string</code></em></code>
+ </p>
+ <p>
+ Type of the JSON item (see <code class="function">json_typeof</code>)
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, "2", {}]', '$[*].type()')</code>
+ → <code class="returnvalue">["number", "string", "object"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">.</code> <code class="literal">size()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Size of the JSON item (number of array elements, or 1 if not an
+ array)
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('{"m": [11, 15]}', '$.m.size()')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">.</code> <code class="literal">double()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Approximate floating-point number converted from a JSON number or
+ string
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('{"len": "1.9"}', '$.len.double() * 2')</code>
+ → <code class="returnvalue">3.8</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">.</code> <code class="literal">ceiling()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Nearest integer greater than or equal to the given number
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('{"h": 1.3}', '$.h.ceiling()')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">.</code> <code class="literal">floor()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Nearest integer less than or equal to the given number
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('{"h": 1.7}', '$.h.floor()')</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">.</code> <code class="literal">abs()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Absolute value of the given number
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('{"z": -0.3}', '$.z.abs()')</code>
+ → <code class="returnvalue">0.3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>string</code></em> <code class="literal">.</code> <code class="literal">datetime()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>datetime_type</code></em></code>
+ (see note)
+ </p>
+ <p>
+ Date/time value converted from a string
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('["2015-8-1", "2015-08-12"]', '$[*] ? (@.datetime() &lt; "2015-08-2".datetime())')</code>
+ → <code class="returnvalue">"2015-8-1"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>string</code></em> <code class="literal">.</code> <code class="literal">datetime(<em class="replaceable"><code>template</code></em>)</code>
+ → <code class="returnvalue"><em class="replaceable"><code>datetime_type</code></em></code>
+ (see note)
+ </p>
+ <p>
+ Date/time value converted from a string using the
+ specified <code class="function">to_timestamp</code> template
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('["12:30", "18:40"]', '$[*].datetime("HH24:MI")')</code>
+ → <code class="returnvalue">["12:30:00", "18:40:00"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>object</code></em> <code class="literal">.</code> <code class="literal">keyvalue()</code>
+ → <code class="returnvalue"><em class="replaceable"><code>array</code></em></code>
+ </p>
+ <p>
+ The object's key-value pairs, represented as an array of objects
+ containing three fields: <code class="literal">"key"</code>,
+ <code class="literal">"value"</code>, and <code class="literal">"id"</code>;
+ <code class="literal">"id"</code> is a unique identifier of the object the
+ key-value pair belongs to
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('{"x": "20", "y": 32}', '$.keyvalue()')</code>
+ → <code class="returnvalue">[{"id": 0, "key": "x", "value": "20"}, {"id": 0, "key": "y", "value": 32}]</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The result type of the <code class="literal">datetime()</code> and
+ <code class="literal">datetime(<em class="replaceable"><code>template</code></em>)</code>
+ methods can be <code class="type">date</code>, <code class="type">timetz</code>, <code class="type">time</code>,
+ <code class="type">timestamptz</code>, or <code class="type">timestamp</code>.
+ Both methods determine their result type dynamically.
+ </p><p>
+ The <code class="literal">datetime()</code> method sequentially tries to
+ match its input string to the ISO formats
+ for <code class="type">date</code>, <code class="type">timetz</code>, <code class="type">time</code>,
+ <code class="type">timestamptz</code>, and <code class="type">timestamp</code>. It stops on
+ the first matching format and emits the corresponding data type.
+ </p><p>
+ The <code class="literal">datetime(<em class="replaceable"><code>template</code></em>)</code>
+ method determines the result type according to the fields used in the
+ provided template string.
+ </p><p>
+ The <code class="literal">datetime()</code> and
+ <code class="literal">datetime(<em class="replaceable"><code>template</code></em>)</code> methods
+ use the same parsing rules as the <code class="literal">to_timestamp</code> SQL
+ function does (see <a class="xref" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Section 9.8</a>), with three
+ exceptions. First, these methods don't allow unmatched template
+ patterns. Second, only the following separators are allowed in the
+ template string: minus sign, period, solidus (slash), comma, apostrophe,
+ semicolon, colon and space. Third, separators in the template string
+ must exactly match the input string.
+ </p><p>
+ If different date/time types need to be compared, an implicit cast is
+ applied. A <code class="type">date</code> value can be cast to <code class="type">timestamp</code>
+ or <code class="type">timestamptz</code>, <code class="type">timestamp</code> can be cast to
+ <code class="type">timestamptz</code>, and <code class="type">time</code> to <code class="type">timetz</code>.
+ However, all but the first of these conversions depend on the current
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> setting, and thus can only be performed
+ within timezone-aware <code class="type">jsonpath</code> functions.
+ </p></div><p>
+ <a class="xref" href="functions-json.html#FUNCTIONS-SQLJSON-FILTER-EX-TABLE" title="Table 9.50. jsonpath Filter Expression Elements">Table 9.50</a> shows the available
+ filter expression elements.
+ </p><div class="table" id="FUNCTIONS-SQLJSON-FILTER-EX-TABLE"><p class="title"><strong>Table 9.50. <code class="type">jsonpath</code> Filter Expression Elements</strong></p><div class="table-contents"><table class="table" summary="jsonpath Filter Expression Elements" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Predicate/Value
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">==</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Equality comparison (this, and the other comparison operators, work on
+ all JSON scalar values)
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == 1)')</code>
+ → <code class="returnvalue">[1, 1]</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, "a", 1, 3]', '$[*] ? (@ == "a")')</code>
+ → <code class="returnvalue">["a"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">!=</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">&lt;&gt;</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Non-equality comparison
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, 2, 1, 3]', '$[*] ? (@ != 1)')</code>
+ → <code class="returnvalue">[2, 3]</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ &lt;&gt; "b")')</code>
+ → <code class="returnvalue">["a", "c"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">&lt;</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Less-than comparison
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ &lt; 2)')</code>
+ → <code class="returnvalue">[1]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">&lt;=</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Less-than-or-equal-to comparison
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('["a", "b", "c"]', '$[*] ? (@ &lt;= "b")')</code>
+ → <code class="returnvalue">["a", "b"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">&gt;</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Greater-than comparison
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ &gt; 2)')</code>
+ → <code class="returnvalue">[3]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">&gt;=</code> <em class="replaceable"><code>value</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Greater-than-or-equal-to comparison
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('[1, 2, 3]', '$[*] ? (@ &gt;= 2)')</code>
+ → <code class="returnvalue">[2, 3]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">true</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ JSON constant <code class="literal">true</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == true)')</code>
+ → <code class="returnvalue">{"name": "Chris", "parent": true}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">false</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ JSON constant <code class="literal">false</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[{"name": "John", "parent": false}, {"name": "Chris", "parent": true}]', '$[*] ? (@.parent == false)')</code>
+ → <code class="returnvalue">{"name": "John", "parent": false}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">null</code>
+ → <code class="returnvalue"><em class="replaceable"><code>value</code></em></code>
+ </p>
+ <p>
+ JSON constant <code class="literal">null</code> (note that, unlike in SQL,
+ comparison to <code class="literal">null</code> works normally)
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[{"name": "Mary", "job": null}, {"name": "Michael", "job": "driver"}]', '$[*] ? (@.job == null) .name')</code>
+ → <code class="returnvalue">"Mary"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>boolean</code></em> <code class="literal">&amp;&amp;</code> <em class="replaceable"><code>boolean</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Boolean AND
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[1, 3, 7]', '$[*] ? (@ &gt; 1 &amp;&amp; @ &lt; 5)')</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>boolean</code></em> <code class="literal">||</code> <em class="replaceable"><code>boolean</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Boolean OR
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[1, 3, 7]', '$[*] ? (@ &lt; 1 || @ &gt; 5)')</code>
+ → <code class="returnvalue">7</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">!</code> <em class="replaceable"><code>boolean</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Boolean NOT
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[1, 3, 7]', '$[*] ? (!(@ &lt; 5))')</code>
+ → <code class="returnvalue">7</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>boolean</code></em> <code class="literal">is unknown</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether a Boolean condition is <code class="literal">unknown</code>.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('[-1, 2, 7, "foo"]', '$[*] ? ((@ &gt; 0) is unknown)')</code>
+ → <code class="returnvalue">"foo"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>string</code></em> <code class="literal">like_regex</code> <em class="replaceable"><code>string</code></em> [<span class="optional"> <code class="literal">flag</code> <em class="replaceable"><code>string</code></em> </span>]
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether the first operand matches the regular expression
+ given by the second operand, optionally with modifications
+ described by a string of <code class="literal">flag</code> characters (see
+ <a class="xref" href="functions-json.html#JSONPATH-REGULAR-EXPRESSIONS" title="9.16.2.3. SQL/JSON Regular Expressions">Section 9.16.2.3</a>).
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c")')</code>
+ → <code class="returnvalue">["abc", "abdacb"]</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('["abc", "abd", "aBdC", "abdacb", "babc"]', '$[*] ? (@ like_regex "^ab.*c" flag "i")')</code>
+ → <code class="returnvalue">["abc", "aBdC", "abdacb"]</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>string</code></em> <code class="literal">starts with</code> <em class="replaceable"><code>string</code></em>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether the second operand is an initial substring of the first
+ operand.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('["John Smith", "Mary Stone", "Bob Johnson"]', '$[*] ? (@ starts with "John")')</code>
+ → <code class="returnvalue">"John Smith"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">exists</code> <code class="literal">(</code> <em class="replaceable"><code>path_expression</code></em> <code class="literal">)</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether a path expression matches at least one SQL/JSON item.
+ Returns <code class="literal">unknown</code> if the path expression would result
+ in an error; the second example uses this to avoid a no-such-key error
+ in strict mode.
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query('{"x": [1, 2], "y": [2, 4]}', 'strict $.* ? (exists (@ ? (@[*] &gt; 2)))')</code>
+ → <code class="returnvalue">[2, 4]</code>
+ </p>
+ <p>
+ <code class="literal">jsonb_path_query_array('{"value": 41}', 'strict $ ? (exists (@.name)) .name')</code>
+ → <code class="returnvalue">[]</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect3" id="JSONPATH-REGULAR-EXPRESSIONS"><div class="titlepage"><div><div><h4 class="title">9.16.2.3. SQL/JSON Regular Expressions</h4></div></div></div><a id="id-1.5.8.22.6.24.2" class="indexterm"></a><p>
+ SQL/JSON path expressions allow matching text to a regular expression
+ with the <code class="literal">like_regex</code> filter. For example, the
+ following SQL/JSON path query would case-insensitively match all
+ strings in an array that start with an English vowel:
+</p><pre class="programlisting">
+$[*] ? (@ like_regex "^[aeiou]" flag "i")
+</pre><p>
+ </p><p>
+ The optional <code class="literal">flag</code> string may include one or more of
+ the characters
+ <code class="literal">i</code> for case-insensitive match,
+ <code class="literal">m</code> to allow <code class="literal">^</code>
+ and <code class="literal">$</code> to match at newlines,
+ <code class="literal">s</code> to allow <code class="literal">.</code> to match a newline,
+ and <code class="literal">q</code> to quote the whole pattern (reducing the
+ behavior to a simple substring match).
+ </p><p>
+ The SQL/JSON standard borrows its definition for regular expressions
+ from the <code class="literal">LIKE_REGEX</code> operator, which in turn uses the
+ XQuery standard. PostgreSQL does not currently support the
+ <code class="literal">LIKE_REGEX</code> operator. Therefore,
+ the <code class="literal">like_regex</code> filter is implemented using the
+ POSIX regular expression engine described in
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>. This leads to various minor
+ discrepancies from standard SQL/JSON behavior, which are cataloged in
+ <a class="xref" href="functions-matching.html#POSIX-VS-XQUERY" title="9.7.3.8. Differences from SQL Standard and XQuery">Section 9.7.3.8</a>.
+ Note, however, that the flag-letter incompatibilities described there
+ do not apply to SQL/JSON, as it translates the XQuery flag letters to
+ match what the POSIX engine expects.
+ </p><p>
+ Keep in mind that the pattern argument of <code class="literal">like_regex</code>
+ is a JSON path string literal, written according to the rules given in
+ <a class="xref" href="datatype-json.html#DATATYPE-JSONPATH" title="8.14.7. jsonpath Type">Section 8.14.7</a>. This means in particular that any
+ backslashes you want to use in the regular expression must be doubled.
+ For example, to match string values of the root document that contain
+ only digits:
+</p><pre class="programlisting">
+$.* ? (@ like_regex "^\\d+$")
+</pre><p>
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-xml.html" title="9.15. XML Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.15. XML Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.17. Sequence Manipulation Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-logical.html b/doc/src/sgml/html/functions-logical.html
new file mode 100644
index 0000000..8c53ea6
--- /dev/null
+++ b/doc/src/sgml/html/functions-logical.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.1. Logical Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions.html" title="Chapter 9. Functions and Operators" /><link rel="next" href="functions-comparison.html" title="9.2. Comparison Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.1. Logical Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions.html" title="Chapter 9. Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-comparison.html" title="9.2. Comparison Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-LOGICAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.1. Logical Operators</h2></div></div></div><a id="id-1.5.8.7.2" class="indexterm"></a><a id="id-1.5.8.7.3" class="indexterm"></a><p>
+ The usual logical operators are available:
+
+ <a id="id-1.5.8.7.4.1" class="indexterm"></a>
+
+ <a id="id-1.5.8.7.4.2" class="indexterm"></a>
+
+ <a id="id-1.5.8.7.4.3" class="indexterm"></a>
+
+ <a id="id-1.5.8.7.4.4" class="indexterm"></a>
+
+ <a id="id-1.5.8.7.4.5" class="indexterm"></a>
+
+ <a id="id-1.5.8.7.4.6" class="indexterm"></a>
+
+</p><pre class="synopsis">
+<code class="type">boolean</code> <code class="literal">AND</code> <code class="type">boolean</code> → <code class="returnvalue">boolean</code>
+<code class="type">boolean</code> <code class="literal">OR</code> <code class="type">boolean</code> → <code class="returnvalue">boolean</code>
+<code class="literal">NOT</code> <code class="type">boolean</code> → <code class="returnvalue">boolean</code>
+</pre><p>
+
+ <acronym class="acronym">SQL</acronym> uses a three-valued logic system with true,
+ false, and <code class="literal">null</code>, which represents <span class="quote">“<span class="quote">unknown</span>”</span>.
+ Observe the following truth tables:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th><em class="replaceable"><code>a</code></em></th><th><em class="replaceable"><code>b</code></em></th><th><em class="replaceable"><code>a</code></em> AND <em class="replaceable"><code>b</code></em></th><th><em class="replaceable"><code>a</code></em> OR <em class="replaceable"><code>b</code></em></th></tr></thead><tbody><tr><td>TRUE</td><td>TRUE</td><td>TRUE</td><td>TRUE</td></tr><tr><td>TRUE</td><td>FALSE</td><td>FALSE</td><td>TRUE</td></tr><tr><td>TRUE</td><td>NULL</td><td>NULL</td><td>TRUE</td></tr><tr><td>FALSE</td><td>FALSE</td><td>FALSE</td><td>FALSE</td></tr><tr><td>FALSE</td><td>NULL</td><td>FALSE</td><td>NULL</td></tr><tr><td>NULL</td><td>NULL</td><td>NULL</td><td>NULL</td></tr></tbody></table></div><p>
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><em class="replaceable"><code>a</code></em></th><th>NOT <em class="replaceable"><code>a</code></em></th></tr></thead><tbody><tr><td>TRUE</td><td>FALSE</td></tr><tr><td>FALSE</td><td>TRUE</td></tr><tr><td>NULL</td><td>NULL</td></tr></tbody></table></div><p>
+ </p><p>
+ The operators <code class="literal">AND</code> and <code class="literal">OR</code> are
+ commutative, that is, you can switch the left and right operands
+ without affecting the result. (However, it is not guaranteed that
+ the left operand is evaluated before the right operand. See <a class="xref" href="sql-expressions.html#SYNTAX-EXPRESS-EVAL" title="4.2.14. Expression Evaluation Rules">Section 4.2.14</a> for more information about the
+ order of evaluation of subexpressions.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions.html" title="Chapter 9. Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-comparison.html" title="9.2. Comparison Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 9. Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.2. Comparison Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-matching.html b/doc/src/sgml/html/functions-matching.html
new file mode 100644
index 0000000..f6c5813
--- /dev/null
+++ b/doc/src/sgml/html/functions-matching.html
@@ -0,0 +1,1415 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.7. Pattern Matching</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators" /><link rel="next" href="functions-formatting.html" title="9.8. Data Type Formatting Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.7. Pattern Matching</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-MATCHING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.7. Pattern Matching</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-matching.html#FUNCTIONS-LIKE">9.7.1. <code class="function">LIKE</code></a></span></dt><dt><span class="sect2"><a href="functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP">9.7.2. <code class="function">SIMILAR TO</code> Regular Expressions</a></span></dt><dt><span class="sect2"><a href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">9.7.3. <acronym class="acronym">POSIX</acronym> Regular Expressions</a></span></dt></dl></div><a id="id-1.5.8.13.2" class="indexterm"></a><p>
+ There are three separate approaches to pattern matching provided
+ by <span class="productname">PostgreSQL</span>: the traditional
+ <acronym class="acronym">SQL</acronym> <code class="function">LIKE</code> operator, the
+ more recent <code class="function">SIMILAR TO</code> operator (added in
+ SQL:1999), and <acronym class="acronym">POSIX</acronym>-style regular
+ expressions. Aside from the basic <span class="quote">“<span class="quote">does this string match
+ this pattern?</span>”</span> operators, functions are available to extract
+ or replace matching substrings and to split a string at matching
+ locations.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If you have pattern matching needs that go beyond this,
+ consider writing a user-defined function in Perl or Tcl.
+ </p></div><div class="caution"><h3 class="title">Caution</h3><p>
+ While most regular-expression searches can be executed very quickly,
+ regular expressions can be contrived that take arbitrary amounts of
+ time and memory to process. Be wary of accepting regular-expression
+ search patterns from hostile sources. If you must do so, it is
+ advisable to impose a statement timeout.
+ </p><p>
+ Searches using <code class="function">SIMILAR TO</code> patterns have the same
+ security hazards, since <code class="function">SIMILAR TO</code> provides many
+ of the same capabilities as <acronym class="acronym">POSIX</acronym>-style regular
+ expressions.
+ </p><p>
+ <code class="function">LIKE</code> searches, being much simpler than the other
+ two options, are safer to use with possibly-hostile pattern sources.
+ </p></div><p>
+ The pattern matching operators of all three kinds do not support
+ nondeterministic collations. If required, apply a different collation to
+ the expression to work around this limitation.
+ </p><div class="sect2" id="FUNCTIONS-LIKE"><div class="titlepage"><div><div><h3 class="title">9.7.1. <code class="function">LIKE</code></h3></div></div></div><a id="id-1.5.8.13.7.2" class="indexterm"></a><pre class="synopsis">
+<em class="replaceable"><code>string</code></em> LIKE <em class="replaceable"><code>pattern</code></em> [<span class="optional">ESCAPE <em class="replaceable"><code>escape-character</code></em></span>]
+<em class="replaceable"><code>string</code></em> NOT LIKE <em class="replaceable"><code>pattern</code></em> [<span class="optional">ESCAPE <em class="replaceable"><code>escape-character</code></em></span>]
+</pre><p>
+ The <code class="function">LIKE</code> expression returns true if the
+ <em class="replaceable"><code>string</code></em> matches the supplied
+ <em class="replaceable"><code>pattern</code></em>. (As
+ expected, the <code class="function">NOT LIKE</code> expression returns
+ false if <code class="function">LIKE</code> returns true, and vice versa.
+ An equivalent expression is
+ <code class="literal">NOT (<em class="replaceable"><code>string</code></em> LIKE
+ <em class="replaceable"><code>pattern</code></em>)</code>.)
+ </p><p>
+ If <em class="replaceable"><code>pattern</code></em> does not contain percent
+ signs or underscores, then the pattern only represents the string
+ itself; in that case <code class="function">LIKE</code> acts like the
+ equals operator. An underscore (<code class="literal">_</code>) in
+ <em class="replaceable"><code>pattern</code></em> stands for (matches) any single
+ character; a percent sign (<code class="literal">%</code>) matches any sequence
+ of zero or more characters.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+'abc' LIKE 'abc' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'abc' LIKE 'a%' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'abc' LIKE '_b_' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'abc' LIKE 'c' <em class="lineannotation"><span class="lineannotation">false</span></em>
+</pre><p>
+ </p><p>
+ <code class="function">LIKE</code> pattern matching always covers the entire
+ string. Therefore, if it's desired to match a sequence anywhere within
+ a string, the pattern must start and end with a percent sign.
+ </p><p>
+ To match a literal underscore or percent sign without matching
+ other characters, the respective character in
+ <em class="replaceable"><code>pattern</code></em> must be
+ preceded by the escape character. The default escape
+ character is the backslash but a different one can be selected by
+ using the <code class="literal">ESCAPE</code> clause. To match the escape
+ character itself, write two escape characters.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If you have <a class="xref" href="runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS">standard_conforming_strings</a> turned off,
+ any backslashes you write in literal string constants will need to be
+ doubled. See <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a> for more information.
+ </p></div><p>
+ It's also possible to select no escape character by writing
+ <code class="literal">ESCAPE ''</code>. This effectively disables the
+ escape mechanism, which makes it impossible to turn off the
+ special meaning of underscore and percent signs in the pattern.
+ </p><p>
+ According to the SQL standard, omitting <code class="literal">ESCAPE</code>
+ means there is no escape character (rather than defaulting to a
+ backslash), and a zero-length <code class="literal">ESCAPE</code> value is
+ disallowed. <span class="productname">PostgreSQL</span>'s behavior in
+ this regard is therefore slightly nonstandard.
+ </p><p>
+ The key word <code class="token">ILIKE</code> can be used instead of
+ <code class="token">LIKE</code> to make the match case-insensitive according
+ to the active locale. This is not in the <acronym class="acronym">SQL</acronym> standard but is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p><p>
+ The operator <code class="literal">~~</code> is equivalent to
+ <code class="function">LIKE</code>, and <code class="literal">~~*</code> corresponds to
+ <code class="function">ILIKE</code>. There are also
+ <code class="literal">!~~</code> and <code class="literal">!~~*</code> operators that
+ represent <code class="function">NOT LIKE</code> and <code class="function">NOT
+ ILIKE</code>, respectively. All of these operators are
+ <span class="productname">PostgreSQL</span>-specific. You may see these
+ operator names in <code class="command">EXPLAIN</code> output and similar
+ places, since the parser actually translates <code class="function">LIKE</code>
+ et al. to these operators.
+ </p><p>
+ The phrases <code class="function">LIKE</code>, <code class="function">ILIKE</code>,
+ <code class="function">NOT LIKE</code>, and <code class="function">NOT ILIKE</code> are
+ generally treated as operators
+ in <span class="productname">PostgreSQL</span> syntax; for example they can
+ be used in <em class="replaceable"><code>expression</code></em>
+ <em class="replaceable"><code>operator</code></em> ANY
+ (<em class="replaceable"><code>subquery</code></em>) constructs, although
+ an <code class="literal">ESCAPE</code> clause cannot be included there. In some
+ obscure cases it may be necessary to use the underlying operator names
+ instead.
+ </p><p>
+ Also see the starts-with operator <code class="literal">^@</code> and the
+ corresponding <code class="function">starts_with()</code> function, which are
+ useful in cases where simply matching the beginning of a string is
+ needed.
+ </p></div><div class="sect2" id="FUNCTIONS-SIMILARTO-REGEXP"><div class="titlepage"><div><div><h3 class="title">9.7.2. <code class="function">SIMILAR TO</code> Regular Expressions</h3></div></div></div><a id="id-1.5.8.13.8.2" class="indexterm"></a><a id="id-1.5.8.13.8.3" class="indexterm"></a><a id="id-1.5.8.13.8.4" class="indexterm"></a><pre class="synopsis">
+<em class="replaceable"><code>string</code></em> SIMILAR TO <em class="replaceable"><code>pattern</code></em> [<span class="optional">ESCAPE <em class="replaceable"><code>escape-character</code></em></span>]
+<em class="replaceable"><code>string</code></em> NOT SIMILAR TO <em class="replaceable"><code>pattern</code></em> [<span class="optional">ESCAPE <em class="replaceable"><code>escape-character</code></em></span>]
+</pre><p>
+ The <code class="function">SIMILAR TO</code> operator returns true or
+ false depending on whether its pattern matches the given string.
+ It is similar to <code class="function">LIKE</code>, except that it
+ interprets the pattern using the SQL standard's definition of a
+ regular expression. SQL regular expressions are a curious cross
+ between <code class="function">LIKE</code> notation and common (POSIX) regular
+ expression notation.
+ </p><p>
+ Like <code class="function">LIKE</code>, the <code class="function">SIMILAR TO</code>
+ operator succeeds only if its pattern matches the entire string;
+ this is unlike common regular expression behavior where the pattern
+ can match any part of the string.
+ Also like
+ <code class="function">LIKE</code>, <code class="function">SIMILAR TO</code> uses
+ <code class="literal">_</code> and <code class="literal">%</code> as wildcard characters denoting
+ any single character and any string, respectively (these are
+ comparable to <code class="literal">.</code> and <code class="literal">.*</code> in POSIX regular
+ expressions).
+ </p><p>
+ In addition to these facilities borrowed from <code class="function">LIKE</code>,
+ <code class="function">SIMILAR TO</code> supports these pattern-matching
+ metacharacters borrowed from POSIX regular expressions:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">|</code> denotes alternation (either of two alternatives).
+ </p></li><li class="listitem"><p>
+ <code class="literal">*</code> denotes repetition of the previous item zero
+ or more times.
+ </p></li><li class="listitem"><p>
+ <code class="literal">+</code> denotes repetition of the previous item one
+ or more times.
+ </p></li><li class="listitem"><p>
+ <code class="literal">?</code> denotes repetition of the previous item zero
+ or one time.
+ </p></li><li class="listitem"><p>
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">}</code> denotes repetition
+ of the previous item exactly <em class="replaceable"><code>m</code></em> times.
+ </p></li><li class="listitem"><p>
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,}</code> denotes repetition
+ of the previous item <em class="replaceable"><code>m</code></em> or more times.
+ </p></li><li class="listitem"><p>
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,</code><em class="replaceable"><code>n</code></em><code class="literal">}</code>
+ denotes repetition of the previous item at least <em class="replaceable"><code>m</code></em> and
+ not more than <em class="replaceable"><code>n</code></em> times.
+ </p></li><li class="listitem"><p>
+ Parentheses <code class="literal">()</code> can be used to group items into
+ a single logical item.
+ </p></li><li class="listitem"><p>
+ A bracket expression <code class="literal">[...]</code> specifies a character
+ class, just as in POSIX regular expressions.
+ </p></li></ul></div><p>
+
+ Notice that the period (<code class="literal">.</code>) is not a metacharacter
+ for <code class="function">SIMILAR TO</code>.
+ </p><p>
+ As with <code class="function">LIKE</code>, a backslash disables the special
+ meaning of any of these metacharacters. A different escape character
+ can be specified with <code class="literal">ESCAPE</code>, or the escape
+ capability can be disabled by writing <code class="literal">ESCAPE ''</code>.
+ </p><p>
+ According to the SQL standard, omitting <code class="literal">ESCAPE</code>
+ means there is no escape character (rather than defaulting to a
+ backslash), and a zero-length <code class="literal">ESCAPE</code> value is
+ disallowed. <span class="productname">PostgreSQL</span>'s behavior in
+ this regard is therefore slightly nonstandard.
+ </p><p>
+ Another nonstandard extension is that following the escape character
+ with a letter or digit provides access to the escape sequences
+ defined for POSIX regular expressions; see
+ <a class="xref" href="functions-matching.html#POSIX-CHARACTER-ENTRY-ESCAPES-TABLE" title="Table 9.20. Regular Expression Character-Entry Escapes">Table 9.20</a>,
+ <a class="xref" href="functions-matching.html#POSIX-CLASS-SHORTHAND-ESCAPES-TABLE" title="Table 9.21. Regular Expression Class-Shorthand Escapes">Table 9.21</a>, and
+ <a class="xref" href="functions-matching.html#POSIX-CONSTRAINT-ESCAPES-TABLE" title="Table 9.22. Regular Expression Constraint Escapes">Table 9.22</a> below.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+'abc' SIMILAR TO 'abc' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'abc' SIMILAR TO 'a' <em class="lineannotation"><span class="lineannotation">false</span></em>
+'abc' SIMILAR TO '%(b|d)%' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'abc' SIMILAR TO '(b|c)%' <em class="lineannotation"><span class="lineannotation">false</span></em>
+'-abc-' SIMILAR TO '%\mabc\M%' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'xabcy' SIMILAR TO '%\mabc\M%' <em class="lineannotation"><span class="lineannotation">false</span></em>
+</pre><p>
+ </p><p>
+ The <code class="function">substring</code> function with three parameters
+ provides extraction of a substring that matches an SQL
+ regular expression pattern. The function can be written according
+ to standard SQL syntax:
+</p><pre class="synopsis">
+substring(<em class="replaceable"><code>string</code></em> similar <em class="replaceable"><code>pattern</code></em> escape <em class="replaceable"><code>escape-character</code></em>)
+</pre><p>
+ or using the now obsolete SQL:1999 syntax:
+</p><pre class="synopsis">
+substring(<em class="replaceable"><code>string</code></em> from <em class="replaceable"><code>pattern</code></em> for <em class="replaceable"><code>escape-character</code></em>)
+</pre><p>
+ or as a plain three-argument function:
+</p><pre class="synopsis">
+substring(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>, <em class="replaceable"><code>escape-character</code></em>)
+</pre><p>
+ As with <code class="literal">SIMILAR TO</code>, the
+ specified pattern must match the entire data string, or else the
+ function fails and returns null. To indicate the part of the
+ pattern for which the matching data sub-string is of interest,
+ the pattern should contain
+ two occurrences of the escape character followed by a double quote
+ (<code class="literal">"</code>).
+ The text matching the portion of the pattern
+ between these separators is returned when the match is successful.
+ </p><p>
+ The escape-double-quote separators actually
+ divide <code class="function">substring</code>'s pattern into three independent
+ regular expressions; for example, a vertical bar (<code class="literal">|</code>)
+ in any of the three sections affects only that section. Also, the first
+ and third of these regular expressions are defined to match the smallest
+ possible amount of text, not the largest, when there is any ambiguity
+ about how much of the data string matches which pattern. (In POSIX
+ parlance, the first and third regular expressions are forced to be
+ non-greedy.)
+ </p><p>
+ As an extension to the SQL standard, <span class="productname">PostgreSQL</span>
+ allows there to be just one escape-double-quote separator, in which case
+ the third regular expression is taken as empty; or no separators, in which
+ case the first and third regular expressions are taken as empty.
+ </p><p>
+ Some examples, with <code class="literal">#"</code> delimiting the return string:
+</p><pre class="programlisting">
+substring('foobar' similar '%#"o_b#"%' escape '#') <em class="lineannotation"><span class="lineannotation">oob</span></em>
+substring('foobar' similar '#"o_b#"%' escape '#') <em class="lineannotation"><span class="lineannotation">NULL</span></em>
+</pre><p>
+ </p></div><div class="sect2" id="FUNCTIONS-POSIX-REGEXP"><div class="titlepage"><div><div><h3 class="title">9.7.3. <acronym class="acronym">POSIX</acronym> Regular Expressions</h3></div></div></div><a id="id-1.5.8.13.9.2" class="indexterm"></a><a id="id-1.5.8.13.9.3" class="indexterm"></a><a id="id-1.5.8.13.9.4" class="indexterm"></a><a id="id-1.5.8.13.9.5" class="indexterm"></a><a id="id-1.5.8.13.9.6" class="indexterm"></a><a id="id-1.5.8.13.9.7" class="indexterm"></a><a id="id-1.5.8.13.9.8" class="indexterm"></a><a id="id-1.5.8.13.9.9" class="indexterm"></a><a id="id-1.5.8.13.9.10" class="indexterm"></a><a id="id-1.5.8.13.9.11" class="indexterm"></a><a id="id-1.5.8.13.9.12" class="indexterm"></a><p>
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-TABLE" title="Table 9.16. Regular Expression Match Operators">Table 9.16</a> lists the available
+ operators for pattern matching using POSIX regular expressions.
+ </p><div class="table" id="FUNCTIONS-POSIX-TABLE"><p class="title"><strong>Table 9.16. Regular Expression Match Operators</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Match Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">~</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ String matches regular expression, case sensitively
+ </p>
+ <p>
+ <code class="literal">'thomas' ~ 't.*ma'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">~*</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ String matches regular expression, case insensitively
+ </p>
+ <p>
+ <code class="literal">'thomas' ~* 'T.*ma'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">!~</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ String does not match regular expression, case sensitively
+ </p>
+ <p>
+ <code class="literal">'thomas' !~ 't.*max'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">!~*</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ String does not match regular expression, case insensitively
+ </p>
+ <p>
+ <code class="literal">'thomas' !~* 'T.*ma'</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <acronym class="acronym">POSIX</acronym> regular expressions provide a more
+ powerful means for pattern matching than the <code class="function">LIKE</code> and
+ <code class="function">SIMILAR TO</code> operators.
+ Many Unix tools such as <code class="command">egrep</code>,
+ <code class="command">sed</code>, or <code class="command">awk</code> use a pattern
+ matching language that is similar to the one described here.
+ </p><p>
+ A regular expression is a character sequence that is an
+ abbreviated definition of a set of strings (a <em class="firstterm">regular
+ set</em>). A string is said to match a regular expression
+ if it is a member of the regular set described by the regular
+ expression. As with <code class="function">LIKE</code>, pattern characters
+ match string characters exactly unless they are special characters
+ in the regular expression language — but regular expressions use
+ different special characters than <code class="function">LIKE</code> does.
+ Unlike <code class="function">LIKE</code> patterns, a
+ regular expression is allowed to match anywhere within a string, unless
+ the regular expression is explicitly anchored to the beginning or
+ end of the string.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+'abcd' ~ 'bc' <em class="lineannotation"><span class="lineannotation">true</span></em>
+'abcd' ~ 'a.c' <em class="lineannotation"><span class="lineannotation">true — dot matches any character</span></em>
+'abcd' ~ 'a.*d' <em class="lineannotation"><span class="lineannotation">true — <code class="literal">*</code> repeats the preceding pattern item</span></em>
+'abcd' ~ '(b|x)' <em class="lineannotation"><span class="lineannotation">true — <code class="literal">|</code> means OR, parentheses group</span></em>
+'abcd' ~ '^a' <em class="lineannotation"><span class="lineannotation">true — <code class="literal">^</code> anchors to start of string</span></em>
+'abcd' ~ '^(b|c)' <em class="lineannotation"><span class="lineannotation">false — would match except for anchoring</span></em>
+</pre><p>
+ </p><p>
+ The <acronym class="acronym">POSIX</acronym> pattern language is described in much
+ greater detail below.
+ </p><p>
+ The <code class="function">substring</code> function with two parameters,
+ <code class="function">substring(<em class="replaceable"><code>string</code></em> from
+ <em class="replaceable"><code>pattern</code></em>)</code>, provides extraction of a
+ substring
+ that matches a POSIX regular expression pattern. It returns null if
+ there is no match, otherwise the first portion of the text that matched the
+ pattern. But if the pattern contains any parentheses, the portion
+ of the text that matched the first parenthesized subexpression (the
+ one whose left parenthesis comes first) is
+ returned. You can put parentheses around the whole expression
+ if you want to use parentheses within it without triggering this
+ exception. If you need parentheses in the pattern before the
+ subexpression you want to extract, see the non-capturing parentheses
+ described below.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+substring('foobar' from 'o.b') <em class="lineannotation"><span class="lineannotation">oob</span></em>
+substring('foobar' from 'o(.)b') <em class="lineannotation"><span class="lineannotation">o</span></em>
+</pre><p>
+ </p><p>
+ The <code class="function">regexp_count</code> function counts the number of
+ places where a POSIX regular expression pattern matches a string.
+ It has the syntax
+ <code class="function">regexp_count</code>(<em class="replaceable"><code>string</code></em>,
+ <em class="replaceable"><code>pattern</code></em>
+ [<span class="optional">, <em class="replaceable"><code>start</code></em>
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em>
+ </span>]</span>]).
+ <em class="replaceable"><code>pattern</code></em> is searched for
+ in <em class="replaceable"><code>string</code></em>, normally from the beginning of
+ the string, but if the <em class="replaceable"><code>start</code></em> parameter is
+ provided then beginning from that character index.
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. For example, including <code class="literal">i</code> in
+ <em class="replaceable"><code>flags</code></em> specifies case-insensitive matching.
+ Supported flags are described in
+ <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+regexp_count('ABCABCAXYaxy', 'A.') <em class="lineannotation"><span class="lineannotation">3</span></em>
+regexp_count('ABCABCAXYaxy', 'A.', 1, 'i') <em class="lineannotation"><span class="lineannotation">4</span></em>
+</pre><p>
+ </p><p>
+ The <code class="function">regexp_instr</code> function returns the starting or
+ ending position of the <em class="replaceable"><code>N</code></em>'th match of a
+ POSIX regular expression pattern to a string, or zero if there is no
+ such match. It has the syntax
+ <code class="function">regexp_instr</code>(<em class="replaceable"><code>string</code></em>,
+ <em class="replaceable"><code>pattern</code></em>
+ [<span class="optional">, <em class="replaceable"><code>start</code></em>
+ [<span class="optional">, <em class="replaceable"><code>N</code></em>
+ [<span class="optional">, <em class="replaceable"><code>endoption</code></em>
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em>
+ [<span class="optional">, <em class="replaceable"><code>subexpr</code></em>
+ </span>]</span>]</span>]</span>]</span>]).
+ <em class="replaceable"><code>pattern</code></em> is searched for
+ in <em class="replaceable"><code>string</code></em>, normally from the beginning of
+ the string, but if the <em class="replaceable"><code>start</code></em> parameter is
+ provided then beginning from that character index.
+ If <em class="replaceable"><code>N</code></em> is specified
+ then the <em class="replaceable"><code>N</code></em>'th match of the pattern
+ is located, otherwise the first match is located.
+ If the <em class="replaceable"><code>endoption</code></em> parameter is omitted or
+ specified as zero, the function returns the position of the first
+ character of the match. Otherwise, <em class="replaceable"><code>endoption</code></em>
+ must be one, and the function returns the position of the character
+ following the match.
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags are described
+ in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ For a pattern containing parenthesized
+ subexpressions, <em class="replaceable"><code>subexpr</code></em> is an integer
+ indicating which subexpression is of interest: the result identifies
+ the position of the substring matching that subexpression.
+ Subexpressions are numbered in the order of their leading parentheses.
+ When <em class="replaceable"><code>subexpr</code></em> is omitted or zero, the result
+ identifies the position of the whole match regardless of
+ parenthesized subexpressions.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2)
+ <em class="lineannotation"><span class="lineannotation">23</span></em>
+regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2)
+ <em class="lineannotation"><span class="lineannotation">6</span></em>
+</pre><p>
+ </p><p>
+ The <code class="function">regexp_like</code> function checks whether a match
+ of a POSIX regular expression pattern occurs within a string,
+ returning boolean true or false. It has the syntax
+ <code class="function">regexp_like</code>(<em class="replaceable"><code>string</code></em>,
+ <em class="replaceable"><code>pattern</code></em>
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em> </span>]).
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags are described
+ in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ This function has the same results as the <code class="literal">~</code>
+ operator if no flags are specified. If only the <code class="literal">i</code>
+ flag is specified, it has the same results as
+ the <code class="literal">~*</code> operator.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+regexp_like('Hello World', 'world') <em class="lineannotation"><span class="lineannotation">false</span></em>
+regexp_like('Hello World', 'world', 'i') <em class="lineannotation"><span class="lineannotation">true</span></em>
+</pre><p>
+ </p><p>
+ The <code class="function">regexp_match</code> function returns a text array of
+ matching substring(s) within the first match of a POSIX
+ regular expression pattern to a string. It has the syntax
+ <code class="function">regexp_match</code>(<em class="replaceable"><code>string</code></em>,
+ <em class="replaceable"><code>pattern</code></em> [<span class="optional">, <em class="replaceable"><code>flags</code></em> </span>]).
+ If there is no match, the result is <code class="literal">NULL</code>.
+ If a match is found, and the <em class="replaceable"><code>pattern</code></em> contains no
+ parenthesized subexpressions, then the result is a single-element text
+ array containing the substring matching the whole pattern.
+ If a match is found, and the <em class="replaceable"><code>pattern</code></em> contains
+ parenthesized subexpressions, then the result is a text array
+ whose <em class="replaceable"><code>n</code></em>'th element is the substring matching
+ the <em class="replaceable"><code>n</code></em>'th parenthesized subexpression of
+ the <em class="replaceable"><code>pattern</code></em> (not counting <span class="quote">“<span class="quote">non-capturing</span>”</span>
+ parentheses; see below for details).
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text string
+ containing zero or more single-letter flags that change the function's
+ behavior. Supported flags are described
+ in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+SELECT regexp_match('foobarbequebaz', 'bar.*que');
+ regexp_match
+--------------
+ {barbeque}
+(1 row)
+
+SELECT regexp_match('foobarbequebaz', '(bar)(beque)');
+ regexp_match
+--------------
+ {bar,beque}
+(1 row)
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ In the common case where you just want the whole matching substring
+ or <code class="literal">NULL</code> for no match, the best solution is to
+ use <code class="function">regexp_substr()</code>.
+ However, <code class="function">regexp_substr()</code> only exists
+ in <span class="productname">PostgreSQL</span> version 15 and up. When
+ working in older versions, you can extract the first element
+ of <code class="function">regexp_match()</code>'s result, for example:
+</p><pre class="programlisting">
+SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
+ regexp_match
+--------------
+ barbeque
+(1 row)
+</pre><p>
+ </p></div><p>
+ The <code class="function">regexp_matches</code> function returns a set of text arrays
+ of matching substring(s) within matches of a POSIX regular
+ expression pattern to a string. It has the same syntax as
+ <code class="function">regexp_match</code>.
+ This function returns no rows if there is no match, one row if there is
+ a match and the <code class="literal">g</code> flag is not given, or <em class="replaceable"><code>N</code></em>
+ rows if there are <em class="replaceable"><code>N</code></em> matches and the <code class="literal">g</code> flag
+ is given. Each returned row is a text array containing the whole
+ matched substring or the substrings matching parenthesized
+ subexpressions of the <em class="replaceable"><code>pattern</code></em>, just as described above
+ for <code class="function">regexp_match</code>.
+ <code class="function">regexp_matches</code> accepts all the flags shown
+ in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>, plus
+ the <code class="literal">g</code> flag which commands it to return all matches, not
+ just the first one.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+SELECT regexp_matches('foo', 'not there');
+ regexp_matches
+----------------
+(0 rows)
+
+SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
+ regexp_matches
+----------------
+ {bar,beque}
+ {bazil,barf}
+(2 rows)
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ In most cases <code class="function">regexp_matches()</code> should be used with
+ the <code class="literal">g</code> flag, since if you only want the first match, it's
+ easier and more efficient to use <code class="function">regexp_match()</code>.
+ However, <code class="function">regexp_match()</code> only exists
+ in <span class="productname">PostgreSQL</span> version 10 and up. When working in older
+ versions, a common trick is to place a <code class="function">regexp_matches()</code>
+ call in a sub-select, for example:
+</p><pre class="programlisting">
+SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;
+</pre><p>
+ This produces a text array if there's a match, or <code class="literal">NULL</code> if
+ not, the same as <code class="function">regexp_match()</code> would do. Without the
+ sub-select, this query would produce no output at all for table rows
+ without a match, which is typically not the desired behavior.
+ </p></div><p>
+ The <code class="function">regexp_replace</code> function provides substitution of
+ new text for substrings that match POSIX regular expression patterns.
+ It has the syntax
+ <code class="function">regexp_replace</code>(<em class="replaceable"><code>source</code></em>,
+ <em class="replaceable"><code>pattern</code></em>, <em class="replaceable"><code>replacement</code></em>
+ [<span class="optional">, <em class="replaceable"><code>start</code></em>
+ [<span class="optional">, <em class="replaceable"><code>N</code></em>
+ </span>]</span>]
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em> </span>]).
+ (Notice that <em class="replaceable"><code>N</code></em> cannot be specified
+ unless <em class="replaceable"><code>start</code></em> is,
+ but <em class="replaceable"><code>flags</code></em> can be given in any case.)
+ The <em class="replaceable"><code>source</code></em> string is returned unchanged if
+ there is no match to the <em class="replaceable"><code>pattern</code></em>. If there is a
+ match, the <em class="replaceable"><code>source</code></em> string is returned with the
+ <em class="replaceable"><code>replacement</code></em> string substituted for the matching
+ substring. The <em class="replaceable"><code>replacement</code></em> string can contain
+ <code class="literal">\</code><em class="replaceable"><code>n</code></em>, where <em class="replaceable"><code>n</code></em> is 1
+ through 9, to indicate that the source substring matching the
+ <em class="replaceable"><code>n</code></em>'th parenthesized subexpression of the pattern should be
+ inserted, and it can contain <code class="literal">\&amp;</code> to indicate that the
+ substring matching the entire pattern should be inserted. Write
+ <code class="literal">\\</code> if you need to put a literal backslash in the replacement
+ text.
+ <em class="replaceable"><code>pattern</code></em> is searched for
+ in <em class="replaceable"><code>string</code></em>, normally from the beginning of
+ the string, but if the <em class="replaceable"><code>start</code></em> parameter is
+ provided then beginning from that character index.
+ By default, only the first match of the pattern is replaced.
+ If <em class="replaceable"><code>N</code></em> is specified and is greater than zero,
+ then the <em class="replaceable"><code>N</code></em>'th match of the pattern
+ is replaced.
+ If the <code class="literal">g</code> flag is given, or
+ if <em class="replaceable"><code>N</code></em> is specified and is zero, then all
+ matches at or after the <em class="replaceable"><code>start</code></em> position are
+ replaced. (The <code class="literal">g</code> flag is ignored
+ when <em class="replaceable"><code>N</code></em> is specified.)
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags (though
+ not <code class="literal">g</code>) are
+ described in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+regexp_replace('foobarbaz', 'b..', 'X')
+ <em class="lineannotation"><span class="lineannotation">fooXbaz</span></em>
+regexp_replace('foobarbaz', 'b..', 'X', 'g')
+ <em class="lineannotation"><span class="lineannotation">fooXX</span></em>
+regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
+ <em class="lineannotation"><span class="lineannotation">fooXarYXazY</span></em>
+regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i')
+ <em class="lineannotation"><span class="lineannotation">X PXstgrXSQL fXnctXXn</span></em>
+regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i')
+ <em class="lineannotation"><span class="lineannotation">A PostgrXSQL function</span></em>
+</pre><p>
+ </p><p>
+ The <code class="function">regexp_split_to_table</code> function splits a string using a POSIX
+ regular expression pattern as a delimiter. It has the syntax
+ <code class="function">regexp_split_to_table</code>(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em> </span>]).
+ If there is no match to the <em class="replaceable"><code>pattern</code></em>, the function returns the
+ <em class="replaceable"><code>string</code></em>. If there is at least one match, for each match it returns
+ the text from the end of the last match (or the beginning of the string)
+ to the beginning of the match. When there are no more matches, it
+ returns the text from the end of the last match to the end of the string.
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text string containing
+ zero or more single-letter flags that change the function's behavior.
+ <code class="function">regexp_split_to_table</code> supports the flags described in
+ <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ </p><p>
+ The <code class="function">regexp_split_to_array</code> function behaves the same as
+ <code class="function">regexp_split_to_table</code>, except that <code class="function">regexp_split_to_array</code>
+ returns its result as an array of <code class="type">text</code>. It has the syntax
+ <code class="function">regexp_split_to_array</code>(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em> </span>]).
+ The parameters are the same as for <code class="function">regexp_split_to_table</code>.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo;
+ foo
+-------
+ the
+ quick
+ brown
+ fox
+ jumps
+ over
+ the
+ lazy
+ dog
+(9 rows)
+
+SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+');
+ regexp_split_to_array
+-----------------------------------------------
+ {the,quick,brown,fox,jumps,over,the,lazy,dog}
+(1 row)
+
+SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
+ foo
+-----
+ t
+ h
+ e
+ q
+ u
+ i
+ c
+ k
+ b
+ r
+ o
+ w
+ n
+ f
+ o
+ x
+(16 rows)
+</pre><p>
+ </p><p>
+ As the last example demonstrates, the regexp split functions ignore
+ zero-length matches that occur at the start or end of the string
+ or immediately after a previous match. This is contrary to the strict
+ definition of regexp matching that is implemented by
+ the other regexp functions, but is usually the most convenient behavior
+ in practice. Other software systems such as Perl use similar definitions.
+ </p><p>
+ The <code class="function">regexp_substr</code> function returns the substring
+ that matches a POSIX regular expression pattern,
+ or <code class="literal">NULL</code> if there is no match. It has the syntax
+ <code class="function">regexp_substr</code>(<em class="replaceable"><code>string</code></em>,
+ <em class="replaceable"><code>pattern</code></em>
+ [<span class="optional">, <em class="replaceable"><code>start</code></em>
+ [<span class="optional">, <em class="replaceable"><code>N</code></em>
+ [<span class="optional">, <em class="replaceable"><code>flags</code></em>
+ [<span class="optional">, <em class="replaceable"><code>subexpr</code></em>
+ </span>]</span>]</span>]</span>]).
+ <em class="replaceable"><code>pattern</code></em> is searched for
+ in <em class="replaceable"><code>string</code></em>, normally from the beginning of
+ the string, but if the <em class="replaceable"><code>start</code></em> parameter is
+ provided then beginning from that character index.
+ If <em class="replaceable"><code>N</code></em> is specified
+ then the <em class="replaceable"><code>N</code></em>'th match of the pattern
+ is returned, otherwise the first match is returned.
+ The <em class="replaceable"><code>flags</code></em> parameter is an optional text
+ string containing zero or more single-letter flags that change the
+ function's behavior. Supported flags are described
+ in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ For a pattern containing parenthesized
+ subexpressions, <em class="replaceable"><code>subexpr</code></em> is an integer
+ indicating which subexpression is of interest: the result is the
+ substring matching that subexpression.
+ Subexpressions are numbered in the order of their leading parentheses.
+ When <em class="replaceable"><code>subexpr</code></em> is omitted or zero, the result
+ is the whole match regardless of parenthesized subexpressions.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2)
+ <em class="lineannotation"><span class="lineannotation"> town zip</span></em>
+regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
+ <em class="lineannotation"><span class="lineannotation">FGH</span></em>
+</pre><p>
+ </p><div class="sect3" id="POSIX-SYNTAX-DETAILS"><div class="titlepage"><div><div><h4 class="title">9.7.3.1. Regular Expression Details</h4></div></div></div><p>
+ <span class="productname">PostgreSQL</span>'s regular expressions are implemented
+ using a software package written by Henry Spencer. Much of
+ the description of regular expressions below is copied verbatim from his
+ manual.
+ </p><p>
+ Regular expressions (<acronym class="acronym">RE</acronym>s), as defined in
+ <acronym class="acronym">POSIX</acronym> 1003.2, come in two forms:
+ <em class="firstterm">extended</em> <acronym class="acronym">RE</acronym>s or <acronym class="acronym">ERE</acronym>s
+ (roughly those of <code class="command">egrep</code>), and
+ <em class="firstterm">basic</em> <acronym class="acronym">RE</acronym>s or <acronym class="acronym">BRE</acronym>s
+ (roughly those of <code class="command">ed</code>).
+ <span class="productname">PostgreSQL</span> supports both forms, and
+ also implements some extensions
+ that are not in the POSIX standard, but have become widely used
+ due to their availability in programming languages such as Perl and Tcl.
+ <acronym class="acronym">RE</acronym>s using these non-POSIX extensions are called
+ <em class="firstterm">advanced</em> <acronym class="acronym">RE</acronym>s or <acronym class="acronym">ARE</acronym>s
+ in this documentation. AREs are almost an exact superset of EREs,
+ but BREs have several notational incompatibilities (as well as being
+ much more limited).
+ We first describe the ARE and ERE forms, noting features that apply
+ only to AREs, and then describe how BREs differ.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> always initially presumes that a regular
+ expression follows the ARE rules. However, the more limited ERE or
+ BRE rules can be chosen by prepending an <em class="firstterm">embedded option</em>
+ to the RE pattern, as described in <a class="xref" href="functions-matching.html#POSIX-METASYNTAX" title="9.7.3.4. Regular Expression Metasyntax">Section 9.7.3.4</a>.
+ This can be useful for compatibility with applications that expect
+ exactly the <acronym class="acronym">POSIX</acronym> 1003.2 rules.
+ </p></div><p>
+ A regular expression is defined as one or more
+ <em class="firstterm">branches</em>, separated by
+ <code class="literal">|</code>. It matches anything that matches one of the
+ branches.
+ </p><p>
+ A branch is zero or more <em class="firstterm">quantified atoms</em> or
+ <em class="firstterm">constraints</em>, concatenated.
+ It matches a match for the first, followed by a match for the second, etc.;
+ an empty branch matches the empty string.
+ </p><p>
+ A quantified atom is an <em class="firstterm">atom</em> possibly followed
+ by a single <em class="firstterm">quantifier</em>.
+ Without a quantifier, it matches a match for the atom.
+ With a quantifier, it can match some number of matches of the atom.
+ An <em class="firstterm">atom</em> can be any of the possibilities
+ shown in <a class="xref" href="functions-matching.html#POSIX-ATOMS-TABLE" title="Table 9.17. Regular Expression Atoms">Table 9.17</a>.
+ The possible quantifiers and their meanings are shown in
+ <a class="xref" href="functions-matching.html#POSIX-QUANTIFIERS-TABLE" title="Table 9.18. Regular Expression Quantifiers">Table 9.18</a>.
+ </p><p>
+ A <em class="firstterm">constraint</em> matches an empty string, but matches only when
+ specific conditions are met. A constraint can be used where an atom
+ could be used, except it cannot be followed by a quantifier.
+ The simple constraints are shown in
+ <a class="xref" href="functions-matching.html#POSIX-CONSTRAINTS-TABLE" title="Table 9.19. Regular Expression Constraints">Table 9.19</a>;
+ some more constraints are described later.
+ </p><div class="table" id="POSIX-ATOMS-TABLE"><p class="title"><strong>Table 9.17. Regular Expression Atoms</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Atoms" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Atom</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">(</code><em class="replaceable"><code>re</code></em><code class="literal">)</code> </td><td> (where <em class="replaceable"><code>re</code></em> is any regular expression)
+ matches a match for
+ <em class="replaceable"><code>re</code></em>, with the match noted for possible reporting </td></tr><tr><td> <code class="literal">(?:</code><em class="replaceable"><code>re</code></em><code class="literal">)</code> </td><td> as above, but the match is not noted for reporting
+ (a <span class="quote">“<span class="quote">non-capturing</span>”</span> set of parentheses)
+ (AREs only) </td></tr><tr><td> <code class="literal">.</code> </td><td> matches any single character </td></tr><tr><td> <code class="literal">[</code><em class="replaceable"><code>chars</code></em><code class="literal">]</code> </td><td> a <em class="firstterm">bracket expression</em>,
+ matching any one of the <em class="replaceable"><code>chars</code></em> (see
+ <a class="xref" href="functions-matching.html#POSIX-BRACKET-EXPRESSIONS" title="9.7.3.2. Bracket Expressions">Section 9.7.3.2</a> for more detail) </td></tr><tr><td> <code class="literal">\</code><em class="replaceable"><code>k</code></em> </td><td> (where <em class="replaceable"><code>k</code></em> is a non-alphanumeric character)
+ matches that character taken as an ordinary character,
+ e.g., <code class="literal">\\</code> matches a backslash character </td></tr><tr><td> <code class="literal">\</code><em class="replaceable"><code>c</code></em> </td><td> where <em class="replaceable"><code>c</code></em> is alphanumeric
+ (possibly followed by other characters)
+ is an <em class="firstterm">escape</em>, see <a class="xref" href="functions-matching.html#POSIX-ESCAPE-SEQUENCES" title="9.7.3.3. Regular Expression Escapes">Section 9.7.3.3</a>
+ (AREs only; in EREs and BREs, this matches <em class="replaceable"><code>c</code></em>) </td></tr><tr><td> <code class="literal">{</code> </td><td> when followed by a character other than a digit,
+ matches the left-brace character <code class="literal">{</code>;
+ when followed by a digit, it is the beginning of a
+ <em class="replaceable"><code>bound</code></em> (see below) </td></tr><tr><td> <em class="replaceable"><code>x</code></em> </td><td> where <em class="replaceable"><code>x</code></em> is a single character with no other
+ significance, matches that character </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ An RE cannot end with a backslash (<code class="literal">\</code>).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If you have <a class="xref" href="runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS">standard_conforming_strings</a> turned off,
+ any backslashes you write in literal string constants will need to be
+ doubled. See <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a> for more information.
+ </p></div><div class="table" id="POSIX-QUANTIFIERS-TABLE"><p class="title"><strong>Table 9.18. Regular Expression Quantifiers</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Quantifiers" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Quantifier</th><th>Matches</th></tr></thead><tbody><tr><td> <code class="literal">*</code> </td><td> a sequence of 0 or more matches of the atom </td></tr><tr><td> <code class="literal">+</code> </td><td> a sequence of 1 or more matches of the atom </td></tr><tr><td> <code class="literal">?</code> </td><td> a sequence of 0 or 1 matches of the atom </td></tr><tr><td> <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">}</code> </td><td> a sequence of exactly <em class="replaceable"><code>m</code></em> matches of the atom </td></tr><tr><td> <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,}</code> </td><td> a sequence of <em class="replaceable"><code>m</code></em> or more matches of the atom </td></tr><tr><td>
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,</code><em class="replaceable"><code>n</code></em><code class="literal">}</code> </td><td> a sequence of <em class="replaceable"><code>m</code></em> through <em class="replaceable"><code>n</code></em>
+ (inclusive) matches of the atom; <em class="replaceable"><code>m</code></em> cannot exceed
+ <em class="replaceable"><code>n</code></em> </td></tr><tr><td> <code class="literal">*?</code> </td><td> non-greedy version of <code class="literal">*</code> </td></tr><tr><td> <code class="literal">+?</code> </td><td> non-greedy version of <code class="literal">+</code> </td></tr><tr><td> <code class="literal">??</code> </td><td> non-greedy version of <code class="literal">?</code> </td></tr><tr><td> <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">}?</code> </td><td> non-greedy version of <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">}</code> </td></tr><tr><td> <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,}?</code> </td><td> non-greedy version of <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,}</code> </td></tr><tr><td>
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,</code><em class="replaceable"><code>n</code></em><code class="literal">}?</code> </td><td> non-greedy version of <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,</code><em class="replaceable"><code>n</code></em><code class="literal">}</code> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The forms using <code class="literal">{</code><em class="replaceable"><code>...</code></em><code class="literal">}</code>
+ are known as <em class="firstterm">bounds</em>.
+ The numbers <em class="replaceable"><code>m</code></em> and <em class="replaceable"><code>n</code></em> within a bound are
+ unsigned decimal integers with permissible values from 0 to 255 inclusive.
+ </p><p>
+ <em class="firstterm">Non-greedy</em> quantifiers (available in AREs only) match the
+ same possibilities as their corresponding normal (<em class="firstterm">greedy</em>)
+ counterparts, but prefer the smallest number rather than the largest
+ number of matches.
+ See <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a> for more detail.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ A quantifier cannot immediately follow another quantifier, e.g.,
+ <code class="literal">**</code> is invalid.
+ A quantifier cannot
+ begin an expression or subexpression or follow
+ <code class="literal">^</code> or <code class="literal">|</code>.
+ </p></div><div class="table" id="POSIX-CONSTRAINTS-TABLE"><p class="title"><strong>Table 9.19. Regular Expression Constraints</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Constraints" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Constraint</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">^</code> </td><td> matches at the beginning of the string </td></tr><tr><td> <code class="literal">$</code> </td><td> matches at the end of the string </td></tr><tr><td> <code class="literal">(?=</code><em class="replaceable"><code>re</code></em><code class="literal">)</code> </td><td> <em class="firstterm">positive lookahead</em> matches at any point
+ where a substring matching <em class="replaceable"><code>re</code></em> begins
+ (AREs only) </td></tr><tr><td> <code class="literal">(?!</code><em class="replaceable"><code>re</code></em><code class="literal">)</code> </td><td> <em class="firstterm">negative lookahead</em> matches at any point
+ where no substring matching <em class="replaceable"><code>re</code></em> begins
+ (AREs only) </td></tr><tr><td> <code class="literal">(?&lt;=</code><em class="replaceable"><code>re</code></em><code class="literal">)</code> </td><td> <em class="firstterm">positive lookbehind</em> matches at any point
+ where a substring matching <em class="replaceable"><code>re</code></em> ends
+ (AREs only) </td></tr><tr><td> <code class="literal">(?&lt;!</code><em class="replaceable"><code>re</code></em><code class="literal">)</code> </td><td> <em class="firstterm">negative lookbehind</em> matches at any point
+ where no substring matching <em class="replaceable"><code>re</code></em> ends
+ (AREs only) </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Lookahead and lookbehind constraints cannot contain <em class="firstterm">back
+ references</em> (see <a class="xref" href="functions-matching.html#POSIX-ESCAPE-SEQUENCES" title="9.7.3.3. Regular Expression Escapes">Section 9.7.3.3</a>),
+ and all parentheses within them are considered non-capturing.
+ </p></div><div class="sect3" id="POSIX-BRACKET-EXPRESSIONS"><div class="titlepage"><div><div><h4 class="title">9.7.3.2. Bracket Expressions</h4></div></div></div><p>
+ A <em class="firstterm">bracket expression</em> is a list of
+ characters enclosed in <code class="literal">[]</code>. It normally matches
+ any single character from the list (but see below). If the list
+ begins with <code class="literal">^</code>, it matches any single character
+ <span class="emphasis"><em>not</em></span> from the rest of the list.
+ If two characters
+ in the list are separated by <code class="literal">-</code>, this is
+ shorthand for the full range of characters between those two
+ (inclusive) in the collating sequence,
+ e.g., <code class="literal">[0-9]</code> in <acronym class="acronym">ASCII</acronym> matches
+ any decimal digit. It is illegal for two ranges to share an
+ endpoint, e.g., <code class="literal">a-c-e</code>. Ranges are very
+ collating-sequence-dependent, so portable programs should avoid
+ relying on them.
+ </p><p>
+ To include a literal <code class="literal">]</code> in the list, make it the
+ first character (after <code class="literal">^</code>, if that is used). To
+ include a literal <code class="literal">-</code>, make it the first or last
+ character, or the second endpoint of a range. To use a literal
+ <code class="literal">-</code> as the first endpoint of a range, enclose it
+ in <code class="literal">[.</code> and <code class="literal">.]</code> to make it a
+ collating element (see below). With the exception of these characters,
+ some combinations using <code class="literal">[</code>
+ (see next paragraphs), and escapes (AREs only), all other special
+ characters lose their special significance within a bracket expression.
+ In particular, <code class="literal">\</code> is not special when following
+ ERE or BRE rules, though it is special (as introducing an escape)
+ in AREs.
+ </p><p>
+ Within a bracket expression, a collating element (a character, a
+ multiple-character sequence that collates as if it were a single
+ character, or a collating-sequence name for either) enclosed in
+ <code class="literal">[.</code> and <code class="literal">.]</code> stands for the
+ sequence of characters of that collating element. The sequence is
+ treated as a single element of the bracket expression's list. This
+ allows a bracket
+ expression containing a multiple-character collating element to
+ match more than one character, e.g., if the collating sequence
+ includes a <code class="literal">ch</code> collating element, then the RE
+ <code class="literal">[[.ch.]]*c</code> matches the first five characters of
+ <code class="literal">chchcc</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> currently does not support multi-character collating
+ elements. This information describes possible future behavior.
+ </p></div><p>
+ Within a bracket expression, a collating element enclosed in
+ <code class="literal">[=</code> and <code class="literal">=]</code> is an <em class="firstterm">equivalence
+ class</em>, standing for the sequences of characters of all collating
+ elements equivalent to that one, including itself. (If there are
+ no other equivalent collating elements, the treatment is as if the
+ enclosing delimiters were <code class="literal">[.</code> and
+ <code class="literal">.]</code>.) For example, if <code class="literal">o</code> and
+ <code class="literal">^</code> are the members of an equivalence class, then
+ <code class="literal">[[=o=]]</code>, <code class="literal">[[=^=]]</code>, and
+ <code class="literal">[o^]</code> are all synonymous. An equivalence class
+ cannot be an endpoint of a range.
+ </p><p>
+ Within a bracket expression, the name of a character class
+ enclosed in <code class="literal">[:</code> and <code class="literal">:]</code> stands
+ for the list of all characters belonging to that class. A character
+ class cannot be used as an endpoint of a range.
+ The <acronym class="acronym">POSIX</acronym> standard defines these character class
+ names:
+ <code class="literal">alnum</code> (letters and numeric digits),
+ <code class="literal">alpha</code> (letters),
+ <code class="literal">blank</code> (space and tab),
+ <code class="literal">cntrl</code> (control characters),
+ <code class="literal">digit</code> (numeric digits),
+ <code class="literal">graph</code> (printable characters except space),
+ <code class="literal">lower</code> (lower-case letters),
+ <code class="literal">print</code> (printable characters including space),
+ <code class="literal">punct</code> (punctuation),
+ <code class="literal">space</code> (any white space),
+ <code class="literal">upper</code> (upper-case letters),
+ and <code class="literal">xdigit</code> (hexadecimal digits).
+ The behavior of these standard character classes is generally
+ consistent across platforms for characters in the 7-bit ASCII set.
+ Whether a given non-ASCII character is considered to belong to one
+ of these classes depends on the <em class="firstterm">collation</em>
+ that is used for the regular-expression function or operator
+ (see <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>), or by default on the
+ database's <code class="envar">LC_CTYPE</code> locale setting (see
+ <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a>). The classification of non-ASCII
+ characters can vary across platforms even in similarly-named
+ locales. (But the <code class="literal">C</code> locale never considers any
+ non-ASCII characters to belong to any of these classes.)
+ In addition to these standard character
+ classes, <span class="productname">PostgreSQL</span> defines
+ the <code class="literal">word</code> character class, which is the same as
+ <code class="literal">alnum</code> plus the underscore (<code class="literal">_</code>)
+ character, and
+ the <code class="literal">ascii</code> character class, which contains exactly
+ the 7-bit ASCII set.
+ </p><p>
+ There are two special cases of bracket expressions: the bracket
+ expressions <code class="literal">[[:&lt;:]]</code> and
+ <code class="literal">[[:&gt;:]]</code> are constraints,
+ matching empty strings at the beginning
+ and end of a word respectively. A word is defined as a sequence
+ of word characters that is neither preceded nor followed by word
+ characters. A word character is any character belonging to the
+ <code class="literal">word</code> character class, that is, any letter, digit,
+ or underscore. This is an extension, compatible with but not
+ specified by <acronym class="acronym">POSIX</acronym> 1003.2, and should be used with
+ caution in software intended to be portable to other systems.
+ The constraint escapes described below are usually preferable; they
+ are no more standard, but are easier to type.
+ </p></div><div class="sect3" id="POSIX-ESCAPE-SEQUENCES"><div class="titlepage"><div><div><h4 class="title">9.7.3.3. Regular Expression Escapes</h4></div></div></div><p>
+ <em class="firstterm">Escapes</em> are special sequences beginning with <code class="literal">\</code>
+ followed by an alphanumeric character. Escapes come in several varieties:
+ character entry, class shorthands, constraint escapes, and back references.
+ A <code class="literal">\</code> followed by an alphanumeric character but not constituting
+ a valid escape is illegal in AREs.
+ In EREs, there are no escapes: outside a bracket expression,
+ a <code class="literal">\</code> followed by an alphanumeric character merely stands for
+ that character as an ordinary character, and inside a bracket expression,
+ <code class="literal">\</code> is an ordinary character.
+ (The latter is the one actual incompatibility between EREs and AREs.)
+ </p><p>
+ <em class="firstterm">Character-entry escapes</em> exist to make it easier to specify
+ non-printing and other inconvenient characters in REs. They are
+ shown in <a class="xref" href="functions-matching.html#POSIX-CHARACTER-ENTRY-ESCAPES-TABLE" title="Table 9.20. Regular Expression Character-Entry Escapes">Table 9.20</a>.
+ </p><p>
+ <em class="firstterm">Class-shorthand escapes</em> provide shorthands for certain
+ commonly-used character classes. They are
+ shown in <a class="xref" href="functions-matching.html#POSIX-CLASS-SHORTHAND-ESCAPES-TABLE" title="Table 9.21. Regular Expression Class-Shorthand Escapes">Table 9.21</a>.
+ </p><p>
+ A <em class="firstterm">constraint escape</em> is a constraint,
+ matching the empty string if specific conditions are met,
+ written as an escape. They are
+ shown in <a class="xref" href="functions-matching.html#POSIX-CONSTRAINT-ESCAPES-TABLE" title="Table 9.22. Regular Expression Constraint Escapes">Table 9.22</a>.
+ </p><p>
+ A <em class="firstterm">back reference</em> (<code class="literal">\</code><em class="replaceable"><code>n</code></em>) matches the
+ same string matched by the previous parenthesized subexpression specified
+ by the number <em class="replaceable"><code>n</code></em>
+ (see <a class="xref" href="functions-matching.html#POSIX-CONSTRAINT-BACKREF-TABLE" title="Table 9.23. Regular Expression Back References">Table 9.23</a>). For example,
+ <code class="literal">([bc])\1</code> matches <code class="literal">bb</code> or <code class="literal">cc</code>
+ but not <code class="literal">bc</code> or <code class="literal">cb</code>.
+ The subexpression must entirely precede the back reference in the RE.
+ Subexpressions are numbered in the order of their leading parentheses.
+ Non-capturing parentheses do not define subexpressions.
+ The back reference considers only the string characters matched by the
+ referenced subexpression, not any constraints contained in it. For
+ example, <code class="literal">(^\d)\1</code> will match <code class="literal">22</code>.
+ </p><div class="table" id="POSIX-CHARACTER-ENTRY-ESCAPES-TABLE"><p class="title"><strong>Table 9.20. Regular Expression Character-Entry Escapes</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Character-Entry Escapes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Escape</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">\a</code> </td><td> alert (bell) character, as in C </td></tr><tr><td> <code class="literal">\b</code> </td><td> backspace, as in C </td></tr><tr><td> <code class="literal">\B</code> </td><td> synonym for backslash (<code class="literal">\</code>) to help reduce the need for backslash
+ doubling </td></tr><tr><td> <code class="literal">\c</code><em class="replaceable"><code>X</code></em> </td><td> (where <em class="replaceable"><code>X</code></em> is any character) the character whose
+ low-order 5 bits are the same as those of
+ <em class="replaceable"><code>X</code></em>, and whose other bits are all zero </td></tr><tr><td> <code class="literal">\e</code> </td><td> the character whose collating-sequence name
+ is <code class="literal">ESC</code>,
+ or failing that, the character with octal value <code class="literal">033</code> </td></tr><tr><td> <code class="literal">\f</code> </td><td> form feed, as in C </td></tr><tr><td> <code class="literal">\n</code> </td><td> newline, as in C </td></tr><tr><td> <code class="literal">\r</code> </td><td> carriage return, as in C </td></tr><tr><td> <code class="literal">\t</code> </td><td> horizontal tab, as in C </td></tr><tr><td> <code class="literal">\u</code><em class="replaceable"><code>wxyz</code></em> </td><td> (where <em class="replaceable"><code>wxyz</code></em> is exactly four hexadecimal digits)
+ the character whose hexadecimal value is
+ <code class="literal">0x</code><em class="replaceable"><code>wxyz</code></em>
+ </td></tr><tr><td> <code class="literal">\U</code><em class="replaceable"><code>stuvwxyz</code></em> </td><td> (where <em class="replaceable"><code>stuvwxyz</code></em> is exactly eight hexadecimal
+ digits)
+ the character whose hexadecimal value is
+ <code class="literal">0x</code><em class="replaceable"><code>stuvwxyz</code></em>
+ </td></tr><tr><td> <code class="literal">\v</code> </td><td> vertical tab, as in C </td></tr><tr><td> <code class="literal">\x</code><em class="replaceable"><code>hhh</code></em> </td><td> (where <em class="replaceable"><code>hhh</code></em> is any sequence of hexadecimal
+ digits)
+ the character whose hexadecimal value is
+ <code class="literal">0x</code><em class="replaceable"><code>hhh</code></em>
+ (a single character no matter how many hexadecimal digits are used)
+ </td></tr><tr><td> <code class="literal">\0</code> </td><td> the character whose value is <code class="literal">0</code> (the null byte)</td></tr><tr><td> <code class="literal">\</code><em class="replaceable"><code>xy</code></em> </td><td> (where <em class="replaceable"><code>xy</code></em> is exactly two octal digits,
+ and is not a <em class="firstterm">back reference</em>)
+ the character whose octal value is
+ <code class="literal">0</code><em class="replaceable"><code>xy</code></em> </td></tr><tr><td> <code class="literal">\</code><em class="replaceable"><code>xyz</code></em> </td><td> (where <em class="replaceable"><code>xyz</code></em> is exactly three octal digits,
+ and is not a <em class="firstterm">back reference</em>)
+ the character whose octal value is
+ <code class="literal">0</code><em class="replaceable"><code>xyz</code></em> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Hexadecimal digits are <code class="literal">0</code>-<code class="literal">9</code>,
+ <code class="literal">a</code>-<code class="literal">f</code>, and <code class="literal">A</code>-<code class="literal">F</code>.
+ Octal digits are <code class="literal">0</code>-<code class="literal">7</code>.
+ </p><p>
+ Numeric character-entry escapes specifying values outside the ASCII range
+ (0–127) have meanings dependent on the database encoding. When the
+ encoding is UTF-8, escape values are equivalent to Unicode code points,
+ for example <code class="literal">\u1234</code> means the character <code class="literal">U+1234</code>.
+ For other multibyte encodings, character-entry escapes usually just
+ specify the concatenation of the byte values for the character. If the
+ escape value does not correspond to any legal character in the database
+ encoding, no error will be raised, but it will never match any data.
+ </p><p>
+ The character-entry escapes are always taken as ordinary characters.
+ For example, <code class="literal">\135</code> is <code class="literal">]</code> in ASCII, but
+ <code class="literal">\135</code> does not terminate a bracket expression.
+ </p><div class="table" id="POSIX-CLASS-SHORTHAND-ESCAPES-TABLE"><p class="title"><strong>Table 9.21. Regular Expression Class-Shorthand Escapes</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Class-Shorthand Escapes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Escape</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">\d</code> </td><td> matches any digit, like
+ <code class="literal">[[:digit:]]</code> </td></tr><tr><td> <code class="literal">\s</code> </td><td> matches any whitespace character, like
+ <code class="literal">[[:space:]]</code> </td></tr><tr><td> <code class="literal">\w</code> </td><td> matches any word character, like
+ <code class="literal">[[:word:]]</code> </td></tr><tr><td> <code class="literal">\D</code> </td><td> matches any non-digit, like
+ <code class="literal">[^[:digit:]]</code> </td></tr><tr><td> <code class="literal">\S</code> </td><td> matches any non-whitespace character, like
+ <code class="literal">[^[:space:]]</code> </td></tr><tr><td> <code class="literal">\W</code> </td><td> matches any non-word character, like
+ <code class="literal">[^[:word:]]</code> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The class-shorthand escapes also work within bracket expressions,
+ although the definitions shown above are not quite syntactically
+ valid in that context.
+ For example, <code class="literal">[a-c\d]</code> is equivalent to
+ <code class="literal">[a-c[:digit:]]</code>.
+ </p><div class="table" id="POSIX-CONSTRAINT-ESCAPES-TABLE"><p class="title"><strong>Table 9.22. Regular Expression Constraint Escapes</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Constraint Escapes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Escape</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">\A</code> </td><td> matches only at the beginning of the string
+ (see <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a> for how this differs from
+ <code class="literal">^</code>) </td></tr><tr><td> <code class="literal">\m</code> </td><td> matches only at the beginning of a word </td></tr><tr><td> <code class="literal">\M</code> </td><td> matches only at the end of a word </td></tr><tr><td> <code class="literal">\y</code> </td><td> matches only at the beginning or end of a word </td></tr><tr><td> <code class="literal">\Y</code> </td><td> matches only at a point that is not the beginning or end of a
+ word </td></tr><tr><td> <code class="literal">\Z</code> </td><td> matches only at the end of the string
+ (see <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a> for how this differs from
+ <code class="literal">$</code>) </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ A word is defined as in the specification of
+ <code class="literal">[[:&lt;:]]</code> and <code class="literal">[[:&gt;:]]</code> above.
+ Constraint escapes are illegal within bracket expressions.
+ </p><div class="table" id="POSIX-CONSTRAINT-BACKREF-TABLE"><p class="title"><strong>Table 9.23. Regular Expression Back References</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Back References" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Escape</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">\</code><em class="replaceable"><code>m</code></em> </td><td> (where <em class="replaceable"><code>m</code></em> is a nonzero digit)
+ a back reference to the <em class="replaceable"><code>m</code></em>'th subexpression </td></tr><tr><td> <code class="literal">\</code><em class="replaceable"><code>mnn</code></em> </td><td> (where <em class="replaceable"><code>m</code></em> is a nonzero digit, and
+ <em class="replaceable"><code>nn</code></em> is some more digits, and the decimal value
+ <em class="replaceable"><code>mnn</code></em> is not greater than the number of closing capturing
+ parentheses seen so far)
+ a back reference to the <em class="replaceable"><code>mnn</code></em>'th subexpression </td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ There is an inherent ambiguity between octal character-entry
+ escapes and back references, which is resolved by the following heuristics,
+ as hinted at above.
+ A leading zero always indicates an octal escape.
+ A single non-zero digit, not followed by another digit,
+ is always taken as a back reference.
+ A multi-digit sequence not starting with a zero is taken as a back
+ reference if it comes after a suitable subexpression
+ (i.e., the number is in the legal range for a back reference),
+ and otherwise is taken as octal.
+ </p></div></div><div class="sect3" id="POSIX-METASYNTAX"><div class="titlepage"><div><div><h4 class="title">9.7.3.4. Regular Expression Metasyntax</h4></div></div></div><p>
+ In addition to the main syntax described above, there are some special
+ forms and miscellaneous syntactic facilities available.
+ </p><p>
+ An RE can begin with one of two special <em class="firstterm">director</em> prefixes.
+ If an RE begins with <code class="literal">***:</code>,
+ the rest of the RE is taken as an ARE. (This normally has no effect in
+ <span class="productname">PostgreSQL</span>, since REs are assumed to be AREs;
+ but it does have an effect if ERE or BRE mode had been specified by
+ the <em class="replaceable"><code>flags</code></em> parameter to a regex function.)
+ If an RE begins with <code class="literal">***=</code>,
+ the rest of the RE is taken to be a literal string,
+ with all characters considered ordinary characters.
+ </p><p>
+ An ARE can begin with <em class="firstterm">embedded options</em>:
+ a sequence <code class="literal">(?</code><em class="replaceable"><code>xyz</code></em><code class="literal">)</code>
+ (where <em class="replaceable"><code>xyz</code></em> is one or more alphabetic characters)
+ specifies options affecting the rest of the RE.
+ These options override any previously determined options —
+ in particular, they can override the case-sensitivity behavior implied by
+ a regex operator, or the <em class="replaceable"><code>flags</code></em> parameter to a regex
+ function.
+ The available option letters are
+ shown in <a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>.
+ Note that these same option letters are used in the <em class="replaceable"><code>flags</code></em>
+ parameters of regex functions.
+ </p><div class="table" id="POSIX-EMBEDDED-OPTIONS-TABLE"><p class="title"><strong>Table 9.24. ARE Embedded-Option Letters</strong></p><div class="table-contents"><table class="table" summary="ARE Embedded-Option Letters" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Option</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">b</code> </td><td> rest of RE is a BRE </td></tr><tr><td> <code class="literal">c</code> </td><td> case-sensitive matching (overrides operator type) </td></tr><tr><td> <code class="literal">e</code> </td><td> rest of RE is an ERE </td></tr><tr><td> <code class="literal">i</code> </td><td> case-insensitive matching (see
+ <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a>) (overrides operator type) </td></tr><tr><td> <code class="literal">m</code> </td><td> historical synonym for <code class="literal">n</code> </td></tr><tr><td> <code class="literal">n</code> </td><td> newline-sensitive matching (see
+ <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a>) </td></tr><tr><td> <code class="literal">p</code> </td><td> partial newline-sensitive matching (see
+ <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a>) </td></tr><tr><td> <code class="literal">q</code> </td><td> rest of RE is a literal (<span class="quote">“<span class="quote">quoted</span>”</span>) string, all ordinary
+ characters </td></tr><tr><td> <code class="literal">s</code> </td><td> non-newline-sensitive matching (default) </td></tr><tr><td> <code class="literal">t</code> </td><td> tight syntax (default; see below) </td></tr><tr><td> <code class="literal">w</code> </td><td> inverse partial newline-sensitive (<span class="quote">“<span class="quote">weird</span>”</span>) matching
+ (see <a class="xref" href="functions-matching.html#POSIX-MATCHING-RULES" title="9.7.3.5. Regular Expression Matching Rules">Section 9.7.3.5</a>) </td></tr><tr><td> <code class="literal">x</code> </td><td> expanded syntax (see below) </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Embedded options take effect at the <code class="literal">)</code> terminating the sequence.
+ They can appear only at the start of an ARE (after the
+ <code class="literal">***:</code> director if any).
+ </p><p>
+ In addition to the usual (<em class="firstterm">tight</em>) RE syntax, in which all
+ characters are significant, there is an <em class="firstterm">expanded</em> syntax,
+ available by specifying the embedded <code class="literal">x</code> option.
+ In the expanded syntax,
+ white-space characters in the RE are ignored, as are
+ all characters between a <code class="literal">#</code>
+ and the following newline (or the end of the RE). This
+ permits paragraphing and commenting a complex RE.
+ There are three exceptions to that basic rule:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ a white-space character or <code class="literal">#</code> preceded by <code class="literal">\</code> is
+ retained
+ </p></li><li class="listitem"><p>
+ white space or <code class="literal">#</code> within a bracket expression is retained
+ </p></li><li class="listitem"><p>
+ white space and comments cannot appear within multi-character symbols,
+ such as <code class="literal">(?:</code>
+ </p></li></ul></div><p>
+
+ For this purpose, white-space characters are blank, tab, newline, and
+ any character that belongs to the <em class="replaceable"><code>space</code></em> character class.
+ </p><p>
+ Finally, in an ARE, outside bracket expressions, the sequence
+ <code class="literal">(?#</code><em class="replaceable"><code>ttt</code></em><code class="literal">)</code>
+ (where <em class="replaceable"><code>ttt</code></em> is any text not containing a <code class="literal">)</code>)
+ is a comment, completely ignored.
+ Again, this is not allowed between the characters of
+ multi-character symbols, like <code class="literal">(?:</code>.
+ Such comments are more a historical artifact than a useful facility,
+ and their use is deprecated; use the expanded syntax instead.
+ </p><p>
+ <span class="emphasis"><em>None</em></span> of these metasyntax extensions is available if
+ an initial <code class="literal">***=</code> director
+ has specified that the user's input be treated as a literal string
+ rather than as an RE.
+ </p></div><div class="sect3" id="POSIX-MATCHING-RULES"><div class="titlepage"><div><div><h4 class="title">9.7.3.5. Regular Expression Matching Rules</h4></div></div></div><p>
+ In the event that an RE could match more than one substring of a given
+ string, the RE matches the one starting earliest in the string.
+ If the RE could match more than one substring starting at that point,
+ either the longest possible match or the shortest possible match will
+ be taken, depending on whether the RE is <em class="firstterm">greedy</em> or
+ <em class="firstterm">non-greedy</em>.
+ </p><p>
+ Whether an RE is greedy or not is determined by the following rules:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Most atoms, and all constraints, have no greediness attribute (because
+ they cannot match variable amounts of text anyway).
+ </p></li><li class="listitem"><p>
+ Adding parentheses around an RE does not change its greediness.
+ </p></li><li class="listitem"><p>
+ A quantified atom with a fixed-repetition quantifier
+ (<code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">}</code>
+ or
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">}?</code>)
+ has the same greediness (possibly none) as the atom itself.
+ </p></li><li class="listitem"><p>
+ A quantified atom with other normal quantifiers (including
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,</code><em class="replaceable"><code>n</code></em><code class="literal">}</code>
+ with <em class="replaceable"><code>m</code></em> equal to <em class="replaceable"><code>n</code></em>)
+ is greedy (prefers longest match).
+ </p></li><li class="listitem"><p>
+ A quantified atom with a non-greedy quantifier (including
+ <code class="literal">{</code><em class="replaceable"><code>m</code></em><code class="literal">,</code><em class="replaceable"><code>n</code></em><code class="literal">}?</code>
+ with <em class="replaceable"><code>m</code></em> equal to <em class="replaceable"><code>n</code></em>)
+ is non-greedy (prefers shortest match).
+ </p></li><li class="listitem"><p>
+ A branch — that is, an RE that has no top-level
+ <code class="literal">|</code> operator — has the same greediness as the first
+ quantified atom in it that has a greediness attribute.
+ </p></li><li class="listitem"><p>
+ An RE consisting of two or more branches connected by the
+ <code class="literal">|</code> operator is always greedy.
+ </p></li></ul></div><p>
+ </p><p>
+ The above rules associate greediness attributes not only with individual
+ quantified atoms, but with branches and entire REs that contain quantified
+ atoms. What that means is that the matching is done in such a way that
+ the branch, or whole RE, matches the longest or shortest possible
+ substring <span class="emphasis"><em>as a whole</em></span>. Once the length of the entire match
+ is determined, the part of it that matches any particular subexpression
+ is determined on the basis of the greediness attribute of that
+ subexpression, with subexpressions starting earlier in the RE taking
+ priority over ones starting later.
+ </p><p>
+ An example of what this means:
+</p><pre class="screen">
+SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">123</code>
+SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">1</code>
+</pre><p>
+ In the first case, the RE as a whole is greedy because <code class="literal">Y*</code>
+ is greedy. It can match beginning at the <code class="literal">Y</code>, and it matches
+ the longest possible string starting there, i.e., <code class="literal">Y123</code>.
+ The output is the parenthesized part of that, or <code class="literal">123</code>.
+ In the second case, the RE as a whole is non-greedy because <code class="literal">Y*?</code>
+ is non-greedy. It can match beginning at the <code class="literal">Y</code>, and it matches
+ the shortest possible string starting there, i.e., <code class="literal">Y1</code>.
+ The subexpression <code class="literal">[0-9]{1,3}</code> is greedy but it cannot change
+ the decision as to the overall match length; so it is forced to match
+ just <code class="literal">1</code>.
+ </p><p>
+ In short, when an RE contains both greedy and non-greedy subexpressions,
+ the total match length is either as long as possible or as short as
+ possible, according to the attribute assigned to the whole RE. The
+ attributes assigned to the subexpressions only affect how much of that
+ match they are allowed to <span class="quote">“<span class="quote">eat</span>”</span> relative to each other.
+ </p><p>
+ The quantifiers <code class="literal">{1,1}</code> and <code class="literal">{1,1}?</code>
+ can be used to force greediness or non-greediness, respectively,
+ on a subexpression or a whole RE.
+ This is useful when you need the whole RE to have a greediness attribute
+ different from what's deduced from its elements. As an example,
+ suppose that we are trying to separate a string containing some digits
+ into the digits and the parts before and after them. We might try to
+ do that like this:
+</p><pre class="screen">
+SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">{abc0123,4,xyz}</code>
+</pre><p>
+ That didn't work: the first <code class="literal">.*</code> is greedy so
+ it <span class="quote">“<span class="quote">eats</span>”</span> as much as it can, leaving the <code class="literal">\d+</code> to
+ match at the last possible place, the last digit. We might try to fix
+ that by making it non-greedy:
+</p><pre class="screen">
+SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">{abc,0,""}</code>
+</pre><p>
+ That didn't work either, because now the RE as a whole is non-greedy
+ and so it ends the overall match as soon as possible. We can get what
+ we want by forcing the RE as a whole to be greedy:
+</p><pre class="screen">
+SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">{abc,01234,xyz}</code>
+</pre><p>
+ Controlling the RE's overall greediness separately from its components'
+ greediness allows great flexibility in handling variable-length patterns.
+ </p><p>
+ When deciding what is a longer or shorter match,
+ match lengths are measured in characters, not collating elements.
+ An empty string is considered longer than no match at all.
+ For example:
+ <code class="literal">bb*</code>
+ matches the three middle characters of <code class="literal">abbbc</code>;
+ <code class="literal">(week|wee)(night|knights)</code>
+ matches all ten characters of <code class="literal">weeknights</code>;
+ when <code class="literal">(.*).*</code>
+ is matched against <code class="literal">abc</code> the parenthesized subexpression
+ matches all three characters; and when
+ <code class="literal">(a*)*</code> is matched against <code class="literal">bc</code>
+ both the whole RE and the parenthesized
+ subexpression match an empty string.
+ </p><p>
+ If case-independent matching is specified,
+ the effect is much as if all case distinctions had vanished from the
+ alphabet.
+ When an alphabetic that exists in multiple cases appears as an
+ ordinary character outside a bracket expression, it is effectively
+ transformed into a bracket expression containing both cases,
+ e.g., <code class="literal">x</code> becomes <code class="literal">[xX]</code>.
+ When it appears inside a bracket expression, all case counterparts
+ of it are added to the bracket expression, e.g.,
+ <code class="literal">[x]</code> becomes <code class="literal">[xX]</code>
+ and <code class="literal">[^x]</code> becomes <code class="literal">[^xX]</code>.
+ </p><p>
+ If newline-sensitive matching is specified, <code class="literal">.</code>
+ and bracket expressions using <code class="literal">^</code>
+ will never match the newline character
+ (so that matches will not cross lines unless the RE
+ explicitly includes a newline)
+ and <code class="literal">^</code> and <code class="literal">$</code>
+ will match the empty string after and before a newline
+ respectively, in addition to matching at beginning and end of string
+ respectively.
+ But the ARE escapes <code class="literal">\A</code> and <code class="literal">\Z</code>
+ continue to match beginning or end of string <span class="emphasis"><em>only</em></span>.
+ Also, the character class shorthands <code class="literal">\D</code>
+ and <code class="literal">\W</code> will match a newline regardless of this mode.
+ (Before <span class="productname">PostgreSQL</span> 14, they did not match
+ newlines when in newline-sensitive mode.
+ Write <code class="literal">[^[:digit:]]</code>
+ or <code class="literal">[^[:word:]]</code> to get the old behavior.)
+ </p><p>
+ If partial newline-sensitive matching is specified,
+ this affects <code class="literal">.</code> and bracket expressions
+ as with newline-sensitive matching, but not <code class="literal">^</code>
+ and <code class="literal">$</code>.
+ </p><p>
+ If inverse partial newline-sensitive matching is specified,
+ this affects <code class="literal">^</code> and <code class="literal">$</code>
+ as with newline-sensitive matching, but not <code class="literal">.</code>
+ and bracket expressions.
+ This isn't very useful but is provided for symmetry.
+ </p></div><div class="sect3" id="POSIX-LIMITS-COMPATIBILITY"><div class="titlepage"><div><div><h4 class="title">9.7.3.6. Limits and Compatibility</h4></div></div></div><p>
+ No particular limit is imposed on the length of REs in this
+ implementation. However,
+ programs intended to be highly portable should not employ REs longer
+ than 256 bytes,
+ as a POSIX-compliant implementation can refuse to accept such REs.
+ </p><p>
+ The only feature of AREs that is actually incompatible with
+ POSIX EREs is that <code class="literal">\</code> does not lose its special
+ significance inside bracket expressions.
+ All other ARE features use syntax which is illegal or has
+ undefined or unspecified effects in POSIX EREs;
+ the <code class="literal">***</code> syntax of directors likewise is outside the POSIX
+ syntax for both BREs and EREs.
+ </p><p>
+ Many of the ARE extensions are borrowed from Perl, but some have
+ been changed to clean them up, and a few Perl extensions are not present.
+ Incompatibilities of note include <code class="literal">\b</code>, <code class="literal">\B</code>,
+ the lack of special treatment for a trailing newline,
+ the addition of complemented bracket expressions to the things
+ affected by newline-sensitive matching,
+ the restrictions on parentheses and back references in lookahead/lookbehind
+ constraints, and the longest/shortest-match (rather than first-match)
+ matching semantics.
+ </p></div><div class="sect3" id="POSIX-BASIC-REGEXES"><div class="titlepage"><div><div><h4 class="title">9.7.3.7. Basic Regular Expressions</h4></div></div></div><p>
+ BREs differ from EREs in several respects.
+ In BREs, <code class="literal">|</code>, <code class="literal">+</code>, and <code class="literal">?</code>
+ are ordinary characters and there is no equivalent
+ for their functionality.
+ The delimiters for bounds are
+ <code class="literal">\{</code> and <code class="literal">\}</code>,
+ with <code class="literal">{</code> and <code class="literal">}</code>
+ by themselves ordinary characters.
+ The parentheses for nested subexpressions are
+ <code class="literal">\(</code> and <code class="literal">\)</code>,
+ with <code class="literal">(</code> and <code class="literal">)</code> by themselves ordinary characters.
+ <code class="literal">^</code> is an ordinary character except at the beginning of the
+ RE or the beginning of a parenthesized subexpression,
+ <code class="literal">$</code> is an ordinary character except at the end of the
+ RE or the end of a parenthesized subexpression,
+ and <code class="literal">*</code> is an ordinary character if it appears at the beginning
+ of the RE or the beginning of a parenthesized subexpression
+ (after a possible leading <code class="literal">^</code>).
+ Finally, single-digit back references are available, and
+ <code class="literal">\&lt;</code> and <code class="literal">\&gt;</code>
+ are synonyms for
+ <code class="literal">[[:&lt;:]]</code> and <code class="literal">[[:&gt;:]]</code>
+ respectively; no other escapes are available in BREs.
+ </p></div><div class="sect3" id="POSIX-VS-XQUERY"><div class="titlepage"><div><div><h4 class="title">9.7.3.8. Differences from SQL Standard and XQuery</h4></div></div></div><a id="id-1.5.8.13.9.48.2" class="indexterm"></a><a id="id-1.5.8.13.9.48.3" class="indexterm"></a><a id="id-1.5.8.13.9.48.4" class="indexterm"></a><a id="id-1.5.8.13.9.48.5" class="indexterm"></a><a id="id-1.5.8.13.9.48.6" class="indexterm"></a><a id="id-1.5.8.13.9.48.7" class="indexterm"></a><p>
+ Since SQL:2008, the SQL standard includes regular expression operators
+ and functions that performs pattern
+ matching according to the XQuery regular expression
+ standard:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">LIKE_REGEX</code></p></li><li class="listitem"><p><code class="literal">OCCURRENCES_REGEX</code></p></li><li class="listitem"><p><code class="literal">POSITION_REGEX</code></p></li><li class="listitem"><p><code class="literal">SUBSTRING_REGEX</code></p></li><li class="listitem"><p><code class="literal">TRANSLATE_REGEX</code></p></li></ul></div><p>
+ <span class="productname">PostgreSQL</span> does not currently implement these
+ operators and functions. You can get approximately equivalent
+ functionality in each case as shown in <a class="xref" href="functions-matching.html#FUNCTIONS-REGEXP-SQL-TABLE" title="Table 9.25. Regular Expression Functions Equivalencies">Table 9.25</a>. (Various optional clauses on
+ both sides have been omitted in this table.)
+ </p><div class="table" id="FUNCTIONS-REGEXP-SQL-TABLE"><p class="title"><strong>Table 9.25. Regular Expression Functions Equivalencies</strong></p><div class="table-contents"><table class="table" summary="Regular Expression Functions Equivalencies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>SQL standard</th><th>PostgreSQL</th></tr></thead><tbody><tr><td><code class="literal"><em class="replaceable"><code>string</code></em> LIKE_REGEX <em class="replaceable"><code>pattern</code></em></code></td><td><code class="literal">regexp_like(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>)</code> or <code class="literal"><em class="replaceable"><code>string</code></em> ~ <em class="replaceable"><code>pattern</code></em></code></td></tr><tr><td><code class="literal">OCCURRENCES_REGEX(<em class="replaceable"><code>pattern</code></em> IN <em class="replaceable"><code>string</code></em>)</code></td><td><code class="literal">regexp_count(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>)</code></td></tr><tr><td><code class="literal">POSITION_REGEX(<em class="replaceable"><code>pattern</code></em> IN <em class="replaceable"><code>string</code></em>)</code></td><td><code class="literal">regexp_instr(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>)</code></td></tr><tr><td><code class="literal">SUBSTRING_REGEX(<em class="replaceable"><code>pattern</code></em> IN <em class="replaceable"><code>string</code></em>)</code></td><td><code class="literal">regexp_substr(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>)</code></td></tr><tr><td><code class="literal">TRANSLATE_REGEX(<em class="replaceable"><code>pattern</code></em> IN <em class="replaceable"><code>string</code></em> WITH <em class="replaceable"><code>replacement</code></em>)</code></td><td><code class="literal">regexp_replace(<em class="replaceable"><code>string</code></em>, <em class="replaceable"><code>pattern</code></em>, <em class="replaceable"><code>replacement</code></em>)</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Regular expression functions similar to those provided by PostgreSQL are
+ also available in a number of other SQL implementations, whereas the
+ SQL-standard functions are not as widely implemented. Some of the
+ details of the regular expression syntax will likely differ in each
+ implementation.
+ </p><p>
+ The SQL-standard operators and functions use XQuery regular expressions,
+ which are quite close to the ARE syntax described above.
+ Notable differences between the existing POSIX-based
+ regular-expression feature and XQuery regular expressions include:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ XQuery character class subtraction is not supported. An example of
+ this feature is using the following to match only English
+ consonants: <code class="literal">[a-z-[aeiou]]</code>.
+ </p></li><li class="listitem"><p>
+ XQuery character class shorthands <code class="literal">\c</code>,
+ <code class="literal">\C</code>, <code class="literal">\i</code>,
+ and <code class="literal">\I</code> are not supported.
+ </p></li><li class="listitem"><p>
+ XQuery character class elements
+ using <code class="literal">\p{UnicodeProperty}</code> or the
+ inverse <code class="literal">\P{UnicodeProperty}</code> are not supported.
+ </p></li><li class="listitem"><p>
+ POSIX interprets character classes such as <code class="literal">\w</code>
+ (see <a class="xref" href="functions-matching.html#POSIX-CLASS-SHORTHAND-ESCAPES-TABLE" title="Table 9.21. Regular Expression Class-Shorthand Escapes">Table 9.21</a>)
+ according to the prevailing locale (which you can control by
+ attaching a <code class="literal">COLLATE</code> clause to the operator or
+ function). XQuery specifies these classes by reference to Unicode
+ character properties, so equivalent behavior is obtained only with
+ a locale that follows the Unicode rules.
+ </p></li><li class="listitem"><p>
+ The SQL standard (not XQuery itself) attempts to cater for more
+ variants of <span class="quote">“<span class="quote">newline</span>”</span> than POSIX does. The
+ newline-sensitive matching options described above consider only
+ ASCII NL (<code class="literal">\n</code>) to be a newline, but SQL would have
+ us treat CR (<code class="literal">\r</code>), CRLF (<code class="literal">\r\n</code>)
+ (a Windows-style newline), and some Unicode-only characters like
+ LINE SEPARATOR (U+2028) as newlines as well.
+ Notably, <code class="literal">.</code> and <code class="literal">\s</code> should
+ count <code class="literal">\r\n</code> as one character not two according to
+ SQL.
+ </p></li><li class="listitem"><p>
+ Of the character-entry escapes described in
+ <a class="xref" href="functions-matching.html#POSIX-CHARACTER-ENTRY-ESCAPES-TABLE" title="Table 9.20. Regular Expression Character-Entry Escapes">Table 9.20</a>,
+ XQuery supports only <code class="literal">\n</code>, <code class="literal">\r</code>,
+ and <code class="literal">\t</code>.
+ </p></li><li class="listitem"><p>
+ XQuery does not support
+ the <code class="literal">[:<em class="replaceable"><code>name</code></em>:]</code> syntax
+ for character classes within bracket expressions.
+ </p></li><li class="listitem"><p>
+ XQuery does not have lookahead or lookbehind constraints,
+ nor any of the constraint escapes described in
+ <a class="xref" href="functions-matching.html#POSIX-CONSTRAINT-ESCAPES-TABLE" title="Table 9.22. Regular Expression Constraint Escapes">Table 9.22</a>.
+ </p></li><li class="listitem"><p>
+ The metasyntax forms described in <a class="xref" href="functions-matching.html#POSIX-METASYNTAX" title="9.7.3.4. Regular Expression Metasyntax">Section 9.7.3.4</a>
+ do not exist in XQuery.
+ </p></li><li class="listitem"><p>
+ The regular expression flag letters defined by XQuery are
+ related to but not the same as the option letters for POSIX
+ (<a class="xref" href="functions-matching.html#POSIX-EMBEDDED-OPTIONS-TABLE" title="Table 9.24. ARE Embedded-Option Letters">Table 9.24</a>). While the
+ <code class="literal">i</code> and <code class="literal">q</code> options behave the
+ same, others do not:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ XQuery's <code class="literal">s</code> (allow dot to match newline)
+ and <code class="literal">m</code> (allow <code class="literal">^</code>
+ and <code class="literal">$</code> to match at newlines) flags provide
+ access to the same behaviors as
+ POSIX's <code class="literal">n</code>, <code class="literal">p</code>
+ and <code class="literal">w</code> flags, but they
+ do <span class="emphasis"><em>not</em></span> match the behavior of
+ POSIX's <code class="literal">s</code> and <code class="literal">m</code> flags.
+ Note in particular that dot-matches-newline is the default
+ behavior in POSIX but not XQuery.
+ </p></li><li class="listitem"><p>
+ XQuery's <code class="literal">x</code> (ignore whitespace in pattern) flag
+ is noticeably different from POSIX's expanded-mode flag.
+ POSIX's <code class="literal">x</code> flag also
+ allows <code class="literal">#</code> to begin a comment in the pattern,
+ and POSIX will not ignore a whitespace character after a
+ backslash.
+ </p></li></ul></div><p>
+ </p></li></ul></div><p>
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-bitstring.html" title="9.6. Bit String Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.6. Bit String Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.8. Data Type Formatting Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-math.html b/doc/src/sgml/html/functions-math.html
new file mode 100644
index 0000000..791268d
--- /dev/null
+++ b/doc/src/sgml/html/functions-math.html
@@ -0,0 +1,1001 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.3. Mathematical Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-comparison.html" title="9.2. Comparison Functions and Operators" /><link rel="next" href="functions-string.html" title="9.4. String Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.3. Mathematical Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-comparison.html" title="9.2. Comparison Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-string.html" title="9.4. String Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-MATH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.3. Mathematical Functions and Operators</h2></div></div></div><p>
+ Mathematical operators are provided for many
+ <span class="productname">PostgreSQL</span> types. For types without
+ standard mathematical conventions
+ (e.g., date/time types) we
+ describe the actual behavior in subsequent sections.
+ </p><p>
+ <a class="xref" href="functions-math.html#FUNCTIONS-MATH-OP-TABLE" title="Table 9.4. Mathematical Operators">Table 9.4</a> shows the mathematical
+ operators that are available for the standard numeric types.
+ Unless otherwise noted, operators shown as
+ accepting <em class="replaceable"><code>numeric_type</code></em> are available for all
+ the types <code class="type">smallint</code>, <code class="type">integer</code>,
+ <code class="type">bigint</code>, <code class="type">numeric</code>, <code class="type">real</code>,
+ and <code class="type">double precision</code>.
+ Operators shown as accepting <em class="replaceable"><code>integral_type</code></em>
+ are available for the types <code class="type">smallint</code>, <code class="type">integer</code>,
+ and <code class="type">bigint</code>.
+ Except where noted, each form of an operator returns the same data type
+ as its argument(s). Calls involving multiple argument data types, such
+ as <code class="type">integer</code> <code class="literal">+</code> <code class="type">numeric</code>,
+ are resolved by using the type appearing later in these lists.
+ </p><div class="table" id="FUNCTIONS-MATH-OP-TABLE"><p class="title"><strong>Table 9.4. Mathematical Operators</strong></p><div class="table-contents"><table class="table" summary="Mathematical Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>numeric_type</code></em> <code class="literal">+</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Addition
+ </p>
+ <p>
+ <code class="literal">2 + 3</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">+</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Unary plus (no operation)
+ </p>
+ <p>
+ <code class="literal">+ 3.5</code>
+ → <code class="returnvalue">3.5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>numeric_type</code></em> <code class="literal">-</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Subtraction
+ </p>
+ <p>
+ <code class="literal">2 - 3</code>
+ → <code class="returnvalue">-1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">-</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Negation
+ </p>
+ <p>
+ <code class="literal">- (-4)</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>numeric_type</code></em> <code class="literal">*</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Multiplication
+ </p>
+ <p>
+ <code class="literal">2 * 3</code>
+ → <code class="returnvalue">6</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>numeric_type</code></em> <code class="literal">/</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Division (for integral types, division truncates the result towards
+ zero)
+ </p>
+ <p>
+ <code class="literal">5.0 / 2</code>
+ → <code class="returnvalue">2.5000000000000000</code>
+ </p>
+ <p>
+ <code class="literal">5 / 2</code>
+ → <code class="returnvalue">2</code>
+ </p>
+ <p>
+ <code class="literal">(-5) / 2</code>
+ → <code class="returnvalue">-2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>numeric_type</code></em> <code class="literal">%</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Modulo (remainder); available for <code class="type">smallint</code>,
+ <code class="type">integer</code>, <code class="type">bigint</code>, and <code class="type">numeric</code>
+ </p>
+ <p>
+ <code class="literal">5 % 4</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">numeric</code> <code class="literal">^</code> <code class="type">numeric</code>
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">double precision</code> <code class="literal">^</code> <code class="type">double precision</code>
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Exponentiation
+ </p>
+ <p>
+ <code class="literal">2 ^ 3</code>
+ → <code class="returnvalue">8</code>
+ </p>
+ <p>
+ Unlike typical mathematical practice, multiple uses of
+ <code class="literal">^</code> will associate left to right by default:
+ </p>
+ <p>
+ <code class="literal">2 ^ 3 ^ 3</code>
+ → <code class="returnvalue">512</code>
+ </p>
+ <p>
+ <code class="literal">2 ^ (3 ^ 3)</code>
+ → <code class="returnvalue">134217728</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">|/</code> <code class="type">double precision</code>
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Square root
+ </p>
+ <p>
+ <code class="literal">|/ 25.0</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">||/</code> <code class="type">double precision</code>
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Cube root
+ </p>
+ <p>
+ <code class="literal">||/ 64.0</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">@</code> <em class="replaceable"><code>numeric_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Absolute value
+ </p>
+ <p>
+ <code class="literal">@ -5.0</code>
+ → <code class="returnvalue">5.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integral_type</code></em> <code class="literal">&amp;</code> <em class="replaceable"><code>integral_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integral_type</code></em></code>
+ </p>
+ <p>
+ Bitwise AND
+ </p>
+ <p>
+ <code class="literal">91 &amp; 15</code>
+ → <code class="returnvalue">11</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integral_type</code></em> <code class="literal">|</code> <em class="replaceable"><code>integral_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integral_type</code></em></code>
+ </p>
+ <p>
+ Bitwise OR
+ </p>
+ <p>
+ <code class="literal">32 | 3</code>
+ → <code class="returnvalue">35</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integral_type</code></em> <code class="literal">#</code> <em class="replaceable"><code>integral_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integral_type</code></em></code>
+ </p>
+ <p>
+ Bitwise exclusive OR
+ </p>
+ <p>
+ <code class="literal">17 # 5</code>
+ → <code class="returnvalue">20</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">~</code> <em class="replaceable"><code>integral_type</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integral_type</code></em></code>
+ </p>
+ <p>
+ Bitwise NOT
+ </p>
+ <p>
+ <code class="literal">~1</code>
+ → <code class="returnvalue">-2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integral_type</code></em> <code class="literal">&lt;&lt;</code> <code class="type">integer</code>
+ → <code class="returnvalue"><em class="replaceable"><code>integral_type</code></em></code>
+ </p>
+ <p>
+ Bitwise shift left
+ </p>
+ <p>
+ <code class="literal">1 &lt;&lt; 4</code>
+ → <code class="returnvalue">16</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integral_type</code></em> <code class="literal">&gt;&gt;</code> <code class="type">integer</code>
+ → <code class="returnvalue"><em class="replaceable"><code>integral_type</code></em></code>
+ </p>
+ <p>
+ Bitwise shift right
+ </p>
+ <p>
+ <code class="literal">8 &gt;&gt; 2</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-math.html#FUNCTIONS-MATH-FUNC-TABLE" title="Table 9.5. Mathematical Functions">Table 9.5</a> shows the available
+ mathematical functions.
+ Many of these functions are provided in multiple forms with different
+ argument types.
+ Except where noted, any given form of a function returns the same
+ data type as its argument(s); cross-type cases are resolved in the
+ same way as explained above for operators.
+ The functions working with <code class="type">double precision</code> data are mostly
+ implemented on top of the host system's C library; accuracy and behavior in
+ boundary cases can therefore vary depending on the host system.
+ </p><div class="table" id="FUNCTIONS-MATH-FUNC-TABLE"><p class="title"><strong>Table 9.5. Mathematical Functions</strong></p><div class="table-contents"><table class="table" summary="Mathematical Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">abs</code> ( <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Absolute value
+ </p>
+ <p>
+ <code class="literal">abs(-17.4)</code>
+ → <code class="returnvalue">17.4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">cbrt</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Cube root
+ </p>
+ <p>
+ <code class="literal">cbrt(64.0)</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">ceil</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">ceil</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Nearest integer greater than or equal to argument
+ </p>
+ <p>
+ <code class="literal">ceil(42.2)</code>
+ → <code class="returnvalue">43</code>
+ </p>
+ <p>
+ <code class="literal">ceil(-42.8)</code>
+ → <code class="returnvalue">-42</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">ceiling</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">ceiling</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Nearest integer greater than or equal to argument (same
+ as <code class="function">ceil</code>)
+ </p>
+ <p>
+ <code class="literal">ceiling(95.3)</code>
+ → <code class="returnvalue">96</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">degrees</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Converts radians to degrees
+ </p>
+ <p>
+ <code class="literal">degrees(0.5)</code>
+ → <code class="returnvalue">28.64788975654116</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">div</code> ( <em class="parameter"><code>y</code></em> <code class="type">numeric</code>,
+ <em class="parameter"><code>x</code></em> <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Integer quotient of <em class="parameter"><code>y</code></em>/<em class="parameter"><code>x</code></em>
+ (truncates towards zero)
+ </p>
+ <p>
+ <code class="literal">div(9, 4)</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">exp</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">exp</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Exponential (<code class="literal">e</code> raised to the given power)
+ </p>
+ <p>
+ <code class="literal">exp(1.0)</code>
+ → <code class="returnvalue">2.7182818284590452</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="FUNCTION-FACTORIAL" class="indexterm"></a>
+ <code class="function">factorial</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Factorial
+ </p>
+ <p>
+ <code class="literal">factorial(5)</code>
+ → <code class="returnvalue">120</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">floor</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">floor</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Nearest integer less than or equal to argument
+ </p>
+ <p>
+ <code class="literal">floor(42.8)</code>
+ → <code class="returnvalue">42</code>
+ </p>
+ <p>
+ <code class="literal">floor(-42.8)</code>
+ → <code class="returnvalue">-43</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">gcd</code> ( <em class="replaceable"><code>numeric_type</code></em>, <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Greatest common divisor (the largest positive number that divides both
+ inputs with no remainder); returns <code class="literal">0</code> if both inputs
+ are zero; available for <code class="type">integer</code>, <code class="type">bigint</code>,
+ and <code class="type">numeric</code>
+ </p>
+ <p>
+ <code class="literal">gcd(1071, 462)</code>
+ → <code class="returnvalue">21</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">lcm</code> ( <em class="replaceable"><code>numeric_type</code></em>, <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Least common multiple (the smallest strictly positive number that is
+ an integral multiple of both inputs); returns <code class="literal">0</code> if
+ either input is zero; available for <code class="type">integer</code>,
+ <code class="type">bigint</code>, and <code class="type">numeric</code>
+ </p>
+ <p>
+ <code class="literal">lcm(1071, 462)</code>
+ → <code class="returnvalue">23562</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">ln</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">ln</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Natural logarithm
+ </p>
+ <p>
+ <code class="literal">ln(2.0)</code>
+ → <code class="returnvalue">0.6931471805599453</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">log</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">log</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Base 10 logarithm
+ </p>
+ <p>
+ <code class="literal">log(100)</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">log10</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">log10</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Base 10 logarithm (same as <code class="function">log</code>)
+ </p>
+ <p>
+ <code class="literal">log10(1000)</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">log</code> ( <em class="parameter"><code>b</code></em> <code class="type">numeric</code>,
+ <em class="parameter"><code>x</code></em> <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Logarithm of <em class="parameter"><code>x</code></em> to base <em class="parameter"><code>b</code></em>
+ </p>
+ <p>
+ <code class="literal">log(2.0, 64.0)</code>
+ → <code class="returnvalue">6.0000000000000000</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">min_scale</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Minimum scale (number of fractional decimal digits) needed
+ to represent the supplied value precisely
+ </p>
+ <p>
+ <code class="literal">min_scale(8.4100)</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">mod</code> ( <em class="parameter"><code>y</code></em> <em class="replaceable"><code>numeric_type</code></em>,
+ <em class="parameter"><code>x</code></em> <em class="replaceable"><code>numeric_type</code></em> )
+ → <code class="returnvalue"><em class="replaceable"><code>numeric_type</code></em></code>
+ </p>
+ <p>
+ Remainder of <em class="parameter"><code>y</code></em>/<em class="parameter"><code>x</code></em>;
+ available for <code class="type">smallint</code>, <code class="type">integer</code>,
+ <code class="type">bigint</code>, and <code class="type">numeric</code>
+ </p>
+ <p>
+ <code class="literal">mod(9, 4)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">pi</code> ( )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Approximate value of <span class="symbol_font">π</span>
+ </p>
+ <p>
+ <code class="literal">pi()</code>
+ → <code class="returnvalue">3.141592653589793</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">power</code> ( <em class="parameter"><code>a</code></em> <code class="type">numeric</code>,
+ <em class="parameter"><code>b</code></em> <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">power</code> ( <em class="parameter"><code>a</code></em> <code class="type">double precision</code>,
+ <em class="parameter"><code>b</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ <em class="parameter"><code>a</code></em> raised to the power of <em class="parameter"><code>b</code></em>
+ </p>
+ <p>
+ <code class="literal">power(9, 3)</code>
+ → <code class="returnvalue">729</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.20.1.1.1" class="indexterm"></a>
+ <code class="function">radians</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Converts degrees to radians
+ </p>
+ <p>
+ <code class="literal">radians(45.0)</code>
+ → <code class="returnvalue">0.7853981633974483</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">round</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">round</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Rounds to nearest integer. For <code class="type">numeric</code>, ties are
+ broken by rounding away from zero. For <code class="type">double precision</code>,
+ the tie-breaking behavior is platform dependent, but
+ <span class="quote">“<span class="quote">round to nearest even</span>”</span> is the most common rule.
+ </p>
+ <p>
+ <code class="literal">round(42.4)</code>
+ → <code class="returnvalue">42</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">round</code> ( <em class="parameter"><code>v</code></em> <code class="type">numeric</code>, <em class="parameter"><code>s</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Rounds <em class="parameter"><code>v</code></em> to <em class="parameter"><code>s</code></em> decimal
+ places. Ties are broken by rounding away from zero.
+ </p>
+ <p>
+ <code class="literal">round(42.4382, 2)</code>
+ → <code class="returnvalue">42.44</code>
+ </p>
+ <p>
+ <code class="literal">round(1234.56, -1)</code>
+ → <code class="returnvalue">1230</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">scale</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Scale of the argument (the number of decimal digits in the fractional part)
+ </p>
+ <p>
+ <code class="literal">scale(8.4100)</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.24.1.1.1" class="indexterm"></a>
+ <code class="function">sign</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sign</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Sign of the argument (-1, 0, or +1)
+ </p>
+ <p>
+ <code class="literal">sign(-8.4)</code>
+ → <code class="returnvalue">-1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.25.1.1.1" class="indexterm"></a>
+ <code class="function">sqrt</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">sqrt</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Square root
+ </p>
+ <p>
+ <code class="literal">sqrt(2)</code>
+ → <code class="returnvalue">1.4142135623730951</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.26.1.1.1" class="indexterm"></a>
+ <code class="function">trim_scale</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Reduces the value's scale (number of fractional decimal digits) by
+ removing trailing zeroes
+ </p>
+ <p>
+ <code class="literal">trim_scale(8.4100)</code>
+ → <code class="returnvalue">8.41</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.27.1.1.1" class="indexterm"></a>
+ <code class="function">trunc</code> ( <code class="type">numeric</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">trunc</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Truncates to integer (towards zero)
+ </p>
+ <p>
+ <code class="literal">trunc(42.8)</code>
+ → <code class="returnvalue">42</code>
+ </p>
+ <p>
+ <code class="literal">trunc(-42.8)</code>
+ → <code class="returnvalue">-42</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">trunc</code> ( <em class="parameter"><code>v</code></em> <code class="type">numeric</code>, <em class="parameter"><code>s</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">numeric</code>
+ </p>
+ <p>
+ Truncates <em class="parameter"><code>v</code></em> to <em class="parameter"><code>s</code></em>
+ decimal places
+ </p>
+ <p>
+ <code class="literal">trunc(42.4382, 2)</code>
+ → <code class="returnvalue">42.43</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.6.2.2.29.1.1.1" class="indexterm"></a>
+ <code class="function">width_bucket</code> ( <em class="parameter"><code>operand</code></em> <code class="type">numeric</code>, <em class="parameter"><code>low</code></em> <code class="type">numeric</code>, <em class="parameter"><code>high</code></em> <code class="type">numeric</code>, <em class="parameter"><code>count</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">width_bucket</code> ( <em class="parameter"><code>operand</code></em> <code class="type">double precision</code>, <em class="parameter"><code>low</code></em> <code class="type">double precision</code>, <em class="parameter"><code>high</code></em> <code class="type">double precision</code>, <em class="parameter"><code>count</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of the bucket in
+ which <em class="parameter"><code>operand</code></em> falls in a histogram
+ having <em class="parameter"><code>count</code></em> equal-width buckets spanning the
+ range <em class="parameter"><code>low</code></em> to <em class="parameter"><code>high</code></em>.
+ Returns <code class="literal">0</code>
+ or <code class="literal"><em class="parameter"><code>count</code></em>+1</code> for an input
+ outside that range.
+ </p>
+ <p>
+ <code class="literal">width_bucket(5.35, 0.024, 10.06, 5)</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">width_bucket</code> ( <em class="parameter"><code>operand</code></em> <code class="type">anycompatible</code>, <em class="parameter"><code>thresholds</code></em> <code class="type">anycompatiblearray</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of the bucket in
+ which <em class="parameter"><code>operand</code></em> falls given an array listing the
+ lower bounds of the buckets. Returns <code class="literal">0</code> for an
+ input less than the first lower
+ bound. <em class="parameter"><code>operand</code></em> and the array elements can be
+ of any type having standard comparison operators.
+ The <em class="parameter"><code>thresholds</code></em> array <span class="emphasis"><em>must be
+ sorted</em></span>, smallest first, or unexpected results will be
+ obtained.
+ </p>
+ <p>
+ <code class="literal">width_bucket(now(), array['yesterday', 'today', 'tomorrow']::timestamptz[])</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <a class="xref" href="functions-math.html#FUNCTIONS-MATH-RANDOM-TABLE" title="Table 9.6. Random Functions">Table 9.6</a> shows functions for
+ generating random numbers.
+ </p><div class="table" id="FUNCTIONS-MATH-RANDOM-TABLE"><p class="title"><strong>Table 9.6. Random Functions</strong></p><div class="table-contents"><table class="table" summary="Random Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.8.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">random</code> ( )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Returns a random value in the range 0.0 &lt;= x &lt; 1.0
+ </p>
+ <p>
+ <code class="literal">random()</code>
+ → <code class="returnvalue">0.897124072839091</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.8.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">setseed</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Sets the seed for subsequent <code class="literal">random()</code> calls;
+ argument must be between -1.0 and 1.0, inclusive
+ </p>
+ <p>
+ <code class="literal">setseed(0.12345)</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="function">random()</code> function uses a deterministic
+ pseudo-random number generator.
+ It is fast but not suitable for cryptographic
+ applications; see the <a class="xref" href="pgcrypto.html" title="F.28. pgcrypto">pgcrypto</a> module for a more
+ secure alternative.
+ If <code class="function">setseed()</code> is called, the series of results of
+ subsequent <code class="function">random()</code> calls in the current session
+ can be repeated by re-issuing <code class="function">setseed()</code> with the same
+ argument.
+ Without any prior <code class="function">setseed()</code> call in the same
+ session, the first <code class="function">random()</code> call obtains a seed
+ from a platform-dependent source of random bits.
+ </p><p>
+ <a class="xref" href="functions-math.html#FUNCTIONS-MATH-TRIG-TABLE" title="Table 9.7. Trigonometric Functions">Table 9.7</a> shows the
+ available trigonometric functions. Each of these functions comes in
+ two variants, one that measures angles in radians and one that
+ measures angles in degrees.
+ </p><div class="table" id="FUNCTIONS-MATH-TRIG-TABLE"><p class="title"><strong>Table 9.7. Trigonometric Functions</strong></p><div class="table-contents"><table class="table" summary="Trigonometric Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">acos</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse cosine, result in radians
+ </p>
+ <p>
+ <code class="literal">acos(1)</code>
+ → <code class="returnvalue">0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">acosd</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse cosine, result in degrees
+ </p>
+ <p>
+ <code class="literal">acosd(0.5)</code>
+ → <code class="returnvalue">60</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">asin</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse sine, result in radians
+ </p>
+ <p>
+ <code class="literal">asin(1)</code>
+ → <code class="returnvalue">1.5707963267948966</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">asind</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse sine, result in degrees
+ </p>
+ <p>
+ <code class="literal">asind(0.5)</code>
+ → <code class="returnvalue">30</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">atan</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse tangent, result in radians
+ </p>
+ <p>
+ <code class="literal">atan(1)</code>
+ → <code class="returnvalue">0.7853981633974483</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">atand</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse tangent, result in degrees
+ </p>
+ <p>
+ <code class="literal">atand(1)</code>
+ → <code class="returnvalue">45</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">atan2</code> ( <em class="parameter"><code>y</code></em> <code class="type">double precision</code>,
+ <em class="parameter"><code>x</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse tangent of
+ <em class="parameter"><code>y</code></em>/<em class="parameter"><code>x</code></em>,
+ result in radians
+ </p>
+ <p>
+ <code class="literal">atan2(1, 0)</code>
+ → <code class="returnvalue">1.5707963267948966</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">atan2d</code> ( <em class="parameter"><code>y</code></em> <code class="type">double precision</code>,
+ <em class="parameter"><code>x</code></em> <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse tangent of
+ <em class="parameter"><code>y</code></em>/<em class="parameter"><code>x</code></em>,
+ result in degrees
+ </p>
+ <p>
+ <code class="literal">atan2d(1, 0)</code>
+ → <code class="returnvalue">90</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">cos</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Cosine, argument in radians
+ </p>
+ <p>
+ <code class="literal">cos(0)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">cosd</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Cosine, argument in degrees
+ </p>
+ <p>
+ <code class="literal">cosd(60)</code>
+ → <code class="returnvalue">0.5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">cot</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Cotangent, argument in radians
+ </p>
+ <p>
+ <code class="literal">cot(0.5)</code>
+ → <code class="returnvalue">1.830487721712452</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">cotd</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Cotangent, argument in degrees
+ </p>
+ <p>
+ <code class="literal">cotd(45)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">sin</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Sine, argument in radians
+ </p>
+ <p>
+ <code class="literal">sin(1)</code>
+ → <code class="returnvalue">0.8414709848078965</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">sind</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Sine, argument in degrees
+ </p>
+ <p>
+ <code class="literal">sind(30)</code>
+ → <code class="returnvalue">0.5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">tan</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Tangent, argument in radians
+ </p>
+ <p>
+ <code class="literal">tan(1)</code>
+ → <code class="returnvalue">1.5574077246549023</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.11.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">tand</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Tangent, argument in degrees
+ </p>
+ <p>
+ <code class="literal">tand(45)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ Another way to work with angles measured in degrees is to use the unit
+ transformation functions <code class="literal"><code class="function">radians()</code></code>
+ and <code class="literal"><code class="function">degrees()</code></code> shown earlier.
+ However, using the degree-based trigonometric functions is preferred,
+ as that way avoids round-off error for special cases such
+ as <code class="literal">sind(30)</code>.
+ </p></div><p>
+ <a class="xref" href="functions-math.html#FUNCTIONS-MATH-HYP-TABLE" title="Table 9.8. Hyperbolic Functions">Table 9.8</a> shows the
+ available hyperbolic functions.
+ </p><div class="table" id="FUNCTIONS-MATH-HYP-TABLE"><p class="title"><strong>Table 9.8. Hyperbolic Functions</strong></p><div class="table-contents"><table class="table" summary="Hyperbolic Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.14.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">sinh</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Hyperbolic sine
+ </p>
+ <p>
+ <code class="literal">sinh(1)</code>
+ → <code class="returnvalue">1.1752011936438014</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.14.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">cosh</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Hyperbolic cosine
+ </p>
+ <p>
+ <code class="literal">cosh(0)</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.14.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">tanh</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Hyperbolic tangent
+ </p>
+ <p>
+ <code class="literal">tanh(1)</code>
+ → <code class="returnvalue">0.7615941559557649</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.14.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">asinh</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse hyperbolic sine
+ </p>
+ <p>
+ <code class="literal">asinh(1)</code>
+ → <code class="returnvalue">0.881373587019543</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.14.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">acosh</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse hyperbolic cosine
+ </p>
+ <p>
+ <code class="literal">acosh(1)</code>
+ → <code class="returnvalue">0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.9.14.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">atanh</code> ( <code class="type">double precision</code> )
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Inverse hyperbolic tangent
+ </p>
+ <p>
+ <code class="literal">atanh(0.5)</code>
+ → <code class="returnvalue">0.5493061443340548</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-comparison.html" title="9.2. Comparison Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-string.html" title="9.4. String Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.2. Comparison Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.4. String Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-net.html b/doc/src/sgml/html/functions-net.html
new file mode 100644
index 0000000..f9fef60
--- /dev/null
+++ b/doc/src/sgml/html/functions-net.html
@@ -0,0 +1,397 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.12. Network Address Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-geometry.html" title="9.11. Geometric Functions and Operators" /><link rel="next" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.12. Network Address Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-NET"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.12. Network Address Functions and Operators</h2></div></div></div><p>
+ The IP network address types, <code class="type">cidr</code> and <code class="type">inet</code>,
+ support the usual comparison operators shown in
+ <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a>
+ as well as the specialized operators and functions shown in
+ <a class="xref" href="functions-net.html#CIDR-INET-OPERATORS-TABLE" title="Table 9.39. IP Address Operators">Table 9.39</a> and
+ <a class="xref" href="functions-net.html#CIDR-INET-FUNCTIONS-TABLE" title="Table 9.40. IP Address Functions">Table 9.40</a>.
+ </p><p>
+ Any <code class="type">cidr</code> value can be cast to <code class="type">inet</code> implicitly;
+ therefore, the operators and functions shown below as operating on
+ <code class="type">inet</code> also work on <code class="type">cidr</code> values. (Where there are
+ separate functions for <code class="type">inet</code> and <code class="type">cidr</code>, it is
+ because the behavior should be different for the two cases.)
+ Also, it is permitted to cast an <code class="type">inet</code> value
+ to <code class="type">cidr</code>. When this is done, any bits to the right of the
+ netmask are silently zeroed to create a valid <code class="type">cidr</code> value.
+ </p><div class="table" id="CIDR-INET-OPERATORS-TABLE"><p class="title"><strong>Table 9.39. IP Address Operators</strong></p><div class="table-contents"><table class="table" summary="IP Address Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">&lt;&lt;</code> <code class="type">inet</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is subnet strictly contained by subnet?
+ This operator, and the next four, test for subnet inclusion. They
+ consider only the network parts of the two addresses (ignoring any
+ bits to the right of the netmasks) and determine whether one network
+ is identical to or a subnet of the other.
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1.5' &lt;&lt; inet '192.168.1/24'</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">inet '192.168.0.5' &lt;&lt; inet '192.168.1/24'</code>
+ → <code class="returnvalue">f</code>
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1/24' &lt;&lt; inet '192.168.1/24'</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">&lt;&lt;=</code> <code class="type">inet</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is subnet contained by or equal to subnet?
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1/24' &lt;&lt;= inet '192.168.1/24'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">&gt;&gt;</code> <code class="type">inet</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does subnet strictly contain subnet?
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1/24' &gt;&gt; inet '192.168.1.5'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">&gt;&gt;=</code> <code class="type">inet</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does subnet contain or equal subnet?
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1/24' &gt;&gt;= inet '192.168.1/24'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">&amp;&amp;</code> <code class="type">inet</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does either subnet contain or equal the other?
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1/24' &amp;&amp; inet '192.168.1.80/28'</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1/24' &amp;&amp; inet '192.168.2.0/28'</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">~</code> <code class="type">inet</code>
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Computes bitwise NOT.
+ </p>
+ <p>
+ <code class="literal">~ inet '192.168.1.6'</code>
+ → <code class="returnvalue">63.87.254.249</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">&amp;</code> <code class="type">inet</code>
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Computes bitwise AND.
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1.6' &amp; inet '0.0.0.255'</code>
+ → <code class="returnvalue">0.0.0.6</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">|</code> <code class="type">inet</code>
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Computes bitwise OR.
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1.6' | inet '0.0.0.255'</code>
+ → <code class="returnvalue">192.168.1.255</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">+</code> <code class="type">bigint</code>
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Adds an offset to an address.
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1.6' + 25</code>
+ → <code class="returnvalue">192.168.1.31</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">bigint</code> <code class="literal">+</code> <code class="type">inet</code>
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Adds an offset to an address.
+ </p>
+ <p>
+ <code class="literal">200 + inet '::ffff:fff0:1'</code>
+ → <code class="returnvalue">::ffff:255.240.0.201</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">-</code> <code class="type">bigint</code>
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Subtracts an offset from an address.
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1.43' - 36</code>
+ → <code class="returnvalue">192.168.1.7</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">inet</code> <code class="literal">-</code> <code class="type">inet</code>
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Computes the difference of two addresses.
+ </p>
+ <p>
+ <code class="literal">inet '192.168.1.43' - inet '192.168.1.19'</code>
+ → <code class="returnvalue">24</code>
+ </p>
+ <p>
+ <code class="literal">inet '::1' - inet '::ffff:1'</code>
+ → <code class="returnvalue">-4294901760</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="CIDR-INET-FUNCTIONS-TABLE"><p class="title"><strong>Table 9.40. IP Address Functions</strong></p><div class="table-contents"><table class="table" summary="IP Address Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">abbrev</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Creates an abbreviated display format as text.
+ (The result is the same as the <code class="type">inet</code> output function
+ produces; it is <span class="quote">“<span class="quote">abbreviated</span>”</span> only in comparison to the
+ result of an explicit cast to <code class="type">text</code>, which for historical
+ reasons will never suppress the netmask part.)
+ </p>
+ <p>
+ <code class="literal">abbrev(inet '10.1.0.0/32')</code>
+ → <code class="returnvalue">10.1.0.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">abbrev</code> ( <code class="type">cidr</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Creates an abbreviated display format as text.
+ (The abbreviation consists of dropping all-zero octets to the right
+ of the netmask; more examples are in
+ <a class="xref" href="datatype-net-types.html#DATATYPE-NET-CIDR-TABLE" title="Table 8.22. cidr Type Input Examples">Table 8.22</a>.)
+ </p>
+ <p>
+ <code class="literal">abbrev(cidr '10.1.0.0/16')</code>
+ → <code class="returnvalue">10.1/16</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">broadcast</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Computes the broadcast address for the address's network.
+ </p>
+ <p>
+ <code class="literal">broadcast(inet '192.168.1.5/24')</code>
+ → <code class="returnvalue">192.168.1.255/24</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">family</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the address's family: <code class="literal">4</code> for IPv4,
+ <code class="literal">6</code> for IPv6.
+ </p>
+ <p>
+ <code class="literal">family(inet '::1')</code>
+ → <code class="returnvalue">6</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">host</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the IP address as text, ignoring the netmask.
+ </p>
+ <p>
+ <code class="literal">host(inet '192.168.1.0/24')</code>
+ → <code class="returnvalue">192.168.1.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">hostmask</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Computes the host mask for the address's network.
+ </p>
+ <p>
+ <code class="literal">hostmask(inet '192.168.23.20/30')</code>
+ → <code class="returnvalue">0.0.0.3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">inet_merge</code> ( <code class="type">inet</code>, <code class="type">inet</code> )
+ → <code class="returnvalue">cidr</code>
+ </p>
+ <p>
+ Computes the smallest network that includes both of the given networks.
+ </p>
+ <p>
+ <code class="literal">inet_merge(inet '192.168.1.5/24', inet '192.168.2.5/24')</code>
+ → <code class="returnvalue">192.168.0.0/22</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">inet_same_family</code> ( <code class="type">inet</code>, <code class="type">inet</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Tests whether the addresses belong to the same IP family.
+ </p>
+ <p>
+ <code class="literal">inet_same_family(inet '192.168.1.5/24', inet '::1')</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">masklen</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the netmask length in bits.
+ </p>
+ <p>
+ <code class="literal">masklen(inet '192.168.1.5/24')</code>
+ → <code class="returnvalue">24</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">netmask</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Computes the network mask for the address's network.
+ </p>
+ <p>
+ <code class="literal">netmask(inet '192.168.1.5/24')</code>
+ → <code class="returnvalue">255.255.255.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">network</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">cidr</code>
+ </p>
+ <p>
+ Returns the network part of the address, zeroing out
+ whatever is to the right of the netmask.
+ (This is equivalent to casting the value to <code class="type">cidr</code>.)
+ </p>
+ <p>
+ <code class="literal">network(inet '192.168.1.5/24')</code>
+ → <code class="returnvalue">192.168.1.0/24</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">set_masklen</code> ( <code class="type">inet</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Sets the netmask length for an <code class="type">inet</code> value.
+ The address part does not change.
+ </p>
+ <p>
+ <code class="literal">set_masklen(inet '192.168.1.5/24', 16)</code>
+ → <code class="returnvalue">192.168.1.5/16</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">set_masklen</code> ( <code class="type">cidr</code>, <code class="type">integer</code> )
+ → <code class="returnvalue">cidr</code>
+ </p>
+ <p>
+ Sets the netmask length for a <code class="type">cidr</code> value.
+ Address bits to the right of the new netmask are set to zero.
+ </p>
+ <p>
+ <code class="literal">set_masklen(cidr '192.168.1.0/24', 16)</code>
+ → <code class="returnvalue">192.168.0.0/16</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.5.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">text</code> ( <code class="type">inet</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the unabbreviated IP address and netmask length as text.
+ (This has the same result as an explicit cast to <code class="type">text</code>.)
+ </p>
+ <p>
+ <code class="literal">text(inet '192.168.1.5')</code>
+ → <code class="returnvalue">192.168.1.5/32</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="tip"><h3 class="title">Tip</h3><p>
+ The <code class="function">abbrev</code>, <code class="function">host</code>,
+ and <code class="function">text</code> functions are primarily intended to offer
+ alternative display formats for IP addresses.
+ </p></div><p>
+ The MAC address types, <code class="type">macaddr</code> and <code class="type">macaddr8</code>,
+ support the usual comparison operators shown in
+ <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a>
+ as well as the specialized functions shown in
+ <a class="xref" href="functions-net.html#MACADDR-FUNCTIONS-TABLE" title="Table 9.41. MAC Address Functions">Table 9.41</a>.
+ In addition, they support the bitwise logical operators
+ <code class="literal">~</code>, <code class="literal">&amp;</code> and <code class="literal">|</code>
+ (NOT, AND and OR), just as shown above for IP addresses.
+ </p><div class="table" id="MACADDR-FUNCTIONS-TABLE"><p class="title"><strong>Table 9.41. MAC Address Functions</strong></p><div class="table-contents"><table class="table" summary="MAC Address Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.8.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">trunc</code> ( <code class="type">macaddr</code> )
+ → <code class="returnvalue">macaddr</code>
+ </p>
+ <p>
+ Sets the last 3 bytes of the address to zero. The remaining prefix
+ can be associated with a particular manufacturer (using data not
+ included in <span class="productname">PostgreSQL</span>).
+ </p>
+ <p>
+ <code class="literal">trunc(macaddr '12:34:56:78:90:ab')</code>
+ → <code class="returnvalue">12:34:56:00:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">trunc</code> ( <code class="type">macaddr8</code> )
+ → <code class="returnvalue">macaddr8</code>
+ </p>
+ <p>
+ Sets the last 5 bytes of the address to zero. The remaining prefix
+ can be associated with a particular manufacturer (using data not
+ included in <span class="productname">PostgreSQL</span>).
+ </p>
+ <p>
+ <code class="literal">trunc(macaddr8 '12:34:56:78:90:ab:cd:ef')</code>
+ → <code class="returnvalue">12:34:56:00:00:00:00:00</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.18.8.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">macaddr8_set7bit</code> ( <code class="type">macaddr8</code> )
+ → <code class="returnvalue">macaddr8</code>
+ </p>
+ <p>
+ Sets the 7th bit of the address to one, creating what is known as
+ modified EUI-64, for inclusion in an IPv6 address.
+ </p>
+ <p>
+ <code class="literal">macaddr8_set7bit(macaddr8 '00:34:56:ab:cd:ef')</code>
+ → <code class="returnvalue">02:34:56:ff:fe:ab:cd:ef</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.11. Geometric Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.13. Text Search Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-range.html b/doc/src/sgml/html/functions-range.html
new file mode 100644
index 0000000..b8466a2
--- /dev/null
+++ b/doc/src/sgml/html/functions-range.html
@@ -0,0 +1,707 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.20. Range/Multirange Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-array.html" title="9.19. Array Functions and Operators" /><link rel="next" href="functions-aggregate.html" title="9.21. Aggregate Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.20. Range/Multirange Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-array.html" title="9.19. Array Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-aggregate.html" title="9.21. Aggregate Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-RANGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.20. Range/Multirange Functions and Operators</h2></div></div></div><p>
+ See <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a> for an overview of range types.
+ </p><p>
+ <a class="xref" href="functions-range.html#RANGE-OPERATORS-TABLE" title="Table 9.54. Range Operators">Table 9.54</a> shows the specialized operators
+ available for range types.
+ <a class="xref" href="functions-range.html#MULTIRANGE-OPERATORS-TABLE" title="Table 9.55. Multirange Operators">Table 9.55</a> shows the specialized operators
+ available for multirange types.
+ In addition to those, the usual comparison operators shown in
+ <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are available for range
+ and multirange types. The comparison operators order first by the range lower
+ bounds, and only if those are equal do they compare the upper bounds. The
+ multirange operators compare each range until one is unequal. This
+ does not usually result in a useful overall ordering, but the operators are
+ provided to allow unique indexes to be constructed on ranges.
+ </p><div class="table" id="RANGE-OPERATORS-TABLE"><p class="title"><strong>Table 9.54. Range Operators</strong></p><div class="table-contents"><table class="table" summary="Range Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">@&gt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first range contain the second?
+ </p>
+ <p>
+ <code class="literal">int4range(2,4) @&gt; int4range(2,3)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">@&gt;</code> <code class="type">anyelement</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the range contain the element?
+ </p>
+ <p>
+ <code class="literal">'[2011-01-01,2011-03-01)'::tsrange @&gt; '2011-01-10'::timestamp</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&lt;@</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first range contained by the second?
+ </p>
+ <p>
+ <code class="literal">int4range(2,4) &lt;@ int4range(1,7)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyelement</code> <code class="literal">&lt;@</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the element contained in the range?
+ </p>
+ <p>
+ <code class="literal">42 &lt;@ int4range(1,7)</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&amp;&amp;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do the ranges overlap, that is, have any elements in common?
+ </p>
+ <p>
+ <code class="literal">int8range(3,7) &amp;&amp; int8range(4,12)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&lt;&lt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first range strictly left of the second?
+ </p>
+ <p>
+ <code class="literal">int8range(1,10) &lt;&lt; int8range(100,110)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&gt;&gt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first range strictly right of the second?
+ </p>
+ <p>
+ <code class="literal">int8range(50,60) &gt;&gt; int8range(20,30)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&amp;&lt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first range not extend to the right of the second?
+ </p>
+ <p>
+ <code class="literal">int8range(1,20) &amp;&lt; int8range(18,20)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&amp;&gt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first range not extend to the left of the second?
+ </p>
+ <p>
+ <code class="literal">int8range(7,20) &amp;&gt; int8range(5,10)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">-|-</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are the ranges adjacent?
+ </p>
+ <p>
+ <code class="literal">numrange(1.1,2.2) -|- numrange(2.2,3.3)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">+</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">anyrange</code>
+ </p>
+ <p>
+ Computes the union of the ranges. The ranges must overlap or be
+ adjacent, so that the union is a single range (but
+ see <code class="function">range_merge()</code>).
+ </p>
+ <p>
+ <code class="literal">numrange(5,15) + numrange(10,20)</code>
+ → <code class="returnvalue">[5,20)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">*</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">anyrange</code>
+ </p>
+ <p>
+ Computes the intersection of the ranges.
+ </p>
+ <p>
+ <code class="literal">int8range(5,15) * int8range(10,20)</code>
+ → <code class="returnvalue">[10,15)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">-</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">anyrange</code>
+ </p>
+ <p>
+ Computes the difference of the ranges. The second range must not be
+ contained in the first in such a way that the difference would not be
+ a single range.
+ </p>
+ <p>
+ <code class="literal">int8range(5,15) - int8range(10,20)</code>
+ → <code class="returnvalue">[5,10)</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="MULTIRANGE-OPERATORS-TABLE"><p class="title"><strong>Table 9.55. Multirange Operators</strong></p><div class="table-contents"><table class="table" summary="Multirange Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">@&gt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first multirange contain the second?
+ </p>
+ <p>
+ <code class="literal">'{[2,4)}'::int4multirange @&gt; '{[2,3)}'::int4multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">@&gt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the multirange contain the range?
+ </p>
+ <p>
+ <code class="literal">'{[2,4)}'::int4multirange @&gt; int4range(2,3)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">@&gt;</code> <code class="type">anyelement</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the multirange contain the element?
+ </p>
+ <p>
+ <code class="literal">'{[2011-01-01,2011-03-01)}'::tsmultirange @&gt; '2011-01-10'::timestamp</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">@&gt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the range contain the multirange?
+ </p>
+ <p>
+ <code class="literal">'[2,4)'::int4range @&gt; '{[2,3)}'::int4multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&lt;@</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first multirange contained by the second?
+ </p>
+ <p>
+ <code class="literal">'{[2,4)}'::int4multirange &lt;@ '{[1,7)}'::int4multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&lt;@</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange contained by the range?
+ </p>
+ <p>
+ <code class="literal">'{[2,4)}'::int4multirange &lt;@ int4range(1,7)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&lt;@</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range contained by the multirange?
+ </p>
+ <p>
+ <code class="literal">int4range(2,4) &lt;@ '{[1,7)}'::int4multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyelement</code> <code class="literal">&lt;@</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the element contained by the multirange?
+ </p>
+ <p>
+ <code class="literal">4 &lt;@ '{[1,7)}'::int4multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&amp;&amp;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do the multiranges overlap, that is, have any elements in common?
+ </p>
+ <p>
+ <code class="literal">'{[3,7)}'::int8multirange &amp;&amp; '{[4,12)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&amp;&amp;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the multirange overlap the range?
+ </p>
+ <p>
+ <code class="literal">'{[3,7)}'::int8multirange &amp;&amp; int8range(4,12)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&amp;&amp;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the range overlap the multirange?
+ </p>
+ <p>
+ <code class="literal">int8range(3,7) &amp;&amp; '{[4,12)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&lt;&lt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first multirange strictly left of the second?
+ </p>
+ <p>
+ <code class="literal">'{[1,10)}'::int8multirange &lt;&lt; '{[100,110)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&lt;&lt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange strictly left of the range?
+ </p>
+ <p>
+ <code class="literal">'{[1,10)}'::int8multirange &lt;&lt; int8range(100,110)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&lt;&lt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range strictly left of the multirange?
+ </p>
+ <p>
+ <code class="literal">int8range(1,10) &lt;&lt; '{[100,110)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&gt;&gt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first multirange strictly right of the second?
+ </p>
+ <p>
+ <code class="literal">'{[50,60)}'::int8multirange &gt;&gt; '{[20,30)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&gt;&gt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange strictly right of the range?
+ </p>
+ <p>
+ <code class="literal">'{[50,60)}'::int8multirange &gt;&gt; int8range(20,30)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&gt;&gt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range strictly right of the multirange?
+ </p>
+ <p>
+ <code class="literal">int8range(50,60) &gt;&gt; '{[20,30)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&amp;&lt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first multirange not extend to the right of the second?
+ </p>
+ <p>
+ <code class="literal">'{[1,20)}'::int8multirange &amp;&lt; '{[18,20)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&amp;&lt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the multirange not extend to the right of the range?
+ </p>
+ <p>
+ <code class="literal">'{[1,20)}'::int8multirange &amp;&lt; int8range(18,20)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&amp;&lt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the range not extend to the right of the multirange?
+ </p>
+ <p>
+ <code class="literal">int8range(1,20) &amp;&lt; '{[18,20)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&amp;&gt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first multirange not extend to the left of the second?
+ </p>
+ <p>
+ <code class="literal">'{[7,20)}'::int8multirange &amp;&gt; '{[5,10)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">&amp;&gt;</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the multirange not extend to the left of the range?
+ </p>
+ <p>
+ <code class="literal">'{[7,20)}'::int8multirange &amp;&gt; int8range(5,10)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">&amp;&gt;</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the range not extend to the left of the multirange?
+ </p>
+ <p>
+ <code class="literal">int8range(7,20) &amp;&gt; '{[5,10)}'::int8multirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">-|-</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are the multiranges adjacent?
+ </p>
+ <p>
+ <code class="literal">'{[1.1,2.2)}'::nummultirange -|- '{[2.2,3.3)}'::nummultirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">-|-</code> <code class="type">anyrange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange adjacent to the range?
+ </p>
+ <p>
+ <code class="literal">'{[1.1,2.2)}'::nummultirange -|- numrange(2.2,3.3)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyrange</code> <code class="literal">-|-</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range adjacent to the multirange?
+ </p>
+ <p>
+ <code class="literal">numrange(1.1,2.2) -|- '{[2.2,3.3)}'::nummultirange</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">+</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p>
+ Computes the union of the multiranges. The multiranges need not overlap
+ or be adjacent.
+ </p>
+ <p>
+ <code class="literal">'{[5,10)}'::nummultirange + '{[15,20)}'::nummultirange</code>
+ → <code class="returnvalue">{[5,10), [15,20)}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">*</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p>
+ Computes the intersection of the multiranges.
+ </p>
+ <p>
+ <code class="literal">'{[5,15)}'::int8multirange * '{[10,20)}'::int8multirange</code>
+ → <code class="returnvalue">{[10,15)}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anymultirange</code> <code class="literal">-</code> <code class="type">anymultirange</code>
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p>
+ Computes the difference of the multiranges.
+ </p>
+ <p>
+ <code class="literal">'{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange</code>
+ → <code class="returnvalue">{[5,10), [15,20)}</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The left-of/right-of/adjacent operators always return false when an empty
+ range or multirange is involved; that is, an empty range is not considered to
+ be either before or after any other range.
+ </p><p>
+ Elsewhere empty ranges and multiranges are treated as the additive identity:
+ anything unioned with an empty value is itself. Anything minus an empty
+ value is itself. An empty multirange has exactly the same points as an empty
+ range. Every range contains the empty range. Every multirange contains as many
+ empty ranges as you like.
+ </p><p>
+ The range union and difference operators will fail if the resulting range would
+ need to contain two disjoint sub-ranges, as such a range cannot be
+ represented. There are separate operators for union and difference that take
+ multirange parameters and return a multirange, and they do not fail even if
+ their arguments are disjoint. So if you need a union or difference operation
+ for ranges that may be disjoint, you can avoid errors by first casting your
+ ranges to multiranges.
+ </p><p>
+ <a class="xref" href="functions-range.html#RANGE-FUNCTIONS-TABLE" title="Table 9.56. Range Functions">Table 9.56</a> shows the functions
+ available for use with range types.
+ <a class="xref" href="functions-range.html#MULTIRANGE-FUNCTIONS-TABLE" title="Table 9.57. Multirange Functions">Table 9.57</a> shows the functions
+ available for use with multirange types.
+ </p><div class="table" id="RANGE-FUNCTIONS-TABLE"><p class="title"><strong>Table 9.56. Range Functions</strong></p><div class="table-contents"><table class="table" summary="Range Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">lower</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Extracts the lower bound of the range (<code class="literal">NULL</code> if the
+ range is empty or the lower bound is infinite).
+ </p>
+ <p>
+ <code class="literal">lower(numrange(1.1,2.2))</code>
+ → <code class="returnvalue">1.1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">upper</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Extracts the upper bound of the range (<code class="literal">NULL</code> if the
+ range is empty or the upper bound is infinite).
+ </p>
+ <p>
+ <code class="literal">upper(numrange(1.1,2.2))</code>
+ → <code class="returnvalue">2.2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">isempty</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range empty?
+ </p>
+ <p>
+ <code class="literal">isempty(numrange(1.1,2.2))</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">lower_inc</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range's lower bound inclusive?
+ </p>
+ <p>
+ <code class="literal">lower_inc(numrange(1.1,2.2))</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">upper_inc</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range's upper bound inclusive?
+ </p>
+ <p>
+ <code class="literal">upper_inc(numrange(1.1,2.2))</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">lower_inf</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range's lower bound infinite?
+ </p>
+ <p>
+ <code class="literal">lower_inf('(,)'::daterange)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">upper_inf</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the range's upper bound infinite?
+ </p>
+ <p>
+ <code class="literal">upper_inf('(,)'::daterange)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.10.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">range_merge</code> ( <code class="type">anyrange</code>, <code class="type">anyrange</code> )
+ → <code class="returnvalue">anyrange</code>
+ </p>
+ <p>
+ Computes the smallest range that includes both of the given ranges.
+ </p>
+ <p>
+ <code class="literal">range_merge('[1,2)'::int4range, '[3,4)'::int4range)</code>
+ → <code class="returnvalue">[1,4)</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="MULTIRANGE-FUNCTIONS-TABLE"><p class="title"><strong>Table 9.57. Multirange Functions</strong></p><div class="table-contents"><table class="table" summary="Multirange Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">lower</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Extracts the lower bound of the multirange (<code class="literal">NULL</code> if the
+ multirange is empty or the lower bound is infinite).
+ </p>
+ <p>
+ <code class="literal">lower('{[1.1,2.2)}'::nummultirange)</code>
+ → <code class="returnvalue">1.1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">upper</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Extracts the upper bound of the multirange (<code class="literal">NULL</code> if the
+ multirange is empty or the upper bound is infinite).
+ </p>
+ <p>
+ <code class="literal">upper('{[1.1,2.2)}'::nummultirange)</code>
+ → <code class="returnvalue">2.2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">isempty</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange empty?
+ </p>
+ <p>
+ <code class="literal">isempty('{[1.1,2.2)}'::nummultirange)</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">lower_inc</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange's lower bound inclusive?
+ </p>
+ <p>
+ <code class="literal">lower_inc('{[1.1,2.2)}'::nummultirange)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">upper_inc</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange's upper bound inclusive?
+ </p>
+ <p>
+ <code class="literal">upper_inc('{[1.1,2.2)}'::nummultirange)</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">lower_inf</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange's lower bound infinite?
+ </p>
+ <p>
+ <code class="literal">lower_inf('{(,)}'::datemultirange)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">upper_inf</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the multirange's upper bound infinite?
+ </p>
+ <p>
+ <code class="literal">upper_inf('{(,)}'::datemultirange)</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">range_merge</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">anyrange</code>
+ </p>
+ <p>
+ Computes the smallest range that includes the entire multirange.
+ </p>
+ <p>
+ <code class="literal">range_merge('{[1,2), [3,4)}'::int4multirange)</code>
+ → <code class="returnvalue">[1,4)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">multirange</code> ( <code class="type">anyrange</code> )
+ → <code class="returnvalue">anymultirange</code>
+ </p>
+ <p>
+ Returns a multirange containing just the given range.
+ </p>
+ <p>
+ <code class="literal">multirange('[1,2)'::int4range)</code>
+ → <code class="returnvalue">{[1,2)}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.26.11.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">unnest</code> ( <code class="type">anymultirange</code> )
+ → <code class="returnvalue">setof anyrange</code>
+ </p>
+ <p>
+ Expands a multirange into a set of ranges.
+ The ranges are read out in storage order (ascending).
+ </p>
+ <p>
+ <code class="literal">unnest('{[1,2), [3,4)}'::int4multirange)</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ [1,2)
+ [3,4)
+</pre><p>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="function">lower_inc</code>, <code class="function">upper_inc</code>,
+ <code class="function">lower_inf</code>, and <code class="function">upper_inf</code>
+ functions all return false for an empty range or multirange.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-array.html" title="9.19. Array Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-aggregate.html" title="9.21. Aggregate Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.19. Array Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.21. Aggregate Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-sequence.html b/doc/src/sgml/html/functions-sequence.html
new file mode 100644
index 0000000..c3c188e
--- /dev/null
+++ b/doc/src/sgml/html/functions-sequence.html
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.17. Sequence Manipulation Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-json.html" title="9.16. JSON Functions and Operators" /><link rel="next" href="functions-conditional.html" title="9.18. Conditional Expressions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.17. Sequence Manipulation Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-json.html" title="9.16. JSON Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-conditional.html" title="9.18. Conditional Expressions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-SEQUENCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.17. Sequence Manipulation Functions</h2></div></div></div><a id="id-1.5.8.23.2" class="indexterm"></a><p>
+ This section describes functions for operating on <em class="firstterm">sequence
+ objects</em>, also called sequence generators or just sequences.
+ Sequence objects are special single-row tables created with <a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a>.
+ Sequence objects are commonly used to generate unique identifiers
+ for rows of a table. The sequence functions, listed in <a class="xref" href="functions-sequence.html#FUNCTIONS-SEQUENCE-TABLE" title="Table 9.51. Sequence Functions">Table 9.51</a>, provide simple, multiuser-safe
+ methods for obtaining successive sequence values from sequence
+ objects.
+ </p><div class="table" id="FUNCTIONS-SEQUENCE-TABLE"><p class="title"><strong>Table 9.51. Sequence Functions</strong></p><div class="table-contents"><table class="table" summary="Sequence Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.23.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">nextval</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Advances the sequence object to its next value and returns that value.
+ This is done atomically: even if multiple sessions
+ execute <code class="function">nextval</code> concurrently, each will safely
+ receive a distinct sequence value.
+ If the sequence object has been created with default parameters,
+ successive <code class="function">nextval</code> calls will return successive
+ values beginning with 1. Other behaviors can be obtained by using
+ appropriate parameters in the <a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a>
+ command.
+ </p>
+ <p>
+ This function requires <code class="literal">USAGE</code>
+ or <code class="literal">UPDATE</code> privilege on the sequence.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.23.4.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">setval</code> ( <code class="type">regclass</code>, <code class="type">bigint</code> [<span class="optional">, <code class="type">boolean</code> </span>] )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Sets the sequence object's current value, and optionally
+ its <code class="literal">is_called</code> flag. The two-parameter
+ form sets the sequence's <code class="literal">last_value</code> field to the
+ specified value and sets its <code class="literal">is_called</code> field to
+ <code class="literal">true</code>, meaning that the next
+ <code class="function">nextval</code> will advance the sequence before
+ returning a value. The value that will be reported
+ by <code class="function">currval</code> is also set to the specified value.
+ In the three-parameter form, <code class="literal">is_called</code> can be set
+ to either <code class="literal">true</code>
+ or <code class="literal">false</code>. <code class="literal">true</code> has the same
+ effect as the two-parameter form. If it is set
+ to <code class="literal">false</code>, the next <code class="function">nextval</code>
+ will return exactly the specified value, and sequence advancement
+ commences with the following <code class="function">nextval</code>.
+ Furthermore, the value reported by <code class="function">currval</code> is not
+ changed in this case. For example,
+</p><pre class="programlisting">
+SELECT setval('myseq', 42); <em class="lineannotation"><span class="lineannotation">Next <code class="function">nextval</code> will return 43</span></em>
+SELECT setval('myseq', 42, true); <em class="lineannotation"><span class="lineannotation">Same as above</span></em>
+SELECT setval('myseq', 42, false); <em class="lineannotation"><span class="lineannotation">Next <code class="function">nextval</code> will return 42</span></em>
+</pre><p>
+ The result returned by <code class="function">setval</code> is just the value of its
+ second argument.
+ </p>
+ <p>
+ This function requires <code class="literal">UPDATE</code> privilege on the
+ sequence.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.23.4.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">currval</code> ( <code class="type">regclass</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the value most recently obtained
+ by <code class="function">nextval</code> for this sequence in the current
+ session. (An error is reported if <code class="function">nextval</code> has
+ never been called for this sequence in this session.) Because this is
+ returning a session-local value, it gives a predictable answer whether
+ or not other sessions have executed <code class="function">nextval</code> since
+ the current session did.
+ </p>
+ <p>
+ This function requires <code class="literal">USAGE</code>
+ or <code class="literal">SELECT</code> privilege on the sequence.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.23.4.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">lastval</code> ()
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the value most recently returned by
+ <code class="function">nextval</code> in the current session. This function is
+ identical to <code class="function">currval</code>, except that instead
+ of taking the sequence name as an argument it refers to whichever
+ sequence <code class="function">nextval</code> was most recently applied to
+ in the current session. It is an error to call
+ <code class="function">lastval</code> if <code class="function">nextval</code>
+ has not yet been called in the current session.
+ </p>
+ <p>
+ This function requires <code class="literal">USAGE</code>
+ or <code class="literal">SELECT</code> privilege on the last used sequence.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="caution"><h3 class="title">Caution</h3><p>
+ To avoid blocking concurrent transactions that obtain numbers from
+ the same sequence, the value obtained by <code class="function">nextval</code>
+ is not reclaimed for re-use if the calling transaction later aborts.
+ This means that transaction aborts or database crashes can result in
+ gaps in the sequence of assigned values. That can happen without a
+ transaction abort, too. For example an <code class="command">INSERT</code> with
+ an <code class="literal">ON CONFLICT</code> clause will compute the to-be-inserted
+ tuple, including doing any required <code class="function">nextval</code>
+ calls, before detecting any conflict that would cause it to follow
+ the <code class="literal">ON CONFLICT</code> rule instead.
+ Thus, <span class="productname">PostgreSQL</span> sequence
+ objects <span class="emphasis"><em>cannot be used to obtain <span class="quote">“<span class="quote">gapless</span>”</span>
+ sequences</em></span>.
+ </p><p>
+ Likewise, sequence state changes made by <code class="function">setval</code>
+ are immediately visible to other transactions, and are not undone if
+ the calling transaction rolls back.
+ </p><p>
+ If the database cluster crashes before committing a transaction
+ containing a <code class="function">nextval</code>
+ or <code class="function">setval</code> call, the sequence state change might
+ not have made its way to persistent storage, so that it is uncertain
+ whether the sequence will have its original or updated state after the
+ cluster restarts. This is harmless for usage of the sequence within
+ the database, since other effects of uncommitted transactions will not
+ be visible either. However, if you wish to use a sequence value for
+ persistent outside-the-database purposes, make sure that the
+ <code class="function">nextval</code> call has been committed before doing so.
+ </p></div><p>
+ The sequence to be operated on by a sequence function is specified by
+ a <code class="type">regclass</code> argument, which is simply the OID of the sequence in the
+ <code class="structname">pg_class</code> system catalog. You do not have to look up the
+ OID by hand, however, since the <code class="type">regclass</code> data type's input
+ converter will do the work for you. See <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>
+ for details.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-json.html" title="9.16. JSON Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-conditional.html" title="9.18. Conditional Expressions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.16. JSON Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.18. Conditional Expressions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-srf.html b/doc/src/sgml/html/functions-srf.html
new file mode 100644
index 0000000..e1c13f3
--- /dev/null
+++ b/doc/src/sgml/html/functions-srf.html
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.25. Set Returning Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-comparisons.html" title="9.24. Row and Array Comparisons" /><link rel="next" href="functions-info.html" title="9.26. System Information Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.25. Set Returning Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-comparisons.html" title="9.24. Row and Array Comparisons">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-info.html" title="9.26. System Information Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-SRF"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.25. Set Returning Functions</h2></div></div></div><a id="id-1.5.8.31.2" class="indexterm"></a><p>
+ This section describes functions that possibly return more than one row.
+ The most widely used functions in this class are series generating
+ functions, as detailed in <a class="xref" href="functions-srf.html#FUNCTIONS-SRF-SERIES" title="Table 9.64. Series Generating Functions">Table 9.64</a> and
+ <a class="xref" href="functions-srf.html#FUNCTIONS-SRF-SUBSCRIPTS" title="Table 9.65. Subscript Generating Functions">Table 9.65</a>. Other, more specialized
+ set-returning functions are described elsewhere in this manual.
+ See <a class="xref" href="queries-table-expressions.html#QUERIES-TABLEFUNCTIONS" title="7.2.1.4. Table Functions">Section 7.2.1.4</a> for ways to combine multiple
+ set-returning functions.
+ </p><div class="table" id="FUNCTIONS-SRF-SERIES"><p class="title"><strong>Table 9.64. Series Generating Functions</strong></p><div class="table-contents"><table class="table" summary="Series Generating Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.31.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">generate_series</code> ( <em class="parameter"><code>start</code></em> <code class="type">integer</code>, <em class="parameter"><code>stop</code></em> <code class="type">integer</code> [<span class="optional">, <em class="parameter"><code>step</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">setof integer</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">generate_series</code> ( <em class="parameter"><code>start</code></em> <code class="type">bigint</code>, <em class="parameter"><code>stop</code></em> <code class="type">bigint</code> [<span class="optional">, <em class="parameter"><code>step</code></em> <code class="type">bigint</code> </span>] )
+ → <code class="returnvalue">setof bigint</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">generate_series</code> ( <em class="parameter"><code>start</code></em> <code class="type">numeric</code>, <em class="parameter"><code>stop</code></em> <code class="type">numeric</code> [<span class="optional">, <em class="parameter"><code>step</code></em> <code class="type">numeric</code> </span>] )
+ → <code class="returnvalue">setof numeric</code>
+ </p>
+ <p>
+ Generates a series of values from <em class="parameter"><code>start</code></em>
+ to <em class="parameter"><code>stop</code></em>, with a step size
+ of <em class="parameter"><code>step</code></em>. <em class="parameter"><code>step</code></em>
+ defaults to 1.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">generate_series</code> ( <em class="parameter"><code>start</code></em> <code class="type">timestamp</code>, <em class="parameter"><code>stop</code></em> <code class="type">timestamp</code>, <em class="parameter"><code>step</code></em> <code class="type">interval</code> )
+ → <code class="returnvalue">setof timestamp</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">generate_series</code> ( <em class="parameter"><code>start</code></em> <code class="type">timestamp with time zone</code>, <em class="parameter"><code>stop</code></em> <code class="type">timestamp with time zone</code>, <em class="parameter"><code>step</code></em> <code class="type">interval</code> )
+ → <code class="returnvalue">setof timestamp with time zone</code>
+ </p>
+ <p>
+ Generates a series of values from <em class="parameter"><code>start</code></em>
+ to <em class="parameter"><code>stop</code></em>, with a step size
+ of <em class="parameter"><code>step</code></em>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ When <em class="parameter"><code>step</code></em> is positive, zero rows are returned if
+ <em class="parameter"><code>start</code></em> is greater than <em class="parameter"><code>stop</code></em>.
+ Conversely, when <em class="parameter"><code>step</code></em> is negative, zero rows are
+ returned if <em class="parameter"><code>start</code></em> is less than <em class="parameter"><code>stop</code></em>.
+ Zero rows are also returned if any input is <code class="literal">NULL</code>.
+ It is an error
+ for <em class="parameter"><code>step</code></em> to be zero. Some examples follow:
+</p><pre class="programlisting">
+SELECT * FROM generate_series(2,4);
+ generate_series
+-----------------
+ 2
+ 3
+ 4
+(3 rows)
+
+SELECT * FROM generate_series(5,1,-2);
+ generate_series
+-----------------
+ 5
+ 3
+ 1
+(3 rows)
+
+SELECT * FROM generate_series(4,3);
+ generate_series
+-----------------
+(0 rows)
+
+SELECT generate_series(1.1, 4, 1.3);
+ generate_series
+-----------------
+ 1.1
+ 2.4
+ 3.7
+(3 rows)
+
+-- this example relies on the date-plus-integer operator:
+SELECT current_date + s.a AS dates FROM generate_series(0,14,7) AS s(a);
+ dates
+------------
+ 2004-02-05
+ 2004-02-12
+ 2004-02-19
+(3 rows)
+
+SELECT * FROM generate_series('2008-03-01 00:00'::timestamp,
+ '2008-03-04 12:00', '10 hours');
+ generate_series
+---------------------
+ 2008-03-01 00:00:00
+ 2008-03-01 10:00:00
+ 2008-03-01 20:00:00
+ 2008-03-02 06:00:00
+ 2008-03-02 16:00:00
+ 2008-03-03 02:00:00
+ 2008-03-03 12:00:00
+ 2008-03-03 22:00:00
+ 2008-03-04 08:00:00
+(9 rows)
+</pre><p>
+ </p><div class="table" id="FUNCTIONS-SRF-SUBSCRIPTS"><p class="title"><strong>Table 9.65. Subscript Generating Functions</strong></p><div class="table-contents"><table class="table" summary="Subscript Generating Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.31.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">generate_subscripts</code> ( <em class="parameter"><code>array</code></em> <code class="type">anyarray</code>, <em class="parameter"><code>dim</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">setof integer</code>
+ </p>
+ <p>
+ Generates a series comprising the valid subscripts of
+ the <em class="parameter"><code>dim</code></em>'th dimension of the given array.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">generate_subscripts</code> ( <em class="parameter"><code>array</code></em> <code class="type">anyarray</code>, <em class="parameter"><code>dim</code></em> <code class="type">integer</code>, <em class="parameter"><code>reverse</code></em> <code class="type">boolean</code> )
+ → <code class="returnvalue">setof integer</code>
+ </p>
+ <p>
+ Generates a series comprising the valid subscripts of
+ the <em class="parameter"><code>dim</code></em>'th dimension of the given array.
+ When <em class="parameter"><code>reverse</code></em> is true, returns the series in
+ reverse order.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="function">generate_subscripts</code> is a convenience function that generates
+ the set of valid subscripts for the specified dimension of the given
+ array.
+ Zero rows are returned for arrays that do not have the requested dimension,
+ or if any input is <code class="literal">NULL</code>.
+ Some examples follow:
+</p><pre class="programlisting">
+-- basic usage:
+SELECT generate_subscripts('{NULL,1,NULL,2}'::int[], 1) AS s;
+ s
+---
+ 1
+ 2
+ 3
+ 4
+(4 rows)
+
+-- presenting an array, the subscript and the subscripted
+-- value requires a subquery:
+SELECT * FROM arrays;
+ a
+--------------------
+ {-1,-2}
+ {100,200,300}
+(2 rows)
+
+SELECT a AS array, s AS subscript, a[s] AS value
+FROM (SELECT generate_subscripts(a, 1) AS s, a FROM arrays) foo;
+ array | subscript | value
+---------------+-----------+-------
+ {-1,-2} | 1 | -1
+ {-1,-2} | 2 | -2
+ {100,200,300} | 1 | 100
+ {100,200,300} | 2 | 200
+ {100,200,300} | 3 | 300
+(5 rows)
+
+-- unnest a 2D array:
+CREATE OR REPLACE FUNCTION unnest2(anyarray)
+RETURNS SETOF anyelement AS $$
+select $1[i][j]
+ from generate_subscripts($1,1) g1(i),
+ generate_subscripts($1,2) g2(j);
+$$ LANGUAGE sql IMMUTABLE;
+CREATE FUNCTION
+SELECT * FROM unnest2(ARRAY[[1,2],[3,4]]);
+ unnest2
+---------
+ 1
+ 2
+ 3
+ 4
+(4 rows)
+</pre><p>
+ </p><a id="id-1.5.8.31.8" class="indexterm"></a><p>
+ When a function in the <code class="literal">FROM</code> clause is suffixed
+ by <code class="literal">WITH ORDINALITY</code>, a <code class="type">bigint</code> column is
+ appended to the function's output column(s), which starts from 1 and
+ increments by 1 for each row of the function's output.
+ This is most useful in the case of set returning
+ functions such as <code class="function">unnest()</code>.
+
+</p><pre class="programlisting">
+-- set returning function WITH ORDINALITY:
+SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n);
+ ls | n
+-----------------+----
+ pg_serial | 1
+ pg_twophase | 2
+ postmaster.opts | 3
+ pg_notify | 4
+ postgresql.conf | 5
+ pg_tblspc | 6
+ logfile | 7
+ base | 8
+ postmaster.pid | 9
+ pg_ident.conf | 10
+ global | 11
+ pg_xact | 12
+ pg_snapshots | 13
+ pg_multixact | 14
+ PG_VERSION | 15
+ pg_wal | 16
+ pg_hba.conf | 17
+ pg_stat_tmp | 18
+ pg_subtrans | 19
+(19 rows)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-comparisons.html" title="9.24. Row and Array Comparisons">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-info.html" title="9.26. System Information Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.24. Row and Array Comparisons </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.26. System Information Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-statistics.html b/doc/src/sgml/html/functions-statistics.html
new file mode 100644
index 0000000..814c172
--- /dev/null
+++ b/doc/src/sgml/html/functions-statistics.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.30. Statistics Information Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-event-triggers.html" title="9.29. Event Trigger Functions" /><link rel="next" href="typeconv.html" title="Chapter 10. Type Conversion" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.30. Statistics Information Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-event-triggers.html" title="9.29. Event Trigger Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv.html" title="Chapter 10. Type Conversion">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-STATISTICS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.30. Statistics Information Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-statistics.html#FUNCTIONS-STATISTICS-MCV">9.30.1. Inspecting MCV Lists</a></span></dt></dl></div><a id="id-1.5.8.36.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a function to inspect complex
+ statistics defined using the <code class="command">CREATE STATISTICS</code> command.
+ </p><div class="sect2" id="FUNCTIONS-STATISTICS-MCV"><div class="titlepage"><div><div><h3 class="title">9.30.1. Inspecting MCV Lists</h3></div></div></div><a id="id-1.5.8.36.4.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">pg_mcv_list_items</code> ( <code class="type">pg_mcv_list</code> ) → <code class="returnvalue">setof record</code>
+</pre><p>
+ <code class="function">pg_mcv_list_items</code> returns a set of records describing
+ all items stored in a multi-column <acronym class="acronym">MCV</acronym> list. It
+ returns the following columns:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">index</code></td><td><code class="type">integer</code></td><td>index of the item in the <acronym class="acronym">MCV</acronym> list</td></tr><tr><td><code class="literal">values</code></td><td><code class="type">text[]</code></td><td>values stored in the MCV item</td></tr><tr><td><code class="literal">nulls</code></td><td><code class="type">boolean[]</code></td><td>flags identifying <code class="literal">NULL</code> values</td></tr><tr><td><code class="literal">frequency</code></td><td><code class="type">double precision</code></td><td>frequency of this <acronym class="acronym">MCV</acronym> item</td></tr><tr><td><code class="literal">base_frequency</code></td><td><code class="type">double precision</code></td><td>base frequency of this <acronym class="acronym">MCV</acronym> item</td></tr></tbody></table></div><p>
+ </p><p>
+ The <code class="function">pg_mcv_list_items</code> function can be used like this:
+
+</p><pre class="programlisting">
+SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
+ pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts';
+</pre><p>
+
+ Values of the <code class="type">pg_mcv_list</code> type can be obtained only from the
+ <code class="structname">pg_statistic_ext_data</code>.<code class="structfield">stxdmcv</code>
+ column.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-event-triggers.html" title="9.29. Event Trigger Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv.html" title="Chapter 10. Type Conversion">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.29. Event Trigger Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 10. Type Conversion</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-string.html b/doc/src/sgml/html/functions-string.html
new file mode 100644
index 0000000..85f8327
--- /dev/null
+++ b/doc/src/sgml/html/functions-string.html
@@ -0,0 +1,1208 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.4. String Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-math.html" title="9.3. Mathematical Functions and Operators" /><link rel="next" href="functions-binarystring.html" title="9.5. Binary String Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.4. String Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-math.html" title="9.3. Mathematical Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-binarystring.html" title="9.5. Binary String Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-STRING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.4. String Functions and Operators</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-string.html#FUNCTIONS-STRING-FORMAT">9.4.1. <code class="function">format</code></a></span></dt></dl></div><p>
+ This section describes functions and operators for examining and
+ manipulating string values. Strings in this context include values
+ of the types <code class="type">character</code>, <code class="type">character varying</code>,
+ and <code class="type">text</code>. Except where noted, these functions and operators
+ are declared to accept and return type <code class="type">text</code>. They will
+ interchangeably accept <code class="type">character varying</code> arguments.
+ Values of type <code class="type">character</code> will be converted
+ to <code class="type">text</code> before the function or operator is applied, resulting
+ in stripping any trailing spaces in the <code class="type">character</code> value.
+ </p><p>
+ <acronym class="acronym">SQL</acronym> defines some string functions that use
+ key words, rather than commas, to separate
+ arguments. Details are in
+ <a class="xref" href="functions-string.html#FUNCTIONS-STRING-SQL" title="Table 9.9. SQL String Functions and Operators">Table 9.9</a>.
+ <span class="productname">PostgreSQL</span> also provides versions of these functions
+ that use the regular function invocation syntax
+ (see <a class="xref" href="functions-string.html#FUNCTIONS-STRING-OTHER" title="Table 9.10. Other String Functions and Operators">Table 9.10</a>).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The string concatenation operator (<code class="literal">||</code>) will accept
+ non-string input, so long as at least one input is of string type, as shown
+ in <a class="xref" href="functions-string.html#FUNCTIONS-STRING-SQL" title="Table 9.9. SQL String Functions and Operators">Table 9.9</a>. For other cases, inserting an
+ explicit coercion to <code class="type">text</code> can be used to have non-string input
+ accepted.
+ </p></div><div class="table" id="FUNCTIONS-STRING-SQL"><p class="title"><strong>Table 9.9. <acronym class="acronym">SQL</acronym> String Functions and Operators</strong></p><div class="table-contents"><table class="table" summary="SQL String Functions and Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function/Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="type">text</code> <code class="literal">||</code> <code class="type">text</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Concatenates the two strings.
+ </p>
+ <p>
+ <code class="literal">'Post' || 'greSQL'</code>
+ → <code class="returnvalue">PostgreSQL</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">||</code> <code class="type">anynonarray</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">anynonarray</code> <code class="literal">||</code> <code class="type">text</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the non-string input to text, then concatenates the two
+ strings. (The non-string input cannot be of an array type, because
+ that would create ambiguity with the array <code class="literal">||</code>
+ operators. If you want to concatenate an array's text equivalent,
+ cast it to <code class="type">text</code> explicitly.)
+ </p>
+ <p>
+ <code class="literal">'Value: ' || 42</code>
+ → <code class="returnvalue">Value: 42</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.3.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.10.5.2.2.3.1.1.2" class="indexterm"></a>
+ <code class="type">text</code> <code class="literal">IS</code> [<span class="optional"><code class="literal">NOT</code></span>] [<span class="optional"><em class="parameter"><code>form</code></em></span>] <code class="literal">NORMALIZED</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Checks whether the string is in the specified Unicode normalization
+ form. The optional <em class="parameter"><code>form</code></em> key word specifies the
+ form: <code class="literal">NFC</code> (the default), <code class="literal">NFD</code>,
+ <code class="literal">NFKC</code>, or <code class="literal">NFKD</code>. This expression can
+ only be used when the server encoding is <code class="literal">UTF8</code>. Note
+ that checking for normalization using this expression is often faster
+ than normalizing possibly already normalized strings.
+ </p>
+ <p>
+ <code class="literal">U&amp;'\0061\0308bc' IS NFD NORMALIZED</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">bit_length</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bits in the string (8
+ times the <code class="function">octet_length</code>).
+ </p>
+ <p>
+ <code class="literal">bit_length('jose')</code>
+ → <code class="returnvalue">32</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.5.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.10.5.2.2.5.1.1.2" class="indexterm"></a>
+ <a id="id-1.5.8.10.5.2.2.5.1.1.3" class="indexterm"></a>
+ <code class="function">char_length</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.5.1.2.1" class="indexterm"></a>
+ <code class="function">character_length</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of characters in the string.
+ </p>
+ <p>
+ <code class="literal">char_length('josé')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">lower</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the string to all lower case, according to the rules of the
+ database's locale.
+ </p>
+ <p>
+ <code class="literal">lower('TOM')</code>
+ → <code class="returnvalue">tom</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.7.1.1.1" class="indexterm"></a>
+ <a id="id-1.5.8.10.5.2.2.7.1.1.2" class="indexterm"></a>
+ <code class="function">normalize</code> ( <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>form</code></em> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the string to the specified Unicode
+ normalization form. The optional <em class="parameter"><code>form</code></em> key word
+ specifies the form: <code class="literal">NFC</code> (the default),
+ <code class="literal">NFD</code>, <code class="literal">NFKC</code>, or
+ <code class="literal">NFKD</code>. This function can only be used when the
+ server encoding is <code class="literal">UTF8</code>.
+ </p>
+ <p>
+ <code class="literal">normalize(U&amp;'\0061\0308bc', NFC)</code>
+ → <code class="returnvalue">U&amp;'\00E4bc'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">octet_length</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bytes in the string.
+ </p>
+ <p>
+ <code class="literal">octet_length('josé')</code>
+ → <code class="returnvalue">5</code> (if server encoding is UTF8)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">octet_length</code> ( <code class="type">character</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of bytes in the string. Since this version of the
+ function accepts type <code class="type">character</code> directly, it will not
+ strip trailing spaces.
+ </p>
+ <p>
+ <code class="literal">octet_length('abc '::character(4))</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">overlay</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code> <code class="literal">PLACING</code> <em class="parameter"><code>newsubstring</code></em> <code class="type">text</code> <code class="literal">FROM</code> <em class="parameter"><code>start</code></em> <code class="type">integer</code> [<span class="optional"> <code class="literal">FOR</code> <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Replaces the substring of <em class="parameter"><code>string</code></em> that starts at
+ the <em class="parameter"><code>start</code></em>'th character and extends
+ for <em class="parameter"><code>count</code></em> characters
+ with <em class="parameter"><code>newsubstring</code></em>.
+ If <em class="parameter"><code>count</code></em> is omitted, it defaults to the length
+ of <em class="parameter"><code>newsubstring</code></em>.
+ </p>
+ <p>
+ <code class="literal">overlay('Txxxxas' placing 'hom' from 2 for 4)</code>
+ → <code class="returnvalue">Thomas</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">position</code> ( <em class="parameter"><code>substring</code></em> <code class="type">text</code> <code class="literal">IN</code> <em class="parameter"><code>string</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns first starting index of the specified
+ <em class="parameter"><code>substring</code></em> within
+ <em class="parameter"><code>string</code></em>, or zero if it's not present.
+ </p>
+ <p>
+ <code class="literal">position('om' in 'Thomas')</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">substring</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code> [<span class="optional"> <code class="literal">FROM</code> <em class="parameter"><code>start</code></em> <code class="type">integer</code> </span>] [<span class="optional"> <code class="literal">FOR</code> <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts the substring of <em class="parameter"><code>string</code></em> starting at
+ the <em class="parameter"><code>start</code></em>'th character if that is specified,
+ and stopping after <em class="parameter"><code>count</code></em> characters if that is
+ specified. Provide at least one of <em class="parameter"><code>start</code></em>
+ and <em class="parameter"><code>count</code></em>.
+ </p>
+ <p>
+ <code class="literal">substring('Thomas' from 2 for 3)</code>
+ → <code class="returnvalue">hom</code>
+ </p>
+ <p>
+ <code class="literal">substring('Thomas' from 3)</code>
+ → <code class="returnvalue">omas</code>
+ </p>
+ <p>
+ <code class="literal">substring('Thomas' for 2)</code>
+ → <code class="returnvalue">Th</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">substring</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code> <code class="literal">FROM</code> <em class="parameter"><code>pattern</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts the first substring matching POSIX regular expression; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">substring('Thomas' from '...$')</code>
+ → <code class="returnvalue">mas</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">substring</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code> <code class="literal">SIMILAR</code> <em class="parameter"><code>pattern</code></em> <code class="type">text</code> <code class="literal">ESCAPE</code> <em class="parameter"><code>escape</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">substring</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code> <code class="literal">FROM</code> <em class="parameter"><code>pattern</code></em> <code class="type">text</code> <code class="literal">FOR</code> <em class="parameter"><code>escape</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts the first substring matching <acronym class="acronym">SQL</acronym> regular expression;
+ see <a class="xref" href="functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP" title="9.7.2. SIMILAR TO Regular Expressions">Section 9.7.2</a>. The first form has
+ been specified since SQL:2003; the second form was only in SQL:1999
+ and should be considered obsolete.
+ </p>
+ <p>
+ <code class="literal">substring('Thomas' similar '%#"o_a#"_' escape '#')</code>
+ → <code class="returnvalue">oma</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">trim</code> ( [<span class="optional"> <code class="literal">LEADING</code> | <code class="literal">TRAILING</code> | <code class="literal">BOTH</code> </span>]
+ [<span class="optional"> <em class="parameter"><code>characters</code></em> <code class="type">text</code> </span>] <code class="literal">FROM</code>
+ <em class="parameter"><code>string</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Removes the longest string containing only characters in
+ <em class="parameter"><code>characters</code></em> (a space by default) from the
+ start, end, or both ends (<code class="literal">BOTH</code> is the default)
+ of <em class="parameter"><code>string</code></em>.
+ </p>
+ <p>
+ <code class="literal">trim(both 'xyz' from 'yxTomxx')</code>
+ → <code class="returnvalue">Tom</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">trim</code> ( [<span class="optional"> <code class="literal">LEADING</code> | <code class="literal">TRAILING</code> | <code class="literal">BOTH</code> </span>] [<span class="optional"> <code class="literal">FROM</code> </span>]
+ <em class="parameter"><code>string</code></em> <code class="type">text</code> [<span class="optional">,
+ <em class="parameter"><code>characters</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ This is a non-standard syntax for <code class="function">trim()</code>.
+ </p>
+ <p>
+ <code class="literal">trim(both from 'yxTomxx', 'xyz')</code>
+ → <code class="returnvalue">Tom</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.5.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">upper</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the string to all upper case, according to the rules of the
+ database's locale.
+ </p>
+ <p>
+ <code class="literal">upper('tom')</code>
+ → <code class="returnvalue">TOM</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Additional string manipulation functions and operators are available
+ and are listed in <a class="xref" href="functions-string.html#FUNCTIONS-STRING-OTHER" title="Table 9.10. Other String Functions and Operators">Table 9.10</a>. (Some of
+ these are used internally to implement
+ the <acronym class="acronym">SQL</acronym>-standard string functions listed in
+ <a class="xref" href="functions-string.html#FUNCTIONS-STRING-SQL" title="Table 9.9. SQL String Functions and Operators">Table 9.9</a>.)
+ There are also pattern-matching operators, which are described in
+ <a class="xref" href="functions-matching.html" title="9.7. Pattern Matching">Section 9.7</a>, and operators for full-text
+ search, which are described in <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a>.
+ </p><div class="table" id="FUNCTIONS-STRING-OTHER"><p class="title"><strong>Table 9.10. Other String Functions and Operators</strong></p><div class="table-contents"><table class="table" summary="Other String Functions and Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function/Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="type">text</code> <code class="literal">^@</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if the first string starts with the second string
+ (equivalent to the <code class="function">starts_with()</code> function).
+ </p>
+ <p>
+ <code class="literal">'alphabet' ^@ 'alph'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">ascii</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the numeric code of the first character of the argument.
+ In <acronym class="acronym">UTF8</acronym> encoding, returns the Unicode code point
+ of the character. In other multibyte encodings, the argument must
+ be an <acronym class="acronym">ASCII</acronym> character.
+ </p>
+ <p>
+ <code class="literal">ascii('x')</code>
+ → <code class="returnvalue">120</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">btrim</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>characters</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Removes the longest string containing only characters
+ in <em class="parameter"><code>characters</code></em> (a space by default)
+ from the start and end of <em class="parameter"><code>string</code></em>.
+ </p>
+ <p>
+ <code class="literal">btrim('xyxtrimyyx', 'xyz')</code>
+ → <code class="returnvalue">trim</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">chr</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the character with the given code. In <acronym class="acronym">UTF8</acronym>
+ encoding the argument is treated as a Unicode code point. In other
+ multibyte encodings the argument must designate
+ an <acronym class="acronym">ASCII</acronym> character. <code class="literal">chr(0)</code> is
+ disallowed because text data types cannot store that character.
+ </p>
+ <p>
+ <code class="literal">chr(65)</code>
+ → <code class="returnvalue">A</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">concat</code> ( <em class="parameter"><code>val1</code></em> <code class="type">"any"</code>
+ [, <em class="parameter"><code>val2</code></em> <code class="type">"any"</code> [, ...] ] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Concatenates the text representations of all the arguments.
+ NULL arguments are ignored.
+ </p>
+ <p>
+ <code class="literal">concat('abcde', 2, NULL, 22)</code>
+ → <code class="returnvalue">abcde222</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">concat_ws</code> ( <em class="parameter"><code>sep</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>val1</code></em> <code class="type">"any"</code>
+ [, <em class="parameter"><code>val2</code></em> <code class="type">"any"</code> [, ...] ] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Concatenates all but the first argument, with separators. The first
+ argument is used as the separator string, and should not be NULL.
+ Other NULL arguments are ignored.
+ </p>
+ <p>
+ <code class="literal">concat_ws(',', 'abcde', 2, NULL, 22)</code>
+ → <code class="returnvalue">abcde,2,22</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">format</code> ( <em class="parameter"><code>formatstr</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>formatarg</code></em> <code class="type">"any"</code> [, ...] ] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Formats arguments according to a format string;
+ see <a class="xref" href="functions-string.html#FUNCTIONS-STRING-FORMAT" title="9.4.1. format">Section 9.4.1</a>.
+ This function is similar to the C function <code class="function">sprintf</code>.
+ </p>
+ <p>
+ <code class="literal">format('Hello %s, %1$s', 'World')</code>
+ → <code class="returnvalue">Hello World, World</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">initcap</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the first letter of each word to upper case and the
+ rest to lower case. Words are sequences of alphanumeric
+ characters separated by non-alphanumeric characters.
+ </p>
+ <p>
+ <code class="literal">initcap('hi THOMAS')</code>
+ → <code class="returnvalue">Hi Thomas</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">left</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns first <em class="parameter"><code>n</code></em> characters in the
+ string, or when <em class="parameter"><code>n</code></em> is negative, returns
+ all but last |<em class="parameter"><code>n</code></em>| characters.
+ </p>
+ <p>
+ <code class="literal">left('abcde', 2)</code>
+ → <code class="returnvalue">ab</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">length</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of characters in the string.
+ </p>
+ <p>
+ <code class="literal">length('jose')</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">lpad</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>length</code></em> <code class="type">integer</code>
+ [<span class="optional">, <em class="parameter"><code>fill</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extends the <em class="parameter"><code>string</code></em> to length
+ <em class="parameter"><code>length</code></em> by prepending the characters
+ <em class="parameter"><code>fill</code></em> (a space by default). If the
+ <em class="parameter"><code>string</code></em> is already longer than
+ <em class="parameter"><code>length</code></em> then it is truncated (on the right).
+ </p>
+ <p>
+ <code class="literal">lpad('hi', 5, 'xy')</code>
+ → <code class="returnvalue">xyxhi</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">ltrim</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>characters</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Removes the longest string containing only characters in
+ <em class="parameter"><code>characters</code></em> (a space by default) from the start of
+ <em class="parameter"><code>string</code></em>.
+ </p>
+ <p>
+ <code class="literal">ltrim('zzzytest', 'xyz')</code>
+ → <code class="returnvalue">test</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">md5</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Computes the MD5 <a class="link" href="functions-binarystring.html#FUNCTIONS-HASH-NOTE">hash</a> of
+ the argument, with the result written in hexadecimal.
+ </p>
+ <p>
+ <code class="literal">md5('abc')</code>
+ → <code class="returnvalue">900150983cd24fb0​d6963f7d28e17f72</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">parse_ident</code> ( <em class="parameter"><code>qualified_identifier</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>strict_mode</code></em> <code class="type">boolean</code> <code class="literal">DEFAULT</code> <code class="literal">true</code> ] )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Splits <em class="parameter"><code>qualified_identifier</code></em> into an array of
+ identifiers, removing any quoting of individual identifiers. By
+ default, extra characters after the last identifier are considered an
+ error; but if the second parameter is <code class="literal">false</code>, then such
+ extra characters are ignored. (This behavior is useful for parsing
+ names for objects like functions.) Note that this function does not
+ truncate over-length identifiers. If you want truncation you can cast
+ the result to <code class="type">name[]</code>.
+ </p>
+ <p>
+ <code class="literal">parse_ident('"SomeSchema".someTable')</code>
+ → <code class="returnvalue">{SomeSchema,sometable}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">pg_client_encoding</code> ( )
+ → <code class="returnvalue">name</code>
+ </p>
+ <p>
+ Returns current client encoding name.
+ </p>
+ <p>
+ <code class="literal">pg_client_encoding()</code>
+ → <code class="returnvalue">UTF8</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">quote_ident</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the given string suitably quoted to be used as an identifier
+ in an <acronym class="acronym">SQL</acronym> statement string.
+ Quotes are added only if necessary (i.e., if the string contains
+ non-identifier characters or would be case-folded).
+ Embedded quotes are properly doubled.
+ See also <a class="xref" href="plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE" title="Example 43.1. Quoting Values in Dynamic Queries">Example 43.1</a>.
+ </p>
+ <p>
+ <code class="literal">quote_ident('Foo bar')</code>
+ → <code class="returnvalue">"Foo bar"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">quote_literal</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the given string suitably quoted to be used as a string literal
+ in an <acronym class="acronym">SQL</acronym> statement string.
+ Embedded single-quotes and backslashes are properly doubled.
+ Note that <code class="function">quote_literal</code> returns null on null
+ input; if the argument might be null,
+ <code class="function">quote_nullable</code> is often more suitable.
+ See also <a class="xref" href="plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE" title="Example 43.1. Quoting Values in Dynamic Queries">Example 43.1</a>.
+ </p>
+ <p>
+ <code class="literal">quote_literal(E'O\'Reilly')</code>
+ → <code class="returnvalue">'O''Reilly'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">quote_literal</code> ( <code class="type">anyelement</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the given value to text and then quotes it as a literal.
+ Embedded single-quotes and backslashes are properly doubled.
+ </p>
+ <p>
+ <code class="literal">quote_literal(42.5)</code>
+ → <code class="returnvalue">'42.5'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">quote_nullable</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the given string suitably quoted to be used as a string literal
+ in an <acronym class="acronym">SQL</acronym> statement string; or, if the argument
+ is null, returns <code class="literal">NULL</code>.
+ Embedded single-quotes and backslashes are properly doubled.
+ See also <a class="xref" href="plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE" title="Example 43.1. Quoting Values in Dynamic Queries">Example 43.1</a>.
+ </p>
+ <p>
+ <code class="literal">quote_nullable(NULL)</code>
+ → <code class="returnvalue">NULL</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">quote_nullable</code> ( <code class="type">anyelement</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the given value to text and then quotes it as a literal;
+ or, if the argument is null, returns <code class="literal">NULL</code>.
+ Embedded single-quotes and backslashes are properly doubled.
+ </p>
+ <p>
+ <code class="literal">quote_nullable(42.5)</code>
+ → <code class="returnvalue">'42.5'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_count</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>start</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] ] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of times the POSIX regular
+ expression <em class="parameter"><code>pattern</code></em> matches in
+ the <em class="parameter"><code>string</code></em>; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_count('123456789012', '\d\d\d', 2)</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_instr</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>start</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>N</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>endoption</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>flags</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>subexpr</code></em> <code class="type">integer</code> ] ] ] ] ] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the position within <em class="parameter"><code>string</code></em> where
+ the <em class="parameter"><code>N</code></em>'th match of the POSIX regular
+ expression <em class="parameter"><code>pattern</code></em> occurs, or zero if there is
+ no such match; see <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i')</code>
+ → <code class="returnvalue">3</code>
+ </p>
+ <p>
+ <code class="literal">regexp_instr('ABCDEF', 'c(.)(..)', 1, 1, 0, 'i', 2)</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_like</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Checks whether a match of the POSIX regular
+ expression <em class="parameter"><code>pattern</code></em> occurs
+ within <em class="parameter"><code>string</code></em>; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_like('Hello World', 'world$', 'i')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.24.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_match</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code> [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Returns substrings within the first match of the POSIX regular
+ expression <em class="parameter"><code>pattern</code></em> to
+ the <em class="parameter"><code>string</code></em>; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_match('foobarbequebaz', '(bar)(beque)')</code>
+ → <code class="returnvalue">{bar,beque}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.25.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_matches</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code> [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">setof text[]</code>
+ </p>
+ <p>
+ Returns substrings within the first match of the POSIX regular
+ expression <em class="parameter"><code>pattern</code></em> to
+ the <em class="parameter"><code>string</code></em>, or substrings within all
+ such matches if the <code class="literal">g</code> flag is used;
+ see <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_matches('foobarbequebaz', 'ba.', 'g')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ {bar}
+ {baz}
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.26.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_replace</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code>, <em class="parameter"><code>replacement</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>start</code></em> <code class="type">integer</code> ]
+ [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Replaces the substring that is the first match to the POSIX
+ regular expression <em class="parameter"><code>pattern</code></em>, or all such
+ matches if the <code class="literal">g</code> flag is used; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_replace('Thomas', '.[mN]a.', 'M')</code>
+ → <code class="returnvalue">ThM</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">regexp_replace</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code>, <em class="parameter"><code>replacement</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>start</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>N</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Replaces the substring that is the <em class="parameter"><code>N</code></em>'th
+ match to the POSIX regular expression <em class="parameter"><code>pattern</code></em>,
+ or all such matches if <em class="parameter"><code>N</code></em> is zero; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_replace('Thomas', '.', 'X', 3, 2)</code>
+ → <code class="returnvalue">ThoXas</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.28.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_split_to_array</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code> [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Splits <em class="parameter"><code>string</code></em> using a POSIX regular
+ expression as the delimiter, producing an array of results; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_split_to_array('hello world', '\s+')</code>
+ → <code class="returnvalue">{hello,world}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.29.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_split_to_table</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code> [, <em class="parameter"><code>flags</code></em> <code class="type">text</code> ] )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Splits <em class="parameter"><code>string</code></em> using a POSIX regular
+ expression as the delimiter, producing a set of results; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_split_to_table('hello world', '\s+')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ hello
+ world
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.30.1.1.1" class="indexterm"></a>
+ <code class="function">regexp_substr</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>pattern</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>start</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>N</code></em> <code class="type">integer</code>
+ [, <em class="parameter"><code>flags</code></em> <code class="type">text</code>
+ [, <em class="parameter"><code>subexpr</code></em> <code class="type">integer</code> ] ] ] ] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the substring within <em class="parameter"><code>string</code></em> that
+ matches the <em class="parameter"><code>N</code></em>'th occurrence of the POSIX
+ regular expression <em class="parameter"><code>pattern</code></em>,
+ or <code class="literal">NULL</code> if there is no such match; see
+ <a class="xref" href="functions-matching.html#FUNCTIONS-POSIX-REGEXP" title="9.7.3. POSIX Regular Expressions">Section 9.7.3</a>.
+ </p>
+ <p>
+ <code class="literal">regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i')</code>
+ → <code class="returnvalue">CDEF</code>
+ </p>
+ <p>
+ <code class="literal">regexp_substr('ABCDEF', 'c(.)(..)', 1, 1, 'i', 2)</code>
+ → <code class="returnvalue">EF</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.31.1.1.1" class="indexterm"></a>
+ <code class="function">repeat</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>number</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Repeats <em class="parameter"><code>string</code></em> the specified
+ <em class="parameter"><code>number</code></em> of times.
+ </p>
+ <p>
+ <code class="literal">repeat('Pg', 4)</code>
+ → <code class="returnvalue">PgPgPgPg</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.32.1.1.1" class="indexterm"></a>
+ <code class="function">replace</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>from</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>to</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Replaces all occurrences in <em class="parameter"><code>string</code></em> of
+ substring <em class="parameter"><code>from</code></em> with
+ substring <em class="parameter"><code>to</code></em>.
+ </p>
+ <p>
+ <code class="literal">replace('abcdefabcdef', 'cd', 'XX')</code>
+ → <code class="returnvalue">abXXefabXXef</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.33.1.1.1" class="indexterm"></a>
+ <code class="function">reverse</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Reverses the order of the characters in the string.
+ </p>
+ <p>
+ <code class="literal">reverse('abcde')</code>
+ → <code class="returnvalue">edcba</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.34.1.1.1" class="indexterm"></a>
+ <code class="function">right</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns last <em class="parameter"><code>n</code></em> characters in the string,
+ or when <em class="parameter"><code>n</code></em> is negative, returns all but
+ first |<em class="parameter"><code>n</code></em>| characters.
+ </p>
+ <p>
+ <code class="literal">right('abcde', 2)</code>
+ → <code class="returnvalue">de</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.35.1.1.1" class="indexterm"></a>
+ <code class="function">rpad</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>length</code></em> <code class="type">integer</code>
+ [<span class="optional">, <em class="parameter"><code>fill</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extends the <em class="parameter"><code>string</code></em> to length
+ <em class="parameter"><code>length</code></em> by appending the characters
+ <em class="parameter"><code>fill</code></em> (a space by default). If the
+ <em class="parameter"><code>string</code></em> is already longer than
+ <em class="parameter"><code>length</code></em> then it is truncated.
+ </p>
+ <p>
+ <code class="literal">rpad('hi', 5, 'xy')</code>
+ → <code class="returnvalue">hixyx</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.36.1.1.1" class="indexterm"></a>
+ <code class="function">rtrim</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>characters</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Removes the longest string containing only characters in
+ <em class="parameter"><code>characters</code></em> (a space by default) from the end of
+ <em class="parameter"><code>string</code></em>.
+ </p>
+ <p>
+ <code class="literal">rtrim('testxxzx', 'xyz')</code>
+ → <code class="returnvalue">test</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.37.1.1.1" class="indexterm"></a>
+ <code class="function">split_part</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>delimiter</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Splits <em class="parameter"><code>string</code></em> at occurrences
+ of <em class="parameter"><code>delimiter</code></em> and returns
+ the <em class="parameter"><code>n</code></em>'th field (counting from one),
+ or when <em class="parameter"><code>n</code></em> is negative, returns
+ the |<em class="parameter"><code>n</code></em>|'th-from-last field.
+ </p>
+ <p>
+ <code class="literal">split_part('abc~@~def~@~ghi', '~@~', 2)</code>
+ → <code class="returnvalue">def</code>
+ </p>
+ <p>
+ <code class="literal">split_part('abc,def,ghi,jkl', ',', -2)</code>
+ → <code class="returnvalue">ghi</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.38.1.1.1" class="indexterm"></a>
+ <code class="function">starts_with</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>prefix</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns true if <em class="parameter"><code>string</code></em> starts
+ with <em class="parameter"><code>prefix</code></em>.
+ </p>
+ <p>
+ <code class="literal">starts_with('alphabet', 'alph')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="FUNCTION-STRING-TO-ARRAY" class="indexterm"></a>
+ <code class="function">string_to_array</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>delimiter</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>null_string</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Splits the <em class="parameter"><code>string</code></em> at occurrences
+ of <em class="parameter"><code>delimiter</code></em> and forms the resulting fields
+ into a <code class="type">text</code> array.
+ If <em class="parameter"><code>delimiter</code></em> is <code class="literal">NULL</code>,
+ each character in the <em class="parameter"><code>string</code></em> will become a
+ separate element in the array.
+ If <em class="parameter"><code>delimiter</code></em> is an empty string, then
+ the <em class="parameter"><code>string</code></em> is treated as a single field.
+ If <em class="parameter"><code>null_string</code></em> is supplied and is
+ not <code class="literal">NULL</code>, fields matching that string are
+ replaced by <code class="literal">NULL</code>.
+ See also <a class="link" href="functions-array.html#FUNCTION-ARRAY-TO-STRING"><code class="function">array_to_string</code></a>.
+ </p>
+ <p>
+ <code class="literal">string_to_array('xx~~yy~~zz', '~~', 'yy')</code>
+ → <code class="returnvalue">{xx,NULL,zz}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.40.1.1.1" class="indexterm"></a>
+ <code class="function">string_to_table</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>delimiter</code></em> <code class="type">text</code> [<span class="optional">, <em class="parameter"><code>null_string</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Splits the <em class="parameter"><code>string</code></em> at occurrences
+ of <em class="parameter"><code>delimiter</code></em> and returns the resulting fields
+ as a set of <code class="type">text</code> rows.
+ If <em class="parameter"><code>delimiter</code></em> is <code class="literal">NULL</code>,
+ each character in the <em class="parameter"><code>string</code></em> will become a
+ separate row of the result.
+ If <em class="parameter"><code>delimiter</code></em> is an empty string, then
+ the <em class="parameter"><code>string</code></em> is treated as a single field.
+ If <em class="parameter"><code>null_string</code></em> is supplied and is
+ not <code class="literal">NULL</code>, fields matching that string are
+ replaced by <code class="literal">NULL</code>.
+ </p>
+ <p>
+ <code class="literal">string_to_table('xx~^~yy~^~zz', '~^~', 'yy')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ xx
+ NULL
+ zz
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.41.1.1.1" class="indexterm"></a>
+ <code class="function">strpos</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>substring</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns first starting index of the specified <em class="parameter"><code>substring</code></em>
+ within <em class="parameter"><code>string</code></em>, or zero if it's not present.
+ (Same as <code class="literal">position(<em class="parameter"><code>substring</code></em> in
+ <em class="parameter"><code>string</code></em>)</code>, but note the reversed
+ argument order.)
+ </p>
+ <p>
+ <code class="literal">strpos('high', 'ig')</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.42.1.1.1" class="indexterm"></a>
+ <code class="function">substr</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>, <em class="parameter"><code>start</code></em> <code class="type">integer</code> [<span class="optional">, <em class="parameter"><code>count</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Extracts the substring of <em class="parameter"><code>string</code></em> starting at
+ the <em class="parameter"><code>start</code></em>'th character,
+ and extending for <em class="parameter"><code>count</code></em> characters if that is
+ specified. (Same
+ as <code class="literal">substring(<em class="parameter"><code>string</code></em>
+ from <em class="parameter"><code>start</code></em>
+ for <em class="parameter"><code>count</code></em>)</code>.)
+ </p>
+ <p>
+ <code class="literal">substr('alphabet', 3)</code>
+ → <code class="returnvalue">phabet</code>
+ </p>
+ <p>
+ <code class="literal">substr('alphabet', 3, 2)</code>
+ → <code class="returnvalue">ph</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.43.1.1.1" class="indexterm"></a>
+ <code class="function">to_ascii</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">to_ascii</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>encoding</code></em> <code class="type">name</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">to_ascii</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>encoding</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts <em class="parameter"><code>string</code></em> to <acronym class="acronym">ASCII</acronym>
+ from another encoding, which may be identified by name or number.
+ If <em class="parameter"><code>encoding</code></em> is omitted the database encoding
+ is assumed (which in practice is the only useful case).
+ The conversion consists primarily of dropping accents.
+ Conversion is only supported
+ from <code class="literal">LATIN1</code>, <code class="literal">LATIN2</code>,
+ <code class="literal">LATIN9</code>, and <code class="literal">WIN1250</code> encodings.
+ (See the <a class="xref" href="unaccent.html" title="F.48. unaccent">unaccent</a> module for another, more flexible
+ solution.)
+ </p>
+ <p>
+ <code class="literal">to_ascii('Karél')</code>
+ → <code class="returnvalue">Karel</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.44.1.1.1" class="indexterm"></a>
+ <code class="function">to_hex</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">to_hex</code> ( <code class="type">bigint</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Converts the number to its equivalent hexadecimal representation.
+ </p>
+ <p>
+ <code class="literal">to_hex(2147483647)</code>
+ → <code class="returnvalue">7fffffff</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.45.1.1.1" class="indexterm"></a>
+ <code class="function">translate</code> ( <em class="parameter"><code>string</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>from</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>to</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Replaces each character in <em class="parameter"><code>string</code></em> that
+ matches a character in the <em class="parameter"><code>from</code></em> set with the
+ corresponding character in the <em class="parameter"><code>to</code></em>
+ set. If <em class="parameter"><code>from</code></em> is longer than
+ <em class="parameter"><code>to</code></em>, occurrences of the extra characters in
+ <em class="parameter"><code>from</code></em> are deleted.
+ </p>
+ <p>
+ <code class="literal">translate('12345', '143', 'ax')</code>
+ → <code class="returnvalue">a2x5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.10.7.2.2.46.1.1.1" class="indexterm"></a>
+ <code class="function">unistr</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Evaluate escaped Unicode characters in the argument. Unicode characters
+ can be specified as
+ <code class="literal">\<em class="replaceable"><code>XXXX</code></em></code> (4 hexadecimal
+ digits), <code class="literal">\+<em class="replaceable"><code>XXXXXX</code></em></code> (6
+ hexadecimal digits),
+ <code class="literal">\u<em class="replaceable"><code>XXXX</code></em></code> (4 hexadecimal
+ digits), or <code class="literal">\U<em class="replaceable"><code>XXXXXXXX</code></em></code>
+ (8 hexadecimal digits). To specify a backslash, write two
+ backslashes. All other characters are taken literally.
+ </p>
+
+ <p>
+ If the server encoding is not UTF-8, the Unicode code point identified
+ by one of these escape sequences is converted to the actual server
+ encoding; an error is reported if that's not possible.
+ </p>
+
+ <p>
+ This function provides a (non-standard) alternative to string
+ constants with Unicode escapes (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE" title="4.1.2.3. String Constants with Unicode Escapes">Section 4.1.2.3</a>).
+ </p>
+
+ <p>
+ <code class="literal">unistr('d\0061t\+000061')</code>
+ → <code class="returnvalue">data</code>
+ </p>
+ <p>
+ <code class="literal">unistr('d\u0061t\U00000061')</code>
+ → <code class="returnvalue">data</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="function">concat</code>, <code class="function">concat_ws</code> and
+ <code class="function">format</code> functions are variadic, so it is possible to
+ pass the values to be concatenated or formatted as an array marked with
+ the <code class="literal">VARIADIC</code> keyword (see <a class="xref" href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS" title="38.5.6. SQL Functions with Variable Numbers of Arguments">Section 38.5.6</a>). The array's elements are
+ treated as if they were separate ordinary arguments to the function.
+ If the variadic array argument is NULL, <code class="function">concat</code>
+ and <code class="function">concat_ws</code> return NULL, but
+ <code class="function">format</code> treats a NULL as a zero-element array.
+ </p><p>
+ See also the aggregate function <code class="function">string_agg</code> in
+ <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a>, and the functions for
+ converting between strings and the <code class="type">bytea</code> type in
+ <a class="xref" href="functions-binarystring.html#FUNCTIONS-BINARYSTRING-CONVERSIONS" title="Table 9.13. Text/Binary String Conversion Functions">Table 9.13</a>.
+ </p><div class="sect2" id="FUNCTIONS-STRING-FORMAT"><div class="titlepage"><div><div><h3 class="title">9.4.1. <code class="function">format</code></h3></div></div></div><a id="id-1.5.8.10.10.2" class="indexterm"></a><p>
+ The function <code class="function">format</code> produces output formatted according to
+ a format string, in a style similar to the C function
+ <code class="function">sprintf</code>.
+ </p><p>
+</p><pre class="synopsis">
+<code class="function">format</code>(<em class="parameter"><code>formatstr</code></em> <code class="type">text</code> [, <em class="parameter"><code>formatarg</code></em> <code class="type">"any"</code> [, ...] ])
+</pre><p>
+ <em class="parameter"><code>formatstr</code></em> is a format string that specifies how the
+ result should be formatted. Text in the format string is copied
+ directly to the result, except where <em class="firstterm">format specifiers</em> are
+ used. Format specifiers act as placeholders in the string, defining how
+ subsequent function arguments should be formatted and inserted into the
+ result. Each <em class="parameter"><code>formatarg</code></em> argument is converted to text
+ according to the usual output rules for its data type, and then formatted
+ and inserted into the result string according to the format specifier(s).
+ </p><p>
+ Format specifiers are introduced by a <code class="literal">%</code> character and have
+ the form
+</p><pre class="synopsis">
+%[<em class="parameter"><code>position</code></em>][<em class="parameter"><code>flags</code></em>][<em class="parameter"><code>width</code></em>]<em class="parameter"><code>type</code></em>
+</pre><p>
+ where the component fields are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>position</code></em> (optional)</span></dt><dd><p>
+ A string of the form <code class="literal"><em class="parameter"><code>n</code></em>$</code> where
+ <em class="parameter"><code>n</code></em> is the index of the argument to print.
+ Index 1 means the first argument after
+ <em class="parameter"><code>formatstr</code></em>. If the <em class="parameter"><code>position</code></em> is
+ omitted, the default is to use the next argument in sequence.
+ </p></dd><dt><span class="term"><em class="parameter"><code>flags</code></em> (optional)</span></dt><dd><p>
+ Additional options controlling how the format specifier's output is
+ formatted. Currently the only supported flag is a minus sign
+ (<code class="literal">-</code>) which will cause the format specifier's output to be
+ left-justified. This has no effect unless the <em class="parameter"><code>width</code></em>
+ field is also specified.
+ </p></dd><dt><span class="term"><em class="parameter"><code>width</code></em> (optional)</span></dt><dd><p>
+ Specifies the <span class="emphasis"><em>minimum</em></span> number of characters to use to
+ display the format specifier's output. The output is padded on the
+ left or right (depending on the <code class="literal">-</code> flag) with spaces as
+ needed to fill the width. A too-small width does not cause
+ truncation of the output, but is simply ignored. The width may be
+ specified using any of the following: a positive integer; an
+ asterisk (<code class="literal">*</code>) to use the next function argument as the
+ width; or a string of the form <code class="literal">*<em class="parameter"><code>n</code></em>$</code> to
+ use the <em class="parameter"><code>n</code></em>th function argument as the width.
+ </p><p>
+ If the width comes from a function argument, that argument is
+ consumed before the argument that is used for the format specifier's
+ value. If the width argument is negative, the result is left
+ aligned (as if the <code class="literal">-</code> flag had been specified) within a
+ field of length <code class="function">abs</code>(<em class="parameter"><code>width</code></em>).
+ </p></dd><dt><span class="term"><em class="parameter"><code>type</code></em> (required)</span></dt><dd><p>
+ The type of format conversion to use to produce the format
+ specifier's output. The following types are supported:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">s</code> formats the argument value as a simple
+ string. A null value is treated as an empty string.
+ </p></li><li class="listitem"><p>
+ <code class="literal">I</code> treats the argument value as an SQL
+ identifier, double-quoting it if necessary.
+ It is an error for the value to be null (equivalent to
+ <code class="function">quote_ident</code>).
+ </p></li><li class="listitem"><p>
+ <code class="literal">L</code> quotes the argument value as an SQL literal.
+ A null value is displayed as the string <code class="literal">NULL</code>, without
+ quotes (equivalent to <code class="function">quote_nullable</code>).
+ </p></li></ul></div><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ In addition to the format specifiers described above, the special sequence
+ <code class="literal">%%</code> may be used to output a literal <code class="literal">%</code> character.
+ </p><p>
+ Here are some examples of the basic format conversions:
+
+</p><pre class="screen">
+SELECT format('Hello %s', 'World');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">Hello World</code>
+
+SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">Testing one, two, three, %</code>
+
+SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">INSERT INTO "Foo bar" VALUES('O''Reilly')</code>
+
+SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">INSERT INTO locations VALUES('C:\Program Files')</code>
+</pre><p>
+ </p><p>
+ Here are examples using <em class="parameter"><code>width</code></em> fields
+ and the <code class="literal">-</code> flag:
+
+</p><pre class="screen">
+SELECT format('|%10s|', 'foo');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">| foo|</code>
+
+SELECT format('|%-10s|', 'foo');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">|foo |</code>
+
+SELECT format('|%*s|', 10, 'foo');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">| foo|</code>
+
+SELECT format('|%*s|', -10, 'foo');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">|foo |</code>
+
+SELECT format('|%-*s|', 10, 'foo');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">|foo |</code>
+
+SELECT format('|%-*s|', -10, 'foo');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">|foo |</code>
+</pre><p>
+ </p><p>
+ These examples show use of <em class="parameter"><code>position</code></em> fields:
+
+</p><pre class="screen">
+SELECT format('Testing %3$s, %2$s, %1$s', 'one', 'two', 'three');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">Testing three, two, one</code>
+
+SELECT format('|%*2$s|', 'foo', 10, 'bar');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">| bar|</code>
+
+SELECT format('|%1$*2$s|', 'foo', 10, 'bar');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">| foo|</code>
+</pre><p>
+ </p><p>
+ Unlike the standard C function <code class="function">sprintf</code>,
+ <span class="productname">PostgreSQL</span>'s <code class="function">format</code> function allows format
+ specifiers with and without <em class="parameter"><code>position</code></em> fields to be mixed
+ in the same format string. A format specifier without a
+ <em class="parameter"><code>position</code></em> field always uses the next argument after the
+ last argument consumed.
+ In addition, the <code class="function">format</code> function does not require all
+ function arguments to be used in the format string.
+ For example:
+
+</p><pre class="screen">
+SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three');
+<em class="lineannotation"><span class="lineannotation">Result: </span></em><code class="computeroutput">Testing three, two, three</code>
+</pre><p>
+ </p><p>
+ The <code class="literal">%I</code> and <code class="literal">%L</code> format specifiers are particularly
+ useful for safely constructing dynamic SQL statements. See
+ <a class="xref" href="plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE" title="Example 43.1. Quoting Values in Dynamic Queries">Example 43.1</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-math.html" title="9.3. Mathematical Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-binarystring.html" title="9.5. Binary String Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.3. Mathematical Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.5. Binary String Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-subquery.html b/doc/src/sgml/html/functions-subquery.html
new file mode 100644
index 0000000..a57a277
--- /dev/null
+++ b/doc/src/sgml/html/functions-subquery.html
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.23. Subquery Expressions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-window.html" title="9.22. Window Functions" /><link rel="next" href="functions-comparisons.html" title="9.24. Row and Array Comparisons" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.23. Subquery Expressions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-window.html" title="9.22. Window Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-comparisons.html" title="9.24. Row and Array Comparisons">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-SUBQUERY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.23. Subquery Expressions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-EXISTS">9.23.1. <code class="literal">EXISTS</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-IN">9.23.2. <code class="literal">IN</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-NOTIN">9.23.3. <code class="literal">NOT IN</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-ANY-SOME">9.23.4. <code class="literal">ANY</code>/<code class="literal">SOME</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-ALL">9.23.5. <code class="literal">ALL</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#id-1.5.8.29.15">9.23.6. Single-Row Comparison</a></span></dt></dl></div><a id="id-1.5.8.29.2" class="indexterm"></a><a id="id-1.5.8.29.3" class="indexterm"></a><a id="id-1.5.8.29.4" class="indexterm"></a><a id="id-1.5.8.29.5" class="indexterm"></a><a id="id-1.5.8.29.6" class="indexterm"></a><a id="id-1.5.8.29.7" class="indexterm"></a><a id="id-1.5.8.29.8" class="indexterm"></a><p>
+ This section describes the <acronym class="acronym">SQL</acronym>-compliant subquery
+ expressions available in <span class="productname">PostgreSQL</span>.
+ All of the expression forms documented in this section return
+ Boolean (true/false) results.
+ </p><div class="sect2" id="FUNCTIONS-SUBQUERY-EXISTS"><div class="titlepage"><div><div><h3 class="title">9.23.1. <code class="literal">EXISTS</code></h3></div></div></div><pre class="synopsis">
+EXISTS (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The argument of <code class="token">EXISTS</code> is an arbitrary <code class="command">SELECT</code> statement,
+ or <em class="firstterm">subquery</em>. The
+ subquery is evaluated to determine whether it returns any rows.
+ If it returns at least one row, the result of <code class="token">EXISTS</code> is
+ <span class="quote">“<span class="quote">true</span>”</span>; if the subquery returns no rows, the result of <code class="token">EXISTS</code>
+ is <span class="quote">“<span class="quote">false</span>”</span>.
+ </p><p>
+ The subquery can refer to variables from the surrounding query,
+ which will act as constants during any one evaluation of the subquery.
+ </p><p>
+ The subquery will generally only be executed long enough to determine
+ whether at least one row is returned, not all the way to completion.
+ It is unwise to write a subquery that has side effects (such as
+ calling sequence functions); whether the side effects occur
+ might be unpredictable.
+ </p><p>
+ Since the result depends only on whether any rows are returned,
+ and not on the contents of those rows, the output list of the
+ subquery is normally unimportant. A common coding convention is
+ to write all <code class="literal">EXISTS</code> tests in the form
+ <code class="literal">EXISTS(SELECT 1 WHERE ...)</code>. There are exceptions to
+ this rule however, such as subqueries that use <code class="token">INTERSECT</code>.
+ </p><p>
+ This simple example is like an inner join on <code class="literal">col2</code>, but
+ it produces at most one output row for each <code class="literal">tab1</code> row,
+ even if there are several matching <code class="literal">tab2</code> rows:
+</p><pre class="screen">
+SELECT col1
+FROM tab1
+WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
+</pre><p>
+ </p></div><div class="sect2" id="FUNCTIONS-SUBQUERY-IN"><div class="titlepage"><div><div><h3 class="title">9.23.2. <code class="literal">IN</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> IN (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <code class="token">IN</code> is <span class="quote">“<span class="quote">true</span>”</span> if any equal subquery row is found.
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if no equal row is found (including the
+ case where the subquery returns no rows).
+ </p><p>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <code class="token">IN</code> construct will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p><p>
+ As with <code class="token">EXISTS</code>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </p><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> IN (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The left-hand side of this form of <code class="token">IN</code> is a row constructor,
+ as described in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <code class="token">IN</code> is <span class="quote">“<span class="quote">true</span>”</span> if any equal subquery row is found.
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if no equal row is found (including the
+ case where the subquery returns no rows).
+ </p><p>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <code class="token">IN</code> is null.
+ </p></div><div class="sect2" id="FUNCTIONS-SUBQUERY-NOTIN"><div class="titlepage"><div><div><h3 class="title">9.23.3. <code class="literal">NOT IN</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> NOT IN (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result.
+ The result of <code class="token">NOT IN</code> is <span class="quote">“<span class="quote">true</span>”</span> if only unequal subquery rows
+ are found (including the case where the subquery returns no rows).
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if any equal row is found.
+ </p><p>
+ Note that if the left-hand expression yields null, or if there are
+ no equal right-hand values and at least one right-hand row yields
+ null, the result of the <code class="token">NOT IN</code> construct will be null, not true.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p><p>
+ As with <code class="token">EXISTS</code>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </p><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> NOT IN (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The left-hand side of this form of <code class="token">NOT IN</code> is a row constructor,
+ as described in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result.
+ The result of <code class="token">NOT IN</code> is <span class="quote">“<span class="quote">true</span>”</span> if only unequal subquery rows
+ are found (including the case where the subquery returns no rows).
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if any equal row is found.
+ </p><p>
+ As usual, null values in the rows are combined per
+ the normal rules of SQL Boolean expressions. Two rows are considered
+ equal if all their corresponding members are non-null and equal; the rows
+ are unequal if any corresponding members are non-null and unequal;
+ otherwise the result of that row comparison is unknown (null).
+ If all the per-row results are either unequal or null, with at least one
+ null, then the result of <code class="token">NOT IN</code> is null.
+ </p></div><div class="sect2" id="FUNCTIONS-SUBQUERY-ANY-SOME"><div class="titlepage"><div><div><h3 class="title">9.23.4. <code class="literal">ANY</code>/<code class="literal">SOME</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> ANY (<em class="replaceable"><code>subquery</code></em>)
+<em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> SOME (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <em class="replaceable"><code>operator</code></em>, which must yield a Boolean
+ result.
+ The result of <code class="token">ANY</code> is <span class="quote">“<span class="quote">true</span>”</span> if any true result is obtained.
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if no true result is found (including the
+ case where the subquery returns no rows).
+ </p><p>
+ <code class="token">SOME</code> is a synonym for <code class="token">ANY</code>.
+ <code class="token">IN</code> is equivalent to <code class="literal">= ANY</code>.
+ </p><p>
+ Note that if there are no successes and at least one right-hand row yields
+ null for the operator's result, the result of the <code class="token">ANY</code> construct
+ will be null, not false.
+ This is in accordance with SQL's normal rules for Boolean combinations
+ of null values.
+ </p><p>
+ As with <code class="token">EXISTS</code>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </p><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> <em class="replaceable"><code>operator</code></em> ANY (<em class="replaceable"><code>subquery</code></em>)
+<em class="replaceable"><code>row_constructor</code></em> <em class="replaceable"><code>operator</code></em> SOME (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The left-hand side of this form of <code class="token">ANY</code> is a row constructor,
+ as described in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <em class="replaceable"><code>operator</code></em>.
+ The result of <code class="token">ANY</code> is <span class="quote">“<span class="quote">true</span>”</span> if the comparison
+ returns true for any subquery row.
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if the comparison returns false for every
+ subquery row (including the case where the subquery returns no
+ rows).
+ The result is NULL if no comparison with a subquery row returns true,
+ and at least one comparison returns NULL.
+ </p><p>
+ See <a class="xref" href="functions-comparisons.html#ROW-WISE-COMPARISON" title="9.24.5. Row Constructor Comparison">Section 9.24.5</a> for details about the meaning
+ of a row constructor comparison.
+ </p></div><div class="sect2" id="FUNCTIONS-SUBQUERY-ALL"><div class="titlepage"><div><div><h3 class="title">9.23.5. <code class="literal">ALL</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> ALL (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The right-hand side is a parenthesized
+ subquery, which must return exactly one column. The left-hand expression
+ is evaluated and compared to each row of the subquery result using the
+ given <em class="replaceable"><code>operator</code></em>, which must yield a Boolean
+ result.
+ The result of <code class="token">ALL</code> is <span class="quote">“<span class="quote">true</span>”</span> if all rows yield true
+ (including the case where the subquery returns no rows).
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if any false result is found.
+ The result is NULL if no comparison with a subquery row returns false,
+ and at least one comparison returns NULL.
+ </p><p>
+ <code class="token">NOT IN</code> is equivalent to <code class="literal">&lt;&gt; ALL</code>.
+ </p><p>
+ As with <code class="token">EXISTS</code>, it's unwise to assume that the subquery will
+ be evaluated completely.
+ </p><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> <em class="replaceable"><code>operator</code></em> ALL (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The left-hand side of this form of <code class="token">ALL</code> is a row constructor,
+ as described in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ The right-hand side is a parenthesized
+ subquery, which must return exactly as many columns as there are
+ expressions in the left-hand row. The left-hand expressions are
+ evaluated and compared row-wise to each row of the subquery result,
+ using the given <em class="replaceable"><code>operator</code></em>.
+ The result of <code class="token">ALL</code> is <span class="quote">“<span class="quote">true</span>”</span> if the comparison
+ returns true for all subquery rows (including the
+ case where the subquery returns no rows).
+ The result is <span class="quote">“<span class="quote">false</span>”</span> if the comparison returns false for any
+ subquery row.
+ The result is NULL if no comparison with a subquery row returns false,
+ and at least one comparison returns NULL.
+ </p><p>
+ See <a class="xref" href="functions-comparisons.html#ROW-WISE-COMPARISON" title="9.24.5. Row Constructor Comparison">Section 9.24.5</a> for details about the meaning
+ of a row constructor comparison.
+ </p></div><div class="sect2" id="id-1.5.8.29.15"><div class="titlepage"><div><div><h3 class="title">9.23.6. Single-Row Comparison</h3></div></div></div><a id="id-1.5.8.29.15.2" class="indexterm"></a><pre class="synopsis">
+<em class="replaceable"><code>row_constructor</code></em> <em class="replaceable"><code>operator</code></em> (<em class="replaceable"><code>subquery</code></em>)
+</pre><p>
+ The left-hand side is a row constructor,
+ as described in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ The right-hand side is a parenthesized subquery, which must return exactly
+ as many columns as there are expressions in the left-hand row. Furthermore,
+ the subquery cannot return more than one row. (If it returns zero rows,
+ the result is taken to be null.) The left-hand side is evaluated and
+ compared row-wise to the single subquery result row.
+ </p><p>
+ See <a class="xref" href="functions-comparisons.html#ROW-WISE-COMPARISON" title="9.24.5. Row Constructor Comparison">Section 9.24.5</a> for details about the meaning
+ of a row constructor comparison.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-window.html" title="9.22. Window Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-comparisons.html" title="9.24. Row and Array Comparisons">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.22. Window Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.24. Row and Array Comparisons</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-textsearch.html b/doc/src/sgml/html/functions-textsearch.html
new file mode 100644
index 0000000..90f1290
--- /dev/null
+++ b/doc/src/sgml/html/functions-textsearch.html
@@ -0,0 +1,763 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.13. Text Search Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-net.html" title="9.12. Network Address Functions and Operators" /><link rel="next" href="functions-uuid.html" title="9.14. UUID Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.13. Text Search Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-net.html" title="9.12. Network Address Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-uuid.html" title="9.14. UUID Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-TEXTSEARCH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.13. Text Search Functions and Operators</h2></div></div></div><a id="id-1.5.8.19.2" class="indexterm"></a><a id="id-1.5.8.19.3" class="indexterm"></a><p>
+ <a class="xref" href="functions-textsearch.html#TEXTSEARCH-OPERATORS-TABLE" title="Table 9.42. Text Search Operators">Table 9.42</a>,
+ <a class="xref" href="functions-textsearch.html#TEXTSEARCH-FUNCTIONS-TABLE" title="Table 9.43. Text Search Functions">Table 9.43</a> and
+ <a class="xref" href="functions-textsearch.html#TEXTSEARCH-FUNCTIONS-DEBUG-TABLE" title="Table 9.44. Text Search Debugging Functions">Table 9.44</a>
+ summarize the functions and operators that are provided
+ for full text searching. See <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for a detailed
+ explanation of <span class="productname">PostgreSQL</span>'s text search
+ facility.
+ </p><div class="table" id="TEXTSEARCH-OPERATORS-TABLE"><p class="title"><strong>Table 9.42. Text Search Operators</strong></p><div class="table-contents"><table class="table" summary="Text Search Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsvector</code> <code class="literal">@@</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">@@</code> <code class="type">tsvector</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">tsvector</code> match <code class="type">tsquery</code>?
+ (The arguments can be given in either order.)
+ </p>
+ <p>
+ <code class="literal">to_tsvector('fat cats ate rats') @@ to_tsquery('cat &amp; rat')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">@@</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does text string, after implicit invocation
+ of <code class="function">to_tsvector()</code>, match <code class="type">tsquery</code>?
+ </p>
+ <p>
+ <code class="literal">'fat cats ate rats' @@ to_tsquery('cat &amp; rat')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsvector</code> <code class="literal">@@@</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">@@@</code> <code class="type">tsvector</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ This is a deprecated synonym for <code class="literal">@@</code>.
+ </p>
+ <p>
+ <code class="literal">to_tsvector('fat cats ate rats') @@@ to_tsquery('cat &amp; rat')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsvector</code> <code class="literal">||</code> <code class="type">tsvector</code>
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Concatenates two <code class="type">tsvector</code>s. If both inputs contain
+ lexeme positions, the second input's positions are adjusted
+ accordingly.
+ </p>
+ <p>
+ <code class="literal">'a:1 b:2'::tsvector || 'c:1 d:2 b:3'::tsvector</code>
+ → <code class="returnvalue">'a':1 'b':2,5 'c':3 'd':4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">&amp;&amp;</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ ANDs two <code class="type">tsquery</code>s together, producing a query that
+ matches documents that match both input queries.
+ </p>
+ <p>
+ <code class="literal">'fat | rat'::tsquery &amp;&amp; 'cat'::tsquery</code>
+ → <code class="returnvalue">( 'fat' | 'rat' ) &amp; 'cat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">||</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ ORs two <code class="type">tsquery</code>s together, producing a query that
+ matches documents that match either input query.
+ </p>
+ <p>
+ <code class="literal">'fat | rat'::tsquery || 'cat'::tsquery</code>
+ → <code class="returnvalue">'fat' | 'rat' | 'cat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">!!</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Negates a <code class="type">tsquery</code>, producing a query that matches
+ documents that do not match the input query.
+ </p>
+ <p>
+ <code class="literal">!! 'cat'::tsquery</code>
+ → <code class="returnvalue">!'cat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">&lt;-&gt;</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Constructs a phrase query, which matches if the two input queries
+ match at successive lexemes.
+ </p>
+ <p>
+ <code class="literal">to_tsquery('fat') &lt;-&gt; to_tsquery('rat')</code>
+ → <code class="returnvalue">'fat' &lt;-&gt; 'rat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">@&gt;</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does first <code class="type">tsquery</code> contain the second? (This considers
+ only whether all the lexemes appearing in one query appear in the
+ other, ignoring the combining operators.)
+ </p>
+ <p>
+ <code class="literal">'cat'::tsquery @&gt; 'cat &amp; rat'::tsquery</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">tsquery</code> <code class="literal">&lt;@</code> <code class="type">tsquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is first <code class="type">tsquery</code> contained in the second? (This
+ considers only whether all the lexemes appearing in one query appear
+ in the other, ignoring the combining operators.)
+ </p>
+ <p>
+ <code class="literal">'cat'::tsquery &lt;@ 'cat &amp; rat'::tsquery</code>
+ → <code class="returnvalue">t</code>
+ </p>
+ <p>
+ <code class="literal">'cat'::tsquery &lt;@ '!cat &amp; rat'::tsquery</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In addition to these specialized operators, the usual comparison
+ operators shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are
+ available for types <code class="type">tsvector</code> and <code class="type">tsquery</code>.
+ These are not very
+ useful for text searching but allow, for example, unique indexes to be
+ built on columns of these types.
+ </p><div class="table" id="TEXTSEARCH-FUNCTIONS-TABLE"><p class="title"><strong>Table 9.43. Text Search Functions</strong></p><div class="table-contents"><table class="table" summary="Text Search Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">array_to_tsvector</code> ( <code class="type">text[]</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Converts an array of text strings to a <code class="type">tsvector</code>.
+ The given strings are used as lexemes as-is, without further
+ processing. Array elements must not be empty strings
+ or <code class="literal">NULL</code>.
+ </p>
+ <p>
+ <code class="literal">array_to_tsvector('{fat,cat,rat}'::text[])</code>
+ → <code class="returnvalue">'cat' 'fat' 'rat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">get_current_ts_config</code> ( )
+ → <code class="returnvalue">regconfig</code>
+ </p>
+ <p>
+ Returns the OID of the current default text search configuration
+ (as set by <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a>).
+ </p>
+ <p>
+ <code class="literal">get_current_ts_config()</code>
+ → <code class="returnvalue">english</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">length</code> ( <code class="type">tsvector</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of lexemes in the <code class="type">tsvector</code>.
+ </p>
+ <p>
+ <code class="literal">length('fat:2,4 cat:3 rat:5A'::tsvector)</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">numnode</code> ( <code class="type">tsquery</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of lexemes plus operators in
+ the <code class="type">tsquery</code>.
+ </p>
+ <p>
+ <code class="literal">numnode('(fat &amp; rat) | cat'::tsquery)</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">plainto_tsquery</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Converts text to a <code class="type">tsquery</code>, normalizing words according to
+ the specified or default configuration. Any punctuation in the string
+ is ignored (it does not determine query operators). The resulting
+ query matches documents containing all non-stopwords in the text.
+ </p>
+ <p>
+ <code class="literal">plainto_tsquery('english', 'The Fat Rats')</code>
+ → <code class="returnvalue">'fat' &amp; 'rat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">phraseto_tsquery</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Converts text to a <code class="type">tsquery</code>, normalizing words according to
+ the specified or default configuration. Any punctuation in the string
+ is ignored (it does not determine query operators). The resulting
+ query matches phrases containing all non-stopwords in the text.
+ </p>
+ <p>
+ <code class="literal">phraseto_tsquery('english', 'The Fat Rats')</code>
+ → <code class="returnvalue">'fat' &lt;-&gt; 'rat'</code>
+ </p>
+ <p>
+ <code class="literal">phraseto_tsquery('english', 'The Cat and Rats')</code>
+ → <code class="returnvalue">'cat' &lt;2&gt; 'rat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">websearch_to_tsquery</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Converts text to a <code class="type">tsquery</code>, normalizing words according
+ to the specified or default configuration. Quoted word sequences are
+ converted to phrase tests. The word <span class="quote">“<span class="quote">or</span>”</span> is understood
+ as producing an OR operator, and a dash produces a NOT operator;
+ other punctuation is ignored.
+ This approximates the behavior of some common web search tools.
+ </p>
+ <p>
+ <code class="literal">websearch_to_tsquery('english', '"fat rat" or cat dog')</code>
+ → <code class="returnvalue">'fat' &lt;-&gt; 'rat' | 'cat' &amp; 'dog'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">querytree</code> ( <code class="type">tsquery</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Produces a representation of the indexable portion of
+ a <code class="type">tsquery</code>. A result that is empty or
+ just <code class="literal">T</code> indicates a non-indexable query.
+ </p>
+ <p>
+ <code class="literal">querytree('foo &amp; ! bar'::tsquery)</code>
+ → <code class="returnvalue">'foo'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">setweight</code> ( <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>, <em class="parameter"><code>weight</code></em> <code class="type">"char"</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Assigns the specified <em class="parameter"><code>weight</code></em> to each element
+ of the <em class="parameter"><code>vector</code></em>.
+ </p>
+ <p>
+ <code class="literal">setweight('fat:2,4 cat:3 rat:5B'::tsvector, 'A')</code>
+ → <code class="returnvalue">'cat':3A 'fat':2A,4A 'rat':5A</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">setweight</code> ( <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>, <em class="parameter"><code>weight</code></em> <code class="type">"char"</code>, <em class="parameter"><code>lexemes</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Assigns the specified <em class="parameter"><code>weight</code></em> to elements
+ of the <em class="parameter"><code>vector</code></em> that are listed
+ in <em class="parameter"><code>lexemes</code></em>.
+ The strings in <em class="parameter"><code>lexemes</code></em> are taken as lexemes
+ as-is, without further processing. Strings that do not match any
+ lexeme in <em class="parameter"><code>vector</code></em> are ignored.
+ </p>
+ <p>
+ <code class="literal">setweight('fat:2,4 cat:3 rat:5,6B'::tsvector, 'A', '{cat,rat}')</code>
+ → <code class="returnvalue">'cat':3A 'fat':2,4 'rat':5A,6A</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">strip</code> ( <code class="type">tsvector</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Removes positions and weights from the <code class="type">tsvector</code>.
+ </p>
+ <p>
+ <code class="literal">strip('fat:2,4 cat:3 rat:5A'::tsvector)</code>
+ → <code class="returnvalue">'cat' 'fat' 'rat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">to_tsquery</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Converts text to a <code class="type">tsquery</code>, normalizing words according to
+ the specified or default configuration. The words must be combined
+ by valid <code class="type">tsquery</code> operators.
+ </p>
+ <p>
+ <code class="literal">to_tsquery('english', 'The &amp; Fat &amp; Rats')</code>
+ → <code class="returnvalue">'fat' &amp; 'rat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">to_tsvector</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Converts text to a <code class="type">tsvector</code>, normalizing words according
+ to the specified or default configuration. Position information is
+ included in the result.
+ </p>
+ <p>
+ <code class="literal">to_tsvector('english', 'The Fat Rats')</code>
+ → <code class="returnvalue">'fat':2 'rat':3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">to_tsvector</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">json</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">to_tsvector</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">jsonb</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Converts each string value in the JSON document to
+ a <code class="type">tsvector</code>, normalizing words according to the specified
+ or default configuration. The results are then concatenated in
+ document order to produce the output. Position information is
+ generated as though one stopword exists between each pair of string
+ values. (Beware that <span class="quote">“<span class="quote">document order</span>”</span> of the fields of a
+ JSON object is implementation-dependent when the input
+ is <code class="type">jsonb</code>; observe the difference in the examples.)
+ </p>
+ <p>
+ <code class="literal">to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::json)</code>
+ → <code class="returnvalue">'dog':5 'fat':2 'rat':3</code>
+ </p>
+ <p>
+ <code class="literal">to_tsvector('english', '{"aa": "The Fat Rats", "b": "dog"}'::jsonb)</code>
+ → <code class="returnvalue">'dog':1 'fat':4 'rat':5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">json_to_tsvector</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">json</code>,
+ <em class="parameter"><code>filter</code></em> <code class="type">jsonb</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.15.1.2.1" class="indexterm"></a>
+ <code class="function">jsonb_to_tsvector</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">jsonb</code>,
+ <em class="parameter"><code>filter</code></em> <code class="type">jsonb</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Selects each item in the JSON document that is requested by
+ the <em class="parameter"><code>filter</code></em> and converts each one to
+ a <code class="type">tsvector</code>, normalizing words according to the specified
+ or default configuration. The results are then concatenated in
+ document order to produce the output. Position information is
+ generated as though one stopword exists between each pair of selected
+ items. (Beware that <span class="quote">“<span class="quote">document order</span>”</span> of the fields of a
+ JSON object is implementation-dependent when the input
+ is <code class="type">jsonb</code>.)
+ The <em class="parameter"><code>filter</code></em> must be a <code class="type">jsonb</code>
+ array containing zero or more of these keywords:
+ <code class="literal">"string"</code> (to include all string values),
+ <code class="literal">"numeric"</code> (to include all numeric values),
+ <code class="literal">"boolean"</code> (to include all boolean values),
+ <code class="literal">"key"</code> (to include all keys), or
+ <code class="literal">"all"</code> (to include all the above).
+ As a special case, the <em class="parameter"><code>filter</code></em> can also be a
+ simple JSON value that is one of these keywords.
+ </p>
+ <p>
+ <code class="literal">json_to_tsvector('english', '{"a": "The Fat Rats", "b": 123}'::json, '["string", "numeric"]')</code>
+ → <code class="returnvalue">'123':5 'fat':2 'rat':3</code>
+ </p>
+ <p>
+ <code class="literal">json_to_tsvector('english', '{"cat": "The Fat Rats", "dog": 123}'::json, '"all"')</code>
+ → <code class="returnvalue">'123':9 'cat':1 'dog':7 'fat':4 'rat':5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">ts_delete</code> ( <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>, <em class="parameter"><code>lexeme</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Removes any occurrence of the given <em class="parameter"><code>lexeme</code></em>
+ from the <em class="parameter"><code>vector</code></em>.
+ The <em class="parameter"><code>lexeme</code></em> string is treated as a lexeme as-is,
+ without further processing.
+ </p>
+ <p>
+ <code class="literal">ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, 'fat')</code>
+ → <code class="returnvalue">'cat':3 'rat':5A</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">ts_delete</code> ( <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>, <em class="parameter"><code>lexemes</code></em> <code class="type">text[]</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Removes any occurrences of the lexemes
+ in <em class="parameter"><code>lexemes</code></em>
+ from the <em class="parameter"><code>vector</code></em>.
+ The strings in <em class="parameter"><code>lexemes</code></em> are taken as lexemes
+ as-is, without further processing. Strings that do not match any
+ lexeme in <em class="parameter"><code>vector</code></em> are ignored.
+ </p>
+ <p>
+ <code class="literal">ts_delete('fat:2,4 cat:3 rat:5A'::tsvector, ARRAY['fat','rat'])</code>
+ → <code class="returnvalue">'cat':3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">ts_filter</code> ( <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>, <em class="parameter"><code>weights</code></em> <code class="type">"char"[]</code> )
+ → <code class="returnvalue">tsvector</code>
+ </p>
+ <p>
+ Selects only elements with the given <em class="parameter"><code>weights</code></em>
+ from the <em class="parameter"><code>vector</code></em>.
+ </p>
+ <p>
+ <code class="literal">ts_filter('fat:2,4 cat:3b,7c rat:5A'::tsvector, '{a,b}')</code>
+ → <code class="returnvalue">'cat':3B 'rat':5A</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">ts_headline</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>
+ [<span class="optional">, <em class="parameter"><code>options</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Displays, in an abbreviated form, the match(es) for
+ the <em class="parameter"><code>query</code></em> in
+ the <em class="parameter"><code>document</code></em>, which must be raw text not
+ a <code class="type">tsvector</code>. Words in the document are normalized
+ according to the specified or default configuration before matching to
+ the query. Use of this function is discussed in
+ <a class="xref" href="textsearch-controls.html#TEXTSEARCH-HEADLINE" title="12.3.4. Highlighting Results">Section 12.3.4</a>, which also describes the
+ available <em class="parameter"><code>options</code></em>.
+ </p>
+ <p>
+ <code class="literal">ts_headline('The fat cat ate the rat.', 'cat')</code>
+ → <code class="returnvalue">The fat &lt;b&gt;cat&lt;/b&gt; ate the rat.</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">ts_headline</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">json</code>,
+ <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>
+ [<span class="optional">, <em class="parameter"><code>options</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">ts_headline</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">jsonb</code>,
+ <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>
+ [<span class="optional">, <em class="parameter"><code>options</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Displays, in an abbreviated form, match(es) for
+ the <em class="parameter"><code>query</code></em> that occur in string values
+ within the JSON <em class="parameter"><code>document</code></em>.
+ See <a class="xref" href="textsearch-controls.html#TEXTSEARCH-HEADLINE" title="12.3.4. Highlighting Results">Section 12.3.4</a> for more details.
+ </p>
+ <p>
+ <code class="literal">ts_headline('{"cat":"raining cats and dogs"}'::jsonb, 'cat')</code>
+ → <code class="returnvalue">{"cat": "raining &lt;b&gt;cats&lt;/b&gt; and dogs"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.21.1.1.1" class="indexterm"></a>
+ <code class="function">ts_rank</code> (
+ [<span class="optional"> <em class="parameter"><code>weights</code></em> <code class="type">real[]</code>, </span>]
+ <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>,
+ <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>
+ [<span class="optional">, <em class="parameter"><code>normalization</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Computes a score showing how well
+ the <em class="parameter"><code>vector</code></em> matches
+ the <em class="parameter"><code>query</code></em>. See
+ <a class="xref" href="textsearch-controls.html#TEXTSEARCH-RANKING" title="12.3.3. Ranking Search Results">Section 12.3.3</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_rank(to_tsvector('raining cats and dogs'), 'cat')</code>
+ → <code class="returnvalue">0.06079271</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">ts_rank_cd</code> (
+ [<span class="optional"> <em class="parameter"><code>weights</code></em> <code class="type">real[]</code>, </span>]
+ <em class="parameter"><code>vector</code></em> <code class="type">tsvector</code>,
+ <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>
+ [<span class="optional">, <em class="parameter"><code>normalization</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Computes a score showing how well
+ the <em class="parameter"><code>vector</code></em> matches
+ the <em class="parameter"><code>query</code></em>, using a cover density
+ algorithm. See <a class="xref" href="textsearch-controls.html#TEXTSEARCH-RANKING" title="12.3.3. Ranking Search Results">Section 12.3.3</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_rank_cd(to_tsvector('raining cats and dogs'), 'cat')</code>
+ → <code class="returnvalue">0.1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.23.1.1.1" class="indexterm"></a>
+ <code class="function">ts_rewrite</code> ( <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>,
+ <em class="parameter"><code>target</code></em> <code class="type">tsquery</code>,
+ <em class="parameter"><code>substitute</code></em> <code class="type">tsquery</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Replaces occurrences of <em class="parameter"><code>target</code></em>
+ with <em class="parameter"><code>substitute</code></em>
+ within the <em class="parameter"><code>query</code></em>.
+ See <a class="xref" href="textsearch-features.html#TEXTSEARCH-QUERY-REWRITING" title="12.4.2.1. Query Rewriting">Section 12.4.2.1</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_rewrite('a &amp; b'::tsquery, 'a'::tsquery, 'foo|bar'::tsquery)</code>
+ → <code class="returnvalue">'b' &amp; ( 'foo' | 'bar' )</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">ts_rewrite</code> ( <em class="parameter"><code>query</code></em> <code class="type">tsquery</code>,
+ <em class="parameter"><code>select</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Replaces portions of the <em class="parameter"><code>query</code></em> according to
+ target(s) and substitute(s) obtained by executing
+ a <code class="command">SELECT</code> command.
+ See <a class="xref" href="textsearch-features.html#TEXTSEARCH-QUERY-REWRITING" title="12.4.2.1. Query Rewriting">Section 12.4.2.1</a> for details.
+ </p>
+ <p>
+ <code class="literal">SELECT ts_rewrite('a &amp; b'::tsquery, 'SELECT t,s FROM aliases')</code>
+ → <code class="returnvalue">'b' &amp; ( 'foo' | 'bar' )</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.25.1.1.1" class="indexterm"></a>
+ <code class="function">tsquery_phrase</code> ( <em class="parameter"><code>query1</code></em> <code class="type">tsquery</code>, <em class="parameter"><code>query2</code></em> <code class="type">tsquery</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Constructs a phrase query that searches
+ for matches of <em class="parameter"><code>query1</code></em>
+ and <em class="parameter"><code>query2</code></em> at successive lexemes (same
+ as <code class="literal">&lt;-&gt;</code> operator).
+ </p>
+ <p>
+ <code class="literal">tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'))</code>
+ → <code class="returnvalue">'fat' &lt;-&gt; 'cat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">tsquery_phrase</code> ( <em class="parameter"><code>query1</code></em> <code class="type">tsquery</code>, <em class="parameter"><code>query2</code></em> <code class="type">tsquery</code>, <em class="parameter"><code>distance</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">tsquery</code>
+ </p>
+ <p>
+ Constructs a phrase query that searches
+ for matches of <em class="parameter"><code>query1</code></em> and
+ <em class="parameter"><code>query2</code></em> that occur exactly
+ <em class="parameter"><code>distance</code></em> lexemes apart.
+ </p>
+ <p>
+ <code class="literal">tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10)</code>
+ → <code class="returnvalue">'fat' &lt;10&gt; 'cat'</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.27.1.1.1" class="indexterm"></a>
+ <code class="function">tsvector_to_array</code> ( <code class="type">tsvector</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Converts a <code class="type">tsvector</code> to an array of lexemes.
+ </p>
+ <p>
+ <code class="literal">tsvector_to_array('fat:2,4 cat:3 rat:5A'::tsvector)</code>
+ → <code class="returnvalue">{cat,fat,rat}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.7.2.2.28.1.1.1" class="indexterm"></a>
+ <code class="function">unnest</code> ( <code class="type">tsvector</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>lexeme</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>positions</code></em> <code class="type">smallint[]</code>,
+ <em class="parameter"><code>weights</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Expands a <code class="type">tsvector</code> into a set of rows, one per lexeme.
+ </p>
+ <p>
+ <code class="literal">select * from unnest('cat:3 fat:2,4 rat:5A'::tsvector)</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ lexeme | positions | weights
+--------+-----------+---------
+ cat | {3} | {D}
+ fat | {2,4} | {D,D}
+ rat | {5} | {A}
+</pre><p>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ All the text search functions that accept an optional <code class="type">regconfig</code>
+ argument will use the configuration specified by
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a>
+ when that argument is omitted.
+ </p></div><p>
+ The functions in
+ <a class="xref" href="functions-textsearch.html#TEXTSEARCH-FUNCTIONS-DEBUG-TABLE" title="Table 9.44. Text Search Debugging Functions">Table 9.44</a>
+ are listed separately because they are not usually used in everyday text
+ searching operations. They are primarily helpful for development and
+ debugging of new text search configurations.
+ </p><div class="table" id="TEXTSEARCH-FUNCTIONS-DEBUG-TABLE"><p class="title"><strong>Table 9.44. Text Search Debugging Functions</strong></p><div class="table-contents"><table class="table" summary="Text Search Debugging Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.10.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">ts_debug</code> (
+ [<span class="optional"> <em class="parameter"><code>config</code></em> <code class="type">regconfig</code>, </span>]
+ <em class="parameter"><code>document</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>alias</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>description</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>token</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>dictionaries</code></em> <code class="type">regdictionary[]</code>,
+ <em class="parameter"><code>dictionary</code></em> <code class="type">regdictionary</code>,
+ <em class="parameter"><code>lexemes</code></em> <code class="type">text[]</code> )
+ </p>
+ <p>
+ Extracts and normalizes tokens from
+ the <em class="parameter"><code>document</code></em> according to the specified or
+ default text search configuration, and returns information about how
+ each token was processed.
+ See <a class="xref" href="textsearch-debugging.html#TEXTSEARCH-CONFIGURATION-TESTING" title="12.8.1. Configuration Testing">Section 12.8.1</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_debug('english', 'The Brightest supernovaes')</code>
+ → <code class="returnvalue">(asciiword,"Word, all ASCII",The,{english_stem},english_stem,{}) ...</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.10.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">ts_lexize</code> ( <em class="parameter"><code>dict</code></em> <code class="type">regdictionary</code>, <em class="parameter"><code>token</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Returns an array of replacement lexemes if the input token is known to
+ the dictionary, or an empty array if the token is known to the
+ dictionary but it is a stop word, or NULL if it is not a known word.
+ See <a class="xref" href="textsearch-debugging.html#TEXTSEARCH-DICTIONARY-TESTING" title="12.8.3. Dictionary Testing">Section 12.8.3</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_lexize('english_stem', 'stars')</code>
+ → <code class="returnvalue">{star}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.10.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">ts_parse</code> ( <em class="parameter"><code>parser_name</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>document</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>tokid</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>token</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Extracts tokens from the <em class="parameter"><code>document</code></em> using the
+ named parser.
+ See <a class="xref" href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING" title="12.8.2. Parser Testing">Section 12.8.2</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_parse('default', 'foo - bar')</code>
+ → <code class="returnvalue">(1,foo) ...</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">ts_parse</code> ( <em class="parameter"><code>parser_oid</code></em> <code class="type">oid</code>,
+ <em class="parameter"><code>document</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>tokid</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>token</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Extracts tokens from the <em class="parameter"><code>document</code></em> using a
+ parser specified by OID.
+ See <a class="xref" href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING" title="12.8.2. Parser Testing">Section 12.8.2</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_parse(3722, 'foo - bar')</code>
+ → <code class="returnvalue">(1,foo) ...</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.10.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">ts_token_type</code> ( <em class="parameter"><code>parser_name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>tokid</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>alias</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>description</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Returns a table that describes each type of token the named parser can
+ recognize.
+ See <a class="xref" href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING" title="12.8.2. Parser Testing">Section 12.8.2</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_token_type('default')</code>
+ → <code class="returnvalue">(1,asciiword,"Word, all ASCII") ...</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">ts_token_type</code> ( <em class="parameter"><code>parser_oid</code></em> <code class="type">oid</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>tokid</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>alias</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>description</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Returns a table that describes each type of token a parser specified
+ by OID can recognize.
+ See <a class="xref" href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING" title="12.8.2. Parser Testing">Section 12.8.2</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_token_type(3722)</code>
+ → <code class="returnvalue">(1,asciiword,"Word, all ASCII") ...</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.19.10.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">ts_stat</code> ( <em class="parameter"><code>sqlquery</code></em> <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>weights</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>word</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>ndoc</code></em> <code class="type">integer</code>,
+ <em class="parameter"><code>nentry</code></em> <code class="type">integer</code> )
+ </p>
+ <p>
+ Executes the <em class="parameter"><code>sqlquery</code></em>, which must return a
+ single <code class="type">tsvector</code> column, and returns statistics about each
+ distinct lexeme contained in the data.
+ See <a class="xref" href="textsearch-features.html#TEXTSEARCH-STATISTICS" title="12.4.4. Gathering Document Statistics">Section 12.4.4</a> for details.
+ </p>
+ <p>
+ <code class="literal">ts_stat('SELECT vector FROM apod')</code>
+ → <code class="returnvalue">(foo,10,15) ...</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-net.html" title="9.12. Network Address Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-uuid.html" title="9.14. UUID Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.12. Network Address Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.14. UUID Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-trigger.html b/doc/src/sgml/html/functions-trigger.html
new file mode 100644
index 0000000..04588b6
--- /dev/null
+++ b/doc/src/sgml/html/functions-trigger.html
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.28. Trigger Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-admin.html" title="9.27. System Administration Functions" /><link rel="next" href="functions-event-triggers.html" title="9.29. Event Trigger Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.28. Trigger Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-admin.html" title="9.27. System Administration Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-event-triggers.html" title="9.29. Event Trigger Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.28. Trigger Functions</h2></div></div></div><p>
+ While many uses of triggers involve user-written trigger functions,
+ <span class="productname">PostgreSQL</span> provides a few built-in trigger
+ functions that can be used directly in user-defined triggers. These
+ are summarized in <a class="xref" href="functions-trigger.html#BUILTIN-TRIGGERS-TABLE" title="Table 9.101. Built-In Trigger Functions">Table 9.101</a>.
+ (Additional built-in trigger functions exist, which implement foreign
+ key constraints and deferred index constraints. Those are not documented
+ here since users need not use them directly.)
+ </p><p>
+ For more information about creating triggers, see
+ <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>.
+ </p><div class="table" id="BUILTIN-TRIGGERS-TABLE"><p class="title"><strong>Table 9.101. Built-In Trigger Functions</strong></p><div class="table-contents"><table class="table" summary="Built-In Trigger Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example Usage
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.34.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">suppress_redundant_updates_trigger</code> ( )
+ → <code class="returnvalue">trigger</code>
+ </p>
+ <p>
+ Suppresses do-nothing update operations. See below for details.
+ </p>
+ <p>
+ <code class="literal">CREATE TRIGGER ... suppress_redundant_updates_trigger()</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.34.4.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">tsvector_update_trigger</code> ( )
+ → <code class="returnvalue">trigger</code>
+ </p>
+ <p>
+ Automatically updates a <code class="type">tsvector</code> column from associated
+ plain-text document column(s). The text search configuration to use
+ is specified by name as a trigger argument. See
+ <a class="xref" href="textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS" title="12.4.3. Triggers for Automatic Updates">Section 12.4.3</a> for details.
+ </p>
+ <p>
+ <code class="literal">CREATE TRIGGER ... tsvector_update_trigger(tsvcol, 'pg_catalog.swedish', title, body)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.34.4.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">tsvector_update_trigger_column</code> ( )
+ → <code class="returnvalue">trigger</code>
+ </p>
+ <p>
+ Automatically updates a <code class="type">tsvector</code> column from associated
+ plain-text document column(s). The text search configuration to use
+ is taken from a <code class="type">regconfig</code> column of the table. See
+ <a class="xref" href="textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS" title="12.4.3. Triggers for Automatic Updates">Section 12.4.3</a> for details.
+ </p>
+ <p>
+ <code class="literal">CREATE TRIGGER ... tsvector_update_trigger_column(tsvcol, tsconfigcol, title, body)</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="function">suppress_redundant_updates_trigger</code> function,
+ when applied as a row-level <code class="literal">BEFORE UPDATE</code> trigger,
+ will prevent any update that does not actually change the data in the
+ row from taking place. This overrides the normal behavior which always
+ performs a physical row update
+ regardless of whether or not the data has changed. (This normal behavior
+ makes updates run faster, since no checking is required, and is also
+ useful in certain cases.)
+ </p><p>
+ Ideally, you should avoid running updates that don't actually
+ change the data in the record. Redundant updates can cost considerable
+ unnecessary time, especially if there are lots of indexes to alter,
+ and space in dead rows that will eventually have to be vacuumed.
+ However, detecting such situations in client code is not
+ always easy, or even possible, and writing expressions to detect
+ them can be error-prone. An alternative is to use
+ <code class="function">suppress_redundant_updates_trigger</code>, which will skip
+ updates that don't change the data. You should use this with care,
+ however. The trigger takes a small but non-trivial time for each record,
+ so if most of the records affected by updates do actually change,
+ use of this trigger will make updates run slower on average.
+ </p><p>
+ The <code class="function">suppress_redundant_updates_trigger</code> function can be
+ added to a table like this:
+</p><pre class="programlisting">
+CREATE TRIGGER z_min_update
+BEFORE UPDATE ON tablename
+FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger();
+</pre><p>
+ In most cases, you need to fire this trigger last for each row, so that
+ it does not override other triggers that might wish to alter the row.
+ Bearing in mind that triggers fire in name order, you would therefore
+ choose a trigger name that comes after the name of any other trigger
+ you might have on the table. (Hence the <span class="quote">“<span class="quote">z</span>”</span> prefix in the
+ example.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-admin.html" title="9.27. System Administration Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-event-triggers.html" title="9.29. Event Trigger Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.27. System Administration Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.29. Event Trigger Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-uuid.html b/doc/src/sgml/html/functions-uuid.html
new file mode 100644
index 0000000..10fd559
--- /dev/null
+++ b/doc/src/sgml/html/functions-uuid.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.14. UUID Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators" /><link rel="next" href="functions-xml.html" title="9.15. XML Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.14. UUID Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-xml.html" title="9.15. XML Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-UUID"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.14. UUID Functions</h2></div></div></div><a id="id-1.5.8.20.2" class="indexterm"></a><a id="id-1.5.8.20.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> includes one function to generate a UUID:
+</p><pre class="synopsis">
+<code class="function">gen_random_uuid</code> () → <code class="returnvalue">uuid</code>
+</pre><p>
+ This function returns a version 4 (random) UUID. This is the most commonly
+ used type of UUID and is appropriate for most applications.
+ </p><p>
+ The <a class="xref" href="uuid-ossp.html" title="F.49. uuid-ossp">uuid-ossp</a> module provides additional functions that
+ implement other standard algorithms for generating UUIDs.
+ </p><p>
+ <span class="productname">PostgreSQL</span> also provides the usual comparison
+ operators shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> for
+ UUIDs.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-xml.html" title="9.15. XML Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.13. Text Search Functions and Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.15. XML Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-window.html b/doc/src/sgml/html/functions-window.html
new file mode 100644
index 0000000..b61d3a5
--- /dev/null
+++ b/doc/src/sgml/html/functions-window.html
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.22. Window Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-aggregate.html" title="9.21. Aggregate Functions" /><link rel="next" href="functions-subquery.html" title="9.23. Subquery Expressions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.22. Window Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-aggregate.html" title="9.21. Aggregate Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-subquery.html" title="9.23. Subquery Expressions">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-WINDOW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.22. Window Functions</h2></div></div></div><a id="id-1.5.8.28.2" class="indexterm"></a><p>
+ <em class="firstterm">Window functions</em> provide the ability to perform
+ calculations across sets of rows that are related to the current query
+ row. See <a class="xref" href="tutorial-window.html" title="3.5. Window Functions">Section 3.5</a> for an introduction to this
+ feature, and <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a> for syntax
+ details.
+ </p><p>
+ The built-in window functions are listed in
+ <a class="xref" href="functions-window.html#FUNCTIONS-WINDOW-TABLE" title="Table 9.63. General-Purpose Window Functions">Table 9.63</a>. Note that these functions
+ <span class="emphasis"><em>must</em></span> be invoked using window function syntax, i.e., an
+ <code class="literal">OVER</code> clause is required.
+ </p><p>
+ In addition to these functions, any built-in or user-defined
+ ordinary aggregate (i.e., not ordered-set or hypothetical-set aggregates)
+ can be used as a window function; see
+ <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a> for a list of the built-in aggregates.
+ Aggregate functions act as window functions only when an <code class="literal">OVER</code>
+ clause follows the call; otherwise they act as plain aggregates
+ and return a single row for the entire set.
+ </p><div class="table" id="FUNCTIONS-WINDOW-TABLE"><p class="title"><strong>Table 9.63. General-Purpose Window Functions</strong></p><div class="table-contents"><table class="table" summary="General-Purpose Window Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">row_number</code> ()
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the number of the current row within its partition, counting
+ from 1.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">rank</code> ()
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the rank of the current row, with gaps; that is,
+ the <code class="function">row_number</code> of the first row in its peer
+ group.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">dense_rank</code> ()
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the rank of the current row, without gaps; this function
+ effectively counts peer groups.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">percent_rank</code> ()
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Returns the relative rank of the current row, that is
+ (<code class="function">rank</code> - 1) / (total partition rows - 1).
+ The value thus ranges from 0 to 1 inclusive.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">cume_dist</code> ()
+ → <code class="returnvalue">double precision</code>
+ </p>
+ <p>
+ Returns the cumulative distribution, that is (number of partition rows
+ preceding or peers with current row) / (total partition rows).
+ The value thus ranges from 1/<em class="parameter"><code>N</code></em> to 1.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">ntile</code> ( <em class="parameter"><code>num_buckets</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns an integer ranging from 1 to the argument value, dividing the
+ partition as equally as possible.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">lag</code> ( <em class="parameter"><code>value</code></em> <code class="type">anycompatible</code>
+ [<span class="optional">, <em class="parameter"><code>offset</code></em> <code class="type">integer</code>
+ [<span class="optional">, <em class="parameter"><code>default</code></em> <code class="type">anycompatible</code> </span>]</span>] )
+ → <code class="returnvalue">anycompatible</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>value</code></em> evaluated at
+ the row that is <em class="parameter"><code>offset</code></em>
+ rows before the current row within the partition; if there is no such
+ row, instead returns <em class="parameter"><code>default</code></em>
+ (which must be of a type compatible with
+ <em class="parameter"><code>value</code></em>).
+ Both <em class="parameter"><code>offset</code></em> and
+ <em class="parameter"><code>default</code></em> are evaluated
+ with respect to the current row. If omitted,
+ <em class="parameter"><code>offset</code></em> defaults to 1 and
+ <em class="parameter"><code>default</code></em> to <code class="literal">NULL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">lead</code> ( <em class="parameter"><code>value</code></em> <code class="type">anycompatible</code>
+ [<span class="optional">, <em class="parameter"><code>offset</code></em> <code class="type">integer</code>
+ [<span class="optional">, <em class="parameter"><code>default</code></em> <code class="type">anycompatible</code> </span>]</span>] )
+ → <code class="returnvalue">anycompatible</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>value</code></em> evaluated at
+ the row that is <em class="parameter"><code>offset</code></em>
+ rows after the current row within the partition; if there is no such
+ row, instead returns <em class="parameter"><code>default</code></em>
+ (which must be of a type compatible with
+ <em class="parameter"><code>value</code></em>).
+ Both <em class="parameter"><code>offset</code></em> and
+ <em class="parameter"><code>default</code></em> are evaluated
+ with respect to the current row. If omitted,
+ <em class="parameter"><code>offset</code></em> defaults to 1 and
+ <em class="parameter"><code>default</code></em> to <code class="literal">NULL</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">first_value</code> ( <em class="parameter"><code>value</code></em> <code class="type">anyelement</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>value</code></em> evaluated
+ at the row that is the first row of the window frame.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">last_value</code> ( <em class="parameter"><code>value</code></em> <code class="type">anyelement</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>value</code></em> evaluated
+ at the row that is the last row of the window frame.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.5.8.28.6.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">nth_value</code> ( <em class="parameter"><code>value</code></em> <code class="type">anyelement</code>, <em class="parameter"><code>n</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Returns <em class="parameter"><code>value</code></em> evaluated
+ at the row that is the <em class="parameter"><code>n</code></em>'th
+ row of the window frame (counting from 1);
+ returns <code class="literal">NULL</code> if there is no such row.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ All of the functions listed in
+ <a class="xref" href="functions-window.html#FUNCTIONS-WINDOW-TABLE" title="Table 9.63. General-Purpose Window Functions">Table 9.63</a> depend on the sort ordering
+ specified by the <code class="literal">ORDER BY</code> clause of the associated window
+ definition. Rows that are not distinct when considering only the
+ <code class="literal">ORDER BY</code> columns are said to be <em class="firstterm">peers</em>.
+ The four ranking functions (including <code class="function">cume_dist</code>) are
+ defined so that they give the same answer for all rows of a peer group.
+ </p><p>
+ Note that <code class="function">first_value</code>, <code class="function">last_value</code>, and
+ <code class="function">nth_value</code> consider only the rows within the <span class="quote">“<span class="quote">window
+ frame</span>”</span>, which by default contains the rows from the start of the
+ partition through the last peer of the current row. This is
+ likely to give unhelpful results for <code class="function">last_value</code> and
+ sometimes also <code class="function">nth_value</code>. You can redefine the frame by
+ adding a suitable frame specification (<code class="literal">RANGE</code>,
+ <code class="literal">ROWS</code> or <code class="literal">GROUPS</code>) to
+ the <code class="literal">OVER</code> clause.
+ See <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a> for more information
+ about frame specifications.
+ </p><p>
+ When an aggregate function is used as a window function, it aggregates
+ over the rows within the current row's window frame.
+ An aggregate used with <code class="literal">ORDER BY</code> and the default window frame
+ definition produces a <span class="quote">“<span class="quote">running sum</span>”</span> type of behavior, which may or
+ may not be what's wanted. To obtain
+ aggregation over the whole partition, omit <code class="literal">ORDER BY</code> or use
+ <code class="literal">ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING</code>.
+ Other frame specifications can be used to obtain other effects.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The SQL standard defines a <code class="literal">RESPECT NULLS</code> or
+ <code class="literal">IGNORE NULLS</code> option for <code class="function">lead</code>, <code class="function">lag</code>,
+ <code class="function">first_value</code>, <code class="function">last_value</code>, and
+ <code class="function">nth_value</code>. This is not implemented in
+ <span class="productname">PostgreSQL</span>: the behavior is always the
+ same as the standard's default, namely <code class="literal">RESPECT NULLS</code>.
+ Likewise, the standard's <code class="literal">FROM FIRST</code> or <code class="literal">FROM LAST</code>
+ option for <code class="function">nth_value</code> is not implemented: only the
+ default <code class="literal">FROM FIRST</code> behavior is supported. (You can achieve
+ the result of <code class="literal">FROM LAST</code> by reversing the <code class="literal">ORDER BY</code>
+ ordering.)
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-aggregate.html" title="9.21. Aggregate Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-subquery.html" title="9.23. Subquery Expressions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.21. Aggregate Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.23. Subquery Expressions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions-xml.html b/doc/src/sgml/html/functions-xml.html
new file mode 100644
index 0000000..71474ab
--- /dev/null
+++ b/doc/src/sgml/html/functions-xml.html
@@ -0,0 +1,912 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>9.15. XML Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-uuid.html" title="9.14. UUID Functions" /><link rel="next" href="functions-json.html" title="9.16. JSON Functions and Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">9.15. XML Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-uuid.html" title="9.14. UUID Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><th width="60%" align="center">Chapter 9. Functions and Operators</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-json.html" title="9.16. JSON Functions and Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUNCTIONS-XML"><div class="titlepage"><div><div><h2 class="title" style="clear: both">9.15. XML Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-PRODUCING-XML">9.15.1. Producing XML Content</a></span></dt><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-XML-PREDICATES">9.15.2. XML Predicates</a></span></dt><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-XML-PROCESSING">9.15.3. Processing XML</a></span></dt><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-XML-MAPPING">9.15.4. Mapping Tables to XML</a></span></dt></dl></div><a id="id-1.5.8.21.2" class="indexterm"></a><p>
+ The functions and function-like expressions described in this
+ section operate on values of type <code class="type">xml</code>. See <a class="xref" href="datatype-xml.html" title="8.13. XML Type">Section 8.13</a> for information about the <code class="type">xml</code>
+ type. The function-like expressions <code class="function">xmlparse</code>
+ and <code class="function">xmlserialize</code> for converting to and from
+ type <code class="type">xml</code> are documented there, not in this section.
+ </p><p>
+ Use of most of these functions
+ requires <span class="productname">PostgreSQL</span> to have been built
+ with <code class="command">configure --with-libxml</code>.
+ </p><div class="sect2" id="FUNCTIONS-PRODUCING-XML"><div class="titlepage"><div><div><h3 class="title">9.15.1. Producing XML Content</h3></div></div></div><p>
+ A set of functions and function-like expressions is available for
+ producing XML content from SQL data. As such, they are
+ particularly suitable for formatting query results into XML
+ documents for processing in client applications.
+ </p><div class="sect3" id="id-1.5.8.21.5.3"><div class="titlepage"><div><div><h4 class="title">9.15.1.1. <code class="literal">xmlcomment</code></h4></div></div></div><a id="id-1.5.8.21.5.3.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlcomment</code> ( <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The function <code class="function">xmlcomment</code> creates an XML value
+ containing an XML comment with the specified text as content.
+ The text cannot contain <span class="quote">“<span class="quote"><code class="literal">--</code></span>”</span> or end with a
+ <span class="quote">“<span class="quote"><code class="literal">-</code></span>”</span>, otherwise the resulting construct
+ would not be a valid XML comment.
+ If the argument is null, the result is null.
+ </p><p>
+ Example:
+</p><pre class="screen">
+SELECT xmlcomment('hello');
+
+ xmlcomment
+--------------
+ &lt;!--hello--&gt;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.5.8.21.5.4"><div class="titlepage"><div><div><h4 class="title">9.15.1.2. <code class="literal">xmlconcat</code></h4></div></div></div><a id="id-1.5.8.21.5.4.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlconcat</code> ( <code class="type">xml</code> [<span class="optional">, ...</span>] ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The function <code class="function">xmlconcat</code> concatenates a list
+ of individual XML values to create a single value containing an
+ XML content fragment. Null values are omitted; the result is
+ only null if there are no nonnull arguments.
+ </p><p>
+ Example:
+</p><pre class="screen">
+SELECT xmlconcat('&lt;abc/&gt;', '&lt;bar&gt;foo&lt;/bar&gt;');
+
+ xmlconcat
+----------------------
+ &lt;abc/&gt;&lt;bar&gt;foo&lt;/bar&gt;
+</pre><p>
+ </p><p>
+ XML declarations, if present, are combined as follows. If all
+ argument values have the same XML version declaration, that
+ version is used in the result, else no version is used. If all
+ argument values have the standalone declaration value
+ <span class="quote">“<span class="quote">yes</span>”</span>, then that value is used in the result. If
+ all argument values have a standalone declaration value and at
+ least one is <span class="quote">“<span class="quote">no</span>”</span>, then that is used in the result.
+ Else the result will have no standalone declaration. If the
+ result is determined to require a standalone declaration but no
+ version declaration, a version declaration with version 1.0 will
+ be used because XML requires an XML declaration to contain a
+ version declaration. Encoding declarations are ignored and
+ removed in all cases.
+ </p><p>
+ Example:
+</p><pre class="screen">
+SELECT xmlconcat('&lt;?xml version="1.1"?&gt;&lt;foo/&gt;', '&lt;?xml version="1.1" standalone="no"?&gt;&lt;bar/&gt;');
+
+ xmlconcat
+-----------------------------------
+ &lt;?xml version="1.1"?&gt;&lt;foo/&gt;&lt;bar/&gt;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.5.8.21.5.5"><div class="titlepage"><div><div><h4 class="title">9.15.1.3. <code class="literal">xmlelement</code></h4></div></div></div><a id="id-1.5.8.21.5.5.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlelement</code> ( <code class="literal">NAME</code> <em class="replaceable"><code>name</code></em> [<span class="optional">, <code class="literal">XMLATTRIBUTES</code> ( <em class="replaceable"><code>attvalue</code></em> [<span class="optional"> <code class="literal">AS</code> <em class="replaceable"><code>attname</code></em> </span>] [<span class="optional">, ...</span>] ) </span>] [<span class="optional">, <em class="replaceable"><code>content</code></em> [<span class="optional">, ...</span>]</span>] ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The <code class="function">xmlelement</code> expression produces an XML
+ element with the given name, attributes, and content.
+ The <em class="replaceable"><code>name</code></em>
+ and <em class="replaceable"><code>attname</code></em> items shown in the syntax are
+ simple identifiers, not values. The <em class="replaceable"><code>attvalue</code></em>
+ and <em class="replaceable"><code>content</code></em> items are expressions, which can
+ yield any <span class="productname">PostgreSQL</span> data type. The
+ argument(s) within <code class="literal">XMLATTRIBUTES</code> generate attributes
+ of the XML element; the <em class="replaceable"><code>content</code></em> value(s) are
+ concatenated to form its content.
+ </p><p>
+ Examples:
+</p><pre class="screen">
+SELECT xmlelement(name foo);
+
+ xmlelement
+------------
+ &lt;foo/&gt;
+
+SELECT xmlelement(name foo, xmlattributes('xyz' as bar));
+
+ xmlelement
+------------------
+ &lt;foo bar="xyz"/&gt;
+
+SELECT xmlelement(name foo, xmlattributes(current_date as bar), 'cont', 'ent');
+
+ xmlelement
+-------------------------------------
+ &lt;foo bar="2007-01-26"&gt;content&lt;/foo&gt;
+</pre><p>
+ </p><p>
+ Element and attribute names that are not valid XML names are
+ escaped by replacing the offending characters by the sequence
+ <code class="literal">_x<em class="replaceable"><code>HHHH</code></em>_</code>, where
+ <em class="replaceable"><code>HHHH</code></em> is the character's Unicode
+ codepoint in hexadecimal notation. For example:
+</p><pre class="screen">
+SELECT xmlelement(name "foo$bar", xmlattributes('xyz' as "a&amp;b"));
+
+ xmlelement
+----------------------------------
+ &lt;foo_x0024_bar a_x0026_b="xyz"/&gt;
+</pre><p>
+ </p><p>
+ An explicit attribute name need not be specified if the attribute
+ value is a column reference, in which case the column's name will
+ be used as the attribute name by default. In other cases, the
+ attribute must be given an explicit name. So this example is
+ valid:
+</p><pre class="screen">
+CREATE TABLE test (a xml, b xml);
+SELECT xmlelement(name test, xmlattributes(a, b)) FROM test;
+</pre><p>
+ But these are not:
+</p><pre class="screen">
+SELECT xmlelement(name test, xmlattributes('constant'), a, b) FROM test;
+SELECT xmlelement(name test, xmlattributes(func(a, b))) FROM test;
+</pre><p>
+ </p><p>
+ Element content, if specified, will be formatted according to
+ its data type. If the content is itself of type <code class="type">xml</code>,
+ complex XML documents can be constructed. For example:
+</p><pre class="screen">
+SELECT xmlelement(name foo, xmlattributes('xyz' as bar),
+ xmlelement(name abc),
+ xmlcomment('test'),
+ xmlelement(name xyz));
+
+ xmlelement
+----------------------------------------------
+ &lt;foo bar="xyz"&gt;&lt;abc/&gt;&lt;!--test--&gt;&lt;xyz/&gt;&lt;/foo&gt;
+</pre><p>
+
+ Content of other types will be formatted into valid XML character
+ data. This means in particular that the characters &lt;, &gt;,
+ and &amp; will be converted to entities. Binary data (data type
+ <code class="type">bytea</code>) will be represented in base64 or hex
+ encoding, depending on the setting of the configuration parameter
+ <a class="xref" href="runtime-config-client.html#GUC-XMLBINARY">xmlbinary</a>. The particular behavior for
+ individual data types is expected to evolve in order to align the
+ PostgreSQL mappings with those specified in SQL:2006 and later,
+ as discussed in <a class="xref" href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-CASTS" title="D.3.1.3. Mappings between SQL and XML Data Types and Values">Section D.3.1.3</a>.
+ </p></div><div class="sect3" id="id-1.5.8.21.5.6"><div class="titlepage"><div><div><h4 class="title">9.15.1.4. <code class="literal">xmlforest</code></h4></div></div></div><a id="id-1.5.8.21.5.6.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlforest</code> ( <em class="replaceable"><code>content</code></em> [<span class="optional"> <code class="literal">AS</code> <em class="replaceable"><code>name</code></em> </span>] [<span class="optional">, ...</span>] ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The <code class="function">xmlforest</code> expression produces an XML
+ forest (sequence) of elements using the given names and content.
+ As for <code class="function">xmlelement</code>,
+ each <em class="replaceable"><code>name</code></em> must be a simple identifier, while
+ the <em class="replaceable"><code>content</code></em> expressions can have any data
+ type.
+ </p><p>
+ Examples:
+</p><pre class="screen">
+SELECT xmlforest('abc' AS foo, 123 AS bar);
+
+ xmlforest
+------------------------------
+ &lt;foo&gt;abc&lt;/foo&gt;&lt;bar&gt;123&lt;/bar&gt;
+
+
+SELECT xmlforest(table_name, column_name)
+FROM information_schema.columns
+WHERE table_schema = 'pg_catalog';
+
+ xmlforest
+------------------------------------​-----------------------------------
+ &lt;table_name&gt;pg_authid&lt;/table_name&gt;​&lt;column_name&gt;rolname&lt;/column_name&gt;
+ &lt;table_name&gt;pg_authid&lt;/table_name&gt;​&lt;column_name&gt;rolsuper&lt;/column_name&gt;
+ ...
+</pre><p>
+
+ As seen in the second example, the element name can be omitted if
+ the content value is a column reference, in which case the column
+ name is used by default. Otherwise, a name must be specified.
+ </p><p>
+ Element names that are not valid XML names are escaped as shown
+ for <code class="function">xmlelement</code> above. Similarly, content
+ data is escaped to make valid XML content, unless it is already
+ of type <code class="type">xml</code>.
+ </p><p>
+ Note that XML forests are not valid XML documents if they consist
+ of more than one element, so it might be useful to wrap
+ <code class="function">xmlforest</code> expressions in
+ <code class="function">xmlelement</code>.
+ </p></div><div class="sect3" id="id-1.5.8.21.5.7"><div class="titlepage"><div><div><h4 class="title">9.15.1.5. <code class="literal">xmlpi</code></h4></div></div></div><a id="id-1.5.8.21.5.7.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlpi</code> ( <code class="literal">NAME</code> <em class="replaceable"><code>name</code></em> [<span class="optional">, <em class="replaceable"><code>content</code></em> </span>] ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The <code class="function">xmlpi</code> expression creates an XML
+ processing instruction.
+ As for <code class="function">xmlelement</code>,
+ the <em class="replaceable"><code>name</code></em> must be a simple identifier, while
+ the <em class="replaceable"><code>content</code></em> expression can have any data type.
+ The <em class="replaceable"><code>content</code></em>, if present, must not contain the
+ character sequence <code class="literal">?&gt;</code>.
+ </p><p>
+ Example:
+</p><pre class="screen">
+SELECT xmlpi(name php, 'echo "hello world";');
+
+ xmlpi
+-----------------------------
+ &lt;?php echo "hello world";?&gt;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.5.8.21.5.8"><div class="titlepage"><div><div><h4 class="title">9.15.1.6. <code class="literal">xmlroot</code></h4></div></div></div><a id="id-1.5.8.21.5.8.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlroot</code> ( <code class="type">xml</code>, <code class="literal">VERSION</code> {<code class="type">text</code>|<code class="literal">NO VALUE</code>} [<span class="optional">, <code class="literal">STANDALONE</code> {<code class="literal">YES</code>|<code class="literal">NO</code>|<code class="literal">NO VALUE</code>} </span>] ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The <code class="function">xmlroot</code> expression alters the properties
+ of the root node of an XML value. If a version is specified,
+ it replaces the value in the root node's version declaration; if a
+ standalone setting is specified, it replaces the value in the
+ root node's standalone declaration.
+ </p><p>
+</p><pre class="screen">
+SELECT xmlroot(xmlparse(document '&lt;?xml version="1.1"?&gt;&lt;content&gt;abc&lt;/content&gt;'),
+ version '1.0', standalone yes);
+
+ xmlroot
+----------------------------------------
+ &lt;?xml version="1.0" standalone="yes"?&gt;
+ &lt;content&gt;abc&lt;/content&gt;
+</pre><p>
+ </p></div><div class="sect3" id="FUNCTIONS-XML-XMLAGG"><div class="titlepage"><div><div><h4 class="title">9.15.1.7. <code class="literal">xmlagg</code></h4></div></div></div><a id="id-1.5.8.21.5.9.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xmlagg</code> ( <code class="type">xml</code> ) → <code class="returnvalue">xml</code>
+</pre><p>
+ The function <code class="function">xmlagg</code> is, unlike the other
+ functions described here, an aggregate function. It concatenates the
+ input values to the aggregate function call,
+ much like <code class="function">xmlconcat</code> does, except that concatenation
+ occurs across rows rather than across expressions in a single row.
+ See <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a> for additional information
+ about aggregate functions.
+ </p><p>
+ Example:
+</p><pre class="screen">
+CREATE TABLE test (y int, x xml);
+INSERT INTO test VALUES (1, '&lt;foo&gt;abc&lt;/foo&gt;');
+INSERT INTO test VALUES (2, '&lt;bar/&gt;');
+SELECT xmlagg(x) FROM test;
+ xmlagg
+----------------------
+ &lt;foo&gt;abc&lt;/foo&gt;&lt;bar/&gt;
+</pre><p>
+ </p><p>
+ To determine the order of the concatenation, an <code class="literal">ORDER BY</code>
+ clause may be added to the aggregate call as described in
+ <a class="xref" href="sql-expressions.html#SYNTAX-AGGREGATES" title="4.2.7. Aggregate Expressions">Section 4.2.7</a>. For example:
+
+</p><pre class="screen">
+SELECT xmlagg(x ORDER BY y DESC) FROM test;
+ xmlagg
+----------------------
+ &lt;bar/&gt;&lt;foo&gt;abc&lt;/foo&gt;
+</pre><p>
+ </p><p>
+ The following non-standard approach used to be recommended
+ in previous versions, and may still be useful in specific
+ cases:
+
+</p><pre class="screen">
+SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab;
+ xmlagg
+----------------------
+ &lt;bar/&gt;&lt;foo&gt;abc&lt;/foo&gt;
+</pre><p>
+ </p></div></div><div class="sect2" id="FUNCTIONS-XML-PREDICATES"><div class="titlepage"><div><div><h3 class="title">9.15.2. XML Predicates</h3></div></div></div><p>
+ The expressions described in this section check properties
+ of <code class="type">xml</code> values.
+ </p><div class="sect3" id="id-1.5.8.21.6.3"><div class="titlepage"><div><div><h4 class="title">9.15.2.1. <code class="literal">IS DOCUMENT</code></h4></div></div></div><a id="id-1.5.8.21.6.3.2" class="indexterm"></a><pre class="synopsis">
+<code class="type">xml</code> <code class="literal">IS DOCUMENT</code> → <code class="returnvalue">boolean</code>
+</pre><p>
+ The expression <code class="literal">IS DOCUMENT</code> returns true if the
+ argument XML value is a proper XML document, false if it is not
+ (that is, it is a content fragment), or null if the argument is
+ null. See <a class="xref" href="datatype-xml.html" title="8.13. XML Type">Section 8.13</a> about the difference
+ between documents and content fragments.
+ </p></div><div class="sect3" id="id-1.5.8.21.6.4"><div class="titlepage"><div><div><h4 class="title">9.15.2.2. <code class="literal">IS NOT DOCUMENT</code></h4></div></div></div><a id="id-1.5.8.21.6.4.2" class="indexterm"></a><pre class="synopsis">
+<code class="type">xml</code> <code class="literal">IS NOT DOCUMENT</code> → <code class="returnvalue">boolean</code>
+</pre><p>
+ The expression <code class="literal">IS NOT DOCUMENT</code> returns false if the
+ argument XML value is a proper XML document, true if it is not (that is,
+ it is a content fragment), or null if the argument is null.
+ </p></div><div class="sect3" id="XML-EXISTS"><div class="titlepage"><div><div><h4 class="title">9.15.2.3. <code class="literal">XMLEXISTS</code></h4></div></div></div><a id="id-1.5.8.21.6.5.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">XMLEXISTS</code> ( <code class="type">text</code> <code class="literal">PASSING</code> [<span class="optional"><code class="literal">BY</code> {<code class="literal">REF</code>|<code class="literal">VALUE</code>}</span>] <code class="type">xml</code> [<span class="optional"><code class="literal">BY</code> {<code class="literal">REF</code>|<code class="literal">VALUE</code>}</span>] ) → <code class="returnvalue">boolean</code>
+</pre><p>
+ The function <code class="function">xmlexists</code> evaluates an XPath 1.0
+ expression (the first argument), with the passed XML value as its context
+ item. The function returns false if the result of that evaluation
+ yields an empty node-set, true if it yields any other value. The
+ function returns null if any argument is null. A nonnull value
+ passed as the context item must be an XML document, not a content
+ fragment or any non-XML value.
+ </p><p>
+ Example:
+ </p><pre class="screen">
+SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE '&lt;towns&gt;&lt;town&gt;Toronto&lt;/town&gt;&lt;town&gt;Ottawa&lt;/town&gt;&lt;/towns&gt;');
+
+ xmlexists
+------------
+ t
+(1 row)
+</pre><p>
+ </p><p>
+ The <code class="literal">BY REF</code> and <code class="literal">BY VALUE</code> clauses
+ are accepted in <span class="productname">PostgreSQL</span>, but are ignored,
+ as discussed in <a class="xref" href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-POSTGRESQL" title="D.3.2. Incidental Limits of the Implementation">Section D.3.2</a>.
+ </p><p>
+ In the SQL standard, the <code class="function">xmlexists</code> function
+ evaluates an expression in the XML Query language,
+ but <span class="productname">PostgreSQL</span> allows only an XPath 1.0
+ expression, as discussed in
+ <a class="xref" href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-XPATH1" title="D.3.1. Queries Are Restricted to XPath 1.0">Section D.3.1</a>.
+ </p></div><div class="sect3" id="XML-IS-WELL-FORMED"><div class="titlepage"><div><div><h4 class="title">9.15.2.4. <code class="literal">xml_is_well_formed</code></h4></div></div></div><a id="id-1.5.8.21.6.6.2" class="indexterm"></a><a id="id-1.5.8.21.6.6.3" class="indexterm"></a><a id="id-1.5.8.21.6.6.4" class="indexterm"></a><pre class="synopsis">
+<code class="function">xml_is_well_formed</code> ( <code class="type">text</code> ) → <code class="returnvalue">boolean</code>
+<code class="function">xml_is_well_formed_document</code> ( <code class="type">text</code> ) → <code class="returnvalue">boolean</code>
+<code class="function">xml_is_well_formed_content</code> ( <code class="type">text</code> ) → <code class="returnvalue">boolean</code>
+</pre><p>
+ These functions check whether a <code class="type">text</code> string represents
+ well-formed XML, returning a Boolean result.
+ <code class="function">xml_is_well_formed_document</code> checks for a well-formed
+ document, while <code class="function">xml_is_well_formed_content</code> checks
+ for well-formed content. <code class="function">xml_is_well_formed</code> does
+ the former if the <a class="xref" href="runtime-config-client.html#GUC-XMLOPTION">xmloption</a> configuration
+ parameter is set to <code class="literal">DOCUMENT</code>, or the latter if it is set to
+ <code class="literal">CONTENT</code>. This means that
+ <code class="function">xml_is_well_formed</code> is useful for seeing whether
+ a simple cast to type <code class="type">xml</code> will succeed, whereas the other two
+ functions are useful for seeing whether the corresponding variants of
+ <code class="function">XMLPARSE</code> will succeed.
+ </p><p>
+ Examples:
+
+</p><pre class="screen">
+SET xmloption TO DOCUMENT;
+SELECT xml_is_well_formed('&lt;&gt;');
+ xml_is_well_formed
+--------------------
+ f
+(1 row)
+
+SELECT xml_is_well_formed('&lt;abc/&gt;');
+ xml_is_well_formed
+--------------------
+ t
+(1 row)
+
+SET xmloption TO CONTENT;
+SELECT xml_is_well_formed('abc');
+ xml_is_well_formed
+--------------------
+ t
+(1 row)
+
+SELECT xml_is_well_formed_document('&lt;pg:foo xmlns:pg="http://postgresql.org/stuff"&gt;bar&lt;/pg:foo&gt;');
+ xml_is_well_formed_document
+-----------------------------
+ t
+(1 row)
+
+SELECT xml_is_well_formed_document('&lt;pg:foo xmlns:pg="http://postgresql.org/stuff"&gt;bar&lt;/my:foo&gt;');
+ xml_is_well_formed_document
+-----------------------------
+ f
+(1 row)
+</pre><p>
+
+ The last example shows that the checks include whether
+ namespaces are correctly matched.
+ </p></div></div><div class="sect2" id="FUNCTIONS-XML-PROCESSING"><div class="titlepage"><div><div><h3 class="title">9.15.3. Processing XML</h3></div></div></div><p>
+ To process values of data type <code class="type">xml</code>, PostgreSQL offers
+ the functions <code class="function">xpath</code> and
+ <code class="function">xpath_exists</code>, which evaluate XPath 1.0
+ expressions, and the <code class="function">XMLTABLE</code>
+ table function.
+ </p><div class="sect3" id="FUNCTIONS-XML-PROCESSING-XPATH"><div class="titlepage"><div><div><h4 class="title">9.15.3.1. <code class="literal">xpath</code></h4></div></div></div><a id="id-1.5.8.21.7.3.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xpath</code> ( <em class="parameter"><code>xpath</code></em> <code class="type">text</code>, <em class="parameter"><code>xml</code></em> <code class="type">xml</code> [<span class="optional">, <em class="parameter"><code>nsarray</code></em> <code class="type">text[]</code> </span>] ) → <code class="returnvalue">xml[]</code>
+</pre><p>
+ The function <code class="function">xpath</code> evaluates the XPath 1.0
+ expression <em class="parameter"><code>xpath</code></em> (given as text)
+ against the XML value
+ <em class="parameter"><code>xml</code></em>. It returns an array of XML values
+ corresponding to the node-set produced by the XPath expression.
+ If the XPath expression returns a scalar value rather than a node-set,
+ a single-element array is returned.
+ </p><p>
+ The second argument must be a well formed XML document. In particular,
+ it must have a single root node element.
+ </p><p>
+ The optional third argument of the function is an array of namespace
+ mappings. This array should be a two-dimensional <code class="type">text</code> array with
+ the length of the second axis being equal to 2 (i.e., it should be an
+ array of arrays, each of which consists of exactly 2 elements).
+ The first element of each array entry is the namespace name (alias), the
+ second the namespace URI. It is not required that aliases provided in
+ this array be the same as those being used in the XML document itself (in
+ other words, both in the XML document and in the <code class="function">xpath</code>
+ function context, aliases are <span class="emphasis"><em>local</em></span>).
+ </p><p>
+ Example:
+</p><pre class="screen">
+SELECT xpath('/my:a/text()', '&lt;my:a xmlns:my="http://example.com"&gt;test&lt;/my:a&gt;',
+ ARRAY[ARRAY['my', 'http://example.com']]);
+
+ xpath
+--------
+ {test}
+(1 row)
+</pre><p>
+ </p><p>
+ To deal with default (anonymous) namespaces, do something like this:
+</p><pre class="screen">
+SELECT xpath('//mydefns:b/text()', '&lt;a xmlns="http://example.com"&gt;&lt;b&gt;test&lt;/b&gt;&lt;/a&gt;',
+ ARRAY[ARRAY['mydefns', 'http://example.com']]);
+
+ xpath
+--------
+ {test}
+(1 row)
+</pre><p>
+ </p></div><div class="sect3" id="FUNCTIONS-XML-PROCESSING-XPATH-EXISTS"><div class="titlepage"><div><div><h4 class="title">9.15.3.2. <code class="literal">xpath_exists</code></h4></div></div></div><a id="id-1.5.8.21.7.4.2" class="indexterm"></a><pre class="synopsis">
+<code class="function">xpath_exists</code> ( <em class="parameter"><code>xpath</code></em> <code class="type">text</code>, <em class="parameter"><code>xml</code></em> <code class="type">xml</code> [<span class="optional">, <em class="parameter"><code>nsarray</code></em> <code class="type">text[]</code> </span>] ) → <code class="returnvalue">boolean</code>
+</pre><p>
+ The function <code class="function">xpath_exists</code> is a specialized form
+ of the <code class="function">xpath</code> function. Instead of returning the
+ individual XML values that satisfy the XPath 1.0 expression, this function
+ returns a Boolean indicating whether the query was satisfied or not
+ (specifically, whether it produced any value other than an empty node-set).
+ This function is equivalent to the <code class="literal">XMLEXISTS</code> predicate,
+ except that it also offers support for a namespace mapping argument.
+ </p><p>
+ Example:
+</p><pre class="screen">
+SELECT xpath_exists('/my:a/text()', '&lt;my:a xmlns:my="http://example.com"&gt;test&lt;/my:a&gt;',
+ ARRAY[ARRAY['my', 'http://example.com']]);
+
+ xpath_exists
+--------------
+ t
+(1 row)
+</pre><p>
+ </p></div><div class="sect3" id="FUNCTIONS-XML-PROCESSING-XMLTABLE"><div class="titlepage"><div><div><h4 class="title">9.15.3.3. <code class="literal">xmltable</code></h4></div></div></div><a id="id-1.5.8.21.7.5.2" class="indexterm"></a><a id="id-1.5.8.21.7.5.3" class="indexterm"></a><pre class="synopsis">
+<code class="function">XMLTABLE</code> (
+ [<span class="optional"> <code class="literal">XMLNAMESPACES</code> ( <em class="replaceable"><code>namespace_uri</code></em> <code class="literal">AS</code> <em class="replaceable"><code>namespace_name</code></em> [<span class="optional">, ...</span>] ), </span>]
+ <em class="replaceable"><code>row_expression</code></em> <code class="literal">PASSING</code> [<span class="optional"><code class="literal">BY</code> {<code class="literal">REF</code>|<code class="literal">VALUE</code>}</span>] <em class="replaceable"><code>document_expression</code></em> [<span class="optional"><code class="literal">BY</code> {<code class="literal">REF</code>|<code class="literal">VALUE</code>}</span>]
+ <code class="literal">COLUMNS</code> <em class="replaceable"><code>name</code></em> { <em class="replaceable"><code>type</code></em> [<span class="optional"><code class="literal">PATH</code> <em class="replaceable"><code>column_expression</code></em></span>] [<span class="optional"><code class="literal">DEFAULT</code> <em class="replaceable"><code>default_expression</code></em></span>] [<span class="optional"><code class="literal">NOT NULL</code> | <code class="literal">NULL</code></span>]
+ | <code class="literal">FOR ORDINALITY</code> }
+ [<span class="optional">, ...</span>]
+) → <code class="returnvalue">setof record</code>
+</pre><p>
+ The <code class="function">xmltable</code> expression produces a table based
+ on an XML value, an XPath filter to extract rows, and a
+ set of column definitions.
+ Although it syntactically resembles a function, it can only appear
+ as a table in a query's <code class="literal">FROM</code> clause.
+ </p><p>
+ The optional <code class="literal">XMLNAMESPACES</code> clause gives a
+ comma-separated list of namespace definitions, where
+ each <em class="replaceable"><code>namespace_uri</code></em> is a <code class="type">text</code>
+ expression and each <em class="replaceable"><code>namespace_name</code></em> is a simple
+ identifier. It specifies the XML namespaces used in the document and
+ their aliases. A default namespace specification is not currently
+ supported.
+ </p><p>
+ The required <em class="replaceable"><code>row_expression</code></em> argument is an
+ XPath 1.0 expression (given as <code class="type">text</code>) that is evaluated,
+ passing the XML value <em class="replaceable"><code>document_expression</code></em> as
+ its context item, to obtain a set of XML nodes. These nodes are what
+ <code class="function">xmltable</code> transforms into output rows. No rows
+ will be produced if the <em class="replaceable"><code>document_expression</code></em>
+ is null, nor if the <em class="replaceable"><code>row_expression</code></em> produces
+ an empty node-set or any value other than a node-set.
+ </p><p>
+ <em class="replaceable"><code>document_expression</code></em> provides the context
+ item for the <em class="replaceable"><code>row_expression</code></em>. It must be a
+ well-formed XML document; fragments/forests are not accepted.
+ The <code class="literal">BY REF</code> and <code class="literal">BY VALUE</code> clauses
+ are accepted but ignored, as discussed in
+ <a class="xref" href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-POSTGRESQL" title="D.3.2. Incidental Limits of the Implementation">Section D.3.2</a>.
+ </p><p>
+ In the SQL standard, the <code class="function">xmltable</code> function
+ evaluates expressions in the XML Query language,
+ but <span class="productname">PostgreSQL</span> allows only XPath 1.0
+ expressions, as discussed in
+ <a class="xref" href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-XPATH1" title="D.3.1. Queries Are Restricted to XPath 1.0">Section D.3.1</a>.
+ </p><p>
+ The required <code class="literal">COLUMNS</code> clause specifies the
+ column(s) that will be produced in the output table.
+ See the syntax summary above for the format.
+ A name is required for each column, as is a data type
+ (unless <code class="literal">FOR ORDINALITY</code> is specified, in which case
+ type <code class="type">integer</code> is implicit). The path, default and
+ nullability clauses are optional.
+ </p><p>
+ A column marked <code class="literal">FOR ORDINALITY</code> will be populated
+ with row numbers, starting with 1, in the order of nodes retrieved from
+ the <em class="replaceable"><code>row_expression</code></em>'s result node-set.
+ At most one column may be marked <code class="literal">FOR ORDINALITY</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ XPath 1.0 does not specify an order for nodes in a node-set, so code
+ that relies on a particular order of the results will be
+ implementation-dependent. Details can be found in
+ <a class="xref" href="xml-limits-conformance.html#XML-XPATH-1-SPECIFICS" title="D.3.1.2. Restriction of XPath to 1.0">Section D.3.1.2</a>.
+ </p></div><p>
+ The <em class="replaceable"><code>column_expression</code></em> for a column is an
+ XPath 1.0 expression that is evaluated for each row, with the current
+ node from the <em class="replaceable"><code>row_expression</code></em> result as its
+ context item, to find the value of the column. If
+ no <em class="replaceable"><code>column_expression</code></em> is given, then the
+ column name is used as an implicit path.
+ </p><p>
+ If a column's XPath expression returns a non-XML value (which is limited
+ to string, boolean, or double in XPath 1.0) and the column has a
+ PostgreSQL type other than <code class="type">xml</code>, the column will be set
+ as if by assigning the value's string representation to the PostgreSQL
+ type. (If the value is a boolean, its string representation is taken
+ to be <code class="literal">1</code> or <code class="literal">0</code> if the output
+ column's type category is numeric, otherwise <code class="literal">true</code> or
+ <code class="literal">false</code>.)
+ </p><p>
+ If a column's XPath expression returns a non-empty set of XML nodes
+ and the column's PostgreSQL type is <code class="type">xml</code>, the column will
+ be assigned the expression result exactly, if it is of document or
+ content form.
+ <a href="#ftn.id-1.5.8.21.7.5.15.2" class="footnote"><sup class="footnote" id="id-1.5.8.21.7.5.15.2">[8]</sup></a>
+ </p><p>
+ A non-XML result assigned to an <code class="type">xml</code> output column produces
+ content, a single text node with the string value of the result.
+ An XML result assigned to a column of any other type may not have more than
+ one node, or an error is raised. If there is exactly one node, the column
+ will be set as if by assigning the node's string
+ value (as defined for the XPath 1.0 <code class="function">string</code> function)
+ to the PostgreSQL type.
+ </p><p>
+ The string value of an XML element is the concatenation, in document order,
+ of all text nodes contained in that element and its descendants. The string
+ value of an element with no descendant text nodes is an
+ empty string (not <code class="literal">NULL</code>).
+ Any <code class="literal">xsi:nil</code> attributes are ignored.
+ Note that the whitespace-only <code class="literal">text()</code> node between two non-text
+ elements is preserved, and that leading whitespace on a <code class="literal">text()</code>
+ node is not flattened.
+ The XPath 1.0 <code class="function">string</code> function may be consulted for the
+ rules defining the string value of other XML node types and non-XML values.
+ </p><p>
+ The conversion rules presented here are not exactly those of the SQL
+ standard, as discussed in <a class="xref" href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-CASTS" title="D.3.1.3. Mappings between SQL and XML Data Types and Values">Section D.3.1.3</a>.
+ </p><p>
+ If the path expression returns an empty node-set
+ (typically, when it does not match)
+ for a given row, the column will be set to <code class="literal">NULL</code>, unless
+ a <em class="replaceable"><code>default_expression</code></em> is specified; then the
+ value resulting from evaluating that expression is used.
+ </p><p>
+ A <em class="replaceable"><code>default_expression</code></em>, rather than being
+ evaluated immediately when <code class="function">xmltable</code> is called,
+ is evaluated each time a default is needed for the column.
+ If the expression qualifies as stable or immutable, the repeat
+ evaluation may be skipped.
+ This means that you can usefully use volatile functions like
+ <code class="function">nextval</code> in
+ <em class="replaceable"><code>default_expression</code></em>.
+ </p><p>
+ Columns may be marked <code class="literal">NOT NULL</code>. If the
+ <em class="replaceable"><code>column_expression</code></em> for a <code class="literal">NOT
+ NULL</code> column does not match anything and there is
+ no <code class="literal">DEFAULT</code> or
+ the <em class="replaceable"><code>default_expression</code></em> also evaluates to null,
+ an error is reported.
+ </p><p>
+ Examples:
+ </p><pre class="screen">
+CREATE TABLE xmldata AS SELECT
+xml $$
+&lt;ROWS&gt;
+ &lt;ROW id="1"&gt;
+ &lt;COUNTRY_ID&gt;AU&lt;/COUNTRY_ID&gt;
+ &lt;COUNTRY_NAME&gt;Australia&lt;/COUNTRY_NAME&gt;
+ &lt;/ROW&gt;
+ &lt;ROW id="5"&gt;
+ &lt;COUNTRY_ID&gt;JP&lt;/COUNTRY_ID&gt;
+ &lt;COUNTRY_NAME&gt;Japan&lt;/COUNTRY_NAME&gt;
+ &lt;PREMIER_NAME&gt;Shinzo Abe&lt;/PREMIER_NAME&gt;
+ &lt;SIZE unit="sq_mi"&gt;145935&lt;/SIZE&gt;
+ &lt;/ROW&gt;
+ &lt;ROW id="6"&gt;
+ &lt;COUNTRY_ID&gt;SG&lt;/COUNTRY_ID&gt;
+ &lt;COUNTRY_NAME&gt;Singapore&lt;/COUNTRY_NAME&gt;
+ &lt;SIZE unit="sq_km"&gt;697&lt;/SIZE&gt;
+ &lt;/ROW&gt;
+&lt;/ROWS&gt;
+$$ AS data;
+
+SELECT xmltable.*
+ FROM xmldata,
+ XMLTABLE('//ROWS/ROW'
+ PASSING data
+ COLUMNS id int PATH '@id',
+ ordinality FOR ORDINALITY,
+ "COUNTRY_NAME" text,
+ country_id text PATH 'COUNTRY_ID',
+ size_sq_km float PATH 'SIZE[@unit = "sq_km"]',
+ size_other text PATH
+ 'concat(SIZE[@unit!="sq_km"], " ", SIZE[@unit!="sq_km"]/@unit)',
+ premier_name text PATH 'PREMIER_NAME' DEFAULT 'not specified');
+
+ id | ordinality | COUNTRY_NAME | country_id | size_sq_km | size_other | premier_name
+----+------------+--------------+------------+------------+--------------+---------------
+ 1 | 1 | Australia | AU | | | not specified
+ 5 | 2 | Japan | JP | | 145935 sq_mi | Shinzo Abe
+ 6 | 3 | Singapore | SG | 697 | | not specified
+</pre><p>
+
+ The following example shows concatenation of multiple text() nodes,
+ usage of the column name as XPath filter, and the treatment of whitespace,
+ XML comments and processing instructions:
+
+ </p><pre class="screen">
+CREATE TABLE xmlelements AS SELECT
+xml $$
+ &lt;root&gt;
+ &lt;element&gt; Hello&lt;!-- xyxxz --&gt;2a2&lt;?aaaaa?&gt; &lt;!--x--&gt; bbb&lt;x&gt;xxx&lt;/x&gt;CC &lt;/element&gt;
+ &lt;/root&gt;
+$$ AS data;
+
+SELECT xmltable.*
+ FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text);
+ element
+-------------------------
+ Hello2a2 bbbxxxCC
+</pre><p>
+ </p><p>
+ The following example illustrates how
+ the <code class="literal">XMLNAMESPACES</code> clause can be used to specify
+ a list of namespaces
+ used in the XML document as well as in the XPath expressions:
+
+ </p><pre class="screen">
+WITH xmldata(data) AS (VALUES ('
+&lt;example xmlns="http://example.com/myns" xmlns:B="http://example.com/b"&gt;
+ &lt;item foo="1" B:bar="2"/&gt;
+ &lt;item foo="3" B:bar="4"/&gt;
+ &lt;item foo="4" B:bar="5"/&gt;
+&lt;/example&gt;'::xml)
+)
+SELECT xmltable.*
+ FROM XMLTABLE(XMLNAMESPACES('http://example.com/myns' AS x,
+ 'http://example.com/b' AS "B"),
+ '/x:example/x:item'
+ PASSING (SELECT data FROM xmldata)
+ COLUMNS foo int PATH '@foo',
+ bar int PATH '@B:bar');
+ foo | bar
+-----+-----
+ 1 | 2
+ 3 | 4
+ 4 | 5
+(3 rows)
+</pre><p>
+ </p></div></div><div class="sect2" id="FUNCTIONS-XML-MAPPING"><div class="titlepage"><div><div><h3 class="title">9.15.4. Mapping Tables to XML</h3></div></div></div><a id="id-1.5.8.21.8.2" class="indexterm"></a><p>
+ The following functions map the contents of relational tables to
+ XML values. They can be thought of as XML export functionality:
+</p><pre class="synopsis">
+<code class="function">table_to_xml</code> ( <em class="parameter"><code>table</code></em> <code class="type">regclass</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">query_to_xml</code> ( <em class="parameter"><code>query</code></em> <code class="type">text</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">cursor_to_xml</code> ( <em class="parameter"><code>cursor</code></em> <code class="type">refcursor</code>, <em class="parameter"><code>count</code></em> <code class="type">integer</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+</pre><p>
+ </p><p>
+ <code class="function">table_to_xml</code> maps the content of the named
+ table, passed as parameter <em class="parameter"><code>table</code></em>. The
+ <code class="type">regclass</code> type accepts strings identifying tables using the
+ usual notation, including optional schema qualification and
+ double quotes (see <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a> for details).
+ <code class="function">query_to_xml</code> executes the
+ query whose text is passed as parameter
+ <em class="parameter"><code>query</code></em> and maps the result set.
+ <code class="function">cursor_to_xml</code> fetches the indicated number of
+ rows from the cursor specified by the parameter
+ <em class="parameter"><code>cursor</code></em>. This variant is recommended if
+ large tables have to be mapped, because the result value is built
+ up in memory by each function.
+ </p><p>
+ If <em class="parameter"><code>tableforest</code></em> is false, then the resulting
+ XML document looks like this:
+</p><pre class="screen">
+&lt;tablename&gt;
+ &lt;row&gt;
+ &lt;columnname1&gt;data&lt;/columnname1&gt;
+ &lt;columnname2&gt;data&lt;/columnname2&gt;
+ &lt;/row&gt;
+
+ &lt;row&gt;
+ ...
+ &lt;/row&gt;
+
+ ...
+&lt;/tablename&gt;
+</pre><p>
+
+ If <em class="parameter"><code>tableforest</code></em> is true, the result is an
+ XML content fragment that looks like this:
+</p><pre class="screen">
+&lt;tablename&gt;
+ &lt;columnname1&gt;data&lt;/columnname1&gt;
+ &lt;columnname2&gt;data&lt;/columnname2&gt;
+&lt;/tablename&gt;
+
+&lt;tablename&gt;
+ ...
+&lt;/tablename&gt;
+
+...
+</pre><p>
+
+ If no table name is available, that is, when mapping a query or a
+ cursor, the string <code class="literal">table</code> is used in the first
+ format, <code class="literal">row</code> in the second format.
+ </p><p>
+ The choice between these formats is up to the user. The first
+ format is a proper XML document, which will be important in many
+ applications. The second format tends to be more useful in the
+ <code class="function">cursor_to_xml</code> function if the result values are to be
+ reassembled into one document later on. The functions for
+ producing XML content discussed above, in particular
+ <code class="function">xmlelement</code>, can be used to alter the results
+ to taste.
+ </p><p>
+ The data values are mapped in the same way as described for the
+ function <code class="function">xmlelement</code> above.
+ </p><p>
+ The parameter <em class="parameter"><code>nulls</code></em> determines whether null
+ values should be included in the output. If true, null values in
+ columns are represented as:
+</p><pre class="screen">
+&lt;columnname xsi:nil="true"/&gt;
+</pre><p>
+ where <code class="literal">xsi</code> is the XML namespace prefix for XML
+ Schema Instance. An appropriate namespace declaration will be
+ added to the result value. If false, columns containing null
+ values are simply omitted from the output.
+ </p><p>
+ The parameter <em class="parameter"><code>targetns</code></em> specifies the
+ desired XML namespace of the result. If no particular namespace
+ is wanted, an empty string should be passed.
+ </p><p>
+ The following functions return XML Schema documents describing the
+ mappings performed by the corresponding functions above:
+</p><pre class="synopsis">
+<code class="function">table_to_xmlschema</code> ( <em class="parameter"><code>table</code></em> <code class="type">regclass</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">query_to_xmlschema</code> ( <em class="parameter"><code>query</code></em> <code class="type">text</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">cursor_to_xmlschema</code> ( <em class="parameter"><code>cursor</code></em> <code class="type">refcursor</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+</pre><p>
+ It is essential that the same parameters are passed in order to
+ obtain matching XML data mappings and XML Schema documents.
+ </p><p>
+ The following functions produce XML data mappings and the
+ corresponding XML Schema in one document (or forest), linked
+ together. They can be useful where self-contained and
+ self-describing results are wanted:
+</p><pre class="synopsis">
+<code class="function">table_to_xml_and_xmlschema</code> ( <em class="parameter"><code>table</code></em> <code class="type">regclass</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">query_to_xml_and_xmlschema</code> ( <em class="parameter"><code>query</code></em> <code class="type">text</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+</pre><p>
+ </p><p>
+ In addition, the following functions are available to produce
+ analogous mappings of entire schemas or the entire current
+ database:
+</p><pre class="synopsis">
+<code class="function">schema_to_xml</code> ( <em class="parameter"><code>schema</code></em> <code class="type">name</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">schema_to_xmlschema</code> ( <em class="parameter"><code>schema</code></em> <code class="type">name</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">schema_to_xml_and_xmlschema</code> ( <em class="parameter"><code>schema</code></em> <code class="type">name</code>, <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+
+<code class="function">database_to_xml</code> ( <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">database_to_xmlschema</code> ( <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+<code class="function">database_to_xml_and_xmlschema</code> ( <em class="parameter"><code>nulls</code></em> <code class="type">boolean</code>,
+ <em class="parameter"><code>tableforest</code></em> <code class="type">boolean</code>, <em class="parameter"><code>targetns</code></em> <code class="type">text</code> ) → <code class="returnvalue">xml</code>
+</pre><p>
+
+ These functions ignore tables that are not readable by the current user.
+ The database-wide functions additionally ignore schemas that the current
+ user does not have <code class="literal">USAGE</code> (lookup) privilege for.
+ </p><p>
+ Note that these potentially produce a lot of data, which needs to
+ be built up in memory. When requesting content mappings of large
+ schemas or databases, it might be worthwhile to consider mapping the
+ tables separately instead, possibly even through a cursor.
+ </p><p>
+ The result of a schema content mapping looks like this:
+
+</p><pre class="screen">
+&lt;schemaname&gt;
+
+table1-mapping
+
+table2-mapping
+
+...
+
+&lt;/schemaname&gt;</pre><p>
+
+ where the format of a table mapping depends on the
+ <em class="parameter"><code>tableforest</code></em> parameter as explained above.
+ </p><p>
+ The result of a database content mapping looks like this:
+
+</p><pre class="screen">
+&lt;dbname&gt;
+
+&lt;schema1name&gt;
+ ...
+&lt;/schema1name&gt;
+
+&lt;schema2name&gt;
+ ...
+&lt;/schema2name&gt;
+
+...
+
+&lt;/dbname&gt;</pre><p>
+
+ where the schema mapping is as above.
+ </p><p>
+ As an example of using the output produced by these functions,
+ <a class="xref" href="functions-xml.html#XSLT-XML-HTML" title="Example 9.1. XSLT Stylesheet for Converting SQL/XML Output to HTML">Example 9.1</a> shows an XSLT stylesheet that
+ converts the output of
+ <code class="function">table_to_xml_and_xmlschema</code> to an HTML
+ document containing a tabular rendition of the table data. In a
+ similar manner, the results from these functions can be
+ converted into other XML-based formats.
+ </p><div class="example" id="XSLT-XML-HTML"><p class="title"><strong>Example 9.1. XSLT Stylesheet for Converting SQL/XML Output to HTML</strong></p><div class="example-contents"><pre class="programlisting">
+&lt;?xml version="1.0"?&gt;
+&lt;xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="http://www.w3.org/1999/xhtml"
+&gt;
+
+ &lt;xsl:output method="xml"
+ doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
+ doctype-public="-//W3C/DTD XHTML 1.0 Strict//EN"
+ indent="yes"/&gt;
+
+ &lt;xsl:template match="/*"&gt;
+ &lt;xsl:variable name="schema" select="//xsd:schema"/&gt;
+ &lt;xsl:variable name="tabletypename"
+ select="$schema/xsd:element[@name=name(current())]/@type"/&gt;
+ &lt;xsl:variable name="rowtypename"
+ select="$schema/xsd:complexType[@name=$tabletypename]/xsd:sequence/xsd:element[@name='row']/@type"/&gt;
+
+ &lt;html&gt;
+ &lt;head&gt;
+ &lt;title&gt;&lt;xsl:value-of select="name(current())"/&gt;&lt;/title&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+ &lt;xsl:for-each select="$schema/xsd:complexType[@name=$rowtypename]/xsd:sequence/xsd:element/@name"&gt;
+ &lt;th&gt;&lt;xsl:value-of select="."/&gt;&lt;/th&gt;
+ &lt;/xsl:for-each&gt;
+ &lt;/tr&gt;
+
+ &lt;xsl:for-each select="row"&gt;
+ &lt;tr&gt;
+ &lt;xsl:for-each select="*"&gt;
+ &lt;td&gt;&lt;xsl:value-of select="."/&gt;&lt;/td&gt;
+ &lt;/xsl:for-each&gt;
+ &lt;/tr&gt;
+ &lt;/xsl:for-each&gt;
+ &lt;/table&gt;
+ &lt;/body&gt;
+ &lt;/html&gt;
+ &lt;/xsl:template&gt;
+
+&lt;/xsl:stylesheet&gt;
+</pre></div></div><br class="example-break" /></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.5.8.21.7.5.15.2" class="footnote"><p><a href="#id-1.5.8.21.7.5.15.2" class="para"><sup class="para">[8] </sup></a>
+ A result containing more than one element node at the top level, or
+ non-whitespace text outside of an element, is an example of content form.
+ An XPath result can be of neither form, for example if it returns an
+ attribute node selected from the element that contains it. Such a result
+ will be put into content form with each such disallowed node replaced by
+ its string value, as defined for the XPath 1.0
+ <code class="function">string</code> function.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-uuid.html" title="9.14. UUID Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="functions.html" title="Chapter 9. Functions and Operators">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-json.html" title="9.16. JSON Functions and Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.14. UUID Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.16. JSON Functions and Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/functions.html b/doc/src/sgml/html/functions.html
new file mode 100644
index 0000000..2d5043d
--- /dev/null
+++ b/doc/src/sgml/html/functions.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 9. Functions and Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datatype-pseudo.html" title="8.21. Pseudo-Types" /><link rel="next" href="functions-logical.html" title="9.1. Logical Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 9. Functions and Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datatype-pseudo.html" title="8.21. Pseudo-Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="functions-logical.html" title="9.1. Logical Operators">Next</a></td></tr></table><hr /></div><div class="chapter" id="FUNCTIONS"><div class="titlepage"><div><div><h2 class="title">Chapter 9. Functions and Operators</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="functions-logical.html">9.1. Logical Operators</a></span></dt><dt><span class="sect1"><a href="functions-comparison.html">9.2. Comparison Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-math.html">9.3. Mathematical Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-string.html">9.4. String Functions and Operators</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-string.html#FUNCTIONS-STRING-FORMAT">9.4.1. <code class="function">format</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-binarystring.html">9.5. Binary String Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-bitstring.html">9.6. Bit String Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-matching.html">9.7. Pattern Matching</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-matching.html#FUNCTIONS-LIKE">9.7.1. <code class="function">LIKE</code></a></span></dt><dt><span class="sect2"><a href="functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP">9.7.2. <code class="function">SIMILAR TO</code> Regular Expressions</a></span></dt><dt><span class="sect2"><a href="functions-matching.html#FUNCTIONS-POSIX-REGEXP">9.7.3. <acronym class="acronym">POSIX</acronym> Regular Expressions</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-formatting.html">9.8. Data Type Formatting Functions</a></span></dt><dt><span class="sect1"><a href="functions-datetime.html">9.9. Date/Time Functions and Operators</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT">9.9.1. <code class="function">EXTRACT</code>, <code class="function">date_part</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-TRUNC">9.9.2. <code class="function">date_trunc</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-BIN">9.9.3. <code class="function">date_bin</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT">9.9.4. <code class="literal">AT TIME ZONE</code></a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-CURRENT">9.9.5. Current Date/Time</a></span></dt><dt><span class="sect2"><a href="functions-datetime.html#FUNCTIONS-DATETIME-DELAY">9.9.6. Delaying Execution</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-enum.html">9.10. Enum Support Functions</a></span></dt><dt><span class="sect1"><a href="functions-geometry.html">9.11. Geometric Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-net.html">9.12. Network Address Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-textsearch.html">9.13. Text Search Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-uuid.html">9.14. UUID Functions</a></span></dt><dt><span class="sect1"><a href="functions-xml.html">9.15. XML Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-PRODUCING-XML">9.15.1. Producing XML Content</a></span></dt><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-XML-PREDICATES">9.15.2. XML Predicates</a></span></dt><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-XML-PROCESSING">9.15.3. Processing XML</a></span></dt><dt><span class="sect2"><a href="functions-xml.html#FUNCTIONS-XML-MAPPING">9.15.4. Mapping Tables to XML</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-json.html">9.16. JSON Functions and Operators</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-json.html#FUNCTIONS-JSON-PROCESSING">9.16.1. Processing and Creating JSON Data</a></span></dt><dt><span class="sect2"><a href="functions-json.html#FUNCTIONS-SQLJSON-PATH">9.16.2. The SQL/JSON Path Language</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-sequence.html">9.17. Sequence Manipulation Functions</a></span></dt><dt><span class="sect1"><a href="functions-conditional.html">9.18. Conditional Expressions</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-CASE">9.18.1. <code class="literal">CASE</code></a></span></dt><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-COALESCE-NVL-IFNULL">9.18.2. <code class="literal">COALESCE</code></a></span></dt><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-NULLIF">9.18.3. <code class="literal">NULLIF</code></a></span></dt><dt><span class="sect2"><a href="functions-conditional.html#FUNCTIONS-GREATEST-LEAST">9.18.4. <code class="literal">GREATEST</code> and <code class="literal">LEAST</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-array.html">9.19. Array Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-range.html">9.20. Range/Multirange Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-aggregate.html">9.21. Aggregate Functions</a></span></dt><dt><span class="sect1"><a href="functions-window.html">9.22. Window Functions</a></span></dt><dt><span class="sect1"><a href="functions-subquery.html">9.23. Subquery Expressions</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-EXISTS">9.23.1. <code class="literal">EXISTS</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-IN">9.23.2. <code class="literal">IN</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-NOTIN">9.23.3. <code class="literal">NOT IN</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-ANY-SOME">9.23.4. <code class="literal">ANY</code>/<code class="literal">SOME</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#FUNCTIONS-SUBQUERY-ALL">9.23.5. <code class="literal">ALL</code></a></span></dt><dt><span class="sect2"><a href="functions-subquery.html#id-1.5.8.29.15">9.23.6. Single-Row Comparison</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-comparisons.html">9.24. Row and Array Comparisons</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-comparisons.html#FUNCTIONS-COMPARISONS-IN-SCALAR">9.24.1. <code class="literal">IN</code></a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#id-1.5.8.30.15">9.24.2. <code class="literal">NOT IN</code></a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#id-1.5.8.30.16">9.24.3. <code class="literal">ANY</code>/<code class="literal">SOME</code> (array)</a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#id-1.5.8.30.17">9.24.4. <code class="literal">ALL</code> (array)</a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#ROW-WISE-COMPARISON">9.24.5. Row Constructor Comparison</a></span></dt><dt><span class="sect2"><a href="functions-comparisons.html#COMPOSITE-TYPE-COMPARISON">9.24.6. Composite Type Comparison</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-srf.html">9.25. Set Returning Functions</a></span></dt><dt><span class="sect1"><a href="functions-info.html">9.26. System Information Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-admin.html">9.27. System Administration Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-SET">9.27.1. Configuration Settings Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL">9.27.2. Server Signaling Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP">9.27.3. Backup Control Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL">9.27.4. Recovery Control Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION">9.27.5. Snapshot Synchronization Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-REPLICATION">9.27.6. Replication Management Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-DBOBJECT">9.27.7. Database Object Management Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-INDEX">9.27.8. Index Maintenance Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE">9.27.9. Generic File Access Functions</a></span></dt><dt><span class="sect2"><a href="functions-admin.html#FUNCTIONS-ADVISORY-LOCKS">9.27.10. Advisory Lock Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-trigger.html">9.28. Trigger Functions</a></span></dt><dt><span class="sect1"><a href="functions-event-triggers.html">9.29. Event Trigger Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-event-triggers.html#PG-EVENT-TRIGGER-DDL-COMMAND-END-FUNCTIONS">9.29.1. Capturing Changes at Command End</a></span></dt><dt><span class="sect2"><a href="functions-event-triggers.html#PG-EVENT-TRIGGER-SQL-DROP-FUNCTIONS">9.29.2. Processing Objects Dropped by a DDL Command</a></span></dt><dt><span class="sect2"><a href="functions-event-triggers.html#PG-EVENT-TRIGGER-TABLE-REWRITE-FUNCTIONS">9.29.3. Handling a Table Rewrite Event</a></span></dt></dl></dd><dt><span class="sect1"><a href="functions-statistics.html">9.30. Statistics Information Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="functions-statistics.html#FUNCTIONS-STATISTICS-MCV">9.30.1. Inspecting MCV Lists</a></span></dt></dl></dd></dl></div><a id="id-1.5.8.2" class="indexterm"></a><a id="id-1.5.8.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a large number of
+ functions and operators for the built-in data types. This chapter
+ describes most of them, although additional special-purpose functions
+ appear in relevant sections of the manual. Users can also
+ define their own functions and operators, as described in
+ <a class="xref" href="server-programming.html" title="Part V. Server Programming">Part V</a>. The
+ <span class="application">psql</span> commands <code class="command">\df</code> and
+ <code class="command">\do</code> can be used to list all
+ available functions and operators, respectively.
+ </p><p>
+ The notation used throughout this chapter to describe the argument and
+ result data types of a function or operator is like this:
+</p><pre class="synopsis">
+<code class="function">repeat</code> ( <code class="type">text</code>, <code class="type">integer</code> ) → <code class="returnvalue">text</code>
+</pre><p>
+ which says that the function <code class="function">repeat</code> takes one text and
+ one integer argument and returns a result of type text. The right arrow
+ is also used to indicate the result of an example, thus:
+</p><pre class="programlisting">
+repeat('Pg', 4) → <code class="returnvalue">PgPgPgPg</code>
+</pre><p>
+ </p><p>
+ If you are concerned about portability then note that most of
+ the functions and operators described in this chapter, with the
+ exception of the most trivial arithmetic and comparison operators
+ and some explicitly marked functions, are not specified by the
+ <acronym class="acronym">SQL</acronym> standard. Some of this extended functionality
+ is present in other <acronym class="acronym">SQL</acronym> database management
+ systems, and in many cases this functionality is compatible and
+ consistent between the various implementations.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datatype-pseudo.html" title="8.21. Pseudo-Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="functions-logical.html" title="9.1. Logical Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.21. Pseudo-Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 9.1. Logical Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/fuzzystrmatch.html b/doc/src/sgml/html/fuzzystrmatch.html
new file mode 100644
index 0000000..3de5f85
--- /dev/null
+++ b/doc/src/sgml/html/fuzzystrmatch.html
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.17. fuzzystrmatch</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="file-fdw.html" title="F.16. file_fdw" /><link rel="next" href="hstore.html" title="F.18. hstore" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.17. fuzzystrmatch</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="file-fdw.html" title="F.16. file_fdw">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="hstore.html" title="F.18. hstore">Next</a></td></tr></table><hr /></div><div class="sect1" id="FUZZYSTRMATCH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.17. fuzzystrmatch</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.6">F.17.1. Soundex</a></span></dt><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.7">F.17.2. Levenshtein</a></span></dt><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.8">F.17.3. Metaphone</a></span></dt><dt><span class="sect2"><a href="fuzzystrmatch.html#id-1.11.7.26.9">F.17.4. Double Metaphone</a></span></dt></dl></div><a id="id-1.11.7.26.2" class="indexterm"></a><p>
+ The <code class="filename">fuzzystrmatch</code> module provides several
+ functions to determine similarities and distance between strings.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ At present, the <code class="function">soundex</code>, <code class="function">metaphone</code>,
+ <code class="function">dmetaphone</code>, and <code class="function">dmetaphone_alt</code> functions do
+ not work well with multibyte encodings (such as UTF-8).
+ </p></div><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.26.6"><div class="titlepage"><div><div><h3 class="title">F.17.1. Soundex</h3></div></div></div><p>
+ The Soundex system is a method of matching similar-sounding names
+ by converting them to the same code. It was initially used by the
+ United States Census in 1880, 1900, and 1910. Note that Soundex
+ is not very useful for non-English names.
+ </p><p>
+ The <code class="filename">fuzzystrmatch</code> module provides two functions
+ for working with Soundex codes:
+ </p><a id="id-1.11.7.26.6.4" class="indexterm"></a><a id="id-1.11.7.26.6.5" class="indexterm"></a><pre class="synopsis">
+soundex(text) returns text
+difference(text, text) returns int
+</pre><p>
+ The <code class="function">soundex</code> function converts a string to its Soundex code.
+ The <code class="function">difference</code> function converts two strings to their Soundex
+ codes and then reports the number of matching code positions. Since
+ Soundex codes have four characters, the result ranges from zero to four,
+ with zero being no match and four being an exact match. (Thus, the
+ function is misnamed — <code class="function">similarity</code> would have been
+ a better name.)
+ </p><p>
+ Here are some usage examples:
+ </p><pre class="programlisting">
+SELECT soundex('hello world!');
+
+SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann');
+SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew');
+SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret');
+
+CREATE TABLE s (nm text);
+
+INSERT INTO s VALUES ('john');
+INSERT INTO s VALUES ('joan');
+INSERT INTO s VALUES ('wobbly');
+INSERT INTO s VALUES ('jack');
+
+SELECT * FROM s WHERE soundex(nm) = soundex('john');
+
+SELECT * FROM s WHERE difference(s.nm, 'john') &gt; 2;
+</pre></div><div class="sect2" id="id-1.11.7.26.7"><div class="titlepage"><div><div><h3 class="title">F.17.2. Levenshtein</h3></div></div></div><p>
+ This function calculates the Levenshtein distance between two strings:
+ </p><a id="id-1.11.7.26.7.3" class="indexterm"></a><a id="id-1.11.7.26.7.4" class="indexterm"></a><pre class="synopsis">
+levenshtein(text source, text target, int ins_cost, int del_cost, int sub_cost) returns int
+levenshtein(text source, text target) returns int
+levenshtein_less_equal(text source, text target, int ins_cost, int del_cost, int sub_cost, int max_d) returns int
+levenshtein_less_equal(text source, text target, int max_d) returns int
+</pre><p>
+ Both <code class="literal">source</code> and <code class="literal">target</code> can be any
+ non-null string, with a maximum of 255 characters. The cost parameters
+ specify how much to charge for a character insertion, deletion, or
+ substitution, respectively. You can omit the cost parameters, as in
+ the second version of the function; in that case they all default to 1.
+ </p><p>
+ <code class="function">levenshtein_less_equal</code> is an accelerated version of the
+ Levenshtein function for use when only small distances are of interest.
+ If the actual distance is less than or equal to <code class="literal">max_d</code>,
+ then <code class="function">levenshtein_less_equal</code> returns the correct
+ distance; otherwise it returns some value greater than <code class="literal">max_d</code>.
+ If <code class="literal">max_d</code> is negative then the behavior is the same as
+ <code class="function">levenshtein</code>.
+ </p><p>
+ Examples:
+ </p><pre class="screen">
+test=# SELECT levenshtein('GUMBO', 'GAMBOL');
+ levenshtein
+-------------
+ 2
+(1 row)
+
+test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1);
+ levenshtein
+-------------
+ 3
+(1 row)
+
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 2);
+ levenshtein_less_equal
+------------------------
+ 3
+(1 row)
+
+test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 4);
+ levenshtein_less_equal
+------------------------
+ 4
+(1 row)
+</pre></div><div class="sect2" id="id-1.11.7.26.8"><div class="titlepage"><div><div><h3 class="title">F.17.3. Metaphone</h3></div></div></div><p>
+ Metaphone, like Soundex, is based on the idea of constructing a
+ representative code for an input string. Two strings are then
+ deemed similar if they have the same codes.
+ </p><p>
+ This function calculates the metaphone code of an input string:
+ </p><a id="id-1.11.7.26.8.4" class="indexterm"></a><pre class="synopsis">
+metaphone(text source, int max_output_length) returns text
+</pre><p>
+ <code class="literal">source</code> has to be a non-null string with a maximum of
+ 255 characters. <code class="literal">max_output_length</code> sets the maximum
+ length of the output metaphone code; if longer, the output is truncated
+ to this length.
+ </p><p>
+ Example:
+ </p><pre class="screen">
+test=# SELECT metaphone('GUMBO', 4);
+ metaphone
+-----------
+ KM
+(1 row)
+</pre></div><div class="sect2" id="id-1.11.7.26.9"><div class="titlepage"><div><div><h3 class="title">F.17.4. Double Metaphone</h3></div></div></div><p>
+ The Double Metaphone system computes two <span class="quote">“<span class="quote">sounds like</span>”</span> strings
+ for a given input string — a <span class="quote">“<span class="quote">primary</span>”</span> and an
+ <span class="quote">“<span class="quote">alternate</span>”</span>. In most cases they are the same, but for non-English
+ names especially they can be a bit different, depending on pronunciation.
+ These functions compute the primary and alternate codes:
+ </p><a id="id-1.11.7.26.9.3" class="indexterm"></a><a id="id-1.11.7.26.9.4" class="indexterm"></a><pre class="synopsis">
+dmetaphone(text source) returns text
+dmetaphone_alt(text source) returns text
+</pre><p>
+ There is no length limit on the input strings.
+ </p><p>
+ Example:
+ </p><pre class="screen">
+test=# SELECT dmetaphone('gumbo');
+ dmetaphone
+------------
+ KMP
+(1 row)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="file-fdw.html" title="F.16. file_fdw">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="hstore.html" title="F.18. hstore">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.16. file_fdw </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.18. hstore</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/generic-wal.html b/doc/src/sgml/html/generic-wal.html
new file mode 100644
index 0000000..45a15c1
--- /dev/null
+++ b/doc/src/sgml/html/generic-wal.html
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 65. Generic WAL Records</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions" /><link rel="next" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 65. Generic WAL Records</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers">Next</a></td></tr></table><hr /></div><div class="chapter" id="GENERIC-WAL"><div class="titlepage"><div><div><h2 class="title">Chapter 65. Generic WAL Records</h2></div></div></div><p>
+ Although all built-in WAL-logged modules have their own types of WAL
+ records, there is also a generic WAL record type, which describes changes
+ to pages in a generic way. This is useful for extensions that provide
+ custom access methods.
+ </p><p>
+ In comparison with <a class="link" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers">Custom WAL Resource
+ Managers</a>, Generic WAL is simpler for an extension to implement and
+ does not require the extension library to be loaded in order to apply the
+ records.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Generic WAL records are ignored during <a class="link" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Logical Decoding</a>. If logical decoding is
+ required for your extension, consider a Custom WAL Resource Manager.
+ </p></div><p>
+ The API for constructing generic WAL records is defined in
+ <code class="filename">access/generic_xlog.h</code> and implemented
+ in <code class="filename">access/transam/generic_xlog.c</code>.
+ </p><p>
+ To perform a WAL-logged data update using the generic WAL record
+ facility, follow these steps:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ <code class="function">state = GenericXLogStart(relation)</code> — start
+ construction of a generic WAL record for the given relation.
+ </p></li><li class="listitem"><p>
+ <code class="function">page = GenericXLogRegisterBuffer(state, buffer, flags)</code>
+ — register a buffer to be modified within the current generic WAL
+ record. This function returns a pointer to a temporary copy of the
+ buffer's page, where modifications should be made. (Do not modify the
+ buffer's contents directly.) The third argument is a bit mask of flags
+ applicable to the operation. Currently the only such flag is
+ <code class="literal">GENERIC_XLOG_FULL_IMAGE</code>, which indicates that a full-page
+ image rather than a delta update should be included in the WAL record.
+ Typically this flag would be set if the page is new or has been
+ rewritten completely.
+ <code class="function">GenericXLogRegisterBuffer</code> can be repeated if the
+ WAL-logged action needs to modify multiple pages.
+ </p></li><li class="listitem"><p>
+ Apply modifications to the page images obtained in the previous step.
+ </p></li><li class="listitem"><p>
+ <code class="function">GenericXLogFinish(state)</code> — apply the changes to
+ the buffers and emit the generic WAL record.
+ </p></li></ol></div><p>
+ </p><p>
+ WAL record construction can be canceled between any of the above steps by
+ calling <code class="function">GenericXLogAbort(state)</code>. This will discard all
+ changes to the page image copies.
+ </p><p>
+ Please note the following points when using the generic WAL record
+ facility:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ No direct modifications of buffers are allowed! All modifications must
+ be done in copies acquired from <code class="function">GenericXLogRegisterBuffer()</code>.
+ In other words, code that makes generic WAL records should never call
+ <code class="function">BufferGetPage()</code> for itself. However, it remains the
+ caller's responsibility to pin/unpin and lock/unlock the buffers at
+ appropriate times. Exclusive lock must be held on each target buffer
+ from before <code class="function">GenericXLogRegisterBuffer()</code> until after
+ <code class="function">GenericXLogFinish()</code>.
+ </p></li><li class="listitem"><p>
+ Registrations of buffers (step 2) and modifications of page images
+ (step 3) can be mixed freely, i.e., both steps may be repeated in any
+ sequence. Keep in mind that buffers should be registered in the same
+ order in which locks are to be obtained on them during replay.
+ </p></li><li class="listitem"><p>
+ The maximum number of buffers that can be registered for a generic WAL
+ record is <code class="literal">MAX_GENERIC_XLOG_PAGES</code>. An error will be thrown
+ if this limit is exceeded.
+ </p></li><li class="listitem"><p>
+ Generic WAL assumes that the pages to be modified have standard
+ layout, and in particular that there is no useful data between
+ <code class="structfield">pd_lower</code> and <code class="structfield">pd_upper</code>.
+ </p></li><li class="listitem"><p>
+ Since you are modifying copies of buffer
+ pages, <code class="function">GenericXLogStart()</code> does not start a critical
+ section. Thus, you can safely do memory allocation, error throwing,
+ etc. between <code class="function">GenericXLogStart()</code> and
+ <code class="function">GenericXLogFinish()</code>. The only actual critical section is
+ present inside <code class="function">GenericXLogFinish()</code>. There is no need to
+ worry about calling <code class="function">GenericXLogAbort()</code> during an error
+ exit, either.
+ </p></li><li class="listitem"><p>
+ <code class="function">GenericXLogFinish()</code> takes care of marking buffers dirty
+ and setting their LSNs. You do not need to do this explicitly.
+ </p></li><li class="listitem"><p>
+ For unlogged relations, everything works the same except that no
+ actual WAL record is emitted. Thus, you typically do not need to do
+ any explicit checks for unlogged relations.
+ </p></li><li class="listitem"><p>
+ The generic WAL redo function will acquire exclusive locks to buffers
+ in the same order as they were registered. After redoing all changes,
+ the locks will be released in the same order.
+ </p></li><li class="listitem"><p>
+ If <code class="literal">GENERIC_XLOG_FULL_IMAGE</code> is not specified for a
+ registered buffer, the generic WAL record contains a delta between
+ the old and the new page images. This delta is based on byte-by-byte
+ comparison. This is not very compact for the case of moving data
+ within a page, and might be improved in the future.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">64.6. Index Cost Estimation Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 66. Custom WAL Resource Managers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/genetic-algorithm.svg b/doc/src/sgml/html/genetic-algorithm.svg
new file mode 100644
index 0000000..fb9fdd1
--- /dev/null
+++ b/doc/src/sgml/html/genetic-algorithm.svg
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: %3 Pages: 1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="583pt" height="580pt" viewBox="0.00 0.00 583.00 580.30">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(72 544.3026)">
+<title>%3</title>
+<polygon fill="#f5f5f5" stroke="none" points="-72,36 -72,-544.3026 511,-544.3026 511,36 -72,36"/>
+<!-- a1 -->
+<g id="node1" class="node">
+<title>a1</title>
+<polygon fill="#ffffff" stroke="#000000" points="187,-508.3026 101,-508.3026 101,-472.3026 187,-472.3026 187,-508.3026"/>
+<text text-anchor="middle" x="144" y="-488.4026" font-family="sans-serif" font-size="8.00" fill="#000000">INITIALIZE t := 0</text>
+</g>
+<!-- a2 -->
+<g id="node2" class="node">
+<title>a2</title>
+<polygon fill="#ffffff" stroke="#000000" points="182,-450.3026 106,-450.3026 106,-414.3026 182,-414.3026 182,-450.3026"/>
+<text text-anchor="middle" x="144" y="-430.4026" font-family="sans-serif" font-size="8.00" fill="#000000">INITIALIZE P(t)</text>
+</g>
+<!-- a1&#45;&gt;a2 -->
+<g id="edge1" class="edge">
+<title>a1-&gt;a2</title>
+<path fill="none" stroke="#000000" d="M144,-472.269C144,-472.269 144,-460.5248 144,-460.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-460.5248 144,-450.5248 140.5001,-460.5249 147.5001,-460.5248"/>
+</g>
+<!-- a3 -->
+<g id="node3" class="node">
+<title>a3</title>
+<polygon fill="#ffffff" stroke="#000000" points="203.5,-392.3026 84.5,-392.3026 84.5,-356.3026 203.5,-356.3026 203.5,-392.3026"/>
+<text text-anchor="middle" x="144" y="-372.4026" font-family="sans-serif" font-size="8.00" fill="#000000">evaluate FITNESS of P(t)</text>
+</g>
+<!-- a2&#45;&gt;a3 -->
+<g id="edge2" class="edge">
+<title>a2-&gt;a3</title>
+<path fill="none" stroke="#000000" d="M144,-414.269C144,-414.269 144,-402.5248 144,-402.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-402.5248 144,-392.5248 140.5001,-402.5249 147.5001,-402.5248"/>
+</g>
+<!-- a4 -->
+<g id="node4" class="node">
+<title>a4</title>
+<polygon fill="#ffffff" stroke="#000000" points="144,-334.3026 0,-316.3026 144,-298.3026 288,-316.3026 144,-334.3026"/>
+<text text-anchor="middle" x="144" y="-314.4026" font-family="sans-serif" font-size="8.00" fill="#000000">STOPPING CRITERION</text>
+</g>
+<!-- a3&#45;&gt;a4 -->
+<g id="edge3" class="edge">
+<title>a3-&gt;a4</title>
+<path fill="none" stroke="#000000" d="M144,-356.269C144,-356.269 144,-344.5248 144,-344.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-344.5248 144,-334.5248 140.5001,-344.5249 147.5001,-344.5248"/>
+</g>
+<!-- a9 -->
+<g id="node5" class="node">
+<title>a9</title>
+<polygon fill="#ffffff" stroke="#000000" points="106,-40.1513 50,-40.1513 50,-4.1513 106,-4.1513 106,-40.1513"/>
+<text text-anchor="middle" x="78" y="-20.2513" font-family="sans-serif" font-size="8.00" fill="#000000">t := t + 1</text>
+</g>
+<!-- a4&#45;&gt;a9 -->
+<g id="edge10" class="edge">
+<title>a4-&gt;a9</title>
+<path fill="none" stroke="#000000" d="M56.75,-299.0314C56.75,-299.0314 56.75,-40.524 56.75,-40.524"/>
+<polygon fill="#000000" stroke="#000000" points="53.2501,-299.0314 56.75,-309.0314 60.2501,-299.0314 53.2501,-299.0314"/>
+</g>
+<!-- end -->
+<g id="node6" class="node">
+<title>end</title>
+<ellipse fill="#ffffff" stroke="#000000" cx="259" cy="-22.1513" rx="18.2761" ry="18.2761"/>
+<ellipse fill="none" stroke="#000000" cx="259" cy="-22.1513" rx="22.3036" ry="22.3036"/>
+<text text-anchor="middle" x="259" y="-20.2513" font-family="sans-serif" font-size="8.00" fill="#000000">end</text>
+</g>
+<!-- a4&#45;&gt;end -->
+<g id="edge5" class="edge">
+<title>a4-&gt;end</title>
+<path fill="none" stroke="#000000" d="M259,-312.5834C259,-312.5834 259,-54.659 259,-54.659"/>
+<polygon fill="#000000" stroke="#000000" points="262.5001,-54.659 259,-44.659 255.5001,-54.6591 262.5001,-54.659"/>
+<text text-anchor="middle" x="246" y="-186.6212" font-family="sans-serif" font-size="10.00" fill="#000000">true  </text>
+</g>
+<!-- a5 -->
+<g id="node7" class="node">
+<title>a5</title>
+<polygon fill="#ffffff" stroke="#000000" points="216,-276.3026 72,-276.3026 72,-240.3026 216,-240.3026 216,-276.3026"/>
+<text text-anchor="middle" x="144" y="-256.4026" font-family="sans-serif" font-size="8.00" fill="#000000">P'(t) := RECOMBINATION{P(t)}</text>
+</g>
+<!-- a4&#45;&gt;a5 -->
+<g id="edge4" class="edge">
+<title>a4-&gt;a5</title>
+<path fill="none" stroke="#000000" d="M144,-298.269C144,-298.269 144,-286.5248 144,-286.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-286.5248 144,-276.5248 140.5001,-286.5249 147.5001,-286.5248"/>
+<text text-anchor="middle" x="127" y="-284.3969" font-family="sans-serif" font-size="10.00" fill="#000000">false   </text>
+</g>
+<!-- a6 -->
+<g id="node8" class="node">
+<title>a6</title>
+<polygon fill="#ffffff" stroke="#000000" points="204.5,-218.3026 83.5,-218.3026 83.5,-182.3026 204.5,-182.3026 204.5,-218.3026"/>
+<text text-anchor="middle" x="144" y="-198.4026" font-family="sans-serif" font-size="8.00" fill="#000000">P''(t) := MUTATION{P'(t)}</text>
+</g>
+<!-- a5&#45;&gt;a6 -->
+<g id="edge6" class="edge">
+<title>a5-&gt;a6</title>
+<path fill="none" stroke="#000000" d="M144,-240.269C144,-240.269 144,-228.5248 144,-228.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-228.5248 144,-218.5248 140.5001,-228.5249 147.5001,-228.5248"/>
+</g>
+<!-- a7 -->
+<g id="node9" class="node">
+<title>a7</title>
+<polygon fill="#ffffff" stroke="#000000" points="224.5,-160.3026 63.5,-160.3026 63.5,-124.3026 224.5,-124.3026 224.5,-160.3026"/>
+<text text-anchor="middle" x="144" y="-140.4026" font-family="sans-serif" font-size="8.00" fill="#000000">P(t+1) := SELECTION{P''(t) + P(t)}</text>
+</g>
+<!-- a6&#45;&gt;a7 -->
+<g id="edge7" class="edge">
+<title>a6-&gt;a7</title>
+<path fill="none" stroke="#000000" d="M144,-182.269C144,-182.269 144,-170.5248 144,-170.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-170.5248 144,-160.5248 140.5001,-170.5249 147.5001,-170.5248"/>
+</g>
+<!-- a8 -->
+<g id="node10" class="node">
+<title>a8</title>
+<polygon fill="#ffffff" stroke="#000000" points="196.5,-102.3026 73.5,-102.3026 73.5,-66.3026 196.5,-66.3026 196.5,-102.3026"/>
+<text text-anchor="middle" x="135" y="-82.4026" font-family="sans-serif" font-size="8.00" fill="#000000">evaluate FITNESS of P''(t)</text>
+</g>
+<!-- a7&#45;&gt;a8 -->
+<g id="edge8" class="edge">
+<title>a7-&gt;a8</title>
+<path fill="none" stroke="#000000" d="M135,-124.269C135,-124.269 135,-112.5248 135,-112.5248"/>
+<polygon fill="#000000" stroke="#000000" points="138.5001,-112.5248 135,-102.5248 131.5001,-112.5249 138.5001,-112.5248"/>
+</g>
+<!-- a8&#45;&gt;a9 -->
+<g id="edge9" class="edge">
+<title>a8-&gt;a9</title>
+<path fill="none" stroke="#000000" d="M89.75,-65.9913C89.75,-65.9913 89.75,-50.5465 89.75,-50.5465"/>
+<polygon fill="#000000" stroke="#000000" points="93.2501,-50.5464 89.75,-40.5465 86.2501,-50.5465 93.2501,-50.5464"/>
+</g>
+<!-- expl -->
+<g id="node11" class="node">
+<title>expl</title>
+<polygon fill="#f5f5f5" stroke="none" points="439,-508.3026 209,-508.3026 209,-472.3026 439,-472.3026 439,-508.3026"/>
+<text text-anchor="start" x="217" y="-493.3026" font-family="sans-serif" font-size="10.00" fill="#000000">P(t): generation of ancestors at a time t</text>
+<text text-anchor="start" x="217" y="-482.3026" font-family="sans-serif" font-size="10.00" fill="#000000">P''(t): generation of descendants at a time t</text>
+</g>
+</g>
+</svg>
diff --git a/doc/src/sgml/html/geqo-biblio.html b/doc/src/sgml/html/geqo-biblio.html
new file mode 100644
index 0000000..aff7220
--- /dev/null
+++ b/doc/src/sgml/html/geqo-biblio.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>62.4. Further Reading</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="geqo-pg-intro.html" title="62.3. Genetic Query Optimization (GEQO) in PostgreSQL" /><link rel="next" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">62.4. Further Reading</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="geqo-pg-intro.html" title="62.3. Genetic Query Optimization (GEQO) in PostgreSQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><th width="60%" align="center">Chapter 62. Genetic Query Optimizer</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Next</a></td></tr></table><hr /></div><div class="sect1" id="GEQO-BIBLIO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">62.4. Further Reading</h2></div></div></div><p>
+ The following resources contain additional information about
+ genetic algorithms:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="ulink" href="http://www.faqs.org/faqs/ai-faq/genetic/part1/" target="_top">
+ The Hitch-Hiker's Guide to Evolutionary Computation</a>, (FAQ for <a class="ulink" href="news://comp.ai.genetic" target="_top">news://comp.ai.genetic</a>)
+ </p></li><li class="listitem"><p>
+ <a class="ulink" href="https://www.red3d.com/cwr/evolve.html" target="_top">
+ Evolutionary Computation and its application to art and design</a>, by
+ Craig Reynolds
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="biblio.html#ELMA04" title="Fundamentals of Database Systems">[elma04]</a>
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="biblio.html#FONG" title="The design and implementation of the POSTGRES query optimizer">[fong]</a>
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="geqo-pg-intro.html" title="62.3. Genetic Query Optimization (GEQO) in PostgreSQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Next</a></td></tr><tr><td width="40%" align="left" valign="top">62.3. Genetic Query Optimization (<acronym class="acronym">GEQO</acronym>) in PostgreSQL </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 63. Table Access Method Interface Definition</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/geqo-intro.html b/doc/src/sgml/html/geqo-intro.html
new file mode 100644
index 0000000..65601c0
--- /dev/null
+++ b/doc/src/sgml/html/geqo-intro.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>62.1. Query Handling as a Complex Optimization Problem</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="geqo.html" title="Chapter 62. Genetic Query Optimizer" /><link rel="next" href="geqo-intro2.html" title="62.2. Genetic Algorithms" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">62.1. Query Handling as a Complex Optimization Problem</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><th width="60%" align="center">Chapter 62. Genetic Query Optimizer</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="geqo-intro2.html" title="62.2. Genetic Algorithms">Next</a></td></tr></table><hr /></div><div class="sect1" id="GEQO-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">62.1. Query Handling as a Complex Optimization Problem</h2></div></div></div><p>
+ Among all relational operators the most difficult one to process
+ and optimize is the <em class="firstterm">join</em>. The number of
+ possible query plans grows exponentially with the
+ number of joins in the query. Further optimization effort is
+ caused by the support of a variety of <em class="firstterm">join
+ methods</em> (e.g., nested loop, hash join, merge join in
+ <span class="productname">PostgreSQL</span>) to process individual joins
+ and a diversity of <em class="firstterm">indexes</em> (e.g.,
+ B-tree, hash, GiST and GIN in <span class="productname">PostgreSQL</span>) as
+ access paths for relations.
+ </p><p>
+ The normal <span class="productname">PostgreSQL</span> query optimizer
+ performs a <em class="firstterm">near-exhaustive search</em> over the
+ space of alternative strategies. This algorithm, first introduced
+ in IBM's System R database, produces a near-optimal join order,
+ but can take an enormous amount of time and memory space when the
+ number of joins in the query grows large. This makes the ordinary
+ <span class="productname">PostgreSQL</span> query optimizer
+ inappropriate for queries that join a large number of tables.
+ </p><p>
+ The Institute of Automatic Control at the University of Mining and
+ Technology, in Freiberg, Germany, encountered some problems when
+ it wanted to use <span class="productname">PostgreSQL</span> as the
+ backend for a decision support knowledge based system for the
+ maintenance of an electrical power grid. The DBMS needed to handle
+ large join queries for the inference machine of the knowledge
+ based system. The number of joins in these queries made using the
+ normal query optimizer infeasible.
+ </p><p>
+ In the following we describe the implementation of a
+ <em class="firstterm">genetic algorithm</em> to solve the join
+ ordering problem in a manner that is efficient for queries
+ involving large numbers of joins.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="geqo-intro2.html" title="62.2. Genetic Algorithms">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 62. Genetic Query Optimizer </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 62.2. Genetic Algorithms</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/geqo-intro2.html b/doc/src/sgml/html/geqo-intro2.html
new file mode 100644
index 0000000..b160ce1
--- /dev/null
+++ b/doc/src/sgml/html/geqo-intro2.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>62.2. Genetic Algorithms</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="geqo-intro.html" title="62.1. Query Handling as a Complex Optimization Problem" /><link rel="next" href="geqo-pg-intro.html" title="62.3. Genetic Query Optimization (GEQO) in PostgreSQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">62.2. Genetic Algorithms</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="geqo-intro.html" title="62.1. Query Handling as a Complex Optimization Problem">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><th width="60%" align="center">Chapter 62. Genetic Query Optimizer</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="geqo-pg-intro.html" title="62.3. Genetic Query Optimization (GEQO) in PostgreSQL">Next</a></td></tr></table><hr /></div><div class="sect1" id="GEQO-INTRO2"><div class="titlepage"><div><div><h2 class="title" style="clear: both">62.2. Genetic Algorithms</h2></div></div></div><p>
+ The genetic algorithm (<acronym class="acronym">GA</acronym>) is a heuristic optimization method which
+ operates through randomized search. The set of possible solutions for the
+ optimization problem is considered as a
+ <em class="firstterm">population</em> of <em class="firstterm">individuals</em>.
+ The degree of adaptation of an individual to its environment is specified
+ by its <em class="firstterm">fitness</em>.
+ </p><p>
+ The coordinates of an individual in the search space are represented
+ by <em class="firstterm">chromosomes</em>, in essence a set of character
+ strings. A <em class="firstterm">gene</em> is a
+ subsection of a chromosome which encodes the value of a single parameter
+ being optimized. Typical encodings for a gene could be <em class="firstterm">binary</em> or
+ <em class="firstterm">integer</em>.
+ </p><p>
+ Through simulation of the evolutionary operations <em class="firstterm">recombination</em>,
+ <em class="firstterm">mutation</em>, and
+ <em class="firstterm">selection</em> new generations of search points are found
+ that show a higher average fitness than their ancestors. <a class="xref" href="geqo-intro2.html#GEQO-FIGURE" title="Figure 62.1. Structure of a Genetic Algorithm">Figure 62.1</a>
+ illustrates these steps.
+ </p><div class="figure" id="GEQO-FIGURE"><p class="title"><strong>Figure 62.1. Structure of a Genetic Algorithm</strong></p><div class="figure-contents"><div class="mediaobject"><object type="image/svg+xml" data="genetic-algorithm.svg" width="100%"></object></div></div></div><br class="figure-break" /><p>
+ According to the <span class="systemitem">comp.ai.genetic</span> <acronym class="acronym">FAQ</acronym> it cannot be stressed too
+ strongly that a <acronym class="acronym">GA</acronym> is not a pure random search for a solution to a
+ problem. A <acronym class="acronym">GA</acronym> uses stochastic processes, but the result is distinctly
+ non-random (better than random).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="geqo-intro.html" title="62.1. Query Handling as a Complex Optimization Problem">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="geqo-pg-intro.html" title="62.3. Genetic Query Optimization (GEQO) in PostgreSQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">62.1. Query Handling as a Complex Optimization Problem </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 62.3. Genetic Query Optimization (<acronym class="acronym">GEQO</acronym>) in PostgreSQL</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/geqo-pg-intro.html b/doc/src/sgml/html/geqo-pg-intro.html
new file mode 100644
index 0000000..bb2af6f
--- /dev/null
+++ b/doc/src/sgml/html/geqo-pg-intro.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>62.3. Genetic Query Optimization (GEQO) in PostgreSQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="geqo-intro2.html" title="62.2. Genetic Algorithms" /><link rel="next" href="geqo-biblio.html" title="62.4. Further Reading" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">62.3. Genetic Query Optimization (<acronym class="acronym">GEQO</acronym>) in PostgreSQL</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="geqo-intro2.html" title="62.2. Genetic Algorithms">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><th width="60%" align="center">Chapter 62. Genetic Query Optimizer</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="geqo-biblio.html" title="62.4. Further Reading">Next</a></td></tr></table><hr /></div><div class="sect1" id="GEQO-PG-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">62.3. Genetic Query Optimization (<acronym class="acronym">GEQO</acronym>) in PostgreSQL</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="geqo-pg-intro.html#id-1.10.13.5.6">62.3.1. Generating Possible Plans with <acronym class="acronym">GEQO</acronym></a></span></dt><dt><span class="sect2"><a href="geqo-pg-intro.html#GEQO-FUTURE">62.3.2. Future Implementation Tasks for
+ <span class="productname">PostgreSQL</span> <acronym class="acronym">GEQO</acronym></a></span></dt></dl></div><p>
+ The <acronym class="acronym">GEQO</acronym> module approaches the query
+ optimization problem as though it were the well-known traveling salesman
+ problem (<acronym class="acronym">TSP</acronym>).
+ Possible query plans are encoded as integer strings. Each string
+ represents the join order from one relation of the query to the next.
+ For example, the join tree
+</p><pre class="literallayout">
+ /\
+ /\ 2
+ /\ 3
+4 1
+</pre><p>
+ is encoded by the integer string '4-1-3-2',
+ which means, first join relation '4' and '1', then '3', and
+ then '2', where 1, 2, 3, 4 are relation IDs within the
+ <span class="productname">PostgreSQL</span> optimizer.
+ </p><p>
+ Specific characteristics of the <acronym class="acronym">GEQO</acronym>
+ implementation in <span class="productname">PostgreSQL</span>
+ are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ Usage of a <em class="firstterm">steady state</em> <acronym class="acronym">GA</acronym> (replacement of the least fit
+ individuals in a population, not whole-generational replacement)
+ allows fast convergence towards improved query plans. This is
+ essential for query handling with reasonable time;
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Usage of <em class="firstterm">edge recombination crossover</em>
+ which is especially suited to keep edge losses low for the
+ solution of the <acronym class="acronym">TSP</acronym> by means of a
+ <acronym class="acronym">GA</acronym>;
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Mutation as genetic operator is deprecated so that no repair
+ mechanisms are needed to generate legal <acronym class="acronym">TSP</acronym> tours.
+ </p></li></ul></div><p>
+ </p><p>
+ Parts of the <acronym class="acronym">GEQO</acronym> module are adapted from D. Whitley's
+ Genitor algorithm.
+ </p><p>
+ The <acronym class="acronym">GEQO</acronym> module allows
+ the <span class="productname">PostgreSQL</span> query optimizer to
+ support large join queries effectively through
+ non-exhaustive search.
+ </p><div class="sect2" id="id-1.10.13.5.6"><div class="titlepage"><div><div><h3 class="title">62.3.1. Generating Possible Plans with <acronym class="acronym">GEQO</acronym></h3></div></div></div><p>
+ The <acronym class="acronym">GEQO</acronym> planning process uses the standard planner
+ code to generate plans for scans of individual relations. Then join
+ plans are developed using the genetic approach. As shown above, each
+ candidate join plan is represented by a sequence in which to join
+ the base relations. In the initial stage, the <acronym class="acronym">GEQO</acronym>
+ code simply generates some possible join sequences at random. For each
+ join sequence considered, the standard planner code is invoked to
+ estimate the cost of performing the query using that join sequence.
+ (For each step of the join sequence, all three possible join strategies
+ are considered; and all the initially-determined relation scan plans
+ are available. The estimated cost is the cheapest of these
+ possibilities.) Join sequences with lower estimated cost are considered
+ <span class="quote">“<span class="quote">more fit</span>”</span> than those with higher cost. The genetic algorithm
+ discards the least fit candidates. Then new candidates are generated
+ by combining genes of more-fit candidates — that is, by using
+ randomly-chosen portions of known low-cost join sequences to create
+ new sequences for consideration. This process is repeated until a
+ preset number of join sequences have been considered; then the best
+ one found at any time during the search is used to generate the finished
+ plan.
+ </p><p>
+ This process is inherently nondeterministic, because of the randomized
+ choices made during both the initial population selection and subsequent
+ <span class="quote">“<span class="quote">mutation</span>”</span> of the best candidates. To avoid surprising changes
+ of the selected plan, each run of the GEQO algorithm restarts its
+ random number generator with the current <a class="xref" href="runtime-config-query.html#GUC-GEQO-SEED">geqo_seed</a>
+ parameter setting. As long as <code class="varname">geqo_seed</code> and the other
+ GEQO parameters are kept fixed, the same plan will be generated for a
+ given query (and other planner inputs such as statistics). To experiment
+ with different search paths, try changing <code class="varname">geqo_seed</code>.
+ </p></div><div class="sect2" id="GEQO-FUTURE"><div class="titlepage"><div><div><h3 class="title">62.3.2. Future Implementation Tasks for
+ <span class="productname">PostgreSQL</span> <acronym class="acronym">GEQO</acronym></h3></div></div></div><p>
+ Work is still needed to improve the genetic algorithm parameter
+ settings.
+ In file <code class="filename">src/backend/optimizer/geqo/geqo_main.c</code>,
+ routines
+ <code class="function">gimme_pool_size</code> and <code class="function">gimme_number_generations</code>,
+ we have to find a compromise for the parameter settings
+ to satisfy two competing demands:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>
+ Optimality of the query plan
+ </p></li><li class="listitem"><p>
+ Computing time
+ </p></li></ul></div><p>
+ </p><p>
+ In the current implementation, the fitness of each candidate join
+ sequence is estimated by running the standard planner's join selection
+ and cost estimation code from scratch. To the extent that different
+ candidates use similar sub-sequences of joins, a great deal of work
+ will be repeated. This could be made significantly faster by retaining
+ cost estimates for sub-joins. The problem is to avoid expending
+ unreasonable amounts of memory on retaining that state.
+ </p><p>
+ At a more basic level, it is not clear that solving query optimization
+ with a GA algorithm designed for TSP is appropriate. In the TSP case,
+ the cost associated with any substring (partial tour) is independent
+ of the rest of the tour, but this is certainly not true for query
+ optimization. Thus it is questionable whether edge recombination
+ crossover is the most effective mutation procedure.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="geqo-intro2.html" title="62.2. Genetic Algorithms">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="geqo-biblio.html" title="62.4. Further Reading">Next</a></td></tr><tr><td width="40%" align="left" valign="top">62.2. Genetic Algorithms </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 62.4. Further Reading</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/geqo.html b/doc/src/sgml/html/geqo.html
new file mode 100644
index 0000000..711d0f4
--- /dev/null
+++ b/doc/src/sgml/html/geqo.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 62. Genetic Query Optimizer</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="custom-scan-execution.html" title="61.3. Executing Custom Scans" /><link rel="next" href="geqo-intro.html" title="62.1. Query Handling as a Complex Optimization Problem" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 62. Genetic Query Optimizer</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="custom-scan-execution.html" title="61.3. Executing Custom Scans">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="geqo-intro.html" title="62.1. Query Handling as a Complex Optimization Problem">Next</a></td></tr></table><hr /></div><div class="chapter" id="GEQO"><div class="titlepage"><div><div><h2 class="title">Chapter 62. Genetic Query Optimizer</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="geqo-intro.html">62.1. Query Handling as a Complex Optimization Problem</a></span></dt><dt><span class="sect1"><a href="geqo-intro2.html">62.2. Genetic Algorithms</a></span></dt><dt><span class="sect1"><a href="geqo-pg-intro.html">62.3. Genetic Query Optimization (<acronym class="acronym">GEQO</acronym>) in PostgreSQL</a></span></dt><dd><dl><dt><span class="sect2"><a href="geqo-pg-intro.html#id-1.10.13.5.6">62.3.1. Generating Possible Plans with <acronym class="acronym">GEQO</acronym></a></span></dt><dt><span class="sect2"><a href="geqo-pg-intro.html#GEQO-FUTURE">62.3.2. Future Implementation Tasks for
+ <span class="productname">PostgreSQL</span> <acronym class="acronym">GEQO</acronym></a></span></dt></dl></dd><dt><span class="sect1"><a href="geqo-biblio.html">62.4. Further Reading</a></span></dt></dl></div><p>
+ </p><div class="note"><h3 class="title">Author</h3><p>
+ Written by Martin Utesch (<code class="email">&lt;<a class="email" href="mailto:utesch@aut.tu-freiberg.de">utesch@aut.tu-freiberg.de</a>&gt;</code>)
+ for the Institute of Automatic Control at the University of Mining and Technology in Freiberg, Germany.
+ </p></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="custom-scan-execution.html" title="61.3. Executing Custom Scans">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="geqo-intro.html" title="62.1. Query Handling as a Complex Optimization Problem">Next</a></td></tr><tr><td width="40%" align="left" valign="top">61.3. Executing Custom Scans </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 62.1. Query Handling as a Complex Optimization Problem</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-builtin-opclasses.html b/doc/src/sgml/html/gin-builtin-opclasses.html
new file mode 100644
index 0000000..6594e86
--- /dev/null
+++ b/doc/src/sgml/html/gin-builtin-opclasses.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.2. Built-in Operator Classes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-intro.html" title="70.1. Introduction" /><link rel="next" href="gin-extensibility.html" title="70.3. Extensibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.2. Built-in Operator Classes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-intro.html" title="70.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-extensibility.html" title="70.3. Extensibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-BUILTIN-OPCLASSES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.2. Built-in Operator Classes</h2></div></div></div><p>
+ The core <span class="productname">PostgreSQL</span> distribution
+ includes the <acronym class="acronym">GIN</acronym> operator classes shown in
+ <a class="xref" href="gin-builtin-opclasses.html#GIN-BUILTIN-OPCLASSES-TABLE" title="Table 70.1. Built-in GIN Operator Classes">Table 70.1</a>.
+ (Some of the optional modules described in <a class="xref" href="contrib.html" title="Appendix F. Additional Supplied Modules">Appendix F</a>
+ provide additional <acronym class="acronym">GIN</acronym> operator classes.)
+ </p><div class="table" id="GIN-BUILTIN-OPCLASSES-TABLE"><p class="title"><strong>Table 70.1. Built-in <acronym class="acronym">GIN</acronym> Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Built-in GIN Operator Classes" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Name</th><th>Indexable Operators</th></tr></thead><tbody><tr><td rowspan="4" valign="middle"><code class="literal">array_ops</code></td><td><code class="literal">&amp;&amp; (anyarray,anyarray)</code></td></tr><tr><td><code class="literal">@&gt; (anyarray,anyarray)</code></td></tr><tr><td><code class="literal">&lt;@ (anyarray,anyarray)</code></td></tr><tr><td><code class="literal">= (anyarray,anyarray)</code></td></tr><tr><td rowspan="6" valign="middle"><code class="literal">jsonb_ops</code></td><td><code class="literal">@&gt; (jsonb,jsonb)</code></td></tr><tr><td><code class="literal">@? (jsonb,jsonpath)</code></td></tr><tr><td><code class="literal">@@ (jsonb,jsonpath)</code></td></tr><tr><td><code class="literal">? (jsonb,text)</code></td></tr><tr><td><code class="literal">?| (jsonb,text[])</code></td></tr><tr><td><code class="literal">?&amp; (jsonb,text[])</code></td></tr><tr><td rowspan="3" valign="middle"><code class="literal">jsonb_path_ops</code></td><td><code class="literal">@&gt; (jsonb,jsonb)</code></td></tr><tr><td><code class="literal">@? (jsonb,jsonpath)</code></td></tr><tr><td><code class="literal">@@ (jsonb,jsonpath)</code></td></tr><tr><td rowspan="2" valign="middle"><code class="literal">tsvector_ops</code></td><td><code class="literal">@@ (tsvector,tsquery)</code></td></tr><tr><td><code class="literal">@@@ (tsvector,tsquery)</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Of the two operator classes for type <code class="type">jsonb</code>, <code class="literal">jsonb_ops</code>
+ is the default. <code class="literal">jsonb_path_ops</code> supports fewer operators but
+ offers better performance for those operators.
+ See <a class="xref" href="datatype-json.html#JSON-INDEXING" title="8.14.4. jsonb Indexing">Section 8.14.4</a> for details.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-intro.html" title="70.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-extensibility.html" title="70.3. Extensibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.3. Extensibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-examples.html b/doc/src/sgml/html/gin-examples.html
new file mode 100644
index 0000000..a24ee48
--- /dev/null
+++ b/doc/src/sgml/html/gin-examples.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.7. Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-limit.html" title="70.6. Limitations" /><link rel="next" href="brin.html" title="Chapter 71. BRIN Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.7. Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-limit.html" title="70.6. Limitations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="brin.html" title="Chapter 71. BRIN Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-EXAMPLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.7. Examples</h2></div></div></div><p>
+ The core <span class="productname">PostgreSQL</span> distribution
+ includes the <acronym class="acronym">GIN</acronym> operator classes previously shown in
+ <a class="xref" href="gin-builtin-opclasses.html#GIN-BUILTIN-OPCLASSES-TABLE" title="Table 70.1. Built-in GIN Operator Classes">Table 70.1</a>.
+ The following <code class="filename">contrib</code> modules also contain
+ <acronym class="acronym">GIN</acronym> operator classes:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="filename">btree_gin</code></span></dt><dd><p>B-tree equivalent functionality for several data types</p></dd><dt><span class="term"><code class="filename">hstore</code></span></dt><dd><p>Module for storing (key, value) pairs</p></dd><dt><span class="term"><code class="filename">intarray</code></span></dt><dd><p>Enhanced support for <code class="type">int[]</code></p></dd><dt><span class="term"><code class="filename">pg_trgm</code></span></dt><dd><p>Text similarity using trigram matching</p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-limit.html" title="70.6. Limitations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="brin.html" title="Chapter 71. BRIN Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.6. Limitations </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 71. BRIN Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-extensibility.html b/doc/src/sgml/html/gin-extensibility.html
new file mode 100644
index 0000000..623fc8b
--- /dev/null
+++ b/doc/src/sgml/html/gin-extensibility.html
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.3. Extensibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes" /><link rel="next" href="gin-implementation.html" title="70.4. Implementation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.3. Extensibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-implementation.html" title="70.4. Implementation">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-EXTENSIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.3. Extensibility</h2></div></div></div><p>
+ The <acronym class="acronym">GIN</acronym> interface has a high level of abstraction,
+ requiring the access method implementer only to implement the semantics of
+ the data type being accessed. The <acronym class="acronym">GIN</acronym> layer itself
+ takes care of concurrency, logging and searching the tree structure.
+ </p><p>
+ All it takes to get a <acronym class="acronym">GIN</acronym> access method working is to
+ implement a few user-defined methods, which define the behavior of
+ keys in the tree and the relationships between keys, indexed items,
+ and indexable queries. In short, <acronym class="acronym">GIN</acronym> combines
+ extensibility with generality, code reuse, and a clean interface.
+ </p><p>
+ There are two methods that an operator class for
+ <acronym class="acronym">GIN</acronym> must provide:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">Datum *extractValue(Datum itemValue, int32 *nkeys,
+ bool **nullFlags)</code></span></dt><dd><p>
+ Returns a palloc'd array of keys given an item to be indexed. The
+ number of returned keys must be stored into <code class="literal">*nkeys</code>.
+ If any of the keys can be null, also palloc an array of
+ <code class="literal">*nkeys</code> <code class="type">bool</code> fields, store its address at
+ <code class="literal">*nullFlags</code>, and set these null flags as needed.
+ <code class="literal">*nullFlags</code> can be left <code class="symbol">NULL</code> (its initial value)
+ if all keys are non-null.
+ The return value can be <code class="symbol">NULL</code> if the item contains no keys.
+ </p></dd><dt><span class="term"><code class="function">Datum *extractQuery(Datum query, int32 *nkeys,
+ StrategyNumber n, bool **pmatch, Pointer **extra_data,
+ bool **nullFlags, int32 *searchMode)</code></span></dt><dd><p>
+ Returns a palloc'd array of keys given a value to be queried; that is,
+ <code class="literal">query</code> is the value on the right-hand side of an
+ indexable operator whose left-hand side is the indexed column.
+ <code class="literal">n</code> is the strategy number of the operator within the
+ operator class (see <a class="xref" href="xindex.html#XINDEX-STRATEGIES" title="38.16.2. Index Method Strategies">Section 38.16.2</a>).
+ Often, <code class="function">extractQuery</code> will need
+ to consult <code class="literal">n</code> to determine the data type of
+ <code class="literal">query</code> and the method it should use to extract key values.
+ The number of returned keys must be stored into <code class="literal">*nkeys</code>.
+ If any of the keys can be null, also palloc an array of
+ <code class="literal">*nkeys</code> <code class="type">bool</code> fields, store its address at
+ <code class="literal">*nullFlags</code>, and set these null flags as needed.
+ <code class="literal">*nullFlags</code> can be left <code class="symbol">NULL</code> (its initial value)
+ if all keys are non-null.
+ The return value can be <code class="symbol">NULL</code> if the <code class="literal">query</code> contains no keys.
+ </p><p>
+ <code class="literal">searchMode</code> is an output argument that allows
+ <code class="function">extractQuery</code> to specify details about how the search
+ will be done.
+ If <code class="literal">*searchMode</code> is set to
+ <code class="literal">GIN_SEARCH_MODE_DEFAULT</code> (which is the value it is
+ initialized to before call), only items that match at least one of
+ the returned keys are considered candidate matches.
+ If <code class="literal">*searchMode</code> is set to
+ <code class="literal">GIN_SEARCH_MODE_INCLUDE_EMPTY</code>, then in addition to items
+ containing at least one matching key, items that contain no keys at
+ all are considered candidate matches. (This mode is useful for
+ implementing is-subset-of operators, for example.)
+ If <code class="literal">*searchMode</code> is set to <code class="literal">GIN_SEARCH_MODE_ALL</code>,
+ then all non-null items in the index are considered candidate
+ matches, whether they match any of the returned keys or not. (This
+ mode is much slower than the other two choices, since it requires
+ scanning essentially the entire index, but it may be necessary to
+ implement corner cases correctly. An operator that needs this mode
+ in most cases is probably not a good candidate for a GIN operator
+ class.)
+ The symbols to use for setting this mode are defined in
+ <code class="filename">access/gin.h</code>.
+ </p><p>
+ <code class="literal">pmatch</code> is an output argument for use when partial match
+ is supported. To use it, <code class="function">extractQuery</code> must allocate
+ an array of <code class="literal">*nkeys</code> <code class="type">bool</code>s and store its address at
+ <code class="literal">*pmatch</code>. Each element of the array should be set to true
+ if the corresponding key requires partial match, false if not.
+ If <code class="literal">*pmatch</code> is set to <code class="symbol">NULL</code> then GIN assumes partial match
+ is not required. The variable is initialized to <code class="symbol">NULL</code> before call,
+ so this argument can simply be ignored by operator classes that do
+ not support partial match.
+ </p><p>
+ <code class="literal">extra_data</code> is an output argument that allows
+ <code class="function">extractQuery</code> to pass additional data to the
+ <code class="function">consistent</code> and <code class="function">comparePartial</code> methods.
+ To use it, <code class="function">extractQuery</code> must allocate
+ an array of <code class="literal">*nkeys</code> pointers and store its address at
+ <code class="literal">*extra_data</code>, then store whatever it wants to into the
+ individual pointers. The variable is initialized to <code class="symbol">NULL</code> before
+ call, so this argument can simply be ignored by operator classes that
+ do not require extra data. If <code class="literal">*extra_data</code> is set, the
+ whole array is passed to the <code class="function">consistent</code> method, and
+ the appropriate element to the <code class="function">comparePartial</code> method.
+ </p></dd></dl></div><p>
+
+ An operator class must also provide a function to check if an indexed item
+ matches the query. It comes in two flavors, a Boolean <code class="function">consistent</code>
+ function, and a ternary <code class="function">triConsistent</code> function.
+ <code class="function">triConsistent</code> covers the functionality of both, so providing
+ <code class="function">triConsistent</code> alone is sufficient. However, if the Boolean
+ variant is significantly cheaper to calculate, it can be advantageous to
+ provide both. If only the Boolean variant is provided, some optimizations
+ that depend on refuting index items before fetching all the keys are
+ disabled.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">bool consistent(bool check[], StrategyNumber n, Datum query,
+ int32 nkeys, Pointer extra_data[], bool *recheck,
+ Datum queryKeys[], bool nullFlags[])</code></span></dt><dd><p>
+ Returns true if an indexed item satisfies the query operator with
+ strategy number <code class="literal">n</code> (or might satisfy it, if the recheck
+ indication is returned). This function does not have direct access
+ to the indexed item's value, since <acronym class="acronym">GIN</acronym> does not
+ store items explicitly. Rather, what is available is knowledge
+ about which key values extracted from the query appear in a given
+ indexed item. The <code class="literal">check</code> array has length
+ <code class="literal">nkeys</code>, which is the same as the number of keys previously
+ returned by <code class="function">extractQuery</code> for this <code class="literal">query</code> datum.
+ Each element of the
+ <code class="literal">check</code> array is true if the indexed item contains the
+ corresponding query key, i.e., if (check[i] == true) the i-th key of the
+ <code class="function">extractQuery</code> result array is present in the indexed item.
+ The original <code class="literal">query</code> datum is
+ passed in case the <code class="function">consistent</code> method needs to consult it,
+ and so are the <code class="literal">queryKeys[]</code> and <code class="literal">nullFlags[]</code>
+ arrays previously returned by <code class="function">extractQuery</code>.
+ <code class="literal">extra_data</code> is the extra-data array returned by
+ <code class="function">extractQuery</code>, or <code class="symbol">NULL</code> if none.
+ </p><p>
+ When <code class="function">extractQuery</code> returns a null key in
+ <code class="literal">queryKeys[]</code>, the corresponding <code class="literal">check[]</code> element
+ is true if the indexed item contains a null key; that is, the
+ semantics of <code class="literal">check[]</code> are like <code class="literal">IS NOT DISTINCT
+ FROM</code>. The <code class="function">consistent</code> function can examine the
+ corresponding <code class="literal">nullFlags[]</code> element if it needs to tell
+ the difference between a regular value match and a null match.
+ </p><p>
+ On success, <code class="literal">*recheck</code> should be set to true if the heap
+ tuple needs to be rechecked against the query operator, or false if
+ the index test is exact. That is, a false return value guarantees
+ that the heap tuple does not match the query; a true return value with
+ <code class="literal">*recheck</code> set to false guarantees that the heap tuple does
+ match the query; and a true return value with
+ <code class="literal">*recheck</code> set to true means that the heap tuple might match
+ the query, so it needs to be fetched and rechecked by evaluating the
+ query operator directly against the originally indexed item.
+ </p></dd><dt><span class="term"><code class="function">GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,
+ int32 nkeys, Pointer extra_data[],
+ Datum queryKeys[], bool nullFlags[])</code></span></dt><dd><p>
+ <code class="function">triConsistent</code> is similar to <code class="function">consistent</code>,
+ but instead of Booleans in the <code class="literal">check</code> vector, there are
+ three possible values for each
+ key: <code class="literal">GIN_TRUE</code>, <code class="literal">GIN_FALSE</code> and
+ <code class="literal">GIN_MAYBE</code>. <code class="literal">GIN_FALSE</code> and <code class="literal">GIN_TRUE</code>
+ have the same meaning as regular Boolean values, while
+ <code class="literal">GIN_MAYBE</code> means that the presence of that key is not known.
+ When <code class="literal">GIN_MAYBE</code> values are present, the function should only
+ return <code class="literal">GIN_TRUE</code> if the item certainly matches whether or
+ not the index item contains the corresponding query keys. Likewise, the
+ function must return <code class="literal">GIN_FALSE</code> only if the item certainly
+ does not match, whether or not it contains the <code class="literal">GIN_MAYBE</code>
+ keys. If the result depends on the <code class="literal">GIN_MAYBE</code> entries, i.e.,
+ the match cannot be confirmed or refuted based on the known query keys,
+ the function must return <code class="literal">GIN_MAYBE</code>.
+ </p><p>
+ When there are no <code class="literal">GIN_MAYBE</code> values in the <code class="literal">check</code>
+ vector, a <code class="literal">GIN_MAYBE</code> return value is the equivalent of
+ setting the <code class="literal">recheck</code> flag in the
+ Boolean <code class="function">consistent</code> function.
+ </p></dd></dl></div><p>
+ </p><p>
+ In addition, GIN must have a way to sort the key values stored in the index.
+ The operator class can define the sort ordering by specifying a comparison
+ method:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">int compare(Datum a, Datum b)</code></span></dt><dd><p>
+ Compares two keys (not indexed items!) and returns an integer less than
+ zero, zero, or greater than zero, indicating whether the first key is
+ less than, equal to, or greater than the second. Null keys are never
+ passed to this function.
+ </p></dd></dl></div><p>
+
+ Alternatively, if the operator class does not provide a <code class="function">compare</code>
+ method, GIN will look up the default btree operator class for the index
+ key data type, and use its comparison function. It is recommended to
+ specify the comparison function in a GIN operator class that is meant for
+ just one data type, as looking up the btree operator class costs a few
+ cycles. However, polymorphic GIN operator classes (such
+ as <code class="literal">array_ops</code>) typically cannot specify a single comparison
+ function.
+ </p><p>
+ An operator class for <acronym class="acronym">GIN</acronym> can optionally supply the
+ following methods:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">int comparePartial(Datum partial_key, Datum key, StrategyNumber n,
+ Pointer extra_data)</code></span></dt><dd><p>
+ Compare a partial-match query key to an index key. Returns an integer
+ whose sign indicates the result: less than zero means the index key
+ does not match the query, but the index scan should continue; zero
+ means that the index key does match the query; greater than zero
+ indicates that the index scan should stop because no more matches
+ are possible. The strategy number <code class="literal">n</code> of the operator
+ that generated the partial match query is provided, in case its
+ semantics are needed to determine when to end the scan. Also,
+ <code class="literal">extra_data</code> is the corresponding element of the extra-data
+ array made by <code class="function">extractQuery</code>, or <code class="symbol">NULL</code> if none.
+ Null keys are never passed to this function.
+ </p></dd><dt><span class="term"><code class="function">void options(local_relopts *relopts)</code></span></dt><dd><p>
+ Defines a set of user-visible parameters that control operator class
+ behavior.
+ </p><p>
+ The <code class="function">options</code> function is passed a pointer to a
+ <code class="structname">local_relopts</code> struct, which needs to be
+ filled with a set of operator class specific options. The options
+ can be accessed from other support functions using the
+ <code class="literal">PG_HAS_OPCLASS_OPTIONS()</code> and
+ <code class="literal">PG_GET_OPCLASS_OPTIONS()</code> macros.
+ </p><p>
+ Since both key extraction of indexed values and representation of the
+ key in <acronym class="acronym">GIN</acronym> are flexible, they may depend on
+ user-specified parameters.
+ </p></dd></dl></div><p>
+ </p><p>
+ To support <span class="quote">“<span class="quote">partial match</span>”</span> queries, an operator class must
+ provide the <code class="function">comparePartial</code> method, and its
+ <code class="function">extractQuery</code> method must set the <code class="literal">pmatch</code>
+ parameter when a partial-match query is encountered. See
+ <a class="xref" href="gin-implementation.html#GIN-PARTIAL-MATCH" title="70.4.2. Partial Match Algorithm">Section 70.4.2</a> for details.
+ </p><p>
+ The actual data types of the various <code class="literal">Datum</code> values mentioned
+ above vary depending on the operator class. The item values passed to
+ <code class="function">extractValue</code> are always of the operator class's input type, and
+ all key values must be of the class's <code class="literal">STORAGE</code> type. The type of
+ the <code class="literal">query</code> argument passed to <code class="function">extractQuery</code>,
+ <code class="function">consistent</code> and <code class="function">triConsistent</code> is whatever is the
+ right-hand input type of the class member operator identified by the
+ strategy number. This need not be the same as the indexed type, so long as
+ key values of the correct type can be extracted from it. However, it is
+ recommended that the SQL declarations of these three support functions use
+ the opclass's indexed data type for the <code class="literal">query</code> argument, even
+ though the actual type might be something else depending on the operator.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-implementation.html" title="70.4. Implementation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.2. Built-in Operator Classes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.4. Implementation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-implementation.html b/doc/src/sgml/html/gin-implementation.html
new file mode 100644
index 0000000..e49b9aa
--- /dev/null
+++ b/doc/src/sgml/html/gin-implementation.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.4. Implementation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-extensibility.html" title="70.3. Extensibility" /><link rel="next" href="gin-tips.html" title="70.5. GIN Tips and Tricks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.4. Implementation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-extensibility.html" title="70.3. Extensibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.4. Implementation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="gin-implementation.html#GIN-FAST-UPDATE">70.4.1. GIN Fast Update Technique</a></span></dt><dt><span class="sect2"><a href="gin-implementation.html#GIN-PARTIAL-MATCH">70.4.2. Partial Match Algorithm</a></span></dt></dl></div><p>
+ Internally, a <acronym class="acronym">GIN</acronym> index contains a B-tree index
+ constructed over keys, where each key is an element of one or more indexed
+ items (a member of an array, for example) and where each tuple in a leaf
+ page contains either a pointer to a B-tree of heap pointers (a
+ <span class="quote">“<span class="quote">posting tree</span>”</span>), or a simple list of heap pointers (a <span class="quote">“<span class="quote">posting
+ list</span>”</span>) when the list is small enough to fit into a single index tuple along
+ with the key value. <a class="xref" href="gin-implementation.html#GIN-INTERNALS-FIGURE" title="Figure 70.1. GIN Internals">Figure 70.1</a> illustrates
+ these components of a GIN index.
+ </p><p>
+ As of <span class="productname">PostgreSQL</span> 9.1, null key values can be
+ included in the index. Also, placeholder nulls are included in the index
+ for indexed items that are null or contain no keys according to
+ <code class="function">extractValue</code>. This allows searches that should find empty
+ items to do so.
+ </p><p>
+ Multicolumn <acronym class="acronym">GIN</acronym> indexes are implemented by building
+ a single B-tree over composite values (column number, key value). The
+ key values for different columns can be of different types.
+ </p><div class="figure" id="GIN-INTERNALS-FIGURE"><p class="title"><strong>Figure 70.1. GIN Internals</strong></p><div class="figure-contents"><div class="mediaobject"><object type="image/svg+xml" data="gin.svg" width="100%"></object></div></div></div><br class="figure-break" /><div class="sect2" id="GIN-FAST-UPDATE"><div class="titlepage"><div><div><h3 class="title">70.4.1. GIN Fast Update Technique</h3></div></div></div><p>
+ Updating a <acronym class="acronym">GIN</acronym> index tends to be slow because of the
+ intrinsic nature of inverted indexes: inserting or updating one heap row
+ can cause many inserts into the index (one for each key extracted
+ from the indexed item).
+ <acronym class="acronym">GIN</acronym> is capable of postponing much of this work by inserting
+ new tuples into a temporary, unsorted list of pending entries.
+ When the table is vacuumed or autoanalyzed, or when
+ <code class="function">gin_clean_pending_list</code> function is called, or if the
+ pending list becomes larger than
+ <a class="xref" href="runtime-config-client.html#GUC-GIN-PENDING-LIST-LIMIT">gin_pending_list_limit</a>, the entries are moved to the
+ main <acronym class="acronym">GIN</acronym> data structure using the same bulk insert
+ techniques used during initial index creation. This greatly improves
+ <acronym class="acronym">GIN</acronym> index update speed, even counting the additional
+ vacuum overhead. Moreover the overhead work can be done by a background
+ process instead of in foreground query processing.
+ </p><p>
+ The main disadvantage of this approach is that searches must scan the list
+ of pending entries in addition to searching the regular index, and so
+ a large list of pending entries will slow searches significantly.
+ Another disadvantage is that, while most updates are fast, an update
+ that causes the pending list to become <span class="quote">“<span class="quote">too large</span>”</span> will incur an
+ immediate cleanup cycle and thus be much slower than other updates.
+ Proper use of autovacuum can minimize both of these problems.
+ </p><p>
+ If consistent response time is more important than update speed,
+ use of pending entries can be disabled by turning off the
+ <code class="literal">fastupdate</code> storage parameter for a
+ <acronym class="acronym">GIN</acronym> index. See <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>
+ for details.
+ </p></div><div class="sect2" id="GIN-PARTIAL-MATCH"><div class="titlepage"><div><div><h3 class="title">70.4.2. Partial Match Algorithm</h3></div></div></div><p>
+ GIN can support <span class="quote">“<span class="quote">partial match</span>”</span> queries, in which the query
+ does not determine an exact match for one or more keys, but the possible
+ matches fall within a reasonably narrow range of key values (within the
+ key sorting order determined by the <code class="function">compare</code> support method).
+ The <code class="function">extractQuery</code> method, instead of returning a key value
+ to be matched exactly, returns a key value that is the lower bound of
+ the range to be searched, and sets the <code class="literal">pmatch</code> flag true.
+ The key range is then scanned using the <code class="function">comparePartial</code>
+ method. <code class="function">comparePartial</code> must return zero for a matching
+ index key, less than zero for a non-match that is still within the range
+ to be searched, or greater than zero if the index key is past the range
+ that could match.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-extensibility.html" title="70.3. Extensibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.3. Extensibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.5. GIN Tips and Tricks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-intro.html b/doc/src/sgml/html/gin-intro.html
new file mode 100644
index 0000000..dda5402
--- /dev/null
+++ b/doc/src/sgml/html/gin-intro.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin.html" title="Chapter 70. GIN Indexes" /><link rel="next" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin.html" title="Chapter 70. GIN Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.1. Introduction</h2></div></div></div><p>
+ <acronym class="acronym">GIN</acronym> stands for Generalized Inverted Index.
+ <acronym class="acronym">GIN</acronym> is designed for handling cases where the items
+ to be indexed are composite values, and the queries to be handled by
+ the index need to search for element values that appear within
+ the composite items. For example, the items could be documents,
+ and the queries could be searches for documents containing specific words.
+ </p><p>
+ We use the word <em class="firstterm">item</em> to refer to a composite value that
+ is to be indexed, and the word <em class="firstterm">key</em> to refer to an element
+ value. <acronym class="acronym">GIN</acronym> always stores and searches for keys,
+ not item values per se.
+ </p><p>
+ A <acronym class="acronym">GIN</acronym> index stores a set of (key, posting list) pairs,
+ where a <em class="firstterm">posting list</em> is a set of row IDs in which the key
+ occurs. The same row ID can appear in multiple posting lists, since
+ an item can contain more than one key. Each key value is stored only
+ once, so a <acronym class="acronym">GIN</acronym> index is very compact for cases
+ where the same key appears many times.
+ </p><p>
+ <acronym class="acronym">GIN</acronym> is generalized in the sense that the
+ <acronym class="acronym">GIN</acronym> access method code does not need to know the
+ specific operations that it accelerates.
+ Instead, it uses custom strategies defined for particular data types.
+ The strategy defines how keys are extracted from indexed items and
+ query conditions, and how to determine whether a row that contains
+ some of the key values in a query actually satisfies the query.
+ </p><p>
+ One advantage of <acronym class="acronym">GIN</acronym> is that it allows the development
+ of custom data types with the appropriate access methods, by
+ an expert in the domain of the data type, rather than a database expert.
+ This is much the same advantage as using <acronym class="acronym">GiST</acronym>.
+ </p><p>
+ The <acronym class="acronym">GIN</acronym>
+ implementation in <span class="productname">PostgreSQL</span> is primarily
+ maintained by Teodor Sigaev and Oleg Bartunov. There is more
+ information about <acronym class="acronym">GIN</acronym> on their
+ <a class="ulink" href="http://www.sai.msu.su/~megera/wiki/Gin" target="_top">website</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin.html" title="Chapter 70. GIN Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-builtin-opclasses.html" title="70.2. Built-in Operator Classes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 70. GIN Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.2. Built-in Operator Classes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-limit.html b/doc/src/sgml/html/gin-limit.html
new file mode 100644
index 0000000..1b37b06
--- /dev/null
+++ b/doc/src/sgml/html/gin-limit.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.6. Limitations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-tips.html" title="70.5. GIN Tips and Tricks" /><link rel="next" href="gin-examples.html" title="70.7. Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.6. Limitations</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-examples.html" title="70.7. Examples">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-LIMIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.6. Limitations</h2></div></div></div><p>
+ <acronym class="acronym">GIN</acronym> assumes that indexable operators are strict. This
+ means that <code class="function">extractValue</code> will not be called at all on a null
+ item value (instead, a placeholder index entry is created automatically),
+ and <code class="function">extractQuery</code> will not be called on a null query
+ value either (instead, the query is presumed to be unsatisfiable). Note
+ however that null key values contained within a non-null composite item
+ or query value are supported.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-examples.html" title="70.7. Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.5. GIN Tips and Tricks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.7. Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin-tips.html b/doc/src/sgml/html/gin-tips.html
new file mode 100644
index 0000000..aea43d5
--- /dev/null
+++ b/doc/src/sgml/html/gin-tips.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>70.5. GIN Tips and Tricks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gin-implementation.html" title="70.4. Implementation" /><link rel="next" href="gin-limit.html" title="70.6. Limitations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">70.5. GIN Tips and Tricks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gin-implementation.html" title="70.4. Implementation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><th width="60%" align="center">Chapter 70. GIN Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-limit.html" title="70.6. Limitations">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIN-TIPS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">70.5. GIN Tips and Tricks</h2></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">Create vs. insert</span></dt><dd><p>
+ Insertion into a <acronym class="acronym">GIN</acronym> index can be slow
+ due to the likelihood of many keys being inserted for each item.
+ So, for bulk insertions into a table it is advisable to drop the GIN
+ index and recreate it after finishing bulk insertion.
+ </p><p>
+ When <code class="literal">fastupdate</code> is enabled for <acronym class="acronym">GIN</acronym>
+ (see <a class="xref" href="gin-implementation.html#GIN-FAST-UPDATE" title="70.4.1. GIN Fast Update Technique">Section 70.4.1</a> for details), the penalty is
+ less than when it is not. But for very large updates it may still be
+ best to drop and recreate the index.
+ </p></dd><dt><span class="term"><a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a></span></dt><dd><p>
+ Build time for a <acronym class="acronym">GIN</acronym> index is very sensitive to
+ the <code class="varname">maintenance_work_mem</code> setting; it doesn't pay to
+ skimp on work memory during index creation.
+ </p></dd><dt><span class="term"><a class="xref" href="runtime-config-client.html#GUC-GIN-PENDING-LIST-LIMIT">gin_pending_list_limit</a></span></dt><dd><p>
+ During a series of insertions into an existing <acronym class="acronym">GIN</acronym>
+ index that has <code class="literal">fastupdate</code> enabled, the system will clean up
+ the pending-entry list whenever the list grows larger than
+ <code class="varname">gin_pending_list_limit</code>. To avoid fluctuations in observed
+ response time, it's desirable to have pending-list cleanup occur in the
+ background (i.e., via autovacuum). Foreground cleanup operations
+ can be avoided by increasing <code class="varname">gin_pending_list_limit</code>
+ or making autovacuum more aggressive.
+ However, enlarging the threshold of the cleanup operation means that
+ if a foreground cleanup does occur, it will take even longer.
+ </p><p>
+ <code class="varname">gin_pending_list_limit</code> can be overridden for individual
+ GIN indexes by changing storage parameters, which allows each
+ GIN index to have its own cleanup threshold.
+ For example, it's possible to increase the threshold only for the GIN
+ index which can be updated heavily, and decrease it otherwise.
+ </p></dd><dt><span class="term"><a class="xref" href="runtime-config-client.html#GUC-GIN-FUZZY-SEARCH-LIMIT">gin_fuzzy_search_limit</a></span></dt><dd><p>
+ The primary goal of developing <acronym class="acronym">GIN</acronym> indexes was
+ to create support for highly scalable full-text search in
+ <span class="productname">PostgreSQL</span>, and there are often situations when
+ a full-text search returns a very large set of results. Moreover, this
+ often happens when the query contains very frequent words, so that the
+ large result set is not even useful. Since reading many
+ tuples from the disk and sorting them could take a lot of time, this is
+ unacceptable for production. (Note that the index search itself is very
+ fast.)
+ </p><p>
+ To facilitate controlled execution of such queries,
+ <acronym class="acronym">GIN</acronym> has a configurable soft upper limit on the
+ number of rows returned: the
+ <code class="varname">gin_fuzzy_search_limit</code> configuration parameter.
+ It is set to 0 (meaning no limit) by default.
+ If a non-zero limit is set, then the returned set is a subset of
+ the whole result set, chosen at random.
+ </p><p>
+ <span class="quote">“<span class="quote">Soft</span>”</span> means that the actual number of returned results
+ could differ somewhat from the specified limit, depending on the query
+ and the quality of the system's random number generator.
+ </p><p>
+ From experience, values in the thousands (e.g., 5000 — 20000)
+ work well.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gin-implementation.html" title="70.4. Implementation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gin.html" title="Chapter 70. GIN Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-limit.html" title="70.6. Limitations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">70.4. Implementation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.6. Limitations</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin.html b/doc/src/sgml/html/gin.html
new file mode 100644
index 0000000..c883eb5
--- /dev/null
+++ b/doc/src/sgml/html/gin.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 70. GIN Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spgist-examples.html" title="69.5. Examples" /><link rel="next" href="gin-intro.html" title="70.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 70. GIN Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spgist-examples.html" title="69.5. Examples">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin-intro.html" title="70.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="GIN"><div class="titlepage"><div><div><h2 class="title">Chapter 70. GIN Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="gin-intro.html">70.1. Introduction</a></span></dt><dt><span class="sect1"><a href="gin-builtin-opclasses.html">70.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="gin-extensibility.html">70.3. Extensibility</a></span></dt><dt><span class="sect1"><a href="gin-implementation.html">70.4. Implementation</a></span></dt><dd><dl><dt><span class="sect2"><a href="gin-implementation.html#GIN-FAST-UPDATE">70.4.1. GIN Fast Update Technique</a></span></dt><dt><span class="sect2"><a href="gin-implementation.html#GIN-PARTIAL-MATCH">70.4.2. Partial Match Algorithm</a></span></dt></dl></dd><dt><span class="sect1"><a href="gin-tips.html">70.5. GIN Tips and Tricks</a></span></dt><dt><span class="sect1"><a href="gin-limit.html">70.6. Limitations</a></span></dt><dt><span class="sect1"><a href="gin-examples.html">70.7. Examples</a></span></dt></dl></div><a id="id-1.10.21.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spgist-examples.html" title="69.5. Examples">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin-intro.html" title="70.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">69.5. Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 70.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gin.svg b/doc/src/sgml/html/gin.svg
new file mode 100644
index 0000000..04fe85b
--- /dev/null
+++ b/doc/src/sgml/html/gin.svg
@@ -0,0 +1,317 @@
+<?xml version="1.0"?>
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: gin Pages: 1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="836pt" height="432pt" viewBox="0.00 0.00 836.00 432.00">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 428)">
+<title>gin</title>
+<polygon fill="#ffffff" stroke="none" points="-4,4 -4,-428 832,-428 832,4 -4,4"/>
+<g id="clust1" class="cluster">
+<title>cluster01</title>
+<polygon fill="none" stroke="#000000" points="100,-162 100,-380 694,-380 694,-162 100,-162"/>
+<text text-anchor="middle" x="397" y="-364.8" font-family="Times,serif" font-size="14.00" fill="#000000">entry tree</text>
+</g>
+<g id="clust5" class="cluster">
+<title>cluster02</title>
+<polygon fill="none" stroke="#000000" points="8,-8 8,-154 245,-154 245,-8 8,-8"/>
+<text text-anchor="middle" x="126.5" y="-138.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting tree</text>
+</g>
+<g id="clust8" class="cluster">
+<title>cluster03</title>
+<polygon fill="none" stroke="#000000" points="279,-80 279,-154 397,-154 397,-80 279,-80"/>
+<text text-anchor="middle" x="338" y="-138.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting tree</text>
+</g>
+<g id="clust10" class="cluster">
+<title>cluster04</title>
+<polygon fill="none" stroke="#000000" points="405,-8 405,-154 642,-154 642,-8 405,-8"/>
+<text text-anchor="middle" x="523.5" y="-138.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting tree</text>
+</g>
+<g id="clust13" class="cluster">
+<title>cluster05</title>
+<polygon fill="none" stroke="#000000" points="702,-80 702,-380 820,-380 820,-80 702,-80"/>
+<text text-anchor="middle" x="761" y="-364.8" font-family="Times,serif" font-size="14.00" fill="#000000">pending list</text>
+</g>
+<!-- m1 -->
+<g id="node1" class="node">
+<title>m1</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="688.5,-424 587.5,-424 587.5,-388 688.5,-388 688.5,-424"/>
+<text text-anchor="middle" x="638" y="-401.8" font-family="Times,serif" font-size="14.00" fill="#000000">meta page</text>
+</g>
+<!-- e1 -->
+<g id="node2" class="node">
+<title>e1</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="506.5,-350 405.5,-350 405.5,-314 506.5,-314 506.5,-350"/>
+</g>
+<!-- m1&#45;&gt;e1 -->
+<g id="edge24" class="edge">
+<title>m1-&gt;e1</title>
+<path fill="none" stroke="#000000" d="M593.4778,-387.8976C568.2655,-377.6464 536.5468,-364.7498 509.931,-353.928"/>
+<polygon fill="#000000" stroke="#000000" points="510.9595,-350.568 500.3776,-350.0436 508.3229,-357.0525 510.9595,-350.568"/>
+</g>
+<!-- n1 -->
+<g id="node18" class="node">
+<title>n1</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-350 710.5,-350 710.5,-314 811.5,-314 811.5,-350"/>
+</g>
+<!-- m1&#45;&gt;n1 -->
+<g id="edge28" class="edge">
+<title>m1-&gt;n1</title>
+<path fill="none" stroke="#000000" d="M683.1514,-387.8551C688.2504,-385.3905 693.2983,-382.7547 698,-380 709.7018,-373.1438 721.7385,-364.4455 732.115,-356.3423"/>
+<polygon fill="#000000" stroke="#000000" points="734.4083,-358.9902 740.0427,-350.0178 730.0428,-353.5181 734.4083,-358.9902"/>
+</g>
+<!-- e2 -->
+<g id="node3" class="node">
+<title>e2</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="328.5,-278 227.5,-278 227.5,-242 328.5,-242 328.5,-278"/>
+</g>
+<!-- e1&#45;&gt;e2 -->
+<g id="edge9" class="edge">
+<title>e1-&gt;e2</title>
+<path fill="none" stroke="#000000" d="M411.0831,-313.8314C387.065,-304.1162 357.3166,-292.0831 332.0408,-281.8592"/>
+<polygon fill="#000000" stroke="#000000" points="333.1767,-278.5432 322.5939,-278.038 330.5518,-285.0325 333.1767,-278.5432"/>
+</g>
+<!-- e3 -->
+<g id="node4" class="node">
+<title>e3</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="447.5,-278 346.5,-278 346.5,-242 447.5,-242 447.5,-278"/>
+</g>
+<!-- e1&#45;&gt;e3 -->
+<g id="edge8" class="edge">
+<title>e1-&gt;e3</title>
+<path fill="none" stroke="#000000" d="M441.1118,-313.8314C434.247,-305.454 425.9699,-295.3531 418.4489,-286.1749"/>
+<polygon fill="#000000" stroke="#000000" points="421.1341,-283.9297 412.0886,-278.4133 415.7197,-288.3665 421.1341,-283.9297"/>
+</g>
+<!-- e4 -->
+<g id="node5" class="node">
+<title>e4</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="566.5,-278 465.5,-278 465.5,-242 566.5,-242 566.5,-278"/>
+</g>
+<!-- e1&#45;&gt;e4 -->
+<g id="edge7" class="edge">
+<title>e1-&gt;e4</title>
+<path fill="none" stroke="#000000" d="M471.1405,-313.8314C478.1217,-305.454 486.5391,-295.3531 494.1876,-286.1749"/>
+<polygon fill="#000000" stroke="#000000" points="496.9425,-288.3362 500.6556,-278.4133 491.5649,-283.8548 496.9425,-288.3362"/>
+</g>
+<!-- e2&#45;&gt;e3 -->
+<g id="edge1" class="edge">
+<title>e2-&gt;e3</title>
+<path fill="none" stroke="#000000" d="M328.668,-260C331.1453,-260 333.6227,-260 336.1001,-260"/>
+<polygon fill="#000000" stroke="#000000" points="336.2849,-263.5001 346.2848,-260 336.2848,-256.5001 336.2849,-263.5001"/>
+</g>
+<!-- e5 -->
+<g id="node6" class="node">
+<title>e5</title>
+<polygon fill="#008b00" stroke="#000000" points="209.5,-206 108.5,-206 108.5,-170 209.5,-170 209.5,-206"/>
+</g>
+<!-- e2&#45;&gt;e5 -->
+<g id="edge10" class="edge">
+<title>e2-&gt;e5</title>
+<path fill="none" stroke="#000000" d="M247.9713,-241.8314C232.7504,-232.6221 214.0872,-221.3301 197.7917,-211.4706"/>
+<polygon fill="#000000" stroke="#000000" points="199.3868,-208.345 189.0191,-206.1628 195.7631,-214.3341 199.3868,-208.345"/>
+</g>
+<!-- e6 -->
+<g id="node7" class="node">
+<title>e6</title>
+<polygon fill="#00ff00" stroke="#000000" points="328.5,-206 227.5,-206 227.5,-170 328.5,-170 328.5,-206"/>
+<text text-anchor="middle" x="278" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting list</text>
+</g>
+<!-- e2&#45;&gt;e6 -->
+<g id="edge11" class="edge">
+<title>e2-&gt;e6</title>
+<path fill="none" stroke="#000000" d="M278,-241.8314C278,-234.131 278,-224.9743 278,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="281.5001,-216.4132 278,-206.4133 274.5001,-216.4133 281.5001,-216.4132"/>
+</g>
+<!-- e3&#45;&gt;e4 -->
+<g id="edge2" class="edge">
+<title>e3-&gt;e4</title>
+<path fill="none" stroke="#000000" d="M447.668,-260C450.1453,-260 452.6227,-260 455.1001,-260"/>
+<polygon fill="#000000" stroke="#000000" points="455.2849,-263.5001 465.2848,-260 455.2848,-256.5001 455.2849,-263.5001"/>
+</g>
+<!-- e7 -->
+<g id="node8" class="node">
+<title>e7</title>
+<polygon fill="#008b00" stroke="#000000" points="447.5,-206 346.5,-206 346.5,-170 447.5,-170 447.5,-206"/>
+</g>
+<!-- e3&#45;&gt;e7 -->
+<g id="edge12" class="edge">
+<title>e3-&gt;e7</title>
+<path fill="none" stroke="#000000" d="M397,-241.8314C397,-234.131 397,-224.9743 397,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="400.5001,-216.4132 397,-206.4133 393.5001,-216.4133 400.5001,-216.4132"/>
+</g>
+<!-- e8 -->
+<g id="node9" class="node">
+<title>e8</title>
+<polygon fill="#00ff00" stroke="#000000" points="566.5,-206 465.5,-206 465.5,-170 566.5,-170 566.5,-206"/>
+<text text-anchor="middle" x="516" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting list</text>
+</g>
+<!-- e4&#45;&gt;e8 -->
+<g id="edge13" class="edge">
+<title>e4-&gt;e8</title>
+<path fill="none" stroke="#000000" d="M516,-241.8314C516,-234.131 516,-224.9743 516,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="519.5001,-216.4132 516,-206.4133 512.5001,-216.4133 519.5001,-216.4132"/>
+</g>
+<!-- e9 -->
+<g id="node10" class="node">
+<title>e9</title>
+<polygon fill="#00ff00" stroke="#000000" points="685.5,-206 584.5,-206 584.5,-170 685.5,-170 685.5,-206"/>
+<text text-anchor="middle" x="635" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting list</text>
+</g>
+<!-- e4&#45;&gt;e9 -->
+<g id="edge14" class="edge">
+<title>e4-&gt;e9</title>
+<path fill="none" stroke="#000000" d="M546.0287,-241.8314C561.2496,-232.6221 579.9128,-221.3301 596.2083,-211.4706"/>
+<polygon fill="#000000" stroke="#000000" points="598.2369,-214.3341 604.9809,-206.1628 594.6132,-208.345 598.2369,-214.3341"/>
+</g>
+<!-- e5&#45;&gt;e6 -->
+<g id="edge3" class="edge">
+<title>e5-&gt;e6</title>
+<path fill="none" stroke="#000000" d="M209.668,-188C212.1453,-188 214.6227,-188 217.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="217.2849,-191.5001 227.2848,-188 217.2848,-184.5001 217.2849,-191.5001"/>
+</g>
+<!-- p1 -->
+<g id="node11" class="node">
+<title>p1</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="209.5,-124 108.5,-124 108.5,-88 209.5,-88 209.5,-124"/>
+</g>
+<!-- e5&#45;&gt;p1 -->
+<g id="edge25" class="edge">
+<title>e5-&gt;p1</title>
+<path fill="none" stroke="#000000" d="M159,-169.8015C159,-159.3976 159,-146.1215 159,-134.3768"/>
+<polygon fill="#000000" stroke="#000000" points="162.5001,-134.1476 159,-124.1476 155.5001,-134.1476 162.5001,-134.1476"/>
+</g>
+<!-- e6&#45;&gt;e7 -->
+<g id="edge4" class="edge">
+<title>e6-&gt;e7</title>
+<path fill="none" stroke="#000000" d="M328.668,-188C331.1453,-188 333.6227,-188 336.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="336.2849,-191.5001 346.2848,-188 336.2848,-184.5001 336.2849,-191.5001"/>
+</g>
+<!-- e7&#45;&gt;e8 -->
+<g id="edge5" class="edge">
+<title>e7-&gt;e8</title>
+<path fill="none" stroke="#000000" d="M447.668,-188C450.1453,-188 452.6227,-188 455.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="455.2849,-191.5001 465.2848,-188 455.2848,-184.5001 455.2849,-191.5001"/>
+</g>
+<!-- p4 -->
+<g id="node14" class="node">
+<title>p4</title>
+<polygon fill="#00ff00" stroke="#000000" points="388.5,-124 287.5,-124 287.5,-88 388.5,-88 388.5,-124"/>
+<text text-anchor="middle" x="338" y="-101.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- e7&#45;&gt;p4 -->
+<g id="edge26" class="edge">
+<title>e7-&gt;p4</title>
+<path fill="none" stroke="#000000" d="M383.906,-169.8015C376.0383,-158.8668 365.8878,-144.7593 357.133,-132.5916"/>
+<polygon fill="#000000" stroke="#000000" points="359.7389,-130.2207 351.0574,-124.1476 354.0569,-134.309 359.7389,-130.2207"/>
+</g>
+<!-- p5 -->
+<g id="node15" class="node">
+<title>p5</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="514.5,-124 413.5,-124 413.5,-88 514.5,-88 514.5,-124"/>
+</g>
+<!-- e7&#45;&gt;p5 -->
+<g id="edge27" class="edge">
+<title>e7-&gt;p5</title>
+<path fill="none" stroke="#000000" d="M411.8695,-169.8015C420.8907,-158.7606 432.5549,-144.4851 442.5618,-132.2378"/>
+<polygon fill="#000000" stroke="#000000" points="445.5552,-134.1059 449.1721,-124.1476 440.1345,-129.6768 445.5552,-134.1059"/>
+</g>
+<!-- e8&#45;&gt;e9 -->
+<g id="edge6" class="edge">
+<title>e8-&gt;e9</title>
+<path fill="none" stroke="#000000" d="M566.668,-188C569.1453,-188 571.6227,-188 574.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="574.2849,-191.5001 584.2848,-188 574.2848,-184.5001 574.2849,-191.5001"/>
+</g>
+<!-- p2 -->
+<g id="node12" class="node">
+<title>p2</title>
+<polygon fill="#00ff00" stroke="#000000" points="117.5,-52 16.5,-52 16.5,-16 117.5,-16 117.5,-52"/>
+<text text-anchor="middle" x="67" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p1&#45;&gt;p2 -->
+<g id="edge16" class="edge">
+<title>p1-&gt;p2</title>
+<path fill="none" stroke="#000000" d="M135.7845,-87.8314C124.453,-78.9632 110.6536,-68.1637 98.3973,-58.5718"/>
+<polygon fill="#000000" stroke="#000000" points="100.2402,-55.5697 90.2081,-52.1628 95.926,-61.0822 100.2402,-55.5697"/>
+</g>
+<!-- p3 -->
+<g id="node13" class="node">
+<title>p3</title>
+<polygon fill="#00ff00" stroke="#000000" points="236.5,-52 135.5,-52 135.5,-16 236.5,-16 236.5,-52"/>
+<text text-anchor="middle" x="186" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p1&#45;&gt;p3 -->
+<g id="edge17" class="edge">
+<title>p1-&gt;p3</title>
+<path fill="none" stroke="#000000" d="M165.8132,-87.8314C168.7644,-79.9617 172.2858,-70.5712 175.555,-61.8533"/>
+<polygon fill="#000000" stroke="#000000" points="178.8609,-63.0055 179.095,-52.4133 172.3066,-60.5476 178.8609,-63.0055"/>
+</g>
+<!-- p2&#45;&gt;p3 -->
+<g id="edge15" class="edge">
+<title>p2-&gt;p3</title>
+<path fill="none" stroke="#000000" d="M117.668,-34C120.1453,-34 122.6227,-34 125.1001,-34"/>
+<polygon fill="#000000" stroke="#000000" points="125.2849,-37.5001 135.2848,-34 125.2848,-30.5001 125.2849,-37.5001"/>
+</g>
+<!-- p6 -->
+<g id="node16" class="node">
+<title>p6</title>
+<polygon fill="#00ff00" stroke="#000000" points="514.5,-52 413.5,-52 413.5,-16 514.5,-16 514.5,-52"/>
+<text text-anchor="middle" x="464" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p5&#45;&gt;p6 -->
+<g id="edge19" class="edge">
+<title>p5-&gt;p6</title>
+<path fill="none" stroke="#000000" d="M464,-87.8314C464,-80.131 464,-70.9743 464,-62.4166"/>
+<polygon fill="#000000" stroke="#000000" points="467.5001,-62.4132 464,-52.4133 460.5001,-62.4133 467.5001,-62.4132"/>
+</g>
+<!-- p7 -->
+<g id="node17" class="node">
+<title>p7</title>
+<polygon fill="#00ff00" stroke="#000000" points="633.5,-52 532.5,-52 532.5,-16 633.5,-16 633.5,-52"/>
+<text text-anchor="middle" x="583" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p5&#45;&gt;p7 -->
+<g id="edge20" class="edge">
+<title>p5-&gt;p7</title>
+<path fill="none" stroke="#000000" d="M494.0287,-87.8314C509.2496,-78.6221 527.9128,-67.3301 544.2083,-57.4706"/>
+<polygon fill="#000000" stroke="#000000" points="546.2369,-60.3341 552.9809,-52.1628 542.6132,-54.345 546.2369,-60.3341"/>
+</g>
+<!-- p6&#45;&gt;p7 -->
+<g id="edge18" class="edge">
+<title>p6-&gt;p7</title>
+<path fill="none" stroke="#000000" d="M514.668,-34C517.1453,-34 519.6227,-34 522.1001,-34"/>
+<polygon fill="#000000" stroke="#000000" points="522.2849,-37.5001 532.2848,-34 522.2848,-30.5001 522.2849,-37.5001"/>
+</g>
+<!-- n2 -->
+<g id="node19" class="node">
+<title>n2</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-278 710.5,-278 710.5,-242 811.5,-242 811.5,-278"/>
+</g>
+<!-- n1&#45;&gt;n2 -->
+<g id="edge21" class="edge">
+<title>n1-&gt;n2</title>
+<path fill="none" stroke="#000000" d="M761,-313.8314C761,-306.131 761,-296.9743 761,-288.4166"/>
+<polygon fill="#000000" stroke="#000000" points="764.5001,-288.4132 761,-278.4133 757.5001,-288.4133 764.5001,-288.4132"/>
+</g>
+<!-- n3 -->
+<g id="node20" class="node">
+<title>n3</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-206 710.5,-206 710.5,-170 811.5,-170 811.5,-206"/>
+</g>
+<!-- n2&#45;&gt;n3 -->
+<g id="edge22" class="edge">
+<title>n2-&gt;n3</title>
+<path fill="none" stroke="#000000" d="M761,-241.8314C761,-234.131 761,-224.9743 761,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="764.5001,-216.4132 761,-206.4133 757.5001,-216.4133 764.5001,-216.4132"/>
+</g>
+<!-- n4 -->
+<g id="node21" class="node">
+<title>n4</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-124 710.5,-124 710.5,-88 811.5,-88 811.5,-124"/>
+</g>
+<!-- n3&#45;&gt;n4 -->
+<g id="edge23" class="edge">
+<title>n3-&gt;n4</title>
+<path fill="none" stroke="#000000" d="M761,-169.8015C761,-159.3976 761,-146.1215 761,-134.3768"/>
+<polygon fill="#000000" stroke="#000000" points="764.5001,-134.1476 761,-124.1476 757.5001,-134.1476 764.5001,-134.1476"/>
+</g>
+</g>
+</svg>
diff --git a/doc/src/sgml/html/gist-builtin-opclasses.html b/doc/src/sgml/html/gist-builtin-opclasses.html
new file mode 100644
index 0000000..4bd74ee
--- /dev/null
+++ b/doc/src/sgml/html/gist-builtin-opclasses.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>68.2. Built-in Operator Classes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gist-intro.html" title="68.1. Introduction" /><link rel="next" href="gist-extensibility.html" title="68.3. Extensibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">68.2. Built-in Operator Classes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gist-intro.html" title="68.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 68. GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gist-extensibility.html" title="68.3. Extensibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIST-BUILTIN-OPCLASSES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.2. Built-in Operator Classes</h2></div></div></div><p>
+ The core <span class="productname">PostgreSQL</span> distribution
+ includes the <acronym class="acronym">GiST</acronym> operator classes shown in
+ <a class="xref" href="gist-builtin-opclasses.html#GIST-BUILTIN-OPCLASSES-TABLE" title="Table 68.1. Built-in GiST Operator Classes">Table 68.1</a>.
+ (Some of the optional modules described in <a class="xref" href="contrib.html" title="Appendix F. Additional Supplied Modules">Appendix F</a>
+ provide additional <acronym class="acronym">GiST</acronym> operator classes.)
+ </p><div class="table" id="GIST-BUILTIN-OPCLASSES-TABLE"><p class="title"><strong>Table 68.1. Built-in <acronym class="acronym">GiST</acronym> Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Built-in GiST Operator Classes" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Indexable Operators</th><th>Ordering Operators</th></tr></thead><tbody><tr><td rowspan="14" valign="middle"><code class="literal">box_ops</code></td><td><code class="literal">&lt;&lt; (box, box)</code></td><td rowspan="14" valign="middle"><code class="literal">&lt;-&gt; (box, point)</code></td></tr><tr><td><code class="literal">&amp;&lt; (box, box)</code></td></tr><tr><td><code class="literal">&amp;&amp; (box, box)</code></td></tr><tr><td><code class="literal">&amp;&gt; (box, box)</code></td></tr><tr><td><code class="literal">&gt;&gt; (box, box)</code></td></tr><tr><td><code class="literal">~= (box, box)</code></td></tr><tr><td><code class="literal">@&gt; (box, box)</code></td></tr><tr><td><code class="literal">&lt;@ (box, box)</code></td></tr><tr><td><code class="literal">&amp;&lt;| (box, box)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (box, box)</code></td></tr><tr><td><code class="literal">|&gt;&gt; (box, box)</code></td></tr><tr><td><code class="literal">|&amp;&gt; (box, box)</code></td></tr><tr><td><code class="literal">~ (box, box)</code></td></tr><tr><td><code class="literal">@ (box, box)</code></td></tr><tr><td rowspan="14" valign="middle"><code class="literal">circle_ops</code></td><td><code class="literal">&lt;&lt; (circle, circle)</code></td><td rowspan="14" valign="middle"><code class="literal">&lt;-&gt; (circle, point)</code></td></tr><tr><td><code class="literal">&amp;&lt; (circle, circle)</code></td></tr><tr><td><code class="literal">&amp;&gt; (circle, circle)</code></td></tr><tr><td><code class="literal">&gt;&gt; (circle, circle)</code></td></tr><tr><td><code class="literal">&lt;@ (circle, circle)</code></td></tr><tr><td><code class="literal">@&gt; (circle, circle)</code></td></tr><tr><td><code class="literal">~= (circle, circle)</code></td></tr><tr><td><code class="literal">&amp;&amp; (circle, circle)</code></td></tr><tr><td><code class="literal">|&gt;&gt; (circle, circle)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (circle, circle)</code></td></tr><tr><td><code class="literal">&amp;&lt;| (circle, circle)</code></td></tr><tr><td><code class="literal">|&amp;&gt; (circle, circle)</code></td></tr><tr><td><code class="literal">@ (circle, circle)</code></td></tr><tr><td><code class="literal">~ (circle, circle)</code></td></tr><tr><td rowspan="11" valign="middle"><code class="literal">inet_ops</code></td><td><code class="literal">&lt;&lt; (inet, inet)</code></td><td rowspan="11" valign="middle"> </td></tr><tr><td><code class="literal">&lt;&lt;= (inet, inet)</code></td></tr><tr><td><code class="literal">&gt;&gt; (inet, inet)</code></td></tr><tr><td><code class="literal">&gt;&gt;= (inet, inet)</code></td></tr><tr><td><code class="literal">= (inet, inet)</code></td></tr><tr><td><code class="literal">&lt;&gt; (inet, inet)</code></td></tr><tr><td><code class="literal">&lt; (inet, inet)</code></td></tr><tr><td><code class="literal">&lt;= (inet, inet)</code></td></tr><tr><td><code class="literal">&gt; (inet, inet)</code></td></tr><tr><td><code class="literal">&gt;= (inet, inet)</code></td></tr><tr><td><code class="literal">&amp;&amp; (inet, inet)</code></td></tr><tr><td rowspan="18" valign="middle"><code class="literal">multirange_ops</code></td><td><code class="literal">= (anymultirange, anymultirange)</code></td><td rowspan="18" valign="middle"> </td></tr><tr><td><code class="literal">&amp;&amp; (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">&amp;&amp; (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">@&gt; (anymultirange, anyelement)</code></td></tr><tr><td><code class="literal">@&gt; (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">@&gt; (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">&lt;@ (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">&lt;@ (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">&lt;&lt; (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">&lt;&lt; (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">&gt;&gt; (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">&gt;&gt; (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">&amp;&lt; (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">&amp;&lt; (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">&amp;&gt; (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">&amp;&gt; (anymultirange, anyrange)</code></td></tr><tr><td><code class="literal">-|- (anymultirange, anymultirange)</code></td></tr><tr><td><code class="literal">-|- (anymultirange, anyrange)</code></td></tr><tr><td rowspan="8" valign="middle"><code class="literal">point_ops</code></td><td><code class="literal">|&gt;&gt; (point, point)</code></td><td rowspan="8" valign="middle"><code class="literal">&lt;-&gt; (point, point)</code></td></tr><tr><td><code class="literal">&lt;&lt; (point, point)</code></td></tr><tr><td><code class="literal">&gt;&gt; (point, point)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (point, point)</code></td></tr><tr><td><code class="literal">~= (point, point)</code></td></tr><tr><td><code class="literal">&lt;@ (point, box)</code></td></tr><tr><td><code class="literal">&lt;@ (point, polygon)</code></td></tr><tr><td><code class="literal">&lt;@ (point, circle)</code></td></tr><tr><td rowspan="14" valign="middle"><code class="literal">poly_ops</code></td><td><code class="literal">&lt;&lt; (polygon, polygon)</code></td><td rowspan="14" valign="middle"><code class="literal">&lt;-&gt; (polygon, point)</code></td></tr><tr><td><code class="literal">&amp;&lt; (polygon, polygon)</code></td></tr><tr><td><code class="literal">&amp;&gt; (polygon, polygon)</code></td></tr><tr><td><code class="literal">&gt;&gt; (polygon, polygon)</code></td></tr><tr><td><code class="literal">&lt;@ (polygon, polygon)</code></td></tr><tr><td><code class="literal">@&gt; (polygon, polygon)</code></td></tr><tr><td><code class="literal">~= (polygon, polygon)</code></td></tr><tr><td><code class="literal">&amp;&amp; (polygon, polygon)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (polygon, polygon)</code></td></tr><tr><td><code class="literal">&amp;&lt;| (polygon, polygon)</code></td></tr><tr><td><code class="literal">|&amp;&gt; (polygon, polygon)</code></td></tr><tr><td><code class="literal">|&gt;&gt; (polygon, polygon)</code></td></tr><tr><td><code class="literal">@ (polygon, polygon)</code></td></tr><tr><td><code class="literal">~ (polygon, polygon)</code></td></tr><tr><td rowspan="18" valign="middle"><code class="literal">range_ops</code></td><td><code class="literal">= (anyrange, anyrange)</code></td><td rowspan="18" valign="middle"> </td></tr><tr><td><code class="literal">&amp;&amp; (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">&amp;&amp; (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange, anyelement)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">&lt;@ (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">&lt;@ (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">&lt;&lt; (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">&lt;&lt; (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">&gt;&gt; (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">&gt;&gt; (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">&amp;&lt; (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">&amp;&lt; (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">&amp;&gt; (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">&amp;&gt; (anyrange, anymultirange)</code></td></tr><tr><td><code class="literal">-|- (anyrange, anyrange)</code></td></tr><tr><td><code class="literal">-|- (anyrange, anymultirange)</code></td></tr><tr><td rowspan="2" valign="middle"><code class="literal">tsquery_ops</code></td><td><code class="literal">&lt;@ (tsquery, tsquery)</code></td><td rowspan="2" valign="middle"> </td></tr><tr><td><code class="literal">@&gt; (tsquery, tsquery)</code></td></tr><tr><td valign="middle"><code class="literal">tsvector_ops</code></td><td><code class="literal">@@ (tsvector, tsquery)</code></td><td> </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For historical reasons, the <code class="literal">inet_ops</code> operator class is
+ not the default class for types <code class="type">inet</code> and <code class="type">cidr</code>.
+ To use it, mention the class name in <code class="command">CREATE INDEX</code>,
+ for example
+</p><pre class="programlisting">
+CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gist-intro.html" title="68.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gist-extensibility.html" title="68.3. Extensibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 68.3. Extensibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gist-examples.html b/doc/src/sgml/html/gist-examples.html
new file mode 100644
index 0000000..f2660a0
--- /dev/null
+++ b/doc/src/sgml/html/gist-examples.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>68.5. Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gist-implementation.html" title="68.4. Implementation" /><link rel="next" href="spgist.html" title="Chapter 69. SP-GiST Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">68.5. Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gist-implementation.html" title="68.4. Implementation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 68. GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIST-EXAMPLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.5. Examples</h2></div></div></div><p>
+ The <span class="productname">PostgreSQL</span> source distribution includes
+ several examples of index methods implemented using
+ <acronym class="acronym">GiST</acronym>. The core system currently provides text search
+ support (indexing for <code class="type">tsvector</code> and <code class="type">tsquery</code>) as well as
+ R-Tree equivalent functionality for some of the built-in geometric data types
+ (see <code class="filename">src/backend/access/gist/gistproc.c</code>). The following
+ <code class="filename">contrib</code> modules also contain <acronym class="acronym">GiST</acronym>
+ operator classes:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="filename">btree_gist</code></span></dt><dd><p>B-tree equivalent functionality for several data types</p></dd><dt><span class="term"><code class="filename">cube</code></span></dt><dd><p>Indexing for multidimensional cubes</p></dd><dt><span class="term"><code class="filename">hstore</code></span></dt><dd><p>Module for storing (key, value) pairs</p></dd><dt><span class="term"><code class="filename">intarray</code></span></dt><dd><p>RD-Tree for one-dimensional array of int4 values</p></dd><dt><span class="term"><code class="filename">ltree</code></span></dt><dd><p>Indexing for tree-like structures</p></dd><dt><span class="term"><code class="filename">pg_trgm</code></span></dt><dd><p>Text similarity using trigram matching</p></dd><dt><span class="term"><code class="filename">seg</code></span></dt><dd><p>Indexing for <span class="quote">“<span class="quote">float ranges</span>”</span></p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gist-implementation.html" title="68.4. Implementation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.4. Implementation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 69. SP-GiST Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gist-extensibility.html b/doc/src/sgml/html/gist-extensibility.html
new file mode 100644
index 0000000..be685d2
--- /dev/null
+++ b/doc/src/sgml/html/gist-extensibility.html
@@ -0,0 +1,813 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>68.3. Extensibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gist-builtin-opclasses.html" title="68.2. Built-in Operator Classes" /><link rel="next" href="gist-implementation.html" title="68.4. Implementation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">68.3. Extensibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gist-builtin-opclasses.html" title="68.2. Built-in Operator Classes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 68. GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gist-implementation.html" title="68.4. Implementation">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIST-EXTENSIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.3. Extensibility</h2></div></div></div><p>
+ Traditionally, implementing a new index access method meant a lot of
+ difficult work. It was necessary to understand the inner workings of the
+ database, such as the lock manager and Write-Ahead Log. The
+ <acronym class="acronym">GiST</acronym> interface has a high level of abstraction,
+ requiring the access method implementer only to implement the semantics of
+ the data type being accessed. The <acronym class="acronym">GiST</acronym> layer itself
+ takes care of concurrency, logging and searching the tree structure.
+ </p><p>
+ This extensibility should not be confused with the extensibility of the
+ other standard search trees in terms of the data they can handle. For
+ example, <span class="productname">PostgreSQL</span> supports extensible B-trees
+ and hash indexes. That means that you can use
+ <span class="productname">PostgreSQL</span> to build a B-tree or hash over any
+ data type you want. But B-trees only support range predicates
+ (<code class="literal">&lt;</code>, <code class="literal">=</code>, <code class="literal">&gt;</code>),
+ and hash indexes only support equality queries.
+ </p><p>
+ So if you index, say, an image collection with a
+ <span class="productname">PostgreSQL</span> B-tree, you can only issue queries
+ such as <span class="quote">“<span class="quote">is imagex equal to imagey</span>”</span>, <span class="quote">“<span class="quote">is imagex less
+ than imagey</span>”</span> and <span class="quote">“<span class="quote">is imagex greater than imagey</span>”</span>.
+ Depending on how you define <span class="quote">“<span class="quote">equals</span>”</span>, <span class="quote">“<span class="quote">less than</span>”</span>
+ and <span class="quote">“<span class="quote">greater than</span>”</span> in this context, this could be useful.
+ However, by using a <acronym class="acronym">GiST</acronym> based index, you could create
+ ways to ask domain-specific questions, perhaps <span class="quote">“<span class="quote">find all images of
+ horses</span>”</span> or <span class="quote">“<span class="quote">find all over-exposed images</span>”</span>.
+ </p><p>
+ All it takes to get a <acronym class="acronym">GiST</acronym> access method up and running
+ is to implement several user-defined methods, which define the behavior of
+ keys in the tree. Of course these methods have to be pretty fancy to
+ support fancy queries, but for all the standard queries (B-trees,
+ R-trees, etc.) they're relatively straightforward. In short,
+ <acronym class="acronym">GiST</acronym> combines extensibility along with generality, code
+ reuse, and a clean interface.
+ </p><p>
+ There are five methods that an index operator class for
+ <acronym class="acronym">GiST</acronym> must provide, and six that are optional.
+ Correctness of the index is ensured
+ by proper implementation of the <code class="function">same</code>, <code class="function">consistent</code>
+ and <code class="function">union</code> methods, while efficiency (size and speed) of the
+ index will depend on the <code class="function">penalty</code> and <code class="function">picksplit</code>
+ methods.
+ Two optional methods are <code class="function">compress</code> and
+ <code class="function">decompress</code>, which allow an index to have internal tree data of
+ a different type than the data it indexes. The leaves are to be of the
+ indexed data type, while the other tree nodes can be of any C struct (but
+ you still have to follow <span class="productname">PostgreSQL</span> data type rules here,
+ see about <code class="literal">varlena</code> for variable sized data). If the tree's
+ internal data type exists at the SQL level, the <code class="literal">STORAGE</code> option
+ of the <code class="command">CREATE OPERATOR CLASS</code> command can be used.
+ The optional eighth method is <code class="function">distance</code>, which is needed
+ if the operator class wishes to support ordered scans (nearest-neighbor
+ searches). The optional ninth method <code class="function">fetch</code> is needed if the
+ operator class wishes to support index-only scans, except when the
+ <code class="function">compress</code> method is omitted. The optional tenth method
+ <code class="function">options</code> is needed if the operator class has
+ user-specified parameters.
+ The optional eleventh method <code class="function">sortsupport</code> is used to
+ speed up building a <acronym class="acronym">GiST</acronym> index.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">consistent</code></span></dt><dd><p>
+ Given an index entry <code class="literal">p</code> and a query value <code class="literal">q</code>,
+ this function determines whether the index entry is
+ <span class="quote">“<span class="quote">consistent</span>”</span> with the query; that is, could the predicate
+ <span class="quote">“<span class="quote"><em class="replaceable"><code>indexed_column</code></em>
+ <em class="replaceable"><code>indexable_operator</code></em> <code class="literal">q</code></span>”</span> be true for
+ any row represented by the index entry? For a leaf index entry this is
+ equivalent to testing the indexable condition, while for an internal
+ tree node this determines whether it is necessary to scan the subtree
+ of the index represented by the tree node. When the result is
+ <code class="literal">true</code>, a <code class="literal">recheck</code> flag must also be returned.
+ This indicates whether the predicate is certainly true or only possibly
+ true. If <code class="literal">recheck</code> = <code class="literal">false</code> then the index has
+ tested the predicate condition exactly, whereas if <code class="literal">recheck</code>
+ = <code class="literal">true</code> the row is only a candidate match. In that case the
+ system will automatically evaluate the
+ <em class="replaceable"><code>indexable_operator</code></em> against the actual row value to see
+ if it is really a match. This convention allows
+ <acronym class="acronym">GiST</acronym> to support both lossless and lossy index
+ structures.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_consistent(internal, data_type, smallint, oid, internal)
+RETURNS bool
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_consistent);
+
+Datum
+my_consistent(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ data_type *query = PG_GETARG_DATA_TYPE_P(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+ /* Oid subtype = PG_GETARG_OID(3); */
+ bool *recheck = (bool *) PG_GETARG_POINTER(4);
+ data_type *key = DatumGetDataType(entry-&gt;key);
+ bool retval;
+
+ /*
+ * determine return value as a function of strategy, key and query.
+ *
+ * Use GIST_LEAF(entry) to know where you're called in the index tree,
+ * which comes handy when supporting the = operator for example (you could
+ * check for non empty union() in non-leaf nodes and equality in leaf
+ * nodes).
+ */
+
+ *recheck = true; /* or false if check is exact */
+
+ PG_RETURN_BOOL(retval);
+}
+</pre><p>
+
+ Here, <code class="varname">key</code> is an element in the index and <code class="varname">query</code>
+ the value being looked up in the index. The <code class="literal">StrategyNumber</code>
+ parameter indicates which operator of your operator class is being
+ applied — it matches one of the operator numbers in the
+ <code class="command">CREATE OPERATOR CLASS</code> command.
+ </p><p>
+ Depending on which operators you have included in the class, the data
+ type of <code class="varname">query</code> could vary with the operator, since it will
+ be whatever type is on the right-hand side of the operator, which might
+ be different from the indexed data type appearing on the left-hand side.
+ (The above code skeleton assumes that only one type is possible; if
+ not, fetching the <code class="varname">query</code> argument value would have to depend
+ on the operator.) It is recommended that the SQL declaration of
+ the <code class="function">consistent</code> function use the opclass's indexed data
+ type for the <code class="varname">query</code> argument, even though the actual type
+ might be something else depending on the operator.
+ </p></dd><dt><span class="term"><code class="function">union</code></span></dt><dd><p>
+ This method consolidates information in the tree. Given a set of
+ entries, this function generates a new index entry that represents
+ all the given entries.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_union(internal, internal)
+RETURNS storage_type
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_union);
+
+Datum
+my_union(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GISTENTRY *ent = entryvec-&gt;vector;
+ data_type *out,
+ *tmp,
+ *old;
+ int numranges,
+ i = 0;
+
+ numranges = entryvec-&gt;n;
+ tmp = DatumGetDataType(ent[0].key);
+ out = tmp;
+
+ if (numranges == 1)
+ {
+ out = data_type_deep_copy(tmp);
+
+ PG_RETURN_DATA_TYPE_P(out);
+ }
+
+ for (i = 1; i &lt; numranges; i++)
+ {
+ old = out;
+ tmp = DatumGetDataType(ent[i].key);
+ out = my_union_implementation(out, tmp);
+ }
+
+ PG_RETURN_DATA_TYPE_P(out);
+}
+</pre><p>
+ </p><p>
+ As you can see, in this skeleton we're dealing with a data type
+ where <code class="literal">union(X, Y, Z) = union(union(X, Y), Z)</code>. It's easy
+ enough to support data types where this is not the case, by
+ implementing the proper union algorithm in this
+ <acronym class="acronym">GiST</acronym> support method.
+ </p><p>
+ The result of the <code class="function">union</code> function must be a value of the
+ index's storage type, whatever that is (it might or might not be
+ different from the indexed column's type). The <code class="function">union</code>
+ function should return a pointer to newly <code class="function">palloc()</code>ed
+ memory. You can't just return the input value as-is, even if there is
+ no type change.
+ </p><p>
+ As shown above, the <code class="function">union</code> function's
+ first <code class="type">internal</code> argument is actually
+ a <code class="structname">GistEntryVector</code> pointer. The second argument is a
+ pointer to an integer variable, which can be ignored. (It used to be
+ required that the <code class="function">union</code> function store the size of its
+ result value into that variable, but this is no longer necessary.)
+ </p></dd><dt><span class="term"><code class="function">compress</code></span></dt><dd><p>
+ Converts a data item into a format suitable for physical storage in
+ an index page.
+ If the <code class="function">compress</code> method is omitted, data items are stored
+ in the index without modification.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_compress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_compress);
+
+Datum
+my_compress(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *retval;
+
+ if (entry-&gt;leafkey)
+ {
+ /* replace entry-&gt;key with a compressed version */
+ compressed_data_type *compressed_data = palloc(sizeof(compressed_data_type));
+
+ /* fill *compressed_data from entry-&gt;key ... */
+
+ retval = palloc(sizeof(GISTENTRY));
+ gistentryinit(*retval, PointerGetDatum(compressed_data),
+ entry-&gt;rel, entry-&gt;page, entry-&gt;offset, FALSE);
+ }
+ else
+ {
+ /* typically we needn't do anything with non-leaf entries */
+ retval = entry;
+ }
+
+ PG_RETURN_POINTER(retval);
+}
+</pre><p>
+ </p><p>
+ You have to adapt <em class="replaceable"><code>compressed_data_type</code></em> to the specific
+ type you're converting to in order to compress your leaf nodes, of
+ course.
+ </p></dd><dt><span class="term"><code class="function">decompress</code></span></dt><dd><p>
+ Converts the stored representation of a data item into a format that
+ can be manipulated by the other GiST methods in the operator class.
+ If the <code class="function">decompress</code> method is omitted, it is assumed that
+ the other GiST methods can work directly on the stored data format.
+ (<code class="function">decompress</code> is not necessarily the reverse of
+ the <code class="function">compress</code> method; in particular,
+ if <code class="function">compress</code> is lossy then it's impossible
+ for <code class="function">decompress</code> to exactly reconstruct the original
+ data. <code class="function">decompress</code> is not necessarily equivalent
+ to <code class="function">fetch</code>, either, since the other GiST methods might not
+ require full reconstruction of the data.)
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_decompress(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_decompress);
+
+Datum
+my_decompress(PG_FUNCTION_ARGS)
+{
+ PG_RETURN_POINTER(PG_GETARG_POINTER(0));
+}
+</pre><p>
+
+ The above skeleton is suitable for the case where no decompression
+ is needed. (But, of course, omitting the method altogether is even
+ easier, and is recommended in such cases.)
+ </p></dd><dt><span class="term"><code class="function">penalty</code></span></dt><dd><p>
+ Returns a value indicating the <span class="quote">“<span class="quote">cost</span>”</span> of inserting the new
+ entry into a particular branch of the tree. Items will be inserted
+ down the path of least <code class="function">penalty</code> in the tree.
+ Values returned by <code class="function">penalty</code> should be non-negative.
+ If a negative value is returned, it will be treated as zero.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_penalty(internal, internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT; -- in some cases penalty functions need not be strict
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_penalty);
+
+Datum
+my_penalty(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
+ float *penalty = (float *) PG_GETARG_POINTER(2);
+ data_type *orig = DatumGetDataType(origentry-&gt;key);
+ data_type *new = DatumGetDataType(newentry-&gt;key);
+
+ *penalty = my_penalty_implementation(orig, new);
+ PG_RETURN_POINTER(penalty);
+}
+</pre><p>
+
+ For historical reasons, the <code class="function">penalty</code> function doesn't
+ just return a <code class="type">float</code> result; instead it has to store the value
+ at the location indicated by the third argument. The return
+ value per se is ignored, though it's conventional to pass back the
+ address of that argument.
+ </p><p>
+ The <code class="function">penalty</code> function is crucial to good performance of
+ the index. It'll get used at insertion time to determine which branch
+ to follow when choosing where to add the new entry in the tree. At
+ query time, the more balanced the index, the quicker the lookup.
+ </p></dd><dt><span class="term"><code class="function">picksplit</code></span></dt><dd><p>
+ When an index page split is necessary, this function decides which
+ entries on the page are to stay on the old page, and which are to move
+ to the new page.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_picksplit(internal, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_picksplit);
+
+Datum
+my_picksplit(PG_FUNCTION_ARGS)
+{
+ GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
+ GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
+ OffsetNumber maxoff = entryvec-&gt;n - 1;
+ GISTENTRY *ent = entryvec-&gt;vector;
+ int i,
+ nbytes;
+ OffsetNumber *left,
+ *right;
+ data_type *tmp_union;
+ data_type *unionL;
+ data_type *unionR;
+ GISTENTRY **raw_entryvec;
+
+ maxoff = entryvec-&gt;n - 1;
+ nbytes = (maxoff + 1) * sizeof(OffsetNumber);
+
+ v-&gt;spl_left = (OffsetNumber *) palloc(nbytes);
+ left = v-&gt;spl_left;
+ v-&gt;spl_nleft = 0;
+
+ v-&gt;spl_right = (OffsetNumber *) palloc(nbytes);
+ right = v-&gt;spl_right;
+ v-&gt;spl_nright = 0;
+
+ unionL = NULL;
+ unionR = NULL;
+
+ /* Initialize the raw entry vector. */
+ raw_entryvec = (GISTENTRY **) malloc(entryvec-&gt;n * sizeof(void *));
+ for (i = FirstOffsetNumber; i &lt;= maxoff; i = OffsetNumberNext(i))
+ raw_entryvec[i] = &amp;(entryvec-&gt;vector[i]);
+
+ for (i = FirstOffsetNumber; i &lt;= maxoff; i = OffsetNumberNext(i))
+ {
+ int real_index = raw_entryvec[i] - entryvec-&gt;vector;
+
+ tmp_union = DatumGetDataType(entryvec-&gt;vector[real_index].key);
+ Assert(tmp_union != NULL);
+
+ /*
+ * Choose where to put the index entries and update unionL and unionR
+ * accordingly. Append the entries to either v-&gt;spl_left or
+ * v-&gt;spl_right, and care about the counters.
+ */
+
+ if (my_choice_is_left(unionL, curl, unionR, curr))
+ {
+ if (unionL == NULL)
+ unionL = tmp_union;
+ else
+ unionL = my_union_implementation(unionL, tmp_union);
+
+ *left = real_index;
+ ++left;
+ ++(v-&gt;spl_nleft);
+ }
+ else
+ {
+ /*
+ * Same on the right
+ */
+ }
+ }
+
+ v-&gt;spl_ldatum = DataTypeGetDatum(unionL);
+ v-&gt;spl_rdatum = DataTypeGetDatum(unionR);
+ PG_RETURN_POINTER(v);
+}
+</pre><p>
+
+ Notice that the <code class="function">picksplit</code> function's result is delivered
+ by modifying the passed-in <code class="structname">v</code> structure. The return
+ value per se is ignored, though it's conventional to pass back the
+ address of <code class="structname">v</code>.
+ </p><p>
+ Like <code class="function">penalty</code>, the <code class="function">picksplit</code> function
+ is crucial to good performance of the index. Designing suitable
+ <code class="function">penalty</code> and <code class="function">picksplit</code> implementations
+ is where the challenge of implementing well-performing
+ <acronym class="acronym">GiST</acronym> indexes lies.
+ </p></dd><dt><span class="term"><code class="function">same</code></span></dt><dd><p>
+ Returns true if two index entries are identical, false otherwise.
+ (An <span class="quote">“<span class="quote">index entry</span>”</span> is a value of the index's storage type,
+ not necessarily the original indexed column's type.)
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_same(storage_type, storage_type, internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_same);
+
+Datum
+my_same(PG_FUNCTION_ARGS)
+{
+ prefix_range *v1 = PG_GETARG_PREFIX_RANGE_P(0);
+ prefix_range *v2 = PG_GETARG_PREFIX_RANGE_P(1);
+ bool *result = (bool *) PG_GETARG_POINTER(2);
+
+ *result = my_eq(v1, v2);
+ PG_RETURN_POINTER(result);
+}
+</pre><p>
+
+ For historical reasons, the <code class="function">same</code> function doesn't
+ just return a Boolean result; instead it has to store the flag
+ at the location indicated by the third argument. The return
+ value per se is ignored, though it's conventional to pass back the
+ address of that argument.
+ </p></dd><dt><span class="term"><code class="function">distance</code></span></dt><dd><p>
+ Given an index entry <code class="literal">p</code> and a query value <code class="literal">q</code>,
+ this function determines the index entry's
+ <span class="quote">“<span class="quote">distance</span>”</span> from the query value. This function must be
+ supplied if the operator class contains any ordering operators.
+ A query using the ordering operator will be implemented by returning
+ index entries with the smallest <span class="quote">“<span class="quote">distance</span>”</span> values first,
+ so the results must be consistent with the operator's semantics.
+ For a leaf index entry the result just represents the distance to
+ the index entry; for an internal tree node, the result must be the
+ smallest distance that any child entry could have.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_distance(internal, data_type, smallint, oid, internal)
+RETURNS float8
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ And the matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_distance);
+
+Datum
+my_distance(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ data_type *query = PG_GETARG_DATA_TYPE_P(1);
+ StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
+ /* Oid subtype = PG_GETARG_OID(3); */
+ /* bool *recheck = (bool *) PG_GETARG_POINTER(4); */
+ data_type *key = DatumGetDataType(entry-&gt;key);
+ double retval;
+
+ /*
+ * determine return value as a function of strategy, key and query.
+ */
+
+ PG_RETURN_FLOAT8(retval);
+}
+</pre><p>
+
+ The arguments to the <code class="function">distance</code> function are identical to
+ the arguments of the <code class="function">consistent</code> function.
+ </p><p>
+ Some approximation is allowed when determining the distance, so long
+ as the result is never greater than the entry's actual distance. Thus,
+ for example, distance to a bounding box is usually sufficient in
+ geometric applications. For an internal tree node, the distance
+ returned must not be greater than the distance to any of the child
+ nodes. If the returned distance is not exact, the function must set
+ <code class="literal">*recheck</code> to true. (This is not necessary for internal tree
+ nodes; for them, the calculation is always assumed to be inexact.) In
+ this case the executor will calculate the accurate distance after
+ fetching the tuple from the heap, and reorder the tuples if necessary.
+ </p><p>
+ If the distance function returns <code class="literal">*recheck = true</code> for any
+ leaf node, the original ordering operator's return type must
+ be <code class="type">float8</code> or <code class="type">float4</code>, and the distance function's
+ result values must be comparable to those of the original ordering
+ operator, since the executor will sort using both distance function
+ results and recalculated ordering-operator results. Otherwise, the
+ distance function's result values can be any finite <code class="type">float8</code>
+ values, so long as the relative order of the result values matches the
+ order returned by the ordering operator. (Infinity and minus infinity
+ are used internally to handle cases such as nulls, so it is not
+ recommended that <code class="function">distance</code> functions return these values.)
+ </p></dd><dt><span class="term"><code class="function">fetch</code></span></dt><dd><p>
+ Converts the compressed index representation of a data item into the
+ original data type, for index-only scans. The returned data must be an
+ exact, non-lossy copy of the originally indexed value.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_fetch(internal)
+RETURNS internal
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ The argument is a pointer to a <code class="structname">GISTENTRY</code> struct. On
+ entry, its <code class="structfield">key</code> field contains a non-NULL leaf datum in
+ compressed form. The return value is another <code class="structname">GISTENTRY</code>
+ struct, whose <code class="structfield">key</code> field contains the same datum in its
+ original, uncompressed form. If the opclass's compress function does
+ nothing for leaf entries, the <code class="function">fetch</code> method can return the
+ argument as-is. Or, if the opclass does not have a compress function,
+ the <code class="function">fetch</code> method can be omitted as well, since it would
+ necessarily be a no-op.
+ </p><p>
+ The matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_fetch);
+
+Datum
+my_fetch(PG_FUNCTION_ARGS)
+{
+ GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
+ input_data_type *in = DatumGetPointer(entry-&gt;key);
+ fetched_data_type *fetched_data;
+ GISTENTRY *retval;
+
+ retval = palloc(sizeof(GISTENTRY));
+ fetched_data = palloc(sizeof(fetched_data_type));
+
+ /*
+ * Convert 'fetched_data' into the a Datum of the original datatype.
+ */
+
+ /* fill *retval from fetched_data. */
+ gistentryinit(*retval, PointerGetDatum(converted_datum),
+ entry-&gt;rel, entry-&gt;page, entry-&gt;offset, FALSE);
+
+ PG_RETURN_POINTER(retval);
+}
+</pre><p>
+ </p><p>
+ If the compress method is lossy for leaf entries, the operator class
+ cannot support index-only scans, and must not define
+ a <code class="function">fetch</code> function.
+ </p></dd><dt><span class="term"><code class="function">options</code></span></dt><dd><p>
+ Allows definition of user-visible parameters that control operator
+ class behavior.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_options(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+ </p><p>
+ The function is passed a pointer to a <code class="structname">local_relopts</code>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using the <code class="literal">PG_HAS_OPCLASS_OPTIONS()</code> and
+ <code class="literal">PG_GET_OPCLASS_OPTIONS()</code> macros.
+ </p><p>
+ An example implementation of my_options() and parameters use
+ from other support functions are given below:
+
+</p><pre class="programlisting">
+typedef enum MyEnumType
+{
+ MY_ENUM_ON,
+ MY_ENUM_OFF,
+ MY_ENUM_AUTO
+} MyEnumType;
+
+typedef struct
+{
+ int32 vl_len_; /* varlena header (do not touch directly!) */
+ int int_param; /* integer parameter */
+ double real_param; /* real parameter */
+ MyEnumType enum_param; /* enum parameter */
+ int str_param; /* string parameter */
+} MyOptionsStruct;
+
+/* String representation of enum values */
+static relopt_enum_elt_def myEnumValues[] =
+{
+ {"on", MY_ENUM_ON},
+ {"off", MY_ENUM_OFF},
+ {"auto", MY_ENUM_AUTO},
+ {(const char *) NULL} /* list terminator */
+};
+
+static char *str_param_default = "default";
+
+/*
+ * Sample validator: checks that string is not longer than 8 bytes.
+ */
+static void
+validate_my_string_relopt(const char *value)
+{
+ if (strlen(value) &gt; 8)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("str_param must be at most 8 bytes")));
+}
+
+/*
+ * Sample filler: switches characters to lower case.
+ */
+static Size
+fill_my_string_relopt(const char *value, void *ptr)
+{
+ char *tmp = str_tolower(value, strlen(value), DEFAULT_COLLATION_OID);
+ int len = strlen(tmp);
+
+ if (ptr)
+ strcpy((char *) ptr, tmp);
+
+ pfree(tmp);
+ return len + 1;
+}
+
+PG_FUNCTION_INFO_V1(my_options);
+
+Datum
+my_options(PG_FUNCTION_ARGS)
+{
+ local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0);
+
+ init_local_reloptions(relopts, sizeof(MyOptionsStruct));
+ add_local_int_reloption(relopts, "int_param", "integer parameter",
+ 100, 0, 1000000,
+ offsetof(MyOptionsStruct, int_param));
+ add_local_real_reloption(relopts, "real_param", "real parameter",
+ 1.0, 0.0, 1000000.0,
+ offsetof(MyOptionsStruct, real_param));
+ add_local_enum_reloption(relopts, "enum_param", "enum parameter",
+ myEnumValues, MY_ENUM_ON,
+ "Valid values are: \"on\", \"off\" and \"auto\".",
+ offsetof(MyOptionsStruct, enum_param));
+ add_local_string_reloption(relopts, "str_param", "string parameter",
+ str_param_default,
+ &amp;validate_my_string_relopt,
+ &amp;fill_my_string_relopt,
+ offsetof(MyOptionsStruct, str_param));
+
+ PG_RETURN_VOID();
+}
+
+PG_FUNCTION_INFO_V1(my_compress);
+
+Datum
+my_compress(PG_FUNCTION_ARGS)
+{
+ int int_param = 100;
+ double real_param = 1.0;
+ MyEnumType enum_param = MY_ENUM_ON;
+ char *str_param = str_param_default;
+
+ /*
+ * Normally, when opclass contains 'options' method, then options are always
+ * passed to support functions. However, if you add 'options' method to
+ * existing opclass, previously defined indexes have no options, so the
+ * check is required.
+ */
+ if (PG_HAS_OPCLASS_OPTIONS())
+ {
+ MyOptionsStruct *options = (MyOptionsStruct *) PG_GET_OPCLASS_OPTIONS();
+
+ int_param = options-&gt;int_param;
+ real_param = options-&gt;real_param;
+ enum_param = options-&gt;enum_param;
+ str_param = GET_STRING_RELOPTION(options, str_param);
+ }
+
+ /* the rest implementation of support function */
+}
+
+</pre><p>
+ </p><p>
+ Since the representation of the key in <acronym class="acronym">GiST</acronym> is
+ flexible, it may depend on user-specified parameters. For instance,
+ the length of key signature may be specified. See
+ <code class="literal">gtsvector_options()</code> for example.
+ </p></dd><dt><span class="term"><code class="function">sortsupport</code></span></dt><dd><p>
+ Returns a comparator function to sort data in a way that preserves
+ locality. It is used by <code class="command">CREATE INDEX</code> and
+ <code class="command">REINDEX</code> commands. The quality of the created index
+ depends on how well the sort order determined by the comparator function
+ preserves locality of the inputs.
+ </p><p>
+ The <code class="function">sortsupport</code> method is optional. If it is not
+ provided, <code class="command">CREATE INDEX</code> builds the index by inserting
+ each tuple to the tree using the <code class="function">penalty</code> and
+ <code class="function">picksplit</code> functions, which is much slower.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like
+ this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_sortsupport(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+
+ The argument is a pointer to a <code class="structname">SortSupport</code>
+ struct. At a minimum, the function must fill in its comparator field.
+ The comparator takes three arguments: two Datums to compare, and
+ a pointer to the <code class="structname">SortSupport</code> struct. The
+ Datums are the two indexed values in the format that they are stored
+ in the index; that is, in the format returned by the
+ <code class="function">compress</code> method. The full API is defined in
+ <code class="filename">src/include/utils/sortsupport.h</code>.
+ </p><p>
+ The matching code in the C module could then follow this skeleton:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(my_sortsupport);
+
+static int
+my_fastcmp(Datum x, Datum y, SortSupport ssup)
+{
+ /* establish order between x and y by computing some sorting value z */
+
+ int z1 = ComputeSpatialCode(x);
+ int z2 = ComputeSpatialCode(y);
+
+ return z1 == z2 ? 0 : z1 &gt; z2 ? 1 : -1;
+}
+
+Datum
+my_sortsupport(PG_FUNCTION_ARGS)
+{
+ SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0);
+
+ ssup-&gt;comparator = my_fastcmp;
+ PG_RETURN_VOID();
+}
+</pre><p>
+ </p></dd></dl></div><p>
+ All the GiST support methods are normally called in short-lived memory
+ contexts; that is, <code class="varname">CurrentMemoryContext</code> will get reset after
+ each tuple is processed. It is therefore not very important to worry about
+ pfree'ing everything you palloc. However, in some cases it's useful for a
+ support method to cache data across repeated calls. To do that, allocate
+ the longer-lived data in <code class="literal">fcinfo-&gt;flinfo-&gt;fn_mcxt</code>, and
+ keep a pointer to it in <code class="literal">fcinfo-&gt;flinfo-&gt;fn_extra</code>. Such
+ data will survive for the life of the index operation (e.g., a single GiST
+ index scan, index build, or index tuple insertion). Be careful to pfree
+ the previous value when replacing a <code class="literal">fn_extra</code> value, or the leak
+ will accumulate for the duration of the operation.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gist-builtin-opclasses.html" title="68.2. Built-in Operator Classes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gist-implementation.html" title="68.4. Implementation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.2. Built-in Operator Classes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 68.4. Implementation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gist-implementation.html b/doc/src/sgml/html/gist-implementation.html
new file mode 100644
index 0000000..92e1544
--- /dev/null
+++ b/doc/src/sgml/html/gist-implementation.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>68.4. Implementation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gist-extensibility.html" title="68.3. Extensibility" /><link rel="next" href="gist-examples.html" title="68.5. Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">68.4. Implementation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gist-extensibility.html" title="68.3. Extensibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 68. GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gist-examples.html" title="68.5. Examples">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIST-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.4. Implementation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="gist-implementation.html#GIST-BUFFERING-BUILD">68.4.1. GiST Index Build Methods</a></span></dt></dl></div><div class="sect2" id="GIST-BUFFERING-BUILD"><div class="titlepage"><div><div><h3 class="title">68.4.1. GiST Index Build Methods</h3></div></div></div><p>
+ The simplest way to build a GiST index is just to insert all the entries,
+ one by one. This tends to be slow for large indexes, because if the
+ index tuples are scattered across the index and the index is large enough
+ to not fit in cache, a lot of random I/O will be
+ needed. <span class="productname">PostgreSQL</span> supports two alternative
+ methods for initial build of a GiST index: <em class="firstterm">sorted</em>
+ and <em class="firstterm">buffered</em> modes.
+ </p><p>
+ The sorted method is only available if each of the opclasses used by the
+ index provides a <code class="function">sortsupport</code> function, as described
+ in <a class="xref" href="gist-extensibility.html" title="68.3. Extensibility">Section 68.3</a>. If they do, this method is
+ usually the best, so it is used by default.
+ </p><p>
+ The buffered method works by not inserting tuples directly into the index
+ right away. It can dramatically reduce the amount of random I/O needed
+ for non-ordered data sets. For well-ordered data sets the benefit is
+ smaller or non-existent, because only a small number of pages receive new
+ tuples at a time, and those pages fit in cache even if the index as a
+ whole does not.
+ </p><p>
+ The buffered method needs to call the <code class="function">penalty</code>
+ function more often than the simple method does, which consumes some
+ extra CPU resources. Also, the buffers need temporary disk space, up to
+ the size of the resulting index. Buffering can also influence the quality
+ of the resulting index, in both positive and negative directions. That
+ influence depends on various factors, like the distribution of the input
+ data and the operator class implementation.
+ </p><p>
+ If sorting is not possible, then by default a GiST index build switches
+ to the buffering method when the index size reaches
+ <a class="xref" href="runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE">effective_cache_size</a>. Buffering can be manually
+ forced or prevented by the <code class="literal">buffering</code> parameter to the
+ CREATE INDEX command. The default behavior is good for most cases, but
+ turning buffering off might speed up the build somewhat if the input data
+ is ordered.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gist-extensibility.html" title="68.3. Extensibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gist-examples.html" title="68.5. Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.3. Extensibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 68.5. Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gist-intro.html b/doc/src/sgml/html/gist-intro.html
new file mode 100644
index 0000000..6ca6da6
--- /dev/null
+++ b/doc/src/sgml/html/gist-intro.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>68.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gist.html" title="Chapter 68. GiST Indexes" /><link rel="next" href="gist-builtin-opclasses.html" title="68.2. Built-in Operator Classes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">68.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gist.html" title="Chapter 68. GiST Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 68. GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gist-builtin-opclasses.html" title="68.2. Built-in Operator Classes">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIST-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.1. Introduction</h2></div></div></div><p>
+ <acronym class="acronym">GiST</acronym> stands for Generalized Search Tree. It is a
+ balanced, tree-structured access method, that acts as a base template in
+ which to implement arbitrary indexing schemes. B-trees, R-trees and many
+ other indexing schemes can be implemented in <acronym class="acronym">GiST</acronym>.
+ </p><p>
+ One advantage of <acronym class="acronym">GiST</acronym> is that it allows the development
+ of custom data types with the appropriate access methods, by
+ an expert in the domain of the data type, rather than a database expert.
+ </p><p>
+ Some of the information here is derived from the University of California
+ at Berkeley's GiST Indexing Project
+ <a class="ulink" href="http://gist.cs.berkeley.edu/" target="_top">web site</a> and
+ Marcel Kornacker's thesis,
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/papers/concurrency/access-methods-for-next-generation.pdf.gz" target="_top">
+ Access Methods for Next-Generation Database Systems</a>.
+ The <acronym class="acronym">GiST</acronym>
+ implementation in <span class="productname">PostgreSQL</span> is primarily
+ maintained by Teodor Sigaev and Oleg Bartunov, and there is more
+ information on their
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/" target="_top">web site</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gist.html" title="Chapter 68. GiST Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="gist.html" title="Chapter 68. GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gist-builtin-opclasses.html" title="68.2. Built-in Operator Classes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 68. GiST Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 68.2. Built-in Operator Classes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gist.html b/doc/src/sgml/html/gist.html
new file mode 100644
index 0000000..de6a434
--- /dev/null
+++ b/doc/src/sgml/html/gist.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 68. GiST Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="btree-implementation.html" title="67.4. Implementation" /><link rel="next" href="gist-intro.html" title="68.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 68. GiST Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="btree-implementation.html" title="67.4. Implementation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gist-intro.html" title="68.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="GIST"><div class="titlepage"><div><div><h2 class="title">Chapter 68. GiST Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="gist-intro.html">68.1. Introduction</a></span></dt><dt><span class="sect1"><a href="gist-builtin-opclasses.html">68.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="gist-extensibility.html">68.3. Extensibility</a></span></dt><dt><span class="sect1"><a href="gist-implementation.html">68.4. Implementation</a></span></dt><dd><dl><dt><span class="sect2"><a href="gist-implementation.html#GIST-BUFFERING-BUILD">68.4.1. GiST Index Build Methods</a></span></dt></dl></dd><dt><span class="sect1"><a href="gist-examples.html">68.5. Examples</a></span></dt></dl></div><a id="id-1.10.19.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="btree-implementation.html" title="67.4. Implementation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gist-intro.html" title="68.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">67.4. Implementation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 68.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/git.html b/doc/src/sgml/html/git.html
new file mode 100644
index 0000000..1aa2f45
--- /dev/null
+++ b/doc/src/sgml/html/git.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>I.1. Getting the Source via Git</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sourcerepo.html" title="Appendix I. The Source Code Repository" /><link rel="next" href="docguide.html" title="Appendix J. Documentation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">I.1. Getting the Source via <span class="productname">Git</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sourcerepo.html" title="Appendix I. The Source Code Repository">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sourcerepo.html" title="Appendix I. The Source Code Repository">Up</a></td><th width="60%" align="center">Appendix I. The Source Code Repository</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="docguide.html" title="Appendix J. Documentation">Next</a></td></tr></table><hr /></div><div class="sect1" id="GIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">I.1. Getting the Source via <span class="productname">Git</span></h2></div></div></div><p>
+ With <span class="productname">Git</span> you will make a copy of the entire code repository
+ on your local machine, so you will have access to all history and branches
+ offline. This is the fastest and most flexible way to develop or test
+ patches.
+ </p><div class="procedure" id="id-1.11.10.5.3"><p class="title"><strong>Git</strong></p><ol class="procedure" type="1"><li class="step"><p>
+ You will need an installed version of <span class="productname">Git</span>, which you can
+ get from <a class="ulink" href="https://git-scm.com" target="_top">https://git-scm.com</a>. Many systems already
+ have a recent version of <span class="application">Git</span> installed by default, or
+ available in their package distribution system.
+ </p></li><li class="step"><p>
+ To begin using the Git repository, make a clone of the official mirror:
+
+</p><pre class="programlisting">
+git clone https://git.postgresql.org/git/postgresql.git
+</pre><p>
+
+ This will copy the full repository to your local machine, so it may take
+ a while to complete, especially if you have a slow Internet connection.
+ The files will be placed in a new subdirectory <code class="filename">postgresql</code> of
+ your current directory.
+ </p><p>
+ The Git mirror can also be reached via the Git protocol. Just change the URL
+ prefix to <code class="literal">git</code>, as in:
+
+</p><pre class="programlisting">
+git clone git://git.postgresql.org/git/postgresql.git
+</pre><p>
+
+ </p></li><li class="step"><p>
+ Whenever you want to get the latest updates in the system, <code class="command">cd</code>
+ into the repository, and run:
+
+</p><pre class="programlisting">
+git fetch
+</pre><p>
+ </p></li></ol></div><p>
+ <span class="productname">Git</span> can do a lot more things than just fetch the source. For
+ more information, consult the <span class="productname">Git</span> man pages, or see the
+ website at <a class="ulink" href="https://git-scm.com" target="_top">https://git-scm.com</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sourcerepo.html" title="Appendix I. The Source Code Repository">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sourcerepo.html" title="Appendix I. The Source Code Repository">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="docguide.html" title="Appendix J. Documentation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix I. The Source Code Repository </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix J. Documentation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/glossary.html b/doc/src/sgml/html/glossary.html
new file mode 100644
index 0000000..909b6fd
--- /dev/null
+++ b/doc/src/sgml/html/glossary.html
@@ -0,0 +1,1061 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix M. Glossary</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="acronyms.html" title="Appendix L. Acronyms" /><link rel="next" href="color.html" title="Appendix N. Color Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix M. Glossary</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="acronyms.html" title="Appendix L. Acronyms">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="color.html" title="Appendix N. Color Support">Next</a></td></tr></table><hr /></div><div class="appendix" id="GLOSSARY"><div class="titlepage"><div><div><h2 class="title">Appendix M. Glossary</h2></div></div></div><p>
+ This is a list of terms and their meaning in the context of
+ <span class="productname">PostgreSQL</span> and relational database
+ systems in general.
+ </p><div class="glosslist"><dl><dt id="GLOSSARY-ACID"><span class="glossterm">ACID</span></dt><dd class="glossdef"><p>
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATOMICITY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATOMICITY" title="Atomicity">Atomicity</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-CONSISTENCY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONSISTENCY" title="Consistency">Consistency</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-ISOLATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ISOLATION" title="Isolation">Isolation</a></em></a>, and
+ <a class="glossterm" href="glossary.html#GLOSSARY-DURABILITY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DURABILITY" title="Durability">Durability</a></em></a>.
+ This set of properties of database transactions is intended to
+ guarantee validity in concurrent operation and even in event of
+ errors, power failures, etc.
+ </p></dd><dt id="GLOSSARY-AGGREGATE"><span class="glossterm">Aggregate function (routine)</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION" title="Function (routine)">function</a></em></a> that
+ combines (<em class="firstterm">aggregates</em>) multiple input values,
+ for example by counting, averaging or adding,
+ yielding a single output value.
+ </p><p>
+ For more information, see
+ <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a>.
+ </p><p>See Also <a class="glossseealso" href="glossary.html#GLOSSARY-WINDOW-FUNCTION">Window function (routine)</a>.</p></dd><dt><span class="glossterm">Analytic function</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-WINDOW-FUNCTION">Window function (routine)</a>.</p></dd><dt id="GLOSSARY-ANALYZE"><span class="glossterm">Analyze (operation)</span></dt><dd class="glossdef"><p>
+ The act of collecting statistics from data in
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">tables</a></em></a>
+ and other <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relations</a></em></a>
+ to help the <a class="glossterm" href="glossary.html#GLOSSARY-PLANNER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PLANNER" title="Query planner">query planner</a></em></a>
+ to make decisions about how to execute
+ <a class="glossterm" href="glossary.html#GLOSSARY-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-QUERY" title="Query">queries</a></em></a>.
+ </p><p>
+ (Don't confuse this term with the <code class="literal">ANALYZE</code> option
+ to the <a class="xref" href="sql-explain.html" title="EXPLAIN"><span class="refentrytitle">EXPLAIN</span></a> command.)
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a>.
+ </p></dd><dt id="GLOSSARY-ATOMIC"><span class="glossterm">Atomic</span></dt><dd class="glossdef"><p>
+ In reference to a <a class="glossterm" href="glossary.html#GLOSSARY-DATUM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATUM" title="Datum">datum</a></em></a>:
+ the fact that its value cannot be broken down into smaller
+ components.
+ </p></dd><dd class="glossdef"><p>
+ In reference to a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">database transaction</a></em></a>:
+ see <a class="glossterm" href="glossary.html#GLOSSARY-ATOMICITY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATOMICITY" title="Atomicity">atomicity</a></em></a>.
+ </p></dd><dt id="GLOSSARY-ATOMICITY"><span class="glossterm">Atomicity</span></dt><dd class="glossdef"><p>
+ The property of a <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a>
+ that either all its operations complete as a single unit or none do.
+ In addition, if a system failure occurs during the execution of a
+ transaction, no partial results are visible after recovery.
+ This is one of the <acronym class="acronym">ACID</acronym> properties.
+ </p></dd><dt id="GLOSSARY-ATTRIBUTE"><span class="glossterm">Attribute</span></dt><dd class="glossdef"><p>
+ An element with a certain name and data type found within a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">tuple</a></em></a>.
+ </p></dd><dt id="GLOSSARY-AUTOVACUUM"><span class="glossterm">Autovacuum (process)</span></dt><dd class="glossdef"><p>
+ A set of background processes that routinely perform
+ <a class="glossterm" href="glossary.html#GLOSSARY-VACUUM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-VACUUM" title="Vacuum">vacuum</a></em></a>
+ and <a class="glossterm" href="glossary.html#GLOSSARY-ANALYZE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ANALYZE" title="Analyze (operation)">analyze</a></em></a> operations.
+ The <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ that coordinates the work and is always present (unless autovacuum
+ is disabled) is known as the <em class="firstterm">autovacuum launcher</em>,
+ and the processes that carry out the tasks are known as the
+ <em class="firstterm">autovacuum workers</em>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>.
+ </p></dd><dt id="GLOSSARY-AUXILIARY-PROC"><span class="glossterm">Auxiliary process</span></dt><dd class="glossdef"><p>
+ A process within an <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>
+ that is in charge of some specific background task for the instance.
+ The auxiliary processes consist of
+
+ the <a class="glossterm" href="glossary.html#GLOSSARY-AUTOVACUUM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUTOVACUUM" title="Autovacuum (process)">autovacuum launcher</a></em></a>
+ (but not the autovacuum workers),
+ the <a class="glossterm" href="glossary.html#GLOSSARY-BACKGROUND-WRITER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKGROUND-WRITER" title="Background writer (process)">background writer</a></em></a>,
+ the <a class="glossterm" href="glossary.html#GLOSSARY-CHECKPOINTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CHECKPOINTER" title="Checkpointer (process)">checkpointer</a></em></a>,
+ the <a class="glossterm" href="glossary.html#GLOSSARY-LOGGER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-LOGGER" title="Logger (process)">logger</a></em></a>,
+ the <a class="glossterm" href="glossary.html#GLOSSARY-STARTUP-PROCESS"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-STARTUP-PROCESS" title="Startup process">startup process</a></em></a>,
+ the <a class="glossterm" href="glossary.html#GLOSSARY-WAL-ARCHIVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-ARCHIVER" title="WAL archiver (process)">WAL archiver</a></em></a>,
+ the <a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECEIVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECEIVER" title="WAL receiver (process)">WAL receiver</a></em></a>
+ (but not the <a class="glossterm" href="glossary.html#GLOSSARY-WAL-SENDER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-SENDER" title="WAL sender (process)">WAL senders</a></em></a>),
+ and the <a class="glossterm" href="glossary.html#GLOSSARY-WAL-WRITER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-WRITER" title="WAL writer (process)">WAL writer</a></em></a>.
+ </p></dd><dt id="GLOSSARY-BACKEND"><span class="glossterm">Backend (process)</span></dt><dd class="glossdef"><p>
+ Process of an <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>
+ which acts on behalf of a <a class="glossterm" href="glossary.html#GLOSSARY-SESSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SESSION" title="Session">client session</a></em></a>
+ and handles its requests.
+ </p><p>
+ (Don't confuse this term with the similar terms
+ <a class="glossterm" href="glossary.html#GLOSSARY-BACKGROUND-WORKER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKGROUND-WORKER" title="Background worker (process)">Background Worker</a></em></a> or
+ <a class="glossterm" href="glossary.html#GLOSSARY-BACKGROUND-WRITER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKGROUND-WRITER" title="Background writer (process)">Background Writer</a></em></a>).
+ </p></dd><dt id="GLOSSARY-BACKGROUND-WORKER"><span class="glossterm">Background worker (process)</span></dt><dd class="glossdef"><p>
+ Process within an <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>,
+ which runs system- or user-supplied code.
+ Serves as infrastructure for several features in
+ <span class="productname">PostgreSQL</span>, such as
+ <a class="glossterm" href="glossary.html#GLOSSARY-REPLICATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICATION" title="Replication">logical replication</a></em></a>
+ and <a class="glossterm" href="glossary.html#GLOSSARY-PARALLEL-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PARALLEL-QUERY" title="Parallel query">parallel queries</a></em></a>.
+ In addition, <a class="glossterm" href="glossary.html#GLOSSARY-EXTENSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-EXTENSION" title="Extension">Extensions</a></em></a> can add
+ custom background worker processes.
+ </p><p>
+ For more information, see
+ <a class="xref" href="bgworker.html" title="Chapter 48. Background Worker Processes">Chapter 48</a>.
+ </p></dd><dt id="GLOSSARY-BACKGROUND-WRITER"><span class="glossterm">Background writer (process)</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ that writes dirty
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATA-PAGE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATA-PAGE" title="Data page">data pages</a></em></a> from
+ <a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY" title="Shared memory">shared memory</a></em></a> to
+ the file system. It wakes up periodically, but works only for a short
+ period in order to distribute its expensive <acronym class="acronym">I/O</acronym>
+ activity over time to avoid generating larger
+ <acronym class="acronym">I/O</acronym> peaks which could block other processes.
+ </p><p>
+ For more information, see
+ <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER" title="20.4.5. Background Writer">Section 20.4.5</a>.
+ </p></dd><dt id="GLOSSARY-BASEBACKUP"><span class="glossterm">Base Backup</span></dt><dd class="glossdef"><p>
+ A binary copy of all
+ <a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER" title="Database cluster">database cluster</a></em></a>
+ files. It is generated by the tool <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a>.
+ In combination with WAL files it can be used as the starting point
+ for recovery, log shipping, or streaming replication.
+ </p></dd><dt id="GLOSSARY-BLOAT"><span class="glossterm">Bloat</span></dt><dd class="glossdef"><p>
+ Space in data pages which does not contain current row versions,
+ such as unused (free) space or outdated row versions.
+ </p></dd><dt id="GLOSSARY-CAST"><span class="glossterm">Cast</span></dt><dd class="glossdef"><p>
+ A conversion of a <a class="glossterm" href="glossary.html#GLOSSARY-DATUM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATUM" title="Datum">datum</a></em></a>
+ from its current data type to another data type.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a>.
+ </p></dd><dt id="GLOSSARY-CATALOG"><span class="glossterm">Catalog</span></dt><dd class="glossdef"><p>
+ The <acronym class="acronym">SQL</acronym> standard uses this term to
+ indicate what is called a
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> in
+ <span class="productname">PostgreSQL</span>'s terminology.
+ </p><p>
+ (Don't confuse this term with
+ <a class="glossterm" href="glossary.html#GLOSSARY-SYSTEM-CATALOG"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SYSTEM-CATALOG" title="System catalog">system catalog</a></em></a>).
+ </p><p>
+ For more information, see
+ <a class="xref" href="manage-ag-overview.html" title="23.1. Overview">Section 23.1</a>.
+ </p></dd><dt id="GLOSSARY-CHECK-CONSTRAINT"><span class="glossterm">Check constraint</span></dt><dd class="glossdef"><p>
+ A type of <a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT" title="Constraint">constraint</a></em></a>
+ defined on a <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>
+ which restricts the values allowed in one or more
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attributes</a></em></a>. The
+ check constraint can make reference to any attribute of the same row in
+ the relation, but cannot reference other rows of the same relation or
+ other relations.
+ </p><p>
+ For more information, see
+ <a class="xref" href="ddl-constraints.html" title="5.4. Constraints">Section 5.4</a>.
+ </p></dd><dt id="GLOSSARY-CHECKPOINT"><span class="glossterm">Checkpoint</span></dt><dd class="glossdef"><p>
+ A point in the <a class="glossterm" href="glossary.html#GLOSSARY-WAL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL" title="Write-ahead log">WAL</a></em></a> sequence
+ at which it is guaranteed that the heap and index data files have been
+ updated with all information from
+ <a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY" title="Shared memory">shared memory</a></em></a>
+ modified before that checkpoint;
+ a <em class="firstterm">checkpoint record</em> is written and flushed to WAL
+ to mark that point.
+ </p><p>
+ A checkpoint is also the act of carrying out all the actions that
+ are necessary to reach a checkpoint as defined above.
+ This process is initiated when predefined conditions are met,
+ such as a specified amount of time has passed, or a certain volume
+ of records has been written; or it can be invoked by the user
+ with the command <code class="command">CHECKPOINT</code>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a>.
+ </p></dd><dt id="GLOSSARY-CHECKPOINTER"><span class="glossterm">Checkpointer (process)</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ that is responsible for executing
+ <a class="glossterm" href="glossary.html#GLOSSARY-CHECKPOINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CHECKPOINT" title="Checkpoint">checkpoints</a></em></a>.
+ </p></dd><dt><span class="glossterm">Class (archaic)</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-RELATION">Relation</a>.</p></dd><dt id="GLOSSARY-CLIENT"><span class="glossterm">Client (process)</span></dt><dd class="glossdef"><p>
+ Any process, possibly remote, that establishes a
+ <a class="glossterm" href="glossary.html#GLOSSARY-SESSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SESSION" title="Session">session</a></em></a>
+ by <a class="glossterm" href="glossary.html#GLOSSARY-CONNECTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONNECTION" title="Connection">connecting</a></em></a> to an
+ <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>
+ to interact with a <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>.
+ </p></dd><dt id="GLOSSARY-COLUMN"><span class="glossterm">Column</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attribute</a></em></a> found in
+ a <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> or
+ <a class="glossterm" href="glossary.html#GLOSSARY-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-VIEW" title="View">view</a></em></a>.
+ </p></dd><dt id="GLOSSARY-COMMIT"><span class="glossterm">Commit</span></dt><dd class="glossdef"><p>
+ The act of finalizing a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a> within
+ the <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>, which
+ makes it visible to other transactions and assures its
+ <a class="glossterm" href="glossary.html#GLOSSARY-DURABILITY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DURABILITY" title="Durability">durability</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>.
+ </p></dd><dt id="GLOSSARY-CONCURRENCY"><span class="glossterm">Concurrency</span></dt><dd class="glossdef"><p>
+ The concept that multiple independent operations happen within the
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> at the same time.
+ In <span class="productname">PostgreSQL</span>, concurrency is controlled by
+ the <a class="glossterm" href="glossary.html#GLOSSARY-MVCC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-MVCC" title="Multi-version concurrency control (MVCC)">multiversion concurrency control</a></em></a>
+ mechanism.
+ </p></dd><dt id="GLOSSARY-CONNECTION"><span class="glossterm">Connection</span></dt><dd class="glossdef"><p>
+ An established line of communication between a client process and a
+ <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend</a></em></a> process,
+ usually over a network, supporting a
+ <a class="glossterm" href="glossary.html#GLOSSARY-SESSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SESSION" title="Session">session</a></em></a>. This term is
+ sometimes used as a synonym for session.
+ </p><p>
+ For more information, see
+ <a class="xref" href="runtime-config-connection.html" title="20.3. Connections and Authentication">Section 20.3</a>.
+ </p></dd><dt id="GLOSSARY-CONSISTENCY"><span class="glossterm">Consistency</span></dt><dd class="glossdef"><p>
+ The property that the data in the
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>
+ is always in compliance with
+ <a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT" title="Constraint">integrity constraints</a></em></a>.
+ Transactions may be allowed to violate some of the constraints
+ transiently before it commits, but if such violations are not resolved
+ by the time it commits, such a transaction is automatically
+ <a class="glossterm" href="glossary.html#GLOSSARY-ROLLBACK"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ROLLBACK" title="Rollback">rolled back</a></em></a>.
+ This is one of the <acronym class="acronym">ACID</acronym> properties.
+ </p></dd><dt id="GLOSSARY-CONSTRAINT"><span class="glossterm">Constraint</span></dt><dd class="glossdef"><p>
+ A restriction on the values of data allowed within a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>,
+ or in attributes of a
+ <a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN" title="Domain">domain</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="ddl-constraints.html" title="5.4. Constraints">Section 5.4</a>.
+ </p></dd><dt id="GLOSSARY-CUMULATIVE-STATISTICS"><span class="glossterm">Cumulative Statistics System</span></dt><dd class="glossdef"><p>
+ A system which, if enabled, accumulates statistical information
+ about the <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>'s
+ activities.
+ </p><p>
+ For more information, see
+ <a class="xref" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">Section 28.2</a>.
+ </p></dd><dt><span class="glossterm">Data area</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-DATA-DIRECTORY">Data directory</a>.</p></dd><dt id="GLOSSARY-DATABASE"><span class="glossterm">Database</span></dt><dd class="glossdef"><p>
+ A named collection of
+ <a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT" title="SQL object">local SQL objects</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="manage-ag-overview.html" title="23.1. Overview">Section 23.1</a>.
+ </p></dd><dt id="GLOSSARY-DB-CLUSTER"><span class="glossterm">Database cluster</span></dt><dd class="glossdef"><p>
+ A collection of databases and global SQL objects,
+ and their common static and dynamic metadata.
+ Sometimes referred to as a
+ <em class="firstterm">cluster</em>.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, the term
+ <em class="firstterm">cluster</em> is also sometimes used to refer to an instance.
+ (Don't confuse this term with the SQL command <code class="command">CLUSTER</code>.)
+ </p></dd><dt><span class="glossterm">Database server</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-INSTANCE">Instance</a>.</p></dd><dt id="GLOSSARY-DATA-DIRECTORY"><span class="glossterm">Data directory</span></dt><dd class="glossdef"><p>
+ The base directory on the file system of a
+ <a class="glossterm" href="glossary.html#GLOSSARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SERVER" title="Server">server</a></em></a> that contains all
+ data files and subdirectories associated with a
+ <a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER" title="Database cluster">database cluster</a></em></a>
+ (with the exception of
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLESPACE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLESPACE" title="Tablespace">tablespaces</a></em></a>,
+ and optionally <a class="glossterm" href="glossary.html#GLOSSARY-WAL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL" title="Write-ahead log">WAL</a></em></a>).
+ The environment variable <code class="literal">PGDATA</code> is commonly used to
+ refer to the data directory.
+ </p><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER" title="Database cluster">cluster</a></em></a>'s storage
+ space comprises the data directory plus any additional tablespaces.
+ </p><p>
+ For more information, see
+ <a class="xref" href="storage-file-layout.html" title="73.1. Database File Layout">Section 73.1</a>.
+ </p></dd><dt id="GLOSSARY-DATA-PAGE"><span class="glossterm">Data page</span></dt><dd class="glossdef"><p>
+ The basic structure used to store relation data.
+ All pages are of the same size.
+ Data pages are typically stored on disk, each in a specific file,
+ and can be read to <a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY" title="Shared memory">shared buffers</a></em></a>
+ where they can be modified, becoming
+ <em class="firstterm">dirty</em>. They become clean when written
+ to disk. New pages, which initially exist in memory only, are also
+ dirty until written.
+ </p></dd><dt id="GLOSSARY-DATUM"><span class="glossterm">Datum</span></dt><dd class="glossdef"><p>
+ The internal representation of one value of an <acronym class="acronym">SQL</acronym>
+ data type.
+ </p></dd><dt id="GLOSSARY-DELETE"><span class="glossterm">Delete</span></dt><dd class="glossdef"><p>
+ An <acronym class="acronym">SQL</acronym> command which removes
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">rows</a></em></a> from a given
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>
+ or <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a>.
+ </p></dd><dt id="GLOSSARY-DOMAIN"><span class="glossterm">Domain</span></dt><dd class="glossdef"><p>
+ A user-defined data type that is based on another underlying data type.
+ It acts the same as the underlying type except for possibly restricting
+ the set of allowed values.
+ </p><p>
+ For more information, see <a class="xref" href="domains.html" title="8.18. Domain Types">Section 8.18</a>.
+ </p></dd><dt id="GLOSSARY-DURABILITY"><span class="glossterm">Durability</span></dt><dd class="glossdef"><p>
+ The assurance that once a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a> has
+ been <a class="glossterm" href="glossary.html#GLOSSARY-COMMIT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-COMMIT" title="Commit">committed</a></em></a>, the
+ changes remain even after a system failure or crash.
+ This is one of the <acronym class="acronym">ACID</acronym> properties.
+ </p></dd><dt><span class="glossterm">Epoch</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-XID">Transaction ID</a>.</p></dd><dt id="GLOSSARY-EXTENSION"><span class="glossterm">Extension</span></dt><dd class="glossdef"><p>
+ A software add-on package that can be installed on an
+ <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a> to
+ get extra features.
+ </p><p>
+ For more information, see
+ <a class="xref" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Section 38.17</a>.
+ </p></dd><dt id="GLOSSARY-FILE-SEGMENT"><span class="glossterm">File segment</span></dt><dd class="glossdef"><p>
+ A physical file which stores data for a given
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>.
+ File segments are limited in size by a configuration value
+ (typically 1 gigabyte),
+ so if a relation exceeds that size, it is split into multiple segments.
+ </p><p>
+ For more information, see
+ <a class="xref" href="storage-file-layout.html" title="73.1. Database File Layout">Section 73.1</a>.
+ </p><p>
+ (Don't confuse this term with the similar term
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE" title="WAL file">WAL segment</a></em></a>).
+ </p></dd><dt id="GLOSSARY-FOREIGN-DATA-WRAPPER"><span class="glossterm">Foreign data wrapper</span></dt><dd class="glossdef"><p>
+ A means of representing data that is not contained in the local
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> so that it appears as if were in local
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table(s)</a></em></a>. With a foreign data wrapper it is
+ possible to define a <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-SERVER" title="Foreign server">foreign server</a></em></a> and
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE" title="Foreign table (relation)">foreign tables</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a>.
+ </p></dd><dt id="GLOSSARY-FOREIGN-KEY"><span class="glossterm">Foreign key</span></dt><dd class="glossdef"><p>
+ A type of <a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT" title="Constraint">constraint</a></em></a>
+ defined on one or more <a class="glossterm" href="glossary.html#GLOSSARY-COLUMN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-COLUMN" title="Column">columns</a></em></a>
+ in a <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> which
+ requires the value(s) in those <a class="glossterm" href="glossary.html#GLOSSARY-COLUMN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-COLUMN" title="Column">columns</a></em></a> to
+ identify zero or one <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">row</a></em></a>
+ in another (or, infrequently, the same)
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>.
+ </p></dd><dt id="GLOSSARY-FOREIGN-SERVER"><span class="glossterm">Foreign server</span></dt><dd class="glossdef"><p>
+ A named collection of
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE" title="Foreign table (relation)">foreign tables</a></em></a> which
+ all use the same
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER" title="Foreign data wrapper">foreign data wrapper</a></em></a>
+ and have other configuration values in common.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>.
+ </p></dd><dt id="GLOSSARY-FOREIGN-TABLE"><span class="glossterm">Foreign table (relation)</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> which appears to have
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">rows</a></em></a> and
+ <a class="glossterm" href="glossary.html#GLOSSARY-COLUMN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-COLUMN" title="Column">columns</a></em></a> similar to a
+ regular <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>, but will forward
+ requests for data through its
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER" title="Foreign data wrapper">foreign data wrapper</a></em></a>,
+ which will return <a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET" title="Result set">result sets</a></em></a>
+ structured according to the definition of the
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE" title="Foreign table (relation)">foreign table</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>.
+ </p></dd><dt id="GLOSSARY-FORK"><span class="glossterm">Fork</span></dt><dd class="glossdef"><p>
+ Each of the separate segmented file sets in which a relation is stored.
+ The <em class="firstterm">main fork</em> is where the actual data resides.
+ There also exist two secondary forks for metadata:
+ the <a class="glossterm" href="glossary.html#GLOSSARY-FSM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FSM" title="Free space map (fork)">free space map</a></em></a>
+ and the <a class="glossterm" href="glossary.html#GLOSSARY-VM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-VM" title="Visibility map (fork)">visibility map</a></em></a>.
+ <a class="glossterm" href="glossary.html#GLOSSARY-UNLOGGED"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-UNLOGGED" title="Unlogged">Unlogged relations</a></em></a>
+ also have an <em class="firstterm">init fork</em>.
+ </p></dd><dt id="GLOSSARY-FSM"><span class="glossterm">Free space map (fork)</span></dt><dd class="glossdef"><p>
+ A storage structure that keeps metadata about each data page of a table's
+ main fork. The free space map entry for each page stores the
+ amount of free space that's available for future tuples, and is structured
+ to be efficiently searched for available space for a new tuple of a given
+ size.
+ </p><p>
+ For more information, see
+ <a class="xref" href="storage-fsm.html" title="73.3. Free Space Map">Section 73.3</a>.
+ </p></dd><dt id="GLOSSARY-FUNCTION"><span class="glossterm">Function (routine)</span></dt><dd class="glossdef"><p>
+ A type of routine that receives zero or more arguments, returns zero or more
+ output values, and is constrained to run within one transaction.
+ Functions are invoked as part of a query, for example via
+ <code class="command">SELECT</code>.
+ Certain functions can return
+ <a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET" title="Result set">sets</a></em></a>; those are
+ called <em class="firstterm">set-returning functions</em>.
+ </p><p>
+ Functions can also be used for
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRIGGER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRIGGER" title="Trigger">triggers</a></em></a> to invoke.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>.
+ </p></dd><dt id="GLOSSARY-GRANT"><span class="glossterm">Grant</span></dt><dd class="glossdef"><p>
+ An <acronym class="acronym">SQL</acronym> command that is used to allow a
+ <a class="glossterm" href="glossary.html#GLOSSARY-USER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-USER" title="User">user</a></em></a> or
+ <a class="glossterm" href="glossary.html#GLOSSARY-ROLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ROLE" title="Role">role</a></em></a> to access
+ specific objects within the <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>.
+ </p></dd><dt id="GLOSSARY-HEAP"><span class="glossterm">Heap</span></dt><dd class="glossdef"><p>
+ Contains the values of <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">row</a></em></a>
+ attributes (i.e., the data) for a
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>.
+ The heap is realized within one or more
+ <a class="glossterm" href="glossary.html#GLOSSARY-FILE-SEGMENT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FILE-SEGMENT" title="File segment">file segments</a></em></a>
+ in the relation's <a class="glossterm" href="glossary.html#GLOSSARY-FORK"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FORK" title="Fork">main fork</a></em></a>.
+ </p></dd><dt id="GLOSSARY-HOST"><span class="glossterm">Host</span></dt><dd class="glossdef"><p>
+ A computer that communicates with other computers over a network.
+ This is sometimes used as a synonym for
+ <a class="glossterm" href="glossary.html#GLOSSARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SERVER" title="Server">server</a></em></a>.
+ It is also used to refer to a computer where
+ <a class="glossterm" href="glossary.html#GLOSSARY-CLIENT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CLIENT" title="Client (process)">client processes</a></em></a> run.
+ </p></dd><dt id="GLOSSARY-INDEX"><span class="glossterm">Index (relation)</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> that contains
+ data derived from a <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>
+ or <a class="glossterm" href="glossary.html#GLOSSARY-MATERIALIZED-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-MATERIALIZED-VIEW" title="Materialized view (relation)">materialized view</a></em></a>.
+ Its internal structure supports fast retrieval of and access to the original
+ data.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>.
+ </p></dd><dt id="GLOSSARY-INSERT"><span class="glossterm">Insert</span></dt><dd class="glossdef"><p>
+ An <acronym class="acronym">SQL</acronym> command used to add new data into a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>.
+ </p></dd><dt id="GLOSSARY-INSTANCE"><span class="glossterm">Instance</span></dt><dd class="glossdef"><p>
+ A group of <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend</a></em></a> and
+ <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary processes</a></em></a>
+ that communicate using a common shared memory area. One
+ <a class="glossterm" href="glossary.html#GLOSSARY-POSTMASTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-POSTMASTER" title="Postmaster (process)">postmaster process</a></em></a>
+ manages the instance; one instance manages exactly one
+ <a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER" title="Database cluster">database cluster</a></em></a>
+ with all its databases. Many instances can run on the same
+ <a class="glossterm" href="glossary.html#GLOSSARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SERVER" title="Server">server</a></em></a>
+ as long as their <acronym class="acronym">TCP</acronym> ports do not conflict.
+ </p><p>
+ The instance handles all key features of a <acronym class="acronym">DBMS</acronym>:
+ read and write access to files and shared memory,
+ assurance of the <acronym class="acronym">ACID</acronym> properties,
+ <a class="glossterm" href="glossary.html#GLOSSARY-CONNECTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONNECTION" title="Connection">connections</a></em></a> to
+ <a class="glossterm" href="glossary.html#GLOSSARY-CLIENT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CLIENT" title="Client (process)">client processes</a></em></a>,
+ privilege verification, crash recovery, replication, etc.
+ </p></dd><dt id="GLOSSARY-ISOLATION"><span class="glossterm">Isolation</span></dt><dd class="glossdef"><p>
+ The property that the effects of a transaction are not visible to
+ <a class="glossterm" href="glossary.html#GLOSSARY-CONCURRENCY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONCURRENCY" title="Concurrency">concurrent transactions</a></em></a>
+ before it commits.
+ This is one of the <acronym class="acronym">ACID</acronym> properties.
+ </p><p>
+ For more information, see <a class="xref" href="transaction-iso.html" title="13.2. Transaction Isolation">Section 13.2</a>.
+ </p></dd><dt id="GLOSSARY-JOIN"><span class="glossterm">Join</span></dt><dd class="glossdef"><p>
+ An operation and <acronym class="acronym">SQL</acronym> keyword used in
+ <a class="glossterm" href="glossary.html#GLOSSARY-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-QUERY" title="Query">queries</a></em></a>
+ for combining data from multiple
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relations</a></em></a>.
+ </p></dd><dt id="GLOSSARY-KEY"><span class="glossterm">Key</span></dt><dd class="glossdef"><p>
+ A means of identifying a <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">row</a></em></a> within a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> or
+ other <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> by
+ values contained within one or more
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attributes</a></em></a>
+ in that relation.
+ </p></dd><dt id="GLOSSARY-LOCK"><span class="glossterm">Lock</span></dt><dd class="glossdef"><p>
+ A mechanism that allows a process to limit or prevent simultaneous
+ access to a resource.
+ </p></dd><dt id="GLOSSARY-LOG-FILE"><span class="glossterm">Log file</span></dt><dd class="glossdef"><p>
+ Log files contain human-readable text lines about events.
+ Examples include login failures, long-running queries, etc.
+ </p><p>
+ For more information, see
+ <a class="xref" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Section 25.3</a>.
+ </p></dd><dt id="GLOSSARY-LOGGED"><span class="glossterm">Logged</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> is considered
+ <a class="glossterm" href="glossary.html#GLOSSARY-LOGGED"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-LOGGED" title="Logged">logged</a></em></a> if changes to it are sent to the
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL" title="Write-ahead log">WAL</a></em></a>. By default, all regular
+ tables are logged. A table can be specified as
+ <a class="glossterm" href="glossary.html#GLOSSARY-UNLOGGED"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-UNLOGGED" title="Unlogged">unlogged</a></em></a> either at
+ creation time or via the <code class="command">ALTER TABLE</code> command.
+ </p></dd><dt id="GLOSSARY-LOGGER"><span class="glossterm">Logger (process)</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ which, if enabled, writes information about database events into the current
+ <a class="glossterm" href="glossary.html#GLOSSARY-LOG-FILE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-LOG-FILE" title="Log file">log file</a></em></a>.
+ When reaching certain time- or
+ volume-dependent criteria, a new log file is created.
+ Also called <em class="firstterm">syslogger</em>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging">Section 20.8</a>.
+ </p></dd><dt id="GLOSSARY-LOG-RECORD"><span class="glossterm">Log record</span></dt><dd class="glossdef"><p>
+ Archaic term for a <a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD" title="WAL record">WAL record</a></em></a>.
+ </p></dd><dt><span class="glossterm">Master (server)</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-PRIMARY-SERVER">Primary (server)</a>.</p></dd><dt id="GLOSSARY-MATERIALIZED"><span class="glossterm">Materialized</span></dt><dd class="glossdef"><p>
+ The property that some information has been pre-computed and stored
+ for later use, rather than computing it on-the-fly.
+ </p><p>
+ This term is used in
+ <a class="glossterm" href="glossary.html#GLOSSARY-MATERIALIZED-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-MATERIALIZED-VIEW" title="Materialized view (relation)">materialized view</a></em></a>,
+ to mean that the data derived from the view's query is stored on
+ disk separately from the sources of that data.
+ </p><p>
+ This term is also used to refer to some multi-step queries to mean that
+ the data resulting from executing a given step is stored in memory
+ (with the possibility of spilling to disk), so that it can be read multiple
+ times by another step.
+ </p></dd><dt id="GLOSSARY-MATERIALIZED-VIEW"><span class="glossterm">Materialized view (relation)</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> that is
+ defined by a <code class="command">SELECT</code> statement
+ (just like a <a class="glossterm" href="glossary.html#GLOSSARY-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-VIEW" title="View">view</a></em></a>),
+ but stores data in the same way that a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> does. It cannot be
+ modified via <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> operations.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW"><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></a>.
+ </p></dd><dt id="GLOSSARY-MVCC"><span class="glossterm">Multi-version concurrency control (MVCC)</span></dt><dd class="glossdef"><p>
+ A mechanism designed to allow several
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transactions</a></em></a> to be
+ reading and writing the same rows without one process causing other
+ processes to stall.
+ In <span class="productname">PostgreSQL</span>, MVCC is implemented by
+ creating copies (<em class="firstterm">versions</em>) of
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">tuples</a></em></a> as they are
+ modified; after transactions that can see the old versions terminate,
+ those old versions need to be removed.
+ </p></dd><dt id="GLOSSARY-NULL"><span class="glossterm">Null</span></dt><dd class="glossdef"><p>
+ A concept of non-existence that is a central tenet of relational
+ database theory. It represents the absence of a definite value.
+ </p></dd><dt><span class="glossterm">Optimizer</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-PLANNER">Query planner</a>.</p></dd><dt id="GLOSSARY-PARALLEL-QUERY"><span class="glossterm">Parallel query</span></dt><dd class="glossdef"><p>
+ The ability to handle parts of executing a
+ <a class="glossterm" href="glossary.html#GLOSSARY-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-QUERY" title="Query">query</a></em></a> to take advantage
+ of parallel processes on servers with multiple <acronym class="acronym">CPU</acronym>s.
+ </p></dd><dt id="GLOSSARY-PARTITION"><span class="glossterm">Partition</span></dt><dd class="glossdef"><p>
+ One of several disjoint (not overlapping) subsets of a larger set.
+ </p></dd><dd class="glossdef"><p>
+ In reference to a
+ <a class="glossterm" href="glossary.html#GLOSSARY-PARTITIONED-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PARTITIONED-TABLE" title="Partitioned table (relation)">partitioned table</a></em></a>:
+ One of the tables that each contain part of the data of the partitioned table,
+ which is said to be the <em class="firstterm">parent</em>.
+ The partition is itself a table, so it can also be queried directly;
+ at the same time, a partition can sometimes be a partitioned table,
+ allowing hierarchies to be created.
+ </p></dd><dd class="glossdef"><p>
+ In reference to a <a class="glossterm" href="glossary.html#GLOSSARY-WINDOW-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WINDOW-FUNCTION" title="Window function (routine)">window function</a></em></a>
+ in a <a class="glossterm" href="glossary.html#GLOSSARY-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-QUERY" title="Query">query</a></em></a>,
+ a partition is a user-defined criterion that identifies which neighboring
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">rows</a></em></a>
+ of the <a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET" title="Result set">query's result set</a></em></a>
+ can be considered by the function.
+ </p></dd><dt id="GLOSSARY-PARTITIONED-TABLE"><span class="glossterm">Partitioned table (relation)</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> that is
+ in semantic terms the same as a <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>,
+ but whose storage is distributed across several
+ <a class="glossterm" href="glossary.html#GLOSSARY-PARTITION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PARTITION" title="Partition">partitions</a></em></a>.
+ </p></dd><dt id="GLOSSARY-POSTMASTER"><span class="glossterm">Postmaster (process)</span></dt><dd class="glossdef"><p>
+ The very first process of an <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>.
+ It starts and manages the
+ <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary processes</a></em></a>
+ and creates <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend processes</a></em></a>
+ on demand.
+ </p><p>
+ For more information, see
+ <a class="xref" href="server-start.html" title="19.3. Starting the Database Server">Section 19.3</a>.
+ </p></dd><dt id="GLOSSARY-PRIMARY-KEY"><span class="glossterm">Primary key</span></dt><dd class="glossdef"><p>
+ A special case of a
+ <a class="glossterm" href="glossary.html#GLOSSARY-UNIQUE-CONSTRAINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-UNIQUE-CONSTRAINT" title="Unique constraint">unique constraint</a></em></a>
+ defined on a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> or other
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> that also
+ guarantees that all of the
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attributes</a></em></a>
+ within the <a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-KEY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-KEY" title="Primary key">primary key</a></em></a>
+ do not have <a class="glossterm" href="glossary.html#GLOSSARY-NULL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-NULL" title="Null">null</a></em></a> values.
+ As the name implies, there can be only one
+ primary key per table, though it is possible to have multiple unique
+ constraints that also have no null-capable attributes.
+ </p></dd><dt id="GLOSSARY-PRIMARY-SERVER"><span class="glossterm">Primary (server)</span></dt><dd class="glossdef"><p>
+ When two or more <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">databases</a></em></a>
+ are linked via <a class="glossterm" href="glossary.html#GLOSSARY-REPLICATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICATION" title="Replication">replication</a></em></a>,
+ the <a class="glossterm" href="glossary.html#GLOSSARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SERVER" title="Server">server</a></em></a>
+ that is considered the authoritative source of information is called
+ the <em class="firstterm">primary</em>,
+ also known as a <em class="firstterm">master</em>.
+ </p></dd><dt id="GLOSSARY-PROCEDURE"><span class="glossterm">Procedure (routine)</span></dt><dd class="glossdef"><p>
+ A type of routine.
+ Their distinctive qualities are that they do not return values,
+ and that they are allowed to make transactional statements such
+ as <code class="command">COMMIT</code> and <code class="command">ROLLBACK</code>.
+ They are invoked via the <code class="command">CALL</code> command.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a>.
+ </p></dd><dt id="GLOSSARY-QUERY"><span class="glossterm">Query</span></dt><dd class="glossdef"><p>
+ A request sent by a client to a <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend</a></em></a>,
+ usually to return results or to modify data on the database.
+ </p></dd><dt id="GLOSSARY-PLANNER"><span class="glossterm">Query planner</span></dt><dd class="glossdef"><p>
+ The part of <span class="productname">PostgreSQL</span> that is devoted to
+ determining (<em class="firstterm">planning</em>) the most efficient way to
+ execute <a class="glossterm" href="glossary.html#GLOSSARY-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-QUERY" title="Query">queries</a></em></a>.
+ Also known as <em class="firstterm">query optimizer</em>,
+ <em class="firstterm">optimizer</em>, or simply <em class="firstterm">planner</em>.
+ </p></dd><dt><span class="glossterm">Record</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-TUPLE">Tuple</a>.</p></dd><dt><span class="glossterm">Recycling</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-WAL-FILE">WAL file</a>.</p></dd><dt id="GLOSSARY-REFERENTIAL-INTEGRITY"><span class="glossterm">Referential integrity</span></dt><dd class="glossdef"><p>
+ A means of restricting data in one <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>
+ by a <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-KEY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-KEY" title="Foreign key">foreign key</a></em></a>
+ so that it must have matching data in another
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>.
+ </p></dd><dt id="GLOSSARY-RELATION"><span class="glossterm">Relation</span></dt><dd class="glossdef"><p>
+ The generic term for all objects in a
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>
+ that have a name and a list of
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attributes</a></em></a>
+ defined in a specific order.
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">Tables</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-SEQUENCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SEQUENCE" title="Sequence (relation)">sequences</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-VIEW" title="View">views</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-TABLE" title="Foreign table (relation)">foreign tables</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-MATERIALIZED-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-MATERIALIZED-VIEW" title="Materialized view (relation)">materialized views</a></em></a>,
+ composite types, and
+ <a class="glossterm" href="glossary.html#GLOSSARY-INDEX"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INDEX" title="Index (relation)">indexes</a></em></a> are all relations.
+ </p><p>
+ More generically, a relation is a set of tuples; for example,
+ the result of a query is also a relation.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>,
+ <em class="firstterm">Class</em> is an archaic synonym for
+ <em class="firstterm">relation</em>.
+ </p></dd><dt id="GLOSSARY-REPLICA"><span class="glossterm">Replica (server)</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> that is paired
+ with a <a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-SERVER" title="Primary (server)">primary</a></em></a>
+ database and is maintaining a copy of some or all of the primary database's
+ data. The foremost reasons for doing this are to allow for greater access
+ to that data, and to maintain availability of the data in the event that
+ the <a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-SERVER" title="Primary (server)">primary</a></em></a>
+ becomes unavailable.
+ </p></dd><dt id="GLOSSARY-REPLICATION"><span class="glossterm">Replication</span></dt><dd class="glossdef"><p>
+ The act of reproducing data on one
+ <a class="glossterm" href="glossary.html#GLOSSARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SERVER" title="Server">server</a></em></a> onto another
+ server called a <a class="glossterm" href="glossary.html#GLOSSARY-REPLICA"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICA" title="Replica (server)">replica</a></em></a>.
+ This can take the form of <em class="firstterm">physical replication</em>,
+ where all file changes from one server are copied verbatim,
+ or <em class="firstterm">logical replication</em> where a defined subset
+ of data changes are conveyed using a higher-level representation.
+ </p></dd><dt id="GLOSSARY-RESULT-SET"><span class="glossterm">Result set</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> transmitted
+ from a <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend process</a></em></a>
+ to a <a class="glossterm" href="glossary.html#GLOSSARY-CLIENT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CLIENT" title="Client (process)">client</a></em></a> upon the
+ completion of an <acronym class="acronym">SQL</acronym> command, usually a
+ <code class="command">SELECT</code> but it can be an
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> command if the <code class="literal">RETURNING</code>
+ clause is specified.
+ </p><p>
+ The fact that a result set is a relation means that a query can be used
+ in the definition of another query, becoming a
+ <em class="firstterm">subquery</em>.
+ </p></dd><dd class="glossdef"><p>
+ </p></dd><dt id="GLOSSARY-REVOKE"><span class="glossterm">Revoke</span></dt><dd class="glossdef"><p>
+ A command to prevent access to a named set of
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> objects for a
+ named list of <a class="glossterm" href="glossary.html#GLOSSARY-ROLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ROLE" title="Role">roles</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a>.
+ </p></dd><dt id="GLOSSARY-ROLE"><span class="glossterm">Role</span></dt><dd class="glossdef"><p>
+ A collection of access privileges to the
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">instance</a></em></a>.
+ Roles are themselves a privilege that can be granted to other roles.
+ This is often done for convenience or to ensure completeness
+ when multiple <a class="glossterm" href="glossary.html#GLOSSARY-USER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-USER" title="User">users</a></em></a> need
+ the same privileges.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>.
+ </p></dd><dt id="GLOSSARY-ROLLBACK"><span class="glossterm">Rollback</span></dt><dd class="glossdef"><p>
+ A command to undo all of the operations performed since the beginning
+ of a <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a>.
+ </p></dd><dt id="GLOSSARY-ROUTINE"><span class="glossterm">Routine</span></dt><dd class="glossdef"><p>
+ A defined set of instructions stored in the database system
+ that can be invoked for execution.
+ A routine can be written in a variety of programming
+ languages. Routines can be
+ <a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION" title="Function (routine)">functions</a></em></a>
+ (including set-returning functions and
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRIGGER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRIGGER" title="Trigger">trigger functions</a></em></a>),
+ <a class="glossterm" href="glossary.html#GLOSSARY-AGGREGATE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AGGREGATE" title="Aggregate function (routine)">aggregate functions</a></em></a>,
+ and <a class="glossterm" href="glossary.html#GLOSSARY-PROCEDURE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PROCEDURE" title="Procedure (routine)">procedures</a></em></a>.
+ </p><p>
+ Many routines are already defined within <span class="productname">PostgreSQL</span>
+ itself, but user-defined ones can also be added.
+ </p></dd><dt><span class="glossterm">Row</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-TUPLE">Tuple</a>.</p></dd><dt id="GLOSSARY-SAVEPOINT"><span class="glossterm">Savepoint</span></dt><dd class="glossdef"><p>
+ A special mark in the sequence of steps in a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a>.
+ Data modifications after this point in time may be reverted
+ to the time of the savepoint.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-savepoint.html" title="SAVEPOINT"><span class="refentrytitle">SAVEPOINT</span></a>.
+ </p></dd><dt id="GLOSSARY-SCHEMA"><span class="glossterm">Schema</span></dt><dd class="glossdef"><p>
+ A schema is a namespace for
+ <a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT" title="SQL object">SQL objects</a></em></a>,
+ which all reside in the same
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>.
+ Each SQL object must reside in exactly one schema.
+ </p><p>
+ All system-defined SQL objects reside in schema <code class="literal">pg_catalog</code>.
+ </p></dd><dd class="glossdef"><p>
+ More generically, the term <em class="firstterm">schema</em> is used to mean
+ all data descriptions (<a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a> definitions,
+ <a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT" title="Constraint">constraints</a></em></a>, comments, etc.)
+ for a given <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> or
+ subset thereof.
+ </p><p>
+ For more information, see
+ <a class="xref" href="ddl-schemas.html" title="5.9. Schemas">Section 5.9</a>.
+ </p></dd><dt><span class="glossterm">Segment</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-FILE-SEGMENT">File segment</a>.</p></dd><dt id="GLOSSARY-SELECT"><span class="glossterm">Select</span></dt><dd class="glossdef"><p>
+ The <acronym class="acronym">SQL</acronym> command used to request data from a
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>.
+ Normally, <code class="command">SELECT</code> commands are not expected to modify the
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> in any way,
+ but it is possible that
+ <a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION" title="Function (routine)">functions</a></em></a> invoked within
+ the query could have side effects that do modify data.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>.
+ </p></dd><dt id="GLOSSARY-SEQUENCE"><span class="glossterm">Sequence (relation)</span></dt><dd class="glossdef"><p>
+ A type of relation that is used to generate values.
+ Typically the generated values are sequential non-repeating numbers.
+ They are commonly used to generate surrogate
+ <a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-KEY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-KEY" title="Primary key">primary key</a></em></a>
+ values.
+ </p></dd><dt id="GLOSSARY-SERVER"><span class="glossterm">Server</span></dt><dd class="glossdef"><p>
+ A computer on which <span class="productname">PostgreSQL</span>
+ <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instances</a></em></a> run.
+ The term <em class="firstterm">server</em> denotes real hardware, a
+ container, or a <em class="firstterm">virtual machine</em>.
+ </p><p>
+ This term is sometimes used to refer to an instance or to a host.
+ </p></dd><dt id="GLOSSARY-SESSION"><span class="glossterm">Session</span></dt><dd class="glossdef"><p>
+ A state that allows a client and a backend to interact,
+ communicating over a <a class="glossterm" href="glossary.html#GLOSSARY-CONNECTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONNECTION" title="Connection">connection</a></em></a>.
+ </p></dd><dt id="GLOSSARY-SHARED-MEMORY"><span class="glossterm">Shared memory</span></dt><dd class="glossdef"><p>
+ <acronym class="acronym">RAM</acronym> which is used by the processes common to an
+ <a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-INSTANCE" title="Instance">instance</a></em></a>.
+ It mirrors parts of <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a>
+ files, provides a transient area for
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD" title="WAL record">WAL records</a></em></a>,
+ and stores additional common information.
+ Note that shared memory belongs to the complete instance, not to a single
+ database.
+ </p><p>
+ The largest part of shared memory is known as <em class="firstterm">shared buffers</em>
+ and is used to mirror part of data files, organized into pages.
+ When a page is modified, it is called a dirty page until it is
+ written back to the file system.
+ </p><p>
+ For more information, see
+ <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY" title="20.4.1. Memory">Section 20.4.1</a>.
+ </p></dd><dt id="GLOSSARY-SQL-OBJECT"><span class="glossterm">SQL object</span></dt><dd class="glossdef"><p>
+ Any object that can be created with a <code class="command">CREATE</code>
+ command. Most objects are specific to one database, and are commonly
+ known as <em class="firstterm">local objects</em>.
+ </p><p>
+ Most local objects reside in a specific
+ <a class="glossterm" href="glossary.html#GLOSSARY-SCHEMA"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SCHEMA" title="Schema">schema</a></em></a> in their
+ containing database, such as
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relations</a></em></a> (all types),
+ <a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION" title="Function (routine)">routines</a></em></a> (all types),
+ data types, etc.
+ The names of such objects of the same type in the same schema
+ are enforced to be unique.
+ </p><p>
+ There also exist local objects that do not reside in schemas; some examples are
+ <a class="glossterm" href="glossary.html#GLOSSARY-EXTENSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-EXTENSION" title="Extension">extensions</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-CAST"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CAST" title="Cast">data type casts</a></em></a>, and
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER" title="Foreign data wrapper">foreign data wrappers</a></em></a>.
+ The names of such objects of the same type are enforced to be unique
+ within the database.
+ </p><p>
+ Other object types, such as
+ <a class="glossterm" href="glossary.html#GLOSSARY-ROLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ROLE" title="Role">roles</a></em></a>,
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLESPACE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLESPACE" title="Tablespace">tablespaces</a></em></a>,
+ replication origins, subscriptions for logical replication, and
+ databases themselves are not local SQL objects since they exist
+ entirely outside of any specific database;
+ they are called <em class="firstterm">global objects</em>.
+ The names of such objects are enforced to be unique within the whole
+ database cluster.
+ </p><p>
+ For more information, see
+ <a class="xref" href="manage-ag-overview.html" title="23.1. Overview">Section 23.1</a>.
+ </p></dd><dt id="GLOSSARY-SQL-STANDARD"><span class="glossterm">SQL standard</span></dt><dd class="glossdef"><p>
+ A series of documents that define the <acronym class="acronym">SQL</acronym> language.
+ </p></dd><dt><span class="glossterm">Standby (server)</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-REPLICA">Replica (server)</a>.</p></dd><dt id="GLOSSARY-STARTUP-PROCESS"><span class="glossterm">Startup process</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ that replays WAL during crash recovery and in a
+ <a class="glossterm" href="glossary.html#GLOSSARY-REPLICATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICATION" title="Replication">physical replica</a></em></a>.
+ </p><p>
+ (The name is historical: the startup process was named before
+ replication was implemented; the name refers to its task as it
+ relates to the server startup following a crash.)
+ </p></dd><dt id="GLOSSARY-SYSTEM-CATALOG"><span class="glossterm">System catalog</span></dt><dd class="glossdef"><p>
+ A collection of <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">tables</a></em></a>
+ which describe the structure of all
+ <a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT" title="SQL object">SQL objects</a></em></a>
+ of the instance.
+ The system catalog resides in the schema <code class="literal">pg_catalog</code>.
+ These tables contain data in internal representation and are
+ not typically considered useful for user examination;
+ a number of user-friendlier <a class="glossterm" href="glossary.html#GLOSSARY-VIEW"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-VIEW" title="View">views</a></em></a>,
+ also in schema <code class="literal">pg_catalog</code>, offer more convenient access to
+ some of that information, while additional tables and views
+ exist in schema <code class="literal">information_schema</code>
+ (see <a class="xref" href="information-schema.html" title="Chapter 37. The Information Schema">Chapter 37</a>) that expose some
+ of the same and additional information as mandated by the
+ <a class="glossterm" href="glossary.html#GLOSSARY-SQL-STANDARD"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SQL-STANDARD" title="SQL standard">SQL standard</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="ddl-schemas.html" title="5.9. Schemas">Section 5.9</a>.
+ </p></dd><dt id="GLOSSARY-TABLE"><span class="glossterm">Table</span></dt><dd class="glossdef"><p>
+ A collection of <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">tuples</a></em></a> having
+ a common data structure (the same number of
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attributes</a></em></a>, in the same
+ order, having the same name and type per position).
+ A table is the most common form of
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> in
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>.
+ </p></dd><dt id="GLOSSARY-TABLESPACE"><span class="glossterm">Tablespace</span></dt><dd class="glossdef"><p>
+ A named location on the server file system.
+ All <a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SQL-OBJECT" title="SQL object">SQL objects</a></em></a>
+ which require storage beyond their definition in the
+ <a class="glossterm" href="glossary.html#GLOSSARY-SYSTEM-CATALOG"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SYSTEM-CATALOG" title="System catalog">system catalog</a></em></a>
+ must belong to a single tablespace.
+ Initially, a database cluster contains a single usable tablespace which is
+ used as the default for all SQL objects, called <code class="literal">pg_default</code>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Section 23.6</a>.
+ </p></dd><dt id="GLOSSARY-TEMPORARY-TABLE"><span class="glossterm">Temporary table</span></dt><dd class="glossdef"><p>
+ <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">Tables</a></em></a> that exist either
+ for the lifetime of a
+ <a class="glossterm" href="glossary.html#GLOSSARY-SESSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SESSION" title="Session">session</a></em></a> or a
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a>, as
+ specified at the time of creation.
+ The data in them is not visible to other sessions, and is not
+ <a class="glossterm" href="glossary.html#GLOSSARY-LOGGED"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-LOGGED" title="Logged">logged</a></em></a>.
+ Temporary tables are often used to store intermediate data for a
+ multi-step operation.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>.
+ </p></dd><dt id="GLOSSARY-TOAST"><span class="glossterm">TOAST</span></dt><dd class="glossdef"><p>
+ A mechanism by which large attributes of table rows are split and
+ stored in a secondary table, called the <em class="firstterm">TOAST table</em>.
+ Each relation with large attributes has its own TOAST table.
+ </p><p>
+ For more information, see
+ <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a>.
+ </p></dd><dt id="GLOSSARY-TRANSACTION"><span class="glossterm">Transaction</span></dt><dd class="glossdef"><p>
+ A combination of commands that must act as a single
+ <a class="glossterm" href="glossary.html#GLOSSARY-ATOMIC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATOMIC" title="Atomic">atomic</a></em></a> command: they all
+ succeed or all fail as a single unit, and their effects are not visible to
+ other <a class="glossterm" href="glossary.html#GLOSSARY-SESSION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SESSION" title="Session">sessions</a></em></a> until
+ the transaction is complete, and possibly even later, depending on the
+ isolation level.
+ </p><p>
+ For more information, see
+ <a class="xref" href="transaction-iso.html" title="13.2. Transaction Isolation">Section 13.2</a>.
+ </p></dd><dt id="GLOSSARY-XID"><span class="glossterm">Transaction ID</span></dt><dd class="glossdef"><p>
+ The numerical, unique, sequentially-assigned identifier that each
+ transaction receives when it first causes a database modification.
+ Frequently abbreviated as <em class="firstterm">xid</em>.
+ When stored on disk, xids are only 32-bits wide, so only
+ approximately four billion write transaction IDs can be generated;
+ to permit the system to run for longer than that,
+ <em class="firstterm">epochs</em> are used, also 32 bits wide.
+ When the counter reaches the maximum xid value, it starts over at
+ <code class="literal">3</code> (values under that are reserved) and the
+ epoch value is incremented by one.
+ In some contexts, the epoch and xid values are
+ considered together as a single 64-bit value.
+ </p><p>
+ For more information, see
+ <a class="xref" href="datatype-oid.html" title="8.19. Object Identifier Types">Section 8.19</a>.
+ </p></dd><dt id="GLOSSARY-TPS"><span class="glossterm">Transactions per second (TPS)</span></dt><dd class="glossdef"><p>
+ Average number of transactions that are executed per second,
+ totaled across all sessions active for a measured run.
+ This is used as a measure of the performance characteristics of
+ an instance.
+ </p></dd><dt id="GLOSSARY-TRIGGER"><span class="glossterm">Trigger</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION" title="Function (routine)">function</a></em></a> which can
+ be defined to execute whenever a certain operation (<code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ <code class="command">TRUNCATE</code>) is applied to a
+ <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>.
+ A trigger executes within the same
+ <a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TRANSACTION" title="Transaction">transaction</a></em></a> as the
+ statement which invoked it, and if the function fails, then the invoking
+ statement also fails.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>.
+ </p></dd><dt id="GLOSSARY-TUPLE"><span class="glossterm">Tuple</span></dt><dd class="glossdef"><p>
+ A collection of <a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ATTRIBUTE" title="Attribute">attributes</a></em></a>
+ in a fixed order.
+ That order may be defined by the <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>
+ (or other <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>)
+ where the tuple is contained, in which case the tuple is often called a
+ <em class="firstterm">row</em>. It may also be defined by the structure of a
+ result set, in which case it is sometimes called a <em class="firstterm">record</em>.
+ </p></dd><dt id="GLOSSARY-UNIQUE-CONSTRAINT"><span class="glossterm">Unique constraint</span></dt><dd class="glossdef"><p>
+ A type of <a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CONSTRAINT" title="Constraint">constraint</a></em></a>
+ defined on a <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a>
+ which restricts the values allowed in one or a combination of columns
+ so that each value or combination of values can only appear once in the
+ relation — that is, no other row in the relation contains values
+ that are equal to those.
+ </p><p>
+ Because <a class="glossterm" href="glossary.html#GLOSSARY-NULL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-NULL" title="Null">null values</a></em></a> are
+ not considered equal to each other, multiple rows with null values are
+ allowed to exist without violating the unique constraint.
+ </p></dd><dt id="GLOSSARY-UNLOGGED"><span class="glossterm">Unlogged</span></dt><dd class="glossdef"><p>
+ The property of certain <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relations</a></em></a>
+ that the changes to them are not reflected in the
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL" title="Write-ahead log">WAL</a></em></a>.
+ This disables replication and crash recovery for these relations.
+ </p><p>
+ The primary use of unlogged tables is for storing
+ transient work data that must be shared across processes.
+ </p><p>
+ <a class="glossterm" href="glossary.html#GLOSSARY-TEMPORARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TEMPORARY-TABLE" title="Temporary table">Temporary tables</a></em></a>
+ are always unlogged.
+ </p></dd><dt id="GLOSSARY-UPDATE"><span class="glossterm">Update</span></dt><dd class="glossdef"><p>
+ An <acronym class="acronym">SQL</acronym> command used to modify
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">rows</a></em></a>
+ that may already exist in a specified <a class="glossterm" href="glossary.html#GLOSSARY-TABLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TABLE" title="Table">table</a></em></a>.
+ It cannot create or remove rows.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-update.html" title="UPDATE"><span class="refentrytitle">UPDATE</span></a>.
+ </p></dd><dt id="GLOSSARY-USER"><span class="glossterm">User</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-ROLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-ROLE" title="Role">role</a></em></a> that has the
+ <code class="literal">LOGIN</code> privilege.
+ </p></dd><dt id="GLOSSARY-USER-MAPPING"><span class="glossterm">User mapping</span></dt><dd class="glossdef"><p>
+ The translation of login credentials in the local
+ <a class="glossterm" href="glossary.html#GLOSSARY-DATABASE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DATABASE" title="Database">database</a></em></a> to credentials
+ in a remote data system defined by a
+ <a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FOREIGN-DATA-WRAPPER" title="Foreign data wrapper">foreign data wrapper</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>.
+ </p></dd><dt id="GLOSSARY-VACUUM"><span class="glossterm">Vacuum</span></dt><dd class="glossdef"><p>
+ The process of removing outdated
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">tuple versions</a></em></a>
+ from tables or materialized views, and other closely related
+ processing required by <span class="productname">PostgreSQL</span>'s
+ implementation of <a class="glossterm" href="glossary.html#GLOSSARY-MVCC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-MVCC" title="Multi-version concurrency control (MVCC)">MVCC</a></em></a>.
+ This can be initiated through the use of
+ the <code class="command">VACUUM</code> command, but can also be handled automatically
+ via <a class="glossterm" href="glossary.html#GLOSSARY-AUTOVACUUM"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUTOVACUUM" title="Autovacuum (process)">autovacuum</a></em></a> processes.
+ </p><p>
+ For more information, see
+ <a class="xref" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Section 25.1</a> .
+ </p></dd><dt id="GLOSSARY-VIEW"><span class="glossterm">View</span></dt><dd class="glossdef"><p>
+ A <a class="glossterm" href="glossary.html#GLOSSARY-RELATION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RELATION" title="Relation">relation</a></em></a> that is defined by a
+ <code class="command">SELECT</code> statement, but has no storage of its own.
+ Any time a query references a view, the definition of the view is
+ substituted into the query as if the user had typed it as a subquery
+ instead of the name of the view.
+ </p><p>
+ For more information, see
+ <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a>.
+ </p></dd><dt id="GLOSSARY-VM"><span class="glossterm">Visibility map (fork)</span></dt><dd class="glossdef"><p>
+ A storage structure that keeps metadata about each data page
+ of a table's main fork. The visibility map entry for
+ each page stores two bits: the first one
+ (<code class="literal">all-visible</code>) indicates that all tuples
+ in the page are visible to all transactions. The second one
+ (<code class="literal">all-frozen</code>) indicates that all tuples
+ in the page are marked frozen.
+ </p></dd><dt><span class="glossterm">WAL</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-WAL">Write-ahead log</a>.</p></dd><dt id="GLOSSARY-WAL-ARCHIVER"><span class="glossterm">WAL archiver (process)</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ which, if enabled, saves copies of
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE" title="WAL file">WAL files</a></em></a>
+ for the purpose of creating backups or keeping
+ <a class="glossterm" href="glossary.html#GLOSSARY-REPLICA"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICA" title="Replica (server)">replicas</a></em></a> current.
+ </p><p>
+ For more information, see
+ <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>.
+ </p></dd><dt id="GLOSSARY-WAL-FILE"><span class="glossterm">WAL file</span></dt><dd class="glossdef"><p>
+ Also known as <em class="firstterm">WAL segment</em> or
+ <em class="firstterm">WAL segment file</em>.
+ Each of the sequentially-numbered files that provide storage space for
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL" title="Write-ahead log">WAL</a></em></a>.
+ The files are all of the same predefined size
+ and are written in sequential order, interspersing changes
+ as they occur in multiple simultaneous sessions.
+ If the system crashes, the files are read in order, and each of the
+ changes is replayed to restore the system to the state it was in
+ before the crash.
+ </p><p>
+ Each WAL file can be released after a
+ <a class="glossterm" href="glossary.html#GLOSSARY-CHECKPOINT"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-CHECKPOINT" title="Checkpoint">checkpoint</a></em></a>
+ writes all the changes in it to the corresponding data files.
+ Releasing the file can be done either by deleting it, or by changing its
+ name so that it will be used in the future, which is called
+ <em class="firstterm">recycling</em>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="wal-internals.html" title="30.6. WAL Internals">Section 30.6</a>.
+ </p></dd><dt id="GLOSSARY-WAL-RECORD"><span class="glossterm">WAL record</span></dt><dd class="glossdef"><p>
+ A low-level description of an individual data change.
+ It contains sufficient information for the data change to be
+ re-executed (<em class="firstterm">replayed</em>) in case a system failure
+ causes the change to be lost.
+ WAL records use a non-printable binary format.
+ </p><p>
+ For more information, see
+ <a class="xref" href="wal-internals.html" title="30.6. WAL Internals">Section 30.6</a>.
+ </p></dd><dt id="GLOSSARY-WAL-RECEIVER"><span class="glossterm">WAL receiver (process)</span></dt><dd class="glossdef"><p>
+ An <a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AUXILIARY-PROC" title="Auxiliary process">auxiliary process</a></em></a>
+ that runs on a <a class="glossterm" href="glossary.html#GLOSSARY-REPLICA"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICA" title="Replica (server)">replica</a></em></a>
+ to receive WAL from the
+ <a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-SERVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PRIMARY-SERVER" title="Primary (server)">primary server</a></em></a>
+ for replay by the
+ <a class="glossterm" href="glossary.html#GLOSSARY-STARTUP-PROCESS"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-STARTUP-PROCESS" title="Startup process">startup process</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>.
+ </p></dd><dt><span class="glossterm">WAL segment</span></dt><dd><p>See <a class="glosssee" href="glossary.html#GLOSSARY-WAL-FILE">WAL file</a>.</p></dd><dt id="GLOSSARY-WAL-SENDER"><span class="glossterm">WAL sender (process)</span></dt><dd class="glossdef"><p>
+ A special <a class="glossterm" href="glossary.html#GLOSSARY-BACKEND"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-BACKEND" title="Backend (process)">backend process</a></em></a>
+ that streams WAL over a network. The receiving end can be a
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECEIVER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECEIVER" title="WAL receiver (process)">WAL receiver</a></em></a>
+ in a <a class="glossterm" href="glossary.html#GLOSSARY-REPLICA"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-REPLICA" title="Replica (server)">replica</a></em></a>,
+ <a class="xref" href="app-pgreceivewal.html" title="pg_receivewal"><span class="refentrytitle"><span class="application">pg_receivewal</span></span></a>, or any other client program
+ that speaks the replication protocol.
+ </p></dd><dt id="GLOSSARY-WAL-WRITER"><span class="glossterm">WAL writer (process)</span></dt><dd class="glossdef"><p>
+ A process that writes <a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD" title="WAL record">WAL records</a></em></a>
+ from <a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-SHARED-MEMORY" title="Shared memory">shared memory</a></em></a> to
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE" title="WAL file">WAL files</a></em></a>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="runtime-config-wal.html" title="20.5. Write Ahead Log">Section 20.5</a>.
+ </p></dd><dt id="GLOSSARY-WINDOW-FUNCTION"><span class="glossterm">Window function (routine)</span></dt><dd class="glossdef"><p>
+ A type of <a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-FUNCTION" title="Function (routine)">function</a></em></a>
+ used in a <a class="glossterm" href="glossary.html#GLOSSARY-QUERY"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-QUERY" title="Query">query</a></em></a>
+ that applies to a <a class="glossterm" href="glossary.html#GLOSSARY-PARTITION"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-PARTITION" title="Partition">partition</a></em></a>
+ of the query's <a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-RESULT-SET" title="Result set">result set</a></em></a>;
+ the function's result is based on values found in
+ <a class="glossterm" href="glossary.html#GLOSSARY-TUPLE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-TUPLE" title="Tuple">rows</a></em></a> of the same partition or frame.
+ </p><p>
+ All <a class="glossterm" href="glossary.html#GLOSSARY-AGGREGATE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-AGGREGATE" title="Aggregate function (routine)">aggregate functions</a></em></a>
+ can be used as window functions, but window functions can also be
+ used to, for example, give ranks to each of the rows in the partition.
+ Also known as <em class="firstterm">analytic functions</em>.
+ </p><p>
+ For more information, see
+ <a class="xref" href="tutorial-window.html" title="3.5. Window Functions">Section 3.5</a>.
+ </p></dd><dt id="GLOSSARY-WAL"><span class="glossterm">Write-ahead log</span></dt><dd class="glossdef"><p>
+ The journal that keeps track of the changes in the
+ <a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DB-CLUSTER" title="Database cluster">database cluster</a></em></a>
+ as user- and system-invoked operations take place.
+ It comprises many individual
+ <a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-RECORD" title="WAL record">WAL records</a></em></a> written
+ sequentially to <a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-WAL-FILE" title="WAL file">WAL files</a></em></a>.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="acronyms.html" title="Appendix L. Acronyms">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="color.html" title="Appendix N. Color Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix L. Acronyms </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix N. Color Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gssapi-auth.html b/doc/src/sgml/html/gssapi-auth.html
new file mode 100644
index 0000000..c986aa9
--- /dev/null
+++ b/doc/src/sgml/html/gssapi-auth.html
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.6. GSSAPI Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="auth-password.html" title="21.5. Password Authentication" /><link rel="next" href="sspi-auth.html" title="21.7. SSPI Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.6. GSSAPI Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="auth-password.html" title="21.5. Password Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sspi-auth.html" title="21.7. SSPI Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="GSSAPI-AUTH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.6. GSSAPI Authentication</h2></div></div></div><a id="id-1.6.8.13.2" class="indexterm"></a><p>
+ <span class="productname">GSSAPI</span> is an industry-standard protocol
+ for secure authentication defined in
+ <a class="ulink" href="https://tools.ietf.org/html/rfc2743" target="_top">RFC 2743</a>.
+ <span class="productname">PostgreSQL</span>
+ supports <span class="productname">GSSAPI</span> for authentication,
+ communications encryption, or both.
+ <span class="productname">GSSAPI</span> provides automatic authentication
+ (single sign-on) for systems that support it. The authentication itself is
+ secure. If <span class="productname">GSSAPI</span> encryption
+ or <acronym class="acronym">SSL</acronym> encryption is
+ used, the data sent along the database connection will be encrypted;
+ otherwise, it will not.
+ </p><p>
+ GSSAPI support has to be enabled when <span class="productname">PostgreSQL</span> is built;
+ see <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a> for more information.
+ </p><p>
+ When <span class="productname">GSSAPI</span> uses
+ <span class="productname">Kerberos</span>, it uses a standard service
+ principal (authentication identity) name in the format
+ <code class="literal"><em class="replaceable"><code>servicename</code></em>/<em class="replaceable"><code>hostname</code></em>@<em class="replaceable"><code>realm</code></em></code>.
+ The principal name used by a particular installation is not encoded in
+ the <span class="productname">PostgreSQL</span> server in any way; rather it
+ is specified in the <em class="firstterm">keytab</em> file that the server
+ reads to determine its identity. If multiple principals are listed in
+ the keytab file, the server will accept any one of them.
+ The server's realm name is the preferred realm specified in the Kerberos
+ configuration file(s) accessible to the server.
+ </p><p>
+ When connecting, the client must know the principal name of the server
+ it intends to connect to. The <em class="replaceable"><code>servicename</code></em>
+ part of the principal is ordinarily <code class="literal">postgres</code>,
+ but another value can be selected via <span class="application">libpq</span>'s
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-KRBSRVNAME">krbsrvname</a> connection parameter.
+ The <em class="replaceable"><code>hostname</code></em> part is the fully qualified
+ host name that <span class="application">libpq</span> is told to connect to.
+ The realm name is the preferred realm specified in the Kerberos
+ configuration file(s) accessible to the client.
+ </p><p>
+ The client will also have a principal name for its own identity
+ (and it must have a valid ticket for this principal). To
+ use <span class="productname">GSSAPI</span> for authentication, the client
+ principal must be associated with
+ a <span class="productname">PostgreSQL</span> database user name.
+ The <code class="filename">pg_ident.conf</code> configuration file can be used
+ to map principals to user names; for example,
+ <code class="literal">pgusername@realm</code> could be mapped to just <code class="literal">pgusername</code>.
+ Alternatively, you can use the full <code class="literal">username@realm</code> principal as
+ the role name in <span class="productname">PostgreSQL</span> without any mapping.
+ </p><p>
+ <span class="productname">PostgreSQL</span> also supports mapping
+ client principals to user names by just stripping the realm from
+ the principal. This method is supported for backwards compatibility and is
+ strongly discouraged as it is then impossible to distinguish different users
+ with the same user name but coming from different realms. To enable this,
+ set <code class="literal">include_realm</code> to 0. For simple single-realm
+ installations, doing that combined with setting the
+ <code class="literal">krb_realm</code> parameter (which checks that the principal's realm
+ matches exactly what is in the <code class="literal">krb_realm</code> parameter)
+ is still secure; but this is a
+ less capable approach compared to specifying an explicit mapping in
+ <code class="filename">pg_ident.conf</code>.
+ </p><p>
+ The location of the server's keytab file is specified by the <a class="xref" href="runtime-config-connection.html#GUC-KRB-SERVER-KEYFILE">krb_server_keyfile</a> configuration parameter.
+ For security reasons, it is recommended to use a separate keytab
+ just for the <span class="productname">PostgreSQL</span> server rather
+ than allowing the server to read the system keytab file.
+ Make sure that your server keytab file is readable (and preferably
+ only readable, not writable) by the <span class="productname">PostgreSQL</span>
+ server account. (See also <a class="xref" href="postgres-user.html" title="19.1. The PostgreSQL User Account">Section 19.1</a>.)
+ </p><p>
+ The keytab file is generated using the Kerberos software; see the
+ Kerberos documentation for details. The following example shows
+ doing this using the <span class="application">kadmin</span> tool of
+ MIT-compatible Kerberos 5 implementations:
+</p><pre class="screen">
+<code class="prompt">kadmin% </code><strong class="userinput"><code>addprinc -randkey postgres/server.my.domain.org</code></strong>
+<code class="prompt">kadmin% </code><strong class="userinput"><code>ktadd -k krb5.keytab postgres/server.my.domain.org</code></strong>
+</pre><p>
+ </p><p>
+ The following authentication options are supported for
+ the <span class="productname">GSSAPI</span> authentication method:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">include_realm</code></span></dt><dd><p>
+ If set to 0, the realm name from the authenticated user principal is
+ stripped off before being passed through the user name mapping
+ (<a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a>). This is discouraged and is
+ primarily available for backwards compatibility, as it is not secure
+ in multi-realm environments unless <code class="literal">krb_realm</code> is
+ also used. It is recommended to
+ leave <code class="literal">include_realm</code> set to the default (1) and to
+ provide an explicit mapping in <code class="filename">pg_ident.conf</code> to convert
+ principal names to <span class="productname">PostgreSQL</span> user names.
+ </p></dd><dt><span class="term"><code class="literal">map</code></span></dt><dd><p>
+ Allows mapping from client principals to database user names. See
+ <a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a> for details. For a GSSAPI/Kerberos
+ principal, such as <code class="literal">username@EXAMPLE.COM</code> (or, less
+ commonly, <code class="literal">username/hostbased@EXAMPLE.COM</code>), the
+ user name used for mapping is
+ <code class="literal">username@EXAMPLE.COM</code> (or
+ <code class="literal">username/hostbased@EXAMPLE.COM</code>, respectively),
+ unless <code class="literal">include_realm</code> has been set to 0, in which case
+ <code class="literal">username</code> (or <code class="literal">username/hostbased</code>)
+ is what is seen as the system user name when mapping.
+ </p></dd><dt><span class="term"><code class="literal">krb_realm</code></span></dt><dd><p>
+ Sets the realm to match user principal names against. If this parameter
+ is set, only users of that realm will be accepted. If it is not set,
+ users of any realm can connect, subject to whatever user name mapping
+ is done.
+ </p></dd></dl></div><p>
+ </p><p>
+ In addition to these settings, which can be different for
+ different <code class="filename">pg_hba.conf</code> entries, there is the
+ server-wide <a class="xref" href="runtime-config-connection.html#GUC-KRB-CASEINS-USERS">krb_caseins_users</a> configuration
+ parameter. If that is set to true, client principals are matched to
+ user map entries case-insensitively. <code class="literal">krb_realm</code>, if
+ set, is also matched case-insensitively.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="auth-password.html" title="21.5. Password Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sspi-auth.html" title="21.7. SSPI Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.5. Password Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.7. SSPI Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/gssapi-enc.html b/doc/src/sgml/html/gssapi-enc.html
new file mode 100644
index 0000000..c8a487d
--- /dev/null
+++ b/doc/src/sgml/html/gssapi-enc.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.10. Secure TCP/IP Connections with GSSAPI Encryption</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL" /><link rel="next" href="ssh-tunnels.html" title="19.11. Secure TCP/IP Connections with SSH Tunnels" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.10. Secure TCP/IP Connections with GSSAPI Encryption</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ssh-tunnels.html" title="19.11. Secure TCP/IP Connections with SSH Tunnels">Next</a></td></tr></table><hr /></div><div class="sect1" id="GSSAPI-ENC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.10. Secure TCP/IP Connections with GSSAPI Encryption</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="gssapi-enc.html#GSSAPI-SETUP">19.10.1. Basic Setup</a></span></dt></dl></div><a id="id-1.6.6.13.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> also has native support for
+ using <acronym class="acronym">GSSAPI</acronym> to encrypt client/server communications for
+ increased security. Support requires that a <acronym class="acronym">GSSAPI</acronym>
+ implementation (such as MIT Kerberos) is installed on both client and server
+ systems, and that support in <span class="productname">PostgreSQL</span> is
+ enabled at build time (see <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a>).
+ </p><div class="sect2" id="GSSAPI-SETUP"><div class="titlepage"><div><div><h3 class="title">19.10.1. Basic Setup</h3></div></div></div><p>
+ The <span class="productname">PostgreSQL</span> server will listen for both
+ normal and <acronym class="acronym">GSSAPI</acronym>-encrypted connections on the same TCP
+ port, and will negotiate with any connecting client whether to
+ use <acronym class="acronym">GSSAPI</acronym> for encryption (and for authentication). By
+ default, this decision is up to the client (which means it can be
+ downgraded by an attacker); see <a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a> about
+ setting up the server to require the use of <acronym class="acronym">GSSAPI</acronym> for
+ some or all connections.
+ </p><p>
+ When using <acronym class="acronym">GSSAPI</acronym> for encryption, it is common to
+ use <acronym class="acronym">GSSAPI</acronym> for authentication as well, since the
+ underlying mechanism will determine both client and server identities
+ (according to the <acronym class="acronym">GSSAPI</acronym> implementation) in any
+ case. But this is not required;
+ another <span class="productname">PostgreSQL</span> authentication method
+ can be chosen to perform additional verification.
+ </p><p>
+ Other than configuration of the negotiation
+ behavior, <acronym class="acronym">GSSAPI</acronym> encryption requires no setup beyond
+ that which is necessary for GSSAPI authentication. (For more information
+ on configuring that, see <a class="xref" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Section 21.6</a>.)
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ssh-tunnels.html" title="19.11. Secure TCP/IP Connections with SSH Tunnels">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.9. Secure TCP/IP Connections with SSL </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.11. Secure TCP/IP Connections with <span class="application">SSH</span> Tunnels</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/hash-implementation.html b/doc/src/sgml/html/hash-implementation.html
new file mode 100644
index 0000000..449299b
--- /dev/null
+++ b/doc/src/sgml/html/hash-implementation.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>72.2. Implementation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="hash-intro.html" title="72.1. Overview" /><link rel="next" href="storage.html" title="Chapter 73. Database Physical Storage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">72.2. Implementation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="hash-intro.html" title="72.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="hash-index.html" title="Chapter 72. Hash Indexes">Up</a></td><th width="60%" align="center">Chapter 72. Hash Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage.html" title="Chapter 73. Database Physical Storage">Next</a></td></tr></table><hr /></div><div class="sect1" id="HASH-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">72.2. Implementation</h2></div></div></div><p>
+ There are four kinds of pages in a hash index: the meta page (page zero),
+ which contains statically allocated control information; primary bucket
+ pages; overflow pages; and bitmap pages, which keep track of overflow
+ pages that have been freed and are available for re-use. For addressing
+ purposes, bitmap pages are regarded as a subset of the overflow pages.
+ </p><p>
+ Both scanning the index and inserting tuples require locating the bucket
+ where a given tuple ought to be located. To do this, we need the bucket
+ count, highmask, and lowmask from the metapage; however, it's undesirable
+ for performance reasons to have to have to lock and pin the metapage for
+ every such operation. Instead, we retain a cached copy of the metapage
+ in each backend's relcache entry. This will produce the correct bucket
+ mapping as long as the target bucket hasn't been split since the last
+ cache refresh.
+ </p><p>
+ Primary bucket pages and overflow pages are allocated independently since
+ any given index might need more or fewer overflow pages relative to its
+ number of buckets. The hash code uses an interesting set of addressing
+ rules to support a variable number of overflow pages while not having to
+ move primary bucket pages around after they are created.
+ </p><p>
+ Each row in the table indexed is represented by a single index tuple in
+ the hash index. Hash index tuples are stored in bucket pages, and if
+ they exist, overflow pages. We speed up searches by keeping the index entries
+ in any one index page sorted by hash code, thus allowing binary search to be
+ used within an index page. Note however that there is *no* assumption about
+ the relative ordering of hash codes across different index pages of a bucket.
+ </p><p>
+ The bucket splitting algorithms to expand the hash index are too complex to
+ be worthy of mention here, though are described in more detail in
+ <code class="filename">src/backend/access/hash/README</code>.
+ The split algorithm is crash safe and can be restarted if not completed
+ successfully.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="hash-intro.html" title="72.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="hash-index.html" title="Chapter 72. Hash Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage.html" title="Chapter 73. Database Physical Storage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">72.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 73. Database Physical Storage</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/hash-index.html b/doc/src/sgml/html/hash-index.html
new file mode 100644
index 0000000..ba41923
--- /dev/null
+++ b/doc/src/sgml/html/hash-index.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 72. Hash Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="brin-extensibility.html" title="71.3. Extensibility" /><link rel="next" href="hash-intro.html" title="72.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 72. Hash Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="brin-extensibility.html" title="71.3. Extensibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="hash-intro.html" title="72.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="HASH-INDEX"><div class="titlepage"><div><div><h2 class="title">Chapter 72. Hash Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="hash-intro.html">72.1. Overview</a></span></dt><dt><span class="sect1"><a href="hash-implementation.html">72.2. Implementation</a></span></dt></dl></div><a id="id-1.10.23.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="brin-extensibility.html" title="71.3. Extensibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="hash-intro.html" title="72.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">71.3. Extensibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 72.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/hash-intro.html b/doc/src/sgml/html/hash-intro.html
new file mode 100644
index 0000000..6a8336c
--- /dev/null
+++ b/doc/src/sgml/html/hash-intro.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>72.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="hash-index.html" title="Chapter 72. Hash Indexes" /><link rel="next" href="hash-implementation.html" title="72.2. Implementation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">72.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="hash-index.html" title="Chapter 72. Hash Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="hash-index.html" title="Chapter 72. Hash Indexes">Up</a></td><th width="60%" align="center">Chapter 72. Hash Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="hash-implementation.html" title="72.2. Implementation">Next</a></td></tr></table><hr /></div><div class="sect1" id="HASH-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">72.1. Overview</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span>
+ includes an implementation of persistent on-disk hash indexes,
+ which are fully crash recoverable. Any data type can be indexed by a
+ hash index, including data types that do not have a well-defined linear
+ ordering. Hash indexes store only the hash value of the data being
+ indexed, thus there are no restrictions on the size of the data column
+ being indexed.
+ </p><p>
+ Hash indexes support only single-column indexes and do not allow
+ uniqueness checking.
+ </p><p>
+ Hash indexes support only the <code class="literal">=</code> operator,
+ so WHERE clauses that specify range operations will not be able to take
+ advantage of hash indexes.
+ </p><p>
+ Each hash index tuple stores just the 4-byte hash value, not the actual
+ column value. As a result, hash indexes may be much smaller than B-trees
+ when indexing longer data items such as UUIDs, URLs, etc. The absence of
+ the column value also makes all hash index scans lossy. Hash indexes may
+ take part in bitmap index scans and backward scans.
+ </p><p>
+ Hash indexes are best optimized for SELECT and UPDATE-heavy workloads
+ that use equality scans on larger tables. In a B-tree index, searches must
+ descend through the tree until the leaf page is found. In tables with
+ millions of rows, this descent can increase access time to data. The
+ equivalent of a leaf page in a hash index is referred to as a bucket page. In
+ contrast, a hash index allows accessing the bucket pages directly,
+ thereby potentially reducing index access time in larger tables. This
+ reduction in "logical I/O" becomes even more pronounced on indexes/data
+ larger than shared_buffers/RAM.
+ </p><p>
+ Hash indexes have been designed to cope with uneven distributions of
+ hash values. Direct access to the bucket pages works well if the hash
+ values are evenly distributed. When inserts mean that the bucket page
+ becomes full, additional overflow pages are chained to that specific
+ bucket page, locally expanding the storage for index tuples that match
+ that hash value. When scanning a hash bucket during queries, we need to
+ scan through all of the overflow pages. Thus an unbalanced hash index
+ might actually be worse than a B-tree in terms of number of block
+ accesses required, for some data.
+ </p><p>
+ As a result of the overflow cases, we can say that hash indexes are
+ most suitable for unique, nearly unique data or data with a low number
+ of rows per hash bucket.
+ One possible way to avoid problems is to exclude highly non-unique
+ values from the index using a partial index condition, but this may
+ not be suitable in many cases.
+ </p><p>
+ Like B-Trees, hash indexes perform simple index tuple deletion. This
+ is a deferred maintenance operation that deletes index tuples that are
+ known to be safe to delete (those whose item identifier's LP_DEAD bit
+ is already set). If an insert finds no space is available on a page we
+ try to avoid creating a new overflow page by attempting to remove dead
+ index tuples. Removal cannot occur if the page is pinned at that time.
+ Deletion of dead index pointers also occurs during VACUUM.
+ </p><p>
+ If it can, VACUUM will also try to squeeze the index tuples onto as
+ few overflow pages as possible, minimizing the overflow chain. If an
+ overflow page becomes empty, overflow pages can be recycled for reuse
+ in other buckets, though we never return them to the operating system.
+ There is currently no provision to shrink a hash index, other than by
+ rebuilding it with REINDEX.
+ There is no provision for reducing the number of buckets, either.
+ </p><p>
+ Hash indexes may expand the number of bucket pages as the number of
+ rows indexed grows. The hash key-to-bucket-number mapping is chosen so that
+ the index can be incrementally expanded. When a new bucket is to be added to
+ the index, exactly one existing bucket will need to be "split", with some of
+ its tuples being transferred to the new bucket according to the updated
+ key-to-bucket-number mapping.
+ </p><p>
+ The expansion occurs in the foreground, which could increase execution
+ time for user inserts. Thus, hash indexes may not be suitable for tables
+ with rapidly increasing number of rows.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="hash-index.html" title="Chapter 72. Hash Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="hash-index.html" title="Chapter 72. Hash Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="hash-implementation.html" title="72.2. Implementation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 72. Hash Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 72.2. Implementation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/high-availability.html b/doc/src/sgml/html/high-availability.html
new file mode 100644
index 0000000..bd7e749
--- /dev/null
+++ b/doc/src/sgml/html/high-availability.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 27. High Availability, Load Balancing, and Replication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)" /><link rel="next" href="different-replication-solutions.html" title="27.1. Comparison of Different Solutions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 27. High Availability, Load Balancing, and Replication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="different-replication-solutions.html" title="27.1. Comparison of Different Solutions">Next</a></td></tr></table><hr /></div><div class="chapter" id="HIGH-AVAILABILITY"><div class="titlepage"><div><div><h2 class="title">Chapter 27. High Availability, Load Balancing, and Replication</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="different-replication-solutions.html">27.1. Comparison of Different Solutions</a></span></dt><dt><span class="sect1"><a href="warm-standby.html">27.2. Log-Shipping Standby Servers</a></span></dt><dd><dl><dt><span class="sect2"><a href="warm-standby.html#STANDBY-PLANNING">27.2.1. Planning</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STANDBY-SERVER-OPERATION">27.2.2. Standby Server Operation</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#PREPARING-PRIMARY-FOR-STANDBY">27.2.3. Preparing the Primary for Standby Servers</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STANDBY-SERVER-SETUP">27.2.4. Setting Up a Standby Server</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STREAMING-REPLICATION">27.2.5. Streaming Replication</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STREAMING-REPLICATION-SLOTS">27.2.6. Replication Slots</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#CASCADING-REPLICATION">27.2.7. Cascading Replication</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#SYNCHRONOUS-REPLICATION">27.2.8. Synchronous Replication</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#CONTINUOUS-ARCHIVING-IN-STANDBY">27.2.9. Continuous Archiving in Standby</a></span></dt></dl></dd><dt><span class="sect1"><a href="warm-standby-failover.html">27.3. Failover</a></span></dt><dt><span class="sect1"><a href="hot-standby.html">27.4. Hot Standby</a></span></dt><dd><dl><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-USERS">27.4.1. User's Overview</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-CONFLICT">27.4.2. Handling Query Conflicts</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-ADMIN">27.4.3. Administrator's Overview</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-PARAMETERS">27.4.4. Hot Standby Parameter Reference</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-CAVEATS">27.4.5. Caveats</a></span></dt></dl></dd></dl></div><a id="id-1.6.14.2" class="indexterm"></a><a id="id-1.6.14.3" class="indexterm"></a><a id="id-1.6.14.4" class="indexterm"></a><a id="id-1.6.14.5" class="indexterm"></a><a id="id-1.6.14.6" class="indexterm"></a><a id="id-1.6.14.7" class="indexterm"></a><p>
+ Database servers can work together to allow a second server to
+ take over quickly if the primary server fails (high
+ availability), or to allow several computers to serve the same
+ data (load balancing). Ideally, database servers could work
+ together seamlessly. Web servers serving static web pages can
+ be combined quite easily by merely load-balancing web requests
+ to multiple machines. In fact, read-only database servers can
+ be combined relatively easily too. Unfortunately, most database
+ servers have a read/write mix of requests, and read/write servers
+ are much harder to combine. This is because though read-only
+ data needs to be placed on each server only once, a write to any
+ server has to be propagated to all servers so that future read
+ requests to those servers return consistent results.
+ </p><p>
+ This synchronization problem is the fundamental difficulty for
+ servers working together. Because there is no single solution
+ that eliminates the impact of the sync problem for all use cases,
+ there are multiple solutions. Each solution addresses this
+ problem in a different way, and minimizes its impact for a specific
+ workload.
+ </p><p>
+ Some solutions deal with synchronization by allowing only one
+ server to modify the data. Servers that can modify data are
+ called read/write, <em class="firstterm">master</em> or <em class="firstterm">primary</em> servers.
+ Servers that track changes in the primary are called <em class="firstterm">standby</em>
+ or <em class="firstterm">secondary</em> servers. A standby server that cannot be connected
+ to until it is promoted to a primary server is called a <em class="firstterm">warm
+ standby</em> server, and one that can accept connections and serves read-only
+ queries is called a <em class="firstterm">hot standby</em> server.
+ </p><p>
+ Some solutions are synchronous,
+ meaning that a data-modifying transaction is not considered
+ committed until all servers have committed the transaction. This
+ guarantees that a failover will not lose any data and that all
+ load-balanced servers will return consistent results no matter
+ which server is queried. In contrast, asynchronous solutions allow some
+ delay between the time of a commit and its propagation to the other servers,
+ opening the possibility that some transactions might be lost in
+ the switch to a backup server, and that load balanced servers
+ might return slightly stale results. Asynchronous communication
+ is used when synchronous would be too slow.
+ </p><p>
+ Solutions can also be categorized by their granularity. Some solutions
+ can deal only with an entire database server, while others allow control
+ at the per-table or per-database level.
+ </p><p>
+ Performance must be considered in any choice. There is usually a
+ trade-off between functionality and
+ performance. For example, a fully synchronous solution over a slow
+ network might cut performance by more than half, while an asynchronous
+ one might have a minimal performance impact.
+ </p><p>
+ The remainder of this section outlines various failover, replication,
+ and load balancing solutions.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="different-replication-solutions.html" title="27.1. Comparison of Different Solutions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">26.3. Continuous Archiving and Point-in-Time Recovery (PITR) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 27.1. Comparison of Different Solutions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/history.html b/doc/src/sgml/html/history.html
new file mode 100644
index 0000000..8a391c9
--- /dev/null
+++ b/doc/src/sgml/html/history.html
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2. A Brief History of PostgreSQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="intro-whatis.html" title="1.  What Is PostgreSQL?" /><link rel="next" href="notation.html" title="3. Conventions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2. A Brief History of <span class="productname">PostgreSQL</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="intro-whatis.html" title="1.  What Is PostgreSQL?">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><th width="60%" align="center">Preface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="notation.html" title="3. Conventions">Next</a></td></tr></table><hr /></div><div class="sect1" id="HISTORY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2. A Brief History of <span class="productname">PostgreSQL</span></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="history.html#HISTORY-BERKELEY">2.1. The Berkeley <span class="productname">POSTGRES</span> Project</a></span></dt><dt><span class="sect2"><a href="history.html#HISTORY-POSTGRES95">2.2. <span class="productname">Postgres95</span></a></span></dt><dt><span class="sect2"><a href="history.html#id-1.3.5.6">2.3. <span class="productname">PostgreSQL</span></a></span></dt></dl></div><a id="id-1.3.5.2" class="indexterm"></a><p>
+ The object-relational database management system now known as
+ <span class="productname">PostgreSQL</span> is derived from the
+ <span class="productname">POSTGRES</span> package written at the
+ University of California at Berkeley. With decades of
+ development behind it, <span class="productname">PostgreSQL</span> is now
+ the most advanced open-source database available anywhere.
+ </p><div class="sect2" id="HISTORY-BERKELEY"><div class="titlepage"><div><div><h3 class="title">2.1. The Berkeley <span class="productname">POSTGRES</span> Project</h3></div></div></div><a id="id-1.3.5.4.2" class="indexterm"></a><p>
+ The <span class="productname">POSTGRES</span> project, led by Professor
+ Michael Stonebraker, was sponsored by the Defense Advanced Research
+ Projects Agency (<acronym class="acronym">DARPA</acronym>), the Army Research
+ Office (<acronym class="acronym">ARO</acronym>), the National Science Foundation
+ (<acronym class="acronym">NSF</acronym>), and ESL, Inc. The implementation of
+ <span class="productname">POSTGRES</span> began in 1986. The initial
+ concepts for the system were presented in <a class="xref" href="biblio.html#STON86">[ston86]</a>,
+ and the definition of the initial data model appeared in <a class="xref" href="biblio.html#ROWE87">[rowe87]</a>. The design of the rule system at that time was
+ described in <a class="xref" href="biblio.html#STON87A">[ston87a]</a>. The rationale and
+ architecture of the storage manager were detailed in <a class="xref" href="biblio.html#STON87B">[ston87b]</a>.
+ </p><p>
+ <span class="productname">POSTGRES</span> has undergone several major
+ releases since then. The first <span class="quote">“<span class="quote">demoware</span>”</span> system
+ became operational in 1987 and was shown at the 1988
+ <acronym class="acronym">ACM-SIGMOD</acronym> Conference. Version 1, described in
+ <a class="xref" href="biblio.html#STON90A">[ston90a]</a>, was released to a few external users in
+ June 1989. In response to a critique of the first rule system
+ (<a class="xref" href="biblio.html#STON89">[ston89]</a>), the rule system was redesigned (<a class="xref" href="biblio.html#STON90B">[ston90b]</a>), and Version 2 was released in June 1990 with
+ the new rule system. Version 3 appeared in 1991 and added support
+ for multiple storage managers, an improved query executor, and a
+ rewritten rule system. For the most part, subsequent releases
+ until <span class="productname">Postgres95</span> (see below) focused on
+ portability and reliability.
+ </p><p>
+ <span class="productname">POSTGRES</span> has been used to implement many
+ different research and production applications. These include: a
+ financial data analysis system, a jet engine performance monitoring
+ package, an asteroid tracking database, a medical information
+ database, and several geographic information systems.
+ <span class="productname">POSTGRES</span> has also been used as an
+ educational tool at several universities. Finally, Illustra
+ Information Technologies (later merged into
+ <a class="ulink" href="https://www.ibm.com/analytics/informix" target="_top"><span class="productname">Informix</span></a>,
+ which is now owned by <a class="ulink" href="https://www.ibm.com/" target="_top">IBM</a>) picked up the code and
+ commercialized it. In late 1992,
+ <span class="productname">POSTGRES</span> became the primary data manager
+ for the
+ <a class="ulink" href="http://meteora.ucsd.edu/s2k/s2k_home.html" target="_top">
+ Sequoia 2000 scientific computing project</a>.
+ </p><p>
+ The size of the external user community nearly doubled during 1993.
+ It became increasingly obvious that maintenance of the prototype
+ code and support was taking up large amounts of time that should
+ have been devoted to database research. In an effort to reduce
+ this support burden, the Berkeley
+ <span class="productname">POSTGRES</span> project officially ended with
+ Version 4.2.
+ </p></div><div class="sect2" id="HISTORY-POSTGRES95"><div class="titlepage"><div><div><h3 class="title">2.2. <span class="productname">Postgres95</span></h3></div></div></div><a id="id-1.3.5.5.2" class="indexterm"></a><p>
+ In 1994, Andrew Yu and Jolly Chen added an SQL language interpreter
+ to <span class="productname">POSTGRES</span>. Under a new name,
+ <span class="productname">Postgres95</span> was subsequently released to
+ the web to find its own way in the world as an open-source
+ descendant of the original <span class="productname">POSTGRES</span>
+ Berkeley code.
+ </p><p>
+ <span class="productname">Postgres95</span> code was completely ANSI C
+ and trimmed in size by 25%. Many internal changes improved
+ performance and
+ maintainability. <span class="productname">Postgres95</span> release
+ 1.0.x ran about 30–50% faster on the Wisconsin Benchmark compared
+ to <span class="productname">POSTGRES</span>, Version 4.2. Apart from
+ bug fixes, the following were the major enhancements:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The query language PostQUEL was replaced with
+ <acronym class="acronym">SQL</acronym> (implemented in the server). (Interface
+ library <a class="link" href="libpq.html" title="Chapter 34. libpq — C Library">libpq</a> was named after PostQUEL.)
+ Subqueries
+ were not supported until <span class="productname">PostgreSQL</span>
+ (see below), but they could be imitated in
+ <span class="productname">Postgres95</span> with user-defined
+ <acronym class="acronym">SQL</acronym> functions. Aggregate functions were
+ re-implemented. Support for the <code class="literal">GROUP BY</code>
+ query clause was also added.
+ </p></li><li class="listitem"><p>
+ A new program
+ (<span class="application">psql</span>) was provided for interactive
+ SQL queries, which used <acronym class="acronym">GNU</acronym>
+ <span class="application">Readline</span>. This largely superseded
+ the old <span class="application">monitor</span> program.
+ </p></li><li class="listitem"><p>
+ A new front-end library, <code class="filename">libpgtcl</code>,
+ supported <acronym class="acronym">Tcl</acronym>-based clients. A sample shell,
+ <code class="command">pgtclsh</code>, provided new Tcl commands to
+ interface <span class="application">Tcl</span> programs with the
+ <span class="productname">Postgres95</span> server.
+ </p></li><li class="listitem"><p>
+ The large-object interface was overhauled. The inversion large
+ objects were the only mechanism for storing large objects. (The
+ inversion file system was removed.)
+ </p></li><li class="listitem"><p>
+ The instance-level rule system was removed. Rules were still
+ available as rewrite rules.
+ </p></li><li class="listitem"><p>
+ A short tutorial introducing regular <acronym class="acronym">SQL</acronym>
+ features as well as those of
+ <span class="productname">Postgres95</span> was distributed with the
+ source code
+ </p></li><li class="listitem"><p>
+ <acronym class="acronym">GNU</acronym> make (instead of <acronym class="acronym">BSD</acronym>
+ make) was used for the build. Also,
+ <span class="productname">Postgres95</span> could be compiled with an
+ unpatched <span class="productname">GCC</span> (data alignment of
+ doubles was fixed).
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="id-1.3.5.6"><div class="titlepage"><div><div><h3 class="title">2.3. <span class="productname">PostgreSQL</span></h3></div></div></div><p>
+ By 1996, it became clear that the name <span class="quote">“<span class="quote">Postgres95</span>”</span>
+ would not stand the test of time. We chose a new name,
+ <span class="productname">PostgreSQL</span>, to reflect the relationship
+ between the original <span class="productname">POSTGRES</span> and the
+ more recent versions with <acronym class="acronym">SQL</acronym> capability. At
+ the same time, we set the version numbering to start at 6.0,
+ putting the numbers back into the sequence originally begun by the
+ Berkeley <span class="productname">POSTGRES</span> project.
+ </p><p>
+ Many people continue to refer to
+ <span class="productname">PostgreSQL</span> as <span class="quote">“<span class="quote">Postgres</span>”</span>
+ (now rarely in all capital letters) because of tradition or because
+ it is easier to pronounce. This usage is widely accepted as a
+ nickname or alias.
+ </p><p>
+ The emphasis during development of
+ <span class="productname">Postgres95</span> was on identifying and
+ understanding existing problems in the server code. With
+ <span class="productname">PostgreSQL</span>, the emphasis has shifted to
+ augmenting features and capabilities, although work continues in
+ all areas.
+ </p><p>
+ Details about what has happened in <span class="productname">PostgreSQL</span> since
+ then can be found in <a class="xref" href="release.html" title="Appendix E. Release Notes">Appendix E</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="intro-whatis.html" title="1.  What Is PostgreSQL?">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="notation.html" title="3. Conventions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1.  What Is <span class="productname">PostgreSQL</span>? </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3. Conventions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/hot-standby.html b/doc/src/sgml/html/hot-standby.html
new file mode 100644
index 0000000..bc09a9f
--- /dev/null
+++ b/doc/src/sgml/html/hot-standby.html
@@ -0,0 +1,575 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>27.4. Hot Standby</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="warm-standby-failover.html" title="27.3. Failover" /><link rel="next" href="monitoring.html" title="Chapter 28. Monitoring Database Activity" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">27.4. Hot Standby</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="warm-standby-failover.html" title="27.3. Failover">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><th width="60%" align="center">Chapter 27. High Availability, Load Balancing, and Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Next</a></td></tr></table><hr /></div><div class="sect1" id="HOT-STANDBY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">27.4. Hot Standby</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-USERS">27.4.1. User's Overview</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-CONFLICT">27.4.2. Handling Query Conflicts</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-ADMIN">27.4.3. Administrator's Overview</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-PARAMETERS">27.4.4. Hot Standby Parameter Reference</a></span></dt><dt><span class="sect2"><a href="hot-standby.html#HOT-STANDBY-CAVEATS">27.4.5. Caveats</a></span></dt></dl></div><a id="id-1.6.14.18.2" class="indexterm"></a><p>
+ Hot standby is the term used to describe the ability to connect to
+ the server and run read-only queries while the server is in archive
+ recovery or standby mode. This
+ is useful both for replication purposes and for restoring a backup
+ to a desired state with great precision.
+ The term hot standby also refers to the ability of the server to move
+ from recovery through to normal operation while users continue running
+ queries and/or keep their connections open.
+ </p><p>
+ Running queries in hot standby mode is similar to normal query operation,
+ though there are several usage and administrative differences
+ explained below.
+ </p><div class="sect2" id="HOT-STANDBY-USERS"><div class="titlepage"><div><div><h3 class="title">27.4.1. User's Overview</h3></div></div></div><p>
+ When the <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY">hot_standby</a> parameter is set to true on a
+ standby server, it will begin accepting connections once the recovery has
+ brought the system to a consistent state. All such connections are
+ strictly read-only; not even temporary tables may be written.
+ </p><p>
+ The data on the standby takes some time to arrive from the primary server
+ so there will be a measurable delay between primary and standby. Running the
+ same query nearly simultaneously on both primary and standby might therefore
+ return differing results. We say that data on the standby is
+ <em class="firstterm">eventually consistent</em> with the primary. Once the
+ commit record for a transaction is replayed on the standby, the changes
+ made by that transaction will be visible to any new snapshots taken on
+ the standby. Snapshots may be taken at the start of each query or at the
+ start of each transaction, depending on the current transaction isolation
+ level. For more details, see <a class="xref" href="transaction-iso.html" title="13.2. Transaction Isolation">Section 13.2</a>.
+ </p><p>
+ Transactions started during hot standby may issue the following commands:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Query access: <code class="command">SELECT</code>, <code class="command">COPY TO</code>
+ </p></li><li class="listitem"><p>
+ Cursor commands: <code class="command">DECLARE</code>, <code class="command">FETCH</code>, <code class="command">CLOSE</code>
+ </p></li><li class="listitem"><p>
+ Settings: <code class="command">SHOW</code>, <code class="command">SET</code>, <code class="command">RESET</code>
+ </p></li><li class="listitem"><p>
+ Transaction management commands:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ <code class="command">BEGIN</code>, <code class="command">END</code>, <code class="command">ABORT</code>, <code class="command">START TRANSACTION</code>
+ </p></li><li class="listitem"><p>
+ <code class="command">SAVEPOINT</code>, <code class="command">RELEASE</code>, <code class="command">ROLLBACK TO SAVEPOINT</code>
+ </p></li><li class="listitem"><p>
+ <code class="command">EXCEPTION</code> blocks and other internal subtransactions
+ </p></li></ul></div><p>
+ </p></li><li class="listitem"><p>
+ <code class="command">LOCK TABLE</code>, though only when explicitly in one of these modes:
+ <code class="literal">ACCESS SHARE</code>, <code class="literal">ROW SHARE</code> or <code class="literal">ROW EXCLUSIVE</code>.
+ </p></li><li class="listitem"><p>
+ Plans and resources: <code class="command">PREPARE</code>, <code class="command">EXECUTE</code>,
+ <code class="command">DEALLOCATE</code>, <code class="command">DISCARD</code>
+ </p></li><li class="listitem"><p>
+ Plugins and extensions: <code class="command">LOAD</code>
+ </p></li><li class="listitem"><p>
+ <code class="command">UNLISTEN</code>
+ </p></li></ul></div><p>
+ </p><p>
+ Transactions started during hot standby will never be assigned a
+ transaction ID and cannot write to the system write-ahead log.
+ Therefore, the following actions will produce error messages:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Data Manipulation Language (DML): <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ <code class="command">MERGE</code>, <code class="command">COPY FROM</code>,
+ <code class="command">TRUNCATE</code>.
+ Note that there are no allowed actions that result in a trigger
+ being executed during recovery. This restriction applies even to
+ temporary tables, because table rows cannot be read or written without
+ assigning a transaction ID, which is currently not possible in a
+ hot standby environment.
+ </p></li><li class="listitem"><p>
+ Data Definition Language (DDL): <code class="command">CREATE</code>,
+ <code class="command">DROP</code>, <code class="command">ALTER</code>, <code class="command">COMMENT</code>.
+ This restriction applies even to temporary tables, because carrying
+ out these operations would require updating the system catalog tables.
+ </p></li><li class="listitem"><p>
+ <code class="command">SELECT ... FOR SHARE | UPDATE</code>, because row locks cannot be
+ taken without updating the underlying data files.
+ </p></li><li class="listitem"><p>
+ Rules on <code class="command">SELECT</code> statements that generate DML commands.
+ </p></li><li class="listitem"><p>
+ <code class="command">LOCK</code> that explicitly requests a mode higher than <code class="literal">ROW EXCLUSIVE MODE</code>.
+ </p></li><li class="listitem"><p>
+ <code class="command">LOCK</code> in short default form, since it requests <code class="literal">ACCESS EXCLUSIVE MODE</code>.
+ </p></li><li class="listitem"><p>
+ Transaction management commands that explicitly set non-read-only state:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ <code class="command">BEGIN READ WRITE</code>,
+ <code class="command">START TRANSACTION READ WRITE</code>
+ </p></li><li class="listitem"><p>
+ <code class="command">SET TRANSACTION READ WRITE</code>,
+ <code class="command">SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE</code>
+ </p></li><li class="listitem"><p>
+ <code class="command">SET transaction_read_only = off</code>
+ </p></li></ul></div><p>
+ </p></li><li class="listitem"><p>
+ Two-phase commit commands: <code class="command">PREPARE TRANSACTION</code>,
+ <code class="command">COMMIT PREPARED</code>, <code class="command">ROLLBACK PREPARED</code>
+ because even read-only transactions need to write WAL in the
+ prepare phase (the first phase of two phase commit).
+ </p></li><li class="listitem"><p>
+ Sequence updates: <code class="function">nextval()</code>, <code class="function">setval()</code>
+ </p></li><li class="listitem"><p>
+ <code class="command">LISTEN</code>, <code class="command">NOTIFY</code>
+ </p></li></ul></div><p>
+ </p><p>
+ In normal operation, <span class="quote">“<span class="quote">read-only</span>”</span> transactions are allowed to
+ use <code class="command">LISTEN</code> and <code class="command">NOTIFY</code>,
+ so hot standby sessions operate under slightly tighter
+ restrictions than ordinary read-only sessions. It is possible that some
+ of these restrictions might be loosened in a future release.
+ </p><p>
+ During hot standby, the parameter <code class="varname">transaction_read_only</code> is always
+ true and may not be changed. But as long as no attempt is made to modify
+ the database, connections during hot standby will act much like any other
+ database connection. If failover or switchover occurs, the database will
+ switch to normal processing mode. Sessions will remain connected while the
+ server changes mode. Once hot standby finishes, it will be possible to
+ initiate read-write transactions (even from a session begun during
+ hot standby).
+ </p><p>
+ Users can determine whether hot standby is currently active for their
+ session by issuing <code class="command">SHOW in_hot_standby</code>.
+ (In server versions before 14, the <code class="varname">in_hot_standby</code>
+ parameter did not exist; a workable substitute method for older servers
+ is <code class="command">SHOW transaction_read_only</code>.) In addition, a set of
+ functions (<a class="xref" href="functions-admin.html#FUNCTIONS-RECOVERY-INFO-TABLE" title="Table 9.90. Recovery Information Functions">Table 9.90</a>) allow users to
+ access information about the standby server. These allow you to write
+ programs that are aware of the current state of the database. These
+ can be used to monitor the progress of recovery, or to allow you to
+ write complex programs that restore the database to particular states.
+ </p></div><div class="sect2" id="HOT-STANDBY-CONFLICT"><div class="titlepage"><div><div><h3 class="title">27.4.2. Handling Query Conflicts</h3></div></div></div><p>
+ The primary and standby servers are in many ways loosely connected. Actions
+ on the primary will have an effect on the standby. As a result, there is
+ potential for negative interactions or conflicts between them. The easiest
+ conflict to understand is performance: if a huge data load is taking place
+ on the primary then this will generate a similar stream of WAL records on the
+ standby, so standby queries may contend for system resources, such as I/O.
+ </p><p>
+ There are also additional types of conflict that can occur with hot standby.
+ These conflicts are <span class="emphasis"><em>hard conflicts</em></span> in the sense that queries
+ might need to be canceled and, in some cases, sessions disconnected to resolve them.
+ The user is provided with several ways to handle these
+ conflicts. Conflict cases include:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Access Exclusive locks taken on the primary server, including both
+ explicit <code class="command">LOCK</code> commands and various <acronym class="acronym">DDL</acronym>
+ actions, conflict with table accesses in standby queries.
+ </p></li><li class="listitem"><p>
+ Dropping a tablespace on the primary conflicts with standby queries
+ using that tablespace for temporary work files.
+ </p></li><li class="listitem"><p>
+ Dropping a database on the primary conflicts with sessions connected
+ to that database on the standby.
+ </p></li><li class="listitem"><p>
+ Application of a vacuum cleanup record from WAL conflicts with
+ standby transactions whose snapshots can still <span class="quote">“<span class="quote">see</span>”</span> any of
+ the rows to be removed.
+ </p></li><li class="listitem"><p>
+ Application of a vacuum cleanup record from WAL conflicts with
+ queries accessing the target page on the standby, whether or not
+ the data to be removed is visible.
+ </p></li></ul></div><p>
+ </p><p>
+ On the primary server, these cases simply result in waiting; and the
+ user might choose to cancel either of the conflicting actions. However,
+ on the standby there is no choice: the WAL-logged action already occurred
+ on the primary so the standby must not fail to apply it. Furthermore,
+ allowing WAL application to wait indefinitely may be very undesirable,
+ because the standby's state will become increasingly far behind the
+ primary's. Therefore, a mechanism is provided to forcibly cancel standby
+ queries that conflict with to-be-applied WAL records.
+ </p><p>
+ An example of the problem situation is an administrator on the primary
+ server running <code class="command">DROP TABLE</code> on a table that is currently being
+ queried on the standby server. Clearly the standby query cannot continue
+ if the <code class="command">DROP TABLE</code> is applied on the standby. If this situation
+ occurred on the primary, the <code class="command">DROP TABLE</code> would wait until the
+ other query had finished. But when <code class="command">DROP TABLE</code> is run on the
+ primary, the primary doesn't have information about what queries are
+ running on the standby, so it will not wait for any such standby
+ queries. The WAL change records come through to the standby while the
+ standby query is still running, causing a conflict. The standby server
+ must either delay application of the WAL records (and everything after
+ them, too) or else cancel the conflicting query so that the <code class="command">DROP
+ TABLE</code> can be applied.
+ </p><p>
+ When a conflicting query is short, it's typically desirable to allow it to
+ complete by delaying WAL application for a little bit; but a long delay in
+ WAL application is usually not desirable. So the cancel mechanism has
+ parameters, <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY">max_standby_archive_delay</a> and <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY">max_standby_streaming_delay</a>, that define the maximum
+ allowed delay in WAL application. Conflicting queries will be canceled
+ once it has taken longer than the relevant delay setting to apply any
+ newly-received WAL data. There are two parameters so that different delay
+ values can be specified for the case of reading WAL data from an archive
+ (i.e., initial recovery from a base backup or <span class="quote">“<span class="quote">catching up</span>”</span> a
+ standby server that has fallen far behind) versus reading WAL data via
+ streaming replication.
+ </p><p>
+ In a standby server that exists primarily for high availability, it's
+ best to set the delay parameters relatively short, so that the server
+ cannot fall far behind the primary due to delays caused by standby
+ queries. However, if the standby server is meant for executing
+ long-running queries, then a high or even infinite delay value may be
+ preferable. Keep in mind however that a long-running query could
+ cause other sessions on the standby server to not see recent changes
+ on the primary, if it delays application of WAL records.
+ </p><p>
+ Once the delay specified by <code class="varname">max_standby_archive_delay</code> or
+ <code class="varname">max_standby_streaming_delay</code> has been exceeded, conflicting
+ queries will be canceled. This usually results just in a cancellation
+ error, although in the case of replaying a <code class="command">DROP DATABASE</code>
+ the entire conflicting session will be terminated. Also, if the conflict
+ is over a lock held by an idle transaction, the conflicting session is
+ terminated (this behavior might change in the future).
+ </p><p>
+ Canceled queries may be retried immediately (after beginning a new
+ transaction, of course). Since query cancellation depends on
+ the nature of the WAL records being replayed, a query that was
+ canceled may well succeed if it is executed again.
+ </p><p>
+ Keep in mind that the delay parameters are compared to the elapsed time
+ since the WAL data was received by the standby server. Thus, the grace
+ period allowed to any one query on the standby is never more than the
+ delay parameter, and could be considerably less if the standby has already
+ fallen behind as a result of waiting for previous queries to complete, or
+ as a result of being unable to keep up with a heavy update load.
+ </p><p>
+ The most common reason for conflict between standby queries and WAL replay
+ is <span class="quote">“<span class="quote">early cleanup</span>”</span>. Normally, <span class="productname">PostgreSQL</span> allows
+ cleanup of old row versions when there are no transactions that need to
+ see them to ensure correct visibility of data according to MVCC rules.
+ However, this rule can only be applied for transactions executing on the
+ primary. So it is possible that cleanup on the primary will remove row
+ versions that are still visible to a transaction on the standby.
+ </p><p>
+ Experienced users should note that both row version cleanup and row version
+ freezing will potentially conflict with standby queries. Running a manual
+ <code class="command">VACUUM FREEZE</code> is likely to cause conflicts even on tables with
+ no updated or deleted rows.
+ </p><p>
+ Users should be clear that tables that are regularly and heavily updated
+ on the primary server will quickly cause cancellation of longer running
+ queries on the standby. In such cases the setting of a finite value for
+ <code class="varname">max_standby_archive_delay</code> or
+ <code class="varname">max_standby_streaming_delay</code> can be considered similar to
+ setting <code class="varname">statement_timeout</code>.
+ </p><p>
+ Remedial possibilities exist if the number of standby-query cancellations
+ is found to be unacceptable. The first option is to set the parameter
+ <code class="varname">hot_standby_feedback</code>, which prevents <code class="command">VACUUM</code> from
+ removing recently-dead rows and so cleanup conflicts do not occur.
+ If you do this, you
+ should note that this will delay cleanup of dead rows on the primary,
+ which may result in undesirable table bloat. However, the cleanup
+ situation will be no worse than if the standby queries were running
+ directly on the primary server, and you are still getting the benefit of
+ off-loading execution onto the standby.
+ If standby servers connect and disconnect frequently, you
+ might want to make adjustments to handle the period when
+ <code class="varname">hot_standby_feedback</code> feedback is not being provided.
+ For example, consider increasing <code class="varname">max_standby_archive_delay</code>
+ so that queries are not rapidly canceled by conflicts in WAL archive
+ files during disconnected periods. You should also consider increasing
+ <code class="varname">max_standby_streaming_delay</code> to avoid rapid cancellations
+ by newly-arrived streaming WAL entries after reconnection.
+ </p><p>
+ Another option is to increase <a class="xref" href="runtime-config-replication.html#GUC-VACUUM-DEFER-CLEANUP-AGE">vacuum_defer_cleanup_age</a>
+ on the primary server, so that dead rows will not be cleaned up as quickly
+ as they normally would be. This will allow more time for queries to
+ execute before they are canceled on the standby, without having to set
+ a high <code class="varname">max_standby_streaming_delay</code>. However it is
+ difficult to guarantee any specific execution-time window with this
+ approach, since <code class="varname">vacuum_defer_cleanup_age</code> is measured in
+ transactions executed on the primary server.
+ </p><p>
+ The number of query cancels and the reason for them can be viewed using
+ the <code class="structname">pg_stat_database_conflicts</code> system view on the standby
+ server. The <code class="structname">pg_stat_database</code> system view also contains
+ summary information.
+ </p><p>
+ Users can control whether a log message is produced when WAL replay is waiting
+ longer than <code class="varname">deadlock_timeout</code> for conflicts. This
+ is controlled by the <a class="xref" href="runtime-config-logging.html#GUC-LOG-RECOVERY-CONFLICT-WAITS">log_recovery_conflict_waits</a> parameter.
+ </p></div><div class="sect2" id="HOT-STANDBY-ADMIN"><div class="titlepage"><div><div><h3 class="title">27.4.3. Administrator's Overview</h3></div></div></div><p>
+ If <code class="varname">hot_standby</code> is <code class="literal">on</code> in <code class="filename">postgresql.conf</code>
+ (the default value) and there is a
+ <a class="link" href="warm-standby.html#FILE-STANDBY-SIGNAL"><code class="filename">standby.signal</code></a><a id="id-1.6.14.18.7.2.5" class="indexterm"></a>
+ file present, the server will run in hot standby mode.
+ However, it may take some time for hot standby connections to be allowed,
+ because the server will not accept connections until it has completed
+ sufficient recovery to provide a consistent state against which queries
+ can run. During this period,
+ clients that attempt to connect will be refused with an error message.
+ To confirm the server has come up, either loop trying to connect from
+ the application, or look for these messages in the server logs:
+
+</p><pre class="programlisting">
+LOG: entering standby mode
+
+... then some time later ...
+
+LOG: consistent recovery state reached
+LOG: database system is ready to accept read-only connections
+</pre><p>
+
+ Consistency information is recorded once per checkpoint on the primary.
+ It is not possible to enable hot standby when reading WAL
+ written during a period when <code class="varname">wal_level</code> was not set to
+ <code class="literal">replica</code> or <code class="literal">logical</code> on the primary. Reaching
+ a consistent state can also be delayed in the presence of both of these
+ conditions:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A write transaction has more than 64 subtransactions
+ </p></li><li class="listitem"><p>
+ Very long-lived write transactions
+ </p></li></ul></div><p>
+
+ If you are running file-based log shipping ("warm standby"), you might need
+ to wait until the next WAL file arrives, which could be as long as the
+ <code class="varname">archive_timeout</code> setting on the primary.
+ </p><p>
+ The settings of some parameters determine the size of shared memory for
+ tracking transaction IDs, locks, and prepared transactions. These shared
+ memory structures must be no smaller on a standby than on the primary in
+ order to ensure that the standby does not run out of shared memory during
+ recovery. For example, if the primary had used a prepared transaction but
+ the standby had not allocated any shared memory for tracking prepared
+ transactions, then recovery could not continue until the standby's
+ configuration is changed. The parameters affected are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="varname">max_connections</code>
+ </p></li><li class="listitem"><p>
+ <code class="varname">max_prepared_transactions</code>
+ </p></li><li class="listitem"><p>
+ <code class="varname">max_locks_per_transaction</code>
+ </p></li><li class="listitem"><p>
+ <code class="varname">max_wal_senders</code>
+ </p></li><li class="listitem"><p>
+ <code class="varname">max_worker_processes</code>
+ </p></li></ul></div><p>
+
+ The easiest way to ensure this does not become a problem is to have these
+ parameters set on the standbys to values equal to or greater than on the
+ primary. Therefore, if you want to increase these values, you should do
+ so on all standby servers first, before applying the changes to the
+ primary server. Conversely, if you want to decrease these values, you
+ should do so on the primary server first, before applying the changes to
+ all standby servers. Keep in mind that when a standby is promoted, it
+ becomes the new reference for the required parameter settings for the
+ standbys that follow it. Therefore, to avoid this becoming a problem
+ during a switchover or failover, it is recommended to keep these settings
+ the same on all standby servers.
+ </p><p>
+ The WAL tracks changes to these parameters on the
+ primary. If a hot standby processes WAL that indicates that the current
+ value on the primary is higher than its own value, it will log a warning
+ and pause recovery, for example:
+</p><pre class="screen">
+WARNING: hot standby is not possible because of insufficient parameter settings
+DETAIL: max_connections = 80 is a lower setting than on the primary server, where its value was 100.
+LOG: recovery has paused
+DETAIL: If recovery is unpaused, the server will shut down.
+HINT: You can then restart the server after making the necessary configuration changes.
+</pre><p>
+ At that point, the settings on the standby need to be updated and the
+ instance restarted before recovery can continue. If the standby is not a
+ hot standby, then when it encounters the incompatible parameter change, it
+ will shut down immediately without pausing, since there is then no value
+ in keeping it up.
+ </p><p>
+ It is important that the administrator select appropriate settings for
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY">max_standby_archive_delay</a> and <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY">max_standby_streaming_delay</a>. The best choices vary
+ depending on business priorities. For example if the server is primarily
+ tasked as a High Availability server, then you will want low delay
+ settings, perhaps even zero, though that is a very aggressive setting. If
+ the standby server is tasked as an additional server for decision support
+ queries then it might be acceptable to set the maximum delay values to
+ many hours, or even -1 which means wait forever for queries to complete.
+ </p><p>
+ Transaction status "hint bits" written on the primary are not WAL-logged,
+ so data on the standby will likely re-write the hints again on the standby.
+ Thus, the standby server will still perform disk writes even though
+ all users are read-only; no changes occur to the data values
+ themselves. Users will still write large sort temporary files and
+ re-generate relcache info files, so no part of the database
+ is truly read-only during hot standby mode.
+ Note also that writes to remote databases using
+ <span class="application">dblink</span> module, and other operations outside the
+ database using PL functions will still be possible, even though the
+ transaction is read-only locally.
+ </p><p>
+ The following types of administration commands are not accepted
+ during recovery mode:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Data Definition Language (DDL): e.g., <code class="command">CREATE INDEX</code>
+ </p></li><li class="listitem"><p>
+ Privilege and Ownership: <code class="command">GRANT</code>, <code class="command">REVOKE</code>,
+ <code class="command">REASSIGN</code>
+ </p></li><li class="listitem"><p>
+ Maintenance commands: <code class="command">ANALYZE</code>, <code class="command">VACUUM</code>,
+ <code class="command">CLUSTER</code>, <code class="command">REINDEX</code>
+ </p></li></ul></div><p>
+ </p><p>
+ Again, note that some of these commands are actually allowed during
+ "read only" mode transactions on the primary.
+ </p><p>
+ As a result, you cannot create additional indexes that exist solely
+ on the standby, nor statistics that exist solely on the standby.
+ If these administration commands are needed, they should be executed
+ on the primary, and eventually those changes will propagate to the
+ standby.
+ </p><p>
+ <code class="function">pg_cancel_backend()</code>
+ and <code class="function">pg_terminate_backend()</code> will work on user backends,
+ but not the startup process, which performs
+ recovery. <code class="structname">pg_stat_activity</code> does not show
+ recovering transactions as active. As a result,
+ <code class="structname">pg_prepared_xacts</code> is always empty during
+ recovery. If you wish to resolve in-doubt prepared transactions, view
+ <code class="literal">pg_prepared_xacts</code> on the primary and issue commands to
+ resolve transactions there or resolve them after the end of recovery.
+ </p><p>
+ <code class="structname">pg_locks</code> will show locks held by backends,
+ as normal. <code class="structname">pg_locks</code> also shows
+ a virtual transaction managed by the startup process that owns all
+ <code class="literal">AccessExclusiveLocks</code> held by transactions being replayed by recovery.
+ Note that the startup process does not acquire locks to
+ make database changes, and thus locks other than <code class="literal">AccessExclusiveLocks</code>
+ do not show in <code class="structname">pg_locks</code> for the Startup
+ process; they are just presumed to exist.
+ </p><p>
+ The <span class="productname">Nagios</span> plugin <span class="productname">check_pgsql</span> will
+ work, because the simple information it checks for exists.
+ The <span class="productname">check_postgres</span> monitoring script will also work,
+ though some reported values could give different or confusing results.
+ For example, last vacuum time will not be maintained, since no
+ vacuum occurs on the standby. Vacuums running on the primary
+ do still send their changes to the standby.
+ </p><p>
+ WAL file control commands will not work during recovery,
+ e.g., <code class="function">pg_backup_start</code>, <code class="function">pg_switch_wal</code> etc.
+ </p><p>
+ Dynamically loadable modules work, including <code class="structname">pg_stat_statements</code>.
+ </p><p>
+ Advisory locks work normally in recovery, including deadlock detection.
+ Note that advisory locks are never WAL logged, so it is impossible for
+ an advisory lock on either the primary or the standby to conflict with WAL
+ replay. Nor is it possible to acquire an advisory lock on the primary
+ and have it initiate a similar advisory lock on the standby. Advisory
+ locks relate only to the server on which they are acquired.
+ </p><p>
+ Trigger-based replication systems such as <span class="productname">Slony</span>,
+ <span class="productname">Londiste</span> and <span class="productname">Bucardo</span> won't run on the
+ standby at all, though they will run happily on the primary server as
+ long as the changes are not sent to standby servers to be applied.
+ WAL replay is not trigger-based so you cannot relay from the
+ standby to any system that requires additional database writes or
+ relies on the use of triggers.
+ </p><p>
+ New OIDs cannot be assigned, though some <acronym class="acronym">UUID</acronym> generators may still
+ work as long as they do not rely on writing new status to the database.
+ </p><p>
+ Currently, temporary table creation is not allowed during read-only
+ transactions, so in some cases existing scripts will not run correctly.
+ This restriction might be relaxed in a later release. This is
+ both an SQL standard compliance issue and a technical issue.
+ </p><p>
+ <code class="command">DROP TABLESPACE</code> can only succeed if the tablespace is empty.
+ Some standby users may be actively using the tablespace via their
+ <code class="varname">temp_tablespaces</code> parameter. If there are temporary files in the
+ tablespace, all active queries are canceled to ensure that temporary
+ files are removed, so the tablespace can be removed and WAL replay
+ can continue.
+ </p><p>
+ Running <code class="command">DROP DATABASE</code> or <code class="command">ALTER DATABASE ... SET
+ TABLESPACE</code> on the primary
+ will generate a WAL entry that will cause all users connected to that
+ database on the standby to be forcibly disconnected. This action occurs
+ immediately, whatever the setting of
+ <code class="varname">max_standby_streaming_delay</code>. Note that
+ <code class="command">ALTER DATABASE ... RENAME</code> does not disconnect users, which
+ in most cases will go unnoticed, though might in some cases cause a
+ program confusion if it depends in some way upon database name.
+ </p><p>
+ In normal (non-recovery) mode, if you issue <code class="command">DROP USER</code> or <code class="command">DROP ROLE</code>
+ for a role with login capability while that user is still connected then
+ nothing happens to the connected user — they remain connected. The user cannot
+ reconnect however. This behavior applies in recovery also, so a
+ <code class="command">DROP USER</code> on the primary does not disconnect that user on the standby.
+ </p><p>
+ The cumulative statistics system is active during recovery. All scans,
+ reads, blocks, index usage, etc., will be recorded normally on the
+ standby. However, WAL replay will not increment relation and database
+ specific counters. I.e. replay will not increment pg_stat_all_tables
+ columns (like n_tup_ins), nor will reads or writes performed by the
+ startup process be tracked in the pg_statio views, nor will associated
+ pg_stat_database columns be incremented.
+ </p><p>
+ Autovacuum is not active during recovery. It will start normally at the
+ end of recovery.
+ </p><p>
+ The checkpointer process and the background writer process are active during
+ recovery. The checkpointer process will perform restartpoints (similar to
+ checkpoints on the primary) and the background writer process will perform
+ normal block cleaning activities. This can include updates of the hint bit
+ information stored on the standby server.
+ The <code class="command">CHECKPOINT</code> command is accepted during recovery,
+ though it performs a restartpoint rather than a new checkpoint.
+ </p></div><div class="sect2" id="HOT-STANDBY-PARAMETERS"><div class="titlepage"><div><div><h3 class="title">27.4.4. Hot Standby Parameter Reference</h3></div></div></div><p>
+ Various parameters have been mentioned above in
+ <a class="xref" href="hot-standby.html#HOT-STANDBY-CONFLICT" title="27.4.2. Handling Query Conflicts">Section 27.4.2</a> and
+ <a class="xref" href="hot-standby.html#HOT-STANDBY-ADMIN" title="27.4.3. Administrator's Overview">Section 27.4.3</a>.
+ </p><p>
+ On the primary, parameters <a class="xref" href="runtime-config-wal.html#GUC-WAL-LEVEL">wal_level</a> and
+ <a class="xref" href="runtime-config-replication.html#GUC-VACUUM-DEFER-CLEANUP-AGE">vacuum_defer_cleanup_age</a> can be used.
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY">max_standby_archive_delay</a> and
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY">max_standby_streaming_delay</a> have no effect if set on
+ the primary.
+ </p><p>
+ On the standby, parameters <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY">hot_standby</a>,
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-ARCHIVE-DELAY">max_standby_archive_delay</a> and
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-STANDBY-STREAMING-DELAY">max_standby_streaming_delay</a> can be used.
+ <a class="xref" href="runtime-config-replication.html#GUC-VACUUM-DEFER-CLEANUP-AGE">vacuum_defer_cleanup_age</a> has no effect
+ as long as the server remains in standby mode, though it will
+ become relevant if the standby becomes primary.
+ </p></div><div class="sect2" id="HOT-STANDBY-CAVEATS"><div class="titlepage"><div><div><h3 class="title">27.4.5. Caveats</h3></div></div></div><p>
+ There are several limitations of hot standby.
+ These can and probably will be fixed in future releases:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Full knowledge of running transactions is required before snapshots
+ can be taken. Transactions that use large numbers of subtransactions
+ (currently greater than 64) will delay the start of read-only
+ connections until the completion of the longest running write transaction.
+ If this situation occurs, explanatory messages will be sent to the server log.
+ </p></li><li class="listitem"><p>
+ Valid starting points for standby queries are generated at each
+ checkpoint on the primary. If the standby is shut down while the primary
+ is in a shutdown state, it might not be possible to re-enter hot standby
+ until the primary is started up, so that it generates further starting
+ points in the WAL logs. This situation isn't a problem in the most
+ common situations where it might happen. Generally, if the primary is
+ shut down and not available anymore, that's likely due to a serious
+ failure that requires the standby being converted to operate as
+ the new primary anyway. And in situations where the primary is
+ being intentionally taken down, coordinating to make sure the standby
+ becomes the new primary smoothly is also standard procedure.
+ </p></li><li class="listitem"><p>
+ At the end of recovery, <code class="literal">AccessExclusiveLocks</code> held by prepared transactions
+ will require twice the normal number of lock table entries. If you plan
+ on running either a large number of concurrent prepared transactions
+ that normally take <code class="literal">AccessExclusiveLocks</code>, or you plan on having one
+ large transaction that takes many <code class="literal">AccessExclusiveLocks</code>, you are
+ advised to select a larger value of <code class="varname">max_locks_per_transaction</code>,
+ perhaps as much as twice the value of the parameter on
+ the primary server. You need not consider this at all if
+ your setting of <code class="varname">max_prepared_transactions</code> is 0.
+ </p></li><li class="listitem"><p>
+ The Serializable transaction isolation level is not yet available in hot
+ standby. (See <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a> and
+ <a class="xref" href="applevel-consistency.html#SERIALIZABLE-CONSISTENCY" title="13.4.1. Enforcing Consistency with Serializable Transactions">Section 13.4.1</a> for details.)
+ An attempt to set a transaction to the serializable isolation level in
+ hot standby mode will generate an error.
+ </p></li></ul></div><p>
+
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="warm-standby-failover.html" title="27.3. Failover">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Next</a></td></tr><tr><td width="40%" align="left" valign="top">27.3. Failover </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 28. Monitoring Database Activity</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/how-parallel-query-works.html b/doc/src/sgml/html/how-parallel-query-works.html
new file mode 100644
index 0000000..89f5518
--- /dev/null
+++ b/doc/src/sgml/html/how-parallel-query-works.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>15.1. How Parallel Query Works</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="parallel-query.html" title="Chapter 15. Parallel Query" /><link rel="next" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">15.1. How Parallel Query Works</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="parallel-query.html" title="Chapter 15. Parallel Query">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><th width="60%" align="center">Chapter 15. Parallel Query</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Next</a></td></tr></table><hr /></div><div class="sect1" id="HOW-PARALLEL-QUERY-WORKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">15.1. How Parallel Query Works</h2></div></div></div><p>
+ When the optimizer determines that parallel query is the fastest execution
+ strategy for a particular query, it will create a query plan that includes
+ a <em class="firstterm">Gather</em> or <em class="firstterm">Gather Merge</em>
+ node. Here is a simple example:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
+ QUERY PLAN
+-------------------------------------------------------------------​------------------
+ Gather (cost=1000.00..217018.43 rows=1 width=97)
+ Workers Planned: 2
+ -&gt; Parallel Seq Scan on pgbench_accounts (cost=0.00..216018.33 rows=1 width=97)
+ Filter: (filler ~~ '%x%'::text)
+(4 rows)
+</pre><p>
+ </p><p>
+ In all cases, the <code class="literal">Gather</code> or
+ <code class="literal">Gather Merge</code> node will have exactly one
+ child plan, which is the portion of the plan that will be executed in
+ parallel. If the <code class="literal">Gather</code> or <code class="literal">Gather Merge</code> node is
+ at the very top of the plan tree, then the entire query will execute in
+ parallel. If it is somewhere else in the plan tree, then only the portion
+ of the plan below it will run in parallel. In the example above, the
+ query accesses only one table, so there is only one plan node other than
+ the <code class="literal">Gather</code> node itself; since that plan node is a child of the
+ <code class="literal">Gather</code> node, it will run in parallel.
+ </p><p>
+ <a class="link" href="using-explain.html" title="14.1. Using EXPLAIN">Using EXPLAIN</a>, you can see the number of
+ workers chosen by the planner. When the <code class="literal">Gather</code> node is reached
+ during query execution, the process that is implementing the user's
+ session will request a number of <a class="link" href="bgworker.html" title="Chapter 48. Background Worker Processes">background
+ worker processes</a> equal to the number
+ of workers chosen by the planner. The number of background workers that
+ the planner will consider using is limited to at most
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER">max_parallel_workers_per_gather</a>. The total number
+ of background workers that can exist at any one time is limited by both
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a> and
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS">max_parallel_workers</a>. Therefore, it is possible for a
+ parallel query to run with fewer workers than planned, or even with
+ no workers at all. The optimal plan may depend on the number of workers
+ that are available, so this can result in poor query performance. If this
+ occurrence is frequent, consider increasing
+ <code class="varname">max_worker_processes</code> and <code class="varname">max_parallel_workers</code>
+ so that more workers can be run simultaneously or alternatively reducing
+ <code class="varname">max_parallel_workers_per_gather</code> so that the planner
+ requests fewer workers.
+ </p><p>
+ Every background worker process that is successfully started for a given
+ parallel query will execute the parallel portion of the plan. The leader
+ will also execute that portion of the plan, but it has an additional
+ responsibility: it must also read all of the tuples generated by the
+ workers. When the parallel portion of the plan generates only a small
+ number of tuples, the leader will often behave very much like an additional
+ worker, speeding up query execution. Conversely, when the parallel portion
+ of the plan generates a large number of tuples, the leader may be almost
+ entirely occupied with reading the tuples generated by the workers and
+ performing any further processing steps that are required by plan nodes
+ above the level of the <code class="literal">Gather</code> node or
+ <code class="literal">Gather Merge</code> node. In such cases, the leader will
+ do very little of the work of executing the parallel portion of the plan.
+ </p><p>
+ When the node at the top of the parallel portion of the plan is
+ <code class="literal">Gather Merge</code> rather than <code class="literal">Gather</code>, it indicates that
+ each process executing the parallel portion of the plan is producing
+ tuples in sorted order, and that the leader is performing an
+ order-preserving merge. In contrast, <code class="literal">Gather</code> reads tuples
+ from the workers in whatever order is convenient, destroying any sort
+ order that may have existed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="parallel-query.html" title="Chapter 15. Parallel Query">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 15. Parallel Query </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 15.2. When Can Parallel Query Be Used?</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/hstore.html b/doc/src/sgml/html/hstore.html
new file mode 100644
index 0000000..8cd5502
--- /dev/null
+++ b/doc/src/sgml/html/hstore.html
@@ -0,0 +1,699 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.18. hstore</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fuzzystrmatch.html" title="F.17. fuzzystrmatch" /><link rel="next" href="intagg.html" title="F.19. intagg" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.18. hstore</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fuzzystrmatch.html" title="F.17. fuzzystrmatch">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="intagg.html" title="F.19. intagg">Next</a></td></tr></table><hr /></div><div class="sect1" id="HSTORE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.18. hstore</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.5">F.18.1. <code class="type">hstore</code> External Representation</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.6">F.18.2. <code class="type">hstore</code> Operators and Functions</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.7">F.18.3. Indexes</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.8">F.18.4. Examples</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.9">F.18.5. Statistics</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.10">F.18.6. Compatibility</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.11">F.18.7. Transforms</a></span></dt><dt><span class="sect2"><a href="hstore.html#id-1.11.7.27.12">F.18.8. Authors</a></span></dt></dl></div><a id="id-1.11.7.27.2" class="indexterm"></a><p>
+ This module implements the <code class="type">hstore</code> data type for storing sets of
+ key/value pairs within a single <span class="productname">PostgreSQL</span> value.
+ This can be useful in various scenarios, such as rows with many attributes
+ that are rarely examined, or semi-structured data. Keys and values are
+ simply text strings.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.27.5"><div class="titlepage"><div><div><h3 class="title">F.18.1. <code class="type">hstore</code> External Representation</h3></div></div></div><p>
+
+ The text representation of an <code class="type">hstore</code>, used for input and output,
+ includes zero or more <em class="replaceable"><code>key</code></em> <code class="literal">=&gt;</code>
+ <em class="replaceable"><code>value</code></em> pairs separated by commas. Some examples:
+
+</p><pre class="synopsis">
+k =&gt; v
+foo =&gt; bar, baz =&gt; whatever
+"1-a" =&gt; "anything at all"
+</pre><p>
+
+ The order of the pairs is not significant (and may not be reproduced on
+ output). Whitespace between pairs or around the <code class="literal">=&gt;</code> sign is
+ ignored. Double-quote keys and values that include whitespace, commas,
+ <code class="literal">=</code>s or <code class="literal">&gt;</code>s. To include a double quote or a
+ backslash in a key or value, escape it with a backslash.
+ </p><p>
+ Each key in an <code class="type">hstore</code> is unique. If you declare an <code class="type">hstore</code>
+ with duplicate keys, only one will be stored in the <code class="type">hstore</code> and
+ there is no guarantee as to which will be kept:
+
+</p><pre class="programlisting">
+SELECT 'a=&gt;1,a=&gt;2'::hstore;
+ hstore
+----------
+ "a"=&gt;"1"
+</pre><p>
+ </p><p>
+ A value (but not a key) can be an SQL <code class="literal">NULL</code>. For example:
+
+</p><pre class="programlisting">
+key =&gt; NULL
+</pre><p>
+
+ The <code class="literal">NULL</code> keyword is case-insensitive. Double-quote the
+ <code class="literal">NULL</code> to treat it as the ordinary string <span class="quote">“<span class="quote">NULL</span>”</span>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Keep in mind that the <code class="type">hstore</code> text format, when used for input,
+ applies <span class="emphasis"><em>before</em></span> any required quoting or escaping. If you are
+ passing an <code class="type">hstore</code> literal via a parameter, then no additional
+ processing is needed. But if you're passing it as a quoted literal
+ constant, then any single-quote characters and (depending on the setting of
+ the <code class="varname">standard_conforming_strings</code> configuration parameter)
+ backslash characters need to be escaped correctly. See
+ <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a> for more on the handling of string
+ constants.
+ </p></div><p>
+ On output, double quotes always surround keys and values, even when it's
+ not strictly necessary.
+ </p></div><div class="sect2" id="id-1.11.7.27.6"><div class="titlepage"><div><div><h3 class="title">F.18.2. <code class="type">hstore</code> Operators and Functions</h3></div></div></div><p>
+ The operators provided by the <code class="literal">hstore</code> module are
+ shown in <a class="xref" href="hstore.html#HSTORE-OP-TABLE" title="Table F.7. hstore Operators">Table F.7</a>, the functions
+ in <a class="xref" href="hstore.html#HSTORE-FUNC-TABLE" title="Table F.8. hstore Functions">Table F.8</a>.
+ </p><div class="table" id="HSTORE-OP-TABLE"><p class="title"><strong>Table F.7. <code class="type">hstore</code> Operators</strong></p><div class="table-contents"><table class="table" summary="hstore Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">-&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns value associated with given key, or <code class="literal">NULL</code> if
+ not present.
+ </p>
+ <p>
+ <code class="literal">'a=&gt;x, b=&gt;y'::hstore -&gt; 'a'</code>
+ → <code class="returnvalue">x</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">-&gt;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Returns values associated with given keys, or <code class="literal">NULL</code>
+ if not present.
+ </p>
+ <p>
+ <code class="literal">'a=&gt;x, b=&gt;y, c=&gt;z'::hstore -&gt; ARRAY['c','a']</code>
+ → <code class="returnvalue">{"z","x"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">||</code> <code class="type">hstore</code>
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Concatenates two <code class="type">hstore</code>s.
+ </p>
+ <p>
+ <code class="literal">'a=&gt;b, c=&gt;d'::hstore || 'c=&gt;x, d=&gt;q'::hstore</code>
+ → <code class="returnvalue">"a"=&gt;"b", "c"=&gt;"x", "d"=&gt;"q"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">?</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">hstore</code> contain key?
+ </p>
+ <p>
+ <code class="literal">'a=&gt;1'::hstore ? 'a'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">?&amp;</code> <code class="type">text[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">hstore</code> contain all the specified keys?
+ </p>
+ <p>
+ <code class="literal">'a=&gt;1,b=&gt;2'::hstore ?&amp; ARRAY['a','b']</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">?|</code> <code class="type">text[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">hstore</code> contain any of the specified keys?
+ </p>
+ <p>
+ <code class="literal">'a=&gt;1,b=&gt;2'::hstore ?| ARRAY['b','c']</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">@&gt;</code> <code class="type">hstore</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does left operand contain right?
+ </p>
+ <p>
+ <code class="literal">'a=&gt;b, b=&gt;1, c=&gt;NULL'::hstore @&gt; 'b=&gt;1'</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">&lt;@</code> <code class="type">hstore</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is left operand contained in right?
+ </p>
+ <p>
+ <code class="literal">'a=&gt;c'::hstore &lt;@ 'a=&gt;b, b=&gt;1, c=&gt;NULL'</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">-</code> <code class="type">text</code>
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Deletes key from left operand.
+ </p>
+ <p>
+ <code class="literal">'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'b'::text</code>
+ → <code class="returnvalue">"a"=&gt;"1", "c"=&gt;"3"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">-</code> <code class="type">text[]</code>
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Deletes keys from left operand.
+ </p>
+ <p>
+ <code class="literal">'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - ARRAY['a','b']</code>
+ → <code class="returnvalue">"c"=&gt;"3"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">hstore</code> <code class="literal">-</code> <code class="type">hstore</code>
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Deletes pairs from left operand that match pairs in the right operand.
+ </p>
+ <p>
+ <code class="literal">'a=&gt;1, b=&gt;2, c=&gt;3'::hstore - 'a=&gt;4, b=&gt;2'::hstore</code>
+ → <code class="returnvalue">"a"=&gt;"1", "c"=&gt;"3"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">anyelement</code> <code class="literal">#=</code> <code class="type">hstore</code>
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Replaces fields in the left operand (which must be a composite type)
+ with matching values from <code class="type">hstore</code>.
+ </p>
+ <p>
+ <code class="literal">ROW(1,3) #= 'f1=&gt;11'::hstore</code>
+ → <code class="returnvalue">(11,3)</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">%%</code> <code class="type">hstore</code>
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Converts <code class="type">hstore</code> to an array of alternating keys and
+ values.
+ </p>
+ <p>
+ <code class="literal">%% 'a=&gt;foo, b=&gt;bar'::hstore</code>
+ → <code class="returnvalue">{a,foo,b,bar}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">%#</code> <code class="type">hstore</code>
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Converts <code class="type">hstore</code> to a two-dimensional key/value array.
+ </p>
+ <p>
+ <code class="literal">%# 'a=&gt;foo, b=&gt;bar'::hstore</code>
+ → <code class="returnvalue">{{a,foo},{b,bar}}</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="HSTORE-FUNC-TABLE"><p class="title"><strong>Table F.8. <code class="type">hstore</code> Functions</strong></p><div class="table-contents"><table class="table" summary="hstore Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">hstore</code> ( <code class="type">record</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Constructs an <code class="type">hstore</code> from a record or row.
+ </p>
+ <p>
+ <code class="literal">hstore(ROW(1,2))</code>
+ → <code class="returnvalue">"f1"=&gt;"1", "f2"=&gt;"2"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">hstore</code> ( <code class="type">text[]</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Constructs an <code class="type">hstore</code> from an array, which may be either
+ a key/value array, or a two-dimensional array.
+ </p>
+ <p>
+ <code class="literal">hstore(ARRAY['a','1','b','2'])</code>
+ → <code class="returnvalue">"a"=&gt;"1", "b"=&gt;"2"</code>
+ </p>
+ <p>
+ <code class="literal">hstore(ARRAY[['c','3'],['d','4']])</code>
+ → <code class="returnvalue">"c"=&gt;"3", "d"=&gt;"4"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">hstore</code> ( <code class="type">text[]</code>, <code class="type">text[]</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Constructs an <code class="type">hstore</code> from separate key and value arrays.
+ </p>
+ <p>
+ <code class="literal">hstore(ARRAY['a','b'], ARRAY['1','2'])</code>
+ → <code class="returnvalue">"a"=&gt;"1", "b"=&gt;"2"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">hstore</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Makes a single-item <code class="type">hstore</code>.
+ </p>
+ <p>
+ <code class="literal">hstore('a', 'b')</code>
+ → <code class="returnvalue">"a"=&gt;"b"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">akeys</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s keys as an array.
+ </p>
+ <p>
+ <code class="literal">akeys('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue">{a,b}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">skeys</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s keys as a set.
+ </p>
+ <p>
+ <code class="literal">skeys('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+a
+b
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">avals</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s values as an array.
+ </p>
+ <p>
+ <code class="literal">avals('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue">{1,2}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">svals</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">setof text</code>
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s values as a set.
+ </p>
+ <p>
+ <code class="literal">svals('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+1
+2
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">hstore_to_array</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s keys and values as an array of
+ alternating keys and values.
+ </p>
+ <p>
+ <code class="literal">hstore_to_array('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue">{a,1,b,2}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">hstore_to_matrix</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s keys and values as a two-dimensional
+ array.
+ </p>
+ <p>
+ <code class="literal">hstore_to_matrix('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue">{{a,1},{b,2}}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">hstore_to_json</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p>
+ Converts an <code class="type">hstore</code> to a <code class="type">json</code> value,
+ converting all non-null values to JSON strings.
+ </p>
+ <p>
+ This function is used implicitly when an <code class="type">hstore</code> value is
+ cast to <code class="type">json</code>.
+ </p>
+ <p>
+ <code class="literal">hstore_to_json('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</code>
+ → <code class="returnvalue">{"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">hstore_to_jsonb</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Converts an <code class="type">hstore</code> to a <code class="type">jsonb</code> value,
+ converting all non-null values to JSON strings.
+ </p>
+ <p>
+ This function is used implicitly when an <code class="type">hstore</code> value is
+ cast to <code class="type">jsonb</code>.
+ </p>
+ <p>
+ <code class="literal">hstore_to_jsonb('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</code>
+ → <code class="returnvalue">{"a key": "1", "b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4"}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">hstore_to_json_loose</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">json</code>
+ </p>
+ <p>
+ Converts an <code class="type">hstore</code> to a <code class="type">json</code> value, but
+ attempts to distinguish numerical and Boolean values so they are
+ unquoted in the JSON.
+ </p>
+ <p>
+ <code class="literal">hstore_to_json_loose('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</code>
+ → <code class="returnvalue">{"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.14.1.1.1" class="indexterm"></a>
+ <code class="function">hstore_to_jsonb_loose</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">jsonb</code>
+ </p>
+ <p>
+ Converts an <code class="type">hstore</code> to a <code class="type">jsonb</code> value, but
+ attempts to distinguish numerical and Boolean values so they are
+ unquoted in the JSON.
+ </p>
+ <p>
+ <code class="literal">hstore_to_jsonb_loose('"a key"=&gt;1, b=&gt;t, c=&gt;null, d=&gt;12345, e=&gt;012345, f=&gt;1.234, g=&gt;2.345e+4')</code>
+ → <code class="returnvalue">{"a key": 1, "b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.15.1.1.1" class="indexterm"></a>
+ <code class="function">slice</code> ( <code class="type">hstore</code>, <code class="type">text[]</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Extracts a subset of an <code class="type">hstore</code> containing only the
+ specified keys.
+ </p>
+ <p>
+ <code class="literal">slice('a=&gt;1,b=&gt;2,c=&gt;3'::hstore, ARRAY['b','c','x'])</code>
+ → <code class="returnvalue">"b"=&gt;"2", "c"=&gt;"3"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.16.1.1.1" class="indexterm"></a>
+ <code class="function">each</code> ( <code class="type">hstore</code> )
+ → <code class="returnvalue">setof record</code>
+ ( <em class="parameter"><code>key</code></em> <code class="type">text</code>,
+ <em class="parameter"><code>value</code></em> <code class="type">text</code> )
+ </p>
+ <p>
+ Extracts an <code class="type">hstore</code>'s keys and values as a set of records.
+ </p>
+ <p>
+ <code class="literal">select * from each('a=&gt;1,b=&gt;2')</code>
+ → <code class="returnvalue"></code>
+</p><pre class="programlisting">
+ key | value
+-----+-------
+ a | 1
+ b | 2
+</pre><p>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.17.1.1.1" class="indexterm"></a>
+ <code class="function">exist</code> ( <code class="type">hstore</code>, <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">hstore</code> contain key?
+ </p>
+ <p>
+ <code class="literal">exist('a=&gt;1', 'a')</code>
+ → <code class="returnvalue">t</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.18.1.1.1" class="indexterm"></a>
+ <code class="function">defined</code> ( <code class="type">hstore</code>, <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">hstore</code> contain a non-<code class="literal">NULL</code> value
+ for key?
+ </p>
+ <p>
+ <code class="literal">defined('a=&gt;NULL', 'a')</code>
+ → <code class="returnvalue">f</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.19.1.1.1" class="indexterm"></a>
+ <code class="function">delete</code> ( <code class="type">hstore</code>, <code class="type">text</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Deletes pair with matching key.
+ </p>
+ <p>
+ <code class="literal">delete('a=&gt;1,b=&gt;2', 'b')</code>
+ → <code class="returnvalue">"a"=&gt;"1"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">delete</code> ( <code class="type">hstore</code>, <code class="type">text[]</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Deletes pairs with matching keys.
+ </p>
+ <p>
+ <code class="literal">delete('a=&gt;1,b=&gt;2,c=&gt;3', ARRAY['a','b'])</code>
+ → <code class="returnvalue">"c"=&gt;"3"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">delete</code> ( <code class="type">hstore</code>, <code class="type">hstore</code> )
+ → <code class="returnvalue">hstore</code>
+ </p>
+ <p>
+ Deletes pairs matching those in the second argument.
+ </p>
+ <p>
+ <code class="literal">delete('a=&gt;1,b=&gt;2', 'a=&gt;4,b=&gt;2'::hstore)</code>
+ → <code class="returnvalue">"a"=&gt;"1"</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.27.6.4.2.2.22.1.1.1" class="indexterm"></a>
+ <code class="function">populate_record</code> ( <code class="type">anyelement</code>, <code class="type">hstore</code> )
+ → <code class="returnvalue">anyelement</code>
+ </p>
+ <p>
+ Replaces fields in the left operand (which must be a composite type)
+ with matching values from <code class="type">hstore</code>.
+ </p>
+ <p>
+ <code class="literal">populate_record(ROW(1,2), 'f1=&gt;42'::hstore)</code>
+ → <code class="returnvalue">(42,2)</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In addition to these operators and functions, values of
+ the <code class="type">hstore</code> type can be subscripted, allowing them to act
+ like associative arrays. Only a single subscript of type <code class="type">text</code>
+ can be specified; it is interpreted as a key and the corresponding
+ value is fetched or stored. For example,
+
+</p><pre class="programlisting">
+CREATE TABLE mytable (h hstore);
+INSERT INTO mytable VALUES ('a=&gt;b, c=&gt;d');
+SELECT h['a'] FROM mytable;
+ h
+---
+ b
+(1 row)
+
+UPDATE mytable SET h['c'] = 'new';
+SELECT h FROM mytable;
+ h
+----------------------
+ "a"=&gt;"b", "c"=&gt;"new"
+(1 row)
+</pre><p>
+
+ A subscripted fetch returns <code class="literal">NULL</code> if the subscript
+ is <code class="literal">NULL</code> or that key does not exist in
+ the <code class="type">hstore</code>. (Thus, a subscripted fetch is not greatly
+ different from the <code class="literal">-&gt;</code> operator.)
+ A subscripted update fails if the subscript is <code class="literal">NULL</code>;
+ otherwise, it replaces the value for that key, adding an entry to
+ the <code class="type">hstore</code> if the key does not already exist.
+ </p></div><div class="sect2" id="id-1.11.7.27.7"><div class="titlepage"><div><div><h3 class="title">F.18.3. Indexes</h3></div></div></div><p>
+ <code class="type">hstore</code> has GiST and GIN index support for the <code class="literal">@&gt;</code>,
+ <code class="literal">?</code>, <code class="literal">?&amp;</code> and <code class="literal">?|</code> operators. For example:
+ </p><pre class="programlisting">
+CREATE INDEX hidx ON testhstore USING GIST (h);
+
+CREATE INDEX hidx ON testhstore USING GIN (h);
+</pre><p>
+ <code class="literal">gist_hstore_ops</code> GiST opclass approximates a set of
+ key/value pairs as a bitmap signature. Its optional integer parameter
+ <code class="literal">siglen</code> determines the
+ signature length in bytes. The default length is 16 bytes.
+ Valid values of signature length are between 1 and 2024 bytes. Longer
+ signatures lead to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </p><p>
+ Example of creating such an index with a signature length of 32 bytes:
+</p><pre class="programlisting">
+CREATE INDEX hidx ON testhstore USING GIST (h gist_hstore_ops(siglen=32));
+</pre><p>
+ </p><p>
+ <code class="type">hstore</code> also supports <code class="type">btree</code> or <code class="type">hash</code> indexes for
+ the <code class="literal">=</code> operator. This allows <code class="type">hstore</code> columns to be
+ declared <code class="literal">UNIQUE</code>, or to be used in <code class="literal">GROUP BY</code>,
+ <code class="literal">ORDER BY</code> or <code class="literal">DISTINCT</code> expressions. The sort ordering
+ for <code class="type">hstore</code> values is not particularly useful, but these indexes
+ may be useful for equivalence lookups. Create indexes for <code class="literal">=</code>
+ comparisons as follows:
+ </p><pre class="programlisting">
+CREATE INDEX hidx ON testhstore USING BTREE (h);
+
+CREATE INDEX hidx ON testhstore USING HASH (h);
+</pre></div><div class="sect2" id="id-1.11.7.27.8"><div class="titlepage"><div><div><h3 class="title">F.18.4. Examples</h3></div></div></div><p>
+ Add a key, or update an existing key with a new value:
+</p><pre class="programlisting">
+UPDATE tab SET h['c'] = '3';
+</pre><p>
+ Another way to do the same thing is:
+</p><pre class="programlisting">
+UPDATE tab SET h = h || hstore('c', '3');
+</pre><p>
+ If multiple keys are to be added or changed in one operation,
+ the concatenation approach is more efficient than subscripting:
+</p><pre class="programlisting">
+UPDATE tab SET h = h || hstore(array['q', 'w'], array['11', '12']);
+</pre><p>
+ </p><p>
+ Delete a key:
+</p><pre class="programlisting">
+UPDATE tab SET h = delete(h, 'k1');
+</pre><p>
+ </p><p>
+ Convert a <code class="type">record</code> to an <code class="type">hstore</code>:
+</p><pre class="programlisting">
+CREATE TABLE test (col1 integer, col2 text, col3 text);
+INSERT INTO test VALUES (123, 'foo', 'bar');
+
+SELECT hstore(t) FROM test AS t;
+ hstore
+---------------------------------------------
+ "col1"=&gt;"123", "col2"=&gt;"foo", "col3"=&gt;"bar"
+(1 row)
+</pre><p>
+ </p><p>
+ Convert an <code class="type">hstore</code> to a predefined <code class="type">record</code> type:
+</p><pre class="programlisting">
+CREATE TABLE test (col1 integer, col2 text, col3 text);
+
+SELECT * FROM populate_record(null::test,
+ '"col1"=&gt;"456", "col2"=&gt;"zzz"');
+ col1 | col2 | col3
+------+------+------
+ 456 | zzz |
+(1 row)
+</pre><p>
+ </p><p>
+ Modify an existing record using the values from an <code class="type">hstore</code>:
+</p><pre class="programlisting">
+CREATE TABLE test (col1 integer, col2 text, col3 text);
+INSERT INTO test VALUES (123, 'foo', 'bar');
+
+SELECT (r).* FROM (SELECT t #= '"col3"=&gt;"baz"' AS r FROM test t) s;
+ col1 | col2 | col3
+------+------+------
+ 123 | foo | baz
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.7.27.9"><div class="titlepage"><div><div><h3 class="title">F.18.5. Statistics</h3></div></div></div><p>
+ The <code class="type">hstore</code> type, because of its intrinsic liberality, could
+ contain a lot of different keys. Checking for valid keys is the task of the
+ application. The following examples demonstrate several techniques for
+ checking keys and obtaining statistics.
+ </p><p>
+ Simple example:
+</p><pre class="programlisting">
+SELECT * FROM each('aaa=&gt;bq, b=&gt;NULL, ""=&gt;1');
+</pre><p>
+ </p><p>
+ Using a table:
+</p><pre class="programlisting">
+CREATE TABLE stat AS SELECT (each(h)).key, (each(h)).value FROM testhstore;
+</pre><p>
+ </p><p>
+ Online statistics:
+</p><pre class="programlisting">
+SELECT key, count(*) FROM
+ (SELECT (each(h)).key FROM testhstore) AS stat
+ GROUP BY key
+ ORDER BY count DESC, key;
+ key | count
+-----------+-------
+ line | 883
+ query | 207
+ pos | 203
+ node | 202
+ space | 197
+ status | 195
+ public | 194
+ title | 190
+ org | 189
+...................
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.7.27.10"><div class="titlepage"><div><div><h3 class="title">F.18.6. Compatibility</h3></div></div></div><p>
+ As of PostgreSQL 9.0, <code class="type">hstore</code> uses a different internal
+ representation than previous versions. This presents no obstacle for
+ dump/restore upgrades since the text representation (used in the dump) is
+ unchanged.
+ </p><p>
+ In the event of a binary upgrade, upward compatibility is maintained by
+ having the new code recognize old-format data. This will entail a slight
+ performance penalty when processing data that has not yet been modified by
+ the new code. It is possible to force an upgrade of all values in a table
+ column by doing an <code class="literal">UPDATE</code> statement as follows:
+</p><pre class="programlisting">
+UPDATE tablename SET hstorecol = hstorecol || '';
+</pre><p>
+ </p><p>
+ Another way to do it is:
+</p><pre class="programlisting">
+ALTER TABLE tablename ALTER hstorecol TYPE hstore USING hstorecol || '';
+</pre><p>
+ The <code class="command">ALTER TABLE</code> method requires an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the table,
+ but does not result in bloating the table with old row versions.
+ </p></div><div class="sect2" id="id-1.11.7.27.11"><div class="titlepage"><div><div><h3 class="title">F.18.7. Transforms</h3></div></div></div><p>
+ Additional extensions are available that implement transforms for
+ the <code class="type">hstore</code> type for the languages PL/Perl and PL/Python. The
+ extensions for PL/Perl are called <code class="literal">hstore_plperl</code>
+ and <code class="literal">hstore_plperlu</code>, for trusted and untrusted PL/Perl.
+ If you install these transforms and specify them when creating a
+ function, <code class="type">hstore</code> values are mapped to Perl hashes. The
+ extension for PL/Python is called <code class="literal">hstore_plpython3u</code>.
+ If you use it, <code class="type">hstore</code> values are mapped to Python dictionaries.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is strongly recommended that the transform extensions be installed in
+ the same schema as <code class="filename">hstore</code>. Otherwise there are
+ installation-time security hazards if a transform extension's schema
+ contains objects defined by a hostile user.
+ </p></div></div><div class="sect2" id="id-1.11.7.27.12"><div class="titlepage"><div><div><h3 class="title">F.18.8. Authors</h3></div></div></div><p>
+ Oleg Bartunov <code class="email">&lt;<a class="email" href="mailto:oleg@sai.msu.su">oleg@sai.msu.su</a>&gt;</code>, Moscow, Moscow University, Russia
+ </p><p>
+ Teodor Sigaev <code class="email">&lt;<a class="email" href="mailto:teodor@sigaev.ru">teodor@sigaev.ru</a>&gt;</code>, Moscow, Delta-Soft Ltd., Russia
+ </p><p>
+ Additional enhancements by Andrew Gierth <code class="email">&lt;<a class="email" href="mailto:andrew@tao11.riddles.org.uk">andrew@tao11.riddles.org.uk</a>&gt;</code>,
+ United Kingdom
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fuzzystrmatch.html" title="F.17. fuzzystrmatch">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="intagg.html" title="F.19. intagg">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.17. fuzzystrmatch </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.19. intagg</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index-api.html b/doc/src/sgml/html/index-api.html
new file mode 100644
index 0000000..f1f2077
--- /dev/null
+++ b/doc/src/sgml/html/index-api.html
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>64.1. Basic API Structure for Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition" /><link rel="next" href="index-functions.html" title="64.2. Index Access Method Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">64.1. Basic API Structure for Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 64. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-functions.html" title="64.2. Index Access Method Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEX-API"><div class="titlepage"><div><div><h2 class="title" style="clear: both">64.1. Basic API Structure for Indexes</h2></div></div></div><p>
+ Each index access method is described by a row in the
+ <a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a>
+ system catalog. The <code class="structname">pg_am</code> entry
+ specifies a name and a <em class="firstterm">handler function</em> for the index
+ access method. These entries can be created and deleted using the
+ <a class="xref" href="sql-create-access-method.html" title="CREATE ACCESS METHOD"><span class="refentrytitle">CREATE ACCESS METHOD</span></a> and
+ <a class="xref" href="sql-drop-access-method.html" title="DROP ACCESS METHOD"><span class="refentrytitle">DROP ACCESS METHOD</span></a> SQL commands.
+ </p><p>
+ An index access method handler function must be declared to accept a
+ single argument of type <code class="type">internal</code> and to return the
+ pseudo-type <code class="type">index_am_handler</code>. The argument is a dummy value that
+ simply serves to prevent handler functions from being called directly from
+ SQL commands. The result of the function must be a palloc'd struct of
+ type <code class="structname">IndexAmRoutine</code>, which contains everything
+ that the core code needs to know to make use of the index access method.
+ The <code class="structname">IndexAmRoutine</code> struct, also called the access
+ method's <em class="firstterm">API struct</em>, includes fields specifying assorted
+ fixed properties of the access method, such as whether it can support
+ multicolumn indexes. More importantly, it contains pointers to support
+ functions for the access method, which do all of the real work to access
+ indexes. These support functions are plain C functions and are not
+ visible or callable at the SQL level. The support functions are described
+ in <a class="xref" href="index-functions.html" title="64.2. Index Access Method Functions">Section 64.2</a>.
+ </p><p>
+ The structure <code class="structname">IndexAmRoutine</code> is defined thus:
+</p><pre class="programlisting">
+typedef struct IndexAmRoutine
+{
+ NodeTag type;
+
+ /*
+ * Total number of strategies (operators) by which we can traverse/search
+ * this AM. Zero if AM does not have a fixed set of strategy assignments.
+ */
+ uint16 amstrategies;
+ /* total number of support functions that this AM uses */
+ uint16 amsupport;
+ /* opclass options support function number or 0 */
+ uint16 amoptsprocnum;
+ /* does AM support ORDER BY indexed column's value? */
+ bool amcanorder;
+ /* does AM support ORDER BY result of an operator on indexed column? */
+ bool amcanorderbyop;
+ /* does AM support backward scanning? */
+ bool amcanbackward;
+ /* does AM support UNIQUE indexes? */
+ bool amcanunique;
+ /* does AM support multi-column indexes? */
+ bool amcanmulticol;
+ /* does AM require scans to have a constraint on the first index column? */
+ bool amoptionalkey;
+ /* does AM handle ScalarArrayOpExpr quals? */
+ bool amsearcharray;
+ /* does AM handle IS NULL/IS NOT NULL quals? */
+ bool amsearchnulls;
+ /* can index storage data type differ from column data type? */
+ bool amstorage;
+ /* can an index of this type be clustered on? */
+ bool amclusterable;
+ /* does AM handle predicate locks? */
+ bool ampredlocks;
+ /* does AM support parallel scan? */
+ bool amcanparallel;
+ /* does AM support columns included with clause INCLUDE? */
+ bool amcaninclude;
+ /* does AM use maintenance_work_mem? */
+ bool amusemaintenanceworkmem;
+ /* OR of parallel vacuum flags */
+ uint8 amparallelvacuumoptions;
+ /* type of data stored in index, or InvalidOid if variable */
+ Oid amkeytype;
+
+ /* interface functions */
+ ambuild_function ambuild;
+ ambuildempty_function ambuildempty;
+ aminsert_function aminsert;
+ ambulkdelete_function ambulkdelete;
+ amvacuumcleanup_function amvacuumcleanup;
+ amcanreturn_function amcanreturn; /* can be NULL */
+ amcostestimate_function amcostestimate;
+ amoptions_function amoptions;
+ amproperty_function amproperty; /* can be NULL */
+ ambuildphasename_function ambuildphasename; /* can be NULL */
+ amvalidate_function amvalidate;
+ amadjustmembers_function amadjustmembers; /* can be NULL */
+ ambeginscan_function ambeginscan;
+ amrescan_function amrescan;
+ amgettuple_function amgettuple; /* can be NULL */
+ amgetbitmap_function amgetbitmap; /* can be NULL */
+ amendscan_function amendscan;
+ ammarkpos_function ammarkpos; /* can be NULL */
+ amrestrpos_function amrestrpos; /* can be NULL */
+
+ /* interface functions to support parallel index scans */
+ amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
+ aminitparallelscan_function aminitparallelscan; /* can be NULL */
+ amparallelrescan_function amparallelrescan; /* can be NULL */
+} IndexAmRoutine;
+</pre><p>
+ </p><p>
+ To be useful, an index access method must also have one or more
+ <em class="firstterm">operator families</em> and
+ <em class="firstterm">operator classes</em> defined in
+ <a class="link" href="catalog-pg-opfamily.html" title="53.35. pg_opfamily"><code class="structname">pg_opfamily</code></a>,
+ <a class="link" href="catalog-pg-opclass.html" title="53.33. pg_opclass"><code class="structname">pg_opclass</code></a>,
+ <a class="link" href="catalog-pg-amop.html" title="53.4. pg_amop"><code class="structname">pg_amop</code></a>, and
+ <a class="link" href="catalog-pg-amproc.html" title="53.5. pg_amproc"><code class="structname">pg_amproc</code></a>.
+ These entries allow the planner
+ to determine what kinds of query qualifications can be used with
+ indexes of this access method. Operator families and classes are described
+ in <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a>, which is prerequisite material for reading
+ this chapter.
+ </p><p>
+ An individual index is defined by a
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>
+ entry that describes it as a physical relation, plus a
+ <a class="link" href="catalog-pg-index.html" title="53.26. pg_index"><code class="structname">pg_index</code></a>
+ entry that shows the logical content of the index — that is, the set
+ of index columns it has and the semantics of those columns, as captured by
+ the associated operator classes. The index columns (key values) can be
+ either simple columns of the underlying table or expressions over the table
+ rows. The index access method normally has no interest in where the index
+ key values come from (it is always handed precomputed key values) but it
+ will be very interested in the operator class information in
+ <code class="structname">pg_index</code>. Both of these catalog entries can be
+ accessed as part of the <code class="structname">Relation</code> data structure that is
+ passed to all operations on the index.
+ </p><p>
+ Some of the flag fields of <code class="structname">IndexAmRoutine</code> have nonobvious
+ implications. The requirements of <code class="structfield">amcanunique</code>
+ are discussed in <a class="xref" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Section 64.5</a>.
+ The <code class="structfield">amcanmulticol</code> flag asserts that the
+ access method supports multi-key-column indexes, while
+ <code class="structfield">amoptionalkey</code> asserts that it allows scans
+ where no indexable restriction clause is given for the first index column.
+ When <code class="structfield">amcanmulticol</code> is false,
+ <code class="structfield">amoptionalkey</code> essentially says whether the
+ access method supports full-index scans without any restriction clause.
+ Access methods that support multiple index columns <span class="emphasis"><em>must</em></span>
+ support scans that omit restrictions on any or all of the columns after
+ the first; however they are permitted to require some restriction to
+ appear for the first index column, and this is signaled by setting
+ <code class="structfield">amoptionalkey</code> false.
+ One reason that an index AM might set
+ <code class="structfield">amoptionalkey</code> false is if it doesn't index
+ null values. Since most indexable operators are
+ strict and hence cannot return true for null inputs,
+ it is at first sight attractive to not store index entries for null values:
+ they could never be returned by an index scan anyway. However, this
+ argument fails when an index scan has no restriction clause for a given
+ index column. In practice this means that
+ indexes that have <code class="structfield">amoptionalkey</code> true must
+ index nulls, since the planner might decide to use such an index
+ with no scan keys at all. A related restriction is that an index
+ access method that supports multiple index columns <span class="emphasis"><em>must</em></span>
+ support indexing null values in columns after the first, because the planner
+ will assume the index can be used for queries that do not restrict
+ these columns. For example, consider an index on (a,b) and a query with
+ <code class="literal">WHERE a = 4</code>. The system will assume the index can be
+ used to scan for rows with <code class="literal">a = 4</code>, which is wrong if the
+ index omits rows where <code class="literal">b</code> is null.
+ It is, however, OK to omit rows where the first indexed column is null.
+ An index access method that does index nulls may also set
+ <code class="structfield">amsearchnulls</code>, indicating that it supports
+ <code class="literal">IS NULL</code> and <code class="literal">IS NOT NULL</code> clauses as search
+ conditions.
+ </p><p>
+ The <code class="structfield">amcaninclude</code> flag indicates whether the
+ access method supports <span class="quote">“<span class="quote">included</span>”</span> columns, that is it can
+ store (without processing) additional columns beyond the key column(s).
+ The requirements of the preceding paragraph apply only to the key
+ columns. In particular, the combination
+ of <code class="structfield">amcanmulticol</code>=<code class="literal">false</code>
+ and <code class="structfield">amcaninclude</code>=<code class="literal">true</code> is
+ sensible: it means that there can only be one key column, but there can
+ also be included column(s). Also, included columns must be allowed to be
+ null, independently of <code class="structfield">amoptionalkey</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-functions.html" title="64.2. Index Access Method Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 64. Index Access Method Interface Definition </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 64.2. Index Access Method Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index-cost-estimation.html b/doc/src/sgml/html/index-cost-estimation.html
new file mode 100644
index 0000000..6589fd2
--- /dev/null
+++ b/doc/src/sgml/html/index-cost-estimation.html
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>64.6. Index Cost Estimation Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks" /><link rel="next" href="generic-wal.html" title="Chapter 65. Generic WAL Records" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">64.6. Index Cost Estimation Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 64. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="generic-wal.html" title="Chapter 65. Generic WAL Records">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEX-COST-ESTIMATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">64.6. Index Cost Estimation Functions</h2></div></div></div><p>
+ The <code class="function">amcostestimate</code> function is given information describing
+ a possible index scan, including lists of WHERE and ORDER BY clauses that
+ have been determined to be usable with the index. It must return estimates
+ of the cost of accessing the index and the selectivity of the WHERE
+ clauses (that is, the fraction of parent-table rows that will be
+ retrieved during the index scan). For simple cases, nearly all the
+ work of the cost estimator can be done by calling standard routines
+ in the optimizer; the point of having an <code class="function">amcostestimate</code> function is
+ to allow index access methods to provide index-type-specific knowledge,
+ in case it is possible to improve on the standard estimates.
+ </p><p>
+ Each <code class="function">amcostestimate</code> function must have the signature:
+
+</p><pre class="programlisting">
+void
+amcostestimate (PlannerInfo *root,
+ IndexPath *path,
+ double loop_count,
+ Cost *indexStartupCost,
+ Cost *indexTotalCost,
+ Selectivity *indexSelectivity,
+ double *indexCorrelation,
+ double *indexPages);
+</pre><p>
+
+ The first three parameters are inputs:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>root</code></em></span></dt><dd><p>
+ The planner's information about the query being processed.
+ </p></dd><dt><span class="term"><em class="parameter"><code>path</code></em></span></dt><dd><p>
+ The index access path being considered. All fields except cost and
+ selectivity values are valid.
+ </p></dd><dt><span class="term"><em class="parameter"><code>loop_count</code></em></span></dt><dd><p>
+ The number of repetitions of the index scan that should be factored
+ into the cost estimates. This will typically be greater than one when
+ considering a parameterized scan for use in the inside of a nestloop
+ join. Note that the cost estimates should still be for just one scan;
+ a larger <em class="parameter"><code>loop_count</code></em> means that it may be appropriate
+ to allow for some caching effects across multiple scans.
+ </p></dd></dl></div><p>
+ </p><p>
+ The last five parameters are pass-by-reference outputs:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>*indexStartupCost</code></em></span></dt><dd><p>
+ Set to cost of index start-up processing
+ </p></dd><dt><span class="term"><em class="parameter"><code>*indexTotalCost</code></em></span></dt><dd><p>
+ Set to total cost of index processing
+ </p></dd><dt><span class="term"><em class="parameter"><code>*indexSelectivity</code></em></span></dt><dd><p>
+ Set to index selectivity
+ </p></dd><dt><span class="term"><em class="parameter"><code>*indexCorrelation</code></em></span></dt><dd><p>
+ Set to correlation coefficient between index scan order and
+ underlying table's order
+ </p></dd><dt><span class="term"><em class="parameter"><code>*indexPages</code></em></span></dt><dd><p>
+ Set to number of index leaf pages
+ </p></dd></dl></div><p>
+ </p><p>
+ Note that cost estimate functions must be written in C, not in SQL or
+ any available procedural language, because they must access internal
+ data structures of the planner/optimizer.
+ </p><p>
+ The index access costs should be computed using the parameters used by
+ <code class="filename">src/backend/optimizer/path/costsize.c</code>: a sequential
+ disk block fetch has cost <code class="varname">seq_page_cost</code>, a nonsequential fetch
+ has cost <code class="varname">random_page_cost</code>, and the cost of processing one index
+ row should usually be taken as <code class="varname">cpu_index_tuple_cost</code>. In
+ addition, an appropriate multiple of <code class="varname">cpu_operator_cost</code> should
+ be charged for any comparison operators invoked during index processing
+ (especially evaluation of the indexquals themselves).
+ </p><p>
+ The access costs should include all disk and CPU costs associated with
+ scanning the index itself, but <span class="emphasis"><em>not</em></span> the costs of retrieving or
+ processing the parent-table rows that are identified by the index.
+ </p><p>
+ The <span class="quote">“<span class="quote">start-up cost</span>”</span> is the part of the total scan cost that
+ must be expended before we can begin to fetch the first row. For most
+ indexes this can be taken as zero, but an index type with a high start-up
+ cost might want to set it nonzero.
+ </p><p>
+ The <em class="parameter"><code>indexSelectivity</code></em> should be set to the estimated fraction of the parent
+ table rows that will be retrieved during the index scan. In the case
+ of a lossy query, this will typically be higher than the fraction of
+ rows that actually pass the given qual conditions.
+ </p><p>
+ The <em class="parameter"><code>indexCorrelation</code></em> should be set to the correlation (ranging between
+ -1.0 and 1.0) between the index order and the table order. This is used
+ to adjust the estimate for the cost of fetching rows from the parent
+ table.
+ </p><p>
+ The <em class="parameter"><code>indexPages</code></em> should be set to the number of leaf pages.
+ This is used to estimate the number of workers for parallel index scan.
+ </p><p>
+ When <em class="parameter"><code>loop_count</code></em> is greater than one, the returned numbers
+ should be averages expected for any one scan of the index.
+ </p><div class="procedure" id="id-1.10.15.12.13"><p class="title"><strong>Cost Estimation</strong></p><p>
+ A typical cost estimator will proceed as follows:
+ </p><ol class="procedure" type="1"><li class="step"><p>
+ Estimate and return the fraction of parent-table rows that will be visited
+ based on the given qual conditions. In the absence of any index-type-specific
+ knowledge, use the standard optimizer function <code class="function">clauselist_selectivity()</code>:
+
+</p><pre class="programlisting">
+*indexSelectivity = clauselist_selectivity(root, path-&gt;indexquals,
+ path-&gt;indexinfo-&gt;rel-&gt;relid,
+ JOIN_INNER, NULL);
+</pre><p>
+ </p></li><li class="step"><p>
+ Estimate the number of index rows that will be visited during the
+ scan. For many index types this is the same as <em class="parameter"><code>indexSelectivity</code></em> times
+ the number of rows in the index, but it might be more. (Note that the
+ index's size in pages and rows is available from the
+ <code class="literal">path-&gt;indexinfo</code> struct.)
+ </p></li><li class="step"><p>
+ Estimate the number of index pages that will be retrieved during the scan.
+ This might be just <em class="parameter"><code>indexSelectivity</code></em> times the index's size in pages.
+ </p></li><li class="step"><p>
+ Compute the index access cost. A generic estimator might do this:
+
+</p><pre class="programlisting">
+/*
+ * Our generic assumption is that the index pages will be read
+ * sequentially, so they cost seq_page_cost each, not random_page_cost.
+ * Also, we charge for evaluation of the indexquals at each index row.
+ * All the costs are assumed to be paid incrementally during the scan.
+ */
+cost_qual_eval(&amp;index_qual_cost, path-&gt;indexquals, root);
+*indexStartupCost = index_qual_cost.startup;
+*indexTotalCost = seq_page_cost * numIndexPages +
+ (cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
+</pre><p>
+
+ However, the above does not account for amortization of index reads
+ across repeated index scans.
+ </p></li><li class="step"><p>
+ Estimate the index correlation. For a simple ordered index on a single
+ field, this can be retrieved from pg_statistic. If the correlation
+ is not known, the conservative estimate is zero (no correlation).
+ </p></li></ol></div><p>
+ Examples of cost estimator functions can be found in
+ <code class="filename">src/backend/utils/adt/selfuncs.c</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="generic-wal.html" title="Chapter 65. Generic WAL Records">Next</a></td></tr><tr><td width="40%" align="left" valign="top">64.5. Index Uniqueness Checks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 65. Generic WAL Records</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index-functions.html b/doc/src/sgml/html/index-functions.html
new file mode 100644
index 0000000..bee58c1
--- /dev/null
+++ b/doc/src/sgml/html/index-functions.html
@@ -0,0 +1,483 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>64.2. Index Access Method Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index-api.html" title="64.1. Basic API Structure for Indexes" /><link rel="next" href="index-scanning.html" title="64.3. Index Scanning" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">64.2. Index Access Method Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-api.html" title="64.1. Basic API Structure for Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 64. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-scanning.html" title="64.3. Index Scanning">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEX-FUNCTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">64.2. Index Access Method Functions</h2></div></div></div><p>
+ The index construction and maintenance functions that an index access
+ method must provide in <code class="structname">IndexAmRoutine</code> are:
+ </p><p>
+</p><pre class="programlisting">
+IndexBuildResult *
+ambuild (Relation heapRelation,
+ Relation indexRelation,
+ IndexInfo *indexInfo);
+</pre><p>
+ Build a new index. The index relation has been physically created,
+ but is empty. It must be filled in with whatever fixed data the
+ access method requires, plus entries for all tuples already existing
+ in the table. Ordinarily the <code class="function">ambuild</code> function will call
+ <code class="function">table_index_build_scan()</code> to scan the table for existing tuples
+ and compute the keys that need to be inserted into the index.
+ The function must return a palloc'd struct containing statistics about
+ the new index.
+ </p><p>
+</p><pre class="programlisting">
+void
+ambuildempty (Relation indexRelation);
+</pre><p>
+ Build an empty index, and write it to the initialization fork (<code class="symbol">INIT_FORKNUM</code>)
+ of the given relation. This method is called only for unlogged indexes; the
+ empty index written to the initialization fork will be copied over the main
+ relation fork on each server restart.
+ </p><p>
+</p><pre class="programlisting">
+bool
+aminsert (Relation indexRelation,
+ Datum *values,
+ bool *isnull,
+ ItemPointer heap_tid,
+ Relation heapRelation,
+ IndexUniqueCheck checkUnique,
+ bool indexUnchanged,
+ IndexInfo *indexInfo);
+</pre><p>
+ Insert a new tuple into an existing index. The <code class="literal">values</code> and
+ <code class="literal">isnull</code> arrays give the key values to be indexed, and
+ <code class="literal">heap_tid</code> is the TID to be indexed.
+ If the access method supports unique indexes (its
+ <code class="structfield">amcanunique</code> flag is true) then
+ <code class="literal">checkUnique</code> indicates the type of uniqueness check to
+ perform. This varies depending on whether the unique constraint is
+ deferrable; see <a class="xref" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Section 64.5</a> for details.
+ Normally the access method only needs the <code class="literal">heapRelation</code>
+ parameter when performing uniqueness checking (since then it will have to
+ look into the heap to verify tuple liveness).
+ </p><p>
+ The <code class="literal">indexUnchanged</code> Boolean value gives a hint
+ about the nature of the tuple to be indexed. When it is true,
+ the tuple is a duplicate of some existing tuple in the index. The
+ new tuple is a logically unchanged successor MVCC tuple version. This
+ happens when an <code class="command">UPDATE</code> takes place that does not
+ modify any columns covered by the index, but nevertheless requires a
+ new version in the index. The index AM may use this hint to decide
+ to apply bottom-up index deletion in parts of the index where many
+ versions of the same logical row accumulate. Note that updating a
+ non-key column does not affect the value of
+ <code class="literal">indexUnchanged</code>.
+ </p><p>
+ The function's Boolean result value is significant only when
+ <code class="literal">checkUnique</code> is <code class="literal">UNIQUE_CHECK_PARTIAL</code>.
+ In this case a true result means the new entry is known unique, whereas
+ false means it might be non-unique (and a deferred uniqueness check must
+ be scheduled). For other cases a constant false result is recommended.
+ </p><p>
+ Some indexes might not index all tuples. If the tuple is not to be
+ indexed, <code class="function">aminsert</code> should just return without doing anything.
+ </p><p>
+ If the index AM wishes to cache data across successive index insertions
+ within an SQL statement, it can allocate space
+ in <code class="literal">indexInfo-&gt;ii_Context</code> and store a pointer to the
+ data in <code class="literal">indexInfo-&gt;ii_AmCache</code> (which will be NULL
+ initially).
+ </p><p>
+</p><pre class="programlisting">
+IndexBulkDeleteResult *
+ambulkdelete (IndexVacuumInfo *info,
+ IndexBulkDeleteResult *stats,
+ IndexBulkDeleteCallback callback,
+ void *callback_state);
+</pre><p>
+ Delete tuple(s) from the index. This is a <span class="quote">“<span class="quote">bulk delete</span>”</span> operation
+ that is intended to be implemented by scanning the whole index and checking
+ each entry to see if it should be deleted.
+ The passed-in <code class="literal">callback</code> function must be called, in the style
+ <code class="literal">callback(<em class="replaceable"><code>TID</code></em>, callback_state) returns bool</code>,
+ to determine whether any particular index entry, as identified by its
+ referenced TID, is to be deleted. Must return either NULL or a palloc'd
+ struct containing statistics about the effects of the deletion operation.
+ It is OK to return NULL if no information needs to be passed on to
+ <code class="function">amvacuumcleanup</code>.
+ </p><p>
+ Because of limited <code class="varname">maintenance_work_mem</code>,
+ <code class="function">ambulkdelete</code> might need to be called more than once when many
+ tuples are to be deleted. The <code class="literal">stats</code> argument is the result
+ of the previous call for this index (it is NULL for the first call within a
+ <code class="command">VACUUM</code> operation). This allows the AM to accumulate statistics
+ across the whole operation. Typically, <code class="function">ambulkdelete</code> will
+ modify and return the same struct if the passed <code class="literal">stats</code> is not
+ null.
+ </p><p>
+</p><pre class="programlisting">
+IndexBulkDeleteResult *
+amvacuumcleanup (IndexVacuumInfo *info,
+ IndexBulkDeleteResult *stats);
+</pre><p>
+ Clean up after a <code class="command">VACUUM</code> operation (zero or more
+ <code class="function">ambulkdelete</code> calls). This does not have to do anything
+ beyond returning index statistics, but it might perform bulk cleanup
+ such as reclaiming empty index pages. <code class="literal">stats</code> is whatever the
+ last <code class="function">ambulkdelete</code> call returned, or NULL if
+ <code class="function">ambulkdelete</code> was not called because no tuples needed to be
+ deleted. If the result is not NULL it must be a palloc'd struct.
+ The statistics it contains will be used to update <code class="structname">pg_class</code>,
+ and will be reported by <code class="command">VACUUM</code> if <code class="literal">VERBOSE</code> is given.
+ It is OK to return NULL if the index was not changed at all during the
+ <code class="command">VACUUM</code> operation, but otherwise correct stats should
+ be returned.
+ </p><p>
+ <code class="function">amvacuumcleanup</code> will also be called at completion of an
+ <code class="command">ANALYZE</code> operation. In this case <code class="literal">stats</code> is always
+ NULL and any return value will be ignored. This case can be distinguished
+ by checking <code class="literal">info-&gt;analyze_only</code>. It is recommended
+ that the access method do nothing except post-insert cleanup in such a
+ call, and that only in an autovacuum worker process.
+ </p><p>
+</p><pre class="programlisting">
+bool
+amcanreturn (Relation indexRelation, int attno);
+</pre><p>
+ Check whether the index can support <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes"><em class="firstterm">index-only scans</em></a> on
+ the given column, by returning the column's original indexed value.
+ The attribute number is 1-based, i.e., the first column's attno is 1.
+ Returns true if supported, else false.
+ This function should always return true for included columns
+ (if those are supported), since there's little point in an included
+ column that can't be retrieved.
+ If the access method does not support index-only scans at all,
+ the <code class="structfield">amcanreturn</code> field in its <code class="structname">IndexAmRoutine</code>
+ struct can be set to NULL.
+ </p><p>
+</p><pre class="programlisting">
+void
+amcostestimate (PlannerInfo *root,
+ IndexPath *path,
+ double loop_count,
+ Cost *indexStartupCost,
+ Cost *indexTotalCost,
+ Selectivity *indexSelectivity,
+ double *indexCorrelation,
+ double *indexPages);
+</pre><p>
+ Estimate the costs of an index scan. This function is described fully
+ in <a class="xref" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions">Section 64.6</a>, below.
+ </p><p>
+</p><pre class="programlisting">
+bytea *
+amoptions (ArrayType *reloptions,
+ bool validate);
+</pre><p>
+ Parse and validate the reloptions array for an index. This is called only
+ when a non-null reloptions array exists for the index.
+ <em class="parameter"><code>reloptions</code></em> is a <code class="type">text</code> array containing entries of the
+ form <em class="replaceable"><code>name</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em>.
+ The function should construct a <code class="type">bytea</code> value, which will be copied
+ into the <code class="structfield">rd_options</code> field of the index's relcache entry.
+ The data contents of the <code class="type">bytea</code> value are open for the access
+ method to define; most of the standard access methods use struct
+ <code class="structname">StdRdOptions</code>.
+ When <em class="parameter"><code>validate</code></em> is true, the function should report a suitable
+ error message if any of the options are unrecognized or have invalid
+ values; when <em class="parameter"><code>validate</code></em> is false, invalid entries should be
+ silently ignored. (<em class="parameter"><code>validate</code></em> is false when loading options
+ already stored in <code class="structname">pg_catalog</code>; an invalid entry could only
+ be found if the access method has changed its rules for options, and in
+ that case ignoring obsolete entries is appropriate.)
+ It is OK to return NULL if default behavior is wanted.
+ </p><p>
+</p><pre class="programlisting">
+bool
+amproperty (Oid index_oid, int attno,
+ IndexAMProperty prop, const char *propname,
+ bool *res, bool *isnull);
+</pre><p>
+ The <code class="function">amproperty</code> method allows index access methods to override
+ the default behavior of <code class="function">pg_index_column_has_property</code>
+ and related functions.
+ If the access method does not have any special behavior for index property
+ inquiries, the <code class="structfield">amproperty</code> field in
+ its <code class="structname">IndexAmRoutine</code> struct can be set to NULL.
+ Otherwise, the <code class="function">amproperty</code> method will be called with
+ <em class="parameter"><code>index_oid</code></em> and <em class="parameter"><code>attno</code></em> both zero for
+ <code class="function">pg_indexam_has_property</code> calls,
+ or with <em class="parameter"><code>index_oid</code></em> valid and <em class="parameter"><code>attno</code></em> zero for
+ <code class="function">pg_index_has_property</code> calls,
+ or with <em class="parameter"><code>index_oid</code></em> valid and <em class="parameter"><code>attno</code></em> greater than
+ zero for <code class="function">pg_index_column_has_property</code> calls.
+ <em class="parameter"><code>prop</code></em> is an enum value identifying the property being tested,
+ while <em class="parameter"><code>propname</code></em> is the original property name string.
+ If the core code does not recognize the property name
+ then <em class="parameter"><code>prop</code></em> is <code class="literal">AMPROP_UNKNOWN</code>.
+ Access methods can define custom property names by
+ checking <em class="parameter"><code>propname</code></em> for a match (use <code class="function">pg_strcasecmp</code>
+ to match, for consistency with the core code); for names known to the core
+ code, it's better to inspect <em class="parameter"><code>prop</code></em>.
+ If the <code class="structfield">amproperty</code> method returns <code class="literal">true</code> then
+ it has determined the property test result: it must set <code class="literal">*res</code>
+ to the Boolean value to return, or set <code class="literal">*isnull</code>
+ to <code class="literal">true</code> to return a NULL. (Both of the referenced variables
+ are initialized to <code class="literal">false</code> before the call.)
+ If the <code class="structfield">amproperty</code> method returns <code class="literal">false</code> then
+ the core code will proceed with its normal logic for determining the
+ property test result.
+ </p><p>
+ Access methods that support ordering operators should
+ implement <code class="literal">AMPROP_DISTANCE_ORDERABLE</code> property testing, as the
+ core code does not know how to do that and will return NULL. It may
+ also be advantageous to implement <code class="literal">AMPROP_RETURNABLE</code> testing,
+ if that can be done more cheaply than by opening the index and calling
+ <code class="function">amcanreturn</code>, which is the core code's default behavior.
+ The default behavior should be satisfactory for all other standard
+ properties.
+ </p><p>
+</p><pre class="programlisting">
+char *
+ambuildphasename (int64 phasenum);
+</pre><p>
+ Return the textual name of the given build phase number.
+ The phase numbers are those reported during an index build via the
+ <code class="function">pgstat_progress_update_param</code> interface.
+ The phase names are then exposed in the
+ <code class="structname">pg_stat_progress_create_index</code> view.
+ </p><p>
+</p><pre class="programlisting">
+bool
+amvalidate (Oid opclassoid);
+</pre><p>
+ Validate the catalog entries for the specified operator class, so far as
+ the access method can reasonably do that. For example, this might include
+ testing that all required support functions are provided.
+ The <code class="function">amvalidate</code> function must return false if the opclass is
+ invalid. Problems should be reported with <code class="function">ereport</code>
+ messages, typically at <code class="literal">INFO</code> level.
+ </p><p>
+</p><pre class="programlisting">
+void
+amadjustmembers (Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
+</pre><p>
+ Validate proposed new operator and function members of an operator family,
+ so far as the access method can reasonably do that, and set their
+ dependency types if the default is not satisfactory. This is called
+ during <code class="command">CREATE OPERATOR CLASS</code> and during
+ <code class="command">ALTER OPERATOR FAMILY ADD</code>; in the latter
+ case <em class="parameter"><code>opclassoid</code></em> is <code class="literal">InvalidOid</code>.
+ The <code class="type">List</code> arguments are lists
+ of <code class="structname">OpFamilyMember</code> structs, as defined
+ in <code class="filename">amapi.h</code>.
+
+ Tests done by this function will typically be a subset of those
+ performed by <code class="function">amvalidate</code>,
+ since <code class="function">amadjustmembers</code> cannot assume that it is
+ seeing a complete set of members. For example, it would be reasonable
+ to check the signature of a support function, but not to check whether
+ all required support functions are provided. Any problems can be
+ reported by throwing an error.
+
+ The dependency-related fields of
+ the <code class="structname">OpFamilyMember</code> structs are initialized by
+ the core code to create hard dependencies on the opclass if this
+ is <code class="command">CREATE OPERATOR CLASS</code>, or soft dependencies on the
+ opfamily if this is <code class="command">ALTER OPERATOR FAMILY ADD</code>.
+ <code class="function">amadjustmembers</code> can adjust these fields if some other
+ behavior is more appropriate. For example, GIN, GiST, and SP-GiST
+ always set operator members to have soft dependencies on the opfamily,
+ since the connection between an operator and an opclass is relatively
+ weak in these index types; so it is reasonable to allow operator members
+ to be added and removed freely. Optional support functions are typically
+ also given soft dependencies, so that they can be removed if necessary.
+ </p><p>
+ The purpose of an index, of course, is to support scans for tuples matching
+ an indexable <code class="literal">WHERE</code> condition, often called a
+ <em class="firstterm">qualifier</em> or <em class="firstterm">scan key</em>. The semantics of
+ index scanning are described more fully in <a class="xref" href="index-scanning.html" title="64.3. Index Scanning">Section 64.3</a>,
+ below. An index access method can support <span class="quote">“<span class="quote">plain</span>”</span> index scans,
+ <span class="quote">“<span class="quote">bitmap</span>”</span> index scans, or both. The scan-related functions that an
+ index access method must or may provide are:
+ </p><p>
+</p><pre class="programlisting">
+IndexScanDesc
+ambeginscan (Relation indexRelation,
+ int nkeys,
+ int norderbys);
+</pre><p>
+ Prepare for an index scan. The <code class="literal">nkeys</code> and <code class="literal">norderbys</code>
+ parameters indicate the number of quals and ordering operators that will be
+ used in the scan; these may be useful for space allocation purposes.
+ Note that the actual values of the scan keys aren't provided yet.
+ The result must be a palloc'd struct.
+ For implementation reasons the index access method
+ <span class="emphasis"><em>must</em></span> create this struct by calling
+ <code class="function">RelationGetIndexScan()</code>. In most cases
+ <code class="function">ambeginscan</code> does little beyond making that call and perhaps
+ acquiring locks;
+ the interesting parts of index-scan startup are in <code class="function">amrescan</code>.
+ </p><p>
+</p><pre class="programlisting">
+void
+amrescan (IndexScanDesc scan,
+ ScanKey keys,
+ int nkeys,
+ ScanKey orderbys,
+ int norderbys);
+</pre><p>
+ Start or restart an index scan, possibly with new scan keys. (To restart
+ using previously-passed keys, NULL is passed for <code class="literal">keys</code> and/or
+ <code class="literal">orderbys</code>.) Note that it is not allowed for
+ the number of keys or order-by operators to be larger than
+ what was passed to <code class="function">ambeginscan</code>. In practice the restart
+ feature is used when a new outer tuple is selected by a nested-loop join
+ and so a new key comparison value is needed, but the scan key structure
+ remains the same.
+ </p><p>
+</p><pre class="programlisting">
+bool
+amgettuple (IndexScanDesc scan,
+ ScanDirection direction);
+</pre><p>
+ Fetch the next tuple in the given scan, moving in the given
+ direction (forward or backward in the index). Returns true if a tuple was
+ obtained, false if no matching tuples remain. In the true case the tuple
+ TID is stored into the <code class="literal">scan</code> structure. Note that
+ <span class="quote">“<span class="quote">success</span>”</span> means only that the index contains an entry that matches
+ the scan keys, not that the tuple necessarily still exists in the heap or
+ will pass the caller's snapshot test. On success, <code class="function">amgettuple</code>
+ must also set <code class="literal">scan-&gt;xs_recheck</code> to true or false.
+ False means it is certain that the index entry matches the scan keys.
+ True means this is not certain, and the conditions represented by the
+ scan keys must be rechecked against the heap tuple after fetching it.
+ This provision supports <span class="quote">“<span class="quote">lossy</span>”</span> index operators.
+ Note that rechecking will extend only to the scan conditions; a partial
+ index predicate (if any) is never rechecked by <code class="function">amgettuple</code>
+ callers.
+ </p><p>
+ If the index supports <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">index-only
+ scans</a> (i.e., <code class="function">amcanreturn</code> returns true for any
+ of its columns),
+ then on success the AM must also check <code class="literal">scan-&gt;xs_want_itup</code>,
+ and if that is true it must return the originally indexed data for the
+ index entry. Columns for which <code class="function">amcanreturn</code> returns
+ false can be returned as nulls.
+ The data can be returned in the form of an
+ <code class="structname">IndexTuple</code> pointer stored at <code class="literal">scan-&gt;xs_itup</code>,
+ with tuple descriptor <code class="literal">scan-&gt;xs_itupdesc</code>; or in the form of
+ a <code class="structname">HeapTuple</code> pointer stored at <code class="literal">scan-&gt;xs_hitup</code>,
+ with tuple descriptor <code class="literal">scan-&gt;xs_hitupdesc</code>. (The latter
+ format should be used when reconstructing data that might possibly not fit
+ into an <code class="structname">IndexTuple</code>.) In either case,
+ management of the data referenced by the pointer is the access method's
+ responsibility. The data must remain good at least until the next
+ <code class="function">amgettuple</code>, <code class="function">amrescan</code>, or <code class="function">amendscan</code>
+ call for the scan.
+ </p><p>
+ The <code class="function">amgettuple</code> function need only be provided if the access
+ method supports <span class="quote">“<span class="quote">plain</span>”</span> index scans. If it doesn't, the
+ <code class="structfield">amgettuple</code> field in its <code class="structname">IndexAmRoutine</code>
+ struct must be set to NULL.
+ </p><p>
+</p><pre class="programlisting">
+int64
+amgetbitmap (IndexScanDesc scan,
+ TIDBitmap *tbm);
+</pre><p>
+ Fetch all tuples in the given scan and add them to the caller-supplied
+ <code class="type">TIDBitmap</code> (that is, OR the set of tuple IDs into whatever set is already
+ in the bitmap). The number of tuples fetched is returned (this might be
+ just an approximate count, for instance some AMs do not detect duplicates).
+ While inserting tuple IDs into the bitmap, <code class="function">amgetbitmap</code> can
+ indicate that rechecking of the scan conditions is required for specific
+ tuple IDs. This is analogous to the <code class="literal">xs_recheck</code> output parameter
+ of <code class="function">amgettuple</code>. Note: in the current implementation, support
+ for this feature is conflated with support for lossy storage of the bitmap
+ itself, and therefore callers recheck both the scan conditions and the
+ partial index predicate (if any) for recheckable tuples. That might not
+ always be true, however.
+ <code class="function">amgetbitmap</code> and
+ <code class="function">amgettuple</code> cannot be used in the same index scan; there
+ are other restrictions too when using <code class="function">amgetbitmap</code>, as explained
+ in <a class="xref" href="index-scanning.html" title="64.3. Index Scanning">Section 64.3</a>.
+ </p><p>
+ The <code class="function">amgetbitmap</code> function need only be provided if the access
+ method supports <span class="quote">“<span class="quote">bitmap</span>”</span> index scans. If it doesn't, the
+ <code class="structfield">amgetbitmap</code> field in its <code class="structname">IndexAmRoutine</code>
+ struct must be set to NULL.
+ </p><p>
+</p><pre class="programlisting">
+void
+amendscan (IndexScanDesc scan);
+</pre><p>
+ End a scan and release resources. The <code class="literal">scan</code> struct itself
+ should not be freed, but any locks or pins taken internally by the
+ access method must be released, as well as any other memory allocated
+ by <code class="function">ambeginscan</code> and other scan-related functions.
+ </p><p>
+</p><pre class="programlisting">
+void
+ammarkpos (IndexScanDesc scan);
+</pre><p>
+ Mark current scan position. The access method need only support one
+ remembered scan position per scan.
+ </p><p>
+ The <code class="function">ammarkpos</code> function need only be provided if the access
+ method supports ordered scans. If it doesn't,
+ the <code class="structfield">ammarkpos</code> field in its <code class="structname">IndexAmRoutine</code>
+ struct may be set to NULL.
+ </p><p>
+</p><pre class="programlisting">
+void
+amrestrpos (IndexScanDesc scan);
+</pre><p>
+ Restore the scan to the most recently marked position.
+ </p><p>
+ The <code class="function">amrestrpos</code> function need only be provided if the access
+ method supports ordered scans. If it doesn't,
+ the <code class="structfield">amrestrpos</code> field in its <code class="structname">IndexAmRoutine</code>
+ struct may be set to NULL.
+ </p><p>
+ In addition to supporting ordinary index scans, some types of index
+ may wish to support <em class="firstterm">parallel index scans</em>, which allow
+ multiple backends to cooperate in performing an index scan. The
+ index access method should arrange things so that each cooperating
+ process returns a subset of the tuples that would be performed by
+ an ordinary, non-parallel index scan, but in such a way that the
+ union of those subsets is equal to the set of tuples that would be
+ returned by an ordinary, non-parallel index scan. Furthermore, while
+ there need not be any global ordering of tuples returned by a parallel
+ scan, the ordering of that subset of tuples returned within each
+ cooperating backend must match the requested ordering. The following
+ functions may be implemented to support parallel index scans:
+ </p><p>
+</p><pre class="programlisting">
+Size
+amestimateparallelscan (void);
+</pre><p>
+ Estimate and return the number of bytes of dynamic shared memory which
+ the access method will be needed to perform a parallel scan. (This number
+ is in addition to, not in lieu of, the amount of space needed for
+ AM-independent data in <code class="structname">ParallelIndexScanDescData</code>.)
+ </p><p>
+ It is not necessary to implement this function for access methods which
+ do not support parallel scans or for which the number of additional bytes
+ of storage required is zero.
+ </p><p>
+</p><pre class="programlisting">
+void
+aminitparallelscan (void *target);
+</pre><p>
+ This function will be called to initialize dynamic shared memory at the
+ beginning of a parallel scan. <em class="parameter"><code>target</code></em> will point to at least
+ the number of bytes previously returned by
+ <code class="function">amestimateparallelscan</code>, and this function may use that
+ amount of space to store whatever data it wishes.
+ </p><p>
+ It is not necessary to implement this function for access methods which
+ do not support parallel scans or in cases where the shared memory space
+ required needs no initialization.
+ </p><p>
+</p><pre class="programlisting">
+void
+amparallelrescan (IndexScanDesc scan);
+</pre><p>
+ This function, if implemented, will be called when a parallel index scan
+ must be restarted. It should reset any shared state set up by
+ <code class="function">aminitparallelscan</code> such that the scan will be restarted from
+ the beginning.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-api.html" title="64.1. Basic API Structure for Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-scanning.html" title="64.3. Index Scanning">Next</a></td></tr><tr><td width="40%" align="left" valign="top">64.1. Basic API Structure for Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 64.3. Index Scanning</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index-locking.html b/doc/src/sgml/html/index-locking.html
new file mode 100644
index 0000000..a24d5f4
--- /dev/null
+++ b/doc/src/sgml/html/index-locking.html
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>64.4. Index Locking Considerations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index-scanning.html" title="64.3. Index Scanning" /><link rel="next" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">64.4. Index Locking Considerations</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-scanning.html" title="64.3. Index Scanning">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 64. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEX-LOCKING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">64.4. Index Locking Considerations</h2></div></div></div><p>
+ Index access methods must handle concurrent updates
+ of the index by multiple processes.
+ The core <span class="productname">PostgreSQL</span> system obtains
+ <code class="literal">AccessShareLock</code> on the index during an index scan, and
+ <code class="literal">RowExclusiveLock</code> when updating the index (including plain
+ <code class="command">VACUUM</code>). Since these lock types do not conflict, the access
+ method is responsible for handling any fine-grained locking it might need.
+ An <code class="literal">ACCESS EXCLUSIVE</code> lock on the index as a whole will be
+ taken only during index creation, destruction, or <code class="command">REINDEX</code>
+ (<code class="literal">SHARE UPDATE EXCLUSIVE</code> is taken instead with
+ <code class="literal">CONCURRENTLY</code>).
+ </p><p>
+ Building an index type that supports concurrent updates usually requires
+ extensive and subtle analysis of the required behavior. For the b-tree
+ and hash index types, you can read about the design decisions involved in
+ <code class="filename">src/backend/access/nbtree/README</code> and
+ <code class="filename">src/backend/access/hash/README</code>.
+ </p><p>
+ Aside from the index's own internal consistency requirements, concurrent
+ updates create issues about consistency between the parent table (the
+ <em class="firstterm">heap</em>) and the index. Because
+ <span class="productname">PostgreSQL</span> separates accesses
+ and updates of the heap from those of the index, there are windows in
+ which the index might be inconsistent with the heap. We handle this problem
+ with the following rules:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A new heap entry is made before making its index entries. (Therefore
+ a concurrent index scan is likely to fail to see the heap entry.
+ This is okay because the index reader would be uninterested in an
+ uncommitted row anyway. But see <a class="xref" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Section 64.5</a>.)
+ </p></li><li class="listitem"><p>
+ When a heap entry is to be deleted (by <code class="command">VACUUM</code>), all its
+ index entries must be removed first.
+ </p></li><li class="listitem"><p>
+ An index scan must maintain a pin
+ on the index page holding the item last returned by
+ <code class="function">amgettuple</code>, and <code class="function">ambulkdelete</code> cannot delete
+ entries from pages that are pinned by other backends. The need
+ for this rule is explained below.
+ </p></li></ul></div><p>
+
+ Without the third rule, it is possible for an index reader to
+ see an index entry just before it is removed by <code class="command">VACUUM</code>, and
+ then to arrive at the corresponding heap entry after that was removed by
+ <code class="command">VACUUM</code>.
+ This creates no serious problems if that item
+ number is still unused when the reader reaches it, since an empty
+ item slot will be ignored by <code class="function">heap_fetch()</code>. But what if a
+ third backend has already re-used the item slot for something else?
+ When using an MVCC-compliant snapshot, there is no problem because
+ the new occupant of the slot is certain to be too new to pass the
+ snapshot test. However, with a non-MVCC-compliant snapshot (such as
+ <code class="literal">SnapshotAny</code>), it would be possible to accept and return
+ a row that does not in fact match the scan keys. We could defend
+ against this scenario by requiring the scan keys to be rechecked
+ against the heap row in all cases, but that is too expensive. Instead,
+ we use a pin on an index page as a proxy to indicate that the reader
+ might still be <span class="quote">“<span class="quote">in flight</span>”</span> from the index entry to the matching
+ heap entry. Making <code class="function">ambulkdelete</code> block on such a pin ensures
+ that <code class="command">VACUUM</code> cannot delete the heap entry before the reader
+ is done with it. This solution costs little in run time, and adds blocking
+ overhead only in the rare cases where there actually is a conflict.
+ </p><p>
+ This solution requires that index scans be <span class="quote">“<span class="quote">synchronous</span>”</span>: we have
+ to fetch each heap tuple immediately after scanning the corresponding index
+ entry. This is expensive for a number of reasons. An
+ <span class="quote">“<span class="quote">asynchronous</span>”</span> scan in which we collect many TIDs from the index,
+ and only visit the heap tuples sometime later, requires much less index
+ locking overhead and can allow a more efficient heap access pattern.
+ Per the above analysis, we must use the synchronous approach for
+ non-MVCC-compliant snapshots, but an asynchronous scan is workable
+ for a query using an MVCC snapshot.
+ </p><p>
+ In an <code class="function">amgetbitmap</code> index scan, the access method does not
+ keep an index pin on any of the returned tuples. Therefore
+ it is only safe to use such scans with MVCC-compliant snapshots.
+ </p><p>
+ When the <code class="structfield">ampredlocks</code> flag is not set, any scan using that
+ index access method within a serializable transaction will acquire a
+ nonblocking predicate lock on the full index. This will generate a
+ read-write conflict with the insert of any tuple into that index by a
+ concurrent serializable transaction. If certain patterns of read-write
+ conflicts are detected among a set of concurrent serializable
+ transactions, one of those transactions may be canceled to protect data
+ integrity. When the flag is set, it indicates that the index access
+ method implements finer-grained predicate locking, which will tend to
+ reduce the frequency of such transaction cancellations.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-scanning.html" title="64.3. Index Scanning">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">64.3. Index Scanning </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 64.5. Index Uniqueness Checks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index-scanning.html b/doc/src/sgml/html/index-scanning.html
new file mode 100644
index 0000000..0497418
--- /dev/null
+++ b/doc/src/sgml/html/index-scanning.html
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>64.3. Index Scanning</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index-functions.html" title="64.2. Index Access Method Functions" /><link rel="next" href="index-locking.html" title="64.4. Index Locking Considerations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">64.3. Index Scanning</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-functions.html" title="64.2. Index Access Method Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 64. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-locking.html" title="64.4. Index Locking Considerations">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEX-SCANNING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">64.3. Index Scanning</h2></div></div></div><p>
+ In an index scan, the index access method is responsible for regurgitating
+ the TIDs of all the tuples it has been told about that match the
+ <em class="firstterm">scan keys</em>. The access method is <span class="emphasis"><em>not</em></span> involved in
+ actually fetching those tuples from the index's parent table, nor in
+ determining whether they pass the scan's visibility test or other
+ conditions.
+ </p><p>
+ A scan key is the internal representation of a <code class="literal">WHERE</code> clause of
+ the form <em class="replaceable"><code>index_key</code></em> <em class="replaceable"><code>operator</code></em>
+ <em class="replaceable"><code>constant</code></em>, where the index key is one of the columns of the
+ index and the operator is one of the members of the operator family
+ associated with that index column. An index scan has zero or more scan
+ keys, which are implicitly ANDed — the returned tuples are expected
+ to satisfy all the indicated conditions.
+ </p><p>
+ The access method can report that the index is <em class="firstterm">lossy</em>, or
+ requires rechecks, for a particular query. This implies that the index
+ scan will return all the entries that pass the scan key, plus possibly
+ additional entries that do not. The core system's index-scan machinery
+ will then apply the index conditions again to the heap tuple to verify
+ whether or not it really should be selected. If the recheck option is not
+ specified, the index scan must return exactly the set of matching entries.
+ </p><p>
+ Note that it is entirely up to the access method to ensure that it
+ correctly finds all and only the entries passing all the given scan keys.
+ Also, the core system will simply hand off all the <code class="literal">WHERE</code>
+ clauses that match the index keys and operator families, without any
+ semantic analysis to determine whether they are redundant or
+ contradictory. As an example, given
+ <code class="literal">WHERE x &gt; 4 AND x &gt; 14</code> where <code class="literal">x</code> is a b-tree
+ indexed column, it is left to the b-tree <code class="function">amrescan</code> function
+ to realize that the first scan key is redundant and can be discarded.
+ The extent of preprocessing needed during <code class="function">amrescan</code> will
+ depend on the extent to which the index access method needs to reduce
+ the scan keys to a <span class="quote">“<span class="quote">normalized</span>”</span> form.
+ </p><p>
+ Some access methods return index entries in a well-defined order, others
+ do not. There are actually two different ways that an access method can
+ support sorted output:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Access methods that always return entries in the natural ordering
+ of their data (such as btree) should set
+ <code class="structfield">amcanorder</code> to true.
+ Currently, such access methods must use btree-compatible strategy
+ numbers for their equality and ordering operators.
+ </p></li><li class="listitem"><p>
+ Access methods that support ordering operators should set
+ <code class="structfield">amcanorderbyop</code> to true.
+ This indicates that the index is capable of returning entries in
+ an order satisfying <code class="literal">ORDER BY</code> <em class="replaceable"><code>index_key</code></em>
+ <em class="replaceable"><code>operator</code></em> <em class="replaceable"><code>constant</code></em>. Scan modifiers
+ of that form can be passed to <code class="function">amrescan</code> as described
+ previously.
+ </p></li></ul></div><p>
+ </p><p>
+ The <code class="function">amgettuple</code> function has a <code class="literal">direction</code> argument,
+ which can be either <code class="literal">ForwardScanDirection</code> (the normal case)
+ or <code class="literal">BackwardScanDirection</code>. If the first call after
+ <code class="function">amrescan</code> specifies <code class="literal">BackwardScanDirection</code>, then the
+ set of matching index entries is to be scanned back-to-front rather than in
+ the normal front-to-back direction, so <code class="function">amgettuple</code> must return
+ the last matching tuple in the index, rather than the first one as it
+ normally would. (This will only occur for access
+ methods that set <code class="structfield">amcanorder</code> to true.) After the
+ first call, <code class="function">amgettuple</code> must be prepared to advance the scan in
+ either direction from the most recently returned entry. (But if
+ <code class="structfield">amcanbackward</code> is false, all subsequent
+ calls will have the same direction as the first one.)
+ </p><p>
+ Access methods that support ordered scans must support <span class="quote">“<span class="quote">marking</span>”</span> a
+ position in a scan and later returning to the marked position. The same
+ position might be restored multiple times. However, only one position need
+ be remembered per scan; a new <code class="function">ammarkpos</code> call overrides the
+ previously marked position. An access method that does not support ordered
+ scans need not provide <code class="function">ammarkpos</code> and <code class="function">amrestrpos</code>
+ functions in <code class="structname">IndexAmRoutine</code>; set those pointers to NULL
+ instead.
+ </p><p>
+ Both the scan position and the mark position (if any) must be maintained
+ consistently in the face of concurrent insertions or deletions in the
+ index. It is OK if a freshly-inserted entry is not returned by a scan that
+ would have found the entry if it had existed when the scan started, or for
+ the scan to return such an entry upon rescanning or backing
+ up even though it had not been returned the first time through. Similarly,
+ a concurrent delete might or might not be reflected in the results of a scan.
+ What is important is that insertions or deletions not cause the scan to
+ miss or multiply return entries that were not themselves being inserted or
+ deleted.
+ </p><p>
+ If the index stores the original indexed data values (and not some lossy
+ representation of them), it is useful to
+ support <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">index-only scans</a>, in
+ which the index returns the actual data not just the TID of the heap tuple.
+ This will only avoid I/O if the visibility map shows that the TID is on an
+ all-visible page; else the heap tuple must be visited anyway to check
+ MVCC visibility. But that is no concern of the access method's.
+ </p><p>
+ Instead of using <code class="function">amgettuple</code>, an index scan can be done with
+ <code class="function">amgetbitmap</code> to fetch all tuples in one call. This can be
+ noticeably more efficient than <code class="function">amgettuple</code> because it allows
+ avoiding lock/unlock cycles within the access method. In principle
+ <code class="function">amgetbitmap</code> should have the same effects as repeated
+ <code class="function">amgettuple</code> calls, but we impose several restrictions to
+ simplify matters. First of all, <code class="function">amgetbitmap</code> returns all
+ tuples at once and marking or restoring scan positions isn't
+ supported. Secondly, the tuples are returned in a bitmap which doesn't
+ have any specific ordering, which is why <code class="function">amgetbitmap</code> doesn't
+ take a <code class="literal">direction</code> argument. (Ordering operators will never be
+ supplied for such a scan, either.)
+ Also, there is no provision for index-only scans with
+ <code class="function">amgetbitmap</code>, since there is no way to return the contents of
+ index tuples.
+ Finally, <code class="function">amgetbitmap</code>
+ does not guarantee any locking of the returned tuples, with implications
+ spelled out in <a class="xref" href="index-locking.html" title="64.4. Index Locking Considerations">Section 64.4</a>.
+ </p><p>
+ Note that it is permitted for an access method to implement only
+ <code class="function">amgetbitmap</code> and not <code class="function">amgettuple</code>, or vice versa,
+ if its internal implementation is unsuited to one API or the other.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-functions.html" title="64.2. Index Access Method Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-locking.html" title="64.4. Index Locking Considerations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">64.2. Index Access Method Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 64.4. Index Locking Considerations</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index-unique-checks.html b/doc/src/sgml/html/index-unique-checks.html
new file mode 100644
index 0000000..bc029e7
--- /dev/null
+++ b/doc/src/sgml/html/index-unique-checks.html
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>64.5. Index Uniqueness Checks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index-locking.html" title="64.4. Index Locking Considerations" /><link rel="next" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">64.5. Index Uniqueness Checks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index-locking.html" title="64.4. Index Locking Considerations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><th width="60%" align="center">Chapter 64. Index Access Method Interface Definition</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEX-UNIQUE-CHECKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">64.5. Index Uniqueness Checks</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> enforces SQL uniqueness constraints
+ using <em class="firstterm">unique indexes</em>, which are indexes that disallow
+ multiple entries with identical keys. An access method that supports this
+ feature sets <code class="structfield">amcanunique</code> true.
+ (At present, only b-tree supports it.) Columns listed in the
+ <code class="literal">INCLUDE</code> clause are not considered when enforcing
+ uniqueness.
+ </p><p>
+ Because of MVCC, it is always necessary to allow duplicate entries to
+ exist physically in an index: the entries might refer to successive
+ versions of a single logical row. The behavior we actually want to
+ enforce is that no MVCC snapshot could include two rows with equal
+ index keys. This breaks down into the following cases that must be
+ checked when inserting a new row into a unique index:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If a conflicting valid row has been deleted by the current transaction,
+ it's okay. (In particular, since an UPDATE always deletes the old row
+ version before inserting the new version, this will allow an UPDATE on
+ a row without changing the key.)
+ </p></li><li class="listitem"><p>
+ If a conflicting row has been inserted by an as-yet-uncommitted
+ transaction, the would-be inserter must wait to see if that transaction
+ commits. If it rolls back then there is no conflict. If it commits
+ without deleting the conflicting row again, there is a uniqueness
+ violation. (In practice we just wait for the other transaction to
+ end and then redo the visibility check in toto.)
+ </p></li><li class="listitem"><p>
+ Similarly, if a conflicting valid row has been deleted by an
+ as-yet-uncommitted transaction, the would-be inserter must wait
+ for that transaction to commit or abort, and then repeat the test.
+ </p></li></ul></div><p>
+ </p><p>
+ Furthermore, immediately before reporting a uniqueness violation
+ according to the above rules, the access method must recheck the
+ liveness of the row being inserted. If it is committed dead then
+ no violation should be reported. (This case cannot occur during the
+ ordinary scenario of inserting a row that's just been created by
+ the current transaction. It can happen during
+ <code class="command">CREATE UNIQUE INDEX CONCURRENTLY</code>, however.)
+ </p><p>
+ We require the index access method to apply these tests itself, which
+ means that it must reach into the heap to check the commit status of
+ any row that is shown to have a duplicate key according to the index
+ contents. This is without a doubt ugly and non-modular, but it saves
+ redundant work: if we did a separate probe then the index lookup for
+ a conflicting row would be essentially repeated while finding the place to
+ insert the new row's index entry. What's more, there is no obvious way
+ to avoid race conditions unless the conflict check is an integral part
+ of insertion of the new index entry.
+ </p><p>
+ If the unique constraint is deferrable, there is additional complexity:
+ we need to be able to insert an index entry for a new row, but defer any
+ uniqueness-violation error until end of statement or even later. To
+ avoid unnecessary repeat searches of the index, the index access method
+ should do a preliminary uniqueness check during the initial insertion.
+ If this shows that there is definitely no conflicting live tuple, we
+ are done. Otherwise, we schedule a recheck to occur when it is time to
+ enforce the constraint. If, at the time of the recheck, both the inserted
+ tuple and some other tuple with the same key are live, then the error
+ must be reported. (Note that for this purpose, <span class="quote">“<span class="quote">live</span>”</span> actually
+ means <span class="quote">“<span class="quote">any tuple in the index entry's HOT chain is live</span>”</span>.)
+ To implement this, the <code class="function">aminsert</code> function is passed a
+ <code class="literal">checkUnique</code> parameter having one of the following values:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">UNIQUE_CHECK_NO</code> indicates that no uniqueness checking
+ should be done (this is not a unique index).
+ </p></li><li class="listitem"><p>
+ <code class="literal">UNIQUE_CHECK_YES</code> indicates that this is a non-deferrable
+ unique index, and the uniqueness check must be done immediately, as
+ described above.
+ </p></li><li class="listitem"><p>
+ <code class="literal">UNIQUE_CHECK_PARTIAL</code> indicates that the unique
+ constraint is deferrable. <span class="productname">PostgreSQL</span>
+ will use this mode to insert each row's index entry. The access
+ method must allow duplicate entries into the index, and report any
+ potential duplicates by returning false from <code class="function">aminsert</code>.
+ For each row for which false is returned, a deferred recheck will
+ be scheduled.
+ </p><p>
+ The access method must identify any rows which might violate the
+ unique constraint, but it is not an error for it to report false
+ positives. This allows the check to be done without waiting for other
+ transactions to finish; conflicts reported here are not treated as
+ errors and will be rechecked later, by which time they may no longer
+ be conflicts.
+ </p></li><li class="listitem"><p>
+ <code class="literal">UNIQUE_CHECK_EXISTING</code> indicates that this is a deferred
+ recheck of a row that was reported as a potential uniqueness violation.
+ Although this is implemented by calling <code class="function">aminsert</code>, the
+ access method must <span class="emphasis"><em>not</em></span> insert a new index entry in this
+ case. The index entry is already present. Rather, the access method
+ must check to see if there is another live index entry. If so, and
+ if the target row is also still live, report error.
+ </p><p>
+ It is recommended that in a <code class="literal">UNIQUE_CHECK_EXISTING</code> call,
+ the access method further verify that the target row actually does
+ have an existing entry in the index, and report error if not. This
+ is a good idea because the index tuple values passed to
+ <code class="function">aminsert</code> will have been recomputed. If the index
+ definition involves functions that are not really immutable, we
+ might be checking the wrong area of the index. Checking that the
+ target row is found in the recheck verifies that we are scanning
+ for the same tuple values as were used in the original insertion.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index-locking.html" title="64.4. Index Locking Considerations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-cost-estimation.html" title="64.6. Index Cost Estimation Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">64.4. Index Locking Considerations </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 64.6. Index Cost Estimation Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/index.html b/doc/src/sgml/html/index.html
new file mode 100644
index 0000000..836495e
--- /dev/null
+++ b/doc/src/sgml/html/index.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PostgreSQL 15.4 Documentation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="next" href="preface.html" title="Preface" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">PostgreSQL 15.4 Documentation</th></tr><tr><td width="10%" align="left"> </td><td width="10%" align="left"> </td><th width="60%" align="center"> </th><td width="10%" align="right"> </td><td width="10%" align="right"> <a accesskey="n" href="preface.html" title="Preface">Next</a></td></tr></table><hr /></div><div class="book" id="POSTGRES"><div class="titlepage"><div><div><h1 class="title">PostgreSQL 15.4 Documentation</h1></div><div><h3 class="corpauthor">The PostgreSQL Global Development Group</h3></div><div><p class="copyright">Copyright © 1996–2023 The PostgreSQL Global Development Group</p></div><div><a href="legalnotice.html">Legal Notice</a></div></div><hr /></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="preface"><a href="preface.html">Preface</a></span></dt><dd><dl><dt><span class="sect1"><a href="intro-whatis.html">1. What Is <span class="productname">PostgreSQL</span>?</a></span></dt><dt><span class="sect1"><a href="history.html">2. A Brief History of <span class="productname">PostgreSQL</span></a></span></dt><dt><span class="sect1"><a href="notation.html">3. Conventions</a></span></dt><dt><span class="sect1"><a href="resources.html">4. Further Information</a></span></dt><dt><span class="sect1"><a href="bug-reporting.html">5. Bug Reporting Guidelines</a></span></dt></dl></dd><dt><span class="part"><a href="tutorial.html">I. Tutorial</a></span></dt><dd><dl><dt><span class="chapter"><a href="tutorial-start.html">1. Getting Started</a></span></dt><dt><span class="chapter"><a href="tutorial-sql.html">2. The <acronym class="acronym">SQL</acronym> Language</a></span></dt><dt><span class="chapter"><a href="tutorial-advanced.html">3. Advanced Features</a></span></dt></dl></dd><dt><span class="part"><a href="sql.html">II. The SQL Language</a></span></dt><dd><dl><dt><span class="chapter"><a href="sql-syntax.html">4. SQL Syntax</a></span></dt><dt><span class="chapter"><a href="ddl.html">5. Data Definition</a></span></dt><dt><span class="chapter"><a href="dml.html">6. Data Manipulation</a></span></dt><dt><span class="chapter"><a href="queries.html">7. Queries</a></span></dt><dt><span class="chapter"><a href="datatype.html">8. Data Types</a></span></dt><dt><span class="chapter"><a href="functions.html">9. Functions and Operators</a></span></dt><dt><span class="chapter"><a href="typeconv.html">10. Type Conversion</a></span></dt><dt><span class="chapter"><a href="indexes.html">11. Indexes</a></span></dt><dt><span class="chapter"><a href="textsearch.html">12. Full Text Search</a></span></dt><dt><span class="chapter"><a href="mvcc.html">13. Concurrency Control</a></span></dt><dt><span class="chapter"><a href="performance-tips.html">14. Performance Tips</a></span></dt><dt><span class="chapter"><a href="parallel-query.html">15. Parallel Query</a></span></dt></dl></dd><dt><span class="part"><a href="admin.html">III. Server Administration</a></span></dt><dd><dl><dt><span class="chapter"><a href="install-binaries.html">16. Installation from Binaries</a></span></dt><dt><span class="chapter"><a href="installation.html">17. Installation from Source Code</a></span></dt><dt><span class="chapter"><a href="install-windows.html">18. Installation from Source Code on <span class="productname">Windows</span></a></span></dt><dt><span class="chapter"><a href="runtime.html">19. Server Setup and Operation</a></span></dt><dt><span class="chapter"><a href="runtime-config.html">20. Server Configuration</a></span></dt><dt><span class="chapter"><a href="client-authentication.html">21. Client Authentication</a></span></dt><dt><span class="chapter"><a href="user-manag.html">22. Database Roles</a></span></dt><dt><span class="chapter"><a href="managing-databases.html">23. Managing Databases</a></span></dt><dt><span class="chapter"><a href="charset.html">24. Localization</a></span></dt><dt><span class="chapter"><a href="maintenance.html">25. Routine Database Maintenance Tasks</a></span></dt><dt><span class="chapter"><a href="backup.html">26. Backup and Restore</a></span></dt><dt><span class="chapter"><a href="high-availability.html">27. High Availability, Load Balancing, and Replication</a></span></dt><dt><span class="chapter"><a href="monitoring.html">28. Monitoring Database Activity</a></span></dt><dt><span class="chapter"><a href="diskusage.html">29. Monitoring Disk Usage</a></span></dt><dt><span class="chapter"><a href="wal.html">30. Reliability and the Write-Ahead Log</a></span></dt><dt><span class="chapter"><a href="logical-replication.html">31. Logical Replication</a></span></dt><dt><span class="chapter"><a href="jit.html">32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</a></span></dt><dt><span class="chapter"><a href="regress.html">33. Regression Tests</a></span></dt></dl></dd><dt><span class="part"><a href="client-interfaces.html">IV. Client Interfaces</a></span></dt><dd><dl><dt><span class="chapter"><a href="libpq.html">34. <span class="application">libpq</span> — C Library</a></span></dt><dt><span class="chapter"><a href="largeobjects.html">35. Large Objects</a></span></dt><dt><span class="chapter"><a href="ecpg.html">36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</a></span></dt><dt><span class="chapter"><a href="information-schema.html">37. The Information Schema</a></span></dt></dl></dd><dt><span class="part"><a href="server-programming.html">V. Server Programming</a></span></dt><dd><dl><dt><span class="chapter"><a href="extend.html">38. Extending <acronym class="acronym">SQL</acronym></a></span></dt><dt><span class="chapter"><a href="triggers.html">39. Triggers</a></span></dt><dt><span class="chapter"><a href="event-triggers.html">40. Event Triggers</a></span></dt><dt><span class="chapter"><a href="rules.html">41. The Rule System</a></span></dt><dt><span class="chapter"><a href="xplang.html">42. Procedural Languages</a></span></dt><dt><span class="chapter"><a href="plpgsql.html">43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</a></span></dt><dt><span class="chapter"><a href="pltcl.html">44. PL/Tcl — Tcl Procedural Language</a></span></dt><dt><span class="chapter"><a href="plperl.html">45. PL/Perl — Perl Procedural Language</a></span></dt><dt><span class="chapter"><a href="plpython.html">46. PL/Python — Python Procedural Language</a></span></dt><dt><span class="chapter"><a href="spi.html">47. Server Programming Interface</a></span></dt><dt><span class="chapter"><a href="bgworker.html">48. Background Worker Processes</a></span></dt><dt><span class="chapter"><a href="logicaldecoding.html">49. Logical Decoding</a></span></dt><dt><span class="chapter"><a href="replication-origins.html">50. Replication Progress Tracking</a></span></dt><dt><span class="chapter"><a href="archive-modules.html">51. Archive Modules</a></span></dt></dl></dd><dt><span class="part"><a href="reference.html">VI. Reference</a></span></dt><dd><dl><dt><span class="reference"><a href="sql-commands.html">I. SQL Commands</a></span></dt><dt><span class="reference"><a href="reference-client.html">II. PostgreSQL Client Applications</a></span></dt><dt><span class="reference"><a href="reference-server.html">III. PostgreSQL Server Applications</a></span></dt></dl></dd><dt><span class="part"><a href="internals.html">VII. Internals</a></span></dt><dd><dl><dt><span class="chapter"><a href="overview.html">52. Overview of PostgreSQL Internals</a></span></dt><dt><span class="chapter"><a href="catalogs.html">53. System Catalogs</a></span></dt><dt><span class="chapter"><a href="views.html">54. System Views</a></span></dt><dt><span class="chapter"><a href="protocol.html">55. Frontend/Backend Protocol</a></span></dt><dt><span class="chapter"><a href="source.html">56. PostgreSQL Coding Conventions</a></span></dt><dt><span class="chapter"><a href="nls.html">57. Native Language Support</a></span></dt><dt><span class="chapter"><a href="plhandler.html">58. Writing a Procedural Language Handler</a></span></dt><dt><span class="chapter"><a href="fdwhandler.html">59. Writing a Foreign Data Wrapper</a></span></dt><dt><span class="chapter"><a href="tablesample-method.html">60. Writing a Table Sampling Method</a></span></dt><dt><span class="chapter"><a href="custom-scan.html">61. Writing a Custom Scan Provider</a></span></dt><dt><span class="chapter"><a href="geqo.html">62. Genetic Query Optimizer</a></span></dt><dt><span class="chapter"><a href="tableam.html">63. Table Access Method Interface Definition</a></span></dt><dt><span class="chapter"><a href="indexam.html">64. Index Access Method Interface Definition</a></span></dt><dt><span class="chapter"><a href="generic-wal.html">65. Generic WAL Records</a></span></dt><dt><span class="chapter"><a href="custom-rmgr.html">66. Custom WAL Resource Managers</a></span></dt><dt><span class="chapter"><a href="btree.html">67. B-Tree Indexes</a></span></dt><dt><span class="chapter"><a href="gist.html">68. GiST Indexes</a></span></dt><dt><span class="chapter"><a href="spgist.html">69. SP-GiST Indexes</a></span></dt><dt><span class="chapter"><a href="gin.html">70. GIN Indexes</a></span></dt><dt><span class="chapter"><a href="brin.html">71. BRIN Indexes</a></span></dt><dt><span class="chapter"><a href="hash-index.html">72. Hash Indexes</a></span></dt><dt><span class="chapter"><a href="storage.html">73. Database Physical Storage</a></span></dt><dt><span class="chapter"><a href="bki.html">74. System Catalog Declarations and Initial Contents</a></span></dt><dt><span class="chapter"><a href="planner-stats-details.html">75. How the Planner Uses Statistics</a></span></dt><dt><span class="chapter"><a href="backup-manifest-format.html">76. Backup Manifest Format</a></span></dt></dl></dd><dt><span class="part"><a href="appendixes.html">VIII. Appendixes</a></span></dt><dd><dl><dt><span class="appendix"><a href="errcodes-appendix.html">A. <span class="productname">PostgreSQL</span> Error Codes</a></span></dt><dt><span class="appendix"><a href="datetime-appendix.html">B. Date/Time Support</a></span></dt><dt><span class="appendix"><a href="sql-keywords-appendix.html">C. <acronym class="acronym">SQL</acronym> Key Words</a></span></dt><dt><span class="appendix"><a href="features.html">D. SQL Conformance</a></span></dt><dt><span class="appendix"><a href="release.html">E. Release Notes</a></span></dt><dt><span class="appendix"><a href="contrib.html">F. Additional Supplied Modules</a></span></dt><dt><span class="appendix"><a href="contrib-prog.html">G. Additional Supplied Programs</a></span></dt><dt><span class="appendix"><a href="external-projects.html">H. External Projects</a></span></dt><dt><span class="appendix"><a href="sourcerepo.html">I. The Source Code Repository</a></span></dt><dt><span class="appendix"><a href="docguide.html">J. Documentation</a></span></dt><dt><span class="appendix"><a href="limits.html">K. <span class="productname">PostgreSQL</span> Limits</a></span></dt><dt><span class="appendix"><a href="acronyms.html">L. Acronyms</a></span></dt><dt><span class="appendix"><a href="glossary.html">M. Glossary</a></span></dt><dt><span class="appendix"><a href="color.html">N. Color Support</a></span></dt><dt><span class="appendix"><a href="appendix-obsolete.html">O. Obsolete or Renamed Features</a></span></dt></dl></dd><dt><span class="bibliography"><a href="biblio.html">Bibliography</a></span></dt><dt><span class="index"><a href="bookindex.html">Index</a></span></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="preface.html" title="Preface">Next</a></td></tr><tr><td width="40%" align="left" valign="top"> </td><td width="20%" align="center"> </td><td width="40%" align="right" valign="top"> Preface</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexam.html b/doc/src/sgml/html/indexam.html
new file mode 100644
index 0000000..0da8eaf
--- /dev/null
+++ b/doc/src/sgml/html/indexam.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 64. Index Access Method Interface Definition</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition" /><link rel="next" href="index-api.html" title="64.1. Basic API Structure for Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 64. Index Access Method Interface Definition</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="index-api.html" title="64.1. Basic API Structure for Indexes">Next</a></td></tr></table><hr /></div><div class="chapter" id="INDEXAM"><div class="titlepage"><div><div><h2 class="title">Chapter 64. Index Access Method Interface Definition</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="index-api.html">64.1. Basic API Structure for Indexes</a></span></dt><dt><span class="sect1"><a href="index-functions.html">64.2. Index Access Method Functions</a></span></dt><dt><span class="sect1"><a href="index-scanning.html">64.3. Index Scanning</a></span></dt><dt><span class="sect1"><a href="index-locking.html">64.4. Index Locking Considerations</a></span></dt><dt><span class="sect1"><a href="index-unique-checks.html">64.5. Index Uniqueness Checks</a></span></dt><dt><span class="sect1"><a href="index-cost-estimation.html">64.6. Index Cost Estimation Functions</a></span></dt></dl></div><a id="id-1.10.15.2" class="indexterm"></a><a id="id-1.10.15.3" class="indexterm"></a><p>
+ This chapter defines the interface between the core
+ <span class="productname">PostgreSQL</span> system and <em class="firstterm">index access
+ methods</em>, which manage individual index types. The core system
+ knows nothing about indexes beyond what is specified here, so it is
+ possible to develop entirely new index types by writing add-on code.
+ </p><p>
+ All indexes in <span class="productname">PostgreSQL</span> are what are known
+ technically as <em class="firstterm">secondary indexes</em>; that is, the index is
+ physically separate from the table file that it describes. Each index
+ is stored as its own physical <em class="firstterm">relation</em> and so is described
+ by an entry in the <code class="structname">pg_class</code> catalog. The contents of an
+ index are entirely under the control of its index access method. In
+ practice, all index access methods divide indexes into standard-size
+ pages so that they can use the regular storage manager and buffer manager
+ to access the index contents. (All the existing index access methods
+ furthermore use the standard page layout described in <a class="xref" href="storage-page-layout.html" title="73.6. Database Page Layout">Section 73.6</a>, and most use the same format for index
+ tuple headers; but these decisions are not forced on an access method.)
+ </p><p>
+ An index is effectively a mapping from some data key values to
+ <em class="firstterm">tuple identifiers</em>, or <acronym class="acronym">TIDs</acronym>, of row versions
+ (tuples) in the index's parent table. A TID consists of a
+ block number and an item number within that block (see <a class="xref" href="storage-page-layout.html" title="73.6. Database Page Layout">Section 73.6</a>). This is sufficient
+ information to fetch a particular row version from the table.
+ Indexes are not directly aware that under MVCC, there might be multiple
+ extant versions of the same logical row; to an index, each tuple is
+ an independent object that needs its own index entry. Thus, an
+ update of a row always creates all-new index entries for the row, even if
+ the key values did not change. (<a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">HOT
+ tuples</a> are an exception to this
+ statement; but indexes do not deal with those, either.) Index entries for
+ dead tuples are reclaimed (by vacuuming) when the dead tuples themselves
+ are reclaimed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="index-api.html" title="64.1. Basic API Structure for Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 63. Table Access Method Interface Definition </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 64.1. Basic API Structure for Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-bitmap-scans.html b/doc/src/sgml/html/indexes-bitmap-scans.html
new file mode 100644
index 0000000..a705d42
--- /dev/null
+++ b/doc/src/sgml/html/indexes-bitmap-scans.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.5. Combining Multiple Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-ordering.html" title="11.4. Indexes and ORDER BY" /><link rel="next" href="indexes-unique.html" title="11.6. Unique Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.5. Combining Multiple Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-ordering.html" title="11.4. Indexes and ORDER BY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-unique.html" title="11.6. Unique Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-BITMAP-SCANS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.5. Combining Multiple Indexes</h2></div></div></div><a id="id-1.5.10.8.2" class="indexterm"></a><a id="id-1.5.10.8.3" class="indexterm"></a><p>
+ A single index scan can only use query clauses that use the index's
+ columns with operators of its operator class and are joined with
+ <code class="literal">AND</code>. For example, given an index on <code class="literal">(a, b)</code>
+ a query condition like <code class="literal">WHERE a = 5 AND b = 6</code> could
+ use the index, but a query like <code class="literal">WHERE a = 5 OR b = 6</code> could not
+ directly use the index.
+ </p><p>
+ Fortunately,
+ <span class="productname">PostgreSQL</span> has the ability to combine multiple indexes
+ (including multiple uses of the same index) to handle cases that cannot
+ be implemented by single index scans. The system can form <code class="literal">AND</code>
+ and <code class="literal">OR</code> conditions across several index scans. For example,
+ a query like <code class="literal">WHERE x = 42 OR x = 47 OR x = 53 OR x = 99</code>
+ could be broken down into four separate scans of an index on <code class="literal">x</code>,
+ each scan using one of the query clauses. The results of these scans are
+ then ORed together to produce the result. Another example is that if we
+ have separate indexes on <code class="literal">x</code> and <code class="literal">y</code>, one possible
+ implementation of a query like <code class="literal">WHERE x = 5 AND y = 6</code> is to
+ use each index with the appropriate query clause and then AND together
+ the index results to identify the result rows.
+ </p><p>
+ To combine multiple indexes, the system scans each needed index and
+ prepares a <em class="firstterm">bitmap</em> in memory giving the locations of
+ table rows that are reported as matching that index's conditions.
+ The bitmaps are then ANDed and ORed together as needed by the query.
+ Finally, the actual table rows are visited and returned. The table rows
+ are visited in physical order, because that is how the bitmap is laid
+ out; this means that any ordering of the original indexes is lost, and
+ so a separate sort step will be needed if the query has an <code class="literal">ORDER
+ BY</code> clause. For this reason, and because each additional index scan
+ adds extra time, the planner will sometimes choose to use a simple index
+ scan even though additional indexes are available that could have been
+ used as well.
+ </p><p>
+ In all but the simplest applications, there are various combinations of
+ indexes that might be useful, and the database developer must make
+ trade-offs to decide which indexes to provide. Sometimes multicolumn
+ indexes are best, but sometimes it's better to create separate indexes
+ and rely on the index-combination feature. For example, if your
+ workload includes a mix of queries that sometimes involve only column
+ <code class="literal">x</code>, sometimes only column <code class="literal">y</code>, and sometimes both
+ columns, you might choose to create two separate indexes on
+ <code class="literal">x</code> and <code class="literal">y</code>, relying on index combination to
+ process the queries that use both columns. You could also create a
+ multicolumn index on <code class="literal">(x, y)</code>. This index would typically be
+ more efficient than index combination for queries involving both
+ columns, but as discussed in <a class="xref" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Section 11.3</a>, it
+ would be almost useless for queries involving only <code class="literal">y</code>, so it
+ should not be the only index. A combination of the multicolumn index
+ and a separate index on <code class="literal">y</code> would serve reasonably well. For
+ queries involving only <code class="literal">x</code>, the multicolumn index could be
+ used, though it would be larger and hence slower than an index on
+ <code class="literal">x</code> alone. The last alternative is to create all three
+ indexes, but this is probably only reasonable if the table is searched
+ much more often than it is updated and all three types of query are
+ common. If one of the types of query is much less common than the
+ others, you'd probably settle for creating just the two indexes that
+ best match the common types.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-ordering.html" title="11.4. Indexes and ORDER BY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-unique.html" title="11.6. Unique Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.4. Indexes and <code class="literal">ORDER BY</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.6. Unique Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-collations.html b/doc/src/sgml/html/indexes-collations.html
new file mode 100644
index 0000000..fc6df20
--- /dev/null
+++ b/doc/src/sgml/html/indexes-collations.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.11. Indexes and Collations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families" /><link rel="next" href="indexes-examine.html" title="11.12. Examining Index Usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.11. Indexes and Collations</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-examine.html" title="11.12. Examining Index Usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-COLLATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.11. Indexes and Collations</h2></div></div></div><p>
+ An index can support only one collation per index column.
+ If multiple collations are of interest, multiple indexes may be needed.
+ </p><p>
+ Consider these statements:
+</p><pre class="programlisting">
+CREATE TABLE test1c (
+ id integer,
+ content varchar COLLATE "x"
+);
+
+CREATE INDEX test1c_content_index ON test1c (content);
+</pre><p>
+ The index automatically uses the collation of the
+ underlying column. So a query of the form
+</p><pre class="programlisting">
+SELECT * FROM test1c WHERE content &gt; <em class="replaceable"><code>constant</code></em>;
+</pre><p>
+ could use the index, because the comparison will by default use the
+ collation of the column. However, this index cannot accelerate queries
+ that involve some other collation. So if queries of the form, say,
+</p><pre class="programlisting">
+SELECT * FROM test1c WHERE content &gt; <em class="replaceable"><code>constant</code></em> COLLATE "y";
+</pre><p>
+ are also of interest, an additional index could be created that supports
+ the <code class="literal">"y"</code> collation, like this:
+</p><pre class="programlisting">
+CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-examine.html" title="11.12. Examining Index Usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.10. Operator Classes and Operator Families </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.12. Examining Index Usage</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-examine.html b/doc/src/sgml/html/indexes-examine.html
new file mode 100644
index 0000000..2f0a2f9
--- /dev/null
+++ b/doc/src/sgml/html/indexes-examine.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.12. Examining Index Usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-collations.html" title="11.11. Indexes and Collations" /><link rel="next" href="textsearch.html" title="Chapter 12. Full Text Search" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.12. Examining Index Usage</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-collations.html" title="11.11. Indexes and Collations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch.html" title="Chapter 12. Full Text Search">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-EXAMINE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.12. Examining Index Usage</h2></div></div></div><a id="id-1.5.10.15.2" class="indexterm"></a><p>
+ Although indexes in <span class="productname">PostgreSQL</span> do not need
+ maintenance or tuning, it is still important to check
+ which indexes are actually used by the real-life query workload.
+ Examining index usage for an individual query is done with the
+ <a class="xref" href="sql-explain.html" title="EXPLAIN"><span class="refentrytitle">EXPLAIN</span></a>
+ command; its application for this purpose is
+ illustrated in <a class="xref" href="using-explain.html" title="14.1. Using EXPLAIN">Section 14.1</a>.
+ It is also possible to gather overall statistics about index usage
+ in a running server, as described in <a class="xref" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">Section 28.2</a>.
+ </p><p>
+ It is difficult to formulate a general procedure for determining
+ which indexes to create. There are a number of typical cases that
+ have been shown in the examples throughout the previous sections.
+ A good deal of experimentation is often necessary.
+ The rest of this section gives some tips for that:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Always run <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a>
+ first. This command
+ collects statistics about the distribution of the values in the
+ table. This information is required to estimate the number of rows
+ returned by a query, which is needed by the planner to assign
+ realistic costs to each possible query plan. In absence of any
+ real statistics, some default values are assumed, which are
+ almost certain to be inaccurate. Examining an application's
+ index usage without having run <code class="command">ANALYZE</code> is
+ therefore a lost cause.
+ See <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a>
+ and <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ </p></li><li class="listitem"><p>
+ Use real data for experimentation. Using test data for setting
+ up indexes will tell you what indexes you need for the test data,
+ but that is all.
+ </p><p>
+ It is especially fatal to use very small test data sets.
+ While selecting 1000 out of 100000 rows could be a candidate for
+ an index, selecting 1 out of 100 rows will hardly be, because the
+ 100 rows probably fit within a single disk page, and there
+ is no plan that can beat sequentially fetching 1 disk page.
+ </p><p>
+ Also be careful when making up test data, which is often
+ unavoidable when the application is not yet in production.
+ Values that are very similar, completely random, or inserted in
+ sorted order will skew the statistics away from the distribution
+ that real data would have.
+ </p></li><li class="listitem"><p>
+ When indexes are not used, it can be useful for testing to force
+ their use. There are run-time parameters that can turn off
+ various plan types (see <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE" title="20.7.1. Planner Method Configuration">Section 20.7.1</a>).
+ For instance, turning off sequential scans
+ (<code class="varname">enable_seqscan</code>) and nested-loop joins
+ (<code class="varname">enable_nestloop</code>), which are the most basic plans,
+ will force the system to use a different plan. If the system
+ still chooses a sequential scan or nested-loop join then there is
+ probably a more fundamental reason why the index is not being
+ used; for example, the query condition does not match the index.
+ (What kind of query can use what kind of index is explained in
+ the previous sections.)
+ </p></li><li class="listitem"><p>
+ If forcing index usage does use the index, then there are two
+ possibilities: Either the system is right and using the index is
+ indeed not appropriate, or the cost estimates of the query plans
+ are not reflecting reality. So you should time your query with
+ and without indexes. The <code class="command">EXPLAIN ANALYZE</code>
+ command can be useful here.
+ </p></li><li class="listitem"><p>
+ If it turns out that the cost estimates are wrong, there are,
+ again, two possibilities. The total cost is computed from the
+ per-row costs of each plan node times the selectivity estimate of
+ the plan node. The costs estimated for the plan nodes can be adjusted
+ via run-time parameters (described in <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS" title="20.7.2. Planner Cost Constants">Section 20.7.2</a>).
+ An inaccurate selectivity estimate is due to
+ insufficient statistics. It might be possible to improve this by
+ tuning the statistics-gathering parameters (see
+ <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>).
+ </p><p>
+ If you do not succeed in adjusting the costs to be more
+ appropriate, then you might have to resort to forcing index usage
+ explicitly. You might also want to contact the
+ <span class="productname">PostgreSQL</span> developers to examine the issue.
+ </p></li></ul></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-collations.html" title="11.11. Indexes and Collations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch.html" title="Chapter 12. Full Text Search">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.11. Indexes and Collations </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 12. Full Text Search</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-expressional.html b/doc/src/sgml/html/indexes-expressional.html
new file mode 100644
index 0000000..f1bb5af
--- /dev/null
+++ b/doc/src/sgml/html/indexes-expressional.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.7. Indexes on Expressions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-unique.html" title="11.6. Unique Indexes" /><link rel="next" href="indexes-partial.html" title="11.8. Partial Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.7. Indexes on Expressions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-unique.html" title="11.6. Unique Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-partial.html" title="11.8. Partial Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-EXPRESSIONAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.7. Indexes on Expressions</h2></div></div></div><a id="id-1.5.10.10.2" class="indexterm"></a><p>
+ An index column need not be just a column of the underlying table,
+ but can be a function or scalar expression computed from one or
+ more columns of the table. This feature is useful to obtain fast
+ access to tables based on the results of computations.
+ </p><p>
+ For example, a common way to do case-insensitive comparisons is to
+ use the <code class="function">lower</code> function:
+</p><pre class="programlisting">
+SELECT * FROM test1 WHERE lower(col1) = 'value';
+</pre><p>
+ This query can use an index if one has been
+ defined on the result of the <code class="literal">lower(col1)</code>
+ function:
+</p><pre class="programlisting">
+CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
+</pre><p>
+ </p><p>
+ If we were to declare this index <code class="literal">UNIQUE</code>, it would prevent
+ creation of rows whose <code class="literal">col1</code> values differ only in case,
+ as well as rows whose <code class="literal">col1</code> values are actually identical.
+ Thus, indexes on expressions can be used to enforce constraints that
+ are not definable as simple unique constraints.
+ </p><p>
+ As another example, if one often does queries like:
+</p><pre class="programlisting">
+SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';
+</pre><p>
+ then it might be worth creating an index like this:
+</p><pre class="programlisting">
+CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
+</pre><p>
+ </p><p>
+ The syntax of the <code class="command">CREATE INDEX</code> command normally requires
+ writing parentheses around index expressions, as shown in the second
+ example. The parentheses can be omitted when the expression is just
+ a function call, as in the first example.
+ </p><p>
+ Index expressions are relatively expensive to maintain, because the
+ derived expression(s) must be computed for each row insertion
+ and <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">non-HOT update.</a> However, the index expressions are
+ <span class="emphasis"><em>not</em></span> recomputed during an indexed search, since they are
+ already stored in the index. In both examples above, the system
+ sees the query as just <code class="literal">WHERE indexedcolumn = 'constant'</code>
+ and so the speed of the search is equivalent to any other simple index
+ query. Thus, indexes on expressions are useful when retrieval speed
+ is more important than insertion and update speed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-unique.html" title="11.6. Unique Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-partial.html" title="11.8. Partial Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.6. Unique Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.8. Partial Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-index-only-scans.html b/doc/src/sgml/html/indexes-index-only-scans.html
new file mode 100644
index 0000000..921f101
--- /dev/null
+++ b/doc/src/sgml/html/indexes-index-only-scans.html
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.9. Index-Only Scans and Covering Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-partial.html" title="11.8. Partial Indexes" /><link rel="next" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.9. Index-Only Scans and Covering Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-partial.html" title="11.8. Partial Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-INDEX-ONLY-SCANS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.9. Index-Only Scans and Covering Indexes</h2></div></div></div><a id="id-1.5.10.12.2" class="indexterm"></a><a id="id-1.5.10.12.3" class="indexterm"></a><a id="id-1.5.10.12.4" class="indexterm"></a><a id="id-1.5.10.12.5" class="indexterm"></a><p>
+ All indexes in <span class="productname">PostgreSQL</span>
+ are <em class="firstterm">secondary</em> indexes, meaning that each index is
+ stored separately from the table's main data area (which is called the
+ table's <em class="firstterm">heap</em>
+ in <span class="productname">PostgreSQL</span> terminology). This means that
+ in an ordinary index scan, each row retrieval requires fetching data from
+ both the index and the heap. Furthermore, while the index entries that
+ match a given indexable <code class="literal">WHERE</code> condition are usually
+ close together in the index, the table rows they reference might be
+ anywhere in the heap. The heap-access portion of an index scan thus
+ involves a lot of random access into the heap, which can be slow,
+ particularly on traditional rotating media. (As described in
+ <a class="xref" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes">Section 11.5</a>, bitmap scans try to alleviate
+ this cost by doing the heap accesses in sorted order, but that only goes
+ so far.)
+ </p><p>
+ To solve this performance problem, <span class="productname">PostgreSQL</span>
+ supports <em class="firstterm">index-only scans</em>, which can answer
+ queries from an index alone without any heap access. The basic idea is
+ to return values directly out of each index entry instead of consulting
+ the associated heap entry. There are two fundamental restrictions on
+ when this method can be used:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ The index type must support index-only scans. B-tree indexes always
+ do. GiST and SP-GiST indexes support index-only scans for some
+ operator classes but not others. Other index types have no support.
+ The underlying requirement is that the index must physically store, or
+ else be able to reconstruct, the original data value for each index
+ entry. As a counterexample, GIN indexes cannot support index-only
+ scans because each index entry typically holds only part of the
+ original data value.
+ </p></li><li class="listitem"><p>
+ The query must reference only columns stored in the index. For
+ example, given an index on columns <code class="literal">x</code>
+ and <code class="literal">y</code> of a table that also has a
+ column <code class="literal">z</code>, these queries could use index-only scans:
+</p><pre class="programlisting">
+SELECT x, y FROM tab WHERE x = 'key';
+SELECT x FROM tab WHERE x = 'key' AND y &lt; 42;
+</pre><p>
+ but these queries could not:
+</p><pre class="programlisting">
+SELECT x, z FROM tab WHERE x = 'key';
+SELECT x FROM tab WHERE x = 'key' AND z &lt; 42;
+</pre><p>
+ (Expression indexes and partial indexes complicate this rule,
+ as discussed below.)
+ </p></li></ol></div><p>
+ </p><p>
+ If these two fundamental requirements are met, then all the data values
+ required by the query are available from the index, so an index-only scan
+ is physically possible. But there is an additional requirement for any
+ table scan in <span class="productname">PostgreSQL</span>: it must verify that
+ each retrieved row be <span class="quote">“<span class="quote">visible</span>”</span> to the query's MVCC
+ snapshot, as discussed in <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>. Visibility information
+ is not stored in index entries, only in heap entries; so at first glance
+ it would seem that every row retrieval would require a heap access
+ anyway. And this is indeed the case, if the table row has been modified
+ recently. However, for seldom-changing data there is a way around this
+ problem. <span class="productname">PostgreSQL</span> tracks, for each page in
+ a table's heap, whether all rows stored in that page are old enough to be
+ visible to all current and future transactions. This information is
+ stored in a bit in the table's <em class="firstterm">visibility map</em>. An
+ index-only scan, after finding a candidate index entry, checks the
+ visibility map bit for the corresponding heap page. If it's set, the row
+ is known visible and so the data can be returned with no further work.
+ If it's not set, the heap entry must be visited to find out whether it's
+ visible, so no performance advantage is gained over a standard index
+ scan. Even in the successful case, this approach trades visibility map
+ accesses for heap accesses; but since the visibility map is four orders
+ of magnitude smaller than the heap it describes, far less physical I/O is
+ needed to access it. In most situations the visibility map remains
+ cached in memory all the time.
+ </p><p>
+ In short, while an index-only scan is possible given the two fundamental
+ requirements, it will be a win only if a significant fraction of the
+ table's heap pages have their all-visible map bits set. But tables in
+ which a large fraction of the rows are unchanging are common enough to
+ make this type of scan very useful in practice.
+ </p><p>
+ <a id="id-1.5.10.12.10.1" class="indexterm"></a>
+ To make effective use of the index-only scan feature, you might choose to
+ create a <em class="firstterm">covering index</em>, which is an index
+ specifically designed to include the columns needed by a particular
+ type of query that you run frequently. Since queries typically need to
+ retrieve more columns than just the ones they search
+ on, <span class="productname">PostgreSQL</span> allows you to create an index
+ in which some columns are just <span class="quote">“<span class="quote">payload</span>”</span> and are not part
+ of the search key. This is done by adding an <code class="literal">INCLUDE</code>
+ clause listing the extra columns. For example, if you commonly run
+ queries like
+</p><pre class="programlisting">
+SELECT y FROM tab WHERE x = 'key';
+</pre><p>
+ the traditional approach to speeding up such queries would be to create
+ an index on <code class="literal">x</code> only. However, an index defined as
+</p><pre class="programlisting">
+CREATE INDEX tab_x_y ON tab(x) INCLUDE (y);
+</pre><p>
+ could handle these queries as index-only scans,
+ because <code class="literal">y</code> can be obtained from the index without
+ visiting the heap.
+ </p><p>
+ Because column <code class="literal">y</code> is not part of the index's search
+ key, it does not have to be of a data type that the index can handle;
+ it's merely stored in the index and is not interpreted by the index
+ machinery. Also, if the index is a unique index, that is
+</p><pre class="programlisting">
+CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y);
+</pre><p>
+ the uniqueness condition applies to just column <code class="literal">x</code>,
+ not to the combination of <code class="literal">x</code> and <code class="literal">y</code>.
+ (An <code class="literal">INCLUDE</code> clause can also be written
+ in <code class="literal">UNIQUE</code> and <code class="literal">PRIMARY KEY</code>
+ constraints, providing alternative syntax for setting up an index like
+ this.)
+ </p><p>
+ It's wise to be conservative about adding non-key payload columns to an
+ index, especially wide columns. If an index tuple exceeds the
+ maximum size allowed for the index type, data insertion will fail.
+ In any case, non-key columns duplicate data from the index's table
+ and bloat the size of the index, thus potentially slowing searches.
+ And remember that there is little point in including payload columns in an
+ index unless the table changes slowly enough that an index-only scan is
+ likely to not need to access the heap. If the heap tuple must be visited
+ anyway, it costs nothing more to get the column's value from there.
+ Other restrictions are that expressions are not currently supported as
+ included columns, and that only B-tree, GiST and SP-GiST indexes currently
+ support included columns.
+ </p><p>
+ Before <span class="productname">PostgreSQL</span> had
+ the <code class="literal">INCLUDE</code> feature, people sometimes made covering
+ indexes by writing the payload columns as ordinary index columns,
+ that is writing
+</p><pre class="programlisting">
+CREATE INDEX tab_x_y ON tab(x, y);
+</pre><p>
+ even though they had no intention of ever using <code class="literal">y</code> as
+ part of a <code class="literal">WHERE</code> clause. This works fine as long as
+ the extra columns are trailing columns; making them be leading columns is
+ unwise for the reasons explained in <a class="xref" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Section 11.3</a>.
+ However, this method doesn't support the case where you want the index to
+ enforce uniqueness on the key column(s).
+ </p><p>
+ <em class="firstterm">Suffix truncation</em> always removes non-key
+ columns from upper B-Tree levels. As payload columns, they are
+ never used to guide index scans. The truncation process also
+ removes one or more trailing key column(s) when the remaining
+ prefix of key column(s) happens to be sufficient to describe tuples
+ on the lowest B-Tree level. In practice, covering indexes without
+ an <code class="literal">INCLUDE</code> clause often avoid storing columns
+ that are effectively payload in the upper levels. However,
+ explicitly defining payload columns as non-key columns
+ <span class="emphasis"><em>reliably</em></span> keeps the tuples in upper levels
+ small.
+ </p><p>
+ In principle, index-only scans can be used with expression indexes.
+ For example, given an index on <code class="literal">f(x)</code>
+ where <code class="literal">x</code> is a table column, it should be possible to
+ execute
+</p><pre class="programlisting">
+SELECT f(x) FROM tab WHERE f(x) &lt; 1;
+</pre><p>
+ as an index-only scan; and this is very attractive
+ if <code class="literal">f()</code> is an expensive-to-compute function.
+ However, <span class="productname">PostgreSQL</span>'s planner is currently not
+ very smart about such cases. It considers a query to be potentially
+ executable by index-only scan only when all <span class="emphasis"><em>columns</em></span>
+ needed by the query are available from the index. In this
+ example, <code class="literal">x</code> is not needed except in the
+ context <code class="literal">f(x)</code>, but the planner does not notice that and
+ concludes that an index-only scan is not possible. If an index-only scan
+ seems sufficiently worthwhile, this can be worked around by
+ adding <code class="literal">x</code> as an included column, for example
+</p><pre class="programlisting">
+CREATE INDEX tab_f_x ON tab (f(x)) INCLUDE (x);
+</pre><p>
+ An additional caveat, if the goal is to avoid
+ recalculating <code class="literal">f(x)</code>, is that the planner won't
+ necessarily match uses of <code class="literal">f(x)</code> that aren't in
+ indexable <code class="literal">WHERE</code> clauses to the index column. It will
+ usually get this right in simple queries such as shown above, but not in
+ queries that involve joins. These deficiencies may be remedied in future
+ versions of <span class="productname">PostgreSQL</span>.
+ </p><p>
+ Partial indexes also have interesting interactions with index-only scans.
+ Consider the partial index shown in <a class="xref" href="indexes-partial.html#INDEXES-PARTIAL-EX3" title="Example 11.3. Setting up a Partial Unique Index">Example 11.3</a>:
+</p><pre class="programlisting">
+CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
+ WHERE success;
+</pre><p>
+ In principle, we could do an index-only scan on this index to satisfy a
+ query like
+</p><pre class="programlisting">
+SELECT target FROM tests WHERE subject = 'some-subject' AND success;
+</pre><p>
+ But there's a problem: the <code class="literal">WHERE</code> clause refers
+ to <code class="literal">success</code> which is not available as a result column
+ of the index. Nonetheless, an index-only scan is possible because the
+ plan does not need to recheck that part of the <code class="literal">WHERE</code>
+ clause at run time: all entries found in the index necessarily
+ have <code class="literal">success = true</code> so this need not be explicitly
+ checked in the plan. <span class="productname">PostgreSQL</span> versions 9.6
+ and later will recognize such cases and allow index-only scans to be
+ generated, but older versions will not.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-partial.html" title="11.8. Partial Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.8. Partial Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.10. Operator Classes and Operator Families</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-intro.html b/doc/src/sgml/html/indexes-intro.html
new file mode 100644
index 0000000..c68c6ba
--- /dev/null
+++ b/doc/src/sgml/html/indexes-intro.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes.html" title="Chapter 11. Indexes" /><link rel="next" href="indexes-types.html" title="11.2. Index Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes.html" title="Chapter 11. Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-types.html" title="11.2. Index Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.1. Introduction</h2></div></div></div><p>
+ Suppose we have a table similar to this:
+</p><pre class="programlisting">
+CREATE TABLE test1 (
+ id integer,
+ content varchar
+);
+</pre><p>
+ and the application issues many queries of the form:
+</p><pre class="programlisting">
+SELECT content FROM test1 WHERE id = <em class="replaceable"><code>constant</code></em>;
+</pre><p>
+ With no advance preparation, the system would have to scan the entire
+ <code class="structname">test1</code> table, row by row, to find all
+ matching entries. If there are many rows in
+ <code class="structname">test1</code> and only a few rows (perhaps zero
+ or one) that would be returned by such a query, this is clearly an
+ inefficient method. But if the system has been instructed to maintain an
+ index on the <code class="structfield">id</code> column, it can use a more
+ efficient method for locating matching rows. For instance, it
+ might only have to walk a few levels deep into a search tree.
+ </p><p>
+ A similar approach is used in most non-fiction books: terms and
+ concepts that are frequently looked up by readers are collected in
+ an alphabetic index at the end of the book. The interested reader
+ can scan the index relatively quickly and flip to the appropriate
+ page(s), rather than having to read the entire book to find the
+ material of interest. Just as it is the task of the author to
+ anticipate the items that readers are likely to look up,
+ it is the task of the database programmer to foresee which indexes
+ will be useful.
+ </p><p>
+ The following command can be used to create an index on the
+ <code class="structfield">id</code> column, as discussed:
+</p><pre class="programlisting">
+CREATE INDEX test1_id_index ON test1 (id);
+</pre><p>
+ The name <code class="structname">test1_id_index</code> can be chosen
+ freely, but you should pick something that enables you to remember
+ later what the index was for.
+ </p><p>
+ To remove an index, use the <code class="command">DROP INDEX</code> command.
+ Indexes can be added to and removed from tables at any time.
+ </p><p>
+ Once an index is created, no further intervention is required: the
+ system will update the index when the table is modified, and it will
+ use the index in queries when it thinks doing so would be more efficient
+ than a sequential table scan. But you might have to run the
+ <code class="command">ANALYZE</code> command regularly to update
+ statistics to allow the query planner to make educated decisions.
+ See <a class="xref" href="performance-tips.html" title="Chapter 14. Performance Tips">Chapter 14</a> for information about
+ how to find out whether an index is used and when and why the
+ planner might choose <span class="emphasis"><em>not</em></span> to use an index.
+ </p><p>
+ Indexes can also benefit <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code> commands with search conditions.
+ Indexes can moreover be used in join searches. Thus,
+ an index defined on a column that is part of a join condition can
+ also significantly speed up queries with joins.
+ </p><p>
+ Creating an index on a large table can take a long time. By default,
+ <span class="productname">PostgreSQL</span> allows reads (<code class="command">SELECT</code> statements) to occur
+ on the table in parallel with index creation, but writes (<code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>) are blocked until the index build is finished.
+ In production environments this is often unacceptable.
+ It is possible to allow writes to occur in parallel with index
+ creation, but there are several caveats to be aware of —
+ for more information see <a class="xref" href="sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY" title="Building Indexes Concurrently">Building Indexes Concurrently</a>.
+ </p><p>
+ After an index is created, the system has to keep it synchronized with the
+ table. This adds overhead to data manipulation operations. Indexes can
+ also prevent the creation of <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">heap-only
+ tuples</a>.
+ Therefore indexes that are seldom or never used in queries
+ should be removed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes.html" title="Chapter 11. Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-types.html" title="11.2. Index Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 11. Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.2. Index Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-multicolumn.html b/doc/src/sgml/html/indexes-multicolumn.html
new file mode 100644
index 0000000..a759814
--- /dev/null
+++ b/doc/src/sgml/html/indexes-multicolumn.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.3. Multicolumn Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-types.html" title="11.2. Index Types" /><link rel="next" href="indexes-ordering.html" title="11.4. Indexes and ORDER BY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.3. Multicolumn Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-types.html" title="11.2. Index Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-ordering.html" title="11.4. Indexes and ORDER BY">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-MULTICOLUMN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.3. Multicolumn Indexes</h2></div></div></div><a id="id-1.5.10.6.2" class="indexterm"></a><p>
+ An index can be defined on more than one column of a table. For example, if
+ you have a table of this form:
+</p><pre class="programlisting">
+CREATE TABLE test2 (
+ major int,
+ minor int,
+ name varchar
+);
+</pre><p>
+ (say, you keep your <code class="filename">/dev</code>
+ directory in a database...) and you frequently issue queries like:
+</p><pre class="programlisting">
+SELECT name FROM test2 WHERE major = <em class="replaceable"><code>constant</code></em> AND minor = <em class="replaceable"><code>constant</code></em>;
+</pre><p>
+ then it might be appropriate to define an index on the columns
+ <code class="structfield">major</code> and
+ <code class="structfield">minor</code> together, e.g.:
+</p><pre class="programlisting">
+CREATE INDEX test2_mm_idx ON test2 (major, minor);
+</pre><p>
+ </p><p>
+ Currently, only the B-tree, GiST, GIN, and BRIN index types support
+ multiple-key-column indexes. Whether there can be multiple key
+ columns is independent of whether <code class="literal">INCLUDE</code> columns
+ can be added to the index. Indexes can have up to 32 columns,
+ including <code class="literal">INCLUDE</code> columns. (This limit can be
+ altered when building <span class="productname">PostgreSQL</span>; see the
+ file <code class="filename">pg_config_manual.h</code>.)
+ </p><p>
+ A multicolumn B-tree index can be used with query conditions that
+ involve any subset of the index's columns, but the index is most
+ efficient when there are constraints on the leading (leftmost) columns.
+ The exact rule is that equality constraints on leading columns, plus
+ any inequality constraints on the first column that does not have an
+ equality constraint, will be used to limit the portion of the index
+ that is scanned. Constraints on columns to the right of these columns
+ are checked in the index, so they save visits to the table proper, but
+ they do not reduce the portion of the index that has to be scanned.
+ For example, given an index on <code class="literal">(a, b, c)</code> and a
+ query condition <code class="literal">WHERE a = 5 AND b &gt;= 42 AND c &lt; 77</code>,
+ the index would have to be scanned from the first entry with
+ <code class="literal">a</code> = 5 and <code class="literal">b</code> = 42 up through the last entry with
+ <code class="literal">a</code> = 5. Index entries with <code class="literal">c</code> &gt;= 77 would be
+ skipped, but they'd still have to be scanned through.
+ This index could in principle be used for queries that have constraints
+ on <code class="literal">b</code> and/or <code class="literal">c</code> with no constraint on <code class="literal">a</code>
+ — but the entire index would have to be scanned, so in most cases
+ the planner would prefer a sequential table scan over using the index.
+ </p><p>
+ A multicolumn GiST index can be used with query conditions that
+ involve any subset of the index's columns. Conditions on additional
+ columns restrict the entries returned by the index, but the condition on
+ the first column is the most important one for determining how much of
+ the index needs to be scanned. A GiST index will be relatively
+ ineffective if its first column has only a few distinct values, even if
+ there are many distinct values in additional columns.
+ </p><p>
+ A multicolumn GIN index can be used with query conditions that
+ involve any subset of the index's columns. Unlike B-tree or GiST,
+ index search effectiveness is the same regardless of which index column(s)
+ the query conditions use.
+ </p><p>
+ A multicolumn BRIN index can be used with query conditions that
+ involve any subset of the index's columns. Like GIN and unlike B-tree or
+ GiST, index search effectiveness is the same regardless of which index
+ column(s) the query conditions use. The only reason to have multiple BRIN
+ indexes instead of one multicolumn BRIN index on a single table is to have
+ a different <code class="literal">pages_per_range</code> storage parameter.
+ </p><p>
+ Of course, each column must be used with operators appropriate to the index
+ type; clauses that involve other operators will not be considered.
+ </p><p>
+ Multicolumn indexes should be used sparingly. In most situations,
+ an index on a single column is sufficient and saves space and time.
+ Indexes with more than three columns are unlikely to be helpful
+ unless the usage of the table is extremely stylized. See also
+ <a class="xref" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes">Section 11.5</a> and
+ <a class="xref" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">Section 11.9</a> for some discussion of the
+ merits of different index configurations.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-types.html" title="11.2. Index Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-ordering.html" title="11.4. Indexes and ORDER BY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.2. Index Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.4. Indexes and <code class="literal">ORDER BY</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-opclass.html b/doc/src/sgml/html/indexes-opclass.html
new file mode 100644
index 0000000..0ed4caf
--- /dev/null
+++ b/doc/src/sgml/html/indexes-opclass.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.10. Operator Classes and Operator Families</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes" /><link rel="next" href="indexes-collations.html" title="11.11. Indexes and Collations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.10. Operator Classes and Operator Families</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-collations.html" title="11.11. Indexes and Collations">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-OPCLASS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.10. Operator Classes and Operator Families</h2></div></div></div><a id="id-1.5.10.13.2" class="indexterm"></a><a id="id-1.5.10.13.3" class="indexterm"></a><p>
+ An index definition can specify an <em class="firstterm">operator
+ class</em> for each column of an index.
+</p><pre class="synopsis">
+CREATE INDEX <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table</code></em> (<em class="replaceable"><code>column</code></em> <em class="replaceable"><code>opclass</code></em> [ ( <em class="replaceable"><code>opclass_options</code></em> ) ] [<span class="optional"><em class="replaceable"><code>sort options</code></em></span>] [<span class="optional">, ...</span>]);
+</pre><p>
+ The operator class identifies the operators to be used by the index
+ for that column. For example, a B-tree index on the type <code class="type">int4</code>
+ would use the <code class="literal">int4_ops</code> class; this operator
+ class includes comparison functions for values of type <code class="type">int4</code>.
+ In practice the default operator class for the column's data type is
+ usually sufficient. The main reason for having operator classes is
+ that for some data types, there could be more than one meaningful
+ index behavior. For example, we might want to sort a complex-number data
+ type either by absolute value or by real part. We could do this by
+ defining two operator classes for the data type and then selecting
+ the proper class when making an index. The operator class determines
+ the basic sort ordering (which can then be modified by adding sort options
+ <code class="literal">COLLATE</code>,
+ <code class="literal">ASC</code>/<code class="literal">DESC</code> and/or
+ <code class="literal">NULLS FIRST</code>/<code class="literal">NULLS LAST</code>).
+ </p><p>
+ There are also some built-in operator classes besides the default ones:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The operator classes <code class="literal">text_pattern_ops</code>,
+ <code class="literal">varchar_pattern_ops</code>, and
+ <code class="literal">bpchar_pattern_ops</code> support B-tree indexes on
+ the types <code class="type">text</code>, <code class="type">varchar</code>, and
+ <code class="type">char</code> respectively. The
+ difference from the default operator classes is that the values
+ are compared strictly character by character rather than
+ according to the locale-specific collation rules. This makes
+ these operator classes suitable for use by queries involving
+ pattern matching expressions (<code class="literal">LIKE</code> or POSIX
+ regular expressions) when the database does not use the standard
+ <span class="quote">“<span class="quote">C</span>”</span> locale. As an example, you might index a
+ <code class="type">varchar</code> column like this:
+</p><pre class="programlisting">
+CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
+</pre><p>
+ Note that you should also create an index with the default operator
+ class if you want queries involving ordinary <code class="literal">&lt;</code>,
+ <code class="literal">&lt;=</code>, <code class="literal">&gt;</code>, or <code class="literal">&gt;=</code> comparisons
+ to use an index. Such queries cannot use the
+ <code class="literal"><em class="replaceable"><code>xxx</code></em>_pattern_ops</code>
+ operator classes. (Ordinary equality comparisons can use these
+ operator classes, however.) It is possible to create multiple
+ indexes on the same column with different operator classes.
+ If you do use the C locale, you do not need the
+ <code class="literal"><em class="replaceable"><code>xxx</code></em>_pattern_ops</code>
+ operator classes, because an index with the default operator class
+ is usable for pattern-matching queries in the C locale.
+ </p></li></ul></div><p>
+ </p><p>
+ The following query shows all defined operator classes:
+
+</p><pre class="programlisting">
+SELECT am.amname AS index_method,
+ opc.opcname AS opclass_name,
+ opc.opcintype::regtype AS indexed_type,
+ opc.opcdefault AS is_default
+ FROM pg_am am, pg_opclass opc
+ WHERE opc.opcmethod = am.oid
+ ORDER BY index_method, opclass_name;
+</pre><p>
+ </p><p>
+ An operator class is actually just a subset of a larger structure called an
+ <em class="firstterm">operator family</em>. In cases where several data types have
+ similar behaviors, it is frequently useful to define cross-data-type
+ operators and allow these to work with indexes. To do this, the operator
+ classes for each of the types must be grouped into the same operator
+ family. The cross-type operators are members of the family, but are not
+ associated with any single class within the family.
+ </p><p>
+ This expanded version of the previous query shows the operator family
+ each operator class belongs to:
+</p><pre class="programlisting">
+SELECT am.amname AS index_method,
+ opc.opcname AS opclass_name,
+ opf.opfname AS opfamily_name,
+ opc.opcintype::regtype AS indexed_type,
+ opc.opcdefault AS is_default
+ FROM pg_am am, pg_opclass opc, pg_opfamily opf
+ WHERE opc.opcmethod = am.oid AND
+ opc.opcfamily = opf.oid
+ ORDER BY index_method, opclass_name;
+</pre><p>
+ </p><p>
+ This query shows all defined operator families and all
+ the operators included in each family:
+</p><pre class="programlisting">
+SELECT am.amname AS index_method,
+ opf.opfname AS opfamily_name,
+ amop.amopopr::regoperator AS opfamily_operator
+ FROM pg_am am, pg_opfamily opf, pg_amop amop
+ WHERE opf.opfmethod = am.oid AND
+ amop.amopfamily = opf.oid
+ ORDER BY index_method, opfamily_name, opfamily_operator;
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> has
+ commands <code class="command">\dAc</code>, <code class="command">\dAf</code>,
+ and <code class="command">\dAo</code>, which provide slightly more sophisticated
+ versions of these queries.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-collations.html" title="11.11. Indexes and Collations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.9. Index-Only Scans and Covering Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.11. Indexes and Collations</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-ordering.html b/doc/src/sgml/html/indexes-ordering.html
new file mode 100644
index 0000000..4ce9a81
--- /dev/null
+++ b/doc/src/sgml/html/indexes-ordering.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.4. Indexes and ORDER BY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes" /><link rel="next" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.4. Indexes and <code class="literal">ORDER BY</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-ORDERING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.4. Indexes and <code class="literal">ORDER BY</code></h2></div></div></div><a id="id-1.5.10.7.2" class="indexterm"></a><p>
+ In addition to simply finding the rows to be returned by a query,
+ an index may be able to deliver them in a specific sorted order.
+ This allows a query's <code class="literal">ORDER BY</code> specification to be honored
+ without a separate sorting step. Of the index types currently
+ supported by <span class="productname">PostgreSQL</span>, only B-tree
+ can produce sorted output — the other index types return
+ matching rows in an unspecified, implementation-dependent order.
+ </p><p>
+ The planner will consider satisfying an <code class="literal">ORDER BY</code> specification
+ either by scanning an available index that matches the specification,
+ or by scanning the table in physical order and doing an explicit
+ sort. For a query that requires scanning a large fraction of the
+ table, an explicit sort is likely to be faster than using an index
+ because it requires
+ less disk I/O due to following a sequential access pattern. Indexes are
+ more useful when only a few rows need be fetched. An important
+ special case is <code class="literal">ORDER BY</code> in combination with
+ <code class="literal">LIMIT</code> <em class="replaceable"><code>n</code></em>: an explicit sort will have to process
+ all the data to identify the first <em class="replaceable"><code>n</code></em> rows, but if there is
+ an index matching the <code class="literal">ORDER BY</code>, the first <em class="replaceable"><code>n</code></em>
+ rows can be retrieved directly, without scanning the remainder at all.
+ </p><p>
+ By default, B-tree indexes store their entries in ascending order
+ with nulls last (table TID is treated as a tiebreaker column among
+ otherwise equal entries). This means that a forward scan of an
+ index on column <code class="literal">x</code> produces output satisfying <code class="literal">ORDER BY x</code>
+ (or more verbosely, <code class="literal">ORDER BY x ASC NULLS LAST</code>). The
+ index can also be scanned backward, producing output satisfying
+ <code class="literal">ORDER BY x DESC</code>
+ (or more verbosely, <code class="literal">ORDER BY x DESC NULLS FIRST</code>, since
+ <code class="literal">NULLS FIRST</code> is the default for <code class="literal">ORDER BY DESC</code>).
+ </p><p>
+ You can adjust the ordering of a B-tree index by including the
+ options <code class="literal">ASC</code>, <code class="literal">DESC</code>, <code class="literal">NULLS FIRST</code>,
+ and/or <code class="literal">NULLS LAST</code> when creating the index; for example:
+</p><pre class="programlisting">
+CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
+CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
+</pre><p>
+ An index stored in ascending order with nulls first can satisfy
+ either <code class="literal">ORDER BY x ASC NULLS FIRST</code> or
+ <code class="literal">ORDER BY x DESC NULLS LAST</code> depending on which direction
+ it is scanned in.
+ </p><p>
+ You might wonder why bother providing all four options, when two
+ options together with the possibility of backward scan would cover
+ all the variants of <code class="literal">ORDER BY</code>. In single-column indexes
+ the options are indeed redundant, but in multicolumn indexes they can be
+ useful. Consider a two-column index on <code class="literal">(x, y)</code>: this can
+ satisfy <code class="literal">ORDER BY x, y</code> if we scan forward, or
+ <code class="literal">ORDER BY x DESC, y DESC</code> if we scan backward.
+ But it might be that the application frequently needs to use
+ <code class="literal">ORDER BY x ASC, y DESC</code>. There is no way to get that
+ ordering from a plain index, but it is possible if the index is defined
+ as <code class="literal">(x ASC, y DESC)</code> or <code class="literal">(x DESC, y ASC)</code>.
+ </p><p>
+ Obviously, indexes with non-default sort orderings are a fairly
+ specialized feature, but sometimes they can produce tremendous
+ speedups for certain queries. Whether it's worth maintaining such an
+ index depends on how often you use queries that require a special
+ sort ordering.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.3. Multicolumn Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.5. Combining Multiple Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-partial.html b/doc/src/sgml/html/indexes-partial.html
new file mode 100644
index 0000000..1aa6c32
--- /dev/null
+++ b/doc/src/sgml/html/indexes-partial.html
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.8. Partial Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-expressional.html" title="11.7. Indexes on Expressions" /><link rel="next" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.8. Partial Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-expressional.html" title="11.7. Indexes on Expressions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-PARTIAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.8. Partial Indexes</h2></div></div></div><a id="id-1.5.10.11.2" class="indexterm"></a><p>
+ A <em class="firstterm">partial index</em> is an index built over a
+ subset of a table; the subset is defined by a conditional
+ expression (called the <em class="firstterm">predicate</em> of the
+ partial index). The index contains entries only for those table
+ rows that satisfy the predicate. Partial indexes are a specialized
+ feature, but there are several situations in which they are useful.
+ </p><p>
+ One major reason for using a partial index is to avoid indexing common
+ values. Since a query searching for a common value (one that
+ accounts for more than a few percent of all the table rows) will not
+ use the index anyway, there is no point in keeping those rows in the
+ index at all. This reduces the size of the index, which will speed
+ up those queries that do use the index. It will also speed up many table
+ update operations because the index does not need to be
+ updated in all cases. <a class="xref" href="indexes-partial.html#INDEXES-PARTIAL-EX1" title="Example 11.1. Setting up a Partial Index to Exclude Common Values">Example 11.1</a> shows a
+ possible application of this idea.
+ </p><div class="example" id="INDEXES-PARTIAL-EX1"><p class="title"><strong>Example 11.1. Setting up a Partial Index to Exclude Common Values</strong></p><div class="example-contents"><p>
+ Suppose you are storing web server access logs in a database.
+ Most accesses originate from the IP address range of your organization but
+ some are from elsewhere (say, employees on dial-up connections).
+ If your searches by IP are primarily for outside accesses,
+ you probably do not need to index the IP range that corresponds to your
+ organization's subnet.
+ </p><p>
+ Assume a table like this:
+</p><pre class="programlisting">
+CREATE TABLE access_log (
+ url varchar,
+ client_ip inet,
+ ...
+);
+</pre><p>
+ </p><p>
+ To create a partial index that suits our example, use a command
+ such as this:
+</p><pre class="programlisting">
+CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
+WHERE NOT (client_ip &gt; inet '192.168.100.0' AND
+ client_ip &lt; inet '192.168.100.255');
+</pre><p>
+ </p><p>
+ A typical query that can use this index would be:
+</p><pre class="programlisting">
+SELECT *
+FROM access_log
+WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';
+</pre><p>
+ Here the query's IP address is covered by the partial index. The
+ following query cannot use the partial index, as it uses an IP address
+ that is excluded from the index:
+</p><pre class="programlisting">
+SELECT *
+FROM access_log
+WHERE url = '/index.html' AND client_ip = inet '192.168.100.23';
+</pre><p>
+ </p><p>
+ Observe that this kind of partial index requires that the common
+ values be predetermined, so such partial indexes are best used for
+ data distributions that do not change. Such indexes can be recreated
+ occasionally to adjust for new data distributions, but this adds
+ maintenance effort.
+ </p></div></div><br class="example-break" /><p>
+ Another possible use for a partial index is to exclude values from the
+ index that the
+ typical query workload is not interested in; this is shown in <a class="xref" href="indexes-partial.html#INDEXES-PARTIAL-EX2" title="Example 11.2. Setting up a Partial Index to Exclude Uninteresting Values">Example 11.2</a>. This results in the same
+ advantages as listed above, but it prevents the
+ <span class="quote">“<span class="quote">uninteresting</span>”</span> values from being accessed via that
+ index, even if an index scan might be profitable in that
+ case. Obviously, setting up partial indexes for this kind of
+ scenario will require a lot of care and experimentation.
+ </p><div class="example" id="INDEXES-PARTIAL-EX2"><p class="title"><strong>Example 11.2. Setting up a Partial Index to Exclude Uninteresting Values</strong></p><div class="example-contents"><p>
+ If you have a table that contains both billed and unbilled orders,
+ where the unbilled orders take up a small fraction of the total
+ table and yet those are the most-accessed rows, you can improve
+ performance by creating an index on just the unbilled rows. The
+ command to create the index would look like this:
+</p><pre class="programlisting">
+CREATE INDEX orders_unbilled_index ON orders (order_nr)
+ WHERE billed is not true;
+</pre><p>
+ </p><p>
+ A possible query to use this index would be:
+</p><pre class="programlisting">
+SELECT * FROM orders WHERE billed is not true AND order_nr &lt; 10000;
+</pre><p>
+ However, the index can also be used in queries that do not involve
+ <code class="structfield">order_nr</code> at all, e.g.:
+</p><pre class="programlisting">
+SELECT * FROM orders WHERE billed is not true AND amount &gt; 5000.00;
+</pre><p>
+ This is not as efficient as a partial index on the
+ <code class="structfield">amount</code> column would be, since the system has to
+ scan the entire index. Yet, if there are relatively few unbilled
+ orders, using this partial index just to find the unbilled orders
+ could be a win.
+ </p><p>
+ Note that this query cannot use this index:
+</p><pre class="programlisting">
+SELECT * FROM orders WHERE order_nr = 3501;
+</pre><p>
+ The order 3501 might be among the billed or unbilled
+ orders.
+ </p></div></div><br class="example-break" /><p>
+ <a class="xref" href="indexes-partial.html#INDEXES-PARTIAL-EX2" title="Example 11.2. Setting up a Partial Index to Exclude Uninteresting Values">Example 11.2</a> also illustrates that the
+ indexed column and the column used in the predicate do not need to
+ match. <span class="productname">PostgreSQL</span> supports partial
+ indexes with arbitrary predicates, so long as only columns of the
+ table being indexed are involved. However, keep in mind that the
+ predicate must match the conditions used in the queries that
+ are supposed to benefit from the index. To be precise, a partial
+ index can be used in a query only if the system can recognize that
+ the <code class="literal">WHERE</code> condition of the query mathematically implies
+ the predicate of the index.
+ <span class="productname">PostgreSQL</span> does not have a sophisticated
+ theorem prover that can recognize mathematically equivalent
+ expressions that are written in different forms. (Not
+ only is such a general theorem prover extremely difficult to
+ create, it would probably be too slow to be of any real use.)
+ The system can recognize simple inequality implications, for example
+ <span class="quote">“<span class="quote">x &lt; 1</span>”</span> implies <span class="quote">“<span class="quote">x &lt; 2</span>”</span>; otherwise
+ the predicate condition must exactly match part of the query's
+ <code class="literal">WHERE</code> condition
+ or the index will not be recognized as usable. Matching takes
+ place at query planning time, not at run time. As a result,
+ parameterized query clauses do not work with a partial index. For
+ example a prepared query with a parameter might specify
+ <span class="quote">“<span class="quote">x &lt; ?</span>”</span> which will never imply
+ <span class="quote">“<span class="quote">x &lt; 2</span>”</span> for all possible values of the parameter.
+ </p><p>
+ A third possible use for partial indexes does not require the
+ index to be used in queries at all. The idea here is to create
+ a unique index over a subset of a table, as in <a class="xref" href="indexes-partial.html#INDEXES-PARTIAL-EX3" title="Example 11.3. Setting up a Partial Unique Index">Example 11.3</a>. This enforces uniqueness
+ among the rows that satisfy the index predicate, without constraining
+ those that do not.
+ </p><div class="example" id="INDEXES-PARTIAL-EX3"><p class="title"><strong>Example 11.3. Setting up a Partial Unique Index</strong></p><div class="example-contents"><p>
+ Suppose that we have a table describing test outcomes. We wish
+ to ensure that there is only one <span class="quote">“<span class="quote">successful</span>”</span> entry for
+ a given subject and target combination, but there might be any number of
+ <span class="quote">“<span class="quote">unsuccessful</span>”</span> entries. Here is one way to do it:
+</p><pre class="programlisting">
+CREATE TABLE tests (
+ subject text,
+ target text,
+ success boolean,
+ ...
+);
+
+CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
+ WHERE success;
+</pre><p>
+ This is a particularly efficient approach when there are few
+ successful tests and many unsuccessful ones. It is also possible to
+ allow only one null in a column by creating a unique partial index
+ with an <code class="literal">IS NULL</code> restriction.
+ </p></div></div><br class="example-break" /><p>
+ Finally, a partial index can also be used to override the system's
+ query plan choices. Also, data sets with peculiar
+ distributions might cause the system to use an index when it really
+ should not. In that case the index can be set up so that it is not
+ available for the offending query. Normally,
+ <span class="productname">PostgreSQL</span> makes reasonable choices about index
+ usage (e.g., it avoids them when retrieving common values, so the
+ earlier example really only saves index size, it is not required to
+ avoid index usage), and grossly incorrect plan choices are cause
+ for a bug report.
+ </p><p>
+ Keep in mind that setting up a partial index indicates that you
+ know at least as much as the query planner knows, in particular you
+ know when an index might be profitable. Forming this knowledge
+ requires experience and understanding of how indexes in
+ <span class="productname">PostgreSQL</span> work. In most cases, the
+ advantage of a partial index over a regular index will be minimal.
+ There are cases where they are quite counterproductive, as in <a class="xref" href="indexes-partial.html#INDEXES-PARTIAL-EX4" title="Example 11.4. Do Not Use Partial Indexes as a Substitute for Partitioning">Example 11.4</a>.
+ </p><div class="example" id="INDEXES-PARTIAL-EX4"><p class="title"><strong>Example 11.4. Do Not Use Partial Indexes as a Substitute for Partitioning</strong></p><div class="example-contents"><p>
+ You might be tempted to create a large set of non-overlapping partial
+ indexes, for example
+
+</p><pre class="programlisting">
+CREATE INDEX mytable_cat_1 ON mytable (data) WHERE category = 1;
+CREATE INDEX mytable_cat_2 ON mytable (data) WHERE category = 2;
+CREATE INDEX mytable_cat_3 ON mytable (data) WHERE category = 3;
+...
+CREATE INDEX mytable_cat_<em class="replaceable"><code>N</code></em> ON mytable (data) WHERE category = <em class="replaceable"><code>N</code></em>;
+</pre><p>
+
+ This is a bad idea! Almost certainly, you'll be better off with a
+ single non-partial index, declared like
+
+</p><pre class="programlisting">
+CREATE INDEX mytable_cat_data ON mytable (category, data);
+</pre><p>
+
+ (Put the category column first, for the reasons described in
+ <a class="xref" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Section 11.3</a>.) While a search in this larger
+ index might have to descend through a couple more tree levels than a
+ search in a smaller index, that's almost certainly going to be cheaper
+ than the planner effort needed to select the appropriate one of the
+ partial indexes. The core of the problem is that the system does not
+ understand the relationship among the partial indexes, and will
+ laboriously test each one to see if it's applicable to the current
+ query.
+ </p><p>
+ If your table is large enough that a single index really is a bad idea,
+ you should look into using partitioning instead (see
+ <a class="xref" href="ddl-partitioning.html" title="5.11. Table Partitioning">Section 5.11</a>). With that mechanism, the system
+ does understand that the tables and indexes are non-overlapping, so
+ far better performance is possible.
+ </p></div></div><br class="example-break" /><p>
+ More information about partial indexes can be found in <a class="xref" href="biblio.html#STON89B">[ston89b]</a>, <a class="xref" href="biblio.html#OLSON93" title="Partial indexing in POSTGRES: research project">[olson93]</a>, and <a class="xref" href="biblio.html#SESHADRI95">[seshadri95]</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-expressional.html" title="11.7. Indexes on Expressions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.7. Indexes on Expressions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.9. Index-Only Scans and Covering Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-types.html b/doc/src/sgml/html/indexes-types.html
new file mode 100644
index 0000000..ce50a25
--- /dev/null
+++ b/doc/src/sgml/html/indexes-types.html
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.2. Index Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-intro.html" title="11.1. Introduction" /><link rel="next" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.2. Index Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-intro.html" title="11.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-TYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.2. Index Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-BTREE">11.2.1. B-Tree</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-HASH">11.2.2. Hash</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPE-GIST">11.2.3. GiST</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPE-SPGIST">11.2.4. SP-GiST</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-GIN">11.2.5. GIN</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-BRIN">11.2.6. BRIN</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> provides several index types:
+ B-tree, Hash, GiST, SP-GiST, GIN, BRIN, and the extension <a class="link" href="bloom.html" title="F.7. bloom">bloom</a>.
+ Each index type uses a different
+ algorithm that is best suited to different types of queries.
+ By default, the <a class="link" href="sql-createindex.html" title="CREATE INDEX"><code class="command">CREATE
+ INDEX</code></a> command creates
+ B-tree indexes, which fit the most common situations.
+ The other index types are selected by writing the keyword
+ <code class="literal">USING</code> followed by the index type name.
+ For example, to create a Hash index:
+</p><pre class="programlisting">
+CREATE INDEX <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table</code></em> USING HASH (<em class="replaceable"><code>column</code></em>);
+</pre><p>
+ </p><div class="sect2" id="INDEXES-TYPES-BTREE"><div class="titlepage"><div><div><h3 class="title">11.2.1. B-Tree</h3></div></div></div><a id="id-1.5.10.5.3.2" class="indexterm"></a><a id="id-1.5.10.5.3.3" class="indexterm"></a><p>
+ B-trees can handle equality and range queries on data that can be sorted
+ into some ordering.
+ In particular, the <span class="productname">PostgreSQL</span> query planner
+ will consider using a B-tree index whenever an indexed column is
+ involved in a comparison using one of these operators:
+
+</p><pre class="synopsis">
+&lt;   &lt;=   =   &gt;=   &gt;
+</pre><p>
+
+ Constructs equivalent to combinations of these operators, such as
+ <code class="literal">BETWEEN</code> and <code class="literal">IN</code>, can also be implemented with
+ a B-tree index search. Also, an <code class="literal">IS NULL</code> or <code class="literal">IS NOT
+ NULL</code> condition on an index column can be used with a B-tree index.
+ </p><p>
+ The optimizer can also use a B-tree index for queries involving the
+ pattern matching operators <code class="literal">LIKE</code> and <code class="literal">~</code>
+ <span class="emphasis"><em>if</em></span> the pattern is a constant and is anchored to
+ the beginning of the string — for example, <code class="literal">col LIKE
+ 'foo%'</code> or <code class="literal">col ~ '^foo'</code>, but not
+ <code class="literal">col LIKE '%bar'</code>. However, if your database does not
+ use the C locale you will need to create the index with a special
+ operator class to support indexing of pattern-matching queries; see
+ <a class="xref" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Section 11.10</a> below. It is also possible to use
+ B-tree indexes for <code class="literal">ILIKE</code> and
+ <code class="literal">~*</code>, but only if the pattern starts with
+ non-alphabetic characters, i.e., characters that are not affected by
+ upper/lower case conversion.
+ </p><p>
+ B-tree indexes can also be used to retrieve data in sorted order.
+ This is not always faster than a simple scan and sort, but it is
+ often helpful.
+ </p></div><div class="sect2" id="INDEXES-TYPES-HASH"><div class="titlepage"><div><div><h3 class="title">11.2.2. Hash</h3></div></div></div><a id="id-1.5.10.5.4.2" class="indexterm"></a><a id="id-1.5.10.5.4.3" class="indexterm"></a><p>
+ Hash indexes store a 32-bit hash code derived from the
+ value of the indexed column. Hence,
+ such indexes can only handle simple equality comparisons.
+ The query planner will consider using a hash index whenever an
+ indexed column is involved in a comparison using the
+ equal operator:
+
+</p><pre class="synopsis">
+=
+</pre><p>
+ </p></div><div class="sect2" id="INDEXES-TYPE-GIST"><div class="titlepage"><div><div><h3 class="title">11.2.3. GiST</h3></div></div></div><a id="id-1.5.10.5.5.2" class="indexterm"></a><a id="id-1.5.10.5.5.3" class="indexterm"></a><p>
+ GiST indexes are not a single kind of index, but rather an infrastructure
+ within which many different indexing strategies can be implemented.
+ Accordingly, the particular operators with which a GiST index can be
+ used vary depending on the indexing strategy (the <em class="firstterm">operator
+ class</em>). As an example, the standard distribution of
+ <span class="productname">PostgreSQL</span> includes GiST operator classes
+ for several two-dimensional geometric data types, which support indexed
+ queries using these operators:
+
+</p><pre class="synopsis">
+&lt;&lt;   &amp;&lt;   &amp;&gt;   &gt;&gt;   &lt;&lt;|   &amp;&lt;|   |&amp;&gt;   |&gt;&gt;   @&gt;   &lt;@   ~=   &amp;&amp;
+</pre><p>
+
+ (See <a class="xref" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Section 9.11</a> for the meaning of
+ these operators.)
+ The GiST operator classes included in the standard distribution are
+ documented in <a class="xref" href="gist-builtin-opclasses.html#GIST-BUILTIN-OPCLASSES-TABLE" title="Table 68.1. Built-in GiST Operator Classes">Table 68.1</a>.
+ Many other GiST operator
+ classes are available in the <code class="literal">contrib</code> collection or as separate
+ projects. For more information see <a class="xref" href="gist.html" title="Chapter 68. GiST Indexes">Chapter 68</a>.
+ </p><p>
+ GiST indexes are also capable of optimizing <span class="quote">“<span class="quote">nearest-neighbor</span>”</span>
+ searches, such as
+</p><pre class="programlisting">
+SELECT * FROM places ORDER BY location &lt;-&gt; point '(101,456)' LIMIT 10;
+
+</pre><p>
+ which finds the ten places closest to a given target point. The ability
+ to do this is again dependent on the particular operator class being used.
+ In <a class="xref" href="gist-builtin-opclasses.html#GIST-BUILTIN-OPCLASSES-TABLE" title="Table 68.1. Built-in GiST Operator Classes">Table 68.1</a>, operators that can be
+ used in this way are listed in the column <span class="quote">“<span class="quote">Ordering Operators</span>”</span>.
+ </p></div><div class="sect2" id="INDEXES-TYPE-SPGIST"><div class="titlepage"><div><div><h3 class="title">11.2.4. SP-GiST</h3></div></div></div><a id="id-1.5.10.5.6.2" class="indexterm"></a><a id="id-1.5.10.5.6.3" class="indexterm"></a><p>
+ SP-GiST indexes, like GiST indexes, offer an infrastructure that supports
+ various kinds of searches. SP-GiST permits implementation of a wide range
+ of different non-balanced disk-based data structures, such as quadtrees,
+ k-d trees, and radix trees (tries). As an example, the standard distribution of
+ <span class="productname">PostgreSQL</span> includes SP-GiST operator classes
+ for two-dimensional points, which support indexed
+ queries using these operators:
+
+</p><pre class="synopsis">
+&lt;&lt;   &gt;&gt;   ~=   &lt;@   &lt;&lt;|   |&gt;&gt;
+</pre><p>
+
+ (See <a class="xref" href="functions-geometry.html" title="9.11. Geometric Functions and Operators">Section 9.11</a> for the meaning of
+ these operators.)
+ The SP-GiST operator classes included in the standard distribution are
+ documented in <a class="xref" href="spgist-builtin-opclasses.html#SPGIST-BUILTIN-OPCLASSES-TABLE" title="Table 69.1. Built-in SP-GiST Operator Classes">Table 69.1</a>.
+ For more information see <a class="xref" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Chapter 69</a>.
+ </p><p>
+ Like GiST, SP-GiST supports <span class="quote">“<span class="quote">nearest-neighbor</span>”</span> searches.
+ For SP-GiST operator classes that support distance ordering, the
+ corresponding operator is listed in the <span class="quote">“<span class="quote">Ordering Operators</span>”</span>
+ column in <a class="xref" href="spgist-builtin-opclasses.html#SPGIST-BUILTIN-OPCLASSES-TABLE" title="Table 69.1. Built-in SP-GiST Operator Classes">Table 69.1</a>.
+ </p></div><div class="sect2" id="INDEXES-TYPES-GIN"><div class="titlepage"><div><div><h3 class="title">11.2.5. GIN</h3></div></div></div><a id="id-1.5.10.5.7.2" class="indexterm"></a><a id="id-1.5.10.5.7.3" class="indexterm"></a><p>
+ GIN indexes are <span class="quote">“<span class="quote">inverted indexes</span>”</span> which are appropriate for
+ data values that contain multiple component values, such as arrays. An
+ inverted index contains a separate entry for each component value, and
+ can efficiently handle queries that test for the presence of specific
+ component values.
+ </p><p>
+ Like GiST and SP-GiST, GIN can support
+ many different user-defined indexing strategies, and the particular
+ operators with which a GIN index can be used vary depending on the
+ indexing strategy.
+ As an example, the standard distribution of
+ <span class="productname">PostgreSQL</span> includes a GIN operator class
+ for arrays, which supports indexed queries using these operators:
+
+</p><pre class="synopsis">
+&lt;@   @&gt;   =   &amp;&amp;
+</pre><p>
+
+ (See <a class="xref" href="functions-array.html" title="9.19. Array Functions and Operators">Section 9.19</a> for the meaning of
+ these operators.)
+ The GIN operator classes included in the standard distribution are
+ documented in <a class="xref" href="gin-builtin-opclasses.html#GIN-BUILTIN-OPCLASSES-TABLE" title="Table 70.1. Built-in GIN Operator Classes">Table 70.1</a>.
+ Many other GIN operator
+ classes are available in the <code class="literal">contrib</code> collection or as separate
+ projects. For more information see <a class="xref" href="gin.html" title="Chapter 70. GIN Indexes">Chapter 70</a>.
+ </p></div><div class="sect2" id="INDEXES-TYPES-BRIN"><div class="titlepage"><div><div><h3 class="title">11.2.6. BRIN</h3></div></div></div><a id="id-1.5.10.5.8.2" class="indexterm"></a><a id="id-1.5.10.5.8.3" class="indexterm"></a><p>
+ BRIN indexes (a shorthand for Block Range INdexes) store summaries about
+ the values stored in consecutive physical block ranges of a table.
+ Thus, they are most effective for columns whose values are well-correlated
+ with the physical order of the table rows.
+ Like GiST, SP-GiST and GIN,
+ BRIN can support many different indexing strategies,
+ and the particular operators with which a BRIN index can be used
+ vary depending on the indexing strategy.
+ For data types that have a linear sort order, the indexed data
+ corresponds to the minimum and maximum values of the
+ values in the column for each block range. This supports indexed queries
+ using these operators:
+
+</p><pre class="synopsis">
+&lt;   &lt;=   =   &gt;=   &gt;
+</pre><p>
+
+ The BRIN operator classes included in the standard distribution are
+ documented in <a class="xref" href="brin-builtin-opclasses.html#BRIN-BUILTIN-OPCLASSES-TABLE" title="Table 71.1. Built-in BRIN Operator Classes">Table 71.1</a>.
+ For more information see <a class="xref" href="brin.html" title="Chapter 71. BRIN Indexes">Chapter 71</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-intro.html" title="11.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-multicolumn.html" title="11.3. Multicolumn Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.3. Multicolumn Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes-unique.html b/doc/src/sgml/html/indexes-unique.html
new file mode 100644
index 0000000..286068c
--- /dev/null
+++ b/doc/src/sgml/html/indexes-unique.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>11.6. Unique Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes" /><link rel="next" href="indexes-expressional.html" title="11.7. Indexes on Expressions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">11.6. Unique Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><th width="60%" align="center">Chapter 11. Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-expressional.html" title="11.7. Indexes on Expressions">Next</a></td></tr></table><hr /></div><div class="sect1" id="INDEXES-UNIQUE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">11.6. Unique Indexes</h2></div></div></div><a id="id-1.5.10.9.2" class="indexterm"></a><p>
+ Indexes can also be used to enforce uniqueness of a column's value,
+ or the uniqueness of the combined values of more than one column.
+</p><pre class="synopsis">
+CREATE UNIQUE INDEX <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table</code></em> (<em class="replaceable"><code>column</code></em> [<span class="optional">, ...</span>]) [<span class="optional"> NULLS [<span class="optional"> NOT </span>] DISTINCT </span>];
+</pre><p>
+ Currently, only B-tree indexes can be declared unique.
+ </p><p>
+ When an index is declared unique, multiple table rows with equal
+ indexed values are not allowed. By default, null values in a unique column
+ are not considered equal, allowing multiple nulls in the column. The
+ <code class="literal">NULLS NOT DISTINCT</code> option modifies this and causes the
+ index to treat nulls as equal. A multicolumn unique index will only reject
+ cases where all indexed columns are equal in multiple rows.
+ </p><p>
+ <span class="productname">PostgreSQL</span> automatically creates a unique
+ index when a unique constraint or primary key is defined for a table.
+ The index covers the columns that make up the primary key or unique
+ constraint (a multicolumn index, if appropriate), and is the mechanism
+ that enforces the constraint.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ There's no need to manually
+ create indexes on unique columns; doing so would just duplicate
+ the automatically-created index.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-bitmap-scans.html" title="11.5. Combining Multiple Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="indexes.html" title="Chapter 11. Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-expressional.html" title="11.7. Indexes on Expressions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.5. Combining Multiple Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.7. Indexes on Expressions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/indexes.html b/doc/src/sgml/html/indexes.html
new file mode 100644
index 0000000..2e2aae9
--- /dev/null
+++ b/doc/src/sgml/html/indexes.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 11. Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-select.html" title="10.6. SELECT Output Columns" /><link rel="next" href="indexes-intro.html" title="11.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 11. Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-select.html" title="10.6. SELECT Output Columns">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes-intro.html" title="11.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="INDEXES"><div class="titlepage"><div><div><h2 class="title">Chapter 11. Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="indexes-intro.html">11.1. Introduction</a></span></dt><dt><span class="sect1"><a href="indexes-types.html">11.2. Index Types</a></span></dt><dd><dl><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-BTREE">11.2.1. B-Tree</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-HASH">11.2.2. Hash</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPE-GIST">11.2.3. GiST</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPE-SPGIST">11.2.4. SP-GiST</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-GIN">11.2.5. GIN</a></span></dt><dt><span class="sect2"><a href="indexes-types.html#INDEXES-TYPES-BRIN">11.2.6. BRIN</a></span></dt></dl></dd><dt><span class="sect1"><a href="indexes-multicolumn.html">11.3. Multicolumn Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-ordering.html">11.4. Indexes and <code class="literal">ORDER BY</code></a></span></dt><dt><span class="sect1"><a href="indexes-bitmap-scans.html">11.5. Combining Multiple Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-unique.html">11.6. Unique Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-expressional.html">11.7. Indexes on Expressions</a></span></dt><dt><span class="sect1"><a href="indexes-partial.html">11.8. Partial Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-index-only-scans.html">11.9. Index-Only Scans and Covering Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-opclass.html">11.10. Operator Classes and Operator Families</a></span></dt><dt><span class="sect1"><a href="indexes-collations.html">11.11. Indexes and Collations</a></span></dt><dt><span class="sect1"><a href="indexes-examine.html">11.12. Examining Index Usage</a></span></dt></dl></div><a id="id-1.5.10.2" class="indexterm"></a><p>
+ Indexes are a common way to enhance database performance. An index
+ allows the database server to find and retrieve specific rows much
+ faster than it could do without an index. But indexes also add
+ overhead to the database system as a whole, so they should be used
+ sensibly.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-select.html" title="10.6. SELECT Output Columns">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes-intro.html" title="11.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.6. <code class="literal">SELECT</code> Output Columns </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 11.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/information-schema.html b/doc/src/sgml/html/information-schema.html
new file mode 100644
index 0000000..ec67f8d
--- /dev/null
+++ b/doc/src/sgml/html/information-schema.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 37. The Information Schema</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ecpg-develop.html" title="36.17. Internals" /><link rel="next" href="infoschema-schema.html" title="37.1. The Schema" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 37. The Information Schema</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ecpg-develop.html" title="36.17. Internals">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><th width="60%" align="center">Part IV. Client Interfaces</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-schema.html" title="37.1. The Schema">Next</a></td></tr></table><hr /></div><div class="chapter" id="INFORMATION-SCHEMA"><div class="titlepage"><div><div><h2 class="title">Chapter 37. The Information Schema</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="infoschema-schema.html">37.1. The Schema</a></span></dt><dt><span class="sect1"><a href="infoschema-datatypes.html">37.2. Data Types</a></span></dt><dt><span class="sect1"><a href="infoschema-information-schema-catalog-name.html">37.3. <code class="literal">information_schema_catalog_name</code></a></span></dt><dt><span class="sect1"><a href="infoschema-administrable-role-authorizations.html">37.4. <code class="literal">administrable_role_​authorizations</code></a></span></dt><dt><span class="sect1"><a href="infoschema-applicable-roles.html">37.5. <code class="literal">applicable_roles</code></a></span></dt><dt><span class="sect1"><a href="infoschema-attributes.html">37.6. <code class="literal">attributes</code></a></span></dt><dt><span class="sect1"><a href="infoschema-character-sets.html">37.7. <code class="literal">character_sets</code></a></span></dt><dt><span class="sect1"><a href="infoschema-check-constraint-routine-usage.html">37.8. <code class="literal">check_constraint_routine_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-check-constraints.html">37.9. <code class="literal">check_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-collations.html">37.10. <code class="literal">collations</code></a></span></dt><dt><span class="sect1"><a href="infoschema-collation-character-set-applicab.html">37.11. <code class="literal">collation_character_set_​applicability</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-column-usage.html">37.12. <code class="literal">column_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-domain-usage.html">37.13. <code class="literal">column_domain_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-options.html">37.14. <code class="literal">column_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-privileges.html">37.15. <code class="literal">column_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-column-udt-usage.html">37.16. <code class="literal">column_udt_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-columns.html">37.17. <code class="literal">columns</code></a></span></dt><dt><span class="sect1"><a href="infoschema-constraint-column-usage.html">37.18. <code class="literal">constraint_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-constraint-table-usage.html">37.19. <code class="literal">constraint_table_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-data-type-privileges.html">37.20. <code class="literal">data_type_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-domain-constraints.html">37.21. <code class="literal">domain_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-domain-udt-usage.html">37.22. <code class="literal">domain_udt_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-domains.html">37.23. <code class="literal">domains</code></a></span></dt><dt><span class="sect1"><a href="infoschema-element-types.html">37.24. <code class="literal">element_types</code></a></span></dt><dt><span class="sect1"><a href="infoschema-enabled-roles.html">37.25. <code class="literal">enabled_roles</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-data-wrapper-options.html">37.26. <code class="literal">foreign_data_wrapper_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-data-wrappers.html">37.27. <code class="literal">foreign_data_wrappers</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-server-options.html">37.28. <code class="literal">foreign_server_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-servers.html">37.29. <code class="literal">foreign_servers</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-table-options.html">37.30. <code class="literal">foreign_table_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-foreign-tables.html">37.31. <code class="literal">foreign_tables</code></a></span></dt><dt><span class="sect1"><a href="infoschema-key-column-usage.html">37.32. <code class="literal">key_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-parameters.html">37.33. <code class="literal">parameters</code></a></span></dt><dt><span class="sect1"><a href="infoschema-referential-constraints.html">37.34. <code class="literal">referential_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-column-grants.html">37.35. <code class="literal">role_column_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-routine-grants.html">37.36. <code class="literal">role_routine_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-table-grants.html">37.37. <code class="literal">role_table_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-udt-grants.html">37.38. <code class="literal">role_udt_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-role-usage-grants.html">37.39. <code class="literal">role_usage_grants</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-column-usage.html">37.40. <code class="literal">routine_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-privileges.html">37.41. <code class="literal">routine_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-routine-usage.html">37.42. <code class="literal">routine_routine_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-sequence-usage.html">37.43. <code class="literal">routine_sequence_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routine-table-usage.html">37.44. <code class="literal">routine_table_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-routines.html">37.45. <code class="literal">routines</code></a></span></dt><dt><span class="sect1"><a href="infoschema-schemata.html">37.46. <code class="literal">schemata</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sequences.html">37.47. <code class="literal">sequences</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-features.html">37.48. <code class="literal">sql_features</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-implementation-info.html">37.49. <code class="literal">sql_implementation_info</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-parts.html">37.50. <code class="literal">sql_parts</code></a></span></dt><dt><span class="sect1"><a href="infoschema-sql-sizing.html">37.51. <code class="literal">sql_sizing</code></a></span></dt><dt><span class="sect1"><a href="infoschema-table-constraints.html">37.52. <code class="literal">table_constraints</code></a></span></dt><dt><span class="sect1"><a href="infoschema-table-privileges.html">37.53. <code class="literal">table_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-tables.html">37.54. <code class="literal">tables</code></a></span></dt><dt><span class="sect1"><a href="infoschema-transforms.html">37.55. <code class="literal">transforms</code></a></span></dt><dt><span class="sect1"><a href="infoschema-triggered-update-columns.html">37.56. <code class="literal">triggered_update_columns</code></a></span></dt><dt><span class="sect1"><a href="infoschema-triggers.html">37.57. <code class="literal">triggers</code></a></span></dt><dt><span class="sect1"><a href="infoschema-udt-privileges.html">37.58. <code class="literal">udt_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-usage-privileges.html">37.59. <code class="literal">usage_privileges</code></a></span></dt><dt><span class="sect1"><a href="infoschema-user-defined-types.html">37.60. <code class="literal">user_defined_types</code></a></span></dt><dt><span class="sect1"><a href="infoschema-user-mapping-options.html">37.61. <code class="literal">user_mapping_options</code></a></span></dt><dt><span class="sect1"><a href="infoschema-user-mappings.html">37.62. <code class="literal">user_mappings</code></a></span></dt><dt><span class="sect1"><a href="infoschema-view-column-usage.html">37.63. <code class="literal">view_column_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-view-routine-usage.html">37.64. <code class="literal">view_routine_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-view-table-usage.html">37.65. <code class="literal">view_table_usage</code></a></span></dt><dt><span class="sect1"><a href="infoschema-views.html">37.66. <code class="literal">views</code></a></span></dt></dl></div><a id="id-1.7.6.2" class="indexterm"></a><p>
+ The information schema consists of a set of views that contain
+ information about the objects defined in the current database. The
+ information schema is defined in the SQL standard and can therefore
+ be expected to be portable and remain stable — unlike the system
+ catalogs, which are specific to
+ <span class="productname">PostgreSQL</span> and are modeled after
+ implementation concerns. The information schema views do not,
+ however, contain information about
+ <span class="productname">PostgreSQL</span>-specific features; to inquire
+ about those you need to query the system catalogs or other
+ <span class="productname">PostgreSQL</span>-specific views.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When querying the database for constraint information, it is possible
+ for a standard-compliant query that expects to return one row to
+ return several. This is because the SQL standard requires constraint
+ names to be unique within a schema, but
+ <span class="productname">PostgreSQL</span> does not enforce this
+ restriction. <span class="productname">PostgreSQL</span>
+ automatically-generated constraint names avoid duplicates in the
+ same schema, but users can specify such duplicate names.
+ </p><p>
+ This problem can appear when querying information schema views such
+ as <code class="literal">check_constraint_routine_usage</code>,
+ <code class="literal">check_constraints</code>, <code class="literal">domain_constraints</code>, and
+ <code class="literal">referential_constraints</code>. Some other views have similar
+ issues but contain the table name to help distinguish duplicate
+ rows, e.g., <code class="literal">constraint_column_usage</code>,
+ <code class="literal">constraint_table_usage</code>, <code class="literal">table_constraints</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ecpg-develop.html" title="36.17. Internals">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-schema.html" title="37.1. The Schema">Next</a></td></tr><tr><td width="40%" align="left" valign="top">36.17. Internals </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.1. The Schema</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-administrable-role-authorizations.html b/doc/src/sgml/html/infoschema-administrable-role-authorizations.html
new file mode 100644
index 0000000..0ab86ee
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-administrable-role-authorizations.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.4. administrable_role_​authorizations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-information-schema-catalog-name.html" title="37.3. information_schema_catalog_name" /><link rel="next" href="infoschema-applicable-roles.html" title="37.5. applicable_roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.4. <code class="literal">administrable_role_​authorizations</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-information-schema-catalog-name.html" title="37.3. information_schema_catalog_name">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-applicable-roles.html" title="37.5. applicable_roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ADMINISTRABLE-ROLE-AUTHORIZATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.4. <code class="literal">administrable_role_​authorizations</code></h2></div></div></div><p>
+ The view <code class="literal">administrable_role_authorizations</code>
+ identifies all roles that the current user has the admin option
+ for.
+ </p><div class="table" id="id-1.7.6.8.3"><p class="title"><strong>Table 37.2. <code class="structname">administrable_role_authorizations</code> Columns</strong></p><div class="table-contents"><table class="table" summary="administrable_role_authorizations Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role to which this role membership was granted (can
+ be the current user, or a different role in case of nested role
+ memberships)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">role_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of a role
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Always <code class="literal">YES</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-information-schema-catalog-name.html" title="37.3. information_schema_catalog_name">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-applicable-roles.html" title="37.5. applicable_roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.3. <code class="literal">information_schema_catalog_name</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.5. <code class="literal">applicable_roles</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-applicable-roles.html b/doc/src/sgml/html/infoschema-applicable-roles.html
new file mode 100644
index 0000000..85b5184
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-applicable-roles.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.5. applicable_roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-administrable-role-authorizations.html" title="37.4. administrable_role_​authorizations" /><link rel="next" href="infoschema-attributes.html" title="37.6. attributes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.5. <code class="literal">applicable_roles</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-administrable-role-authorizations.html" title="37.4. administrable_role_​authorizations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-attributes.html" title="37.6. attributes">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-APPLICABLE-ROLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.5. <code class="literal">applicable_roles</code></h2></div></div></div><p>
+ The view <code class="literal">applicable_roles</code> identifies all roles
+ whose privileges the current user can use. This means there is
+ some chain of role grants from the current user to the role in
+ question. The current user itself is also an applicable role. The
+ set of applicable roles is generally used for permission checking.
+ <a id="id-1.7.6.9.2.2" class="indexterm"></a>
+ <a id="id-1.7.6.9.2.3" class="indexterm"></a>
+ </p><div class="table" id="id-1.7.6.9.3"><p class="title"><strong>Table 37.3. <code class="structname">applicable_roles</code> Columns</strong></p><div class="table-contents"><table class="table" summary="applicable_roles Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role to which this role membership was granted (can
+ be the current user, or a different role in case of nested role
+ memberships)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">role_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of a role
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the grantee has the admin option on
+ the role, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-administrable-role-authorizations.html" title="37.4. administrable_role_​authorizations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-attributes.html" title="37.6. attributes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.4. <code class="literal">administrable_role_​authorizations</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.6. <code class="literal">attributes</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-attributes.html b/doc/src/sgml/html/infoschema-attributes.html
new file mode 100644
index 0000000..0093904
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-attributes.html
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.6. attributes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-applicable-roles.html" title="37.5. applicable_roles" /><link rel="next" href="infoschema-character-sets.html" title="37.7. character_sets" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.6. <code class="literal">attributes</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-applicable-roles.html" title="37.5. applicable_roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-character-sets.html" title="37.7. character_sets">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ATTRIBUTES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.6. <code class="literal">attributes</code></h2></div></div></div><p>
+ The view <code class="literal">attributes</code> contains information about
+ the attributes of composite data types defined in the database.
+ (Note that the view does not give information about table columns,
+ which are sometimes called attributes in PostgreSQL contexts.)
+ Only those attributes are shown that the current user has access to (by way
+ of being the owner of or having some privilege on the type).
+ </p><div class="table" id="id-1.7.6.10.3"><p class="title"><strong>Table 37.4. <code class="structname">attributes</code> Columns</strong></p><div class="table-contents"><table class="table" summary="attributes Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the data type (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attribute_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the attribute
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordinal_position</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Ordinal position of the attribute within the data type (count starts at 1)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attribute_default</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Default expression of the attribute
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_nullable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the attribute is possibly nullable,
+ <code class="literal">NO</code> if it is known not nullable.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Data type of the attribute, if it is a built-in type, or
+ <code class="literal">ARRAY</code> if it is some array (in that case, see
+ the view <code class="literal">element_types</code>), else
+ <code class="literal">USER-DEFINED</code> (in that case, the type is
+ identified in <code class="literal">attribute_udt_name</code> and
+ associated columns).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a character or bit
+ string type, the declared maximum length; null for all other
+ data types or if no maximum length was declared.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a character type,
+ the maximum possible length in octets (bytes) of a datum; null
+ for all other data types. The maximum octet length depends on
+ the declared character maximum length (see above) and the
+ server encoding.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the collation of the attribute
+ (always the current database), null if default or the data type
+ of the attribute is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the collation of the attribute,
+ null if default or the data type of the attribute is not
+ collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the collation of the attribute, null if default or the
+ data type of the attribute is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a numeric type, this
+ column contains the (declared or implicit) precision of the
+ type for this attribute. The precision indicates the number of
+ significant digits. It can be expressed in decimal (base 10)
+ or binary (base 2) terms, as specified in the column
+ <code class="literal">numeric_precision_radix</code>. For all other data
+ types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a numeric type, this
+ column indicates in which base the values in the columns
+ <code class="literal">numeric_precision</code> and
+ <code class="literal">numeric_scale</code> are expressed. The value is
+ either 2 or 10. For all other data types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies an exact numeric
+ type, this column contains the (declared or implicit) scale of
+ the type for this attribute. The scale indicates the number of
+ significant digits to the right of the decimal point. It can
+ be expressed in decimal (base 10) or binary (base 2) terms, as
+ specified in the column
+ <code class="literal">numeric_precision_radix</code>. For all other data
+ types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a date, time,
+ timestamp, or interval type, this column contains the (declared
+ or implicit) fractional seconds precision of the type for this
+ attribute, that is, the number of decimal digits maintained
+ following the decimal point in the seconds value. For all
+ other data types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies an interval type,
+ this column contains the specification which fields the
+ intervals include for this attribute, e.g., <code class="literal">YEAR TO
+ MONTH</code>, <code class="literal">DAY TO SECOND</code>, etc. If no
+ field restrictions were specified (that is, the interval
+ accepts all fields), and for all other data types, this field
+ is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available
+ in <span class="productname">PostgreSQL</span>
+ (see <code class="literal">datetime_precision</code> for the fractional
+ seconds precision of interval type attributes)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attribute_udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the attribute data type is defined in
+ (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attribute_udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the attribute data type is defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attribute_udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the attribute data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, because arrays always have unlimited maximum cardinality in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ An identifier of the data type descriptor of the column, unique
+ among the data type descriptors pertaining to the table. This
+ is mainly useful for joining with other instances of such
+ identifiers. (The specific format of the identifier is not
+ defined and not guaranteed to remain the same in future
+ versions.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_derived_reference_attribute</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ See also under <a class="xref" href="infoschema-columns.html" title="37.17. columns">Section 37.17</a>, a similarly
+ structured view, for further information on some of the columns.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-applicable-roles.html" title="37.5. applicable_roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-character-sets.html" title="37.7. character_sets">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.5. <code class="literal">applicable_roles</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.7. <code class="literal">character_sets</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-character-sets.html b/doc/src/sgml/html/infoschema-character-sets.html
new file mode 100644
index 0000000..f6b8f0c
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-character-sets.html
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.7. character_sets</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-attributes.html" title="37.6. attributes" /><link rel="next" href="infoschema-check-constraint-routine-usage.html" title="37.8. check_constraint_routine_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.7. <code class="literal">character_sets</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-attributes.html" title="37.6. attributes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-check-constraint-routine-usage.html" title="37.8. check_constraint_routine_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-CHARACTER-SETS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.7. <code class="literal">character_sets</code></h2></div></div></div><p>
+ The view <code class="literal">character_sets</code> identifies the character
+ sets available in the current database. Since PostgreSQL does not
+ support multiple character sets within one database, this view only
+ shows one, which is the database encoding.
+ </p><p>
+ Take note of how the following terms are used in the SQL standard:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">character repertoire</span></dt><dd><p>
+ An abstract collection of characters, for
+ example <code class="literal">UNICODE</code>, <code class="literal">UCS</code>, or
+ <code class="literal">LATIN1</code>. Not exposed as an SQL object, but
+ visible in this view.
+ </p></dd><dt><span class="term">character encoding form</span></dt><dd><p>
+ An encoding of some character repertoire. Most older character
+ repertoires only use one encoding form, and so there are no
+ separate names for them (e.g., <code class="literal">LATIN1</code> is an
+ encoding form applicable to the <code class="literal">LATIN1</code>
+ repertoire). But for example Unicode has the encoding forms
+ <code class="literal">UTF8</code>, <code class="literal">UTF16</code>, etc. (not
+ all supported by PostgreSQL). Encoding forms are not exposed
+ as an SQL object, but are visible in this view.
+ </p></dd><dt><span class="term">character set</span></dt><dd><p>
+ A named SQL object that identifies a character repertoire, a
+ character encoding, and a default collation. A predefined
+ character set would typically have the same name as an encoding
+ form, but users could define other names. For example, the
+ character set <code class="literal">UTF8</code> would typically identify
+ the character repertoire <code class="literal">UCS</code>, encoding
+ form <code class="literal">UTF8</code>, and some default collation.
+ </p></dd></dl></div><p>
+
+ You can think of an <span class="quote">“<span class="quote">encoding</span>”</span> in PostgreSQL either as
+ a character set or a character encoding form. They will have the
+ same name, and there can only be one in one database.
+ </p><div class="table" id="id-1.7.6.11.4"><p class="title"><strong>Table 37.5. <code class="structname">character_sets</code> Columns</strong></p><div class="table-contents"><table class="table" summary="character_sets Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Character sets are currently not implemented as schema objects, so this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Character sets are currently not implemented as schema objects, so this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the character set, currently implemented as showing the name of the database encoding
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_repertoire</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Character repertoire, showing <code class="literal">UCS</code> if the encoding is <code class="literal">UTF8</code>, else just the encoding name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">form_of_use</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Character encoding form, same as the database encoding
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_collate_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the default collation (always the current database, if any collation is identified)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_collate_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the default collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_collate_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the default collation. The default collation is
+ identified as the collation that matches
+ the <code class="literal">COLLATE</code> and <code class="literal">CTYPE</code>
+ settings of the current database. If there is no such
+ collation, then this column and the associated schema and
+ catalog columns are null.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-attributes.html" title="37.6. attributes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-check-constraint-routine-usage.html" title="37.8. check_constraint_routine_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.6. <code class="literal">attributes</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.8. <code class="literal">check_constraint_routine_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-check-constraint-routine-usage.html b/doc/src/sgml/html/infoschema-check-constraint-routine-usage.html
new file mode 100644
index 0000000..8545f0b
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-check-constraint-routine-usage.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.8. check_constraint_routine_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-character-sets.html" title="37.7. character_sets" /><link rel="next" href="infoschema-check-constraints.html" title="37.9. check_constraints" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.8. <code class="literal">check_constraint_routine_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-character-sets.html" title="37.7. character_sets">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-check-constraints.html" title="37.9. check_constraints">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-CHECK-CONSTRAINT-ROUTINE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.8. <code class="literal">check_constraint_routine_usage</code></h2></div></div></div><p>
+ The view <code class="literal">check_constraint_routine_usage</code>
+ identifies routines (functions and procedures) that are used by a
+ check constraint. Only those routines are shown that are owned by
+ a currently enabled role.
+ </p><div class="table" id="id-1.7.6.12.3"><p class="title"><strong>Table 37.6. <code class="structname">check_constraint_routine_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="check_constraint_routine_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-character-sets.html" title="37.7. character_sets">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-check-constraints.html" title="37.9. check_constraints">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.7. <code class="literal">character_sets</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.9. <code class="literal">check_constraints</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-check-constraints.html b/doc/src/sgml/html/infoschema-check-constraints.html
new file mode 100644
index 0000000..36a40e0
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-check-constraints.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.9. check_constraints</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-check-constraint-routine-usage.html" title="37.8. check_constraint_routine_usage" /><link rel="next" href="infoschema-collations.html" title="37.10. collations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.9. <code class="literal">check_constraints</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-check-constraint-routine-usage.html" title="37.8. check_constraint_routine_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-collations.html" title="37.10. collations">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-CHECK-CONSTRAINTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.9. <code class="literal">check_constraints</code></h2></div></div></div><p>
+ The view <code class="literal">check_constraints</code> contains all check
+ constraints, either defined on a table or on a domain, that are
+ owned by a currently enabled role. (The owner of the table or
+ domain is the owner of the constraint.)
+ </p><div class="table" id="id-1.7.6.13.3"><p class="title"><strong>Table 37.7. <code class="structname">check_constraints</code> Columns</strong></p><div class="table-contents"><table class="table" summary="check_constraints Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">check_clause</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The check expression of the check constraint
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-check-constraint-routine-usage.html" title="37.8. check_constraint_routine_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-collations.html" title="37.10. collations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.8. <code class="literal">check_constraint_routine_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.10. <code class="literal">collations</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-collation-character-set-applicab.html b/doc/src/sgml/html/infoschema-collation-character-set-applicab.html
new file mode 100644
index 0000000..c3ab01f
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-collation-character-set-applicab.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.11. collation_character_set_​applicability</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-collations.html" title="37.10. collations" /><link rel="next" href="infoschema-column-column-usage.html" title="37.12. column_column_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.11. <code class="literal">collation_character_set_​applicability</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-collations.html" title="37.10. collations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-column-column-usage.html" title="37.12. column_column_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLLATION-CHARACTER-SET-APPLICAB"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.11. <code class="literal">collation_character_set_​applicability</code></h2></div></div></div><p>
+ The view <code class="literal">collation_character_set_applicability</code>
+ identifies which character set the available collations are
+ applicable to. In PostgreSQL, there is only one character set per
+ database (see explanation
+ in <a class="xref" href="infoschema-character-sets.html" title="37.7. character_sets">Section 37.7</a>), so this view does
+ not provide much useful information.
+ </p><div class="table" id="id-1.7.6.15.3"><p class="title"><strong>Table 37.9. <code class="structname">collation_character_set_applicability</code> Columns</strong></p><div class="table-contents"><table class="table" summary="collation_character_set_applicability Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the collation (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the default collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Character sets are currently not implemented as schema objects, so this column is null
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Character sets are currently not implemented as schema objects, so this column is null
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the character set
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-collations.html" title="37.10. collations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-column-column-usage.html" title="37.12. column_column_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.10. <code class="literal">collations</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.12. <code class="literal">column_column_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-collations.html b/doc/src/sgml/html/infoschema-collations.html
new file mode 100644
index 0000000..b683fc4
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-collations.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.10. collations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-check-constraints.html" title="37.9. check_constraints" /><link rel="next" href="infoschema-collation-character-set-applicab.html" title="37.11. collation_character_set_​applicability" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.10. <code class="literal">collations</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-check-constraints.html" title="37.9. check_constraints">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-collation-character-set-applicab.html" title="37.11. collation_character_set_​applicability">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLLATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.10. <code class="literal">collations</code></h2></div></div></div><p>
+ The view <code class="literal">collations</code> contains the collations
+ available in the current database.
+ </p><div class="table" id="id-1.7.6.14.3"><p class="title"><strong>Table 37.8. <code class="structname">collations</code> Columns</strong></p><div class="table-contents"><table class="table" summary="collations Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the collation (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the default collation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pad_attribute</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">NO PAD</code> (The alternative <code class="literal">PAD
+ SPACE</code> is not supported by PostgreSQL.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-check-constraints.html" title="37.9. check_constraints">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-collation-character-set-applicab.html" title="37.11. collation_character_set_​applicability">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.9. <code class="literal">check_constraints</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.11. <code class="literal">collation_character_set_​applicability</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-column-column-usage.html b/doc/src/sgml/html/infoschema-column-column-usage.html
new file mode 100644
index 0000000..36c0436
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-column-column-usage.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.12. column_column_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-collation-character-set-applicab.html" title="37.11. collation_character_set_​applicability" /><link rel="next" href="infoschema-column-domain-usage.html" title="37.13. column_domain_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.12. <code class="literal">column_column_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-collation-character-set-applicab.html" title="37.11. collation_character_set_​applicability">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-column-domain-usage.html" title="37.13. column_domain_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLUMN-COLUMN-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.12. <code class="literal">column_column_usage</code></h2></div></div></div><p>
+ The view <code class="literal">column_column_usage</code> identifies all generated
+ columns that depend on another base column in the same table. Only tables
+ owned by a currently enabled role are included.
+ </p><div class="table" id="id-1.7.6.16.3"><p class="title"><strong>Table 37.10. <code class="structname">column_column_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="column_column_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the base column that a generated column depends on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dependent_column</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the generated column
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-collation-character-set-applicab.html" title="37.11. collation_character_set_​applicability">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-column-domain-usage.html" title="37.13. column_domain_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.11. <code class="literal">collation_character_set_​applicability</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.13. <code class="literal">column_domain_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-column-domain-usage.html b/doc/src/sgml/html/infoschema-column-domain-usage.html
new file mode 100644
index 0000000..695dc42
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-column-domain-usage.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.13. column_domain_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-column-column-usage.html" title="37.12. column_column_usage" /><link rel="next" href="infoschema-column-options.html" title="37.14. column_options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.13. <code class="literal">column_domain_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-column-column-usage.html" title="37.12. column_column_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-column-options.html" title="37.14. column_options">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLUMN-DOMAIN-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.13. <code class="literal">column_domain_usage</code></h2></div></div></div><p>
+ The view <code class="literal">column_domain_usage</code> identifies all
+ columns (of a table or a view) that make use of some domain defined
+ in the current database and owned by a currently enabled role.
+ </p><div class="table" id="id-1.7.6.17.3"><p class="title"><strong>Table 37.11. <code class="structname">column_domain_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="column_domain_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the domain (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-column-column-usage.html" title="37.12. column_column_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-column-options.html" title="37.14. column_options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.12. <code class="literal">column_column_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.14. <code class="literal">column_options</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-column-options.html b/doc/src/sgml/html/infoschema-column-options.html
new file mode 100644
index 0000000..61702a2
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-column-options.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.14. column_options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-column-domain-usage.html" title="37.13. column_domain_usage" /><link rel="next" href="infoschema-column-privileges.html" title="37.15. column_privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.14. <code class="literal">column_options</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-column-domain-usage.html" title="37.13. column_domain_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-column-privileges.html" title="37.15. column_privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLUMN-OPTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.14. <code class="literal">column_options</code></h2></div></div></div><p>
+ The view <code class="literal">column_options</code> contains all the
+ options defined for foreign table columns in the current database. Only
+ those foreign table columns are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.18.3"><p class="title"><strong>Table 37.12. <code class="structname">column_options</code> Columns</strong></p><div class="table-contents"><table class="table" summary="column_options Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the foreign table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of an option
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Value of the option
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-column-domain-usage.html" title="37.13. column_domain_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-column-privileges.html" title="37.15. column_privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.13. <code class="literal">column_domain_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.15. <code class="literal">column_privileges</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-column-privileges.html b/doc/src/sgml/html/infoschema-column-privileges.html
new file mode 100644
index 0000000..771bfdd
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-column-privileges.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.15. column_privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-column-options.html" title="37.14. column_options" /><link rel="next" href="infoschema-column-udt-usage.html" title="37.16. column_udt_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.15. <code class="literal">column_privileges</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-column-options.html" title="37.14. column_options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-column-udt-usage.html" title="37.16. column_udt_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLUMN-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.15. <code class="literal">column_privileges</code></h2></div></div></div><p>
+ The view <code class="literal">column_privileges</code> identifies all
+ privileges granted on columns to a currently enabled role or by a
+ currently enabled role. There is one row for each combination of
+ column, grantor, and grantee.
+ </p><p>
+ If a privilege has been granted on an entire table, it will show up in
+ this view as a grant for each column, but only for the
+ privilege types where column granularity is possible:
+ <code class="literal">SELECT</code>, <code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, <code class="literal">REFERENCES</code>.
+ </p><div class="table" id="id-1.7.6.19.4"><p class="title"><strong>Table 37.13. <code class="structname">column_privileges</code> Columns</strong></p><div class="table-contents"><table class="table" summary="column_privileges Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that contains the column (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that contains the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that contains the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Type of the privilege: <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, or
+ <code class="literal">REFERENCES</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-column-options.html" title="37.14. column_options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-column-udt-usage.html" title="37.16. column_udt_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.14. <code class="literal">column_options</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.16. <code class="literal">column_udt_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-column-udt-usage.html b/doc/src/sgml/html/infoschema-column-udt-usage.html
new file mode 100644
index 0000000..fd87388
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-column-udt-usage.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.16. column_udt_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-column-privileges.html" title="37.15. column_privileges" /><link rel="next" href="infoschema-columns.html" title="37.17. columns" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.16. <code class="literal">column_udt_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-column-privileges.html" title="37.15. column_privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-columns.html" title="37.17. columns">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLUMN-UDT-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.16. <code class="literal">column_udt_usage</code></h2></div></div></div><p>
+ The view <code class="literal">column_udt_usage</code> identifies all columns
+ that use data types owned by a currently enabled role. Note that in
+ <span class="productname">PostgreSQL</span>, built-in data types behave
+ like user-defined types, so they are included here as well. See
+ also <a class="xref" href="infoschema-columns.html" title="37.17. columns">Section 37.17</a> for details.
+ </p><div class="table" id="id-1.7.6.20.3"><p class="title"><strong>Table 37.14. <code class="structname">column_udt_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="column_udt_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the column data type (the underlying
+ type of the domain, if applicable) is defined in (always the
+ current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the column data type (the underlying
+ type of the domain, if applicable) is defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column data type (the underlying type of the
+ domain, if applicable)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-column-privileges.html" title="37.15. column_privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-columns.html" title="37.17. columns">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.15. <code class="literal">column_privileges</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.17. <code class="literal">columns</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-columns.html b/doc/src/sgml/html/infoschema-columns.html
new file mode 100644
index 0000000..978df68
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-columns.html
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.17. columns</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-column-udt-usage.html" title="37.16. column_udt_usage" /><link rel="next" href="infoschema-constraint-column-usage.html" title="37.18. constraint_column_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.17. <code class="literal">columns</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-column-udt-usage.html" title="37.16. column_udt_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-constraint-column-usage.html" title="37.18. constraint_column_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-COLUMNS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.17. <code class="literal">columns</code></h2></div></div></div><p>
+ The view <code class="literal">columns</code> contains information about all
+ table columns (or view columns) in the database. System columns
+ (<code class="literal">ctid</code>, etc.) are not included. Only those columns are
+ shown that the current user has access to (by way of being the
+ owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.21.3"><p class="title"><strong>Table 37.15. <code class="structname">columns</code> Columns</strong></p><div class="table-contents"><table class="table" summary="columns Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordinal_position</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Ordinal position of the column within the table (count starts at 1)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_default</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Default expression of the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_nullable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the column is possibly nullable,
+ <code class="literal">NO</code> if it is known not nullable. A not-null
+ constraint is one way a column can be known not nullable, but
+ there can be others.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Data type of the column, if it is a built-in type, or
+ <code class="literal">ARRAY</code> if it is some array (in that case, see
+ the view <code class="literal">element_types</code>), else
+ <code class="literal">USER-DEFINED</code> (in that case, the type is
+ identified in <code class="literal">udt_name</code> and associated
+ columns). If the column is based on a domain, this column
+ refers to the type underlying the domain (and the domain is
+ identified in <code class="literal">domain_name</code> and associated
+ columns).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a character or bit
+ string type, the declared maximum length; null for all other
+ data types or if no maximum length was declared.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a character type,
+ the maximum possible length in octets (bytes) of a datum; null
+ for all other data types. The maximum octet length depends on
+ the declared character maximum length (see above) and the
+ server encoding.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a numeric type, this
+ column contains the (declared or implicit) precision of the
+ type for this column. The precision indicates the number of
+ significant digits. It can be expressed in decimal (base 10)
+ or binary (base 2) terms, as specified in the column
+ <code class="literal">numeric_precision_radix</code>. For all other data
+ types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a numeric type, this
+ column indicates in which base the values in the columns
+ <code class="literal">numeric_precision</code> and
+ <code class="literal">numeric_scale</code> are expressed. The value is
+ either 2 or 10. For all other data types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies an exact numeric
+ type, this column contains the (declared or implicit) scale of
+ the type for this column. The scale indicates the number of
+ significant digits to the right of the decimal point. It can
+ be expressed in decimal (base 10) or binary (base 2) terms, as
+ specified in the column
+ <code class="literal">numeric_precision_radix</code>. For all other data
+ types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a date, time,
+ timestamp, or interval type, this column contains the (declared
+ or implicit) fractional seconds precision of the type for this
+ column, that is, the number of decimal digits maintained
+ following the decimal point in the seconds value. For all
+ other data types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies an interval type,
+ this column contains the specification which fields the
+ intervals include for this column, e.g., <code class="literal">YEAR TO
+ MONTH</code>, <code class="literal">DAY TO SECOND</code>, etc. If no
+ field restrictions were specified (that is, the interval
+ accepts all fields), and for all other data types, this field
+ is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available
+ in <span class="productname">PostgreSQL</span>
+ (see <code class="literal">datetime_precision</code> for the fractional
+ seconds precision of interval type columns)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the collation of the column
+ (always the current database), null if default or the data type
+ of the column is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the collation of the column, null
+ if default or the data type of the column is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the collation of the column, null if default or the
+ data type of the column is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ If the column has a domain type, the name of the database that
+ the domain is defined in (always the current database), else
+ null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ If the column has a domain type, the name of the schema that
+ the domain is defined in, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ If the column has a domain type, the name of the domain, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the column data type (the underlying
+ type of the domain, if applicable) is defined in (always the
+ current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the column data type (the underlying
+ type of the domain, if applicable) is defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column data type (the underlying type of the
+ domain, if applicable)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, because arrays always have unlimited maximum cardinality in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ An identifier of the data type descriptor of the column, unique
+ among the data type descriptors pertaining to the table. This
+ is mainly useful for joining with other instances of such
+ identifiers. (The specific format of the identifier is not
+ defined and not guaranteed to remain the same in future
+ versions.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_self_referencing</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_identity</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ If the column is an identity column, then <code class="literal">YES</code>,
+ else <code class="literal">NO</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">identity_generation</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is an identity column, then <code class="literal">ALWAYS</code>
+ or <code class="literal">BY DEFAULT</code>, reflecting the definition of the
+ column.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">identity_start</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is an identity column, then the start value of the
+ internal sequence, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">identity_increment</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is an identity column, then the increment of the internal
+ sequence, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">identity_maximum</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is an identity column, then the maximum value of the
+ internal sequence, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">identity_minimum</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is an identity column, then the minimum value of the
+ internal sequence, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">identity_cycle</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ If the column is an identity column, then <code class="literal">YES</code> if the
+ internal sequence cycles or <code class="literal">NO</code> if it does not;
+ otherwise null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_generated</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is a generated column, then <code class="literal">ALWAYS</code>,
+ else <code class="literal">NEVER</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">generation_expression</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the column is a generated column, then the generation expression,
+ else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_updatable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the column is updatable,
+ <code class="literal">NO</code> if not (Columns in base tables are always
+ updatable, columns in views not necessarily)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Since data types can be defined in a variety of ways in SQL, and
+ <span class="productname">PostgreSQL</span> contains additional ways to
+ define data types, their representation in the information schema
+ can be somewhat difficult. The column <code class="literal">data_type</code>
+ is supposed to identify the underlying built-in type of the column.
+ In <span class="productname">PostgreSQL</span>, this means that the type
+ is defined in the system catalog schema
+ <code class="literal">pg_catalog</code>. This column might be useful if the
+ application can handle the well-known built-in types specially (for
+ example, format the numeric types differently or use the data in
+ the precision columns). The columns <code class="literal">udt_name</code>,
+ <code class="literal">udt_schema</code>, and <code class="literal">udt_catalog</code>
+ always identify the underlying data type of the column, even if the
+ column is based on a domain. (Since
+ <span class="productname">PostgreSQL</span> treats built-in types like
+ user-defined types, built-in types appear here as well. This is an
+ extension of the SQL standard.) These columns should be used if an
+ application wants to process data differently according to the
+ type, because in that case it wouldn't matter if the column is
+ really based on a domain. If the column is based on a domain, the
+ identity of the domain is stored in the columns
+ <code class="literal">domain_name</code>, <code class="literal">domain_schema</code>,
+ and <code class="literal">domain_catalog</code>. If you want to pair up
+ columns with their associated data types and treat domains as
+ separate types, you could write <code class="literal">coalesce(domain_name,
+ udt_name)</code>, etc.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-column-udt-usage.html" title="37.16. column_udt_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-constraint-column-usage.html" title="37.18. constraint_column_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.16. <code class="literal">column_udt_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.18. <code class="literal">constraint_column_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-constraint-column-usage.html b/doc/src/sgml/html/infoschema-constraint-column-usage.html
new file mode 100644
index 0000000..00f5d36
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-constraint-column-usage.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.18. constraint_column_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-columns.html" title="37.17. columns" /><link rel="next" href="infoschema-constraint-table-usage.html" title="37.19. constraint_table_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.18. <code class="literal">constraint_column_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-columns.html" title="37.17. columns">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-constraint-table-usage.html" title="37.19. constraint_table_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-CONSTRAINT-COLUMN-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.18. <code class="literal">constraint_column_usage</code></h2></div></div></div><p>
+ The view <code class="literal">constraint_column_usage</code> identifies all
+ columns in the current database that are used by some constraint.
+ Only those columns are shown that are contained in a table owned by
+ a currently enabled role. For a check constraint, this view
+ identifies the columns that are used in the check expression. For
+ a foreign key constraint, this view identifies the columns that the
+ foreign key references. For a unique or primary key constraint,
+ this view identifies the constrained columns.
+ </p><div class="table" id="id-1.7.6.22.3"><p class="title"><strong>Table 37.16. <code class="structname">constraint_column_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="constraint_column_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that contains the
+ column that is used by some constraint (always the current
+ database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that contains the
+ column that is used by some constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that contains the column that is used by some
+ constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column that is used by some constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-columns.html" title="37.17. columns">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-constraint-table-usage.html" title="37.19. constraint_table_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.17. <code class="literal">columns</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.19. <code class="literal">constraint_table_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-constraint-table-usage.html b/doc/src/sgml/html/infoschema-constraint-table-usage.html
new file mode 100644
index 0000000..e439db8
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-constraint-table-usage.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.19. constraint_table_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-constraint-column-usage.html" title="37.18. constraint_column_usage" /><link rel="next" href="infoschema-data-type-privileges.html" title="37.20. data_type_privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.19. <code class="literal">constraint_table_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-constraint-column-usage.html" title="37.18. constraint_column_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-data-type-privileges.html" title="37.20. data_type_privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-CONSTRAINT-TABLE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.19. <code class="literal">constraint_table_usage</code></h2></div></div></div><p>
+ The view <code class="literal">constraint_table_usage</code> identifies all
+ tables in the current database that are used by some constraint and
+ are owned by a currently enabled role. (This is different from the
+ view <code class="literal">table_constraints</code>, which identifies all
+ table constraints along with the table they are defined on.) For a
+ foreign key constraint, this view identifies the table that the
+ foreign key references. For a unique or primary key constraint,
+ this view simply identifies the table the constraint belongs to.
+ Check constraints and not-null constraints are not included in this
+ view.
+ </p><div class="table" id="id-1.7.6.23.3"><p class="title"><strong>Table 37.17. <code class="structname">constraint_table_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="constraint_table_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that is used by
+ some constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that is used by some
+ constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that is used by some constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-constraint-column-usage.html" title="37.18. constraint_column_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-data-type-privileges.html" title="37.20. data_type_privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.18. <code class="literal">constraint_column_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.20. <code class="literal">data_type_privileges</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-data-type-privileges.html b/doc/src/sgml/html/infoschema-data-type-privileges.html
new file mode 100644
index 0000000..b89a775
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-data-type-privileges.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.20. data_type_privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-constraint-table-usage.html" title="37.19. constraint_table_usage" /><link rel="next" href="infoschema-domain-constraints.html" title="37.21. domain_constraints" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.20. <code class="literal">data_type_privileges</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-constraint-table-usage.html" title="37.19. constraint_table_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-domain-constraints.html" title="37.21. domain_constraints">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-DATA-TYPE-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.20. <code class="literal">data_type_privileges</code></h2></div></div></div><p>
+ The view <code class="literal">data_type_privileges</code> identifies all
+ data type descriptors that the current user has access to, by way
+ of being the owner of the described object or having some privilege
+ for it. A data type descriptor is generated whenever a data type
+ is used in the definition of a table column, a domain, or a
+ function (as parameter or return type) and stores some information
+ about how the data type is used in that instance (for example, the
+ declared maximum length, if applicable). Each data type
+ descriptor is assigned an arbitrary identifier that is unique
+ among the data type descriptor identifiers assigned for one object
+ (table, domain, function). This view is probably not useful for
+ applications, but it is used to define some other views in the
+ information schema.
+ </p><div class="table" id="id-1.7.6.24.3"><p class="title"><strong>Table 37.18. <code class="structname">data_type_privileges</code> Columns</strong></p><div class="table-contents"><table class="table" summary="data_type_privileges Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the described object (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the described object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the described object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The type of the described object: one of
+ <code class="literal">TABLE</code> (the data type descriptor pertains to
+ a column of that table), <code class="literal">DOMAIN</code> (the data
+ type descriptors pertains to that domain),
+ <code class="literal">ROUTINE</code> (the data type descriptor pertains
+ to a parameter or the return data type of that function).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The identifier of the data type descriptor, which is unique
+ among the data type descriptors for that same object.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-constraint-table-usage.html" title="37.19. constraint_table_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-domain-constraints.html" title="37.21. domain_constraints">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.19. <code class="literal">constraint_table_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.21. <code class="literal">domain_constraints</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-datatypes.html b/doc/src/sgml/html/infoschema-datatypes.html
new file mode 100644
index 0000000..0a63bc6
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-datatypes.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.2. Data Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-schema.html" title="37.1. The Schema" /><link rel="next" href="infoschema-information-schema-catalog-name.html" title="37.3. information_schema_catalog_name" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.2. Data Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-schema.html" title="37.1. The Schema">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-information-schema-catalog-name.html" title="37.3. information_schema_catalog_name">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-DATATYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.2. Data Types</h2></div></div></div><p>
+ The columns of the information schema views use special data types
+ that are defined in the information schema. These are defined as
+ simple domains over ordinary built-in types. You should not use
+ these types for work outside the information schema, but your
+ applications must be prepared for them if they select from the
+ information schema.
+ </p><p>
+ These types are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="type">cardinal_number</code></span></dt><dd><p>
+ A nonnegative integer.
+ </p></dd><dt><span class="term"><code class="type">character_data</code></span></dt><dd><p>
+ A character string (without specific maximum length).
+ </p></dd><dt><span class="term"><code class="type">sql_identifier</code></span></dt><dd><p>
+ A character string. This type is used for SQL identifiers, the
+ type <code class="type">character_data</code> is used for any other kind of
+ text data.
+ </p></dd><dt><span class="term"><code class="type">time_stamp</code></span></dt><dd><p>
+ A domain over the type <code class="type">timestamp with time zone</code>
+ </p></dd><dt><span class="term"><code class="type">yes_or_no</code></span></dt><dd><p>
+ A character string domain that contains
+ either <code class="literal">YES</code> or <code class="literal">NO</code>. This
+ is used to represent Boolean (true/false) data in the
+ information schema. (The information schema was invented
+ before the type <code class="type">boolean</code> was added to the SQL
+ standard, so this convention is necessary to keep the
+ information schema backward compatible.)
+ </p></dd></dl></div><p>
+
+ Every column in the information schema has one of these five types.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-schema.html" title="37.1. The Schema">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-information-schema-catalog-name.html" title="37.3. information_schema_catalog_name">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.1. The Schema </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.3. <code class="literal">information_schema_catalog_name</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-domain-constraints.html b/doc/src/sgml/html/infoschema-domain-constraints.html
new file mode 100644
index 0000000..ccc7db1
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-domain-constraints.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.21. domain_constraints</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-data-type-privileges.html" title="37.20. data_type_privileges" /><link rel="next" href="infoschema-domain-udt-usage.html" title="37.22. domain_udt_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.21. <code class="literal">domain_constraints</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-data-type-privileges.html" title="37.20. data_type_privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-domain-udt-usage.html" title="37.22. domain_udt_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-DOMAIN-CONSTRAINTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.21. <code class="literal">domain_constraints</code></h2></div></div></div><p>
+ The view <code class="literal">domain_constraints</code> contains all constraints
+ belonging to domains defined in the current database. Only those domains
+ are shown that the current user has access to (by way of being the owner or
+ having some privilege).
+ </p><div class="table" id="id-1.7.6.25.3"><p class="title"><strong>Table 37.19. <code class="structname">domain_constraints</code> Columns</strong></p><div class="table-contents"><table class="table" summary="domain_constraints Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the domain (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_deferrable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the constraint is deferrable, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">initially_deferred</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the constraint is deferrable and initially deferred, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-data-type-privileges.html" title="37.20. data_type_privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-domain-udt-usage.html" title="37.22. domain_udt_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.20. <code class="literal">data_type_privileges</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.22. <code class="literal">domain_udt_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-domain-udt-usage.html b/doc/src/sgml/html/infoschema-domain-udt-usage.html
new file mode 100644
index 0000000..12ec545
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-domain-udt-usage.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.22. domain_udt_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-domain-constraints.html" title="37.21. domain_constraints" /><link rel="next" href="infoschema-domains.html" title="37.23. domains" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.22. <code class="literal">domain_udt_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-domain-constraints.html" title="37.21. domain_constraints">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-domains.html" title="37.23. domains">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-DOMAIN-UDT-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.22. <code class="literal">domain_udt_usage</code></h2></div></div></div><p>
+ The view <code class="literal">domain_udt_usage</code> identifies all domains
+ that are based on data types owned by a currently enabled role.
+ Note that in <span class="productname">PostgreSQL</span>, built-in data
+ types behave like user-defined types, so they are included here as
+ well.
+ </p><div class="table" id="id-1.7.6.26.3"><p class="title"><strong>Table 37.20. <code class="structname">domain_udt_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="domain_udt_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the domain data type is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the domain data type is defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the domain data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the domain (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the domain
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-domain-constraints.html" title="37.21. domain_constraints">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-domains.html" title="37.23. domains">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.21. <code class="literal">domain_constraints</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.23. <code class="literal">domains</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-domains.html b/doc/src/sgml/html/infoschema-domains.html
new file mode 100644
index 0000000..fbba2f5
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-domains.html
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.23. domains</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-domain-udt-usage.html" title="37.22. domain_udt_usage" /><link rel="next" href="infoschema-element-types.html" title="37.24. element_types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.23. <code class="literal">domains</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-domain-udt-usage.html" title="37.22. domain_udt_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-element-types.html" title="37.24. element_types">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-DOMAINS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.23. <code class="literal">domains</code></h2></div></div></div><p>
+ The view <code class="literal">domains</code> contains all
+ <a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN" title="Domain">domains</a></em></a> defined in the
+ current database. Only those domains are shown that the current user has
+ access to (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.27.3"><p class="title"><strong>Table 37.21. <code class="structname">domains</code> Columns</strong></p><div class="table-contents"><table class="table" summary="domains Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the domain (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Data type of the domain, if it is a built-in type, or
+ <code class="literal">ARRAY</code> if it is some array (in that case, see
+ the view <code class="literal">element_types</code>), else
+ <code class="literal">USER-DEFINED</code> (in that case, the type is
+ identified in <code class="literal">udt_name</code> and associated
+ columns).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If the domain has a character or bit string type, the declared
+ maximum length; null for all other data types or if no maximum
+ length was declared.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If the domain has a character type, the maximum possible length
+ in octets (bytes) of a datum; null for all other data types.
+ The maximum octet length depends on the declared character
+ maximum length (see above) and the server encoding.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the collation of the domain
+ (always the current database), null if default or the data type
+ of the domain is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the collation of the domain, null
+ if default or the data type of the domain is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the collation of the domain, null if default or the
+ data type of the domain is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If the domain has a numeric type, this column contains the
+ (declared or implicit) precision of the type for this domain.
+ The precision indicates the number of significant digits. It
+ can be expressed in decimal (base 10) or binary (base 2) terms,
+ as specified in the column
+ <code class="literal">numeric_precision_radix</code>. For all other data
+ types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If the domain has a numeric type, this column indicates in
+ which base the values in the columns
+ <code class="literal">numeric_precision</code> and
+ <code class="literal">numeric_scale</code> are expressed. The value is
+ either 2 or 10. For all other data types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If the domain has an exact numeric type, this column contains
+ the (declared or implicit) scale of the type for this domain.
+ The scale indicates the number of significant digits to the
+ right of the decimal point. It can be expressed in decimal
+ (base 10) or binary (base 2) terms, as specified in the column
+ <code class="literal">numeric_precision_radix</code>. For all other data
+ types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies a date, time,
+ timestamp, or interval type, this column contains the (declared
+ or implicit) fractional seconds precision of the type for this
+ domain, that is, the number of decimal digits maintained
+ following the decimal point in the seconds value. For all
+ other data types, this column is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If <code class="literal">data_type</code> identifies an interval type,
+ this column contains the specification which fields the
+ intervals include for this domain, e.g., <code class="literal">YEAR TO
+ MONTH</code>, <code class="literal">DAY TO SECOND</code>, etc. If no
+ field restrictions were specified (that is, the interval
+ accepts all fields), and for all other data types, this field
+ is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available
+ in <span class="productname">PostgreSQL</span>
+ (see <code class="literal">datetime_precision</code> for the fractional
+ seconds precision of interval type domains)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_default</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Default expression of the domain
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the domain data type is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the domain data type is defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the domain data type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, because arrays always have unlimited maximum cardinality in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ An identifier of the data type descriptor of the domain, unique
+ among the data type descriptors pertaining to the domain (which
+ is trivial, because a domain only contains one data type
+ descriptor). This is mainly useful for joining with other
+ instances of such identifiers. (The specific format of the
+ identifier is not defined and not guaranteed to remain the same
+ in future versions.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-domain-udt-usage.html" title="37.22. domain_udt_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-element-types.html" title="37.24. element_types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.22. <code class="literal">domain_udt_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.24. <code class="literal">element_types</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-element-types.html b/doc/src/sgml/html/infoschema-element-types.html
new file mode 100644
index 0000000..206d889
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-element-types.html
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.24. element_types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-domains.html" title="37.23. domains" /><link rel="next" href="infoschema-enabled-roles.html" title="37.25. enabled_roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.24. <code class="literal">element_types</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-domains.html" title="37.23. domains">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-enabled-roles.html" title="37.25. enabled_roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ELEMENT-TYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.24. <code class="literal">element_types</code></h2></div></div></div><p>
+ The view <code class="literal">element_types</code> contains the data type
+ descriptors of the elements of arrays. When a table column, composite-type attribute,
+ domain, function parameter, or function return value is defined to
+ be of an array type, the respective information schema view only
+ contains <code class="literal">ARRAY</code> in the column
+ <code class="literal">data_type</code>. To obtain information on the element
+ type of the array, you can join the respective view with this view.
+ For example, to show the columns of a table with data types and
+ array element types, if applicable, you could do:
+</p><pre class="programlisting">
+SELECT c.column_name, c.data_type, e.data_type AS element_type
+FROM information_schema.columns c LEFT JOIN information_schema.element_types e
+ ON ((c.table_catalog, c.table_schema, c.table_name, 'TABLE', c.dtd_identifier)
+ = (e.object_catalog, e.object_schema, e.object_name, e.object_type, e.collection_type_identifier))
+WHERE c.table_schema = '...' AND c.table_name = '...'
+ORDER BY c.ordinal_position;
+</pre><p>
+ This view only includes objects that the current user has access
+ to, by way of being the owner or having some privilege.
+ </p><div class="table" id="id-1.7.6.28.3"><p class="title"><strong>Table 37.22. <code class="structname">element_types</code> Columns</strong></p><div class="table-contents"><table class="table" summary="element_types Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the object that uses the
+ array being described (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the object that uses the array
+ being described
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the object that uses the array being described
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The type of the object that uses the array being described: one
+ of <code class="literal">TABLE</code> (the array is used by a column of
+ that table), <code class="literal">USER-DEFINED TYPE</code> (the array is
+ used by an attribute of that composite type),
+ <code class="literal">DOMAIN</code> (the array is used by that domain),
+ <code class="literal">ROUTINE</code> (the array is used by a parameter or
+ the return data type of that function).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collection_type_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The identifier of the data type descriptor of the array being
+ described. Use this to join with the
+ <code class="literal">dtd_identifier</code> columns of other information
+ schema views.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Data type of the array elements, if it is a built-in type, else
+ <code class="literal">USER-DEFINED</code> (in that case, the type is
+ identified in <code class="literal">udt_name</code> and associated
+ columns).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the collation of the element
+ type (always the current database), null if default or the data
+ type of the element is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the collation of the element
+ type, null if default or the data type of the element is not
+ collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the collation of the element type, null if default or
+ the data type of the element is not collatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to array element data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">domain_default</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Not yet implemented
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the data type of the elements is
+ defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the data type of the elements is
+ defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the data type of the elements
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, because arrays always have unlimited maximum cardinality in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ An identifier of the data type descriptor of the element. This
+ is currently not useful.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-domains.html" title="37.23. domains">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-enabled-roles.html" title="37.25. enabled_roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.23. <code class="literal">domains</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.25. <code class="literal">enabled_roles</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-enabled-roles.html b/doc/src/sgml/html/infoschema-enabled-roles.html
new file mode 100644
index 0000000..3d31b80
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-enabled-roles.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.25. enabled_roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-element-types.html" title="37.24. element_types" /><link rel="next" href="infoschema-foreign-data-wrapper-options.html" title="37.26. foreign_data_wrapper_options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.25. <code class="literal">enabled_roles</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-element-types.html" title="37.24. element_types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-foreign-data-wrapper-options.html" title="37.26. foreign_data_wrapper_options">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ENABLED-ROLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.25. <code class="literal">enabled_roles</code></h2></div></div></div><p>
+ The view <code class="literal">enabled_roles</code> identifies the currently
+ <span class="quote">“<span class="quote">enabled roles</span>”</span>. The enabled roles are recursively
+ defined as the current user together with all roles that have been
+ granted to the enabled roles with automatic inheritance. In other
+ words, these are all roles that the current user has direct or
+ indirect, automatically inheriting membership in.
+ <a id="id-1.7.6.29.2.3" class="indexterm"></a>
+ <a id="id-1.7.6.29.2.4" class="indexterm"></a>
+ </p><p>
+ For permission checking, the set of <span class="quote">“<span class="quote">applicable roles</span>”</span>
+ is applied, which can be broader than the set of enabled roles. So
+ generally, it is better to use the view
+ <code class="literal">applicable_roles</code> instead of this one; See
+ <a class="xref" href="infoschema-applicable-roles.html" title="37.5. applicable_roles">Section 37.5</a> for details on
+ <code class="literal">applicable_roles</code> view.
+ </p><div class="table" id="id-1.7.6.29.4"><p class="title"><strong>Table 37.23. <code class="structname">enabled_roles</code> Columns</strong></p><div class="table-contents"><table class="table" summary="enabled_roles Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">role_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of a role
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-element-types.html" title="37.24. element_types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-foreign-data-wrapper-options.html" title="37.26. foreign_data_wrapper_options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.24. <code class="literal">element_types</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.26. <code class="literal">foreign_data_wrapper_options</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-foreign-data-wrapper-options.html b/doc/src/sgml/html/infoschema-foreign-data-wrapper-options.html
new file mode 100644
index 0000000..2d329ca
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-foreign-data-wrapper-options.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.26. foreign_data_wrapper_options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-enabled-roles.html" title="37.25. enabled_roles" /><link rel="next" href="infoschema-foreign-data-wrappers.html" title="37.27. foreign_data_wrappers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.26. <code class="literal">foreign_data_wrapper_options</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-enabled-roles.html" title="37.25. enabled_roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-foreign-data-wrappers.html" title="37.27. foreign_data_wrappers">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-FOREIGN-DATA-WRAPPER-OPTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.26. <code class="literal">foreign_data_wrapper_options</code></h2></div></div></div><p>
+ The view <code class="literal">foreign_data_wrapper_options</code> contains
+ all the options defined for foreign-data wrappers in the current
+ database. Only those foreign-data wrappers are shown that the
+ current user has access to (by way of being the owner or having
+ some privilege).
+ </p><div class="table" id="id-1.7.6.30.3"><p class="title"><strong>Table 37.24. <code class="structname">foreign_data_wrapper_options</code> Columns</strong></p><div class="table-contents"><table class="table" summary="foreign_data_wrapper_options Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign-data wrapper is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign-data wrapper
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of an option
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Value of the option
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-enabled-roles.html" title="37.25. enabled_roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-foreign-data-wrappers.html" title="37.27. foreign_data_wrappers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.25. <code class="literal">enabled_roles</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.27. <code class="literal">foreign_data_wrappers</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-foreign-data-wrappers.html b/doc/src/sgml/html/infoschema-foreign-data-wrappers.html
new file mode 100644
index 0000000..cec2a35
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-foreign-data-wrappers.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.27. foreign_data_wrappers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-foreign-data-wrapper-options.html" title="37.26. foreign_data_wrapper_options" /><link rel="next" href="infoschema-foreign-server-options.html" title="37.28. foreign_server_options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.27. <code class="literal">foreign_data_wrappers</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-foreign-data-wrapper-options.html" title="37.26. foreign_data_wrapper_options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-foreign-server-options.html" title="37.28. foreign_server_options">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-FOREIGN-DATA-WRAPPERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.27. <code class="literal">foreign_data_wrappers</code></h2></div></div></div><p>
+ The view <code class="literal">foreign_data_wrappers</code> contains all
+ foreign-data wrappers defined in the current database. Only those
+ foreign-data wrappers are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.31.3"><p class="title"><strong>Table 37.25. <code class="structname">foreign_data_wrappers</code> Columns</strong></p><div class="table-contents"><table class="table" summary="foreign_data_wrappers Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the foreign-data
+ wrapper (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign-data wrapper
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">authorization_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the owner of the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">library_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ File name of the library that implementing this foreign-data wrapper
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_language</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Language used to implement this foreign-data wrapper
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-foreign-data-wrapper-options.html" title="37.26. foreign_data_wrapper_options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-foreign-server-options.html" title="37.28. foreign_server_options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.26. <code class="literal">foreign_data_wrapper_options</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.28. <code class="literal">foreign_server_options</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-foreign-server-options.html b/doc/src/sgml/html/infoschema-foreign-server-options.html
new file mode 100644
index 0000000..05d4ee9
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-foreign-server-options.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.28. foreign_server_options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-foreign-data-wrappers.html" title="37.27. foreign_data_wrappers" /><link rel="next" href="infoschema-foreign-servers.html" title="37.29. foreign_servers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.28. <code class="literal">foreign_server_options</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-foreign-data-wrappers.html" title="37.27. foreign_data_wrappers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-foreign-servers.html" title="37.29. foreign_servers">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-FOREIGN-SERVER-OPTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.28. <code class="literal">foreign_server_options</code></h2></div></div></div><p>
+ The view <code class="literal">foreign_server_options</code> contains all the
+ options defined for foreign servers in the current database. Only
+ those foreign servers are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.32.3"><p class="title"><strong>Table 37.26. <code class="structname">foreign_server_options</code> Columns</strong></p><div class="table-contents"><table class="table" summary="foreign_server_options Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign server is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of an option
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Value of the option
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-foreign-data-wrappers.html" title="37.27. foreign_data_wrappers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-foreign-servers.html" title="37.29. foreign_servers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.27. <code class="literal">foreign_data_wrappers</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.29. <code class="literal">foreign_servers</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-foreign-servers.html b/doc/src/sgml/html/infoschema-foreign-servers.html
new file mode 100644
index 0000000..55f33d8
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-foreign-servers.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.29. foreign_servers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-foreign-server-options.html" title="37.28. foreign_server_options" /><link rel="next" href="infoschema-foreign-table-options.html" title="37.30. foreign_table_options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.29. <code class="literal">foreign_servers</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-foreign-server-options.html" title="37.28. foreign_server_options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-foreign-table-options.html" title="37.30. foreign_table_options">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-FOREIGN-SERVERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.29. <code class="literal">foreign_servers</code></h2></div></div></div><p>
+ The view <code class="literal">foreign_servers</code> contains all foreign
+ servers defined in the current database. Only those foreign
+ servers are shown that the current user has access to (by way of
+ being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.33.3"><p class="title"><strong>Table 37.27. <code class="structname">foreign_servers</code> Columns</strong></p><div class="table-contents"><table class="table" summary="foreign_servers Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign server is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the foreign-data
+ wrapper used by the foreign server (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_data_wrapper_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign-data wrapper used by the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Foreign server type information, if specified upon creation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_version</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Foreign server version information, if specified upon creation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">authorization_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the owner of the foreign server
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-foreign-server-options.html" title="37.28. foreign_server_options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-foreign-table-options.html" title="37.30. foreign_table_options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.28. <code class="literal">foreign_server_options</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.30. <code class="literal">foreign_table_options</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-foreign-table-options.html b/doc/src/sgml/html/infoschema-foreign-table-options.html
new file mode 100644
index 0000000..416ae57
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-foreign-table-options.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.30. foreign_table_options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-foreign-servers.html" title="37.29. foreign_servers" /><link rel="next" href="infoschema-foreign-tables.html" title="37.31. foreign_tables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.30. <code class="literal">foreign_table_options</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-foreign-servers.html" title="37.29. foreign_servers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-foreign-tables.html" title="37.31. foreign_tables">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-FOREIGN-TABLE-OPTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.30. <code class="literal">foreign_table_options</code></h2></div></div></div><p>
+ The view <code class="literal">foreign_table_options</code> contains all the
+ options defined for foreign tables in the current database. Only
+ those foreign tables are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.34.3"><p class="title"><strong>Table 37.28. <code class="structname">foreign_table_options</code> Columns</strong></p><div class="table-contents"><table class="table" summary="foreign_table_options Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the foreign table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of an option
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Value of the option
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-foreign-servers.html" title="37.29. foreign_servers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-foreign-tables.html" title="37.31. foreign_tables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.29. <code class="literal">foreign_servers</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.31. <code class="literal">foreign_tables</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-foreign-tables.html b/doc/src/sgml/html/infoschema-foreign-tables.html
new file mode 100644
index 0000000..64edcd2
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-foreign-tables.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.31. foreign_tables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-foreign-table-options.html" title="37.30. foreign_table_options" /><link rel="next" href="infoschema-key-column-usage.html" title="37.32. key_column_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.31. <code class="literal">foreign_tables</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-foreign-table-options.html" title="37.30. foreign_table_options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-key-column-usage.html" title="37.32. key_column_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-FOREIGN-TABLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.31. <code class="literal">foreign_tables</code></h2></div></div></div><p>
+ The view <code class="literal">foreign_tables</code> contains all foreign
+ tables defined in the current database. Only those foreign
+ tables are shown that the current user has access to (by way of
+ being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.35.3"><p class="title"><strong>Table 37.29. <code class="structname">foreign_tables</code> Columns</strong></p><div class="table-contents"><table class="table" summary="foreign_tables Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign table is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign server is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign server
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-foreign-table-options.html" title="37.30. foreign_table_options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-key-column-usage.html" title="37.32. key_column_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.30. <code class="literal">foreign_table_options</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.32. <code class="literal">key_column_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-information-schema-catalog-name.html b/doc/src/sgml/html/infoschema-information-schema-catalog-name.html
new file mode 100644
index 0000000..cb2d52a
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-information-schema-catalog-name.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.3. information_schema_catalog_name</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-datatypes.html" title="37.2. Data Types" /><link rel="next" href="infoschema-administrable-role-authorizations.html" title="37.4. administrable_role_​authorizations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.3. <code class="literal">information_schema_catalog_name</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-datatypes.html" title="37.2. Data Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-administrable-role-authorizations.html" title="37.4. administrable_role_​authorizations">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-INFORMATION-SCHEMA-CATALOG-NAME"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.3. <code class="literal">information_schema_catalog_name</code></h2></div></div></div><p>
+ <code class="literal">information_schema_catalog_name</code> is a table that
+ always contains one row and one column containing the name of the
+ current database (current catalog, in SQL terminology).
+ </p><div class="table" id="id-1.7.6.7.3"><p class="title"><strong>Table 37.1. <code class="structname">information_schema_catalog_name</code> Columns</strong></p><div class="table-contents"><table class="table" summary="information_schema_catalog_name Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">catalog_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains this information schema
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-datatypes.html" title="37.2. Data Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-administrable-role-authorizations.html" title="37.4. administrable_role_​authorizations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.2. Data Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.4. <code class="literal">administrable_role_​authorizations</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-key-column-usage.html b/doc/src/sgml/html/infoschema-key-column-usage.html
new file mode 100644
index 0000000..76de070
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-key-column-usage.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.32. key_column_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-foreign-tables.html" title="37.31. foreign_tables" /><link rel="next" href="infoschema-parameters.html" title="37.33. parameters" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.32. <code class="literal">key_column_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-foreign-tables.html" title="37.31. foreign_tables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-parameters.html" title="37.33. parameters">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-KEY-COLUMN-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.32. <code class="literal">key_column_usage</code></h2></div></div></div><p>
+ The view <code class="literal">key_column_usage</code> identifies all columns
+ in the current database that are restricted by some unique, primary
+ key, or foreign key constraint. Check constraints are not included
+ in this view. Only those columns are shown that the current user
+ has access to, by way of being the owner or having some privilege.
+ </p><div class="table" id="id-1.7.6.36.3"><p class="title"><strong>Table 37.30. <code class="structname">key_column_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="key_column_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that contains the
+ column that is restricted by this constraint (always the
+ current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that contains the
+ column that is restricted by this constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that contains the column that is restricted
+ by this constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column that is restricted by this constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordinal_position</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Ordinal position of the column within the constraint key (count
+ starts at 1)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">position_in_unique_constraint</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ For a foreign-key constraint, ordinal position of the referenced
+ column within its unique constraint (count starts at 1);
+ otherwise null
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-foreign-tables.html" title="37.31. foreign_tables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-parameters.html" title="37.33. parameters">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.31. <code class="literal">foreign_tables</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.33. <code class="literal">parameters</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-parameters.html b/doc/src/sgml/html/infoschema-parameters.html
new file mode 100644
index 0000000..532a8ed
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-parameters.html
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.33. parameters</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-key-column-usage.html" title="37.32. key_column_usage" /><link rel="next" href="infoschema-referential-constraints.html" title="37.34. referential_constraints" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.33. <code class="literal">parameters</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-key-column-usage.html" title="37.32. key_column_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-referential-constraints.html" title="37.34. referential_constraints">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-PARAMETERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.33. <code class="literal">parameters</code></h2></div></div></div><p>
+ The view <code class="literal">parameters</code> contains information about
+ the parameters (arguments) of all functions in the current database.
+ Only those functions are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.37.3"><p class="title"><strong>Table 37.31. <code class="structname">parameters</code> Columns</strong></p><div class="table-contents"><table class="table" summary="parameters Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordinal_position</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Ordinal position of the parameter in the argument list of the
+ function (count starts at 1)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parameter_mode</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">IN</code> for input parameter,
+ <code class="literal">OUT</code> for output parameter,
+ and <code class="literal">INOUT</code> for input/output parameter.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_result</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">as_locator</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parameter_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the parameter, or null if the parameter has no name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Data type of the parameter, if it is a built-in type, or
+ <code class="literal">ARRAY</code> if it is some array (in that case, see
+ the view <code class="literal">element_types</code>), else
+ <code class="literal">USER-DEFINED</code> (in that case, the type is
+ identified in <code class="literal">udt_name</code> and associated
+ columns).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to parameter data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the data type of the parameter is
+ defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the data type of the parameter is
+ defined in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the data type of the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, because arrays always have unlimited maximum cardinality in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ An identifier of the data type descriptor of the parameter,
+ unique among the data type descriptors pertaining to the
+ function. This is mainly useful for joining with other
+ instances of such identifiers. (The specific format of the
+ identifier is not defined and not guaranteed to remain the same
+ in future versions.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parameter_default</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The default expression of the parameter, or null if none or if the
+ function is not owned by a currently enabled role.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-key-column-usage.html" title="37.32. key_column_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-referential-constraints.html" title="37.34. referential_constraints">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.32. <code class="literal">key_column_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.34. <code class="literal">referential_constraints</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-referential-constraints.html b/doc/src/sgml/html/infoschema-referential-constraints.html
new file mode 100644
index 0000000..86e4678
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-referential-constraints.html
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.34. referential_constraints</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-parameters.html" title="37.33. parameters" /><link rel="next" href="infoschema-role-column-grants.html" title="37.35. role_column_grants" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.34. <code class="literal">referential_constraints</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-parameters.html" title="37.33. parameters">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-role-column-grants.html" title="37.35. role_column_grants">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-REFERENTIAL-CONSTRAINTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.34. <code class="literal">referential_constraints</code></h2></div></div></div><p>
+ The view <code class="literal">referential_constraints</code> contains all
+ referential (foreign key) constraints in the current database.
+ Only those constraints are shown for which the current user has
+ write access to the referencing table (by way of being the
+ owner or having some privilege other than <code class="literal">SELECT</code>).
+ </p><div class="table" id="id-1.7.6.38.3"><p class="title"><strong>Table 37.32. <code class="structname">referential_constraints</code> Columns</strong></p><div class="table-contents"><table class="table" summary="referential_constraints Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">unique_constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the unique or primary key
+ constraint that the foreign key constraint references (always
+ the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">unique_constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the unique or primary key
+ constraint that the foreign key constraint references
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">unique_constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the unique or primary key constraint that the foreign
+ key constraint references
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">match_option</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Match option of the foreign key constraint:
+ <code class="literal">FULL</code>, <code class="literal">PARTIAL</code>, or
+ <code class="literal">NONE</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">update_rule</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Update rule of the foreign key constraint:
+ <code class="literal">CASCADE</code>, <code class="literal">SET NULL</code>,
+ <code class="literal">SET DEFAULT</code>, <code class="literal">RESTRICT</code>, or
+ <code class="literal">NO ACTION</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">delete_rule</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Delete rule of the foreign key constraint:
+ <code class="literal">CASCADE</code>, <code class="literal">SET NULL</code>,
+ <code class="literal">SET DEFAULT</code>, <code class="literal">RESTRICT</code>, or
+ <code class="literal">NO ACTION</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-parameters.html" title="37.33. parameters">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-role-column-grants.html" title="37.35. role_column_grants">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.33. <code class="literal">parameters</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.35. <code class="literal">role_column_grants</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-role-column-grants.html b/doc/src/sgml/html/infoschema-role-column-grants.html
new file mode 100644
index 0000000..215f9ef
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-role-column-grants.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.35. role_column_grants</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-referential-constraints.html" title="37.34. referential_constraints" /><link rel="next" href="infoschema-role-routine-grants.html" title="37.36. role_routine_grants" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.35. <code class="literal">role_column_grants</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-referential-constraints.html" title="37.34. referential_constraints">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-role-routine-grants.html" title="37.36. role_routine_grants">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROLE-COLUMN-GRANTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.35. <code class="literal">role_column_grants</code></h2></div></div></div><p>
+ The view <code class="literal">role_column_grants</code> identifies all
+ privileges granted on columns where the grantor or grantee is a
+ currently enabled role. Further information can be found under
+ <code class="literal">column_privileges</code>. The only effective
+ difference between this view
+ and <code class="literal">column_privileges</code> is that this view omits
+ columns that have been made accessible to the current user by way
+ of a grant to <code class="literal">PUBLIC</code>.
+ </p><div class="table" id="id-1.7.6.39.3"><p class="title"><strong>Table 37.33. <code class="structname">role_column_grants</code> Columns</strong></p><div class="table-contents"><table class="table" summary="role_column_grants Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that contains the column (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that contains the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that contains the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Type of the privilege: <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, or
+ <code class="literal">REFERENCES</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-referential-constraints.html" title="37.34. referential_constraints">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-role-routine-grants.html" title="37.36. role_routine_grants">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.34. <code class="literal">referential_constraints</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.36. <code class="literal">role_routine_grants</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-role-routine-grants.html b/doc/src/sgml/html/infoschema-role-routine-grants.html
new file mode 100644
index 0000000..c97a0df
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-role-routine-grants.html
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.36. role_routine_grants</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-role-column-grants.html" title="37.35. role_column_grants" /><link rel="next" href="infoschema-role-table-grants.html" title="37.37. role_table_grants" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.36. <code class="literal">role_routine_grants</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-role-column-grants.html" title="37.35. role_column_grants">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-role-table-grants.html" title="37.37. role_table_grants">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROLE-ROUTINE-GRANTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.36. <code class="literal">role_routine_grants</code></h2></div></div></div><p>
+ The view <code class="literal">role_routine_grants</code> identifies all
+ privileges granted on functions where the grantor or grantee is a
+ currently enabled role. Further information can be found under
+ <code class="literal">routine_privileges</code>. The only effective
+ difference between this view
+ and <code class="literal">routine_privileges</code> is that this view omits
+ functions that have been made accessible to the current user by way
+ of a grant to <code class="literal">PUBLIC</code>.
+ </p><div class="table" id="id-1.7.6.40.3"><p class="title"><strong>Table 37.34. <code class="structname">role_routine_grants</code> Columns</strong></p><div class="table-contents"><table class="table" summary="role_routine_grants Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the function (might be duplicated in case of overloading)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">EXECUTE</code> (the only privilege type for functions)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-role-column-grants.html" title="37.35. role_column_grants">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-role-table-grants.html" title="37.37. role_table_grants">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.35. <code class="literal">role_column_grants</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.37. <code class="literal">role_table_grants</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-role-table-grants.html b/doc/src/sgml/html/infoschema-role-table-grants.html
new file mode 100644
index 0000000..f44c200
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-role-table-grants.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.37. role_table_grants</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-role-routine-grants.html" title="37.36. role_routine_grants" /><link rel="next" href="infoschema-role-udt-grants.html" title="37.38. role_udt_grants" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.37. <code class="literal">role_table_grants</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-role-routine-grants.html" title="37.36. role_routine_grants">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-role-udt-grants.html" title="37.38. role_udt_grants">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROLE-TABLE-GRANTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.37. <code class="literal">role_table_grants</code></h2></div></div></div><p>
+ The view <code class="literal">role_table_grants</code> identifies all
+ privileges granted on tables or views where the grantor or grantee
+ is a currently enabled role. Further information can be found
+ under <code class="literal">table_privileges</code>. The only effective
+ difference between this view
+ and <code class="literal">table_privileges</code> is that this view omits
+ tables that have been made accessible to the current user by way of
+ a grant to <code class="literal">PUBLIC</code>.
+ </p><div class="table" id="id-1.7.6.41.3"><p class="title"><strong>Table 37.35. <code class="structname">role_table_grants</code> Columns</strong></p><div class="table-contents"><table class="table" summary="role_table_grants Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Type of the privilege: <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, <code class="literal">TRUNCATE</code>,
+ <code class="literal">REFERENCES</code>, or <code class="literal">TRIGGER</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">with_hierarchy</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ In the SQL standard, <code class="literal">WITH HIERARCHY OPTION</code>
+ is a separate (sub-)privilege allowing certain operations on
+ table inheritance hierarchies. In PostgreSQL, this is included
+ in the <code class="literal">SELECT</code> privilege, so this column
+ shows <code class="literal">YES</code> if the privilege
+ is <code class="literal">SELECT</code>, else <code class="literal">NO</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-role-routine-grants.html" title="37.36. role_routine_grants">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-role-udt-grants.html" title="37.38. role_udt_grants">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.36. <code class="literal">role_routine_grants</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.38. <code class="literal">role_udt_grants</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-role-udt-grants.html b/doc/src/sgml/html/infoschema-role-udt-grants.html
new file mode 100644
index 0000000..3d81615
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-role-udt-grants.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.38. role_udt_grants</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-role-table-grants.html" title="37.37. role_table_grants" /><link rel="next" href="infoschema-role-usage-grants.html" title="37.39. role_usage_grants" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.38. <code class="literal">role_udt_grants</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-role-table-grants.html" title="37.37. role_table_grants">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-role-usage-grants.html" title="37.39. role_usage_grants">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROLE-UDT-GRANTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.38. <code class="literal">role_udt_grants</code></h2></div></div></div><p>
+ The view <code class="literal">role_udt_grants</code> is intended to identify
+ <code class="literal">USAGE</code> privileges granted on user-defined types
+ where the grantor or grantee is a currently enabled role. Further
+ information can be found under
+ <code class="literal">udt_privileges</code>. The only effective difference
+ between this view and <code class="literal">udt_privileges</code> is that
+ this view omits objects that have been made accessible to the
+ current user by way of a grant to <code class="literal">PUBLIC</code>. Since
+ data types do not have real privileges in PostgreSQL, but only an
+ implicit grant to <code class="literal">PUBLIC</code>, this view is empty.
+ </p><div class="table" id="id-1.7.6.42.3"><p class="title"><strong>Table 37.36. <code class="structname">role_udt_grants</code> Columns</strong></p><div class="table-contents"><table class="table" summary="role_udt_grants Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the type (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">TYPE USAGE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-role-table-grants.html" title="37.37. role_table_grants">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-role-usage-grants.html" title="37.39. role_usage_grants">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.37. <code class="literal">role_table_grants</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.39. <code class="literal">role_usage_grants</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-role-usage-grants.html b/doc/src/sgml/html/infoschema-role-usage-grants.html
new file mode 100644
index 0000000..1bfe394
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-role-usage-grants.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.39. role_usage_grants</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-role-udt-grants.html" title="37.38. role_udt_grants" /><link rel="next" href="infoschema-routine-column-usage.html" title="37.40. routine_column_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.39. <code class="literal">role_usage_grants</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-role-udt-grants.html" title="37.38. role_udt_grants">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-routine-column-usage.html" title="37.40. routine_column_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROLE-USAGE-GRANTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.39. <code class="literal">role_usage_grants</code></h2></div></div></div><p>
+ The view <code class="literal">role_usage_grants</code> identifies
+ <code class="literal">USAGE</code> privileges granted on various kinds of
+ objects where the grantor or grantee is a currently enabled role.
+ Further information can be found under
+ <code class="literal">usage_privileges</code>. The only effective difference
+ between this view and <code class="literal">usage_privileges</code> is that
+ this view omits objects that have been made accessible to the
+ current user by way of a grant to <code class="literal">PUBLIC</code>.
+ </p><div class="table" id="id-1.7.6.43.3"><p class="title"><strong>Table 37.37. <code class="structname">role_usage_grants</code> Columns</strong></p><div class="table-contents"><table class="table" summary="role_usage_grants Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the object (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the object, if applicable,
+ else an empty string
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">COLLATION</code> or <code class="literal">DOMAIN</code> or <code class="literal">FOREIGN DATA WRAPPER</code> or <code class="literal">FOREIGN SERVER</code> or <code class="literal">SEQUENCE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">USAGE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-role-udt-grants.html" title="37.38. role_udt_grants">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-routine-column-usage.html" title="37.40. routine_column_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.38. <code class="literal">role_udt_grants</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.40. <code class="literal">routine_column_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-routine-column-usage.html b/doc/src/sgml/html/infoschema-routine-column-usage.html
new file mode 100644
index 0000000..0f7587b
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-routine-column-usage.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.40. routine_column_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-role-usage-grants.html" title="37.39. role_usage_grants" /><link rel="next" href="infoschema-routine-privileges.html" title="37.41. routine_privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.40. <code class="literal">routine_column_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-role-usage-grants.html" title="37.39. role_usage_grants">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-routine-privileges.html" title="37.41. routine_privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROUTINE-COLUMN-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.40. <code class="literal">routine_column_usage</code></h2></div></div></div><p>
+ The view <code class="literal">routine_column_usage</code> is meant to identify all
+ columns that are used by a function or procedure. This information is
+ currently not tracked by <span class="productname">PostgreSQL</span>.
+ </p><div class="table" id="id-1.7.6.44.3"><p class="title"><strong>Table 37.38. <code class="literal">routine_column_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="routine_column_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the function (might be duplicated in case of overloading)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that is used by the
+ function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that is used by the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that is used by the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column that is used by the function
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-role-usage-grants.html" title="37.39. role_usage_grants">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-routine-privileges.html" title="37.41. routine_privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.39. <code class="literal">role_usage_grants</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.41. <code class="literal">routine_privileges</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-routine-privileges.html b/doc/src/sgml/html/infoschema-routine-privileges.html
new file mode 100644
index 0000000..c5daf15
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-routine-privileges.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.41. routine_privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-routine-column-usage.html" title="37.40. routine_column_usage" /><link rel="next" href="infoschema-routine-routine-usage.html" title="37.42. routine_routine_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.41. <code class="literal">routine_privileges</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-routine-column-usage.html" title="37.40. routine_column_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-routine-routine-usage.html" title="37.42. routine_routine_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROUTINE-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.41. <code class="literal">routine_privileges</code></h2></div></div></div><p>
+ The view <code class="literal">routine_privileges</code> identifies all
+ privileges granted on functions to a currently enabled role or by a
+ currently enabled role. There is one row for each combination of function,
+ grantor, and grantee.
+ </p><div class="table" id="id-1.7.6.45.3"><p class="title"><strong>Table 37.39. <code class="structname">routine_privileges</code> Columns</strong></p><div class="table-contents"><table class="table" summary="routine_privileges Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the function (might be duplicated in case of overloading)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">EXECUTE</code> (the only privilege type for functions)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-routine-column-usage.html" title="37.40. routine_column_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-routine-routine-usage.html" title="37.42. routine_routine_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.40. <code class="literal">routine_column_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.42. <code class="literal">routine_routine_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-routine-routine-usage.html b/doc/src/sgml/html/infoschema-routine-routine-usage.html
new file mode 100644
index 0000000..6d5ecea
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-routine-routine-usage.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.42. routine_routine_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-routine-privileges.html" title="37.41. routine_privileges" /><link rel="next" href="infoschema-routine-sequence-usage.html" title="37.43. routine_sequence_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.42. <code class="literal">routine_routine_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-routine-privileges.html" title="37.41. routine_privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-routine-sequence-usage.html" title="37.43. routine_sequence_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROUTINE-ROUTINE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.42. <code class="literal">routine_routine_usage</code></h2></div></div></div><p>
+ The view <code class="literal">routine_routine_usage</code> is meant to identify all
+ functions or procedures that are used by another (or the same) function or
+ procedure, either in the body or in parameter default expressions.
+ Currently, only functions used in parameter default expressions are
+ tracked. An entry is included here only if the used function is owned by a
+ currently enabled role. (There is no such restriction on the using
+ function.)
+ </p><p>
+ Note that the entries for both functions in the view refer to the
+ <span class="quote">“<span class="quote">specific</span>”</span> name of the routine, even though the column names
+ are used in a way that is inconsistent with other information schema views
+ about routines. This is per SQL standard, although it is arguably a
+ misdesign. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information
+ about specific names.
+ </p><div class="table" id="id-1.7.6.46.4"><p class="title"><strong>Table 37.40. <code class="literal">routine_routine_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="routine_routine_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the using function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the using function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the using function.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the function that is used by the
+ first function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the function that is used by the first
+ function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function that is used by the
+ first function.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-routine-privileges.html" title="37.41. routine_privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-routine-sequence-usage.html" title="37.43. routine_sequence_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.41. <code class="literal">routine_privileges</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.43. <code class="literal">routine_sequence_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-routine-sequence-usage.html b/doc/src/sgml/html/infoschema-routine-sequence-usage.html
new file mode 100644
index 0000000..48b26a5
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-routine-sequence-usage.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.43. routine_sequence_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-routine-routine-usage.html" title="37.42. routine_routine_usage" /><link rel="next" href="infoschema-routine-table-usage.html" title="37.44. routine_table_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.43. <code class="literal">routine_sequence_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-routine-routine-usage.html" title="37.42. routine_routine_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-routine-table-usage.html" title="37.44. routine_table_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROUTINE-SEQUENCE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.43. <code class="literal">routine_sequence_usage</code></h2></div></div></div><p>
+ The view <code class="literal">routine_sequence_usage</code> is meant to identify all
+ sequences that are used by a function or procedure, either in the body or
+ in parameter default expressions. Currently, only sequences used in
+ parameter default expressions are tracked. A sequence is only included if
+ that sequence is owned by a currently enabled role.
+ </p><div class="table" id="id-1.7.6.47.3"><p class="title"><strong>Table 37.41. <code class="literal">routine_sequence_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="routine_sequence_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the function (might be duplicated in case of overloading)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schema_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the sequence that is used by the
+ function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequence_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the sequence that is used by the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequence_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the sequence that is used by the function
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-routine-routine-usage.html" title="37.42. routine_routine_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-routine-table-usage.html" title="37.44. routine_table_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.42. <code class="literal">routine_routine_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.44. <code class="literal">routine_table_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-routine-table-usage.html b/doc/src/sgml/html/infoschema-routine-table-usage.html
new file mode 100644
index 0000000..4a0ebca
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-routine-table-usage.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.44. routine_table_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-routine-sequence-usage.html" title="37.43. routine_sequence_usage" /><link rel="next" href="infoschema-routines.html" title="37.45. routines" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.44. <code class="literal">routine_table_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-routine-sequence-usage.html" title="37.43. routine_sequence_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-routines.html" title="37.45. routines">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROUTINE-TABLE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.44. <code class="literal">routine_table_usage</code></h2></div></div></div><p>
+ The view <code class="literal">routine_table_usage</code> is meant to identify all
+ tables that are used by a function or procedure. This information is
+ currently not tracked by <span class="productname">PostgreSQL</span>.
+ </p><div class="table" id="id-1.7.6.48.3"><p class="title"><strong>Table 37.42. <code class="literal">routine_table_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="routine_table_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the function (might be duplicated in case of overloading)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that is used by the
+ function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that is used by the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that is used by the function
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-routine-sequence-usage.html" title="37.43. routine_sequence_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-routines.html" title="37.45. routines">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.43. <code class="literal">routine_sequence_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.45. <code class="literal">routines</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-routines.html b/doc/src/sgml/html/infoschema-routines.html
new file mode 100644
index 0000000..6c9c2b9
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-routines.html
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.45. routines</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-routine-table-usage.html" title="37.44. routine_table_usage" /><link rel="next" href="infoschema-schemata.html" title="37.46. schemata" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.45. <code class="literal">routines</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-routine-table-usage.html" title="37.44. routine_table_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-schemata.html" title="37.46. schemata">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-ROUTINES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.45. <code class="literal">routines</code></h2></div></div></div><p>
+ The view <code class="literal">routines</code> contains all functions and procedures in the
+ current database. Only those functions and procedures are shown that the current
+ user has access to (by way of being the owner or having some
+ privilege).
+ </p><div class="table" id="id-1.7.6.49.3"><p class="title"><strong>Table 37.43. <code class="structname">routines</code> Columns</strong></p><div class="table-contents"><table class="table" summary="routines Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. This is a
+ name that uniquely identifies the function in the schema, even
+ if the real name of the function is overloaded. The format of
+ the specific name is not defined, it should only be used to
+ compare it to other instances of specific routine names.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the function (might be duplicated in case of overloading)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">FUNCTION</code> for a
+ function, <code class="literal">PROCEDURE</code> for a procedure
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">module_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">module_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">module_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Return data type of the function, if it is a built-in type, or
+ <code class="literal">ARRAY</code> if it is some array (in that case, see
+ the view <code class="literal">element_types</code>), else
+ <code class="literal">USER-DEFINED</code> (in that case, the type is
+ identified in <code class="literal">type_udt_name</code> and associated
+ columns). Null for a procedure.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, since this information is not applied to return data types in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">type_udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the return data type of the function
+ is defined in (always the current database). Null for a procedure.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">type_udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that the return data type of the function is
+ defined in. Null for a procedure.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">type_udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the return data type of the function. Null for a procedure.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Always null, because arrays always have unlimited maximum cardinality in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ An identifier of the data type descriptor of the return data
+ type of this function, unique among the data type descriptors
+ pertaining to the function. This is mainly useful for joining
+ with other instances of such identifiers. (The specific format
+ of the identifier is not defined and not guaranteed to remain
+ the same in future versions.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_body</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the function is an SQL function, then
+ <code class="literal">SQL</code>, else <code class="literal">EXTERNAL</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">routine_definition</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The source text of the function (null if the function is not
+ owned by a currently enabled role). (According to the SQL
+ standard, this column is only applicable if
+ <code class="literal">routine_body</code> is <code class="literal">SQL</code>, but
+ in <span class="productname">PostgreSQL</span> it will contain
+ whatever source text was specified when the function was
+ created.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">external_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If this function is a C function, then the external name (link
+ symbol) of the function; else null. (This works out to be the
+ same value that is shown in
+ <code class="literal">routine_definition</code>.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">external_language</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The language the function is written in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parameter_style</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">GENERAL</code> (The SQL standard defines
+ other parameter styles, which are not available in <span class="productname">PostgreSQL</span>.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_deterministic</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ If the function is declared immutable (called deterministic in
+ the SQL standard), then <code class="literal">YES</code>, else
+ <code class="literal">NO</code>. (You cannot query the other volatility
+ levels available in <span class="productname">PostgreSQL</span> through the information schema.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sql_data_access</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">MODIFIES</code>, meaning that the function
+ possibly modifies SQL data. This information is not useful for
+ <span class="productname">PostgreSQL</span>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_null_call</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ If the function automatically returns null if any of its
+ arguments are null, then <code class="literal">YES</code>, else
+ <code class="literal">NO</code>. Null for a procedure.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sql_path</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schema_level_routine</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Always <code class="literal">YES</code> (The opposite would be a method
+ of a user-defined type, which is a feature not available in
+ <span class="productname">PostgreSQL</span>.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">max_dynamic_result_sets</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_user_defined_cast</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_implicitly_invocable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">security_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ If the function runs with the privileges of the current user,
+ then <code class="literal">INVOKER</code>, if the function runs with the
+ privileges of the user who defined it, then
+ <code class="literal">DEFINER</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">to_sql_specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">to_sql_specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">to_sql_specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">as_locator</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">created</code> <code class="type">time_stamp</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_altered</code> <code class="type">time_stamp</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">new_savepoint_level</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_udt_dependent</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Currently always <code class="literal">NO</code>. The alternative
+ <code class="literal">YES</code> applies to a feature not available in
+ <span class="productname">PostgreSQL</span>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_from_data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_as_locator</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_char_max_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_char_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_char_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_char_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_char_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_type_udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_type_udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_type_udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_scope_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_scope_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_scope_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_maximum_cardinality</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">result_cast_dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-routine-table-usage.html" title="37.44. routine_table_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-schemata.html" title="37.46. schemata">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.44. <code class="literal">routine_table_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.46. <code class="literal">schemata</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-schema.html b/doc/src/sgml/html/infoschema-schema.html
new file mode 100644
index 0000000..6943a15
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-schema.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.1. The Schema</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="information-schema.html" title="Chapter 37. The Information Schema" /><link rel="next" href="infoschema-datatypes.html" title="37.2. Data Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.1. The Schema</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="information-schema.html" title="Chapter 37. The Information Schema">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-datatypes.html" title="37.2. Data Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SCHEMA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.1. The Schema</h2></div></div></div><p>
+ The information schema itself is a schema named
+ <code class="literal">information_schema</code>. This schema automatically
+ exists in all databases. The owner of this schema is the initial
+ database user in the cluster, and that user naturally has all the
+ privileges on this schema, including the ability to drop it (but
+ the space savings achieved by that are minuscule).
+ </p><p>
+ By default, the information schema is not in the schema search
+ path, so you need to access all objects in it through qualified
+ names. Since the names of some of the objects in the information
+ schema are generic names that might occur in user applications, you
+ should be careful if you want to put the information schema in the
+ path.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="information-schema.html" title="Chapter 37. The Information Schema">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-datatypes.html" title="37.2. Data Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 37. The Information Schema </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.2. Data Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-schemata.html b/doc/src/sgml/html/infoschema-schemata.html
new file mode 100644
index 0000000..bd8fc25
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-schemata.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.46. schemata</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-routines.html" title="37.45. routines" /><link rel="next" href="infoschema-sequences.html" title="37.47. sequences" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.46. <code class="literal">schemata</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-routines.html" title="37.45. routines">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-sequences.html" title="37.47. sequences">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SCHEMATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.46. <code class="literal">schemata</code></h2></div></div></div><p>
+ The view <code class="literal">schemata</code> contains all schemas in the current
+ database that the current user has access to (by way of being the owner or
+ having some privilege).
+ </p><div class="table" id="id-1.7.6.50.3"><p class="title"><strong>Table 37.44. <code class="structname">schemata</code> Columns</strong></p><div class="table-contents"><table class="table" summary="schemata Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">catalog_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the schema is contained in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schema_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schema_owner</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the owner of the schema
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sql_path</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-routines.html" title="37.45. routines">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-sequences.html" title="37.47. sequences">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.45. <code class="literal">routines</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.47. <code class="literal">sequences</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-sequences.html b/doc/src/sgml/html/infoschema-sequences.html
new file mode 100644
index 0000000..6982f85
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-sequences.html
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.47. sequences</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-schemata.html" title="37.46. schemata" /><link rel="next" href="infoschema-sql-features.html" title="37.48. sql_features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.47. <code class="literal">sequences</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-schemata.html" title="37.46. schemata">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-sql-features.html" title="37.48. sql_features">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SEQUENCES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.47. <code class="literal">sequences</code></h2></div></div></div><p>
+ The view <code class="literal">sequences</code> contains all sequences
+ defined in the current database. Only those sequences are shown
+ that the current user has access to (by way of being the owner or
+ having some privilege).
+ </p><div class="table" id="id-1.7.6.51.3"><p class="title"><strong>Table 37.45. <code class="structname">sequences</code> Columns</strong></p><div class="table-contents"><table class="table" summary="sequences Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequence_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the sequence (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequence_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequence_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The data type of the sequence.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ This column contains the (declared or implicit) precision of
+ the sequence data type (see above). The precision indicates
+ the number of significant digits. It can be expressed in
+ decimal (base 10) or binary (base 2) terms, as specified in the
+ column <code class="literal">numeric_precision_radix</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ This column indicates in which base the values in the columns
+ <code class="literal">numeric_precision</code> and
+ <code class="literal">numeric_scale</code> are expressed. The value is
+ either 2 or 10.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ This column contains the (declared or implicit) scale of the
+ sequence data type (see above). The scale indicates the number
+ of significant digits to the right of the decimal point. It
+ can be expressed in decimal (base 10) or binary (base 2) terms,
+ as specified in the column
+ <code class="literal">numeric_precision_radix</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">start_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The start value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">minimum_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The minimum value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maximum_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The maximum value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">increment</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ The increment of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cycle_option</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the sequence cycles, else <code class="literal">NO</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Note that in accordance with the SQL standard, the start, minimum,
+ maximum, and increment values are returned as character strings.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-schemata.html" title="37.46. schemata">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-sql-features.html" title="37.48. sql_features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.46. <code class="literal">schemata</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.48. <code class="literal">sql_features</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-sql-features.html b/doc/src/sgml/html/infoschema-sql-features.html
new file mode 100644
index 0000000..715dd74
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-sql-features.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.48. sql_features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-sequences.html" title="37.47. sequences" /><link rel="next" href="infoschema-sql-implementation-info.html" title="37.49. sql_implementation_info" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.48. <code class="literal">sql_features</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-sequences.html" title="37.47. sequences">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-sql-implementation-info.html" title="37.49. sql_implementation_info">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SQL-FEATURES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.48. <code class="literal">sql_features</code></h2></div></div></div><p>
+ The table <code class="literal">sql_features</code> contains information
+ about which formal features defined in the SQL standard are
+ supported by <span class="productname">PostgreSQL</span>. This is the
+ same information that is presented in <a class="xref" href="features.html" title="Appendix D. SQL Conformance">Appendix D</a>.
+ There you can also find some additional background information.
+ </p><div class="table" id="id-1.7.6.52.3"><p class="title"><strong>Table 37.46. <code class="structname">sql_features</code> Columns</strong></p><div class="table-contents"><table class="table" summary="sql_features Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">feature_id</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Identifier string of the feature
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">feature_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Descriptive name of the feature
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sub_feature_id</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Identifier string of the subfeature, or a zero-length string if not a subfeature
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sub_feature_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Descriptive name of the subfeature, or a zero-length string if not a subfeature
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_supported</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the feature is fully supported by the
+ current version of <span class="productname">PostgreSQL</span>, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_verified_by</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always null, since the <span class="productname">PostgreSQL</span> development group does not
+ perform formal testing of feature conformance
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">comments</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Possibly a comment about the supported status of the feature
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-sequences.html" title="37.47. sequences">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-sql-implementation-info.html" title="37.49. sql_implementation_info">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.47. <code class="literal">sequences</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.49. <code class="literal">sql_implementation_info</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-sql-implementation-info.html b/doc/src/sgml/html/infoschema-sql-implementation-info.html
new file mode 100644
index 0000000..0d1ab37
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-sql-implementation-info.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.49. sql_implementation_info</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-sql-features.html" title="37.48. sql_features" /><link rel="next" href="infoschema-sql-parts.html" title="37.50. sql_parts" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.49. <code class="literal">sql_implementation_info</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-sql-features.html" title="37.48. sql_features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-sql-parts.html" title="37.50. sql_parts">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SQL-IMPLEMENTATION-INFO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.49. <code class="literal">sql_implementation_info</code></h2></div></div></div><p>
+ The table <code class="literal">sql_implementation_info</code> contains
+ information about various aspects that are left
+ implementation-defined by the SQL standard. This information is
+ primarily intended for use in the context of the ODBC interface;
+ users of other interfaces will probably find this information to be
+ of little use. For this reason, the individual implementation
+ information items are not described here; you will find them in the
+ description of the ODBC interface.
+ </p><div class="table" id="id-1.7.6.53.3"><p class="title"><strong>Table 37.47. <code class="structname">sql_implementation_info</code> Columns</strong></p><div class="table-contents"><table class="table" summary="sql_implementation_info Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">implementation_info_id</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Identifier string of the implementation information item
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">implementation_info_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Descriptive name of the implementation information item
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">integer_value</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Value of the implementation information item, or null if the
+ value is contained in the column
+ <code class="literal">character_value</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Value of the implementation information item, or null if the
+ value is contained in the column
+ <code class="literal">integer_value</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">comments</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Possibly a comment pertaining to the implementation information item
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-sql-features.html" title="37.48. sql_features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-sql-parts.html" title="37.50. sql_parts">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.48. <code class="literal">sql_features</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.50. <code class="literal">sql_parts</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-sql-parts.html b/doc/src/sgml/html/infoschema-sql-parts.html
new file mode 100644
index 0000000..e168890
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-sql-parts.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.50. sql_parts</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-sql-implementation-info.html" title="37.49. sql_implementation_info" /><link rel="next" href="infoschema-sql-sizing.html" title="37.51. sql_sizing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.50. <code class="literal">sql_parts</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-sql-implementation-info.html" title="37.49. sql_implementation_info">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-sql-sizing.html" title="37.51. sql_sizing">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SQL-PARTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.50. <code class="literal">sql_parts</code></h2></div></div></div><p>
+ The table <code class="literal">sql_parts</code> contains information about
+ which of the several parts of the SQL standard are supported by
+ <span class="productname">PostgreSQL</span>.
+ </p><div class="table" id="id-1.7.6.54.3"><p class="title"><strong>Table 37.48. <code class="structname">sql_parts</code> Columns</strong></p><div class="table-contents"><table class="table" summary="sql_parts Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">feature_id</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ An identifier string containing the number of the part
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">feature_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Descriptive name of the part
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_supported</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the part is fully supported by the
+ current version of <span class="productname">PostgreSQL</span>,
+ <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_verified_by</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always null, since the <span class="productname">PostgreSQL</span> development group does not
+ perform formal testing of feature conformance
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">comments</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Possibly a comment about the supported status of the part
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-sql-implementation-info.html" title="37.49. sql_implementation_info">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-sql-sizing.html" title="37.51. sql_sizing">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.49. <code class="literal">sql_implementation_info</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.51. <code class="literal">sql_sizing</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-sql-sizing.html b/doc/src/sgml/html/infoschema-sql-sizing.html
new file mode 100644
index 0000000..49bef2c
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-sql-sizing.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.51. sql_sizing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-sql-parts.html" title="37.50. sql_parts" /><link rel="next" href="infoschema-table-constraints.html" title="37.52. table_constraints" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.51. <code class="literal">sql_sizing</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-sql-parts.html" title="37.50. sql_parts">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-table-constraints.html" title="37.52. table_constraints">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-SQL-SIZING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.51. <code class="literal">sql_sizing</code></h2></div></div></div><p>
+ The table <code class="literal">sql_sizing</code> contains information about
+ various size limits and maximum values in
+ <span class="productname">PostgreSQL</span>. This information is
+ primarily intended for use in the context of the ODBC interface;
+ users of other interfaces will probably find this information to be
+ of little use. For this reason, the individual sizing items are
+ not described here; you will find them in the description of the
+ ODBC interface.
+ </p><div class="table" id="id-1.7.6.55.3"><p class="title"><strong>Table 37.49. <code class="structname">sql_sizing</code> Columns</strong></p><div class="table-contents"><table class="table" summary="sql_sizing Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sizing_id</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Identifier of the sizing item
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sizing_name</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Descriptive name of the sizing item
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">supported_value</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Value of the sizing item, or 0 if the size is unlimited or
+ cannot be determined, or null if the features for which the
+ sizing item is applicable are not supported
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">comments</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Possibly a comment pertaining to the sizing item
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-sql-parts.html" title="37.50. sql_parts">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-table-constraints.html" title="37.52. table_constraints">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.50. <code class="literal">sql_parts</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.52. <code class="literal">table_constraints</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-table-constraints.html b/doc/src/sgml/html/infoschema-table-constraints.html
new file mode 100644
index 0000000..8fce535
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-table-constraints.html
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.52. table_constraints</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-sql-sizing.html" title="37.51. sql_sizing" /><link rel="next" href="infoschema-table-privileges.html" title="37.53. table_privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.52. <code class="literal">table_constraints</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-sql-sizing.html" title="37.51. sql_sizing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-table-privileges.html" title="37.53. table_privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-TABLE-CONSTRAINTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.52. <code class="literal">table_constraints</code></h2></div></div></div><p>
+ The view <code class="literal">table_constraints</code> contains all
+ constraints belonging to tables that the current user owns or has
+ some privilege other than <code class="literal">SELECT</code> on.
+ </p><div class="table" id="id-1.7.6.56.3"><p class="title"><strong>Table 37.50. <code class="structname">table_constraints</code> Columns</strong></p><div class="table-contents"><table class="table" summary="table_constraints Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the constraint (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the constraint
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">constraint_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Type of the constraint: <code class="literal">CHECK</code>,
+ <code class="literal">FOREIGN KEY</code>, <code class="literal">PRIMARY KEY</code>,
+ or <code class="literal">UNIQUE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_deferrable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the constraint is deferrable, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">initially_deferred</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the constraint is deferrable and initially deferred, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">enforced</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in
+ <span class="productname">PostgreSQL</span> (currently always
+ <code class="literal">YES</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">nulls_distinct</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ If the constraint is a unique constraint, then <code class="literal">YES</code>
+ if the constraint treats nulls as distinct or <code class="literal">NO</code> if
+ it treats nulls as not distinct, otherwise null for other types of
+ constraints.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-sql-sizing.html" title="37.51. sql_sizing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-table-privileges.html" title="37.53. table_privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.51. <code class="literal">sql_sizing</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.53. <code class="literal">table_privileges</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-table-privileges.html b/doc/src/sgml/html/infoschema-table-privileges.html
new file mode 100644
index 0000000..dfa9117
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-table-privileges.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.53. table_privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-table-constraints.html" title="37.52. table_constraints" /><link rel="next" href="infoschema-tables.html" title="37.54. tables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.53. <code class="literal">table_privileges</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-table-constraints.html" title="37.52. table_constraints">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-tables.html" title="37.54. tables">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-TABLE-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.53. <code class="literal">table_privileges</code></h2></div></div></div><p>
+ The view <code class="literal">table_privileges</code> identifies all
+ privileges granted on tables or views to a currently enabled role
+ or by a currently enabled role. There is one row for each
+ combination of table, grantor, and grantee.
+ </p><div class="table" id="id-1.7.6.57.3"><p class="title"><strong>Table 37.51. <code class="structname">table_privileges</code> Columns</strong></p><div class="table-contents"><table class="table" summary="table_privileges Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Type of the privilege: <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, <code class="literal">TRUNCATE</code>,
+ <code class="literal">REFERENCES</code>, or <code class="literal">TRIGGER</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">with_hierarchy</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ In the SQL standard, <code class="literal">WITH HIERARCHY OPTION</code>
+ is a separate (sub-)privilege allowing certain operations on
+ table inheritance hierarchies. In PostgreSQL, this is included
+ in the <code class="literal">SELECT</code> privilege, so this column
+ shows <code class="literal">YES</code> if the privilege
+ is <code class="literal">SELECT</code>, else <code class="literal">NO</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-table-constraints.html" title="37.52. table_constraints">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-tables.html" title="37.54. tables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.52. <code class="literal">table_constraints</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.54. <code class="literal">tables</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-tables.html b/doc/src/sgml/html/infoschema-tables.html
new file mode 100644
index 0000000..d9b2a8a
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-tables.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.54. tables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-table-privileges.html" title="37.53. table_privileges" /><link rel="next" href="infoschema-transforms.html" title="37.55. transforms" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.54. <code class="literal">tables</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-table-privileges.html" title="37.53. table_privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-transforms.html" title="37.55. transforms">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-TABLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.54. <code class="literal">tables</code></h2></div></div></div><p>
+ The view <code class="literal">tables</code> contains all tables and views
+ defined in the current database. Only those tables and views are
+ shown that the current user has access to (by way of being the
+ owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.58.3"><p class="title"><strong>Table 37.52. <code class="structname">tables</code> Columns</strong></p><div class="table-contents"><table class="table" summary="tables Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Type of the table: <code class="literal">BASE TABLE</code> for a
+ persistent base table (the normal table type),
+ <code class="literal">VIEW</code> for a view, <code class="literal">FOREIGN</code>
+ for a foreign table, or
+ <code class="literal">LOCAL TEMPORARY</code> for a temporary table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">self_referencing_column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reference_generation</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ If the table is a typed table, the name of the database that
+ contains the underlying data type (always the current
+ database), else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ If the table is a typed table, the name of the schema that
+ contains the underlying data type, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ If the table is a typed table, the name of the underlying data
+ type, else null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_insertable_into</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the table is insertable into,
+ <code class="literal">NO</code> if not (Base tables are always insertable
+ into, views not necessarily.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_typed</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the table is a typed table, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">commit_action</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Not yet implemented
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-table-privileges.html" title="37.53. table_privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-transforms.html" title="37.55. transforms">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.53. <code class="literal">table_privileges</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.55. <code class="literal">transforms</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-transforms.html b/doc/src/sgml/html/infoschema-transforms.html
new file mode 100644
index 0000000..582e125
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-transforms.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.55. transforms</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-tables.html" title="37.54. tables" /><link rel="next" href="infoschema-triggered-update-columns.html" title="37.56. triggered_update_columns" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.55. <code class="literal">transforms</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-tables.html" title="37.54. tables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-triggered-update-columns.html" title="37.56. triggered_update_columns">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-TRANSFORMS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.55. <code class="literal">transforms</code></h2></div></div></div><p>
+ The view <code class="literal">transforms</code> contains information about the
+ transforms defined in the current database. More precisely, it contains a
+ row for each function contained in a transform (the <span class="quote">“<span class="quote">from SQL</span>”</span>
+ or <span class="quote">“<span class="quote">to SQL</span>”</span> function).
+ </p><div class="table" id="id-1.7.6.59.3"><p class="title"><strong>Table 37.53. <code class="structname">transforms</code> Columns</strong></p><div class="table-contents"><table class="table" summary="transforms Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the type the transform is for (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the type the transform is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the type the transform is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">group_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The SQL standard allows defining transforms in <span class="quote">“<span class="quote">groups</span>”</span>,
+ and selecting a group at run time. PostgreSQL does not support this.
+ Instead, transforms are specific to a language. As a compromise, this
+ field contains the language the transform is for.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">transform_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">FROM SQL</code> or <code class="literal">TO SQL</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-tables.html" title="37.54. tables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-triggered-update-columns.html" title="37.56. triggered_update_columns">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.54. <code class="literal">tables</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.56. <code class="literal">triggered_update_columns</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-triggered-update-columns.html b/doc/src/sgml/html/infoschema-triggered-update-columns.html
new file mode 100644
index 0000000..fbce82e
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-triggered-update-columns.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.56. triggered_update_columns</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-transforms.html" title="37.55. transforms" /><link rel="next" href="infoschema-triggers.html" title="37.57. triggers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.56. <code class="literal">triggered_update_columns</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-transforms.html" title="37.55. transforms">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-triggers.html" title="37.57. triggers">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-TRIGGERED-UPDATE-COLUMNS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.56. <code class="literal">triggered_update_columns</code></h2></div></div></div><p>
+ For triggers in the current database that specify a column list
+ (like <code class="literal">UPDATE OF column1, column2</code>), the
+ view <code class="literal">triggered_update_columns</code> identifies these
+ columns. Triggers that do not specify a column list are not
+ included in this view. Only those columns are shown that the
+ current user owns or has some privilege other than
+ <code class="literal">SELECT</code> on.
+ </p><div class="table" id="id-1.7.6.60.3"><p class="title"><strong>Table 37.54. <code class="structname">triggered_update_columns</code> Columns</strong></p><div class="table-contents"><table class="table" summary="triggered_update_columns Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trigger_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the trigger (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trigger_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the trigger
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trigger_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the trigger
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that the trigger
+ is defined on (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that the trigger is defined on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_table</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that the trigger is defined on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_column</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column that the trigger is defined on
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-transforms.html" title="37.55. transforms">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-triggers.html" title="37.57. triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.55. <code class="literal">transforms</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.57. <code class="literal">triggers</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-triggers.html b/doc/src/sgml/html/infoschema-triggers.html
new file mode 100644
index 0000000..1c38e67
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-triggers.html
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.57. triggers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-triggered-update-columns.html" title="37.56. triggered_update_columns" /><link rel="next" href="infoschema-udt-privileges.html" title="37.58. udt_privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.57. <code class="literal">triggers</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-triggered-update-columns.html" title="37.56. triggered_update_columns">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-udt-privileges.html" title="37.58. udt_privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-TRIGGERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.57. <code class="literal">triggers</code></h2></div></div></div><p>
+ The view <code class="literal">triggers</code> contains all triggers defined
+ in the current database on tables and views that the current user owns
+ or has some privilege other than <code class="literal">SELECT</code> on.
+ </p><div class="table" id="id-1.7.6.61.3"><p class="title"><strong>Table 37.55. <code class="structname">triggers</code> Columns</strong></p><div class="table-contents"><table class="table" summary="triggers Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trigger_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the trigger (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trigger_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the trigger
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trigger_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the trigger
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_manipulation</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Event that fires the trigger (<code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, or <code class="literal">DELETE</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that the trigger
+ is defined on (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that the trigger is defined on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">event_object_table</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that the trigger is defined on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_order</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Firing order among triggers on the same table having the same
+ <code class="literal">event_manipulation</code>,
+ <code class="literal">action_timing</code>, and
+ <code class="literal">action_orientation</code>. In
+ <span class="productname">PostgreSQL</span>, triggers are fired in name
+ order, so this column reflects that.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_condition</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">WHEN</code> condition of the trigger, null if none
+ (also null if the table is not owned by a currently enabled
+ role)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_statement</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Statement that is executed by the trigger (currently always
+ <code class="literal">EXECUTE FUNCTION
+ <em class="replaceable"><code>function</code></em>(...)</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_orientation</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Identifies whether the trigger fires once for each processed
+ row or once for each statement (<code class="literal">ROW</code> or
+ <code class="literal">STATEMENT</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_timing</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Time at which the trigger fires (<code class="literal">BEFORE</code>,
+ <code class="literal">AFTER</code>, or <code class="literal">INSTEAD OF</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_reference_old_table</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the <span class="quote">“<span class="quote">old</span>”</span> transition table, or null if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_reference_new_table</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the <span class="quote">“<span class="quote">new</span>”</span> transition table, or null if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_reference_old_row</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">action_reference_new_row</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">created</code> <code class="type">time_stamp</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Triggers in <span class="productname">PostgreSQL</span> have two
+ incompatibilities with the SQL standard that affect the
+ representation in the information schema. First, trigger names are
+ local to each table in <span class="productname">PostgreSQL</span>, rather
+ than being independent schema objects. Therefore there can be duplicate
+ trigger names defined in one schema, so long as they belong to
+ different tables. (<code class="literal">trigger_catalog</code> and
+ <code class="literal">trigger_schema</code> are really the values pertaining
+ to the table that the trigger is defined on.) Second, triggers can
+ be defined to fire on multiple events in
+ <span class="productname">PostgreSQL</span> (e.g., <code class="literal">ON INSERT OR
+ UPDATE</code>), whereas the SQL standard only allows one. If a
+ trigger is defined to fire on multiple events, it is represented as
+ multiple rows in the information schema, one for each type of
+ event. As a consequence of these two issues, the primary key of
+ the view <code class="literal">triggers</code> is really
+ <code class="literal">(trigger_catalog, trigger_schema, event_object_table,
+ trigger_name, event_manipulation)</code> instead of
+ <code class="literal">(trigger_catalog, trigger_schema, trigger_name)</code>,
+ which is what the SQL standard specifies. Nonetheless, if you
+ define your triggers in a manner that conforms with the SQL
+ standard (trigger names unique in the schema and only one event
+ type per trigger), this will not affect you.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Prior to <span class="productname">PostgreSQL</span> 9.1, this view's columns
+ <code class="structfield">action_timing</code>,
+ <code class="structfield">action_reference_old_table</code>,
+ <code class="structfield">action_reference_new_table</code>,
+ <code class="structfield">action_reference_old_row</code>, and
+ <code class="structfield">action_reference_new_row</code>
+ were named
+ <code class="structfield">condition_timing</code>,
+ <code class="structfield">condition_reference_old_table</code>,
+ <code class="structfield">condition_reference_new_table</code>,
+ <code class="structfield">condition_reference_old_row</code>, and
+ <code class="structfield">condition_reference_new_row</code>
+ respectively.
+ That was how they were named in the SQL:1999 standard.
+ The new naming conforms to SQL:2003 and later.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-triggered-update-columns.html" title="37.56. triggered_update_columns">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-udt-privileges.html" title="37.58. udt_privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.56. <code class="literal">triggered_update_columns</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.58. <code class="literal">udt_privileges</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-udt-privileges.html b/doc/src/sgml/html/infoschema-udt-privileges.html
new file mode 100644
index 0000000..820e25e
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-udt-privileges.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.58. udt_privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-triggers.html" title="37.57. triggers" /><link rel="next" href="infoschema-usage-privileges.html" title="37.59. usage_privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.58. <code class="literal">udt_privileges</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-triggers.html" title="37.57. triggers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-usage-privileges.html" title="37.59. usage_privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-UDT-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.58. <code class="literal">udt_privileges</code></h2></div></div></div><p>
+ The view <code class="literal">udt_privileges</code> identifies
+ <code class="literal">USAGE</code> privileges granted on user-defined types to a
+ currently enabled role or by a currently enabled role. There is one row for
+ each combination of type, grantor, and grantee. This view shows only
+ composite types (see under <a class="xref" href="infoschema-user-defined-types.html" title="37.60. user_defined_types">Section 37.60</a>
+ for why); see
+ <a class="xref" href="infoschema-usage-privileges.html" title="37.59. usage_privileges">Section 37.59</a> for domain privileges.
+ </p><div class="table" id="id-1.7.6.62.3"><p class="title"><strong>Table 37.56. <code class="structname">udt_privileges</code> Columns</strong></p><div class="table-contents"><table class="table" summary="udt_privileges Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the type (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">udt_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">TYPE USAGE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-triggers.html" title="37.57. triggers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-usage-privileges.html" title="37.59. usage_privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.57. <code class="literal">triggers</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.59. <code class="literal">usage_privileges</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-usage-privileges.html b/doc/src/sgml/html/infoschema-usage-privileges.html
new file mode 100644
index 0000000..2c5e1ed
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-usage-privileges.html
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.59. usage_privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-udt-privileges.html" title="37.58. udt_privileges" /><link rel="next" href="infoschema-user-defined-types.html" title="37.60. user_defined_types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.59. <code class="literal">usage_privileges</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-udt-privileges.html" title="37.58. udt_privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-user-defined-types.html" title="37.60. user_defined_types">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-USAGE-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.59. <code class="literal">usage_privileges</code></h2></div></div></div><p>
+ The view <code class="literal">usage_privileges</code> identifies
+ <code class="literal">USAGE</code> privileges granted on various kinds of
+ objects to a currently enabled role or by a currently enabled role.
+ In <span class="productname">PostgreSQL</span>, this currently applies to
+ collations, domains, foreign-data wrappers, foreign servers, and sequences. There is one
+ row for each combination of object, grantor, and grantee.
+ </p><p>
+ Since collations do not have real privileges
+ in <span class="productname">PostgreSQL</span>, this view shows implicit
+ non-grantable <code class="literal">USAGE</code> privileges granted by the
+ owner to <code class="literal">PUBLIC</code> for all collations. The other
+ object types, however, show real privileges.
+ </p><p>
+ In PostgreSQL, sequences also support <code class="literal">SELECT</code>
+ and <code class="literal">UPDATE</code> privileges in addition to
+ the <code class="literal">USAGE</code> privilege. These are nonstandard and therefore
+ not visible in the information schema.
+ </p><div class="table" id="id-1.7.6.63.5"><p class="title"><strong>Table 37.57. <code class="structname">usage_privileges</code> Columns</strong></p><div class="table-contents"><table class="table" summary="usage_privileges Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantor</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that granted the privilege
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grantee</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the role that the privilege was granted to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the object (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the object, if applicable,
+ else an empty string
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">object_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">COLLATION</code> or <code class="literal">DOMAIN</code> or <code class="literal">FOREIGN DATA WRAPPER</code> or <code class="literal">FOREIGN SERVER</code> or <code class="literal">SEQUENCE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">privilege_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Always <code class="literal">USAGE</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_grantable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the privilege is grantable, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-udt-privileges.html" title="37.58. udt_privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-user-defined-types.html" title="37.60. user_defined_types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.58. <code class="literal">udt_privileges</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.60. <code class="literal">user_defined_types</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-user-defined-types.html b/doc/src/sgml/html/infoschema-user-defined-types.html
new file mode 100644
index 0000000..e10e8a4
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-user-defined-types.html
@@ -0,0 +1,168 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.60. user_defined_types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-usage-privileges.html" title="37.59. usage_privileges" /><link rel="next" href="infoschema-user-mapping-options.html" title="37.61. user_mapping_options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.60. <code class="literal">user_defined_types</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-usage-privileges.html" title="37.59. usage_privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-user-mapping-options.html" title="37.61. user_mapping_options">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-USER-DEFINED-TYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.60. <code class="literal">user_defined_types</code></h2></div></div></div><p>
+ The view <code class="literal">user_defined_types</code> currently contains
+ all composite types defined in the current database.
+ Only those types are shown that the current user has access to (by way
+ of being the owner or having some privilege).
+ </p><p>
+ SQL knows about two kinds of user-defined types: structured types
+ (also known as composite types
+ in <span class="productname">PostgreSQL</span>) and distinct types (not
+ implemented in <span class="productname">PostgreSQL</span>). To be
+ future-proof, use the
+ column <code class="literal">user_defined_type_category</code> to
+ differentiate between these. Other user-defined types such as base
+ types and enums, which are <span class="productname">PostgreSQL</span>
+ extensions, are not shown here. For domains,
+ see <a class="xref" href="infoschema-domains.html" title="37.23. domains">Section 37.23</a> instead.
+ </p><div class="table" id="id-1.7.6.64.4"><p class="title"><strong>Table 37.58. <code class="structname">user_defined_types</code> Columns</strong></p><div class="table-contents"><table class="table" summary="user_defined_types Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the type (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the type
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_defined_type_category</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Currently always <code class="literal">STRUCTURED</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_instantiable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_final</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordering_form</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordering_category</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordering_routine_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordering_routine_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ordering_routine_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reference_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_maximum_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_octet_length</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">character_set_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">collation_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_precision_radix</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numeric_scale</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datetime_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_type</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">interval_precision</code> <code class="type">cardinal_number</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">source_dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ref_dtd_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Applies to a feature not available in <span class="productname">PostgreSQL</span>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-usage-privileges.html" title="37.59. usage_privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-user-mapping-options.html" title="37.61. user_mapping_options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.59. <code class="literal">usage_privileges</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.61. <code class="literal">user_mapping_options</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-user-mapping-options.html b/doc/src/sgml/html/infoschema-user-mapping-options.html
new file mode 100644
index 0000000..c36569b
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-user-mapping-options.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.61. user_mapping_options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-user-defined-types.html" title="37.60. user_defined_types" /><link rel="next" href="infoschema-user-mappings.html" title="37.62. user_mappings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.61. <code class="literal">user_mapping_options</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-user-defined-types.html" title="37.60. user_defined_types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-user-mappings.html" title="37.62. user_mappings">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-USER-MAPPING-OPTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.61. <code class="literal">user_mapping_options</code></h2></div></div></div><p>
+ The view <code class="literal">user_mapping_options</code> contains all the
+ options defined for user mappings in the current database. Only
+ those user mappings are shown where the current user has access to
+ the corresponding foreign server (by way of being the owner or
+ having some privilege).
+ </p><div class="table" id="id-1.7.6.65.3"><p class="title"><strong>Table 37.59. <code class="structname">user_mapping_options</code> Columns</strong></p><div class="table-contents"><table class="table" summary="user_mapping_options Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">authorization_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the user being mapped,
+ or <code class="literal">PUBLIC</code> if the mapping is public
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign server used by this
+ mapping is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign server used by this mapping
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of an option
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">option_value</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Value of the option. This column will show as null
+ unless the current user is the user being mapped, or the mapping
+ is for <code class="literal">PUBLIC</code> and the current user is the
+ server owner, or the current user is a superuser. The intent is
+ to protect password information stored as user mapping
+ option.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-user-defined-types.html" title="37.60. user_defined_types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-user-mappings.html" title="37.62. user_mappings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.60. <code class="literal">user_defined_types</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.62. <code class="literal">user_mappings</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-user-mappings.html b/doc/src/sgml/html/infoschema-user-mappings.html
new file mode 100644
index 0000000..9b821c9
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-user-mappings.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.62. user_mappings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-user-mapping-options.html" title="37.61. user_mapping_options" /><link rel="next" href="infoschema-view-column-usage.html" title="37.63. view_column_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.62. <code class="literal">user_mappings</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-user-mapping-options.html" title="37.61. user_mapping_options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-view-column-usage.html" title="37.63. view_column_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-USER-MAPPINGS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.62. <code class="literal">user_mappings</code></h2></div></div></div><p>
+ The view <code class="literal">user_mappings</code> contains all user
+ mappings defined in the current database. Only those user mappings
+ are shown where the current user has access to the corresponding
+ foreign server (by way of being the owner or having some
+ privilege).
+ </p><div class="table" id="id-1.7.6.66.3"><p class="title"><strong>Table 37.60. <code class="structname">user_mappings</code> Columns</strong></p><div class="table-contents"><table class="table" summary="user_mappings Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">authorization_identifier</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the user being mapped,
+ or <code class="literal">PUBLIC</code> if the mapping is public
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that the foreign server used by this
+ mapping is defined in (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">foreign_server_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the foreign server used by this mapping
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-user-mapping-options.html" title="37.61. user_mapping_options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-view-column-usage.html" title="37.63. view_column_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.61. <code class="literal">user_mapping_options</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.63. <code class="literal">view_column_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-view-column-usage.html b/doc/src/sgml/html/infoschema-view-column-usage.html
new file mode 100644
index 0000000..a6c1bd8
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-view-column-usage.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.63. view_column_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-user-mappings.html" title="37.62. user_mappings" /><link rel="next" href="infoschema-view-routine-usage.html" title="37.64. view_routine_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.63. <code class="literal">view_column_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-user-mappings.html" title="37.62. user_mappings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-view-routine-usage.html" title="37.64. view_routine_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-VIEW-COLUMN-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.63. <code class="literal">view_column_usage</code></h2></div></div></div><p>
+ The view <code class="literal">view_column_usage</code> identifies all
+ columns that are used in the query expression of a view (the
+ <code class="command">SELECT</code> statement that defines the view). A
+ column is only included if the table that contains the column is
+ owned by a currently enabled role.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Columns of system tables are not included. This should be fixed
+ sometime.
+ </p></div><div class="table" id="id-1.7.6.67.4"><p class="title"><strong>Table 37.61. <code class="structname">view_column_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="view_column_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the view (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that contains the
+ column that is used by the view (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that contains the
+ column that is used by the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that contains the column that is used by the
+ view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">column_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the column that is used by the view
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-user-mappings.html" title="37.62. user_mappings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-view-routine-usage.html" title="37.64. view_routine_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.62. <code class="literal">user_mappings</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.64. <code class="literal">view_routine_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-view-routine-usage.html b/doc/src/sgml/html/infoschema-view-routine-usage.html
new file mode 100644
index 0000000..7fa39e7
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-view-routine-usage.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.64. view_routine_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-view-column-usage.html" title="37.63. view_column_usage" /><link rel="next" href="infoschema-view-table-usage.html" title="37.65. view_table_usage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.64. <code class="literal">view_routine_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-view-column-usage.html" title="37.63. view_column_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-view-table-usage.html" title="37.65. view_table_usage">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-VIEW-ROUTINE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.64. <code class="literal">view_routine_usage</code></h2></div></div></div><p>
+ The view <code class="literal">view_routine_usage</code> identifies all
+ routines (functions and procedures) that are used in the query
+ expression of a view (the <code class="command">SELECT</code> statement that
+ defines the view). A routine is only included if that routine is
+ owned by a currently enabled role.
+ </p><div class="table" id="id-1.7.6.68.3"><p class="title"><strong>Table 37.62. <code class="structname">view_routine_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="view_routine_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the view (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database containing the function (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema containing the function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">specific_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ The <span class="quote">“<span class="quote">specific name</span>”</span> of the function. See <a class="xref" href="infoschema-routines.html" title="37.45. routines">Section 37.45</a> for more information.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-view-column-usage.html" title="37.63. view_column_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-view-table-usage.html" title="37.65. view_table_usage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.63. <code class="literal">view_column_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.65. <code class="literal">view_table_usage</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-view-table-usage.html b/doc/src/sgml/html/infoschema-view-table-usage.html
new file mode 100644
index 0000000..f310c1f
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-view-table-usage.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.65. view_table_usage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-view-routine-usage.html" title="37.64. view_routine_usage" /><link rel="next" href="infoschema-views.html" title="37.66. views" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.65. <code class="literal">view_table_usage</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-view-routine-usage.html" title="37.64. view_routine_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="infoschema-views.html" title="37.66. views">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-VIEW-TABLE-USAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.65. <code class="literal">view_table_usage</code></h2></div></div></div><p>
+ The view <code class="literal">view_table_usage</code> identifies all tables
+ that are used in the query expression of a view (the
+ <code class="command">SELECT</code> statement that defines the view). A
+ table is only included if that table is owned by a currently
+ enabled role.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ System tables are not included. This should be fixed sometime.
+ </p></div><div class="table" id="id-1.7.6.69.4"><p class="title"><strong>Table 37.63. <code class="structname">view_table_usage</code> Columns</strong></p><div class="table-contents"><table class="table" summary="view_table_usage Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the view (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the table that is
+ used by the view (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the table that is used by the
+ view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the table that is used by the view
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-view-routine-usage.html" title="37.64. view_routine_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="infoschema-views.html" title="37.66. views">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.64. <code class="literal">view_routine_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.66. <code class="literal">views</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/infoschema-views.html b/doc/src/sgml/html/infoschema-views.html
new file mode 100644
index 0000000..28aa069
--- /dev/null
+++ b/doc/src/sgml/html/infoschema-views.html
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.66. views</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-view-table-usage.html" title="37.65. view_table_usage" /><link rel="next" href="server-programming.html" title="Part V. Server Programming" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.66. <code class="literal">views</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-view-table-usage.html" title="37.65. view_table_usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><th width="60%" align="center">Chapter 37. The Information Schema</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="server-programming.html" title="Part V. Server Programming">Next</a></td></tr></table><hr /></div><div class="sect1" id="INFOSCHEMA-VIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.66. <code class="literal">views</code></h2></div></div></div><p>
+ The view <code class="literal">views</code> contains all views defined in the
+ current database. Only those views are shown that the current user
+ has access to (by way of being the owner or having some privilege).
+ </p><div class="table" id="id-1.7.6.70.3"><p class="title"><strong>Table 37.64. <code class="structname">views</code> Columns</strong></p><div class="table-contents"><table class="table" summary="views Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_catalog</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the database that contains the view (always the current database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_schema</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the schema that contains the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">table_name</code> <code class="type">sql_identifier</code>
+ </p>
+ <p>
+ Name of the view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">view_definition</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ Query expression defining the view (null if the view is not
+ owned by a currently enabled role)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">check_option</code> <code class="type">character_data</code>
+ </p>
+ <p>
+ <code class="literal">CASCADED</code> or <code class="literal">LOCAL</code> if the view
+ has a <code class="literal">CHECK OPTION</code> defined on it,
+ <code class="literal">NONE</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_updatable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the view is updatable (allows
+ <code class="command">UPDATE</code> and <code class="command">DELETE</code>),
+ <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_insertable_into</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the view is insertable into (allows
+ <code class="command">INSERT</code>), <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_trigger_updatable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the view has an <code class="literal">INSTEAD OF</code>
+ <code class="command">UPDATE</code> trigger defined on it, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_trigger_deletable</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the view has an <code class="literal">INSTEAD OF</code>
+ <code class="command">DELETE</code> trigger defined on it, <code class="literal">NO</code> if not
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_trigger_insertable_into</code> <code class="type">yes_or_no</code>
+ </p>
+ <p>
+ <code class="literal">YES</code> if the view has an <code class="literal">INSTEAD OF</code>
+ <code class="command">INSERT</code> trigger defined on it, <code class="literal">NO</code> if not
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-view-table-usage.html" title="37.65. view_table_usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="information-schema.html" title="Chapter 37. The Information Schema">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="server-programming.html" title="Part V. Server Programming">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.65. <code class="literal">view_table_usage</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part V. Server Programming</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-binaries.html b/doc/src/sgml/html/install-binaries.html
new file mode 100644
index 0000000..66dace3
--- /dev/null
+++ b/doc/src/sgml/html/install-binaries.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 16. Installation from Binaries</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="admin.html" title="Part III. Server Administration" /><link rel="next" href="installation.html" title="Chapter 17. Installation from Source Code" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 16. Installation from Binaries</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="admin.html" title="Part III. Server Administration">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="installation.html" title="Chapter 17. Installation from Source Code">Next</a></td></tr></table><hr /></div><div class="chapter" id="INSTALL-BINARIES"><div class="titlepage"><div><div><h2 class="title">Chapter 16. Installation from Binaries</h2></div></div></div><a id="id-1.6.3.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> is available in the form of binary
+ packages for most common operating systems today. When available, this is
+ the recommended way to install PostgreSQL for users of the system. Building
+ from source (see <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a>) is only recommended for
+ people developing <span class="productname">PostgreSQL</span> or extensions.
+ </p><p>
+ For an updated list of platforms providing binary packages, please visit
+ the download section on the <span class="productname">PostgreSQL</span> website at
+ <a class="ulink" href="https://www.postgresql.org/download/" target="_top">https://www.postgresql.org/download/</a> and follow the
+ instructions for the specific platform.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="admin.html" title="Part III. Server Administration">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="installation.html" title="Chapter 17. Installation from Source Code">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part III. Server Administration </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 17. Installation from Source Code</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-getsource.html b/doc/src/sgml/html/install-getsource.html
new file mode 100644
index 0000000..30d83db
--- /dev/null
+++ b/doc/src/sgml/html/install-getsource.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.3. Getting the Source</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-requirements.html" title="17.2. Requirements" /><link rel="next" href="install-procedure.html" title="17.4. Installation Procedure" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.3. Getting the Source</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-requirements.html" title="17.2. Requirements">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-procedure.html" title="17.4. Installation Procedure">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALL-GETSOURCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.3. Getting the Source</h2></div></div></div><p>
+ The <span class="productname">PostgreSQL</span> source code for released versions
+ can be obtained from the download section of our website:
+ <a class="ulink" href="https://www.postgresql.org/ftp/source/" target="_top">https://www.postgresql.org/ftp/source/</a>.
+ Download the
+ <code class="filename">postgresql-<em class="replaceable"><code>version</code></em>.tar.gz</code>
+ or <code class="filename">postgresql-<em class="replaceable"><code>version</code></em>.tar.bz2</code>
+ file you're interested in, then unpack it:
+</p><pre class="screen">
+<strong class="userinput"><code>tar xf postgresql-<em class="replaceable"><code>version</code></em>.tar.bz2</code></strong>
+</pre><p>
+ This will create a directory
+ <code class="filename">postgresql-<em class="replaceable"><code>version</code></em></code> under
+ the current directory with the <span class="productname">PostgreSQL</span> sources.
+ Change into that directory for the rest of the installation procedure.
+ </p><p>
+ Alternatively, you can use the Git version control system; see
+ <a class="xref" href="git.html" title="I.1. Getting the Source via Git">Section I.1</a> for more information.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-requirements.html" title="17.2. Requirements">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-procedure.html" title="17.4. Installation Procedure">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.2. Requirements </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.4. Installation Procedure</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-post.html b/doc/src/sgml/html/install-post.html
new file mode 100644
index 0000000..ffa9d28
--- /dev/null
+++ b/doc/src/sgml/html/install-post.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.5. Post-Installation Setup</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-procedure.html" title="17.4. Installation Procedure" /><link rel="next" href="supported-platforms.html" title="17.6. Supported Platforms" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.5. Post-Installation Setup</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-procedure.html" title="17.4. Installation Procedure">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="supported-platforms.html" title="17.6. Supported Platforms">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALL-POST"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.5. Post-Installation Setup</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="install-post.html#INSTALL-POST-SHLIBS">17.5.1. Shared Libraries</a></span></dt><dt><span class="sect2"><a href="install-post.html#id-1.6.4.9.3">17.5.2. Environment Variables</a></span></dt></dl></div><div class="sect2" id="INSTALL-POST-SHLIBS"><div class="titlepage"><div><div><h3 class="title">17.5.1. Shared Libraries</h3></div></div></div><a id="id-1.6.4.9.2.2" class="indexterm"></a><p>
+ On some systems with shared libraries
+ you need to tell the system how to find the newly installed
+ shared libraries. The systems on which this is
+ <span class="emphasis"><em>not</em></span> necessary include
+ <span class="systemitem">FreeBSD</span>,
+ <span class="systemitem">HP-UX</span>,
+ <span class="systemitem">Linux</span>,
+ <span class="systemitem">NetBSD</span>, <span class="systemitem">OpenBSD</span>, and
+ <span class="systemitem">Solaris</span>.
+ </p><p>
+ The method to set the shared library search path varies between
+ platforms, but the most widely-used method is to set the
+ environment variable <code class="envar">LD_LIBRARY_PATH</code> like so: In Bourne
+ shells (<code class="command">sh</code>, <code class="command">ksh</code>, <code class="command">bash</code>, <code class="command">zsh</code>):
+</p><pre class="programlisting">
+LD_LIBRARY_PATH=/usr/local/pgsql/lib
+export LD_LIBRARY_PATH
+</pre><p>
+ or in <code class="command">csh</code> or <code class="command">tcsh</code>:
+</p><pre class="programlisting">
+setenv LD_LIBRARY_PATH /usr/local/pgsql/lib
+</pre><p>
+ Replace <code class="literal">/usr/local/pgsql/lib</code> with whatever you set
+ <code class="option"><code class="literal">--libdir</code></code> to in <a class="xref" href="install-procedure.html#CONFIGURE" title="Configuration">Step 1</a>.
+ You should put these commands into a shell start-up file such as
+ <code class="filename">/etc/profile</code> or <code class="filename">~/.bash_profile</code>. Some
+ good information about the caveats associated with this method can
+ be found at <a class="ulink" href="http://xahlee.info/UnixResource_dir/_/ldpath.html" target="_top">http://xahlee.info/UnixResource_dir/_/ldpath.html</a>.
+ </p><p>
+ On some systems it might be preferable to set the environment
+ variable <code class="envar">LD_RUN_PATH</code> <span class="emphasis"><em>before</em></span>
+ building.
+ </p><p>
+ On <span class="systemitem">Cygwin</span>, put the library
+ directory in the <code class="envar">PATH</code> or move the
+ <code class="filename">.dll</code> files into the <code class="filename">bin</code>
+ directory.
+ </p><p>
+ If in doubt, refer to the manual pages of your system (perhaps
+ <code class="command">ld.so</code> or <code class="command">rld</code>). If you later
+ get a message like:
+</p><pre class="screen">
+psql: error in loading shared libraries
+libpq.so.2.1: cannot open shared object file: No such file or directory
+</pre><p>
+ then this step was necessary. Simply take care of it then.
+ </p><p>
+ <a id="id-1.6.4.9.2.8.1" class="indexterm"></a>
+ If you are on <span class="systemitem">Linux</span> and you have root
+ access, you can run:
+</p><pre class="programlisting">
+/sbin/ldconfig /usr/local/pgsql/lib
+</pre><p>
+ (or equivalent directory) after installation to enable the
+ run-time linker to find the shared libraries faster. Refer to the
+ manual page of <code class="command">ldconfig</code> for more information. On
+ <span class="systemitem">FreeBSD</span>, <span class="systemitem">NetBSD</span>, and <span class="systemitem">OpenBSD</span> the command is:
+</p><pre class="programlisting">
+/sbin/ldconfig -m /usr/local/pgsql/lib
+</pre><p>
+ instead. Other systems are not known to have an equivalent
+ command.
+ </p></div><div class="sect2" id="id-1.6.4.9.3"><div class="titlepage"><div><div><h3 class="title">17.5.2. Environment Variables</h3></div></div></div><a id="id-1.6.4.9.3.2" class="indexterm"></a><p>
+ If you installed into <code class="filename">/usr/local/pgsql</code> or some other
+ location that is not searched for programs by default, you should
+ add <code class="filename">/usr/local/pgsql/bin</code> (or whatever you set
+ <code class="option"><code class="literal">--bindir</code></code> to in <a class="xref" href="install-procedure.html#CONFIGURE" title="Configuration">Step 1</a>)
+ into your <code class="envar">PATH</code>. Strictly speaking, this is not
+ necessary, but it will make the use of <span class="productname">PostgreSQL</span>
+ much more convenient.
+ </p><p>
+ To do this, add the following to your shell start-up file, such as
+ <code class="filename">~/.bash_profile</code> (or <code class="filename">/etc/profile</code>, if you
+ want it to affect all users):
+</p><pre class="programlisting">
+PATH=/usr/local/pgsql/bin:$PATH
+export PATH
+</pre><p>
+ If you are using <code class="command">csh</code> or <code class="command">tcsh</code>, then use this command:
+</p><pre class="programlisting">
+set path = ( /usr/local/pgsql/bin $path )
+</pre><p>
+ </p><p>
+ <a id="id-1.6.4.9.3.5.1" class="indexterm"></a>
+ To enable your system to find the <span class="application">man</span>
+ documentation, you need to add lines like the following to a
+ shell start-up file unless you installed into a location that is
+ searched by default:
+</p><pre class="programlisting">
+MANPATH=/usr/local/pgsql/share/man:$MANPATH
+export MANPATH
+</pre><p>
+ </p><p>
+ The environment variables <code class="envar">PGHOST</code> and <code class="envar">PGPORT</code>
+ specify to client applications the host and port of the database
+ server, overriding the compiled-in defaults. If you are going to
+ run client applications remotely then it is convenient if every
+ user that plans to use the database sets <code class="envar">PGHOST</code>. This
+ is not required, however; the settings can be communicated via command
+ line options to most client programs.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-procedure.html" title="17.4. Installation Procedure">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="supported-platforms.html" title="17.6. Supported Platforms">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.4. Installation Procedure </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.6. Supported Platforms</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-procedure.html b/doc/src/sgml/html/install-procedure.html
new file mode 100644
index 0000000..3c3166c
--- /dev/null
+++ b/doc/src/sgml/html/install-procedure.html
@@ -0,0 +1,818 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.4. Installation Procedure</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-getsource.html" title="17.3. Getting the Source" /><link rel="next" href="install-post.html" title="17.5. Post-Installation Setup" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.4. Installation Procedure</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-getsource.html" title="17.3. Getting the Source">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-post.html" title="17.5. Post-Installation Setup">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALL-PROCEDURE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.4. Installation Procedure</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="install-procedure.html#CONFIGURE-OPTIONS">17.4.1. <code class="filename">configure</code> Options</a></span></dt><dt><span class="sect2"><a href="install-procedure.html#CONFIGURE-ENVVARS">17.4.2. <code class="filename">configure</code> Environment Variables</a></span></dt></dl></div><div class="procedure"><ol class="procedure" type="1"><li class="step" id="CONFIGURE"><p class="title"><strong>Configuration</strong></p><a id="id-1.6.4.8.2.1.2" class="indexterm"></a><p>
+ The first step of the installation procedure is to configure the
+ source tree for your system and choose the options you would like.
+ This is done by running the <code class="filename">configure</code> script. For a
+ default installation simply enter:
+</p><pre class="screen">
+<strong class="userinput"><code>./configure</code></strong>
+</pre><p>
+ This script will run a number of tests to determine values for various
+ system dependent variables and detect any quirks of your
+ operating system, and finally will create several files in the
+ build tree to record what it found.
+ </p><p>
+ You can also run <code class="filename">configure</code> in a directory outside
+ the source tree, and then build there, if you want to keep the build
+ directory separate from the original source files. This procedure is
+ called a
+ <a id="id-1.6.4.8.2.1.4.2" class="indexterm"></a><em class="firstterm">VPATH</em>
+ build. Here's how:
+</p><pre class="screen">
+<strong class="userinput"><code>mkdir build_dir</code></strong>
+<strong class="userinput"><code>cd build_dir</code></strong>
+<strong class="userinput"><code>/path/to/source/tree/configure [options go here]</code></strong>
+<strong class="userinput"><code>make</code></strong>
+</pre><p>
+ </p><p>
+ The default configuration will build the server and utilities, as
+ well as all client applications and interfaces that require only a
+ C compiler. All files will be installed under
+ <code class="filename">/usr/local/pgsql</code> by default.
+ </p><p>
+ You can customize the build and installation process by supplying one
+ or more command line options to <code class="filename">configure</code>.
+ Typically you would customize the install location, or the set of
+ optional features that are built. <code class="filename">configure</code>
+ has a large number of options, which are described in
+ <a class="xref" href="install-procedure.html#CONFIGURE-OPTIONS" title="17.4.1. configure Options">Section 17.4.1</a>.
+ </p><p>
+ Also, <code class="filename">configure</code> responds to certain environment
+ variables, as described in <a class="xref" href="install-procedure.html#CONFIGURE-ENVVARS" title="17.4.2. configure Environment Variables">Section 17.4.2</a>.
+ These provide additional ways to customize the configuration.
+ </p></li><li class="step" id="BUILD"><p class="title"><strong>Build</strong></p><p>
+ To start the build, type either of:
+</p><pre class="screen">
+<strong class="userinput"><code>make</code></strong>
+<strong class="userinput"><code>make all</code></strong>
+</pre><p>
+ (Remember to use <acronym class="acronym">GNU</acronym> <span class="application">make</span>.)
+ The build will take a few minutes depending on your
+ hardware.
+ </p><p>
+ If you want to build everything that can be built, including the
+ documentation (HTML and man pages), and the additional modules
+ (<code class="filename">contrib</code>), type instead:
+</p><pre class="screen">
+<strong class="userinput"><code>make world</code></strong>
+</pre><p>
+ </p><p>
+ If you want to build everything that can be built, including the
+ additional modules (<code class="filename">contrib</code>), but without
+ the documentation, type instead:
+</p><pre class="screen">
+<strong class="userinput"><code>make world-bin</code></strong>
+</pre><p>
+ </p><p>
+ If you want to invoke the build from another makefile rather than
+ manually, you must unset <code class="varname">MAKELEVEL</code> or set it to zero,
+ for instance like this:
+</p><pre class="programlisting">
+build-postgresql:
+ $(MAKE) -C postgresql MAKELEVEL=0 all
+</pre><p>
+ Failure to do that can lead to strange error messages, typically about
+ missing header files.
+ </p></li><li class="step"><p class="title"><strong>Regression Tests</strong></p><a id="id-1.6.4.8.2.3.2" class="indexterm"></a><p>
+ If you want to test the newly built server before you install it,
+ you can run the regression tests at this point. The regression
+ tests are a test suite to verify that <span class="productname">PostgreSQL</span>
+ runs on your machine in the way the developers expected it
+ to. Type:
+</p><pre class="screen">
+<strong class="userinput"><code>make check</code></strong>
+</pre><p>
+ (This won't work as root; do it as an unprivileged user.)
+ See <a class="xref" href="regress.html" title="Chapter 33. Regression Tests">Chapter 33</a> for
+ detailed information about interpreting the test results. You can
+ repeat this test at any later time by issuing the same command.
+ </p></li><li class="step" id="INSTALL"><p class="title"><strong>Installing the Files</strong></p><div class="note"><h3 class="title">Note</h3><p>
+ If you are upgrading an existing system be sure to read
+ <a class="xref" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster">Section 19.6</a>,
+ which has instructions about upgrading a
+ cluster.
+ </p></div><p>
+ To install <span class="productname">PostgreSQL</span> enter:
+</p><pre class="screen">
+<strong class="userinput"><code>make install</code></strong>
+</pre><p>
+ This will install files into the directories that were specified
+ in <a class="xref" href="install-procedure.html#CONFIGURE" title="Configuration">Step 1</a>. Make sure that you have appropriate
+ permissions to write into that area. Normally you need to do this
+ step as root. Alternatively, you can create the target
+ directories in advance and arrange for appropriate permissions to
+ be granted.
+ </p><p>
+ To install the documentation (HTML and man pages), enter:
+</p><pre class="screen">
+<strong class="userinput"><code>make install-docs</code></strong>
+</pre><p>
+ </p><p>
+ If you built the world above, type instead:
+</p><pre class="screen">
+<strong class="userinput"><code>make install-world</code></strong>
+</pre><p>
+ This also installs the documentation.
+ </p><p>
+ If you built the world without the documentation above, type instead:
+</p><pre class="screen">
+<strong class="userinput"><code>make install-world-bin</code></strong>
+</pre><p>
+ </p><p>
+ You can use <code class="literal">make install-strip</code> instead of
+ <code class="literal">make install</code> to strip the executable files and
+ libraries as they are installed. This will save some space. If
+ you built with debugging support, stripping will effectively
+ remove the debugging support, so it should only be done if
+ debugging is no longer needed. <code class="literal">install-strip</code>
+ tries to do a reasonable job saving space, but it does not have
+ perfect knowledge of how to strip every unneeded byte from an
+ executable file, so if you want to save all the disk space you
+ possibly can, you will have to do manual work.
+ </p><p>
+ The standard installation provides all the header files needed for client
+ application development as well as for server-side program
+ development, such as custom functions or data types written in C.
+ </p><p><strong>Client-only installation: </strong>
+ If you want to install only the client applications and
+ interface libraries, then you can use these commands:
+</p><pre class="screen">
+<strong class="userinput"><code>make -C src/bin install</code></strong>
+<strong class="userinput"><code>make -C src/include install</code></strong>
+<strong class="userinput"><code>make -C src/interfaces install</code></strong>
+<strong class="userinput"><code>make -C doc install</code></strong>
+</pre><p>
+ <code class="filename">src/bin</code> has a few binaries for server-only use,
+ but they are small.
+ </p></li></ol></div><p><strong>Uninstallation: </strong>
+ To undo the installation use the command <code class="command">make
+ uninstall</code>. However, this will not remove any created directories.
+ </p><p><strong>Cleaning: </strong>
+ After the installation you can free disk space by removing the built
+ files from the source tree with the command <code class="command">make
+ clean</code>. This will preserve the files made by the <code class="command">configure</code>
+ program, so that you can rebuild everything with <code class="command">make</code>
+ later on. To reset the source tree to the state in which it was
+ distributed, use <code class="command">make distclean</code>. If you are going to
+ build for several platforms within the same source tree you must do
+ this and re-configure for each platform. (Alternatively, use
+ a separate build tree for each platform, so that the source tree
+ remains unmodified.)
+ </p><p>
+ If you perform a build and then discover that your <code class="command">configure</code>
+ options were wrong, or if you change anything that <code class="command">configure</code>
+ investigates (for example, software upgrades), then it's a good
+ idea to do <code class="command">make distclean</code> before reconfiguring and
+ rebuilding. Without this, your changes in configuration choices
+ might not propagate everywhere they need to.
+ </p><div class="sect2" id="CONFIGURE-OPTIONS"><div class="titlepage"><div><div><h3 class="title">17.4.1. <code class="filename">configure</code> Options</h3></div></div></div><a id="id-1.6.4.8.6.2" class="indexterm"></a><p>
+ <code class="command">configure</code>'s command line options are explained below.
+ This list is not exhaustive (use <code class="literal">./configure --help</code>
+ to get one that is). The options not covered here are meant for
+ advanced use-cases such as cross-compilation, and are documented in
+ the standard Autoconf documentation.
+ </p><div class="sect3" id="CONFIGURE-OPTIONS-LOCATIONS"><div class="titlepage"><div><div><h4 class="title">17.4.1.1. Installation Locations</h4></div></div></div><p>
+ These options control where <code class="literal">make install</code> will put
+ the files. The <code class="option">--prefix</code> option is sufficient for
+ most cases. If you have special needs, you can customize the
+ installation subdirectories with the other options described in this
+ section. Beware however that changing the relative locations of the
+ different subdirectories may render the installation non-relocatable,
+ meaning you won't be able to move it after installation.
+ (The <code class="literal">man</code> and <code class="literal">doc</code> locations are
+ not affected by this restriction.) For relocatable installs, you
+ might want to use the <code class="literal">--disable-rpath</code> option
+ described later.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--prefix=<em class="replaceable"><code>PREFIX</code></em></code></span></dt><dd><p>
+ Install all files under the directory <em class="replaceable"><code>PREFIX</code></em>
+ instead of <code class="filename">/usr/local/pgsql</code>. The actual
+ files will be installed into various subdirectories; no files
+ will ever be installed directly into the
+ <em class="replaceable"><code>PREFIX</code></em> directory.
+ </p></dd><dt><span class="term"><code class="option">--exec-prefix=<em class="replaceable"><code>EXEC-PREFIX</code></em></code></span></dt><dd><p>
+ You can install architecture-dependent files under a
+ different prefix, <em class="replaceable"><code>EXEC-PREFIX</code></em>, than what
+ <em class="replaceable"><code>PREFIX</code></em> was set to. This can be useful to
+ share architecture-independent files between hosts. If you
+ omit this, then <em class="replaceable"><code>EXEC-PREFIX</code></em> is set equal to
+ <em class="replaceable"><code>PREFIX</code></em> and both architecture-dependent and
+ independent files will be installed under the same tree,
+ which is probably what you want.
+ </p></dd><dt><span class="term"><code class="option">--bindir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Specifies the directory for executable programs. The default
+ is <code class="filename"><em class="replaceable"><code>EXEC-PREFIX</code></em>/bin</code>, which
+ normally means <code class="filename">/usr/local/pgsql/bin</code>.
+ </p></dd><dt><span class="term"><code class="option">--sysconfdir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the directory for various configuration files,
+ <code class="filename"><em class="replaceable"><code>PREFIX</code></em>/etc</code> by default.
+ </p></dd><dt><span class="term"><code class="option">--libdir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the location to install libraries and dynamically loadable
+ modules. The default is
+ <code class="filename"><em class="replaceable"><code>EXEC-PREFIX</code></em>/lib</code>.
+ </p></dd><dt><span class="term"><code class="option">--includedir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the directory for installing C and C++ header files. The
+ default is <code class="filename"><em class="replaceable"><code>PREFIX</code></em>/include</code>.
+ </p></dd><dt><span class="term"><code class="option">--datarootdir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the root directory for various types of read-only data
+ files. This only sets the default for some of the following
+ options. The default is
+ <code class="filename"><em class="replaceable"><code>PREFIX</code></em>/share</code>.
+ </p></dd><dt><span class="term"><code class="option">--datadir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the directory for read-only data files used by the
+ installed programs. The default is
+ <code class="filename"><em class="replaceable"><code>DATAROOTDIR</code></em></code>. Note that this has
+ nothing to do with where your database files will be placed.
+ </p></dd><dt><span class="term"><code class="option">--localedir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the directory for installing locale data, in particular
+ message translation catalog files. The default is
+ <code class="filename"><em class="replaceable"><code>DATAROOTDIR</code></em>/locale</code>.
+ </p></dd><dt><span class="term"><code class="option">--mandir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ The man pages that come with <span class="productname">PostgreSQL</span> will be installed under
+ this directory, in their respective
+ <code class="filename">man<em class="replaceable"><code>x</code></em></code> subdirectories.
+ The default is <code class="filename"><em class="replaceable"><code>DATAROOTDIR</code></em>/man</code>.
+ </p></dd><dt><span class="term"><code class="option">--docdir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Sets the root directory for installing documentation files,
+ except <span class="quote">“<span class="quote">man</span>”</span> pages. This only sets the default for
+ the following options. The default value for this option is
+ <code class="filename"><em class="replaceable"><code>DATAROOTDIR</code></em>/doc/postgresql</code>.
+ </p></dd><dt><span class="term"><code class="option">--htmldir=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ The HTML-formatted documentation for
+ <span class="productname">PostgreSQL</span> will be installed under
+ this directory. The default is
+ <code class="filename"><em class="replaceable"><code>DATAROOTDIR</code></em></code>.
+ </p></dd></dl></div><div class="note"><h3 class="title">Note</h3><p>
+ Care has been taken to make it possible to install
+ <span class="productname">PostgreSQL</span> into shared installation locations
+ (such as <code class="filename">/usr/local/include</code>) without
+ interfering with the namespace of the rest of the system. First,
+ the string <span class="quote">“<span class="quote"><code class="literal">/postgresql</code></span>”</span> is
+ automatically appended to <code class="varname">datadir</code>,
+ <code class="varname">sysconfdir</code>, and <code class="varname">docdir</code>,
+ unless the fully expanded directory name already contains the
+ string <span class="quote">“<span class="quote"><code class="literal">postgres</code></span>”</span> or
+ <span class="quote">“<span class="quote"><code class="literal">pgsql</code></span>”</span>. For example, if you choose
+ <code class="filename">/usr/local</code> as prefix, the documentation will
+ be installed in <code class="filename">/usr/local/doc/postgresql</code>,
+ but if the prefix is <code class="filename">/opt/postgres</code>, then it
+ will be in <code class="filename">/opt/postgres/doc</code>. The public C
+ header files of the client interfaces are installed into
+ <code class="varname">includedir</code> and are namespace-clean. The
+ internal header files and the server header files are installed
+ into private directories under <code class="varname">includedir</code>. See
+ the documentation of each interface for information about how to
+ access its header files. Finally, a private subdirectory will
+ also be created, if appropriate, under <code class="varname">libdir</code>
+ for dynamically loadable modules.
+ </p></div></div><div class="sect3" id="CONFIGURE-OPTIONS-FEATURES"><div class="titlepage"><div><div><h4 class="title">17.4.1.2. <span class="productname">PostgreSQL</span> Features</h4></div></div></div><p>
+ The options described in this section enable building of
+ various <span class="productname">PostgreSQL</span> features that are not
+ built by default. Most of these are non-default only because they
+ require additional software, as described in
+ <a class="xref" href="install-requirements.html" title="17.2. Requirements">Section 17.2</a>.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--enable-nls[<span class="optional">=<em class="replaceable"><code>LANGUAGES</code></em></span>]</code></span></dt><dd><p>
+ Enables Native Language Support (<acronym class="acronym">NLS</acronym>),
+ that is, the ability to display a program's messages in a
+ language other than English.
+ <em class="replaceable"><code>LANGUAGES</code></em> is an optional space-separated
+ list of codes of the languages that you want supported, for
+ example <code class="literal">--enable-nls='de fr'</code>. (The intersection
+ between your list and the set of actually provided
+ translations will be computed automatically.) If you do not
+ specify a list, then all available translations are
+ installed.
+ </p><p>
+ To use this option, you will need an implementation of the
+ <span class="application">Gettext</span> API.
+ </p></dd><dt><span class="term"><code class="option">--with-perl</code></span></dt><dd><p>
+ Build the <span class="application">PL/Perl</span> server-side language.
+ </p></dd><dt><span class="term"><code class="option">--with-python</code></span></dt><dd><p>
+ Build the <span class="application">PL/Python</span> server-side language.
+ </p></dd><dt><span class="term"><code class="option">--with-tcl</code></span></dt><dd><p>
+ Build the <span class="application">PL/Tcl</span> server-side language.
+ </p></dd><dt><span class="term"><code class="option">--with-tclconfig=<em class="replaceable"><code>DIRECTORY</code></em></code></span></dt><dd><p>
+ Tcl installs the file <code class="filename">tclConfig.sh</code>, which
+ contains configuration information needed to build modules
+ interfacing to Tcl. This file is normally found automatically
+ at a well-known location, but if you want to use a different
+ version of Tcl you can specify the directory in which to look
+ for <code class="filename">tclConfig.sh</code>.
+ </p></dd><dt><span class="term"><code class="option">--with-icu</code></span></dt><dd><p>
+ Build with support for
+ the <span class="productname">ICU</span><a id="id-1.6.4.8.6.5.3.6.2.1.2" class="indexterm"></a>
+ library, enabling use of ICU collation
+ features<span class="phrase"> (see
+ <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>)</span>.
+ This requires the <span class="productname">ICU4C</span> package
+ to be installed. The minimum required version
+ of <span class="productname">ICU4C</span> is currently 4.2.
+ </p><p>
+ By default,
+ <span class="productname">pkg-config</span><a id="id-1.6.4.8.6.5.3.6.2.2.2" class="indexterm"></a>
+ will be used to find the required compilation options. This is
+ supported for <span class="productname">ICU4C</span> version 4.6 and later.
+ For older versions, or if <span class="productname">pkg-config</span> is
+ not available, the variables <code class="envar">ICU_CFLAGS</code>
+ and <code class="envar">ICU_LIBS</code> can be specified
+ to <code class="filename">configure</code>, like in this example:
+</p><pre class="programlisting">
+./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata'
+</pre><p>
+ (If <span class="productname">ICU4C</span> is in the default search path
+ for the compiler, then you still need to specify nonempty strings in
+ order to avoid use of <span class="productname">pkg-config</span>, for
+ example, <code class="literal">ICU_CFLAGS=' '</code>.)
+ </p></dd><dt id="CONFIGURE-WITH-LLVM"><span class="term"><code class="option">--with-llvm</code></span></dt><dd><p>
+ Build with support for <span class="productname">LLVM</span> based
+ <acronym class="acronym">JIT</acronym> compilation<span class="phrase"> (see <a class="xref" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Chapter 32</a>)</span>. This
+ requires the <span class="productname">LLVM</span> library to be installed.
+ The minimum required version of <span class="productname">LLVM</span> is
+ currently 3.9.
+ </p><p>
+ <code class="command">llvm-config</code><a id="id-1.6.4.8.6.5.3.7.2.2.2" class="indexterm"></a>
+ will be used to find the required compilation options.
+ <code class="command">llvm-config</code>, and then
+ <code class="command">llvm-config-$major-$minor</code> for all supported
+ versions, will be searched for in your <code class="envar">PATH</code>. If
+ that would not yield the desired program,
+ use <code class="envar">LLVM_CONFIG</code> to specify a path to the
+ correct <code class="command">llvm-config</code>. For example
+</p><pre class="programlisting">
+./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config'
+</pre><p>
+ </p><p>
+ <span class="productname">LLVM</span> support requires a compatible
+ <code class="command">clang</code> compiler (specified, if necessary, using the
+ <code class="envar">CLANG</code> environment variable), and a working C++
+ compiler (specified, if necessary, using the <code class="envar">CXX</code>
+ environment variable).
+ </p></dd><dt><span class="term"><code class="option">--with-lz4</code></span></dt><dd><p>
+ Build with <span class="productname">LZ4</span> compression support.
+ </p></dd><dt><span class="term"><code class="option">--with-zstd</code></span></dt><dd><p>
+ Build with <span class="productname">Zstandard</span> compression support.
+ </p></dd><dt><span class="term"><code class="option">--with-ssl=<em class="replaceable"><code>LIBRARY</code></em></code>
+ <a id="id-1.6.4.8.6.5.3.10.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Build with support for <acronym class="acronym">SSL</acronym> (encrypted)
+ connections. The only <em class="replaceable"><code>LIBRARY</code></em>
+ supported is <code class="option">openssl</code>. This requires the
+ <span class="productname">OpenSSL</span> package to be installed.
+ <code class="filename">configure</code> will check for the required
+ header files and libraries to make sure that your
+ <span class="productname">OpenSSL</span> installation is sufficient
+ before proceeding.
+ </p></dd><dt><span class="term"><code class="option">--with-openssl</code></span></dt><dd><p>
+ Obsolete equivalent of <code class="literal">--with-ssl=openssl</code>.
+ </p></dd><dt><span class="term"><code class="option">--with-gssapi</code></span></dt><dd><p>
+ Build with support for GSSAPI authentication. On many systems, the
+ GSSAPI system (usually a part of the Kerberos installation) is not
+ installed in a location
+ that is searched by default (e.g., <code class="filename">/usr/include</code>,
+ <code class="filename">/usr/lib</code>), so you must use the options
+ <code class="option">--with-includes</code> and <code class="option">--with-libraries</code> in
+ addition to this option. <code class="filename">configure</code> will check
+ for the required header files and libraries to make sure that
+ your GSSAPI installation is sufficient before proceeding.
+ </p></dd><dt><span class="term"><code class="option">--with-ldap</code></span></dt><dd><p>
+ Build with <acronym class="acronym">LDAP</acronym><a id="id-1.6.4.8.6.5.3.13.2.1.2" class="indexterm"></a>
+ support for authentication and connection parameter lookup (see
+ <span id="INSTALL-LDAP-LINKS" class="phrase"><a class="xref" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters">Section 34.18</a> and
+ <a class="xref" href="auth-ldap.html" title="21.10. LDAP Authentication">Section 21.10</a></span> for more information). On Unix,
+ this requires the <span class="productname">OpenLDAP</span> package to be
+ installed. On Windows, the default <span class="productname">WinLDAP</span>
+ library is used. <code class="filename">configure</code> will check for the required
+ header files and libraries to make sure that your
+ <span class="productname">OpenLDAP</span> installation is sufficient before
+ proceeding.
+ </p></dd><dt><span class="term"><code class="option">--with-pam</code></span></dt><dd><p>
+ Build with <acronym class="acronym">PAM</acronym><a id="id-1.6.4.8.6.5.3.14.2.1.2" class="indexterm"></a>
+ (Pluggable Authentication Modules) support.
+ </p></dd><dt><span class="term"><code class="option">--with-bsd-auth</code></span></dt><dd><p>
+ Build with BSD Authentication support.
+ (The BSD Authentication framework is
+ currently only available on OpenBSD.)
+ </p></dd><dt><span class="term"><code class="option">--with-systemd</code></span></dt><dd><p>
+ Build with support
+ for <span class="application">systemd</span><a id="id-1.6.4.8.6.5.3.16.2.1.2" class="indexterm"></a>
+ service notifications. This improves integration if the server
+ is started under <span class="application">systemd</span> but has no impact
+ otherwise<span class="phrase">; see <a class="xref" href="server-start.html" title="19.3. Starting the Database Server">Section 19.3</a> for more
+ information</span>. <span class="application">libsystemd</span> and the
+ associated header files need to be installed to use this option.
+ </p></dd><dt><span class="term"><code class="option">--with-bonjour</code></span></dt><dd><p>
+ Build with support for Bonjour automatic service discovery.
+ This requires Bonjour support in your operating system.
+ Recommended on macOS.
+ </p></dd><dt><span class="term"><code class="option">--with-uuid=<em class="replaceable"><code>LIBRARY</code></em></code></span></dt><dd><p>
+ Build the <a class="xref" href="uuid-ossp.html" title="F.49. uuid-ossp">uuid-ossp</a> module
+ (which provides functions to generate UUIDs), using the specified
+ UUID library.<a id="id-1.6.4.8.6.5.3.18.2.1.2" class="indexterm"></a>
+ <em class="replaceable"><code>LIBRARY</code></em> must be one of:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="option">bsd</code> to use the UUID functions found in FreeBSD
+ and some other BSD-derived systems
+ </p></li><li class="listitem"><p>
+ <code class="option">e2fs</code> to use the UUID library created by
+ the <code class="literal">e2fsprogs</code> project; this library is present in most
+ Linux systems and in macOS, and can be obtained for other
+ platforms as well
+ </p></li><li class="listitem"><p>
+ <code class="option">ossp</code> to use the <a class="ulink" href="http://www.ossp.org/pkg/lib/uuid/" target="_top">OSSP UUID library</a>
+ </p></li></ul></div></dd><dt><span class="term"><code class="option">--with-ossp-uuid</code></span></dt><dd><p>
+ Obsolete equivalent of <code class="literal">--with-uuid=ossp</code>.
+ </p></dd><dt><span class="term"><code class="option">--with-libxml</code></span></dt><dd><p>
+ Build with libxml2, enabling SQL/XML support. Libxml2 version 2.6.23 or
+ later is required for this feature.
+ </p><p>
+ To detect the required compiler and linker options, PostgreSQL will
+ query <code class="command">pkg-config</code>, if that is installed and knows
+ about libxml2. Otherwise the program <code class="command">xml2-config</code>,
+ which is installed by libxml2, will be used if it is found. Use
+ of <code class="command">pkg-config</code> is preferred, because it can deal
+ with multi-architecture installations better.
+ </p><p>
+ To use a libxml2 installation that is in an unusual location, you
+ can set <code class="command">pkg-config</code>-related environment
+ variables (see its documentation), or set the environment variable
+ <code class="envar">XML2_CONFIG</code> to point to
+ the <code class="command">xml2-config</code> program belonging to the libxml2
+ installation, or set the variables <code class="envar">XML2_CFLAGS</code>
+ and <code class="envar">XML2_LIBS</code>. (If <code class="command">pkg-config</code> is
+ installed, then to override its idea of where libxml2 is you must
+ either set <code class="envar">XML2_CONFIG</code> or set
+ both <code class="envar">XML2_CFLAGS</code> and <code class="envar">XML2_LIBS</code> to
+ nonempty strings.)
+ </p></dd><dt><span class="term"><code class="option">--with-libxslt</code></span></dt><dd><p>
+ Build with libxslt, enabling the
+ <a class="xref" href="xml2.html" title="F.50. xml2">xml2</a>
+ module to perform XSL transformations of XML.
+ <code class="option">--with-libxml</code> must be specified as well.
+ </p></dd></dl></div></div><div class="sect3" id="CONFIGURE-OPTIONS-ANTI-FEATURES"><div class="titlepage"><div><div><h4 class="title">17.4.1.3. Anti-Features</h4></div></div></div><p>
+ The options described in this section allow disabling
+ certain <span class="productname">PostgreSQL</span> features that are built
+ by default, but which might need to be turned off if the required
+ software or system features are not available. Using these options is
+ not recommended unless really necessary.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--without-readline</code></span></dt><dd><p>
+ Prevents use of the <span class="application">Readline</span> library
+ (and <span class="application">libedit</span> as well). This option disables
+ command-line editing and history in
+ <span class="application">psql</span>.
+ </p></dd><dt><span class="term"><code class="option">--with-libedit-preferred</code></span></dt><dd><p>
+ Favors the use of the BSD-licensed <span class="application">libedit</span> library
+ rather than GPL-licensed <span class="application">Readline</span>. This option
+ is significant only if you have both libraries installed; the
+ default in that case is to use <span class="application">Readline</span>.
+ </p></dd><dt><span class="term"><code class="option">--without-zlib</code></span></dt><dd><p>
+ <a id="id-1.6.4.8.6.6.3.3.2.1.1" class="indexterm"></a>
+ Prevents use of the <span class="application">Zlib</span> library.
+ This disables
+ support for compressed archives in <span class="application">pg_dump</span>
+ and <span class="application">pg_restore</span>.
+ </p></dd><dt><span class="term"><code class="option">--disable-spinlocks</code></span></dt><dd><p>
+ Allow the build to succeed even if <span class="productname">PostgreSQL</span>
+ has no CPU spinlock support for the platform. The lack of
+ spinlock support will result in very poor performance; therefore,
+ this option should only be used if the build aborts and
+ informs you that the platform lacks spinlock support. If this
+ option is required to build <span class="productname">PostgreSQL</span> on
+ your platform, please report the problem to the
+ <span class="productname">PostgreSQL</span> developers.
+ </p></dd><dt><span class="term"><code class="option">--disable-atomics</code></span></dt><dd><p>
+ Disable use of CPU atomic operations. This option does nothing on
+ platforms that lack such operations. On platforms that do have
+ them, this will result in poor performance. This option is only
+ useful for debugging or making performance comparisons.
+ </p></dd><dt><span class="term"><code class="option">--disable-thread-safety</code></span></dt><dd><p>
+ Disable the thread-safety of client libraries. This prevents
+ concurrent threads in <span class="application">libpq</span> and
+ <span class="application">ECPG</span> programs from safely controlling
+ their private connection handles. Use this only on platforms
+ with deficient threading support.
+ </p></dd></dl></div></div><div class="sect3" id="CONFIGURE-OPTIONS-BUILD-PROCESS"><div class="titlepage"><div><div><h4 class="title">17.4.1.4. Build Process Details</h4></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--with-includes=<em class="replaceable"><code>DIRECTORIES</code></em></code></span></dt><dd><p>
+ <em class="replaceable"><code>DIRECTORIES</code></em> is a colon-separated list of
+ directories that will be added to the list the compiler
+ searches for header files. If you have optional packages
+ (such as GNU <span class="application">Readline</span>) installed in a non-standard
+ location,
+ you have to use this option and probably also the corresponding
+ <code class="option">--with-libraries</code> option.
+ </p><p>
+ Example: <code class="literal">--with-includes=/opt/gnu/include:/usr/sup/include</code>.
+ </p></dd><dt><span class="term"><code class="option">--with-libraries=<em class="replaceable"><code>DIRECTORIES</code></em></code></span></dt><dd><p>
+ <em class="replaceable"><code>DIRECTORIES</code></em> is a colon-separated list of
+ directories to search for libraries. You will probably have
+ to use this option (and the corresponding
+ <code class="option">--with-includes</code> option) if you have packages
+ installed in non-standard locations.
+ </p><p>
+ Example: <code class="literal">--with-libraries=/opt/gnu/lib:/usr/sup/lib</code>.
+ </p></dd><dt><span class="term"><code class="option">--with-system-tzdata=<em class="replaceable"><code>DIRECTORY</code></em></code>
+ <a id="id-1.6.4.8.6.7.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <span class="productname">PostgreSQL</span> includes its own time zone database,
+ which it requires for date and time operations. This time zone
+ database is in fact compatible with the IANA time zone
+ database provided by many operating systems such as FreeBSD,
+ Linux, and Solaris, so it would be redundant to install it again.
+ When this option is used, the system-supplied time zone database
+ in <em class="replaceable"><code>DIRECTORY</code></em> is used instead of the one
+ included in the PostgreSQL source distribution.
+ <em class="replaceable"><code>DIRECTORY</code></em> must be specified as an
+ absolute path. <code class="filename">/usr/share/zoneinfo</code> is a
+ likely directory on some operating systems. Note that the
+ installation routine will not detect mismatching or erroneous time
+ zone data. If you use this option, you are advised to run the
+ regression tests to verify that the time zone data you have
+ pointed to works correctly with <span class="productname">PostgreSQL</span>.
+ </p><a id="id-1.6.4.8.6.7.2.3.2.2" class="indexterm"></a><p>
+ This option is mainly aimed at binary package distributors
+ who know their target operating system well. The main
+ advantage of using this option is that the PostgreSQL package
+ won't need to be upgraded whenever any of the many local
+ daylight-saving time rules change. Another advantage is that
+ PostgreSQL can be cross-compiled more straightforwardly if the
+ time zone database files do not need to be built during the
+ installation.
+ </p></dd><dt><span class="term"><code class="option">--with-extra-version=<em class="replaceable"><code>STRING</code></em></code></span></dt><dd><p>
+ Append <em class="replaceable"><code>STRING</code></em> to the PostgreSQL version number. You
+ can use this, for example, to mark binaries built from unreleased Git
+ snapshots or containing custom patches with an extra version string,
+ such as a <code class="command">git describe</code> identifier or a
+ distribution package release number.
+ </p></dd><dt><span class="term"><code class="option">--disable-rpath</code></span></dt><dd><p>
+ Do not mark <span class="productname">PostgreSQL</span>'s executables
+ to indicate that they should search for shared libraries in the
+ installation's library directory (see <code class="option">--libdir</code>).
+ On most platforms, this marking uses an absolute path to the
+ library directory, so that it will be unhelpful if you relocate
+ the installation later. However, you will then need to provide
+ some other way for the executables to find the shared libraries.
+ Typically this requires configuring the operating system's
+ dynamic linker to search the library directory; see
+ <a class="xref" href="install-post.html#INSTALL-POST-SHLIBS" title="17.5.1. Shared Libraries">Section 17.5.1</a> for more detail.
+ </p></dd></dl></div></div><div class="sect3" id="CONFIGURE-OPTIONS-MISC"><div class="titlepage"><div><div><h4 class="title">17.4.1.5. Miscellaneous</h4></div></div></div><p>
+ It's fairly common, particularly for test builds, to adjust the
+ default port number with <code class="option">--with-pgport</code>.
+ The other options in this section are recommended only for advanced
+ users.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--with-pgport=<em class="replaceable"><code>NUMBER</code></em></code></span></dt><dd><p>
+ Set <em class="replaceable"><code>NUMBER</code></em> as the default port number for
+ server and clients. The default is 5432. The port can always
+ be changed later on, but if you specify it here then both
+ server and clients will have the same default compiled in,
+ which can be very convenient. Usually the only good reason
+ to select a non-default value is if you intend to run multiple
+ <span class="productname">PostgreSQL</span> servers on the same machine.
+ </p></dd><dt><span class="term"><code class="option">--with-krb-srvnam=<em class="replaceable"><code>NAME</code></em></code></span></dt><dd><p>
+ The default name of the Kerberos service principal used
+ by GSSAPI.
+ <code class="literal">postgres</code> is the default. There's usually no
+ reason to change this unless you are building for a Windows
+ environment, in which case it must be set to upper case
+ <code class="literal">POSTGRES</code>.
+ </p></dd><dt><span class="term"><code class="option">--with-segsize=<em class="replaceable"><code>SEGSIZE</code></em></code></span></dt><dd><p>
+ Set the <em class="firstterm">segment size</em>, in gigabytes. Large tables are
+ divided into multiple operating-system files, each of size equal
+ to the segment size. This avoids problems with file size limits
+ that exist on many platforms. The default segment size, 1 gigabyte,
+ is safe on all supported platforms. If your operating system has
+ <span class="quote">“<span class="quote">largefile</span>”</span> support (which most do, nowadays), you can use
+ a larger segment size. This can be helpful to reduce the number of
+ file descriptors consumed when working with very large tables.
+ But be careful not to select a value larger than is supported
+ by your platform and the file systems you intend to use. Other
+ tools you might wish to use, such as <span class="application">tar</span>, could
+ also set limits on the usable file size.
+ It is recommended, though not absolutely required, that this value
+ be a power of 2.
+ Note that changing this value breaks on-disk database compatibility,
+ meaning you cannot use <code class="command">pg_upgrade</code> to upgrade to
+ a build with a different segment size.
+ </p></dd><dt><span class="term"><code class="option">--with-blocksize=<em class="replaceable"><code>BLOCKSIZE</code></em></code></span></dt><dd><p>
+ Set the <em class="firstterm">block size</em>, in kilobytes. This is the unit
+ of storage and I/O within tables. The default, 8 kilobytes,
+ is suitable for most situations; but other values may be useful
+ in special cases.
+ The value must be a power of 2 between 1 and 32 (kilobytes).
+ Note that changing this value breaks on-disk database compatibility,
+ meaning you cannot use <code class="command">pg_upgrade</code> to upgrade to
+ a build with a different block size.
+ </p></dd><dt><span class="term"><code class="option">--with-wal-blocksize=<em class="replaceable"><code>BLOCKSIZE</code></em></code></span></dt><dd><p>
+ Set the <em class="firstterm">WAL block size</em>, in kilobytes. This is the unit
+ of storage and I/O within the WAL log. The default, 8 kilobytes,
+ is suitable for most situations; but other values may be useful
+ in special cases.
+ The value must be a power of 2 between 1 and 64 (kilobytes).
+ Note that changing this value breaks on-disk database compatibility,
+ meaning you cannot use <code class="command">pg_upgrade</code> to upgrade to
+ a build with a different WAL block size.
+ </p></dd></dl></div></div><div class="sect3" id="CONFIGURE-OPTIONS-DEVEL"><div class="titlepage"><div><div><h4 class="title">17.4.1.6. Developer Options</h4></div></div></div><p>
+ Most of the options in this section are only of interest for
+ developing or debugging <span class="productname">PostgreSQL</span>.
+ They are not recommended for production builds, except
+ for <code class="option">--enable-debug</code>, which can be useful to enable
+ detailed bug reports in the unlucky event that you encounter a bug.
+ On platforms supporting DTrace, <code class="option">--enable-dtrace</code>
+ may also be reasonable to use in production.
+ </p><p>
+ When building an installation that will be used to develop code inside
+ the server, it is recommended to use at least the
+ options <code class="option">--enable-debug</code>
+ and <code class="option">--enable-cassert</code>.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">--enable-debug</code></span></dt><dd><p>
+ Compiles all programs and libraries with debugging symbols.
+ This means that you can run the programs in a debugger
+ to analyze problems. This enlarges the size of the installed
+ executables considerably, and on non-GCC compilers it usually
+ also disables compiler optimization, causing slowdowns. However,
+ having the symbols available is extremely helpful for dealing
+ with any problems that might arise. Currently, this option is
+ recommended for production installations only if you use GCC.
+ But you should always have it on if you are doing development work
+ or running a beta version.
+ </p></dd><dt><span class="term"><code class="option">--enable-cassert</code></span></dt><dd><p>
+ Enables <em class="firstterm">assertion</em> checks in the server, which test for
+ many <span class="quote">“<span class="quote">cannot happen</span>”</span> conditions. This is invaluable for
+ code development purposes, but the tests can slow down the
+ server significantly.
+ Also, having the tests turned on won't necessarily enhance the
+ stability of your server! The assertion checks are not categorized
+ for severity, and so what might be a relatively harmless bug will
+ still lead to server restarts if it triggers an assertion
+ failure. This option is not recommended for production use, but
+ you should have it on for development work or when running a beta
+ version.
+ </p></dd><dt><span class="term"><code class="option">--enable-tap-tests</code></span></dt><dd><p>
+ Enable tests using the Perl TAP tools. This requires a Perl
+ installation and the Perl module <code class="literal">IPC::Run</code>.
+ <span class="phrase">See <a class="xref" href="regress-tap.html" title="33.4. TAP Tests">Section 33.4</a> for more information.</span>
+ </p></dd><dt><span class="term"><code class="option">--enable-depend</code></span></dt><dd><p>
+ Enables automatic dependency tracking. With this option, the
+ makefiles are set up so that all affected object files will
+ be rebuilt when any header file is changed. This is useful
+ if you are doing development work, but is just wasted overhead
+ if you intend only to compile once and install. At present,
+ this option only works with GCC.
+ </p></dd><dt><span class="term"><code class="option">--enable-coverage</code></span></dt><dd><p>
+ If using GCC, all programs and libraries are compiled with
+ code coverage testing instrumentation. When run, they
+ generate files in the build directory with code coverage
+ metrics.
+ <span class="phrase">See <a class="xref" href="regress-coverage.html" title="33.5. Test Coverage Examination">Section 33.5</a>
+ for more information.</span> This option is for use only with GCC
+ and when doing development work.
+ </p></dd><dt><span class="term"><code class="option">--enable-profiling</code></span></dt><dd><p>
+ If using GCC, all programs and libraries are compiled so they
+ can be profiled. On backend exit, a subdirectory will be created
+ that contains the <code class="filename">gmon.out</code> file containing
+ profile data.
+ This option is for use only with GCC and when doing development work.
+ </p></dd><dt><span class="term"><code class="option">--enable-dtrace</code></span></dt><dd><p>
+ <a id="id-1.6.4.8.6.9.4.7.2.1.1" class="indexterm"></a>
+ Compiles <span class="productname">PostgreSQL</span> with support for the
+ dynamic tracing tool DTrace.
+ <span class="phrase">See <a class="xref" href="dynamic-trace.html" title="28.5. Dynamic Tracing">Section 28.5</a>
+ for more information.</span>
+ </p><p>
+ To point to the <code class="command">dtrace</code> program, the
+ environment variable <code class="envar">DTRACE</code> can be set. This
+ will often be necessary because <code class="command">dtrace</code> is
+ typically installed under <code class="filename">/usr/sbin</code>,
+ which might not be in your <code class="envar">PATH</code>.
+ </p><p>
+ Extra command-line options for the <code class="command">dtrace</code> program
+ can be specified in the environment variable
+ <code class="envar">DTRACEFLAGS</code>. On Solaris,
+ to include DTrace support in a 64-bit binary, you must specify
+ <code class="literal">DTRACEFLAGS="-64"</code>. For example,
+ using the GCC compiler:
+</p><pre class="screen">
+./configure CC='gcc -m64' --enable-dtrace DTRACEFLAGS='-64' ...
+</pre><p>
+ Using Sun's compiler:
+</p><pre class="screen">
+./configure CC='/opt/SUNWspro/bin/cc -xtarget=native64' --enable-dtrace DTRACEFLAGS='-64' ...
+</pre><p>
+ </p></dd></dl></div></div></div><div class="sect2" id="CONFIGURE-ENVVARS"><div class="titlepage"><div><div><h3 class="title">17.4.2. <code class="filename">configure</code> Environment Variables</h3></div></div></div><a id="id-1.6.4.8.7.2" class="indexterm"></a><p>
+ In addition to the ordinary command-line options described above,
+ <code class="filename">configure</code> responds to a number of environment
+ variables.
+ You can specify environment variables on the
+ <code class="filename">configure</code> command line, for example:
+</p><pre class="screen">
+<strong class="userinput"><code>./configure CC=/opt/bin/gcc CFLAGS='-O2 -pipe'</code></strong>
+</pre><p>
+ In this usage an environment variable is little different from a
+ command-line option.
+ You can also set such variables beforehand:
+</p><pre class="screen">
+<strong class="userinput"><code>export CC=/opt/bin/gcc</code></strong>
+<strong class="userinput"><code>export CFLAGS='-O2 -pipe'</code></strong>
+<strong class="userinput"><code>./configure</code></strong>
+</pre><p>
+ This usage can be convenient because many programs' configuration
+ scripts respond to these variables in similar ways.
+ </p><p>
+ The most commonly used of these environment variables are
+ <code class="envar">CC</code> and <code class="envar">CFLAGS</code>.
+ If you prefer a C compiler different from the one
+ <code class="filename">configure</code> picks, you can set the
+ variable <code class="envar">CC</code> to the program of your choice.
+ By default, <code class="filename">configure</code> will pick
+ <code class="filename">gcc</code> if available, else the platform's
+ default (usually <code class="filename">cc</code>). Similarly, you can override the
+ default compiler flags if needed with the <code class="envar">CFLAGS</code> variable.
+ </p><p>
+ Here is a list of the significant variables that can be set in
+ this manner:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">BISON</code></span></dt><dd><p>
+ Bison program
+ </p></dd><dt><span class="term"><code class="envar">CC</code></span></dt><dd><p>
+ C compiler
+ </p></dd><dt><span class="term"><code class="envar">CFLAGS</code></span></dt><dd><p>
+ options to pass to the C compiler
+ </p></dd><dt><span class="term"><code class="envar">CLANG</code></span></dt><dd><p>
+ path to <code class="command">clang</code> program used to process source code
+ for inlining when compiling with <code class="literal">--with-llvm</code>
+ </p></dd><dt><span class="term"><code class="envar">CPP</code></span></dt><dd><p>
+ C preprocessor
+ </p></dd><dt><span class="term"><code class="envar">CPPFLAGS</code></span></dt><dd><p>
+ options to pass to the C preprocessor
+ </p></dd><dt><span class="term"><code class="envar">CXX</code></span></dt><dd><p>
+ C++ compiler
+ </p></dd><dt><span class="term"><code class="envar">CXXFLAGS</code></span></dt><dd><p>
+ options to pass to the C++ compiler
+ </p></dd><dt><span class="term"><code class="envar">DTRACE</code></span></dt><dd><p>
+ location of the <code class="command">dtrace</code> program
+ </p></dd><dt><span class="term"><code class="envar">DTRACEFLAGS</code></span></dt><dd><p>
+ options to pass to the <code class="command">dtrace</code> program
+ </p></dd><dt><span class="term"><code class="envar">FLEX</code></span></dt><dd><p>
+ Flex program
+ </p></dd><dt><span class="term"><code class="envar">LDFLAGS</code></span></dt><dd><p>
+ options to use when linking either executables or shared libraries
+ </p></dd><dt><span class="term"><code class="envar">LDFLAGS_EX</code></span></dt><dd><p>
+ additional options for linking executables only
+ </p></dd><dt><span class="term"><code class="envar">LDFLAGS_SL</code></span></dt><dd><p>
+ additional options for linking shared libraries only
+ </p></dd><dt><span class="term"><code class="envar">LLVM_CONFIG</code></span></dt><dd><p>
+ <code class="command">llvm-config</code> program used to locate the
+ <span class="productname">LLVM</span> installation
+ </p></dd><dt><span class="term"><code class="envar">MSGFMT</code></span></dt><dd><p>
+ <code class="command">msgfmt</code> program for native language support
+ </p></dd><dt><span class="term"><code class="envar">PERL</code></span></dt><dd><p>
+ Perl interpreter program. This will be used to determine the
+ dependencies for building PL/Perl. The default is
+ <code class="command">perl</code>.
+ </p></dd><dt><span class="term"><code class="envar">PYTHON</code></span></dt><dd><p>
+ Python interpreter program. This will be used to determine the
+ dependencies for building PL/Python. If this is not set, the
+ following are probed in this order:
+ <code class="literal">python3 python</code>.
+ </p></dd><dt><span class="term"><code class="envar">TCLSH</code></span></dt><dd><p>
+ Tcl interpreter program. This will be used to
+ determine the dependencies for building PL/Tcl.
+ If this is not set, the following are probed in this
+ order: <code class="literal">tclsh tcl tclsh8.6 tclsh86 tclsh8.5 tclsh85
+ tclsh8.4 tclsh84</code>.
+ </p></dd><dt><span class="term"><code class="envar">XML2_CONFIG</code></span></dt><dd><p>
+ <code class="command">xml2-config</code> program used to locate the
+ libxml2 installation
+ </p></dd></dl></div><p>
+ </p><p>
+ Sometimes it is useful to add compiler flags after-the-fact to the set
+ that were chosen by <code class="filename">configure</code>. An important example is
+ that <span class="application">gcc</span>'s <code class="option">-Werror</code> option cannot be included
+ in the <code class="envar">CFLAGS</code> passed to <code class="filename">configure</code>, because
+ it will break many of <code class="filename">configure</code>'s built-in tests. To add
+ such flags, include them in the <code class="envar">COPT</code> environment variable
+ while running <code class="filename">make</code>. The contents of <code class="envar">COPT</code>
+ are added to both the <code class="envar">CFLAGS</code> and <code class="envar">LDFLAGS</code>
+ options set up by <code class="filename">configure</code>. For example, you could do
+</p><pre class="screen">
+<strong class="userinput"><code>make COPT='-Werror'</code></strong>
+</pre><p>
+ or
+</p><pre class="screen">
+<strong class="userinput"><code>export COPT='-Werror'</code></strong>
+<strong class="userinput"><code>make</code></strong>
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If using GCC, it is best to build with an optimization level of
+ at least <code class="option">-O1</code>, because using no optimization
+ (<code class="option">-O0</code>) disables some important compiler warnings (such
+ as the use of uninitialized variables). However, non-zero
+ optimization levels can complicate debugging because stepping
+ through compiled code will usually not match up one-to-one with
+ source code lines. If you get confused while trying to debug
+ optimized code, recompile the specific files of interest with
+ <code class="option">-O0</code>. An easy way to do this is by passing an option
+ to <span class="application">make</span>: <code class="command">make PROFILE=-O0 file.o</code>.
+ </p><p>
+ The <code class="envar">COPT</code> and <code class="envar">PROFILE</code> environment variables are
+ actually handled identically by the <span class="productname">PostgreSQL</span>
+ makefiles. Which to use is a matter of preference, but a common habit
+ among developers is to use <code class="envar">PROFILE</code> for one-time flag
+ adjustments, while <code class="envar">COPT</code> might be kept set all the time.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-getsource.html" title="17.3. Getting the Source">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-post.html" title="17.5. Post-Installation Setup">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.3. Getting the Source </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.5. Post-Installation Setup</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-requirements.html b/doc/src/sgml/html/install-requirements.html
new file mode 100644
index 0000000..7464d5b
--- /dev/null
+++ b/doc/src/sgml/html/install-requirements.html
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.2. Requirements</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-short.html" title="17.1. Short Version" /><link rel="next" href="install-getsource.html" title="17.3. Getting the Source" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.2. Requirements</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-short.html" title="17.1. Short Version">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-getsource.html" title="17.3. Getting the Source">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALL-REQUIREMENTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.2. Requirements</h2></div></div></div><p>
+ In general, a modern Unix-compatible platform should be able to run
+ <span class="productname">PostgreSQL</span>.
+ The platforms that had received specific testing at the
+ time of release are described in <a class="xref" href="supported-platforms.html" title="17.6. Supported Platforms">Section 17.6</a>
+ below.
+ </p><p>
+ The following software packages are required for building
+ <span class="productname">PostgreSQL</span>:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a id="id-1.6.4.6.3.2.1.1.1" class="indexterm"></a>
+
+ <acronym class="acronym">GNU</acronym> <span class="application">make</span> version 3.81 or newer is required; other
+ <span class="application">make</span> programs or older <acronym class="acronym">GNU</acronym> <span class="application">make</span> versions will <span class="emphasis"><em>not</em></span> work.
+ (<acronym class="acronym">GNU</acronym> <span class="application">make</span> is sometimes installed under
+ the name <code class="filename">gmake</code>.) To test for <acronym class="acronym">GNU</acronym>
+ <span class="application">make</span> enter:
+</p><pre class="screen">
+<strong class="userinput"><code>make --version</code></strong>
+</pre><p>
+ </p></li><li class="listitem"><p>
+ You need an <acronym class="acronym">ISO</acronym>/<acronym class="acronym">ANSI</acronym> C compiler (at least
+ C99-compliant). Recent
+ versions of <span class="productname">GCC</span> are recommended, but
+ <span class="productname">PostgreSQL</span> is known to build using a wide variety
+ of compilers from different vendors.
+ </p></li><li class="listitem"><p>
+ <span class="application">tar</span> is required to unpack the source
+ distribution, in addition to either
+ <span class="application">gzip</span> or <span class="application">bzip2</span>.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.6.4.6.3.2.4.1.1" class="indexterm"></a>
+ <a id="id-1.6.4.6.3.2.4.1.2" class="indexterm"></a>
+
+ The <acronym class="acronym">GNU</acronym> <span class="productname">Readline</span> library is used by
+ default. It allows <span class="application">psql</span> (the
+ PostgreSQL command line SQL interpreter) to remember each
+ command you type, and allows you to use arrow keys to recall and
+ edit previous commands. This is very helpful and is strongly
+ recommended. If you don't want to use it then you must specify
+ the <code class="option">--without-readline</code> option to
+ <code class="filename">configure</code>. As an alternative, you can often use the
+ BSD-licensed <code class="filename">libedit</code> library, originally
+ developed on <span class="productname">NetBSD</span>. The
+ <code class="filename">libedit</code> library is
+ GNU <span class="productname">Readline</span>-compatible and is used if
+ <code class="filename">libreadline</code> is not found, or if
+ <code class="option">--with-libedit-preferred</code> is used as an
+ option to <code class="filename">configure</code>. If you are using a package-based
+ Linux distribution, be aware that you need both the
+ <code class="literal">readline</code> and <code class="literal">readline-devel</code> packages, if
+ those are separate in your distribution.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.6.4.6.3.2.5.1.1" class="indexterm"></a>
+
+ The <span class="productname">zlib</span> compression library is
+ used by default. If you don't want to use it then you must
+ specify the <code class="option">--without-zlib</code> option to
+ <code class="filename">configure</code>. Using this option disables
+ support for compressed archives in <span class="application">pg_dump</span> and
+ <span class="application">pg_restore</span>.
+ </p></li></ul></div><p>
+ </p><p>
+ The following packages are optional. They are not required in the
+ default configuration, but they are needed when certain build
+ options are enabled, as explained below:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ To build the server programming language
+ <span class="application">PL/Perl</span> you need a full
+ <span class="productname">Perl</span> installation, including the
+ <code class="filename">libperl</code> library and the header files.
+ The minimum required version is <span class="productname">Perl</span> 5.8.3.
+ Since <span class="application">PL/Perl</span> will be a shared
+ library, the <a id="id-1.6.4.6.4.1.1.1.6" class="indexterm"></a>
+ <code class="filename">libperl</code> library must be a shared library
+ also on most platforms. This appears to be the default in
+ recent <span class="productname">Perl</span> versions, but it was not
+ in earlier versions, and in any case it is the choice of whomever
+ installed Perl at your site. <code class="filename">configure</code> will fail
+ if building <span class="application">PL/Perl</span> is selected but it cannot
+ find a shared <code class="filename">libperl</code>. In that case, you will have
+ to rebuild and install <span class="productname">Perl</span> manually to be
+ able to build <span class="application">PL/Perl</span>. During the
+ configuration process for <span class="productname">Perl</span>, request a
+ shared library.
+ </p><p>
+ If you intend to make more than incidental use of
+ <span class="application">PL/Perl</span>, you should ensure that the
+ <span class="productname">Perl</span> installation was built with the
+ <code class="literal">usemultiplicity</code> option enabled (<code class="literal">perl -V</code>
+ will show whether this is the case).
+ </p></li><li class="listitem"><p>
+ To build the <span class="application">PL/Python</span> server programming
+ language, you need a <span class="productname">Python</span>
+ installation with the header files and
+ the <span class="application">sysconfig</span> module. The minimum
+ required version is <span class="productname">Python</span> 3.2.
+ </p><p>
+ Since <span class="application">PL/Python</span> will be a shared
+ library, the <a id="id-1.6.4.6.4.1.2.2.2" class="indexterm"></a>
+ <code class="filename">libpython</code> library must be a shared library
+ also on most platforms. This is not the case in a default
+ <span class="productname">Python</span> installation built from source, but a
+ shared library is available in many operating system
+ distributions. <code class="filename">configure</code> will fail if
+ building <span class="application">PL/Python</span> is selected but it cannot
+ find a shared <code class="filename">libpython</code>. That might mean that you
+ either have to install additional packages or rebuild (part of) your
+ <span class="productname">Python</span> installation to provide this shared
+ library. When building from source, run <span class="productname">Python</span>'s
+ configure with the <code class="literal">--enable-shared</code> flag.
+ </p></li><li class="listitem"><p>
+ To build the <span class="application">PL/Tcl</span>
+ procedural language, you of course need a <span class="productname">Tcl</span>
+ installation. The minimum required version is
+ <span class="productname">Tcl</span> 8.4.
+ </p></li><li class="listitem"><p>
+ To enable Native Language Support (<acronym class="acronym">NLS</acronym>), that
+ is, the ability to display a program's messages in a language
+ other than English, you need an implementation of the
+ <span class="application">Gettext</span> <acronym class="acronym">API</acronym>. Some operating
+ systems have this built-in (e.g., <span class="systemitem">Linux</span>, <span class="systemitem">NetBSD</span>,
+ <span class="systemitem">Solaris</span>), for other systems you
+ can download an add-on package from <a class="ulink" href="https://www.gnu.org/software/gettext/" target="_top">https://www.gnu.org/software/gettext/</a>.
+ If you are using the <span class="application">Gettext</span> implementation in
+ the <acronym class="acronym">GNU</acronym> C library then you will additionally
+ need the <span class="productname">GNU Gettext</span> package for some
+ utility programs. For any of the other implementations you will
+ not need it.
+ </p></li><li class="listitem"><p>
+ You need <span class="productname">OpenSSL</span>, if you want to support
+ encrypted client connections. <span class="productname">OpenSSL</span> is
+ also required for random number generation on platforms that do not
+ have <code class="filename">/dev/urandom</code> (except Windows). The minimum
+ required version is 1.0.1.
+ </p></li><li class="listitem"><p>
+ You need <span class="application">Kerberos</span>, <span class="productname">OpenLDAP</span>,
+ and/or <span class="application">PAM</span>, if you want to support authentication
+ using those services.
+ </p></li><li class="listitem"><p>
+ You need <span class="productname">LZ4</span>, if you want to support
+ compression of data with that method; see
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TOAST-COMPRESSION">default_toast_compression</a> and
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-COMPRESSION">wal_compression</a>.
+ </p></li><li class="listitem"><p>
+ You need <span class="productname">Zstandard</span>, if you want to support
+ compression of data with that method; see
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-COMPRESSION">wal_compression</a>.
+ The minimum required version is 1.4.0.
+ </p></li><li class="listitem"><p>
+ To build the <span class="productname">PostgreSQL</span> documentation,
+ there is a separate set of requirements; see
+ <a class="xref" href="docguide-toolsets.html" title="J.2. Tool Sets">Section J.2</a>.
+ </p></li></ul></div><p>
+ </p><p>
+ If you are building from a <span class="productname">Git</span> tree instead of
+ using a released source package, or if you want to do server development,
+ you also need the following packages:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a id="id-1.6.4.6.5.2.1.1.1" class="indexterm"></a>
+ <a id="id-1.6.4.6.5.2.1.1.2" class="indexterm"></a>
+ <a id="id-1.6.4.6.5.2.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.4.6.5.2.1.1.4" class="indexterm"></a>
+
+ <span class="application">Flex</span> and <span class="application">Bison</span>
+ are needed to build from a Git checkout, or if you changed the actual
+ scanner and parser definition files. If you need them, be sure
+ to get <span class="application">Flex</span> 2.5.31 or later and
+ <span class="application">Bison</span> 1.875 or later. Other <span class="application">lex</span>
+ and <span class="application">yacc</span> programs cannot be used.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.6.4.6.5.2.2.1.1" class="indexterm"></a>
+
+ <span class="application">Perl</span> 5.8.3 or later is needed to build from a Git checkout,
+ or if you changed the input files for any of the build steps that
+ use Perl scripts. If building on Windows you will need
+ <span class="application">Perl</span> in any case. <span class="application">Perl</span> is
+ also required to run some test suites.
+ </p></li></ul></div><p>
+ </p><p>
+ If you need to get a <acronym class="acronym">GNU</acronym> package, you can find
+ it at your local <acronym class="acronym">GNU</acronym> mirror site (see <a class="ulink" href="https://www.gnu.org/prep/ftp" target="_top">https://www.gnu.org/prep/ftp</a>
+ for a list) or at <a class="ulink" href="ftp://ftp.gnu.org/gnu/" target="_top">ftp://ftp.gnu.org/gnu/</a>.
+ </p><p>
+ Also check that you have sufficient disk space. You will need about
+ 350 MB for the source tree during compilation and about 60 MB for
+ the installation directory. An empty database cluster takes about
+ 40 MB; databases take about five times the amount of space that a
+ flat text file with the same data would take. If you are going to
+ run the regression tests you will temporarily need up to an extra
+ 300 MB. Use the <code class="command">df</code> command to check free disk
+ space.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-short.html" title="17.1. Short Version">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-getsource.html" title="17.3. Getting the Source">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.1. Short Version </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.3. Getting the Source</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-short.html b/doc/src/sgml/html/install-short.html
new file mode 100644
index 0000000..d8405b7
--- /dev/null
+++ b/doc/src/sgml/html/install-short.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.1. Short Version</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="installation.html" title="Chapter 17. Installation from Source Code" /><link rel="next" href="install-requirements.html" title="17.2. Requirements" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.1. Short Version</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="installation.html" title="Chapter 17. Installation from Source Code">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-requirements.html" title="17.2. Requirements">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALL-SHORT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.1. Short Version</h2></div></div></div><p>
+</p><pre class="synopsis">
+./configure
+make
+su
+make install
+adduser postgres
+mkdir -p /usr/local/pgsql/data
+chown postgres /usr/local/pgsql/data
+su - postgres
+/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
+/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start
+/usr/local/pgsql/bin/createdb test
+/usr/local/pgsql/bin/psql test
+</pre><p>
+ The long version is the rest of this
+ <span class="phrase">chapter</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="installation.html" title="Chapter 17. Installation from Source Code">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-requirements.html" title="17.2. Requirements">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 17. Installation from Source Code </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.2. Requirements</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-windows-full.html b/doc/src/sgml/html/install-windows-full.html
new file mode 100644
index 0000000..22621a2
--- /dev/null
+++ b/doc/src/sgml/html/install-windows-full.html
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>18.1. Building with Visual C++ or the Microsoft Windows SDK</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows" /><link rel="next" href="runtime.html" title="Chapter 19. Server Setup and Operation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">18.1. Building with <span class="productname">Visual C++</span> or the
+ <span class="productname">Microsoft Windows SDK</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Up</a></td><th width="60%" align="center">Chapter 18. Installation from Source Code on <span class="productname">Windows</span></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime.html" title="Chapter 19. Server Setup and Operation">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALL-WINDOWS-FULL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">18.1. Building with <span class="productname">Visual C++</span> or the
+ <span class="productname">Microsoft Windows SDK</span></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.8">18.1.1. Requirements</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.9">18.1.2. Special Considerations for 64-Bit Windows</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.10">18.1.3. Building</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.11">18.1.4. Cleaning and Installing</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.12">18.1.5. Running the Regression Tests</a></span></dt></dl></div><p>
+ PostgreSQL can be built using the Visual C++ compiler suite from Microsoft.
+ These compilers can be either from <span class="productname">Visual Studio</span>,
+ <span class="productname">Visual Studio Express</span> or some versions of the
+ <span class="productname">Microsoft Windows SDK</span>. If you do not already have a
+ <span class="productname">Visual Studio</span> environment set up, the easiest
+ ways are to use the compilers from
+ <span class="productname">Visual Studio 2022</span> or those in the
+ <span class="productname">Windows SDK 10</span>, which are both free downloads
+ from Microsoft.
+ </p><p>
+ Both 32-bit and 64-bit builds are possible with the Microsoft Compiler suite.
+ 32-bit PostgreSQL builds are possible with
+ <span class="productname">Visual Studio 2013</span> to
+ <span class="productname">Visual Studio 2022</span>,
+ as well as standalone Windows SDK releases 8.1a to 10.
+ 64-bit PostgreSQL builds are supported with
+ <span class="productname">Microsoft Windows SDK</span> version 8.1a to 10 or
+ <span class="productname">Visual Studio 2013</span> and above. Compilation
+ is supported down to <span class="productname">Windows 7</span> and
+ <span class="productname">Windows Server 2008 R2 SP1</span> when building with
+ <span class="productname">Visual Studio 2013</span> to
+ <span class="productname">Visual Studio 2022</span>.
+
+ </p><p>
+ The tools for building using <span class="productname">Visual C++</span> or
+ <span class="productname">Platform SDK</span> are in the
+ <code class="filename">src\tools\msvc</code> directory. When building, make sure
+ there are no tools from <span class="productname">MinGW</span> or
+ <span class="productname">Cygwin</span> present in your system PATH. Also, make
+ sure you have all the required Visual C++ tools available in the PATH. In
+ <span class="productname">Visual Studio</span>, start the
+ <span class="application">Visual Studio Command Prompt</span>.
+ If you wish to build a 64-bit version, you must use the 64-bit version of
+ the command, and vice versa.
+ Starting with <span class="productname">Visual Studio 2017</span> this can be
+ done from the command line using <code class="command">VsDevCmd.bat</code>, see
+ <code class="command">-help</code> for the available options and their default values.
+ <code class="command">vsvars32.bat</code> is available in
+ <span class="productname">Visual Studio 2015</span> and earlier versions for the
+ same purpose.
+ From the <span class="application">Visual Studio Command Prompt</span>, you can
+ change the targeted CPU architecture, build type, and target OS by using the
+ <code class="command">vcvarsall.bat</code> command, e.g.,
+ <code class="command">vcvarsall.bat x64 10.0.10240.0</code> to target Windows 10
+ with a 64-bit release build. See <code class="command">-help</code> for the other
+ options of <code class="command">vcvarsall.bat</code>. All commands should be run from
+ the <code class="filename">src\tools\msvc</code> directory.
+ </p><p>
+ Before you build, you can create the file <code class="filename">config.pl</code>
+ to reflect any configuration options you want to change, or the paths to
+ any third party libraries to use. The complete configuration is determined
+ by first reading and parsing the file <code class="filename">config_default.pl</code>,
+ and then apply any changes from <code class="filename">config.pl</code>. For example,
+ to specify the location of your <span class="productname">Python</span> installation,
+ put the following in <code class="filename">config.pl</code>:
+</p><pre class="programlisting">
+$config-&gt;{python} = 'c:\python310';
+</pre><p>
+ You only need to specify those parameters that are different from what's in
+ <code class="filename">config_default.pl</code>.
+ </p><p>
+ If you need to set any other environment variables, create a file called
+ <code class="filename">buildenv.pl</code> and put the required commands there. For
+ example, to add the path for bison when it's not in the PATH, create a file
+ containing:
+</p><pre class="programlisting">
+$ENV{PATH}=$ENV{PATH} . ';c:\some\where\bison\bin';
+</pre><p>
+ </p><p>
+ To pass additional command line arguments to the Visual Studio build
+ command (msbuild or vcbuild):
+</p><pre class="programlisting">
+$ENV{MSBFLAGS}="/m";
+</pre><p>
+ </p><div class="sect2" id="id-1.6.5.8.8"><div class="titlepage"><div><div><h3 class="title">18.1.1. Requirements</h3></div></div></div><p>
+ The following additional products are required to build
+ <span class="productname">PostgreSQL</span>. Use the
+ <code class="filename">config.pl</code> file to specify which directories the libraries
+ are available in.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><span class="productname">Microsoft Windows SDK</span></span></dt><dd><p>
+ If your build environment doesn't ship with a supported version of the
+ <span class="productname">Microsoft Windows SDK</span> it
+ is recommended that you upgrade to the latest version (currently
+ version 10), available for download from
+ <a class="ulink" href="https://www.microsoft.com/download" target="_top">https://www.microsoft.com/download</a>.
+ </p><p>
+ You must always include the
+ <span class="application">Windows Headers and Libraries</span> part of the SDK.
+ If you install a <span class="productname">Windows SDK</span>
+ including the <span class="application">Visual C++ Compilers</span>,
+ you don't need <span class="productname">Visual Studio</span> to build.
+ Note that as of Version 8.0a the Windows SDK no longer ships with a
+ complete command-line build environment.
+ </p></dd><dt><span class="term"><span class="productname">ActiveState Perl</span></span></dt><dd><p>
+ ActiveState Perl is required to run the build generation scripts. MinGW
+ or Cygwin Perl will not work. It must also be present in the PATH.
+ Binaries can be downloaded from
+ <a class="ulink" href="https://www.activestate.com" target="_top">https://www.activestate.com</a>
+ (Note: version 5.8.3 or later is required,
+ the free Standard Distribution is sufficient).
+ </p></dd></dl></div><p>
+ </p><p>
+ The following additional products are not required to get started,
+ but are required to build the complete package. Use the
+ <code class="filename">config.pl</code> file to specify which directories the libraries
+ are available in.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><span class="productname">ActiveState TCL</span></span></dt><dd><p>
+ Required for building <span class="application">PL/Tcl</span> (Note: version
+ 8.4 is required, the free Standard Distribution is sufficient).
+ </p></dd><dt><span class="term"><span class="productname">Bison</span> and
+ <span class="productname">Flex</span></span></dt><dd><p>
+ <span class="productname">Bison</span> and <span class="productname">Flex</span> are
+ required to build from Git, but not required when building from a release
+ file. Only <span class="productname">Bison</span> 1.875 or versions 2.2 and later
+ will work. <span class="productname">Flex</span> must be version 2.5.31 or later.
+ </p><p>
+ Both <span class="productname">Bison</span> and <span class="productname">Flex</span>
+ are included in the <span class="productname">msys</span> tool suite, available
+ from <a class="ulink" href="http://www.mingw.org/wiki/MSYS" target="_top">http://www.mingw.org/wiki/MSYS</a> as part of the
+ <span class="productname">MinGW</span> compiler suite.
+ </p><p>
+ You will need to add the directory containing
+ <code class="filename">flex.exe</code> and <code class="filename">bison.exe</code> to the
+ PATH environment variable in <code class="filename">buildenv.pl</code> unless
+ they are already in PATH. In the case of MinGW, the directory is the
+ <code class="filename">\msys\1.0\bin</code> subdirectory of your MinGW
+ installation directory.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The Bison distribution from GnuWin32 appears to have a bug that
+ causes Bison to malfunction when installed in a directory with
+ spaces in the name, such as the default location on English
+ installations <code class="filename">C:\Program Files\GnuWin32</code>.
+ Consider installing into <code class="filename">C:\GnuWin32</code> or use the
+ NTFS short name path to GnuWin32 in your PATH environment setting
+ (e.g., <code class="filename">C:\PROGRA~1\GnuWin32</code>).
+ </p></div></dd><dt><span class="term"><span class="productname">Diff</span></span></dt><dd><p>
+ Diff is required to run the regression tests, and can be downloaded
+ from <a class="ulink" href="http://gnuwin32.sourceforge.net" target="_top">http://gnuwin32.sourceforge.net</a>.
+ </p></dd><dt><span class="term"><span class="productname">Gettext</span></span></dt><dd><p>
+ Gettext is required to build with NLS support, and can be downloaded
+ from <a class="ulink" href="http://gnuwin32.sourceforge.net" target="_top">http://gnuwin32.sourceforge.net</a>. Note that binaries,
+ dependencies and developer files are all needed.
+ </p></dd><dt><span class="term"><span class="productname">MIT Kerberos</span></span></dt><dd><p>
+ Required for GSSAPI authentication support. MIT Kerberos can be
+ downloaded from
+ <a class="ulink" href="https://web.mit.edu/Kerberos/dist/index.html" target="_top">https://web.mit.edu/Kerberos/dist/index.html</a>.
+ </p></dd><dt><span class="term"><span class="productname">libxml2</span> and
+ <span class="productname">libxslt</span></span></dt><dd><p>
+ Required for XML support. Binaries can be downloaded from
+ <a class="ulink" href="https://zlatkovic.com/pub/libxml" target="_top">https://zlatkovic.com/pub/libxml</a> or source from
+ <a class="ulink" href="http://xmlsoft.org" target="_top">http://xmlsoft.org</a>. Note that libxml2 requires iconv,
+ which is available from the same download location.
+ </p></dd><dt><span class="term"><span class="productname">LZ4</span></span></dt><dd><p>
+ Required for supporting <span class="productname">LZ4</span> compression.
+ Binaries and source can be downloaded from
+ <a class="ulink" href="https://github.com/lz4/lz4/releases" target="_top">https://github.com/lz4/lz4/releases</a>.
+ </p></dd><dt><span class="term"><span class="productname">Zstandard</span></span></dt><dd><p>
+ Required for supporting <span class="productname">Zstandard</span> compression.
+ Binaries and source can be downloaded from
+ <a class="ulink" href="https://github.com/facebook/zstd/releases" target="_top">https://github.com/facebook/zstd/releases</a>.
+ </p></dd><dt><span class="term"><span class="productname">OpenSSL</span></span></dt><dd><p>
+ Required for SSL support. Binaries can be downloaded from
+ <a class="ulink" href="https://slproweb.com/products/Win32OpenSSL.html" target="_top">https://slproweb.com/products/Win32OpenSSL.html</a>
+ or source from <a class="ulink" href="https://www.openssl.org" target="_top">https://www.openssl.org</a>.
+ </p></dd><dt><span class="term"><span class="productname">ossp-uuid</span></span></dt><dd><p>
+ Required for UUID-OSSP support (contrib only). Source can be
+ downloaded from
+ <a class="ulink" href="http://www.ossp.org/pkg/lib/uuid/" target="_top">http://www.ossp.org/pkg/lib/uuid/</a>.
+ </p></dd><dt><span class="term"><span class="productname">Python</span></span></dt><dd><p>
+ Required for building <span class="application">PL/Python</span>. Binaries can
+ be downloaded from <a class="ulink" href="https://www.python.org" target="_top">https://www.python.org</a>.
+ </p></dd><dt><span class="term"><span class="productname">zlib</span></span></dt><dd><p>
+ Required for compression support in <span class="application">pg_dump</span>
+ and <span class="application">pg_restore</span>. Binaries can be downloaded
+ from <a class="ulink" href="https://www.zlib.net" target="_top">https://www.zlib.net</a>.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="id-1.6.5.8.9"><div class="titlepage"><div><div><h3 class="title">18.1.2. Special Considerations for 64-Bit Windows</h3></div></div></div><p>
+ PostgreSQL will only build for the x64 architecture on 64-bit Windows, there
+ is no support for Itanium processors.
+ </p><p>
+ Mixing 32- and 64-bit versions in the same build tree is not supported.
+ The build system will automatically detect if it's running in a 32- or
+ 64-bit environment, and build PostgreSQL accordingly. For this reason, it
+ is important to start the correct command prompt before building.
+ </p><p>
+ To use a server-side third party library such as <span class="productname">Python</span> or
+ <span class="productname">OpenSSL</span>, this library <span class="emphasis"><em>must</em></span> also be
+ 64-bit. There is no support for loading a 32-bit library in a 64-bit
+ server. Several of the third party libraries that PostgreSQL supports may
+ only be available in 32-bit versions, in which case they cannot be used with
+ 64-bit PostgreSQL.
+ </p></div><div class="sect2" id="id-1.6.5.8.10"><div class="titlepage"><div><div><h3 class="title">18.1.3. Building</h3></div></div></div><p>
+ To build all of PostgreSQL in release configuration (the default), run the
+ command:
+</p><pre class="screen">
+<strong class="userinput"><code>build</code></strong>
+</pre><p>
+ To build all of PostgreSQL in debug configuration, run the command:
+</p><pre class="screen">
+<strong class="userinput"><code>build DEBUG</code></strong>
+</pre><p>
+ To build just a single project, for example psql, run the commands:
+</p><pre class="screen">
+<strong class="userinput"><code>build psql</code></strong>
+<strong class="userinput"><code>build DEBUG psql</code></strong>
+</pre><p>
+ To change the default build configuration to debug, put the following
+ in the <code class="filename">buildenv.pl</code> file:
+</p><pre class="programlisting">
+$ENV{CONFIG}="Debug";
+</pre><p>
+ </p><p>
+ It is also possible to build from inside the Visual Studio GUI. In this
+ case, you need to run:
+</p><pre class="screen">
+<strong class="userinput"><code>perl mkvcbuild.pl</code></strong>
+</pre><p>
+ from the command prompt, and then open the generated
+ <code class="filename">pgsql.sln</code> (in the root directory of the source tree)
+ in Visual Studio.
+ </p></div><div class="sect2" id="id-1.6.5.8.11"><div class="titlepage"><div><div><h3 class="title">18.1.4. Cleaning and Installing</h3></div></div></div><p>
+ Most of the time, the automatic dependency tracking in Visual Studio will
+ handle changed files. But if there have been large changes, you may need
+ to clean the installation. To do this, simply run the
+ <code class="filename">clean.bat</code> command, which will automatically clean out
+ all generated files. You can also run it with the
+ <em class="parameter"><code>dist</code></em> parameter, in which case it will behave like
+ <strong class="userinput"><code>make distclean</code></strong> and remove the flex/bison output files
+ as well.
+ </p><p>
+ By default, all files are written into a subdirectory of the
+ <code class="filename">debug</code> or <code class="filename">release</code> directories. To
+ install these files using the standard layout, and also generate the files
+ required to initialize and use the database, run the command:
+</p><pre class="screen">
+<strong class="userinput"><code>install c:\destination\directory</code></strong>
+</pre><p>
+ </p><p>
+ If you want to install only the client applications and
+ interface libraries, then you can use these commands:
+</p><pre class="screen">
+<strong class="userinput"><code>install c:\destination\directory client</code></strong>
+</pre><p>
+ </p></div><div class="sect2" id="id-1.6.5.8.12"><div class="titlepage"><div><div><h3 class="title">18.1.5. Running the Regression Tests</h3></div></div></div><p>
+ To run the regression tests, make sure you have completed the build of all
+ required parts first. Also, make sure that the DLLs required to load all
+ parts of the system (such as the Perl and Python DLLs for the procedural
+ languages) are present in the system path. If they are not, set it through
+ the <code class="filename">buildenv.pl</code> file. To run the tests, run one of
+ the following commands from the <code class="filename">src\tools\msvc</code>
+ directory:
+</p><pre class="screen">
+<strong class="userinput"><code>vcregress check</code></strong>
+<strong class="userinput"><code>vcregress installcheck</code></strong>
+<strong class="userinput"><code>vcregress plcheck</code></strong>
+<strong class="userinput"><code>vcregress contribcheck</code></strong>
+<strong class="userinput"><code>vcregress modulescheck</code></strong>
+<strong class="userinput"><code>vcregress ecpgcheck</code></strong>
+<strong class="userinput"><code>vcregress isolationcheck</code></strong>
+<strong class="userinput"><code>vcregress bincheck</code></strong>
+<strong class="userinput"><code>vcregress recoverycheck</code></strong>
+</pre><p>
+
+ To change the schedule used (default is parallel), append it to the
+ command line like:
+</p><pre class="screen">
+<strong class="userinput"><code>vcregress check serial</code></strong>
+</pre><p>
+
+ For more information about the regression tests, see
+ <a class="xref" href="regress.html" title="Chapter 33. Regression Tests">Chapter 33</a>.
+ </p><p>
+ Running the regression tests on client programs, with
+ <code class="command">vcregress bincheck</code>, or on recovery tests, with
+ <code class="command">vcregress recoverycheck</code>, requires an additional Perl module
+ to be installed:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><span class="productname">IPC::Run</span></span></dt><dd><p>
+ As of this writing, <code class="literal">IPC::Run</code> is not included in the
+ ActiveState Perl installation, nor in the ActiveState Perl Package
+ Manager (PPM) library. To install, download the
+ <code class="filename">IPC-Run-&lt;version&gt;.tar.gz</code> source archive from CPAN,
+ at <a class="ulink" href="https://metacpan.org/release/IPC-Run" target="_top">https://metacpan.org/release/IPC-Run</a>, and
+ uncompress. Edit the <code class="filename">buildenv.pl</code> file, and add a PERL5LIB
+ variable to point to the <code class="filename">lib</code> subdirectory from the
+ extracted archive. For example:
+</p><pre class="programlisting">
+$ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
+</pre><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ The TAP tests run with <code class="command">vcregress</code> support the
+ environment variables <code class="varname">PROVE_TESTS</code>, that is expanded
+ automatically using the name patterns given, and
+ <code class="varname">PROVE_FLAGS</code>. These can be set on a Windows terminal,
+ before running <code class="command">vcregress</code>:
+</p><pre class="programlisting">
+set PROVE_FLAGS=--timer --jobs 2
+set PROVE_TESTS=t/020*.pl t/010*.pl
+</pre><p>
+ It is also possible to set up those parameters in
+ <code class="filename">buildenv.pl</code>:
+</p><pre class="programlisting">
+$ENV{PROVE_FLAGS}='--timer --jobs 2'
+$ENV{PROVE_TESTS}='t/020*.pl t/010*.pl'
+</pre><p>
+ </p><p>
+ Some of the TAP tests depend on a set of external commands that would
+ optionally trigger tests related to them. Each one of those variables
+ can be set or unset in <code class="filename">buildenv.pl</code>:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">GZIP_PROGRAM</code></span></dt><dd><p>
+ Path to a <span class="application">gzip</span> command. The default is
+ <code class="literal">gzip</code>, which will search for a command by that
+ name in the configured <code class="envar">PATH</code>.
+ </p></dd><dt><span class="term"><code class="varname">LZ4</code></span></dt><dd><p>
+ Path to a <span class="application">lz4</span> command. The default is
+ <code class="literal">lz4</code>, which will search for a command by that
+ name in the configured <code class="envar">PATH</code>.
+ </p></dd><dt><span class="term"><code class="varname">TAR</code></span></dt><dd><p>
+ Path to a <span class="application">tar</span> command. The default is
+ <code class="literal">tar</code>, which will search for a command by that
+ name in the configured <code class="envar">PATH</code>.
+ </p></dd><dt><span class="term"><code class="varname">ZSTD</code></span></dt><dd><p>
+ Path to a <span class="application">zstd</span> command. The default is
+ <code class="literal">zstd</code>, which will search for a command by that
+ name in the configured <code class="envar">PATH</code>.
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime.html" title="Chapter 19. Server Setup and Operation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 18. Installation from Source Code on <span class="productname">Windows</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 19. Server Setup and Operation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/install-windows.html b/doc/src/sgml/html/install-windows.html
new file mode 100644
index 0000000..dc2b1ff
--- /dev/null
+++ b/doc/src/sgml/html/install-windows.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 18. Installation from Source Code on Windows</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes" /><link rel="next" href="install-windows-full.html" title="18.1. Building with Visual C++ or the Microsoft Windows SDK" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 18. Installation from Source Code on <span class="productname">Windows</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-windows-full.html" title="18.1. Building with Visual C++ or the&#10; Microsoft Windows SDK">Next</a></td></tr></table><hr /></div><div class="chapter" id="INSTALL-WINDOWS"><div class="titlepage"><div><div><h2 class="title">Chapter 18. Installation from Source Code on <span class="productname">Windows</span></h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="install-windows-full.html">18.1. Building with <span class="productname">Visual C++</span> or the
+ <span class="productname">Microsoft Windows SDK</span></a></span></dt><dd><dl><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.8">18.1.1. Requirements</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.9">18.1.2. Special Considerations for 64-Bit Windows</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.10">18.1.3. Building</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.11">18.1.4. Cleaning and Installing</a></span></dt><dt><span class="sect2"><a href="install-windows-full.html#id-1.6.5.8.12">18.1.5. Running the Regression Tests</a></span></dt></dl></dd></dl></div><a id="id-1.6.5.2" class="indexterm"></a><p>
+ It is recommended that most users download the binary distribution for
+ Windows, available as a graphical installer package
+ from the <span class="productname">PostgreSQL</span> website at
+ <a class="ulink" href="https://www.postgresql.org/download/" target="_top">https://www.postgresql.org/download/</a>. Building from source
+ is only intended for people developing <span class="productname">PostgreSQL</span>
+ or extensions.
+ </p><p>
+ There are several different ways of building PostgreSQL on
+ <span class="productname">Windows</span>. The simplest way to build with
+ Microsoft tools is to install <span class="productname">Visual Studio 2022</span>
+ and use the included compiler. It is also possible to build with the full
+ <span class="productname">Microsoft Visual C++ 2013 to 2022</span>.
+ In some cases that requires the installation of the
+ <span class="productname">Windows SDK</span> in addition to the compiler.
+ </p><p>
+ It is also possible to build PostgreSQL using the GNU compiler tools
+ provided by <span class="productname">MinGW</span>, or using
+ <span class="productname">Cygwin</span> for older versions of
+ <span class="productname">Windows</span>.
+ </p><p>
+ Building using <span class="productname">MinGW</span> or
+ <span class="productname">Cygwin</span> uses the normal build system, see
+ <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a> and the specific notes in
+ <a class="xref" href="installation-platform-notes.html#INSTALLATION-NOTES-MINGW" title="17.7.4. MinGW/Native Windows">Section 17.7.4</a> and <a class="xref" href="installation-platform-notes.html#INSTALLATION-NOTES-CYGWIN" title="17.7.2. Cygwin">Section 17.7.2</a>.
+ To produce native 64 bit binaries in these environments, use the tools from
+ <span class="productname">MinGW-w64</span>. These tools can also be used to
+ cross-compile for 32 bit and 64 bit <span class="productname">Windows</span>
+ targets on other hosts, such as <span class="productname">Linux</span> and
+ <span class="productname">macOS</span>.
+ <span class="productname">Cygwin</span> is not recommended for running a
+ production server, and it should only be used for running on
+ older versions of <span class="productname">Windows</span> where
+ the native build does not work. The official
+ binaries are built using <span class="productname">Visual Studio</span>.
+ </p><p>
+ Native builds of <span class="application">psql</span> don't support command
+ line editing. The <span class="productname">Cygwin</span> build does support
+ command line editing, so it should be used where psql is needed for
+ interactive use on <span class="productname">Windows</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-windows-full.html" title="18.1. Building with Visual C++ or the&#10; Microsoft Windows SDK">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.7. Platform-Specific Notes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 18.1. Building with <span class="productname">Visual C++</span> or the
+ <span class="productname">Microsoft Windows SDK</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/installation-platform-notes.html b/doc/src/sgml/html/installation-platform-notes.html
new file mode 100644
index 0000000..45cbe2b
--- /dev/null
+++ b/doc/src/sgml/html/installation-platform-notes.html
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.7. Platform-Specific Notes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="supported-platforms.html" title="17.6. Supported Platforms" /><link rel="next" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.7. Platform-Specific Notes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="supported-platforms.html" title="17.6. Supported Platforms">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Next</a></td></tr></table><hr /></div><div class="sect1" id="INSTALLATION-PLATFORM-NOTES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.7. Platform-Specific Notes</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-AIX">17.7.1. AIX</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-CYGWIN">17.7.2. Cygwin</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-MACOS">17.7.3. macOS</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-MINGW">17.7.4. MinGW/Native Windows</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-SOLARIS">17.7.5. Solaris</a></span></dt></dl></div><p>
+ This section documents additional platform-specific issues
+ regarding the installation and setup of PostgreSQL. Be sure to
+ read the installation instructions, and in
+ particular <a class="xref" href="install-requirements.html" title="17.2. Requirements">Section 17.2</a> as well. Also,
+ check <a class="xref" href="regress.html" title="Chapter 33. Regression Tests">Chapter 33</a> regarding the
+ interpretation of regression test results.
+ </p><p>
+ Platforms that are not covered here have no known platform-specific
+ installation issues.
+ </p><div class="sect2" id="INSTALLATION-NOTES-AIX"><div class="titlepage"><div><div><h3 class="title">17.7.1. AIX</h3></div></div></div><a id="id-1.6.4.11.4.2" class="indexterm"></a><p>
+ You can use GCC or the native IBM compiler <code class="command">xlc</code>
+ to build <span class="productname">PostgreSQL</span>
+ on <span class="productname">AIX</span>.
+ </p><p>
+ <span class="productname">AIX</span> versions before 7.1 are no longer
+ tested nor supported by the <span class="productname">PostgreSQL</span>
+ community.
+ </p><div class="sect3" id="id-1.6.4.11.4.5"><div class="titlepage"><div><div><h4 class="title">17.7.1.1. Memory Management</h4></div></div></div><p>
+ AIX can be somewhat peculiar with regards to the way it does
+ memory management. You can have a server with many multiples of
+ gigabytes of RAM free, but still get out of memory or address
+ space errors when running applications. One example
+ is loading of extensions failing with unusual errors.
+ For example, running as the owner of the PostgreSQL installation:
+</p><pre class="screen">
+=# CREATE EXTENSION plperl;
+ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process.
+</pre><p>
+ Running as a non-owner in the group possessing the PostgreSQL
+ installation:
+</p><pre class="screen">
+=# CREATE EXTENSION plperl;
+ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address
+</pre><p>
+ Another example is out of memory errors in the PostgreSQL server
+ logs, with every memory allocation near or greater than 256 MB
+ failing.
+ </p><p>
+ The overall cause of all these problems is the default bittedness
+ and memory model used by the server process. By default, all
+ binaries built on AIX are 32-bit. This does not depend upon
+ hardware type or kernel in use. These 32-bit processes are
+ limited to 4 GB of memory laid out in 256 MB segments using one
+ of a few models. The default allows for less than 256 MB in the
+ heap as it shares a single segment with the stack.
+ </p><p>
+ In the case of the <code class="literal">plperl</code> example, above,
+ check your umask and the permissions of the binaries in your
+ PostgreSQL installation. The binaries involved in that example
+ were 32-bit and installed as mode 750 instead of 755. Due to the
+ permissions being set in this fashion, only the owner or a member
+ of the possessing group can load the library. Since it isn't
+ world-readable, the loader places the object into the process'
+ heap instead of the shared library segments where it would
+ otherwise be placed.
+ </p><p>
+ The <span class="quote">“<span class="quote">ideal</span>”</span> solution for this is to use a 64-bit
+ build of PostgreSQL, but that is not always practical, because
+ systems with 32-bit processors can build, but not run, 64-bit
+ binaries.
+ </p><p>
+ If a 32-bit binary is desired, set <code class="symbol">LDR_CNTRL</code> to
+ <code class="literal">MAXDATA=0x<em class="replaceable"><code>n</code></em>0000000</code>,
+ where 1 &lt;= n &lt;= 8, before starting the PostgreSQL server,
+ and try different values and <code class="filename">postgresql.conf</code>
+ settings to find a configuration that works satisfactorily. This
+ use of <code class="symbol">LDR_CNTRL</code> tells AIX that you want the
+ server to have <code class="symbol">MAXDATA</code> bytes set aside for the
+ heap, allocated in 256 MB segments. When you find a workable
+ configuration,
+ <code class="command">ldedit</code> can be used to modify the binaries so
+ that they default to using the desired heap size. PostgreSQL can
+ also be rebuilt, passing <code class="literal">configure
+ LDFLAGS="-Wl,-bmaxdata:0x<em class="replaceable"><code>n</code></em>0000000"</code>
+ to achieve the same effect.
+ </p><p>
+ For a 64-bit build, set <code class="envar">OBJECT_MODE</code> to 64 and
+ pass <code class="literal">CC="gcc -maix64"</code>
+ and <code class="literal">LDFLAGS="-Wl,-bbigtoc"</code>
+ to <code class="command">configure</code>. (Options for
+ <code class="command">xlc</code> might differ.) If you omit the export of
+ <code class="envar">OBJECT_MODE</code>, your build may fail with linker errors. When
+ <code class="envar">OBJECT_MODE</code> is set, it tells AIX's build utilities
+ such as <code class="command">ar</code>, <code class="command">as</code>, and <code class="command">ld</code> what
+ type of objects to default to handling.
+ </p><p>
+ By default, overcommit of paging space can happen. While we have
+ not seen this occur, AIX will kill processes when it runs out of
+ memory and the overcommit is accessed. The closest to this that
+ we have seen is fork failing because the system decided that
+ there was not enough memory for another process. Like many other
+ parts of AIX, the paging space allocation method and
+ out-of-memory kill is configurable on a system- or process-wide
+ basis if this becomes a problem.
+ </p></div></div><div class="sect2" id="INSTALLATION-NOTES-CYGWIN"><div class="titlepage"><div><div><h3 class="title">17.7.2. Cygwin</h3></div></div></div><a id="id-1.6.4.11.5.2" class="indexterm"></a><p>
+ PostgreSQL can be built using Cygwin, a Linux-like environment for
+ Windows, but that method is inferior to the native Windows build
+ <span class="phrase">(see <a class="xref" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Chapter 18</a>)</span> and
+ running a server under Cygwin is no longer recommended.
+ </p><p>
+ When building from source, proceed according to the Unix-style
+ installation procedure (i.e., <code class="literal">./configure;
+ make</code>; etc.), noting the following Cygwin-specific
+ differences:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Set your path to use the Cygwin bin directory before the
+ Windows utilities. This will help prevent problems with
+ compilation.
+ </p></li><li class="listitem"><p>
+ The <code class="command">adduser</code> command is not supported; use
+ the appropriate user management application on Windows NT,
+ 2000, or XP. Otherwise, skip this step.
+ </p></li><li class="listitem"><p>
+ The <code class="command">su</code> command is not supported; use ssh to
+ simulate su on Windows NT, 2000, or XP. Otherwise, skip this
+ step.
+ </p></li><li class="listitem"><p>
+ <span class="productname">OpenSSL</span> is not supported.
+ </p></li><li class="listitem"><p>
+ Start <code class="command">cygserver</code> for shared memory support.
+ To do this, enter the command <code class="literal">/usr/sbin/cygserver
+ &amp;</code>. This program needs to be running anytime you
+ start the PostgreSQL server or initialize a database cluster
+ (<code class="command">initdb</code>). The
+ default <code class="command">cygserver</code> configuration may need to
+ be changed (e.g., increase <code class="symbol">SEMMNS</code>) to prevent
+ PostgreSQL from failing due to a lack of system resources.
+ </p></li><li class="listitem"><p>
+ Building might fail on some systems where a locale other than
+ C is in use. To fix this, set the locale to C by doing
+ <code class="command">export LANG=C.utf8</code> before building, and then
+ setting it back to the previous setting after you have installed
+ PostgreSQL.
+ </p></li><li class="listitem"><p>
+ The parallel regression tests (<code class="literal">make check</code>)
+ can generate spurious regression test failures due to
+ overflowing the <code class="function">listen()</code> backlog queue
+ which causes connection refused errors or hangs. You can limit
+ the number of connections using the make
+ variable <code class="varname">MAX_CONNECTIONS</code> thus:
+</p><pre class="programlisting">
+make MAX_CONNECTIONS=5 check
+</pre><p>
+ (On some systems you can have up to about 10 simultaneous
+ connections.)
+ </p></li></ul></div><p>
+ </p><p>
+ It is possible to install <code class="command">cygserver</code> and the
+ PostgreSQL server as Windows NT services. For information on how
+ to do this, please refer to the <code class="filename">README</code>
+ document included with the PostgreSQL binary package on Cygwin.
+ It is installed in the
+ directory <code class="filename">/usr/share/doc/Cygwin</code>.
+ </p></div><div class="sect2" id="INSTALLATION-NOTES-MACOS"><div class="titlepage"><div><div><h3 class="title">17.7.3. macOS</h3></div></div></div><a id="id-1.6.4.11.6.2" class="indexterm"></a><p>
+ To build <span class="productname">PostgreSQL</span> from source
+ on <span class="productname">macOS</span>, you will need to install Apple's
+ command line developer tools, which can be done by issuing
+</p><pre class="programlisting">
+xcode-select --install
+</pre><p>
+ (note that this will pop up a GUI dialog window for confirmation).
+ You may or may not wish to also install Xcode.
+ </p><p>
+ On recent <span class="productname">macOS</span> releases, it's necessary to
+ embed the <span class="quote">“<span class="quote">sysroot</span>”</span> path in the include switches used to
+ find some system header files. This results in the outputs of
+ the <span class="application">configure</span> script varying depending on
+ which SDK version was used during <span class="application">configure</span>.
+ That shouldn't pose any problem in simple scenarios, but if you are
+ trying to do something like building an extension on a different machine
+ than the server code was built on, you may need to force use of a
+ different sysroot path. To do that, set <code class="varname">PG_SYSROOT</code>,
+ for example
+</p><pre class="programlisting">
+make PG_SYSROOT=<em class="replaceable"><code>/desired/path</code></em> all
+</pre><p>
+ To find out the appropriate path on your machine, run
+</p><pre class="programlisting">
+xcrun --show-sdk-path
+</pre><p>
+ Note that building an extension using a different sysroot version than
+ was used to build the core server is not really recommended; in the
+ worst case it could result in hard-to-debug ABI inconsistencies.
+ </p><p>
+ You can also select a non-default sysroot path when configuring, by
+ specifying <code class="varname">PG_SYSROOT</code>
+ to <span class="application">configure</span>:
+</p><pre class="programlisting">
+./configure ... PG_SYSROOT=<em class="replaceable"><code>/desired/path</code></em>
+</pre><p>
+ This would primarily be useful to cross-compile for some other
+ macOS version. There is no guarantee that the resulting executables
+ will run on the current host.
+ </p><p>
+ To suppress the <code class="option">-isysroot</code> options altogether, use
+</p><pre class="programlisting">
+./configure ... PG_SYSROOT=none
+</pre><p>
+ (any nonexistent pathname will work). This might be useful if you wish
+ to build with a non-Apple compiler, but beware that that case is not
+ tested or supported by the PostgreSQL developers.
+ </p><p>
+ <span class="productname">macOS</span>'s <span class="quote">“<span class="quote">System Integrity
+ Protection</span>”</span> (SIP) feature breaks <code class="literal">make check</code>,
+ because it prevents passing the needed setting
+ of <code class="literal">DYLD_LIBRARY_PATH</code> down to the executables being
+ tested. You can work around that by doing <code class="literal">make
+ install</code> before <code class="literal">make check</code>.
+ Most PostgreSQL developers just turn off SIP, though.
+ </p></div><div class="sect2" id="INSTALLATION-NOTES-MINGW"><div class="titlepage"><div><div><h3 class="title">17.7.4. MinGW/Native Windows</h3></div></div></div><a id="id-1.6.4.11.7.2" class="indexterm"></a><p>
+ PostgreSQL for Windows can be built using MinGW, a Unix-like build
+ environment for Microsoft operating systems, or using
+ Microsoft's <span class="productname">Visual C++</span> compiler suite.
+ The MinGW build procedure uses the normal build system described in
+ this chapter; the Visual C++ build works completely differently
+ and is described in <a class="xref" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Chapter 18</a>.
+ </p><p>
+ The native Windows port requires a 32 or 64-bit version of Windows
+ 2000 or later. Earlier operating systems do
+ not have sufficient infrastructure (but Cygwin may be used on
+ those). MinGW, the Unix-like build tools, and MSYS, a collection
+ of Unix tools required to run shell scripts
+ like <code class="command">configure</code>, can be downloaded
+ from <a class="ulink" href="http://www.mingw.org/" target="_top">http://www.mingw.org/</a>. Neither is
+ required to run the resulting binaries; they are needed only for
+ creating the binaries.
+ </p><p>
+ To build 64 bit binaries using MinGW, install the 64 bit tool set
+ from <a class="ulink" href="https://mingw-w64.org/" target="_top">https://mingw-w64.org/</a>, put its bin
+ directory in the <code class="envar">PATH</code>, and run
+ <code class="command">configure</code> with the
+ <code class="command">--host=x86_64-w64-mingw32</code> option.
+ </p><p>
+ After you have everything installed, it is suggested that you
+ run <span class="application">psql</span>
+ under <code class="command">CMD.EXE</code>, as the MSYS console has
+ buffering issues.
+ </p><div class="sect3" id="WINDOWS-CRASH-DUMPS"><div class="titlepage"><div><div><h4 class="title">17.7.4.1. Collecting Crash Dumps on Windows</h4></div></div></div><p>
+ If PostgreSQL on Windows crashes, it has the ability to generate
+ <span class="productname">minidumps</span> that can be used to track down the cause
+ for the crash, similar to core dumps on Unix. These dumps can be
+ read using the <span class="productname">Windows Debugger Tools</span> or using
+ <span class="productname">Visual Studio</span>. To enable the generation of dumps
+ on Windows, create a subdirectory named <code class="filename">crashdumps</code>
+ inside the cluster data directory. The dumps will then be written
+ into this directory with a unique name based on the identifier of
+ the crashing process and the current time of the crash.
+ </p></div></div><div class="sect2" id="INSTALLATION-NOTES-SOLARIS"><div class="titlepage"><div><div><h3 class="title">17.7.5. Solaris</h3></div></div></div><a id="id-1.6.4.11.8.2" class="indexterm"></a><p>
+ PostgreSQL is well-supported on Solaris. The more up to date your
+ operating system, the fewer issues you will experience.
+ </p><div class="sect3" id="id-1.6.4.11.8.4"><div class="titlepage"><div><div><h4 class="title">17.7.5.1. Required Tools</h4></div></div></div><p>
+ You can build with either GCC or Sun's compiler suite. For
+ better code optimization, Sun's compiler is strongly recommended
+ on the SPARC architecture. If
+ you are using Sun's compiler, be careful not to select
+ <code class="filename">/usr/ucb/cc</code>;
+ use <code class="filename">/opt/SUNWspro/bin/cc</code>.
+ </p><p>
+ You can download Sun Studio
+ from <a class="ulink" href="https://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/" target="_top">https://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/</a>.
+ Many GNU tools are integrated into Solaris 10, or they are
+ present on the Solaris companion CD. If you need packages for
+ older versions of Solaris, you can find these tools
+ at <a class="ulink" href="http://www.sunfreeware.com" target="_top">http://www.sunfreeware.com</a>.
+ If you prefer
+ sources, look
+ at <a class="ulink" href="https://www.gnu.org/prep/ftp" target="_top">https://www.gnu.org/prep/ftp</a>.
+ </p></div><div class="sect3" id="id-1.6.4.11.8.5"><div class="titlepage"><div><div><h4 class="title">17.7.5.2. configure Complains About a Failed Test Program</h4></div></div></div><p>
+ If <code class="command">configure</code> complains about a failed test
+ program, this is probably a case of the run-time linker being
+ unable to find some library, probably libz, libreadline or some
+ other non-standard library such as libssl. To point it to the
+ right location, set the <code class="envar">LDFLAGS</code> environment
+ variable on the <code class="command">configure</code> command line, e.g.,
+</p><pre class="programlisting">
+configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib"
+</pre><p>
+ See
+ the <span class="citerefentry"><span class="refentrytitle">ld</span></span>
+ man page for more information.
+ </p></div><div class="sect3" id="id-1.6.4.11.8.6"><div class="titlepage"><div><div><h4 class="title">17.7.5.3. Compiling for Optimal Performance</h4></div></div></div><p>
+ On the SPARC architecture, Sun Studio is strongly recommended for
+ compilation. Try using the <code class="option">-xO5</code> optimization
+ flag to generate significantly faster binaries. Do not use any
+ flags that modify behavior of floating-point operations
+ and <code class="varname">errno</code> processing (e.g.,
+ <code class="option">-fast</code>).
+ </p><p>
+ If you do not have a reason to use 64-bit binaries on SPARC,
+ prefer the 32-bit version. The 64-bit operations are slower and
+ 64-bit binaries are slower than the 32-bit variants. On the
+ other hand, 32-bit code on the AMD64 CPU family is not native,
+ so 32-bit code is significantly slower on that CPU family.
+ </p></div><div class="sect3" id="id-1.6.4.11.8.7"><div class="titlepage"><div><div><h4 class="title">17.7.5.4. Using DTrace for Tracing PostgreSQL</h4></div></div></div><p>
+ Yes, using DTrace is possible. See <a class="xref" href="dynamic-trace.html" title="28.5. Dynamic Tracing">Section 28.5</a> for
+ further information.
+ </p><p>
+ If you see the linking of the <code class="command">postgres</code> executable abort with an
+ error message like:
+</p><pre class="screen">
+Undefined first referenced
+ symbol in file
+AbortTransaction utils/probes.o
+CommitTransaction utils/probes.o
+ld: fatal: Symbol referencing errors. No output written to postgres
+collect2: ld returned 1 exit status
+make: *** [postgres] Error 1
+</pre><p>
+ your DTrace installation is too old to handle probes in static
+ functions. You need Solaris 10u4 or newer to use DTrace.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="supported-platforms.html" title="17.6. Supported Platforms">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.6. Supported Platforms </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 18. Installation from Source Code on <span class="productname">Windows</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/installation.html b/doc/src/sgml/html/installation.html
new file mode 100644
index 0000000..e764640
--- /dev/null
+++ b/doc/src/sgml/html/installation.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 17. Installation from Source Code</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-binaries.html" title="Chapter 16. Installation from Binaries" /><link rel="next" href="install-short.html" title="17.1. Short Version" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 17. Installation from Source Code</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-binaries.html" title="Chapter 16. Installation from Binaries">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="install-short.html" title="17.1. Short Version">Next</a></td></tr></table><hr /></div><div class="chapter" id="INSTALLATION"><div class="titlepage"><div><div><h2 class="title">Chapter 17. Installation from Source Code</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="install-short.html">17.1. Short Version</a></span></dt><dt><span class="sect1"><a href="install-requirements.html">17.2. Requirements</a></span></dt><dt><span class="sect1"><a href="install-getsource.html">17.3. Getting the Source</a></span></dt><dt><span class="sect1"><a href="install-procedure.html">17.4. Installation Procedure</a></span></dt><dd><dl><dt><span class="sect2"><a href="install-procedure.html#CONFIGURE-OPTIONS">17.4.1. <code class="filename">configure</code> Options</a></span></dt><dt><span class="sect2"><a href="install-procedure.html#CONFIGURE-ENVVARS">17.4.2. <code class="filename">configure</code> Environment Variables</a></span></dt></dl></dd><dt><span class="sect1"><a href="install-post.html">17.5. Post-Installation Setup</a></span></dt><dd><dl><dt><span class="sect2"><a href="install-post.html#INSTALL-POST-SHLIBS">17.5.1. Shared Libraries</a></span></dt><dt><span class="sect2"><a href="install-post.html#id-1.6.4.9.3">17.5.2. Environment Variables</a></span></dt></dl></dd><dt><span class="sect1"><a href="supported-platforms.html">17.6. Supported Platforms</a></span></dt><dt><span class="sect1"><a href="installation-platform-notes.html">17.7. Platform-Specific Notes</a></span></dt><dd><dl><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-AIX">17.7.1. AIX</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-CYGWIN">17.7.2. Cygwin</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-MACOS">17.7.3. macOS</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-MINGW">17.7.4. MinGW/Native Windows</a></span></dt><dt><span class="sect2"><a href="installation-platform-notes.html#INSTALLATION-NOTES-SOLARIS">17.7.5. Solaris</a></span></dt></dl></dd></dl></div><a id="id-1.6.4.2" class="indexterm"></a><p>
+ This chapter describes the installation of
+ <span class="productname">PostgreSQL</span> using the source code
+ distribution. If you are installing a pre-packaged distribution,
+ such as an RPM or Debian package, ignore this chapter
+ and see <a class="xref" href="install-binaries.html" title="Chapter 16. Installation from Binaries">Chapter 16</a> instead.
+ </p><p>
+ If you are building <span class="productname">PostgreSQL</span> for Microsoft
+ Windows, read this chapter if you intend to build with MinGW or Cygwin;
+ but if you intend to build with Microsoft's <span class="productname">Visual
+ C++</span>, see <a class="xref" href="install-windows.html" title="Chapter 18. Installation from Source Code on Windows">Chapter 18</a> instead.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-binaries.html" title="Chapter 16. Installation from Binaries">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="install-short.html" title="17.1. Short Version">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 16. Installation from Binaries </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.1. Short Version</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/intagg.html b/doc/src/sgml/html/intagg.html
new file mode 100644
index 0000000..5c49adf
--- /dev/null
+++ b/doc/src/sgml/html/intagg.html
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.19. intagg</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="hstore.html" title="F.18. hstore" /><link rel="next" href="intarray.html" title="F.20. intarray" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.19. intagg</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="hstore.html" title="F.18. hstore">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="intarray.html" title="F.20. intarray">Next</a></td></tr></table><hr /></div><div class="sect1" id="INTAGG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.19. intagg</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="intagg.html#id-1.11.7.28.4">F.19.1. Functions</a></span></dt><dt><span class="sect2"><a href="intagg.html#id-1.11.7.28.5">F.19.2. Sample Uses</a></span></dt></dl></div><a id="id-1.11.7.28.2" class="indexterm"></a><p>
+ The <code class="filename">intagg</code> module provides an integer aggregator and an
+ enumerator. <code class="filename">intagg</code> is now obsolete, because there
+ are built-in functions that provide a superset of its capabilities.
+ However, the module is still provided as a compatibility wrapper around
+ the built-in functions.
+ </p><div class="sect2" id="id-1.11.7.28.4"><div class="titlepage"><div><div><h3 class="title">F.19.1. Functions</h3></div></div></div><a id="id-1.11.7.28.4.2" class="indexterm"></a><a id="id-1.11.7.28.4.3" class="indexterm"></a><p>
+ The aggregator is an aggregate function
+ <code class="function">int_array_aggregate(integer)</code>
+ that produces an integer array
+ containing exactly the integers it is fed.
+ This is a wrapper around <code class="function">array_agg</code>,
+ which does the same thing for any array type.
+ </p><a id="id-1.11.7.28.4.5" class="indexterm"></a><p>
+ The enumerator is a function
+ <code class="function">int_array_enum(integer[])</code>
+ that returns <code class="type">setof integer</code>. It is essentially the reverse
+ operation of the aggregator: given an array of integers, expand it
+ into a set of rows. This is a wrapper around <code class="function">unnest</code>,
+ which does the same thing for any array type.
+ </p></div><div class="sect2" id="id-1.11.7.28.5"><div class="titlepage"><div><div><h3 class="title">F.19.2. Sample Uses</h3></div></div></div><p>
+ Many database systems have the notion of a one to many table. Such a table
+ usually sits between two indexed tables, for example:
+
+</p><pre class="programlisting">
+CREATE TABLE left (id INT PRIMARY KEY, ...);
+CREATE TABLE right (id INT PRIMARY KEY, ...);
+CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
+</pre><p>
+
+ It is typically used like this:
+
+</p><pre class="programlisting">
+SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
+ WHERE one_to_many.left = <em class="replaceable"><code>item</code></em>;
+</pre><p>
+
+ This will return all the items in the right hand table for an entry
+ in the left hand table. This is a very common construct in SQL.
+ </p><p>
+ Now, this methodology can be cumbersome with a very large number of
+ entries in the <code class="structname">one_to_many</code> table. Often,
+ a join like this would result in an index scan
+ and a fetch for each right hand entry in the table for a particular
+ left hand entry. If you have a very dynamic system, there is not much you
+ can do. However, if you have some data which is fairly static, you can
+ create a summary table with the aggregator.
+
+</p><pre class="programlisting">
+CREATE TABLE summary AS
+ SELECT left, int_array_aggregate(right) AS right
+ FROM one_to_many
+ GROUP BY left;
+</pre><p>
+
+ This will create a table with one row per left item, and an array
+ of right items. Now this is pretty useless without some way of using
+ the array; that's why there is an array enumerator. You can do
+
+</p><pre class="programlisting">
+SELECT left, int_array_enum(right) FROM summary WHERE left = <em class="replaceable"><code>item</code></em>;
+</pre><p>
+
+ The above query using <code class="function">int_array_enum</code> produces the same results
+ as
+
+</p><pre class="programlisting">
+SELECT left, right FROM one_to_many WHERE left = <em class="replaceable"><code>item</code></em>;
+</pre><p>
+
+ The difference is that the query against the summary table has to get
+ only one row from the table, whereas the direct query against
+ <code class="structname">one_to_many</code> must index scan and fetch a row for each entry.
+ </p><p>
+ On one system, an <code class="command">EXPLAIN</code> showed a query with a cost of 8488 was
+ reduced to a cost of 329. The original query was a join involving the
+ <code class="structname">one_to_many</code> table, which was replaced by:
+
+</p><pre class="programlisting">
+SELECT right, count(right) FROM
+ ( SELECT left, int_array_enum(right) AS right
+ FROM summary JOIN (SELECT left FROM left_table WHERE left = <em class="replaceable"><code>item</code></em>) AS lefts
+ ON (summary.left = lefts.left)
+ ) AS list
+ GROUP BY right
+ ORDER BY count DESC;
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="hstore.html" title="F.18. hstore">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="intarray.html" title="F.20. intarray">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.18. hstore </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.20. intarray</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/intarray.html b/doc/src/sgml/html/intarray.html
new file mode 100644
index 0000000..ccfff79
--- /dev/null
+++ b/doc/src/sgml/html/intarray.html
@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.20. intarray</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="intagg.html" title="F.19. intagg" /><link rel="next" href="isn.html" title="F.21. isn" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.20. intarray</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="intagg.html" title="F.19. intagg">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="isn.html" title="F.21. isn">Next</a></td></tr></table><hr /></div><div class="sect1" id="INTARRAY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.20. intarray</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.7">F.20.1. <code class="filename">intarray</code> Functions and Operators</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.8">F.20.2. Index Support</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.9">F.20.3. Example</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.10">F.20.4. Benchmark</a></span></dt><dt><span class="sect2"><a href="intarray.html#id-1.11.7.29.11">F.20.5. Authors</a></span></dt></dl></div><a id="id-1.11.7.29.2" class="indexterm"></a><p>
+ The <code class="filename">intarray</code> module provides a number of useful functions
+ and operators for manipulating null-free arrays of integers.
+ There is also support for indexed searches using some of the operators.
+ </p><p>
+ All of these operations will throw an error if a supplied array contains any
+ NULL elements.
+ </p><p>
+ Many of these operations are only sensible for one-dimensional arrays.
+ Although they will accept input arrays of more dimensions, the data is
+ treated as though it were a linear array in storage order.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.29.7"><div class="titlepage"><div><div><h3 class="title">F.20.1. <code class="filename">intarray</code> Functions and Operators</h3></div></div></div><p>
+ The functions provided by the <code class="filename">intarray</code> module
+ are shown in <a class="xref" href="intarray.html#INTARRAY-FUNC-TABLE" title="Table F.9. intarray Functions">Table F.9</a>, the operators
+ in <a class="xref" href="intarray.html#INTARRAY-OP-TABLE" title="Table F.10. intarray Operators">Table F.10</a>.
+ </p><div class="table" id="INTARRAY-FUNC-TABLE"><p class="title"><strong>Table F.9. <code class="filename">intarray</code> Functions</strong></p><div class="table-contents"><table class="table" summary="intarray Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">icount</code> ( <code class="type">integer[]</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of elements in the array.
+ </p>
+ <p>
+ <code class="literal">icount('{1,2,3}'::integer[])</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">sort</code> ( <code class="type">integer[]</code>, <em class="parameter"><code>dir</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Sorts the array in either ascending or descending order.
+ <em class="parameter"><code>dir</code></em> must be <code class="literal">asc</code>
+ or <code class="literal">desc</code>.
+ </p>
+ <p>
+ <code class="literal">sort('{1,3,2}'::integer[], 'desc')</code>
+ → <code class="returnvalue">{3,2,1}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sort</code> ( <code class="type">integer[]</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.3.1.2.1" class="indexterm"></a>
+ <code class="function">sort_asc</code> ( <code class="type">integer[]</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Sorts in ascending order.
+ </p>
+ <p>
+ <code class="literal">sort(array[11,77,44])</code>
+ → <code class="returnvalue">{11,44,77}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">sort_desc</code> ( <code class="type">integer[]</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Sorts in descending order.
+ </p>
+ <p>
+ <code class="literal">sort_desc(array[11,77,44])</code>
+ → <code class="returnvalue">{77,44,11}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">uniq</code> ( <code class="type">integer[]</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Removes adjacent duplicates.
+ Often used with <code class="function">sort</code> to remove all duplicates.
+ </p>
+ <p>
+ <code class="literal">uniq('{1,2,2,3,1,1}'::integer[])</code>
+ → <code class="returnvalue">{1,2,3,1}</code>
+ </p>
+ <p>
+ <code class="literal">uniq(sort('{1,2,3,2,1}'::integer[]))</code>
+ → <code class="returnvalue">{1,2,3}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">idx</code> ( <code class="type">integer[]</code>, <em class="parameter"><code>item</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns index of the first array element
+ matching <em class="parameter"><code>item</code></em>, or 0 if no match.
+ </p>
+ <p>
+ <code class="literal">idx(array[11,22,33,22,11], 22)</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">subarray</code> ( <code class="type">integer[]</code>, <em class="parameter"><code>start</code></em> <code class="type">integer</code>, <em class="parameter"><code>len</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Extracts the portion of the array starting at
+ position <em class="parameter"><code>start</code></em>, with <em class="parameter"><code>len</code></em>
+ elements.
+ </p>
+ <p>
+ <code class="literal">subarray('{1,2,3,2,1}'::integer[], 2, 3)</code>
+ → <code class="returnvalue">{2,3,2}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">subarray</code> ( <code class="type">integer[]</code>, <em class="parameter"><code>start</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Extracts the portion of the array starting at
+ position <em class="parameter"><code>start</code></em>.
+ </p>
+ <p>
+ <code class="literal">subarray('{1,2,3,2,1}'::integer[], 2)</code>
+ → <code class="returnvalue">{2,3,2,1}</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.29.7.3.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">intset</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Makes a single-element array.
+ </p>
+ <p>
+ <code class="literal">intset(42)</code>
+ → <code class="returnvalue">{42}</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="INTARRAY-OP-TABLE"><p class="title"><strong>Table F.10. <code class="filename">intarray</code> Operators</strong></p><div class="table-contents"><table class="table" summary="intarray Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">&amp;&amp;</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do arrays overlap (have at least one element in common)?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">@&gt;</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does left array contain right array?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">&lt;@</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is left array contained in right array?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type"></code> <code class="literal">#</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the number of elements in the array.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">#</code> <code class="type">integer</code>
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns index of the first array element
+ matching the right argument, or 0 if no match.
+ (Same as <code class="function">idx</code> function.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">+</code> <code class="type">integer</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Adds element to end of array.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">+</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Concatenates the arrays.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">-</code> <code class="type">integer</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Removes entries matching the right argument from the array.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">-</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Removes elements of the right array from the left array.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">|</code> <code class="type">integer</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Computes the union of the arguments.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">|</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Computes the union of the arguments.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">&amp;</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">integer[]</code>
+ </p>
+ <p>
+ Computes the intersection of the arguments.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">integer[]</code> <code class="literal">@@</code> <code class="type">query_int</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array satisfy query? (see below)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">query_int</code> <code class="literal">~~</code> <code class="type">integer[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array satisfy query? (commutator of <code class="literal">@@</code>)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The operators <code class="literal">&amp;&amp;</code>, <code class="literal">@&gt;</code> and
+ <code class="literal">&lt;@</code> are equivalent to <span class="productname">PostgreSQL</span>'s built-in
+ operators of the same names, except that they work only on integer arrays
+ that do not contain nulls, while the built-in operators work for any array
+ type. This restriction makes them faster than the built-in operators
+ in many cases.
+ </p><p>
+ The <code class="literal">@@</code> and <code class="literal">~~</code> operators test whether an array
+ satisfies a <em class="firstterm">query</em>, which is expressed as a value of a
+ specialized data type <code class="type">query_int</code>. A <em class="firstterm">query</em>
+ consists of integer values that are checked against the elements of
+ the array, possibly combined using the operators <code class="literal">&amp;</code>
+ (AND), <code class="literal">|</code> (OR), and <code class="literal">!</code> (NOT). Parentheses
+ can be used as needed. For example,
+ the query <code class="literal">1&amp;(2|3)</code> matches arrays that contain 1
+ and also contain either 2 or 3.
+ </p></div><div class="sect2" id="id-1.11.7.29.8"><div class="titlepage"><div><div><h3 class="title">F.20.2. Index Support</h3></div></div></div><p>
+ <code class="filename">intarray</code> provides index support for the
+ <code class="literal">&amp;&amp;</code>, <code class="literal">@&gt;</code>,
+ and <code class="literal">@@</code> operators, as well as regular array equality.
+ </p><p>
+ Two parameterized GiST index operator classes are provided:
+ <code class="literal">gist__int_ops</code> (used by default) is suitable for
+ small- to medium-size data sets, while
+ <code class="literal">gist__intbig_ops</code> uses a larger signature and is more
+ suitable for indexing large data sets (i.e., columns containing
+ a large number of distinct array values).
+ The implementation uses an RD-tree data structure with
+ built-in lossy compression.
+ </p><p>
+ <code class="literal">gist__int_ops</code> approximates an integer set as an array of
+ integer ranges. Its optional integer parameter <code class="literal">numranges</code>
+ determines the maximum number of ranges in
+ one index key. The default value of <code class="literal">numranges</code> is 100.
+ Valid values are between 1 and 253. Using larger arrays as GiST index
+ keys leads to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </p><p>
+ <code class="literal">gist__intbig_ops</code> approximates an integer set as a bitmap
+ signature. Its optional integer parameter <code class="literal">siglen</code>
+ determines the signature length in bytes.
+ The default signature length is 16 bytes. Valid values of signature length
+ are between 1 and 2024 bytes. Longer signatures lead to a more precise
+ search (scanning a smaller fraction of the index and fewer heap pages), at
+ the cost of a larger index.
+ </p><p>
+ There is also a non-default GIN operator class
+ <code class="literal">gin__int_ops</code>, which supports these operators as well
+ as <code class="literal">&lt;@</code>.
+ </p><p>
+ The choice between GiST and GIN indexing depends on the relative
+ performance characteristics of GiST and GIN, which are discussed elsewhere.
+ </p></div><div class="sect2" id="id-1.11.7.29.9"><div class="titlepage"><div><div><h3 class="title">F.20.3. Example</h3></div></div></div><pre class="programlisting">
+-- a message can be in one or more <span class="quote">“<span class="quote">sections</span>”</span>
+CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
+
+-- create specialized index with signature length of 32 bytes
+CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32));
+
+-- select messages in section 1 OR 2 - OVERLAP operator
+SELECT message.mid FROM message WHERE message.sections &amp;&amp; '{1,2}';
+
+-- select messages in sections 1 AND 2 - CONTAINS operator
+SELECT message.mid FROM message WHERE message.sections @&gt; '{1,2}';
+
+-- the same, using QUERY operator
+SELECT message.mid FROM message WHERE message.sections @@ '1&amp;2'::query_int;
+</pre></div><div class="sect2" id="id-1.11.7.29.10"><div class="titlepage"><div><div><h3 class="title">F.20.4. Benchmark</h3></div></div></div><p>
+ The source directory <code class="filename">contrib/intarray/bench</code> contains a
+ benchmark test suite, which can be run against an installed
+ <span class="productname">PostgreSQL</span> server. (It also requires <code class="filename">DBD::Pg</code>
+ to be installed.) To run:
+ </p><pre class="programlisting">
+cd .../contrib/intarray/bench
+createdb TEST
+psql -c "CREATE EXTENSION intarray" TEST
+./create_test.pl | psql TEST
+./bench.pl
+</pre><p>
+ The <code class="filename">bench.pl</code> script has numerous options, which
+ are displayed when it is run without any arguments.
+ </p></div><div class="sect2" id="id-1.11.7.29.11"><div class="titlepage"><div><div><h3 class="title">F.20.5. Authors</h3></div></div></div><p>
+ All work was done by Teodor Sigaev (<code class="email">&lt;<a class="email" href="mailto:teodor@sigaev.ru">teodor@sigaev.ru</a>&gt;</code>) and
+ Oleg Bartunov (<code class="email">&lt;<a class="email" href="mailto:oleg@sai.msu.su">oleg@sai.msu.su</a>&gt;</code>). See
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/" target="_top">http://www.sai.msu.su/~megera/postgres/gist/</a> for
+ additional information. Andrey Oktyabrski did a great work on adding new
+ functions and operations.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="intagg.html" title="F.19. intagg">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="isn.html" title="F.21. isn">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.19. intagg </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.21. isn</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/internals.html b/doc/src/sgml/html/internals.html
new file mode 100644
index 0000000..a84dd1a
--- /dev/null
+++ b/doc/src/sgml/html/internals.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part VII. Internals</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-postmaster.html" title="postmaster" /><link rel="next" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part VII. Internals</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-postmaster.html" title="postmaster">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Next</a></td></tr></table><hr /></div><div class="part" id="INTERNALS"><div class="titlepage"><div><div><h1 class="title">Part VII. Internals</h1></div></div></div><div class="partintro" id="id-1.10.2"><div></div><p>
+ This part contains assorted information that might be of use to
+ <span class="productname">PostgreSQL</span> developers.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="overview.html">52. Overview of PostgreSQL Internals</a></span></dt><dd><dl><dt><span class="sect1"><a href="query-path.html">52.1. The Path of a Query</a></span></dt><dt><span class="sect1"><a href="connect-estab.html">52.2. How Connections Are Established</a></span></dt><dt><span class="sect1"><a href="parser-stage.html">52.3. The Parser Stage</a></span></dt><dt><span class="sect1"><a href="rule-system.html">52.4. The <span class="productname">PostgreSQL</span> Rule System</a></span></dt><dt><span class="sect1"><a href="planner-optimizer.html">52.5. Planner/Optimizer</a></span></dt><dt><span class="sect1"><a href="executor.html">52.6. Executor</a></span></dt></dl></dd><dt><span class="chapter"><a href="catalogs.html">53. System Catalogs</a></span></dt><dd><dl><dt><span class="sect1"><a href="catalogs-overview.html">53.1. Overview</a></span></dt><dt><span class="sect1"><a href="catalog-pg-aggregate.html">53.2. <code class="structname">pg_aggregate</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-am.html">53.3. <code class="structname">pg_am</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-amop.html">53.4. <code class="structname">pg_amop</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-amproc.html">53.5. <code class="structname">pg_amproc</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-attrdef.html">53.6. <code class="structname">pg_attrdef</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-attribute.html">53.7. <code class="structname">pg_attribute</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-authid.html">53.8. <code class="structname">pg_authid</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-auth-members.html">53.9. <code class="structname">pg_auth_members</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-cast.html">53.10. <code class="structname">pg_cast</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-class.html">53.11. <code class="structname">pg_class</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-collation.html">53.12. <code class="structname">pg_collation</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-constraint.html">53.13. <code class="structname">pg_constraint</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-conversion.html">53.14. <code class="structname">pg_conversion</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-database.html">53.15. <code class="structname">pg_database</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-db-role-setting.html">53.16. <code class="structname">pg_db_role_setting</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-default-acl.html">53.17. <code class="structname">pg_default_acl</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-depend.html">53.18. <code class="structname">pg_depend</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-description.html">53.19. <code class="structname">pg_description</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-enum.html">53.20. <code class="structname">pg_enum</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-event-trigger.html">53.21. <code class="structname">pg_event_trigger</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-extension.html">53.22. <code class="structname">pg_extension</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-foreign-data-wrapper.html">53.23. <code class="structname">pg_foreign_data_wrapper</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-foreign-server.html">53.24. <code class="structname">pg_foreign_server</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-foreign-table.html">53.25. <code class="structname">pg_foreign_table</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-index.html">53.26. <code class="structname">pg_index</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-inherits.html">53.27. <code class="structname">pg_inherits</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-init-privs.html">53.28. <code class="structname">pg_init_privs</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-language.html">53.29. <code class="structname">pg_language</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-largeobject.html">53.30. <code class="structname">pg_largeobject</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-largeobject-metadata.html">53.31. <code class="structname">pg_largeobject_metadata</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-namespace.html">53.32. <code class="structname">pg_namespace</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-opclass.html">53.33. <code class="structname">pg_opclass</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-operator.html">53.34. <code class="structname">pg_operator</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-opfamily.html">53.35. <code class="structname">pg_opfamily</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-parameter-acl.html">53.36. <code class="structname">pg_parameter_acl</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-partitioned-table.html">53.37. <code class="structname">pg_partitioned_table</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-policy.html">53.38. <code class="structname">pg_policy</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-proc.html">53.39. <code class="structname">pg_proc</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-publication.html">53.40. <code class="structname">pg_publication</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-publication-namespace.html">53.41. <code class="structname">pg_publication_namespace</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-publication-rel.html">53.42. <code class="structname">pg_publication_rel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-range.html">53.43. <code class="structname">pg_range</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-replication-origin.html">53.44. <code class="structname">pg_replication_origin</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-rewrite.html">53.45. <code class="structname">pg_rewrite</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-seclabel.html">53.46. <code class="structname">pg_seclabel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-sequence.html">53.47. <code class="structname">pg_sequence</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-shdepend.html">53.48. <code class="structname">pg_shdepend</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-shdescription.html">53.49. <code class="structname">pg_shdescription</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-shseclabel.html">53.50. <code class="structname">pg_shseclabel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-statistic.html">53.51. <code class="structname">pg_statistic</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-statistic-ext.html">53.52. <code class="structname">pg_statistic_ext</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-statistic-ext-data.html">53.53. <code class="structname">pg_statistic_ext_data</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-subscription.html">53.54. <code class="structname">pg_subscription</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-subscription-rel.html">53.55. <code class="structname">pg_subscription_rel</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-tablespace.html">53.56. <code class="structname">pg_tablespace</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-transform.html">53.57. <code class="structname">pg_transform</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-trigger.html">53.58. <code class="structname">pg_trigger</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-config.html">53.59. <code class="structname">pg_ts_config</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-config-map.html">53.60. <code class="structname">pg_ts_config_map</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-dict.html">53.61. <code class="structname">pg_ts_dict</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-parser.html">53.62. <code class="structname">pg_ts_parser</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-ts-template.html">53.63. <code class="structname">pg_ts_template</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-type.html">53.64. <code class="structname">pg_type</code></a></span></dt><dt><span class="sect1"><a href="catalog-pg-user-mapping.html">53.65. <code class="structname">pg_user_mapping</code></a></span></dt></dl></dd><dt><span class="chapter"><a href="views.html">54. System Views</a></span></dt><dd><dl><dt><span class="sect1"><a href="views-overview.html">54.1. Overview</a></span></dt><dt><span class="sect1"><a href="view-pg-available-extensions.html">54.2. <code class="structname">pg_available_extensions</code></a></span></dt><dt><span class="sect1"><a href="view-pg-available-extension-versions.html">54.3. <code class="structname">pg_available_extension_versions</code></a></span></dt><dt><span class="sect1"><a href="view-pg-backend-memory-contexts.html">54.4. <code class="structname">pg_backend_memory_contexts</code></a></span></dt><dt><span class="sect1"><a href="view-pg-config.html">54.5. <code class="structname">pg_config</code></a></span></dt><dt><span class="sect1"><a href="view-pg-cursors.html">54.6. <code class="structname">pg_cursors</code></a></span></dt><dt><span class="sect1"><a href="view-pg-file-settings.html">54.7. <code class="structname">pg_file_settings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-group.html">54.8. <code class="structname">pg_group</code></a></span></dt><dt><span class="sect1"><a href="view-pg-hba-file-rules.html">54.9. <code class="structname">pg_hba_file_rules</code></a></span></dt><dt><span class="sect1"><a href="view-pg-ident-file-mappings.html">54.10. <code class="structname">pg_ident_file_mappings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-indexes.html">54.11. <code class="structname">pg_indexes</code></a></span></dt><dt><span class="sect1"><a href="view-pg-locks.html">54.12. <code class="structname">pg_locks</code></a></span></dt><dt><span class="sect1"><a href="view-pg-matviews.html">54.13. <code class="structname">pg_matviews</code></a></span></dt><dt><span class="sect1"><a href="view-pg-policies.html">54.14. <code class="structname">pg_policies</code></a></span></dt><dt><span class="sect1"><a href="view-pg-prepared-statements.html">54.15. <code class="structname">pg_prepared_statements</code></a></span></dt><dt><span class="sect1"><a href="view-pg-prepared-xacts.html">54.16. <code class="structname">pg_prepared_xacts</code></a></span></dt><dt><span class="sect1"><a href="view-pg-publication-tables.html">54.17. <code class="structname">pg_publication_tables</code></a></span></dt><dt><span class="sect1"><a href="view-pg-replication-origin-status.html">54.18. <code class="structname">pg_replication_origin_status</code></a></span></dt><dt><span class="sect1"><a href="view-pg-replication-slots.html">54.19. <code class="structname">pg_replication_slots</code></a></span></dt><dt><span class="sect1"><a href="view-pg-roles.html">54.20. <code class="structname">pg_roles</code></a></span></dt><dt><span class="sect1"><a href="view-pg-rules.html">54.21. <code class="structname">pg_rules</code></a></span></dt><dt><span class="sect1"><a href="view-pg-seclabels.html">54.22. <code class="structname">pg_seclabels</code></a></span></dt><dt><span class="sect1"><a href="view-pg-sequences.html">54.23. <code class="structname">pg_sequences</code></a></span></dt><dt><span class="sect1"><a href="view-pg-settings.html">54.24. <code class="structname">pg_settings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-shadow.html">54.25. <code class="structname">pg_shadow</code></a></span></dt><dt><span class="sect1"><a href="view-pg-shmem-allocations.html">54.26. <code class="structname">pg_shmem_allocations</code></a></span></dt><dt><span class="sect1"><a href="view-pg-stats.html">54.27. <code class="structname">pg_stats</code></a></span></dt><dt><span class="sect1"><a href="view-pg-stats-ext.html">54.28. <code class="structname">pg_stats_ext</code></a></span></dt><dt><span class="sect1"><a href="view-pg-stats-ext-exprs.html">54.29. <code class="structname">pg_stats_ext_exprs</code></a></span></dt><dt><span class="sect1"><a href="view-pg-tables.html">54.30. <code class="structname">pg_tables</code></a></span></dt><dt><span class="sect1"><a href="view-pg-timezone-abbrevs.html">54.31. <code class="structname">pg_timezone_abbrevs</code></a></span></dt><dt><span class="sect1"><a href="view-pg-timezone-names.html">54.32. <code class="structname">pg_timezone_names</code></a></span></dt><dt><span class="sect1"><a href="view-pg-user.html">54.33. <code class="structname">pg_user</code></a></span></dt><dt><span class="sect1"><a href="view-pg-user-mappings.html">54.34. <code class="structname">pg_user_mappings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-views.html">54.35. <code class="structname">pg_views</code></a></span></dt></dl></dd><dt><span class="chapter"><a href="protocol.html">55. Frontend/Backend Protocol</a></span></dt><dd><dl><dt><span class="sect1"><a href="protocol-overview.html">55.1. Overview</a></span></dt><dt><span class="sect1"><a href="protocol-flow.html">55.2. Message Flow</a></span></dt><dt><span class="sect1"><a href="sasl-authentication.html">55.3. SASL Authentication</a></span></dt><dt><span class="sect1"><a href="protocol-replication.html">55.4. Streaming Replication Protocol</a></span></dt><dt><span class="sect1"><a href="protocol-logical-replication.html">55.5. Logical Streaming Replication Protocol</a></span></dt><dt><span class="sect1"><a href="protocol-message-types.html">55.6. Message Data Types</a></span></dt><dt><span class="sect1"><a href="protocol-message-formats.html">55.7. Message Formats</a></span></dt><dt><span class="sect1"><a href="protocol-error-fields.html">55.8. Error and Notice Message Fields</a></span></dt><dt><span class="sect1"><a href="protocol-logicalrep-message-formats.html">55.9. Logical Replication Message Formats</a></span></dt><dt><span class="sect1"><a href="protocol-changes.html">55.10. Summary of Changes since Protocol 2.0</a></span></dt></dl></dd><dt><span class="chapter"><a href="source.html">56. PostgreSQL Coding Conventions</a></span></dt><dd><dl><dt><span class="sect1"><a href="source-format.html">56.1. Formatting</a></span></dt><dt><span class="sect1"><a href="error-message-reporting.html">56.2. Reporting Errors Within the Server</a></span></dt><dt><span class="sect1"><a href="error-style-guide.html">56.3. Error Message Style Guide</a></span></dt><dt><span class="sect1"><a href="source-conventions.html">56.4. Miscellaneous Coding Conventions</a></span></dt></dl></dd><dt><span class="chapter"><a href="nls.html">57. Native Language Support</a></span></dt><dd><dl><dt><span class="sect1"><a href="nls-translator.html">57.1. For the Translator</a></span></dt><dt><span class="sect1"><a href="nls-programmer.html">57.2. For the Programmer</a></span></dt></dl></dd><dt><span class="chapter"><a href="plhandler.html">58. Writing a Procedural Language Handler</a></span></dt><dt><span class="chapter"><a href="fdwhandler.html">59. Writing a Foreign Data Wrapper</a></span></dt><dd><dl><dt><span class="sect1"><a href="fdw-functions.html">59.1. Foreign Data Wrapper Functions</a></span></dt><dt><span class="sect1"><a href="fdw-callbacks.html">59.2. Foreign Data Wrapper Callback Routines</a></span></dt><dt><span class="sect1"><a href="fdw-helpers.html">59.3. Foreign Data Wrapper Helper Functions</a></span></dt><dt><span class="sect1"><a href="fdw-planning.html">59.4. Foreign Data Wrapper Query Planning</a></span></dt><dt><span class="sect1"><a href="fdw-row-locking.html">59.5. Row Locking in Foreign Data Wrappers</a></span></dt></dl></dd><dt><span class="chapter"><a href="tablesample-method.html">60. Writing a Table Sampling Method</a></span></dt><dd><dl><dt><span class="sect1"><a href="tablesample-support-functions.html">60.1. Sampling Method Support Functions</a></span></dt></dl></dd><dt><span class="chapter"><a href="custom-scan.html">61. Writing a Custom Scan Provider</a></span></dt><dd><dl><dt><span class="sect1"><a href="custom-scan-path.html">61.1. Creating Custom Scan Paths</a></span></dt><dt><span class="sect1"><a href="custom-scan-plan.html">61.2. Creating Custom Scan Plans</a></span></dt><dt><span class="sect1"><a href="custom-scan-execution.html">61.3. Executing Custom Scans</a></span></dt></dl></dd><dt><span class="chapter"><a href="geqo.html">62. Genetic Query Optimizer</a></span></dt><dd><dl><dt><span class="sect1"><a href="geqo-intro.html">62.1. Query Handling as a Complex Optimization Problem</a></span></dt><dt><span class="sect1"><a href="geqo-intro2.html">62.2. Genetic Algorithms</a></span></dt><dt><span class="sect1"><a href="geqo-pg-intro.html">62.3. Genetic Query Optimization (<acronym class="acronym">GEQO</acronym>) in PostgreSQL</a></span></dt><dt><span class="sect1"><a href="geqo-biblio.html">62.4. Further Reading</a></span></dt></dl></dd><dt><span class="chapter"><a href="tableam.html">63. Table Access Method Interface Definition</a></span></dt><dt><span class="chapter"><a href="indexam.html">64. Index Access Method Interface Definition</a></span></dt><dd><dl><dt><span class="sect1"><a href="index-api.html">64.1. Basic API Structure for Indexes</a></span></dt><dt><span class="sect1"><a href="index-functions.html">64.2. Index Access Method Functions</a></span></dt><dt><span class="sect1"><a href="index-scanning.html">64.3. Index Scanning</a></span></dt><dt><span class="sect1"><a href="index-locking.html">64.4. Index Locking Considerations</a></span></dt><dt><span class="sect1"><a href="index-unique-checks.html">64.5. Index Uniqueness Checks</a></span></dt><dt><span class="sect1"><a href="index-cost-estimation.html">64.6. Index Cost Estimation Functions</a></span></dt></dl></dd><dt><span class="chapter"><a href="generic-wal.html">65. Generic WAL Records</a></span></dt><dt><span class="chapter"><a href="custom-rmgr.html">66. Custom WAL Resource Managers</a></span></dt><dt><span class="chapter"><a href="btree.html">67. B-Tree Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="btree-intro.html">67.1. Introduction</a></span></dt><dt><span class="sect1"><a href="btree-behavior.html">67.2. Behavior of B-Tree Operator Classes</a></span></dt><dt><span class="sect1"><a href="btree-support-funcs.html">67.3. B-Tree Support Functions</a></span></dt><dt><span class="sect1"><a href="btree-implementation.html">67.4. Implementation</a></span></dt></dl></dd><dt><span class="chapter"><a href="gist.html">68. GiST Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="gist-intro.html">68.1. Introduction</a></span></dt><dt><span class="sect1"><a href="gist-builtin-opclasses.html">68.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="gist-extensibility.html">68.3. Extensibility</a></span></dt><dt><span class="sect1"><a href="gist-implementation.html">68.4. Implementation</a></span></dt><dt><span class="sect1"><a href="gist-examples.html">68.5. Examples</a></span></dt></dl></dd><dt><span class="chapter"><a href="spgist.html">69. SP-GiST Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="spgist-intro.html">69.1. Introduction</a></span></dt><dt><span class="sect1"><a href="spgist-builtin-opclasses.html">69.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="spgist-extensibility.html">69.3. Extensibility</a></span></dt><dt><span class="sect1"><a href="spgist-implementation.html">69.4. Implementation</a></span></dt><dt><span class="sect1"><a href="spgist-examples.html">69.5. Examples</a></span></dt></dl></dd><dt><span class="chapter"><a href="gin.html">70. GIN Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="gin-intro.html">70.1. Introduction</a></span></dt><dt><span class="sect1"><a href="gin-builtin-opclasses.html">70.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="gin-extensibility.html">70.3. Extensibility</a></span></dt><dt><span class="sect1"><a href="gin-implementation.html">70.4. Implementation</a></span></dt><dt><span class="sect1"><a href="gin-tips.html">70.5. GIN Tips and Tricks</a></span></dt><dt><span class="sect1"><a href="gin-limit.html">70.6. Limitations</a></span></dt><dt><span class="sect1"><a href="gin-examples.html">70.7. Examples</a></span></dt></dl></dd><dt><span class="chapter"><a href="brin.html">71. BRIN Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="brin-intro.html">71.1. Introduction</a></span></dt><dt><span class="sect1"><a href="brin-builtin-opclasses.html">71.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="brin-extensibility.html">71.3. Extensibility</a></span></dt></dl></dd><dt><span class="chapter"><a href="hash-index.html">72. Hash Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="hash-intro.html">72.1. Overview</a></span></dt><dt><span class="sect1"><a href="hash-implementation.html">72.2. Implementation</a></span></dt></dl></dd><dt><span class="chapter"><a href="storage.html">73. Database Physical Storage</a></span></dt><dd><dl><dt><span class="sect1"><a href="storage-file-layout.html">73.1. Database File Layout</a></span></dt><dt><span class="sect1"><a href="storage-toast.html">73.2. TOAST</a></span></dt><dt><span class="sect1"><a href="storage-fsm.html">73.3. Free Space Map</a></span></dt><dt><span class="sect1"><a href="storage-vm.html">73.4. Visibility Map</a></span></dt><dt><span class="sect1"><a href="storage-init.html">73.5. The Initialization Fork</a></span></dt><dt><span class="sect1"><a href="storage-page-layout.html">73.6. Database Page Layout</a></span></dt><dt><span class="sect1"><a href="storage-hot.html">73.7. Heap-Only Tuples (<acronym class="acronym">HOT</acronym>)</a></span></dt></dl></dd><dt><span class="chapter"><a href="bki.html">74. System Catalog Declarations and Initial Contents</a></span></dt><dd><dl><dt><span class="sect1"><a href="system-catalog-declarations.html">74.1. System Catalog Declaration Rules</a></span></dt><dt><span class="sect1"><a href="system-catalog-initial-data.html">74.2. System Catalog Initial Data</a></span></dt><dt><span class="sect1"><a href="bki-format.html">74.3. <acronym class="acronym">BKI</acronym> File Format</a></span></dt><dt><span class="sect1"><a href="bki-commands.html">74.4. <acronym class="acronym">BKI</acronym> Commands</a></span></dt><dt><span class="sect1"><a href="bki-structure.html">74.5. Structure of the Bootstrap <acronym class="acronym">BKI</acronym> File</a></span></dt><dt><span class="sect1"><a href="bki-example.html">74.6. BKI Example</a></span></dt></dl></dd><dt><span class="chapter"><a href="planner-stats-details.html">75. How the Planner Uses Statistics</a></span></dt><dd><dl><dt><span class="sect1"><a href="row-estimation-examples.html">75.1. Row Estimation Examples</a></span></dt><dt><span class="sect1"><a href="multivariate-statistics-examples.html">75.2. Multivariate Statistics Examples</a></span></dt><dt><span class="sect1"><a href="planner-stats-security.html">75.3. Planner Statistics and Security</a></span></dt></dl></dd><dt><span class="chapter"><a href="backup-manifest-format.html">76. Backup Manifest Format</a></span></dt><dd><dl><dt><span class="sect1"><a href="backup-manifest-toplevel.html">76.1. Backup Manifest Top-level Object</a></span></dt><dt><span class="sect1"><a href="backup-manifest-files.html">76.2. Backup Manifest File Object</a></span></dt><dt><span class="sect1"><a href="backup-manifest-wal-ranges.html">76.3. Backup Manifest WAL Range Object</a></span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-postmaster.html" title="postmaster">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">postmaster</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 52. Overview of PostgreSQL Internals</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/intro-whatis.html b/doc/src/sgml/html/intro-whatis.html
new file mode 100644
index 0000000..9be3234
--- /dev/null
+++ b/doc/src/sgml/html/intro-whatis.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>1.  What Is PostgreSQL?</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="preface.html" title="Preface" /><link rel="next" href="history.html" title="2. A Brief History of PostgreSQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">1.  What Is <span class="productname">PostgreSQL</span>?</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="preface.html" title="Preface">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><th width="60%" align="center">Preface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="history.html" title="2. A Brief History of PostgreSQL">Next</a></td></tr></table><hr /></div><div class="sect1" id="INTRO-WHATIS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">1.  What Is <span class="productname">PostgreSQL</span>?</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> is an object-relational
+ database management system (<acronym class="acronym">ORDBMS</acronym>) based on
+ <a class="ulink" href="https://dsf.berkeley.edu/postgres.html" target="_top">
+ <span class="productname">POSTGRES, Version 4.2</span></a>,
+ developed at the University of California at Berkeley Computer Science
+ Department. POSTGRES pioneered many concepts that only became
+ available in some commercial database systems much later.
+ </p><p>
+ <span class="productname">PostgreSQL</span> is an open-source descendant
+ of this original Berkeley code. It supports a large part of the SQL
+ standard and offers many modern features:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem">complex queries</li><li class="listitem">foreign keys</li><li class="listitem">triggers</li><li class="listitem">updatable views</li><li class="listitem">transactional integrity</li><li class="listitem">multiversion concurrency control</li></ul></div><p>
+
+ Also, <span class="productname">PostgreSQL</span> can be extended by the
+ user in many ways, for example by adding new
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem">data types</li><li class="listitem">functions</li><li class="listitem">operators</li><li class="listitem">aggregate functions</li><li class="listitem">index methods</li><li class="listitem">procedural languages</li></ul></div><p>
+ </p><p>
+ And because of the liberal license,
+ <span class="productname">PostgreSQL</span> can be used, modified, and
+ distributed by anyone free of charge for any purpose, be it
+ private, commercial, or academic.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="preface.html" title="Preface">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="history.html" title="2. A Brief History of PostgreSQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Preface </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2. A Brief History of <span class="productname">PostgreSQL</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/isn.html b/doc/src/sgml/html/isn.html
new file mode 100644
index 0000000..b13b505
--- /dev/null
+++ b/doc/src/sgml/html/isn.html
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.21. isn</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="intarray.html" title="F.20. intarray" /><link rel="next" href="lo.html" title="F.22. lo" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.21. isn</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="intarray.html" title="F.20. intarray">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="lo.html" title="F.22. lo">Next</a></td></tr></table><hr /></div><div class="sect1" id="ISN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.21. isn</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.5">F.21.1. Data Types</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.6">F.21.2. Casts</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.7">F.21.3. Functions and Operators</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.8">F.21.4. Examples</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.9">F.21.5. Bibliography</a></span></dt><dt><span class="sect2"><a href="isn.html#id-1.11.7.30.10">F.21.6. Author</a></span></dt></dl></div><a id="id-1.11.7.30.2" class="indexterm"></a><p>
+ The <code class="filename">isn</code> module provides data types for the following
+ international product numbering standards: EAN13, UPC, ISBN (books), ISMN
+ (music), and ISSN (serials). Numbers are validated on input according to a
+ hard-coded list of prefixes; this list of prefixes is also used to hyphenate
+ numbers on output. Since new prefixes are assigned from time to time, the
+ list of prefixes may be out of date. It is hoped that a future version of
+ this module will obtain the prefix list from one or more tables that
+ can be easily updated by users as needed; however, at present, the
+ list can only be updated by modifying the source code and recompiling.
+ Alternatively, prefix validation and hyphenation support may be
+ dropped from a future version of this module.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.30.5"><div class="titlepage"><div><div><h3 class="title">F.21.1. Data Types</h3></div></div></div><p>
+ <a class="xref" href="isn.html#ISN-DATATYPES" title="Table F.11. isn Data Types">Table F.11</a> shows the data types provided by
+ the <code class="filename">isn</code> module.
+ </p><div class="table" id="ISN-DATATYPES"><p class="title"><strong>Table F.11. <code class="filename">isn</code> Data Types</strong></p><div class="table-contents"><table class="table" summary="isn Data Types" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Data Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="type">EAN13</code></td><td>
+ European Article Numbers, always displayed in the EAN13 display format
+ </td></tr><tr><td><code class="type">ISBN13</code></td><td>
+ International Standard Book Numbers to be displayed in
+ the new EAN13 display format
+ </td></tr><tr><td><code class="type">ISMN13</code></td><td>
+ International Standard Music Numbers to be displayed in
+ the new EAN13 display format
+ </td></tr><tr><td><code class="type">ISSN13</code></td><td>
+ International Standard Serial Numbers to be displayed in the new
+ EAN13 display format
+ </td></tr><tr><td><code class="type">ISBN</code></td><td>
+ International Standard Book Numbers to be displayed in the old
+ short display format
+ </td></tr><tr><td><code class="type">ISMN</code></td><td>
+ International Standard Music Numbers to be displayed in the
+ old short display format
+ </td></tr><tr><td><code class="type">ISSN</code></td><td>
+ International Standard Serial Numbers to be displayed in the
+ old short display format
+ </td></tr><tr><td><code class="type">UPC</code></td><td>
+ Universal Product Codes
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Some notes:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>ISBN13, ISMN13, ISSN13 numbers are all EAN13 numbers.</p></li><li class="listitem"><p>EAN13 numbers aren't always ISBN13, ISMN13 or ISSN13 (some
+ are).</p></li><li class="listitem"><p>Some ISBN13 numbers can be displayed as ISBN.</p></li><li class="listitem"><p>Some ISMN13 numbers can be displayed as ISMN.</p></li><li class="listitem"><p>Some ISSN13 numbers can be displayed as ISSN.</p></li><li class="listitem"><p>UPC numbers are a subset of the EAN13 numbers (they are basically
+ EAN13 without the first <code class="literal">0</code> digit).</p></li><li class="listitem"><p>All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13
+ numbers.</p></li></ol></div><p>
+ Internally, all these types use the same representation (a 64-bit
+ integer), and all are interchangeable. Multiple types are provided
+ to control display formatting and to permit tighter validity checking
+ of input that is supposed to denote one particular type of number.
+ </p><p>
+ The <code class="type">ISBN</code>, <code class="type">ISMN</code>, and <code class="type">ISSN</code> types will display the
+ short version of the number (ISxN 10) whenever it's possible, and will show
+ ISxN 13 format for numbers that do not fit in the short version.
+ The <code class="type">EAN13</code>, <code class="type">ISBN13</code>, <code class="type">ISMN13</code> and
+ <code class="type">ISSN13</code> types will always display the long version of the ISxN
+ (EAN13).
+ </p></div><div class="sect2" id="id-1.11.7.30.6"><div class="titlepage"><div><div><h3 class="title">F.21.2. Casts</h3></div></div></div><p>
+ The <code class="filename">isn</code> module provides the following pairs of type casts:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ ISBN13 &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ ISMN13 &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ ISSN13 &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ ISBN &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ ISMN &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ ISSN &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ UPC &lt;=&gt; EAN13
+ </p></li><li class="listitem"><p>
+ ISBN &lt;=&gt; ISBN13
+ </p></li><li class="listitem"><p>
+ ISMN &lt;=&gt; ISMN13
+ </p></li><li class="listitem"><p>
+ ISSN &lt;=&gt; ISSN13
+ </p></li></ul></div><p>
+ When casting from <code class="type">EAN13</code> to another type, there is a run-time
+ check that the value is within the domain of the other type, and an error
+ is thrown if not. The other casts are simply relabelings that will
+ always succeed.
+ </p></div><div class="sect2" id="id-1.11.7.30.7"><div class="titlepage"><div><div><h3 class="title">F.21.3. Functions and Operators</h3></div></div></div><p>
+ The <code class="filename">isn</code> module provides the standard comparison operators,
+ plus B-tree and hash indexing support for all these data types. In
+ addition there are several specialized functions; shown in <a class="xref" href="isn.html#ISN-FUNCTIONS" title="Table F.12. isn Functions">Table F.12</a>.
+ In this table,
+ <code class="type">isn</code> means any one of the module's data types.
+ </p><div class="table" id="ISN-FUNCTIONS"><p class="title"><strong>Table F.12. <code class="filename">isn</code> Functions</strong></p><div class="table-contents"><table class="table" summary="isn Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.30.7.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">isn_weak</code> ( <code class="type">boolean</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Sets the weak input mode, and returns new setting.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">isn_weak</code> ()
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns the current status of the weak mode.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.30.7.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">make_valid</code> ( <code class="type">isn</code> )
+ → <code class="returnvalue">isn</code>
+ </p>
+ <p>
+ Validates an invalid number (clears the invalid flag).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.30.7.3.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">is_valid</code> ( <code class="type">isn</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Checks for the presence of the invalid flag.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <em class="firstterm">Weak</em> mode is used to be able to insert invalid data
+ into a table. Invalid means the check digit is wrong, not that there are
+ missing numbers.
+ </p><p>
+ Why would you want to use the weak mode? Well, it could be that
+ you have a huge collection of ISBN numbers, and that there are so many of
+ them that for weird reasons some have the wrong check digit (perhaps the
+ numbers were scanned from a printed list and the OCR got the numbers wrong,
+ perhaps the numbers were manually captured... who knows). Anyway, the point
+ is you might want to clean the mess up, but you still want to be able to
+ have all the numbers in your database and maybe use an external tool to
+ locate the invalid numbers in the database so you can verify the
+ information and validate it more easily; so for example you'd want to
+ select all the invalid numbers in the table.
+ </p><p>
+ When you insert invalid numbers in a table using the weak mode, the number
+ will be inserted with the corrected check digit, but it will be displayed
+ with an exclamation mark (<code class="literal">!</code>) at the end, for example
+ <code class="literal">0-11-000322-5!</code>. This invalid marker can be checked with
+ the <code class="function">is_valid</code> function and cleared with the
+ <code class="function">make_valid</code> function.
+ </p><p>
+ You can also force the insertion of invalid numbers even when not in the
+ weak mode, by appending the <code class="literal">!</code> character at the end of the
+ number.
+ </p><p>
+ Another special feature is that during input, you can write
+ <code class="literal">?</code> in place of the check digit, and the correct check digit
+ will be inserted automatically.
+ </p></div><div class="sect2" id="id-1.11.7.30.8"><div class="titlepage"><div><div><h3 class="title">F.21.4. Examples</h3></div></div></div><pre class="programlisting">
+--Using the types directly:
+SELECT isbn('978-0-393-04002-9');
+SELECT isbn13('0901690546');
+SELECT issn('1436-4522');
+
+--Casting types:
+-- note that you can only cast from ean13 to another type when the
+-- number would be valid in the realm of the target type;
+-- thus, the following will NOT work: select isbn(ean13('0220356483481'));
+-- but these will:
+SELECT upc(ean13('0220356483481'));
+SELECT ean13(upc('220356483481'));
+
+--Create a table with a single column to hold ISBN numbers:
+CREATE TABLE test (id isbn);
+INSERT INTO test VALUES('9780393040029');
+
+--Automatically calculate check digits (observe the '?'):
+INSERT INTO test VALUES('220500896?');
+INSERT INTO test VALUES('978055215372?');
+
+SELECT issn('3251231?');
+SELECT ismn('979047213542?');
+
+--Using the weak mode:
+SELECT isn_weak(true);
+INSERT INTO test VALUES('978-0-11-000533-4');
+INSERT INTO test VALUES('9780141219307');
+INSERT INTO test VALUES('2-205-00876-X');
+SELECT isn_weak(false);
+
+SELECT id FROM test WHERE NOT is_valid(id);
+UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!';
+
+SELECT * FROM test;
+
+SELECT isbn13(id) FROM test;
+</pre></div><div class="sect2" id="id-1.11.7.30.9"><div class="titlepage"><div><div><h3 class="title">F.21.5. Bibliography</h3></div></div></div><p>
+ The information to implement this module was collected from
+ several sites, including:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="ulink" href="https://www.isbn-international.org/" target="_top">https://www.isbn-international.org/</a></p></li><li class="listitem"><p><a class="ulink" href="https://www.issn.org/" target="_top">https://www.issn.org/</a></p></li><li class="listitem"><p><a class="ulink" href="https://www.ismn-international.org/" target="_top">https://www.ismn-international.org/</a></p></li><li class="listitem"><p><a class="ulink" href="https://www.wikipedia.org/" target="_top">https://www.wikipedia.org/</a></p></li></ul></div><p>
+
+ The prefixes used for hyphenation were also compiled from:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="ulink" href="https://www.gs1.org/standards/id-keys" target="_top">https://www.gs1.org/standards/id-keys</a></p></li><li class="listitem"><p><a class="ulink" href="https://en.wikipedia.org/wiki/List_of_ISBN_identifier_groups" target="_top">https://en.wikipedia.org/wiki/List_of_ISBN_identifier_groups</a></p></li><li class="listitem"><p><a class="ulink" href="https://www.isbn-international.org/content/isbn-users-manual" target="_top">https://www.isbn-international.org/content/isbn-users-manual</a></p></li><li class="listitem"><p><a class="ulink" href="https://en.wikipedia.org/wiki/International_Standard_Music_Number" target="_top">https://en.wikipedia.org/wiki/International_Standard_Music_Number</a></p></li><li class="listitem"><p><a class="ulink" href="https://www.ismn-international.org/ranges.html" target="_top">https://www.ismn-international.org/ranges.html</a></p></li></ul></div><p>
+
+ Care was taken during the creation of the algorithms and they
+ were meticulously verified against the suggested algorithms
+ in the official ISBN, ISMN, ISSN User Manuals.
+ </p></div><div class="sect2" id="id-1.11.7.30.10"><div class="titlepage"><div><div><h3 class="title">F.21.6. Author</h3></div></div></div><p>
+ Germán Méndez Bravo (Kronuz), 2004–2006
+ </p><p>
+ This module was inspired by Garrett A. Wollman's
+ <code class="filename">isbn_issn</code> code.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="intarray.html" title="F.20. intarray">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="lo.html" title="F.22. lo">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.20. intarray </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.22. lo</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/jit-configuration.html b/doc/src/sgml/html/jit-configuration.html
new file mode 100644
index 0000000..78f1da2
--- /dev/null
+++ b/doc/src/sgml/html/jit-configuration.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>32.3. Configuration</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="jit-decision.html" title="32.2. When to JIT?" /><link rel="next" href="jit-extensibility.html" title="32.4. Extensibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">32.3. Configuration</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="jit-decision.html" title="32.2. When to JIT?">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><th width="60%" align="center">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="jit-extensibility.html" title="32.4. Extensibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="JIT-CONFIGURATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">32.3. Configuration</h2></div></div></div><p>
+ The configuration variable
+ <a class="xref" href="runtime-config-query.html#GUC-JIT">jit</a> determines whether <acronym class="acronym">JIT</acronym>
+ compilation is enabled or disabled.
+ If it is enabled, the configuration variables
+ <a class="xref" href="runtime-config-query.html#GUC-JIT-ABOVE-COST">jit_above_cost</a>, <a class="xref" href="runtime-config-query.html#GUC-JIT-INLINE-ABOVE-COST">jit_inline_above_cost</a>, and <a class="xref" href="runtime-config-query.html#GUC-JIT-OPTIMIZE-ABOVE-COST">jit_optimize_above_cost</a> determine
+ whether <acronym class="acronym">JIT</acronym> compilation is performed for a query,
+ and how much effort is spent doing so.
+ </p><p>
+ <a class="xref" href="runtime-config-client.html#GUC-JIT-PROVIDER">jit_provider</a> determines which <acronym class="acronym">JIT</acronym>
+ implementation is used. It is rarely required to be changed. See <a class="xref" href="jit-extensibility.html#JIT-PLUGGABLE" title="32.4.2. Pluggable JIT Providers">Section 32.4.2</a>.
+ </p><p>
+ For development and debugging purposes a few additional configuration
+ parameters exist, as described in
+ <a class="xref" href="runtime-config-developer.html" title="20.17. Developer Options">Section 20.17</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jit-decision.html" title="32.2. When to JIT?">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jit-extensibility.html" title="32.4. Extensibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">32.2. When to <acronym class="acronym">JIT</acronym>? </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 32.4. Extensibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/jit-decision.html b/doc/src/sgml/html/jit-decision.html
new file mode 100644
index 0000000..fc81b21
--- /dev/null
+++ b/doc/src/sgml/html/jit-decision.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>32.2. When to JIT?</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="jit-reason.html" title="32.1. What Is JIT compilation?" /><link rel="next" href="jit-configuration.html" title="32.3. Configuration" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">32.2. When to <acronym class="acronym">JIT</acronym>?</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="jit-reason.html" title="32.1. What Is JIT compilation?">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><th width="60%" align="center">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="jit-configuration.html" title="32.3. Configuration">Next</a></td></tr></table><hr /></div><div class="sect1" id="JIT-DECISION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">32.2. When to <acronym class="acronym">JIT</acronym>?</h2></div></div></div><p>
+ <acronym class="acronym">JIT</acronym> compilation is beneficial primarily for long-running
+ CPU-bound queries. Frequently these will be analytical queries. For short
+ queries the added overhead of performing <acronym class="acronym">JIT</acronym> compilation
+ will often be higher than the time it can save.
+ </p><p>
+ To determine whether <acronym class="acronym">JIT</acronym> compilation should be used,
+ the total estimated cost of a query (see
+ <a class="xref" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Chapter 75</a> and
+ <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS" title="20.7.2. Planner Cost Constants">Section 20.7.2</a>) is used.
+ The estimated cost of the query will be compared with the setting of <a class="xref" href="runtime-config-query.html#GUC-JIT-ABOVE-COST">jit_above_cost</a>. If the cost is higher,
+ <acronym class="acronym">JIT</acronym> compilation will be performed.
+ Two further decisions are then needed.
+ Firstly, if the estimated cost is more
+ than the setting of <a class="xref" href="runtime-config-query.html#GUC-JIT-INLINE-ABOVE-COST">jit_inline_above_cost</a>, short
+ functions and operators used in the query will be inlined.
+ Secondly, if the estimated cost is more than the setting of <a class="xref" href="runtime-config-query.html#GUC-JIT-OPTIMIZE-ABOVE-COST">jit_optimize_above_cost</a>, expensive optimizations are
+ applied to improve the generated code.
+ Each of these options increases the <acronym class="acronym">JIT</acronym> compilation
+ overhead, but can reduce query execution time considerably.
+ </p><p>
+ These cost-based decisions will be made at plan time, not execution
+ time. This means that when prepared statements are in use, and a generic
+ plan is used (see <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a>), the values of the
+ configuration parameters in effect at prepare time control the decisions,
+ not the settings at execution time.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If <a class="xref" href="runtime-config-query.html#GUC-JIT">jit</a> is set to <code class="literal">off</code>, or if no
+ <acronym class="acronym">JIT</acronym> implementation is available (for example because
+ the server was compiled without <code class="literal">--with-llvm</code>),
+ <acronym class="acronym">JIT</acronym> will not be performed, even if it would be
+ beneficial based on the above criteria. Setting <a class="xref" href="runtime-config-query.html#GUC-JIT">jit</a>
+ to <code class="literal">off</code> has effects at both plan and execution time.
+ </p></div><p>
+ <a class="xref" href="sql-explain.html" title="EXPLAIN"><span class="refentrytitle">EXPLAIN</span></a> can be used to see whether
+ <acronym class="acronym">JIT</acronym> is used or not. As an example, here is a query that
+ is not using <acronym class="acronym">JIT</acronym>:
+</p><pre class="screen">
+=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class;
+ QUERY PLAN
+-------------------------------------------------------------------​------------------------------------------
+ Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1)
+ -&gt; Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1)
+ Planning Time: 0.116 ms
+ Execution Time: 0.365 ms
+(4 rows)
+</pre><p>
+ Given the cost of the plan, it is entirely reasonable that no
+ <acronym class="acronym">JIT</acronym> was used; the cost of <acronym class="acronym">JIT</acronym> would
+ have been bigger than the potential savings. Adjusting the cost limits
+ will lead to <acronym class="acronym">JIT</acronym> use:
+</p><pre class="screen">
+=# SET jit_above_cost = 10;
+SET
+=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class;
+ QUERY PLAN
+-------------------------------------------------------------------​------------------------------------------
+ Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1)
+ -&gt; Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1)
+ Planning Time: 0.133 ms
+ JIT:
+ Functions: 3
+ Options: Inlining false, Optimization false, Expressions true, Deforming true
+ Timing: Generation 1.259 ms, Inlining 0.000 ms, Optimization 0.797 ms, Emission 5.048 ms, Total 7.104 ms
+ Execution Time: 7.416 ms
+</pre><p>
+ As visible here, <acronym class="acronym">JIT</acronym> was used, but inlining and
+ expensive optimization were not. If <a class="xref" href="runtime-config-query.html#GUC-JIT-INLINE-ABOVE-COST">jit_inline_above_cost</a> or <a class="xref" href="runtime-config-query.html#GUC-JIT-OPTIMIZE-ABOVE-COST">jit_optimize_above_cost</a> were also lowered,
+ that would change.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jit-reason.html" title="32.1. What Is JIT compilation?">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jit-configuration.html" title="32.3. Configuration">Next</a></td></tr><tr><td width="40%" align="left" valign="top">32.1. What Is <acronym class="acronym">JIT</acronym> compilation? </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 32.3. Configuration</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/jit-extensibility.html b/doc/src/sgml/html/jit-extensibility.html
new file mode 100644
index 0000000..54c2308
--- /dev/null
+++ b/doc/src/sgml/html/jit-extensibility.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>32.4. Extensibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="jit-configuration.html" title="32.3. Configuration" /><link rel="next" href="regress.html" title="Chapter 33. Regression Tests" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">32.4. Extensibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="jit-configuration.html" title="32.3. Configuration">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><th width="60%" align="center">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="regress.html" title="Chapter 33. Regression Tests">Next</a></td></tr></table><hr /></div><div class="sect1" id="JIT-EXTENSIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">32.4. Extensibility</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="jit-extensibility.html#JIT-EXTENSIBILITY-BITCODE">32.4.1. Inlining Support for Extensions</a></span></dt><dt><span class="sect2"><a href="jit-extensibility.html#JIT-PLUGGABLE">32.4.2. Pluggable <acronym class="acronym">JIT</acronym> Providers</a></span></dt></dl></div><div class="sect2" id="JIT-EXTENSIBILITY-BITCODE"><div class="titlepage"><div><div><h3 class="title">32.4.1. Inlining Support for Extensions</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span>'s <acronym class="acronym">JIT</acronym>
+ implementation can inline the bodies of functions
+ of types <code class="literal">C</code> and <code class="literal">internal</code>, as well as
+ operators based on such functions. To do so for functions in extensions,
+ the definitions of those functions need to be made available.
+ When using <a class="link" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure">PGXS</a> to build an extension
+ against a server that has been compiled with LLVM JIT support, the
+ relevant files will be built and installed automatically.
+ </p><p>
+ The relevant files have to be installed into
+ <code class="filename">$pkglibdir/bitcode/$extension/</code> and a summary of them
+ into <code class="filename">$pkglibdir/bitcode/$extension.index.bc</code>, where
+ <code class="literal">$pkglibdir</code> is the directory returned by
+ <code class="literal">pg_config --pkglibdir</code> and <code class="literal">$extension</code>
+ is the base name of the extension's shared library.
+
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ For functions built into <span class="productname">PostgreSQL</span> itself,
+ the bitcode is installed into
+ <code class="literal">$pkglibdir/bitcode/postgres</code>.
+ </p></div><p>
+ </p></div><div class="sect2" id="JIT-PLUGGABLE"><div class="titlepage"><div><div><h3 class="title">32.4.2. Pluggable <acronym class="acronym">JIT</acronym> Providers</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> provides a <acronym class="acronym">JIT</acronym>
+ implementation based on <span class="productname">LLVM</span>. The interface to
+ the <acronym class="acronym">JIT</acronym> provider is pluggable and the provider can be
+ changed without recompiling (although currently, the build process only
+ provides inlining support data for <span class="productname">LLVM</span>).
+ The active provider is chosen via the setting
+ <a class="xref" href="runtime-config-client.html#GUC-JIT-PROVIDER">jit_provider</a>.
+ </p><div class="sect3" id="id-1.6.19.8.3.3"><div class="titlepage"><div><div><h4 class="title">32.4.2.1. <acronym class="acronym">JIT</acronym> Provider Interface</h4></div></div></div><p>
+ A <acronym class="acronym">JIT</acronym> provider is loaded by dynamically loading the
+ named shared library. The normal library search path is used to locate
+ the library. To provide the required <acronym class="acronym">JIT</acronym> provider
+ callbacks and to indicate that the library is actually a
+ <acronym class="acronym">JIT</acronym> provider, it needs to provide a C function named
+ <code class="function">_PG_jit_provider_init</code>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions:
+</p><pre class="programlisting">
+struct JitProviderCallbacks
+{
+ JitProviderResetAfterErrorCB reset_after_error;
+ JitProviderReleaseContextCB release_context;
+ JitProviderCompileExprCB compile_expr;
+};
+
+extern void _PG_jit_provider_init(JitProviderCallbacks *cb);
+</pre><p>
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jit-configuration.html" title="32.3. Configuration">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="regress.html" title="Chapter 33. Regression Tests">Next</a></td></tr><tr><td width="40%" align="left" valign="top">32.3. Configuration </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 33. Regression Tests</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/jit-reason.html b/doc/src/sgml/html/jit-reason.html
new file mode 100644
index 0000000..716527e
--- /dev/null
+++ b/doc/src/sgml/html/jit-reason.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>32.1. What Is JIT compilation?</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)" /><link rel="next" href="jit-decision.html" title="32.2. When to JIT?" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">32.1. What Is <acronym class="acronym">JIT</acronym> compilation?</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><th width="60%" align="center">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="jit-decision.html" title="32.2. When to JIT?">Next</a></td></tr></table><hr /></div><div class="sect1" id="JIT-REASON"><div class="titlepage"><div><div><h2 class="title" style="clear: both">32.1. What Is <acronym class="acronym">JIT</acronym> compilation?</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="jit-reason.html#JIT-ACCELERATED-OPERATIONS">32.1.1. <acronym class="acronym">JIT</acronym> Accelerated Operations</a></span></dt><dt><span class="sect2"><a href="jit-reason.html#JIT-INLINING">32.1.2. Inlining</a></span></dt><dt><span class="sect2"><a href="jit-reason.html#JIT-OPTIMIZATION">32.1.3. Optimization</a></span></dt></dl></div><p>
+ Just-in-Time (<acronym class="acronym">JIT</acronym>) compilation is the process of turning
+ some form of interpreted program evaluation into a native program, and
+ doing so at run time.
+ For example, instead of using general-purpose code that can evaluate
+ arbitrary SQL expressions to evaluate a particular SQL predicate
+ like <code class="literal">WHERE a.col = 3</code>, it is possible to generate a
+ function that is specific to that expression and can be natively executed
+ by the CPU, yielding a speedup.
+ </p><p>
+ <span class="productname">PostgreSQL</span> has builtin support to perform
+ <acronym class="acronym">JIT</acronym> compilation using <a class="ulink" href="https://llvm.org/" target="_top"><span class="productname">LLVM</span></a> when
+ <span class="productname">PostgreSQL</span> is built with
+ <a class="link" href="install-procedure.html#CONFIGURE-WITH-LLVM"><code class="literal">--with-llvm</code></a>.
+ </p><p>
+ See <code class="filename">src/backend/jit/README</code> for further details.
+ </p><div class="sect2" id="JIT-ACCELERATED-OPERATIONS"><div class="titlepage"><div><div><h3 class="title">32.1.1. <acronym class="acronym">JIT</acronym> Accelerated Operations</h3></div></div></div><p>
+ Currently <span class="productname">PostgreSQL</span>'s <acronym class="acronym">JIT</acronym>
+ implementation has support for accelerating expression evaluation and
+ tuple deforming. Several other operations could be accelerated in the
+ future.
+ </p><p>
+ Expression evaluation is used to evaluate <code class="literal">WHERE</code>
+ clauses, target lists, aggregates and projections. It can be accelerated
+ by generating code specific to each case.
+ </p><p>
+ Tuple deforming is the process of transforming an on-disk tuple (see <a class="xref" href="storage-page-layout.html#STORAGE-TUPLE-LAYOUT" title="73.6.1. Table Row Layout">Section 73.6.1</a>) into its in-memory representation.
+ It can be accelerated by creating a function specific to the table layout
+ and the number of columns to be extracted.
+ </p></div><div class="sect2" id="JIT-INLINING"><div class="titlepage"><div><div><h3 class="title">32.1.2. Inlining</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> is very extensible and allows new
+ data types, functions, operators and other database objects to be defined;
+ see <a class="xref" href="extend.html" title="Chapter 38. Extending SQL">Chapter 38</a>. In fact the built-in objects are implemented
+ using nearly the same mechanisms. This extensibility implies some
+ overhead, for example due to function calls (see <a class="xref" href="xfunc.html" title="38.3. User-Defined Functions">Section 38.3</a>).
+ To reduce that overhead, <acronym class="acronym">JIT</acronym> compilation can inline the
+ bodies of small functions into the expressions using them. That allows a
+ significant percentage of the overhead to be optimized away.
+ </p></div><div class="sect2" id="JIT-OPTIMIZATION"><div class="titlepage"><div><div><h3 class="title">32.1.3. Optimization</h3></div></div></div><p>
+ <span class="productname">LLVM</span> has support for optimizing generated
+ code. Some of the optimizations are cheap enough to be performed whenever
+ <acronym class="acronym">JIT</acronym> is used, while others are only beneficial for
+ longer-running queries.
+ See <a class="ulink" href="https://llvm.org/docs/Passes.html#transform-passes" target="_top">https://llvm.org/docs/Passes.html#transform-passes</a> for
+ more details about optimizations.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jit-decision.html" title="32.2. When to JIT?">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 32.2. When to <acronym class="acronym">JIT</acronym>?</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/jit.html b/doc/src/sgml/html/jit.html
new file mode 100644
index 0000000..4b93424
--- /dev/null
+++ b/doc/src/sgml/html/jit.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 32. Just-in-Time Compilation (JIT)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-quick-setup.html" title="31.11. Quick Setup" /><link rel="next" href="jit-reason.html" title="32.1. What Is JIT compilation?" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-quick-setup.html" title="31.11. Quick Setup">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="jit-reason.html" title="32.1. What Is JIT compilation?">Next</a></td></tr></table><hr /></div><div class="chapter" id="JIT"><div class="titlepage"><div><div><h2 class="title">Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="jit-reason.html">32.1. What Is <acronym class="acronym">JIT</acronym> compilation?</a></span></dt><dd><dl><dt><span class="sect2"><a href="jit-reason.html#JIT-ACCELERATED-OPERATIONS">32.1.1. <acronym class="acronym">JIT</acronym> Accelerated Operations</a></span></dt><dt><span class="sect2"><a href="jit-reason.html#JIT-INLINING">32.1.2. Inlining</a></span></dt><dt><span class="sect2"><a href="jit-reason.html#JIT-OPTIMIZATION">32.1.3. Optimization</a></span></dt></dl></dd><dt><span class="sect1"><a href="jit-decision.html">32.2. When to <acronym class="acronym">JIT</acronym>?</a></span></dt><dt><span class="sect1"><a href="jit-configuration.html">32.3. Configuration</a></span></dt><dt><span class="sect1"><a href="jit-extensibility.html">32.4. Extensibility</a></span></dt><dd><dl><dt><span class="sect2"><a href="jit-extensibility.html#JIT-EXTENSIBILITY-BITCODE">32.4.1. Inlining Support for Extensions</a></span></dt><dt><span class="sect2"><a href="jit-extensibility.html#JIT-PLUGGABLE">32.4.2. Pluggable <acronym class="acronym">JIT</acronym> Providers</a></span></dt></dl></dd></dl></div><a id="id-1.6.19.2" class="indexterm"></a><a id="id-1.6.19.3" class="indexterm"></a><p>
+ This chapter explains what just-in-time compilation is, and how it can be
+ configured in <span class="productname">PostgreSQL</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-quick-setup.html" title="31.11. Quick Setup">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jit-reason.html" title="32.1. What Is JIT compilation?">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.11. Quick Setup </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 32.1. What Is <acronym class="acronym">JIT</acronym> compilation?</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/kernel-resources.html b/doc/src/sgml/html/kernel-resources.html
new file mode 100644
index 0000000..8d94e12
--- /dev/null
+++ b/doc/src/sgml/html/kernel-resources.html
@@ -0,0 +1,553 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.4. Managing Kernel Resources</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="server-start.html" title="19.3. Starting the Database Server" /><link rel="next" href="server-shutdown.html" title="19.5. Shutting Down the Server" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.4. Managing Kernel Resources</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="server-start.html" title="19.3. Starting the Database Server">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="server-shutdown.html" title="19.5. Shutting Down the Server">Next</a></td></tr></table><hr /></div><div class="sect1" id="KERNEL-RESOURCES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.4. Managing Kernel Resources</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="kernel-resources.html#SYSVIPC">19.4.1. Shared Memory and Semaphores</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#SYSTEMD-REMOVEIPC">19.4.2. systemd RemoveIPC</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#id-1.6.6.7.5">19.4.3. Resource Limits</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#LINUX-MEMORY-OVERCOMMIT">19.4.4. Linux Memory Overcommit</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#LINUX-HUGE-PAGES">19.4.5. Linux Huge Pages</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> can sometimes exhaust various operating system
+ resource limits, especially when multiple copies of the server are running
+ on the same system, or in very large installations. This section explains
+ the kernel resources used by <span class="productname">PostgreSQL</span> and the steps you
+ can take to resolve problems related to kernel resource consumption.
+ </p><div class="sect2" id="SYSVIPC"><div class="titlepage"><div><div><h3 class="title">19.4.1. Shared Memory and Semaphores</h3></div></div></div><a id="id-1.6.6.7.3.2" class="indexterm"></a><a id="id-1.6.6.7.3.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> requires the operating system to provide
+ inter-process communication (<acronym class="acronym">IPC</acronym>) features, specifically
+ shared memory and semaphores. Unix-derived systems typically provide
+ <span class="quote">“<span class="quote"><span class="systemitem">System V</span></span>”</span> <acronym class="acronym">IPC</acronym>,
+ <span class="quote">“<span class="quote"><span class="systemitem">POSIX</span></span>”</span> <acronym class="acronym">IPC</acronym>, or both.
+ <span class="systemitem">Windows</span> has its own implementation of
+ these features and is not discussed here.
+ </p><p>
+ By default, <span class="productname">PostgreSQL</span> allocates
+ a very small amount of System V shared memory, as well as a much larger
+ amount of anonymous <code class="function">mmap</code> shared memory.
+ Alternatively, a single large System V shared memory region can be used
+ (see <a class="xref" href="runtime-config-resource.html#GUC-SHARED-MEMORY-TYPE">shared_memory_type</a>).
+
+ In addition a significant number of semaphores, which can be either
+ System V or POSIX style, are created at server startup. Currently,
+ POSIX semaphores are used on Linux and FreeBSD systems while other
+ platforms use System V semaphores.
+ </p><p>
+ System V <acronym class="acronym">IPC</acronym> features are typically constrained by
+ system-wide allocation limits.
+ When <span class="productname">PostgreSQL</span> exceeds one of these limits,
+ the server will refuse to start and
+ should leave an instructive error message describing the problem
+ and what to do about it. (See also <a class="xref" href="server-start.html#SERVER-START-FAILURES" title="19.3.1. Server Start-up Failures">Section 19.3.1</a>.) The relevant kernel
+ parameters are named consistently across different systems; <a class="xref" href="kernel-resources.html#SYSVIPC-PARAMETERS" title="Table 19.1. System V IPC Parameters">Table 19.1</a> gives an overview. The methods to set
+ them, however, vary. Suggestions for some platforms are given below.
+ </p><div class="table" id="SYSVIPC-PARAMETERS"><p class="title"><strong>Table 19.1. <span class="systemitem">System V</span> <acronym class="acronym">IPC</acronym> Parameters</strong></p><div class="table-contents"><table class="table" summary="System V IPC Parameters" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Description</th><th>Values needed to run one <span class="productname">PostgreSQL</span> instance</th></tr></thead><tbody><tr><td><code class="varname">SHMMAX</code></td><td>Maximum size of shared memory segment (bytes)</td><td>at least 1kB, but the default is usually much higher</td></tr><tr><td><code class="varname">SHMMIN</code></td><td>Minimum size of shared memory segment (bytes)</td><td>1</td></tr><tr><td><code class="varname">SHMALL</code></td><td>Total amount of shared memory available (bytes or pages)</td><td>same as <code class="varname">SHMMAX</code> if bytes,
+ or <code class="literal">ceil(SHMMAX/PAGE_SIZE)</code> if pages,
+ plus room for other applications</td></tr><tr><td><code class="varname">SHMSEG</code></td><td>Maximum number of shared memory segments per process</td><td>only 1 segment is needed, but the default is much higher</td></tr><tr><td><code class="varname">SHMMNI</code></td><td>Maximum number of shared memory segments system-wide</td><td>like <code class="varname">SHMSEG</code> plus room for other applications</td></tr><tr><td><code class="varname">SEMMNI</code></td><td>Maximum number of semaphore identifiers (i.e., sets)</td><td>at least <code class="literal">ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16)</code> plus room for other applications</td></tr><tr><td><code class="varname">SEMMNS</code></td><td>Maximum number of semaphores system-wide</td><td><code class="literal">ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17</code> plus room for other applications</td></tr><tr><td><code class="varname">SEMMSL</code></td><td>Maximum number of semaphores per set</td><td>at least 17</td></tr><tr><td><code class="varname">SEMMAP</code></td><td>Number of entries in semaphore map</td><td>see text</td></tr><tr><td><code class="varname">SEMVMX</code></td><td>Maximum value of semaphore</td><td>at least 1000 (The default is often 32767; do not change unless necessary)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <span class="productname">PostgreSQL</span> requires a few bytes of System V shared memory
+ (typically 48 bytes, on 64-bit platforms) for each copy of the server.
+ On most modern operating systems, this amount can easily be allocated.
+ However, if you are running many copies of the server or you explicitly
+ configure the server to use large amounts of System V shared memory (see
+ <a class="xref" href="runtime-config-resource.html#GUC-SHARED-MEMORY-TYPE">shared_memory_type</a> and <a class="xref" href="runtime-config-resource.html#GUC-DYNAMIC-SHARED-MEMORY-TYPE">dynamic_shared_memory_type</a>), it may be necessary to
+ increase <code class="varname">SHMALL</code>, which is the total amount of System V shared
+ memory system-wide. Note that <code class="varname">SHMALL</code> is measured in pages
+ rather than bytes on many systems.
+ </p><p>
+ Less likely to cause problems is the minimum size for shared
+ memory segments (<code class="varname">SHMMIN</code>), which should be at most
+ approximately 32 bytes for <span class="productname">PostgreSQL</span> (it is
+ usually just 1). The maximum number of segments system-wide
+ (<code class="varname">SHMMNI</code>) or per-process (<code class="varname">SHMSEG</code>) are unlikely
+ to cause a problem unless your system has them set to zero.
+ </p><p>
+ When using System V semaphores,
+ <span class="productname">PostgreSQL</span> uses one semaphore per allowed connection
+ (<a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>), allowed autovacuum worker process
+ (<a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS">autovacuum_max_workers</a>) and allowed background
+ process (<a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>), in sets of 16.
+ Each such set will
+ also contain a 17th semaphore which contains a <span class="quote">“<span class="quote">magic
+ number</span>”</span>, to detect collision with semaphore sets used by
+ other applications. The maximum number of semaphores in the system
+ is set by <code class="varname">SEMMNS</code>, which consequently must be at least
+ as high as <code class="varname">max_connections</code> plus
+ <code class="varname">autovacuum_max_workers</code> plus <code class="varname">max_wal_senders</code>,
+ plus <code class="varname">max_worker_processes</code>, plus one extra for each 16
+ allowed connections plus workers (see the formula in <a class="xref" href="kernel-resources.html#SYSVIPC-PARAMETERS" title="Table 19.1. System V IPC Parameters">Table 19.1</a>). The parameter <code class="varname">SEMMNI</code>
+ determines the limit on the number of semaphore sets that can
+ exist on the system at one time. Hence this parameter must be at
+ least <code class="literal">ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16)</code>.
+ Lowering the number
+ of allowed connections is a temporary workaround for failures,
+ which are usually confusingly worded <span class="quote">“<span class="quote">No space
+ left on device</span>”</span>, from the function <code class="function">semget</code>.
+ </p><p>
+ In some cases it might also be necessary to increase
+ <code class="varname">SEMMAP</code> to be at least on the order of
+ <code class="varname">SEMMNS</code>. If the system has this parameter
+ (many do not), it defines the size of the semaphore
+ resource map, in which each contiguous block of available semaphores
+ needs an entry. When a semaphore set is freed it is either added to
+ an existing entry that is adjacent to the freed block or it is
+ registered under a new map entry. If the map is full, the freed
+ semaphores get lost (until reboot). Fragmentation of the semaphore
+ space could over time lead to fewer available semaphores than there
+ should be.
+ </p><p>
+ Various other settings related to <span class="quote">“<span class="quote">semaphore undo</span>”</span>, such as
+ <code class="varname">SEMMNU</code> and <code class="varname">SEMUME</code>, do not affect
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ When using POSIX semaphores, the number of semaphores needed is the
+ same as for System V, that is one semaphore per allowed connection
+ (<a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>), allowed autovacuum worker process
+ (<a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS">autovacuum_max_workers</a>) and allowed background
+ process (<a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>).
+ On the platforms where this option is preferred, there is no specific
+ kernel limit on the number of POSIX semaphores.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><span class="systemitem">AIX</span>
+ <a id="id-1.6.6.7.3.14.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ It should not be necessary to do
+ any special configuration for such parameters as
+ <code class="varname">SHMMAX</code>, as it appears this is configured to
+ allow all memory to be used as shared memory. That is the
+ sort of configuration commonly used for other databases such
+ as <span class="application">DB/2</span>.</p><p> It might, however, be necessary to modify the global
+ <code class="command">ulimit</code> information in
+ <code class="filename">/etc/security/limits</code>, as the default hard
+ limits for file sizes (<code class="varname">fsize</code>) and numbers of
+ files (<code class="varname">nofiles</code>) might be too low.
+ </p></dd><dt><span class="term"><span class="systemitem">FreeBSD</span>
+ <a id="id-1.6.6.7.3.14.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The default shared memory settings are usually good enough, unless
+ you have set <code class="literal">shared_memory_type</code> to <code class="literal">sysv</code>.
+ System V semaphores are not used on this platform.
+ </p><p>
+ The default IPC settings can be changed using
+ the <code class="command">sysctl</code> or
+ <code class="command">loader</code> interfaces. The following
+ parameters can be set using <code class="command">sysctl</code>:
+</p><pre class="screen">
+<code class="prompt">#</code> <strong class="userinput"><code>sysctl kern.ipc.shmall=32768</code></strong>
+<code class="prompt">#</code> <strong class="userinput"><code>sysctl kern.ipc.shmmax=134217728</code></strong>
+</pre><p>
+ To make these settings persist over reboots, modify
+ <code class="filename">/etc/sysctl.conf</code>.
+ </p><p>
+ If you have set <code class="literal">shared_memory_type</code> to
+ <code class="literal">sysv</code>, you might also want to configure your kernel
+ to lock System V shared memory into RAM and prevent it from being paged
+ out to swap. This can be accomplished using the <code class="command">sysctl</code>
+ setting <code class="literal">kern.ipc.shm_use_phys</code>.
+ </p><p>
+ If running in a FreeBSD jail, you should set its
+ <code class="literal">sysvshm</code> parameter to <code class="literal">new</code>, so that
+ it has its own separate System V shared memory namespace.
+ (Before FreeBSD 11.0, it was necessary to enable shared access to
+ the host's IPC namespace from jails, and take measures to avoid
+ collisions.)
+ </p></dd><dt><span class="term"><span class="systemitem">NetBSD</span>
+ <a id="id-1.6.6.7.3.14.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The default shared memory settings are usually good enough, unless
+ you have set <code class="literal">shared_memory_type</code> to <code class="literal">sysv</code>.
+ You will usually want to increase <code class="literal">kern.ipc.semmni</code>
+ and <code class="literal">kern.ipc.semmns</code>,
+ as <span class="systemitem">NetBSD</span>'s default settings
+ for these are uncomfortably small.
+ </p><p>
+ IPC parameters can be adjusted using <code class="command">sysctl</code>,
+ for example:
+</p><pre class="screen">
+<code class="prompt">#</code> <strong class="userinput"><code>sysctl -w kern.ipc.semmni=100</code></strong>
+</pre><p>
+ To make these settings persist over reboots, modify
+ <code class="filename">/etc/sysctl.conf</code>.
+ </p><p>
+ If you have set <code class="literal">shared_memory_type</code> to
+ <code class="literal">sysv</code>, you might also want to configure your kernel
+ to lock System V shared memory into RAM and prevent it from being paged
+ out to swap. This can be accomplished using the <code class="command">sysctl</code>
+ setting <code class="literal">kern.ipc.shm_use_phys</code>.
+ </p></dd><dt><span class="term"><span class="systemitem">OpenBSD</span>
+ <a id="id-1.6.6.7.3.14.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The default shared memory settings are usually good enough, unless
+ you have set <code class="literal">shared_memory_type</code> to <code class="literal">sysv</code>.
+ You will usually want to
+ increase <code class="literal">kern.seminfo.semmni</code>
+ and <code class="literal">kern.seminfo.semmns</code>,
+ as <span class="systemitem">OpenBSD</span>'s default settings
+ for these are uncomfortably small.
+ </p><p>
+ IPC parameters can be adjusted using <code class="command">sysctl</code>,
+ for example:
+</p><pre class="screen">
+<code class="prompt">#</code> <strong class="userinput"><code>sysctl kern.seminfo.semmni=100</code></strong>
+</pre><p>
+ To make these settings persist over reboots, modify
+ <code class="filename">/etc/sysctl.conf</code>.
+ </p></dd><dt><span class="term"><span class="systemitem">HP-UX</span>
+ <a id="id-1.6.6.7.3.14.5.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The default settings tend to suffice for normal installations.
+ </p><p>
+ <acronym class="acronym">IPC</acronym> parameters can be set in the <span class="application">System
+ Administration Manager</span> (<acronym class="acronym">SAM</acronym>) under
+ <span class="guimenu">Kernel
+ Configuration</span> → <span class="guimenuitem">Configurable Parameters</span>. Choose
+ <span class="guibutton">Create A New Kernel</span> when you're done.
+ </p></dd><dt><span class="term"><span class="systemitem">Linux</span>
+ <a id="id-1.6.6.7.3.14.6.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The default shared memory settings are usually good enough, unless
+ you have set <code class="literal">shared_memory_type</code> to <code class="literal">sysv</code>,
+ and even then only on older kernel versions that shipped with low defaults.
+ System V semaphores are not used on this platform.
+ </p><p>
+ The shared memory size settings can be changed via the
+ <code class="command">sysctl</code> interface. For example, to allow 16 GB:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>sysctl -w kernel.shmmax=17179869184</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>sysctl -w kernel.shmall=4194304</code></strong>
+</pre><p>
+ To make these settings persist over reboots, see
+ <code class="filename">/etc/sysctl.conf</code>.
+ </p></dd><dt><span class="term"><span class="systemitem">macOS</span>
+ <a id="id-1.6.6.7.3.14.7.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The default shared memory and semaphore settings are usually good enough, unless
+ you have set <code class="literal">shared_memory_type</code> to <code class="literal">sysv</code>.
+ </p><p>
+ The recommended method for configuring shared memory in macOS
+ is to create a file named <code class="filename">/etc/sysctl.conf</code>,
+ containing variable assignments such as:
+</p><pre class="programlisting">
+kern.sysv.shmmax=4194304
+kern.sysv.shmmin=1
+kern.sysv.shmmni=32
+kern.sysv.shmseg=8
+kern.sysv.shmall=1024
+</pre><p>
+ Note that in some macOS versions,
+ <span class="emphasis"><em>all five</em></span> shared-memory parameters must be set in
+ <code class="filename">/etc/sysctl.conf</code>, else the values will be ignored.
+ </p><p>
+ <code class="varname">SHMMAX</code> can only be set to a multiple of 4096.
+ </p><p>
+ <code class="varname">SHMALL</code> is measured in 4 kB pages on this platform.
+ </p><p>
+ It is possible to change all but <code class="varname">SHMMNI</code> on the fly, using
+ <span class="application">sysctl</span>. But it's still best to set up your preferred
+ values via <code class="filename">/etc/sysctl.conf</code>, so that the values will be
+ kept across reboots.
+ </p></dd><dt><span class="term"><span class="systemitem">Solaris</span><br /></span><span class="term"><span class="systemitem">illumos</span></span></dt><dd><p>
+ The default shared memory and semaphore settings are usually good enough for most
+ <span class="productname">PostgreSQL</span> applications. Solaris defaults
+ to a <code class="varname">SHMMAX</code> of one-quarter of system <acronym class="acronym">RAM</acronym>.
+ To further adjust this setting, use a project setting associated
+ with the <code class="literal">postgres</code> user. For example, run the
+ following as <code class="literal">root</code>:
+</p><pre class="programlisting">
+projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres
+</pre><p>
+ </p><p>
+ This command adds the <code class="literal">user.postgres</code> project and
+ sets the shared memory maximum for the <code class="literal">postgres</code>
+ user to 8GB, and takes effect the next time that user logs
+ in, or when you restart <span class="productname">PostgreSQL</span> (not reload).
+ The above assumes that <span class="productname">PostgreSQL</span> is run by
+ the <code class="literal">postgres</code> user in the <code class="literal">postgres</code>
+ group. No server reboot is required.
+ </p><p>
+ Other recommended kernel setting changes for database servers which will
+ have a large number of connections are:
+</p><pre class="programlisting">
+project.max-shm-ids=(priv,32768,deny)
+project.max-sem-ids=(priv,4096,deny)
+project.max-msg-ids=(priv,4096,deny)
+</pre><p>
+ </p><p>
+ Additionally, if you are running <span class="productname">PostgreSQL</span>
+ inside a zone, you may need to raise the zone resource usage
+ limits as well. See "Chapter2: Projects and Tasks" in the
+ <em class="citetitle">System Administrator's Guide</em> for more
+ information on <code class="literal">projects</code> and <code class="command">prctl</code>.
+ </p></dd></dl></div></div><div class="sect2" id="SYSTEMD-REMOVEIPC"><div class="titlepage"><div><div><h3 class="title">19.4.2. systemd RemoveIPC</h3></div></div></div><a id="id-1.6.6.7.4.2" class="indexterm"></a><p>
+ If <span class="productname">systemd</span> is in use, some care must be taken
+ that IPC resources (including shared memory) are not prematurely
+ removed by the operating system. This is especially of concern when
+ installing PostgreSQL from source. Users of distribution packages of
+ PostgreSQL are less likely to be affected, as
+ the <code class="literal">postgres</code> user is then normally created as a system
+ user.
+ </p><p>
+ The setting <code class="literal">RemoveIPC</code>
+ in <code class="filename">logind.conf</code> controls whether IPC objects are
+ removed when a user fully logs out. System users are exempt. This
+ setting defaults to on in stock <span class="productname">systemd</span>, but
+ some operating system distributions default it to off.
+ </p><p>
+ A typical observed effect when this setting is on is that shared memory
+ objects used for parallel query execution are removed at apparently random
+ times, leading to errors and warnings while attempting to open and remove
+ them, like
+</p><pre class="screen">
+WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory
+</pre><p>
+ Different types of IPC objects (shared memory vs. semaphores, System V
+ vs. POSIX) are treated slightly differently
+ by <span class="productname">systemd</span>, so one might observe that some IPC
+ resources are not removed in the same way as others. But it is not
+ advisable to rely on these subtle differences.
+ </p><p>
+ A <span class="quote">“<span class="quote">user logging out</span>”</span> might happen as part of a maintenance
+ job or manually when an administrator logs in as
+ the <code class="literal">postgres</code> user or something similar, so it is hard
+ to prevent in general.
+ </p><p>
+ What is a <span class="quote">“<span class="quote">system user</span>”</span> is determined
+ at <span class="productname">systemd</span> compile time from
+ the <code class="symbol">SYS_UID_MAX</code> setting
+ in <code class="filename">/etc/login.defs</code>.
+ </p><p>
+ Packaging and deployment scripts should be careful to create
+ the <code class="literal">postgres</code> user as a system user by
+ using <code class="literal">useradd -r</code>, <code class="literal">adduser --system</code>,
+ or equivalent.
+ </p><p>
+ Alternatively, if the user account was created incorrectly or cannot be
+ changed, it is recommended to set
+</p><pre class="programlisting">
+RemoveIPC=no
+</pre><p>
+ in <code class="filename">/etc/systemd/logind.conf</code> or another appropriate
+ configuration file.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ At least one of these two things has to be ensured, or the PostgreSQL
+ server will be very unreliable.
+ </p></div></div><div class="sect2" id="id-1.6.6.7.5"><div class="titlepage"><div><div><h3 class="title">19.4.3. Resource Limits</h3></div></div></div><p>
+ Unix-like operating systems enforce various kinds of resource limits
+ that might interfere with the operation of your
+ <span class="productname">PostgreSQL</span> server. Of particular
+ importance are limits on the number of processes per user, the
+ number of open files per process, and the amount of memory available
+ to each process. Each of these have a <span class="quote">“<span class="quote">hard</span>”</span> and a
+ <span class="quote">“<span class="quote">soft</span>”</span> limit. The soft limit is what actually counts
+ but it can be changed by the user up to the hard limit. The hard
+ limit can only be changed by the root user. The system call
+ <code class="function">setrlimit</code> is responsible for setting these
+ parameters. The shell's built-in command <code class="command">ulimit</code>
+ (Bourne shells) or <code class="command">limit</code> (<span class="application">csh</span>) is
+ used to control the resource limits from the command line. On
+ BSD-derived systems the file <code class="filename">/etc/login.conf</code>
+ controls the various resource limits set during login. See the
+ operating system documentation for details. The relevant
+ parameters are <code class="varname">maxproc</code>,
+ <code class="varname">openfiles</code>, and <code class="varname">datasize</code>. For
+ example:
+</p><pre class="programlisting">
+default:\
+...
+ :datasize-cur=256M:\
+ :maxproc-cur=256:\
+ :openfiles-cur=256:\
+...
+</pre><p>
+ (<code class="literal">-cur</code> is the soft limit. Append
+ <code class="literal">-max</code> to set the hard limit.)
+ </p><p>
+ Kernels can also have system-wide limits on some resources.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ On <span class="productname">Linux</span> the kernel parameter
+ <code class="varname">fs.file-max</code> determines the maximum number of open
+ files that the kernel will support. It can be changed with
+ <code class="literal">sysctl -w fs.file-max=<em class="replaceable"><code>N</code></em></code>.
+ To make the setting persist across reboots, add an assignment
+ in <code class="filename">/etc/sysctl.conf</code>.
+ The maximum limit of files per process is fixed at the time the
+ kernel is compiled; see
+ <code class="filename">/usr/src/linux/Documentation/proc.txt</code> for
+ more information.
+ </p></li></ul></div><p>
+ </p><p>
+ The <span class="productname">PostgreSQL</span> server uses one process
+ per connection so you should provide for at least as many processes
+ as allowed connections, in addition to what you need for the rest
+ of your system. This is usually not a problem but if you run
+ several servers on one machine things might get tight.
+ </p><p>
+ The factory default limit on open files is often set to
+ <span class="quote">“<span class="quote">socially friendly</span>”</span> values that allow many users to
+ coexist on a machine without using an inappropriate fraction of
+ the system resources. If you run many servers on a machine this
+ is perhaps what you want, but on dedicated servers you might want to
+ raise this limit.
+ </p><p>
+ On the other side of the coin, some systems allow individual
+ processes to open large numbers of files; if more than a few
+ processes do so then the system-wide limit can easily be exceeded.
+ If you find this happening, and you do not want to alter the
+ system-wide limit, you can set <span class="productname">PostgreSQL</span>'s <a class="xref" href="runtime-config-resource.html#GUC-MAX-FILES-PER-PROCESS">max_files_per_process</a> configuration parameter to
+ limit the consumption of open files.
+ </p><p>
+ Another kernel limit that may be of concern when supporting large
+ numbers of client connections is the maximum socket connection queue
+ length. If more than that many connection requests arrive within a very
+ short period, some may get rejected before the postmaster can service
+ the requests, with those clients receiving unhelpful connection failure
+ errors such as <span class="quote">“<span class="quote">Resource temporarily unavailable</span>”</span> or
+ <span class="quote">“<span class="quote">Connection refused</span>”</span>. The default queue length limit is 128
+ on many platforms. To raise it, adjust the appropriate kernel parameter
+ via <span class="application">sysctl</span>, then restart the postmaster.
+ The parameter is variously named <code class="varname">net.core.somaxconn</code>
+ on Linux, <code class="varname">kern.ipc.soacceptqueue</code> on newer FreeBSD,
+ and <code class="varname">kern.ipc.somaxconn</code> on macOS and other BSD
+ variants.
+ </p></div><div class="sect2" id="LINUX-MEMORY-OVERCOMMIT"><div class="titlepage"><div><div><h3 class="title">19.4.4. Linux Memory Overcommit</h3></div></div></div><a id="id-1.6.6.7.6.2" class="indexterm"></a><a id="id-1.6.6.7.6.3" class="indexterm"></a><a id="id-1.6.6.7.6.4" class="indexterm"></a><p>
+ The default virtual memory behavior on Linux is not
+ optimal for <span class="productname">PostgreSQL</span>. Because of the
+ way that the kernel implements memory overcommit, the kernel might
+ terminate the <span class="productname">PostgreSQL</span> postmaster (the
+ supervisor server process) if the memory demands of either
+ <span class="productname">PostgreSQL</span> or another process cause the
+ system to run out of virtual memory.
+ </p><p>
+ If this happens, you will see a kernel message that looks like
+ this (consult your system documentation and configuration on where
+ to look for such a message):
+</p><pre class="programlisting">
+Out of Memory: Killed process 12345 (postgres).
+</pre><p>
+ This indicates that the <code class="filename">postgres</code> process
+ has been terminated due to memory pressure.
+ Although existing database connections will continue to function
+ normally, no new connections will be accepted. To recover,
+ <span class="productname">PostgreSQL</span> will need to be restarted.
+ </p><p>
+ One way to avoid this problem is to run
+ <span class="productname">PostgreSQL</span> on a machine where you can
+ be sure that other processes will not run the machine out of
+ memory. If memory is tight, increasing the swap space of the
+ operating system can help avoid the problem, because the
+ out-of-memory (OOM) killer is invoked only when physical memory and
+ swap space are exhausted.
+ </p><p>
+ If <span class="productname">PostgreSQL</span> itself is the cause of the
+ system running out of memory, you can avoid the problem by changing
+ your configuration. In some cases, it may help to lower memory-related
+ configuration parameters, particularly
+ <a class="link" href="runtime-config-resource.html#GUC-SHARED-BUFFERS"><code class="varname">shared_buffers</code></a>,
+ <a class="link" href="runtime-config-resource.html#GUC-WORK-MEM"><code class="varname">work_mem</code></a>, and
+ <a class="link" href="runtime-config-resource.html#GUC-HASH-MEM-MULTIPLIER"><code class="varname">hash_mem_multiplier</code></a>.
+ In other cases, the problem may be caused by allowing too many
+ connections to the database server itself. In many cases, it may
+ be better to reduce
+ <a class="link" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS"><code class="varname">max_connections</code></a>
+ and instead make use of external connection-pooling software.
+ </p><p>
+ It is possible to modify the
+ kernel's behavior so that it will not <span class="quote">“<span class="quote">overcommit</span>”</span> memory.
+ Although this setting will not prevent the <a class="ulink" href="https://lwn.net/Articles/104179/" target="_top">OOM killer</a> from being invoked
+ altogether, it will lower the chances significantly and will therefore
+ lead to more robust system behavior. This is done by selecting strict
+ overcommit mode via <code class="command">sysctl</code>:
+</p><pre class="programlisting">
+sysctl -w vm.overcommit_memory=2
+</pre><p>
+ or placing an equivalent entry in <code class="filename">/etc/sysctl.conf</code>.
+ You might also wish to modify the related setting
+ <code class="varname">vm.overcommit_ratio</code>. For details see the kernel documentation
+ file <a class="ulink" href="https://www.kernel.org/doc/Documentation/vm/overcommit-accounting" target="_top">https://www.kernel.org/doc/Documentation/vm/overcommit-accounting</a>.
+ </p><p>
+ Another approach, which can be used with or without altering
+ <code class="varname">vm.overcommit_memory</code>, is to set the process-specific
+ <em class="firstterm">OOM score adjustment</em> value for the postmaster process to
+ <code class="literal">-1000</code>, thereby guaranteeing it will not be targeted by the OOM
+ killer. The simplest way to do this is to execute
+</p><pre class="programlisting">
+echo -1000 &gt; /proc/self/oom_score_adj
+</pre><p>
+ in the postmaster's startup script just before invoking the postmaster.
+ Note that this action must be done as root, or it will have no effect;
+ so a root-owned startup script is the easiest place to do it. If you
+ do this, you should also set these environment variables in the startup
+ script before invoking the postmaster:
+</p><pre class="programlisting">
+export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
+export PG_OOM_ADJUST_VALUE=0
+</pre><p>
+ These settings will cause postmaster child processes to run with the
+ normal OOM score adjustment of zero, so that the OOM killer can still
+ target them at need. You could use some other value for
+ <code class="envar">PG_OOM_ADJUST_VALUE</code> if you want the child processes to run
+ with some other OOM score adjustment. (<code class="envar">PG_OOM_ADJUST_VALUE</code>
+ can also be omitted, in which case it defaults to zero.) If you do not
+ set <code class="envar">PG_OOM_ADJUST_FILE</code>, the child processes will run with the
+ same OOM score adjustment as the postmaster, which is unwise since the
+ whole point is to ensure that the postmaster has a preferential setting.
+ </p></div><div class="sect2" id="LINUX-HUGE-PAGES"><div class="titlepage"><div><div><h3 class="title">19.4.5. Linux Huge Pages</h3></div></div></div><p>
+ Using huge pages reduces overhead when using large contiguous chunks of
+ memory, as <span class="productname">PostgreSQL</span> does, particularly when
+ using large values of <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>. To use this
+ feature in <span class="productname">PostgreSQL</span> you need a kernel
+ with <code class="varname">CONFIG_HUGETLBFS=y</code> and
+ <code class="varname">CONFIG_HUGETLB_PAGE=y</code>. You will also have to configure
+ the operating system to provide enough huge pages of the desired size.
+ To determine the number of huge pages needed, use the
+ <code class="command">postgres</code> command to see the value of
+ <a class="xref" href="runtime-config-preset.html#GUC-SHARED-MEMORY-SIZE-IN-HUGE-PAGES">shared_memory_size_in_huge_pages</a>. Note that the
+ server must be shut down to view this runtime-computed parameter.
+ This might look like:
+</p><pre class="programlisting">
+$ <strong class="userinput"><code>postgres -D $PGDATA -C shared_memory_size_in_huge_pages</code></strong>
+3170
+$ <strong class="userinput"><code>grep ^Hugepagesize /proc/meminfo</code></strong>
+Hugepagesize: 2048 kB
+$ <strong class="userinput"><code>ls /sys/kernel/mm/hugepages</code></strong>
+hugepages-1048576kB hugepages-2048kB
+</pre><p>
+
+ In this example the default is 2MB, but you can also explicitly request
+ either 2MB or 1GB with <a class="xref" href="runtime-config-resource.html#GUC-HUGE-PAGE-SIZE">huge_page_size</a> to adapt
+ the number of pages calculated by
+ <code class="varname">shared_memory_size_in_huge_pages</code>.
+
+ While we need at least <code class="literal">3170</code> huge pages in this example,
+ a larger setting would be appropriate if other programs on the machine
+ also need huge pages.
+ We can set this with:
+</p><pre class="programlisting">
+# <strong class="userinput"><code>sysctl -w vm.nr_hugepages=3170</code></strong>
+</pre><p>
+ Don't forget to add this setting to <code class="filename">/etc/sysctl.conf</code>
+ so that it is reapplied after reboots. For non-default huge page sizes,
+ we can instead use:
+</p><pre class="programlisting">
+# <strong class="userinput"><code>echo 3170 &gt; /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages</code></strong>
+</pre><p>
+ It is also possible to provide these settings at boot time using
+ kernel parameters such as <code class="literal">hugepagesz=2M hugepages=3170</code>.
+ </p><p>
+ Sometimes the kernel is not able to allocate the desired number of huge
+ pages immediately due to fragmentation, so it might be necessary
+ to repeat the command or to reboot. (Immediately after a reboot, most of
+ the machine's memory should be available to convert into huge pages.)
+ To verify the huge page allocation situation for a given size, use:
+</p><pre class="programlisting">
+$ <strong class="userinput"><code>cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages</code></strong>
+</pre><p>
+ </p><p>
+ It may also be necessary to give the database server's operating system
+ user permission to use huge pages by setting
+ <code class="varname">vm.hugetlb_shm_group</code> via <span class="application">sysctl</span>, and/or
+ give permission to lock memory with <code class="command">ulimit -l</code>.
+ </p><p>
+ The default behavior for huge pages in
+ <span class="productname">PostgreSQL</span> is to use them when possible, with
+ the system's default huge page size, and
+ to fall back to normal pages on failure. To enforce the use of huge
+ pages, you can set <a class="xref" href="runtime-config-resource.html#GUC-HUGE-PAGES">huge_pages</a>
+ to <code class="literal">on</code> in <code class="filename">postgresql.conf</code>.
+ Note that with this setting <span class="productname">PostgreSQL</span> will fail to
+ start if not enough huge pages are available.
+ </p><p>
+ For a detailed description of the <span class="productname">Linux</span> huge
+ pages feature have a look
+ at <a class="ulink" href="https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt" target="_top">https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="server-start.html" title="19.3. Starting the Database Server">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="server-shutdown.html" title="19.5. Shutting Down the Server">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.3. Starting the Database Server </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.5. Shutting Down the Server</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/largeobjects.html b/doc/src/sgml/html/largeobjects.html
new file mode 100644
index 0000000..0218a9e
--- /dev/null
+++ b/doc/src/sgml/html/largeobjects.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 35. Large Objects</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-example.html" title="34.22. Example Programs" /><link rel="next" href="lo-intro.html" title="35.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 35. Large Objects</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-example.html" title="34.22. Example Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><th width="60%" align="center">Part IV. Client Interfaces</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="lo-intro.html" title="35.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="LARGEOBJECTS"><div class="titlepage"><div><div><h2 class="title">Chapter 35. Large Objects</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="lo-intro.html">35.1. Introduction</a></span></dt><dt><span class="sect1"><a href="lo-implementation.html">35.2. Implementation Features</a></span></dt><dt><span class="sect1"><a href="lo-interfaces.html">35.3. Client Interfaces</a></span></dt><dd><dl><dt><span class="sect2"><a href="lo-interfaces.html#LO-CREATE">35.3.1. Creating a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-IMPORT">35.3.2. Importing a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-EXPORT">35.3.3. Exporting a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-OPEN">35.3.4. Opening an Existing Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-WRITE">35.3.5. Writing Data to a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-READ">35.3.6. Reading Data from a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-SEEK">35.3.7. Seeking in a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-TELL">35.3.8. Obtaining the Seek Position of a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-TRUNCATE">35.3.9. Truncating a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-CLOSE">35.3.10. Closing a Large Object Descriptor</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-UNLINK">35.3.11. Removing a Large Object</a></span></dt></dl></dd><dt><span class="sect1"><a href="lo-funcs.html">35.4. Server-Side Functions</a></span></dt><dt><span class="sect1"><a href="lo-examplesect.html">35.5. Example Program</a></span></dt></dl></div><a id="id-1.7.4.2" class="indexterm"></a><a id="id-1.7.4.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> has a <em class="firstterm">large object</em>
+ facility, which provides stream-style access to user data that is stored
+ in a special large-object structure. Streaming access is useful
+ when working with data values that are too large to manipulate
+ conveniently as a whole.
+ </p><p>
+ This chapter describes the implementation and the programming and
+ query language interfaces to <span class="productname">PostgreSQL</span>
+ large object data. We use the <span class="application">libpq</span> C
+ library for the examples in this chapter, but most programming
+ interfaces native to <span class="productname">PostgreSQL</span> support
+ equivalent functionality. Other interfaces might use the large
+ object interface internally to provide generic support for large
+ values. This is not described here.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-example.html" title="34.22. Example Programs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="lo-intro.html" title="35.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.22. Example Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 35.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/legalnotice.html b/doc/src/sgml/html/legalnotice.html
new file mode 100644
index 0000000..8fec481
--- /dev/null
+++ b/doc/src/sgml/html/legalnotice.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Legal Notice</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /></head><body id="docContent" class="container-fluid col-10"><div class="legalnotice" id="LEGALNOTICE"><p class="legalnotice-title"><strong>Legal Notice</strong></p><p>
+ <span class="productname">PostgreSQL</span> is Copyright © 1996–2023
+ by the PostgreSQL Global Development Group.
+ </p><p>
+ <span class="productname">Postgres95</span> is Copyright © 1994–5
+ by the Regents of the University of California.
+ </p><p>
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose, without fee, and without a
+ written agreement is hereby granted, provided that the above
+ copyright notice and this paragraph and the following two paragraphs
+ appear in all copies.
+ </p><p>
+ IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
+ PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS
+ SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
+ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ </p><p>
+ THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+ PROVIDED HEREUNDER IS ON AN <span class="quote">“<span class="quote">AS-IS</span>”</span> BASIS, AND THE UNIVERSITY OF
+ CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
+ UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ </p></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-async.html b/doc/src/sgml/html/libpq-async.html
new file mode 100644
index 0000000..3d06a03
--- /dev/null
+++ b/doc/src/sgml/html/libpq-async.html
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.4. Asynchronous Command Processing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-exec.html" title="34.3. Command Execution Functions" /><link rel="next" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.4. Asynchronous Command Processing</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-exec.html" title="34.3. Command Execution Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-ASYNC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.4. Asynchronous Command Processing</h2></div></div></div><a id="id-1.7.3.11.2" class="indexterm"></a><p>
+ The <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> function is adequate for submitting
+ commands in normal, synchronous applications. It has a few
+ deficiencies, however, that can be of importance to some users:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> waits for the command to be completed.
+ The application might have other work to do (such as maintaining a
+ user interface), in which case it won't want to block waiting for
+ the response.
+ </p></li><li class="listitem"><p>
+ Since the execution of the client application is suspended while it
+ waits for the result, it is hard for the application to decide that
+ it would like to try to cancel the ongoing command. (It can be done
+ from a signal handler, but not otherwise.)
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> can return only one
+ <code class="structname">PGresult</code> structure. If the submitted command
+ string contains multiple <acronym class="acronym">SQL</acronym> commands, all but
+ the last <code class="structname">PGresult</code> are discarded by
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> always collects the command's entire result,
+ buffering it in a single <code class="structname">PGresult</code>. While
+ this simplifies error-handling logic for the application, it can be
+ impractical for results containing many rows.
+ </p></li></ul></div><p>
+ </p><p>
+ Applications that do not like these limitations can instead use the
+ underlying functions that <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> is built from:
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> and <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>.
+ There are also
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPARAMS"><code class="function">PQsendQueryParams</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDPREPARE"><code class="function">PQsendPrepare</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPREPARED"><code class="function">PQsendQueryPrepared</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDDESCRIBEPREPARED"><code class="function">PQsendDescribePrepared</code></a>, and
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDDESCRIBEPORTAL"><code class="function">PQsendDescribePortal</code></a>,
+ which can be used with <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to duplicate
+ the functionality of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQPREPARE"><code class="function">PQprepare</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPREPARED"><code class="function">PQexecPrepared</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a>, and
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPORTAL"><code class="function">PQdescribePortal</code></a>
+ respectively.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQSENDQUERY"><span class="term"><code class="function">PQsendQuery</code><a id="id-1.7.3.11.4.15.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a command to the server without waiting for the result(s).
+ 1 is returned if the command was successfully dispatched and 0 if
+ not (in which case, use <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to get more
+ information about the failure).
+</p><pre class="synopsis">
+int PQsendQuery(PGconn *conn, const char *command);
+</pre><p>
+
+ After successfully calling <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a>, call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> one or more times to obtain the
+ results. <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> cannot be called again
+ (on the same connection) until <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>
+ has returned a null pointer, indicating that the command is done.
+ </p><p>
+ In pipeline mode, this function is disallowed.
+ </p></dd><dt id="LIBPQ-PQSENDQUERYPARAMS"><span class="term"><code class="function">PQsendQueryParams</code><a id="id-1.7.3.11.4.15.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a command and separate parameters to the server without
+ waiting for the result(s).
+</p><pre class="synopsis">
+int PQsendQueryParams(PGconn *conn,
+ const char *command,
+ int nParams,
+ const Oid *paramTypes,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</pre><p>
+
+ This is equivalent to <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> except that
+ query parameters can be specified separately from the query string.
+ The function's parameters are handled identically to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a>. Like
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a>, it allows only one command in the
+ query string.
+ </p></dd><dt id="LIBPQ-PQSENDPREPARE"><span class="term"><code class="function">PQsendPrepare</code><a id="id-1.7.3.11.4.15.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends a request to create a prepared statement with the given
+ parameters, without waiting for completion.
+</p><pre class="synopsis">
+int PQsendPrepare(PGconn *conn,
+ const char *stmtName,
+ const char *query,
+ int nParams,
+ const Oid *paramTypes);
+</pre><p>
+
+ This is an asynchronous version of <a class="xref" href="libpq-exec.html#LIBPQ-PQPREPARE"><code class="function">PQprepare</code></a>: it
+ returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to
+ determine whether the server successfully created the prepared
+ statement. The function's parameters are handled identically to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQPREPARE"><code class="function">PQprepare</code></a>.
+ </p></dd><dt id="LIBPQ-PQSENDQUERYPREPARED"><span class="term"><code class="function">PQsendQueryPrepared</code><a id="id-1.7.3.11.4.15.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends a request to execute a prepared statement with given
+ parameters, without waiting for the result(s).
+</p><pre class="synopsis">
+int PQsendQueryPrepared(PGconn *conn,
+ const char *stmtName,
+ int nParams,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</pre><p>
+
+ This is similar to <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPARAMS"><code class="function">PQsendQueryParams</code></a>, but
+ the command to be executed is specified by naming a
+ previously-prepared statement, instead of giving a query string.
+ The function's parameters are handled identically to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPREPARED"><code class="function">PQexecPrepared</code></a>.
+ </p></dd><dt id="LIBPQ-PQSENDDESCRIBEPREPARED"><span class="term"><code class="function">PQsendDescribePrepared</code><a id="id-1.7.3.11.4.15.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a request to obtain information about the specified
+ prepared statement, without waiting for completion.
+</p><pre class="synopsis">
+int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
+</pre><p>
+
+ This is an asynchronous version of <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a>:
+ it returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to
+ obtain the results. The function's parameters are handled
+ identically to <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a>.
+ </p></dd><dt id="LIBPQ-PQSENDDESCRIBEPORTAL"><span class="term"><code class="function">PQsendDescribePortal</code><a id="id-1.7.3.11.4.15.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a request to obtain information about the specified
+ portal, without waiting for completion.
+</p><pre class="synopsis">
+int PQsendDescribePortal(PGconn *conn, const char *portalName);
+</pre><p>
+
+ This is an asynchronous version of <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPORTAL"><code class="function">PQdescribePortal</code></a>:
+ it returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to
+ obtain the results. The function's parameters are handled
+ identically to <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPORTAL"><code class="function">PQdescribePortal</code></a>.
+ </p></dd><dt id="LIBPQ-PQGETRESULT"><span class="term"><code class="function">PQgetResult</code><a id="id-1.7.3.11.4.15.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Waits for the next result from a prior
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPARAMS"><code class="function">PQsendQueryParams</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDPREPARE"><code class="function">PQsendPrepare</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPREPARED"><code class="function">PQsendQueryPrepared</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDDESCRIBEPREPARED"><code class="function">PQsendDescribePrepared</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDDESCRIBEPORTAL"><code class="function">PQsendDescribePortal</code></a>, or
+ <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PQPIPELINESYNC"><code class="function">PQpipelineSync</code></a>
+ call, and returns it.
+ A null pointer is returned when the command is complete and there
+ will be no more results.
+</p><pre class="synopsis">
+PGresult *PQgetResult(PGconn *conn);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> must be called repeatedly until
+ it returns a null pointer, indicating that the command is done.
+ (If called when no command is active,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> will just return a null pointer
+ at once.) Each non-null result from
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> should be processed using the
+ same <code class="structname">PGresult</code> accessor functions previously
+ described. Don't forget to free each result object with
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> when done with it. Note that
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> will block only if a command is
+ active and the necessary response data has not yet been read by
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a>.
+ </p><p>
+ In pipeline mode, <code class="function">PQgetResult</code> will return normally
+ unless an error occurs; for any subsequent query sent after the one
+ that caused the error until (and excluding) the next synchronization point,
+ a special result of type <code class="literal">PGRES_PIPELINE_ABORTED</code> will
+ be returned, and a null pointer will be returned after it.
+ When the pipeline synchronization point is reached, a result of type
+ <code class="literal">PGRES_PIPELINE_SYNC</code> will be returned.
+ The result of the next query after the synchronization point follows
+ immediately (that is, no null pointer is returned after
+ the synchronization point.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Even when <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTSTATUS"><code class="function">PQresultStatus</code></a> indicates a fatal
+ error, <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> should be called until it
+ returns a null pointer, to allow <span class="application">libpq</span> to
+ process the error information completely.
+ </p></div></dd></dl></div><p>
+ </p><p>
+ Using <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> and
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> solves one of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>'s problems: If a command string contains
+ multiple <acronym class="acronym">SQL</acronym> commands, the results of those commands
+ can be obtained individually. (This allows a simple form of overlapped
+ processing, by the way: the client can be handling the results of one
+ command while the server is still working on later queries in the same
+ command string.)
+ </p><p>
+ Another frequently-desired feature that can be obtained with
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> and <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>
+ is retrieving large query results a row at a time. This is discussed
+ in <a class="xref" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Section 34.6</a>.
+ </p><p>
+ By itself, calling <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>
+ will still cause the client to block until the server completes the
+ next <acronym class="acronym">SQL</acronym> command. This can be avoided by proper
+ use of two more functions:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQCONSUMEINPUT"><span class="term"><code class="function">PQconsumeInput</code><a id="id-1.7.3.11.7.3.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ If input is available from the server, consume it.
+</p><pre class="synopsis">
+int PQconsumeInput(PGconn *conn);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> normally returns 1 indicating
+ <span class="quote">“<span class="quote">no error</span>”</span>, but returns 0 if there was some kind of
+ trouble (in which case <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> can be
+ consulted). Note that the result does not say whether any input
+ data was actually collected. After calling
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a>, the application can check
+ <a class="xref" href="libpq-async.html#LIBPQ-PQISBUSY"><code class="function">PQisBusy</code></a> and/or
+ <code class="function">PQnotifies</code> to see if their state has changed.
+ </p><p>
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> can be called even if the
+ application is not prepared to deal with a result or notification
+ just yet. The function will read available data and save it in
+ a buffer, thereby causing a <code class="function">select()</code>
+ read-ready indication to go away. The application can thus use
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> to clear the
+ <code class="function">select()</code> condition immediately, and then
+ examine the results at leisure.
+ </p></dd><dt id="LIBPQ-PQISBUSY"><span class="term"><code class="function">PQisBusy</code><a id="id-1.7.3.11.7.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns 1 if a command is busy, that is,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> would block waiting for input.
+ A 0 return indicates that <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> can be
+ called with assurance of not blocking.
+</p><pre class="synopsis">
+int PQisBusy(PGconn *conn);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-async.html#LIBPQ-PQISBUSY"><code class="function">PQisBusy</code></a> will not itself attempt to read data
+ from the server; therefore <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a>
+ must be invoked first, or the busy state will never end.
+ </p></dd></dl></div><p>
+ </p><p>
+ A typical application using these functions will have a main loop that
+ uses <code class="function">select()</code> or <code class="function">poll()</code> to wait for
+ all the conditions that it must respond to. One of the conditions
+ will be input available from the server, which in terms of
+ <code class="function">select()</code> means readable data on the file
+ descriptor identified by <a class="xref" href="libpq-status.html#LIBPQ-PQSOCKET"><code class="function">PQsocket</code></a>. When the main
+ loop detects input ready, it should call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> to read the input. It can then
+ call <a class="xref" href="libpq-async.html#LIBPQ-PQISBUSY"><code class="function">PQisBusy</code></a>, followed by
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> if <a class="xref" href="libpq-async.html#LIBPQ-PQISBUSY"><code class="function">PQisBusy</code></a>
+ returns false (0). It can also call <code class="function">PQnotifies</code>
+ to detect <code class="command">NOTIFY</code> messages (see <a class="xref" href="libpq-notify.html" title="34.9. Asynchronous Notification">Section 34.9</a>).
+ </p><p>
+ A client that uses
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a>/<a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>
+ can also attempt to cancel a command that is still being processed
+ by the server; see <a class="xref" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress">Section 34.7</a>. But regardless of
+ the return value of <a class="xref" href="libpq-cancel.html#LIBPQ-PQCANCEL"><code class="function">PQcancel</code></a>, the application
+ must continue with the normal result-reading sequence using
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>. A successful cancellation will
+ simply cause the command to terminate sooner than it would have
+ otherwise.
+ </p><p>
+ By using the functions described above, it is possible to avoid
+ blocking while waiting for input from the database server. However,
+ it is still possible that the application will block waiting to send
+ output to the server. This is relatively uncommon but can happen if
+ very long SQL commands or data values are sent. (It is much more
+ probable if the application sends data via <code class="command">COPY IN</code>,
+ however.) To prevent this possibility and achieve completely
+ nonblocking database operation, the following additional functions
+ can be used.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQSETNONBLOCKING"><span class="term"><code class="function">PQsetnonblocking</code><a id="id-1.7.3.11.10.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sets the nonblocking status of the connection.
+</p><pre class="synopsis">
+int PQsetnonblocking(PGconn *conn, int arg);
+</pre><p>
+ </p><p>
+ Sets the state of the connection to nonblocking if
+ <em class="parameter"><code>arg</code></em> is 1, or blocking if
+ <em class="parameter"><code>arg</code></em> is 0. Returns 0 if OK, -1 if error.
+ </p><p>
+ In the nonblocking state, calls to
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a>, <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a>,
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTNBYTES"><code class="function">PQputnbytes</code></a>, <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTCOPYDATA"><code class="function">PQputCopyData</code></a>,
+ and <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a> will not block but instead return
+ an error if they need to be called again.
+ </p><p>
+ Note that <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> does not honor nonblocking
+ mode; if it is called, it will act in blocking fashion anyway.
+ </p></dd><dt id="LIBPQ-PQISNONBLOCKING"><span class="term"><code class="function">PQisnonblocking</code><a id="id-1.7.3.11.10.2.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the blocking status of the database connection.
+</p><pre class="synopsis">
+int PQisnonblocking(const PGconn *conn);
+</pre><p>
+ </p><p>
+ Returns 1 if the connection is set to nonblocking mode and 0 if
+ blocking.
+ </p></dd><dt id="LIBPQ-PQFLUSH"><span class="term"><code class="function">PQflush</code><a id="id-1.7.3.11.10.2.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Attempts to flush any queued output data to the server. Returns
+ 0 if successful (or if the send queue is empty), -1 if it failed
+ for some reason, or 1 if it was unable to send all the data in
+ the send queue yet (this case can only occur if the connection
+ is nonblocking).
+</p><pre class="synopsis">
+int PQflush(PGconn *conn);
+</pre><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ After sending any command or data on a nonblocking connection, call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a>. If it returns 1, wait for the socket
+ to become read- or write-ready. If it becomes write-ready, call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a> again. If it becomes read-ready, call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a>, then call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a> again. Repeat until
+ <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a> returns 0. (It is necessary to check for
+ read-ready and drain the input with <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a>,
+ because the server can block trying to send us data, e.g., NOTICE
+ messages, and won't read our data until we read its.) Once
+ <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a> returns 0, wait for the socket to be
+ read-ready and then read the response as described above.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-exec.html" title="34.3. Command Execution Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.3. Command Execution Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.5. Pipeline Mode</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-build.html b/doc/src/sgml/html/libpq-build.html
new file mode 100644
index 0000000..0262280
--- /dev/null
+++ b/doc/src/sgml/html/libpq-build.html
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.21. Building libpq Programs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-threading.html" title="34.20. Behavior in Threaded Programs" /><link rel="next" href="libpq-example.html" title="34.22. Example Programs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.21. Building <span class="application">libpq</span> Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-threading.html" title="34.20. Behavior in Threaded Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-example.html" title="34.22. Example Programs">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-BUILD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.21. Building <span class="application">libpq</span> Programs</h2></div></div></div><a id="id-1.7.3.28.2" class="indexterm"></a><p>
+ To build (i.e., compile and link) a program using
+ <span class="application">libpq</span> you need to do all of the following
+ things:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Include the <code class="filename">libpq-fe.h</code> header file:
+</p><pre class="programlisting">
+#include &lt;libpq-fe.h&gt;
+</pre><p>
+ If you failed to do that then you will normally get error messages
+ from your compiler similar to:
+</p><pre class="screen">
+foo.c: In function `main':
+foo.c:34: `PGconn' undeclared (first use in this function)
+foo.c:35: `PGresult' undeclared (first use in this function)
+foo.c:54: `CONNECTION_BAD' undeclared (first use in this function)
+foo.c:68: `PGRES_COMMAND_OK' undeclared (first use in this function)
+foo.c:95: `PGRES_TUPLES_OK' undeclared (first use in this function)
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Point your compiler to the directory where the <span class="productname">PostgreSQL</span> header
+ files were installed, by supplying the
+ <code class="literal">-I<em class="replaceable"><code>directory</code></em></code> option
+ to your compiler. (In some cases the compiler will look into
+ the directory in question by default, so you can omit this
+ option.) For instance, your compile command line could look
+ like:
+</p><pre class="programlisting">
+cc -c -I/usr/local/pgsql/include testprog.c
+</pre><p>
+ If you are using makefiles then add the option to the
+ <code class="varname">CPPFLAGS</code> variable:
+</p><pre class="programlisting">
+CPPFLAGS += -I/usr/local/pgsql/include
+</pre><p>
+ </p><p>
+ If there is any chance that your program might be compiled by
+ other users then you should not hardcode the directory location
+ like that. Instead, you can run the utility
+ <code class="command">pg_config</code><a id="id-1.7.3.28.3.2.2.2.2" class="indexterm"></a> to find out where the header
+ files are on the local system:
+</p><pre class="screen">
+<code class="prompt">$</code> pg_config --includedir
+<code class="computeroutput">/usr/local/include</code>
+</pre><p>
+ </p><p>
+ If you
+ have <code class="command">pkg-config</code><a id="id-1.7.3.28.3.2.2.3.2" class="indexterm"></a> installed, you can run instead:
+</p><pre class="screen">
+<code class="prompt">$</code> pkg-config --cflags libpq
+<code class="computeroutput">-I/usr/local/include</code>
+</pre><p>
+ Note that this will already include the <code class="option">-I</code> in front of
+ the path.
+ </p><p>
+ Failure to specify the correct option to the compiler will
+ result in an error message such as:
+</p><pre class="screen">
+testlibpq.c:8:22: libpq-fe.h: No such file or directory
+</pre><p>
+ </p></li><li class="listitem"><p>
+ When linking the final program, specify the option
+ <code class="literal">-lpq</code> so that the <span class="application">libpq</span>
+ library gets pulled in, as well as the option
+ <code class="literal">-L<em class="replaceable"><code>directory</code></em></code> to point
+ the compiler to the directory where the
+ <span class="application">libpq</span> library resides. (Again, the
+ compiler will search some directories by default.) For maximum
+ portability, put the <code class="option">-L</code> option before the
+ <code class="option">-lpq</code> option. For example:
+</p><pre class="programlisting">
+cc -o testprog testprog1.o testprog2.o -L/usr/local/pgsql/lib -lpq
+</pre><p>
+ </p><p>
+ You can find out the library directory using
+ <code class="command">pg_config</code> as well:
+</p><pre class="screen">
+<code class="prompt">$</code> pg_config --libdir
+<code class="computeroutput">/usr/local/pgsql/lib</code>
+</pre><p>
+ </p><p>
+ Or again use <code class="command">pkg-config</code>:
+</p><pre class="screen">
+<code class="prompt">$</code> pkg-config --libs libpq
+<code class="computeroutput">-L/usr/local/pgsql/lib -lpq</code>
+</pre><p>
+ Note again that this prints the full options, not only the path.
+ </p><p>
+ Error messages that point to problems in this area could look like
+ the following:
+</p><pre class="screen">
+testlibpq.o: In function `main':
+testlibpq.o(.text+0x60): undefined reference to `PQsetdbLogin'
+testlibpq.o(.text+0x71): undefined reference to `PQstatus'
+testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage'
+</pre><p>
+ This means you forgot <code class="option">-lpq</code>.
+</p><pre class="screen">
+/usr/bin/ld: cannot find -lpq
+</pre><p>
+ This means you forgot the <code class="option">-L</code> option or did not
+ specify the right directory.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-threading.html" title="34.20. Behavior in Threaded Programs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-example.html" title="34.22. Example Programs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.20. Behavior in Threaded Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.22. Example Programs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-cancel.html b/doc/src/sgml/html/libpq-cancel.html
new file mode 100644
index 0000000..6dd1d01
--- /dev/null
+++ b/doc/src/sgml/html/libpq-cancel.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.7. Canceling Queries in Progress</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row" /><link rel="next" href="libpq-fastpath.html" title="34.8. The Fast-Path Interface" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.7. Canceling Queries in Progress</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-fastpath.html" title="34.8. The Fast-Path Interface">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-CANCEL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.7. Canceling Queries in Progress</h2></div></div></div><a id="id-1.7.3.14.2" class="indexterm"></a><p>
+ A client application can request cancellation of a command that is
+ still being processed by the server, using the functions described in
+ this section.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQGETCANCEL"><span class="term"><code class="function">PQgetCancel</code><a id="id-1.7.3.14.3.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Creates a data structure containing the information needed to cancel
+ a command issued through a particular database connection.
+</p><pre class="synopsis">
+PGcancel *PQgetCancel(PGconn *conn);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-cancel.html#LIBPQ-PQGETCANCEL"><code class="function">PQgetCancel</code></a> creates a
+ <code class="structname">PGcancel</code><a id="id-1.7.3.14.3.1.1.2.2.3" class="indexterm"></a> object
+ given a <code class="structname">PGconn</code> connection object. It will return
+ <code class="symbol">NULL</code> if the given <em class="parameter"><code>conn</code></em> is <code class="symbol">NULL</code> or an invalid
+ connection. The <code class="structname">PGcancel</code> object is an opaque
+ structure that is not meant to be accessed directly by the
+ application; it can only be passed to <a class="xref" href="libpq-cancel.html#LIBPQ-PQCANCEL"><code class="function">PQcancel</code></a>
+ or <a class="xref" href="libpq-cancel.html#LIBPQ-PQFREECANCEL"><code class="function">PQfreeCancel</code></a>.
+ </p></dd><dt id="LIBPQ-PQFREECANCEL"><span class="term"><code class="function">PQfreeCancel</code><a id="id-1.7.3.14.3.1.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Frees a data structure created by <a class="xref" href="libpq-cancel.html#LIBPQ-PQGETCANCEL"><code class="function">PQgetCancel</code></a>.
+</p><pre class="synopsis">
+void PQfreeCancel(PGcancel *cancel);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-cancel.html#LIBPQ-PQFREECANCEL"><code class="function">PQfreeCancel</code></a> frees a data object previously created
+ by <a class="xref" href="libpq-cancel.html#LIBPQ-PQGETCANCEL"><code class="function">PQgetCancel</code></a>.
+ </p></dd><dt id="LIBPQ-PQCANCEL"><span class="term"><code class="function">PQcancel</code><a id="id-1.7.3.14.3.1.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Requests that the server abandon processing of the current command.
+</p><pre class="synopsis">
+int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);
+</pre><p>
+ </p><p>
+ The return value is 1 if the cancel request was successfully
+ dispatched and 0 if not. If not, <em class="parameter"><code>errbuf</code></em> is filled
+ with an explanatory error message. <em class="parameter"><code>errbuf</code></em>
+ must be a char array of size <em class="parameter"><code>errbufsize</code></em> (the
+ recommended size is 256 bytes).
+ </p><p>
+ Successful dispatch is no guarantee that the request will have
+ any effect, however. If the cancellation is effective, the current
+ command will terminate early and return an error result. If the
+ cancellation fails (say, because the server was already done
+ processing the command), then there will be no visible result at
+ all.
+ </p><p>
+ <a class="xref" href="libpq-cancel.html#LIBPQ-PQCANCEL"><code class="function">PQcancel</code></a> can safely be invoked from a signal
+ handler, if the <em class="parameter"><code>errbuf</code></em> is a local variable in the
+ signal handler. The <code class="structname">PGcancel</code> object is read-only
+ as far as <a class="xref" href="libpq-cancel.html#LIBPQ-PQCANCEL"><code class="function">PQcancel</code></a> is concerned, so it can
+ also be invoked from a thread that is separate from the one
+ manipulating the <code class="structname">PGconn</code> object.
+ </p></dd></dl></div><p>
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQREQUESTCANCEL"><span class="term"><code class="function">PQrequestCancel</code><a id="id-1.7.3.14.3.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a class="xref" href="libpq-cancel.html#LIBPQ-PQREQUESTCANCEL"><code class="function">PQrequestCancel</code></a> is a deprecated variant of
+ <a class="xref" href="libpq-cancel.html#LIBPQ-PQCANCEL"><code class="function">PQcancel</code></a>.
+</p><pre class="synopsis">
+int PQrequestCancel(PGconn *conn);
+</pre><p>
+ </p><p>
+ Requests that the server abandon processing of the current
+ command. It operates directly on the
+ <code class="structname">PGconn</code> object, and in case of failure stores the
+ error message in the <code class="structname">PGconn</code> object (whence it can
+ be retrieved by <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a>). Although
+ the functionality is the same, this approach is not safe within
+ multiple-thread programs or signal handlers, since it is possible
+ that overwriting the <code class="structname">PGconn</code>'s error message will
+ mess up the operation currently in progress on the connection.
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-fastpath.html" title="34.8. The Fast-Path Interface">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.6. Retrieving Query Results Row-by-Row </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.8. The Fast-Path Interface</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-connect.html b/doc/src/sgml/html/libpq-connect.html
new file mode 100644
index 0000000..04f7a56
--- /dev/null
+++ b/doc/src/sgml/html/libpq-connect.html
@@ -0,0 +1,1134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.1. Database Connection Control Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq.html" title="Chapter 34. libpq — C Library" /><link rel="next" href="libpq-status.html" title="34.2. Connection Status Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.1. Database Connection Control Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq.html" title="Chapter 34. libpq — C Library">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-status.html" title="34.2. Connection Status Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-CONNECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.1. Database Connection Control Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-connect.html#LIBPQ-CONNSTRING">34.1.1. Connection Strings</a></span></dt><dt><span class="sect2"><a href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">34.1.2. Parameter Key Words</a></span></dt></dl></div><p>
+ The following functions deal with making a connection to a
+ <span class="productname">PostgreSQL</span> backend server. An
+ application program can have several backend connections open at
+ one time. (One reason to do that is to access more than one
+ database.) Each connection is represented by a
+ <code class="structname">PGconn</code><a id="id-1.7.3.8.2.3" class="indexterm"></a> object, which
+ is obtained from the function <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>,
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS"><code class="function">PQconnectdbParams</code></a>, or
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQSETDBLOGIN"><code class="function">PQsetdbLogin</code></a>. Note that these functions will always
+ return a non-null object pointer, unless perhaps there is too
+ little memory even to allocate the <code class="structname">PGconn</code> object.
+ The <a class="xref" href="libpq-status.html#LIBPQ-PQSTATUS"><code class="function">PQstatus</code></a> function should be called to check
+ the return value for a successful connection before queries are sent
+ via the connection object.
+
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ If untrusted users have access to a database that has not adopted a
+ <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage pattern</a>,
+ begin each session by removing publicly-writable schemas from
+ <code class="varname">search_path</code>. One can set parameter key
+ word <code class="literal">options</code> to
+ value <code class="literal">-csearch_path=</code>. Alternately, one can
+ issue <code class="literal">PQexec(<em class="replaceable"><code>conn</code></em>, "SELECT
+ pg_catalog.set_config('search_path', '', false)")</code> after
+ connecting. This consideration is not specific
+ to <span class="application">libpq</span>; it applies to every interface for
+ executing arbitrary SQL commands.
+ </p></div><p>
+
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ On Unix, forking a process with open libpq connections can lead to
+ unpredictable results because the parent and child processes share
+ the same sockets and operating system resources. For this reason,
+ such usage is not recommended, though doing an <code class="function">exec</code> from
+ the child process to load a new executable is safe.
+ </p></div><p>
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQCONNECTDBPARAMS"><span class="term"><code class="function">PQconnectdbParams</code><a id="id-1.7.3.8.2.11.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Makes a new connection to the database server.
+
+</p><pre class="synopsis">
+PGconn *PQconnectdbParams(const char * const *keywords,
+ const char * const *values,
+ int expand_dbname);
+</pre><p>
+ </p><p>
+ This function opens a new database connection using the parameters taken
+ from two <code class="symbol">NULL</code>-terminated arrays. The first,
+ <code class="literal">keywords</code>, is defined as an array of strings, each one
+ being a key word. The second, <code class="literal">values</code>, gives the value
+ for each key word. Unlike <a class="xref" href="libpq-connect.html#LIBPQ-PQSETDBLOGIN"><code class="function">PQsetdbLogin</code></a> below, the parameter
+ set can be extended without changing the function signature, so use of
+ this function (or its nonblocking analogs <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a>
+ and <code class="function">PQconnectPoll</code>) is preferred for new application
+ programming.
+ </p><p>
+ The currently recognized parameter key words are listed in
+ <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a>.
+ </p><p>
+ The passed arrays can be empty to use all default parameters, or can
+ contain one or more parameter settings. They must be matched in length.
+ Processing will stop at the first <code class="symbol">NULL</code> entry
+ in the <code class="literal">keywords</code> array.
+ Also, if the <code class="literal">values</code> entry associated with a
+ non-<code class="symbol">NULL</code> <code class="literal">keywords</code> entry is
+ <code class="symbol">NULL</code> or an empty string, that entry is ignored and
+ processing continues with the next pair of array entries.
+ </p><p>
+ When <code class="literal">expand_dbname</code> is non-zero, the value for
+ the first <em class="parameter"><code>dbname</code></em> key word is checked to see
+ if it is a <em class="firstterm">connection string</em>. If so, it
+ is <span class="quote">“<span class="quote">expanded</span>”</span> into the individual connection
+ parameters extracted from the string. The value is considered to
+ be a connection string, rather than just a database name, if it
+ contains an equal sign (<code class="literal">=</code>) or it begins with a
+ URI scheme designator. (More details on connection string formats
+ appear in <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a>.) Only the first
+ occurrence of <em class="parameter"><code>dbname</code></em> is treated in this way;
+ any subsequent <em class="parameter"><code>dbname</code></em> parameter is processed
+ as a plain database name.
+ </p><p>
+ In general the parameter arrays are processed from start to end.
+ If any key word is repeated, the last value (that is
+ not <code class="symbol">NULL</code> or empty) is used. This rule applies in
+ particular when a key word found in a connection string conflicts
+ with one appearing in the <code class="literal">keywords</code> array. Thus,
+ the programmer may determine whether array entries can override or
+ be overridden by values taken from a connection string. Array
+ entries appearing before an expanded <em class="parameter"><code>dbname</code></em>
+ entry can be overridden by fields of the connection string, and in
+ turn those fields are overridden by array entries appearing
+ after <em class="parameter"><code>dbname</code></em> (but, again, only if those
+ entries supply non-empty values).
+ </p><p>
+ After processing all the array entries and any expanded connection
+ string, any connection parameters that remain unset are filled with
+ default values. If an unset parameter's corresponding environment
+ variable (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>) is set, its value is
+ used. If the environment variable is not set either, then the
+ parameter's built-in default value is used.
+ </p></dd><dt id="LIBPQ-PQCONNECTDB"><span class="term"><code class="function">PQconnectdb</code><a id="id-1.7.3.8.2.11.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Makes a new connection to the database server.
+
+</p><pre class="synopsis">
+PGconn *PQconnectdb(const char *conninfo);
+</pre><p>
+ </p><p>
+ This function opens a new database connection using the parameters taken
+ from the string <code class="literal">conninfo</code>.
+ </p><p>
+ The passed string can be empty to use all default parameters, or it can
+ contain one or more parameter settings separated by whitespace,
+ or it can contain a <acronym class="acronym">URI</acronym>.
+ See <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a> for details.
+ </p></dd><dt id="LIBPQ-PQSETDBLOGIN"><span class="term"><code class="function">PQsetdbLogin</code><a id="id-1.7.3.8.2.11.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Makes a new connection to the database server.
+</p><pre class="synopsis">
+PGconn *PQsetdbLogin(const char *pghost,
+ const char *pgport,
+ const char *pgoptions,
+ const char *pgtty,
+ const char *dbName,
+ const char *login,
+ const char *pwd);
+</pre><p>
+ </p><p>
+ This is the predecessor of <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a> with a fixed
+ set of parameters. It has the same functionality except that the
+ missing parameters will always take on default values. Write <code class="symbol">NULL</code> or an
+ empty string for any one of the fixed parameters that is to be defaulted.
+ </p><p>
+ If the <em class="parameter"><code>dbName</code></em> contains
+ an <code class="symbol">=</code> sign or has a valid connection <acronym class="acronym">URI</acronym> prefix, it
+ is taken as a <em class="parameter"><code>conninfo</code></em> string in exactly the same way as
+ if it had been passed to <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>, and the remaining
+ parameters are then applied as specified for <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS"><code class="function">PQconnectdbParams</code></a>.
+ </p><p>
+ <code class="literal">pgtty</code> is no longer used and any value passed will
+ be ignored.
+ </p></dd><dt id="LIBPQ-PQSETDB"><span class="term"><code class="function">PQsetdb</code><a id="id-1.7.3.8.2.11.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Makes a new connection to the database server.
+</p><pre class="synopsis">
+PGconn *PQsetdb(char *pghost,
+ char *pgport,
+ char *pgoptions,
+ char *pgtty,
+ char *dbName);
+</pre><p>
+ </p><p>
+ This is a macro that calls <a class="xref" href="libpq-connect.html#LIBPQ-PQSETDBLOGIN"><code class="function">PQsetdbLogin</code></a> with null pointers
+ for the <em class="parameter"><code>login</code></em> and <em class="parameter"><code>pwd</code></em> parameters. It is provided
+ for backward compatibility with very old programs.
+ </p></dd><dt id="LIBPQ-PQCONNECTSTARTPARAMS"><span class="term"><code class="function">PQconnectStartParams</code><a id="id-1.7.3.8.2.11.5.1.2" class="indexterm"></a><br /></span><span class="term"><code class="function">PQconnectStart</code><a id="id-1.7.3.8.2.11.5.2.2" class="indexterm"></a><br /></span><span class="term"><code class="function">PQconnectPoll</code><a id="id-1.7.3.8.2.11.5.3.2" class="indexterm"></a></span></dt><dd><p>
+ <a id="id-1.7.3.8.2.11.5.4.1.1" class="indexterm"></a>
+ Make a connection to the database server in a nonblocking manner.
+
+</p><pre class="synopsis">
+PGconn *PQconnectStartParams(const char * const *keywords,
+ const char * const *values,
+ int expand_dbname);
+
+PGconn *PQconnectStart(const char *conninfo);
+
+PostgresPollingStatusType PQconnectPoll(PGconn *conn);
+</pre><p>
+ </p><p>
+ These three functions are used to open a connection to a database server such
+ that your application's thread of execution is not blocked on remote I/O
+ whilst doing so. The point of this approach is that the waits for I/O to
+ complete can occur in the application's main loop, rather than down inside
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS"><code class="function">PQconnectdbParams</code></a> or <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>, and so the
+ application can manage this operation in parallel with other activities.
+ </p><p>
+ With <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a>, the database connection is made
+ using the parameters taken from the <code class="literal">keywords</code> and
+ <code class="literal">values</code> arrays, and controlled by <code class="literal">expand_dbname</code>,
+ as described above for <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS"><code class="function">PQconnectdbParams</code></a>.
+ </p><p>
+ With <code class="function">PQconnectStart</code>, the database connection is made
+ using the parameters taken from the string <code class="literal">conninfo</code> as
+ described above for <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>.
+ </p><p>
+ Neither <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a> nor <code class="function">PQconnectStart</code>
+ nor <code class="function">PQconnectPoll</code> will block, so long as a number of
+ restrictions are met:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The <code class="literal">hostaddr</code> parameter must be used appropriately
+ to prevent DNS queries from being made. See the documentation of
+ this parameter in <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a> for details.
+ </p></li><li class="listitem"><p>
+ If you call <a class="xref" href="libpq-control.html#LIBPQ-PQTRACE"><code class="function">PQtrace</code></a>, ensure that the stream object
+ into which you trace will not block.
+ </p></li><li class="listitem"><p>
+ You must ensure that the socket is in the appropriate state
+ before calling <code class="function">PQconnectPoll</code>, as described below.
+ </p></li></ul></div><p>
+ </p><p>
+ To begin a nonblocking connection request,
+ call <code class="function">PQconnectStart</code>
+ or <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a>. If the result is null,
+ then <span class="application">libpq</span> has been unable to allocate a
+ new <code class="structname">PGconn</code> structure. Otherwise, a
+ valid <code class="structname">PGconn</code> pointer is returned (though not
+ yet representing a valid connection to the database). Next
+ call <code class="literal">PQstatus(conn)</code>. If the result
+ is <code class="symbol">CONNECTION_BAD</code>, the connection attempt has already
+ failed, typically because of invalid connection parameters.
+ </p><p>
+ If <code class="function">PQconnectStart</code>
+ or <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a> succeeds, the next stage
+ is to poll <span class="application">libpq</span> so that it can proceed with
+ the connection sequence.
+ Use <code class="function">PQsocket(conn)</code> to obtain the descriptor of the
+ socket underlying the database connection.
+ (Caution: do not assume that the socket remains the same
+ across <code class="function">PQconnectPoll</code> calls.)
+ Loop thus: If <code class="function">PQconnectPoll(conn)</code> last returned
+ <code class="symbol">PGRES_POLLING_READING</code>, wait until the socket is ready to
+ read (as indicated by <code class="function">select()</code>, <code class="function">poll()</code>, or
+ similar system function).
+ Then call <code class="function">PQconnectPoll(conn)</code> again.
+ Conversely, if <code class="function">PQconnectPoll(conn)</code> last returned
+ <code class="symbol">PGRES_POLLING_WRITING</code>, wait until the socket is ready
+ to write, then call <code class="function">PQconnectPoll(conn)</code> again.
+ On the first iteration, i.e., if you have yet to call
+ <code class="function">PQconnectPoll</code>, behave as if it last returned
+ <code class="symbol">PGRES_POLLING_WRITING</code>. Continue this loop until
+ <code class="function">PQconnectPoll(conn)</code> returns
+ <code class="symbol">PGRES_POLLING_FAILED</code>, indicating the connection procedure
+ has failed, or <code class="symbol">PGRES_POLLING_OK</code>, indicating the connection
+ has been successfully made.
+ </p><p>
+ At any time during connection, the status of the connection can be
+ checked by calling <a class="xref" href="libpq-status.html#LIBPQ-PQSTATUS"><code class="function">PQstatus</code></a>. If this call returns <code class="symbol">CONNECTION_BAD</code>, then the
+ connection procedure has failed; if the call returns <code class="function">CONNECTION_OK</code>, then the
+ connection is ready. Both of these states are equally detectable
+ from the return value of <code class="function">PQconnectPoll</code>, described above. Other states might also occur
+ during (and only during) an asynchronous connection procedure. These
+ indicate the current stage of the connection procedure and might be useful
+ to provide feedback to the user for example. These statuses are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-CONNECTION-STARTED"><span class="term"><code class="symbol">CONNECTION_STARTED</code></span></dt><dd><p>
+ Waiting for connection to be made.
+ </p></dd><dt id="LIBPQ-CONNECTION-MADE"><span class="term"><code class="symbol">CONNECTION_MADE</code></span></dt><dd><p>
+ Connection OK; waiting to send.
+ </p></dd><dt id="LIBPQ-CONNECTION-AWAITING-RESPONSE"><span class="term"><code class="symbol">CONNECTION_AWAITING_RESPONSE</code></span></dt><dd><p>
+ Waiting for a response from the server.
+ </p></dd><dt id="LIBPQ-CONNECTION-AUTH-OK"><span class="term"><code class="symbol">CONNECTION_AUTH_OK</code></span></dt><dd><p>
+ Received authentication; waiting for backend start-up to finish.
+ </p></dd><dt id="LIBPQ-CONNECTION-SSL-STARTUP"><span class="term"><code class="symbol">CONNECTION_SSL_STARTUP</code></span></dt><dd><p>
+ Negotiating SSL encryption.
+ </p></dd><dt id="LIBPQ-CONNECTION-SETENV"><span class="term"><code class="symbol">CONNECTION_SETENV</code></span></dt><dd><p>
+ Negotiating environment-driven parameter settings.
+ </p></dd><dt id="LIBPQ-CONNECTION-CHECK-WRITABLE"><span class="term"><code class="symbol">CONNECTION_CHECK_WRITABLE</code></span></dt><dd><p>
+ Checking if connection is able to handle write transactions.
+ </p></dd><dt id="LIBPQ-CONNECTION-CONSUME"><span class="term"><code class="symbol">CONNECTION_CONSUME</code></span></dt><dd><p>
+ Consuming any remaining response messages on connection.
+ </p></dd></dl></div><p>
+
+ Note that, although these constants will remain (in order to maintain
+ compatibility), an application should never rely upon these occurring in a
+ particular order, or at all, or on the status always being one of these
+ documented values. An application might do something like this:
+</p><pre class="programlisting">
+switch(PQstatus(conn))
+{
+ case CONNECTION_STARTED:
+ feedback = "Connecting...";
+ break;
+
+ case CONNECTION_MADE:
+ feedback = "Connected to server...";
+ break;
+.
+.
+.
+ default:
+ feedback = "Connecting...";
+}
+</pre><p>
+ </p><p>
+ The <code class="literal">connect_timeout</code> connection parameter is ignored
+ when using <code class="function">PQconnectPoll</code>; it is the application's
+ responsibility to decide whether an excessive amount of time has elapsed.
+ Otherwise, <code class="function">PQconnectStart</code> followed by a
+ <code class="function">PQconnectPoll</code> loop is equivalent to
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>.
+ </p><p>
+ Note that when <code class="function">PQconnectStart</code>
+ or <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a> returns a non-null
+ pointer, you must call <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a> when you are
+ finished with it, in order to dispose of the structure and any
+ associated memory blocks. This must be done even if the connection
+ attempt fails or is abandoned.
+ </p></dd><dt id="LIBPQ-PQCONNDEFAULTS"><span class="term"><code class="function">PQconndefaults</code><a id="id-1.7.3.8.2.11.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the default connection options.
+</p><pre class="synopsis">
+PQconninfoOption *PQconndefaults(void);
+
+typedef struct
+{
+ char *keyword; /* The keyword of the option */
+ char *envvar; /* Fallback environment variable name */
+ char *compiled; /* Fallback compiled in default value */
+ char *val; /* Option's current value, or NULL */
+ char *label; /* Label for field in connect dialog */
+ char *dispchar; /* Indicates how to display this field
+ in a connect dialog. Values are:
+ "" Display entered value as is
+ "*" Password field - hide value
+ "D" Debug option - don't show by default */
+ int dispsize; /* Field size in characters for dialog */
+} PQconninfoOption;
+</pre><p>
+ </p><p>
+ Returns a connection options array. This can be used to determine
+ all possible <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a> options and their
+ current default values. The return value points to an array of
+ <code class="structname">PQconninfoOption</code> structures, which ends
+ with an entry having a null <code class="structfield">keyword</code> pointer. The
+ null pointer is returned if memory could not be allocated. Note that
+ the current default values (<code class="structfield">val</code> fields)
+ will depend on environment variables and other context. A
+ missing or invalid service file will be silently ignored. Callers
+ must treat the connection options data as read-only.
+ </p><p>
+ After processing the options array, free it by passing it to
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQCONNINFOFREE"><code class="function">PQconninfoFree</code></a>. If this is not done, a small amount of memory
+ is leaked for each call to <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNDEFAULTS"><code class="function">PQconndefaults</code></a>.
+ </p></dd><dt id="LIBPQ-PQCONNINFO"><span class="term"><code class="function">PQconninfo</code><a id="id-1.7.3.8.2.11.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the connection options used by a live connection.
+</p><pre class="synopsis">
+PQconninfoOption *PQconninfo(PGconn *conn);
+</pre><p>
+ </p><p>
+ Returns a connection options array. This can be used to determine
+ all possible <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a> options and the
+ values that were used to connect to the server. The return
+ value points to an array of <code class="structname">PQconninfoOption</code>
+ structures, which ends with an entry having a null <code class="structfield">keyword</code>
+ pointer. All notes above for <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNDEFAULTS"><code class="function">PQconndefaults</code></a> also
+ apply to the result of <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNINFO"><code class="function">PQconninfo</code></a>.
+ </p></dd><dt id="LIBPQ-PQCONNINFOPARSE"><span class="term"><code class="function">PQconninfoParse</code><a id="id-1.7.3.8.2.11.8.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns parsed connection options from the provided connection string.
+
+</p><pre class="synopsis">
+PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
+</pre><p>
+ </p><p>
+ Parses a connection string and returns the resulting options as an
+ array; or returns <code class="symbol">NULL</code> if there is a problem with the connection
+ string. This function can be used to extract
+ the <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a> options in the provided
+ connection string. The return value points to an array of
+ <code class="structname">PQconninfoOption</code> structures, which ends
+ with an entry having a null <code class="structfield">keyword</code> pointer.
+ </p><p>
+ All legal options will be present in the result array, but the
+ <code class="literal">PQconninfoOption</code> for any option not present
+ in the connection string will have <code class="literal">val</code> set to
+ <code class="literal">NULL</code>; default values are not inserted.
+ </p><p>
+ If <code class="literal">errmsg</code> is not <code class="symbol">NULL</code>, then <code class="literal">*errmsg</code> is set
+ to <code class="symbol">NULL</code> on success, else to a <code class="function">malloc</code>'d error string explaining
+ the problem. (It is also possible for <code class="literal">*errmsg</code> to be
+ set to <code class="symbol">NULL</code> and the function to return <code class="symbol">NULL</code>;
+ this indicates an out-of-memory condition.)
+ </p><p>
+ After processing the options array, free it by passing it to
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQCONNINFOFREE"><code class="function">PQconninfoFree</code></a>. If this is not done, some memory
+ is leaked for each call to <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNINFOPARSE"><code class="function">PQconninfoParse</code></a>.
+ Conversely, if an error occurs and <code class="literal">errmsg</code> is not <code class="symbol">NULL</code>,
+ be sure to free the error string using <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a>.
+ </p></dd><dt id="LIBPQ-PQFINISH"><span class="term"><code class="function">PQfinish</code><a id="id-1.7.3.8.2.11.9.1.2" class="indexterm"></a></span></dt><dd><p>
+ Closes the connection to the server. Also frees
+ memory used by the <code class="structname">PGconn</code> object.
+</p><pre class="synopsis">
+void PQfinish(PGconn *conn);
+</pre><p>
+ </p><p>
+ Note that even if the server connection attempt fails (as
+ indicated by <a class="xref" href="libpq-status.html#LIBPQ-PQSTATUS"><code class="function">PQstatus</code></a>), the application should call <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a>
+ to free the memory used by the <code class="structname">PGconn</code> object.
+ The <code class="structname">PGconn</code> pointer must not be used again after
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a> has been called.
+ </p></dd><dt id="LIBPQ-PQRESET"><span class="term"><code class="function">PQreset</code><a id="id-1.7.3.8.2.11.10.1.2" class="indexterm"></a></span></dt><dd><p>
+ Resets the communication channel to the server.
+</p><pre class="synopsis">
+void PQreset(PGconn *conn);
+</pre><p>
+ </p><p>
+ This function will close the connection
+ to the server and attempt to establish a new
+ connection, using all the same
+ parameters previously used. This might be useful for
+ error recovery if a working connection is lost.
+ </p></dd><dt id="LIBPQ-PQRESETSTART"><span class="term"><code class="function">PQresetStart</code><a id="id-1.7.3.8.2.11.11.1.2" class="indexterm"></a><br /></span><span class="term"><code class="function">PQresetPoll</code><a id="id-1.7.3.8.2.11.11.2.2" class="indexterm"></a></span></dt><dd><p>
+ Reset the communication channel to the server, in a nonblocking manner.
+
+</p><pre class="synopsis">
+int PQresetStart(PGconn *conn);
+
+PostgresPollingStatusType PQresetPoll(PGconn *conn);
+</pre><p>
+ </p><p>
+ These functions will close the connection to the server and attempt to
+ establish a new connection, using all the same
+ parameters previously used. This can be useful for error recovery if a
+ working connection is lost. They differ from <a class="xref" href="libpq-connect.html#LIBPQ-PQRESET"><code class="function">PQreset</code></a> (above) in that they
+ act in a nonblocking manner. These functions suffer from the same
+ restrictions as <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a>, <code class="function">PQconnectStart</code>
+ and <code class="function">PQconnectPoll</code>.
+ </p><p>
+ To initiate a connection reset, call
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQRESETSTART"><code class="function">PQresetStart</code></a>. If it returns 0, the reset has
+ failed. If it returns 1, poll the reset using
+ <code class="function">PQresetPoll</code> in exactly the same way as you
+ would create the connection using <code class="function">PQconnectPoll</code>.
+ </p></dd><dt id="LIBPQ-PQPINGPARAMS"><span class="term"><code class="function">PQpingParams</code><a id="id-1.7.3.8.2.11.12.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQPINGPARAMS"><code class="function">PQpingParams</code></a> reports the status of the
+ server. It accepts connection parameters identical to those of
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS"><code class="function">PQconnectdbParams</code></a>, described above. It is not
+ necessary to supply correct user name, password, or database name
+ values to obtain the server status; however, if incorrect values
+ are provided, the server will log a failed connection attempt.
+
+</p><pre class="synopsis">
+PGPing PQpingParams(const char * const *keywords,
+ const char * const *values,
+ int expand_dbname);
+</pre><p>
+
+ The function returns one of the following values:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQPINGPARAMS-PQPING_OK"><span class="term"><code class="literal">PQPING_OK</code></span></dt><dd><p>
+ The server is running and appears to be accepting connections.
+ </p></dd><dt id="LIBPQ-PQPINGPARAMS-PQPING_REJECT"><span class="term"><code class="literal">PQPING_REJECT</code></span></dt><dd><p>
+ The server is running but is in a state that disallows connections
+ (startup, shutdown, or crash recovery).
+ </p></dd><dt id="LIBPQ-PQPINGPARAMS-PQPING_NO_RESPONSE"><span class="term"><code class="literal">PQPING_NO_RESPONSE</code></span></dt><dd><p>
+ The server could not be contacted. This might indicate that the
+ server is not running, or that there is something wrong with the
+ given connection parameters (for example, wrong port number), or
+ that there is a network connectivity problem (for example, a
+ firewall blocking the connection request).
+ </p></dd><dt id="LIBPQ-PQPINGPARAMS-PQPING_NO_ATTEMPT"><span class="term"><code class="literal">PQPING_NO_ATTEMPT</code></span></dt><dd><p>
+ No attempt was made to contact the server, because the supplied
+ parameters were obviously incorrect or there was some client-side
+ problem (for example, out of memory).
+ </p></dd></dl></div><p>
+
+ </p></dd><dt id="LIBPQ-PQPING"><span class="term"><code class="function">PQping</code><a id="id-1.7.3.8.2.11.13.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQPING"><code class="function">PQping</code></a> reports the status of the
+ server. It accepts connection parameters identical to those of
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>, described above. It is not
+ necessary to supply correct user name, password, or database name
+ values to obtain the server status; however, if incorrect values
+ are provided, the server will log a failed connection attempt.
+
+</p><pre class="synopsis">
+PGPing PQping(const char *conninfo);
+</pre><p>
+ </p><p>
+ The return values are the same as for <a class="xref" href="libpq-connect.html#LIBPQ-PQPINGPARAMS"><code class="function">PQpingParams</code></a>.
+ </p></dd><dt id="LIBPQ-PQSETSSLKEYPASSHOOK-OPENSSL"><span class="term"><code class="function">PQsetSSLKeyPassHook_OpenSSL</code><a id="id-1.7.3.8.2.11.14.1.2" class="indexterm"></a></span></dt><dd><p>
+ <code class="function">PQsetSSLKeyPassHook_OpenSSL</code> lets an application override
+ <span class="application">libpq</span>'s <a class="link" href="libpq-ssl.html#LIBPQ-SSL-CLIENTCERT" title="34.19.2. Client Certificates">default
+ handling of encrypted client certificate key files</a> using
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLPASSWORD">sslpassword</a> or interactive prompting.
+
+</p><pre class="synopsis">
+void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);
+</pre><p>
+
+ The application passes a pointer to a callback function with signature:
+</p><pre class="programlisting">
+int callback_fn(char *buf, int size, PGconn *conn);
+</pre><p>
+ which <span class="application">libpq</span> will then call
+ <span class="emphasis"><em>instead of</em></span> its default
+ <code class="function">PQdefaultSSLKeyPassHook_OpenSSL</code> handler. The
+ callback should determine the password for the key and copy it to
+ result-buffer <em class="parameter"><code>buf</code></em> of size
+ <em class="parameter"><code>size</code></em>. The string in <em class="parameter"><code>buf</code></em>
+ must be null-terminated. The callback must return the length of the
+ password stored in <em class="parameter"><code>buf</code></em> excluding the null
+ terminator. On failure, the callback should set
+ <code class="literal">buf[0] = '\0'</code> and return 0. See
+ <code class="function">PQdefaultSSLKeyPassHook_OpenSSL</code> in
+ <span class="application">libpq</span>'s source code for an example.
+ </p><p>
+ If the user specified an explicit key location,
+ its path will be in <code class="literal">conn-&gt;sslkey</code> when the callback
+ is invoked. This will be empty if the default key path is being used.
+ For keys that are engine specifiers, it is up to engine implementations
+ whether they use the <span class="productname">OpenSSL</span> password
+ callback or define their own handling.
+ </p><p>
+ The app callback may choose to delegate unhandled cases to
+ <code class="function">PQdefaultSSLKeyPassHook_OpenSSL</code>,
+ or call it first and try something else if it returns 0, or completely override it.
+ </p><p>
+ The callback <span class="emphasis"><em>must not</em></span> escape normal flow control with exceptions,
+ <code class="function">longjmp(...)</code>, etc. It must return normally.
+ </p></dd><dt id="LIBPQ-PQGETSSLKEYPASSHOOK-OPENSSL"><span class="term"><code class="function">PQgetSSLKeyPassHook_OpenSSL</code><a id="id-1.7.3.8.2.11.15.1.2" class="indexterm"></a></span></dt><dd><p>
+ <code class="function">PQgetSSLKeyPassHook_OpenSSL</code> returns the current
+ client certificate key password hook, or <code class="literal">NULL</code>
+ if none has been set.
+
+</p><pre class="synopsis">
+PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void);
+</pre><p>
+ </p></dd></dl></div><p>
+ </p><div class="sect2" id="LIBPQ-CONNSTRING"><div class="titlepage"><div><div><h3 class="title">34.1.1. Connection Strings</h3></div></div></div><a id="id-1.7.3.8.3.2" class="indexterm"></a><a id="id-1.7.3.8.3.3" class="indexterm"></a><p>
+ Several <span class="application">libpq</span> functions parse a user-specified string to obtain
+ connection parameters. There are two accepted formats for these strings:
+ plain keyword/value strings
+ and URIs. URIs generally follow
+ <a class="ulink" href="https://tools.ietf.org/html/rfc3986" target="_top">RFC
+ 3986</a>, except that multi-host connection strings are allowed
+ as further described below.
+ </p><div class="sect3" id="id-1.7.3.8.3.5"><div class="titlepage"><div><div><h4 class="title">34.1.1.1. Keyword/Value Connection Strings</h4></div></div></div><p>
+ In the keyword/value format, each parameter setting is in the form
+ <em class="replaceable"><code>keyword</code></em> <code class="literal">=</code>
+ <em class="replaceable"><code>value</code></em>, with space(s) between settings.
+ Spaces around a setting's equal sign are
+ optional. To write an empty value, or a value containing spaces, surround it
+ with single quotes, for example <code class="literal">keyword = 'a value'</code>.
+ Single quotes and backslashes within
+ a value must be escaped with a backslash, i.e., <code class="literal">\'</code> and
+ <code class="literal">\\</code>.
+ </p><p>
+ Example:
+</p><pre class="programlisting">
+host=localhost port=5432 dbname=mydb connect_timeout=10
+</pre><p>
+ </p><p>
+ The recognized parameter key words are listed in <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a>.
+ </p></div><div class="sect3" id="id-1.7.3.8.3.6"><div class="titlepage"><div><div><h4 class="title">34.1.1.2. Connection URIs</h4></div></div></div><p>
+ The general form for a connection <acronym class="acronym">URI</acronym> is:
+</p><pre class="synopsis">
+postgresql://[<span class="optional"><em class="replaceable"><code>userspec</code></em>@</span>][<span class="optional"><em class="replaceable"><code>hostspec</code></em></span>][<span class="optional">/<em class="replaceable"><code>dbname</code></em></span>][<span class="optional">?<em class="replaceable"><code>paramspec</code></em></span>]
+
+<span class="phrase">where <em class="replaceable"><code>userspec</code></em> is:</span>
+
+<em class="replaceable"><code>user</code></em>[<span class="optional">:<em class="replaceable"><code>password</code></em></span>]
+
+<span class="phrase">and <em class="replaceable"><code>hostspec</code></em> is:</span>
+
+[<span class="optional"><em class="replaceable"><code>host</code></em></span>][<span class="optional">:<em class="replaceable"><code>port</code></em></span>][<span class="optional">,...</span>]
+
+<span class="phrase">and <em class="replaceable"><code>paramspec</code></em> is:</span>
+
+<em class="replaceable"><code>name</code></em>=<em class="replaceable"><code>value</code></em>[<span class="optional">&amp;...</span>]
+</pre><p>
+ </p><p>
+ The <acronym class="acronym">URI</acronym> scheme designator can be either
+ <code class="literal">postgresql://</code> or <code class="literal">postgres://</code>. Each
+ of the remaining <acronym class="acronym">URI</acronym> parts is optional. The
+ following examples illustrate valid <acronym class="acronym">URI</acronym> syntax:
+</p><pre class="programlisting">
+postgresql://
+postgresql://localhost
+postgresql://localhost:5433
+postgresql://localhost/mydb
+postgresql://user@localhost
+postgresql://user:secret@localhost
+postgresql://other@localhost/otherdb?connect_timeout=10&amp;application_name=myapp
+postgresql://host1:123,host2:456/somedb?target_session_attrs=any&amp;application_name=myapp
+</pre><p>
+ Values that would normally appear in the hierarchical part of
+ the <acronym class="acronym">URI</acronym> can alternatively be given as named
+ parameters. For example:
+</p><pre class="programlisting">
+postgresql:///mydb?host=localhost&amp;port=5433
+</pre><p>
+ All named parameters must match key words listed in
+ <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a>, except that for compatibility
+ with JDBC connection <acronym class="acronym">URI</acronym>s, instances
+ of <code class="literal">ssl=true</code> are translated into
+ <code class="literal">sslmode=require</code>.
+ </p><p>
+ The connection <acronym class="acronym">URI</acronym> needs to be encoded with <a class="ulink" href="https://tools.ietf.org/html/rfc3986#section-2.1" target="_top">percent-encoding</a>
+ if it includes symbols with special meaning in any of its parts. Here is
+ an example where the equal sign (<code class="literal">=</code>) is replaced with
+ <code class="literal">%3D</code> and the space character with
+ <code class="literal">%20</code>:
+</p><pre class="programlisting">
+postgresql://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff
+</pre><p>
+ </p><p>
+ The host part may be either a host name or an IP address. To specify an
+ IPv6 address, enclose it in square brackets:
+</p><pre class="synopsis">
+postgresql://[2001:db8::1234]/database
+</pre><p>
+ </p><p>
+ The host part is interpreted as described for the parameter <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-HOST">host</a>. In particular, a Unix-domain socket
+ connection is chosen if the host part is either empty or looks like an
+ absolute path name,
+ otherwise a TCP/IP connection is initiated. Note, however, that the
+ slash is a reserved character in the hierarchical part of the URI. So, to
+ specify a non-standard Unix-domain socket directory, either omit the host
+ part of the URI and specify the host as a named parameter, or
+ percent-encode the path in the host part of the URI:
+</p><pre class="programlisting">
+postgresql:///dbname?host=/var/lib/postgresql
+postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
+</pre><p>
+ </p><p>
+ It is possible to specify multiple host components, each with an optional
+ port component, in a single URI. A URI of the form
+ <code class="literal">postgresql://host1:port1,host2:port2,host3:port3/</code>
+ is equivalent to a connection string of the form
+ <code class="literal">host=host1,host2,host3 port=port1,port2,port3</code>.
+ As further described below, each
+ host will be tried in turn until a connection is successfully established.
+ </p></div><div class="sect3" id="LIBPQ-MULTIPLE-HOSTS"><div class="titlepage"><div><div><h4 class="title">34.1.1.3. Specifying Multiple Hosts</h4></div></div></div><p>
+ It is possible to specify multiple hosts to connect to, so that they are
+ tried in the given order. In the Keyword/Value format, the <code class="literal">host</code>,
+ <code class="literal">hostaddr</code>, and <code class="literal">port</code> options accept comma-separated
+ lists of values. The same number of elements must be given in each
+ option that is specified, such
+ that e.g., the first <code class="literal">hostaddr</code> corresponds to the first host name,
+ the second <code class="literal">hostaddr</code> corresponds to the second host name, and so
+ forth. As an exception, if only one <code class="literal">port</code> is specified, it
+ applies to all the hosts.
+ </p><p>
+ In the connection URI format, you can list multiple <code class="literal">host:port</code> pairs
+ separated by commas in the <code class="literal">host</code> component of the URI.
+ </p><p>
+ In either format, a single host name can translate to multiple network
+ addresses. A common example of this is a host that has both an IPv4 and
+ an IPv6 address.
+ </p><p>
+ When multiple hosts are specified, or when a single host name is
+ translated to multiple addresses, all the hosts and addresses will be
+ tried in order, until one succeeds. If none of the hosts can be reached,
+ the connection fails. If a connection is established successfully, but
+ authentication fails, the remaining hosts in the list are not tried.
+ </p><p>
+ If a password file is used, you can have different passwords for
+ different hosts. All the other connection options are the same for every
+ host in the list; it is not possible to e.g., specify different
+ usernames for different hosts.
+ </p></div></div><div class="sect2" id="LIBPQ-PARAMKEYWORDS"><div class="titlepage"><div><div><h3 class="title">34.1.2. Parameter Key Words</h3></div></div></div><p>
+ The currently recognized parameter key words are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-CONNECT-HOST"><span class="term"><code class="literal">host</code></span></dt><dd><p>
+ Name of host to connect to.<a id="id-1.7.3.8.4.2.1.1.2.1.1" class="indexterm"></a> If a host name looks like an absolute path
+ name, it specifies Unix-domain communication rather than TCP/IP
+ communication; the value is the name of the directory in which the
+ socket file is stored. (On Unix, an absolute path name begins with a
+ slash. On Windows, paths starting with drive letters are also
+ recognized.) If the host name starts with <code class="literal">@</code>, it is
+ taken as a Unix-domain socket in the abstract namespace (currently
+ supported on Linux and Windows).
+ The default behavior when <code class="literal">host</code> is not
+ specified, or is empty, is to connect to a Unix-domain
+ socket<a id="id-1.7.3.8.4.2.1.1.2.1.4" class="indexterm"></a> in
+ <code class="filename">/tmp</code> (or whatever socket directory was specified
+ when <span class="productname">PostgreSQL</span> was built). On Windows and
+ on machines without Unix-domain sockets, the default is to connect to
+ <code class="literal">localhost</code>.
+ </p><p>
+ A comma-separated list of host names is also accepted, in which case
+ each host name in the list is tried in order; an empty item in the
+ list selects the default behavior as explained above. See
+ <a class="xref" href="libpq-connect.html#LIBPQ-MULTIPLE-HOSTS" title="34.1.1.3. Specifying Multiple Hosts">Section 34.1.1.3</a> for details.
+ </p></dd><dt id="LIBPQ-CONNECT-HOSTADDR"><span class="term"><code class="literal">hostaddr</code></span></dt><dd><p>
+ Numeric IP address of host to connect to. This should be in the
+ standard IPv4 address format, e.g., <code class="literal">172.28.40.9</code>. If
+ your machine supports IPv6, you can also use those addresses.
+ TCP/IP communication is
+ always used when a nonempty string is specified for this parameter.
+ If this parameter is not specified, the value of <code class="literal">host</code>
+ will be looked up to find the corresponding IP address — or, if
+ <code class="literal">host</code> specifies an IP address, that value will be
+ used directly.
+ </p><p>
+ Using <code class="literal">hostaddr</code> allows the
+ application to avoid a host name look-up, which might be important
+ in applications with time constraints. However, a host name is
+ required for GSSAPI or SSPI authentication
+ methods, as well as for <code class="literal">verify-full</code> SSL
+ certificate verification. The following rules are used:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If <code class="literal">host</code> is specified
+ without <code class="literal">hostaddr</code>, a host name lookup occurs.
+ (When using <code class="function">PQconnectPoll</code>, the lookup occurs
+ when <code class="function">PQconnectPoll</code> first considers this host
+ name, and it may cause <code class="function">PQconnectPoll</code> to block
+ for a significant amount of time.)
+ </p></li><li class="listitem"><p>
+ If <code class="literal">hostaddr</code> is specified without <code class="literal">host</code>,
+ the value for <code class="literal">hostaddr</code> gives the server network address.
+ The connection attempt will fail if the authentication
+ method requires a host name.
+ </p></li><li class="listitem"><p>
+ If both <code class="literal">host</code> and <code class="literal">hostaddr</code> are specified,
+ the value for <code class="literal">hostaddr</code> gives the server network address.
+ The value for <code class="literal">host</code> is ignored unless the
+ authentication method requires it, in which case it will be
+ used as the host name.
+ </p></li></ul></div><p>
+ Note that authentication is likely to fail if <code class="literal">host</code>
+ is not the name of the server at network address <code class="literal">hostaddr</code>.
+ Also, when both <code class="literal">host</code> and <code class="literal">hostaddr</code>
+ are specified, <code class="literal">host</code>
+ is used to identify the connection in a password file (see
+ <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a>).
+ </p><p>
+ A comma-separated list of <code class="literal">hostaddr</code> values is also
+ accepted, in which case each host in the list is tried in order.
+ An empty item in the list causes the corresponding host name to be
+ used, or the default host name if that is empty as well. See
+ <a class="xref" href="libpq-connect.html#LIBPQ-MULTIPLE-HOSTS" title="34.1.1.3. Specifying Multiple Hosts">Section 34.1.1.3</a> for details.
+ </p><p>
+ Without either a host name or host address,
+ <span class="application">libpq</span> will connect using a local
+ Unix-domain socket; or on Windows and on machines without Unix-domain
+ sockets, it will attempt to connect to <code class="literal">localhost</code>.
+ </p></dd><dt id="LIBPQ-CONNECT-PORT"><span class="term"><code class="literal">port</code></span></dt><dd><p>
+ Port number to connect to at the server host, or socket file
+ name extension for Unix-domain
+ connections.<a id="id-1.7.3.8.4.2.1.3.2.1.1" class="indexterm"></a>
+ If multiple hosts were given in the <code class="literal">host</code> or
+ <code class="literal">hostaddr</code> parameters, this parameter may specify a
+ comma-separated list of ports of the same length as the host list, or
+ it may specify a single port number to be used for all hosts.
+ An empty string, or an empty item in a comma-separated list,
+ specifies the default port number established
+ when <span class="productname">PostgreSQL</span> was built.
+ </p></dd><dt id="LIBPQ-CONNECT-DBNAME"><span class="term"><code class="literal">dbname</code></span></dt><dd><p>
+ The database name. Defaults to be the same as the user name.
+ In certain contexts, the value is checked for extended
+ formats; see <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a> for more details on
+ those.
+ </p></dd><dt id="LIBPQ-CONNECT-USER"><span class="term"><code class="literal">user</code></span></dt><dd><p>
+ <span class="productname">PostgreSQL</span> user name to connect as.
+ Defaults to be the same as the operating system name of the user
+ running the application.
+ </p></dd><dt id="LIBPQ-CONNECT-PASSWORD"><span class="term"><code class="literal">password</code></span></dt><dd><p>
+ Password to be used if the server demands password authentication.
+ </p></dd><dt id="LIBPQ-CONNECT-PASSFILE"><span class="term"><code class="literal">passfile</code></span></dt><dd><p>
+ Specifies the name of the file used to store passwords
+ (see <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a>).
+ Defaults to <code class="filename">~/.pgpass</code>, or
+ <code class="filename">%APPDATA%\postgresql\pgpass.conf</code> on Microsoft Windows.
+ (No error is reported if this file does not exist.)
+ </p></dd><dt id="LIBPQ-CONNECT-CHANNEL-BINDING"><span class="term"><code class="literal">channel_binding</code></span></dt><dd><p>
+ This option controls the client's use of channel binding. A setting
+ of <code class="literal">require</code> means that the connection must employ
+ channel binding, <code class="literal">prefer</code> means that the client will
+ choose channel binding if available, and <code class="literal">disable</code>
+ prevents the use of channel binding. The default
+ is <code class="literal">prefer</code> if
+ <span class="productname">PostgreSQL</span> is compiled with SSL support;
+ otherwise the default is <code class="literal">disable</code>.
+ </p><p>
+ Channel binding is a method for the server to authenticate itself to
+ the client. It is only supported over SSL connections
+ with <span class="productname">PostgreSQL</span> 11 or later servers using
+ the <code class="literal">SCRAM</code> authentication method.
+ </p></dd><dt id="LIBPQ-CONNECT-CONNECT-TIMEOUT"><span class="term"><code class="literal">connect_timeout</code></span></dt><dd><p>
+ Maximum time to wait while connecting, in seconds (write as a decimal integer,
+ e.g., <code class="literal">10</code>). Zero, negative, or not specified means
+ wait indefinitely. The minimum allowed timeout is 2 seconds, therefore
+ a value of <code class="literal">1</code> is interpreted as <code class="literal">2</code>.
+ This timeout applies separately to each host name or IP address.
+ For example, if you specify two hosts and <code class="literal">connect_timeout</code>
+ is 5, each host will time out if no connection is made within 5
+ seconds, so the total time spent waiting for a connection might be
+ up to 10 seconds.
+ </p></dd><dt id="LIBPQ-CONNECT-CLIENT-ENCODING"><span class="term"><code class="literal">client_encoding</code></span></dt><dd><p>
+ This sets the <code class="varname">client_encoding</code>
+ configuration parameter for this connection. In addition to
+ the values accepted by the corresponding server option, you
+ can use <code class="literal">auto</code> to determine the right
+ encoding from the current locale in the client
+ (<code class="envar">LC_CTYPE</code> environment variable on Unix
+ systems).
+ </p></dd><dt id="LIBPQ-CONNECT-OPTIONS"><span class="term"><code class="literal">options</code></span></dt><dd><p>
+ Specifies command-line options to send to the server at connection
+ start. For example, setting this to <code class="literal">-c geqo=off</code> sets the
+ session's value of the <code class="varname">geqo</code> parameter to
+ <code class="literal">off</code>. Spaces within this string are considered to
+ separate command-line arguments, unless escaped with a backslash
+ (<code class="literal">\</code>); write <code class="literal">\\</code> to represent a literal
+ backslash. For a detailed discussion of the available
+ options, consult <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>.
+ </p></dd><dt id="LIBPQ-CONNECT-APPLICATION-NAME"><span class="term"><code class="literal">application_name</code></span></dt><dd><p>
+ Specifies a value for the <a class="xref" href="runtime-config-logging.html#GUC-APPLICATION-NAME">application_name</a>
+ configuration parameter.
+ </p></dd><dt id="LIBPQ-CONNECT-FALLBACK-APPLICATION-NAME"><span class="term"><code class="literal">fallback_application_name</code></span></dt><dd><p>
+ Specifies a fallback value for the <a class="xref" href="runtime-config-logging.html#GUC-APPLICATION-NAME">application_name</a> configuration parameter.
+ This value will be used if no value has been given for
+ <code class="literal">application_name</code> via a connection parameter or the
+ <code class="envar">PGAPPNAME</code> environment variable. Specifying
+ a fallback name is useful in generic utility programs that
+ wish to set a default application name but allow it to be
+ overridden by the user.
+ </p></dd><dt id="LIBPQ-KEEPALIVES"><span class="term"><code class="literal">keepalives</code></span></dt><dd><p>
+ Controls whether client-side TCP keepalives are used. The default
+ value is 1, meaning on, but you can change this to 0, meaning off,
+ if keepalives are not wanted. This parameter is ignored for
+ connections made via a Unix-domain socket.
+ </p></dd><dt id="LIBPQ-KEEPALIVES-IDLE"><span class="term"><code class="literal">keepalives_idle</code></span></dt><dd><p>
+ Controls the number of seconds of inactivity after which TCP should
+ send a keepalive message to the server. A value of zero uses the
+ system default. This parameter is ignored for connections made via a
+ Unix-domain socket, or if keepalives are disabled.
+ It is only supported on systems where <code class="symbol">TCP_KEEPIDLE</code> or
+ an equivalent socket option is available, and on Windows; on other
+ systems, it has no effect.
+ </p></dd><dt id="LIBPQ-KEEPALIVES-INTERVAL"><span class="term"><code class="literal">keepalives_interval</code></span></dt><dd><p>
+ Controls the number of seconds after which a TCP keepalive message
+ that is not acknowledged by the server should be retransmitted. A
+ value of zero uses the system default. This parameter is ignored for
+ connections made via a Unix-domain socket, or if keepalives are disabled.
+ It is only supported on systems where <code class="symbol">TCP_KEEPINTVL</code> or
+ an equivalent socket option is available, and on Windows; on other
+ systems, it has no effect.
+ </p></dd><dt id="LIBPQ-KEEPALIVES-COUNT"><span class="term"><code class="literal">keepalives_count</code></span></dt><dd><p>
+ Controls the number of TCP keepalives that can be lost before the
+ client's connection to the server is considered dead. A value of
+ zero uses the system default. This parameter is ignored for
+ connections made via a Unix-domain socket, or if keepalives are disabled.
+ It is only supported on systems where <code class="symbol">TCP_KEEPCNT</code> or
+ an equivalent socket option is available; on other systems, it has no
+ effect.
+ </p></dd><dt id="LIBPQ-TCP-USER-TIMEOUT"><span class="term"><code class="literal">tcp_user_timeout</code></span></dt><dd><p>
+ Controls the number of milliseconds that transmitted data may
+ remain unacknowledged before a connection is forcibly closed.
+ A value of zero uses the system default. This parameter is
+ ignored for connections made via a Unix-domain socket.
+ It is only supported on systems where <code class="symbol">TCP_USER_TIMEOUT</code>
+ is available; on other systems, it has no effect.
+ </p></dd><dt id="LIBPQ-CONNECT-REPLICATION"><span class="term"><code class="literal">replication</code></span></dt><dd><p>
+ This option determines whether the connection should use the
+ replication protocol instead of the normal protocol. This is what
+ PostgreSQL replication connections as well as tools such as
+ <span class="application">pg_basebackup</span> use internally, but it can
+ also be used by third-party applications. For a description of the
+ replication protocol, consult <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>.
+ </p><p>
+ The following values, which are case-insensitive, are supported:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal">true</code>, <code class="literal">on</code>,
+ <code class="literal">yes</code>, <code class="literal">1</code>
+ </span></dt><dd><p>
+ The connection goes into physical replication mode.
+ </p></dd><dt><span class="term"><code class="literal">database</code></span></dt><dd><p>
+ The connection goes into logical replication mode, connecting to
+ the database specified in the <code class="literal">dbname</code> parameter.
+ </p></dd><dt><span class="term">
+ <code class="literal">false</code>, <code class="literal">off</code>,
+ <code class="literal">no</code>, <code class="literal">0</code>
+ </span></dt><dd><p>
+ The connection is a regular one, which is the default behavior.
+ </p></dd></dl></div><p>
+ </p><p>
+ In physical or logical replication mode, only the simple query protocol
+ can be used.
+ </p></dd><dt id="LIBPQ-CONNECT-GSSENCMODE"><span class="term"><code class="literal">gssencmode</code></span></dt><dd><p>
+ This option determines whether or with what priority a secure
+ <acronym class="acronym">GSS</acronym> TCP/IP connection will be negotiated with the
+ server. There are three modes:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">disable</code></span></dt><dd><p>
+ only try a non-<acronym class="acronym">GSSAPI</acronym>-encrypted connection
+ </p></dd><dt><span class="term"><code class="literal">prefer</code> (default)</span></dt><dd><p>
+ if there are <acronym class="acronym">GSSAPI</acronym> credentials present (i.e.,
+ in a credentials cache), first try
+ a <acronym class="acronym">GSSAPI</acronym>-encrypted connection; if that fails or
+ there are no credentials, try a
+ non-<acronym class="acronym">GSSAPI</acronym>-encrypted connection. This is the
+ default when <span class="productname">PostgreSQL</span> has been
+ compiled with <acronym class="acronym">GSSAPI</acronym> support.
+ </p></dd><dt><span class="term"><code class="literal">require</code></span></dt><dd><p>
+ only try a <acronym class="acronym">GSSAPI</acronym>-encrypted connection
+ </p></dd></dl></div><p>
+ </p><p>
+ <code class="literal">gssencmode</code> is ignored for Unix domain socket
+ communication. If <span class="productname">PostgreSQL</span> is compiled
+ without GSSAPI support, using the <code class="literal">require</code> option
+ will cause an error, while <code class="literal">prefer</code> will be accepted
+ but <span class="application">libpq</span> will not actually attempt
+ a <acronym class="acronym">GSSAPI</acronym>-encrypted
+ connection.<a id="id-1.7.3.8.4.2.1.20.2.2.7" class="indexterm"></a>
+ </p></dd><dt id="LIBPQ-CONNECT-SSLMODE"><span class="term"><code class="literal">sslmode</code></span></dt><dd><p>
+ This option determines whether or with what priority a secure
+ <acronym class="acronym">SSL</acronym> TCP/IP connection will be negotiated with the
+ server. There are six modes:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">disable</code></span></dt><dd><p>
+ only try a non-<acronym class="acronym">SSL</acronym> connection
+ </p></dd><dt><span class="term"><code class="literal">allow</code></span></dt><dd><p>
+ first try a non-<acronym class="acronym">SSL</acronym> connection; if that
+ fails, try an <acronym class="acronym">SSL</acronym> connection
+ </p></dd><dt><span class="term"><code class="literal">prefer</code> (default)</span></dt><dd><p>
+ first try an <acronym class="acronym">SSL</acronym> connection; if that fails,
+ try a non-<acronym class="acronym">SSL</acronym> connection
+ </p></dd><dt><span class="term"><code class="literal">require</code></span></dt><dd><p>
+ only try an <acronym class="acronym">SSL</acronym> connection. If a root CA
+ file is present, verify the certificate in the same way as
+ if <code class="literal">verify-ca</code> was specified
+ </p></dd><dt><span class="term"><code class="literal">verify-ca</code></span></dt><dd><p>
+ only try an <acronym class="acronym">SSL</acronym> connection, and verify that
+ the server certificate is issued by a trusted
+ certificate authority (<acronym class="acronym">CA</acronym>)
+ </p></dd><dt><span class="term"><code class="literal">verify-full</code></span></dt><dd><p>
+ only try an <acronym class="acronym">SSL</acronym> connection, verify that the
+ server certificate is issued by a
+ trusted <acronym class="acronym">CA</acronym> and that the requested server host name
+ matches that in the certificate
+ </p></dd></dl></div><p>
+
+ See <a class="xref" href="libpq-ssl.html" title="34.19. SSL Support">Section 34.19</a> for a detailed description of how
+ these options work.
+ </p><p>
+ <code class="literal">sslmode</code> is ignored for Unix domain socket
+ communication.
+ If <span class="productname">PostgreSQL</span> is compiled without SSL support,
+ using options <code class="literal">require</code>, <code class="literal">verify-ca</code>, or
+ <code class="literal">verify-full</code> will cause an error, while
+ options <code class="literal">allow</code> and <code class="literal">prefer</code> will be
+ accepted but <span class="application">libpq</span> will not actually attempt
+ an <acronym class="acronym">SSL</acronym>
+ connection.<a id="id-1.7.3.8.4.2.1.21.2.2.10" class="indexterm"></a>
+ </p><p>
+ Note that if <acronym class="acronym">GSSAPI</acronym> encryption is possible,
+ that will be used in preference to <acronym class="acronym">SSL</acronym>
+ encryption, regardless of the value of <code class="literal">sslmode</code>.
+ To force use of <acronym class="acronym">SSL</acronym> encryption in an
+ environment that has working <acronym class="acronym">GSSAPI</acronym>
+ infrastructure (such as a Kerberos server), also
+ set <code class="literal">gssencmode</code> to <code class="literal">disable</code>.
+ </p></dd><dt id="LIBPQ-CONNECT-REQUIRESSL"><span class="term"><code class="literal">requiressl</code></span></dt><dd><p>
+ This option is deprecated in favor of the <code class="literal">sslmode</code>
+ setting.
+ </p><p>
+ If set to 1, an <acronym class="acronym">SSL</acronym> connection to the server
+ is required (this is equivalent to <code class="literal">sslmode</code>
+ <code class="literal">require</code>). <span class="application">libpq</span> will then refuse
+ to connect if the server does not accept an
+ <acronym class="acronym">SSL</acronym> connection. If set to 0 (default),
+ <span class="application">libpq</span> will negotiate the connection type with
+ the server (equivalent to <code class="literal">sslmode</code>
+ <code class="literal">prefer</code>). This option is only available if
+ <span class="productname">PostgreSQL</span> is compiled with SSL support.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLCOMPRESSION"><span class="term"><code class="literal">sslcompression</code></span></dt><dd><p>
+ If set to 1, data sent over SSL connections will be compressed. If
+ set to 0, compression will be disabled. The default is 0. This
+ parameter is ignored if a connection without SSL is made.
+ </p><p>
+ SSL compression is nowadays considered insecure and its use is no
+ longer recommended. <span class="productname">OpenSSL</span> 1.1.0 disables
+ compression by default, and many operating system distributions
+ disable it in prior versions as well, so setting this parameter to on
+ will not have any effect if the server does not accept compression.
+ <span class="productname">PostgreSQL</span> 14 disables compression
+ completely in the backend.
+ </p><p>
+ If security is not a primary concern, compression can improve
+ throughput if the network is the bottleneck. Disabling compression
+ can improve response time and throughput if CPU performance is the
+ limiting factor.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLCERT"><span class="term"><code class="literal">sslcert</code></span></dt><dd><p>
+ This parameter specifies the file name of the client SSL
+ certificate, replacing the default
+ <code class="filename">~/.postgresql/postgresql.crt</code>.
+ This parameter is ignored if an SSL connection is not made.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLKEY"><span class="term"><code class="literal">sslkey</code></span></dt><dd><p>
+ This parameter specifies the location for the secret key used for
+ the client certificate. It can either specify a file name that will
+ be used instead of the default
+ <code class="filename">~/.postgresql/postgresql.key</code>, or it can specify a key
+ obtained from an external <span class="quote">“<span class="quote">engine</span>”</span> (engines are
+ <span class="productname">OpenSSL</span> loadable modules). An external engine
+ specification should consist of a colon-separated engine name and
+ an engine-specific key identifier. This parameter is ignored if an
+ SSL connection is not made.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLPASSWORD"><span class="term"><code class="literal">sslpassword</code></span></dt><dd><p>
+ This parameter specifies the password for the secret key specified in
+ <code class="literal">sslkey</code>, allowing client certificate private keys
+ to be stored in encrypted form on disk even when interactive passphrase
+ input is not practical.
+ </p><p>
+ Specifying this parameter with any non-empty value suppresses the
+ <code class="literal">Enter PEM pass phrase:</code>
+ prompt that <span class="productname">OpenSSL</span> will emit by default
+ when an encrypted client certificate key is provided to
+ <code class="literal">libpq</code>.
+ </p><p>
+ If the key is not encrypted this parameter is ignored. The parameter
+ has no effect on keys specified by <span class="productname">OpenSSL</span>
+ engines unless the engine uses the <span class="productname">OpenSSL</span>
+ password callback mechanism for prompts.
+ </p><p>
+ There is no environment variable equivalent to this option, and no
+ facility for looking it up in <code class="filename">.pgpass</code>. It can be
+ used in a service file connection definition. Users with
+ more sophisticated uses should consider using <span class="productname">OpenSSL</span> engines and
+ tools like PKCS#11 or USB crypto offload devices.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLROOTCERT"><span class="term"><code class="literal">sslrootcert</code></span></dt><dd><p>
+ This parameter specifies the name of a file containing SSL
+ certificate authority (<acronym class="acronym">CA</acronym>) certificate(s).
+ If the file exists, the server's certificate will be verified
+ to be signed by one of these authorities. The default is
+ <code class="filename">~/.postgresql/root.crt</code>.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLCRL"><span class="term"><code class="literal">sslcrl</code></span></dt><dd><p>
+ This parameter specifies the file name of the SSL server certificate
+ revocation list (CRL). Certificates listed in this file, if it
+ exists, will be rejected while attempting to authenticate the
+ server's certificate. If neither
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLCRL">sslcrl</a> nor
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLCRLDIR">sslcrldir</a> is set, this setting is
+ taken as
+ <code class="filename">~/.postgresql/root.crl</code>.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLCRLDIR"><span class="term"><code class="literal">sslcrldir</code></span></dt><dd><p>
+ This parameter specifies the directory name of the SSL server certificate
+ revocation list (CRL). Certificates listed in the files in this
+ directory, if it exists, will be rejected while attempting to
+ authenticate the server's certificate.
+ </p><p>
+ The directory needs to be prepared with the
+ <span class="productname">OpenSSL</span> command
+ <code class="literal">openssl rehash</code> or <code class="literal">c_rehash</code>. See
+ its documentation for details.
+ </p><p>
+ Both <code class="literal">sslcrl</code> and <code class="literal">sslcrldir</code> can be
+ specified together.
+ </p></dd><dt id="LIBPQ-CONNECT-SSLSNI"><span class="term"><code class="literal">sslsni</code><a id="id-1.7.3.8.4.2.1.30.1.2" class="indexterm"></a></span></dt><dd><p>
+ If set to 1 (default), libpq sets the TLS extension <span class="quote">“<span class="quote">Server Name
+ Indication</span>”</span> (<acronym class="acronym">SNI</acronym>) on SSL-enabled connections.
+ By setting this parameter to 0, this is turned off.
+ </p><p>
+ The Server Name Indication can be used by SSL-aware proxies to route
+ connections without having to decrypt the SSL stream. (Note that this
+ requires a proxy that is aware of the PostgreSQL protocol handshake,
+ not just any SSL proxy.) However, <acronym class="acronym">SNI</acronym> makes the
+ destination host name appear in cleartext in the network traffic, so
+ it might be undesirable in some cases.
+ </p></dd><dt id="LIBPQ-CONNECT-REQUIREPEER"><span class="term"><code class="literal">requirepeer</code></span></dt><dd><p>
+ This parameter specifies the operating-system user name of the
+ server, for example <code class="literal">requirepeer=postgres</code>.
+ When making a Unix-domain socket connection, if this
+ parameter is set, the client checks at the beginning of the
+ connection that the server process is running under the specified
+ user name; if it is not, the connection is aborted with an error.
+ This parameter can be used to provide server authentication similar
+ to that available with SSL certificates on TCP/IP connections.
+ (Note that if the Unix-domain socket is in
+ <code class="filename">/tmp</code> or another publicly writable location,
+ any user could start a server listening there. Use this parameter
+ to ensure that you are connected to a server run by a trusted user.)
+ This option is only supported on platforms for which the
+ <code class="literal">peer</code> authentication method is implemented; see
+ <a class="xref" href="auth-peer.html" title="21.9. Peer Authentication">Section 21.9</a>.
+ </p></dd><dt id="LIBPQ-CONNECT-SSL-MIN-PROTOCOL-VERSION"><span class="term"><code class="literal">ssl_min_protocol_version</code></span></dt><dd><p>
+ This parameter specifies the minimum SSL/TLS protocol version to allow
+ for the connection. Valid values are <code class="literal">TLSv1</code>,
+ <code class="literal">TLSv1.1</code>, <code class="literal">TLSv1.2</code> and
+ <code class="literal">TLSv1.3</code>. The supported protocols depend on the
+ version of <span class="productname">OpenSSL</span> used, older versions
+ not supporting the most modern protocol versions. If not specified,
+ the default is <code class="literal">TLSv1.2</code>, which satisfies industry
+ best practices as of this writing.
+ </p></dd><dt id="LIBPQ-CONNECT-SSL-MAX-PROTOCOL-VERSION"><span class="term"><code class="literal">ssl_max_protocol_version</code></span></dt><dd><p>
+ This parameter specifies the maximum SSL/TLS protocol version to allow
+ for the connection. Valid values are <code class="literal">TLSv1</code>,
+ <code class="literal">TLSv1.1</code>, <code class="literal">TLSv1.2</code> and
+ <code class="literal">TLSv1.3</code>. The supported protocols depend on the
+ version of <span class="productname">OpenSSL</span> used, older versions
+ not supporting the most modern protocol versions. If not set, this
+ parameter is ignored and the connection will use the maximum bound
+ defined by the backend, if set. Setting the maximum protocol version
+ is mainly useful for testing or if some component has issues working
+ with a newer protocol.
+ </p></dd><dt id="LIBPQ-CONNECT-KRBSRVNAME"><span class="term"><code class="literal">krbsrvname</code></span></dt><dd><p>
+ Kerberos service name to use when authenticating with GSSAPI.
+ This must match the service name specified in the server
+ configuration for Kerberos authentication to succeed. (See also
+ <a class="xref" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Section 21.6</a>.)
+ The default value is normally <code class="literal">postgres</code>,
+ but that can be changed when
+ building <span class="productname">PostgreSQL</span> via
+ the <code class="option">--with-krb-srvnam</code> option
+ of <span class="application">configure</span>.
+ In most environments, this parameter never needs to be changed.
+ Some Kerberos implementations might require a different service name,
+ such as Microsoft Active Directory which requires the service name
+ to be in upper case (<code class="literal">POSTGRES</code>).
+ </p></dd><dt id="LIBPQ-CONNECT-GSSLIB"><span class="term"><code class="literal">gsslib</code></span></dt><dd><p>
+ GSS library to use for GSSAPI authentication.
+ Currently this is disregarded except on Windows builds that include
+ both GSSAPI and SSPI support. In that case, set
+ this to <code class="literal">gssapi</code> to cause libpq to use the GSSAPI
+ library for authentication instead of the default SSPI.
+ </p></dd><dt id="LIBPQ-CONNECT-SERVICE"><span class="term"><code class="literal">service</code></span></dt><dd><p>
+ Service name to use for additional parameters. It specifies a service
+ name in <code class="filename">pg_service.conf</code> that holds additional connection parameters.
+ This allows applications to specify only a service name so connection parameters
+ can be centrally maintained. See <a class="xref" href="libpq-pgservice.html" title="34.17. The Connection Service File">Section 34.17</a>.
+ </p></dd><dt id="LIBPQ-CONNECT-TARGET-SESSION-ATTRS"><span class="term"><code class="literal">target_session_attrs</code></span></dt><dd><p>
+ This option determines whether the session must have certain
+ properties to be acceptable. It's typically used in combination
+ with multiple host names to select the first acceptable alternative
+ among several hosts. There are six modes:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">any</code> (default)</span></dt><dd><p>
+ any successful connection is acceptable
+ </p></dd><dt><span class="term"><code class="literal">read-write</code></span></dt><dd><p>
+ session must accept read-write transactions by default (that
+ is, the server must not be in hot standby mode and
+ the <code class="varname">default_transaction_read_only</code> parameter
+ must be <code class="literal">off</code>)
+ </p></dd><dt><span class="term"><code class="literal">read-only</code></span></dt><dd><p>
+ session must not accept read-write transactions by default (the
+ converse)
+ </p></dd><dt><span class="term"><code class="literal">primary</code></span></dt><dd><p>
+ server must not be in hot standby mode
+ </p></dd><dt><span class="term"><code class="literal">standby</code></span></dt><dd><p>
+ server must be in hot standby mode
+ </p></dd><dt><span class="term"><code class="literal">prefer-standby</code></span></dt><dd><p>
+ first try to find a standby server, but if none of the listed
+ hosts is a standby server, try again in <code class="literal">any</code>
+ mode
+ </p></dd></dl></div><p>
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq.html" title="Chapter 34. libpq — C Library">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-status.html" title="34.2. Connection Status Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 34. <span class="application">libpq</span> — C Library </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.2. Connection Status Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-control.html b/doc/src/sgml/html/libpq-control.html
new file mode 100644
index 0000000..e84637b
--- /dev/null
+++ b/doc/src/sgml/html/libpq-control.html
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.11. Control Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-copy.html" title="34.10. Functions Associated with the COPY Command" /><link rel="next" href="libpq-misc.html" title="34.12. Miscellaneous Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.11. Control Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-copy.html" title="34.10. Functions Associated with the COPY Command">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-misc.html" title="34.12. Miscellaneous Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-CONTROL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.11. Control Functions</h2></div></div></div><p>
+ These functions control miscellaneous details of <span class="application">libpq</span>'s
+ behavior.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQCLIENTENCODING"><span class="term"><code class="function">PQclientEncoding</code><a id="id-1.7.3.18.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the client encoding.
+</p><pre class="synopsis">
+int PQclientEncoding(const PGconn *<em class="replaceable"><code>conn</code></em>);
+</pre><p>
+
+ Note that it returns the encoding ID, not a symbolic string
+ such as <code class="literal">EUC_JP</code>. If unsuccessful, it returns -1.
+ To convert an encoding ID to an encoding name, you
+ can use:
+
+</p><pre class="synopsis">
+char *pg_encoding_to_char(int <em class="replaceable"><code>encoding_id</code></em>);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQSETCLIENTENCODING"><span class="term"><code class="function">PQsetClientEncoding</code><a id="id-1.7.3.18.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sets the client encoding.
+</p><pre class="synopsis">
+int PQsetClientEncoding(PGconn *<em class="replaceable"><code>conn</code></em>, const char *<em class="replaceable"><code>encoding</code></em>);
+</pre><p>
+
+ <em class="replaceable"><code>conn</code></em> is a connection to the server,
+ and <em class="replaceable"><code>encoding</code></em> is the encoding you want to
+ use. If the function successfully sets the encoding, it returns 0,
+ otherwise -1. The current encoding for this connection can be
+ determined by using <a class="xref" href="libpq-control.html#LIBPQ-PQCLIENTENCODING"><code class="function">PQclientEncoding</code></a>.
+ </p></dd><dt id="LIBPQ-PQSETERRORVERBOSITY"><span class="term"><code class="function">PQsetErrorVerbosity</code><a id="id-1.7.3.18.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Determines the verbosity of messages returned by
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> and <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a>.
+</p><pre class="synopsis">
+typedef enum
+{
+ PQERRORS_TERSE,
+ PQERRORS_DEFAULT,
+ PQERRORS_VERBOSE,
+ PQERRORS_SQLSTATE
+} PGVerbosity;
+
+PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
+</pre><p>
+
+ <a class="xref" href="libpq-control.html#LIBPQ-PQSETERRORVERBOSITY"><code class="function">PQsetErrorVerbosity</code></a> sets the verbosity mode,
+ returning the connection's previous setting.
+ In <em class="firstterm">TERSE</em> mode, returned messages include
+ severity, primary text, and position only; this will normally fit on a
+ single line. The <em class="firstterm">DEFAULT</em> mode produces messages
+ that include the above plus any detail, hint, or context fields (these
+ might span multiple lines). The <em class="firstterm">VERBOSE</em> mode
+ includes all available fields. The <em class="firstterm">SQLSTATE</em>
+ mode includes only the error severity and the <code class="symbol">SQLSTATE</code>
+ error code, if one is available (if not, the output is like
+ <em class="firstterm">TERSE</em> mode).
+ </p><p>
+ Changing the verbosity setting does not affect the messages available
+ from already-existing <code class="structname">PGresult</code> objects, only
+ subsequently-created ones.
+ (But see <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTVERBOSEERRORMESSAGE"><code class="function">PQresultVerboseErrorMessage</code></a> if you
+ want to print a previous error with a different verbosity.)
+ </p></dd><dt id="LIBPQ-PQSETERRORCONTEXTVISIBILITY"><span class="term"><code class="function">PQsetErrorContextVisibility</code><a id="id-1.7.3.18.3.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Determines the handling of <code class="literal">CONTEXT</code> fields in messages
+ returned by <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a>
+ and <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a>.
+</p><pre class="synopsis">
+typedef enum
+{
+ PQSHOW_CONTEXT_NEVER,
+ PQSHOW_CONTEXT_ERRORS,
+ PQSHOW_CONTEXT_ALWAYS
+} PGContextVisibility;
+
+PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context);
+</pre><p>
+
+ <a class="xref" href="libpq-control.html#LIBPQ-PQSETERRORCONTEXTVISIBILITY"><code class="function">PQsetErrorContextVisibility</code></a> sets the context display mode,
+ returning the connection's previous setting. This mode controls
+ whether the <code class="literal">CONTEXT</code> field is included in messages.
+ The <em class="firstterm">NEVER</em> mode
+ never includes <code class="literal">CONTEXT</code>, while <em class="firstterm">ALWAYS</em> always
+ includes it if available. In <em class="firstterm">ERRORS</em> mode (the
+ default), <code class="literal">CONTEXT</code> fields are included only in error
+ messages, not in notices and warnings.
+ (However, if the verbosity setting is <em class="firstterm">TERSE</em>
+ or <em class="firstterm">SQLSTATE</em>, <code class="literal">CONTEXT</code> fields
+ are omitted regardless of the context display mode.)
+ </p><p>
+ Changing this mode does not
+ affect the messages available from
+ already-existing <code class="structname">PGresult</code> objects, only
+ subsequently-created ones.
+ (But see <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTVERBOSEERRORMESSAGE"><code class="function">PQresultVerboseErrorMessage</code></a> if you
+ want to print a previous error with a different display mode.)
+ </p></dd><dt id="LIBPQ-PQTRACE"><span class="term"><code class="function">PQtrace</code><a id="id-1.7.3.18.3.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Enables tracing of the client/server communication to a debugging file
+ stream.
+</p><pre class="synopsis">
+void PQtrace(PGconn *conn, FILE *stream);
+</pre><p>
+ </p><p>
+ Each line consists of: an optional timestamp, a direction indicator
+ (<code class="literal">F</code> for messages from client to server
+ or <code class="literal">B</code> for messages from server to client),
+ message length, message type, and message contents.
+ Non-message contents fields (timestamp, direction, length and message type)
+ are separated by a tab. Message contents are separated by a space.
+ Protocol strings are enclosed in double quotes, while strings used as data
+ values are enclosed in single quotes. Non-printable chars are printed as
+ hexadecimal escapes.
+ Further message-type-specific detail can be found in
+ <a class="xref" href="protocol-message-formats.html" title="55.7. Message Formats">Section 55.7</a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ On Windows, if the <span class="application">libpq</span> library and an application are
+ compiled with different flags, this function call will crash the
+ application because the internal representation of the <code class="literal">FILE</code>
+ pointers differ. Specifically, multithreaded/single-threaded,
+ release/debug, and static/dynamic flags should be the same for the
+ library and all applications using that library.
+ </p></div></dd><dt id="LIBPQ-PQSETTRACEFLAGS"><span class="term"><code class="function">PQsetTraceFlags</code><a id="id-1.7.3.18.3.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Controls the tracing behavior of client/server communication.
+</p><pre class="synopsis">
+void PQsetTraceFlags(PGconn *conn, int flags);
+</pre><p>
+ </p><p>
+ <code class="literal">flags</code> contains flag bits describing the operating mode
+ of tracing.
+ If <code class="literal">flags</code> contains <code class="literal">PQTRACE_SUPPRESS_TIMESTAMPS</code>,
+ then the timestamp is not included when printing each message.
+ If <code class="literal">flags</code> contains <code class="literal">PQTRACE_REGRESS_MODE</code>,
+ then some fields are redacted when printing each message, such as object
+ OIDs, to make the output more convenient to use in testing frameworks.
+ This function must be called after calling <code class="function">PQtrace</code>.
+ </p></dd><dt id="LIBPQ-PQUNTRACE"><span class="term"><code class="function">PQuntrace</code><a id="id-1.7.3.18.3.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Disables tracing started by <a class="xref" href="libpq-control.html#LIBPQ-PQTRACE"><code class="function">PQtrace</code></a>.
+</p><pre class="synopsis">
+void PQuntrace(PGconn *conn);
+</pre><p>
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-copy.html" title="34.10. Functions Associated with the COPY Command">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-misc.html" title="34.12. Miscellaneous Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.10. Functions Associated with the <code class="command">COPY</code> Command </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.12. Miscellaneous Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-copy.html b/doc/src/sgml/html/libpq-copy.html
new file mode 100644
index 0000000..c643ee6
--- /dev/null
+++ b/doc/src/sgml/html/libpq-copy.html
@@ -0,0 +1,300 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.10. Functions Associated with the COPY Command</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-notify.html" title="34.9. Asynchronous Notification" /><link rel="next" href="libpq-control.html" title="34.11. Control Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.10. Functions Associated with the <code class="command">COPY</code> Command</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-notify.html" title="34.9. Asynchronous Notification">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-control.html" title="34.11. Control Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-COPY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.10. Functions Associated with the <code class="command">COPY</code> Command</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-SEND">34.10.1. Functions for Sending <code class="command">COPY</code> Data</a></span></dt><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-RECEIVE">34.10.2. Functions for Receiving <code class="command">COPY</code> Data</a></span></dt><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">34.10.3. Obsolete Functions for <code class="command">COPY</code></a></span></dt></dl></div><a id="id-1.7.3.17.2" class="indexterm"></a><p>
+ The <code class="command">COPY</code> command in
+ <span class="productname">PostgreSQL</span> has options to read from or write
+ to the network connection used by <span class="application">libpq</span>.
+ The functions described in this section allow applications to take
+ advantage of this capability by supplying or consuming copied data.
+ </p><p>
+ The overall process is that the application first issues the SQL
+ <code class="command">COPY</code> command via <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> or one
+ of the equivalent functions. The response to this (if there is no
+ error in the command) will be a <code class="structname">PGresult</code> object bearing
+ a status code of <code class="literal">PGRES_COPY_OUT</code> or
+ <code class="literal">PGRES_COPY_IN</code> (depending on the specified copy
+ direction). The application should then use the functions of this
+ section to receive or transmit data rows. When the data transfer is
+ complete, another <code class="structname">PGresult</code> object is returned to indicate
+ success or failure of the transfer. Its status will be
+ <code class="literal">PGRES_COMMAND_OK</code> for success or
+ <code class="literal">PGRES_FATAL_ERROR</code> if some problem was encountered.
+ At this point further SQL commands can be issued via
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>. (It is not possible to execute other SQL
+ commands using the same connection while the <code class="command">COPY</code>
+ operation is in progress.)
+ </p><p>
+ If a <code class="command">COPY</code> command is issued via
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> in a string that could contain additional
+ commands, the application must continue fetching results via
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> after completing the <code class="command">COPY</code>
+ sequence. Only when <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> returns
+ <code class="symbol">NULL</code> is it certain that the <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>
+ command string is done and it is safe to issue more commands.
+ </p><p>
+ The functions of this section should be executed only after obtaining
+ a result status of <code class="literal">PGRES_COPY_OUT</code> or
+ <code class="literal">PGRES_COPY_IN</code> from <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> or
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>.
+ </p><p>
+ A <code class="structname">PGresult</code> object bearing one of these status values
+ carries some additional data about the <code class="command">COPY</code> operation
+ that is starting. This additional data is available using functions
+ that are also used in connection with query results:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQNFIELDS-1"><span class="term"><code class="function">PQnfields</code><a id="id-1.7.3.17.7.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the number of columns (fields) to be copied.
+ </p></dd><dt id="LIBPQ-PQBINARYTUPLES-1"><span class="term"><code class="function">PQbinaryTuples</code><a id="id-1.7.3.17.7.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ 0 indicates the overall copy format is textual (rows separated by
+ newlines, columns separated by separator characters, etc.). 1
+ indicates the overall copy format is binary. See <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for more information.
+ </p></dd><dt id="LIBPQ-PQFFORMAT-1"><span class="term"><code class="function">PQfformat</code><a id="id-1.7.3.17.7.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the format code (0 for text, 1 for binary) associated with
+ each column of the copy operation. The per-column format codes
+ will always be zero when the overall copy format is textual, but
+ the binary format can support both text and binary columns.
+ (However, as of the current implementation of <code class="command">COPY</code>,
+ only binary columns appear in a binary copy; so the per-column
+ formats always match the overall format at present.)
+ </p></dd></dl></div><p>
+ </p><div class="sect2" id="LIBPQ-COPY-SEND"><div class="titlepage"><div><div><h3 class="title">34.10.1. Functions for Sending <code class="command">COPY</code> Data</h3></div></div></div><p>
+ These functions are used to send data during <code class="literal">COPY FROM
+ STDIN</code>. They will fail if called when the connection is not in
+ <code class="literal">COPY_IN</code> state.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQPUTCOPYDATA"><span class="term"><code class="function">PQputCopyData</code><a id="id-1.7.3.17.8.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends data to the server during <code class="literal">COPY_IN</code> state.
+</p><pre class="synopsis">
+int PQputCopyData(PGconn *conn,
+ const char *buffer,
+ int nbytes);
+</pre><p>
+ </p><p>
+ Transmits the <code class="command">COPY</code> data in the specified
+ <em class="parameter"><code>buffer</code></em>, of length <em class="parameter"><code>nbytes</code></em>, to the server.
+ The result is 1 if the data was queued, zero if it was not queued
+ because of full buffers (this will only happen in nonblocking mode),
+ or -1 if an error occurred.
+ (Use <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to retrieve details if
+ the return value is -1. If the value is zero, wait for write-ready
+ and try again.)
+ </p><p>
+ The application can divide the <code class="command">COPY</code> data stream
+ into buffer loads of any convenient size. Buffer-load boundaries
+ have no semantic significance when sending. The contents of the
+ data stream must match the data format expected by the
+ <code class="command">COPY</code> command; see <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for details.
+ </p></dd><dt id="LIBPQ-PQPUTCOPYEND"><span class="term"><code class="function">PQputCopyEnd</code><a id="id-1.7.3.17.8.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends end-of-data indication to the server during <code class="literal">COPY_IN</code> state.
+</p><pre class="synopsis">
+int PQputCopyEnd(PGconn *conn,
+ const char *errormsg);
+</pre><p>
+ </p><p>
+ Ends the <code class="literal">COPY_IN</code> operation successfully if
+ <em class="parameter"><code>errormsg</code></em> is <code class="symbol">NULL</code>. If
+ <em class="parameter"><code>errormsg</code></em> is not <code class="symbol">NULL</code> then the
+ <code class="command">COPY</code> is forced to fail, with the string pointed to by
+ <em class="parameter"><code>errormsg</code></em> used as the error message. (One should not
+ assume that this exact error message will come back from the server,
+ however, as the server might have already failed the
+ <code class="command">COPY</code> for its own reasons.)
+ </p><p>
+ The result is 1 if the termination message was sent; or in
+ nonblocking mode, this may only indicate that the termination
+ message was successfully queued. (In nonblocking mode, to be
+ certain that the data has been sent, you should next wait for
+ write-ready and call <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a>, repeating until it
+ returns zero.) Zero indicates that the function could not queue
+ the termination message because of full buffers; this will only
+ happen in nonblocking mode. (In this case, wait for
+ write-ready and try the <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTCOPYEND"><code class="function">PQputCopyEnd</code></a> call
+ again.) If a hard error occurs, -1 is returned; you can use
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to retrieve details.
+ </p><p>
+ After successfully calling <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTCOPYEND"><code class="function">PQputCopyEnd</code></a>, call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to obtain the final result status of the
+ <code class="command">COPY</code> command. One can wait for this result to be
+ available in the usual way. Then return to normal operation.
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-COPY-RECEIVE"><div class="titlepage"><div><div><h3 class="title">34.10.2. Functions for Receiving <code class="command">COPY</code> Data</h3></div></div></div><p>
+ These functions are used to receive data during <code class="literal">COPY TO
+ STDOUT</code>. They will fail if called when the connection is not in
+ <code class="literal">COPY_OUT</code> state.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQGETCOPYDATA"><span class="term"><code class="function">PQgetCopyData</code><a id="id-1.7.3.17.9.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Receives data from the server during <code class="literal">COPY_OUT</code> state.
+</p><pre class="synopsis">
+int PQgetCopyData(PGconn *conn,
+ char **buffer,
+ int async);
+</pre><p>
+ </p><p>
+ Attempts to obtain another row of data from the server during a
+ <code class="command">COPY</code>. Data is always returned one data row at
+ a time; if only a partial row is available, it is not returned.
+ Successful return of a data row involves allocating a chunk of
+ memory to hold the data. The <em class="parameter"><code>buffer</code></em> parameter must
+ be non-<code class="symbol">NULL</code>. <em class="parameter"><code>*buffer</code></em> is set to
+ point to the allocated memory, or to <code class="symbol">NULL</code> in cases
+ where no buffer is returned. A non-<code class="symbol">NULL</code> result
+ buffer should be freed using <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a> when no longer
+ needed.
+ </p><p>
+ When a row is successfully returned, the return value is the number
+ of data bytes in the row (this will always be greater than zero).
+ The returned string is always null-terminated, though this is
+ probably only useful for textual <code class="command">COPY</code>. A result
+ of zero indicates that the <code class="command">COPY</code> is still in
+ progress, but no row is yet available (this is only possible when
+ <em class="parameter"><code>async</code></em> is true). A result of -1 indicates that the
+ <code class="command">COPY</code> is done. A result of -2 indicates that an
+ error occurred (consult <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> for the reason).
+ </p><p>
+ When <em class="parameter"><code>async</code></em> is true (not zero),
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> will not block waiting for input; it
+ will return zero if the <code class="command">COPY</code> is still in progress
+ but no complete row is available. (In this case wait for read-ready
+ and then call <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> before calling
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> again.) When <em class="parameter"><code>async</code></em> is
+ false (zero), <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> will block until data is
+ available or the operation completes.
+ </p><p>
+ After <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> returns -1, call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to obtain the final result status of the
+ <code class="command">COPY</code> command. One can wait for this result to be
+ available in the usual way. Then return to normal operation.
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-COPY-DEPRECATED"><div class="titlepage"><div><div><h3 class="title">34.10.3. Obsolete Functions for <code class="command">COPY</code></h3></div></div></div><p>
+ These functions represent older methods of handling <code class="command">COPY</code>.
+ Although they still work, they are deprecated due to poor error handling,
+ inconvenient methods of detecting end-of-data, and lack of support for binary
+ or nonblocking transfers.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQGETLINE"><span class="term"><code class="function">PQgetline</code><a id="id-1.7.3.17.10.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Reads a newline-terminated line of characters (transmitted
+ by the server) into a buffer string of size <em class="parameter"><code>length</code></em>.
+</p><pre class="synopsis">
+int PQgetline(PGconn *conn,
+ char *buffer,
+ int length);
+</pre><p>
+ </p><p>
+ This function copies up to <em class="parameter"><code>length</code></em>-1 characters into
+ the buffer and converts the terminating newline into a zero byte.
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a> returns <code class="symbol">EOF</code> at the
+ end of input, 0 if the entire line has been read, and 1 if the
+ buffer is full but the terminating newline has not yet been read.
+ </p><p>
+ Note that the application must check to see if a new line consists
+ of the two characters <code class="literal">\.</code>, which indicates
+ that the server has finished sending the results of the
+ <code class="command">COPY</code> command. If the application might receive
+ lines that are more than <em class="parameter"><code>length</code></em>-1 characters long,
+ care is needed to be sure it recognizes the <code class="literal">\.</code>
+ line correctly (and does not, for example, mistake the end of a
+ long data line for a terminator line).
+ </p></dd><dt id="LIBPQ-PQGETLINEASYNC"><span class="term"><code class="function">PQgetlineAsync</code><a id="id-1.7.3.17.10.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Reads a row of <code class="command">COPY</code> data (transmitted by the
+ server) into a buffer without blocking.
+</p><pre class="synopsis">
+int PQgetlineAsync(PGconn *conn,
+ char *buffer,
+ int bufsize);
+</pre><p>
+ </p><p>
+ This function is similar to <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a>, but it can be used
+ by applications
+ that must read <code class="command">COPY</code> data asynchronously, that is, without blocking.
+ Having issued the <code class="command">COPY</code> command and gotten a <code class="literal">PGRES_COPY_OUT</code>
+ response, the
+ application should call <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> and
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINEASYNC"><code class="function">PQgetlineAsync</code></a> until the
+ end-of-data signal is detected.
+ </p><p>
+ Unlike <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a>, this function takes
+ responsibility for detecting end-of-data.
+ </p><p>
+ On each call, <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINEASYNC"><code class="function">PQgetlineAsync</code></a> will return data if a
+ complete data row is available in <span class="application">libpq</span>'s input buffer.
+ Otherwise, no data is returned until the rest of the row arrives.
+ The function returns -1 if the end-of-copy-data marker has been recognized,
+ or 0 if no data is available, or a positive number giving the number of
+ bytes of data returned. If -1 is returned, the caller must next call
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a>, and then return to normal processing.
+ </p><p>
+ The data returned will not extend beyond a data-row boundary. If possible
+ a whole row will be returned at one time. But if the buffer offered by
+ the caller is too small to hold a row sent by the server, then a partial
+ data row will be returned. With textual data this can be detected by testing
+ whether the last returned byte is <code class="literal">\n</code> or not. (In a binary
+ <code class="command">COPY</code>, actual parsing of the <code class="command">COPY</code> data format will be needed to make the
+ equivalent determination.)
+ The returned string is not null-terminated. (If you want to add a
+ terminating null, be sure to pass a <em class="parameter"><code>bufsize</code></em> one smaller
+ than the room actually available.)
+ </p></dd><dt id="LIBPQ-PQPUTLINE"><span class="term"><code class="function">PQputline</code><a id="id-1.7.3.17.10.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends a null-terminated string to the server. Returns 0 if
+ OK and <code class="symbol">EOF</code> if unable to send the string.
+</p><pre class="synopsis">
+int PQputline(PGconn *conn,
+ const char *string);
+</pre><p>
+ </p><p>
+ The <code class="command">COPY</code> data stream sent by a series of calls
+ to <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> has the same format as that
+ returned by <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINEASYNC"><code class="function">PQgetlineAsync</code></a>, except that
+ applications are not obliged to send exactly one data row per
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> call; it is okay to send a partial
+ line or multiple lines per call.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> protocol 3.0, it was necessary
+ for the application to explicitly send the two characters
+ <code class="literal">\.</code> as a final line to indicate to the server that it had
+ finished sending <code class="command">COPY</code> data. While this still works, it is deprecated and the
+ special meaning of <code class="literal">\.</code> can be expected to be removed in a
+ future release. It is sufficient to call <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a> after
+ having sent the actual data.
+ </p></div></dd><dt id="LIBPQ-PQPUTNBYTES"><span class="term"><code class="function">PQputnbytes</code><a id="id-1.7.3.17.10.3.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends a non-null-terminated string to the server. Returns
+ 0 if OK and <code class="symbol">EOF</code> if unable to send the string.
+</p><pre class="synopsis">
+int PQputnbytes(PGconn *conn,
+ const char *buffer,
+ int nbytes);
+</pre><p>
+ </p><p>
+ This is exactly like <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a>, except that the data
+ buffer need not be null-terminated since the number of bytes to send is
+ specified directly. Use this procedure when sending binary data.
+ </p></dd><dt id="LIBPQ-PQENDCOPY"><span class="term"><code class="function">PQendcopy</code><a id="id-1.7.3.17.10.3.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Synchronizes with the server.
+</p><pre class="synopsis">
+int PQendcopy(PGconn *conn);
+</pre><p>
+ This function waits until the server has finished the copying.
+ It should either be issued when the last string has been sent
+ to the server using <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> or when the
+ last string has been received from the server using
+ <code class="function">PQgetline</code>. It must be issued or the server
+ will get <span class="quote">“<span class="quote">out of sync</span>”</span> with the client. Upon return
+ from this function, the server is ready to receive the next SQL
+ command. The return value is 0 on successful completion,
+ nonzero otherwise. (Use <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to
+ retrieve details if the return value is nonzero.)
+ </p><p>
+ When using <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>, the application should
+ respond to a <code class="literal">PGRES_COPY_OUT</code> result by executing
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a> repeatedly, followed by
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a> after the terminator line is seen.
+ It should then return to the <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> loop
+ until <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> returns a null pointer.
+ Similarly a <code class="literal">PGRES_COPY_IN</code> result is processed
+ by a series of <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> calls followed by
+ <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a>, then return to the
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> loop. This arrangement will
+ ensure that a <code class="command">COPY</code> command embedded in a series
+ of <acronym class="acronym">SQL</acronym> commands will be executed correctly.
+ </p><p>
+ Older applications are likely to submit a <code class="command">COPY</code>
+ via <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> and assume that the transaction
+ is done after <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a>. This will work
+ correctly only if the <code class="command">COPY</code> is the only
+ <acronym class="acronym">SQL</acronym> command in the command string.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-notify.html" title="34.9. Asynchronous Notification">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-control.html" title="34.11. Control Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.9. Asynchronous Notification </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.11. Control Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-envars.html b/doc/src/sgml/html/libpq-envars.html
new file mode 100644
index 0000000..c039c5f
--- /dev/null
+++ b/doc/src/sgml/html/libpq-envars.html
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.15. Environment Variables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-events.html" title="34.14. Event System" /><link rel="next" href="libpq-pgpass.html" title="34.16. The Password File" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.15. Environment Variables</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-events.html" title="34.14. Event System">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-pgpass.html" title="34.16. The Password File">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-ENVARS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.15. Environment Variables</h2></div></div></div><a id="id-1.7.3.22.2" class="indexterm"></a><p>
+ The following environment variables can be used to select default
+ connection parameter values, which will be used by
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>, <a class="xref" href="libpq-connect.html#LIBPQ-PQSETDBLOGIN"><code class="function">PQsetdbLogin</code></a> and
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQSETDB"><code class="function">PQsetdb</code></a> if no value is directly specified by the calling
+ code. These are useful to avoid hard-coding database connection
+ information into simple client applications, for example.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.1.1.1" class="indexterm"></a>
+ <code class="envar">PGHOST</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-HOST">host</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.2.1.1" class="indexterm"></a>
+ <code class="envar">PGHOSTADDR</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-HOSTADDR">hostaddr</a> connection parameter.
+ This can be set instead of or in addition to <code class="envar">PGHOST</code>
+ to avoid DNS lookup overhead.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.3.1.1" class="indexterm"></a>
+ <code class="envar">PGPORT</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-PORT">port</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.4.1.1" class="indexterm"></a>
+ <code class="envar">PGDATABASE</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-DBNAME">dbname</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.5.1.1" class="indexterm"></a>
+ <code class="envar">PGUSER</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-USER">user</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.6.1.1" class="indexterm"></a>
+ <code class="envar">PGPASSWORD</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-PASSWORD">password</a> connection parameter.
+ Use of this environment variable
+ is not recommended for security reasons, as some operating systems
+ allow non-root users to see process environment variables via
+ <span class="application">ps</span>; instead consider using a password file
+ (see <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a>).
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.7.1.1" class="indexterm"></a>
+ <code class="envar">PGPASSFILE</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-PASSFILE">passfile</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.8.1.1" class="indexterm"></a>
+ <code class="envar">PGCHANNELBINDING</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-CHANNEL-BINDING">channel_binding</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.9.1.1" class="indexterm"></a>
+ <code class="envar">PGSERVICE</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SERVICE">service</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.10.1.1" class="indexterm"></a>
+ <code class="envar">PGSERVICEFILE</code> specifies the name of the per-user
+ connection service file
+ (see <a class="xref" href="libpq-pgservice.html" title="34.17. The Connection Service File">Section 34.17</a>).
+ Defaults to <code class="filename">~/.pg_service.conf</code>, or
+ <code class="filename">%APPDATA%\postgresql\.pg_service.conf</code> on
+ Microsoft Windows.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.11.1.1" class="indexterm"></a>
+ <code class="envar">PGOPTIONS</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-OPTIONS">options</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.12.1.1" class="indexterm"></a>
+ <code class="envar">PGAPPNAME</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-APPLICATION-NAME">application_name</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.13.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLMODE</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLMODE">sslmode</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.14.1.1" class="indexterm"></a>
+ <code class="envar">PGREQUIRESSL</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-REQUIRESSL">requiressl</a> connection parameter.
+ This environment variable is deprecated in favor of the
+ <code class="envar">PGSSLMODE</code> variable; setting both variables suppresses the
+ effect of this one.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.15.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLCOMPRESSION</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLCOMPRESSION">sslcompression</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.16.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLCERT</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLCERT">sslcert</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.17.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLKEY</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLKEY">sslkey</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.18.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLROOTCERT</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLROOTCERT">sslrootcert</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.19.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLCRL</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLCRL">sslcrl</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.20.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLCRLDIR</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLCRLDIR">sslcrldir</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.21.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLSNI</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLSNI">sslsni</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.22.1.1" class="indexterm"></a>
+ <code class="envar">PGREQUIREPEER</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-REQUIREPEER">requirepeer</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.23.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLMINPROTOCOLVERSION</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSL-MIN-PROTOCOL-VERSION">ssl_min_protocol_version</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.24.1.1" class="indexterm"></a>
+ <code class="envar">PGSSLMAXPROTOCOLVERSION</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSL-MAX-PROTOCOL-VERSION">ssl_max_protocol_version</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.25.1.1" class="indexterm"></a>
+ <code class="envar">PGGSSENCMODE</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-GSSENCMODE">gssencmode</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.26.1.1" class="indexterm"></a>
+ <code class="envar">PGKRBSRVNAME</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-KRBSRVNAME">krbsrvname</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.27.1.1" class="indexterm"></a>
+ <code class="envar">PGGSSLIB</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-GSSLIB">gsslib</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.28.1.1" class="indexterm"></a>
+ <code class="envar">PGCONNECT_TIMEOUT</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT">connect_timeout</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.29.1.1" class="indexterm"></a>
+ <code class="envar">PGCLIENTENCODING</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-CLIENT-ENCODING">client_encoding</a> connection parameter.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.3.4.30.1.1" class="indexterm"></a>
+ <code class="envar">PGTARGETSESSIONATTRS</code> behaves the same as the <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-TARGET-SESSION-ATTRS">target_session_attrs</a> connection parameter.
+ </p></li></ul></div><p>
+ </p><p>
+ The following environment variables can be used to specify default
+ behavior for each <span class="productname">PostgreSQL</span> session. (See
+ also the <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>
+ and <a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a>
+ commands for ways to set default behavior on a per-user or per-database
+ basis.)
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a id="id-1.7.3.22.4.4.1.1.1" class="indexterm"></a>
+ <code class="envar">PGDATESTYLE</code> sets the default style of date/time
+ representation. (Equivalent to <code class="literal">SET datestyle TO
+ ...</code>.)
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.4.4.2.1.1" class="indexterm"></a>
+ <code class="envar">PGTZ</code> sets the default time zone. (Equivalent to
+ <code class="literal">SET timezone TO ...</code>.)
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.4.4.3.1.1" class="indexterm"></a>
+ <code class="envar">PGGEQO</code> sets the default mode for the genetic query
+ optimizer. (Equivalent to <code class="literal">SET geqo TO ...</code>.)
+ </p></li></ul></div><p>
+
+ Refer to the <acronym class="acronym">SQL</acronym> command <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a>
+ for information on correct values for these
+ environment variables.
+ </p><p>
+ The following environment variables determine internal behavior of
+ <span class="application">libpq</span>; they override compiled-in defaults.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a id="id-1.7.3.22.5.2.1.1.1" class="indexterm"></a>
+ <code class="envar">PGSYSCONFDIR</code> sets the directory containing the
+ <code class="filename">pg_service.conf</code> file and in a future version
+ possibly other system-wide configuration files.
+ </p></li><li class="listitem"><p>
+ <a id="id-1.7.3.22.5.2.2.1.1" class="indexterm"></a>
+ <code class="envar">PGLOCALEDIR</code> sets the directory containing the
+ <code class="literal">locale</code> files for message localization.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-events.html" title="34.14. Event System">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-pgpass.html" title="34.16. The Password File">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.14. Event System </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.16. The Password File</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-events.html b/doc/src/sgml/html/libpq-events.html
new file mode 100644
index 0000000..81c1c2f
--- /dev/null
+++ b/doc/src/sgml/html/libpq-events.html
@@ -0,0 +1,425 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.14. Event System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-notice-processing.html" title="34.13. Notice Processing" /><link rel="next" href="libpq-envars.html" title="34.15. Environment Variables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.14. Event System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-notice-processing.html" title="34.13. Notice Processing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-envars.html" title="34.15. Environment Variables">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-EVENTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.14. Event System</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-TYPES">34.14.1. Event Types</a></span></dt><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-PROC">34.14.2. Event Callback Procedure</a></span></dt><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-FUNCS">34.14.3. Event Support Functions</a></span></dt><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-EXAMPLE">34.14.4. Event Example</a></span></dt></dl></div><p>
+ <span class="application">libpq</span>'s event system is designed to notify
+ registered event handlers about interesting
+ <span class="application">libpq</span> events, such as the creation or
+ destruction of <code class="structname">PGconn</code> and
+ <code class="structname">PGresult</code> objects. A principal use case is that
+ this allows applications to associate their own data with a
+ <code class="structname">PGconn</code> or <code class="structname">PGresult</code>
+ and ensure that that data is freed at an appropriate time.
+ </p><p>
+ Each registered event handler is associated with two pieces of data,
+ known to <span class="application">libpq</span> only as opaque <code class="literal">void *</code>
+ pointers. There is a <em class="firstterm">pass-through</em> pointer that is provided
+ by the application when the event handler is registered with a
+ <code class="structname">PGconn</code>. The pass-through pointer never changes for the
+ life of the <code class="structname">PGconn</code> and all <code class="structname">PGresult</code>s
+ generated from it; so if used, it must point to long-lived data.
+ In addition there is an <em class="firstterm">instance data</em> pointer, which starts
+ out <code class="symbol">NULL</code> in every <code class="structname">PGconn</code> and <code class="structname">PGresult</code>.
+ This pointer can be manipulated using the
+ <a class="xref" href="libpq-events.html#LIBPQ-PQINSTANCEDATA"><code class="function">PQinstanceData</code></a>,
+ <a class="xref" href="libpq-events.html#LIBPQ-PQSETINSTANCEDATA"><code class="function">PQsetInstanceData</code></a>,
+ <a class="xref" href="libpq-events.html#LIBPQ-PQRESULTINSTANCEDATA"><code class="function">PQresultInstanceData</code></a> and
+ <a class="xref" href="libpq-events.html#LIBPQ-PQRESULTSETINSTANCEDATA"><code class="function">PQresultSetInstanceData</code></a> functions. Note that
+ unlike the pass-through pointer, instance data of a <code class="structname">PGconn</code>
+ is not automatically inherited by <code class="structname">PGresult</code>s created from
+ it. <span class="application">libpq</span> does not know what pass-through
+ and instance data pointers point to (if anything) and will never attempt
+ to free them — that is the responsibility of the event handler.
+ </p><div class="sect2" id="LIBPQ-EVENTS-TYPES"><div class="titlepage"><div><div><h3 class="title">34.14.1. Event Types</h3></div></div></div><p>
+ The enum <code class="literal">PGEventId</code> names the types of events handled by
+ the event system. All its values have names beginning with
+ <code class="literal">PGEVT</code>. For each event type, there is a corresponding
+ event info structure that carries the parameters passed to the event
+ handlers. The event types are:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PGEVT-REGISTER"><span class="term"><code class="literal">PGEVT_REGISTER</code></span></dt><dd><p>
+ The register event occurs when <a class="xref" href="libpq-events.html#LIBPQ-PQREGISTEREVENTPROC"><code class="function">PQregisterEventProc</code></a>
+ is called. It is the ideal time to initialize any
+ <code class="literal">instanceData</code> an event procedure may need. Only one
+ register event will be fired per event handler per connection. If the
+ event procedure fails (returns zero), the registration is cancelled.
+
+</p><pre class="synopsis">
+typedef struct
+{
+ PGconn *conn;
+} PGEventRegister;
+</pre><p>
+
+ When a <code class="literal">PGEVT_REGISTER</code> event is received, the
+ <em class="parameter"><code>evtInfo</code></em> pointer should be cast to a
+ <code class="structname">PGEventRegister *</code>. This structure contains a
+ <code class="structname">PGconn</code> that should be in the
+ <code class="literal">CONNECTION_OK</code> status; guaranteed if one calls
+ <a class="xref" href="libpq-events.html#LIBPQ-PQREGISTEREVENTPROC"><code class="function">PQregisterEventProc</code></a> right after obtaining a good
+ <code class="structname">PGconn</code>. When returning a failure code, all
+ cleanup must be performed as no <code class="literal">PGEVT_CONNDESTROY</code>
+ event will be sent.
+ </p></dd><dt id="LIBPQ-PGEVT-CONNRESET"><span class="term"><code class="literal">PGEVT_CONNRESET</code></span></dt><dd><p>
+ The connection reset event is fired on completion of
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQRESET"><code class="function">PQreset</code></a> or <code class="function">PQresetPoll</code>. In
+ both cases, the event is only fired if the reset was successful.
+ The return value of the event procedure is ignored
+ in <span class="productname">PostgreSQL</span> v15 and later.
+ With earlier versions, however, it's important to return success
+ (nonzero) or the connection will be aborted.
+
+</p><pre class="synopsis">
+typedef struct
+{
+ PGconn *conn;
+} PGEventConnReset;
+</pre><p>
+
+ When a <code class="literal">PGEVT_CONNRESET</code> event is received, the
+ <em class="parameter"><code>evtInfo</code></em> pointer should be cast to a
+ <code class="structname">PGEventConnReset *</code>. Although the contained
+ <code class="structname">PGconn</code> was just reset, all event data remains
+ unchanged. This event should be used to reset/reload/requery any
+ associated <code class="literal">instanceData</code>. Note that even if the
+ event procedure fails to process <code class="literal">PGEVT_CONNRESET</code>, it will
+ still receive a <code class="literal">PGEVT_CONNDESTROY</code> event when the connection
+ is closed.
+ </p></dd><dt id="LIBPQ-PGEVT-CONNDESTROY"><span class="term"><code class="literal">PGEVT_CONNDESTROY</code></span></dt><dd><p>
+ The connection destroy event is fired in response to
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a>. It is the event procedure's
+ responsibility to properly clean up its event data as libpq has no
+ ability to manage this memory. Failure to clean up will lead
+ to memory leaks.
+
+</p><pre class="synopsis">
+typedef struct
+{
+ PGconn *conn;
+} PGEventConnDestroy;
+</pre><p>
+
+ When a <code class="literal">PGEVT_CONNDESTROY</code> event is received, the
+ <em class="parameter"><code>evtInfo</code></em> pointer should be cast to a
+ <code class="structname">PGEventConnDestroy *</code>. This event is fired
+ prior to <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a> performing any other cleanup.
+ The return value of the event procedure is ignored since there is no
+ way of indicating a failure from <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a>. Also,
+ an event procedure failure should not abort the process of cleaning up
+ unwanted memory.
+ </p></dd><dt id="LIBPQ-PGEVT-RESULTCREATE"><span class="term"><code class="literal">PGEVT_RESULTCREATE</code></span></dt><dd><p>
+ The result creation event is fired in response to any query execution
+ function that generates a result, including
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>. This event will only be fired after
+ the result has been created successfully.
+
+</p><pre class="synopsis">
+typedef struct
+{
+ PGconn *conn;
+ PGresult *result;
+} PGEventResultCreate;
+</pre><p>
+
+ When a <code class="literal">PGEVT_RESULTCREATE</code> event is received, the
+ <em class="parameter"><code>evtInfo</code></em> pointer should be cast to a
+ <code class="structname">PGEventResultCreate *</code>. The
+ <em class="parameter"><code>conn</code></em> is the connection used to generate the
+ result. This is the ideal place to initialize any
+ <code class="literal">instanceData</code> that needs to be associated with the
+ result. If an event procedure fails (returns zero), that event
+ procedure will be ignored for the remaining lifetime of the result;
+ that is, it will not receive <code class="literal">PGEVT_RESULTCOPY</code>
+ or <code class="literal">PGEVT_RESULTDESTROY</code> events for this result or
+ results copied from it.
+ </p></dd><dt id="LIBPQ-PGEVT-RESULTCOPY"><span class="term"><code class="literal">PGEVT_RESULTCOPY</code></span></dt><dd><p>
+ The result copy event is fired in response to
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQCOPYRESULT"><code class="function">PQcopyResult</code></a>. This event will only be fired after
+ the copy is complete. Only event procedures that have
+ successfully handled the <code class="literal">PGEVT_RESULTCREATE</code>
+ or <code class="literal">PGEVT_RESULTCOPY</code> event for the source result
+ will receive <code class="literal">PGEVT_RESULTCOPY</code> events.
+
+</p><pre class="synopsis">
+typedef struct
+{
+ const PGresult *src;
+ PGresult *dest;
+} PGEventResultCopy;
+</pre><p>
+
+ When a <code class="literal">PGEVT_RESULTCOPY</code> event is received, the
+ <em class="parameter"><code>evtInfo</code></em> pointer should be cast to a
+ <code class="structname">PGEventResultCopy *</code>. The
+ <em class="parameter"><code>src</code></em> result is what was copied while the
+ <em class="parameter"><code>dest</code></em> result is the copy destination. This event
+ can be used to provide a deep copy of <code class="literal">instanceData</code>,
+ since <code class="literal">PQcopyResult</code> cannot do that. If an event
+ procedure fails (returns zero), that event procedure will be
+ ignored for the remaining lifetime of the new result; that is, it
+ will not receive <code class="literal">PGEVT_RESULTCOPY</code>
+ or <code class="literal">PGEVT_RESULTDESTROY</code> events for that result or
+ results copied from it.
+ </p></dd><dt id="LIBPQ-PGEVT-RESULTDESTROY"><span class="term"><code class="literal">PGEVT_RESULTDESTROY</code></span></dt><dd><p>
+ The result destroy event is fired in response to a
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>. It is the event procedure's
+ responsibility to properly clean up its event data as libpq has no
+ ability to manage this memory. Failure to clean up will lead
+ to memory leaks.
+
+</p><pre class="synopsis">
+typedef struct
+{
+ PGresult *result;
+} PGEventResultDestroy;
+</pre><p>
+
+ When a <code class="literal">PGEVT_RESULTDESTROY</code> event is received, the
+ <em class="parameter"><code>evtInfo</code></em> pointer should be cast to a
+ <code class="structname">PGEventResultDestroy *</code>. This event is fired
+ prior to <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> performing any other cleanup.
+ The return value of the event procedure is ignored since there is no
+ way of indicating a failure from <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>. Also,
+ an event procedure failure should not abort the process of cleaning up
+ unwanted memory.
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-EVENTS-PROC"><div class="titlepage"><div><div><h3 class="title">34.14.2. Event Callback Procedure</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PGEVENTPROC"><span class="term"><code class="literal">PGEventProc</code><a id="id-1.7.3.21.5.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ <code class="literal">PGEventProc</code> is a typedef for a pointer to an
+ event procedure, that is, the user callback function that receives
+ events from libpq. The signature of an event procedure must be
+
+</p><pre class="synopsis">
+int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)
+</pre><p>
+
+ The <em class="parameter"><code>evtId</code></em> parameter indicates which
+ <code class="literal">PGEVT</code> event occurred. The
+ <em class="parameter"><code>evtInfo</code></em> pointer must be cast to the appropriate
+ structure type to obtain further information about the event.
+ The <em class="parameter"><code>passThrough</code></em> parameter is the pointer
+ provided to <a class="xref" href="libpq-events.html#LIBPQ-PQREGISTEREVENTPROC"><code class="function">PQregisterEventProc</code></a> when the event
+ procedure was registered. The function should return a non-zero value
+ if it succeeds and zero if it fails.
+ </p><p>
+ A particular event procedure can be registered only once in any
+ <code class="structname">PGconn</code>. This is because the address of the procedure
+ is used as a lookup key to identify the associated instance data.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ On Windows, functions can have two different addresses: one visible
+ from outside a DLL and another visible from inside the DLL. One
+ should be careful that only one of these addresses is used with
+ <span class="application">libpq</span>'s event-procedure functions, else confusion will
+ result. The simplest rule for writing code that will work is to
+ ensure that event procedures are declared <code class="literal">static</code>. If the
+ procedure's address must be available outside its own source file,
+ expose a separate function to return the address.
+ </p></div></dd></dl></div></div><div class="sect2" id="LIBPQ-EVENTS-FUNCS"><div class="titlepage"><div><div><h3 class="title">34.14.3. Event Support Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQREGISTEREVENTPROC"><span class="term"><code class="function">PQregisterEventProc</code><a id="id-1.7.3.21.6.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Registers an event callback procedure with libpq.
+
+</p><pre class="synopsis">
+int PQregisterEventProc(PGconn *conn, PGEventProc proc,
+ const char *name, void *passThrough);
+</pre><p>
+ </p><p>
+ An event procedure must be registered once on each
+ <code class="structname">PGconn</code> you want to receive events about. There is no
+ limit, other than memory, on the number of event procedures that
+ can be registered with a connection. The function returns a non-zero
+ value if it succeeds and zero if it fails.
+ </p><p>
+ The <em class="parameter"><code>proc</code></em> argument will be called when a libpq
+ event is fired. Its memory address is also used to lookup
+ <code class="literal">instanceData</code>. The <em class="parameter"><code>name</code></em>
+ argument is used to refer to the event procedure in error messages.
+ This value cannot be <code class="symbol">NULL</code> or a zero-length string. The name string is
+ copied into the <code class="structname">PGconn</code>, so what is passed need not be
+ long-lived. The <em class="parameter"><code>passThrough</code></em> pointer is passed
+ to the <em class="parameter"><code>proc</code></em> whenever an event occurs. This
+ argument can be <code class="symbol">NULL</code>.
+ </p></dd><dt id="LIBPQ-PQSETINSTANCEDATA"><span class="term"><code class="function">PQsetInstanceData</code><a id="id-1.7.3.21.6.2.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sets the connection <em class="parameter"><code>conn</code></em>'s <code class="literal">instanceData</code>
+ for procedure <em class="parameter"><code>proc</code></em> to <em class="parameter"><code>data</code></em>. This
+ returns non-zero for success and zero for failure. (Failure is
+ only possible if <em class="parameter"><code>proc</code></em> has not been properly
+ registered in <em class="parameter"><code>conn</code></em>.)
+
+</p><pre class="synopsis">
+int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQINSTANCEDATA"><span class="term"><code class="function">PQinstanceData</code><a id="id-1.7.3.21.6.2.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the
+ connection <em class="parameter"><code>conn</code></em>'s <code class="literal">instanceData</code>
+ associated with procedure <em class="parameter"><code>proc</code></em>,
+ or <code class="symbol">NULL</code> if there is none.
+
+</p><pre class="synopsis">
+void *PQinstanceData(const PGconn *conn, PGEventProc proc);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQRESULTSETINSTANCEDATA"><span class="term"><code class="function">PQresultSetInstanceData</code><a id="id-1.7.3.21.6.2.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sets the result's <code class="literal">instanceData</code>
+ for <em class="parameter"><code>proc</code></em> to <em class="parameter"><code>data</code></em>. This returns
+ non-zero for success and zero for failure. (Failure is only
+ possible if <em class="parameter"><code>proc</code></em> has not been properly registered
+ in the result.)
+
+</p><pre class="synopsis">
+int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);
+</pre><p>
+ </p><p>
+ Beware that any storage represented by <em class="parameter"><code>data</code></em>
+ will not be accounted for by <a class="xref" href="libpq-misc.html#LIBPQ-PQRESULTMEMORYSIZE"><code class="function">PQresultMemorySize</code></a>,
+ unless it is allocated using <a class="xref" href="libpq-misc.html#LIBPQ-PQRESULTALLOC"><code class="function">PQresultAlloc</code></a>.
+ (Doing so is recommendable because it eliminates the need to free
+ such storage explicitly when the result is destroyed.)
+ </p></dd><dt id="LIBPQ-PQRESULTINSTANCEDATA"><span class="term"><code class="function">PQresultInstanceData</code><a id="id-1.7.3.21.6.2.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the result's <code class="literal">instanceData</code> associated with <em class="parameter"><code>proc</code></em>, or <code class="symbol">NULL</code>
+ if there is none.
+
+</p><pre class="synopsis">
+void *PQresultInstanceData(const PGresult *res, PGEventProc proc);
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-EVENTS-EXAMPLE"><div class="titlepage"><div><div><h3 class="title">34.14.4. Event Example</h3></div></div></div><p>
+ Here is a skeleton example of managing private data associated with
+ libpq connections and results.
+ </p><pre class="programlisting">
+
+/* required header for libpq events (note: includes libpq-fe.h) */
+#include &lt;libpq-events.h&gt;
+
+/* The instanceData */
+typedef struct
+{
+ int n;
+ char *str;
+} mydata;
+
+/* PGEventProc */
+static int myEventProc(PGEventId evtId, void *evtInfo, void *passThrough);
+
+int
+main(void)
+{
+ mydata *data;
+ PGresult *res;
+ PGconn *conn =
+ PQconnectdb("dbname=postgres options=-csearch_path=");
+
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ /* PQerrorMessage's result includes a trailing newline */
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ PQfinish(conn);
+ return 1;
+ }
+
+ /* called once on any connection that should receive events.
+ * Sends a PGEVT_REGISTER to myEventProc.
+ */
+ if (!PQregisterEventProc(conn, myEventProc, "mydata_proc", NULL))
+ {
+ fprintf(stderr, "Cannot register PGEventProc\n");
+ PQfinish(conn);
+ return 1;
+ }
+
+ /* conn instanceData is available */
+ data = PQinstanceData(conn, myEventProc);
+
+ /* Sends a PGEVT_RESULTCREATE to myEventProc */
+ res = PQexec(conn, "SELECT 1 + 1");
+
+ /* result instanceData is available */
+ data = PQresultInstanceData(res, myEventProc);
+
+ /* If PG_COPYRES_EVENTS is used, sends a PGEVT_RESULTCOPY to myEventProc */
+ res_copy = PQcopyResult(res, PG_COPYRES_TUPLES | PG_COPYRES_EVENTS);
+
+ /* result instanceData is available if PG_COPYRES_EVENTS was
+ * used during the PQcopyResult call.
+ */
+ data = PQresultInstanceData(res_copy, myEventProc);
+
+ /* Both clears send a PGEVT_RESULTDESTROY to myEventProc */
+ PQclear(res);
+ PQclear(res_copy);
+
+ /* Sends a PGEVT_CONNDESTROY to myEventProc */
+ PQfinish(conn);
+
+ return 0;
+}
+
+static int
+myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
+{
+ switch (evtId)
+ {
+ case PGEVT_REGISTER:
+ {
+ PGEventRegister *e = (PGEventRegister *)evtInfo;
+ mydata *data = get_mydata(e-&gt;conn);
+
+ /* associate app specific data with connection */
+ PQsetInstanceData(e-&gt;conn, myEventProc, data);
+ break;
+ }
+
+ case PGEVT_CONNRESET:
+ {
+ PGEventConnReset *e = (PGEventConnReset *)evtInfo;
+ mydata *data = PQinstanceData(e-&gt;conn, myEventProc);
+
+ if (data)
+ memset(data, 0, sizeof(mydata));
+ break;
+ }
+
+ case PGEVT_CONNDESTROY:
+ {
+ PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo;
+ mydata *data = PQinstanceData(e-&gt;conn, myEventProc);
+
+ /* free instance data because the conn is being destroyed */
+ if (data)
+ free_mydata(data);
+ break;
+ }
+
+ case PGEVT_RESULTCREATE:
+ {
+ PGEventResultCreate *e = (PGEventResultCreate *)evtInfo;
+ mydata *conn_data = PQinstanceData(e-&gt;conn, myEventProc);
+ mydata *res_data = dup_mydata(conn_data);
+
+ /* associate app specific data with result (copy it from conn) */
+ PQresultSetInstanceData(e-&gt;result, myEventProc, res_data);
+ break;
+ }
+
+ case PGEVT_RESULTCOPY:
+ {
+ PGEventResultCopy *e = (PGEventResultCopy *)evtInfo;
+ mydata *src_data = PQresultInstanceData(e-&gt;src, myEventProc);
+ mydata *dest_data = dup_mydata(src_data);
+
+ /* associate app specific data with result (copy it from a result) */
+ PQresultSetInstanceData(e-&gt;dest, myEventProc, dest_data);
+ break;
+ }
+
+ case PGEVT_RESULTDESTROY:
+ {
+ PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
+ mydata *data = PQresultInstanceData(e-&gt;result, myEventProc);
+
+ /* free instance data because the result is being destroyed */
+ if (data)
+ free_mydata(data);
+ break;
+ }
+
+ /* unknown event ID, just return true. */
+ default:
+ break;
+ }
+
+ return true; /* event processing succeeded */
+}
+
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-notice-processing.html" title="34.13. Notice Processing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-envars.html" title="34.15. Environment Variables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.13. Notice Processing </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.15. Environment Variables</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-example.html b/doc/src/sgml/html/libpq-example.html
new file mode 100644
index 0000000..1737edd
--- /dev/null
+++ b/doc/src/sgml/html/libpq-example.html
@@ -0,0 +1,529 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.22. Example Programs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-build.html" title="34.21. Building libpq Programs" /><link rel="next" href="largeobjects.html" title="Chapter 35. Large Objects" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.22. Example Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-build.html" title="34.21. Building libpq Programs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="largeobjects.html" title="Chapter 35. Large Objects">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.22. Example Programs</h2></div></div></div><p>
+ These examples and others can be found in the
+ directory <code class="filename">src/test/examples</code> in the source code
+ distribution.
+ </p><div class="example" id="LIBPQ-EXAMPLE-1"><p class="title"><strong>Example 34.1. <span class="application">libpq</span> Example Program 1</strong></p><div class="example-contents"><pre class="programlisting">
+
+/*
+ * src/test/examples/testlibpq.c
+ *
+ *
+ * testlibpq.c
+ *
+ * Test the C version of libpq, the PostgreSQL frontend library.
+ */
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include "libpq-fe.h"
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *conninfo;
+ PGconn *conn;
+ PGresult *res;
+ int nFields;
+ int i,
+ j;
+
+ /*
+ * If the user supplies a parameter on the command line, use it as the
+ * conninfo string; otherwise default to setting dbname=postgres and using
+ * environment variables or defaults for all other connection parameters.
+ */
+ if (argc &gt; 1)
+ conninfo = argv[1];
+ else
+ conninfo = "dbname = postgres";
+
+ /* Make a connection to the database */
+ conn = PQconnectdb(conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn,
+ "SELECT pg_catalog.set_config('search_path', '', false)");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * Should PQclear PGresult whenever it is no longer needed to avoid memory
+ * leaks
+ */
+ PQclear(res);
+
+ /*
+ * Our test case here involves using a cursor, for which we must be inside
+ * a transaction block. We could do the whole thing with a single
+ * PQexec() of "select * from pg_database", but that's too trivial to make
+ * a good example.
+ */
+
+ /* Start a transaction block */
+ res = PQexec(conn, "BEGIN");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ /*
+ * Fetch rows from pg_database, the system catalog of databases
+ */
+ res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ res = PQexec(conn, "FETCH ALL in myportal");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /* first, print out the attribute names */
+ nFields = PQnfields(res);
+ for (i = 0; i &lt; nFields; i++)
+ printf("%-15s", PQfname(res, i));
+ printf("\n\n");
+
+ /* next, print out the rows */
+ for (i = 0; i &lt; PQntuples(res); i++)
+ {
+ for (j = 0; j &lt; nFields; j++)
+ printf("%-15s", PQgetvalue(res, i, j));
+ printf("\n");
+ }
+
+ PQclear(res);
+
+ /* close the portal ... we don't bother to check for errors ... */
+ res = PQexec(conn, "CLOSE myportal");
+ PQclear(res);
+
+ /* end the transaction */
+ res = PQexec(conn, "END");
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+ return 0;
+}
+
+</pre></div></div><br class="example-break" /><div class="example" id="LIBPQ-EXAMPLE-2"><p class="title"><strong>Example 34.2. <span class="application">libpq</span> Example Program 2</strong></p><div class="example-contents"><pre class="programlisting">
+
+/*
+ * src/test/examples/testlibpq2.c
+ *
+ *
+ * testlibpq2.c
+ * Test of the asynchronous notification interface
+ *
+ * Start this program, then from psql in another window do
+ * NOTIFY TBL2;
+ * Repeat four times to get this program to exit.
+ *
+ * Or, if you want to get fancy, try this:
+ * populate a database with the following commands
+ * (provided in src/test/examples/testlibpq2.sql):
+ *
+ * CREATE SCHEMA TESTLIBPQ2;
+ * SET search_path = TESTLIBPQ2;
+ * CREATE TABLE TBL1 (i int4);
+ * CREATE TABLE TBL2 (i int4);
+ * CREATE RULE r1 AS ON INSERT TO TBL1 DO
+ * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
+ *
+ * Start this program, then from psql do this four times:
+ *
+ * INSERT INTO TESTLIBPQ2.TBL1 VALUES (10);
+ */
+
+#ifdef WIN32
+#include &lt;windows.h&gt;
+#endif
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+#include &lt;errno.h&gt;
+#include &lt;sys/time.h&gt;
+#include &lt;sys/types.h&gt;
+#ifdef HAVE_SYS_SELECT_H
+#include &lt;sys/select.h&gt;
+#endif
+
+#include "libpq-fe.h"
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *conninfo;
+ PGconn *conn;
+ PGresult *res;
+ PGnotify *notify;
+ int nnotifies;
+
+ /*
+ * If the user supplies a parameter on the command line, use it as the
+ * conninfo string; otherwise default to setting dbname=postgres and using
+ * environment variables or defaults for all other connection parameters.
+ */
+ if (argc &gt; 1)
+ conninfo = argv[1];
+ else
+ conninfo = "dbname = postgres";
+
+ /* Make a connection to the database */
+ conn = PQconnectdb(conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn,
+ "SELECT pg_catalog.set_config('search_path', '', false)");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * Should PQclear PGresult whenever it is no longer needed to avoid memory
+ * leaks
+ */
+ PQclear(res);
+
+ /*
+ * Issue LISTEN command to enable notifications from the rule's NOTIFY.
+ */
+ res = PQexec(conn, "LISTEN TBL2");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ /* Quit after four notifies are received. */
+ nnotifies = 0;
+ while (nnotifies &lt; 4)
+ {
+ /*
+ * Sleep until something happens on the connection. We use select(2)
+ * to wait for input, but you could also use poll() or similar
+ * facilities.
+ */
+ int sock;
+ fd_set input_mask;
+
+ sock = PQsocket(conn);
+
+ if (sock &lt; 0)
+ break; /* shouldn't happen */
+
+ FD_ZERO(&amp;input_mask);
+ FD_SET(sock, &amp;input_mask);
+
+ if (select(sock + 1, &amp;input_mask, NULL, NULL, NULL) &lt; 0)
+ {
+ fprintf(stderr, "select() failed: %s\n", strerror(errno));
+ exit_nicely(conn);
+ }
+
+ /* Now check for input */
+ PQconsumeInput(conn);
+ while ((notify = PQnotifies(conn)) != NULL)
+ {
+ fprintf(stderr,
+ "ASYNC NOTIFY of '%s' received from backend PID %d\n",
+ notify-&gt;relname, notify-&gt;be_pid);
+ PQfreemem(notify);
+ nnotifies++;
+ PQconsumeInput(conn);
+ }
+ }
+
+ fprintf(stderr, "Done.\n");
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+ return 0;
+}
+
+</pre></div></div><br class="example-break" /><div class="example" id="LIBPQ-EXAMPLE-3"><p class="title"><strong>Example 34.3. <span class="application">libpq</span> Example Program 3</strong></p><div class="example-contents"><pre class="programlisting">
+
+/*
+ * src/test/examples/testlibpq3.c
+ *
+ *
+ * testlibpq3.c
+ * Test out-of-line parameters and binary I/O.
+ *
+ * Before running this, populate a database with the following commands
+ * (provided in src/test/examples/testlibpq3.sql):
+ *
+ * CREATE SCHEMA testlibpq3;
+ * SET search_path = testlibpq3;
+ * SET standard_conforming_strings = ON;
+ * CREATE TABLE test1 (i int4, t text, b bytea);
+ * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004');
+ * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000');
+ *
+ * The expected output is:
+ *
+ * tuple 0: got
+ * i = (4 bytes) 1
+ * t = (11 bytes) 'joe's place'
+ * b = (5 bytes) \000\001\002\003\004
+ *
+ * tuple 0: got
+ * i = (4 bytes) 2
+ * t = (8 bytes) 'ho there'
+ * b = (5 bytes) \004\003\002\001\000
+ */
+
+#ifdef WIN32
+#include &lt;windows.h&gt;
+#endif
+
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;stdint.h&gt;
+#include &lt;string.h&gt;
+#include &lt;sys/types.h&gt;
+#include "libpq-fe.h"
+
+/* for ntohl/htonl */
+#include &lt;netinet/in.h&gt;
+#include &lt;arpa/inet.h&gt;
+
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+/*
+ * This function prints a query result that is a binary-format fetch from
+ * a table defined as in the comment above. We split it out because the
+ * main() function uses it twice.
+ */
+static void
+show_binary_results(PGresult *res)
+{
+ int i,
+ j;
+ int i_fnum,
+ t_fnum,
+ b_fnum;
+
+ /* Use PQfnumber to avoid assumptions about field order in result */
+ i_fnum = PQfnumber(res, "i");
+ t_fnum = PQfnumber(res, "t");
+ b_fnum = PQfnumber(res, "b");
+
+ for (i = 0; i &lt; PQntuples(res); i++)
+ {
+ char *iptr;
+ char *tptr;
+ char *bptr;
+ int blen;
+ int ival;
+
+ /* Get the field values (we ignore possibility they are null!) */
+ iptr = PQgetvalue(res, i, i_fnum);
+ tptr = PQgetvalue(res, i, t_fnum);
+ bptr = PQgetvalue(res, i, b_fnum);
+
+ /*
+ * The binary representation of INT4 is in network byte order, which
+ * we'd better coerce to the local byte order.
+ */
+ ival = ntohl(*((uint32_t *) iptr));
+
+ /*
+ * The binary representation of TEXT is, well, text, and since libpq
+ * was nice enough to append a zero byte to it, it'll work just fine
+ * as a C string.
+ *
+ * The binary representation of BYTEA is a bunch of bytes, which could
+ * include embedded nulls so we have to pay attention to field length.
+ */
+ blen = PQgetlength(res, i, b_fnum);
+
+ printf("tuple %d: got\n", i);
+ printf(" i = (%d bytes) %d\n",
+ PQgetlength(res, i, i_fnum), ival);
+ printf(" t = (%d bytes) '%s'\n",
+ PQgetlength(res, i, t_fnum), tptr);
+ printf(" b = (%d bytes) ", blen);
+ for (j = 0; j &lt; blen; j++)
+ printf("\\%03o", bptr[j]);
+ printf("\n\n");
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *conninfo;
+ PGconn *conn;
+ PGresult *res;
+ const char *paramValues[1];
+ int paramLengths[1];
+ int paramFormats[1];
+ uint32_t binaryIntVal;
+
+ /*
+ * If the user supplies a parameter on the command line, use it as the
+ * conninfo string; otherwise default to setting dbname=postgres and using
+ * environment variables or defaults for all other connection parameters.
+ */
+ if (argc &gt; 1)
+ conninfo = argv[1];
+ else
+ conninfo = "dbname = postgres";
+
+ /* Make a connection to the database */
+ conn = PQconnectdb(conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn, "SET search_path = testlibpq3");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ /*
+ * The point of this program is to illustrate use of PQexecParams() with
+ * out-of-line parameters, as well as binary transmission of data.
+ *
+ * This first example transmits the parameters as text, but receives the
+ * results in binary format. By using out-of-line parameters we can avoid
+ * a lot of tedious mucking about with quoting and escaping, even though
+ * the data is text. Notice how we don't have to do anything special with
+ * the quote mark in the parameter value.
+ */
+
+ /* Here is our out-of-line parameter value */
+ paramValues[0] = "joe's place";
+
+ res = PQexecParams(conn,
+ "SELECT * FROM test1 WHERE t = $1",
+ 1, /* one param */
+ NULL, /* let the backend deduce param type */
+ paramValues,
+ NULL, /* don't need param lengths since text */
+ NULL, /* default to all text params */
+ 1); /* ask for binary results */
+
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ show_binary_results(res);
+
+ PQclear(res);
+
+ /*
+ * In this second example we transmit an integer parameter in binary form,
+ * and again retrieve the results in binary form.
+ *
+ * Although we tell PQexecParams we are letting the backend deduce
+ * parameter type, we really force the decision by casting the parameter
+ * symbol in the query text. This is a good safety measure when sending
+ * binary parameters.
+ */
+
+ /* Convert integer value "2" to network byte order */
+ binaryIntVal = htonl((uint32_t) 2);
+
+ /* Set up parameter arrays for PQexecParams */
+ paramValues[0] = (char *) &amp;binaryIntVal;
+ paramLengths[0] = sizeof(binaryIntVal);
+ paramFormats[0] = 1; /* binary */
+
+ res = PQexecParams(conn,
+ "SELECT * FROM test1 WHERE i = $1::int4",
+ 1, /* one param */
+ NULL, /* let the backend deduce param type */
+ paramValues,
+ paramLengths,
+ paramFormats,
+ 1); /* ask for binary results */
+
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ show_binary_results(res);
+
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+ return 0;
+}
+
+</pre></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-build.html" title="34.21. Building libpq Programs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="largeobjects.html" title="Chapter 35. Large Objects">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.21. Building <span class="application">libpq</span> Programs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 35. Large Objects</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-exec.html b/doc/src/sgml/html/libpq-exec.html
new file mode 100644
index 0000000..094855c
--- /dev/null
+++ b/doc/src/sgml/html/libpq-exec.html
@@ -0,0 +1,1050 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.3. Command Execution Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-status.html" title="34.2. Connection Status Functions" /><link rel="next" href="libpq-async.html" title="34.4. Asynchronous Command Processing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.3. Command Execution Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-status.html" title="34.2. Connection Status Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-async.html" title="34.4. Asynchronous Command Processing">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-EXEC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.3. Command Execution Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-MAIN">34.3.1. Main Functions</a></span></dt><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">34.3.2. Retrieving Query Result Information</a></span></dt><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">34.3.3. Retrieving Other Result Information</a></span></dt><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">34.3.4. Escaping Strings for Inclusion in SQL Commands</a></span></dt></dl></div><p>
+ Once a connection to a database server has been successfully
+ established, the functions described here are used to perform
+ SQL queries and commands.
+ </p><div class="sect2" id="LIBPQ-EXEC-MAIN"><div class="titlepage"><div><div><h3 class="title">34.3.1. Main Functions</h3></div></div></div><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQEXEC"><span class="term"><code class="function">PQexec</code><a id="id-1.7.3.10.3.2.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a command to the server and waits for the result.
+
+</p><pre class="synopsis">
+PGresult *PQexec(PGconn *conn, const char *command);
+</pre><p>
+ </p><p>
+ Returns a <code class="structname">PGresult</code> pointer or possibly a null
+ pointer. A non-null pointer will generally be returned except in
+ out-of-memory conditions or serious errors such as inability to send
+ the command to the server. The <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTSTATUS"><code class="function">PQresultStatus</code></a> function
+ should be called to check the return value for any errors (including
+ the value of a null pointer, in which case it will return
+ <code class="symbol">PGRES_FATAL_ERROR</code>). Use
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to get more information about such
+ errors.
+ </p></dd></dl></div><p>
+
+ The command string can include multiple SQL commands
+ (separated by semicolons). Multiple queries sent in a single
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> call are processed in a single transaction, unless
+ there are explicit <code class="command">BEGIN</code>/<code class="command">COMMIT</code>
+ commands included in the query string to divide it into multiple
+ transactions. (See <a class="xref" href="protocol-flow.html#PROTOCOL-FLOW-MULTI-STATEMENT" title="55.2.2.1. Multiple Statements in a Simple Query">Section 55.2.2.1</a>
+ for more details about how the server handles multi-query strings.)
+ Note however that the returned
+ <code class="structname">PGresult</code> structure describes only the result
+ of the last command executed from the string. Should one of the
+ commands fail, processing of the string stops with it and the returned
+ <code class="structname">PGresult</code> describes the error condition.
+ </p><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQEXECPARAMS"><span class="term"><code class="function">PQexecParams</code><a id="id-1.7.3.10.3.3.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a command to the server and waits for the result,
+ with the ability to pass parameters separately from the SQL
+ command text.
+
+</p><pre class="synopsis">
+PGresult *PQexecParams(PGconn *conn,
+ const char *command,
+ int nParams,
+ const Oid *paramTypes,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a> is like <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>, but offers additional
+ functionality: parameter values can be specified separately from the command
+ string proper, and query results can be requested in either text or binary
+ format.
+ </p><p>
+ The function arguments are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="parameter"><code>conn</code></em></span></dt><dd><p>
+ The connection object to send the command through.
+ </p></dd><dt><span class="term"><em class="parameter"><code>command</code></em></span></dt><dd><p>
+ The SQL command string to be executed. If parameters are used,
+ they are referred to in the command string as <code class="literal">$1</code>,
+ <code class="literal">$2</code>, etc.
+ </p></dd><dt><span class="term"><em class="parameter"><code>nParams</code></em></span></dt><dd><p>
+ The number of parameters supplied; it is the length of the arrays
+ <em class="parameter"><code>paramTypes[]</code></em>, <em class="parameter"><code>paramValues[]</code></em>,
+ <em class="parameter"><code>paramLengths[]</code></em>, and <em class="parameter"><code>paramFormats[]</code></em>. (The
+ array pointers can be <code class="symbol">NULL</code> when <em class="parameter"><code>nParams</code></em>
+ is zero.)
+ </p></dd><dt><span class="term"><em class="parameter"><code>paramTypes[]</code></em></span></dt><dd><p>
+ Specifies, by OID, the data types to be assigned to the
+ parameter symbols. If <em class="parameter"><code>paramTypes</code></em> is
+ <code class="symbol">NULL</code>, or any particular element in the array
+ is zero, the server infers a data type for the parameter symbol
+ in the same way it would do for an untyped literal string.
+ </p></dd><dt><span class="term"><em class="parameter"><code>paramValues[]</code></em></span></dt><dd><p>
+ Specifies the actual values of the parameters. A null pointer
+ in this array means the corresponding parameter is null;
+ otherwise the pointer points to a zero-terminated text string
+ (for text format) or binary data in the format expected by the
+ server (for binary format).
+ </p></dd><dt><span class="term"><em class="parameter"><code>paramLengths[]</code></em></span></dt><dd><p>
+ Specifies the actual data lengths of binary-format parameters.
+ It is ignored for null parameters and text-format parameters.
+ The array pointer can be null when there are no binary parameters.
+ </p></dd><dt><span class="term"><em class="parameter"><code>paramFormats[]</code></em></span></dt><dd><p>
+ Specifies whether parameters are text (put a zero in the
+ array entry for the corresponding parameter) or binary (put
+ a one in the array entry for the corresponding parameter).
+ If the array pointer is null then all parameters are presumed
+ to be text strings.
+ </p><p>
+ Values passed in binary format require knowledge of
+ the internal representation expected by the backend.
+ For example, integers must be passed in network byte
+ order. Passing <code class="type">numeric</code> values requires
+ knowledge of the server storage format, as implemented
+ in
+ <code class="filename">src/backend/utils/adt/numeric.c::numeric_send()</code> and
+ <code class="filename">src/backend/utils/adt/numeric.c::numeric_recv()</code>.
+ </p></dd><dt><span class="term"><em class="parameter"><code>resultFormat</code></em></span></dt><dd><p>
+ Specify zero to obtain results in text format, or one to obtain
+ results in binary format. (There is not currently a provision
+ to obtain different result columns in different formats,
+ although that is possible in the underlying protocol.)
+ </p></dd></dl></div><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ The primary advantage of <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a> over
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> is that parameter values can be separated from the
+ command string, thus avoiding the need for tedious and error-prone
+ quoting and escaping.
+ </p><p>
+ Unlike <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>, <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a> allows at most
+ one SQL command in the given string. (There can be semicolons in it,
+ but not more than one nonempty command.) This is a limitation of the
+ underlying protocol, but has some usefulness as an extra defense against
+ SQL-injection attacks.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Specifying parameter types via OIDs is tedious, particularly if you prefer
+ not to hard-wire particular OID values into your program. However, you can
+ avoid doing so even in cases where the server by itself cannot determine the
+ type of the parameter, or chooses a different type than you want. In the
+ SQL command text, attach an explicit cast to the parameter symbol to show what
+ data type you will send. For example:
+</p><pre class="programlisting">
+SELECT * FROM mytable WHERE x = $1::bigint;
+</pre><p>
+ This forces parameter <code class="literal">$1</code> to be treated as <code class="type">bigint</code>, whereas
+ by default it would be assigned the same type as <code class="literal">x</code>. Forcing the
+ parameter type decision, either this way or by specifying a numeric type OID,
+ is strongly recommended when sending parameter values in binary format, because
+ binary format has less redundancy than text format and so there is less chance
+ that the server will detect a type mismatch mistake for you.
+ </p></div><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQPREPARE"><span class="term"><code class="function">PQprepare</code><a id="id-1.7.3.10.3.7.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a request to create a prepared statement with the
+ given parameters, and waits for completion.
+</p><pre class="synopsis">
+PGresult *PQprepare(PGconn *conn,
+ const char *stmtName,
+ const char *query,
+ int nParams,
+ const Oid *paramTypes);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQPREPARE"><code class="function">PQprepare</code></a> creates a prepared statement for later
+ execution with <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPREPARED"><code class="function">PQexecPrepared</code></a>. This feature allows
+ commands to be executed repeatedly without being parsed and
+ planned each time; see <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a> for details.
+ </p><p>
+ The function creates a prepared statement named
+ <em class="parameter"><code>stmtName</code></em> from the <em class="parameter"><code>query</code></em> string, which
+ must contain a single SQL command. <em class="parameter"><code>stmtName</code></em> can be
+ <code class="literal">""</code> to create an unnamed statement, in which case any
+ pre-existing unnamed statement is automatically replaced; otherwise
+ it is an error if the statement name is already defined in the
+ current session. If any parameters are used, they are referred
+ to in the query as <code class="literal">$1</code>, <code class="literal">$2</code>, etc.
+ <em class="parameter"><code>nParams</code></em> is the number of parameters for which types
+ are pre-specified in the array <em class="parameter"><code>paramTypes[]</code></em>. (The
+ array pointer can be <code class="symbol">NULL</code> when
+ <em class="parameter"><code>nParams</code></em> is zero.) <em class="parameter"><code>paramTypes[]</code></em>
+ specifies, by OID, the data types to be assigned to the parameter
+ symbols. If <em class="parameter"><code>paramTypes</code></em> is <code class="symbol">NULL</code>,
+ or any particular element in the array is zero, the server assigns
+ a data type to the parameter symbol in the same way it would do
+ for an untyped literal string. Also, the query can use parameter
+ symbols with numbers higher than <em class="parameter"><code>nParams</code></em>; data types
+ will be inferred for these symbols as well. (See
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a> for a means to find out
+ what data types were inferred.)
+ </p><p>
+ As with <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>, the result is normally a
+ <code class="structname">PGresult</code> object whose contents indicate
+ server-side success or failure. A null result indicates
+ out-of-memory or inability to send the command at all. Use
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to get more information about
+ such errors.
+ </p></dd></dl></div><p>
+
+ Prepared statements for use with <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPREPARED"><code class="function">PQexecPrepared</code></a> can also
+ be created by executing SQL <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a>
+ statements. Also, although there is no <span class="application">libpq</span>
+ function for deleting a prepared statement, the SQL <a class="xref" href="sql-deallocate.html" title="DEALLOCATE"><span class="refentrytitle">DEALLOCATE</span></a> statement
+ can be used for that purpose.
+ </p><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQEXECPREPARED"><span class="term"><code class="function">PQexecPrepared</code><a id="id-1.7.3.10.3.8.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends a request to execute a prepared statement with given
+ parameters, and waits for the result.
+</p><pre class="synopsis">
+PGresult *PQexecPrepared(PGconn *conn,
+ const char *stmtName,
+ int nParams,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPREPARED"><code class="function">PQexecPrepared</code></a> is like <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a>,
+ but the command to be executed is specified by naming a
+ previously-prepared statement, instead of giving a query string.
+ This feature allows commands that will be used repeatedly to be
+ parsed and planned just once, rather than each time they are
+ executed. The statement must have been prepared previously in
+ the current session.
+ </p><p>
+ The parameters are identical to <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a>, except that the
+ name of a prepared statement is given instead of a query string, and the
+ <em class="parameter"><code>paramTypes[]</code></em> parameter is not present (it is not needed since
+ the prepared statement's parameter types were determined when it was created).
+ </p></dd><dt id="LIBPQ-PQDESCRIBEPREPARED"><span class="term"><code class="function">PQdescribePrepared</code><a id="id-1.7.3.10.3.8.1.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a request to obtain information about the specified
+ prepared statement, and waits for completion.
+</p><pre class="synopsis">
+PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a> allows an application to obtain
+ information about a previously prepared statement.
+ </p><p>
+ <em class="parameter"><code>stmtName</code></em> can be <code class="literal">""</code> or <code class="symbol">NULL</code> to reference
+ the unnamed statement, otherwise it must be the name of an existing
+ prepared statement. On success, a <code class="structname">PGresult</code> with
+ status <code class="literal">PGRES_COMMAND_OK</code> is returned. The
+ functions <a class="xref" href="libpq-exec.html#LIBPQ-PQNPARAMS"><code class="function">PQnparams</code></a> and
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQPARAMTYPE"><code class="function">PQparamtype</code></a> can be applied to this
+ <code class="structname">PGresult</code> to obtain information about the parameters
+ of the prepared statement, and the functions
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQNFIELDS"><code class="function">PQnfields</code></a>, <a class="xref" href="libpq-exec.html#LIBPQ-PQFNAME"><code class="function">PQfname</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQFTYPE"><code class="function">PQftype</code></a>, etc. provide information about the
+ result columns (if any) of the statement.
+ </p></dd><dt id="LIBPQ-PQDESCRIBEPORTAL"><span class="term"><code class="function">PQdescribePortal</code><a id="id-1.7.3.10.3.8.1.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Submits a request to obtain information about the specified
+ portal, and waits for completion.
+</p><pre class="synopsis">
+PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPORTAL"><code class="function">PQdescribePortal</code></a> allows an application to obtain
+ information about a previously created portal.
+ (<span class="application">libpq</span> does not provide any direct access to
+ portals, but you can use this function to inspect the properties
+ of a cursor created with a <code class="command">DECLARE CURSOR</code> SQL command.)
+ </p><p>
+ <em class="parameter"><code>portalName</code></em> can be <code class="literal">""</code> or <code class="symbol">NULL</code> to reference
+ the unnamed portal, otherwise it must be the name of an existing
+ portal. On success, a <code class="structname">PGresult</code> with status
+ <code class="literal">PGRES_COMMAND_OK</code> is returned. The functions
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQNFIELDS"><code class="function">PQnfields</code></a>, <a class="xref" href="libpq-exec.html#LIBPQ-PQFNAME"><code class="function">PQfname</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQFTYPE"><code class="function">PQftype</code></a>, etc. can be applied to the
+ <code class="structname">PGresult</code> to obtain information about the result
+ columns (if any) of the portal.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <code class="structname">PGresult</code><a id="id-1.7.3.10.3.9.2" class="indexterm"></a>
+ structure encapsulates the result returned by the server.
+ <span class="application">libpq</span> application programmers should be
+ careful to maintain the <code class="structname">PGresult</code> abstraction.
+ Use the accessor functions below to get at the contents of
+ <code class="structname">PGresult</code>. Avoid directly referencing the
+ fields of the <code class="structname">PGresult</code> structure because they
+ are subject to change in the future.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQRESULTSTATUS"><span class="term"><code class="function">PQresultStatus</code><a id="id-1.7.3.10.3.9.7.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the result status of the command.
+</p><pre class="synopsis">
+ExecStatusType PQresultStatus(const PGresult *res);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTSTATUS"><code class="function">PQresultStatus</code></a> can return one of the following values:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PGRES-EMPTY-QUERY"><span class="term"><code class="literal">PGRES_EMPTY_QUERY</code></span></dt><dd><p>
+ The string sent to the server was empty.
+ </p></dd><dt id="LIBPQ-PGRES-COMMAND-OK"><span class="term"><code class="literal">PGRES_COMMAND_OK</code></span></dt><dd><p>
+ Successful completion of a command returning no data.
+ </p></dd><dt id="LIBPQ-PGRES-TUPLES-OK"><span class="term"><code class="literal">PGRES_TUPLES_OK</code></span></dt><dd><p>
+ Successful completion of a command returning data (such as
+ a <code class="command">SELECT</code> or <code class="command">SHOW</code>).
+ </p></dd><dt id="LIBPQ-PGRES-COPY-OUT"><span class="term"><code class="literal">PGRES_COPY_OUT</code></span></dt><dd><p>
+ Copy Out (from server) data transfer started.
+ </p></dd><dt id="LIBPQ-PGRES-COPY-IN"><span class="term"><code class="literal">PGRES_COPY_IN</code></span></dt><dd><p>
+ Copy In (to server) data transfer started.
+ </p></dd><dt id="LIBPQ-PGRES-BAD-RESPONSE"><span class="term"><code class="literal">PGRES_BAD_RESPONSE</code></span></dt><dd><p>
+ The server's response was not understood.
+ </p></dd><dt id="LIBPQ-PGRES-NONFATAL-ERROR"><span class="term"><code class="literal">PGRES_NONFATAL_ERROR</code></span></dt><dd><p>
+ A nonfatal error (a notice or warning) occurred.
+ </p></dd><dt id="LIBPQ-PGRES-FATAL-ERROR"><span class="term"><code class="literal">PGRES_FATAL_ERROR</code></span></dt><dd><p>
+ A fatal error occurred.
+ </p></dd><dt id="LIBPQ-PGRES-COPY-BOTH"><span class="term"><code class="literal">PGRES_COPY_BOTH</code></span></dt><dd><p>
+ Copy In/Out (to and from server) data transfer started. This
+ feature is currently used only for streaming replication,
+ so this status should not occur in ordinary applications.
+ </p></dd><dt id="LIBPQ-PGRES-SINGLE-TUPLE"><span class="term"><code class="literal">PGRES_SINGLE_TUPLE</code></span></dt><dd><p>
+ The <code class="structname">PGresult</code> contains a single result tuple
+ from the current command. This status occurs only when
+ single-row mode has been selected for the query
+ (see <a class="xref" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Section 34.6</a>).
+ </p></dd><dt id="LIBPQ-PGRES-PIPELINE-SYNC"><span class="term"><code class="literal">PGRES_PIPELINE_SYNC</code></span></dt><dd><p>
+ The <code class="structname">PGresult</code> represents a
+ synchronization point in pipeline mode, requested by
+ <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PQPIPELINESYNC"><code class="function">PQpipelineSync</code></a>.
+ This status occurs only when pipeline mode has been selected.
+ </p></dd><dt id="LIBPQ-PGRES-PIPELINE-ABORTED"><span class="term"><code class="literal">PGRES_PIPELINE_ABORTED</code></span></dt><dd><p>
+ The <code class="structname">PGresult</code> represents a pipeline that has
+ received an error from the server. <code class="function">PQgetResult</code>
+ must be called repeatedly, and each time it will return this status code
+ until the end of the current pipeline, at which point it will return
+ <code class="literal">PGRES_PIPELINE_SYNC</code> and normal processing can
+ resume.
+ </p></dd></dl></div><p>
+
+ If the result status is <code class="literal">PGRES_TUPLES_OK</code> or
+ <code class="literal">PGRES_SINGLE_TUPLE</code>, then
+ the functions described below can be used to retrieve the rows
+ returned by the query. Note that a <code class="command">SELECT</code>
+ command that happens to retrieve zero rows still shows
+ <code class="literal">PGRES_TUPLES_OK</code>.
+ <code class="literal">PGRES_COMMAND_OK</code> is for commands that can never
+ return rows (<code class="command">INSERT</code> or <code class="command">UPDATE</code>
+ without a <code class="literal">RETURNING</code> clause,
+ etc.). A response of <code class="literal">PGRES_EMPTY_QUERY</code> might
+ indicate a bug in the client software.
+ </p><p>
+ A result of status <code class="symbol">PGRES_NONFATAL_ERROR</code> will
+ never be returned directly by <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> or other
+ query execution functions; results of this kind are instead passed
+ to the notice processor (see <a class="xref" href="libpq-notice-processing.html" title="34.13. Notice Processing">Section 34.13</a>).
+ </p></dd><dt id="LIBPQ-PQRESSTATUS"><span class="term"><code class="function">PQresStatus</code><a id="id-1.7.3.10.3.9.7.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Converts the enumerated type returned by
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTSTATUS"><code class="function">PQresultStatus</code></a> into a string constant describing the
+ status code. The caller should not free the result.
+
+</p><pre class="synopsis">
+char *PQresStatus(ExecStatusType status);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQRESULTERRORMESSAGE"><span class="term"><code class="function">PQresultErrorMessage</code><a id="id-1.7.3.10.3.9.7.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the error message associated with the command, or an empty string
+ if there was no error.
+</p><pre class="synopsis">
+char *PQresultErrorMessage(const PGresult *res);
+</pre><p>
+ If there was an error, the returned string will include a trailing
+ newline. The caller should not free the result directly. It will
+ be freed when the associated <code class="structname">PGresult</code> handle is
+ passed to <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+ </p><p>
+ Immediately following a <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> or
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> call,
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> (on the connection) will return
+ the same string as <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a> (on
+ the result). However, a <code class="structname">PGresult</code> will
+ retain its error message until destroyed, whereas the connection's
+ error message will change when subsequent operations are done.
+ Use <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a> when you want to
+ know the status associated with a particular
+ <code class="structname">PGresult</code>; use
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> when you want to know the
+ status from the latest operation on the connection.
+ </p></dd><dt id="LIBPQ-PQRESULTVERBOSEERRORMESSAGE"><span class="term"><code class="function">PQresultVerboseErrorMessage</code><a id="id-1.7.3.10.3.9.7.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns a reformatted version of the error message associated with
+ a <code class="structname">PGresult</code> object.
+</p><pre class="synopsis">
+char *PQresultVerboseErrorMessage(const PGresult *res,
+ PGVerbosity verbosity,
+ PGContextVisibility show_context);
+</pre><p>
+ In some situations a client might wish to obtain a more detailed
+ version of a previously-reported error.
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTVERBOSEERRORMESSAGE"><code class="function">PQresultVerboseErrorMessage</code></a> addresses this need
+ by computing the message that would have been produced
+ by <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a> if the specified
+ verbosity settings had been in effect for the connection when the
+ given <code class="structname">PGresult</code> was generated. If
+ the <code class="structname">PGresult</code> is not an error result,
+ <span class="quote">“<span class="quote">PGresult is not an error result</span>”</span> is reported instead.
+ The returned string includes a trailing newline.
+ </p><p>
+ Unlike most other functions for extracting data from
+ a <code class="structname">PGresult</code>, the result of this function is a freshly
+ allocated string. The caller must free it
+ using <code class="function">PQfreemem()</code> when the string is no longer needed.
+ </p><p>
+ A NULL return is possible if there is insufficient memory.
+ </p></dd><dt id="LIBPQ-PQRESULTERRORFIELD"><span class="term"><code class="function">PQresultErrorField</code><a id="id-1.7.3.10.3.9.7.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns an individual field of an error report.
+</p><pre class="synopsis">
+char *PQresultErrorField(const PGresult *res, int fieldcode);
+</pre><p>
+ <em class="parameter"><code>fieldcode</code></em> is an error field identifier; see the symbols
+ listed below. <code class="symbol">NULL</code> is returned if the
+ <code class="structname">PGresult</code> is not an error or warning result,
+ or does not include the specified field. Field values will normally
+ not include a trailing newline. The caller should not free the
+ result directly. It will be freed when the
+ associated <code class="structname">PGresult</code> handle is passed to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+ </p><p>
+ The following field codes are available:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PG-DIAG-SEVERITY"><span class="term"><code class="symbol">PG_DIAG_SEVERITY</code></span></dt><dd><p>
+ The severity; the field contents are <code class="literal">ERROR</code>,
+ <code class="literal">FATAL</code>, or <code class="literal">PANIC</code> (in an error message),
+ or <code class="literal">WARNING</code>, <code class="literal">NOTICE</code>, <code class="literal">DEBUG</code>,
+ <code class="literal">INFO</code>, or <code class="literal">LOG</code> (in a notice message), or
+ a localized translation of one of these. Always present.
+ </p></dd><dt id="LIBPQ-PG-DIAG-SEVERITY-NONLOCALIZED"><span class="term"><code class="symbol">PG_DIAG_SEVERITY_NONLOCALIZED</code></span></dt><dd><p>
+ The severity; the field contents are <code class="literal">ERROR</code>,
+ <code class="literal">FATAL</code>, or <code class="literal">PANIC</code> (in an error message),
+ or <code class="literal">WARNING</code>, <code class="literal">NOTICE</code>, <code class="literal">DEBUG</code>,
+ <code class="literal">INFO</code>, or <code class="literal">LOG</code> (in a notice message).
+ This is identical to the <code class="symbol">PG_DIAG_SEVERITY</code> field except
+ that the contents are never localized. This is present only in
+ reports generated by <span class="productname">PostgreSQL</span> versions 9.6
+ and later.
+ </p></dd><dt id="LIBPQ-PG-DIAG-SQLSTATE"><span class="term"><code class="symbol">PG_DIAG_SQLSTATE</code><a id="id-1.7.3.10.3.9.7.5.2.2.1.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ The SQLSTATE code for the error. The SQLSTATE code identifies
+ the type of error that has occurred; it can be used by
+ front-end applications to perform specific operations (such
+ as error handling) in response to a particular database error.
+ For a list of the possible SQLSTATE codes, see <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>. This field is not localizable,
+ and is always present.
+ </p></dd><dt id="LIBPQ-PG-DIAG-MESSAGE-PRIMARY"><span class="term"><code class="symbol">PG_DIAG_MESSAGE_PRIMARY</code></span></dt><dd><p>
+ The primary human-readable error message (typically one line).
+ Always present.
+ </p></dd><dt id="LIBPQ-PG-DIAG-MESSAGE-DETAIL"><span class="term"><code class="symbol">PG_DIAG_MESSAGE_DETAIL</code></span></dt><dd><p>
+ Detail: an optional secondary error message carrying more
+ detail about the problem. Might run to multiple lines.
+ </p></dd><dt id="LIBPQ-PG-DIAG-MESSAGE-HINT"><span class="term"><code class="symbol">PG_DIAG_MESSAGE_HINT</code></span></dt><dd><p>
+ Hint: an optional suggestion what to do about the problem.
+ This is intended to differ from detail in that it offers advice
+ (potentially inappropriate) rather than hard facts. Might
+ run to multiple lines.
+ </p></dd><dt id="LIBPQ-PG-DIAG-STATEMENT-POSITION"><span class="term"><code class="symbol">PG_DIAG_STATEMENT_POSITION</code></span></dt><dd><p>
+ A string containing a decimal integer indicating an error cursor
+ position as an index into the original statement string. The
+ first character has index 1, and positions are measured in
+ characters not bytes.
+ </p></dd><dt id="LIBPQ-PG-DIAG-INTERNAL-POSITION"><span class="term"><code class="symbol">PG_DIAG_INTERNAL_POSITION</code></span></dt><dd><p>
+ This is defined the same as the
+ <code class="symbol">PG_DIAG_STATEMENT_POSITION</code> field, but it is used
+ when the cursor position refers to an internally generated
+ command rather than the one submitted by the client. The
+ <code class="symbol">PG_DIAG_INTERNAL_QUERY</code> field will always appear when
+ this field appears.
+ </p></dd><dt id="LIBPQ-PG-DIAG-INTERNAL-QUERY"><span class="term"><code class="symbol">PG_DIAG_INTERNAL_QUERY</code></span></dt><dd><p>
+ The text of a failed internally-generated command. This could
+ be, for example, an SQL query issued by a PL/pgSQL function.
+ </p></dd><dt id="LIBPQ-PG-DIAG-CONTEXT"><span class="term"><code class="symbol">PG_DIAG_CONTEXT</code></span></dt><dd><p>
+ An indication of the context in which the error occurred.
+ Presently this includes a call stack traceback of active
+ procedural language functions and internally-generated queries.
+ The trace is one entry per line, most recent first.
+ </p></dd><dt id="LIBPQ-PG-DIAG-SCHEMA-NAME"><span class="term"><code class="symbol">PG_DIAG_SCHEMA_NAME</code></span></dt><dd><p>
+ If the error was associated with a specific database object,
+ the name of the schema containing that object, if any.
+ </p></dd><dt id="LIBPQ-PG-DIAG-TABLE-NAME"><span class="term"><code class="symbol">PG_DIAG_TABLE_NAME</code></span></dt><dd><p>
+ If the error was associated with a specific table, the name of the
+ table. (Refer to the schema name field for the name of the
+ table's schema.)
+ </p></dd><dt id="LIBPQ-PG-DIAG-COLUMN-NAME"><span class="term"><code class="symbol">PG_DIAG_COLUMN_NAME</code></span></dt><dd><p>
+ If the error was associated with a specific table column, the name
+ of the column. (Refer to the schema and table name fields to
+ identify the table.)
+ </p></dd><dt id="LIBPQ-PG-DIAG-DATATYPE-NAME"><span class="term"><code class="symbol">PG_DIAG_DATATYPE_NAME</code></span></dt><dd><p>
+ If the error was associated with a specific data type, the name of
+ the data type. (Refer to the schema name field for the name of
+ the data type's schema.)
+ </p></dd><dt id="LIBPQ-PG-DIAG-CONSTRAINT-NAME"><span class="term"><code class="symbol">PG_DIAG_CONSTRAINT_NAME</code></span></dt><dd><p>
+ If the error was associated with a specific constraint, the name
+ of the constraint. Refer to fields listed above for the
+ associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with
+ constraint syntax.)
+ </p></dd><dt id="LIBPQ-PG-DIAG-SOURCE-FILE"><span class="term"><code class="symbol">PG_DIAG_SOURCE_FILE</code></span></dt><dd><p>
+ The file name of the source-code location where the error was
+ reported.
+ </p></dd><dt id="LIBPQ-PG-DIAG-SOURCE-LINE"><span class="term"><code class="symbol">PG_DIAG_SOURCE_LINE</code></span></dt><dd><p>
+ The line number of the source-code location where the error
+ was reported.
+ </p></dd><dt id="LIBPQ-PG-DIAG-SOURCE-FUNCTION"><span class="term"><code class="symbol">PG_DIAG_SOURCE_FUNCTION</code></span></dt><dd><p>
+ The name of the source-code function reporting the error.
+ </p></dd></dl></div><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The fields for schema name, table name, column name, data type name,
+ and constraint name are supplied only for a limited number of error
+ types; see <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>. Do not assume that
+ the presence of any of these fields guarantees the presence of
+ another field. Core error sources observe the interrelationships
+ noted above, but user-defined functions may use these fields in other
+ ways. In the same vein, do not assume that these fields denote
+ contemporary objects in the current database.
+ </p></div><p>
+ The client is responsible for formatting displayed information to meet
+ its needs; in particular it should break long lines as needed.
+ Newline characters appearing in the error message fields should be
+ treated as paragraph breaks, not line breaks.
+ </p><p>
+ Errors generated internally by <span class="application">libpq</span> will
+ have severity and primary message, but typically no other fields.
+ </p><p>
+ Note that error fields are only available from
+ <code class="structname">PGresult</code> objects, not
+ <code class="structname">PGconn</code> objects; there is no
+ <code class="function">PQerrorField</code> function.
+ </p></dd><dt id="LIBPQ-PQCLEAR"><span class="term"><code class="function">PQclear</code><a id="id-1.7.3.10.3.9.7.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Frees the storage associated with a
+ <code class="structname">PGresult</code>. Every command result should be
+ freed via <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> when it is no longer
+ needed.
+
+</p><pre class="synopsis">
+void PQclear(PGresult *res);
+</pre><p>
+ </p><p>
+ You can keep a <code class="structname">PGresult</code> object around for
+ as long as you need it; it does not go away when you issue a new
+ command, nor even if you close the connection. To get rid of it,
+ you must call <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>. Failure to do this
+ will result in memory leaks in your application.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="LIBPQ-EXEC-SELECT-INFO"><div class="titlepage"><div><div><h3 class="title">34.3.2. Retrieving Query Result Information</h3></div></div></div><p>
+ These functions are used to extract information from a
+ <code class="structname">PGresult</code> object that represents a successful
+ query result (that is, one that has status
+ <code class="literal">PGRES_TUPLES_OK</code> or <code class="literal">PGRES_SINGLE_TUPLE</code>).
+ They can also be used to extract
+ information from a successful Describe operation: a Describe's result
+ has all the same column information that actual execution of the query
+ would provide, but it has zero rows. For objects with other status values,
+ these functions will act as though the result has zero rows and zero columns.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQNTUPLES"><span class="term"><code class="function">PQntuples</code><a id="id-1.7.3.10.4.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the number of rows (tuples) in the query result.
+ (Note that <code class="structname">PGresult</code> objects are limited to no more
+ than <code class="literal">INT_MAX</code> rows, so an <code class="type">int</code> result is
+ sufficient.)
+
+</p><pre class="synopsis">
+int PQntuples(const PGresult *res);
+</pre><p>
+
+ </p></dd><dt id="LIBPQ-PQNFIELDS"><span class="term"><code class="function">PQnfields</code><a id="id-1.7.3.10.4.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the number of columns (fields) in each row of the query
+ result.
+
+</p><pre class="synopsis">
+int PQnfields(const PGresult *res);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQFNAME"><span class="term"><code class="function">PQfname</code><a id="id-1.7.3.10.4.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the column name associated with the given column number.
+ Column numbers start at 0. The caller should not free the result
+ directly. It will be freed when the associated
+ <code class="structname">PGresult</code> handle is passed to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+</p><pre class="synopsis">
+char *PQfname(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ <code class="symbol">NULL</code> is returned if the column number is out of range.
+ </p></dd><dt id="LIBPQ-PQFNUMBER"><span class="term"><code class="function">PQfnumber</code><a id="id-1.7.3.10.4.3.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the column number associated with the given column name.
+</p><pre class="synopsis">
+int PQfnumber(const PGresult *res,
+ const char *column_name);
+</pre><p>
+ </p><p>
+ -1 is returned if the given name does not match any column.
+ </p><p>
+ The given name is treated like an identifier in an SQL command,
+ that is, it is downcased unless double-quoted. For example, given
+ a query result generated from the SQL command:
+</p><pre class="programlisting">
+SELECT 1 AS FOO, 2 AS "BAR";
+</pre><p>
+ we would have the results:
+</p><pre class="programlisting">
+PQfname(res, 0) <em class="lineannotation"><span class="lineannotation">foo</span></em>
+PQfname(res, 1) <em class="lineannotation"><span class="lineannotation">BAR</span></em>
+PQfnumber(res, "FOO") <em class="lineannotation"><span class="lineannotation">0</span></em>
+PQfnumber(res, "foo") <em class="lineannotation"><span class="lineannotation">0</span></em>
+PQfnumber(res, "BAR") <em class="lineannotation"><span class="lineannotation">-1</span></em>
+PQfnumber(res, "\"BAR\"") <em class="lineannotation"><span class="lineannotation">1</span></em>
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQFTABLE"><span class="term"><code class="function">PQftable</code><a id="id-1.7.3.10.4.3.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the OID of the table from which the given column was
+ fetched. Column numbers start at 0.
+</p><pre class="synopsis">
+Oid PQftable(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ <code class="literal">InvalidOid</code> is returned if the column number is out of range,
+ or if the specified column is not a simple reference to a table column.
+ You can query the system table <code class="literal">pg_class</code> to determine
+ exactly which table is referenced.
+ </p><p>
+ The type <code class="type">Oid</code> and the constant
+ <code class="literal">InvalidOid</code> will be defined when you include
+ the <span class="application">libpq</span> header file. They will both
+ be some integer type.
+ </p></dd><dt id="LIBPQ-PQFTABLECOL"><span class="term"><code class="function">PQftablecol</code><a id="id-1.7.3.10.4.3.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the column number (within its table) of the column making
+ up the specified query result column. Query-result column numbers
+ start at 0, but table columns have nonzero numbers.
+</p><pre class="synopsis">
+int PQftablecol(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ Zero is returned if the column number is out of range, or if the
+ specified column is not a simple reference to a table column.
+ </p></dd><dt id="LIBPQ-PQFFORMAT"><span class="term"><code class="function">PQfformat</code><a id="id-1.7.3.10.4.3.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the format code indicating the format of the given
+ column. Column numbers start at 0.
+</p><pre class="synopsis">
+int PQfformat(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ Format code zero indicates textual data representation, while format
+ code one indicates binary representation. (Other codes are reserved
+ for future definition.)
+ </p></dd><dt id="LIBPQ-PQFTYPE"><span class="term"><code class="function">PQftype</code><a id="id-1.7.3.10.4.3.8.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the data type associated with the given column number.
+ The integer returned is the internal OID number of the type.
+ Column numbers start at 0.
+</p><pre class="synopsis">
+Oid PQftype(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ You can query the system table <code class="literal">pg_type</code> to
+ obtain the names and properties of the various data types. The
+ <acronym class="acronym">OID</acronym>s of the built-in data types are defined
+ in the file <code class="filename">catalog/pg_type_d.h</code>
+ in the <span class="productname">PostgreSQL</span>
+ installation's <code class="filename">include</code> directory.
+ </p></dd><dt id="LIBPQ-PQFMOD"><span class="term"><code class="function">PQfmod</code><a id="id-1.7.3.10.4.3.9.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the type modifier of the column associated with the
+ given column number. Column numbers start at 0.
+</p><pre class="synopsis">
+int PQfmod(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ The interpretation of modifier values is type-specific; they
+ typically indicate precision or size limits. The value -1 is
+ used to indicate <span class="quote">“<span class="quote">no information available</span>”</span>. Most data
+ types do not use modifiers, in which case the value is always
+ -1.
+ </p></dd><dt id="LIBPQ-PQFSIZE"><span class="term"><code class="function">PQfsize</code><a id="id-1.7.3.10.4.3.10.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the size in bytes of the column associated with the
+ given column number. Column numbers start at 0.
+</p><pre class="synopsis">
+int PQfsize(const PGresult *res,
+ int column_number);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQFSIZE"><code class="function">PQfsize</code></a> returns the space allocated for this column
+ in a database row, in other words the size of the server's
+ internal representation of the data type. (Accordingly, it is
+ not really very useful to clients.) A negative value indicates
+ the data type is variable-length.
+ </p></dd><dt id="LIBPQ-PQBINARYTUPLES"><span class="term"><code class="function">PQbinaryTuples</code><a id="id-1.7.3.10.4.3.11.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns 1 if the <code class="structname">PGresult</code> contains binary data
+ and 0 if it contains text data.
+</p><pre class="synopsis">
+int PQbinaryTuples(const PGresult *res);
+</pre><p>
+ </p><p>
+ This function is deprecated (except for its use in connection with
+ <code class="command">COPY</code>), because it is possible for a single
+ <code class="structname">PGresult</code> to contain text data in some columns and
+ binary data in others. <a class="xref" href="libpq-exec.html#LIBPQ-PQFFORMAT"><code class="function">PQfformat</code></a> is preferred.
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQBINARYTUPLES"><code class="function">PQbinaryTuples</code></a> returns 1 only if all columns of the
+ result are binary (format 1).
+ </p></dd><dt id="LIBPQ-PQGETVALUE"><span class="term"><code class="function">PQgetvalue</code><a id="id-1.7.3.10.4.3.12.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns a single field value of one row of a
+ <code class="structname">PGresult</code>. Row and column numbers start
+ at 0. The caller should not free the result directly. It will
+ be freed when the associated <code class="structname">PGresult</code> handle is
+ passed to <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+</p><pre class="synopsis">
+char *PQgetvalue(const PGresult *res,
+ int row_number,
+ int column_number);
+</pre><p>
+ </p><p>
+ For data in text format, the value returned by
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a> is a null-terminated character
+ string representation of the field value. For data in binary
+ format, the value is in the binary representation determined by
+ the data type's <code class="function">typsend</code> and <code class="function">typreceive</code>
+ functions. (The value is actually followed by a zero byte in
+ this case too, but that is not ordinarily useful, since the
+ value is likely to contain embedded nulls.)
+ </p><p>
+ An empty string is returned if the field value is null. See
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQGETISNULL"><code class="function">PQgetisnull</code></a> to distinguish null values from
+ empty-string values.
+ </p><p>
+ The pointer returned by <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a> points
+ to storage that is part of the <code class="structname">PGresult</code>
+ structure. One should not modify the data it points to, and one
+ must explicitly copy the data into other storage if it is to be
+ used past the lifetime of the <code class="structname">PGresult</code>
+ structure itself.
+ </p></dd><dt id="LIBPQ-PQGETISNULL"><span class="term"><code class="function">PQgetisnull</code><a id="id-1.7.3.10.4.3.13.1.2" class="indexterm"></a><a id="id-1.7.3.10.4.3.13.1.3" class="indexterm"></a></span></dt><dd><p>
+ Tests a field for a null value. Row and column numbers start
+ at 0.
+</p><pre class="synopsis">
+int PQgetisnull(const PGresult *res,
+ int row_number,
+ int column_number);
+</pre><p>
+ </p><p>
+ This function returns 1 if the field is null and 0 if it
+ contains a non-null value. (Note that
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a> will return an empty string,
+ not a null pointer, for a null field.)
+ </p></dd><dt id="LIBPQ-PQGETLENGTH"><span class="term"><code class="function">PQgetlength</code><a id="id-1.7.3.10.4.3.14.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the actual length of a field value in bytes. Row and
+ column numbers start at 0.
+</p><pre class="synopsis">
+int PQgetlength(const PGresult *res,
+ int row_number,
+ int column_number);
+</pre><p>
+ </p><p>
+ This is the actual data length for the particular data value,
+ that is, the size of the object pointed to by
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a>. For text data format this is
+ the same as <code class="function">strlen()</code>. For binary format this is
+ essential information. Note that one should <span class="emphasis"><em>not</em></span>
+ rely on <a class="xref" href="libpq-exec.html#LIBPQ-PQFSIZE"><code class="function">PQfsize</code></a> to obtain the actual data
+ length.
+ </p></dd><dt id="LIBPQ-PQNPARAMS"><span class="term"><code class="function">PQnparams</code><a id="id-1.7.3.10.4.3.15.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the number of parameters of a prepared statement.
+</p><pre class="synopsis">
+int PQnparams(const PGresult *res);
+</pre><p>
+ </p><p>
+ This function is only useful when inspecting the result of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a>. For other types of queries it
+ will return zero.
+ </p></dd><dt id="LIBPQ-PQPARAMTYPE"><span class="term"><code class="function">PQparamtype</code><a id="id-1.7.3.10.4.3.16.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the data type of the indicated statement parameter.
+ Parameter numbers start at 0.
+</p><pre class="synopsis">
+Oid PQparamtype(const PGresult *res, int param_number);
+</pre><p>
+ </p><p>
+ This function is only useful when inspecting the result of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQDESCRIBEPREPARED"><code class="function">PQdescribePrepared</code></a>. For other types of queries it
+ will return zero.
+ </p></dd><dt id="LIBPQ-PQPRINT"><span class="term"><code class="function">PQprint</code><a id="id-1.7.3.10.4.3.17.1.2" class="indexterm"></a></span></dt><dd><p>
+ Prints out all the rows and, optionally, the column names to
+ the specified output stream.
+</p><pre class="synopsis">
+void PQprint(FILE *fout, /* output stream */
+ const PGresult *res,
+ const PQprintOpt *po);
+typedef struct
+{
+ pqbool header; /* print output field headings and row count */
+ pqbool align; /* fill align the fields */
+ pqbool standard; /* old brain dead format */
+ pqbool html3; /* output HTML tables */
+ pqbool expanded; /* expand tables */
+ pqbool pager; /* use pager for output if needed */
+ char *fieldSep; /* field separator */
+ char *tableOpt; /* attributes for HTML table element */
+ char *caption; /* HTML table caption */
+ char **fieldName; /* null-terminated array of replacement field names */
+} PQprintOpt;
+</pre><p>
+ </p><p>
+ This function was formerly used by <span class="application">psql</span>
+ to print query results, but this is no longer the case. Note
+ that it assumes all the data is in text format.
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-EXEC-NONSELECT"><div class="titlepage"><div><div><h3 class="title">34.3.3. Retrieving Other Result Information</h3></div></div></div><p>
+ These functions are used to extract other information from
+ <code class="structname">PGresult</code> objects.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQCMDSTATUS"><span class="term"><code class="function">PQcmdStatus</code><a id="id-1.7.3.10.5.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the command status tag from the SQL command that generated
+ the <code class="structname">PGresult</code>.
+</p><pre class="synopsis">
+char *PQcmdStatus(PGresult *res);
+</pre><p>
+ </p><p>
+ Commonly this is just the name of the command, but it might include
+ additional data such as the number of rows processed. The caller
+ should not free the result directly. It will be freed when the
+ associated <code class="structname">PGresult</code> handle is passed to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+ </p></dd><dt id="LIBPQ-PQCMDTUPLES"><span class="term"><code class="function">PQcmdTuples</code><a id="id-1.7.3.10.5.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the number of rows affected by the SQL command.
+</p><pre class="synopsis">
+char *PQcmdTuples(PGresult *res);
+</pre><p>
+ </p><p>
+ This function returns a string containing the number of rows
+ affected by the <acronym class="acronym">SQL</acronym> statement that generated the
+ <code class="structname">PGresult</code>. This function can only be used following
+ the execution of a <code class="command">SELECT</code>, <code class="command">CREATE TABLE AS</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ <code class="command">MERGE</code>, <code class="command">MOVE</code>, <code class="command">FETCH</code>,
+ or <code class="command">COPY</code> statement, or an <code class="command">EXECUTE</code> of a
+ prepared query that contains an <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ or <code class="command">MERGE</code> statement.
+ If the command that generated the <code class="structname">PGresult</code> was anything
+ else, <a class="xref" href="libpq-exec.html#LIBPQ-PQCMDTUPLES"><code class="function">PQcmdTuples</code></a> returns an empty string. The caller
+ should not free the return value directly. It will be freed when
+ the associated <code class="structname">PGresult</code> handle is passed to
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+ </p></dd><dt id="LIBPQ-PQOIDVALUE"><span class="term"><code class="function">PQoidValue</code><a id="id-1.7.3.10.5.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the OID<a id="id-1.7.3.10.5.3.3.2.1.1" class="indexterm"></a>
+ of the inserted row, if the <acronym class="acronym">SQL</acronym> command was an
+ <code class="command">INSERT</code> that inserted exactly one row into a table that
+ has OIDs, or a <code class="command">EXECUTE</code> of a prepared query containing
+ a suitable <code class="command">INSERT</code> statement. Otherwise, this function
+ returns <code class="literal">InvalidOid</code>. This function will also
+ return <code class="literal">InvalidOid</code> if the table affected by the
+ <code class="command">INSERT</code> statement does not contain OIDs.
+</p><pre class="synopsis">
+Oid PQoidValue(const PGresult *res);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQOIDSTATUS"><span class="term"><code class="function">PQoidStatus</code><a id="id-1.7.3.10.5.3.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ This function is deprecated in favor of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQOIDVALUE"><code class="function">PQoidValue</code></a> and is not thread-safe.
+ It returns a string with the OID of the inserted row, while
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQOIDVALUE"><code class="function">PQoidValue</code></a> returns the OID value.
+</p><pre class="synopsis">
+char *PQoidStatus(const PGresult *res);
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-EXEC-ESCAPE-STRING"><div class="titlepage"><div><div><h3 class="title">34.3.4. Escaping Strings for Inclusion in SQL Commands</h3></div></div></div><a id="id-1.7.3.10.6.2" class="indexterm"></a><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQESCAPELITERAL"><span class="term"><code class="function">PQescapeLiteral</code><a id="id-1.7.3.10.6.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+</p><pre class="synopsis">
+char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a> escapes a string for
+ use within an SQL command. This is useful when inserting data
+ values as literal constants in SQL commands. Certain characters
+ (such as quotes and backslashes) must be escaped to prevent them
+ from being interpreted specially by the SQL parser.
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a> performs this operation.
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a> returns an escaped version of the
+ <em class="parameter"><code>str</code></em> parameter in memory allocated with
+ <code class="function">malloc()</code>. This memory should be freed using
+ <code class="function">PQfreemem()</code> when the result is no longer needed.
+ A terminating zero byte is not required, and should not be
+ counted in <em class="parameter"><code>length</code></em>. (If a terminating zero byte is found
+ before <em class="parameter"><code>length</code></em> bytes are processed,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a> stops at the zero; the behavior is
+ thus rather like <code class="function">strncpy</code>.) The
+ return string has all special characters replaced so that they can
+ be properly processed by the <span class="productname">PostgreSQL</span>
+ string literal parser. A terminating zero byte is also added. The
+ single quotes that must surround <span class="productname">PostgreSQL</span>
+ string literals are included in the result string.
+ </p><p>
+ On error, <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a> returns <code class="symbol">NULL</code> and a suitable
+ message is stored in the <em class="parameter"><code>conn</code></em> object.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ It is especially important to do proper escaping when handling
+ strings that were received from an untrustworthy source.
+ Otherwise there is a security risk: you are vulnerable to
+ <span class="quote">“<span class="quote">SQL injection</span>”</span> attacks wherein unwanted SQL commands are
+ fed to your database.
+ </p></div><p>
+ Note that it is neither necessary nor correct to do escaping when a data
+ value is passed as a separate parameter in <a class="xref" href="libpq-exec.html#LIBPQ-PQEXECPARAMS"><code class="function">PQexecParams</code></a> or
+ its sibling routines.
+ </p></dd><dt id="LIBPQ-PQESCAPEIDENTIFIER"><span class="term"><code class="function">PQescapeIdentifier</code><a id="id-1.7.3.10.6.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+</p><pre class="synopsis">
+char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEIDENTIFIER"><code class="function">PQescapeIdentifier</code></a> escapes a string for
+ use as an SQL identifier, such as a table, column, or function name.
+ This is useful when a user-supplied identifier might contain
+ special characters that would otherwise not be interpreted as part
+ of the identifier by the SQL parser, or when the identifier might
+ contain upper case characters whose case should be preserved.
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEIDENTIFIER"><code class="function">PQescapeIdentifier</code></a> returns a version of the
+ <em class="parameter"><code>str</code></em> parameter escaped as an SQL identifier
+ in memory allocated with <code class="function">malloc()</code>. This memory must be
+ freed using <code class="function">PQfreemem()</code> when the result is no longer
+ needed. A terminating zero byte is not required, and should not be
+ counted in <em class="parameter"><code>length</code></em>. (If a terminating zero byte is found
+ before <em class="parameter"><code>length</code></em> bytes are processed,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEIDENTIFIER"><code class="function">PQescapeIdentifier</code></a> stops at the zero; the behavior is
+ thus rather like <code class="function">strncpy</code>.) The
+ return string has all special characters replaced so that it
+ will be properly processed as an SQL identifier. A terminating zero byte
+ is also added. The return string will also be surrounded by double
+ quotes.
+ </p><p>
+ On error, <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEIDENTIFIER"><code class="function">PQescapeIdentifier</code></a> returns <code class="symbol">NULL</code> and a suitable
+ message is stored in the <em class="parameter"><code>conn</code></em> object.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ As with string literals, to prevent SQL injection attacks,
+ SQL identifiers must be escaped when they are received from an
+ untrustworthy source.
+ </p></div></dd><dt id="LIBPQ-PQESCAPESTRINGCONN"><span class="term"><code class="function">PQescapeStringConn</code><a id="id-1.7.3.10.6.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+</p><pre class="synopsis">
+size_t PQescapeStringConn(PGconn *conn,
+ char *to, const char *from, size_t length,
+ int *error);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a> escapes string literals, much like
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a>. Unlike <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPELITERAL"><code class="function">PQescapeLiteral</code></a>,
+ the caller is responsible for providing an appropriately sized buffer.
+ Furthermore, <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a> does not generate the
+ single quotes that must surround <span class="productname">PostgreSQL</span> string
+ literals; they should be provided in the SQL command that the
+ result is inserted into. The parameter <em class="parameter"><code>from</code></em> points to
+ the first character of the string that is to be escaped, and the
+ <em class="parameter"><code>length</code></em> parameter gives the number of bytes in this
+ string. A terminating zero byte is not required, and should not be
+ counted in <em class="parameter"><code>length</code></em>. (If a terminating zero byte is found
+ before <em class="parameter"><code>length</code></em> bytes are processed,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a> stops at the zero; the behavior is
+ thus rather like <code class="function">strncpy</code>.) <em class="parameter"><code>to</code></em> shall point
+ to a buffer that is able to hold at least one more byte than twice
+ the value of <em class="parameter"><code>length</code></em>, otherwise the behavior is undefined.
+ Behavior is likewise undefined if the <em class="parameter"><code>to</code></em> and
+ <em class="parameter"><code>from</code></em> strings overlap.
+ </p><p>
+ If the <em class="parameter"><code>error</code></em> parameter is not <code class="symbol">NULL</code>, then
+ <code class="literal">*error</code> is set to zero on success, nonzero on error.
+ Presently the only possible error conditions involve invalid multibyte
+ encoding in the source string. The output string is still generated
+ on error, but it can be expected that the server will reject it as
+ malformed. On error, a suitable message is stored in the
+ <em class="parameter"><code>conn</code></em> object, whether or not <em class="parameter"><code>error</code></em> is <code class="symbol">NULL</code>.
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a> returns the number of bytes written
+ to <em class="parameter"><code>to</code></em>, not including the terminating zero byte.
+ </p></dd><dt id="LIBPQ-PQESCAPESTRING"><span class="term"><code class="function">PQescapeString</code><a id="id-1.7.3.10.6.3.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRING"><code class="function">PQescapeString</code></a> is an older, deprecated version of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a>.
+</p><pre class="synopsis">
+size_t PQescapeString (char *to, const char *from, size_t length);
+</pre><p>
+ </p><p>
+ The only difference from <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a> is that
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRING"><code class="function">PQescapeString</code></a> does not take <code class="structname">PGconn</code>
+ or <em class="parameter"><code>error</code></em> parameters.
+ Because of this, it cannot adjust its behavior depending on the
+ connection properties (such as character encoding) and therefore
+ <span class="emphasis"><em>it might give the wrong results</em></span>. Also, it has no way
+ to report error conditions.
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRING"><code class="function">PQescapeString</code></a> can be used safely in
+ client programs that work with only one <span class="productname">PostgreSQL</span>
+ connection at a time (in this case it can find out what it needs to
+ know <span class="quote">“<span class="quote">behind the scenes</span>”</span>). In other contexts it is a security
+ hazard and should be avoided in favor of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a>.
+ </p></dd><dt id="LIBPQ-PQESCAPEBYTEACONN"><span class="term"><code class="function">PQescapeByteaConn</code><a id="id-1.7.3.10.6.3.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Escapes binary data for use within an SQL command with the type
+ <code class="type">bytea</code>. As with <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPESTRINGCONN"><code class="function">PQescapeStringConn</code></a>,
+ this is only used when inserting data directly into an SQL command string.
+</p><pre class="synopsis">
+unsigned char *PQescapeByteaConn(PGconn *conn,
+ const unsigned char *from,
+ size_t from_length,
+ size_t *to_length);
+</pre><p>
+ </p><p>
+ Certain byte values must be escaped when used as part of a
+ <code class="type">bytea</code> literal in an <acronym class="acronym">SQL</acronym> statement.
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEACONN"><code class="function">PQescapeByteaConn</code></a> escapes bytes using
+ either hex encoding or backslash escaping. See <a class="xref" href="datatype-binary.html" title="8.4. Binary Data Types">Section 8.4</a> for more information.
+ </p><p>
+ The <em class="parameter"><code>from</code></em> parameter points to the first
+ byte of the string that is to be escaped, and the
+ <em class="parameter"><code>from_length</code></em> parameter gives the number of
+ bytes in this binary string. (A terminating zero byte is
+ neither necessary nor counted.) The <em class="parameter"><code>to_length</code></em>
+ parameter points to a variable that will hold the resultant
+ escaped string length. This result string length includes the terminating
+ zero byte of the result.
+ </p><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEACONN"><code class="function">PQescapeByteaConn</code></a> returns an escaped version of the
+ <em class="parameter"><code>from</code></em> parameter binary string in memory
+ allocated with <code class="function">malloc()</code>. This memory should be freed using
+ <code class="function">PQfreemem()</code> when the result is no longer needed. The
+ return string has all special characters replaced so that they can
+ be properly processed by the <span class="productname">PostgreSQL</span>
+ string literal parser, and the <code class="type">bytea</code> input function. A
+ terminating zero byte is also added. The single quotes that must
+ surround <span class="productname">PostgreSQL</span> string literals are
+ not part of the result string.
+ </p><p>
+ On error, a null pointer is returned, and a suitable error message
+ is stored in the <em class="parameter"><code>conn</code></em> object. Currently, the only
+ possible error is insufficient memory for the result string.
+ </p></dd><dt id="LIBPQ-PQESCAPEBYTEA"><span class="term"><code class="function">PQescapeBytea</code><a id="id-1.7.3.10.6.3.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEA"><code class="function">PQescapeBytea</code></a> is an older, deprecated version of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEACONN"><code class="function">PQescapeByteaConn</code></a>.
+</p><pre class="synopsis">
+unsigned char *PQescapeBytea(const unsigned char *from,
+ size_t from_length,
+ size_t *to_length);
+</pre><p>
+ </p><p>
+ The only difference from <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEACONN"><code class="function">PQescapeByteaConn</code></a> is that
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEA"><code class="function">PQescapeBytea</code></a> does not take a <code class="structname">PGconn</code>
+ parameter. Because of this, <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEA"><code class="function">PQescapeBytea</code></a> can
+ only be used safely in client programs that use a single
+ <span class="productname">PostgreSQL</span> connection at a time (in this case
+ it can find out what it needs to know <span class="quote">“<span class="quote">behind the
+ scenes</span>”</span>). It <span class="emphasis"><em>might give the wrong results</em></span> if
+ used in programs that use multiple database connections (use
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEACONN"><code class="function">PQescapeByteaConn</code></a> in such cases).
+ </p></dd><dt id="LIBPQ-PQUNESCAPEBYTEA"><span class="term"><code class="function">PQunescapeBytea</code><a id="id-1.7.3.10.6.3.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Converts a string representation of binary data into binary data
+ — the reverse of <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEA"><code class="function">PQescapeBytea</code></a>. This
+ is needed when retrieving <code class="type">bytea</code> data in text format,
+ but not when retrieving it in binary format.
+
+</p><pre class="synopsis">
+unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
+</pre><p>
+ </p><p>
+ The <em class="parameter"><code>from</code></em> parameter points to a string
+ such as might be returned by <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a> when applied
+ to a <code class="type">bytea</code> column. <a class="xref" href="libpq-exec.html#LIBPQ-PQUNESCAPEBYTEA"><code class="function">PQunescapeBytea</code></a>
+ converts this string representation into its binary representation.
+ It returns a pointer to a buffer allocated with
+ <code class="function">malloc()</code>, or <code class="symbol">NULL</code> on error, and puts the size of
+ the buffer in <em class="parameter"><code>to_length</code></em>. The result must be
+ freed using <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a> when it is no longer needed.
+ </p><p>
+ This conversion is not exactly the inverse of
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEA"><code class="function">PQescapeBytea</code></a>, because the string is not expected
+ to be <span class="quote">“<span class="quote">escaped</span>”</span> when received from <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a>.
+ In particular this means there is no need for string quoting considerations,
+ and so no need for a <code class="structname">PGconn</code> parameter.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-status.html" title="34.2. Connection Status Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-async.html" title="34.4. Asynchronous Command Processing">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.2. Connection Status Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.4. Asynchronous Command Processing</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-fastpath.html b/doc/src/sgml/html/libpq-fastpath.html
new file mode 100644
index 0000000..9df84a7
--- /dev/null
+++ b/doc/src/sgml/html/libpq-fastpath.html
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.8. The Fast-Path Interface</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress" /><link rel="next" href="libpq-notify.html" title="34.9. Asynchronous Notification" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.8. The Fast-Path Interface</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-notify.html" title="34.9. Asynchronous Notification">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-FASTPATH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.8. The Fast-Path Interface</h2></div></div></div><a id="id-1.7.3.15.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a fast-path interface
+ to send simple function calls to the server.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ This interface is somewhat obsolete, as one can achieve similar
+ performance and greater functionality by setting up a prepared
+ statement to define the function call. Then, executing the statement
+ with binary transmission of parameters and results substitutes for a
+ fast-path function call.
+ </p></div><p>
+ The function <code class="function" id="LIBPQ-PQFN">PQfn</code><a id="id-1.7.3.15.5.2" class="indexterm"></a>
+ requests execution of a server function via the fast-path interface:
+</p><pre class="synopsis">
+PGresult *PQfn(PGconn *conn,
+ int fnid,
+ int *result_buf,
+ int *result_len,
+ int result_is_int,
+ const PQArgBlock *args,
+ int nargs);
+
+typedef struct
+{
+ int len;
+ int isint;
+ union
+ {
+ int *ptr;
+ int integer;
+ } u;
+} PQArgBlock;
+</pre><p>
+ </p><p>
+ The <em class="parameter"><code>fnid</code></em> argument is the OID of the function to be
+ executed. <em class="parameter"><code>args</code></em> and <em class="parameter"><code>nargs</code></em> define the
+ parameters to be passed to the function; they must match the declared
+ function argument list. When the <em class="parameter"><code>isint</code></em> field of a
+ parameter structure is true, the <em class="parameter"><code>u.integer</code></em> value is sent
+ to the server as an integer of the indicated length (this must be
+ 2 or 4 bytes); proper byte-swapping occurs. When <em class="parameter"><code>isint</code></em>
+ is false, the indicated number of bytes at <em class="parameter"><code>*u.ptr</code></em> are
+ sent with no processing; the data must be in the format expected by
+ the server for binary transmission of the function's argument data
+ type. (The declaration of <em class="parameter"><code>u.ptr</code></em> as being of
+ type <code class="type">int *</code> is historical; it would be better to consider
+ it <code class="type">void *</code>.)
+ <em class="parameter"><code>result_buf</code></em> points to the buffer in which to place
+ the function's return value. The caller must have allocated sufficient
+ space to store the return value. (There is no check!) The actual result
+ length in bytes will be returned in the integer pointed to by
+ <em class="parameter"><code>result_len</code></em>. If a 2- or 4-byte integer result
+ is expected, set <em class="parameter"><code>result_is_int</code></em> to 1, otherwise
+ set it to 0. Setting <em class="parameter"><code>result_is_int</code></em> to 1 causes
+ <span class="application">libpq</span> to byte-swap the value if necessary, so that it
+ is delivered as a proper <code class="type">int</code> value for the client machine;
+ note that a 4-byte integer is delivered into <em class="parameter"><code>*result_buf</code></em>
+ for either allowed result size.
+ When <em class="parameter"><code>result_is_int</code></em> is 0, the binary-format byte string
+ sent by the server is returned unmodified. (In this case it's better
+ to consider <em class="parameter"><code>result_buf</code></em> as being of
+ type <code class="type">void *</code>.)
+ </p><p>
+ <code class="function">PQfn</code> always returns a valid
+ <code class="structname">PGresult</code> pointer, with
+ status <code class="literal">PGRES_COMMAND_OK</code> for success
+ or <code class="literal">PGRES_FATAL_ERROR</code> if some problem was encountered.
+ The result status should be
+ checked before the result is used. The caller is responsible for
+ freeing the <code class="structname">PGresult</code> with
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> when it is no longer needed.
+ </p><p>
+ To pass a NULL argument to the function, set
+ the <em class="parameter"><code>len</code></em> field of that parameter structure
+ to <code class="literal">-1</code>; the <em class="parameter"><code>isint</code></em>
+ and <em class="parameter"><code>u</code></em> fields are then irrelevant.
+ </p><p>
+ If the function returns NULL, <em class="parameter"><code>*result_len</code></em> is set
+ to <code class="literal">-1</code>, and <em class="parameter"><code>*result_buf</code></em> is not
+ modified.
+ </p><p>
+ Note that it is not possible to handle set-valued results when using
+ this interface. Also, the function must be a plain function, not an
+ aggregate, window function, or procedure.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-notify.html" title="34.9. Asynchronous Notification">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.7. Canceling Queries in Progress </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.9. Asynchronous Notification</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-ldap.html b/doc/src/sgml/html/libpq-ldap.html
new file mode 100644
index 0000000..a626fcc
--- /dev/null
+++ b/doc/src/sgml/html/libpq-ldap.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.18. LDAP Lookup of Connection Parameters</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-pgservice.html" title="34.17. The Connection Service File" /><link rel="next" href="libpq-ssl.html" title="34.19. SSL Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.18. LDAP Lookup of Connection Parameters</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-pgservice.html" title="34.17. The Connection Service File">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-ssl.html" title="34.19. SSL Support">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-LDAP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.18. LDAP Lookup of Connection Parameters</h2></div></div></div><a id="id-1.7.3.25.2" class="indexterm"></a><p>
+ If <span class="application">libpq</span> has been compiled with LDAP support (option
+ <code class="literal"><code class="option">--with-ldap</code></code> for <code class="command">configure</code>)
+ it is possible to retrieve connection options like <code class="literal">host</code>
+ or <code class="literal">dbname</code> via LDAP from a central server.
+ The advantage is that if the connection parameters for a database change,
+ the connection information doesn't have to be updated on all client machines.
+ </p><p>
+ LDAP connection parameter lookup uses the connection service file
+ <code class="filename">pg_service.conf</code> (see <a class="xref" href="libpq-pgservice.html" title="34.17. The Connection Service File">Section 34.17</a>). A line in a
+ <code class="filename">pg_service.conf</code> stanza that starts with
+ <code class="literal">ldap://</code> will be recognized as an LDAP URL and an
+ LDAP query will be performed. The result must be a list of
+ <code class="literal">keyword = value</code> pairs which will be used to set
+ connection options. The URL must conform to
+ <a class="ulink" href="https://tools.ietf.org/html/rfc1959" target="_top">RFC 1959</a>
+ and be of the form
+</p><pre class="synopsis">
+ldap://[<em class="replaceable"><code>hostname</code></em>[:<em class="replaceable"><code>port</code></em>]]/<em class="replaceable"><code>search_base</code></em>?<em class="replaceable"><code>attribute</code></em>?<em class="replaceable"><code>search_scope</code></em>?<em class="replaceable"><code>filter</code></em>
+</pre><p>
+ where <em class="replaceable"><code>hostname</code></em> defaults to
+ <code class="literal">localhost</code> and <em class="replaceable"><code>port</code></em>
+ defaults to 389.
+ </p><p>
+ Processing of <code class="filename">pg_service.conf</code> is terminated after
+ a successful LDAP lookup, but is continued if the LDAP server cannot
+ be contacted. This is to provide a fallback with further LDAP URL
+ lines that point to different LDAP servers, classical <code class="literal">keyword
+ = value</code> pairs, or default connection options. If you would
+ rather get an error message in this case, add a syntactically incorrect
+ line after the LDAP URL.
+ </p><p>
+ A sample LDAP entry that has been created with the LDIF file
+</p><pre class="programlisting">
+version:1
+dn:cn=mydatabase,dc=mycompany,dc=com
+changetype:add
+objectclass:top
+objectclass:device
+cn:mydatabase
+description:host=dbserver.mycompany.com
+description:port=5439
+description:dbname=mydb
+description:user=mydb_user
+description:sslmode=require
+</pre><p>
+ might be queried with the following LDAP URL:
+</p><pre class="programlisting">
+ldap://ldap.mycompany.com/dc=mycompany,dc=com?description?one?(cn=mydatabase)
+</pre><p>
+ </p><p>
+ You can also mix regular service file entries with LDAP lookups.
+ A complete example for a stanza in <code class="filename">pg_service.conf</code>
+ would be:
+</p><pre class="programlisting">
+# only host and port are stored in LDAP, specify dbname and user explicitly
+[customerdb]
+dbname=customer
+user=appuser
+ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-pgservice.html" title="34.17. The Connection Service File">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-ssl.html" title="34.19. SSL Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.17. The Connection Service File </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.19. SSL Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-misc.html b/doc/src/sgml/html/libpq-misc.html
new file mode 100644
index 0000000..646f5d9
--- /dev/null
+++ b/doc/src/sgml/html/libpq-misc.html
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.12. Miscellaneous Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-control.html" title="34.11. Control Functions" /><link rel="next" href="libpq-notice-processing.html" title="34.13. Notice Processing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.12. Miscellaneous Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-control.html" title="34.11. Control Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-notice-processing.html" title="34.13. Notice Processing">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-MISC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.12. Miscellaneous Functions</h2></div></div></div><p>
+ As always, there are some functions that just don't fit anywhere.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQFREEMEM"><span class="term"><code class="function">PQfreemem</code><a id="id-1.7.3.19.3.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Frees memory allocated by <span class="application">libpq</span>.
+</p><pre class="synopsis">
+void PQfreemem(void *ptr);
+</pre><p>
+ </p><p>
+ Frees memory allocated by <span class="application">libpq</span>, particularly
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEACONN"><code class="function">PQescapeByteaConn</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQESCAPEBYTEA"><code class="function">PQescapeBytea</code></a>,
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQUNESCAPEBYTEA"><code class="function">PQunescapeBytea</code></a>,
+ and <code class="function">PQnotifies</code>.
+ It is particularly important that this function, rather than
+ <code class="function">free()</code>, be used on Microsoft Windows. This is because
+ allocating memory in a DLL and releasing it in the application works
+ only if multithreaded/single-threaded, release/debug, and static/dynamic
+ flags are the same for the DLL and the application. On non-Microsoft
+ Windows platforms, this function is the same as the standard library
+ function <code class="function">free()</code>.
+ </p></dd><dt id="LIBPQ-PQCONNINFOFREE"><span class="term"><code class="function">PQconninfoFree</code><a id="id-1.7.3.19.3.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Frees the data structures allocated by
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNDEFAULTS"><code class="function">PQconndefaults</code></a> or <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNINFOPARSE"><code class="function">PQconninfoParse</code></a>.
+</p><pre class="synopsis">
+void PQconninfoFree(PQconninfoOption *connOptions);
+</pre><p>
+ </p><p>
+ A simple <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a> will not do for this, since
+ the array contains references to subsidiary strings.
+ </p></dd><dt id="LIBPQ-PQENCRYPTPASSWORDCONN"><span class="term"><code class="function">PQencryptPasswordConn</code><a id="id-1.7.3.19.3.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Prepares the encrypted form of a <span class="productname">PostgreSQL</span> password.
+</p><pre class="synopsis">
+char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm);
+</pre><p>
+ This function is intended to be used by client applications that
+ wish to send commands like <code class="literal">ALTER USER joe PASSWORD
+ 'pwd'</code>. It is good practice not to send the original cleartext
+ password in such a command, because it might be exposed in command
+ logs, activity displays, and so on. Instead, use this function to
+ convert the password to encrypted form before it is sent.
+ </p><p>
+ The <em class="parameter"><code>passwd</code></em> and <em class="parameter"><code>user</code></em> arguments
+ are the cleartext password, and the SQL name of the user it is for.
+ <em class="parameter"><code>algorithm</code></em> specifies the encryption algorithm
+ to use to encrypt the password. Currently supported algorithms are
+ <code class="literal">md5</code> and <code class="literal">scram-sha-256</code> (<code class="literal">on</code> and
+ <code class="literal">off</code> are also accepted as aliases for <code class="literal">md5</code>, for
+ compatibility with older server versions). Note that support for
+ <code class="literal">scram-sha-256</code> was introduced in <span class="productname">PostgreSQL</span>
+ version 10, and will not work correctly with older server versions. If
+ <em class="parameter"><code>algorithm</code></em> is <code class="symbol">NULL</code>, this function will query
+ the server for the current value of the
+ <a class="xref" href="runtime-config-connection.html#GUC-PASSWORD-ENCRYPTION">password_encryption</a> setting. That can block, and
+ will fail if the current transaction is aborted, or if the connection
+ is busy executing another query. If you wish to use the default
+ algorithm for the server but want to avoid blocking, query
+ <code class="varname">password_encryption</code> yourself before calling
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN"><code class="function">PQencryptPasswordConn</code></a>, and pass that value as the
+ <em class="parameter"><code>algorithm</code></em>.
+ </p><p>
+ The return value is a string allocated by <code class="function">malloc</code>.
+ The caller can assume the string doesn't contain any special characters
+ that would require escaping. Use <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a> to free the
+ result when done with it. On error, returns <code class="symbol">NULL</code>, and
+ a suitable message is stored in the connection object.
+ </p></dd><dt id="LIBPQ-PQENCRYPTPASSWORD"><span class="term"><code class="function">PQencryptPassword</code><a id="id-1.7.3.19.3.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Prepares the md5-encrypted form of a <span class="productname">PostgreSQL</span> password.
+</p><pre class="synopsis">
+char *PQencryptPassword(const char *passwd, const char *user);
+</pre><p>
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQENCRYPTPASSWORD"><code class="function">PQencryptPassword</code></a> is an older, deprecated version of
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQENCRYPTPASSWORDCONN"><code class="function">PQencryptPasswordConn</code></a>. The difference is that
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQENCRYPTPASSWORD"><code class="function">PQencryptPassword</code></a> does not
+ require a connection object, and <code class="literal">md5</code> is always used as the
+ encryption algorithm.
+ </p></dd><dt id="LIBPQ-PQMAKEEMPTYPGRESULT"><span class="term"><code class="function">PQmakeEmptyPGresult</code><a id="id-1.7.3.19.3.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Constructs an empty <code class="structname">PGresult</code> object with the given status.
+</p><pre class="synopsis">
+PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
+</pre><p>
+ </p><p>
+ This is <span class="application">libpq</span>'s internal function to allocate and
+ initialize an empty <code class="structname">PGresult</code> object. This
+ function returns <code class="symbol">NULL</code> if memory could not be allocated. It is
+ exported because some applications find it useful to generate result
+ objects (particularly objects with error status) themselves. If
+ <em class="parameter"><code>conn</code></em> is not null and <em class="parameter"><code>status</code></em>
+ indicates an error, the current error message of the specified
+ connection is copied into the <code class="structname">PGresult</code>.
+ Also, if <em class="parameter"><code>conn</code></em> is not null, any event procedures
+ registered in the connection are copied into the
+ <code class="structname">PGresult</code>. (They do not get
+ <code class="literal">PGEVT_RESULTCREATE</code> calls, but see
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQFIRERESULTCREATEEVENTS"><code class="function">PQfireResultCreateEvents</code></a>.)
+ Note that <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> should eventually be called
+ on the object, just as with a <code class="structname">PGresult</code>
+ returned by <span class="application">libpq</span> itself.
+ </p></dd><dt id="LIBPQ-PQFIRERESULTCREATEEVENTS"><span class="term"><code class="function">PQfireResultCreateEvents</code><a id="id-1.7.3.19.3.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Fires a <code class="literal">PGEVT_RESULTCREATE</code> event (see <a class="xref" href="libpq-events.html" title="34.14. Event System">Section 34.14</a>) for each event procedure registered in the
+ <code class="structname">PGresult</code> object. Returns non-zero for success,
+ zero if any event procedure fails.
+
+</p><pre class="synopsis">
+int PQfireResultCreateEvents(PGconn *conn, PGresult *res);
+</pre><p>
+ </p><p>
+ The <code class="literal">conn</code> argument is passed through to event procedures
+ but not used directly. It can be <code class="symbol">NULL</code> if the event
+ procedures won't use it.
+ </p><p>
+ Event procedures that have already received a
+ <code class="literal">PGEVT_RESULTCREATE</code> or <code class="literal">PGEVT_RESULTCOPY</code> event
+ for this object are not fired again.
+ </p><p>
+ The main reason that this function is separate from
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQMAKEEMPTYPGRESULT"><code class="function">PQmakeEmptyPGresult</code></a> is that it is often appropriate
+ to create a <code class="structname">PGresult</code> and fill it with data
+ before invoking the event procedures.
+ </p></dd><dt id="LIBPQ-PQCOPYRESULT"><span class="term"><code class="function">PQcopyResult</code><a id="id-1.7.3.19.3.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Makes a copy of a <code class="structname">PGresult</code> object. The copy is
+ not linked to the source result in any way and
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> must be called when the copy is no longer
+ needed. If the function fails, <code class="symbol">NULL</code> is returned.
+
+</p><pre class="synopsis">
+PGresult *PQcopyResult(const PGresult *src, int flags);
+</pre><p>
+ </p><p>
+ This is not intended to make an exact copy. The returned result is
+ always put into <code class="literal">PGRES_TUPLES_OK</code> status, and does not
+ copy any error message in the source. (It does copy the command status
+ string, however.) The <em class="parameter"><code>flags</code></em> argument determines
+ what else is copied. It is a bitwise OR of several flags.
+ <code class="literal">PG_COPYRES_ATTRS</code> specifies copying the source
+ result's attributes (column definitions).
+ <code class="literal">PG_COPYRES_TUPLES</code> specifies copying the source
+ result's tuples. (This implies copying the attributes, too.)
+ <code class="literal">PG_COPYRES_NOTICEHOOKS</code> specifies
+ copying the source result's notify hooks.
+ <code class="literal">PG_COPYRES_EVENTS</code> specifies copying the source
+ result's events. (But any instance data associated with the source
+ is not copied.)
+ The event procedures receive <code class="literal">PGEVT_RESULTCOPY</code> events.
+ </p></dd><dt id="LIBPQ-PQSETRESULTATTRS"><span class="term"><code class="function">PQsetResultAttrs</code><a id="id-1.7.3.19.3.8.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sets the attributes of a <code class="structname">PGresult</code> object.
+</p><pre class="synopsis">
+int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs);
+</pre><p>
+ </p><p>
+ The provided <em class="parameter"><code>attDescs</code></em> are copied into the result.
+ If the <em class="parameter"><code>attDescs</code></em> pointer is <code class="symbol">NULL</code> or
+ <em class="parameter"><code>numAttributes</code></em> is less than one, the request is
+ ignored and the function succeeds. If <em class="parameter"><code>res</code></em>
+ already contains attributes, the function will fail. If the function
+ fails, the return value is zero. If the function succeeds, the return
+ value is non-zero.
+ </p></dd><dt id="LIBPQ-PQSETVALUE"><span class="term"><code class="function">PQsetvalue</code><a id="id-1.7.3.19.3.9.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sets a tuple field value of a <code class="structname">PGresult</code> object.
+</p><pre class="synopsis">
+int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len);
+</pre><p>
+ </p><p>
+ The function will automatically grow the result's internal tuples array
+ as needed. However, the <em class="parameter"><code>tup_num</code></em> argument must be
+ less than or equal to <a class="xref" href="libpq-exec.html#LIBPQ-PQNTUPLES"><code class="function">PQntuples</code></a>, meaning this
+ function can only grow the tuples array one tuple at a time. But any
+ field of any existing tuple can be modified in any order. If a value at
+ <em class="parameter"><code>field_num</code></em> already exists, it will be overwritten.
+ If <em class="parameter"><code>len</code></em> is -1 or
+ <em class="parameter"><code>value</code></em> is <code class="symbol">NULL</code>, the field value
+ will be set to an SQL null value. The
+ <em class="parameter"><code>value</code></em> is copied into the result's private storage,
+ thus is no longer needed after the function
+ returns. If the function fails, the return value is zero. If the
+ function succeeds, the return value is non-zero.
+ </p></dd><dt id="LIBPQ-PQRESULTALLOC"><span class="term"><code class="function">PQresultAlloc</code><a id="id-1.7.3.19.3.10.1.2" class="indexterm"></a></span></dt><dd><p>
+ Allocate subsidiary storage for a <code class="structname">PGresult</code> object.
+</p><pre class="synopsis">
+void *PQresultAlloc(PGresult *res, size_t nBytes);
+</pre><p>
+ </p><p>
+ Any memory allocated with this function will be freed when
+ <em class="parameter"><code>res</code></em> is cleared. If the function fails,
+ the return value is <code class="symbol">NULL</code>. The result is
+ guaranteed to be adequately aligned for any type of data,
+ just as for <code class="function">malloc</code>.
+ </p></dd><dt id="LIBPQ-PQRESULTMEMORYSIZE"><span class="term"><code class="function">PQresultMemorySize</code><a id="id-1.7.3.19.3.11.1.2" class="indexterm"></a></span></dt><dd><p>
+ Retrieves the number of bytes allocated for
+ a <code class="structname">PGresult</code> object.
+</p><pre class="synopsis">
+size_t PQresultMemorySize(const PGresult *res);
+</pre><p>
+ </p><p>
+ This value is the sum of all <code class="function">malloc</code> requests
+ associated with the <code class="structname">PGresult</code> object, that is,
+ all the space that will be freed by <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a>.
+ This information can be useful for managing memory consumption.
+ </p></dd><dt id="LIBPQ-PQLIBVERSION"><span class="term"><code class="function">PQlibVersion</code><a id="id-1.7.3.19.3.12.1.2" class="indexterm"></a></span></dt><dd><p>
+ Return the version of <span class="productname">libpq</span> that is being used.
+</p><pre class="synopsis">
+int PQlibVersion(void);
+</pre><p>
+ </p><p>
+ The result of this function can be used to determine, at
+ run time, whether specific functionality is available in the currently
+ loaded version of libpq. The function can be used, for example,
+ to determine which connection options are available in
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTDB"><code class="function">PQconnectdb</code></a>.
+ </p><p>
+ The result is formed by multiplying the library's major version
+ number by 10000 and adding the minor version number. For example,
+ version 10.1 will be returned as 100001, and version 11.0 will be
+ returned as 110000.
+ </p><p>
+ Prior to major version 10, <span class="productname">PostgreSQL</span> used
+ three-part version numbers in which the first two parts together
+ represented the major version. For those
+ versions, <a class="xref" href="libpq-misc.html#LIBPQ-PQLIBVERSION"><code class="function">PQlibVersion</code></a> uses two digits for each
+ part; for example version 9.1.5 will be returned as 90105, and
+ version 9.2.0 will be returned as 90200.
+ </p><p>
+ Therefore, for purposes of determining feature compatibility,
+ applications should divide the result of <a class="xref" href="libpq-misc.html#LIBPQ-PQLIBVERSION"><code class="function">PQlibVersion</code></a>
+ by 100 not 10000 to determine a logical major version number.
+ In all release series, only the last two digits differ between
+ minor releases (bug-fix releases).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This function appeared in <span class="productname">PostgreSQL</span> version 9.1, so
+ it cannot be used to detect required functionality in earlier
+ versions, since calling it will create a link dependency
+ on version 9.1 or later.
+ </p></div></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-control.html" title="34.11. Control Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-notice-processing.html" title="34.13. Notice Processing">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.11. Control Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.13. Notice Processing</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-notice-processing.html b/doc/src/sgml/html/libpq-notice-processing.html
new file mode 100644
index 0000000..2b2dad8
--- /dev/null
+++ b/doc/src/sgml/html/libpq-notice-processing.html
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.13. Notice Processing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-misc.html" title="34.12. Miscellaneous Functions" /><link rel="next" href="libpq-events.html" title="34.14. Event System" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.13. Notice Processing</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-misc.html" title="34.12. Miscellaneous Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-events.html" title="34.14. Event System">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-NOTICE-PROCESSING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.13. Notice Processing</h2></div></div></div><a id="id-1.7.3.20.2" class="indexterm"></a><p>
+ Notice and warning messages generated by the server are not returned
+ by the query execution functions, since they do not imply failure of
+ the query. Instead they are passed to a notice handling function, and
+ execution continues normally after the handler returns. The default
+ notice handling function prints the message on
+ <code class="filename">stderr</code>, but the application can override this
+ behavior by supplying its own handling function.
+ </p><p>
+ For historical reasons, there are two levels of notice handling, called
+ the notice receiver and notice processor. The default behavior is for
+ the notice receiver to format the notice and pass a string to the notice
+ processor for printing. However, an application that chooses to provide
+ its own notice receiver will typically ignore the notice processor
+ layer and just do all the work in the notice receiver.
+ </p><p>
+ The function <code class="function" id="LIBPQ-PQSETNOTICERECEIVER">PQsetNoticeReceiver</code>
+ <a id="id-1.7.3.20.5.2" class="indexterm"></a>
+ <a id="id-1.7.3.20.5.3" class="indexterm"></a> sets or
+ examines the current notice receiver for a connection object.
+ Similarly, <code class="function" id="LIBPQ-PQSETNOTICEPROCESSOR">PQsetNoticeProcessor</code>
+ <a id="id-1.7.3.20.5.5" class="indexterm"></a>
+ <a id="id-1.7.3.20.5.6" class="indexterm"></a> sets or
+ examines the current notice processor.
+
+</p><pre class="synopsis">
+typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);
+
+PQnoticeReceiver
+PQsetNoticeReceiver(PGconn *conn,
+ PQnoticeReceiver proc,
+ void *arg);
+
+typedef void (*PQnoticeProcessor) (void *arg, const char *message);
+
+PQnoticeProcessor
+PQsetNoticeProcessor(PGconn *conn,
+ PQnoticeProcessor proc,
+ void *arg);
+</pre><p>
+
+ Each of these functions returns the previous notice receiver or
+ processor function pointer, and sets the new value. If you supply a
+ null function pointer, no action is taken, but the current pointer is
+ returned.
+ </p><p>
+ When a notice or warning message is received from the server, or
+ generated internally by <span class="application">libpq</span>, the notice
+ receiver function is called. It is passed the message in the form of
+ a <code class="symbol">PGRES_NONFATAL_ERROR</code>
+ <code class="structname">PGresult</code>. (This allows the receiver to extract
+ individual fields using <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORFIELD"><code class="function">PQresultErrorField</code></a>, or obtain a
+ complete preformatted message using <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a>
+ or <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTVERBOSEERRORMESSAGE"><code class="function">PQresultVerboseErrorMessage</code></a>.) The same
+ void pointer passed to <code class="function">PQsetNoticeReceiver</code> is also
+ passed. (This pointer can be used to access application-specific state
+ if needed.)
+ </p><p>
+ The default notice receiver simply extracts the message (using
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQRESULTERRORMESSAGE"><code class="function">PQresultErrorMessage</code></a>) and passes it to the notice
+ processor.
+ </p><p>
+ The notice processor is responsible for handling a notice or warning
+ message given in text form. It is passed the string text of the message
+ (including a trailing newline), plus a void pointer that is the same
+ one passed to <code class="function">PQsetNoticeProcessor</code>. (This pointer
+ can be used to access application-specific state if needed.)
+ </p><p>
+ The default notice processor is simply:
+</p><pre class="programlisting">
+static void
+defaultNoticeProcessor(void *arg, const char *message)
+{
+ fprintf(stderr, "%s", message);
+}
+</pre><p>
+ </p><p>
+ Once you have set a notice receiver or processor, you should expect
+ that that function could be called as long as either the
+ <code class="structname">PGconn</code> object or <code class="structname">PGresult</code> objects made
+ from it exist. At creation of a <code class="structname">PGresult</code>, the
+ <code class="structname">PGconn</code>'s current notice handling pointers are copied
+ into the <code class="structname">PGresult</code> for possible use by functions like
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQGETVALUE"><code class="function">PQgetvalue</code></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-misc.html" title="34.12. Miscellaneous Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-events.html" title="34.14. Event System">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.12. Miscellaneous Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.14. Event System</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-notify.html b/doc/src/sgml/html/libpq-notify.html
new file mode 100644
index 0000000..52528f5
--- /dev/null
+++ b/doc/src/sgml/html/libpq-notify.html
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.9. Asynchronous Notification</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-fastpath.html" title="34.8. The Fast-Path Interface" /><link rel="next" href="libpq-copy.html" title="34.10. Functions Associated with the COPY Command" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.9. Asynchronous Notification</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-fastpath.html" title="34.8. The Fast-Path Interface">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-copy.html" title="34.10. Functions Associated with the COPY Command">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-NOTIFY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.9. Asynchronous Notification</h2></div></div></div><a id="id-1.7.3.16.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> offers asynchronous notification
+ via the <code class="command">LISTEN</code> and <code class="command">NOTIFY</code>
+ commands. A client session registers its interest in a particular
+ notification channel with the <code class="command">LISTEN</code> command (and
+ can stop listening with the <code class="command">UNLISTEN</code> command). All
+ sessions listening on a particular channel will be notified
+ asynchronously when a <code class="command">NOTIFY</code> command with that
+ channel name is executed by any session. A <span class="quote">“<span class="quote">payload</span>”</span> string can
+ be passed to communicate additional data to the listeners.
+ </p><p>
+ <span class="application">libpq</span> applications submit
+ <code class="command">LISTEN</code>, <code class="command">UNLISTEN</code>,
+ and <code class="command">NOTIFY</code> commands as
+ ordinary SQL commands. The arrival of <code class="command">NOTIFY</code>
+ messages can subsequently be detected by calling
+ <code class="function" id="LIBPQ-PQNOTIFIES">PQnotifies</code>.<a id="id-1.7.3.16.4.7" class="indexterm"></a>
+ </p><p>
+ The function <code class="function">PQnotifies</code> returns the next notification
+ from a list of unhandled notification messages received from the server.
+ It returns a null pointer if there are no pending notifications. Once a
+ notification is returned from <code class="function">PQnotifies</code>, it is considered
+ handled and will be removed from the list of notifications.
+
+</p><pre class="synopsis">
+PGnotify *PQnotifies(PGconn *conn);
+
+typedef struct pgNotify
+{
+ char *relname; /* notification channel name */
+ int be_pid; /* process ID of notifying server process */
+ char *extra; /* notification payload string */
+} PGnotify;
+</pre><p>
+
+ After processing a <code class="structname">PGnotify</code> object returned
+ by <code class="function">PQnotifies</code>, be sure to free it with
+ <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a>. It is sufficient to free the
+ <code class="structname">PGnotify</code> pointer; the
+ <code class="structfield">relname</code> and <code class="structfield">extra</code>
+ fields do not represent separate allocations. (The names of these fields
+ are historical; in particular, channel names need not have anything to
+ do with relation names.)
+ </p><p>
+ <a class="xref" href="libpq-example.html#LIBPQ-EXAMPLE-2" title="Example 34.2. libpq Example Program 2">Example 34.2</a> gives a sample program that illustrates
+ the use of asynchronous notification.
+ </p><p>
+ <code class="function">PQnotifies</code> does not actually read data from the
+ server; it just returns messages previously absorbed by another
+ <span class="application">libpq</span> function. In ancient releases of
+ <span class="application">libpq</span>, the only way to ensure timely receipt
+ of <code class="command">NOTIFY</code> messages was to constantly submit commands, even
+ empty ones, and then check <code class="function">PQnotifies</code> after each
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>. While this still works, it is deprecated
+ as a waste of processing power.
+ </p><p>
+ A better way to check for <code class="command">NOTIFY</code> messages when you have no
+ useful commands to execute is to call
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a>, then check
+ <code class="function">PQnotifies</code>. You can use
+ <code class="function">select()</code> to wait for data to arrive from the
+ server, thereby using no <acronym class="acronym">CPU</acronym> power unless there is
+ something to do. (See <a class="xref" href="libpq-status.html#LIBPQ-PQSOCKET"><code class="function">PQsocket</code></a> to obtain the file
+ descriptor number to use with <code class="function">select()</code>.) Note that
+ this will work OK whether you submit commands with
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a>/<a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> or
+ simply use <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>. You should, however, remember
+ to check <code class="function">PQnotifies</code> after each
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> or <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>, to
+ see if any notifications came in during the processing of the command.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-fastpath.html" title="34.8. The Fast-Path Interface">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-copy.html" title="34.10. Functions Associated with the COPY Command">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.8. The Fast-Path Interface </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.10. Functions Associated with the <code class="command">COPY</code> Command</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-pgpass.html b/doc/src/sgml/html/libpq-pgpass.html
new file mode 100644
index 0000000..c4d37fe
--- /dev/null
+++ b/doc/src/sgml/html/libpq-pgpass.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.16. The Password File</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-envars.html" title="34.15. Environment Variables" /><link rel="next" href="libpq-pgservice.html" title="34.17. The Connection Service File" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.16. The Password File</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-envars.html" title="34.15. Environment Variables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-pgservice.html" title="34.17. The Connection Service File">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-PGPASS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.16. The Password File</h2></div></div></div><a id="id-1.7.3.23.2" class="indexterm"></a><a id="id-1.7.3.23.3" class="indexterm"></a><p>
+ The file <code class="filename">.pgpass</code> in a user's home directory can
+ contain passwords to
+ be used if the connection requires a password (and no password has been
+ specified otherwise). On Microsoft Windows the file is named
+ <code class="filename">%APPDATA%\postgresql\pgpass.conf</code> (where
+ <code class="filename">%APPDATA%</code> refers to the Application Data subdirectory in
+ the user's profile).
+ Alternatively, the password file to use can be specified
+ using the connection parameter <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-PASSFILE">passfile</a>
+ or the environment variable <code class="envar">PGPASSFILE</code>.
+ </p><p>
+ This file should contain lines of the following format:
+</p><pre class="synopsis">
+<em class="replaceable"><code>hostname</code></em>:<em class="replaceable"><code>port</code></em>:<em class="replaceable"><code>database</code></em>:<em class="replaceable"><code>username</code></em>:<em class="replaceable"><code>password</code></em>
+</pre><p>
+ (You can add a reminder comment to the file by copying the line above and
+ preceding it with <code class="literal">#</code>.)
+ Each of the first four fields can be a literal value, or
+ <code class="literal">*</code>, which matches anything. The password field from
+ the first line that matches the current connection parameters will be
+ used. (Therefore, put more-specific entries first when you are using
+ wildcards.) If an entry needs to contain <code class="literal">:</code> or
+ <code class="literal">\</code>, escape this character with <code class="literal">\</code>.
+ The host name field is matched to the <code class="literal">host</code> connection
+ parameter if that is specified, otherwise to
+ the <code class="literal">hostaddr</code> parameter if that is specified; if neither
+ are given then the host name <code class="literal">localhost</code> is searched for.
+ The host name <code class="literal">localhost</code> is also searched for when
+ the connection is a Unix-domain socket connection and
+ the <code class="literal">host</code> parameter
+ matches <span class="application">libpq</span>'s default socket directory path.
+ In a standby server, a database field of <code class="literal">replication</code>
+ matches streaming replication connections made to the primary server.
+ The database field is of limited usefulness otherwise, because users have
+ the same password for all databases in the same cluster.
+ </p><p>
+ On Unix systems, the permissions on a password file must
+ disallow any access to world or group; achieve this by a command such as
+ <code class="command">chmod 0600 ~/.pgpass</code>. If the permissions are less
+ strict than this, the file will be ignored. On Microsoft Windows, it
+ is assumed that the file is stored in a directory that is secure, so
+ no special permissions check is made.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-envars.html" title="34.15. Environment Variables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-pgservice.html" title="34.17. The Connection Service File">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.15. Environment Variables </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.17. The Connection Service File</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-pgservice.html b/doc/src/sgml/html/libpq-pgservice.html
new file mode 100644
index 0000000..e4d4775
--- /dev/null
+++ b/doc/src/sgml/html/libpq-pgservice.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.17. The Connection Service File</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-pgpass.html" title="34.16. The Password File" /><link rel="next" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.17. The Connection Service File</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-pgpass.html" title="34.16. The Password File">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-PGSERVICE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.17. The Connection Service File</h2></div></div></div><a id="id-1.7.3.24.2" class="indexterm"></a><a id="id-1.7.3.24.3" class="indexterm"></a><a id="id-1.7.3.24.4" class="indexterm"></a><p>
+ The connection service file allows libpq connection parameters to be
+ associated with a single service name. That service name can then be
+ specified in a libpq connection string, and the associated settings will be
+ used. This allows connection parameters to be modified without requiring
+ a recompile of the libpq-using application. The service name can also be
+ specified using the <code class="envar">PGSERVICE</code> environment variable.
+ </p><p>
+ Service names can be defined in either a per-user service file or a
+ system-wide file. If the same service name exists in both the user
+ and the system file, the user file takes precedence.
+ By default, the per-user service file is named
+ <code class="filename">~/.pg_service.conf</code>.
+ On Microsoft Windows, it is named
+ <code class="filename">%APPDATA%\postgresql\.pg_service.conf</code> (where
+ <code class="filename">%APPDATA%</code> refers to the Application Data subdirectory
+ in the user's profile). A different file name can be specified by
+ setting the environment variable <code class="envar">PGSERVICEFILE</code>.
+ The system-wide file is named <code class="filename">pg_service.conf</code>.
+ By default it is sought in the <code class="filename">etc</code> directory
+ of the <span class="productname">PostgreSQL</span> installation
+ (use <code class="literal">pg_config --sysconfdir</code> to identify this
+ directory precisely). Another directory, but not a different file
+ name, can be specified by setting the environment variable
+ <code class="envar">PGSYSCONFDIR</code>.
+ </p><p>
+ Either service file uses an <span class="quote">“<span class="quote">INI file</span>”</span> format where the section
+ name is the service name and the parameters are connection
+ parameters; see <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a> for a list. For
+ example:
+</p><pre class="programlisting">
+# comment
+[mydb]
+host=somehost
+port=5433
+user=admin
+</pre><p>
+ An example file is provided in
+ the <span class="productname">PostgreSQL</span> installation at
+ <code class="filename">share/pg_service.conf.sample</code>.
+ </p><p>
+ Connection parameters obtained from a service file are combined with
+ parameters obtained from other sources. A service file setting
+ overrides the corresponding environment variable, and in turn can be
+ overridden by a value given directly in the connection string.
+ For example, using the above service file, a connection string
+ <code class="literal">service=mydb port=5434</code> will use
+ host <code class="literal">somehost</code>, port <code class="literal">5434</code>,
+ user <code class="literal">admin</code>, and other parameters as set by
+ environment variables or built-in defaults.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-pgpass.html" title="34.16. The Password File">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.16. The Password File </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.18. LDAP Lookup of Connection Parameters</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-pipeline-mode.html b/doc/src/sgml/html/libpq-pipeline-mode.html
new file mode 100644
index 0000000..b6195e9
--- /dev/null
+++ b/doc/src/sgml/html/libpq-pipeline-mode.html
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.5. Pipeline Mode</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-async.html" title="34.4. Asynchronous Command Processing" /><link rel="next" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.5. Pipeline Mode</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-async.html" title="34.4. Asynchronous Command Processing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-PIPELINE-MODE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.5. Pipeline Mode</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-USING">34.5.1. Using Pipeline Mode</a></span></dt><dt><span class="sect2"><a href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">34.5.2. Functions Associated with Pipeline Mode</a></span></dt><dt><span class="sect2"><a href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-TIPS">34.5.3. When to Use Pipeline Mode</a></span></dt></dl></div><a id="id-1.7.3.12.2" class="indexterm"></a><a id="id-1.7.3.12.3" class="indexterm"></a><a id="id-1.7.3.12.4" class="indexterm"></a><p>
+ <span class="application">libpq</span> pipeline mode allows applications to
+ send a query without having to read the result of the previously
+ sent query. Taking advantage of the pipeline mode, a client will wait
+ less for the server, since multiple queries/results can be
+ sent/received in a single network transaction.
+ </p><p>
+ While pipeline mode provides a significant performance boost, writing
+ clients using the pipeline mode is more complex because it involves
+ managing a queue of pending queries and finding which result
+ corresponds to which query in the queue.
+ </p><p>
+ Pipeline mode also generally consumes more memory on both the client and server,
+ though careful and aggressive management of the send/receive queue can mitigate
+ this. This applies whether or not the connection is in blocking or non-blocking
+ mode.
+ </p><p>
+ While <span class="application">libpq</span>'s pipeline API was introduced in
+ <span class="productname">PostgreSQL</span> 14, it is a client-side feature
+ which doesn't require special server support and works on any server
+ that supports the v3 extended query protocol. For more information see
+ <a class="xref" href="protocol-flow.html#PROTOCOL-FLOW-PIPELINING" title="55.2.4. Pipelining">Section 55.2.4</a>.
+ </p><div class="sect2" id="LIBPQ-PIPELINE-USING"><div class="titlepage"><div><div><h3 class="title">34.5.1. Using Pipeline Mode</h3></div></div></div><p>
+ To issue pipelines, the application must switch the connection
+ into pipeline mode,
+ which is done with <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PQENTERPIPELINEMODE"><code class="function">PQenterPipelineMode</code></a>.
+ <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PQPIPELINESTATUS"><code class="function">PQpipelineStatus</code></a> can be used
+ to test whether pipeline mode is active.
+ In pipeline mode, only <a class="link" href="libpq-async.html" title="34.4. Asynchronous Command Processing">asynchronous operations</a>
+ that utilize the extended query protocol
+ are permitted, command strings containing multiple SQL commands are
+ disallowed, and so is <code class="literal">COPY</code>.
+ Using synchronous command execution functions
+ such as <code class="function">PQfn</code>,
+ <code class="function">PQexec</code>,
+ <code class="function">PQexecParams</code>,
+ <code class="function">PQprepare</code>,
+ <code class="function">PQexecPrepared</code>,
+ <code class="function">PQdescribePrepared</code>,
+ <code class="function">PQdescribePortal</code>,
+ is an error condition.
+ <code class="function">PQsendQuery</code> is
+ also disallowed, because it uses the simple query protocol.
+ Once all dispatched commands have had their results processed, and
+ the end pipeline result has been consumed, the application may return
+ to non-pipelined mode with <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PQEXITPIPELINEMODE"><code class="function">PQexitPipelineMode</code></a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ It is best to use pipeline mode with <span class="application">libpq</span> in
+ <a class="link" href="libpq-async.html#LIBPQ-PQSETNONBLOCKING">non-blocking mode</a>. If used
+ in blocking mode it is possible for a client/server deadlock to occur.
+ <a href="#ftn.id-1.7.3.12.9.3.1.3" class="footnote"><sup class="footnote" id="id-1.7.3.12.9.3.1.3">[15]</sup></a>
+ </p></div><div class="sect3" id="LIBPQ-PIPELINE-SENDING"><div class="titlepage"><div><div><h4 class="title">34.5.1.1. Issuing Queries</h4></div></div></div><p>
+ After entering pipeline mode, the application dispatches requests using
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPARAMS"><code class="function">PQsendQueryParams</code></a>
+ or its prepared-query sibling
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERYPREPARED"><code class="function">PQsendQueryPrepared</code></a>.
+ These requests are queued on the client-side until flushed to the server;
+ this occurs when <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PQPIPELINESYNC"><code class="function">PQpipelineSync</code></a> is used to
+ establish a synchronization point in the pipeline,
+ or when <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a> is called.
+ The functions <a class="xref" href="libpq-async.html#LIBPQ-PQSENDPREPARE"><code class="function">PQsendPrepare</code></a>,
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDDESCRIBEPREPARED"><code class="function">PQsendDescribePrepared</code></a>, and
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDDESCRIBEPORTAL"><code class="function">PQsendDescribePortal</code></a> also work in pipeline mode.
+ Result processing is described below.
+ </p><p>
+ The server executes statements, and returns results, in the order the
+ client sends them. The server will begin executing the commands in the
+ pipeline immediately, not waiting for the end of the pipeline.
+ Note that results are buffered on the server side; the server flushes
+ that buffer when a synchronization point is established with
+ <code class="function">PQpipelineSync</code>, or when
+ <code class="function">PQsendFlushRequest</code> is called.
+ If any statement encounters an error, the server aborts the current
+ transaction and does not execute any subsequent command in the queue
+ until the next synchronization point;
+ a <code class="literal">PGRES_PIPELINE_ABORTED</code> result is produced for
+ each such command.
+ (This remains true even if the commands in the pipeline would rollback
+ the transaction.)
+ Query processing resumes after the synchronization point.
+ </p><p>
+ It's fine for one operation to depend on the results of a
+ prior one; for example, one query may define a table that the next
+ query in the same pipeline uses. Similarly, an application may
+ create a named prepared statement and execute it with later
+ statements in the same pipeline.
+ </p></div><div class="sect3" id="LIBPQ-PIPELINE-RESULTS"><div class="titlepage"><div><div><h4 class="title">34.5.1.2. Processing Results</h4></div></div></div><p>
+ To process the result of one query in a pipeline, the application calls
+ <code class="function">PQgetResult</code> repeatedly and handles each result
+ until <code class="function">PQgetResult</code> returns null.
+ The result from the next query in the pipeline may then be retrieved using
+ <code class="function">PQgetResult</code> again and the cycle repeated.
+ The application handles individual statement results as normal.
+ When the results of all the queries in the pipeline have been
+ returned, <code class="function">PQgetResult</code> returns a result
+ containing the status value <code class="literal">PGRES_PIPELINE_SYNC</code>
+ </p><p>
+ The client may choose to defer result processing until the complete
+ pipeline has been sent, or interleave that with sending further
+ queries in the pipeline; see <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-INTERLEAVE" title="34.5.1.4. Interleaving Result Processing and Query Dispatch">Section 34.5.1.4</a>.
+ </p><p>
+ To enter single-row mode, call <code class="function">PQsetSingleRowMode</code>
+ before retrieving results with <code class="function">PQgetResult</code>.
+ This mode selection is effective only for the query currently
+ being processed. For more information on the use of
+ <code class="function">PQsetSingleRowMode</code>,
+ refer to <a class="xref" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Section 34.6</a>.
+ </p><p>
+ <code class="function">PQgetResult</code> behaves the same as for normal
+ asynchronous processing except that it may contain the new
+ <code class="type">PGresult</code> types <code class="literal">PGRES_PIPELINE_SYNC</code>
+ and <code class="literal">PGRES_PIPELINE_ABORTED</code>.
+ <code class="literal">PGRES_PIPELINE_SYNC</code> is reported exactly once for each
+ <code class="function">PQpipelineSync</code> at the corresponding point
+ in the pipeline.
+ <code class="literal">PGRES_PIPELINE_ABORTED</code> is emitted in place of a normal
+ query result for the first error and all subsequent results
+ until the next <code class="literal">PGRES_PIPELINE_SYNC</code>;
+ see <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-ERRORS" title="34.5.1.3. Error Handling">Section 34.5.1.3</a>.
+ </p><p>
+ <code class="function">PQisBusy</code>, <code class="function">PQconsumeInput</code>, etc
+ operate as normal when processing pipeline results. In particular,
+ a call to <code class="function">PQisBusy</code> in the middle of a pipeline
+ returns 0 if the results for all the queries issued so far have been
+ consumed.
+ </p><p>
+ <span class="application">libpq</span> does not provide any information to the
+ application about the query currently being processed (except that
+ <code class="function">PQgetResult</code> returns null to indicate that we start
+ returning the results of next query). The application must keep track
+ of the order in which it sent queries, to associate them with their
+ corresponding results.
+ Applications will typically use a state machine or a FIFO queue for this.
+ </p></div><div class="sect3" id="LIBPQ-PIPELINE-ERRORS"><div class="titlepage"><div><div><h4 class="title">34.5.1.3. Error Handling</h4></div></div></div><p>
+ From the client's perspective, after <code class="function">PQresultStatus</code>
+ returns <code class="literal">PGRES_FATAL_ERROR</code>,
+ the pipeline is flagged as aborted.
+ <code class="function">PQresultStatus</code> will report a
+ <code class="literal">PGRES_PIPELINE_ABORTED</code> result for each remaining queued
+ operation in an aborted pipeline. The result for
+ <code class="function">PQpipelineSync</code> is reported as
+ <code class="literal">PGRES_PIPELINE_SYNC</code> to signal the end of the aborted pipeline
+ and resumption of normal result processing.
+ </p><p>
+ The client <span class="emphasis"><em>must</em></span> process results with
+ <code class="function">PQgetResult</code> during error recovery.
+ </p><p>
+ If the pipeline used an implicit transaction, then operations that have
+ already executed are rolled back and operations that were queued to follow
+ the failed operation are skipped entirely. The same behavior holds if the
+ pipeline starts and commits a single explicit transaction (i.e. the first
+ statement is <code class="literal">BEGIN</code> and the last is
+ <code class="literal">COMMIT</code>) except that the session remains in an aborted
+ transaction state at the end of the pipeline. If a pipeline contains
+ <span class="emphasis"><em>multiple explicit transactions</em></span>, all transactions that
+ committed prior to the error remain committed, the currently in-progress
+ transaction is aborted, and all subsequent operations are skipped completely,
+ including subsequent transactions. If a pipeline synchronization point
+ occurs with an explicit transaction block in aborted state, the next pipeline
+ will become aborted immediately unless the next command puts the transaction
+ in normal mode with <code class="command">ROLLBACK</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The client must not assume that work is committed when it
+ <span class="emphasis"><em>sends</em></span> a <code class="literal">COMMIT</code> — only when the
+ corresponding result is received to confirm the commit is complete.
+ Because errors arrive asynchronously, the application needs to be able to
+ restart from the last <span class="emphasis"><em>received</em></span> committed change and
+ resend work done after that point if something goes wrong.
+ </p></div></div><div class="sect3" id="LIBPQ-PIPELINE-INTERLEAVE"><div class="titlepage"><div><div><h4 class="title">34.5.1.4. Interleaving Result Processing and Query Dispatch</h4></div></div></div><p>
+ To avoid deadlocks on large pipelines the client should be structured
+ around a non-blocking event loop using operating system facilities
+ such as <code class="function">select</code>, <code class="function">poll</code>,
+ <code class="function">WaitForMultipleObjectEx</code>, etc.
+ </p><p>
+ The client application should generally maintain a queue of work
+ remaining to be dispatched and a queue of work that has been dispatched
+ but not yet had its results processed. When the socket is writable
+ it should dispatch more work. When the socket is readable it should
+ read results and process them, matching them up to the next entry in
+ its corresponding results queue. Based on available memory, results from the
+ socket should be read frequently: there's no need to wait until the
+ pipeline end to read the results. Pipelines should be scoped to logical
+ units of work, usually (but not necessarily) one transaction per pipeline.
+ There's no need to exit pipeline mode and re-enter it between pipelines,
+ or to wait for one pipeline to finish before sending the next.
+ </p><p>
+ An example using <code class="function">select()</code> and a simple state
+ machine to track sent and received work is in
+ <code class="filename">src/test/modules/libpq_pipeline/libpq_pipeline.c</code>
+ in the PostgreSQL source distribution.
+ </p></div></div><div class="sect2" id="LIBPQ-PIPELINE-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">34.5.2. Functions Associated with Pipeline Mode</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQPIPELINESTATUS"><span class="term"><code class="function">PQpipelineStatus</code><a id="id-1.7.3.12.10.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the current pipeline mode status of the
+ <span class="application">libpq</span> connection.
+</p><pre class="synopsis">
+PGpipelineStatus PQpipelineStatus(const PGconn *conn);
+</pre><p>
+ </p><p>
+ <code class="function">PQpipelineStatus</code> can return one of the following values:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal">PQ_PIPELINE_ON</code>
+ </span></dt><dd><p>
+ The <span class="application">libpq</span> connection is in
+ pipeline mode.
+ </p></dd><dt><span class="term">
+ <code class="literal">PQ_PIPELINE_OFF</code>
+ </span></dt><dd><p>
+ The <span class="application">libpq</span> connection is
+ <span class="emphasis"><em>not</em></span> in pipeline mode.
+ </p></dd><dt><span class="term">
+ <code class="literal">PQ_PIPELINE_ABORTED</code>
+ </span></dt><dd><p>
+ The <span class="application">libpq</span> connection is in pipeline
+ mode and an error occurred while processing the current pipeline.
+ The aborted flag is cleared when <code class="function">PQgetResult</code>
+ returns a result of type <code class="literal">PGRES_PIPELINE_SYNC</code>.
+ </p></dd></dl></div><p>
+ </p></dd><dt id="LIBPQ-PQENTERPIPELINEMODE"><span class="term"><code class="function">PQenterPipelineMode</code><a id="id-1.7.3.12.10.2.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Causes a connection to enter pipeline mode if it is currently idle or
+ already in pipeline mode.
+
+</p><pre class="synopsis">
+int PQenterPipelineMode(PGconn *conn);
+</pre><p>
+
+ </p><p>
+ Returns 1 for success.
+ Returns 0 and has no effect if the connection is not currently
+ idle, i.e., it has a result ready, or it is waiting for more
+ input from the server, etc.
+ This function does not actually send anything to the server,
+ it just changes the <span class="application">libpq</span> connection
+ state.
+ </p></dd><dt id="LIBPQ-PQEXITPIPELINEMODE"><span class="term"><code class="function">PQexitPipelineMode</code><a id="id-1.7.3.12.10.2.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Causes a connection to exit pipeline mode if it is currently in pipeline mode
+ with an empty queue and no pending results.
+</p><pre class="synopsis">
+int PQexitPipelineMode(PGconn *conn);
+</pre><p>
+ </p><p>
+ Returns 1 for success. Returns 1 and takes no action if not in
+ pipeline mode. If the current statement isn't finished processing,
+ or <code class="function">PQgetResult</code> has not been called to collect
+ results from all previously sent query, returns 0 (in which case,
+ use <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to get more information
+ about the failure).
+ </p></dd><dt id="LIBPQ-PQPIPELINESYNC"><span class="term"><code class="function">PQpipelineSync</code><a id="id-1.7.3.12.10.2.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Marks a synchronization point in a pipeline by sending a
+ <a class="link" href="protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY" title="55.2.3. Extended Query">sync message</a>
+ and flushing the send buffer. This serves as
+ the delimiter of an implicit transaction and an error recovery
+ point; see <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-ERRORS" title="34.5.1.3. Error Handling">Section 34.5.1.3</a>.
+
+</p><pre class="synopsis">
+int PQpipelineSync(PGconn *conn);
+</pre><p>
+ </p><p>
+ Returns 1 for success. Returns 0 if the connection is not in
+ pipeline mode or sending a
+ <a class="link" href="protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY" title="55.2.3. Extended Query">sync message</a>
+ failed.
+ </p></dd><dt id="LIBPQ-PQSENDFLUSHREQUEST"><span class="term"><code class="function">PQsendFlushRequest</code><a id="id-1.7.3.12.10.2.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Sends a request for the server to flush its output buffer.
+</p><pre class="synopsis">
+int PQsendFlushRequest(PGconn *conn);
+</pre><p>
+ </p><p>
+ Returns 1 for success. Returns 0 on any failure.
+ </p><p>
+ The server flushes its output buffer automatically as a result of
+ <code class="function">PQpipelineSync</code> being called, or
+ on any request when not in pipeline mode; this function is useful
+ to cause the server to flush its output buffer in pipeline mode
+ without establishing a synchronization point.
+ Note that the request is not itself flushed to the server automatically;
+ use <code class="function">PQflush</code> if necessary.
+ </p></dd></dl></div></div><div class="sect2" id="LIBPQ-PIPELINE-TIPS"><div class="titlepage"><div><div><h3 class="title">34.5.3. When to Use Pipeline Mode</h3></div></div></div><p>
+ Much like asynchronous query mode, there is no meaningful performance
+ overhead when using pipeline mode. It increases client application complexity,
+ and extra caution is required to prevent client/server deadlocks, but
+ pipeline mode can offer considerable performance improvements, in exchange for
+ increased memory usage from leaving state around longer.
+ </p><p>
+ Pipeline mode is most useful when the server is distant, i.e., network latency
+ (<span class="quote">“<span class="quote">ping time</span>”</span>) is high, and also when many small operations
+ are being performed in rapid succession. There is usually less benefit
+ in using pipelined commands when each query takes many multiples of the client/server
+ round-trip time to execute. A 100-statement operation run on a server
+ 300 ms round-trip-time away would take 30 seconds in network latency alone
+ without pipelining; with pipelining it may spend as little as 0.3 s waiting for
+ results from the server.
+ </p><p>
+ Use pipelined commands when your application does lots of small
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code> and
+ <code class="literal">DELETE</code> operations that can't easily be transformed
+ into operations on sets, or into a <code class="literal">COPY</code> operation.
+ </p><p>
+ Pipeline mode is not useful when information from one operation is required by
+ the client to produce the next operation. In such cases, the client
+ would have to introduce a synchronization point and wait for a full client/server
+ round-trip to get the results it needs. However, it's often possible to
+ adjust the client design to exchange the required information server-side.
+ Read-modify-write cycles are especially good candidates; for example:
+</p><pre class="programlisting">
+BEGIN;
+SELECT x FROM mytable WHERE id = 42 FOR UPDATE;
+-- result: x=2
+-- client adds 1 to x:
+UPDATE mytable SET x = 3 WHERE id = 42;
+COMMIT;
+</pre><p>
+ could be much more efficiently done with:
+</p><pre class="programlisting">
+UPDATE mytable SET x = x + 1 WHERE id = 42;
+</pre><p>
+ </p><p>
+ Pipelining is less useful, and more complex, when a single pipeline contains
+ multiple transactions (see <a class="xref" href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-ERRORS" title="34.5.1.3. Error Handling">Section 34.5.1.3</a>).
+ </p></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.7.3.12.9.3.1.3" class="footnote"><p><a href="#id-1.7.3.12.9.3.1.3" class="para"><sup class="para">[15] </sup></a>
+ The client will block trying to send queries to the server, but the
+ server will block trying to send results to the client from queries
+ it has already processed. This only occurs when the client sends
+ enough queries to fill both its output buffer and the server's receive
+ buffer before it switches to processing input from the server,
+ but it's hard to predict exactly when that will happen.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-async.html" title="34.4. Asynchronous Command Processing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-single-row-mode.html" title="34.6. Retrieving Query Results Row-by-Row">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.4. Asynchronous Command Processing </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.6. Retrieving Query Results Row-by-Row</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-single-row-mode.html b/doc/src/sgml/html/libpq-single-row-mode.html
new file mode 100644
index 0000000..2b2099f
--- /dev/null
+++ b/doc/src/sgml/html/libpq-single-row-mode.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.6. Retrieving Query Results Row-by-Row</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode" /><link rel="next" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.6. Retrieving Query Results Row-by-Row</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-SINGLE-ROW-MODE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.6. Retrieving Query Results Row-by-Row</h2></div></div></div><a id="id-1.7.3.13.2" class="indexterm"></a><p>
+ Ordinarily, <span class="application">libpq</span> collects an SQL command's
+ entire result and returns it to the application as a single
+ <code class="structname">PGresult</code>. This can be unworkable for commands
+ that return a large number of rows. For such cases, applications can use
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> and <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> in
+ <em class="firstterm">single-row mode</em>. In this mode, the result row(s) are
+ returned to the application one at a time, as they are received from the
+ server.
+ </p><p>
+ To enter single-row mode, call <a class="xref" href="libpq-single-row-mode.html#LIBPQ-PQSETSINGLEROWMODE"><code class="function">PQsetSingleRowMode</code></a>
+ immediately after a successful call of <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a>
+ (or a sibling function). This mode selection is effective only for the
+ currently executing query. Then call <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>
+ repeatedly, until it returns null, as documented in <a class="xref" href="libpq-async.html" title="34.4. Asynchronous Command Processing">Section 34.4</a>. If the query returns any rows, they are returned
+ as individual <code class="structname">PGresult</code> objects, which look like
+ normal query results except for having status code
+ <code class="literal">PGRES_SINGLE_TUPLE</code> instead of
+ <code class="literal">PGRES_TUPLES_OK</code>. After the last row, or immediately if
+ the query returns zero rows, a zero-row object with status
+ <code class="literal">PGRES_TUPLES_OK</code> is returned; this is the signal that no
+ more rows will arrive. (But note that it is still necessary to continue
+ calling <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> until it returns null.) All of
+ these <code class="structname">PGresult</code> objects will contain the same row
+ description data (column names, types, etc.) that an ordinary
+ <code class="structname">PGresult</code> object for the query would have.
+ Each object should be freed with <a class="xref" href="libpq-exec.html#LIBPQ-PQCLEAR"><code class="function">PQclear</code></a> as usual.
+ </p><p>
+ When using pipeline mode, single-row mode needs to be activated for each
+ query in the pipeline before retrieving results for that query
+ with <code class="function">PQgetResult</code>.
+ See <a class="xref" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode">Section 34.5</a> for more information.
+ </p><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQSETSINGLEROWMODE"><span class="term"><code class="function">PQsetSingleRowMode</code><a id="id-1.7.3.13.6.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Select single-row mode for the currently-executing query.
+
+</p><pre class="synopsis">
+int PQsetSingleRowMode(PGconn *conn);
+</pre><p>
+ </p><p>
+ This function can only be called immediately after
+ <a class="xref" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery</code></a> or one of its sibling functions,
+ before any other operation on the connection such as
+ <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>
+ </a> or
+ <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>. If called at the correct time,
+ the function activates single-row mode for the current query and
+ returns 1. Otherwise the mode stays unchanged and the function
+ returns 0. In any case, the mode reverts to normal after
+ completion of the current query.
+ </p></dd></dl></div><p>
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ While processing a query, the server may return some rows and then
+ encounter an error, causing the query to be aborted. Ordinarily,
+ <span class="application">libpq</span> discards any such rows and reports only the
+ error. But in single-row mode, those rows will have already been
+ returned to the application. Hence, the application will see some
+ <code class="literal">PGRES_SINGLE_TUPLE</code> <code class="structname">PGresult</code>
+ objects followed by a <code class="literal">PGRES_FATAL_ERROR</code> object. For
+ proper transactional behavior, the application must be designed to
+ discard or undo whatever has been done with the previously-processed
+ rows, if the query ultimately fails.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-cancel.html" title="34.7. Canceling Queries in Progress">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.5. Pipeline Mode </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.7. Canceling Queries in Progress</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-ssl.html b/doc/src/sgml/html/libpq-ssl.html
new file mode 100644
index 0000000..eefd647
--- /dev/null
+++ b/doc/src/sgml/html/libpq-ssl.html
@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.19. SSL Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters" /><link rel="next" href="libpq-threading.html" title="34.20. Behavior in Threaded Programs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.19. SSL Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-threading.html" title="34.20. Behavior in Threaded Programs">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-SSL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.19. SSL Support</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-ssl.html#LIBQ-SSL-CERTIFICATES">34.19.1. Client Verification of Server Certificates</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-CLIENTCERT">34.19.2. Client Certificates</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-PROTECTION">34.19.3. Protection Provided in Different Modes</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-FILEUSAGE">34.19.4. SSL Client File Usage</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-INITIALIZE">34.19.5. SSL Library Initialization</a></span></dt></dl></div><a id="id-1.7.3.26.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> has native support for using <acronym class="acronym">SSL</acronym>
+ connections to encrypt client/server communications using
+ <acronym class="acronym">TLS</acronym> protocols for increased security.
+ See <a class="xref" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Section 19.9</a> for details about the server-side
+ <acronym class="acronym">SSL</acronym> functionality.
+ </p><p>
+ <span class="application">libpq</span> reads the system-wide
+ <span class="productname">OpenSSL</span> configuration file. By default, this
+ file is named <code class="filename">openssl.cnf</code> and is located in the
+ directory reported by <code class="literal">openssl version -d</code>. This default
+ can be overridden by setting environment variable
+ <code class="envar">OPENSSL_CONF</code> to the name of the desired configuration
+ file.
+ </p><div class="sect2" id="LIBQ-SSL-CERTIFICATES"><div class="titlepage"><div><div><h3 class="title">34.19.1. Client Verification of Server Certificates</h3></div></div></div><p>
+ By default, <span class="productname">PostgreSQL</span> will not perform any verification of
+ the server certificate. This means that it is possible to spoof the server
+ identity (for example by modifying a DNS record or by taking over the server
+ IP address) without the client knowing. In order to prevent spoofing,
+ the client must be able to verify the server's identity via a chain of
+ trust. A chain of trust is established by placing a root (self-signed)
+ certificate authority (<acronym class="acronym">CA</acronym>) certificate on one
+ computer and a leaf certificate <span class="emphasis"><em>signed</em></span> by the
+ root certificate on another computer. It is also possible to use an
+ <span class="quote">“<span class="quote">intermediate</span>”</span> certificate which is signed by the root
+ certificate and signs leaf certificates.
+ </p><p>
+ To allow the client to verify the identity of the server, place a root
+ certificate on the client and a leaf certificate signed by the root
+ certificate on the server. To allow the server to verify the identity
+ of the client, place a root certificate on the server and a leaf
+ certificate signed by the root certificate on the client. One or more
+ intermediate certificates (usually stored with the leaf certificate)
+ can also be used to link the leaf certificate to the root certificate.
+ </p><p>
+ Once a chain of trust has been established, there are two ways for
+ the client to validate the leaf certificate sent by the server.
+ If the parameter <code class="literal">sslmode</code> is set to <code class="literal">verify-ca</code>,
+ libpq will verify that the server is trustworthy by checking the
+ certificate chain up to the root certificate stored on the client.
+ If <code class="literal">sslmode</code> is set to <code class="literal">verify-full</code>,
+ libpq will <span class="emphasis"><em>also</em></span> verify that the server host
+ name matches the name stored in the server certificate. The
+ SSL connection will fail if the server certificate cannot be
+ verified. <code class="literal">verify-full</code> is recommended in most
+ security-sensitive environments.
+ </p><p>
+ In <code class="literal">verify-full</code> mode, the host name is matched against the
+ certificate's Subject Alternative Name attribute(s) (SAN), or against the
+ Common Name attribute if no SAN of type <code class="literal">dNSName</code> is
+ present. If the certificate's name attribute starts with an asterisk
+ (<code class="literal">*</code>), the asterisk will be treated as
+ a wildcard, which will match all characters <span class="emphasis"><em>except</em></span> a dot
+ (<code class="literal">.</code>). This means the certificate will not match subdomains.
+ If the connection is made using an IP address instead of a host name, the
+ IP address will be matched (without doing any DNS lookups) against SANs of
+ type <code class="literal">iPAddress</code> or <code class="literal">dNSName</code>. If no
+ <code class="literal">iPAddress</code> SAN is present and no
+ matching <code class="literal">dNSName</code> SAN is present, the host IP address is
+ matched against the Common Name attribute.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ For backward compatibility with earlier versions of PostgreSQL, the host
+ IP address is verified in a manner different
+ from <a class="ulink" href="https://tools.ietf.org/html/rfc6125" target="_top">RFC 6125</a>.
+ The host IP address is always matched against <code class="literal">dNSName</code>
+ SANs as well as <code class="literal">iPAddress</code> SANs, and can be matched
+ against the Common Name attribute if no relevant SANs exist.
+ </p></div><p>
+ To allow server certificate verification, one or more root certificates
+ must be placed in the file <code class="filename">~/.postgresql/root.crt</code>
+ in the user's home directory. (On Microsoft Windows the file is named
+ <code class="filename">%APPDATA%\postgresql\root.crt</code>.) Intermediate
+ certificates should also be added to the file if they are needed to link
+ the certificate chain sent by the server to the root certificates
+ stored on the client.
+ </p><p>
+ Certificate Revocation List (CRL) entries are also checked
+ if the file <code class="filename">~/.postgresql/root.crl</code> exists
+ (<code class="filename">%APPDATA%\postgresql\root.crl</code> on Microsoft
+ Windows).
+ </p><p>
+ The location of the root certificate file and the CRL can be changed by
+ setting
+ the connection parameters <code class="literal">sslrootcert</code> and <code class="literal">sslcrl</code>
+ or the environment variables <code class="envar">PGSSLROOTCERT</code> and <code class="envar">PGSSLCRL</code>.
+ <code class="literal">sslcrldir</code> or the environment variable <code class="envar">PGSSLCRLDIR</code>
+ can also be used to specify a directory containing CRL files.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ For backwards compatibility with earlier versions of PostgreSQL, if a
+ root CA file exists, the behavior of
+ <code class="literal">sslmode</code>=<code class="literal">require</code> will be the same
+ as that of <code class="literal">verify-ca</code>, meaning the server certificate
+ is validated against the CA. Relying on this behavior is discouraged,
+ and applications that need certificate validation should always use
+ <code class="literal">verify-ca</code> or <code class="literal">verify-full</code>.
+ </p></div></div><div class="sect2" id="LIBPQ-SSL-CLIENTCERT"><div class="titlepage"><div><div><h3 class="title">34.19.2. Client Certificates</h3></div></div></div><p>
+ If the server attempts to verify the identity of the
+ client by requesting the client's leaf certificate,
+ <span class="application">libpq</span> will send the certificate(s) stored in
+ file <code class="filename">~/.postgresql/postgresql.crt</code> in the user's home
+ directory. The certificates must chain to the root certificate trusted
+ by the server. A matching
+ private key file <code class="filename">~/.postgresql/postgresql.key</code> must also
+ be present.
+ On Microsoft Windows these files are named
+ <code class="filename">%APPDATA%\postgresql\postgresql.crt</code> and
+ <code class="filename">%APPDATA%\postgresql\postgresql.key</code>.
+ The location of the certificate and key files can be overridden by the
+ connection parameters <code class="literal">sslcert</code>
+ and <code class="literal">sslkey</code>, or by the
+ environment variables <code class="envar">PGSSLCERT</code> and <code class="envar">PGSSLKEY</code>.
+ </p><p>
+ On Unix systems, the permissions on the private key file must disallow
+ any access to world or group; achieve this by a command such as
+ <code class="command">chmod 0600 ~/.postgresql/postgresql.key</code>.
+ Alternatively, the file can be owned by root and have group read access
+ (that is, <code class="literal">0640</code> permissions). That setup is intended
+ for installations where certificate and key files are managed by the
+ operating system. The user of <span class="application">libpq</span> should
+ then be made a member of the group that has access to those certificate
+ and key files. (On Microsoft Windows, there is no file permissions
+ check, since the <code class="filename">%APPDATA%\postgresql</code> directory is
+ presumed secure.)
+ </p><p>
+ The first certificate in <code class="filename">postgresql.crt</code> must be the
+ client's certificate because it must match the client's private key.
+ <span class="quote">“<span class="quote">Intermediate</span>”</span> certificates can be optionally appended
+ to the file — doing so avoids requiring storage of intermediate
+ certificates on the server (<a class="xref" href="runtime-config-connection.html#GUC-SSL-CA-FILE">ssl_ca_file</a>).
+ </p><p>
+ The certificate and key may be in PEM or ASN.1 DER format.
+ </p><p>
+ The key may be
+ stored in cleartext or encrypted with a passphrase using any algorithm
+ supported by <span class="productname">OpenSSL</span>, like AES-128. If the key
+ is stored encrypted, then the passphrase may be provided in the
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNECT-SSLPASSWORD">sslpassword</a> connection option. If an
+ encrypted key is supplied and the <code class="literal">sslpassword</code> option
+ is absent or blank, a password will be prompted for interactively by
+ <span class="productname">OpenSSL</span> with a
+ <code class="literal">Enter PEM pass phrase:</code> prompt if a TTY is available.
+ Applications can override the client certificate prompt and the handling
+ of the <code class="literal">sslpassword</code> parameter by supplying their own
+ key password callback; see
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQSETSSLKEYPASSHOOK-OPENSSL"><code class="function">PQsetSSLKeyPassHook_OpenSSL</code></a>.
+ </p><p>
+ For instructions on creating certificates, see <a class="xref" href="ssl-tcp.html#SSL-CERTIFICATE-CREATION" title="19.9.5. Creating Certificates">Section 19.9.5</a>.
+ </p></div><div class="sect2" id="LIBPQ-SSL-PROTECTION"><div class="titlepage"><div><div><h3 class="title">34.19.3. Protection Provided in Different Modes</h3></div></div></div><p>
+ The different values for the <code class="literal">sslmode</code> parameter provide different
+ levels of protection. SSL can provide
+ protection against three types of attacks:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Eavesdropping</span></dt><dd><p>If a third party can examine the network traffic between the
+ client and the server, it can read both connection information (including
+ the user name and password) and the data that is passed. <acronym class="acronym">SSL</acronym>
+ uses encryption to prevent this.
+ </p></dd><dt><span class="term">Man-in-the-middle (<acronym class="acronym">MITM</acronym>)</span></dt><dd><p>If a third party can modify the data while passing between the
+ client and server, it can pretend to be the server and therefore see and
+ modify data <span class="emphasis"><em>even if it is encrypted</em></span>. The third party can then
+ forward the connection information and data to the original server,
+ making it impossible to detect this attack. Common vectors to do this
+ include DNS poisoning and address hijacking, whereby the client is directed
+ to a different server than intended. There are also several other
+ attack methods that can accomplish this. <acronym class="acronym">SSL</acronym> uses certificate
+ verification to prevent this, by authenticating the server to the client.
+ </p></dd><dt><span class="term">Impersonation</span></dt><dd><p>If a third party can pretend to be an authorized client, it can
+ simply access data it should not have access to. Typically this can
+ happen through insecure password management. <acronym class="acronym">SSL</acronym> uses
+ client certificates to prevent this, by making sure that only holders
+ of valid certificates can access the server.
+ </p></dd></dl></div><p>
+ </p><p>
+ For a connection to be known SSL-secured, SSL usage must be configured
+ on <span class="emphasis"><em>both the client and the server</em></span> before the connection
+ is made. If it is only configured on the server, the client may end up
+ sending sensitive information (e.g., passwords) before
+ it knows that the server requires high security. In libpq, secure
+ connections can be ensured
+ by setting the <code class="literal">sslmode</code> parameter to <code class="literal">verify-full</code> or
+ <code class="literal">verify-ca</code>, and providing the system with a root certificate to
+ verify against. This is analogous to using an <code class="literal">https</code>
+ <acronym class="acronym">URL</acronym> for encrypted web browsing.
+ </p><p>
+ Once the server has been authenticated, the client can pass sensitive data.
+ This means that up until this point, the client does not need to know if
+ certificates will be used for authentication, making it safe to specify that
+ only in the server configuration.
+ </p><p>
+ All <acronym class="acronym">SSL</acronym> options carry overhead in the form of encryption and
+ key-exchange, so there is a trade-off that has to be made between performance
+ and security. <a class="xref" href="libpq-ssl.html#LIBPQ-SSL-SSLMODE-STATEMENTS" title="Table 34.1. SSL Mode Descriptions">Table 34.1</a>
+ illustrates the risks the different <code class="literal">sslmode</code> values
+ protect against, and what statement they make about security and overhead.
+ </p><div class="table" id="LIBPQ-SSL-SSLMODE-STATEMENTS"><p class="title"><strong>Table 34.1. SSL Mode Descriptions</strong></p><div class="table-contents"><table class="table" summary="SSL Mode Descriptions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th><code class="literal">sslmode</code></th><th>Eavesdropping protection</th><th><acronym class="acronym">MITM</acronym> protection</th><th>Statement</th></tr></thead><tbody><tr><td><code class="literal">disable</code></td><td>No</td><td>No</td><td>I don't care about security, and I don't want to pay the overhead
+ of encryption.
+ </td></tr><tr><td><code class="literal">allow</code></td><td>Maybe</td><td>No</td><td>I don't care about security, but I will pay the overhead of
+ encryption if the server insists on it.
+ </td></tr><tr><td><code class="literal">prefer</code></td><td>Maybe</td><td>No</td><td>I don't care about encryption, but I wish to pay the overhead of
+ encryption if the server supports it.
+ </td></tr><tr><td><code class="literal">require</code></td><td>Yes</td><td>No</td><td>I want my data to be encrypted, and I accept the overhead. I trust
+ that the network will make sure I always connect to the server I want.
+ </td></tr><tr><td><code class="literal">verify-ca</code></td><td>Yes</td><td>Depends on CA policy</td><td>I want my data encrypted, and I accept the overhead. I want to be
+ sure that I connect to a server that I trust.
+ </td></tr><tr><td><code class="literal">verify-full</code></td><td>Yes</td><td>Yes</td><td>I want my data encrypted, and I accept the overhead. I want to be
+ sure that I connect to a server I trust, and that it's the one I
+ specify.
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The difference between <code class="literal">verify-ca</code> and <code class="literal">verify-full</code>
+ depends on the policy of the root <acronym class="acronym">CA</acronym>. If a public
+ <acronym class="acronym">CA</acronym> is used, <code class="literal">verify-ca</code> allows connections to a server
+ that <span class="emphasis"><em>somebody else</em></span> may have registered with the <acronym class="acronym">CA</acronym>.
+ In this case, <code class="literal">verify-full</code> should always be used. If
+ a local <acronym class="acronym">CA</acronym> is used, or even a self-signed certificate, using
+ <code class="literal">verify-ca</code> often provides enough protection.
+ </p><p>
+ The default value for <code class="literal">sslmode</code> is <code class="literal">prefer</code>. As is shown
+ in the table, this makes no sense from a security point of view, and it only
+ promises performance overhead if possible. It is only provided as the default
+ for backward compatibility, and is not recommended in secure deployments.
+ </p></div><div class="sect2" id="LIBPQ-SSL-FILEUSAGE"><div class="titlepage"><div><div><h3 class="title">34.19.4. SSL Client File Usage</h3></div></div></div><p>
+ <a class="xref" href="libpq-ssl.html#LIBPQ-SSL-FILE-USAGE" title="Table 34.2. Libpq/Client SSL File Usage">Table 34.2</a> summarizes the files that are
+ relevant to the SSL setup on the client.
+ </p><div class="table" id="LIBPQ-SSL-FILE-USAGE"><p class="title"><strong>Table 34.2. Libpq/Client SSL File Usage</strong></p><div class="table-contents"><table class="table" summary="Libpq/Client SSL File Usage" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>File</th><th>Contents</th><th>Effect</th></tr></thead><tbody><tr><td><code class="filename">~/.postgresql/postgresql.crt</code></td><td>client certificate</td><td>sent to server</td></tr><tr><td><code class="filename">~/.postgresql/postgresql.key</code></td><td>client private key</td><td>proves client certificate sent by owner; does not indicate
+ certificate owner is trustworthy</td></tr><tr><td><code class="filename">~/.postgresql/root.crt</code></td><td>trusted certificate authorities</td><td>checks that server certificate is signed by a trusted certificate
+ authority</td></tr><tr><td><code class="filename">~/.postgresql/root.crl</code></td><td>certificates revoked by certificate authorities</td><td>server certificate must not be on this list</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="LIBPQ-SSL-INITIALIZE"><div class="titlepage"><div><div><h3 class="title">34.19.5. SSL Library Initialization</h3></div></div></div><p>
+ If your application initializes <code class="literal">libssl</code> and/or
+ <code class="literal">libcrypto</code> libraries and <span class="application">libpq</span>
+ is built with <acronym class="acronym">SSL</acronym> support, you should call
+ <a class="xref" href="libpq-ssl.html#LIBPQ-PQINITOPENSSL"><code class="function">PQinitOpenSSL</code></a> to tell <span class="application">libpq</span>
+ that the <code class="literal">libssl</code> and/or <code class="literal">libcrypto</code> libraries
+ have been initialized by your application, so that
+ <span class="application">libpq</span> will not also initialize those libraries.
+ However, this is unnecessary when using <span class="productname">OpenSSL</span>
+ version 1.1.0 or later, as duplicate initializations are no longer problematic.
+ </p><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQINITOPENSSL"><span class="term"><code class="function">PQinitOpenSSL</code><a id="id-1.7.3.26.9.3.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Allows applications to select which security libraries to initialize.
+</p><pre class="synopsis">
+void PQinitOpenSSL(int do_ssl, int do_crypto);
+</pre><p>
+ </p><p>
+ When <em class="parameter"><code>do_ssl</code></em> is non-zero, <span class="application">libpq</span>
+ will initialize the <span class="productname">OpenSSL</span> library before first
+ opening a database connection. When <em class="parameter"><code>do_crypto</code></em> is
+ non-zero, the <code class="literal">libcrypto</code> library will be initialized. By
+ default (if <a class="xref" href="libpq-ssl.html#LIBPQ-PQINITOPENSSL"><code class="function">PQinitOpenSSL</code></a> is not called), both libraries
+ are initialized. When SSL support is not compiled in, this function is
+ present but does nothing.
+ </p><p>
+ If your application uses and initializes either <span class="productname">OpenSSL</span>
+ or its underlying <code class="literal">libcrypto</code> library, you <span class="emphasis"><em>must</em></span>
+ call this function with zeroes for the appropriate parameter(s)
+ before first opening a database connection. Also be sure that you
+ have done that initialization before opening a database connection.
+ </p></dd><dt id="LIBPQ-PQINITSSL"><span class="term"><code class="function">PQinitSSL</code><a id="id-1.7.3.26.9.3.1.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Allows applications to select which security libraries to initialize.
+</p><pre class="synopsis">
+void PQinitSSL(int do_ssl);
+</pre><p>
+ </p><p>
+ This function is equivalent to
+ <code class="literal">PQinitOpenSSL(do_ssl, do_ssl)</code>.
+ It is sufficient for applications that initialize both or neither
+ of <span class="productname">OpenSSL</span> and <code class="literal">libcrypto</code>.
+ </p><p>
+ <a class="xref" href="libpq-ssl.html#LIBPQ-PQINITSSL"><code class="function">PQinitSSL</code></a> has been present since
+ <span class="productname">PostgreSQL</span> 8.0, while <a class="xref" href="libpq-ssl.html#LIBPQ-PQINITOPENSSL"><code class="function">PQinitOpenSSL</code></a>
+ was added in <span class="productname">PostgreSQL</span> 8.4, so <a class="xref" href="libpq-ssl.html#LIBPQ-PQINITSSL"><code class="function">PQinitSSL</code></a>
+ might be preferable for applications that need to work with older
+ versions of <span class="application">libpq</span>.
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-ldap.html" title="34.18. LDAP Lookup of Connection Parameters">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-threading.html" title="34.20. Behavior in Threaded Programs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.18. LDAP Lookup of Connection Parameters </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.20. Behavior in Threaded Programs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-status.html b/doc/src/sgml/html/libpq-status.html
new file mode 100644
index 0000000..fb209ee
--- /dev/null
+++ b/doc/src/sgml/html/libpq-status.html
@@ -0,0 +1,427 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.2. Connection Status Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-connect.html" title="34.1. Database Connection Control Functions" /><link rel="next" href="libpq-exec.html" title="34.3. Command Execution Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.2. Connection Status Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-connect.html" title="34.1. Database Connection Control Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-exec.html" title="34.3. Command Execution Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-STATUS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.2. Connection Status Functions</h2></div></div></div><p>
+ These functions can be used to interrogate the status
+ of an existing database connection object.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <a id="id-1.7.3.9.3.1.1" class="indexterm"></a>
+ <a id="id-1.7.3.9.3.1.2" class="indexterm"></a>
+ <span class="application">libpq</span> application programmers should be careful to
+ maintain the <code class="structname">PGconn</code> abstraction. Use the accessor
+ functions described below to get at the contents of <code class="structname">PGconn</code>.
+ Reference to internal <code class="structname">PGconn</code> fields using
+ <code class="filename">libpq-int.h</code> is not recommended because they are subject to change
+ in the future.
+ </p></div><p>
+ The following functions return parameter values established at connection.
+ These values are fixed for the life of the connection. If a multi-host
+ connection string is used, the values of <a class="xref" href="libpq-status.html#LIBPQ-PQHOST"><code class="function">PQhost</code></a>,
+ <a class="xref" href="libpq-status.html#LIBPQ-PQPORT"><code class="function">PQport</code></a>, and <a class="xref" href="libpq-status.html#LIBPQ-PQPASS"><code class="function">PQpass</code></a> can change if a new connection
+ is established using the same <code class="structname">PGconn</code> object. Other values
+ are fixed for the lifetime of the <code class="structname">PGconn</code> object.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQDB"><span class="term"><code class="function">PQdb</code><a id="id-1.7.3.9.4.6.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the database name of the connection.
+</p><pre class="synopsis">
+char *PQdb(const PGconn *conn);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQUSER"><span class="term"><code class="function">PQuser</code><a id="id-1.7.3.9.4.6.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the user name of the connection.
+</p><pre class="synopsis">
+char *PQuser(const PGconn *conn);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQPASS"><span class="term"><code class="function">PQpass</code><a id="id-1.7.3.9.4.6.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the password of the connection.
+</p><pre class="synopsis">
+char *PQpass(const PGconn *conn);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-status.html#LIBPQ-PQPASS"><code class="function">PQpass</code></a> will return either the password specified
+ in the connection parameters, or if there was none and the password
+ was obtained from the <a class="link" href="libpq-pgpass.html" title="34.16. The Password File">password
+ file</a>, it will return that. In the latter case,
+ if multiple hosts were specified in the connection parameters, it is
+ not possible to rely on the result of <a class="xref" href="libpq-status.html#LIBPQ-PQPASS"><code class="function">PQpass</code></a> until
+ the connection is established. The status of the connection can be
+ checked using the function <a class="xref" href="libpq-status.html#LIBPQ-PQSTATUS"><code class="function">PQstatus</code></a>.
+ </p></dd><dt id="LIBPQ-PQHOST"><span class="term"><code class="function">PQhost</code><a id="id-1.7.3.9.4.6.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the server host name of the active connection.
+ This can be a host name, an IP address, or a directory path if the
+ connection is via Unix socket. (The path case can be distinguished
+ because it will always be an absolute path, beginning
+ with <code class="literal">/</code>.)
+</p><pre class="synopsis">
+char *PQhost(const PGconn *conn);
+</pre><p>
+ </p><p>
+ If the connection parameters specified both <code class="literal">host</code> and
+ <code class="literal">hostaddr</code>, then <a class="xref" href="libpq-status.html#LIBPQ-PQHOST"><code class="function">PQhost</code></a> will
+ return the <code class="literal">host</code> information. If only
+ <code class="literal">hostaddr</code> was specified, then that is returned.
+ If multiple hosts were specified in the connection parameters,
+ <a class="xref" href="libpq-status.html#LIBPQ-PQHOST"><code class="function">PQhost</code></a> returns the host actually connected to.
+ </p><p>
+ <a class="xref" href="libpq-status.html#LIBPQ-PQHOST"><code class="function">PQhost</code></a> returns <code class="symbol">NULL</code> if the
+ <em class="parameter"><code>conn</code></em> argument is <code class="symbol">NULL</code>.
+ Otherwise, if there is an error producing the host information (perhaps
+ if the connection has not been fully established or there was an
+ error), it returns an empty string.
+ </p><p>
+ If multiple hosts were specified in the connection parameters, it is
+ not possible to rely on the result of <a class="xref" href="libpq-status.html#LIBPQ-PQHOST"><code class="function">PQhost</code></a> until
+ the connection is established. The status of the connection can be
+ checked using the function <a class="xref" href="libpq-status.html#LIBPQ-PQSTATUS"><code class="function">PQstatus</code></a>.
+ </p></dd><dt id="LIBPQ-PQHOSTADDR"><span class="term"><code class="function">PQhostaddr</code><a id="id-1.7.3.9.4.6.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the server IP address of the active connection.
+ This can be the address that a host name resolved to,
+ or an IP address provided through the <code class="literal">hostaddr</code>
+ parameter.
+</p><pre class="synopsis">
+char *PQhostaddr(const PGconn *conn);
+</pre><p>
+ </p><p>
+ <a class="xref" href="libpq-status.html#LIBPQ-PQHOSTADDR"><code class="function">PQhostaddr</code></a> returns <code class="symbol">NULL</code> if the
+ <em class="parameter"><code>conn</code></em> argument is <code class="symbol">NULL</code>.
+ Otherwise, if there is an error producing the host information
+ (perhaps if the connection has not been fully established or
+ there was an error), it returns an empty string.
+ </p></dd><dt id="LIBPQ-PQPORT"><span class="term"><code class="function">PQport</code><a id="id-1.7.3.9.4.6.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the port of the active connection.
+
+</p><pre class="synopsis">
+char *PQport(const PGconn *conn);
+</pre><p>
+ </p><p>
+ If multiple ports were specified in the connection parameters,
+ <a class="xref" href="libpq-status.html#LIBPQ-PQPORT"><code class="function">PQport</code></a> returns the port actually connected to.
+ </p><p>
+ <a class="xref" href="libpq-status.html#LIBPQ-PQPORT"><code class="function">PQport</code></a> returns <code class="symbol">NULL</code> if the
+ <em class="parameter"><code>conn</code></em> argument is <code class="symbol">NULL</code>.
+ Otherwise, if there is an error producing the port information (perhaps
+ if the connection has not been fully established or there was an
+ error), it returns an empty string.
+ </p><p>
+ If multiple ports were specified in the connection parameters, it is
+ not possible to rely on the result of <a class="xref" href="libpq-status.html#LIBPQ-PQPORT"><code class="function">PQport</code></a> until
+ the connection is established. The status of the connection can be
+ checked using the function <a class="xref" href="libpq-status.html#LIBPQ-PQSTATUS"><code class="function">PQstatus</code></a>.
+ </p></dd><dt id="LIBPQ-PQTTY"><span class="term"><code class="function">PQtty</code><a id="id-1.7.3.9.4.6.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ This function no longer does anything, but it remains for backwards
+ compatibility. The function always return an empty string, or
+ <code class="symbol">NULL</code> if the <em class="parameter"><code>conn</code></em> argument is
+ <code class="symbol">NULL</code>.
+
+</p><pre class="synopsis">
+char *PQtty(const PGconn *conn);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQOPTIONS"><span class="term"><code class="function">PQoptions</code><a id="id-1.7.3.9.4.6.8.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the command-line options passed in the connection request.
+</p><pre class="synopsis">
+char *PQoptions(const PGconn *conn);
+</pre><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ The following functions return status data that can change as operations
+ are executed on the <code class="structname">PGconn</code> object.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQSTATUS"><span class="term"><code class="function">PQstatus</code><a id="id-1.7.3.9.5.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the status of the connection.
+</p><pre class="synopsis">
+ConnStatusType PQstatus(const PGconn *conn);
+</pre><p>
+ </p><p>
+ The status can be one of a number of values. However, only two of
+ these are seen outside of an asynchronous connection procedure:
+ <code class="literal">CONNECTION_OK</code> and
+ <code class="literal">CONNECTION_BAD</code>. A good connection to the database
+ has the status <code class="literal">CONNECTION_OK</code>. A failed
+ connection attempt is signaled by status
+ <code class="literal">CONNECTION_BAD</code>. Ordinarily, an OK status will
+ remain so until <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a>, but a communications
+ failure might result in the status changing to
+ <code class="literal">CONNECTION_BAD</code> prematurely. In that case the
+ application could try to recover by calling
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQRESET"><code class="function">PQreset</code></a>.
+ </p><p>
+ See the entry for <a class="xref" href="libpq-connect.html#LIBPQ-PQCONNECTSTARTPARAMS"><code class="function">PQconnectStartParams</code></a>, <code class="function">PQconnectStart</code>
+ and <code class="function">PQconnectPoll</code> with regards to other status codes that
+ might be returned.
+ </p></dd><dt id="LIBPQ-PQTRANSACTIONSTATUS"><span class="term"><code class="function">PQtransactionStatus</code><a id="id-1.7.3.9.5.2.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the current in-transaction status of the server.
+
+</p><pre class="synopsis">
+PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
+</pre><p>
+
+ The status can be <code class="literal">PQTRANS_IDLE</code> (currently idle),
+ <code class="literal">PQTRANS_ACTIVE</code> (a command is in progress),
+ <code class="literal">PQTRANS_INTRANS</code> (idle, in a valid transaction block),
+ or <code class="literal">PQTRANS_INERROR</code> (idle, in a failed transaction block).
+ <code class="literal">PQTRANS_UNKNOWN</code> is reported if the connection is bad.
+ <code class="literal">PQTRANS_ACTIVE</code> is reported only when a query
+ has been sent to the server and not yet completed.
+ </p></dd><dt id="LIBPQ-PQPARAMETERSTATUS"><span class="term"><code class="function">PQparameterStatus</code><a id="id-1.7.3.9.5.2.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Looks up a current parameter setting of the server.
+
+</p><pre class="synopsis">
+const char *PQparameterStatus(const PGconn *conn, const char *paramName);
+</pre><p>
+
+ Certain parameter values are reported by the server automatically at
+ connection startup or whenever their values change.
+ <a class="xref" href="libpq-status.html#LIBPQ-PQPARAMETERSTATUS"><code class="function">PQparameterStatus</code></a> can be used to interrogate these settings.
+ It returns the current value of a parameter if known, or <code class="symbol">NULL</code>
+ if the parameter is not known.
+ </p><p>
+ Parameters reported as of the current release include
+ <code class="varname">server_version</code>,
+ <code class="varname">server_encoding</code>,
+ <code class="varname">client_encoding</code>,
+ <code class="varname">application_name</code>,
+ <code class="varname">default_transaction_read_only</code>,
+ <code class="varname">in_hot_standby</code>,
+ <code class="varname">is_superuser</code>,
+ <code class="varname">session_authorization</code>,
+ <code class="varname">DateStyle</code>,
+ <code class="varname">IntervalStyle</code>,
+ <code class="varname">TimeZone</code>,
+ <code class="varname">integer_datetimes</code>, and
+ <code class="varname">standard_conforming_strings</code>.
+ (<code class="varname">server_encoding</code>, <code class="varname">TimeZone</code>, and
+ <code class="varname">integer_datetimes</code> were not reported by releases before 8.0;
+ <code class="varname">standard_conforming_strings</code> was not reported by releases
+ before 8.1;
+ <code class="varname">IntervalStyle</code> was not reported by releases before 8.4;
+ <code class="varname">application_name</code> was not reported by releases before
+ 9.0;
+ <code class="varname">default_transaction_read_only</code> and
+ <code class="varname">in_hot_standby</code> were not reported by releases before
+ 14.)
+ Note that
+ <code class="varname">server_version</code>,
+ <code class="varname">server_encoding</code> and
+ <code class="varname">integer_datetimes</code>
+ cannot change after startup.
+ </p><p>
+ If no value for <code class="varname">standard_conforming_strings</code> is reported,
+ applications can assume it is <code class="literal">off</code>, that is, backslashes
+ are treated as escapes in string literals. Also, the presence of
+ this parameter can be taken as an indication that the escape string
+ syntax (<code class="literal">E'...'</code>) is accepted.
+ </p><p>
+ Although the returned pointer is declared <code class="literal">const</code>, it in fact
+ points to mutable storage associated with the <code class="literal">PGconn</code> structure.
+ It is unwise to assume the pointer will remain valid across queries.
+ </p></dd><dt id="LIBPQ-PQPROTOCOLVERSION"><span class="term"><code class="function">PQprotocolVersion</code><a id="id-1.7.3.9.5.2.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Interrogates the frontend/backend protocol being used.
+</p><pre class="synopsis">
+int PQprotocolVersion(const PGconn *conn);
+</pre><p>
+ Applications might wish to use this function to determine whether certain
+ features are supported. Currently, the possible values are 3
+ (3.0 protocol), or zero (connection bad). The protocol version will
+ not change after connection startup is complete, but it could
+ theoretically change during a connection reset. The 3.0 protocol is
+ supported by <span class="productname">PostgreSQL</span> server versions 7.4
+ and above.
+ </p></dd><dt id="LIBPQ-PQSERVERVERSION"><span class="term"><code class="function">PQserverVersion</code><a id="id-1.7.3.9.5.2.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns an integer representing the server version.
+</p><pre class="synopsis">
+int PQserverVersion(const PGconn *conn);
+</pre><p>
+ </p><p>
+ Applications might use this function to determine the version of the
+ database server they are connected to. The result is formed by
+ multiplying the server's major version number by 10000 and adding
+ the minor version number. For example, version 10.1 will be
+ returned as 100001, and version 11.0 will be returned as 110000.
+ Zero is returned if the connection is bad.
+ </p><p>
+ Prior to major version 10, <span class="productname">PostgreSQL</span> used
+ three-part version numbers in which the first two parts together
+ represented the major version. For those
+ versions, <a class="xref" href="libpq-status.html#LIBPQ-PQSERVERVERSION"><code class="function">PQserverVersion</code></a> uses two digits for each
+ part; for example version 9.1.5 will be returned as 90105, and
+ version 9.2.0 will be returned as 90200.
+ </p><p>
+ Therefore, for purposes of determining feature compatibility,
+ applications should divide the result of <a class="xref" href="libpq-status.html#LIBPQ-PQSERVERVERSION"><code class="function">PQserverVersion</code></a>
+ by 100 not 10000 to determine a logical major version number.
+ In all release series, only the last two digits differ between
+ minor releases (bug-fix releases).
+ </p></dd><dt id="LIBPQ-PQERRORMESSAGE"><span class="term"><code class="function">PQerrorMessage</code><a id="id-1.7.3.9.5.2.6.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a id="id-1.7.3.9.5.2.6.2.1.1" class="indexterm"></a> Returns the error message
+ most recently generated by an operation on the connection.
+
+</p><pre class="synopsis">
+char *PQerrorMessage(const PGconn *conn);
+</pre><p>
+
+ </p><p>
+ Nearly all <span class="application">libpq</span> functions will set a message for
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> if they fail. Note that by
+ <span class="application">libpq</span> convention, a nonempty
+ <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> result can consist of multiple lines,
+ and will include a trailing newline. The caller should not free
+ the result directly. It will be freed when the associated
+ <code class="structname">PGconn</code> handle is passed to
+ <a class="xref" href="libpq-connect.html#LIBPQ-PQFINISH"><code class="function">PQfinish</code></a>. The result string should not be
+ expected to remain the same across operations on the
+ <code class="literal">PGconn</code> structure.
+ </p></dd><dt id="LIBPQ-PQSOCKET"><span class="term"><code class="function">PQsocket</code><a id="id-1.7.3.9.5.2.7.1.2" class="indexterm"></a></span></dt><dd><p>
+ Obtains the file descriptor number of the connection socket to
+ the server. A valid descriptor will be greater than or equal
+ to 0; a result of -1 indicates that no server connection is
+ currently open. (This will not change during normal operation,
+ but could change during connection setup or reset.)
+
+</p><pre class="synopsis">
+int PQsocket(const PGconn *conn);
+</pre><p>
+
+ </p></dd><dt id="LIBPQ-PQBACKENDPID"><span class="term"><code class="function">PQbackendPID</code><a id="id-1.7.3.9.5.2.8.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the process <acronym class="acronym">ID</acronym> (PID)<a id="id-1.7.3.9.5.2.8.2.1.2" class="indexterm"></a>
+ of the backend process handling this connection.
+
+</p><pre class="synopsis">
+int PQbackendPID(const PGconn *conn);
+</pre><p>
+ </p><p>
+ The backend <acronym class="acronym">PID</acronym> is useful for debugging
+ purposes and for comparison to <code class="command">NOTIFY</code>
+ messages (which include the <acronym class="acronym">PID</acronym> of the
+ notifying backend process). Note that the
+ <acronym class="acronym">PID</acronym> belongs to a process executing on the
+ database server host, not the local host!
+ </p></dd><dt id="LIBPQ-PQCONNECTIONNEEDSPASSWORD"><span class="term"><code class="function">PQconnectionNeedsPassword</code><a id="id-1.7.3.9.5.2.9.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns true (1) if the connection authentication method
+ required a password, but none was available.
+ Returns false (0) if not.
+
+</p><pre class="synopsis">
+int PQconnectionNeedsPassword(const PGconn *conn);
+</pre><p>
+ </p><p>
+ This function can be applied after a failed connection attempt
+ to decide whether to prompt the user for a password.
+ </p></dd><dt id="LIBPQ-PQCONNECTIONUSEDPASSWORD"><span class="term"><code class="function">PQconnectionUsedPassword</code><a id="id-1.7.3.9.5.2.10.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns true (1) if the connection authentication method
+ used a password. Returns false (0) if not.
+
+</p><pre class="synopsis">
+int PQconnectionUsedPassword(const PGconn *conn);
+</pre><p>
+ </p><p>
+ This function can be applied after either a failed or successful
+ connection attempt to detect whether the server demanded a password.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following functions return information related to SSL. This information
+ usually doesn't change after a connection is established.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQSSLINUSE"><span class="term"><code class="function">PQsslInUse</code><a id="id-1.7.3.9.6.1.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns true (1) if the connection uses SSL, false (0) if not.
+
+</p><pre class="synopsis">
+int PQsslInUse(const PGconn *conn);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQSSLATTRIBUTE"><span class="term"><code class="function">PQsslAttribute</code><a id="id-1.7.3.9.6.1.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns SSL-related information about the connection.
+
+</p><pre class="synopsis">
+const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
+</pre><p>
+ </p><p>
+ The list of available attributes varies depending on the SSL library
+ being used and the type of connection. Returns NULL if the connection
+ does not use SSL or the specified attribute name is not defined for the
+ library in use.
+ </p><p>
+ The following attributes are commonly available:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">library</code></span></dt><dd><p>
+ Name of the SSL implementation in use. (Currently, only
+ <code class="literal">"OpenSSL"</code> is implemented)
+ </p></dd><dt><span class="term"><code class="literal">protocol</code></span></dt><dd><p>
+ SSL/TLS version in use. Common values
+ are <code class="literal">"TLSv1"</code>, <code class="literal">"TLSv1.1"</code>
+ and <code class="literal">"TLSv1.2"</code>, but an implementation may
+ return other strings if some other protocol is used.
+ </p></dd><dt><span class="term"><code class="literal">key_bits</code></span></dt><dd><p>
+ Number of key bits used by the encryption algorithm.
+ </p></dd><dt><span class="term"><code class="literal">cipher</code></span></dt><dd><p>
+ A short name of the ciphersuite used, e.g.,
+ <code class="literal">"DHE-RSA-DES-CBC3-SHA"</code>. The names are specific
+ to each SSL implementation.
+ </p></dd><dt><span class="term"><code class="literal">compression</code></span></dt><dd><p>
+ Returns "on" if SSL compression is in use, else it returns "off".
+ </p></dd></dl></div><p>
+ </p><p>
+ As a special case, the <code class="literal">library</code> attribute may be
+ queried without a connection by passing NULL as
+ the <code class="literal">conn</code> argument. The result will be the default
+ SSL library name, or NULL if <span class="application">libpq</span> was
+ compiled without any SSL support. (Prior
+ to <span class="productname">PostgreSQL</span> version 15, passing NULL as
+ the <code class="literal">conn</code> argument always resulted in NULL.
+ Client programs needing to differentiate between the newer and older
+ implementations of this case may check the
+ <code class="literal">LIBPQ_HAS_SSL_LIBRARY_DETECTION</code> feature macro.)
+ </p></dd><dt id="LIBPQ-PQSSLATTRIBUTENAMES"><span class="term"><code class="function">PQsslAttributeNames</code><a id="id-1.7.3.9.6.1.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns an array of SSL attribute names available.
+ The array is terminated by a NULL pointer.
+</p><pre class="synopsis">
+const char * const * PQsslAttributeNames(const PGconn *conn);
+</pre><p>
+ </p></dd><dt id="LIBPQ-PQSSLSTRUCT"><span class="term"><code class="function">PQsslStruct</code><a id="id-1.7.3.9.6.1.4.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns a pointer to an SSL-implementation-specific object describing
+ the connection. Returns NULL if the connection is not encrypted
+ or the requested type of object is not available from the connection's
+ SSL implementation.
+</p><pre class="synopsis">
+void *PQsslStruct(const PGconn *conn, const char *struct_name);
+</pre><p>
+ </p><p>
+ The struct(s) available depend on the SSL implementation in use.
+ For <span class="productname">OpenSSL</span>, there is one struct,
+ available under the name <code class="literal">OpenSSL</code>,
+ and it returns a pointer to
+ <span class="productname">OpenSSL</span>'s <code class="literal">SSL</code> struct.
+ To use this function, code along the following lines could be used:
+</p><pre class="programlisting">
+#include &lt;libpq-fe.h&gt;
+#include &lt;openssl/ssl.h&gt;
+
+...
+
+ SSL *ssl;
+
+ dbconn = PQconnectdb(...);
+ ...
+
+ ssl = PQsslStruct(dbconn, "OpenSSL");
+ if (ssl)
+ {
+ /* use OpenSSL functions to access ssl */
+ }
+</pre><p>
+ </p><p>
+ This structure can be used to verify encryption levels, check server
+ certificates, and more. Refer to the <span class="productname">OpenSSL</span>
+ documentation for information about this structure.
+ </p></dd><dt id="LIBPQ-PQGETSSL"><span class="term"><code class="function">PQgetssl</code><a id="id-1.7.3.9.6.1.5.1.2" class="indexterm"></a></span></dt><dd><p>
+ <a id="id-1.7.3.9.6.1.5.2.1.1" class="indexterm"></a>
+ Returns the SSL structure used in the connection, or NULL
+ if SSL is not in use.
+
+</p><pre class="synopsis">
+void *PQgetssl(const PGconn *conn);
+</pre><p>
+ </p><p>
+ This function is equivalent to <code class="literal">PQsslStruct(conn, "OpenSSL")</code>. It should
+ not be used in new applications, because the returned struct is
+ specific to <span class="productname">OpenSSL</span> and will not be
+ available if another <acronym class="acronym">SSL</acronym> implementation is used.
+ To check if a connection uses SSL, call
+ <a class="xref" href="libpq-status.html#LIBPQ-PQSSLINUSE"><code class="function">PQsslInUse</code></a> instead, and for more details about the
+ connection, use <a class="xref" href="libpq-status.html#LIBPQ-PQSSLATTRIBUTE"><code class="function">PQsslAttribute</code></a>.
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-connect.html" title="34.1. Database Connection Control Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-exec.html" title="34.3. Command Execution Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.1. Database Connection Control Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.3. Command Execution Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq-threading.html b/doc/src/sgml/html/libpq-threading.html
new file mode 100644
index 0000000..402f164
--- /dev/null
+++ b/doc/src/sgml/html/libpq-threading.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.20. Behavior in Threaded Programs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-ssl.html" title="34.19. SSL Support" /><link rel="next" href="libpq-build.html" title="34.21. Building libpq Programs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.20. Behavior in Threaded Programs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-ssl.html" title="34.19. SSL Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-build.html" title="34.21. Building libpq Programs">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-THREADING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.20. Behavior in Threaded Programs</h2></div></div></div><a id="id-1.7.3.27.2" class="indexterm"></a><p>
+ <span class="application">libpq</span> is reentrant and thread-safe by default.
+ You might need to use special compiler command-line
+ options when you compile your application code. Refer to your
+ system's documentation for information about how to build
+ thread-enabled applications, or look in
+ <code class="filename">src/Makefile.global</code> for <code class="literal">PTHREAD_CFLAGS</code>
+ and <code class="literal">PTHREAD_LIBS</code>. This function allows the querying of
+ <span class="application">libpq</span>'s thread-safe status:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQISTHREADSAFE"><span class="term"><code class="function">PQisthreadsafe</code><a id="id-1.7.3.27.4.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ Returns the thread safety status of the
+ <span class="application">libpq</span> library.
+</p><pre class="synopsis">
+int PQisthreadsafe();
+</pre><p>
+ </p><p>
+ Returns 1 if the <span class="application">libpq</span> is thread-safe
+ and 0 if it is not.
+ </p></dd></dl></div><p>
+ One thread restriction is that no two threads attempt to manipulate
+ the same <code class="structname">PGconn</code> object at the same time. In particular,
+ you cannot issue concurrent commands from different threads through
+ the same connection object. (If you need to run concurrent commands,
+ use multiple connections.)
+ </p><p>
+ <code class="structname">PGresult</code> objects are normally read-only after creation,
+ and so can be passed around freely between threads. However, if you use
+ any of the <code class="structname">PGresult</code>-modifying functions described in
+ <a class="xref" href="libpq-misc.html" title="34.12. Miscellaneous Functions">Section 34.12</a> or <a class="xref" href="libpq-events.html" title="34.14. Event System">Section 34.14</a>, it's up
+ to you to avoid concurrent operations on the same <code class="structname">PGresult</code>,
+ too.
+ </p><p>
+ The deprecated functions <a class="xref" href="libpq-cancel.html#LIBPQ-PQREQUESTCANCEL"><code class="function">PQrequestCancel</code></a> and
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQOIDSTATUS"><code class="function">PQoidStatus</code></a> are not thread-safe and should not be
+ used in multithread programs. <a class="xref" href="libpq-cancel.html#LIBPQ-PQREQUESTCANCEL"><code class="function">PQrequestCancel</code></a>
+ can be replaced by <a class="xref" href="libpq-cancel.html#LIBPQ-PQCANCEL"><code class="function">PQcancel</code></a>.
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQOIDSTATUS"><code class="function">PQoidStatus</code></a> can be replaced by
+ <a class="xref" href="libpq-exec.html#LIBPQ-PQOIDVALUE"><code class="function">PQoidValue</code></a>.
+ </p><p>
+ If you are using Kerberos inside your application (in addition to inside
+ <span class="application">libpq</span>), you will need to do locking around
+ Kerberos calls because Kerberos functions are not thread-safe. See
+ function <code class="function">PQregisterThreadLock</code> in the
+ <span class="application">libpq</span> source code for a way to do cooperative
+ locking between <span class="application">libpq</span> and your application.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-ssl.html" title="34.19. SSL Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-build.html" title="34.21. Building libpq Programs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.19. SSL Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.21. Building <span class="application">libpq</span> Programs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/libpq.html b/doc/src/sgml/html/libpq.html
new file mode 100644
index 0000000..dc8230e
--- /dev/null
+++ b/doc/src/sgml/html/libpq.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 34. libpq — C Library</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="client-interfaces.html" title="Part IV. Client Interfaces" /><link rel="next" href="libpq-connect.html" title="34.1. Database Connection Control Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="client-interfaces.html" title="Part IV. Client Interfaces">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><th width="60%" align="center">Part IV. Client Interfaces</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-connect.html" title="34.1. Database Connection Control Functions">Next</a></td></tr></table><hr /></div><div class="chapter" id="LIBPQ"><div class="titlepage"><div><div><h2 class="title">Chapter 34. <span class="application">libpq</span> — C Library</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="libpq-connect.html">34.1. Database Connection Control Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="libpq-connect.html#LIBPQ-CONNSTRING">34.1.1. Connection Strings</a></span></dt><dt><span class="sect2"><a href="libpq-connect.html#LIBPQ-PARAMKEYWORDS">34.1.2. Parameter Key Words</a></span></dt></dl></dd><dt><span class="sect1"><a href="libpq-status.html">34.2. Connection Status Functions</a></span></dt><dt><span class="sect1"><a href="libpq-exec.html">34.3. Command Execution Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-MAIN">34.3.1. Main Functions</a></span></dt><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-SELECT-INFO">34.3.2. Retrieving Query Result Information</a></span></dt><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-NONSELECT">34.3.3. Retrieving Other Result Information</a></span></dt><dt><span class="sect2"><a href="libpq-exec.html#LIBPQ-EXEC-ESCAPE-STRING">34.3.4. Escaping Strings for Inclusion in SQL Commands</a></span></dt></dl></dd><dt><span class="sect1"><a href="libpq-async.html">34.4. Asynchronous Command Processing</a></span></dt><dt><span class="sect1"><a href="libpq-pipeline-mode.html">34.5. Pipeline Mode</a></span></dt><dd><dl><dt><span class="sect2"><a href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-USING">34.5.1. Using Pipeline Mode</a></span></dt><dt><span class="sect2"><a href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-FUNCTIONS">34.5.2. Functions Associated with Pipeline Mode</a></span></dt><dt><span class="sect2"><a href="libpq-pipeline-mode.html#LIBPQ-PIPELINE-TIPS">34.5.3. When to Use Pipeline Mode</a></span></dt></dl></dd><dt><span class="sect1"><a href="libpq-single-row-mode.html">34.6. Retrieving Query Results Row-by-Row</a></span></dt><dt><span class="sect1"><a href="libpq-cancel.html">34.7. Canceling Queries in Progress</a></span></dt><dt><span class="sect1"><a href="libpq-fastpath.html">34.8. The Fast-Path Interface</a></span></dt><dt><span class="sect1"><a href="libpq-notify.html">34.9. Asynchronous Notification</a></span></dt><dt><span class="sect1"><a href="libpq-copy.html">34.10. Functions Associated with the <code class="command">COPY</code> Command</a></span></dt><dd><dl><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-SEND">34.10.1. Functions for Sending <code class="command">COPY</code> Data</a></span></dt><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-RECEIVE">34.10.2. Functions for Receiving <code class="command">COPY</code> Data</a></span></dt><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">34.10.3. Obsolete Functions for <code class="command">COPY</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="libpq-control.html">34.11. Control Functions</a></span></dt><dt><span class="sect1"><a href="libpq-misc.html">34.12. Miscellaneous Functions</a></span></dt><dt><span class="sect1"><a href="libpq-notice-processing.html">34.13. Notice Processing</a></span></dt><dt><span class="sect1"><a href="libpq-events.html">34.14. Event System</a></span></dt><dd><dl><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-TYPES">34.14.1. Event Types</a></span></dt><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-PROC">34.14.2. Event Callback Procedure</a></span></dt><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-FUNCS">34.14.3. Event Support Functions</a></span></dt><dt><span class="sect2"><a href="libpq-events.html#LIBPQ-EVENTS-EXAMPLE">34.14.4. Event Example</a></span></dt></dl></dd><dt><span class="sect1"><a href="libpq-envars.html">34.15. Environment Variables</a></span></dt><dt><span class="sect1"><a href="libpq-pgpass.html">34.16. The Password File</a></span></dt><dt><span class="sect1"><a href="libpq-pgservice.html">34.17. The Connection Service File</a></span></dt><dt><span class="sect1"><a href="libpq-ldap.html">34.18. LDAP Lookup of Connection Parameters</a></span></dt><dt><span class="sect1"><a href="libpq-ssl.html">34.19. SSL Support</a></span></dt><dd><dl><dt><span class="sect2"><a href="libpq-ssl.html#LIBQ-SSL-CERTIFICATES">34.19.1. Client Verification of Server Certificates</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-CLIENTCERT">34.19.2. Client Certificates</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-PROTECTION">34.19.3. Protection Provided in Different Modes</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-FILEUSAGE">34.19.4. SSL Client File Usage</a></span></dt><dt><span class="sect2"><a href="libpq-ssl.html#LIBPQ-SSL-INITIALIZE">34.19.5. SSL Library Initialization</a></span></dt></dl></dd><dt><span class="sect1"><a href="libpq-threading.html">34.20. Behavior in Threaded Programs</a></span></dt><dt><span class="sect1"><a href="libpq-build.html">34.21. Building <span class="application">libpq</span> Programs</a></span></dt><dt><span class="sect1"><a href="libpq-example.html">34.22. Example Programs</a></span></dt></dl></div><a id="id-1.7.3.2" class="indexterm"></a><a id="id-1.7.3.3" class="indexterm"></a><p>
+ <span class="application">libpq</span> is the <acronym class="acronym">C</acronym>
+ application programmer's interface to <span class="productname">PostgreSQL</span>.
+ <span class="application">libpq</span> is a set of library functions that allow
+ client programs to pass queries to the <span class="productname">PostgreSQL</span>
+ backend server and to receive the results of these queries.
+ </p><p>
+ <span class="application">libpq</span> is also the underlying engine for several
+ other <span class="productname">PostgreSQL</span> application interfaces, including
+ those written for C++, Perl, Python, Tcl and <span class="application">ECPG</span>.
+ So some aspects of <span class="application">libpq</span>'s behavior will be
+ important to you if you use one of those packages. In particular,
+ <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>,
+ <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a> and
+ <a class="xref" href="libpq-ssl.html" title="34.19. SSL Support">Section 34.19</a>
+ describe behavior that is visible to the user of any application
+ that uses <span class="application">libpq</span>.
+ </p><p>
+ Some short programs are included at the end of this chapter (<a class="xref" href="libpq-example.html" title="34.22. Example Programs">Section 34.22</a>) to show how
+ to write programs that use <span class="application">libpq</span>. There are also several
+ complete examples of <span class="application">libpq</span> applications in the
+ directory <code class="filename">src/test/examples</code> in the source code distribution.
+ </p><p>
+ Client programs that use <span class="application">libpq</span> must
+ include the header file
+ <code class="filename">libpq-fe.h</code><a id="id-1.7.3.7.3" class="indexterm"></a>
+ and must link with the <span class="application">libpq</span> library.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="client-interfaces.html" title="Part IV. Client Interfaces">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-interfaces.html" title="Part IV. Client Interfaces">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-connect.html" title="34.1. Database Connection Control Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part IV. Client Interfaces </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.1. Database Connection Control Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/limits.html b/doc/src/sgml/html/limits.html
new file mode 100644
index 0000000..1df447b
--- /dev/null
+++ b/doc/src/sgml/html/limits.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix K. PostgreSQL Limits</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="docguide-style.html" title="J.5. Style Guide" /><link rel="next" href="acronyms.html" title="Appendix L. Acronyms" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix K. <span class="productname">PostgreSQL</span> Limits</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="docguide-style.html" title="J.5. Style Guide">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="acronyms.html" title="Appendix L. Acronyms">Next</a></td></tr></table><hr /></div><div class="appendix" id="LIMITS"><div class="titlepage"><div><div><h2 class="title">Appendix K. <span class="productname">PostgreSQL</span> Limits</h2></div></div></div><p>
+ <a class="xref" href="limits.html#LIMITS-TABLE" title="Table K.1. PostgreSQL Limitations">Table K.1</a> describes various hard limits of
+ <span class="productname">PostgreSQL</span>. However, practical limits, such as
+ performance limitations or available disk space may apply before absolute
+ hard limits are reached.
+ </p><div class="table" id="LIMITS-TABLE"><p class="title"><strong>Table K.1. <span class="productname">PostgreSQL</span> Limitations</strong></p><div class="table-contents"><table class="table" summary="PostgreSQL Limitations" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Item</th><th>Upper Limit</th><th>Comment</th></tr></thead><tbody><tr><td>database size</td><td>unlimited</td><td> </td></tr><tr><td>number of databases</td><td>4,294,950,911</td><td> </td></tr><tr><td>relations per database</td><td>1,431,650,303</td><td> </td></tr><tr><td>relation size</td><td>32 TB</td><td>with the default <code class="symbol">BLCKSZ</code> of 8192 bytes</td></tr><tr><td>rows per table</td><td>limited by the number of tuples that can fit onto 4,294,967,295 pages</td><td> </td></tr><tr><td>columns per table</td><td>1600</td><td>further limited by tuple size fitting on a single page; see note
+ below</td></tr><tr><td>columns in a result set</td><td>1664</td><td> </td></tr><tr><td>field size</td><td>1 GB</td><td> </td></tr><tr><td>identifier length</td><td>63 bytes</td><td>can be increased by recompiling <span class="productname">PostgreSQL</span></td></tr><tr><td>indexes per table</td><td>unlimited</td><td>constrained by maximum relations per database</td></tr><tr><td>columns per index</td><td>32</td><td>can be increased by recompiling <span class="productname">PostgreSQL</span></td></tr><tr><td>partition keys</td><td>32</td><td>can be increased by recompiling <span class="productname">PostgreSQL</span></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The maximum number of columns for a table is further reduced as the tuple
+ being stored must fit in a single 8192-byte heap page. For example,
+ excluding the tuple header, a tuple made up of 1600 <code class="type">int</code> columns
+ would consume 6400 bytes and could be stored in a heap page, but a tuple of
+ 1600 <code class="type">bigint</code> columns would consume 12800 bytes and would
+ therefore not fit inside a heap page.
+ Variable-length fields of
+ types such as <code class="type">text</code>, <code class="type">varchar</code>, and <code class="type">char</code>
+ can have their values stored out of line in the table's TOAST table when the
+ values are large enough to require it. Only an 18-byte pointer must remain
+ inside the tuple in the table's heap. For shorter length variable-length
+ fields, either a 4-byte or 1-byte field header is used and the value is
+ stored inside the heap tuple.
+ </p><p>
+ Columns that have been dropped from the table also contribute to the maximum
+ column limit. Moreover, although the dropped column values for newly
+ created tuples are internally marked as null in the tuple's null bitmap, the
+ null bitmap also occupies space.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="docguide-style.html" title="J.5. Style Guide">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="acronyms.html" title="Appendix L. Acronyms">Next</a></td></tr><tr><td width="40%" align="left" valign="top">J.5. Style Guide </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix L. Acronyms</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/lo-examplesect.html b/doc/src/sgml/html/lo-examplesect.html
new file mode 100644
index 0000000..8968642
--- /dev/null
+++ b/doc/src/sgml/html/lo-examplesect.html
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>35.5. Example Program</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="lo-funcs.html" title="35.4. Server-Side Functions" /><link rel="next" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">35.5. Example Program</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="lo-funcs.html" title="35.4. Server-Side Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><th width="60%" align="center">Chapter 35. Large Objects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Next</a></td></tr></table><hr /></div><div class="sect1" id="LO-EXAMPLESECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">35.5. Example Program</h2></div></div></div><p>
+ <a class="xref" href="lo-examplesect.html#LO-EXAMPLE" title="Example 35.1. Large Objects with libpq Example Program">Example 35.1</a> is a sample program which shows how the large object
+ interface
+ in <span class="application">libpq</span> can be used. Parts of the program are
+ commented out but are left in the source for the reader's
+ benefit. This program can also be found in
+ <code class="filename">src/test/examples/testlo.c</code> in the source distribution.
+</p><div class="example" id="LO-EXAMPLE"><p class="title"><strong>Example 35.1. Large Objects with <span class="application">libpq</span> Example Program</strong></p><div class="example-contents"><pre class="programlisting">
+/*-----------------------------------------------------------------
+ *
+ * testlo.c
+ * test using large objects with libpq
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/test/examples/testlo.c
+ *
+ *-----------------------------------------------------------------
+ */
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+
+#include &lt;sys/types.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;unistd.h&gt;
+
+#include "libpq-fe.h"
+#include "libpq/libpq-fs.h"
+
+#define BUFSIZE 1024
+
+/*
+ * importFile -
+ * import file "in_filename" into database as large object "lobjOid"
+ *
+ */
+static Oid
+importFile(PGconn *conn, char *filename)
+{
+ Oid lobjId;
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * open the file to be read in
+ */
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd &lt; 0)
+ { /* error */
+ fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
+ }
+
+ /*
+ * create the large object
+ */
+ lobjId = lo_creat(conn, INV_READ | INV_WRITE);
+ if (lobjId == 0)
+ fprintf(stderr, "cannot create large object");
+
+ lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0)
+ {
+ tmp = lo_write(conn, lobj_fd, buf, nbytes);
+ if (tmp &lt; nbytes)
+ fprintf(stderr, "error while reading \"%s\"", filename);
+ }
+
+ close(fd);
+ lo_close(conn, lobj_fd);
+
+ return lobjId;
+}
+
+static void
+pickout(PGconn *conn, Oid lobjId, int start, int len)
+{
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nread;
+
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd &lt; 0)
+ fprintf(stderr, "cannot open large object %u", lobjId);
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ nread = 0;
+ while (len - nread &gt; 0)
+ {
+ nbytes = lo_read(conn, lobj_fd, buf, len - nread);
+ buf[nbytes] = '\0';
+ fprintf(stderr, "&gt;&gt;&gt; %s", buf);
+ nread += nbytes;
+ if (nbytes &lt;= 0)
+ break; /* no more data? */
+ }
+ free(buf);
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
+}
+
+static void
+overwrite(PGconn *conn, Oid lobjId, int start, int len)
+{
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nwritten;
+ int i;
+
+ lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+ if (lobj_fd &lt; 0)
+ fprintf(stderr, "cannot open large object %u", lobjId);
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ for (i = 0; i &lt; len; i++)
+ buf[i] = 'X';
+ buf[i] = '\0';
+
+ nwritten = 0;
+ while (len - nwritten &gt; 0)
+ {
+ nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
+ nwritten += nbytes;
+ if (nbytes &lt;= 0)
+ {
+ fprintf(stderr, "\nWRITE FAILED!\n");
+ break;
+ }
+ }
+ free(buf);
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
+}
+
+
+/*
+ * exportFile -
+ * export large object "lobjOid" to file "out_filename"
+ *
+ */
+static void
+exportFile(PGconn *conn, Oid lobjId, char *filename)
+{
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * open the large object
+ */
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd &lt; 0)
+ fprintf(stderr, "cannot open large object %u", lobjId);
+
+ /*
+ * open the file to be written to
+ */
+ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+ if (fd &lt; 0)
+ { /* error */
+ fprintf(stderr, "cannot open unix file\"%s\"",
+ filename);
+ }
+
+ /*
+ * read in from the inversion file and write to the Unix file
+ */
+ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0)
+ {
+ tmp = write(fd, buf, nbytes);
+ if (tmp &lt; nbytes)
+ {
+ fprintf(stderr, "error while writing \"%s\"",
+ filename);
+ }
+ }
+
+ lo_close(conn, lobj_fd);
+ close(fd);
+}
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *in_filename,
+ *out_filename;
+ char *database;
+ Oid lobjOid;
+ PGconn *conn;
+ PGresult *res;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
+ argv[0]);
+ exit(1);
+ }
+
+ database = argv[1];
+ in_filename = argv[2];
+ out_filename = argv[3];
+
+ /*
+ * set up the connection
+ */
+ conn = PQsetdb(NULL, NULL, NULL, NULL, database);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn,
+ "SELECT pg_catalog.set_config('search_path', '', false)");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ res = PQexec(conn, "begin");
+ PQclear(res);
+ printf("importing file \"%s\" ...\n", in_filename);
+/* lobjOid = importFile(conn, in_filename); */
+ lobjOid = lo_import(conn, in_filename);
+ if (lobjOid == 0)
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ else
+ {
+ printf("\tas large object %u.\n", lobjOid);
+
+ printf("picking out bytes 1000-2000 of the large object\n");
+ pickout(conn, lobjOid, 1000, 1000);
+
+ printf("overwriting bytes 1000-2000 of the large object with X's\n");
+ overwrite(conn, lobjOid, 1000, 1000);
+
+ printf("exporting large object to file \"%s\" ...\n", out_filename);
+/* exportFile(conn, lobjOid, out_filename); */
+ if (lo_export(conn, lobjOid, out_filename) &lt; 0)
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ }
+
+ res = PQexec(conn, "end");
+ PQclear(res);
+ PQfinish(conn);
+ return 0;
+}
+
+</pre></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lo-funcs.html" title="35.4. Server-Side Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Next</a></td></tr><tr><td width="40%" align="left" valign="top">35.4. Server-Side Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 36. <span class="application">ECPG</span> — Embedded <acronym class="acronym">SQL</acronym> in C</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/lo-funcs.html b/doc/src/sgml/html/lo-funcs.html
new file mode 100644
index 0000000..476489b
--- /dev/null
+++ b/doc/src/sgml/html/lo-funcs.html
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>35.4. Server-Side Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="lo-interfaces.html" title="35.3. Client Interfaces" /><link rel="next" href="lo-examplesect.html" title="35.5. Example Program" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">35.4. Server-Side Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="lo-interfaces.html" title="35.3. Client Interfaces">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><th width="60%" align="center">Chapter 35. Large Objects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="lo-examplesect.html" title="35.5. Example Program">Next</a></td></tr></table><hr /></div><div class="sect1" id="LO-FUNCS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">35.4. Server-Side Functions</h2></div></div></div><p>
+ Server-side functions tailored for manipulating large objects from SQL are
+ listed in <a class="xref" href="lo-funcs.html#LO-FUNCS-TABLE" title="Table 35.1. SQL-Oriented Large Object Functions">Table 35.1</a>.
+ </p><div class="table" id="LO-FUNCS-TABLE"><p class="title"><strong>Table 35.1. SQL-Oriented Large Object Functions</strong></p><div class="table-contents"><table class="table" summary="SQL-Oriented Large Object Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.7.4.9.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">lo_from_bytea</code> ( <em class="parameter"><code>loid</code></em> <code class="type">oid</code>, <em class="parameter"><code>data</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Creates a large object and stores <em class="parameter"><code>data</code></em> in it.
+ If <em class="parameter"><code>loid</code></em> is zero then the system will choose a
+ free OID, otherwise that OID is used (with an error if some large
+ object already has that OID). On success, the large object's OID is
+ returned.
+ </p>
+ <p>
+ <code class="literal">lo_from_bytea(0, '\xffffff00')</code>
+ → <code class="returnvalue">24528</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.7.4.9.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">lo_put</code> ( <em class="parameter"><code>loid</code></em> <code class="type">oid</code>, <em class="parameter"><code>offset</code></em> <code class="type">bigint</code>, <em class="parameter"><code>data</code></em> <code class="type">bytea</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Writes <em class="parameter"><code>data</code></em> starting at the given offset within
+ the large object; the large object is enlarged if necessary.
+ </p>
+ <p>
+ <code class="literal">lo_put(24528, 1, '\xaa')</code>
+ → <code class="returnvalue"></code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.7.4.9.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">lo_get</code> ( <em class="parameter"><code>loid</code></em> <code class="type">oid</code> [<span class="optional">, <em class="parameter"><code>offset</code></em> <code class="type">bigint</code>, <em class="parameter"><code>length</code></em> <code class="type">integer</code> </span>] )
+ → <code class="returnvalue">bytea</code>
+ </p>
+ <p>
+ Extracts the large object's contents, or a substring thereof.
+ </p>
+ <p>
+ <code class="literal">lo_get(24528, 0, 3)</code>
+ → <code class="returnvalue">\xffaaff</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ There are additional server-side functions corresponding to each of the
+ client-side functions described earlier; indeed, for the most part the
+ client-side functions are simply interfaces to the equivalent server-side
+ functions. The ones just as convenient to call via SQL commands are
+ <code class="function">lo_creat</code><a id="id-1.7.4.9.4.2" class="indexterm"></a>,
+ <code class="function">lo_create</code>,
+ <code class="function">lo_unlink</code><a id="id-1.7.4.9.4.5" class="indexterm"></a>,
+ <code class="function">lo_import</code><a id="id-1.7.4.9.4.7" class="indexterm"></a>, and
+ <code class="function">lo_export</code><a id="id-1.7.4.9.4.9" class="indexterm"></a>.
+ Here are examples of their use:
+
+</p><pre class="programlisting">
+CREATE TABLE image (
+ name text,
+ raster oid
+);
+
+SELECT lo_creat(-1); -- returns OID of new, empty large object
+
+SELECT lo_create(43213); -- attempts to create large object with OID 43213
+
+SELECT lo_unlink(173454); -- deletes large object with OID 173454
+
+INSERT INTO image (name, raster)
+ VALUES ('beautiful image', lo_import('/etc/motd'));
+
+INSERT INTO image (name, raster) -- same as above, but specify OID to use
+ VALUES ('beautiful image', lo_import('/etc/motd', 68583));
+
+SELECT lo_export(image.raster, '/tmp/motd') FROM image
+ WHERE name = 'beautiful image';
+</pre><p>
+ </p><p>
+ The server-side <code class="function">lo_import</code> and
+ <code class="function">lo_export</code> functions behave considerably differently
+ from their client-side analogs. These two functions read and write files
+ in the server's file system, using the permissions of the database's
+ owning user. Therefore, by default their use is restricted to superusers.
+ In contrast, the client-side import and export functions read and write
+ files in the client's file system, using the permissions of the client
+ program. The client-side functions do not require any database
+ privileges, except the privilege to read or write the large object in
+ question.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is possible to <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a> use of the
+ server-side <code class="function">lo_import</code>
+ and <code class="function">lo_export</code> functions to non-superusers, but
+ careful consideration of the security implications is required. A
+ malicious user of such privileges could easily parlay them into becoming
+ superuser (for example by rewriting server configuration files), or could
+ attack the rest of the server's file system without bothering to obtain
+ database superuser privileges as such. <span class="emphasis"><em>Access to roles having
+ such privilege must therefore be guarded just as carefully as access to
+ superuser roles.</em></span> Nonetheless, if use of
+ server-side <code class="function">lo_import</code>
+ or <code class="function">lo_export</code> is needed for some routine task, it's
+ safer to use a role with such privileges than one with full superuser
+ privileges, as that helps to reduce the risk of damage from accidental
+ errors.
+ </p></div><p>
+ The functionality of <code class="function">lo_read</code> and
+ <code class="function">lo_write</code> is also available via server-side calls,
+ but the names of the server-side functions differ from the client side
+ interfaces in that they do not contain underscores. You must call
+ these functions as <code class="function">loread</code> and <code class="function">lowrite</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lo-interfaces.html" title="35.3. Client Interfaces">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="lo-examplesect.html" title="35.5. Example Program">Next</a></td></tr><tr><td width="40%" align="left" valign="top">35.3. Client Interfaces </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 35.5. Example Program</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/lo-implementation.html b/doc/src/sgml/html/lo-implementation.html
new file mode 100644
index 0000000..c7766ee
--- /dev/null
+++ b/doc/src/sgml/html/lo-implementation.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>35.2. Implementation Features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="lo-intro.html" title="35.1. Introduction" /><link rel="next" href="lo-interfaces.html" title="35.3. Client Interfaces" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">35.2. Implementation Features</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="lo-intro.html" title="35.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><th width="60%" align="center">Chapter 35. Large Objects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="lo-interfaces.html" title="35.3. Client Interfaces">Next</a></td></tr></table><hr /></div><div class="sect1" id="LO-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">35.2. Implementation Features</h2></div></div></div><p>
+ The large object implementation breaks large
+ objects up into <span class="quote">“<span class="quote">chunks</span>”</span> and stores the chunks in
+ rows in the database. A B-tree index guarantees fast
+ searches for the correct chunk number when doing random
+ access reads and writes.
+ </p><p>
+ The chunks stored for a large object do not have to be contiguous.
+ For example, if an application opens a new large object, seeks to offset
+ 1000000, and writes a few bytes there, this does not result in allocation
+ of 1000000 bytes worth of storage; only of chunks covering the range of
+ data bytes actually written. A read operation will, however, read out
+ zeroes for any unallocated locations preceding the last existing chunk.
+ This corresponds to the common behavior of <span class="quote">“<span class="quote">sparsely allocated</span>”</span>
+ files in <acronym class="acronym">Unix</acronym> file systems.
+ </p><p>
+ As of <span class="productname">PostgreSQL</span> 9.0, large objects have an owner
+ and a set of access permissions, which can be managed using
+ <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a> and
+ <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a>.
+ <code class="literal">SELECT</code> privileges are required to read a large
+ object, and
+ <code class="literal">UPDATE</code> privileges are required to write or
+ truncate it.
+ Only the large object's owner (or a database superuser) can delete,
+ comment on, or change the owner of a large object.
+ To adjust this behavior for compatibility with prior releases, see the
+ <a class="xref" href="runtime-config-compatible.html#GUC-LO-COMPAT-PRIVILEGES">lo_compat_privileges</a> run-time parameter.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lo-intro.html" title="35.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="lo-interfaces.html" title="35.3. Client Interfaces">Next</a></td></tr><tr><td width="40%" align="left" valign="top">35.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 35.3. Client Interfaces</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/lo-interfaces.html b/doc/src/sgml/html/lo-interfaces.html
new file mode 100644
index 0000000..47e5c2a
--- /dev/null
+++ b/doc/src/sgml/html/lo-interfaces.html
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>35.3. Client Interfaces</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="lo-implementation.html" title="35.2. Implementation Features" /><link rel="next" href="lo-funcs.html" title="35.4. Server-Side Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">35.3. Client Interfaces</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="lo-implementation.html" title="35.2. Implementation Features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><th width="60%" align="center">Chapter 35. Large Objects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="lo-funcs.html" title="35.4. Server-Side Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LO-INTERFACES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">35.3. Client Interfaces</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="lo-interfaces.html#LO-CREATE">35.3.1. Creating a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-IMPORT">35.3.2. Importing a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-EXPORT">35.3.3. Exporting a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-OPEN">35.3.4. Opening an Existing Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-WRITE">35.3.5. Writing Data to a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-READ">35.3.6. Reading Data from a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-SEEK">35.3.7. Seeking in a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-TELL">35.3.8. Obtaining the Seek Position of a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-TRUNCATE">35.3.9. Truncating a Large Object</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-CLOSE">35.3.10. Closing a Large Object Descriptor</a></span></dt><dt><span class="sect2"><a href="lo-interfaces.html#LO-UNLINK">35.3.11. Removing a Large Object</a></span></dt></dl></div><p>
+ This section describes the facilities that
+ <span class="productname">PostgreSQL</span>'s <span class="application">libpq</span>
+ client interface library provides for accessing large objects.
+ The <span class="productname">PostgreSQL</span> large object interface is
+ modeled after the <acronym class="acronym">Unix</acronym> file-system interface, with
+ analogues of <code class="function">open</code>, <code class="function">read</code>,
+ <code class="function">write</code>,
+ <code class="function">lseek</code>, etc.
+ </p><p>
+ All large object manipulation using these functions
+ <span class="emphasis"><em>must</em></span> take place within an SQL transaction block,
+ since large object file descriptors are only valid for the duration of
+ a transaction.
+ </p><p>
+ If an error occurs while executing any one of these functions, the
+ function will return an otherwise-impossible value, typically 0 or -1.
+ A message describing the error is stored in the connection object and
+ can be retrieved with <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a>.
+ </p><p>
+ Client applications that use these functions should include the header file
+ <code class="filename">libpq/libpq-fs.h</code> and link with the
+ <span class="application">libpq</span> library.
+ </p><p>
+ Client applications cannot use these functions while a libpq connection is in pipeline mode.
+ </p><div class="sect2" id="LO-CREATE"><div class="titlepage"><div><div><h3 class="title">35.3.1. Creating a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.7.2.1" class="indexterm"></a>
+ The function
+</p><pre class="synopsis">
+Oid lo_create(PGconn *conn, Oid lobjId);
+</pre><p>
+ creates a new large object. The OID to be assigned can be
+ specified by <em class="replaceable"><code>lobjId</code></em>;
+ if so, failure occurs if that OID is already in use for some large
+ object. If <em class="replaceable"><code>lobjId</code></em>
+ is <code class="symbol">InvalidOid</code> (zero) then <code class="function">lo_create</code>
+ assigns an unused OID.
+ The return value is the OID that was assigned to the new large object,
+ or <code class="symbol">InvalidOid</code> (zero) on failure.
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+inv_oid = lo_create(conn, desired_oid);
+</pre><p>
+ </p><p>
+ <a id="id-1.7.4.8.7.4.1" class="indexterm"></a>
+ The older function
+</p><pre class="synopsis">
+Oid lo_creat(PGconn *conn, int mode);
+</pre><p>
+ also creates a new large object, always assigning an unused OID.
+ The return value is the OID that was assigned to the new large object,
+ or <code class="symbol">InvalidOid</code> (zero) on failure.
+ </p><p>
+ In <span class="productname">PostgreSQL</span> releases 8.1 and later,
+ the <em class="replaceable"><code>mode</code></em> is ignored,
+ so that <code class="function">lo_creat</code> is exactly equivalent to
+ <code class="function">lo_create</code> with a zero second argument.
+ However, there is little reason to use <code class="function">lo_creat</code>
+ unless you need to work with servers older than 8.1.
+ To work with such an old server, you must
+ use <code class="function">lo_creat</code> not <code class="function">lo_create</code>,
+ and you must set <em class="replaceable"><code>mode</code></em> to
+ one of <code class="symbol">INV_READ</code>, <code class="symbol">INV_WRITE</code>,
+ or <code class="symbol">INV_READ</code> <code class="literal">|</code> <code class="symbol">INV_WRITE</code>.
+ (These symbolic constants are defined
+ in the header file <code class="filename">libpq/libpq-fs.h</code>.)
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
+</pre><p>
+ </p></div><div class="sect2" id="LO-IMPORT"><div class="titlepage"><div><div><h3 class="title">35.3.2. Importing a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.8.2.1" class="indexterm"></a>
+ To import an operating system file as a large object, call
+</p><pre class="synopsis">
+Oid lo_import(PGconn *conn, const char *filename);
+</pre><p>
+ <em class="replaceable"><code>filename</code></em>
+ specifies the operating system name of
+ the file to be imported as a large object.
+ The return value is the OID that was assigned to the new large object,
+ or <code class="symbol">InvalidOid</code> (zero) on failure.
+ Note that the file is read by the client interface library, not by
+ the server; so it must exist in the client file system and be readable
+ by the client application.
+ </p><p>
+ <a id="id-1.7.4.8.8.3.1" class="indexterm"></a>
+ The function
+</p><pre class="synopsis">
+Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
+</pre><p>
+ also imports a new large object. The OID to be assigned can be
+ specified by <em class="replaceable"><code>lobjId</code></em>;
+ if so, failure occurs if that OID is already in use for some large
+ object. If <em class="replaceable"><code>lobjId</code></em>
+ is <code class="symbol">InvalidOid</code> (zero) then <code class="function">lo_import_with_oid</code> assigns an unused
+ OID (this is the same behavior as <code class="function">lo_import</code>).
+ The return value is the OID that was assigned to the new large object,
+ or <code class="symbol">InvalidOid</code> (zero) on failure.
+ </p><p>
+ <code class="function">lo_import_with_oid</code> is new as of <span class="productname">PostgreSQL</span>
+ 8.4 and uses <code class="function">lo_create</code> internally which is new in 8.1; if this function is run against 8.0 or before, it will
+ fail and return <code class="symbol">InvalidOid</code>.
+ </p></div><div class="sect2" id="LO-EXPORT"><div class="titlepage"><div><div><h3 class="title">35.3.3. Exporting a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.9.2.1" class="indexterm"></a>
+ To export a large object
+ into an operating system file, call
+</p><pre class="synopsis">
+int lo_export(PGconn *conn, Oid lobjId, const char *filename);
+</pre><p>
+ The <em class="parameter"><code>lobjId</code></em> argument specifies the OID of the large
+ object to export and the <em class="parameter"><code>filename</code></em> argument
+ specifies the operating system name of the file. Note that the file is
+ written by the client interface library, not by the server. Returns 1
+ on success, -1 on failure.
+ </p></div><div class="sect2" id="LO-OPEN"><div class="titlepage"><div><div><h3 class="title">35.3.4. Opening an Existing Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.10.2.1" class="indexterm"></a>
+ To open an existing large object for reading or writing, call
+</p><pre class="synopsis">
+int lo_open(PGconn *conn, Oid lobjId, int mode);
+</pre><p>
+ The <em class="parameter"><code>lobjId</code></em> argument specifies the OID of the large
+ object to open. The <em class="parameter"><code>mode</code></em> bits control whether the
+ object is opened for reading (<code class="symbol">INV_READ</code>), writing
+ (<code class="symbol">INV_WRITE</code>), or both.
+ (These symbolic constants are defined
+ in the header file <code class="filename">libpq/libpq-fs.h</code>.)
+ <code class="function">lo_open</code> returns a (non-negative) large object
+ descriptor for later use in <code class="function">lo_read</code>,
+ <code class="function">lo_write</code>, <code class="function">lo_lseek</code>,
+ <code class="function">lo_lseek64</code>, <code class="function">lo_tell</code>,
+ <code class="function">lo_tell64</code>, <code class="function">lo_truncate</code>,
+ <code class="function">lo_truncate64</code>, and <code class="function">lo_close</code>.
+ The descriptor is only valid for
+ the duration of the current transaction.
+ On failure, -1 is returned.
+ </p><p>
+ The server currently does not distinguish between modes
+ <code class="symbol">INV_WRITE</code> and <code class="symbol">INV_READ</code> <code class="literal">|</code>
+ <code class="symbol">INV_WRITE</code>: you are allowed to read from the descriptor
+ in either case. However there is a significant difference between
+ these modes and <code class="symbol">INV_READ</code> alone: with <code class="symbol">INV_READ</code>
+ you cannot write on the descriptor, and the data read from it will
+ reflect the contents of the large object at the time of the transaction
+ snapshot that was active when <code class="function">lo_open</code> was executed,
+ regardless of later writes by this or other transactions. Reading
+ from a descriptor opened with <code class="symbol">INV_WRITE</code> returns
+ data that reflects all writes of other committed transactions as well
+ as writes of the current transaction. This is similar to the behavior
+ of <code class="literal">REPEATABLE READ</code> versus <code class="literal">READ COMMITTED</code> transaction
+ modes for ordinary SQL <code class="command">SELECT</code> commands.
+ </p><p>
+ <code class="function">lo_open</code> will fail if <code class="literal">SELECT</code>
+ privilege is not available for the large object, or
+ if <code class="symbol">INV_WRITE</code> is specified and <code class="literal">UPDATE</code>
+ privilege is not available.
+ (Prior to <span class="productname">PostgreSQL</span> 11, these privilege
+ checks were instead performed at the first actual read or write call
+ using the descriptor.)
+ These privilege checks can be disabled with the
+ <a class="xref" href="runtime-config-compatible.html#GUC-LO-COMPAT-PRIVILEGES">lo_compat_privileges</a> run-time parameter.
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);
+</pre><p>
+ </p></div><div class="sect2" id="LO-WRITE"><div class="titlepage"><div><div><h3 class="title">35.3.5. Writing Data to a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.11.2.1" class="indexterm"></a>
+ The function
+</p><pre class="synopsis">
+int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
+</pre><p>
+ writes <em class="parameter"><code>len</code></em> bytes from <em class="parameter"><code>buf</code></em>
+ (which must be of size <em class="parameter"><code>len</code></em>) to large object
+ descriptor <em class="parameter"><code>fd</code></em>. The <em class="parameter"><code>fd</code></em> argument must
+ have been returned by a previous <code class="function">lo_open</code>. The
+ number of bytes actually written is returned (in the current
+ implementation, this will always equal <em class="parameter"><code>len</code></em> unless
+ there is an error). In the event of an error, the return value is -1.
+</p><p>
+ Although the <em class="parameter"><code>len</code></em> parameter is declared as
+ <code class="type">size_t</code>, this function will reject length values larger than
+ <code class="literal">INT_MAX</code>. In practice, it's best to transfer data in chunks
+ of at most a few megabytes anyway.
+</p></div><div class="sect2" id="LO-READ"><div class="titlepage"><div><div><h3 class="title">35.3.6. Reading Data from a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.12.2.1" class="indexterm"></a>
+ The function
+</p><pre class="synopsis">
+int lo_read(PGconn *conn, int fd, char *buf, size_t len);
+</pre><p>
+ reads up to <em class="parameter"><code>len</code></em> bytes from large object descriptor
+ <em class="parameter"><code>fd</code></em> into <em class="parameter"><code>buf</code></em> (which must be
+ of size <em class="parameter"><code>len</code></em>). The <em class="parameter"><code>fd</code></em>
+ argument must have been returned by a previous
+ <code class="function">lo_open</code>. The number of bytes actually read is
+ returned; this will be less than <em class="parameter"><code>len</code></em> if the end of
+ the large object is reached first. In the event of an error, the return
+ value is -1.
+</p><p>
+ Although the <em class="parameter"><code>len</code></em> parameter is declared as
+ <code class="type">size_t</code>, this function will reject length values larger than
+ <code class="literal">INT_MAX</code>. In practice, it's best to transfer data in chunks
+ of at most a few megabytes anyway.
+</p></div><div class="sect2" id="LO-SEEK"><div class="titlepage"><div><div><h3 class="title">35.3.7. Seeking in a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.13.2.1" class="indexterm"></a>
+ To change the current read or write location associated with a
+ large object descriptor, call
+</p><pre class="synopsis">
+int lo_lseek(PGconn *conn, int fd, int offset, int whence);
+</pre><p>
+ This function moves the
+ current location pointer for the large object descriptor identified by
+ <em class="parameter"><code>fd</code></em> to the new location specified by
+ <em class="parameter"><code>offset</code></em>. The valid values for <em class="parameter"><code>whence</code></em>
+ are <code class="symbol">SEEK_SET</code> (seek from object start),
+ <code class="symbol">SEEK_CUR</code> (seek from current position), and
+ <code class="symbol">SEEK_END</code> (seek from object end). The return value is
+ the new location pointer, or -1 on error.
+</p><p>
+ <a id="id-1.7.4.8.13.3.1" class="indexterm"></a>
+ When dealing with large objects that might exceed 2GB in size,
+ instead use
+</p><pre class="synopsis">
+pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
+</pre><p>
+ This function has the same behavior
+ as <code class="function">lo_lseek</code>, but it can accept an
+ <em class="parameter"><code>offset</code></em> larger than 2GB and/or deliver a result larger
+ than 2GB.
+ Note that <code class="function">lo_lseek</code> will fail if the new location
+ pointer would be greater than 2GB.
+</p><p>
+ <code class="function">lo_lseek64</code> is new as of <span class="productname">PostgreSQL</span>
+ 9.3. If this function is run against an older server version, it will
+ fail and return -1.
+</p></div><div class="sect2" id="LO-TELL"><div class="titlepage"><div><div><h3 class="title">35.3.8. Obtaining the Seek Position of a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.14.2.1" class="indexterm"></a>
+ To obtain the current read or write location of a large object descriptor,
+ call
+</p><pre class="synopsis">
+int lo_tell(PGconn *conn, int fd);
+</pre><p>
+ If there is an error, the return value is -1.
+</p><p>
+ <a id="id-1.7.4.8.14.3.1" class="indexterm"></a>
+ When dealing with large objects that might exceed 2GB in size,
+ instead use
+</p><pre class="synopsis">
+pg_int64 lo_tell64(PGconn *conn, int fd);
+</pre><p>
+ This function has the same behavior
+ as <code class="function">lo_tell</code>, but it can deliver a result larger
+ than 2GB.
+ Note that <code class="function">lo_tell</code> will fail if the current
+ read/write location is greater than 2GB.
+</p><p>
+ <code class="function">lo_tell64</code> is new as of <span class="productname">PostgreSQL</span>
+ 9.3. If this function is run against an older server version, it will
+ fail and return -1.
+</p></div><div class="sect2" id="LO-TRUNCATE"><div class="titlepage"><div><div><h3 class="title">35.3.9. Truncating a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.15.2.1" class="indexterm"></a>
+ To truncate a large object to a given length, call
+</p><pre class="synopsis">
+int lo_truncate(PGconn *conn, int fd, size_t len);
+</pre><p>
+ This function truncates the large object
+ descriptor <em class="parameter"><code>fd</code></em> to length <em class="parameter"><code>len</code></em>. The
+ <em class="parameter"><code>fd</code></em> argument must have been returned by a
+ previous <code class="function">lo_open</code>. If <em class="parameter"><code>len</code></em> is
+ greater than the large object's current length, the large object
+ is extended to the specified length with null bytes ('\0').
+ On success, <code class="function">lo_truncate</code> returns
+ zero. On error, the return value is -1.
+</p><p>
+ The read/write location associated with the descriptor
+ <em class="parameter"><code>fd</code></em> is not changed.
+</p><p>
+ Although the <em class="parameter"><code>len</code></em> parameter is declared as
+ <code class="type">size_t</code>, <code class="function">lo_truncate</code> will reject length
+ values larger than <code class="literal">INT_MAX</code>.
+</p><p>
+ <a id="id-1.7.4.8.15.5.1" class="indexterm"></a>
+ When dealing with large objects that might exceed 2GB in size,
+ instead use
+</p><pre class="synopsis">
+int lo_truncate64(PGconn *conn, int fd, pg_int64 len);
+</pre><p>
+ This function has the same
+ behavior as <code class="function">lo_truncate</code>, but it can accept a
+ <em class="parameter"><code>len</code></em> value exceeding 2GB.
+</p><p>
+ <code class="function">lo_truncate</code> is new as of <span class="productname">PostgreSQL</span>
+ 8.3; if this function is run against an older server version, it will
+ fail and return -1.
+</p><p>
+ <code class="function">lo_truncate64</code> is new as of <span class="productname">PostgreSQL</span>
+ 9.3; if this function is run against an older server version, it will
+ fail and return -1.
+</p></div><div class="sect2" id="LO-CLOSE"><div class="titlepage"><div><div><h3 class="title">35.3.10. Closing a Large Object Descriptor</h3></div></div></div><p>
+ <a id="id-1.7.4.8.16.2.1" class="indexterm"></a>
+ A large object descriptor can be closed by calling
+</p><pre class="synopsis">
+int lo_close(PGconn *conn, int fd);
+</pre><p>
+ where <em class="parameter"><code>fd</code></em> is a
+ large object descriptor returned by <code class="function">lo_open</code>.
+ On success, <code class="function">lo_close</code> returns zero. On
+ error, the return value is -1.
+</p><p>
+ Any large object descriptors that remain open at the end of a
+ transaction will be closed automatically.
+</p></div><div class="sect2" id="LO-UNLINK"><div class="titlepage"><div><div><h3 class="title">35.3.11. Removing a Large Object</h3></div></div></div><p>
+ <a id="id-1.7.4.8.17.2.1" class="indexterm"></a>
+ To remove a large object from the database, call
+</p><pre class="synopsis">
+int lo_unlink(PGconn *conn, Oid lobjId);
+</pre><p>
+ The <em class="parameter"><code>lobjId</code></em> argument specifies the OID of the
+ large object to remove. Returns 1 if successful, -1 on failure.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lo-implementation.html" title="35.2. Implementation Features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="lo-funcs.html" title="35.4. Server-Side Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">35.2. Implementation Features </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 35.4. Server-Side Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/lo-intro.html b/doc/src/sgml/html/lo-intro.html
new file mode 100644
index 0000000..a77e633
--- /dev/null
+++ b/doc/src/sgml/html/lo-intro.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>35.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="largeobjects.html" title="Chapter 35. Large Objects" /><link rel="next" href="lo-implementation.html" title="35.2. Implementation Features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">35.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="largeobjects.html" title="Chapter 35. Large Objects">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><th width="60%" align="center">Chapter 35. Large Objects</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="lo-implementation.html" title="35.2. Implementation Features">Next</a></td></tr></table><hr /></div><div class="sect1" id="LO-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">35.1. Introduction</h2></div></div></div><a id="id-1.7.4.6.2" class="indexterm"></a><p>
+ All large objects are stored in a single system table named <a class="link" href="catalog-pg-largeobject.html" title="53.30. pg_largeobject"><code class="structname">pg_largeobject</code></a>.
+ Each large object also has an entry in the system table <a class="link" href="catalog-pg-largeobject-metadata.html" title="53.31. pg_largeobject_metadata"><code class="structname">pg_largeobject_metadata</code></a>.
+ Large objects can be created, modified, and deleted using a read/write API
+ that is similar to standard operations on files.
+ </p><p>
+ <span class="productname">PostgreSQL</span> also supports a storage system called
+ <a class="link" href="storage-toast.html" title="73.2. TOAST"><span class="quote">“<span class="quote"><acronym class="acronym">TOAST</acronym></span>”</span></a>,
+ which automatically stores values
+ larger than a single database page into a secondary storage area per table.
+ This makes the large object facility partially obsolete. One
+ remaining advantage of the large object facility is that it allows values
+ up to 4 TB in size, whereas <acronym class="acronym">TOAST</acronym>ed fields can be at
+ most 1 GB. Also, reading and updating portions of a large object can be
+ done efficiently, while most operations on a <acronym class="acronym">TOAST</acronym>ed
+ field will read or write the whole value as a unit.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="largeobjects.html" title="Chapter 35. Large Objects">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="largeobjects.html" title="Chapter 35. Large Objects">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="lo-implementation.html" title="35.2. Implementation Features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 35. Large Objects </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 35.2. Implementation Features</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/lo.html b/doc/src/sgml/html/lo.html
new file mode 100644
index 0000000..3a3fd2a
--- /dev/null
+++ b/doc/src/sgml/html/lo.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.22. lo</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="isn.html" title="F.21. isn" /><link rel="next" href="ltree.html" title="F.23. ltree" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.22. lo</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="isn.html" title="F.21. isn">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ltree.html" title="F.23. ltree">Next</a></td></tr></table><hr /></div><div class="sect1" id="LO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.22. lo</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.5">F.22.1. Rationale</a></span></dt><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.6">F.22.2. How to Use It</a></span></dt><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.7">F.22.3. Limitations</a></span></dt><dt><span class="sect2"><a href="lo.html#id-1.11.7.31.8">F.22.4. Author</a></span></dt></dl></div><a id="id-1.11.7.31.2" class="indexterm"></a><p>
+ The <code class="filename">lo</code> module provides support for managing Large Objects
+ (also called LOs or BLOBs). This includes a data type <code class="type">lo</code>
+ and a trigger <code class="function">lo_manage</code>.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.31.5"><div class="titlepage"><div><div><h3 class="title">F.22.1. Rationale</h3></div></div></div><p>
+ One of the problems with the JDBC driver (and this affects the ODBC driver
+ also), is that the specification assumes that references to BLOBs (Binary
+ Large OBjects) are stored within a table, and if that entry is changed, the
+ associated BLOB is deleted from the database.
+ </p><p>
+ As <span class="productname">PostgreSQL</span> stands, this doesn't occur. Large objects
+ are treated as objects in their own right; a table entry can reference a
+ large object by OID, but there can be multiple table entries referencing
+ the same large object OID, so the system doesn't delete the large object
+ just because you change or remove one such entry.
+ </p><p>
+ Now this is fine for <span class="productname">PostgreSQL</span>-specific applications, but
+ standard code using JDBC or ODBC won't delete the objects, resulting in
+ orphan objects — objects that are not referenced by anything, and
+ simply occupy disk space.
+ </p><p>
+ The <code class="filename">lo</code> module allows fixing this by attaching a trigger
+ to tables that contain LO reference columns. The trigger essentially just
+ does a <code class="function">lo_unlink</code> whenever you delete or modify a value
+ referencing a large object. When you use this trigger, you are assuming
+ that there is only one database reference to any large object that is
+ referenced in a trigger-controlled column!
+ </p><p>
+ The module also provides a data type <code class="type">lo</code>, which is really just
+ a <a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN" title="Domain">domain</a></em></a> over
+ the <code class="type">oid</code> type. This is useful for differentiating
+ database columns that hold large object references from those that are
+ OIDs of other things. You don't have to use the <code class="type">lo</code> type to
+ use the trigger, but it may be convenient to use it to keep track of which
+ columns in your database represent large objects that you are managing with
+ the trigger. It is also rumored that the ODBC driver gets confused if you
+ don't use <code class="type">lo</code> for BLOB columns.
+ </p></div><div class="sect2" id="id-1.11.7.31.6"><div class="titlepage"><div><div><h3 class="title">F.22.2. How to Use It</h3></div></div></div><p>
+ Here's a simple example of usage:
+ </p><pre class="programlisting">
+CREATE TABLE image (title text, raster lo);
+
+CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
+ FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);
+</pre><p>
+ For each column that will contain unique references to large objects,
+ create a <code class="literal">BEFORE UPDATE OR DELETE</code> trigger, and give the column
+ name as the sole trigger argument. You can also restrict the trigger
+ to only execute on updates to the column by using <code class="literal">BEFORE UPDATE
+ OF</code> <em class="replaceable"><code>column_name</code></em>.
+ If you need multiple <code class="type">lo</code>
+ columns in the same table, create a separate trigger for each one,
+ remembering to give a different name to each trigger on the same table.
+ </p></div><div class="sect2" id="id-1.11.7.31.7"><div class="titlepage"><div><div><h3 class="title">F.22.3. Limitations</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Dropping a table will still orphan any objects it contains, as the trigger
+ is not executed. You can avoid this by preceding the <code class="command">DROP
+ TABLE</code> with <code class="command">DELETE FROM <em class="replaceable"><code>table</code></em></code>.
+ </p><p>
+ <code class="command">TRUNCATE</code> has the same hazard.
+ </p><p>
+ If you already have, or suspect you have, orphaned large objects, see the
+ <a class="xref" href="vacuumlo.html" title="vacuumlo"><span class="refentrytitle"><span class="application">vacuumlo</span></span></a> module to help
+ you clean them up. It's a good idea to run <span class="application">vacuumlo</span>
+ occasionally as a back-stop to the <code class="function">lo_manage</code> trigger.
+ </p></li><li class="listitem"><p>
+ Some frontends may create their own tables, and will not create the
+ associated trigger(s). Also, users may not remember (or know) to create
+ the triggers.
+ </p></li></ul></div></div><div class="sect2" id="id-1.11.7.31.8"><div class="titlepage"><div><div><h3 class="title">F.22.4. Author</h3></div></div></div><p>
+ Peter Mount <code class="email">&lt;<a class="email" href="mailto:peter@retep.org.uk">peter@retep.org.uk</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="isn.html" title="F.21. isn">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ltree.html" title="F.23. ltree">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.21. isn </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.23. ltree</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/locale.html b/doc/src/sgml/html/locale.html
new file mode 100644
index 0000000..ee467f6
--- /dev/null
+++ b/doc/src/sgml/html/locale.html
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>24.1. Locale Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="charset.html" title="Chapter 24. Localization" /><link rel="next" href="collation.html" title="24.2. Collation Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">24.1. Locale Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="charset.html" title="Chapter 24. Localization">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="charset.html" title="Chapter 24. Localization">Up</a></td><th width="60%" align="center">Chapter 24. Localization</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="collation.html" title="24.2. Collation Support">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOCALE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">24.1. Locale Support</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.4">24.1.1. Overview</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.5">24.1.2. Behavior</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.6">24.1.3. Selecting Locales</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.7">24.1.4. Locale Providers</a></span></dt><dt><span class="sect2"><a href="locale.html#id-1.6.11.3.8">24.1.5. Problems</a></span></dt></dl></div><a id="id-1.6.11.3.2" class="indexterm"></a><p>
+ <em class="firstterm">Locale</em> support refers to an application respecting
+ cultural preferences regarding alphabets, sorting, number
+ formatting, etc. <span class="productname">PostgreSQL</span> uses the standard ISO
+ C and <acronym class="acronym">POSIX</acronym> locale facilities provided by the server operating
+ system. For additional information refer to the documentation of your
+ system.
+ </p><div class="sect2" id="id-1.6.11.3.4"><div class="titlepage"><div><div><h3 class="title">24.1.1. Overview</h3></div></div></div><p>
+ Locale support is automatically initialized when a database
+ cluster is created using <code class="command">initdb</code>.
+ <code class="command">initdb</code> will initialize the database cluster
+ with the locale setting of its execution environment by default,
+ so if your system is already set to use the locale that you want
+ in your database cluster then there is nothing else you need to
+ do. If you want to use a different locale (or you are not sure
+ which locale your system is set to), you can instruct
+ <code class="command">initdb</code> exactly which locale to use by
+ specifying the <code class="option">--locale</code> option. For example:
+</p><pre class="screen">
+initdb --locale=sv_SE
+</pre><p>
+ </p><p>
+ This example for Unix systems sets the locale to Swedish
+ (<code class="literal">sv</code>) as spoken
+ in Sweden (<code class="literal">SE</code>). Other possibilities might include
+ <code class="literal">en_US</code> (U.S. English) and <code class="literal">fr_CA</code> (French
+ Canadian). If more than one character set can be used for a
+ locale then the specifications can take the form
+ <em class="replaceable"><code>language_territory.codeset</code></em>. For example,
+ <code class="literal">fr_BE.UTF-8</code> represents the French language (fr) as
+ spoken in Belgium (BE), with a <acronym class="acronym">UTF-8</acronym> character set
+ encoding.
+ </p><p>
+ What locales are available on your
+ system under what names depends on what was provided by the operating
+ system vendor and what was installed. On most Unix systems, the command
+ <code class="literal">locale -a</code> will provide a list of available locales.
+ Windows uses more verbose locale names, such as <code class="literal">German_Germany</code>
+ or <code class="literal">Swedish_Sweden.1252</code>, but the principles are the same.
+ </p><p>
+ Occasionally it is useful to mix rules from several locales, e.g.,
+ use English collation rules but Spanish messages. To support that, a
+ set of locale subcategories exist that control only certain
+ aspects of the localization rules:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><tbody><tr><td><code class="envar">LC_COLLATE</code></td><td>String sort order</td></tr><tr><td><code class="envar">LC_CTYPE</code></td><td>Character classification (What is a letter? Its upper-case equivalent?)</td></tr><tr><td><code class="envar">LC_MESSAGES</code></td><td>Language of messages</td></tr><tr><td><code class="envar">LC_MONETARY</code></td><td>Formatting of currency amounts</td></tr><tr><td><code class="envar">LC_NUMERIC</code></td><td>Formatting of numbers</td></tr><tr><td><code class="envar">LC_TIME</code></td><td>Formatting of dates and times</td></tr></tbody></table></div><p>
+
+ The category names translate into names of
+ <code class="command">initdb</code> options to override the locale choice
+ for a specific category. For instance, to set the locale to
+ French Canadian, but use U.S. rules for formatting currency, use
+ <code class="literal">initdb --locale=fr_CA --lc-monetary=en_US</code>.
+ </p><p>
+ If you want the system to behave as if it had no locale support,
+ use the special locale name <code class="literal">C</code>, or equivalently
+ <code class="literal">POSIX</code>.
+ </p><p>
+ Some locale categories must have their values
+ fixed when the database is created. You can use different settings
+ for different databases, but once a database is created, you cannot
+ change them for that database anymore. <code class="literal">LC_COLLATE</code>
+ and <code class="literal">LC_CTYPE</code> are these categories. They affect
+ the sort order of indexes, so they must be kept fixed, or indexes on
+ text columns would become corrupt.
+ (But you can alleviate this restriction using collations, as discussed
+ in <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>.)
+ The default values for these
+ categories are determined when <code class="command">initdb</code> is run, and
+ those values are used when new databases are created, unless
+ specified otherwise in the <code class="command">CREATE DATABASE</code> command.
+ </p><p>
+ The other locale categories can be changed whenever desired
+ by setting the server configuration parameters
+ that have the same name as the locale categories (see <a class="xref" href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT" title="20.11.2. Locale and Formatting">Section 20.11.2</a> for details). The values
+ that are chosen by <code class="command">initdb</code> are actually only written
+ into the configuration file <code class="filename">postgresql.conf</code> to
+ serve as defaults when the server is started. If you remove these
+ assignments from <code class="filename">postgresql.conf</code> then the
+ server will inherit the settings from its execution environment.
+ </p><p>
+ Note that the locale behavior of the server is determined by the
+ environment variables seen by the server, not by the environment
+ of any client. Therefore, be careful to configure the correct locale settings
+ before starting the server. A consequence of this is that if
+ client and server are set up in different locales, messages might
+ appear in different languages depending on where they originated.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When we speak of inheriting the locale from the execution
+ environment, this means the following on most operating systems:
+ For a given locale category, say the collation, the following
+ environment variables are consulted in this order until one is
+ found to be set: <code class="envar">LC_ALL</code>, <code class="envar">LC_COLLATE</code>
+ (or the variable corresponding to the respective category),
+ <code class="envar">LANG</code>. If none of these environment variables are
+ set then the locale defaults to <code class="literal">C</code>.
+ </p><p>
+ Some message localization libraries also look at the environment
+ variable <code class="envar">LANGUAGE</code> which overrides all other locale
+ settings for the purpose of setting the language of messages. If
+ in doubt, please refer to the documentation of your operating
+ system, in particular the documentation about
+ <span class="application">gettext</span>.
+ </p></div><p>
+ To enable messages to be translated to the user's preferred language,
+ <acronym class="acronym">NLS</acronym> must have been selected at build time
+ (<code class="literal">configure --enable-nls</code>). All other locale support is
+ built in automatically.
+ </p></div><div class="sect2" id="id-1.6.11.3.5"><div class="titlepage"><div><div><h3 class="title">24.1.2. Behavior</h3></div></div></div><p>
+ The locale settings influence the following SQL features:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Sort order in queries using <code class="literal">ORDER BY</code> or the standard
+ comparison operators on textual data
+ <a id="id-1.6.11.3.5.2.1.1.1.2" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ The <code class="function">upper</code>, <code class="function">lower</code>, and <code class="function">initcap</code>
+ functions
+ <a id="id-1.6.11.3.5.2.1.2.1.4" class="indexterm"></a>
+ <a id="id-1.6.11.3.5.2.1.2.1.5" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ Pattern matching operators (<code class="literal">LIKE</code>, <code class="literal">SIMILAR TO</code>,
+ and POSIX-style regular expressions); locales affect both case
+ insensitive matching and the classification of characters by
+ character-class regular expressions
+ <a id="id-1.6.11.3.5.2.1.3.1.3" class="indexterm"></a>
+ <a id="id-1.6.11.3.5.2.1.3.1.4" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ The <code class="function">to_char</code> family of functions
+ <a id="id-1.6.11.3.5.2.1.4.1.2" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ The ability to use indexes with <code class="literal">LIKE</code> clauses
+ </p></li></ul></div><p>
+ </p><p>
+ The drawback of using locales other than <code class="literal">C</code> or
+ <code class="literal">POSIX</code> in <span class="productname">PostgreSQL</span> is its performance
+ impact. It slows character handling and prevents ordinary indexes
+ from being used by <code class="literal">LIKE</code>. For this reason use locales
+ only if you actually need them.
+ </p><p>
+ As a workaround to allow <span class="productname">PostgreSQL</span> to use indexes
+ with <code class="literal">LIKE</code> clauses under a non-C locale, several custom
+ operator classes exist. These allow the creation of an index that
+ performs a strict character-by-character comparison, ignoring
+ locale comparison rules. Refer to <a class="xref" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Section 11.10</a>
+ for more information. Another approach is to create indexes using
+ the <code class="literal">C</code> collation, as discussed in
+ <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>.
+ </p></div><div class="sect2" id="id-1.6.11.3.6"><div class="titlepage"><div><div><h3 class="title">24.1.3. Selecting Locales</h3></div></div></div><p>
+ Locales can be selected in different scopes depending on requirements.
+ The above overview showed how locales are specified using
+ <code class="command">initdb</code> to set the defaults for the entire cluster. The
+ following list shows where locales can be selected. Each item provides
+ the defaults for the subsequent items, and each lower item allows
+ overriding the defaults on a finer granularity.
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ As explained above, the environment of the operating system provides the
+ defaults for the locales of a newly initialized database cluster. In
+ many cases, this is enough: If the operating system is configured for
+ the desired language/territory, then
+ <span class="productname">PostgreSQL</span> will by default also behave
+ according to that locale.
+ </p></li><li class="listitem"><p>
+ As shown above, command-line options for <code class="command">initdb</code>
+ specify the locale settings for a newly initialized database cluster.
+ Use this if the operating system does not have the locale configuration
+ you want for your database system.
+ </p></li><li class="listitem"><p>
+ A locale can be selected separately for each database. The SQL command
+ <code class="command">CREATE DATABASE</code> and its command-line equivalent
+ <code class="command">createdb</code> have options for that. Use this for example
+ if a database cluster houses databases for multiple tenants with
+ different requirements.
+ </p></li><li class="listitem"><p>
+ Locale settings can be made for individual table columns. This uses an
+ SQL object called <em class="firstterm">collation</em> and is explained in
+ <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>. Use this for example to sort data in
+ different languages or customize the sort order of a particular table.
+ </p></li><li class="listitem"><p>
+ Finally, locales can be selected for an individual query. Again, this
+ uses SQL collation objects. This could be used to change the sort order
+ based on run-time choices or for ad-hoc experimentation.
+ </p></li></ol></div></div><div class="sect2" id="id-1.6.11.3.7"><div class="titlepage"><div><div><h3 class="title">24.1.4. Locale Providers</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> supports multiple <em class="firstterm">locale
+ providers</em>. This specifies which library supplies the locale
+ data. One standard provider name is <code class="literal">libc</code>, which uses
+ the locales provided by the operating system C library. These are the
+ locales used by most tools provided by the operating system. Another
+ provider is <code class="literal">icu</code>, which uses the external
+ ICU<a id="id-1.6.11.3.7.2.5" class="indexterm"></a> library. ICU locales can
+ only be used if support for ICU was configured when PostgreSQL was built.
+ </p><p>
+ The commands and tools that select the locale settings, as described
+ above, each have an option to select the locale provider. The examples
+ shown earlier all use the <code class="literal">libc</code> provider, which is the
+ default. Here is an example to initialize a database cluster using the
+ ICU provider:
+</p><pre class="programlisting">
+initdb --locale-provider=icu --icu-locale=en
+</pre><p>
+ See the description of the respective commands and programs for
+ details. Note that you can mix locale providers at different
+ granularities, for example use <code class="literal">libc</code> by default for the
+ cluster but have one database that uses the <code class="literal">icu</code>
+ provider, and then have collation objects using either provider within
+ those databases.
+ </p><p>
+ Which locale provider to use depends on individual requirements. For most
+ basic uses, either provider will give adequate results. For the libc
+ provider, it depends on what the operating system offers; some operating
+ systems are better than others. For advanced uses, ICU offers more locale
+ variants and customization options.
+ </p></div><div class="sect2" id="id-1.6.11.3.8"><div class="titlepage"><div><div><h3 class="title">24.1.5. Problems</h3></div></div></div><p>
+ If locale support doesn't work according to the explanation above,
+ check that the locale support in your operating system is
+ correctly configured. To check what locales are installed on your
+ system, you can use the command <code class="literal">locale -a</code> if
+ your operating system provides it.
+ </p><p>
+ Check that <span class="productname">PostgreSQL</span> is actually using the locale
+ that you think it is. The <code class="envar">LC_COLLATE</code> and <code class="envar">LC_CTYPE</code>
+ settings are determined when a database is created, and cannot be
+ changed except by creating a new database. Other locale
+ settings including <code class="envar">LC_MESSAGES</code> and <code class="envar">LC_MONETARY</code>
+ are initially determined by the environment the server is started
+ in, but can be changed on-the-fly. You can check the active locale
+ settings using the <code class="command">SHOW</code> command.
+ </p><p>
+ The directory <code class="filename">src/test/locale</code> in the source
+ distribution contains a test suite for
+ <span class="productname">PostgreSQL</span>'s locale support.
+ </p><p>
+ Client applications that handle server-side errors by parsing the
+ text of the error message will obviously have problems when the
+ server's messages are in a different language. Authors of such
+ applications are advised to make use of the error code scheme
+ instead.
+ </p><p>
+ Maintaining catalogs of message translations requires the on-going
+ efforts of many volunteers that want to see
+ <span class="productname">PostgreSQL</span> speak their preferred language well.
+ If messages in your language are currently not available or not fully
+ translated, your assistance would be appreciated. If you want to
+ help, refer to <a class="xref" href="nls.html" title="Chapter 57. Native Language Support">Chapter 57</a> or write to the developers'
+ mailing list.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="charset.html" title="Chapter 24. Localization">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="charset.html" title="Chapter 24. Localization">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="collation.html" title="24.2. Collation Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 24. Localization </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 24.2. Collation Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/locking-indexes.html b/doc/src/sgml/html/locking-indexes.html
new file mode 100644
index 0000000..3adfb5c
--- /dev/null
+++ b/doc/src/sgml/html/locking-indexes.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.7. Locking and Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="mvcc-caveats.html" title="13.6. Caveats" /><link rel="next" href="performance-tips.html" title="Chapter 14. Performance Tips" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.7. Locking and Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="mvcc-caveats.html" title="13.6. Caveats">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="performance-tips.html" title="Chapter 14. Performance Tips">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOCKING-INDEXES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.7. Locking and Indexes</h2></div></div></div><a id="id-1.5.12.10.2" class="indexterm"></a><p>
+ Though <span class="productname">PostgreSQL</span>
+ provides nonblocking read/write access to table
+ data, nonblocking read/write access is not currently offered for every
+ index access method implemented
+ in <span class="productname">PostgreSQL</span>.
+ The various index types are handled as follows:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ B-tree, <acronym class="acronym">GiST</acronym> and <acronym class="acronym">SP-GiST</acronym> indexes
+ </span></dt><dd><p>
+ Short-term share/exclusive page-level locks are used for
+ read/write access. Locks are released immediately after each
+ index row is fetched or inserted. These index types provide
+ the highest concurrency without deadlock conditions.
+ </p></dd><dt><span class="term">
+ Hash indexes
+ </span></dt><dd><p>
+ Share/exclusive hash-bucket-level locks are used for read/write
+ access. Locks are released after the whole bucket is processed.
+ Bucket-level locks provide better concurrency than index-level
+ ones, but deadlock is possible since the locks are held longer
+ than one index operation.
+ </p></dd><dt><span class="term">
+ <acronym class="acronym">GIN</acronym> indexes
+ </span></dt><dd><p>
+ Short-term share/exclusive page-level locks are used for
+ read/write access. Locks are released immediately after each
+ index row is fetched or inserted. But note that insertion of a
+ GIN-indexed value usually produces several index key insertions
+ per row, so GIN might do substantial work for a single value's
+ insertion.
+ </p></dd></dl></div><p>
+ </p><p>
+ Currently, B-tree indexes offer the best performance for concurrent
+ applications; since they also have more features than hash
+ indexes, they are the recommended index type for concurrent
+ applications that need to index scalar data. When dealing with
+ non-scalar data, B-trees are not useful, and GiST, SP-GiST or GIN
+ indexes should be used instead.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="mvcc-caveats.html" title="13.6. Caveats">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="performance-tips.html" title="Chapter 14. Performance Tips">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.6. Caveats </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 14. Performance Tips</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logfile-maintenance.html b/doc/src/sgml/html/logfile-maintenance.html
new file mode 100644
index 0000000..34ca283
--- /dev/null
+++ b/doc/src/sgml/html/logfile-maintenance.html
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>25.3. Log File Maintenance</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="routine-reindex.html" title="25.2. Routine Reindexing" /><link rel="next" href="backup.html" title="Chapter 26. Backup and Restore" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">25.3. Log File Maintenance</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="routine-reindex.html" title="25.2. Routine Reindexing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Up</a></td><th width="60%" align="center">Chapter 25. Routine Database Maintenance Tasks</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup.html" title="Chapter 26. Backup and Restore">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGFILE-MAINTENANCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">25.3. Log File Maintenance</h2></div></div></div><a id="id-1.6.12.12.2" class="indexterm"></a><p>
+ It is a good idea to save the database server's log output
+ somewhere, rather than just discarding it via <code class="filename">/dev/null</code>.
+ The log output is invaluable when diagnosing
+ problems.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The server log can contain sensitive information and needs to be protected,
+ no matter how or where it is stored, or the destination to which it is routed.
+ For example, some DDL statements might contain plaintext passwords or other
+ authentication details. Logged statements at the <code class="literal">ERROR</code>
+ level might show the SQL source code for applications
+ and might also contain some parts of data rows. Recording data, events and
+ related information is the intended function of this facility, so this is
+ not a leakage or a bug. Please ensure the server logs are visible only to
+ appropriately authorized people.
+ </p></div><p>
+ Log output tends to be voluminous
+ (especially at higher debug levels) so you won't want to save it
+ indefinitely. You need to <span class="emphasis"><em>rotate</em></span> the log files so that
+ new log files are started and old ones removed after a reasonable
+ period of time.
+ </p><p>
+ If you simply direct the <span class="systemitem">stderr</span> of
+ <code class="command">postgres</code> into a
+ file, you will have log output, but
+ the only way to truncate the log file is to stop and restart
+ the server. This might be acceptable if you are using
+ <span class="productname">PostgreSQL</span> in a development environment,
+ but few production servers would find this behavior acceptable.
+ </p><p>
+ A better approach is to send the server's
+ <span class="systemitem">stderr</span> output to some type of log rotation program.
+ There is a built-in log rotation facility, which you can use by
+ setting the configuration parameter <code class="varname">logging_collector</code> to
+ <code class="literal">true</code> in <code class="filename">postgresql.conf</code>. The control
+ parameters for this program are described in <a class="xref" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE" title="20.8.1. Where to Log">Section 20.8.1</a>. You can also use this approach
+ to capture the log data in machine readable <acronym class="acronym">CSV</acronym>
+ (comma-separated values) format.
+ </p><p>
+ Alternatively, you might prefer to use an external log rotation
+ program if you have one that you are already using with other
+ server software. For example, the <span class="application">rotatelogs</span>
+ tool included in the <span class="productname">Apache</span> distribution
+ can be used with <span class="productname">PostgreSQL</span>. One way to
+ do this is to pipe the server's
+ <span class="systemitem">stderr</span> output to the desired program.
+ If you start the server with
+ <code class="command">pg_ctl</code>, then <span class="systemitem">stderr</span>
+ is already redirected to <span class="systemitem">stdout</span>, so you just need a
+ pipe command, for example:
+
+</p><pre class="programlisting">
+pg_ctl start | rotatelogs /var/log/pgsql_log 86400
+</pre><p>
+ </p><p>
+ You can combine these approaches by setting up <span class="application">logrotate</span>
+ to collect log files produced by <span class="productname">PostgreSQL</span> built-in
+ logging collector. In this case, the logging collector defines the names and
+ location of the log files, while <span class="application">logrotate</span>
+ periodically archives these files. When initiating log rotation,
+ <span class="application">logrotate</span> must ensure that the application
+ sends further output to the new file. This is commonly done with a
+ <code class="literal">postrotate</code> script that sends a <code class="literal">SIGHUP</code>
+ signal to the application, which then reopens the log file.
+ In <span class="productname">PostgreSQL</span>, you can run <code class="command">pg_ctl</code>
+ with the <code class="literal">logrotate</code> option instead. When the server receives
+ this command, the server either switches to a new log file or reopens the
+ existing file, depending on the logging configuration
+ (see <a class="xref" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE" title="20.8.1. Where to Log">Section 20.8.1</a>).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When using static log file names, the server might fail to reopen the log
+ file if the max open file limit is reached or a file table overflow occurs.
+ In this case, log messages are sent to the old log file until a
+ successful log rotation. If <span class="application">logrotate</span> is
+ configured to compress the log file and delete it, the server may lose
+ the messages logged in this time frame. To avoid this issue, you can
+ configure the logging collector to dynamically assign log file names
+ and use a <code class="literal">prerotate</code> script to ignore open log files.
+ </p></div><p>
+ Another production-grade approach to managing log output is to
+ send it to <span class="application">syslog</span> and let
+ <span class="application">syslog</span> deal with file rotation. To do this, set the
+ configuration parameter <code class="varname">log_destination</code> to <code class="literal">syslog</code>
+ (to log to <span class="application">syslog</span> only) in
+ <code class="filename">postgresql.conf</code>. Then you can send a <code class="literal">SIGHUP</code>
+ signal to the <span class="application">syslog</span> daemon whenever you want to force it
+ to start writing a new log file. If you want to automate log
+ rotation, the <span class="application">logrotate</span> program can be
+ configured to work with log files from
+ <span class="application">syslog</span>.
+ </p><p>
+ On many systems, however, <span class="application">syslog</span> is not very reliable,
+ particularly with large log messages; it might truncate or drop messages
+ just when you need them the most. Also, on <span class="productname">Linux</span>,
+ <span class="application">syslog</span> will flush each message to disk, yielding poor
+ performance. (You can use a <span class="quote">“<span class="quote"><code class="literal">-</code></span>”</span> at the start of the file name
+ in the <span class="application">syslog</span> configuration file to disable syncing.)
+ </p><p>
+ Note that all the solutions described above take care of starting new
+ log files at configurable intervals, but they do not handle deletion
+ of old, no-longer-useful log files. You will probably want to set
+ up a batch job to periodically delete old log files. Another possibility
+ is to configure the rotation program so that old log files are overwritten
+ cyclically.
+ </p><p>
+ <a class="ulink" href="https://pgbadger.darold.net/" target="_top"><span class="productname">pgBadger</span></a>
+ is an external project that does sophisticated log file analysis.
+ <a class="ulink" href="https://bucardo.org/check_postgres/" target="_top"><span class="productname">check_postgres</span></a>
+ provides Nagios alerts when important messages appear in the log
+ files, as well as detection of many other extraordinary conditions.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="routine-reindex.html" title="25.2. Routine Reindexing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup.html" title="Chapter 26. Backup and Restore">Next</a></td></tr><tr><td width="40%" align="left" valign="top">25.2. Routine Reindexing </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 26. Backup and Restore</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-architecture.html b/doc/src/sgml/html/logical-replication-architecture.html
new file mode 100644
index 0000000..bd268de
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-architecture.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.7. Architecture</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-restrictions.html" title="31.6. Restrictions" /><link rel="next" href="logical-replication-monitoring.html" title="31.8. Monitoring" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.7. Architecture</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-restrictions.html" title="31.6. Restrictions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-monitoring.html" title="31.8. Monitoring">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-ARCHITECTURE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.7. Architecture</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logical-replication-architecture.html#LOGICAL-REPLICATION-SNAPSHOT">31.7.1. Initial Snapshot</a></span></dt></dl></div><p>
+ Logical replication starts by copying a snapshot of the data on the
+ publisher database. Once that is done, changes on the publisher are sent
+ to the subscriber as they occur in real time. The subscriber applies data
+ in the order in which commits were made on the publisher so that
+ transactional consistency is guaranteed for the publications within any
+ single subscription.
+ </p><p>
+ Logical replication is built with an architecture similar to physical
+ streaming replication (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>). It is
+ implemented by <span class="quote">“<span class="quote">walsender</span>”</span> and <span class="quote">“<span class="quote">apply</span>”</span>
+ processes. The walsender process starts logical decoding (described
+ in <a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>) of the WAL and loads the standard
+ logical decoding plugin (pgoutput). The plugin transforms the changes read
+ from WAL to the logical replication protocol
+ (see <a class="xref" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol">Section 55.5</a>) and filters the data
+ according to the publication specification. The data is then continuously
+ transferred using the streaming replication protocol to the apply worker,
+ which maps the data to local tables and applies the individual changes as
+ they are received, in correct transactional order.
+ </p><p>
+ The apply process on the subscriber database always runs with
+ <a class="link" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE"><code class="varname">session_replication_role</code></a>
+ set to <code class="literal">replica</code>. This means that, by default,
+ triggers and rules will not fire on a subscriber. Users can optionally choose to
+ enable triggers and rules on a table using the
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a> command
+ and the <code class="literal">ENABLE TRIGGER</code> and <code class="literal">ENABLE RULE</code>
+ clauses.
+ </p><p>
+ The logical replication apply process currently only fires row triggers,
+ not statement triggers. The initial table synchronization, however, is
+ implemented like a <code class="command">COPY</code> command and thus fires both row
+ and statement triggers for <code class="command">INSERT</code>.
+ </p><div class="sect2" id="LOGICAL-REPLICATION-SNAPSHOT"><div class="titlepage"><div><div><h3 class="title">31.7.1. Initial Snapshot</h3></div></div></div><p>
+ The initial data in existing subscribed tables are snapshotted and
+ copied in a parallel instance of a special kind of apply process.
+ This process will create its own replication slot and copy the existing
+ data. As soon as the copy is finished the table contents will become
+ visible to other backends. Once existing data is copied, the worker
+ enters synchronization mode, which ensures that the table is brought
+ up to a synchronized state with the main apply process by streaming
+ any changes that happened during the initial data copy using standard
+ logical replication. During this synchronization phase, the changes
+ are applied and committed in the same order as they happened on the
+ publisher. Once synchronization is done, control of the
+ replication of the table is given back to the main apply process where
+ replication continues as normal.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The publication <code class="literal">publish</code> parameter only affects what
+ DML operations will be replicated. The initial data synchronization does
+ not take this parameter into account when copying the existing table data.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-restrictions.html" title="31.6. Restrictions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-monitoring.html" title="31.8. Monitoring">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.6. Restrictions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.8. Monitoring</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-col-lists.html b/doc/src/sgml/html/logical-replication-col-lists.html
new file mode 100644
index 0000000..55088e8
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-col-lists.html
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.4. Column Lists</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-row-filter.html" title="31.3. Row Filters" /><link rel="next" href="logical-replication-conflicts.html" title="31.5. Conflicts" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.4. Column Lists</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-row-filter.html" title="31.3. Row Filters">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-conflicts.html" title="31.5. Conflicts">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-COL-LISTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.4. Column Lists</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logical-replication-col-lists.html#LOGICAL-REPLICATION-COL-LIST-EXAMPLES">31.4.1. Examples</a></span></dt></dl></div><p>
+ Each publication can optionally specify which columns of each table are
+ replicated to subscribers. The table on the subscriber side must have at
+ least all the columns that are published. If no column list is specified,
+ then all columns on the publisher are replicated.
+ See <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a> for details on the syntax.
+ </p><p>
+ The choice of columns can be based on behavioral or performance reasons.
+ However, do not rely on this feature for security: a malicious subscriber
+ is able to obtain data from columns that are not specifically
+ published. If security is a consideration, protections can be applied
+ at the publisher side.
+ </p><p>
+ If no column list is specified, any columns added later are automatically
+ replicated. This means that having a column list which names all columns
+ is not the same as having no column list at all.
+ </p><p>
+ A column list can contain only simple column references. The order
+ of columns in the list is not preserved.
+ </p><p>
+ Specifying a column list when the publication also publishes
+ <code class="literal">FOR TABLES IN SCHEMA</code> is not supported.
+ </p><p>
+ For partitioned tables, the publication parameter
+ <code class="literal">publish_via_partition_root</code> determines which column list
+ is used. If <code class="literal">publish_via_partition_root</code> is
+ <code class="literal">true</code>, the root partitioned table's column list is used.
+ Otherwise, if <code class="literal">publish_via_partition_root</code> is
+ <code class="literal">false</code> (the default), each partition's column list is used.
+ </p><p>
+ If a publication publishes <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> operations, any column list must include the
+ table's replica identity columns (see
+ <a class="xref" href="sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY"><code class="literal">REPLICA IDENTITY</code></a>).
+ If a publication publishes only <code class="command">INSERT</code> operations, then
+ the column list may omit replica identity columns.
+ </p><p>
+ Column lists have no effect for the <code class="literal">TRUNCATE</code> command.
+ </p><p>
+ During initial data synchronization, only the published columns are
+ copied. However, if the subscriber is from a release prior to 15, then
+ all the columns in the table are copied during initial data synchronization,
+ ignoring any column lists.
+ </p><div class="warning" id="LOGICAL-REPLICATION-COL-LIST-COMBINING"><h3 class="title">Warning: Combining Column Lists from Multiple Publications</h3><p>
+ There's currently no support for subscriptions comprising several
+ publications where the same table has been published with different
+ column lists. <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a> disallows
+ creating such subscriptions, but it is still possible to get into
+ that situation by adding or altering column lists on the publication
+ side after a subscription has been created.
+ </p><p>
+ This means changing the column lists of tables on publications that are
+ already subscribed could lead to errors being thrown on the subscriber
+ side.
+ </p><p>
+ If a subscription is affected by this problem, the only way to resume
+ replication is to adjust one of the column lists on the publication
+ side so that they all match; and then either recreate the subscription,
+ or use <code class="literal">ALTER SUBSCRIPTION ... DROP PUBLICATION</code> to
+ remove one of the offending publications and add it again.
+ </p></div><div class="sect2" id="LOGICAL-REPLICATION-COL-LIST-EXAMPLES"><div class="titlepage"><div><div><h3 class="title">31.4.1. Examples</h3></div></div></div><p>
+ Create a table <code class="literal">t1</code> to be used in the following example.
+</p><pre class="programlisting">
+test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id));
+CREATE TABLE
+</pre><p>
+ Create a publication <code class="literal">p1</code>. A column list is defined for
+ table <code class="literal">t1</code> to reduce the number of columns that will be
+ replicated. Notice that the order of column names in the column list does
+ not matter.
+</p><pre class="programlisting">
+test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d);
+CREATE PUBLICATION
+</pre><p>
+ <code class="literal">psql</code> can be used to show the column lists (if defined)
+ for each publication.
+</p><pre class="programlisting">
+test_pub=# \dRp+
+ Publication p1
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t1" (id, a, b, d)
+</pre><p>
+ <code class="literal">psql</code> can be used to show the column lists (if defined)
+ for each table.
+</p><pre class="programlisting">
+test_pub=# \d t1
+ Table "public.t1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ id | integer | | not null |
+ a | text | | |
+ b | text | | |
+ c | text | | |
+ d | text | | |
+ e | text | | |
+Indexes:
+ "t1_pkey" PRIMARY KEY, btree (id)
+Publications:
+ "p1" (id, a, b, d)
+</pre><p>
+ On the subscriber node, create a table <code class="literal">t1</code> which now
+ only needs a subset of the columns that were on the publisher table
+ <code class="literal">t1</code>, and also create the subscription
+ <code class="literal">s1</code> that subscribes to the publication
+ <code class="literal">p1</code>.
+</p><pre class="programlisting">
+test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
+CREATE TABLE
+test_sub=# CREATE SUBSCRIPTION s1
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
+test_sub-# PUBLICATION p1;
+CREATE SUBSCRIPTION
+</pre><p>
+ On the publisher node, insert some rows to table <code class="literal">t1</code>.
+</p><pre class="programlisting">
+test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
+INSERT 0 1
+test_pub=# SELECT * FROM t1 ORDER BY id;
+ id | a | b | c | d | e
+----+-----+-----+-----+-----+-----
+ 1 | a-1 | b-1 | c-1 | d-1 | e-1
+ 2 | a-2 | b-2 | c-2 | d-2 | e-2
+ 3 | a-3 | b-3 | c-3 | d-3 | e-3
+(3 rows)
+</pre><p>
+ Only data from the column list of publication <code class="literal">p1</code> is
+ replicated.
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1 ORDER BY id;
+ id | b | a | d
+----+-----+-----+-----
+ 1 | b-1 | a-1 | d-1
+ 2 | b-2 | a-2 | d-2
+ 3 | b-3 | a-3 | d-3
+(3 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-row-filter.html" title="31.3. Row Filters">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-conflicts.html" title="31.5. Conflicts">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.3. Row Filters </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.5. Conflicts</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-config.html b/doc/src/sgml/html/logical-replication-config.html
new file mode 100644
index 0000000..8f799ee
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-config.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.10. Configuration Settings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-security.html" title="31.9. Security" /><link rel="next" href="logical-replication-quick-setup.html" title="31.11. Quick Setup" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.10. Configuration Settings</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-security.html" title="31.9. Security">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-quick-setup.html" title="31.11. Quick Setup">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-CONFIG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.10. Configuration Settings</h2></div></div></div><p>
+ Logical replication requires several configuration options to be set.
+ </p><p>
+ On the publisher side, <code class="varname">wal_level</code> must be set to
+ <code class="literal">logical</code>, and <code class="varname">max_replication_slots</code>
+ must be set to at least the number of subscriptions expected to connect,
+ plus some reserve for table synchronization. And
+ <code class="varname">max_wal_senders</code> should be set to at least the same as
+ <code class="varname">max_replication_slots</code> plus the number of physical
+ replicas that are connected at the same time.
+ </p><p>
+ <code class="varname">max_replication_slots</code> must also be set on the subscriber.
+ It should be set to at least the number of subscriptions that will be added
+ to the subscriber, plus some reserve for table synchronization.
+ <code class="varname">max_logical_replication_workers</code> must be set to at least
+ the number of subscriptions, again plus some reserve for the table
+ synchronization. Additionally the <code class="varname">max_worker_processes</code>
+ may need to be adjusted to accommodate for replication workers, at least
+ (<code class="varname">max_logical_replication_workers</code>
+ + <code class="literal">1</code>). Note that some extensions and parallel queries
+ also take worker slots from <code class="varname">max_worker_processes</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-security.html" title="31.9. Security">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-quick-setup.html" title="31.11. Quick Setup">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.9. Security </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.11. Quick Setup</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-conflicts.html b/doc/src/sgml/html/logical-replication-conflicts.html
new file mode 100644
index 0000000..d64ab49
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-conflicts.html
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.5. Conflicts</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-col-lists.html" title="31.4. Column Lists" /><link rel="next" href="logical-replication-restrictions.html" title="31.6. Restrictions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.5. Conflicts</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-col-lists.html" title="31.4. Column Lists">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-restrictions.html" title="31.6. Restrictions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-CONFLICTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.5. Conflicts</h2></div></div></div><p>
+ Logical replication behaves similarly to normal DML operations in that
+ the data will be updated even if it was changed locally on the subscriber
+ node. If incoming data violates any constraints the replication will
+ stop. This is referred to as a <em class="firstterm">conflict</em>. When
+ replicating <code class="command">UPDATE</code> or <code class="command">DELETE</code>
+ operations, missing data will not produce a conflict and such operations
+ will simply be skipped.
+ </p><p>
+ Logical replication operations are performed with the privileges of the role
+ which owns the subscription. Permissions failures on target tables will
+ cause replication conflicts, as will enabled
+ <a class="link" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">row-level security</a> on target tables
+ that the subscription owner is subject to, without regard to whether any
+ policy would ordinarily reject the <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code> or
+ <code class="command">TRUNCATE</code> which is being replicated. This restriction on
+ row-level security may be lifted in a future version of
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ A conflict will produce an error and will stop the replication; it must be
+ resolved manually by the user. Details about the conflict can be found in
+ the subscriber's server log.
+ </p><p>
+ The resolution can be done either by changing data or permissions on the subscriber so
+ that it does not conflict with the incoming change or by skipping the
+ transaction that conflicts with the existing data. When a conflict produces
+ an error, the replication won't proceed, and the logical replication worker will
+ emit the following kind of message to the subscriber's server log:
+</p><pre class="screen">
+ERROR: duplicate key value violates unique constraint "test_pkey"
+DETAIL: Key (c)=(1) already exists.
+CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378
+</pre><p>
+ The LSN of the transaction that contains the change violating the constraint and
+ the replication origin name can be found from the server log (LSN 0/14C0378 and
+ replication origin <code class="literal">pg_16395</code> in the above case). The
+ transaction that produced the conflict can be skipped by using
+ <code class="command">ALTER SUBSCRIPTION ... SKIP</code> with the finish LSN
+ (i.e., LSN 0/14C0378). The finish LSN could be an LSN at which the transaction
+ is committed or prepared on the publisher. Alternatively, the transaction can
+ also be skipped by calling the <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-ADVANCE">
+ <code class="function">pg_replication_origin_advance()</code></a> function.
+ Before using this function, the subscription needs to be disabled temporarily
+ either by <code class="command">ALTER SUBSCRIPTION ... DISABLE</code> or, the
+ subscription can be used with the <code class="literal">disable_on_error</code> option.
+ Then, you can use <code class="function">pg_replication_origin_advance()</code> function
+ with the <em class="parameter"><code>node_name</code></em> (i.e., <code class="literal">pg_16395</code>)
+ and the next LSN of the finish LSN (i.e., 0/14C0379). The current position of
+ origins can be seen in the <a class="link" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">
+ <code class="structname">pg_replication_origin_status</code></a> system view.
+ Please note that skipping the whole transaction includes skipping changes that
+ might not violate any constraint. This can easily make the subscriber
+ inconsistent.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-col-lists.html" title="31.4. Column Lists">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-restrictions.html" title="31.6. Restrictions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.4. Column Lists </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.6. Restrictions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-monitoring.html b/doc/src/sgml/html/logical-replication-monitoring.html
new file mode 100644
index 0000000..108ffa0
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-monitoring.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.8. Monitoring</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-architecture.html" title="31.7. Architecture" /><link rel="next" href="logical-replication-security.html" title="31.9. Security" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.8. Monitoring</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-architecture.html" title="31.7. Architecture">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-security.html" title="31.9. Security">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-MONITORING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.8. Monitoring</h2></div></div></div><p>
+ Because logical replication is based on a similar architecture as
+ <a class="link" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">physical streaming replication</a>,
+ the monitoring on a publication node is similar to monitoring of a
+ physical replication primary
+ (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-MONITORING" title="27.2.5.2. Monitoring">Section 27.2.5.2</a>).
+ </p><p>
+ The monitoring information about subscription is visible in
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION" title="28.2.8. pg_stat_subscription">
+ <code class="structname">pg_stat_subscription</code></a>.
+ This view contains one row for every subscription worker. A subscription
+ can have zero or more active subscription workers depending on its state.
+ </p><p>
+ Normally, there is a single apply process running for an enabled
+ subscription. A disabled subscription or a crashed subscription will have
+ zero rows in this view. If the initial data synchronization of any
+ table is in progress, there will be additional workers for the tables
+ being synchronized.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-architecture.html" title="31.7. Architecture">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-security.html" title="31.9. Security">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.7. Architecture </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.9. Security</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-publication.html b/doc/src/sgml/html/logical-replication-publication.html
new file mode 100644
index 0000000..0dd242d
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-publication.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.1. Publication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication.html" title="Chapter 31. Logical Replication" /><link rel="next" href="logical-replication-subscription.html" title="31.2. Subscription" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.1. Publication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication.html" title="Chapter 31. Logical Replication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-subscription.html" title="31.2. Subscription">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-PUBLICATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.1. Publication</h2></div></div></div><p>
+ A <em class="firstterm">publication</em> can be defined on any physical
+ replication primary. The node where a publication is defined is referred to
+ as <em class="firstterm">publisher</em>. A publication is a set of changes
+ generated from a table or a group of tables, and might also be described as
+ a change set or replication set. Each publication exists in only one database.
+ </p><p>
+ Publications are different from schemas and do not affect how the table is
+ accessed. Each table can be added to multiple publications if needed.
+ Publications may currently only contain tables and all tables in schema.
+ Objects must be added explicitly, except when a publication is created for
+ <code class="literal">ALL TABLES</code>.
+ </p><p>
+ Publications can choose to limit the changes they produce to
+ any combination of <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, and <code class="command">TRUNCATE</code>, similar to how triggers are fired by
+ particular event types. By default, all operation types are replicated.
+ These publication specifications apply only for DML operations; they do not affect the initial
+ data synchronization copy. (Row filters have no effect for
+ <code class="command">TRUNCATE</code>. See <a class="xref" href="logical-replication-row-filter.html" title="31.3. Row Filters">Section 31.3</a>).
+ </p><p>
+ A published table must have a <span class="quote">“<span class="quote">replica identity</span>”</span> configured in
+ order to be able to replicate <code class="command">UPDATE</code>
+ and <code class="command">DELETE</code> operations, so that appropriate rows to
+ update or delete can be identified on the subscriber side. By default,
+ this is the primary key, if there is one. Another unique index (with
+ certain additional requirements) can also be set to be the replica
+ identity. If the table does not have any suitable key, then it can be set
+ to replica identity <span class="quote">“<span class="quote">full</span>”</span>, which means the entire row becomes
+ the key. This, however, is very inefficient and should only be used as a
+ fallback if no other solution is possible. If a replica identity other
+ than <span class="quote">“<span class="quote">full</span>”</span> is set on the publisher side, a replica identity
+ comprising the same or fewer columns must also be set on the subscriber
+ side. See <a class="xref" href="sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY"><code class="literal">REPLICA IDENTITY</code></a> for details on
+ how to set the replica identity. If a table without a replica identity is
+ added to a publication that replicates <code class="command">UPDATE</code>
+ or <code class="command">DELETE</code> operations then
+ subsequent <code class="command">UPDATE</code> or <code class="command">DELETE</code>
+ operations will cause an error on the publisher. <code class="command">INSERT</code>
+ operations can proceed regardless of any replica identity.
+ </p><p>
+ Every publication can have multiple subscribers.
+ </p><p>
+ A publication is created using the <a class="link" href="sql-createpublication.html" title="CREATE PUBLICATION"><code class="command">CREATE PUBLICATION</code></a>
+ command and may later be altered or dropped using corresponding commands.
+ </p><p>
+ The individual tables can be added and removed dynamically using
+ <a class="link" href="sql-alterpublication.html" title="ALTER PUBLICATION"><code class="command">ALTER PUBLICATION</code></a>. Both the <code class="literal">ADD
+ TABLE</code> and <code class="literal">DROP TABLE</code> operations are
+ transactional; so the table will start or stop replicating at the correct
+ snapshot once the transaction has committed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication.html" title="Chapter 31. Logical Replication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-subscription.html" title="31.2. Subscription">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 31. Logical Replication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.2. Subscription</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-quick-setup.html b/doc/src/sgml/html/logical-replication-quick-setup.html
new file mode 100644
index 0000000..eafda8a
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-quick-setup.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.11. Quick Setup</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-config.html" title="31.10. Configuration Settings" /><link rel="next" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.11. Quick Setup</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-config.html" title="31.10. Configuration Settings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-QUICK-SETUP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.11. Quick Setup</h2></div></div></div><p>
+ First set the configuration options in <code class="filename">postgresql.conf</code>:
+</p><pre class="programlisting">
+wal_level = logical
+</pre><p>
+ The other required settings have default values that are sufficient for a
+ basic setup.
+ </p><p>
+ <code class="filename">pg_hba.conf</code> needs to be adjusted to allow replication
+ (the values here depend on your actual network configuration and user you
+ want to use for connecting):
+</p><pre class="programlisting">
+host all repuser 0.0.0.0/0 md5
+</pre><p>
+ </p><p>
+ Then on the publisher database:
+</p><pre class="programlisting">
+CREATE PUBLICATION mypub FOR TABLE users, departments;
+</pre><p>
+ </p><p>
+ And on the subscriber database:
+</p><pre class="programlisting">
+CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=bar user=repuser' PUBLICATION mypub;
+</pre><p>
+ </p><p>
+ The above will start the replication process, which synchronizes the
+ initial table contents of the tables <code class="literal">users</code> and
+ <code class="literal">departments</code> and then starts replicating
+ incremental changes to those tables.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-config.html" title="31.10. Configuration Settings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.10. Configuration Settings </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 32. Just-in-Time Compilation (<acronym class="acronym">JIT</acronym>)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-restrictions.html b/doc/src/sgml/html/logical-replication-restrictions.html
new file mode 100644
index 0000000..d922b80
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-restrictions.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.6. Restrictions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-conflicts.html" title="31.5. Conflicts" /><link rel="next" href="logical-replication-architecture.html" title="31.7. Architecture" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.6. Restrictions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-conflicts.html" title="31.5. Conflicts">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-architecture.html" title="31.7. Architecture">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-RESTRICTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.6. Restrictions</h2></div></div></div><p>
+ Logical replication currently has the following restrictions or missing
+ functionality. These might be addressed in future releases.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The database schema and DDL commands are not replicated. The initial
+ schema can be copied by hand using <code class="literal">pg_dump
+ --schema-only</code>. Subsequent schema changes would need to be kept
+ in sync manually. (Note, however, that there is no need for the schemas
+ to be absolutely the same on both sides.) Logical replication is robust
+ when schema definitions change in a live database: When the schema is
+ changed on the publisher and replicated data starts arriving at the
+ subscriber but does not fit into the table schema, replication will error
+ until the schema is updated. In many cases, intermittent errors can be
+ avoided by applying additive schema changes to the subscriber first.
+ </p></li><li class="listitem"><p>
+ Sequence data is not replicated. The data in serial or identity columns
+ backed by sequences will of course be replicated as part of the table,
+ but the sequence itself would still show the start value on the
+ subscriber. If the subscriber is used as a read-only database, then this
+ should typically not be a problem. If, however, some kind of switchover
+ or failover to the subscriber database is intended, then the sequences
+ would need to be updated to the latest values, either by copying the
+ current data from the publisher (perhaps
+ using <code class="command">pg_dump</code>) or by determining a sufficiently high
+ value from the tables themselves.
+ </p></li><li class="listitem"><p>
+ Replication of <code class="command">TRUNCATE</code> commands is supported, but
+ some care must be taken when truncating groups of tables connected by
+ foreign keys. When replicating a truncate action, the subscriber will
+ truncate the same group of tables that was truncated on the publisher,
+ either explicitly specified or implicitly collected via
+ <code class="literal">CASCADE</code>, minus tables that are not part of the
+ subscription. This will work correctly if all affected tables are part
+ of the same subscription. But if some tables to be truncated on the
+ subscriber have foreign-key links to tables that are not part of the same
+ (or any) subscription, then the application of the truncate action on the
+ subscriber will fail.
+ </p></li><li class="listitem"><p>
+ Large objects (see <a class="xref" href="largeobjects.html" title="Chapter 35. Large Objects">Chapter 35</a>) are not replicated.
+ There is no workaround for that, other than storing data in normal
+ tables.
+ </p></li><li class="listitem"><p>
+ Replication is only supported by tables, including partitioned tables.
+ Attempts to replicate other types of relations, such as views, materialized
+ views, or foreign tables, will result in an error.
+ </p></li><li class="listitem"><p>
+ When replicating between partitioned tables, the actual replication
+ originates, by default, from the leaf partitions on the publisher, so
+ partitions on the publisher must also exist on the subscriber as valid
+ target tables. (They could either be leaf partitions themselves, or they
+ could be further subpartitioned, or they could even be independent
+ tables.) Publications can also specify that changes are to be replicated
+ using the identity and schema of the partitioned root table instead of
+ that of the individual leaf partitions in which the changes actually
+ originate (see <a class="link" href="sql-createpublication.html" title="CREATE PUBLICATION"><code class="command">CREATE PUBLICATION</code></a>).
+ </p></li></ul></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-conflicts.html" title="31.5. Conflicts">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-architecture.html" title="31.7. Architecture">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.5. Conflicts </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.7. Architecture</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-row-filter.html b/doc/src/sgml/html/logical-replication-row-filter.html
new file mode 100644
index 0000000..4f88690
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-row-filter.html
@@ -0,0 +1,440 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.3. Row Filters</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-subscription.html" title="31.2. Subscription" /><link rel="next" href="logical-replication-col-lists.html" title="31.4. Column Lists" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.3. Row Filters</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-subscription.html" title="31.2. Subscription">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-col-lists.html" title="31.4. Column Lists">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-ROW-FILTER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.3. Row Filters</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-RULES">31.3.1. Row Filter Rules</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-RESTRICTIONS">31.3.2. Expression Restrictions</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-TRANSFORMATIONS">31.3.3. UPDATE Transformations</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-PARTITIONED-TABLE">31.3.4. Partitioned Tables</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-INITIAL-DATA-SYNC">31.3.5. Initial Data Synchronization</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-COMBINING">31.3.6. Combining Multiple Row Filters</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-EXAMPLES">31.3.7. Examples</a></span></dt></dl></div><p>
+ By default, all data from all published tables will be replicated to the
+ appropriate subscribers. The replicated data can be reduced by using a
+ <em class="firstterm">row filter</em>. A user might choose to use row filters
+ for behavioral, security or performance reasons. If a published table sets a
+ row filter, a row is replicated only if its data satisfies the row filter
+ expression. This allows a set of tables to be partially replicated. The row
+ filter is defined per table. Use a <code class="literal">WHERE</code> clause after the
+ table name for each published table that requires data to be filtered out.
+ The <code class="literal">WHERE</code> clause must be enclosed by parentheses. See
+ <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a> for details.
+ </p><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-RULES"><div class="titlepage"><div><div><h3 class="title">31.3.1. Row Filter Rules</h3></div></div></div><p>
+ Row filters are applied <span class="emphasis"><em>before</em></span> publishing the changes.
+ If the row filter evaluates to <code class="literal">false</code> or <code class="literal">NULL</code>
+ then the row is not replicated. The <code class="literal">WHERE</code> clause expression
+ is evaluated with the same role used for the replication connection (i.e.
+ the role specified in the <code class="literal">CONNECTION</code> clause of the
+ <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>). Row filters have no effect for
+ <code class="command">TRUNCATE</code> command.
+ </p></div><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-RESTRICTIONS"><div class="titlepage"><div><div><h3 class="title">31.3.2. Expression Restrictions</h3></div></div></div><p>
+ The <code class="literal">WHERE</code> clause allows only simple expressions. It
+ cannot contain user-defined functions, operators, types, and collations,
+ system column references or non-immutable built-in functions.
+ </p><p>
+ If a publication publishes <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> operations, the row filter <code class="literal">WHERE</code>
+ clause must contain only columns that are covered by the replica identity
+ (see <a class="xref" href="sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY"><code class="literal">REPLICA IDENTITY</code></a>). If a publication
+ publishes only <code class="command">INSERT</code> operations, the row filter
+ <code class="literal">WHERE</code> clause can use any column.
+ </p></div><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-TRANSFORMATIONS"><div class="titlepage"><div><div><h3 class="title">31.3.3. UPDATE Transformations</h3></div></div></div><p>
+ Whenever an <code class="command">UPDATE</code> is processed, the row filter
+ expression is evaluated for both the old and new row (i.e. using the data
+ before and after the update). If both evaluations are <code class="literal">true</code>,
+ it replicates the <code class="command">UPDATE</code> change. If both evaluations are
+ <code class="literal">false</code>, it doesn't replicate the change. If only one of
+ the old/new rows matches the row filter expression, the <code class="command">UPDATE</code>
+ is transformed to <code class="command">INSERT</code> or <code class="command">DELETE</code>, to
+ avoid any data inconsistency. The row on the subscriber should reflect what
+ is defined by the row filter expression on the publisher.
+ </p><p>
+ If the old row satisfies the row filter expression (it was sent to the
+ subscriber) but the new row doesn't, then, from a data consistency
+ perspective the old row should be removed from the subscriber.
+ So the <code class="command">UPDATE</code> is transformed into a <code class="command">DELETE</code>.
+ </p><p>
+ If the old row doesn't satisfy the row filter expression (it wasn't sent
+ to the subscriber) but the new row does, then, from a data consistency
+ perspective the new row should be added to the subscriber.
+ So the <code class="command">UPDATE</code> is transformed into an <code class="command">INSERT</code>.
+ </p><p>
+ <a class="xref" href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-TRANSFORMATIONS-SUMMARY" title="Table 31.1. UPDATE Transformation Summary">Table 31.1</a>
+ summarizes the applied transformations.
+ </p><div class="table" id="LOGICAL-REPLICATION-ROW-FILTER-TRANSFORMATIONS-SUMMARY"><p class="title"><strong>Table 31.1. <code class="command">UPDATE</code> Transformation Summary</strong></p><div class="table-contents"><table class="table" summary="UPDATE Transformation Summary" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Old row</th><th>New row</th><th>Transformation</th></tr></thead><tbody><tr><td>no match</td><td>no match</td><td>don't replicate</td></tr><tr><td>no match</td><td>match</td><td><code class="literal">INSERT</code></td></tr><tr><td>match</td><td>no match</td><td><code class="literal">DELETE</code></td></tr><tr><td>match</td><td>match</td><td><code class="literal">UPDATE</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-PARTITIONED-TABLE"><div class="titlepage"><div><div><h3 class="title">31.3.4. Partitioned Tables</h3></div></div></div><p>
+ If the publication contains a partitioned table, the publication parameter
+ <code class="literal">publish_via_partition_root</code> determines which row filter
+ is used. If <code class="literal">publish_via_partition_root</code> is <code class="literal">true</code>,
+ the <span class="emphasis"><em>root partitioned table's</em></span> row filter is used. Otherwise,
+ if <code class="literal">publish_via_partition_root</code> is <code class="literal">false</code>
+ (default), each <span class="emphasis"><em>partition's</em></span> row filter is used.
+ </p></div><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-INITIAL-DATA-SYNC"><div class="titlepage"><div><div><h3 class="title">31.3.5. Initial Data Synchronization</h3></div></div></div><p>
+ If the subscription requires copying pre-existing table data
+ and a publication contains <code class="literal">WHERE</code> clauses, only data that
+ satisfies the row filter expressions is copied to the subscriber.
+ </p><p>
+ If the subscription has several publications in which a table has been
+ published with different <code class="literal">WHERE</code> clauses, rows that satisfy
+ <span class="emphasis"><em>any</em></span> of the expressions will be copied. See
+ <a class="xref" href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-COMBINING" title="31.3.6. Combining Multiple Row Filters">Section 31.3.6</a> for details.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ Because initial data synchronization does not take into account the
+ <code class="literal">publish</code> parameter when copying existing table data,
+ some rows may be copied that would not be replicated using DML. Refer to
+ <a class="xref" href="logical-replication-architecture.html#LOGICAL-REPLICATION-SNAPSHOT" title="31.7.1. Initial Snapshot">Section 31.7.1</a>, and see
+ <a class="xref" href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES" title="31.2.2. Examples">Section 31.2.2</a> for examples.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ If the subscriber is in a release prior to 15, copy pre-existing data
+ doesn't use row filters even if they are defined in the publication.
+ This is because old releases can only copy the entire table data.
+ </p></div></div><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-COMBINING"><div class="titlepage"><div><div><h3 class="title">31.3.6. Combining Multiple Row Filters</h3></div></div></div><p>
+ If the subscription has several publications in which the same table has
+ been published with different row filters (for the same <code class="literal">publish</code>
+ operation), those expressions get ORed together, so that rows satisfying
+ <span class="emphasis"><em>any</em></span> of the expressions will be replicated. This means all
+ the other row filters for the same table become redundant if:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ One of the publications has no row filter.
+ </p></li><li class="listitem"><p>
+ One of the publications was created using <code class="literal">FOR ALL TABLES</code>.
+ This clause does not allow row filters.
+ </p></li><li class="listitem"><p>
+ One of the publications was created using
+ <code class="literal">FOR TABLES IN SCHEMA</code> and the table belongs to
+ the referred schema. This clause does not allow row filters.
+ </p></li></ul></div></div><div class="sect2" id="LOGICAL-REPLICATION-ROW-FILTER-EXAMPLES"><div class="titlepage"><div><div><h3 class="title">31.3.7. Examples</h3></div></div></div><p>
+ Create some tables to be used in the following examples.
+</p><pre class="programlisting">
+test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
+CREATE TABLE
+test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d));
+CREATE TABLE
+test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g));
+CREATE TABLE
+</pre><p>
+ Create some publications. Publication <code class="literal">p1</code> has one table
+ (<code class="literal">t1</code>) and that table has a row filter. Publication
+ <code class="literal">p2</code> has two tables. Table <code class="literal">t1</code> has no row
+ filter, and table <code class="literal">t2</code> has a row filter. Publication
+ <code class="literal">p3</code> has two tables, and both of them have a row filter.
+</p><pre class="programlisting">
+test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a &gt; 5 AND c = 'NSW');
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99);
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10);
+CREATE PUBLICATION
+</pre><p>
+ <code class="command">psql</code> can be used to show the row filter expressions (if
+ defined) for each publication.
+</p><pre class="programlisting">
+test_pub=# \dRp+
+ Publication p1
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t1" WHERE ((a &gt; 5) AND (c = 'NSW'::text))
+
+ Publication p2
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t1"
+ "public.t2" WHERE (e = 99)
+
+ Publication p3
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t2" WHERE (d = 10)
+ "public.t3" WHERE (g = 10)
+</pre><p>
+ <code class="command">psql</code> can be used to show the row filter expressions (if
+ defined) for each table. See that table <code class="literal">t1</code> is a member
+ of two publications, but has a row filter only in <code class="literal">p1</code>.
+ See that table <code class="literal">t2</code> is a member of two publications, and
+ has a different row filter in each of them.
+</p><pre class="programlisting">
+test_pub=# \d t1
+ Table "public.t1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | integer | | not null |
+ b | integer | | |
+ c | text | | not null |
+Indexes:
+ "t1_pkey" PRIMARY KEY, btree (a, c)
+Publications:
+ "p1" WHERE ((a &gt; 5) AND (c = 'NSW'::text))
+ "p2"
+
+test_pub=# \d t2
+ Table "public.t2"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ d | integer | | not null |
+ e | integer | | |
+ f | integer | | |
+Indexes:
+ "t2_pkey" PRIMARY KEY, btree (d)
+Publications:
+ "p2" WHERE (e = 99)
+ "p3" WHERE (d = 10)
+
+test_pub=# \d t3
+ Table "public.t3"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ g | integer | | not null |
+ h | integer | | |
+ i | integer | | |
+Indexes:
+ "t3_pkey" PRIMARY KEY, btree (g)
+Publications:
+ "p3" WHERE (g = 10)
+</pre><p>
+ On the subscriber node, create a table <code class="literal">t1</code> with the same
+ definition as the one on the publisher, and also create the subscription
+ <code class="literal">s1</code> that subscribes to the publication <code class="literal">p1</code>.
+</p><pre class="programlisting">
+test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
+CREATE TABLE
+test_sub=# CREATE SUBSCRIPTION s1
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
+test_sub-# PUBLICATION p1;
+CREATE SUBSCRIPTION
+</pre><p>
+ Insert some rows. Only the rows satisfying the <code class="literal">t1 WHERE</code>
+ clause of publication <code class="literal">p1</code> are replicated.
+</p><pre class="programlisting">
+test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW');
+INSERT 0 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 2 | 102 | NSW
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 6 | 106 | NSW
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 9 | 109 | NSW
+(8 rows)
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 6 | 106 | NSW
+ 9 | 109 | NSW
+(2 rows)
+</pre><p>
+ Update some data, where the old and new row values both
+ satisfy the <code class="literal">t1 WHERE</code> clause of publication
+ <code class="literal">p1</code>. The <code class="command">UPDATE</code> replicates
+ the change as normal.
+</p><pre class="programlisting">
+test_pub=# UPDATE t1 SET b = 999 WHERE a = 6;
+UPDATE 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 2 | 102 | NSW
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+(8 rows)
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+(2 rows)
+</pre><p>
+ Update some data, where the old row values did not satisfy
+ the <code class="literal">t1 WHERE</code> clause of publication <code class="literal">p1</code>,
+ but the new row values do satisfy it. The <code class="command">UPDATE</code> is
+ transformed into an <code class="command">INSERT</code> and the change is replicated.
+ See the new row on the subscriber.
+</p><pre class="programlisting">
+test_pub=# UPDATE t1 SET a = 555 WHERE a = 2;
+UPDATE 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+(8 rows)
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+(3 rows)
+</pre><p>
+ Update some data, where the old row values satisfied
+ the <code class="literal">t1 WHERE</code> clause of publication <code class="literal">p1</code>,
+ but the new row values do not satisfy it. The <code class="command">UPDATE</code> is
+ transformed into a <code class="command">DELETE</code> and the change is replicated.
+ See that the row is removed from the subscriber.
+</p><pre class="programlisting">
+test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9;
+UPDATE 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+ 9 | 109 | VIC
+(8 rows)
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+(2 rows)
+</pre><p>
+ The following examples show how the publication parameter
+ <code class="literal">publish_via_partition_root</code> determines whether the row
+ filter of the parent or child table will be used in the case of partitioned
+ tables.
+ </p><p>
+ Create a partitioned table on the publisher.
+</p><pre class="programlisting">
+test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
+CREATE TABLE
+test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT;
+CREATE TABLE
+</pre><p>
+ Create the same tables on the subscriber.
+</p><pre class="programlisting">
+test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
+CREATE TABLE
+test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT;
+CREATE TABLE
+</pre><p>
+ Create a publication <code class="literal">p4</code>, and then subscribe to it. The
+ publication parameter <code class="literal">publish_via_partition_root</code> is set
+ as true. There are row filters defined on both the partitioned table
+ (<code class="literal">parent</code>), and on the partition (<code class="literal">child</code>).
+</p><pre class="programlisting">
+test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a &lt; 5), child WHERE (a &gt;= 5)
+test_pub-# WITH (publish_via_partition_root=true);
+CREATE PUBLICATION
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# CREATE SUBSCRIPTION s4
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4'
+test_sub-# PUBLICATION p4;
+CREATE SUBSCRIPTION
+</pre><p>
+ Insert some values directly into the <code class="literal">parent</code> and
+ <code class="literal">child</code> tables. They replicate using the row filter of
+ <code class="literal">parent</code> (because <code class="literal">publish_via_partition_root</code>
+ is true).
+</p><pre class="programlisting">
+test_pub=# INSERT INTO parent VALUES (2), (4), (6);
+INSERT 0 3
+test_pub=# INSERT INTO child VALUES (3), (5), (7);
+INSERT 0 3
+
+test_pub=# SELECT * FROM parent ORDER BY a;
+ a
+---
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+(6 rows)
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM parent ORDER BY a;
+ a
+---
+ 2
+ 3
+ 4
+(3 rows)
+</pre><p>
+ Repeat the same test, but with a different value for <code class="literal">publish_via_partition_root</code>.
+ The publication parameter <code class="literal">publish_via_partition_root</code> is
+ set as false. A row filter is defined on the partition (<code class="literal">child</code>).
+</p><pre class="programlisting">
+test_pub=# DROP PUBLICATION p4;
+DROP PUBLICATION
+test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a &gt;= 5)
+test_pub-# WITH (publish_via_partition_root=false);
+CREATE PUBLICATION
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION;
+ALTER SUBSCRIPTION
+</pre><p>
+ Do the inserts on the publisher same as before. They replicate using the
+ row filter of <code class="literal">child</code> (because
+ <code class="literal">publish_via_partition_root</code> is false).
+</p><pre class="programlisting">
+test_pub=# TRUNCATE parent;
+TRUNCATE TABLE
+test_pub=# INSERT INTO parent VALUES (2), (4), (6);
+INSERT 0 3
+test_pub=# INSERT INTO child VALUES (3), (5), (7);
+INSERT 0 3
+
+test_pub=# SELECT * FROM parent ORDER BY a;
+ a
+---
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+(6 rows)
+</pre><p>
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM child ORDER BY a;
+ a
+---
+ 5
+ 6
+ 7
+(3 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-subscription.html" title="31.2. Subscription">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-col-lists.html" title="31.4. Column Lists">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.2. Subscription </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.4. Column Lists</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-security.html b/doc/src/sgml/html/logical-replication-security.html
new file mode 100644
index 0000000..33e9de6
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-security.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.9. Security</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-monitoring.html" title="31.8. Monitoring" /><link rel="next" href="logical-replication-config.html" title="31.10. Configuration Settings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.9. Security</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-monitoring.html" title="31.8. Monitoring">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-config.html" title="31.10. Configuration Settings">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-SECURITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.9. Security</h2></div></div></div><p>
+ A user able to modify the schema of subscriber-side tables can execute
+ arbitrary code as the role which owns any subscription which modifies those tables. Limit ownership
+ and <code class="literal">TRIGGER</code> privilege on such tables to trusted roles.
+ Moreover, if untrusted users can create tables, use only
+ publications that list tables explicitly. That is to say, create a
+ subscription <code class="literal">FOR ALL TABLES</code> or
+ <code class="literal">FOR TABLES IN SCHEMA</code> only when superusers trust
+ every user permitted to create a non-temp table on the publisher or the
+ subscriber.
+ </p><p>
+ The role used for the replication connection must have
+ the <code class="literal">REPLICATION</code> attribute (or be a superuser). If the
+ role lacks <code class="literal">SUPERUSER</code> and <code class="literal">BYPASSRLS</code>,
+ publisher row security policies can execute. If the role does not trust
+ all table owners, include <code class="literal">options=-crow_security=off</code> in
+ the connection string; if a table owner then adds a row security policy,
+ that setting will cause replication to halt rather than execute the policy.
+ Access for the role must be configured in <code class="filename">pg_hba.conf</code>
+ and it must have the <code class="literal">LOGIN</code> attribute.
+ </p><p>
+ In order to be able to copy the initial table data, the role used for the
+ replication connection must have the <code class="literal">SELECT</code> privilege on
+ a published table (or be a superuser).
+ </p><p>
+ To create a publication, the user must have the <code class="literal">CREATE</code>
+ privilege in the database.
+ </p><p>
+ To add tables to a publication, the user must have ownership rights on the
+ table. To add all tables in schema to a publication, the user must be a
+ superuser. To create a publication that publishes all tables or all tables in
+ schema automatically, the user must be a superuser.
+ </p><p>
+ To create a subscription, the user must be a superuser.
+ </p><p>
+ The subscription apply process will run in the local database with the
+ privileges of the subscription owner.
+ </p><p>
+ On the publisher, privileges are only checked once at the start of a
+ replication connection and are not re-checked as each change record is read.
+ </p><p>
+ On the subscriber, the subscription owner's privileges are re-checked for
+ each transaction when applied. If a worker is in the process of applying a
+ transaction when the ownership of the subscription is changed by a
+ concurrent transaction, the application of the current transaction will
+ continue under the old owner's privileges.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-monitoring.html" title="31.8. Monitoring">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-config.html" title="31.10. Configuration Settings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.8. Monitoring </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.10. Configuration Settings</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication-subscription.html b/doc/src/sgml/html/logical-replication-subscription.html
new file mode 100644
index 0000000..d1b4dcb
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication-subscription.html
@@ -0,0 +1,278 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>31.2. Subscription</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logical-replication-publication.html" title="31.1. Publication" /><link rel="next" href="logical-replication-row-filter.html" title="31.3. Row Filters" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">31.2. Subscription</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logical-replication-publication.html" title="31.1. Publication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><th width="60%" align="center">Chapter 31. Logical Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-row-filter.html" title="31.3. Row Filters">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICAL-REPLICATION-SUBSCRIPTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">31.2. Subscription</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-SLOT">31.2.1. Replication Slot Management</a></span></dt><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES">31.2.2. Examples</a></span></dt></dl></div><p>
+ A <em class="firstterm">subscription</em> is the downstream side of logical
+ replication. The node where a subscription is defined is referred to as
+ the <em class="firstterm">subscriber</em>. A subscription defines the connection
+ to another database and set of publications (one or more) to which it wants
+ to subscribe.
+ </p><p>
+ The subscriber database behaves in the same way as any other PostgreSQL
+ instance and can be used as a publisher for other databases by defining its
+ own publications.
+ </p><p>
+ A subscriber node may have multiple subscriptions if desired. It is
+ possible to define multiple subscriptions between a single
+ publisher-subscriber pair, in which case care must be taken to ensure
+ that the subscribed publication objects don't overlap.
+ </p><p>
+ Each subscription will receive changes via one replication slot (see
+ <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a>). Additional replication
+ slots may be required for the initial data synchronization of
+ pre-existing table data and those will be dropped at the end of data
+ synchronization.
+ </p><p>
+ A logical replication subscription can be a standby for synchronous
+ replication (see <a class="xref" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="27.2.8. Synchronous Replication">Section 27.2.8</a>). The standby
+ name is by default the subscription name. An alternative name can be
+ specified as <code class="literal">application_name</code> in the connection
+ information of the subscription.
+ </p><p>
+ Subscriptions are dumped by <code class="command">pg_dump</code> if the current user
+ is a superuser. Otherwise a warning is written and subscriptions are
+ skipped, because non-superusers cannot read all subscription information
+ from the <code class="structname">pg_subscription</code> catalog.
+ </p><p>
+ The subscription is added using <a class="link" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><code class="command">CREATE SUBSCRIPTION</code></a> and
+ can be stopped/resumed at any time using the
+ <a class="link" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><code class="command">ALTER SUBSCRIPTION</code></a> command and removed using
+ <a class="link" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION"><code class="command">DROP SUBSCRIPTION</code></a>.
+ </p><p>
+ When a subscription is dropped and recreated, the synchronization
+ information is lost. This means that the data has to be resynchronized
+ afterwards.
+ </p><p>
+ The schema definitions are not replicated, and the published tables must
+ exist on the subscriber. Only regular tables may be
+ the target of replication. For example, you can't replicate to a view.
+ </p><p>
+ The tables are matched between the publisher and the subscriber using the
+ fully qualified table name. Replication to differently-named tables on the
+ subscriber is not supported.
+ </p><p>
+ Columns of a table are also matched by name. The order of columns in the
+ subscriber table does not need to match that of the publisher. The data
+ types of the columns do not need to match, as long as the text
+ representation of the data can be converted to the target type. For
+ example, you can replicate from a column of type <code class="type">integer</code> to a
+ column of type <code class="type">bigint</code>. The target table can also have
+ additional columns not provided by the published table. Any such columns
+ will be filled with the default value as specified in the definition of the
+ target table.
+ </p><div class="sect2" id="LOGICAL-REPLICATION-SUBSCRIPTION-SLOT"><div class="titlepage"><div><div><h3 class="title">31.2.1. Replication Slot Management</h3></div></div></div><p>
+ As mentioned earlier, each (active) subscription receives changes from a
+ replication slot on the remote (publishing) side.
+ </p><p>
+ Additional table synchronization slots are normally transient, created
+ internally to perform initial table synchronization and dropped
+ automatically when they are no longer needed. These table synchronization
+ slots have generated names: <span class="quote">“<span class="quote"><code class="literal">pg_%u_sync_%u_%llu</code></span>”</span>
+ (parameters: Subscription <em class="parameter"><code>oid</code></em>,
+ Table <em class="parameter"><code>relid</code></em>, system identifier <em class="parameter"><code>sysid</code></em>)
+ </p><p>
+ Normally, the remote replication slot is created automatically when the
+ subscription is created using <code class="command">CREATE SUBSCRIPTION</code> and it
+ is dropped automatically when the subscription is dropped using
+ <code class="command">DROP SUBSCRIPTION</code>. In some situations, however, it can
+ be useful or necessary to manipulate the subscription and the underlying
+ replication slot separately. Here are some scenarios:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ When creating a subscription, the replication slot already exists. In
+ that case, the subscription can be created using
+ the <code class="literal">create_slot = false</code> option to associate with the
+ existing slot.
+ </p></li><li class="listitem"><p>
+ When creating a subscription, the remote host is not reachable or in an
+ unclear state. In that case, the subscription can be created using
+ the <code class="literal">connect = false</code> option. The remote host will then not
+ be contacted at all. This is what <span class="application">pg_dump</span>
+ uses. The remote replication slot will then have to be created
+ manually before the subscription can be activated.
+ </p></li><li class="listitem"><p>
+ When dropping a subscription, the replication slot should be kept.
+ This could be useful when the subscriber database is being moved to a
+ different host and will be activated from there. In that case,
+ disassociate the slot from the subscription using <code class="command">ALTER
+ SUBSCRIPTION</code> before attempting to drop the subscription.
+ </p></li><li class="listitem"><p>
+ When dropping a subscription, the remote host is not reachable. In
+ that case, disassociate the slot from the subscription
+ using <code class="command">ALTER SUBSCRIPTION</code> before attempting to drop
+ the subscription. If the remote database instance no longer exists, no
+ further action is then necessary. If, however, the remote database
+ instance is just unreachable, the replication slot (and any still
+ remaining table synchronization slots) should then be
+ dropped manually; otherwise it/they would continue to reserve WAL and might
+ eventually cause the disk to fill up. Such cases should be carefully
+ investigated.
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES"><div class="titlepage"><div><div><h3 class="title">31.2.2. Examples</h3></div></div></div><p>
+ Create some test tables on the publisher.
+</p><pre class="programlisting">
+test_pub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
+CREATE TABLE
+test_pub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
+CREATE TABLE
+test_pub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
+CREATE TABLE
+</pre><p>
+ Create the same tables on the subscriber.
+</p><pre class="programlisting">
+test_sub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
+CREATE TABLE
+test_sub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
+CREATE TABLE
+test_sub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
+CREATE TABLE
+</pre><p>
+ Insert data to the tables at the publisher side.
+</p><pre class="programlisting">
+test_pub=# INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
+INSERT 0 3
+test_pub=# INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C');
+INSERT 0 3
+test_pub=# INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii');
+INSERT 0 3
+</pre><p>
+ Create publications for the tables. The publications <code class="literal">pub2</code>
+ and <code class="literal">pub3a</code> disallow some <code class="literal">publish</code>
+ operations. The publication <code class="literal">pub3b</code> has a row filter (see
+ <a class="xref" href="logical-replication-row-filter.html" title="31.3. Row Filters">Section 31.3</a>).
+</p><pre class="programlisting">
+test_pub=# CREATE PUBLICATION pub1 FOR TABLE t1;
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate');
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate');
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e &gt; 5);
+CREATE PUBLICATION
+</pre><p>
+ Create subscriptions for the publications. The subscription
+ <code class="literal">sub3</code> subscribes to both <code class="literal">pub3a</code> and
+ <code class="literal">pub3b</code>. All subscriptions will copy initial data by default.
+</p><pre class="programlisting">
+test_sub=# CREATE SUBSCRIPTION sub1
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub1'
+test_sub-# PUBLICATION pub1;
+CREATE SUBSCRIPTION
+test_sub=# CREATE SUBSCRIPTION sub2
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub2'
+test_sub-# PUBLICATION pub2;
+CREATE SUBSCRIPTION
+test_sub=# CREATE SUBSCRIPTION sub3
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub3'
+test_sub-# PUBLICATION pub3a, pub3b;
+CREATE SUBSCRIPTION
+</pre><p>
+ Observe that initial table data is copied, regardless of the
+ <code class="literal">publish</code> operation of the publication.
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1;
+ a | b
+---+-------
+ 1 | one
+ 2 | two
+ 3 | three
+(3 rows)
+
+test_sub=# SELECT * FROM t2;
+ c | d
+---+---
+ 1 | A
+ 2 | B
+ 3 | C
+(3 rows)
+</pre><p>
+ Furthermore, because the initial data copy ignores the <code class="literal">publish</code>
+ operation, and because publication <code class="literal">pub3a</code> has no row filter,
+ it means the copied table <code class="literal">t3</code> contains all rows even when
+ they do not match the row filter of publication <code class="literal">pub3b</code>.
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t3;
+ e | f
+---+-----
+ 1 | i
+ 2 | ii
+ 3 | iii
+(3 rows)
+</pre><p>
+ Insert more data to the tables at the publisher side.
+</p><pre class="programlisting">
+test_pub=# INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six');
+INSERT 0 3
+test_pub=# INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F');
+INSERT 0 3
+test_pub=# INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi');
+INSERT 0 3
+</pre><p>
+ Now the publisher side data looks like:
+</p><pre class="programlisting">
+test_pub=# SELECT * FROM t1;
+ a | b
+---+-------
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+ 5 | five
+ 6 | six
+(6 rows)
+
+test_pub=# SELECT * FROM t2;
+ c | d
+---+---
+ 1 | A
+ 2 | B
+ 3 | C
+ 4 | D
+ 5 | E
+ 6 | F
+(6 rows)
+
+test_pub=# SELECT * FROM t3;
+ e | f
+---+-----
+ 1 | i
+ 2 | ii
+ 3 | iii
+ 4 | iv
+ 5 | v
+ 6 | vi
+(6 rows)
+</pre><p>
+ Observe that during normal replication the appropriate
+ <code class="literal">publish</code> operations are used. This means publications
+ <code class="literal">pub2</code> and <code class="literal">pub3a</code> will not replicate the
+ <code class="literal">INSERT</code>. Also, publication <code class="literal">pub3b</code> will
+ only replicate data that matches the row filter of <code class="literal">pub3b</code>.
+ Now the subscriber side data looks like:
+</p><pre class="programlisting">
+test_sub=# SELECT * FROM t1;
+ a | b
+---+-------
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+ 5 | five
+ 6 | six
+(6 rows)
+
+test_sub=# SELECT * FROM t2;
+ c | d
+---+---
+ 1 | A
+ 2 | B
+ 3 | C
+(3 rows)
+
+test_sub=# SELECT * FROM t3;
+ e | f
+---+-----
+ 1 | i
+ 2 | ii
+ 3 | iii
+ 6 | vi
+(4 rows)
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logical-replication-publication.html" title="31.1. Publication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logical-replication.html" title="Chapter 31. Logical Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-row-filter.html" title="31.3. Row Filters">Next</a></td></tr><tr><td width="40%" align="left" valign="top">31.1. Publication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.3. Row Filters</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logical-replication.html b/doc/src/sgml/html/logical-replication.html
new file mode 100644
index 0000000..30dbb6d
--- /dev/null
+++ b/doc/src/sgml/html/logical-replication.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 31. Logical Replication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="wal-internals.html" title="30.6. WAL Internals" /><link rel="next" href="logical-replication-publication.html" title="31.1. Publication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 31. Logical Replication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="wal-internals.html" title="30.6. WAL Internals">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication-publication.html" title="31.1. Publication">Next</a></td></tr></table><hr /></div><div class="chapter" id="LOGICAL-REPLICATION"><div class="titlepage"><div><div><h2 class="title">Chapter 31. Logical Replication</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="logical-replication-publication.html">31.1. Publication</a></span></dt><dt><span class="sect1"><a href="logical-replication-subscription.html">31.2. Subscription</a></span></dt><dd><dl><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-SLOT">31.2.1. Replication Slot Management</a></span></dt><dt><span class="sect2"><a href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES">31.2.2. Examples</a></span></dt></dl></dd><dt><span class="sect1"><a href="logical-replication-row-filter.html">31.3. Row Filters</a></span></dt><dd><dl><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-RULES">31.3.1. Row Filter Rules</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-RESTRICTIONS">31.3.2. Expression Restrictions</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-TRANSFORMATIONS">31.3.3. UPDATE Transformations</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-PARTITIONED-TABLE">31.3.4. Partitioned Tables</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-INITIAL-DATA-SYNC">31.3.5. Initial Data Synchronization</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-COMBINING">31.3.6. Combining Multiple Row Filters</a></span></dt><dt><span class="sect2"><a href="logical-replication-row-filter.html#LOGICAL-REPLICATION-ROW-FILTER-EXAMPLES">31.3.7. Examples</a></span></dt></dl></dd><dt><span class="sect1"><a href="logical-replication-col-lists.html">31.4. Column Lists</a></span></dt><dd><dl><dt><span class="sect2"><a href="logical-replication-col-lists.html#LOGICAL-REPLICATION-COL-LIST-EXAMPLES">31.4.1. Examples</a></span></dt></dl></dd><dt><span class="sect1"><a href="logical-replication-conflicts.html">31.5. Conflicts</a></span></dt><dt><span class="sect1"><a href="logical-replication-restrictions.html">31.6. Restrictions</a></span></dt><dt><span class="sect1"><a href="logical-replication-architecture.html">31.7. Architecture</a></span></dt><dd><dl><dt><span class="sect2"><a href="logical-replication-architecture.html#LOGICAL-REPLICATION-SNAPSHOT">31.7.1. Initial Snapshot</a></span></dt></dl></dd><dt><span class="sect1"><a href="logical-replication-monitoring.html">31.8. Monitoring</a></span></dt><dt><span class="sect1"><a href="logical-replication-security.html">31.9. Security</a></span></dt><dt><span class="sect1"><a href="logical-replication-config.html">31.10. Configuration Settings</a></span></dt><dt><span class="sect1"><a href="logical-replication-quick-setup.html">31.11. Quick Setup</a></span></dt></dl></div><p>
+ Logical replication is a method of replicating data objects and their
+ changes, based upon their replication identity (usually a primary key). We
+ use the term logical in contrast to physical replication, which uses exact
+ block addresses and byte-by-byte replication. PostgreSQL supports both
+ mechanisms concurrently, see <a class="xref" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Chapter 27</a>. Logical
+ replication allows fine-grained control over both data replication and
+ security.
+ </p><p>
+ Logical replication uses a <em class="firstterm">publish</em>
+ and <em class="firstterm">subscribe</em> model with one or
+ more <em class="firstterm">subscribers</em> subscribing to one or more
+ <em class="firstterm">publications</em> on a <em class="firstterm">publisher</em>
+ node. Subscribers pull data from the publications they subscribe to and may
+ subsequently re-publish data to allow cascading replication or more complex
+ configurations.
+ </p><p>
+ Logical replication of a table typically starts with taking a snapshot
+ of the data on the publisher database and copying that to the subscriber.
+ Once that is done, the changes on the publisher are sent to the subscriber
+ as they occur in real-time. The subscriber applies the data in the same
+ order as the publisher so that transactional consistency is guaranteed for
+ publications within a single subscription. This method of data replication
+ is sometimes referred to as transactional replication.
+ </p><p>
+ The typical use-cases for logical replication are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Sending incremental changes in a single database or a subset of a
+ database to subscribers as they occur.
+ </p></li><li class="listitem"><p>
+ Firing triggers for individual changes as they arrive on the
+ subscriber.
+ </p></li><li class="listitem"><p>
+ Consolidating multiple databases into a single one (for example for
+ analytical purposes).
+ </p></li><li class="listitem"><p>
+ Replicating between different major versions of PostgreSQL.
+ </p></li><li class="listitem"><p>
+ Replicating between PostgreSQL instances on different platforms (for
+ example Linux to Windows)
+ </p></li><li class="listitem"><p>
+ Giving access to replicated data to different groups of users.
+ </p></li><li class="listitem"><p>
+ Sharing a subset of the database between multiple databases.
+ </p></li></ul></div><p>
+ </p><p>
+ The subscriber database behaves in the same way as any other PostgreSQL
+ instance and can be used as a publisher for other databases by defining its
+ own publications. When the subscriber is treated as read-only by
+ application, there will be no conflicts from a single subscription. On the
+ other hand, if there are other writes done either by an application or by other
+ subscribers to the same set of tables, conflicts can arise.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="wal-internals.html" title="30.6. WAL Internals">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication-publication.html" title="31.1. Publication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">30.6. WAL Internals </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 31.1. Publication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-catalogs.html b/doc/src/sgml/html/logicaldecoding-catalogs.html
new file mode 100644
index 0000000..dfe3d8e
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-catalogs.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.5. System Catalogs Related to Logical Decoding</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface" /><link rel="next" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.5. System Catalogs Related to Logical Decoding</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-CATALOGS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.5. System Catalogs Related to Logical Decoding</h2></div></div></div><p>
+ The <a class="link" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots"><code class="structname">pg_replication_slots</code></a>
+ view and the
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW" title="28.2.4. pg_stat_replication">
+ <code class="structname">pg_stat_replication</code></a>
+ view provide information about the current state of replication slots and
+ streaming replication connections respectively. These views apply to both physical and
+ logical replication. The
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-SLOTS-VIEW" title="28.2.5. pg_stat_replication_slots">
+ <code class="structname">pg_stat_replication_slots</code></a>
+ view provides statistics information about the logical replication slots.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.4. Logical Decoding <acronym class="acronym">SQL</acronym> Interface </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.6. Logical Decoding Output Plugins</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-example.html b/doc/src/sgml/html/logicaldecoding-example.html
new file mode 100644
index 0000000..1b826d9
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-example.html
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.1. Logical Decoding Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding.html" title="Chapter 49. Logical Decoding" /><link rel="next" href="logicaldecoding-explanation.html" title="49.2. Logical Decoding Concepts" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.1. Logical Decoding Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-explanation.html" title="49.2. Logical Decoding Concepts">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.1. Logical Decoding Examples</h2></div></div></div><p>
+ The following example demonstrates controlling logical decoding using the
+ SQL interface.
+ </p><p>
+ Before you can use logical decoding, you must set
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-LEVEL">wal_level</a> to <code class="literal">logical</code> and
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-REPLICATION-SLOTS">max_replication_slots</a> to at least 1. Then, you
+ should connect to the target database (in the example
+ below, <code class="literal">postgres</code>) as a superuser.
+ </p><pre class="programlisting">
+postgres=# -- Create a slot named 'regression_slot' using the output plugin 'test_decoding'
+postgres=# SELECT * FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
+ slot_name | lsn
+-----------------+-----------
+ regression_slot | 0/16B1970
+(1 row)
+
+postgres=# SELECT slot_name, plugin, slot_type, database, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots;
+ slot_name | plugin | slot_type | database | active | restart_lsn | confirmed_flush_lsn
+-----------------+---------------+-----------+----------+--------+-------------+-----------------
+ regression_slot | test_decoding | logical | postgres | f | 0/16A4408 | 0/16A4440
+(1 row)
+
+postgres=# -- There are no changes to see yet
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----+-----+------
+(0 rows)
+
+postgres=# CREATE TABLE data(id serial primary key, data text);
+CREATE TABLE
+
+postgres=# -- DDL isn't replicated, so all you'll see is the transaction
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+--------------
+ 0/BA2DA58 | 10297 | BEGIN 10297
+ 0/BA5A5A0 | 10297 | COMMIT 10297
+(2 rows)
+
+postgres=# -- Once changes are read, they're consumed and not emitted
+postgres=# -- in a subsequent call:
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----+-----+------
+(0 rows)
+
+postgres=# BEGIN;
+postgres=*# INSERT INTO data(data) VALUES('1');
+postgres=*# INSERT INTO data(data) VALUES('2');
+postgres=*# COMMIT;
+
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A688 | 10298 | BEGIN 10298
+ 0/BA5A6F0 | 10298 | table public.data: INSERT: id[integer]:1 data[text]:'1'
+ 0/BA5A7F8 | 10298 | table public.data: INSERT: id[integer]:2 data[text]:'2'
+ 0/BA5A8A8 | 10298 | COMMIT 10298
+(4 rows)
+
+postgres=# INSERT INTO data(data) VALUES('3');
+
+postgres=# -- You can also peek ahead in the change stream without consuming changes
+postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A8E0 | 10299 | BEGIN 10299
+ 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3'
+ 0/BA5A990 | 10299 | COMMIT 10299
+(3 rows)
+
+postgres=# -- The next call to pg_logical_slot_peek_changes() returns the same changes again
+postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A8E0 | 10299 | BEGIN 10299
+ 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3'
+ 0/BA5A990 | 10299 | COMMIT 10299
+(3 rows)
+
+postgres=# -- options can be passed to output plugin, to influence the formatting
+postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-timestamp', 'on');
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A8E0 | 10299 | BEGIN 10299
+ 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3'
+ 0/BA5A990 | 10299 | COMMIT 10299 (at 2017-05-10 12:07:21.272494-04)
+(3 rows)
+
+postgres=# -- Remember to destroy a slot you no longer need to stop it consuming
+postgres=# -- server resources:
+postgres=# SELECT pg_drop_replication_slot('regression_slot');
+ pg_drop_replication_slot
+-----------------------
+
+(1 row)
+</pre><p>
+ The following examples shows how logical decoding is controlled over the
+ streaming replication protocol, using the
+ program <a class="xref" href="app-pgrecvlogical.html" title="pg_recvlogical"><span class="refentrytitle"><span class="application">pg_recvlogical</span></span></a> included in the PostgreSQL
+ distribution. This requires that client authentication is set up to allow
+ replication connections
+ (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-AUTHENTICATION" title="27.2.5.1. Authentication">Section 27.2.5.1</a>) and
+ that <code class="varname">max_wal_senders</code> is set sufficiently high to allow
+ an additional connection. The second example shows how to stream two-phase
+ transactions. Before you use two-phase commands, you must set
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS">max_prepared_transactions</a> to at least 1.
+ </p><pre class="programlisting">
+Example 1:
+$ pg_recvlogical -d postgres --slot=test --create-slot
+$ pg_recvlogical -d postgres --slot=test --start -f -
+<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>Z</strong></span>
+$ psql -d postgres -c "INSERT INTO data(data) VALUES('4');"
+$ fg
+BEGIN 693
+table public.data: INSERT: id[integer]:4 data[text]:'4'
+COMMIT 693
+<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>C</strong></span>
+$ pg_recvlogical -d postgres --slot=test --drop-slot
+
+Example 2:
+$ pg_recvlogical -d postgres --slot=test --create-slot --two-phase
+$ pg_recvlogical -d postgres --slot=test --start -f -
+<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>Z</strong></span>
+$ psql -d postgres -c "BEGIN;INSERT INTO data(data) VALUES('5');PREPARE TRANSACTION 'test';"
+$ fg
+BEGIN 694
+table public.data: INSERT: id[integer]:5 data[text]:'5'
+PREPARE TRANSACTION 'test', txid 694
+<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>Z</strong></span>
+$ psql -d postgres -c "COMMIT PREPARED 'test';"
+$ fg
+COMMIT PREPARED 'test', txid 694
+<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>C</strong></span>
+$ pg_recvlogical -d postgres --slot=test --drop-slot
+</pre><p>
+ The following example shows SQL interface that can be used to decode prepared
+ transactions. Before you use two-phase commit commands, you must set
+ <code class="varname">max_prepared_transactions</code> to at least 1. You must also have
+ set the two-phase parameter as 'true' while creating the slot using
+ <code class="function">pg_create_logical_replication_slot</code>
+ Note that we will stream the entire transaction after the commit if it
+ is not already decoded.
+ </p><pre class="programlisting">
+postgres=# BEGIN;
+postgres=*# INSERT INTO data(data) VALUES('5');
+postgres=*# PREPARE TRANSACTION 'test_prepared1';
+
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+---------------------------------------------------------
+ 0/1689DC0 | 529 | BEGIN 529
+ 0/1689DC0 | 529 | table public.data: INSERT: id[integer]:3 data[text]:'5'
+ 0/1689FC0 | 529 | PREPARE TRANSACTION 'test_prepared1', txid 529
+(3 rows)
+
+postgres=# COMMIT PREPARED 'test_prepared1';
+postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+--------------------------------------------
+ 0/168A060 | 529 | COMMIT PREPARED 'test_prepared1', txid 529
+(4 row)
+
+postgres=#-- you can also rollback a prepared transaction
+postgres=# BEGIN;
+postgres=*# INSERT INTO data(data) VALUES('6');
+postgres=*# PREPARE TRANSACTION 'test_prepared2';
+postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+---------------------------------------------------------
+ 0/168A180 | 530 | BEGIN 530
+ 0/168A1E8 | 530 | table public.data: INSERT: id[integer]:4 data[text]:'6'
+ 0/168A430 | 530 | PREPARE TRANSACTION 'test_prepared2', txid 530
+(3 rows)
+
+postgres=# ROLLBACK PREPARED 'test_prepared2';
+postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+----------------------------------------------
+ 0/168A4B8 | 530 | ROLLBACK PREPARED 'test_prepared2', txid 530
+(1 row)
+</pre></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-explanation.html" title="49.2. Logical Decoding Concepts">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 49. Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.2. Logical Decoding Concepts</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-explanation.html b/doc/src/sgml/html/logicaldecoding-explanation.html
new file mode 100644
index 0000000..05d0239
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-explanation.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.2. Logical Decoding Concepts</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples" /><link rel="next" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.2. Logical Decoding Concepts</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-EXPLANATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.2. Logical Decoding Concepts</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logicaldecoding-explanation.html#id-1.8.14.8.2">49.2.1. Logical Decoding</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-explanation.html#LOGICALDECODING-REPLICATION-SLOTS">49.2.2. Replication Slots</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-explanation.html#id-1.8.14.8.4">49.2.3. Output Plugins</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-explanation.html#id-1.8.14.8.5">49.2.4. Exported Snapshots</a></span></dt></dl></div><div class="sect2" id="id-1.8.14.8.2"><div class="titlepage"><div><div><h3 class="title">49.2.1. Logical Decoding</h3></div></div></div><a id="id-1.8.14.8.2.2" class="indexterm"></a><p>
+ Logical decoding is the process of extracting all persistent changes
+ to a database's tables into a coherent, easy to understand format which
+ can be interpreted without detailed knowledge of the database's internal
+ state.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, logical decoding is implemented
+ by decoding the contents of the <a class="link" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">write-ahead
+ log</a>, which describe changes on a storage level, into an
+ application-specific form such as a stream of tuples or SQL statements.
+ </p></div><div class="sect2" id="LOGICALDECODING-REPLICATION-SLOTS"><div class="titlepage"><div><div><h3 class="title">49.2.2. Replication Slots</h3></div></div></div><a id="id-1.8.14.8.3.2" class="indexterm"></a><p>
+ In the context of logical replication, a slot represents a stream of
+ changes that can be replayed to a client in the order they were made on
+ the origin server. Each slot streams a sequence of changes from a single
+ database.
+ </p><div class="note"><h3 class="title">Note</h3><p><span class="productname">PostgreSQL</span> also has streaming replication slots
+ (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>), but they are used somewhat
+ differently there.
+ </p></div><p>
+ A replication slot has an identifier that is unique across all databases
+ in a <span class="productname">PostgreSQL</span> cluster. Slots persist
+ independently of the connection using them and are crash-safe.
+ </p><p>
+ A logical slot will emit each change just once in normal operation.
+ The current position of each slot is persisted only at checkpoint, so in
+ the case of a crash the slot may return to an earlier LSN, which will
+ then cause recent changes to be sent again when the server restarts.
+ Logical decoding clients are responsible for avoiding ill effects from
+ handling the same message more than once. Clients may wish to record
+ the last LSN they saw when decoding and skip over any repeated data or
+ (when using the replication protocol) request that decoding start from
+ that LSN rather than letting the server determine the start point.
+ The Replication Progress Tracking feature is designed for this purpose,
+ refer to <a class="link" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">replication origins</a>.
+ </p><p>
+ Multiple independent slots may exist for a single database. Each slot has
+ its own state, allowing different consumers to receive changes from
+ different points in the database change stream. For most applications, a
+ separate slot will be required for each consumer.
+ </p><p>
+ A logical replication slot knows nothing about the state of the
+ receiver(s). It's even possible to have multiple different receivers using
+ the same slot at different times; they'll just get the changes following
+ on from when the last receiver stopped consuming them. Only one receiver
+ may consume changes from a slot at any given time.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ Replication slots persist across crashes and know nothing about the state
+ of their consumer(s). They will prevent removal of required resources
+ even when there is no connection using them. This consumes storage
+ because neither required WAL nor required rows from the system catalogs
+ can be removed by <code class="command">VACUUM</code> as long as they are required by a replication
+ slot. In extreme cases this could cause the database to shut down to prevent
+ transaction ID wraparound (see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>).
+ So if a slot is no longer required it should be dropped.
+ </p></div></div><div class="sect2" id="id-1.8.14.8.4"><div class="titlepage"><div><div><h3 class="title">49.2.3. Output Plugins</h3></div></div></div><p>
+ Output plugins transform the data from the write-ahead log's internal
+ representation into the format the consumer of a replication slot desires.
+ </p></div><div class="sect2" id="id-1.8.14.8.5"><div class="titlepage"><div><div><h3 class="title">49.2.4. Exported Snapshots</h3></div></div></div><p>
+ When a new replication slot is created using the streaming replication
+ interface (see <a class="xref" href="protocol-replication.html#PROTOCOL-REPLICATION-CREATE-REPLICATION-SLOT">CREATE_REPLICATION_SLOT</a>), a
+ snapshot is exported
+ (see <a class="xref" href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION" title="9.27.5. Snapshot Synchronization Functions">Section 9.27.5</a>), which will show
+ exactly the state of the database after which all changes will be
+ included in the change stream. This can be used to create a new replica by
+ using <a class="link" href="sql-set-transaction.html" title="SET TRANSACTION"><code class="literal">SET TRANSACTION
+ SNAPSHOT</code></a> to read the state of the database at the moment
+ the slot was created. This transaction can then be used to dump the
+ database's state at that point in time, which afterwards can be updated
+ using the slot's contents without losing any changes.
+ </p><p>
+ Creation of a snapshot is not always possible. In particular, it will
+ fail when connected to a hot standby. Applications that do not require
+ snapshot export may suppress it with the <code class="literal">NOEXPORT_SNAPSHOT</code>
+ option.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.1. Logical Decoding Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.3. Streaming Replication Protocol Interface</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-output-plugin.html b/doc/src/sgml/html/logicaldecoding-output-plugin.html
new file mode 100644
index 0000000..992b338
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-output-plugin.html
@@ -0,0 +1,471 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.6. Logical Decoding Output Plugins</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding" /><link rel="next" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.6. Logical Decoding Output Plugins</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-OUTPUT-PLUGIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.6. Logical Decoding Output Plugins</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-INIT">49.6.1. Initialization Function</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-CAPABILITIES">49.6.2. Capabilities</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE">49.6.3. Output Modes</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS">49.6.4. Output Plugin Callbacks</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT">49.6.5. Functions for Producing Output</a></span></dt></dl></div><p>
+ An example output plugin can be found in the
+ <a class="link" href="test-decoding.html" title="F.45. test_decoding">
+ <code class="filename">contrib/test_decoding</code>
+ </a>
+ subdirectory of the PostgreSQL source tree.
+ </p><div class="sect2" id="LOGICALDECODING-OUTPUT-INIT"><div class="titlepage"><div><div><h3 class="title">49.6.1. Initialization Function</h3></div></div></div><a id="id-1.8.14.12.3.2" class="indexterm"></a><p>
+ An output plugin is loaded by dynamically loading a shared library with
+ the output plugin's name as the library base name. The normal library
+ search path is used to locate the library. To provide the required output
+ plugin callbacks and to indicate that the library is actually an output
+ plugin it needs to provide a function named
+ <code class="function">_PG_output_plugin_init</code>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions.
+</p><pre class="programlisting">
+typedef struct OutputPluginCallbacks
+{
+ LogicalDecodeStartupCB startup_cb;
+ LogicalDecodeBeginCB begin_cb;
+ LogicalDecodeChangeCB change_cb;
+ LogicalDecodeTruncateCB truncate_cb;
+ LogicalDecodeCommitCB commit_cb;
+ LogicalDecodeMessageCB message_cb;
+ LogicalDecodeFilterByOriginCB filter_by_origin_cb;
+ LogicalDecodeShutdownCB shutdown_cb;
+ LogicalDecodeFilterPrepareCB filter_prepare_cb;
+ LogicalDecodeBeginPrepareCB begin_prepare_cb;
+ LogicalDecodePrepareCB prepare_cb;
+ LogicalDecodeCommitPreparedCB commit_prepared_cb;
+ LogicalDecodeRollbackPreparedCB rollback_prepared_cb;
+ LogicalDecodeStreamStartCB stream_start_cb;
+ LogicalDecodeStreamStopCB stream_stop_cb;
+ LogicalDecodeStreamAbortCB stream_abort_cb;
+ LogicalDecodeStreamPrepareCB stream_prepare_cb;
+ LogicalDecodeStreamCommitCB stream_commit_cb;
+ LogicalDecodeStreamChangeCB stream_change_cb;
+ LogicalDecodeStreamMessageCB stream_message_cb;
+ LogicalDecodeStreamTruncateCB stream_truncate_cb;
+} OutputPluginCallbacks;
+
+typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb);
+</pre><p>
+ The <code class="function">begin_cb</code>, <code class="function">change_cb</code>
+ and <code class="function">commit_cb</code> callbacks are required,
+ while <code class="function">startup_cb</code>,
+ <code class="function">filter_by_origin_cb</code>, <code class="function">truncate_cb</code>,
+ and <code class="function">shutdown_cb</code> are optional.
+ If <code class="function">truncate_cb</code> is not set but a
+ <code class="command">TRUNCATE</code> is to be decoded, the action will be ignored.
+ </p><p>
+ An output plugin may also define functions to support streaming of large,
+ in-progress transactions. The <code class="function">stream_start_cb</code>,
+ <code class="function">stream_stop_cb</code>, <code class="function">stream_abort_cb</code>,
+ <code class="function">stream_commit_cb</code>, <code class="function">stream_change_cb</code>,
+ and <code class="function">stream_prepare_cb</code>
+ are required, while <code class="function">stream_message_cb</code> and
+ <code class="function">stream_truncate_cb</code> are optional.
+ </p><p>
+ An output plugin may also define functions to support two-phase commits,
+ which allows actions to be decoded on the <code class="command">PREPARE TRANSACTION</code>.
+ The <code class="function">begin_prepare_cb</code>, <code class="function">prepare_cb</code>,
+ <code class="function">stream_prepare_cb</code>,
+ <code class="function">commit_prepared_cb</code> and <code class="function">rollback_prepared_cb</code>
+ callbacks are required, while <code class="function">filter_prepare_cb</code> is optional.
+ </p></div><div class="sect2" id="LOGICALDECODING-CAPABILITIES"><div class="titlepage"><div><div><h3 class="title">49.6.2. Capabilities</h3></div></div></div><p>
+ To decode, format and output changes, output plugins can use most of the
+ backend's normal infrastructure, including calling output functions. Read
+ only access to relations is permitted as long as only relations are
+ accessed that either have been created by <code class="command">initdb</code> in
+ the <code class="literal">pg_catalog</code> schema, or have been marked as user
+ provided catalog tables using
+</p><pre class="programlisting">
+ALTER TABLE user_catalog_table SET (user_catalog_table = true);
+CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
+</pre><p>
+ Note that access to user catalog tables or regular system catalog tables
+ in the output plugins has to be done via the <code class="literal">systable_*</code>
+ scan APIs only. Access via the <code class="literal">heap_*</code> scan APIs will
+ error out. Additionally, any actions leading to transaction ID assignment
+ are prohibited. That, among others, includes writing to tables, performing
+ DDL changes, and calling <code class="literal">pg_current_xact_id()</code>.
+ </p></div><div class="sect2" id="LOGICALDECODING-OUTPUT-MODE"><div class="titlepage"><div><div><h3 class="title">49.6.3. Output Modes</h3></div></div></div><p>
+ Output plugin callbacks can pass data to the consumer in nearly arbitrary
+ formats. For some use cases, like viewing the changes via SQL, returning
+ data in a data type that can contain arbitrary data (e.g., <code class="type">bytea</code>) is
+ cumbersome. If the output plugin only outputs textual data in the
+ server's encoding, it can declare that by
+ setting <code class="literal">OutputPluginOptions.output_type</code>
+ to <code class="literal">OUTPUT_PLUGIN_TEXTUAL_OUTPUT</code> instead
+ of <code class="literal">OUTPUT_PLUGIN_BINARY_OUTPUT</code> in
+ the <a class="link" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-STARTUP" title="49.6.4.1. Startup Callback">startup
+ callback</a>. In that case, all the data has to be in the server's encoding
+ so that a <code class="type">text</code> datum can contain it. This is checked in assertion-enabled
+ builds.
+ </p></div><div class="sect2" id="LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS"><div class="titlepage"><div><div><h3 class="title">49.6.4. Output Plugin Callbacks</h3></div></div></div><p>
+ An output plugin gets notified about changes that are happening via
+ various callbacks it needs to provide.
+ </p><p>
+ Concurrent transactions are decoded in commit order, and only changes
+ belonging to a specific transaction are decoded between
+ the <code class="literal">begin</code> and <code class="literal">commit</code>
+ callbacks. Transactions that were rolled back explicitly or implicitly
+ never get
+ decoded. Successful savepoints are
+ folded into the transaction containing them in the order they were
+ executed within that transaction. A transaction that is prepared for
+ a two-phase commit using <code class="command">PREPARE TRANSACTION</code> will
+ also be decoded if the output plugin callbacks needed for decoding
+ them are provided. It is possible that the current prepared transaction
+ which is being decoded is aborted concurrently via a
+ <code class="command">ROLLBACK PREPARED</code> command. In that case, the logical
+ decoding of this transaction will be aborted too. All the changes of such
+ a transaction are skipped once the abort is detected and the
+ <code class="function">prepare_cb</code> callback is invoked. Thus even in case of
+ a concurrent abort, enough information is provided to the output plugin
+ for it to properly deal with <code class="command">ROLLBACK PREPARED</code> once
+ that is decoded.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Only transactions that have already safely been flushed to disk will be
+ decoded. That can lead to a <code class="command">COMMIT</code> not immediately being decoded in a
+ directly following <code class="literal">pg_logical_slot_get_changes()</code>
+ when <code class="varname">synchronous_commit</code> is set
+ to <code class="literal">off</code>.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STARTUP"><div class="titlepage"><div><div><h4 class="title">49.6.4.1. Startup Callback</h4></div></div></div><p>
+ The optional <code class="function">startup_cb</code> callback is called whenever
+ a replication slot is created or asked to stream changes, independent
+ of the number of changes that are ready to be put out.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx,
+ OutputPluginOptions *options,
+ bool is_init);
+</pre><p>
+ The <code class="literal">is_init</code> parameter will be true when the
+ replication slot is being created and false
+ otherwise. <em class="parameter"><code>options</code></em> points to a struct of options
+ that output plugins can set:
+</p><pre class="programlisting">
+typedef struct OutputPluginOptions
+{
+ OutputPluginOutputType output_type;
+ bool receive_rewrites;
+} OutputPluginOptions;
+</pre><p>
+ <code class="literal">output_type</code> has to either be set to
+ <code class="literal">OUTPUT_PLUGIN_TEXTUAL_OUTPUT</code>
+ or <code class="literal">OUTPUT_PLUGIN_BINARY_OUTPUT</code>. See also
+ <a class="xref" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE" title="49.6.3. Output Modes">Section 49.6.3</a>.
+ If <code class="literal">receive_rewrites</code> is true, the output plugin will
+ also be called for changes made by heap rewrites during certain DDL
+ operations. These are of interest to plugins that handle DDL
+ replication, but they require special handling.
+ </p><p>
+ The startup callback should validate the options present in
+ <code class="literal">ctx-&gt;output_plugin_options</code>. If the output plugin
+ needs to have a state, it can
+ use <code class="literal">ctx-&gt;output_plugin_private</code> to store it.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-SHUTDOWN"><div class="titlepage"><div><div><h4 class="title">49.6.4.2. Shutdown Callback</h4></div></div></div><p>
+ The optional <code class="function">shutdown_cb</code> callback is called
+ whenever a formerly active replication slot is not used anymore and can
+ be used to deallocate resources private to the output plugin. The slot
+ isn't necessarily being dropped, streaming is just being stopped.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-BEGIN"><div class="titlepage"><div><div><h4 class="title">49.6.4.3. Transaction Begin Callback</h4></div></div></div><p>
+ The required <code class="function">begin_cb</code> callback is called whenever a
+ start of a committed transaction has been decoded. Aborted transactions
+ and their contents never get decoded.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ The <em class="parameter"><code>txn</code></em> parameter contains meta information about
+ the transaction, like the time stamp at which it has been committed and
+ its XID.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-COMMIT"><div class="titlepage"><div><div><h4 class="title">49.6.4.4. Transaction End Callback</h4></div></div></div><p>
+ The required <code class="function">commit_cb</code> callback is called whenever
+ a transaction commit has been
+ decoded. The <code class="function">change_cb</code> callbacks for all modified
+ rows will have been called before this, if there have been any modified
+ rows.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-CHANGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.5. Change Callback</h4></div></div></div><p>
+ The required <code class="function">change_cb</code> callback is called for every
+ individual row modification inside a transaction, may it be
+ an <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ or <code class="command">DELETE</code>. Even if the original command modified
+ several rows at once the callback will be called individually for each
+ row. The <code class="function">change_cb</code> callback may access system or
+ user catalog tables to aid in the process of outputting the row
+ modification details. In case of decoding a prepared (but yet
+ uncommitted) transaction or decoding of an uncommitted transaction, this
+ change callback might also error out due to simultaneous rollback of
+ this very same transaction. In that case, the logical decoding of this
+ aborted transaction is stopped gracefully.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ Relation relation,
+ ReorderBufferChange *change);
+</pre><p>
+ The <em class="parameter"><code>ctx</code></em> and <em class="parameter"><code>txn</code></em> parameters
+ have the same contents as for the <code class="function">begin_cb</code>
+ and <code class="function">commit_cb</code> callbacks, but additionally the
+ relation descriptor <em class="parameter"><code>relation</code></em> points to the
+ relation the row belongs to and a struct
+ <em class="parameter"><code>change</code></em> describing the row modification are passed
+ in.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Only changes in user defined tables that are not unlogged
+ (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-UNLOGGED"><code class="literal">UNLOGGED</code></a>) and not temporary
+ (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-TEMPORARY"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></a>) can be extracted using
+ logical decoding.
+ </p></div></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-TRUNCATE"><div class="titlepage"><div><div><h4 class="title">49.6.4.6. Truncate Callback</h4></div></div></div><p>
+ The <code class="function">truncate_cb</code> callback is called for a
+ <code class="command">TRUNCATE</code> command.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ int nrelations,
+ Relation relations[],
+ ReorderBufferChange *change);
+</pre><p>
+ The parameters are analogous to the <code class="function">change_cb</code>
+ callback. However, because <code class="command">TRUNCATE</code> actions on
+ tables connected by foreign keys need to be executed together, this
+ callback receives an array of relations instead of just a single one.
+ See the description of the <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> statement for
+ details.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-FILTER-ORIGIN"><div class="titlepage"><div><div><h4 class="title">49.6.4.7. Origin Filter Callback</h4></div></div></div><p>
+ The optional <code class="function">filter_by_origin_cb</code> callback
+ is called to determine whether data that has been replayed
+ from <em class="parameter"><code>origin_id</code></em> is of interest to the
+ output plugin.
+</p><pre class="programlisting">
+typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx,
+ RepOriginId origin_id);
+</pre><p>
+ The <em class="parameter"><code>ctx</code></em> parameter has the same contents
+ as for the other callbacks. No information but the origin is
+ available. To signal that changes originating on the passed in
+ node are irrelevant, return true, causing them to be filtered
+ away; false otherwise. The other callbacks will not be called
+ for transactions and changes that have been filtered away.
+ </p><p>
+ This is useful when implementing cascading or multidirectional
+ replication solutions. Filtering by the origin allows to
+ prevent replicating the same changes back and forth in such
+ setups. While transactions and changes also carry information
+ about the origin, filtering via this callback is noticeably
+ more efficient.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-MESSAGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.8. Generic Message Callback</h4></div></div></div><p>
+ The optional <code class="function">message_cb</code> callback is called whenever
+ a logical decoding message has been decoded.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr message_lsn,
+ bool transactional,
+ const char *prefix,
+ Size message_size,
+ const char *message);
+</pre><p>
+ The <em class="parameter"><code>txn</code></em> parameter contains meta information about
+ the transaction, like the time stamp at which it has been committed and
+ its XID. Note however that it can be NULL when the message is
+ non-transactional and the XID was not assigned yet in the transaction
+ which logged the message. The <em class="parameter"><code>lsn</code></em> has WAL
+ location of the message. The <em class="parameter"><code>transactional</code></em> says
+ if the message was sent as transactional or not. Similar to the change
+ callback, in case of decoding a prepared (but yet uncommitted)
+ transaction or decoding of an uncommitted transaction, this message
+ callback might also error out due to simultaneous rollback of
+ this very same transaction. In that case, the logical decoding of this
+ aborted transaction is stopped gracefully.
+
+ The <em class="parameter"><code>prefix</code></em> is arbitrary null-terminated prefix
+ which can be used for identifying interesting messages for the current
+ plugin. And finally the <em class="parameter"><code>message</code></em> parameter holds
+ the actual message of <em class="parameter"><code>message_size</code></em> size.
+ </p><p>
+ Extra care should be taken to ensure that the prefix the output plugin
+ considers interesting is unique. Using name of the extension or the
+ output plugin itself is often a good choice.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-FILTER-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.9. Prepare Filter Callback</h4></div></div></div><p>
+ The optional <code class="function">filter_prepare_cb</code> callback
+ is called to determine whether data that is part of the current
+ two-phase commit transaction should be considered for decoding
+ at this prepare stage or later as a regular one-phase transaction at
+ <code class="command">COMMIT PREPARED</code> time. To signal that
+ decoding should be skipped, return <code class="literal">true</code>;
+ <code class="literal">false</code> otherwise. When the callback is not
+ defined, <code class="literal">false</code> is assumed (i.e. no filtering, all
+ transactions using two-phase commit are decoded in two phases as well).
+</p><pre class="programlisting">
+typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx,
+ TransactionId xid,
+ const char *gid);
+</pre><p>
+ The <em class="parameter"><code>ctx</code></em> parameter has the same contents as for
+ the other callbacks. The parameters <em class="parameter"><code>xid</code></em>
+ and <em class="parameter"><code>gid</code></em> provide two different ways to identify
+ the transaction. The later <code class="command">COMMIT PREPARED</code> or
+ <code class="command">ROLLBACK PREPARED</code> carries both identifiers,
+ providing an output plugin the choice of what to use.
+ </p><p>
+ The callback may be invoked multiple times per transaction to decode
+ and must provide the same static answer for a given pair of
+ <em class="parameter"><code>xid</code></em> and <em class="parameter"><code>gid</code></em> every time
+ it is called.
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-BEGIN-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.10. Transaction Begin Prepare Callback</h4></div></div></div><p>
+ The required <code class="function">begin_prepare_cb</code> callback is called
+ whenever the start of a prepared transaction has been decoded. The
+ <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback to
+ check if the plugin has already received this <code class="command">PREPARE</code>
+ in which case it can either error out or skip the remaining changes of
+ the transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.11. Transaction Prepare Callback</h4></div></div></div><p>
+ The required <code class="function">prepare_cb</code> callback is called whenever
+ a transaction which is prepared for two-phase commit has been
+ decoded. The <code class="function">change_cb</code> callback for all modified
+ rows will have been called before this, if there have been any modified
+ rows. The <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-COMMIT-PREPARED"><div class="titlepage"><div><div><h4 class="title">49.6.4.12. Transaction Commit Prepared Callback</h4></div></div></div><p>
+ The required <code class="function">commit_prepared_cb</code> callback is called
+ whenever a transaction <code class="command">COMMIT PREPARED</code> has been decoded.
+ The <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-ROLLBACK-PREPARED"><div class="titlepage"><div><div><h4 class="title">49.6.4.13. Transaction Rollback Prepared Callback</h4></div></div></div><p>
+ The required <code class="function">rollback_prepared_cb</code> callback is called
+ whenever a transaction <code class="command">ROLLBACK PREPARED</code> has been
+ decoded. The <em class="parameter"><code>gid</code></em> field, which is part of the
+ <em class="parameter"><code>txn</code></em> parameter, can be used in this callback. The
+ parameters <em class="parameter"><code>prepare_end_lsn</code></em> and
+ <em class="parameter"><code>prepare_time</code></em> can be used to check if the plugin
+ has received this <code class="command">PREPARE TRANSACTION</code> in which case
+ it can apply the rollback, otherwise, it can skip the rollback operation. The
+ <em class="parameter"><code>gid</code></em> alone is not sufficient because the downstream
+ node can have a prepared transaction with same identifier.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_end_lsn,
+ TimestampTz prepare_time);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-START"><div class="titlepage"><div><div><h4 class="title">49.6.4.14. Stream Start Callback</h4></div></div></div><p>
+ The <code class="function">stream_start_cb</code> callback is called when opening
+ a block of streamed changes from an in-progress transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-STOP"><div class="titlepage"><div><div><h4 class="title">49.6.4.15. Stream Stop Callback</h4></div></div></div><p>
+ The <code class="function">stream_stop_cb</code> callback is called when closing
+ a block of streamed changes from an in-progress transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-ABORT"><div class="titlepage"><div><div><h4 class="title">49.6.4.16. Stream Abort Callback</h4></div></div></div><p>
+ The <code class="function">stream_abort_cb</code> callback is called to abort
+ a previously streamed transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr abort_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-PREPARE"><div class="titlepage"><div><div><h4 class="title">49.6.4.17. Stream Prepare Callback</h4></div></div></div><p>
+ The <code class="function">stream_prepare_cb</code> callback is called to prepare
+ a previously streamed transaction as part of a two-phase commit.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-COMMIT"><div class="titlepage"><div><div><h4 class="title">49.6.4.18. Stream Commit Callback</h4></div></div></div><p>
+ The <code class="function">stream_commit_cb</code> callback is called to commit
+ a previously streamed transaction.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-CHANGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.19. Stream Change Callback</h4></div></div></div><p>
+ The <code class="function">stream_change_cb</code> callback is called when sending
+ a change in a block of streamed changes (demarcated by
+ <code class="function">stream_start_cb</code> and <code class="function">stream_stop_cb</code> calls).
+ The actual changes are not displayed as the transaction can abort at a later
+ point in time and we don't decode changes for aborted transactions.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ Relation relation,
+ ReorderBufferChange *change);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-MESSAGE"><div class="titlepage"><div><div><h4 class="title">49.6.4.20. Stream Message Callback</h4></div></div></div><p>
+ The <code class="function">stream_message_cb</code> callback is called when sending
+ a generic message in a block of streamed changes (demarcated by
+ <code class="function">stream_start_cb</code> and <code class="function">stream_stop_cb</code> calls).
+ The message contents for transactional messages are not displayed as the transaction
+ can abort at a later point in time and we don't decode changes for aborted
+ transactions.
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr message_lsn,
+ bool transactional,
+ const char *prefix,
+ Size message_size,
+ const char *message);
+</pre><p>
+ </p></div><div class="sect3" id="LOGICALDECODING-OUTPUT-PLUGIN-STREAM-TRUNCATE"><div class="titlepage"><div><div><h4 class="title">49.6.4.21. Stream Truncate Callback</h4></div></div></div><p>
+ The <code class="function">stream_truncate_cb</code> callback is called for a
+ <code class="command">TRUNCATE</code> command in a block of streamed changes
+ (demarcated by <code class="function">stream_start_cb</code> and
+ <code class="function">stream_stop_cb</code> calls).
+</p><pre class="programlisting">
+typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ int nrelations,
+ Relation relations[],
+ ReorderBufferChange *change);
+</pre><p>
+ The parameters are analogous to the <code class="function">stream_change_cb</code>
+ callback. However, because <code class="command">TRUNCATE</code> actions on
+ tables connected by foreign keys need to be executed together, this
+ callback receives an array of relations instead of just a single one.
+ See the description of the <a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a> statement for
+ details.
+ </p></div></div><div class="sect2" id="LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT"><div class="titlepage"><div><div><h3 class="title">49.6.5. Functions for Producing Output</h3></div></div></div><p>
+ To actually produce output, output plugins can write data to
+ the <code class="literal">StringInfo</code> output buffer
+ in <code class="literal">ctx-&gt;out</code> when inside
+ the <code class="function">begin_cb</code>, <code class="function">commit_cb</code>,
+ or <code class="function">change_cb</code> callbacks. Before writing to the output
+ buffer, <code class="function">OutputPluginPrepareWrite(ctx, last_write)</code> has
+ to be called, and after finishing writing to the
+ buffer, <code class="function">OutputPluginWrite(ctx, last_write)</code> has to be
+ called to perform the write. The <em class="parameter"><code>last_write</code></em>
+ indicates whether a particular write was the callback's last write.
+ </p><p>
+ The following example shows how to output data to the consumer of an
+ output plugin:
+</p><pre class="programlisting">
+OutputPluginPrepareWrite(ctx, true);
+appendStringInfo(ctx-&gt;out, "BEGIN %u", txn-&gt;xid);
+OutputPluginWrite(ctx, true);
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.5. System Catalogs Related to Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.7. Logical Decoding Output Writers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-sql.html b/doc/src/sgml/html/logicaldecoding-sql.html
new file mode 100644
index 0000000..0139b65
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-sql.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.4. Logical Decoding SQL Interface</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface" /><link rel="next" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.4. Logical Decoding <acronym class="acronym">SQL</acronym> Interface</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-SQL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.4. Logical Decoding <acronym class="acronym">SQL</acronym> Interface</h2></div></div></div><p>
+ See <a class="xref" href="functions-admin.html#FUNCTIONS-REPLICATION" title="9.27.6. Replication Management Functions">Section 9.27.6</a> for detailed documentation on
+ the SQL-level API for interacting with logical decoding.
+ </p><p>
+ Synchronous replication (see <a class="xref" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="27.2.8. Synchronous Replication">Section 27.2.8</a>) is
+ only supported on replication slots used over the streaming replication interface. The
+ function interface and additional, non-core interfaces do not support
+ synchronous replication.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-catalogs.html" title="49.5. System Catalogs Related to Logical Decoding">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.3. Streaming Replication Protocol Interface </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.5. System Catalogs Related to Logical Decoding</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-streaming.html b/doc/src/sgml/html/logicaldecoding-streaming.html
new file mode 100644
index 0000000..dc911ae
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-streaming.html
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.9. Streaming of Large Transactions for Logical Decoding</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-synchronous.html" title="49.8. Synchronous Replication Support for Logical Decoding" /><link rel="next" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.9. Streaming of Large Transactions for Logical Decoding</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-synchronous.html" title="49.8. Synchronous Replication Support for Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-STREAMING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.9. Streaming of Large Transactions for Logical Decoding</h2></div></div></div><p>
+ The basic output plugin callbacks (e.g., <code class="function">begin_cb</code>,
+ <code class="function">change_cb</code>, <code class="function">commit_cb</code> and
+ <code class="function">message_cb</code>) are only invoked when the transaction
+ actually commits. The changes are still decoded from the transaction
+ log, but are only passed to the output plugin at commit (and discarded
+ if the transaction aborts).
+ </p><p>
+ This means that while the decoding happens incrementally, and may spill
+ to disk to keep memory usage under control, all the decoded changes have
+ to be transmitted when the transaction finally commits (or more precisely,
+ when the commit is decoded from the transaction log). Depending on the
+ size of the transaction and network bandwidth, the transfer time may
+ significantly increase the apply lag.
+ </p><p>
+ To reduce the apply lag caused by large transactions, an output plugin
+ may provide additional callback to support incremental streaming of
+ in-progress transactions. There are multiple required streaming callbacks
+ (<code class="function">stream_start_cb</code>, <code class="function">stream_stop_cb</code>,
+ <code class="function">stream_abort_cb</code>, <code class="function">stream_commit_cb</code>
+ and <code class="function">stream_change_cb</code>) and two optional callbacks
+ (<code class="function">stream_message_cb</code> and <code class="function">stream_truncate_cb</code>).
+ Also, if streaming of two-phase commands is to be supported, then additional
+ callbacks must be provided. (See <a class="xref" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding">Section 49.10</a>
+ for details).
+ </p><p>
+ When streaming an in-progress transaction, the changes (and messages) are
+ streamed in blocks demarcated by <code class="function">stream_start_cb</code>
+ and <code class="function">stream_stop_cb</code> callbacks. Once all the decoded
+ changes are transmitted, the transaction can be committed using the
+ <code class="function">stream_commit_cb</code> callback
+ (or possibly aborted using the <code class="function">stream_abort_cb</code> callback).
+ If two-phase commits are supported, the transaction can be prepared using the
+ <code class="function">stream_prepare_cb</code> callback,
+ <code class="command">COMMIT PREPARED</code> using the
+ <code class="function">commit_prepared_cb</code> callback or aborted using the
+ <code class="function">rollback_prepared_cb</code>.
+ </p><p>
+ One example sequence of streaming callback calls for one transaction may
+ look like this:
+</p><pre class="programlisting">
+stream_start_cb(...); &lt;-- start of first block of changes
+ stream_change_cb(...);
+ stream_change_cb(...);
+ stream_message_cb(...);
+ stream_change_cb(...);
+ ...
+ stream_change_cb(...);
+stream_stop_cb(...); &lt;-- end of first block of changes
+
+stream_start_cb(...); &lt;-- start of second block of changes
+ stream_change_cb(...);
+ stream_change_cb(...);
+ stream_change_cb(...);
+ ...
+ stream_message_cb(...);
+ stream_change_cb(...);
+stream_stop_cb(...); &lt;-- end of second block of changes
+
+
+[a. when using normal commit]
+stream_commit_cb(...); &lt;-- commit of the streamed transaction
+
+[b. when using two-phase commit]
+stream_prepare_cb(...); &lt;-- prepare the streamed transaction
+commit_prepared_cb(...); &lt;-- commit of the prepared transaction
+</pre><p>
+ </p><p>
+ The actual sequence of callback calls may be more complicated, of course.
+ There may be blocks for multiple streamed transactions, some of the
+ transactions may get aborted, etc.
+ </p><p>
+ Similar to spill-to-disk behavior, streaming is triggered when the total
+ amount of changes decoded from the WAL (for all in-progress transactions)
+ exceeds the limit defined by <code class="varname">logical_decoding_work_mem</code> setting.
+ At that point, the largest top-level transaction (measured by the amount of memory
+ currently used for decoded changes) is selected and streamed. However, in
+ some cases we still have to spill to disk even if streaming is enabled
+ because we exceed the memory threshold but still have not decoded the
+ complete tuple e.g., only decoded toast table insert but not the main table
+ insert.
+ </p><p>
+ Even when streaming large transactions, the changes are still applied in
+ commit order, preserving the same guarantees as the non-streaming mode.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-synchronous.html" title="49.8. Synchronous Replication Support for Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.8. Synchronous Replication Support for Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.10. Two-phase Commit Support for Logical Decoding</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-synchronous.html b/doc/src/sgml/html/logicaldecoding-synchronous.html
new file mode 100644
index 0000000..9bad61a
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-synchronous.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.8. Synchronous Replication Support for Logical Decoding</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers" /><link rel="next" href="logicaldecoding-streaming.html" title="49.9. Streaming of Large Transactions for Logical Decoding" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.8. Synchronous Replication Support for Logical Decoding</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-streaming.html" title="49.9. Streaming of Large Transactions for Logical Decoding">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-SYNCHRONOUS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.8. Synchronous Replication Support for Logical Decoding</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="logicaldecoding-synchronous.html#id-1.8.14.14.2">49.8.1. Overview</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-synchronous.html#LOGICALDECODING-SYNCHRONOUS-CAVEATS">49.8.2. Caveats</a></span></dt></dl></div><div class="sect2" id="id-1.8.14.14.2"><div class="titlepage"><div><div><h3 class="title">49.8.1. Overview</h3></div></div></div><p>
+ Logical decoding can be used to build
+ <a class="link" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="27.2.8. Synchronous Replication">synchronous
+ replication</a> solutions with the same user interface as synchronous
+ replication for <a class="link" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">streaming
+ replication</a>. To do this, the streaming replication interface
+ (see <a class="xref" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface">Section 49.3</a>) must be used to stream out
+ data. Clients have to send <code class="literal">Standby status update (F)</code>
+ (see <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>) messages, just like streaming
+ replication clients do.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ A synchronous replica receiving changes via logical decoding will work in
+ the scope of a single database. Since, in contrast to
+ that, <em class="parameter"><code>synchronous_standby_names</code></em> currently is
+ server wide, this means this technique will not work properly if more
+ than one database is actively used.
+ </p></div></div><div class="sect2" id="LOGICALDECODING-SYNCHRONOUS-CAVEATS"><div class="titlepage"><div><div><h3 class="title">49.8.2. Caveats</h3></div></div></div><p>
+ In synchronous replication setup, a deadlock can happen, if the transaction
+ has locked [user] catalog tables exclusively. See
+ <a class="xref" href="logicaldecoding-output-plugin.html#LOGICALDECODING-CAPABILITIES" title="49.6.2. Capabilities">Section 49.6.2</a> for information on user
+ catalog tables. This is because logical decoding of transactions can lock
+ catalog tables to access them. To avoid this users must refrain from taking
+ an exclusive lock on [user] catalog tables. This can happen in the following
+ ways:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Issuing an explicit <code class="command">LOCK</code> on <code class="structname">pg_class</code>
+ in a transaction.
+ </p></li><li class="listitem"><p>
+ Perform <code class="command">CLUSTER</code> on <code class="structname">pg_class</code> in
+ a transaction.
+ </p></li><li class="listitem"><p>
+ <code class="command">PREPARE TRANSACTION</code> after <code class="command">LOCK</code> command
+ on <code class="structname">pg_class</code> and allow logical decoding of two-phase
+ transactions.
+ </p></li><li class="listitem"><p>
+ <code class="command">PREPARE TRANSACTION</code> after <code class="command">CLUSTER</code>
+ command on <code class="structname">pg_trigger</code> and allow logical decoding of
+ two-phase transactions. This will lead to deadlock only when published table
+ have a trigger.
+ </p></li><li class="listitem"><p>
+ Executing <code class="command">TRUNCATE</code> on [user] catalog table in a
+ transaction.
+ </p></li></ul></div><p>
+
+ Note that these commands that can cause deadlock apply to not only explicitly
+ indicated system catalog tables above but also to any other [user] catalog
+ table.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-streaming.html" title="49.9. Streaming of Large Transactions for Logical Decoding">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.7. Logical Decoding Output Writers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.9. Streaming of Large Transactions for Logical Decoding</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-two-phase-commits.html b/doc/src/sgml/html/logicaldecoding-two-phase-commits.html
new file mode 100644
index 0000000..ccd3add
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-two-phase-commits.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.10. Two-phase Commit Support for Logical Decoding</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-streaming.html" title="49.9. Streaming of Large Transactions for Logical Decoding" /><link rel="next" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.10. Two-phase Commit Support for Logical Decoding</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-streaming.html" title="49.9. Streaming of Large Transactions for Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-TWO-PHASE-COMMITS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.10. Two-phase Commit Support for Logical Decoding</h2></div></div></div><p>
+ With the basic output plugin callbacks (eg., <code class="function">begin_cb</code>,
+ <code class="function">change_cb</code>, <code class="function">commit_cb</code> and
+ <code class="function">message_cb</code>) two-phase commit commands like
+ <code class="command">PREPARE TRANSACTION</code>, <code class="command">COMMIT PREPARED</code>
+ and <code class="command">ROLLBACK PREPARED</code> are not decoded. While the
+ <code class="command">PREPARE TRANSACTION</code> is ignored,
+ <code class="command">COMMIT PREPARED</code> is decoded as a <code class="command">COMMIT</code>
+ and <code class="command">ROLLBACK PREPARED</code> is decoded as a
+ <code class="command">ROLLBACK</code>.
+ </p><p>
+ To support the streaming of two-phase commands, an output plugin needs to
+ provide additional callbacks. There are multiple two-phase commit callbacks
+ that are required, (<code class="function">begin_prepare_cb</code>,
+ <code class="function">prepare_cb</code>, <code class="function">commit_prepared_cb</code>,
+ <code class="function">rollback_prepared_cb</code> and
+ <code class="function">stream_prepare_cb</code>) and an optional callback
+ (<code class="function">filter_prepare_cb</code>).
+ </p><p>
+ If the output plugin callbacks for decoding two-phase commit commands are
+ provided, then on <code class="command">PREPARE TRANSACTION</code>, the changes of
+ that transaction are decoded, passed to the output plugin, and the
+ <code class="function">prepare_cb</code> callback is invoked. This differs from the
+ basic decoding setup where changes are only passed to the output plugin
+ when a transaction is committed. The start of a prepared transaction is
+ indicated by the <code class="function">begin_prepare_cb</code> callback.
+ </p><p>
+ When a prepared transaction is rolled back using the
+ <code class="command">ROLLBACK PREPARED</code>, then the
+ <code class="function">rollback_prepared_cb</code> callback is invoked and when the
+ prepared transaction is committed using <code class="command">COMMIT PREPARED</code>,
+ then the <code class="function">commit_prepared_cb</code> callback is invoked.
+ </p><p>
+ Optionally the output plugin can define filtering rules via
+ <code class="function">filter_prepare_cb</code> to decode only specific transaction
+ in two phases. This can be achieved by pattern matching on the
+ <em class="parameter"><code>gid</code></em> or via lookups using the
+ <em class="parameter"><code>xid</code></em>.
+ </p><p>
+ The users that want to decode prepared transactions need to be careful about
+ below mentioned points:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If the prepared transaction has locked [user] catalog tables exclusively
+ then decoding prepare can block till the main transaction is committed.
+ </p></li><li class="listitem"><p>
+ The logical replication solution that builds distributed two phase commit
+ using this feature can deadlock if the prepared transaction has locked
+ [user] catalog tables exclusively. To avoid this users must refrain from
+ having locks on catalog tables (e.g. explicit <code class="command">LOCK</code> command)
+ in such transactions.
+ See <a class="xref" href="logicaldecoding-synchronous.html#LOGICALDECODING-SYNCHRONOUS-CAVEATS" title="49.8.2. Caveats">Section 49.8.2</a> for the details.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-streaming.html" title="49.9. Streaming of Large Transactions for Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.9. Streaming of Large Transactions for Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 50. Replication Progress Tracking</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-walsender.html b/doc/src/sgml/html/logicaldecoding-walsender.html
new file mode 100644
index 0000000..af82d71
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-walsender.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.3. Streaming Replication Protocol Interface</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-explanation.html" title="49.2. Logical Decoding Concepts" /><link rel="next" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.3. Streaming Replication Protocol Interface</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-explanation.html" title="49.2. Logical Decoding Concepts">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-WALSENDER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.3. Streaming Replication Protocol Interface</h2></div></div></div><p>
+ The commands
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">CREATE_REPLICATION_SLOT <em class="replaceable"><code>slot_name</code></em> LOGICAL <em class="replaceable"><code>output_plugin</code></em></code></p></li><li class="listitem"><p><code class="literal">DROP_REPLICATION_SLOT <em class="replaceable"><code>slot_name</code></em></code> [<span class="optional"> <code class="literal">WAIT</code> </span>]</p></li><li class="listitem"><p><code class="literal">START_REPLICATION SLOT <em class="replaceable"><code>slot_name</code></em> LOGICAL ...</code></p></li></ul></div><p>
+ are used to create, drop, and stream changes from a replication
+ slot, respectively. These commands are only available over a replication
+ connection; they cannot be used via SQL.
+ See <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a> for details on these commands.
+ </p><p>
+ The command <a class="xref" href="app-pgrecvlogical.html" title="pg_recvlogical"><span class="refentrytitle"><span class="application">pg_recvlogical</span></span></a> can be used to control
+ logical decoding over a streaming replication connection. (It uses
+ these commands internally.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-explanation.html" title="49.2. Logical Decoding Concepts">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.2. Logical Decoding Concepts </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.4. Logical Decoding <acronym class="acronym">SQL</acronym> Interface</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding-writer.html b/doc/src/sgml/html/logicaldecoding-writer.html
new file mode 100644
index 0000000..c39ef08
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding-writer.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>49.7. Logical Decoding Output Writers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins" /><link rel="next" href="logicaldecoding-synchronous.html" title="49.8. Synchronous Replication Support for Logical Decoding" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">49.7. Logical Decoding Output Writers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><th width="60%" align="center">Chapter 49. Logical Decoding</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-synchronous.html" title="49.8. Synchronous Replication Support for Logical Decoding">Next</a></td></tr></table><hr /></div><div class="sect1" id="LOGICALDECODING-WRITER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">49.7. Logical Decoding Output Writers</h2></div></div></div><p>
+ It is possible to add more output methods for logical decoding.
+ For details, see
+ <code class="filename">src/backend/replication/logical/logicalfuncs.c</code>.
+ Essentially, three functions need to be provided: one to read WAL, one to
+ prepare writing output, and one to write the output
+ (see <a class="xref" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT" title="49.6.5. Functions for Producing Output">Section 49.6.5</a>).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-synchronous.html" title="49.8. Synchronous Replication Support for Logical Decoding">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.6. Logical Decoding Output Plugins </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.8. Synchronous Replication Support for Logical Decoding</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/logicaldecoding.html b/doc/src/sgml/html/logicaldecoding.html
new file mode 100644
index 0000000..7e10402
--- /dev/null
+++ b/doc/src/sgml/html/logicaldecoding.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 49. Logical Decoding</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bgworker.html" title="Chapter 48. Background Worker Processes" /><link rel="next" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 49. Logical Decoding</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bgworker.html" title="Chapter 48. Background Worker Processes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples">Next</a></td></tr></table><hr /></div><div class="chapter" id="LOGICALDECODING"><div class="titlepage"><div><div><h2 class="title">Chapter 49. Logical Decoding</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="logicaldecoding-example.html">49.1. Logical Decoding Examples</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-explanation.html">49.2. Logical Decoding Concepts</a></span></dt><dd><dl><dt><span class="sect2"><a href="logicaldecoding-explanation.html#id-1.8.14.8.2">49.2.1. Logical Decoding</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-explanation.html#LOGICALDECODING-REPLICATION-SLOTS">49.2.2. Replication Slots</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-explanation.html#id-1.8.14.8.4">49.2.3. Output Plugins</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-explanation.html#id-1.8.14.8.5">49.2.4. Exported Snapshots</a></span></dt></dl></dd><dt><span class="sect1"><a href="logicaldecoding-walsender.html">49.3. Streaming Replication Protocol Interface</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-sql.html">49.4. Logical Decoding <acronym class="acronym">SQL</acronym> Interface</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-catalogs.html">49.5. System Catalogs Related to Logical Decoding</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-output-plugin.html">49.6. Logical Decoding Output Plugins</a></span></dt><dd><dl><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-INIT">49.6.1. Initialization Function</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-CAPABILITIES">49.6.2. Capabilities</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-MODE">49.6.3. Output Modes</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-CALLBACKS">49.6.4. Output Plugin Callbacks</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-OUTPUT">49.6.5. Functions for Producing Output</a></span></dt></dl></dd><dt><span class="sect1"><a href="logicaldecoding-writer.html">49.7. Logical Decoding Output Writers</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-synchronous.html">49.8. Synchronous Replication Support for Logical Decoding</a></span></dt><dd><dl><dt><span class="sect2"><a href="logicaldecoding-synchronous.html#id-1.8.14.14.2">49.8.1. Overview</a></span></dt><dt><span class="sect2"><a href="logicaldecoding-synchronous.html#LOGICALDECODING-SYNCHRONOUS-CAVEATS">49.8.2. Caveats</a></span></dt></dl></dd><dt><span class="sect1"><a href="logicaldecoding-streaming.html">49.9. Streaming of Large Transactions for Logical Decoding</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-two-phase-commits.html">49.10. Two-phase Commit Support for Logical Decoding</a></span></dt></dl></div><a id="id-1.8.14.2" class="indexterm"></a><p>
+ PostgreSQL provides infrastructure to stream the modifications performed
+ via SQL to external consumers. This functionality can be used for a
+ variety of purposes, including replication solutions and auditing.
+ </p><p>
+ Changes are sent out in streams identified by logical replication slots.
+ </p><p>
+ The format in which those changes are streamed is determined by the output
+ plugin used. An example plugin is provided in the PostgreSQL distribution.
+ Additional plugins can be
+ written to extend the choice of available formats without modifying any
+ core code.
+ Every output plugin has access to each individual new row produced
+ by <code class="command">INSERT</code> and the new row version created
+ by <code class="command">UPDATE</code>. Availability of old row versions for
+ <code class="command">UPDATE</code> and <code class="command">DELETE</code> depends on
+ the configured replica identity (see <a class="xref" href="sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY"><code class="literal">REPLICA IDENTITY</code></a>).
+ </p><p>
+ Changes can be consumed either using the streaming replication protocol
+ (see <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a> and
+ <a class="xref" href="logicaldecoding-walsender.html" title="49.3. Streaming Replication Protocol Interface">Section 49.3</a>), or by calling functions
+ via SQL (see <a class="xref" href="logicaldecoding-sql.html" title="49.4. Logical Decoding SQL Interface">Section 49.4</a>). It is also possible
+ to write additional methods of consuming the output of a replication slot
+ without modifying core code
+ (see <a class="xref" href="logicaldecoding-writer.html" title="49.7. Logical Decoding Output Writers">Section 49.7</a>).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bgworker.html" title="Chapter 48. Background Worker Processes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logicaldecoding-example.html" title="49.1. Logical Decoding Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 48. Background Worker Processes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 49.1. Logical Decoding Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ltree.html b/doc/src/sgml/html/ltree.html
new file mode 100644
index 0000000..8216be6
--- /dev/null
+++ b/doc/src/sgml/html/ltree.html
@@ -0,0 +1,582 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.23. ltree</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="lo.html" title="F.22. lo" /><link rel="next" href="oldsnapshot.html" title="F.24. old_snapshot" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.23. ltree</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="lo.html" title="F.22. lo">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="oldsnapshot.html" title="F.24. old_snapshot">Next</a></td></tr></table><hr /></div><div class="sect1" id="LTREE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.23. ltree</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.5">F.23.1. Definitions</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.6">F.23.2. Operators and Functions</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.7">F.23.3. Indexes</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.8">F.23.4. Example</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.9">F.23.5. Transforms</a></span></dt><dt><span class="sect2"><a href="ltree.html#id-1.11.7.32.10">F.23.6. Authors</a></span></dt></dl></div><a id="id-1.11.7.32.2" class="indexterm"></a><p>
+ This module implements a data type <code class="type">ltree</code> for representing
+ labels of data stored in a hierarchical tree-like structure.
+ Extensive facilities for searching through label trees are provided.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.32.5"><div class="titlepage"><div><div><h3 class="title">F.23.1. Definitions</h3></div></div></div><p>
+ A <em class="firstterm">label</em> is a sequence of alphanumeric characters
+ and underscores (for example, in C locale the characters
+ <code class="literal">A-Za-z0-9_</code> are allowed).
+ Labels must be less than 256 characters long.
+ </p><p>
+ Examples: <code class="literal">42</code>, <code class="literal">Personal_Services</code>
+ </p><p>
+ A <em class="firstterm">label path</em> is a sequence of zero or more
+ labels separated by dots, for example <code class="literal">L1.L2.L3</code>, representing
+ a path from the root of a hierarchical tree to a particular node. The
+ length of a label path cannot exceed 65535 labels.
+ </p><p>
+ Example: <code class="literal">Top.Countries.Europe.Russia</code>
+ </p><p>
+ The <code class="filename">ltree</code> module provides several data types:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="type">ltree</code> stores a label path.
+ </p></li><li class="listitem"><p>
+ <code class="type">lquery</code> represents a regular-expression-like pattern
+ for matching <code class="type">ltree</code> values. A simple word matches that
+ label within a path. A star symbol (<code class="literal">*</code>) matches zero
+ or more labels. These can be joined with dots to form a pattern that
+ must match the whole label path. For example:
+</p><pre class="synopsis">
+foo <em class="lineannotation"><span class="lineannotation">Match the exact label path <code class="literal">foo</code></span></em>
+*.foo.* <em class="lineannotation"><span class="lineannotation">Match any label path containing the label <code class="literal">foo</code></span></em>
+*.foo <em class="lineannotation"><span class="lineannotation">Match any label path whose last label is <code class="literal">foo</code></span></em>
+</pre><p>
+ </p><p>
+ Both star symbols and simple words can be quantified to restrict how many
+ labels they can match:
+</p><pre class="synopsis">
+*{<em class="replaceable"><code>n</code></em>} <em class="lineannotation"><span class="lineannotation">Match exactly <em class="replaceable"><code>n</code></em> labels</span></em>
+*{<em class="replaceable"><code>n</code></em>,} <em class="lineannotation"><span class="lineannotation">Match at least <em class="replaceable"><code>n</code></em> labels</span></em>
+*{<em class="replaceable"><code>n</code></em>,<em class="replaceable"><code>m</code></em>} <em class="lineannotation"><span class="lineannotation">Match at least <em class="replaceable"><code>n</code></em> but not more than <em class="replaceable"><code>m</code></em> labels</span></em>
+*{,<em class="replaceable"><code>m</code></em>} <em class="lineannotation"><span class="lineannotation">Match at most <em class="replaceable"><code>m</code></em> labels — same as </span></em>*{0,<em class="replaceable"><code>m</code></em>}
+foo{<em class="replaceable"><code>n</code></em>,<em class="replaceable"><code>m</code></em>} <em class="lineannotation"><span class="lineannotation">Match at least <em class="replaceable"><code>n</code></em> but not more than <em class="replaceable"><code>m</code></em> occurrences of <code class="literal">foo</code></span></em>
+foo{,} <em class="lineannotation"><span class="lineannotation">Match any number of occurrences of <code class="literal">foo</code>, including zero</span></em>
+</pre><p>
+ In the absence of any explicit quantifier, the default for a star symbol
+ is to match any number of labels (that is, <code class="literal">{,}</code>) while
+ the default for a non-star item is to match exactly once (that
+ is, <code class="literal">{1}</code>).
+ </p><p>
+ There are several modifiers that can be put at the end of a non-star
+ <code class="type">lquery</code> item to make it match more than just the exact match:
+</p><pre class="synopsis">
+@ <em class="lineannotation"><span class="lineannotation">Match case-insensitively, for example <code class="literal">a@</code> matches <code class="literal">A</code></span></em>
+* <em class="lineannotation"><span class="lineannotation">Match any label with this prefix, for example <code class="literal">foo*</code> matches <code class="literal">foobar</code></span></em>
+% <em class="lineannotation"><span class="lineannotation">Match initial underscore-separated words</span></em>
+</pre><p>
+ The behavior of <code class="literal">%</code> is a bit complicated. It tries to match
+ words rather than the entire label. For example
+ <code class="literal">foo_bar%</code> matches <code class="literal">foo_bar_baz</code> but not
+ <code class="literal">foo_barbaz</code>. If combined with <code class="literal">*</code>, prefix
+ matching applies to each word separately, for example
+ <code class="literal">foo_bar%*</code> matches <code class="literal">foo1_bar2_baz</code> but
+ not <code class="literal">foo1_br2_baz</code>.
+ </p><p>
+ Also, you can write several possibly-modified non-star items separated with
+ <code class="literal">|</code> (OR) to match any of those items, and you can put
+ <code class="literal">!</code> (NOT) at the start of a non-star group to match any
+ label that doesn't match any of the alternatives. A quantifier, if any,
+ goes at the end of the group; it means some number of matches for the
+ group as a whole (that is, some number of labels matching or not matching
+ any of the alternatives).
+ </p><p>
+ Here's an annotated example of <code class="type">lquery</code>:
+</p><pre class="programlisting">
+Top.*{0,2}.sport*@.!football|tennis{1,}.Russ*|Spain
+a. b. c. d. e.
+</pre><p>
+ This query will match any label path that:
+ </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p>
+ begins with the label <code class="literal">Top</code>
+ </p></li><li class="listitem"><p>
+ and next has zero to two labels before
+ </p></li><li class="listitem"><p>
+ a label beginning with the case-insensitive prefix <code class="literal">sport</code>
+ </p></li><li class="listitem"><p>
+ then has one or more labels, none of which
+ match <code class="literal">football</code> nor <code class="literal">tennis</code>
+ </p></li><li class="listitem"><p>
+ and then ends with a label beginning with <code class="literal">Russ</code> or
+ exactly matching <code class="literal">Spain</code>.
+ </p></li></ol></div></li><li class="listitem"><p><code class="type">ltxtquery</code> represents a full-text-search-like
+ pattern for matching <code class="type">ltree</code> values. An
+ <code class="type">ltxtquery</code> value contains words, possibly with the
+ modifiers <code class="literal">@</code>, <code class="literal">*</code>, <code class="literal">%</code> at the end;
+ the modifiers have the same meanings as in <code class="type">lquery</code>.
+ Words can be combined with <code class="literal">&amp;</code> (AND),
+ <code class="literal">|</code> (OR), <code class="literal">!</code> (NOT), and parentheses.
+ The key difference from
+ <code class="type">lquery</code> is that <code class="type">ltxtquery</code> matches words without
+ regard to their position in the label path.
+ </p><p>
+ Here's an example <code class="type">ltxtquery</code>:
+</p><pre class="programlisting">
+Europe &amp; Russia*@ &amp; !Transportation
+</pre><p>
+ This will match paths that contain the label <code class="literal">Europe</code> and
+ any label beginning with <code class="literal">Russia</code> (case-insensitive),
+ but not paths containing the label <code class="literal">Transportation</code>.
+ The location of these words within the path is not important.
+ Also, when <code class="literal">%</code> is used, the word can be matched to any
+ underscore-separated word within a label, regardless of position.
+ </p></li></ul></div><p>
+ Note: <code class="type">ltxtquery</code> allows whitespace between symbols, but
+ <code class="type">ltree</code> and <code class="type">lquery</code> do not.
+ </p></div><div class="sect2" id="id-1.11.7.32.6"><div class="titlepage"><div><div><h3 class="title">F.23.2. Operators and Functions</h3></div></div></div><p>
+ Type <code class="type">ltree</code> has the usual comparison operators
+ <code class="literal">=</code>, <code class="literal">&lt;&gt;</code>,
+ <code class="literal">&lt;</code>, <code class="literal">&gt;</code>, <code class="literal">&lt;=</code>, <code class="literal">&gt;=</code>.
+ Comparison sorts in the order of a tree traversal, with the children
+ of a node sorted by label text. In addition, the specialized
+ operators shown in <a class="xref" href="ltree.html#LTREE-OP-TABLE" title="Table F.13. ltree Operators">Table F.13</a> are available.
+ </p><div class="table" id="LTREE-OP-TABLE"><p class="title"><strong>Table F.13. <code class="type">ltree</code> Operators</strong></p><div class="table-contents"><table class="table" summary="ltree Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">@&gt;</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is left argument an ancestor of right (or equal)?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">&lt;@</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is left argument a descendant of right (or equal)?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">~</code> <code class="type">lquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">lquery</code> <code class="literal">~</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">ltree</code> match <code class="type">lquery</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">?</code> <code class="type">lquery[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">lquery[]</code> <code class="literal">?</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">ltree</code> match any <code class="type">lquery</code> in array?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">@</code> <code class="type">ltxtquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">ltxtquery</code> <code class="literal">@</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">ltree</code> match <code class="type">ltxtquery</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">||</code> <code class="type">ltree</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Concatenates <code class="type">ltree</code> paths.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">||</code> <code class="type">text</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">text</code> <code class="literal">||</code> <code class="type">ltree</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Converts text to <code class="type">ltree</code> and concatenates.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">@&gt;</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">&lt;@</code> <code class="type">ltree[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array contain an ancestor of <code class="type">ltree</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">&lt;@</code> <code class="type">ltree</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">ltree</code> <code class="literal">@&gt;</code> <code class="type">ltree[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array contain a descendant of <code class="type">ltree</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">~</code> <code class="type">lquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">lquery</code> <code class="literal">~</code> <code class="type">ltree[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array contain any path matching <code class="type">lquery</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">?</code> <code class="type">lquery[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">lquery[]</code> <code class="literal">?</code> <code class="type">ltree[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does <code class="type">ltree</code> array contain any path matching
+ any <code class="type">lquery</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">@</code> <code class="type">ltxtquery</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p class="func_signature">
+ <code class="type">ltxtquery</code> <code class="literal">@</code> <code class="type">ltree[]</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does array contain any path matching <code class="type">ltxtquery</code>?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">?@&gt;</code> <code class="type">ltree</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns first array entry that is an ancestor of <code class="type">ltree</code>,
+ or <code class="literal">NULL</code> if none.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">?&lt;@</code> <code class="type">ltree</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns first array entry that is a descendant of <code class="type">ltree</code>,
+ or <code class="literal">NULL</code> if none.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">?~</code> <code class="type">lquery</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns first array entry that matches <code class="type">lquery</code>,
+ or <code class="literal">NULL</code> if none.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">ltree[]</code> <code class="literal">?@</code> <code class="type">ltxtquery</code>
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns first array entry that matches <code class="type">ltxtquery</code>,
+ or <code class="literal">NULL</code> if none.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The operators <code class="literal">&lt;@</code>, <code class="literal">@&gt;</code>,
+ <code class="literal">@</code> and <code class="literal">~</code> have analogues
+ <code class="literal">^&lt;@</code>, <code class="literal">^@&gt;</code>, <code class="literal">^@</code>,
+ <code class="literal">^~</code>, which are the same except they do not use
+ indexes. These are useful only for testing purposes.
+ </p><p>
+ The available functions are shown in <a class="xref" href="ltree.html#LTREE-FUNC-TABLE" title="Table F.14. ltree Functions">Table F.14</a>.
+ </p><div class="table" id="LTREE-FUNC-TABLE"><p class="title"><strong>Table F.14. <code class="type">ltree</code> Functions</strong></p><div class="table-contents"><table class="table" summary="ltree Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">subltree</code> ( <code class="type">ltree</code>, <em class="parameter"><code>start</code></em> <code class="type">integer</code>, <em class="parameter"><code>end</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns subpath of <code class="type">ltree</code> from
+ position <em class="parameter"><code>start</code></em> to
+ position <em class="parameter"><code>end</code></em>-1 (counting from 0).
+ </p>
+ <p>
+ <code class="literal">subltree('Top.Child1.Child2', 1, 2)</code>
+ → <code class="returnvalue">Child1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">subpath</code> ( <code class="type">ltree</code>, <em class="parameter"><code>offset</code></em> <code class="type">integer</code>, <em class="parameter"><code>len</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns subpath of <code class="type">ltree</code> starting at
+ position <em class="parameter"><code>offset</code></em>, with
+ length <em class="parameter"><code>len</code></em>. If <em class="parameter"><code>offset</code></em>
+ is negative, subpath starts that far from the end of the path.
+ If <em class="parameter"><code>len</code></em> is negative, leaves that many labels off
+ the end of the path.
+ </p>
+ <p>
+ <code class="literal">subpath('Top.Child1.Child2', 0, 2)</code>
+ → <code class="returnvalue">Top.Child1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">subpath</code> ( <code class="type">ltree</code>, <em class="parameter"><code>offset</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Returns subpath of <code class="type">ltree</code> starting at
+ position <em class="parameter"><code>offset</code></em>, extending to end of path.
+ If <em class="parameter"><code>offset</code></em> is negative, subpath starts that far
+ from the end of the path.
+ </p>
+ <p>
+ <code class="literal">subpath('Top.Child1.Child2', 1)</code>
+ → <code class="returnvalue">Child1.Child2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">nlevel</code> ( <code class="type">ltree</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns number of labels in path.
+ </p>
+ <p>
+ <code class="literal">nlevel('Top.Child1.Child2')</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">index</code> ( <em class="parameter"><code>a</code></em> <code class="type">ltree</code>, <em class="parameter"><code>b</code></em> <code class="type">ltree</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns position of first occurrence of <em class="parameter"><code>b</code></em> in
+ <em class="parameter"><code>a</code></em>, or -1 if not found.
+ </p>
+ <p>
+ <code class="literal">index('0.1.2.3.5.4.5.6.8.5.6.8', '5.6')</code>
+ → <code class="returnvalue">6</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">index</code> ( <em class="parameter"><code>a</code></em> <code class="type">ltree</code>, <em class="parameter"><code>b</code></em> <code class="type">ltree</code>, <em class="parameter"><code>offset</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns position of first occurrence of <em class="parameter"><code>b</code></em>
+ in <em class="parameter"><code>a</code></em>, or -1 if not found. The search starts at
+ position <em class="parameter"><code>offset</code></em>;
+ negative <em class="parameter"><code>offset</code></em> means
+ start <em class="parameter"><code>-offset</code></em> labels from the end of the path.
+ </p>
+ <p>
+ <code class="literal">index('0.1.2.3.5.4.5.6.8.5.6.8', '5.6', -4)</code>
+ → <code class="returnvalue">9</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">text2ltree</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Casts <code class="type">text</code> to <code class="type">ltree</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">ltree2text</code> ( <code class="type">ltree</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Casts <code class="type">ltree</code> to <code class="type">text</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.32.6.6.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">lca</code> ( <code class="type">ltree</code> [<span class="optional">, <code class="type">ltree</code> [<span class="optional">, ... </span>]</span>] )
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Computes longest common ancestor of paths
+ (up to 8 arguments are supported).
+ </p>
+ <p>
+ <code class="literal">lca('1.2.3', '1.2.3.4.5.6')</code>
+ → <code class="returnvalue">1.2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">lca</code> ( <code class="type">ltree[]</code> )
+ → <code class="returnvalue">ltree</code>
+ </p>
+ <p>
+ Computes longest common ancestor of paths in array.
+ </p>
+ <p>
+ <code class="literal">lca(array['1.2.3'::ltree,'1.2.3.4'])</code>
+ → <code class="returnvalue">1.2</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.32.7"><div class="titlepage"><div><div><h3 class="title">F.23.3. Indexes</h3></div></div></div><p>
+ <code class="filename">ltree</code> supports several types of indexes that can speed
+ up the indicated operators:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ B-tree index over <code class="type">ltree</code>:
+ <code class="literal">&lt;</code>, <code class="literal">&lt;=</code>, <code class="literal">=</code>,
+ <code class="literal">&gt;=</code>, <code class="literal">&gt;</code>
+ </p></li><li class="listitem"><p>
+ GiST index over <code class="type">ltree</code> (<code class="literal">gist_ltree_ops</code>
+ opclass):
+ <code class="literal">&lt;</code>, <code class="literal">&lt;=</code>, <code class="literal">=</code>,
+ <code class="literal">&gt;=</code>, <code class="literal">&gt;</code>,
+ <code class="literal">@&gt;</code>, <code class="literal">&lt;@</code>,
+ <code class="literal">@</code>, <code class="literal">~</code>, <code class="literal">?</code>
+ </p><p>
+ <code class="literal">gist_ltree_ops</code> GiST opclass approximates a set of
+ path labels as a bitmap signature. Its optional integer parameter
+ <code class="literal">siglen</code> determines the
+ signature length in bytes. The default signature length is 8 bytes.
+ The length must be a positive multiple of <code class="type">int</code> alignment
+ (4 bytes on most machines)) up to 2024. Longer
+ signatures lead to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </p><p>
+ Example of creating such an index with the default signature length of 8 bytes:
+ </p><pre class="programlisting">
+CREATE INDEX path_gist_idx ON test USING GIST (path);
+</pre><p>
+ Example of creating such an index with a signature length of 100 bytes:
+ </p><pre class="programlisting">
+CREATE INDEX path_gist_idx ON test USING GIST (path gist_ltree_ops(siglen=100));
+</pre></li><li class="listitem"><p>
+ GiST index over <code class="type">ltree[]</code> (<code class="literal">gist__ltree_ops</code>
+ opclass):
+ <code class="literal">ltree[] &lt;@ ltree</code>, <code class="literal">ltree @&gt; ltree[]</code>,
+ <code class="literal">@</code>, <code class="literal">~</code>, <code class="literal">?</code>
+ </p><p>
+ <code class="literal">gist__ltree_ops</code> GiST opclass works similarly to
+ <code class="literal">gist_ltree_ops</code> and also takes signature length as
+ a parameter. The default value of <code class="literal">siglen</code> in
+ <code class="literal">gist__ltree_ops</code> is 28 bytes.
+ </p><p>
+ Example of creating such an index with the default signature length of 28 bytes:
+ </p><pre class="programlisting">
+CREATE INDEX path_gist_idx ON test USING GIST (array_path);
+</pre><p>
+ Example of creating such an index with a signature length of 100 bytes:
+ </p><pre class="programlisting">
+CREATE INDEX path_gist_idx ON test USING GIST (array_path gist__ltree_ops(siglen=100));
+</pre><p>
+ Note: This index type is lossy.
+ </p></li></ul></div></div><div class="sect2" id="id-1.11.7.32.8"><div class="titlepage"><div><div><h3 class="title">F.23.4. Example</h3></div></div></div><p>
+ This example uses the following data (also available in file
+ <code class="filename">contrib/ltree/ltreetest.sql</code> in the source distribution):
+ </p><pre class="programlisting">
+CREATE TABLE test (path ltree);
+INSERT INTO test VALUES ('Top');
+INSERT INTO test VALUES ('Top.Science');
+INSERT INTO test VALUES ('Top.Science.Astronomy');
+INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics');
+INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology');
+INSERT INTO test VALUES ('Top.Hobbies');
+INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy');
+INSERT INTO test VALUES ('Top.Collections');
+INSERT INTO test VALUES ('Top.Collections.Pictures');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts');
+CREATE INDEX path_gist_idx ON test USING GIST (path);
+CREATE INDEX path_idx ON test USING BTREE (path);
+</pre><p>
+ Now, we have a table <code class="structname">test</code> populated with data describing
+ the hierarchy shown below:
+ </p><pre class="literallayout">
+ Top
+ / | \
+ Science Hobbies Collections
+ / | \
+ Astronomy Amateurs_Astronomy Pictures
+ / \ |
+Astrophysics Cosmology Astronomy
+ / | \
+ Galaxies Stars Astronauts
+</pre><p>
+ We can do inheritance:
+</p><pre class="screen">
+ltreetest=&gt; SELECT path FROM test WHERE path &lt;@ 'Top.Science';
+ path
+------------------------------------
+ Top.Science
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+(4 rows)
+</pre><p>
+ </p><p>
+ Here are some examples of path matching:
+</p><pre class="screen">
+ltreetest=&gt; SELECT path FROM test WHERE path ~ '*.Astronomy.*';
+ path
+-----------------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+ Top.Collections.Pictures.Astronomy
+ Top.Collections.Pictures.Astronomy.Stars
+ Top.Collections.Pictures.Astronomy.Galaxies
+ Top.Collections.Pictures.Astronomy.Astronauts
+(7 rows)
+
+ltreetest=&gt; SELECT path FROM test WHERE path ~ '*.!pictures@.Astronomy.*';
+ path
+------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+(3 rows)
+</pre><p>
+ </p><p>
+ Here are some examples of full text search:
+</p><pre class="screen">
+ltreetest=&gt; SELECT path FROM test WHERE path @ 'Astro*% &amp; !pictures@';
+ path
+------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+ Top.Hobbies.Amateurs_Astronomy
+(4 rows)
+
+ltreetest=&gt; SELECT path FROM test WHERE path @ 'Astro* &amp; !pictures@';
+ path
+------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+(3 rows)
+</pre><p>
+ </p><p>
+ Path construction using functions:
+</p><pre class="screen">
+ltreetest=&gt; SELECT subpath(path,0,2)||'Space'||subpath(path,2) FROM test WHERE path &lt;@ 'Top.Science.Astronomy';
+ ?column?
+------------------------------------------
+ Top.Science.Space.Astronomy
+ Top.Science.Space.Astronomy.Astrophysics
+ Top.Science.Space.Astronomy.Cosmology
+(3 rows)
+</pre><p>
+ </p><p>
+ We could simplify this by creating an SQL function that inserts a label
+ at a specified position in a path:
+</p><pre class="screen">
+CREATE FUNCTION ins_label(ltree, int, text) RETURNS ltree
+ AS 'select subpath($1,0,$2) || $3 || subpath($1,$2);'
+ LANGUAGE SQL IMMUTABLE;
+
+ltreetest=&gt; SELECT ins_label(path,2,'Space') FROM test WHERE path &lt;@ 'Top.Science.Astronomy';
+ ins_label
+------------------------------------------
+ Top.Science.Space.Astronomy
+ Top.Science.Space.Astronomy.Astrophysics
+ Top.Science.Space.Astronomy.Cosmology
+(3 rows)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.7.32.9"><div class="titlepage"><div><div><h3 class="title">F.23.5. Transforms</h3></div></div></div><p>
+ The <code class="literal">ltree_plpython3u</code> extension implements transforms for
+ the <code class="type">ltree</code> type for PL/Python. If installed and specified when
+ creating a function, <code class="type">ltree</code> values are mapped to Python lists.
+ (The reverse is currently not supported, however.)
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is strongly recommended that the transform extension be installed in
+ the same schema as <code class="filename">ltree</code>. Otherwise there are
+ installation-time security hazards if a transform extension's schema
+ contains objects defined by a hostile user.
+ </p></div></div><div class="sect2" id="id-1.11.7.32.10"><div class="titlepage"><div><div><h3 class="title">F.23.6. Authors</h3></div></div></div><p>
+ All work was done by Teodor Sigaev (<code class="email">&lt;<a class="email" href="mailto:teodor@stack.net">teodor@stack.net</a>&gt;</code>) and
+ Oleg Bartunov (<code class="email">&lt;<a class="email" href="mailto:oleg@sai.msu.su">oleg@sai.msu.su</a>&gt;</code>). See
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/" target="_top">http://www.sai.msu.su/~megera/postgres/gist/</a> for
+ additional information. Authors would like to thank Eugeny Rodichev for
+ helpful discussions. Comments and bug reports are welcome.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="lo.html" title="F.22. lo">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="oldsnapshot.html" title="F.24. old_snapshot">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.22. lo </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.24. old_snapshot</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/maintenance.html b/doc/src/sgml/html/maintenance.html
new file mode 100644
index 0000000..07c96ac
--- /dev/null
+++ b/doc/src/sgml/html/maintenance.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 25. Routine Database Maintenance Tasks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="multibyte.html" title="24.3. Character Set Support" /><link rel="next" href="routine-vacuuming.html" title="25.1. Routine Vacuuming" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 25. Routine Database Maintenance Tasks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="multibyte.html" title="24.3. Character Set Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Next</a></td></tr></table><hr /></div><div class="chapter" id="MAINTENANCE"><div class="titlepage"><div><div><h2 class="title">Chapter 25. Routine Database Maintenance Tasks</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="routine-vacuuming.html">25.1. Routine Vacuuming</a></span></dt><dd><dl><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-BASICS">25.1.1. Vacuuming Basics</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-SPACE-RECOVERY">25.1.2. Recovering Disk Space</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-STATISTICS">25.1.3. Updating Planner Statistics</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-VISIBILITY-MAP">25.1.4. Updating the Visibility Map</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND">25.1.5. Preventing Transaction ID Wraparound Failures</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#AUTOVACUUM">25.1.6. The Autovacuum Daemon</a></span></dt></dl></dd><dt><span class="sect1"><a href="routine-reindex.html">25.2. Routine Reindexing</a></span></dt><dt><span class="sect1"><a href="logfile-maintenance.html">25.3. Log File Maintenance</a></span></dt></dl></div><a id="id-1.6.12.2" class="indexterm"></a><a id="id-1.6.12.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span>, like any database software, requires that certain tasks
+ be performed regularly to achieve optimum performance. The tasks
+ discussed here are <span class="emphasis"><em>required</em></span>, but they
+ are repetitive in nature and can easily be automated using standard
+ tools such as <span class="application">cron</span> scripts or
+ Windows' <span class="application">Task Scheduler</span>. It is the database
+ administrator's responsibility to set up appropriate scripts, and to
+ check that they execute successfully.
+ </p><p>
+ One obvious maintenance task is the creation of backup copies of the data on a
+ regular schedule. Without a recent backup, you have no chance of recovery
+ after a catastrophe (disk failure, fire, mistakenly dropping a critical
+ table, etc.). The backup and recovery mechanisms available in
+ <span class="productname">PostgreSQL</span> are discussed at length in
+ <a class="xref" href="backup.html" title="Chapter 26. Backup and Restore">Chapter 26</a>.
+ </p><p>
+ The other main category of maintenance task is periodic <span class="quote">“<span class="quote">vacuuming</span>”</span>
+ of the database. This activity is discussed in
+ <a class="xref" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Section 25.1</a>. Closely related to this is updating
+ the statistics that will be used by the query planner, as discussed in
+ <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a>.
+ </p><p>
+ Another task that might need periodic attention is log file management.
+ This is discussed in <a class="xref" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Section 25.3</a>.
+ </p><p>
+ <a class="ulink" href="https://bucardo.org/check_postgres/" target="_top"><span class="application">check_postgres</span></a>
+ is available for monitoring database health and reporting unusual
+ conditions. <span class="application">check_postgres</span> integrates with
+ Nagios and MRTG, but can be run standalone too.
+ </p><p>
+ <span class="productname">PostgreSQL</span> is low-maintenance compared
+ to some other database management systems. Nonetheless,
+ appropriate attention to these tasks will go far towards ensuring a
+ pleasant and productive experience with the system.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multibyte.html" title="24.3. Character Set Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Next</a></td></tr><tr><td width="40%" align="left" valign="top">24.3. Character Set Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 25.1. Routine Vacuuming</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/manage-ag-config.html b/doc/src/sgml/html/manage-ag-config.html
new file mode 100644
index 0000000..cc47859
--- /dev/null
+++ b/doc/src/sgml/html/manage-ag-config.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>23.4. Database Configuration</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="manage-ag-templatedbs.html" title="23.3. Template Databases" /><link rel="next" href="manage-ag-dropdb.html" title="23.5. Destroying a Database" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">23.4. Database Configuration</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><th width="60%" align="center">Chapter 23. Managing Databases</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="manage-ag-dropdb.html" title="23.5. Destroying a Database">Next</a></td></tr></table><hr /></div><div class="sect1" id="MANAGE-AG-CONFIG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">23.4. Database Configuration</h2></div></div></div><p>
+ Recall from <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> that the
+ <span class="productname">PostgreSQL</span> server provides a large number of
+ run-time configuration variables. You can set database-specific
+ default values for many of these settings.
+ </p><p>
+ For example, if for some reason you want to disable the
+ <acronym class="acronym">GEQO</acronym> optimizer for a given database, you'd
+ ordinarily have to either disable it for all databases or make sure
+ that every connecting client is careful to issue <code class="literal">SET geqo
+ TO off</code>. To make this setting the default within a particular
+ database, you can execute the command:
+</p><pre class="programlisting">
+ALTER DATABASE mydb SET geqo TO off;
+</pre><p>
+ This will save the setting (but not set it immediately). In
+ subsequent connections to this database it will appear as though
+ <code class="literal">SET geqo TO off;</code> had been executed just before the
+ session started.
+ Note that users can still alter this setting during their sessions; it
+ will only be the default. To undo any such setting, use
+ <code class="literal">ALTER DATABASE <em class="replaceable"><code>dbname</code></em> RESET
+ <em class="replaceable"><code>varname</code></em></code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="manage-ag-dropdb.html" title="23.5. Destroying a Database">Next</a></td></tr><tr><td width="40%" align="left" valign="top">23.3. Template Databases </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 23.5. Destroying a Database</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/manage-ag-createdb.html b/doc/src/sgml/html/manage-ag-createdb.html
new file mode 100644
index 0000000..172be42
--- /dev/null
+++ b/doc/src/sgml/html/manage-ag-createdb.html
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>23.2. Creating a Database</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="manage-ag-overview.html" title="23.1. Overview" /><link rel="next" href="manage-ag-templatedbs.html" title="23.3. Template Databases" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">23.2. Creating a Database</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="manage-ag-overview.html" title="23.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><th width="60%" align="center">Chapter 23. Managing Databases</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Next</a></td></tr></table><hr /></div><div class="sect1" id="MANAGE-AG-CREATEDB"><div class="titlepage"><div><div><h2 class="title" style="clear: both">23.2. Creating a Database</h2></div></div></div><a id="id-1.6.10.5.2" class="indexterm"></a><p>
+ In order to create a database, the <span class="productname">PostgreSQL</span>
+ server must be up and running (see <a class="xref" href="server-start.html" title="19.3. Starting the Database Server">Section 19.3</a>).
+ </p><p>
+ Databases are created with the SQL command
+ <a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a>:
+</p><pre class="synopsis">
+CREATE DATABASE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ where <em class="replaceable"><code>name</code></em> follows the usual rules for
+ <acronym class="acronym">SQL</acronym> identifiers. The current role automatically
+ becomes the owner of the new database. It is the privilege of the
+ owner of a database to remove it later (which also removes all
+ the objects in it, even if they have a different owner).
+ </p><p>
+ The creation of databases is a restricted operation. See <a class="xref" href="role-attributes.html" title="22.2. Role Attributes">Section 22.2</a> for how to grant permission.
+ </p><p>
+ Since you need to be connected to the database server in order to
+ execute the <code class="command">CREATE DATABASE</code> command, the
+ question remains how the <span class="emphasis"><em>first</em></span> database at any given
+ site can be created. The first database is always created by the
+ <code class="command">initdb</code> command when the data storage area is
+ initialized. (See <a class="xref" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Section 19.2</a>.) This
+ database is called
+ <code class="literal">postgres</code>.<a id="id-1.6.10.5.6.6" class="indexterm"></a> So to
+ create the first <span class="quote">“<span class="quote">ordinary</span>”</span> database you can connect to
+ <code class="literal">postgres</code>.
+ </p><p>
+ Two additional databases,
+ <code class="literal">template1</code><a id="id-1.6.10.5.7.2" class="indexterm"></a>
+ and
+ <code class="literal">template0</code>,<a id="id-1.6.10.5.7.4" class="indexterm"></a>
+ are also created during database cluster initialization. Whenever a
+ new database is created within the
+ cluster, <code class="literal">template1</code> is essentially cloned.
+ This means that any changes you make in <code class="literal">template1</code> are
+ propagated to all subsequently created databases. Because of this,
+ avoid creating objects in <code class="literal">template1</code> unless you want them
+ propagated to every newly created database.
+ <code class="literal">template0</code> is meant as a pristine copy of the original
+ contents of <code class="literal">template1</code>. It can be cloned instead
+ of <code class="literal">template1</code> when it is important to make a database
+ without any such site-local additions. More details
+ appear in <a class="xref" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Section 23.3</a>.
+ </p><p>
+ As a convenience, there is a program you can
+ execute from the shell to create new databases,
+ <code class="command">createdb</code>.<a id="id-1.6.10.5.8.2" class="indexterm"></a>
+
+</p><pre class="synopsis">
+createdb <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+
+ <code class="command">createdb</code> does no magic. It connects to the <code class="literal">postgres</code>
+ database and issues the <code class="command">CREATE DATABASE</code> command,
+ exactly as described above.
+ The <a class="xref" href="app-createdb.html" title="createdb"><span class="refentrytitle"><span class="application">createdb</span></span></a> reference page contains the invocation
+ details. Note that <code class="command">createdb</code> without any arguments will create
+ a database with the current user name.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a> contains information about
+ how to restrict who can connect to a given database.
+ </p></div><p>
+ Sometimes you want to create a database for someone else, and have them
+ become the owner of the new database, so they can
+ configure and manage it themselves. To achieve that, use one of the
+ following commands:
+</p><pre class="programlisting">
+CREATE DATABASE <em class="replaceable"><code>dbname</code></em> OWNER <em class="replaceable"><code>rolename</code></em>;
+</pre><p>
+ from the SQL environment, or:
+</p><pre class="programlisting">
+createdb -O <em class="replaceable"><code>rolename</code></em> <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+ from the shell.
+ Only the superuser is allowed to create a database for
+ someone else (that is, for a role you are not a member of).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manage-ag-overview.html" title="23.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Next</a></td></tr><tr><td width="40%" align="left" valign="top">23.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 23.3. Template Databases</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/manage-ag-dropdb.html b/doc/src/sgml/html/manage-ag-dropdb.html
new file mode 100644
index 0000000..0959df3
--- /dev/null
+++ b/doc/src/sgml/html/manage-ag-dropdb.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>23.5. Destroying a Database</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="manage-ag-config.html" title="23.4. Database Configuration" /><link rel="next" href="manage-ag-tablespaces.html" title="23.6. Tablespaces" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">23.5. Destroying a Database</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="manage-ag-config.html" title="23.4. Database Configuration">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><th width="60%" align="center">Chapter 23. Managing Databases</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Next</a></td></tr></table><hr /></div><div class="sect1" id="MANAGE-AG-DROPDB"><div class="titlepage"><div><div><h2 class="title" style="clear: both">23.5. Destroying a Database</h2></div></div></div><p>
+ Databases are destroyed with the command
+ <a class="xref" href="sql-dropdatabase.html" title="DROP DATABASE"><span class="refentrytitle">DROP DATABASE</span></a>:<a id="id-1.6.10.8.2.2" class="indexterm"></a>
+</p><pre class="synopsis">
+DROP DATABASE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ Only the owner of the database, or
+ a superuser, can drop a database. Dropping a database removes all objects
+ that were
+ contained within the database. The destruction of a database cannot
+ be undone.
+ </p><p>
+ You cannot execute the <code class="command">DROP DATABASE</code> command
+ while connected to the victim database. You can, however, be
+ connected to any other database, including the <code class="literal">template1</code>
+ database.
+ <code class="literal">template1</code> would be the only option for dropping the last user database of a
+ given cluster.
+ </p><p>
+ For convenience, there is also a shell program to drop
+ databases, <a class="xref" href="app-dropdb.html" title="dropdb"><span class="refentrytitle"><span class="application">dropdb</span></span></a>:<a id="id-1.6.10.8.4.2" class="indexterm"></a>
+</p><pre class="synopsis">
+dropdb <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+ (Unlike <code class="command">createdb</code>, it is not the default action to drop
+ the database with the current user name.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manage-ag-config.html" title="23.4. Database Configuration">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Next</a></td></tr><tr><td width="40%" align="left" valign="top">23.4. Database Configuration </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 23.6. Tablespaces</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/manage-ag-overview.html b/doc/src/sgml/html/manage-ag-overview.html
new file mode 100644
index 0000000..ff2e08d
--- /dev/null
+++ b/doc/src/sgml/html/manage-ag-overview.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>23.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="managing-databases.html" title="Chapter 23. Managing Databases" /><link rel="next" href="manage-ag-createdb.html" title="23.2. Creating a Database" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">23.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="managing-databases.html" title="Chapter 23. Managing Databases">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><th width="60%" align="center">Chapter 23. Managing Databases</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="manage-ag-createdb.html" title="23.2. Creating a Database">Next</a></td></tr></table><hr /></div><div class="sect1" id="MANAGE-AG-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">23.1. Overview</h2></div></div></div><a id="id-1.6.10.4.2" class="indexterm"></a><p>
+ A small number of objects, like role, database, and tablespace
+ names, are defined at the cluster level and stored in the
+ <code class="literal">pg_global</code> tablespace. Inside the cluster are
+ multiple databases, which are isolated from each other but can access
+ cluster-level objects. Inside each database are multiple schemas,
+ which contain objects like tables and functions. So the full hierarchy
+ is: cluster, database, schema, table (or some other kind of object,
+ such as a function).
+ </p><p>
+ When connecting to the database server, a client must specify the
+ database name in its connection request.
+ It is not possible to access more than one database per
+ connection. However, clients can open multiple connections to
+ the same database, or different databases.
+ Database-level security has two components: access control
+ (see <a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a>), managed at the
+ connection level, and authorization control
+ (see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>), managed via the grant system.
+ Foreign data wrappers (see <a class="xref" href="postgres-fdw.html" title="F.38. postgres_fdw">postgres_fdw</a>)
+ allow for objects within one database to act as proxies for objects in
+ other database or clusters.
+ The older dblink module (see <a class="xref" href="dblink.html" title="F.12. dblink">dblink</a>) provides a similar capability.
+ By default, all users can connect to all databases using all connection methods.
+ </p><p>
+ If one <span class="productname">PostgreSQL</span> server cluster is planned to contain
+ unrelated projects or users that should be, for the most part, unaware
+ of each other, it is recommended to put them into separate databases and
+ adjust authorizations and access controls accordingly.
+ If the projects or users are interrelated, and thus should be able to use
+ each other's resources, they should be put in the same database but probably
+ into separate schemas; this provides a modular structure with namespace
+ isolation and authorization control.
+ More information about managing schemas is in <a class="xref" href="ddl-schemas.html" title="5.9. Schemas">Section 5.9</a>.
+ </p><p>
+ While multiple databases can be created within a single cluster, it is advised
+ to consider carefully whether the benefits outweigh the risks and limitations.
+ In particular, the impact that having a shared WAL (see <a class="xref" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Chapter 30</a>)
+ has on backup and recovery options. While individual databases in the cluster
+ are isolated when considered from the user's perspective, they are closely bound
+ from the database administrator's point-of-view.
+ </p><p>
+ Databases are created with the <code class="command">CREATE DATABASE</code> command
+ (see <a class="xref" href="manage-ag-createdb.html" title="23.2. Creating a Database">Section 23.2</a>) and destroyed with the
+ <code class="command">DROP DATABASE</code> command
+ (see <a class="xref" href="manage-ag-dropdb.html" title="23.5. Destroying a Database">Section 23.5</a>).
+ To determine the set of existing databases, examine the
+ <code class="structname">pg_database</code> system catalog, for example
+</p><pre class="synopsis">
+SELECT datname FROM pg_database;
+</pre><p>
+ The <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> program's <code class="literal">\l</code> meta-command
+ and <code class="option">-l</code> command-line option are also useful for listing the
+ existing databases.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <acronym class="acronym">SQL</acronym> standard calls databases <span class="quote">“<span class="quote">catalogs</span>”</span>, but there
+ is no difference in practice.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="managing-databases.html" title="Chapter 23. Managing Databases">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="manage-ag-createdb.html" title="23.2. Creating a Database">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 23. Managing Databases </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 23.2. Creating a Database</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/manage-ag-tablespaces.html b/doc/src/sgml/html/manage-ag-tablespaces.html
new file mode 100644
index 0000000..f9a3c13
--- /dev/null
+++ b/doc/src/sgml/html/manage-ag-tablespaces.html
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>23.6. Tablespaces</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="manage-ag-dropdb.html" title="23.5. Destroying a Database" /><link rel="next" href="charset.html" title="Chapter 24. Localization" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">23.6. Tablespaces</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="manage-ag-dropdb.html" title="23.5. Destroying a Database">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><th width="60%" align="center">Chapter 23. Managing Databases</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="charset.html" title="Chapter 24. Localization">Next</a></td></tr></table><hr /></div><div class="sect1" id="MANAGE-AG-TABLESPACES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">23.6. Tablespaces</h2></div></div></div><a id="id-1.6.10.9.2" class="indexterm"></a><p>
+ Tablespaces in <span class="productname">PostgreSQL</span> allow database administrators to
+ define locations in the file system where the files representing
+ database objects can be stored. Once created, a tablespace can be referred
+ to by name when creating database objects.
+ </p><p>
+ By using tablespaces, an administrator can control the disk layout
+ of a <span class="productname">PostgreSQL</span> installation. This is useful in at
+ least two ways. First, if the partition or volume on which the
+ cluster was initialized runs out of space and cannot be extended,
+ a tablespace can be created on a different partition and used
+ until the system can be reconfigured.
+ </p><p>
+ Second, tablespaces allow an administrator to use knowledge of the
+ usage pattern of database objects to optimize performance. For
+ example, an index which is very heavily used can be placed on a
+ very fast, highly available disk, such as an expensive solid state
+ device. At the same time a table storing archived data which is
+ rarely used or not performance critical could be stored on a less
+ expensive, slower disk system.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ Even though located outside the main PostgreSQL data directory,
+ tablespaces are an integral part of the database cluster and
+ <span class="emphasis"><em>cannot</em></span> be treated as an autonomous collection
+ of data files. They are dependent on metadata contained in the main
+ data directory, and therefore cannot be attached to a different
+ database cluster or backed up individually. Similarly, if you lose
+ a tablespace (file deletion, disk failure, etc.), the database cluster
+ might become unreadable or unable to start. Placing a tablespace
+ on a temporary file system like a RAM disk risks the reliability of
+ the entire cluster.
+ </p></div><p>
+ To define a tablespace, use the <a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a>
+ command, for example:<a id="id-1.6.10.9.7.2" class="indexterm"></a>:
+</p><pre class="programlisting">
+CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
+</pre><p>
+ The location must be an existing, empty directory that is owned by
+ the <span class="productname">PostgreSQL</span> operating system user. All objects subsequently
+ created within the tablespace will be stored in files underneath this
+ directory. The location must not be on removable or transient storage,
+ as the cluster might fail to function if the tablespace is missing
+ or lost.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ There is usually not much point in making more than one
+ tablespace per logical file system, since you cannot control the location
+ of individual files within a logical file system. However,
+ <span class="productname">PostgreSQL</span> does not enforce any such limitation, and
+ indeed it is not directly aware of the file system boundaries on your
+ system. It just stores files in the directories you tell it to use.
+ </p></div><p>
+ Creation of the tablespace itself must be done as a database superuser,
+ but after that you can allow ordinary database users to use it.
+ To do that, grant them the <code class="literal">CREATE</code> privilege on it.
+ </p><p>
+ Tables, indexes, and entire databases can be assigned to
+ particular tablespaces. To do so, a user with the <code class="literal">CREATE</code>
+ privilege on a given tablespace must pass the tablespace name as a
+ parameter to the relevant command. For example, the following creates
+ a table in the tablespace <code class="literal">space1</code>:
+</p><pre class="programlisting">
+CREATE TABLE foo(i int) TABLESPACE space1;
+</pre><p>
+ </p><p>
+ Alternatively, use the <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> parameter:
+</p><pre class="programlisting">
+SET default_tablespace = space1;
+CREATE TABLE foo(i int);
+</pre><p>
+ When <code class="varname">default_tablespace</code> is set to anything but an empty
+ string, it supplies an implicit <code class="literal">TABLESPACE</code> clause for
+ <code class="command">CREATE TABLE</code> and <code class="command">CREATE INDEX</code> commands that
+ do not have an explicit one.
+ </p><p>
+ There is also a <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> parameter, which
+ determines the placement of temporary tables and indexes, as well as
+ temporary files that are used for purposes such as sorting large data
+ sets. This can be a list of tablespace names, rather than only one,
+ so that the load associated with temporary objects can be spread over
+ multiple tablespaces. A random member of the list is picked each time
+ a temporary object is to be created.
+ </p><p>
+ The tablespace associated with a database is used to store the system
+ catalogs of that database. Furthermore, it is the default tablespace
+ used for tables, indexes, and temporary files created within the database,
+ if no <code class="literal">TABLESPACE</code> clause is given and no other selection is
+ specified by <code class="varname">default_tablespace</code> or
+ <code class="varname">temp_tablespaces</code> (as appropriate).
+ If a database is created without specifying a tablespace for it,
+ it uses the same tablespace as the template database it is copied from.
+ </p><p>
+ Two tablespaces are automatically created when the database cluster
+ is initialized. The
+ <code class="literal">pg_global</code> tablespace is used for shared system catalogs. The
+ <code class="literal">pg_default</code> tablespace is the default tablespace of the
+ <code class="literal">template1</code> and <code class="literal">template0</code> databases (and, therefore,
+ will be the default tablespace for other databases as well, unless
+ overridden by a <code class="literal">TABLESPACE</code> clause in <code class="command">CREATE
+ DATABASE</code>).
+ </p><p>
+ Once created, a tablespace can be used from any database, provided
+ the requesting user has sufficient privilege. This means that a tablespace
+ cannot be dropped until all objects in all databases using the tablespace
+ have been removed.
+ </p><p>
+ To remove an empty tablespace, use the <a class="xref" href="sql-droptablespace.html" title="DROP TABLESPACE"><span class="refentrytitle">DROP TABLESPACE</span></a>
+ command.
+ </p><p>
+ To determine the set of existing tablespaces, examine the
+ <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code>
+ </a> system catalog, for example
+</p><pre class="synopsis">
+SELECT spcname FROM pg_tablespace;
+</pre><p>
+ The <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a> program's <code class="literal">\db</code> meta-command
+ is also useful for listing the existing tablespaces.
+ </p><p>
+ <span class="productname">PostgreSQL</span> makes use of symbolic links
+ to simplify the implementation of tablespaces. This
+ means that tablespaces can be used <span class="emphasis"><em>only</em></span> on systems
+ that support symbolic links.
+ </p><p>
+ The directory <code class="filename">$PGDATA/pg_tblspc</code> contains symbolic links that
+ point to each of the non-built-in tablespaces defined in the cluster.
+ Although not recommended, it is possible to adjust the tablespace
+ layout by hand by redefining these links. Under no circumstances perform
+ this operation while the server is running. Note that in PostgreSQL 9.1
+ and earlier you will also need to update the <code class="structname">pg_tablespace</code>
+ catalog with the new locations. (If you do not, <code class="literal">pg_dump</code> will
+ continue to output the old tablespace locations.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manage-ag-dropdb.html" title="23.5. Destroying a Database">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="charset.html" title="Chapter 24. Localization">Next</a></td></tr><tr><td width="40%" align="left" valign="top">23.5. Destroying a Database </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 24. Localization</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/manage-ag-templatedbs.html b/doc/src/sgml/html/manage-ag-templatedbs.html
new file mode 100644
index 0000000..c4bf917
--- /dev/null
+++ b/doc/src/sgml/html/manage-ag-templatedbs.html
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>23.3. Template Databases</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="manage-ag-createdb.html" title="23.2. Creating a Database" /><link rel="next" href="manage-ag-config.html" title="23.4. Database Configuration" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">23.3. Template Databases</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="manage-ag-createdb.html" title="23.2. Creating a Database">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><th width="60%" align="center">Chapter 23. Managing Databases</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="manage-ag-config.html" title="23.4. Database Configuration">Next</a></td></tr></table><hr /></div><div class="sect1" id="MANAGE-AG-TEMPLATEDBS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">23.3. Template Databases</h2></div></div></div><p>
+ <code class="command">CREATE DATABASE</code> actually works by copying an existing
+ database. By default, it copies the standard system database named
+ <code class="literal">template1</code>.<a id="id-1.6.10.6.2.3" class="indexterm"></a> Thus that
+ database is the <span class="quote">“<span class="quote">template</span>”</span> from which new databases are
+ made. If you add objects to <code class="literal">template1</code>, these objects
+ will be copied into subsequently created user databases. This
+ behavior allows site-local modifications to the standard set of
+ objects in databases. For example, if you install the procedural
+ language <span class="application">PL/Perl</span> in <code class="literal">template1</code>, it will
+ automatically be available in user databases without any extra
+ action being taken when those databases are created.
+ </p><p>
+ There is a second standard system database named
+ <code class="literal">template0</code>.<a id="id-1.6.10.6.3.2" class="indexterm"></a> This
+ database contains the same data as the initial contents of
+ <code class="literal">template1</code>, that is, only the standard objects
+ predefined by your version of
+ <span class="productname">PostgreSQL</span>. <code class="literal">template0</code>
+ should never be changed after the database cluster has been
+ initialized. By instructing
+ <code class="command">CREATE DATABASE</code> to copy <code class="literal">template0</code> instead
+ of <code class="literal">template1</code>, you can create a <span class="quote">“<span class="quote">pristine</span>”</span> user
+ database (one where no user-defined objects exist and where the system
+ objects have not been altered) that contains none of the site-local additions in
+ <code class="literal">template1</code>. This is particularly handy when restoring a
+ <code class="literal">pg_dump</code> dump: the dump script should be restored in a
+ pristine database to ensure that one recreates the correct contents
+ of the dumped database, without conflicting with objects that
+ might have been added to <code class="literal">template1</code> later on.
+ </p><p>
+ Another common reason for copying <code class="literal">template0</code> instead
+ of <code class="literal">template1</code> is that new encoding and locale settings
+ can be specified when copying <code class="literal">template0</code>, whereas a copy
+ of <code class="literal">template1</code> must use the same settings it does.
+ This is because <code class="literal">template1</code> might contain encoding-specific
+ or locale-specific data, while <code class="literal">template0</code> is known not to.
+ </p><p>
+ To create a database by copying <code class="literal">template0</code>, use:
+</p><pre class="programlisting">
+CREATE DATABASE <em class="replaceable"><code>dbname</code></em> TEMPLATE template0;
+</pre><p>
+ from the SQL environment, or:
+</p><pre class="programlisting">
+createdb -T template0 <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+ from the shell.
+ </p><p>
+ It is possible to create additional template databases, and indeed
+ one can copy any database in a cluster by specifying its name
+ as the template for <code class="command">CREATE DATABASE</code>. It is important to
+ understand, however, that this is not (yet) intended as
+ a general-purpose <span class="quote">“<span class="quote"><code class="command">COPY DATABASE</code></span>”</span> facility.
+ The principal limitation is that no other sessions can be connected to
+ the source database while it is being copied. <code class="command">CREATE
+ DATABASE</code> will fail if any other connection exists when it starts;
+ during the copy operation, new connections to the source database
+ are prevented.
+ </p><p>
+ Two useful flags exist in <code class="literal">pg_database</code><a id="id-1.6.10.6.7.2" class="indexterm"></a> for each
+ database: the columns <code class="literal">datistemplate</code> and
+ <code class="literal">datallowconn</code>. <code class="literal">datistemplate</code>
+ can be set to indicate that a database is intended as a template for
+ <code class="command">CREATE DATABASE</code>. If this flag is set, the database can be
+ cloned by any user with <code class="literal">CREATEDB</code> privileges; if it is not set,
+ only superusers and the owner of the database can clone it.
+ If <code class="literal">datallowconn</code> is false, then no new connections
+ to that database will be allowed (but existing sessions are not terminated
+ simply by setting the flag false). The <code class="literal">template0</code>
+ database is normally marked <code class="literal">datallowconn = false</code> to prevent its modification.
+ Both <code class="literal">template0</code> and <code class="literal">template1</code>
+ should always be marked with <code class="literal">datistemplate = true</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">template1</code> and <code class="literal">template0</code> do not have any special
+ status beyond the fact that the name <code class="literal">template1</code> is the default
+ source database name for <code class="command">CREATE DATABASE</code>.
+ For example, one could drop <code class="literal">template1</code> and recreate it from
+ <code class="literal">template0</code> without any ill effects. This course of action
+ might be advisable if one has carelessly added a bunch of junk in
+ <code class="literal">template1</code>. (To delete <code class="literal">template1</code>,
+ it must have <code class="literal">pg_database.datistemplate = false</code>.)
+ </p><p>
+ The <code class="literal">postgres</code> database is also created when a database
+ cluster is initialized. This database is meant as a default database for
+ users and applications to connect to. It is simply a copy of
+ <code class="literal">template1</code> and can be dropped and recreated if necessary.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="manage-ag-createdb.html" title="23.2. Creating a Database">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="managing-databases.html" title="Chapter 23. Managing Databases">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="manage-ag-config.html" title="23.4. Database Configuration">Next</a></td></tr><tr><td width="40%" align="left" valign="top">23.2. Creating a Database </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 23.4. Database Configuration</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/managing-databases.html b/doc/src/sgml/html/managing-databases.html
new file mode 100644
index 0000000..b99376b
--- /dev/null
+++ b/doc/src/sgml/html/managing-databases.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 23. Managing Databases</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="perm-functions.html" title="22.6. Function Security" /><link rel="next" href="manage-ag-overview.html" title="23.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 23. Managing Databases</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="perm-functions.html" title="22.6. Function Security">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="manage-ag-overview.html" title="23.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="MANAGING-DATABASES"><div class="titlepage"><div><div><h2 class="title">Chapter 23. Managing Databases</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="manage-ag-overview.html">23.1. Overview</a></span></dt><dt><span class="sect1"><a href="manage-ag-createdb.html">23.2. Creating a Database</a></span></dt><dt><span class="sect1"><a href="manage-ag-templatedbs.html">23.3. Template Databases</a></span></dt><dt><span class="sect1"><a href="manage-ag-config.html">23.4. Database Configuration</a></span></dt><dt><span class="sect1"><a href="manage-ag-dropdb.html">23.5. Destroying a Database</a></span></dt><dt><span class="sect1"><a href="manage-ag-tablespaces.html">23.6. Tablespaces</a></span></dt></dl></div><a id="id-1.6.10.2" class="indexterm"></a><p>
+ Every instance of a running <span class="productname">PostgreSQL</span>
+ server manages one or more databases. Databases are therefore the
+ topmost hierarchical level for organizing <acronym class="acronym">SQL</acronym>
+ objects (<span class="quote">“<span class="quote">database objects</span>”</span>). This chapter describes
+ the properties of databases, and how to create, manage, and destroy
+ them.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="perm-functions.html" title="22.6. Function Security">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="manage-ag-overview.html" title="23.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">22.6. Function Security </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 23.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/monitoring-locks.html b/doc/src/sgml/html/monitoring-locks.html
new file mode 100644
index 0000000..c8d670c
--- /dev/null
+++ b/doc/src/sgml/html/monitoring-locks.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>28.3. Viewing Locks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System" /><link rel="next" href="progress-reporting.html" title="28.4. Progress Reporting" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">28.3. Viewing Locks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><th width="60%" align="center">Chapter 28. Monitoring Database Activity</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="progress-reporting.html" title="28.4. Progress Reporting">Next</a></td></tr></table><hr /></div><div class="sect1" id="MONITORING-LOCKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">28.3. Viewing Locks</h2></div></div></div><a id="id-1.6.15.8.2" class="indexterm"></a><p>
+ Another useful tool for monitoring database activity is the
+ <code class="structname">pg_locks</code> system table. It allows the
+ database administrator to view information about the outstanding
+ locks in the lock manager. For example, this capability can be used
+ to:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ View all the locks currently outstanding, all the locks on
+ relations in a particular database, all the locks on a
+ particular relation, or all the locks held by a particular
+ <span class="productname">PostgreSQL</span> session.
+ </p></li><li class="listitem"><p>
+ Determine the relation in the current database with the most
+ ungranted locks (which might be a source of contention among
+ database clients).
+ </p></li><li class="listitem"><p>
+ Determine the effect of lock contention on overall database
+ performance, as well as the extent to which contention varies
+ with overall database traffic.
+ </p></li></ul></div><p>
+
+ Details of the <code class="structname">pg_locks</code> view appear in
+ <a class="xref" href="view-pg-locks.html" title="54.12. pg_locks">Section 54.12</a>.
+ For more information on locking and managing concurrency with
+ <span class="productname">PostgreSQL</span>, refer to <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="progress-reporting.html" title="28.4. Progress Reporting">Next</a></td></tr><tr><td width="40%" align="left" valign="top">28.2. The Cumulative Statistics System </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 28.4. Progress Reporting</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/monitoring-ps.html b/doc/src/sgml/html/monitoring-ps.html
new file mode 100644
index 0000000..ea5c3ed
--- /dev/null
+++ b/doc/src/sgml/html/monitoring-ps.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>28.1. Standard Unix Tools</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="monitoring.html" title="Chapter 28. Monitoring Database Activity" /><link rel="next" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">28.1. Standard Unix Tools</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><th width="60%" align="center">Chapter 28. Monitoring Database Activity</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">Next</a></td></tr></table><hr /></div><div class="sect1" id="MONITORING-PS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">28.1. Standard Unix Tools</h2></div></div></div><a id="id-1.6.15.6.2" class="indexterm"></a><p>
+ On most Unix platforms, <span class="productname">PostgreSQL</span> modifies its
+ command title as reported by <code class="command">ps</code>, so that individual server
+ processes can readily be identified. A sample display is
+
+</p><pre class="screen">
+$ ps auxww | grep ^postgres
+postgres 15551 0.0 0.1 57536 7132 pts/0 S 18:02 0:00 postgres -i
+postgres 15554 0.0 0.0 57536 1184 ? Ss 18:02 0:00 postgres: background writer
+postgres 15555 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: checkpointer
+postgres 15556 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: walwriter
+postgres 15557 0.0 0.0 58504 2244 ? Ss 18:02 0:00 postgres: autovacuum launcher
+postgres 15582 0.0 0.0 58772 3080 ? Ss 18:04 0:00 postgres: joe runbug 127.0.0.1 idle
+postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl regression [local] SELECT waiting
+postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction
+</pre><p>
+
+ (The appropriate invocation of <code class="command">ps</code> varies across different
+ platforms, as do the details of what is shown. This example is from a
+ recent Linux system.) The first process listed here is the
+ primary server process. The command arguments
+ shown for it are the same ones used when it was launched. The next four
+ processes are background worker processes automatically launched by the
+ primary process. (The <span class="quote">“<span class="quote">autovacuum launcher</span>”</span> process will not
+ be present if you have set the system not to run autovacuum.)
+ Each of the remaining
+ processes is a server process handling one client connection. Each such
+ process sets its command line display in the form
+
+</p><pre class="screen">
+postgres: <em class="replaceable"><code>user</code></em> <em class="replaceable"><code>database</code></em> <em class="replaceable"><code>host</code></em> <em class="replaceable"><code>activity</code></em>
+</pre><p>
+
+ The user, database, and (client) host items remain the same for
+ the life of the client connection, but the activity indicator changes.
+ The activity can be <code class="literal">idle</code> (i.e., waiting for a client command),
+ <code class="literal">idle in transaction</code> (waiting for client inside a <code class="command">BEGIN</code> block),
+ or a command type name such as <code class="literal">SELECT</code>. Also,
+ <code class="literal">waiting</code> is appended if the server process is presently waiting
+ on a lock held by another session. In the above example we can infer
+ that process 15606 is waiting for process 15610 to complete its transaction
+ and thereby release some lock. (Process 15610 must be the blocker, because
+ there is no other active session. In more complicated cases it would be
+ necessary to look into the
+ <a class="link" href="view-pg-locks.html" title="54.12. pg_locks"><code class="structname">pg_locks</code></a>
+ system view to determine who is blocking whom.)
+ </p><p>
+ If <a class="xref" href="runtime-config-logging.html#GUC-CLUSTER-NAME">cluster_name</a> has been configured the
+ cluster name will also be shown in <code class="command">ps</code> output:
+</p><pre class="screen">
+$ psql -c 'SHOW cluster_name'
+ cluster_name
+--------------
+ server1
+(1 row)
+
+$ ps aux|grep server1
+postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: server1: background writer
+...
+</pre><p>
+ </p><p>
+ If you have turned off <a class="xref" href="runtime-config-logging.html#GUC-UPDATE-PROCESS-TITLE">update_process_title</a> then the
+ activity indicator is not updated; the process title is set only once
+ when a new process is launched. On some platforms this saves a measurable
+ amount of per-command overhead; on others it's insignificant.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <span class="productname">Solaris</span> requires special handling. You must
+ use <code class="command">/usr/ucb/ps</code>, rather than
+ <code class="command">/bin/ps</code>. You also must use two <code class="option">w</code>
+ flags, not just one. In addition, your original invocation of the
+ <code class="command">postgres</code> command must have a shorter
+ <code class="command">ps</code> status display than that provided by each
+ server process. If you fail to do all three things, the <code class="command">ps</code>
+ output for each server process will be the original <code class="command">postgres</code>
+ command line.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 28. Monitoring Database Activity </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 28.2. The Cumulative Statistics System</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/monitoring-stats.html b/doc/src/sgml/html/monitoring-stats.html
new file mode 100644
index 0000000..23cde4b
--- /dev/null
+++ b/doc/src/sgml/html/monitoring-stats.html
@@ -0,0 +1,2470 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>28.2. The Cumulative Statistics System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="monitoring-ps.html" title="28.1. Standard Unix Tools" /><link rel="next" href="monitoring-locks.html" title="28.3. Viewing Locks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">28.2. The Cumulative Statistics System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="monitoring-ps.html" title="28.1. Standard Unix Tools">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><th width="60%" align="center">Chapter 28. Monitoring Database Activity</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="monitoring-locks.html" title="28.3. Viewing Locks">Next</a></td></tr></table><hr /></div><div class="sect1" id="MONITORING-STATS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">28.2. The Cumulative Statistics System</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-STATS-SETUP">28.2.1. Statistics Collection Configuration</a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-STATS-VIEWS">28.2.2. Viewing Statistics</a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW">28.2.3. <code class="structname">pg_stat_activity</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW">28.2.4. <code class="structname">pg_stat_replication</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-SLOTS-VIEW">28.2.5. <code class="structname">pg_stat_replication_slots</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-WAL-RECEIVER-VIEW">28.2.6. <code class="structname">pg_stat_wal_receiver</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-RECOVERY-PREFETCH">28.2.7. <code class="structname">pg_stat_recovery_prefetch</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION">28.2.8. <code class="structname">pg_stat_subscription</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS">28.2.9. <code class="structname">pg_stat_subscription_stats</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SSL-VIEW">28.2.10. <code class="structname">pg_stat_ssl</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-GSSAPI-VIEW">28.2.11. <code class="structname">pg_stat_gssapi</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ARCHIVER-VIEW">28.2.12. <code class="structname">pg_stat_archiver</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-BGWRITER-VIEW">28.2.13. <code class="structname">pg_stat_bgwriter</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-WAL-VIEW">28.2.14. <code class="structname">pg_stat_wal</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW">28.2.15. <code class="structname">pg_stat_database</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-CONFLICTS-VIEW">28.2.16. <code class="structname">pg_stat_database_conflicts</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW">28.2.17. <code class="structname">pg_stat_all_tables</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW">28.2.18. <code class="structname">pg_stat_all_indexes</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-TABLES-VIEW">28.2.19. <code class="structname">pg_statio_all_tables</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-INDEXES-VIEW">28.2.20. <code class="structname">pg_statio_all_indexes</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-SEQUENCES-VIEW">28.2.21. <code class="structname">pg_statio_all_sequences</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-USER-FUNCTIONS-VIEW">28.2.22. <code class="structname">pg_stat_user_functions</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SLRU-VIEW">28.2.23. <code class="structname">pg_stat_slru</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">28.2.24. Statistics Functions</a></span></dt></dl></div><a id="id-1.6.15.7.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span>'s <em class="firstterm">cumulative statistics
+ system</em> supports collection and reporting of information about
+ server activity. Presently, accesses to tables and indexes in both
+ disk-block and individual-row terms are counted. The total number of rows
+ in each table, and information about vacuum and analyze actions for each
+ table are also counted. If enabled, calls to user-defined functions and
+ the total time spent in each one are counted as well.
+ </p><p>
+ <span class="productname">PostgreSQL</span> also supports reporting dynamic
+ information about exactly what is going on in the system right now, such as
+ the exact command currently being executed by other server processes, and
+ which other connections exist in the system. This facility is independent
+ of the cumulative statistics system.
+ </p><div class="sect2" id="MONITORING-STATS-SETUP"><div class="titlepage"><div><div><h3 class="title">28.2.1. Statistics Collection Configuration</h3></div></div></div><p>
+ Since collection of statistics adds some overhead to query execution,
+ the system can be configured to collect or not collect information.
+ This is controlled by configuration parameters that are normally set in
+ <code class="filename">postgresql.conf</code>. (See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for
+ details about setting configuration parameters.)
+ </p><p>
+ The parameter <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-ACTIVITIES">track_activities</a> enables monitoring
+ of the current command being executed by any server process.
+ </p><p>
+ The parameter <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-COUNTS">track_counts</a> controls whether
+ cumulative statistics are collected about table and index accesses.
+ </p><p>
+ The parameter <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-FUNCTIONS">track_functions</a> enables tracking of
+ usage of user-defined functions.
+ </p><p>
+ The parameter <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> enables monitoring
+ of block read and write times.
+ </p><p>
+ The parameter <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-WAL-IO-TIMING">track_wal_io_timing</a> enables monitoring
+ of WAL write times.
+ </p><p>
+ Normally these parameters are set in <code class="filename">postgresql.conf</code> so
+ that they apply to all server processes, but it is possible to turn
+ them on or off in individual sessions using the <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> command. (To prevent
+ ordinary users from hiding their activity from the administrator,
+ only superusers are allowed to change these parameters with
+ <code class="command">SET</code>.)
+ </p><p>
+ Cumulative statistics are collected in shared memory. Every
+ <span class="productname">PostgreSQL</span> process collects statistics locally,
+ then updates the shared data at appropriate intervals. When a server,
+ including a physical replica, shuts down cleanly, a permanent copy of the
+ statistics data is stored in the <code class="filename">pg_stat</code> subdirectory,
+ so that statistics can be retained across server restarts. In contrast,
+ when starting from an unclean shutdown (e.g., after an immediate shutdown,
+ a server crash, starting from a base backup, and point-in-time recovery),
+ all statistics counters are reset.
+ </p></div><div class="sect2" id="MONITORING-STATS-VIEWS"><div class="titlepage"><div><div><h3 class="title">28.2.2. Viewing Statistics</h3></div></div></div><p>
+ Several predefined views, listed in <a class="xref" href="monitoring-stats.html#MONITORING-STATS-DYNAMIC-VIEWS-TABLE" title="Table 28.1. Dynamic Statistics Views">Table 28.1</a>, are available to show
+ the current state of the system. There are also several other
+ views, listed in <a class="xref" href="monitoring-stats.html#MONITORING-STATS-VIEWS-TABLE" title="Table 28.2. Collected Statistics Views">Table 28.2</a>, available to show the accumulated
+ statistics. Alternatively, one can
+ build custom views using the underlying cumulative statistics functions, as
+ discussed in <a class="xref" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS" title="28.2.24. Statistics Functions">Section 28.2.24</a>.
+ </p><p>
+ When using the cumulative statistics views and functions to monitor
+ collected data, it is important to realize that the information does not
+ update instantaneously. Each individual server process flushes out
+ accumulated statistics to shared memory just before going idle, but not
+ more frequently than once per <code class="varname">PGSTAT_MIN_INTERVAL</code>
+ milliseconds (1 second unless altered while building the server); so a
+ query or transaction still in progress does not affect the displayed totals
+ and the displayed information lags behind actual activity. However,
+ current-query information collected by <code class="varname">track_activities</code>
+ is always up-to-date.
+ </p><p>
+ Another important point is that when a server process is asked to display
+ any of the accumulated statistics, accessed values are cached until the end
+ of its current transaction in the default configuration. So the statistics
+ will show static information as long as you continue the current
+ transaction. Similarly, information about the current queries of all
+ sessions is collected when any such information is first requested within a
+ transaction, and the same information will be displayed throughout the
+ transaction. This is a feature, not a bug, because it allows you to perform
+ several queries on the statistics and correlate the results without
+ worrying that the numbers are changing underneath you.
+
+ When analyzing statistics interactively, or with expensive queries, the
+ time delta between accesses to individual statistics can lead to
+ significant skew in the cached statistics. To minimize skew,
+ <code class="varname">stats_fetch_consistency</code> can be set to
+ <code class="literal">snapshot</code>, at the price of increased memory usage for
+ caching not-needed statistics data. Conversely, if it's known that
+ statistics are only accessed once, caching accessed statistics is
+ unnecessary and can be avoided by setting
+ <code class="varname">stats_fetch_consistency</code> to <code class="literal">none</code>.
+
+ You can invoke <code class="function">pg_stat_clear_snapshot</code>() to discard the
+ current transaction's statistics snapshot or cached values (if any). The
+ next use of statistical information will (when in snapshot mode) cause a
+ new snapshot to be built or (when in cache mode) accessed statistics to be
+ cached.
+ </p><p>
+ A transaction can also see its own statistics (not yet flushed out to the
+ shared memory statistics) in the views
+ <code class="structname">pg_stat_xact_all_tables</code>,
+ <code class="structname">pg_stat_xact_sys_tables</code>,
+ <code class="structname">pg_stat_xact_user_tables</code>, and
+ <code class="structname">pg_stat_xact_user_functions</code>. These numbers do not act as
+ stated above; instead they update continuously throughout the transaction.
+ </p><p>
+ Some of the information in the dynamic statistics views shown in <a class="xref" href="monitoring-stats.html#MONITORING-STATS-DYNAMIC-VIEWS-TABLE" title="Table 28.1. Dynamic Statistics Views">Table 28.1</a> is security restricted.
+ Ordinary users can only see all the information about their own sessions
+ (sessions belonging to a role that they are a member of). In rows about
+ other sessions, many columns will be null. Note, however, that the
+ existence of a session and its general properties such as its sessions user
+ and database are visible to all users. Superusers and roles with privileges of
+ built-in role <code class="literal">pg_read_all_stats</code> (see also <a class="xref" href="predefined-roles.html" title="22.5. Predefined Roles">Section 22.5</a>) can see all the information about all sessions.
+ </p><div class="table" id="MONITORING-STATS-DYNAMIC-VIEWS-TABLE"><p class="title"><strong>Table 28.1. Dynamic Statistics Views</strong></p><div class="table-contents"><table class="table" summary="Dynamic Statistics Views" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>View Name</th><th>Description</th></tr></thead><tbody><tr><td>
+ <code class="structname">pg_stat_activity</code>
+ <a id="id-1.6.15.7.6.7.2.2.1.1.2" class="indexterm"></a>
+ </td><td>
+ One row per server process, showing information related to
+ the current activity of that process, such as state and current query.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW" title="28.2.3. pg_stat_activity">
+ <code class="structname">pg_stat_activity</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_replication</code><a id="id-1.6.15.7.6.7.2.2.2.1.2" class="indexterm"></a></td><td>One row per WAL sender process, showing statistics about
+ replication to that sender's connected standby server.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW" title="28.2.4. pg_stat_replication">
+ <code class="structname">pg_stat_replication</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_wal_receiver</code><a id="id-1.6.15.7.6.7.2.2.3.1.2" class="indexterm"></a></td><td>Only one row, showing statistics about the WAL receiver from
+ that receiver's connected server.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-WAL-RECEIVER-VIEW" title="28.2.6. pg_stat_wal_receiver">
+ <code class="structname">pg_stat_wal_receiver</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_recovery_prefetch</code><a id="id-1.6.15.7.6.7.2.2.4.1.2" class="indexterm"></a></td><td>Only one row, showing statistics about blocks prefetched during recovery.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-RECOVERY-PREFETCH" title="28.2.7. pg_stat_recovery_prefetch">
+ <code class="structname">pg_stat_recovery_prefetch</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_subscription</code><a id="id-1.6.15.7.6.7.2.2.5.1.2" class="indexterm"></a></td><td>At least one row per subscription, showing information about
+ the subscription workers.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION" title="28.2.8. pg_stat_subscription">
+ <code class="structname">pg_stat_subscription</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_ssl</code><a id="id-1.6.15.7.6.7.2.2.6.1.2" class="indexterm"></a></td><td>One row per connection (regular and replication), showing information about
+ SSL used on this connection.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SSL-VIEW" title="28.2.10. pg_stat_ssl">
+ <code class="structname">pg_stat_ssl</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_gssapi</code><a id="id-1.6.15.7.6.7.2.2.7.1.2" class="indexterm"></a></td><td>One row per connection (regular and replication), showing information about
+ GSSAPI authentication and encryption used on this connection.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-GSSAPI-VIEW" title="28.2.11. pg_stat_gssapi">
+ <code class="structname">pg_stat_gssapi</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_progress_analyze</code><a id="id-1.6.15.7.6.7.2.2.8.1.2" class="indexterm"></a></td><td>One row for each backend (including autovacuum worker processes) running
+ <code class="command">ANALYZE</code>, showing current progress.
+ See <a class="xref" href="progress-reporting.html#ANALYZE-PROGRESS-REPORTING" title="28.4.1. ANALYZE Progress Reporting">Section 28.4.1</a>.
+ </td></tr><tr><td><code class="structname">pg_stat_progress_create_index</code><a id="id-1.6.15.7.6.7.2.2.9.1.2" class="indexterm"></a></td><td>One row for each backend running <code class="command">CREATE INDEX</code> or <code class="command">REINDEX</code>, showing
+ current progress.
+ See <a class="xref" href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING" title="28.4.2. CREATE INDEX Progress Reporting">Section 28.4.2</a>.
+ </td></tr><tr><td><code class="structname">pg_stat_progress_vacuum</code><a id="id-1.6.15.7.6.7.2.2.10.1.2" class="indexterm"></a></td><td>One row for each backend (including autovacuum worker processes) running
+ <code class="command">VACUUM</code>, showing current progress.
+ See <a class="xref" href="progress-reporting.html#VACUUM-PROGRESS-REPORTING" title="28.4.3. VACUUM Progress Reporting">Section 28.4.3</a>.
+ </td></tr><tr><td><code class="structname">pg_stat_progress_cluster</code><a id="id-1.6.15.7.6.7.2.2.11.1.2" class="indexterm"></a></td><td>One row for each backend running
+ <code class="command">CLUSTER</code> or <code class="command">VACUUM FULL</code>, showing current progress.
+ See <a class="xref" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING" title="28.4.4. CLUSTER Progress Reporting">Section 28.4.4</a>.
+ </td></tr><tr><td><code class="structname">pg_stat_progress_basebackup</code><a id="id-1.6.15.7.6.7.2.2.12.1.2" class="indexterm"></a></td><td>One row for each WAL sender process streaming a base backup,
+ showing current progress.
+ See <a class="xref" href="progress-reporting.html#BASEBACKUP-PROGRESS-REPORTING" title="28.4.5. Base Backup Progress Reporting">Section 28.4.5</a>.
+ </td></tr><tr><td><code class="structname">pg_stat_progress_copy</code><a id="id-1.6.15.7.6.7.2.2.13.1.2" class="indexterm"></a></td><td>One row for each backend running <code class="command">COPY</code>, showing current progress.
+ See <a class="xref" href="progress-reporting.html#COPY-PROGRESS-REPORTING" title="28.4.6. COPY Progress Reporting">Section 28.4.6</a>.
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="MONITORING-STATS-VIEWS-TABLE"><p class="title"><strong>Table 28.2. Collected Statistics Views</strong></p><div class="table-contents"><table class="table" summary="Collected Statistics Views" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>View Name</th><th>Description</th></tr></thead><tbody><tr><td><code class="structname">pg_stat_archiver</code><a id="id-1.6.15.7.6.8.2.2.1.1.2" class="indexterm"></a></td><td>One row only, showing statistics about the
+ WAL archiver process's activity. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ARCHIVER-VIEW" title="28.2.12. pg_stat_archiver">
+ <code class="structname">pg_stat_archiver</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_bgwriter</code><a id="id-1.6.15.7.6.8.2.2.2.1.2" class="indexterm"></a></td><td>One row only, showing statistics about the
+ background writer process's activity. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-BGWRITER-VIEW" title="28.2.13. pg_stat_bgwriter">
+ <code class="structname">pg_stat_bgwriter</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_wal</code><a id="id-1.6.15.7.6.8.2.2.3.1.2" class="indexterm"></a></td><td>One row only, showing statistics about WAL activity. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-WAL-VIEW" title="28.2.14. pg_stat_wal">
+ <code class="structname">pg_stat_wal</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_database</code><a id="id-1.6.15.7.6.8.2.2.4.1.2" class="indexterm"></a></td><td>One row per database, showing database-wide statistics. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW" title="28.2.15. pg_stat_database">
+ <code class="structname">pg_stat_database</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_database_conflicts</code><a id="id-1.6.15.7.6.8.2.2.5.1.2" class="indexterm"></a></td><td>
+ One row per database, showing database-wide statistics about
+ query cancels due to conflict with recovery on standby servers.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-CONFLICTS-VIEW" title="28.2.16. pg_stat_database_conflicts">
+ <code class="structname">pg_stat_database_conflicts</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_all_tables</code><a id="id-1.6.15.7.6.8.2.2.6.1.2" class="indexterm"></a></td><td>
+ One row for each table in the current database, showing statistics
+ about accesses to that specific table.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW" title="28.2.17. pg_stat_all_tables">
+ <code class="structname">pg_stat_all_tables</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_sys_tables</code><a id="id-1.6.15.7.6.8.2.2.7.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_stat_all_tables</code>, except that only
+ system tables are shown.</td></tr><tr><td><code class="structname">pg_stat_user_tables</code><a id="id-1.6.15.7.6.8.2.2.8.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_stat_all_tables</code>, except that only user
+ tables are shown.</td></tr><tr><td><code class="structname">pg_stat_xact_all_tables</code><a id="id-1.6.15.7.6.8.2.2.9.1.2" class="indexterm"></a></td><td>Similar to <code class="structname">pg_stat_all_tables</code>, but counts actions
+ taken so far within the current transaction (which are <span class="emphasis"><em>not</em></span>
+ yet included in <code class="structname">pg_stat_all_tables</code> and related views).
+ The columns for numbers of live and dead rows and vacuum and
+ analyze actions are not present in this view.</td></tr><tr><td><code class="structname">pg_stat_xact_sys_tables</code><a id="id-1.6.15.7.6.8.2.2.10.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_stat_xact_all_tables</code>, except that only
+ system tables are shown.</td></tr><tr><td><code class="structname">pg_stat_xact_user_tables</code><a id="id-1.6.15.7.6.8.2.2.11.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_stat_xact_all_tables</code>, except that only
+ user tables are shown.</td></tr><tr><td><code class="structname">pg_stat_all_indexes</code><a id="id-1.6.15.7.6.8.2.2.12.1.2" class="indexterm"></a></td><td>
+ One row for each index in the current database, showing statistics
+ about accesses to that specific index.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW" title="28.2.18. pg_stat_all_indexes">
+ <code class="structname">pg_stat_all_indexes</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_sys_indexes</code><a id="id-1.6.15.7.6.8.2.2.13.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_stat_all_indexes</code>, except that only
+ indexes on system tables are shown.</td></tr><tr><td><code class="structname">pg_stat_user_indexes</code><a id="id-1.6.15.7.6.8.2.2.14.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_stat_all_indexes</code>, except that only
+ indexes on user tables are shown.</td></tr><tr><td><code class="structname">pg_statio_all_tables</code><a id="id-1.6.15.7.6.8.2.2.15.1.2" class="indexterm"></a></td><td>
+ One row for each table in the current database, showing statistics
+ about I/O on that specific table.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-TABLES-VIEW" title="28.2.19. pg_statio_all_tables">
+ <code class="structname">pg_statio_all_tables</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_statio_sys_tables</code><a id="id-1.6.15.7.6.8.2.2.16.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_statio_all_tables</code>, except that only
+ system tables are shown.</td></tr><tr><td><code class="structname">pg_statio_user_tables</code><a id="id-1.6.15.7.6.8.2.2.17.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_statio_all_tables</code>, except that only
+ user tables are shown.</td></tr><tr><td><code class="structname">pg_statio_all_indexes</code><a id="id-1.6.15.7.6.8.2.2.18.1.2" class="indexterm"></a></td><td>
+ One row for each index in the current database,
+ showing statistics about I/O on that specific index.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-INDEXES-VIEW" title="28.2.20. pg_statio_all_indexes">
+ <code class="structname">pg_statio_all_indexes</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_statio_sys_indexes</code><a id="id-1.6.15.7.6.8.2.2.19.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_statio_all_indexes</code>, except that only
+ indexes on system tables are shown.</td></tr><tr><td><code class="structname">pg_statio_user_indexes</code><a id="id-1.6.15.7.6.8.2.2.20.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_statio_all_indexes</code>, except that only
+ indexes on user tables are shown.</td></tr><tr><td><code class="structname">pg_statio_all_sequences</code><a id="id-1.6.15.7.6.8.2.2.21.1.2" class="indexterm"></a></td><td>
+ One row for each sequence in the current database,
+ showing statistics about I/O on that specific sequence.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-SEQUENCES-VIEW" title="28.2.21. pg_statio_all_sequences">
+ <code class="structname">pg_statio_all_sequences</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_statio_sys_sequences</code><a id="id-1.6.15.7.6.8.2.2.22.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_statio_all_sequences</code>, except that only
+ system sequences are shown. (Presently, no system sequences are defined,
+ so this view is always empty.)</td></tr><tr><td><code class="structname">pg_statio_user_sequences</code><a id="id-1.6.15.7.6.8.2.2.23.1.2" class="indexterm"></a></td><td>Same as <code class="structname">pg_statio_all_sequences</code>, except that only
+ user sequences are shown.</td></tr><tr><td><code class="structname">pg_stat_user_functions</code><a id="id-1.6.15.7.6.8.2.2.24.1.2" class="indexterm"></a></td><td>
+ One row for each tracked function, showing statistics
+ about executions of that function. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-USER-FUNCTIONS-VIEW" title="28.2.22. pg_stat_user_functions">
+ <code class="structname">pg_stat_user_functions</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_xact_user_functions</code><a id="id-1.6.15.7.6.8.2.2.25.1.2" class="indexterm"></a></td><td>Similar to <code class="structname">pg_stat_user_functions</code>, but counts only
+ calls during the current transaction (which are <span class="emphasis"><em>not</em></span>
+ yet included in <code class="structname">pg_stat_user_functions</code>).</td></tr><tr><td><code class="structname">pg_stat_slru</code><a id="id-1.6.15.7.6.8.2.2.26.1.2" class="indexterm"></a></td><td>One row per SLRU, showing statistics of operations. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SLRU-VIEW" title="28.2.23. pg_stat_slru">
+ <code class="structname">pg_stat_slru</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_replication_slots</code><a id="id-1.6.15.7.6.8.2.2.27.1.2" class="indexterm"></a></td><td>One row per replication slot, showing statistics about the
+ replication slot's usage. See
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-SLOTS-VIEW" title="28.2.5. pg_stat_replication_slots">
+ <code class="structname">pg_stat_replication_slots</code></a> for details.
+ </td></tr><tr><td><code class="structname">pg_stat_subscription_stats</code><a id="id-1.6.15.7.6.8.2.2.28.1.2" class="indexterm"></a></td><td>One row per subscription, showing statistics about errors.
+ See <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS" title="28.2.9. pg_stat_subscription_stats">
+ <code class="structname">pg_stat_subscription_stats</code></a> for details.
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The per-index statistics are particularly useful to determine which
+ indexes are being used and how effective they are.
+ </p><p>
+ The <code class="structname">pg_statio_</code> views are primarily useful to
+ determine the effectiveness of the buffer cache. When the number
+ of actual disk reads is much smaller than the number of buffer
+ hits, then the cache is satisfying most read requests without
+ invoking a kernel call. However, these statistics do not give the
+ entire story: due to the way in which <span class="productname">PostgreSQL</span>
+ handles disk I/O, data that is not in the
+ <span class="productname">PostgreSQL</span> buffer cache might still reside in the
+ kernel's I/O cache, and might therefore still be fetched without
+ requiring a physical read. Users interested in obtaining more
+ detailed information on <span class="productname">PostgreSQL</span> I/O behavior are
+ advised to use the <span class="productname">PostgreSQL</span> statistics views
+ in combination with operating system utilities that allow insight
+ into the kernel's handling of I/O.
+ </p></div><div class="sect2" id="MONITORING-PG-STAT-ACTIVITY-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.3. <code class="structname">pg_stat_activity</code></h3></div></div></div><a id="id-1.6.15.7.7.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_activity</code> view will have one row
+ per server process, showing information related to
+ the current activity of that process.
+ </p><div class="table" id="PG-STAT-ACTIVITY-VIEW"><p class="title"><strong>Table 28.3. <code class="structname">pg_stat_activity</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_activity View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the database this backend is connected to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the database this backend is connected to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of this backend
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">leader_pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of the parallel group leader, if this process is a
+ parallel query worker. <code class="literal">NULL</code> if this process is a
+ parallel group leader or does not participate in parallel query.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usesysid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the user logged into this backend
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usename</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the user logged into this backend
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">application_name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the application that is connected
+ to this backend
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_addr</code> <code class="type">inet</code>
+ </p>
+ <p>
+ IP address of the client connected to this backend.
+ If this field is null, it indicates either that the client is
+ connected via a Unix socket on the server machine or that this is an
+ internal process such as autovacuum.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_hostname</code> <code class="type">text</code>
+ </p>
+ <p>
+ Host name of the connected client, as reported by a
+ reverse DNS lookup of <code class="structfield">client_addr</code>. This field will
+ only be non-null for IP connections, and only when <a class="xref" href="runtime-config-logging.html#GUC-LOG-HOSTNAME">log_hostname</a> is enabled.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_port</code> <code class="type">integer</code>
+ </p>
+ <p>
+ TCP port number that the client is using for communication
+ with this backend, or <code class="literal">-1</code> if a Unix socket is used.
+ If this field is null, it indicates that this is an internal server process.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backend_start</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time when this process was started. For client backends,
+ this is the time the client connected to the server.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">xact_start</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time when this process' current transaction was started, or null
+ if no transaction is active. If the current
+ query is the first of its transaction, this column is equal to the
+ <code class="structfield">query_start</code> column.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">query_start</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time when the currently active query was started, or if
+ <code class="structfield">state</code> is not <code class="literal">active</code>, when the last query
+ was started
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">state_change</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time when the <code class="structfield">state</code> was last changed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wait_event_type</code> <code class="type">text</code>
+ </p>
+ <p>
+ The type of event for which the backend is waiting, if any;
+ otherwise NULL. See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-TABLE" title="Table 28.4. Wait Event Types">Table 28.4</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wait_event</code> <code class="type">text</code>
+ </p>
+ <p>
+ Wait event name if backend is currently waiting, otherwise NULL.
+ See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-ACTIVITY-TABLE" title="Table 28.5. Wait Events of Type Activity">Table 28.5</a> through
+ <a class="xref" href="monitoring-stats.html#WAIT-EVENT-TIMEOUT-TABLE" title="Table 28.13. Wait Events of Type Timeout">Table 28.13</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">state</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current overall state of this backend.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">active</code>: The backend is executing a query.
+ </p></li><li class="listitem"><p>
+ <code class="literal">idle</code>: The backend is waiting for a new client command.
+ </p></li><li class="listitem"><p>
+ <code class="literal">idle in transaction</code>: The backend is in a transaction,
+ but is not currently executing a query.
+ </p></li><li class="listitem"><p>
+ <code class="literal">idle in transaction (aborted)</code>: This state is similar to
+ <code class="literal">idle in transaction</code>, except one of the statements in
+ the transaction caused an error.
+ </p></li><li class="listitem"><p>
+ <code class="literal">fastpath function call</code>: The backend is executing a
+ fast-path function.
+ </p></li><li class="listitem"><p>
+ <code class="literal">disabled</code>: This state is reported if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-ACTIVITIES">track_activities</a> is disabled in this backend.
+ </p></li></ul></div><p>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backend_xid</code> <code class="type">xid</code>
+ </p>
+ <p>
+ Top-level transaction identifier of this backend, if any.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backend_xmin</code> <code class="type">xid</code>
+ </p>
+ <p>
+ The current backend's <code class="literal">xmin</code> horizon.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">query_id</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Identifier of this backend's most recent query. If
+ <code class="structfield">state</code> is <code class="literal">active</code> this
+ field shows the identifier of the currently executing query. In
+ all other states, it shows the identifier of last query that was
+ executed. Query identifiers are not computed by default so this
+ field will be null unless <a class="xref" href="runtime-config-statistics.html#GUC-COMPUTE-QUERY-ID">compute_query_id</a>
+ parameter is enabled or a third-party module that computes query
+ identifiers is configured.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">query</code> <code class="type">text</code>
+ </p>
+ <p>
+ Text of this backend's most recent query. If
+ <code class="structfield">state</code> is <code class="literal">active</code> this field shows the
+ currently executing query. In all other states, it shows the last query
+ that was executed. By default the query text is truncated at 1024
+ bytes; this value can be changed via the parameter
+ <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-ACTIVITY-QUERY-SIZE">track_activity_query_size</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backend_type</code> <code class="type">text</code>
+ </p>
+ <p>
+ Type of current backend. Possible types are
+ <code class="literal">autovacuum launcher</code>, <code class="literal">autovacuum worker</code>,
+ <code class="literal">logical replication launcher</code>,
+ <code class="literal">logical replication worker</code>,
+ <code class="literal">parallel worker</code>, <code class="literal">background writer</code>,
+ <code class="literal">client backend</code>, <code class="literal">checkpointer</code>,
+ <code class="literal">archiver</code>,
+ <code class="literal">startup</code>, <code class="literal">walreceiver</code>,
+ <code class="literal">walsender</code> and <code class="literal">walwriter</code>.
+ In addition, background workers registered by extensions may have
+ additional types.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="structfield">wait_event</code> and <code class="structfield">state</code> columns are
+ independent. If a backend is in the <code class="literal">active</code> state,
+ it may or may not be <code class="literal">waiting</code> on some event. If the state
+ is <code class="literal">active</code> and <code class="structfield">wait_event</code> is non-null, it
+ means that a query is being executed, but is being blocked somewhere
+ in the system.
+ </p></div><div class="table" id="WAIT-EVENT-TABLE"><p class="title"><strong>Table 28.4. Wait Event Types</strong></p><div class="table-contents"><table class="table" summary="Wait Event Types" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Wait Event Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">Activity</code></td><td>The server process is idle. This event type indicates a process
+ waiting for activity in its main processing loop.
+ <code class="literal">wait_event</code> will identify the specific wait point;
+ see <a class="xref" href="monitoring-stats.html#WAIT-EVENT-ACTIVITY-TABLE" title="Table 28.5. Wait Events of Type Activity">Table 28.5</a>.
+ </td></tr><tr><td><code class="literal">BufferPin</code></td><td>The server process is waiting for exclusive access to
+ a data buffer. Buffer pin waits can be protracted if
+ another process holds an open cursor that last read data from the
+ buffer in question. See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-BUFFERPIN-TABLE" title="Table 28.6. Wait Events of Type BufferPin">Table 28.6</a>.
+ </td></tr><tr><td><code class="literal">Client</code></td><td>The server process is waiting for activity on a socket
+ connected to a user application. Thus, the server expects something
+ to happen that is independent of its internal processes.
+ <code class="literal">wait_event</code> will identify the specific wait point;
+ see <a class="xref" href="monitoring-stats.html#WAIT-EVENT-CLIENT-TABLE" title="Table 28.7. Wait Events of Type Client">Table 28.7</a>.
+ </td></tr><tr><td><code class="literal">Extension</code></td><td>The server process is waiting for some condition defined by an
+ extension module.
+ See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-EXTENSION-TABLE" title="Table 28.8. Wait Events of Type Extension">Table 28.8</a>.
+ </td></tr><tr><td><code class="literal">IO</code></td><td>The server process is waiting for an I/O operation to complete.
+ <code class="literal">wait_event</code> will identify the specific wait point;
+ see <a class="xref" href="monitoring-stats.html#WAIT-EVENT-IO-TABLE" title="Table 28.9. Wait Events of Type IO">Table 28.9</a>.
+ </td></tr><tr><td><code class="literal">IPC</code></td><td>The server process is waiting for some interaction with
+ another server process. <code class="literal">wait_event</code> will
+ identify the specific wait point;
+ see <a class="xref" href="monitoring-stats.html#WAIT-EVENT-IPC-TABLE" title="Table 28.10. Wait Events of Type IPC">Table 28.10</a>.
+ </td></tr><tr><td><code class="literal">Lock</code></td><td>The server process is waiting for a heavyweight lock.
+ Heavyweight locks, also known as lock manager locks or simply locks,
+ primarily protect SQL-visible objects such as tables. However,
+ they are also used to ensure mutual exclusion for certain internal
+ operations such as relation extension. <code class="literal">wait_event</code>
+ will identify the type of lock awaited;
+ see <a class="xref" href="monitoring-stats.html#WAIT-EVENT-LOCK-TABLE" title="Table 28.11. Wait Events of Type Lock">Table 28.11</a>.
+ </td></tr><tr><td><code class="literal">LWLock</code></td><td> The server process is waiting for a lightweight lock.
+ Most such locks protect a particular data structure in shared memory.
+ <code class="literal">wait_event</code> will contain a name identifying the purpose
+ of the lightweight lock. (Some locks have specific names; others
+ are part of a group of locks each with a similar purpose.)
+ See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-LWLOCK-TABLE" title="Table 28.12. Wait Events of Type LWLock">Table 28.12</a>.
+ </td></tr><tr><td><code class="literal">Timeout</code></td><td>The server process is waiting for a timeout
+ to expire. <code class="literal">wait_event</code> will identify the specific wait
+ point; see <a class="xref" href="monitoring-stats.html#WAIT-EVENT-TIMEOUT-TABLE" title="Table 28.13. Wait Events of Type Timeout">Table 28.13</a>.
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-ACTIVITY-TABLE"><p class="title"><strong>Table 28.5. Wait Events of Type <code class="literal">Activity</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type Activity" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">Activity</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">ArchiverMain</code></td><td>Waiting in main loop of archiver process.</td></tr><tr><td><code class="literal">AutoVacuumMain</code></td><td>Waiting in main loop of autovacuum launcher process.</td></tr><tr><td><code class="literal">BgWriterHibernate</code></td><td>Waiting in background writer process, hibernating.</td></tr><tr><td><code class="literal">BgWriterMain</code></td><td>Waiting in main loop of background writer process.</td></tr><tr><td><code class="literal">CheckpointerMain</code></td><td>Waiting in main loop of checkpointer process.</td></tr><tr><td><code class="literal">LogicalApplyMain</code></td><td>Waiting in main loop of logical replication apply process.</td></tr><tr><td><code class="literal">LogicalLauncherMain</code></td><td>Waiting in main loop of logical replication launcher process.</td></tr><tr><td><code class="literal">RecoveryWalStream</code></td><td>Waiting in main loop of startup process for WAL to arrive, during
+ streaming recovery.</td></tr><tr><td><code class="literal">SysLoggerMain</code></td><td>Waiting in main loop of syslogger process.</td></tr><tr><td><code class="literal">WalReceiverMain</code></td><td>Waiting in main loop of WAL receiver process.</td></tr><tr><td><code class="literal">WalSenderMain</code></td><td>Waiting in main loop of WAL sender process.</td></tr><tr><td><code class="literal">WalWriterMain</code></td><td>Waiting in main loop of WAL writer process.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-BUFFERPIN-TABLE"><p class="title"><strong>Table 28.6. Wait Events of Type <code class="literal">BufferPin</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type BufferPin" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">BufferPin</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">BufferPin</code></td><td>Waiting to acquire an exclusive pin on a buffer.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-CLIENT-TABLE"><p class="title"><strong>Table 28.7. Wait Events of Type <code class="literal">Client</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type Client" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">Client</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">ClientRead</code></td><td>Waiting to read data from the client.</td></tr><tr><td><code class="literal">ClientWrite</code></td><td>Waiting to write data to the client.</td></tr><tr><td><code class="literal">GSSOpenServer</code></td><td>Waiting to read data from the client while establishing a GSSAPI
+ session.</td></tr><tr><td><code class="literal">LibPQWalReceiverConnect</code></td><td>Waiting in WAL receiver to establish connection to remote
+ server.</td></tr><tr><td><code class="literal">LibPQWalReceiverReceive</code></td><td>Waiting in WAL receiver to receive data from remote server.</td></tr><tr><td><code class="literal">SSLOpenServer</code></td><td>Waiting for SSL while attempting connection.</td></tr><tr><td><code class="literal">WalSenderWaitForWAL</code></td><td>Waiting for WAL to be flushed in WAL sender process.</td></tr><tr><td><code class="literal">WalSenderWriteData</code></td><td>Waiting for any activity when processing replies from WAL
+ receiver in WAL sender process.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-EXTENSION-TABLE"><p class="title"><strong>Table 28.8. Wait Events of Type <code class="literal">Extension</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type Extension" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">Extension</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">Extension</code></td><td>Waiting in an extension.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-IO-TABLE"><p class="title"><strong>Table 28.9. Wait Events of Type <code class="literal">IO</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type IO" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">IO</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">BaseBackupRead</code></td><td>Waiting for base backup to read from a file.</td></tr><tr><td><code class="literal">BaseBackupSync</code></td><td>Waiting for data written by a base backup to reach durable storage.</td></tr><tr><td><code class="literal">BaseBackupWrite</code></td><td>Waiting for base backup to write to a file.</td></tr><tr><td><code class="literal">BufFileRead</code></td><td>Waiting for a read from a buffered file.</td></tr><tr><td><code class="literal">BufFileWrite</code></td><td>Waiting for a write to a buffered file.</td></tr><tr><td><code class="literal">BufFileTruncate</code></td><td>Waiting for a buffered file to be truncated.</td></tr><tr><td><code class="literal">ControlFileRead</code></td><td>Waiting for a read from the <code class="filename">pg_control</code>
+ file.</td></tr><tr><td><code class="literal">ControlFileSync</code></td><td>Waiting for the <code class="filename">pg_control</code> file to reach
+ durable storage.</td></tr><tr><td><code class="literal">ControlFileSyncUpdate</code></td><td>Waiting for an update to the <code class="filename">pg_control</code> file
+ to reach durable storage.</td></tr><tr><td><code class="literal">ControlFileWrite</code></td><td>Waiting for a write to the <code class="filename">pg_control</code>
+ file.</td></tr><tr><td><code class="literal">ControlFileWriteUpdate</code></td><td>Waiting for a write to update the <code class="filename">pg_control</code>
+ file.</td></tr><tr><td><code class="literal">CopyFileRead</code></td><td>Waiting for a read during a file copy operation.</td></tr><tr><td><code class="literal">CopyFileWrite</code></td><td>Waiting for a write during a file copy operation.</td></tr><tr><td><code class="literal">DSMFillZeroWrite</code></td><td>Waiting to fill a dynamic shared memory backing file with
+ zeroes.</td></tr><tr><td><code class="literal">DataFileExtend</code></td><td>Waiting for a relation data file to be extended.</td></tr><tr><td><code class="literal">DataFileFlush</code></td><td>Waiting for a relation data file to reach durable storage.</td></tr><tr><td><code class="literal">DataFileImmediateSync</code></td><td>Waiting for an immediate synchronization of a relation data file to
+ durable storage.</td></tr><tr><td><code class="literal">DataFilePrefetch</code></td><td>Waiting for an asynchronous prefetch from a relation data
+ file.</td></tr><tr><td><code class="literal">DataFileRead</code></td><td>Waiting for a read from a relation data file.</td></tr><tr><td><code class="literal">DataFileSync</code></td><td>Waiting for changes to a relation data file to reach durable storage.</td></tr><tr><td><code class="literal">DataFileTruncate</code></td><td>Waiting for a relation data file to be truncated.</td></tr><tr><td><code class="literal">DataFileWrite</code></td><td>Waiting for a write to a relation data file.</td></tr><tr><td><code class="literal">LockFileAddToDataDirRead</code></td><td>Waiting for a read while adding a line to the data directory lock
+ file.</td></tr><tr><td><code class="literal">LockFileAddToDataDirSync</code></td><td>Waiting for data to reach durable storage while adding a line to the
+ data directory lock file.</td></tr><tr><td><code class="literal">LockFileAddToDataDirWrite</code></td><td>Waiting for a write while adding a line to the data directory
+ lock file.</td></tr><tr><td><code class="literal">LockFileCreateRead</code></td><td>Waiting to read while creating the data directory lock
+ file.</td></tr><tr><td><code class="literal">LockFileCreateSync</code></td><td>Waiting for data to reach durable storage while creating the data
+ directory lock file.</td></tr><tr><td><code class="literal">LockFileCreateWrite</code></td><td>Waiting for a write while creating the data directory lock
+ file.</td></tr><tr><td><code class="literal">LockFileReCheckDataDirRead</code></td><td>Waiting for a read during recheck of the data directory lock
+ file.</td></tr><tr><td><code class="literal">LogicalRewriteCheckpointSync</code></td><td>Waiting for logical rewrite mappings to reach durable storage
+ during a checkpoint.</td></tr><tr><td><code class="literal">LogicalRewriteMappingSync</code></td><td>Waiting for mapping data to reach durable storage during a logical
+ rewrite.</td></tr><tr><td><code class="literal">LogicalRewriteMappingWrite</code></td><td>Waiting for a write of mapping data during a logical
+ rewrite.</td></tr><tr><td><code class="literal">LogicalRewriteSync</code></td><td>Waiting for logical rewrite mappings to reach durable
+ storage.</td></tr><tr><td><code class="literal">LogicalRewriteTruncate</code></td><td>Waiting for truncate of mapping data during a logical
+ rewrite.</td></tr><tr><td><code class="literal">LogicalRewriteWrite</code></td><td>Waiting for a write of logical rewrite mappings.</td></tr><tr><td><code class="literal">RelationMapRead</code></td><td>Waiting for a read of the relation map file.</td></tr><tr><td><code class="literal">RelationMapSync</code></td><td>Waiting for the relation map file to reach durable storage.</td></tr><tr><td><code class="literal">RelationMapWrite</code></td><td>Waiting for a write to the relation map file.</td></tr><tr><td><code class="literal">ReorderBufferRead</code></td><td>Waiting for a read during reorder buffer management.</td></tr><tr><td><code class="literal">ReorderBufferWrite</code></td><td>Waiting for a write during reorder buffer management.</td></tr><tr><td><code class="literal">ReorderLogicalMappingRead</code></td><td>Waiting for a read of a logical mapping during reorder buffer
+ management.</td></tr><tr><td><code class="literal">ReplicationSlotRead</code></td><td>Waiting for a read from a replication slot control file.</td></tr><tr><td><code class="literal">ReplicationSlotRestoreSync</code></td><td>Waiting for a replication slot control file to reach durable storage
+ while restoring it to memory.</td></tr><tr><td><code class="literal">ReplicationSlotSync</code></td><td>Waiting for a replication slot control file to reach durable
+ storage.</td></tr><tr><td><code class="literal">ReplicationSlotWrite</code></td><td>Waiting for a write to a replication slot control file.</td></tr><tr><td><code class="literal">SLRUFlushSync</code></td><td>Waiting for SLRU data to reach durable storage during a checkpoint
+ or database shutdown.</td></tr><tr><td><code class="literal">SLRURead</code></td><td>Waiting for a read of an SLRU page.</td></tr><tr><td><code class="literal">SLRUSync</code></td><td>Waiting for SLRU data to reach durable storage following a page
+ write.</td></tr><tr><td><code class="literal">SLRUWrite</code></td><td>Waiting for a write of an SLRU page.</td></tr><tr><td><code class="literal">SnapbuildRead</code></td><td>Waiting for a read of a serialized historical catalog
+ snapshot.</td></tr><tr><td><code class="literal">SnapbuildSync</code></td><td>Waiting for a serialized historical catalog snapshot to reach
+ durable storage.</td></tr><tr><td><code class="literal">SnapbuildWrite</code></td><td>Waiting for a write of a serialized historical catalog
+ snapshot.</td></tr><tr><td><code class="literal">TimelineHistoryFileSync</code></td><td>Waiting for a timeline history file received via streaming
+ replication to reach durable storage.</td></tr><tr><td><code class="literal">TimelineHistoryFileWrite</code></td><td>Waiting for a write of a timeline history file received via
+ streaming replication.</td></tr><tr><td><code class="literal">TimelineHistoryRead</code></td><td>Waiting for a read of a timeline history file.</td></tr><tr><td><code class="literal">TimelineHistorySync</code></td><td>Waiting for a newly created timeline history file to reach durable
+ storage.</td></tr><tr><td><code class="literal">TimelineHistoryWrite</code></td><td>Waiting for a write of a newly created timeline history
+ file.</td></tr><tr><td><code class="literal">TwophaseFileRead</code></td><td>Waiting for a read of a two phase state file.</td></tr><tr><td><code class="literal">TwophaseFileSync</code></td><td>Waiting for a two phase state file to reach durable storage.</td></tr><tr><td><code class="literal">TwophaseFileWrite</code></td><td>Waiting for a write of a two phase state file.</td></tr><tr><td><code class="literal">VersionFileWrite</code></td><td>Waiting for the version file to be written while creating a database.</td></tr><tr><td><code class="literal">WALBootstrapSync</code></td><td>Waiting for WAL to reach durable storage during
+ bootstrapping.</td></tr><tr><td><code class="literal">WALBootstrapWrite</code></td><td>Waiting for a write of a WAL page during bootstrapping.</td></tr><tr><td><code class="literal">WALCopyRead</code></td><td>Waiting for a read when creating a new WAL segment by copying an
+ existing one.</td></tr><tr><td><code class="literal">WALCopySync</code></td><td>Waiting for a new WAL segment created by copying an existing one to
+ reach durable storage.</td></tr><tr><td><code class="literal">WALCopyWrite</code></td><td>Waiting for a write when creating a new WAL segment by copying an
+ existing one.</td></tr><tr><td><code class="literal">WALInitSync</code></td><td>Waiting for a newly initialized WAL file to reach durable
+ storage.</td></tr><tr><td><code class="literal">WALInitWrite</code></td><td>Waiting for a write while initializing a new WAL file.</td></tr><tr><td><code class="literal">WALRead</code></td><td>Waiting for a read from a WAL file.</td></tr><tr><td><code class="literal">WALSenderTimelineHistoryRead</code></td><td>Waiting for a read from a timeline history file during a walsender
+ timeline command.</td></tr><tr><td><code class="literal">WALSync</code></td><td>Waiting for a WAL file to reach durable storage.</td></tr><tr><td><code class="literal">WALSyncMethodAssign</code></td><td>Waiting for data to reach durable storage while assigning a new
+ WAL sync method.</td></tr><tr><td><code class="literal">WALWrite</code></td><td>Waiting for a write to a WAL file.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-IPC-TABLE"><p class="title"><strong>Table 28.10. Wait Events of Type <code class="literal">IPC</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type IPC" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">IPC</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">AppendReady</code></td><td>Waiting for subplan nodes of an <code class="literal">Append</code> plan
+ node to be ready.</td></tr><tr><td><code class="literal">ArchiveCleanupCommand</code></td><td>Waiting for <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-CLEANUP-COMMAND">archive_cleanup_command</a> to
+ complete.</td></tr><tr><td><code class="literal">ArchiveCommand</code></td><td>Waiting for <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> to
+ complete.</td></tr><tr><td><code class="literal">BackendTermination</code></td><td>Waiting for the termination of another backend.</td></tr><tr><td><code class="literal">BackupWaitWalArchive</code></td><td>Waiting for WAL files required for a backup to be successfully
+ archived.</td></tr><tr><td><code class="literal">BgWorkerShutdown</code></td><td>Waiting for background worker to shut down.</td></tr><tr><td><code class="literal">BgWorkerStartup</code></td><td>Waiting for background worker to start up.</td></tr><tr><td><code class="literal">BtreePage</code></td><td>Waiting for the page number needed to continue a parallel B-tree
+ scan to become available.</td></tr><tr><td><code class="literal">BufferIO</code></td><td>Waiting for buffer I/O to complete.</td></tr><tr><td><code class="literal">CheckpointDone</code></td><td>Waiting for a checkpoint to complete.</td></tr><tr><td><code class="literal">CheckpointStart</code></td><td>Waiting for a checkpoint to start.</td></tr><tr><td><code class="literal">ExecuteGather</code></td><td>Waiting for activity from a child process while
+ executing a <code class="literal">Gather</code> plan node.</td></tr><tr><td><code class="literal">HashBatchAllocate</code></td><td>Waiting for an elected Parallel Hash participant to allocate a hash
+ table.</td></tr><tr><td><code class="literal">HashBatchElect</code></td><td>Waiting to elect a Parallel Hash participant to allocate a hash
+ table.</td></tr><tr><td><code class="literal">HashBatchLoad</code></td><td>Waiting for other Parallel Hash participants to finish loading a
+ hash table.</td></tr><tr><td><code class="literal">HashBuildAllocate</code></td><td>Waiting for an elected Parallel Hash participant to allocate the
+ initial hash table.</td></tr><tr><td><code class="literal">HashBuildElect</code></td><td>Waiting to elect a Parallel Hash participant to allocate the
+ initial hash table.</td></tr><tr><td><code class="literal">HashBuildHashInner</code></td><td>Waiting for other Parallel Hash participants to finish hashing the
+ inner relation.</td></tr><tr><td><code class="literal">HashBuildHashOuter</code></td><td>Waiting for other Parallel Hash participants to finish partitioning
+ the outer relation.</td></tr><tr><td><code class="literal">HashGrowBatchesAllocate</code></td><td>Waiting for an elected Parallel Hash participant to allocate more
+ batches.</td></tr><tr><td><code class="literal">HashGrowBatchesDecide</code></td><td>Waiting to elect a Parallel Hash participant to decide on future
+ batch growth.</td></tr><tr><td><code class="literal">HashGrowBatchesElect</code></td><td>Waiting to elect a Parallel Hash participant to allocate more
+ batches.</td></tr><tr><td><code class="literal">HashGrowBatchesFinish</code></td><td>Waiting for an elected Parallel Hash participant to decide on
+ future batch growth.</td></tr><tr><td><code class="literal">HashGrowBatchesRepartition</code></td><td>Waiting for other Parallel Hash participants to finish
+ repartitioning.</td></tr><tr><td><code class="literal">HashGrowBucketsAllocate</code></td><td>Waiting for an elected Parallel Hash participant to finish
+ allocating more buckets.</td></tr><tr><td><code class="literal">HashGrowBucketsElect</code></td><td>Waiting to elect a Parallel Hash participant to allocate more
+ buckets.</td></tr><tr><td><code class="literal">HashGrowBucketsReinsert</code></td><td>Waiting for other Parallel Hash participants to finish inserting
+ tuples into new buckets.</td></tr><tr><td><code class="literal">LogicalSyncData</code></td><td>Waiting for a logical replication remote server to send data for
+ initial table synchronization.</td></tr><tr><td><code class="literal">LogicalSyncStateChange</code></td><td>Waiting for a logical replication remote server to change
+ state.</td></tr><tr><td><code class="literal">MessageQueueInternal</code></td><td>Waiting for another process to be attached to a shared message
+ queue.</td></tr><tr><td><code class="literal">MessageQueuePutMessage</code></td><td>Waiting to write a protocol message to a shared message queue.</td></tr><tr><td><code class="literal">MessageQueueReceive</code></td><td>Waiting to receive bytes from a shared message queue.</td></tr><tr><td><code class="literal">MessageQueueSend</code></td><td>Waiting to send bytes to a shared message queue.</td></tr><tr><td><code class="literal">ParallelBitmapScan</code></td><td>Waiting for parallel bitmap scan to become initialized.</td></tr><tr><td><code class="literal">ParallelCreateIndexScan</code></td><td>Waiting for parallel <code class="command">CREATE INDEX</code> workers to
+ finish heap scan.</td></tr><tr><td><code class="literal">ParallelFinish</code></td><td>Waiting for parallel workers to finish computing.</td></tr><tr><td><code class="literal">ProcArrayGroupUpdate</code></td><td>Waiting for the group leader to clear the transaction ID at
+ end of a parallel operation.</td></tr><tr><td><code class="literal">ProcSignalBarrier</code></td><td>Waiting for a barrier event to be processed by all
+ backends.</td></tr><tr><td><code class="literal">Promote</code></td><td>Waiting for standby promotion.</td></tr><tr><td><code class="literal">RecoveryConflictSnapshot</code></td><td>Waiting for recovery conflict resolution for a vacuum
+ cleanup.</td></tr><tr><td><code class="literal">RecoveryConflictTablespace</code></td><td>Waiting for recovery conflict resolution for dropping a
+ tablespace.</td></tr><tr><td><code class="literal">RecoveryEndCommand</code></td><td>Waiting for <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-END-COMMAND">recovery_end_command</a> to
+ complete.</td></tr><tr><td><code class="literal">RecoveryPause</code></td><td>Waiting for recovery to be resumed.</td></tr><tr><td><code class="literal">ReplicationOriginDrop</code></td><td>Waiting for a replication origin to become inactive so it can be
+ dropped.</td></tr><tr><td><code class="literal">ReplicationSlotDrop</code></td><td>Waiting for a replication slot to become inactive so it can be
+ dropped.</td></tr><tr><td><code class="literal">RestoreCommand</code></td><td>Waiting for <a class="xref" href="runtime-config-wal.html#GUC-RESTORE-COMMAND">restore_command</a> to
+ complete.</td></tr><tr><td><code class="literal">SafeSnapshot</code></td><td>Waiting to obtain a valid snapshot for a <code class="literal">READ ONLY
+ DEFERRABLE</code> transaction.</td></tr><tr><td><code class="literal">SyncRep</code></td><td>Waiting for confirmation from a remote server during synchronous
+ replication.</td></tr><tr><td><code class="literal">WalReceiverExit</code></td><td>Waiting for the WAL receiver to exit.</td></tr><tr><td><code class="literal">WalReceiverWaitStart</code></td><td>Waiting for startup process to send initial data for streaming
+ replication.</td></tr><tr><td><code class="literal">XactGroupUpdate</code></td><td>Waiting for the group leader to update transaction status at
+ end of a parallel operation.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-LOCK-TABLE"><p class="title"><strong>Table 28.11. Wait Events of Type <code class="literal">Lock</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type Lock" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">Lock</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">advisory</code></td><td>Waiting to acquire an advisory user lock.</td></tr><tr><td><code class="literal">extend</code></td><td>Waiting to extend a relation.</td></tr><tr><td><code class="literal">frozenid</code></td><td>Waiting to
+ update <code class="structname">pg_database</code>.<code class="structfield">datfrozenxid</code>
+ and <code class="structname">pg_database</code>.<code class="structfield">datminmxid</code>.</td></tr><tr><td><code class="literal">object</code></td><td>Waiting to acquire a lock on a non-relation database object.</td></tr><tr><td><code class="literal">page</code></td><td>Waiting to acquire a lock on a page of a relation.</td></tr><tr><td><code class="literal">relation</code></td><td>Waiting to acquire a lock on a relation.</td></tr><tr><td><code class="literal">spectoken</code></td><td>Waiting to acquire a speculative insertion lock.</td></tr><tr><td><code class="literal">transactionid</code></td><td>Waiting for a transaction to finish.</td></tr><tr><td><code class="literal">tuple</code></td><td>Waiting to acquire a lock on a tuple.</td></tr><tr><td><code class="literal">userlock</code></td><td>Waiting to acquire a user lock.</td></tr><tr><td><code class="literal">virtualxid</code></td><td>Waiting to acquire a virtual transaction ID lock.</td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="WAIT-EVENT-LWLOCK-TABLE"><p class="title"><strong>Table 28.12. Wait Events of Type <code class="literal">LWLock</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type LWLock" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">LWLock</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">AddinShmemInit</code></td><td>Waiting to manage an extension's space allocation in shared
+ memory.</td></tr><tr><td><code class="literal">AutoFile</code></td><td>Waiting to update the <code class="filename">postgresql.auto.conf</code>
+ file.</td></tr><tr><td><code class="literal">Autovacuum</code></td><td>Waiting to read or update the current state of autovacuum
+ workers.</td></tr><tr><td><code class="literal">AutovacuumSchedule</code></td><td>Waiting to ensure that a table selected for autovacuum
+ still needs vacuuming.</td></tr><tr><td><code class="literal">BackgroundWorker</code></td><td>Waiting to read or update background worker state.</td></tr><tr><td><code class="literal">BtreeVacuum</code></td><td>Waiting to read or update vacuum-related information for a
+ B-tree index.</td></tr><tr><td><code class="literal">BufferContent</code></td><td>Waiting to access a data page in memory.</td></tr><tr><td><code class="literal">BufferMapping</code></td><td>Waiting to associate a data block with a buffer in the buffer
+ pool.</td></tr><tr><td><code class="literal">CheckpointerComm</code></td><td>Waiting to manage fsync requests.</td></tr><tr><td><code class="literal">CommitTs</code></td><td>Waiting to read or update the last value set for a
+ transaction commit timestamp.</td></tr><tr><td><code class="literal">CommitTsBuffer</code></td><td>Waiting for I/O on a commit timestamp SLRU buffer.</td></tr><tr><td><code class="literal">CommitTsSLRU</code></td><td>Waiting to access the commit timestamp SLRU cache.</td></tr><tr><td><code class="literal">ControlFile</code></td><td>Waiting to read or update the <code class="filename">pg_control</code>
+ file or create a new WAL file.</td></tr><tr><td><code class="literal">DynamicSharedMemoryControl</code></td><td>Waiting to read or update dynamic shared memory allocation
+ information.</td></tr><tr><td><code class="literal">LockFastPath</code></td><td>Waiting to read or update a process' fast-path lock
+ information.</td></tr><tr><td><code class="literal">LockManager</code></td><td>Waiting to read or update information
+ about <span class="quote">“<span class="quote">heavyweight</span>”</span> locks.</td></tr><tr><td><code class="literal">LogicalRepWorker</code></td><td>Waiting to read or update the state of logical replication
+ workers.</td></tr><tr><td><code class="literal">MultiXactGen</code></td><td>Waiting to read or update shared multixact state.</td></tr><tr><td><code class="literal">MultiXactMemberBuffer</code></td><td>Waiting for I/O on a multixact member SLRU buffer.</td></tr><tr><td><code class="literal">MultiXactMemberSLRU</code></td><td>Waiting to access the multixact member SLRU cache.</td></tr><tr><td><code class="literal">MultiXactOffsetBuffer</code></td><td>Waiting for I/O on a multixact offset SLRU buffer.</td></tr><tr><td><code class="literal">MultiXactOffsetSLRU</code></td><td>Waiting to access the multixact offset SLRU cache.</td></tr><tr><td><code class="literal">MultiXactTruncation</code></td><td>Waiting to read or truncate multixact information.</td></tr><tr><td><code class="literal">NotifyBuffer</code></td><td>Waiting for I/O on a <code class="command">NOTIFY</code> message SLRU
+ buffer.</td></tr><tr><td><code class="literal">NotifyQueue</code></td><td>Waiting to read or update <code class="command">NOTIFY</code> messages.</td></tr><tr><td><code class="literal">NotifyQueueTail</code></td><td>Waiting to update limit on <code class="command">NOTIFY</code> message
+ storage.</td></tr><tr><td><code class="literal">NotifySLRU</code></td><td>Waiting to access the <code class="command">NOTIFY</code> message SLRU
+ cache.</td></tr><tr><td><code class="literal">OidGen</code></td><td>Waiting to allocate a new OID.</td></tr><tr><td><code class="literal">OldSnapshotTimeMap</code></td><td>Waiting to read or update old snapshot control information.</td></tr><tr><td><code class="literal">ParallelAppend</code></td><td>Waiting to choose the next subplan during Parallel Append plan
+ execution.</td></tr><tr><td><code class="literal">ParallelHashJoin</code></td><td>Waiting to synchronize workers during Parallel Hash Join plan
+ execution.</td></tr><tr><td><code class="literal">ParallelQueryDSA</code></td><td>Waiting for parallel query dynamic shared memory allocation.</td></tr><tr><td><code class="literal">PerSessionDSA</code></td><td>Waiting for parallel query dynamic shared memory allocation.</td></tr><tr><td><code class="literal">PerSessionRecordType</code></td><td>Waiting to access a parallel query's information about composite
+ types.</td></tr><tr><td><code class="literal">PerSessionRecordTypmod</code></td><td>Waiting to access a parallel query's information about type
+ modifiers that identify anonymous record types.</td></tr><tr><td><code class="literal">PerXactPredicateList</code></td><td>Waiting to access the list of predicate locks held by the current
+ serializable transaction during a parallel query.</td></tr><tr><td><code class="literal">PredicateLockManager</code></td><td>Waiting to access predicate lock information used by
+ serializable transactions.</td></tr><tr><td><code class="literal">ProcArray</code></td><td>Waiting to access the shared per-process data structures
+ (typically, to get a snapshot or report a session's transaction
+ ID).</td></tr><tr><td><code class="literal">RelationMapping</code></td><td>Waiting to read or update
+ a <code class="filename">pg_filenode.map</code> file (used to track the
+ filenode assignments of certain system catalogs).</td></tr><tr><td><code class="literal">RelCacheInit</code></td><td>Waiting to read or update a <code class="filename">pg_internal.init</code>
+ relation cache initialization file.</td></tr><tr><td><code class="literal">ReplicationOrigin</code></td><td>Waiting to create, drop or use a replication origin.</td></tr><tr><td><code class="literal">ReplicationOriginState</code></td><td>Waiting to read or update the progress of one replication
+ origin.</td></tr><tr><td><code class="literal">ReplicationSlotAllocation</code></td><td>Waiting to allocate or free a replication slot.</td></tr><tr><td><code class="literal">ReplicationSlotControl</code></td><td>Waiting to read or update replication slot state.</td></tr><tr><td><code class="literal">ReplicationSlotIO</code></td><td>Waiting for I/O on a replication slot.</td></tr><tr><td><code class="literal">SerialBuffer</code></td><td>Waiting for I/O on a serializable transaction conflict SLRU
+ buffer.</td></tr><tr><td><code class="literal">SerializableFinishedList</code></td><td>Waiting to access the list of finished serializable
+ transactions.</td></tr><tr><td><code class="literal">SerializablePredicateList</code></td><td>Waiting to access the list of predicate locks held by
+ serializable transactions.</td></tr><tr><td><code class="literal">PgStatsDSA</code></td><td>Waiting for stats dynamic shared memory allocator access</td></tr><tr><td><code class="literal">PgStatsHash</code></td><td>Waiting for stats shared memory hash table access</td></tr><tr><td><code class="literal">PgStatsData</code></td><td>Waiting for shared memory stats data access</td></tr><tr><td><code class="literal">SerializableXactHash</code></td><td>Waiting to read or update information about serializable
+ transactions.</td></tr><tr><td><code class="literal">SerialSLRU</code></td><td>Waiting to access the serializable transaction conflict SLRU
+ cache.</td></tr><tr><td><code class="literal">SharedTidBitmap</code></td><td>Waiting to access a shared TID bitmap during a parallel bitmap
+ index scan.</td></tr><tr><td><code class="literal">SharedTupleStore</code></td><td>Waiting to access a shared tuple store during parallel
+ query.</td></tr><tr><td><code class="literal">ShmemIndex</code></td><td>Waiting to find or allocate space in shared memory.</td></tr><tr><td><code class="literal">SInvalRead</code></td><td>Waiting to retrieve messages from the shared catalog invalidation
+ queue.</td></tr><tr><td><code class="literal">SInvalWrite</code></td><td>Waiting to add a message to the shared catalog invalidation
+ queue.</td></tr><tr><td><code class="literal">SubtransBuffer</code></td><td>Waiting for I/O on a sub-transaction SLRU buffer.</td></tr><tr><td><code class="literal">SubtransSLRU</code></td><td>Waiting to access the sub-transaction SLRU cache.</td></tr><tr><td><code class="literal">SyncRep</code></td><td>Waiting to read or update information about the state of
+ synchronous replication.</td></tr><tr><td><code class="literal">SyncScan</code></td><td>Waiting to select the starting location of a synchronized table
+ scan.</td></tr><tr><td><code class="literal">TablespaceCreate</code></td><td>Waiting to create or drop a tablespace.</td></tr><tr><td><code class="literal">TwoPhaseState</code></td><td>Waiting to read or update the state of prepared transactions.</td></tr><tr><td><code class="literal">WALBufMapping</code></td><td>Waiting to replace a page in WAL buffers.</td></tr><tr><td><code class="literal">WALInsert</code></td><td>Waiting to insert WAL data into a memory buffer.</td></tr><tr><td><code class="literal">WALWrite</code></td><td>Waiting for WAL buffers to be written to disk.</td></tr><tr><td><code class="literal">WrapLimitsVacuum</code></td><td>Waiting to update limits on transaction id and multixact
+ consumption.</td></tr><tr><td><code class="literal">XactBuffer</code></td><td>Waiting for I/O on a transaction status SLRU buffer.</td></tr><tr><td><code class="literal">XactSLRU</code></td><td>Waiting to access the transaction status SLRU cache.</td></tr><tr><td><code class="literal">XactTruncation</code></td><td>Waiting to execute <code class="function">pg_xact_status</code> or update
+ the oldest transaction ID available to it.</td></tr><tr><td><code class="literal">XidGen</code></td><td>Waiting to allocate a new transaction ID.</td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ Extensions can add <code class="literal">LWLock</code> types to the list shown in
+ <a class="xref" href="monitoring-stats.html#WAIT-EVENT-LWLOCK-TABLE" title="Table 28.12. Wait Events of Type LWLock">Table 28.12</a>. In some cases, the name
+ assigned by an extension will not be available in all server processes;
+ so an <code class="literal">LWLock</code> wait event might be reported as
+ just <span class="quote">“<span class="quote"><code class="literal">extension</code></span>”</span> rather than the
+ extension-assigned name.
+ </p></div><div class="table" id="WAIT-EVENT-TIMEOUT-TABLE"><p class="title"><strong>Table 28.13. Wait Events of Type <code class="literal">Timeout</code></strong></p><div class="table-contents"><table class="table" summary="Wait Events of Type Timeout" border="1"><colgroup><col /><col /></colgroup><thead><tr><th><code class="literal">Timeout</code> Wait Event</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">BaseBackupThrottle</code></td><td>Waiting during base backup when throttling activity.</td></tr><tr><td><code class="literal">CheckpointWriteDelay</code></td><td>Waiting between writes while performing a checkpoint.</td></tr><tr><td><code class="literal">PgSleep</code></td><td>Waiting due to a call to <code class="function">pg_sleep</code> or
+ a sibling function.</td></tr><tr><td><code class="literal">RecoveryApplyDelay</code></td><td>Waiting to apply WAL during recovery because of a delay
+ setting.</td></tr><tr><td><code class="literal">RecoveryRetrieveRetryInterval</code></td><td>Waiting during recovery when WAL data is not available from any
+ source (<code class="filename">pg_wal</code>, archive or stream).</td></tr><tr><td><code class="literal">RegisterSyncRequest</code></td><td>Waiting while sending synchronization requests to the
+ checkpointer, because the request queue is full.</td></tr><tr><td><code class="literal">VacuumDelay</code></td><td>Waiting in a cost-based vacuum delay point.</td></tr><tr><td><code class="literal">VacuumTruncate</code></td><td>Waiting to acquire an exclusive lock to truncate off any
+ empty pages at the end of a table vacuumed.</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Here is an example of how wait events can be viewed:
+
+</p><pre class="programlisting">
+SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL;
+ pid | wait_event_type | wait_event
+------+-----------------+------------
+ 2540 | Lock | relation
+ 6644 | LWLock | ProcArray
+(2 rows)
+</pre><p>
+ </p></div><div class="sect2" id="MONITORING-PG-STAT-REPLICATION-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.4. <code class="structname">pg_stat_replication</code></h3></div></div></div><a id="id-1.6.15.7.8.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_replication</code> view will contain one row
+ per WAL sender process, showing statistics about replication to that
+ sender's connected standby server. Only directly connected standbys are
+ listed; no information is available about downstream standby servers.
+ </p><div class="table" id="PG-STAT-REPLICATION-VIEW"><p class="title"><strong>Table 28.14. <code class="structname">pg_stat_replication</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_replication View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of a WAL sender process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usesysid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the user logged into this WAL sender process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usename</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the user logged into this WAL sender process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">application_name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the application that is connected
+ to this WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_addr</code> <code class="type">inet</code>
+ </p>
+ <p>
+ IP address of the client connected to this WAL sender.
+ If this field is null, it indicates that the client is
+ connected via a Unix socket on the server machine.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_hostname</code> <code class="type">text</code>
+ </p>
+ <p>
+ Host name of the connected client, as reported by a
+ reverse DNS lookup of <code class="structfield">client_addr</code>. This field will
+ only be non-null for IP connections, and only when <a class="xref" href="runtime-config-logging.html#GUC-LOG-HOSTNAME">log_hostname</a> is enabled.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_port</code> <code class="type">integer</code>
+ </p>
+ <p>
+ TCP port number that the client is using for communication
+ with this WAL sender, or <code class="literal">-1</code> if a Unix socket is used
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backend_start</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time when this process was started, i.e., when the
+ client connected to this WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backend_xmin</code> <code class="type">xid</code>
+ </p>
+ <p>
+ This standby's <code class="literal">xmin</code> horizon reported
+ by <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY-FEEDBACK">hot_standby_feedback</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">state</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current WAL sender state.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">startup</code>: This WAL sender is starting up.
+ </p></li><li class="listitem"><p>
+ <code class="literal">catchup</code>: This WAL sender's connected standby is
+ catching up with the primary.
+ </p></li><li class="listitem"><p>
+ <code class="literal">streaming</code>: This WAL sender is streaming changes
+ after its connected standby server has caught up with the primary.
+ </p></li><li class="listitem"><p>
+ <code class="literal">backup</code>: This WAL sender is sending a backup.
+ </p></li><li class="listitem"><p>
+ <code class="literal">stopping</code>: This WAL sender is stopping.
+ </p></li></ul></div><p>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sent_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location sent on this connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">write_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location written to disk by this standby
+ server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">flush_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location flushed to disk by this standby
+ server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">replay_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location replayed into the database on this
+ standby server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">write_lag</code> <code class="type">interval</code>
+ </p>
+ <p>
+ Time elapsed between flushing recent WAL locally and receiving
+ notification that this standby server has written it (but not yet
+ flushed it or applied it). This can be used to gauge the delay that
+ <code class="literal">synchronous_commit</code> level
+ <code class="literal">remote_write</code> incurred while committing if this
+ server was configured as a synchronous standby.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">flush_lag</code> <code class="type">interval</code>
+ </p>
+ <p>
+ Time elapsed between flushing recent WAL locally and receiving
+ notification that this standby server has written and flushed it
+ (but not yet applied it). This can be used to gauge the delay that
+ <code class="literal">synchronous_commit</code> level
+ <code class="literal">on</code> incurred while committing if this
+ server was configured as a synchronous standby.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">replay_lag</code> <code class="type">interval</code>
+ </p>
+ <p>
+ Time elapsed between flushing recent WAL locally and receiving
+ notification that this standby server has written, flushed and
+ applied it. This can be used to gauge the delay that
+ <code class="literal">synchronous_commit</code> level
+ <code class="literal">remote_apply</code> incurred while committing if this
+ server was configured as a synchronous standby.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sync_priority</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Priority of this standby server for being chosen as the
+ synchronous standby in a priority-based synchronous replication.
+ This has no effect in a quorum-based synchronous replication.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sync_state</code> <code class="type">text</code>
+ </p>
+ <p>
+ Synchronous state of this standby server.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">async</code>: This standby server is asynchronous.
+ </p></li><li class="listitem"><p>
+ <code class="literal">potential</code>: This standby server is now asynchronous,
+ but can potentially become synchronous if one of current
+ synchronous ones fails.
+ </p></li><li class="listitem"><p>
+ <code class="literal">sync</code>: This standby server is synchronous.
+ </p></li><li class="listitem"><p>
+ <code class="literal">quorum</code>: This standby server is considered as a candidate
+ for quorum standbys.
+ </p></li></ul></div><p>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reply_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Send time of last reply message received from standby server
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The lag times reported in the <code class="structname">pg_stat_replication</code>
+ view are measurements of the time taken for recent WAL to be written,
+ flushed and replayed and for the sender to know about it. These times
+ represent the commit delay that was (or would have been) introduced by each
+ synchronous commit level, if the remote server was configured as a
+ synchronous standby. For an asynchronous standby, the
+ <code class="structfield">replay_lag</code> column approximates the delay
+ before recent transactions became visible to queries. If the standby
+ server has entirely caught up with the sending server and there is no more
+ WAL activity, the most recently measured lag times will continue to be
+ displayed for a short time and then show NULL.
+ </p><p>
+ Lag times work automatically for physical replication. Logical decoding
+ plugins may optionally emit tracking messages; if they do not, the tracking
+ mechanism will simply display NULL lag.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The reported lag times are not predictions of how long it will take for
+ the standby to catch up with the sending server assuming the current
+ rate of replay. Such a system would show similar times while new WAL is
+ being generated, but would differ when the sender becomes idle. In
+ particular, when the standby has caught up completely,
+ <code class="structname">pg_stat_replication</code> shows the time taken to
+ write, flush and replay the most recent reported WAL location rather than
+ zero as some users might expect. This is consistent with the goal of
+ measuring synchronous commit and transaction visibility delays for
+ recent write transactions.
+ To reduce confusion for users expecting a different model of lag, the
+ lag columns revert to NULL after a short time on a fully replayed idle
+ system. Monitoring systems should choose whether to represent this
+ as missing data, zero or continue to display the last known value.
+ </p></div></div><div class="sect2" id="MONITORING-PG-STAT-REPLICATION-SLOTS-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.5. <code class="structname">pg_stat_replication_slots</code></h3></div></div></div><a id="id-1.6.15.7.9.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_replication_slots</code> view will contain
+ one row per logical replication slot, showing statistics about its usage.
+ </p><div class="table" id="PG-STAT-REPLICATION-SLOTS-VIEW"><p class="title"><strong>Table 28.15. <code class="structname">pg_stat_replication_slots</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_replication_slots View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">slot_name</code> <code class="type">text</code>
+ </p>
+ <p>
+ A unique, cluster-wide identifier for the replication slot
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spill_txns</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of transactions spilled to disk once the memory used by
+ logical decoding to decode changes from WAL has exceeded
+ <code class="literal">logical_decoding_work_mem</code>. The counter gets
+ incremented for both top-level transactions and subtransactions.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spill_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times transactions were spilled to disk while decoding
+ changes from WAL for this slot. This counter is incremented each time
+ a transaction is spilled, and the same transaction may be spilled
+ multiple times.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">spill_bytes</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Amount of decoded transaction data spilled to disk while performing
+ decoding of changes from WAL for this slot. This and other spill
+ counters can be used to gauge the I/O which occurred during logical
+ decoding and allow tuning <code class="literal">logical_decoding_work_mem</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stream_txns</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of in-progress transactions streamed to the decoding output
+ plugin after the memory used by logical decoding to decode changes
+ from WAL for this slot has exceeded
+ <code class="literal">logical_decoding_work_mem</code>. Streaming only
+ works with top-level transactions (subtransactions can't be streamed
+ independently), so the counter is not incremented for subtransactions.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stream_count</code><code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times in-progress transactions were streamed to the decoding
+ output plugin while decoding changes from WAL for this slot. This
+ counter is incremented each time a transaction is streamed, and the
+ same transaction may be streamed multiple times.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stream_bytes</code><code class="type">bigint</code>
+ </p>
+ <p>
+ Amount of transaction data decoded for streaming in-progress
+ transactions to the decoding output plugin while decoding changes from
+ WAL for this slot. This and other streaming counters for this slot can
+ be used to tune <code class="literal">logical_decoding_work_mem</code>.
+ </p>
+ </td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_txns</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of decoded transactions sent to the decoding output plugin for
+ this slot. This counts top-level transactions only, and is not incremented
+ for subtransactions. Note that this includes the transactions that are
+ streamed and/or spilled.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_bytes</code><code class="type">bigint</code>
+ </p>
+ <p>
+ Amount of transaction data decoded for sending transactions to the
+ decoding output plugin while decoding changes from WAL for this slot.
+ Note that this includes data that is streamed and/or spilled.
+ </p>
+ </td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-WAL-RECEIVER-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.6. <code class="structname">pg_stat_wal_receiver</code></h3></div></div></div><a id="id-1.6.15.7.10.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_wal_receiver</code> view will contain only
+ one row, showing statistics about the WAL receiver from that receiver's
+ connected server.
+ </p><div class="table" id="PG-STAT-WAL-RECEIVER-VIEW"><p class="title"><strong>Table 28.16. <code class="structname">pg_stat_wal_receiver</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_wal_receiver View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of the WAL receiver process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">status</code> <code class="type">text</code>
+ </p>
+ <p>
+ Activity status of the WAL receiver process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">receive_start_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ First write-ahead log location used when WAL receiver is
+ started
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">receive_start_tli</code> <code class="type">integer</code>
+ </p>
+ <p>
+ First timeline number used when WAL receiver is started
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">written_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location already received and written to disk,
+ but not flushed. This should not be used for data integrity checks.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">flushed_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location already received and flushed to
+ disk, the initial value of this field being the first log location used
+ when WAL receiver is started
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">received_tli</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Timeline number of last write-ahead log location received and
+ flushed to disk, the initial value of this field being the timeline
+ number of the first log location used when WAL receiver is started
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_msg_send_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Send time of last message received from origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_msg_receipt_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Receipt time of last message received from origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">latest_end_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location reported to origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">latest_end_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time of last write-ahead log location reported to origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">slot_name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Replication slot name used by this WAL receiver
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sender_host</code> <code class="type">text</code>
+ </p>
+ <p>
+ Host of the <span class="productname">PostgreSQL</span> instance
+ this WAL receiver is connected to. This can be a host name,
+ an IP address, or a directory path if the connection is via
+ Unix socket. (The path case can be distinguished because it
+ will always be an absolute path, beginning with <code class="literal">/</code>.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sender_port</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Port number of the <span class="productname">PostgreSQL</span> instance
+ this WAL receiver is connected to.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conninfo</code> <code class="type">text</code>
+ </p>
+ <p>
+ Connection string used by this WAL receiver,
+ with security-sensitive fields obfuscated.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-RECOVERY-PREFETCH"><div class="titlepage"><div><div><h3 class="title">28.2.7. <code class="structname">pg_stat_recovery_prefetch</code></h3></div></div></div><a id="id-1.6.15.7.11.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_recovery_prefetch</code> view will contain
+ only one row. The columns <code class="structfield">wal_distance</code>,
+ <code class="structfield">block_distance</code> and
+ <code class="structfield">io_depth</code> show current values, and the
+ other columns show cumulative counters that can be reset
+ with the <code class="function">pg_stat_reset_shared</code> function.
+ </p><div class="table" id="PG-STAT-RECOVERY-PREFETCH-VIEW"><p class="title"><strong>Table 28.17. <code class="structname">pg_stat_recovery_prefetch</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_recovery_prefetch View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">prefetch</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks prefetched because they were not in the buffer pool
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks not prefetched because they were already in the buffer pool
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">skip_init</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks not prefetched because they would be zero-initialized
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">skip_new</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks not prefetched because they didn't exist yet
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">skip_fpw</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks not prefetched because a full page image was included in the WAL
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">skip_rep</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks not prefetched because they were already recently prefetched
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">wal_distance</code> <code class="type">int</code>
+ </p>
+ <p>
+ How many bytes ahead the prefetcher is looking
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">block_distance</code> <code class="type">int</code>
+ </p>
+ <p>
+ How many blocks ahead the prefetcher is looking
+ </p>
+ </td></tr><tr><td class="catalog_table_entry">
+ <p class="column_definition">
+ <code class="structfield">io_depth</code> <code class="type">int</code>
+ </p>
+ <p>
+ How many prefetches have been initiated but are not yet known to have completed
+ </p>
+ </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-SUBSCRIPTION"><div class="titlepage"><div><div><h3 class="title">28.2.8. <code class="structname">pg_stat_subscription</code></h3></div></div></div><a id="id-1.6.15.7.12.2" class="indexterm"></a><div class="table" id="PG-STAT-SUBSCRIPTION"><p class="title"><strong>Table 28.18. <code class="structname">pg_stat_subscription</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_subscription View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of the subscription worker process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the relation that the worker is synchronizing; null for the
+ main apply worker
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">received_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location received, the initial value of
+ this field being 0
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_msg_send_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Send time of last message received from origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_msg_receipt_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Receipt time of last message received from origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">latest_end_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ Last write-ahead log location reported to origin WAL sender
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">latest_end_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time of last write-ahead log location reported to origin WAL
+ sender
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-SUBSCRIPTION-STATS"><div class="titlepage"><div><div><h3 class="title">28.2.9. <code class="structname">pg_stat_subscription_stats</code></h3></div></div></div><a id="id-1.6.15.7.13.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_subscription_stats</code> view will contain
+ one row per subscription.
+ </p><div class="table" id="PG-STAT-SUBSCRIPTION-STATS"><p class="title"><strong>Table 28.19. <code class="structname">pg_stat_subscription_stats</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_subscription_stats View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">subname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the subscription
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">apply_error_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times an error occurred while applying changes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sync_error_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times an error occurred during the initial table
+ synchronization
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-SSL-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.10. <code class="structname">pg_stat_ssl</code></h3></div></div></div><a id="id-1.6.15.7.14.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_ssl</code> view will contain one row per
+ backend or WAL sender process, showing statistics about SSL usage on
+ this connection. It can be joined to <code class="structname">pg_stat_activity</code>
+ or <code class="structname">pg_stat_replication</code> on the
+ <code class="structfield">pid</code> column to get more details about the
+ connection.
+ </p><div class="table" id="PG-STAT-SSL-VIEW"><p class="title"><strong>Table 28.20. <code class="structname">pg_stat_ssl</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_ssl View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of a backend or WAL sender process
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ssl</code> <code class="type">boolean</code>
+ </p>
+ <p>
+ True if SSL is used on this connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">version</code> <code class="type">text</code>
+ </p>
+ <p>
+ Version of SSL in use, or NULL if SSL is not in use
+ on this connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cipher</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of SSL cipher in use, or NULL if SSL is not in use
+ on this connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">bits</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Number of bits in the encryption algorithm used, or NULL
+ if SSL is not used on this connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_dn</code> <code class="type">text</code>
+ </p>
+ <p>
+ Distinguished Name (DN) field from the client certificate
+ used, or NULL if no client certificate was supplied or if SSL
+ is not in use on this connection. This field is truncated if the
+ DN field is longer than <code class="symbol">NAMEDATALEN</code> (64 characters
+ in a standard build).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">client_serial</code> <code class="type">numeric</code>
+ </p>
+ <p>
+ Serial number of the client certificate, or NULL if no client
+ certificate was supplied or if SSL is not in use on this connection. The
+ combination of certificate serial number and certificate issuer uniquely
+ identifies a certificate (unless the issuer erroneously reuses serial
+ numbers).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">issuer_dn</code> <code class="type">text</code>
+ </p>
+ <p>
+ DN of the issuer of the client certificate, or NULL if no client
+ certificate was supplied or if SSL is not in use on this connection.
+ This field is truncated like <code class="structfield">client_dn</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-GSSAPI-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.11. <code class="structname">pg_stat_gssapi</code></h3></div></div></div><a id="id-1.6.15.7.15.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_gssapi</code> view will contain one row per
+ backend, showing information about GSSAPI usage on this connection. It can
+ be joined to <code class="structname">pg_stat_activity</code> or
+ <code class="structname">pg_stat_replication</code> on the
+ <code class="structfield">pid</code> column to get more details about the
+ connection.
+ </p><div class="table" id="PG-STAT-GSSAPI-VIEW"><p class="title"><strong>Table 28.21. <code class="structname">pg_stat_gssapi</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_gssapi View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of a backend
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">gss_authenticated</code> <code class="type">boolean</code>
+ </p>
+ <p>
+ True if GSSAPI authentication was used for this connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">principal</code> <code class="type">text</code>
+ </p>
+ <p>
+ Principal used to authenticate this connection, or NULL
+ if GSSAPI was not used to authenticate this connection. This
+ field is truncated if the principal is longer than
+ <code class="symbol">NAMEDATALEN</code> (64 characters in a standard build).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">encrypted</code> <code class="type">boolean</code>
+ </p>
+ <p>
+ True if GSSAPI encryption is in use on this connection
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-ARCHIVER-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.12. <code class="structname">pg_stat_archiver</code></h3></div></div></div><a id="id-1.6.15.7.16.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_archiver</code> view will always have a
+ single row, containing data about the archiver process of the cluster.
+ </p><div class="table" id="PG-STAT-ARCHIVER-VIEW"><p class="title"><strong>Table 28.22. <code class="structname">pg_stat_archiver</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_archiver View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">archived_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of WAL files that have been successfully archived
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_archived_wal</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the WAL file most recently successfully archived
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_archived_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time of the most recent successful archive operation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">failed_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of failed attempts for archiving WAL files
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_failed_wal</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the WAL file of the most recent failed archival operation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_failed_time</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time of the most recent failed archival operation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Normally, WAL files are archived in order, oldest to newest, but that is
+ not guaranteed, and does not hold under special circumstances like when
+ promoting a standby or after crash recovery. Therefore it is not safe to
+ assume that all files older than
+ <code class="structfield">last_archived_wal</code> have also been successfully
+ archived.
+ </p></div><div class="sect2" id="MONITORING-PG-STAT-BGWRITER-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.13. <code class="structname">pg_stat_bgwriter</code></h3></div></div></div><a id="id-1.6.15.7.17.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_bgwriter</code> view will always have a
+ single row, containing global data for the cluster.
+ </p><div class="table" id="PG-STAT-BGWRITER-VIEW"><p class="title"><strong>Table 28.23. <code class="structname">pg_stat_bgwriter</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_bgwriter View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">checkpoints_timed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of scheduled checkpoints that have been performed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">checkpoints_req</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of requested checkpoints that have been performed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">checkpoint_write_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total amount of time that has been spent in the portion of
+ checkpoint processing where files are written to disk, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">checkpoint_sync_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total amount of time that has been spent in the portion of
+ checkpoint processing where files are synchronized to disk, in
+ milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">buffers_checkpoint</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffers written during checkpoints
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">buffers_clean</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffers written by the background writer
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">maxwritten_clean</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times the background writer stopped a cleaning
+ scan because it had written too many buffers
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">buffers_backend</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffers written directly by a backend
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">buffers_backend_fsync</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times a backend had to execute its own
+ <code class="function">fsync</code> call (normally the background writer handles those
+ even when the backend does its own write)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">buffers_alloc</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffers allocated
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-WAL-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.14. <code class="structname">pg_stat_wal</code></h3></div></div></div><a id="id-1.6.15.7.18.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_wal</code> view will always have a
+ single row, containing data about WAL activity of the cluster.
+ </p><div class="table" id="PG-STAT-WAL-VIEW"><p class="title"><strong>Table 28.24. <code class="structname">pg_stat_wal</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_wal View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_records</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of WAL records generated
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_fpi</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of WAL full page images generated
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_bytes</code> <code class="type">numeric</code>
+ </p>
+ <p>
+ Total amount of WAL generated in bytes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_buffers_full</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times WAL data was written to disk because WAL buffers became full
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_write</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times WAL buffers were written out to disk via
+ <code class="function">XLogWrite</code> request.
+ See <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a> for more information about
+ the internal WAL function <code class="function">XLogWrite</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_sync</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times WAL files were synced to disk via
+ <code class="function">issue_xlog_fsync</code> request
+ (if <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a> is <code class="literal">on</code> and
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-SYNC-METHOD">wal_sync_method</a> is either
+ <code class="literal">fdatasync</code>, <code class="literal">fsync</code> or
+ <code class="literal">fsync_writethrough</code>, otherwise zero).
+ See <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a> for more information about
+ the internal WAL function <code class="function">issue_xlog_fsync</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_write_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total amount of time spent writing WAL buffers to disk via
+ <code class="function">XLogWrite</code> request, in milliseconds
+ (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-WAL-IO-TIMING">track_wal_io_timing</a> is enabled,
+ otherwise zero). This includes the sync time when
+ <code class="varname">wal_sync_method</code> is either
+ <code class="literal">open_datasync</code> or <code class="literal">open_sync</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_sync_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total amount of time spent syncing WAL files to disk via
+ <code class="function">issue_xlog_fsync</code> request, in milliseconds
+ (if <code class="varname">track_wal_io_timing</code> is enabled,
+ <code class="varname">fsync</code> is <code class="literal">on</code>, and
+ <code class="varname">wal_sync_method</code> is either
+ <code class="literal">fdatasync</code>, <code class="literal">fsync</code> or
+ <code class="literal">fsync_writethrough</code>, otherwise zero).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-DATABASE-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.15. <code class="structname">pg_stat_database</code></h3></div></div></div><a id="id-1.6.15.7.19.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_database</code> view will contain one row
+ for each database in the cluster, plus one for shared objects, showing
+ database-wide statistics.
+ </p><div class="table" id="PG-STAT-DATABASE-VIEW"><p class="title"><strong>Table 28.25. <code class="structname">pg_stat_database</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_database View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of this database, or 0 for objects belonging to a shared
+ relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this database, or <code class="literal">NULL</code> for shared
+ objects.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">numbackends</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Number of backends currently connected to this database, or
+ <code class="literal">NULL</code> for shared objects. This is the only column
+ in this view that returns a value reflecting current state; all other
+ columns return the accumulated values since the last reset.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">xact_commit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of transactions in this database that have been
+ committed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">xact_rollback</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of transactions in this database that have been
+ rolled back
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times disk blocks were found already in the buffer
+ cache, so that a read was not necessary (this only includes hits in the
+ PostgreSQL buffer cache, not the operating system's file system cache)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tup_returned</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of live rows fetched by sequential scans and index entries returned by index scans in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tup_fetched</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of live rows fetched by index scans in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tup_inserted</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows inserted by queries in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tup_updated</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows updated by queries in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tup_deleted</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows deleted by queries in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">conflicts</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of queries canceled due to conflicts with recovery
+ in this database. (Conflicts occur only on standby servers; see
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-CONFLICTS-VIEW" title="28.2.16. pg_stat_database_conflicts">
+ <code class="structname">pg_stat_database_conflicts</code></a> for details.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temp_files</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of temporary files created by queries in this database.
+ All temporary files are counted, regardless of why the temporary file
+ was created (e.g., sorting or hashing), and regardless of the
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-TEMP-FILES">log_temp_files</a> setting.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temp_bytes</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total amount of data written to temporary files by queries in
+ this database. All temporary files are counted, regardless of why
+ the temporary file was created, and
+ regardless of the <a class="xref" href="runtime-config-logging.html#GUC-LOG-TEMP-FILES">log_temp_files</a> setting.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">deadlocks</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of deadlocks detected in this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">checksum_failures</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of data page checksum failures detected in this
+ database (or on a shared object), or NULL if data checksums are not
+ enabled.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">checksum_last_failure</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which the last data page checksum failure was detected in
+ this database (or on a shared object), or NULL if data checksums are not
+ enabled.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blk_read_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Time spent reading data file blocks by backends in this database,
+ in milliseconds (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blk_write_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Time spent writing data file blocks by backends in this database,
+ in milliseconds (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">session_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Time spent by database sessions in this database, in milliseconds
+ (note that statistics are only updated when the state of a session
+ changes, so if sessions have been idle for a long time, this idle time
+ won't be included)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">active_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Time spent executing SQL statements in this database, in milliseconds
+ (this corresponds to the states <code class="literal">active</code> and
+ <code class="literal">fastpath function call</code> in
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW" title="28.2.3. pg_stat_activity">
+ <code class="structname">pg_stat_activity</code></a>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idle_in_transaction_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Time spent idling while in a transaction in this database, in milliseconds
+ (this corresponds to the states <code class="literal">idle in transaction</code> and
+ <code class="literal">idle in transaction (aborted)</code> in
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW" title="28.2.3. pg_stat_activity">
+ <code class="structname">pg_stat_activity</code></a>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sessions</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of sessions established to this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sessions_abandoned</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of database sessions to this database that were terminated
+ because connection to the client was lost
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sessions_fatal</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of database sessions to this database that were terminated
+ by fatal errors
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sessions_killed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of database sessions to this database that were terminated
+ by operator intervention
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-DATABASE-CONFLICTS-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.16. <code class="structname">pg_stat_database_conflicts</code></h3></div></div></div><a id="id-1.6.15.7.20.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_database_conflicts</code> view will contain
+ one row per database, showing database-wide statistics about
+ query cancels occurring due to conflicts with recovery on standby servers.
+ This view will only contain information on standby servers, since
+ conflicts do not occur on primary servers.
+ </p><div class="table" id="PG-STAT-DATABASE-CONFLICTS-VIEW"><p class="title"><strong>Table 28.26. <code class="structname">pg_stat_database_conflicts</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_database_conflicts View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of a database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this database
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confl_tablespace</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of queries in this database that have been canceled due to
+ dropped tablespaces
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confl_lock</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of queries in this database that have been canceled due to
+ lock timeouts
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confl_snapshot</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of queries in this database that have been canceled due to
+ old snapshots
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confl_bufferpin</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of queries in this database that have been canceled due to
+ pinned buffers
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confl_deadlock</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of queries in this database that have been canceled due to
+ deadlocks
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-ALL-TABLES-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.17. <code class="structname">pg_stat_all_tables</code></h3></div></div></div><a id="id-1.6.15.7.21.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_all_tables</code> view will contain
+ one row for each table in the current database (including TOAST
+ tables), showing statistics about accesses to that specific table. The
+ <code class="structname">pg_stat_user_tables</code> and
+ <code class="structname">pg_stat_sys_tables</code> views
+ contain the same information,
+ but filtered to only show user and system tables respectively.
+ </p><div class="table" id="PG-STAT-ALL-TABLES-VIEW"><p class="title"><strong>Table 28.27. <code class="structname">pg_stat_all_tables</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_all_tables View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of a table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema that this table is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seq_scan</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of sequential scans initiated on this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seq_tup_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of live rows fetched by sequential scans
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_scan</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of index scans initiated on this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_tup_fetch</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of live rows fetched by index scans
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_tup_ins</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows inserted
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_tup_upd</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows updated (includes <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">HOT updated rows</a>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_tup_del</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows deleted
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_tup_hot_upd</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of rows HOT updated (i.e., with no separate index
+ update required)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_live_tup</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Estimated number of live rows
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_dead_tup</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Estimated number of dead rows
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_mod_since_analyze</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Estimated number of rows modified since this table was last analyzed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_ins_since_vacuum</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Estimated number of rows inserted since this table was last vacuumed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_vacuum</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Last time at which this table was manually vacuumed
+ (not counting <code class="command">VACUUM FULL</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_autovacuum</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Last time at which this table was vacuumed by the autovacuum
+ daemon
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_analyze</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Last time at which this table was manually analyzed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_autoanalyze</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Last time at which this table was analyzed by the autovacuum
+ daemon
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">vacuum_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times this table has been manually vacuumed
+ (not counting <code class="command">VACUUM FULL</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">autovacuum_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times this table has been vacuumed by the autovacuum
+ daemon
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">analyze_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times this table has been manually analyzed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">autoanalyze_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times this table has been analyzed by the autovacuum
+ daemon
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-ALL-INDEXES-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.18. <code class="structname">pg_stat_all_indexes</code></h3></div></div></div><a id="id-1.6.15.7.22.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_all_indexes</code> view will contain
+ one row for each index in the current database,
+ showing statistics about accesses to that specific index. The
+ <code class="structname">pg_stat_user_indexes</code> and
+ <code class="structname">pg_stat_sys_indexes</code> views
+ contain the same information,
+ but filtered to only show user and system indexes respectively.
+ </p><div class="table" id="PG-STAT-ALL-INDEXES-VIEW"><p class="title"><strong>Table 28.28. <code class="structname">pg_stat_all_indexes</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_all_indexes View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table for this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexrelid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema this index is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the table for this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexrelname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_scan</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of index scans initiated on this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_tup_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of index entries returned by scans on this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_tup_fetch</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of live table rows fetched by simple index scans using this
+ index
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Indexes can be used by simple index scans, <span class="quote">“<span class="quote">bitmap</span>”</span> index scans,
+ and the optimizer. In a bitmap scan
+ the output of several indexes can be combined via AND or OR rules,
+ so it is difficult to associate individual heap row fetches
+ with specific indexes when a bitmap scan is used. Therefore, a bitmap
+ scan increments the
+ <code class="structname">pg_stat_all_indexes</code>.<code class="structfield">idx_tup_read</code>
+ count(s) for the index(es) it uses, and it increments the
+ <code class="structname">pg_stat_all_tables</code>.<code class="structfield">idx_tup_fetch</code>
+ count for the table, but it does not affect
+ <code class="structname">pg_stat_all_indexes</code>.<code class="structfield">idx_tup_fetch</code>.
+ The optimizer also accesses indexes to check for supplied constants
+ whose values are outside the recorded range of the optimizer statistics
+ because the optimizer statistics might be stale.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="structfield">idx_tup_read</code> and <code class="structfield">idx_tup_fetch</code> counts
+ can be different even without any use of bitmap scans,
+ because <code class="structfield">idx_tup_read</code> counts
+ index entries retrieved from the index while <code class="structfield">idx_tup_fetch</code>
+ counts live rows fetched from the table. The latter will be less if any
+ dead or not-yet-committed rows are fetched using the index, or if any
+ heap fetches are avoided by means of an index-only scan.
+ </p></div></div><div class="sect2" id="MONITORING-PG-STATIO-ALL-TABLES-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.19. <code class="structname">pg_statio_all_tables</code></h3></div></div></div><a id="id-1.6.15.7.23.2" class="indexterm"></a><p>
+ The <code class="structname">pg_statio_all_tables</code> view will contain
+ one row for each table in the current database (including TOAST
+ tables), showing statistics about I/O on that specific table. The
+ <code class="structname">pg_statio_user_tables</code> and
+ <code class="structname">pg_statio_sys_tables</code> views
+ contain the same information,
+ but filtered to only show user and system tables respectively.
+ </p><div class="table" id="PG-STATIO-ALL-TABLES-VIEW"><p class="title"><strong>Table 28.29. <code class="structname">pg_statio_all_tables</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_statio_all_tables View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of a table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema that this table is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read from this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffer hits in this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read from all indexes on this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffer hits in all indexes on this table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">toast_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read from this table's TOAST table (if any)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">toast_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffer hits in this table's TOAST table (if any)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tidx_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read from this table's TOAST table indexes (if any)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tidx_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffer hits in this table's TOAST table indexes (if any)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STATIO-ALL-INDEXES-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.20. <code class="structname">pg_statio_all_indexes</code></h3></div></div></div><a id="id-1.6.15.7.24.2" class="indexterm"></a><p>
+ The <code class="structname">pg_statio_all_indexes</code> view will contain
+ one row for each index in the current database,
+ showing statistics about I/O on that specific index. The
+ <code class="structname">pg_statio_user_indexes</code> and
+ <code class="structname">pg_statio_sys_indexes</code> views
+ contain the same information,
+ but filtered to only show user and system indexes respectively.
+ </p><div class="table" id="PG-STATIO-ALL-INDEXES-VIEW"><p class="title"><strong>Table 28.30. <code class="structname">pg_statio_all_indexes</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_statio_all_indexes View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table for this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexrelid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema this index is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the table for this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexrelname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read from this index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">idx_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffer hits in this index
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STATIO-ALL-SEQUENCES-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.21. <code class="structname">pg_statio_all_sequences</code></h3></div></div></div><a id="id-1.6.15.7.25.2" class="indexterm"></a><p>
+ The <code class="structname">pg_statio_all_sequences</code> view will contain
+ one row for each sequence in the current database,
+ showing statistics about I/O on that specific sequence.
+ </p><div class="table" id="PG-STATIO-ALL-SEQUENCES-VIEW"><p class="title"><strong>Table 28.31. <code class="structname">pg_statio_all_sequences</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_statio_all_sequences View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of a sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema this sequence is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read from this sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of buffer hits in this sequence
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-USER-FUNCTIONS-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.22. <code class="structname">pg_stat_user_functions</code></h3></div></div></div><a id="id-1.6.15.7.26.2" class="indexterm"></a><p>
+ The <code class="structname">pg_stat_user_functions</code> view will contain
+ one row for each tracked function, showing statistics about executions of
+ that function. The <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-FUNCTIONS">track_functions</a> parameter
+ controls exactly which functions are tracked.
+ </p><div class="table" id="PG-STAT-USER-FUNCTIONS-VIEW"><p class="title"><strong>Table 28.32. <code class="structname">pg_stat_user_functions</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_user_functions View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">funcid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of a function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema this function is in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">funcname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of this function
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">calls</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times this function has been called
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent in this function and all other functions
+ called by it, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">self_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent in this function itself, not including
+ other functions called by it, in milliseconds
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-PG-STAT-SLRU-VIEW"><div class="titlepage"><div><div><h3 class="title">28.2.23. <code class="structname">pg_stat_slru</code></h3></div></div></div><a id="id-1.6.15.7.27.2" class="indexterm"></a><a id="id-1.6.15.7.27.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> accesses certain on-disk information
+ via <em class="firstterm">SLRU</em> (simple least-recently-used) caches.
+ The <code class="structname">pg_stat_slru</code> view will contain
+ one row for each tracked SLRU cache, showing statistics about access
+ to cached pages.
+ </p><div class="table" id="PG-STAT-SLRU-VIEW"><p class="title"><strong>Table 28.33. <code class="structname">pg_stat_slru</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_slru View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the SLRU
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_zeroed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks zeroed during initializations
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times disk blocks were found already in the SLRU,
+ so that a read was not necessary (this only includes hits in the
+ SLRU, not the operating system's file system cache)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks read for this SLRU
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_written</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of disk blocks written for this SLRU
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blks_exists</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks checked for existence for this SLRU
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">flushes</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of flushes of dirty data for this SLRU
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">truncates</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of truncates for this SLRU
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which these statistics were last reset
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="MONITORING-STATS-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">28.2.24. Statistics Functions</h3></div></div></div><p>
+ Other ways of looking at the statistics can be set up by writing
+ queries that use the same underlying statistics access functions used by
+ the standard views shown above. For details such as the functions' names,
+ consult the definitions of the standard views. (For example, in
+ <span class="application">psql</span> you could issue <code class="literal">\d+ pg_stat_activity</code>.)
+ The access functions for per-database statistics take a database OID as an
+ argument to identify which database to report on.
+ The per-table and per-index functions take a table or index OID.
+ The functions for per-function statistics take a function OID.
+ Note that only tables, indexes, and functions in the current database
+ can be seen with these functions.
+ </p><p>
+ Additional functions related to the cumulative statistics system are listed
+ in <a class="xref" href="monitoring-stats.html#MONITORING-STATS-FUNCS-TABLE" title="Table 28.34. Additional Statistics Functions">Table 28.34</a>.
+ </p><div class="table" id="MONITORING-STATS-FUNCS-TABLE"><p class="title"><strong>Table 28.34. Additional Statistics Functions</strong></p><div class="table-contents"><table class="table" summary="Additional Statistics Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pg_backend_pid</code> ()
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the process ID of the server process attached to the current
+ session.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_activity</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Returns a record of information about the backend with the specified
+ process ID, or one record for each active backend in the system
+ if <code class="literal">NULL</code> is specified. The fields returned are a
+ subset of those in the <code class="structname">pg_stat_activity</code> view.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_snapshot_timestamp</code> ()
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the timestamp of the current statistics snapshot, or NULL if
+ no statistics snapshot has been taken. A snapshot is taken the first
+ time cumulative statistics are accessed in a transaction if
+ <code class="varname">stats_fetch_consistency</code> is set to
+ <code class="literal">snapshot</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_xact_blocks_fetched</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the number of block read requests for table or index, in the
+ current transaction. This number minus
+ <code class="function">pg_stat_get_xact_blocks_hit</code> gives the number of
+ kernel <code class="function">read()</code> calls; the number of actual
+ physical reads is usually lower due to kernel-level buffering.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_xact_blocks_hit</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">bigint</code>
+ </p>
+ <p>
+ Returns the number of block read requests for table or index, in the
+ current transaction, found in cache (not triggering kernel
+ <code class="function">read()</code> calls).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_clear_snapshot</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Discards the current statistics snapshot or cached information.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset</code> ()
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets all statistics counters for the current database to zero.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset_shared</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets some cluster-wide statistics counters to zero, depending on the
+ argument. The argument can be <code class="literal">bgwriter</code> to reset
+ all the counters shown in
+ the <code class="structname">pg_stat_bgwriter</code>
+ view, <code class="literal">archiver</code> to reset all the counters shown in
+ the <code class="structname">pg_stat_archiver</code> view,
+ <code class="literal">wal</code> to reset all the counters shown in the
+ <code class="structname">pg_stat_wal</code> view or
+ <code class="literal">recovery_prefetch</code> to reset all the counters shown
+ in the <code class="structname">pg_stat_recovery_prefetch</code> view.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset_single_table_counters</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets statistics for a single table or index in the current database
+ or shared across all databases in the cluster to zero.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset_single_function_counters</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets statistics for a single function in the current database to
+ zero.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset_slru</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets statistics to zero for a single SLRU cache, or for all SLRUs in
+ the cluster. If the argument is NULL, all counters shown in
+ the <code class="structname">pg_stat_slru</code> view for all SLRU caches are
+ reset. The argument can be one of
+ <code class="literal">CommitTs</code>,
+ <code class="literal">MultiXactMember</code>,
+ <code class="literal">MultiXactOffset</code>,
+ <code class="literal">Notify</code>,
+ <code class="literal">Serial</code>,
+ <code class="literal">Subtrans</code>, or
+ <code class="literal">Xact</code>
+ to reset the counters for only that entry.
+ If the argument is <code class="literal">other</code> (or indeed, any
+ unrecognized name), then the counters for all other SLRU caches, such
+ as extension-defined caches, are reset.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset_replication_slot</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets statistics of the replication slot defined by the argument. If
+ the argument is <code class="literal">NULL</code>, resets statistics for all
+ the replication slots.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.4.2.2.13.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_reset_subscription_stats</code> ( <code class="type">oid</code> )
+ → <code class="returnvalue">void</code>
+ </p>
+ <p>
+ Resets statistics for a single subscription shown in the
+ <code class="structname">pg_stat_subscription_stats</code> view to zero. If
+ the argument is <code class="literal">NULL</code>, reset statistics for all
+ subscriptions.
+ </p>
+ <p>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="warning"><h3 class="title">Warning</h3><p>
+ Using <code class="function">pg_stat_reset()</code> also resets counters that
+ autovacuum uses to determine when to trigger a vacuum or an analyze.
+ Resetting these counters can cause autovacuum to not perform necessary
+ work, which can cause problems such as table bloat or out-dated
+ table statistics. A database-wide <code class="command">ANALYZE</code> is
+ recommended after the statistics have been reset.
+ </p></div><p>
+ <code class="function">pg_stat_get_activity</code>, the underlying function of
+ the <code class="structname">pg_stat_activity</code> view, returns a set of records
+ containing all the available information about each backend process.
+ Sometimes it may be more convenient to obtain just a subset of this
+ information. In such cases, an older set of per-backend statistics
+ access functions can be used; these are shown in <a class="xref" href="monitoring-stats.html#MONITORING-STATS-BACKEND-FUNCS-TABLE" title="Table 28.35. Per-Backend Statistics Functions">Table 28.35</a>.
+ These access functions use a backend ID number, which ranges from one
+ to the number of currently active backends.
+ The function <code class="function">pg_stat_get_backend_idset</code> provides a
+ convenient way to generate one row for each active backend for
+ invoking these functions. For example, to show the <acronym class="acronym">PID</acronym>s and
+ current queries of all backends:
+
+</p><pre class="programlisting">
+SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
+ pg_stat_get_backend_activity(s.backendid) AS query
+ FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;
+</pre><p>
+ </p><div class="table" id="MONITORING-STATS-BACKEND-FUNCS-TABLE"><p class="title"><strong>Table 28.35. Per-Backend Statistics Functions</strong></p><div class="table-contents"><table class="table" summary="Per-Backend Statistics Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_idset</code> ()
+ → <code class="returnvalue">setof integer</code>
+ </p>
+ <p>
+ Returns the set of currently active backend ID numbers (from 1 to the
+ number of active backends).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_activity</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the text of this backend's most recent query.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_activity_start</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the time when the backend's most recent query was started.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_client_addr</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">inet</code>
+ </p>
+ <p>
+ Returns the IP address of the client connected to this backend.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_client_port</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the TCP port number that the client is using for communication.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_dbid</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Returns the OID of the database this backend is connected to.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.7.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_pid</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Returns the process ID of this backend.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.8.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_start</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the time when this process was started.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.9.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_userid</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">oid</code>
+ </p>
+ <p>
+ Returns the OID of the user logged into this backend.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.10.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_wait_event_type</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the wait event type name if this backend is currently waiting,
+ otherwise NULL. See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-TABLE" title="Table 28.4. Wait Event Types">Table 28.4</a> for details.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.11.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_wait_event</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the wait event name if this backend is currently waiting,
+ otherwise NULL. See <a class="xref" href="monitoring-stats.html#WAIT-EVENT-ACTIVITY-TABLE" title="Table 28.5. Wait Events of Type Activity">Table 28.5</a> through
+ <a class="xref" href="monitoring-stats.html#WAIT-EVENT-TIMEOUT-TABLE" title="Table 28.13. Wait Events of Type Timeout">Table 28.13</a>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.6.15.7.28.7.2.2.12.1.1.1" class="indexterm"></a>
+ <code class="function">pg_stat_get_backend_xact_start</code> ( <code class="type">integer</code> )
+ → <code class="returnvalue">timestamp with time zone</code>
+ </p>
+ <p>
+ Returns the time when the backend's current transaction was started.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="monitoring-ps.html" title="28.1. Standard Unix Tools">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="monitoring-locks.html" title="28.3. Viewing Locks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">28.1. Standard Unix Tools </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 28.3. Viewing Locks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/monitoring.html b/doc/src/sgml/html/monitoring.html
new file mode 100644
index 0000000..12ecc7b
--- /dev/null
+++ b/doc/src/sgml/html/monitoring.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 28. Monitoring Database Activity</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="hot-standby.html" title="27.4. Hot Standby" /><link rel="next" href="monitoring-ps.html" title="28.1. Standard Unix Tools" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 28. Monitoring Database Activity</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="hot-standby.html" title="27.4. Hot Standby">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="monitoring-ps.html" title="28.1. Standard Unix Tools">Next</a></td></tr></table><hr /></div><div class="chapter" id="MONITORING"><div class="titlepage"><div><div><h2 class="title">Chapter 28. Monitoring Database Activity</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="monitoring-ps.html">28.1. Standard Unix Tools</a></span></dt><dt><span class="sect1"><a href="monitoring-stats.html">28.2. The Cumulative Statistics System</a></span></dt><dd><dl><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-STATS-SETUP">28.2.1. Statistics Collection Configuration</a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-STATS-VIEWS">28.2.2. Viewing Statistics</a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW">28.2.3. <code class="structname">pg_stat_activity</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW">28.2.4. <code class="structname">pg_stat_replication</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-SLOTS-VIEW">28.2.5. <code class="structname">pg_stat_replication_slots</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-WAL-RECEIVER-VIEW">28.2.6. <code class="structname">pg_stat_wal_receiver</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-RECOVERY-PREFETCH">28.2.7. <code class="structname">pg_stat_recovery_prefetch</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION">28.2.8. <code class="structname">pg_stat_subscription</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS">28.2.9. <code class="structname">pg_stat_subscription_stats</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SSL-VIEW">28.2.10. <code class="structname">pg_stat_ssl</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-GSSAPI-VIEW">28.2.11. <code class="structname">pg_stat_gssapi</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ARCHIVER-VIEW">28.2.12. <code class="structname">pg_stat_archiver</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-BGWRITER-VIEW">28.2.13. <code class="structname">pg_stat_bgwriter</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-WAL-VIEW">28.2.14. <code class="structname">pg_stat_wal</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW">28.2.15. <code class="structname">pg_stat_database</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-CONFLICTS-VIEW">28.2.16. <code class="structname">pg_stat_database_conflicts</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW">28.2.17. <code class="structname">pg_stat_all_tables</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW">28.2.18. <code class="structname">pg_stat_all_indexes</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-TABLES-VIEW">28.2.19. <code class="structname">pg_statio_all_tables</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-INDEXES-VIEW">28.2.20. <code class="structname">pg_statio_all_indexes</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-SEQUENCES-VIEW">28.2.21. <code class="structname">pg_statio_all_sequences</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-USER-FUNCTIONS-VIEW">28.2.22. <code class="structname">pg_stat_user_functions</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-PG-STAT-SLRU-VIEW">28.2.23. <code class="structname">pg_stat_slru</code></a></span></dt><dt><span class="sect2"><a href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS">28.2.24. Statistics Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="monitoring-locks.html">28.3. Viewing Locks</a></span></dt><dt><span class="sect1"><a href="progress-reporting.html">28.4. Progress Reporting</a></span></dt><dd><dl><dt><span class="sect2"><a href="progress-reporting.html#ANALYZE-PROGRESS-REPORTING">28.4.1. ANALYZE Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING">28.4.2. CREATE INDEX Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#VACUUM-PROGRESS-REPORTING">28.4.3. VACUUM Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING">28.4.4. CLUSTER Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#BASEBACKUP-PROGRESS-REPORTING">28.4.5. Base Backup Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#COPY-PROGRESS-REPORTING">28.4.6. COPY Progress Reporting</a></span></dt></dl></dd><dt><span class="sect1"><a href="dynamic-trace.html">28.5. Dynamic Tracing</a></span></dt><dd><dl><dt><span class="sect2"><a href="dynamic-trace.html#COMPILING-FOR-TRACE">28.5.1. Compiling for Dynamic Tracing</a></span></dt><dt><span class="sect2"><a href="dynamic-trace.html#TRACE-POINTS">28.5.2. Built-in Probes</a></span></dt><dt><span class="sect2"><a href="dynamic-trace.html#USING-TRACE-POINTS">28.5.3. Using Probes</a></span></dt><dt><span class="sect2"><a href="dynamic-trace.html#DEFINING-TRACE-POINTS">28.5.4. Defining New Probes</a></span></dt></dl></dd></dl></div><a id="id-1.6.15.2" class="indexterm"></a><a id="id-1.6.15.3" class="indexterm"></a><p>
+ A database administrator frequently wonders, <span class="quote">“<span class="quote">What is the system
+ doing right now?</span>”</span>
+ This chapter discusses how to find that out.
+ </p><p>
+ Several tools are available for monitoring database activity and
+ analyzing performance. Most of this chapter is devoted to describing
+ <span class="productname">PostgreSQL</span>'s cumulative statistics system,
+ but one should not neglect regular Unix monitoring programs such as
+ <code class="command">ps</code>, <code class="command">top</code>, <code class="command">iostat</code>, and <code class="command">vmstat</code>.
+ Also, once one has identified a
+ poorly-performing query, further investigation might be needed using
+ <span class="productname">PostgreSQL</span>'s <a class="link" href="sql-explain.html" title="EXPLAIN"><code class="command">EXPLAIN</code></a> command.
+ <a class="xref" href="using-explain.html" title="14.1. Using EXPLAIN">Section 14.1</a> discusses <code class="command">EXPLAIN</code>
+ and other methods for understanding the behavior of an individual
+ query.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="hot-standby.html" title="27.4. Hot Standby">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="monitoring-ps.html" title="28.1. Standard Unix Tools">Next</a></td></tr><tr><td width="40%" align="left" valign="top">27.4. Hot Standby </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 28.1. Standard Unix Tools</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/multibyte.html b/doc/src/sgml/html/multibyte.html
new file mode 100644
index 0000000..4629747
--- /dev/null
+++ b/doc/src/sgml/html/multibyte.html
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>24.3. Character Set Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="collation.html" title="24.2. Collation Support" /><link rel="next" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">24.3. Character Set Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="collation.html" title="24.2. Collation Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="charset.html" title="Chapter 24. Localization">Up</a></td><th width="60%" align="center">Chapter 24. Localization</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Next</a></td></tr></table><hr /></div><div class="sect1" id="MULTIBYTE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">24.3. Character Set Support</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED">24.3.1. Supported Character Sets</a></span></dt><dt><span class="sect2"><a href="multibyte.html#id-1.6.11.5.6">24.3.2. Setting the Character Set</a></span></dt><dt><span class="sect2"><a href="multibyte.html#id-1.6.11.5.7">24.3.3. Automatic Character Set Conversion Between Server and Client</a></span></dt><dt><span class="sect2"><a href="multibyte.html#MULTIBYTE-CONVERSIONS-SUPPORTED">24.3.4. Available Character Set Conversions</a></span></dt><dt><span class="sect2"><a href="multibyte.html#id-1.6.11.5.9">24.3.5. Further Reading</a></span></dt></dl></div><a id="id-1.6.11.5.2" class="indexterm"></a><p>
+ The character set support in <span class="productname">PostgreSQL</span>
+ allows you to store text in a variety of character sets (also called
+ encodings), including
+ single-byte character sets such as the ISO 8859 series and
+ multiple-byte character sets such as <acronym class="acronym">EUC</acronym> (Extended Unix
+ Code), UTF-8, and Mule internal code. All supported character sets
+ can be used transparently by clients, but a few are not supported
+ for use within the server (that is, as a server-side encoding).
+ The default character set is selected while
+ initializing your <span class="productname">PostgreSQL</span> database
+ cluster using <code class="command">initdb</code>. It can be overridden when you
+ create a database, so you can have multiple
+ databases each with a different character set.
+ </p><p>
+ An important restriction, however, is that each database's character set
+ must be compatible with the database's <code class="envar">LC_CTYPE</code> (character
+ classification) and <code class="envar">LC_COLLATE</code> (string sort order) locale
+ settings. For <code class="literal">C</code> or
+ <code class="literal">POSIX</code> locale, any character set is allowed, but for other
+ libc-provided locales there is only one character set that will work
+ correctly.
+ (On Windows, however, UTF-8 encoding can be used with any locale.)
+ If you have ICU support configured, ICU-provided locales can be used
+ with most but not all server-side encodings.
+ </p><div class="sect2" id="MULTIBYTE-CHARSET-SUPPORTED"><div class="titlepage"><div><div><h3 class="title">24.3.1. Supported Character Sets</h3></div></div></div><p>
+ <a class="xref" href="multibyte.html#CHARSET-TABLE" title="Table 24.1. PostgreSQL Character Sets">Table 24.1</a> shows the character sets available
+ for use in <span class="productname">PostgreSQL</span>.
+ </p><div class="table" id="CHARSET-TABLE"><p class="title"><strong>Table 24.1. <span class="productname">PostgreSQL</span> Character Sets</strong></p><div class="table-contents"><table class="table" summary="PostgreSQL Character Sets" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /><col class="col6" /><col class="col7" /></colgroup><thead><tr><th>Name</th><th>Description</th><th>Language</th><th>Server?</th><th>ICU?</th><th>Bytes/​Char</th><th>Aliases</th></tr></thead><tbody><tr><td><code class="literal">BIG5</code></td><td>Big Five</td><td>Traditional Chinese</td><td>No</td><td>No</td><td>1–2</td><td><code class="literal">WIN950</code>, <code class="literal">Windows950</code></td></tr><tr><td><code class="literal">EUC_CN</code></td><td>Extended UNIX Code-CN</td><td>Simplified Chinese</td><td>Yes</td><td>Yes</td><td>1–3</td><td> </td></tr><tr><td><code class="literal">EUC_JP</code></td><td>Extended UNIX Code-JP</td><td>Japanese</td><td>Yes</td><td>Yes</td><td>1–3</td><td> </td></tr><tr><td><code class="literal">EUC_JIS_2004</code></td><td>Extended UNIX Code-JP, JIS X 0213</td><td>Japanese</td><td>Yes</td><td>No</td><td>1–3</td><td> </td></tr><tr><td><code class="literal">EUC_KR</code></td><td>Extended UNIX Code-KR</td><td>Korean</td><td>Yes</td><td>Yes</td><td>1–3</td><td> </td></tr><tr><td><code class="literal">EUC_TW</code></td><td>Extended UNIX Code-TW</td><td>Traditional Chinese, Taiwanese</td><td>Yes</td><td>Yes</td><td>1–3</td><td> </td></tr><tr><td><code class="literal">GB18030</code></td><td>National Standard</td><td>Chinese</td><td>No</td><td>No</td><td>1–4</td><td> </td></tr><tr><td><code class="literal">GBK</code></td><td>Extended National Standard</td><td>Simplified Chinese</td><td>No</td><td>No</td><td>1–2</td><td><code class="literal">WIN936</code>, <code class="literal">Windows936</code></td></tr><tr><td><code class="literal">ISO_8859_5</code></td><td>ISO 8859-5, <acronym class="acronym">ECMA</acronym> 113</td><td>Latin/Cyrillic</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">ISO_8859_6</code></td><td>ISO 8859-6, <acronym class="acronym">ECMA</acronym> 114</td><td>Latin/Arabic</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">ISO_8859_7</code></td><td>ISO 8859-7, <acronym class="acronym">ECMA</acronym> 118</td><td>Latin/Greek</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">ISO_8859_8</code></td><td>ISO 8859-8, <acronym class="acronym">ECMA</acronym> 121</td><td>Latin/Hebrew</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">JOHAB</code></td><td><acronym class="acronym">JOHAB</acronym></td><td>Korean (Hangul)</td><td>No</td><td>No</td><td>1–3</td><td> </td></tr><tr><td><code class="literal">KOI8R</code></td><td><acronym class="acronym">KOI</acronym>8-R</td><td>Cyrillic (Russian)</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">KOI8</code></td></tr><tr><td><code class="literal">KOI8U</code></td><td><acronym class="acronym">KOI</acronym>8-U</td><td>Cyrillic (Ukrainian)</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">LATIN1</code></td><td>ISO 8859-1, <acronym class="acronym">ECMA</acronym> 94</td><td>Western European</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO88591</code></td></tr><tr><td><code class="literal">LATIN2</code></td><td>ISO 8859-2, <acronym class="acronym">ECMA</acronym> 94</td><td>Central European</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO88592</code></td></tr><tr><td><code class="literal">LATIN3</code></td><td>ISO 8859-3, <acronym class="acronym">ECMA</acronym> 94</td><td>South European</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO88593</code></td></tr><tr><td><code class="literal">LATIN4</code></td><td>ISO 8859-4, <acronym class="acronym">ECMA</acronym> 94</td><td>North European</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO88594</code></td></tr><tr><td><code class="literal">LATIN5</code></td><td>ISO 8859-9, <acronym class="acronym">ECMA</acronym> 128</td><td>Turkish</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO88599</code></td></tr><tr><td><code class="literal">LATIN6</code></td><td>ISO 8859-10, <acronym class="acronym">ECMA</acronym> 144</td><td>Nordic</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO885910</code></td></tr><tr><td><code class="literal">LATIN7</code></td><td>ISO 8859-13</td><td>Baltic</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO885913</code></td></tr><tr><td><code class="literal">LATIN8</code></td><td>ISO 8859-14</td><td>Celtic</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO885914</code></td></tr><tr><td><code class="literal">LATIN9</code></td><td>ISO 8859-15</td><td>LATIN1 with Euro and accents</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ISO885915</code></td></tr><tr><td><code class="literal">LATIN10</code></td><td>ISO 8859-16, <acronym class="acronym">ASRO</acronym> SR 14111</td><td>Romanian</td><td>Yes</td><td>No</td><td>1</td><td><code class="literal">ISO885916</code></td></tr><tr><td><code class="literal">MULE_INTERNAL</code></td><td>Mule internal code</td><td>Multilingual Emacs</td><td>Yes</td><td>No</td><td>1–4</td><td> </td></tr><tr><td><code class="literal">SJIS</code></td><td>Shift JIS</td><td>Japanese</td><td>No</td><td>No</td><td>1–2</td><td><code class="literal">Mskanji</code>, <code class="literal">ShiftJIS</code>, <code class="literal">WIN932</code>, <code class="literal">Windows932</code></td></tr><tr><td><code class="literal">SHIFT_JIS_2004</code></td><td>Shift JIS, JIS X 0213</td><td>Japanese</td><td>No</td><td>No</td><td>1–2</td><td> </td></tr><tr><td><code class="literal">SQL_ASCII</code></td><td>unspecified (see text)</td><td><span class="emphasis"><em>any</em></span></td><td>Yes</td><td>No</td><td>1</td><td> </td></tr><tr><td><code class="literal">UHC</code></td><td>Unified Hangul Code</td><td>Korean</td><td>No</td><td>No</td><td>1–2</td><td><code class="literal">WIN949</code>, <code class="literal">Windows949</code></td></tr><tr><td><code class="literal">UTF8</code></td><td>Unicode, 8-bit</td><td><span class="emphasis"><em>all</em></span></td><td>Yes</td><td>Yes</td><td>1–4</td><td><code class="literal">Unicode</code></td></tr><tr><td><code class="literal">WIN866</code></td><td>Windows CP866</td><td>Cyrillic</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ALT</code></td></tr><tr><td><code class="literal">WIN874</code></td><td>Windows CP874</td><td>Thai</td><td>Yes</td><td>No</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1250</code></td><td>Windows CP1250</td><td>Central European</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1251</code></td><td>Windows CP1251</td><td>Cyrillic</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">WIN</code></td></tr><tr><td><code class="literal">WIN1252</code></td><td>Windows CP1252</td><td>Western European</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1253</code></td><td>Windows CP1253</td><td>Greek</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1254</code></td><td>Windows CP1254</td><td>Turkish</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1255</code></td><td>Windows CP1255</td><td>Hebrew</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1256</code></td><td>Windows CP1256</td><td>Arabic</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1257</code></td><td>Windows CP1257</td><td>Baltic</td><td>Yes</td><td>Yes</td><td>1</td><td> </td></tr><tr><td><code class="literal">WIN1258</code></td><td>Windows CP1258</td><td>Vietnamese</td><td>Yes</td><td>Yes</td><td>1</td><td><code class="literal">ABC</code>, <code class="literal">TCVN</code>, <code class="literal">TCVN5712</code>, <code class="literal">VSCII</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Not all client <acronym class="acronym">API</acronym>s support all the listed character sets. For example, the
+ <span class="productname">PostgreSQL</span>
+ JDBC driver does not support <code class="literal">MULE_INTERNAL</code>, <code class="literal">LATIN6</code>,
+ <code class="literal">LATIN8</code>, and <code class="literal">LATIN10</code>.
+ </p><p>
+ The <code class="literal">SQL_ASCII</code> setting behaves considerably differently
+ from the other settings. When the server character set is
+ <code class="literal">SQL_ASCII</code>, the server interprets byte values 0–127
+ according to the ASCII standard, while byte values 128–255 are taken
+ as uninterpreted characters. No encoding conversion will be done when
+ the setting is <code class="literal">SQL_ASCII</code>. Thus, this setting is not so
+ much a declaration that a specific encoding is in use, as a declaration
+ of ignorance about the encoding. In most cases, if you are
+ working with any non-ASCII data, it is unwise to use the
+ <code class="literal">SQL_ASCII</code> setting because
+ <span class="productname">PostgreSQL</span> will be unable to help you by
+ converting or validating non-ASCII characters.
+ </p></div><div class="sect2" id="id-1.6.11.5.6"><div class="titlepage"><div><div><h3 class="title">24.3.2. Setting the Character Set</h3></div></div></div><p>
+ <code class="command">initdb</code> defines the default character set (encoding)
+ for a <span class="productname">PostgreSQL</span> cluster. For example,
+
+</p><pre class="screen">
+initdb -E EUC_JP
+</pre><p>
+
+ sets the default character set to
+ <code class="literal">EUC_JP</code> (Extended Unix Code for Japanese). You
+ can use <code class="option">--encoding</code> instead of
+ <code class="option">-E</code> if you prefer longer option strings.
+ If no <code class="option">-E</code> or <code class="option">--encoding</code> option is
+ given, <code class="command">initdb</code> attempts to determine the appropriate
+ encoding to use based on the specified or default locale.
+ </p><p>
+ You can specify a non-default encoding at database creation time,
+ provided that the encoding is compatible with the selected locale:
+
+</p><pre class="screen">
+createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean
+</pre><p>
+
+ This will create a database named <code class="literal">korean</code> that
+ uses the character set <code class="literal">EUC_KR</code>, and locale <code class="literal">ko_KR</code>.
+ Another way to accomplish this is to use this SQL command:
+
+</p><pre class="programlisting">
+CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
+</pre><p>
+
+ Notice that the above commands specify copying the <code class="literal">template0</code>
+ database. When copying any other database, the encoding and locale
+ settings cannot be changed from those of the source database, because
+ that might result in corrupt data. For more information see
+ <a class="xref" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Section 23.3</a>.
+ </p><p>
+ The encoding for a database is stored in the system catalog
+ <code class="literal">pg_database</code>. You can see it by using the
+ <code class="command">psql</code> <code class="option">-l</code> option or the
+ <code class="command">\l</code> command.
+
+</p><pre class="screen">
+$ <strong class="userinput"><code>psql -l</code></strong>
+ List of databases
+ Name | Owner | Encoding | Collation | Ctype | Access Privileges
+-----------+----------+-----------+-------------+-------------+-------------------------------------
+ clocaledb | hlinnaka | SQL_ASCII | C | C |
+ englishdb | hlinnaka | UTF8 | en_GB.UTF8 | en_GB.UTF8 |
+ japanese | hlinnaka | UTF8 | ja_JP.UTF8 | ja_JP.UTF8 |
+ korean | hlinnaka | EUC_KR | ko_KR.euckr | ko_KR.euckr |
+ postgres | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 |
+ template0 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
+ template1 | hlinnaka | UTF8 | fi_FI.UTF8 | fi_FI.UTF8 | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
+(7 rows)
+</pre><p>
+ </p><div class="important"><h3 class="title">Important</h3><p>
+ On most modern operating systems, <span class="productname">PostgreSQL</span>
+ can determine which character set is implied by the <code class="envar">LC_CTYPE</code>
+ setting, and it will enforce that only the matching database encoding is
+ used. On older systems it is your responsibility to ensure that you use
+ the encoding expected by the locale you have selected. A mistake in
+ this area is likely to lead to strange behavior of locale-dependent
+ operations such as sorting.
+ </p><p>
+ <span class="productname">PostgreSQL</span> will allow superusers to create
+ databases with <code class="literal">SQL_ASCII</code> encoding even when
+ <code class="envar">LC_CTYPE</code> is not <code class="literal">C</code> or <code class="literal">POSIX</code>. As noted
+ above, <code class="literal">SQL_ASCII</code> does not enforce that the data stored in
+ the database has any particular encoding, and so this choice poses risks
+ of locale-dependent misbehavior. Using this combination of settings is
+ deprecated and may someday be forbidden altogether.
+ </p></div></div><div class="sect2" id="id-1.6.11.5.7"><div class="titlepage"><div><div><h3 class="title">24.3.3. Automatic Character Set Conversion Between Server and Client</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> supports automatic character
+ set conversion between server and client for many combinations of
+ character sets (<a class="xref" href="multibyte.html#MULTIBYTE-CONVERSIONS-SUPPORTED" title="24.3.4. Available Character Set Conversions">Section 24.3.4</a>
+ shows which ones).
+ </p><p>
+ To enable automatic character set conversion, you have to
+ tell <span class="productname">PostgreSQL</span> the character set
+ (encoding) you would like to use in the client. There are several
+ ways to accomplish this:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Using the <code class="command">\encoding</code> command in
+ <span class="application">psql</span>.
+ <code class="command">\encoding</code> allows you to change client
+ encoding on the fly. For
+ example, to change the encoding to <code class="literal">SJIS</code>, type:
+
+</p><pre class="programlisting">
+\encoding SJIS
+</pre><p>
+ </p></li><li class="listitem"><p>
+ <span class="application">libpq</span> (<a class="xref" href="libpq-control.html" title="34.11. Control Functions">Section 34.11</a>) has functions to control the client encoding.
+ </p></li><li class="listitem"><p>
+ Using <code class="command">SET client_encoding TO</code>.
+
+ Setting the client encoding can be done with this SQL command:
+
+</p><pre class="programlisting">
+SET CLIENT_ENCODING TO '<em class="replaceable"><code>value</code></em>';
+</pre><p>
+
+ Also you can use the standard SQL syntax <code class="literal">SET NAMES</code>
+ for this purpose:
+
+</p><pre class="programlisting">
+SET NAMES '<em class="replaceable"><code>value</code></em>';
+</pre><p>
+
+ To query the current client encoding:
+
+</p><pre class="programlisting">
+SHOW client_encoding;
+</pre><p>
+
+ To return to the default encoding:
+
+</p><pre class="programlisting">
+RESET client_encoding;
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Using <code class="envar">PGCLIENTENCODING</code>. If the environment variable
+ <code class="envar">PGCLIENTENCODING</code> is defined in the client's
+ environment, that client encoding is automatically selected
+ when a connection to the server is made. (This can
+ subsequently be overridden using any of the other methods
+ mentioned above.)
+ </p></li><li class="listitem"><p>
+ Using the configuration variable <a class="xref" href="runtime-config-client.html#GUC-CLIENT-ENCODING">client_encoding</a>. If the
+ <code class="varname">client_encoding</code> variable is set, that client
+ encoding is automatically selected when a connection to the
+ server is made. (This can subsequently be overridden using any
+ of the other methods mentioned above.)
+ </p></li></ul></div><p>
+ </p><p>
+ If the conversion of a particular character is not possible
+ — suppose you chose <code class="literal">EUC_JP</code> for the
+ server and <code class="literal">LATIN1</code> for the client, and some
+ Japanese characters are returned that do not have a representation in
+ <code class="literal">LATIN1</code> — an error is reported.
+ </p><p>
+ If the client character set is defined as <code class="literal">SQL_ASCII</code>,
+ encoding conversion is disabled, regardless of the server's character
+ set. (However, if the server's character set is
+ not <code class="literal">SQL_ASCII</code>, the server will still check that
+ incoming data is valid for that encoding; so the net effect is as
+ though the client character set were the same as the server's.)
+ Just as for the server, use of <code class="literal">SQL_ASCII</code> is unwise
+ unless you are working with all-ASCII data.
+ </p></div><div class="sect2" id="MULTIBYTE-CONVERSIONS-SUPPORTED"><div class="titlepage"><div><div><h3 class="title">24.3.4. Available Character Set Conversions</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> allows conversion between any
+ two character sets for which a conversion function is listed in the
+ <a class="link" href="catalog-pg-conversion.html" title="53.14. pg_conversion"><code class="structname">pg_conversion</code></a>
+ system catalog. <span class="productname">PostgreSQL</span> comes with
+ some predefined conversions, as summarized in
+ <a class="xref" href="multibyte.html#MULTIBYTE-TRANSLATION-TABLE" title="Table 24.2. Built-in Client/Server Character Set Conversions">Table 24.2</a> and shown in more
+ detail in <a class="xref" href="multibyte.html#BUILTIN-CONVERSIONS-TABLE" title="Table 24.3. All Built-in Character Set Conversions">Table 24.3</a>. You can
+ create a new conversion using the SQL command
+ <a class="xref" href="sql-createconversion.html" title="CREATE CONVERSION"><span class="refentrytitle">CREATE CONVERSION</span></a>. (To be used for automatic
+ client/server conversions, a conversion must be marked
+ as <span class="quote">“<span class="quote">default</span>”</span> for its character set pair.)
+ </p><div class="table" id="MULTIBYTE-TRANSLATION-TABLE"><p class="title"><strong>Table 24.2. Built-in Client/Server Character Set Conversions</strong></p><div class="table-contents"><table class="table" summary="Built-in Client/Server Character Set Conversions" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Server Character Set</th><th>Available Client Character Sets</th></tr></thead><tbody><tr><td><code class="literal">BIG5</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">EUC_CN</code></td><td><span class="emphasis"><em>EUC_CN</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">EUC_JP</code></td><td><span class="emphasis"><em>EUC_JP</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">SJIS</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">EUC_JIS_2004</code></td><td><span class="emphasis"><em>EUC_JIS_2004</em></span>,
+ <code class="literal">SHIFT_JIS_2004</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">EUC_KR</code></td><td><span class="emphasis"><em>EUC_KR</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">EUC_TW</code></td><td><span class="emphasis"><em>EUC_TW</em></span>,
+ <code class="literal">BIG5</code>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">GB18030</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">GBK</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">ISO_8859_5</code></td><td><span class="emphasis"><em>ISO_8859_5</em></span>,
+ <code class="literal">KOI8R</code>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>,
+ <code class="literal">WIN866</code>,
+ <code class="literal">WIN1251</code>
+ </td></tr><tr><td><code class="literal">ISO_8859_6</code></td><td><span class="emphasis"><em>ISO_8859_6</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">ISO_8859_7</code></td><td><span class="emphasis"><em>ISO_8859_7</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">ISO_8859_8</code></td><td><span class="emphasis"><em>ISO_8859_8</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">JOHAB</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">KOI8R</code></td><td><span class="emphasis"><em>KOI8R</em></span>,
+ <code class="literal">ISO_8859_5</code>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>,
+ <code class="literal">WIN866</code>,
+ <code class="literal">WIN1251</code>
+ </td></tr><tr><td><code class="literal">KOI8U</code></td><td><span class="emphasis"><em>KOI8U</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN1</code></td><td><span class="emphasis"><em>LATIN1</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN2</code></td><td><span class="emphasis"><em>LATIN2</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>,
+ <code class="literal">WIN1250</code>
+ </td></tr><tr><td><code class="literal">LATIN3</code></td><td><span class="emphasis"><em>LATIN3</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN4</code></td><td><span class="emphasis"><em>LATIN4</em></span>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN5</code></td><td><span class="emphasis"><em>LATIN5</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN6</code></td><td><span class="emphasis"><em>LATIN6</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN7</code></td><td><span class="emphasis"><em>LATIN7</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN8</code></td><td><span class="emphasis"><em>LATIN8</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN9</code></td><td><span class="emphasis"><em>LATIN9</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">LATIN10</code></td><td><span class="emphasis"><em>LATIN10</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">MULE_INTERNAL</code></td><td><span class="emphasis"><em>MULE_INTERNAL</em></span>,
+ <code class="literal">BIG5</code>,
+ <code class="literal">EUC_CN</code>,
+ <code class="literal">EUC_JP</code>,
+ <code class="literal">EUC_KR</code>,
+ <code class="literal">EUC_TW</code>,
+ <code class="literal">ISO_8859_5</code>,
+ <code class="literal">KOI8R</code>,
+ <code class="literal">LATIN1</code> to <code class="literal">LATIN4</code>,
+ <code class="literal">SJIS</code>,
+ <code class="literal">WIN866</code>,
+ <code class="literal">WIN1250</code>,
+ <code class="literal">WIN1251</code>
+ </td></tr><tr><td><code class="literal">SJIS</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">SHIFT_JIS_2004</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">SQL_ASCII</code></td><td><span class="emphasis"><em>any (no conversion will be performed)</em></span>
+ </td></tr><tr><td><code class="literal">UHC</code></td><td><span class="emphasis"><em>not supported as a server encoding</em></span>
+ </td></tr><tr><td><code class="literal">UTF8</code></td><td><span class="emphasis"><em>all supported encodings</em></span>
+ </td></tr><tr><td><code class="literal">WIN866</code></td><td><span class="emphasis"><em>WIN866</em></span>,
+ <code class="literal">ISO_8859_5</code>,
+ <code class="literal">KOI8R</code>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>,
+ <code class="literal">WIN1251</code>
+ </td></tr><tr><td><code class="literal">WIN874</code></td><td><span class="emphasis"><em>WIN874</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1250</code></td><td><span class="emphasis"><em>WIN1250</em></span>,
+ <code class="literal">LATIN2</code>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1251</code></td><td><span class="emphasis"><em>WIN1251</em></span>,
+ <code class="literal">ISO_8859_5</code>,
+ <code class="literal">KOI8R</code>,
+ <code class="literal">MULE_INTERNAL</code>,
+ <code class="literal">UTF8</code>,
+ <code class="literal">WIN866</code>
+ </td></tr><tr><td><code class="literal">WIN1252</code></td><td><span class="emphasis"><em>WIN1252</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1253</code></td><td><span class="emphasis"><em>WIN1253</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1254</code></td><td><span class="emphasis"><em>WIN1254</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1255</code></td><td><span class="emphasis"><em>WIN1255</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1256</code></td><td><span class="emphasis"><em>WIN1256</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1257</code></td><td><span class="emphasis"><em>WIN1257</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr><tr><td><code class="literal">WIN1258</code></td><td><span class="emphasis"><em>WIN1258</em></span>,
+ <code class="literal">UTF8</code>
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="BUILTIN-CONVERSIONS-TABLE"><p class="title"><strong>Table 24.3. All Built-in Character Set Conversions</strong></p><div class="table-contents"><table class="table" summary="All Built-in Character Set Conversions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Conversion Name
+ <a href="#ftn.id-1.6.11.5.8.4.2.4.1.1.1" class="footnote"><sup class="footnote" id="id-1.6.11.5.8.4.2.4.1.1.1">[a]</sup></a>
+ </th><th>Source Encoding</th><th>Destination Encoding</th></tr></thead><tbody><tr><td><code class="literal">big5_to_euc_tw</code></td><td><code class="literal">BIG5</code></td><td><code class="literal">EUC_TW</code></td></tr><tr><td><code class="literal">big5_to_mic</code></td><td><code class="literal">BIG5</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">big5_to_utf8</code></td><td><code class="literal">BIG5</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">euc_cn_to_mic</code></td><td><code class="literal">EUC_CN</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">euc_cn_to_utf8</code></td><td><code class="literal">EUC_CN</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">euc_jp_to_mic</code></td><td><code class="literal">EUC_JP</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">euc_jp_to_sjis</code></td><td><code class="literal">EUC_JP</code></td><td><code class="literal">SJIS</code></td></tr><tr><td><code class="literal">euc_jp_to_utf8</code></td><td><code class="literal">EUC_JP</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">euc_kr_to_mic</code></td><td><code class="literal">EUC_KR</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">euc_kr_to_utf8</code></td><td><code class="literal">EUC_KR</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">euc_tw_to_big5</code></td><td><code class="literal">EUC_TW</code></td><td><code class="literal">BIG5</code></td></tr><tr><td><code class="literal">euc_tw_to_mic</code></td><td><code class="literal">EUC_TW</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">euc_tw_to_utf8</code></td><td><code class="literal">EUC_TW</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">gb18030_to_utf8</code></td><td><code class="literal">GB18030</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">gbk_to_utf8</code></td><td><code class="literal">GBK</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_10_to_utf8</code></td><td><code class="literal">LATIN6</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_13_to_utf8</code></td><td><code class="literal">LATIN7</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_14_to_utf8</code></td><td><code class="literal">LATIN8</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_15_to_utf8</code></td><td><code class="literal">LATIN9</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_16_to_utf8</code></td><td><code class="literal">LATIN10</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_1_to_mic</code></td><td><code class="literal">LATIN1</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">iso_8859_1_to_utf8</code></td><td><code class="literal">LATIN1</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_2_to_mic</code></td><td><code class="literal">LATIN2</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">iso_8859_2_to_utf8</code></td><td><code class="literal">LATIN2</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_2_to_windows_1250</code></td><td><code class="literal">LATIN2</code></td><td><code class="literal">WIN1250</code></td></tr><tr><td><code class="literal">iso_8859_3_to_mic</code></td><td><code class="literal">LATIN3</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">iso_8859_3_to_utf8</code></td><td><code class="literal">LATIN3</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_4_to_mic</code></td><td><code class="literal">LATIN4</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">iso_8859_4_to_utf8</code></td><td><code class="literal">LATIN4</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_5_to_koi8_r</code></td><td><code class="literal">ISO_8859_5</code></td><td><code class="literal">KOI8R</code></td></tr><tr><td><code class="literal">iso_8859_5_to_mic</code></td><td><code class="literal">ISO_8859_5</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">iso_8859_5_to_utf8</code></td><td><code class="literal">ISO_8859_5</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_5_to_windows_1251</code></td><td><code class="literal">ISO_8859_5</code></td><td><code class="literal">WIN1251</code></td></tr><tr><td><code class="literal">iso_8859_5_to_windows_866</code></td><td><code class="literal">ISO_8859_5</code></td><td><code class="literal">WIN866</code></td></tr><tr><td><code class="literal">iso_8859_6_to_utf8</code></td><td><code class="literal">ISO_8859_6</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_7_to_utf8</code></td><td><code class="literal">ISO_8859_7</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_8_to_utf8</code></td><td><code class="literal">ISO_8859_8</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">iso_8859_9_to_utf8</code></td><td><code class="literal">LATIN5</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">johab_to_utf8</code></td><td><code class="literal">JOHAB</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">koi8_r_to_iso_8859_5</code></td><td><code class="literal">KOI8R</code></td><td><code class="literal">ISO_8859_5</code></td></tr><tr><td><code class="literal">koi8_r_to_mic</code></td><td><code class="literal">KOI8R</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">koi8_r_to_utf8</code></td><td><code class="literal">KOI8R</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">koi8_r_to_windows_1251</code></td><td><code class="literal">KOI8R</code></td><td><code class="literal">WIN1251</code></td></tr><tr><td><code class="literal">koi8_r_to_windows_866</code></td><td><code class="literal">KOI8R</code></td><td><code class="literal">WIN866</code></td></tr><tr><td><code class="literal">koi8_u_to_utf8</code></td><td><code class="literal">KOI8U</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">mic_to_big5</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">BIG5</code></td></tr><tr><td><code class="literal">mic_to_euc_cn</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">EUC_CN</code></td></tr><tr><td><code class="literal">mic_to_euc_jp</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">EUC_JP</code></td></tr><tr><td><code class="literal">mic_to_euc_kr</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">EUC_KR</code></td></tr><tr><td><code class="literal">mic_to_euc_tw</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">EUC_TW</code></td></tr><tr><td><code class="literal">mic_to_iso_8859_1</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">LATIN1</code></td></tr><tr><td><code class="literal">mic_to_iso_8859_2</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">LATIN2</code></td></tr><tr><td><code class="literal">mic_to_iso_8859_3</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">LATIN3</code></td></tr><tr><td><code class="literal">mic_to_iso_8859_4</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">LATIN4</code></td></tr><tr><td><code class="literal">mic_to_iso_8859_5</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">ISO_8859_5</code></td></tr><tr><td><code class="literal">mic_to_koi8_r</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">KOI8R</code></td></tr><tr><td><code class="literal">mic_to_sjis</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">SJIS</code></td></tr><tr><td><code class="literal">mic_to_windows_1250</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">WIN1250</code></td></tr><tr><td><code class="literal">mic_to_windows_1251</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">WIN1251</code></td></tr><tr><td><code class="literal">mic_to_windows_866</code></td><td><code class="literal">MULE_INTERNAL</code></td><td><code class="literal">WIN866</code></td></tr><tr><td><code class="literal">sjis_to_euc_jp</code></td><td><code class="literal">SJIS</code></td><td><code class="literal">EUC_JP</code></td></tr><tr><td><code class="literal">sjis_to_mic</code></td><td><code class="literal">SJIS</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">sjis_to_utf8</code></td><td><code class="literal">SJIS</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">windows_1258_to_utf8</code></td><td><code class="literal">WIN1258</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">uhc_to_utf8</code></td><td><code class="literal">UHC</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">utf8_to_big5</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">BIG5</code></td></tr><tr><td><code class="literal">utf8_to_euc_cn</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">EUC_CN</code></td></tr><tr><td><code class="literal">utf8_to_euc_jp</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">EUC_JP</code></td></tr><tr><td><code class="literal">utf8_to_euc_kr</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">EUC_KR</code></td></tr><tr><td><code class="literal">utf8_to_euc_tw</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">EUC_TW</code></td></tr><tr><td><code class="literal">utf8_to_gb18030</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">GB18030</code></td></tr><tr><td><code class="literal">utf8_to_gbk</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">GBK</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_1</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN1</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_10</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN6</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_13</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN7</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_14</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN8</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_15</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN9</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_16</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN10</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_2</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN2</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_3</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN3</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_4</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN4</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_5</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">ISO_8859_5</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_6</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">ISO_8859_6</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_7</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">ISO_8859_7</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_8</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">ISO_8859_8</code></td></tr><tr><td><code class="literal">utf8_to_iso_8859_9</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">LATIN5</code></td></tr><tr><td><code class="literal">utf8_to_johab</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">JOHAB</code></td></tr><tr><td><code class="literal">utf8_to_koi8_r</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">KOI8R</code></td></tr><tr><td><code class="literal">utf8_to_koi8_u</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">KOI8U</code></td></tr><tr><td><code class="literal">utf8_to_sjis</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">SJIS</code></td></tr><tr><td><code class="literal">utf8_to_windows_1258</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1258</code></td></tr><tr><td><code class="literal">utf8_to_uhc</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">UHC</code></td></tr><tr><td><code class="literal">utf8_to_windows_1250</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1250</code></td></tr><tr><td><code class="literal">utf8_to_windows_1251</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1251</code></td></tr><tr><td><code class="literal">utf8_to_windows_1252</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1252</code></td></tr><tr><td><code class="literal">utf8_to_windows_1253</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1253</code></td></tr><tr><td><code class="literal">utf8_to_windows_1254</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1254</code></td></tr><tr><td><code class="literal">utf8_to_windows_1255</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1255</code></td></tr><tr><td><code class="literal">utf8_to_windows_1256</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1256</code></td></tr><tr><td><code class="literal">utf8_to_windows_1257</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN1257</code></td></tr><tr><td><code class="literal">utf8_to_windows_866</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN866</code></td></tr><tr><td><code class="literal">utf8_to_windows_874</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">WIN874</code></td></tr><tr><td><code class="literal">windows_1250_to_iso_8859_2</code></td><td><code class="literal">WIN1250</code></td><td><code class="literal">LATIN2</code></td></tr><tr><td><code class="literal">windows_1250_to_mic</code></td><td><code class="literal">WIN1250</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">windows_1250_to_utf8</code></td><td><code class="literal">WIN1250</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">windows_1251_to_iso_8859_5</code></td><td><code class="literal">WIN1251</code></td><td><code class="literal">ISO_8859_5</code></td></tr><tr><td><code class="literal">windows_1251_to_koi8_r</code></td><td><code class="literal">WIN1251</code></td><td><code class="literal">KOI8R</code></td></tr><tr><td><code class="literal">windows_1251_to_mic</code></td><td><code class="literal">WIN1251</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">windows_1251_to_utf8</code></td><td><code class="literal">WIN1251</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">windows_1251_to_windows_866</code></td><td><code class="literal">WIN1251</code></td><td><code class="literal">WIN866</code></td></tr><tr><td><code class="literal">windows_1252_to_utf8</code></td><td><code class="literal">WIN1252</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">windows_1256_to_utf8</code></td><td><code class="literal">WIN1256</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">windows_866_to_iso_8859_5</code></td><td><code class="literal">WIN866</code></td><td><code class="literal">ISO_8859_5</code></td></tr><tr><td><code class="literal">windows_866_to_koi8_r</code></td><td><code class="literal">WIN866</code></td><td><code class="literal">KOI8R</code></td></tr><tr><td><code class="literal">windows_866_to_mic</code></td><td><code class="literal">WIN866</code></td><td><code class="literal">MULE_INTERNAL</code></td></tr><tr><td><code class="literal">windows_866_to_utf8</code></td><td><code class="literal">WIN866</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">windows_866_to_windows_1251</code></td><td><code class="literal">WIN866</code></td><td><code class="literal">WIN</code></td></tr><tr><td><code class="literal">windows_874_to_utf8</code></td><td><code class="literal">WIN874</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">euc_jis_2004_to_utf8</code></td><td><code class="literal">EUC_JIS_2004</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">utf8_to_euc_jis_2004</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">EUC_JIS_2004</code></td></tr><tr><td><code class="literal">shift_jis_2004_to_utf8</code></td><td><code class="literal">SHIFT_JIS_2004</code></td><td><code class="literal">UTF8</code></td></tr><tr><td><code class="literal">utf8_to_shift_jis_2004</code></td><td><code class="literal">UTF8</code></td><td><code class="literal">SHIFT_JIS_2004</code></td></tr><tr><td><code class="literal">euc_jis_2004_to_shift_jis_2004</code></td><td><code class="literal">EUC_JIS_2004</code></td><td><code class="literal">SHIFT_JIS_2004</code></td></tr><tr><td><code class="literal">shift_jis_2004_to_euc_jis_2004</code></td><td><code class="literal">SHIFT_JIS_2004</code></td><td><code class="literal">EUC_JIS_2004</code></td></tr></tbody><tbody class="footnotes"><tr><td colspan="3"><div id="ftn.id-1.6.11.5.8.4.2.4.1.1.1" class="footnote"><p><a href="#id-1.6.11.5.8.4.2.4.1.1.1" class="para"><sup class="para">[a] </sup></a>
+ The conversion names follow a standard naming scheme: The
+ official name of the source encoding with all
+ non-alphanumeric characters replaced by underscores, followed
+ by <code class="literal">_to_</code>, followed by the similarly processed
+ destination encoding name. Therefore, these names sometimes
+ deviate from the customary encoding names shown in
+ <a class="xref" href="multibyte.html#CHARSET-TABLE" title="Table 24.1. PostgreSQL Character Sets">Table 24.1</a>.
+ </p></div></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.6.11.5.9"><div class="titlepage"><div><div><h3 class="title">24.3.5. Further Reading</h3></div></div></div><p>
+ These are good sources to start learning about various kinds of encoding
+ systems.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="citetitle">CJKV Information Processing: Chinese, Japanese, Korean &amp; Vietnamese Computing</em></span></dt><dd><p>
+ Contains detailed explanations of <code class="literal">EUC_JP</code>,
+ <code class="literal">EUC_CN</code>, <code class="literal">EUC_KR</code>,
+ <code class="literal">EUC_TW</code>.
+ </p></dd><dt><span class="term"><a class="ulink" href="https://www.unicode.org/" target="_top">https://www.unicode.org/</a></span></dt><dd><p>
+ The web site of the Unicode Consortium.
+ </p></dd><dt><span class="term"><a class="ulink" href="https://tools.ietf.org/html/rfc3629" target="_top">RFC 3629</a></span></dt><dd><p>
+ <acronym class="acronym">UTF</acronym>-8 (8-bit UCS/Unicode Transformation
+ Format) is defined here.
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="collation.html" title="24.2. Collation Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="charset.html" title="Chapter 24. Localization">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">24.2. Collation Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 25. Routine Database Maintenance Tasks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/multivariate-statistics-examples.html b/doc/src/sgml/html/multivariate-statistics-examples.html
new file mode 100644
index 0000000..e41a6d2
--- /dev/null
+++ b/doc/src/sgml/html/multivariate-statistics-examples.html
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>75.2. Multivariate Statistics Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="row-estimation-examples.html" title="75.1. Row Estimation Examples" /><link rel="next" href="planner-stats-security.html" title="75.3. Planner Statistics and Security" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">75.2. Multivariate Statistics Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="row-estimation-examples.html" title="75.1. Row Estimation Examples">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Up</a></td><th width="60%" align="center">Chapter 75. How the Planner Uses Statistics</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="planner-stats-security.html" title="75.3. Planner Statistics and Security">Next</a></td></tr></table><hr /></div><div class="sect1" id="MULTIVARIATE-STATISTICS-EXAMPLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">75.2. Multivariate Statistics Examples</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="multivariate-statistics-examples.html#FUNCTIONAL-DEPENDENCIES">75.2.1. Functional Dependencies</a></span></dt><dt><span class="sect2"><a href="multivariate-statistics-examples.html#MULTIVARIATE-NDISTINCT-COUNTS">75.2.2. Multivariate N-Distinct Counts</a></span></dt><dt><span class="sect2"><a href="multivariate-statistics-examples.html#MCV-LISTS">75.2.3. MCV Lists</a></span></dt></dl></div><a id="id-1.10.26.5.2" class="indexterm"></a><div class="sect2" id="FUNCTIONAL-DEPENDENCIES"><div class="titlepage"><div><div><h3 class="title">75.2.1. Functional Dependencies</h3></div></div></div><p>
+ Multivariate correlation can be demonstrated with a very simple data set
+ — a table with two columns, both containing the same values:
+
+</p><pre class="programlisting">
+CREATE TABLE t (a INT, b INT);
+INSERT INTO t SELECT i % 100, i % 100 FROM generate_series(1, 10000) s(i);
+ANALYZE t;
+</pre><p>
+
+ As explained in <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>, the planner can determine
+ cardinality of <code class="structname">t</code> using the number of pages and
+ rows obtained from <code class="structname">pg_class</code>:
+
+</p><pre class="programlisting">
+SELECT relpages, reltuples FROM pg_class WHERE relname = 't';
+
+ relpages | reltuples
+----------+-----------
+ 45 | 10000
+</pre><p>
+
+ The data distribution is very simple; there are only 100 distinct values
+ in each column, uniformly distributed.
+ </p><p>
+ The following example shows the result of estimating a <code class="literal">WHERE</code>
+ condition on the <code class="structfield">a</code> column:
+
+</p><pre class="programlisting">
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
+ QUERY PLAN
+-------------------------------------------------------------------​------------
+ Seq Scan on t (cost=0.00..170.00 rows=100 width=8) (actual rows=100 loops=1)
+ Filter: (a = 1)
+ Rows Removed by Filter: 9900
+</pre><p>
+
+ The planner examines the condition and determines the selectivity
+ of this clause to be 1%. By comparing this estimate and the actual
+ number of rows, we see that the estimate is very accurate
+ (in fact exact, as the table is very small). Changing the
+ <code class="literal">WHERE</code> condition to use the <code class="structfield">b</code> column, an
+ identical plan is generated. But observe what happens if we apply the same
+ condition on both columns, combining them with <code class="literal">AND</code>:
+
+</p><pre class="programlisting">
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
+ QUERY PLAN
+-------------------------------------------------------------------​----------
+ Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=100 loops=1)
+ Filter: ((a = 1) AND (b = 1))
+ Rows Removed by Filter: 9900
+</pre><p>
+
+ The planner estimates the selectivity for each condition individually,
+ arriving at the same 1% estimates as above. Then it assumes that the
+ conditions are independent, and so it multiplies their selectivities,
+ producing a final selectivity estimate of just 0.01%.
+ This is a significant underestimate, as the actual number of rows
+ matching the conditions (100) is two orders of magnitude higher.
+ </p><p>
+ This problem can be fixed by creating a statistics object that
+ directs <code class="command">ANALYZE</code> to calculate functional-dependency
+ multivariate statistics on the two columns:
+
+</p><pre class="programlisting">
+CREATE STATISTICS stts (dependencies) ON a, b FROM t;
+ANALYZE t;
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
+ QUERY PLAN
+-------------------------------------------------------------------​------------
+ Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
+ Filter: ((a = 1) AND (b = 1))
+ Rows Removed by Filter: 9900
+</pre><p>
+ </p></div><div class="sect2" id="MULTIVARIATE-NDISTINCT-COUNTS"><div class="titlepage"><div><div><h3 class="title">75.2.2. Multivariate N-Distinct Counts</h3></div></div></div><p>
+ A similar problem occurs with estimation of the cardinality of sets of
+ multiple columns, such as the number of groups that would be generated by
+ a <code class="command">GROUP BY</code> clause. When <code class="command">GROUP BY</code>
+ lists a single column, the n-distinct estimate (which is visible as the
+ estimated number of rows returned by the HashAggregate node) is very
+ accurate:
+</p><pre class="programlisting">
+EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a;
+ QUERY PLAN
+-------------------------------------------------------------------​----------------------
+ HashAggregate (cost=195.00..196.00 rows=100 width=12) (actual rows=100 loops=1)
+ Group Key: a
+ -&gt; Seq Scan on t (cost=0.00..145.00 rows=10000 width=4) (actual rows=10000 loops=1)
+</pre><p>
+ But without multivariate statistics, the estimate for the number of
+ groups in a query with two columns in <code class="command">GROUP BY</code>, as
+ in the following example, is off by an order of magnitude:
+</p><pre class="programlisting">
+EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------------
+ HashAggregate (cost=220.00..230.00 rows=1000 width=16) (actual rows=100 loops=1)
+ Group Key: a, b
+ -&gt; Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (actual rows=10000 loops=1)
+</pre><p>
+ By redefining the statistics object to include n-distinct counts for the
+ two columns, the estimate is much improved:
+</p><pre class="programlisting">
+DROP STATISTICS stts;
+CREATE STATISTICS stts (dependencies, ndistinct) ON a, b FROM t;
+ANALYZE t;
+EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------------
+ HashAggregate (cost=220.00..221.00 rows=100 width=16) (actual rows=100 loops=1)
+ Group Key: a, b
+ -&gt; Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (actual rows=10000 loops=1)
+</pre><p>
+ </p></div><div class="sect2" id="MCV-LISTS"><div class="titlepage"><div><div><h3 class="title">75.2.3. MCV Lists</h3></div></div></div><p>
+ As explained in <a class="xref" href="multivariate-statistics-examples.html#FUNCTIONAL-DEPENDENCIES" title="75.2.1. Functional Dependencies">Section 75.2.1</a>, functional
+ dependencies are very cheap and efficient type of statistics, but their
+ main limitation is their global nature (only tracking dependencies at
+ the column level, not between individual column values).
+ </p><p>
+ This section introduces multivariate variant of <acronym class="acronym">MCV</acronym>
+ (most-common values) lists, a straightforward extension of the per-column
+ statistics described in <a class="xref" href="row-estimation-examples.html" title="75.1. Row Estimation Examples">Section 75.1</a>. These
+ statistics address the limitation by storing individual values, but it is
+ naturally more expensive, both in terms of building the statistics in
+ <code class="command">ANALYZE</code>, storage and planning time.
+ </p><p>
+ Let's look at the query from <a class="xref" href="multivariate-statistics-examples.html#FUNCTIONAL-DEPENDENCIES" title="75.2.1. Functional Dependencies">Section 75.2.1</a>
+ again, but this time with a <acronym class="acronym">MCV</acronym> list created on the
+ same set of columns (be sure to drop the functional dependencies, to
+ make sure the planner uses the newly created statistics).
+
+</p><pre class="programlisting">
+DROP STATISTICS stts;
+CREATE STATISTICS stts2 (mcv) ON a, b FROM t;
+ANALYZE t;
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
+ QUERY PLAN
+-------------------------------------------------------------------​------------
+ Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
+ Filter: ((a = 1) AND (b = 1))
+ Rows Removed by Filter: 9900
+</pre><p>
+
+ The estimate is as accurate as with the functional dependencies, mostly
+ thanks to the table being fairly small and having a simple distribution
+ with a low number of distinct values. Before looking at the second query,
+ which was not handled by functional dependencies particularly well,
+ let's inspect the <acronym class="acronym">MCV</acronym> list a bit.
+ </p><p>
+ Inspecting the <acronym class="acronym">MCV</acronym> list is possible using
+ <code class="function">pg_mcv_list_items</code> set-returning function.
+
+</p><pre class="programlisting">
+SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
+ pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts2';
+ index | values | nulls | frequency | base_frequency
+-------+----------+-------+-----------+----------------
+ 0 | {0, 0} | {f,f} | 0.01 | 0.0001
+ 1 | {1, 1} | {f,f} | 0.01 | 0.0001
+ ...
+ 49 | {49, 49} | {f,f} | 0.01 | 0.0001
+ 50 | {50, 50} | {f,f} | 0.01 | 0.0001
+ ...
+ 97 | {97, 97} | {f,f} | 0.01 | 0.0001
+ 98 | {98, 98} | {f,f} | 0.01 | 0.0001
+ 99 | {99, 99} | {f,f} | 0.01 | 0.0001
+(100 rows)
+</pre><p>
+
+ This confirms there are 100 distinct combinations in the two columns, and
+ all of them are about equally likely (1% frequency for each one). The
+ base frequency is the frequency computed from per-column statistics, as if
+ there were no multi-column statistics. Had there been any null values in
+ either of the columns, this would be identified in the
+ <code class="structfield">nulls</code> column.
+ </p><p>
+ When estimating the selectivity, the planner applies all the conditions
+ on items in the <acronym class="acronym">MCV</acronym> list, and then sums the frequencies
+ of the matching ones. See <code class="function">mcv_clauselist_selectivity</code>
+ in <code class="filename">src/backend/statistics/mcv.c</code> for details.
+ </p><p>
+ Compared to functional dependencies, <acronym class="acronym">MCV</acronym> lists have two
+ major advantages. Firstly, the list stores actual values, making it possible
+ to decide which combinations are compatible.
+
+</p><pre class="programlisting">
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 10;
+ QUERY PLAN
+-------------------------------------------------------------------​--------
+ Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
+ Filter: ((a = 1) AND (b = 10))
+ Rows Removed by Filter: 10000
+</pre><p>
+
+ Secondly, <acronym class="acronym">MCV</acronym> lists handle a wider range of clause types,
+ not just equality clauses like functional dependencies. For example,
+ consider the following range query for the same table:
+
+</p><pre class="programlisting">
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a &lt;= 49 AND b &gt; 49;
+ QUERY PLAN
+-------------------------------------------------------------------​--------
+ Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
+ Filter: ((a &lt;= 49) AND (b &gt; 49))
+ Rows Removed by Filter: 10000
+</pre><p>
+
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="row-estimation-examples.html" title="75.1. Row Estimation Examples">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="planner-stats-security.html" title="75.3. Planner Statistics and Security">Next</a></td></tr><tr><td width="40%" align="left" valign="top">75.1. Row Estimation Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 75.3. Planner Statistics and Security</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/mvcc-caveats.html b/doc/src/sgml/html/mvcc-caveats.html
new file mode 100644
index 0000000..fbaa079
--- /dev/null
+++ b/doc/src/sgml/html/mvcc-caveats.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.6. Caveats</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling" /><link rel="next" href="locking-indexes.html" title="13.7. Locking and Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.6. Caveats</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="locking-indexes.html" title="13.7. Locking and Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="MVCC-CAVEATS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.6. Caveats</h2></div></div></div><p>
+ Some DDL commands, currently only <a class="link" href="sql-truncate.html" title="TRUNCATE"><code class="command">TRUNCATE</code></a> and the
+ table-rewriting forms of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>, are not
+ MVCC-safe. This means that after the truncation or rewrite commits, the
+ table will appear empty to concurrent transactions, if they are using a
+ snapshot taken before the DDL command committed. This will only be an
+ issue for a transaction that did not access the table in question
+ before the DDL command started — any transaction that has done so
+ would hold at least an <code class="literal">ACCESS SHARE</code> table lock,
+ which would block the DDL command until that transaction completes.
+ So these commands will not cause any apparent inconsistency in the
+ table contents for successive queries on the target table, but they
+ could cause visible inconsistency between the contents of the target
+ table and other tables in the database.
+ </p><p>
+ Support for the Serializable transaction isolation level has not yet
+ been added to hot standby replication targets (described in
+ <a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a>). The strictest isolation level currently
+ supported in hot standby mode is Repeatable Read. While performing all
+ permanent database writes within Serializable transactions on the
+ primary will ensure that all standbys will eventually reach a consistent
+ state, a Repeatable Read transaction run on the standby can sometimes
+ see a transient state that is inconsistent with any serial execution
+ of the transactions on the primary.
+ </p><p>
+ Internal access to the system catalogs is not done using the isolation
+ level of the current transaction. This means that newly created database
+ objects such as tables are visible to concurrent Repeatable Read and
+ Serializable transactions, even though the rows they contain are not. In
+ contrast, queries that explicitly examine the system catalogs don't see
+ rows representing concurrently created database objects, in the higher
+ isolation levels.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="mvcc-serialization-failure-handling.html" title="13.5. Serialization Failure Handling">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="locking-indexes.html" title="13.7. Locking and Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.5. Serialization Failure Handling </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.7. Locking and Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/mvcc-intro.html b/doc/src/sgml/html/mvcc-intro.html
new file mode 100644
index 0000000..74ddf34
--- /dev/null
+++ b/doc/src/sgml/html/mvcc-intro.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="mvcc.html" title="Chapter 13. Concurrency Control" /><link rel="next" href="transaction-iso.html" title="13.2. Transaction Isolation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="mvcc.html" title="Chapter 13. Concurrency Control">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="transaction-iso.html" title="13.2. Transaction Isolation">Next</a></td></tr></table><hr /></div><div class="sect1" id="MVCC-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.1. Introduction</h2></div></div></div><a id="id-1.5.12.4.2" class="indexterm"></a><a id="id-1.5.12.4.3" class="indexterm"></a><a id="id-1.5.12.4.4" class="indexterm"></a><a id="id-1.5.12.4.5" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a rich set of tools
+ for developers to manage concurrent access to data. Internally,
+ data consistency is maintained by using a multiversion
+ model (Multiversion Concurrency Control, <acronym class="acronym">MVCC</acronym>).
+ This means that each SQL statement sees
+ a snapshot of data (a <em class="firstterm">database version</em>)
+ as it was some
+ time ago, regardless of the current state of the underlying data.
+ This prevents statements from viewing inconsistent data produced
+ by concurrent transactions performing updates on the same
+ data rows, providing <em class="firstterm">transaction isolation</em>
+ for each database session. <acronym class="acronym">MVCC</acronym>, by eschewing
+ the locking methodologies of traditional database systems,
+ minimizes lock contention in order to allow for reasonable
+ performance in multiuser environments.
+ </p><p>
+ The main advantage of using the <acronym class="acronym">MVCC</acronym> model of
+ concurrency control rather than locking is that in
+ <acronym class="acronym">MVCC</acronym> locks acquired for querying (reading) data
+ do not conflict with locks acquired for writing data, and so
+ reading never blocks writing and writing never blocks reading.
+ <span class="productname">PostgreSQL</span> maintains this guarantee
+ even when providing the strictest level of transaction
+ isolation through the use of an innovative <em class="firstterm">Serializable
+ Snapshot Isolation</em> (<acronym class="acronym">SSI</acronym>) level.
+ </p><p>
+ Table- and row-level locking facilities are also available in
+ <span class="productname">PostgreSQL</span> for applications which don't
+ generally need full transaction isolation and prefer to explicitly
+ manage particular points of conflict. However, proper
+ use of <acronym class="acronym">MVCC</acronym> will generally provide better
+ performance than locks. In addition, application-defined advisory
+ locks provide a mechanism for acquiring locks that are not tied
+ to a single transaction.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="mvcc.html" title="Chapter 13. Concurrency Control">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="transaction-iso.html" title="13.2. Transaction Isolation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 13. Concurrency Control </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.2. Transaction Isolation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/mvcc-serialization-failure-handling.html b/doc/src/sgml/html/mvcc-serialization-failure-handling.html
new file mode 100644
index 0000000..05a8233
--- /dev/null
+++ b/doc/src/sgml/html/mvcc-serialization-failure-handling.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.5. Serialization Failure Handling</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level" /><link rel="next" href="mvcc-caveats.html" title="13.6. Caveats" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.5. Serialization Failure Handling</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="mvcc-caveats.html" title="13.6. Caveats">Next</a></td></tr></table><hr /></div><div class="sect1" id="MVCC-SERIALIZATION-FAILURE-HANDLING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.5. Serialization Failure Handling</h2></div></div></div><a id="id-1.5.12.8.2" class="indexterm"></a><a id="id-1.5.12.8.3" class="indexterm"></a><p>
+ Both Repeatable Read and Serializable isolation levels can produce
+ errors that are designed to prevent serialization anomalies. As
+ previously stated, applications using these levels must be prepared to
+ retry transactions that fail due to serialization errors. Such an
+ error's message text will vary according to the precise circumstances,
+ but it will always have the SQLSTATE code <code class="literal">40001</code>
+ (<code class="literal">serialization_failure</code>).
+ </p><p>
+ It may also be advisable to retry deadlock failures.
+ These have the SQLSTATE code <code class="literal">40P01</code>
+ (<code class="literal">deadlock_detected</code>).
+ </p><p>
+ In some cases it is also appropriate to retry unique-key failures,
+ which have SQLSTATE code <code class="literal">23505</code>
+ (<code class="literal">unique_violation</code>), and exclusion constraint
+ failures, which have SQLSTATE code <code class="literal">23P01</code>
+ (<code class="literal">exclusion_violation</code>). For example, if the
+ application selects a new value for a primary key column after
+ inspecting the currently stored keys, it could get a unique-key
+ failure because another application instance selected the same new key
+ concurrently. This is effectively a serialization failure, but the
+ server will not detect it as such because it cannot <span class="quote">“<span class="quote">see</span>”</span>
+ the connection between the inserted value and the previous reads.
+ There are also some corner cases in which the server will issue a
+ unique-key or exclusion constraint error even though in principle it
+ has enough information to determine that a serialization problem
+ is the underlying cause. While it's recommendable to just
+ retry <code class="literal">serialization_failure</code> errors unconditionally,
+ more care is needed when retrying these other error codes, since they
+ might represent persistent error conditions rather than transient
+ failures.
+ </p><p>
+ It is important to retry the complete transaction, including all logic
+ that decides which SQL to issue and/or which values to use.
+ Therefore, <span class="productname">PostgreSQL</span> does not offer an
+ automatic retry facility, since it cannot do so with any guarantee of
+ correctness.
+ </p><p>
+ Transaction retry does not guarantee that the retried transaction will
+ complete; multiple retries may be needed. In cases with very high
+ contention, it is possible that completion of a transaction may take
+ many attempts. In cases involving a conflicting prepared transaction,
+ it may not be possible to make progress until the prepared transaction
+ commits or rolls back.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="applevel-consistency.html" title="13.4. Data Consistency Checks at the Application Level">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="mvcc-caveats.html" title="13.6. Caveats">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.4. Data Consistency Checks at the Application Level </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.6. Caveats</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/mvcc.html b/doc/src/sgml/html/mvcc.html
new file mode 100644
index 0000000..c31dee3
--- /dev/null
+++ b/doc/src/sgml/html/mvcc.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 13. Concurrency Control</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-limitations.html" title="12.11. Limitations" /><link rel="next" href="mvcc-intro.html" title="13.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 13. Concurrency Control</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-limitations.html" title="12.11. Limitations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="mvcc-intro.html" title="13.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="MVCC"><div class="titlepage"><div><div><h2 class="title">Chapter 13. Concurrency Control</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="mvcc-intro.html">13.1. Introduction</a></span></dt><dt><span class="sect1"><a href="transaction-iso.html">13.2. Transaction Isolation</a></span></dt><dd><dl><dt><span class="sect2"><a href="transaction-iso.html#XACT-READ-COMMITTED">13.2.1. Read Committed Isolation Level</a></span></dt><dt><span class="sect2"><a href="transaction-iso.html#XACT-REPEATABLE-READ">13.2.2. Repeatable Read Isolation Level</a></span></dt><dt><span class="sect2"><a href="transaction-iso.html#XACT-SERIALIZABLE">13.2.3. Serializable Isolation Level</a></span></dt></dl></dd><dt><span class="sect1"><a href="explicit-locking.html">13.3. Explicit Locking</a></span></dt><dd><dl><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-TABLES">13.3.1. Table-Level Locks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-ROWS">13.3.2. Row-Level Locks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-PAGES">13.3.3. Page-Level Locks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#LOCKING-DEADLOCKS">13.3.4. Deadlocks</a></span></dt><dt><span class="sect2"><a href="explicit-locking.html#ADVISORY-LOCKS">13.3.5. Advisory Locks</a></span></dt></dl></dd><dt><span class="sect1"><a href="applevel-consistency.html">13.4. Data Consistency Checks at the Application Level</a></span></dt><dd><dl><dt><span class="sect2"><a href="applevel-consistency.html#SERIALIZABLE-CONSISTENCY">13.4.1. Enforcing Consistency with Serializable Transactions</a></span></dt><dt><span class="sect2"><a href="applevel-consistency.html#NON-SERIALIZABLE-CONSISTENCY">13.4.2. Enforcing Consistency with Explicit Blocking Locks</a></span></dt></dl></dd><dt><span class="sect1"><a href="mvcc-serialization-failure-handling.html">13.5. Serialization Failure Handling</a></span></dt><dt><span class="sect1"><a href="mvcc-caveats.html">13.6. Caveats</a></span></dt><dt><span class="sect1"><a href="locking-indexes.html">13.7. Locking and Indexes</a></span></dt></dl></div><a id="id-1.5.12.2" class="indexterm"></a><p>
+ This chapter describes the behavior of the
+ <span class="productname">PostgreSQL</span> database system when two or
+ more sessions try to access the same data at the same time. The
+ goals in that situation are to allow efficient access for all
+ sessions while maintaining strict data integrity. Every developer
+ of database applications should be familiar with the topics covered
+ in this chapter.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-limitations.html" title="12.11. Limitations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="mvcc-intro.html" title="13.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.11. Limitations </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/nls-programmer.html b/doc/src/sgml/html/nls-programmer.html
new file mode 100644
index 0000000..17ff7c1
--- /dev/null
+++ b/doc/src/sgml/html/nls-programmer.html
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>57.2. For the Programmer</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="nls-translator.html" title="57.1. For the Translator" /><link rel="next" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">57.2. For the Programmer</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="nls-translator.html" title="57.1. For the Translator">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="nls.html" title="Chapter 57. Native Language Support">Up</a></td><th width="60%" align="center">Chapter 57. Native Language Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Next</a></td></tr></table><hr /></div><div class="sect1" id="NLS-PROGRAMMER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">57.2. For the Programmer</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="nls-programmer.html#NLS-MECHANICS">57.2.1. Mechanics</a></span></dt><dt><span class="sect2"><a href="nls-programmer.html#NLS-GUIDELINES">57.2.2. Message-Writing Guidelines</a></span></dt></dl></div><div class="sect2" id="NLS-MECHANICS"><div class="titlepage"><div><div><h3 class="title">57.2.1. Mechanics</h3></div></div></div><p>
+ This section describes how to implement native language support in a
+ program or library that is part of the
+ <span class="productname">PostgreSQL</span> distribution.
+ Currently, it only applies to C programs.
+ </p><div class="procedure" id="id-1.10.8.3.2.3"><p class="title"><strong>Adding NLS Support to a Program</strong></p><ol class="procedure" type="1"><li class="step"><p>
+ Insert this code into the start-up sequence of the program:
+</p><pre class="programlisting">
+#ifdef ENABLE_NLS
+#include &lt;locale.h&gt;
+#endif
+
+...
+
+#ifdef ENABLE_NLS
+setlocale(LC_ALL, "");
+bindtextdomain("<em class="replaceable"><code>progname</code></em>", LOCALEDIR);
+textdomain("<em class="replaceable"><code>progname</code></em>");
+#endif
+</pre><p>
+ (The <em class="replaceable"><code>progname</code></em> can actually be chosen
+ freely.)
+ </p></li><li class="step"><p>
+ Wherever a message that is a candidate for translation is found,
+ a call to <code class="function">gettext()</code> needs to be inserted. E.g.:
+</p><pre class="programlisting">
+fprintf(stderr, "panic level %d\n", lvl);
+</pre><p>
+ would be changed to:
+</p><pre class="programlisting">
+fprintf(stderr, gettext("panic level %d\n"), lvl);
+</pre><p>
+ (<code class="symbol">gettext</code> is defined as a no-op if NLS support is
+ not configured.)
+ </p><p>
+ This tends to add a lot of clutter. One common shortcut is to use:
+</p><pre class="programlisting">
+#define _(x) gettext(x)
+</pre><p>
+ Another solution is feasible if the program does much of its
+ communication through one or a few functions, such as
+ <code class="function">ereport()</code> in the backend. Then you make this
+ function call <code class="function">gettext</code> internally on all
+ input strings.
+ </p></li><li class="step"><p>
+ Add a file <code class="filename">nls.mk</code> in the directory with the
+ program sources. This file will be read as a makefile. The
+ following variable assignments need to be made here:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">CATALOG_NAME</code></span></dt><dd><p>
+ The program name, as provided in the
+ <code class="function">textdomain()</code> call.
+ </p></dd><dt><span class="term"><code class="varname">AVAIL_LANGUAGES</code></span></dt><dd><p>
+ List of provided translations — initially empty.
+ </p></dd><dt><span class="term"><code class="varname">GETTEXT_FILES</code></span></dt><dd><p>
+ List of files that contain translatable strings, i.e., those
+ marked with <code class="function">gettext</code> or an alternative
+ solution. Eventually, this will include nearly all source
+ files of the program. If this list gets too long you can
+ make the first <span class="quote">“<span class="quote">file</span>”</span> be a <code class="literal">+</code>
+ and the second word be a file that contains one file name per
+ line.
+ </p></dd><dt><span class="term"><code class="varname">GETTEXT_TRIGGERS</code></span></dt><dd><p>
+ The tools that generate message catalogs for the translators
+ to work on need to know what function calls contain
+ translatable strings. By default, only
+ <code class="function">gettext()</code> calls are known. If you used
+ <code class="function">_</code> or other identifiers you need to list
+ them here. If the translatable string is not the first
+ argument, the item needs to be of the form
+ <code class="literal">func:2</code> (for the second argument).
+ If you have a function that supports pluralized messages,
+ the item should look like <code class="literal">func:1,2</code>
+ (identifying the singular and plural message arguments).
+ </p></dd></dl></div><p>
+ </p></li></ol></div><p>
+ The build system will automatically take care of building and
+ installing the message catalogs.
+ </p></div><div class="sect2" id="NLS-GUIDELINES"><div class="titlepage"><div><div><h3 class="title">57.2.2. Message-Writing Guidelines</h3></div></div></div><p>
+ Here are some guidelines for writing messages that are easily
+ translatable.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Do not construct sentences at run-time, like:
+</p><pre class="programlisting">
+printf("Files were %s.\n", flag ? "copied" : "removed");
+</pre><p>
+ The word order within the sentence might be different in other
+ languages. Also, even if you remember to call <code class="function">gettext()</code> on
+ each fragment, the fragments might not translate well separately. It's
+ better to duplicate a little code so that each message to be
+ translated is a coherent whole. Only numbers, file names, and
+ such-like run-time variables should be inserted at run time into
+ a message text.
+ </p></li><li class="listitem"><p>
+ For similar reasons, this won't work:
+</p><pre class="programlisting">
+printf("copied %d file%s", n, n!=1 ? "s" : "");
+</pre><p>
+ because it assumes how the plural is formed. If you figured you
+ could solve it like this:
+</p><pre class="programlisting">
+if (n==1)
+ printf("copied 1 file");
+else
+ printf("copied %d files", n):
+</pre><p>
+ then be disappointed. Some languages have more than two forms,
+ with some peculiar rules. It's often best to design the message
+ to avoid the issue altogether, for instance like this:
+</p><pre class="programlisting">
+printf("number of copied files: %d", n);
+</pre><p>
+ </p><p>
+ If you really want to construct a properly pluralized message,
+ there is support for this, but it's a bit awkward. When generating
+ a primary or detail error message in <code class="function">ereport()</code>, you can
+ write something like this:
+</p><pre class="programlisting">
+errmsg_plural("copied %d file",
+ "copied %d files",
+ n,
+ n)
+</pre><p>
+ The first argument is the format string appropriate for English
+ singular form, the second is the format string appropriate for
+ English plural form, and the third is the integer control value
+ that determines which plural form to use. Subsequent arguments
+ are formatted per the format string as usual. (Normally, the
+ pluralization control value will also be one of the values to be
+ formatted, so it has to be written twice.) In English it only
+ matters whether <em class="replaceable"><code>n</code></em> is 1 or not 1, but in other
+ languages there can be many different plural forms. The translator
+ sees the two English forms as a group and has the opportunity to
+ supply multiple substitute strings, with the appropriate one being
+ selected based on the run-time value of <em class="replaceable"><code>n</code></em>.
+ </p><p>
+ If you need to pluralize a message that isn't going directly to an
+ <code class="function">errmsg</code> or <code class="function">errdetail</code> report, you have to use
+ the underlying function <code class="function">ngettext</code>. See the gettext
+ documentation.
+ </p></li><li class="listitem"><p>
+ If you want to communicate something to the translator, such as
+ about how a message is intended to line up with other output,
+ precede the occurrence of the string with a comment that starts
+ with <code class="literal">translator</code>, e.g.:
+</p><pre class="programlisting">
+/* translator: This message is not what it seems to be. */
+</pre><p>
+ These comments are copied to the message catalog files so that
+ the translators can see them.
+ </p></li></ul></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="nls-translator.html" title="57.1. For the Translator">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="nls.html" title="Chapter 57. Native Language Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Next</a></td></tr><tr><td width="40%" align="left" valign="top">57.1. For the Translator </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 58. Writing a Procedural Language Handler</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/nls-translator.html b/doc/src/sgml/html/nls-translator.html
new file mode 100644
index 0000000..cfaf7fa
--- /dev/null
+++ b/doc/src/sgml/html/nls-translator.html
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>57.1. For the Translator</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="nls.html" title="Chapter 57. Native Language Support" /><link rel="next" href="nls-programmer.html" title="57.2. For the Programmer" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">57.1. For the Translator</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="nls.html" title="Chapter 57. Native Language Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="nls.html" title="Chapter 57. Native Language Support">Up</a></td><th width="60%" align="center">Chapter 57. Native Language Support</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="nls-programmer.html" title="57.2. For the Programmer">Next</a></td></tr></table><hr /></div><div class="sect1" id="NLS-TRANSLATOR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">57.1. For the Translator</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.3">57.1.1. Requirements</a></span></dt><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.4">57.1.2. Concepts</a></span></dt><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.5">57.1.3. Creating and Maintaining Message Catalogs</a></span></dt><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.6">57.1.4. Editing the PO Files</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span>
+ programs (server and client) can issue their messages in
+ your favorite language — if the messages have been translated.
+ Creating and maintaining translated message sets needs the help of
+ people who speak their own language well and want to contribute to
+ the <span class="productname">PostgreSQL</span> effort. You do not have to be a
+ programmer at all
+ to do this. This section explains how to help.
+ </p><div class="sect2" id="id-1.10.8.2.3"><div class="titlepage"><div><div><h3 class="title">57.1.1. Requirements</h3></div></div></div><p>
+ We won't judge your language skills — this section is about
+ software tools. Theoretically, you only need a text editor. But
+ this is only in the unlikely event that you do not want to try out
+ your translated messages. When you configure your source tree, be
+ sure to use the <code class="option">--enable-nls</code> option. This will
+ also check for the <span class="application">libintl</span> library and the
+ <code class="filename">msgfmt</code> program, which all end users will need
+ anyway. To try out your work, follow the applicable portions of
+ the installation instructions.
+ </p><p>
+ If you want to start a new translation effort or want to do a
+ message catalog merge (described later), you will need the
+ programs <code class="filename">xgettext</code> and
+ <code class="filename">msgmerge</code>, respectively, in a GNU-compatible
+ implementation. Later, we will try to arrange it so that if you
+ use a packaged source distribution, you won't need
+ <code class="filename">xgettext</code>. (If working from Git, you will still need
+ it.) <span class="application">GNU Gettext 0.10.36</span> or later is currently recommended.
+ </p><p>
+ Your local gettext implementation should come with its own
+ documentation. Some of that is probably duplicated in what
+ follows, but for additional details you should look there.
+ </p></div><div class="sect2" id="id-1.10.8.2.4"><div class="titlepage"><div><div><h3 class="title">57.1.2. Concepts</h3></div></div></div><p>
+ The pairs of original (English) messages and their (possibly)
+ translated equivalents are kept in <em class="firstterm">message
+ catalogs</em>, one for each program (although related
+ programs can share a message catalog) and for each target
+ language. There are two file formats for message catalogs: The
+ first is the <span class="quote">“<span class="quote">PO</span>”</span> file (for Portable Object), which
+ is a plain text file with special syntax that translators edit.
+ The second is the <span class="quote">“<span class="quote">MO</span>”</span> file (for Machine Object),
+ which is a binary file generated from the respective PO file and
+ is used while the internationalized program is run. Translators
+ do not deal with MO files; in fact hardly anyone does.
+ </p><p>
+ The extension of the message catalog file is to no surprise either
+ <code class="filename">.po</code> or <code class="filename">.mo</code>. The base
+ name is either the name of the program it accompanies, or the
+ language the file is for, depending on the situation. This is a
+ bit confusing. Examples are <code class="filename">psql.po</code> (PO file
+ for psql) or <code class="filename">fr.mo</code> (MO file in French).
+ </p><p>
+ The file format of the PO files is illustrated here:
+</p><pre class="programlisting">
+# comment
+
+msgid "original string"
+msgstr "translated string"
+
+msgid "more original"
+msgstr "another translated"
+"string can be broken up like this"
+
+...
+</pre><p>
+ The msgid lines are extracted from the program source. (They need not
+ be, but this is the most common way.) The msgstr lines are
+ initially empty and are filled in with useful strings by the
+ translator. The strings can contain C-style escape characters and
+ can be continued across lines as illustrated. (The next line must
+ start at the beginning of the line.)
+ </p><p>
+ The # character introduces a comment. If whitespace immediately
+ follows the # character, then this is a comment maintained by the
+ translator. There can also be automatic comments, which have a
+ non-whitespace character immediately following the #. These are
+ maintained by the various tools that operate on the PO files and
+ are intended to aid the translator.
+</p><pre class="programlisting">
+#. automatic comment
+#: filename.c:1023
+#, flags, flags
+</pre><p>
+ The #. style comments are extracted from the source file where the
+ message is used. Possibly the programmer has inserted information
+ for the translator, such as about expected alignment. The #:
+ comments indicate the exact locations where the message is used
+ in the source. The translator need not look at the program
+ source, but can if there is doubt about the correct
+ translation. The #, comments contain flags that describe the
+ message in some way. There are currently two flags:
+ <code class="literal">fuzzy</code> is set if the message has possibly been
+ outdated because of changes in the program source. The translator
+ can then verify this and possibly remove the fuzzy flag. Note
+ that fuzzy messages are not made available to the end user. The
+ other flag is <code class="literal">c-format</code>, which indicates that
+ the message is a <code class="function">printf</code>-style format
+ template. This means that the translation should also be a format
+ string with the same number and type of placeholders. There are
+ tools that can verify this, which key off the c-format flag.
+ </p></div><div class="sect2" id="id-1.10.8.2.5"><div class="titlepage"><div><div><h3 class="title">57.1.3. Creating and Maintaining Message Catalogs</h3></div></div></div><p>
+ OK, so how does one create a <span class="quote">“<span class="quote">blank</span>”</span> message
+ catalog? First, go into the directory that contains the program
+ whose messages you want to translate. If there is a file
+ <code class="filename">nls.mk</code>, then this program has been prepared
+ for translation.
+ </p><p>
+ If there are already some <code class="filename">.po</code> files, then
+ someone has already done some translation work. The files are
+ named <code class="filename"><em class="replaceable"><code>language</code></em>.po</code>,
+ where <em class="replaceable"><code>language</code></em> is the
+ <a class="ulink" href="https://www.loc.gov/standards/iso639-2/php/English_list.php" target="_top">
+ ISO 639-1 two-letter language code (in lower case)</a>, e.g.,
+ <code class="filename">fr.po</code> for French. If there is really a need
+ for more than one translation effort per language then the files
+ can also be named
+ <code class="filename"><em class="replaceable"><code>language</code></em>_<em class="replaceable"><code>region</code></em>.po</code>
+ where <em class="replaceable"><code>region</code></em> is the
+ <a class="ulink" href="https://www.iso.org/iso-3166-country-codes.html" target="_top">
+ ISO 3166-1 two-letter country code (in upper case)</a>,
+ e.g.,
+ <code class="filename">pt_BR.po</code> for Portuguese in Brazil. If you
+ find the language you wanted you can just start working on that
+ file.
+ </p><p>
+ If you need to start a new translation effort, then first run the
+ command:
+</p><pre class="programlisting">
+make init-po
+</pre><p>
+ This will create a file
+ <code class="filename"><em class="replaceable"><code>progname</code></em>.pot</code>.
+ (<code class="filename">.pot</code> to distinguish it from PO files that
+ are <span class="quote">“<span class="quote">in production</span>”</span>. The <code class="literal">T</code> stands for
+ <span class="quote">“<span class="quote">template</span>”</span>.)
+ Copy this file to
+ <code class="filename"><em class="replaceable"><code>language</code></em>.po</code> and
+ edit it. To make it known that the new language is available,
+ also edit the file <code class="filename">nls.mk</code> and add the
+ language (or language and country) code to the line that looks like:
+</p><pre class="programlisting">
+AVAIL_LANGUAGES := de fr
+</pre><p>
+ (Other languages can appear, of course.)
+ </p><p>
+ As the underlying program or library changes, messages might be
+ changed or added by the programmers. In this case you do not need
+ to start from scratch. Instead, run the command:
+</p><pre class="programlisting">
+make update-po
+</pre><p>
+ which will create a new blank message catalog file (the pot file
+ you started with) and will merge it with the existing PO files.
+ If the merge algorithm is not sure about a particular message it
+ marks it <span class="quote">“<span class="quote">fuzzy</span>”</span> as explained above. The new PO file
+ is saved with a <code class="filename">.po.new</code> extension.
+ </p></div><div class="sect2" id="id-1.10.8.2.6"><div class="titlepage"><div><div><h3 class="title">57.1.4. Editing the PO Files</h3></div></div></div><p>
+ The PO files can be edited with a regular text editor. The
+ translator should only change the area between the quotes after
+ the msgstr directive, add comments, and alter the fuzzy flag.
+ There is (unsurprisingly) a PO mode for Emacs, which I find quite
+ useful.
+ </p><p>
+ The PO files need not be completely filled in. The software will
+ automatically fall back to the original string if no translation
+ (or an empty translation) is available. It is no problem to
+ submit incomplete translations for inclusions in the source tree;
+ that gives room for other people to pick up your work. However,
+ you are encouraged to give priority to removing fuzzy entries
+ after doing a merge. Remember that fuzzy entries will not be
+ installed; they only serve as reference for what might be the right
+ translation.
+ </p><p>
+ Here are some things to keep in mind while editing the
+ translations:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Make sure that if the original ends with a newline, the
+ translation does, too. Similarly for tabs, etc.
+ </p></li><li class="listitem"><p>
+ If the original is a <code class="function">printf</code> format string, the translation
+ also needs to be. The translation also needs to have the same
+ format specifiers in the same order. Sometimes the natural
+ rules of the language make this impossible or at least awkward.
+ In that case you can modify the format specifiers like this:
+</p><pre class="programlisting">
+msgstr "Die Datei %2$s hat %1$u Zeichen."
+</pre><p>
+ Then the first placeholder will actually use the second
+ argument from the list. The
+ <code class="literal"><em class="replaceable"><code>digits</code></em>$</code> needs to
+ follow the % immediately, before any other format manipulators.
+ (This feature really exists in the <code class="function">printf</code>
+ family of functions. You might not have heard of it before because
+ there is little use for it outside of message
+ internationalization.)
+ </p></li><li class="listitem"><p>
+ If the original string contains a linguistic mistake, report
+ that (or fix it yourself in the program source) and translate
+ normally. The corrected string can be merged in when the
+ program sources have been updated. If the original string
+ contains a factual mistake, report that (or fix it yourself)
+ and do not translate it. Instead, you can mark the string with
+ a comment in the PO file.
+ </p></li><li class="listitem"><p>
+ Maintain the style and tone of the original string.
+ Specifically, messages that are not sentences (<code class="literal">cannot
+ open file %s</code>) should probably not start with a
+ capital letter (if your language distinguishes letter case) or
+ end with a period (if your language uses punctuation marks).
+ It might help to read <a class="xref" href="error-style-guide.html" title="56.3. Error Message Style Guide">Section 56.3</a>.
+ </p></li><li class="listitem"><p>
+ If you don't know what a message means, or if it is ambiguous,
+ ask on the developers' mailing list. Chances are that English
+ speaking end users might also not understand it or find it
+ ambiguous, so it's best to improve the message.
+ </p></li></ul></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="nls.html" title="Chapter 57. Native Language Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="nls.html" title="Chapter 57. Native Language Support">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="nls-programmer.html" title="57.2. For the Programmer">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 57. Native Language Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 57.2. For the Programmer</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/nls.html b/doc/src/sgml/html/nls.html
new file mode 100644
index 0000000..fa5d4c3
--- /dev/null
+++ b/doc/src/sgml/html/nls.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 57. Native Language Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="source-conventions.html" title="56.4. Miscellaneous Coding Conventions" /><link rel="next" href="nls-translator.html" title="57.1. For the Translator" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 57. Native Language Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="source-conventions.html" title="56.4. Miscellaneous Coding Conventions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="nls-translator.html" title="57.1. For the Translator">Next</a></td></tr></table><hr /></div><div class="chapter" id="NLS"><div class="titlepage"><div><div><h2 class="title">Chapter 57. Native Language Support</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="nls-translator.html">57.1. For the Translator</a></span></dt><dd><dl><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.3">57.1.1. Requirements</a></span></dt><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.4">57.1.2. Concepts</a></span></dt><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.5">57.1.3. Creating and Maintaining Message Catalogs</a></span></dt><dt><span class="sect2"><a href="nls-translator.html#id-1.10.8.2.6">57.1.4. Editing the PO Files</a></span></dt></dl></dd><dt><span class="sect1"><a href="nls-programmer.html">57.2. For the Programmer</a></span></dt><dd><dl><dt><span class="sect2"><a href="nls-programmer.html#NLS-MECHANICS">57.2.1. Mechanics</a></span></dt><dt><span class="sect2"><a href="nls-programmer.html#NLS-GUIDELINES">57.2.2. Message-Writing Guidelines</a></span></dt></dl></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="source-conventions.html" title="56.4. Miscellaneous Coding Conventions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="nls-translator.html" title="57.1. For the Translator">Next</a></td></tr><tr><td width="40%" align="left" valign="top">56.4. Miscellaneous Coding Conventions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 57.1. For the Translator</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/non-durability.html b/doc/src/sgml/html/non-durability.html
new file mode 100644
index 0000000..d219821
--- /dev/null
+++ b/doc/src/sgml/html/non-durability.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>14.5. Non-Durable Settings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="populate.html" title="14.4. Populating a Database" /><link rel="next" href="parallel-query.html" title="Chapter 15. Parallel Query" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">14.5. Non-Durable Settings</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="populate.html" title="14.4. Populating a Database">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><th width="60%" align="center">Chapter 14. Performance Tips</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="parallel-query.html" title="Chapter 15. Parallel Query">Next</a></td></tr></table><hr /></div><div class="sect1" id="NON-DURABILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">14.5. Non-Durable Settings</h2></div></div></div><a id="id-1.5.13.8.2" class="indexterm"></a><p>
+ Durability is a database feature that guarantees the recording of
+ committed transactions even if the server crashes or loses
+ power. However, durability adds significant database overhead,
+ so if your site does not require such a guarantee,
+ <span class="productname">PostgreSQL</span> can be configured to run
+ much faster. The following are configuration changes you can make
+ to improve performance in such cases. Except as noted below, durability
+ is still guaranteed in case of a crash of the database software;
+ only an abrupt operating system crash creates a risk of data loss
+ or corruption when these settings are used.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Place the database cluster's data directory in a memory-backed
+ file system (i.e., <acronym class="acronym">RAM</acronym> disk). This eliminates all
+ database disk I/O, but limits data storage to the amount of
+ available memory (and perhaps swap).
+ </p></li><li class="listitem"><p>
+ Turn off <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a>; there is no need to flush
+ data to disk.
+ </p></li><li class="listitem"><p>
+ Turn off <a class="xref" href="runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT">synchronous_commit</a>; there might be no
+ need to force <acronym class="acronym">WAL</acronym> writes to disk on every
+ commit. This setting does risk transaction loss (though not data
+ corruption) in case of a crash of the <span class="emphasis"><em>database</em></span>.
+ </p></li><li class="listitem"><p>
+ Turn off <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a>; there is no need
+ to guard against partial page writes.
+ </p></li><li class="listitem"><p>
+ Increase <a class="xref" href="runtime-config-wal.html#GUC-MAX-WAL-SIZE">max_wal_size</a> and <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-TIMEOUT">checkpoint_timeout</a>; this reduces the frequency
+ of checkpoints, but increases the storage requirements of
+ <code class="filename">/pg_wal</code>.
+ </p></li><li class="listitem"><p>
+ Create <a class="link" href="sql-createtable.html#SQL-CREATETABLE-UNLOGGED">unlogged
+ tables</a> to avoid <acronym class="acronym">WAL</acronym> writes, though it
+ makes the tables non-crash-safe.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="populate.html" title="14.4. Populating a Database">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="parallel-query.html" title="Chapter 15. Parallel Query">Next</a></td></tr><tr><td width="40%" align="left" valign="top">14.4. Populating a Database </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 15. Parallel Query</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/notation.html b/doc/src/sgml/html/notation.html
new file mode 100644
index 0000000..85cd72e
--- /dev/null
+++ b/doc/src/sgml/html/notation.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3. Conventions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="history.html" title="2. A Brief History of PostgreSQL" /><link rel="next" href="resources.html" title="4. Further Information" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3. Conventions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="history.html" title="2. A Brief History of PostgreSQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><th width="60%" align="center">Preface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="resources.html" title="4. Further Information">Next</a></td></tr></table><hr /></div><div class="sect1" id="NOTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3. Conventions</h2></div></div></div><p>
+ The following conventions are used in the synopsis of a command:
+ brackets (<code class="literal">[</code> and <code class="literal">]</code>) indicate
+ optional parts. Braces
+ (<code class="literal">{</code> and <code class="literal">}</code>) and vertical lines
+ (<code class="literal">|</code>) indicate that you must choose one
+ alternative. Dots (<code class="literal">...</code>) mean that the preceding element
+ can be repeated. All other symbols, including parentheses, should be
+ taken literally.
+ </p><p>
+ Where it enhances the clarity, SQL commands are preceded by the
+ prompt <code class="literal">=&gt;</code>, and shell commands are preceded by the
+ prompt <code class="literal">$</code>. Normally, prompts are not shown, though.
+ </p><p>
+ An <em class="firstterm">administrator</em> is generally a person who is
+ in charge of installing and running the server. A <em class="firstterm">user</em>
+ could be anyone who is using, or wants to use, any part of the
+ <span class="productname">PostgreSQL</span> system. These terms should not
+ be interpreted too narrowly; this book does not have fixed
+ presumptions about system administration procedures.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="history.html" title="2. A Brief History of PostgreSQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="resources.html" title="4. Further Information">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2. A Brief History of <span class="productname">PostgreSQL</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 4. Further Information</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/oid2name.html b/doc/src/sgml/html/oid2name.html
new file mode 100644
index 0000000..57e83eb
--- /dev/null
+++ b/doc/src/sgml/html/oid2name.html
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>oid2name</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-prog-client.html" title="G.1. Client Applications" /><link rel="next" href="vacuumlo.html" title="vacuumlo" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">oid2name</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-prog-client.html" title="G.1. Client Applications">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib-prog-client.html" title="G.1. Client Applications">Up</a></td><th width="60%" align="center">G.1. Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="vacuumlo.html" title="vacuumlo">Next</a></td></tr></table><hr /></div><div class="refentry" id="OID2NAME"><div class="titlepage"></div><a id="id-1.11.8.4.3.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">oid2name</span></h2><p>oid2name — resolve OIDs and file nodes in a <span class="productname">PostgreSQL</span> data directory</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.11.8.4.3.4.1"><code class="command">oid2name</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.11.8.4.3.5"><h2>Description</h2><p>
+ <span class="application">oid2name</span> is a utility program that helps administrators to
+ examine the file structure used by PostgreSQL. To make use of it, you need
+ to be familiar with the database file structure, which is described in
+ <a class="xref" href="storage.html" title="Chapter 73. Database Physical Storage">Chapter 73</a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The name <span class="quote">“<span class="quote">oid2name</span>”</span> is historical, and is actually rather
+ misleading, since most of the time when you use it, you will really
+ be concerned with tables' filenode numbers (which are the file names
+ visible in the database directories). Be sure you understand the
+ difference between table OIDs and table filenodes!
+ </p></div><p>
+ <span class="application">oid2name</span> connects to a target database and
+ extracts OID, filenode, and/or table name information. You can also have
+ it show database OIDs or tablespace OIDs.
+ </p></div><div class="refsect1" id="id-1.11.8.4.3.6"><h2>Options</h2><p>
+ <span class="application">oid2name</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-f <em class="replaceable"><code>filenode</code></em></code><br /></span><span class="term"><code class="option">--filenode=<em class="replaceable"><code>filenode</code></em></code></span></dt><dd><p>show info for table with filenode <em class="replaceable"><code>filenode</code></em>.</p></dd><dt><span class="term"><code class="option">-i</code><br /></span><span class="term"><code class="option">--indexes</code></span></dt><dd><p>include indexes and sequences in the listing.</p></dd><dt><span class="term"><code class="option">-o <em class="replaceable"><code>oid</code></em></code><br /></span><span class="term"><code class="option">--oid=<em class="replaceable"><code>oid</code></em></code></span></dt><dd><p>show info for table with OID <em class="replaceable"><code>oid</code></em>.</p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>omit headers (useful for scripting).</p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--tablespaces</code></span></dt><dd><p>show tablespace OIDs.</p></dd><dt><span class="term"><code class="option">-S</code><br /></span><span class="term"><code class="option">--system-objects</code></span></dt><dd><p>include system objects (those in
+ <code class="option">information_schema</code>, <code class="option">pg_toast</code>
+ and <code class="option">pg_catalog</code> schemas).
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>tablename_pattern</code></em></code><br /></span><span class="term"><code class="option">--table=<em class="replaceable"><code>tablename_pattern</code></em></code></span></dt><dd><p>show info for table(s) matching <em class="replaceable"><code>tablename_pattern</code></em>.</p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">oid2name</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-x</code><br /></span><span class="term"><code class="option">--extended</code></span></dt><dd><p>display more information about each object shown: tablespace name,
+ schema name, and OID.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">oid2name</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">oid2name</span> also accepts the following command-line
+ arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>database</code></em></code><br /></span><span class="term"><code class="option">--dbname=<em class="replaceable"><code>database</code></em></code></span></dt><dd><p>database to connect to.</p></dd><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>database server's host.</p></dd><dt><span class="term"><code class="option">-H <em class="replaceable"><code>host</code></em></code></span></dt><dd><p>database server's host. Use of this parameter is
+ <span class="emphasis"><em>deprecated</em></span> as of
+ <span class="productname">PostgreSQL</span> 12.</p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>database server's port.</p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>user name to connect as.</p></dd></dl></div><p>
+ </p><p>
+ To display specific tables, select which tables to show by
+ using <code class="option">-o</code>, <code class="option">-f</code> and/or <code class="option">-t</code>.
+ <code class="option">-o</code> takes an OID,
+ <code class="option">-f</code> takes a filenode,
+ and <code class="option">-t</code> takes a table name (actually, it's a <code class="literal">LIKE</code>
+ pattern, so you can use things like <code class="literal">foo%</code>).
+ You can use as many
+ of these options as you like, and the listing will include all objects
+ matched by any of the options. But note that these options can only
+ show objects in the database given by <code class="option">-d</code>.
+ </p><p>
+ If you don't give any of <code class="option">-o</code>, <code class="option">-f</code> or <code class="option">-t</code>,
+ but do give <code class="option">-d</code>, it will list all tables in the database
+ named by <code class="option">-d</code>. In this mode, the <code class="option">-S</code> and
+ <code class="option">-i</code> options control what gets listed.
+ </p><p>
+ If you don't give <code class="option">-d</code> either, it will show a listing of database
+ OIDs. Alternatively you can give <code class="option">-s</code> to get a tablespace
+ listing.
+ </p></div><div class="refsect1" id="id-1.11.8.4.3.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span>
+ utilities, also uses the environment variables supported by
+ <span class="application">libpq</span> (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.11.8.4.3.8"><h2>Notes</h2><p>
+ <span class="application">oid2name</span> requires a running database server with
+ non-corrupt system catalogs. It is therefore of only limited use
+ for recovering from catastrophic database corruption situations.
+ </p></div><div class="refsect1" id="id-1.11.8.4.3.9"><h2>Examples</h2><pre class="screen">
+$ # what's in this database server, anyway?
+$ oid2name
+All databases:
+ Oid Database Name Tablespace
+----------------------------------
+ 17228 alvherre pg_default
+ 17255 regression pg_default
+ 17227 template0 pg_default
+ 1 template1 pg_default
+
+$ oid2name -s
+All tablespaces:
+ Oid Tablespace Name
+-------------------------
+ 1663 pg_default
+ 1664 pg_global
+ 155151 fastdisk
+ 155152 bigdisk
+
+$ # OK, let's look into database alvherre
+$ cd $PGDATA/base/17228
+
+$ # get top 10 db objects in the default tablespace, ordered by size
+$ ls -lS * | head -10
+-rw------- 1 alvherre alvherre 136536064 sep 14 09:51 155173
+-rw------- 1 alvherre alvherre 17965056 sep 14 09:51 1155291
+-rw------- 1 alvherre alvherre 1204224 sep 14 09:51 16717
+-rw------- 1 alvherre alvherre 581632 sep 6 17:51 1255
+-rw------- 1 alvherre alvherre 237568 sep 14 09:50 16674
+-rw------- 1 alvherre alvherre 212992 sep 14 09:51 1249
+-rw------- 1 alvherre alvherre 204800 sep 14 09:51 16684
+-rw------- 1 alvherre alvherre 196608 sep 14 09:50 16700
+-rw------- 1 alvherre alvherre 163840 sep 14 09:50 16699
+-rw------- 1 alvherre alvherre 122880 sep 6 17:51 16751
+
+$ # I wonder what file 155173 is ...
+$ oid2name -d alvherre -f 155173
+From database "alvherre":
+ Filenode Table Name
+----------------------
+ 155173 accounts
+
+$ # you can ask for more than one object
+$ oid2name -d alvherre -f 155173 -f 1155291
+From database "alvherre":
+ Filenode Table Name
+-------------------------
+ 155173 accounts
+ 1155291 accounts_pkey
+
+$ # you can mix the options, and get more details with -x
+$ oid2name -d alvherre -t accounts -f 1155291 -x
+From database "alvherre":
+ Filenode Table Name Oid Schema Tablespace
+------------------------------------------------------
+ 155173 accounts 155173 public pg_default
+ 1155291 accounts_pkey 1155291 public pg_default
+
+$ # show disk space for every db object
+$ du [0-9]* |
+&gt; while read SIZE FILENODE
+&gt; do
+&gt; echo "$SIZE `oid2name -q -d alvherre -i -f $FILENODE`"
+&gt; done
+16 1155287 branches_pkey
+16 1155289 tellers_pkey
+17561 1155291 accounts_pkey
+...
+
+$ # same, but sort by size
+$ du [0-9]* | sort -rn | while read SIZE FN
+&gt; do
+&gt; echo "$SIZE `oid2name -q -d alvherre -f $FN`"
+&gt; done
+133466 155173 accounts
+17561 1155291 accounts_pkey
+1177 16717 pg_proc_proname_args_nsp_index
+...
+
+$ # If you want to see what's in tablespaces, use the pg_tblspc directory
+$ cd $PGDATA/pg_tblspc
+$ oid2name -s
+All tablespaces:
+ Oid Tablespace Name
+-------------------------
+ 1663 pg_default
+ 1664 pg_global
+ 155151 fastdisk
+ 155152 bigdisk
+
+$ # what databases have objects in tablespace "fastdisk"?
+$ ls -d 155151/*
+155151/17228/ 155151/PG_VERSION
+
+$ # Oh, what was database 17228 again?
+$ oid2name
+All databases:
+ Oid Database Name Tablespace
+----------------------------------
+ 17228 alvherre pg_default
+ 17255 regression pg_default
+ 17227 template0 pg_default
+ 1 template1 pg_default
+
+$ # Let's see what objects does this database have in the tablespace.
+$ cd 155151/17228
+$ ls -l
+total 0
+-rw------- 1 postgres postgres 0 sep 13 23:20 155156
+
+$ # OK, this is a pretty small table ... but which one is it?
+$ oid2name -d alvherre -f 155156
+From database "alvherre":
+ Filenode Table Name
+----------------------
+ 155156 foo
+</pre></div><div class="refsect1" id="id-1.11.8.4.3.10"><h2>Author</h2><p>
+ B. Palmer <code class="email">&lt;<a class="email" href="mailto:bpalmer@crimelabs.net">bpalmer@crimelabs.net</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-prog-client.html" title="G.1. Client Applications">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib-prog-client.html" title="G.1. Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="vacuumlo.html" title="vacuumlo">Next</a></td></tr><tr><td width="40%" align="left" valign="top">G.1. Client Applications </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">vacuumlo</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/oldsnapshot.html b/doc/src/sgml/html/oldsnapshot.html
new file mode 100644
index 0000000..5847ec0
--- /dev/null
+++ b/doc/src/sgml/html/oldsnapshot.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.24. old_snapshot</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="ltree.html" title="F.23. ltree" /><link rel="next" href="pageinspect.html" title="F.25. pageinspect" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.24. old_snapshot</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="ltree.html" title="F.23. ltree">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pageinspect.html" title="F.25. pageinspect">Next</a></td></tr></table><hr /></div><div class="sect1" id="OLDSNAPSHOT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.24. old_snapshot</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="oldsnapshot.html#id-1.11.7.33.4">F.24.1. Functions</a></span></dt></dl></div><a id="id-1.11.7.33.2" class="indexterm"></a><p>
+ The <code class="filename">old_snapshot</code> module allows inspection
+ of the server state that is used to implement
+ <a class="xref" href="runtime-config-resource.html#GUC-OLD-SNAPSHOT-THRESHOLD">old_snapshot_threshold</a>.
+ </p><div class="sect2" id="id-1.11.7.33.4"><div class="titlepage"><div><div><h3 class="title">F.24.1. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">pg_old_snapshot_time_mapping(array_offset OUT int4, end_timestamp OUT timestamptz, newest_xmin OUT xid) returns setof record</code></span></dt><dd><p>
+ Returns all of the entries in the server's timestamp to XID mapping.
+ Each entry represents the newest xmin of any snapshot taken in the
+ corresponding minute.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="ltree.html" title="F.23. ltree">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pageinspect.html" title="F.25. pageinspect">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.23. ltree </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.25. pageinspect</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/overview.html b/doc/src/sgml/html/overview.html
new file mode 100644
index 0000000..c1bdd12
--- /dev/null
+++ b/doc/src/sgml/html/overview.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 52. Overview of PostgreSQL Internals</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="internals.html" title="Part VII. Internals" /><link rel="next" href="query-path.html" title="52.1. The Path of a Query" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 52. Overview of PostgreSQL Internals</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="internals.html" title="Part VII. Internals">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="query-path.html" title="52.1. The Path of a Query">Next</a></td></tr></table><hr /></div><div class="chapter" id="OVERVIEW"><div class="titlepage"><div><div><h2 class="title">Chapter 52. Overview of PostgreSQL Internals</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="query-path.html">52.1. The Path of a Query</a></span></dt><dt><span class="sect1"><a href="connect-estab.html">52.2. How Connections Are Established</a></span></dt><dt><span class="sect1"><a href="parser-stage.html">52.3. The Parser Stage</a></span></dt><dd><dl><dt><span class="sect2"><a href="parser-stage.html#id-1.10.3.6.3">52.3.1. Parser</a></span></dt><dt><span class="sect2"><a href="parser-stage.html#id-1.10.3.6.4">52.3.2. Transformation Process</a></span></dt></dl></dd><dt><span class="sect1"><a href="rule-system.html">52.4. The <span class="productname">PostgreSQL</span> Rule System</a></span></dt><dt><span class="sect1"><a href="planner-optimizer.html">52.5. Planner/Optimizer</a></span></dt><dd><dl><dt><span class="sect2"><a href="planner-optimizer.html#id-1.10.3.8.5">52.5.1. Generating Possible Plans</a></span></dt></dl></dd><dt><span class="sect1"><a href="executor.html">52.6. Executor</a></span></dt></dl></div><div class="note"><h3 class="title">Author</h3><p>
+ This chapter originated as part of
+ <a class="xref" href="biblio.html#SIM98" title="Enhancement of the ANSI SQL Implementation of PostgreSQL">[sim98]</a> Stefan Simkovics'
+ Master's Thesis prepared at Vienna University of Technology under the direction
+ of O.Univ.Prof.Dr. Georg Gottlob and Univ.Ass. Mag. Katrin Seyr.
+ </p></div><p>
+ This chapter gives an overview of the internal structure of the
+ backend of <span class="productname">PostgreSQL</span>. After having
+ read the following sections you should have an idea of how a query
+ is processed. This chapter is intended to help the reader
+ understand the general sequence of operations that occur within the
+ backend from the point at which a query is received, to the point
+ at which the results are returned to the client.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="internals.html" title="Part VII. Internals">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="query-path.html" title="52.1. The Path of a Query">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part VII. Internals </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 52.1. The Path of a Query</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pageinspect.html b/doc/src/sgml/html/pageinspect.html
new file mode 100644
index 0000000..6d53bae
--- /dev/null
+++ b/doc/src/sgml/html/pageinspect.html
@@ -0,0 +1,567 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.25. pageinspect</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="oldsnapshot.html" title="F.24. old_snapshot" /><link rel="next" href="passwordcheck.html" title="F.26. passwordcheck" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.25. pageinspect</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="oldsnapshot.html" title="F.24. old_snapshot">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="passwordcheck.html" title="F.26. passwordcheck">Next</a></td></tr></table><hr /></div><div class="sect1" id="PAGEINSPECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.25. pageinspect</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.4">F.25.1. General Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.5">F.25.2. Heap Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.6">F.25.3. B-Tree Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.7">F.25.4. BRIN Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.8">F.25.5. GIN Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.9">F.25.6. GiST Functions</a></span></dt><dt><span class="sect2"><a href="pageinspect.html#id-1.11.7.34.10">F.25.7. Hash Functions</a></span></dt></dl></div><a id="id-1.11.7.34.2" class="indexterm"></a><p>
+ The <code class="filename">pageinspect</code> module provides functions that allow you to
+ inspect the contents of database pages at a low level, which is useful for
+ debugging purposes. All of these functions may be used only by superusers.
+ </p><div class="sect2" id="id-1.11.7.34.4"><div class="titlepage"><div><div><h3 class="title">F.25.1. General Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">get_raw_page(relname text, fork text, blkno bigint) returns bytea</code>
+ <a id="id-1.11.7.34.4.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">get_raw_page</code> reads the specified block of the named
+ relation and returns a copy as a <code class="type">bytea</code> value. This allows a
+ single time-consistent copy of the block to be obtained.
+ <em class="replaceable"><code>fork</code></em> should be <code class="literal">'main'</code> for
+ the main data fork, <code class="literal">'fsm'</code> for the
+ <a class="link" href="storage-fsm.html" title="73.3. Free Space Map">free space map</a>,
+ <code class="literal">'vm'</code> for the
+ <a class="link" href="storage-vm.html" title="73.4. Visibility Map">visibility map</a>, or
+ <code class="literal">'init'</code> for the initialization fork.
+ </p></dd><dt><span class="term">
+ <code class="function">get_raw_page(relname text, blkno bigint) returns bytea</code>
+ </span></dt><dd><p>
+ A shorthand version of <code class="function">get_raw_page</code>, for reading
+ from the main fork. Equivalent to
+ <code class="literal">get_raw_page(relname, 'main', blkno)</code>
+ </p></dd><dt><span class="term">
+ <code class="function">page_header(page bytea) returns record</code>
+ <a id="id-1.11.7.34.4.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">page_header</code> shows fields that are common to all
+ <span class="productname">PostgreSQL</span> heap and index pages.
+ </p><p>
+ A page image obtained with <code class="function">get_raw_page</code> should be
+ passed as argument. For example:
+</p><pre class="screen">
+test=# SELECT * FROM page_header(get_raw_page('pg_class', 0));
+ lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid
+-----------+----------+--------+-------+-------+---------+----------+---------+-----------
+ 0/24A1B50 | 0 | 1 | 232 | 368 | 8192 | 8192 | 4 | 0
+</pre><p>
+ The returned columns correspond to the fields in the
+ <code class="structname">PageHeaderData</code> struct.
+ See <code class="filename">src/include/storage/bufpage.h</code> for details.
+ </p><p>
+ The <code class="structfield">checksum</code> field is the checksum stored in
+ the page, which might be incorrect if the page is somehow corrupted. If
+ data checksums are not enabled for this instance, then the value stored
+ is meaningless.
+ </p></dd><dt><span class="term">
+ <code class="function">page_checksum(page bytea, blkno bigint) returns smallint</code>
+ <a id="id-1.11.7.34.4.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">page_checksum</code> computes the checksum for the page, as if
+ it was located at the given block.
+ </p><p>
+ A page image obtained with <code class="function">get_raw_page</code> should be
+ passed as argument. For example:
+</p><pre class="screen">
+test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0);
+ page_checksum
+---------------
+ 13443
+</pre><p>
+ Note that the checksum depends on the block number, so matching block
+ numbers should be passed (except when doing esoteric debugging).
+ </p><p>
+ The checksum computed with this function can be compared with
+ the <code class="structfield">checksum</code> result field of the
+ function <code class="function">page_header</code>. If data checksums are
+ enabled for this instance, then the two values should be equal.
+ </p></dd><dt><span class="term">
+ <code class="function">fsm_page_contents(page bytea) returns text</code>
+ <a id="id-1.11.7.34.4.2.5.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">fsm_page_contents</code> shows the internal node structure
+ of an <acronym class="acronym">FSM</acronym> page. For example:
+</p><pre class="screen">
+test=# SELECT fsm_page_contents(get_raw_page('pg_class', 'fsm', 0));
+</pre><p>
+ The output is a multiline string, with one line per node in the binary
+ tree within the page. Only those nodes that are not zero are printed.
+ The so-called "next" pointer, which points to the next slot to be
+ returned from the page, is also printed.
+ </p><p>
+ See <code class="filename">src/backend/storage/freespace/README</code> for more
+ information on the structure of an <acronym class="acronym">FSM</acronym> page.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.34.5"><div class="titlepage"><div><div><h3 class="title">F.25.2. Heap Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">heap_page_items(page bytea) returns setof record</code>
+ <a id="id-1.11.7.34.5.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">heap_page_items</code> shows all line pointers on a heap
+ page. For those line pointers that are in use, tuple headers as well
+ as tuple raw data are also shown. All tuples are shown, whether or not
+ the tuples were visible to an MVCC snapshot at the time the raw page
+ was copied.
+ </p><p>
+ A heap page image obtained with <code class="function">get_raw_page</code> should
+ be passed as argument. For example:
+</p><pre class="screen">
+test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0));
+</pre><p>
+ See <code class="filename">src/include/storage/itemid.h</code> and
+ <code class="filename">src/include/access/htup_details.h</code> for explanations of the fields
+ returned.
+ </p><p>
+ The <code class="function">heap_tuple_infomask_flags</code> function can be
+ used to unpack the flag bits of <code class="structfield">t_infomask</code>
+ and <code class="structfield">t_infomask2</code> for heap tuples.
+ </p></dd><dt><span class="term">
+ <code class="function">tuple_data_split(rel_oid oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[]</code>
+ <a id="id-1.11.7.34.5.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">tuple_data_split</code> splits tuple data into attributes
+ in the same way as backend internals.
+</p><pre class="screen">
+test=# SELECT tuple_data_split('pg_class'::regclass, t_data, t_infomask, t_infomask2, t_bits) FROM heap_page_items(get_raw_page('pg_class', 0));
+</pre><p>
+ This function should be called with the same arguments as the return
+ attributes of <code class="function">heap_page_items</code>.
+ </p><p>
+ If <em class="parameter"><code>do_detoast</code></em> is <code class="literal">true</code>,
+ attributes will be detoasted as needed. Default value is
+ <code class="literal">false</code>.
+ </p></dd><dt><span class="term">
+ <code class="function">heap_page_item_attrs(page bytea, rel_oid regclass [, do_detoast bool]) returns setof record</code>
+ <a id="id-1.11.7.34.5.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">heap_page_item_attrs</code> is equivalent to
+ <code class="function">heap_page_items</code> except that it returns
+ tuple raw data as an array of attributes that can optionally
+ be detoasted by <em class="parameter"><code>do_detoast</code></em> which is
+ <code class="literal">false</code> by default.
+ </p><p>
+ A heap page image obtained with <code class="function">get_raw_page</code> should
+ be passed as argument. For example:
+</p><pre class="screen">
+test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class'::regclass);
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">heap_tuple_infomask_flags(t_infomask integer, t_infomask2 integer) returns record</code>
+ <a id="id-1.11.7.34.5.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">heap_tuple_infomask_flags</code> decodes the
+ <code class="structfield">t_infomask</code> and
+ <code class="structfield">t_infomask2</code> returned by
+ <code class="function">heap_page_items</code> into a human-readable
+ set of arrays made of flag names, with one column for all
+ the flags and one column for combined flags. For example:
+</p><pre class="screen">
+test=# SELECT t_ctid, raw_flags, combined_flags
+ FROM heap_page_items(get_raw_page('pg_class', 0)),
+ LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2)
+ WHERE t_infomask IS NOT NULL OR t_infomask2 IS NOT NULL;
+</pre><p>
+ This function should be called with the same arguments as the return
+ attributes of <code class="function">heap_page_items</code>.
+ </p><p>
+ Combined flags are displayed for source-level macros that take into
+ account the value of more than one raw bit, such as
+ <code class="literal">HEAP_XMIN_FROZEN</code>.
+ </p><p>
+ See <code class="filename">src/include/access/htup_details.h</code> for
+ explanations of the flag names returned.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.34.6"><div class="titlepage"><div><div><h3 class="title">F.25.3. B-Tree Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">bt_metap(relname text) returns record</code>
+ <a id="id-1.11.7.34.6.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">bt_metap</code> returns information about a B-tree
+ index's metapage. For example:
+</p><pre class="screen">
+test=# SELECT * FROM bt_metap('pg_cast_oid_index');
+-[ RECORD 1 ]-------------+-------
+magic | 340322
+version | 4
+root | 1
+level | 0
+fastroot | 1
+fastlevel | 0
+last_cleanup_num_delpages | 0
+last_cleanup_num_tuples | 230
+allequalimage | f
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">bt_page_stats(relname text, blkno bigint) returns record</code>
+ <a id="id-1.11.7.34.6.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">bt_page_stats</code> returns summary information about
+ single pages of B-tree indexes. For example:
+</p><pre class="screen">
+test=# SELECT * FROM bt_page_stats('pg_cast_oid_index', 1);
+-[ RECORD 1 ]-+-----
+blkno | 1
+type | l
+live_items | 224
+dead_items | 0
+avg_item_size | 16
+page_size | 8192
+free_size | 3668
+btpo_prev | 0
+btpo_next | 0
+btpo_level | 0
+btpo_flags | 3
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">bt_page_items(relname text, blkno bigint) returns setof record</code>
+ <a id="id-1.11.7.34.6.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">bt_page_items</code> returns detailed information about
+ all of the items on a B-tree index page. For example:
+</p><pre class="screen">
+test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids
+ FROM bt_page_items('tenk2_hundred', 5);
+ itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids
+------------+-----------+---------+-------+------+-------------------------+------+--------+---------------------
+ 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | |
+ 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"}
+ 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"}
+ 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"}
+ 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"}
+ 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"}
+ 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"}
+ 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"}
+ 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"}
+ 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"}
+ 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"}
+ 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"}
+ 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"}
+(13 rows)
+</pre><p>
+ This is a B-tree leaf page. All tuples that point to the table
+ happen to be posting list tuples (all of which store a total of
+ 100 6 byte TIDs). There is also a <span class="quote">“<span class="quote">high key</span>”</span> tuple
+ at <code class="literal">itemoffset</code> number 1.
+ <code class="structfield">ctid</code> is used to store encoded
+ information about each tuple in this example, though leaf page
+ tuples often store a heap TID directly in the
+ <code class="structfield">ctid</code> field instead.
+ <code class="structfield">tids</code> is the list of TIDs stored as a
+ posting list.
+ </p><p>
+ In an internal page (not shown), the block number part of
+ <code class="structfield">ctid</code> is a <span class="quote">“<span class="quote">downlink</span>”</span>,
+ which is a block number of another page in the index itself.
+ The offset part (the second number) of
+ <code class="structfield">ctid</code> stores encoded information about
+ the tuple, such as the number of columns present (suffix
+ truncation may have removed unneeded suffix columns). Truncated
+ columns are treated as having the value <span class="quote">“<span class="quote">minus
+ infinity</span>”</span>.
+ </p><p>
+ <code class="structfield">htid</code> shows a heap TID for the tuple,
+ regardless of the underlying tuple representation. This value
+ may match <code class="structfield">ctid</code>, or may be decoded
+ from the alternative representations used by posting list tuples
+ and tuples from internal pages. Tuples in internal pages
+ usually have the implementation level heap TID column truncated
+ away, which is represented as a NULL
+ <code class="structfield">htid</code> value.
+ </p><p>
+ Note that the first item on any non-rightmost page (any page with
+ a non-zero value in the <code class="structfield">btpo_next</code> field) is the
+ page's <span class="quote">“<span class="quote">high key</span>”</span>, meaning its <code class="structfield">data</code>
+ serves as an upper bound on all items appearing on the page, while
+ its <code class="structfield">ctid</code> field does not point to
+ another block. Also, on internal pages, the first real data
+ item (the first item that is not a high key) reliably has every
+ column truncated away, leaving no actual value in its
+ <code class="structfield">data</code> field. Such an item does have a
+ valid downlink in its <code class="structfield">ctid</code> field,
+ however.
+ </p><p>
+ For more details about the structure of B-tree indexes, see
+ <a class="xref" href="btree-implementation.html#BTREE-STRUCTURE" title="67.4.1. B-Tree Structure">Section 67.4.1</a>. For more details about
+ deduplication and posting lists, see <a class="xref" href="btree-implementation.html#BTREE-DEDUPLICATION" title="67.4.3. Deduplication">Section 67.4.3</a>.
+ </p></dd><dt><span class="term">
+ <code class="function">bt_page_items(page bytea) returns setof record</code>
+ <a id="id-1.11.7.34.6.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ It is also possible to pass a page to <code class="function">bt_page_items</code>
+ as a <code class="type">bytea</code> value. A page image obtained
+ with <code class="function">get_raw_page</code> should be passed as argument. So
+ the last example could also be rewritten like this:
+</p><pre class="screen">
+test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids
+ FROM bt_page_items(get_raw_page('tenk2_hundred', 5));
+ itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids
+------------+-----------+---------+-------+------+-------------------------+------+--------+---------------------
+ 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | |
+ 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"}
+ 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"}
+ 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"}
+ 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"}
+ 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"}
+ 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"}
+ 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"}
+ 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"}
+ 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"}
+ 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"}
+ 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"}
+ 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"}
+(13 rows)
+</pre><p>
+ All the other details are the same as explained in the previous item.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.34.7"><div class="titlepage"><div><div><h3 class="title">F.25.4. BRIN Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">brin_page_type(page bytea) returns text</code>
+ <a id="id-1.11.7.34.7.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">brin_page_type</code> returns the page type of the given
+ <acronym class="acronym">BRIN</acronym> index page, or throws an error if the page is
+ not a valid <acronym class="acronym">BRIN</acronym> page. For example:
+</p><pre class="screen">
+test=# SELECT brin_page_type(get_raw_page('brinidx', 0));
+ brin_page_type
+----------------
+ meta
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">brin_metapage_info(page bytea) returns record</code>
+ <a id="id-1.11.7.34.7.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">brin_metapage_info</code> returns assorted information
+ about a <acronym class="acronym">BRIN</acronym> index metapage. For example:
+</p><pre class="screen">
+test=# SELECT * FROM brin_metapage_info(get_raw_page('brinidx', 0));
+ magic | version | pagesperrange | lastrevmappage
+------------+---------+---------------+----------------
+ 0xA8109CFA | 1 | 4 | 2
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">brin_revmap_data(page bytea) returns setof tid</code>
+ <a id="id-1.11.7.34.7.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">brin_revmap_data</code> returns the list of tuple
+ identifiers in a <acronym class="acronym">BRIN</acronym> index range map page.
+ For example:
+</p><pre class="screen">
+test=# SELECT * FROM brin_revmap_data(get_raw_page('brinidx', 2)) LIMIT 5;
+ pages
+---------
+ (6,137)
+ (6,138)
+ (6,139)
+ (6,140)
+ (6,141)
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">brin_page_items(page bytea, index oid) returns setof record</code>
+ <a id="id-1.11.7.34.7.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">brin_page_items</code> returns the data stored in the
+ <acronym class="acronym">BRIN</acronym> data page. For example:
+</p><pre class="screen">
+test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5),
+ 'brinidx')
+ ORDER BY blknum, attnum LIMIT 6;
+ itemoffset | blknum | attnum | allnulls | hasnulls | placeholder | value
+------------+--------+--------+----------+----------+-------------+--------------
+ 137 | 0 | 1 | t | f | f |
+ 137 | 0 | 2 | f | f | f | {1 .. 88}
+ 138 | 4 | 1 | t | f | f |
+ 138 | 4 | 2 | f | f | f | {89 .. 176}
+ 139 | 8 | 1 | t | f | f |
+ 139 | 8 | 2 | f | f | f | {177 .. 264}
+</pre><p>
+ The returned columns correspond to the fields in the
+ <code class="structname">BrinMemTuple</code> and <code class="structname">BrinValues</code> structs.
+ See <code class="filename">src/include/access/brin_tuple.h</code> for details.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.34.8"><div class="titlepage"><div><div><h3 class="title">F.25.5. GIN Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">gin_metapage_info(page bytea) returns record</code>
+ <a id="id-1.11.7.34.8.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">gin_metapage_info</code> returns information about
+ a <acronym class="acronym">GIN</acronym> index metapage. For example:
+</p><pre class="screen">
+test=# SELECT * FROM gin_metapage_info(get_raw_page('gin_index', 0));
+-[ RECORD 1 ]----+-----------
+pending_head | 4294967295
+pending_tail | 4294967295
+tail_free_size | 0
+n_pending_pages | 0
+n_pending_tuples | 0
+n_total_pages | 7
+n_entry_pages | 6
+n_data_pages | 0
+n_entries | 693
+version | 2
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">gin_page_opaque_info(page bytea) returns record</code>
+ <a id="id-1.11.7.34.8.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">gin_page_opaque_info</code> returns information about
+ a <acronym class="acronym">GIN</acronym> index opaque area, like the page type.
+ For example:
+</p><pre class="screen">
+test=# SELECT * FROM gin_page_opaque_info(get_raw_page('gin_index', 2));
+ rightlink | maxoff | flags
+-----------+--------+------------------------
+ 5 | 0 | {data,leaf,compressed}
+(1 row)
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">gin_leafpage_items(page bytea) returns setof record</code>
+ <a id="id-1.11.7.34.8.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">gin_leafpage_items</code> returns information about
+ the data stored in a <acronym class="acronym">GIN</acronym> leaf page. For example:
+</p><pre class="screen">
+test=# SELECT first_tid, nbytes, tids[0:5] AS some_tids
+ FROM gin_leafpage_items(get_raw_page('gin_test_idx', 2));
+ first_tid | nbytes | some_tids
+-----------+--------+----------------------------------------------------------
+ (8,41) | 244 | {"(8,41)","(8,43)","(8,44)","(8,45)","(8,46)"}
+ (10,45) | 248 | {"(10,45)","(10,46)","(10,47)","(10,48)","(10,49)"}
+ (12,52) | 248 | {"(12,52)","(12,53)","(12,54)","(12,55)","(12,56)"}
+ (14,59) | 320 | {"(14,59)","(14,60)","(14,61)","(14,62)","(14,63)"}
+ (167,16) | 376 | {"(167,16)","(167,17)","(167,18)","(167,19)","(167,20)"}
+ (170,30) | 376 | {"(170,30)","(170,31)","(170,32)","(170,33)","(170,34)"}
+ (173,44) | 197 | {"(173,44)","(173,45)","(173,46)","(173,47)","(173,48)"}
+(7 rows)
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.34.9"><div class="titlepage"><div><div><h3 class="title">F.25.6. GiST Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">gist_page_opaque_info(page bytea) returns record</code>
+ <a id="id-1.11.7.34.9.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">gist_page_opaque_info</code> returns information from
+ a <acronym class="acronym">GiST</acronym> index page's opaque area, such as the NSN,
+ rightlink and page type.
+ For example:
+</p><pre class="screen">
+test=# SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2));
+ lsn | nsn | rightlink | flags
+-----+-----+-----------+--------
+ 0/1 | 0/0 | 1 | {leaf}
+(1 row)
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">gist_page_items(page bytea, index_oid regclass) returns setof record</code>
+ <a id="id-1.11.7.34.9.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">gist_page_items</code> returns information about
+ the data stored in a page of a <acronym class="acronym">GiST</acronym> index. For example:
+</p><pre class="screen">
+test=# SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx');
+ itemoffset | ctid | itemlen | dead | keys
+------------+-----------+---------+------+-------------------------------
+ 1 | (1,65535) | 40 | f | (p)=("(185,185),(1,1)")
+ 2 | (2,65535) | 40 | f | (p)=("(370,370),(186,186)")
+ 3 | (3,65535) | 40 | f | (p)=("(555,555),(371,371)")
+ 4 | (4,65535) | 40 | f | (p)=("(740,740),(556,556)")
+ 5 | (5,65535) | 40 | f | (p)=("(870,870),(741,741)")
+ 6 | (6,65535) | 40 | f | (p)=("(1000,1000),(871,871)")
+(6 rows)
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">gist_page_items_bytea(page bytea) returns setof record</code>
+ <a id="id-1.11.7.34.9.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Same as <code class="function">gist_page_items</code>, but returns the key data
+ as a raw <code class="type">bytea</code> blob. Since it does not attempt to decode
+ the key, it does not need to know which index is involved. For
+ example:
+</p><pre class="screen">
+test=# SELECT * FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0));
+ itemoffset | ctid | itemlen | dead | key_data
+------------+-----------+---------+------+-----------------------------------------​-------------------------------------------
+ 1 | (1,65535) | 40 | f | \x00000100ffff28000000000000c0644000000000​00c06440000000000000f03f000000000000f03f
+ 2 | (2,65535) | 40 | f | \x00000200ffff28000000000000c0744000000000​00c074400000000000e064400000000000e06440
+ 3 | (3,65535) | 40 | f | \x00000300ffff28000000000000207f4000000000​00207f400000000000d074400000000000d07440
+ 4 | (4,65535) | 40 | f | \x00000400ffff28000000000000c0844000000000​00c084400000000000307f400000000000307f40
+ 5 | (5,65535) | 40 | f | \x00000500ffff28000000000000f0894000000000​00f089400000000000c884400000000000c88440
+ 6 | (6,65535) | 40 | f | \x00000600ffff28000000000000208f4000000000​00208f400000000000f889400000000000f88940
+ 7 | (7,65535) | 40 | f | \x00000700ffff28000000000000408f4000000000​00408f400000000000288f400000000000288f40
+(7 rows)
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.34.10"><div class="titlepage"><div><div><h3 class="title">F.25.7. Hash Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">hash_page_type(page bytea) returns text</code>
+ <a id="id-1.11.7.34.10.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">hash_page_type</code> returns page type of
+ the given <acronym class="acronym">HASH</acronym> index page. For example:
+</p><pre class="screen">
+test=# SELECT hash_page_type(get_raw_page('con_hash_index', 0));
+ hash_page_type
+----------------
+ metapage
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">hash_page_stats(page bytea) returns setof record</code>
+ <a id="id-1.11.7.34.10.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">hash_page_stats</code> returns information about
+ a bucket or overflow page of a <acronym class="acronym">HASH</acronym> index.
+ For example:
+</p><pre class="screen">
+test=# SELECT * FROM hash_page_stats(get_raw_page('con_hash_index', 1));
+-[ RECORD 1 ]---+-----------
+live_items | 407
+dead_items | 0
+page_size | 8192
+free_size | 8
+hasho_prevblkno | 4096
+hasho_nextblkno | 8474
+hasho_bucket | 0
+hasho_flag | 66
+hasho_page_id | 65408
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">hash_page_items(page bytea) returns setof record</code>
+ <a id="id-1.11.7.34.10.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">hash_page_items</code> returns information about
+ the data stored in a bucket or overflow page of a <acronym class="acronym">HASH</acronym>
+ index page. For example:
+</p><pre class="screen">
+test=# SELECT * FROM hash_page_items(get_raw_page('con_hash_index', 1)) LIMIT 5;
+ itemoffset | ctid | data
+------------+-----------+------------
+ 1 | (899,77) | 1053474816
+ 2 | (897,29) | 1053474816
+ 3 | (894,207) | 1053474816
+ 4 | (892,159) | 1053474816
+ 5 | (890,111) | 1053474816
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">hash_bitmap_info(index oid, blkno bigint) returns record</code>
+ <a id="id-1.11.7.34.10.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">hash_bitmap_info</code> shows the status of a bit
+ in the bitmap page for a particular overflow page of <acronym class="acronym">HASH</acronym>
+ index. For example:
+</p><pre class="screen">
+test=# SELECT * FROM hash_bitmap_info('con_hash_index', 2052);
+ bitmapblkno | bitmapbit | bitstatus
+-------------+-----------+-----------
+ 65 | 3 | t
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">hash_metapage_info(page bytea) returns record</code>
+ <a id="id-1.11.7.34.10.2.5.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">hash_metapage_info</code> returns information stored
+ in the meta page of a <acronym class="acronym">HASH</acronym> index. For example:
+</p><pre class="screen">
+test=# SELECT magic, version, ntuples, ffactor, bsize, bmsize, bmshift,
+test-# maxbucket, highmask, lowmask, ovflpoint, firstfree, nmaps, procid,
+test-# regexp_replace(spares::text, '(,0)*}', '}') as spares,
+test-# regexp_replace(mapp::text, '(,0)*}', '}') as mapp
+test-# FROM hash_metapage_info(get_raw_page('con_hash_index', 0));
+-[ RECORD 1 ]-------------------------------------------------​------------------------------
+magic | 105121344
+version | 4
+ntuples | 500500
+ffactor | 40
+bsize | 8152
+bmsize | 4096
+bmshift | 15
+maxbucket | 12512
+highmask | 16383
+lowmask | 8191
+ovflpoint | 28
+firstfree | 1204
+nmaps | 1
+procid | 450
+spares | {0,0,0,0,0,0,1,1,1,1,1,1,1,1,3,4,4,4,45,55,58,59,​508,567,628,704,1193,1202,1204}
+mapp | {65}
+</pre><p>
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="oldsnapshot.html" title="F.24. old_snapshot">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="passwordcheck.html" title="F.26. passwordcheck">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.24. old_snapshot </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.26. passwordcheck</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pagelayout.svg b/doc/src/sgml/html/pagelayout.svg
new file mode 100644
index 0000000..5b2caaf
--- /dev/null
+++ b/doc/src/sgml/html/pagelayout.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 610 210" width="610" height="210" shape-rendering="geometricPrecision" version="1.0">
+ <defs>
+ <filter id="f2" x="0" y="0" width="200%" height="200%">
+ <feOffset result="offOut" in="SourceGraphic" dx="5" dy="5"/>
+ <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
+ <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
+ </filter>
+ </defs>
+ <g stroke-width="1" stroke-linecap="square" stroke-linejoin="round">
+ <rect x="0" y="0" width="610" height="210" style="fill: #ffffff"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M25.0 35.0 L25.0 175.0 L585.0 175.0 L585.0 35.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M305.0 175.0 L485.0 175.0 L485.0 147.0 L305.0 147.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M25.0 35.0 L25.0 63.0 L195.0 63.0 L195.0 35.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M305.0 147.0 L305.0 175.0 L195.0 175.0 L195.0 147.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M325.0 63.0 L325.0 91.0 L265.0 91.0 L265.0 105.0 L235.0 105.0 L235.0 63.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M585.0 147.0 L585.0 175.0 L485.0 175.0 L485.0 147.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M195.0 35.0 L285.0 35.0 L285.0 63.0 L195.0 63.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M375.0 35.0 L375.0 63.0 L285.0 63.0 L285.0 35.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M335.0 133.0 L335.0 105.0 L265.0 105.0 "/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M470.0 42.0 L480.0 49.0 L470.0 56.0 z"/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M260.0 126.0 L265.0 140.0 L270.0 126.0 z"/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M330.0 126.0 L335.0 140.0 L340.0 126.0 z"/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M140.0 154.0 L130.0 161.0 L140.0 168.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M265.0 105.0 L265.0 133.0 "/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-dasharray="5.000000,5.000000" stroke-miterlimit="0" stroke-linecap="butt" stroke-linejoin="round" fill="white" d="M375.0 49.0 L475.0 49.0 "/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-dasharray="5.000000,5.000000" stroke-miterlimit="0" stroke-linecap="butt" stroke-linejoin="round" fill="white" d="M135.0 161.0 L195.0 161.0 "/>
+ <text x="48" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">PageHeaderData</text>
+ <text x="214" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">Item</text>
+ <text x="216" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">ItemId</text>
+ <text x="306" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">ItemId</text>
+ <text x="324" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">Item</text>
+ <text x="509" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">Special</text>
+ </g>
+</svg>
diff --git a/doc/src/sgml/html/parallel-plans.html b/doc/src/sgml/html/parallel-plans.html
new file mode 100644
index 0000000..f0e6911
--- /dev/null
+++ b/doc/src/sgml/html/parallel-plans.html
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>15.3. Parallel Plans</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?" /><link rel="next" href="parallel-safety.html" title="15.4. Parallel Safety" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">15.3. Parallel Plans</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><th width="60%" align="center">Chapter 15. Parallel Query</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="parallel-safety.html" title="15.4. Parallel Safety">Next</a></td></tr></table><hr /></div><div class="sect1" id="PARALLEL-PLANS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">15.3. Parallel Plans</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-SCANS">15.3.1. Parallel Scans</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-JOINS">15.3.2. Parallel Joins</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-AGGREGATION">15.3.3. Parallel Aggregation</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-APPEND">15.3.4. Parallel Append</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-PLAN-TIPS">15.3.5. Parallel Plan Tips</a></span></dt></dl></div><p>
+ Because each worker executes the parallel portion of the plan to
+ completion, it is not possible to simply take an ordinary query plan
+ and run it using multiple workers. Each worker would produce a full
+ copy of the output result set, so the query would not run any faster
+ than normal but would produce incorrect results. Instead, the parallel
+ portion of the plan must be what is known internally to the query
+ optimizer as a <em class="firstterm">partial plan</em>; that is, it must be constructed
+ so that each process that executes the plan will generate only a
+ subset of the output rows in such a way that each required output row
+ is guaranteed to be generated by exactly one of the cooperating processes.
+ Generally, this means that the scan on the driving table of the query
+ must be a parallel-aware scan.
+ </p><div class="sect2" id="PARALLEL-SCANS"><div class="titlepage"><div><div><h3 class="title">15.3.1. Parallel Scans</h3></div></div></div><p>
+ The following types of parallel-aware table scans are currently supported.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ In a <span class="emphasis"><em>parallel sequential scan</em></span>, the table's blocks will
+ be divided into ranges and shared among the cooperating processes. Each
+ worker process will complete the scanning of its given range of blocks before
+ requesting an additional range of blocks.
+ </p></li><li class="listitem"><p>
+ In a <span class="emphasis"><em>parallel bitmap heap scan</em></span>, one process is chosen
+ as the leader. That process performs a scan of one or more indexes
+ and builds a bitmap indicating which table blocks need to be visited.
+ These blocks are then divided among the cooperating processes as in
+ a parallel sequential scan. In other words, the heap scan is performed
+ in parallel, but the underlying index scan is not.
+ </p></li><li class="listitem"><p>
+ In a <span class="emphasis"><em>parallel index scan</em></span> or <span class="emphasis"><em>parallel index-only
+ scan</em></span>, the cooperating processes take turns reading data from the
+ index. Currently, parallel index scans are supported only for
+ btree indexes. Each process will claim a single index block and will
+ scan and return all tuples referenced by that block; other processes can
+ at the same time be returning tuples from a different index block.
+ The results of a parallel btree scan are returned in sorted order
+ within each worker process.
+ </p></li></ul></div><p>
+
+ Other scan types, such as scans of non-btree indexes, may support
+ parallel scans in the future.
+ </p></div><div class="sect2" id="PARALLEL-JOINS"><div class="titlepage"><div><div><h3 class="title">15.3.2. Parallel Joins</h3></div></div></div><p>
+ Just as in a non-parallel plan, the driving table may be joined to one or
+ more other tables using a nested loop, hash join, or merge join. The
+ inner side of the join may be any kind of non-parallel plan that is
+ otherwise supported by the planner provided that it is safe to run within
+ a parallel worker. Depending on the join type, the inner side may also be
+ a parallel plan.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ In a <span class="emphasis"><em>nested loop join</em></span>, the inner side is always
+ non-parallel. Although it is executed in full, this is efficient if
+ the inner side is an index scan, because the outer tuples and thus
+ the loops that look up values in the index are divided over the
+ cooperating processes.
+ </p></li><li class="listitem"><p>
+ In a <span class="emphasis"><em>merge join</em></span>, the inner side is always
+ a non-parallel plan and therefore executed in full. This may be
+ inefficient, especially if a sort must be performed, because the work
+ and resulting data are duplicated in every cooperating process.
+ </p></li><li class="listitem"><p>
+ In a <span class="emphasis"><em>hash join</em></span> (without the "parallel" prefix),
+ the inner side is executed in full by every cooperating process
+ to build identical copies of the hash table. This may be inefficient
+ if the hash table is large or the plan is expensive. In a
+ <span class="emphasis"><em>parallel hash join</em></span>, the inner side is a
+ <span class="emphasis"><em>parallel hash</em></span> that divides the work of building
+ a shared hash table over the cooperating processes.
+ </p></li></ul></div></div><div class="sect2" id="PARALLEL-AGGREGATION"><div class="titlepage"><div><div><h3 class="title">15.3.3. Parallel Aggregation</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> supports parallel aggregation by aggregating in
+ two stages. First, each process participating in the parallel portion of
+ the query performs an aggregation step, producing a partial result for
+ each group of which that process is aware. This is reflected in the plan
+ as a <code class="literal">Partial Aggregate</code> node. Second, the partial results are
+ transferred to the leader via <code class="literal">Gather</code> or <code class="literal">Gather
+ Merge</code>. Finally, the leader re-aggregates the results across all
+ workers in order to produce the final result. This is reflected in the
+ plan as a <code class="literal">Finalize Aggregate</code> node.
+ </p><p>
+ Because the <code class="literal">Finalize Aggregate</code> node runs on the leader
+ process, queries that produce a relatively large number of groups in
+ comparison to the number of input rows will appear less favorable to the
+ query planner. For example, in the worst-case scenario the number of
+ groups seen by the <code class="literal">Finalize Aggregate</code> node could be as many as
+ the number of input rows that were seen by all worker processes in the
+ <code class="literal">Partial Aggregate</code> stage. For such cases, there is clearly
+ going to be no performance benefit to using parallel aggregation. The
+ query planner takes this into account during the planning process and is
+ unlikely to choose parallel aggregate in this scenario.
+ </p><p>
+ Parallel aggregation is not supported in all situations. Each aggregate
+ must be <a class="link" href="parallel-safety.html" title="15.4. Parallel Safety">safe</a> for parallelism and must
+ have a combine function. If the aggregate has a transition state of type
+ <code class="literal">internal</code>, it must have serialization and deserialization
+ functions. See <a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a> for more details.
+ Parallel aggregation is not supported if any aggregate function call
+ contains <code class="literal">DISTINCT</code> or <code class="literal">ORDER BY</code> clause and is also
+ not supported for ordered set aggregates or when the query involves
+ <code class="literal">GROUPING SETS</code>. It can only be used when all joins involved in
+ the query are also part of the parallel portion of the plan.
+ </p></div><div class="sect2" id="PARALLEL-APPEND"><div class="titlepage"><div><div><h3 class="title">15.3.4. Parallel Append</h3></div></div></div><p>
+ Whenever <span class="productname">PostgreSQL</span> needs to combine rows
+ from multiple sources into a single result set, it uses an
+ <code class="literal">Append</code> or <code class="literal">MergeAppend</code> plan node.
+ This commonly happens when implementing <code class="literal">UNION ALL</code> or
+ when scanning a partitioned table. Such nodes can be used in parallel
+ plans just as they can in any other plan. However, in a parallel plan,
+ the planner may instead use a <code class="literal">Parallel Append</code> node.
+ </p><p>
+ When an <code class="literal">Append</code> node is used in a parallel plan, each
+ process will execute the child plans in the order in which they appear,
+ so that all participating processes cooperate to execute the first child
+ plan until it is complete and then move to the second plan at around the
+ same time. When a <code class="literal">Parallel Append</code> is used instead, the
+ executor will instead spread out the participating processes as evenly as
+ possible across its child plans, so that multiple child plans are executed
+ simultaneously. This avoids contention, and also avoids paying the startup
+ cost of a child plan in those processes that never execute it.
+ </p><p>
+ Also, unlike a regular <code class="literal">Append</code> node, which can only have
+ partial children when used within a parallel plan, a <code class="literal">Parallel
+ Append</code> node can have both partial and non-partial child plans.
+ Non-partial children will be scanned by only a single process, since
+ scanning them more than once would produce duplicate results. Plans that
+ involve appending multiple results sets can therefore achieve
+ coarse-grained parallelism even when efficient partial plans are not
+ available. For example, consider a query against a partitioned table
+ that can only be implemented efficiently by using an index that does
+ not support parallel scans. The planner might choose a <code class="literal">Parallel
+ Append</code> of regular <code class="literal">Index Scan</code> plans; each
+ individual index scan would have to be executed to completion by a single
+ process, but different scans could be performed at the same time by
+ different processes.
+ </p><p>
+ <a class="xref" href="runtime-config-query.html#GUC-ENABLE-PARALLEL-APPEND">enable_parallel_append</a> can be used to disable
+ this feature.
+ </p></div><div class="sect2" id="PARALLEL-PLAN-TIPS"><div class="titlepage"><div><div><h3 class="title">15.3.5. Parallel Plan Tips</h3></div></div></div><p>
+ If a query that is expected to do so does not produce a parallel plan,
+ you can try reducing <a class="xref" href="runtime-config-query.html#GUC-PARALLEL-SETUP-COST">parallel_setup_cost</a> or
+ <a class="xref" href="runtime-config-query.html#GUC-PARALLEL-TUPLE-COST">parallel_tuple_cost</a>. Of course, this plan may turn
+ out to be slower than the serial plan that the planner preferred, but
+ this will not always be the case. If you don't get a parallel
+ plan even with very small values of these settings (e.g., after setting
+ them both to zero), there may be some reason why the query planner is
+ unable to generate a parallel plan for your query. See
+ <a class="xref" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Section 15.2</a> and
+ <a class="xref" href="parallel-safety.html" title="15.4. Parallel Safety">Section 15.4</a> for information on why this may be
+ the case.
+ </p><p>
+ When executing a parallel plan, you can use <code class="literal">EXPLAIN (ANALYZE,
+ VERBOSE)</code> to display per-worker statistics for each plan node.
+ This may be useful in determining whether the work is being evenly
+ distributed between all plan nodes and more generally in understanding the
+ performance characteristics of the plan.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="when-can-parallel-query-be-used.html" title="15.2. When Can Parallel Query Be Used?">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="parallel-safety.html" title="15.4. Parallel Safety">Next</a></td></tr><tr><td width="40%" align="left" valign="top">15.2. When Can Parallel Query Be Used? </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 15.4. Parallel Safety</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/parallel-query.html b/doc/src/sgml/html/parallel-query.html
new file mode 100644
index 0000000..07fc5ea
--- /dev/null
+++ b/doc/src/sgml/html/parallel-query.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 15. Parallel Query</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="non-durability.html" title="14.5. Non-Durable Settings" /><link rel="next" href="how-parallel-query-works.html" title="15.1. How Parallel Query Works" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 15. Parallel Query</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="non-durability.html" title="14.5. Non-Durable Settings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="how-parallel-query-works.html" title="15.1. How Parallel Query Works">Next</a></td></tr></table><hr /></div><div class="chapter" id="PARALLEL-QUERY"><div class="titlepage"><div><div><h2 class="title">Chapter 15. Parallel Query</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="how-parallel-query-works.html">15.1. How Parallel Query Works</a></span></dt><dt><span class="sect1"><a href="when-can-parallel-query-be-used.html">15.2. When Can Parallel Query Be Used?</a></span></dt><dt><span class="sect1"><a href="parallel-plans.html">15.3. Parallel Plans</a></span></dt><dd><dl><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-SCANS">15.3.1. Parallel Scans</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-JOINS">15.3.2. Parallel Joins</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-AGGREGATION">15.3.3. Parallel Aggregation</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-APPEND">15.3.4. Parallel Append</a></span></dt><dt><span class="sect2"><a href="parallel-plans.html#PARALLEL-PLAN-TIPS">15.3.5. Parallel Plan Tips</a></span></dt></dl></dd><dt><span class="sect1"><a href="parallel-safety.html">15.4. Parallel Safety</a></span></dt><dd><dl><dt><span class="sect2"><a href="parallel-safety.html#PARALLEL-LABELING">15.4.1. Parallel Labeling for Functions and Aggregates</a></span></dt></dl></dd></dl></div><a id="id-1.5.14.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> can devise query plans that can leverage
+ multiple CPUs in order to answer queries faster. This feature is known
+ as parallel query. Many queries cannot benefit from parallel query, either
+ due to limitations of the current implementation or because there is no
+ imaginable query plan that is any faster than the serial query plan.
+ However, for queries that can benefit, the speedup from parallel query
+ is often very significant. Many queries can run more than twice as fast
+ when using parallel query, and some queries can run four times faster or
+ even more. Queries that touch a large amount of data but return only a
+ few rows to the user will typically benefit most. This chapter explains
+ some details of how parallel query works and in which situations it can be
+ used so that users who wish to make use of it can understand what to expect.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="non-durability.html" title="14.5. Non-Durable Settings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="how-parallel-query-works.html" title="15.1. How Parallel Query Works">Next</a></td></tr><tr><td width="40%" align="left" valign="top">14.5. Non-Durable Settings </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 15.1. How Parallel Query Works</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/parallel-safety.html b/doc/src/sgml/html/parallel-safety.html
new file mode 100644
index 0000000..6d4b485
--- /dev/null
+++ b/doc/src/sgml/html/parallel-safety.html
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>15.4. Parallel Safety</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="parallel-plans.html" title="15.3. Parallel Plans" /><link rel="next" href="admin.html" title="Part III. Server Administration" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">15.4. Parallel Safety</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="parallel-plans.html" title="15.3. Parallel Plans">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><th width="60%" align="center">Chapter 15. Parallel Query</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="admin.html" title="Part III. Server Administration">Next</a></td></tr></table><hr /></div><div class="sect1" id="PARALLEL-SAFETY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">15.4. Parallel Safety</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="parallel-safety.html#PARALLEL-LABELING">15.4.1. Parallel Labeling for Functions and Aggregates</a></span></dt></dl></div><p>
+ The planner classifies operations involved in a query as either
+ <em class="firstterm">parallel safe</em>, <em class="firstterm">parallel restricted</em>,
+ or <em class="firstterm">parallel unsafe</em>. A parallel safe operation is one that
+ does not conflict with the use of parallel query. A parallel restricted
+ operation is one that cannot be performed in a parallel worker, but that
+ can be performed in the leader while parallel query is in use. Therefore,
+ parallel restricted operations can never occur below a <code class="literal">Gather</code>
+ or <code class="literal">Gather Merge</code> node, but can occur elsewhere in a plan that
+ contains such a node. A parallel unsafe operation is one that cannot
+ be performed while parallel query is in use, not even in the leader.
+ When a query contains anything that is parallel unsafe, parallel query
+ is completely disabled for that query.
+ </p><p>
+ The following operations are always parallel restricted:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Scans of common table expressions (CTEs).
+ </p></li><li class="listitem"><p>
+ Scans of temporary tables.
+ </p></li><li class="listitem"><p>
+ Scans of foreign tables, unless the foreign data wrapper has
+ an <code class="literal">IsForeignScanParallelSafe</code> API that indicates otherwise.
+ </p></li><li class="listitem"><p>
+ Plan nodes to which an <code class="literal">InitPlan</code> is attached.
+ </p></li><li class="listitem"><p>
+ Plan nodes that reference a correlated <code class="literal">SubPlan</code>.
+ </p></li></ul></div><div class="sect2" id="PARALLEL-LABELING"><div class="titlepage"><div><div><h3 class="title">15.4.1. Parallel Labeling for Functions and Aggregates</h3></div></div></div><p>
+ The planner cannot automatically determine whether a user-defined
+ function or aggregate is parallel safe, parallel restricted, or parallel
+ unsafe, because this would require predicting every operation that the
+ function could possibly perform. In general, this is equivalent to the
+ Halting Problem and therefore impossible. Even for simple functions
+ where it could conceivably be done, we do not try, since this would be expensive
+ and error-prone. Instead, all user-defined functions are assumed to
+ be parallel unsafe unless otherwise marked. When using
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> or
+ <a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>, markings can be set by specifying
+ <code class="literal">PARALLEL SAFE</code>, <code class="literal">PARALLEL RESTRICTED</code>, or
+ <code class="literal">PARALLEL UNSAFE</code> as appropriate. When using
+ <a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a>, the
+ <code class="literal">PARALLEL</code> option can be specified with <code class="literal">SAFE</code>,
+ <code class="literal">RESTRICTED</code>, or <code class="literal">UNSAFE</code> as the corresponding value.
+ </p><p>
+ Functions and aggregates must be marked <code class="literal">PARALLEL UNSAFE</code> if
+ they write to the database, access sequences, change the transaction state
+ even temporarily (e.g., a PL/pgSQL function that establishes an
+ <code class="literal">EXCEPTION</code> block to catch errors), or make persistent changes to
+ settings. Similarly, functions must be marked <code class="literal">PARALLEL
+ RESTRICTED</code> if they access temporary tables, client connection state,
+ cursors, prepared statements, or miscellaneous backend-local state that
+ the system cannot synchronize across workers. For example,
+ <code class="literal">setseed</code> and <code class="literal">random</code> are parallel restricted for
+ this last reason.
+ </p><p>
+ In general, if a function is labeled as being safe when it is restricted or
+ unsafe, or if it is labeled as being restricted when it is in fact unsafe,
+ it may throw errors or produce wrong answers when used in a parallel query.
+ C-language functions could in theory exhibit totally undefined behavior if
+ mislabeled, since there is no way for the system to protect itself against
+ arbitrary C code, but in most likely cases the result will be no worse than
+ for any other function. If in doubt, it is probably best to label functions
+ as <code class="literal">UNSAFE</code>.
+ </p><p>
+ If a function executed within a parallel worker acquires locks that are
+ not held by the leader, for example by querying a table not referenced in
+ the query, those locks will be released at worker exit, not end of
+ transaction. If you write a function that does this, and this behavior
+ difference is important to you, mark such functions as
+ <code class="literal">PARALLEL RESTRICTED</code>
+ to ensure that they execute only in the leader.
+ </p><p>
+ Note that the query planner does not consider deferring the evaluation of
+ parallel-restricted functions or aggregates involved in the query in
+ order to obtain a superior plan. So, for example, if a <code class="literal">WHERE</code>
+ clause applied to a particular table is parallel restricted, the query
+ planner will not consider performing a scan of that table in the parallel
+ portion of a plan. In some cases, it would be
+ possible (and perhaps even efficient) to include the scan of that table in
+ the parallel portion of the query and defer the evaluation of the
+ <code class="literal">WHERE</code> clause so that it happens above the <code class="literal">Gather</code>
+ node. However, the planner does not do this.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="parallel-plans.html" title="15.3. Parallel Plans">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="admin.html" title="Part III. Server Administration">Next</a></td></tr><tr><td width="40%" align="left" valign="top">15.3. Parallel Plans </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part III. Server Administration</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/parser-stage.html b/doc/src/sgml/html/parser-stage.html
new file mode 100644
index 0000000..4b041c7
--- /dev/null
+++ b/doc/src/sgml/html/parser-stage.html
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>52.3. The Parser Stage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="connect-estab.html" title="52.2. How Connections Are Established" /><link rel="next" href="rule-system.html" title="52.4. The PostgreSQL Rule System" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">52.3. The Parser Stage</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="connect-estab.html" title="52.2. How Connections Are Established">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><th width="60%" align="center">Chapter 52. Overview of PostgreSQL Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rule-system.html" title="52.4. The PostgreSQL Rule System">Next</a></td></tr></table><hr /></div><div class="sect1" id="PARSER-STAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">52.3. The Parser Stage</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="parser-stage.html#id-1.10.3.6.3">52.3.1. Parser</a></span></dt><dt><span class="sect2"><a href="parser-stage.html#id-1.10.3.6.4">52.3.2. Transformation Process</a></span></dt></dl></div><p>
+ The <em class="firstterm">parser stage</em> consists of two parts:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The <em class="firstterm">parser</em> defined in
+ <code class="filename">gram.y</code> and <code class="filename">scan.l</code> is
+ built using the Unix tools <span class="application">bison</span>
+ and <span class="application">flex</span>.
+ </p></li><li class="listitem"><p>
+ The <em class="firstterm">transformation process</em> does
+ modifications and augmentations to the data structures returned by the parser.
+ </p></li></ul></div><p>
+ </p><div class="sect2" id="id-1.10.3.6.3"><div class="titlepage"><div><div><h3 class="title">52.3.1. Parser</h3></div></div></div><p>
+ The parser has to check the query string (which arrives as plain
+ text) for valid syntax. If the syntax is correct a
+ <em class="firstterm">parse tree</em> is built up and handed back;
+ otherwise an error is returned. The parser and lexer are
+ implemented using the well-known Unix tools <span class="application">bison</span>
+ and <span class="application">flex</span>.
+ </p><p>
+ The <em class="firstterm">lexer</em> is defined in the file
+ <code class="filename">scan.l</code> and is responsible
+ for recognizing <em class="firstterm">identifiers</em>,
+ the <em class="firstterm">SQL key words</em> etc. For
+ every key word or identifier that is found, a <em class="firstterm">token</em>
+ is generated and handed to the parser.
+ </p><p>
+ The parser is defined in the file <code class="filename">gram.y</code> and
+ consists of a set of <em class="firstterm">grammar rules</em> and
+ <em class="firstterm">actions</em> that are executed whenever a rule
+ is fired. The code of the actions (which is actually C code) is
+ used to build up the parse tree.
+ </p><p>
+ The file <code class="filename">scan.l</code> is transformed to the C
+ source file <code class="filename">scan.c</code> using the program
+ <span class="application">flex</span> and <code class="filename">gram.y</code> is
+ transformed to <code class="filename">gram.c</code> using
+ <span class="application">bison</span>. After these transformations
+ have taken place a normal C compiler can be used to create the
+ parser. Never make any changes to the generated C files as they
+ will be overwritten the next time <span class="application">flex</span>
+ or <span class="application">bison</span> is called.
+
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The mentioned transformations and compilations are normally done
+ automatically using the <em class="firstterm">makefiles</em>
+ shipped with the <span class="productname">PostgreSQL</span>
+ source distribution.
+ </p></div><p>
+ </p><p>
+ A detailed description of <span class="application">bison</span> or
+ the grammar rules given in <code class="filename">gram.y</code> would be
+ beyond the scope of this manual. There are many books and
+ documents dealing with <span class="application">flex</span> and
+ <span class="application">bison</span>. You should be familiar with
+ <span class="application">bison</span> before you start to study the
+ grammar given in <code class="filename">gram.y</code> otherwise you won't
+ understand what happens there.
+ </p></div><div class="sect2" id="id-1.10.3.6.4"><div class="titlepage"><div><div><h3 class="title">52.3.2. Transformation Process</h3></div></div></div><p>
+ The parser stage creates a parse tree using only fixed rules about
+ the syntactic structure of SQL. It does not make any lookups in the
+ system catalogs, so there is no possibility to understand the detailed
+ semantics of the requested operations. After the parser completes,
+ the <em class="firstterm">transformation process</em> takes the tree handed
+ back by the parser as input and does the semantic interpretation needed
+ to understand which tables, functions, and operators are referenced by
+ the query. The data structure that is built to represent this
+ information is called the <em class="firstterm">query tree</em>.
+ </p><p>
+ The reason for separating raw parsing from semantic analysis is that
+ system catalog lookups can only be done within a transaction, and we
+ do not wish to start a transaction immediately upon receiving a query
+ string. The raw parsing stage is sufficient to identify the transaction
+ control commands (<code class="command">BEGIN</code>, <code class="command">ROLLBACK</code>, etc.), and
+ these can then be correctly executed without any further analysis.
+ Once we know that we are dealing with an actual query (such as
+ <code class="command">SELECT</code> or <code class="command">UPDATE</code>), it is okay to
+ start a transaction if we're not already in one. Only then can the
+ transformation process be invoked.
+ </p><p>
+ The query tree created by the transformation process is structurally
+ similar to the raw parse tree in most places, but it has many differences
+ in detail. For example, a <code class="structname">FuncCall</code> node in the
+ parse tree represents something that looks syntactically like a function
+ call. This might be transformed to either a <code class="structname">FuncExpr</code>
+ or <code class="structname">Aggref</code> node depending on whether the referenced
+ name turns out to be an ordinary function or an aggregate function.
+ Also, information about the actual data types of columns and expression
+ results is added to the query tree.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="connect-estab.html" title="52.2. How Connections Are Established">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rule-system.html" title="52.4. The PostgreSQL Rule System">Next</a></td></tr><tr><td width="40%" align="left" valign="top">52.2. How Connections Are Established </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 52.4. The <span class="productname">PostgreSQL</span> Rule System</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/passwordcheck.html b/doc/src/sgml/html/passwordcheck.html
new file mode 100644
index 0000000..2f5b32a
--- /dev/null
+++ b/doc/src/sgml/html/passwordcheck.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.26. passwordcheck</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pageinspect.html" title="F.25. pageinspect" /><link rel="next" href="pgbuffercache.html" title="F.27. pg_buffercache" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.26. passwordcheck</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pageinspect.html" title="F.25. pageinspect">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgbuffercache.html" title="F.27. pg_buffercache">Next</a></td></tr></table><hr /></div><div class="sect1" id="PASSWORDCHECK"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.26. passwordcheck</h2></div></div></div><a id="id-1.11.7.35.2" class="indexterm"></a><p>
+ The <code class="filename">passwordcheck</code> module checks users' passwords
+ whenever they are set with
+ <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a> or
+ <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>.
+ If a password is considered too weak, it will be rejected and
+ the command will terminate with an error.
+ </p><p>
+ To enable this module, add <code class="literal">'$libdir/passwordcheck'</code>
+ to <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> in
+ <code class="filename">postgresql.conf</code>, then restart the server.
+ </p><p>
+ You can adapt this module to your needs by changing the source code.
+ For example, you can use
+ <a class="ulink" href="https://github.com/cracklib/cracklib" target="_top">CrackLib</a>
+ to check passwords — this only requires uncommenting
+ two lines in the <code class="filename">Makefile</code> and rebuilding the
+ module. (We cannot include <span class="productname">CrackLib</span>
+ by default for license reasons.)
+ Without <span class="productname">CrackLib</span>, the module enforces a few
+ simple rules for password strength, which you can modify or extend
+ as you see fit.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ To prevent unencrypted passwords from being sent across the network,
+ written to the server log or otherwise stolen by a database administrator,
+ <span class="productname">PostgreSQL</span> allows the user to supply
+ pre-encrypted passwords. Many client programs make use of this
+ functionality and encrypt the password before sending it to the server.
+ </p><p>
+ This limits the usefulness of the <code class="filename">passwordcheck</code>
+ module, because in that case it can only try to guess the password.
+ For this reason, <code class="filename">passwordcheck</code> is not
+ recommended if your security requirements are high.
+ It is more secure to use an external authentication method such as GSSAPI
+ (see <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a>) than to rely on
+ passwords within the database.
+ </p><p>
+ Alternatively, you could modify <code class="filename">passwordcheck</code>
+ to reject pre-encrypted passwords, but forcing users to set their
+ passwords in clear text carries its own security risks.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pageinspect.html" title="F.25. pageinspect">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgbuffercache.html" title="F.27. pg_buffercache">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.25. pageinspect </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.27. pg_buffercache</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/performance-tips.html b/doc/src/sgml/html/performance-tips.html
new file mode 100644
index 0000000..65bfe4f
--- /dev/null
+++ b/doc/src/sgml/html/performance-tips.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 14. Performance Tips</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="locking-indexes.html" title="13.7. Locking and Indexes" /><link rel="next" href="using-explain.html" title="14.1. Using EXPLAIN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 14. Performance Tips</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="locking-indexes.html" title="13.7. Locking and Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="using-explain.html" title="14.1. Using EXPLAIN">Next</a></td></tr></table><hr /></div><div class="chapter" id="PERFORMANCE-TIPS"><div class="titlepage"><div><div><h2 class="title">Chapter 14. Performance Tips</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="using-explain.html">14.1. Using <code class="command">EXPLAIN</code></a></span></dt><dd><dl><dt><span class="sect2"><a href="using-explain.html#USING-EXPLAIN-BASICS">14.1.1. <code class="command">EXPLAIN</code> Basics</a></span></dt><dt><span class="sect2"><a href="using-explain.html#USING-EXPLAIN-ANALYZE">14.1.2. <code class="command">EXPLAIN ANALYZE</code></a></span></dt><dt><span class="sect2"><a href="using-explain.html#USING-EXPLAIN-CAVEATS">14.1.3. Caveats</a></span></dt></dl></dd><dt><span class="sect1"><a href="planner-stats.html">14.2. Statistics Used by the Planner</a></span></dt><dd><dl><dt><span class="sect2"><a href="planner-stats.html#id-1.5.13.5.3">14.2.1. Single-Column Statistics</a></span></dt><dt><span class="sect2"><a href="planner-stats.html#PLANNER-STATS-EXTENDED">14.2.2. Extended Statistics</a></span></dt></dl></dd><dt><span class="sect1"><a href="explicit-joins.html">14.3. Controlling the Planner with Explicit <code class="literal">JOIN</code> Clauses</a></span></dt><dt><span class="sect1"><a href="populate.html">14.4. Populating a Database</a></span></dt><dd><dl><dt><span class="sect2"><a href="populate.html#DISABLE-AUTOCOMMIT">14.4.1. Disable Autocommit</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-COPY-FROM">14.4.2. Use <code class="command">COPY</code></a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-RM-INDEXES">14.4.3. Remove Indexes</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-RM-FKEYS">14.4.4. Remove Foreign Key Constraints</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-WORK-MEM">14.4.5. Increase <code class="varname">maintenance_work_mem</code></a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-MAX-WAL-SIZE">14.4.6. Increase <code class="varname">max_wal_size</code></a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-PITR">14.4.7. Disable WAL Archival and Streaming Replication</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-ANALYZE">14.4.8. Run <code class="command">ANALYZE</code> Afterwards</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-PG-DUMP">14.4.9. Some Notes about <span class="application">pg_dump</span></a></span></dt></dl></dd><dt><span class="sect1"><a href="non-durability.html">14.5. Non-Durable Settings</a></span></dt></dl></div><a id="id-1.5.13.2" class="indexterm"></a><p>
+ Query performance can be affected by many things. Some of these can
+ be controlled by the user, while others are fundamental to the underlying
+ design of the system. This chapter provides some hints about understanding
+ and tuning <span class="productname">PostgreSQL</span> performance.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="locking-indexes.html" title="13.7. Locking and Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="using-explain.html" title="14.1. Using EXPLAIN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.7. Locking and Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 14.1. Using <code class="command">EXPLAIN</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/perm-functions.html b/doc/src/sgml/html/perm-functions.html
new file mode 100644
index 0000000..a39c2eb
--- /dev/null
+++ b/doc/src/sgml/html/perm-functions.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>22.6. Function Security</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="predefined-roles.html" title="22.5. Predefined Roles" /><link rel="next" href="managing-databases.html" title="Chapter 23. Managing Databases" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">22.6. Function Security</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="predefined-roles.html" title="22.5. Predefined Roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><th width="60%" align="center">Chapter 22. Database Roles</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="managing-databases.html" title="Chapter 23. Managing Databases">Next</a></td></tr></table><hr /></div><div class="sect1" id="PERM-FUNCTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">22.6. Function Security</h2></div></div></div><p>
+ Functions, triggers and row-level security policies allow users to insert
+ code into the backend server that other users might execute
+ unintentionally. Hence, these mechanisms permit users to <span class="quote">“<span class="quote">Trojan
+ horse</span>”</span> others with relative ease. The strongest protection is tight
+ control over who can define objects. Where that is infeasible, write
+ queries referring only to objects having trusted owners. Remove
+ from <code class="varname">search_path</code> any schemas that permit untrusted users
+ to create objects.
+ </p><p>
+ Functions run inside the backend
+ server process with the operating system permissions of the
+ database server daemon. If the programming language
+ used for the function allows unchecked memory accesses, it is
+ possible to change the server's internal data structures.
+ Hence, among many other things, such functions can circumvent any
+ system access controls. Function languages that allow such access
+ are considered <span class="quote">“<span class="quote">untrusted</span>”</span>, and
+ <span class="productname">PostgreSQL</span> allows only superusers to
+ create functions written in those languages.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="predefined-roles.html" title="22.5. Predefined Roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="managing-databases.html" title="Chapter 23. Managing Databases">Next</a></td></tr><tr><td width="40%" align="left" valign="top">22.5. Predefined Roles </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 23. Managing Databases</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgarchivecleanup.html b/doc/src/sgml/html/pgarchivecleanup.html
new file mode 100644
index 0000000..41ce358
--- /dev/null
+++ b/doc/src/sgml/html/pgarchivecleanup.html
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_archivecleanup</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-initdb.html" title="initdb" /><link rel="next" href="app-pgchecksums.html" title="pg_checksums" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_archivecleanup</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-initdb.html" title="initdb">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgchecksums.html" title="pg_checksums">Next</a></td></tr></table><hr /></div><div class="refentry" id="PGARCHIVECLEANUP"><div class="titlepage"></div><a id="id-1.9.5.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_archivecleanup</span></span></h2><p>pg_archivecleanup — clean up <span class="productname">PostgreSQL</span> WAL archive files</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.4.4.1"><code class="command">pg_archivecleanup</code> [<em class="replaceable"><code>option</code></em>...] <em class="replaceable"><code>archivelocation</code></em> <em class="replaceable"><code>oldestkeptwalfile</code></em> </p></div></div><div class="refsect1" id="id-1.9.5.4.5"><h2>Description</h2><p>
+ <span class="application">pg_archivecleanup</span> is designed to be used as an
+ <code class="literal">archive_cleanup_command</code> to clean up WAL file archives when
+ running as a standby server (see <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>).
+ <span class="application">pg_archivecleanup</span> can also be used as a standalone program to
+ clean WAL file archives.
+ </p><p>
+ To configure a standby
+ server to use <span class="application">pg_archivecleanup</span>, put this into its
+ <code class="filename">postgresql.conf</code> configuration file:
+</p><pre class="programlisting">
+archive_cleanup_command = 'pg_archivecleanup <em class="replaceable"><code>archivelocation</code></em> %r'
+</pre><p>
+ where <em class="replaceable"><code>archivelocation</code></em> is the directory from which WAL segment
+ files should be removed.
+ </p><p>
+ When used within <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-CLEANUP-COMMAND">archive_cleanup_command</a>, all WAL files
+ logically preceding the value of the <code class="literal">%r</code> argument will be removed
+ from <em class="replaceable"><code>archivelocation</code></em>. This minimizes the number of files
+ that need to be retained, while preserving crash-restart capability. Use of
+ this parameter is appropriate if the <em class="replaceable"><code>archivelocation</code></em> is a
+ transient staging area for this particular standby server, but
+ <span class="emphasis"><em>not</em></span> when the <em class="replaceable"><code>archivelocation</code></em> is intended as a
+ long-term WAL archive area, or when multiple standby servers are recovering
+ from the same archive location.
+ </p><p>
+ When used as a standalone program all WAL files logically preceding the
+ <em class="replaceable"><code>oldestkeptwalfile</code></em> will be removed from <em class="replaceable"><code>archivelocation</code></em>.
+ In this mode, if you specify a <code class="filename">.partial</code> or <code class="filename">.backup</code>
+ file name, then only the file prefix will be used as the
+ <em class="replaceable"><code>oldestkeptwalfile</code></em>. This treatment of <code class="filename">.backup</code>
+ file name allows you to remove
+ all WAL files archived prior to a specific base backup without error.
+ For example, the following example will remove all files older than
+ WAL file name <code class="filename">000000010000003700000010</code>:
+</p><pre class="programlisting">
+pg_archivecleanup -d archive 000000010000003700000010.00000020.backup
+
+pg_archivecleanup: keep WAL file "archive/000000010000003700000010" and later
+pg_archivecleanup: removing file "archive/00000001000000370000000F"
+pg_archivecleanup: removing file "archive/00000001000000370000000E"
+</pre><p>
+ </p><p>
+ <span class="application">pg_archivecleanup</span> assumes that
+ <em class="replaceable"><code>archivelocation</code></em> is a directory readable and writable by the
+ server-owning user.
+ </p></div><div class="refsect1" id="id-1.9.5.4.6"><h2>Options</h2><p>
+ <span class="application">pg_archivecleanup</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d</code></span></dt><dd><p>
+ Print lots of debug logging output on <code class="filename">stderr</code>.
+ </p></dd><dt><span class="term"><code class="option">-n</code></span></dt><dd><p>
+ Print the names of the files that would have been removed on <code class="filename">stdout</code> (performs a dry run).
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_archivecleanup</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-x</code> <em class="replaceable"><code>extension</code></em></span></dt><dd><p>
+ Provide an extension
+ that will be stripped from all file names before deciding if they
+ should be deleted. This is typically useful for cleaning up archives
+ that have been compressed during storage, and therefore have had an
+ extension added by the compression program. For example: <code class="literal">-x
+ .gz</code>.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_archivecleanup</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.4.7"><h2>Environment</h2><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.5.4.8"><h2>Notes</h2><p>
+ <span class="application">pg_archivecleanup</span> is designed to work with
+ <span class="productname">PostgreSQL</span> 8.0 and later when used as a standalone utility,
+ or with <span class="productname">PostgreSQL</span> 9.0 and later when used as an
+ archive cleanup command.
+ </p><p>
+ <span class="application">pg_archivecleanup</span> is written in C and has an
+ easy-to-modify source code, with specifically designated sections to modify
+ for your own needs
+ </p></div><div class="refsect1" id="id-1.9.5.4.9"><h2>Examples</h2><p>On Linux or Unix systems, you might use:
+</p><pre class="programlisting">
+archive_cleanup_command = 'pg_archivecleanup -d /mnt/standby/archive %r 2&gt;&gt;cleanup.log'
+</pre><p>
+ where the archive directory is physically located on the standby server,
+ so that the <code class="varname">archive_command</code> is accessing it across NFS,
+ but the files are local to the standby.
+ This will:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ produce debugging output in <code class="filename">cleanup.log</code>
+ </p></li><li class="listitem"><p>
+ remove no-longer-needed files from the archive directory
+ </p></li></ul></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-initdb.html" title="initdb">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgchecksums.html" title="pg_checksums">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">initdb</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_checksums</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgbench.html b/doc/src/sgml/html/pgbench.html
new file mode 100644
index 0000000..6f9b8d8
--- /dev/null
+++ b/doc/src/sgml/html/pgbench.html
@@ -0,0 +1,1721 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pgbench</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgbasebackup.html" title="pg_basebackup" /><link rel="next" href="app-pgconfig.html" title="pg_config" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pgbench</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgbasebackup.html" title="pg_basebackup">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><th width="60%" align="center">PostgreSQL Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgconfig.html" title="pg_config">Next</a></td></tr></table><hr /></div><div class="refentry" id="PGBENCH"><div class="titlepage"></div><a id="id-1.9.4.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pgbench</span></span></h2><p>pgbench — run a benchmark test on <span class="productname">PostgreSQL</span></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.4.11.4.1"><code class="command">pgbench</code> <code class="option">-i</code> [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>dbname</code></em>]</p></div><div class="cmdsynopsis"><p id="id-1.9.4.11.4.2"><code class="command">pgbench</code> [<em class="replaceable"><code>option</code></em>...] [<em class="replaceable"><code>dbname</code></em>]</p></div></div><div class="refsect1" id="id-1.9.4.11.5"><h2>Description</h2><p>
+ <span class="application">pgbench</span> is a simple program for running benchmark
+ tests on <span class="productname">PostgreSQL</span>. It runs the same sequence of SQL
+ commands over and over, possibly in multiple concurrent database sessions,
+ and then calculates the average transaction rate (transactions per second).
+ By default, <span class="application">pgbench</span> tests a scenario that is
+ loosely based on TPC-B, involving five <code class="command">SELECT</code>,
+ <code class="command">UPDATE</code>, and <code class="command">INSERT</code> commands per transaction.
+ However, it is easy to test other cases by writing your own transaction
+ script files.
+ </p><p>
+ Typical output from <span class="application">pgbench</span> looks like:
+
+</p><pre class="screen">
+transaction type: &lt;builtin: TPC-B (sort of)&gt;
+scaling factor: 10
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+number of failed transactions: 0 (0.000%)
+latency average = 11.013 ms
+latency stddev = 7.351 ms
+initial connection time = 45.758 ms
+tps = 896.967014 (without initial connection time)
+</pre><p>
+
+ The first seven lines report some of the most important parameter
+ settings.
+ The sixth line reports the maximum number of tries for transactions with
+ serialization or deadlock errors (see <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a>
+ for more information).
+ The eighth line reports the number of transactions completed
+ and intended (the latter being just the product of number of clients
+ and number of transactions per client); these will be equal unless the run
+ failed before completion or some SQL command(s) failed. (In
+ <code class="option">-T</code> mode, only the actual number of transactions is printed.)
+ The next line reports the number of failed transactions due to
+ serialization or deadlock errors (see <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a>
+ for more information).
+ The last line reports the number of transactions per second.
+ </p><p>
+ The default TPC-B-like transaction test requires specific tables to be
+ set up beforehand. <span class="application">pgbench</span> should be invoked with
+ the <code class="option">-i</code> (initialize) option to create and populate these
+ tables. (When you are testing a custom script, you don't need this
+ step, but will instead need to do whatever setup your test needs.)
+ Initialization looks like:
+
+</p><pre class="programlisting">
+pgbench -i [<span class="optional"> <em class="replaceable"><code>other-options</code></em> </span>] <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+
+ where <em class="replaceable"><code>dbname</code></em> is the name of the already-created
+ database to test in. (You may also need <code class="option">-h</code>,
+ <code class="option">-p</code>, and/or <code class="option">-U</code> options to specify how to
+ connect to the database server.)
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ <code class="literal">pgbench -i</code> creates four tables <code class="structname">pgbench_accounts</code>,
+ <code class="structname">pgbench_branches</code>, <code class="structname">pgbench_history</code>, and
+ <code class="structname">pgbench_tellers</code>,
+ destroying any existing tables of these names.
+ Be very careful to use another database if you have tables having these
+ names!
+ </p></div><p>
+ At the default <span class="quote">“<span class="quote">scale factor</span>”</span> of 1, the tables initially
+ contain this many rows:
+</p><pre class="screen">
+table # of rows
+---------------------------------
+pgbench_branches 1
+pgbench_tellers 10
+pgbench_accounts 100000
+pgbench_history 0
+</pre><p>
+ You can (and, for most purposes, probably should) increase the number
+ of rows by using the <code class="option">-s</code> (scale factor) option. The
+ <code class="option">-F</code> (fillfactor) option might also be used at this point.
+ </p><p>
+ Once you have done the necessary setup, you can run your benchmark
+ with a command that doesn't include <code class="option">-i</code>, that is
+
+</p><pre class="programlisting">
+pgbench [<span class="optional"> <em class="replaceable"><code>options</code></em> </span>] <em class="replaceable"><code>dbname</code></em>
+</pre><p>
+
+ In nearly all cases, you'll need some options to make a useful test.
+ The most important options are <code class="option">-c</code> (number of clients),
+ <code class="option">-t</code> (number of transactions), <code class="option">-T</code> (time limit),
+ and <code class="option">-f</code> (specify a custom script file).
+ See below for a full list.
+ </p></div><div class="refsect1" id="id-1.9.4.11.6"><h2>Options</h2><p>
+ The following is divided into three subsections. Different options are
+ used during database initialization and while running benchmarks, but some
+ options are useful in both cases.
+ </p><div class="refsect2" id="PGBENCH-INIT-OPTIONS"><h3>Initialization Options</h3><p>
+ <span class="application">pgbench</span> accepts the following command-line
+ initialization arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>dbname</code></em></span></dt><dd><p>
+ Specifies the name of the database to test in. If this is
+ not specified, the environment variable
+ <code class="envar">PGDATABASE</code> is used. If that is not set, the
+ user name specified for the connection is used.
+ </p></dd><dt><span class="term"><code class="option">-i</code><br /></span><span class="term"><code class="option">--initialize</code></span></dt><dd><p>
+ Required to invoke initialization mode.
+ </p></dd><dt><span class="term"><code class="option">-I <em class="replaceable"><code>init_steps</code></em></code><br /></span><span class="term"><code class="option">--init-steps=<em class="replaceable"><code>init_steps</code></em></code></span></dt><dd><p>
+ Perform just a selected set of the normal initialization steps.
+ <em class="replaceable"><code>init_steps</code></em> specifies the
+ initialization steps to be performed, using one character per step.
+ Each step is invoked in the specified order.
+ The default is <code class="literal">dtgvp</code>.
+ The available steps are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">d</code> (Drop)</span></dt><dd><p>
+ Drop any existing <span class="application">pgbench</span> tables.
+ </p></dd><dt><span class="term"><code class="literal">t</code> (create Tables)</span></dt><dd><p>
+ Create the tables used by the
+ standard <span class="application">pgbench</span> scenario, namely
+ <code class="structname">pgbench_accounts</code>,
+ <code class="structname">pgbench_branches</code>,
+ <code class="structname">pgbench_history</code>, and
+ <code class="structname">pgbench_tellers</code>.
+ </p></dd><dt><span class="term"><code class="literal">g</code> or <code class="literal">G</code> (Generate data, client-side or server-side)</span></dt><dd><p>
+ Generate data and load it into the standard tables,
+ replacing any data already present.
+ </p><p>
+ With <code class="literal">g</code> (client-side data generation),
+ data is generated in <code class="command">pgbench</code> client and then
+ sent to the server. This uses the client/server bandwidth
+ extensively through a <code class="command">COPY</code>.
+ <code class="command">pgbench</code> uses the FREEZE option with version 14 or later
+ of <span class="productname">PostgreSQL</span> to speed up
+ subsequent <code class="command">VACUUM</code>, unless partitions are enabled.
+ Using <code class="literal">g</code> causes logging to print one message
+ every 100,000 rows while generating data for the
+ <code class="structname">pgbench_accounts</code> table.
+ </p><p>
+ With <code class="literal">G</code> (server-side data generation),
+ only small queries are sent from the <code class="command">pgbench</code>
+ client and then data is actually generated in the server.
+ No significant bandwidth is required for this variant, but
+ the server will do more work.
+ Using <code class="literal">G</code> causes logging not to print any progress
+ message while generating data.
+ </p><p>
+ The default initialization behavior uses client-side data
+ generation (equivalent to <code class="literal">g</code>).
+ </p></dd><dt><span class="term"><code class="literal">v</code> (Vacuum)</span></dt><dd><p>
+ Invoke <code class="command">VACUUM</code> on the standard tables.
+ </p></dd><dt><span class="term"><code class="literal">p</code> (create Primary keys)</span></dt><dd><p>
+ Create primary key indexes on the standard tables.
+ </p></dd><dt><span class="term"><code class="literal">f</code> (create Foreign keys)</span></dt><dd><p>
+ Create foreign key constraints between the standard tables.
+ (Note that this step is not performed by default.)
+ </p></dd></dl></div></dd><dt><span class="term"><code class="option">-F</code> <em class="replaceable"><code>fillfactor</code></em><br /></span><span class="term"><code class="option">--fillfactor=</code><em class="replaceable"><code>fillfactor</code></em></span></dt><dd><p>
+ Create the <code class="structname">pgbench_accounts</code>,
+ <code class="structname">pgbench_tellers</code> and
+ <code class="structname">pgbench_branches</code> tables with the given fillfactor.
+ Default is 100.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-vacuum</code></span></dt><dd><p>
+ Perform no vacuuming during initialization.
+ (This option suppresses the <code class="literal">v</code> initialization step,
+ even if it was specified in <code class="option">-I</code>.)
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Switch logging to quiet mode, producing only one progress message per 5
+ seconds. The default logging prints one message each 100,000 rows, which
+ often outputs many lines per second (especially on good hardware).
+ </p><p>
+ This setting has no effect if <code class="literal">G</code> is specified
+ in <code class="option">-I</code>.
+ </p></dd><dt><span class="term"><code class="option">-s</code> <em class="replaceable"><code>scale_factor</code></em><br /></span><span class="term"><code class="option">--scale=</code><em class="replaceable"><code>scale_factor</code></em></span></dt><dd><p>
+ Multiply the number of rows generated by the scale factor.
+ For example, <code class="literal">-s 100</code> will create 10,000,000 rows
+ in the <code class="structname">pgbench_accounts</code> table. Default is 1.
+ When the scale is 20,000 or larger, the columns used to
+ hold account identifiers (<code class="structfield">aid</code> columns)
+ will switch to using larger integers (<code class="type">bigint</code>),
+ in order to be big enough to hold the range of account
+ identifiers.
+ </p></dd><dt><span class="term"><code class="option">--foreign-keys</code></span></dt><dd><p>
+ Create foreign key constraints between the standard tables.
+ (This option adds the <code class="literal">f</code> step to the initialization
+ step sequence, if it is not already present.)
+ </p></dd><dt><span class="term"><code class="option">--index-tablespace=<em class="replaceable"><code>index_tablespace</code></em></code></span></dt><dd><p>
+ Create indexes in the specified tablespace, rather than the default
+ tablespace.
+ </p></dd><dt><span class="term"><code class="option">--partition-method=<em class="replaceable"><code>NAME</code></em></code></span></dt><dd><p>
+ Create a partitioned <code class="literal">pgbench_accounts</code> table with
+ <em class="replaceable"><code>NAME</code></em> method.
+ Expected values are <code class="literal">range</code> or <code class="literal">hash</code>.
+ This option requires that <code class="option">--partitions</code> is set to non-zero.
+ If unspecified, default is <code class="literal">range</code>.
+ </p></dd><dt><span class="term"><code class="option">--partitions=<em class="replaceable"><code>NUM</code></em></code></span></dt><dd><p>
+ Create a partitioned <code class="literal">pgbench_accounts</code> table with
+ <em class="replaceable"><code>NUM</code></em> partitions of nearly equal size for
+ the scaled number of accounts.
+ Default is <code class="literal">0</code>, meaning no partitioning.
+ </p></dd><dt><span class="term"><code class="option">--tablespace=<em class="replaceable"><code>tablespace</code></em></code></span></dt><dd><p>
+ Create tables in the specified tablespace, rather than the default
+ tablespace.
+ </p></dd><dt><span class="term"><code class="option">--unlogged-tables</code></span></dt><dd><p>
+ Create all tables as unlogged tables, rather than permanent tables.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect2" id="PGBENCH-RUN-OPTIONS"><h3>Benchmarking Options</h3><p>
+ <span class="application">pgbench</span> accepts the following command-line
+ benchmarking arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-b</code> <em class="replaceable"><code>scriptname[@weight]</code></em><br /></span><span class="term"><code class="option">--builtin</code>=<em class="replaceable"><code>scriptname[@weight]</code></em></span></dt><dd><p>
+ Add the specified built-in script to the list of scripts to be executed.
+ Available built-in scripts are: <code class="literal">tpcb-like</code>,
+ <code class="literal">simple-update</code> and <code class="literal">select-only</code>.
+ Unambiguous prefixes of built-in names are accepted.
+ With the special name <code class="literal">list</code>, show the list of built-in scripts
+ and exit immediately.
+ </p><p>
+ Optionally, write an integer weight after <code class="literal">@</code> to
+ adjust the probability of selecting this script versus other ones.
+ The default weight is 1.
+ See below for details.
+ </p></dd><dt><span class="term"><code class="option">-c</code> <em class="replaceable"><code>clients</code></em><br /></span><span class="term"><code class="option">--client=</code><em class="replaceable"><code>clients</code></em></span></dt><dd><p>
+ Number of clients simulated, that is, number of concurrent database
+ sessions. Default is 1.
+ </p></dd><dt><span class="term"><code class="option">-C</code><br /></span><span class="term"><code class="option">--connect</code></span></dt><dd><p>
+ Establish a new connection for each transaction, rather than
+ doing it just once per client session.
+ This is useful to measure the connection overhead.
+ </p></dd><dt><span class="term"><code class="option">-d</code><br /></span><span class="term"><code class="option">--debug</code></span></dt><dd><p>
+ Print debugging output.
+ </p></dd><dt><span class="term"><code class="option">-D</code> <em class="replaceable"><code>varname</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em><br /></span><span class="term"><code class="option">--define=</code><em class="replaceable"><code>varname</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ Define a variable for use by a custom script (see below).
+ Multiple <code class="option">-D</code> options are allowed.
+ </p></dd><dt><span class="term"><code class="option">-f</code> <em class="replaceable"><code>filename[@weight]</code></em><br /></span><span class="term"><code class="option">--file=</code><em class="replaceable"><code>filename[@weight]</code></em></span></dt><dd><p>
+ Add a transaction script read from <em class="replaceable"><code>filename</code></em>
+ to the list of scripts to be executed.
+ </p><p>
+ Optionally, write an integer weight after <code class="literal">@</code> to
+ adjust the probability of selecting this script versus other ones.
+ The default weight is 1.
+ (To use a script file name that includes an <code class="literal">@</code>
+ character, append a weight so that there is no ambiguity, for
+ example <code class="literal">filen@me@1</code>.)
+ See below for details.
+ </p></dd><dt><span class="term"><code class="option">-j</code> <em class="replaceable"><code>threads</code></em><br /></span><span class="term"><code class="option">--jobs=</code><em class="replaceable"><code>threads</code></em></span></dt><dd><p>
+ Number of worker threads within <span class="application">pgbench</span>.
+ Using more than one thread can be helpful on multi-CPU machines.
+ Clients are distributed as evenly as possible among available threads.
+ Default is 1.
+ </p></dd><dt><span class="term"><code class="option">-l</code><br /></span><span class="term"><code class="option">--log</code></span></dt><dd><p>
+ Write information about each transaction to a log file.
+ See below for details.
+ </p></dd><dt><span class="term"><code class="option">-L</code> <em class="replaceable"><code>limit</code></em><br /></span><span class="term"><code class="option">--latency-limit=</code><em class="replaceable"><code>limit</code></em></span></dt><dd><p>
+ Transactions that last more than <em class="replaceable"><code>limit</code></em> milliseconds
+ are counted and reported separately, as <em class="firstterm">late</em>.
+ </p><p>
+ When throttling is used (<code class="option">--rate=...</code>), transactions that
+ lag behind schedule by more than <em class="replaceable"><code>limit</code></em> ms, and thus
+ have no hope of meeting the latency limit, are not sent to the server
+ at all. They are counted and reported separately as
+ <em class="firstterm">skipped</em>.
+ </p><p>
+ When the <code class="option">--max-tries</code> option is used, a transaction
+ which fails due to a serialization anomaly or from a deadlock will not
+ be retried if the total time of all its tries is greater than
+ <em class="replaceable"><code>limit</code></em> ms. To limit only the time of tries
+ and not their number, use <code class="literal">--max-tries=0</code>. By
+ default, the option <code class="option">--max-tries</code> is set to 1 and
+ transactions with serialization/deadlock errors are not retried. See
+ <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a> for more information about
+ retrying such transactions.
+ </p></dd><dt><span class="term"><code class="option">-M</code> <em class="replaceable"><code>querymode</code></em><br /></span><span class="term"><code class="option">--protocol=</code><em class="replaceable"><code>querymode</code></em></span></dt><dd><p>
+ Protocol to use for submitting queries to the server:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">simple</code>: use simple query protocol.</p></li><li class="listitem"><p><code class="literal">extended</code>: use extended query protocol.</p></li><li class="listitem"><p><code class="literal">prepared</code>: use extended query protocol with prepared statements.</p></li></ul></div><p>
+
+ In the <code class="literal">prepared</code> mode, <span class="application">pgbench</span>
+ reuses the parse analysis result starting from the second query
+ iteration, so <span class="application">pgbench</span> runs faster
+ than in other modes.
+ </p><p>
+ The default is simple query protocol. (See <a class="xref" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Chapter 55</a>
+ for more information.)
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--no-vacuum</code></span></dt><dd><p>
+ Perform no vacuuming before running the test.
+ This option is <span class="emphasis"><em>necessary</em></span>
+ if you are running a custom test scenario that does not include
+ the standard tables <code class="structname">pgbench_accounts</code>,
+ <code class="structname">pgbench_branches</code>, <code class="structname">pgbench_history</code>, and
+ <code class="structname">pgbench_tellers</code>.
+ </p></dd><dt><span class="term"><code class="option">-N</code><br /></span><span class="term"><code class="option">--skip-some-updates</code></span></dt><dd><p>
+ Run built-in simple-update script.
+ Shorthand for <code class="option">-b simple-update</code>.
+ </p></dd><dt><span class="term"><code class="option">-P</code> <em class="replaceable"><code>sec</code></em><br /></span><span class="term"><code class="option">--progress=</code><em class="replaceable"><code>sec</code></em></span></dt><dd><p>
+ Show progress report every <em class="replaceable"><code>sec</code></em> seconds. The report
+ includes the time since the beginning of the run, the TPS since the
+ last report, and the transaction latency average, standard deviation,
+ and the number of failed transactions since the last report. Under
+ throttling (<code class="option">-R</code>), the latency is computed with respect
+ to the transaction scheduled start time, not the actual transaction
+ beginning time, thus it also includes the average schedule lag time.
+ When <code class="option">--max-tries</code> is used to enable transaction retries
+ after serialization/deadlock errors, the report includes the number of
+ retried transactions and the sum of all retries.
+ </p></dd><dt><span class="term"><code class="option">-r</code><br /></span><span class="term"><code class="option">--report-per-command</code></span></dt><dd><p>
+ Report the following statistics for each command after the benchmark
+ finishes: the average per-statement latency (execution time from the
+ perspective of the client), the number of failures, and the number of
+ retries after serialization or deadlock errors in this command. The
+ report displays retry statistics only if the
+ <code class="option">--max-tries</code> option is not equal to 1.
+ </p></dd><dt><span class="term"><code class="option">-R</code> <em class="replaceable"><code>rate</code></em><br /></span><span class="term"><code class="option">--rate=</code><em class="replaceable"><code>rate</code></em></span></dt><dd><p>
+ Execute transactions targeting the specified rate instead of running
+ as fast as possible (the default). The rate is given in transactions
+ per second. If the targeted rate is above the maximum possible rate,
+ the rate limit won't impact the results.
+ </p><p>
+ The rate is targeted by starting transactions along a
+ Poisson-distributed schedule time line. The expected start time
+ schedule moves forward based on when the client first started, not
+ when the previous transaction ended. That approach means that when
+ transactions go past their original scheduled end time, it is
+ possible for later ones to catch up again.
+ </p><p>
+ When throttling is active, the transaction latency reported at the
+ end of the run is calculated from the scheduled start times, so it
+ includes the time each transaction had to wait for the previous
+ transaction to finish. The wait time is called the schedule lag time,
+ and its average and maximum are also reported separately. The
+ transaction latency with respect to the actual transaction start time,
+ i.e., the time spent executing the transaction in the database, can be
+ computed by subtracting the schedule lag time from the reported
+ latency.
+ </p><p>
+ If <code class="option">--latency-limit</code> is used together with <code class="option">--rate</code>,
+ a transaction can lag behind so much that it is already over the
+ latency limit when the previous transaction ends, because the latency
+ is calculated from the scheduled start time. Such transactions are
+ not sent to the server, but are skipped altogether and counted
+ separately.
+ </p><p>
+ A high schedule lag time is an indication that the system cannot
+ process transactions at the specified rate, with the chosen number of
+ clients and threads. When the average transaction execution time is
+ longer than the scheduled interval between each transaction, each
+ successive transaction will fall further behind, and the schedule lag
+ time will keep increasing the longer the test run is. When that
+ happens, you will have to reduce the specified transaction rate.
+ </p></dd><dt><span class="term"><code class="option">-s</code> <em class="replaceable"><code>scale_factor</code></em><br /></span><span class="term"><code class="option">--scale=</code><em class="replaceable"><code>scale_factor</code></em></span></dt><dd><p>
+ Report the specified scale factor in <span class="application">pgbench</span>'s
+ output. With the built-in tests, this is not necessary; the
+ correct scale factor will be detected by counting the number of
+ rows in the <code class="structname">pgbench_branches</code> table.
+ However, when testing only custom benchmarks (<code class="option">-f</code> option),
+ the scale factor will be reported as 1 unless this option is used.
+ </p></dd><dt><span class="term"><code class="option">-S</code><br /></span><span class="term"><code class="option">--select-only</code></span></dt><dd><p>
+ Run built-in select-only script.
+ Shorthand for <code class="option">-b select-only</code>.
+ </p></dd><dt><span class="term"><code class="option">-t</code> <em class="replaceable"><code>transactions</code></em><br /></span><span class="term"><code class="option">--transactions=</code><em class="replaceable"><code>transactions</code></em></span></dt><dd><p>
+ Number of transactions each client runs. Default is 10.
+ </p></dd><dt><span class="term"><code class="option">-T</code> <em class="replaceable"><code>seconds</code></em><br /></span><span class="term"><code class="option">--time=</code><em class="replaceable"><code>seconds</code></em></span></dt><dd><p>
+ Run the test for this many seconds, rather than a fixed number of
+ transactions per client. <code class="option">-t</code> and
+ <code class="option">-T</code> are mutually exclusive.
+ </p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--vacuum-all</code></span></dt><dd><p>
+ Vacuum all four standard tables before running the test.
+ With neither <code class="option">-n</code> nor <code class="option">-v</code>, <span class="application">pgbench</span> will vacuum the
+ <code class="structname">pgbench_tellers</code> and <code class="structname">pgbench_branches</code>
+ tables, and will truncate <code class="structname">pgbench_history</code>.
+ </p></dd><dt><span class="term"><code class="option">--aggregate-interval=<em class="replaceable"><code>seconds</code></em></code></span></dt><dd><p>
+ Length of aggregation interval (in seconds). May be used only
+ with <code class="option">-l</code> option. With this option, the log contains
+ per-interval summary data, as described below.
+ </p></dd><dt><span class="term"><code class="option">--failures-detailed</code></span></dt><dd><p>
+ Report failures in per-transaction and aggregation logs, as well as in
+ the main and per-script reports, grouped by the following types:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>serialization failures;</p></li><li class="listitem"><p>deadlock failures;</p></li></ul></div><p>
+ See <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a> for more information.
+ </p></dd><dt><span class="term"><code class="option">--log-prefix=<em class="replaceable"><code>prefix</code></em></code></span></dt><dd><p>
+ Set the filename prefix for the log files created by
+ <code class="option">--log</code>. The default is <code class="literal">pgbench_log</code>.
+ </p></dd><dt><span class="term"><code class="option">--max-tries=<em class="replaceable"><code>number_of_tries</code></em></code></span></dt><dd><p>
+ Enable retries for transactions with serialization/deadlock errors and
+ set the maximum number of these tries. This option can be combined with
+ the <code class="option">--latency-limit</code> option which limits the total time
+ of all transaction tries; moreover, you cannot use an unlimited number
+ of tries (<code class="literal">--max-tries=0</code>) without
+ <code class="option">--latency-limit</code> or <code class="option">--time</code>.
+ The default value is 1 and transactions with serialization/deadlock
+ errors are not retried. See <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a>
+ for more information about retrying such transactions.
+ </p></dd><dt><span class="term"><code class="option">--progress-timestamp</code></span></dt><dd><p>
+ When showing progress (option <code class="option">-P</code>), use a timestamp
+ (Unix epoch) instead of the number of seconds since the
+ beginning of the run. The unit is in seconds, with millisecond
+ precision after the dot.
+ This helps compare logs generated by various tools.
+ </p></dd><dt><span class="term"><code class="option">--random-seed=</code><em class="replaceable"><code>seed</code></em></span></dt><dd><p>
+ Set random generator seed. Seeds the system random number generator,
+ which then produces a sequence of initial generator states, one for
+ each thread.
+ Values for <em class="replaceable"><code>seed</code></em> may be:
+ <code class="literal">time</code> (the default, the seed is based on the current time),
+ <code class="literal">rand</code> (use a strong random source, failing if none
+ is available), or an unsigned decimal integer value.
+ The random generator is invoked explicitly from a pgbench script
+ (<code class="literal">random...</code> functions) or implicitly (for instance option
+ <code class="option">--rate</code> uses it to schedule transactions).
+ When explicitly set, the value used for seeding is shown on the terminal.
+ Any value allowed for <em class="replaceable"><code>seed</code></em> may also be
+ provided through the environment variable
+ <code class="literal">PGBENCH_RANDOM_SEED</code>.
+ To ensure that the provided seed impacts all possible uses, put this option
+ first or use the environment variable.
+ </p><p>
+ Setting the seed explicitly allows to reproduce a <code class="command">pgbench</code>
+ run exactly, as far as random numbers are concerned.
+ As the random state is managed per thread, this means the exact same
+ <code class="command">pgbench</code> run for an identical invocation if there is one
+ client per thread and there are no external or data dependencies.
+ From a statistical viewpoint reproducing runs exactly is a bad idea because
+ it can hide the performance variability or improve performance unduly,
+ e.g., by hitting the same pages as a previous run.
+ However, it may also be of great help for debugging, for instance
+ re-running a tricky case which leads to an error.
+ Use wisely.
+ </p></dd><dt><span class="term"><code class="option">--sampling-rate=<em class="replaceable"><code>rate</code></em></code></span></dt><dd><p>
+ Sampling rate, used when writing data into the log, to reduce the
+ amount of log generated. If this option is given, only the specified
+ fraction of transactions are logged. 1.0 means all transactions will
+ be logged, 0.05 means only 5% of the transactions will be logged.
+ </p><p>
+ Remember to take the sampling rate into account when processing the
+ log file. For example, when computing TPS values, you need to multiply
+ the numbers accordingly (e.g., with 0.01 sample rate, you'll only get
+ 1/100 of the actual TPS).
+ </p></dd><dt><span class="term"><code class="option">--show-script=</code><em class="replaceable"><code>scriptname</code></em></span></dt><dd><p>
+ Show the actual code of builtin script <em class="replaceable"><code>scriptname</code></em>
+ on stderr, and exit immediately.
+ </p></dd><dt><span class="term"><code class="option">--verbose-errors</code></span></dt><dd><p>
+ Print messages about all errors and failures (errors without retrying)
+ including which limit for retries was exceeded and how far it was
+ exceeded for the serialization/deadlock failures. (Note that in this
+ case the output can be significantly increased.).
+ See <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a> for more information.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect2" id="PGBENCH-COMMON-OPTIONS"><h3>Common Options</h3><p>
+ <span class="application">pgbench</span> also accepts the following common command-line
+ arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h</code> <em class="replaceable"><code>hostname</code></em><br /></span><span class="term"><code class="option">--host=</code><em class="replaceable"><code>hostname</code></em></span></dt><dd><p>
+ The database server's host name
+ </p></dd><dt><span class="term"><code class="option">-p</code> <em class="replaceable"><code>port</code></em><br /></span><span class="term"><code class="option">--port=</code><em class="replaceable"><code>port</code></em></span></dt><dd><p>
+ The database server's port number
+ </p></dd><dt><span class="term"><code class="option">-U</code> <em class="replaceable"><code>login</code></em><br /></span><span class="term"><code class="option">--username=</code><em class="replaceable"><code>login</code></em></span></dt><dd><p>
+ The user name to connect as
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pgbench</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pgbench</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div></div><div class="refsect1" id="id-1.9.4.11.7"><h2>Exit Status</h2><p>
+ A successful run will exit with status 0. Exit status 1 indicates static
+ problems such as invalid command-line options or internal errors which
+ are supposed to never occur. Early errors that occur when starting
+ benchmark such as initial connection failures also exit with status 1.
+ Errors during the run such as database errors or problems in the script
+ will result in exit status 2. In the latter case,
+ <span class="application">pgbench</span> will print partial results.
+ </p></div><div class="refsect1" id="id-1.9.4.11.8"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATABASE</code><br /></span><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.4.11.9"><h2>Notes</h2><div class="refsect2" id="TRANSACTIONS-AND-SCRIPTS"><h3>What Is the <span class="quote">“<span class="quote">Transaction</span>”</span> Actually Performed in <span class="application">pgbench</span>?</h3><p>
+ <span class="application">pgbench</span> executes test scripts chosen randomly
+ from a specified list.
+ The scripts may include built-in scripts specified with <code class="option">-b</code>
+ and user-provided scripts specified with <code class="option">-f</code>.
+ Each script may be given a relative weight specified after an
+ <code class="literal">@</code> so as to change its selection probability.
+ The default weight is <code class="literal">1</code>.
+ Scripts with a weight of <code class="literal">0</code> are ignored.
+ </p><p>
+ The default built-in transaction script (also invoked with <code class="option">-b tpcb-like</code>)
+ issues seven commands per transaction over randomly chosen <code class="literal">aid</code>,
+ <code class="literal">tid</code>, <code class="literal">bid</code> and <code class="literal">delta</code>.
+ The scenario is inspired by the TPC-B benchmark, but is not actually TPC-B,
+ hence the name.
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p><code class="literal">BEGIN;</code></p></li><li class="listitem"><p><code class="literal">UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;</code></p></li><li class="listitem"><p><code class="literal">SELECT abalance FROM pgbench_accounts WHERE aid = :aid;</code></p></li><li class="listitem"><p><code class="literal">UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;</code></p></li><li class="listitem"><p><code class="literal">UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;</code></p></li><li class="listitem"><p><code class="literal">INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);</code></p></li><li class="listitem"><p><code class="literal">END;</code></p></li></ol></div><p>
+ If you select the <code class="literal">simple-update</code> built-in (also <code class="option">-N</code>),
+ steps 4 and 5 aren't included in the transaction.
+ This will avoid update contention on these tables, but
+ it makes the test case even less like TPC-B.
+ </p><p>
+ If you select the <code class="literal">select-only</code> built-in (also <code class="option">-S</code>),
+ only the <code class="command">SELECT</code> is issued.
+ </p></div><div class="refsect2" id="id-1.9.4.11.9.3"><h3>Custom Scripts</h3><p>
+ <span class="application">pgbench</span> has support for running custom
+ benchmark scenarios by replacing the default transaction script
+ (described above) with a transaction script read from a file
+ (<code class="option">-f</code> option). In this case a <span class="quote">“<span class="quote">transaction</span>”</span>
+ counts as one execution of a script file.
+ </p><p>
+ A script file contains one or more SQL commands terminated by
+ semicolons. Empty lines and lines beginning with
+ <code class="literal">--</code> are ignored. Script files can also contain
+ <span class="quote">“<span class="quote">meta commands</span>”</span>, which are interpreted by <span class="application">pgbench</span>
+ itself, as described below.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> 9.6, SQL commands in script files
+ were terminated by newlines, and so they could not be continued across
+ lines. Now a semicolon is <span class="emphasis"><em>required</em></span> to separate consecutive
+ SQL commands (though an SQL command does not need one if it is followed
+ by a meta command). If you need to create a script file that works with
+ both old and new versions of <span class="application">pgbench</span>, be sure to write
+ each SQL command on a single line ending with a semicolon.
+ </p><p>
+ It is assumed that pgbench scripts do not contain incomplete blocks of SQL
+ transactions. If at runtime the client reaches the end of the script without
+ completing the last transaction block, it will be aborted.
+ </p></div><p>
+ There is a simple variable-substitution facility for script files.
+ Variable names must consist of letters (including non-Latin letters),
+ digits, and underscores, with the first character not being a digit.
+ Variables can be set by the command-line <code class="option">-D</code> option,
+ explained above, or by the meta commands explained below.
+ In addition to any variables preset by <code class="option">-D</code> command-line options,
+ there are a few variables that are preset automatically, listed in
+ <a class="xref" href="pgbench.html#PGBENCH-AUTOMATIC-VARIABLES" title="Table 288. pgbench Automatic Variables">Table 288</a>. A value specified for these
+ variables using <code class="option">-D</code> takes precedence over the automatic presets.
+ Once set, a variable's
+ value can be inserted into an SQL command by writing
+ <code class="literal">:</code><em class="replaceable"><code>variablename</code></em>. When running more than
+ one client session, each session has its own set of variables.
+ <span class="application">pgbench</span> supports up to 255 variable uses in one
+ statement.
+ </p><div class="table" id="PGBENCH-AUTOMATIC-VARIABLES"><p class="title"><strong>Table 288. pgbench Automatic Variables</strong></p><div class="table-contents"><table class="table" summary="pgbench Automatic Variables" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Variable</th><th>Description</th></tr></thead><tbody><tr><td> <code class="literal">client_id</code> </td><td>unique number identifying the client session (starts from zero)</td></tr><tr><td> <code class="literal">default_seed</code> </td><td>seed used in hash and pseudorandom permutation functions by default</td></tr><tr><td> <code class="literal">random_seed</code> </td><td>random generator seed (unless overwritten with <code class="option">-D</code>)</td></tr><tr><td> <code class="literal">scale</code> </td><td>current scale factor</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Script file meta commands begin with a backslash (<code class="literal">\</code>) and
+ normally extend to the end of the line, although they can be continued
+ to additional lines by writing backslash-return.
+ Arguments to a meta command are separated by white space.
+ These meta commands are supported:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PGBENCH-METACOMMAND-GSET"><span class="term">
+ <code class="literal">\gset [<em class="replaceable"><code>prefix</code></em>]</code>
+ <code class="literal">\aset [<em class="replaceable"><code>prefix</code></em>]</code>
+ </span></dt><dd><p>
+ These commands may be used to end SQL queries, taking the place of the
+ terminating semicolon (<code class="literal">;</code>).
+ </p><p>
+ When the <code class="literal">\gset</code> command is used, the preceding SQL query is
+ expected to return one row, the columns of which are stored into variables
+ named after column names, and prefixed with <em class="replaceable"><code>prefix</code></em>
+ if provided.
+ </p><p>
+ When the <code class="literal">\aset</code> command is used, all combined SQL queries
+ (separated by <code class="literal">\;</code>) have their columns stored into variables
+ named after column names, and prefixed with <em class="replaceable"><code>prefix</code></em>
+ if provided. If a query returns no row, no assignment is made and the variable
+ can be tested for existence to detect this. If a query returns more than one
+ row, the last value is kept.
+ </p><p>
+ <code class="literal">\gset</code> and <code class="literal">\aset</code> cannot be used in
+ pipeline mode, since the query results are not yet available by the time
+ the commands would need them.
+ </p><p>
+ The following example puts the final account balance from the first query
+ into variable <em class="replaceable"><code>abalance</code></em>, and fills variables
+ <em class="replaceable"><code>p_two</code></em> and <em class="replaceable"><code>p_three</code></em>
+ with integers from the third query.
+ The result of the second query is discarded.
+ The result of the two last combined queries are stored in variables
+ <em class="replaceable"><code>four</code></em> and <em class="replaceable"><code>five</code></em>.
+</p><pre class="programlisting">
+UPDATE pgbench_accounts
+ SET abalance = abalance + :delta
+ WHERE aid = :aid
+ RETURNING abalance \gset
+-- compound of two queries
+SELECT 1 \;
+SELECT 2 AS two, 3 AS three \gset p_
+SELECT 4 AS four \; SELECT 5 AS five \aset
+</pre></dd><dt><span class="term"><code class="literal">\if</code> <em class="replaceable"><code>expression</code></em><br /></span><span class="term"><code class="literal">\elif</code> <em class="replaceable"><code>expression</code></em><br /></span><span class="term"><code class="literal">\else</code><br /></span><span class="term"><code class="literal">\endif</code></span></dt><dd><p>
+ This group of commands implements nestable conditional blocks,
+ similarly to <code class="literal">psql</code>'s <a class="xref" href="app-psql.html#PSQL-METACOMMAND-IF"><code class="literal">\if</code> <em class="replaceable"><code>expression</code></em></a>.
+ Conditional expressions are identical to those with <code class="literal">\set</code>,
+ with non-zero values interpreted as true.
+ </p></dd><dt id="PGBENCH-METACOMMAND-SET"><span class="term">
+ <code class="literal">\set <em class="replaceable"><code>varname</code></em> <em class="replaceable"><code>expression</code></em></code>
+ </span></dt><dd><p>
+ Sets variable <em class="replaceable"><code>varname</code></em> to a value calculated
+ from <em class="replaceable"><code>expression</code></em>.
+ The expression may contain the <code class="literal">NULL</code> constant,
+ Boolean constants <code class="literal">TRUE</code> and <code class="literal">FALSE</code>,
+ integer constants such as <code class="literal">5432</code>,
+ double constants such as <code class="literal">3.14159</code>,
+ references to variables <code class="literal">:</code><em class="replaceable"><code>variablename</code></em>,
+ <a class="link" href="pgbench.html#PGBENCH-BUILTIN-OPERATORS" title="Built-in Operators">operators</a>
+ with their usual SQL precedence and associativity,
+ <a class="link" href="pgbench.html#PGBENCH-BUILTIN-FUNCTIONS" title="Built-In Functions">function calls</a>,
+ SQL <a class="link" href="functions-conditional.html#FUNCTIONS-CASE" title="9.18.1. CASE"><code class="token">CASE</code> generic conditional
+ expressions</a> and parentheses.
+ </p><p>
+ Functions and most operators return <code class="literal">NULL</code> on
+ <code class="literal">NULL</code> input.
+ </p><p>
+ For conditional purposes, non zero numerical values are
+ <code class="literal">TRUE</code>, zero numerical values and <code class="literal">NULL</code>
+ are <code class="literal">FALSE</code>.
+ </p><p>
+ Too large or small integer and double constants, as well as
+ integer arithmetic operators (<code class="literal">+</code>,
+ <code class="literal">-</code>, <code class="literal">*</code> and <code class="literal">/</code>)
+ raise errors on overflows.
+ </p><p>
+ When no final <code class="token">ELSE</code> clause is provided to a
+ <code class="token">CASE</code>, the default value is <code class="literal">NULL</code>.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+\set ntellers 10 * :scale
+\set aid (1021 * random(1, 100000 * :scale)) % \
+ (100000 * :scale) + 1
+\set divx CASE WHEN :x &lt;&gt; 0 THEN :y/:x ELSE NULL END
+</pre></dd><dt><span class="term">
+ <code class="literal">\sleep <em class="replaceable"><code>number</code></em> [ us | ms | s ]</code>
+ </span></dt><dd><p>
+ Causes script execution to sleep for the specified duration in
+ microseconds (<code class="literal">us</code>), milliseconds (<code class="literal">ms</code>) or seconds
+ (<code class="literal">s</code>). If the unit is omitted then seconds are the default.
+ <em class="replaceable"><code>number</code></em> can be either an integer constant or a
+ <code class="literal">:</code><em class="replaceable"><code>variablename</code></em> reference to a variable
+ having an integer value.
+ </p><p>
+ Example:
+</p><pre class="programlisting">
+\sleep 10 ms
+</pre></dd><dt><span class="term">
+ <code class="literal">\setshell <em class="replaceable"><code>varname</code></em> <em class="replaceable"><code>command</code></em> [ <em class="replaceable"><code>argument</code></em> ... ]</code>
+ </span></dt><dd><p>
+ Sets variable <em class="replaceable"><code>varname</code></em> to the result of the shell command
+ <em class="replaceable"><code>command</code></em> with the given <em class="replaceable"><code>argument</code></em>(s).
+ The command must return an integer value through its standard output.
+ </p><p>
+ <em class="replaceable"><code>command</code></em> and each <em class="replaceable"><code>argument</code></em> can be either
+ a text constant or a <code class="literal">:</code><em class="replaceable"><code>variablename</code></em> reference
+ to a variable. If you want to use an <em class="replaceable"><code>argument</code></em> starting
+ with a colon, write an additional colon at the beginning of
+ <em class="replaceable"><code>argument</code></em>.
+ </p><p>
+ Example:
+</p><pre class="programlisting">
+\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
+</pre></dd><dt><span class="term">
+ <code class="literal">\shell <em class="replaceable"><code>command</code></em> [ <em class="replaceable"><code>argument</code></em> ... ]</code>
+ </span></dt><dd><p>
+ Same as <code class="literal">\setshell</code>, but the result of the command
+ is discarded.
+ </p><p>
+ Example:
+</p><pre class="programlisting">
+\shell command literal_argument :variable ::literal_starting_with_colon
+</pre></dd><dt id="PGBENCH-METACOMMAND-PIPELINE"><span class="term"><code class="literal">\startpipeline</code><br /></span><span class="term"><code class="literal">\endpipeline</code></span></dt><dd><p>
+ These commands delimit the start and end of a pipeline of SQL
+ statements. In pipeline mode, statements are sent to the server
+ without waiting for the results of previous statements. See
+ <a class="xref" href="libpq-pipeline-mode.html" title="34.5. Pipeline Mode">Section 34.5</a> for more details.
+ Pipeline mode requires the use of extended query protocol.
+ </p></dd></dl></div></div><div class="refsect2" id="PGBENCH-BUILTIN-OPERATORS"><h3>Built-in Operators</h3><p>
+ The arithmetic, bitwise, comparison and logical operators listed in
+ <a class="xref" href="pgbench.html#PGBENCH-OPERATORS" title="Table 289. pgbench Operators">Table 289</a> are built into <span class="application">pgbench</span>
+ and may be used in expressions appearing in
+ <a class="link" href="pgbench.html#PGBENCH-METACOMMAND-SET"><code class="literal">\set</code></a>.
+ The operators are listed in increasing precedence order.
+ Except as noted, operators taking two numeric inputs will produce
+ a double value if either input is double, otherwise they produce
+ an integer result.
+ </p><div class="table" id="PGBENCH-OPERATORS"><p class="title"><strong>Table 289. pgbench Operators</strong></p><div class="table-contents"><table class="table" summary="pgbench Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>boolean</code></em> <code class="literal">OR</code> <em class="replaceable"><code>boolean</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Logical OR
+ </p>
+ <p>
+ <code class="literal">5 or 0</code>
+ → <code class="returnvalue">TRUE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>boolean</code></em> <code class="literal">AND</code> <em class="replaceable"><code>boolean</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Logical AND
+ </p>
+ <p>
+ <code class="literal">3 and 0</code>
+ → <code class="returnvalue">FALSE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">NOT</code> <em class="replaceable"><code>boolean</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Logical NOT
+ </p>
+ <p>
+ <code class="literal">not false</code>
+ → <code class="returnvalue">TRUE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>boolean</code></em> <code class="literal">IS [NOT] (NULL|TRUE|FALSE)</code>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Boolean value tests
+ </p>
+ <p>
+ <code class="literal">1 is null</code>
+ → <code class="returnvalue">FALSE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>value</code></em> <code class="literal">ISNULL|NOTNULL</code>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Nullness tests
+ </p>
+ <p>
+ <code class="literal">1 notnull</code>
+ → <code class="returnvalue">TRUE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">=</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Equal
+ </p>
+ <p>
+ <code class="literal">5 = 4</code>
+ → <code class="returnvalue">FALSE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">&lt;&gt;</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Not equal
+ </p>
+ <p>
+ <code class="literal">5 &lt;&gt; 4</code>
+ → <code class="returnvalue">TRUE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">!=</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Not equal
+ </p>
+ <p>
+ <code class="literal">5 != 5</code>
+ → <code class="returnvalue">FALSE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">&lt;</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Less than
+ </p>
+ <p>
+ <code class="literal">5 &lt; 4</code>
+ → <code class="returnvalue">FALSE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">&lt;=</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Less than or equal to
+ </p>
+ <p>
+ <code class="literal">5 &lt;= 4</code>
+ → <code class="returnvalue">FALSE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">&gt;</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Greater than
+ </p>
+ <p>
+ <code class="literal">5 &gt; 4</code>
+ → <code class="returnvalue">TRUE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">&gt;=</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>boolean</code></em></code>
+ </p>
+ <p>
+ Greater than or equal to
+ </p>
+ <p>
+ <code class="literal">5 &gt;= 4</code>
+ → <code class="returnvalue">TRUE</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integer</code></em> <code class="literal">|</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Bitwise OR
+ </p>
+ <p>
+ <code class="literal">1 | 2</code>
+ → <code class="returnvalue">3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integer</code></em> <code class="literal">#</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Bitwise XOR
+ </p>
+ <p>
+ <code class="literal">1 # 3</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integer</code></em> <code class="literal">&amp;</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Bitwise AND
+ </p>
+ <p>
+ <code class="literal">1 &amp; 3</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">~</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Bitwise NOT
+ </p>
+ <p>
+ <code class="literal">~ 1</code>
+ → <code class="returnvalue">-2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integer</code></em> <code class="literal">&lt;&lt;</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Bitwise shift left
+ </p>
+ <p>
+ <code class="literal">1 &lt;&lt; 2</code>
+ → <code class="returnvalue">4</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integer</code></em> <code class="literal">&gt;&gt;</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Bitwise shift right
+ </p>
+ <p>
+ <code class="literal">8 &gt;&gt; 2</code>
+ → <code class="returnvalue">2</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">+</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Addition
+ </p>
+ <p>
+ <code class="literal">5 + 4</code>
+ → <code class="returnvalue">9</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">-</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Subtraction
+ </p>
+ <p>
+ <code class="literal">3 - 2.0</code>
+ → <code class="returnvalue">1.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">*</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Multiplication
+ </p>
+ <p>
+ <code class="literal">5 * 4</code>
+ → <code class="returnvalue">20</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>number</code></em> <code class="literal">/</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Division (truncates the result towards zero if both inputs are integers)
+ </p>
+ <p>
+ <code class="literal">5 / 3</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <em class="replaceable"><code>integer</code></em> <code class="literal">%</code> <em class="replaceable"><code>integer</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>integer</code></em></code>
+ </p>
+ <p>
+ Modulo (remainder)
+ </p>
+ <p>
+ <code class="literal">3 % 2</code>
+ → <code class="returnvalue">1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="literal">-</code> <em class="replaceable"><code>number</code></em>
+ → <code class="returnvalue"><em class="replaceable"><code>number</code></em></code>
+ </p>
+ <p>
+ Negation
+ </p>
+ <p>
+ <code class="literal">- 2.0</code>
+ → <code class="returnvalue">-2.0</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="refsect2" id="PGBENCH-BUILTIN-FUNCTIONS"><h3>Built-In Functions</h3><p>
+ The functions listed in <a class="xref" href="pgbench.html#PGBENCH-FUNCTIONS" title="Table 290. pgbench Functions">Table 290</a> are built
+ into <span class="application">pgbench</span> and may be used in expressions appearing in
+ <a class="link" href="pgbench.html#PGBENCH-METACOMMAND-SET"><code class="literal">\set</code></a>.
+ </p><div class="table" id="PGBENCH-FUNCTIONS"><p class="title"><strong>Table 290. pgbench Functions</strong></p><div class="table-contents"><table class="table" summary="pgbench Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p>
+ <p>
+ Example(s)
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">abs</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue"></code> same type as input
+ </p>
+ <p>
+ Absolute value
+ </p>
+ <p>
+ <code class="literal">abs(-17)</code>
+ → <code class="returnvalue">17</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">debug</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue"></code> same type as input
+ </p>
+ <p>
+ Prints the argument to <span class="systemitem">stderr</span>,
+ and returns the argument.
+ </p>
+ <p>
+ <code class="literal">debug(5432.1)</code>
+ → <code class="returnvalue">5432.1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">double</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue">double</code>
+ </p>
+ <p>
+ Casts to double.
+ </p>
+ <p>
+ <code class="literal">double(5432)</code>
+ → <code class="returnvalue">5432.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">exp</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue">double</code>
+ </p>
+ <p>
+ Exponential (<code class="literal">e</code> raised to the given power)
+ </p>
+ <p>
+ <code class="literal">exp(1.0)</code>
+ → <code class="returnvalue">2.718281828459045</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">greatest</code> ( <em class="replaceable"><code>number</code></em> [<span class="optional">, <code class="literal">...</code> </span>] )
+ → <code class="returnvalue"></code> <code class="type">double</code> if any argument is double, else <code class="type">integer</code>
+ </p>
+ <p>
+ Selects the largest value among the arguments.
+ </p>
+ <p>
+ <code class="literal">greatest(5, 4, 3, 2)</code>
+ → <code class="returnvalue">5</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">hash</code> ( <em class="parameter"><code>value</code></em> [<span class="optional">, <em class="parameter"><code>seed</code></em> </span>] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ This is an alias for <code class="function">hash_murmur2</code>.
+ </p>
+ <p>
+ <code class="literal">hash(10, 5432)</code>
+ → <code class="returnvalue">-5817877081768721676</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">hash_fnv1a</code> ( <em class="parameter"><code>value</code></em> [<span class="optional">, <em class="parameter"><code>seed</code></em> </span>] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Computes <a class="ulink" href="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function" target="_top">FNV-1a hash</a>.
+ </p>
+ <p>
+ <code class="literal">hash_fnv1a(10, 5432)</code>
+ → <code class="returnvalue">-7793829335365542153</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">hash_murmur2</code> ( <em class="parameter"><code>value</code></em> [<span class="optional">, <em class="parameter"><code>seed</code></em> </span>] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Computes <a class="ulink" href="https://en.wikipedia.org/wiki/MurmurHash" target="_top">MurmurHash2 hash</a>.
+ </p>
+ <p>
+ <code class="literal">hash_murmur2(10, 5432)</code>
+ → <code class="returnvalue">-5817877081768721676</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">int</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Casts to integer.
+ </p>
+ <p>
+ <code class="literal">int(5.4 + 3.8)</code>
+ → <code class="returnvalue">9</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">least</code> ( <em class="replaceable"><code>number</code></em> [<span class="optional">, <code class="literal">...</code> </span>] )
+ → <code class="returnvalue"></code> <code class="type">double</code> if any argument is double, else <code class="type">integer</code>
+ </p>
+ <p>
+ Selects the smallest value among the arguments.
+ </p>
+ <p>
+ <code class="literal">least(5, 4, 3, 2.1)</code>
+ → <code class="returnvalue">2.1</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">ln</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue">double</code>
+ </p>
+ <p>
+ Natural logarithm
+ </p>
+ <p>
+ <code class="literal">ln(2.718281828459045)</code>
+ → <code class="returnvalue">1.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+<code class="function">mod</code> ( <em class="replaceable"><code>integer</code></em>, <em class="replaceable"><code>integer</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Modulo (remainder)
+ </p>
+ <p>
+ <code class="literal">mod(54, 32)</code>
+ → <code class="returnvalue">22</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">permute</code> ( <em class="parameter"><code>i</code></em>, <em class="parameter"><code>size</code></em> [, <em class="parameter"><code>seed</code></em> ] )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Permuted value of <em class="parameter"><code>i</code></em>, in the range
+ <code class="literal">[0, size)</code>. This is the new position of
+ <em class="parameter"><code>i</code></em> (modulo <em class="parameter"><code>size</code></em>) in a
+ pseudorandom permutation of the integers <code class="literal">0...size-1</code>,
+ parameterized by <em class="parameter"><code>seed</code></em>, see below.
+ </p>
+ <p>
+ <code class="literal">permute(0, 4)</code>
+ → <code class="returnvalue">an integer between 0 and 3</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pi</code> ()
+ → <code class="returnvalue">double</code>
+ </p>
+ <p>
+ Approximate value of <span class="symbol_font">π</span>
+ </p>
+ <p>
+ <code class="literal">pi()</code>
+ → <code class="returnvalue">3.14159265358979323846</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">pow</code> ( <em class="parameter"><code>x</code></em>, <em class="parameter"><code>y</code></em> )
+ → <code class="returnvalue">double</code>
+ </p>
+ <p class="func_signature">
+ <code class="function">power</code> ( <em class="parameter"><code>x</code></em>, <em class="parameter"><code>y</code></em> )
+ → <code class="returnvalue">double</code>
+ </p>
+ <p>
+ <em class="parameter"><code>x</code></em> raised to the power of <em class="parameter"><code>y</code></em>
+ </p>
+ <p>
+ <code class="literal">pow(2.0, 10)</code>
+ → <code class="returnvalue">1024.0</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">random</code> ( <em class="parameter"><code>lb</code></em>, <em class="parameter"><code>ub</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Computes a uniformly-distributed random integer in <code class="literal">[lb,
+ ub]</code>.
+ </p>
+ <p>
+ <code class="literal">random(1, 10)</code>
+ → <code class="returnvalue">an integer between 1 and 10</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">random_exponential</code> ( <em class="parameter"><code>lb</code></em>, <em class="parameter"><code>ub</code></em>, <em class="parameter"><code>parameter</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Computes an exponentially-distributed random integer in <code class="literal">[lb,
+ ub]</code>, see below.
+ </p>
+ <p>
+ <code class="literal">random_exponential(1, 10, 3.0)</code>
+ → <code class="returnvalue">an integer between 1 and 10</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">random_gaussian</code> ( <em class="parameter"><code>lb</code></em>, <em class="parameter"><code>ub</code></em>, <em class="parameter"><code>parameter</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Computes a Gaussian-distributed random integer in <code class="literal">[lb,
+ ub]</code>, see below.
+ </p>
+ <p>
+ <code class="literal">random_gaussian(1, 10, 2.5)</code>
+ → <code class="returnvalue">an integer between 1 and 10</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">random_zipfian</code> ( <em class="parameter"><code>lb</code></em>, <em class="parameter"><code>ub</code></em>, <em class="parameter"><code>parameter</code></em> )
+ → <code class="returnvalue">integer</code>
+ </p>
+ <p>
+ Computes a Zipfian-distributed random integer in <code class="literal">[lb,
+ ub]</code>, see below.
+ </p>
+ <p>
+ <code class="literal">random_zipfian(1, 10, 1.5)</code>
+ → <code class="returnvalue">an integer between 1 and 10</code>
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sqrt</code> ( <em class="replaceable"><code>number</code></em> )
+ → <code class="returnvalue">double</code>
+ </p>
+ <p>
+ Square root
+ </p>
+ <p>
+ <code class="literal">sqrt(2.0)</code>
+ → <code class="returnvalue">1.414213562</code>
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="literal">random</code> function generates values using a uniform
+ distribution, that is all the values are drawn within the specified
+ range with equal probability. The <code class="literal">random_exponential</code>,
+ <code class="literal">random_gaussian</code> and <code class="literal">random_zipfian</code>
+ functions require an additional double parameter which determines the precise
+ shape of the distribution.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ For an exponential distribution, <em class="replaceable"><code>parameter</code></em>
+ controls the distribution by truncating a quickly-decreasing
+ exponential distribution at <em class="replaceable"><code>parameter</code></em>, and then
+ projecting onto integers between the bounds.
+ To be precise, with
+</p><div class="literallayout"><p><br />
+f(x) = exp(-parameter * (x - min) / (max - min + 1)) / (1 - exp(-parameter))<br />
+</p></div><p>
+ Then value <em class="replaceable"><code>i</code></em> between <em class="replaceable"><code>min</code></em> and
+ <em class="replaceable"><code>max</code></em> inclusive is drawn with probability:
+ <code class="literal">f(i) - f(i + 1)</code>.
+ </p><p>
+ Intuitively, the larger the <em class="replaceable"><code>parameter</code></em>, the more
+ frequently values close to <em class="replaceable"><code>min</code></em> are accessed, and the
+ less frequently values close to <em class="replaceable"><code>max</code></em> are accessed.
+ The closer to 0 <em class="replaceable"><code>parameter</code></em> is, the flatter (more
+ uniform) the access distribution.
+ A crude approximation of the distribution is that the most frequent 1%
+ values in the range, close to <em class="replaceable"><code>min</code></em>, are drawn
+ <em class="replaceable"><code>parameter</code></em>% of the time.
+ The <em class="replaceable"><code>parameter</code></em> value must be strictly positive.
+ </p></li><li class="listitem"><p>
+ For a Gaussian distribution, the interval is mapped onto a standard
+ normal distribution (the classical bell-shaped Gaussian curve) truncated
+ at <code class="literal">-parameter</code> on the left and <code class="literal">+parameter</code>
+ on the right.
+ Values in the middle of the interval are more likely to be drawn.
+ To be precise, if <code class="literal">PHI(x)</code> is the cumulative distribution
+ function of the standard normal distribution, with mean <code class="literal">mu</code>
+ defined as <code class="literal">(max + min) / 2.0</code>, with
+</p><div class="literallayout"><p><br />
+f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) /<br />
+       (2.0 * PHI(parameter) - 1)<br />
+</p></div><p>
+ then value <em class="replaceable"><code>i</code></em> between <em class="replaceable"><code>min</code></em> and
+ <em class="replaceable"><code>max</code></em> inclusive is drawn with probability:
+ <code class="literal">f(i + 0.5) - f(i - 0.5)</code>.
+ Intuitively, the larger the <em class="replaceable"><code>parameter</code></em>, the more
+ frequently values close to the middle of the interval are drawn, and the
+ less frequently values close to the <em class="replaceable"><code>min</code></em> and
+ <em class="replaceable"><code>max</code></em> bounds. About 67% of values are drawn from the
+ middle <code class="literal">1.0 / parameter</code>, that is a relative
+ <code class="literal">0.5 / parameter</code> around the mean, and 95% in the middle
+ <code class="literal">2.0 / parameter</code>, that is a relative
+ <code class="literal">1.0 / parameter</code> around the mean; for instance, if
+ <em class="replaceable"><code>parameter</code></em> is 4.0, 67% of values are drawn from the
+ middle quarter (1.0 / 4.0) of the interval (i.e., from
+ <code class="literal">3.0 / 8.0</code> to <code class="literal">5.0 / 8.0</code>) and 95% from
+ the middle half (<code class="literal">2.0 / 4.0</code>) of the interval (second and third
+ quartiles). The minimum allowed <em class="replaceable"><code>parameter</code></em>
+ value is 2.0.
+ </p></li><li class="listitem"><p>
+ <code class="literal">random_zipfian</code> generates a bounded Zipfian
+ distribution.
+ <em class="replaceable"><code>parameter</code></em> defines how skewed the distribution
+ is. The larger the <em class="replaceable"><code>parameter</code></em>, the more
+ frequently values closer to the beginning of the interval are drawn.
+ The distribution is such that, assuming the range starts from 1,
+ the ratio of the probability of drawing <em class="replaceable"><code>k</code></em>
+ versus drawing <em class="replaceable"><code>k+1</code></em> is
+ <code class="literal">((<em class="replaceable"><code>k</code></em>+1)/<em class="replaceable"><code>k</code></em>)**<em class="replaceable"><code>parameter</code></em></code>.
+ For example, <code class="literal">random_zipfian(1, ..., 2.5)</code> produces
+ the value <code class="literal">1</code> about <code class="literal">(2/1)**2.5 =
+ 5.66</code> times more frequently than <code class="literal">2</code>, which
+ itself is produced <code class="literal">(3/2)**2.5 = 2.76</code> times more
+ frequently than <code class="literal">3</code>, and so on.
+ </p><p>
+ <span class="application">pgbench</span>'s implementation is based on
+ "Non-Uniform Random Variate Generation", Luc Devroye, p. 550-551,
+ Springer 1986. Due to limitations of that algorithm,
+ the <em class="replaceable"><code>parameter</code></em> value is restricted to
+ the range [1.001, 1000].
+ </p></li></ul></div><div class="note"><h3 class="title">Note</h3><p>
+ When designing a benchmark which selects rows non-uniformly, be aware
+ that the rows chosen may be correlated with other data such as IDs from
+ a sequence or the physical row ordering, which may skew performance
+ measurements.
+ </p><p>
+ To avoid this, you may wish to use the <code class="function">permute</code>
+ function, or some other additional step with similar effect, to shuffle
+ the selected rows and remove such correlations.
+ </p></div><p>
+ Hash functions <code class="literal">hash</code>, <code class="literal">hash_murmur2</code> and
+ <code class="literal">hash_fnv1a</code> accept an input value and an optional seed parameter.
+ In case the seed isn't provided the value of <code class="literal">:default_seed</code>
+ is used, which is initialized randomly unless set by the command-line
+ <code class="literal">-D</code> option.
+ </p><p>
+ <code class="literal">permute</code> accepts an input value, a size, and an optional
+ seed parameter. It generates a pseudorandom permutation of integers in
+ the range <code class="literal">[0, size)</code>, and returns the index of the input
+ value in the permuted values. The permutation chosen is parameterized by
+ the seed, which defaults to <code class="literal">:default_seed</code>, if not
+ specified. Unlike the hash functions, <code class="literal">permute</code> ensures
+ that there are no collisions or holes in the output values. Input values
+ outside the interval are interpreted modulo the size. The function raises
+ an error if the size is not positive. <code class="function">permute</code> can be
+ used to scatter the distribution of non-uniform random functions such as
+ <code class="literal">random_zipfian</code> or <code class="literal">random_exponential</code>
+ so that values drawn more often are not trivially correlated. For
+ instance, the following <span class="application">pgbench</span> script
+ simulates a possible real world workload typical for social media and
+ blogging platforms where a few accounts generate excessive load:
+
+</p><pre class="programlisting">
+\set size 1000000
+\set r random_zipfian(1, :size, 1.07)
+\set k 1 + permute(:r, :size)
+</pre><p>
+
+ In some cases several distinct distributions are needed which don't correlate
+ with each other and this is when the optional seed parameter comes in handy:
+
+</p><pre class="programlisting">
+\set k1 1 + permute(:r, :size, :default_seed + 123)
+\set k2 1 + permute(:r, :size, :default_seed + 321)
+</pre><p>
+
+ A similar behavior can also be approximated with <code class="function">hash</code>:
+
+</p><pre class="programlisting">
+\set size 1000000
+\set r random_zipfian(1, 100 * :size, 1.07)
+\set k 1 + abs(hash(:r)) % :size
+</pre><p>
+
+ However, since <code class="function">hash</code> generates collisions, some values
+ will not be reachable and others will be more frequent than expected from
+ the original distribution.
+ </p><p>
+ As an example, the full definition of the built-in TPC-B-like
+ transaction is:
+
+</p><pre class="programlisting">
+\set aid random(1, 100000 * :scale)
+\set bid random(1, 1 * :scale)
+\set tid random(1, 10 * :scale)
+\set delta random(-5000, 5000)
+BEGIN;
+UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+END;
+</pre><p>
+
+ This script allows each iteration of the transaction to reference
+ different, randomly-chosen rows. (This example also shows why it's
+ important for each client session to have its own variables —
+ otherwise they'd not be independently touching different rows.)
+ </p></div><div class="refsect2" id="id-1.9.4.11.9.6"><h3>Per-Transaction Logging</h3><p>
+ With the <code class="option">-l</code> option (but without
+ the <code class="option">--aggregate-interval</code> option),
+ <span class="application">pgbench</span> writes information about each transaction
+ to a log file. The log file will be named
+ <code class="filename"><em class="replaceable"><code>prefix</code></em>.<em class="replaceable"><code>nnn</code></em></code>,
+ where <em class="replaceable"><code>prefix</code></em> defaults to <code class="literal">pgbench_log</code>, and
+ <em class="replaceable"><code>nnn</code></em> is the PID of the
+ <span class="application">pgbench</span> process.
+ The prefix can be changed by using the <code class="option">--log-prefix</code> option.
+ If the <code class="option">-j</code> option is 2 or higher, so that there are multiple
+ worker threads, each will have its own log file. The first worker will
+ use the same name for its log file as in the standard single worker case.
+ The additional log files for the other workers will be named
+ <code class="filename"><em class="replaceable"><code>prefix</code></em>.<em class="replaceable"><code>nnn</code></em>.<em class="replaceable"><code>mmm</code></em></code>,
+ where <em class="replaceable"><code>mmm</code></em> is a sequential number for each worker starting
+ with 1.
+ </p><p>
+ Each line in a log file describes one transaction.
+ It contains the following space-separated fields:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>client_id</code></em></span></dt><dd><p>
+ identifies the client session that ran the transaction
+ </p></dd><dt><span class="term"><em class="replaceable"><code>transaction_no</code></em></span></dt><dd><p>
+ counts how many transactions have been run by that session
+ </p></dd><dt><span class="term"><em class="replaceable"><code>time</code></em></span></dt><dd><p>
+ transaction's elapsed time, in microseconds
+ </p></dd><dt><span class="term"><em class="replaceable"><code>script_no</code></em></span></dt><dd><p>
+ identifies the script file that was used for the transaction
+ (useful when multiple scripts are specified
+ with <code class="option">-f</code> or <code class="option">-b</code>)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>time_epoch</code></em></span></dt><dd><p>
+ transaction's completion time, as a Unix-epoch time stamp
+ </p></dd><dt><span class="term"><em class="replaceable"><code>time_us</code></em></span></dt><dd><p>
+ fractional-second part of transaction's completion time, in
+ microseconds
+ </p></dd><dt><span class="term"><em class="replaceable"><code>schedule_lag</code></em></span></dt><dd><p>
+ transaction start delay, that is the difference between the
+ transaction's scheduled start time and the time it actually
+ started, in microseconds
+ (present only if <code class="option">--rate</code> is specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>retries</code></em></span></dt><dd><p>
+ count of retries after serialization or deadlock errors during the
+ transaction
+ (present only if <code class="option">--max-tries</code> is not equal to one)
+ </p></dd></dl></div><p>
+ </p><p>
+ When both <code class="option">--rate</code> and <code class="option">--latency-limit</code> are used,
+ the <em class="replaceable"><code>time</code></em> for a skipped transaction will be reported as
+ <code class="literal">skipped</code>.
+ If the transaction ends with a failure, its <em class="replaceable"><code>time</code></em>
+ will be reported as <code class="literal">failed</code>. If you use the
+ <code class="option">--failures-detailed</code> option, the
+ <em class="replaceable"><code>time</code></em> of the failed transaction will be reported as
+ <code class="literal">serialization</code> or
+ <code class="literal">deadlock</code> depending on the type of failure (see
+ <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a> for more information).
+ </p><p>
+ Here is a snippet of a log file generated in a single-client run:
+</p><pre class="screen">
+0 199 2241 0 1175850568 995598
+0 200 2465 0 1175850568 998079
+0 201 2513 0 1175850569 608
+0 202 2038 0 1175850569 2663
+</pre><p>
+
+ Another example with <code class="literal">--rate=100</code>
+ and <code class="literal">--latency-limit=5</code> (note the additional
+ <em class="replaceable"><code>schedule_lag</code></em> column):
+</p><pre class="screen">
+0 81 4621 0 1412881037 912698 3005
+0 82 6173 0 1412881037 914578 4304
+0 83 skipped 0 1412881037 914578 5217
+0 83 skipped 0 1412881037 914578 5099
+0 83 4722 0 1412881037 916203 3108
+0 84 4142 0 1412881037 918023 2333
+0 85 2465 0 1412881037 919759 740
+</pre><p>
+ In this example, transaction 82 was late, because its latency (6.173 ms) was
+ over the 5 ms limit. The next two transactions were skipped, because they
+ were already late before they were even started.
+ </p><p>
+ The following example shows a snippet of a log file with failures and
+ retries, with the maximum number of tries set to 10 (note the additional
+ <em class="replaceable"><code>retries</code></em> column):
+</p><pre class="screen">
+3 0 47423 0 1499414498 34501 3
+3 1 8333 0 1499414498 42848 0
+3 2 8358 0 1499414498 51219 0
+4 0 72345 0 1499414498 59433 6
+1 3 41718 0 1499414498 67879 4
+1 4 8416 0 1499414498 76311 0
+3 3 33235 0 1499414498 84469 3
+0 0 failed 0 1499414498 84905 9
+2 0 failed 0 1499414498 86248 9
+3 4 8307 0 1499414498 92788 0
+</pre><p>
+ </p><p>
+ If the <code class="option">--failures-detailed</code> option is used, the type of
+ failure is reported in the <em class="replaceable"><code>time</code></em> like this:
+</p><pre class="screen">
+3 0 47423 0 1499414498 34501 3
+3 1 8333 0 1499414498 42848 0
+3 2 8358 0 1499414498 51219 0
+4 0 72345 0 1499414498 59433 6
+1 3 41718 0 1499414498 67879 4
+1 4 8416 0 1499414498 76311 0
+3 3 33235 0 1499414498 84469 3
+0 0 serialization 0 1499414498 84905 9
+2 0 serialization 0 1499414498 86248 9
+3 4 8307 0 1499414498 92788 0
+</pre><p>
+ </p><p>
+ When running a long test on hardware that can handle a lot of transactions,
+ the log files can become very large. The <code class="option">--sampling-rate</code> option
+ can be used to log only a random sample of transactions.
+ </p></div><div class="refsect2" id="id-1.9.4.11.9.7"><h3>Aggregated Logging</h3><p>
+ With the <code class="option">--aggregate-interval</code> option, a different
+ format is used for the log files. Each log line describes one
+ aggregation interval. It contains the following space-separated
+ fields:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>interval_start</code></em></span></dt><dd><p>
+ start time of the interval, as a Unix-epoch time stamp
+ </p></dd><dt><span class="term"><em class="replaceable"><code>num_transactions</code></em></span></dt><dd><p>
+ number of transactions within the interval
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sum_latency</code></em></span></dt><dd><p>
+ sum of transaction latencies
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sum_latency_2</code></em></span></dt><dd><p>
+ sum of squares of transaction latencies
+ </p></dd><dt><span class="term"><em class="replaceable"><code>min_latency</code></em></span></dt><dd><p>
+ minimum transaction latency
+ </p></dd><dt><span class="term"><em class="replaceable"><code>max_latency</code></em></span></dt><dd><p>
+ maximum transaction latency
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sum_lag</code></em></span></dt><dd><p>
+ sum of transaction start delays
+ (zero unless <code class="option">--rate</code> is specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sum_lag_2</code></em></span></dt><dd><p>
+ sum of squares of transaction start delays
+ (zero unless <code class="option">--rate</code> is specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>min_lag</code></em></span></dt><dd><p>
+ minimum transaction start delay
+ (zero unless <code class="option">--rate</code> is specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>max_lag</code></em></span></dt><dd><p>
+ maximum transaction start delay
+ (zero unless <code class="option">--rate</code> is specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>skipped</code></em></span></dt><dd><p>
+ number of transactions skipped because they would have started too late
+ (zero unless <code class="option">--rate</code>
+ and <code class="option">--latency-limit</code> are specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>retried</code></em></span></dt><dd><p>
+ number of retried transactions
+ (zero unless <code class="option">--max-tries</code> is not equal to one)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>retries</code></em></span></dt><dd><p>
+ number of retries after serialization or deadlock errors
+ (zero unless <code class="option">--max-tries</code> is not equal to one)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>serialization_failures</code></em></span></dt><dd><p>
+ number of transactions that got a serialization error and were not
+ retried afterwards
+ (zero unless <code class="option">--failures-detailed</code> is specified)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>deadlock_failures</code></em></span></dt><dd><p>
+ number of transactions that got a deadlock error and were not
+ retried afterwards
+ (zero unless <code class="option">--failures-detailed</code> is specified)
+ </p></dd></dl></div><p>
+ </p><p>
+ Here is some example output generated with these options:
+</p><pre class="screen">
+<strong class="userinput"><code>pgbench --aggregate-interval=10 --time=20 --client=10 --log --rate=1000 --latency-limit=10 --failures-detailed --max-tries=10 test</code></strong>
+
+1650260552 5178 26171317 177284491527 1136 44462 2647617 7321113867 0 9866 64 7564 28340 4148 0
+1650260562 4808 25573984 220121792172 1171 62083 3037380 9666800914 0 9998 598 7392 26621 4527 0
+</pre><p>
+ </p><p>
+ Notice that while the plain (unaggregated) log format shows which script
+ was used for each transaction, the aggregated format does not. Therefore if
+ you need per-script data, you need to aggregate the data on your own.
+ </p></div><div class="refsect2" id="id-1.9.4.11.9.8"><h3>Per-Statement Report</h3><p>
+ With the <code class="option">-r</code> option, <span class="application">pgbench</span>
+ collects the following statistics for each statement:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">latency</code> — elapsed transaction time for each
+ statement. <span class="application">pgbench</span> reports an average value
+ of all successful runs of the statement.
+ </p></li><li class="listitem"><p>
+ The number of failures in this statement. See
+ <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a> for more information.
+ </p></li><li class="listitem"><p>
+ The number of retries after a serialization or a deadlock error in this
+ statement. See <a class="xref" href="pgbench.html#FAILURES-AND-RETRIES" title="Failures and Serialization/Deadlock Retries">Failures and Serialization/Deadlock Retries</a> for more information.
+ </p></li></ul></div><p>
+ </p><p>
+ The report displays retry statistics only if the <code class="option">--max-tries</code>
+ option is not equal to 1.
+ </p><p>
+ All values are computed for each statement executed by every client and are
+ reported after the benchmark has finished.
+ </p><p>
+ For the default script, the output will look similar to this:
+</p><pre class="screen">
+starting vacuum...end.
+transaction type: &lt;builtin: TPC-B (sort of)&gt;
+scaling factor: 1
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+number of failed transactions: 0 (0.000%)
+number of transactions above the 50.0 ms latency limit: 1311/10000 (13.110 %)
+latency average = 28.488 ms
+latency stddev = 21.009 ms
+initial connection time = 69.068 ms
+tps = 346.224794 (without initial connection time)
+statement latencies in milliseconds and failures:
+ 0.012 0 \set aid random(1, 100000 * :scale)
+ 0.002 0 \set bid random(1, 1 * :scale)
+ 0.002 0 \set tid random(1, 10 * :scale)
+ 0.002 0 \set delta random(-5000, 5000)
+ 0.319 0 BEGIN;
+ 0.834 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+ 0.641 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+ 11.126 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+ 12.961 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+ 0.634 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+ 1.957 0 END;
+</pre><p>
+
+ Another example of output for the default script using serializable default
+ transaction isolation level (<code class="command">PGOPTIONS='-c
+ default_transaction_isolation=serializable' pgbench ...</code>):
+</p><pre class="screen">
+starting vacuum...end.
+transaction type: &lt;builtin: TPC-B (sort of)&gt;
+scaling factor: 1
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 10
+number of transactions per client: 1000
+number of transactions actually processed: 6317/10000
+number of failed transactions: 3683 (36.830%)
+number of transactions retried: 7667 (76.670%)
+total number of retries: 45339
+number of transactions above the 50.0 ms latency limit: 106/6317 (1.678 %)
+latency average = 17.016 ms
+latency stddev = 13.283 ms
+initial connection time = 45.017 ms
+tps = 186.792667 (without initial connection time)
+statement latencies in milliseconds, failures and retries:
+ 0.006 0 0 \set aid random(1, 100000 * :scale)
+ 0.001 0 0 \set bid random(1, 1 * :scale)
+ 0.001 0 0 \set tid random(1, 10 * :scale)
+ 0.001 0 0 \set delta random(-5000, 5000)
+ 0.385 0 0 BEGIN;
+ 0.773 0 1 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+ 0.624 0 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+ 1.098 320 3762 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+ 0.582 3363 41576 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+ 0.465 0 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+ 1.933 0 0 END;
+</pre><p>
+ If multiple script files are specified, all statistics are reported
+ separately for each script file.
+ </p><p>
+ Note that collecting the additional timing information needed for
+ per-statement latency computation adds some overhead. This will slow
+ average execution speed and lower the computed TPS. The amount
+ of slowdown varies significantly depending on platform and hardware.
+ Comparing average TPS values with and without latency reporting enabled
+ is a good way to measure if the timing overhead is significant.
+ </p></div><div class="refsect2" id="FAILURES-AND-RETRIES"><h3>Failures and Serialization/Deadlock Retries</h3><p>
+ When executing <span class="application">pgbench</span>, there are three main types
+ of errors:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Errors of the main program. They are the most serious and always result
+ in an immediate exit from <span class="application">pgbench</span> with the
+ corresponding error message. They include:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ errors at the beginning of <span class="application">pgbench</span>
+ (e.g. an invalid option value);
+ </p></li><li class="listitem"><p>
+ errors in the initialization mode (e.g. the query to create
+ tables for built-in scripts fails);
+ </p></li><li class="listitem"><p>
+ errors before starting threads (e.g. could not connect to the
+ database server, syntax error in the meta command, thread
+ creation failure);
+ </p></li><li class="listitem"><p>
+ internal <span class="application">pgbench</span> errors (which are
+ supposed to never occur...).
+ </p></li></ul></div></li><li class="listitem"><p>
+ Errors when the thread manages its clients (e.g. the client could not
+ start a connection to the database server / the socket for connecting
+ the client to the database server has become invalid). In such cases
+ all clients of this thread stop while other threads continue to work.
+ </p></li><li class="listitem"><p>
+ Direct client errors. They lead to immediate exit from
+ <span class="application">pgbench</span> with the corresponding error message
+ only in the case of an internal <span class="application">pgbench</span>
+ error (which are supposed to never occur...). Otherwise in the worst
+ case they only lead to the abortion of the failed client while other
+ clients continue their run (but some client errors are handled without
+ an abortion of the client and reported separately, see below). Later in
+ this section it is assumed that the discussed errors are only the
+ direct client errors and they are not internal
+ <span class="application">pgbench</span> errors.
+ </p></li></ul></div><p>
+ </p><p>
+ A client's run is aborted in case of a serious error; for example, the
+ connection with the database server was lost or the end of script was reached
+ without completing the last transaction. In addition, if execution of an SQL
+ or meta command fails for reasons other than serialization or deadlock errors,
+ the client is aborted. Otherwise, if an SQL command fails with serialization or
+ deadlock errors, the client is not aborted. In such cases, the current
+ transaction is rolled back, which also includes setting the client variables
+ as they were before the run of this transaction (it is assumed that one
+ transaction script contains only one transaction; see
+ <a class="xref" href="pgbench.html#TRANSACTIONS-AND-SCRIPTS" title="What Is the “Transaction” Actually Performed in pgbench?">What Is the "Transaction" Actually Performed in pgbench?</a> for more information).
+ Transactions with serialization or deadlock errors are repeated after
+ rollbacks until they complete successfully or reach the maximum
+ number of tries (specified by the <code class="option">--max-tries</code> option) / the maximum
+ time of retries (specified by the <code class="option">--latency-limit</code> option) / the end
+ of benchmark (specified by the <code class="option">--time</code> option). If
+ the last trial run fails, this transaction will be reported as failed but
+ the client is not aborted and continues to work.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Without specifying the <code class="option">--max-tries</code> option, a transaction will
+ never be retried after a serialization or deadlock error because its default
+ value is 1. Use an unlimited number of tries (<code class="literal">--max-tries=0</code>)
+ and the <code class="option">--latency-limit</code> option to limit only the maximum time
+ of tries. You can also use the <code class="option">--time</code> option to limit the
+ benchmark duration under an unlimited number of tries.
+ </p><p>
+ Be careful when repeating scripts that contain multiple transactions: the
+ script is always retried completely, so successful transactions can be
+ performed several times.
+ </p><p>
+ Be careful when repeating transactions with shell commands. Unlike the
+ results of SQL commands, the results of shell commands are not rolled back,
+ except for the variable value of the <code class="command">\setshell</code> command.
+ </p></div><p>
+ The latency of a successful transaction includes the entire time of
+ transaction execution with rollbacks and retries. The latency is measured
+ only for successful transactions and commands but not for failed transactions
+ or commands.
+ </p><p>
+ The main report contains the number of failed transactions. If the
+ <code class="option">--max-tries</code> option is not equal to 1, the main report also
+ contains statistics related to retries: the total number of retried
+ transactions and total number of retries. The per-script report inherits all
+ these fields from the main report. The per-statement report displays retry
+ statistics only if the <code class="option">--max-tries</code> option is not equal to 1.
+ </p><p>
+ If you want to group failures by basic types in per-transaction and
+ aggregation logs, as well as in the main and per-script reports, use the
+ <code class="option">--failures-detailed</code> option. If you also want to distinguish
+ all errors and failures (errors without retrying) by type including which
+ limit for retries was exceeded and how much it was exceeded by for the
+ serialization/deadlock failures, use the <code class="option">--verbose-errors</code>
+ option.
+ </p></div><div class="refsect2" id="id-1.9.4.11.9.10"><h3>Good Practices</h3><p>
+ It is very easy to use <span class="application">pgbench</span> to produce completely
+ meaningless numbers. Here are some guidelines to help you get useful
+ results.
+ </p><p>
+ In the first place, <span class="emphasis"><em>never</em></span> believe any test that runs
+ for only a few seconds. Use the <code class="option">-t</code> or <code class="option">-T</code> option
+ to make the run last at least a few minutes, so as to average out noise.
+ In some cases you could need hours to get numbers that are reproducible.
+ It's a good idea to try the test run a few times, to find out if your
+ numbers are reproducible or not.
+ </p><p>
+ For the default TPC-B-like test scenario, the initialization scale factor
+ (<code class="option">-s</code>) should be at least as large as the largest number of
+ clients you intend to test (<code class="option">-c</code>); else you'll mostly be
+ measuring update contention. There are only <code class="option">-s</code> rows in
+ the <code class="structname">pgbench_branches</code> table, and every transaction wants to
+ update one of them, so <code class="option">-c</code> values in excess of <code class="option">-s</code>
+ will undoubtedly result in lots of transactions blocked waiting for
+ other transactions.
+ </p><p>
+ The default test scenario is also quite sensitive to how long it's been
+ since the tables were initialized: accumulation of dead rows and dead space
+ in the tables changes the results. To understand the results you must keep
+ track of the total number of updates and when vacuuming happens. If
+ autovacuum is enabled it can result in unpredictable changes in measured
+ performance.
+ </p><p>
+ A limitation of <span class="application">pgbench</span> is that it can itself become
+ the bottleneck when trying to test a large number of client sessions.
+ This can be alleviated by running <span class="application">pgbench</span> on a different
+ machine from the database server, although low network latency will be
+ essential. It might even be useful to run several <span class="application">pgbench</span>
+ instances concurrently, on several client machines, against the same
+ database server.
+ </p></div><div class="refsect2" id="id-1.9.4.11.9.11"><h3>Security</h3><p>
+ If untrusted users have access to a database that has not adopted a
+ <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage pattern</a>,
+ do not run <span class="application">pgbench</span> in that
+ database. <span class="application">pgbench</span> uses unqualified names and
+ does not manipulate the search path.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgbasebackup.html" title="pg_basebackup">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-client.html" title="PostgreSQL Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgconfig.html" title="pg_config">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_basebackup</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_config</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgbuffercache.html b/doc/src/sgml/html/pgbuffercache.html
new file mode 100644
index 0000000..1c03510
--- /dev/null
+++ b/doc/src/sgml/html/pgbuffercache.html
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.27. pg_buffercache</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="passwordcheck.html" title="F.26. passwordcheck" /><link rel="next" href="pgcrypto.html" title="F.28. pgcrypto" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.27. pg_buffercache</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="passwordcheck.html" title="F.26. passwordcheck">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgcrypto.html" title="F.28. pgcrypto">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGBUFFERCACHE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.27. pg_buffercache</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgbuffercache.html#id-1.11.7.36.7">F.27.1. The <code class="structname">pg_buffercache</code> View</a></span></dt><dt><span class="sect2"><a href="pgbuffercache.html#id-1.11.7.36.8">F.27.2. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgbuffercache.html#id-1.11.7.36.9">F.27.3. Authors</a></span></dt></dl></div><a id="id-1.11.7.36.2" class="indexterm"></a><p>
+ The <code class="filename">pg_buffercache</code> module provides a means for
+ examining what's happening in the shared buffer cache in real time.
+ </p><a id="id-1.11.7.36.4" class="indexterm"></a><p>
+ The module provides a C function <code class="function">pg_buffercache_pages</code>
+ that returns a set of records, plus a view
+ <code class="structname">pg_buffercache</code> that wraps the function for
+ convenient use.
+ </p><p>
+ By default, use is restricted to superusers and roles with privileges of the
+ <code class="literal">pg_monitor</code> role. Access may be granted to others
+ using <code class="command">GRANT</code>.
+ </p><div class="sect2" id="id-1.11.7.36.7"><div class="titlepage"><div><div><h3 class="title">F.27.1. The <code class="structname">pg_buffercache</code> View</h3></div></div></div><p>
+ The definitions of the columns exposed by the view are shown in <a class="xref" href="pgbuffercache.html#PGBUFFERCACHE-COLUMNS" title="Table F.15. pg_buffercache Columns">Table F.15</a>.
+ </p><div class="table" id="PGBUFFERCACHE-COLUMNS"><p class="title"><strong>Table F.15. <code class="structname">pg_buffercache</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_buffercache Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">bufferid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ ID, in the range 1..<code class="varname">shared_buffers</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relfilenode</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relfilenode</code>)
+ </p>
+ <p>
+ Filenode number of the relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reltablespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Tablespace OID of the relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reldatabase</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Database OID of the relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relforknumber</code> <code class="type">smallint</code>
+ </p>
+ <p>
+ Fork number within the relation; see
+ <code class="filename">common/relpath.h</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relblocknumber</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Page number within the relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">isdirty</code> <code class="type">boolean</code>
+ </p>
+ <p>
+ Is the page dirty?
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usagecount</code> <code class="type">smallint</code>
+ </p>
+ <p>
+ Clock-sweep access count
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pinning_backends</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Number of backends pinning this buffer
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ There is one row for each buffer in the shared cache. Unused buffers are
+ shown with all fields null except <code class="structfield">bufferid</code>. Shared system
+ catalogs are shown as belonging to database zero.
+ </p><p>
+ Because the cache is shared by all the databases, there will normally be
+ pages from relations not belonging to the current database. This means
+ that there may not be matching join rows in <code class="structname">pg_class</code> for
+ some rows, or that there could even be incorrect joins. If you are
+ trying to join against <code class="structname">pg_class</code>, it's a good idea to
+ restrict the join to rows having <code class="structfield">reldatabase</code> equal to
+ the current database's OID or zero.
+ </p><p>
+ Since buffer manager locks are not taken to copy the buffer state data that
+ the view will display, accessing <code class="structname">pg_buffercache</code> view
+ has less impact on normal buffer activity but it doesn't provide a consistent
+ set of results across all buffers. However, we ensure that the information of
+ each buffer is self-consistent.
+ </p></div><div class="sect2" id="id-1.11.7.36.8"><div class="titlepage"><div><div><h3 class="title">F.27.2. Sample Output</h3></div></div></div><pre class="screen">
+regression=# SELECT n.nspname, c.relname, count(*) AS buffers
+ FROM pg_buffercache b JOIN pg_class c
+ ON b.relfilenode = pg_relation_filenode(c.oid) AND
+ b.reldatabase IN (0, (SELECT oid FROM pg_database
+ WHERE datname = current_database()))
+ JOIN pg_namespace n ON n.oid = c.relnamespace
+ GROUP BY n.nspname, c.relname
+ ORDER BY 3 DESC
+ LIMIT 10;
+
+ nspname | relname | buffers
+------------+------------------------+---------
+ public | delete_test_table | 593
+ public | delete_test_table_pkey | 494
+ pg_catalog | pg_attribute | 472
+ public | quad_poly_tbl | 353
+ public | tenk2 | 349
+ public | tenk1 | 349
+ public | gin_test_idx | 306
+ pg_catalog | pg_largeobject | 206
+ public | gin_test_tbl | 188
+ public | spgist_text_tbl | 182
+(10 rows)
+</pre></div><div class="sect2" id="id-1.11.7.36.9"><div class="titlepage"><div><div><h3 class="title">F.27.3. Authors</h3></div></div></div><p>
+ Mark Kirkwood <code class="email">&lt;<a class="email" href="mailto:markir@paradise.net.nz">markir@paradise.net.nz</a>&gt;</code>
+ </p><p>
+ Design suggestions: Neil Conway <code class="email">&lt;<a class="email" href="mailto:neilc@samurai.com">neilc@samurai.com</a>&gt;</code>
+ </p><p>
+ Debugging advice: Tom Lane <code class="email">&lt;<a class="email" href="mailto:tgl@sss.pgh.pa.us">tgl@sss.pgh.pa.us</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="passwordcheck.html" title="F.26. passwordcheck">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgcrypto.html" title="F.28. pgcrypto">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.26. passwordcheck </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.28. pgcrypto</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgcrypto.html b/doc/src/sgml/html/pgcrypto.html
new file mode 100644
index 0000000..abb6aa8
--- /dev/null
+++ b/doc/src/sgml/html/pgcrypto.html
@@ -0,0 +1,544 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.28. pgcrypto</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgbuffercache.html" title="F.27. pg_buffercache" /><link rel="next" href="pgfreespacemap.html" title="F.29. pg_freespacemap" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.28. pgcrypto</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgbuffercache.html" title="F.27. pg_buffercache">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgfreespacemap.html" title="F.29. pg_freespacemap">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGCRYPTO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.28. pgcrypto</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.7">F.28.1. General Hashing Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.8">F.28.2. Password Hashing Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.9">F.28.3. PGP Encryption Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.10">F.28.4. Raw Encryption Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.11">F.28.5. Random-Data Functions</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.12">F.28.6. Notes</a></span></dt><dt><span class="sect2"><a href="pgcrypto.html#id-1.11.7.37.13">F.28.7. Author</a></span></dt></dl></div><a id="id-1.11.7.37.2" class="indexterm"></a><a id="id-1.11.7.37.3" class="indexterm"></a><p>
+ The <code class="filename">pgcrypto</code> module provides cryptographic functions for
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><p>
+ <code class="filename">pgcrypto</code> requires OpenSSL and won't be installed if
+ OpenSSL support was not selected when PostgreSQL was built.
+ </p><div class="sect2" id="id-1.11.7.37.7"><div class="titlepage"><div><div><h3 class="title">F.28.1. General Hashing Functions</h3></div></div></div><div class="sect3" id="id-1.11.7.37.7.2"><div class="titlepage"><div><div><h4 class="title">F.28.1.1. <code class="function">digest()</code></h4></div></div></div><a id="id-1.11.7.37.7.2.2" class="indexterm"></a><pre class="synopsis">
+digest(data text, type text) returns bytea
+digest(data bytea, type text) returns bytea
+</pre><p>
+ Computes a binary hash of the given <em class="parameter"><code>data</code></em>.
+ <em class="parameter"><code>type</code></em> is the algorithm to use.
+ Standard algorithms are <code class="literal">md5</code>, <code class="literal">sha1</code>,
+ <code class="literal">sha224</code>, <code class="literal">sha256</code>,
+ <code class="literal">sha384</code> and <code class="literal">sha512</code>.
+ Moreover, any digest algorithm <span class="productname">OpenSSL</span> supports
+ is automatically picked up.
+ </p><p>
+ If you want the digest as a hexadecimal string, use
+ <code class="function">encode()</code> on the result. For example:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
+ SELECT encode(digest($1, 'sha1'), 'hex')
+$$ LANGUAGE SQL STRICT IMMUTABLE;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.11.7.37.7.3"><div class="titlepage"><div><div><h4 class="title">F.28.1.2. <code class="function">hmac()</code></h4></div></div></div><a id="id-1.11.7.37.7.3.2" class="indexterm"></a><pre class="synopsis">
+hmac(data text, key text, type text) returns bytea
+hmac(data bytea, key bytea, type text) returns bytea
+</pre><p>
+ Calculates hashed MAC for <em class="parameter"><code>data</code></em> with key <em class="parameter"><code>key</code></em>.
+ <em class="parameter"><code>type</code></em> is the same as in <code class="function">digest()</code>.
+ </p><p>
+ This is similar to <code class="function">digest()</code> but the hash can only be
+ recalculated knowing the key. This prevents the scenario of someone
+ altering data and also changing the hash to match.
+ </p><p>
+ If the key is larger than the hash block size it will first be hashed and
+ the result will be used as key.
+ </p></div></div><div class="sect2" id="id-1.11.7.37.8"><div class="titlepage"><div><div><h3 class="title">F.28.2. Password Hashing Functions</h3></div></div></div><p>
+ The functions <code class="function">crypt()</code> and <code class="function">gen_salt()</code>
+ are specifically designed for hashing passwords.
+ <code class="function">crypt()</code> does the hashing and <code class="function">gen_salt()</code>
+ prepares algorithm parameters for it.
+ </p><p>
+ The algorithms in <code class="function">crypt()</code> differ from the usual
+ MD5 or SHA1 hashing algorithms in the following respects:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ They are slow. As the amount of data is so small, this is the only
+ way to make brute-forcing passwords hard.
+ </p></li><li class="listitem"><p>
+ They use a random value, called the <em class="firstterm">salt</em>, so that users
+ having the same password will have different encrypted passwords.
+ This is also an additional defense against reversing the algorithm.
+ </p></li><li class="listitem"><p>
+ They include the algorithm type in the result, so passwords hashed with
+ different algorithms can co-exist.
+ </p></li><li class="listitem"><p>
+ Some of them are adaptive — that means when computers get
+ faster, you can tune the algorithm to be slower, without
+ introducing incompatibility with existing passwords.
+ </p></li></ol></div><p>
+ <a class="xref" href="pgcrypto.html#PGCRYPTO-CRYPT-ALGORITHMS" title="Table F.16. Supported Algorithms for crypt()">Table F.16</a> lists the algorithms
+ supported by the <code class="function">crypt()</code> function.
+ </p><div class="table" id="PGCRYPTO-CRYPT-ALGORITHMS"><p class="title"><strong>Table F.16. Supported Algorithms for <code class="function">crypt()</code></strong></p><div class="table-contents"><table class="table" summary="Supported Algorithms for crypt()" border="1"><colgroup><col /><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Algorithm</th><th>Max Password Length</th><th>Adaptive?</th><th>Salt Bits</th><th>Output Length</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">bf</code></td><td>72</td><td>yes</td><td>128</td><td>60</td><td>Blowfish-based, variant 2a</td></tr><tr><td><code class="literal">md5</code></td><td>unlimited</td><td>no</td><td>48</td><td>34</td><td>MD5-based crypt</td></tr><tr><td><code class="literal">xdes</code></td><td>8</td><td>yes</td><td>24</td><td>20</td><td>Extended DES</td></tr><tr><td><code class="literal">des</code></td><td>8</td><td>no</td><td>12</td><td>13</td><td>Original UNIX crypt</td></tr></tbody></table></div></div><br class="table-break" /><div class="sect3" id="id-1.11.7.37.8.7"><div class="titlepage"><div><div><h4 class="title">F.28.2.1. <code class="function">crypt()</code></h4></div></div></div><a id="id-1.11.7.37.8.7.2" class="indexterm"></a><pre class="synopsis">
+crypt(password text, salt text) returns text
+</pre><p>
+ Calculates a crypt(3)-style hash of <em class="parameter"><code>password</code></em>.
+ When storing a new password, you need to use
+ <code class="function">gen_salt()</code> to generate a new <em class="parameter"><code>salt</code></em> value.
+ To check a password, pass the stored hash value as <em class="parameter"><code>salt</code></em>,
+ and test whether the result matches the stored value.
+ </p><p>
+ Example of setting a new password:
+</p><pre class="programlisting">
+UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
+</pre><p>
+ </p><p>
+ Example of authentication:
+</p><pre class="programlisting">
+SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;
+</pre><p>
+ This returns <code class="literal">true</code> if the entered password is correct.
+ </p></div><div class="sect3" id="id-1.11.7.37.8.8"><div class="titlepage"><div><div><h4 class="title">F.28.2.2. <code class="function">gen_salt()</code></h4></div></div></div><a id="id-1.11.7.37.8.8.2" class="indexterm"></a><pre class="synopsis">
+gen_salt(type text [, iter_count integer ]) returns text
+</pre><p>
+ Generates a new random salt string for use in <code class="function">crypt()</code>.
+ The salt string also tells <code class="function">crypt()</code> which algorithm to use.
+ </p><p>
+ The <em class="parameter"><code>type</code></em> parameter specifies the hashing algorithm.
+ The accepted types are: <code class="literal">des</code>, <code class="literal">xdes</code>,
+ <code class="literal">md5</code> and <code class="literal">bf</code>.
+ </p><p>
+ The <em class="parameter"><code>iter_count</code></em> parameter lets the user specify the iteration
+ count, for algorithms that have one.
+ The higher the count, the more time it takes to hash
+ the password and therefore the more time to break it. Although with
+ too high a count the time to calculate a hash may be several years
+ — which is somewhat impractical. If the <em class="parameter"><code>iter_count</code></em>
+ parameter is omitted, the default iteration count is used.
+ Allowed values for <em class="parameter"><code>iter_count</code></em> depend on the algorithm and
+ are shown in <a class="xref" href="pgcrypto.html#PGCRYPTO-ICFC-TABLE" title="Table F.17. Iteration Counts for crypt()">Table F.17</a>.
+ </p><div class="table" id="PGCRYPTO-ICFC-TABLE"><p class="title"><strong>Table F.17. Iteration Counts for <code class="function">crypt()</code></strong></p><div class="table-contents"><table class="table" summary="Iteration Counts for crypt()" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Algorithm</th><th>Default</th><th>Min</th><th>Max</th></tr></thead><tbody><tr><td><code class="literal">xdes</code></td><td>725</td><td>1</td><td>16777215</td></tr><tr><td><code class="literal">bf</code></td><td>6</td><td>4</td><td>31</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For <code class="literal">xdes</code> there is an additional limitation that the
+ iteration count must be an odd number.
+ </p><p>
+ To pick an appropriate iteration count, consider that
+ the original DES crypt was designed to have the speed of 4 hashes per
+ second on the hardware of that time.
+ Slower than 4 hashes per second would probably dampen usability.
+ Faster than 100 hashes per second is probably too fast.
+ </p><p>
+ <a class="xref" href="pgcrypto.html#PGCRYPTO-HASH-SPEED-TABLE" title="Table F.18. Hash Algorithm Speeds">Table F.18</a> gives an overview of the relative slowness
+ of different hashing algorithms.
+ The table shows how much time it would take to try all
+ combinations of characters in an 8-character password, assuming
+ that the password contains either only lower case letters, or
+ upper- and lower-case letters and numbers.
+ In the <code class="literal">crypt-bf</code> entries, the number after a slash is
+ the <em class="parameter"><code>iter_count</code></em> parameter of
+ <code class="function">gen_salt</code>.
+ </p><div class="table" id="PGCRYPTO-HASH-SPEED-TABLE"><p class="title"><strong>Table F.18. Hash Algorithm Speeds</strong></p><div class="table-contents"><table class="table" summary="Hash Algorithm Speeds" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th>Algorithm</th><th>Hashes/sec</th><th>For <code class="literal">[a-z]</code></th><th>For <code class="literal">[A-Za-z0-9]</code></th><th>Duration relative to <code class="literal">md5 hash</code></th></tr></thead><tbody><tr><td><code class="literal">crypt-bf/8</code></td><td>1792</td><td>4 years</td><td>3927 years</td><td>100k</td></tr><tr><td><code class="literal">crypt-bf/7</code></td><td>3648</td><td>2 years</td><td>1929 years</td><td>50k</td></tr><tr><td><code class="literal">crypt-bf/6</code></td><td>7168</td><td>1 year</td><td>982 years</td><td>25k</td></tr><tr><td><code class="literal">crypt-bf/5</code></td><td>13504</td><td>188 days</td><td>521 years</td><td>12.5k</td></tr><tr><td><code class="literal">crypt-md5</code></td><td>171584</td><td>15 days</td><td>41 years</td><td>1k</td></tr><tr><td><code class="literal">crypt-des</code></td><td>23221568</td><td>157.5 minutes</td><td>108 days</td><td>7</td></tr><tr><td><code class="literal">sha1</code></td><td>37774272</td><td>90 minutes</td><td>68 days</td><td>4</td></tr><tr><td><code class="literal">md5</code> (hash)</td><td>150085504</td><td>22.5 minutes</td><td>17 days</td><td>1</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Notes:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The machine used is an Intel Mobile Core i3.
+ </p></li><li class="listitem"><p>
+ <code class="literal">crypt-des</code> and <code class="literal">crypt-md5</code> algorithm numbers are
+ taken from John the Ripper v1.6.38 <code class="literal">-test</code> output.
+ </p></li><li class="listitem"><p>
+ <code class="literal">md5 hash</code> numbers are from mdcrack 1.2.
+ </p></li><li class="listitem"><p>
+ <code class="literal">sha1</code> numbers are from lcrack-20031130-beta.
+ </p></li><li class="listitem"><p>
+ <code class="literal">crypt-bf</code> numbers are taken using a simple program that
+ loops over 1000 8-character passwords. That way I can show the speed
+ with different numbers of iterations. For reference: <code class="literal">john
+ -test</code> shows 13506 loops/sec for <code class="literal">crypt-bf/5</code>.
+ (The very small
+ difference in results is in accordance with the fact that the
+ <code class="literal">crypt-bf</code> implementation in <code class="filename">pgcrypto</code>
+ is the same one used in John the Ripper.)
+ </p></li></ul></div><p>
+ Note that <span class="quote">“<span class="quote">try all combinations</span>”</span> is not a realistic exercise.
+ Usually password cracking is done with the help of dictionaries, which
+ contain both regular words and various mutations of them. So, even
+ somewhat word-like passwords could be cracked much faster than the above
+ numbers suggest, while a 6-character non-word-like password may escape
+ cracking. Or not.
+ </p></div></div><div class="sect2" id="id-1.11.7.37.9"><div class="titlepage"><div><div><h3 class="title">F.28.3. PGP Encryption Functions</h3></div></div></div><p>
+ The functions here implement the encryption part of the OpenPGP
+ (<a class="ulink" href="https://tools.ietf.org/html/rfc4880" target="_top">RFC 4880</a>)
+ standard. Supported are both symmetric-key and public-key encryption.
+ </p><p>
+ An encrypted PGP message consists of 2 parts, or <em class="firstterm">packets</em>:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Packet containing a session key — either symmetric-key or public-key
+ encrypted.
+ </p></li><li class="listitem"><p>
+ Packet containing data encrypted with the session key.
+ </p></li></ul></div><p>
+ When encrypting with a symmetric key (i.e., a password):
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ The given password is hashed using a String2Key (S2K) algorithm. This is
+ rather similar to <code class="function">crypt()</code> algorithms — purposefully
+ slow and with random salt — but it produces a full-length binary
+ key.
+ </p></li><li class="listitem"><p>
+ If a separate session key is requested, a new random key will be
+ generated. Otherwise the S2K key will be used directly as the session
+ key.
+ </p></li><li class="listitem"><p>
+ If the S2K key is to be used directly, then only S2K settings will be put
+ into the session key packet. Otherwise the session key will be encrypted
+ with the S2K key and put into the session key packet.
+ </p></li></ol></div><p>
+ When encrypting with a public key:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ A new random session key is generated.
+ </p></li><li class="listitem"><p>
+ It is encrypted using the public key and put into the session key packet.
+ </p></li></ol></div><p>
+ In either case the data to be encrypted is processed as follows:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ Optional data-manipulation: compression, conversion to UTF-8,
+ and/or conversion of line-endings.
+ </p></li><li class="listitem"><p>
+ The data is prefixed with a block of random bytes. This is equivalent
+ to using a random IV.
+ </p></li><li class="listitem"><p>
+ A SHA1 hash of the random prefix and data is appended.
+ </p></li><li class="listitem"><p>
+ All this is encrypted with the session key and placed in the data packet.
+ </p></li></ol></div><div class="sect3" id="id-1.11.7.37.9.11"><div class="titlepage"><div><div><h4 class="title">F.28.3.1. <code class="function">pgp_sym_encrypt()</code></h4></div></div></div><a id="id-1.11.7.37.9.11.2" class="indexterm"></a><a id="id-1.11.7.37.9.11.3" class="indexterm"></a><pre class="synopsis">
+pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
+pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea
+</pre><p>
+ Encrypt <em class="parameter"><code>data</code></em> with a symmetric PGP key <em class="parameter"><code>psw</code></em>.
+ The <em class="parameter"><code>options</code></em> parameter can contain option settings,
+ as described below.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.12"><div class="titlepage"><div><div><h4 class="title">F.28.3.2. <code class="function">pgp_sym_decrypt()</code></h4></div></div></div><a id="id-1.11.7.37.9.12.2" class="indexterm"></a><a id="id-1.11.7.37.9.12.3" class="indexterm"></a><pre class="synopsis">
+pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text
+pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea
+</pre><p>
+ Decrypt a symmetric-key-encrypted PGP message.
+ </p><p>
+ Decrypting <code class="type">bytea</code> data with <code class="function">pgp_sym_decrypt</code> is disallowed.
+ This is to avoid outputting invalid character data. Decrypting
+ originally textual data with <code class="function">pgp_sym_decrypt_bytea</code> is fine.
+ </p><p>
+ The <em class="parameter"><code>options</code></em> parameter can contain option settings,
+ as described below.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.13"><div class="titlepage"><div><div><h4 class="title">F.28.3.3. <code class="function">pgp_pub_encrypt()</code></h4></div></div></div><a id="id-1.11.7.37.9.13.2" class="indexterm"></a><a id="id-1.11.7.37.9.13.3" class="indexterm"></a><pre class="synopsis">
+pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
+pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea
+</pre><p>
+ Encrypt <em class="parameter"><code>data</code></em> with a public PGP key <em class="parameter"><code>key</code></em>.
+ Giving this function a secret key will produce an error.
+ </p><p>
+ The <em class="parameter"><code>options</code></em> parameter can contain option settings,
+ as described below.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.14"><div class="titlepage"><div><div><h4 class="title">F.28.3.4. <code class="function">pgp_pub_decrypt()</code></h4></div></div></div><a id="id-1.11.7.37.9.14.2" class="indexterm"></a><a id="id-1.11.7.37.9.14.3" class="indexterm"></a><pre class="synopsis">
+pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns text
+pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea
+</pre><p>
+ Decrypt a public-key-encrypted message. <em class="parameter"><code>key</code></em> must be the
+ secret key corresponding to the public key that was used to encrypt.
+ If the secret key is password-protected, you must give the password in
+ <em class="parameter"><code>psw</code></em>. If there is no password, but you want to specify
+ options, you need to give an empty password.
+ </p><p>
+ Decrypting <code class="type">bytea</code> data with <code class="function">pgp_pub_decrypt</code> is disallowed.
+ This is to avoid outputting invalid character data. Decrypting
+ originally textual data with <code class="function">pgp_pub_decrypt_bytea</code> is fine.
+ </p><p>
+ The <em class="parameter"><code>options</code></em> parameter can contain option settings,
+ as described below.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.15"><div class="titlepage"><div><div><h4 class="title">F.28.3.5. <code class="function">pgp_key_id()</code></h4></div></div></div><a id="id-1.11.7.37.9.15.2" class="indexterm"></a><pre class="synopsis">
+pgp_key_id(bytea) returns text
+</pre><p>
+ <code class="function">pgp_key_id</code> extracts the key ID of a PGP public or secret key.
+ Or it gives the key ID that was used for encrypting the data, if given
+ an encrypted message.
+ </p><p>
+ It can return 2 special key IDs:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">SYMKEY</code>
+ </p><p>
+ The message is encrypted with a symmetric key.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ANYKEY</code>
+ </p><p>
+ The message is public-key encrypted, but the key ID has been removed.
+ That means you will need to try all your secret keys on it to see
+ which one decrypts it. <code class="filename">pgcrypto</code> itself does not produce
+ such messages.
+ </p></li></ul></div><p>
+ Note that different keys may have the same ID. This is rare but a normal
+ event. The client application should then try to decrypt with each one,
+ to see which fits — like handling <code class="literal">ANYKEY</code>.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.16"><div class="titlepage"><div><div><h4 class="title">F.28.3.6. <code class="function">armor()</code>, <code class="function">dearmor()</code></h4></div></div></div><a id="id-1.11.7.37.9.16.2" class="indexterm"></a><a id="id-1.11.7.37.9.16.3" class="indexterm"></a><pre class="synopsis">
+armor(data bytea [ , keys text[], values text[] ]) returns text
+dearmor(data text) returns bytea
+</pre><p>
+ These functions wrap/unwrap binary data into PGP ASCII-armor format,
+ which is basically Base64 with CRC and additional formatting.
+ </p><p>
+ If the <em class="parameter"><code>keys</code></em> and <em class="parameter"><code>values</code></em> arrays are specified,
+ an <em class="firstterm">armor header</em> is added to the armored format for each
+ key/value pair. Both arrays must be single-dimensional, and they must
+ be of the same length. The keys and values cannot contain any non-ASCII
+ characters.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.17"><div class="titlepage"><div><div><h4 class="title">F.28.3.7. <code class="function">pgp_armor_headers</code></h4></div></div></div><a id="id-1.11.7.37.9.17.2" class="indexterm"></a><pre class="synopsis">
+pgp_armor_headers(data text, key out text, value out text) returns setof record
+</pre><p>
+ <code class="function">pgp_armor_headers()</code> extracts the armor headers from
+ <em class="parameter"><code>data</code></em>. The return value is a set of rows with two columns,
+ key and value. If the keys or values contain any non-ASCII characters,
+ they are treated as UTF-8.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.18"><div class="titlepage"><div><div><h4 class="title">F.28.3.8. Options for PGP Functions</h4></div></div></div><p>
+ Options are named to be similar to GnuPG. An option's value should be
+ given after an equal sign; separate options from each other with commas.
+ For example:
+</p><pre class="programlisting">
+pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')
+</pre><p>
+ </p><p>
+ All of the options except <code class="literal">convert-crlf</code> apply only to
+ encrypt functions. Decrypt functions get the parameters from the PGP
+ data.
+ </p><p>
+ The most interesting options are probably
+ <code class="literal">compress-algo</code> and <code class="literal">unicode-mode</code>.
+ The rest should have reasonable defaults.
+ </p><div class="sect4" id="id-1.11.7.37.9.18.5"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.1. cipher-algo</h5></div></div></div><p>
+ Which cipher algorithm to use.
+ </p><div class="literallayout"><p><br />
+Values: bf, aes128, aes192, aes256, 3des, cast5<br />
+Default: aes128<br />
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.6"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.2. compress-algo</h5></div></div></div><p>
+ Which compression algorithm to use. Only available if
+ <span class="productname">PostgreSQL</span> was built with zlib.
+ </p><div class="literallayout"><p><br />
+Values:<br />
+  0 - no compression<br />
+  1 - ZIP compression<br />
+  2 - ZLIB compression (= ZIP plus meta-data and block CRCs)<br />
+Default: 0<br />
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.7"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.3. compress-level</h5></div></div></div><p>
+ How much to compress. Higher levels compress smaller but are slower.
+ 0 disables compression.
+ </p><div class="literallayout"><p><br />
+Values: 0, 1-9<br />
+Default: 6<br />
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.8"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.4. convert-crlf</h5></div></div></div><p>
+ Whether to convert <code class="literal">\n</code> into <code class="literal">\r\n</code> when
+ encrypting and <code class="literal">\r\n</code> to <code class="literal">\n</code> when
+ decrypting. <acronym class="acronym">RFC</acronym> 4880 specifies that text data should be stored using
+ <code class="literal">\r\n</code> line-feeds. Use this to get fully RFC-compliant
+ behavior.
+ </p><div class="literallayout"><p><br />
+Values: 0, 1<br />
+Default: 0<br />
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt, pgp_sym_decrypt, pgp_pub_decrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.9"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.5. disable-mdc</h5></div></div></div><p>
+ Do not protect data with SHA-1. The only good reason to use this
+ option is to achieve compatibility with ancient PGP products, predating
+ the addition of SHA-1 protected packets to <acronym class="acronym">RFC</acronym> 4880.
+ Recent gnupg.org and pgp.com software supports it fine.
+ </p><div class="literallayout"><p><br />
+Values: 0, 1<br />
+Default: 0<br />
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.10"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.6. sess-key</h5></div></div></div><p>
+ Use separate session key. Public-key encryption always uses a separate
+ session key; this option is for symmetric-key encryption, which by default
+ uses the S2K key directly.
+ </p><div class="literallayout"><p><br />
+Values: 0, 1<br />
+Default: 0<br />
+Applies to: pgp_sym_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.11"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.7. s2k-mode</h5></div></div></div><p>
+ Which S2K algorithm to use.
+ </p><div class="literallayout"><p><br />
+Values:<br />
+  0 - Without salt.  Dangerous!<br />
+  1 - With salt but with fixed iteration count.<br />
+  3 - Variable iteration count.<br />
+Default: 3<br />
+Applies to: pgp_sym_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.12"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.8. s2k-count</h5></div></div></div><p>
+ The number of iterations of the S2K algorithm to use. It must
+ be a value between 1024 and 65011712, inclusive.
+ </p><div class="literallayout"><p><br />
+Default: A random value between 65536 and 253952<br />
+Applies to: pgp_sym_encrypt, only with s2k-mode=3<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.13"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.9. s2k-digest-algo</h5></div></div></div><p>
+ Which digest algorithm to use in S2K calculation.
+ </p><div class="literallayout"><p><br />
+Values: md5, sha1<br />
+Default: sha1<br />
+Applies to: pgp_sym_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.14"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.10. s2k-cipher-algo</h5></div></div></div><p>
+ Which cipher to use for encrypting separate session key.
+ </p><div class="literallayout"><p><br />
+Values: bf, aes, aes128, aes192, aes256<br />
+Default: use cipher-algo<br />
+Applies to: pgp_sym_encrypt<br />
+</p></div></div><div class="sect4" id="id-1.11.7.37.9.18.15"><div class="titlepage"><div><div><h5 class="title">F.28.3.8.11. unicode-mode</h5></div></div></div><p>
+ Whether to convert textual data from database internal encoding to
+ UTF-8 and back. If your database already is UTF-8, no conversion will
+ be done, but the message will be tagged as UTF-8. Without this option
+ it will not be.
+ </p><div class="literallayout"><p><br />
+Values: 0, 1<br />
+Default: 0<br />
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt<br />
+</p></div></div></div><div class="sect3" id="id-1.11.7.37.9.19"><div class="titlepage"><div><div><h4 class="title">F.28.3.9. Generating PGP Keys with GnuPG</h4></div></div></div><p>
+ To generate a new key:
+</p><pre class="programlisting">
+gpg --gen-key
+</pre><p>
+ </p><p>
+ The preferred key type is <span class="quote">“<span class="quote">DSA and Elgamal</span>”</span>.
+ </p><p>
+ For RSA encryption you must create either DSA or RSA sign-only key
+ as master and then add an RSA encryption subkey with
+ <code class="literal">gpg --edit-key</code>.
+ </p><p>
+ To list keys:
+</p><pre class="programlisting">
+gpg --list-secret-keys
+</pre><p>
+ </p><p>
+ To export a public key in ASCII-armor format:
+</p><pre class="programlisting">
+gpg -a --export KEYID &gt; public.key
+</pre><p>
+ </p><p>
+ To export a secret key in ASCII-armor format:
+</p><pre class="programlisting">
+gpg -a --export-secret-keys KEYID &gt; secret.key
+</pre><p>
+ </p><p>
+ You need to use <code class="function">dearmor()</code> on these keys before giving them to
+ the PGP functions. Or if you can handle binary data, you can drop
+ <code class="literal">-a</code> from the command.
+ </p><p>
+ For more details see <code class="literal">man gpg</code>,
+ <a class="ulink" href="https://www.gnupg.org/gph/en/manual.html" target="_top">The GNU
+ Privacy Handbook</a> and other documentation on
+ <a class="ulink" href="https://www.gnupg.org/" target="_top">https://www.gnupg.org/</a>.
+ </p></div><div class="sect3" id="id-1.11.7.37.9.20"><div class="titlepage"><div><div><h4 class="title">F.28.3.10. Limitations of PGP Code</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ No support for signing. That also means that it is not checked
+ whether the encryption subkey belongs to the master key.
+ </p></li><li class="listitem"><p>
+ No support for encryption key as master key. As such practice
+ is generally discouraged, this should not be a problem.
+ </p></li><li class="listitem"><p>
+ No support for several subkeys. This may seem like a problem, as this
+ is common practice. On the other hand, you should not use your regular
+ GPG/PGP keys with <code class="filename">pgcrypto</code>, but create new ones,
+ as the usage scenario is rather different.
+ </p></li></ul></div></div></div><div class="sect2" id="id-1.11.7.37.10"><div class="titlepage"><div><div><h3 class="title">F.28.4. Raw Encryption Functions</h3></div></div></div><p>
+ These functions only run a cipher over data; they don't have any advanced
+ features of PGP encryption. Therefore they have some major problems:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ They use user key directly as cipher key.
+ </p></li><li class="listitem"><p>
+ They don't provide any integrity checking, to see
+ if the encrypted data was modified.
+ </p></li><li class="listitem"><p>
+ They expect that users manage all encryption parameters
+ themselves, even IV.
+ </p></li><li class="listitem"><p>
+ They don't handle text.
+ </p></li></ol></div><p>
+ So, with the introduction of PGP encryption, usage of raw
+ encryption functions is discouraged.
+ </p><a id="id-1.11.7.37.10.5" class="indexterm"></a><a id="id-1.11.7.37.10.6" class="indexterm"></a><a id="id-1.11.7.37.10.7" class="indexterm"></a><a id="id-1.11.7.37.10.8" class="indexterm"></a><pre class="synopsis">
+encrypt(data bytea, key bytea, type text) returns bytea
+decrypt(data bytea, key bytea, type text) returns bytea
+
+encrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
+decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
+</pre><p>
+ Encrypt/decrypt data using the cipher method specified by
+ <em class="parameter"><code>type</code></em>. The syntax of the
+ <em class="parameter"><code>type</code></em> string is:
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>algorithm</code></em> [<span class="optional"> <code class="literal">-</code> <em class="replaceable"><code>mode</code></em> </span>] [<span class="optional"> <code class="literal">/pad:</code> <em class="replaceable"><code>padding</code></em> </span>]
+</pre><p>
+ where <em class="replaceable"><code>algorithm</code></em> is one of:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">bf</code> — Blowfish</p></li><li class="listitem"><p><code class="literal">aes</code> — AES (Rijndael-128, -192 or -256)</p></li></ul></div><p>
+ and <em class="replaceable"><code>mode</code></em> is one of:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">cbc</code> — next block depends on previous (default)
+ </p></li><li class="listitem"><p>
+ <code class="literal">ecb</code> — each block is encrypted separately (for
+ testing only)
+ </p></li></ul></div><p>
+ and <em class="replaceable"><code>padding</code></em> is one of:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">pkcs</code> — data may be any length (default)
+ </p></li><li class="listitem"><p>
+ <code class="literal">none</code> — data must be multiple of cipher block size
+ </p></li></ul></div><p>
+ </p><p>
+ So, for example, these are equivalent:
+</p><pre class="programlisting">
+encrypt(data, 'fooz', 'bf')
+encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')
+</pre><p>
+ </p><p>
+ In <code class="function">encrypt_iv</code> and <code class="function">decrypt_iv</code>, the
+ <em class="parameter"><code>iv</code></em> parameter is the initial value for the CBC mode;
+ it is ignored for ECB.
+ It is clipped or padded with zeroes if not exactly block size.
+ It defaults to all zeroes in the functions without this parameter.
+ </p></div><div class="sect2" id="id-1.11.7.37.11"><div class="titlepage"><div><div><h3 class="title">F.28.5. Random-Data Functions</h3></div></div></div><a id="id-1.11.7.37.11.2" class="indexterm"></a><pre class="synopsis">
+gen_random_bytes(count integer) returns bytea
+</pre><p>
+ Returns <em class="parameter"><code>count</code></em> cryptographically strong random bytes.
+ At most 1024 bytes can be extracted at a time. This is to avoid
+ draining the randomness generator pool.
+ </p><a id="id-1.11.7.37.11.5" class="indexterm"></a><pre class="synopsis">
+gen_random_uuid() returns uuid
+</pre><p>
+ Returns a version 4 (random) UUID. (Obsolete, this function
+ internally calls the <a class="link" href="functions-uuid.html" title="9.14. UUID Functions">core
+ function</a> of the same name.)
+ </p></div><div class="sect2" id="id-1.11.7.37.12"><div class="titlepage"><div><div><h3 class="title">F.28.6. Notes</h3></div></div></div><div class="sect3" id="id-1.11.7.37.12.2"><div class="titlepage"><div><div><h4 class="title">F.28.6.1. Configuration</h4></div></div></div><p>
+ <code class="filename">pgcrypto</code> configures itself according to the findings of the
+ main PostgreSQL <code class="literal">configure</code> script. The options that
+ affect it are <code class="literal">--with-zlib</code> and
+ <code class="literal">--with-ssl=openssl</code>.
+ </p><p>
+ When compiled with zlib, PGP encryption functions are able to
+ compress data before encrypting.
+ </p><p>
+ <code class="filename">pgcrypto</code> requires <span class="productname">OpenSSL</span>.
+ Otherwise, it will not be built or installed.
+ </p><p>
+ When compiled against <span class="productname">OpenSSL</span> 3.0.0 and later
+ versions, the legacy provider must be activated in the
+ <code class="filename">openssl.cnf</code> configuration file in order to use older
+ ciphers like DES or Blowfish.
+ </p></div><div class="sect3" id="id-1.11.7.37.12.3"><div class="titlepage"><div><div><h4 class="title">F.28.6.2. NULL Handling</h4></div></div></div><p>
+ As is standard in SQL, all functions return NULL, if any of the arguments
+ are NULL. This may create security risks on careless usage.
+ </p></div><div class="sect3" id="id-1.11.7.37.12.4"><div class="titlepage"><div><div><h4 class="title">F.28.6.3. Security Limitations</h4></div></div></div><p>
+ All <code class="filename">pgcrypto</code> functions run inside the database server.
+ That means that all
+ the data and passwords move between <code class="filename">pgcrypto</code> and client
+ applications in clear text. Thus you must:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>Connect locally or use SSL connections.</p></li><li class="listitem"><p>Trust both system and database administrator.</p></li></ol></div><p>
+ If you cannot, then better do crypto inside client application.
+ </p><p>
+ The implementation does not resist
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Side-channel_attack" target="_top">side-channel
+ attacks</a>. For example, the time required for
+ a <code class="filename">pgcrypto</code> decryption function to complete varies among
+ ciphertexts of a given size.
+ </p></div><div class="sect3" id="id-1.11.7.37.12.5"><div class="titlepage"><div><div><h4 class="title">F.28.6.4. Useful Reading</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="ulink" href="https://www.gnupg.org/gph/en/manual.html" target="_top">https://www.gnupg.org/gph/en/manual.html</a></p><p>The GNU Privacy Handbook.</p></li><li class="listitem"><p><a class="ulink" href="https://www.openwall.com/crypt/" target="_top">https://www.openwall.com/crypt/</a></p><p>Describes the crypt-blowfish algorithm.</p></li><li class="listitem"><p>
+ <a class="ulink" href="https://www.iusmentis.com/security/passphrasefaq/" target="_top">https://www.iusmentis.com/security/passphrasefaq/</a>
+ </p><p>How to choose a good password.</p></li><li class="listitem"><p><a class="ulink" href="http://world.std.com/~reinhold/diceware.html" target="_top">http://world.std.com/~reinhold/diceware.html</a></p><p>Interesting idea for picking passwords.</p></li><li class="listitem"><p>
+ <a class="ulink" href="http://www.interhack.net/people/cmcurtin/snake-oil-faq.html" target="_top">http://www.interhack.net/people/cmcurtin/snake-oil-faq.html</a>
+ </p><p>Describes good and bad cryptography.</p></li></ul></div></div><div class="sect3" id="id-1.11.7.37.12.6"><div class="titlepage"><div><div><h4 class="title">F.28.6.5. Technical References</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="ulink" href="https://tools.ietf.org/html/rfc4880" target="_top">https://tools.ietf.org/html/rfc4880</a></p><p>OpenPGP message format.</p></li><li class="listitem"><p><a class="ulink" href="https://tools.ietf.org/html/rfc1321" target="_top">https://tools.ietf.org/html/rfc1321</a></p><p>The MD5 Message-Digest Algorithm.</p></li><li class="listitem"><p><a class="ulink" href="https://tools.ietf.org/html/rfc2104" target="_top">https://tools.ietf.org/html/rfc2104</a></p><p>HMAC: Keyed-Hashing for Message Authentication.</p></li><li class="listitem"><p>
+ <a class="ulink" href="https://www.usenix.org/legacy/events/usenix99/provos.html" target="_top">https://www.usenix.org/legacy/events/usenix99/provos.html</a>
+ </p><p>Comparison of crypt-des, crypt-md5 and bcrypt algorithms.</p></li><li class="listitem"><p>
+ <a class="ulink" href="https://en.wikipedia.org/wiki/Fortuna_(PRNG)" target="_top">https://en.wikipedia.org/wiki/Fortuna_(PRNG)</a>
+ </p><p>Description of Fortuna CSPRNG.</p></li><li class="listitem"><p><a class="ulink" href="https://jlcooke.ca/random/" target="_top">https://jlcooke.ca/random/</a></p><p>Jean-Luc Cooke Fortuna-based <code class="filename">/dev/random</code> driver for Linux.</p></li></ul></div></div></div><div class="sect2" id="id-1.11.7.37.13"><div class="titlepage"><div><div><h3 class="title">F.28.7. Author</h3></div></div></div><p>
+ Marko Kreen <code class="email">&lt;<a class="email" href="mailto:markokr@gmail.com">markokr@gmail.com</a>&gt;</code>
+ </p><p>
+ <code class="filename">pgcrypto</code> uses code from the following sources:
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Algorithm</th><th>Author</th><th>Source origin</th></tr></thead><tbody><tr><td>DES crypt</td><td>David Burren and others</td><td>FreeBSD libcrypt</td></tr><tr><td>MD5 crypt</td><td>Poul-Henning Kamp</td><td>FreeBSD libcrypt</td></tr><tr><td>Blowfish crypt</td><td>Solar Designer</td><td>www.openwall.com</td></tr></tbody></table></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgbuffercache.html" title="F.27. pg_buffercache">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgfreespacemap.html" title="F.29. pg_freespacemap">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.27. pg_buffercache </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.29. pg_freespacemap</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgfreespacemap.html b/doc/src/sgml/html/pgfreespacemap.html
new file mode 100644
index 0000000..178125b
--- /dev/null
+++ b/doc/src/sgml/html/pgfreespacemap.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.29. pg_freespacemap</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgcrypto.html" title="F.28. pgcrypto" /><link rel="next" href="pgprewarm.html" title="F.30. pg_prewarm" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.29. pg_freespacemap</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgcrypto.html" title="F.28. pgcrypto">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgprewarm.html" title="F.30. pg_prewarm">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGFREESPACEMAP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.29. pg_freespacemap</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgfreespacemap.html#id-1.11.7.38.5">F.29.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgfreespacemap.html#id-1.11.7.38.6">F.29.2. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgfreespacemap.html#id-1.11.7.38.7">F.29.3. Author</a></span></dt></dl></div><a id="id-1.11.7.38.2" class="indexterm"></a><p>
+ The <code class="filename">pg_freespacemap</code> module provides a means for examining the
+ <a class="link" href="storage-fsm.html" title="73.3. Free Space Map">free space map</a> (<acronym class="acronym">FSM</acronym>).
+ It provides a function called <code class="function">pg_freespace</code>, or two
+ overloaded functions, to be precise. The functions show the value recorded in
+ the free space map for a given page, or for all pages in the relation.
+ </p><p>
+ By default use is restricted to superusers and roles with privileges of the
+ <code class="literal">pg_stat_scan_tables</code> role. Access may be granted to others
+ using <code class="command">GRANT</code>.
+ </p><div class="sect2" id="id-1.11.7.38.5"><div class="titlepage"><div><div><h3 class="title">F.29.1. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">pg_freespace(rel regclass IN, blkno bigint IN) returns int2</code>
+ <a id="id-1.11.7.38.5.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns the amount of free space on the page of the relation, specified
+ by <code class="literal">blkno</code>, according to the <acronym class="acronym">FSM</acronym>.
+ </p></dd><dt><span class="term">
+ <code class="function">pg_freespace(rel regclass IN, blkno OUT bigint, avail OUT int2)</code>
+ </span></dt><dd><p>
+ Displays the amount of free space on each page of the relation,
+ according to the <acronym class="acronym">FSM</acronym>. A set of
+ <code class="literal">(blkno bigint, avail int2)</code>
+ tuples is returned, one tuple for each page in the relation.
+ </p></dd></dl></div><p>
+ The values stored in the free space map are not exact. They're rounded
+ to precision of 1/256th of <code class="symbol">BLCKSZ</code> (32 bytes with default <code class="symbol">BLCKSZ</code>), and
+ they're not kept fully up-to-date as tuples are inserted and updated.
+ </p><p>
+ For indexes, what is tracked is entirely-unused pages, rather than free
+ space within pages. Therefore, the values are not meaningful, just
+ whether a page is full or empty.
+ </p></div><div class="sect2" id="id-1.11.7.38.6"><div class="titlepage"><div><div><h3 class="title">F.29.2. Sample Output</h3></div></div></div><pre class="screen">
+postgres=# SELECT * FROM pg_freespace('foo');
+ blkno | avail
+-------+-------
+ 0 | 0
+ 1 | 0
+ 2 | 0
+ 3 | 32
+ 4 | 704
+ 5 | 704
+ 6 | 704
+ 7 | 1216
+ 8 | 704
+ 9 | 704
+ 10 | 704
+ 11 | 704
+ 12 | 704
+ 13 | 704
+ 14 | 704
+ 15 | 704
+ 16 | 704
+ 17 | 704
+ 18 | 704
+ 19 | 3648
+(20 rows)
+
+postgres=# SELECT * FROM pg_freespace('foo', 7);
+ pg_freespace
+--------------
+ 1216
+(1 row)
+</pre></div><div class="sect2" id="id-1.11.7.38.7"><div class="titlepage"><div><div><h3 class="title">F.29.3. Author</h3></div></div></div><p>
+ Original version by Mark Kirkwood <code class="email">&lt;<a class="email" href="mailto:markir@paradise.net.nz">markir@paradise.net.nz</a>&gt;</code>.
+ Rewritten in version 8.4 to suit new <acronym class="acronym">FSM</acronym> implementation
+ by Heikki Linnakangas <code class="email">&lt;<a class="email" href="mailto:heikki@enterprisedb.com">heikki@enterprisedb.com</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgcrypto.html" title="F.28. pgcrypto">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgprewarm.html" title="F.30. pg_prewarm">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.28. pgcrypto </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.30. pg_prewarm</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgprewarm.html b/doc/src/sgml/html/pgprewarm.html
new file mode 100644
index 0000000..a38b35f
--- /dev/null
+++ b/doc/src/sgml/html/pgprewarm.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.30. pg_prewarm</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgfreespacemap.html" title="F.29. pg_freespacemap" /><link rel="next" href="pgrowlocks.html" title="F.31. pgrowlocks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.30. pg_prewarm</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgfreespacemap.html" title="F.29. pg_freespacemap">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgrowlocks.html" title="F.31. pgrowlocks">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGPREWARM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.30. pg_prewarm</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgprewarm.html#id-1.11.7.39.4">F.30.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgprewarm.html#id-1.11.7.39.5">F.30.2. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="pgprewarm.html#id-1.11.7.39.6">F.30.3. Author</a></span></dt></dl></div><a id="id-1.11.7.39.2" class="indexterm"></a><p>
+ The <code class="filename">pg_prewarm</code> module provides a convenient way
+ to load relation data into either the operating system buffer cache
+ or the <span class="productname">PostgreSQL</span> buffer cache. Prewarming
+ can be performed manually using the <code class="filename">pg_prewarm</code> function,
+ or can be performed automatically by including <code class="literal">pg_prewarm</code> in
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a>. In the latter case, the
+ system will run a background worker which periodically records the contents
+ of shared buffers in a file called <code class="filename">autoprewarm.blocks</code> and
+ will, using 2 background workers, reload those same blocks after a restart.
+ </p><div class="sect2" id="id-1.11.7.39.4"><div class="titlepage"><div><div><h3 class="title">F.30.1. Functions</h3></div></div></div><pre class="synopsis">
+pg_prewarm(regclass, mode text default 'buffer', fork text default 'main',
+ first_block int8 default null,
+ last_block int8 default null) RETURNS int8
+</pre><p>
+ The first argument is the relation to be prewarmed. The second argument
+ is the prewarming method to be used, as further discussed below; the third
+ is the relation fork to be prewarmed, usually <code class="literal">main</code>.
+ The fourth argument is the first block number to prewarm
+ (<code class="literal">NULL</code> is accepted as a synonym for zero). The fifth
+ argument is the last block number to prewarm (<code class="literal">NULL</code>
+ means prewarm through the last block in the relation). The return value
+ is the number of blocks prewarmed.
+ </p><p>
+ There are three available prewarming methods. <code class="literal">prefetch</code>
+ issues asynchronous prefetch requests to the operating system, if this is
+ supported, or throws an error otherwise. <code class="literal">read</code> reads
+ the requested range of blocks; unlike <code class="literal">prefetch</code>, this is
+ synchronous and supported on all platforms and builds, but may be slower.
+ <code class="literal">buffer</code> reads the requested range of blocks into the
+ database buffer cache.
+ </p><p>
+ Note that with any of these methods, attempting to prewarm more blocks than
+ can be cached — by the OS when using <code class="literal">prefetch</code> or
+ <code class="literal">read</code>, or by <span class="productname">PostgreSQL</span> when
+ using <code class="literal">buffer</code> — will likely result in lower-numbered
+ blocks being evicted as higher numbered blocks are read in. Prewarmed data
+ also enjoys no special protection from cache evictions, so it is possible
+ that other system activity may evict the newly prewarmed blocks shortly
+ after they are read; conversely, prewarming may also evict other data from
+ cache. For these reasons, prewarming is typically most useful at startup,
+ when caches are largely empty.
+ </p><pre class="synopsis">
+autoprewarm_start_worker() RETURNS void
+</pre><p>
+ Launch the main autoprewarm worker. This will normally happen
+ automatically, but is useful if automatic prewarm was not configured at
+ server startup time and you wish to start up the worker at a later time.
+ </p><pre class="synopsis">
+autoprewarm_dump_now() RETURNS int8
+</pre><p>
+ Update <code class="filename">autoprewarm.blocks</code> immediately. This may be useful
+ if the autoprewarm worker is not running but you anticipate running it
+ after the next restart. The return value is the number of records written
+ to <code class="filename">autoprewarm.blocks</code>.
+ </p></div><div class="sect2" id="id-1.11.7.39.5"><div class="titlepage"><div><div><h3 class="title">F.30.2. Configuration Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">pg_prewarm.autoprewarm</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.39.5.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls whether the server should run the autoprewarm worker. This is
+ on by default. This parameter can only be set at server start.
+ </p></dd></dl></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">pg_prewarm.autoprewarm_interval</code> (<code class="type">integer</code>)
+ <a id="id-1.11.7.39.5.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This is the interval between updates to <code class="literal">autoprewarm.blocks</code>.
+ The default is 300 seconds. If set to 0, the file will not be
+ dumped at regular intervals, but only when the server is shut down.
+ </p></dd></dl></div><p>
+ These parameters must be set in <code class="filename">postgresql.conf</code>.
+ Typical usage might be:
+ </p><pre class="programlisting">
+# postgresql.conf
+shared_preload_libraries = 'pg_prewarm'
+
+pg_prewarm.autoprewarm = true
+pg_prewarm.autoprewarm_interval = 300s
+
+</pre></div><div class="sect2" id="id-1.11.7.39.6"><div class="titlepage"><div><div><h3 class="title">F.30.3. Author</h3></div></div></div><p>
+ Robert Haas <code class="email">&lt;<a class="email" href="mailto:rhaas@postgresql.org">rhaas@postgresql.org</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgfreespacemap.html" title="F.29. pg_freespacemap">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgrowlocks.html" title="F.31. pgrowlocks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.29. pg_freespacemap </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.31. pgrowlocks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgrowlocks.html b/doc/src/sgml/html/pgrowlocks.html
new file mode 100644
index 0000000..cd5ea35
--- /dev/null
+++ b/doc/src/sgml/html/pgrowlocks.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.31. pgrowlocks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgprewarm.html" title="F.30. pg_prewarm" /><link rel="next" href="pgstatstatements.html" title="F.32. pg_stat_statements" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.31. pgrowlocks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgprewarm.html" title="F.30. pg_prewarm">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgstatstatements.html" title="F.32. pg_stat_statements">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGROWLOCKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.31. pgrowlocks</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgrowlocks.html#id-1.11.7.40.5">F.31.1. Overview</a></span></dt><dt><span class="sect2"><a href="pgrowlocks.html#id-1.11.7.40.6">F.31.2. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgrowlocks.html#id-1.11.7.40.7">F.31.3. Author</a></span></dt></dl></div><a id="id-1.11.7.40.2" class="indexterm"></a><p>
+ The <code class="filename">pgrowlocks</code> module provides a function to show row
+ locking information for a specified table.
+ </p><p>
+ By default use is restricted to superusers, roles with privileges of the
+ <code class="literal">pg_stat_scan_tables</code> role, and users with
+ <code class="literal">SELECT</code> permissions on the table.
+ </p><div class="sect2" id="id-1.11.7.40.5"><div class="titlepage"><div><div><h3 class="title">F.31.1. Overview</h3></div></div></div><a id="id-1.11.7.40.5.2" class="indexterm"></a><pre class="synopsis">
+pgrowlocks(text) returns setof record
+</pre><p>
+ The parameter is the name of a table. The result is a set of records,
+ with one row for each locked row within the table. The output columns
+ are shown in <a class="xref" href="pgrowlocks.html#PGROWLOCKS-COLUMNS" title="Table F.19. pgrowlocks Output Columns">Table F.19</a>.
+ </p><div class="table" id="PGROWLOCKS-COLUMNS"><p class="title"><strong>Table F.19. <code class="function">pgrowlocks</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pgrowlocks Output Columns" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">locked_row</code></td><td><code class="type">tid</code></td><td>Tuple ID (TID) of locked row</td></tr><tr><td><code class="structfield">locker</code></td><td><code class="type">xid</code></td><td>Transaction ID of locker, or multixact ID if multitransaction</td></tr><tr><td><code class="structfield">multi</code></td><td><code class="type">boolean</code></td><td>True if locker is a multitransaction</td></tr><tr><td><code class="structfield">xids</code></td><td><code class="type">xid[]</code></td><td>Transaction IDs of lockers (more than one if multitransaction)</td></tr><tr><td><code class="structfield">modes</code></td><td><code class="type">text[]</code></td><td>Lock mode of lockers (more than one if multitransaction),
+ an array of <code class="literal">Key Share</code>, <code class="literal">Share</code>,
+ <code class="literal">For No Key Update</code>, <code class="literal">No Key Update</code>,
+ <code class="literal">For Update</code>, <code class="literal">Update</code>.</td></tr><tr><td><code class="structfield">pids</code></td><td><code class="type">integer[]</code></td><td>Process IDs of locking backends (more than one if multitransaction)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="function">pgrowlocks</code> takes <code class="literal">AccessShareLock</code> for the
+ target table and reads each row one by one to collect the row locking
+ information. This is not very speedy for a large table. Note that:
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ If an <code class="literal">ACCESS EXCLUSIVE</code> lock is taken on the table,
+ <code class="function">pgrowlocks</code> will be blocked.
+ </p></li><li class="listitem"><p>
+ <code class="function">pgrowlocks</code> is not guaranteed to produce a
+ self-consistent snapshot. It is possible that a new row lock is taken,
+ or an old lock is freed, during its execution.
+ </p></li></ol></div><p>
+ <code class="function">pgrowlocks</code> does not show the contents of locked
+ rows. If you want to take a look at the row contents at the same time, you
+ could do something like this:
+
+</p><pre class="programlisting">
+SELECT * FROM accounts AS a, pgrowlocks('accounts') AS p
+ WHERE p.locked_row = a.ctid;
+</pre><p>
+
+ Be aware however that such a query will be very inefficient.
+ </p></div><div class="sect2" id="id-1.11.7.40.6"><div class="titlepage"><div><div><h3 class="title">F.31.2. Sample Output</h3></div></div></div><pre class="screen">
+=# SELECT * FROM pgrowlocks('t1');
+ locked_row | locker | multi | xids | modes | pids
+------------+--------+-------+-------+----------------+--------
+ (0,1) | 609 | f | {609} | {"For Share"} | {3161}
+ (0,2) | 609 | f | {609} | {"For Share"} | {3161}
+ (0,3) | 607 | f | {607} | {"For Update"} | {3107}
+ (0,4) | 607 | f | {607} | {"For Update"} | {3107}
+(4 rows)
+</pre></div><div class="sect2" id="id-1.11.7.40.7"><div class="titlepage"><div><div><h3 class="title">F.31.3. Author</h3></div></div></div><p>
+ Tatsuo Ishii
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgprewarm.html" title="F.30. pg_prewarm">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgstatstatements.html" title="F.32. pg_stat_statements">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.30. pg_prewarm </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.32. pg_stat_statements</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgstatstatements.html b/doc/src/sgml/html/pgstatstatements.html
new file mode 100644
index 0000000..dfeb9af
--- /dev/null
+++ b/doc/src/sgml/html/pgstatstatements.html
@@ -0,0 +1,613 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.32. pg_stat_statements</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgrowlocks.html" title="F.31. pgrowlocks" /><link rel="next" href="pgstattuple.html" title="F.33. pgstattuple" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.32. pg_stat_statements</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgrowlocks.html" title="F.31. pgrowlocks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgstattuple.html" title="F.33. pgstattuple">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGSTATSTATEMENTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.32. pg_stat_statements</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.6">F.32.1. The <code class="structname">pg_stat_statements</code> View</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.7">F.32.2. The <code class="structname">pg_stat_statements_info</code> View</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.8">F.32.3. Functions</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.9">F.32.4. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.10">F.32.5. Sample Output</a></span></dt><dt><span class="sect2"><a href="pgstatstatements.html#id-1.11.7.41.11">F.32.6. Authors</a></span></dt></dl></div><a id="id-1.11.7.41.2" class="indexterm"></a><p>
+ The <code class="filename">pg_stat_statements</code> module provides a means for
+ tracking planning and execution statistics of all SQL statements executed by
+ a server.
+ </p><p>
+ The module must be loaded by adding <code class="literal">pg_stat_statements</code> to
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> in
+ <code class="filename">postgresql.conf</code>, because it requires additional shared memory.
+ This means that a server restart is needed to add or remove the module.
+ In addition, query identifier calculation must be enabled in order for the
+ module to be active, which is done automatically if <a class="xref" href="runtime-config-statistics.html#GUC-COMPUTE-QUERY-ID">compute_query_id</a>
+ is set to <code class="literal">auto</code> or <code class="literal">on</code>, or any third-party
+ module that calculates query identifiers is loaded.
+ </p><p>
+ When <code class="filename">pg_stat_statements</code> is active, it tracks
+ statistics across all databases of the server. To access and manipulate
+ these statistics, the module provides views
+ <code class="structname">pg_stat_statements</code> and
+ <code class="structname">pg_stat_statements_info</code>,
+ and the utility functions <code class="function">pg_stat_statements_reset</code> and
+ <code class="function">pg_stat_statements</code>. These are not available globally but
+ can be enabled for a specific database with
+ <code class="command">CREATE EXTENSION pg_stat_statements</code>.
+ </p><div class="sect2" id="id-1.11.7.41.6"><div class="titlepage"><div><div><h3 class="title">F.32.1. The <code class="structname">pg_stat_statements</code> View</h3></div></div></div><p>
+ The statistics gathered by the module are made available via a
+ view named <code class="structname">pg_stat_statements</code>. This view
+ contains one row for each distinct combination of database ID, user
+ ID, query ID and whether it's a top-level statement or not (up to
+ the maximum number of distinct statements that the module can track).
+ The columns of the view are shown in
+ <a class="xref" href="pgstatstatements.html#PGSTATSTATEMENTS-COLUMNS" title="Table F.20. pg_stat_statements Columns">Table F.20</a>.
+ </p><div class="table" id="PGSTATSTATEMENTS-COLUMNS"><p class="title"><strong>Table F.20. <code class="structname">pg_stat_statements</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_stat_statements Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">userid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of user who executed the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dbid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of database in which the statement was executed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">toplevel</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the query was executed as a top-level statement
+ (always true if <code class="varname">pg_stat_statements.track</code> is set to
+ <code class="literal">top</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">queryid</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Hash code to identify identical normalized queries.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">query</code> <code class="type">text</code>
+ </p>
+ <p>
+ Text of a representative statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">plans</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times the statement was planned
+ (if <code class="varname">pg_stat_statements.track_planning</code> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_plan_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent planning the statement, in milliseconds
+ (if <code class="varname">pg_stat_statements.track_planning</code> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">min_plan_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Minimum time spent planning the statement, in milliseconds
+ (if <code class="varname">pg_stat_statements.track_planning</code> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">max_plan_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Maximum time spent planning the statement, in milliseconds
+ (if <code class="varname">pg_stat_statements.track_planning</code> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">mean_plan_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Mean time spent planning the statement, in milliseconds
+ (if <code class="varname">pg_stat_statements.track_planning</code> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stddev_plan_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Population standard deviation of time spent planning the statement,
+ in milliseconds
+ (if <code class="varname">pg_stat_statements.track_planning</code> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">calls</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times the statement was executed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_exec_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent executing the statement, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">min_exec_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Minimum time spent executing the statement, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">max_exec_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Maximum time spent executing the statement, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">mean_exec_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Mean time spent executing the statement, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stddev_exec_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Population standard deviation of time spent executing the statement, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rows</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of rows retrieved or affected by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">shared_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of shared block cache hits by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">shared_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of shared blocks read by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">shared_blks_dirtied</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of shared blocks dirtied by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">shared_blks_written</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of shared blocks written by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">local_blks_hit</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of local block cache hits by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">local_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of local blocks read by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">local_blks_dirtied</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of local blocks dirtied by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">local_blks_written</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of local blocks written by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temp_blks_read</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of temp blocks read by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temp_blks_written</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of temp blocks written by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blk_read_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time the statement spent reading data file blocks, in milliseconds
+ (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled, otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blk_write_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time the statement spent writing data file blocks, in milliseconds
+ (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled, otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temp_blk_read_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time the statement spent reading temporary file blocks, in
+ milliseconds (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temp_blk_write_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time the statement spent writing temporary file blocks, in
+ milliseconds (if <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled,
+ otherwise zero)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_records</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of WAL records generated by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_fpi</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of WAL full page images generated by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_bytes</code> <code class="type">numeric</code>
+ </p>
+ <p>
+ Total amount of WAL generated by the statement in bytes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_functions</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of functions JIT-compiled by the statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_generation_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent by the statement on generating JIT code, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_inlining_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times functions have been inlined
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_inlining_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent by the statement on inlining functions, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_optimization_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times the statement has been optimized
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_optimization_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent by the statement on optimizing, in milliseconds
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_emission_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of times code has been emitted
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">jit_emission_time</code> <code class="type">double precision</code>
+ </p>
+ <p>
+ Total time spent by the statement on emitting code, in milliseconds
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ For security reasons, only superusers and roles with privileges of the
+ <code class="literal">pg_read_all_stats</code> role are allowed to see the SQL text and
+ <code class="structfield">queryid</code> of queries executed by other users.
+ Other users can see the statistics, however, if the view has been installed
+ in their database.
+ </p><p>
+ Plannable queries (that is, <code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, and <code class="command">MERGE</code>) are combined into a single
+ <code class="structname">pg_stat_statements</code> entry whenever they have identical query
+ structures according to an internal hash calculation. Typically, two
+ queries will be considered the same for this purpose if they are
+ semantically equivalent except for the values of literal constants
+ appearing in the query. Utility commands (that is, all other commands)
+ are compared strictly on the basis of their textual query strings, however.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The following details about constant replacement and
+ <code class="structfield">queryid</code> only apply when <a class="xref" href="runtime-config-statistics.html#GUC-COMPUTE-QUERY-ID">compute_query_id</a> is enabled. If you use an external
+ module instead to compute <code class="structfield">queryid</code>, you
+ should refer to its documentation for details.
+ </p></div><p>
+ When a constant's value has been ignored for purposes of matching the query
+ to other queries, the constant is replaced by a parameter symbol, such
+ as <code class="literal">$1</code>, in the <code class="structname">pg_stat_statements</code>
+ display.
+ The rest of the query text is that of the first query that had the
+ particular <code class="structfield">queryid</code> hash value associated with the
+ <code class="structname">pg_stat_statements</code> entry.
+ </p><p>
+ In some cases, queries with visibly different texts might get merged into a
+ single <code class="structname">pg_stat_statements</code> entry. Normally this will happen
+ only for semantically equivalent queries, but there is a small chance of
+ hash collisions causing unrelated queries to be merged into one entry.
+ (This cannot happen for queries belonging to different users or databases,
+ however.)
+ </p><p>
+ Since the <code class="structfield">queryid</code> hash value is computed on the
+ post-parse-analysis representation of the queries, the opposite is
+ also possible: queries with identical texts might appear as
+ separate entries, if they have different meanings as a result of
+ factors such as different <code class="varname">search_path</code> settings.
+ </p><p>
+ Consumers of <code class="structname">pg_stat_statements</code> may wish to use
+ <code class="structfield">queryid</code> (perhaps in combination with
+ <code class="structfield">dbid</code> and <code class="structfield">userid</code>) as a more stable
+ and reliable identifier for each entry than its query text.
+ However, it is important to understand that there are only limited
+ guarantees around the stability of the <code class="structfield">queryid</code> hash
+ value. Since the identifier is derived from the
+ post-parse-analysis tree, its value is a function of, among other
+ things, the internal object identifiers appearing in this representation.
+ This has some counterintuitive implications. For example,
+ <code class="filename">pg_stat_statements</code> will consider two apparently-identical
+ queries to be distinct, if they reference a table that was dropped
+ and recreated between the executions of the two queries.
+ The hashing process is also sensitive to differences in
+ machine architecture and other facets of the platform.
+ Furthermore, it is not safe to assume that <code class="structfield">queryid</code>
+ will be stable across major versions of <span class="productname">PostgreSQL</span>.
+ </p><p>
+ As a rule of thumb, <code class="structfield">queryid</code> values can be assumed to be
+ stable and comparable only so long as the underlying server version and
+ catalog metadata details stay exactly the same. Two servers
+ participating in replication based on physical WAL replay can be expected
+ to have identical <code class="structfield">queryid</code> values for the same query.
+ However, logical replication schemes do not promise to keep replicas
+ identical in all relevant details, so <code class="structfield">queryid</code> will
+ not be a useful identifier for accumulating costs across a set of logical
+ replicas. If in doubt, direct testing is recommended.
+ </p><p>
+ The parameter symbols used to replace constants in
+ representative query texts start from the next number after the
+ highest <code class="literal">$</code><em class="replaceable"><code>n</code></em> parameter in the original query
+ text, or <code class="literal">$1</code> if there was none. It's worth noting that in
+ some cases there may be hidden parameter symbols that affect this
+ numbering. For example, <span class="application">PL/pgSQL</span> uses hidden parameter
+ symbols to insert values of function local variables into queries, so that
+ a <span class="application">PL/pgSQL</span> statement like <code class="literal">SELECT i + 1 INTO j</code>
+ would have representative text like <code class="literal">SELECT i + $2</code>.
+ </p><p>
+ The representative query texts are kept in an external disk file, and do
+ not consume shared memory. Therefore, even very lengthy query texts can
+ be stored successfully. However, if many long query texts are
+ accumulated, the external file might grow unmanageably large. As a
+ recovery method if that happens, <code class="filename">pg_stat_statements</code> may
+ choose to discard the query texts, whereupon all existing entries in
+ the <code class="structname">pg_stat_statements</code> view will show
+ null <code class="structfield">query</code> fields, though the statistics associated with
+ each <code class="structfield">queryid</code> are preserved. If this happens, consider
+ reducing <code class="varname">pg_stat_statements.max</code> to prevent
+ recurrences.
+ </p><p>
+ <code class="structfield">plans</code> and <code class="structfield">calls</code> aren't
+ always expected to match because planning and execution statistics are
+ updated at their respective end phase, and only for successful operations.
+ For example, if a statement is successfully planned but fails during
+ the execution phase, only its planning statistics will be updated.
+ If planning is skipped because a cached plan is used, only its execution
+ statistics will be updated.
+ </p></div><div class="sect2" id="id-1.11.7.41.7"><div class="titlepage"><div><div><h3 class="title">F.32.2. The <code class="structname">pg_stat_statements_info</code> View</h3></div></div></div><a id="id-1.11.7.41.7.2" class="indexterm"></a><p>
+ The statistics of the <code class="filename">pg_stat_statements</code> module
+ itself are tracked and made available via a view named
+ <code class="structname">pg_stat_statements_info</code>. This view contains
+ only a single row. The columns of the view are shown in
+ <a class="xref" href="pgstatstatements.html#PGSTATSTATEMENTSINFO-COLUMNS" title="Table F.21. pg_stat_statements_info Columns">Table F.21</a>.
+ </p><div class="table" id="PGSTATSTATEMENTSINFO-COLUMNS"><p class="title"><strong>Table F.21. <code class="structname">pg_stat_statements_info</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_stat_statements_info Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dealloc</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of times <code class="structname">pg_stat_statements</code>
+ entries about the least-executed statements were deallocated
+ because more distinct statements than
+ <code class="varname">pg_stat_statements.max</code> were observed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">stats_reset</code> <code class="type">timestamp with time zone</code>
+ </p>
+ <p>
+ Time at which all statistics in the
+ <code class="structname">pg_stat_statements</code> view were last reset.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.41.8"><div class="titlepage"><div><div><h3 class="title">F.32.3. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">pg_stat_statements_reset(userid Oid, dbid Oid, queryid bigint) returns void</code>
+ <a id="id-1.11.7.41.8.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">pg_stat_statements_reset</code> discards statistics
+ gathered so far by <code class="filename">pg_stat_statements</code> corresponding
+ to the specified <code class="structfield">userid</code>, <code class="structfield">dbid</code>
+ and <code class="structfield">queryid</code>. If any of the parameters are not
+ specified, the default value <code class="literal">0</code>(invalid) is used for
+ each of them and the statistics that match with other parameters will be
+ reset. If no parameter is specified or all the specified parameters are
+ <code class="literal">0</code>(invalid), it will discard all statistics.
+ If all statistics in the <code class="filename">pg_stat_statements</code>
+ view are discarded, it will also reset the statistics in the
+ <code class="structname">pg_stat_statements_info</code> view.
+ By default, this function can only be executed by superusers.
+ Access may be granted to others using <code class="command">GRANT</code>.
+ </p></dd><dt><span class="term">
+ <code class="function">pg_stat_statements(showtext boolean) returns setof record</code>
+ <a id="id-1.11.7.41.8.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The <code class="structname">pg_stat_statements</code> view is defined in
+ terms of a function also named <code class="function">pg_stat_statements</code>.
+ It is possible for clients to call
+ the <code class="function">pg_stat_statements</code> function directly, and by
+ specifying <code class="literal">showtext := false</code> have query text be
+ omitted (that is, the <code class="literal">OUT</code> argument that corresponds
+ to the view's <code class="structfield">query</code> column will return nulls). This
+ feature is intended to support external tools that might wish to avoid
+ the overhead of repeatedly retrieving query texts of indeterminate
+ length. Such tools can instead cache the first query text observed
+ for each entry themselves, since that is
+ all <code class="filename">pg_stat_statements</code> itself does, and then retrieve
+ query texts only as needed. Since the server stores query texts in a
+ file, this approach may reduce physical I/O for repeated examination
+ of the <code class="structname">pg_stat_statements</code> data.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.41.9"><div class="titlepage"><div><div><h3 class="title">F.32.4. Configuration Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="varname">pg_stat_statements.max</code> (<code class="type">integer</code>)
+ <a id="id-1.11.7.41.9.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">pg_stat_statements.max</code> is the maximum number of
+ statements tracked by the module (i.e., the maximum number of rows
+ in the <code class="structname">pg_stat_statements</code> view). If more distinct
+ statements than that are observed, information about the least-executed
+ statements is discarded. The number of times such information was
+ discarded can be seen in the
+ <code class="structname">pg_stat_statements_info</code> view.
+ The default value is 5000.
+ This parameter can only be set at server start.
+ </p></dd><dt><span class="term">
+ <code class="varname">pg_stat_statements.track</code> (<code class="type">enum</code>)
+ <a id="id-1.11.7.41.9.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">pg_stat_statements.track</code> controls which statements
+ are counted by the module.
+ Specify <code class="literal">top</code> to track top-level statements (those issued
+ directly by clients), <code class="literal">all</code> to also track nested statements
+ (such as statements invoked within functions), or <code class="literal">none</code> to
+ disable statement statistics collection.
+ The default value is <code class="literal">top</code>.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">pg_stat_statements.track_utility</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.41.9.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">pg_stat_statements.track_utility</code> controls whether
+ utility commands are tracked by the module. Utility commands are
+ all those other than <code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, and <code class="command">MERGE</code>.
+ The default value is <code class="literal">on</code>.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">pg_stat_statements.track_planning</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.41.9.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">pg_stat_statements.track_planning</code> controls whether
+ planning operations and duration are tracked by the module.
+ Enabling this parameter may incur a noticeable performance penalty,
+ especially when statements with identical query structure are executed
+ by many concurrent connections which compete to update a small number of
+ <code class="structname">pg_stat_statements</code> entries.
+ The default value is <code class="literal">off</code>.
+ Only superusers can change this setting.
+ </p></dd><dt><span class="term">
+ <code class="varname">pg_stat_statements.save</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.41.9.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">pg_stat_statements.save</code> specifies whether to
+ save statement statistics across server shutdowns.
+ If it is <code class="literal">off</code> then statistics are not saved at
+ shutdown nor reloaded at server start.
+ The default value is <code class="literal">on</code>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div><p>
+ The module requires additional shared memory proportional to
+ <code class="varname">pg_stat_statements.max</code>. Note that this
+ memory is consumed whenever the module is loaded, even if
+ <code class="varname">pg_stat_statements.track</code> is set to <code class="literal">none</code>.
+ </p><p>
+ These parameters must be set in <code class="filename">postgresql.conf</code>.
+ Typical usage might be:
+
+</p><pre class="programlisting">
+# postgresql.conf
+shared_preload_libraries = 'pg_stat_statements'
+
+compute_query_id = on
+pg_stat_statements.max = 10000
+pg_stat_statements.track = all
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.7.41.10"><div class="titlepage"><div><div><h3 class="title">F.32.5. Sample Output</h3></div></div></div><pre class="screen">
+bench=# SELECT pg_stat_statements_reset();
+
+$ pgbench -i bench
+$ pgbench -c10 -t300 bench
+
+bench=# \x
+bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit /
+ nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
+ FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
+-[ RECORD 1 ]---+--------------------------------------------------​------------------
+query | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2
+calls | 3000
+total_exec_time | 25565.855387
+rows | 3000
+hit_percent | 100.0000000000000000
+-[ RECORD 2 ]---+--------------------------------------------------​------------------
+query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2
+calls | 3000
+total_exec_time | 20756.669379
+rows | 3000
+hit_percent | 100.0000000000000000
+-[ RECORD 3 ]---+--------------------------------------------------​------------------
+query | copy pgbench_accounts from stdin
+calls | 1
+total_exec_time | 291.865911
+rows | 100000
+hit_percent | 100.0000000000000000
+-[ RECORD 4 ]---+--------------------------------------------------​------------------
+query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2
+calls | 3000
+total_exec_time | 271.232977
+rows | 3000
+hit_percent | 98.8454011741682975
+-[ RECORD 5 ]---+--------------------------------------------------​------------------
+query | alter table pgbench_accounts add primary key (aid)
+calls | 1
+total_exec_time | 160.588563
+rows | 0
+hit_percent | 100.0000000000000000
+
+
+bench=# SELECT pg_stat_statements_reset(0,0,s.queryid) FROM pg_stat_statements AS s
+ WHERE s.query = 'UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2';
+
+bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit /
+ nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
+ FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
+-[ RECORD 1 ]---+--------------------------------------------------​------------------
+query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2
+calls | 3000
+total_exec_time | 20756.669379
+rows | 3000
+hit_percent | 100.0000000000000000
+-[ RECORD 2 ]---+--------------------------------------------------​------------------
+query | copy pgbench_accounts from stdin
+calls | 1
+total_exec_time | 291.865911
+rows | 100000
+hit_percent | 100.0000000000000000
+-[ RECORD 3 ]---+--------------------------------------------------​------------------
+query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2
+calls | 3000
+total_exec_time | 271.232977
+rows | 3000
+hit_percent | 98.8454011741682975
+-[ RECORD 4 ]---+--------------------------------------------------​------------------
+query | alter table pgbench_accounts add primary key (aid)
+calls | 1
+total_exec_time | 160.588563
+rows | 0
+hit_percent | 100.0000000000000000
+-[ RECORD 5 ]---+--------------------------------------------------​------------------
+query | vacuum analyze pgbench_accounts
+calls | 1
+total_exec_time | 136.448116
+rows | 0
+hit_percent | 99.9201915403032721
+
+bench=# SELECT pg_stat_statements_reset(0,0,0);
+
+bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit /
+ nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
+ FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
+-[ RECORD 1 ]---+--------------------------------------------------​---------------------------
+query | SELECT pg_stat_statements_reset(0,0,0)
+calls | 1
+total_exec_time | 0.189497
+rows | 1
+hit_percent |
+-[ RECORD 2 ]---+--------------------------------------------------​---------------------------
+query | SELECT query, calls, total_exec_time, rows, $1 * shared_blks_hit / +
+ | nullif(shared_blks_hit + shared_blks_read, $2) AS hit_percent+
+ | FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT $3
+calls | 0
+total_exec_time | 0
+rows | 0
+hit_percent |
+
+</pre></div><div class="sect2" id="id-1.11.7.41.11"><div class="titlepage"><div><div><h3 class="title">F.32.6. Authors</h3></div></div></div><p>
+ Takahiro Itagaki <code class="email">&lt;<a class="email" href="mailto:itagaki.takahiro@oss.ntt.co.jp">itagaki.takahiro@oss.ntt.co.jp</a>&gt;</code>.
+ Query normalization added by Peter Geoghegan <code class="email">&lt;<a class="email" href="mailto:peter@2ndquadrant.com">peter@2ndquadrant.com</a>&gt;</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgrowlocks.html" title="F.31. pgrowlocks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgstattuple.html" title="F.33. pgstattuple">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.31. pgrowlocks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.33. pgstattuple</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgstattuple.html b/doc/src/sgml/html/pgstattuple.html
new file mode 100644
index 0000000..ec9133f
--- /dev/null
+++ b/doc/src/sgml/html/pgstattuple.html
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.33. pgstattuple</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgstatstatements.html" title="F.32. pg_stat_statements" /><link rel="next" href="pgsurgery.html" title="F.34. pg_surgery" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.33. pgstattuple</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgstatstatements.html" title="F.32. pg_stat_statements">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgsurgery.html" title="F.34. pg_surgery">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGSTATTUPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.33. pgstattuple</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgstattuple.html#id-1.11.7.42.5">F.33.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgstattuple.html#id-1.11.7.42.6">F.33.2. Authors</a></span></dt></dl></div><a id="id-1.11.7.42.2" class="indexterm"></a><p>
+ The <code class="filename">pgstattuple</code> module provides various functions to
+ obtain tuple-level statistics.
+ </p><p>
+ Because these functions return detailed page-level information, access is
+ restricted by default. By default, only the
+ role <code class="literal">pg_stat_scan_tables</code> has <code class="literal">EXECUTE</code>
+ privilege. Superusers of course bypass this restriction. After the
+ extension has been installed, users may issue <code class="command">GRANT</code>
+ commands to change the privileges on the functions to allow others to
+ execute them. However, it might be preferable to add those users to
+ the <code class="literal">pg_stat_scan_tables</code> role instead.
+ </p><div class="sect2" id="id-1.11.7.42.5"><div class="titlepage"><div><div><h3 class="title">F.33.1. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <a id="id-1.11.7.42.5.2.1.1.1" class="indexterm"></a>
+ <code class="function">pgstattuple(regclass) returns record</code>
+ </span></dt><dd><p>
+ <code class="function">pgstattuple</code> returns a relation's physical length,
+ percentage of <span class="quote">“<span class="quote">dead</span>”</span> tuples, and other info. This may help users
+ to determine whether vacuum is necessary or not. The argument is the
+ target relation's name (optionally schema-qualified) or OID.
+ For example:
+</p><pre class="programlisting">
+test=&gt; SELECT * FROM pgstattuple('pg_catalog.pg_proc');
+-[ RECORD 1 ]------+-------
+table_len | 458752
+tuple_count | 1470
+tuple_len | 438896
+tuple_percent | 95.67
+dead_tuple_count | 11
+dead_tuple_len | 3157
+dead_tuple_percent | 0.69
+free_space | 8932
+free_percent | 1.95
+</pre><p>
+ The output columns are described in <a class="xref" href="pgstattuple.html#PGSTATTUPLE-COLUMNS" title="Table F.22. pgstattuple Output Columns">Table F.22</a>.
+ </p><div class="table" id="PGSTATTUPLE-COLUMNS"><p class="title"><strong>Table F.22. <code class="function">pgstattuple</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pgstattuple Output Columns" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Column</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">table_len</code></td><td><code class="type">bigint</code></td><td>Physical relation length in bytes</td></tr><tr><td><code class="structfield">tuple_count</code></td><td><code class="type">bigint</code></td><td>Number of live tuples</td></tr><tr><td><code class="structfield">tuple_len</code></td><td><code class="type">bigint</code></td><td>Total length of live tuples in bytes</td></tr><tr><td><code class="structfield">tuple_percent</code></td><td><code class="type">float8</code></td><td>Percentage of live tuples</td></tr><tr><td><code class="structfield">dead_tuple_count</code></td><td><code class="type">bigint</code></td><td>Number of dead tuples</td></tr><tr><td><code class="structfield">dead_tuple_len</code></td><td><code class="type">bigint</code></td><td>Total length of dead tuples in bytes</td></tr><tr><td><code class="structfield">dead_tuple_percent</code></td><td><code class="type">float8</code></td><td>Percentage of dead tuples</td></tr><tr><td><code class="structfield">free_space</code></td><td><code class="type">bigint</code></td><td>Total free space in bytes</td></tr><tr><td><code class="structfield">free_percent</code></td><td><code class="type">float8</code></td><td>Percentage of free space</td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="literal">table_len</code> will always be greater than the sum
+ of the <code class="literal">tuple_len</code>, <code class="literal">dead_tuple_len</code>
+ and <code class="literal">free_space</code>. The difference is accounted for by
+ fixed page overhead, the per-page table of pointers to tuples, and
+ padding to ensure that tuples are correctly aligned.
+ </p></div><p>
+ <code class="function">pgstattuple</code> acquires only a read lock on the
+ relation. So the results do not reflect an instantaneous snapshot;
+ concurrent updates will affect them.
+ </p><p>
+ <code class="function">pgstattuple</code> judges a tuple is <span class="quote">“<span class="quote">dead</span>”</span> if
+ <code class="function">HeapTupleSatisfiesDirty</code> returns false.
+ </p></dd><dt><span class="term">
+ <code class="function">pgstattuple(text) returns record</code>
+ </span></dt><dd><p>
+ This is the same as <code class="function">pgstattuple(regclass)</code>, except
+ that the target relation is specified as TEXT. This function is kept
+ because of backward-compatibility so far, and will be deprecated in
+ some future release.
+ </p></dd><dt><span class="term">
+ <a id="id-1.11.7.42.5.2.3.1.1" class="indexterm"></a>
+ <code class="function">pgstatindex(regclass) returns record</code>
+ </span></dt><dd><p>
+ <code class="function">pgstatindex</code> returns a record showing information
+ about a B-tree index. For example:
+</p><pre class="programlisting">
+test=&gt; SELECT * FROM pgstatindex('pg_cast_oid_index');
+-[ RECORD 1 ]------+------
+version | 2
+tree_level | 0
+index_size | 16384
+root_block_no | 1
+internal_pages | 0
+leaf_pages | 1
+empty_pages | 0
+deleted_pages | 0
+avg_leaf_density | 54.27
+leaf_fragmentation | 0
+</pre><p>
+ </p><p>
+ The output columns are:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Column</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">version</code></td><td><code class="type">integer</code></td><td>B-tree version number</td></tr><tr><td><code class="structfield">tree_level</code></td><td><code class="type">integer</code></td><td>Tree level of the root page</td></tr><tr><td><code class="structfield">index_size</code></td><td><code class="type">bigint</code></td><td>Total index size in bytes</td></tr><tr><td><code class="structfield">root_block_no</code></td><td><code class="type">bigint</code></td><td>Location of root page (zero if none)</td></tr><tr><td><code class="structfield">internal_pages</code></td><td><code class="type">bigint</code></td><td>Number of <span class="quote">“<span class="quote">internal</span>”</span> (upper-level) pages</td></tr><tr><td><code class="structfield">leaf_pages</code></td><td><code class="type">bigint</code></td><td>Number of leaf pages</td></tr><tr><td><code class="structfield">empty_pages</code></td><td><code class="type">bigint</code></td><td>Number of empty pages</td></tr><tr><td><code class="structfield">deleted_pages</code></td><td><code class="type">bigint</code></td><td>Number of deleted pages</td></tr><tr><td><code class="structfield">avg_leaf_density</code></td><td><code class="type">float8</code></td><td>Average density of leaf pages</td></tr><tr><td><code class="structfield">leaf_fragmentation</code></td><td><code class="type">float8</code></td><td>Leaf page fragmentation</td></tr></tbody></table></div><p>
+ </p><p>
+ The reported <code class="literal">index_size</code> will normally correspond to one more
+ page than is accounted for by <code class="literal">internal_pages + leaf_pages +
+ empty_pages + deleted_pages</code>, because it also includes the
+ index's metapage.
+ </p><p>
+ As with <code class="function">pgstattuple</code>, the results are accumulated
+ page-by-page, and should not be expected to represent an
+ instantaneous snapshot of the whole index.
+ </p></dd><dt><span class="term">
+ <code class="function">pgstatindex(text) returns record</code>
+ </span></dt><dd><p>
+ This is the same as <code class="function">pgstatindex(regclass)</code>, except
+ that the target index is specified as TEXT. This function is kept
+ because of backward-compatibility so far, and will be deprecated in
+ some future release.
+ </p></dd><dt><span class="term">
+ <a id="id-1.11.7.42.5.2.5.1.1" class="indexterm"></a>
+ <code class="function">pgstatginindex(regclass) returns record</code>
+ </span></dt><dd><p>
+ <code class="function">pgstatginindex</code> returns a record showing information
+ about a GIN index. For example:
+</p><pre class="programlisting">
+test=&gt; SELECT * FROM pgstatginindex('test_gin_index');
+-[ RECORD 1 ]--+--
+version | 1
+pending_pages | 0
+pending_tuples | 0
+</pre><p>
+ </p><p>
+ The output columns are:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Column</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">version</code></td><td><code class="type">integer</code></td><td>GIN version number</td></tr><tr><td><code class="structfield">pending_pages</code></td><td><code class="type">integer</code></td><td>Number of pages in the pending list</td></tr><tr><td><code class="structfield">pending_tuples</code></td><td><code class="type">bigint</code></td><td>Number of tuples in the pending list</td></tr></tbody></table></div><p>
+ </p></dd><dt><span class="term">
+ <a id="id-1.11.7.42.5.2.6.1.1" class="indexterm"></a>
+ <code class="function">pgstathashindex(regclass) returns record</code>
+ </span></dt><dd><p>
+ <code class="function">pgstathashindex</code> returns a record showing information
+ about a HASH index. For example:
+</p><pre class="programlisting">
+test=&gt; select * from pgstathashindex('con_hash_index');
+-[ RECORD 1 ]--+-----------------
+version | 4
+bucket_pages | 33081
+overflow_pages | 0
+bitmap_pages | 1
+unused_pages | 32455
+live_items | 10204006
+dead_items | 0
+free_percent | 61.8005949100872
+</pre><p>
+ </p><p>
+ The output columns are:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Column</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">version</code></td><td><code class="type">integer</code></td><td>HASH version number</td></tr><tr><td><code class="structfield">bucket_pages</code></td><td><code class="type">bigint</code></td><td>Number of bucket pages</td></tr><tr><td><code class="structfield">overflow_pages</code></td><td><code class="type">bigint</code></td><td>Number of overflow pages</td></tr><tr><td><code class="structfield">bitmap_pages</code></td><td><code class="type">bigint</code></td><td>Number of bitmap pages</td></tr><tr><td><code class="structfield">unused_pages</code></td><td><code class="type">bigint</code></td><td>Number of unused pages</td></tr><tr><td><code class="structfield">live_items</code></td><td><code class="type">bigint</code></td><td>Number of live tuples</td></tr><tr><td><code class="structfield">dead_tuples</code></td><td><code class="type">bigint</code></td><td>Number of dead tuples</td></tr><tr><td><code class="structfield">free_percent</code></td><td><code class="type">float</code></td><td>Percentage of free space</td></tr></tbody></table></div><p>
+ </p></dd><dt><span class="term">
+ <a id="id-1.11.7.42.5.2.7.1.1" class="indexterm"></a>
+ <code class="function">pg_relpages(regclass) returns bigint</code>
+ </span></dt><dd><p>
+ <code class="function">pg_relpages</code> returns the number of pages in the
+ relation.
+ </p></dd><dt><span class="term">
+ <code class="function">pg_relpages(text) returns bigint</code>
+ </span></dt><dd><p>
+ This is the same as <code class="function">pg_relpages(regclass)</code>, except
+ that the target relation is specified as TEXT. This function is kept
+ because of backward-compatibility so far, and will be deprecated in
+ some future release.
+ </p></dd><dt><span class="term">
+ <a id="id-1.11.7.42.5.2.9.1.1" class="indexterm"></a>
+ <code class="function">pgstattuple_approx(regclass) returns record</code>
+ </span></dt><dd><p>
+ <code class="function">pgstattuple_approx</code> is a faster alternative to
+ <code class="function">pgstattuple</code> that returns approximate results.
+ The argument is the target relation's name or OID.
+ For example:
+</p><pre class="programlisting">
+test=&gt; SELECT * FROM pgstattuple_approx('pg_catalog.pg_proc'::regclass);
+-[ RECORD 1 ]--------+-------
+table_len | 573440
+scanned_percent | 2
+approx_tuple_count | 2740
+approx_tuple_len | 561210
+approx_tuple_percent | 97.87
+dead_tuple_count | 0
+dead_tuple_len | 0
+dead_tuple_percent | 0
+approx_free_space | 11996
+approx_free_percent | 2.09
+</pre><p>
+ The output columns are described in <a class="xref" href="pgstattuple.html#PGSTATAPPROX-COLUMNS" title="Table F.23. pgstattuple_approx Output Columns">Table F.23</a>.
+ </p><p>
+ Whereas <code class="function">pgstattuple</code> always performs a
+ full-table scan and returns an exact count of live and dead tuples
+ (and their sizes) and free space, <code class="function">pgstattuple_approx</code>
+ tries to avoid the full-table scan and returns exact dead tuple
+ statistics along with an approximation of the number and
+ size of live tuples and free space.
+ </p><p>
+ It does this by skipping pages that have only visible tuples
+ according to the visibility map (if a page has the corresponding VM
+ bit set, then it is assumed to contain no dead tuples). For such
+ pages, it derives the free space value from the free space map, and
+ assumes that the rest of the space on the page is taken up by live
+ tuples.
+ </p><p>
+ For pages that cannot be skipped, it scans each tuple, recording its
+ presence and size in the appropriate counters, and adding up the
+ free space on the page. At the end, it estimates the total number of
+ live tuples based on the number of pages and tuples scanned (in the
+ same way that VACUUM estimates pg_class.reltuples).
+ </p><div class="table" id="PGSTATAPPROX-COLUMNS"><p class="title"><strong>Table F.23. <code class="function">pgstattuple_approx</code> Output Columns</strong></p><div class="table-contents"><table class="table" summary="pgstattuple_approx Output Columns" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Column</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="structfield">table_len</code></td><td><code class="type">bigint</code></td><td>Physical relation length in bytes (exact)</td></tr><tr><td><code class="structfield">scanned_percent</code></td><td><code class="type">float8</code></td><td>Percentage of table scanned</td></tr><tr><td><code class="structfield">approx_tuple_count</code></td><td><code class="type">bigint</code></td><td>Number of live tuples (estimated)</td></tr><tr><td><code class="structfield">approx_tuple_len</code></td><td><code class="type">bigint</code></td><td>Total length of live tuples in bytes (estimated)</td></tr><tr><td><code class="structfield">approx_tuple_percent</code></td><td><code class="type">float8</code></td><td>Percentage of live tuples</td></tr><tr><td><code class="structfield">dead_tuple_count</code></td><td><code class="type">bigint</code></td><td>Number of dead tuples (exact)</td></tr><tr><td><code class="structfield">dead_tuple_len</code></td><td><code class="type">bigint</code></td><td>Total length of dead tuples in bytes (exact)</td></tr><tr><td><code class="structfield">dead_tuple_percent</code></td><td><code class="type">float8</code></td><td>Percentage of dead tuples</td></tr><tr><td><code class="structfield">approx_free_space</code></td><td><code class="type">bigint</code></td><td>Total free space in bytes (estimated)</td></tr><tr><td><code class="structfield">approx_free_percent</code></td><td><code class="type">float8</code></td><td>Percentage of free space</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In the above output, the free space figures may not match the
+ <code class="function">pgstattuple</code> output exactly, because the free
+ space map gives us an exact figure, but is not guaranteed to be
+ accurate to the byte.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.42.6"><div class="titlepage"><div><div><h3 class="title">F.33.2. Authors</h3></div></div></div><p>
+ Tatsuo Ishii, Satoshi Nagayasu and Abhijit Menon-Sen
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgstatstatements.html" title="F.32. pg_stat_statements">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgsurgery.html" title="F.34. pg_surgery">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.32. pg_stat_statements </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.34. pg_surgery</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgsurgery.html b/doc/src/sgml/html/pgsurgery.html
new file mode 100644
index 0000000..bd34b2a
--- /dev/null
+++ b/doc/src/sgml/html/pgsurgery.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.34. pg_surgery</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgstattuple.html" title="F.33. pgstattuple" /><link rel="next" href="pgtrgm.html" title="F.35. pg_trgm" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.34. pg_surgery</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgstattuple.html" title="F.33. pgstattuple">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgtrgm.html" title="F.35. pg_trgm">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGSURGERY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.34. pg_surgery</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgsurgery.html#id-1.11.7.43.4">F.34.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgsurgery.html#id-1.11.7.43.5">F.34.2. Authors</a></span></dt></dl></div><a id="id-1.11.7.43.2" class="indexterm"></a><p>
+ The <code class="filename">pg_surgery</code> module provides various functions to
+ perform surgery on a damaged relation. These functions are unsafe by design
+ and using them may corrupt (or further corrupt) your database. For example,
+ these functions can easily be used to make a table inconsistent with its
+ own indexes, to cause <code class="literal">UNIQUE</code> or
+ <code class="literal">FOREIGN KEY</code> constraint violations, or even to make
+ tuples visible which, when read, will cause a database server crash.
+ They should be used with great caution and only as a last resort.
+ </p><div class="sect2" id="id-1.11.7.43.4"><div class="titlepage"><div><div><h3 class="title">F.34.1. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">heap_force_kill(regclass, tid[]) returns void</code>
+ </span></dt><dd><p>
+ <code class="function">heap_force_kill</code> marks <span class="quote">“<span class="quote">used</span>”</span> line
+ pointers as <span class="quote">“<span class="quote">dead</span>”</span> without examining the tuples. The
+ intended use of this function is to forcibly remove tuples that are not
+ otherwise accessible. For example:
+</p><pre class="programlisting">
+test=&gt; select * from t1 where ctid = '(0, 1)';
+ERROR: could not access status of transaction 4007513275
+DETAIL: Could not open file "pg_xact/0EED": No such file or directory.
+
+test=# select heap_force_kill('t1'::regclass, ARRAY['(0, 1)']::tid[]);
+ heap_force_kill
+-----------------
+
+(1 row)
+
+test=# select * from t1 where ctid = '(0, 1)';
+(0 rows)
+
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">heap_force_freeze(regclass, tid[]) returns void</code>
+ </span></dt><dd><p>
+ <code class="function">heap_force_freeze</code> marks tuples as frozen without
+ examining the tuple data. The intended use of this function is to
+ make accessible tuples which are inaccessible due to corrupted
+ visibility information, or which prevent the table from being
+ successfully vacuumed due to corrupted visibility information.
+ For example:
+</p><pre class="programlisting">
+test=&gt; vacuum t1;
+ERROR: found xmin 507 from before relfrozenxid 515
+CONTEXT: while scanning block 0 of relation "public.t1"
+
+test=# select ctid from t1 where xmin = 507;
+ ctid
+-------
+ (0,3)
+(1 row)
+
+test=# select heap_force_freeze('t1'::regclass, ARRAY['(0, 3)']::tid[]);
+ heap_force_freeze
+-------------------
+
+(1 row)
+
+test=# select ctid from t1 where xmin = 2;
+ ctid
+-------
+ (0,3)
+(1 row)
+
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.43.5"><div class="titlepage"><div><div><h3 class="title">F.34.2. Authors</h3></div></div></div><p>
+ Ashutosh Sharma <code class="email">&lt;<a class="email" href="mailto:ashu.coek88@gmail.com">ashu.coek88@gmail.com</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgstattuple.html" title="F.33. pgstattuple">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgtrgm.html" title="F.35. pg_trgm">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.33. pgstattuple </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.35. pg_trgm</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgtestfsync.html b/doc/src/sgml/html/pgtestfsync.html
new file mode 100644
index 0000000..1b692a7
--- /dev/null
+++ b/doc/src/sgml/html/pgtestfsync.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_test_fsync</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-pgrewind.html" title="pg_rewind" /><link rel="next" href="pgtesttiming.html" title="pg_test_timing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_test_fsync</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-pgrewind.html" title="pg_rewind">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgtesttiming.html" title="pg_test_timing">Next</a></td></tr></table><hr /></div><div class="refentry" id="PGTESTFSYNC"><div class="titlepage"></div><a id="id-1.9.5.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_test_fsync</span></span></h2><p>pg_test_fsync — determine fastest <code class="varname">wal_sync_method</code> for <span class="productname">PostgreSQL</span></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.10.4.1"><code class="command">pg_test_fsync</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.5.10.5"><h2>Description</h2><p>
+ <span class="application">pg_test_fsync</span> is intended to give you a reasonable
+ idea of what the fastest <a class="xref" href="runtime-config-wal.html#GUC-WAL-SYNC-METHOD">wal_sync_method</a> is on your
+ specific system,
+ as well as supplying diagnostic information in the event of an identified I/O
+ problem. However, differences shown by
+ <span class="application">pg_test_fsync</span> might not make any significant
+ difference in real database throughput, especially since many database servers
+ are not speed-limited by their write-ahead logs.
+ <span class="application">pg_test_fsync</span> reports average file sync operation
+ time in microseconds for each <code class="literal">wal_sync_method</code>, which can also be used to
+ inform efforts to optimize the value of <a class="xref" href="runtime-config-wal.html#GUC-COMMIT-DELAY">commit_delay</a>.
+ </p></div><div class="refsect1" id="id-1.9.5.10.6"><h2>Options</h2><p>
+ <span class="application">pg_test_fsync</span> accepts the following
+ command-line options:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-f</code><br /></span><span class="term"><code class="option">--filename</code></span></dt><dd><p>
+ Specifies the file name to write test data in.
+ This file should be in the same file system that the
+ <code class="filename">pg_wal</code> directory is or will be placed in.
+ (<code class="filename">pg_wal</code> contains the <acronym class="acronym">WAL</acronym> files.)
+ The default is <code class="filename">pg_test_fsync.out</code> in the current
+ directory.
+ </p></dd><dt><span class="term"><code class="option">-s</code><br /></span><span class="term"><code class="option">--secs-per-test</code></span></dt><dd><p>
+ Specifies the number of seconds for each test. The more time
+ per test, the greater the test's accuracy, but the longer it takes
+ to run. The default is 5 seconds, which allows the program to
+ complete in under 2 minutes.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_test_fsync</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_test_fsync</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.10.7"><h2>Environment</h2><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.9.5.10.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-pgrewind.html" title="pg_rewind">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgtesttiming.html" title="pg_test_timing">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_rewind</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_test_timing</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgtesttiming.html b/doc/src/sgml/html/pgtesttiming.html
new file mode 100644
index 0000000..96a189e
--- /dev/null
+++ b/doc/src/sgml/html/pgtesttiming.html
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_test_timing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgtestfsync.html" title="pg_test_fsync" /><link rel="next" href="pgupgrade.html" title="pg_upgrade" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_test_timing</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgtestfsync.html" title="pg_test_fsync">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgupgrade.html" title="pg_upgrade">Next</a></td></tr></table><hr /></div><div class="refentry" id="PGTESTTIMING"><div class="titlepage"></div><a id="id-1.9.5.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_test_timing</span></span></h2><p>pg_test_timing — measure timing overhead</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.11.4.1"><code class="command">pg_test_timing</code> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.5.11.5"><h2>Description</h2><p>
+ <span class="application">pg_test_timing</span> is a tool to measure the timing overhead
+ on your system and confirm that the system time never moves backwards.
+ Systems that are slow to collect timing data can give less accurate
+ <code class="command">EXPLAIN ANALYZE</code> results.
+ </p></div><div class="refsect1" id="id-1.9.5.11.6"><h2>Options</h2><p>
+ <span class="application">pg_test_timing</span> accepts the following
+ command-line options:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-d <em class="replaceable"><code>duration</code></em></code><br /></span><span class="term"><code class="option">--duration=<em class="replaceable"><code>duration</code></em></code></span></dt><dd><p>
+ Specifies the test duration, in seconds. Longer durations
+ give slightly better accuracy, and are more likely to discover
+ problems with the system clock moving backwards. The default
+ test duration is 3 seconds.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_test_timing</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_test_timing</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.11.7"><h2>Usage</h2><div class="refsect2" id="id-1.9.5.11.7.2"><h3>Interpreting Results</h3><p>
+ Good results will show most (&gt;90%) individual timing calls take less than
+ one microsecond. Average per loop overhead will be even lower, below 100
+ nanoseconds. This example from an Intel i7-860 system using a TSC clock
+ source shows excellent performance:
+
+</p><pre class="screen">
+Testing timing overhead for 3 seconds.
+Per loop time including overhead: 35.96 ns
+Histogram of timing durations:
+ &lt; us % of total count
+ 1 96.40465 80435604
+ 2 3.59518 2999652
+ 4 0.00015 126
+ 8 0.00002 13
+ 16 0.00000 2
+</pre><p>
+ </p><p>
+ Note that different units are used for the per loop time than the
+ histogram. The loop can have resolution within a few nanoseconds (ns),
+ while the individual timing calls can only resolve down to one microsecond
+ (us).
+ </p></div><div class="refsect2" id="id-1.9.5.11.7.3"><h3>Measuring Executor Timing Overhead</h3><p>
+ When the query executor is running a statement using
+ <code class="command">EXPLAIN ANALYZE</code>, individual operations are timed as well
+ as showing a summary. The overhead of your system can be checked by
+ counting rows with the <span class="application">psql</span> program:
+
+</p><pre class="screen">
+CREATE TABLE t AS SELECT * FROM generate_series(1,100000);
+\timing
+SELECT COUNT(*) FROM t;
+EXPLAIN ANALYZE SELECT COUNT(*) FROM t;
+</pre><p>
+ </p><p>
+ The i7-860 system measured runs the count query in 9.8 ms while
+ the <code class="command">EXPLAIN ANALYZE</code> version takes 16.6 ms, each
+ processing just over 100,000 rows. That 6.8 ms difference means the timing
+ overhead per row is 68 ns, about twice what pg_test_timing estimated it
+ would be. Even that relatively small amount of overhead is making the fully
+ timed count statement take almost 70% longer. On more substantial queries,
+ the timing overhead would be less problematic.
+ </p></div><div class="refsect2" id="id-1.9.5.11.7.4"><h3>Changing Time Sources</h3><p>
+ On some newer Linux systems, it's possible to change the clock source used
+ to collect timing data at any time. A second example shows the slowdown
+ possible from switching to the slower acpi_pm time source, on the same
+ system used for the fast results above:
+
+</p><pre class="screen">
+# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
+tsc hpet acpi_pm
+# echo acpi_pm &gt; /sys/devices/system/clocksource/clocksource0/current_clocksource
+# pg_test_timing
+Per loop time including overhead: 722.92 ns
+Histogram of timing durations:
+ &lt; us % of total count
+ 1 27.84870 1155682
+ 2 72.05956 2990371
+ 4 0.07810 3241
+ 8 0.01357 563
+ 16 0.00007 3
+</pre><p>
+ </p><p>
+ In this configuration, the sample <code class="command">EXPLAIN ANALYZE</code> above
+ takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple
+ of what's measured directly by this utility. That much timing overhead
+ means the actual query itself is only taking a tiny fraction of the
+ accounted for time, most of it is being consumed in overhead instead. In
+ this configuration, any <code class="command">EXPLAIN ANALYZE</code> totals involving
+ many timed operations would be inflated significantly by timing overhead.
+ </p><p>
+ FreeBSD also allows changing the time source on the fly, and it logs
+ information about the timer selected during boot:
+
+</p><pre class="screen">
+# dmesg | grep "Timecounter"
+Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
+Timecounter "i8254" frequency 1193182 Hz quality 0
+Timecounters tick every 10.000 msec
+Timecounter "TSC" frequency 2531787134 Hz quality 800
+# sysctl kern.timecounter.hardware=TSC
+kern.timecounter.hardware: ACPI-fast -&gt; TSC
+</pre><p>
+ </p><p>
+ Other systems may only allow setting the time source on boot. On older
+ Linux systems the "clock" kernel setting is the only way to make this sort
+ of change. And even on some more recent ones, the only option you'll see
+ for a clock source is "jiffies". Jiffies are the older Linux software clock
+ implementation, which can have good resolution when it's backed by fast
+ enough timing hardware, as in this example:
+
+</p><pre class="screen">
+$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
+jiffies
+$ dmesg | grep time.c
+time.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.
+time.c: Detected 2400.153 MHz processor.
+$ pg_test_timing
+Testing timing overhead for 3 seconds.
+Per timing duration including loop overhead: 97.75 ns
+Histogram of timing durations:
+ &lt; us % of total count
+ 1 90.23734 27694571
+ 2 9.75277 2993204
+ 4 0.00981 3010
+ 8 0.00007 22
+ 16 0.00000 1
+ 32 0.00000 1
+</pre></div><div class="refsect2" id="id-1.9.5.11.7.5"><h3>Clock Hardware and Timing Accuracy</h3><p>
+ Collecting accurate timing information is normally done on computers using
+ hardware clocks with various levels of accuracy. With some hardware the
+ operating systems can pass the system clock time almost directly to
+ programs. A system clock can also be derived from a chip that simply
+ provides timing interrupts, periodic ticks at some known time interval. In
+ either case, operating system kernels provide a clock source that hides
+ these details. But the accuracy of that clock source and how quickly it can
+ return results varies based on the underlying hardware.
+ </p><p>
+ Inaccurate time keeping can result in system instability. Test any change
+ to the clock source very carefully. Operating system defaults are sometimes
+ made to favor reliability over best accuracy. And if you are using a virtual
+ machine, look into the recommended time sources compatible with it. Virtual
+ hardware faces additional difficulties when emulating timers, and there are
+ often per operating system settings suggested by vendors.
+ </p><p>
+ The Time Stamp Counter (TSC) clock source is the most accurate one available
+ on current generation CPUs. It's the preferred way to track the system time
+ when it's supported by the operating system and the TSC clock is
+ reliable. There are several ways that TSC can fail to provide an accurate
+ timing source, making it unreliable. Older systems can have a TSC clock that
+ varies based on the CPU temperature, making it unusable for timing. Trying
+ to use TSC on some older multicore CPUs can give a reported time that's
+ inconsistent among multiple cores. This can result in the time going
+ backwards, a problem this program checks for. And even the newest systems
+ can fail to provide accurate TSC timing with very aggressive power saving
+ configurations.
+ </p><p>
+ Newer operating systems may check for the known TSC problems and switch to a
+ slower, more stable clock source when they are seen. If your system
+ supports TSC time but doesn't default to that, it may be disabled for a good
+ reason. And some operating systems may not detect all the possible problems
+ correctly, or will allow using TSC even in situations where it's known to be
+ inaccurate.
+ </p><p>
+ The High Precision Event Timer (HPET) is the preferred timer on systems
+ where it's available and TSC is not accurate. The timer chip itself is
+ programmable to allow up to 100 nanosecond resolution, but you may not see
+ that much accuracy in your system clock.
+ </p><p>
+ Advanced Configuration and Power Interface (ACPI) provides a Power
+ Management (PM) Timer, which Linux refers to as the acpi_pm. The clock
+ derived from acpi_pm will at best provide 300 nanosecond resolution.
+ </p><p>
+ Timers used on older PC hardware include the 8254 Programmable Interval
+ Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt
+ Controller (APIC) timer, and the Cyclone timer. These timers aim for
+ millisecond resolution.
+ </p></div></div><div class="refsect1" id="id-1.9.5.11.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-explain.html" title="EXPLAIN"><span class="refentrytitle">EXPLAIN</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgtestfsync.html" title="pg_test_fsync">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgupgrade.html" title="pg_upgrade">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_test_fsync</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_upgrade</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgtrgm.html b/doc/src/sgml/html/pgtrgm.html
new file mode 100644
index 0000000..5a1ec26
--- /dev/null
+++ b/doc/src/sgml/html/pgtrgm.html
@@ -0,0 +1,424 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.35. pg_trgm</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgsurgery.html" title="F.34. pg_surgery" /><link rel="next" href="pgvisibility.html" title="F.36. pg_visibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.35. pg_trgm</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgsurgery.html" title="F.34. pg_surgery">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgvisibility.html" title="F.36. pg_visibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGTRGM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.35. pg_trgm</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.5">F.35.1. Trigram (or Trigraph) Concepts</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.6">F.35.2. Functions and Operators</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.7">F.35.3. GUC Parameters</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.8">F.35.4. Index Support</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.9">F.35.5. Text Search Integration</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.10">F.35.6. References</a></span></dt><dt><span class="sect2"><a href="pgtrgm.html#id-1.11.7.44.11">F.35.7. Authors</a></span></dt></dl></div><a id="id-1.11.7.44.2" class="indexterm"></a><p>
+ The <code class="filename">pg_trgm</code> module provides functions and operators
+ for determining the similarity of
+ alphanumeric text based on trigram matching, as
+ well as index operator classes that support fast searching for similar
+ strings.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.44.5"><div class="titlepage"><div><div><h3 class="title">F.35.1. Trigram (or Trigraph) Concepts</h3></div></div></div><p>
+ A trigram is a group of three consecutive characters taken
+ from a string. We can measure the similarity of two strings by
+ counting the number of trigrams they share. This simple idea
+ turns out to be very effective for measuring the similarity of
+ words in many natural languages.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="filename">pg_trgm</code> ignores non-word characters
+ (non-alphanumerics) when extracting trigrams from a string.
+ Each word is considered to have two spaces
+ prefixed and one space suffixed when determining the set
+ of trigrams contained in the string.
+ For example, the set of trigrams in the string
+ <span class="quote">“<span class="quote"><code class="literal">cat</code></span>”</span> is
+ <span class="quote">“<span class="quote"><code class="literal"> c</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal"> ca</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal">cat</code></span>”</span>, and
+ <span class="quote">“<span class="quote"><code class="literal">at </code></span>”</span>.
+ The set of trigrams in the string
+ <span class="quote">“<span class="quote"><code class="literal">foo|bar</code></span>”</span> is
+ <span class="quote">“<span class="quote"><code class="literal"> f</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal"> fo</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal">foo</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal">oo </code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal"> b</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal"> ba</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal">bar</code></span>”</span>, and
+ <span class="quote">“<span class="quote"><code class="literal">ar </code></span>”</span>.
+ </p></div></div><div class="sect2" id="id-1.11.7.44.6"><div class="titlepage"><div><div><h3 class="title">F.35.2. Functions and Operators</h3></div></div></div><p>
+ The functions provided by the <code class="filename">pg_trgm</code> module
+ are shown in <a class="xref" href="pgtrgm.html#PGTRGM-FUNC-TABLE" title="Table F.24. pg_trgm Functions">Table F.24</a>, the operators
+ in <a class="xref" href="pgtrgm.html#PGTRGM-OP-TABLE" title="Table F.25. pg_trgm Operators">Table F.25</a>.
+ </p><div class="table" id="PGTRGM-FUNC-TABLE"><p class="title"><strong>Table F.24. <code class="filename">pg_trgm</code> Functions</strong></p><div class="table-contents"><table class="table" summary="pg_trgm Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.44.6.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">similarity</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Returns a number that indicates how similar the two arguments are.
+ The range of the result is zero (indicating that the two strings are
+ completely dissimilar) to one (indicating that the two strings are
+ identical).
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.44.6.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">show_trgm</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text[]</code>
+ </p>
+ <p>
+ Returns an array of all the trigrams in the given string.
+ (In practice this is seldom useful except for debugging.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.44.6.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">word_similarity</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Returns a number that indicates the greatest similarity between
+ the set of trigrams in the first string and any continuous extent
+ of an ordered set of trigrams in the second string. For details, see
+ the explanation below.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.44.6.3.2.2.4.1.1.1" class="indexterm"></a>
+ <code class="function">strict_word_similarity</code> ( <code class="type">text</code>, <code class="type">text</code> )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Same as <code class="function">word_similarity</code>, but forces
+ extent boundaries to match word boundaries. Since we don't have
+ cross-word trigrams, this function actually returns greatest similarity
+ between first string and any continuous extent of words of the second
+ string.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.44.6.3.2.2.5.1.1.1" class="indexterm"></a>
+ <code class="function">show_limit</code> ()
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Returns the current similarity threshold used by the <code class="literal">%</code>
+ operator. This sets the minimum similarity between
+ two words for them to be considered similar enough to
+ be misspellings of each other, for example.
+ (<span class="emphasis"><em>Deprecated</em></span>; instead use <code class="command">SHOW</code>
+ <code class="varname">pg_trgm.similarity_threshold</code>.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.44.6.3.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">set_limit</code> ( <code class="type">real</code> )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Sets the current similarity threshold that is used by the <code class="literal">%</code>
+ operator. The threshold must be between 0 and 1 (default is 0.3).
+ Returns the same value passed in.
+ (<span class="emphasis"><em>Deprecated</em></span>; instead use <code class="command">SET</code>
+ <code class="varname">pg_trgm.similarity_threshold</code>.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Consider the following example:
+
+</p><pre class="programlisting">
+# SELECT word_similarity('word', 'two words');
+ word_similarity
+-----------------
+ 0.8
+(1 row)
+</pre><p>
+
+ In the first string, the set of trigrams is
+ <code class="literal">{" w"," wo","wor","ord","rd "}</code>.
+ In the second string, the ordered set of trigrams is
+ <code class="literal">{" t"," tw","two","wo "," w"," wo","wor","ord","rds","ds "}</code>.
+ The most similar extent of an ordered set of trigrams in the second string
+ is <code class="literal">{" w"," wo","wor","ord"}</code>, and the similarity is
+ <code class="literal">0.8</code>.
+ </p><p>
+ This function returns a value that can be approximately understood as the
+ greatest similarity between the first string and any substring of the second
+ string. However, this function does not add padding to the boundaries of
+ the extent. Thus, the number of additional characters present in the
+ second string is not considered, except for the mismatched word boundaries.
+ </p><p>
+ At the same time, <code class="function">strict_word_similarity</code>
+ selects an extent of words in the second string. In the example above,
+ <code class="function">strict_word_similarity</code> would select the
+ extent of a single word <code class="literal">'words'</code>, whose set of trigrams is
+ <code class="literal">{" w"," wo","wor","ord","rds","ds "}</code>.
+
+</p><pre class="programlisting">
+# SELECT strict_word_similarity('word', 'two words'), similarity('word', 'words');
+ strict_word_similarity | similarity
+------------------------+------------
+ 0.571429 | 0.571429
+(1 row)
+</pre><p>
+ </p><p>
+ Thus, the <code class="function">strict_word_similarity</code> function
+ is useful for finding the similarity to whole words, while
+ <code class="function">word_similarity</code> is more suitable for
+ finding the similarity for parts of words.
+ </p><div class="table" id="PGTRGM-OP-TABLE"><p class="title"><strong>Table F.25. <code class="filename">pg_trgm</code> Operators</strong></p><div class="table-contents"><table class="table" summary="pg_trgm Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">%</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns <code class="literal">true</code> if its arguments have a similarity
+ that is greater than the current similarity threshold set by
+ <code class="varname">pg_trgm.similarity_threshold</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;%</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns <code class="literal">true</code> if the similarity between the trigram
+ set in the first argument and a continuous extent of an ordered trigram
+ set in the second argument is greater than the current word similarity
+ threshold set by <code class="varname">pg_trgm.word_similarity_threshold</code>
+ parameter.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">%&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Commutator of the <code class="literal">&lt;%</code> operator.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;&lt;%</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Returns <code class="literal">true</code> if its second argument has a continuous
+ extent of an ordered trigram set that matches word boundaries,
+ and its similarity to the trigram set of the first argument is greater
+ than the current strict word similarity threshold set by the
+ <code class="varname">pg_trgm.strict_word_similarity_threshold</code> parameter.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">%&gt;&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Commutator of the <code class="literal">&lt;&lt;%</code> operator.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;-&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Returns the <span class="quote">“<span class="quote">distance</span>”</span> between the arguments, that is
+ one minus the <code class="function">similarity()</code> value.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;&lt;-&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Returns the <span class="quote">“<span class="quote">distance</span>”</span> between the arguments, that is
+ one minus the <code class="function">word_similarity()</code> value.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;-&gt;&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Commutator of the <code class="literal">&lt;&lt;-&gt;</code> operator.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;&lt;&lt;-&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Returns the <span class="quote">“<span class="quote">distance</span>”</span> between the arguments, that is
+ one minus the <code class="function">strict_word_similarity()</code> value.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">text</code> <code class="literal">&lt;-&gt;&gt;&gt;</code> <code class="type">text</code>
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Commutator of the <code class="literal">&lt;&lt;&lt;-&gt;</code> operator.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.44.7"><div class="titlepage"><div><div><h3 class="title">F.35.3. GUC Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-PGTRGM-SIMILARITY-THRESHOLD"><span class="term">
+ <code class="varname">pg_trgm.similarity_threshold</code> (<code class="type">real</code>)
+ <a id="id-1.11.7.44.7.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the current similarity threshold that is used by the <code class="literal">%</code>
+ operator. The threshold must be between 0 and 1 (default is 0.3).
+ </p></dd><dt id="GUC-PGTRGM-WORD-SIMILARITY-THRESHOLD"><span class="term">
+ <code class="varname">pg_trgm.word_similarity_threshold</code> (<code class="type">real</code>)
+ <a id="id-1.11.7.44.7.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the current word similarity threshold that is used by the
+ <code class="literal">&lt;%</code> and <code class="literal">%&gt;</code> operators. The threshold
+ must be between 0 and 1 (default is 0.6).
+ </p></dd><dt id="GUC-PGTRGM-STRICT-WORD-SIMILARITY-THRESHOLD"><span class="term">
+ <code class="varname">pg_trgm.strict_word_similarity_threshold</code> (<code class="type">real</code>)
+ <a id="id-1.11.7.44.7.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the current strict word similarity threshold that is used by the
+ <code class="literal">&lt;&lt;%</code> and <code class="literal">%&gt;&gt;</code> operators. The threshold
+ must be between 0 and 1 (default is 0.5).
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.44.8"><div class="titlepage"><div><div><h3 class="title">F.35.4. Index Support</h3></div></div></div><p>
+ The <code class="filename">pg_trgm</code> module provides GiST and GIN index
+ operator classes that allow you to create an index over a text column for
+ the purpose of very fast similarity searches. These index types support
+ the above-described similarity operators, and additionally support
+ trigram-based index searches for <code class="literal">LIKE</code>, <code class="literal">ILIKE</code>,
+ <code class="literal">~</code>, <code class="literal">~*</code> and <code class="literal">=</code> queries.
+ Inequality operators are not supported.
+ Note that those indexes may not be as efficient as regular B-tree indexes
+ for equality operator.
+ </p><p>
+ Example:
+
+</p><pre class="programlisting">
+CREATE TABLE test_trgm (t text);
+CREATE INDEX trgm_idx ON test_trgm USING GIST (t gist_trgm_ops);
+</pre><p>
+or
+</p><pre class="programlisting">
+CREATE INDEX trgm_idx ON test_trgm USING GIN (t gin_trgm_ops);
+</pre><p>
+ </p><p>
+ <code class="literal">gist_trgm_ops</code> GiST opclass approximates a set of
+ trigrams as a bitmap signature. Its optional integer parameter
+ <code class="literal">siglen</code> determines the
+ signature length in bytes. The default length is 12 bytes.
+ Valid values of signature length are between 1 and 2024 bytes. Longer
+ signatures lead to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </p><p>
+ Example of creating such an index with a signature length of 32 bytes:
+ </p><pre class="programlisting">
+CREATE INDEX trgm_idx ON test_trgm USING GIST (t gist_trgm_ops(siglen=32));
+</pre><p>
+ At this point, you will have an index on the <code class="structfield">t</code> column that
+ you can use for similarity searching. A typical query is
+</p><pre class="programlisting">
+SELECT t, similarity(t, '<em class="replaceable"><code>word</code></em>') AS sml
+ FROM test_trgm
+ WHERE t % '<em class="replaceable"><code>word</code></em>'
+ ORDER BY sml DESC, t;
+</pre><p>
+ This will return all values in the text column that are sufficiently
+ similar to <em class="replaceable"><code>word</code></em>, sorted from best match to worst. The
+ index will be used to make this a fast operation even over very large data
+ sets.
+ </p><p>
+ A variant of the above query is
+</p><pre class="programlisting">
+SELECT t, t &lt;-&gt; '<em class="replaceable"><code>word</code></em>' AS dist
+ FROM test_trgm
+ ORDER BY dist LIMIT 10;
+</pre><p>
+ This can be implemented quite efficiently by GiST indexes, but not
+ by GIN indexes. It will usually beat the first formulation when only
+ a small number of the closest matches is wanted.
+ </p><p>
+ Also you can use an index on the <code class="structfield">t</code> column for word
+ similarity or strict word similarity. Typical queries are:
+</p><pre class="programlisting">
+SELECT t, word_similarity('<em class="replaceable"><code>word</code></em>', t) AS sml
+ FROM test_trgm
+ WHERE '<em class="replaceable"><code>word</code></em>' &lt;% t
+ ORDER BY sml DESC, t;
+</pre><p>
+ and
+</p><pre class="programlisting">
+SELECT t, strict_word_similarity('<em class="replaceable"><code>word</code></em>', t) AS sml
+ FROM test_trgm
+ WHERE '<em class="replaceable"><code>word</code></em>' &lt;&lt;% t
+ ORDER BY sml DESC, t;
+</pre><p>
+ This will return all values in the text column for which there is a
+ continuous extent in the corresponding ordered trigram set that is
+ sufficiently similar to the trigram set of <em class="replaceable"><code>word</code></em>,
+ sorted from best match to worst. The index will be used to make this
+ a fast operation even over very large data sets.
+ </p><p>
+ Possible variants of the above queries are:
+</p><pre class="programlisting">
+SELECT t, '<em class="replaceable"><code>word</code></em>' &lt;&lt;-&gt; t AS dist
+ FROM test_trgm
+ ORDER BY dist LIMIT 10;
+</pre><p>
+ and
+</p><pre class="programlisting">
+SELECT t, '<em class="replaceable"><code>word</code></em>' &lt;&lt;&lt;-&gt; t AS dist
+ FROM test_trgm
+ ORDER BY dist LIMIT 10;
+</pre><p>
+ This can be implemented quite efficiently by GiST indexes, but not
+ by GIN indexes.
+ </p><p>
+ Beginning in <span class="productname">PostgreSQL</span> 9.1, these index types also support
+ index searches for <code class="literal">LIKE</code> and <code class="literal">ILIKE</code>, for example
+</p><pre class="programlisting">
+SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';
+</pre><p>
+ The index search works by extracting trigrams from the search string
+ and then looking these up in the index. The more trigrams in the search
+ string, the more effective the index search is. Unlike B-tree based
+ searches, the search string need not be left-anchored.
+ </p><p>
+ Beginning in <span class="productname">PostgreSQL</span> 9.3, these index types also support
+ index searches for regular-expression matches
+ (<code class="literal">~</code> and <code class="literal">~*</code> operators), for example
+</p><pre class="programlisting">
+SELECT * FROM test_trgm WHERE t ~ '(foo|bar)';
+</pre><p>
+ The index search works by extracting trigrams from the regular expression
+ and then looking these up in the index. The more trigrams that can be
+ extracted from the regular expression, the more effective the index search
+ is. Unlike B-tree based searches, the search string need not be
+ left-anchored.
+ </p><p>
+ For both <code class="literal">LIKE</code> and regular-expression searches, keep in mind
+ that a pattern with no extractable trigrams will degenerate to a full-index
+ scan.
+ </p><p>
+ The choice between GiST and GIN indexing depends on the relative
+ performance characteristics of GiST and GIN, which are discussed elsewhere.
+ </p></div><div class="sect2" id="id-1.11.7.44.9"><div class="titlepage"><div><div><h3 class="title">F.35.5. Text Search Integration</h3></div></div></div><p>
+ Trigram matching is a very useful tool when used in conjunction
+ with a full text index. In particular it can help to recognize
+ misspelled input words that will not be matched directly by the
+ full text search mechanism.
+ </p><p>
+ The first step is to generate an auxiliary table containing all
+ the unique words in the documents:
+
+</p><pre class="programlisting">
+CREATE TABLE words AS SELECT word FROM
+ ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
+</pre><p>
+
+ where <code class="structname">documents</code> is a table that has a text field
+ <code class="structfield">bodytext</code> that we wish to search. The reason for using
+ the <code class="literal">simple</code> configuration with the <code class="function">to_tsvector</code>
+ function, instead of using a language-specific configuration,
+ is that we want a list of the original (unstemmed) words.
+ </p><p>
+ Next, create a trigram index on the word column:
+
+</p><pre class="programlisting">
+CREATE INDEX words_idx ON words USING GIN (word gin_trgm_ops);
+</pre><p>
+
+ Now, a <code class="command">SELECT</code> query similar to the previous example can
+ be used to suggest spellings for misspelled words in user search terms.
+ A useful extra test is to require that the selected words are also of
+ similar length to the misspelled word.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Since the <code class="structname">words</code> table has been generated as a separate,
+ static table, it will need to be periodically regenerated so that
+ it remains reasonably up-to-date with the document collection.
+ Keeping it exactly current is usually unnecessary.
+ </p></div></div><div class="sect2" id="id-1.11.7.44.10"><div class="titlepage"><div><div><h3 class="title">F.35.6. References</h3></div></div></div><p>
+ GiST Development Site
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/" target="_top">http://www.sai.msu.su/~megera/postgres/gist/</a>
+ </p><p>
+ Tsearch2 Development Site
+ <a class="ulink" href="http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/" target="_top">http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/</a>
+ </p></div><div class="sect2" id="id-1.11.7.44.11"><div class="titlepage"><div><div><h3 class="title">F.35.7. Authors</h3></div></div></div><p>
+ Oleg Bartunov <code class="email">&lt;<a class="email" href="mailto:oleg@sai.msu.su">oleg@sai.msu.su</a>&gt;</code>, Moscow, Moscow University, Russia
+ </p><p>
+ Teodor Sigaev <code class="email">&lt;<a class="email" href="mailto:teodor@sigaev.ru">teodor@sigaev.ru</a>&gt;</code>, Moscow, Delta-Soft Ltd.,Russia
+ </p><p>
+ Alexander Korotkov <code class="email">&lt;<a class="email" href="mailto:a.korotkov@postgrespro.ru">a.korotkov@postgrespro.ru</a>&gt;</code>, Moscow, Postgres Professional, Russia
+ </p><p>
+ Documentation: Christopher Kings-Lynne
+ </p><p>
+ This module is sponsored by Delta-Soft Ltd., Moscow, Russia.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgsurgery.html" title="F.34. pg_surgery">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgvisibility.html" title="F.36. pg_visibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.34. pg_surgery </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.36. pg_visibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgupgrade.html b/doc/src/sgml/html/pgupgrade.html
new file mode 100644
index 0000000..f0cd2e1
--- /dev/null
+++ b/doc/src/sgml/html/pgupgrade.html
@@ -0,0 +1,434 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_upgrade</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgtesttiming.html" title="pg_test_timing" /><link rel="next" href="pgwaldump.html" title="pg_waldump" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_upgrade</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgtesttiming.html" title="pg_test_timing">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgwaldump.html" title="pg_waldump">Next</a></td></tr></table><hr /></div><div class="refentry" id="PGUPGRADE"><div class="titlepage"></div><a id="id-1.9.5.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_upgrade</span></span></h2><p>pg_upgrade — upgrade a <span class="productname">PostgreSQL</span> server instance</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.12.4.1"><code class="command">pg_upgrade</code> <code class="option">-b</code> <em class="replaceable"><code>oldbindir</code></em> [<code class="option">-B</code> <em class="replaceable"><code>newbindir</code></em>] <code class="option">-d</code> <em class="replaceable"><code>oldconfigdir</code></em> <code class="option">-D</code> <em class="replaceable"><code>newconfigdir</code></em> [<em class="replaceable"><code>option</code></em>...]</p></div></div><div class="refsect1" id="id-1.9.5.12.5"><h2>Description</h2><p>
+ <span class="application">pg_upgrade</span> (formerly called <span class="application">pg_migrator</span>) allows data
+ stored in <span class="productname">PostgreSQL</span> data files to be upgraded to a later <span class="productname">PostgreSQL</span>
+ major version without the data dump/restore typically required for
+ major version upgrades, e.g., from 9.5.8 to 9.6.4 or from 10.7 to 11.2.
+ It is not required for minor version upgrades, e.g., from 9.6.2 to 9.6.3
+ or from 10.1 to 10.2.
+ </p><p>
+ Major PostgreSQL releases regularly add new features that often
+ change the layout of the system tables, but the internal data storage
+ format rarely changes. <span class="application">pg_upgrade</span> uses this fact
+ to perform rapid upgrades by creating new system tables and simply
+ reusing the old user data files. If a future major release ever
+ changes the data storage format in a way that makes the old data
+ format unreadable, <span class="application">pg_upgrade</span> will not be usable
+ for such upgrades. (The community will attempt to avoid such
+ situations.)
+ </p><p>
+ <span class="application">pg_upgrade</span> does its best to
+ make sure the old and new clusters are binary-compatible, e.g., by
+ checking for compatible compile-time settings, including 32/64-bit
+ binaries. It is important that
+ any external modules are also binary compatible, though this cannot
+ be checked by <span class="application">pg_upgrade</span>.
+ </p><p>
+ pg_upgrade supports upgrades from 9.2.X and later to the current
+ major release of <span class="productname">PostgreSQL</span>, including snapshot and beta releases.
+ </p></div><div class="refsect1" id="id-1.9.5.12.6"><h2>Options</h2><p>
+ <span class="application">pg_upgrade</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-b</code> <em class="replaceable"><code>bindir</code></em><br /></span><span class="term"><code class="option">--old-bindir=</code><em class="replaceable"><code>bindir</code></em></span></dt><dd><p>the old PostgreSQL executable directory;
+ environment variable <code class="envar">PGBINOLD</code></p></dd><dt><span class="term"><code class="option">-B</code> <em class="replaceable"><code>bindir</code></em><br /></span><span class="term"><code class="option">--new-bindir=</code><em class="replaceable"><code>bindir</code></em></span></dt><dd><p>the new PostgreSQL executable directory;
+ default is the directory where <span class="application">pg_upgrade</span> resides;
+ environment variable <code class="envar">PGBINNEW</code></p></dd><dt><span class="term"><code class="option">-c</code><br /></span><span class="term"><code class="option">--check</code></span></dt><dd><p>check clusters only, don't change any data</p></dd><dt><span class="term"><code class="option">-d</code> <em class="replaceable"><code>configdir</code></em><br /></span><span class="term"><code class="option">--old-datadir=</code><em class="replaceable"><code>configdir</code></em></span></dt><dd><p>the old database cluster configuration directory; environment
+ variable <code class="envar">PGDATAOLD</code></p></dd><dt><span class="term"><code class="option">-D</code> <em class="replaceable"><code>configdir</code></em><br /></span><span class="term"><code class="option">--new-datadir=</code><em class="replaceable"><code>configdir</code></em></span></dt><dd><p>the new database cluster configuration directory; environment
+ variable <code class="envar">PGDATANEW</code></p></dd><dt><span class="term"><code class="option">-j <em class="replaceable"><code>njobs</code></em></code><br /></span><span class="term"><code class="option">--jobs=<em class="replaceable"><code>njobs</code></em></code></span></dt><dd><p>number of simultaneous processes or threads to use
+ </p></dd><dt><span class="term"><code class="option">-k</code><br /></span><span class="term"><code class="option">--link</code></span></dt><dd><p>use hard links instead of copying files to the new
+ cluster</p></dd><dt><span class="term"><code class="option">-N</code><br /></span><span class="term"><code class="option">--no-sync</code></span></dt><dd><p>
+ By default, <code class="command">pg_upgrade</code> will wait for all files
+ of the upgraded cluster to be written safely to disk. This option
+ causes <code class="command">pg_upgrade</code> to return without waiting, which
+ is faster, but means that a subsequent operating system crash can leave
+ the data directory corrupt. Generally, this option is
+ useful for testing but should not be used on a production
+ installation.
+ </p></dd><dt><span class="term"><code class="option">-o</code> <em class="replaceable"><code>options</code></em><br /></span><span class="term"><code class="option">--old-options</code> <em class="replaceable"><code>options</code></em></span></dt><dd><p>options to be passed directly to the
+ old <code class="command">postgres</code> command; multiple
+ option invocations are appended</p></dd><dt><span class="term"><code class="option">-O</code> <em class="replaceable"><code>options</code></em><br /></span><span class="term"><code class="option">--new-options</code> <em class="replaceable"><code>options</code></em></span></dt><dd><p>options to be passed directly to the
+ new <code class="command">postgres</code> command; multiple
+ option invocations are appended</p></dd><dt><span class="term"><code class="option">-p</code> <em class="replaceable"><code>port</code></em><br /></span><span class="term"><code class="option">--old-port=</code><em class="replaceable"><code>port</code></em></span></dt><dd><p>the old cluster port number; environment
+ variable <code class="envar">PGPORTOLD</code></p></dd><dt><span class="term"><code class="option">-P</code> <em class="replaceable"><code>port</code></em><br /></span><span class="term"><code class="option">--new-port=</code><em class="replaceable"><code>port</code></em></span></dt><dd><p>the new cluster port number; environment
+ variable <code class="envar">PGPORTNEW</code></p></dd><dt><span class="term"><code class="option">-r</code><br /></span><span class="term"><code class="option">--retain</code></span></dt><dd><p>retain SQL and log files even after successful completion
+ </p></dd><dt><span class="term"><code class="option">-s</code> <em class="replaceable"><code>dir</code></em><br /></span><span class="term"><code class="option">--socketdir=</code><em class="replaceable"><code>dir</code></em></span></dt><dd><p>directory to use for postmaster sockets during upgrade;
+ default is current working directory; environment
+ variable <code class="envar">PGSOCKETDIR</code></p></dd><dt><span class="term"><code class="option">-U</code> <em class="replaceable"><code>username</code></em><br /></span><span class="term"><code class="option">--username=</code><em class="replaceable"><code>username</code></em></span></dt><dd><p>cluster's install user name; environment
+ variable <code class="envar">PGUSER</code></p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>enable verbose internal logging</p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>display version information, then exit</p></dd><dt><span class="term"><code class="option">--clone</code></span></dt><dd><p>
+ Use efficient file cloning (also known as <span class="quote">“<span class="quote">reflinks</span>”</span> on
+ some systems) instead of copying files to the new cluster. This can
+ result in near-instantaneous copying of the data files, giving the
+ speed advantages of <code class="option">-k</code>/<code class="option">--link</code> while
+ leaving the old cluster untouched.
+ </p><p>
+ File cloning is only supported on some operating systems and file
+ systems. If it is selected but not supported, the
+ <span class="application">pg_upgrade</span> run will error. At present, it
+ is supported on Linux (kernel 4.5 or later) with Btrfs and XFS (on
+ file systems created with reflink support), and on macOS with APFS.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>show help, then exit</p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.12.7"><h2>Usage</h2><p>
+ These are the steps to perform an upgrade
+ with <span class="application">pg_upgrade</span>:
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p class="title"><strong>Optionally move the old cluster</strong></p><p>
+ If you are using a version-specific installation directory, e.g.,
+ <code class="filename">/opt/PostgreSQL/15</code>, you do not need to move the old cluster. The
+ graphical installers all use version-specific installation directories.
+ </p><p>
+ If your installation directory is not version-specific, e.g.,
+ <code class="filename">/usr/local/pgsql</code>, it is necessary to move the current PostgreSQL install
+ directory so it does not interfere with the new <span class="productname">PostgreSQL</span> installation.
+ Once the current <span class="productname">PostgreSQL</span> server is shut down, it is safe to rename the
+ PostgreSQL installation directory; assuming the old directory is
+ <code class="filename">/usr/local/pgsql</code>, you can do:
+
+</p><pre class="programlisting">
+mv /usr/local/pgsql /usr/local/pgsql.old
+</pre><p>
+ to rename the directory.
+ </p></li><li class="step"><p class="title"><strong>For source installs, build the new version</strong></p><p>
+ Build the new PostgreSQL source with <code class="command">configure</code> flags that are compatible
+ with the old cluster. <span class="application">pg_upgrade</span> will check <code class="command">pg_controldata</code> to make
+ sure all settings are compatible before starting the upgrade.
+ </p></li><li class="step"><p class="title"><strong>Install the new PostgreSQL binaries</strong></p><p>
+ Install the new server's binaries and support
+ files. <span class="application">pg_upgrade</span> is included in a default installation.
+ </p><p>
+ For source installs, if you wish to install the new server in a custom
+ location, use the <code class="literal">prefix</code> variable:
+
+</p><pre class="programlisting">
+make prefix=/usr/local/pgsql.new install
+</pre></li><li class="step"><p class="title"><strong>Initialize the new PostgreSQL cluster</strong></p><p>
+ Initialize the new cluster using <code class="command">initdb</code>.
+ Again, use compatible <code class="command">initdb</code>
+ flags that match the old cluster. Many
+ prebuilt installers do this step automatically. There is no need to
+ start the new cluster.
+ </p></li><li class="step"><p class="title"><strong>Install extension shared object files</strong></p><p>
+ Many extensions and custom modules, whether from
+ <code class="filename">contrib</code> or another source, use shared object
+ files (or DLLs), e.g., <code class="filename">pgcrypto.so</code>. If the old
+ cluster used these, shared object files matching the new server binary
+ must be installed in the new cluster, usually via operating system
+ commands. Do not load the schema definitions, e.g., <code class="command">CREATE
+ EXTENSION pgcrypto</code>, because these will be duplicated from
+ the old cluster. If extension updates are available,
+ <span class="application">pg_upgrade</span> will report this and create
+ a script that can be run later to update them.
+ </p></li><li class="step"><p class="title"><strong>Copy custom full-text search files</strong></p><p>
+ Copy any custom full text search files (dictionary, synonym,
+ thesaurus, stop words) from the old to the new cluster.
+ </p></li><li class="step"><p class="title"><strong>Adjust authentication</strong></p><p>
+ <code class="command">pg_upgrade</code> will connect to the old and new servers several
+ times, so you might want to set authentication to <code class="literal">peer</code>
+ in <code class="filename">pg_hba.conf</code> or use a <code class="filename">~/.pgpass</code> file
+ (see <a class="xref" href="libpq-pgpass.html" title="34.16. The Password File">Section 34.16</a>).
+ </p></li><li class="step"><p class="title"><strong>Stop both servers</strong></p><p>
+ Make sure both database servers are stopped using, on Unix, e.g.:
+
+</p><pre class="programlisting">
+pg_ctl -D /opt/PostgreSQL/9.6 stop
+pg_ctl -D /opt/PostgreSQL/15 stop
+</pre><p>
+
+ or on Windows, using the proper service names:
+
+</p><pre class="programlisting">
+NET STOP postgresql-9.6
+NET STOP postgresql-15
+</pre><p>
+ </p><p>
+ Streaming replication and log-shipping standby servers can
+ remain running until a later step.
+ </p></li><li class="step"><p class="title"><strong>Prepare for standby server upgrades</strong></p><p>
+ If you are upgrading standby servers using methods outlined in section <a class="xref" href="pgupgrade.html#PGUPGRADE-STEP-REPLICAS" title="Upgrade streaming replication and log-shipping standby servers">Step 11</a>, verify that the old standby
+ servers are caught up by running <span class="application">pg_controldata</span>
+ against the old primary and standby clusters. Verify that the
+ <span class="quote">“<span class="quote">Latest checkpoint location</span>”</span> values match in all clusters.
+ (There will be a mismatch if old standby servers were shut down
+ before the old primary or if the old standby servers are still running.)
+ Also, make sure <code class="varname">wal_level</code> is not set to
+ <code class="literal">minimal</code> in the <code class="filename">postgresql.conf</code> file on the
+ new primary cluster.
+ </p></li><li class="step"><p class="title"><strong>Run <span class="application">pg_upgrade</span></strong></p><p>
+ Always run the <span class="application">pg_upgrade</span> binary of the new server, not the old one.
+ <span class="application">pg_upgrade</span> requires the specification of the old and new cluster's
+ data and executable (<code class="filename">bin</code>) directories. You can also specify
+ user and port values, and whether you want the data files linked or cloned
+ instead of the default copy behavior.
+ </p><p>
+ If you use link mode, the upgrade will be much faster (no file
+ copying) and use less disk space, but you will not be able to access
+ your old cluster
+ once you start the new cluster after the upgrade. Link mode also
+ requires that the old and new cluster data directories be in the
+ same file system. (Tablespaces and <code class="filename">pg_wal</code> can be on
+ different file systems.)
+ Clone mode provides the same speed and disk space advantages but
+ does not cause the old cluster to be unusable once the new cluster
+ is started. Clone mode also requires that the old and new data
+ directories be in the same file system. This mode is only available
+ on certain operating systems and file systems.
+ </p><p>
+ The <code class="option">--jobs</code> option allows multiple CPU cores to be used
+ for copying/linking of files and to dump and restore database schemas
+ in parallel; a good place to start is the maximum of the number of
+ CPU cores and tablespaces. This option can dramatically reduce the
+ time to upgrade a multi-database server running on a multiprocessor
+ machine.
+ </p><p>
+ For Windows users, you must be logged into an administrative account, and
+ then start a shell as the <code class="literal">postgres</code> user and set the proper path:
+
+</p><pre class="programlisting">
+RUNAS /USER:postgres "CMD.EXE"
+SET PATH=%PATH%;C:\Program Files\PostgreSQL\15\bin;
+</pre><p>
+
+ and then run <span class="application">pg_upgrade</span> with quoted directories, e.g.:
+
+</p><pre class="programlisting">
+pg_upgrade.exe
+ --old-datadir "C:/Program Files/PostgreSQL/9.6/data"
+ --new-datadir "C:/Program Files/PostgreSQL/15/data"
+ --old-bindir "C:/Program Files/PostgreSQL/9.6/bin"
+ --new-bindir "C:/Program Files/PostgreSQL/15/bin"
+</pre><p>
+
+ Once started, <code class="command">pg_upgrade</code> will verify the two clusters are compatible
+ and then do the upgrade. You can use <code class="command">pg_upgrade --check</code>
+ to perform only the checks, even if the old server is still
+ running. <code class="command">pg_upgrade --check</code> will also outline any
+ manual adjustments you will need to make after the upgrade. If you
+ are going to be using link or clone mode, you should use the option
+ <code class="option">--link</code> or <code class="option">--clone</code> with
+ <code class="option">--check</code> to enable mode-specific checks.
+ <code class="command">pg_upgrade</code> requires write permission in the current directory.
+ </p><p>
+ Obviously, no one should be accessing the clusters during the
+ upgrade. <span class="application">pg_upgrade</span> defaults to running servers
+ on port 50432 to avoid unintended client connections.
+ You can use the same port number for both clusters when doing an
+ upgrade because the old and new clusters will not be running at the
+ same time. However, when checking an old running server, the old
+ and new port numbers must be different.
+ </p><p>
+ If an error occurs while restoring the database schema, <code class="command">pg_upgrade</code> will
+ exit and you will have to revert to the old cluster as outlined in <a class="xref" href="pgupgrade.html#PGUPGRADE-STEP-REVERT" title="Reverting to old cluster">Step 17</a>
+ below. To try <code class="command">pg_upgrade</code> again, you will need to modify the old
+ cluster so the pg_upgrade schema restore succeeds. If the problem is a
+ <code class="filename">contrib</code> module, you might need to uninstall the <code class="filename">contrib</code> module from
+ the old cluster and install it in the new cluster after the upgrade,
+ assuming the module is not being used to store user data.
+ </p></li><li class="step" id="PGUPGRADE-STEP-REPLICAS"><p class="title"><strong>Upgrade streaming replication and log-shipping standby servers</strong></p><p>
+ If you used link mode and have Streaming Replication (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>) or Log-Shipping (see <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>) standby servers, you can follow these steps to
+ quickly upgrade them. You will not be running <span class="application">pg_upgrade</span> on
+ the standby servers, but rather <span class="application">rsync</span> on the primary.
+ Do not start any servers yet.
+ </p><p>
+ If you did <span class="emphasis"><em>not</em></span> use link mode, do not have or do not
+ want to use <span class="application">rsync</span>, or want an easier solution, skip
+ the instructions in this section and simply recreate the standby
+ servers once <span class="application">pg_upgrade</span> completes and the new primary
+ is running.
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p class="title"><strong>Install the new PostgreSQL binaries on standby servers</strong></p><p>
+ Make sure the new binaries and support files are installed on all
+ standby servers.
+ </p></li><li class="step"><p class="title"><strong>Make sure the new standby data directories do <span class="emphasis"><em>not</em></span> exist</strong></p><p>
+ Make sure the new standby data directories do <span class="emphasis"><em>not</em></span>
+ exist or are empty. If <span class="application">initdb</span> was run, delete
+ the standby servers' new data directories.
+ </p></li><li class="step"><p class="title"><strong>Install extension shared object files</strong></p><p>
+ Install the same extension shared object files on the new standbys
+ that you installed in the new primary cluster.
+ </p></li><li class="step"><p class="title"><strong>Stop standby servers</strong></p><p>
+ If the standby servers are still running, stop them now using the
+ above instructions.
+ </p></li><li class="step"><p class="title"><strong>Save configuration files</strong></p><p>
+ Save any configuration files from the old standbys' configuration
+ directories you need to keep, e.g., <code class="filename">postgresql.conf</code>
+ (and any files included by it), <code class="filename">postgresql.auto.conf</code>,
+ <code class="literal">pg_hba.conf</code>, because these will be overwritten
+ or removed in the next step.
+ </p></li><li class="step"><p class="title"><strong>Run <span class="application">rsync</span></strong></p><p>
+ When using link mode, standby servers can be quickly upgraded using
+ <span class="application">rsync</span>. To accomplish this, from a directory on
+ the primary server that is above the old and new database cluster
+ directories, run this on the <span class="emphasis"><em>primary</em></span> for each standby
+ server:
+
+</p><pre class="programlisting">
+rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir
+</pre><p>
+
+ where <code class="option">old_cluster</code> and <code class="option">new_cluster</code> are relative
+ to the current directory on the primary, and <code class="option">remote_dir</code>
+ is <span class="emphasis"><em>above</em></span> the old and new cluster directories
+ on the standby. The directory structure under the specified
+ directories on the primary and standbys must match. Consult the
+ <span class="application">rsync</span> manual page for details on specifying the
+ remote directory, e.g.,
+
+</p><pre class="programlisting">
+rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \
+ /opt/PostgreSQL/9.6 standby.example.com:/opt/PostgreSQL
+</pre><p>
+
+ You can verify what the command will do using
+ <span class="application">rsync</span>'s <code class="option">--dry-run</code> option. While
+ <span class="application">rsync</span> must be run on the primary for at least one
+ standby, it is possible to run <span class="application">rsync</span> on an upgraded
+ standby to upgrade other standbys, as long as the upgraded standby
+ has not been started.
+ </p><p>
+ What this does is to record the links created by
+ <span class="application">pg_upgrade</span>'s link mode that connect files in the
+ old and new clusters on the primary server. It then finds matching
+ files in the standby's old cluster and creates links for them in the
+ standby's new cluster. Files that were not linked on the primary
+ are copied from the primary to the standby. (They are usually
+ small.) This provides rapid standby upgrades. Unfortunately,
+ <span class="application">rsync</span> needlessly copies files associated with
+ temporary and unlogged tables because these files don't normally
+ exist on standby servers.
+ </p><p>
+ If you have tablespaces, you will need to run a similar
+ <span class="application">rsync</span> command for each tablespace directory, e.g.:
+
+</p><pre class="programlisting">
+rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_9.5_201510051 \
+ /vol1/pg_tblsp/PG_9.6_201608131 standby.example.com:/vol1/pg_tblsp
+</pre><p>
+
+ If you have relocated <code class="filename">pg_wal</code> outside the data
+ directories, <span class="application">rsync</span> must be run on those directories
+ too.
+ </p></li><li class="step"><p class="title"><strong>Configure streaming replication and log-shipping standby servers</strong></p><p>
+ Configure the servers for log shipping. (You do not need to run
+ <code class="function">pg_backup_start()</code> and <code class="function">pg_backup_stop()</code>
+ or take a file system backup as the standbys are still synchronized
+ with the primary.) Replication slots are not copied and must
+ be recreated.
+ </p></li></ol></div></li><li class="step"><p class="title"><strong>Restore <code class="filename">pg_hba.conf</code></strong></p><p>
+ If you modified <code class="filename">pg_hba.conf</code>, restore its original settings.
+ It might also be necessary to adjust other configuration files in the new
+ cluster to match the old cluster, e.g., <code class="filename">postgresql.conf</code>
+ (and any files included by it), <code class="filename">postgresql.auto.conf</code>.
+ </p></li><li class="step"><p class="title"><strong>Start the new server</strong></p><p>
+ The new server can now be safely started, and then any
+ <span class="application">rsync</span>'ed standby servers.
+ </p></li><li class="step"><p class="title"><strong>Post-upgrade processing</strong></p><p>
+ If any post-upgrade processing is required, pg_upgrade will issue
+ warnings as it completes. It will also generate script files that must
+ be run by the administrator. The script files will connect to each
+ database that needs post-upgrade processing. Each script should be
+ run using:
+
+</p><pre class="programlisting">
+psql --username=postgres --file=script.sql postgres
+</pre><p>
+
+ The scripts can be run in any order and can be deleted once they have
+ been run.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ In general it is unsafe to access tables referenced in rebuild scripts
+ until the rebuild scripts have run to completion; doing so could yield
+ incorrect results or poor performance. Tables not referenced in rebuild
+ scripts can be accessed immediately.
+ </p></div></li><li class="step"><p class="title"><strong>Statistics</strong></p><p>
+ Because optimizer statistics are not transferred by <code class="command">pg_upgrade</code>, you will
+ be instructed to run a command to regenerate that information at the end
+ of the upgrade. You might need to set connection parameters to
+ match your new cluster.
+ </p></li><li class="step"><p class="title"><strong>Delete old cluster</strong></p><p>
+ Once you are satisfied with the upgrade, you can delete the old
+ cluster's data directories by running the script mentioned when
+ <code class="command">pg_upgrade</code> completes. (Automatic deletion is not
+ possible if you have user-defined tablespaces inside the old data
+ directory.) You can also delete the old installation directories
+ (e.g., <code class="filename">bin</code>, <code class="filename">share</code>).
+ </p></li><li class="step" id="PGUPGRADE-STEP-REVERT"><p class="title"><strong>Reverting to old cluster</strong></p><p>
+ If, after running <code class="command">pg_upgrade</code>, you wish to revert to the old cluster,
+ there are several options:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If the <code class="option">--check</code> option was used, the old cluster
+ was unmodified; it can be restarted.
+ </p></li><li class="listitem"><p>
+ If the <code class="option">--link</code> option was <span class="emphasis"><em>not</em></span>
+ used, the old cluster was unmodified; it can be restarted.
+ </p></li><li class="listitem"><p>
+ If the <code class="option">--link</code> option was used, the data
+ files might be shared between the old and new cluster:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ If <code class="command">pg_upgrade</code> aborted before linking started,
+ the old cluster was unmodified; it can be restarted.
+ </p></li><li class="listitem"><p>
+ If you did <span class="emphasis"><em>not</em></span> start the new cluster, the old
+ cluster was unmodified except that, when linking started, a
+ <code class="literal">.old</code> suffix was appended to
+ <code class="filename">$PGDATA/global/pg_control</code>. To reuse the old
+ cluster, remove the <code class="filename">.old</code> suffix from
+ <code class="filename">$PGDATA/global/pg_control</code>; you can then restart
+ the old cluster.
+ </p></li><li class="listitem"><p>
+ If you did start the new cluster, it has written to shared files
+ and it is unsafe to use the old cluster. The old cluster will
+ need to be restored from backup in this case.
+ </p></li></ul></div></li></ul></div></li></ol></div></div><div class="refsect1" id="id-1.9.5.12.8"><h2>Notes</h2><p>
+ <span class="application">pg_upgrade</span> creates various working files, such
+ as schema dumps, stored within <code class="filename">pg_upgrade_output.d</code> in
+ the directory of the new cluster. Each run creates a new subdirectory named
+ with a timestamp formatted as per ISO 8601
+ (<code class="literal">%Y%m%dT%H%M%S</code>), where all its generated files are
+ stored.
+ <code class="filename">pg_upgrade_output.d</code> and its contained files will be
+ removed automatically if <span class="application">pg_upgrade</span> completes
+ successfully; but in the event of trouble, the files there may provide
+ useful debugging information.
+ </p><p>
+ <span class="application">pg_upgrade</span> launches short-lived postmasters in
+ the old and new data directories. Temporary Unix socket files for
+ communication with these postmasters are, by default, made in the current
+ working directory. In some situations the path name for the current
+ directory might be too long to be a valid socket name. In that case you
+ can use the <code class="option">-s</code> option to put the socket files in some
+ directory with a shorter path name. For security, be sure that that
+ directory is not readable or writable by any other users.
+ (This is not supported on Windows.)
+ </p><p>
+ All failure, rebuild, and reindex cases will be reported by
+ <span class="application">pg_upgrade</span> if they affect your installation;
+ post-upgrade scripts to rebuild tables and indexes will be
+ generated automatically. If you are trying to automate the upgrade
+ of many clusters, you should find that clusters with identical database
+ schemas require the same post-upgrade steps for all cluster upgrades;
+ this is because the post-upgrade steps are based on the database
+ schemas, and not user data.
+ </p><p>
+ For deployment testing, create a schema-only copy of the old cluster,
+ insert dummy data, and upgrade that.
+ </p><p>
+ <span class="application">pg_upgrade</span> does not support upgrading of databases
+ containing table columns using these <code class="type">reg*</code> OID-referencing system data types:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="type">regcollation</code></td></tr><tr><td><code class="type">regconfig</code></td></tr><tr><td><code class="type">regdictionary</code></td></tr><tr><td><code class="type">regnamespace</code></td></tr><tr><td><code class="type">regoper</code></td></tr><tr><td><code class="type">regoperator</code></td></tr><tr><td><code class="type">regproc</code></td></tr><tr><td><code class="type">regprocedure</code></td></tr></table><p>
+ (<code class="type">regclass</code>, <code class="type">regrole</code>, and <code class="type">regtype</code> can be upgraded.)
+ </p><p>
+ If you want to use link mode and you do not want your old cluster
+ to be modified when the new cluster is started, consider using the clone mode.
+ If that is not available, make a copy of the
+ old cluster and upgrade that in link mode. To make a valid copy
+ of the old cluster, use <code class="command">rsync</code> to create a dirty
+ copy of the old cluster while the server is running, then shut down
+ the old server and run <code class="command">rsync --checksum</code> again to update the
+ copy with any changes to make it consistent. (<code class="option">--checksum</code>
+ is necessary because <code class="command">rsync</code> only has file modification-time
+ granularity of one second.) You might want to exclude some
+ files, e.g., <code class="filename">postmaster.pid</code>, as documented in <a class="xref" href="continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP" title="26.3.3. Making a Base Backup Using the Low Level API">Section 26.3.3</a>. If your file system supports
+ file system snapshots or copy-on-write file copies, you can use that
+ to make a backup of the old cluster and tablespaces, though the snapshot
+ and copies must be created simultaneously or while the database server
+ is down.
+ </p></div><div class="refsect1" id="id-1.9.5.12.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-initdb.html" title="initdb"><span class="refentrytitle"><span class="application">initdb</span></span></a>, <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a>, <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a>, <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgtesttiming.html" title="pg_test_timing">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgwaldump.html" title="pg_waldump">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_test_timing</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">pg_waldump</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgvisibility.html b/doc/src/sgml/html/pgvisibility.html
new file mode 100644
index 0000000..2b9157a
--- /dev/null
+++ b/doc/src/sgml/html/pgvisibility.html
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.36. pg_visibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgtrgm.html" title="F.35. pg_trgm" /><link rel="next" href="pgwalinspect.html" title="F.37. pg_walinspect" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.36. pg_visibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgtrgm.html" title="F.35. pg_trgm">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pgwalinspect.html" title="F.37. pg_walinspect">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGVISIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.36. pg_visibility</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgvisibility.html#id-1.11.7.45.6">F.36.1. Functions</a></span></dt><dt><span class="sect2"><a href="pgvisibility.html#id-1.11.7.45.7">F.36.2. Author</a></span></dt></dl></div><a id="id-1.11.7.45.2" class="indexterm"></a><p>
+ The <code class="filename">pg_visibility</code> module provides a means for examining the
+ visibility map (VM) and page-level visibility information of a table.
+ It also provides functions to check the integrity of a visibility map and to
+ force it to be rebuilt.
+ </p><p>
+ Three different bits are used to store information about page-level
+ visibility. The all-visible bit in the visibility map indicates that every
+ tuple in the corresponding page of the relation is visible to every current
+ and future transaction. The all-frozen bit in the visibility map indicates
+ that every tuple in the page is frozen; that is, no future vacuum will need
+ to modify the page until such time as a tuple is inserted, updated, deleted,
+ or locked on that page.
+ The page header's <code class="literal">PD_ALL_VISIBLE</code> bit has the
+ same meaning as the all-visible bit in the visibility map, but is stored
+ within the data page itself rather than in a separate data structure.
+ These two bits will normally agree, but the page's all-visible bit can
+ sometimes be set while the visibility map bit is clear after a crash
+ recovery. The reported values can also disagree because of a change that
+ occurs after <code class="literal">pg_visibility</code> examines the visibility map and
+ before it examines the data page. Any event that causes data corruption
+ can also cause these bits to disagree.
+ </p><p>
+ Functions that display information about <code class="literal">PD_ALL_VISIBLE</code> bits
+ are much more costly than those that only consult the visibility map,
+ because they must read the relation's data blocks rather than only the
+ (much smaller) visibility map. Functions that check the relation's
+ data blocks are similarly expensive.
+ </p><div class="sect2" id="id-1.11.7.45.6"><div class="titlepage"><div><div><h3 class="title">F.36.1. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">pg_visibility_map(relation regclass, blkno bigint, all_visible OUT boolean, all_frozen OUT boolean) returns record</code></span></dt><dd><p>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ the given block of the given relation.
+ </p></dd><dt><span class="term"><code class="function">pg_visibility(relation regclass, blkno bigint, all_visible OUT boolean, all_frozen OUT boolean, pd_all_visible OUT boolean) returns record</code></span></dt><dd><p>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ the given block of the given relation, plus the
+ <code class="literal">PD_ALL_VISIBLE</code> bit of that block.
+ </p></dd><dt><span class="term"><code class="function">pg_visibility_map(relation regclass, blkno OUT bigint, all_visible OUT boolean, all_frozen OUT boolean) returns setof record</code></span></dt><dd><p>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ each block of the given relation.
+ </p></dd><dt><span class="term"><code class="function">pg_visibility(relation regclass, blkno OUT bigint, all_visible OUT boolean, all_frozen OUT boolean, pd_all_visible OUT boolean) returns setof record</code></span></dt><dd><p>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ each block of the given relation, plus the <code class="literal">PD_ALL_VISIBLE</code>
+ bit of each block.
+ </p></dd><dt><span class="term"><code class="function">pg_visibility_map_summary(relation regclass, all_visible OUT bigint, all_frozen OUT bigint) returns record</code></span></dt><dd><p>
+ Returns the number of all-visible pages and the number of all-frozen
+ pages in the relation according to the visibility map.
+ </p></dd><dt><span class="term"><code class="function">pg_check_frozen(relation regclass, t_ctid OUT tid) returns setof tid</code></span></dt><dd><p>
+ Returns the TIDs of non-frozen tuples stored in pages marked all-frozen
+ in the visibility map. If this function returns a non-empty set of
+ TIDs, the visibility map is corrupt.
+ </p></dd><dt><span class="term"><code class="function">pg_check_visible(relation regclass, t_ctid OUT tid) returns setof tid</code></span></dt><dd><p>
+ Returns the TIDs of non-all-visible tuples stored in pages marked
+ all-visible in the visibility map. If this function returns a non-empty
+ set of TIDs, the visibility map is corrupt.
+ </p></dd><dt><span class="term"><code class="function">pg_truncate_visibility_map(relation regclass) returns void</code></span></dt><dd><p>
+ Truncates the visibility map for the given relation. This function is
+ useful if you believe that the visibility map for the relation is
+ corrupt and wish to force rebuilding it. The first <code class="command">VACUUM</code>
+ executed on the given relation after this function is executed will scan
+ every page in the relation and rebuild the visibility map. (Until that
+ is done, queries will treat the visibility map as containing all zeroes.)
+ </p></dd></dl></div><p>
+ By default, these functions are executable only by superusers and roles with privileges
+ of the <code class="literal">pg_stat_scan_tables</code> role, with the exception of
+ <code class="function">pg_truncate_visibility_map(relation regclass)</code> which can only
+ be executed by superusers.
+ </p></div><div class="sect2" id="id-1.11.7.45.7"><div class="titlepage"><div><div><h3 class="title">F.36.2. Author</h3></div></div></div><p>
+ Robert Haas <code class="email">&lt;<a class="email" href="mailto:rhaas@postgresql.org">rhaas@postgresql.org</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgtrgm.html" title="F.35. pg_trgm">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pgwalinspect.html" title="F.37. pg_walinspect">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.35. pg_trgm </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.37. pg_walinspect</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgwaldump.html b/doc/src/sgml/html/pgwaldump.html
new file mode 100644
index 0000000..e996584
--- /dev/null
+++ b/doc/src/sgml/html/pgwaldump.html
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>pg_waldump</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgupgrade.html" title="pg_upgrade" /><link rel="next" href="app-postgres.html" title="postgres" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">pg_waldump</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgupgrade.html" title="pg_upgrade">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><th width="60%" align="center">PostgreSQL Server Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-postgres.html" title="postgres">Next</a></td></tr></table><hr /></div><div class="refentry" id="PGWALDUMP"><div class="titlepage"></div><a id="id-1.9.5.13.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">pg_waldump</span></span></h2><p>pg_waldump — display a human-readable rendering of the write-ahead log of a <span class="productname">PostgreSQL</span> database cluster</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.9.5.13.4.1"><code class="command">pg_waldump</code> [<code class="option">option</code>...] [<code class="option">startseg</code> [<code class="option">endseg</code>]]</p></div></div><div class="refsect1" id="R1-APP-PGWALDUMP-1"><h2>Description</h2><p>
+ <code class="command">pg_waldump</code> displays the write-ahead log (WAL) and is mainly
+ useful for debugging or educational purposes.
+ </p><p>
+ This utility can only be run by the user who installed the server, because
+ it requires read-only access to the data directory.
+ </p></div><div class="refsect1" id="id-1.9.5.13.6"><h2>Options</h2><p>
+ The following command-line options control the location and format of the
+ output:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>startseg</code></em></span></dt><dd><p>
+ Start reading at the specified log segment file. This implicitly determines
+ the path in which files will be searched for, and the timeline to use.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>endseg</code></em></span></dt><dd><p>
+ Stop after reading the specified log segment file.
+ </p></dd><dt><span class="term"><code class="option">-b</code><br /></span><span class="term"><code class="option">--bkp-details</code></span></dt><dd><p>
+ Output detailed information about backup blocks.
+ </p></dd><dt><span class="term"><code class="option">-B <em class="replaceable"><code>block</code></em></code><br /></span><span class="term"><code class="option">--block=<em class="replaceable"><code>block</code></em></code></span></dt><dd><p>
+ Only display records that modify the given block. The relation must
+ also be provided with <code class="option">--relation</code> or
+ <code class="option">-R</code>.
+ </p></dd><dt><span class="term"><code class="option">-e <em class="replaceable"><code>end</code></em></code><br /></span><span class="term"><code class="option">--end=<em class="replaceable"><code>end</code></em></code></span></dt><dd><p>
+ Stop reading at the specified WAL location, instead of reading to the
+ end of the log stream.
+ </p></dd><dt><span class="term"><code class="option">-f</code><br /></span><span class="term"><code class="option">--follow</code></span></dt><dd><p>
+ After reaching the end of valid WAL, keep polling once per second for
+ new WAL to appear.
+ </p></dd><dt><span class="term"><code class="option">-F <em class="replaceable"><code>fork</code></em></code><br /></span><span class="term"><code class="option">--fork=<em class="replaceable"><code>fork</code></em></code></span></dt><dd><p>
+ If provided, only display records that modify blocks in the given fork.
+ The valid values are <code class="literal">main</code> for the main fork,
+ <code class="literal">fsm</code> for the free space map,
+ <code class="literal">vm</code> for the visibility map,
+ and <code class="literal">init</code> for the init fork.
+ </p></dd><dt><span class="term"><code class="option">-n <em class="replaceable"><code>limit</code></em></code><br /></span><span class="term"><code class="option">--limit=<em class="replaceable"><code>limit</code></em></code></span></dt><dd><p>
+ Display the specified number of records, then stop.
+ </p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>path</code></em></code><br /></span><span class="term"><code class="option">--path=<em class="replaceable"><code>path</code></em></code></span></dt><dd><p>
+ Specifies a directory to search for log segment files or a
+ directory with a <code class="literal">pg_wal</code> subdirectory that
+ contains such files. The default is to search in the current
+ directory, the <code class="literal">pg_wal</code> subdirectory of the
+ current directory, and the <code class="literal">pg_wal</code> subdirectory
+ of <code class="envar">PGDATA</code>.
+ </p></dd><dt><span class="term"><code class="option">-q</code><br /></span><span class="term"><code class="option">--quiet</code></span></dt><dd><p>
+ Do not print any output, except for errors. This option can be useful
+ when you want to know whether a range of WAL records can be
+ successfully parsed but don't care about the record contents.
+ </p></dd><dt><span class="term"><code class="option">-r <em class="replaceable"><code>rmgr</code></em></code><br /></span><span class="term"><code class="option">--rmgr=<em class="replaceable"><code>rmgr</code></em></code></span></dt><dd><p>
+ Only display records generated by the specified resource manager. You can
+ specify the option multiple times to select multiple resource managers.
+ If <code class="literal">list</code> is passed as name, print a list of valid resource manager
+ names, and exit.
+ </p><p>
+ Extensions may define custom resource managers, but pg_waldump does
+ not load the extension module and therefore does not recognize custom
+ resource managers by name. Instead, you can specify the custom
+ resource managers as <code class="literal">custom###</code> where
+ "<code class="literal">###</code>" is the three-digit resource manager ID. Names
+ of this form will always be considered valid.
+ </p></dd><dt><span class="term"><code class="option">-R <em class="replaceable"><code>tblspc</code></em>/<em class="replaceable"><code>db</code></em>/<em class="replaceable"><code>rel</code></em></code><br /></span><span class="term"><code class="option">--relation=<em class="replaceable"><code>tblspc</code></em>/<em class="replaceable"><code>db</code></em>/<em class="replaceable"><code>rel</code></em></code></span></dt><dd><p>
+ Only display records that modify blocks in the given relation. The
+ relation is specified with tablespace OID, database OID, and relfilenode
+ separated by slashes, for example <code class="literal">1234/12345/12345</code>.
+ This is the same format used for relations in the program's output.
+ </p></dd><dt><span class="term"><code class="option">-s <em class="replaceable"><code>start</code></em></code><br /></span><span class="term"><code class="option">--start=<em class="replaceable"><code>start</code></em></code></span></dt><dd><p>
+ WAL location at which to start reading. The default is to start reading
+ the first valid log record found in the earliest file found.
+ </p></dd><dt><span class="term"><code class="option">-t <em class="replaceable"><code>timeline</code></em></code><br /></span><span class="term"><code class="option">--timeline=<em class="replaceable"><code>timeline</code></em></code></span></dt><dd><p>
+ Timeline from which to read log records. The default is to use the
+ value in <em class="replaceable"><code>startseg</code></em>, if that is specified; otherwise, the
+ default is 1.
+ </p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">pg_waldump</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--fullpage</code></span></dt><dd><p>
+ Only display records that include full page images.
+ </p></dd><dt><span class="term"><code class="option">-x <em class="replaceable"><code>xid</code></em></code><br /></span><span class="term"><code class="option">--xid=<em class="replaceable"><code>xid</code></em></code></span></dt><dd><p>
+ Only display records marked with the given transaction ID.
+ </p></dd><dt><span class="term"><code class="option">-z</code><br /></span><span class="term"><code class="option">--stats[=record]</code></span></dt><dd><p>
+ Display summary statistics (number and size of records and
+ full-page images) instead of individual records. Optionally
+ generate statistics per-record instead of per-rmgr.
+ </p><p>
+ If <span class="application">pg_waldump</span> is terminated by signal
+ <span class="systemitem">SIGINT</span>
+ (<span class="keycap"><strong>Control</strong></span>+<span class="keycap"><strong>C</strong></span>),
+ the summary of the statistics computed is displayed up to the
+ termination point. This operation is not supported on
+ <span class="productname">Windows</span>.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">pg_waldump</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.5.13.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGDATA</code></span></dt><dd><p>
+ Data directory; see also the <code class="option">-p</code> option.
+ </p></dd><dt><span class="term"><code class="envar">PG_COLOR</code></span></dt><dd><p>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.5.13.8"><h2>Notes</h2><p>
+ Can give wrong results when the server is running.
+ </p><p>
+ Only the specified timeline is displayed (or the default, if none is
+ specified). Records in other timelines are ignored.
+ </p><p>
+ <span class="application">pg_waldump</span> cannot read WAL files with suffix
+ <code class="literal">.partial</code>. If those files need to be read, <code class="literal">.partial</code>
+ suffix needs to be removed from the file name.
+ </p></div><div class="refsect1" id="id-1.9.5.13.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="wal-internals.html" title="30.6. WAL Internals">Section 30.6</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgupgrade.html" title="pg_upgrade">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference-server.html" title="PostgreSQL Server Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-postgres.html" title="postgres">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">pg_upgrade</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">postgres</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgwalinspect.html b/doc/src/sgml/html/pgwalinspect.html
new file mode 100644
index 0000000..8db8ab3
--- /dev/null
+++ b/doc/src/sgml/html/pgwalinspect.html
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.37. pg_walinspect</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgvisibility.html" title="F.36. pg_visibility" /><link rel="next" href="postgres-fdw.html" title="F.38. postgres_fdw" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.37. pg_walinspect</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgvisibility.html" title="F.36. pg_visibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="postgres-fdw.html" title="F.38. postgres_fdw">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGWALINSPECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.37. pg_walinspect</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="pgwalinspect.html#id-1.11.7.46.8">F.37.1. General Functions</a></span></dt><dt><span class="sect2"><a href="pgwalinspect.html#id-1.11.7.46.9">F.37.2. Author</a></span></dt></dl></div><a id="id-1.11.7.46.2" class="indexterm"></a><p>
+ The <code class="filename">pg_walinspect</code> module provides SQL functions that
+ allow you to inspect the contents of write-ahead log of
+ a running <span class="productname">PostgreSQL</span> database cluster at a low
+ level, which is useful for debugging, analytical, reporting or
+ educational purposes. It is similar to <a class="xref" href="pgwaldump.html" title="pg_waldump"><span class="refentrytitle"><span class="application">pg_waldump</span></span></a>, but
+ accessible through SQL rather than a separate utility.
+ </p><p>
+ All the functions of this module will provide the WAL information using the
+ current server's timeline ID.
+ </p><p>
+ All the functions of this module will try to find the first valid WAL record
+ that is at or after the given <em class="replaceable"><code>in_lsn</code></em> or
+ <em class="replaceable"><code>start_lsn</code></em> and will emit error if no such record
+ is available. Similarly, the <em class="replaceable"><code>end_lsn</code></em> must be
+ available, and if it falls in the middle of a record, the entire record must
+ be available.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Some functions, such as <code class="function"><a class="link" href="functions-admin.html#PG-LOGICAL-EMIT-MESSAGE">pg_logical_emit_message</a></code>,
+ return the LSN <span class="emphasis"><em>after</em></span> the record just
+ inserted. Therefore, if you pass that LSN as
+ <em class="replaceable"><code>in_lsn</code></em> or <em class="replaceable"><code>start_lsn</code></em>
+ to one of these functions, it will return the <span class="emphasis"><em>next</em></span>
+ record.
+ </p></div><p>
+ By default, use of these functions is restricted to superusers and members of
+ the <code class="literal">pg_read_server_files</code> role. Access may be granted by
+ superusers to others using <code class="command">GRANT</code>.
+ </p><div class="sect2" id="id-1.11.7.46.8"><div class="titlepage"><div><div><h3 class="title">F.37.1. General Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">pg_get_wal_record_info(in_lsn pg_lsn) returns record</code>
+ </span></dt><dd><p>
+ Gets WAL record information of a given LSN. If the given LSN isn't
+ at the start of a WAL record, it gives the information of the next
+ available valid WAL record; or an error if no such record is found.
+ For example, usage of the function is as
+ follows:
+</p><pre class="screen">
+postgres=# SELECT * FROM pg_get_wal_record_info('0/1E826E98');
+-[ RECORD 1 ]----+----------------------------------------------------
+start_lsn | 0/1E826F20
+end_lsn | 0/1E826F60
+prev_lsn | 0/1E826C80
+xid | 0
+resource_manager | Heap2
+record_type | PRUNE
+record_length | 58
+main_data_length | 8
+fpi_length | 0
+description | snapshotConflictHorizon 33748 nredirected 0 ndead 2
+block_ref | blkref #0: rel 1663/5/60221 fork main blk 2
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">
+ pg_get_wal_records_info(start_lsn pg_lsn, end_lsn pg_lsn)
+ returns setof record
+ </code>
+ </span></dt><dd><p>
+ Gets information of all the valid WAL records between
+ <em class="replaceable"><code>start_lsn</code></em> and <em class="replaceable"><code>end_lsn</code></em>.
+ Returns one row per WAL record. If <em class="replaceable"><code>start_lsn</code></em>
+ or <em class="replaceable"><code>end_lsn</code></em> are not yet available, the
+ function will raise an error. For example:
+</p><pre class="screen">
+postgres=# SELECT * FROM pg_get_wal_records_info('0/1E913618', '0/1E913740') LIMIT 1;
+-[ RECORD 1 ]----+--------------------------------------------------------------
+start_lsn | 0/1E913618
+end_lsn | 0/1E913650
+prev_lsn | 0/1E9135A0
+xid | 0
+resource_manager | Standby
+record_type | RUNNING_XACTS
+record_length | 50
+main_data_length | 24
+fpi_length | 0
+description | nextXid 33775 latestCompletedXid 33774 oldestRunningXid 33775
+block_ref |
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">
+ pg_get_wal_records_info_till_end_of_wal(start_lsn pg_lsn)
+ returns setof record
+ </code>
+ </span></dt><dd><p>
+ This function is the same as <code class="function">pg_get_wal_records_info()</code>,
+ except that it gets information of all the valid WAL records from
+ <em class="replaceable"><code>start_lsn</code></em> till the end of WAL.
+ </p></dd><dt><span class="term">
+ <code class="function">
+ pg_get_wal_stats(start_lsn pg_lsn, end_lsn pg_lsn, per_record boolean DEFAULT false)
+ returns setof record
+ </code>
+ </span></dt><dd><p>
+ Gets statistics of all the valid WAL records between
+ <em class="replaceable"><code>start_lsn</code></em> and
+ <em class="replaceable"><code>end_lsn</code></em>. By default, it returns one row per
+ <em class="replaceable"><code>resource_manager</code></em> type. When
+ <em class="replaceable"><code>per_record</code></em> is set to <code class="literal">true</code>,
+ it returns one row per <em class="replaceable"><code>record_type</code></em>.
+ If <em class="replaceable"><code>start_lsn</code></em>
+ or <em class="replaceable"><code>end_lsn</code></em> are not yet available, the
+ function will raise an error. For example:
+</p><pre class="screen">
+postgres=# SELECT * FROM pg_get_wal_stats('0/1E847D00', '0/1E84F500')
+ WHERE count &gt; 0 AND
+ "resource_manager/record_type" = 'Transaction'
+ LIMIT 1;
+-[ RECORD 1 ]----------------+-------------------
+resource_manager/record_type | Transaction
+count | 2
+count_percentage | 8
+record_size | 875
+record_size_percentage | 41.23468426013195
+fpi_size | 0
+fpi_size_percentage | 0
+combined_size | 875
+combined_size_percentage | 2.8634072910530795
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="function">
+ pg_get_wal_stats_till_end_of_wal(start_lsn pg_lsn, per_record boolean DEFAULT false)
+ returns setof record
+ </code>
+ </span></dt><dd><p>
+ This function is the same as <code class="function">pg_get_wal_stats()</code>,
+ except that it gets statistics of all the valid WAL records from
+ <em class="replaceable"><code>start_lsn</code></em> till end of WAL.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.46.9"><div class="titlepage"><div><div><h3 class="title">F.37.2. Author</h3></div></div></div><p>
+ Bharath Rupireddy <code class="email">&lt;<a class="email" href="mailto:bharath.rupireddyforpostgres@gmail.com">bharath.rupireddyforpostgres@gmail.com</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgvisibility.html" title="F.36. pg_visibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="postgres-fdw.html" title="F.38. postgres_fdw">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.36. pg_visibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.38. postgres_fdw</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pgxlogdump.html b/doc/src/sgml/html/pgxlogdump.html
new file mode 100644
index 0000000..3675336
--- /dev/null
+++ b/doc/src/sgml/html/pgxlogdump.html
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>O.3. pg_xlogdump renamed to pg_waldump</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="default-roles.html" title="O.2. Default Roles Renamed to Predefined Roles" /><link rel="next" href="app-pgresetxlog.html" title="O.4. pg_resetxlog renamed to pg_resetwal" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">O.3. <code class="command">pg_xlogdump</code> renamed to <code class="command">pg_waldump</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="default-roles.html" title="O.2. Default Roles Renamed to Predefined Roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><th width="60%" align="center">Appendix O. Obsolete or Renamed Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-pgresetxlog.html" title="O.4. pg_resetxlog renamed to pg_resetwal">Next</a></td></tr></table><hr /></div><div class="sect1" id="PGXLOGDUMP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">O.3. <code class="command">pg_xlogdump</code> renamed to <code class="command">pg_waldump</code></h2></div></div></div><a id="id-1.11.16.5.2" class="indexterm"></a><p>
+ PostgreSQL 9.6 and below provided a command named
+ <code class="command">pg_xlogdump</code>
+ <a id="id-1.11.16.5.3.2" class="indexterm"></a>
+ to read write-ahead-log (WAL) files. This command was renamed to <code class="command">pg_waldump</code>, see
+ <a class="xref" href="pgwaldump.html" title="pg_waldump"><span class="refentrytitle"><span class="application">pg_waldump</span></span></a> for documentation of <code class="command">pg_waldump</code> and see
+ <a class="link" href="release-prior.html" title="E.6. Prior Releases">the release notes for PostgreSQL 10</a> for details
+ on this change.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="default-roles.html" title="O.2. Default Roles Renamed to Predefined Roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-pgresetxlog.html" title="O.4. pg_resetxlog renamed to pg_resetwal">Next</a></td></tr><tr><td width="40%" align="left" valign="top">O.2. Default Roles Renamed to Predefined Roles </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> O.4. <code class="command">pg_resetxlog</code> renamed to <code class="command">pg_resetwal</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/planner-optimizer.html b/doc/src/sgml/html/planner-optimizer.html
new file mode 100644
index 0000000..882ee77
--- /dev/null
+++ b/doc/src/sgml/html/planner-optimizer.html
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>52.5. Planner/Optimizer</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rule-system.html" title="52.4. The PostgreSQL Rule System" /><link rel="next" href="executor.html" title="52.6. Executor" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">52.5. Planner/Optimizer</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rule-system.html" title="52.4. The PostgreSQL Rule System">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><th width="60%" align="center">Chapter 52. Overview of PostgreSQL Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="executor.html" title="52.6. Executor">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLANNER-OPTIMIZER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">52.5. Planner/Optimizer</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="planner-optimizer.html#id-1.10.3.8.5">52.5.1. Generating Possible Plans</a></span></dt></dl></div><p>
+ The task of the <em class="firstterm">planner/optimizer</em> is to
+ create an optimal execution plan. A given SQL query (and hence, a
+ query tree) can be actually executed in a wide variety of
+ different ways, each of which will produce the same set of
+ results. If it is computationally feasible, the query optimizer
+ will examine each of these possible execution plans, ultimately
+ selecting the execution plan that is expected to run the fastest.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In some situations, examining each possible way in which a query
+ can be executed would take an excessive amount of time and memory.
+ In particular, this occurs when executing queries
+ involving large numbers of join operations. In order to determine
+ a reasonable (not necessarily optimal) query plan in a reasonable amount
+ of time, <span class="productname">PostgreSQL</span> uses a <em class="firstterm">Genetic
+ Query Optimizer</em> (see <a class="xref" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Chapter 62</a>) when the number of joins
+ exceeds a threshold (see <a class="xref" href="runtime-config-query.html#GUC-GEQO-THRESHOLD">geqo_threshold</a>).
+ </p></div><p>
+ The planner's search procedure actually works with data structures
+ called <em class="firstterm">paths</em>, which are simply cut-down representations of
+ plans containing only as much information as the planner needs to make
+ its decisions. After the cheapest path is determined, a full-fledged
+ <em class="firstterm">plan tree</em> is built to pass to the executor. This represents
+ the desired execution plan in sufficient detail for the executor to run it.
+ In the rest of this section we'll ignore the distinction between paths
+ and plans.
+ </p><div class="sect2" id="id-1.10.3.8.5"><div class="titlepage"><div><div><h3 class="title">52.5.1. Generating Possible Plans</h3></div></div></div><p>
+ The planner/optimizer starts by generating plans for scanning each
+ individual relation (table) used in the query. The possible plans
+ are determined by the available indexes on each relation.
+ There is always the possibility of performing a
+ sequential scan on a relation, so a sequential scan plan is always
+ created. Assume an index is defined on a
+ relation (for example a B-tree index) and a query contains the
+ restriction
+ <code class="literal">relation.attribute OPR constant</code>. If
+ <code class="literal">relation.attribute</code> happens to match the key of the B-tree
+ index and <code class="literal">OPR</code> is one of the operators listed in
+ the index's <em class="firstterm">operator class</em>, another plan is created using
+ the B-tree index to scan the relation. If there are further indexes
+ present and the restrictions in the query happen to match a key of an
+ index, further plans will be considered. Index scan plans are also
+ generated for indexes that have a sort ordering that can match the
+ query's <code class="literal">ORDER BY</code> clause (if any), or a sort ordering that
+ might be useful for merge joining (see below).
+ </p><p>
+ If the query requires joining two or more relations,
+ plans for joining relations are considered
+ after all feasible plans have been found for scanning single relations.
+ The three available join strategies are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <em class="firstterm">nested loop join</em>: The right relation is scanned
+ once for every row found in the left relation. This strategy
+ is easy to implement but can be very time consuming. (However,
+ if the right relation can be scanned with an index scan, this can
+ be a good strategy. It is possible to use values from the current
+ row of the left relation as keys for the index scan of the right.)
+ </p></li><li class="listitem"><p>
+ <em class="firstterm">merge join</em>: Each relation is sorted on the join
+ attributes before the join starts. Then the two relations are
+ scanned in parallel, and matching rows are combined to form
+ join rows. This kind of join is
+ attractive because each relation has to be scanned only once.
+ The required sorting might be achieved either by an explicit sort
+ step, or by scanning the relation in the proper order using an
+ index on the join key.
+ </p></li><li class="listitem"><p>
+ <em class="firstterm">hash join</em>: the right relation is first scanned
+ and loaded into a hash table, using its join attributes as hash keys.
+ Next the left relation is scanned and the
+ appropriate values of every row found are used as hash keys to
+ locate the matching rows in the table.
+ </p></li></ul></div><p>
+ </p><p>
+ When the query involves more than two relations, the final result
+ must be built up by a tree of join steps, each with two inputs.
+ The planner examines different possible join sequences to find the
+ cheapest one.
+ </p><p>
+ If the query uses fewer than <a class="xref" href="runtime-config-query.html#GUC-GEQO-THRESHOLD">geqo_threshold</a>
+ relations, a near-exhaustive search is conducted to find the best
+ join sequence. The planner preferentially considers joins between any
+ two relations for which there exists a corresponding join clause in the
+ <code class="literal">WHERE</code> qualification (i.e., for
+ which a restriction like <code class="literal">where rel1.attr1=rel2.attr2</code>
+ exists). Join pairs with no join clause are considered only when there
+ is no other choice, that is, a particular relation has no available
+ join clauses to any other relation. All possible plans are generated for
+ every join pair considered by the planner, and the one that is
+ (estimated to be) the cheapest is chosen.
+ </p><p>
+ When <code class="varname">geqo_threshold</code> is exceeded, the join
+ sequences considered are determined by heuristics, as described
+ in <a class="xref" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Chapter 62</a>. Otherwise the process is the same.
+ </p><p>
+ The finished plan tree consists of sequential or index scans of
+ the base relations, plus nested-loop, merge, or hash join nodes as
+ needed, plus any auxiliary steps needed, such as sort nodes or
+ aggregate-function calculation nodes. Most of these plan node
+ types have the additional ability to do <em class="firstterm">selection</em>
+ (discarding rows that do not meet a specified Boolean condition)
+ and <em class="firstterm">projection</em> (computation of a derived column set
+ based on given column values, that is, evaluation of scalar
+ expressions where needed). One of the responsibilities of the
+ planner is to attach selection conditions from the
+ <code class="literal">WHERE</code> clause and computation of required
+ output expressions to the most appropriate nodes of the plan
+ tree.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rule-system.html" title="52.4. The PostgreSQL Rule System">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="executor.html" title="52.6. Executor">Next</a></td></tr><tr><td width="40%" align="left" valign="top">52.4. The <span class="productname">PostgreSQL</span> Rule System </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 52.6. Executor</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/planner-stats-details.html b/doc/src/sgml/html/planner-stats-details.html
new file mode 100644
index 0000000..8428b50
--- /dev/null
+++ b/doc/src/sgml/html/planner-stats-details.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 75. How the Planner Uses Statistics</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bki-example.html" title="74.6. BKI Example" /><link rel="next" href="row-estimation-examples.html" title="75.1. Row Estimation Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 75. How the Planner Uses Statistics</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bki-example.html" title="74.6. BKI Example">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="row-estimation-examples.html" title="75.1. Row Estimation Examples">Next</a></td></tr></table><hr /></div><div class="chapter" id="PLANNER-STATS-DETAILS"><div class="titlepage"><div><div><h2 class="title">Chapter 75. How the Planner Uses Statistics</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="row-estimation-examples.html">75.1. Row Estimation Examples</a></span></dt><dt><span class="sect1"><a href="multivariate-statistics-examples.html">75.2. Multivariate Statistics Examples</a></span></dt><dd><dl><dt><span class="sect2"><a href="multivariate-statistics-examples.html#FUNCTIONAL-DEPENDENCIES">75.2.1. Functional Dependencies</a></span></dt><dt><span class="sect2"><a href="multivariate-statistics-examples.html#MULTIVARIATE-NDISTINCT-COUNTS">75.2.2. Multivariate N-Distinct Counts</a></span></dt><dt><span class="sect2"><a href="multivariate-statistics-examples.html#MCV-LISTS">75.2.3. MCV Lists</a></span></dt></dl></dd><dt><span class="sect1"><a href="planner-stats-security.html">75.3. Planner Statistics and Security</a></span></dt></dl></div><p>
+ This chapter builds on the material covered in <a class="xref" href="using-explain.html" title="14.1. Using EXPLAIN">Section 14.1</a> and <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a> to show some
+ additional details about how the planner uses the
+ system statistics to estimate the number of rows each part of a query might
+ return. This is a significant part of the planning process,
+ providing much of the raw material for cost calculation.
+ </p><p>
+ The intent of this chapter is not to document the code in detail,
+ but to present an overview of how it works.
+ This will perhaps ease the learning curve for someone who subsequently
+ wishes to read the code.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bki-example.html" title="74.6. BKI Example">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="row-estimation-examples.html" title="75.1. Row Estimation Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">74.6. BKI Example </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 75.1. Row Estimation Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/planner-stats-security.html b/doc/src/sgml/html/planner-stats-security.html
new file mode 100644
index 0000000..2b9d012
--- /dev/null
+++ b/doc/src/sgml/html/planner-stats-security.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>75.3. Planner Statistics and Security</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples" /><link rel="next" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">75.3. Planner Statistics and Security</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Up</a></td><th width="60%" align="center">Chapter 75. How the Planner Uses Statistics</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLANNER-STATS-SECURITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">75.3. Planner Statistics and Security</h2></div></div></div><p>
+ Access to the table <code class="structname">pg_statistic</code> is restricted to
+ superusers, so that ordinary users cannot learn about the contents of the
+ tables of other users from it. Some selectivity estimation functions will
+ use a user-provided operator (either the operator appearing in the query or
+ a related operator) to analyze the stored statistics. For example, in order
+ to determine whether a stored most common value is applicable, the
+ selectivity estimator will have to run the appropriate <code class="literal">=</code>
+ operator to compare the constant in the query to the stored value.
+ Thus the data in <code class="structname">pg_statistic</code> is potentially
+ passed to user-defined operators. An appropriately crafted operator can
+ intentionally leak the passed operands (for example, by logging them
+ or writing them to a different table), or accidentally leak them by showing
+ their values in error messages, in either case possibly exposing data from
+ <code class="structname">pg_statistic</code> to a user who should not be able to
+ see it.
+ </p><p>
+ In order to prevent this, the following applies to all built-in selectivity
+ estimation functions. When planning a query, in order to be able to use
+ stored statistics, the current user must either
+ have <code class="literal">SELECT</code> privilege on the table or the involved
+ columns, or the operator used must be <code class="literal">LEAKPROOF</code> (more
+ accurately, the function that the operator is based on). If not, then the
+ selectivity estimator will behave as if no statistics are available, and
+ the planner will proceed with default or fall-back assumptions.
+ </p><p>
+ If a user does not have the required privilege on the table or columns,
+ then in many cases the query will ultimately receive a permission-denied
+ error, in which case this mechanism is invisible in practice. But if the
+ user is reading from a security-barrier view, then the planner might wish
+ to check the statistics of an underlying table that is otherwise
+ inaccessible to the user. In that case, the operator should be leak-proof
+ or the statistics will not be used. There is no direct feedback about
+ that, except that the plan might be suboptimal. If one suspects that this
+ is the case, one could try running the query as a more privileged user,
+ to see if a different plan results.
+ </p><p>
+ This restriction applies only to cases where the planner would need to
+ execute a user-defined operator on one or more values
+ from <code class="structname">pg_statistic</code>. Thus the planner is permitted
+ to use generic statistical information, such as the fraction of null values
+ or the number of distinct values in a column, regardless of access
+ privileges.
+ </p><p>
+ Selectivity estimation functions contained in third-party extensions that
+ potentially operate on statistics with user-defined operators should follow
+ the same security rules. Consult the PostgreSQL source code for guidance.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="backup-manifest-format.html" title="Chapter 76. Backup Manifest Format">Next</a></td></tr><tr><td width="40%" align="left" valign="top">75.2. Multivariate Statistics Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 76. Backup Manifest Format</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/planner-stats.html b/doc/src/sgml/html/planner-stats.html
new file mode 100644
index 0000000..27cf1c8
--- /dev/null
+++ b/doc/src/sgml/html/planner-stats.html
@@ -0,0 +1,336 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>14.2. Statistics Used by the Planner</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="using-explain.html" title="14.1. Using EXPLAIN" /><link rel="next" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">14.2. Statistics Used by the Planner</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="using-explain.html" title="14.1. Using EXPLAIN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><th width="60%" align="center">Chapter 14. Performance Tips</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLANNER-STATS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">14.2. Statistics Used by the Planner</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="planner-stats.html#id-1.5.13.5.3">14.2.1. Single-Column Statistics</a></span></dt><dt><span class="sect2"><a href="planner-stats.html#PLANNER-STATS-EXTENDED">14.2.2. Extended Statistics</a></span></dt></dl></div><a id="id-1.5.13.5.2" class="indexterm"></a><div class="sect2" id="id-1.5.13.5.3"><div class="titlepage"><div><div><h3 class="title">14.2.1. Single-Column Statistics</h3></div></div></div><p>
+ As we saw in the previous section, the query planner needs to estimate
+ the number of rows retrieved by a query in order to make good choices
+ of query plans. This section provides a quick look at the statistics
+ that the system uses for these estimates.
+ </p><p>
+ One component of the statistics is the total number of entries in
+ each table and index, as well as the number of disk blocks occupied
+ by each table and index. This information is kept in the table
+ <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>,
+ in the columns <code class="structfield">reltuples</code> and
+ <code class="structfield">relpages</code>. We can look at it with
+ queries similar to this one:
+
+</p><pre class="screen">
+SELECT relname, relkind, reltuples, relpages
+FROM pg_class
+WHERE relname LIKE 'tenk1%';
+
+ relname | relkind | reltuples | relpages
+----------------------+---------+-----------+----------
+ tenk1 | r | 10000 | 358
+ tenk1_hundred | i | 10000 | 30
+ tenk1_thous_tenthous | i | 10000 | 30
+ tenk1_unique1 | i | 10000 | 30
+ tenk1_unique2 | i | 10000 | 30
+(5 rows)
+</pre><p>
+
+ Here we can see that <code class="structname">tenk1</code> contains 10000
+ rows, as do its indexes, but the indexes are (unsurprisingly) much
+ smaller than the table.
+ </p><p>
+ For efficiency reasons, <code class="structfield">reltuples</code>
+ and <code class="structfield">relpages</code> are not updated on-the-fly,
+ and so they usually contain somewhat out-of-date values.
+ They are updated by <code class="command">VACUUM</code>, <code class="command">ANALYZE</code>, and a
+ few DDL commands such as <code class="command">CREATE INDEX</code>. A <code class="command">VACUUM</code>
+ or <code class="command">ANALYZE</code> operation that does not scan the entire table
+ (which is commonly the case) will incrementally update the
+ <code class="structfield">reltuples</code> count on the basis of the part
+ of the table it did scan, resulting in an approximate value.
+ In any case, the planner
+ will scale the values it finds in <code class="structname">pg_class</code>
+ to match the current physical table size, thus obtaining a closer
+ approximation.
+ </p><a id="id-1.5.13.5.3.5" class="indexterm"></a><p>
+ Most queries retrieve only a fraction of the rows in a table, due
+ to <code class="literal">WHERE</code> clauses that restrict the rows to be
+ examined. The planner thus needs to make an estimate of the
+ <em class="firstterm">selectivity</em> of <code class="literal">WHERE</code> clauses, that is,
+ the fraction of rows that match each condition in the
+ <code class="literal">WHERE</code> clause. The information used for this task is
+ stored in the
+ <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a>
+ system catalog. Entries in <code class="structname">pg_statistic</code>
+ are updated by the <code class="command">ANALYZE</code> and <code class="command">VACUUM
+ ANALYZE</code> commands, and are always approximate even when freshly
+ updated.
+ </p><a id="id-1.5.13.5.3.7" class="indexterm"></a><p>
+ Rather than look at <code class="structname">pg_statistic</code> directly,
+ it's better to look at its view
+ <a class="link" href="view-pg-stats.html" title="54.27. pg_stats"><code class="structname">pg_stats</code></a>
+ when examining the statistics manually. <code class="structname">pg_stats</code>
+ is designed to be more easily readable. Furthermore,
+ <code class="structname">pg_stats</code> is readable by all, whereas
+ <code class="structname">pg_statistic</code> is only readable by a superuser.
+ (This prevents unprivileged users from learning something about
+ the contents of other people's tables from the statistics. The
+ <code class="structname">pg_stats</code> view is restricted to show only
+ rows about tables that the current user can read.)
+ For example, we might do:
+
+</p><pre class="screen">
+SELECT attname, inherited, n_distinct,
+ array_to_string(most_common_vals, E'\n') as most_common_vals
+FROM pg_stats
+WHERE tablename = 'road';
+
+ attname | inherited | n_distinct | most_common_vals
+---------+-----------+------------+------------------------------------
+ name | f | -0.363388 | I- 580 Ramp+
+ | | | I- 880 Ramp+
+ | | | Sp Railroad +
+ | | | I- 580 +
+ | | | I- 680 Ramp
+ name | t | -0.284859 | I- 880 Ramp+
+ | | | I- 580 Ramp+
+ | | | I- 680 Ramp+
+ | | | I- 580 +
+ | | | State Hwy 13 Ramp
+(2 rows)
+</pre><p>
+
+ Note that two rows are displayed for the same column, one corresponding
+ to the complete inheritance hierarchy starting at the
+ <code class="literal">road</code> table (<code class="literal">inherited</code>=<code class="literal">t</code>),
+ and another one including only the <code class="literal">road</code> table itself
+ (<code class="literal">inherited</code>=<code class="literal">f</code>).
+ </p><p>
+ The amount of information stored in <code class="structname">pg_statistic</code>
+ by <code class="command">ANALYZE</code>, in particular the maximum number of entries in the
+ <code class="structfield">most_common_vals</code> and <code class="structfield">histogram_bounds</code>
+ arrays for each column, can be set on a
+ column-by-column basis using the <code class="command">ALTER TABLE SET STATISTICS</code>
+ command, or globally by setting the
+ <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> configuration variable.
+ The default limit is presently 100 entries. Raising the limit
+ might allow more accurate planner estimates to be made, particularly for
+ columns with irregular data distributions, at the price of consuming
+ more space in <code class="structname">pg_statistic</code> and slightly more
+ time to compute the estimates. Conversely, a lower limit might be
+ sufficient for columns with simple data distributions.
+ </p><p>
+ Further details about the planner's use of statistics can be found in
+ <a class="xref" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Chapter 75</a>.
+ </p></div><div class="sect2" id="PLANNER-STATS-EXTENDED"><div class="titlepage"><div><div><h3 class="title">14.2.2. Extended Statistics</h3></div></div></div><a id="id-1.5.13.5.4.2" class="indexterm"></a><a id="id-1.5.13.5.4.3" class="indexterm"></a><a id="id-1.5.13.5.4.4" class="indexterm"></a><a id="id-1.5.13.5.4.5" class="indexterm"></a><p>
+ It is common to see slow queries running bad execution plans because
+ multiple columns used in the query clauses are correlated.
+ The planner normally assumes that multiple conditions
+ are independent of each other,
+ an assumption that does not hold when column values are correlated.
+ Regular statistics, because of their per-individual-column nature,
+ cannot capture any knowledge about cross-column correlation.
+ However, <span class="productname">PostgreSQL</span> has the ability to compute
+ <em class="firstterm">multivariate statistics</em>, which can capture
+ such information.
+ </p><p>
+ Because the number of possible column combinations is very large,
+ it's impractical to compute multivariate statistics automatically.
+ Instead, <em class="firstterm">extended statistics objects</em>, more often
+ called just <em class="firstterm">statistics objects</em>, can be created to instruct
+ the server to obtain statistics across interesting sets of columns.
+ </p><p>
+ Statistics objects are created using the
+ <a class="link" href="sql-createstatistics.html" title="CREATE STATISTICS"><code class="command">CREATE STATISTICS</code></a> command.
+ Creation of such an object merely creates a catalog entry expressing
+ interest in the statistics. Actual data collection is performed
+ by <code class="command">ANALYZE</code> (either a manual command, or background
+ auto-analyze). The collected values can be examined in the
+ <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>
+ catalog.
+ </p><p>
+ <code class="command">ANALYZE</code> computes extended statistics based on the same
+ sample of table rows that it takes for computing regular single-column
+ statistics. Since the sample size is increased by increasing the
+ statistics target for the table or any of its columns (as described in
+ the previous section), a larger statistics target will normally result in
+ more accurate extended statistics, as well as more time spent calculating
+ them.
+ </p><p>
+ The following subsections describe the kinds of extended statistics
+ that are currently supported.
+ </p><div class="sect3" id="id-1.5.13.5.4.11"><div class="titlepage"><div><div><h4 class="title">14.2.2.1. Functional Dependencies</h4></div></div></div><p>
+ The simplest kind of extended statistics tracks <em class="firstterm">functional
+ dependencies</em>, a concept used in definitions of database normal forms.
+ We say that column <code class="structfield">b</code> is functionally dependent on
+ column <code class="structfield">a</code> if knowledge of the value of
+ <code class="structfield">a</code> is sufficient to determine the value
+ of <code class="structfield">b</code>, that is there are no two rows having the same value
+ of <code class="structfield">a</code> but different values of <code class="structfield">b</code>.
+ In a fully normalized database, functional dependencies should exist
+ only on primary keys and superkeys. However, in practice many data sets
+ are not fully normalized for various reasons; intentional
+ denormalization for performance reasons is a common example.
+ Even in a fully normalized database, there may be partial correlation
+ between some columns, which can be expressed as partial functional
+ dependency.
+ </p><p>
+ The existence of functional dependencies directly affects the accuracy
+ of estimates in certain queries. If a query contains conditions on
+ both the independent and the dependent column(s), the
+ conditions on the dependent columns do not further reduce the result
+ size; but without knowledge of the functional dependency, the query
+ planner will assume that the conditions are independent, resulting
+ in underestimating the result size.
+ </p><p>
+ To inform the planner about functional dependencies, <code class="command">ANALYZE</code>
+ can collect measurements of cross-column dependency. Assessing the
+ degree of dependency between all sets of columns would be prohibitively
+ expensive, so data collection is limited to those groups of columns
+ appearing together in a statistics object defined with
+ the <code class="literal">dependencies</code> option. It is advisable to create
+ <code class="literal">dependencies</code> statistics only for column groups that are
+ strongly correlated, to avoid unnecessary overhead in both
+ <code class="command">ANALYZE</code> and later query planning.
+ </p><p>
+ Here is an example of collecting functional-dependency statistics:
+</p><pre class="programlisting">
+CREATE STATISTICS stts (dependencies) ON city, zip FROM zipcodes;
+
+ANALYZE zipcodes;
+
+SELECT stxname, stxkeys, stxddependencies
+ FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid)
+ WHERE stxname = 'stts';
+ stxname | stxkeys | stxddependencies
+---------+---------+------------------------------------------
+ stts | 1 5 | {"1 =&gt; 5": 1.000000, "5 =&gt; 1": 0.423130}
+(1 row)
+</pre><p>
+ Here it can be seen that column 1 (zip code) fully determines column
+ 5 (city) so the coefficient is 1.0, while city only determines zip code
+ about 42% of the time, meaning that there are many cities (58%) that are
+ represented by more than a single ZIP code.
+ </p><p>
+ When computing the selectivity for a query involving functionally
+ dependent columns, the planner adjusts the per-condition selectivity
+ estimates using the dependency coefficients so as not to produce
+ an underestimate.
+ </p><div class="sect4" id="id-1.5.13.5.4.11.7"><div class="titlepage"><div><div><h5 class="title">14.2.2.1.1. Limitations of Functional Dependencies</h5></div></div></div><p>
+ Functional dependencies are currently only applied when considering
+ simple equality conditions that compare columns to constant values,
+ and <code class="literal">IN</code> clauses with constant values.
+ They are not used to improve estimates for equality conditions
+ comparing two columns or comparing a column to an expression, nor for
+ range clauses, <code class="literal">LIKE</code> or any other type of condition.
+ </p><p>
+ When estimating with functional dependencies, the planner assumes that
+ conditions on the involved columns are compatible and hence redundant.
+ If they are incompatible, the correct estimate would be zero rows, but
+ that possibility is not considered. For example, given a query like
+</p><pre class="programlisting">
+SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '94105';
+</pre><p>
+ the planner will disregard the <code class="structfield">city</code> clause as not
+ changing the selectivity, which is correct. However, it will make
+ the same assumption about
+</p><pre class="programlisting">
+SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210';
+</pre><p>
+ even though there will really be zero rows satisfying this query.
+ Functional dependency statistics do not provide enough information
+ to conclude that, however.
+ </p><p>
+ In many practical situations, this assumption is usually satisfied;
+ for example, there might be a GUI in the application that only allows
+ selecting compatible city and ZIP code values to use in a query.
+ But if that's not the case, functional dependencies may not be a viable
+ option.
+ </p></div></div><div class="sect3" id="id-1.5.13.5.4.12"><div class="titlepage"><div><div><h4 class="title">14.2.2.2. Multivariate N-Distinct Counts</h4></div></div></div><p>
+ Single-column statistics store the number of distinct values in each
+ column. Estimates of the number of distinct values when combining more
+ than one column (for example, for <code class="literal">GROUP BY a, b</code>) are
+ frequently wrong when the planner only has single-column statistical
+ data, causing it to select bad plans.
+ </p><p>
+ To improve such estimates, <code class="command">ANALYZE</code> can collect n-distinct
+ statistics for groups of columns. As before, it's impractical to do
+ this for every possible column grouping, so data is collected only for
+ those groups of columns appearing together in a statistics object
+ defined with the <code class="literal">ndistinct</code> option. Data will be collected
+ for each possible combination of two or more columns from the set of
+ listed columns.
+ </p><p>
+ Continuing the previous example, the n-distinct counts in a
+ table of ZIP codes might look like the following:
+</p><pre class="programlisting">
+CREATE STATISTICS stts2 (ndistinct) ON city, state, zip FROM zipcodes;
+
+ANALYZE zipcodes;
+
+SELECT stxkeys AS k, stxdndistinct AS nd
+ FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid)
+ WHERE stxname = 'stts2';
+-[ RECORD 1 ]------------------------------------------------------​--
+k | 1 2 5
+nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
+(1 row)
+</pre><p>
+ This indicates that there are three combinations of columns that
+ have 33178 distinct values: ZIP code and state; ZIP code and city;
+ and ZIP code, city and state (the fact that they are all equal is
+ expected given that ZIP code alone is unique in this table). On the
+ other hand, the combination of city and state has only 27435 distinct
+ values.
+ </p><p>
+ It's advisable to create <code class="literal">ndistinct</code> statistics objects only
+ on combinations of columns that are actually used for grouping, and
+ for which misestimation of the number of groups is resulting in bad
+ plans. Otherwise, the <code class="command">ANALYZE</code> cycles are just wasted.
+ </p></div><div class="sect3" id="id-1.5.13.5.4.13"><div class="titlepage"><div><div><h4 class="title">14.2.2.3. Multivariate MCV Lists</h4></div></div></div><p>
+ Another type of statistic stored for each column are most-common value
+ lists. This allows very accurate estimates for individual columns, but
+ may result in significant misestimates for queries with conditions on
+ multiple columns.
+ </p><p>
+ To improve such estimates, <code class="command">ANALYZE</code> can collect MCV
+ lists on combinations of columns. Similarly to functional dependencies
+ and n-distinct coefficients, it's impractical to do this for every
+ possible column grouping. Even more so in this case, as the MCV list
+ (unlike functional dependencies and n-distinct coefficients) does store
+ the common column values. So data is collected only for those groups
+ of columns appearing together in a statistics object defined with the
+ <code class="literal">mcv</code> option.
+ </p><p>
+ Continuing the previous example, the MCV list for a table of ZIP codes
+ might look like the following (unlike for simpler types of statistics,
+ a function is required for inspection of MCV contents):
+
+</p><pre class="programlisting">
+CREATE STATISTICS stts3 (mcv) ON city, state FROM zipcodes;
+
+ANALYZE zipcodes;
+
+SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
+ pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts3';
+
+ index | values | nulls | frequency | base_frequency
+-------+------------------------+-------+-----------+----------------
+ 0 | {Washington, DC} | {f,f} | 0.003467 | 2.7e-05
+ 1 | {Apo, AE} | {f,f} | 0.003067 | 1.9e-05
+ 2 | {Houston, TX} | {f,f} | 0.002167 | 0.000133
+ 3 | {El Paso, TX} | {f,f} | 0.002 | 0.000113
+ 4 | {New York, NY} | {f,f} | 0.001967 | 0.000114
+ 5 | {Atlanta, GA} | {f,f} | 0.001633 | 3.3e-05
+ 6 | {Sacramento, CA} | {f,f} | 0.001433 | 7.8e-05
+ 7 | {Miami, FL} | {f,f} | 0.0014 | 6e-05
+ 8 | {Dallas, TX} | {f,f} | 0.001367 | 8.8e-05
+ 9 | {Chicago, IL} | {f,f} | 0.001333 | 5.1e-05
+ ...
+(99 rows)
+</pre><p>
+ This indicates that the most common combination of city and state is
+ Washington in DC, with actual frequency (in the sample) about 0.35%.
+ The base frequency of the combination (as computed from the simple
+ per-column frequencies) is only 0.0027%, resulting in two orders of
+ magnitude under-estimates.
+ </p><p>
+ It's advisable to create <acronym class="acronym">MCV</acronym> statistics objects only
+ on combinations of columns that are actually used in conditions together,
+ and for which misestimation of the number of groups is resulting in bad
+ plans. Otherwise, the <code class="command">ANALYZE</code> and planning cycles
+ are just wasted.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="using-explain.html" title="14.1. Using EXPLAIN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Next</a></td></tr><tr><td width="40%" align="left" valign="top">14.1. Using <code class="command">EXPLAIN</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 14.3. Controlling the Planner with Explicit <code class="literal">JOIN</code> Clauses</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plhandler.html b/doc/src/sgml/html/plhandler.html
new file mode 100644
index 0000000..2e80bef
--- /dev/null
+++ b/doc/src/sgml/html/plhandler.html
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 58. Writing a Procedural Language Handler</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="nls-programmer.html" title="57.2. For the Programmer" /><link rel="next" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 58. Writing a Procedural Language Handler</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="nls-programmer.html" title="57.2. For the Programmer">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Next</a></td></tr></table><hr /></div><div class="chapter" id="PLHANDLER"><div class="titlepage"><div><div><h2 class="title">Chapter 58. Writing a Procedural Language Handler</h2></div></div></div><a id="id-1.10.9.2" class="indexterm"></a><p>
+ All calls to functions that are written in a language other than
+ the current <span class="quote">“<span class="quote">version 1</span>”</span> interface for compiled
+ languages (this includes functions in user-defined procedural languages
+ and functions written in SQL) go through a <em class="firstterm">call handler</em>
+ function for the specific language. It is the responsibility of
+ the call handler to execute the function in a meaningful way, such
+ as by interpreting the supplied source text. This chapter outlines
+ how a new procedural language's call handler can be written.
+ </p><p>
+ The call handler for a procedural language is a
+ <span class="quote">“<span class="quote">normal</span>”</span> function that must be written in a compiled
+ language such as C, using the version-1 interface, and registered
+ with <span class="productname">PostgreSQL</span> as taking no arguments
+ and returning the type <code class="type">language_handler</code>. This
+ special pseudo-type identifies the function as a call handler and
+ prevents it from being called directly in SQL commands.
+ For more details on C language calling conventions and dynamic loading,
+ see <a class="xref" href="xfunc-c.html" title="38.10. C-Language Functions">Section 38.10</a>.
+ </p><p>
+ The call handler is called in the same way as any other function:
+ It receives a pointer to a
+ <code class="structname">FunctionCallInfoBaseData</code> <code class="type">struct</code> containing
+ argument values and information about the called function, and it
+ is expected to return a <code class="type">Datum</code> result (and possibly
+ set the <code class="structfield">isnull</code> field of the
+ <code class="structname">FunctionCallInfoBaseData</code> structure, if it wishes
+ to return an SQL null result). The difference between a call
+ handler and an ordinary callee function is that the
+ <code class="structfield">flinfo-&gt;fn_oid</code> field of the
+ <code class="structname">FunctionCallInfoBaseData</code> structure will contain
+ the OID of the actual function to be called, not of the call
+ handler itself. The call handler must use this field to determine
+ which function to execute. Also, the passed argument list has
+ been set up according to the declaration of the target function,
+ not of the call handler.
+ </p><p>
+ It's up to the call handler to fetch the entry of the function from the
+ <code class="classname">pg_proc</code> system catalog and to analyze the argument
+ and return types of the called function. The <code class="literal">AS</code> clause from the
+ <code class="command">CREATE FUNCTION</code> command for the function will be found
+ in the <code class="literal">prosrc</code> column of the
+ <code class="classname">pg_proc</code> row. This is commonly source
+ text in the procedural language, but in theory it could be something else,
+ such as a path name to a file, or anything else that tells the call handler
+ what to do in detail.
+ </p><p>
+ Often, the same function is called many times per SQL statement.
+ A call handler can avoid repeated lookups of information about the
+ called function by using the
+ <code class="structfield">flinfo-&gt;fn_extra</code> field. This will
+ initially be <code class="symbol">NULL</code>, but can be set by the call handler to point at
+ information about the called function. On subsequent calls, if
+ <code class="structfield">flinfo-&gt;fn_extra</code> is already non-<code class="symbol">NULL</code>
+ then it can be used and the information lookup step skipped. The
+ call handler must make sure that
+ <code class="structfield">flinfo-&gt;fn_extra</code> is made to point at
+ memory that will live at least until the end of the current query,
+ since an <code class="structname">FmgrInfo</code> data structure could be
+ kept that long. One way to do this is to allocate the extra data
+ in the memory context specified by
+ <code class="structfield">flinfo-&gt;fn_mcxt</code>; such data will
+ normally have the same lifespan as the
+ <code class="structname">FmgrInfo</code> itself. But the handler could
+ also choose to use a longer-lived memory context so that it can cache
+ function definition information across queries.
+ </p><p>
+ When a procedural-language function is invoked as a trigger, no arguments
+ are passed in the usual way, but the
+ <code class="structname">FunctionCallInfoBaseData</code>'s
+ <code class="structfield">context</code> field points at a
+ <code class="structname">TriggerData</code> structure, rather than being <code class="symbol">NULL</code>
+ as it is in a plain function call. A language handler should
+ provide mechanisms for procedural-language functions to get at the trigger
+ information.
+ </p><p>
+ A template for a procedural-language handler written as a C extension is
+ provided in <code class="literal">src/test/modules/plsample</code>. This is a
+ working sample demonstrating one way to create a procedural-language
+ handler, process parameters, and return a value.
+ </p><p>
+ Although providing a call handler is sufficient to create a minimal
+ procedural language, there are two other functions that can optionally
+ be provided to make the language more convenient to use. These
+ are a <em class="firstterm">validator</em> and an
+ <em class="firstterm">inline handler</em>. A validator can be provided
+ to allow language-specific checking to be done during
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>.
+ An inline handler can be provided to allow the language to support
+ anonymous code blocks executed via the <a class="xref" href="sql-do.html" title="DO"><span class="refentrytitle">DO</span></a> command.
+ </p><p>
+ If a validator is provided by a procedural language, it
+ must be declared as a function taking a single parameter of type
+ <code class="type">oid</code>. The validator's result is ignored, so it is customarily
+ declared to return <code class="type">void</code>. The validator will be called at
+ the end of a <code class="command">CREATE FUNCTION</code> command that has created
+ or updated a function written in the procedural language.
+ The passed-in OID is the OID of the function's <code class="classname">pg_proc</code>
+ row. The validator must fetch this row in the usual way, and do
+ whatever checking is appropriate.
+ First, call <code class="function">CheckFunctionValidatorAccess()</code> to diagnose
+ explicit calls to the validator that the user could not achieve through
+ <code class="command">CREATE FUNCTION</code>. Typical checks then include verifying
+ that the function's argument and result types are supported by the
+ language, and that the function's body is syntactically correct
+ in the language. If the validator finds the function to be okay,
+ it should just return. If it finds an error, it should report that
+ via the normal <code class="function">ereport()</code> error reporting mechanism.
+ Throwing an error will force a transaction rollback and thus prevent
+ the incorrect function definition from being committed.
+ </p><p>
+ Validator functions should typically honor the <a class="xref" href="runtime-config-client.html#GUC-CHECK-FUNCTION-BODIES">check_function_bodies</a> parameter: if it is turned off then
+ any expensive or context-sensitive checking should be skipped. If the
+ language provides for code execution at compilation time, the validator
+ must suppress checks that would induce such execution. In particular,
+ this parameter is turned off by <span class="application">pg_dump</span> so that it can
+ load procedural language functions without worrying about side effects or
+ dependencies of the function bodies on other database objects.
+ (Because of this requirement, the call handler should avoid
+ assuming that the validator has fully checked the function. The point
+ of having a validator is not to let the call handler omit checks, but
+ to notify the user immediately if there are obvious errors in a
+ <code class="command">CREATE FUNCTION</code> command.)
+ While the choice of exactly what to check is mostly left to the
+ discretion of the validator function, note that the core
+ <code class="command">CREATE FUNCTION</code> code only executes <code class="literal">SET</code> clauses
+ attached to a function when <code class="varname">check_function_bodies</code> is on.
+ Therefore, checks whose results might be affected by GUC parameters
+ definitely should be skipped when <code class="varname">check_function_bodies</code> is
+ off, to avoid false failures when restoring a dump.
+ </p><p>
+ If an inline handler is provided by a procedural language, it
+ must be declared as a function taking a single parameter of type
+ <code class="type">internal</code>. The inline handler's result is ignored, so it is
+ customarily declared to return <code class="type">void</code>. The inline handler
+ will be called when a <code class="command">DO</code> statement is executed specifying
+ the procedural language. The parameter actually passed is a pointer
+ to an <code class="structname">InlineCodeBlock</code> struct, which contains information
+ about the <code class="command">DO</code> statement's parameters, in particular the
+ text of the anonymous code block to be executed. The inline handler
+ should execute this code and return.
+ </p><p>
+ It's recommended that you wrap all these function declarations,
+ as well as the <code class="command">CREATE LANGUAGE</code> command itself, into
+ an <em class="firstterm">extension</em> so that a simple <code class="command">CREATE EXTENSION</code>
+ command is sufficient to install the language. See
+ <a class="xref" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Section 38.17</a> for information about writing
+ extensions.
+ </p><p>
+ The procedural languages included in the standard distribution
+ are good references when trying to write your own language handler.
+ Look into the <code class="filename">src/pl</code> subdirectory of the source tree.
+ The <a class="xref" href="sql-createlanguage.html" title="CREATE LANGUAGE"><span class="refentrytitle">CREATE LANGUAGE</span></a>
+ reference page also has some useful details.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="nls-programmer.html" title="57.2. For the Programmer">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="fdwhandler.html" title="Chapter 59. Writing a Foreign Data Wrapper">Next</a></td></tr><tr><td width="40%" align="left" valign="top">57.2. For the Programmer </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 59. Writing a Foreign Data Wrapper</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-builtins.html b/doc/src/sgml/html/plperl-builtins.html
new file mode 100644
index 0000000..e1e8b15
--- /dev/null
+++ b/doc/src/sgml/html/plperl-builtins.html
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.3. Built-in Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-data.html" title="45.2. Data Values in PL/Perl" /><link rel="next" href="plperl-global.html" title="45.4. Global Values in PL/Perl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.3. Built-in Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-data.html" title="45.2. Data Values in PL/Perl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-global.html" title="45.4. Global Values in PL/Perl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-BUILTINS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.3. Built-in Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plperl-builtins.html#PLPERL-DATABASE">45.3.1. Database Access from PL/Perl</a></span></dt><dt><span class="sect2"><a href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">45.3.2. Utility Functions in PL/Perl</a></span></dt></dl></div><div class="sect2" id="PLPERL-DATABASE"><div class="titlepage"><div><div><h3 class="title">45.3.1. Database Access from PL/Perl</h3></div></div></div><p>
+ Access to the database itself from your Perl function can be done
+ via the following functions:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal"><code class="function">spi_exec_query</code>(<em class="replaceable"><code>query</code></em> [, <em class="replaceable"><code>limit</code></em>])</code>
+ <a id="id-1.8.10.11.2.3.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="function">spi_exec_query</code> executes an SQL command and
+returns the entire row set as a reference to an array of hash references.
+If <em class="replaceable"><code>limit</code></em> is specified and is greater than zero,
+then <code class="function">spi_exec_query</code> retrieves at
+most <em class="replaceable"><code>limit</code></em> rows, much as if the query included
+a <code class="literal">LIMIT</code> clause. Omitting <em class="replaceable"><code>limit</code></em>
+or specifying it as zero results in no row limit.
+ </p><p>
+<span class="emphasis"><em>You should only use this command when you know
+that the result set will be relatively small.</em></span> Here is an
+example of a query (<code class="command">SELECT</code> command) with the
+optional maximum number of rows:
+
+</p><pre class="programlisting">
+$rv = spi_exec_query('SELECT * FROM my_table', 5);
+</pre><p>
+ This returns up to 5 rows from the table
+ <code class="literal">my_table</code>. If <code class="literal">my_table</code>
+ has a column <code class="literal">my_column</code>, you can get that
+ value from row <code class="literal">$i</code> of the result like this:
+</p><pre class="programlisting">
+$foo = $rv-&gt;{rows}[$i]-&gt;{my_column};
+</pre><p>
+ The total number of rows returned from a <code class="command">SELECT</code>
+ query can be accessed like this:
+</p><pre class="programlisting">
+$nrows = $rv-&gt;{processed}
+</pre><p>
+ </p><p>
+ Here is an example using a different command type:
+</p><pre class="programlisting">
+$query = "INSERT INTO my_table VALUES (1, 'test')";
+$rv = spi_exec_query($query);
+</pre><p>
+ You can then access the command status (e.g.,
+ <code class="literal">SPI_OK_INSERT</code>) like this:
+</p><pre class="programlisting">
+$res = $rv-&gt;{status};
+</pre><p>
+ To get the number of rows affected, do:
+</p><pre class="programlisting">
+$nrows = $rv-&gt;{processed};
+</pre><p>
+ </p><p>
+ Here is a complete example:
+</p><pre class="programlisting">
+CREATE TABLE test (
+ i int,
+ v varchar
+);
+
+INSERT INTO test (i, v) VALUES (1, 'first line');
+INSERT INTO test (i, v) VALUES (2, 'second line');
+INSERT INTO test (i, v) VALUES (3, 'third line');
+INSERT INTO test (i, v) VALUES (4, 'immortal');
+
+CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$
+ my $rv = spi_exec_query('select i, v from test;');
+ my $status = $rv-&gt;{status};
+ my $nrows = $rv-&gt;{processed};
+ foreach my $rn (0 .. $nrows - 1) {
+ my $row = $rv-&gt;{rows}[$rn];
+ $row-&gt;{i} += 200 if defined($row-&gt;{i});
+ $row-&gt;{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row-&gt;{v}));
+ return_next($row);
+ }
+ return undef;
+$$ LANGUAGE plperl;
+
+SELECT * FROM test_munge();
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">spi_query(<em class="replaceable"><code>command</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.2.1.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">spi_fetchrow(<em class="replaceable"><code>cursor</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.2.2.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">spi_cursor_close(<em class="replaceable"><code>cursor</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.2.3.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="literal">spi_query</code> and <code class="literal">spi_fetchrow</code>
+ work together as a pair for row sets which might be large, or for cases
+ where you wish to return rows as they arrive.
+ <code class="literal">spi_fetchrow</code> works <span class="emphasis"><em>only</em></span> with
+ <code class="literal">spi_query</code>. The following example illustrates how
+ you use them together:
+
+</p><pre class="programlisting">
+CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);
+
+CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
+ use Digest::MD5 qw(md5_hex);
+ my $file = '/usr/share/dict/words';
+ my $t = localtime;
+ elog(NOTICE, "opening file $file at $t" );
+ open my $fh, '&lt;', $file # ooh, it's a file access!
+ or elog(ERROR, "cannot open $file for reading: $!");
+ my @words = &lt;$fh&gt;;
+ close $fh;
+ $t = localtime;
+ elog(NOTICE, "closed file $file at $t");
+ chomp(@words);
+ my $row;
+ my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
+ while (defined ($row = spi_fetchrow($sth))) {
+ return_next({
+ the_num =&gt; $row-&gt;{a},
+ the_text =&gt; md5_hex($words[rand @words])
+ });
+ }
+ return;
+$$ LANGUAGE plperlu;
+
+SELECT * from lotsa_md5(500);
+</pre><p>
+ </p><p>
+ Normally, <code class="function">spi_fetchrow</code> should be repeated until it
+ returns <code class="literal">undef</code>, indicating that there are no more
+ rows to read. The cursor returned by <code class="literal">spi_query</code>
+ is automatically freed when
+ <code class="function">spi_fetchrow</code> returns <code class="literal">undef</code>.
+ If you do not wish to read all the rows, instead call
+ <code class="function">spi_cursor_close</code> to free the cursor.
+ Failure to do so will result in memory leaks.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">spi_prepare(<em class="replaceable"><code>command</code></em>, <em class="replaceable"><code>argument types</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.3.1.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">spi_query_prepared(<em class="replaceable"><code>plan</code></em>, <em class="replaceable"><code>arguments</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.3.2.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">spi_exec_prepared(<em class="replaceable"><code>plan</code></em> [, <em class="replaceable"><code>attributes</code></em>], <em class="replaceable"><code>arguments</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.3.3.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">spi_freeplan(<em class="replaceable"><code>plan</code></em>)</code></code>
+ <a id="id-1.8.10.11.2.3.3.4.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="literal">spi_prepare</code>, <code class="literal">spi_query_prepared</code>, <code class="literal">spi_exec_prepared</code>,
+ and <code class="literal">spi_freeplan</code> implement the same functionality but for prepared queries.
+ <code class="literal">spi_prepare</code> accepts a query string with numbered argument placeholders ($1, $2, etc.)
+ and a string list of argument types:
+</p><pre class="programlisting">
+$plan = spi_prepare('SELECT * FROM test WHERE id &gt; $1 AND name = $2',
+ 'INTEGER', 'TEXT');
+</pre><p>
+ Once a query plan is prepared by a call to <code class="literal">spi_prepare</code>, the plan can be used instead
+ of the string query, either in <code class="literal">spi_exec_prepared</code>, where the result is the same as returned
+ by <code class="literal">spi_exec_query</code>, or in <code class="literal">spi_query_prepared</code> which returns a cursor
+ exactly as <code class="literal">spi_query</code> does, which can be later passed to <code class="literal">spi_fetchrow</code>.
+ The optional second parameter to <code class="literal">spi_exec_prepared</code> is a hash reference of attributes;
+ the only attribute currently supported is <code class="literal">limit</code>, which
+ sets the maximum number of rows returned from the query.
+ Omitting <code class="literal">limit</code> or specifying it as zero results in no
+ row limit.
+ </p><p>
+ The advantage of prepared queries is that is it possible to use one prepared plan for more
+ than one query execution. After the plan is not needed anymore, it can be freed with
+ <code class="literal">spi_freeplan</code>:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$
+ $_SHARED{my_plan} = spi_prepare('SELECT (now() + $1)::date AS now',
+ 'INTERVAL');
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
+ return spi_exec_prepared(
+ $_SHARED{my_plan},
+ $_[0]
+ )-&gt;{rows}-&gt;[0]-&gt;{now};
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$
+ spi_freeplan( $_SHARED{my_plan});
+ undef $_SHARED{my_plan};
+$$ LANGUAGE plperl;
+
+SELECT init();
+SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
+SELECT done();
+
+ add_time | add_time | add_time
+------------+------------+------------
+ 2005-12-10 | 2005-12-11 | 2005-12-12
+</pre><p>
+ Note that the parameter subscript in <code class="literal">spi_prepare</code> is defined via
+ $1, $2, $3, etc., so avoid declaring query strings in double quotes that might easily
+ lead to hard-to-catch bugs.
+ </p><p>
+ Another example illustrates usage of an optional parameter in <code class="literal">spi_exec_prepared</code>:
+</p><pre class="programlisting">
+CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address
+ FROM generate_series(1,3) AS id;
+
+CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$
+ $_SHARED{plan} = spi_prepare('SELECT * FROM hosts
+ WHERE address &lt;&lt; $1', 'inet');
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$
+ return spi_exec_prepared(
+ $_SHARED{plan},
+ {limit =&gt; 2},
+ $_[0]
+ )-&gt;{rows};
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION release_hosts_query() RETURNS VOID AS $$
+ spi_freeplan($_SHARED{plan});
+ undef $_SHARED{plan};
+$$ LANGUAGE plperl;
+
+SELECT init_hosts_query();
+SELECT query_hosts('192.168.1.0/30');
+SELECT release_hosts_query();
+
+ query_hosts
+-----------------
+ (1,192.168.1.1)
+ (2,192.168.1.2)
+(2 rows)
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">spi_commit()</code></code>
+ <a id="id-1.8.10.11.2.3.4.1.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">spi_rollback()</code></code>
+ <a id="id-1.8.10.11.2.3.4.2.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Commit or roll back the current transaction. This can only be called
+ in a procedure or anonymous code block (<code class="command">DO</code> command)
+ called from the top level. (Note that it is not possible to run the
+ SQL commands <code class="command">COMMIT</code> or <code class="command">ROLLBACK</code>
+ via <code class="function">spi_exec_query</code> or similar. It has to be done
+ using these functions.) After a transaction is ended, a new
+ transaction is automatically started, so there is no separate function
+ for that.
+ </p><p>
+ Here is an example:
+</p><pre class="programlisting">
+CREATE PROCEDURE transaction_test1()
+LANGUAGE plperl
+AS $$
+foreach my $i (0..9) {
+ spi_exec_query("INSERT INTO test1 (a) VALUES ($i)");
+ if ($i % 2 == 0) {
+ spi_commit();
+ } else {
+ spi_rollback();
+ }
+}
+$$;
+
+CALL transaction_test1();
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="PLPERL-UTILITY-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">45.3.2. Utility Functions in PL/Perl</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal"><code class="function">elog(<em class="replaceable"><code>level</code></em>, <em class="replaceable"><code>msg</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Emit a log or error message. Possible levels are
+ <code class="literal">DEBUG</code>, <code class="literal">LOG</code>, <code class="literal">INFO</code>,
+ <code class="literal">NOTICE</code>, <code class="literal">WARNING</code>, and <code class="literal">ERROR</code>.
+ <code class="literal">ERROR</code>
+ raises an error condition; if this is not trapped by the surrounding
+ Perl code, the error propagates out to the calling query, causing
+ the current transaction or subtransaction to be aborted. This
+ is effectively the same as the Perl <code class="literal">die</code> command.
+ The other levels only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a> and
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> configuration
+ variables. See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for more
+ information.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">quote_literal(<em class="replaceable"><code>string</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Return the given string suitably quoted to be used as a string literal in an SQL
+ statement string. Embedded single-quotes and backslashes are properly doubled.
+ Note that <code class="function">quote_literal</code> returns undef on undef input; if the argument
+ might be undef, <code class="function">quote_nullable</code> is often more suitable.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">quote_nullable(<em class="replaceable"><code>string</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Return the given string suitably quoted to be used as a string literal in an SQL
+ statement string; or, if the argument is undef, return the unquoted string "NULL".
+ Embedded single-quotes and backslashes are properly doubled.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">quote_ident(<em class="replaceable"><code>string</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Return the given string suitably quoted to be used as an identifier in
+ an SQL statement string. Quotes are added only if necessary (i.e., if
+ the string contains non-identifier characters or would be case-folded).
+ Embedded quotes are properly doubled.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">decode_bytea(<em class="replaceable"><code>string</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.5.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Return the unescaped binary data represented by the contents of the given string,
+ which should be <code class="type">bytea</code> encoded.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">encode_bytea(<em class="replaceable"><code>string</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.6.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Return the <code class="type">bytea</code> encoded form of the binary data contents of the given string.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">encode_array_literal(<em class="replaceable"><code>array</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.7.1.2" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="literal"><code class="function">encode_array_literal(<em class="replaceable"><code>array</code></em>, <em class="replaceable"><code>delimiter</code></em>)</code></code>
+ </span></dt><dd><p>
+ Returns the contents of the referenced array as a string in array literal format
+ (see <a class="xref" href="arrays.html#ARRAYS-INPUT" title="8.15.2. Array Value Input">Section 8.15.2</a>).
+ Returns the argument value unaltered if it's not a reference to an array.
+ The delimiter used between elements of the array literal defaults to "<code class="literal">, </code>"
+ if a delimiter is not specified or is undef.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">encode_typed_literal(<em class="replaceable"><code>value</code></em>, <em class="replaceable"><code>typename</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.8.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Converts a Perl variable to the value of the data type passed as a
+ second argument and returns a string representation of this value.
+ Correctly handles nested arrays and values of composite types.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">encode_array_constructor(<em class="replaceable"><code>array</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.9.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns the contents of the referenced array as a string in array constructor format
+ (see <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS" title="4.2.12. Array Constructors">Section 4.2.12</a>).
+ Individual values are quoted using <code class="function">quote_nullable</code>.
+ Returns the argument value, quoted using <code class="function">quote_nullable</code>,
+ if it's not a reference to an array.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">looks_like_number(<em class="replaceable"><code>string</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.10.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns a true value if the content of the given string looks like a
+ number, according to Perl, returns false otherwise.
+ Returns undef if the argument is undef. Leading and trailing space is
+ ignored. <code class="literal">Inf</code> and <code class="literal">Infinity</code> are regarded as numbers.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="function">is_array_ref(<em class="replaceable"><code>argument</code></em>)</code></code>
+ <a id="id-1.8.10.11.3.2.11.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns a true value if the given argument may be treated as an
+ array reference, that is, if ref of the argument is <code class="literal">ARRAY</code> or
+ <code class="literal">PostgreSQL::InServer::ARRAY</code>. Returns false otherwise.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-data.html" title="45.2. Data Values in PL/Perl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-global.html" title="45.4. Global Values in PL/Perl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.2. Data Values in PL/Perl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.4. Global Values in PL/Perl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-data.html b/doc/src/sgml/html/plperl-data.html
new file mode 100644
index 0000000..8232061
--- /dev/null
+++ b/doc/src/sgml/html/plperl-data.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.2. Data Values in PL/Perl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-funcs.html" title="45.1. PL/Perl Functions and Arguments" /><link rel="next" href="plperl-builtins.html" title="45.3. Built-in Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.2. Data Values in PL/Perl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-funcs.html" title="45.1. PL/Perl Functions and Arguments">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-builtins.html" title="45.3. Built-in Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-DATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.2. Data Values in PL/Perl</h2></div></div></div><p>
+ The argument values supplied to a PL/Perl function's code are
+ simply the input arguments converted to text form (just as if they
+ had been displayed by a <code class="command">SELECT</code> statement).
+ Conversely, the <code class="function">return</code> and <code class="function">return_next</code>
+ commands will accept any string that is acceptable input format
+ for the function's declared return type.
+ </p><p>
+ If this behavior is inconvenient for a particular case, it can be
+ improved by using a transform, as already illustrated
+ for <code class="type">bool</code> values. Several examples of transform modules
+ are included in the <span class="productname">PostgreSQL</span> distribution.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-funcs.html" title="45.1. PL/Perl Functions and Arguments">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-builtins.html" title="45.3. Built-in Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.1. PL/Perl Functions and Arguments </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.3. Built-in Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-event-triggers.html b/doc/src/sgml/html/plperl-event-triggers.html
new file mode 100644
index 0000000..9952f7a
--- /dev/null
+++ b/doc/src/sgml/html/plperl-event-triggers.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.7. PL/Perl Event Triggers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-triggers.html" title="45.6. PL/Perl Triggers" /><link rel="next" href="plperl-under-the-hood.html" title="45.8. PL/Perl Under the Hood" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.7. PL/Perl Event Triggers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-triggers.html" title="45.6. PL/Perl Triggers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-under-the-hood.html" title="45.8. PL/Perl Under the Hood">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-EVENT-TRIGGERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.7. PL/Perl Event Triggers</h2></div></div></div><p>
+ PL/Perl can be used to write event trigger functions. In an event trigger
+ function, the hash reference <code class="varname">$_TD</code> contains information
+ about the current trigger event. <code class="varname">$_TD</code> is a global variable,
+ which gets a separate local value for each invocation of the trigger. The
+ fields of the <code class="varname">$_TD</code> hash reference are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">$_TD-&gt;{event}</code></span></dt><dd><p>
+ The name of the event the trigger is fired for.
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{tag}</code></span></dt><dd><p>
+ The command tag for which the trigger is fired.
+ </p></dd></dl></div><p>
+ </p><p>
+ The return value of the trigger function is ignored.
+ </p><p>
+ Here is an example of an event trigger function, illustrating some of the
+ above:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION perlsnitch() RETURNS event_trigger AS $$
+ elog(NOTICE, "perlsnitch: " . $_TD-&gt;{event} . " " . $_TD-&gt;{tag} . " ");
+$$ LANGUAGE plperl;
+
+CREATE EVENT TRIGGER perl_a_snitch
+ ON ddl_command_start
+ EXECUTE FUNCTION perlsnitch();
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-triggers.html" title="45.6. PL/Perl Triggers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-under-the-hood.html" title="45.8. PL/Perl Under the Hood">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.6. PL/Perl Triggers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.8. PL/Perl Under the Hood</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-funcs.html b/doc/src/sgml/html/plperl-funcs.html
new file mode 100644
index 0000000..de579c4
--- /dev/null
+++ b/doc/src/sgml/html/plperl-funcs.html
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.1. PL/Perl Functions and Arguments</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language" /><link rel="next" href="plperl-data.html" title="45.2. Data Values in PL/Perl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.1. PL/Perl Functions and Arguments</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-data.html" title="45.2. Data Values in PL/Perl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-FUNCS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.1. PL/Perl Functions and Arguments</h2></div></div></div><p>
+ To create a function in the PL/Perl language, use the standard
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>
+ syntax:
+
+</p><pre class="programlisting">
+CREATE FUNCTION <em class="replaceable"><code>funcname</code></em> (<em class="replaceable"><code>argument-types</code></em>)
+RETURNS <em class="replaceable"><code>return-type</code></em>
+-- function attributes can go here
+AS $$
+ # PL/Perl function body goes here
+$$ LANGUAGE plperl;
+</pre><p>
+
+ The body of the function is ordinary Perl code. In fact, the PL/Perl
+ glue code wraps it inside a Perl subroutine. A PL/Perl function is
+ called in a scalar context, so it can't return a list. You can return
+ non-scalar values (arrays, records, and sets) by returning a reference,
+ as discussed below.
+ </p><p>
+ In a PL/Perl procedure, any return value from the Perl code is ignored.
+ </p><p>
+ PL/Perl also supports anonymous code blocks called with the
+ <a class="xref" href="sql-do.html" title="DO"><span class="refentrytitle">DO</span></a> statement:
+
+</p><pre class="programlisting">
+DO $$
+ # PL/Perl code
+$$ LANGUAGE plperl;
+</pre><p>
+
+ An anonymous code block receives no arguments, and whatever value it
+ might return is discarded. Otherwise it behaves just like a function.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The use of named nested subroutines is dangerous in Perl, especially if
+ they refer to lexical variables in the enclosing scope. Because a PL/Perl
+ function is wrapped in a subroutine, any named subroutine you place inside
+ one will be nested. In general, it is far safer to create anonymous
+ subroutines which you call via a coderef. For more information, see the
+ entries for <code class="literal">Variable "%s" will not stay shared</code> and
+ <code class="literal">Variable "%s" is not available</code> in the
+ <span class="citerefentry"><span class="refentrytitle">perldiag</span></span> man page, or
+ search the Internet for <span class="quote">“<span class="quote">perl nested named subroutine</span>”</span>.
+ </p></div><p>
+ The syntax of the <code class="command">CREATE FUNCTION</code> command requires
+ the function body to be written as a string constant. It is usually
+ most convenient to use dollar quoting (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>) for the string constant.
+ If you choose to use escape string syntax <code class="literal">E''</code>,
+ you must double any single quote marks (<code class="literal">'</code>) and backslashes
+ (<code class="literal">\</code>) used in the body of the function
+ (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a>).
+ </p><p>
+ Arguments and results are handled as in any other Perl subroutine:
+ arguments are passed in <code class="varname">@_</code>, and a result value
+ is returned with <code class="literal">return</code> or as the last expression
+ evaluated in the function.
+ </p><p>
+ For example, a function returning the greater of two integer values
+ could be defined as:
+
+</p><pre class="programlisting">
+CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
+ if ($_[0] &gt; $_[1]) { return $_[0]; }
+ return $_[1];
+$$ LANGUAGE plperl;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Arguments will be converted from the database's encoding to UTF-8
+ for use inside PL/Perl, and then converted from UTF-8 back to the
+ database encoding upon return.
+ </p></div><p>
+ If an SQL null value<a id="id-1.8.10.9.10.1" class="indexterm"></a> is passed to a function,
+ the argument value will appear as <span class="quote">“<span class="quote">undefined</span>”</span> in Perl. The
+ above function definition will not behave very nicely with null
+ inputs (in fact, it will act as though they are zeroes). We could
+ add <code class="literal">STRICT</code> to the function definition to make
+ <span class="productname">PostgreSQL</span> do something more reasonable:
+ if a null value is passed, the function will not be called at all,
+ but will just return a null result automatically. Alternatively,
+ we could check for undefined inputs in the function body. For
+ example, suppose that we wanted <code class="function">perl_max</code> with
+ one null and one nonnull argument to return the nonnull argument,
+ rather than a null value:
+
+</p><pre class="programlisting">
+CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
+ my ($x, $y) = @_;
+ if (not defined $x) {
+ return undef if not defined $y;
+ return $y;
+ }
+ return $x if not defined $y;
+ return $x if $x &gt; $y;
+ return $y;
+$$ LANGUAGE plperl;
+</pre><p>
+ As shown above, to return an SQL null value from a PL/Perl
+ function, return an undefined value. This can be done whether the
+ function is strict or not.
+ </p><p>
+ Anything in a function argument that is not a reference is
+ a string, which is in the standard <span class="productname">PostgreSQL</span>
+ external text representation for the relevant data type. In the case of
+ ordinary numeric or text types, Perl will just do the right thing and
+ the programmer will normally not have to worry about it. However, in
+ other cases the argument will need to be converted into a form that is
+ more usable in Perl. For example, the <code class="function">decode_bytea</code>
+ function can be used to convert an argument of
+ type <code class="type">bytea</code> into unescaped binary.
+ </p><p>
+ Similarly, values passed back to <span class="productname">PostgreSQL</span>
+ must be in the external text representation format. For example, the
+ <code class="function">encode_bytea</code> function can be used to
+ escape binary data for a return value of type <code class="type">bytea</code>.
+ </p><p>
+ One case that is particularly important is boolean values. As just
+ stated, the default behavior for <code class="type">bool</code> values is that they
+ are passed to Perl as text, thus either <code class="literal">'t'</code>
+ or <code class="literal">'f'</code>. This is problematic, since Perl will not
+ treat <code class="literal">'f'</code> as false! It is possible to improve matters
+ by using a <span class="quote">“<span class="quote">transform</span>”</span> (see
+ <a class="xref" href="sql-createtransform.html" title="CREATE TRANSFORM"><span class="refentrytitle">CREATE TRANSFORM</span></a>). Suitable transforms are provided
+ by the <code class="filename">bool_plperl</code> extension. To use it, install
+ the extension:
+</p><pre class="programlisting">
+CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU
+</pre><p>
+ Then use the <code class="literal">TRANSFORM</code> function attribute for a
+ PL/Perl function that takes or returns <code class="type">bool</code>, for example:
+</p><pre class="programlisting">
+CREATE FUNCTION perl_and(bool, bool) RETURNS bool
+TRANSFORM FOR TYPE bool
+AS $$
+ my ($a, $b) = @_;
+ return $a &amp;&amp; $b;
+$$ LANGUAGE plperl;
+</pre><p>
+ When this transform is applied, <code class="type">bool</code> arguments will be seen
+ by Perl as being <code class="literal">1</code> or empty, thus properly true or
+ false. If the function result is type <code class="type">bool</code>, it will be true
+ or false according to whether Perl would evaluate the returned value as
+ true.
+ Similar transformations are also performed for boolean query arguments
+ and results of SPI queries performed inside the function
+ (<a class="xref" href="plperl-builtins.html#PLPERL-DATABASE" title="45.3.1. Database Access from PL/Perl">Section 45.3.1</a>).
+ </p><p>
+ Perl can return <span class="productname">PostgreSQL</span> arrays as
+ references to Perl arrays. Here is an example:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE function returns_array()
+RETURNS text[][] AS $$
+ return [['a"b','c,d'],['e\\f','g']];
+$$ LANGUAGE plperl;
+
+select returns_array();
+</pre><p>
+ </p><p>
+ Perl passes <span class="productname">PostgreSQL</span> arrays as a blessed
+ <code class="type">PostgreSQL::InServer::ARRAY</code> object. This object may be treated as an array
+ reference or a string, allowing for backward compatibility with Perl
+ code written for <span class="productname">PostgreSQL</span> versions below 9.1 to
+ run. For example:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$
+ my $arg = shift;
+ my $result = "";
+ return undef if (!defined $arg);
+
+ # as an array reference
+ for (@$arg) {
+ $result .= $_;
+ }
+
+ # also works as a string
+ $result .= $arg;
+
+ return $result;
+$$ LANGUAGE plperl;
+
+SELECT concat_array_elements(ARRAY['PL','/','Perl']);
+</pre><p>
+
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Multidimensional arrays are represented as references to
+ lower-dimensional arrays of references in a way common to every Perl
+ programmer.
+ </p></div><p>
+ </p><p>
+ Composite-type arguments are passed to the function as references
+ to hashes. The keys of the hash are the attribute names of the
+ composite type. Here is an example:
+
+</p><pre class="programlisting">
+CREATE TABLE employee (
+ name text,
+ basesalary integer,
+ bonus integer
+);
+
+CREATE FUNCTION empcomp(employee) RETURNS integer AS $$
+ my ($emp) = @_;
+ return $emp-&gt;{basesalary} + $emp-&gt;{bonus};
+$$ LANGUAGE plperl;
+
+SELECT name, empcomp(employee.*) FROM employee;
+</pre><p>
+ </p><p>
+ A PL/Perl function can return a composite-type result using the same
+ approach: return a reference to a hash that has the required attributes.
+ For example:
+
+</p><pre class="programlisting">
+CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text);
+
+CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$
+ return {f2 =&gt; 'hello', f1 =&gt; 1, f3 =&gt; 'world'};
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_row();
+</pre><p>
+
+ Any columns in the declared result data type that are not present in the
+ hash will be returned as null values.
+ </p><p>
+ Similarly, output arguments of procedures can be returned as a hash
+ reference:
+
+</p><pre class="programlisting">
+CREATE PROCEDURE perl_triple(INOUT a integer, INOUT b integer) AS $$
+ my ($a, $b) = @_;
+ return {a =&gt; $a * 3, b =&gt; $b * 3};
+$$ LANGUAGE plperl;
+
+CALL perl_triple(5, 10);
+</pre><p>
+ </p><p>
+ PL/Perl functions can also return sets of either scalar or
+ composite types. Usually you'll want to return rows one at a
+ time, both to speed up startup time and to keep from queuing up
+ the entire result set in memory. You can do this with
+ <code class="function">return_next</code> as illustrated below. Note that
+ after the last <code class="function">return_next</code>, you must put
+ either <code class="literal">return</code> or (better) <code class="literal">return
+ undef</code>.
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION perl_set_int(int)
+RETURNS SETOF INTEGER AS $$
+ foreach (0..$_[0]) {
+ return_next($_);
+ }
+ return undef;
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set_int(5);
+
+CREATE OR REPLACE FUNCTION perl_set()
+RETURNS SETOF testrowperl AS $$
+ return_next({ f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' });
+ return_next({ f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' });
+ return_next({ f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' });
+ return undef;
+$$ LANGUAGE plperl;
+</pre><p>
+
+ For small result sets, you can return a reference to an array that
+ contains either scalars, references to arrays, or references to
+ hashes for simple types, array types, and composite types,
+ respectively. Here are some simple examples of returning the entire
+ result set as an array reference:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
+ return [0..$_[0]];
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set_int(5);
+
+CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
+ return [
+ { f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' },
+ { f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' },
+ { f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' }
+ ];
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set();
+</pre><p>
+ </p><p>
+ If you wish to use the <code class="literal">strict</code> pragma with your code you
+ have a few options. For temporary global use you can <code class="command">SET</code>
+ <code class="literal">plperl.use_strict</code> to true.
+ This will affect subsequent compilations of <span class="application">PL/Perl</span>
+ functions, but not functions already compiled in the current session.
+ For permanent global use you can set <code class="literal">plperl.use_strict</code>
+ to true in the <code class="filename">postgresql.conf</code> file.
+ </p><p>
+ For permanent use in specific functions you can simply put:
+</p><pre class="programlisting">
+use strict;
+</pre><p>
+ at the top of the function body.
+ </p><p>
+ The <code class="literal">feature</code> pragma is also available to <code class="function">use</code> if your Perl is version 5.10.0 or higher.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-data.html" title="45.2. Data Values in PL/Perl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 45. PL/Perl — Perl Procedural Language </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.2. Data Values in PL/Perl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-global.html b/doc/src/sgml/html/plperl-global.html
new file mode 100644
index 0000000..fec3f61
--- /dev/null
+++ b/doc/src/sgml/html/plperl-global.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.4. Global Values in PL/Perl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-builtins.html" title="45.3. Built-in Functions" /><link rel="next" href="plperl-trusted.html" title="45.5. Trusted and Untrusted PL/Perl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.4. Global Values in PL/Perl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-builtins.html" title="45.3. Built-in Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-trusted.html" title="45.5. Trusted and Untrusted PL/Perl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-GLOBAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.4. Global Values in PL/Perl</h2></div></div></div><p>
+ You can use the global hash <code class="varname">%_SHARED</code> to store
+ data, including code references, between function calls for the
+ lifetime of the current session.
+ </p><p>
+ Here is a simple example for shared data:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$
+ if ($_SHARED{$_[0]} = $_[1]) {
+ return 'ok';
+ } else {
+ return "cannot set shared variable $_[0] to $_[1]";
+ }
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$
+ return $_SHARED{$_[0]};
+$$ LANGUAGE plperl;
+
+SELECT set_var('sample', 'Hello, PL/Perl! How''s tricks?');
+SELECT get_var('sample');
+</pre><p>
+ </p><p>
+ Here is a slightly more complicated example using a code reference:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$
+ $_SHARED{myquote} = sub {
+ my $arg = shift;
+ $arg =~ s/(['\\])/\\$1/g;
+ return "'$arg'";
+ };
+$$ LANGUAGE plperl;
+
+SELECT myfuncs(); /* initializes the function */
+
+/* Set up a function that uses the quote function */
+
+CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$
+ my $text_to_quote = shift;
+ my $qfunc = $_SHARED{myquote};
+ return &amp;$qfunc($text_to_quote);
+$$ LANGUAGE plperl;
+</pre><p>
+
+ (You could have replaced the above with the one-liner
+ <code class="literal">return $_SHARED{myquote}-&gt;($_[0]);</code>
+ at the expense of readability.)
+ </p><p>
+ For security reasons, PL/Perl executes functions called by any one SQL role
+ in a separate Perl interpreter for that role. This prevents accidental or
+ malicious interference by one user with the behavior of another user's
+ PL/Perl functions. Each such interpreter has its own value of the
+ <code class="varname">%_SHARED</code> variable and other global state. Thus, two
+ PL/Perl functions will share the same value of <code class="varname">%_SHARED</code>
+ if and only if they are executed by the same SQL role. In an application
+ wherein a single session executes code under multiple SQL roles (via
+ <code class="literal">SECURITY DEFINER</code> functions, use of <code class="command">SET ROLE</code>, etc.)
+ you may need to take explicit steps to ensure that PL/Perl functions can
+ share data via <code class="varname">%_SHARED</code>. To do that, make sure that
+ functions that should communicate are owned by the same user, and mark
+ them <code class="literal">SECURITY DEFINER</code>. You must of course take care that
+ such functions can't be used to do anything unintended.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-builtins.html" title="45.3. Built-in Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-trusted.html" title="45.5. Trusted and Untrusted PL/Perl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.3. Built-in Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.5. Trusted and Untrusted PL/Perl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-triggers.html b/doc/src/sgml/html/plperl-triggers.html
new file mode 100644
index 0000000..bd19ca6
--- /dev/null
+++ b/doc/src/sgml/html/plperl-triggers.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.6. PL/Perl Triggers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-trusted.html" title="45.5. Trusted and Untrusted PL/Perl" /><link rel="next" href="plperl-event-triggers.html" title="45.7. PL/Perl Event Triggers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.6. PL/Perl Triggers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-trusted.html" title="45.5. Trusted and Untrusted PL/Perl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-event-triggers.html" title="45.7. PL/Perl Event Triggers">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-TRIGGERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.6. PL/Perl Triggers</h2></div></div></div><p>
+ PL/Perl can be used to write trigger functions. In a trigger function,
+ the hash reference <code class="varname">$_TD</code> contains information about the
+ current trigger event. <code class="varname">$_TD</code> is a global variable,
+ which gets a separate local value for each invocation of the trigger.
+ The fields of the <code class="varname">$_TD</code> hash reference are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">$_TD-&gt;{new}{foo}</code></span></dt><dd><p>
+ <code class="literal">NEW</code> value of column <code class="literal">foo</code>
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{old}{foo}</code></span></dt><dd><p>
+ <code class="literal">OLD</code> value of column <code class="literal">foo</code>
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{name}</code></span></dt><dd><p>
+ Name of the trigger being called
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{event}</code></span></dt><dd><p>
+ Trigger event: <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, <code class="literal">TRUNCATE</code>, or <code class="literal">UNKNOWN</code>
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{when}</code></span></dt><dd><p>
+ When the trigger was called: <code class="literal">BEFORE</code>,
+ <code class="literal">AFTER</code>, <code class="literal">INSTEAD OF</code>, or
+ <code class="literal">UNKNOWN</code>
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{level}</code></span></dt><dd><p>
+ The trigger level: <code class="literal">ROW</code>, <code class="literal">STATEMENT</code>, or <code class="literal">UNKNOWN</code>
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{relid}</code></span></dt><dd><p>
+ OID of the table on which the trigger fired
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{table_name}</code></span></dt><dd><p>
+ Name of the table on which the trigger fired
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{relname}</code></span></dt><dd><p>
+ Name of the table on which the trigger fired. This has been deprecated,
+ and could be removed in a future release.
+ Please use $_TD-&gt;{table_name} instead.
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{table_schema}</code></span></dt><dd><p>
+ Name of the schema in which the table on which the trigger fired, is
+ </p></dd><dt><span class="term"><code class="literal">$_TD-&gt;{argc}</code></span></dt><dd><p>
+ Number of arguments of the trigger function
+ </p></dd><dt><span class="term"><code class="literal">@{$_TD-&gt;{args}}</code></span></dt><dd><p>
+ Arguments of the trigger function. Does not exist if <code class="literal">$_TD-&gt;{argc}</code> is 0.
+ </p></dd></dl></div><p>
+ </p><p>
+ Row-level triggers can return one of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">return;</code></span></dt><dd><p>
+ Execute the operation
+ </p></dd><dt><span class="term"><code class="literal">"SKIP"</code></span></dt><dd><p>
+ Don't execute the operation
+ </p></dd><dt><span class="term"><code class="literal">"MODIFY"</code></span></dt><dd><p>
+ Indicates that the <code class="literal">NEW</code> row was modified by
+ the trigger function
+ </p></dd></dl></div><p>
+ </p><p>
+ Here is an example of a trigger function, illustrating some of the
+ above:
+</p><pre class="programlisting">
+CREATE TABLE test (
+ i int,
+ v varchar
+);
+
+CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$
+ if (($_TD-&gt;{new}{i} &gt;= 100) || ($_TD-&gt;{new}{i} &lt;= 0)) {
+ return "SKIP"; # skip INSERT/UPDATE command
+ } elsif ($_TD-&gt;{new}{v} ne "immortal") {
+ $_TD-&gt;{new}{v} .= "(modified by trigger)";
+ return "MODIFY"; # modify row and execute INSERT/UPDATE command
+ } else {
+ return; # execute INSERT/UPDATE command
+ }
+$$ LANGUAGE plperl;
+
+CREATE TRIGGER test_valid_id_trig
+ BEFORE INSERT OR UPDATE ON test
+ FOR EACH ROW EXECUTE FUNCTION valid_id();
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-trusted.html" title="45.5. Trusted and Untrusted PL/Perl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-event-triggers.html" title="45.7. PL/Perl Event Triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.5. Trusted and Untrusted PL/Perl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.7. PL/Perl Event Triggers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-trusted.html b/doc/src/sgml/html/plperl-trusted.html
new file mode 100644
index 0000000..36b9d86
--- /dev/null
+++ b/doc/src/sgml/html/plperl-trusted.html
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.5. Trusted and Untrusted PL/Perl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-global.html" title="45.4. Global Values in PL/Perl" /><link rel="next" href="plperl-triggers.html" title="45.6. PL/Perl Triggers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.5. Trusted and Untrusted PL/Perl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-global.html" title="45.4. Global Values in PL/Perl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-triggers.html" title="45.6. PL/Perl Triggers">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-TRUSTED"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.5. Trusted and Untrusted PL/Perl</h2></div></div></div><a id="id-1.8.10.13.2" class="indexterm"></a><p>
+ Normally, PL/Perl is installed as a <span class="quote">“<span class="quote">trusted</span>”</span> programming
+ language named <code class="literal">plperl</code>. In this setup, certain Perl
+ operations are disabled to preserve security. In general, the
+ operations that are restricted are those that interact with the
+ environment. This includes file handle operations,
+ <code class="literal">require</code>, and <code class="literal">use</code> (for
+ external modules). There is no way to access internals of the
+ database server process or to gain OS-level access with the
+ permissions of the server process,
+ as a C function can do. Thus, any unprivileged database user can
+ be permitted to use this language.
+ </p><p>
+ Here is an example of a function that will not work because file
+ system operations are not allowed for security reasons:
+</p><pre class="programlisting">
+CREATE FUNCTION badfunc() RETURNS integer AS $$
+ my $tmpfile = "/tmp/badfile";
+ open my $fh, '&gt;', $tmpfile
+ or elog(ERROR, qq{could not open the file "$tmpfile": $!});
+ print $fh "Testing writing to a file\n";
+ close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!});
+ return 1;
+$$ LANGUAGE plperl;
+</pre><p>
+ The creation of this function will fail as its use of a forbidden
+ operation will be caught by the validator.
+ </p><p>
+ Sometimes it is desirable to write Perl functions that are not
+ restricted. For example, one might want a Perl function that sends
+ mail. To handle these cases, PL/Perl can also be installed as an
+ <span class="quote">“<span class="quote">untrusted</span>”</span> language (usually called
+ <span class="application">PL/PerlU</span><a id="id-1.8.10.13.5.3" class="indexterm"></a>).
+ In this case the full Perl language is available. When installing the
+ language, the language name <code class="literal">plperlu</code> will select
+ the untrusted PL/Perl variant.
+ </p><p>
+ The writer of a <span class="application">PL/PerlU</span> function must take care that the function
+ cannot be used to do anything unwanted, since it will be able to do
+ anything that could be done by a user logged in as the database
+ administrator. Note that the database system allows only database
+ superusers to create functions in untrusted languages.
+ </p><p>
+ If the above function was created by a superuser using the language
+ <code class="literal">plperlu</code>, execution would succeed.
+ </p><p>
+ In the same way, anonymous code blocks written in Perl can use
+ restricted operations if the language is specified as
+ <code class="literal">plperlu</code> rather than <code class="literal">plperl</code>, but the caller
+ must be a superuser.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ While <span class="application">PL/Perl</span> functions run in a separate Perl
+ interpreter for each SQL role, all <span class="application">PL/PerlU</span> functions
+ executed in a given session run in a single Perl interpreter (which is
+ not any of the ones used for <span class="application">PL/Perl</span> functions).
+ This allows <span class="application">PL/PerlU</span> functions to share data freely,
+ but no communication can occur between <span class="application">PL/Perl</span> and
+ <span class="application">PL/PerlU</span> functions.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Perl cannot support multiple interpreters within one process unless
+ it was built with the appropriate flags, namely either
+ <code class="literal">usemultiplicity</code> or <code class="literal">useithreads</code>.
+ (<code class="literal">usemultiplicity</code> is preferred unless you actually need
+ to use threads. For more details, see the
+ <span class="citerefentry"><span class="refentrytitle">perlembed</span></span> man page.)
+ If <span class="application">PL/Perl</span> is used with a copy of Perl that was not built
+ this way, then it is only possible to have one Perl interpreter per
+ session, and so any one session can only execute either
+ <span class="application">PL/PerlU</span> functions, or <span class="application">PL/Perl</span> functions
+ that are all called by the same SQL role.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-global.html" title="45.4. Global Values in PL/Perl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-triggers.html" title="45.6. PL/Perl Triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.4. Global Values in PL/Perl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.6. PL/Perl Triggers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl-under-the-hood.html b/doc/src/sgml/html/plperl-under-the-hood.html
new file mode 100644
index 0000000..627f1ce
--- /dev/null
+++ b/doc/src/sgml/html/plperl-under-the-hood.html
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>45.8. PL/Perl Under the Hood</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-event-triggers.html" title="45.7. PL/Perl Event Triggers" /><link rel="next" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">45.8. PL/Perl Under the Hood</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-event-triggers.html" title="45.7. PL/Perl Event Triggers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPERL-UNDER-THE-HOOD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">45.8. PL/Perl Under the Hood</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plperl-under-the-hood.html#PLPERL-CONFIG">45.8.1. Configuration</a></span></dt><dt><span class="sect2"><a href="plperl-under-the-hood.html#PLPERL-MISSING">45.8.2. Limitations and Missing Features</a></span></dt></dl></div><div class="sect2" id="PLPERL-CONFIG"><div class="titlepage"><div><div><h3 class="title">45.8.1. Configuration</h3></div></div></div><p>
+ This section lists configuration parameters that affect <span class="application">PL/Perl</span>.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-PLPERL-ON-INIT"><span class="term">
+ <code class="varname">plperl.on_init</code> (<code class="type">string</code>)
+ <a id="id-1.8.10.16.2.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies Perl code to be executed when a Perl interpreter is first
+ initialized, before it is specialized for use by <code class="literal">plperl</code> or
+ <code class="literal">plperlu</code>.
+ The SPI functions are not available when this code is executed.
+ If the code fails with an error it will abort the initialization of
+ the interpreter and propagate out to the calling query, causing the
+ current transaction or subtransaction to be aborted.
+ </p><p>
+ The Perl code is limited to a single string. Longer code can be placed
+ into a module and loaded by the <code class="literal">on_init</code> string.
+ Examples:
+</p><pre class="programlisting">
+plperl.on_init = 'require "plperlinit.pl"'
+plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'
+</pre><p>
+ </p><p>
+ Any modules loaded by <code class="literal">plperl.on_init</code>, either directly or
+ indirectly, will be available for use by <code class="literal">plperl</code>. This may
+ create a security risk. To see what modules have been loaded you can use:
+</p><pre class="programlisting">
+DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
+</pre><p>
+ </p><p>
+ Initialization will happen in the postmaster if the <code class="literal">plperl</code> library is
+ included in <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a>, in which
+ case extra consideration should be given to the risk of destabilizing
+ the postmaster. The principal reason for making use of this feature
+ is that Perl modules loaded by <code class="literal">plperl.on_init</code> need be
+ loaded only at postmaster start, and will be instantly available
+ without loading overhead in individual database sessions. However,
+ keep in mind that the overhead is avoided only for the first Perl
+ interpreter used by a database session — either PL/PerlU, or
+ PL/Perl for the first SQL role that calls a PL/Perl function. Any
+ additional Perl interpreters created in a database session will have
+ to execute <code class="literal">plperl.on_init</code> afresh. Also, on Windows there
+ will be no savings whatsoever from preloading, since the Perl
+ interpreter created in the postmaster process does not propagate to
+ child processes.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-PLPERL-ON-PLPERL-INIT"><span class="term">
+ <code class="varname">plperl.on_plperl_init</code> (<code class="type">string</code>)
+ <a id="id-1.8.10.16.2.3.2.1.3" class="indexterm"></a>
+ <br /></span><span class="term">
+ <code class="varname">plperl.on_plperlu_init</code> (<code class="type">string</code>)
+ <a id="id-1.8.10.16.2.3.2.2.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ These parameters specify Perl code to be executed when a Perl
+ interpreter is specialized for <code class="literal">plperl</code> or
+ <code class="literal">plperlu</code> respectively. This will happen when a PL/Perl or
+ PL/PerlU function is first executed in a database session, or when
+ an additional interpreter has to be created because the other language
+ is called or a PL/Perl function is called by a new SQL role. This
+ follows any initialization done by <code class="literal">plperl.on_init</code>.
+ The SPI functions are not available when this code is executed.
+ The Perl code in <code class="literal">plperl.on_plperl_init</code> is executed after
+ <span class="quote">“<span class="quote">locking down</span>”</span> the interpreter, and thus it can only perform
+ trusted operations.
+ </p><p>
+ If the code fails with an error it will abort the initialization and
+ propagate out to the calling query, causing the current transaction or
+ subtransaction to be aborted. Any actions already done within Perl
+ won't be undone; however, that interpreter won't be used again.
+ If the language is used again the initialization will be attempted
+ again within a fresh Perl interpreter.
+ </p><p>
+ Only superusers can change these settings. Although these settings
+ can be changed within a session, such changes will not affect Perl
+ interpreters that have already been used to execute functions.
+ </p></dd><dt id="GUC-PLPERL-USE-STRICT"><span class="term">
+ <code class="varname">plperl.use_strict</code> (<code class="type">boolean</code>)
+ <a id="id-1.8.10.16.2.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set true subsequent compilations of PL/Perl functions will have
+ the <code class="literal">strict</code> pragma enabled. This parameter does not affect
+ functions already compiled in the current session.
+ </p></dd></dl></div></div><div class="sect2" id="PLPERL-MISSING"><div class="titlepage"><div><div><h3 class="title">45.8.2. Limitations and Missing Features</h3></div></div></div><p>
+ The following features are currently missing from PL/Perl, but they
+ would make welcome contributions.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ PL/Perl functions cannot call each other directly.
+ </p></li><li class="listitem"><p>
+ SPI is not yet fully implemented.
+ </p></li><li class="listitem"><p>
+ If you are fetching very large data sets using
+ <code class="literal">spi_exec_query</code>, you should be aware that
+ these will all go into memory. You can avoid this by using
+ <code class="literal">spi_query</code>/<code class="literal">spi_fetchrow</code> as
+ illustrated earlier.
+ </p><p>
+ A similar problem occurs if a set-returning function passes a
+ large set of rows back to PostgreSQL via <code class="literal">return</code>. You
+ can avoid this problem too by instead using
+ <code class="literal">return_next</code> for each row returned, as shown
+ previously.
+ </p></li><li class="listitem"><p>
+ When a session ends normally, not due to a fatal error, any
+ <code class="literal">END</code> blocks that have been defined are executed.
+ Currently no other actions are performed. Specifically,
+ file handles are not automatically flushed and objects are
+ not automatically destroyed.
+ </p></li></ul></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-event-triggers.html" title="45.7. PL/Perl Event Triggers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.7. PL/Perl Event Triggers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 46. PL/Python — Python Procedural Language</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plperl.html b/doc/src/sgml/html/plperl.html
new file mode 100644
index 0000000..c6d7b4a
--- /dev/null
+++ b/doc/src/sgml/html/plperl.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 45. PL/Perl — Perl Procedural Language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-procnames.html" title="44.12. Tcl Procedure Names" /><link rel="next" href="plperl-funcs.html" title="45.1. PL/Perl Functions and Arguments" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 45. PL/Perl — Perl Procedural Language</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-procnames.html" title="44.12. Tcl Procedure Names">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl-funcs.html" title="45.1. PL/Perl Functions and Arguments">Next</a></td></tr></table><hr /></div><div class="chapter" id="PLPERL"><div class="titlepage"><div><div><h2 class="title">Chapter 45. PL/Perl — Perl Procedural Language</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="plperl-funcs.html">45.1. PL/Perl Functions and Arguments</a></span></dt><dt><span class="sect1"><a href="plperl-data.html">45.2. Data Values in PL/Perl</a></span></dt><dt><span class="sect1"><a href="plperl-builtins.html">45.3. Built-in Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="plperl-builtins.html#PLPERL-DATABASE">45.3.1. Database Access from PL/Perl</a></span></dt><dt><span class="sect2"><a href="plperl-builtins.html#PLPERL-UTILITY-FUNCTIONS">45.3.2. Utility Functions in PL/Perl</a></span></dt></dl></dd><dt><span class="sect1"><a href="plperl-global.html">45.4. Global Values in PL/Perl</a></span></dt><dt><span class="sect1"><a href="plperl-trusted.html">45.5. Trusted and Untrusted PL/Perl</a></span></dt><dt><span class="sect1"><a href="plperl-triggers.html">45.6. PL/Perl Triggers</a></span></dt><dt><span class="sect1"><a href="plperl-event-triggers.html">45.7. PL/Perl Event Triggers</a></span></dt><dt><span class="sect1"><a href="plperl-under-the-hood.html">45.8. PL/Perl Under the Hood</a></span></dt><dd><dl><dt><span class="sect2"><a href="plperl-under-the-hood.html#PLPERL-CONFIG">45.8.1. Configuration</a></span></dt><dt><span class="sect2"><a href="plperl-under-the-hood.html#PLPERL-MISSING">45.8.2. Limitations and Missing Features</a></span></dt></dl></dd></dl></div><a id="id-1.8.10.2" class="indexterm"></a><a id="id-1.8.10.3" class="indexterm"></a><p>
+ PL/Perl is a loadable procedural language that enables you to write
+ <span class="productname">PostgreSQL</span> functions and procedures in the
+ <a class="ulink" href="https://www.perl.org" target="_top">Perl programming language</a>.
+ </p><p>
+ The main advantage to using PL/Perl is that this allows use,
+ within stored functions and procedures, of the manyfold <span class="quote">“<span class="quote">string
+ munging</span>”</span> operators and functions available for Perl. Parsing
+ complex strings might be easier using Perl than it is with the
+ string functions and control structures provided in PL/pgSQL.
+ </p><p>
+ To install PL/Perl in a particular database, use
+ <code class="literal">CREATE EXTENSION plperl</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If a language is installed into <code class="literal">template1</code>, all subsequently
+ created databases will have the language installed automatically.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Users of source packages must specially enable the build of
+ PL/Perl during the installation process. (Refer to <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a> for more information.) Users of
+ binary packages might find PL/Perl in a separate subpackage.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-procnames.html" title="44.12. Tcl Procedure Names">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl-funcs.html" title="45.1. PL/Perl Functions and Arguments">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.12. Tcl Procedure Names </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 45.1. PL/Perl Functions and Arguments</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-control-structures.html b/doc/src/sgml/html/plpgsql-control-structures.html
new file mode 100644
index 0000000..e1133b7
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-control-structures.html
@@ -0,0 +1,943 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.6. Control Structures</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-statements.html" title="43.5. Basic Statements" /><link rel="next" href="plpgsql-cursors.html" title="43.7. Cursors" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.6. Control Structures</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-statements.html" title="43.5. Basic Statements">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-cursors.html" title="43.7. Cursors">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-CONTROL-STRUCTURES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.6. Control Structures</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING">43.6.1. Returning from a Function</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING-PROCEDURE">43.6.2. Returning from a Procedure</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-CALLING-PROCEDURE">43.6.3. Calling a Procedure</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-CONDITIONALS">43.6.4. Conditionals</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-CONTROL-STRUCTURES-LOOPS">43.6.5. Simple Loops</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING">43.6.6. Looping through Query Results</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-FOREACH-ARRAY">43.6.7. Looping through Arrays</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING">43.6.8. Trapping Errors</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-CALL-STACK">43.6.9. Obtaining Execution Location Information</a></span></dt></dl></div><p>
+ Control structures are probably the most useful (and
+ important) part of <span class="application">PL/pgSQL</span>. With
+ <span class="application">PL/pgSQL</span>'s control structures,
+ you can manipulate <span class="productname">PostgreSQL</span> data in a very
+ flexible and powerful way.
+ </p><div class="sect2" id="PLPGSQL-STATEMENTS-RETURNING"><div class="titlepage"><div><div><h3 class="title">43.6.1. Returning from a Function</h3></div></div></div><p>
+ There are two commands available that allow you to return data
+ from a function: <code class="command">RETURN</code> and <code class="command">RETURN
+ NEXT</code>.
+ </p><div class="sect3" id="id-1.8.8.8.3.3"><div class="titlepage"><div><div><h4 class="title">43.6.1.1. <code class="command">RETURN</code></h4></div></div></div><pre class="synopsis">
+RETURN <em class="replaceable"><code>expression</code></em>;
+</pre><p>
+ <code class="command">RETURN</code> with an expression terminates the
+ function and returns the value of
+ <em class="replaceable"><code>expression</code></em> to the caller. This form
+ is used for <span class="application">PL/pgSQL</span> functions that do
+ not return a set.
+ </p><p>
+ In a function that returns a scalar type, the expression's result will
+ automatically be cast into the function's return type as described for
+ assignments. But to return a composite (row) value, you must write an
+ expression delivering exactly the requested column set. This may
+ require use of explicit casting.
+ </p><p>
+ If you declared the function with output parameters, write just
+ <code class="command">RETURN</code> with no expression. The current values
+ of the output parameter variables will be returned.
+ </p><p>
+ If you declared the function to return <code class="type">void</code>, a
+ <code class="command">RETURN</code> statement can be used to exit the function
+ early; but do not write an expression following
+ <code class="command">RETURN</code>.
+ </p><p>
+ The return value of a function cannot be left undefined. If
+ control reaches the end of the top-level block of the function
+ without hitting a <code class="command">RETURN</code> statement, a run-time
+ error will occur. This restriction does not apply to functions
+ with output parameters and functions returning <code class="type">void</code>,
+ however. In those cases a <code class="command">RETURN</code> statement is
+ automatically executed if the top-level block finishes.
+ </p><p>
+ Some examples:
+
+</p><pre class="programlisting">
+-- functions returning a scalar type
+RETURN 1 + 2;
+RETURN scalar_var;
+
+-- functions returning a composite type
+RETURN composite_type_var;
+RETURN (1, 2, 'three'::text); -- must cast columns to correct types
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.8.3.4"><div class="titlepage"><div><div><h4 class="title">43.6.1.2. <code class="command">RETURN NEXT</code> and <code class="command">RETURN QUERY</code></h4></div></div></div><a id="id-1.8.8.8.3.4.2" class="indexterm"></a><a id="id-1.8.8.8.3.4.3" class="indexterm"></a><pre class="synopsis">
+RETURN NEXT <em class="replaceable"><code>expression</code></em>;
+RETURN QUERY <em class="replaceable"><code>query</code></em>;
+RETURN QUERY EXECUTE <em class="replaceable"><code>command-string</code></em> [<span class="optional"> USING <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>];
+</pre><p>
+ When a <span class="application">PL/pgSQL</span> function is declared to return
+ <code class="literal">SETOF <em class="replaceable"><code>sometype</code></em></code>, the procedure
+ to follow is slightly different. In that case, the individual
+ items to return are specified by a sequence of <code class="command">RETURN
+ NEXT</code> or <code class="command">RETURN QUERY</code> commands, and
+ then a final <code class="command">RETURN</code> command with no argument
+ is used to indicate that the function has finished executing.
+ <code class="command">RETURN NEXT</code> can be used with both scalar and
+ composite data types; with a composite result type, an entire
+ <span class="quote">“<span class="quote">table</span>”</span> of results will be returned.
+ <code class="command">RETURN QUERY</code> appends the results of executing
+ a query to the function's result set. <code class="command">RETURN
+ NEXT</code> and <code class="command">RETURN QUERY</code> can be freely
+ intermixed in a single set-returning function, in which case
+ their results will be concatenated.
+ </p><p>
+ <code class="command">RETURN NEXT</code> and <code class="command">RETURN
+ QUERY</code> do not actually return from the function —
+ they simply append zero or more rows to the function's result
+ set. Execution then continues with the next statement in the
+ <span class="application">PL/pgSQL</span> function. As successive
+ <code class="command">RETURN NEXT</code> or <code class="command">RETURN
+ QUERY</code> commands are executed, the result set is built
+ up. A final <code class="command">RETURN</code>, which should have no
+ argument, causes control to exit the function (or you can just
+ let control reach the end of the function).
+ </p><p>
+ <code class="command">RETURN QUERY</code> has a variant
+ <code class="command">RETURN QUERY EXECUTE</code>, which specifies the
+ query to be executed dynamically. Parameter expressions can
+ be inserted into the computed query string via <code class="literal">USING</code>,
+ in just the same way as in the <code class="command">EXECUTE</code> command.
+ </p><p>
+ If you declared the function with output parameters, write just
+ <code class="command">RETURN NEXT</code> with no expression. On each
+ execution, the current values of the output parameter
+ variable(s) will be saved for eventual return as a row of the
+ result. Note that you must declare the function as returning
+ <code class="literal">SETOF record</code> when there are multiple output
+ parameters, or <code class="literal">SETOF <em class="replaceable"><code>sometype</code></em></code>
+ when there is just one output parameter of type
+ <em class="replaceable"><code>sometype</code></em>, in order to create a set-returning
+ function with output parameters.
+ </p><p>
+ Here is an example of a function using <code class="command">RETURN
+ NEXT</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT);
+INSERT INTO foo VALUES (1, 2, 'three');
+INSERT INTO foo VALUES (4, 5, 'six');
+
+CREATE OR REPLACE FUNCTION get_all_foo() RETURNS SETOF foo AS
+$BODY$
+DECLARE
+ r foo%rowtype;
+BEGIN
+ FOR r IN
+ SELECT * FROM foo WHERE fooid &gt; 0
+ LOOP
+ -- can do some processing here
+ RETURN NEXT r; -- return current row of SELECT
+ END LOOP;
+ RETURN;
+END;
+$BODY$
+LANGUAGE plpgsql;
+
+SELECT * FROM get_all_foo();
+</pre><p>
+ </p><p>
+ Here is an example of a function using <code class="command">RETURN
+ QUERY</code>:
+
+</p><pre class="programlisting">
+CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS
+$BODY$
+BEGIN
+ RETURN QUERY SELECT flightid
+ FROM flight
+ WHERE flightdate &gt;= $1
+ AND flightdate &lt; ($1 + 1);
+
+ -- Since execution is not finished, we can check whether rows were returned
+ -- and raise exception if not.
+ IF NOT FOUND THEN
+ RAISE EXCEPTION 'No flight at %.', $1;
+ END IF;
+
+ RETURN;
+ END;
+$BODY$
+LANGUAGE plpgsql;
+
+-- Returns available flights or raises exception if there are no
+-- available flights.
+SELECT * FROM get_available_flightid(CURRENT_DATE);
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The current implementation of <code class="command">RETURN NEXT</code>
+ and <code class="command">RETURN QUERY</code> stores the entire result set
+ before returning from the function, as discussed above. That
+ means that if a <span class="application">PL/pgSQL</span> function produces a
+ very large result set, performance might be poor: data will be
+ written to disk to avoid memory exhaustion, but the function
+ itself will not return until the entire result set has been
+ generated. A future version of <span class="application">PL/pgSQL</span> might
+ allow users to define set-returning functions
+ that do not have this limitation. Currently, the point at
+ which data begins being written to disk is controlled by the
+ <a class="xref" href="runtime-config-resource.html#GUC-WORK-MEM">work_mem</a>
+ configuration variable. Administrators who have sufficient
+ memory to store larger result sets in memory should consider
+ increasing this parameter.
+ </p></div></div></div><div class="sect2" id="PLPGSQL-STATEMENTS-RETURNING-PROCEDURE"><div class="titlepage"><div><div><h3 class="title">43.6.2. Returning from a Procedure</h3></div></div></div><p>
+ A procedure does not have a return value. A procedure can therefore end
+ without a <code class="command">RETURN</code> statement. If you wish to use
+ a <code class="command">RETURN</code> statement to exit the code early, write
+ just <code class="command">RETURN</code> with no expression.
+ </p><p>
+ If the procedure has output parameters, the final values of the output
+ parameter variables will be returned to the caller.
+ </p></div><div class="sect2" id="PLPGSQL-STATEMENTS-CALLING-PROCEDURE"><div class="titlepage"><div><div><h3 class="title">43.6.3. Calling a Procedure</h3></div></div></div><p>
+ A <span class="application">PL/pgSQL</span> function, procedure,
+ or <code class="command">DO</code> block can call a procedure
+ using <code class="command">CALL</code>. Output parameters are handled
+ differently from the way that <code class="command">CALL</code> works in plain
+ SQL. Each <code class="literal">OUT</code> or <code class="literal">INOUT</code>
+ parameter of the procedure must
+ correspond to a variable in the <code class="command">CALL</code> statement, and
+ whatever the procedure returns is assigned back to that variable after
+ it returns. For example:
+</p><pre class="programlisting">
+CREATE PROCEDURE triple(INOUT x int)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ x := x * 3;
+END;
+$$;
+
+DO $$
+DECLARE myvar int := 5;
+BEGIN
+ CALL triple(myvar);
+ RAISE NOTICE 'myvar = %', myvar; -- prints 15
+END;
+$$;
+</pre><p>
+ The variable corresponding to an output parameter can be a simple
+ variable or a field of a composite-type variable. Currently,
+ it cannot be an element of an array.
+ </p></div><div class="sect2" id="PLPGSQL-CONDITIONALS"><div class="titlepage"><div><div><h3 class="title">43.6.4. Conditionals</h3></div></div></div><p>
+ <code class="command">IF</code> and <code class="command">CASE</code> statements let you execute
+ alternative commands based on certain conditions.
+ <span class="application">PL/pgSQL</span> has three forms of <code class="command">IF</code>:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">IF ... THEN ... END IF</code></p></li><li class="listitem"><p><code class="literal">IF ... THEN ... ELSE ... END IF</code></p></li><li class="listitem"><p><code class="literal">IF ... THEN ... ELSIF ... THEN ... ELSE ... END IF</code></p></li></ul></div><p>
+
+ and two forms of <code class="command">CASE</code>:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">CASE ... WHEN ... THEN ... ELSE ... END CASE</code></p></li><li class="listitem"><p><code class="literal">CASE WHEN ... THEN ... ELSE ... END CASE</code></p></li></ul></div><p>
+ </p><div class="sect3" id="id-1.8.8.8.6.3"><div class="titlepage"><div><div><h4 class="title">43.6.4.1. <code class="literal">IF-THEN</code></h4></div></div></div><pre class="synopsis">
+IF <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+END IF;
+</pre><p>
+ <code class="literal">IF-THEN</code> statements are the simplest form of
+ <code class="literal">IF</code>. The statements between
+ <code class="literal">THEN</code> and <code class="literal">END IF</code> will be
+ executed if the condition is true. Otherwise, they are
+ skipped.
+ </p><p>
+ Example:
+</p><pre class="programlisting">
+IF v_user_id &lt;&gt; 0 THEN
+ UPDATE users SET email = v_email WHERE user_id = v_user_id;
+END IF;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.8.6.4"><div class="titlepage"><div><div><h4 class="title">43.6.4.2. <code class="literal">IF-THEN-ELSE</code></h4></div></div></div><pre class="synopsis">
+IF <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+ELSE
+ <em class="replaceable"><code>statements</code></em>
+END IF;
+</pre><p>
+ <code class="literal">IF-THEN-ELSE</code> statements add to
+ <code class="literal">IF-THEN</code> by letting you specify an
+ alternative set of statements that should be executed if the
+ condition is not true. (Note this includes the case where the
+ condition evaluates to NULL.)
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+IF parentid IS NULL OR parentid = ''
+THEN
+ RETURN fullname;
+ELSE
+ RETURN hp_true_filename(parentid) || '/' || fullname;
+END IF;
+</pre><p>
+
+</p><pre class="programlisting">
+IF v_count &gt; 0 THEN
+ INSERT INTO users_count (count) VALUES (v_count);
+ RETURN 't';
+ELSE
+ RETURN 'f';
+END IF;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.8.6.5"><div class="titlepage"><div><div><h4 class="title">43.6.4.3. <code class="literal">IF-THEN-ELSIF</code></h4></div></div></div><pre class="synopsis">
+IF <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+[<span class="optional"> ELSIF <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+[<span class="optional"> ELSIF <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+ ...
+</span>]
+</span>]
+[<span class="optional"> ELSE
+ <em class="replaceable"><code>statements</code></em> </span>]
+END IF;
+</pre><p>
+ Sometimes there are more than just two alternatives.
+ <code class="literal">IF-THEN-ELSIF</code> provides a convenient
+ method of checking several alternatives in turn.
+ The <code class="literal">IF</code> conditions are tested successively
+ until the first one that is true is found. Then the
+ associated statement(s) are executed, after which control
+ passes to the next statement after <code class="literal">END IF</code>.
+ (Any subsequent <code class="literal">IF</code> conditions are <span class="emphasis"><em>not</em></span>
+ tested.) If none of the <code class="literal">IF</code> conditions is true,
+ then the <code class="literal">ELSE</code> block (if any) is executed.
+ </p><p>
+ Here is an example:
+
+</p><pre class="programlisting">
+IF number = 0 THEN
+ result := 'zero';
+ELSIF number &gt; 0 THEN
+ result := 'positive';
+ELSIF number &lt; 0 THEN
+ result := 'negative';
+ELSE
+ -- hmm, the only other possibility is that number is null
+ result := 'NULL';
+END IF;
+</pre><p>
+ </p><p>
+ The key word <code class="literal">ELSIF</code> can also be spelled
+ <code class="literal">ELSEIF</code>.
+ </p><p>
+ An alternative way of accomplishing the same task is to nest
+ <code class="literal">IF-THEN-ELSE</code> statements, as in the
+ following example:
+
+</p><pre class="programlisting">
+IF demo_row.sex = 'm' THEN
+ pretty_sex := 'man';
+ELSE
+ IF demo_row.sex = 'f' THEN
+ pretty_sex := 'woman';
+ END IF;
+END IF;
+</pre><p>
+ </p><p>
+ However, this method requires writing a matching <code class="literal">END IF</code>
+ for each <code class="literal">IF</code>, so it is much more cumbersome than
+ using <code class="literal">ELSIF</code> when there are many alternatives.
+ </p></div><div class="sect3" id="id-1.8.8.8.6.6"><div class="titlepage"><div><div><h4 class="title">43.6.4.4. Simple <code class="literal">CASE</code></h4></div></div></div><pre class="synopsis">
+CASE <em class="replaceable"><code>search-expression</code></em>
+ WHEN <em class="replaceable"><code>expression</code></em> [<span class="optional">, <em class="replaceable"><code>expression</code></em> [<span class="optional"> ... </span>]</span>] THEN
+ <em class="replaceable"><code>statements</code></em>
+ [<span class="optional"> WHEN <em class="replaceable"><code>expression</code></em> [<span class="optional">, <em class="replaceable"><code>expression</code></em> [<span class="optional"> ... </span>]</span>] THEN
+ <em class="replaceable"><code>statements</code></em>
+ ... </span>]
+ [<span class="optional"> ELSE
+ <em class="replaceable"><code>statements</code></em> </span>]
+END CASE;
+</pre><p>
+ The simple form of <code class="command">CASE</code> provides conditional execution
+ based on equality of operands. The <em class="replaceable"><code>search-expression</code></em>
+ is evaluated (once) and successively compared to each
+ <em class="replaceable"><code>expression</code></em> in the <code class="literal">WHEN</code> clauses.
+ If a match is found, then the corresponding
+ <em class="replaceable"><code>statements</code></em> are executed, and then control
+ passes to the next statement after <code class="literal">END CASE</code>. (Subsequent
+ <code class="literal">WHEN</code> expressions are not evaluated.) If no match is
+ found, the <code class="literal">ELSE</code> <em class="replaceable"><code>statements</code></em> are
+ executed; but if <code class="literal">ELSE</code> is not present, then a
+ <code class="literal">CASE_NOT_FOUND</code> exception is raised.
+ </p><p>
+ Here is a simple example:
+
+</p><pre class="programlisting">
+CASE x
+ WHEN 1, 2 THEN
+ msg := 'one or two';
+ ELSE
+ msg := 'other value than one or two';
+END CASE;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.8.6.7"><div class="titlepage"><div><div><h4 class="title">43.6.4.5. Searched <code class="literal">CASE</code></h4></div></div></div><pre class="synopsis">
+CASE
+ WHEN <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+ [<span class="optional"> WHEN <em class="replaceable"><code>boolean-expression</code></em> THEN
+ <em class="replaceable"><code>statements</code></em>
+ ... </span>]
+ [<span class="optional"> ELSE
+ <em class="replaceable"><code>statements</code></em> </span>]
+END CASE;
+</pre><p>
+ The searched form of <code class="command">CASE</code> provides conditional execution
+ based on truth of Boolean expressions. Each <code class="literal">WHEN</code> clause's
+ <em class="replaceable"><code>boolean-expression</code></em> is evaluated in turn,
+ until one is found that yields <code class="literal">true</code>. Then the
+ corresponding <em class="replaceable"><code>statements</code></em> are executed, and
+ then control passes to the next statement after <code class="literal">END CASE</code>.
+ (Subsequent <code class="literal">WHEN</code> expressions are not evaluated.)
+ If no true result is found, the <code class="literal">ELSE</code>
+ <em class="replaceable"><code>statements</code></em> are executed;
+ but if <code class="literal">ELSE</code> is not present, then a
+ <code class="literal">CASE_NOT_FOUND</code> exception is raised.
+ </p><p>
+ Here is an example:
+
+</p><pre class="programlisting">
+CASE
+ WHEN x BETWEEN 0 AND 10 THEN
+ msg := 'value is between zero and ten';
+ WHEN x BETWEEN 11 AND 20 THEN
+ msg := 'value is between eleven and twenty';
+END CASE;
+</pre><p>
+ </p><p>
+ This form of <code class="command">CASE</code> is entirely equivalent to
+ <code class="literal">IF-THEN-ELSIF</code>, except for the rule that reaching
+ an omitted <code class="literal">ELSE</code> clause results in an error rather
+ than doing nothing.
+ </p></div></div><div class="sect2" id="PLPGSQL-CONTROL-STRUCTURES-LOOPS"><div class="titlepage"><div><div><h3 class="title">43.6.5. Simple Loops</h3></div></div></div><a id="id-1.8.8.8.7.2" class="indexterm"></a><p>
+ With the <code class="literal">LOOP</code>, <code class="literal">EXIT</code>,
+ <code class="literal">CONTINUE</code>, <code class="literal">WHILE</code>, <code class="literal">FOR</code>,
+ and <code class="literal">FOREACH</code> statements, you can arrange for your
+ <span class="application">PL/pgSQL</span> function to repeat a series of commands.
+ </p><div class="sect3" id="id-1.8.8.8.7.4"><div class="titlepage"><div><div><h4 class="title">43.6.5.1. <code class="literal">LOOP</code></h4></div></div></div><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ <code class="literal">LOOP</code> defines an unconditional loop that is repeated
+ indefinitely until terminated by an <code class="literal">EXIT</code> or
+ <code class="command">RETURN</code> statement. The optional
+ <em class="replaceable"><code>label</code></em> can be used by <code class="literal">EXIT</code>
+ and <code class="literal">CONTINUE</code> statements within nested loops to
+ specify which loop those statements refer to.
+ </p></div><div class="sect3" id="id-1.8.8.8.7.5"><div class="titlepage"><div><div><h4 class="title">43.6.5.2. <code class="literal">EXIT</code></h4></div></div></div><a id="id-1.8.8.8.7.5.2" class="indexterm"></a><pre class="synopsis">
+EXIT [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>] [<span class="optional"> WHEN <em class="replaceable"><code>boolean-expression</code></em> </span>];
+</pre><p>
+ If no <em class="replaceable"><code>label</code></em> is given, the innermost
+ loop is terminated and the statement following <code class="literal">END
+ LOOP</code> is executed next. If <em class="replaceable"><code>label</code></em>
+ is given, it must be the label of the current or some outer
+ level of nested loop or block. Then the named loop or block is
+ terminated and control continues with the statement after the
+ loop's/block's corresponding <code class="literal">END</code>.
+ </p><p>
+ If <code class="literal">WHEN</code> is specified, the loop exit occurs only if
+ <em class="replaceable"><code>boolean-expression</code></em> is true. Otherwise, control passes
+ to the statement after <code class="literal">EXIT</code>.
+ </p><p>
+ <code class="literal">EXIT</code> can be used with all types of loops; it is
+ not limited to use with unconditional loops.
+ </p><p>
+ When used with a
+ <code class="literal">BEGIN</code> block, <code class="literal">EXIT</code> passes
+ control to the next statement after the end of the block.
+ Note that a label must be used for this purpose; an unlabeled
+ <code class="literal">EXIT</code> is never considered to match a
+ <code class="literal">BEGIN</code> block. (This is a change from
+ pre-8.4 releases of <span class="productname">PostgreSQL</span>, which
+ would allow an unlabeled <code class="literal">EXIT</code> to match
+ a <code class="literal">BEGIN</code> block.)
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+LOOP
+ -- some computations
+ IF count &gt; 0 THEN
+ EXIT; -- exit loop
+ END IF;
+END LOOP;
+
+LOOP
+ -- some computations
+ EXIT WHEN count &gt; 0; -- same result as previous example
+END LOOP;
+
+&lt;&lt;ablock&gt;&gt;
+BEGIN
+ -- some computations
+ IF stocks &gt; 100000 THEN
+ EXIT ablock; -- causes exit from the BEGIN block
+ END IF;
+ -- computations here will be skipped when stocks &gt; 100000
+END;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.8.7.6"><div class="titlepage"><div><div><h4 class="title">43.6.5.3. <code class="literal">CONTINUE</code></h4></div></div></div><a id="id-1.8.8.8.7.6.2" class="indexterm"></a><pre class="synopsis">
+CONTINUE [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>] [<span class="optional"> WHEN <em class="replaceable"><code>boolean-expression</code></em> </span>];
+</pre><p>
+ If no <em class="replaceable"><code>label</code></em> is given, the next iteration of
+ the innermost loop is begun. That is, all statements remaining
+ in the loop body are skipped, and control returns
+ to the loop control expression (if any) to determine whether
+ another loop iteration is needed.
+ If <em class="replaceable"><code>label</code></em> is present, it
+ specifies the label of the loop whose execution will be
+ continued.
+ </p><p>
+ If <code class="literal">WHEN</code> is specified, the next iteration of the
+ loop is begun only if <em class="replaceable"><code>boolean-expression</code></em> is
+ true. Otherwise, control passes to the statement after
+ <code class="literal">CONTINUE</code>.
+ </p><p>
+ <code class="literal">CONTINUE</code> can be used with all types of loops; it
+ is not limited to use with unconditional loops.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+LOOP
+ -- some computations
+ EXIT WHEN count &gt; 100;
+ CONTINUE WHEN count &lt; 50;
+ -- some computations for count IN [50 .. 100]
+END LOOP;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.8.7.7"><div class="titlepage"><div><div><h4 class="title">43.6.5.4. <code class="literal">WHILE</code></h4></div></div></div><a id="id-1.8.8.8.7.7.2" class="indexterm"></a><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+WHILE <em class="replaceable"><code>boolean-expression</code></em> LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ The <code class="literal">WHILE</code> statement repeats a
+ sequence of statements so long as the
+ <em class="replaceable"><code>boolean-expression</code></em>
+ evaluates to true. The expression is checked just before
+ each entry to the loop body.
+ </p><p>
+ For example:
+</p><pre class="programlisting">
+WHILE amount_owed &gt; 0 AND gift_certificate_balance &gt; 0 LOOP
+ -- some computations here
+END LOOP;
+
+WHILE NOT done LOOP
+ -- some computations here
+END LOOP;
+</pre><p>
+ </p></div><div class="sect3" id="PLPGSQL-INTEGER-FOR"><div class="titlepage"><div><div><h4 class="title">43.6.5.5. <code class="literal">FOR</code> (Integer Variant)</h4></div></div></div><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+FOR <em class="replaceable"><code>name</code></em> IN [<span class="optional"> REVERSE </span>] <em class="replaceable"><code>expression</code></em> .. <em class="replaceable"><code>expression</code></em> [<span class="optional"> BY <em class="replaceable"><code>expression</code></em> </span>] LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ This form of <code class="literal">FOR</code> creates a loop that iterates over a range
+ of integer values. The variable
+ <em class="replaceable"><code>name</code></em> is automatically defined as type
+ <code class="type">integer</code> and exists only inside the loop (any existing
+ definition of the variable name is ignored within the loop).
+ The two expressions giving
+ the lower and upper bound of the range are evaluated once when entering
+ the loop. If the <code class="literal">BY</code> clause isn't specified the iteration
+ step is 1, otherwise it's the value specified in the <code class="literal">BY</code>
+ clause, which again is evaluated once on loop entry.
+ If <code class="literal">REVERSE</code> is specified then the step value is
+ subtracted, rather than added, after each iteration.
+ </p><p>
+ Some examples of integer <code class="literal">FOR</code> loops:
+</p><pre class="programlisting">
+FOR i IN 1..10 LOOP
+ -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
+END LOOP;
+
+FOR i IN REVERSE 10..1 LOOP
+ -- i will take on the values 10,9,8,7,6,5,4,3,2,1 within the loop
+END LOOP;
+
+FOR i IN REVERSE 10..1 BY 2 LOOP
+ -- i will take on the values 10,8,6,4,2 within the loop
+END LOOP;
+</pre><p>
+ </p><p>
+ If the lower bound is greater than the upper bound (or less than,
+ in the <code class="literal">REVERSE</code> case), the loop body is not
+ executed at all. No error is raised.
+ </p><p>
+ If a <em class="replaceable"><code>label</code></em> is attached to the
+ <code class="literal">FOR</code> loop then the integer loop variable can be
+ referenced with a qualified name, using that
+ <em class="replaceable"><code>label</code></em>.
+ </p></div></div><div class="sect2" id="PLPGSQL-RECORDS-ITERATING"><div class="titlepage"><div><div><h3 class="title">43.6.6. Looping through Query Results</h3></div></div></div><p>
+ Using a different type of <code class="literal">FOR</code> loop, you can iterate through
+ the results of a query and manipulate that data
+ accordingly. The syntax is:
+</p><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+FOR <em class="replaceable"><code>target</code></em> IN <em class="replaceable"><code>query</code></em> LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ The <em class="replaceable"><code>target</code></em> is a record variable, row variable,
+ or comma-separated list of scalar variables.
+ The <em class="replaceable"><code>target</code></em> is successively assigned each row
+ resulting from the <em class="replaceable"><code>query</code></em> and the loop body is
+ executed for each row. Here is an example:
+</p><pre class="programlisting">
+CREATE FUNCTION refresh_mviews() RETURNS integer AS $$
+DECLARE
+ mviews RECORD;
+BEGIN
+ RAISE NOTICE 'Refreshing all materialized views...';
+
+ FOR mviews IN
+ SELECT n.nspname AS mv_schema,
+ c.relname AS mv_name,
+ pg_catalog.pg_get_userbyid(c.relowner) AS owner
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
+ WHERE c.relkind = 'm'
+ ORDER BY 1
+ LOOP
+
+ -- Now "mviews" has one record with information about the materialized view
+
+ RAISE NOTICE 'Refreshing materialized view %.% (owner: %)...',
+ quote_ident(mviews.mv_schema),
+ quote_ident(mviews.mv_name),
+ quote_ident(mviews.owner);
+ EXECUTE format('REFRESH MATERIALIZED VIEW %I.%I', mviews.mv_schema, mviews.mv_name);
+ END LOOP;
+
+ RAISE NOTICE 'Done refreshing materialized views.';
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ If the loop is terminated by an <code class="literal">EXIT</code> statement, the last
+ assigned row value is still accessible after the loop.
+ </p><p>
+ The <em class="replaceable"><code>query</code></em> used in this type of <code class="literal">FOR</code>
+ statement can be any SQL command that returns rows to the caller:
+ <code class="command">SELECT</code> is the most common case,
+ but you can also use <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> with a <code class="literal">RETURNING</code> clause. Some utility
+ commands such as <code class="command">EXPLAIN</code> will work too.
+ </p><p>
+ <span class="application">PL/pgSQL</span> variables are replaced by query parameters,
+ and the query plan is cached for possible re-use, as discussed in
+ detail in <a class="xref" href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST" title="43.11.1. Variable Substitution">Section 43.11.1</a> and
+ <a class="xref" href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING" title="43.11.2. Plan Caching">Section 43.11.2</a>.
+ </p><p>
+ The <code class="literal">FOR-IN-EXECUTE</code> statement is another way to iterate over
+ rows:
+</p><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+FOR <em class="replaceable"><code>target</code></em> IN EXECUTE <em class="replaceable"><code>text_expression</code></em> [<span class="optional"> USING <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>] LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ This is like the previous form, except that the source query
+ is specified as a string expression, which is evaluated and replanned
+ on each entry to the <code class="literal">FOR</code> loop. This allows the programmer to
+ choose the speed of a preplanned query or the flexibility of a dynamic
+ query, just as with a plain <code class="command">EXECUTE</code> statement.
+ As with <code class="command">EXECUTE</code>, parameter values can be inserted
+ into the dynamic command via <code class="literal">USING</code>.
+ </p><p>
+ Another way to specify the query whose results should be iterated
+ through is to declare it as a cursor. This is described in
+ <a class="xref" href="plpgsql-cursors.html#PLPGSQL-CURSOR-FOR-LOOP" title="43.7.4. Looping through a Cursor's Result">Section 43.7.4</a>.
+ </p></div><div class="sect2" id="PLPGSQL-FOREACH-ARRAY"><div class="titlepage"><div><div><h3 class="title">43.6.7. Looping through Arrays</h3></div></div></div><p>
+ The <code class="literal">FOREACH</code> loop is much like a <code class="literal">FOR</code> loop,
+ but instead of iterating through the rows returned by an SQL query,
+ it iterates through the elements of an array value.
+ (In general, <code class="literal">FOREACH</code> is meant for looping through
+ components of a composite-valued expression; variants for looping
+ through composites besides arrays may be added in future.)
+ The <code class="literal">FOREACH</code> statement to loop over an array is:
+
+</p><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+FOREACH <em class="replaceable"><code>target</code></em> [<span class="optional"> SLICE <em class="replaceable"><code>number</code></em> </span>] IN ARRAY <em class="replaceable"><code>expression</code></em> LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ </p><p>
+ Without <code class="literal">SLICE</code>, or if <code class="literal">SLICE 0</code> is specified,
+ the loop iterates through individual elements of the array produced
+ by evaluating the <em class="replaceable"><code>expression</code></em>.
+ The <em class="replaceable"><code>target</code></em> variable is assigned each
+ element value in sequence, and the loop body is executed for each element.
+ Here is an example of looping through the elements of an integer
+ array:
+
+</p><pre class="programlisting">
+CREATE FUNCTION sum(int[]) RETURNS int8 AS $$
+DECLARE
+ s int8 := 0;
+ x int;
+BEGIN
+ FOREACH x IN ARRAY $1
+ LOOP
+ s := s + x;
+ END LOOP;
+ RETURN s;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ The elements are visited in storage order, regardless of the number of
+ array dimensions. Although the <em class="replaceable"><code>target</code></em> is
+ usually just a single variable, it can be a list of variables when
+ looping through an array of composite values (records). In that case,
+ for each array element, the variables are assigned from successive
+ columns of the composite value.
+ </p><p>
+ With a positive <code class="literal">SLICE</code> value, <code class="literal">FOREACH</code>
+ iterates through slices of the array rather than single elements.
+ The <code class="literal">SLICE</code> value must be an integer constant not larger
+ than the number of dimensions of the array. The
+ <em class="replaceable"><code>target</code></em> variable must be an array,
+ and it receives successive slices of the array value, where each slice
+ is of the number of dimensions specified by <code class="literal">SLICE</code>.
+ Here is an example of iterating through one-dimensional slices:
+
+</p><pre class="programlisting">
+CREATE FUNCTION scan_rows(int[]) RETURNS void AS $$
+DECLARE
+ x int[];
+BEGIN
+ FOREACH x SLICE 1 IN ARRAY $1
+ LOOP
+ RAISE NOTICE 'row = %', x;
+ END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT scan_rows(ARRAY[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]);
+
+NOTICE: row = {1,2,3}
+NOTICE: row = {4,5,6}
+NOTICE: row = {7,8,9}
+NOTICE: row = {10,11,12}
+</pre><p>
+ </p></div><div class="sect2" id="PLPGSQL-ERROR-TRAPPING"><div class="titlepage"><div><div><h3 class="title">43.6.8. Trapping Errors</h3></div></div></div><a id="id-1.8.8.8.10.2" class="indexterm"></a><p>
+ By default, any error occurring in a <span class="application">PL/pgSQL</span>
+ function aborts execution of the function and the
+ surrounding transaction. You can trap errors and recover
+ from them by using a <code class="command">BEGIN</code> block with an
+ <code class="literal">EXCEPTION</code> clause. The syntax is an extension of the
+ normal syntax for a <code class="command">BEGIN</code> block:
+
+</p><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+[<span class="optional"> DECLARE
+ <em class="replaceable"><code>declarations</code></em> </span>]
+BEGIN
+ <em class="replaceable"><code>statements</code></em>
+EXCEPTION
+ WHEN <em class="replaceable"><code>condition</code></em> [<span class="optional"> OR <em class="replaceable"><code>condition</code></em> ... </span>] THEN
+ <em class="replaceable"><code>handler_statements</code></em>
+ [<span class="optional"> WHEN <em class="replaceable"><code>condition</code></em> [<span class="optional"> OR <em class="replaceable"><code>condition</code></em> ... </span>] THEN
+ <em class="replaceable"><code>handler_statements</code></em>
+ ... </span>]
+END;
+</pre><p>
+ </p><p>
+ If no error occurs, this form of block simply executes all the
+ <em class="replaceable"><code>statements</code></em>, and then control passes
+ to the next statement after <code class="literal">END</code>. But if an error
+ occurs within the <em class="replaceable"><code>statements</code></em>, further
+ processing of the <em class="replaceable"><code>statements</code></em> is
+ abandoned, and control passes to the <code class="literal">EXCEPTION</code> list.
+ The list is searched for the first <em class="replaceable"><code>condition</code></em>
+ matching the error that occurred. If a match is found, the
+ corresponding <em class="replaceable"><code>handler_statements</code></em> are
+ executed, and then control passes to the next statement after
+ <code class="literal">END</code>. If no match is found, the error propagates out
+ as though the <code class="literal">EXCEPTION</code> clause were not there at all:
+ the error can be caught by an enclosing block with
+ <code class="literal">EXCEPTION</code>, or if there is none it aborts processing
+ of the function.
+ </p><p>
+ The <em class="replaceable"><code>condition</code></em> names can be any of
+ those shown in <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>. A category
+ name matches any error within its category. The special
+ condition name <code class="literal">OTHERS</code> matches every error type except
+ <code class="literal">QUERY_CANCELED</code> and <code class="literal">ASSERT_FAILURE</code>.
+ (It is possible, but often unwise, to trap those two error types
+ by name.) Condition names are
+ not case-sensitive. Also, an error condition can be specified
+ by <code class="literal">SQLSTATE</code> code; for example these are equivalent:
+</p><pre class="programlisting">
+WHEN division_by_zero THEN ...
+WHEN SQLSTATE '22012' THEN ...
+</pre><p>
+ </p><p>
+ If a new error occurs within the selected
+ <em class="replaceable"><code>handler_statements</code></em>, it cannot be caught
+ by this <code class="literal">EXCEPTION</code> clause, but is propagated out.
+ A surrounding <code class="literal">EXCEPTION</code> clause could catch it.
+ </p><p>
+ When an error is caught by an <code class="literal">EXCEPTION</code> clause,
+ the local variables of the <span class="application">PL/pgSQL</span> function
+ remain as they were when the error occurred, but all changes
+ to persistent database state within the block are rolled back.
+ As an example, consider this fragment:
+
+</p><pre class="programlisting">
+INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
+BEGIN
+ UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
+ x := x + 1;
+ y := x / 0;
+EXCEPTION
+ WHEN division_by_zero THEN
+ RAISE NOTICE 'caught division_by_zero';
+ RETURN x;
+END;
+</pre><p>
+
+ When control reaches the assignment to <code class="literal">y</code>, it will
+ fail with a <code class="literal">division_by_zero</code> error. This will be caught by
+ the <code class="literal">EXCEPTION</code> clause. The value returned in the
+ <code class="command">RETURN</code> statement will be the incremented value of
+ <code class="literal">x</code>, but the effects of the <code class="command">UPDATE</code> command will
+ have been rolled back. The <code class="command">INSERT</code> command preceding the
+ block is not rolled back, however, so the end result is that the database
+ contains <code class="literal">Tom Jones</code> not <code class="literal">Joe Jones</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ A block containing an <code class="literal">EXCEPTION</code> clause is significantly
+ more expensive to enter and exit than a block without one. Therefore,
+ don't use <code class="literal">EXCEPTION</code> without need.
+ </p></div><div class="example" id="PLPGSQL-UPSERT-EXAMPLE"><p class="title"><strong>Example 43.2. Exceptions with <code class="command">UPDATE</code>/<code class="command">INSERT</code></strong></p><div class="example-contents"><p>
+
+ This example uses exception handling to perform either
+ <code class="command">UPDATE</code> or <code class="command">INSERT</code>, as appropriate. It is
+ recommended that applications use <code class="command">INSERT</code> with
+ <code class="literal">ON CONFLICT DO UPDATE</code> rather than actually using
+ this pattern. This example serves primarily to illustrate use of
+ <span class="application">PL/pgSQL</span> control flow structures:
+
+</p><pre class="programlisting">
+CREATE TABLE db (a INT PRIMARY KEY, b TEXT);
+
+CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
+$$
+BEGIN
+ LOOP
+ -- first try to update the key
+ UPDATE db SET b = data WHERE a = key;
+ IF found THEN
+ RETURN;
+ END IF;
+ -- not there, so try to insert the key
+ -- if someone else inserts the same key concurrently,
+ -- we could get a unique-key failure
+ BEGIN
+ INSERT INTO db(a,b) VALUES (key, data);
+ RETURN;
+ EXCEPTION WHEN unique_violation THEN
+ -- Do nothing, and loop to try the UPDATE again.
+ END;
+ END LOOP;
+END;
+$$
+LANGUAGE plpgsql;
+
+SELECT merge_db(1, 'david');
+SELECT merge_db(1, 'dennis');
+</pre><p>
+
+ This coding assumes the <code class="literal">unique_violation</code> error is caused by
+ the <code class="command">INSERT</code>, and not by, say, an <code class="command">INSERT</code> in a
+ trigger function on the table. It might also misbehave if there is
+ more than one unique index on the table, since it will retry the
+ operation regardless of which index caused the error.
+ More safety could be had by using the
+ features discussed next to check that the trapped error was the one
+ expected.
+ </p></div></div><br class="example-break" /><div class="sect3" id="PLPGSQL-EXCEPTION-DIAGNOSTICS"><div class="titlepage"><div><div><h4 class="title">43.6.8.1. Obtaining Information about an Error</h4></div></div></div><p>
+ Exception handlers frequently need to identify the specific error that
+ occurred. There are two ways to get information about the current
+ exception in <span class="application">PL/pgSQL</span>: special variables and the
+ <code class="command">GET STACKED DIAGNOSTICS</code> command.
+ </p><p>
+ Within an exception handler, the special variable
+ <code class="varname">SQLSTATE</code> contains the error code that corresponds to
+ the exception that was raised (refer to <a class="xref" href="errcodes-appendix.html#ERRCODES-TABLE" title="Table A.1. PostgreSQL Error Codes">Table A.1</a>
+ for a list of possible error codes). The special variable
+ <code class="varname">SQLERRM</code> contains the error message associated with the
+ exception. These variables are undefined outside exception handlers.
+ </p><p>
+ Within an exception handler, one may also retrieve
+ information about the current exception by using the
+ <code class="command">GET STACKED DIAGNOSTICS</code> command, which has the form:
+
+</p><pre class="synopsis">
+GET STACKED DIAGNOSTICS <em class="replaceable"><code>variable</code></em> { = | := } <em class="replaceable"><code>item</code></em> [<span class="optional"> , ... </span>];
+</pre><p>
+
+ Each <em class="replaceable"><code>item</code></em> is a key word identifying a status
+ value to be assigned to the specified <em class="replaceable"><code>variable</code></em>
+ (which should be of the right data type to receive it). The currently
+ available status items are shown
+ in <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-EXCEPTION-DIAGNOSTICS-VALUES" title="Table 43.2. Error Diagnostics Items">Table 43.2</a>.
+ </p><div class="table" id="PLPGSQL-EXCEPTION-DIAGNOSTICS-VALUES"><p class="title"><strong>Table 43.2. Error Diagnostics Items</strong></p><div class="table-contents"><table class="table" summary="Error Diagnostics Items" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">RETURNED_SQLSTATE</code></td><td><code class="type">text</code></td><td>the SQLSTATE error code of the exception</td></tr><tr><td><code class="literal">COLUMN_NAME</code></td><td><code class="type">text</code></td><td>the name of the column related to exception</td></tr><tr><td><code class="literal">CONSTRAINT_NAME</code></td><td><code class="type">text</code></td><td>the name of the constraint related to exception</td></tr><tr><td><code class="literal">PG_DATATYPE_NAME</code></td><td><code class="type">text</code></td><td>the name of the data type related to exception</td></tr><tr><td><code class="literal">MESSAGE_TEXT</code></td><td><code class="type">text</code></td><td>the text of the exception's primary message</td></tr><tr><td><code class="literal">TABLE_NAME</code></td><td><code class="type">text</code></td><td>the name of the table related to exception</td></tr><tr><td><code class="literal">SCHEMA_NAME</code></td><td><code class="type">text</code></td><td>the name of the schema related to exception</td></tr><tr><td><code class="literal">PG_EXCEPTION_DETAIL</code></td><td><code class="type">text</code></td><td>the text of the exception's detail message, if any</td></tr><tr><td><code class="literal">PG_EXCEPTION_HINT</code></td><td><code class="type">text</code></td><td>the text of the exception's hint message, if any</td></tr><tr><td><code class="literal">PG_EXCEPTION_CONTEXT</code></td><td><code class="type">text</code></td><td>line(s) of text describing the call stack at the time of the
+ exception (see <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-CALL-STACK" title="43.6.9. Obtaining Execution Location Information">Section 43.6.9</a>)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ If the exception did not set a value for an item, an empty string
+ will be returned.
+ </p><p>
+ Here is an example:
+</p><pre class="programlisting">
+DECLARE
+ text_var1 text;
+ text_var2 text;
+ text_var3 text;
+BEGIN
+ -- some processing which might cause an exception
+ ...
+EXCEPTION WHEN OTHERS THEN
+ GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
+ text_var2 = PG_EXCEPTION_DETAIL,
+ text_var3 = PG_EXCEPTION_HINT;
+END;
+</pre><p>
+ </p></div></div><div class="sect2" id="PLPGSQL-CALL-STACK"><div class="titlepage"><div><div><h3 class="title">43.6.9. Obtaining Execution Location Information</h3></div></div></div><p>
+ The <code class="command">GET DIAGNOSTICS</code> command, previously described
+ in <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS" title="43.5.5. Obtaining the Result Status">Section 43.5.5</a>, retrieves information
+ about current execution state (whereas the <code class="command">GET STACKED
+ DIAGNOSTICS</code> command discussed above reports information about
+ the execution state as of a previous error). Its <code class="literal">PG_CONTEXT</code>
+ status item is useful for identifying the current execution
+ location. <code class="literal">PG_CONTEXT</code> returns a text string with line(s)
+ of text describing the call stack. The first line refers to the current
+ function and currently executing <code class="command">GET DIAGNOSTICS</code>
+ command. The second and any subsequent lines refer to calling functions
+ further up the call stack. For example:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$
+BEGIN
+ RETURN inner_func();
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$
+DECLARE
+ stack text;
+BEGIN
+ GET DIAGNOSTICS stack = PG_CONTEXT;
+ RAISE NOTICE E'--- Call Stack ---\n%', stack;
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT outer_func();
+
+NOTICE: --- Call Stack ---
+PL/pgSQL function inner_func() line 5 at GET DIAGNOSTICS
+PL/pgSQL function outer_func() line 3 at RETURN
+CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN
+ outer_func
+ ------------
+ 1
+(1 row)
+</pre><p>
+
+ </p><p>
+ <code class="literal">GET STACKED DIAGNOSTICS ... PG_EXCEPTION_CONTEXT</code>
+ returns the same sort of stack trace, but describing the location
+ at which an error was detected, rather than the current location.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-statements.html" title="43.5. Basic Statements">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-cursors.html" title="43.7. Cursors">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.5. Basic Statements </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.7. Cursors</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-cursors.html b/doc/src/sgml/html/plpgsql-cursors.html
new file mode 100644
index 0000000..6dd67a8
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-cursors.html
@@ -0,0 +1,386 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.7. Cursors</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-control-structures.html" title="43.6. Control Structures" /><link rel="next" href="plpgsql-transactions.html" title="43.8. Transaction Management" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.7. Cursors</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-control-structures.html" title="43.6. Control Structures">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-transactions.html" title="43.8. Transaction Management">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-CURSORS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.7. Cursors</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-DECLARATIONS">43.7.1. Declaring Cursor Variables</a></span></dt><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING">43.7.2. Opening Cursors</a></span></dt><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-USING">43.7.3. Using Cursors</a></span></dt><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-FOR-LOOP">43.7.4. Looping through a Cursor's Result</a></span></dt></dl></div><a id="id-1.8.8.9.2" class="indexterm"></a><p>
+ Rather than executing a whole query at once, it is possible to set
+ up a <em class="firstterm">cursor</em> that encapsulates the query, and then read
+ the query result a few rows at a time. One reason for doing this is
+ to avoid memory overrun when the result contains a large number of
+ rows. (However, <span class="application">PL/pgSQL</span> users do not normally need
+ to worry about that, since <code class="literal">FOR</code> loops automatically use a cursor
+ internally to avoid memory problems.) A more interesting usage is to
+ return a reference to a cursor that a function has created, allowing the
+ caller to read the rows. This provides an efficient way to return
+ large row sets from functions.
+ </p><div class="sect2" id="PLPGSQL-CURSOR-DECLARATIONS"><div class="titlepage"><div><div><h3 class="title">43.7.1. Declaring Cursor Variables</h3></div></div></div><p>
+ All access to cursors in <span class="application">PL/pgSQL</span> goes through
+ cursor variables, which are always of the special data type
+ <code class="type">refcursor</code>. One way to create a cursor variable
+ is just to declare it as a variable of type <code class="type">refcursor</code>.
+ Another way is to use the cursor declaration syntax,
+ which in general is:
+</p><pre class="synopsis">
+<em class="replaceable"><code>name</code></em> [<span class="optional"> [<span class="optional"> NO </span>] SCROLL </span>] CURSOR [<span class="optional"> ( <em class="replaceable"><code>arguments</code></em> ) </span>] FOR <em class="replaceable"><code>query</code></em>;
+</pre><p>
+ (<code class="literal">FOR</code> can be replaced by <code class="literal">IS</code> for
+ <span class="productname">Oracle</span> compatibility.)
+ If <code class="literal">SCROLL</code> is specified, the cursor will be capable of
+ scrolling backward; if <code class="literal">NO SCROLL</code> is specified, backward
+ fetches will be rejected; if neither specification appears, it is
+ query-dependent whether backward fetches will be allowed.
+ <em class="replaceable"><code>arguments</code></em>, if specified, is a
+ comma-separated list of pairs <code class="literal"><em class="replaceable"><code>name</code></em>
+ <em class="replaceable"><code>datatype</code></em></code> that define names to be
+ replaced by parameter values in the given query. The actual
+ values to substitute for these names will be specified later,
+ when the cursor is opened.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+DECLARE
+ curs1 refcursor;
+ curs2 CURSOR FOR SELECT * FROM tenk1;
+ curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;
+</pre><p>
+ All three of these variables have the data type <code class="type">refcursor</code>,
+ but the first can be used with any query, while the second has
+ a fully specified query already <em class="firstterm">bound</em> to it, and the last
+ has a parameterized query bound to it. (<code class="literal">key</code> will be
+ replaced by an integer parameter value when the cursor is opened.)
+ The variable <code class="literal">curs1</code>
+ is said to be <em class="firstterm">unbound</em> since it is not bound to
+ any particular query.
+ </p><p>
+ The <code class="literal">SCROLL</code> option cannot be used when the cursor's
+ query uses <code class="literal">FOR UPDATE/SHARE</code>. Also, it is
+ best to use <code class="literal">NO SCROLL</code> with a query that involves
+ volatile functions. The implementation of <code class="literal">SCROLL</code>
+ assumes that re-reading the query's output will give consistent
+ results, which a volatile function might not do.
+ </p></div><div class="sect2" id="PLPGSQL-CURSOR-OPENING"><div class="titlepage"><div><div><h3 class="title">43.7.2. Opening Cursors</h3></div></div></div><p>
+ Before a cursor can be used to retrieve rows, it must be
+ <em class="firstterm">opened</em>. (This is the equivalent action to the SQL
+ command <code class="command">DECLARE CURSOR</code>.) <span class="application">PL/pgSQL</span> has
+ three forms of the <code class="command">OPEN</code> statement, two of which use unbound
+ cursor variables while the third uses a bound cursor variable.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Bound cursor variables can also be used without explicitly opening the cursor,
+ via the <code class="command">FOR</code> statement described in
+ <a class="xref" href="plpgsql-cursors.html#PLPGSQL-CURSOR-FOR-LOOP" title="43.7.4. Looping through a Cursor's Result">Section 43.7.4</a>.
+ </p></div><div class="sect3" id="id-1.8.8.9.5.4"><div class="titlepage"><div><div><h4 class="title">43.7.2.1. <code class="command">OPEN FOR</code> <em class="replaceable"><code>query</code></em></h4></div></div></div><pre class="synopsis">
+OPEN <em class="replaceable"><code>unbound_cursorvar</code></em> [<span class="optional"> [<span class="optional"> NO </span>] SCROLL </span>] FOR <em class="replaceable"><code>query</code></em>;
+</pre><p>
+ The cursor variable is opened and given the specified query to
+ execute. The cursor cannot be open already, and it must have been
+ declared as an unbound cursor variable (that is, as a simple
+ <code class="type">refcursor</code> variable). The query must be a
+ <code class="command">SELECT</code>, or something else that returns rows
+ (such as <code class="command">EXPLAIN</code>). The query
+ is treated in the same way as other SQL commands in
+ <span class="application">PL/pgSQL</span>: <span class="application">PL/pgSQL</span>
+ variable names are substituted, and the query plan is cached for
+ possible reuse. When a <span class="application">PL/pgSQL</span>
+ variable is substituted into the cursor query, the value that is
+ substituted is the one it has at the time of the <code class="command">OPEN</code>;
+ subsequent changes to the variable will not affect the cursor's
+ behavior.
+ The <code class="literal">SCROLL</code> and <code class="literal">NO SCROLL</code>
+ options have the same meanings as for a bound cursor.
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.9.5.5"><div class="titlepage"><div><div><h4 class="title">43.7.2.2. <code class="command">OPEN FOR EXECUTE</code></h4></div></div></div><pre class="synopsis">
+OPEN <em class="replaceable"><code>unbound_cursorvar</code></em> [<span class="optional"> [<span class="optional"> NO </span>] SCROLL </span>] FOR EXECUTE <em class="replaceable"><code>query_string</code></em>
+ [<span class="optional"> USING <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>];
+</pre><p>
+ The cursor variable is opened and given the specified query to
+ execute. The cursor cannot be open already, and it must have been
+ declared as an unbound cursor variable (that is, as a simple
+ <code class="type">refcursor</code> variable). The query is specified as a string
+ expression, in the same way as in the <code class="command">EXECUTE</code>
+ command. As usual, this gives flexibility so the query plan can vary
+ from one run to the next (see <a class="xref" href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING" title="43.11.2. Plan Caching">Section 43.11.2</a>),
+ and it also means that variable substitution is not done on the
+ command string. As with <code class="command">EXECUTE</code>, parameter values
+ can be inserted into the dynamic command via
+ <code class="literal">format()</code> and <code class="literal">USING</code>.
+ The <code class="literal">SCROLL</code> and
+ <code class="literal">NO SCROLL</code> options have the same meanings as for a bound
+ cursor.
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING keyvalue;
+</pre><p>
+ In this example, the table name is inserted into the query via
+ <code class="function">format()</code>. The comparison value for <code class="literal">col1</code>
+ is inserted via a <code class="literal">USING</code> parameter, so it needs
+ no quoting.
+ </p></div><div class="sect3" id="PLPGSQL-OPEN-BOUND-CURSOR"><div class="titlepage"><div><div><h4 class="title">43.7.2.3. Opening a Bound Cursor</h4></div></div></div><pre class="synopsis">
+OPEN <em class="replaceable"><code>bound_cursorvar</code></em> [<span class="optional"> ( [<span class="optional"> <em class="replaceable"><code>argument_name</code></em> := </span>] <em class="replaceable"><code>argument_value</code></em> [<span class="optional">, ...</span>] ) </span>];
+</pre><p>
+ This form of <code class="command">OPEN</code> is used to open a cursor
+ variable whose query was bound to it when it was declared. The
+ cursor cannot be open already. A list of actual argument value
+ expressions must appear if and only if the cursor was declared to
+ take arguments. These values will be substituted in the query.
+ </p><p>
+ The query plan for a bound cursor is always considered cacheable;
+ there is no equivalent of <code class="command">EXECUTE</code> in this case.
+ Notice that <code class="literal">SCROLL</code> and <code class="literal">NO SCROLL</code> cannot be
+ specified in <code class="command">OPEN</code>, as the cursor's scrolling
+ behavior was already determined.
+ </p><p>
+ Argument values can be passed using either <em class="firstterm">positional</em>
+ or <em class="firstterm">named</em> notation. In positional
+ notation, all arguments are specified in order. In named notation,
+ each argument's name is specified using <code class="literal">:=</code> to
+ separate it from the argument expression. Similar to calling
+ functions, described in <a class="xref" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Section 4.3</a>, it
+ is also allowed to mix positional and named notation.
+ </p><p>
+ Examples (these use the cursor declaration examples above):
+</p><pre class="programlisting">
+OPEN curs2;
+OPEN curs3(42);
+OPEN curs3(key := 42);
+</pre><p>
+ </p><p>
+ Because variable substitution is done on a bound cursor's query,
+ there are really two ways to pass values into the cursor: either
+ with an explicit argument to <code class="command">OPEN</code>, or implicitly by
+ referencing a <span class="application">PL/pgSQL</span> variable in the query.
+ However, only variables declared before the bound cursor was
+ declared will be substituted into it. In either case the value to
+ be passed is determined at the time of the <code class="command">OPEN</code>.
+ For example, another way to get the same effect as the
+ <code class="literal">curs3</code> example above is
+</p><pre class="programlisting">
+DECLARE
+ key integer;
+ curs4 CURSOR FOR SELECT * FROM tenk1 WHERE unique1 = key;
+BEGIN
+ key := 42;
+ OPEN curs4;
+</pre><p>
+ </p></div></div><div class="sect2" id="PLPGSQL-CURSOR-USING"><div class="titlepage"><div><div><h3 class="title">43.7.3. Using Cursors</h3></div></div></div><p>
+ Once a cursor has been opened, it can be manipulated with the
+ statements described here.
+ </p><p>
+ These manipulations need not occur in the same function that
+ opened the cursor to begin with. You can return a <code class="type">refcursor</code>
+ value out of a function and let the caller operate on the cursor.
+ (Internally, a <code class="type">refcursor</code> value is simply the string name
+ of a so-called portal containing the active query for the cursor. This name
+ can be passed around, assigned to other <code class="type">refcursor</code> variables,
+ and so on, without disturbing the portal.)
+ </p><p>
+ All portals are implicitly closed at transaction end. Therefore
+ a <code class="type">refcursor</code> value is usable to reference an open cursor
+ only until the end of the transaction.
+ </p><div class="sect3" id="id-1.8.8.9.6.5"><div class="titlepage"><div><div><h4 class="title">43.7.3.1. <code class="literal">FETCH</code></h4></div></div></div><pre class="synopsis">
+FETCH [<span class="optional"> <em class="replaceable"><code>direction</code></em> { FROM | IN } </span>] <em class="replaceable"><code>cursor</code></em> INTO <em class="replaceable"><code>target</code></em>;
+</pre><p>
+ <code class="command">FETCH</code> retrieves the next row from the
+ cursor into a target, which might be a row variable, a record
+ variable, or a comma-separated list of simple variables, just like
+ <code class="command">SELECT INTO</code>. If there is no next row, the
+ target is set to NULL(s). As with <code class="command">SELECT
+ INTO</code>, the special variable <code class="literal">FOUND</code> can
+ be checked to see whether a row was obtained or not.
+ </p><p>
+ The <em class="replaceable"><code>direction</code></em> clause can be any of the
+ variants allowed in the SQL <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a>
+ command except the ones that can fetch
+ more than one row; namely, it can be
+ <code class="literal">NEXT</code>,
+ <code class="literal">PRIOR</code>,
+ <code class="literal">FIRST</code>,
+ <code class="literal">LAST</code>,
+ <code class="literal">ABSOLUTE</code> <em class="replaceable"><code>count</code></em>,
+ <code class="literal">RELATIVE</code> <em class="replaceable"><code>count</code></em>,
+ <code class="literal">FORWARD</code>, or
+ <code class="literal">BACKWARD</code>.
+ Omitting <em class="replaceable"><code>direction</code></em> is the same
+ as specifying <code class="literal">NEXT</code>.
+ In the forms using a <em class="replaceable"><code>count</code></em>,
+ the <em class="replaceable"><code>count</code></em> can be any integer-valued
+ expression (unlike the SQL <code class="command">FETCH</code> command,
+ which only allows an integer constant).
+ <em class="replaceable"><code>direction</code></em> values that require moving
+ backward are likely to fail unless the cursor was declared or opened
+ with the <code class="literal">SCROLL</code> option.
+ </p><p>
+ <em class="replaceable"><code>cursor</code></em> must be the name of a <code class="type">refcursor</code>
+ variable that references an open cursor portal.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+FETCH curs1 INTO rowvar;
+FETCH curs2 INTO foo, bar, baz;
+FETCH LAST FROM curs3 INTO x, y;
+FETCH RELATIVE -2 FROM curs4 INTO x;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.9.6.6"><div class="titlepage"><div><div><h4 class="title">43.7.3.2. <code class="literal">MOVE</code></h4></div></div></div><pre class="synopsis">
+MOVE [<span class="optional"> <em class="replaceable"><code>direction</code></em> { FROM | IN } </span>] <em class="replaceable"><code>cursor</code></em>;
+</pre><p>
+ <code class="command">MOVE</code> repositions a cursor without retrieving
+ any data. <code class="command">MOVE</code> works exactly like the
+ <code class="command">FETCH</code> command, except it only repositions the
+ cursor and does not return the row moved to. As with <code class="command">SELECT
+ INTO</code>, the special variable <code class="literal">FOUND</code> can
+ be checked to see whether there was a next row to move to.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+MOVE curs1;
+MOVE LAST FROM curs3;
+MOVE RELATIVE -2 FROM curs4;
+MOVE FORWARD 2 FROM curs4;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.9.6.7"><div class="titlepage"><div><div><h4 class="title">43.7.3.3. <code class="literal">UPDATE/DELETE WHERE CURRENT OF</code></h4></div></div></div><pre class="synopsis">
+UPDATE <em class="replaceable"><code>table</code></em> SET ... WHERE CURRENT OF <em class="replaceable"><code>cursor</code></em>;
+DELETE FROM <em class="replaceable"><code>table</code></em> WHERE CURRENT OF <em class="replaceable"><code>cursor</code></em>;
+</pre><p>
+ When a cursor is positioned on a table row, that row can be updated
+ or deleted using the cursor to identify the row. There are
+ restrictions on what the cursor's query can be (in particular,
+ no grouping) and it's best to use <code class="literal">FOR UPDATE</code> in the
+ cursor. For more information see the
+ <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>
+ reference page.
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+UPDATE foo SET dataval = myval WHERE CURRENT OF curs1;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.9.6.8"><div class="titlepage"><div><div><h4 class="title">43.7.3.4. <code class="literal">CLOSE</code></h4></div></div></div><pre class="synopsis">
+CLOSE <em class="replaceable"><code>cursor</code></em>;
+</pre><p>
+ <code class="command">CLOSE</code> closes the portal underlying an open
+ cursor. This can be used to release resources earlier than end of
+ transaction, or to free up the cursor variable to be opened again.
+ </p><p>
+ An example:
+</p><pre class="programlisting">
+CLOSE curs1;
+</pre><p>
+ </p></div><div class="sect3" id="id-1.8.8.9.6.9"><div class="titlepage"><div><div><h4 class="title">43.7.3.5. Returning Cursors</h4></div></div></div><p>
+ <span class="application">PL/pgSQL</span> functions can return cursors to the
+ caller. This is useful to return multiple rows or columns,
+ especially with very large result sets. To do this, the function
+ opens the cursor and returns the cursor name to the caller (or simply
+ opens the cursor using a portal name specified by or otherwise known
+ to the caller). The caller can then fetch rows from the cursor. The
+ cursor can be closed by the caller, or it will be closed automatically
+ when the transaction closes.
+ </p><p>
+ The portal name used for a cursor can be specified by the
+ programmer or automatically generated. To specify a portal name,
+ simply assign a string to the <code class="type">refcursor</code> variable before
+ opening it. The string value of the <code class="type">refcursor</code> variable
+ will be used by <code class="command">OPEN</code> as the name of the underlying portal.
+ However, if the <code class="type">refcursor</code> variable is null,
+ <code class="command">OPEN</code> automatically generates a name that does not
+ conflict with any existing portal, and assigns it to the
+ <code class="type">refcursor</code> variable.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ A bound cursor variable is initialized to the string value
+ representing its name, so that the portal name is the same as
+ the cursor variable name, unless the programmer overrides it
+ by assignment before opening the cursor. But an unbound cursor
+ variable defaults to the null value initially, so it will receive
+ an automatically-generated unique name, unless overridden.
+ </p></div><p>
+ The following example shows one way a cursor name can be supplied by
+ the caller:
+
+</p><pre class="programlisting">
+CREATE TABLE test (col text);
+INSERT INTO test VALUES ('123');
+
+CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
+BEGIN
+ OPEN $1 FOR SELECT col FROM test;
+ RETURN $1;
+END;
+' LANGUAGE plpgsql;
+
+BEGIN;
+SELECT reffunc('funccursor');
+FETCH ALL IN funccursor;
+COMMIT;
+</pre><p>
+ </p><p>
+ The following example uses automatic cursor name generation:
+
+</p><pre class="programlisting">
+CREATE FUNCTION reffunc2() RETURNS refcursor AS '
+DECLARE
+ ref refcursor;
+BEGIN
+ OPEN ref FOR SELECT col FROM test;
+ RETURN ref;
+END;
+' LANGUAGE plpgsql;
+
+-- need to be in a transaction to use cursors.
+BEGIN;
+SELECT reffunc2();
+
+ reffunc2
+--------------------
+ &lt;unnamed cursor 1&gt;
+(1 row)
+
+FETCH ALL IN "&lt;unnamed cursor 1&gt;";
+COMMIT;
+</pre><p>
+ </p><p>
+ The following example shows one way to return multiple cursors
+ from a single function:
+
+</p><pre class="programlisting">
+CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
+BEGIN
+ OPEN $1 FOR SELECT * FROM table_1;
+ RETURN NEXT $1;
+ OPEN $2 FOR SELECT * FROM table_2;
+ RETURN NEXT $2;
+END;
+$$ LANGUAGE plpgsql;
+
+-- need to be in a transaction to use cursors.
+BEGIN;
+
+SELECT * FROM myfunc('a', 'b');
+
+FETCH ALL FROM a;
+FETCH ALL FROM b;
+COMMIT;
+</pre><p>
+ </p></div></div><div class="sect2" id="PLPGSQL-CURSOR-FOR-LOOP"><div class="titlepage"><div><div><h3 class="title">43.7.4. Looping through a Cursor's Result</h3></div></div></div><p>
+ There is a variant of the <code class="command">FOR</code> statement that allows
+ iterating through the rows returned by a cursor. The syntax is:
+
+</p><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+FOR <em class="replaceable"><code>recordvar</code></em> IN <em class="replaceable"><code>bound_cursorvar</code></em> [<span class="optional"> ( [<span class="optional"> <em class="replaceable"><code>argument_name</code></em> := </span>] <em class="replaceable"><code>argument_value</code></em> [<span class="optional">, ...</span>] ) </span>] LOOP
+ <em class="replaceable"><code>statements</code></em>
+END LOOP [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+
+ The cursor variable must have been bound to some query when it was
+ declared, and it <span class="emphasis"><em>cannot</em></span> be open already. The
+ <code class="command">FOR</code> statement automatically opens the cursor, and it closes
+ the cursor again when the loop exits. A list of actual argument value
+ expressions must appear if and only if the cursor was declared to take
+ arguments. These values will be substituted in the query, in just
+ the same way as during an <code class="command">OPEN</code> (see <a class="xref" href="plpgsql-cursors.html#PLPGSQL-OPEN-BOUND-CURSOR" title="43.7.2.3. Opening a Bound Cursor">Section 43.7.2.3</a>).
+ </p><p>
+ The variable <em class="replaceable"><code>recordvar</code></em> is automatically
+ defined as type <code class="type">record</code> and exists only inside the loop (any
+ existing definition of the variable name is ignored within the loop).
+ Each row returned by the cursor is successively assigned to this
+ record variable and the loop body is executed.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-control-structures.html" title="43.6. Control Structures">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-transactions.html" title="43.8. Transaction Management">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.6. Control Structures </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.8. Transaction Management</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-declarations.html b/doc/src/sgml/html/plpgsql-declarations.html
new file mode 100644
index 0000000..148b20c
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-declarations.html
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.3. Declarations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL" /><link rel="next" href="plpgsql-expressions.html" title="43.4. Expressions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.3. Declarations</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-expressions.html" title="43.4. Expressions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-DECLARATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.3. Declarations</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS">43.3.1. Declaring Function Parameters</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-ALIAS">43.3.2. <code class="literal">ALIAS</code></a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-TYPE">43.3.3. Copying Types</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-ROWTYPES">43.3.4. Row Types</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-RECORDS">43.3.5. Record Types</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-COLLATION">43.3.6. Collation of <span class="application">PL/pgSQL</span> Variables</a></span></dt></dl></div><p>
+ All variables used in a block must be declared in the
+ declarations section of the block.
+ (The only exceptions are that the loop variable of a <code class="literal">FOR</code> loop
+ iterating over a range of integer values is automatically declared as an
+ integer variable, and likewise the loop variable of a <code class="literal">FOR</code> loop
+ iterating over a cursor's result is automatically declared as a
+ record variable.)
+ </p><p>
+ <span class="application">PL/pgSQL</span> variables can have any SQL data type, such as
+ <code class="type">integer</code>, <code class="type">varchar</code>, and
+ <code class="type">char</code>.
+ </p><p>
+ Here are some examples of variable declarations:
+</p><pre class="programlisting">
+user_id integer;
+quantity numeric(5);
+url varchar;
+myrow tablename%ROWTYPE;
+myfield tablename.columnname%TYPE;
+arow RECORD;
+</pre><p>
+ </p><p>
+ The general syntax of a variable declaration is:
+</p><pre class="synopsis">
+<em class="replaceable"><code>name</code></em> [<span class="optional"> CONSTANT </span>] <em class="replaceable"><code>type</code></em> [<span class="optional"> COLLATE <em class="replaceable"><code>collation_name</code></em> </span>] [<span class="optional"> NOT NULL </span>] [<span class="optional"> { DEFAULT | := | = } <em class="replaceable"><code>expression</code></em> </span>];
+</pre><p>
+ The <code class="literal">DEFAULT</code> clause, if given, specifies the initial value assigned
+ to the variable when the block is entered. If the <code class="literal">DEFAULT</code> clause
+ is not given then the variable is initialized to the
+ <acronym class="acronym">SQL</acronym> null value.
+ The <code class="literal">CONSTANT</code> option prevents the variable from being
+ assigned to after initialization, so that its value will remain constant
+ for the duration of the block.
+ The <code class="literal">COLLATE</code> option specifies a collation to use for the
+ variable (see <a class="xref" href="plpgsql-declarations.html#PLPGSQL-DECLARATION-COLLATION" title="43.3.6. Collation of PL/pgSQL Variables">Section 43.3.6</a>).
+ If <code class="literal">NOT NULL</code>
+ is specified, an assignment of a null value results in a run-time
+ error. All variables declared as <code class="literal">NOT NULL</code>
+ must have a nonnull default value specified.
+ Equal (<code class="literal">=</code>) can be used instead of PL/SQL-compliant
+ <code class="literal">:=</code>.
+ </p><p>
+ A variable's default value is evaluated and assigned to the variable
+ each time the block is entered (not just once per function call).
+ So, for example, assigning <code class="literal">now()</code> to a variable of type
+ <code class="type">timestamp</code> causes the variable to have the
+ time of the current function call, not the time when the function was
+ precompiled.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+quantity integer DEFAULT 32;
+url varchar := 'http://mysite.com';
+transaction_time CONSTANT timestamp with time zone := now();
+</pre><p>
+ </p><p>
+ Once declared, a variable's value can be used in later initialization
+ expressions in the same block, for example:
+</p><pre class="programlisting">
+DECLARE
+ x integer := 1;
+ y integer := x + 1;
+</pre><p>
+ </p><div class="sect2" id="PLPGSQL-DECLARATION-PARAMETERS"><div class="titlepage"><div><div><h3 class="title">43.3.1. Declaring Function Parameters</h3></div></div></div><p>
+ Parameters passed to functions are named with the identifiers
+ <code class="literal">$1</code>, <code class="literal">$2</code>,
+ etc. Optionally, aliases can be declared for
+ <code class="literal">$<em class="replaceable"><code>n</code></em></code>
+ parameter names for increased readability. Either the alias or the
+ numeric identifier can then be used to refer to the parameter value.
+ </p><p>
+ There are two ways to create an alias. The preferred way is to give a
+ name to the parameter in the <code class="command">CREATE FUNCTION</code> command,
+ for example:
+</p><pre class="programlisting">
+CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
+BEGIN
+ RETURN subtotal * 0.06;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ The other way is to explicitly declare an alias, using the
+ declaration syntax
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>name</code></em> ALIAS FOR $<em class="replaceable"><code>n</code></em>;
+</pre><p>
+
+ The same example in this style looks like:
+</p><pre class="programlisting">
+CREATE FUNCTION sales_tax(real) RETURNS real AS $$
+DECLARE
+ subtotal ALIAS FOR $1;
+BEGIN
+ RETURN subtotal * 0.06;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ These two examples are not perfectly equivalent. In the first case,
+ <code class="literal">subtotal</code> could be referenced as
+ <code class="literal">sales_tax.subtotal</code>, but in the second case it could not.
+ (Had we attached a label to the inner block, <code class="literal">subtotal</code> could
+ be qualified with that label, instead.)
+ </p></div><p>
+ Some more examples:
+</p><pre class="programlisting">
+CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$
+DECLARE
+ v_string ALIAS FOR $1;
+ index ALIAS FOR $2;
+BEGIN
+ -- some computations using v_string and index here
+END;
+$$ LANGUAGE plpgsql;
+
+
+CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURNS text AS $$
+BEGIN
+ RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ When a <span class="application">PL/pgSQL</span> function is declared
+ with output parameters, the output parameters are given
+ <code class="literal">$<em class="replaceable"><code>n</code></em></code> names and optional
+ aliases in just the same way as the normal input parameters. An
+ output parameter is effectively a variable that starts out NULL;
+ it should be assigned to during the execution of the function.
+ The final value of the parameter is what is returned. For instance,
+ the sales-tax example could also be done this way:
+
+</p><pre class="programlisting">
+CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
+BEGIN
+ tax := subtotal * 0.06;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ Notice that we omitted <code class="literal">RETURNS real</code> — we could have
+ included it, but it would be redundant.
+ </p><p>
+ To call a function with <code class="literal">OUT</code> parameters, omit the
+ output parameter(s) in the function call:
+</p><pre class="programlisting">
+SELECT sales_tax(100.00);
+</pre><p>
+ </p><p>
+ Output parameters are most useful when returning multiple values.
+ A trivial example is:
+
+</p><pre class="programlisting">
+CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$
+BEGIN
+ sum := x + y;
+ prod := x * y;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT * FROM sum_n_product(2, 4);
+ sum | prod
+-----+------
+ 6 | 8
+</pre><p>
+
+ As discussed in <a class="xref" href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS" title="38.5.4. SQL Functions with Output Parameters">Section 38.5.4</a>, this
+ effectively creates an anonymous record type for the function's
+ results. If a <code class="literal">RETURNS</code> clause is given, it must say
+ <code class="literal">RETURNS record</code>.
+ </p><p>
+ This also works with procedures, for example:
+
+</p><pre class="programlisting">
+CREATE PROCEDURE sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$
+BEGIN
+ sum := x + y;
+ prod := x * y;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ In a call to a procedure, all the parameters must be specified. For
+ output parameters, <code class="literal">NULL</code> may be specified when
+ calling the procedure from plain SQL:
+</p><pre class="programlisting">
+CALL sum_n_product(2, 4, NULL, NULL);
+ sum | prod
+-----+------
+ 6 | 8
+</pre><p>
+
+ However, when calling a procedure
+ from <span class="application">PL/pgSQL</span>, you should instead write a
+ variable for any output parameter; the variable will receive the result
+ of the call. See <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-CALLING-PROCEDURE" title="43.6.3. Calling a Procedure">Section 43.6.3</a>
+ for details.
+ </p><p>
+ Another way to declare a <span class="application">PL/pgSQL</span> function
+ is with <code class="literal">RETURNS TABLE</code>, for example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION extended_sales(p_itemno int)
+RETURNS TABLE(quantity int, total numeric) AS $$
+BEGIN
+ RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales AS s
+ WHERE s.itemno = p_itemno;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ This is exactly equivalent to declaring one or more <code class="literal">OUT</code>
+ parameters and specifying <code class="literal">RETURNS SETOF
+ <em class="replaceable"><code>sometype</code></em></code>.
+ </p><p>
+ When the return type of a <span class="application">PL/pgSQL</span> function
+ is declared as a polymorphic type (see
+ <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>), a special
+ parameter <code class="literal">$0</code> is created. Its data type is the actual
+ return type of the function, as deduced from the actual input types.
+ This allows the function to access its actual return type
+ as shown in <a class="xref" href="plpgsql-declarations.html#PLPGSQL-DECLARATION-TYPE" title="43.3.3. Copying Types">Section 43.3.3</a>.
+ <code class="literal">$0</code> is initialized to null and can be modified by
+ the function, so it can be used to hold the return value if desired,
+ though that is not required. <code class="literal">$0</code> can also be
+ given an alias. For example, this function works on any data type
+ that has a <code class="literal">+</code> operator:
+
+</p><pre class="programlisting">
+CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
+RETURNS anyelement AS $$
+DECLARE
+ result ALIAS FOR $0;
+BEGIN
+ result := v1 + v2 + v3;
+ RETURN result;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ The same effect can be obtained by declaring one or more output parameters as
+ polymorphic types. In this case the
+ special <code class="literal">$0</code> parameter is not used; the output
+ parameters themselves serve the same purpose. For example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement,
+ OUT sum anyelement)
+AS $$
+BEGIN
+ sum := v1 + v2 + v3;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ In practice it might be more useful to declare a polymorphic function
+ using the <code class="type">anycompatible</code> family of types, so that automatic
+ promotion of the input arguments to a common type will occur.
+ For example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible)
+RETURNS anycompatible AS $$
+BEGIN
+ RETURN v1 + v2 + v3;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ With this example, a call such as
+
+</p><pre class="programlisting">
+SELECT add_three_values(1, 2, 4.7);
+</pre><p>
+
+ will work, automatically promoting the integer inputs to numeric.
+ The function using <code class="type">anyelement</code> would require you to
+ cast the three inputs to the same type manually.
+ </p></div><div class="sect2" id="PLPGSQL-DECLARATION-ALIAS"><div class="titlepage"><div><div><h3 class="title">43.3.2. <code class="literal">ALIAS</code></h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>newname</code></em> ALIAS FOR <em class="replaceable"><code>oldname</code></em>;
+</pre><p>
+ The <code class="literal">ALIAS</code> syntax is more general than is suggested in the
+ previous section: you can declare an alias for any variable, not just
+ function parameters. The main practical use for this is to assign
+ a different name for variables with predetermined names, such as
+ <code class="varname">NEW</code> or <code class="varname">OLD</code> within
+ a trigger function.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+DECLARE
+ prior ALIAS FOR old;
+ updated ALIAS FOR new;
+</pre><p>
+ </p><p>
+ Since <code class="literal">ALIAS</code> creates two different ways to name the same
+ object, unrestricted use can be confusing. It's best to use it only
+ for the purpose of overriding predetermined names.
+ </p></div><div class="sect2" id="PLPGSQL-DECLARATION-TYPE"><div class="titlepage"><div><div><h3 class="title">43.3.3. Copying Types</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>variable</code></em>%TYPE
+</pre><p>
+ <code class="literal">%TYPE</code> provides the data type of a variable or
+ table column. You can use this to declare variables that will hold
+ database values. For example, let's say you have a column named
+ <code class="literal">user_id</code> in your <code class="literal">users</code>
+ table. To declare a variable with the same data type as
+ <code class="literal">users.user_id</code> you write:
+</p><pre class="programlisting">
+user_id users.user_id%TYPE;
+</pre><p>
+ </p><p>
+ By using <code class="literal">%TYPE</code> you don't need to know the data
+ type of the structure you are referencing, and most importantly,
+ if the data type of the referenced item changes in the future (for
+ instance: you change the type of <code class="literal">user_id</code>
+ from <code class="type">integer</code> to <code class="type">real</code>), you might not need
+ to change your function definition.
+ </p><p>
+ <code class="literal">%TYPE</code> is particularly valuable in polymorphic
+ functions, since the data types needed for internal variables can
+ change from one call to the next. Appropriate variables can be
+ created by applying <code class="literal">%TYPE</code> to the function's
+ arguments or result placeholders.
+ </p></div><div class="sect2" id="PLPGSQL-DECLARATION-ROWTYPES"><div class="titlepage"><div><div><h3 class="title">43.3.4. Row Types</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>name</code></em> <em class="replaceable"><code>table_name</code></em><code class="literal">%ROWTYPE</code>;
+<em class="replaceable"><code>name</code></em> <em class="replaceable"><code>composite_type_name</code></em>;
+</pre><p>
+ A variable of a composite type is called a <em class="firstterm">row</em>
+ variable (or <em class="firstterm">row-type</em> variable). Such a variable
+ can hold a whole row of a <code class="command">SELECT</code> or <code class="command">FOR</code>
+ query result, so long as that query's column set matches the
+ declared type of the variable.
+ The individual fields of the row value
+ are accessed using the usual dot notation, for example
+ <code class="literal">rowvar.field</code>.
+ </p><p>
+ A row variable can be declared to have the same type as the rows of
+ an existing table or view, by using the
+ <em class="replaceable"><code>table_name</code></em><code class="literal">%ROWTYPE</code>
+ notation; or it can be declared by giving a composite type's name.
+ (Since every table has an associated composite type of the same name,
+ it actually does not matter in <span class="productname">PostgreSQL</span> whether you
+ write <code class="literal">%ROWTYPE</code> or not. But the form with
+ <code class="literal">%ROWTYPE</code> is more portable.)
+ </p><p>
+ Parameters to a function can be
+ composite types (complete table rows). In that case, the
+ corresponding identifier <code class="literal">$<em class="replaceable"><code>n</code></em></code> will be a row variable, and fields can
+ be selected from it, for example <code class="literal">$1.user_id</code>.
+ </p><p>
+ Here is an example of using composite types. <code class="structname">table1</code>
+ and <code class="structname">table2</code> are existing tables having at least the
+ mentioned fields:
+
+</p><pre class="programlisting">
+CREATE FUNCTION merge_fields(t_row table1) RETURNS text AS $$
+DECLARE
+ t2_row table2%ROWTYPE;
+BEGIN
+ SELECT * INTO t2_row FROM table2 WHERE ... ;
+ RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT merge_fields(t.*) FROM table1 t WHERE ... ;
+</pre><p>
+ </p></div><div class="sect2" id="PLPGSQL-DECLARATION-RECORDS"><div class="titlepage"><div><div><h3 class="title">43.3.5. Record Types</h3></div></div></div><pre class="synopsis">
+<em class="replaceable"><code>name</code></em> RECORD;
+</pre><p>
+ Record variables are similar to row-type variables, but they have no
+ predefined structure. They take on the actual row structure of the
+ row they are assigned during a <code class="command">SELECT</code> or <code class="command">FOR</code> command. The substructure
+ of a record variable can change each time it is assigned to.
+ A consequence of this is that until a record variable is first assigned
+ to, it has no substructure, and any attempt to access a
+ field in it will draw a run-time error.
+ </p><p>
+ Note that <code class="literal">RECORD</code> is not a true data type, only a placeholder.
+ One should also realize that when a <span class="application">PL/pgSQL</span>
+ function is declared to return type <code class="type">record</code>, this is not quite the
+ same concept as a record variable, even though such a function might
+ use a record variable to hold its result. In both cases the actual row
+ structure is unknown when the function is written, but for a function
+ returning <code class="type">record</code> the actual structure is determined when the
+ calling query is parsed, whereas a record variable can change its row
+ structure on-the-fly.
+ </p></div><div class="sect2" id="PLPGSQL-DECLARATION-COLLATION"><div class="titlepage"><div><div><h3 class="title">43.3.6. Collation of <span class="application">PL/pgSQL</span> Variables</h3></div></div></div><a id="id-1.8.8.5.14.2" class="indexterm"></a><p>
+ When a <span class="application">PL/pgSQL</span> function has one or more
+ parameters of collatable data types, a collation is identified for each
+ function call depending on the collations assigned to the actual
+ arguments, as described in <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>. If a collation is
+ successfully identified (i.e., there are no conflicts of implicit
+ collations among the arguments) then all the collatable parameters are
+ treated as having that collation implicitly. This will affect the
+ behavior of collation-sensitive operations within the function.
+ For example, consider
+
+</p><pre class="programlisting">
+CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
+BEGIN
+ RETURN a &lt; b;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT less_than(text_field_1, text_field_2) FROM table1;
+SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1;
+</pre><p>
+
+ The first use of <code class="function">less_than</code> will use the common collation
+ of <code class="structfield">text_field_1</code> and <code class="structfield">text_field_2</code> for
+ the comparison, while the second use will use <code class="literal">C</code> collation.
+ </p><p>
+ Furthermore, the identified collation is also assumed as the collation of
+ any local variables that are of collatable types. Thus this function
+ would not work any differently if it were written as
+
+</p><pre class="programlisting">
+CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
+DECLARE
+ local_a text := a;
+ local_b text := b;
+BEGIN
+ RETURN local_a &lt; local_b;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ If there are no parameters of collatable data types, or no common
+ collation can be identified for them, then parameters and local variables
+ use the default collation of their data type (which is usually the
+ database's default collation, but could be different for variables of
+ domain types).
+ </p><p>
+ A local variable of a collatable data type can have a different collation
+ associated with it by including the <code class="literal">COLLATE</code> option in its
+ declaration, for example
+
+</p><pre class="programlisting">
+DECLARE
+ local_a text COLLATE "en_US";
+</pre><p>
+
+ This option overrides the collation that would otherwise be
+ given to the variable according to the rules above.
+ </p><p>
+ Also, of course explicit <code class="literal">COLLATE</code> clauses can be written inside
+ a function if it is desired to force a particular collation to be used in
+ a particular operation. For example,
+
+</p><pre class="programlisting">
+CREATE FUNCTION less_than_c(a text, b text) RETURNS boolean AS $$
+BEGIN
+ RETURN a &lt; b COLLATE "C";
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ This overrides the collations associated with the table columns,
+ parameters, or local variables used in the expression, just as would
+ happen in a plain SQL command.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-expressions.html" title="43.4. Expressions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.2. Structure of <span class="application">PL/pgSQL</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.4. Expressions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-development-tips.html b/doc/src/sgml/html/plpgsql-development-tips.html
new file mode 100644
index 0000000..fdc7887
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-development-tips.html
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.12. Tips for Developing in PL/pgSQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-implementation.html" title="43.11. PL/pgSQL under the Hood" /><link rel="next" href="plpgsql-porting.html" title="43.13. Porting from Oracle PL/SQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.12. Tips for Developing in <span class="application">PL/pgSQL</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-implementation.html" title="43.11. PL/pgSQL under the Hood">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-porting.html" title="43.13. Porting from Oracle PL/SQL">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-DEVELOPMENT-TIPS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.12. Tips for Developing in <span class="application">PL/pgSQL</span></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-development-tips.html#PLPGSQL-QUOTE-TIPS">43.12.1. Handling of Quotation Marks</a></span></dt><dt><span class="sect2"><a href="plpgsql-development-tips.html#PLPGSQL-EXTRA-CHECKS">43.12.2. Additional Compile-Time and Run-Time Checks</a></span></dt></dl></div><p>
+ One good way to develop in
+ <span class="application">PL/pgSQL</span> is to use the text editor of your
+ choice to create your functions, and in another window, use
+ <span class="application">psql</span> to load and test those functions.
+ If you are doing it this way, it
+ is a good idea to write the function using <code class="command">CREATE OR
+ REPLACE FUNCTION</code>. That way you can just reload the file to update
+ the function definition. For example:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $$
+ ....
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ While running <span class="application">psql</span>, you can load or reload such
+ a function definition file with:
+</p><pre class="programlisting">
+\i filename.sql
+</pre><p>
+ and then immediately issue SQL commands to test the function.
+ </p><p>
+ Another good way to develop in <span class="application">PL/pgSQL</span> is with a
+ GUI database access tool that facilitates development in a
+ procedural language. One example of such a tool is
+ <span class="application">pgAdmin</span>, although others exist. These tools often
+ provide convenient features such as escaping single quotes and
+ making it easier to recreate and debug functions.
+ </p><div class="sect2" id="PLPGSQL-QUOTE-TIPS"><div class="titlepage"><div><div><h3 class="title">43.12.1. Handling of Quotation Marks</h3></div></div></div><p>
+ The code of a <span class="application">PL/pgSQL</span> function is specified in
+ <code class="command">CREATE FUNCTION</code> as a string literal. If you
+ write the string literal in the ordinary way with surrounding
+ single quotes, then any single quotes inside the function body
+ must be doubled; likewise any backslashes must be doubled (assuming
+ escape string syntax is used).
+ Doubling quotes is at best tedious, and in more complicated cases
+ the code can become downright incomprehensible, because you can
+ easily find yourself needing half a dozen or more adjacent quote marks.
+ It's recommended that you instead write the function body as a
+ <span class="quote">“<span class="quote">dollar-quoted</span>”</span> string literal (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>). In the dollar-quoting
+ approach, you never double any quote marks, but instead take care to
+ choose a different dollar-quoting delimiter for each level of
+ nesting you need. For example, you might write the <code class="command">CREATE
+ FUNCTION</code> command as:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$
+ ....
+$PROC$ LANGUAGE plpgsql;
+</pre><p>
+ Within this, you might use quote marks for simple literal strings in
+ SQL commands and <code class="literal">$$</code> to delimit fragments of SQL commands
+ that you are assembling as strings. If you need to quote text that
+ includes <code class="literal">$$</code>, you could use <code class="literal">$Q$</code>, and so on.
+ </p><p>
+ The following chart shows what you have to do when writing quote
+ marks without dollar quoting. It might be useful when translating
+ pre-dollar quoting code into something more comprehensible.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">1 quotation mark</span></dt><dd><p>
+ To begin and end the function body, for example:
+</p><pre class="programlisting">
+CREATE FUNCTION foo() RETURNS integer AS '
+ ....
+' LANGUAGE plpgsql;
+</pre><p>
+ Anywhere within a single-quoted function body, quote marks
+ <span class="emphasis"><em>must</em></span> appear in pairs.
+ </p></dd><dt><span class="term">2 quotation marks</span></dt><dd><p>
+ For string literals inside the function body, for example:
+</p><pre class="programlisting">
+a_output := ''Blah'';
+SELECT * FROM users WHERE f_name=''foobar'';
+</pre><p>
+ In the dollar-quoting approach, you'd just write:
+</p><pre class="programlisting">
+a_output := 'Blah';
+SELECT * FROM users WHERE f_name='foobar';
+</pre><p>
+ which is exactly what the <span class="application">PL/pgSQL</span> parser would see
+ in either case.
+ </p></dd><dt><span class="term">4 quotation marks</span></dt><dd><p>
+ When you need a single quotation mark in a string constant inside the
+ function body, for example:
+</p><pre class="programlisting">
+a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz''
+</pre><p>
+ The value actually appended to <code class="literal">a_output</code> would be:
+ <code class="literal"> AND name LIKE 'foobar' AND xyz</code>.
+ </p><p>
+ In the dollar-quoting approach, you'd write:
+</p><pre class="programlisting">
+a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$
+</pre><p>
+ being careful that any dollar-quote delimiters around this are not
+ just <code class="literal">$$</code>.
+ </p></dd><dt><span class="term">6 quotation marks</span></dt><dd><p>
+ When a single quotation mark in a string inside the function body is
+ adjacent to the end of that string constant, for example:
+</p><pre class="programlisting">
+a_output := a_output || '' AND name LIKE ''''foobar''''''
+</pre><p>
+ The value appended to <code class="literal">a_output</code> would then be:
+ <code class="literal"> AND name LIKE 'foobar'</code>.
+ </p><p>
+ In the dollar-quoting approach, this becomes:
+</p><pre class="programlisting">
+a_output := a_output || $$ AND name LIKE 'foobar'$$
+</pre><p>
+ </p></dd><dt><span class="term">10 quotation marks</span></dt><dd><p>
+ When you want two single quotation marks in a string constant (which
+ accounts for 8 quotation marks) and this is adjacent to the end of that
+ string constant (2 more). You will probably only need that if
+ you are writing a function that generates other functions, as in
+ <a class="xref" href="plpgsql-porting.html#PLPGSQL-PORTING-EX2" title="Example 43.10. Porting a Function that Creates Another Function from PL/SQL to PL/pgSQL">Example 43.10</a>.
+ For example:
+</p><pre class="programlisting">
+a_output := a_output || '' if v_'' ||
+ referrer_keys.kind || '' like ''''''''''
+ || referrer_keys.key_string || ''''''''''
+ then return '''''' || referrer_keys.referrer_type
+ || ''''''; end if;'';
+</pre><p>
+ The value of <code class="literal">a_output</code> would then be:
+</p><pre class="programlisting">
+if v_... like ''...'' then return ''...''; end if;
+</pre><p>
+ </p><p>
+ In the dollar-quoting approach, this becomes:
+</p><pre class="programlisting">
+a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$
+ || referrer_keys.key_string || $$'
+ then return '$$ || referrer_keys.referrer_type
+ || $$'; end if;$$;
+</pre><p>
+ where we assume we only need to put single quote marks into
+ <code class="literal">a_output</code>, because it will be re-quoted before use.
+ </p></dd></dl></div></div><div class="sect2" id="PLPGSQL-EXTRA-CHECKS"><div class="titlepage"><div><div><h3 class="title">43.12.2. Additional Compile-Time and Run-Time Checks</h3></div></div></div><p>
+ To aid the user in finding instances of simple but common problems before
+ they cause harm, <span class="application">PL/pgSQL</span> provides additional
+ <em class="replaceable"><code>checks</code></em>. When enabled, depending on the configuration, they
+ can be used to emit either a <code class="literal">WARNING</code> or an <code class="literal">ERROR</code>
+ during the compilation of a function. A function which has received
+ a <code class="literal">WARNING</code> can be executed without producing further messages,
+ so you are advised to test in a separate development environment.
+ </p><p>
+ Setting <code class="varname">plpgsql.extra_warnings</code>, or
+ <code class="varname">plpgsql.extra_errors</code>, as appropriate, to <code class="literal">"all"</code>
+ is encouraged in development and/or testing environments.
+ </p><p>
+ These additional checks are enabled through the configuration variables
+ <code class="varname">plpgsql.extra_warnings</code> for warnings and
+ <code class="varname">plpgsql.extra_errors</code> for errors. Both can be set either to
+ a comma-separated list of checks, <code class="literal">"none"</code> or
+ <code class="literal">"all"</code>. The default is <code class="literal">"none"</code>. Currently
+ the list of available checks includes:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">shadowed_variables</code></span></dt><dd><p>
+ Checks if a declaration shadows a previously defined variable.
+ </p></dd><dt><span class="term"><code class="varname">strict_multi_assignment</code></span></dt><dd><p>
+ Some <span class="application">PL/PgSQL</span> commands allow assigning
+ values to more than one variable at a time, such as
+ <code class="command">SELECT INTO</code>. Typically, the number of target
+ variables and the number of source variables should match, though
+ <span class="application">PL/PgSQL</span> will use <code class="literal">NULL</code>
+ for missing values and extra variables are ignored. Enabling this
+ check will cause <span class="application">PL/PgSQL</span> to throw a
+ <code class="literal">WARNING</code> or <code class="literal">ERROR</code> whenever the
+ number of target variables and the number of source variables are
+ different.
+ </p></dd><dt><span class="term"><code class="varname">too_many_rows</code></span></dt><dd><p>
+ Enabling this check will cause <span class="application">PL/PgSQL</span> to
+ check if a given query returns more than one row when an
+ <code class="literal">INTO</code> clause is used. As an <code class="literal">INTO</code>
+ statement will only ever use one row, having a query return multiple
+ rows is generally either inefficient and/or nondeterministic and
+ therefore is likely an error.
+ </p></dd></dl></div><p>
+
+ The following example shows the effect of <code class="varname">plpgsql.extra_warnings</code>
+ set to <code class="varname">shadowed_variables</code>:
+</p><pre class="programlisting">
+SET plpgsql.extra_warnings TO 'shadowed_variables';
+
+CREATE FUNCTION foo(f1 int) RETURNS int AS $$
+DECLARE
+f1 int;
+BEGIN
+RETURN f1;
+END;
+$$ LANGUAGE plpgsql;
+WARNING: variable "f1" shadows a previously defined variable
+LINE 3: f1 int;
+ ^
+CREATE FUNCTION
+</pre><p>
+ The below example shows the effects of setting
+ <code class="varname">plpgsql.extra_warnings</code> to
+ <code class="varname">strict_multi_assignment</code>:
+</p><pre class="programlisting">
+SET plpgsql.extra_warnings TO 'strict_multi_assignment';
+
+CREATE OR REPLACE FUNCTION public.foo()
+ RETURNS void
+ LANGUAGE plpgsql
+AS $$
+DECLARE
+ x int;
+ y int;
+BEGIN
+ SELECT 1 INTO x, y;
+ SELECT 1, 2 INTO x, y;
+ SELECT 1, 2, 3 INTO x, y;
+END;
+$$;
+
+SELECT foo();
+WARNING: number of source and target fields in assignment does not match
+DETAIL: strict_multi_assignment check of extra_warnings is active.
+HINT: Make sure the query returns the exact list of columns.
+WARNING: number of source and target fields in assignment does not match
+DETAIL: strict_multi_assignment check of extra_warnings is active.
+HINT: Make sure the query returns the exact list of columns.
+
+ foo
+-----
+
+(1 row)
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-implementation.html" title="43.11. PL/pgSQL under the Hood">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-porting.html" title="43.13. Porting from Oracle PL/SQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.11. <span class="application">PL/pgSQL</span> under the Hood </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.13. Porting from <span class="productname">Oracle</span> PL/SQL</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-errors-and-messages.html b/doc/src/sgml/html/plpgsql-errors-and-messages.html
new file mode 100644
index 0000000..6e9c577
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-errors-and-messages.html
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.9. Errors and Messages</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-transactions.html" title="43.8. Transaction Management" /><link rel="next" href="plpgsql-trigger.html" title="43.10. Trigger Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.9. Errors and Messages</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-transactions.html" title="43.8. Transaction Management">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-trigger.html" title="43.10. Trigger Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-ERRORS-AND-MESSAGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.9. Errors and Messages</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-RAISE">43.9.1. Reporting Errors and Messages</a></span></dt><dt><span class="sect2"><a href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-ASSERT">43.9.2. Checking Assertions</a></span></dt></dl></div><div class="sect2" id="PLPGSQL-STATEMENTS-RAISE"><div class="titlepage"><div><div><h3 class="title">43.9.1. Reporting Errors and Messages</h3></div></div></div><a id="id-1.8.8.11.2.2" class="indexterm"></a><a id="id-1.8.8.11.2.3" class="indexterm"></a><p>
+ Use the <code class="command">RAISE</code> statement to report messages and
+ raise errors.
+
+</p><pre class="synopsis">
+RAISE [<span class="optional"> <em class="replaceable"><code>level</code></em> </span>] '<em class="replaceable"><code>format</code></em>' [<span class="optional">, <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>]</span>] [<span class="optional"> USING <em class="replaceable"><code>option</code></em> = <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>];
+RAISE [<span class="optional"> <em class="replaceable"><code>level</code></em> </span>] <em class="replaceable"><code>condition_name</code></em> [<span class="optional"> USING <em class="replaceable"><code>option</code></em> = <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>];
+RAISE [<span class="optional"> <em class="replaceable"><code>level</code></em> </span>] SQLSTATE '<em class="replaceable"><code>sqlstate</code></em>' [<span class="optional"> USING <em class="replaceable"><code>option</code></em> = <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>];
+RAISE [<span class="optional"> <em class="replaceable"><code>level</code></em> </span>] USING <em class="replaceable"><code>option</code></em> = <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>];
+RAISE ;
+</pre><p>
+
+ The <em class="replaceable"><code>level</code></em> option specifies
+ the error severity. Allowed levels are <code class="literal">DEBUG</code>,
+ <code class="literal">LOG</code>, <code class="literal">INFO</code>,
+ <code class="literal">NOTICE</code>, <code class="literal">WARNING</code>,
+ and <code class="literal">EXCEPTION</code>, with <code class="literal">EXCEPTION</code>
+ being the default.
+ <code class="literal">EXCEPTION</code> raises an error (which normally aborts the
+ current transaction); the other levels only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a> and
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> configuration
+ variables. See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for more
+ information.
+ </p><p>
+ After <em class="replaceable"><code>level</code></em> if any,
+ you can specify a <em class="replaceable"><code>format</code></em> string
+ (which must be a simple string literal, not an expression). The
+ format string specifies the error message text to be reported.
+ The format string can be followed
+ by optional argument expressions to be inserted into the message.
+ Inside the format string, <code class="literal">%</code> is replaced by the
+ string representation of the next optional argument's value. Write
+ <code class="literal">%%</code> to emit a literal <code class="literal">%</code>.
+ The number of arguments must match the number of <code class="literal">%</code>
+ placeholders in the format string, or an error is raised during
+ the compilation of the function.
+ </p><p>
+ In this example, the value of <code class="literal">v_job_id</code> will replace the
+ <code class="literal">%</code> in the string:
+</p><pre class="programlisting">
+RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;
+</pre><p>
+ </p><p>
+ You can attach additional information to the error report by writing
+ <code class="literal">USING</code> followed by <em class="replaceable"><code>option</code></em> = <em class="replaceable"><code>expression</code></em> items. Each
+ <em class="replaceable"><code>expression</code></em> can be any
+ string-valued expression. The allowed <em class="replaceable"><code>option</code></em> key words are:
+
+ </p><div class="variablelist" id="RAISE-USING-OPTIONS"><dl class="variablelist"><dt><span class="term"><code class="literal">MESSAGE</code></span></dt><dd><p>Sets the error message text. This option can't be used in the
+ form of <code class="command">RAISE</code> that includes a format string
+ before <code class="literal">USING</code>.</p></dd><dt><span class="term"><code class="literal">DETAIL</code></span></dt><dd><p>Supplies an error detail message.</p></dd><dt><span class="term"><code class="literal">HINT</code></span></dt><dd><p>Supplies a hint message.</p></dd><dt><span class="term"><code class="literal">ERRCODE</code></span></dt><dd><p>Specifies the error code (SQLSTATE) to report, either by condition
+ name, as shown in <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>, or directly as a
+ five-character SQLSTATE code.</p></dd><dt><span class="term"><code class="literal">COLUMN</code><br /></span><span class="term"><code class="literal">CONSTRAINT</code><br /></span><span class="term"><code class="literal">DATATYPE</code><br /></span><span class="term"><code class="literal">TABLE</code><br /></span><span class="term"><code class="literal">SCHEMA</code></span></dt><dd><p>Supplies the name of a related object.</p></dd></dl></div><p>
+ </p><p>
+ This example will abort the transaction with the given error message
+ and hint:
+</p><pre class="programlisting">
+RAISE EXCEPTION 'Nonexistent ID --&gt; %', user_id
+ USING HINT = 'Please check your user ID';
+</pre><p>
+ </p><p>
+ These two examples show equivalent ways of setting the SQLSTATE:
+</p><pre class="programlisting">
+RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
+RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
+</pre><p>
+ </p><p>
+ There is a second <code class="command">RAISE</code> syntax in which the main argument
+ is the condition name or SQLSTATE to be reported, for example:
+</p><pre class="programlisting">
+RAISE division_by_zero;
+RAISE SQLSTATE '22012';
+</pre><p>
+ In this syntax, <code class="literal">USING</code> can be used to supply a custom
+ error message, detail, or hint. Another way to do the earlier
+ example is
+</p><pre class="programlisting">
+RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;
+</pre><p>
+ </p><p>
+ Still another variant is to write <code class="literal">RAISE USING</code> or <code class="literal">RAISE
+ <em class="replaceable"><code>level</code></em> USING</code> and put
+ everything else into the <code class="literal">USING</code> list.
+ </p><p>
+ The last variant of <code class="command">RAISE</code> has no parameters at all.
+ This form can only be used inside a <code class="literal">BEGIN</code> block's
+ <code class="literal">EXCEPTION</code> clause;
+ it causes the error currently being handled to be re-thrown.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> 9.1, <code class="command">RAISE</code> without
+ parameters was interpreted as re-throwing the error from the block
+ containing the active exception handler. Thus an <code class="literal">EXCEPTION</code>
+ clause nested within that handler could not catch it, even if the
+ <code class="command">RAISE</code> was within the nested <code class="literal">EXCEPTION</code> clause's
+ block. This was deemed surprising as well as being incompatible with
+ Oracle's PL/SQL.
+ </p></div><p>
+ If no condition name nor SQLSTATE is specified in a
+ <code class="command">RAISE EXCEPTION</code> command, the default is to use
+ <code class="literal">ERRCODE_RAISE_EXCEPTION</code> (<code class="literal">P0001</code>).
+ If no message text is specified, the default is to use the condition
+ name or SQLSTATE as message text.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When specifying an error code by SQLSTATE code, you are not
+ limited to the predefined error codes, but can select any
+ error code consisting of five digits and/or upper-case ASCII
+ letters, other than <code class="literal">00000</code>. It is recommended that
+ you avoid throwing error codes that end in three zeroes, because
+ these are category codes and can only be trapped by trapping
+ the whole category.
+ </p></div></div><div class="sect2" id="PLPGSQL-STATEMENTS-ASSERT"><div class="titlepage"><div><div><h3 class="title">43.9.2. Checking Assertions</h3></div></div></div><a id="id-1.8.8.11.3.2" class="indexterm"></a><a id="id-1.8.8.11.3.3" class="indexterm"></a><a id="id-1.8.8.11.3.4" class="indexterm"></a><p>
+ The <code class="command">ASSERT</code> statement is a convenient shorthand for
+ inserting debugging checks into <span class="application">PL/pgSQL</span>
+ functions.
+
+</p><pre class="synopsis">
+ASSERT <em class="replaceable"><code>condition</code></em> [<span class="optional"> , <em class="replaceable"><code>message</code></em> </span>];
+</pre><p>
+
+ The <em class="replaceable"><code>condition</code></em> is a Boolean
+ expression that is expected to always evaluate to true; if it does,
+ the <code class="command">ASSERT</code> statement does nothing further. If the
+ result is false or null, then an <code class="literal">ASSERT_FAILURE</code> exception
+ is raised. (If an error occurs while evaluating
+ the <em class="replaceable"><code>condition</code></em>, it is
+ reported as a normal error.)
+ </p><p>
+ If the optional <em class="replaceable"><code>message</code></em> is
+ provided, it is an expression whose result (if not null) replaces the
+ default error message text <span class="quote">“<span class="quote">assertion failed</span>”</span>, should
+ the <em class="replaceable"><code>condition</code></em> fail.
+ The <em class="replaceable"><code>message</code></em> expression is
+ not evaluated in the normal case where the assertion succeeds.
+ </p><p>
+ Testing of assertions can be enabled or disabled via the configuration
+ parameter <code class="literal">plpgsql.check_asserts</code>, which takes a Boolean
+ value; the default is <code class="literal">on</code>. If this parameter
+ is <code class="literal">off</code> then <code class="command">ASSERT</code> statements do nothing.
+ </p><p>
+ Note that <code class="command">ASSERT</code> is meant for detecting program
+ bugs, not for reporting ordinary error conditions. Use
+ the <code class="command">RAISE</code> statement, described above, for that.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-transactions.html" title="43.8. Transaction Management">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-trigger.html" title="43.10. Trigger Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.8. Transaction Management </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.10. Trigger Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-expressions.html b/doc/src/sgml/html/plpgsql-expressions.html
new file mode 100644
index 0000000..d6d377f
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-expressions.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.4. Expressions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-declarations.html" title="43.3. Declarations" /><link rel="next" href="plpgsql-statements.html" title="43.5. Basic Statements" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.4. Expressions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-declarations.html" title="43.3. Declarations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-statements.html" title="43.5. Basic Statements">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-EXPRESSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.4. Expressions</h2></div></div></div><p>
+ All expressions used in <span class="application">PL/pgSQL</span>
+ statements are processed using the server's main
+ <acronym class="acronym">SQL</acronym> executor. For example, when you write
+ a <span class="application">PL/pgSQL</span> statement like
+</p><pre class="synopsis">
+IF <em class="replaceable"><code>expression</code></em> THEN ...
+</pre><p>
+ <span class="application">PL/pgSQL</span> will evaluate the expression by
+ feeding a query like
+</p><pre class="synopsis">
+SELECT <em class="replaceable"><code>expression</code></em>
+</pre><p>
+ to the main SQL engine. While forming the <code class="command">SELECT</code> command,
+ any occurrences of <span class="application">PL/pgSQL</span> variable names
+ are replaced by query parameters, as discussed in detail in
+ <a class="xref" href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST" title="43.11.1. Variable Substitution">Section 43.11.1</a>.
+ This allows the query plan for the <code class="command">SELECT</code> to
+ be prepared just once and then reused for subsequent
+ evaluations with different values of the variables. Thus, what
+ really happens on first use of an expression is essentially a
+ <code class="command">PREPARE</code> command. For example, if we have declared
+ two integer variables <code class="literal">x</code> and <code class="literal">y</code>, and we write
+</p><pre class="programlisting">
+IF x &lt; y THEN ...
+</pre><p>
+ what happens behind the scenes is equivalent to
+</p><pre class="programlisting">
+PREPARE <em class="replaceable"><code>statement_name</code></em>(integer, integer) AS SELECT $1 &lt; $2;
+</pre><p>
+ and then this prepared statement is <code class="command">EXECUTE</code>d for each
+ execution of the <code class="command">IF</code> statement, with the current values
+ of the <span class="application">PL/pgSQL</span> variables supplied as
+ parameter values. Normally these details are
+ not important to a <span class="application">PL/pgSQL</span> user, but
+ they are useful to know when trying to diagnose a problem.
+ More information appears in <a class="xref" href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING" title="43.11.2. Plan Caching">Section 43.11.2</a>.
+ </p><p>
+ Since an <em class="replaceable"><code>expression</code></em> is converted to a
+ <code class="literal">SELECT</code> command, it can contain the same clauses
+ that an ordinary <code class="literal">SELECT</code> would, except that it
+ cannot include a top-level <code class="literal">UNION</code>,
+ <code class="literal">INTERSECT</code>, or <code class="literal">EXCEPT</code> clause.
+ Thus for example one could test whether a table is non-empty with
+</p><pre class="programlisting">
+IF count(*) &gt; 0 FROM my_table THEN ...
+</pre><p>
+ since the <em class="replaceable"><code>expression</code></em>
+ between <code class="literal">IF</code> and <code class="literal">THEN</code> is parsed as
+ though it were <code class="literal">SELECT count(*) &gt; 0 FROM my_table</code>.
+ The <code class="literal">SELECT</code> must produce a single column, and not
+ more than one row. (If it produces no rows, the result is taken as
+ NULL.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-declarations.html" title="43.3. Declarations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-statements.html" title="43.5. Basic Statements">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.3. Declarations </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.5. Basic Statements</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-implementation.html b/doc/src/sgml/html/plpgsql-implementation.html
new file mode 100644
index 0000000..8911f4c
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-implementation.html
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.11. PL/pgSQL under the Hood</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-trigger.html" title="43.10. Trigger Functions" /><link rel="next" href="plpgsql-development-tips.html" title="43.12. Tips for Developing in PL/pgSQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.11. <span class="application">PL/pgSQL</span> under the Hood</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-trigger.html" title="43.10. Trigger Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-development-tips.html" title="43.12. Tips for Developing in PL/pgSQL">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.11. <span class="application">PL/pgSQL</span> under the Hood</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST">43.11.1. Variable Substitution</a></span></dt><dt><span class="sect2"><a href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING">43.11.2. Plan Caching</a></span></dt></dl></div><p>
+ This section discusses some implementation details that are
+ frequently important for <span class="application">PL/pgSQL</span> users to know.
+ </p><div class="sect2" id="PLPGSQL-VAR-SUBST"><div class="titlepage"><div><div><h3 class="title">43.11.1. Variable Substitution</h3></div></div></div><p>
+ SQL statements and expressions within a <span class="application">PL/pgSQL</span> function
+ can refer to variables and parameters of the function. Behind the scenes,
+ <span class="application">PL/pgSQL</span> substitutes query parameters for such references.
+ Query parameters will only be substituted in places where they are
+ syntactically permissible. As an extreme case, consider
+ this example of poor programming style:
+</p><pre class="programlisting">
+INSERT INTO foo (foo) VALUES (foo(foo));
+</pre><p>
+ The first occurrence of <code class="literal">foo</code> must syntactically be a table
+ name, so it will not be substituted, even if the function has a variable
+ named <code class="literal">foo</code>. The second occurrence must be the name of a
+ column of that table, so it will not be substituted either. Likewise
+ the third occurrence must be a function name, so it also will not be
+ substituted for. Only the last occurrence is a candidate to be a
+ reference to a variable of the <span class="application">PL/pgSQL</span>
+ function.
+ </p><p>
+ Another way to understand this is that variable substitution can only
+ insert data values into an SQL command; it cannot dynamically change which
+ database objects are referenced by the command. (If you want to do
+ that, you must build a command string dynamically, as explained in
+ <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN" title="43.5.4. Executing Dynamic Commands">Section 43.5.4</a>.)
+ </p><p>
+ Since the names of variables are syntactically no different from the names
+ of table columns, there can be ambiguity in statements that also refer to
+ tables: is a given name meant to refer to a table column, or a variable?
+ Let's change the previous example to
+</p><pre class="programlisting">
+INSERT INTO dest (col) SELECT foo + bar FROM src;
+</pre><p>
+ Here, <code class="literal">dest</code> and <code class="literal">src</code> must be table names, and
+ <code class="literal">col</code> must be a column of <code class="literal">dest</code>, but <code class="literal">foo</code>
+ and <code class="literal">bar</code> might reasonably be either variables of the function
+ or columns of <code class="literal">src</code>.
+ </p><p>
+ By default, <span class="application">PL/pgSQL</span> will report an error if a name
+ in an SQL statement could refer to either a variable or a table column.
+ You can fix such a problem by renaming the variable or column,
+ or by qualifying the ambiguous reference, or by telling
+ <span class="application">PL/pgSQL</span> which interpretation to prefer.
+ </p><p>
+ The simplest solution is to rename the variable or column.
+ A common coding rule is to use a
+ different naming convention for <span class="application">PL/pgSQL</span>
+ variables than you use for column names. For example,
+ if you consistently name function variables
+ <code class="literal">v_<em class="replaceable"><code>something</code></em></code> while none of your
+ column names start with <code class="literal">v_</code>, no conflicts will occur.
+ </p><p>
+ Alternatively you can qualify ambiguous references to make them clear.
+ In the above example, <code class="literal">src.foo</code> would be an unambiguous reference
+ to the table column. To create an unambiguous reference to a variable,
+ declare it in a labeled block and use the block's label
+ (see <a class="xref" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL">Section 43.2</a>). For example,
+</p><pre class="programlisting">
+&lt;&lt;block&gt;&gt;
+DECLARE
+ foo int;
+BEGIN
+ foo := ...;
+ INSERT INTO dest (col) SELECT block.foo + bar FROM src;
+</pre><p>
+ Here <code class="literal">block.foo</code> means the variable even if there is a column
+ <code class="literal">foo</code> in <code class="literal">src</code>. Function parameters, as well as
+ special variables such as <code class="literal">FOUND</code>, can be qualified by the
+ function's name, because they are implicitly declared in an outer block
+ labeled with the function's name.
+ </p><p>
+ Sometimes it is impractical to fix all the ambiguous references in a
+ large body of <span class="application">PL/pgSQL</span> code. In such cases you can
+ specify that <span class="application">PL/pgSQL</span> should resolve ambiguous references
+ as the variable (which is compatible with <span class="application">PL/pgSQL</span>'s
+ behavior before <span class="productname">PostgreSQL</span> 9.0), or as the
+ table column (which is compatible with some other systems such as
+ <span class="productname">Oracle</span>).
+ </p><a id="id-1.8.8.13.3.9" class="indexterm"></a><p>
+ To change this behavior on a system-wide basis, set the configuration
+ parameter <code class="literal">plpgsql.variable_conflict</code> to one of
+ <code class="literal">error</code>, <code class="literal">use_variable</code>, or
+ <code class="literal">use_column</code> (where <code class="literal">error</code> is the factory default).
+ This parameter affects subsequent compilations
+ of statements in <span class="application">PL/pgSQL</span> functions, but not statements
+ already compiled in the current session.
+ Because changing this setting
+ can cause unexpected changes in the behavior of <span class="application">PL/pgSQL</span>
+ functions, it can only be changed by a superuser.
+ </p><p>
+ You can also set the behavior on a function-by-function basis, by
+ inserting one of these special commands at the start of the function
+ text:
+</p><pre class="programlisting">
+#variable_conflict error
+#variable_conflict use_variable
+#variable_conflict use_column
+</pre><p>
+ These commands affect only the function they are written in, and override
+ the setting of <code class="literal">plpgsql.variable_conflict</code>. An example is
+</p><pre class="programlisting">
+CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
+ #variable_conflict use_variable
+ DECLARE
+ curtime timestamp := now();
+ BEGIN
+ UPDATE users SET last_modified = curtime, comment = comment
+ WHERE users.id = id;
+ END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ In the <code class="literal">UPDATE</code> command, <code class="literal">curtime</code>, <code class="literal">comment</code>,
+ and <code class="literal">id</code> will refer to the function's variable and parameters
+ whether or not <code class="literal">users</code> has columns of those names. Notice
+ that we had to qualify the reference to <code class="literal">users.id</code> in the
+ <code class="literal">WHERE</code> clause to make it refer to the table column.
+ But we did not have to qualify the reference to <code class="literal">comment</code>
+ as a target in the <code class="literal">UPDATE</code> list, because syntactically
+ that must be a column of <code class="literal">users</code>. We could write the same
+ function without depending on the <code class="literal">variable_conflict</code> setting
+ in this way:
+</p><pre class="programlisting">
+CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
+ &lt;&lt;fn&gt;&gt;
+ DECLARE
+ curtime timestamp := now();
+ BEGIN
+ UPDATE users SET last_modified = fn.curtime, comment = stamp_user.comment
+ WHERE users.id = stamp_user.id;
+ END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ Variable substitution does not happen in a command string given
+ to <code class="command">EXECUTE</code> or one of its variants. If you need to
+ insert a varying value into such a command, do so as part of
+ constructing the string value, or use <code class="literal">USING</code>, as illustrated in
+ <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN" title="43.5.4. Executing Dynamic Commands">Section 43.5.4</a>.
+ </p><p>
+ Variable substitution currently works only in <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, and commands containing one of
+ these (such as <code class="command">EXPLAIN</code> and <code class="command">CREATE TABLE
+ ... AS SELECT</code>),
+ because the main SQL engine allows query parameters only in these
+ commands. To use a non-constant name or value in other statement
+ types (generically called utility statements), you must construct
+ the utility statement as a string and <code class="command">EXECUTE</code> it.
+ </p></div><div class="sect2" id="PLPGSQL-PLAN-CACHING"><div class="titlepage"><div><div><h3 class="title">43.11.2. Plan Caching</h3></div></div></div><p>
+ The <span class="application">PL/pgSQL</span> interpreter parses the function's source
+ text and produces an internal binary instruction tree the first time the
+ function is called (within each session). The instruction tree
+ fully translates the
+ <span class="application">PL/pgSQL</span> statement structure, but individual
+ <acronym class="acronym">SQL</acronym> expressions and <acronym class="acronym">SQL</acronym> commands
+ used in the function are not translated immediately.
+ </p><p>
+ <a id="id-1.8.8.13.4.3.1" class="indexterm"></a>
+ As each expression and <acronym class="acronym">SQL</acronym> command is first
+ executed in the function, the <span class="application">PL/pgSQL</span> interpreter
+ parses and analyzes the command to create a prepared statement,
+ using the <acronym class="acronym">SPI</acronym> manager's
+ <code class="function">SPI_prepare</code> function.
+ Subsequent visits to that expression or command
+ reuse the prepared statement. Thus, a function with conditional code
+ paths that are seldom visited will never incur the overhead of
+ analyzing those commands that are never executed within the current
+ session. A disadvantage is that errors
+ in a specific expression or command cannot be detected until that
+ part of the function is reached in execution. (Trivial syntax
+ errors will be detected during the initial parsing pass, but
+ anything deeper will not be detected until execution.)
+ </p><p>
+ <span class="application">PL/pgSQL</span> (or more precisely, the SPI manager) can
+ furthermore attempt to cache the execution plan associated with any
+ particular prepared statement. If a cached plan is not used, then
+ a fresh execution plan is generated on each visit to the statement,
+ and the current parameter values (that is, <span class="application">PL/pgSQL</span>
+ variable values) can be used to optimize the selected plan. If the
+ statement has no parameters, or is executed many times, the SPI manager
+ will consider creating a <em class="firstterm">generic</em> plan that is not dependent
+ on specific parameter values, and caching that for re-use. Typically
+ this will happen only if the execution plan is not very sensitive to
+ the values of the <span class="application">PL/pgSQL</span> variables referenced in it.
+ If it is, generating a plan each time is a net win. See <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a> for more information about the behavior of
+ prepared statements.
+ </p><p>
+ Because <span class="application">PL/pgSQL</span> saves prepared statements
+ and sometimes execution plans in this way,
+ SQL commands that appear directly in a
+ <span class="application">PL/pgSQL</span> function must refer to the
+ same tables and columns on every execution; that is, you cannot use
+ a parameter as the name of a table or column in an SQL command. To get
+ around this restriction, you can construct dynamic commands using
+ the <span class="application">PL/pgSQL</span> <code class="command">EXECUTE</code>
+ statement — at the price of performing new parse analysis and
+ constructing a new execution plan on every execution.
+ </p><p>
+ The mutable nature of record variables presents another problem in this
+ connection. When fields of a record variable are used in
+ expressions or statements, the data types of the fields must not
+ change from one call of the function to the next, since each
+ expression will be analyzed using the data type that is present
+ when the expression is first reached. <code class="command">EXECUTE</code> can be
+ used to get around this problem when necessary.
+ </p><p>
+ If the same function is used as a trigger for more than one table,
+ <span class="application">PL/pgSQL</span> prepares and caches statements
+ independently for each such table — that is, there is a cache
+ for each trigger function and table combination, not just for each
+ function. This alleviates some of the problems with varying
+ data types; for instance, a trigger function will be able to work
+ successfully with a column named <code class="literal">key</code> even if it happens
+ to have different types in different tables.
+ </p><p>
+ Likewise, functions having polymorphic argument types have a separate
+ statement cache for each combination of actual argument types they have
+ been invoked for, so that data type differences do not cause unexpected
+ failures.
+ </p><p>
+ Statement caching can sometimes have surprising effects on the
+ interpretation of time-sensitive values. For example there
+ is a difference between what these two functions do:
+
+</p><pre class="programlisting">
+CREATE FUNCTION logfunc1(logtxt text) RETURNS void AS $$
+ BEGIN
+ INSERT INTO logtable VALUES (logtxt, 'now');
+ END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ and:
+
+</p><pre class="programlisting">
+CREATE FUNCTION logfunc2(logtxt text) RETURNS void AS $$
+ DECLARE
+ curtime timestamp;
+ BEGIN
+ curtime := 'now';
+ INSERT INTO logtable VALUES (logtxt, curtime);
+ END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ In the case of <code class="function">logfunc1</code>, the
+ <span class="productname">PostgreSQL</span> main parser knows when
+ analyzing the <code class="command">INSERT</code> that the
+ string <code class="literal">'now'</code> should be interpreted as
+ <code class="type">timestamp</code>, because the target column of
+ <code class="classname">logtable</code> is of that type. Thus,
+ <code class="literal">'now'</code> will be converted to a <code class="type">timestamp</code>
+ constant when the
+ <code class="command">INSERT</code> is analyzed, and then used in all
+ invocations of <code class="function">logfunc1</code> during the lifetime
+ of the session. Needless to say, this isn't what the programmer
+ wanted. A better idea is to use the <code class="literal">now()</code> or
+ <code class="literal">current_timestamp</code> function.
+ </p><p>
+ In the case of <code class="function">logfunc2</code>, the
+ <span class="productname">PostgreSQL</span> main parser does not know
+ what type <code class="literal">'now'</code> should become and therefore
+ it returns a data value of type <code class="type">text</code> containing the string
+ <code class="literal">now</code>. During the ensuing assignment
+ to the local variable <code class="varname">curtime</code>, the
+ <span class="application">PL/pgSQL</span> interpreter casts this
+ string to the <code class="type">timestamp</code> type by calling the
+ <code class="function">textout</code> and <code class="function">timestamp_in</code>
+ functions for the conversion. So, the computed time stamp is updated
+ on each execution as the programmer expects. Even though this
+ happens to work as expected, it's not terribly efficient, so
+ use of the <code class="literal">now()</code> function would still be a better idea.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-trigger.html" title="43.10. Trigger Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-development-tips.html" title="43.12. Tips for Developing in PL/pgSQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.10. Trigger Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.12. Tips for Developing in <span class="application">PL/pgSQL</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-overview.html b/doc/src/sgml/html/plpgsql-overview.html
new file mode 100644
index 0000000..0b77072
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-overview.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language" /><link rel="next" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.1. Overview</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-overview.html#PLPGSQL-ADVANTAGES">43.1.1. Advantages of Using <span class="application">PL/pgSQL</span></a></span></dt><dt><span class="sect2"><a href="plpgsql-overview.html#PLPGSQL-ARGS-RESULTS">43.1.2. Supported Argument and Result Data Types</a></span></dt></dl></div><p>
+ <span class="application">PL/pgSQL</span> is a loadable procedural
+ language for the <span class="productname">PostgreSQL</span> database
+ system. The design goals of <span class="application">PL/pgSQL</span> were to create
+ a loadable procedural language that
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ can be used to create functions, procedures, and triggers,
+ </p></li><li class="listitem"><p>
+ adds control structures to the <acronym class="acronym">SQL</acronym> language,
+ </p></li><li class="listitem"><p>
+ can perform complex computations,
+ </p></li><li class="listitem"><p>
+ inherits all user-defined types, functions, procedures, and operators,
+ </p></li><li class="listitem"><p>
+ can be defined to be trusted by the server,
+ </p></li><li class="listitem"><p>
+ is easy to use.
+ </p></li></ul></div><p>
+ </p><p>
+ Functions created with <span class="application">PL/pgSQL</span> can be
+ used anywhere that built-in functions could be used.
+ For example, it is possible to
+ create complex conditional computation functions and later use
+ them to define operators or use them in index expressions.
+ </p><p>
+ In <span class="productname">PostgreSQL</span> 9.0 and later,
+ <span class="application">PL/pgSQL</span> is installed by default.
+ However it is still a loadable module, so especially security-conscious
+ administrators could choose to remove it.
+ </p><div class="sect2" id="PLPGSQL-ADVANTAGES"><div class="titlepage"><div><div><h3 class="title">43.1.1. Advantages of Using <span class="application">PL/pgSQL</span></h3></div></div></div><p>
+ <acronym class="acronym">SQL</acronym> is the language <span class="productname">PostgreSQL</span>
+ and most other relational databases use as query language. It's
+ portable and easy to learn. But every <acronym class="acronym">SQL</acronym>
+ statement must be executed individually by the database server.
+ </p><p>
+ That means that your client application must send each query to
+ the database server, wait for it to be processed, receive and
+ process the results, do some computation, then send further
+ queries to the server. All this incurs interprocess
+ communication and will also incur network overhead if your client
+ is on a different machine than the database server.
+ </p><p>
+ With <span class="application">PL/pgSQL</span> you can group a block of
+ computation and a series of queries <span class="emphasis"><em>inside</em></span>
+ the database server, thus having the power of a procedural
+ language and the ease of use of SQL, but with considerable
+ savings of client/server communication overhead.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p> Extra round trips between
+ client and server are eliminated </p></li><li class="listitem"><p> Intermediate results that the client does not
+ need do not have to be marshaled or transferred between server
+ and client </p></li><li class="listitem"><p> Multiple rounds of query
+ parsing can be avoided </p></li></ul></div><p> This can result in a considerable performance increase as
+ compared to an application that does not use stored functions.
+ </p><p>
+ Also, with <span class="application">PL/pgSQL</span> you can use all
+ the data types, operators and functions of SQL.
+ </p></div><div class="sect2" id="PLPGSQL-ARGS-RESULTS"><div class="titlepage"><div><div><h3 class="title">43.1.2. Supported Argument and Result Data Types</h3></div></div></div><p>
+ Functions written in <span class="application">PL/pgSQL</span> can accept
+ as arguments any scalar or array data type supported by the server,
+ and they can return a result of any of these types. They can also
+ accept or return any composite type (row type) specified by name.
+ It is also possible to declare a <span class="application">PL/pgSQL</span>
+ function as accepting <code class="type">record</code>, which means that any
+ composite type will do as input, or
+ as returning <code class="type">record</code>, which means that the result
+ is a row type whose columns are determined by specification in the
+ calling query, as discussed in <a class="xref" href="queries-table-expressions.html#QUERIES-TABLEFUNCTIONS" title="7.2.1.4. Table Functions">Section 7.2.1.4</a>.
+ </p><p>
+ <span class="application">PL/pgSQL</span> functions can be declared to accept a variable
+ number of arguments by using the <code class="literal">VARIADIC</code> marker. This
+ works exactly the same way as for SQL functions, as discussed in
+ <a class="xref" href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS" title="38.5.6. SQL Functions with Variable Numbers of Arguments">Section 38.5.6</a>.
+ </p><p>
+ <span class="application">PL/pgSQL</span> functions can also be declared to
+ accept and return the polymorphic types described in
+ <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>, thus allowing the actual data
+ types handled by the function to vary from call to call.
+ Examples appear in <a class="xref" href="plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS" title="43.3.1. Declaring Function Parameters">Section 43.3.1</a>.
+ </p><p>
+ <span class="application">PL/pgSQL</span> functions can also be declared to return
+ a <span class="quote">“<span class="quote">set</span>”</span> (or table) of any data type that can be returned as
+ a single instance. Such a function generates its output by executing
+ <code class="command">RETURN NEXT</code> for each desired element of the result
+ set, or by using <code class="command">RETURN QUERY</code> to output the result of
+ evaluating a query.
+ </p><p>
+ Finally, a <span class="application">PL/pgSQL</span> function can be declared to return
+ <code class="type">void</code> if it has no useful return value. (Alternatively, it
+ could be written as a procedure in that case.)
+ </p><p>
+ <span class="application">PL/pgSQL</span> functions can also be declared with output
+ parameters in place of an explicit specification of the return type.
+ This does not add any fundamental capability to the language, but
+ it is often convenient, especially for returning multiple values.
+ The <code class="literal">RETURNS TABLE</code> notation can also be used in place
+ of <code class="literal">RETURNS SETOF</code>.
+ </p><p>
+ Specific examples appear in
+ <a class="xref" href="plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS" title="43.3.1. Declaring Function Parameters">Section 43.3.1</a> and
+ <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING" title="43.6.1. Returning from a Function">Section 43.6.1</a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-structure.html" title="43.2. Structure of PL/pgSQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.2. Structure of <span class="application">PL/pgSQL</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-porting.html b/doc/src/sgml/html/plpgsql-porting.html
new file mode 100644
index 0000000..222560c
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-porting.html
@@ -0,0 +1,560 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.13. Porting from Oracle PL/SQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-development-tips.html" title="43.12. Tips for Developing in PL/pgSQL" /><link rel="next" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.13. Porting from <span class="productname">Oracle</span> PL/SQL</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-development-tips.html" title="43.12. Tips for Developing in PL/pgSQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-PORTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.13. Porting from <span class="productname">Oracle</span> PL/SQL</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-porting.html#id-1.8.8.15.6">43.13.1. Porting Examples</a></span></dt><dt><span class="sect2"><a href="plpgsql-porting.html#PLPGSQL-PORTING-OTHER">43.13.2. Other Things to Watch For</a></span></dt><dt><span class="sect2"><a href="plpgsql-porting.html#PLPGSQL-PORTING-APPENDIX">43.13.3. Appendix</a></span></dt></dl></div><a id="id-1.8.8.15.2" class="indexterm"></a><a id="id-1.8.8.15.3" class="indexterm"></a><p>
+ This section explains differences between
+ <span class="productname">PostgreSQL</span>'s <span class="application">PL/pgSQL</span>
+ language and Oracle's <span class="application">PL/SQL</span> language,
+ to help developers who port applications from
+ <span class="trademark">Oracle</span>® to <span class="productname">PostgreSQL</span>.
+ </p><p>
+ <span class="application">PL/pgSQL</span> is similar to PL/SQL in many
+ aspects. It is a block-structured, imperative language, and all
+ variables have to be declared. Assignments, loops, and conditionals
+ are similar. The main differences you should keep in mind when
+ porting from <span class="application">PL/SQL</span> to
+ <span class="application">PL/pgSQL</span> are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If a name used in an SQL command could be either a column name of a
+ table used in the command or a reference to a variable of the function,
+ <span class="application">PL/SQL</span> treats it as a column name.
+ By default, <span class="application">PL/pgSQL</span> will throw an error
+ complaining that the name is ambiguous. You can specify
+ <code class="literal">plpgsql.variable_conflict</code> = <code class="literal">use_column</code>
+ to change this behavior to match <span class="application">PL/SQL</span>,
+ as explained in <a class="xref" href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST" title="43.11.1. Variable Substitution">Section 43.11.1</a>.
+ It's often best to avoid such ambiguities in the first place,
+ but if you have to port a large amount of code that depends on
+ this behavior, setting <code class="literal">variable_conflict</code> may be the
+ best solution.
+ </p></li><li class="listitem"><p>
+ In <span class="productname">PostgreSQL</span> the function body must be written as
+ a string literal. Therefore you need to use dollar quoting or escape
+ single quotes in the function body. (See <a class="xref" href="plpgsql-development-tips.html#PLPGSQL-QUOTE-TIPS" title="43.12.1. Handling of Quotation Marks">Section 43.12.1</a>.)
+ </p></li><li class="listitem"><p>
+ Data type names often need translation. For example, in Oracle string
+ values are commonly declared as being of type <code class="type">varchar2</code>, which
+ is a non-SQL-standard type. In <span class="productname">PostgreSQL</span>,
+ use type <code class="type">varchar</code> or <code class="type">text</code> instead. Similarly, replace
+ type <code class="type">number</code> with <code class="type">numeric</code>, or use some other numeric
+ data type if there's a more appropriate one.
+ </p></li><li class="listitem"><p>
+ Instead of packages, use schemas to organize your functions
+ into groups.
+ </p></li><li class="listitem"><p>
+ Since there are no packages, there are no package-level variables
+ either. This is somewhat annoying. You can keep per-session state
+ in temporary tables instead.
+ </p></li><li class="listitem"><p>
+ Integer <code class="command">FOR</code> loops with <code class="literal">REVERSE</code> work
+ differently: <span class="application">PL/SQL</span> counts down from the second
+ number to the first, while <span class="application">PL/pgSQL</span> counts down
+ from the first number to the second, requiring the loop bounds
+ to be swapped when porting. This incompatibility is unfortunate
+ but is unlikely to be changed. (See <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-INTEGER-FOR" title="43.6.5.5. FOR (Integer Variant)">Section 43.6.5.5</a>.)
+ </p></li><li class="listitem"><p>
+ <code class="command">FOR</code> loops over queries (other than cursors) also work
+ differently: the target variable(s) must have been declared,
+ whereas <span class="application">PL/SQL</span> always declares them implicitly.
+ An advantage of this is that the variable values are still accessible
+ after the loop exits.
+ </p></li><li class="listitem"><p>
+ There are various notational differences for the use of cursor
+ variables.
+ </p></li></ul></div><p>
+ </p><div class="sect2" id="id-1.8.8.15.6"><div class="titlepage"><div><div><h3 class="title">43.13.1. Porting Examples</h3></div></div></div><p>
+ <a class="xref" href="plpgsql-porting.html#PGSQL-PORTING-EX1" title="Example 43.9. Porting a Simple Function from PL/SQL to PL/pgSQL">Example 43.9</a> shows how to port a simple
+ function from <span class="application">PL/SQL</span> to <span class="application">PL/pgSQL</span>.
+ </p><div class="example" id="PGSQL-PORTING-EX1"><p class="title"><strong>Example 43.9. Porting a Simple Function from <span class="application">PL/SQL</span> to <span class="application">PL/pgSQL</span></strong></p><div class="example-contents"><p>
+ Here is an <span class="productname">Oracle</span> <span class="application">PL/SQL</span> function:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar2,
+ v_version varchar2)
+RETURN varchar2 IS
+BEGIN
+ IF v_version IS NULL THEN
+ RETURN v_name;
+ END IF;
+ RETURN v_name || '/' || v_version;
+END;
+/
+show errors;
+</pre><p>
+ </p><p>
+ Let's go through this function and see the differences compared to
+ <span class="application">PL/pgSQL</span>:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The type name <code class="type">varchar2</code> has to be changed to <code class="type">varchar</code>
+ or <code class="type">text</code>. In the examples in this section, we'll
+ use <code class="type">varchar</code>, but <code class="type">text</code> is often a better choice if
+ you do not need specific string length limits.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">RETURN</code> key word in the function
+ prototype (not the function body) becomes
+ <code class="literal">RETURNS</code> in
+ <span class="productname">PostgreSQL</span>.
+ Also, <code class="literal">IS</code> becomes <code class="literal">AS</code>, and you need to
+ add a <code class="literal">LANGUAGE</code> clause because <span class="application">PL/pgSQL</span>
+ is not the only possible function language.
+ </p></li><li class="listitem"><p>
+ In <span class="productname">PostgreSQL</span>, the function body is considered
+ to be a string literal, so you need to use quote marks or dollar
+ quotes around it. This substitutes for the terminating <code class="literal">/</code>
+ in the Oracle approach.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">show errors</code> command does not exist in
+ <span class="productname">PostgreSQL</span>, and is not needed since errors are
+ reported automatically.
+ </p></li></ul></div><p>
+ </p><p>
+ This is how this function would look when ported to
+ <span class="productname">PostgreSQL</span>:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar,
+ v_version varchar)
+RETURNS varchar AS $$
+BEGIN
+ IF v_version IS NULL THEN
+ RETURN v_name;
+ END IF;
+ RETURN v_name || '/' || v_version;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p></div></div><br class="example-break" /><p>
+ <a class="xref" href="plpgsql-porting.html#PLPGSQL-PORTING-EX2" title="Example 43.10. Porting a Function that Creates Another Function from PL/SQL to PL/pgSQL">Example 43.10</a> shows how to port a
+ function that creates another function and how to handle the
+ ensuing quoting problems.
+ </p><div class="example" id="PLPGSQL-PORTING-EX2"><p class="title"><strong>Example 43.10. Porting a Function that Creates Another Function from <span class="application">PL/SQL</span> to <span class="application">PL/pgSQL</span></strong></p><div class="example-contents"><p>
+ The following procedure grabs rows from a
+ <code class="command">SELECT</code> statement and builds a large function
+ with the results in <code class="literal">IF</code> statements, for the
+ sake of efficiency.
+ </p><p>
+ This is the Oracle version:
+</p><pre class="programlisting">
+CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc IS
+ CURSOR referrer_keys IS
+ SELECT * FROM cs_referrer_keys
+ ORDER BY try_order;
+ func_cmd VARCHAR(4000);
+BEGIN
+ func_cmd := 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host IN VARCHAR2,
+ v_domain IN VARCHAR2, v_url IN VARCHAR2) RETURN VARCHAR2 IS BEGIN';
+
+ FOR referrer_key IN referrer_keys LOOP
+ func_cmd := func_cmd ||
+ ' IF v_' || referrer_key.kind
+ || ' LIKE ''' || referrer_key.key_string
+ || ''' THEN RETURN ''' || referrer_key.referrer_type
+ || '''; END IF;';
+ END LOOP;
+
+ func_cmd := func_cmd || ' RETURN NULL; END;';
+
+ EXECUTE IMMEDIATE func_cmd;
+END;
+/
+show errors;
+</pre><p>
+ </p><p>
+ Here is how this function would end up in <span class="productname">PostgreSQL</span>:
+</p><pre class="programlisting">
+CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$
+DECLARE
+ referrer_keys CURSOR IS
+ SELECT * FROM cs_referrer_keys
+ ORDER BY try_order;
+ func_body text;
+ func_cmd text;
+BEGIN
+ func_body := 'BEGIN';
+
+ FOR referrer_key IN referrer_keys LOOP
+ func_body := func_body ||
+ ' IF v_' || referrer_key.kind
+ || ' LIKE ' || quote_literal(referrer_key.key_string)
+ || ' THEN RETURN ' || quote_literal(referrer_key.referrer_type)
+ || '; END IF;' ;
+ END LOOP;
+
+ func_body := func_body || ' RETURN NULL; END;';
+
+ func_cmd :=
+ 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host varchar,
+ v_domain varchar,
+ v_url varchar)
+ RETURNS varchar AS '
+ || quote_literal(func_body)
+ || ' LANGUAGE plpgsql;' ;
+
+ EXECUTE func_cmd;
+END;
+$func$ LANGUAGE plpgsql;
+</pre><p>
+ Notice how the body of the function is built separately and passed
+ through <code class="literal">quote_literal</code> to double any quote marks in it. This
+ technique is needed because we cannot safely use dollar quoting for
+ defining the new function: we do not know for sure what strings will
+ be interpolated from the <code class="structfield">referrer_key.key_string</code> field.
+ (We are assuming here that <code class="structfield">referrer_key.kind</code> can be
+ trusted to always be <code class="literal">host</code>, <code class="literal">domain</code>, or
+ <code class="literal">url</code>, but <code class="structfield">referrer_key.key_string</code> might be
+ anything, in particular it might contain dollar signs.) This function
+ is actually an improvement on the Oracle original, because it will
+ not generate broken code when <code class="structfield">referrer_key.key_string</code> or
+ <code class="structfield">referrer_key.referrer_type</code> contain quote marks.
+ </p></div></div><br class="example-break" /><p>
+ <a class="xref" href="plpgsql-porting.html#PLPGSQL-PORTING-EX3" title="Example 43.11. Porting a Procedure With String Manipulation and OUT Parameters from PL/SQL to PL/pgSQL">Example 43.11</a> shows how to port a function
+ with <code class="literal">OUT</code> parameters and string manipulation.
+ <span class="productname">PostgreSQL</span> does not have a built-in
+ <code class="function">instr</code> function, but you can create one
+ using a combination of other
+ functions. In <a class="xref" href="plpgsql-porting.html#PLPGSQL-PORTING-APPENDIX" title="43.13.3. Appendix">Section 43.13.3</a> there is a
+ <span class="application">PL/pgSQL</span> implementation of
+ <code class="function">instr</code> that you can use to make your porting
+ easier.
+ </p><div class="example" id="PLPGSQL-PORTING-EX3"><p class="title"><strong>Example 43.11. Porting a Procedure With String Manipulation and
+ <code class="literal">OUT</code> Parameters from <span class="application">PL/SQL</span> to
+ <span class="application">PL/pgSQL</span></strong></p><div class="example-contents"><p>
+ The following <span class="productname">Oracle</span> PL/SQL procedure is used
+ to parse a URL and return several elements (host, path, and query).
+ </p><p>
+ This is the Oracle version:
+</p><pre class="programlisting">
+CREATE OR REPLACE PROCEDURE cs_parse_url(
+ v_url IN VARCHAR2,
+ v_host OUT VARCHAR2, -- This will be passed back
+ v_path OUT VARCHAR2, -- This one too
+ v_query OUT VARCHAR2) -- And this one
+IS
+ a_pos1 INTEGER;
+ a_pos2 INTEGER;
+BEGIN
+ v_host := NULL;
+ v_path := NULL;
+ v_query := NULL;
+ a_pos1 := instr(v_url, '//');
+
+ IF a_pos1 = 0 THEN
+ RETURN;
+ END IF;
+ a_pos2 := instr(v_url, '/', a_pos1 + 2);
+ IF a_pos2 = 0 THEN
+ v_host := substr(v_url, a_pos1 + 2);
+ v_path := '/';
+ RETURN;
+ END IF;
+
+ v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
+ a_pos1 := instr(v_url, '?', a_pos2 + 1);
+
+ IF a_pos1 = 0 THEN
+ v_path := substr(v_url, a_pos2);
+ RETURN;
+ END IF;
+
+ v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
+ v_query := substr(v_url, a_pos1 + 1);
+END;
+/
+show errors;
+</pre><p>
+ </p><p>
+ Here is a possible translation into <span class="application">PL/pgSQL</span>:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION cs_parse_url(
+ v_url IN VARCHAR,
+ v_host OUT VARCHAR, -- This will be passed back
+ v_path OUT VARCHAR, -- This one too
+ v_query OUT VARCHAR) -- And this one
+AS $$
+DECLARE
+ a_pos1 INTEGER;
+ a_pos2 INTEGER;
+BEGIN
+ v_host := NULL;
+ v_path := NULL;
+ v_query := NULL;
+ a_pos1 := instr(v_url, '//');
+
+ IF a_pos1 = 0 THEN
+ RETURN;
+ END IF;
+ a_pos2 := instr(v_url, '/', a_pos1 + 2);
+ IF a_pos2 = 0 THEN
+ v_host := substr(v_url, a_pos1 + 2);
+ v_path := '/';
+ RETURN;
+ END IF;
+
+ v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
+ a_pos1 := instr(v_url, '?', a_pos2 + 1);
+
+ IF a_pos1 = 0 THEN
+ v_path := substr(v_url, a_pos2);
+ RETURN;
+ END IF;
+
+ v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
+ v_query := substr(v_url, a_pos1 + 1);
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ This function could be used like this:
+</p><pre class="programlisting">
+SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz');
+</pre><p>
+ </p></div></div><br class="example-break" /><p>
+ <a class="xref" href="plpgsql-porting.html#PLPGSQL-PORTING-EX4" title="Example 43.12. Porting a Procedure from PL/SQL to PL/pgSQL">Example 43.12</a> shows how to port a procedure
+ that uses numerous features that are specific to Oracle.
+ </p><div class="example" id="PLPGSQL-PORTING-EX4"><p class="title"><strong>Example 43.12. Porting a Procedure from <span class="application">PL/SQL</span> to <span class="application">PL/pgSQL</span></strong></p><div class="example-contents"><p>
+ The Oracle version:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS
+ a_running_job_count INTEGER;
+BEGIN
+ LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
+
+ SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
+
+ IF a_running_job_count &gt; 0 THEN
+ COMMIT; -- free lock
+ raise_application_error(-20000,
+ 'Unable to create a new job: a job is currently running.');
+ END IF;
+
+ DELETE FROM cs_active_job;
+ INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
+
+ BEGIN
+ INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
+ EXCEPTION
+ WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists
+ END;
+ COMMIT;
+END;
+/
+show errors
+</pre><p>
+ </p><p>
+ This is how we could port this procedure to <span class="application">PL/pgSQL</span>:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$
+DECLARE
+ a_running_job_count integer;
+BEGIN
+ LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
+
+ SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
+
+ IF a_running_job_count &gt; 0 THEN
+ COMMIT; -- free lock
+ RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- <span id="co.plpgsql-porting-raise"></span>(1)
+ END IF;
+
+ DELETE FROM cs_active_job;
+ INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
+
+ BEGIN
+ INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
+ EXCEPTION
+ WHEN unique_violation THEN -- <span id="co.plpgsql-porting-exception"></span>(2)
+ -- don't worry if it already exists
+ END;
+ COMMIT;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+
+ </p><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><p><a href="#co.plpgsql-porting-raise">(1)</a> </p></td><td valign="top" align="left"><p>
+ The syntax of <code class="literal">RAISE</code> is considerably different from
+ Oracle's statement, although the basic case <code class="literal">RAISE</code>
+ <em class="replaceable"><code>exception_name</code></em> works
+ similarly.
+ </p></td></tr><tr><td width="5%" valign="top" align="left"><p><a href="#co.plpgsql-porting-exception">(2)</a> </p></td><td valign="top" align="left"><p>
+ The exception names supported by <span class="application">PL/pgSQL</span> are
+ different from Oracle's. The set of built-in exception names
+ is much larger (see <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>). There
+ is not currently a way to declare user-defined exception names,
+ although you can throw user-chosen SQLSTATE values instead.
+ </p></td></tr></table></div><p>
+ </p></div></div><br class="example-break" /></div><div class="sect2" id="PLPGSQL-PORTING-OTHER"><div class="titlepage"><div><div><h3 class="title">43.13.2. Other Things to Watch For</h3></div></div></div><p>
+ This section explains a few other things to watch for when porting
+ Oracle <span class="application">PL/SQL</span> functions to
+ <span class="productname">PostgreSQL</span>.
+ </p><div class="sect3" id="PLPGSQL-PORTING-EXCEPTIONS"><div class="titlepage"><div><div><h4 class="title">43.13.2.1. Implicit Rollback after Exceptions</h4></div></div></div><p>
+ In <span class="application">PL/pgSQL</span>, when an exception is caught by an
+ <code class="literal">EXCEPTION</code> clause, all database changes since the block's
+ <code class="literal">BEGIN</code> are automatically rolled back. That is, the behavior
+ is equivalent to what you'd get in Oracle with:
+
+</p><pre class="programlisting">
+BEGIN
+ SAVEPOINT s1;
+ ... code here ...
+EXCEPTION
+ WHEN ... THEN
+ ROLLBACK TO s1;
+ ... code here ...
+ WHEN ... THEN
+ ROLLBACK TO s1;
+ ... code here ...
+END;
+</pre><p>
+
+ If you are translating an Oracle procedure that uses
+ <code class="command">SAVEPOINT</code> and <code class="command">ROLLBACK TO</code> in this style,
+ your task is easy: just omit the <code class="command">SAVEPOINT</code> and
+ <code class="command">ROLLBACK TO</code>. If you have a procedure that uses
+ <code class="command">SAVEPOINT</code> and <code class="command">ROLLBACK TO</code> in a different way
+ then some actual thought will be required.
+ </p></div><div class="sect3" id="id-1.8.8.15.7.4"><div class="titlepage"><div><div><h4 class="title">43.13.2.2. <code class="command">EXECUTE</code></h4></div></div></div><p>
+ The <span class="application">PL/pgSQL</span> version of
+ <code class="command">EXECUTE</code> works similarly to the
+ <span class="application">PL/SQL</span> version, but you have to remember to use
+ <code class="function">quote_literal</code> and
+ <code class="function">quote_ident</code> as described in <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN" title="43.5.4. Executing Dynamic Commands">Section 43.5.4</a>. Constructs of the
+ type <code class="literal">EXECUTE 'SELECT * FROM $1';</code> will not work
+ reliably unless you use these functions.
+ </p></div><div class="sect3" id="PLPGSQL-PORTING-OPTIMIZATION"><div class="titlepage"><div><div><h4 class="title">43.13.2.3. Optimizing <span class="application">PL/pgSQL</span> Functions</h4></div></div></div><p>
+ <span class="productname">PostgreSQL</span> gives you two function creation
+ modifiers to optimize execution: <span class="quote">“<span class="quote">volatility</span>”</span> (whether
+ the function always returns the same result when given the same
+ arguments) and <span class="quote">“<span class="quote">strictness</span>”</span> (whether the function
+ returns null if any argument is null). Consult the <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>
+ reference page for details.
+ </p><p>
+ When making use of these optimization attributes, your
+ <code class="command">CREATE FUNCTION</code> statement might look something
+ like this:
+
+</p><pre class="programlisting">
+CREATE FUNCTION foo(...) RETURNS integer AS $$
+...
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+</pre><p>
+ </p></div></div><div class="sect2" id="PLPGSQL-PORTING-APPENDIX"><div class="titlepage"><div><div><h3 class="title">43.13.3. Appendix</h3></div></div></div><p>
+ This section contains the code for a set of Oracle-compatible
+ <code class="function">instr</code> functions that you can use to simplify
+ your porting efforts.
+ </p><a id="id-1.8.8.15.8.3" class="indexterm"></a><pre class="programlisting">
+--
+-- instr functions that mimic Oracle's counterpart
+-- Syntax: instr(string1, string2 [, n [, m]])
+-- where [] denotes optional parameters.
+--
+-- Search string1, beginning at the nth character, for the mth occurrence
+-- of string2. If n is negative, search backwards, starting at the abs(n)'th
+-- character from the end of string1.
+-- If n is not passed, assume 1 (search starts at first character).
+-- If m is not passed, assume 1 (find first occurrence).
+-- Returns starting index of string2 in string1, or 0 if string2 is not found.
+--
+
+CREATE FUNCTION instr(varchar, varchar) RETURNS integer AS $$
+BEGIN
+ RETURN instr($1, $2, 1);
+END;
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+
+
+CREATE FUNCTION instr(string varchar, string_to_search_for varchar,
+ beg_index integer)
+RETURNS integer AS $$
+DECLARE
+ pos integer NOT NULL DEFAULT 0;
+ temp_str varchar;
+ beg integer;
+ length integer;
+ ss_length integer;
+BEGIN
+ IF beg_index &gt; 0 THEN
+ temp_str := substring(string FROM beg_index);
+ pos := position(string_to_search_for IN temp_str);
+
+ IF pos = 0 THEN
+ RETURN 0;
+ ELSE
+ RETURN pos + beg_index - 1;
+ END IF;
+ ELSIF beg_index &lt; 0 THEN
+ ss_length := char_length(string_to_search_for);
+ length := char_length(string);
+ beg := length + 1 + beg_index;
+
+ WHILE beg &gt; 0 LOOP
+ temp_str := substring(string FROM beg FOR ss_length);
+ IF string_to_search_for = temp_str THEN
+ RETURN beg;
+ END IF;
+
+ beg := beg - 1;
+ END LOOP;
+
+ RETURN 0;
+ ELSE
+ RETURN 0;
+ END IF;
+END;
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+
+
+CREATE FUNCTION instr(string varchar, string_to_search_for varchar,
+ beg_index integer, occur_index integer)
+RETURNS integer AS $$
+DECLARE
+ pos integer NOT NULL DEFAULT 0;
+ occur_number integer NOT NULL DEFAULT 0;
+ temp_str varchar;
+ beg integer;
+ i integer;
+ length integer;
+ ss_length integer;
+BEGIN
+ IF occur_index &lt;= 0 THEN
+ RAISE 'argument ''%'' is out of range', occur_index
+ USING ERRCODE = '22003';
+ END IF;
+
+ IF beg_index &gt; 0 THEN
+ beg := beg_index - 1;
+ FOR i IN 1..occur_index LOOP
+ temp_str := substring(string FROM beg + 1);
+ pos := position(string_to_search_for IN temp_str);
+ IF pos = 0 THEN
+ RETURN 0;
+ END IF;
+ beg := beg + pos;
+ END LOOP;
+
+ RETURN beg;
+ ELSIF beg_index &lt; 0 THEN
+ ss_length := char_length(string_to_search_for);
+ length := char_length(string);
+ beg := length + 1 + beg_index;
+
+ WHILE beg &gt; 0 LOOP
+ temp_str := substring(string FROM beg FOR ss_length);
+ IF string_to_search_for = temp_str THEN
+ occur_number := occur_number + 1;
+ IF occur_number = occur_index THEN
+ RETURN beg;
+ END IF;
+ END IF;
+
+ beg := beg - 1;
+ END LOOP;
+
+ RETURN 0;
+ ELSE
+ RETURN 0;
+ END IF;
+END;
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+
+</pre></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-development-tips.html" title="43.12. Tips for Developing in PL/pgSQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.12. Tips for Developing in <span class="application">PL/pgSQL</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 44. PL/Tcl — Tcl Procedural Language</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-statements.html b/doc/src/sgml/html/plpgsql-statements.html
new file mode 100644
index 0000000..5c4d0ab
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-statements.html
@@ -0,0 +1,598 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.5. Basic Statements</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-expressions.html" title="43.4. Expressions" /><link rel="next" href="plpgsql-control-structures.html" title="43.6. Control Structures" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.5. Basic Statements</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-expressions.html" title="43.4. Expressions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-control-structures.html" title="43.6. Control Structures">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-STATEMENTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.5. Basic Statements</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-ASSIGNMENT">43.5.1. Assignment</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-GENERAL-SQL">43.5.2. Executing SQL Commands</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW">43.5.3. Executing a Command with a Single-Row Result</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN">43.5.4. Executing Dynamic Commands</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS">43.5.5. Obtaining the Result Status</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-NULL">43.5.6. Doing Nothing At All</a></span></dt></dl></div><p>
+ In this section and the following ones, we describe all the statement
+ types that are explicitly understood by
+ <span class="application">PL/pgSQL</span>.
+ Anything not recognized as one of these statement types is presumed
+ to be an SQL command and is sent to the main database engine to execute,
+ as described in <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-GENERAL-SQL" title="43.5.2. Executing SQL Commands">Section 43.5.2</a>.
+ </p><div class="sect2" id="PLPGSQL-STATEMENTS-ASSIGNMENT"><div class="titlepage"><div><div><h3 class="title">43.5.1. Assignment</h3></div></div></div><p>
+ An assignment of a value to a <span class="application">PL/pgSQL</span>
+ variable is written as:
+</p><pre class="synopsis">
+<em class="replaceable"><code>variable</code></em> { := | = } <em class="replaceable"><code>expression</code></em>;
+</pre><p>
+ As explained previously, the expression in such a statement is evaluated
+ by means of an SQL <code class="command">SELECT</code> command sent to the main
+ database engine. The expression must yield a single value (possibly
+ a row value, if the variable is a row or record variable). The target
+ variable can be a simple variable (optionally qualified with a block
+ name), a field of a row or record target, or an element or slice of
+ an array target. Equal (<code class="literal">=</code>) can be
+ used instead of PL/SQL-compliant <code class="literal">:=</code>.
+ </p><p>
+ If the expression's result data type doesn't match the variable's
+ data type, the value will be coerced as though by an assignment cast
+ (see <a class="xref" href="typeconv-query.html" title="10.4. Value Storage">Section 10.4</a>). If no assignment cast is known
+ for the pair of data types involved, the <span class="application">PL/pgSQL</span>
+ interpreter will attempt to convert the result value textually, that is
+ by applying the result type's output function followed by the variable
+ type's input function. Note that this could result in run-time errors
+ generated by the input function, if the string form of the result value
+ is not acceptable to the input function.
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+tax := subtotal * 0.06;
+my_record.user_id := 20;
+my_array[j] := 20;
+my_array[1:3] := array[1,2,3];
+complex_array[n].realpart = 12.3;
+</pre><p>
+ </p></div><div class="sect2" id="PLPGSQL-STATEMENTS-GENERAL-SQL"><div class="titlepage"><div><div><h3 class="title">43.5.2. Executing SQL Commands</h3></div></div></div><p>
+ In general, any SQL command that does not return rows can be executed
+ within a <span class="application">PL/pgSQL</span> function just by writing
+ the command. For example, you could create and fill a table by writing
+</p><pre class="programlisting">
+CREATE TABLE mytable (id int primary key, data text);
+INSERT INTO mytable VALUES (1,'one'), (2,'two');
+</pre><p>
+ </p><p>
+ If the command does return rows (for example <code class="command">SELECT</code>,
+ or <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code>
+ with <code class="literal">RETURNING</code>), there are two ways to proceed.
+ When the command will return at most one row, or you only care about
+ the first row of output, write the command as usual but add
+ an <code class="literal">INTO</code> clause to capture the output, as described
+ in <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW" title="43.5.3. Executing a Command with a Single-Row Result">Section 43.5.3</a>.
+ To process all of the output rows, write the command as the data
+ source for a <code class="command">FOR</code> loop, as described in
+ <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING" title="43.6.6. Looping through Query Results">Section 43.6.6</a>.
+ </p><p>
+ Usually it is not sufficient just to execute statically-defined SQL
+ commands. Typically you'll want a command to use varying data values,
+ or even to vary in more fundamental ways such as by using different
+ table names at different times. Again, there are two ways to proceed
+ depending on the situation.
+ </p><p>
+ <span class="application">PL/pgSQL</span> variable values can be
+ automatically inserted into optimizable SQL commands, which
+ are <code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ <code class="command">MERGE</code>, and certain
+ utility commands that incorporate one of these, such
+ as <code class="command">EXPLAIN</code> and <code class="command">CREATE TABLE ... AS
+ SELECT</code>. In these commands,
+ any <span class="application">PL/pgSQL</span> variable name appearing
+ in the command text is replaced by a query parameter, and then the
+ current value of the variable is provided as the parameter value
+ at run time. This is exactly like the processing described earlier
+ for expressions; for details see <a class="xref" href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST" title="43.11.1. Variable Substitution">Section 43.11.1</a>.
+ </p><p>
+ When executing an optimizable SQL command in this way,
+ <span class="application">PL/pgSQL</span> may cache and re-use the execution
+ plan for the command, as discussed in
+ <a class="xref" href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING" title="43.11.2. Plan Caching">Section 43.11.2</a>.
+ </p><p>
+ Non-optimizable SQL commands (also called utility commands) are not
+ capable of accepting query parameters. So automatic substitution
+ of <span class="application">PL/pgSQL</span> variables does not work in such
+ commands. To include non-constant text in a utility command executed
+ from <span class="application">PL/pgSQL</span>, you must build the utility
+ command as a string and then <code class="command">EXECUTE</code> it, as
+ discussed in <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN" title="43.5.4. Executing Dynamic Commands">Section 43.5.4</a>.
+ </p><p>
+ <code class="command">EXECUTE</code> must also be used if you want to modify
+ the command in some other way than supplying a data value, for example
+ by changing a table name.
+ </p><p>
+ Sometimes it is useful to evaluate an expression or <code class="command">SELECT</code>
+ query but discard the result, for example when calling a function
+ that has side-effects but no useful result value. To do
+ this in <span class="application">PL/pgSQL</span>, use the
+ <code class="command">PERFORM</code> statement:
+
+</p><pre class="synopsis">
+PERFORM <em class="replaceable"><code>query</code></em>;
+</pre><p>
+
+ This executes <em class="replaceable"><code>query</code></em> and discards the
+ result. Write the <em class="replaceable"><code>query</code></em> the same
+ way you would write an SQL <code class="command">SELECT</code> command, but replace the
+ initial keyword <code class="command">SELECT</code> with <code class="command">PERFORM</code>.
+ For <code class="command">WITH</code> queries, use <code class="command">PERFORM</code> and then
+ place the query in parentheses. (In this case, the query can only
+ return one row.)
+ <span class="application">PL/pgSQL</span> variables will be
+ substituted into the query just as described above,
+ and the plan is cached in the same way. Also, the special variable
+ <code class="literal">FOUND</code> is set to true if the query produced at
+ least one row, or false if it produced no rows (see
+ <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS" title="43.5.5. Obtaining the Result Status">Section 43.5.5</a>).
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ One might expect that writing <code class="command">SELECT</code> directly
+ would accomplish this result, but at
+ present the only accepted way to do it is
+ <code class="command">PERFORM</code>. An SQL command that can return rows,
+ such as <code class="command">SELECT</code>, will be rejected as an error
+ unless it has an <code class="literal">INTO</code> clause as discussed in the
+ next section.
+ </p></div><p>
+ An example:
+</p><pre class="programlisting">
+PERFORM create_mv('cs_session_page_requests_mv', my_query);
+</pre><p>
+ </p></div><div class="sect2" id="PLPGSQL-STATEMENTS-SQL-ONEROW"><div class="titlepage"><div><div><h3 class="title">43.5.3. Executing a Command with a Single-Row Result</h3></div></div></div><a id="id-1.8.8.7.5.2" class="indexterm"></a><a id="id-1.8.8.7.5.3" class="indexterm"></a><p>
+ The result of an SQL command yielding a single row (possibly of multiple
+ columns) can be assigned to a record variable, row-type variable, or list
+ of scalar variables. This is done by writing the base SQL command and
+ adding an <code class="literal">INTO</code> clause. For example,
+
+</p><pre class="synopsis">
+SELECT <em class="replaceable"><code>select_expressions</code></em> INTO [<span class="optional">STRICT</span>] <em class="replaceable"><code>target</code></em> FROM ...;
+INSERT ... RETURNING <em class="replaceable"><code>expressions</code></em> INTO [<span class="optional">STRICT</span>] <em class="replaceable"><code>target</code></em>;
+UPDATE ... RETURNING <em class="replaceable"><code>expressions</code></em> INTO [<span class="optional">STRICT</span>] <em class="replaceable"><code>target</code></em>;
+DELETE ... RETURNING <em class="replaceable"><code>expressions</code></em> INTO [<span class="optional">STRICT</span>] <em class="replaceable"><code>target</code></em>;
+</pre><p>
+
+ where <em class="replaceable"><code>target</code></em> can be a record variable, a row
+ variable, or a comma-separated list of simple variables and
+ record/row fields.
+ <span class="application">PL/pgSQL</span> variables will be
+ substituted into the rest of the command (that is, everything but the
+ <code class="literal">INTO</code> clause) just as described above,
+ and the plan is cached in the same way.
+ This works for <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code> with
+ <code class="literal">RETURNING</code>, and certain utility commands
+ that return row sets, such as <code class="command">EXPLAIN</code>.
+ Except for the <code class="literal">INTO</code> clause, the SQL command is the same
+ as it would be written outside <span class="application">PL/pgSQL</span>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Note that this interpretation of <code class="command">SELECT</code> with <code class="literal">INTO</code>
+ is quite different from <span class="productname">PostgreSQL</span>'s regular
+ <code class="command">SELECT INTO</code> command, wherein the <code class="literal">INTO</code>
+ target is a newly created table. If you want to create a table from a
+ <code class="command">SELECT</code> result inside a
+ <span class="application">PL/pgSQL</span> function, use the syntax
+ <code class="command">CREATE TABLE ... AS SELECT</code>.
+ </p></div><p>
+ If a row variable or a variable list is used as target,
+ the command's result columns
+ must exactly match the structure of the target as to number and data
+ types, or else a run-time error
+ occurs. When a record variable is the target, it automatically
+ configures itself to the row type of the command's result columns.
+ </p><p>
+ The <code class="literal">INTO</code> clause can appear almost anywhere in the SQL
+ command. Customarily it is written either just before or just after
+ the list of <em class="replaceable"><code>select_expressions</code></em> in a
+ <code class="command">SELECT</code> command, or at the end of the command for other
+ command types. It is recommended that you follow this convention
+ in case the <span class="application">PL/pgSQL</span> parser becomes
+ stricter in future versions.
+ </p><p>
+ If <code class="literal">STRICT</code> is not specified in the <code class="literal">INTO</code>
+ clause, then <em class="replaceable"><code>target</code></em> will be set to the first
+ row returned by the command, or to nulls if the command returned no rows.
+ (Note that <span class="quote">“<span class="quote">the first row</span>”</span> is not
+ well-defined unless you've used <code class="literal">ORDER BY</code>.) Any result rows
+ after the first row are discarded.
+ You can check the special <code class="literal">FOUND</code> variable (see
+ <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS" title="43.5.5. Obtaining the Result Status">Section 43.5.5</a>) to
+ determine whether a row was returned:
+
+</p><pre class="programlisting">
+SELECT * INTO myrec FROM emp WHERE empname = myname;
+IF NOT FOUND THEN
+ RAISE EXCEPTION 'employee % not found', myname;
+END IF;
+</pre><p>
+
+ If the <code class="literal">STRICT</code> option is specified, the command must
+ return exactly one row or a run-time error will be reported, either
+ <code class="literal">NO_DATA_FOUND</code> (no rows) or <code class="literal">TOO_MANY_ROWS</code>
+ (more than one row). You can use an exception block if you wish
+ to catch the error, for example:
+
+</p><pre class="programlisting">
+BEGIN
+ SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
+ EXCEPTION
+ WHEN NO_DATA_FOUND THEN
+ RAISE EXCEPTION 'employee % not found', myname;
+ WHEN TOO_MANY_ROWS THEN
+ RAISE EXCEPTION 'employee % not unique', myname;
+END;
+</pre><p>
+ Successful execution of a command with <code class="literal">STRICT</code>
+ always sets <code class="literal">FOUND</code> to true.
+ </p><p>
+ For <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code> with
+ <code class="literal">RETURNING</code>, <span class="application">PL/pgSQL</span> reports
+ an error for more than one returned row, even when
+ <code class="literal">STRICT</code> is not specified. This is because there
+ is no option such as <code class="literal">ORDER BY</code> with which to determine
+ which affected row should be returned.
+ </p><p>
+ If <code class="literal">print_strict_params</code> is enabled for the function,
+ then when an error is thrown because the requirements
+ of <code class="literal">STRICT</code> are not met, the <code class="literal">DETAIL</code> part of
+ the error message will include information about the parameters
+ passed to the command.
+ You can change the <code class="literal">print_strict_params</code>
+ setting for all functions by setting
+ <code class="varname">plpgsql.print_strict_params</code>, though only subsequent
+ function compilations will be affected. You can also enable it
+ on a per-function basis by using a compiler option, for example:
+</p><pre class="programlisting">
+CREATE FUNCTION get_userid(username text) RETURNS int
+AS $$
+#print_strict_params on
+DECLARE
+userid int;
+BEGIN
+ SELECT users.userid INTO STRICT userid
+ FROM users WHERE users.username = get_userid.username;
+ RETURN userid;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ On failure, this function might produce an error message such as
+</p><pre class="programlisting">
+ERROR: query returned no rows
+DETAIL: parameters: $1 = 'nosuchuser'
+CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="literal">STRICT</code> option matches the behavior of
+ Oracle PL/SQL's <code class="command">SELECT INTO</code> and related statements.
+ </p></div></div><div class="sect2" id="PLPGSQL-STATEMENTS-EXECUTING-DYN"><div class="titlepage"><div><div><h3 class="title">43.5.4. Executing Dynamic Commands</h3></div></div></div><p>
+ Oftentimes you will want to generate dynamic commands inside your
+ <span class="application">PL/pgSQL</span> functions, that is, commands
+ that will involve different tables or different data types each
+ time they are executed. <span class="application">PL/pgSQL</span>'s
+ normal attempts to cache plans for commands (as discussed in
+ <a class="xref" href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING" title="43.11.2. Plan Caching">Section 43.11.2</a>) will not work in such
+ scenarios. To handle this sort of problem, the
+ <code class="command">EXECUTE</code> statement is provided:
+
+</p><pre class="synopsis">
+EXECUTE <em class="replaceable"><code>command-string</code></em> [<span class="optional"> INTO [<span class="optional">STRICT</span>] <em class="replaceable"><code>target</code></em> </span>] [<span class="optional"> USING <em class="replaceable"><code>expression</code></em> [<span class="optional">, ... </span>] </span>];
+</pre><p>
+
+ where <em class="replaceable"><code>command-string</code></em> is an expression
+ yielding a string (of type <code class="type">text</code>) containing the
+ command to be executed. The optional <em class="replaceable"><code>target</code></em>
+ is a record variable, a row variable, or a comma-separated list of
+ simple variables and record/row fields, into which the results of
+ the command will be stored. The optional <code class="literal">USING</code> expressions
+ supply values to be inserted into the command.
+ </p><p>
+ No substitution of <span class="application">PL/pgSQL</span> variables is done on the
+ computed command string. Any required variable values must be inserted
+ in the command string as it is constructed; or you can use parameters
+ as described below.
+ </p><p>
+ Also, there is no plan caching for commands executed via
+ <code class="command">EXECUTE</code>. Instead, the command is always planned
+ each time the statement is run. Thus the command
+ string can be dynamically created within the function to perform
+ actions on different tables and columns.
+ </p><p>
+ The <code class="literal">INTO</code> clause specifies where the results of
+ an SQL command returning rows should be assigned. If a row variable
+ or variable list is provided, it must exactly match the structure
+ of the command's results; if a
+ record variable is provided, it will configure itself to match the
+ result structure automatically. If multiple rows are returned,
+ only the first will be assigned to the <code class="literal">INTO</code>
+ variable(s). If no rows are returned, NULL is assigned to the
+ <code class="literal">INTO</code> variable(s). If no <code class="literal">INTO</code>
+ clause is specified, the command results are discarded.
+ </p><p>
+ If the <code class="literal">STRICT</code> option is given, an error is reported
+ unless the command produces exactly one row.
+ </p><p>
+ The command string can use parameter values, which are referenced
+ in the command as <code class="literal">$1</code>, <code class="literal">$2</code>, etc.
+ These symbols refer to values supplied in the <code class="literal">USING</code>
+ clause. This method is often preferable to inserting data values
+ into the command string as text: it avoids run-time overhead of
+ converting the values to text and back, and it is much less prone
+ to SQL-injection attacks since there is no need for quoting or escaping.
+ An example is:
+</p><pre class="programlisting">
+EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted &lt;= $2'
+ INTO c
+ USING checked_user, checked_date;
+</pre><p>
+ </p><p>
+ Note that parameter symbols can only be used for data values
+ — if you want to use dynamically determined table or column
+ names, you must insert them into the command string textually.
+ For example, if the preceding query needed to be done against a
+ dynamically selected table, you could do this:
+</p><pre class="programlisting">
+EXECUTE 'SELECT count(*) FROM '
+ || quote_ident(tabname)
+ || ' WHERE inserted_by = $1 AND inserted &lt;= $2'
+ INTO c
+ USING checked_user, checked_date;
+</pre><p>
+ A cleaner approach is to use <code class="function">format()</code>'s <code class="literal">%I</code>
+ specification to insert table or column names with automatic quoting:
+</p><pre class="programlisting">
+EXECUTE format('SELECT count(*) FROM %I '
+ 'WHERE inserted_by = $1 AND inserted &lt;= $2', tabname)
+ INTO c
+ USING checked_user, checked_date;
+</pre><p>
+ (This example relies on the SQL rule that string literals separated by a
+ newline are implicitly concatenated.)
+ </p><p>
+ Another restriction on parameter symbols is that they only work in
+ optimizable SQL commands
+ (<code class="command">SELECT</code>, <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">MERGE</code>, and certain commands containing one of these).
+ In other statement
+ types (generically called utility statements), you must insert
+ values textually even if they are just data values.
+ </p><p>
+ An <code class="command">EXECUTE</code> with a simple constant command string and some
+ <code class="literal">USING</code> parameters, as in the first example above, is
+ functionally equivalent to just writing the command directly in
+ <span class="application">PL/pgSQL</span> and allowing replacement of
+ <span class="application">PL/pgSQL</span> variables to happen automatically.
+ The important difference is that <code class="command">EXECUTE</code> will re-plan
+ the command on each execution, generating a plan that is specific
+ to the current parameter values; whereas
+ <span class="application">PL/pgSQL</span> may otherwise create a generic plan
+ and cache it for re-use. In situations where the best plan depends
+ strongly on the parameter values, it can be helpful to use
+ <code class="command">EXECUTE</code> to positively ensure that a generic plan is not
+ selected.
+ </p><p>
+ <code class="command">SELECT INTO</code> is not currently supported within
+ <code class="command">EXECUTE</code>; instead, execute a plain <code class="command">SELECT</code>
+ command and specify <code class="literal">INTO</code> as part of the <code class="command">EXECUTE</code>
+ itself.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <span class="application">PL/pgSQL</span>
+ <code class="command">EXECUTE</code> statement is not related to the
+ <a class="link" href="sql-execute.html" title="EXECUTE"><code class="command">EXECUTE</code></a> SQL
+ statement supported by the
+ <span class="productname">PostgreSQL</span> server. The server's
+ <code class="command">EXECUTE</code> statement cannot be used directly within
+ <span class="application">PL/pgSQL</span> functions (and is not needed).
+ </p></div><div class="example" id="PLPGSQL-QUOTE-LITERAL-EXAMPLE"><p class="title"><strong>Example 43.1. Quoting Values in Dynamic Queries</strong></p><div class="example-contents"><a id="id-1.8.8.7.6.13.2" class="indexterm"></a><a id="id-1.8.8.7.6.13.3" class="indexterm"></a><a id="id-1.8.8.7.6.13.4" class="indexterm"></a><a id="id-1.8.8.7.6.13.5" class="indexterm"></a><p>
+ When working with dynamic commands you will often have to handle escaping
+ of single quotes. The recommended method for quoting fixed text in your
+ function body is dollar quoting. (If you have legacy code that does
+ not use dollar quoting, please refer to the
+ overview in <a class="xref" href="plpgsql-development-tips.html#PLPGSQL-QUOTE-TIPS" title="43.12.1. Handling of Quotation Marks">Section 43.12.1</a>, which can save you
+ some effort when translating said code to a more reasonable scheme.)
+ </p><p>
+ Dynamic values require careful handling since they might contain
+ quote characters.
+ An example using <code class="function">format()</code> (this assumes that you are
+ dollar quoting the function body so quote marks need not be doubled):
+</p><pre class="programlisting">
+EXECUTE format('UPDATE tbl SET %I = $1 '
+ 'WHERE key = $2', colname) USING newvalue, keyvalue;
+</pre><p>
+ It is also possible to call the quoting functions directly:
+</p><pre class="programlisting">
+EXECUTE 'UPDATE tbl SET '
+ || quote_ident(colname)
+ || ' = '
+ || quote_literal(newvalue)
+ || ' WHERE key = '
+ || quote_literal(keyvalue);
+</pre><p>
+ </p><p>
+ This example demonstrates the use of the
+ <code class="function">quote_ident</code> and
+ <code class="function">quote_literal</code> functions (see <a class="xref" href="functions-string.html" title="9.4. String Functions and Operators">Section 9.4</a>). For safety, expressions containing column
+ or table identifiers should be passed through
+ <code class="function">quote_ident</code> before insertion in a dynamic query.
+ Expressions containing values that should be literal strings in the
+ constructed command should be passed through <code class="function">quote_literal</code>.
+ These functions take the appropriate steps to return the input text
+ enclosed in double or single quotes respectively, with any embedded
+ special characters properly escaped.
+ </p><p>
+ Because <code class="function">quote_literal</code> is labeled
+ <code class="literal">STRICT</code>, it will always return null when called with a
+ null argument. In the above example, if <code class="literal">newvalue</code> or
+ <code class="literal">keyvalue</code> were null, the entire dynamic query string would
+ become null, leading to an error from <code class="command">EXECUTE</code>.
+ You can avoid this problem by using the <code class="function">quote_nullable</code>
+ function, which works the same as <code class="function">quote_literal</code> except that
+ when called with a null argument it returns the string <code class="literal">NULL</code>.
+ For example,
+</p><pre class="programlisting">
+EXECUTE 'UPDATE tbl SET '
+ || quote_ident(colname)
+ || ' = '
+ || quote_nullable(newvalue)
+ || ' WHERE key = '
+ || quote_nullable(keyvalue);
+</pre><p>
+ If you are dealing with values that might be null, you should usually
+ use <code class="function">quote_nullable</code> in place of <code class="function">quote_literal</code>.
+ </p><p>
+ As always, care must be taken to ensure that null values in a query do
+ not deliver unintended results. For example the <code class="literal">WHERE</code> clause
+</p><pre class="programlisting">
+'WHERE key = ' || quote_nullable(keyvalue)
+</pre><p>
+ will never succeed if <code class="literal">keyvalue</code> is null, because the
+ result of using the equality operator <code class="literal">=</code> with a null operand
+ is always null. If you wish null to work like an ordinary key value,
+ you would need to rewrite the above as
+</p><pre class="programlisting">
+'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue)
+</pre><p>
+ (At present, <code class="literal">IS NOT DISTINCT FROM</code> is handled much less
+ efficiently than <code class="literal">=</code>, so don't do this unless you must.
+ See <a class="xref" href="functions-comparison.html" title="9.2. Comparison Functions and Operators">Section 9.2</a> for
+ more information on nulls and <code class="literal">IS DISTINCT</code>.)
+ </p><p>
+ Note that dollar quoting is only useful for quoting fixed text.
+ It would be a very bad idea to try to write this example as:
+</p><pre class="programlisting">
+EXECUTE 'UPDATE tbl SET '
+ || quote_ident(colname)
+ || ' = $$'
+ || newvalue
+ || '$$ WHERE key = '
+ || quote_literal(keyvalue);
+</pre><p>
+ because it would break if the contents of <code class="literal">newvalue</code>
+ happened to contain <code class="literal">$$</code>. The same objection would
+ apply to any other dollar-quoting delimiter you might pick.
+ So, to safely quote text that is not known in advance, you
+ <span class="emphasis"><em>must</em></span> use <code class="function">quote_literal</code>,
+ <code class="function">quote_nullable</code>, or <code class="function">quote_ident</code>, as appropriate.
+ </p><p>
+ Dynamic SQL statements can also be safely constructed using the
+ <code class="function">format</code> function (see <a class="xref" href="functions-string.html#FUNCTIONS-STRING-FORMAT" title="9.4.1. format">Section 9.4.1</a>). For example:
+</p><pre class="programlisting">
+EXECUTE format('UPDATE tbl SET %I = %L '
+ 'WHERE key = %L', colname, newvalue, keyvalue);
+</pre><p>
+ <code class="literal">%I</code> is equivalent to <code class="function">quote_ident</code>, and
+ <code class="literal">%L</code> is equivalent to <code class="function">quote_nullable</code>.
+ The <code class="function">format</code> function can be used in conjunction with
+ the <code class="literal">USING</code> clause:
+</p><pre class="programlisting">
+EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname)
+ USING newvalue, keyvalue;
+</pre><p>
+ This form is better because the variables are handled in their native
+ data type format, rather than unconditionally converting them to
+ text and quoting them via <code class="literal">%L</code>. It is also more efficient.
+ </p></div></div><br class="example-break" /><p>
+ A much larger example of a dynamic command and
+ <code class="command">EXECUTE</code> can be seen in <a class="xref" href="plpgsql-porting.html#PLPGSQL-PORTING-EX2" title="Example 43.10. Porting a Function that Creates Another Function from PL/SQL to PL/pgSQL">Example 43.10</a>, which builds and executes a
+ <code class="command">CREATE FUNCTION</code> command to define a new function.
+ </p></div><div class="sect2" id="PLPGSQL-STATEMENTS-DIAGNOSTICS"><div class="titlepage"><div><div><h3 class="title">43.5.5. Obtaining the Result Status</h3></div></div></div><p>
+ There are several ways to determine the effect of a command. The
+ first method is to use the <code class="command">GET DIAGNOSTICS</code>
+ command, which has the form:
+
+</p><pre class="synopsis">
+GET [<span class="optional"> CURRENT </span>] DIAGNOSTICS <em class="replaceable"><code>variable</code></em> { = | := } <em class="replaceable"><code>item</code></em> [<span class="optional"> , ... </span>];
+</pre><p>
+
+ This command allows retrieval of system status indicators.
+ <code class="literal">CURRENT</code> is a noise word (but see also <code class="command">GET STACKED
+ DIAGNOSTICS</code> in <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-EXCEPTION-DIAGNOSTICS" title="43.6.8.1. Obtaining Information about an Error">Section 43.6.8.1</a>).
+ Each <em class="replaceable"><code>item</code></em> is a key word identifying a status
+ value to be assigned to the specified <em class="replaceable"><code>variable</code></em>
+ (which should be of the right data type to receive it). The currently
+ available status items are shown
+ in <a class="xref" href="plpgsql-statements.html#PLPGSQL-CURRENT-DIAGNOSTICS-VALUES" title="Table 43.1. Available Diagnostics Items">Table 43.1</a>. Colon-equal
+ (<code class="literal">:=</code>) can be used instead of the SQL-standard <code class="literal">=</code>
+ token. An example:
+</p><pre class="programlisting">
+GET DIAGNOSTICS integer_var = ROW_COUNT;
+</pre><p>
+ </p><div class="table" id="PLPGSQL-CURRENT-DIAGNOSTICS-VALUES"><p class="title"><strong>Table 43.1. Available Diagnostics Items</strong></p><div class="table-contents"><table class="table" summary="Available Diagnostics Items" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="varname">ROW_COUNT</code></td><td><code class="type">bigint</code></td><td>the number of rows processed by the most
+ recent <acronym class="acronym">SQL</acronym> command</td></tr><tr><td><code class="literal">PG_CONTEXT</code></td><td><code class="type">text</code></td><td>line(s) of text describing the current call stack
+ (see <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-CALL-STACK" title="43.6.9. Obtaining Execution Location Information">Section 43.6.9</a>)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The second method to determine the effects of a command is to check the
+ special variable named <code class="literal">FOUND</code>, which is of
+ type <code class="type">boolean</code>. <code class="literal">FOUND</code> starts out
+ false within each <span class="application">PL/pgSQL</span> function call.
+ It is set by each of the following types of statements:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A <code class="command">SELECT INTO</code> statement sets
+ <code class="literal">FOUND</code> true if a row is assigned, false if no
+ row is returned.
+ </p></li><li class="listitem"><p>
+ A <code class="command">PERFORM</code> statement sets <code class="literal">FOUND</code>
+ true if it produces (and discards) one or more rows, false if
+ no row is produced.
+ </p></li><li class="listitem"><p>
+ <code class="command">UPDATE</code>, <code class="command">INSERT</code>, <code class="command">DELETE</code>,
+ and <code class="command">MERGE</code>
+ statements set <code class="literal">FOUND</code> true if at least one
+ row is affected, false if no row is affected.
+ </p></li><li class="listitem"><p>
+ A <code class="command">FETCH</code> statement sets <code class="literal">FOUND</code>
+ true if it returns a row, false if no row is returned.
+ </p></li><li class="listitem"><p>
+ A <code class="command">MOVE</code> statement sets <code class="literal">FOUND</code>
+ true if it successfully repositions the cursor, false otherwise.
+ </p></li><li class="listitem"><p>
+ A <code class="command">FOR</code> or <code class="command">FOREACH</code> statement sets
+ <code class="literal">FOUND</code> true
+ if it iterates one or more times, else false.
+ <code class="literal">FOUND</code> is set this way when the
+ loop exits; inside the execution of the loop,
+ <code class="literal">FOUND</code> is not modified by the
+ loop statement, although it might be changed by the
+ execution of other statements within the loop body.
+ </p></li><li class="listitem"><p>
+ <code class="command">RETURN QUERY</code> and <code class="command">RETURN QUERY
+ EXECUTE</code> statements set <code class="literal">FOUND</code>
+ true if the query returns at least one row, false if no row
+ is returned.
+ </p></li></ul></div><p>
+
+ Other <span class="application">PL/pgSQL</span> statements do not change
+ the state of <code class="literal">FOUND</code>.
+ Note in particular that <code class="command">EXECUTE</code>
+ changes the output of <code class="command">GET DIAGNOSTICS</code>, but
+ does not change <code class="literal">FOUND</code>.
+ </p><p>
+ <code class="literal">FOUND</code> is a local variable within each
+ <span class="application">PL/pgSQL</span> function; any changes to it
+ affect only the current function.
+ </p></div><div class="sect2" id="PLPGSQL-STATEMENTS-NULL"><div class="titlepage"><div><div><h3 class="title">43.5.6. Doing Nothing At All</h3></div></div></div><p>
+ Sometimes a placeholder statement that does nothing is useful.
+ For example, it can indicate that one arm of an if/then/else
+ chain is deliberately empty. For this purpose, use the
+ <code class="command">NULL</code> statement:
+
+</p><pre class="synopsis">
+NULL;
+</pre><p>
+ </p><p>
+ For example, the following two fragments of code are equivalent:
+</p><pre class="programlisting">
+BEGIN
+ y := x / 0;
+EXCEPTION
+ WHEN division_by_zero THEN
+ NULL; -- ignore the error
+END;
+</pre><p>
+
+</p><pre class="programlisting">
+BEGIN
+ y := x / 0;
+EXCEPTION
+ WHEN division_by_zero THEN -- ignore the error
+END;
+</pre><p>
+ Which is preferable is a matter of taste.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In Oracle's PL/SQL, empty statement lists are not allowed, and so
+ <code class="command">NULL</code> statements are <span class="emphasis"><em>required</em></span> for situations
+ such as this. <span class="application">PL/pgSQL</span> allows you to
+ just write nothing, instead.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-expressions.html" title="43.4. Expressions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-control-structures.html" title="43.6. Control Structures">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.4. Expressions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.6. Control Structures</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-structure.html b/doc/src/sgml/html/plpgsql-structure.html
new file mode 100644
index 0000000..15e7d27
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-structure.html
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.2. Structure of PL/pgSQL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-overview.html" title="43.1. Overview" /><link rel="next" href="plpgsql-declarations.html" title="43.3. Declarations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.2. Structure of <span class="application">PL/pgSQL</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-overview.html" title="43.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-declarations.html" title="43.3. Declarations">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-STRUCTURE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.2. Structure of <span class="application">PL/pgSQL</span></h2></div></div></div><p>
+ Functions written in <span class="application">PL/pgSQL</span> are defined
+ to the server by executing <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> commands.
+ Such a command would normally look like, say,
+</p><pre class="programlisting">
+CREATE FUNCTION somefunc(integer, text) RETURNS integer
+AS '<em class="replaceable"><code>function body text</code></em>'
+LANGUAGE plpgsql;
+</pre><p>
+ The function body is simply a string literal so far as <code class="command">CREATE
+ FUNCTION</code> is concerned. It is often helpful to use dollar quoting
+ (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>) to write the function
+ body, rather than the normal single quote syntax. Without dollar quoting,
+ any single quotes or backslashes in the function body must be escaped by
+ doubling them. Almost all the examples in this chapter use dollar-quoted
+ literals for their function bodies.
+ </p><p>
+ <span class="application">PL/pgSQL</span> is a block-structured language.
+ The complete text of a function body must be a
+ <em class="firstterm">block</em>. A block is defined as:
+
+</p><pre class="synopsis">
+[<span class="optional"> &lt;&lt;<em class="replaceable"><code>label</code></em>&gt;&gt; </span>]
+[<span class="optional"> DECLARE
+ <em class="replaceable"><code>declarations</code></em> </span>]
+BEGIN
+ <em class="replaceable"><code>statements</code></em>
+END [<span class="optional"> <em class="replaceable"><code>label</code></em> </span>];
+</pre><p>
+ </p><p>
+ Each declaration and each statement within a block is terminated
+ by a semicolon. A block that appears within another block must
+ have a semicolon after <code class="literal">END</code>, as shown above;
+ however the final <code class="literal">END</code> that
+ concludes a function body does not require a semicolon.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ A common mistake is to write a semicolon immediately after
+ <code class="literal">BEGIN</code>. This is incorrect and will result in a syntax error.
+ </p></div><p>
+ A <em class="replaceable"><code>label</code></em> is only needed if you want to
+ identify the block for use
+ in an <code class="literal">EXIT</code> statement, or to qualify the names of the
+ variables declared in the block. If a label is given after
+ <code class="literal">END</code>, it must match the label at the block's beginning.
+ </p><p>
+ All key words are case-insensitive.
+ Identifiers are implicitly converted to lower case
+ unless double-quoted, just as they are in ordinary SQL commands.
+ </p><p>
+ Comments work the same way in <span class="application">PL/pgSQL</span> code as in
+ ordinary SQL. A double dash (<code class="literal">--</code>) starts a comment
+ that extends to the end of the line. A <code class="literal">/*</code> starts a
+ block comment that extends to the matching occurrence of
+ <code class="literal">*/</code>. Block comments nest.
+ </p><p>
+ Any statement in the statement section of a block
+ can be a <em class="firstterm">subblock</em>. Subblocks can be used for
+ logical grouping or to localize variables to a small group
+ of statements. Variables declared in a subblock mask any
+ similarly-named variables of outer blocks for the duration
+ of the subblock; but you can access the outer variables anyway
+ if you qualify their names with their block's label. For example:
+</p><pre class="programlisting">
+CREATE FUNCTION somefunc() RETURNS integer AS $$
+&lt;&lt; outerblock &gt;&gt;
+DECLARE
+ quantity integer := 30;
+BEGIN
+ RAISE NOTICE 'Quantity here is %', quantity; -- Prints 30
+ quantity := 50;
+ --
+ -- Create a subblock
+ --
+ DECLARE
+ quantity integer := 80;
+ BEGIN
+ RAISE NOTICE 'Quantity here is %', quantity; -- Prints 80
+ RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50
+ END;
+
+ RAISE NOTICE 'Quantity here is %', quantity; -- Prints 50
+
+ RETURN quantity;
+END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ There is actually a hidden <span class="quote">“<span class="quote">outer block</span>”</span> surrounding the body
+ of any <span class="application">PL/pgSQL</span> function. This block provides the
+ declarations of the function's parameters (if any), as well as some
+ special variables such as <code class="literal">FOUND</code> (see
+ <a class="xref" href="plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS" title="43.5.5. Obtaining the Result Status">Section 43.5.5</a>). The outer block is
+ labeled with the function's name, meaning that parameters and special
+ variables can be qualified with the function's name.
+ </p></div><p>
+ It is important not to confuse the use of
+ <code class="command">BEGIN</code>/<code class="command">END</code> for grouping statements in
+ <span class="application">PL/pgSQL</span> with the similarly-named SQL commands
+ for transaction
+ control. <span class="application">PL/pgSQL</span>'s <code class="command">BEGIN</code>/<code class="command">END</code>
+ are only for grouping; they do not start or end a transaction.
+ See <a class="xref" href="plpgsql-transactions.html" title="43.8. Transaction Management">Section 43.8</a> for information on managing
+ transactions in <span class="application">PL/pgSQL</span>.
+ Also, a block containing an <code class="literal">EXCEPTION</code> clause effectively
+ forms a subtransaction that can be rolled back without affecting the
+ outer transaction. For more about that see <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING" title="43.6.8. Trapping Errors">Section 43.6.8</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-overview.html" title="43.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-declarations.html" title="43.3. Declarations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.3. Declarations</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-transactions.html b/doc/src/sgml/html/plpgsql-transactions.html
new file mode 100644
index 0000000..3480528
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-transactions.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.8. Transaction Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-cursors.html" title="43.7. Cursors" /><link rel="next" href="plpgsql-errors-and-messages.html" title="43.9. Errors and Messages" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.8. Transaction Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-cursors.html" title="43.7. Cursors">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-errors-and-messages.html" title="43.9. Errors and Messages">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-TRANSACTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.8. Transaction Management</h2></div></div></div><p>
+ In procedures invoked by the <code class="command">CALL</code> command
+ as well as in anonymous code blocks (<code class="command">DO</code> command),
+ it is possible to end transactions using the
+ commands <code class="command">COMMIT</code> and <code class="command">ROLLBACK</code>. A new
+ transaction is started automatically after a transaction is ended using
+ these commands, so there is no separate <code class="command">START
+ TRANSACTION</code> command. (Note that <code class="command">BEGIN</code> and
+ <code class="command">END</code> have different meanings in PL/pgSQL.)
+ </p><p>
+ Here is a simple example:
+</p><pre class="programlisting">
+CREATE PROCEDURE transaction_test1()
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ FOR i IN 0..9 LOOP
+ INSERT INTO test1 (a) VALUES (i);
+ IF i % 2 = 0 THEN
+ COMMIT;
+ ELSE
+ ROLLBACK;
+ END IF;
+ END LOOP;
+END;
+$$;
+
+CALL transaction_test1();
+</pre><p>
+ </p><a id="id-1.8.8.10.4" class="indexterm"></a><p id="PLPGSQL-TRANSACTION-CHAIN">
+ A new transaction starts out with default transaction characteristics such
+ as transaction isolation level. In cases where transactions are committed
+ in a loop, it might be desirable to start new transactions automatically
+ with the same characteristics as the previous one. The commands
+ <code class="command">COMMIT AND CHAIN</code> and <code class="command">ROLLBACK AND
+ CHAIN</code> accomplish this.
+ </p><p>
+ Transaction control is only possible in <code class="command">CALL</code> or
+ <code class="command">DO</code> invocations from the top level or nested
+ <code class="command">CALL</code> or <code class="command">DO</code> invocations without any
+ other intervening command. For example, if the call stack is
+ <code class="command">CALL proc1()</code> → <code class="command">CALL proc2()</code>
+ → <code class="command">CALL proc3()</code>, then the second and third
+ procedures can perform transaction control actions. But if the call stack
+ is <code class="command">CALL proc1()</code> → <code class="command">SELECT
+ func2()</code> → <code class="command">CALL proc3()</code>, then the last
+ procedure cannot do transaction control, because of the
+ <code class="command">SELECT</code> in between.
+ </p><p>
+ Special considerations apply to cursor loops. Consider this example:
+</p><pre class="programlisting">
+CREATE PROCEDURE transaction_test2()
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ r RECORD;
+BEGIN
+ FOR r IN SELECT * FROM test2 ORDER BY x LOOP
+ INSERT INTO test1 (a) VALUES (r.x);
+ COMMIT;
+ END LOOP;
+END;
+$$;
+
+CALL transaction_test2();
+</pre><p>
+ Normally, cursors are automatically closed at transaction commit.
+ However, a cursor created as part of a loop like this is automatically
+ converted to a holdable cursor by the first <code class="command">COMMIT</code> or
+ <code class="command">ROLLBACK</code>. That means that the cursor is fully
+ evaluated at the first <code class="command">COMMIT</code> or
+ <code class="command">ROLLBACK</code> rather than row by row. The cursor is still
+ removed automatically after the loop, so this is mostly invisible to the
+ user.
+ </p><p>
+ Transaction commands are not allowed in cursor loops driven by commands
+ that are not read-only (for example <code class="command">UPDATE
+ ... RETURNING</code>).
+ </p><p>
+ A transaction cannot be ended inside a block with exception handlers.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-cursors.html" title="43.7. Cursors">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-errors-and-messages.html" title="43.9. Errors and Messages">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.7. Cursors </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.9. Errors and Messages</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql-trigger.html b/doc/src/sgml/html/plpgsql-trigger.html
new file mode 100644
index 0000000..3f51fd5
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql-trigger.html
@@ -0,0 +1,516 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>43.10. Trigger Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-errors-and-messages.html" title="43.9. Errors and Messages" /><link rel="next" href="plpgsql-implementation.html" title="43.11. PL/pgSQL under the Hood" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">43.10. Trigger Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-errors-and-messages.html" title="43.9. Errors and Messages">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><th width="60%" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-implementation.html" title="43.11. PL/pgSQL under the Hood">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPGSQL-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">43.10. Trigger Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpgsql-trigger.html#PLPGSQL-DML-TRIGGER">43.10.1. Triggers on Data Changes</a></span></dt><dt><span class="sect2"><a href="plpgsql-trigger.html#PLPGSQL-EVENT-TRIGGER">43.10.2. Triggers on Events</a></span></dt></dl></div><a id="id-1.8.8.12.2" class="indexterm"></a><p>
+ <span class="application">PL/pgSQL</span> can be used to define trigger
+ functions on data changes or database events.
+ A trigger function is created with the <code class="command">CREATE FUNCTION</code>
+ command, declaring it as a function with no arguments and a return type of
+ <code class="type">trigger</code> (for data change triggers) or
+ <code class="type">event_trigger</code> (for database event triggers).
+ Special local variables named <code class="varname">TG_<em class="replaceable"><code>something</code></em></code> are
+ automatically defined to describe the condition that triggered the call.
+ </p><div class="sect2" id="PLPGSQL-DML-TRIGGER"><div class="titlepage"><div><div><h3 class="title">43.10.1. Triggers on Data Changes</h3></div></div></div><p>
+ A <a class="link" href="triggers.html" title="Chapter 39. Triggers">data change trigger</a> is declared as a
+ function with no arguments and a return type of <code class="type">trigger</code>.
+ Note that the function must be declared with no arguments even if it
+ expects to receive some arguments specified in <code class="command">CREATE TRIGGER</code>
+ — such arguments are passed via <code class="varname">TG_ARGV</code>, as described
+ below.
+ </p><p>
+ When a <span class="application">PL/pgSQL</span> function is called as a
+ trigger, several special variables are created automatically in the
+ top-level block. They are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">NEW</code></span></dt><dd><p>
+ Data type <code class="type">RECORD</code>; variable holding the new
+ database row for <code class="command">INSERT</code>/<code class="command">UPDATE</code> operations in row-level
+ triggers. This variable is null in statement-level triggers
+ and for <code class="command">DELETE</code> operations.
+ </p></dd><dt><span class="term"><code class="varname">OLD</code></span></dt><dd><p>
+ Data type <code class="type">RECORD</code>; variable holding the old
+ database row for <code class="command">UPDATE</code>/<code class="command">DELETE</code> operations in row-level
+ triggers. This variable is null in statement-level triggers
+ and for <code class="command">INSERT</code> operations.
+ </p></dd><dt><span class="term"><code class="varname">TG_NAME</code></span></dt><dd><p>
+ Data type <code class="type">name</code>; variable that contains the name of the trigger actually
+ fired.
+ </p></dd><dt><span class="term"><code class="varname">TG_WHEN</code></span></dt><dd><p>
+ Data type <code class="type">text</code>; a string of
+ <code class="literal">BEFORE</code>, <code class="literal">AFTER</code>, or
+ <code class="literal">INSTEAD OF</code>, depending on the trigger's definition.
+ </p></dd><dt><span class="term"><code class="varname">TG_LEVEL</code></span></dt><dd><p>
+ Data type <code class="type">text</code>; a string of either
+ <code class="literal">ROW</code> or <code class="literal">STATEMENT</code>
+ depending on the trigger's definition.
+ </p></dd><dt><span class="term"><code class="varname">TG_OP</code></span></dt><dd><p>
+ Data type <code class="type">text</code>; a string of
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, or <code class="literal">TRUNCATE</code>
+ telling for which operation the trigger was fired.
+ </p></dd><dt><span class="term"><code class="varname">TG_RELID</code></span></dt><dd><p>
+ Data type <code class="type">oid</code>; the object ID of the table that caused the
+ trigger invocation.
+ </p></dd><dt><span class="term"><code class="varname">TG_RELNAME</code></span></dt><dd><p>
+ Data type <code class="type">name</code>; the name of the table that caused the trigger
+ invocation. This is now deprecated, and could disappear in a future
+ release. Use <code class="literal">TG_TABLE_NAME</code> instead.
+ </p></dd><dt><span class="term"><code class="varname">TG_TABLE_NAME</code></span></dt><dd><p>
+ Data type <code class="type">name</code>; the name of the table that
+ caused the trigger invocation.
+ </p></dd><dt><span class="term"><code class="varname">TG_TABLE_SCHEMA</code></span></dt><dd><p>
+ Data type <code class="type">name</code>; the name of the schema of the
+ table that caused the trigger invocation.
+ </p></dd><dt><span class="term"><code class="varname">TG_NARGS</code></span></dt><dd><p>
+ Data type <code class="type">integer</code>; the number of arguments given to the trigger
+ function in the <code class="command">CREATE TRIGGER</code> statement.
+ </p></dd><dt><span class="term"><code class="varname">TG_ARGV[]</code></span></dt><dd><p>
+ Data type array of <code class="type">text</code>; the arguments from
+ the <code class="command">CREATE TRIGGER</code> statement.
+ The index counts from 0. Invalid
+ indexes (less than 0 or greater than or equal to <code class="varname">tg_nargs</code>)
+ result in a null value.
+ </p></dd></dl></div><p>
+ </p><p>
+ A trigger function must return either <code class="symbol">NULL</code> or a
+ record/row value having exactly the structure of the table the
+ trigger was fired for.
+ </p><p>
+ Row-level triggers fired <code class="literal">BEFORE</code> can return null to signal the
+ trigger manager to skip the rest of the operation for this row
+ (i.e., subsequent triggers are not fired, and the
+ <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code> does not occur
+ for this row). If a nonnull
+ value is returned then the operation proceeds with that row value.
+ Returning a row value different from the original value
+ of <code class="varname">NEW</code> alters the row that will be inserted or
+ updated. Thus, if the trigger function wants the triggering
+ action to succeed normally without altering the row
+ value, <code class="varname">NEW</code> (or a value equal thereto) has to be
+ returned. To alter the row to be stored, it is possible to
+ replace single values directly in <code class="varname">NEW</code> and return the
+ modified <code class="varname">NEW</code>, or to build a complete new record/row to
+ return. In the case of a before-trigger
+ on <code class="command">DELETE</code>, the returned value has no direct
+ effect, but it has to be nonnull to allow the trigger action to
+ proceed. Note that <code class="varname">NEW</code> is null
+ in <code class="command">DELETE</code> triggers, so returning that is
+ usually not sensible. The usual idiom in <code class="command">DELETE</code>
+ triggers is to return <code class="varname">OLD</code>.
+ </p><p>
+ <code class="literal">INSTEAD OF</code> triggers (which are always row-level triggers,
+ and may only be used on views) can return null to signal that they did
+ not perform any updates, and that the rest of the operation for this
+ row should be skipped (i.e., subsequent triggers are not fired, and the
+ row is not counted in the rows-affected status for the surrounding
+ <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code>).
+ Otherwise a nonnull value should be returned, to signal
+ that the trigger performed the requested operation. For
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> operations, the return value
+ should be <code class="varname">NEW</code>, which the trigger function may modify to
+ support <code class="command">INSERT RETURNING</code> and <code class="command">UPDATE RETURNING</code>
+ (this will also affect the row value passed to any subsequent triggers,
+ or passed to a special <code class="varname">EXCLUDED</code> alias reference within
+ an <code class="command">INSERT</code> statement with an <code class="literal">ON CONFLICT DO
+ UPDATE</code> clause). For <code class="command">DELETE</code> operations, the return
+ value should be <code class="varname">OLD</code>.
+ </p><p>
+ The return value of a row-level trigger
+ fired <code class="literal">AFTER</code> or a statement-level trigger
+ fired <code class="literal">BEFORE</code> or <code class="literal">AFTER</code> is
+ always ignored; it might as well be null. However, any of these types of
+ triggers might still abort the entire operation by raising an error.
+ </p><p>
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE" title="Example 43.3. A PL/pgSQL Trigger Function">Example 43.3</a> shows an example of a
+ trigger function in <span class="application">PL/pgSQL</span>.
+ </p><div class="example" id="PLPGSQL-TRIGGER-EXAMPLE"><p class="title"><strong>Example 43.3. A <span class="application">PL/pgSQL</span> Trigger Function</strong></p><div class="example-contents"><p>
+ This example trigger ensures that any time a row is inserted or updated
+ in the table, the current user name and time are stamped into the
+ row. And it checks that an employee's name is given and that the
+ salary is a positive value.
+ </p><pre class="programlisting">
+CREATE TABLE emp (
+ empname text,
+ salary integer,
+ last_date timestamp,
+ last_user text
+);
+
+CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
+ BEGIN
+ -- Check that empname and salary are given
+ IF NEW.empname IS NULL THEN
+ RAISE EXCEPTION 'empname cannot be null';
+ END IF;
+ IF NEW.salary IS NULL THEN
+ RAISE EXCEPTION '% cannot have null salary', NEW.empname;
+ END IF;
+
+ -- Who works for us when they must pay for it?
+ IF NEW.salary &lt; 0 THEN
+ RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
+ END IF;
+
+ -- Remember who changed the payroll when
+ NEW.last_date := current_timestamp;
+ NEW.last_user := current_user;
+ RETURN NEW;
+ END;
+$emp_stamp$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
+ FOR EACH ROW EXECUTE FUNCTION emp_stamp();
+</pre></div></div><br class="example-break" /><p>
+ Another way to log changes to a table involves creating a new table that
+ holds a row for each insert, update, or delete that occurs. This approach
+ can be thought of as auditing changes to a table.
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-TRIGGER-AUDIT-EXAMPLE" title="Example 43.4. A PL/pgSQL Trigger Function for Auditing">Example 43.4</a> shows an example of an
+ audit trigger function in <span class="application">PL/pgSQL</span>.
+ </p><div class="example" id="PLPGSQL-TRIGGER-AUDIT-EXAMPLE"><p class="title"><strong>Example 43.4. A <span class="application">PL/pgSQL</span> Trigger Function for Auditing</strong></p><div class="example-contents"><p>
+ This example trigger ensures that any insert, update or delete of a row
+ in the <code class="literal">emp</code> table is recorded (i.e., audited) in the <code class="literal">emp_audit</code> table.
+ The current time and user name are stamped into the row, together with
+ the type of operation performed on it.
+ </p><pre class="programlisting">
+CREATE TABLE emp (
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE TABLE emp_audit(
+ operation char(1) NOT NULL,
+ stamp timestamp NOT NULL,
+ userid text NOT NULL,
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$
+ BEGIN
+ --
+ -- Create a row in emp_audit to reflect the operation performed on emp,
+ -- making use of the special variable TG_OP to work out the operation.
+ --
+ IF (TG_OP = 'DELETE') THEN
+ INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*;
+ ELSIF (TG_OP = 'UPDATE') THEN
+ INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;
+ END IF;
+ RETURN NULL; -- result is ignored since this is an AFTER trigger
+ END;
+$emp_audit$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_audit
+AFTER INSERT OR UPDATE OR DELETE ON emp
+ FOR EACH ROW EXECUTE FUNCTION process_emp_audit();
+</pre></div></div><br class="example-break" /><p>
+ A variation of the previous example uses a view joining the main table
+ to the audit table, to show when each entry was last modified. This
+ approach still records the full audit trail of changes to the table,
+ but also presents a simplified view of the audit trail, showing just
+ the last modified timestamp derived from the audit trail for each entry.
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-VIEW-TRIGGER-AUDIT-EXAMPLE" title="Example 43.5. A PL/pgSQL View Trigger Function for Auditing">Example 43.5</a> shows an example
+ of an audit trigger on a view in <span class="application">PL/pgSQL</span>.
+ </p><div class="example" id="PLPGSQL-VIEW-TRIGGER-AUDIT-EXAMPLE"><p class="title"><strong>Example 43.5. A <span class="application">PL/pgSQL</span> View Trigger Function for Auditing</strong></p><div class="example-contents"><p>
+ This example uses a trigger on the view to make it updatable, and
+ ensure that any insert, update or delete of a row in the view is
+ recorded (i.e., audited) in the <code class="literal">emp_audit</code> table. The current time
+ and user name are recorded, together with the type of operation
+ performed, and the view displays the last modified time of each row.
+ </p><pre class="programlisting">
+CREATE TABLE emp (
+ empname text PRIMARY KEY,
+ salary integer
+);
+
+CREATE TABLE emp_audit(
+ operation char(1) NOT NULL,
+ userid text NOT NULL,
+ empname text NOT NULL,
+ salary integer,
+ stamp timestamp NOT NULL
+);
+
+CREATE VIEW emp_view AS
+ SELECT e.empname,
+ e.salary,
+ max(ea.stamp) AS last_updated
+ FROM emp e
+ LEFT JOIN emp_audit ea ON ea.empname = e.empname
+ GROUP BY 1, 2;
+
+CREATE OR REPLACE FUNCTION update_emp_view() RETURNS TRIGGER AS $$
+ BEGIN
+ --
+ -- Perform the required operation on emp, and create a row in emp_audit
+ -- to reflect the change made to emp.
+ --
+ IF (TG_OP = 'DELETE') THEN
+ DELETE FROM emp WHERE empname = OLD.empname;
+ IF NOT FOUND THEN RETURN NULL; END IF;
+
+ OLD.last_updated = now();
+ INSERT INTO emp_audit VALUES('D', user, OLD.*);
+ RETURN OLD;
+ ELSIF (TG_OP = 'UPDATE') THEN
+ UPDATE emp SET salary = NEW.salary WHERE empname = OLD.empname;
+ IF NOT FOUND THEN RETURN NULL; END IF;
+
+ NEW.last_updated = now();
+ INSERT INTO emp_audit VALUES('U', user, NEW.*);
+ RETURN NEW;
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO emp VALUES(NEW.empname, NEW.salary);
+
+ NEW.last_updated = now();
+ INSERT INTO emp_audit VALUES('I', user, NEW.*);
+ RETURN NEW;
+ END IF;
+ END;
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_audit
+INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view
+ FOR EACH ROW EXECUTE FUNCTION update_emp_view();
+</pre></div></div><br class="example-break" /><p>
+ One use of triggers is to maintain a summary table
+ of another table. The resulting summary can be used in place of the
+ original table for certain queries — often with vastly reduced run
+ times.
+ This technique is commonly used in Data Warehousing, where the tables
+ of measured or observed data (called fact tables) might be extremely large.
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-TRIGGER-SUMMARY-EXAMPLE" title="Example 43.6. A PL/pgSQL Trigger Function for Maintaining a Summary Table">Example 43.6</a> shows an example of a
+ trigger function in <span class="application">PL/pgSQL</span> that maintains
+ a summary table for a fact table in a data warehouse.
+ </p><div class="example" id="PLPGSQL-TRIGGER-SUMMARY-EXAMPLE"><p class="title"><strong>Example 43.6. A <span class="application">PL/pgSQL</span> Trigger Function for Maintaining a Summary Table</strong></p><div class="example-contents"><p>
+ The schema detailed here is partly based on the <span class="emphasis"><em>Grocery Store
+ </em></span> example from <span class="emphasis"><em>The Data Warehouse Toolkit</em></span>
+ by Ralph Kimball.
+ </p><pre class="programlisting">
+--
+-- Main tables - time dimension and sales fact.
+--
+CREATE TABLE time_dimension (
+ time_key integer NOT NULL,
+ day_of_week integer NOT NULL,
+ day_of_month integer NOT NULL,
+ month integer NOT NULL,
+ quarter integer NOT NULL,
+ year integer NOT NULL
+);
+CREATE UNIQUE INDEX time_dimension_key ON time_dimension(time_key);
+
+CREATE TABLE sales_fact (
+ time_key integer NOT NULL,
+ product_key integer NOT NULL,
+ store_key integer NOT NULL,
+ amount_sold numeric(12,2) NOT NULL,
+ units_sold integer NOT NULL,
+ amount_cost numeric(12,2) NOT NULL
+);
+CREATE INDEX sales_fact_time ON sales_fact(time_key);
+
+--
+-- Summary table - sales by time.
+--
+CREATE TABLE sales_summary_bytime (
+ time_key integer NOT NULL,
+ amount_sold numeric(15,2) NOT NULL,
+ units_sold numeric(12) NOT NULL,
+ amount_cost numeric(15,2) NOT NULL
+);
+CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key);
+
+--
+-- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE.
+--
+CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER
+AS $maint_sales_summary_bytime$
+ DECLARE
+ delta_time_key integer;
+ delta_amount_sold numeric(15,2);
+ delta_units_sold numeric(12);
+ delta_amount_cost numeric(15,2);
+ BEGIN
+
+ -- Work out the increment/decrement amount(s).
+ IF (TG_OP = 'DELETE') THEN
+
+ delta_time_key = OLD.time_key;
+ delta_amount_sold = -1 * OLD.amount_sold;
+ delta_units_sold = -1 * OLD.units_sold;
+ delta_amount_cost = -1 * OLD.amount_cost;
+
+ ELSIF (TG_OP = 'UPDATE') THEN
+
+ -- forbid updates that change the time_key -
+ -- (probably not too onerous, as DELETE + INSERT is how most
+ -- changes will be made).
+ IF ( OLD.time_key != NEW.time_key) THEN
+ RAISE EXCEPTION 'Update of time_key : % -&gt; % not allowed',
+ OLD.time_key, NEW.time_key;
+ END IF;
+
+ delta_time_key = OLD.time_key;
+ delta_amount_sold = NEW.amount_sold - OLD.amount_sold;
+ delta_units_sold = NEW.units_sold - OLD.units_sold;
+ delta_amount_cost = NEW.amount_cost - OLD.amount_cost;
+
+ ELSIF (TG_OP = 'INSERT') THEN
+
+ delta_time_key = NEW.time_key;
+ delta_amount_sold = NEW.amount_sold;
+ delta_units_sold = NEW.units_sold;
+ delta_amount_cost = NEW.amount_cost;
+
+ END IF;
+
+
+ -- Insert or update the summary row with the new values.
+ &lt;&lt;insert_update&gt;&gt;
+ LOOP
+ UPDATE sales_summary_bytime
+ SET amount_sold = amount_sold + delta_amount_sold,
+ units_sold = units_sold + delta_units_sold,
+ amount_cost = amount_cost + delta_amount_cost
+ WHERE time_key = delta_time_key;
+
+ EXIT insert_update WHEN found;
+
+ BEGIN
+ INSERT INTO sales_summary_bytime (
+ time_key,
+ amount_sold,
+ units_sold,
+ amount_cost)
+ VALUES (
+ delta_time_key,
+ delta_amount_sold,
+ delta_units_sold,
+ delta_amount_cost
+ );
+
+ EXIT insert_update;
+
+ EXCEPTION
+ WHEN UNIQUE_VIOLATION THEN
+ -- do nothing
+ END;
+ END LOOP insert_update;
+
+ RETURN NULL;
+
+ END;
+$maint_sales_summary_bytime$ LANGUAGE plpgsql;
+
+CREATE TRIGGER maint_sales_summary_bytime
+AFTER INSERT OR UPDATE OR DELETE ON sales_fact
+ FOR EACH ROW EXECUTE FUNCTION maint_sales_summary_bytime();
+
+INSERT INTO sales_fact VALUES(1,1,1,10,3,15);
+INSERT INTO sales_fact VALUES(1,2,1,20,5,35);
+INSERT INTO sales_fact VALUES(2,2,1,40,15,135);
+INSERT INTO sales_fact VALUES(2,3,1,10,1,13);
+SELECT * FROM sales_summary_bytime;
+DELETE FROM sales_fact WHERE product_key = 1;
+SELECT * FROM sales_summary_bytime;
+UPDATE sales_fact SET units_sold = units_sold * 2;
+SELECT * FROM sales_summary_bytime;
+</pre></div></div><br class="example-break" /><p>
+ <code class="literal">AFTER</code> triggers can also make use of <em class="firstterm">transition
+ tables</em> to inspect the entire set of rows changed by the triggering
+ statement. The <code class="command">CREATE TRIGGER</code> command assigns names to one
+ or both transition tables, and then the function can refer to those names
+ as though they were read-only temporary tables.
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-TRIGGER-AUDIT-TRANSITION-EXAMPLE" title="Example 43.7. Auditing with Transition Tables">Example 43.7</a> shows an example.
+ </p><div class="example" id="PLPGSQL-TRIGGER-AUDIT-TRANSITION-EXAMPLE"><p class="title"><strong>Example 43.7. Auditing with Transition Tables</strong></p><div class="example-contents"><p>
+ This example produces the same results as
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-TRIGGER-AUDIT-EXAMPLE" title="Example 43.4. A PL/pgSQL Trigger Function for Auditing">Example 43.4</a>, but instead of using a
+ trigger that fires for every row, it uses a trigger that fires once
+ per statement, after collecting the relevant information in a transition
+ table. This can be significantly faster than the row-trigger approach
+ when the invoking statement has modified many rows. Notice that we must
+ make a separate trigger declaration for each kind of event, since the
+ <code class="literal">REFERENCING</code> clauses must be different for each case. But
+ this does not stop us from using a single trigger function if we choose.
+ (In practice, it might be better to use three separate functions and
+ avoid the run-time tests on <code class="varname">TG_OP</code>.)
+ </p><pre class="programlisting">
+CREATE TABLE emp (
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE TABLE emp_audit(
+ operation char(1) NOT NULL,
+ stamp timestamp NOT NULL,
+ userid text NOT NULL,
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$
+ BEGIN
+ --
+ -- Create rows in emp_audit to reflect the operations performed on emp,
+ -- making use of the special variable TG_OP to work out the operation.
+ --
+ IF (TG_OP = 'DELETE') THEN
+ INSERT INTO emp_audit
+ SELECT 'D', now(), user, o.* FROM old_table o;
+ ELSIF (TG_OP = 'UPDATE') THEN
+ INSERT INTO emp_audit
+ SELECT 'U', now(), user, n.* FROM new_table n;
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO emp_audit
+ SELECT 'I', now(), user, n.* FROM new_table n;
+ END IF;
+ RETURN NULL; -- result is ignored since this is an AFTER trigger
+ END;
+$emp_audit$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_audit_ins
+ AFTER INSERT ON emp
+ REFERENCING NEW TABLE AS new_table
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
+CREATE TRIGGER emp_audit_upd
+ AFTER UPDATE ON emp
+ REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
+CREATE TRIGGER emp_audit_del
+ AFTER DELETE ON emp
+ REFERENCING OLD TABLE AS old_table
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
+</pre></div></div><br class="example-break" /></div><div class="sect2" id="PLPGSQL-EVENT-TRIGGER"><div class="titlepage"><div><div><h3 class="title">43.10.2. Triggers on Events</h3></div></div></div><p>
+ <span class="application">PL/pgSQL</span> can be used to define
+ <a class="link" href="event-triggers.html" title="Chapter 40. Event Triggers">event triggers</a>.
+ <span class="productname">PostgreSQL</span> requires that a function that
+ is to be called as an event trigger must be declared as a function with
+ no arguments and a return type of <code class="literal">event_trigger</code>.
+ </p><p>
+ When a <span class="application">PL/pgSQL</span> function is called as an
+ event trigger, several special variables are created automatically
+ in the top-level block. They are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">TG_EVENT</code></span></dt><dd><p>
+ Data type <code class="type">text</code>; a string representing the event the
+ trigger is fired for.
+ </p></dd><dt><span class="term"><code class="varname">TG_TAG</code></span></dt><dd><p>
+ Data type <code class="type">text</code>; variable that contains the command tag
+ for which the trigger is fired.
+ </p></dd></dl></div><p>
+ </p><p>
+ <a class="xref" href="plpgsql-trigger.html#PLPGSQL-EVENT-TRIGGER-EXAMPLE" title="Example 43.8. A PL/pgSQL Event Trigger Function">Example 43.8</a> shows an example of an
+ event trigger function in <span class="application">PL/pgSQL</span>.
+ </p><div class="example" id="PLPGSQL-EVENT-TRIGGER-EXAMPLE"><p class="title"><strong>Example 43.8. A <span class="application">PL/pgSQL</span> Event Trigger Function</strong></p><div class="example-contents"><p>
+ This example trigger simply raises a <code class="literal">NOTICE</code> message
+ each time a supported command is executed.
+ </p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION snitch() RETURNS event_trigger AS $$
+BEGIN
+ RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch();
+</pre></div></div><br class="example-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-errors-and-messages.html" title="43.9. Errors and Messages">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-implementation.html" title="43.11. PL/pgSQL under the Hood">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.9. Errors and Messages </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.11. <span class="application">PL/pgSQL</span> under the Hood</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpgsql.html b/doc/src/sgml/html/plpgsql.html
new file mode 100644
index 0000000..c2390be
--- /dev/null
+++ b/doc/src/sgml/html/plpgsql.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 43. PL/pgSQL — SQL Procedural Language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xplang-install.html" title="42.1. Installing Procedural Languages" /><link rel="next" href="plpgsql-overview.html" title="43.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xplang-install.html" title="42.1. Installing Procedural Languages">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql-overview.html" title="43.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="PLPGSQL"><div class="titlepage"><div><div><h2 class="title">Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="plpgsql-overview.html">43.1. Overview</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-overview.html#PLPGSQL-ADVANTAGES">43.1.1. Advantages of Using <span class="application">PL/pgSQL</span></a></span></dt><dt><span class="sect2"><a href="plpgsql-overview.html#PLPGSQL-ARGS-RESULTS">43.1.2. Supported Argument and Result Data Types</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-structure.html">43.2. Structure of <span class="application">PL/pgSQL</span></a></span></dt><dt><span class="sect1"><a href="plpgsql-declarations.html">43.3. Declarations</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-PARAMETERS">43.3.1. Declaring Function Parameters</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-ALIAS">43.3.2. <code class="literal">ALIAS</code></a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-TYPE">43.3.3. Copying Types</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-ROWTYPES">43.3.4. Row Types</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-RECORDS">43.3.5. Record Types</a></span></dt><dt><span class="sect2"><a href="plpgsql-declarations.html#PLPGSQL-DECLARATION-COLLATION">43.3.6. Collation of <span class="application">PL/pgSQL</span> Variables</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-expressions.html">43.4. Expressions</a></span></dt><dt><span class="sect1"><a href="plpgsql-statements.html">43.5. Basic Statements</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-ASSIGNMENT">43.5.1. Assignment</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-GENERAL-SQL">43.5.2. Executing SQL Commands</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW">43.5.3. Executing a Command with a Single-Row Result</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-EXECUTING-DYN">43.5.4. Executing Dynamic Commands</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS">43.5.5. Obtaining the Result Status</a></span></dt><dt><span class="sect2"><a href="plpgsql-statements.html#PLPGSQL-STATEMENTS-NULL">43.5.6. Doing Nothing At All</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-control-structures.html">43.6. Control Structures</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING">43.6.1. Returning from a Function</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-RETURNING-PROCEDURE">43.6.2. Returning from a Procedure</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-CALLING-PROCEDURE">43.6.3. Calling a Procedure</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-CONDITIONALS">43.6.4. Conditionals</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-CONTROL-STRUCTURES-LOOPS">43.6.5. Simple Loops</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING">43.6.6. Looping through Query Results</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-FOREACH-ARRAY">43.6.7. Looping through Arrays</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING">43.6.8. Trapping Errors</a></span></dt><dt><span class="sect2"><a href="plpgsql-control-structures.html#PLPGSQL-CALL-STACK">43.6.9. Obtaining Execution Location Information</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-cursors.html">43.7. Cursors</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-DECLARATIONS">43.7.1. Declaring Cursor Variables</a></span></dt><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING">43.7.2. Opening Cursors</a></span></dt><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-USING">43.7.3. Using Cursors</a></span></dt><dt><span class="sect2"><a href="plpgsql-cursors.html#PLPGSQL-CURSOR-FOR-LOOP">43.7.4. Looping through a Cursor's Result</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-transactions.html">43.8. Transaction Management</a></span></dt><dt><span class="sect1"><a href="plpgsql-errors-and-messages.html">43.9. Errors and Messages</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-RAISE">43.9.1. Reporting Errors and Messages</a></span></dt><dt><span class="sect2"><a href="plpgsql-errors-and-messages.html#PLPGSQL-STATEMENTS-ASSERT">43.9.2. Checking Assertions</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-trigger.html">43.10. Trigger Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-trigger.html#PLPGSQL-DML-TRIGGER">43.10.1. Triggers on Data Changes</a></span></dt><dt><span class="sect2"><a href="plpgsql-trigger.html#PLPGSQL-EVENT-TRIGGER">43.10.2. Triggers on Events</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-implementation.html">43.11. <span class="application">PL/pgSQL</span> under the Hood</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-implementation.html#PLPGSQL-VAR-SUBST">43.11.1. Variable Substitution</a></span></dt><dt><span class="sect2"><a href="plpgsql-implementation.html#PLPGSQL-PLAN-CACHING">43.11.2. Plan Caching</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-development-tips.html">43.12. Tips for Developing in <span class="application">PL/pgSQL</span></a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-development-tips.html#PLPGSQL-QUOTE-TIPS">43.12.1. Handling of Quotation Marks</a></span></dt><dt><span class="sect2"><a href="plpgsql-development-tips.html#PLPGSQL-EXTRA-CHECKS">43.12.2. Additional Compile-Time and Run-Time Checks</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpgsql-porting.html">43.13. Porting from <span class="productname">Oracle</span> PL/SQL</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpgsql-porting.html#id-1.8.8.15.6">43.13.1. Porting Examples</a></span></dt><dt><span class="sect2"><a href="plpgsql-porting.html#PLPGSQL-PORTING-OTHER">43.13.2. Other Things to Watch For</a></span></dt><dt><span class="sect2"><a href="plpgsql-porting.html#PLPGSQL-PORTING-APPENDIX">43.13.3. Appendix</a></span></dt></dl></dd></dl></div><a id="id-1.8.8.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xplang-install.html" title="42.1. Installing Procedural Languages">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql-overview.html" title="43.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">42.1. Installing Procedural Languages </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 43.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-data.html b/doc/src/sgml/html/plpython-data.html
new file mode 100644
index 0000000..ef7179c
--- /dev/null
+++ b/doc/src/sgml/html/plpython-data.html
@@ -0,0 +1,343 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.2. Data Values</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-funcs.html" title="46.1. PL/Python Functions" /><link rel="next" href="plpython-sharing.html" title="46.3. Sharing Data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.2. Data Values</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-funcs.html" title="46.1. PL/Python Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-sharing.html" title="46.3. Sharing Data">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-DATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.2. Data Values</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.3">46.2.1. Data Type Mapping</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.4">46.2.2. Null, None</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#PLPYTHON-ARRAYS">46.2.3. Arrays, Lists</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.6">46.2.4. Composite Types</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.7">46.2.5. Set-Returning Functions</a></span></dt></dl></div><p>
+ Generally speaking, the aim of PL/Python is to provide
+ a <span class="quote">“<span class="quote">natural</span>”</span> mapping between the PostgreSQL and the
+ Python worlds. This informs the data mapping rules described
+ below.
+ </p><div class="sect2" id="id-1.8.11.10.3"><div class="titlepage"><div><div><h3 class="title">46.2.1. Data Type Mapping</h3></div></div></div><p>
+ When a PL/Python function is called, its arguments are converted from
+ their PostgreSQL data type to a corresponding Python type:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ PostgreSQL <code class="type">boolean</code> is converted to Python <code class="type">bool</code>.
+ </p></li><li class="listitem"><p>
+ PostgreSQL <code class="type">smallint</code>, <code class="type">int</code>, <code class="type">bigint</code>
+ and <code class="type">oid</code> are converted to Python <code class="type">int</code>.
+ </p></li><li class="listitem"><p>
+ PostgreSQL <code class="type">real</code> and <code class="type">double</code> are converted to
+ Python <code class="type">float</code>.
+ </p></li><li class="listitem"><p>
+ PostgreSQL <code class="type">numeric</code> is converted to
+ Python <code class="type">Decimal</code>. This type is imported from
+ the <code class="literal">cdecimal</code> package if that is available.
+ Otherwise,
+ <code class="literal">decimal.Decimal</code> from the standard library will be
+ used. <code class="literal">cdecimal</code> is significantly faster
+ than <code class="literal">decimal</code>. In Python 3.3 and up,
+ however, <code class="literal">cdecimal</code> has been integrated into the
+ standard library under the name <code class="literal">decimal</code>, so there is
+ no longer any difference.
+ </p></li><li class="listitem"><p>
+ PostgreSQL <code class="type">bytea</code> is converted to Python <code class="type">bytes</code>.
+ </p></li><li class="listitem"><p>
+ All other data types, including the PostgreSQL character string types,
+ are converted to a Python <code class="type">str</code> (in Unicode like all Python
+ strings).
+ </p></li><li class="listitem"><p>
+ For nonscalar data types, see below.
+ </p></li></ul></div><p>
+ </p><p>
+ When a PL/Python function returns, its return value is converted to the
+ function's declared PostgreSQL return data type as follows:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ When the PostgreSQL return type is <code class="type">boolean</code>, the
+ return value will be evaluated for truth according to the
+ <span class="emphasis"><em>Python</em></span> rules. That is, 0 and empty string
+ are false, but notably <code class="literal">'f'</code> is true.
+ </p></li><li class="listitem"><p>
+ When the PostgreSQL return type is <code class="type">bytea</code>, the return value
+ will be converted to Python <code class="type">bytes</code> using the respective
+ Python built-ins, with the result being converted to
+ <code class="type">bytea</code>.
+ </p></li><li class="listitem"><p>
+ For all other PostgreSQL return types, the return value is converted
+ to a string using the Python built-in <code class="literal">str</code>, and the
+ result is passed to the input function of the PostgreSQL data type.
+ (If the Python value is a <code class="type">float</code>, it is converted using
+ the <code class="literal">repr</code> built-in instead of <code class="literal">str</code>, to
+ avoid loss of precision.)
+ </p><p>
+ Strings are automatically converted to the PostgreSQL server encoding
+ when they are passed to PostgreSQL.
+ </p></li><li class="listitem"><p>
+ For nonscalar data types, see below.
+ </p></li></ul></div><p>
+
+ Note that logical mismatches between the declared PostgreSQL
+ return type and the Python data type of the actual return object
+ are not flagged; the value will be converted in any case.
+ </p></div><div class="sect2" id="id-1.8.11.10.4"><div class="titlepage"><div><div><h3 class="title">46.2.2. Null, None</h3></div></div></div><p>
+ If an SQL null value<a id="id-1.8.11.10.4.2.1" class="indexterm"></a> is passed to a
+ function, the argument value will appear as <code class="symbol">None</code> in
+ Python. For example, the function definition of <code class="function">pymax</code>
+ shown in <a class="xref" href="plpython-funcs.html" title="46.1. PL/Python Functions">Section 46.1</a> will return the wrong answer for null
+ inputs. We could add <code class="literal">STRICT</code> to the function definition
+ to make <span class="productname">PostgreSQL</span> do something more reasonable:
+ if a null value is passed, the function will not be called at all,
+ but will just return a null result automatically. Alternatively,
+ we could check for null inputs in the function body:
+
+</p><pre class="programlisting">
+CREATE FUNCTION pymax (a integer, b integer)
+ RETURNS integer
+AS $$
+ if (a is None) or (b is None):
+ return None
+ if a &gt; b:
+ return a
+ return b
+$$ LANGUAGE plpython3u;
+</pre><p>
+
+ As shown above, to return an SQL null value from a PL/Python
+ function, return the value <code class="symbol">None</code>. This can be done whether the
+ function is strict or not.
+ </p></div><div class="sect2" id="PLPYTHON-ARRAYS"><div class="titlepage"><div><div><h3 class="title">46.2.3. Arrays, Lists</h3></div></div></div><p>
+ SQL array values are passed into PL/Python as a Python list. To
+ return an SQL array value out of a PL/Python function, return a
+ Python list:
+
+</p><pre class="programlisting">
+CREATE FUNCTION return_arr()
+ RETURNS int[]
+AS $$
+return [1, 2, 3, 4, 5]
+$$ LANGUAGE plpython3u;
+
+SELECT return_arr();
+ return_arr
+-------------
+ {1,2,3,4,5}
+(1 row)
+</pre><p>
+
+ Multidimensional arrays are passed into PL/Python as nested Python lists.
+ A 2-dimensional array is a list of lists, for example. When returning
+ a multi-dimensional SQL array out of a PL/Python function, the inner
+ lists at each level must all be of the same size. For example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM test_type_conversion_array_int4(ARRAY[[1,2,3],[4,5,6]]);
+INFO: ([[1, 2, 3], [4, 5, 6]], &lt;type 'list'&gt;)
+ test_type_conversion_array_int4
+---------------------------------
+ {{1,2,3},{4,5,6}}
+(1 row)
+</pre><p>
+
+ Other Python sequences, like tuples, are also accepted for
+ backwards-compatibility with PostgreSQL versions 9.6 and below, when
+ multi-dimensional arrays were not supported. However, they are always
+ treated as one-dimensional arrays, because they are ambiguous with
+ composite types. For the same reason, when a composite type is used in a
+ multi-dimensional array, it must be represented by a tuple, rather than a
+ list.
+ </p><p>
+ Note that in Python, strings are sequences, which can have
+ undesirable effects that might be familiar to Python programmers:
+
+</p><pre class="programlisting">
+CREATE FUNCTION return_str_arr()
+ RETURNS varchar[]
+AS $$
+return "hello"
+$$ LANGUAGE plpython3u;
+
+SELECT return_str_arr();
+ return_str_arr
+----------------
+ {h,e,l,l,o}
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.8.11.10.6"><div class="titlepage"><div><div><h3 class="title">46.2.4. Composite Types</h3></div></div></div><p>
+ Composite-type arguments are passed to the function as Python mappings. The
+ element names of the mapping are the attribute names of the composite type.
+ If an attribute in the passed row has the null value, it has the value
+ <code class="symbol">None</code> in the mapping. Here is an example:
+
+</p><pre class="programlisting">
+CREATE TABLE employee (
+ name text,
+ salary integer,
+ age integer
+);
+
+CREATE FUNCTION overpaid (e employee)
+ RETURNS boolean
+AS $$
+ if e["salary"] &gt; 200000:
+ return True
+ if (e["age"] &lt; 30) and (e["salary"] &gt; 100000):
+ return True
+ return False
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p><p>
+ There are multiple ways to return row or composite types from a Python
+ function. The following examples assume we have:
+
+</p><pre class="programlisting">
+CREATE TYPE named_value AS (
+ name text,
+ value integer
+);
+</pre><p>
+
+ A composite result can be returned as a:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Sequence type (a tuple or list, but not a set because
+ it is not indexable)</span></dt><dd><p>
+ Returned sequence objects must have the same number of items as the
+ composite result type has fields. The item with index 0 is assigned to
+ the first field of the composite type, 1 to the second and so on. For
+ example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION make_pair (name text, value integer)
+ RETURNS named_value
+AS $$
+ return ( name, value )
+ # or alternatively, as list: return [ name, value ]
+$$ LANGUAGE plpython3u;
+</pre><p>
+
+ To return an SQL null for any column, insert <code class="symbol">None</code> at
+ the corresponding position.
+ </p><p>
+ When an array of composite types is returned, it cannot be returned as a list,
+ because it is ambiguous whether the Python list represents a composite type,
+ or another array dimension.
+ </p></dd><dt><span class="term">Mapping (dictionary)</span></dt><dd><p>
+ The value for each result type column is retrieved from the mapping
+ with the column name as key. Example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION make_pair (name text, value integer)
+ RETURNS named_value
+AS $$
+ return { "name": name, "value": value }
+$$ LANGUAGE plpython3u;
+</pre><p>
+
+ Any extra dictionary key/value pairs are ignored. Missing keys are
+ treated as errors.
+ To return an SQL null value for any column, insert
+ <code class="symbol">None</code> with the corresponding column name as the key.
+ </p></dd><dt><span class="term">Object (any object providing method <code class="literal">__getattr__</code>)</span></dt><dd><p>
+ This works the same as a mapping.
+ Example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION make_pair (name text, value integer)
+ RETURNS named_value
+AS $$
+ class named_value:
+ def __init__ (self, n, v):
+ self.name = n
+ self.value = v
+ return named_value(name, value)
+
+ # or simply
+ class nv: pass
+ nv.name = name
+ nv.value = value
+ return nv
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p></dd></dl></div><p>
+ </p><p>
+ Functions with <code class="literal">OUT</code> parameters are also supported. For example:
+</p><pre class="programlisting">
+CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$
+return (1, 2)
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM multiout_simple();
+</pre><p>
+ </p><p>
+ Output parameters of procedures are passed back the same way. For example:
+</p><pre class="programlisting">
+CREATE PROCEDURE python_triple(INOUT a integer, INOUT b integer) AS $$
+return (a * 3, b * 3)
+$$ LANGUAGE plpython3u;
+
+CALL python_triple(5, 10);
+</pre><p>
+ </p></div><div class="sect2" id="id-1.8.11.10.7"><div class="titlepage"><div><div><h3 class="title">46.2.5. Set-Returning Functions</h3></div></div></div><p>
+ A <span class="application">PL/Python</span> function can also return sets of
+ scalar or composite types. There are several ways to achieve this because
+ the returned object is internally turned into an iterator. The following
+ examples assume we have composite type:
+
+</p><pre class="programlisting">
+CREATE TYPE greeting AS (
+ how text,
+ who text
+);
+</pre><p>
+
+ A set result can be returned from a:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Sequence type (tuple, list, set)</span></dt><dd><p>
+</p><pre class="programlisting">
+CREATE FUNCTION greet (how text)
+ RETURNS SETOF greeting
+AS $$
+ # return tuple containing lists as composite types
+ # all other combinations work also
+ return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] )
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p></dd><dt><span class="term">Iterator (any object providing <code class="symbol">__iter__</code> and
+ <code class="symbol">next</code> methods)</span></dt><dd><p>
+</p><pre class="programlisting">
+CREATE FUNCTION greet (how text)
+ RETURNS SETOF greeting
+AS $$
+ class producer:
+ def __init__ (self, how, who):
+ self.how = how
+ self.who = who
+ self.ndx = -1
+
+ def __iter__ (self):
+ return self
+
+ def next (self):
+ self.ndx += 1
+ if self.ndx == len(self.who):
+ raise StopIteration
+ return ( self.how, self.who[self.ndx] )
+
+ return producer(how, [ "World", "PostgreSQL", "PL/Python" ])
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p></dd><dt><span class="term">Generator (<code class="literal">yield</code>)</span></dt><dd><p>
+</p><pre class="programlisting">
+CREATE FUNCTION greet (how text)
+ RETURNS SETOF greeting
+AS $$
+ for who in [ "World", "PostgreSQL", "PL/Python" ]:
+ yield ( how, who )
+$$ LANGUAGE plpython3u;
+</pre><p>
+
+ </p></dd></dl></div><p>
+ </p><p>
+ Set-returning functions with <code class="literal">OUT</code> parameters
+ (using <code class="literal">RETURNS SETOF record</code>) are also
+ supported. For example:
+</p><pre class="programlisting">
+CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$
+return [(1, 2)] * n
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM multiout_simple_setof(3);
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-funcs.html" title="46.1. PL/Python Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-sharing.html" title="46.3. Sharing Data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.1. PL/Python Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.3. Sharing Data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-database.html b/doc/src/sgml/html/plpython-database.html
new file mode 100644
index 0000000..8fa0507
--- /dev/null
+++ b/doc/src/sgml/html/plpython-database.html
@@ -0,0 +1,238 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.6. Database Access</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-trigger.html" title="46.5. Trigger Functions" /><link rel="next" href="plpython-subtransaction.html" title="46.7. Explicit Subtransactions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.6. Database Access</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-trigger.html" title="46.5. Trigger Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-subtransaction.html" title="46.7. Explicit Subtransactions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-DATABASE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.6. Database Access</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpython-database.html#id-1.8.11.14.3">46.6.1. Database Access Functions</a></span></dt><dt><span class="sect2"><a href="plpython-database.html#PLPYTHON-TRAPPING">46.6.2. Trapping Errors</a></span></dt></dl></div><p>
+ The PL/Python language module automatically imports a Python module
+ called <code class="literal">plpy</code>. The functions and constants in
+ this module are available to you in the Python code as
+ <code class="literal">plpy.<em class="replaceable"><code>foo</code></em></code>.
+ </p><div class="sect2" id="id-1.8.11.14.3"><div class="titlepage"><div><div><h3 class="title">46.6.1. Database Access Functions</h3></div></div></div><p>
+ The <code class="literal">plpy</code> module provides several functions to execute
+ database commands:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">plpy.<code class="function">execute</code>(<em class="replaceable"><code>query</code></em> [, <em class="replaceable"><code>limit</code></em>])</code></span></dt><dd><p>
+ Calling <code class="function">plpy.execute</code> with a query string and an
+ optional row limit argument causes that query to be run and the result to
+ be returned in a result object.
+ </p><p>
+ If <em class="replaceable"><code>limit</code></em> is specified and is greater than
+ zero, then <code class="function">plpy.execute</code> retrieves at
+ most <em class="replaceable"><code>limit</code></em> rows, much as if the query
+ included a <code class="literal">LIMIT</code>
+ clause. Omitting <em class="replaceable"><code>limit</code></em> or specifying it as
+ zero results in no row limit.
+ </p><p>
+ The result object emulates a list or dictionary object. The result
+ object can be accessed by row number and column name. For example:
+</p><pre class="programlisting">
+rv = plpy.execute("SELECT * FROM my_table", 5)
+</pre><p>
+ returns up to 5 rows from <code class="literal">my_table</code>. If
+ <code class="literal">my_table</code> has a column
+ <code class="literal">my_column</code>, it would be accessed as:
+</p><pre class="programlisting">
+foo = rv[i]["my_column"]
+</pre><p>
+ The number of rows returned can be obtained using the built-in
+ <code class="function">len</code> function.
+ </p><p>
+ The result object has these additional methods:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal"><code class="function">nrows</code>()</code></span></dt><dd><p>
+ Returns the number of rows processed by the command. Note that this
+ is not necessarily the same as the number of rows returned. For
+ example, an <code class="command">UPDATE</code> command will set this value but
+ won't return any rows (unless <code class="literal">RETURNING</code> is used).
+ </p></dd><dt><span class="term"><code class="literal"><code class="function">status</code>()</code></span></dt><dd><p>
+ The <code class="function">SPI_execute()</code> return value.
+ </p></dd><dt><span class="term"><code class="literal"><code class="function">colnames</code>()</code><br /></span><span class="term"><code class="literal"><code class="function">coltypes</code>()</code><br /></span><span class="term"><code class="literal"><code class="function">coltypmods</code>()</code></span></dt><dd><p>
+ Return a list of column names, list of column type OIDs, and list of
+ type-specific type modifiers for the columns, respectively.
+ </p><p>
+ These methods raise an exception when called on a result object from
+ a command that did not produce a result set, e.g.,
+ <code class="command">UPDATE</code> without <code class="literal">RETURNING</code>, or
+ <code class="command">DROP TABLE</code>. But it is OK to use these methods on
+ a result set containing zero rows.
+ </p></dd><dt><span class="term"><code class="literal"><code class="function">__str__</code>()</code></span></dt><dd><p>
+ The standard <code class="literal">__str__</code> method is defined so that it
+ is possible for example to debug query execution results
+ using <code class="literal">plpy.debug(rv)</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ The result object can be modified.
+ </p><p>
+ Note that calling <code class="literal">plpy.execute</code> will cause the entire
+ result set to be read into memory. Only use that function when you are
+ sure that the result set will be relatively small. If you don't want to
+ risk excessive memory usage when fetching large results,
+ use <code class="literal">plpy.cursor</code> rather
+ than <code class="literal">plpy.execute</code>.
+ </p></dd><dt><span class="term"><code class="literal">plpy.<code class="function">prepare</code>(<em class="replaceable"><code>query</code></em> [, <em class="replaceable"><code>argtypes</code></em>])</code><br /></span><span class="term"><code class="literal">plpy.<code class="function">execute</code>(<em class="replaceable"><code>plan</code></em> [, <em class="replaceable"><code>arguments</code></em> [, <em class="replaceable"><code>limit</code></em>]])</code></span></dt><dd><p>
+ <a id="id-1.8.11.14.3.3.2.3.1.1" class="indexterm"></a>
+ <code class="function">plpy.prepare</code> prepares the execution plan for a
+ query. It is called with a query string and a list of parameter types,
+ if you have parameter references in the query. For example:
+</p><pre class="programlisting">
+plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", ["text"])
+</pre><p>
+ <code class="literal">text</code> is the type of the variable you will be passing
+ for <code class="literal">$1</code>. The second argument is optional if you don't
+ want to pass any parameters to the query.
+ </p><p>
+ After preparing a statement, you use a variant of the
+ function <code class="function">plpy.execute</code> to run it:
+</p><pre class="programlisting">
+rv = plpy.execute(plan, ["name"], 5)
+</pre><p>
+ Pass the plan as the first argument (instead of the query string), and a
+ list of values to substitute into the query as the second argument. The
+ second argument is optional if the query does not expect any parameters.
+ The third argument is the optional row limit as before.
+ </p><p>
+ Alternatively, you can call the <code class="function">execute</code> method on
+ the plan object:
+</p><pre class="programlisting">
+rv = plan.execute(["name"], 5)
+</pre><p>
+ </p><p>
+ Query parameters and result row fields are converted between PostgreSQL
+ and Python data types as described in <a class="xref" href="plpython-data.html" title="46.2. Data Values">Section 46.2</a>.
+ </p><p>
+ When you prepare a plan using the PL/Python module it is automatically
+ saved. Read the SPI documentation (<a class="xref" href="spi.html" title="Chapter 47. Server Programming Interface">Chapter 47</a>) for a
+ description of what this means. In order to make effective use of this
+ across function calls one needs to use one of the persistent storage
+ dictionaries <code class="literal">SD</code> or <code class="literal">GD</code> (see
+ <a class="xref" href="plpython-sharing.html" title="46.3. Sharing Data">Section 46.3</a>). For example:
+</p><pre class="programlisting">
+CREATE FUNCTION usesavedplan() RETURNS trigger AS $$
+ if "plan" in SD:
+ plan = SD["plan"]
+ else:
+ plan = plpy.prepare("SELECT 1")
+ SD["plan"] = plan
+ # rest of function
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">plpy.<code class="function">cursor</code>(<em class="replaceable"><code>query</code></em>)</code><br /></span><span class="term"><code class="literal">plpy.<code class="function">cursor</code>(<em class="replaceable"><code>plan</code></em> [, <em class="replaceable"><code>arguments</code></em>])</code></span></dt><dd><p>
+ The <code class="literal">plpy.cursor</code> function accepts the same arguments
+ as <code class="literal">plpy.execute</code> (except for the row limit) and returns
+ a cursor object, which allows you to process large result sets in smaller
+ chunks. As with <code class="literal">plpy.execute</code>, either a query string
+ or a plan object along with a list of arguments can be used, or
+ the <code class="function">cursor</code> function can be called as a method of
+ the plan object.
+ </p><p>
+ The cursor object provides a <code class="literal">fetch</code> method that accepts
+ an integer parameter and returns a result object. Each time you
+ call <code class="literal">fetch</code>, the returned object will contain the next
+ batch of rows, never larger than the parameter value. Once all rows are
+ exhausted, <code class="literal">fetch</code> starts returning an empty result
+ object. Cursor objects also provide an
+ <a class="ulink" href="https://docs.python.org/library/stdtypes.html#iterator-types" target="_top">iterator
+ interface</a>, yielding one row at a time until all rows are
+ exhausted. Data fetched that way is not returned as result objects, but
+ rather as dictionaries, each dictionary corresponding to a single result
+ row.
+ </p><p>
+ An example of two ways of processing data from a large table is:
+</p><pre class="programlisting">
+CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$
+odd = 0
+for row in plpy.cursor("select num from largetable"):
+ if row['num'] % 2:
+ odd += 1
+return odd
+$$ LANGUAGE plpython3u;
+
+CREATE FUNCTION count_odd_fetch(batch_size integer) RETURNS integer AS $$
+odd = 0
+cursor = plpy.cursor("select num from largetable")
+while True:
+ rows = cursor.fetch(batch_size)
+ if not rows:
+ break
+ for row in rows:
+ if row['num'] % 2:
+ odd += 1
+return odd
+$$ LANGUAGE plpython3u;
+
+CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$
+odd = 0
+plan = plpy.prepare("select num from largetable where num % $1 &lt;&gt; 0", ["integer"])
+rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2]))
+
+return len(rows)
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p><p>
+ Cursors are automatically disposed of. But if you want to explicitly
+ release all resources held by a cursor, use the <code class="literal">close</code>
+ method. Once closed, a cursor cannot be fetched from anymore.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Do not confuse objects created by <code class="literal">plpy.cursor</code> with
+ DB-API cursors as defined by
+ the <a class="ulink" href="https://www.python.org/dev/peps/pep-0249/" target="_top">Python
+ Database API specification</a>. They don't have anything in common
+ except for the name.
+ </p></div></dd></dl></div></div><div class="sect2" id="PLPYTHON-TRAPPING"><div class="titlepage"><div><div><h3 class="title">46.6.2. Trapping Errors</h3></div></div></div><p>
+ Functions accessing the database might encounter errors, which
+ will cause them to abort and raise an exception. Both
+ <code class="function">plpy.execute</code> and
+ <code class="function">plpy.prepare</code> can raise an instance of a subclass of
+ <code class="literal">plpy.SPIError</code>, which by default will terminate
+ the function. This error can be handled just like any other
+ Python exception, by using the <code class="literal">try/except</code>
+ construct. For example:
+</p><pre class="programlisting">
+CREATE FUNCTION try_adding_joe() RETURNS text AS $$
+ try:
+ plpy.execute("INSERT INTO users(username) VALUES ('joe')")
+ except plpy.SPIError:
+ return "something went wrong"
+ else:
+ return "Joe added"
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p><p>
+ The actual class of the exception being raised corresponds to the
+ specific condition that caused the error. Refer
+ to <a class="xref" href="errcodes-appendix.html#ERRCODES-TABLE" title="Table A.1. PostgreSQL Error Codes">Table A.1</a> for a list of possible
+ conditions. The module
+ <code class="literal">plpy.spiexceptions</code> defines an exception class
+ for each <span class="productname">PostgreSQL</span> condition, deriving
+ their names from the condition name. For
+ instance, <code class="literal">division_by_zero</code>
+ becomes <code class="literal">DivisionByZero</code>, <code class="literal">unique_violation</code>
+ becomes <code class="literal">UniqueViolation</code>, <code class="literal">fdw_error</code>
+ becomes <code class="literal">FdwError</code>, and so on. Each of these
+ exception classes inherits from <code class="literal">SPIError</code>. This
+ separation makes it easier to handle specific errors, for
+ instance:
+</p><pre class="programlisting">
+CREATE FUNCTION insert_fraction(numerator int, denominator int) RETURNS text AS $$
+from plpy import spiexceptions
+try:
+ plan = plpy.prepare("INSERT INTO fractions (frac) VALUES ($1 / $2)", ["int", "int"])
+ plpy.execute(plan, [numerator, denominator])
+except spiexceptions.DivisionByZero:
+ return "denominator cannot equal zero"
+except spiexceptions.UniqueViolation:
+ return "already have that fraction"
+except plpy.SPIError as e:
+ return "other error, SQLSTATE %s" % e.sqlstate
+else:
+ return "fraction inserted"
+$$ LANGUAGE plpython3u;
+</pre><p>
+ Note that because all exceptions from
+ the <code class="literal">plpy.spiexceptions</code> module inherit
+ from <code class="literal">SPIError</code>, an <code class="literal">except</code>
+ clause handling it will catch any database access error.
+ </p><p>
+ As an alternative way of handling different error conditions, you
+ can catch the <code class="literal">SPIError</code> exception and determine
+ the specific error condition inside the <code class="literal">except</code>
+ block by looking at the <code class="literal">sqlstate</code> attribute of
+ the exception object. This attribute is a string value containing
+ the <span class="quote">“<span class="quote">SQLSTATE</span>”</span> error code. This approach provides
+ approximately the same functionality
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-trigger.html" title="46.5. Trigger Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-subtransaction.html" title="46.7. Explicit Subtransactions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.5. Trigger Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.7. Explicit Subtransactions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-do.html b/doc/src/sgml/html/plpython-do.html
new file mode 100644
index 0000000..963951b
--- /dev/null
+++ b/doc/src/sgml/html/plpython-do.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.4. Anonymous Code Blocks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-sharing.html" title="46.3. Sharing Data" /><link rel="next" href="plpython-trigger.html" title="46.5. Trigger Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.4. Anonymous Code Blocks</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-sharing.html" title="46.3. Sharing Data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-trigger.html" title="46.5. Trigger Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-DO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.4. Anonymous Code Blocks</h2></div></div></div><p>
+ PL/Python also supports anonymous code blocks called with the
+ <a class="xref" href="sql-do.html" title="DO"><span class="refentrytitle">DO</span></a> statement:
+
+</p><pre class="programlisting">
+DO $$
+ # PL/Python code
+$$ LANGUAGE plpython3u;
+</pre><p>
+
+ An anonymous code block receives no arguments, and whatever value it
+ might return is discarded. Otherwise it behaves just like a function.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-sharing.html" title="46.3. Sharing Data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-trigger.html" title="46.5. Trigger Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.3. Sharing Data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.5. Trigger Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-envar.html b/doc/src/sgml/html/plpython-envar.html
new file mode 100644
index 0000000..6c66017
--- /dev/null
+++ b/doc/src/sgml/html/plpython-envar.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.11. Environment Variables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-python23.html" title="46.10. Python 2 vs. Python 3" /><link rel="next" href="spi.html" title="Chapter 47. Server Programming Interface" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.11. Environment Variables</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-python23.html" title="46.10. Python 2 vs. Python 3">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi.html" title="Chapter 47. Server Programming Interface">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-ENVAR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.11. Environment Variables</h2></div></div></div><p>
+ Some of the environment variables that are accepted by the Python
+ interpreter can also be used to affect PL/Python behavior. They
+ would need to be set in the environment of the main PostgreSQL
+ server process, for example in a start script. The available
+ environment variables depend on the version of Python; see the
+ Python documentation for details. At the time of this writing, the
+ following environment variables have an affect on PL/Python,
+ assuming an adequate Python version:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="envar">PYTHONHOME</code></p></li><li class="listitem"><p><code class="envar">PYTHONPATH</code></p></li><li class="listitem"><p><code class="envar">PYTHONY2K</code></p></li><li class="listitem"><p><code class="envar">PYTHONOPTIMIZE</code></p></li><li class="listitem"><p><code class="envar">PYTHONDEBUG</code></p></li><li class="listitem"><p><code class="envar">PYTHONVERBOSE</code></p></li><li class="listitem"><p><code class="envar">PYTHONCASEOK</code></p></li><li class="listitem"><p><code class="envar">PYTHONDONTWRITEBYTECODE</code></p></li><li class="listitem"><p><code class="envar">PYTHONIOENCODING</code></p></li><li class="listitem"><p><code class="envar">PYTHONUSERBASE</code></p></li><li class="listitem"><p><code class="envar">PYTHONHASHSEED</code></p></li></ul></div><p>
+
+ (It appears to be a Python implementation detail beyond the control
+ of PL/Python that some of the environment variables listed on
+ the <code class="command">python</code> man page are only effective in a
+ command-line interpreter and not an embedded Python interpreter.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-python23.html" title="46.10. Python 2 vs. Python 3">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi.html" title="Chapter 47. Server Programming Interface">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.10. Python 2 vs. Python 3 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 47. Server Programming Interface</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-funcs.html b/doc/src/sgml/html/plpython-funcs.html
new file mode 100644
index 0000000..97c9e3f
--- /dev/null
+++ b/doc/src/sgml/html/plpython-funcs.html
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.1. PL/Python Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language" /><link rel="next" href="plpython-data.html" title="46.2. Data Values" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.1. PL/Python Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-data.html" title="46.2. Data Values">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-FUNCS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.1. PL/Python Functions</h2></div></div></div><p>
+ Functions in PL/Python are declared via the
+ standard <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> syntax:
+
+</p><pre class="programlisting">
+CREATE FUNCTION <em class="replaceable"><code>funcname</code></em> (<em class="replaceable"><code>argument-list</code></em>)
+ RETURNS <em class="replaceable"><code>return-type</code></em>
+AS $$
+ # PL/Python function body
+$$ LANGUAGE plpython3u;
+</pre><p>
+ </p><p>
+ The body of a function is simply a Python script. When the function
+ is called, its arguments are passed as elements of the list
+ <code class="varname">args</code>; named arguments are also passed as
+ ordinary variables to the Python script. Use of named arguments is
+ usually more readable. The result is returned from the Python code
+ in the usual way, with <code class="literal">return</code> or
+ <code class="literal">yield</code> (in case of a result-set statement). If
+ you do not provide a return value, Python returns the default
+ <code class="symbol">None</code>. <span class="application">PL/Python</span> translates
+ Python's <code class="symbol">None</code> into the SQL null value. In a procedure,
+ the result from the Python code must be <code class="symbol">None</code> (typically
+ achieved by ending the procedure without a <code class="literal">return</code>
+ statement or by using a <code class="literal">return</code> statement without
+ argument); otherwise, an error will be raised.
+ </p><p>
+ For example, a function to return the greater of two integers can be
+ defined as:
+
+</p><pre class="programlisting">
+CREATE FUNCTION pymax (a integer, b integer)
+ RETURNS integer
+AS $$
+ if a &gt; b:
+ return a
+ return b
+$$ LANGUAGE plpython3u;
+</pre><p>
+
+ The Python code that is given as the body of the function definition
+ is transformed into a Python function. For example, the above results in:
+
+</p><pre class="programlisting">
+def __plpython_procedure_pymax_23456():
+ if a &gt; b:
+ return a
+ return b
+</pre><p>
+
+ assuming that 23456 is the OID assigned to the function by
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ The arguments are set as global variables. Because of the scoping
+ rules of Python, this has the subtle consequence that an argument
+ variable cannot be reassigned inside the function to the value of
+ an expression that involves the variable name itself, unless the
+ variable is redeclared as global in the block. For example, the
+ following won't work:
+</p><pre class="programlisting">
+CREATE FUNCTION pystrip(x text)
+ RETURNS text
+AS $$
+ x = x.strip() # error
+ return x
+$$ LANGUAGE plpython3u;
+</pre><p>
+ because assigning to <code class="varname">x</code>
+ makes <code class="varname">x</code> a local variable for the entire block,
+ and so the <code class="varname">x</code> on the right-hand side of the
+ assignment refers to a not-yet-assigned local
+ variable <code class="varname">x</code>, not the PL/Python function
+ parameter. Using the <code class="literal">global</code> statement, this can
+ be made to work:
+</p><pre class="programlisting">
+CREATE FUNCTION pystrip(x text)
+ RETURNS text
+AS $$
+ global x
+ x = x.strip() # ok now
+ return x
+$$ LANGUAGE plpython3u;
+</pre><p>
+ But it is advisable not to rely on this implementation detail of
+ PL/Python. It is better to treat the function parameters as
+ read-only.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-data.html" title="46.2. Data Values">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 46. PL/Python — Python Procedural Language </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.2. Data Values</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-python23.html b/doc/src/sgml/html/plpython-python23.html
new file mode 100644
index 0000000..ed5b4a4
--- /dev/null
+++ b/doc/src/sgml/html/plpython-python23.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.10. Python 2 vs. Python 3</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-util.html" title="46.9. Utility Functions" /><link rel="next" href="plpython-envar.html" title="46.11. Environment Variables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.10. Python 2 vs. Python 3</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-util.html" title="46.9. Utility Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-envar.html" title="46.11. Environment Variables">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-PYTHON23"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.10. Python 2 vs. Python 3</h2></div></div></div><p>
+ PL/Python supports only Python 3. Past versions of
+ <span class="productname">PostgreSQL</span> supported Python 2, using the
+ <code class="literal">plpythonu</code> and <code class="literal">plpython2u</code> language
+ names.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-util.html" title="46.9. Utility Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-envar.html" title="46.11. Environment Variables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.9. Utility Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.11. Environment Variables</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-sharing.html b/doc/src/sgml/html/plpython-sharing.html
new file mode 100644
index 0000000..aa383fb
--- /dev/null
+++ b/doc/src/sgml/html/plpython-sharing.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.3. Sharing Data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-data.html" title="46.2. Data Values" /><link rel="next" href="plpython-do.html" title="46.4. Anonymous Code Blocks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.3. Sharing Data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-data.html" title="46.2. Data Values">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-do.html" title="46.4. Anonymous Code Blocks">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-SHARING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.3. Sharing Data</h2></div></div></div><p>
+ The global dictionary <code class="varname">SD</code> is available to store
+ private data between repeated calls to the same function.
+ The global dictionary <code class="varname">GD</code> is public data,
+ that is available to all Python functions within a session; use with
+ care.<a id="id-1.8.11.11.2.3" class="indexterm"></a>
+ </p><p>
+ Each function gets its own execution environment in the
+ Python interpreter, so that global data and function arguments from
+ <code class="function">myfunc</code> are not available to
+ <code class="function">myfunc2</code>. The exception is the data in the
+ <code class="varname">GD</code> dictionary, as mentioned above.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-data.html" title="46.2. Data Values">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-do.html" title="46.4. Anonymous Code Blocks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.2. Data Values </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.4. Anonymous Code Blocks</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-subtransaction.html b/doc/src/sgml/html/plpython-subtransaction.html
new file mode 100644
index 0000000..0ac4ab2
--- /dev/null
+++ b/doc/src/sgml/html/plpython-subtransaction.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.7. Explicit Subtransactions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-database.html" title="46.6. Database Access" /><link rel="next" href="plpython-transactions.html" title="46.8. Transaction Management" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.7. Explicit Subtransactions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-database.html" title="46.6. Database Access">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-transactions.html" title="46.8. Transaction Management">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-SUBTRANSACTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.7. Explicit Subtransactions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="plpython-subtransaction.html#id-1.8.11.15.3">46.7.1. Subtransaction Context Managers</a></span></dt></dl></div><p>
+ Recovering from errors caused by database access as described in
+ <a class="xref" href="plpython-database.html#PLPYTHON-TRAPPING" title="46.6.2. Trapping Errors">Section 46.6.2</a> can lead to an undesirable
+ situation where some operations succeed before one of them fails,
+ and after recovering from that error the data is left in an
+ inconsistent state. PL/Python offers a solution to this problem in
+ the form of explicit subtransactions.
+ </p><div class="sect2" id="id-1.8.11.15.3"><div class="titlepage"><div><div><h3 class="title">46.7.1. Subtransaction Context Managers</h3></div></div></div><p>
+ Consider a function that implements a transfer between two
+ accounts:
+</p><pre class="programlisting">
+CREATE FUNCTION transfer_funds() RETURNS void AS $$
+try:
+ plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'")
+ plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'")
+except plpy.SPIError as e:
+ result = "error transferring funds: %s" % e.args
+else:
+ result = "funds transferred correctly"
+plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"])
+plpy.execute(plan, [result])
+$$ LANGUAGE plpython3u;
+</pre><p>
+ If the second <code class="literal">UPDATE</code> statement results in an
+ exception being raised, this function will report the error, but
+ the result of the first <code class="literal">UPDATE</code> will
+ nevertheless be committed. In other words, the funds will be
+ withdrawn from Joe's account, but will not be transferred to
+ Mary's account.
+ </p><p>
+ To avoid such issues, you can wrap your
+ <code class="literal">plpy.execute</code> calls in an explicit
+ subtransaction. The <code class="literal">plpy</code> module provides a
+ helper object to manage explicit subtransactions that gets created
+ with the <code class="literal">plpy.subtransaction()</code> function.
+ Objects created by this function implement the
+ <a class="ulink" href="https://docs.python.org/library/stdtypes.html#context-manager-types" target="_top">
+ context manager interface</a>. Using explicit subtransactions
+ we can rewrite our function as:
+</p><pre class="programlisting">
+CREATE FUNCTION transfer_funds2() RETURNS void AS $$
+try:
+ with plpy.subtransaction():
+ plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'")
+ plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'")
+except plpy.SPIError as e:
+ result = "error transferring funds: %s" % e.args
+else:
+ result = "funds transferred correctly"
+plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"])
+plpy.execute(plan, [result])
+$$ LANGUAGE plpython3u;
+</pre><p>
+ Note that the use of <code class="literal">try/catch</code> is still
+ required. Otherwise the exception would propagate to the top of
+ the Python stack and would cause the whole function to abort with
+ a <span class="productname">PostgreSQL</span> error, so that the
+ <code class="literal">operations</code> table would not have any row
+ inserted into it. The subtransaction context manager does not
+ trap errors, it only assures that all database operations executed
+ inside its scope will be atomically committed or rolled back. A
+ rollback of the subtransaction block occurs on any kind of
+ exception exit, not only ones caused by errors originating from
+ database access. A regular Python exception raised inside an
+ explicit subtransaction block would also cause the subtransaction
+ to be rolled back.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-database.html" title="46.6. Database Access">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-transactions.html" title="46.8. Transaction Management">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.6. Database Access </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.8. Transaction Management</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-transactions.html b/doc/src/sgml/html/plpython-transactions.html
new file mode 100644
index 0000000..0671d1b
--- /dev/null
+++ b/doc/src/sgml/html/plpython-transactions.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.8. Transaction Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-subtransaction.html" title="46.7. Explicit Subtransactions" /><link rel="next" href="plpython-util.html" title="46.9. Utility Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.8. Transaction Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-subtransaction.html" title="46.7. Explicit Subtransactions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-util.html" title="46.9. Utility Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-TRANSACTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.8. Transaction Management</h2></div></div></div><p>
+ In a procedure called from the top level or an anonymous code block
+ (<code class="command">DO</code> command) called from the top level it is possible to
+ control transactions. To commit the current transaction, call
+ <code class="literal">plpy.commit()</code>. To roll back the current transaction,
+ call <code class="literal">plpy.rollback()</code>. (Note that it is not possible to
+ run the SQL commands <code class="command">COMMIT</code> or
+ <code class="command">ROLLBACK</code> via <code class="function">plpy.execute</code> or
+ similar. It has to be done using these functions.) After a transaction is
+ ended, a new transaction is automatically started, so there is no separate
+ function for that.
+ </p><p>
+ Here is an example:
+</p><pre class="programlisting">
+CREATE PROCEDURE transaction_test1()
+LANGUAGE plpython3u
+AS $$
+for i in range(0, 10):
+ plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
+ if i % 2 == 0:
+ plpy.commit()
+ else:
+ plpy.rollback()
+$$;
+
+CALL transaction_test1();
+</pre><p>
+ </p><p>
+ Transactions cannot be ended when an explicit subtransaction is active.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-subtransaction.html" title="46.7. Explicit Subtransactions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-util.html" title="46.9. Utility Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.7. Explicit Subtransactions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.9. Utility Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-trigger.html b/doc/src/sgml/html/plpython-trigger.html
new file mode 100644
index 0000000..a7230fb
--- /dev/null
+++ b/doc/src/sgml/html/plpython-trigger.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.5. Trigger Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-do.html" title="46.4. Anonymous Code Blocks" /><link rel="next" href="plpython-database.html" title="46.6. Database Access" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.5. Trigger Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-do.html" title="46.4. Anonymous Code Blocks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-database.html" title="46.6. Database Access">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.5. Trigger Functions</h2></div></div></div><a id="id-1.8.11.13.2" class="indexterm"></a><p>
+ When a function is used as a trigger, the dictionary
+ <code class="literal">TD</code> contains trigger-related values:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TD["event"]</code></span></dt><dd><p>
+ contains the event as a string:
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, or <code class="literal">TRUNCATE</code>.
+ </p></dd><dt><span class="term"><code class="literal">TD["when"]</code></span></dt><dd><p>
+ contains one of <code class="literal">BEFORE</code>, <code class="literal">AFTER</code>, or
+ <code class="literal">INSTEAD OF</code>.
+ </p></dd><dt><span class="term"><code class="literal">TD["level"]</code></span></dt><dd><p>
+ contains <code class="literal">ROW</code> or <code class="literal">STATEMENT</code>.
+ </p></dd><dt><span class="term"><code class="literal">TD["new"]</code><br /></span><span class="term"><code class="literal">TD["old"]</code></span></dt><dd><p>
+ For a row-level trigger, one or both of these fields contain
+ the respective trigger rows, depending on the trigger event.
+ </p></dd><dt><span class="term"><code class="literal">TD["name"]</code></span></dt><dd><p>
+ contains the trigger name.
+ </p></dd><dt><span class="term"><code class="literal">TD["table_name"]</code></span></dt><dd><p>
+ contains the name of the table on which the trigger occurred.
+ </p></dd><dt><span class="term"><code class="literal">TD["table_schema"]</code></span></dt><dd><p>
+ contains the schema of the table on which the trigger occurred.
+ </p></dd><dt><span class="term"><code class="literal">TD["relid"]</code></span></dt><dd><p>
+ contains the OID of the table on which the trigger occurred.
+ </p></dd><dt><span class="term"><code class="literal">TD["args"]</code></span></dt><dd><p>
+ If the <code class="command">CREATE TRIGGER</code> command
+ included arguments, they are available in <code class="literal">TD["args"][0]</code> to
+ <code class="literal">TD["args"][<em class="replaceable"><code>n</code></em>-1]</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ If <code class="literal">TD["when"]</code> is <code class="literal">BEFORE</code> or
+ <code class="literal">INSTEAD OF</code> and
+ <code class="literal">TD["level"]</code> is <code class="literal">ROW</code>, you can
+ return <code class="literal">None</code> or <code class="literal">"OK"</code> from the
+ Python function to indicate the row is unmodified,
+ <code class="literal">"SKIP"</code> to abort the event, or if <code class="literal">TD["event"]</code>
+ is <code class="command">INSERT</code> or <code class="command">UPDATE</code> you can return
+ <code class="literal">"MODIFY"</code> to indicate you've modified the new row.
+ Otherwise the return value is ignored.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-do.html" title="46.4. Anonymous Code Blocks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-database.html" title="46.6. Database Access">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.4. Anonymous Code Blocks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.6. Database Access</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython-util.html b/doc/src/sgml/html/plpython-util.html
new file mode 100644
index 0000000..63eeac3
--- /dev/null
+++ b/doc/src/sgml/html/plpython-util.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>46.9. Utility Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-transactions.html" title="46.8. Transaction Management" /><link rel="next" href="plpython-python23.html" title="46.10. Python 2 vs. Python 3" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">46.9. Utility Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-transactions.html" title="46.8. Transaction Management">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><th width="60%" align="center">Chapter 46. PL/Python — Python Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-python23.html" title="46.10. Python 2 vs. Python 3">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLPYTHON-UTIL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">46.9. Utility Functions</h2></div></div></div><p>
+ The <code class="literal">plpy</code> module also provides the functions
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">plpy.debug(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr><tr><td><code class="literal">plpy.log(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr><tr><td><code class="literal">plpy.info(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr><tr><td><code class="literal">plpy.notice(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr><tr><td><code class="literal">plpy.warning(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr><tr><td><code class="literal">plpy.error(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr><tr><td><code class="literal">plpy.fatal(<em class="replaceable"><code>msg, **kwargs</code></em>)</code></td></tr></table><p>
+ <a id="id-1.8.11.17.2.3" class="indexterm"></a>
+ <code class="function">plpy.error</code> and <code class="function">plpy.fatal</code>
+ actually raise a Python exception which, if uncaught, propagates out to
+ the calling query, causing the current transaction or subtransaction to
+ be aborted. <code class="literal">raise plpy.Error(<em class="replaceable"><code>msg</code></em>)</code> and
+ <code class="literal">raise plpy.Fatal(<em class="replaceable"><code>msg</code></em>)</code> are
+ equivalent to calling <code class="literal">plpy.error(<em class="replaceable"><code>msg</code></em>)</code> and
+ <code class="literal">plpy.fatal(<em class="replaceable"><code>msg</code></em>)</code>, respectively but
+ the <code class="literal">raise</code> form does not allow passing keyword arguments.
+ The other functions only generate messages of different priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a> and
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> configuration
+ variables. See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for more information.
+ </p><p>
+ The <em class="replaceable"><code>msg</code></em> argument is given as a positional argument. For
+ backward compatibility, more than one positional argument can be given. In
+ that case, the string representation of the tuple of positional arguments
+ becomes the message reported to the client.
+ </p><p>
+ The following keyword-only arguments are accepted:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="literal">detail</code></td></tr><tr><td><code class="literal">hint</code></td></tr><tr><td><code class="literal">sqlstate</code></td></tr><tr><td><code class="literal">schema_name</code></td></tr><tr><td><code class="literal">table_name</code></td></tr><tr><td><code class="literal">column_name</code></td></tr><tr><td><code class="literal">datatype_name</code></td></tr><tr><td><code class="literal">constraint_name</code></td></tr></table><p>
+ The string representation of the objects passed as keyword-only arguments
+ is used to enrich the messages reported to the client. For example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION raise_custom_exception() RETURNS void AS $$
+plpy.error("custom exception message",
+ detail="some info about exception",
+ hint="hint for users")
+$$ LANGUAGE plpython3u;
+
+=# SELECT raise_custom_exception();
+ERROR: plpy.Error: custom exception message
+DETAIL: some info about exception
+HINT: hint for users
+CONTEXT: Traceback (most recent call last):
+ PL/Python function "raise_custom_exception", line 4, in &lt;module&gt;
+ hint="hint for users")
+PL/Python function "raise_custom_exception"
+</pre><p>
+ </p><p>
+ Another set of utility functions are
+ <code class="literal">plpy.quote_literal(<em class="replaceable"><code>string</code></em>)</code>,
+ <code class="literal">plpy.quote_nullable(<em class="replaceable"><code>string</code></em>)</code>, and
+ <code class="literal">plpy.quote_ident(<em class="replaceable"><code>string</code></em>)</code>. They
+ are equivalent to the built-in quoting functions described in <a class="xref" href="functions-string.html" title="9.4. String Functions and Operators">Section 9.4</a>. They are useful when constructing
+ ad-hoc queries. A PL/Python equivalent of dynamic SQL from <a class="xref" href="plpgsql-statements.html#PLPGSQL-QUOTE-LITERAL-EXAMPLE" title="Example 43.1. Quoting Values in Dynamic Queries">Example 43.1</a> would be:
+</p><pre class="programlisting">
+plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % (
+ plpy.quote_ident(colname),
+ plpy.quote_nullable(newvalue),
+ plpy.quote_literal(keyvalue)))
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-transactions.html" title="46.8. Transaction Management">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-python23.html" title="46.10. Python 2 vs. Python 3">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.8. Transaction Management </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.10. Python 2 vs. Python 3</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/plpython.html b/doc/src/sgml/html/plpython.html
new file mode 100644
index 0000000..ecaf7e5
--- /dev/null
+++ b/doc/src/sgml/html/plpython.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 46. PL/Python — Python Procedural Language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plperl-under-the-hood.html" title="45.8. PL/Perl Under the Hood" /><link rel="next" href="plpython-funcs.html" title="46.1. PL/Python Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 46. PL/Python — Python Procedural Language</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plperl-under-the-hood.html" title="45.8. PL/Perl Under the Hood">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpython-funcs.html" title="46.1. PL/Python Functions">Next</a></td></tr></table><hr /></div><div class="chapter" id="PLPYTHON"><div class="titlepage"><div><div><h2 class="title">Chapter 46. PL/Python — Python Procedural Language</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="plpython-funcs.html">46.1. PL/Python Functions</a></span></dt><dt><span class="sect1"><a href="plpython-data.html">46.2. Data Values</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.3">46.2.1. Data Type Mapping</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.4">46.2.2. Null, None</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#PLPYTHON-ARRAYS">46.2.3. Arrays, Lists</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.6">46.2.4. Composite Types</a></span></dt><dt><span class="sect2"><a href="plpython-data.html#id-1.8.11.10.7">46.2.5. Set-Returning Functions</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpython-sharing.html">46.3. Sharing Data</a></span></dt><dt><span class="sect1"><a href="plpython-do.html">46.4. Anonymous Code Blocks</a></span></dt><dt><span class="sect1"><a href="plpython-trigger.html">46.5. Trigger Functions</a></span></dt><dt><span class="sect1"><a href="plpython-database.html">46.6. Database Access</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpython-database.html#id-1.8.11.14.3">46.6.1. Database Access Functions</a></span></dt><dt><span class="sect2"><a href="plpython-database.html#PLPYTHON-TRAPPING">46.6.2. Trapping Errors</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpython-subtransaction.html">46.7. Explicit Subtransactions</a></span></dt><dd><dl><dt><span class="sect2"><a href="plpython-subtransaction.html#id-1.8.11.15.3">46.7.1. Subtransaction Context Managers</a></span></dt></dl></dd><dt><span class="sect1"><a href="plpython-transactions.html">46.8. Transaction Management</a></span></dt><dt><span class="sect1"><a href="plpython-util.html">46.9. Utility Functions</a></span></dt><dt><span class="sect1"><a href="plpython-python23.html">46.10. Python 2 vs. Python 3</a></span></dt><dt><span class="sect1"><a href="plpython-envar.html">46.11. Environment Variables</a></span></dt></dl></div><a id="id-1.8.11.2" class="indexterm"></a><a id="id-1.8.11.3" class="indexterm"></a><p>
+ The <span class="application">PL/Python</span> procedural language allows
+ <span class="productname">PostgreSQL</span> functions and procedures to be written in the
+ <a class="ulink" href="https://www.python.org" target="_top">Python language</a>.
+ </p><p>
+ To install PL/Python in a particular database, use
+ <code class="literal">CREATE EXTENSION plpython3u</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If a language is installed into <code class="literal">template1</code>, all subsequently
+ created databases will have the language installed automatically.
+ </p></div><p>
+ PL/Python is only available as an <span class="quote">“<span class="quote">untrusted</span>”</span> language, meaning
+ it does not offer any way of restricting what users can do in it and
+ is therefore named <code class="literal">plpython3u</code>. A trusted
+ variant <code class="literal">plpython</code> might become available in the future
+ if a secure execution mechanism is developed in Python. The
+ writer of a function in untrusted PL/Python must take care that the
+ function cannot be used to do anything unwanted, since it will be
+ able to do anything that could be done by a user logged in as the
+ database administrator. Only superusers can create functions in
+ untrusted languages such as <code class="literal">plpython3u</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Users of source packages must specially enable the build of
+ PL/Python during the installation process. (Refer to the
+ installation instructions for more information.) Users of binary
+ packages might find PL/Python in a separate subpackage.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plperl-under-the-hood.html" title="45.8. PL/Perl Under the Hood">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpython-funcs.html" title="46.1. PL/Python Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">45.8. PL/Perl Under the Hood </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 46.1. PL/Python Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-config.html b/doc/src/sgml/html/pltcl-config.html
new file mode 100644
index 0000000..63e9f21
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-config.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.11. PL/Tcl Configuration</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-transactions.html" title="44.10. Transaction Management" /><link rel="next" href="pltcl-procnames.html" title="44.12. Tcl Procedure Names" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.11. PL/Tcl Configuration</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-transactions.html" title="44.10. Transaction Management">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-procnames.html" title="44.12. Tcl Procedure Names">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-CONFIG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.11. PL/Tcl Configuration</h2></div></div></div><p>
+ This section lists configuration parameters that
+ affect <span class="application">PL/Tcl</span>.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-PLTCL-START-PROC"><span class="term">
+ <code class="varname">pltcl.start_proc</code> (<code class="type">string</code>)
+ <a id="id-1.8.9.15.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter, if set to a nonempty string, specifies the name
+ (possibly schema-qualified) of a parameterless PL/Tcl function that
+ is to be executed whenever a new Tcl interpreter is created for
+ PL/Tcl. Such a function can perform per-session initialization, such
+ as loading additional Tcl code. A new Tcl interpreter is created
+ when a PL/Tcl function is first executed in a database session, or
+ when an additional interpreter has to be created because a PL/Tcl
+ function is called by a new SQL role.
+ </p><p>
+ The referenced function must be written in the <code class="literal">pltcl</code>
+ language, and must not be marked <code class="literal">SECURITY DEFINER</code>.
+ (These restrictions ensure that it runs in the interpreter it's
+ supposed to initialize.) The current user must have permission to
+ call it, too.
+ </p><p>
+ If the function fails with an error it will abort the function call
+ that caused the new interpreter to be created and propagate out to
+ the calling query, causing the current transaction or subtransaction
+ to be aborted. Any actions already done within Tcl won't be undone;
+ however, that interpreter won't be used again. If the language is
+ used again the initialization will be attempted again within a fresh
+ Tcl interpreter.
+ </p><p>
+ Only superusers can change this setting. Although this setting
+ can be changed within a session, such changes will not affect Tcl
+ interpreters that have already been created.
+ </p></dd><dt id="GUC-PLTCLU-START-PROC"><span class="term">
+ <code class="varname">pltclu.start_proc</code> (<code class="type">string</code>)
+ <a id="id-1.8.9.15.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter is exactly like <code class="varname">pltcl.start_proc</code>,
+ except that it applies to PL/TclU. The referenced function must
+ be written in the <code class="literal">pltclu</code> language.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-transactions.html" title="44.10. Transaction Management">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-procnames.html" title="44.12. Tcl Procedure Names">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.10. Transaction Management </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.12. Tcl Procedure Names</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-data.html b/doc/src/sgml/html/pltcl-data.html
new file mode 100644
index 0000000..a4d5237
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-data.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.3. Data Values in PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-functions.html" title="44.2. PL/Tcl Functions and Arguments" /><link rel="next" href="pltcl-global.html" title="44.4. Global Data in PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.3. Data Values in PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-functions.html" title="44.2. PL/Tcl Functions and Arguments">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-global.html" title="44.4. Global Data in PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-DATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.3. Data Values in PL/Tcl</h2></div></div></div><p>
+ The argument values supplied to a PL/Tcl function's code are simply
+ the input arguments converted to text form (just as if they had been
+ displayed by a <code class="command">SELECT</code> statement). Conversely, the
+ <code class="literal">return</code> and <code class="literal">return_next</code> commands will accept
+ any string that is acceptable input format for the function's declared
+ result type, or for the specified column of a composite result type.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-functions.html" title="44.2. PL/Tcl Functions and Arguments">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-global.html" title="44.4. Global Data in PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.2. PL/Tcl Functions and Arguments </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.4. Global Data in PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-dbaccess.html b/doc/src/sgml/html/pltcl-dbaccess.html
new file mode 100644
index 0000000..9631213
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-dbaccess.html
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.5. Database Access from PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-global.html" title="44.4. Global Data in PL/Tcl" /><link rel="next" href="pltcl-trigger.html" title="44.6. Trigger Functions in PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.5. Database Access from PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-global.html" title="44.4. Global Data in PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-trigger.html" title="44.6. Trigger Functions in PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-DBACCESS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.5. Database Access from PL/Tcl</h2></div></div></div><p>
+ In this section, we follow the usual Tcl convention of using question
+ marks, rather than brackets, to indicate an optional element in a
+ syntax synopsis. The following commands are available to access
+ the database from the body of a PL/Tcl function:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal"><code class="function">spi_exec</code> ?<span class="optional">-count <em class="replaceable"><code>n</code></em></span>? ?<span class="optional">-array <em class="replaceable"><code>name</code></em></span>? <em class="replaceable"><code>command</code></em> ?<span class="optional"><em class="replaceable"><code>loop-body</code></em></span>?</code></span></dt><dd><p>
+ Executes an SQL command given as a string. An error in the command
+ causes an error to be raised. Otherwise, the return value of <code class="function">spi_exec</code>
+ is the number of rows processed (selected, inserted, updated, or
+ deleted) by the command, or zero if the command is a utility
+ statement. In addition, if the command is a <code class="command">SELECT</code> statement, the
+ values of the selected columns are placed in Tcl variables as
+ described below.
+ </p><p>
+ The optional <code class="literal">-count</code> value tells
+ <code class="function">spi_exec</code> to stop
+ once <em class="replaceable"><code>n</code></em> rows have been retrieved,
+ much as if the query included a <code class="literal">LIMIT</code> clause.
+ If <em class="replaceable"><code>n</code></em> is zero, the query is run to
+ completion, the same as when <code class="literal">-count</code> is omitted.
+ </p><p>
+ If the command is a <code class="command">SELECT</code> statement, the values of the
+ result columns are placed into Tcl variables named after the columns.
+ If the <code class="literal">-array</code> option is given, the column values are
+ instead stored into elements of the named associative array, with the
+ column names used as array indexes. In addition, the current row
+ number within the result (counting from zero) is stored into the array
+ element named <span class="quote">“<span class="quote"><code class="literal">.tupno</code></span>”</span>, unless that name is
+ in use as a column name in the result.
+ </p><p>
+ If the command is a <code class="command">SELECT</code> statement and no <em class="replaceable"><code>loop-body</code></em>
+ script is given, then only the first row of results are stored into
+ Tcl variables or array elements; remaining rows, if any, are ignored.
+ No storing occurs if the query returns no rows. (This case can be
+ detected by checking the result of <code class="function">spi_exec</code>.)
+ For example:
+</p><pre class="programlisting">
+spi_exec "SELECT count(*) AS cnt FROM pg_proc"
+</pre><p>
+ will set the Tcl variable <code class="literal">$cnt</code> to the number of rows in
+ the <code class="structname">pg_proc</code> system catalog.
+ </p><p>
+ If the optional <em class="replaceable"><code>loop-body</code></em> argument is given, it is
+ a piece of Tcl script that is executed once for each row in the
+ query result. (<em class="replaceable"><code>loop-body</code></em> is ignored if the given
+ command is not a <code class="command">SELECT</code>.)
+ The values of the current row's columns
+ are stored into Tcl variables or array elements before each iteration.
+ For example:
+</p><pre class="programlisting">
+spi_exec -array C "SELECT * FROM pg_class" {
+ elog DEBUG "have table $C(relname)"
+}
+</pre><p>
+ will print a log message for every row of <code class="literal">pg_class</code>. This
+ feature works similarly to other Tcl looping constructs; in
+ particular <code class="literal">continue</code> and <code class="literal">break</code> work in the
+ usual way inside the loop body.
+ </p><p>
+ If a column of a query result is null, the target
+ variable for it is <span class="quote">“<span class="quote">unset</span>”</span> rather than being set.
+ </p></dd><dt><span class="term"><code class="function">spi_prepare</code> <em class="replaceable"><code>query</code></em> <em class="replaceable"><code>typelist</code></em></span></dt><dd><p>
+ Prepares and saves a query plan for later execution. The
+ saved plan will be retained for the life of the current
+ session.<a id="id-1.8.9.9.2.1.2.2.1.1" class="indexterm"></a>
+ </p><p>
+ The query can use parameters, that is, placeholders for
+ values to be supplied whenever the plan is actually executed.
+ In the query string, refer to parameters
+ by the symbols <code class="literal">$1</code> ... <code class="literal">$<em class="replaceable"><code>n</code></em></code>.
+ If the query uses parameters, the names of the parameter types
+ must be given as a Tcl list. (Write an empty list for
+ <em class="replaceable"><code>typelist</code></em> if no parameters are used.)
+ </p><p>
+ The return value from <code class="function">spi_prepare</code> is a query ID
+ to be used in subsequent calls to <code class="function">spi_execp</code>. See
+ <code class="function">spi_execp</code> for an example.
+ </p></dd><dt><span class="term"><code class="literal"><code class="function">spi_execp</code> ?<span class="optional">-count <em class="replaceable"><code>n</code></em></span>? ?<span class="optional">-array <em class="replaceable"><code>name</code></em></span>? ?<span class="optional">-nulls <em class="replaceable"><code>string</code></em></span>? <em class="replaceable"><code>queryid</code></em> ?<span class="optional"><em class="replaceable"><code>value-list</code></em></span>? ?<span class="optional"><em class="replaceable"><code>loop-body</code></em></span>?</code></span></dt><dd><p>
+ Executes a query previously prepared with <code class="function">spi_prepare</code>.
+ <em class="replaceable"><code>queryid</code></em> is the ID returned by
+ <code class="function">spi_prepare</code>. If the query references parameters,
+ a <em class="replaceable"><code>value-list</code></em> must be supplied. This
+ is a Tcl list of actual values for the parameters. The list must be
+ the same length as the parameter type list previously given to
+ <code class="function">spi_prepare</code>. Omit <em class="replaceable"><code>value-list</code></em>
+ if the query has no parameters.
+ </p><p>
+ The optional value for <code class="literal">-nulls</code> is a string of spaces and
+ <code class="literal">'n'</code> characters telling <code class="function">spi_execp</code>
+ which of the parameters are null values. If given, it must have exactly the
+ same length as the <em class="replaceable"><code>value-list</code></em>. If it
+ is not given, all the parameter values are nonnull.
+ </p><p>
+ Except for the way in which the query and its parameters are specified,
+ <code class="function">spi_execp</code> works just like <code class="function">spi_exec</code>.
+ The <code class="literal">-count</code>, <code class="literal">-array</code>, and
+ <em class="replaceable"><code>loop-body</code></em> options are the same,
+ and so is the result value.
+ </p><p>
+ Here's an example of a PL/Tcl function using a prepared plan:
+
+</p><pre class="programlisting">
+CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
+ if {![ info exists GD(plan) ]} {
+ # prepare the saved plan on the first call
+ set GD(plan) [ spi_prepare \
+ "SELECT count(*) AS cnt FROM t1 WHERE num &gt;= \$1 AND num &lt;= \$2" \
+ [ list int4 int4 ] ]
+ }
+ spi_execp -count 1 $GD(plan) [ list $1 $2 ]
+ return $cnt
+$$ LANGUAGE pltcl;
+</pre><p>
+
+ We need backslashes inside the query string given to
+ <code class="function">spi_prepare</code> to ensure that the
+ <code class="literal">$<em class="replaceable"><code>n</code></em></code> markers will be passed
+ through to <code class="function">spi_prepare</code> as-is, and not replaced by Tcl
+ variable substitution.
+
+ </p></dd><dt><span class="term"><code class="function">subtransaction</code> <em class="replaceable"><code>command</code></em></span></dt><dd><p>
+ The Tcl script contained in <em class="replaceable"><code>command</code></em> is
+ executed within an SQL subtransaction. If the script returns an
+ error, that entire subtransaction is rolled back before returning the
+ error out to the surrounding Tcl code.
+ See <a class="xref" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl">Section 44.9</a> for more details and an
+ example.
+ </p></dd><dt><span class="term"><code class="function">quote</code> <em class="replaceable"><code>string</code></em></span></dt><dd><p>
+ Doubles all occurrences of single quote and backslash characters
+ in the given string. This can be used to safely quote strings
+ that are to be inserted into SQL commands given
+ to <code class="function">spi_exec</code> or
+ <code class="function">spi_prepare</code>.
+ For example, think about an SQL command string like:
+
+</p><pre class="programlisting">
+"SELECT '$val' AS ret"
+</pre><p>
+
+ where the Tcl variable <code class="literal">val</code> actually contains
+ <code class="literal">doesn't</code>. This would result
+ in the final command string:
+
+</p><pre class="programlisting">
+SELECT 'doesn't' AS ret
+</pre><p>
+
+ which would cause a parse error during
+ <code class="function">spi_exec</code> or
+ <code class="function">spi_prepare</code>.
+ To work properly, the submitted command should contain:
+
+</p><pre class="programlisting">
+SELECT 'doesn''t' AS ret
+</pre><p>
+
+ which can be formed in PL/Tcl using:
+
+</p><pre class="programlisting">
+"SELECT '[ quote $val ]' AS ret"
+</pre><p>
+
+ One advantage of <code class="function">spi_execp</code> is that you don't
+ have to quote parameter values like this, since the parameters are never
+ parsed as part of an SQL command string.
+ </p></dd><dt><span class="term">
+ <code class="function">elog</code> <em class="replaceable"><code>level</code></em> <em class="replaceable"><code>msg</code></em>
+ <a id="id-1.8.9.9.2.1.6.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Emits a log or error message. Possible levels are
+ <code class="literal">DEBUG</code>, <code class="literal">LOG</code>, <code class="literal">INFO</code>,
+ <code class="literal">NOTICE</code>, <code class="literal">WARNING</code>, <code class="literal">ERROR</code>, and
+ <code class="literal">FATAL</code>. <code class="literal">ERROR</code>
+ raises an error condition; if this is not trapped by the surrounding
+ Tcl code, the error propagates out to the calling query, causing
+ the current transaction or subtransaction to be aborted. This
+ is effectively the same as the Tcl <code class="literal">error</code> command.
+ <code class="literal">FATAL</code> aborts the transaction and causes the current
+ session to shut down. (There is probably no good reason to use
+ this error level in PL/Tcl functions, but it's provided for
+ completeness.) The other levels only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a> and
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> configuration
+ variables. See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ and <a class="xref" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl">Section 44.8</a>
+ for more information.
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-global.html" title="44.4. Global Data in PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-trigger.html" title="44.6. Trigger Functions in PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.4. Global Data in PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.6. Trigger Functions in PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-error-handling.html b/doc/src/sgml/html/pltcl-error-handling.html
new file mode 100644
index 0000000..1cce490
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-error-handling.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.8. Error Handling in PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-event-trigger.html" title="44.7. Event Trigger Functions in PL/Tcl" /><link rel="next" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.8. Error Handling in PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-event-trigger.html" title="44.7. Event Trigger Functions in PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-ERROR-HANDLING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.8. Error Handling in PL/Tcl</h2></div></div></div><a id="id-1.8.9.12.2" class="indexterm"></a><p>
+ Tcl code within or called from a PL/Tcl function can raise an error,
+ either by executing some invalid operation or by generating an error
+ using the Tcl <code class="function">error</code> command or
+ PL/Tcl's <code class="function">elog</code> command. Such errors can be caught
+ within Tcl using the Tcl <code class="function">catch</code> command. If an
+ error is not caught but is allowed to propagate out to the top level of
+ execution of the PL/Tcl function, it is reported as an SQL error in the
+ function's calling query.
+ </p><p>
+ Conversely, SQL errors that occur within PL/Tcl's
+ <code class="function">spi_exec</code>, <code class="function">spi_prepare</code>,
+ and <code class="function">spi_execp</code> commands are reported as Tcl errors,
+ so they are catchable by Tcl's <code class="function">catch</code> command.
+ (Each of these PL/Tcl commands runs its SQL operation in a
+ subtransaction, which is rolled back on error, so that any
+ partially-completed operation is automatically cleaned up.)
+ Again, if an error propagates out to the top level without being caught,
+ it turns back into an SQL error.
+ </p><p>
+ Tcl provides an <code class="varname">errorCode</code> variable that can represent
+ additional information about an error in a form that is easy for Tcl
+ programs to interpret. The contents are in Tcl list format, and the
+ first word identifies the subsystem or library reporting the error;
+ beyond that the contents are left to the individual subsystem or
+ library. For database errors reported by PL/Tcl commands, the first
+ word is <code class="literal">POSTGRES</code>, the second word is the PostgreSQL
+ version number, and additional words are field name/value pairs
+ providing detailed information about the error.
+ Fields <code class="varname">SQLSTATE</code>, <code class="varname">condition</code>,
+ and <code class="varname">message</code> are always supplied
+ (the first two represent the error code and condition name as shown
+ in <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>).
+ Fields that may be present include
+ <code class="varname">detail</code>, <code class="varname">hint</code>, <code class="varname">context</code>,
+ <code class="varname">schema</code>, <code class="varname">table</code>, <code class="varname">column</code>,
+ <code class="varname">datatype</code>, <code class="varname">constraint</code>,
+ <code class="varname">statement</code>, <code class="varname">cursor_position</code>,
+ <code class="varname">filename</code>, <code class="varname">lineno</code>, and
+ <code class="varname">funcname</code>.
+ </p><p>
+ A convenient way to work with PL/Tcl's <code class="varname">errorCode</code>
+ information is to load it into an array, so that the field names become
+ array subscripts. Code for doing that might look like
+</p><pre class="programlisting">
+if {[catch { spi_exec $sql_command }]} {
+ if {[lindex $::errorCode 0] == "POSTGRES"} {
+ array set errorArray $::errorCode
+ if {$errorArray(condition) == "undefined_table"} {
+ # deal with missing table
+ } else {
+ # deal with some other type of SQL error
+ }
+ }
+}
+</pre><p>
+ (The double colons explicitly specify that <code class="varname">errorCode</code>
+ is a global variable.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-event-trigger.html" title="44.7. Event Trigger Functions in PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.7. Event Trigger Functions in PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.9. Explicit Subtransactions in PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-event-trigger.html b/doc/src/sgml/html/pltcl-event-trigger.html
new file mode 100644
index 0000000..5d1a594
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-event-trigger.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.7. Event Trigger Functions in PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-trigger.html" title="44.6. Trigger Functions in PL/Tcl" /><link rel="next" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.7. Event Trigger Functions in PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-trigger.html" title="44.6. Trigger Functions in PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-EVENT-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.7. Event Trigger Functions in PL/Tcl</h2></div></div></div><a id="id-1.8.9.11.2" class="indexterm"></a><p>
+ Event trigger functions can be written in PL/Tcl.
+ <span class="productname">PostgreSQL</span> requires that a function that is
+ to be called as an event trigger must be declared as a function with no
+ arguments and a return type of <code class="literal">event_trigger</code>.
+ </p><p>
+ The information from the trigger manager is passed to the function body
+ in the following variables:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">$TG_event</code></span></dt><dd><p>
+ The name of the event the trigger is fired for.
+ </p></dd><dt><span class="term"><code class="varname">$TG_tag</code></span></dt><dd><p>
+ The command tag for which the trigger is fired.
+ </p></dd></dl></div><p>
+ </p><p>
+ The return value of the trigger function is ignored.
+ </p><p>
+ Here's a little example event trigger function that simply raises
+ a <code class="literal">NOTICE</code> message each time a supported command is
+ executed:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$
+ elog NOTICE "tclsnitch: $TG_event $TG_tag"
+$$ LANGUAGE pltcl;
+
+CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitch();
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-trigger.html" title="44.6. Trigger Functions in PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.6. Trigger Functions in PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.8. Error Handling in PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-functions.html b/doc/src/sgml/html/pltcl-functions.html
new file mode 100644
index 0000000..0d48612
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-functions.html
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.2. PL/Tcl Functions and Arguments</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-overview.html" title="44.1. Overview" /><link rel="next" href="pltcl-data.html" title="44.3. Data Values in PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.2. PL/Tcl Functions and Arguments</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-overview.html" title="44.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-data.html" title="44.3. Data Values in PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-FUNCTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.2. PL/Tcl Functions and Arguments</h2></div></div></div><p>
+ To create a function in the <span class="application">PL/Tcl</span> language, use
+ the standard <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> syntax:
+
+</p><pre class="programlisting">
+CREATE FUNCTION <em class="replaceable"><code>funcname</code></em> (<em class="replaceable"><code>argument-types</code></em>) RETURNS <em class="replaceable"><code>return-type</code></em> AS $$
+ # PL/Tcl function body
+$$ LANGUAGE pltcl;
+</pre><p>
+
+ <span class="application">PL/TclU</span> is the same, except that the language has to be specified as
+ <code class="literal">pltclu</code>.
+ </p><p>
+ The body of the function is simply a piece of Tcl script.
+ When the function is called, the argument values are passed to the
+ Tcl script as variables named <code class="literal">1</code>
+ ... <code class="literal"><em class="replaceable"><code>n</code></em></code>. The result is
+ returned from the Tcl code in the usual way, with
+ a <code class="literal">return</code> statement. In a procedure, the return value
+ from the Tcl code is ignored.
+ </p><p>
+ For example, a function
+ returning the greater of two integer values could be defined as:
+
+</p><pre class="programlisting">
+CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
+ if {$1 &gt; $2} {return $1}
+ return $2
+$$ LANGUAGE pltcl STRICT;
+</pre><p>
+
+ Note the clause <code class="literal">STRICT</code>, which saves us from
+ having to think about null input values: if a null value is passed, the
+ function will not be called at all, but will just return a null
+ result automatically.
+ </p><p>
+ In a nonstrict function,
+ if the actual value of an argument is null, the corresponding
+ <code class="literal">$<em class="replaceable"><code>n</code></em></code> variable will be set to an empty string.
+ To detect whether a particular argument is null, use the function
+ <code class="literal">argisnull</code>. For example, suppose that we wanted <code class="function">tcl_max</code>
+ with one null and one nonnull argument to return the nonnull
+ argument, rather than null:
+
+</p><pre class="programlisting">
+CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
+ if {[argisnull 1]} {
+ if {[argisnull 2]} { return_null }
+ return $2
+ }
+ if {[argisnull 2]} { return $1 }
+ if {$1 &gt; $2} {return $1}
+ return $2
+$$ LANGUAGE pltcl;
+</pre><p>
+ </p><p>
+ As shown above,
+ to return a null value from a PL/Tcl function, execute
+ <code class="literal">return_null</code>. This can be done whether the
+ function is strict or not.
+ </p><p>
+ Composite-type arguments are passed to the function as Tcl
+ arrays. The element names of the array are the attribute names
+ of the composite type. If an attribute in the passed row has the
+ null value, it will not appear in the array. Here is an example:
+
+</p><pre class="programlisting">
+CREATE TABLE employee (
+ name text,
+ salary integer,
+ age integer
+);
+
+CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
+ if {200000.0 &lt; $1(salary)} {
+ return "t"
+ }
+ if {$1(age) &lt; 30 &amp;&amp; 100000.0 &lt; $1(salary)} {
+ return "t"
+ }
+ return "f"
+$$ LANGUAGE pltcl;
+</pre><p>
+ </p><p>
+ PL/Tcl functions can return composite-type results, too. To do this,
+ the Tcl code must return a list of column name/value pairs matching
+ the expected result type. Any column names omitted from the list
+ are returned as nulls, and an error is raised if there are unexpected
+ column names. Here is an example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION square_cube(in int, out squared int, out cubed int) AS $$
+ return [list squared [expr {$1 * $1}] cubed [expr {$1 * $1 * $1}]]
+$$ LANGUAGE pltcl;
+</pre><p>
+ </p><p>
+ Output arguments of procedures are returned in the same way, for example:
+
+</p><pre class="programlisting">
+CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$
+ return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
+$$ LANGUAGE pltcl;
+
+CALL tcl_triple(5, 10);
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The result list can be made from an array representation of the
+ desired tuple with the <code class="literal">array get</code> Tcl command. For example:
+
+</p><pre class="programlisting">
+CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
+ set 1(salary) [expr {$1(salary) + $2}]
+ return [array get 1]
+$$ LANGUAGE pltcl;
+</pre><p>
+ </p></div><p>
+ PL/Tcl functions can return sets. To do this, the Tcl code should
+ call <code class="function">return_next</code> once per row to be returned,
+ passing either the appropriate value when returning a scalar type,
+ or a list of column name/value pairs when returning a composite type.
+ Here is an example returning a scalar type:
+
+</p><pre class="programlisting">
+CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
+ for {set i $1} {$i &lt; $2} {incr i} {
+ return_next $i
+ }
+$$ LANGUAGE pltcl;
+</pre><p>
+
+ and here is one returning a composite type:
+
+</p><pre class="programlisting">
+CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$
+ for {set i $1} {$i &lt; $2} {incr i} {
+ return_next [list x $i x2 [expr {$i * $i}]]
+ }
+$$ LANGUAGE pltcl;
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-overview.html" title="44.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-data.html" title="44.3. Data Values in PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.3. Data Values in PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-global.html b/doc/src/sgml/html/pltcl-global.html
new file mode 100644
index 0000000..38ee06d
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-global.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.4. Global Data in PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-data.html" title="44.3. Data Values in PL/Tcl" /><link rel="next" href="pltcl-dbaccess.html" title="44.5. Database Access from PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.4. Global Data in PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-data.html" title="44.3. Data Values in PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-dbaccess.html" title="44.5. Database Access from PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-GLOBAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.4. Global Data in PL/Tcl</h2></div></div></div><a id="id-1.8.9.8.2" class="indexterm"></a><p>
+ Sometimes it
+ is useful to have some global data that is held between two
+ calls to a function or is shared between different functions.
+ This is easily done in PL/Tcl, but there are some restrictions that
+ must be understood.
+ </p><p>
+ For security reasons, PL/Tcl executes functions called by any one SQL
+ role in a separate Tcl interpreter for that role. This prevents
+ accidental or malicious interference by one user with the behavior of
+ another user's PL/Tcl functions. Each such interpreter will have its own
+ values for any <span class="quote">“<span class="quote">global</span>”</span> Tcl variables. Thus, two PL/Tcl
+ functions will share the same global variables if and only if they are
+ executed by the same SQL role. In an application wherein a single
+ session executes code under multiple SQL roles (via <code class="literal">SECURITY
+ DEFINER</code> functions, use of <code class="command">SET ROLE</code>, etc.) you may need to
+ take explicit steps to ensure that PL/Tcl functions can share data. To
+ do that, make sure that functions that should communicate are owned by
+ the same user, and mark them <code class="literal">SECURITY DEFINER</code>. You must of
+ course take care that such functions can't be used to do anything
+ unintended.
+ </p><p>
+ All PL/TclU functions used in a session execute in the same Tcl
+ interpreter, which of course is distinct from the interpreter(s)
+ used for PL/Tcl functions. So global data is automatically shared
+ between PL/TclU functions. This is not considered a security risk
+ because all PL/TclU functions execute at the same trust level,
+ namely that of a database superuser.
+ </p><p>
+ To help protect PL/Tcl functions from unintentionally interfering
+ with each other, a global
+ array is made available to each function via the <code class="function">upvar</code>
+ command. The global name of this variable is the function's internal
+ name, and the local name is <code class="literal">GD</code>. It is recommended that
+ <code class="literal">GD</code> be used
+ for persistent private data of a function. Use regular Tcl global
+ variables only for values that you specifically intend to be shared among
+ multiple functions. (Note that the <code class="literal">GD</code> arrays are only
+ global within a particular interpreter, so they do not bypass the
+ security restrictions mentioned above.)
+ </p><p>
+ An example of using <code class="literal">GD</code> appears in the
+ <code class="function">spi_execp</code> example below.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-data.html" title="44.3. Data Values in PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-dbaccess.html" title="44.5. Database Access from PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.3. Data Values in PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.5. Database Access from PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-overview.html b/doc/src/sgml/html/pltcl-overview.html
new file mode 100644
index 0000000..b7b775f
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-overview.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language" /><link rel="next" href="pltcl-functions.html" title="44.2. PL/Tcl Functions and Arguments" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-functions.html" title="44.2. PL/Tcl Functions and Arguments">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.1. Overview</h2></div></div></div><p>
+ PL/Tcl offers most of the capabilities a function writer has in
+ the C language, with a few restrictions, and with the addition of
+ the powerful string processing libraries that are available for
+ Tcl.
+ </p><p>
+ One compelling <span class="emphasis"><em>good</em></span> restriction is that
+ everything is executed from within the safety of the context of a
+ Tcl interpreter. In addition to the limited command set of safe
+ Tcl, only a few commands are available to access the database via
+ SPI and to raise messages via <code class="function">elog()</code>. PL/Tcl
+ provides no way to access internals of the database server or to
+ gain OS-level access under the permissions of the
+ <span class="productname">PostgreSQL</span> server process, as a C
+ function can do. Thus, unprivileged database users can be trusted
+ to use this language; it does not give them unlimited authority.
+ </p><p>
+ The other notable implementation restriction is that Tcl functions
+ cannot be used to create input/output functions for new data
+ types.
+ </p><p>
+ Sometimes it is desirable to write Tcl functions that are not restricted
+ to safe Tcl. For example, one might want a Tcl function that sends
+ email. To handle these cases, there is a variant of <span class="application">PL/Tcl</span> called <code class="literal">PL/TclU</code>
+ (for untrusted Tcl). This is exactly the same language except that a full
+ Tcl interpreter is used. <span class="emphasis"><em>If <span class="application">PL/TclU</span> is used, it must be
+ installed as an untrusted procedural language</em></span> so that only
+ database superusers can create functions in it. The writer of a <span class="application">PL/TclU</span>
+ function must take care that the function cannot be used to do anything
+ unwanted, since it will be able to do anything that could be done by
+ a user logged in as the database administrator.
+ </p><p>
+ The shared object code for the <span class="application">PL/Tcl</span> and
+ <span class="application">PL/TclU</span> call handlers is automatically built and
+ installed in the <span class="productname">PostgreSQL</span> library
+ directory if Tcl support is specified in the configuration step of
+ the installation procedure. To install <span class="application">PL/Tcl</span>
+ and/or <span class="application">PL/TclU</span> in a particular database, use the
+ <code class="command">CREATE EXTENSION</code> command, for example
+ <code class="literal">CREATE EXTENSION pltcl</code> or
+ <code class="literal">CREATE EXTENSION pltclu</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-functions.html" title="44.2. PL/Tcl Functions and Arguments">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 44. PL/Tcl — Tcl Procedural Language </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.2. PL/Tcl Functions and Arguments</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-procnames.html b/doc/src/sgml/html/pltcl-procnames.html
new file mode 100644
index 0000000..494505c
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-procnames.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.12. Tcl Procedure Names</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-config.html" title="44.11. PL/Tcl Configuration" /><link rel="next" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.12. Tcl Procedure Names</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-config.html" title="44.11. PL/Tcl Configuration">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-PROCNAMES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.12. Tcl Procedure Names</h2></div></div></div><p>
+ In <span class="productname">PostgreSQL</span>, the same function name can be used for
+ different function definitions as long as the number of arguments or their types
+ differ. Tcl, however, requires all procedure names to be distinct.
+ PL/Tcl deals with this by making the internal Tcl procedure names contain
+ the object
+ ID of the function from the system table <code class="structname">pg_proc</code> as part of their name. Thus,
+ <span class="productname">PostgreSQL</span> functions with the same name
+ and different argument types will be different Tcl procedures, too. This
+ is not normally a concern for a PL/Tcl programmer, but it might be visible
+ when debugging.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-config.html" title="44.11. PL/Tcl Configuration">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.11. PL/Tcl Configuration </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 45. PL/Perl — Perl Procedural Language</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-subtransactions.html b/doc/src/sgml/html/pltcl-subtransactions.html
new file mode 100644
index 0000000..04d4207
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-subtransactions.html
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.9. Explicit Subtransactions in PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl" /><link rel="next" href="pltcl-transactions.html" title="44.10. Transaction Management" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.9. Explicit Subtransactions in PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-transactions.html" title="44.10. Transaction Management">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-SUBTRANSACTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.9. Explicit Subtransactions in PL/Tcl</h2></div></div></div><a id="id-1.8.9.13.2" class="indexterm"></a><p>
+ Recovering from errors caused by database access as described in
+ <a class="xref" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl">Section 44.8</a> can lead to an undesirable
+ situation where some operations succeed before one of them fails,
+ and after recovering from that error the data is left in an
+ inconsistent state. PL/Tcl offers a solution to this problem in
+ the form of explicit subtransactions.
+ </p><p>
+ Consider a function that implements a transfer between two accounts:
+</p><pre class="programlisting">
+CREATE FUNCTION transfer_funds() RETURNS void AS $$
+ if [catch {
+ spi_exec "UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'"
+ spi_exec "UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'"
+ } errormsg] {
+ set result [format "error transferring funds: %s" $errormsg]
+ } else {
+ set result "funds transferred successfully"
+ }
+ spi_exec "INSERT INTO operations (result) VALUES ('[quote $result]')"
+$$ LANGUAGE pltcl;
+</pre><p>
+ If the second <code class="command">UPDATE</code> statement results in an
+ exception being raised, this function will log the failure, but
+ the result of the first <code class="command">UPDATE</code> will
+ nevertheless be committed. In other words, the funds will be
+ withdrawn from Joe's account, but will not be transferred to
+ Mary's account. This happens because each <code class="function">spi_exec</code>
+ is a separate subtransaction, and only one of those subtransactions
+ got rolled back.
+ </p><p>
+ To handle such cases, you can wrap multiple database operations in an
+ explicit subtransaction, which will succeed or roll back as a whole.
+ PL/Tcl provides a <code class="function">subtransaction</code> command to manage
+ this. We can rewrite our function as:
+</p><pre class="programlisting">
+CREATE FUNCTION transfer_funds2() RETURNS void AS $$
+ if [catch {
+ subtransaction {
+ spi_exec "UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'"
+ spi_exec "UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'"
+ }
+ } errormsg] {
+ set result [format "error transferring funds: %s" $errormsg]
+ } else {
+ set result "funds transferred successfully"
+ }
+ spi_exec "INSERT INTO operations (result) VALUES ('[quote $result]')"
+$$ LANGUAGE pltcl;
+</pre><p>
+ Note that use of <code class="function">catch</code> is still required for this
+ purpose. Otherwise the error would propagate to the top level of the
+ function, preventing the desired insertion into
+ the <code class="structname">operations</code> table.
+ The <code class="function">subtransaction</code> command does not trap errors, it
+ only assures that all database operations executed inside its scope will
+ be rolled back together when an error is reported.
+ </p><p>
+ A rollback of an explicit subtransaction occurs on any error reported
+ by the contained Tcl code, not only errors originating from database
+ access. Thus a regular Tcl exception raised inside
+ a <code class="function">subtransaction</code> command will also cause the
+ subtransaction to be rolled back. However, non-error exits out of the
+ contained Tcl code (for instance, due to <code class="function">return</code>) do
+ not cause a rollback.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-error-handling.html" title="44.8. Error Handling in PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-transactions.html" title="44.10. Transaction Management">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.8. Error Handling in PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.10. Transaction Management</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-transactions.html b/doc/src/sgml/html/pltcl-transactions.html
new file mode 100644
index 0000000..9438254
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-transactions.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.10. Transaction Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl" /><link rel="next" href="pltcl-config.html" title="44.11. PL/Tcl Configuration" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.10. Transaction Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-config.html" title="44.11. PL/Tcl Configuration">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-TRANSACTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.10. Transaction Management</h2></div></div></div><p>
+ In a procedure called from the top level or an anonymous code block
+ (<code class="command">DO</code> command) called from the top level it is possible
+ to control transactions. To commit the current transaction, call the
+ <code class="literal">commit</code> command. To roll back the current transaction,
+ call the <code class="literal">rollback</code> command. (Note that it is not
+ possible to run the SQL commands <code class="command">COMMIT</code> or
+ <code class="command">ROLLBACK</code> via <code class="function">spi_exec</code> or similar.
+ It has to be done using these functions.) After a transaction is ended,
+ a new transaction is automatically started, so there is no separate
+ command for that.
+ </p><p>
+ Here is an example:
+</p><pre class="programlisting">
+CREATE PROCEDURE transaction_test1()
+LANGUAGE pltcl
+AS $$
+for {set i 0} {$i &lt; 10} {incr i} {
+ spi_exec "INSERT INTO test1 (a) VALUES ($i)"
+ if {$i % 2 == 0} {
+ commit
+ } else {
+ rollback
+ }
+}
+$$;
+
+CALL transaction_test1();
+</pre><p>
+ </p><p>
+ Transactions cannot be ended when an explicit subtransaction is active.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-subtransactions.html" title="44.9. Explicit Subtransactions in PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-config.html" title="44.11. PL/Tcl Configuration">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.9. Explicit Subtransactions in PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.11. PL/Tcl Configuration</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl-trigger.html b/doc/src/sgml/html/pltcl-trigger.html
new file mode 100644
index 0000000..6cb9cf8
--- /dev/null
+++ b/doc/src/sgml/html/pltcl-trigger.html
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>44.6. Trigger Functions in PL/Tcl</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pltcl-dbaccess.html" title="44.5. Database Access from PL/Tcl" /><link rel="next" href="pltcl-event-trigger.html" title="44.7. Event Trigger Functions in PL/Tcl" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">44.6. Trigger Functions in PL/Tcl</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pltcl-dbaccess.html" title="44.5. Database Access from PL/Tcl">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><th width="60%" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-event-trigger.html" title="44.7. Event Trigger Functions in PL/Tcl">Next</a></td></tr></table><hr /></div><div class="sect1" id="PLTCL-TRIGGER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">44.6. Trigger Functions in PL/Tcl</h2></div></div></div><a id="id-1.8.9.10.2" class="indexterm"></a><p>
+ Trigger functions can be written in PL/Tcl.
+ <span class="productname">PostgreSQL</span> requires that a function that is to be called
+ as a trigger must be declared as a function with no arguments
+ and a return type of <code class="literal">trigger</code>.
+ </p><p>
+ The information from the trigger manager is passed to the function body
+ in the following variables:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="varname">$TG_name</code></span></dt><dd><p>
+ The name of the trigger from the <code class="command">CREATE TRIGGER</code> statement.
+ </p></dd><dt><span class="term"><code class="varname">$TG_relid</code></span></dt><dd><p>
+ The object ID of the table that caused the trigger function
+ to be invoked.
+ </p></dd><dt><span class="term"><code class="varname">$TG_table_name</code></span></dt><dd><p>
+ The name of the table that caused the trigger function
+ to be invoked.
+ </p></dd><dt><span class="term"><code class="varname">$TG_table_schema</code></span></dt><dd><p>
+ The schema of the table that caused the trigger function
+ to be invoked.
+ </p></dd><dt><span class="term"><code class="varname">$TG_relatts</code></span></dt><dd><p>
+ A Tcl list of the table column names, prefixed with an empty list
+ element. So looking up a column name in the list with <span class="application">Tcl</span>'s
+ <code class="function">lsearch</code> command returns the element's number starting
+ with 1 for the first column, the same way the columns are customarily
+ numbered in <span class="productname">PostgreSQL</span>. (Empty list
+ elements also appear in the positions of columns that have been
+ dropped, so that the attribute numbering is correct for columns
+ to their right.)
+ </p></dd><dt><span class="term"><code class="varname">$TG_when</code></span></dt><dd><p>
+ The string <code class="literal">BEFORE</code>, <code class="literal">AFTER</code>, or
+ <code class="literal">INSTEAD OF</code>, depending on the type of trigger event.
+ </p></dd><dt><span class="term"><code class="varname">$TG_level</code></span></dt><dd><p>
+ The string <code class="literal">ROW</code> or <code class="literal">STATEMENT</code> depending on the
+ type of trigger event.
+ </p></dd><dt><span class="term"><code class="varname">$TG_op</code></span></dt><dd><p>
+ The string <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, or <code class="literal">TRUNCATE</code> depending on the type of
+ trigger event.
+ </p></dd><dt><span class="term"><code class="varname">$NEW</code></span></dt><dd><p>
+ An associative array containing the values of the new table
+ row for <code class="command">INSERT</code> or <code class="command">UPDATE</code> actions, or
+ empty for <code class="command">DELETE</code>. The array is indexed by column
+ name. Columns that are null will not appear in the array.
+ This is not set for statement-level triggers.
+ </p></dd><dt><span class="term"><code class="varname">$OLD</code></span></dt><dd><p>
+ An associative array containing the values of the old table
+ row for <code class="command">UPDATE</code> or <code class="command">DELETE</code> actions, or
+ empty for <code class="command">INSERT</code>. The array is indexed by column
+ name. Columns that are null will not appear in the array.
+ This is not set for statement-level triggers.
+ </p></dd><dt><span class="term"><code class="varname">$args</code></span></dt><dd><p>
+ A Tcl list of the arguments to the function as given in the
+ <code class="command">CREATE TRIGGER</code> statement. These arguments are also accessible as
+ <code class="literal">$1</code> ... <code class="literal">$<em class="replaceable"><code>n</code></em></code> in the function body.
+ </p></dd></dl></div><p>
+ </p><p>
+ The return value from a trigger function can be one of the strings
+ <code class="literal">OK</code> or <code class="literal">SKIP</code>, or a list of column name/value pairs.
+ If the return value is <code class="literal">OK</code>,
+ the operation (<code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code>)
+ that fired the trigger will proceed
+ normally. <code class="literal">SKIP</code> tells the trigger manager to silently suppress
+ the operation for this row. If a list is returned, it tells PL/Tcl to
+ return a modified row to the trigger manager; the contents of the
+ modified row are specified by the column names and values in the list.
+ Any columns not mentioned in the list are set to null.
+ Returning a modified row is only meaningful
+ for row-level <code class="literal">BEFORE</code> <code class="command">INSERT</code> or <code class="command">UPDATE</code>
+ triggers, for which the modified row will be inserted instead of the one
+ given in <code class="varname">$NEW</code>; or for row-level <code class="literal">INSTEAD OF</code>
+ <code class="command">INSERT</code> or <code class="command">UPDATE</code> triggers where the returned row
+ is used as the source data for <code class="command">INSERT RETURNING</code> or
+ <code class="command">UPDATE RETURNING</code> clauses.
+ In row-level <code class="literal">BEFORE</code> <code class="command">DELETE</code> or <code class="literal">INSTEAD
+ OF</code> <code class="command">DELETE</code> triggers, returning a modified row has the same
+ effect as returning <code class="literal">OK</code>, that is the operation proceeds.
+ The trigger return value is ignored for all other types of triggers.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The result list can be made from an array representation of the
+ modified tuple with the <code class="literal">array get</code> Tcl command.
+ </p></div><p>
+ Here's a little example trigger function that forces an integer value
+ in a table to keep track of the number of updates that are performed on the
+ row. For new rows inserted, the value is initialized to 0 and then
+ incremented on every update operation.
+
+</p><pre class="programlisting">
+CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
+ switch $TG_op {
+ INSERT {
+ set NEW($1) 0
+ }
+ UPDATE {
+ set NEW($1) $OLD($1)
+ incr NEW($1)
+ }
+ default {
+ return OK
+ }
+ }
+ return [array get NEW]
+$$ LANGUAGE pltcl;
+
+CREATE TABLE mytab (num integer, description text, modcnt integer);
+
+CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
+ FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt');
+</pre><p>
+
+ Notice that the trigger function itself does not know the column
+ name; that's supplied from the trigger arguments. This lets the
+ trigger function be reused with different tables.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pltcl-dbaccess.html" title="44.5. Database Access from PL/Tcl">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-event-trigger.html" title="44.7. Event Trigger Functions in PL/Tcl">Next</a></td></tr><tr><td width="40%" align="left" valign="top">44.5. Database Access from PL/Tcl </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.7. Event Trigger Functions in PL/Tcl</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/pltcl.html b/doc/src/sgml/html/pltcl.html
new file mode 100644
index 0000000..ad98bcc
--- /dev/null
+++ b/doc/src/sgml/html/pltcl.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 44. PL/Tcl — Tcl Procedural Language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpgsql-porting.html" title="43.13. Porting from Oracle PL/SQL" /><link rel="next" href="pltcl-overview.html" title="44.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 44. PL/Tcl — Tcl Procedural Language</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpgsql-porting.html" title="43.13. Porting from Oracle PL/SQL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="pltcl-overview.html" title="44.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="PLTCL"><div class="titlepage"><div><div><h2 class="title">Chapter 44. PL/Tcl — Tcl Procedural Language</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="pltcl-overview.html">44.1. Overview</a></span></dt><dt><span class="sect1"><a href="pltcl-functions.html">44.2. PL/Tcl Functions and Arguments</a></span></dt><dt><span class="sect1"><a href="pltcl-data.html">44.3. Data Values in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-global.html">44.4. Global Data in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-dbaccess.html">44.5. Database Access from PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-trigger.html">44.6. Trigger Functions in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-event-trigger.html">44.7. Event Trigger Functions in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-error-handling.html">44.8. Error Handling in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-subtransactions.html">44.9. Explicit Subtransactions in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-transactions.html">44.10. Transaction Management</a></span></dt><dt><span class="sect1"><a href="pltcl-config.html">44.11. PL/Tcl Configuration</a></span></dt><dt><span class="sect1"><a href="pltcl-procnames.html">44.12. Tcl Procedure Names</a></span></dt></dl></div><a id="id-1.8.9.2" class="indexterm"></a><a id="id-1.8.9.3" class="indexterm"></a><p>
+ PL/Tcl is a loadable procedural language for the
+ <span class="productname">PostgreSQL</span> database system
+ that enables the <a class="ulink" href="https://www.tcl.tk/" target="_top">
+ Tcl language</a> to be used to write
+ <span class="productname">PostgreSQL</span> functions and procedures.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpgsql-porting.html" title="43.13. Porting from Oracle PL/SQL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="pltcl-overview.html" title="44.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">43.13. Porting from <span class="productname">Oracle</span> PL/SQL </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 44.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/populate.html b/doc/src/sgml/html/populate.html
new file mode 100644
index 0000000..c67b2ba
--- /dev/null
+++ b/doc/src/sgml/html/populate.html
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>14.4. Populating a Database</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses" /><link rel="next" href="non-durability.html" title="14.5. Non-Durable Settings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">14.4. Populating a Database</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><th width="60%" align="center">Chapter 14. Performance Tips</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="non-durability.html" title="14.5. Non-Durable Settings">Next</a></td></tr></table><hr /></div><div class="sect1" id="POPULATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">14.4. Populating a Database</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="populate.html#DISABLE-AUTOCOMMIT">14.4.1. Disable Autocommit</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-COPY-FROM">14.4.2. Use <code class="command">COPY</code></a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-RM-INDEXES">14.4.3. Remove Indexes</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-RM-FKEYS">14.4.4. Remove Foreign Key Constraints</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-WORK-MEM">14.4.5. Increase <code class="varname">maintenance_work_mem</code></a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-MAX-WAL-SIZE">14.4.6. Increase <code class="varname">max_wal_size</code></a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-PITR">14.4.7. Disable WAL Archival and Streaming Replication</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-ANALYZE">14.4.8. Run <code class="command">ANALYZE</code> Afterwards</a></span></dt><dt><span class="sect2"><a href="populate.html#POPULATE-PG-DUMP">14.4.9. Some Notes about <span class="application">pg_dump</span></a></span></dt></dl></div><p>
+ One might need to insert a large amount of data when first populating
+ a database. This section contains some suggestions on how to make
+ this process as efficient as possible.
+ </p><div class="sect2" id="DISABLE-AUTOCOMMIT"><div class="titlepage"><div><div><h3 class="title">14.4.1. Disable Autocommit</h3></div></div></div><a id="id-1.5.13.7.3.2" class="indexterm"></a><p>
+ When using multiple <code class="command">INSERT</code>s, turn off autocommit and just do
+ one commit at the end. (In plain
+ SQL, this means issuing <code class="command">BEGIN</code> at the start and
+ <code class="command">COMMIT</code> at the end. Some client libraries might
+ do this behind your back, in which case you need to make sure the
+ library does it when you want it done.) If you allow each
+ insertion to be committed separately,
+ <span class="productname">PostgreSQL</span> is doing a lot of work for
+ each row that is added. An additional benefit of doing all
+ insertions in one transaction is that if the insertion of one row
+ were to fail then the insertion of all rows inserted up to that
+ point would be rolled back, so you won't be stuck with partially
+ loaded data.
+ </p></div><div class="sect2" id="POPULATE-COPY-FROM"><div class="titlepage"><div><div><h3 class="title">14.4.2. Use <code class="command">COPY</code></h3></div></div></div><p>
+ Use <a class="link" href="sql-copy.html" title="COPY"><code class="command">COPY</code></a> to load
+ all the rows in one command, instead of using a series of
+ <code class="command">INSERT</code> commands. The <code class="command">COPY</code>
+ command is optimized for loading large numbers of rows; it is less
+ flexible than <code class="command">INSERT</code>, but incurs significantly
+ less overhead for large data loads. Since <code class="command">COPY</code>
+ is a single command, there is no need to disable autocommit if you
+ use this method to populate a table.
+ </p><p>
+ If you cannot use <code class="command">COPY</code>, it might help to use <a class="link" href="sql-prepare.html" title="PREPARE"><code class="command">PREPARE</code></a> to create a
+ prepared <code class="command">INSERT</code> statement, and then use
+ <code class="command">EXECUTE</code> as many times as required. This avoids
+ some of the overhead of repeatedly parsing and planning
+ <code class="command">INSERT</code>. Different interfaces provide this facility
+ in different ways; look for <span class="quote">“<span class="quote">prepared statements</span>”</span> in the interface
+ documentation.
+ </p><p>
+ Note that loading a large number of rows using
+ <code class="command">COPY</code> is almost always faster than using
+ <code class="command">INSERT</code>, even if <code class="command">PREPARE</code> is used and
+ multiple insertions are batched into a single transaction.
+ </p><p>
+ <code class="command">COPY</code> is fastest when used within the same
+ transaction as an earlier <code class="command">CREATE TABLE</code> or
+ <code class="command">TRUNCATE</code> command. In such cases no WAL
+ needs to be written, because in case of an error, the files
+ containing the newly loaded data will be removed anyway.
+ However, this consideration only applies when
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-LEVEL">wal_level</a> is <code class="literal">minimal</code>
+ as all commands must write WAL otherwise.
+ </p></div><div class="sect2" id="POPULATE-RM-INDEXES"><div class="titlepage"><div><div><h3 class="title">14.4.3. Remove Indexes</h3></div></div></div><p>
+ If you are loading a freshly created table, the fastest method is to
+ create the table, bulk load the table's data using
+ <code class="command">COPY</code>, then create any indexes needed for the
+ table. Creating an index on pre-existing data is quicker than
+ updating it incrementally as each row is loaded.
+ </p><p>
+ If you are adding large amounts of data to an existing table,
+ it might be a win to drop the indexes,
+ load the table, and then recreate the indexes. Of course, the
+ database performance for other users might suffer
+ during the time the indexes are missing. One should also think
+ twice before dropping a unique index, since the error checking
+ afforded by the unique constraint will be lost while the index is
+ missing.
+ </p></div><div class="sect2" id="POPULATE-RM-FKEYS"><div class="titlepage"><div><div><h3 class="title">14.4.4. Remove Foreign Key Constraints</h3></div></div></div><p>
+ Just as with indexes, a foreign key constraint can be checked
+ <span class="quote">“<span class="quote">in bulk</span>”</span> more efficiently than row-by-row. So it might be
+ useful to drop foreign key constraints, load data, and re-create
+ the constraints. Again, there is a trade-off between data load
+ speed and loss of error checking while the constraint is missing.
+ </p><p>
+ What's more, when you load data into a table with existing foreign key
+ constraints, each new row requires an entry in the server's list of
+ pending trigger events (since it is the firing of a trigger that checks
+ the row's foreign key constraint). Loading many millions of rows can
+ cause the trigger event queue to overflow available memory, leading to
+ intolerable swapping or even outright failure of the command. Therefore
+ it may be <span class="emphasis"><em>necessary</em></span>, not just desirable, to drop and re-apply
+ foreign keys when loading large amounts of data. If temporarily removing
+ the constraint isn't acceptable, the only other recourse may be to split
+ up the load operation into smaller transactions.
+ </p></div><div class="sect2" id="POPULATE-WORK-MEM"><div class="titlepage"><div><div><h3 class="title">14.4.5. Increase <code class="varname">maintenance_work_mem</code></h3></div></div></div><p>
+ Temporarily increasing the <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a>
+ configuration variable when loading large amounts of data can
+ lead to improved performance. This will help to speed up <code class="command">CREATE
+ INDEX</code> commands and <code class="command">ALTER TABLE ADD FOREIGN KEY</code> commands.
+ It won't do much for <code class="command">COPY</code> itself, so this advice is
+ only useful when you are using one or both of the above techniques.
+ </p></div><div class="sect2" id="POPULATE-MAX-WAL-SIZE"><div class="titlepage"><div><div><h3 class="title">14.4.6. Increase <code class="varname">max_wal_size</code></h3></div></div></div><p>
+ Temporarily increasing the <a class="xref" href="runtime-config-wal.html#GUC-MAX-WAL-SIZE">max_wal_size</a>
+ configuration variable can also
+ make large data loads faster. This is because loading a large
+ amount of data into <span class="productname">PostgreSQL</span> will
+ cause checkpoints to occur more often than the normal checkpoint
+ frequency (specified by the <code class="varname">checkpoint_timeout</code>
+ configuration variable). Whenever a checkpoint occurs, all dirty
+ pages must be flushed to disk. By increasing
+ <code class="varname">max_wal_size</code> temporarily during bulk
+ data loads, the number of checkpoints that are required can be
+ reduced.
+ </p></div><div class="sect2" id="POPULATE-PITR"><div class="titlepage"><div><div><h3 class="title">14.4.7. Disable WAL Archival and Streaming Replication</h3></div></div></div><p>
+ When loading large amounts of data into an installation that uses
+ WAL archiving or streaming replication, it might be faster to take a
+ new base backup after the load has completed than to process a large
+ amount of incremental WAL data. To prevent incremental WAL logging
+ while loading, disable archiving and streaming replication, by setting
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-LEVEL">wal_level</a> to <code class="literal">minimal</code>,
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-MODE">archive_mode</a> to <code class="literal">off</code>, and
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</a> to zero.
+ But note that changing these settings requires a server restart,
+ and makes any base backups taken before unavailable for archive
+ recovery and standby server, which may lead to data loss.
+ </p><p>
+ Aside from avoiding the time for the archiver or WAL sender to process the
+ WAL data, doing this will actually make certain commands faster, because
+ they do not to write WAL at all if <code class="varname">wal_level</code>
+ is <code class="literal">minimal</code> and the current subtransaction (or top-level
+ transaction) created or truncated the table or index they change. (They
+ can guarantee crash safety more cheaply by doing
+ an <code class="function">fsync</code> at the end than by writing WAL.)
+ </p></div><div class="sect2" id="POPULATE-ANALYZE"><div class="titlepage"><div><div><h3 class="title">14.4.8. Run <code class="command">ANALYZE</code> Afterwards</h3></div></div></div><p>
+ Whenever you have significantly altered the distribution of data
+ within a table, running <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> is strongly recommended. This
+ includes bulk loading large amounts of data into the table. Running
+ <code class="command">ANALYZE</code> (or <code class="command">VACUUM ANALYZE</code>)
+ ensures that the planner has up-to-date statistics about the
+ table. With no statistics or obsolete statistics, the planner might
+ make poor decisions during query planning, leading to poor
+ performance on any tables with inaccurate or nonexistent
+ statistics. Note that if the autovacuum daemon is enabled, it might
+ run <code class="command">ANALYZE</code> automatically; see
+ <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a>
+ and <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ </p></div><div class="sect2" id="POPULATE-PG-DUMP"><div class="titlepage"><div><div><h3 class="title">14.4.9. Some Notes about <span class="application">pg_dump</span></h3></div></div></div><p>
+ Dump scripts generated by <span class="application">pg_dump</span> automatically apply
+ several, but not all, of the above guidelines. To restore a
+ <span class="application">pg_dump</span> dump as quickly as possible, you need to
+ do a few extra things manually. (Note that these points apply while
+ <span class="emphasis"><em>restoring</em></span> a dump, not while <span class="emphasis"><em>creating</em></span> it.
+ The same points apply whether loading a text dump with
+ <span class="application">psql</span> or using <span class="application">pg_restore</span> to load
+ from a <span class="application">pg_dump</span> archive file.)
+ </p><p>
+ By default, <span class="application">pg_dump</span> uses <code class="command">COPY</code>, and when
+ it is generating a complete schema-and-data dump, it is careful to
+ load data before creating indexes and foreign keys. So in this case
+ several guidelines are handled automatically. What is left
+ for you to do is to:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Set appropriate (i.e., larger than normal) values for
+ <code class="varname">maintenance_work_mem</code> and
+ <code class="varname">max_wal_size</code>.
+ </p></li><li class="listitem"><p>
+ If using WAL archiving or streaming replication, consider disabling
+ them during the restore. To do that, set <code class="varname">archive_mode</code>
+ to <code class="literal">off</code>,
+ <code class="varname">wal_level</code> to <code class="literal">minimal</code>, and
+ <code class="varname">max_wal_senders</code> to zero before loading the dump.
+ Afterwards, set them back to the right values and take a fresh
+ base backup.
+ </p></li><li class="listitem"><p>
+ Experiment with the parallel dump and restore modes of both
+ <span class="application">pg_dump</span> and <span class="application">pg_restore</span> and find the
+ optimal number of concurrent jobs to use. Dumping and restoring in
+ parallel by means of the <code class="option">-j</code> option should give you a
+ significantly higher performance over the serial mode.
+ </p></li><li class="listitem"><p>
+ Consider whether the whole dump should be restored as a single
+ transaction. To do that, pass the <code class="option">-1</code> or
+ <code class="option">--single-transaction</code> command-line option to
+ <span class="application">psql</span> or <span class="application">pg_restore</span>. When using this
+ mode, even the smallest of errors will rollback the entire restore,
+ possibly discarding many hours of processing. Depending on how
+ interrelated the data is, that might seem preferable to manual cleanup,
+ or not. <code class="command">COPY</code> commands will run fastest if you use a single
+ transaction and have WAL archiving turned off.
+ </p></li><li class="listitem"><p>
+ If multiple CPUs are available in the database server, consider using
+ <span class="application">pg_restore</span>'s <code class="option">--jobs</code> option. This
+ allows concurrent data loading and index creation.
+ </p></li><li class="listitem"><p>
+ Run <code class="command">ANALYZE</code> afterwards.
+ </p></li></ul></div><p>
+ </p><p>
+ A data-only dump will still use <code class="command">COPY</code>, but it does not
+ drop or recreate indexes, and it does not normally touch foreign
+ keys.
+
+ <a href="#ftn.id-1.5.13.7.11.4.2" class="footnote"><sup class="footnote" id="id-1.5.13.7.11.4.2">[14]</sup></a>
+
+ So when loading a data-only dump, it is up to you to drop and recreate
+ indexes and foreign keys if you wish to use those techniques.
+ It's still useful to increase <code class="varname">max_wal_size</code>
+ while loading the data, but don't bother increasing
+ <code class="varname">maintenance_work_mem</code>; rather, you'd do that while
+ manually recreating indexes and foreign keys afterwards.
+ And don't forget to <code class="command">ANALYZE</code> when you're done; see
+ <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-STATISTICS" title="25.1.3. Updating Planner Statistics">Section 25.1.3</a>
+ and <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ </p></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.5.13.7.11.4.2" class="footnote"><p><a href="#id-1.5.13.7.11.4.2" class="para"><sup class="para">[14] </sup></a>
+ You can get the effect of disabling foreign keys by using
+ the <code class="option">--disable-triggers</code> option — but realize that
+ that eliminates, rather than just postpones, foreign key
+ validation, and so it is possible to insert bad data if you use it.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="non-durability.html" title="14.5. Non-Durable Settings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">14.3. Controlling the Planner with Explicit <code class="literal">JOIN</code> Clauses </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 14.5. Non-Durable Settings</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/postgres-fdw.html b/doc/src/sgml/html/postgres-fdw.html
new file mode 100644
index 0000000..fbde04d
--- /dev/null
+++ b/doc/src/sgml/html/postgres-fdw.html
@@ -0,0 +1,677 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.38. postgres_fdw</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="pgwalinspect.html" title="F.37. pg_walinspect" /><link rel="next" href="seg.html" title="F.39. seg" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.38. postgres_fdw</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="pgwalinspect.html" title="F.37. pg_walinspect">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="seg.html" title="F.39. seg">Next</a></td></tr></table><hr /></div><div class="sect1" id="POSTGRES-FDW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.38. postgres_fdw</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.11">F.38.1. FDW Options of postgres_fdw</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.12">F.38.2. Functions</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.13">F.38.3. Connection Management</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.14">F.38.4. Transaction Management</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.15">F.38.5. Remote Query Optimization</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.16">F.38.6. Remote Query Execution Environment</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.17">F.38.7. Cross-Version Compatibility</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.18">F.38.8. Configuration Parameters</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.19">F.38.9. Examples</a></span></dt><dt><span class="sect2"><a href="postgres-fdw.html#id-1.11.7.47.20">F.38.10. Author</a></span></dt></dl></div><a id="id-1.11.7.47.2" class="indexterm"></a><p>
+ The <code class="filename">postgres_fdw</code> module provides the foreign-data wrapper
+ <code class="literal">postgres_fdw</code>, which can be used to access data
+ stored in external <span class="productname">PostgreSQL</span> servers.
+ </p><p>
+ The functionality provided by this module overlaps substantially
+ with the functionality of the older <a class="xref" href="dblink.html" title="F.12. dblink">dblink</a> module.
+ But <code class="filename">postgres_fdw</code> provides more transparent and
+ standards-compliant syntax for accessing remote tables, and can give
+ better performance in many cases.
+ </p><p>
+ To prepare for remote access using <code class="filename">postgres_fdw</code>:
+ </p><div class="orderedlist"><ol class="orderedlist compact" type="1"><li class="listitem"><p>
+ Install the <code class="filename">postgres_fdw</code> extension using <a class="xref" href="sql-createextension.html" title="CREATE EXTENSION"><span class="refentrytitle">CREATE EXTENSION</span></a>.
+ </p></li><li class="listitem"><p>
+ Create a foreign server object, using <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>,
+ to represent each remote database you want to connect to.
+ Specify connection information, except <code class="literal">user</code> and
+ <code class="literal">password</code>, as options of the server object.
+ </p></li><li class="listitem"><p>
+ Create a user mapping, using <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>, for
+ each database user you want to allow to access each foreign server.
+ Specify the remote user name and password to use as
+ <code class="literal">user</code> and <code class="literal">password</code> options of the
+ user mapping.
+ </p></li><li class="listitem"><p>
+ Create a foreign table, using <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>
+ or <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a>,
+ for each remote table you want to access. The columns of the foreign
+ table must match the referenced remote table. You can, however, use
+ table and/or column names different from the remote table's, if you
+ specify the correct remote names as options of the foreign table object.
+ </p></li></ol></div><p>
+ </p><p>
+ Now you need only <code class="command">SELECT</code> from a foreign table to access
+ the data stored in its underlying remote table. You can also modify
+ the remote table using <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">COPY</code>, or
+ <code class="command">TRUNCATE</code>.
+ (Of course, the remote user you have specified in your user mapping must
+ have privileges to do these things.)
+ </p><p>
+ Note that the <code class="literal">ONLY</code> option specified in
+ <code class="command">SELECT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code> or <code class="command">TRUNCATE</code>
+ has no effect when accessing or modifying the remote table.
+ </p><p>
+ Note that <code class="filename">postgres_fdw</code> currently lacks support for
+ <code class="command">INSERT</code> statements with an <code class="literal">ON CONFLICT DO
+ UPDATE</code> clause. However, the <code class="literal">ON CONFLICT DO NOTHING</code>
+ clause is supported, provided a unique index inference specification
+ is omitted.
+ Note also that <code class="filename">postgres_fdw</code> supports row movement
+ invoked by <code class="command">UPDATE</code> statements executed on partitioned
+ tables, but it currently does not handle the case where a remote partition
+ chosen to insert a moved row into is also an <code class="command">UPDATE</code>
+ target partition that will be updated elsewhere in the same command.
+ </p><p>
+ It is generally recommended that the columns of a foreign table be declared
+ with exactly the same data types, and collations if applicable, as the
+ referenced columns of the remote table. Although <code class="filename">postgres_fdw</code>
+ is currently rather forgiving about performing data type conversions at
+ need, surprising semantic anomalies may arise when types or collations do
+ not match, due to the remote server interpreting query conditions
+ differently from the local server.
+ </p><p>
+ Note that a foreign table can be declared with fewer columns, or with a
+ different column order, than its underlying remote table has. Matching
+ of columns to the remote table is by name, not position.
+ </p><div class="sect2" id="id-1.11.7.47.11"><div class="titlepage"><div><div><h3 class="title">F.38.1. FDW Options of postgres_fdw</h3></div></div></div><div class="sect3" id="id-1.11.7.47.11.2"><div class="titlepage"><div><div><h4 class="title">F.38.1.1. Connection Options</h4></div></div></div><p>
+ A foreign server using the <code class="filename">postgres_fdw</code> foreign data wrapper
+ can have the same options that <span class="application">libpq</span> accepts in
+ connection strings, as described in <a class="xref" href="libpq-connect.html#LIBPQ-PARAMKEYWORDS" title="34.1.2. Parameter Key Words">Section 34.1.2</a>,
+ except that these options are not allowed or have special handling:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">user</code>, <code class="literal">password</code> and <code class="literal">sslpassword</code> (specify these
+ in a user mapping, instead, or use a service file)
+ </p></li><li class="listitem"><p>
+ <code class="literal">client_encoding</code> (this is automatically set from the local
+ server encoding)
+ </p></li><li class="listitem"><p>
+ <code class="literal">application_name</code> - this may appear in
+ <span class="emphasis"><em>either or both</em></span> a connection and
+ <a class="xref" href="postgres-fdw.html#GUC-PGFDW-APPLICATION-NAME">postgres_fdw.application_name</a>.
+ If both are present, <code class="varname">postgres_fdw.application_name</code>
+ overrides the connection setting.
+ Unlike <span class="application">libpq</span>,
+ <code class="filename">postgres_fdw</code> allows
+ <code class="varname">application_name</code> to include
+ <span class="quote">“<span class="quote">escape sequences</span>”</span>.
+ See <a class="xref" href="postgres-fdw.html#GUC-PGFDW-APPLICATION-NAME">postgres_fdw.application_name</a> for details.
+ </p></li><li class="listitem"><p>
+ <code class="literal">fallback_application_name</code> (always set to
+ <code class="literal">postgres_fdw</code>)
+ </p></li><li class="listitem"><p>
+ <code class="literal">sslkey</code> and <code class="literal">sslcert</code> - these may
+ appear in <span class="emphasis"><em>either or both</em></span> a connection and a user
+ mapping. If both are present, the user mapping setting overrides the
+ connection setting.
+ </p></li></ul></div><p>
+ </p><p>
+ Only superusers may create or modify user mappings with the
+ <code class="literal">sslcert</code> or <code class="literal">sslkey</code> settings.
+ </p><p>
+ Only superusers may connect to foreign servers without password
+ authentication, so always specify the <code class="literal">password</code> option
+ for user mappings belonging to non-superusers.
+ </p><p>
+ A superuser may override this check on a per-user-mapping basis by setting
+ the user mapping option <code class="literal">password_required 'false'</code>, e.g.,
+</p><pre class="programlisting">
+ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw
+OPTIONS (ADD password_required 'false');
+</pre><p>
+ To prevent unprivileged users from exploiting the authentication rights
+ of the unix user the postgres server is running as to escalate to superuser
+ rights, only the superuser may set this option on a user mapping.
+ </p><p>
+ Care is required to ensure that this does not allow the mapped
+ user the ability to connect as superuser to the mapped database per
+ CVE-2007-3278 and CVE-2007-6601. Don't set
+ <code class="literal">password_required=false</code>
+ on the <code class="literal">public</code> role. Keep in mind that the mapped
+ user can potentially use any client certificates,
+ <code class="filename">.pgpass</code>,
+ <code class="filename">.pg_service.conf</code> etc. in the unix home directory of the
+ system user the postgres server runs as. They can also use any trust
+ relationship granted by authentication modes like <code class="literal">peer</code>
+ or <code class="literal">ident</code> authentication.
+ </p></div><div class="sect3" id="id-1.11.7.47.11.3"><div class="titlepage"><div><div><h4 class="title">F.38.1.2. Object Name Options</h4></div></div></div><p>
+ These options can be used to control the names used in SQL statements
+ sent to the remote <span class="productname">PostgreSQL</span> server. These
+ options are needed when a foreign table is created with names different
+ from the underlying remote table's names.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">schema_name</code> (<code class="type">string</code>)</span></dt><dd><p>
+ This option, which can be specified for a foreign table, gives the
+ schema name to use for the foreign table on the remote server. If this
+ option is omitted, the name of the foreign table's schema is used.
+ </p></dd><dt><span class="term"><code class="literal">table_name</code> (<code class="type">string</code>)</span></dt><dd><p>
+ This option, which can be specified for a foreign table, gives the
+ table name to use for the foreign table on the remote server. If this
+ option is omitted, the foreign table's name is used.
+ </p></dd><dt><span class="term"><code class="literal">column_name</code> (<code class="type">string</code>)</span></dt><dd><p>
+ This option, which can be specified for a column of a foreign table,
+ gives the column name to use for the column on the remote server.
+ If this option is omitted, the column's name is used.
+ </p></dd></dl></div></div><div class="sect3" id="id-1.11.7.47.11.4"><div class="titlepage"><div><div><h4 class="title">F.38.1.3. Cost Estimation Options</h4></div></div></div><p>
+ <code class="filename">postgres_fdw</code> retrieves remote data by executing queries
+ against remote servers, so ideally the estimated cost of scanning a
+ foreign table should be whatever it costs to be done on the remote
+ server, plus some overhead for communication. The most reliable way to
+ get such an estimate is to ask the remote server and then add something
+ for overhead — but for simple queries, it may not be worth the cost
+ of an additional remote query to get a cost estimate.
+ So <code class="filename">postgres_fdw</code> provides the following options to control
+ how cost estimation is done:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">use_remote_estimate</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option, which can be specified for a foreign table or a foreign
+ server, controls whether <code class="filename">postgres_fdw</code> issues remote
+ <code class="command">EXPLAIN</code> commands to obtain cost estimates.
+ A setting for a foreign table overrides any setting for its server,
+ but only for that table.
+ The default is <code class="literal">false</code>.
+ </p></dd><dt><span class="term"><code class="literal">fdw_startup_cost</code> (<code class="type">floating point</code>)</span></dt><dd><p>
+ This option, which can be specified for a foreign server, is a floating
+ point value that is added to the estimated startup cost of any
+ foreign-table scan on that server. This represents the additional
+ overhead of establishing a connection, parsing and planning the query on
+ the remote side, etc.
+ The default value is <code class="literal">100</code>.
+ </p></dd><dt><span class="term"><code class="literal">fdw_tuple_cost</code> (<code class="type">floating point</code>)</span></dt><dd><p>
+ This option, which can be specified for a foreign server, is a floating
+ point value that is used as extra cost per-tuple for foreign-table
+ scans on that server. This represents the additional overhead of
+ data transfer between servers. You might increase or decrease this
+ number to reflect higher or lower network delay to the remote server.
+ The default value is <code class="literal">0.01</code>.
+ </p></dd></dl></div><p>
+ When <code class="literal">use_remote_estimate</code> is true,
+ <code class="filename">postgres_fdw</code> obtains row count and cost estimates from the
+ remote server and then adds <code class="literal">fdw_startup_cost</code> and
+ <code class="literal">fdw_tuple_cost</code> to the cost estimates. When
+ <code class="literal">use_remote_estimate</code> is false,
+ <code class="filename">postgres_fdw</code> performs local row count and cost estimation
+ and then adds <code class="literal">fdw_startup_cost</code> and
+ <code class="literal">fdw_tuple_cost</code> to the cost estimates. This local
+ estimation is unlikely to be very accurate unless local copies of the
+ remote table's statistics are available. Running
+ <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a> on the foreign table is the way to update
+ the local statistics; this will perform a scan of the remote table and
+ then calculate and store statistics just as though the table were local.
+ Keeping local statistics can be a useful way to reduce per-query planning
+ overhead for a remote table — but if the remote table is
+ frequently updated, the local statistics will soon be obsolete.
+ </p></div><div class="sect3" id="id-1.11.7.47.11.5"><div class="titlepage"><div><div><h4 class="title">F.38.1.4. Remote Execution Options</h4></div></div></div><p>
+ By default, only <code class="literal">WHERE</code> clauses using built-in operators and
+ functions will be considered for execution on the remote server. Clauses
+ involving non-built-in functions are checked locally after rows are
+ fetched. If such functions are available on the remote server and can be
+ relied on to produce the same results as they do locally, performance can
+ be improved by sending such <code class="literal">WHERE</code> clauses for remote
+ execution. This behavior can be controlled using the following option:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">extensions</code> (<code class="type">string</code>)</span></dt><dd><p>
+ This option is a comma-separated list of names
+ of <span class="productname">PostgreSQL</span> extensions that are installed, in
+ compatible versions, on both the local and remote servers. Functions
+ and operators that are immutable and belong to a listed extension will
+ be considered shippable to the remote server.
+ This option can only be specified for foreign servers, not per-table.
+ </p><p>
+ When using the <code class="literal">extensions</code> option, <span class="emphasis"><em>it is the
+ user's responsibility</em></span> that the listed extensions exist and behave
+ identically on both the local and remote servers. Otherwise, remote
+ queries may fail or behave unexpectedly.
+ </p></dd><dt><span class="term"><code class="literal">fetch_size</code> (<code class="type">integer</code>)</span></dt><dd><p>
+ This option specifies the number of rows <code class="filename">postgres_fdw</code>
+ should get in each fetch operation. It can be specified for a foreign
+ table or a foreign server. The option specified on a table overrides
+ an option specified for the server.
+ The default is <code class="literal">100</code>.
+ </p></dd><dt><span class="term"><code class="literal">batch_size</code> (<code class="type">integer</code>)</span></dt><dd><p>
+ This option specifies the number of rows <code class="filename">postgres_fdw</code>
+ should insert in each insert operation. It can be specified for a
+ foreign table or a foreign server. The option specified on a table
+ overrides an option specified for the server.
+ The default is <code class="literal">1</code>.
+ </p><p>
+ Note the actual number of rows <code class="filename">postgres_fdw</code> inserts at
+ once depends on the number of columns and the provided
+ <code class="literal">batch_size</code> value. The batch is executed as a single
+ query, and the libpq protocol (which <code class="filename">postgres_fdw</code>
+ uses to connect to a remote server) limits the number of parameters in a
+ single query to 65535. When the number of columns * <code class="literal">batch_size</code>
+ exceeds the limit, the <code class="literal">batch_size</code> will be adjusted to
+ avoid an error.
+ </p></dd></dl></div></div><div class="sect3" id="id-1.11.7.47.11.6"><div class="titlepage"><div><div><h4 class="title">F.38.1.5. Asynchronous Execution Options</h4></div></div></div><p>
+ <code class="filename">postgres_fdw</code> supports asynchronous execution, which
+ runs multiple parts of an <code class="structname">Append</code> node
+ concurrently rather than serially to improve performance.
+ This execution can be controlled using the following option:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">async_capable</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether <code class="filename">postgres_fdw</code> allows
+ foreign tables to be scanned concurrently for asynchronous execution.
+ It can be specified for a foreign table or a foreign server.
+ A table-level option overrides a server-level option.
+ The default is <code class="literal">false</code>.
+ </p><p>
+ In order to ensure that the data being returned from a foreign server
+ is consistent, <code class="filename">postgres_fdw</code> will only open one
+ connection for a given foreign server and will run all queries against
+ that server sequentially even if there are multiple foreign tables
+ involved, unless those tables are subject to different user mappings.
+ In such a case, it may be more performant to disable this option to
+ eliminate the overhead associated with running queries asynchronously.
+ </p><p>
+ Asynchronous execution is applied even when an
+ <code class="structname">Append</code> node contains subplan(s) executed
+ synchronously as well as subplan(s) executed asynchronously.
+ In such a case, if the asynchronous subplans are ones processed using
+ <code class="filename">postgres_fdw</code>, tuples from the asynchronous
+ subplans are not returned until after at least one synchronous subplan
+ returns all tuples, as that subplan is executed while the asynchronous
+ subplans are waiting for the results of asynchronous queries sent to
+ foreign servers.
+ This behavior might change in a future release.
+ </p></dd></dl></div></div><div class="sect3" id="id-1.11.7.47.11.7"><div class="titlepage"><div><div><h4 class="title">F.38.1.6. Transaction Management Options</h4></div></div></div><p>
+ As described in the Transaction Management section, in
+ <code class="filename">postgres_fdw</code> transactions are managed by creating
+ corresponding remote transactions, and subtransactions are managed by
+ creating corresponding remote subtransactions. When multiple remote
+ transactions are involved in the current local transaction, by default
+ <code class="filename">postgres_fdw</code> commits those remote transactions
+ serially when the local transaction is committed. When multiple remote
+ subtransactions are involved in the current local subtransaction, by
+ default <code class="filename">postgres_fdw</code> commits those remote
+ subtransactions serially when the local subtransaction is committed.
+ Performance can be improved with the following option:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">parallel_commit</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether <code class="filename">postgres_fdw</code> commits
+ in parallel remote transactions opened on a foreign server in a local
+ transaction when the local transaction is committed. This setting also
+ applies to remote and local subtransactions. This option can only be
+ specified for foreign servers, not per-table. The default is
+ <code class="literal">false</code>.
+ </p><p>
+ If multiple foreign servers with this option enabled are involved in a
+ local transaction, multiple remote transactions on those foreign
+ servers are committed in parallel across those foreign servers when
+ the local transaction is committed.
+ </p><p>
+ When this option is enabled, a foreign server with many remote
+ transactions may see a negative performance impact when the local
+ transaction is committed.
+ </p></dd></dl></div></div><div class="sect3" id="id-1.11.7.47.11.8"><div class="titlepage"><div><div><h4 class="title">F.38.1.7. Updatability Options</h4></div></div></div><p>
+ By default all foreign tables using <code class="filename">postgres_fdw</code> are assumed
+ to be updatable. This may be overridden using the following option:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">updatable</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether <code class="filename">postgres_fdw</code> allows foreign
+ tables to be modified using <code class="command">INSERT</code>, <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code> commands. It can be specified for a foreign table
+ or a foreign server. A table-level option overrides a server-level
+ option.
+ The default is <code class="literal">true</code>.
+ </p><p>
+ Of course, if the remote table is not in fact updatable, an error
+ would occur anyway. Use of this option primarily allows the error to
+ be thrown locally without querying the remote server. Note however
+ that the <code class="literal">information_schema</code> views will report a
+ <code class="filename">postgres_fdw</code> foreign table to be updatable (or not)
+ according to the setting of this option, without any check of the
+ remote server.
+ </p></dd></dl></div></div><div class="sect3" id="id-1.11.7.47.11.9"><div class="titlepage"><div><div><h4 class="title">F.38.1.8. Truncatability Options</h4></div></div></div><p>
+ By default all foreign tables using <code class="filename">postgres_fdw</code> are assumed
+ to be truncatable. This may be overridden using the following option:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">truncatable</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether <code class="filename">postgres_fdw</code> allows
+ foreign tables to be truncated using the <code class="command">TRUNCATE</code>
+ command. It can be specified for a foreign table or a foreign server.
+ A table-level option overrides a server-level option.
+ The default is <code class="literal">true</code>.
+ </p><p>
+ Of course, if the remote table is not in fact truncatable, an error
+ would occur anyway. Use of this option primarily allows the error to
+ be thrown locally without querying the remote server.
+ </p></dd></dl></div></div><div class="sect3" id="id-1.11.7.47.11.10"><div class="titlepage"><div><div><h4 class="title">F.38.1.9. Importing Options</h4></div></div></div><p>
+ <code class="filename">postgres_fdw</code> is able to import foreign table definitions
+ using <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a>. This command creates
+ foreign table definitions on the local server that match tables or
+ views present on the remote server. If the remote tables to be imported
+ have columns of user-defined data types, the local server must have
+ compatible types of the same names.
+ </p><p>
+ Importing behavior can be customized with the following options
+ (given in the <code class="command">IMPORT FOREIGN SCHEMA</code> command):
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">import_collate</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether column <code class="literal">COLLATE</code> options
+ are included in the definitions of foreign tables imported
+ from a foreign server. The default is <code class="literal">true</code>. You might
+ need to turn this off if the remote server has a different set of
+ collation names than the local server does, which is likely to be the
+ case if it's running on a different operating system.
+ If you do so, however, there is a very severe risk that the imported
+ table columns' collations will not match the underlying data, resulting
+ in anomalous query behavior.
+ </p><p>
+ Even when this parameter is set to <code class="literal">true</code>, importing
+ columns whose collation is the remote server's default can be risky.
+ They will be imported with <code class="literal">COLLATE "default"</code>, which
+ will select the local server's default collation, which could be
+ different.
+ </p></dd><dt><span class="term"><code class="literal">import_default</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether column <code class="literal">DEFAULT</code> expressions
+ are included in the definitions of foreign tables imported
+ from a foreign server. The default is <code class="literal">false</code>. If you
+ enable this option, be wary of defaults that might get computed
+ differently on the local server than they would be on the remote
+ server; <code class="function">nextval()</code> is a common source of problems.
+ The <code class="command">IMPORT</code> will fail altogether if an imported default
+ expression uses a function or operator that does not exist locally.
+ </p></dd><dt><span class="term"><code class="literal">import_generated</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether column <code class="literal">GENERATED</code> expressions
+ are included in the definitions of foreign tables imported
+ from a foreign server. The default is <code class="literal">true</code>.
+ The <code class="command">IMPORT</code> will fail altogether if an imported generated
+ expression uses a function or operator that does not exist locally.
+ </p></dd><dt><span class="term"><code class="literal">import_not_null</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether column <code class="literal">NOT NULL</code>
+ constraints are included in the definitions of foreign tables imported
+ from a foreign server. The default is <code class="literal">true</code>.
+ </p></dd></dl></div><p>
+ Note that constraints other than <code class="literal">NOT NULL</code> will never be
+ imported from the remote tables. Although <span class="productname">PostgreSQL</span>
+ does support check constraints on foreign tables, there is no
+ provision for importing them automatically, because of the risk that a
+ constraint expression could evaluate differently on the local and remote
+ servers. Any such inconsistency in the behavior of a check
+ constraint could lead to hard-to-detect errors in query optimization.
+ So if you wish to import check constraints, you must do so
+ manually, and you should verify the semantics of each one carefully.
+ For more detail about the treatment of check constraints on
+ foreign tables, see <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>.
+ </p><p>
+ Tables or foreign tables which are partitions of some other table are
+ imported only when they are explicitly specified in
+ <code class="literal">LIMIT TO</code> clause. Otherwise they are automatically
+ excluded from <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a>.
+ Since all data can be accessed through the partitioned table
+ which is the root of the partitioning hierarchy, importing only
+ partitioned tables should allow access to all the data without
+ creating extra objects.
+ </p></div><div class="sect3" id="id-1.11.7.47.11.11"><div class="titlepage"><div><div><h4 class="title">F.38.1.10. Connection Management Options</h4></div></div></div><p>
+ By default, all connections that <code class="filename">postgres_fdw</code>
+ establishes to foreign servers are kept open in the local session
+ for re-use.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">keep_connections</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option controls whether <code class="filename">postgres_fdw</code> keeps
+ the connections to the foreign server open so that subsequent
+ queries can re-use them. It can only be specified for a foreign server.
+ The default is <code class="literal">on</code>. If set to <code class="literal">off</code>,
+ all connections to this foreign server will be discarded at the end of
+ each transaction.
+ </p></dd></dl></div></div></div><div class="sect2" id="id-1.11.7.47.12"><div class="titlepage"><div><div><h3 class="title">F.38.2. Functions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record</code></span></dt><dd><p>
+ This function returns the foreign server names of all the open
+ connections that <code class="filename">postgres_fdw</code> established from
+ the local session to the foreign servers. It also returns whether
+ each connection is valid or not. <code class="literal">false</code> is returned
+ if the foreign server connection is used in the current local
+ transaction but its foreign server or user mapping is changed or
+ dropped (Note that server name of an invalid connection will be
+ <code class="literal">NULL</code> if the server is dropped),
+ and then such invalid connection will be closed at
+ the end of that transaction. <code class="literal">true</code> is returned
+ otherwise. If there are no open connections, no record is returned.
+ Example usage of the function:
+</p><pre class="screen">
+postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
+ server_name | valid
+-------------+-------
+ loopback1 | t
+ loopback2 | f
+</pre><p>
+ </p></dd><dt><span class="term"><code class="function">postgres_fdw_disconnect(server_name text) returns boolean</code></span></dt><dd><p>
+ This function discards the open connections that are established by
+ <code class="filename">postgres_fdw</code> from the local session to
+ the foreign server with the given name. Note that there can be
+ multiple connections to the given server using different user mappings.
+ If the connections are used in the current local transaction,
+ they are not disconnected and warning messages are reported.
+ This function returns <code class="literal">true</code> if it disconnects
+ at least one connection, otherwise <code class="literal">false</code>.
+ If no foreign server with the given name is found, an error is reported.
+ Example usage of the function:
+</p><pre class="screen">
+postgres=# SELECT postgres_fdw_disconnect('loopback1');
+ postgres_fdw_disconnect
+-------------------------
+ t
+</pre><p>
+ </p></dd><dt><span class="term"><code class="function">postgres_fdw_disconnect_all() returns boolean</code></span></dt><dd><p>
+ This function discards all the open connections that are established by
+ <code class="filename">postgres_fdw</code> from the local session to
+ foreign servers. If the connections are used in the current local
+ transaction, they are not disconnected and warning messages are reported.
+ This function returns <code class="literal">true</code> if it disconnects
+ at least one connection, otherwise <code class="literal">false</code>.
+ Example usage of the function:
+</p><pre class="screen">
+postgres=# SELECT postgres_fdw_disconnect_all();
+ postgres_fdw_disconnect_all
+-----------------------------
+ t
+</pre><p>
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.47.13"><div class="titlepage"><div><div><h3 class="title">F.38.3. Connection Management</h3></div></div></div><p>
+ <code class="filename">postgres_fdw</code> establishes a connection to a
+ foreign server during the first query that uses a foreign table
+ associated with the foreign server. By default this connection
+ is kept and re-used for subsequent queries in the same session.
+ This behavior can be controlled using
+ <code class="literal">keep_connections</code> option for a foreign server. If
+ multiple user identities (user mappings) are used to access the foreign
+ server, a connection is established for each user mapping.
+ </p><p>
+ When changing the definition of or removing a foreign server or
+ a user mapping, the associated connections are closed.
+ But note that if any connections are in use in the current local transaction,
+ they are kept until the end of the transaction.
+ Closed connections will be re-established when they are necessary
+ by future queries using a foreign table.
+ </p><p>
+ Once a connection to a foreign server has been established,
+ it's by default kept until the local or corresponding remote
+ session exits. To disconnect a connection explicitly,
+ <code class="literal">keep_connections</code> option for a foreign server
+ may be disabled, or
+ <code class="function">postgres_fdw_disconnect</code> and
+ <code class="function">postgres_fdw_disconnect_all</code> functions
+ may be used. For example, these are useful to close
+ connections that are no longer necessary, thereby releasing
+ connections on the foreign server.
+ </p></div><div class="sect2" id="id-1.11.7.47.14"><div class="titlepage"><div><div><h3 class="title">F.38.4. Transaction Management</h3></div></div></div><p>
+ During a query that references any remote tables on a foreign server,
+ <code class="filename">postgres_fdw</code> opens a transaction on the
+ remote server if one is not already open corresponding to the current
+ local transaction. The remote transaction is committed or aborted when
+ the local transaction commits or aborts. Savepoints are similarly
+ managed by creating corresponding remote savepoints.
+ </p><p>
+ The remote transaction uses <code class="literal">SERIALIZABLE</code>
+ isolation level when the local transaction has <code class="literal">SERIALIZABLE</code>
+ isolation level; otherwise it uses <code class="literal">REPEATABLE READ</code>
+ isolation level. This choice ensures that if a query performs multiple
+ table scans on the remote server, it will get snapshot-consistent results
+ for all the scans. A consequence is that successive queries within a
+ single transaction will see the same data from the remote server, even if
+ concurrent updates are occurring on the remote server due to other
+ activities. That behavior would be expected anyway if the local
+ transaction uses <code class="literal">SERIALIZABLE</code> or <code class="literal">REPEATABLE READ</code>
+ isolation level, but it might be surprising for a <code class="literal">READ
+ COMMITTED</code> local transaction. A future
+ <span class="productname">PostgreSQL</span> release might modify these rules.
+ </p><p>
+ Note that it is currently not supported by
+ <code class="filename">postgres_fdw</code> to prepare the remote transaction for
+ two-phase commit.
+ </p></div><div class="sect2" id="id-1.11.7.47.15"><div class="titlepage"><div><div><h3 class="title">F.38.5. Remote Query Optimization</h3></div></div></div><p>
+ <code class="filename">postgres_fdw</code> attempts to optimize remote queries to reduce
+ the amount of data transferred from foreign servers. This is done by
+ sending query <code class="literal">WHERE</code> clauses to the remote server for
+ execution, and by not retrieving table columns that are not needed for
+ the current query. To reduce the risk of misexecution of queries,
+ <code class="literal">WHERE</code> clauses are not sent to the remote server unless they use
+ only data types, operators, and functions that are built-in or belong to an
+ extension that's listed in the foreign server's <code class="literal">extensions</code>
+ option. Operators and functions in such clauses must
+ be <code class="literal">IMMUTABLE</code> as well.
+ For an <code class="command">UPDATE</code> or <code class="command">DELETE</code> query,
+ <code class="filename">postgres_fdw</code> attempts to optimize the query execution by
+ sending the whole query to the remote server if there are no query
+ <code class="literal">WHERE</code> clauses that cannot be sent to the remote server,
+ no local joins for the query, no row-level local <code class="literal">BEFORE</code> or
+ <code class="literal">AFTER</code> triggers or stored generated columns on the target
+ table, and no <code class="literal">CHECK OPTION</code> constraints from parent
+ views. In <code class="command">UPDATE</code>,
+ expressions to assign to target columns must use only built-in data types,
+ <code class="literal">IMMUTABLE</code> operators, or <code class="literal">IMMUTABLE</code> functions,
+ to reduce the risk of misexecution of the query.
+ </p><p>
+ When <code class="filename">postgres_fdw</code> encounters a join between foreign tables on
+ the same foreign server, it sends the entire join to the foreign server,
+ unless for some reason it believes that it will be more efficient to fetch
+ rows from each table individually, or unless the table references involved
+ are subject to different user mappings. While sending the <code class="literal">JOIN</code>
+ clauses, it takes the same precautions as mentioned above for the
+ <code class="literal">WHERE</code> clauses.
+ </p><p>
+ The query that is actually sent to the remote server for execution can
+ be examined using <code class="command">EXPLAIN VERBOSE</code>.
+ </p></div><div class="sect2" id="id-1.11.7.47.16"><div class="titlepage"><div><div><h3 class="title">F.38.6. Remote Query Execution Environment</h3></div></div></div><p>
+ In the remote sessions opened by <code class="filename">postgres_fdw</code>,
+ the <a class="xref" href="runtime-config-client.html#GUC-SEARCH-PATH">search_path</a> parameter is set to
+ just <code class="literal">pg_catalog</code>, so that only built-in objects are visible
+ without schema qualification. This is not an issue for queries
+ generated by <code class="filename">postgres_fdw</code> itself, because it always
+ supplies such qualification. However, this can pose a hazard for
+ functions that are executed on the remote server via triggers or rules
+ on remote tables. For example, if a remote table is actually a view,
+ any functions used in that view will be executed with the restricted
+ search path. It is recommended to schema-qualify all names in such
+ functions, or else attach <code class="literal">SET search_path</code> options
+ (see <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>) to such functions
+ to establish their expected search path environment.
+ </p><p>
+ <code class="filename">postgres_fdw</code> likewise establishes remote session settings
+ for various parameters:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> is set to <code class="literal">UTC</code>
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a> is set to <code class="literal">ISO</code>
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="runtime-config-client.html#GUC-INTERVALSTYLE">IntervalStyle</a> is set to <code class="literal">postgres</code>
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="runtime-config-client.html#GUC-EXTRA-FLOAT-DIGITS">extra_float_digits</a> is set to <code class="literal">3</code> for remote
+ servers 9.0 and newer and is set to <code class="literal">2</code> for older versions
+ </p></li></ul></div><p>
+ These are less likely to be problematic than <code class="varname">search_path</code>, but
+ can be handled with function <code class="literal">SET</code> options if the need arises.
+ </p><p>
+ It is <span class="emphasis"><em>not</em></span> recommended that you override this behavior by
+ changing the session-level settings of these parameters; that is likely
+ to cause <code class="filename">postgres_fdw</code> to malfunction.
+ </p></div><div class="sect2" id="id-1.11.7.47.17"><div class="titlepage"><div><div><h3 class="title">F.38.7. Cross-Version Compatibility</h3></div></div></div><p>
+ <code class="filename">postgres_fdw</code> can be used with remote servers dating back
+ to <span class="productname">PostgreSQL</span> 8.3. Read-only capability is available
+ back to 8.1. A limitation however is that <code class="filename">postgres_fdw</code>
+ generally assumes that immutable built-in functions and operators are
+ safe to send to the remote server for execution, if they appear in a
+ <code class="literal">WHERE</code> clause for a foreign table. Thus, a built-in
+ function that was added since the remote server's release might be sent
+ to it for execution, resulting in <span class="quote">“<span class="quote">function does not exist</span>”</span> or
+ a similar error. This type of failure can be worked around by
+ rewriting the query, for example by embedding the foreign table
+ reference in a sub-<code class="literal">SELECT</code> with <code class="literal">OFFSET 0</code> as an
+ optimization fence, and placing the problematic function or operator
+ outside the sub-<code class="literal">SELECT</code>.
+ </p></div><div class="sect2" id="id-1.11.7.47.18"><div class="titlepage"><div><div><h3 class="title">F.38.8. Configuration Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-PGFDW-APPLICATION-NAME"><span class="term">
+ <code class="varname">postgres_fdw.application_name</code> (<code class="type">string</code>)
+ <a id="id-1.11.7.47.18.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a value for <a class="xref" href="runtime-config-logging.html#GUC-APPLICATION-NAME">application_name</a>
+ configuration parameter used when <code class="filename">postgres_fdw</code>
+ establishes a connection to a foreign server. This overrides
+ <code class="varname">application_name</code> option of the server object.
+ Note that change of this parameter doesn't affect any existing
+ connections until they are re-established.
+ </p><p>
+ <code class="varname">postgres_fdw.application_name</code> can be any string
+ of any length and contain even non-ASCII characters. However when
+ it's passed to and used as <code class="varname">application_name</code>
+ in a foreign server, note that it will be truncated to less than
+ <code class="symbol">NAMEDATALEN</code> characters and anything other than
+ printable ASCII characters will be replaced with question
+ marks (<code class="literal">?</code>).
+ See <a class="xref" href="runtime-config-logging.html#GUC-APPLICATION-NAME">application_name</a> for details.
+ </p><p>
+ <code class="literal">%</code> characters begin <span class="quote">“<span class="quote">escape sequences</span>”</span>
+ that are replaced with status information as outlined below.
+ Unrecognized escapes are ignored. Other characters are copied straight
+ to the application name. Note that it's not allowed to specify a
+ plus/minus sign or a numeric literal after the <code class="literal">%</code>
+ and before the option, for alignment and padding.
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Escape</th><th>Effect</th></tr></thead><tbody><tr><td><code class="literal">%a</code></td><td>Application name on local server</td></tr><tr><td><code class="literal">%c</code></td><td>
+ Session ID on local server
+ (see <a class="xref" href="runtime-config-logging.html#GUC-LOG-LINE-PREFIX">log_line_prefix</a> for details)
+ </td></tr><tr><td><code class="literal">%C</code></td><td>
+ Cluster name on local server
+ (see <a class="xref" href="runtime-config-logging.html#GUC-CLUSTER-NAME">cluster_name</a> for details)
+ </td></tr><tr><td><code class="literal">%u</code></td><td>User name on local server</td></tr><tr><td><code class="literal">%d</code></td><td>Database name on local server</td></tr><tr><td><code class="literal">%p</code></td><td>Process ID of backend on local server</td></tr><tr><td><code class="literal">%%</code></td><td>Literal %</td></tr></tbody></table></div><p>
+ For example, suppose user <code class="literal">local_user</code> establishes
+ a connection from database <code class="literal">local_db</code> to
+ <code class="literal">foreign_db</code> as user <code class="literal">foreign_user</code>,
+ the setting <code class="literal">'db=%d, user=%u'</code> is replaced with
+ <code class="literal">'db=local_db, user=local_user'</code>.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.47.19"><div class="titlepage"><div><div><h3 class="title">F.38.9. Examples</h3></div></div></div><p>
+ Here is an example of creating a foreign table with
+ <code class="literal">postgres_fdw</code>. First install the extension:
+ </p><pre class="programlisting">
+CREATE EXTENSION postgres_fdw;
+</pre><p>
+ Then create a foreign server using <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>.
+ In this example we wish to connect to a <span class="productname">PostgreSQL</span> server
+ on host <code class="literal">192.83.123.89</code> listening on
+ port <code class="literal">5432</code>. The database to which the connection is made
+ is named <code class="literal">foreign_db</code> on the remote server:
+
+</p><pre class="programlisting">
+CREATE SERVER foreign_server
+ FOREIGN DATA WRAPPER postgres_fdw
+ OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db');
+</pre><p>
+ </p><p>
+ A user mapping, defined with <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>, is
+ needed as well to identify the role that will be used on the remote
+ server:
+
+</p><pre class="programlisting">
+CREATE USER MAPPING FOR local_user
+ SERVER foreign_server
+ OPTIONS (user 'foreign_user', password 'password');
+</pre><p>
+ </p><p>
+ Now it is possible to create a foreign table with
+ <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>. In this example we
+ wish to access the table named <code class="structname">some_schema.some_table</code>
+ on the remote server. The local name for it will
+ be <code class="structname">foreign_table</code>:
+
+</p><pre class="programlisting">
+CREATE FOREIGN TABLE foreign_table (
+ id integer NOT NULL,
+ data text
+)
+ SERVER foreign_server
+ OPTIONS (schema_name 'some_schema', table_name 'some_table');
+</pre><p>
+
+ It's essential that the data types and other properties of the columns
+ declared in <code class="command">CREATE FOREIGN TABLE</code> match the actual remote table.
+ Column names must match as well, unless you attach <code class="literal">column_name</code>
+ options to the individual columns to show how they are named in the remote
+ table.
+ In many cases, use of <a class="link" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><code class="command">IMPORT FOREIGN SCHEMA</code></a> is
+ preferable to constructing foreign table definitions manually.
+ </p></div><div class="sect2" id="id-1.11.7.47.20"><div class="titlepage"><div><div><h3 class="title">F.38.10. Author</h3></div></div></div><p>
+ Shigeru Hanada <code class="email">&lt;<a class="email" href="mailto:shigeru.hanada@gmail.com">shigeru.hanada@gmail.com</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pgwalinspect.html" title="F.37. pg_walinspect">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="seg.html" title="F.39. seg">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.37. pg_walinspect </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.39. seg</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/postgres-user.html b/doc/src/sgml/html/postgres-user.html
new file mode 100644
index 0000000..f81aa99
--- /dev/null
+++ b/doc/src/sgml/html/postgres-user.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.1. The PostgreSQL User Account</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime.html" title="Chapter 19. Server Setup and Operation" /><link rel="next" href="creating-cluster.html" title="19.2. Creating a Database Cluster" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.1. The <span class="productname">PostgreSQL</span> User Account</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime.html" title="Chapter 19. Server Setup and Operation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Next</a></td></tr></table><hr /></div><div class="sect1" id="POSTGRES-USER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.1. The <span class="productname">PostgreSQL</span> User Account</h2></div></div></div><a id="id-1.6.6.4.2" class="indexterm"></a><p>
+ As with any server daemon that is accessible to the outside world,
+ it is advisable to run <span class="productname">PostgreSQL</span> under a
+ separate user account. This user account should only own the data
+ that is managed by the server, and should not be shared with other
+ daemons. (For example, using the user <code class="literal">nobody</code> is a bad
+ idea.) In particular, it is advisable that this user account not own
+ the <span class="productname">PostgreSQL</span> executable files, to ensure
+ that a compromised server process could not modify those executables.
+ </p><p>
+ Pre-packaged versions of <span class="productname">PostgreSQL</span> will
+ typically create a suitable user account automatically during
+ package installation.
+ </p><p>
+ To add a Unix user account to your system, look for a command
+ <code class="command">useradd</code> or <code class="command">adduser</code>. The user
+ name <span class="systemitem">postgres</span> is often used, and is assumed
+ throughout this book, but you can use another name if you like.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime.html" title="Chapter 19. Server Setup and Operation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 19. Server Setup and Operation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.2. Creating a Database Cluster</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/predefined-roles.html b/doc/src/sgml/html/predefined-roles.html
new file mode 100644
index 0000000..16a530f
--- /dev/null
+++ b/doc/src/sgml/html/predefined-roles.html
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>22.5. Predefined Roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="role-removal.html" title="22.4. Dropping Roles" /><link rel="next" href="perm-functions.html" title="22.6. Function Security" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">22.5. Predefined Roles</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="role-removal.html" title="22.4. Dropping Roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><th width="60%" align="center">Chapter 22. Database Roles</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="perm-functions.html" title="22.6. Function Security">Next</a></td></tr></table><hr /></div><div class="sect1" id="PREDEFINED-ROLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">22.5. Predefined Roles</h2></div></div></div><a id="id-1.6.9.9.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides a set of predefined roles
+ that provide access to certain, commonly needed, privileged capabilities
+ and information. Administrators (including roles that have the
+ <code class="literal">CREATEROLE</code> privilege) can <code class="command">GRANT</code> these
+ roles to users and/or other roles in their environment, providing those
+ users with access to the specified capabilities and information.
+ </p><p>
+ The predefined roles are described in <a class="xref" href="predefined-roles.html#PREDEFINED-ROLES-TABLE" title="Table 22.1. Predefined Roles">Table 22.1</a>.
+ Note that the specific permissions for each of the roles may change in
+ the future as additional capabilities are added. Administrators
+ should monitor the release notes for changes.
+ </p><div class="table" id="PREDEFINED-ROLES-TABLE"><p class="title"><strong>Table 22.1. Predefined Roles</strong></p><div class="table-contents"><table class="table" summary="Predefined Roles" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Role</th><th>Allowed Access</th></tr></thead><tbody><tr><td>pg_read_all_data</td><td>Read all data (tables, views, sequences), as if having
+ <code class="command">SELECT</code> rights on those objects, and USAGE rights on
+ all schemas, even without having it explicitly. This role does not have
+ the role attribute <code class="literal">BYPASSRLS</code> set. If RLS is being
+ used, an administrator may wish to set <code class="literal">BYPASSRLS</code> on
+ roles which this role is GRANTed to.</td></tr><tr><td>pg_write_all_data</td><td>Write all data (tables, views, sequences), as if having
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> rights on those objects, and USAGE rights on
+ all schemas, even without having it explicitly. This role does not have
+ the role attribute <code class="literal">BYPASSRLS</code> set. If RLS is being
+ used, an administrator may wish to set <code class="literal">BYPASSRLS</code> on
+ roles which this role is GRANTed to.</td></tr><tr><td>pg_read_all_settings</td><td>Read all configuration variables, even those normally visible only to
+ superusers.</td></tr><tr><td>pg_read_all_stats</td><td>Read all pg_stat_* views and use various statistics related extensions,
+ even those normally visible only to superusers.</td></tr><tr><td>pg_stat_scan_tables</td><td>Execute monitoring functions that may take <code class="literal">ACCESS SHARE</code> locks on tables,
+ potentially for a long time.</td></tr><tr><td>pg_monitor</td><td>Read/execute various monitoring views and functions.
+ This role is a member of <code class="literal">pg_read_all_settings</code>,
+ <code class="literal">pg_read_all_stats</code> and
+ <code class="literal">pg_stat_scan_tables</code>.</td></tr><tr><td>pg_database_owner</td><td>None. Membership consists, implicitly, of the current database owner.</td></tr><tr><td>pg_signal_backend</td><td>Signal another backend to cancel a query or terminate its session.</td></tr><tr><td>pg_read_server_files</td><td>Allow reading files from any location the database can access on the server with COPY and
+ other file-access functions.</td></tr><tr><td>pg_write_server_files</td><td>Allow writing to files in any location the database can access on the server with COPY and
+ other file-access functions.</td></tr><tr><td>pg_execute_server_program</td><td>Allow executing programs on the database server as the user the database runs as with
+ COPY and other functions which allow executing a server-side program.</td></tr><tr><td>pg_checkpoint</td><td>Allow executing
+ the <a class="link" href="sql-checkpoint.html" title="CHECKPOINT"><code class="command">CHECKPOINT</code></a>
+ command.</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="literal">pg_monitor</code>, <code class="literal">pg_read_all_settings</code>,
+ <code class="literal">pg_read_all_stats</code> and <code class="literal">pg_stat_scan_tables</code>
+ roles are intended to allow administrators to easily configure a role for the
+ purpose of monitoring the database server. They grant a set of common privileges
+ allowing the role to read various useful configuration settings, statistics and
+ other system information normally restricted to superusers.
+ </p><p>
+ The <code class="literal">pg_database_owner</code> role has one implicit,
+ situation-dependent member, namely the owner of the current database. Like
+ any role, it can own objects or receive grants of access privileges.
+ Consequently, once <code class="literal">pg_database_owner</code> has rights within a
+ template database, each owner of a database instantiated from that template
+ will exercise those rights. <code class="literal">pg_database_owner</code> cannot be
+ a member of any role, and it cannot have non-implicit members. Initially,
+ this role owns the <code class="literal">public</code> schema, so each database owner
+ governs local use of the schema.
+ </p><p>
+ The <code class="literal">pg_signal_backend</code> role is intended to allow
+ administrators to enable trusted, but non-superuser, roles to send signals
+ to other backends. Currently this role enables sending of signals for
+ canceling a query on another backend or terminating its session. A user
+ granted this role cannot however send signals to a backend owned by a
+ superuser. See <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL" title="9.27.2. Server Signaling Functions">Section 9.27.2</a>.
+ </p><p>
+ The <code class="literal">pg_read_server_files</code>, <code class="literal">pg_write_server_files</code> and
+ <code class="literal">pg_execute_server_program</code> roles are intended to allow administrators to have
+ trusted, but non-superuser, roles which are able to access files and run programs on the
+ database server as the user the database runs as. As these roles are able to access any file on
+ the server file system, they bypass all database-level permission checks when accessing files
+ directly and they could be used to gain superuser-level access, therefore
+ great care should be taken when granting these roles to users.
+ </p><p>
+ Care should be taken when granting these roles to ensure they are only used where
+ needed and with the understanding that these roles grant access to privileged
+ information.
+ </p><p>
+ Administrators can grant access to these roles to users using the
+ <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> command, for example:
+
+</p><pre class="programlisting">
+GRANT pg_signal_backend TO admin_user;
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="role-removal.html" title="22.4. Dropping Roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="perm-functions.html" title="22.6. Function Security">Next</a></td></tr><tr><td width="40%" align="left" valign="top">22.4. Dropping Roles </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 22.6. Function Security</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/preface.html b/doc/src/sgml/html/preface.html
new file mode 100644
index 0000000..55e8f64
--- /dev/null
+++ b/doc/src/sgml/html/preface.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Preface</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="index.html" title="PostgreSQL 15.4 Documentation" /><link rel="next" href="intro-whatis.html" title="1.  What Is PostgreSQL?" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Preface</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="index.html" title="PostgreSQL 15.4 Documentation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="intro-whatis.html" title="1.  What Is PostgreSQL?">Next</a></td></tr></table><hr /></div><div class="preface" id="PREFACE"><div class="titlepage"><div><div><h1 class="title">Preface</h1></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="intro-whatis.html">1. What Is <span class="productname">PostgreSQL</span>?</a></span></dt><dt><span class="sect1"><a href="history.html">2. A Brief History of <span class="productname">PostgreSQL</span></a></span></dt><dd><dl><dt><span class="sect2"><a href="history.html#HISTORY-BERKELEY">2.1. The Berkeley <span class="productname">POSTGRES</span> Project</a></span></dt><dt><span class="sect2"><a href="history.html#HISTORY-POSTGRES95">2.2. <span class="productname">Postgres95</span></a></span></dt><dt><span class="sect2"><a href="history.html#id-1.3.5.6">2.3. <span class="productname">PostgreSQL</span></a></span></dt></dl></dd><dt><span class="sect1"><a href="notation.html">3. Conventions</a></span></dt><dt><span class="sect1"><a href="resources.html">4. Further Information</a></span></dt><dt><span class="sect1"><a href="bug-reporting.html">5. Bug Reporting Guidelines</a></span></dt><dd><dl><dt><span class="sect2"><a href="bug-reporting.html#id-1.3.8.5">5.1. Identifying Bugs</a></span></dt><dt><span class="sect2"><a href="bug-reporting.html#id-1.3.8.6">5.2. What to Report</a></span></dt><dt><span class="sect2"><a href="bug-reporting.html#id-1.3.8.7">5.3. Where to Report Bugs</a></span></dt></dl></dd></dl></div><p>
+ This book is the official documentation of
+ <span class="productname">PostgreSQL</span>. It has been written by the
+ <span class="productname">PostgreSQL</span> developers and other
+ volunteers in parallel to the development of the
+ <span class="productname">PostgreSQL</span> software. It describes all
+ the functionality that the current version of
+ <span class="productname">PostgreSQL</span> officially supports.
+ </p><p>
+ To make the large amount of information about
+ <span class="productname">PostgreSQL</span> manageable, this book has been
+ organized in several parts. Each part is targeted at a different
+ class of users, or at users in different stages of their
+ <span class="productname">PostgreSQL</span> experience:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="xref" href="tutorial.html" title="Part I. Tutorial">Part I</a> is an informal introduction for new users.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="sql.html" title="Part II. The SQL Language">Part II</a> documents the <acronym class="acronym">SQL</acronym> query
+ language environment, including data types and functions, as well
+ as user-level performance tuning. Every
+ <span class="productname">PostgreSQL</span> user should read this.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="admin.html" title="Part III. Server Administration">Part III</a> describes the installation and
+ administration of the server. Everyone who runs a
+ <span class="productname">PostgreSQL</span> server, be it for private
+ use or for others, should read this part.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="client-interfaces.html" title="Part IV. Client Interfaces">Part IV</a> describes the programming
+ interfaces for <span class="productname">PostgreSQL</span> client
+ programs.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="server-programming.html" title="Part V. Server Programming">Part V</a> contains information for
+ advanced users about the extensibility capabilities of the
+ server. Topics include user-defined data types and
+ functions.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="reference.html" title="Part VI. Reference">Part VI</a> contains reference information about
+ SQL commands, client and server programs. This part supports
+ the other parts with structured information sorted by command or
+ program.
+ </p></li><li class="listitem"><p>
+ <a class="xref" href="internals.html" title="Part VII. Internals">Part VII</a> contains assorted information that might be of
+ use to <span class="productname">PostgreSQL</span> developers.
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="index.html" title="PostgreSQL 15.4 Documentation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="intro-whatis.html" title="1.  What Is PostgreSQL?">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PostgreSQL 15.4 Documentation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 1.  What Is <span class="productname">PostgreSQL</span>?</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/preventing-server-spoofing.html b/doc/src/sgml/html/preventing-server-spoofing.html
new file mode 100644
index 0000000..8a88229
--- /dev/null
+++ b/doc/src/sgml/html/preventing-server-spoofing.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.7. Preventing Server Spoofing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster" /><link rel="next" href="encryption-options.html" title="19.8. Encryption Options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.7. Preventing Server Spoofing</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="encryption-options.html" title="19.8. Encryption Options">Next</a></td></tr></table><hr /></div><div class="sect1" id="PREVENTING-SERVER-SPOOFING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.7. Preventing Server Spoofing</h2></div></div></div><a id="id-1.6.6.10.2" class="indexterm"></a><p>
+ While the server is running, it is not possible for a malicious user
+ to take the place of the normal database server. However, when the
+ server is down, it is possible for a local user to spoof the normal
+ server by starting their own server. The spoof server could read
+ passwords and queries sent by clients, but could not return any data
+ because the <code class="varname">PGDATA</code> directory would still be secure because
+ of directory permissions. Spoofing is possible because any user can
+ start a database server; a client cannot identify an invalid server
+ unless it is specially configured.
+ </p><p>
+ One way to prevent spoofing of <code class="literal">local</code>
+ connections is to use a Unix domain socket directory (<a class="xref" href="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES">unix_socket_directories</a>) that has write permission only
+ for a trusted local user. This prevents a malicious user from creating
+ their own socket file in that directory. If you are concerned that
+ some applications might still reference <code class="filename">/tmp</code> for the
+ socket file and hence be vulnerable to spoofing, during operating system
+ startup create a symbolic link <code class="filename">/tmp/.s.PGSQL.5432</code> that points
+ to the relocated socket file. You also might need to modify your
+ <code class="filename">/tmp</code> cleanup script to prevent removal of the symbolic link.
+ </p><p>
+ Another option for <code class="literal">local</code> connections is for clients to use
+ <a class="link" href="libpq-connect.html#LIBPQ-CONNECT-REQUIREPEER"><code class="literal">requirepeer</code></a>
+ to specify the required owner of the server process connected to
+ the socket.
+ </p><p>
+ To prevent spoofing on TCP connections, either use
+ SSL certificates and make sure that clients check the server's certificate,
+ or use GSSAPI encryption (or both, if they're on separate connections).
+ </p><p>
+ To prevent spoofing with SSL, the server
+ must be configured to accept only <code class="literal">hostssl</code> connections (<a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a>) and have SSL key and certificate files
+ (<a class="xref" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Section 19.9</a>). The TCP client must connect using
+ <code class="literal">sslmode=verify-ca</code> or
+ <code class="literal">verify-full</code> and have the appropriate root certificate
+ file installed (<a class="xref" href="libpq-ssl.html#LIBQ-SSL-CERTIFICATES" title="34.19.1. Client Verification of Server Certificates">Section 34.19.1</a>).
+ </p><p>
+ To prevent spoofing with GSSAPI, the server must be configured to accept
+ only <code class="literal">hostgssenc</code> connections
+ (<a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a>) and use <code class="literal">gss</code>
+ authentication with them. The TCP client must connect
+ using <code class="literal">gssencmode=require</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="encryption-options.html" title="19.8. Encryption Options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.6. Upgrading a <span class="productname">PostgreSQL</span> Cluster </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.8. Encryption Options</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/progress-reporting.html b/doc/src/sgml/html/progress-reporting.html
new file mode 100644
index 0000000..6e84ac1
--- /dev/null
+++ b/doc/src/sgml/html/progress-reporting.html
@@ -0,0 +1,651 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>28.4. Progress Reporting</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="monitoring-locks.html" title="28.3. Viewing Locks" /><link rel="next" href="dynamic-trace.html" title="28.5. Dynamic Tracing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">28.4. Progress Reporting</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="monitoring-locks.html" title="28.3. Viewing Locks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><th width="60%" align="center">Chapter 28. Monitoring Database Activity</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="dynamic-trace.html" title="28.5. Dynamic Tracing">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROGRESS-REPORTING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">28.4. Progress Reporting</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="progress-reporting.html#ANALYZE-PROGRESS-REPORTING">28.4.1. ANALYZE Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING">28.4.2. CREATE INDEX Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#VACUUM-PROGRESS-REPORTING">28.4.3. VACUUM Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING">28.4.4. CLUSTER Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#BASEBACKUP-PROGRESS-REPORTING">28.4.5. Base Backup Progress Reporting</a></span></dt><dt><span class="sect2"><a href="progress-reporting.html#COPY-PROGRESS-REPORTING">28.4.6. COPY Progress Reporting</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> has the ability to report the progress of
+ certain commands during command execution. Currently, the only commands
+ which support progress reporting are <code class="command">ANALYZE</code>,
+ <code class="command">CLUSTER</code>,
+ <code class="command">CREATE INDEX</code>, <code class="command">VACUUM</code>,
+ <code class="command">COPY</code>,
+ and <a class="xref" href="protocol-replication.html#PROTOCOL-REPLICATION-BASE-BACKUP">BASE_BACKUP</a> (i.e., replication
+ command that <a class="xref" href="app-pgbasebackup.html" title="pg_basebackup"><span class="refentrytitle"><span class="application">pg_basebackup</span></span></a> issues to take
+ a base backup).
+ This may be expanded in the future.
+ </p><div class="sect2" id="ANALYZE-PROGRESS-REPORTING"><div class="titlepage"><div><div><h3 class="title">28.4.1. ANALYZE Progress Reporting</h3></div></div></div><a id="id-1.6.15.9.3.2" class="indexterm"></a><p>
+ Whenever <code class="command">ANALYZE</code> is running, the
+ <code class="structname">pg_stat_progress_analyze</code> view will contain a
+ row for each backend that is currently running that command. The tables
+ below describe the information that will be reported and provide
+ information about how to interpret it.
+ </p><div class="table" id="PG-STAT-PROGRESS-ANALYZE-VIEW"><p class="title"><strong>Table 28.36. <code class="structname">pg_stat_progress_analyze</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_progress_analyze View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of backend.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table being analyzed.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">phase</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current processing phase. See <a class="xref" href="progress-reporting.html#ANALYZE-PHASES" title="Table 28.37. ANALYZE Phases">Table 28.37</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sample_blks_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of heap blocks that will be sampled.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sample_blks_scanned</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of heap blocks scanned.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ext_stats_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of extended statistics.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ext_stats_computed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of extended statistics computed. This counter only advances
+ when the phase is <code class="literal">computing extended statistics</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">child_tables_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of child tables.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">child_tables_done</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of child tables scanned. This counter only advances when the
+ phase is <code class="literal">acquiring inherited sample rows</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">current_child_table_relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the child table currently being scanned. This field is
+ only valid when the phase is
+ <code class="literal">acquiring inherited sample rows</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="ANALYZE-PHASES"><p class="title"><strong>Table 28.37. ANALYZE Phases</strong></p><div class="table-contents"><table class="table" summary="ANALYZE Phases" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Phase</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">initializing</code></td><td>
+ The command is preparing to begin scanning the heap. This phase is
+ expected to be very brief.
+ </td></tr><tr><td><code class="literal">acquiring sample rows</code></td><td>
+ The command is currently scanning the table given by
+ <code class="structfield">relid</code> to obtain sample rows.
+ </td></tr><tr><td><code class="literal">acquiring inherited sample rows</code></td><td>
+ The command is currently scanning child tables to obtain sample rows.
+ Columns <code class="structfield">child_tables_total</code>,
+ <code class="structfield">child_tables_done</code>, and
+ <code class="structfield">current_child_table_relid</code> contain the
+ progress information for this phase.
+ </td></tr><tr><td><code class="literal">computing statistics</code></td><td>
+ The command is computing statistics from the sample rows obtained
+ during the table scan.
+ </td></tr><tr><td><code class="literal">computing extended statistics</code></td><td>
+ The command is computing extended statistics from the sample rows
+ obtained during the table scan.
+ </td></tr><tr><td><code class="literal">finalizing analyze</code></td><td>
+ The command is updating <code class="structname">pg_class</code>. When this
+ phase is completed, <code class="command">ANALYZE</code> will end.
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ Note that when <code class="command">ANALYZE</code> is run on a partitioned table,
+ all of its partitions are also recursively analyzed.
+ In that case, <code class="command">ANALYZE</code>
+ progress is reported first for the parent table, whereby its inheritance
+ statistics are collected, followed by that for each partition.
+ </p></div></div><div class="sect2" id="CREATE-INDEX-PROGRESS-REPORTING"><div class="titlepage"><div><div><h3 class="title">28.4.2. CREATE INDEX Progress Reporting</h3></div></div></div><a id="id-1.6.15.9.4.2" class="indexterm"></a><p>
+ Whenever <code class="command">CREATE INDEX</code> or <code class="command">REINDEX</code> is running, the
+ <code class="structname">pg_stat_progress_create_index</code> view will contain
+ one row for each backend that is currently creating indexes. The tables
+ below describe the information that will be reported and provide information
+ about how to interpret it.
+ </p><div class="table" id="PG-STAT-PROGRESS-CREATE-INDEX-VIEW"><p class="title"><strong>Table 28.38. <code class="structname">pg_stat_progress_create_index</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_progress_create_index View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of backend.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table on which the index is being created.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">index_relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the index being created or reindexed. During a
+ non-concurrent <code class="command">CREATE INDEX</code>, this is 0.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">command</code> <code class="type">text</code>
+ </p>
+ <p>
+ The command that is running: <code class="literal">CREATE INDEX</code>,
+ <code class="literal">CREATE INDEX CONCURRENTLY</code>,
+ <code class="literal">REINDEX</code>, or <code class="literal">REINDEX CONCURRENTLY</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">phase</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current processing phase of index creation. See <a class="xref" href="progress-reporting.html#CREATE-INDEX-PHASES" title="Table 28.39. CREATE INDEX Phases">Table 28.39</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lockers_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of lockers to wait for, when applicable.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">lockers_done</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of lockers already waited for.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">current_locker_pid</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Process ID of the locker currently being waited for.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blocks_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of blocks to be processed in the current phase.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">blocks_done</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of blocks already processed in the current phase.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tuples_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of tuples to be processed in the current phase.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tuples_done</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of tuples already processed in the current phase.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partitions_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ When creating an index on a partitioned table, this column is set to
+ the total number of partitions on which the index is to be created.
+ This field is <code class="literal">0</code> during a <code class="literal">REINDEX</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">partitions_done</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ When creating an index on a partitioned table, this column is set to
+ the number of partitions on which the index has been created.
+ This field is <code class="literal">0</code> during a <code class="literal">REINDEX</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="CREATE-INDEX-PHASES"><p class="title"><strong>Table 28.39. CREATE INDEX Phases</strong></p><div class="table-contents"><table class="table" summary="CREATE INDEX Phases" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Phase</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">initializing</code></td><td>
+ <code class="command">CREATE INDEX</code> or <code class="command">REINDEX</code> is preparing to create the index. This
+ phase is expected to be very brief.
+ </td></tr><tr><td><code class="literal">waiting for writers before build</code></td><td>
+ <code class="command">CREATE INDEX CONCURRENTLY</code> or <code class="command">REINDEX CONCURRENTLY</code> is waiting for transactions
+ with write locks that can potentially see the table to finish.
+ This phase is skipped when not in concurrent mode.
+ Columns <code class="structname">lockers_total</code>, <code class="structname">lockers_done</code>
+ and <code class="structname">current_locker_pid</code> contain the progress
+ information for this phase.
+ </td></tr><tr><td><code class="literal">building index</code></td><td>
+ The index is being built by the access method-specific code. In this phase,
+ access methods that support progress reporting fill in their own progress data,
+ and the subphase is indicated in this column. Typically,
+ <code class="structname">blocks_total</code> and <code class="structname">blocks_done</code>
+ will contain progress data, as well as potentially
+ <code class="structname">tuples_total</code> and <code class="structname">tuples_done</code>.
+ </td></tr><tr><td><code class="literal">waiting for writers before validation</code></td><td>
+ <code class="command">CREATE INDEX CONCURRENTLY</code> or <code class="command">REINDEX CONCURRENTLY</code> is waiting for transactions
+ with write locks that can potentially write into the table to finish.
+ This phase is skipped when not in concurrent mode.
+ Columns <code class="structname">lockers_total</code>, <code class="structname">lockers_done</code>
+ and <code class="structname">current_locker_pid</code> contain the progress
+ information for this phase.
+ </td></tr><tr><td><code class="literal">index validation: scanning index</code></td><td>
+ <code class="command">CREATE INDEX CONCURRENTLY</code> is scanning the index searching
+ for tuples that need to be validated.
+ This phase is skipped when not in concurrent mode.
+ Columns <code class="structname">blocks_total</code> (set to the total size of the index)
+ and <code class="structname">blocks_done</code> contain the progress information for this phase.
+ </td></tr><tr><td><code class="literal">index validation: sorting tuples</code></td><td>
+ <code class="command">CREATE INDEX CONCURRENTLY</code> is sorting the output of the
+ index scanning phase.
+ </td></tr><tr><td><code class="literal">index validation: scanning table</code></td><td>
+ <code class="command">CREATE INDEX CONCURRENTLY</code> is scanning the table
+ to validate the index tuples collected in the previous two phases.
+ This phase is skipped when not in concurrent mode.
+ Columns <code class="structname">blocks_total</code> (set to the total size of the table)
+ and <code class="structname">blocks_done</code> contain the progress information for this phase.
+ </td></tr><tr><td><code class="literal">waiting for old snapshots</code></td><td>
+ <code class="command">CREATE INDEX CONCURRENTLY</code> or <code class="command">REINDEX CONCURRENTLY</code> is waiting for transactions
+ that can potentially see the table to release their snapshots. This
+ phase is skipped when not in concurrent mode.
+ Columns <code class="structname">lockers_total</code>, <code class="structname">lockers_done</code>
+ and <code class="structname">current_locker_pid</code> contain the progress
+ information for this phase.
+ </td></tr><tr><td><code class="literal">waiting for readers before marking dead</code></td><td>
+ <code class="command">REINDEX CONCURRENTLY</code> is waiting for transactions
+ with read locks on the table to finish, before marking the old index dead.
+ This phase is skipped when not in concurrent mode.
+ Columns <code class="structname">lockers_total</code>, <code class="structname">lockers_done</code>
+ and <code class="structname">current_locker_pid</code> contain the progress
+ information for this phase.
+ </td></tr><tr><td><code class="literal">waiting for readers before dropping</code></td><td>
+ <code class="command">REINDEX CONCURRENTLY</code> is waiting for transactions
+ with read locks on the table to finish, before dropping the old index.
+ This phase is skipped when not in concurrent mode.
+ Columns <code class="structname">lockers_total</code>, <code class="structname">lockers_done</code>
+ and <code class="structname">current_locker_pid</code> contain the progress
+ information for this phase.
+ </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="VACUUM-PROGRESS-REPORTING"><div class="titlepage"><div><div><h3 class="title">28.4.3. VACUUM Progress Reporting</h3></div></div></div><a id="id-1.6.15.9.5.2" class="indexterm"></a><p>
+ Whenever <code class="command">VACUUM</code> is running, the
+ <code class="structname">pg_stat_progress_vacuum</code> view will contain
+ one row for each backend (including autovacuum worker processes) that is
+ currently vacuuming. The tables below describe the information
+ that will be reported and provide information about how to interpret it.
+ Progress for <code class="command">VACUUM FULL</code> commands is reported via
+ <code class="structname">pg_stat_progress_cluster</code>
+ because both <code class="command">VACUUM FULL</code> and <code class="command">CLUSTER</code>
+ rewrite the table, while regular <code class="command">VACUUM</code> only modifies it
+ in place. See <a class="xref" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING" title="28.4.4. CLUSTER Progress Reporting">Section 28.4.4</a>.
+ </p><div class="table" id="PG-STAT-PROGRESS-VACUUM-VIEW"><p class="title"><strong>Table 28.40. <code class="structname">pg_stat_progress_vacuum</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_progress_vacuum View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of backend.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table being vacuumed.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">phase</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current processing phase of vacuum. See <a class="xref" href="progress-reporting.html#VACUUM-PHASES" title="Table 28.41. VACUUM Phases">Table 28.41</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of heap blocks in the table. This number is reported
+ as of the beginning of the scan; blocks added later will not be (and
+ need not be) visited by this <code class="command">VACUUM</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_scanned</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of heap blocks scanned. Because the
+ <a class="link" href="storage-vm.html" title="73.4. Visibility Map">visibility map</a> is used to optimize scans,
+ some blocks will be skipped without inspection; skipped blocks are
+ included in this total, so that this number will eventually become
+ equal to <code class="structfield">heap_blks_total</code> when the vacuum is complete.
+ This counter only advances when the phase is <code class="literal">scanning heap</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_vacuumed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of heap blocks vacuumed. Unless the table has no indexes, this
+ counter only advances when the phase is <code class="literal">vacuuming heap</code>.
+ Blocks that contain no dead tuples are skipped, so the counter may
+ sometimes skip forward in large increments.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">index_vacuum_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of completed index vacuum cycles.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">max_dead_tuples</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of dead tuples that we can store before needing to perform
+ an index vacuum cycle, based on
+ <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">num_dead_tuples</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of dead tuples collected since the last index vacuum cycle.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="VACUUM-PHASES"><p class="title"><strong>Table 28.41. VACUUM Phases</strong></p><div class="table-contents"><table class="table" summary="VACUUM Phases" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Phase</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">initializing</code></td><td>
+ <code class="command">VACUUM</code> is preparing to begin scanning the heap. This
+ phase is expected to be very brief.
+ </td></tr><tr><td><code class="literal">scanning heap</code></td><td>
+ <code class="command">VACUUM</code> is currently scanning the heap. It will prune and
+ defragment each page if required, and possibly perform freezing
+ activity. The <code class="structfield">heap_blks_scanned</code> column can be used
+ to monitor the progress of the scan.
+ </td></tr><tr><td><code class="literal">vacuuming indexes</code></td><td>
+ <code class="command">VACUUM</code> is currently vacuuming the indexes. If a table has
+ any indexes, this will happen at least once per vacuum, after the heap
+ has been completely scanned. It may happen multiple times per vacuum
+ if <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a> (or, in the case of autovacuum,
+ <a class="xref" href="runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM">autovacuum_work_mem</a> if set) is insufficient to store
+ the number of dead tuples found.
+ </td></tr><tr><td><code class="literal">vacuuming heap</code></td><td>
+ <code class="command">VACUUM</code> is currently vacuuming the heap. Vacuuming the heap
+ is distinct from scanning the heap, and occurs after each instance of
+ vacuuming indexes. If <code class="structfield">heap_blks_scanned</code> is less than
+ <code class="structfield">heap_blks_total</code>, the system will return to scanning
+ the heap after this phase is completed; otherwise, it will begin
+ cleaning up indexes after this phase is completed.
+ </td></tr><tr><td><code class="literal">cleaning up indexes</code></td><td>
+ <code class="command">VACUUM</code> is currently cleaning up indexes. This occurs after
+ the heap has been completely scanned and all vacuuming of the indexes
+ and the heap has been completed.
+ </td></tr><tr><td><code class="literal">truncating heap</code></td><td>
+ <code class="command">VACUUM</code> is currently truncating the heap so as to return
+ empty pages at the end of the relation to the operating system. This
+ occurs after cleaning up indexes.
+ </td></tr><tr><td><code class="literal">performing final cleanup</code></td><td>
+ <code class="command">VACUUM</code> is performing final cleanup. During this phase,
+ <code class="command">VACUUM</code> will vacuum the free space map, update statistics
+ in <code class="literal">pg_class</code>, and report statistics to the cumulative
+ statistics system. When this phase is completed, <code class="command">VACUUM</code> will end.
+ </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="CLUSTER-PROGRESS-REPORTING"><div class="titlepage"><div><div><h3 class="title">28.4.4. CLUSTER Progress Reporting</h3></div></div></div><a id="id-1.6.15.9.6.2" class="indexterm"></a><p>
+ Whenever <code class="command">CLUSTER</code> or <code class="command">VACUUM FULL</code> is
+ running, the <code class="structname">pg_stat_progress_cluster</code> view will
+ contain a row for each backend that is currently running either command.
+ The tables below describe the information that will be reported and
+ provide information about how to interpret it.
+ </p><div class="table" id="PG-STAT-PROGRESS-CLUSTER-VIEW"><p class="title"><strong>Table 28.42. <code class="structname">pg_stat_progress_cluster</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_progress_cluster View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of backend.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table being clustered.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">command</code> <code class="type">text</code>
+ </p>
+ <p>
+ The command that is running. Either <code class="literal">CLUSTER</code> or <code class="literal">VACUUM FULL</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">phase</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current processing phase. See <a class="xref" href="progress-reporting.html#CLUSTER-PHASES" title="Table 28.43. CLUSTER and VACUUM FULL Phases">Table 28.43</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cluster_index_relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ If the table is being scanned using an index, this is the OID of the
+ index being used; otherwise, it is zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_tuples_scanned</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of heap tuples scanned.
+ This counter only advances when the phase is
+ <code class="literal">seq scanning heap</code>,
+ <code class="literal">index scanning heap</code>
+ or <code class="literal">writing new heap</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_tuples_written</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of heap tuples written.
+ This counter only advances when the phase is
+ <code class="literal">seq scanning heap</code>,
+ <code class="literal">index scanning heap</code>
+ or <code class="literal">writing new heap</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of heap blocks in the table. This number is reported
+ as of the beginning of <code class="literal">seq scanning heap</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">heap_blks_scanned</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of heap blocks scanned. This counter only advances when the
+ phase is <code class="literal">seq scanning heap</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">index_rebuild_count</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of indexes rebuilt. This counter only advances when the phase
+ is <code class="literal">rebuilding index</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="CLUSTER-PHASES"><p class="title"><strong>Table 28.43. CLUSTER and VACUUM FULL Phases</strong></p><div class="table-contents"><table class="table" summary="CLUSTER and VACUUM FULL Phases" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Phase</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">initializing</code></td><td>
+ The command is preparing to begin scanning the heap. This phase is
+ expected to be very brief.
+ </td></tr><tr><td><code class="literal">seq scanning heap</code></td><td>
+ The command is currently scanning the table using a sequential scan.
+ </td></tr><tr><td><code class="literal">index scanning heap</code></td><td>
+ <code class="command">CLUSTER</code> is currently scanning the table using an index scan.
+ </td></tr><tr><td><code class="literal">sorting tuples</code></td><td>
+ <code class="command">CLUSTER</code> is currently sorting tuples.
+ </td></tr><tr><td><code class="literal">writing new heap</code></td><td>
+ <code class="command">CLUSTER</code> is currently writing the new heap.
+ </td></tr><tr><td><code class="literal">swapping relation files</code></td><td>
+ The command is currently swapping newly-built files into place.
+ </td></tr><tr><td><code class="literal">rebuilding index</code></td><td>
+ The command is currently rebuilding an index.
+ </td></tr><tr><td><code class="literal">performing final cleanup</code></td><td>
+ The command is performing final cleanup. When this phase is
+ completed, <code class="command">CLUSTER</code>
+ or <code class="command">VACUUM FULL</code> will end.
+ </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="BASEBACKUP-PROGRESS-REPORTING"><div class="titlepage"><div><div><h3 class="title">28.4.5. Base Backup Progress Reporting</h3></div></div></div><a id="id-1.6.15.9.7.2" class="indexterm"></a><p>
+ Whenever an application like <span class="application">pg_basebackup</span>
+ is taking a base backup, the
+ <code class="structname">pg_stat_progress_basebackup</code>
+ view will contain a row for each WAL sender process that is currently
+ running the <code class="command">BASE_BACKUP</code> replication command
+ and streaming the backup. The tables below describe the information
+ that will be reported and provide information about how to interpret it.
+ </p><div class="table" id="PG-STAT-PROGRESS-BASEBACKUP-VIEW"><p class="title"><strong>Table 28.44. <code class="structname">pg_stat_progress_basebackup</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_progress_basebackup View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of a WAL sender process.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">phase</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current processing phase. See <a class="xref" href="progress-reporting.html#BASEBACKUP-PHASES" title="Table 28.45. Base Backup Phases">Table 28.45</a>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backup_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total amount of data that will be streamed. This is estimated and
+ reported as of the beginning of
+ <code class="literal">streaming database files</code> phase. Note that
+ this is only an approximation since the database
+ may change during <code class="literal">streaming database files</code> phase
+ and WAL log may be included in the backup later. This is always
+ the same value as <code class="structfield">backup_streamed</code>
+ once the amount of data streamed exceeds the estimated
+ total size. If the estimation is disabled in
+ <span class="application">pg_basebackup</span>
+ (i.e., <code class="literal">--no-estimate-size</code> option is specified),
+ this is <code class="literal">NULL</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">backup_streamed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Amount of data streamed. This counter only advances
+ when the phase is <code class="literal">streaming database files</code> or
+ <code class="literal">transferring wal files</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablespaces_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Total number of tablespaces that will be streamed.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablespaces_streamed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of tablespaces streamed. This counter only
+ advances when the phase is <code class="literal">streaming database files</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="BASEBACKUP-PHASES"><p class="title"><strong>Table 28.45. Base Backup Phases</strong></p><div class="table-contents"><table class="table" summary="Base Backup Phases" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Phase</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">initializing</code></td><td>
+ The WAL sender process is preparing to begin the backup.
+ This phase is expected to be very brief.
+ </td></tr><tr><td><code class="literal">waiting for checkpoint to finish</code></td><td>
+ The WAL sender process is currently performing
+ <code class="function">pg_backup_start</code> to prepare to
+ take a base backup, and waiting for the start-of-backup
+ checkpoint to finish.
+ </td></tr><tr><td><code class="literal">estimating backup size</code></td><td>
+ The WAL sender process is currently estimating the total amount
+ of database files that will be streamed as a base backup.
+ </td></tr><tr><td><code class="literal">streaming database files</code></td><td>
+ The WAL sender process is currently streaming database files
+ as a base backup.
+ </td></tr><tr><td><code class="literal">waiting for wal archiving to finish</code></td><td>
+ The WAL sender process is currently performing
+ <code class="function">pg_backup_stop</code> to finish the backup,
+ and waiting for all the WAL files required for the base backup
+ to be successfully archived.
+ If either <code class="literal">--wal-method=none</code> or
+ <code class="literal">--wal-method=stream</code> is specified in
+ <span class="application">pg_basebackup</span>, the backup will end
+ when this phase is completed.
+ </td></tr><tr><td><code class="literal">transferring wal files</code></td><td>
+ The WAL sender process is currently transferring all WAL logs
+ generated during the backup. This phase occurs after
+ <code class="literal">waiting for wal archiving to finish</code> phase if
+ <code class="literal">--wal-method=fetch</code> is specified in
+ <span class="application">pg_basebackup</span>. The backup will end
+ when this phase is completed.
+ </td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="COPY-PROGRESS-REPORTING"><div class="titlepage"><div><div><h3 class="title">28.4.6. COPY Progress Reporting</h3></div></div></div><a id="id-1.6.15.9.8.2" class="indexterm"></a><p>
+ Whenever <code class="command">COPY</code> is running, the
+ <code class="structname">pg_stat_progress_copy</code> view will contain one row
+ for each backend that is currently running a <code class="command">COPY</code> command.
+ The table below describes the information that will be reported and provides
+ information about how to interpret it.
+ </p><div class="table" id="PG-STAT-PROGRESS-COPY-VIEW"><p class="title"><strong>Table 28.46. <code class="structname">pg_stat_progress_copy</code> View</strong></p><div class="table-contents"><table class="table" summary="pg_stat_progress_copy View" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">integer</code>
+ </p>
+ <p>
+ Process ID of backend.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the database to which this backend is connected.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ OID of the table on which the <code class="command">COPY</code> command is
+ executed. It is set to <code class="literal">0</code> if copying from a
+ <code class="command">SELECT</code> query.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">command</code> <code class="type">text</code>
+ </p>
+ <p>
+ The command that is running: <code class="literal">COPY FROM</code>, or
+ <code class="literal">COPY TO</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">type</code> <code class="type">text</code>
+ </p>
+ <p>
+ The io type that the data is read from or written to:
+ <code class="literal">FILE</code>, <code class="literal">PROGRAM</code>,
+ <code class="literal">PIPE</code> (for <code class="command">COPY FROM STDIN</code> and
+ <code class="command">COPY TO STDOUT</code>), or <code class="literal">CALLBACK</code>
+ (used for example during the initial table synchronization in
+ logical replication).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">bytes_processed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of bytes already processed by <code class="command">COPY</code> command.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">bytes_total</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Size of source file for <code class="command">COPY FROM</code> command in bytes.
+ It is set to <code class="literal">0</code> if not available.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tuples_processed</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of tuples already processed by <code class="command">COPY</code> command.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tuples_excluded</code> <code class="type">bigint</code>
+ </p>
+ <p>
+ Number of tuples not processed because they were excluded by the
+ <code class="command">WHERE</code> clause of the <code class="command">COPY</code> command.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="monitoring-locks.html" title="28.3. Viewing Locks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="dynamic-trace.html" title="28.5. Dynamic Tracing">Next</a></td></tr><tr><td width="40%" align="left" valign="top">28.3. Viewing Locks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 28.5. Dynamic Tracing</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-changes.html b/doc/src/sgml/html/protocol-changes.html
new file mode 100644
index 0000000..914fdba
--- /dev/null
+++ b/doc/src/sgml/html/protocol-changes.html
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.10. Summary of Changes since Protocol 2.0</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats" /><link rel="next" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.10. Summary of Changes since Protocol 2.0</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-CHANGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.10. Summary of Changes since Protocol 2.0</h2></div></div></div><p>
+ This section provides a quick checklist of changes, for the benefit of
+ developers trying to update existing client libraries to protocol 3.0.
+ </p><p>
+ The initial startup packet uses a flexible list-of-strings format
+ instead of a fixed format. Notice that session default values for run-time
+ parameters can now be specified directly in the startup packet. (Actually,
+ you could do that before using the <code class="literal">options</code> field, but given the
+ limited width of <code class="literal">options</code> and the lack of any way to quote
+ whitespace in the values, it wasn't a very safe technique.)
+ </p><p>
+ All messages now have a length count immediately following the message type
+ byte (except for startup packets, which have no type byte). Also note that
+ PasswordMessage now has a type byte.
+ </p><p>
+ ErrorResponse and NoticeResponse ('<code class="literal">E</code>' and '<code class="literal">N</code>')
+ messages now contain multiple fields, from which the client code can
+ assemble an error message of the desired level of verbosity. Note that
+ individual fields will typically not end with a newline, whereas the single
+ string sent in the older protocol always did.
+ </p><p>
+ The ReadyForQuery ('<code class="literal">Z</code>') message includes a transaction status
+ indicator.
+ </p><p>
+ The distinction between BinaryRow and DataRow message types is gone; the
+ single DataRow message type serves for returning data in all formats.
+ Note that the layout of DataRow has changed to make it easier to parse.
+ Also, the representation of binary values has changed: it is no longer
+ directly tied to the server's internal representation.
+ </p><p>
+ There is a new <span class="quote">“<span class="quote">extended query</span>”</span> sub-protocol, which adds the frontend
+ message types Parse, Bind, Execute, Describe, Close, Flush, and Sync, and the
+ backend message types ParseComplete, BindComplete, PortalSuspended,
+ ParameterDescription, NoData, and CloseComplete. Existing clients do not
+ have to concern themselves with this sub-protocol, but making use of it
+ might allow improvements in performance or functionality.
+ </p><p>
+ <code class="command">COPY</code> data is now encapsulated into CopyData and CopyDone messages. There
+ is a well-defined way to recover from errors during <code class="command">COPY</code>. The special
+ <span class="quote">“<span class="quote"><code class="literal">\.</code></span>”</span> last line is not needed anymore, and is not sent
+ during <code class="command">COPY OUT</code>.
+ (It is still recognized as a terminator during <code class="command">COPY IN</code>, but its use is
+ deprecated and will eventually be removed.) Binary <code class="command">COPY</code> is supported.
+ The CopyInResponse and CopyOutResponse messages include fields indicating
+ the number of columns and the format of each column.
+ </p><p>
+ The layout of FunctionCall and FunctionCallResponse messages has changed.
+ FunctionCall can now support passing NULL arguments to functions. It also
+ can handle passing parameters and retrieving results in either text or
+ binary format. There is no longer any reason to consider FunctionCall a
+ potential security hole, since it does not offer direct access to internal
+ server data representations.
+ </p><p>
+ The backend sends ParameterStatus ('<code class="literal">S</code>') messages during connection
+ startup for all parameters it considers interesting to the client library.
+ Subsequently, a ParameterStatus message is sent whenever the active value
+ changes for any of these parameters.
+ </p><p>
+ The RowDescription ('<code class="literal">T</code>') message carries new table OID and column
+ number fields for each column of the described row. It also shows the format
+ code for each column.
+ </p><p>
+ The CursorResponse ('<code class="literal">P</code>') message is no longer generated by
+ the backend.
+ </p><p>
+ The NotificationResponse ('<code class="literal">A</code>') message has an additional string
+ field, which can carry a <span class="quote">“<span class="quote">payload</span>”</span> string passed
+ from the <code class="command">NOTIFY</code> event sender.
+ </p><p>
+ The EmptyQueryResponse ('<code class="literal">I</code>') message used to include an empty
+ string parameter; this has been removed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.9. Logical Replication Message Formats </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 56. PostgreSQL Coding Conventions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-error-fields.html b/doc/src/sgml/html/protocol-error-fields.html
new file mode 100644
index 0000000..d7e54ec
--- /dev/null
+++ b/doc/src/sgml/html/protocol-error-fields.html
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.8. Error and Notice Message Fields</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-message-formats.html" title="55.7. Message Formats" /><link rel="next" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.8. Error and Notice Message Fields</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-message-formats.html" title="55.7. Message Formats">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-ERROR-FIELDS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.8. Error and Notice Message Fields</h2></div></div></div><p>
+ This section describes the fields that can appear in ErrorResponse and
+ NoticeResponse messages. Each field type has a single-byte identification
+ token. Note that any given field type should appear at most once per
+ message.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">S</code></span></dt><dd><p>
+ Severity: the field contents are
+ <code class="literal">ERROR</code>, <code class="literal">FATAL</code>, or
+ <code class="literal">PANIC</code> (in an error message), or
+ <code class="literal">WARNING</code>, <code class="literal">NOTICE</code>, <code class="literal">DEBUG</code>,
+ <code class="literal">INFO</code>, or <code class="literal">LOG</code> (in a notice message),
+ or a localized translation of one of these. Always present.
+ </p></dd><dt><span class="term"><code class="literal">V</code></span></dt><dd><p>
+ Severity: the field contents are
+ <code class="literal">ERROR</code>, <code class="literal">FATAL</code>, or
+ <code class="literal">PANIC</code> (in an error message), or
+ <code class="literal">WARNING</code>, <code class="literal">NOTICE</code>, <code class="literal">DEBUG</code>,
+ <code class="literal">INFO</code>, or <code class="literal">LOG</code> (in a notice message).
+ This is identical to the <code class="literal">S</code> field except
+ that the contents are never localized. This is present only in
+ messages generated by <span class="productname">PostgreSQL</span> versions 9.6
+ and later.
+ </p></dd><dt><span class="term"><code class="literal">C</code></span></dt><dd><p>
+ Code: the SQLSTATE code for the error (see <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>). Not localizable. Always present.
+ </p></dd><dt><span class="term"><code class="literal">M</code></span></dt><dd><p>
+ Message: the primary human-readable error message.
+ This should be accurate but terse (typically one line).
+ Always present.
+ </p></dd><dt><span class="term"><code class="literal">D</code></span></dt><dd><p>
+ Detail: an optional secondary error message carrying more
+ detail about the problem. Might run to multiple lines.
+ </p></dd><dt><span class="term"><code class="literal">H</code></span></dt><dd><p>
+ Hint: an optional suggestion what to do about the problem.
+ This is intended to differ from Detail in that it offers advice
+ (potentially inappropriate) rather than hard facts.
+ Might run to multiple lines.
+ </p></dd><dt><span class="term"><code class="literal">P</code></span></dt><dd><p>
+ Position: the field value is a decimal ASCII integer, indicating
+ an error cursor position as an index into the original query string.
+ The first character has index 1, and positions are measured in
+ characters not bytes.
+ </p></dd><dt><span class="term"><code class="literal">p</code></span></dt><dd><p>
+ Internal position: this is defined the same as the <code class="literal">P</code>
+ field, but it is used when the cursor position refers to an internally
+ generated command rather than the one submitted by the client.
+ The <code class="literal">q</code> field will always appear when this field appears.
+ </p></dd><dt><span class="term"><code class="literal">q</code></span></dt><dd><p>
+ Internal query: the text of a failed internally-generated command.
+ This could be, for example, an SQL query issued by a PL/pgSQL function.
+ </p></dd><dt><span class="term"><code class="literal">W</code></span></dt><dd><p>
+ Where: an indication of the context in which the error occurred.
+ Presently this includes a call stack traceback of active
+ procedural language functions and internally-generated queries.
+ The trace is one entry per line, most recent first.
+ </p></dd><dt><span class="term"><code class="literal">s</code></span></dt><dd><p>
+ Schema name: if the error was associated with a specific database
+ object, the name of the schema containing that object, if any.
+ </p></dd><dt><span class="term"><code class="literal">t</code></span></dt><dd><p>
+ Table name: if the error was associated with a specific table, the
+ name of the table. (Refer to the schema name field for the name of
+ the table's schema.)
+ </p></dd><dt><span class="term"><code class="literal">c</code></span></dt><dd><p>
+ Column name: if the error was associated with a specific table column,
+ the name of the column. (Refer to the schema and table name fields to
+ identify the table.)
+ </p></dd><dt><span class="term"><code class="literal">d</code></span></dt><dd><p>
+ Data type name: if the error was associated with a specific data type,
+ the name of the data type. (Refer to the schema name field for the
+ name of the data type's schema.)
+ </p></dd><dt><span class="term"><code class="literal">n</code></span></dt><dd><p>
+ Constraint name: if the error was associated with a specific
+ constraint, the name of the constraint. Refer to fields listed above
+ for the associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with constraint
+ syntax.)
+ </p></dd><dt><span class="term"><code class="literal">F</code></span></dt><dd><p>
+ File: the file name of the source-code location where the error
+ was reported.
+ </p></dd><dt><span class="term"><code class="literal">L</code></span></dt><dd><p>
+ Line: the line number of the source-code location where the error
+ was reported.
+ </p></dd><dt><span class="term"><code class="literal">R</code></span></dt><dd><p>
+ Routine: the name of the source-code routine reporting the error.
+ </p></dd></dl></div><div class="note"><h3 class="title">Note</h3><p>
+ The fields for schema name, table name, column name, data type name, and
+ constraint name are supplied only for a limited number of error types;
+ see <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>. Frontends should not assume that
+ the presence of any of these fields guarantees the presence of another
+ field. Core error sources observe the interrelationships noted above, but
+ user-defined functions may use these fields in other ways. In the same
+ vein, clients should not assume that these fields denote contemporary
+ objects in the current database.
+ </p></div><p>
+ The client is responsible for formatting displayed information to meet its
+ needs; in particular it should break long lines as needed. Newline characters
+ appearing in the error message fields should be treated as paragraph breaks,
+ not line breaks.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-message-formats.html" title="55.7. Message Formats">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.7. Message Formats </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.9. Logical Replication Message Formats</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-flow.html b/doc/src/sgml/html/protocol-flow.html
new file mode 100644
index 0000000..7c7a544
--- /dev/null
+++ b/doc/src/sgml/html/protocol-flow.html
@@ -0,0 +1,975 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.2. Message Flow</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-overview.html" title="55.1. Overview" /><link rel="next" href="sasl-authentication.html" title="55.3. SASL Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.2. Message Flow</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-overview.html" title="55.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sasl-authentication.html" title="55.3. SASL Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-FLOW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.2. Message Flow</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.3">55.2.1. Start-up</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.4">55.2.2. Simple Query</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY">55.2.3. Extended Query</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-FLOW-PIPELINING">55.2.4. Pipelining</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.7">55.2.5. Function Call</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-COPY">55.2.6. COPY Operations</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-ASYNC">55.2.7. Asynchronous Operations</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.10">55.2.8. Canceling Requests in Progress</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.11">55.2.9. Termination</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.12">55.2.10. <acronym class="acronym">SSL</acronym> Session Encryption</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.13">55.2.11. <acronym class="acronym">GSSAPI</acronym> Session Encryption</a></span></dt></dl></div><p>
+ This section describes the message flow and the semantics of each
+ message type. (Details of the exact representation of each message
+ appear in <a class="xref" href="protocol-message-formats.html" title="55.7. Message Formats">Section 55.7</a>.) There are
+ several different sub-protocols depending on the state of the
+ connection: start-up, query, function call,
+ <code class="command">COPY</code>, and termination. There are also special
+ provisions for asynchronous operations (including notification
+ responses and command cancellation), which can occur at any time
+ after the start-up phase.
+ </p><div class="sect2" id="id-1.10.6.7.3"><div class="titlepage"><div><div><h3 class="title">55.2.1. Start-up</h3></div></div></div><p>
+ To begin a session, a frontend opens a connection to the server and sends
+ a startup message. This message includes the names of the user and of the
+ database the user wants to connect to; it also identifies the particular
+ protocol version to be used. (Optionally, the startup message can include
+ additional settings for run-time parameters.)
+ The server then uses this information and
+ the contents of its configuration files (such as
+ <code class="filename">pg_hba.conf</code>) to determine
+ whether the connection is provisionally acceptable, and what additional
+ authentication is required (if any).
+ </p><p>
+ The server then sends an appropriate authentication request message,
+ to which the frontend must reply with an appropriate authentication
+ response message (such as a password).
+ For all authentication methods except GSSAPI, SSPI and SASL, there is at
+ most one request and one response. In some methods, no response
+ at all is needed from the frontend, and so no authentication request
+ occurs. For GSSAPI, SSPI and SASL, multiple exchanges of packets may be
+ needed to complete the authentication.
+ </p><p>
+ The authentication cycle ends with the server either rejecting the
+ connection attempt (ErrorResponse), or sending AuthenticationOk.
+ </p><p>
+ The possible messages from the server in this phase are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">ErrorResponse</span></dt><dd><p>
+ The connection attempt has been rejected.
+ The server then immediately closes the connection.
+ </p></dd><dt><span class="term">AuthenticationOk</span></dt><dd><p>
+ The authentication exchange is successfully completed.
+ </p></dd><dt><span class="term">AuthenticationKerberosV5</span></dt><dd><p>
+ The frontend must now take part in a Kerberos V5
+ authentication dialog (not described here, part of the
+ Kerberos specification) with the server. If this is
+ successful, the server responds with an AuthenticationOk,
+ otherwise it responds with an ErrorResponse. This is no
+ longer supported.
+ </p></dd><dt><span class="term">AuthenticationCleartextPassword</span></dt><dd><p>
+ The frontend must now send a PasswordMessage containing the
+ password in clear-text form. If
+ this is the correct password, the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ </p></dd><dt><span class="term">AuthenticationMD5Password</span></dt><dd><p>
+ The frontend must now send a PasswordMessage containing the
+ password (with user name) encrypted via MD5, then encrypted
+ again using the 4-byte random salt specified in the
+ AuthenticationMD5Password message. If this is the correct
+ password, the server responds with an AuthenticationOk,
+ otherwise it responds with an ErrorResponse. The actual
+ PasswordMessage can be computed in SQL as <code class="literal">concat('md5',
+ md5(concat(md5(concat(password, username)), random-salt)))</code>.
+ (Keep in mind the <code class="function">md5()</code> function returns its
+ result as a hex string.)
+ </p></dd><dt><span class="term">AuthenticationSCMCredential</span></dt><dd><p>
+ This response is only possible for local Unix-domain connections
+ on platforms that support SCM credential messages. The frontend
+ must issue an SCM credential message and then send a single data
+ byte. (The contents of the data byte are uninteresting; it's
+ only used to ensure that the server waits long enough to receive
+ the credential message.) If the credential is acceptable,
+ the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ (This message type is only issued by pre-9.1 servers. It may
+ eventually be removed from the protocol specification.)
+ </p></dd><dt><span class="term">AuthenticationGSS</span></dt><dd><p>
+ The frontend must now initiate a GSSAPI negotiation. The frontend
+ will send a GSSResponse message with the first part of the GSSAPI
+ data stream in response to this. If further messages are needed,
+ the server will respond with AuthenticationGSSContinue.
+ </p></dd><dt><span class="term">AuthenticationSSPI</span></dt><dd><p>
+ The frontend must now initiate an SSPI negotiation. The frontend
+ will send a GSSResponse with the first part of the SSPI
+ data stream in response to this. If further messages are needed,
+ the server will respond with AuthenticationGSSContinue.
+ </p></dd><dt><span class="term">AuthenticationGSSContinue</span></dt><dd><p>
+ This message contains the response data from the previous step
+ of GSSAPI or SSPI negotiation (AuthenticationGSS, AuthenticationSSPI
+ or a previous AuthenticationGSSContinue). If the GSSAPI
+ or SSPI data in this message
+ indicates more data is needed to complete the authentication,
+ the frontend must send that data as another GSSResponse message. If
+ GSSAPI or SSPI authentication is completed by this message, the server
+ will next send AuthenticationOk to indicate successful authentication
+ or ErrorResponse to indicate failure.
+ </p></dd><dt><span class="term">AuthenticationSASL</span></dt><dd><p>
+ The frontend must now initiate a SASL negotiation, using one of the
+ SASL mechanisms listed in the message. The frontend will send a
+ SASLInitialResponse with the name of the selected mechanism, and the
+ first part of the SASL data stream in response to this. If further
+ messages are needed, the server will respond with
+ AuthenticationSASLContinue. See <a class="xref" href="sasl-authentication.html" title="55.3. SASL Authentication">Section 55.3</a>
+ for details.
+ </p></dd><dt><span class="term">AuthenticationSASLContinue</span></dt><dd><p>
+ This message contains challenge data from the previous step of SASL
+ negotiation (AuthenticationSASL, or a previous
+ AuthenticationSASLContinue). The frontend must respond with a
+ SASLResponse message.
+ </p></dd><dt><span class="term">AuthenticationSASLFinal</span></dt><dd><p>
+ SASL authentication has completed with additional mechanism-specific
+ data for the client. The server will next send AuthenticationOk to
+ indicate successful authentication, or an ErrorResponse to indicate
+ failure. This message is sent only if the SASL mechanism specifies
+ additional data to be sent from server to client at completion.
+ </p></dd><dt><span class="term">NegotiateProtocolVersion</span></dt><dd><p>
+ The server does not support the minor protocol version requested
+ by the client, but does support an earlier version of the protocol;
+ this message indicates the highest supported minor version. This
+ message will also be sent if the client requested unsupported protocol
+ options (i.e., beginning with <code class="literal">_pq_.</code>) in the
+ startup packet. This message will be followed by an ErrorResponse or
+ a message indicating the success or failure of authentication.
+ </p></dd></dl></div><p>
+ </p><p>
+ If the frontend does not support the authentication method
+ requested by the server, then it should immediately close the
+ connection.
+ </p><p>
+ After having received AuthenticationOk, the frontend must wait
+ for further messages from the server. In this phase a backend process
+ is being started, and the frontend is just an interested bystander.
+ It is still possible for the startup attempt
+ to fail (ErrorResponse) or the server to decline support for the requested
+ minor protocol version (NegotiateProtocolVersion), but in the normal case
+ the backend will send some ParameterStatus messages, BackendKeyData, and
+ finally ReadyForQuery.
+ </p><p>
+ During this phase the backend will attempt to apply any additional
+ run-time parameter settings that were given in the startup message.
+ If successful, these values become session defaults. An error causes
+ ErrorResponse and exit.
+ </p><p>
+ The possible messages from the backend in this phase are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">BackendKeyData</span></dt><dd><p>
+ This message provides secret-key data that the frontend must
+ save if it wants to be able to issue cancel requests later.
+ The frontend should not respond to this message, but should
+ continue listening for a ReadyForQuery message.
+ </p></dd><dt><span class="term">ParameterStatus</span></dt><dd><p>
+ This message informs the frontend about the current (initial)
+ setting of backend parameters, such as <a class="xref" href="runtime-config-client.html#GUC-CLIENT-ENCODING">client_encoding</a> or <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a>.
+ The frontend can ignore this message, or record the settings
+ for its future use; see <a class="xref" href="protocol-flow.html#PROTOCOL-ASYNC" title="55.2.7. Asynchronous Operations">Section 55.2.7</a> for
+ more details. The frontend should not respond to this
+ message, but should continue listening for a ReadyForQuery
+ message.
+ </p></dd><dt><span class="term">ReadyForQuery</span></dt><dd><p>
+ Start-up is completed. The frontend can now issue commands.
+ </p></dd><dt><span class="term">ErrorResponse</span></dt><dd><p>
+ Start-up failed. The connection is closed after sending this
+ message.
+ </p></dd><dt><span class="term">NoticeResponse</span></dt><dd><p>
+ A warning message has been issued. The frontend should
+ display the message but continue listening for ReadyForQuery
+ or ErrorResponse.
+ </p></dd></dl></div><p>
+ </p><p>
+ The ReadyForQuery message is the same one that the backend will
+ issue after each command cycle. Depending on the coding needs of
+ the frontend, it is reasonable to consider ReadyForQuery as
+ starting a command cycle, or to consider ReadyForQuery as ending the
+ start-up phase and each subsequent command cycle.
+ </p></div><div class="sect2" id="id-1.10.6.7.4"><div class="titlepage"><div><div><h3 class="title">55.2.2. Simple Query</h3></div></div></div><p>
+ A simple query cycle is initiated by the frontend sending a Query message
+ to the backend. The message includes an SQL command (or commands)
+ expressed as a text string.
+ The backend then sends one or more response
+ messages depending on the contents of the query command string,
+ and finally a ReadyForQuery response message. ReadyForQuery
+ informs the frontend that it can safely send a new command.
+ (It is not actually necessary for the frontend to wait for
+ ReadyForQuery before issuing another command, but the frontend must
+ then take responsibility for figuring out what happens if the earlier
+ command fails and already-issued later commands succeed.)
+ </p><p>
+ The possible response messages from the backend are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">CommandComplete</span></dt><dd><p>
+ An SQL command completed normally.
+ </p></dd><dt><span class="term">CopyInResponse</span></dt><dd><p>
+ The backend is ready to copy data from the frontend to a
+ table; see <a class="xref" href="protocol-flow.html#PROTOCOL-COPY" title="55.2.6. COPY Operations">Section 55.2.6</a>.
+ </p></dd><dt><span class="term">CopyOutResponse</span></dt><dd><p>
+ The backend is ready to copy data from a table to the
+ frontend; see <a class="xref" href="protocol-flow.html#PROTOCOL-COPY" title="55.2.6. COPY Operations">Section 55.2.6</a>.
+ </p></dd><dt><span class="term">RowDescription</span></dt><dd><p>
+ Indicates that rows are about to be returned in response to
+ a <code class="command">SELECT</code>, <code class="command">FETCH</code>, etc. query.
+ The contents of this message describe the column layout of the rows.
+ This will be followed by a DataRow message for each row being returned
+ to the frontend.
+ </p></dd><dt><span class="term">DataRow</span></dt><dd><p>
+ One of the set of rows returned by
+ a <code class="command">SELECT</code>, <code class="command">FETCH</code>, etc. query.
+ </p></dd><dt><span class="term">EmptyQueryResponse</span></dt><dd><p>
+ An empty query string was recognized.
+ </p></dd><dt><span class="term">ErrorResponse</span></dt><dd><p>
+ An error has occurred.
+ </p></dd><dt><span class="term">ReadyForQuery</span></dt><dd><p>
+ Processing of the query string is complete. A separate
+ message is sent to indicate this because the query string might
+ contain multiple SQL commands. (CommandComplete marks the
+ end of processing one SQL command, not the whole string.)
+ ReadyForQuery will always be sent, whether processing
+ terminates successfully or with an error.
+ </p></dd><dt><span class="term">NoticeResponse</span></dt><dd><p>
+ A warning message has been issued in relation to the query.
+ Notices are in addition to other responses, i.e., the backend
+ will continue processing the command.
+ </p></dd></dl></div><p>
+ </p><p>
+ The response to a <code class="command">SELECT</code> query (or other queries that
+ return row sets, such as <code class="command">EXPLAIN</code> or <code class="command">SHOW</code>)
+ normally consists of RowDescription, zero or more
+ DataRow messages, and then CommandComplete.
+ <code class="command">COPY</code> to or from the frontend invokes special protocol
+ as described in <a class="xref" href="protocol-flow.html#PROTOCOL-COPY" title="55.2.6. COPY Operations">Section 55.2.6</a>.
+ All other query types normally produce only
+ a CommandComplete message.
+ </p><p>
+ Since a query string could contain several queries (separated by
+ semicolons), there might be several such response sequences before the
+ backend finishes processing the query string. ReadyForQuery is issued
+ when the entire string has been processed and the backend is ready to
+ accept a new query string.
+ </p><p>
+ If a completely empty (no contents other than whitespace) query string
+ is received, the response is EmptyQueryResponse followed by ReadyForQuery.
+ </p><p>
+ In the event of an error, ErrorResponse is issued followed by
+ ReadyForQuery. All further processing of the query string is aborted by
+ ErrorResponse (even if more queries remained in it). Note that this
+ might occur partway through the sequence of messages generated by an
+ individual query.
+ </p><p>
+ In simple Query mode, the format of retrieved values is always text,
+ except when the given command is a <code class="command">FETCH</code> from a cursor
+ declared with the <code class="literal">BINARY</code> option. In that case, the
+ retrieved values are in binary format. The format codes given in
+ the RowDescription message tell which format is being used.
+ </p><p>
+ A frontend must be prepared to accept ErrorResponse and
+ NoticeResponse messages whenever it is expecting any other type of
+ message. See also <a class="xref" href="protocol-flow.html#PROTOCOL-ASYNC" title="55.2.7. Asynchronous Operations">Section 55.2.7</a> concerning messages
+ that the backend might generate due to outside events.
+ </p><p>
+ Recommended practice is to code frontends in a state-machine style
+ that will accept any message type at any time that it could make sense,
+ rather than wiring in assumptions about the exact sequence of messages.
+ </p><div class="sect3" id="PROTOCOL-FLOW-MULTI-STATEMENT"><div class="titlepage"><div><div><h4 class="title">55.2.2.1. Multiple Statements in a Simple Query</h4></div></div></div><p>
+ When a simple Query message contains more than one SQL statement
+ (separated by semicolons), those statements are executed as a single
+ transaction, unless explicit transaction control commands are included
+ to force a different behavior. For example, if the message contains
+</p><pre class="programlisting">
+INSERT INTO mytable VALUES(1);
+SELECT 1/0;
+INSERT INTO mytable VALUES(2);
+</pre><p>
+ then the divide-by-zero failure in the <code class="command">SELECT</code> will force
+ rollback of the first <code class="command">INSERT</code>. Furthermore, because
+ execution of the message is abandoned at the first error, the second
+ <code class="command">INSERT</code> is never attempted at all.
+ </p><p>
+ If instead the message contains
+</p><pre class="programlisting">
+BEGIN;
+INSERT INTO mytable VALUES(1);
+COMMIT;
+INSERT INTO mytable VALUES(2);
+SELECT 1/0;
+</pre><p>
+ then the first <code class="command">INSERT</code> is committed by the
+ explicit <code class="command">COMMIT</code> command. The second <code class="command">INSERT</code>
+ and the <code class="command">SELECT</code> are still treated as a single transaction,
+ so that the divide-by-zero failure will roll back the
+ second <code class="command">INSERT</code>, but not the first one.
+ </p><p>
+ This behavior is implemented by running the statements in a
+ multi-statement Query message in an <em class="firstterm">implicit transaction
+ block</em> unless there is some explicit transaction block for them to
+ run in. The main difference between an implicit transaction block and
+ a regular one is that an implicit block is closed automatically at the
+ end of the Query message, either by an implicit commit if there was no
+ error, or an implicit rollback if there was an error. This is similar
+ to the implicit commit or rollback that happens for a statement
+ executed by itself (when not in a transaction block).
+ </p><p>
+ If the session is already in a transaction block, as a result of
+ a <code class="command">BEGIN</code> in some previous message, then the Query message
+ simply continues that transaction block, whether the message contains
+ one statement or several. However, if the Query message contains
+ a <code class="command">COMMIT</code> or <code class="command">ROLLBACK</code> closing the existing
+ transaction block, then any following statements are executed in an
+ implicit transaction block.
+ Conversely, if a <code class="command">BEGIN</code> appears in a multi-statement Query
+ message, then it starts a regular transaction block that will only be
+ terminated by an explicit <code class="command">COMMIT</code> or <code class="command">ROLLBACK</code>,
+ whether that appears in this Query message or a later one.
+ If the <code class="command">BEGIN</code> follows some statements that were executed as
+ an implicit transaction block, those statements are not immediately
+ committed; in effect, they are retroactively included into the new
+ regular transaction block.
+ </p><p>
+ A <code class="command">COMMIT</code> or <code class="command">ROLLBACK</code> appearing in an implicit
+ transaction block is executed as normal, closing the implicit block;
+ however, a warning will be issued since a <code class="command">COMMIT</code>
+ or <code class="command">ROLLBACK</code> without a previous <code class="command">BEGIN</code> might
+ represent a mistake. If more statements follow, a new implicit
+ transaction block will be started for them.
+ </p><p>
+ Savepoints are not allowed in an implicit transaction block, since
+ they would conflict with the behavior of automatically closing the
+ block upon any error.
+ </p><p>
+ Remember that, regardless of any transaction control commands that may
+ be present, execution of the Query message stops at the first error.
+ Thus for example given
+</p><pre class="programlisting">
+BEGIN;
+SELECT 1/0;
+ROLLBACK;
+</pre><p>
+ in a single Query message, the session will be left inside a failed
+ regular transaction block, since the <code class="command">ROLLBACK</code> is not
+ reached after the divide-by-zero error. Another <code class="command">ROLLBACK</code>
+ will be needed to restore the session to a usable state.
+ </p><p>
+ Another behavior of note is that initial lexical and syntactic
+ analysis is done on the entire query string before any of it is
+ executed. Thus simple errors (such as a misspelled keyword) in later
+ statements can prevent execution of any of the statements. This
+ is normally invisible to users since the statements would all roll
+ back anyway when done as an implicit transaction block. However,
+ it can be visible when attempting to do multiple transactions within a
+ multi-statement Query. For instance, if a typo turned our previous
+ example into
+</p><pre class="programlisting">
+BEGIN;
+INSERT INTO mytable VALUES(1);
+COMMIT;
+INSERT INTO mytable VALUES(2);
+SELCT 1/0;
+</pre><p>
+ then none of the statements would get run, resulting in the visible
+ difference that the first <code class="command">INSERT</code> is not committed.
+ Errors detected at semantic analysis or later, such as a misspelled
+ table or column name, do not have this effect.
+ </p></div></div><div class="sect2" id="PROTOCOL-FLOW-EXT-QUERY"><div class="titlepage"><div><div><h3 class="title">55.2.3. Extended Query</h3></div></div></div><p>
+ The extended query protocol breaks down the above-described simple
+ query protocol into multiple steps. The results of preparatory
+ steps can be re-used multiple times for improved efficiency.
+ Furthermore, additional features are available, such as the possibility
+ of supplying data values as separate parameters instead of having to
+ insert them directly into a query string.
+ </p><p>
+ In the extended protocol, the frontend first sends a Parse message,
+ which contains a textual query string, optionally some information
+ about data types of parameter placeholders, and the
+ name of a destination prepared-statement object (an empty string
+ selects the unnamed prepared statement). The response is
+ either ParseComplete or ErrorResponse. Parameter data types can be
+ specified by OID; if not given, the parser attempts to infer the
+ data types in the same way as it would do for untyped literal string
+ constants.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ A parameter data type can be left unspecified by setting it to zero,
+ or by making the array of parameter type OIDs shorter than the
+ number of parameter symbols (<code class="literal">$</code><em class="replaceable"><code>n</code></em>)
+ used in the query string. Another special case is that a parameter's
+ type can be specified as <code class="type">void</code> (that is, the OID of the
+ <code class="type">void</code> pseudo-type). This is meant to allow parameter symbols
+ to be used for function parameters that are actually OUT parameters.
+ Ordinarily there is no context in which a <code class="type">void</code> parameter
+ could be used, but if such a parameter symbol appears in a function's
+ parameter list, it is effectively ignored. For example, a function
+ call such as <code class="literal">foo($1,$2,$3,$4)</code> could match a function with
+ two IN and two OUT arguments, if <code class="literal">$3</code> and <code class="literal">$4</code>
+ are specified as having type <code class="type">void</code>.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ The query string contained in a Parse message cannot include more
+ than one SQL statement; else a syntax error is reported. This
+ restriction does not exist in the simple-query protocol, but it
+ does exist in the extended protocol, because allowing prepared
+ statements or portals to contain multiple commands would complicate
+ the protocol unduly.
+ </p></div><p>
+ If successfully created, a named prepared-statement object lasts till
+ the end of the current session, unless explicitly destroyed. An unnamed
+ prepared statement lasts only until the next Parse statement specifying
+ the unnamed statement as destination is issued. (Note that a simple
+ Query message also destroys the unnamed statement.) Named prepared
+ statements must be explicitly closed before they can be redefined by
+ another Parse message, but this is not required for the unnamed statement.
+ Named prepared statements can also be created and accessed at the SQL
+ command level, using <code class="command">PREPARE</code> and <code class="command">EXECUTE</code>.
+ </p><p>
+ Once a prepared statement exists, it can be readied for execution using a
+ Bind message. The Bind message gives the name of the source prepared
+ statement (empty string denotes the unnamed prepared statement), the name
+ of the destination portal (empty string denotes the unnamed portal), and
+ the values to use for any parameter placeholders present in the prepared
+ statement. The
+ supplied parameter set must match those needed by the prepared statement.
+ (If you declared any <code class="type">void</code> parameters in the Parse message,
+ pass NULL values for them in the Bind message.)
+ Bind also specifies the format to use for any data returned
+ by the query; the format can be specified overall, or per-column.
+ The response is either BindComplete or ErrorResponse.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The choice between text and binary output is determined by the format
+ codes given in Bind, regardless of the SQL command involved. The
+ <code class="literal">BINARY</code> attribute in cursor declarations is irrelevant when
+ using extended query protocol.
+ </p></div><p>
+ Query planning typically occurs when the Bind message is processed.
+ If the prepared statement has no parameters, or is executed repeatedly,
+ the server might save the created plan and re-use it during subsequent
+ Bind messages for the same prepared statement. However, it will do so
+ only if it finds that a generic plan can be created that is not much
+ less efficient than a plan that depends on the specific parameter values
+ supplied. This happens transparently so far as the protocol is concerned.
+ </p><p>
+ If successfully created, a named portal object lasts till the end of the
+ current transaction, unless explicitly destroyed. An unnamed portal is
+ destroyed at the end of the transaction, or as soon as the next Bind
+ statement specifying the unnamed portal as destination is issued. (Note
+ that a simple Query message also destroys the unnamed portal.) Named
+ portals must be explicitly closed before they can be redefined by another
+ Bind message, but this is not required for the unnamed portal.
+ Named portals can also be created and accessed at the SQL
+ command level, using <code class="command">DECLARE CURSOR</code> and <code class="command">FETCH</code>.
+ </p><p>
+ Once a portal exists, it can be executed using an Execute message.
+ The Execute message specifies the portal name (empty string denotes the
+ unnamed portal) and
+ a maximum result-row count (zero meaning <span class="quote">“<span class="quote">fetch all rows</span>”</span>).
+ The result-row count is only meaningful for portals
+ containing commands that return row sets; in other cases the command is
+ always executed to completion, and the row count is ignored.
+ The possible
+ responses to Execute are the same as those described above for queries
+ issued via simple query protocol, except that Execute doesn't cause
+ ReadyForQuery or RowDescription to be issued.
+ </p><p>
+ If Execute terminates before completing the execution of a portal
+ (due to reaching a nonzero result-row count), it will send a
+ PortalSuspended message; the appearance of this message tells the frontend
+ that another Execute should be issued against the same portal to
+ complete the operation. The CommandComplete message indicating
+ completion of the source SQL command is not sent until
+ the portal's execution is completed. Therefore, an Execute phase is
+ always terminated by the appearance of exactly one of these messages:
+ CommandComplete, EmptyQueryResponse (if the portal was created from
+ an empty query string), ErrorResponse, or PortalSuspended.
+ </p><p>
+ At completion of each series of extended-query messages, the frontend
+ should issue a Sync message. This parameterless message causes the
+ backend to close the current transaction if it's not inside a
+ <code class="command">BEGIN</code>/<code class="command">COMMIT</code> transaction block (<span class="quote">“<span class="quote">close</span>”</span>
+ meaning to commit if no error, or roll back if error). Then a
+ ReadyForQuery response is issued. The purpose of Sync is to provide
+ a resynchronization point for error recovery. When an error is detected
+ while processing any extended-query message, the backend issues
+ ErrorResponse, then reads and discards messages until a Sync is reached,
+ then issues ReadyForQuery and returns to normal message processing.
+ (But note that no skipping occurs if an error is detected
+ <span class="emphasis"><em>while</em></span> processing Sync — this ensures that there is one
+ and only one ReadyForQuery sent for each Sync.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Sync does not cause a transaction block opened with <code class="command">BEGIN</code>
+ to be closed. It is possible to detect this situation since the
+ ReadyForQuery message includes transaction status information.
+ </p></div><p>
+ In addition to these fundamental, required operations, there are several
+ optional operations that can be used with extended-query protocol.
+ </p><p>
+ The Describe message (portal variant) specifies the name of an existing
+ portal (or an empty string for the unnamed portal). The response is a
+ RowDescription message describing the rows that will be returned by
+ executing the portal; or a NoData message if the portal does not contain a
+ query that will return rows; or ErrorResponse if there is no such portal.
+ </p><p>
+ The Describe message (statement variant) specifies the name of an existing
+ prepared statement (or an empty string for the unnamed prepared
+ statement). The response is a ParameterDescription message describing the
+ parameters needed by the statement, followed by a RowDescription message
+ describing the rows that will be returned when the statement is eventually
+ executed (or a NoData message if the statement will not return rows).
+ ErrorResponse is issued if there is no such prepared statement. Note that
+ since Bind has not yet been issued, the formats to be used for returned
+ columns are not yet known to the backend; the format code fields in the
+ RowDescription message will be zeroes in this case.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ In most scenarios the frontend should issue one or the other variant
+ of Describe before issuing Execute, to ensure that it knows how to
+ interpret the results it will get back.
+ </p></div><p>
+ The Close message closes an existing prepared statement or portal
+ and releases resources. It is not an error to issue Close against
+ a nonexistent statement or portal name. The response is normally
+ CloseComplete, but could be ErrorResponse if some difficulty is
+ encountered while releasing resources. Note that closing a prepared
+ statement implicitly closes any open portals that were constructed
+ from that statement.
+ </p><p>
+ The Flush message does not cause any specific output to be generated,
+ but forces the backend to deliver any data pending in its output
+ buffers. A Flush must be sent after any extended-query command except
+ Sync, if the frontend wishes to examine the results of that command before
+ issuing more commands. Without Flush, messages returned by the backend
+ will be combined into the minimum possible number of packets to minimize
+ network overhead.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The simple Query message is approximately equivalent to the series Parse,
+ Bind, portal Describe, Execute, Close, Sync, using the unnamed prepared
+ statement and portal objects and no parameters. One difference is that
+ it will accept multiple SQL statements in the query string, automatically
+ performing the bind/describe/execute sequence for each one in succession.
+ Another difference is that it will not return ParseComplete, BindComplete,
+ CloseComplete, or NoData messages.
+ </p></div></div><div class="sect2" id="PROTOCOL-FLOW-PIPELINING"><div class="titlepage"><div><div><h3 class="title">55.2.4. Pipelining</h3></div></div></div><a id="id-1.10.6.7.6.2" class="indexterm"></a><p>
+ Use of the extended query protocol
+ allows <em class="firstterm">pipelining</em>, which means sending a series
+ of queries without waiting for earlier ones to complete. This reduces
+ the number of network round trips needed to complete a given series of
+ operations. However, the user must carefully consider the required
+ behavior if one of the steps fails, since later queries will already
+ be in flight to the server.
+ </p><p>
+ One way to deal with that is to make the whole query series be a
+ single transaction, that is wrap it in <code class="command">BEGIN</code> ...
+ <code class="command">COMMIT</code>. However, this does not help if one wishes
+ for some of the commands to commit independently of others.
+ </p><p>
+ The extended query protocol provides another way to manage this
+ concern, which is to omit sending Sync messages between steps that
+ are dependent. Since, after an error, the backend will skip command
+ messages until it finds Sync, this allows later commands in a pipeline
+ to be skipped automatically when an earlier one fails, without the
+ client having to manage that explicitly with <code class="command">BEGIN</code>
+ and <code class="command">COMMIT</code>. Independently-committable segments
+ of the pipeline can be separated by Sync messages.
+ </p><p>
+ If the client has not issued an explicit <code class="command">BEGIN</code>,
+ then each Sync ordinarily causes an implicit <code class="command">COMMIT</code>
+ if the preceding step(s) succeeded, or an
+ implicit <code class="command">ROLLBACK</code> if they failed. However, there
+ are a few DDL commands (such as <code class="command">CREATE DATABASE</code>)
+ that cannot be executed inside a transaction block. If one of
+ these is executed in a pipeline, it will fail unless it is the first
+ command in the pipeline. Furthermore, upon success it will force an
+ immediate commit to preserve database consistency. Thus a Sync
+ immediately following one of these commands has no effect except to
+ respond with ReadyForQuery.
+ </p><p>
+ When using this method, completion of the pipeline must be determined
+ by counting ReadyForQuery messages and waiting for that to reach the
+ number of Syncs sent. Counting command completion responses is
+ unreliable, since some of the commands may be skipped and thus not
+ produce a completion message.
+ </p></div><div class="sect2" id="id-1.10.6.7.7"><div class="titlepage"><div><div><h3 class="title">55.2.5. Function Call</h3></div></div></div><p>
+ The Function Call sub-protocol allows the client to request a direct
+ call of any function that exists in the database's
+ <code class="structname">pg_proc</code> system catalog. The client must have
+ execute permission for the function.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The Function Call sub-protocol is a legacy feature that is probably best
+ avoided in new code. Similar results can be accomplished by setting up
+ a prepared statement that does <code class="literal">SELECT function($1, ...)</code>.
+ The Function Call cycle can then be replaced with Bind/Execute.
+ </p></div><p>
+ A Function Call cycle is initiated by the frontend sending a
+ FunctionCall message to the backend. The backend then sends one
+ or more response messages depending on the results of the function
+ call, and finally a ReadyForQuery response message. ReadyForQuery
+ informs the frontend that it can safely send a new query or
+ function call.
+ </p><p>
+ The possible response messages from the backend are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">ErrorResponse</span></dt><dd><p>
+ An error has occurred.
+ </p></dd><dt><span class="term">FunctionCallResponse</span></dt><dd><p>
+ The function call was completed and returned the result given
+ in the message.
+ (Note that the Function Call protocol can only handle a single
+ scalar result, not a row type or set of results.)
+ </p></dd><dt><span class="term">ReadyForQuery</span></dt><dd><p>
+ Processing of the function call is complete. ReadyForQuery
+ will always be sent, whether processing terminates
+ successfully or with an error.
+ </p></dd><dt><span class="term">NoticeResponse</span></dt><dd><p>
+ A warning message has been issued in relation to the function
+ call. Notices are in addition to other responses, i.e., the
+ backend will continue processing the command.
+ </p></dd></dl></div><p>
+ </p></div><div class="sect2" id="PROTOCOL-COPY"><div class="titlepage"><div><div><h3 class="title">55.2.6. COPY Operations</h3></div></div></div><p>
+ The <code class="command">COPY</code> command allows high-speed bulk data transfer
+ to or from the server. Copy-in and copy-out operations each switch
+ the connection into a distinct sub-protocol, which lasts until the
+ operation is completed.
+ </p><p>
+ Copy-in mode (data transfer to the server) is initiated when the
+ backend executes a <code class="command">COPY FROM STDIN</code> SQL statement. The backend
+ sends a CopyInResponse message to the frontend. The frontend should
+ then send zero or more CopyData messages, forming a stream of input
+ data. (The message boundaries are not required to have anything to do
+ with row boundaries, although that is often a reasonable choice.)
+ The frontend can terminate the copy-in mode by sending either a CopyDone
+ message (allowing successful termination) or a CopyFail message (which
+ will cause the <code class="command">COPY</code> SQL statement to fail with an
+ error). The backend then reverts to the command-processing mode it was
+ in before the <code class="command">COPY</code> started, which will be either simple or
+ extended query protocol. It will next send either CommandComplete
+ (if successful) or ErrorResponse (if not).
+ </p><p>
+ In the event of a backend-detected error during copy-in mode (including
+ receipt of a CopyFail message), the backend will issue an ErrorResponse
+ message. If the <code class="command">COPY</code> command was issued via an extended-query
+ message, the backend will now discard frontend messages until a Sync
+ message is received, then it will issue ReadyForQuery and return to normal
+ processing. If the <code class="command">COPY</code> command was issued in a simple
+ Query message, the rest of that message is discarded and ReadyForQuery
+ is issued. In either case, any subsequent CopyData, CopyDone, or CopyFail
+ messages issued by the frontend will simply be dropped.
+ </p><p>
+ The backend will ignore Flush and Sync messages received during copy-in
+ mode. Receipt of any other non-copy message type constitutes an error
+ that will abort the copy-in state as described above. (The exception for
+ Flush and Sync is for the convenience of client libraries that always
+ send Flush or Sync after an Execute message, without checking whether
+ the command to be executed is a <code class="command">COPY FROM STDIN</code>.)
+ </p><p>
+ Copy-out mode (data transfer from the server) is initiated when the
+ backend executes a <code class="command">COPY TO STDOUT</code> SQL statement. The backend
+ sends a CopyOutResponse message to the frontend, followed by
+ zero or more CopyData messages (always one per row), followed by CopyDone.
+ The backend then reverts to the command-processing mode it was
+ in before the <code class="command">COPY</code> started, and sends CommandComplete.
+ The frontend cannot abort the transfer (except by closing the connection
+ or issuing a Cancel request),
+ but it can discard unwanted CopyData and CopyDone messages.
+ </p><p>
+ In the event of a backend-detected error during copy-out mode,
+ the backend will issue an ErrorResponse message and revert to normal
+ processing. The frontend should treat receipt of ErrorResponse as
+ terminating the copy-out mode.
+ </p><p>
+ It is possible for NoticeResponse and ParameterStatus messages to be
+ interspersed between CopyData messages; frontends must handle these cases,
+ and should be prepared for other asynchronous message types as well (see
+ <a class="xref" href="protocol-flow.html#PROTOCOL-ASYNC" title="55.2.7. Asynchronous Operations">Section 55.2.7</a>). Otherwise, any message type other than
+ CopyData or CopyDone may be treated as terminating copy-out mode.
+ </p><p>
+ There is another Copy-related mode called copy-both, which allows
+ high-speed bulk data transfer to <span class="emphasis"><em>and</em></span> from the server.
+ Copy-both mode is initiated when a backend in walsender mode
+ executes a <code class="command">START_REPLICATION</code> statement. The
+ backend sends a CopyBothResponse message to the frontend. Both
+ the backend and the frontend may then send CopyData messages
+ until either end sends a CopyDone message. After the client
+ sends a CopyDone message, the connection goes from copy-both mode to
+ copy-out mode, and the client may not send any more CopyData messages.
+ Similarly, when the server sends a CopyDone message, the connection
+ goes into copy-in mode, and the server may not send any more CopyData
+ messages. After both sides have sent a CopyDone message, the copy mode
+ is terminated, and the backend reverts to the command-processing mode.
+ In the event of a backend-detected error during copy-both mode,
+ the backend will issue an ErrorResponse message, discard frontend messages
+ until a Sync message is received, and then issue ReadyForQuery and return
+ to normal processing. The frontend should treat receipt of ErrorResponse
+ as terminating the copy in both directions; no CopyDone should be sent
+ in this case. See <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a> for more
+ information on the subprotocol transmitted over copy-both mode.
+ </p><p>
+ The CopyInResponse, CopyOutResponse and CopyBothResponse messages
+ include fields that inform the frontend of the number of columns
+ per row and the format codes being used for each column. (As of
+ the present implementation, all columns in a given <code class="command">COPY</code>
+ operation will use the same format, but the message design does not
+ assume this.)
+ </p></div><div class="sect2" id="PROTOCOL-ASYNC"><div class="titlepage"><div><div><h3 class="title">55.2.7. Asynchronous Operations</h3></div></div></div><p>
+ There are several cases in which the backend will send messages that
+ are not specifically prompted by the frontend's command stream.
+ Frontends must be prepared to deal with these messages at any time,
+ even when not engaged in a query.
+ At minimum, one should check for these cases before beginning to
+ read a query response.
+ </p><p>
+ It is possible for NoticeResponse messages to be generated due to
+ outside activity; for example, if the database administrator commands
+ a <span class="quote">“<span class="quote">fast</span>”</span> database shutdown, the backend will send a NoticeResponse
+ indicating this fact before closing the connection. Accordingly,
+ frontends should always be prepared to accept and display NoticeResponse
+ messages, even when the connection is nominally idle.
+ </p><p>
+ ParameterStatus messages will be generated whenever the active
+ value changes for any of the parameters the backend believes the
+ frontend should know about. Most commonly this occurs in response
+ to a <code class="command">SET</code> SQL command executed by the frontend, and
+ this case is effectively synchronous — but it is also possible
+ for parameter status changes to occur because the administrator
+ changed a configuration file and then sent the
+ <span class="systemitem">SIGHUP</span> signal to the server. Also,
+ if a <code class="command">SET</code> command is rolled back, an appropriate
+ ParameterStatus message will be generated to report the current
+ effective value.
+ </p><p>
+ At present there is a hard-wired set of parameters for which
+ ParameterStatus will be generated: they are
+ <code class="varname">server_version</code>,
+ <code class="varname">server_encoding</code>,
+ <code class="varname">client_encoding</code>,
+ <code class="varname">application_name</code>,
+ <code class="varname">default_transaction_read_only</code>,
+ <code class="varname">in_hot_standby</code>,
+ <code class="varname">is_superuser</code>,
+ <code class="varname">session_authorization</code>,
+ <code class="varname">DateStyle</code>,
+ <code class="varname">IntervalStyle</code>,
+ <code class="varname">TimeZone</code>,
+ <code class="varname">integer_datetimes</code>, and
+ <code class="varname">standard_conforming_strings</code>.
+ (<code class="varname">server_encoding</code>, <code class="varname">TimeZone</code>, and
+ <code class="varname">integer_datetimes</code> were not reported by releases before 8.0;
+ <code class="varname">standard_conforming_strings</code> was not reported by releases
+ before 8.1;
+ <code class="varname">IntervalStyle</code> was not reported by releases before 8.4;
+ <code class="varname">application_name</code> was not reported by releases before
+ 9.0;
+ <code class="varname">default_transaction_read_only</code> and
+ <code class="varname">in_hot_standby</code> were not reported by releases before
+ 14.)
+ Note that
+ <code class="varname">server_version</code>,
+ <code class="varname">server_encoding</code> and
+ <code class="varname">integer_datetimes</code>
+ are pseudo-parameters that cannot change after startup.
+ This set might change in the future, or even become configurable.
+ Accordingly, a frontend should simply ignore ParameterStatus for
+ parameters that it does not understand or care about.
+ </p><p>
+ If a frontend issues a <code class="command">LISTEN</code> command, then the
+ backend will send a NotificationResponse message (not to be
+ confused with NoticeResponse!) whenever a
+ <code class="command">NOTIFY</code> command is executed for the same
+ channel name.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ At present, NotificationResponse can only be sent outside a
+ transaction, and thus it will not occur in the middle of a
+ command-response series, though it might occur just before ReadyForQuery.
+ It is unwise to design frontend logic that assumes that, however.
+ Good practice is to be able to accept NotificationResponse at any
+ point in the protocol.
+ </p></div></div><div class="sect2" id="id-1.10.6.7.10"><div class="titlepage"><div><div><h3 class="title">55.2.8. Canceling Requests in Progress</h3></div></div></div><p>
+ During the processing of a query, the frontend might request
+ cancellation of the query. The cancel request is not sent
+ directly on the open connection to the backend for reasons of
+ implementation efficiency: we don't want to have the backend
+ constantly checking for new input from the frontend during query
+ processing. Cancel requests should be relatively infrequent, so
+ we make them slightly cumbersome in order to avoid a penalty in
+ the normal case.
+ </p><p>
+ To issue a cancel request, the frontend opens a new connection to
+ the server and sends a CancelRequest message, rather than the
+ StartupMessage message that would ordinarily be sent across a new
+ connection. The server will process this request and then close
+ the connection. For security reasons, no direct reply is made to
+ the cancel request message.
+ </p><p>
+ A CancelRequest message will be ignored unless it contains the
+ same key data (PID and secret key) passed to the frontend during
+ connection start-up. If the request matches the PID and secret
+ key for a currently executing backend, the processing of the
+ current query is aborted. (In the existing implementation, this is
+ done by sending a special signal to the backend process that is
+ processing the query.)
+ </p><p>
+ The cancellation signal might or might not have any effect — for
+ example, if it arrives after the backend has finished processing
+ the query, then it will have no effect. If the cancellation is
+ effective, it results in the current command being terminated
+ early with an error message.
+ </p><p>
+ The upshot of all this is that for reasons of both security and
+ efficiency, the frontend has no direct way to tell whether a
+ cancel request has succeeded. It must continue to wait for the
+ backend to respond to the query. Issuing a cancel simply improves
+ the odds that the current query will finish soon, and improves the
+ odds that it will fail with an error message instead of
+ succeeding.
+ </p><p>
+ Since the cancel request is sent across a new connection to the
+ server and not across the regular frontend/backend communication
+ link, it is possible for the cancel request to be issued by any
+ process, not just the frontend whose query is to be canceled.
+ This might provide additional flexibility when building
+ multiple-process applications. It also introduces a security
+ risk, in that unauthorized persons might try to cancel queries.
+ The security risk is addressed by requiring a dynamically
+ generated secret key to be supplied in cancel requests.
+ </p></div><div class="sect2" id="id-1.10.6.7.11"><div class="titlepage"><div><div><h3 class="title">55.2.9. Termination</h3></div></div></div><p>
+ The normal, graceful termination procedure is that the frontend
+ sends a Terminate message and immediately closes the connection.
+ On receipt of this message, the backend closes the connection and
+ terminates.
+ </p><p>
+ In rare cases (such as an administrator-commanded database shutdown)
+ the backend might disconnect without any frontend request to do so.
+ In such cases the backend will attempt to send an error or notice message
+ giving the reason for the disconnection before it closes the connection.
+ </p><p>
+ Other termination scenarios arise from various failure cases, such as core
+ dump at one end or the other, loss of the communications link, loss of
+ message-boundary synchronization, etc. If either frontend or backend sees
+ an unexpected closure of the connection, it should clean
+ up and terminate. The frontend has the option of launching a new backend
+ by recontacting the server if it doesn't want to terminate itself.
+ Closing the connection is also advisable if an unrecognizable message type
+ is received, since this probably indicates loss of message-boundary sync.
+ </p><p>
+ For either normal or abnormal termination, any open transaction is
+ rolled back, not committed. One should note however that if a
+ frontend disconnects while a non-<code class="command">SELECT</code> query
+ is being processed, the backend will probably finish the query
+ before noticing the disconnection. If the query is outside any
+ transaction block (<code class="command">BEGIN</code> ... <code class="command">COMMIT</code>
+ sequence) then its results might be committed before the
+ disconnection is recognized.
+ </p></div><div class="sect2" id="id-1.10.6.7.12"><div class="titlepage"><div><div><h3 class="title">55.2.10. <acronym class="acronym">SSL</acronym> Session Encryption</h3></div></div></div><p>
+ If <span class="productname">PostgreSQL</span> was built with
+ <acronym class="acronym">SSL</acronym> support, frontend/backend communications
+ can be encrypted using <acronym class="acronym">SSL</acronym>. This provides
+ communication security in environments where attackers might be
+ able to capture the session traffic. For more information on
+ encrypting <span class="productname">PostgreSQL</span> sessions with
+ <acronym class="acronym">SSL</acronym>, see <a class="xref" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Section 19.9</a>.
+ </p><p>
+ To initiate an <acronym class="acronym">SSL</acronym>-encrypted connection, the
+ frontend initially sends an SSLRequest message rather than a
+ StartupMessage. The server then responds with a single byte
+ containing <code class="literal">S</code> or <code class="literal">N</code>, indicating that it is
+ willing or unwilling to perform <acronym class="acronym">SSL</acronym>,
+ respectively. The frontend might close the connection at this point
+ if it is dissatisfied with the response. To continue after
+ <code class="literal">S</code>, perform an <acronym class="acronym">SSL</acronym> startup handshake
+ (not described here, part of the <acronym class="acronym">SSL</acronym>
+ specification) with the server. If this is successful, continue
+ with sending the usual StartupMessage. In this case the
+ StartupMessage and all subsequent data will be
+ <acronym class="acronym">SSL</acronym>-encrypted. To continue after
+ <code class="literal">N</code>, send the usual StartupMessage and proceed without
+ encryption.
+ (Alternatively, it is permissible to issue a GSSENCRequest message
+ after an <code class="literal">N</code> response to try to
+ use <acronym class="acronym">GSSAPI</acronym> encryption instead
+ of <acronym class="acronym">SSL</acronym>.)
+ </p><p>
+ The frontend should also be prepared to handle an ErrorMessage
+ response to SSLRequest from the server. This would only occur if
+ the server predates the addition of <acronym class="acronym">SSL</acronym> support
+ to <span class="productname">PostgreSQL</span>. (Such servers are now very ancient,
+ and likely do not exist in the wild anymore.)
+ In this case the connection must
+ be closed, but the frontend might choose to open a fresh connection
+ and proceed without requesting <acronym class="acronym">SSL</acronym>.
+ </p><p>
+ When <acronym class="acronym">SSL</acronym> encryption can be performed, the server
+ is expected to send only the single <code class="literal">S</code> byte and then
+ wait for the frontend to initiate an <acronym class="acronym">SSL</acronym> handshake.
+ If additional bytes are available to read at this point, it likely
+ means that a man-in-the-middle is attempting to perform a
+ buffer-stuffing attack
+ (<a class="ulink" href="https://www.postgresql.org/support/security/CVE-2021-23222/" target="_top">CVE-2021-23222</a>).
+ Frontends should be coded either to read exactly one byte from the
+ socket before turning the socket over to their SSL library, or to
+ treat it as a protocol violation if they find they have read additional
+ bytes.
+ </p><p>
+ An initial SSLRequest can also be used in a connection that is being
+ opened to send a CancelRequest message.
+ </p><p>
+ While the protocol itself does not provide a way for the server to
+ force <acronym class="acronym">SSL</acronym> encryption, the administrator can
+ configure the server to reject unencrypted sessions as a byproduct
+ of authentication checking.
+ </p></div><div class="sect2" id="id-1.10.6.7.13"><div class="titlepage"><div><div><h3 class="title">55.2.11. <acronym class="acronym">GSSAPI</acronym> Session Encryption</h3></div></div></div><p>
+ If <span class="productname">PostgreSQL</span> was built with
+ <acronym class="acronym">GSSAPI</acronym> support, frontend/backend communications
+ can be encrypted using <acronym class="acronym">GSSAPI</acronym>. This provides
+ communication security in environments where attackers might be
+ able to capture the session traffic. For more information on
+ encrypting <span class="productname">PostgreSQL</span> sessions with
+ <acronym class="acronym">GSSAPI</acronym>, see <a class="xref" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption">Section 19.10</a>.
+ </p><p>
+ To initiate a <acronym class="acronym">GSSAPI</acronym>-encrypted connection, the
+ frontend initially sends a GSSENCRequest message rather than a
+ StartupMessage. The server then responds with a single byte
+ containing <code class="literal">G</code> or <code class="literal">N</code>, indicating that it
+ is willing or unwilling to perform <acronym class="acronym">GSSAPI</acronym> encryption,
+ respectively. The frontend might close the connection at this point
+ if it is dissatisfied with the response. To continue after
+ <code class="literal">G</code>, using the GSSAPI C bindings as discussed in
+ <a class="ulink" href="https://tools.ietf.org/html/rfc2744" target="_top">RFC 2744</a>
+ or equivalent, perform a <acronym class="acronym">GSSAPI</acronym> initialization by
+ calling <code class="function">gss_init_sec_context()</code> in a loop and sending
+ the result to the server, starting with an empty input and then with each
+ result from the server, until it returns no output. When sending the
+ results of <code class="function">gss_init_sec_context()</code> to the server,
+ prepend the length of the message as a four byte integer in network byte
+ order.
+ To continue after
+ <code class="literal">N</code>, send the usual StartupMessage and proceed without
+ encryption.
+ (Alternatively, it is permissible to issue an SSLRequest message
+ after an <code class="literal">N</code> response to try to
+ use <acronym class="acronym">SSL</acronym> encryption instead
+ of <acronym class="acronym">GSSAPI</acronym>.)
+ </p><p>
+ The frontend should also be prepared to handle an ErrorMessage
+ response to GSSENCRequest from the server. This would only occur if
+ the server predates the addition of <acronym class="acronym">GSSAPI</acronym> encryption
+ support to <span class="productname">PostgreSQL</span>. In this case the
+ connection must be closed, but the frontend might choose to open a fresh
+ connection and proceed without requesting <acronym class="acronym">GSSAPI</acronym>
+ encryption.
+ </p><p>
+ When <acronym class="acronym">GSSAPI</acronym> encryption can be performed, the server
+ is expected to send only the single <code class="literal">G</code> byte and then
+ wait for the frontend to initiate a <acronym class="acronym">GSSAPI</acronym> handshake.
+ If additional bytes are available to read at this point, it likely
+ means that a man-in-the-middle is attempting to perform a
+ buffer-stuffing attack
+ (<a class="ulink" href="https://www.postgresql.org/support/security/CVE-2021-23222/" target="_top">CVE-2021-23222</a>).
+ Frontends should be coded either to read exactly one byte from the
+ socket before turning the socket over to their GSSAPI library, or to
+ treat it as a protocol violation if they find they have read additional
+ bytes.
+ </p><p>
+ An initial GSSENCRequest can also be used in a connection that is being
+ opened to send a CancelRequest message.
+ </p><p>
+ Once <acronym class="acronym">GSSAPI</acronym> encryption has been successfully
+ established, use <code class="function">gss_wrap()</code> to
+ encrypt the usual StartupMessage and all subsequent data, prepending the
+ length of the result from <code class="function">gss_wrap()</code> as a four byte
+ integer in network byte order to the actual encrypted payload. Note that
+ the server will only accept encrypted packets from the client which are less
+ than 16kB; <code class="function">gss_wrap_size_limit()</code> should be used by the
+ client to determine the size of the unencrypted message which will fit
+ within this limit and larger messages should be broken up into multiple
+ <code class="function">gss_wrap()</code> calls. Typical segments are 8kB of
+ unencrypted data, resulting in encrypted packets of slightly larger than 8kB
+ but well within the 16kB maximum. The server can be expected to not send
+ encrypted packets of larger than 16kB to the client.
+ </p><p>
+ While the protocol itself does not provide a way for the server to
+ force <acronym class="acronym">GSSAPI</acronym> encryption, the administrator can
+ configure the server to reject unencrypted sessions as a byproduct
+ of authentication checking.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-overview.html" title="55.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sasl-authentication.html" title="55.3. SASL Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.3. SASL Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-logical-replication.html b/doc/src/sgml/html/protocol-logical-replication.html
new file mode 100644
index 0000000..971707b
--- /dev/null
+++ b/doc/src/sgml/html/protocol-logical-replication.html
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.5. Logical Streaming Replication Protocol</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-replication.html" title="55.4. Streaming Replication Protocol" /><link rel="next" href="protocol-message-types.html" title="55.6. Message Data Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.5. Logical Streaming Replication Protocol</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-message-types.html" title="55.6. Message Data Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-LOGICAL-REPLICATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.5. Logical Streaming Replication Protocol</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="protocol-logical-replication.html#PROTOCOL-LOGICAL-REPLICATION-PARAMS">55.5.1. Logical Streaming Replication Parameters</a></span></dt><dt><span class="sect2"><a href="protocol-logical-replication.html#PROTOCOL-LOGICAL-MESSAGES">55.5.2. Logical Replication Protocol Messages</a></span></dt><dt><span class="sect2"><a href="protocol-logical-replication.html#PROTOCOL-LOGICAL-MESSAGES-FLOW">55.5.3. Logical Replication Protocol Message Flow</a></span></dt></dl></div><p>
+ This section describes the logical replication protocol, which is the message
+ flow started by the <code class="literal">START_REPLICATION</code>
+ <code class="literal">SLOT</code> <em class="replaceable"><code>slot_name</code></em>
+ <code class="literal">LOGICAL</code> replication command.
+ </p><p>
+ The logical streaming replication protocol builds on the primitives of
+ the physical streaming replication protocol.
+ </p><div class="sect2" id="PROTOCOL-LOGICAL-REPLICATION-PARAMS"><div class="titlepage"><div><div><h3 class="title">55.5.1. Logical Streaming Replication Parameters</h3></div></div></div><p>
+ The logical replication <code class="literal">START_REPLICATION</code> command
+ accepts following parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ proto_version
+ </span></dt><dd><p>
+ Protocol version. Currently versions <code class="literal">1</code>, <code class="literal">2</code>,
+ and <code class="literal">3</code> are supported.
+ </p><p>
+ Version <code class="literal">2</code> is supported only for server version 14
+ and above, and it allows streaming of large in-progress transactions.
+ </p><p>
+ Version <code class="literal">3</code> is supported only for server version 15
+ and above, and it allows streaming of two-phase commits.
+ </p></dd><dt><span class="term">
+ publication_names
+ </span></dt><dd><p>
+ Comma separated list of publication names for which to subscribe
+ (receive changes). The individual publication names are treated
+ as standard objects names and can be quoted the same as needed.
+ </p></dd></dl></div><p>
+
+ </p></div><div class="sect2" id="PROTOCOL-LOGICAL-MESSAGES"><div class="titlepage"><div><div><h3 class="title">55.5.2. Logical Replication Protocol Messages</h3></div></div></div><p>
+ The individual protocol messages are discussed in the following
+ subsections. Individual messages are described in
+ <a class="xref" href="protocol-logicalrep-message-formats.html" title="55.9. Logical Replication Message Formats">Section 55.9</a>.
+ </p><p>
+ All top-level protocol messages begin with a message type byte.
+ While represented in code as a character, this is a signed byte with no
+ associated encoding.
+ </p><p>
+ Since the streaming replication protocol supplies a message length there
+ is no need for top-level protocol messages to embed a length in their
+ header.
+ </p></div><div class="sect2" id="PROTOCOL-LOGICAL-MESSAGES-FLOW"><div class="titlepage"><div><div><h3 class="title">55.5.3. Logical Replication Protocol Message Flow</h3></div></div></div><p>
+ With the exception of the <code class="literal">START_REPLICATION</code> command and
+ the replay progress messages, all information flows only from the backend
+ to the frontend.
+ </p><p>
+ The logical replication protocol sends individual transactions one by one.
+ This means that all messages between a pair of Begin and Commit messages
+ belong to the same transaction. Similarly, all messages between a pair of
+ Begin Prepare and Prepare messages belong to the same transaction.
+ It also sends changes of large in-progress transactions between a pair of
+ Stream Start and Stream Stop messages. The last stream of such a transaction
+ contains a Stream Commit or Stream Abort message.
+ </p><p>
+ Every sent transaction contains zero or more DML messages (Insert,
+ Update, Delete). In case of a cascaded setup it can also contain Origin
+ messages. The origin message indicates that the transaction originated on
+ different replication node. Since a replication node in the scope of logical
+ replication protocol can be pretty much anything, the only identifier
+ is the origin name. It's downstream's responsibility to handle this as
+ needed (if needed). The Origin message is always sent before any DML
+ messages in the transaction.
+ </p><p>
+ Every DML message contains a relation OID, identifying the publisher's
+ relation that was acted on. Before the first DML message for a given
+ relation OID, a Relation message will be sent, describing the schema of
+ that relation. Subsequently, a new Relation message will be sent if
+ the relation's definition has changed since the last Relation message
+ was sent for it. (The protocol assumes that the client is capable of
+ remembering this metadata for as many relations as needed.)
+ </p><p>
+ Relation messages identify column types by their OIDs. In the case
+ of a built-in type, it is assumed that the client can look up that
+ type OID locally, so no additional data is needed. For a non-built-in
+ type OID, a Type message will be sent before the Relation message,
+ to provide the type name associated with that OID. Thus, a client that
+ needs to specifically identify the types of relation columns should
+ cache the contents of Type messages, and first consult that cache to
+ see if the type OID is defined there. If not, look up the type OID
+ locally.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-message-types.html" title="55.6. Message Data Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.4. Streaming Replication Protocol </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.6. Message Data Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-logicalrep-message-formats.html b/doc/src/sgml/html/protocol-logicalrep-message-formats.html
new file mode 100644
index 0000000..ea3a293
--- /dev/null
+++ b/doc/src/sgml/html/protocol-logicalrep-message-formats.html
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.9. Logical Replication Message Formats</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields" /><link rel="next" href="protocol-changes.html" title="55.10. Summary of Changes since Protocol 2.0" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.9. Logical Replication Message Formats</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-changes.html" title="55.10. Summary of Changes since Protocol 2.0">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.9. Logical Replication Message Formats</h2></div></div></div><p>
+ This section describes the detailed format of each logical replication
+ message. These messages are either returned by the replication slot SQL
+ interface or are sent by a walsender. In the case of a walsender, they are
+ encapsulated inside replication protocol WAL messages as described in
+ <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>, and generally obey the same message
+ flow as physical replication.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-BEGIN"><span class="term">Begin</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('B')</span></dt><dd><p>
+ Identifies the message as a begin message.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The final LSN of the transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-MESSAGE"><span class="term">Message</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('M')</span></dt><dd><p>
+ Identifies the message as a logical decoding message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ Flags; Either 0 for no flags or 1 if the logical decoding
+ message is transactional.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the logical decoding message.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The prefix of the logical decoding message.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of the content.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ The content of the logical decoding message.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-COMMIT"><span class="term">Commit</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('C')</span></dt><dd><p>
+ Identifies the message as a commit message.
+ </p></dd><dt><span class="term">Int8(0)</span></dt><dd><p>
+ Flags; currently unused.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the commit.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-ORIGIN"><span class="term">Origin</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('O')</span></dt><dd><p>
+ Identifies the message as an origin message.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the commit on the origin server.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Name of the origin.
+ </p></dd></dl></div><p>
+ Note that there can be multiple Origin messages inside a single transaction.
+ </p></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-RELATION"><span class="term">Relation</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as a relation message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the relation.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Namespace (empty string for <code class="literal">pg_catalog</code>).
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Relation name.
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ Replica identity setting for the relation (same as
+ <code class="structfield">relreplident</code> in <code class="structname">pg_class</code>).
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ Number of columns.
+ </p></dd></dl></div><p>
+ Next, the following message part appears for each column included in
+ the publication (except generated columns):
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int8</span></dt><dd><p>
+ Flags for the column. Currently can be either 0 for no flags
+ or 1 which marks the column as part of the key.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Name of the column.
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the column's data type.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Type modifier of the column (<code class="structfield">atttypmod</code>).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-TYPE"><span class="term">Type</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('Y')</span></dt><dd><p>
+ Identifies the message as a type message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the data type.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Namespace (empty string for <code class="literal">pg_catalog</code>).
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Name of the data type.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-INSERT"><span class="term">Insert</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('I')</span></dt><dd><p>
+ Identifies the message as an insert message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the relation corresponding to the ID in the relation
+ message.
+ </p></dd><dt><span class="term">Byte1('N')</span></dt><dd><p>
+ Identifies the following TupleData message as a new tuple.
+ </p></dd><dt><span class="term">TupleData</span></dt><dd><p>
+ TupleData message part representing the contents of new tuple.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-UPDATE"><span class="term">Update</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('U')</span></dt><dd><p>
+ Identifies the message as an update message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the relation corresponding to the ID in the relation
+ message.
+ </p></dd><dt><span class="term">Byte1('K')</span></dt><dd><p>
+ Identifies the following TupleData submessage as a key.
+ This field is optional and is only present if
+ the update changed data in any of the column(s) that are
+ part of the REPLICA IDENTITY index.
+ </p></dd><dt><span class="term">Byte1('O')</span></dt><dd><p>
+ Identifies the following TupleData submessage as an old tuple.
+ This field is optional and is only present if table in which
+ the update happened has REPLICA IDENTITY set to FULL.
+ </p></dd><dt><span class="term">TupleData</span></dt><dd><p>
+ TupleData message part representing the contents of the old tuple
+ or primary key. Only present if the previous 'O' or 'K' part
+ is present.
+ </p></dd><dt><span class="term">Byte1('N')</span></dt><dd><p>
+ Identifies the following TupleData message as a new tuple.
+ </p></dd><dt><span class="term">TupleData</span></dt><dd><p>
+ TupleData message part representing the contents of a new tuple.
+ </p></dd></dl></div><p>
+ The Update message may contain either a 'K' message part or an 'O' message part
+ or neither of them, but never both of them.
+ </p></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-DELETE"><span class="term">Delete</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('D')</span></dt><dd><p>
+ Identifies the message as a delete message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the relation corresponding to the ID in the relation
+ message.
+ </p></dd><dt><span class="term">Byte1('K')</span></dt><dd><p>
+ Identifies the following TupleData submessage as a key.
+ This field is present if the table in which the delete has
+ happened uses an index as REPLICA IDENTITY.
+ </p></dd><dt><span class="term">Byte1('O')</span></dt><dd><p>
+ Identifies the following TupleData message as an old tuple.
+ This field is present if the table in which the delete
+ happened has REPLICA IDENTITY set to FULL.
+ </p></dd><dt><span class="term">TupleData</span></dt><dd><p>
+ TupleData message part representing the contents of the old tuple
+ or primary key, depending on the previous field.
+ </p></dd></dl></div><p>
+ The Delete message may contain either a 'K' message part or an 'O' message part,
+ but never both of them.
+ </p></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-TRUNCATE"><span class="term">Truncate</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('T')</span></dt><dd><p>
+ Identifies the message as a truncate message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Number of relations
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ Option bits for <code class="command">TRUNCATE</code>:
+ 1 for <code class="literal">CASCADE</code>, 2 for <code class="literal">RESTART IDENTITY</code>
+ </p></dd><dt><span class="term">Int32 (Oid)</span></dt><dd><p>
+ OID of the relation corresponding to the ID in the relation
+ message. This field is repeated for each relation.
+ </p></dd></dl></div></dd></dl></div><p>
+ The following messages (Stream Start, Stream Stop, Stream Commit, and
+ Stream Abort) are available since protocol version 2.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-STREAM-START"><span class="term">Stream Start</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('S')</span></dt><dd><p>
+ Identifies the message as a stream start message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ A value of 1 indicates this is the first stream segment for
+ this XID, 0 for any other stream segment.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-STREAM-STOP"><span class="term">Stream Stop</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('E')</span></dt><dd><p>
+ Identifies the message as a stream stop message.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-STREAM-COMMIT"><span class="term">Stream Commit</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('c')</span></dt><dd><p>
+ Identifies the message as a stream commit message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">Int8(0)</span></dt><dd><p>
+ Flags; currently unused.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the commit.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-STREAM-ABORT"><span class="term">Stream Abort</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('A')</span></dt><dd><p>
+ Identifies the message as a stream abort message.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the subtransaction (will be same as xid of the transaction for top-level
+ transactions).
+ </p></dd></dl></div></dd></dl></div><p>
+ The following messages (Begin Prepare, Prepare, Commit Prepared, Rollback Prepared, Stream Prepare)
+ are available since protocol version 3.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-BEGIN-PREPARE"><span class="term">Begin Prepare</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('b')</span></dt><dd><p>
+ Identifies the message as the beginning of a prepared transaction message.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the prepare.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The user defined GID of the prepared transaction.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-PREPARE"><span class="term">Prepare</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('P')</span></dt><dd><p>
+ Identifies the message as a prepared transaction message.
+ </p></dd><dt><span class="term">Int8(0)</span></dt><dd><p>
+ Flags; currently unused.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the prepare.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The user defined GID of the prepared transaction.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-COMMIT-PREPARED"><span class="term">Commit Prepared</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('K')</span></dt><dd><p>
+ Identifies the message as the commit of a prepared transaction message.
+ </p></dd><dt><span class="term">Int8(0)</span></dt><dd><p>
+ Flags; currently unused.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the commit of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the commit of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The user defined GID of the prepared transaction.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-ROLLBACK-PREPARED"><span class="term">Rollback Prepared</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('r')</span></dt><dd><p>
+ Identifies the message as the rollback of a prepared transaction message.
+ </p></dd><dt><span class="term">Int8(0)</span></dt><dd><p>
+ Flags; currently unused.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the rollback of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Rollback timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The user defined GID of the prepared transaction.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-STREAM-PREPARE"><span class="term">Stream Prepare</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('p')</span></dt><dd><p>
+ Identifies the message as a stream prepared transaction message.
+ </p></dd><dt><span class="term">Int8(0)</span></dt><dd><p>
+ Flags; currently unused.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The LSN of the prepare.
+ </p></dd><dt><span class="term">Int64 (XLogRecPtr)</span></dt><dd><p>
+ The end LSN of the prepared transaction.
+ </p></dd><dt><span class="term">Int64 (TimestampTz)</span></dt><dd><p>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </p></dd><dt><span class="term">Int32 (TransactionId)</span></dt><dd><p>
+ Xid of the transaction.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The user defined GID of the prepared transaction.
+ </p></dd></dl></div></dd></dl></div><p>
+ The following message parts are shared by the above messages.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-LOGICALREP-MESSAGE-FORMATS-TUPLEDATA"><span class="term">TupleData</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int16</span></dt><dd><p>
+ Number of columns.
+ </p></dd></dl></div><p>
+ Next, one of the following submessages appears for each column (except generated columns):
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('n')</span></dt><dd><p>
+ Identifies the data as NULL value.
+ </p></dd></dl></div><p>
+ Or
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('u')</span></dt><dd><p>
+ Identifies unchanged TOASTed value (the actual value is not
+ sent).
+ </p></dd></dl></div><p>
+ Or
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('t')</span></dt><dd><p>
+ Identifies the data as text formatted value.
+ </p></dd></dl></div><p>
+ Or
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('b')</span></dt><dd><p>
+ Identifies the data as binary formatted value.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of the column value.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ The value of the column, either in binary or in text format.
+ (As specified in the preceding format byte).
+ <em class="replaceable"><code>n</code></em> is the above length.
+ </p></dd></dl></div><p>
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-changes.html" title="55.10. Summary of Changes since Protocol 2.0">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.8. Error and Notice Message Fields </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.10. Summary of Changes since Protocol 2.0</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-message-formats.html b/doc/src/sgml/html/protocol-message-formats.html
new file mode 100644
index 0000000..d32d4e1
--- /dev/null
+++ b/doc/src/sgml/html/protocol-message-formats.html
@@ -0,0 +1,676 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.7. Message Formats</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-message-types.html" title="55.6. Message Data Types" /><link rel="next" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.7. Message Formats</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-message-types.html" title="55.6. Message Data Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-MESSAGE-FORMATS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.7. Message Formats</h2></div></div></div><p>
+ This section describes the detailed format of each message. Each is marked to
+ indicate that it can be sent by a frontend (F), a backend (B), or both
+ (F &amp; B).
+ Notice that although each message includes a byte count at the beginning,
+ the message format is defined so that the message end can be found without
+ reference to the byte count. This aids validity checking. (The CopyData
+ message is an exception, because it forms part of a data stream; the contents
+ of any individual CopyData message cannot be interpretable on their own.)
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONOK"><span class="term">AuthenticationOk (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(0)</span></dt><dd><p>
+ Specifies that the authentication was successful.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONKERBEROSV5"><span class="term">AuthenticationKerberosV5 (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(2)</span></dt><dd><p>
+ Specifies that Kerberos V5 authentication is required.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONCLEARTEXTPASSWORD"><span class="term">AuthenticationCleartextPassword (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(3)</span></dt><dd><p>
+ Specifies that a clear-text password is required.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONMD5PASSWORD"><span class="term">AuthenticationMD5Password (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(12)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(5)</span></dt><dd><p>
+ Specifies that an MD5-encrypted password is required.
+ </p></dd><dt><span class="term">Byte4</span></dt><dd><p>
+ The salt to use when encrypting the password.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONSCMCREDENTIAL"><span class="term">AuthenticationSCMCredential (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(6)</span></dt><dd><p>
+ Specifies that an SCM credentials message is required.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONGSS"><span class="term">AuthenticationGSS (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(7)</span></dt><dd><p>
+ Specifies that GSSAPI authentication is required.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONGSSCONTINUE"><span class="term">AuthenticationGSSContinue (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Specifies that this message contains GSSAPI or SSPI data.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ GSSAPI or SSPI authentication data.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONSSPI"><span class="term">AuthenticationSSPI (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(9)</span></dt><dd><p>
+ Specifies that SSPI authentication is required.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONSASL"><span class="term">AuthenticationSASL (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(10)</span></dt><dd><p>
+ Specifies that SASL authentication is required.
+ </p></dd></dl></div><p>
+ The message body is a list of SASL authentication mechanisms, in the
+ server's order of preference. A zero byte is required as terminator after
+ the last authentication mechanism name. For each mechanism, there is the
+ following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">String</span></dt><dd><p>
+ Name of a SASL authentication mechanism.
+ </p></dd></dl></div><p>
+ </p></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONSASLCONTINUE"><span class="term">AuthenticationSASLContinue (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(11)</span></dt><dd><p>
+ Specifies that this message contains a SASL challenge.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ SASL data, specific to the SASL mechanism being used.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-AUTHENTICATIONSASLFINAL"><span class="term">AuthenticationSASLFinal (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('R')</span></dt><dd><p>
+ Identifies the message as an authentication request.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(12)</span></dt><dd><p>
+ Specifies that SASL authentication has completed.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ SASL outcome "additional data", specific to the SASL mechanism
+ being used.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-BACKENDKEYDATA"><span class="term">BackendKeyData (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('K')</span></dt><dd><p>
+ Identifies the message as cancellation key data.
+ The frontend must save these values if it wishes to be
+ able to issue CancelRequest messages later.
+ </p></dd><dt><span class="term">Int32(12)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The process ID of this backend.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The secret key of this backend.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-BIND"><span class="term">Bind (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('B')</span></dt><dd><p>
+ Identifies the message as a Bind command.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the destination portal
+ (an empty string selects the unnamed portal).
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the source prepared statement
+ (an empty string selects the unnamed prepared statement).
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of parameter format codes that follow
+ (denoted <em class="replaceable"><code>C</code></em> below).
+ This can be zero to indicate that there are no parameters
+ or that the parameters all use the default format (text);
+ or one, in which case the specified format code is applied
+ to all parameters; or it can equal the actual number of
+ parameters.
+ </p></dd><dt><span class="term">Int16[<em class="replaceable"><code>C</code></em>]</span></dt><dd><p>
+ The parameter format codes. Each must presently be
+ zero (text) or one (binary).
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of parameter values that follow (possibly zero).
+ This must match the number of parameters needed by the query.
+ </p></dd></dl></div><p>
+ Next, the following pair of fields appear for each parameter:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32</span></dt><dd><p>
+ The length of the parameter value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL parameter value.
+ No value bytes follow in the NULL case.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ The value of the parameter, in the format indicated by the
+ associated format code.
+ <em class="replaceable"><code>n</code></em> is the above length.
+ </p></dd></dl></div><p>
+ After the last parameter, the following fields appear:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int16</span></dt><dd><p>
+ The number of result-column format codes that follow
+ (denoted <em class="replaceable"><code>R</code></em> below).
+ This can be zero to indicate that there are no result columns
+ or that the result columns should all use the default format
+ (text);
+ or one, in which case the specified format code is applied
+ to all result columns (if any); or it can equal the actual
+ number of result columns of the query.
+ </p></dd><dt><span class="term">Int16[<em class="replaceable"><code>R</code></em>]</span></dt><dd><p>
+ The result-column format codes. Each must presently be
+ zero (text) or one (binary).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-BINDCOMPLETE"><span class="term">BindComplete (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('2')</span></dt><dd><p>
+ Identifies the message as a Bind-complete indicator.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-CANCELREQUEST"><span class="term">CancelRequest (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32(16)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(80877102)</span></dt><dd><p>
+ The cancel request code. The value is chosen to contain
+ <code class="literal">1234</code> in the most significant 16 bits, and <code class="literal">5678</code> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The process ID of the target backend.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The secret key for the target backend.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-CLOSE"><span class="term">Close (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('C')</span></dt><dd><p>
+ Identifies the message as a Close command.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Byte1</span></dt><dd><p>
+ '<code class="literal">S</code>' to close a prepared statement; or
+ '<code class="literal">P</code>' to close a portal.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the prepared statement or portal to close
+ (an empty string selects the unnamed prepared statement
+ or portal).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-CLOSECOMPLETE"><span class="term">CloseComplete (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('3')</span></dt><dd><p>
+ Identifies the message as a Close-complete indicator.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COMMANDCOMPLETE"><span class="term">CommandComplete (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('C')</span></dt><dd><p>
+ Identifies the message as a command-completed response.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The command tag. This is usually a single
+ word that identifies which SQL command was completed.
+ </p><p>
+ For an <code class="command">INSERT</code> command, the tag is
+ <code class="literal">INSERT <em class="replaceable"><code>oid</code></em>
+ <em class="replaceable"><code>rows</code></em></code>, where
+ <em class="replaceable"><code>rows</code></em> is the number of rows
+ inserted. <em class="replaceable"><code>oid</code></em> used to be the object ID
+ of the inserted row if <em class="replaceable"><code>rows</code></em> was 1
+ and the target table had OIDs, but OIDs system columns are
+ not supported anymore; therefore <em class="replaceable"><code>oid</code></em>
+ is always 0.
+ </p><p>
+ For a <code class="command">DELETE</code> command, the tag is
+ <code class="literal">DELETE <em class="replaceable"><code>rows</code></em></code> where
+ <em class="replaceable"><code>rows</code></em> is the number of rows deleted.
+ </p><p>
+ For an <code class="command">UPDATE</code> command, the tag is
+ <code class="literal">UPDATE <em class="replaceable"><code>rows</code></em></code> where
+ <em class="replaceable"><code>rows</code></em> is the number of rows updated.
+ </p><p>
+ For a <code class="command">MERGE</code> command, the tag is
+ <code class="literal">MERGE <em class="replaceable"><code>rows</code></em></code> where
+ <em class="replaceable"><code>rows</code></em> is the number of rows inserted,
+ updated, or deleted.
+ </p><p>
+ For a <code class="command">SELECT</code> or <code class="command">CREATE TABLE AS</code>
+ command, the tag is <code class="literal">SELECT <em class="replaceable"><code>rows</code></em></code>
+ where <em class="replaceable"><code>rows</code></em> is the number of rows retrieved.
+ </p><p>
+ For a <code class="command">MOVE</code> command, the tag is
+ <code class="literal">MOVE <em class="replaceable"><code>rows</code></em></code> where
+ <em class="replaceable"><code>rows</code></em> is the number of rows the
+ cursor's position has been changed by.
+ </p><p>
+ For a <code class="command">FETCH</code> command, the tag is
+ <code class="literal">FETCH <em class="replaceable"><code>rows</code></em></code> where
+ <em class="replaceable"><code>rows</code></em> is the number of rows that
+ have been retrieved from the cursor.
+ </p><p>
+ For a <code class="command">COPY</code> command, the tag is
+ <code class="literal">COPY <em class="replaceable"><code>rows</code></em></code> where
+ <em class="replaceable"><code>rows</code></em> is the number of rows copied.
+ (Note: the row count appears only in
+ <span class="productname">PostgreSQL</span> 8.2 and later.)
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COPYDATA"><span class="term">CopyData (F &amp; B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('d')</span></dt><dd><p>
+ Identifies the message as <code class="command">COPY</code> data.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ Data that forms part of a <code class="command">COPY</code> data stream. Messages sent
+ from the backend will always correspond to single data rows,
+ but messages sent by frontends might divide the data stream
+ arbitrarily.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COPYDONE"><span class="term">CopyDone (F &amp; B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('c')</span></dt><dd><p>
+ Identifies the message as a <code class="command">COPY</code>-complete indicator.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COPYFAIL"><span class="term">CopyFail (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('f')</span></dt><dd><p>
+ Identifies the message as a <code class="command">COPY</code>-failure indicator.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ An error message to report as the cause of failure.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COPYINRESPONSE"><span class="term">CopyInResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('G')</span></dt><dd><p>
+ Identifies the message as a Start Copy In response.
+ The frontend must now send copy-in data (if not
+ prepared to do so, send a CopyFail message).
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ 0 indicates the overall <code class="command">COPY</code> format is textual (rows
+ separated by newlines, columns separated by separator
+ characters, etc.).
+ 1 indicates the overall copy format is binary (similar
+ to DataRow format).
+ See <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a>
+ for more information.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of columns in the data to be copied
+ (denoted <em class="replaceable"><code>N</code></em> below).
+ </p></dd><dt><span class="term">Int16[<em class="replaceable"><code>N</code></em>]</span></dt><dd><p>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COPYOUTRESPONSE"><span class="term">CopyOutResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('H')</span></dt><dd><p>
+ Identifies the message as a Start Copy Out response.
+ This message will be followed by copy-out data.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ 0 indicates the overall <code class="command">COPY</code> format
+ is textual (rows separated by newlines, columns
+ separated by separator characters, etc.). 1 indicates
+ the overall copy format is binary (similar to DataRow
+ format). See <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for more information.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of columns in the data to be copied
+ (denoted <em class="replaceable"><code>N</code></em> below).
+ </p></dd><dt><span class="term">Int16[<em class="replaceable"><code>N</code></em>]</span></dt><dd><p>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-COPYBOTHRESPONSE"><span class="term">CopyBothResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('W')</span></dt><dd><p>
+ Identifies the message as a Start Copy Both response.
+ This message is used only for Streaming Replication.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int8</span></dt><dd><p>
+ 0 indicates the overall <code class="command">COPY</code> format
+ is textual (rows separated by newlines, columns
+ separated by separator characters, etc.). 1 indicates
+ the overall copy format is binary (similar to DataRow
+ format). See <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for more information.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of columns in the data to be copied
+ (denoted <em class="replaceable"><code>N</code></em> below).
+ </p></dd><dt><span class="term">Int16[<em class="replaceable"><code>N</code></em>]</span></dt><dd><p>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-DATAROW"><span class="term">DataRow (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('D')</span></dt><dd><p>
+ Identifies the message as a data row.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of column values that follow (possibly zero).
+ </p></dd></dl></div><p>
+ Next, the following pair of fields appear for each column:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32</span></dt><dd><p>
+ The length of the column value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL column value.
+ No value bytes follow in the NULL case.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ The value of the column, in the format indicated by the
+ associated format code.
+ <em class="replaceable"><code>n</code></em> is the above length.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-DESCRIBE"><span class="term">Describe (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('D')</span></dt><dd><p>
+ Identifies the message as a Describe command.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Byte1</span></dt><dd><p>
+ '<code class="literal">S</code>' to describe a prepared statement; or
+ '<code class="literal">P</code>' to describe a portal.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the prepared statement or portal to describe
+ (an empty string selects the unnamed prepared statement
+ or portal).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-EMPTYQUERYRESPONSE"><span class="term">EmptyQueryResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('I')</span></dt><dd><p>
+ Identifies the message as a response to an empty query string.
+ (This substitutes for CommandComplete.)
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-ERRORRESPONSE"><span class="term">ErrorResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('E')</span></dt><dd><p>
+ Identifies the message as an error.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div><p>
+ The message body consists of one or more identified fields,
+ followed by a zero byte as a terminator. Fields can appear in
+ any order. For each field there is the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1</span></dt><dd><p>
+ A code identifying the field type; if zero, this is
+ the message terminator and no string follows.
+ The presently defined field types are listed in
+ <a class="xref" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields">Section 55.8</a>.
+ Since more field types might be added in future,
+ frontends should silently ignore fields of unrecognized
+ type.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The field value.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-EXECUTE"><span class="term">Execute (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('E')</span></dt><dd><p>
+ Identifies the message as an Execute command.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the portal to execute
+ (an empty string selects the unnamed portal).
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Maximum number of rows to return, if portal contains
+ a query that returns rows (ignored otherwise). Zero
+ denotes <span class="quote">“<span class="quote">no limit</span>”</span>.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-FLUSH"><span class="term">Flush (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('H')</span></dt><dd><p>
+ Identifies the message as a Flush command.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-FUNCTIONCALL"><span class="term">FunctionCall (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('F')</span></dt><dd><p>
+ Identifies the message as a function call.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Specifies the object ID of the function to call.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of argument format codes that follow
+ (denoted <em class="replaceable"><code>C</code></em> below).
+ This can be zero to indicate that there are no arguments
+ or that the arguments all use the default format (text);
+ or one, in which case the specified format code is applied
+ to all arguments; or it can equal the actual number of
+ arguments.
+ </p></dd><dt><span class="term">Int16[<em class="replaceable"><code>C</code></em>]</span></dt><dd><p>
+ The argument format codes. Each must presently be
+ zero (text) or one (binary).
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ Specifies the number of arguments being supplied to the
+ function.
+ </p></dd></dl></div><p>
+ Next, the following pair of fields appear for each argument:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32</span></dt><dd><p>
+ The length of the argument value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL argument value.
+ No value bytes follow in the NULL case.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ The value of the argument, in the format indicated by the
+ associated format code.
+ <em class="replaceable"><code>n</code></em> is the above length.
+ </p></dd></dl></div><p>
+ After the last argument, the following field appears:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int16</span></dt><dd><p>
+ The format code for the function result. Must presently be
+ zero (text) or one (binary).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-FUNCTIONCALLRESPONSE"><span class="term">FunctionCallResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('V')</span></dt><dd><p>
+ Identifies the message as a function call result.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The length of the function result value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL function result.
+ No value bytes follow in the NULL case.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ The value of the function result, in the format indicated by
+ the associated format code.
+ <em class="replaceable"><code>n</code></em> is the above length.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-GSSENCREQUEST"><span class="term">GSSENCRequest (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(80877104)</span></dt><dd><p>
+ The <acronym class="acronym">GSSAPI</acronym> Encryption request code. The value is chosen to contain
+ <code class="literal">1234</code> in the most significant 16 bits, and <code class="literal">5680</code> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-GSSRESPONSE"><span class="term">GSSResponse (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('p')</span></dt><dd><p>
+ Identifies the message as a GSSAPI or SSPI response. Note that
+ this is also used for SASL and password response messages.
+ The exact message type can be deduced from the context.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ GSSAPI/SSPI specific message data.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-NEGOTIATEPROTOCOLVERSION"><span class="term">NegotiateProtocolVersion (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('v')</span></dt><dd><p>
+ Identifies the message as a protocol version negotiation
+ message.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Newest minor protocol version supported by the server
+ for the major protocol version requested by the client.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Number of protocol options not recognized by the server.
+ </p></dd></dl></div><p>
+ Then, for protocol option not recognized by the server, there
+ is the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">String</span></dt><dd><p>
+ The option name.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-NODATA"><span class="term">NoData (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('n')</span></dt><dd><p>
+ Identifies the message as a no-data indicator.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-NOTICERESPONSE"><span class="term">NoticeResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('N')</span></dt><dd><p>
+ Identifies the message as a notice.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div><p>
+ The message body consists of one or more identified fields,
+ followed by a zero byte as a terminator. Fields can appear in
+ any order. For each field there is the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1</span></dt><dd><p>
+ A code identifying the field type; if zero, this is
+ the message terminator and no string follows.
+ The presently defined field types are listed in
+ <a class="xref" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields">Section 55.8</a>.
+ Since more field types might be added in future,
+ frontends should silently ignore fields of unrecognized
+ type.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The field value.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-NOTIFICATIONRESPONSE"><span class="term">NotificationResponse (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('A')</span></dt><dd><p>
+ Identifies the message as a notification response.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The process ID of the notifying backend process.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the channel that the notify has been raised on.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The <span class="quote">“<span class="quote">payload</span>”</span> string passed from the notifying process.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-PARAMETERDESCRIPTION"><span class="term">ParameterDescription (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('t')</span></dt><dd><p>
+ Identifies the message as a parameter description.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of parameters used by the statement
+ (can be zero).
+ </p></dd></dl></div><p>
+ Then, for each parameter, there is the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32</span></dt><dd><p>
+ Specifies the object ID of the parameter data type.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-PARAMETERSTATUS"><span class="term">ParameterStatus (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('S')</span></dt><dd><p>
+ Identifies the message as a run-time parameter status report.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the run-time parameter being reported.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The current value of the parameter.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-PARSE"><span class="term">Parse (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('P')</span></dt><dd><p>
+ Identifies the message as a Parse command.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The name of the destination prepared statement
+ (an empty string selects the unnamed prepared statement).
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The query string to be parsed.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The number of parameter data types specified
+ (can be zero). Note that this is not an indication of
+ the number of parameters that might appear in the
+ query string, only the number that the frontend wants to
+ prespecify types for.
+ </p></dd></dl></div><p>
+ Then, for each parameter, there is the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32</span></dt><dd><p>
+ Specifies the object ID of the parameter data type.
+ Placing a zero here is equivalent to leaving the type
+ unspecified.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-PARSECOMPLETE"><span class="term">ParseComplete (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('1')</span></dt><dd><p>
+ Identifies the message as a Parse-complete indicator.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-PASSWORDMESSAGE"><span class="term">PasswordMessage (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('p')</span></dt><dd><p>
+ Identifies the message as a password response. Note that
+ this is also used for GSSAPI, SSPI and SASL response messages.
+ The exact message type can be deduced from the context.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The password (encrypted, if requested).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-PORTALSUSPENDED"><span class="term">PortalSuspended (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('s')</span></dt><dd><p>
+ Identifies the message as a portal-suspended indicator.
+ Note this only appears if an Execute message's row-count limit
+ was reached.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-QUERY"><span class="term">Query (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('Q')</span></dt><dd><p>
+ Identifies the message as a simple query.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The query string itself.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-READYFORQUERY"><span class="term">ReadyForQuery (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('Z')</span></dt><dd><p>
+ Identifies the message type. ReadyForQuery is sent
+ whenever the backend is ready for a new query cycle.
+ </p></dd><dt><span class="term">Int32(5)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Byte1</span></dt><dd><p>
+ Current backend transaction status indicator.
+ Possible values are '<code class="literal">I</code>' if idle (not in
+ a transaction block); '<code class="literal">T</code>' if in a transaction
+ block; or '<code class="literal">E</code>' if in a failed transaction
+ block (queries will be rejected until block is ended).
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-ROWDESCRIPTION"><span class="term">RowDescription (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('T')</span></dt><dd><p>
+ Identifies the message as a row description.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ Specifies the number of fields in a row (can be zero).
+ </p></dd></dl></div><p>
+ Then, for each field, there is the following:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">String</span></dt><dd><p>
+ The field name.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ If the field can be identified as a column of a specific
+ table, the object ID of the table; otherwise zero.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ If the field can be identified as a column of a specific
+ table, the attribute number of the column; otherwise zero.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The object ID of the field's data type.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The data type size (see <code class="varname">pg_type.typlen</code>).
+ Note that negative values denote variable-width types.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The type modifier (see <code class="varname">pg_attribute.atttypmod</code>).
+ The meaning of the modifier is type-specific.
+ </p></dd><dt><span class="term">Int16</span></dt><dd><p>
+ The format code being used for the field. Currently will
+ be zero (text) or one (binary). In a RowDescription
+ returned from the statement variant of Describe, the
+ format code is not yet known and will always be zero.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-SASLINITIALRESPONSE"><span class="term">SASLInitialResponse (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('p')</span></dt><dd><p>
+ Identifies the message as an initial SASL response. Note that
+ this is also used for GSSAPI, SSPI and password response messages.
+ The exact message type is deduced from the context.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ Name of the SASL authentication mechanism that the client
+ selected.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of SASL mechanism specific "Initial Client Response" that
+ follows, or -1 if there is no Initial Response.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ SASL mechanism specific "Initial Response".
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-SASLRESPONSE"><span class="term">SASLResponse (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('p')</span></dt><dd><p>
+ Identifies the message as a SASL response. Note that
+ this is also used for GSSAPI, SSPI and password response messages.
+ The exact message type can be deduced from the context.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ SASL mechanism specific message data.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-SSLREQUEST"><span class="term">SSLRequest (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32(8)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(80877103)</span></dt><dd><p>
+ The <acronym class="acronym">SSL</acronym> request code. The value is chosen to contain
+ <code class="literal">1234</code> in the most significant 16 bits, and <code class="literal">5679</code> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-STARTUPMESSAGE"><span class="term">StartupMessage (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int32</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd><dt><span class="term">Int32(196608)</span></dt><dd><p>
+ The protocol version number. The most significant 16 bits are
+ the major version number (3 for the protocol described here).
+ The least significant 16 bits are the minor version number
+ (0 for the protocol described here).
+ </p></dd></dl></div><p>
+ The protocol version number is followed by one or more pairs of
+ parameter name and value strings. A zero byte is required as a
+ terminator after the last name/value pair.
+ Parameters can appear in any
+ order. <code class="literal">user</code> is required, others are optional.
+ Each parameter is specified as:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">String</span></dt><dd><p>
+ The parameter name. Currently recognized names are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">user</code></span></dt><dd><p>
+ The database user name to connect as. Required;
+ there is no default.
+ </p></dd><dt><span class="term"><code class="literal">database</code></span></dt><dd><p>
+ The database to connect to. Defaults to the user name.
+ </p></dd><dt><span class="term"><code class="literal">options</code></span></dt><dd><p>
+ Command-line arguments for the backend. (This is
+ deprecated in favor of setting individual run-time
+ parameters.) Spaces within this string are
+ considered to separate arguments, unless escaped with
+ a backslash (<code class="literal">\</code>); write <code class="literal">\\</code> to
+ represent a literal backslash.
+ </p></dd><dt><span class="term"><code class="literal">replication</code></span></dt><dd><p>
+ Used to connect in streaming replication mode, where
+ a small set of replication commands can be issued
+ instead of SQL statements. Value can be
+ <code class="literal">true</code>, <code class="literal">false</code>, or
+ <code class="literal">database</code>, and the default is
+ <code class="literal">false</code>. See
+ <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a> for details.
+ </p></dd></dl></div><p>
+
+ In addition to the above, other parameters may be listed.
+ Parameter names beginning with <code class="literal">_pq_.</code> are
+ reserved for use as protocol extensions, while others are
+ treated as run-time parameters to be set at backend start
+ time. Such settings will be applied during backend start
+ (after parsing the command-line arguments if any) and will
+ act as session defaults.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The parameter value.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-SYNC"><span class="term">Sync (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('S')</span></dt><dd><p>
+ Identifies the message as a Sync command.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-MESSAGE-FORMATS-TERMINATE"><span class="term">Terminate (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('X')</span></dt><dd><p>
+ Identifies the message as a termination.
+ </p></dd><dt><span class="term">Int32(4)</span></dt><dd><p>
+ Length of message contents in bytes, including self.
+ </p></dd></dl></div></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-message-types.html" title="55.6. Message Data Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-error-fields.html" title="55.8. Error and Notice Message Fields">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.6. Message Data Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.8. Error and Notice Message Fields</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-message-types.html b/doc/src/sgml/html/protocol-message-types.html
new file mode 100644
index 0000000..fdd2938
--- /dev/null
+++ b/doc/src/sgml/html/protocol-message-types.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.6. Message Data Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol" /><link rel="next" href="protocol-message-formats.html" title="55.7. Message Formats" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.6. Message Data Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-message-formats.html" title="55.7. Message Formats">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-MESSAGE-TYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.6. Message Data Types</h2></div></div></div><p>
+ This section describes the base data types used in messages.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Int<em class="replaceable"><code>n</code></em>(<em class="replaceable"><code>i</code></em>)</span></dt><dd><p>
+ An <em class="replaceable"><code>n</code></em>-bit integer in network byte
+ order (most significant byte first).
+ If <em class="replaceable"><code>i</code></em> is specified it
+ is the exact value that will appear, otherwise the value
+ is variable. Eg. Int16, Int32(42).
+ </p></dd><dt><span class="term">Int<em class="replaceable"><code>n</code></em>[<em class="replaceable"><code>k</code></em>]</span></dt><dd><p>
+ An array of <em class="replaceable"><code>k</code></em>
+ <em class="replaceable"><code>n</code></em>-bit integers, each in network
+ byte order. The array length <em class="replaceable"><code>k</code></em>
+ is always determined by an earlier field in the message.
+ Eg. Int16[M].
+ </p></dd><dt><span class="term">String(<em class="replaceable"><code>s</code></em>)</span></dt><dd><p>
+ A null-terminated string (C-style string). There is no
+ specific length limitation on strings.
+ If <em class="replaceable"><code>s</code></em> is specified it is the exact
+ value that will appear, otherwise the value is variable.
+ Eg. String, String("user").
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="emphasis"><em>There is no predefined limit</em></span> on the length of a string
+ that can be returned by the backend. Good coding strategy for a frontend
+ is to use an expandable buffer so that anything that fits in memory can be
+ accepted. If that's not feasible, read the full string and discard trailing
+ characters that don't fit into your fixed-size buffer.
+ </p></div></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em>(<em class="replaceable"><code>c</code></em>)</span></dt><dd><p>
+ Exactly <em class="replaceable"><code>n</code></em> bytes. If the field
+ width <em class="replaceable"><code>n</code></em> is not a constant, it is
+ always determinable from an earlier field in the message.
+ If <em class="replaceable"><code>c</code></em> is specified it is the exact
+ value. Eg. Byte2, Byte1('\n').
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-message-formats.html" title="55.7. Message Formats">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.5. Logical Streaming Replication Protocol </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.7. Message Formats</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-overview.html b/doc/src/sgml/html/protocol-overview.html
new file mode 100644
index 0000000..722603b
--- /dev/null
+++ b/doc/src/sgml/html/protocol-overview.html
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol" /><link rel="next" href="protocol-flow.html" title="55.2. Message Flow" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-flow.html" title="55.2. Message Flow">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.1. Overview</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="protocol-overview.html#PROTOCOL-MESSAGE-CONCEPTS">55.1.1. Messaging Overview</a></span></dt><dt><span class="sect2"><a href="protocol-overview.html#PROTOCOL-QUERY-CONCEPTS">55.1.2. Extended Query Overview</a></span></dt><dt><span class="sect2"><a href="protocol-overview.html#PROTOCOL-FORMAT-CODES">55.1.3. Formats and Format Codes</a></span></dt></dl></div><p>
+ The protocol has separate phases for startup and normal operation.
+ In the startup phase, the frontend opens a connection to the server
+ and authenticates itself to the satisfaction of the server. (This might
+ involve a single message, or multiple messages depending on the
+ authentication method being used.) If all goes well, the server then sends
+ status information to the frontend, and finally enters normal operation.
+ Except for the initial startup-request message, this part of the
+ protocol is driven by the server.
+ </p><p>
+ During normal operation, the frontend sends queries and
+ other commands to the backend, and the backend sends back query results
+ and other responses. There are a few cases (such as <code class="command">NOTIFY</code>)
+ wherein the
+ backend will send unsolicited messages, but for the most part this portion
+ of a session is driven by frontend requests.
+ </p><p>
+ Termination of the session is normally by frontend choice, but can be
+ forced by the backend in certain cases. In any case, when the backend
+ closes the connection, it will roll back any open (incomplete) transaction
+ before exiting.
+ </p><p>
+ Within normal operation, SQL commands can be executed through either of
+ two sub-protocols. In the <span class="quote">“<span class="quote">simple query</span>”</span> protocol, the frontend
+ just sends a textual query string, which is parsed and immediately
+ executed by the backend. In the <span class="quote">“<span class="quote">extended query</span>”</span> protocol,
+ processing of queries is separated into multiple steps: parsing,
+ binding of parameter values, and execution. This offers flexibility
+ and performance benefits, at the cost of extra complexity.
+ </p><p>
+ Normal operation has additional sub-protocols for special operations
+ such as <code class="command">COPY</code>.
+ </p><div class="sect2" id="PROTOCOL-MESSAGE-CONCEPTS"><div class="titlepage"><div><div><h3 class="title">55.1.1. Messaging Overview</h3></div></div></div><p>
+ All communication is through a stream of messages. The first byte of a
+ message identifies the message type, and the next four bytes specify the
+ length of the rest of the message (this length count includes itself, but
+ not the message-type byte). The remaining contents of the message are
+ determined by the message type. For historical reasons, the very first
+ message sent by the client (the startup message) has no initial
+ message-type byte.
+ </p><p>
+ To avoid losing synchronization with the message stream, both servers and
+ clients typically read an entire message into a buffer (using the byte
+ count) before attempting to process its contents. This allows easy
+ recovery if an error is detected while processing the contents. In
+ extreme situations (such as not having enough memory to buffer the
+ message), the receiver can use the byte count to determine how much
+ input to skip before it resumes reading messages.
+ </p><p>
+ Conversely, both servers and clients must take care never to send an
+ incomplete message. This is commonly done by marshaling the entire message
+ in a buffer before beginning to send it. If a communications failure
+ occurs partway through sending or receiving a message, the only sensible
+ response is to abandon the connection, since there is little hope of
+ recovering message-boundary synchronization.
+ </p></div><div class="sect2" id="PROTOCOL-QUERY-CONCEPTS"><div class="titlepage"><div><div><h3 class="title">55.1.2. Extended Query Overview</h3></div></div></div><p>
+ In the extended-query protocol, execution of SQL commands is divided
+ into multiple steps. The state retained between steps is represented
+ by two types of objects: <em class="firstterm">prepared statements</em> and
+ <em class="firstterm">portals</em>. A prepared statement represents the result of
+ parsing and semantic analysis of a textual query string.
+ A prepared statement is not in itself ready to execute, because it might
+ lack specific values for <em class="firstterm">parameters</em>. A portal represents
+ a ready-to-execute or already-partially-executed statement, with any
+ missing parameter values filled in. (For <code class="command">SELECT</code> statements,
+ a portal is equivalent to an open cursor, but we choose to use a different
+ term since cursors don't handle non-<code class="command">SELECT</code> statements.)
+ </p><p>
+ The overall execution cycle consists of a <em class="firstterm">parse</em> step,
+ which creates a prepared statement from a textual query string; a
+ <em class="firstterm">bind</em> step, which creates a portal given a prepared
+ statement and values for any needed parameters; and an
+ <em class="firstterm">execute</em> step that runs a portal's query. In the case of
+ a query that returns rows (<code class="command">SELECT</code>, <code class="command">SHOW</code>, etc.),
+ the execute step can be told to fetch only
+ a limited number of rows, so that multiple execute steps might be needed
+ to complete the operation.
+ </p><p>
+ The backend can keep track of multiple prepared statements and portals
+ (but note that these exist only within a session, and are never shared
+ across sessions). Existing prepared statements and portals are
+ referenced by names assigned when they were created. In addition,
+ an <span class="quote">“<span class="quote">unnamed</span>”</span> prepared statement and portal exist. Although these
+ behave largely the same as named objects, operations on them are optimized
+ for the case of executing a query only once and then discarding it,
+ whereas operations on named objects are optimized on the expectation
+ of multiple uses.
+ </p></div><div class="sect2" id="PROTOCOL-FORMAT-CODES"><div class="titlepage"><div><div><h3 class="title">55.1.3. Formats and Format Codes</h3></div></div></div><p>
+ Data of a particular data type might be transmitted in any of several
+ different <em class="firstterm">formats</em>. As of <span class="productname">PostgreSQL</span> 7.4
+ the only supported formats are <span class="quote">“<span class="quote">text</span>”</span> and <span class="quote">“<span class="quote">binary</span>”</span>,
+ but the protocol makes provision for future extensions. The desired
+ format for any value is specified by a <em class="firstterm">format code</em>.
+ Clients can specify a format code for each transmitted parameter value
+ and for each column of a query result. Text has format code zero,
+ binary has format code one, and all other format codes are reserved
+ for future definition.
+ </p><p>
+ The text representation of values is whatever strings are produced
+ and accepted by the input/output conversion functions for the
+ particular data type. In the transmitted representation, there is
+ no trailing null character; the frontend must add one to received
+ values if it wants to process them as C strings.
+ (The text format does not allow embedded nulls, by the way.)
+ </p><p>
+ Binary representations for integers use network byte order (most
+ significant byte first). For other data types consult the documentation
+ or source code to learn about the binary representation. Keep in mind
+ that binary representations for complex data types might change across
+ server versions; the text format is usually the more portable choice.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-flow.html" title="55.2. Message Flow">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 55. Frontend/Backend Protocol </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.2. Message Flow</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol-replication.html b/doc/src/sgml/html/protocol-replication.html
new file mode 100644
index 0000000..93174eb
--- /dev/null
+++ b/doc/src/sgml/html/protocol-replication.html
@@ -0,0 +1,529 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.4. Streaming Replication Protocol</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sasl-authentication.html" title="55.3. SASL Authentication" /><link rel="next" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.4. Streaming Replication Protocol</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sasl-authentication.html" title="55.3. SASL Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol">Next</a></td></tr></table><hr /></div><div class="sect1" id="PROTOCOL-REPLICATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.4. Streaming Replication Protocol</h2></div></div></div><p>
+ To initiate streaming replication, the frontend sends the
+ <code class="literal">replication</code> parameter in the startup message. A Boolean
+ value of <code class="literal">true</code> (or <code class="literal">on</code>,
+ <code class="literal">yes</code>, <code class="literal">1</code>) tells the backend to go into
+ physical replication walsender mode, wherein a small set of replication
+ commands, shown below, can be issued instead of SQL statements.
+ </p><p>
+ Passing <code class="literal">database</code> as the value for the
+ <code class="literal">replication</code> parameter instructs the backend to go into
+ logical replication walsender mode, connecting to the database specified in
+ the <code class="literal">dbname</code> parameter. In logical replication walsender
+ mode, the replication commands shown below as well as normal SQL commands can
+ be issued.
+ </p><p>
+ In either physical replication or logical replication walsender mode, only the
+ simple query protocol can be used.
+ </p><p>
+ For the purpose of testing replication commands, you can make a replication
+ connection via <span class="application">psql</span> or any other
+ <span class="application">libpq</span>-using tool with a connection string including
+ the <code class="literal">replication</code> option,
+ e.g.:
+</p><pre class="programlisting">
+psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
+</pre><p>
+ However, it is often more useful to use
+ <a class="xref" href="app-pgreceivewal.html" title="pg_receivewal"><span class="refentrytitle"><span class="application">pg_receivewal</span></span></a> (for physical replication) or
+ <a class="xref" href="app-pgrecvlogical.html" title="pg_recvlogical"><span class="refentrytitle"><span class="application">pg_recvlogical</span></span></a> (for logical replication).
+ </p><p>
+ Replication commands are logged in the server log when
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-REPLICATION-COMMANDS">log_replication_commands</a> is enabled.
+ </p><p>
+ The commands accepted in replication mode are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-REPLICATION-IDENTIFY-SYSTEM"><span class="term"><code class="literal">IDENTIFY_SYSTEM</code>
+ <a id="id-1.10.6.9.7.1.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Requests the server to identify itself. Server replies with a result
+ set of a single row, containing four fields:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">systemid</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The unique system identifier identifying the cluster. This
+ can be used to check that the base backup used to initialize the
+ standby came from the same cluster.
+ </p></dd><dt><span class="term"><code class="literal">timeline</code> (<code class="type">int4</code>)</span></dt><dd><p>
+ Current timeline ID. Also useful to check that the standby is
+ consistent with the primary.
+ </p></dd><dt><span class="term"><code class="literal">xlogpos</code> (<code class="type">text</code>)</span></dt><dd><p>
+ Current WAL flush location. Useful to get a known location in the
+ write-ahead log where streaming can start.
+ </p></dd><dt><span class="term"><code class="literal">dbname</code> (<code class="type">text</code>)</span></dt><dd><p>
+ Database connected to or null.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-SHOW"><span class="term"><code class="literal">SHOW</code> <em class="replaceable"><code>name</code></em>
+ <a id="id-1.10.6.9.7.1.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Requests the server to send the current setting of a run-time parameter.
+ This is similar to the SQL command <a class="xref" href="sql-show.html" title="SHOW"><span class="refentrytitle">SHOW</span></a>.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a run-time parameter. Available parameters are documented
+ in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-TIMELINE-HISTORY"><span class="term"><code class="literal">TIMELINE_HISTORY</code> <em class="replaceable"><code>tli</code></em>
+ <a id="id-1.10.6.9.7.1.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Requests the server to send over the timeline history file for timeline
+ <em class="replaceable"><code>tli</code></em>. Server replies with a
+ result set of a single row, containing two fields. While the fields
+ are labeled as <code class="type">text</code>, they effectively return raw bytes,
+ with no encoding conversion:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">filename</code> (<code class="type">text</code>)</span></dt><dd><p>
+ File name of the timeline history file, e.g., <code class="filename">00000002.history</code>.
+ </p></dd><dt><span class="term"><code class="literal">content</code> (<code class="type">text</code>)</span></dt><dd><p>
+ Contents of the timeline history file.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-CREATE-REPLICATION-SLOT"><span class="term"><code class="literal">CREATE_REPLICATION_SLOT</code> <em class="replaceable"><code>slot_name</code></em> [ <code class="literal">TEMPORARY</code> ] { <code class="literal">PHYSICAL</code> | <code class="literal">LOGICAL</code> <em class="replaceable"><code>output_plugin</code></em> } [ ( <em class="replaceable"><code>option</code></em> [, ...] ) ]
+ <a id="id-1.10.6.9.7.1.4.1.8" class="indexterm"></a>
+ </span></dt><dd><p>
+ Create a physical or logical replication
+ slot. See <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a> for more about
+ replication slots.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>slot_name</code></em></span></dt><dd><p>
+ The name of the slot to create. Must be a valid replication slot
+ name (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS-MANIPULATION" title="27.2.6.1. Querying and Manipulating Replication Slots">Section 27.2.6.1</a>).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_plugin</code></em></span></dt><dd><p>
+ The name of the output plugin used for logical decoding
+ (see <a class="xref" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins">Section 49.6</a>).
+ </p></dd><dt><span class="term"><code class="literal">TEMPORARY</code></span></dt><dd><p>
+ Specify that this replication slot is a temporary one. Temporary
+ slots are not saved to disk and are automatically dropped on error
+ or when the session has finished.
+ </p></dd></dl></div><p>The following options are supported:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TWO_PHASE [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If true, this logical replication slot supports decoding of two-phase
+ commit. With this option, commands related to two-phase commit such as
+ <code class="literal">PREPARE TRANSACTION</code>, <code class="literal">COMMIT PREPARED</code>
+ and <code class="literal">ROLLBACK PREPARED</code> are decoded and transmitted.
+ The transaction will be decoded and transmitted at
+ <code class="literal">PREPARE TRANSACTION</code> time.
+ The default is false.
+ </p></dd><dt><span class="term"><code class="literal">RESERVE_WAL [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If true, this physical replication slot reserves <acronym class="acronym">WAL</acronym>
+ immediately. Otherwise, <acronym class="acronym">WAL</acronym> is only reserved upon
+ connection from a streaming replication client.
+ The default is false.
+ </p></dd><dt><span class="term"><code class="literal">SNAPSHOT { 'export' | 'use' | 'nothing' }</code></span></dt><dd><p>
+ Decides what to do with the snapshot created during logical slot
+ initialization. <code class="literal">'export'</code>, which is the default,
+ will export the snapshot for use in other sessions. This option can't
+ be used inside a transaction. <code class="literal">'use'</code> will use the
+ snapshot for the current transaction executing the command. This
+ option must be used in a transaction, and
+ <code class="literal">CREATE_REPLICATION_SLOT</code> must be the first command
+ run in that transaction. Finally, <code class="literal">'nothing'</code> will
+ just use the snapshot for logical decoding as normal but won't do
+ anything else with it.
+ </p></dd></dl></div><p>
+ In response to this command, the server will send a one-row result set
+ containing the following fields:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">slot_name</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The name of the newly-created replication slot.
+ </p></dd><dt><span class="term"><code class="literal">consistent_point</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The WAL location at which the slot became consistent. This is the
+ earliest location from which streaming can start on this replication
+ slot.
+ </p></dd><dt><span class="term"><code class="literal">snapshot_name</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The identifier of the snapshot exported by the command. The
+ snapshot is valid until a new command is executed on this connection
+ or the replication connection is closed. Null if the created slot
+ is physical.
+ </p></dd><dt><span class="term"><code class="literal">output_plugin</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The name of the output plugin used by the newly-created replication
+ slot. Null if the created slot is physical.
+ </p></dd></dl></div><p>
+ </p></dd><dt id="PROTOCOL-REPLICATION-CREATE-REPLICATION-SLOT-LEGACY"><span class="term"><code class="literal">CREATE_REPLICATION_SLOT</code> <em class="replaceable"><code>slot_name</code></em> [ <code class="literal">TEMPORARY</code> ] { <code class="literal">PHYSICAL</code> [ <code class="literal">RESERVE_WAL</code> ] | <code class="literal">LOGICAL</code> <em class="replaceable"><code>output_plugin</code></em> [ <code class="literal">EXPORT_SNAPSHOT</code> | <code class="literal">NOEXPORT_SNAPSHOT</code> | <code class="literal">USE_SNAPSHOT</code> | <code class="literal">TWO_PHASE</code> ] }
+ </span></dt><dd><p>
+ For compatibility with older releases, this alternative syntax for
+ the <code class="literal">CREATE_REPLICATION_SLOT</code> command is still supported.
+ </p></dd><dt id="PROTOCOL-REPLICATION-READ-REPLICATION-SLOT"><span class="term"><code class="literal">READ_REPLICATION_SLOT</code> <em class="replaceable"><code>slot_name</code></em>
+ <a id="id-1.10.6.9.7.1.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Read some information associated with a replication slot. Returns a tuple
+ with <code class="literal">NULL</code> values if the replication slot does not
+ exist. This command is currently only supported for physical replication
+ slots.
+ </p><p>
+ In response to this command, the server will return a one-row result set,
+ containing the following fields:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">slot_type</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The replication slot's type, either <code class="literal">physical</code> or
+ <code class="literal">NULL</code>.
+ </p></dd><dt><span class="term"><code class="literal">restart_lsn</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The replication slot's <code class="literal">restart_lsn</code>.
+ </p></dd><dt><span class="term"><code class="literal">restart_tli</code> (<code class="type">int8</code>)</span></dt><dd><p>
+ The timeline ID associated with <code class="literal">restart_lsn</code>,
+ following the current timeline history.
+ </p></dd></dl></div><p>
+ </p></dd><dt id="PROTOCOL-REPLICATION-START-REPLICATION"><span class="term"><code class="literal">START_REPLICATION</code> [ <code class="literal">SLOT</code> <em class="replaceable"><code>slot_name</code></em> ] [ <code class="literal">PHYSICAL</code> ] <em class="replaceable"><code>XXX/XXX</code></em> [ <code class="literal">TIMELINE</code> <em class="replaceable"><code>tli</code></em> ]
+ <a id="id-1.10.6.9.7.1.7.1.8" class="indexterm"></a>
+ </span></dt><dd><p>
+ Instructs server to start streaming WAL, starting at
+ WAL location <em class="replaceable"><code>XXX/XXX</code></em>.
+ If <code class="literal">TIMELINE</code> option is specified,
+ streaming starts on timeline <em class="replaceable"><code>tli</code></em>;
+ otherwise, the server's current timeline is selected. The server can
+ reply with an error, for example if the requested section of WAL has already
+ been recycled. On success, the server responds with a CopyBothResponse
+ message, and then starts to stream WAL to the frontend.
+ </p><p>
+ If a slot's name is provided
+ via <em class="replaceable"><code>slot_name</code></em>, it will be updated
+ as replication progresses so that the server knows which WAL segments,
+ and if <code class="varname">hot_standby_feedback</code> is on which transactions,
+ are still needed by the standby.
+ </p><p>
+ If the client requests a timeline that's not the latest but is part of
+ the history of the server, the server will stream all the WAL on that
+ timeline starting from the requested start point up to the point where
+ the server switched to another timeline. If the client requests
+ streaming at exactly the end of an old timeline, the server skips COPY
+ mode entirely.
+ </p><p>
+ After streaming all the WAL on a timeline that is not the latest one,
+ the server will end streaming by exiting the COPY mode. When the client
+ acknowledges this by also exiting COPY mode, the server sends a result
+ set with one row and two columns, indicating the next timeline in this
+ server's history. The first column is the next timeline's ID (type <code class="type">int8</code>), and the
+ second column is the WAL location where the switch happened (type <code class="type">text</code>). Usually,
+ the switch position is the end of the WAL that was streamed, but there
+ are corner cases where the server can send some WAL from the old
+ timeline that it has not itself replayed before promoting. Finally, the
+ server sends two CommandComplete messages (one that ends the CopyData
+ and the other ends the <code class="literal">START_REPLICATION</code> itself), and
+ is ready to accept a new command.
+ </p><p>
+ WAL data is sent as a series of CopyData messages. (This allows
+ other information to be intermixed; in particular the server can send
+ an ErrorResponse message if it encounters a failure after beginning
+ to stream.) The payload of each CopyData message from server to the
+ client contains a message of one of the following formats:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-REPLICATION-XLOGDATA"><span class="term">XLogData (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('w')</span></dt><dd><p>
+ Identifies the message as WAL data.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The starting point of the WAL data in this message.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The current end of WAL on the server.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ A section of the WAL data stream.
+ </p><p>
+ A single WAL record is never split across two XLogData messages.
+ When a WAL record crosses a WAL page boundary, and is therefore
+ already split using continuation records, it can be split at the page
+ boundary. In other words, the first main WAL record and its
+ continuation records can be sent in different XLogData messages.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-PRIMARY-KEEPALIVE-MESSAGE"><span class="term">Primary keepalive message (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('k')</span></dt><dd><p>
+ Identifies the message as a sender keepalive.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The current end of WAL on the server.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </p></dd><dt><span class="term">Byte1</span></dt><dd><p>
+ 1 means that the client should reply to this message as soon as
+ possible, to avoid a timeout disconnect. 0 otherwise.
+ </p></dd></dl></div></dd></dl></div><p>
+ The receiving process can send replies back to the sender at any time,
+ using one of the following message formats (also in the payload of a
+ CopyData message):
+ </p><div class="variablelist"><dl class="variablelist"><dt id="PROTOCOL-REPLICATION-STANDBY-STATUS-UPDATE"><span class="term">Standby status update (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('r')</span></dt><dd><p>
+ Identifies the message as a receiver status update.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The location of the last WAL byte + 1 received and written to disk
+ in the standby.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The location of the last WAL byte + 1 flushed to disk in
+ the standby.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The location of the last WAL byte + 1 applied in the standby.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </p></dd><dt><span class="term">Byte1</span></dt><dd><p>
+ If 1, the client requests the server to reply to this message
+ immediately. This can be used to ping the server, to test if
+ the connection is still healthy.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-HOT-STANDBY-FEEDBACK-MESSAGE"><span class="term">Hot standby feedback message (F)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('h')</span></dt><dd><p>
+ Identifies the message as a hot standby feedback message.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The standby's current global xmin, excluding the catalog_xmin from any
+ replication slots. If both this value and the following
+ catalog_xmin are 0 this is treated as a notification that hot standby
+ feedback will no longer be sent on this connection. Later non-zero
+ messages may reinitiate the feedback mechanism.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The epoch of the global xmin xid on the standby.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The lowest catalog_xmin of any replication slots on the standby. Set to 0
+ if no catalog_xmin exists on the standby or if hot standby feedback is being
+ disabled.
+ </p></dd><dt><span class="term">Int32</span></dt><dd><p>
+ The epoch of the catalog_xmin xid on the standby.
+ </p></dd></dl></div></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-START-REPLICATION-SLOT-LOGICAL"><span class="term"><code class="literal">START_REPLICATION</code> <code class="literal">SLOT</code> <em class="replaceable"><code>slot_name</code></em> <code class="literal">LOGICAL</code> <em class="replaceable"><code>XXX/XXX</code></em> [ ( <em class="replaceable"><code>option_name</code></em> [ <em class="replaceable"><code>option_value</code></em> ] [, ...] ) ]</span></dt><dd><p>
+ Instructs server to start streaming WAL for logical replication,
+ starting at either WAL location <em class="replaceable"><code>XXX/XXX</code></em> or the slot's
+ <code class="literal">confirmed_flush_lsn</code> (see <a class="xref" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots">Section 54.19</a>), whichever is greater. This
+ behavior makes it easier for clients to avoid updating their local LSN
+ status when there is no data to process. However, starting at a
+ different LSN than requested might not catch certain kinds of client
+ errors; so the client may wish to check that
+ <code class="literal">confirmed_flush_lsn</code> matches its expectations before
+ issuing <code class="literal">START_REPLICATION</code>.
+ </p><p>
+ The server can reply with an error, for example if the
+ slot does not exist. On success, the server responds with a CopyBothResponse
+ message, and then starts to stream WAL to the frontend.
+ </p><p>
+ The messages inside the CopyBothResponse messages are of the same format
+ documented for <code class="literal">START_REPLICATION ... PHYSICAL</code>, including
+ two CommandComplete messages.
+ </p><p>
+ The output plugin associated with the selected slot is used
+ to process the output for streaming.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SLOT</code> <em class="replaceable"><code>slot_name</code></em></span></dt><dd><p>
+ The name of the slot to stream changes from. This parameter is required,
+ and must correspond to an existing logical replication slot created
+ with <code class="literal">CREATE_REPLICATION_SLOT</code> in
+ <code class="literal">LOGICAL</code> mode.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>XXX/XXX</code></em></span></dt><dd><p>
+ The WAL location to begin streaming at.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>option_name</code></em></span></dt><dd><p>
+ The name of an option passed to the slot's logical decoding plugin.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>option_value</code></em></span></dt><dd><p>
+ Optional value, in the form of a string constant, associated with the
+ specified option.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-DROP-REPLICATION-SLOT"><span class="term">
+ <code class="literal">DROP_REPLICATION_SLOT</code> <em class="replaceable"><code>slot_name</code></em> [<span class="optional"> <code class="literal">WAIT</code> </span>]
+ <a id="id-1.10.6.9.7.1.9.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Drops a replication slot, freeing any reserved server-side resources.
+ If the slot is a logical slot that was created in a database other than
+ the database the walsender is connected to, this command fails.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>slot_name</code></em></span></dt><dd><p>
+ The name of the slot to drop.
+ </p></dd><dt><span class="term"><code class="literal">WAIT</code></span></dt><dd><p>
+ This option causes the command to wait if the slot is active until
+ it becomes inactive, instead of the default behavior of raising an
+ error.
+ </p></dd></dl></div></dd><dt id="PROTOCOL-REPLICATION-BASE-BACKUP"><span class="term"><code class="literal">BASE_BACKUP</code> [ ( <em class="replaceable"><code>option</code></em> [, ...] ) ]
+ <a id="id-1.10.6.9.7.1.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Instructs the server to start streaming a base backup.
+ The system will automatically be put in backup mode before the backup
+ is started, and taken out of it when the backup is complete. The
+ following options are accepted:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">LABEL</code> <em class="replaceable"><code>'label'</code></em></span></dt><dd><p>
+ Sets the label of the backup. If none is specified, a backup label
+ of <code class="literal">base backup</code> will be used. The quoting rules
+ for the label are the same as a standard SQL string with
+ <a class="xref" href="runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS">standard_conforming_strings</a> turned on.
+ </p></dd><dt><span class="term"><code class="literal">TARGET</code> <em class="replaceable"><code>'target'</code></em></span></dt><dd><p>
+ Tells the server where to send the backup. If the target is
+ <code class="literal">client</code>, which is the default, the backup data is
+ sent to the client. If it is <code class="literal">server</code>, the backup
+ data is written to the server at the pathname specified by the
+ <code class="literal">TARGET_DETAIL</code> option. If it is
+ <code class="literal">blackhole</code>, the backup data is not sent
+ anywhere; it is simply discarded.
+ </p><p>
+ The <code class="literal">server</code> target requires superuser privilege or
+ being granted the <code class="literal">pg_write_server_files</code> role.
+ </p></dd><dt><span class="term"><code class="literal">TARGET_DETAIL</code> <em class="replaceable"><code>'detail'</code></em></span></dt><dd><p>
+ Provides additional information about the backup target.
+ </p><p>
+ Currently, this option can only be used when the backup target is
+ <code class="literal">server</code>. It specifies the server directory
+ to which the backup should be written.
+ </p></dd><dt><span class="term"><code class="literal">PROGRESS [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If set to true, request information required to generate a progress
+ report. This will send back an approximate size in the header of each
+ tablespace, which can be used to calculate how far along the stream
+ is done. This is calculated by enumerating all the file sizes once
+ before the transfer is even started, and might as such have a
+ negative impact on the performance. In particular, it might take
+ longer before the first data
+ is streamed. Since the database files can change during the backup,
+ the size is only approximate and might both grow and shrink between
+ the time of approximation and the sending of the actual files.
+ The default is false.
+ </p></dd><dt><span class="term"><code class="literal">CHECKPOINT { 'fast' | 'spread' }</code></span></dt><dd><p>
+ Sets the type of checkpoint to be performed at the beginning of the
+ base backup. The default is <code class="literal">spread</code>.
+ </p></dd><dt><span class="term"><code class="literal">WAL [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If set to true, include the necessary WAL segments in the backup.
+ This will include all the files between start and stop backup in the
+ <code class="filename">pg_wal</code> directory of the base directory tar
+ file. The default is false.
+ </p></dd><dt><span class="term"><code class="literal">WAIT [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If set to true, the backup will wait until the last required WAL
+ segment has been archived, or emit a warning if log archiving is
+ not enabled. If false, the backup will neither wait nor warn,
+ leaving the client responsible for ensuring the required log is
+ available. The default is true.
+ </p></dd><dt><span class="term"><code class="literal">COMPRESSION</code> <em class="replaceable"><code>'method'</code></em></span></dt><dd><p>
+ Instructs the server to compress the backup using the specified
+ method. Currently, the supported methods are <code class="literal">gzip</code>,
+ <code class="literal">lz4</code>, and <code class="literal">zstd</code>.
+ </p></dd><dt><span class="term"><code class="literal">COMPRESSION_DETAIL</code> <em class="replaceable"><code>detail</code></em></span></dt><dd><p>
+ Specifies details for the chosen compression method. This should only
+ be used in conjunction with the <code class="literal">COMPRESSION</code>
+ option. If the value is an integer, it specifies the compression
+ level. Otherwise, it should be a comma-separated list of items,
+ each of the form <em class="replaceable"><code>keyword</code></em> or
+ <em class="replaceable"><code>keyword=value</code></em>. Currently, the supported
+ keywords are <code class="literal">level</code> and <code class="literal">workers</code>.
+ </p><p>
+ The <code class="literal">level</code> keyword sets the compression level.
+ For <code class="literal">gzip</code> the compression level should be an
+ integer between <code class="literal">1</code> and <code class="literal">9</code>
+ (default <code class="literal">Z_DEFAULT_COMPRESSION</code> or
+ <code class="literal">-1</code>), for <code class="literal">lz4</code> an integer
+ between 1 and 12 (default <code class="literal">0</code> for fast compression
+ mode), and for <code class="literal">zstd</code> an integer between
+ <code class="literal">ZSTD_minCLevel()</code> (usually <code class="literal">-131072</code>)
+ and <code class="literal">ZSTD_maxCLevel()</code> (usually <code class="literal">22</code>),
+ (default <code class="literal">ZSTD_CLEVEL_DEFAULT</code> or
+ <code class="literal">3</code>).
+ </p><p>
+ The <code class="literal">workers</code> keyword sets the number of threads
+ that should be used for parallel compression. Parallel compression
+ is supported only for <code class="literal">zstd</code>.
+ </p></dd><dt><span class="term"><code class="literal">MAX_RATE</code> <em class="replaceable"><code>rate</code></em></span></dt><dd><p>
+ Limit (throttle) the maximum amount of data transferred from server
+ to client per unit of time. The expected unit is kilobytes per second.
+ If this option is specified, the value must either be equal to zero
+ or it must fall within the range from 32 kB through 1 GB (inclusive).
+ If zero is passed or the option is not specified, no restriction is
+ imposed on the transfer.
+ </p></dd><dt><span class="term"><code class="literal">TABLESPACE_MAP [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If true, include information about symbolic links present in the
+ directory <code class="filename">pg_tblspc</code> in a file named
+ <code class="filename">tablespace_map</code>. The tablespace map file includes
+ each symbolic link name as it exists in the directory
+ <code class="filename">pg_tblspc/</code> and the full path of that symbolic link.
+ The default is false.
+ </p></dd><dt><span class="term"><code class="literal">VERIFY_CHECKSUMS [ <em class="replaceable"><code>boolean</code></em> ]</code></span></dt><dd><p>
+ If true, checksums are verified during a base backup if they are
+ enabled. If false, this is skipped. The default is true.
+ </p></dd><dt><span class="term"><code class="literal">MANIFEST</code> <em class="replaceable"><code>manifest_option</code></em></span></dt><dd><p>
+ When this option is specified with a value of <code class="literal">yes</code>
+ or <code class="literal">force-encode</code>, a backup manifest is created
+ and sent along with the backup. The manifest is a list of every
+ file present in the backup with the exception of any WAL files that
+ may be included. It also stores the size, last modification time, and
+ optionally a checksum for each file.
+ A value of <code class="literal">force-encode</code> forces all filenames
+ to be hex-encoded; otherwise, this type of encoding is performed only
+ for files whose names are non-UTF8 octet sequences.
+ <code class="literal">force-encode</code> is intended primarily for testing
+ purposes, to be sure that clients which read the backup manifest
+ can handle this case. For compatibility with previous releases,
+ the default is <code class="literal">MANIFEST 'no'</code>.
+ </p></dd><dt><span class="term"><code class="literal">MANIFEST_CHECKSUMS</code> <em class="replaceable"><code>checksum_algorithm</code></em></span></dt><dd><p>
+ Specifies the checksum algorithm that should be applied to each file included
+ in the backup manifest. Currently, the available
+ algorithms are <code class="literal">NONE</code>, <code class="literal">CRC32C</code>,
+ <code class="literal">SHA224</code>, <code class="literal">SHA256</code>,
+ <code class="literal">SHA384</code>, and <code class="literal">SHA512</code>.
+ The default is <code class="literal">CRC32C</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ When the backup is started, the server will first send two
+ ordinary result sets, followed by one or more CopyOutResponse
+ results.
+ </p><p>
+ The first ordinary result set contains the starting position of the
+ backup, in a single row with two columns. The first column contains
+ the start position given in XLogRecPtr format, and the second column
+ contains the corresponding timeline ID.
+ </p><p>
+ The second ordinary result set has one row for each tablespace.
+ The fields in this row are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">spcoid</code> (<code class="type">oid</code>)</span></dt><dd><p>
+ The OID of the tablespace, or null if it's the base
+ directory.
+ </p></dd><dt><span class="term"><code class="literal">spclocation</code> (<code class="type">text</code>)</span></dt><dd><p>
+ The full path of the tablespace directory, or null
+ if it's the base directory.
+ </p></dd><dt><span class="term"><code class="literal">size</code> (<code class="type">int8</code>)</span></dt><dd><p>
+ The approximate size of the tablespace, in kilobytes (1024 bytes),
+ if progress report has been requested; otherwise it's null.
+ </p></dd></dl></div><p>
+ </p><p>
+ After the second regular result set, a CopyOutResponse will be sent.
+ The payload of each CopyData message will contain a message in one of
+ the following formats:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">new archive (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('n')</span></dt><dd><p>
+ Identifies the message as indicating the start of a new archive.
+ There will be one archive for the main data directory and one
+ for each additional tablespace; each will use tar format
+ (following the <span class="quote">“<span class="quote">ustar interchange format</span>”</span> specified
+ in the POSIX 1003.1-2008 standard).
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ The file name for this archive.
+ </p></dd><dt><span class="term">String</span></dt><dd><p>
+ For the main data directory, an empty string. For other
+ tablespaces, the full path to the directory from which this
+ archive was created.
+ </p></dd></dl></div></dd><dt><span class="term">manifest (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('m')</span></dt><dd><p>
+ Identifies the message as indicating the start of the backup
+ manifest.
+ </p></dd></dl></div></dd><dt><span class="term">archive or manifest data (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('d')</span></dt><dd><p>
+ Identifies the message as containing archive or manifest data.
+ </p></dd><dt><span class="term">Byte<em class="replaceable"><code>n</code></em></span></dt><dd><p>
+ Data bytes.
+ </p></dd></dl></div></dd><dt><span class="term">progress report (B)</span></dt><dd><div class="variablelist"><dl class="variablelist"><dt><span class="term">Byte1('p')</span></dt><dd><p>
+ Identifies the message as a progress report.
+ </p></dd><dt><span class="term">Int64</span></dt><dd><p>
+ The number of bytes from the current tablespace for which
+ processing has been completed.
+ </p></dd></dl></div></dd></dl></div><p>
+ After the CopyOutResponse, or all such responses, have been sent, a
+ final ordinary result set will be sent, containing the WAL end position
+ of the backup, in the same format as the start position.
+ </p><p>
+ The tar archive for the data directory and each tablespace will contain
+ all files in the directories, regardless of whether they are
+ <span class="productname">PostgreSQL</span> files or other files added to the same
+ directory. The only excluded files are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <code class="filename">postmaster.pid</code>
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="filename">postmaster.opts</code>
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="filename">pg_internal.init</code> (found in multiple directories)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Various temporary files and directories created during the operation
+ of the PostgreSQL server, such as any file or directory beginning
+ with <code class="filename">pgsql_tmp</code> and temporary relations.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Unlogged relations, except for the init fork which is required to
+ recreate the (empty) unlogged relation on recovery.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="filename">pg_wal</code>, including subdirectories. If the backup is run
+ with WAL files included, a synthesized version of <code class="filename">pg_wal</code> will be
+ included, but it will only contain the files necessary for the
+ backup to work, not the rest of the contents.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="filename">pg_dynshmem</code>, <code class="filename">pg_notify</code>,
+ <code class="filename">pg_replslot</code>, <code class="filename">pg_serial</code>,
+ <code class="filename">pg_snapshots</code>, <code class="filename">pg_stat_tmp</code>, and
+ <code class="filename">pg_subtrans</code> are copied as empty directories (even if
+ they are symbolic links).
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Files other than regular files and directories, such as symbolic
+ links (other than for the directories listed above) and special
+ device files, are skipped. (Symbolic links
+ in <code class="filename">pg_tblspc</code> are maintained.)
+ </p></li></ul></div><p>
+ Owner, group, and file mode are set if the underlying file system on
+ the server supports it.
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sasl-authentication.html" title="55.3. SASL Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-logical-replication.html" title="55.5. Logical Streaming Replication Protocol">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.3. SASL Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.5. Logical Streaming Replication Protocol</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/protocol.html b/doc/src/sgml/html/protocol.html
new file mode 100644
index 0000000..d7f94ed
--- /dev/null
+++ b/doc/src/sgml/html/protocol.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 55. Frontend/Backend Protocol</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-views.html" title="54.35. pg_views" /><link rel="next" href="protocol-overview.html" title="55.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 55. Frontend/Backend Protocol</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-views.html" title="54.35. pg_views">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-overview.html" title="55.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="PROTOCOL"><div class="titlepage"><div><div><h2 class="title">Chapter 55. Frontend/Backend Protocol</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="protocol-overview.html">55.1. Overview</a></span></dt><dd><dl><dt><span class="sect2"><a href="protocol-overview.html#PROTOCOL-MESSAGE-CONCEPTS">55.1.1. Messaging Overview</a></span></dt><dt><span class="sect2"><a href="protocol-overview.html#PROTOCOL-QUERY-CONCEPTS">55.1.2. Extended Query Overview</a></span></dt><dt><span class="sect2"><a href="protocol-overview.html#PROTOCOL-FORMAT-CODES">55.1.3. Formats and Format Codes</a></span></dt></dl></dd><dt><span class="sect1"><a href="protocol-flow.html">55.2. Message Flow</a></span></dt><dd><dl><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.3">55.2.1. Start-up</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.4">55.2.2. Simple Query</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY">55.2.3. Extended Query</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-FLOW-PIPELINING">55.2.4. Pipelining</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.7">55.2.5. Function Call</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-COPY">55.2.6. COPY Operations</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#PROTOCOL-ASYNC">55.2.7. Asynchronous Operations</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.10">55.2.8. Canceling Requests in Progress</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.11">55.2.9. Termination</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.12">55.2.10. <acronym class="acronym">SSL</acronym> Session Encryption</a></span></dt><dt><span class="sect2"><a href="protocol-flow.html#id-1.10.6.7.13">55.2.11. <acronym class="acronym">GSSAPI</acronym> Session Encryption</a></span></dt></dl></dd><dt><span class="sect1"><a href="sasl-authentication.html">55.3. SASL Authentication</a></span></dt><dd><dl><dt><span class="sect2"><a href="sasl-authentication.html#SASL-SCRAM-SHA-256">55.3.1. SCRAM-SHA-256 Authentication</a></span></dt></dl></dd><dt><span class="sect1"><a href="protocol-replication.html">55.4. Streaming Replication Protocol</a></span></dt><dt><span class="sect1"><a href="protocol-logical-replication.html">55.5. Logical Streaming Replication Protocol</a></span></dt><dd><dl><dt><span class="sect2"><a href="protocol-logical-replication.html#PROTOCOL-LOGICAL-REPLICATION-PARAMS">55.5.1. Logical Streaming Replication Parameters</a></span></dt><dt><span class="sect2"><a href="protocol-logical-replication.html#PROTOCOL-LOGICAL-MESSAGES">55.5.2. Logical Replication Protocol Messages</a></span></dt><dt><span class="sect2"><a href="protocol-logical-replication.html#PROTOCOL-LOGICAL-MESSAGES-FLOW">55.5.3. Logical Replication Protocol Message Flow</a></span></dt></dl></dd><dt><span class="sect1"><a href="protocol-message-types.html">55.6. Message Data Types</a></span></dt><dt><span class="sect1"><a href="protocol-message-formats.html">55.7. Message Formats</a></span></dt><dt><span class="sect1"><a href="protocol-error-fields.html">55.8. Error and Notice Message Fields</a></span></dt><dt><span class="sect1"><a href="protocol-logicalrep-message-formats.html">55.9. Logical Replication Message Formats</a></span></dt><dt><span class="sect1"><a href="protocol-changes.html">55.10. Summary of Changes since Protocol 2.0</a></span></dt></dl></div><a id="id-1.10.6.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> uses a message-based protocol
+ for communication between frontends and backends (clients and servers).
+ The protocol is supported over <acronym class="acronym">TCP/IP</acronym> and also over
+ Unix-domain sockets. Port number 5432 has been registered with IANA as
+ the customary TCP port number for servers supporting this protocol, but
+ in practice any non-privileged port number can be used.
+ </p><p>
+ This document describes version 3.0 of the protocol, implemented in
+ <span class="productname">PostgreSQL</span> 7.4 and later. For descriptions
+ of the earlier protocol versions, see previous releases of the
+ <span class="productname">PostgreSQL</span> documentation. A single server
+ can support multiple protocol versions. The initial startup-request
+ message tells the server which protocol version the client is attempting to
+ use. If the major version requested by the client is not supported by
+ the server, the connection will be rejected (for example, this would occur
+ if the client requested protocol version 4.0, which does not exist as of
+ this writing). If the minor version requested by the client is not
+ supported by the server (e.g., the client requests version 3.1, but the
+ server supports only 3.0), the server may either reject the connection or
+ may respond with a NegotiateProtocolVersion message containing the highest
+ minor protocol version which it supports. The client may then choose either
+ to continue with the connection using the specified protocol version or
+ to abort the connection.
+ </p><p>
+ In order to serve multiple clients efficiently, the server launches
+ a new <span class="quote">“<span class="quote">backend</span>”</span> process for each client.
+ In the current implementation, a new child
+ process is created immediately after an incoming connection is detected.
+ This is transparent to the protocol, however. For purposes of the
+ protocol, the terms <span class="quote">“<span class="quote">backend</span>”</span> and <span class="quote">“<span class="quote">server</span>”</span> are
+ interchangeable; likewise <span class="quote">“<span class="quote">frontend</span>”</span> and <span class="quote">“<span class="quote">client</span>”</span>
+ are interchangeable.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-views.html" title="54.35. pg_views">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-overview.html" title="55.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.35. <code class="structname">pg_views</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-limit.html b/doc/src/sgml/html/queries-limit.html
new file mode 100644
index 0000000..4236145
--- /dev/null
+++ b/doc/src/sgml/html/queries-limit.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.6. LIMIT and OFFSET</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)" /><link rel="next" href="queries-values.html" title="7.7. VALUES Lists" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.6. <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-values.html" title="7.7. VALUES Lists">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-LIMIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.6. <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code></h2></div></div></div><a id="id-1.5.6.10.2" class="indexterm"></a><a id="id-1.5.6.10.3" class="indexterm"></a><p>
+ <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code> allow you to retrieve just
+ a portion of the rows that are generated by the rest of the query:
+</p><pre class="synopsis">
+SELECT <em class="replaceable"><code>select_list</code></em>
+ FROM <em class="replaceable"><code>table_expression</code></em>
+ [<span class="optional"> ORDER BY ... </span>]
+ [<span class="optional"> LIMIT { <em class="replaceable"><code>number</code></em> | ALL } </span>] [<span class="optional"> OFFSET <em class="replaceable"><code>number</code></em> </span>]
+</pre><p>
+ </p><p>
+ If a limit count is given, no more than that many rows will be
+ returned (but possibly fewer, if the query itself yields fewer rows).
+ <code class="literal">LIMIT ALL</code> is the same as omitting the <code class="literal">LIMIT</code>
+ clause, as is <code class="literal">LIMIT</code> with a NULL argument.
+ </p><p>
+ <code class="literal">OFFSET</code> says to skip that many rows before beginning to
+ return rows. <code class="literal">OFFSET 0</code> is the same as omitting the
+ <code class="literal">OFFSET</code> clause, as is <code class="literal">OFFSET</code> with a NULL argument.
+ </p><p>
+ If both <code class="literal">OFFSET</code>
+ and <code class="literal">LIMIT</code> appear, then <code class="literal">OFFSET</code> rows are
+ skipped before starting to count the <code class="literal">LIMIT</code> rows that
+ are returned.
+ </p><p>
+ When using <code class="literal">LIMIT</code>, it is important to use an
+ <code class="literal">ORDER BY</code> clause that constrains the result rows into a
+ unique order. Otherwise you will get an unpredictable subset of
+ the query's rows. You might be asking for the tenth through
+ twentieth rows, but tenth through twentieth in what ordering? The
+ ordering is unknown, unless you specified <code class="literal">ORDER BY</code>.
+ </p><p>
+ The query optimizer takes <code class="literal">LIMIT</code> into account when
+ generating query plans, so you are very likely to get different
+ plans (yielding different row orders) depending on what you give
+ for <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code>. Thus, using
+ different <code class="literal">LIMIT</code>/<code class="literal">OFFSET</code> values to select
+ different subsets of a query result <span class="emphasis"><em>will give
+ inconsistent results</em></span> unless you enforce a predictable
+ result ordering with <code class="literal">ORDER BY</code>. This is not a bug; it
+ is an inherent consequence of the fact that SQL does not promise to
+ deliver the results of a query in any particular order unless
+ <code class="literal">ORDER BY</code> is used to constrain the order.
+ </p><p>
+ The rows skipped by an <code class="literal">OFFSET</code> clause still have to be
+ computed inside the server; therefore a large <code class="literal">OFFSET</code>
+ might be inefficient.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-values.html" title="7.7. VALUES Lists">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.5. Sorting Rows (<code class="literal">ORDER BY</code>) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.7. <code class="literal">VALUES</code> Lists</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-order.html b/doc/src/sgml/html/queries-order.html
new file mode 100644
index 0000000..7775b81
--- /dev/null
+++ b/doc/src/sgml/html/queries-order.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.5. Sorting Rows (ORDER BY)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-union.html" title="7.4. Combining Queries (UNION, INTERSECT, EXCEPT)" /><link rel="next" href="queries-limit.html" title="7.6. LIMIT and OFFSET" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.5. Sorting Rows (<code class="literal">ORDER BY</code>)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-union.html" title="7.4. Combining Queries (UNION, INTERSECT, EXCEPT)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-limit.html" title="7.6. LIMIT and OFFSET">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-ORDER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.5. Sorting Rows (<code class="literal">ORDER BY</code>)</h2></div></div></div><a id="id-1.5.6.9.2" class="indexterm"></a><a id="id-1.5.6.9.3" class="indexterm"></a><p>
+ After a query has produced an output table (after the select list
+ has been processed) it can optionally be sorted. If sorting is not
+ chosen, the rows will be returned in an unspecified order. The actual
+ order in that case will depend on the scan and join plan types and
+ the order on disk, but it must not be relied on. A particular
+ output ordering can only be guaranteed if the sort step is explicitly
+ chosen.
+ </p><p>
+ The <code class="literal">ORDER BY</code> clause specifies the sort order:
+</p><pre class="synopsis">
+SELECT <em class="replaceable"><code>select_list</code></em>
+ FROM <em class="replaceable"><code>table_expression</code></em>
+ ORDER BY <em class="replaceable"><code>sort_expression1</code></em> [<span class="optional">ASC | DESC</span>] [<span class="optional">NULLS { FIRST | LAST }</span>]
+ [<span class="optional">, <em class="replaceable"><code>sort_expression2</code></em> [<span class="optional">ASC | DESC</span>] [<span class="optional">NULLS { FIRST | LAST }</span>] ...</span>]
+</pre><p>
+ The sort expression(s) can be any expression that would be valid in the
+ query's select list. An example is:
+</p><pre class="programlisting">
+SELECT a, b FROM table1 ORDER BY a + b, c;
+</pre><p>
+ When more than one expression is specified,
+ the later values are used to sort rows that are equal according to the
+ earlier values. Each expression can be followed by an optional
+ <code class="literal">ASC</code> or <code class="literal">DESC</code> keyword to set the sort direction to
+ ascending or descending. <code class="literal">ASC</code> order is the default.
+ Ascending order puts smaller values first, where
+ <span class="quote">“<span class="quote">smaller</span>”</span> is defined in terms of the
+ <code class="literal">&lt;</code> operator. Similarly, descending order is
+ determined with the <code class="literal">&gt;</code> operator.
+ <a href="#ftn.id-1.5.6.9.5.10" class="footnote"><sup class="footnote" id="id-1.5.6.9.5.10">[6]</sup></a>
+ </p><p>
+ The <code class="literal">NULLS FIRST</code> and <code class="literal">NULLS LAST</code> options can be
+ used to determine whether nulls appear before or after non-null values
+ in the sort ordering. By default, null values sort as if larger than any
+ non-null value; that is, <code class="literal">NULLS FIRST</code> is the default for
+ <code class="literal">DESC</code> order, and <code class="literal">NULLS LAST</code> otherwise.
+ </p><p>
+ Note that the ordering options are considered independently for each
+ sort column. For example <code class="literal">ORDER BY x, y DESC</code> means
+ <code class="literal">ORDER BY x ASC, y DESC</code>, which is not the same as
+ <code class="literal">ORDER BY x DESC, y DESC</code>.
+ </p><p>
+ A <em class="replaceable"><code>sort_expression</code></em> can also be the column label or number
+ of an output column, as in:
+</p><pre class="programlisting">
+SELECT a + b AS sum, c FROM table1 ORDER BY sum;
+SELECT a, max(b) FROM table1 GROUP BY a ORDER BY 1;
+</pre><p>
+ both of which sort by the first output column. Note that an output
+ column name has to stand alone, that is, it cannot be used in an expression
+ — for example, this is <span class="emphasis"><em>not</em></span> correct:
+</p><pre class="programlisting">
+SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong
+</pre><p>
+ This restriction is made to reduce ambiguity. There is still
+ ambiguity if an <code class="literal">ORDER BY</code> item is a simple name that
+ could match either an output column name or a column from the table
+ expression. The output column is used in such cases. This would
+ only cause confusion if you use <code class="literal">AS</code> to rename an output
+ column to match some other table column's name.
+ </p><p>
+ <code class="literal">ORDER BY</code> can be applied to the result of a
+ <code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, or <code class="literal">EXCEPT</code>
+ combination, but in this case it is only permitted to sort by
+ output column names or numbers, not by expressions.
+ </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.5.6.9.5.10" class="footnote"><p><a href="#id-1.5.6.9.5.10" class="para"><sup class="para">[6] </sup></a>
+ Actually, <span class="productname">PostgreSQL</span> uses the <em class="firstterm">default B-tree
+ operator class</em> for the expression's data type to determine the sort
+ ordering for <code class="literal">ASC</code> and <code class="literal">DESC</code>. Conventionally,
+ data types will be set up so that the <code class="literal">&lt;</code> and
+ <code class="literal">&gt;</code> operators correspond to this sort ordering,
+ but a user-defined data type's designer could choose to do something
+ different.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-union.html" title="7.4. Combining Queries (UNION, INTERSECT, EXCEPT)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-limit.html" title="7.6. LIMIT and OFFSET">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.4. Combining Queries (<code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.6. <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-overview.html b/doc/src/sgml/html/queries-overview.html
new file mode 100644
index 0000000..6020652
--- /dev/null
+++ b/doc/src/sgml/html/queries-overview.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries.html" title="Chapter 7. Queries" /><link rel="next" href="queries-table-expressions.html" title="7.2. Table Expressions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries.html" title="Chapter 7. Queries">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-table-expressions.html" title="7.2. Table Expressions">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.1. Overview</h2></div></div></div><p>
+ The process of retrieving or the command to retrieve data from a
+ database is called a <em class="firstterm">query</em>. In SQL the
+ <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a> command is
+ used to specify queries. The general syntax of the
+ <code class="command">SELECT</code> command is
+</p><pre class="synopsis">
+[<span class="optional">WITH <em class="replaceable"><code>with_queries</code></em></span>] SELECT <em class="replaceable"><code>select_list</code></em> FROM <em class="replaceable"><code>table_expression</code></em> [<span class="optional"><em class="replaceable"><code>sort_specification</code></em></span>]
+</pre><p>
+ The following sections describe the details of the select list, the
+ table expression, and the sort specification. <code class="literal">WITH</code>
+ queries are treated last since they are an advanced feature.
+ </p><p>
+ A simple kind of query has the form:
+</p><pre class="programlisting">
+SELECT * FROM table1;
+</pre><p>
+ Assuming that there is a table called <code class="literal">table1</code>,
+ this command would retrieve all rows and all user-defined columns from
+ <code class="literal">table1</code>. (The method of retrieval depends on the
+ client application. For example, the
+ <span class="application">psql</span> program will display an ASCII-art
+ table on the screen, while client libraries will offer functions to
+ extract individual values from the query result.) The select list
+ specification <code class="literal">*</code> means all columns that the table
+ expression happens to provide. A select list can also select a
+ subset of the available columns or make calculations using the
+ columns. For example, if
+ <code class="literal">table1</code> has columns named <code class="literal">a</code>,
+ <code class="literal">b</code>, and <code class="literal">c</code> (and perhaps others) you can make
+ the following query:
+</p><pre class="programlisting">
+SELECT a, b + c FROM table1;
+</pre><p>
+ (assuming that <code class="literal">b</code> and <code class="literal">c</code> are of a numerical
+ data type).
+ See <a class="xref" href="queries-select-lists.html" title="7.3. Select Lists">Section 7.3</a> for more details.
+ </p><p>
+ <code class="literal">FROM table1</code> is a simple kind of
+ table expression: it reads just one table. In general, table
+ expressions can be complex constructs of base tables, joins, and
+ subqueries. But you can also omit the table expression entirely and
+ use the <code class="command">SELECT</code> command as a calculator:
+</p><pre class="programlisting">
+SELECT 3 * 4;
+</pre><p>
+ This is more useful if the expressions in the select list return
+ varying results. For example, you could call a function this way:
+</p><pre class="programlisting">
+SELECT random();
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries.html" title="Chapter 7. Queries">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-table-expressions.html" title="7.2. Table Expressions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 7. Queries </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.2. Table Expressions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-select-lists.html b/doc/src/sgml/html/queries-select-lists.html
new file mode 100644
index 0000000..1d3b545
--- /dev/null
+++ b/doc/src/sgml/html/queries-select-lists.html
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.3. Select Lists</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-table-expressions.html" title="7.2. Table Expressions" /><link rel="next" href="queries-union.html" title="7.4. Combining Queries (UNION, INTERSECT, EXCEPT)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.3. Select Lists</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-table-expressions.html" title="7.2. Table Expressions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-union.html" title="7.4. Combining Queries (UNION, INTERSECT, EXCEPT)">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-SELECT-LISTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.3. Select Lists</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="queries-select-lists.html#QUERIES-SELECT-LIST-ITEMS">7.3.1. Select-List Items</a></span></dt><dt><span class="sect2"><a href="queries-select-lists.html#QUERIES-COLUMN-LABELS">7.3.2. Column Labels</a></span></dt><dt><span class="sect2"><a href="queries-select-lists.html#QUERIES-DISTINCT">7.3.3. <code class="literal">DISTINCT</code></a></span></dt></dl></div><a id="id-1.5.6.7.2" class="indexterm"></a><p>
+ As shown in the previous section,
+ the table expression in the <code class="command">SELECT</code> command
+ constructs an intermediate virtual table by possibly combining
+ tables, views, eliminating rows, grouping, etc. This table is
+ finally passed on to processing by the <em class="firstterm">select list</em>. The select
+ list determines which <span class="emphasis"><em>columns</em></span> of the
+ intermediate table are actually output.
+ </p><div class="sect2" id="QUERIES-SELECT-LIST-ITEMS"><div class="titlepage"><div><div><h3 class="title">7.3.1. Select-List Items</h3></div></div></div><a id="id-1.5.6.7.4.2" class="indexterm"></a><p>
+ The simplest kind of select list is <code class="literal">*</code> which
+ emits all columns that the table expression produces. Otherwise,
+ a select list is a comma-separated list of value expressions (as
+ defined in <a class="xref" href="sql-expressions.html" title="4.2. Value Expressions">Section 4.2</a>). For instance, it
+ could be a list of column names:
+</p><pre class="programlisting">
+SELECT a, b, c FROM ...
+</pre><p>
+ The columns names <code class="literal">a</code>, <code class="literal">b</code>, and <code class="literal">c</code>
+ are either the actual names of the columns of tables referenced
+ in the <code class="literal">FROM</code> clause, or the aliases given to them as
+ explained in <a class="xref" href="queries-table-expressions.html#QUERIES-TABLE-ALIASES" title="7.2.1.2. Table and Column Aliases">Section 7.2.1.2</a>. The name
+ space available in the select list is the same as in the
+ <code class="literal">WHERE</code> clause, unless grouping is used, in which case
+ it is the same as in the <code class="literal">HAVING</code> clause.
+ </p><p>
+ If more than one table has a column of the same name, the table
+ name must also be given, as in:
+</p><pre class="programlisting">
+SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
+</pre><p>
+ When working with multiple tables, it can also be useful to ask for
+ all the columns of a particular table:
+</p><pre class="programlisting">
+SELECT tbl1.*, tbl2.a FROM ...
+</pre><p>
+ See <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a> for more about
+ the <em class="replaceable"><code>table_name</code></em><code class="literal">.*</code> notation.
+ </p><p>
+ If an arbitrary value expression is used in the select list, it
+ conceptually adds a new virtual column to the returned table. The
+ value expression is evaluated once for each result row, with
+ the row's values substituted for any column references. But the
+ expressions in the select list do not have to reference any
+ columns in the table expression of the <code class="literal">FROM</code> clause;
+ they can be constant arithmetic expressions, for instance.
+ </p></div><div class="sect2" id="QUERIES-COLUMN-LABELS"><div class="titlepage"><div><div><h3 class="title">7.3.2. Column Labels</h3></div></div></div><a id="id-1.5.6.7.5.2" class="indexterm"></a><p>
+ The entries in the select list can be assigned names for subsequent
+ processing, such as for use in an <code class="literal">ORDER BY</code> clause
+ or for display by the client application. For example:
+</p><pre class="programlisting">
+SELECT a AS value, b + c AS sum FROM ...
+</pre><p>
+ </p><p>
+ If no output column name is specified using <code class="literal">AS</code>,
+ the system assigns a default column name. For simple column references,
+ this is the name of the referenced column. For function
+ calls, this is the name of the function. For complex expressions,
+ the system will generate a generic name.
+ </p><p>
+ The <code class="literal">AS</code> key word is usually optional, but in some
+ cases where the desired column name matches a
+ <span class="productname">PostgreSQL</span> key word, you must write
+ <code class="literal">AS</code> or double-quote the column name in order to
+ avoid ambiguity.
+ (<a class="xref" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Appendix C</a> shows which key words
+ require <code class="literal">AS</code> to be used as a column label.)
+ For example, <code class="literal">FROM</code> is one such key word, so this
+ does not work:
+</p><pre class="programlisting">
+SELECT a from, b + c AS sum FROM ...
+</pre><p>
+ but either of these do:
+</p><pre class="programlisting">
+SELECT a AS from, b + c AS sum FROM ...
+SELECT a "from", b + c AS sum FROM ...
+</pre><p>
+ For greatest safety against possible
+ future key word additions, it is recommended that you always either
+ write <code class="literal">AS</code> or double-quote the output column name.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The naming of output columns here is different from that done in
+ the <code class="literal">FROM</code> clause (see <a class="xref" href="queries-table-expressions.html#QUERIES-TABLE-ALIASES" title="7.2.1.2. Table and Column Aliases">Section 7.2.1.2</a>). It is possible
+ to rename the same column twice, but the name assigned in
+ the select list is the one that will be passed on.
+ </p></div></div><div class="sect2" id="QUERIES-DISTINCT"><div class="titlepage"><div><div><h3 class="title">7.3.3. <code class="literal">DISTINCT</code></h3></div></div></div><a id="id-1.5.6.7.6.2" class="indexterm"></a><a id="id-1.5.6.7.6.3" class="indexterm"></a><a id="id-1.5.6.7.6.4" class="indexterm"></a><p>
+ After the select list has been processed, the result table can
+ optionally be subject to the elimination of duplicate rows. The
+ <code class="literal">DISTINCT</code> key word is written directly after
+ <code class="literal">SELECT</code> to specify this:
+</p><pre class="synopsis">
+SELECT DISTINCT <em class="replaceable"><code>select_list</code></em> ...
+</pre><p>
+ (Instead of <code class="literal">DISTINCT</code> the key word <code class="literal">ALL</code>
+ can be used to specify the default behavior of retaining all rows.)
+ </p><a id="id-1.5.6.7.6.6" class="indexterm"></a><p>
+ Obviously, two rows are considered distinct if they differ in at
+ least one column value. Null values are considered equal in this
+ comparison.
+ </p><p>
+ Alternatively, an arbitrary expression can determine what rows are
+ to be considered distinct:
+</p><pre class="synopsis">
+SELECT DISTINCT ON (<em class="replaceable"><code>expression</code></em> [<span class="optional">, <em class="replaceable"><code>expression</code></em> ...</span>]) <em class="replaceable"><code>select_list</code></em> ...
+</pre><p>
+ Here <em class="replaceable"><code>expression</code></em> is an arbitrary value
+ expression that is evaluated for all rows. A set of rows for
+ which all the expressions are equal are considered duplicates, and
+ only the first row of the set is kept in the output. Note that
+ the <span class="quote">“<span class="quote">first row</span>”</span> of a set is unpredictable unless the
+ query is sorted on enough columns to guarantee a unique ordering
+ of the rows arriving at the <code class="literal">DISTINCT</code> filter.
+ (<code class="literal">DISTINCT ON</code> processing occurs after <code class="literal">ORDER
+ BY</code> sorting.)
+ </p><p>
+ The <code class="literal">DISTINCT ON</code> clause is not part of the SQL standard
+ and is sometimes considered bad style because of the potentially
+ indeterminate nature of its results. With judicious use of
+ <code class="literal">GROUP BY</code> and subqueries in <code class="literal">FROM</code>, this
+ construct can be avoided, but it is often the most convenient
+ alternative.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-table-expressions.html" title="7.2. Table Expressions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-union.html" title="7.4. Combining Queries (UNION, INTERSECT, EXCEPT)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.2. Table Expressions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.4. Combining Queries (<code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-table-expressions.html b/doc/src/sgml/html/queries-table-expressions.html
new file mode 100644
index 0000000..3eca961
--- /dev/null
+++ b/doc/src/sgml/html/queries-table-expressions.html
@@ -0,0 +1,1030 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.2. Table Expressions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-overview.html" title="7.1. Overview" /><link rel="next" href="queries-select-lists.html" title="7.3. Select Lists" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.2. Table Expressions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-overview.html" title="7.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-select-lists.html" title="7.3. Select Lists">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-TABLE-EXPRESSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.2. Table Expressions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-FROM">7.2.1. The <code class="literal">FROM</code> Clause</a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-WHERE">7.2.2. The <code class="literal">WHERE</code> Clause</a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-GROUP">7.2.3. The <code class="literal">GROUP BY</code> and <code class="literal">HAVING</code> Clauses</a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-GROUPING-SETS">7.2.4. <code class="literal">GROUPING SETS</code>, <code class="literal">CUBE</code>, and <code class="literal">ROLLUP</code></a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-WINDOW">7.2.5. Window Function Processing</a></span></dt></dl></div><a id="id-1.5.6.6.2" class="indexterm"></a><p>
+ A <em class="firstterm">table expression</em> computes a table. The
+ table expression contains a <code class="literal">FROM</code> clause that is
+ optionally followed by <code class="literal">WHERE</code>, <code class="literal">GROUP BY</code>, and
+ <code class="literal">HAVING</code> clauses. Trivial table expressions simply refer
+ to a table on disk, a so-called base table, but more complex
+ expressions can be used to modify or combine base tables in various
+ ways.
+ </p><p>
+ The optional <code class="literal">WHERE</code>, <code class="literal">GROUP BY</code>, and
+ <code class="literal">HAVING</code> clauses in the table expression specify a
+ pipeline of successive transformations performed on the table
+ derived in the <code class="literal">FROM</code> clause. All these transformations
+ produce a virtual table that provides the rows that are passed to
+ the select list to compute the output rows of the query.
+ </p><div class="sect2" id="QUERIES-FROM"><div class="titlepage"><div><div><h3 class="title">7.2.1. The <code class="literal">FROM</code> Clause</h3></div></div></div><p>
+ The <a class="link" href="sql-select.html#SQL-FROM" title="FROM Clause"><code class="literal">FROM</code></a> clause derives a
+ table from one or more other tables given in a comma-separated
+ table reference list.
+</p><pre class="synopsis">
+FROM <em class="replaceable"><code>table_reference</code></em> [<span class="optional">, <em class="replaceable"><code>table_reference</code></em> [<span class="optional">, ...</span>]</span>]
+</pre><p>
+
+ A table reference can be a table name (possibly schema-qualified),
+ or a derived table such as a subquery, a <code class="literal">JOIN</code> construct, or
+ complex combinations of these. If more than one table reference is
+ listed in the <code class="literal">FROM</code> clause, the tables are cross-joined
+ (that is, the Cartesian product of their rows is formed; see below).
+ The result of the <code class="literal">FROM</code> list is an intermediate virtual
+ table that can then be subject to
+ transformations by the <code class="literal">WHERE</code>, <code class="literal">GROUP BY</code>,
+ and <code class="literal">HAVING</code> clauses and is finally the result of the
+ overall table expression.
+ </p><a id="id-1.5.6.6.5.3" class="indexterm"></a><p>
+ When a table reference names a table that is the parent of a
+ table inheritance hierarchy, the table reference produces rows of
+ not only that table but all of its descendant tables, unless the
+ key word <code class="literal">ONLY</code> precedes the table name. However, the
+ reference produces only the columns that appear in the named table
+ — any columns added in subtables are ignored.
+ </p><p>
+ Instead of writing <code class="literal">ONLY</code> before the table name, you can write
+ <code class="literal">*</code> after the table name to explicitly specify that descendant
+ tables are included. There is no real reason to use this syntax any more,
+ because searching descendant tables is now always the default behavior.
+ However, it is supported for compatibility with older releases.
+ </p><div class="sect3" id="QUERIES-JOIN"><div class="titlepage"><div><div><h4 class="title">7.2.1.1. Joined Tables</h4></div></div></div><a id="id-1.5.6.6.5.6.2" class="indexterm"></a><p>
+ A joined table is a table derived from two other (real or
+ derived) tables according to the rules of the particular join
+ type. Inner, outer, and cross-joins are available.
+ The general syntax of a joined table is
+</p><pre class="synopsis">
+<em class="replaceable"><code>T1</code></em> <em class="replaceable"><code>join_type</code></em> <em class="replaceable"><code>T2</code></em> [<span class="optional"> <em class="replaceable"><code>join_condition</code></em> </span>]
+</pre><p>
+ Joins of all types can be chained together, or nested: either or
+ both <em class="replaceable"><code>T1</code></em> and
+ <em class="replaceable"><code>T2</code></em> can be joined tables. Parentheses
+ can be used around <code class="literal">JOIN</code> clauses to control the join
+ order. In the absence of parentheses, <code class="literal">JOIN</code> clauses
+ nest left-to-right.
+ </p><div class="variablelist"><p class="title"><strong>Join Types</strong></p><dl class="variablelist"><dt><span class="term">Cross join
+ <a id="id-1.5.6.6.5.6.4.2.1.1" class="indexterm"></a>
+
+ <a id="id-1.5.6.6.5.6.4.2.1.2" class="indexterm"></a>
+ </span></dt><dd><pre class="synopsis">
+<em class="replaceable"><code>T1</code></em> CROSS JOIN <em class="replaceable"><code>T2</code></em>
+</pre><p>
+ For every possible combination of rows from
+ <em class="replaceable"><code>T1</code></em> and
+ <em class="replaceable"><code>T2</code></em> (i.e., a Cartesian product),
+ the joined table will contain a
+ row consisting of all columns in <em class="replaceable"><code>T1</code></em>
+ followed by all columns in <em class="replaceable"><code>T2</code></em>. If
+ the tables have N and M rows respectively, the joined
+ table will have N * M rows.
+ </p><p>
+ <code class="literal">FROM <em class="replaceable"><code>T1</code></em> CROSS JOIN
+ <em class="replaceable"><code>T2</code></em></code> is equivalent to
+ <code class="literal">FROM <em class="replaceable"><code>T1</code></em> INNER JOIN
+ <em class="replaceable"><code>T2</code></em> ON TRUE</code> (see below).
+ It is also equivalent to
+ <code class="literal">FROM <em class="replaceable"><code>T1</code></em>,
+ <em class="replaceable"><code>T2</code></em></code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This latter equivalence does not hold exactly when more than two
+ tables appear, because <code class="literal">JOIN</code> binds more tightly than
+ comma. For example
+ <code class="literal">FROM <em class="replaceable"><code>T1</code></em> CROSS JOIN
+ <em class="replaceable"><code>T2</code></em> INNER JOIN <em class="replaceable"><code>T3</code></em>
+ ON <em class="replaceable"><code>condition</code></em></code>
+ is not the same as
+ <code class="literal">FROM <em class="replaceable"><code>T1</code></em>,
+ <em class="replaceable"><code>T2</code></em> INNER JOIN <em class="replaceable"><code>T3</code></em>
+ ON <em class="replaceable"><code>condition</code></em></code>
+ because the <em class="replaceable"><code>condition</code></em> can
+ reference <em class="replaceable"><code>T1</code></em> in the first case but not
+ the second.
+ </p></div><p>
+ </p></dd><dt><span class="term">Qualified joins
+ <a id="id-1.5.6.6.5.6.4.3.1.1" class="indexterm"></a>
+
+ <a id="id-1.5.6.6.5.6.4.3.1.2" class="indexterm"></a>
+ </span></dt><dd><pre class="synopsis">
+<em class="replaceable"><code>T1</code></em> { [<span class="optional">INNER</span>] | { LEFT | RIGHT | FULL } [<span class="optional">OUTER</span>] } JOIN <em class="replaceable"><code>T2</code></em> ON <em class="replaceable"><code>boolean_expression</code></em>
+<em class="replaceable"><code>T1</code></em> { [<span class="optional">INNER</span>] | { LEFT | RIGHT | FULL } [<span class="optional">OUTER</span>] } JOIN <em class="replaceable"><code>T2</code></em> USING ( <em class="replaceable"><code>join column list</code></em> )
+<em class="replaceable"><code>T1</code></em> NATURAL { [<span class="optional">INNER</span>] | { LEFT | RIGHT | FULL } [<span class="optional">OUTER</span>] } JOIN <em class="replaceable"><code>T2</code></em>
+</pre><p>
+ The words <code class="literal">INNER</code> and
+ <code class="literal">OUTER</code> are optional in all forms.
+ <code class="literal">INNER</code> is the default;
+ <code class="literal">LEFT</code>, <code class="literal">RIGHT</code>, and
+ <code class="literal">FULL</code> imply an outer join.
+ </p><p>
+ The <em class="firstterm">join condition</em> is specified in the
+ <code class="literal">ON</code> or <code class="literal">USING</code> clause, or implicitly by
+ the word <code class="literal">NATURAL</code>. The join condition determines
+ which rows from the two source tables are considered to
+ <span class="quote">“<span class="quote">match</span>”</span>, as explained in detail below.
+ </p><p>
+ The possible types of qualified join are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">INNER JOIN</code></span></dt><dd><p>
+ For each row R1 of T1, the joined table has a row for each
+ row in T2 that satisfies the join condition with R1.
+ </p></dd><dt><span class="term"><code class="literal">LEFT OUTER JOIN</code>
+ <a id="id-1.5.6.6.5.6.4.3.2.4.1.2.1.2" class="indexterm"></a>
+
+ <a id="id-1.5.6.6.5.6.4.3.2.4.1.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ First, an inner join is performed. Then, for each row in
+ T1 that does not satisfy the join condition with any row in
+ T2, a joined row is added with null values in columns of
+ T2. Thus, the joined table always has at least
+ one row for each row in T1.
+ </p></dd><dt><span class="term"><code class="literal">RIGHT OUTER JOIN</code>
+ <a id="id-1.5.6.6.5.6.4.3.2.4.1.3.1.2" class="indexterm"></a>
+
+ <a id="id-1.5.6.6.5.6.4.3.2.4.1.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ First, an inner join is performed. Then, for each row in
+ T2 that does not satisfy the join condition with any row in
+ T1, a joined row is added with null values in columns of
+ T1. This is the converse of a left join: the result table
+ will always have a row for each row in T2.
+ </p></dd><dt><span class="term"><code class="literal">FULL OUTER JOIN</code></span></dt><dd><p>
+ First, an inner join is performed. Then, for each row in
+ T1 that does not satisfy the join condition with any row in
+ T2, a joined row is added with null values in columns of
+ T2. Also, for each row of T2 that does not satisfy the
+ join condition with any row in T1, a joined row with null
+ values in the columns of T1 is added.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <code class="literal">ON</code> clause is the most general kind of join
+ condition: it takes a Boolean value expression of the same
+ kind as is used in a <code class="literal">WHERE</code> clause. A pair of rows
+ from <em class="replaceable"><code>T1</code></em> and <em class="replaceable"><code>T2</code></em> match if the
+ <code class="literal">ON</code> expression evaluates to true.
+ </p><p>
+ The <code class="literal">USING</code> clause is a shorthand that allows you to take
+ advantage of the specific situation where both sides of the join use
+ the same name for the joining column(s). It takes a
+ comma-separated list of the shared column names
+ and forms a join condition that includes an equality comparison
+ for each one. For example, joining <em class="replaceable"><code>T1</code></em>
+ and <em class="replaceable"><code>T2</code></em> with <code class="literal">USING (a, b)</code> produces
+ the join condition <code class="literal">ON <em class="replaceable"><code>T1</code></em>.a
+ = <em class="replaceable"><code>T2</code></em>.a AND <em class="replaceable"><code>T1</code></em>.b
+ = <em class="replaceable"><code>T2</code></em>.b</code>.
+ </p><p>
+ Furthermore, the output of <code class="literal">JOIN USING</code> suppresses
+ redundant columns: there is no need to print both of the matched
+ columns, since they must have equal values. While <code class="literal">JOIN
+ ON</code> produces all columns from <em class="replaceable"><code>T1</code></em> followed by all
+ columns from <em class="replaceable"><code>T2</code></em>, <code class="literal">JOIN USING</code> produces one
+ output column for each of the listed column pairs (in the listed
+ order), followed by any remaining columns from <em class="replaceable"><code>T1</code></em>,
+ followed by any remaining columns from <em class="replaceable"><code>T2</code></em>.
+ </p><p>
+ <a id="id-1.5.6.6.5.6.4.3.2.8.1" class="indexterm"></a>
+ <a id="id-1.5.6.6.5.6.4.3.2.8.2" class="indexterm"></a>
+ Finally, <code class="literal">NATURAL</code> is a shorthand form of
+ <code class="literal">USING</code>: it forms a <code class="literal">USING</code> list
+ consisting of all column names that appear in both
+ input tables. As with <code class="literal">USING</code>, these columns appear
+ only once in the output table. If there are no common
+ column names, <code class="literal">NATURAL JOIN</code> behaves like
+ <code class="literal">JOIN ... ON TRUE</code>, producing a cross-product join.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">USING</code> is reasonably safe from column changes
+ in the joined relations since only the listed columns
+ are combined. <code class="literal">NATURAL</code> is considerably more risky since
+ any schema changes to either relation that cause a new matching
+ column name to be present will cause the join to combine that new
+ column as well.
+ </p></div></dd></dl></div><p>
+ To put this together, assume we have tables <code class="literal">t1</code>:
+</p><pre class="programlisting">
+ num | name
+-----+------
+ 1 | a
+ 2 | b
+ 3 | c
+</pre><p>
+ and <code class="literal">t2</code>:
+</p><pre class="programlisting">
+ num | value
+-----+-------
+ 1 | xxx
+ 3 | yyy
+ 5 | zzz
+</pre><p>
+ then we get the following results for the various joins:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 CROSS JOIN t2;</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 1 | a | 3 | yyy
+ 1 | a | 5 | zzz
+ 2 | b | 1 | xxx
+ 2 | b | 3 | yyy
+ 2 | b | 5 | zzz
+ 3 | c | 1 | xxx
+ 3 | c | 3 | yyy
+ 3 | c | 5 | zzz
+(9 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 3 | c | 3 | yyy
+(2 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 INNER JOIN t2 USING (num);</code></strong>
+ num | name | value
+-----+------+-------
+ 1 | a | xxx
+ 3 | c | yyy
+(2 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 NATURAL INNER JOIN t2;</code></strong>
+ num | name | value
+-----+------+-------
+ 1 | a | xxx
+ 3 | c | yyy
+(2 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 2 | b | |
+ 3 | c | 3 | yyy
+(3 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 LEFT JOIN t2 USING (num);</code></strong>
+ num | name | value
+-----+------+-------
+ 1 | a | xxx
+ 2 | b |
+ 3 | c | yyy
+(3 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 3 | c | 3 | yyy
+ | | 5 | zzz
+(3 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 2 | b | |
+ 3 | c | 3 | yyy
+ | | 5 | zzz
+(4 rows)
+</pre><p>
+ </p><p>
+ The join condition specified with <code class="literal">ON</code> can also contain
+ conditions that do not relate directly to the join. This can
+ prove useful for some queries but needs to be thought out
+ carefully. For example:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 2 | b | |
+ 3 | c | |
+(3 rows)
+</pre><p>
+ Notice that placing the restriction in the <code class="literal">WHERE</code> clause
+ produces a different result:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';</code></strong>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+(1 row)
+</pre><p>
+ This is because a restriction placed in the <code class="literal">ON</code>
+ clause is processed <span class="emphasis"><em>before</em></span> the join, while
+ a restriction placed in the <code class="literal">WHERE</code> clause is processed
+ <span class="emphasis"><em>after</em></span> the join.
+ That does not matter with inner joins, but it matters a lot with outer
+ joins.
+ </p></div><div class="sect3" id="QUERIES-TABLE-ALIASES"><div class="titlepage"><div><div><h4 class="title">7.2.1.2. Table and Column Aliases</h4></div></div></div><a id="id-1.5.6.6.5.7.2" class="indexterm"></a><a id="id-1.5.6.6.5.7.3" class="indexterm"></a><p>
+ A temporary name can be given to tables and complex table
+ references to be used for references to the derived table in
+ the rest of the query. This is called a <em class="firstterm">table
+ alias</em>.
+ </p><p>
+ To create a table alias, write
+</p><pre class="synopsis">
+FROM <em class="replaceable"><code>table_reference</code></em> AS <em class="replaceable"><code>alias</code></em>
+</pre><p>
+ or
+</p><pre class="synopsis">
+FROM <em class="replaceable"><code>table_reference</code></em> <em class="replaceable"><code>alias</code></em>
+</pre><p>
+ The <code class="literal">AS</code> key word is optional noise.
+ <em class="replaceable"><code>alias</code></em> can be any identifier.
+ </p><p>
+ A typical application of table aliases is to assign short
+ identifiers to long table names to keep the join clauses
+ readable. For example:
+</p><pre class="programlisting">
+SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.id = a.num;
+</pre><p>
+ </p><p>
+ The alias becomes the new name of the table reference so far as the
+ current query is concerned — it is not allowed to refer to the
+ table by the original name elsewhere in the query. Thus, this is not
+ valid:
+</p><pre class="programlisting">
+SELECT * FROM my_table AS m WHERE my_table.a &gt; 5; -- wrong
+</pre><p>
+ </p><p>
+ Table aliases are mainly for notational convenience, but it is
+ necessary to use them when joining a table to itself, e.g.:
+</p><pre class="programlisting">
+SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id;
+</pre><p>
+ Additionally, an alias is required if the table reference is a
+ subquery (see <a class="xref" href="queries-table-expressions.html#QUERIES-SUBQUERIES" title="7.2.1.3. Subqueries">Section 7.2.1.3</a>).
+ </p><p>
+ Parentheses are used to resolve ambiguities. In the following example,
+ the first statement assigns the alias <code class="literal">b</code> to the second
+ instance of <code class="literal">my_table</code>, but the second statement assigns the
+ alias to the result of the join:
+</p><pre class="programlisting">
+SELECT * FROM my_table AS a CROSS JOIN my_table AS b ...
+SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b ...
+</pre><p>
+ </p><p>
+ Another form of table aliasing gives temporary names to the columns of
+ the table, as well as the table itself:
+</p><pre class="synopsis">
+FROM <em class="replaceable"><code>table_reference</code></em> [<span class="optional">AS</span>] <em class="replaceable"><code>alias</code></em> ( <em class="replaceable"><code>column1</code></em> [<span class="optional">, <em class="replaceable"><code>column2</code></em> [<span class="optional">, ...</span>]</span>] )
+</pre><p>
+ If fewer column aliases are specified than the actual table has
+ columns, the remaining columns are not renamed. This syntax is
+ especially useful for self-joins or subqueries.
+ </p><p>
+ When an alias is applied to the output of a <code class="literal">JOIN</code>
+ clause, the alias hides the original
+ name(s) within the <code class="literal">JOIN</code>. For example:
+</p><pre class="programlisting">
+SELECT a.* FROM my_table AS a JOIN your_table AS b ON ...
+</pre><p>
+ is valid SQL, but:
+</p><pre class="programlisting">
+SELECT a.* FROM (my_table AS a JOIN your_table AS b ON ...) AS c
+</pre><p>
+ is not valid; the table alias <code class="literal">a</code> is not visible
+ outside the alias <code class="literal">c</code>.
+ </p></div><div class="sect3" id="QUERIES-SUBQUERIES"><div class="titlepage"><div><div><h4 class="title">7.2.1.3. Subqueries</h4></div></div></div><a id="id-1.5.6.6.5.8.2" class="indexterm"></a><p>
+ Subqueries specifying a derived table must be enclosed in
+ parentheses and <span class="emphasis"><em>must</em></span> be assigned a table
+ alias name (as in <a class="xref" href="queries-table-expressions.html#QUERIES-TABLE-ALIASES" title="7.2.1.2. Table and Column Aliases">Section 7.2.1.2</a>). For
+ example:
+</p><pre class="programlisting">
+FROM (SELECT * FROM table1) AS alias_name
+</pre><p>
+ </p><p>
+ This example is equivalent to <code class="literal">FROM table1 AS
+ alias_name</code>. More interesting cases, which cannot be
+ reduced to a plain join, arise when the subquery involves
+ grouping or aggregation.
+ </p><p>
+ A subquery can also be a <code class="command">VALUES</code> list:
+</p><pre class="programlisting">
+FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow'))
+ AS names(first, last)
+</pre><p>
+ Again, a table alias is required. Assigning alias names to the columns
+ of the <code class="command">VALUES</code> list is optional, but is good practice.
+ For more information see <a class="xref" href="queries-values.html" title="7.7. VALUES Lists">Section 7.7</a>.
+ </p></div><div class="sect3" id="QUERIES-TABLEFUNCTIONS"><div class="titlepage"><div><div><h4 class="title">7.2.1.4. Table Functions</h4></div></div></div><a id="id-1.5.6.6.5.9.2" class="indexterm"></a><a id="id-1.5.6.6.5.9.3" class="indexterm"></a><p>
+ Table functions are functions that produce a set of rows, made up
+ of either base data types (scalar types) or composite data types
+ (table rows). They are used like a table, view, or subquery in
+ the <code class="literal">FROM</code> clause of a query. Columns returned by table
+ functions can be included in <code class="literal">SELECT</code>,
+ <code class="literal">JOIN</code>, or <code class="literal">WHERE</code> clauses in the same manner
+ as columns of a table, view, or subquery.
+ </p><p>
+ Table functions may also be combined using the <code class="literal">ROWS FROM</code>
+ syntax, with the results returned in parallel columns; the number of
+ result rows in this case is that of the largest function result, with
+ smaller results padded with null values to match.
+ </p><pre class="synopsis">
+<em class="replaceable"><code>function_call</code></em> [<span class="optional">WITH ORDINALITY</span>] [<span class="optional">[<span class="optional">AS</span>] <em class="replaceable"><code>table_alias</code></em> [<span class="optional">(<em class="replaceable"><code>column_alias</code></em> [<span class="optional">, ... </span>])</span>]</span>]
+ROWS FROM( <em class="replaceable"><code>function_call</code></em> [<span class="optional">, ... </span>] ) [<span class="optional">WITH ORDINALITY</span>] [<span class="optional">[<span class="optional">AS</span>] <em class="replaceable"><code>table_alias</code></em> [<span class="optional">(<em class="replaceable"><code>column_alias</code></em> [<span class="optional">, ... </span>])</span>]</span>]
+</pre><p>
+ If the <code class="literal">WITH ORDINALITY</code> clause is specified, an
+ additional column of type <code class="type">bigint</code> will be added to the
+ function result columns. This column numbers the rows of the function
+ result set, starting from 1. (This is a generalization of the
+ SQL-standard syntax for <code class="literal">UNNEST ... WITH ORDINALITY</code>.)
+ By default, the ordinal column is called <code class="literal">ordinality</code>, but
+ a different column name can be assigned to it using
+ an <code class="literal">AS</code> clause.
+ </p><p>
+ The special table function <code class="literal">UNNEST</code> may be called with
+ any number of array parameters, and it returns a corresponding number of
+ columns, as if <code class="literal">UNNEST</code>
+ (<a class="xref" href="functions-array.html" title="9.19. Array Functions and Operators">Section 9.19</a>) had been called on each parameter
+ separately and combined using the <code class="literal">ROWS FROM</code> construct.
+ </p><pre class="synopsis">
+UNNEST( <em class="replaceable"><code>array_expression</code></em> [<span class="optional">, ... </span>] ) [<span class="optional">WITH ORDINALITY</span>] [<span class="optional">[<span class="optional">AS</span>] <em class="replaceable"><code>table_alias</code></em> [<span class="optional">(<em class="replaceable"><code>column_alias</code></em> [<span class="optional">, ... </span>])</span>]</span>]
+</pre><p>
+ If no <em class="replaceable"><code>table_alias</code></em> is specified, the function
+ name is used as the table name; in the case of a <code class="literal">ROWS FROM()</code>
+ construct, the first function's name is used.
+ </p><p>
+ If column aliases are not supplied, then for a function returning a base
+ data type, the column name is also the same as the function name. For a
+ function returning a composite type, the result columns get the names
+ of the individual attributes of the type.
+ </p><p>
+ Some examples:
+</p><pre class="programlisting">
+CREATE TABLE foo (fooid int, foosubid int, fooname text);
+
+CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
+ SELECT * FROM foo WHERE fooid = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM getfoo(1) AS t1;
+
+SELECT * FROM foo
+ WHERE foosubid IN (
+ SELECT foosubid
+ FROM getfoo(foo.fooid) z
+ WHERE z.fooid = foo.fooid
+ );
+
+CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
+
+SELECT * FROM vw_getfoo;
+</pre><p>
+ </p><p>
+ In some cases it is useful to define table functions that can
+ return different column sets depending on how they are invoked.
+ To support this, the table function can be declared as returning
+ the pseudo-type <code class="type">record</code> with no <code class="literal">OUT</code>
+ parameters. When such a function is used in
+ a query, the expected row structure must be specified in the
+ query itself, so that the system can know how to parse and plan
+ the query. This syntax looks like:
+ </p><pre class="synopsis">
+<em class="replaceable"><code>function_call</code></em> [<span class="optional">AS</span>] <em class="replaceable"><code>alias</code></em> (<em class="replaceable"><code>column_definition</code></em> [<span class="optional">, ... </span>])
+<em class="replaceable"><code>function_call</code></em> AS [<span class="optional"><em class="replaceable"><code>alias</code></em></span>] (<em class="replaceable"><code>column_definition</code></em> [<span class="optional">, ... </span>])
+ROWS FROM( ... <em class="replaceable"><code>function_call</code></em> AS (<em class="replaceable"><code>column_definition</code></em> [<span class="optional">, ... </span>]) [<span class="optional">, ... </span>] )
+</pre><p>
+ When not using the <code class="literal">ROWS FROM()</code> syntax,
+ the <em class="replaceable"><code>column_definition</code></em> list replaces the column
+ alias list that could otherwise be attached to the <code class="literal">FROM</code>
+ item; the names in the column definitions serve as column aliases.
+ When using the <code class="literal">ROWS FROM()</code> syntax,
+ a <em class="replaceable"><code>column_definition</code></em> list can be attached to
+ each member function separately; or if there is only one member function
+ and no <code class="literal">WITH ORDINALITY</code> clause,
+ a <em class="replaceable"><code>column_definition</code></em> list can be written in
+ place of a column alias list following <code class="literal">ROWS FROM()</code>.
+ </p><p>
+ Consider this example:
+</p><pre class="programlisting">
+SELECT *
+ FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc')
+ AS t1(proname name, prosrc text)
+ WHERE proname LIKE 'bytea%';
+</pre><p>
+ The <a class="xref" href="contrib-dblink-function.html" title="dblink"><span class="refentrytitle">dblink</span></a> function
+ (part of the <a class="xref" href="dblink.html" title="F.12. dblink">dblink</a> module) executes
+ a remote query. It is declared to return
+ <code class="type">record</code> since it might be used for any kind of query.
+ The actual column set must be specified in the calling query so
+ that the parser knows, for example, what <code class="literal">*</code> should
+ expand to.
+ </p><p>
+ This example uses <code class="literal">ROWS FROM</code>:
+</p><pre class="programlisting">
+SELECT *
+FROM ROWS FROM
+ (
+ json_to_recordset('[{"a":40,"b":"foo"},{"a":"100","b":"bar"}]')
+ AS (a INTEGER, b TEXT),
+ generate_series(1, 3)
+ ) AS x (p, q, s)
+ORDER BY p;
+
+ p | q | s
+-----+-----+---
+ 40 | foo | 1
+ 100 | bar | 2
+ | | 3
+</pre><p>
+ It joins two functions into a single <code class="literal">FROM</code>
+ target. <code class="function">json_to_recordset()</code> is instructed
+ to return two columns, the first <code class="type">integer</code>
+ and the second <code class="type">text</code>. The result of
+ <code class="function">generate_series()</code> is used directly.
+ The <code class="literal">ORDER BY</code> clause sorts the column values
+ as integers.
+ </p></div><div class="sect3" id="QUERIES-LATERAL"><div class="titlepage"><div><div><h4 class="title">7.2.1.5. <code class="literal">LATERAL</code> Subqueries</h4></div></div></div><a id="id-1.5.6.6.5.10.2" class="indexterm"></a><p>
+ Subqueries appearing in <code class="literal">FROM</code> can be
+ preceded by the key word <code class="literal">LATERAL</code>. This allows them to
+ reference columns provided by preceding <code class="literal">FROM</code> items.
+ (Without <code class="literal">LATERAL</code>, each subquery is
+ evaluated independently and so cannot cross-reference any other
+ <code class="literal">FROM</code> item.)
+ </p><p>
+ Table functions appearing in <code class="literal">FROM</code> can also be
+ preceded by the key word <code class="literal">LATERAL</code>, but for functions the
+ key word is optional; the function's arguments can contain references
+ to columns provided by preceding <code class="literal">FROM</code> items in any case.
+ </p><p>
+ A <code class="literal">LATERAL</code> item can appear at the top level in the
+ <code class="literal">FROM</code> list, or within a <code class="literal">JOIN</code> tree. In the latter
+ case it can also refer to any items that are on the left-hand side of a
+ <code class="literal">JOIN</code> that it is on the right-hand side of.
+ </p><p>
+ When a <code class="literal">FROM</code> item contains <code class="literal">LATERAL</code>
+ cross-references, evaluation proceeds as follows: for each row of the
+ <code class="literal">FROM</code> item providing the cross-referenced column(s), or
+ set of rows of multiple <code class="literal">FROM</code> items providing the
+ columns, the <code class="literal">LATERAL</code> item is evaluated using that
+ row or row set's values of the columns. The resulting row(s) are
+ joined as usual with the rows they were computed from. This is
+ repeated for each row or set of rows from the column source table(s).
+ </p><p>
+ A trivial example of <code class="literal">LATERAL</code> is
+</p><pre class="programlisting">
+SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;
+</pre><p>
+ This is not especially useful since it has exactly the same result as
+ the more conventional
+</p><pre class="programlisting">
+SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;
+</pre><p>
+ <code class="literal">LATERAL</code> is primarily useful when the cross-referenced
+ column is necessary for computing the row(s) to be joined. A common
+ application is providing an argument value for a set-returning function.
+ For example, supposing that <code class="function">vertices(polygon)</code> returns the
+ set of vertices of a polygon, we could identify close-together vertices
+ of polygons stored in a table with:
+</p><pre class="programlisting">
+SELECT p1.id, p2.id, v1, v2
+FROM polygons p1, polygons p2,
+ LATERAL vertices(p1.poly) v1,
+ LATERAL vertices(p2.poly) v2
+WHERE (v1 &lt;-&gt; v2) &lt; 10 AND p1.id != p2.id;
+</pre><p>
+ This query could also be written
+</p><pre class="programlisting">
+SELECT p1.id, p2.id, v1, v2
+FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,
+ polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2
+WHERE (v1 &lt;-&gt; v2) &lt; 10 AND p1.id != p2.id;
+</pre><p>
+ or in several other equivalent formulations. (As already mentioned,
+ the <code class="literal">LATERAL</code> key word is unnecessary in this example, but
+ we use it for clarity.)
+ </p><p>
+ It is often particularly handy to <code class="literal">LEFT JOIN</code> to a
+ <code class="literal">LATERAL</code> subquery, so that source rows will appear in
+ the result even if the <code class="literal">LATERAL</code> subquery produces no
+ rows for them. For example, if <code class="function">get_product_names()</code> returns
+ the names of products made by a manufacturer, but some manufacturers in
+ our table currently produce no products, we could find out which ones
+ those are like this:
+</p><pre class="programlisting">
+SELECT m.name
+FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true
+WHERE pname IS NULL;
+</pre><p>
+ </p></div></div><div class="sect2" id="QUERIES-WHERE"><div class="titlepage"><div><div><h3 class="title">7.2.2. The <code class="literal">WHERE</code> Clause</h3></div></div></div><a id="id-1.5.6.6.6.2" class="indexterm"></a><p>
+ The syntax of the <a class="link" href="sql-select.html#SQL-WHERE" title="WHERE Clause"><code class="literal">WHERE</code></a>
+ clause is
+</p><pre class="synopsis">
+WHERE <em class="replaceable"><code>search_condition</code></em>
+</pre><p>
+ where <em class="replaceable"><code>search_condition</code></em> is any value
+ expression (see <a class="xref" href="sql-expressions.html" title="4.2. Value Expressions">Section 4.2</a>) that
+ returns a value of type <code class="type">boolean</code>.
+ </p><p>
+ After the processing of the <code class="literal">FROM</code> clause is done, each
+ row of the derived virtual table is checked against the search
+ condition. If the result of the condition is true, the row is
+ kept in the output table, otherwise (i.e., if the result is
+ false or null) it is discarded. The search condition typically
+ references at least one column of the table generated in the
+ <code class="literal">FROM</code> clause; this is not required, but otherwise the
+ <code class="literal">WHERE</code> clause will be fairly useless.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The join condition of an inner join can be written either in
+ the <code class="literal">WHERE</code> clause or in the <code class="literal">JOIN</code> clause.
+ For example, these table expressions are equivalent:
+</p><pre class="programlisting">
+FROM a, b WHERE a.id = b.id AND b.val &gt; 5
+</pre><p>
+ and:
+</p><pre class="programlisting">
+FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val &gt; 5
+</pre><p>
+ or perhaps even:
+</p><pre class="programlisting">
+FROM a NATURAL JOIN b WHERE b.val &gt; 5
+</pre><p>
+ Which one of these you use is mainly a matter of style. The
+ <code class="literal">JOIN</code> syntax in the <code class="literal">FROM</code> clause is
+ probably not as portable to other SQL database management systems,
+ even though it is in the SQL standard. For
+ outer joins there is no choice: they must be done in
+ the <code class="literal">FROM</code> clause. The <code class="literal">ON</code> or <code class="literal">USING</code>
+ clause of an outer join is <span class="emphasis"><em>not</em></span> equivalent to a
+ <code class="literal">WHERE</code> condition, because it results in the addition
+ of rows (for unmatched input rows) as well as the removal of rows
+ in the final result.
+ </p></div><p>
+ Here are some examples of <code class="literal">WHERE</code> clauses:
+</p><pre class="programlisting">
+SELECT ... FROM fdt WHERE c1 &gt; 5
+
+SELECT ... FROM fdt WHERE c1 IN (1, 2, 3)
+
+SELECT ... FROM fdt WHERE c1 IN (SELECT c1 FROM t2)
+
+SELECT ... FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)
+
+SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100
+
+SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 &gt; fdt.c1)
+</pre><p>
+ <code class="literal">fdt</code> is the table derived in the
+ <code class="literal">FROM</code> clause. Rows that do not meet the search
+ condition of the <code class="literal">WHERE</code> clause are eliminated from
+ <code class="literal">fdt</code>. Notice the use of scalar subqueries as
+ value expressions. Just like any other query, the subqueries can
+ employ complex table expressions. Notice also how
+ <code class="literal">fdt</code> is referenced in the subqueries.
+ Qualifying <code class="literal">c1</code> as <code class="literal">fdt.c1</code> is only necessary
+ if <code class="literal">c1</code> is also the name of a column in the derived
+ input table of the subquery. But qualifying the column name adds
+ clarity even when it is not needed. This example shows how the column
+ naming scope of an outer query extends into its inner queries.
+ </p></div><div class="sect2" id="QUERIES-GROUP"><div class="titlepage"><div><div><h3 class="title">7.2.3. The <code class="literal">GROUP BY</code> and <code class="literal">HAVING</code> Clauses</h3></div></div></div><a id="id-1.5.6.6.7.2" class="indexterm"></a><a id="id-1.5.6.6.7.3" class="indexterm"></a><p>
+ After passing the <code class="literal">WHERE</code> filter, the derived input
+ table might be subject to grouping, using the <code class="literal">GROUP BY</code>
+ clause, and elimination of group rows using the <code class="literal">HAVING</code>
+ clause.
+ </p><pre class="synopsis">
+SELECT <em class="replaceable"><code>select_list</code></em>
+ FROM ...
+ [<span class="optional">WHERE ...</span>]
+ GROUP BY <em class="replaceable"><code>grouping_column_reference</code></em> [<span class="optional">, <em class="replaceable"><code>grouping_column_reference</code></em></span>]...
+</pre><p>
+ The <a class="link" href="sql-select.html#SQL-GROUPBY" title="GROUP BY Clause"><code class="literal">GROUP BY</code></a> clause is
+ used to group together those rows in a table that have the same
+ values in all the columns listed. The order in which the columns
+ are listed does not matter. The effect is to combine each set
+ of rows having common values into one group row that
+ represents all rows in the group. This is done to
+ eliminate redundancy in the output and/or compute aggregates that
+ apply to these groups. For instance:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM test1;</code></strong>
+ x | y
+---+---
+ a | 3
+ c | 2
+ b | 5
+ a | 1
+(4 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT x FROM test1 GROUP BY x;</code></strong>
+ x
+---
+ a
+ b
+ c
+(3 rows)
+</pre><p>
+ </p><p>
+ In the second query, we could not have written <code class="literal">SELECT *
+ FROM test1 GROUP BY x</code>, because there is no single value
+ for the column <code class="literal">y</code> that could be associated with each
+ group. The grouped-by columns can be referenced in the select list since
+ they have a single value in each group.
+ </p><p>
+ In general, if a table is grouped, columns that are not
+ listed in <code class="literal">GROUP BY</code> cannot be referenced except in aggregate
+ expressions. An example with aggregate expressions is:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT x, sum(y) FROM test1 GROUP BY x;</code></strong>
+ x | sum
+---+-----
+ a | 4
+ b | 5
+ c | 2
+(3 rows)
+</pre><p>
+ Here <code class="literal">sum</code> is an aggregate function that
+ computes a single value over the entire group. More information
+ about the available aggregate functions can be found in <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Grouping without aggregate expressions effectively calculates the
+ set of distinct values in a column. This can also be achieved
+ using the <code class="literal">DISTINCT</code> clause (see <a class="xref" href="queries-select-lists.html#QUERIES-DISTINCT" title="7.3.3. DISTINCT">Section 7.3.3</a>).
+ </p></div><p>
+ Here is another example: it calculates the total sales for each
+ product (rather than the total sales of all products):
+</p><pre class="programlisting">
+SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
+ FROM products p LEFT JOIN sales s USING (product_id)
+ GROUP BY product_id, p.name, p.price;
+</pre><p>
+ In this example, the columns <code class="literal">product_id</code>,
+ <code class="literal">p.name</code>, and <code class="literal">p.price</code> must be
+ in the <code class="literal">GROUP BY</code> clause since they are referenced in
+ the query select list (but see below). The column
+ <code class="literal">s.units</code> does not have to be in the <code class="literal">GROUP
+ BY</code> list since it is only used in an aggregate expression
+ (<code class="literal">sum(...)</code>), which represents the sales
+ of a product. For each product, the query returns a summary row about
+ all sales of the product.
+ </p><a id="id-1.5.6.6.7.11" class="indexterm"></a><p>
+ If the products table is set up so that, say,
+ <code class="literal">product_id</code> is the primary key, then it would be
+ enough to group by <code class="literal">product_id</code> in the above example,
+ since name and price would be <em class="firstterm">functionally
+ dependent</em> on the product ID, and so there would be no
+ ambiguity about which name and price value to return for each product
+ ID group.
+ </p><p>
+ In strict SQL, <code class="literal">GROUP BY</code> can only group by columns of
+ the source table but <span class="productname">PostgreSQL</span> extends
+ this to also allow <code class="literal">GROUP BY</code> to group by columns in the
+ select list. Grouping by value expressions instead of simple
+ column names is also allowed.
+ </p><a id="id-1.5.6.6.7.14" class="indexterm"></a><p>
+ If a table has been grouped using <code class="literal">GROUP BY</code>,
+ but only certain groups are of interest, the
+ <code class="literal">HAVING</code> clause can be used, much like a
+ <code class="literal">WHERE</code> clause, to eliminate groups from the result.
+ The syntax is:
+</p><pre class="synopsis">
+SELECT <em class="replaceable"><code>select_list</code></em> FROM ... [<span class="optional">WHERE ...</span>] GROUP BY ... HAVING <em class="replaceable"><code>boolean_expression</code></em>
+</pre><p>
+ Expressions in the <code class="literal">HAVING</code> clause can refer both to
+ grouped expressions and to ungrouped expressions (which necessarily
+ involve an aggregate function).
+ </p><p>
+ Example:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) &gt; 3;</code></strong>
+ x | sum
+---+-----
+ a | 4
+ b | 5
+(2 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT x, sum(y) FROM test1 GROUP BY x HAVING x &lt; 'c';</code></strong>
+ x | sum
+---+-----
+ a | 4
+ b | 5
+(2 rows)
+</pre><p>
+ </p><p>
+ Again, a more realistic example:
+</p><pre class="programlisting">
+SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit
+ FROM products p LEFT JOIN sales s USING (product_id)
+ WHERE s.date &gt; CURRENT_DATE - INTERVAL '4 weeks'
+ GROUP BY product_id, p.name, p.price, p.cost
+ HAVING sum(p.price * s.units) &gt; 5000;
+</pre><p>
+ In the example above, the <code class="literal">WHERE</code> clause is selecting
+ rows by a column that is not grouped (the expression is only true for
+ sales during the last four weeks), while the <code class="literal">HAVING</code>
+ clause restricts the output to groups with total gross sales over
+ 5000. Note that the aggregate expressions do not necessarily need
+ to be the same in all parts of the query.
+ </p><p>
+ If a query contains aggregate function calls, but no <code class="literal">GROUP BY</code>
+ clause, grouping still occurs: the result is a single group row (or
+ perhaps no rows at all, if the single row is then eliminated by
+ <code class="literal">HAVING</code>).
+ The same is true if it contains a <code class="literal">HAVING</code> clause, even
+ without any aggregate function calls or <code class="literal">GROUP BY</code> clause.
+ </p></div><div class="sect2" id="QUERIES-GROUPING-SETS"><div class="titlepage"><div><div><h3 class="title">7.2.4. <code class="literal">GROUPING SETS</code>, <code class="literal">CUBE</code>, and <code class="literal">ROLLUP</code></h3></div></div></div><a id="id-1.5.6.6.8.2" class="indexterm"></a><a id="id-1.5.6.6.8.3" class="indexterm"></a><a id="id-1.5.6.6.8.4" class="indexterm"></a><p>
+ More complex grouping operations than those described above are possible
+ using the concept of <em class="firstterm">grouping sets</em>. The data selected by
+ the <code class="literal">FROM</code> and <code class="literal">WHERE</code> clauses is grouped separately
+ by each specified grouping set, aggregates computed for each group just as
+ for simple <code class="literal">GROUP BY</code> clauses, and then the results returned.
+ For example:
+</p><pre class="screen">
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT * FROM items_sold;</code></strong>
+ brand | size | sales
+-------+------+-------
+ Foo | L | 10
+ Foo | M | 20
+ Bar | M | 15
+ Bar | L | 5
+(4 rows)
+
+<code class="prompt">=&gt;</code> <strong class="userinput"><code>SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());</code></strong>
+ brand | size | sum
+-------+------+-----
+ Foo | | 30
+ Bar | | 20
+ | L | 15
+ | M | 35
+ | | 50
+(5 rows)
+</pre><p>
+ </p><p>
+ Each sublist of <code class="literal">GROUPING SETS</code> may specify zero or more columns
+ or expressions and is interpreted the same way as though it were directly
+ in the <code class="literal">GROUP BY</code> clause. An empty grouping set means that all
+ rows are aggregated down to a single group (which is output even if no
+ input rows were present), as described above for the case of aggregate
+ functions with no <code class="literal">GROUP BY</code> clause.
+ </p><p>
+ References to the grouping columns or expressions are replaced
+ by null values in result rows for grouping sets in which those
+ columns do not appear. To distinguish which grouping a particular output
+ row resulted from, see <a class="xref" href="functions-aggregate.html#FUNCTIONS-GROUPING-TABLE" title="Table 9.62. Grouping Operations">Table 9.62</a>.
+ </p><p>
+ A shorthand notation is provided for specifying two common types of grouping set.
+ A clause of the form
+</p><pre class="programlisting">
+ROLLUP ( <em class="replaceable"><code>e1</code></em>, <em class="replaceable"><code>e2</code></em>, <em class="replaceable"><code>e3</code></em>, ... )
+</pre><p>
+ represents the given list of expressions and all prefixes of the list including
+ the empty list; thus it is equivalent to
+</p><pre class="programlisting">
+GROUPING SETS (
+ ( <em class="replaceable"><code>e1</code></em>, <em class="replaceable"><code>e2</code></em>, <em class="replaceable"><code>e3</code></em>, ... ),
+ ...
+ ( <em class="replaceable"><code>e1</code></em>, <em class="replaceable"><code>e2</code></em> ),
+ ( <em class="replaceable"><code>e1</code></em> ),
+ ( )
+)
+</pre><p>
+ This is commonly used for analysis over hierarchical data; e.g., total
+ salary by department, division, and company-wide total.
+ </p><p>
+ A clause of the form
+</p><pre class="programlisting">
+CUBE ( <em class="replaceable"><code>e1</code></em>, <em class="replaceable"><code>e2</code></em>, ... )
+</pre><p>
+ represents the given list and all of its possible subsets (i.e., the power
+ set). Thus
+</p><pre class="programlisting">
+CUBE ( a, b, c )
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+GROUPING SETS (
+ ( a, b, c ),
+ ( a, b ),
+ ( a, c ),
+ ( a ),
+ ( b, c ),
+ ( b ),
+ ( c ),
+ ( )
+)
+</pre><p>
+ </p><p>
+ The individual elements of a <code class="literal">CUBE</code> or <code class="literal">ROLLUP</code>
+ clause may be either individual expressions, or sublists of elements in
+ parentheses. In the latter case, the sublists are treated as single
+ units for the purposes of generating the individual grouping sets.
+ For example:
+</p><pre class="programlisting">
+CUBE ( (a, b), (c, d) )
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+GROUPING SETS (
+ ( a, b, c, d ),
+ ( a, b ),
+ ( c, d ),
+ ( )
+)
+</pre><p>
+ and
+</p><pre class="programlisting">
+ROLLUP ( a, (b, c), d )
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+GROUPING SETS (
+ ( a, b, c, d ),
+ ( a, b, c ),
+ ( a ),
+ ( )
+)
+</pre><p>
+ </p><p>
+ The <code class="literal">CUBE</code> and <code class="literal">ROLLUP</code> constructs can be used either
+ directly in the <code class="literal">GROUP BY</code> clause, or nested inside a
+ <code class="literal">GROUPING SETS</code> clause. If one <code class="literal">GROUPING SETS</code> clause
+ is nested inside another, the effect is the same as if all the elements of
+ the inner clause had been written directly in the outer clause.
+ </p><p>
+ If multiple grouping items are specified in a single <code class="literal">GROUP BY</code>
+ clause, then the final list of grouping sets is the cross product of the
+ individual items. For example:
+</p><pre class="programlisting">
+GROUP BY a, CUBE (b, c), GROUPING SETS ((d), (e))
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+GROUP BY GROUPING SETS (
+ (a, b, c, d), (a, b, c, e),
+ (a, b, d), (a, b, e),
+ (a, c, d), (a, c, e),
+ (a, d), (a, e)
+)
+</pre><p>
+ </p><p>
+ <a id="id-1.5.6.6.8.13.1" class="indexterm"></a>
+ <a id="id-1.5.6.6.8.13.2" class="indexterm"></a>
+ When specifying multiple grouping items together, the final set of grouping
+ sets might contain duplicates. For example:
+</p><pre class="programlisting">
+GROUP BY ROLLUP (a, b), ROLLUP (a, c)
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+GROUP BY GROUPING SETS (
+ (a, b, c),
+ (a, b),
+ (a, b),
+ (a, c),
+ (a),
+ (a),
+ (a, c),
+ (a),
+ ()
+)
+</pre><p>
+ If these duplicates are undesirable, they can be removed using the
+ <code class="literal">DISTINCT</code> clause directly on the <code class="literal">GROUP BY</code>.
+ Therefore:
+</p><pre class="programlisting">
+GROUP BY <span class="emphasis"><strong>DISTINCT</strong></span> ROLLUP (a, b), ROLLUP (a, c)
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+GROUP BY GROUPING SETS (
+ (a, b, c),
+ (a, b),
+ (a, c),
+ (a),
+ ()
+)
+</pre><p>
+ This is not the same as using <code class="literal">SELECT DISTINCT</code> because the output
+ rows may still contain duplicates. If any of the ungrouped columns contains NULL,
+ it will be indistinguishable from the NULL used when that same column is grouped.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The construct <code class="literal">(a, b)</code> is normally recognized in expressions as
+ a <a class="link" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">row constructor</a>.
+ Within the <code class="literal">GROUP BY</code> clause, this does not apply at the top
+ levels of expressions, and <code class="literal">(a, b)</code> is parsed as a list of
+ expressions as described above. If for some reason you <span class="emphasis"><em>need</em></span>
+ a row constructor in a grouping expression, use <code class="literal">ROW(a, b)</code>.
+ </p></div></div><div class="sect2" id="QUERIES-WINDOW"><div class="titlepage"><div><div><h3 class="title">7.2.5. Window Function Processing</h3></div></div></div><a id="id-1.5.6.6.9.2" class="indexterm"></a><p>
+ If the query contains any window functions (see
+ <a class="xref" href="tutorial-window.html" title="3.5. Window Functions">Section 3.5</a>,
+ <a class="xref" href="functions-window.html" title="9.22. Window Functions">Section 9.22</a> and
+ <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a>), these functions are evaluated
+ after any grouping, aggregation, and <code class="literal">HAVING</code> filtering is
+ performed. That is, if the query uses any aggregates, <code class="literal">GROUP
+ BY</code>, or <code class="literal">HAVING</code>, then the rows seen by the window functions
+ are the group rows instead of the original table rows from
+ <code class="literal">FROM</code>/<code class="literal">WHERE</code>.
+ </p><p>
+ When multiple window functions are used, all the window functions having
+ syntactically equivalent <code class="literal">PARTITION BY</code> and <code class="literal">ORDER BY</code>
+ clauses in their window definitions are guaranteed to be evaluated in a
+ single pass over the data. Therefore they will see the same sort ordering,
+ even if the <code class="literal">ORDER BY</code> does not uniquely determine an ordering.
+ However, no guarantees are made about the evaluation of functions having
+ different <code class="literal">PARTITION BY</code> or <code class="literal">ORDER BY</code> specifications.
+ (In such cases a sort step is typically required between the passes of
+ window function evaluations, and the sort is not guaranteed to preserve
+ ordering of rows that its <code class="literal">ORDER BY</code> sees as equivalent.)
+ </p><p>
+ Currently, window functions always require presorted data, and so the
+ query output will be ordered according to one or another of the window
+ functions' <code class="literal">PARTITION BY</code>/<code class="literal">ORDER BY</code> clauses.
+ It is not recommended to rely on this, however. Use an explicit
+ top-level <code class="literal">ORDER BY</code> clause if you want to be sure the
+ results are sorted in a particular way.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-overview.html" title="7.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-select-lists.html" title="7.3. Select Lists">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.3. Select Lists</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-union.html b/doc/src/sgml/html/queries-union.html
new file mode 100644
index 0000000..ec00fd0
--- /dev/null
+++ b/doc/src/sgml/html/queries-union.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.4. Combining Queries (UNION, INTERSECT, EXCEPT)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-select-lists.html" title="7.3. Select Lists" /><link rel="next" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.4. Combining Queries (<code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-select-lists.html" title="7.3. Select Lists">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-UNION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.4. Combining Queries (<code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>)</h2></div></div></div><a id="id-1.5.6.8.2" class="indexterm"></a><a id="id-1.5.6.8.3" class="indexterm"></a><a id="id-1.5.6.8.4" class="indexterm"></a><a id="id-1.5.6.8.5" class="indexterm"></a><a id="id-1.5.6.8.6" class="indexterm"></a><a id="id-1.5.6.8.7" class="indexterm"></a><a id="id-1.5.6.8.8" class="indexterm"></a><p>
+ The results of two queries can be combined using the set operations
+ union, intersection, and difference. The syntax is
+</p><pre class="synopsis">
+<em class="replaceable"><code>query1</code></em> UNION [<span class="optional">ALL</span>] <em class="replaceable"><code>query2</code></em>
+<em class="replaceable"><code>query1</code></em> INTERSECT [<span class="optional">ALL</span>] <em class="replaceable"><code>query2</code></em>
+<em class="replaceable"><code>query1</code></em> EXCEPT [<span class="optional">ALL</span>] <em class="replaceable"><code>query2</code></em>
+</pre><p>
+ where <em class="replaceable"><code>query1</code></em> and
+ <em class="replaceable"><code>query2</code></em> are queries that can use any of
+ the features discussed up to this point.
+ </p><p>
+ <code class="literal">UNION</code> effectively appends the result of
+ <em class="replaceable"><code>query2</code></em> to the result of
+ <em class="replaceable"><code>query1</code></em> (although there is no guarantee
+ that this is the order in which the rows are actually returned).
+ Furthermore, it eliminates duplicate rows from its result, in the same
+ way as <code class="literal">DISTINCT</code>, unless <code class="literal">UNION ALL</code> is used.
+ </p><p>
+ <code class="literal">INTERSECT</code> returns all rows that are both in the result
+ of <em class="replaceable"><code>query1</code></em> and in the result of
+ <em class="replaceable"><code>query2</code></em>. Duplicate rows are eliminated
+ unless <code class="literal">INTERSECT ALL</code> is used.
+ </p><p>
+ <code class="literal">EXCEPT</code> returns all rows that are in the result of
+ <em class="replaceable"><code>query1</code></em> but not in the result of
+ <em class="replaceable"><code>query2</code></em>. (This is sometimes called the
+ <em class="firstterm">difference</em> between two queries.) Again, duplicates
+ are eliminated unless <code class="literal">EXCEPT ALL</code> is used.
+ </p><p>
+ In order to calculate the union, intersection, or difference of two
+ queries, the two queries must be <span class="quote">“<span class="quote">union compatible</span>”</span>,
+ which means that they return the same number of columns and
+ the corresponding columns have compatible data types, as
+ described in <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a>.
+ </p><p>
+ Set operations can be combined, for example
+</p><pre class="synopsis">
+<em class="replaceable"><code>query1</code></em> UNION <em class="replaceable"><code>query2</code></em> EXCEPT <em class="replaceable"><code>query3</code></em>
+</pre><p>
+ which is equivalent to
+</p><pre class="synopsis">
+(<em class="replaceable"><code>query1</code></em> UNION <em class="replaceable"><code>query2</code></em>) EXCEPT <em class="replaceable"><code>query3</code></em>
+</pre><p>
+ As shown here, you can use parentheses to control the order of
+ evaluation. Without parentheses, <code class="literal">UNION</code>
+ and <code class="literal">EXCEPT</code> associate left-to-right,
+ but <code class="literal">INTERSECT</code> binds more tightly than those two
+ operators. Thus
+</p><pre class="synopsis">
+<em class="replaceable"><code>query1</code></em> UNION <em class="replaceable"><code>query2</code></em> INTERSECT <em class="replaceable"><code>query3</code></em>
+</pre><p>
+ means
+</p><pre class="synopsis">
+<em class="replaceable"><code>query1</code></em> UNION (<em class="replaceable"><code>query2</code></em> INTERSECT <em class="replaceable"><code>query3</code></em>)
+</pre><p>
+ You can also surround an individual <em class="replaceable"><code>query</code></em>
+ with parentheses. This is important if
+ the <em class="replaceable"><code>query</code></em> needs to use any of the clauses
+ discussed in following sections, such as <code class="literal">LIMIT</code>.
+ Without parentheses, you'll get a syntax error, or else the clause will
+ be understood as applying to the output of the set operation rather
+ than one of its inputs. For example,
+</p><pre class="synopsis">
+SELECT a FROM b UNION SELECT x FROM y LIMIT 10
+</pre><p>
+ is accepted, but it means
+</p><pre class="synopsis">
+(SELECT a FROM b UNION SELECT x FROM y) LIMIT 10
+</pre><p>
+ not
+</p><pre class="synopsis">
+SELECT a FROM b UNION (SELECT x FROM y LIMIT 10)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-select-lists.html" title="7.3. Select Lists">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.3. Select Lists </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.5. Sorting Rows (<code class="literal">ORDER BY</code>)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-values.html b/doc/src/sgml/html/queries-values.html
new file mode 100644
index 0000000..84bafb6
--- /dev/null
+++ b/doc/src/sgml/html/queries-values.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.7. VALUES Lists</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-limit.html" title="7.6. LIMIT and OFFSET" /><link rel="next" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.7. <code class="literal">VALUES</code> Lists</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-limit.html" title="7.6. LIMIT and OFFSET">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-VALUES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.7. <code class="literal">VALUES</code> Lists</h2></div></div></div><a id="id-1.5.6.11.2" class="indexterm"></a><p>
+ <code class="literal">VALUES</code> provides a way to generate a <span class="quote">“<span class="quote">constant table</span>”</span>
+ that can be used in a query without having to actually create and populate
+ a table on-disk. The syntax is
+</p><pre class="synopsis">
+VALUES ( <em class="replaceable"><code>expression</code></em> [, ...] ) [, ...]
+</pre><p>
+ Each parenthesized list of expressions generates a row in the table.
+ The lists must all have the same number of elements (i.e., the number
+ of columns in the table), and corresponding entries in each list must
+ have compatible data types. The actual data type assigned to each column
+ of the result is determined using the same rules as for <code class="literal">UNION</code>
+ (see <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a>).
+ </p><p>
+ As an example:
+</p><pre class="programlisting">
+VALUES (1, 'one'), (2, 'two'), (3, 'three');
+</pre><p>
+
+ will return a table of two columns and three rows. It's effectively
+ equivalent to:
+</p><pre class="programlisting">
+SELECT 1 AS column1, 'one' AS column2
+UNION ALL
+SELECT 2, 'two'
+UNION ALL
+SELECT 3, 'three';
+</pre><p>
+
+ By default, <span class="productname">PostgreSQL</span> assigns the names
+ <code class="literal">column1</code>, <code class="literal">column2</code>, etc. to the columns of a
+ <code class="literal">VALUES</code> table. The column names are not specified by the
+ SQL standard and different database systems do it differently, so
+ it's usually better to override the default names with a table alias
+ list, like this:
+</p><pre class="programlisting">
+=&gt; SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);
+ num | letter
+-----+--------
+ 1 | one
+ 2 | two
+ 3 | three
+(3 rows)
+</pre><p>
+ </p><p>
+ Syntactically, <code class="literal">VALUES</code> followed by expression lists is
+ treated as equivalent to:
+</p><pre class="synopsis">
+SELECT <em class="replaceable"><code>select_list</code></em> FROM <em class="replaceable"><code>table_expression</code></em>
+</pre><p>
+ and can appear anywhere a <code class="literal">SELECT</code> can. For example, you can
+ use it as part of a <code class="literal">UNION</code>, or attach a
+ <em class="replaceable"><code>sort_specification</code></em> (<code class="literal">ORDER BY</code>,
+ <code class="literal">LIMIT</code>, and/or <code class="literal">OFFSET</code>) to it. <code class="literal">VALUES</code>
+ is most commonly used as the data source in an <code class="command">INSERT</code> command,
+ and next most commonly as a subquery.
+ </p><p>
+ For more information see <a class="xref" href="sql-values.html" title="VALUES"><span class="refentrytitle">VALUES</span></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-limit.html" title="7.6. LIMIT and OFFSET">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.6. <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.8. <code class="literal">WITH</code> Queries (Common Table Expressions)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries-with.html b/doc/src/sgml/html/queries-with.html
new file mode 100644
index 0000000..0a8ef3b
--- /dev/null
+++ b/doc/src/sgml/html/queries-with.html
@@ -0,0 +1,564 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>7.8. WITH Queries (Common Table Expressions)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="queries-values.html" title="7.7. VALUES Lists" /><link rel="next" href="datatype.html" title="Chapter 8. Data Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="queries-values.html" title="7.7. VALUES Lists">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><th width="60%" align="center">Chapter 7. Queries</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="datatype.html" title="Chapter 8. Data Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERIES-WITH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions)</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-SELECT">7.8.1. <code class="command">SELECT</code> in <code class="literal">WITH</code></a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-RECURSIVE">7.8.2. Recursive Queries</a></span></dt><dt><span class="sect2"><a href="queries-with.html#id-1.5.6.12.7">7.8.3. Common Table Expression Materialization</a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-MODIFYING">7.8.4. Data-Modifying Statements in <code class="literal">WITH</code></a></span></dt></dl></div><a id="id-1.5.6.12.2" class="indexterm"></a><a id="id-1.5.6.12.3" class="indexterm"></a><p>
+ <code class="literal">WITH</code> provides a way to write auxiliary statements for use in a
+ larger query. These statements, which are often referred to as Common
+ Table Expressions or <acronym class="acronym">CTE</acronym>s, can be thought of as defining
+ temporary tables that exist just for one query. Each auxiliary statement
+ in a <code class="literal">WITH</code> clause can be a <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or <code class="command">DELETE</code>; and the
+ <code class="literal">WITH</code> clause itself is attached to a primary statement that can
+ be a <code class="command">SELECT</code>, <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, or <code class="command">MERGE</code>.
+ </p><div class="sect2" id="QUERIES-WITH-SELECT"><div class="titlepage"><div><div><h3 class="title">7.8.1. <code class="command">SELECT</code> in <code class="literal">WITH</code></h3></div></div></div><p>
+ The basic value of <code class="command">SELECT</code> in <code class="literal">WITH</code> is to
+ break down complicated queries into simpler parts. An example is:
+
+</p><pre class="programlisting">
+WITH regional_sales AS (
+ SELECT region, SUM(amount) AS total_sales
+ FROM orders
+ GROUP BY region
+), top_regions AS (
+ SELECT region
+ FROM regional_sales
+ WHERE total_sales &gt; (SELECT SUM(total_sales)/10 FROM regional_sales)
+)
+SELECT region,
+ product,
+ SUM(quantity) AS product_units,
+ SUM(amount) AS product_sales
+FROM orders
+WHERE region IN (SELECT region FROM top_regions)
+GROUP BY region, product;
+</pre><p>
+
+ which displays per-product sales totals in only the top sales regions.
+ The <code class="literal">WITH</code> clause defines two auxiliary statements named
+ <code class="structname">regional_sales</code> and <code class="structname">top_regions</code>,
+ where the output of <code class="structname">regional_sales</code> is used in
+ <code class="structname">top_regions</code> and the output of <code class="structname">top_regions</code>
+ is used in the primary <code class="command">SELECT</code> query.
+ This example could have been written without <code class="literal">WITH</code>,
+ but we'd have needed two levels of nested sub-<code class="command">SELECT</code>s. It's a bit
+ easier to follow this way.
+ </p></div><div class="sect2" id="QUERIES-WITH-RECURSIVE"><div class="titlepage"><div><div><h3 class="title">7.8.2. Recursive Queries</h3></div></div></div><p>
+ <a id="id-1.5.6.12.6.2.1" class="indexterm"></a>
+ The optional <code class="literal">RECURSIVE</code> modifier changes <code class="literal">WITH</code>
+ from a mere syntactic convenience into a feature that accomplishes
+ things not otherwise possible in standard SQL. Using
+ <code class="literal">RECURSIVE</code>, a <code class="literal">WITH</code> query can refer to its own
+ output. A very simple example is this query to sum the integers from 1
+ through 100:
+
+</p><pre class="programlisting">
+WITH RECURSIVE t(n) AS (
+ VALUES (1)
+ UNION ALL
+ SELECT n+1 FROM t WHERE n &lt; 100
+)
+SELECT sum(n) FROM t;
+</pre><p>
+
+ The general form of a recursive <code class="literal">WITH</code> query is always a
+ <em class="firstterm">non-recursive term</em>, then <code class="literal">UNION</code> (or
+ <code class="literal">UNION ALL</code>), then a
+ <em class="firstterm">recursive term</em>, where only the recursive term can contain
+ a reference to the query's own output. Such a query is executed as
+ follows:
+ </p><div class="procedure" id="id-1.5.6.12.6.3"><p class="title"><strong>Recursive Query Evaluation</strong></p><ol class="procedure" type="1"><li class="step"><p>
+ Evaluate the non-recursive term. For <code class="literal">UNION</code> (but not
+ <code class="literal">UNION ALL</code>), discard duplicate rows. Include all remaining
+ rows in the result of the recursive query, and also place them in a
+ temporary <em class="firstterm">working table</em>.
+ </p></li><li class="step"><p>
+ So long as the working table is not empty, repeat these steps:
+ </p><ol type="a" class="substeps"><li class="step"><p>
+ Evaluate the recursive term, substituting the current contents of
+ the working table for the recursive self-reference.
+ For <code class="literal">UNION</code> (but not <code class="literal">UNION ALL</code>), discard
+ duplicate rows and rows that duplicate any previous result row.
+ Include all remaining rows in the result of the recursive query, and
+ also place them in a temporary <em class="firstterm">intermediate table</em>.
+ </p></li><li class="step"><p>
+ Replace the contents of the working table with the contents of the
+ intermediate table, then empty the intermediate table.
+ </p></li></ol></li></ol></div><div class="note"><h3 class="title">Note</h3><p>
+ While <code class="literal">RECURSIVE</code> allows queries to be specified
+ recursively, internally such queries are evaluated iteratively.
+ </p></div><p>
+ In the example above, the working table has just a single row in each step,
+ and it takes on the values from 1 through 100 in successive steps. In
+ the 100th step, there is no output because of the <code class="literal">WHERE</code>
+ clause, and so the query terminates.
+ </p><p>
+ Recursive queries are typically used to deal with hierarchical or
+ tree-structured data. A useful example is this query to find all the
+ direct and indirect sub-parts of a product, given only a table that
+ shows immediate inclusions:
+
+</p><pre class="programlisting">
+WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
+ SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
+ UNION ALL
+ SELECT p.sub_part, p.part, p.quantity * pr.quantity
+ FROM included_parts pr, parts p
+ WHERE p.part = pr.sub_part
+)
+SELECT sub_part, SUM(quantity) as total_quantity
+FROM included_parts
+GROUP BY sub_part
+</pre><p>
+ </p><div class="sect3" id="QUERIES-WITH-SEARCH"><div class="titlepage"><div><div><h4 class="title">7.8.2.1. Search Order</h4></div></div></div><p>
+ When computing a tree traversal using a recursive query, you might want to
+ order the results in either depth-first or breadth-first order. This can
+ be done by computing an ordering column alongside the other data columns
+ and using that to sort the results at the end. Note that this does not
+ actually control in which order the query evaluation visits the rows; that
+ is as always in SQL implementation-dependent. This approach merely
+ provides a convenient way to order the results afterwards.
+ </p><p>
+ To create a depth-first order, we compute for each result row an array of
+ rows that we have visited so far. For example, consider the following
+ query that searches a table <code class="structname">tree</code> using a
+ <code class="structfield">link</code> field:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_tree(id, link, data) AS (
+ SELECT t.id, t.link, t.data
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree;
+</pre><p>
+
+ To add depth-first ordering information, you can write this:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_tree(id, link, data, <span class="emphasis"><strong>path</strong></span>) AS (
+ SELECT t.id, t.link, t.data, <span class="emphasis"><strong>ARRAY[t.id]</strong></span>
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data, <span class="emphasis"><strong>path || t.id</strong></span>
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree <span class="emphasis"><strong>ORDER BY path</strong></span>;
+</pre><p>
+ </p><p>
+ In the general case where more than one field needs to be used to identify
+ a row, use an array of rows. For example, if we needed to track fields
+ <code class="structfield">f1</code> and <code class="structfield">f2</code>:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_tree(id, link, data, <span class="emphasis"><strong>path</strong></span>) AS (
+ SELECT t.id, t.link, t.data, <span class="emphasis"><strong>ARRAY[ROW(t.f1, t.f2)]</strong></span>
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data, <span class="emphasis"><strong>path || ROW(t.f1, t.f2)</strong></span>
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree <span class="emphasis"><strong>ORDER BY path</strong></span>;
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Omit the <code class="literal">ROW()</code> syntax in the common case where only one
+ field needs to be tracked. This allows a simple array rather than a
+ composite-type array to be used, gaining efficiency.
+ </p></div><p>
+ To create a breadth-first order, you can add a column that tracks the depth
+ of the search, for example:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_tree(id, link, data, <span class="emphasis"><strong>depth</strong></span>) AS (
+ SELECT t.id, t.link, t.data, <span class="emphasis"><strong>0</strong></span>
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data, <span class="emphasis"><strong>depth + 1</strong></span>
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree <span class="emphasis"><strong>ORDER BY depth</strong></span>;
+</pre><p>
+
+ To get a stable sort, add data columns as secondary sorting columns.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The recursive query evaluation algorithm produces its output in
+ breadth-first search order. However, this is an implementation detail and
+ it is perhaps unsound to rely on it. The order of the rows within each
+ level is certainly undefined, so some explicit ordering might be desired
+ in any case.
+ </p></div><p>
+ There is built-in syntax to compute a depth- or breadth-first sort column.
+ For example:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_tree(id, link, data) AS (
+ SELECT t.id, t.link, t.data
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+) <span class="emphasis"><strong>SEARCH DEPTH FIRST BY id SET ordercol</strong></span>
+SELECT * FROM search_tree ORDER BY ordercol;
+
+WITH RECURSIVE search_tree(id, link, data) AS (
+ SELECT t.id, t.link, t.data
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+) <span class="emphasis"><strong>SEARCH BREADTH FIRST BY id SET ordercol</strong></span>
+SELECT * FROM search_tree ORDER BY ordercol;
+</pre><p>
+ This syntax is internally expanded to something similar to the above
+ hand-written forms. The <code class="literal">SEARCH</code> clause specifies whether
+ depth- or breadth first search is wanted, the list of columns to track for
+ sorting, and a column name that will contain the result data that can be
+ used for sorting. That column will implicitly be added to the output rows
+ of the CTE.
+ </p></div><div class="sect3" id="QUERIES-WITH-CYCLE"><div class="titlepage"><div><div><h4 class="title">7.8.2.2. Cycle Detection</h4></div></div></div><p>
+ When working with recursive queries it is important to be sure that
+ the recursive part of the query will eventually return no tuples,
+ or else the query will loop indefinitely. Sometimes, using
+ <code class="literal">UNION</code> instead of <code class="literal">UNION ALL</code> can accomplish this
+ by discarding rows that duplicate previous output rows. However, often a
+ cycle does not involve output rows that are completely duplicate: it may be
+ necessary to check just one or a few fields to see if the same point has
+ been reached before. The standard method for handling such situations is
+ to compute an array of the already-visited values. For example, consider again
+ the following query that searches a table <code class="structname">graph</code> using a
+ <code class="structfield">link</code> field:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_graph(id, link, data, depth) AS (
+ SELECT g.id, g.link, g.data, 0
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link
+)
+SELECT * FROM search_graph;
+</pre><p>
+
+ This query will loop if the <code class="structfield">link</code> relationships contain
+ cycles. Because we require a <span class="quote">“<span class="quote">depth</span>”</span> output, just changing
+ <code class="literal">UNION ALL</code> to <code class="literal">UNION</code> would not eliminate the looping.
+ Instead we need to recognize whether we have reached the same row again
+ while following a particular path of links. We add two columns
+ <code class="structfield">is_cycle</code> and <code class="structfield">path</code> to the loop-prone query:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_graph(id, link, data, depth, <span class="emphasis"><strong>is_cycle, path</strong></span>) AS (
+ SELECT g.id, g.link, g.data, 0,
+ <span class="emphasis"><strong>false,
+ ARRAY[g.id]</strong></span>
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1,
+ <span class="emphasis"><strong>g.id = ANY(path),
+ path || g.id</strong></span>
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link <span class="emphasis"><strong>AND NOT is_cycle</strong></span>
+)
+SELECT * FROM search_graph;
+</pre><p>
+
+ Aside from preventing cycles, the array value is often useful in its own
+ right as representing the <span class="quote">“<span class="quote">path</span>”</span> taken to reach any particular row.
+ </p><p>
+ In the general case where more than one field needs to be checked to
+ recognize a cycle, use an array of rows. For example, if we needed to
+ compare fields <code class="structfield">f1</code> and <code class="structfield">f2</code>:
+
+</p><pre class="programlisting">
+WITH RECURSIVE search_graph(id, link, data, depth, <span class="emphasis"><strong>is_cycle, path</strong></span>) AS (
+ SELECT g.id, g.link, g.data, 0,
+ <span class="emphasis"><strong>false,
+ ARRAY[ROW(g.f1, g.f2)]</strong></span>
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1,
+ <span class="emphasis"><strong>ROW(g.f1, g.f2) = ANY(path),
+ path || ROW(g.f1, g.f2)</strong></span>
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link <span class="emphasis"><strong>AND NOT is_cycle</strong></span>
+)
+SELECT * FROM search_graph;
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Omit the <code class="literal">ROW()</code> syntax in the common case where only one field
+ needs to be checked to recognize a cycle. This allows a simple array
+ rather than a composite-type array to be used, gaining efficiency.
+ </p></div><p>
+ There is built-in syntax to simplify cycle detection. The above query can
+ also be written like this:
+</p><pre class="programlisting">
+WITH RECURSIVE search_graph(id, link, data, depth) AS (
+ SELECT g.id, g.link, g.data, 1
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link
+) <span class="emphasis"><strong>CYCLE id SET is_cycle USING path</strong></span>
+SELECT * FROM search_graph;
+</pre><p>
+ and it will be internally rewritten to the above form. The
+ <code class="literal">CYCLE</code> clause specifies first the list of columns to
+ track for cycle detection, then a column name that will show whether a
+ cycle has been detected, and finally the name of another column that will track the
+ path. The cycle and path columns will implicitly be added to the output
+ rows of the CTE.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The cycle path column is computed in the same way as the depth-first
+ ordering column show in the previous section. A query can have both a
+ <code class="literal">SEARCH</code> and a <code class="literal">CYCLE</code> clause, but a
+ depth-first search specification and a cycle detection specification would
+ create redundant computations, so it's more efficient to just use the
+ <code class="literal">CYCLE</code> clause and order by the path column. If
+ breadth-first ordering is wanted, then specifying both
+ <code class="literal">SEARCH</code> and <code class="literal">CYCLE</code> can be useful.
+ </p></div><p>
+ A helpful trick for testing queries
+ when you are not certain if they might loop is to place a <code class="literal">LIMIT</code>
+ in the parent query. For example, this query would loop forever without
+ the <code class="literal">LIMIT</code>:
+
+</p><pre class="programlisting">
+WITH RECURSIVE t(n) AS (
+ SELECT 1
+ UNION ALL
+ SELECT n+1 FROM t
+)
+SELECT n FROM t <span class="emphasis"><strong>LIMIT 100</strong></span>;
+</pre><p>
+
+ This works because <span class="productname">PostgreSQL</span>'s implementation
+ evaluates only as many rows of a <code class="literal">WITH</code> query as are actually
+ fetched by the parent query. Using this trick in production is not
+ recommended, because other systems might work differently. Also, it
+ usually won't work if you make the outer query sort the recursive query's
+ results or join them to some other table, because in such cases the
+ outer query will usually try to fetch all of the <code class="literal">WITH</code> query's
+ output anyway.
+ </p></div></div><div class="sect2" id="id-1.5.6.12.7"><div class="titlepage"><div><div><h3 class="title">7.8.3. Common Table Expression Materialization</h3></div></div></div><p>
+ A useful property of <code class="literal">WITH</code> queries is that they are
+ normally evaluated only once per execution of the parent query, even if
+ they are referred to more than once by the parent query or
+ sibling <code class="literal">WITH</code> queries.
+ Thus, expensive calculations that are needed in multiple places can be
+ placed within a <code class="literal">WITH</code> query to avoid redundant work. Another
+ possible application is to prevent unwanted multiple evaluations of
+ functions with side-effects.
+ However, the other side of this coin is that the optimizer is not able to
+ push restrictions from the parent query down into a multiply-referenced
+ <code class="literal">WITH</code> query, since that might affect all uses of the
+ <code class="literal">WITH</code> query's output when it should affect only one.
+ The multiply-referenced <code class="literal">WITH</code> query will be
+ evaluated as written, without suppression of rows that the parent query
+ might discard afterwards. (But, as mentioned above, evaluation might stop
+ early if the reference(s) to the query demand only a limited number of
+ rows.)
+ </p><p>
+ However, if a <code class="literal">WITH</code> query is non-recursive and
+ side-effect-free (that is, it is a <code class="literal">SELECT</code> containing
+ no volatile functions) then it can be folded into the parent query,
+ allowing joint optimization of the two query levels. By default, this
+ happens if the parent query references the <code class="literal">WITH</code> query
+ just once, but not if it references the <code class="literal">WITH</code> query
+ more than once. You can override that decision by
+ specifying <code class="literal">MATERIALIZED</code> to force separate calculation
+ of the <code class="literal">WITH</code> query, or by specifying <code class="literal">NOT
+ MATERIALIZED</code> to force it to be merged into the parent query.
+ The latter choice risks duplicate computation of
+ the <code class="literal">WITH</code> query, but it can still give a net savings if
+ each usage of the <code class="literal">WITH</code> query needs only a small part
+ of the <code class="literal">WITH</code> query's full output.
+ </p><p>
+ A simple example of these rules is
+</p><pre class="programlisting">
+WITH w AS (
+ SELECT * FROM big_table
+)
+SELECT * FROM w WHERE key = 123;
+</pre><p>
+ This <code class="literal">WITH</code> query will be folded, producing the same
+ execution plan as
+</p><pre class="programlisting">
+SELECT * FROM big_table WHERE key = 123;
+</pre><p>
+ In particular, if there's an index on <code class="structfield">key</code>,
+ it will probably be used to fetch just the rows having <code class="literal">key =
+ 123</code>. On the other hand, in
+</p><pre class="programlisting">
+WITH w AS (
+ SELECT * FROM big_table
+)
+SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
+WHERE w2.key = 123;
+</pre><p>
+ the <code class="literal">WITH</code> query will be materialized, producing a
+ temporary copy of <code class="structname">big_table</code> that is then
+ joined with itself — without benefit of any index. This query
+ will be executed much more efficiently if written as
+</p><pre class="programlisting">
+WITH w AS NOT MATERIALIZED (
+ SELECT * FROM big_table
+)
+SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
+WHERE w2.key = 123;
+</pre><p>
+ so that the parent query's restrictions can be applied directly
+ to scans of <code class="structname">big_table</code>.
+ </p><p>
+ An example where <code class="literal">NOT MATERIALIZED</code> could be
+ undesirable is
+</p><pre class="programlisting">
+WITH w AS (
+ SELECT key, very_expensive_function(val) as f FROM some_table
+)
+SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f;
+</pre><p>
+ Here, materialization of the <code class="literal">WITH</code> query ensures
+ that <code class="function">very_expensive_function</code> is evaluated only
+ once per table row, not twice.
+ </p><p>
+ The examples above only show <code class="literal">WITH</code> being used with
+ <code class="command">SELECT</code>, but it can be attached in the same way to
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, or <code class="command">MERGE</code>.
+ In each case it effectively provides temporary table(s) that can
+ be referred to in the main command.
+ </p></div><div class="sect2" id="QUERIES-WITH-MODIFYING"><div class="titlepage"><div><div><h3 class="title">7.8.4. Data-Modifying Statements in <code class="literal">WITH</code></h3></div></div></div><p>
+ You can use most data-modifying statements (<code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, or <code class="command">DELETE</code>, but not
+ <code class="command">MERGE</code>) in <code class="literal">WITH</code>. This
+ allows you to perform several different operations in the same query.
+ An example is:
+
+</p><pre class="programlisting">
+WITH moved_rows AS (
+ DELETE FROM products
+ WHERE
+ "date" &gt;= '2010-10-01' AND
+ "date" &lt; '2010-11-01'
+ RETURNING *
+)
+INSERT INTO products_log
+SELECT * FROM moved_rows;
+</pre><p>
+
+ This query effectively moves rows from <code class="structname">products</code> to
+ <code class="structname">products_log</code>. The <code class="command">DELETE</code> in <code class="literal">WITH</code>
+ deletes the specified rows from <code class="structname">products</code>, returning their
+ contents by means of its <code class="literal">RETURNING</code> clause; and then the
+ primary query reads that output and inserts it into
+ <code class="structname">products_log</code>.
+ </p><p>
+ A fine point of the above example is that the <code class="literal">WITH</code> clause is
+ attached to the <code class="command">INSERT</code>, not the sub-<code class="command">SELECT</code> within
+ the <code class="command">INSERT</code>. This is necessary because data-modifying
+ statements are only allowed in <code class="literal">WITH</code> clauses that are attached
+ to the top-level statement. However, normal <code class="literal">WITH</code> visibility
+ rules apply, so it is possible to refer to the <code class="literal">WITH</code>
+ statement's output from the sub-<code class="command">SELECT</code>.
+ </p><p>
+ Data-modifying statements in <code class="literal">WITH</code> usually have
+ <code class="literal">RETURNING</code> clauses (see <a class="xref" href="dml-returning.html" title="6.4. Returning Data from Modified Rows">Section 6.4</a>),
+ as shown in the example above.
+ It is the output of the <code class="literal">RETURNING</code> clause, <span class="emphasis"><em>not</em></span> the
+ target table of the data-modifying statement, that forms the temporary
+ table that can be referred to by the rest of the query. If a
+ data-modifying statement in <code class="literal">WITH</code> lacks a <code class="literal">RETURNING</code>
+ clause, then it forms no temporary table and cannot be referred to in
+ the rest of the query. Such a statement will be executed nonetheless.
+ A not-particularly-useful example is:
+
+</p><pre class="programlisting">
+WITH t AS (
+ DELETE FROM foo
+)
+DELETE FROM bar;
+</pre><p>
+
+ This example would remove all rows from tables <code class="structname">foo</code> and
+ <code class="structname">bar</code>. The number of affected rows reported to the client
+ would only include rows removed from <code class="structname">bar</code>.
+ </p><p>
+ Recursive self-references in data-modifying statements are not
+ allowed. In some cases it is possible to work around this limitation by
+ referring to the output of a recursive <code class="literal">WITH</code>, for example:
+
+</p><pre class="programlisting">
+WITH RECURSIVE included_parts(sub_part, part) AS (
+ SELECT sub_part, part FROM parts WHERE part = 'our_product'
+ UNION ALL
+ SELECT p.sub_part, p.part
+ FROM included_parts pr, parts p
+ WHERE p.part = pr.sub_part
+)
+DELETE FROM parts
+ WHERE part IN (SELECT part FROM included_parts);
+</pre><p>
+
+ This query would remove all direct and indirect subparts of a product.
+ </p><p>
+ Data-modifying statements in <code class="literal">WITH</code> are executed exactly once,
+ and always to completion, independently of whether the primary query
+ reads all (or indeed any) of their output. Notice that this is different
+ from the rule for <code class="command">SELECT</code> in <code class="literal">WITH</code>: as stated in the
+ previous section, execution of a <code class="command">SELECT</code> is carried only as far
+ as the primary query demands its output.
+ </p><p>
+ The sub-statements in <code class="literal">WITH</code> are executed concurrently with
+ each other and with the main query. Therefore, when using data-modifying
+ statements in <code class="literal">WITH</code>, the order in which the specified updates
+ actually happen is unpredictable. All the statements are executed with
+ the same <em class="firstterm">snapshot</em> (see <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>), so they
+ cannot <span class="quote">“<span class="quote">see</span>”</span> one another's effects on the target tables. This
+ alleviates the effects of the unpredictability of the actual order of row
+ updates, and means that <code class="literal">RETURNING</code> data is the only way to
+ communicate changes between different <code class="literal">WITH</code> sub-statements and
+ the main query. An example of this is that in
+
+</p><pre class="programlisting">
+WITH t AS (
+ UPDATE products SET price = price * 1.05
+ RETURNING *
+)
+SELECT * FROM products;
+</pre><p>
+
+ the outer <code class="command">SELECT</code> would return the original prices before the
+ action of the <code class="command">UPDATE</code>, while in
+
+</p><pre class="programlisting">
+WITH t AS (
+ UPDATE products SET price = price * 1.05
+ RETURNING *
+)
+SELECT * FROM t;
+</pre><p>
+
+ the outer <code class="command">SELECT</code> would return the updated data.
+ </p><p>
+ Trying to update the same row twice in a single statement is not
+ supported. Only one of the modifications takes place, but it is not easy
+ (and sometimes not possible) to reliably predict which one. This also
+ applies to deleting a row that was already updated in the same statement:
+ only the update is performed. Therefore you should generally avoid trying
+ to modify a single row twice in a single statement. In particular avoid
+ writing <code class="literal">WITH</code> sub-statements that could affect the same rows
+ changed by the main statement or a sibling sub-statement. The effects
+ of such a statement will not be predictable.
+ </p><p>
+ At present, any table used as the target of a data-modifying statement in
+ <code class="literal">WITH</code> must not have a conditional rule, nor an <code class="literal">ALSO</code>
+ rule, nor an <code class="literal">INSTEAD</code> rule that expands to multiple statements.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="queries-values.html" title="7.7. VALUES Lists">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="queries.html" title="Chapter 7. Queries">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="datatype.html" title="Chapter 8. Data Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">7.7. <code class="literal">VALUES</code> Lists </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 8. Data Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/queries.html b/doc/src/sgml/html/queries.html
new file mode 100644
index 0000000..88bdb12
--- /dev/null
+++ b/doc/src/sgml/html/queries.html
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 7. Queries</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="dml-returning.html" title="6.4. Returning Data from Modified Rows" /><link rel="next" href="queries-overview.html" title="7.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 7. Queries</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="dml-returning.html" title="6.4. Returning Data from Modified Rows">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="queries-overview.html" title="7.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="QUERIES"><div class="titlepage"><div><div><h2 class="title">Chapter 7. Queries</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="queries-overview.html">7.1. Overview</a></span></dt><dt><span class="sect1"><a href="queries-table-expressions.html">7.2. Table Expressions</a></span></dt><dd><dl><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-FROM">7.2.1. The <code class="literal">FROM</code> Clause</a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-WHERE">7.2.2. The <code class="literal">WHERE</code> Clause</a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-GROUP">7.2.3. The <code class="literal">GROUP BY</code> and <code class="literal">HAVING</code> Clauses</a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-GROUPING-SETS">7.2.4. <code class="literal">GROUPING SETS</code>, <code class="literal">CUBE</code>, and <code class="literal">ROLLUP</code></a></span></dt><dt><span class="sect2"><a href="queries-table-expressions.html#QUERIES-WINDOW">7.2.5. Window Function Processing</a></span></dt></dl></dd><dt><span class="sect1"><a href="queries-select-lists.html">7.3. Select Lists</a></span></dt><dd><dl><dt><span class="sect2"><a href="queries-select-lists.html#QUERIES-SELECT-LIST-ITEMS">7.3.1. Select-List Items</a></span></dt><dt><span class="sect2"><a href="queries-select-lists.html#QUERIES-COLUMN-LABELS">7.3.2. Column Labels</a></span></dt><dt><span class="sect2"><a href="queries-select-lists.html#QUERIES-DISTINCT">7.3.3. <code class="literal">DISTINCT</code></a></span></dt></dl></dd><dt><span class="sect1"><a href="queries-union.html">7.4. Combining Queries (<code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>)</a></span></dt><dt><span class="sect1"><a href="queries-order.html">7.5. Sorting Rows (<code class="literal">ORDER BY</code>)</a></span></dt><dt><span class="sect1"><a href="queries-limit.html">7.6. <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code></a></span></dt><dt><span class="sect1"><a href="queries-values.html">7.7. <code class="literal">VALUES</code> Lists</a></span></dt><dt><span class="sect1"><a href="queries-with.html">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions)</a></span></dt><dd><dl><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-SELECT">7.8.1. <code class="command">SELECT</code> in <code class="literal">WITH</code></a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-RECURSIVE">7.8.2. Recursive Queries</a></span></dt><dt><span class="sect2"><a href="queries-with.html#id-1.5.6.12.7">7.8.3. Common Table Expression Materialization</a></span></dt><dt><span class="sect2"><a href="queries-with.html#QUERIES-WITH-MODIFYING">7.8.4. Data-Modifying Statements in <code class="literal">WITH</code></a></span></dt></dl></dd></dl></div><a id="id-1.5.6.2" class="indexterm"></a><a id="id-1.5.6.3" class="indexterm"></a><p>
+ The previous chapters explained how to create tables, how to fill
+ them with data, and how to manipulate that data. Now we finally
+ discuss how to retrieve the data from the database.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="dml-returning.html" title="6.4. Returning Data from Modified Rows">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="queries-overview.html" title="7.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.4. Returning Data from Modified Rows </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 7.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/query-path.html b/doc/src/sgml/html/query-path.html
new file mode 100644
index 0000000..de8af48
--- /dev/null
+++ b/doc/src/sgml/html/query-path.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>52.1. The Path of a Query</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals" /><link rel="next" href="connect-estab.html" title="52.2. How Connections Are Established" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">52.1. The Path of a Query</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><th width="60%" align="center">Chapter 52. Overview of PostgreSQL Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="connect-estab.html" title="52.2. How Connections Are Established">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERY-PATH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">52.1. The Path of a Query</h2></div></div></div><p>
+ Here we give a short overview of the stages a query has to pass
+ to obtain a result.
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p>
+ A connection from an application program to the <span class="productname">PostgreSQL</span>
+ server has to be established. The application program transmits a
+ query to the server and waits to receive the results sent back by the
+ server.
+ </p></li><li class="step"><p>
+ The <em class="firstterm">parser stage</em> checks the query
+ transmitted by the application
+ program for correct syntax and creates
+ a <em class="firstterm">query tree</em>.
+ </p></li><li class="step"><p>
+ The <em class="firstterm">rewrite system</em> takes
+ the query tree created by the parser stage and looks for
+ any <em class="firstterm">rules</em> (stored in the
+ <em class="firstterm">system catalogs</em>) to apply to
+ the query tree. It performs the
+ transformations given in the <em class="firstterm">rule bodies</em>.
+ </p><p>
+ One application of the rewrite system is in the realization of
+ <em class="firstterm">views</em>.
+ Whenever a query against a view
+ (i.e., a <em class="firstterm">virtual table</em>) is made,
+ the rewrite system rewrites the user's query to
+ a query that accesses the <em class="firstterm">base tables</em> given in
+ the <em class="firstterm">view definition</em> instead.
+ </p></li><li class="step"><p>
+ The <em class="firstterm">planner/optimizer</em> takes
+ the (rewritten) query tree and creates a
+ <em class="firstterm">query plan</em> that will be the input to the
+ <em class="firstterm">executor</em>.
+ </p><p>
+ It does so by first creating all possible <em class="firstterm">paths</em>
+ leading to the same result. For example if there is an index on a
+ relation to be scanned, there are two paths for the
+ scan. One possibility is a simple sequential scan and the other
+ possibility is to use the index. Next the cost for the execution of
+ each path is estimated and the cheapest path is chosen. The cheapest
+ path is expanded into a complete plan that the executor can use.
+ </p></li><li class="step"><p>
+ The executor recursively steps through
+ the <em class="firstterm">plan tree</em> and
+ retrieves rows in the way represented by the plan.
+ The executor makes use of the
+ <em class="firstterm">storage system</em> while scanning
+ relations, performs <em class="firstterm">sorts</em> and <em class="firstterm">joins</em>,
+ evaluates <em class="firstterm">qualifications</em> and finally hands back the rows derived.
+ </p></li></ol></div><p>
+ In the following sections we will cover each of the above listed items
+ in more detail to give a better understanding of <span class="productname">PostgreSQL</span>'s internal
+ control and data structures.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="connect-estab.html" title="52.2. How Connections Are Established">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 52. Overview of PostgreSQL Internals </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 52.2. How Connections Are Established</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/querytree.html b/doc/src/sgml/html/querytree.html
new file mode 100644
index 0000000..13a14ec
--- /dev/null
+++ b/doc/src/sgml/html/querytree.html
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.1. The Query Tree</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules.html" title="Chapter 41. The Rule System" /><link rel="next" href="rules-views.html" title="41.2. Views and the Rule System" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.1. The Query Tree</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules.html" title="Chapter 41. The Rule System">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-views.html" title="41.2. Views and the Rule System">Next</a></td></tr></table><hr /></div><div class="sect1" id="QUERYTREE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.1. The Query Tree</h2></div></div></div><a id="id-1.8.6.6.2" class="indexterm"></a><p>
+ To understand how the rule system works it is necessary to know
+ when it is invoked and what its input and results are.
+</p><p>
+ The rule system is located between the parser and the planner.
+ It takes the output of the parser, one query tree, and the user-defined
+ rewrite rules, which are also
+ query trees with some extra information, and creates zero or more
+ query trees as result. So its input and output are always things
+ the parser itself could have produced and thus, anything it sees
+ is basically representable as an <acronym class="acronym">SQL</acronym> statement.
+</p><p>
+ Now what is a query tree? It is an internal representation of an
+ <acronym class="acronym">SQL</acronym> statement where the single parts that it is
+ built from are stored separately. These query trees can be shown
+ in the server log if you set the configuration parameters
+ <code class="varname">debug_print_parse</code>,
+ <code class="varname">debug_print_rewritten</code>, or
+ <code class="varname">debug_print_plan</code>. The rule actions are also
+ stored as query trees, in the system catalog
+ <code class="structname">pg_rewrite</code>. They are not formatted like
+ the log output, but they contain exactly the same information.
+</p><p>
+ Reading a raw query tree requires some experience. But since
+ <acronym class="acronym">SQL</acronym> representations of query trees are
+ sufficient to understand the rule system, this chapter will not
+ teach how to read them.
+</p><p>
+ When reading the <acronym class="acronym">SQL</acronym> representations of the
+ query trees in this chapter it is necessary to be able to identify
+ the parts the statement is broken into when it is in the query tree
+ structure. The parts of a query tree are
+
+</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ the command type
+ </span></dt><dd><p>
+ This is a simple value telling which command
+ (<code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>) produced
+ the query tree.
+ </p></dd><dt><span class="term">
+ the range table
+ <a id="id-1.8.6.6.7.2.2.1.1" class="indexterm"></a>
+ </span></dt><dd><p>
+ The range table is a list of relations that are used in the query.
+ In a <code class="command">SELECT</code> statement these are the relations given after
+ the <code class="literal">FROM</code> key word.
+ </p><p>
+ Every range table entry identifies a table or view and tells
+ by which name it is called in the other parts of the query.
+ In the query tree, the range table entries are referenced by
+ number rather than by name, so here it doesn't matter if there
+ are duplicate names as it would in an <acronym class="acronym">SQL</acronym>
+ statement. This can happen after the range tables of rules
+ have been merged in. The examples in this chapter will not have
+ this situation.
+ </p></dd><dt><span class="term">
+ the result relation
+ </span></dt><dd><p>
+ This is an index into the range table that identifies the
+ relation where the results of the query go.
+ </p><p>
+ <code class="command">SELECT</code> queries don't have a result
+ relation. (The special case of <code class="command">SELECT INTO</code> is
+ mostly identical to <code class="command">CREATE TABLE</code> followed by
+ <code class="literal">INSERT ... SELECT</code>, and is not discussed
+ separately here.)
+ </p><p>
+ For <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> commands, the result relation is the table
+ (or view!) where the changes are to take effect.
+ </p></dd><dt><span class="term">
+ the target list
+ <a id="id-1.8.6.6.7.2.4.1.1" class="indexterm"></a>
+ </span></dt><dd><p>
+ The target list is a list of expressions that define the
+ result of the query. In the case of a
+ <code class="command">SELECT</code>, these expressions are the ones that
+ build the final output of the query. They correspond to the
+ expressions between the key words <code class="command">SELECT</code>
+ and <code class="command">FROM</code>. (<code class="literal">*</code> is just an
+ abbreviation for all the column names of a relation. It is
+ expanded by the parser into the individual columns, so the
+ rule system never sees it.)
+ </p><p>
+ <code class="command">DELETE</code> commands don't need a normal target list
+ because they don't produce any result. Instead, the planner
+ adds a special <acronym class="acronym">CTID</acronym> entry to the empty target list,
+ to allow the executor to find the row to be deleted.
+ (<acronym class="acronym">CTID</acronym> is added when the result relation is an ordinary
+ table. If it is a view, a whole-row variable is added instead, by
+ the rule system, as described in <a class="xref" href="rules-views.html#RULES-VIEWS-UPDATE" title="41.2.4. Updating a View">Section 41.2.4</a>.)
+ </p><p>
+ For <code class="command">INSERT</code> commands, the target list describes
+ the new rows that should go into the result relation. It consists of the
+ expressions in the <code class="literal">VALUES</code> clause or the ones from the
+ <code class="command">SELECT</code> clause in <code class="literal">INSERT
+ ... SELECT</code>. The first step of the rewrite process adds
+ target list entries for any columns that were not assigned to by
+ the original command but have defaults. Any remaining columns (with
+ neither a given value nor a default) will be filled in by the
+ planner with a constant null expression.
+ </p><p>
+ For <code class="command">UPDATE</code> commands, the target list
+ describes the new rows that should replace the old ones. In the
+ rule system, it contains just the expressions from the <code class="literal">SET
+ column = expression</code> part of the command. The planner will
+ handle missing columns by inserting expressions that copy the values
+ from the old row into the new one. Just as for <code class="command">DELETE</code>,
+ a <acronym class="acronym">CTID</acronym> or whole-row variable is added so that
+ the executor can identify the old row to be updated.
+ </p><p>
+ Every entry in the target list contains an expression that can
+ be a constant value, a variable pointing to a column of one
+ of the relations in the range table, a parameter, or an expression
+ tree made of function calls, constants, variables, operators, etc.
+ </p></dd><dt><span class="term">
+ the qualification
+ </span></dt><dd><p>
+ The query's qualification is an expression much like one of
+ those contained in the target list entries. The result value of
+ this expression is a Boolean that tells whether the operation
+ (<code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, or <code class="command">SELECT</code>) for the
+ final result row should be executed or not. It corresponds to the <code class="literal">WHERE</code> clause
+ of an <acronym class="acronym">SQL</acronym> statement.
+ </p></dd><dt><span class="term">
+ the join tree
+ </span></dt><dd><p>
+ The query's join tree shows the structure of the <code class="literal">FROM</code> clause.
+ For a simple query like <code class="literal">SELECT ... FROM a, b, c</code>, the join tree is just
+ a list of the <code class="literal">FROM</code> items, because we are allowed to join them in
+ any order. But when <code class="literal">JOIN</code> expressions, particularly outer joins,
+ are used, we have to join in the order shown by the joins.
+ In that case, the join tree shows the structure of the <code class="literal">JOIN</code> expressions. The
+ restrictions associated with particular <code class="literal">JOIN</code> clauses (from <code class="literal">ON</code> or
+ <code class="literal">USING</code> expressions) are stored as qualification expressions attached
+ to those join-tree nodes. It turns out to be convenient to store
+ the top-level <code class="literal">WHERE</code> expression as a qualification attached to the
+ top-level join-tree item, too. So really the join tree represents
+ both the <code class="literal">FROM</code> and <code class="literal">WHERE</code> clauses of a <code class="command">SELECT</code>.
+ </p></dd><dt><span class="term">
+ the others
+ </span></dt><dd><p>
+ The other parts of the query tree like the <code class="literal">ORDER BY</code>
+ clause aren't of interest here. The rule system
+ substitutes some entries there while applying rules, but that
+ doesn't have much to do with the fundamentals of the rule
+ system.
+ </p></dd></dl></div><p>
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules.html" title="Chapter 41. The Rule System">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-views.html" title="41.2. Views and the Rule System">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 41. The Rule System </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.2. Views and the Rule System</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rangetypes.html b/doc/src/sgml/html/rangetypes.html
new file mode 100644
index 0000000..fc3e218
--- /dev/null
+++ b/doc/src/sgml/html/rangetypes.html
@@ -0,0 +1,435 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.17. Range Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rowtypes.html" title="8.16. Composite Types" /><link rel="next" href="domains.html" title="8.18. Domain Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.17. Range Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rowtypes.html" title="8.16. Composite Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="domains.html" title="8.18. Domain Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="RANGETYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.17. Range Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-BUILTIN">8.17.1. Built-in Range and Multirange Types</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-EXAMPLES">8.17.2. Examples</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-INCLUSIVITY">8.17.3. Inclusive and Exclusive Bounds</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-INFINITE">8.17.4. Infinite (Unbounded) Ranges</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-IO">8.17.5. Range Input/Output</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-CONSTRUCT">8.17.6. Constructing Ranges and Multiranges</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-DISCRETE">8.17.7. Discrete Range Types</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-DEFINING">8.17.8. Defining New Range Types</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-INDEXING">8.17.9. Indexing</a></span></dt><dt><span class="sect2"><a href="rangetypes.html#RANGETYPES-CONSTRAINT">8.17.10. Constraints on Ranges</a></span></dt></dl></div><a id="id-1.5.7.25.2" class="indexterm"></a><a id="id-1.5.7.25.3" class="indexterm"></a><p>
+ Range types are data types representing a range of values of some
+ element type (called the range's <em class="firstterm">subtype</em>).
+ For instance, ranges
+ of <code class="type">timestamp</code> might be used to represent the ranges of
+ time that a meeting room is reserved. In this case the data type
+ is <code class="type">tsrange</code> (short for <span class="quote">“<span class="quote">timestamp range</span>”</span>),
+ and <code class="type">timestamp</code> is the subtype. The subtype must have
+ a total order so that it is well-defined whether element values are
+ within, before, or after a range of values.
+ </p><p>
+ Range types are useful because they represent many element values in a
+ single range value, and because concepts such as overlapping ranges can
+ be expressed clearly. The use of time and date ranges for scheduling
+ purposes is the clearest example; but price ranges, measurement
+ ranges from an instrument, and so forth can also be useful.
+ </p><p>
+ Every range type has a corresponding multirange type. A multirange is
+ an ordered list of non-contiguous, non-empty, non-null ranges. Most
+ range operators also work on multiranges, and they have a few functions
+ of their own.
+ </p><div class="sect2" id="RANGETYPES-BUILTIN"><div class="titlepage"><div><div><h3 class="title">8.17.1. Built-in Range and Multirange Types</h3></div></div></div><p>
+ PostgreSQL comes with the following built-in range types:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="type">int4range</code> — Range of <code class="type">integer</code>,
+ <code class="type">int4multirange</code> — corresponding Multirange
+ </p></li><li class="listitem"><p>
+ <code class="type">int8range</code> — Range of <code class="type">bigint</code>,
+ <code class="type">int8multirange</code> — corresponding Multirange
+ </p></li><li class="listitem"><p>
+ <code class="type">numrange</code> — Range of <code class="type">numeric</code>,
+ <code class="type">nummultirange</code> — corresponding Multirange
+ </p></li><li class="listitem"><p>
+ <code class="type">tsrange</code> — Range of <code class="type">timestamp without time zone</code>,
+ <code class="type">tsmultirange</code> — corresponding Multirange
+ </p></li><li class="listitem"><p>
+ <code class="type">tstzrange</code> — Range of <code class="type">timestamp with time zone</code>,
+ <code class="type">tstzmultirange</code> — corresponding Multirange
+ </p></li><li class="listitem"><p>
+ <code class="type">daterange</code> — Range of <code class="type">date</code>,
+ <code class="type">datemultirange</code> — corresponding Multirange
+ </p></li></ul></div><p>
+ In addition, you can define your own range types;
+ see <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> for more information.
+ </p></div><div class="sect2" id="RANGETYPES-EXAMPLES"><div class="titlepage"><div><div><h3 class="title">8.17.2. Examples</h3></div></div></div><p>
+</p><pre class="programlisting">
+CREATE TABLE reservation (room int, during tsrange);
+INSERT INTO reservation VALUES
+ (1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
+
+-- Containment
+SELECT int4range(10, 20) @&gt; 3;
+
+-- Overlaps
+SELECT numrange(11.1, 22.2) &amp;&amp; numrange(20.0, 30.0);
+
+-- Extract the upper bound
+SELECT upper(int8range(15, 25));
+
+-- Compute the intersection
+SELECT int4range(10, 20) * int4range(15, 25);
+
+-- Is the range empty?
+SELECT isempty(numrange(1, 5));
+</pre><p>
+
+ See <a class="xref" href="functions-range.html#RANGE-OPERATORS-TABLE" title="Table 9.54. Range Operators">Table 9.54</a>
+ and <a class="xref" href="functions-range.html#RANGE-FUNCTIONS-TABLE" title="Table 9.56. Range Functions">Table 9.56</a> for complete lists of
+ operators and functions on range types.
+ </p></div><div class="sect2" id="RANGETYPES-INCLUSIVITY"><div class="titlepage"><div><div><h3 class="title">8.17.3. Inclusive and Exclusive Bounds</h3></div></div></div><p>
+ Every non-empty range has two bounds, the lower bound and the upper
+ bound. All points between these values are included in the range. An
+ inclusive bound means that the boundary point itself is included in
+ the range as well, while an exclusive bound means that the boundary
+ point is not included in the range.
+ </p><p>
+ In the text form of a range, an inclusive lower bound is represented by
+ <span class="quote">“<span class="quote"><code class="literal">[</code></span>”</span> while an exclusive lower bound is
+ represented by <span class="quote">“<span class="quote"><code class="literal">(</code></span>”</span>. Likewise, an inclusive upper bound is represented by
+ <span class="quote">“<span class="quote"><code class="literal">]</code></span>”</span>, while an exclusive upper bound is
+ represented by <span class="quote">“<span class="quote"><code class="literal">)</code></span>”</span>.
+ (See <a class="xref" href="rangetypes.html#RANGETYPES-IO" title="8.17.5. Range Input/Output">Section 8.17.5</a> for more details.)
+ </p><p>
+ The functions <code class="literal">lower_inc</code>
+ and <code class="literal">upper_inc</code> test the inclusivity of the lower
+ and upper bounds of a range value, respectively.
+ </p></div><div class="sect2" id="RANGETYPES-INFINITE"><div class="titlepage"><div><div><h3 class="title">8.17.4. Infinite (Unbounded) Ranges</h3></div></div></div><p>
+ The lower bound of a range can be omitted, meaning that all
+ values less than the upper bound are included in the range, e.g.,
+ <code class="literal">(,3]</code>. Likewise, if the upper bound of the range
+ is omitted, then all values greater than the lower bound are included
+ in the range. If both lower and upper bounds are omitted, all values
+ of the element type are considered to be in the range. Specifying a
+ missing bound as inclusive is automatically converted to exclusive,
+ e.g., <code class="literal">[,]</code> is converted to <code class="literal">(,)</code>.
+ You can think of these missing values as +/-infinity, but they are
+ special range type values and are considered to be beyond any range
+ element type's +/-infinity values.
+ </p><p>
+ Element types that have the notion of <span class="quote">“<span class="quote">infinity</span>”</span> can
+ use them as explicit bound values. For example, with timestamp
+ ranges, <code class="literal">[today,infinity)</code> excludes the special
+ <code class="type">timestamp</code> value <code class="literal">infinity</code>,
+ while <code class="literal">[today,infinity]</code> include it, as does
+ <code class="literal">[today,)</code> and <code class="literal">[today,]</code>.
+ </p><p>
+ The functions <code class="literal">lower_inf</code>
+ and <code class="literal">upper_inf</code> test for infinite lower
+ and upper bounds of a range, respectively.
+ </p></div><div class="sect2" id="RANGETYPES-IO"><div class="titlepage"><div><div><h3 class="title">8.17.5. Range Input/Output</h3></div></div></div><p>
+ The input for a range value must follow one of the following patterns:
+</p><pre class="synopsis">
+(<em class="replaceable"><code>lower-bound</code></em>,<em class="replaceable"><code>upper-bound</code></em>)
+(<em class="replaceable"><code>lower-bound</code></em>,<em class="replaceable"><code>upper-bound</code></em>]
+[<em class="replaceable"><code>lower-bound</code></em>,<em class="replaceable"><code>upper-bound</code></em>)
+[<em class="replaceable"><code>lower-bound</code></em>,<em class="replaceable"><code>upper-bound</code></em>]
+empty
+</pre><p>
+ The parentheses or brackets indicate whether the lower and upper bounds
+ are exclusive or inclusive, as described previously.
+ Notice that the final pattern is <code class="literal">empty</code>, which
+ represents an empty range (a range that contains no points).
+ </p><p>
+ The <em class="replaceable"><code>lower-bound</code></em> may be either a string
+ that is valid input for the subtype, or empty to indicate no
+ lower bound. Likewise, <em class="replaceable"><code>upper-bound</code></em> may be
+ either a string that is valid input for the subtype, or empty to
+ indicate no upper bound.
+ </p><p>
+ Each bound value can be quoted using <code class="literal">"</code> (double quote)
+ characters. This is necessary if the bound value contains parentheses,
+ brackets, commas, double quotes, or backslashes, since these characters
+ would otherwise be taken as part of the range syntax. To put a double
+ quote or backslash in a quoted bound value, precede it with a
+ backslash. (Also, a pair of double quotes within a double-quoted bound
+ value is taken to represent a double quote character, analogously to the
+ rules for single quotes in SQL literal strings.) Alternatively, you can
+ avoid quoting and use backslash-escaping to protect all data characters
+ that would otherwise be taken as range syntax. Also, to write a bound
+ value that is an empty string, write <code class="literal">""</code>, since writing
+ nothing means an infinite bound.
+ </p><p>
+ Whitespace is allowed before and after the range value, but any whitespace
+ between the parentheses or brackets is taken as part of the lower or upper
+ bound value. (Depending on the element type, it might or might not be
+ significant.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ These rules are very similar to those for writing field values in
+ composite-type literals. See <a class="xref" href="rowtypes.html#ROWTYPES-IO-SYNTAX" title="8.16.6. Composite Type Input and Output Syntax">Section 8.16.6</a> for
+ additional commentary.
+ </p></div><p>
+ Examples:
+</p><pre class="programlisting">
+-- includes 3, does not include 7, and does include all points in between
+SELECT '[3,7)'::int4range;
+
+-- does not include either 3 or 7, but includes all points in between
+SELECT '(3,7)'::int4range;
+
+-- includes only the single point 4
+SELECT '[4,4]'::int4range;
+
+-- includes no points (and will be normalized to 'empty')
+SELECT '[4,4)'::int4range;
+</pre><p>
+ </p><p>
+ The input for a multirange is curly brackets (<code class="literal">{</code> and
+ <code class="literal">}</code>) containing zero or more valid ranges,
+ separated by commas. Whitespace is permitted around the brackets and
+ commas. This is intended to be reminiscent of array syntax, although
+ multiranges are much simpler: they have just one dimension and there is
+ no need to quote their contents. (The bounds of their ranges may be
+ quoted as above however.)
+ </p><p>
+ Examples:
+</p><pre class="programlisting">
+SELECT '{}'::int4multirange;
+SELECT '{[3,7)}'::int4multirange;
+SELECT '{[3,7), [8,9)}'::int4multirange;
+</pre><p>
+ </p></div><div class="sect2" id="RANGETYPES-CONSTRUCT"><div class="titlepage"><div><div><h3 class="title">8.17.6. Constructing Ranges and Multiranges</h3></div></div></div><p>
+ Each range type has a constructor function with the same name as the range
+ type. Using the constructor function is frequently more convenient than
+ writing a range literal constant, since it avoids the need for extra
+ quoting of the bound values. The constructor function
+ accepts two or three arguments. The two-argument form constructs a range
+ in standard form (lower bound inclusive, upper bound exclusive), while
+ the three-argument form constructs a range with bounds of the form
+ specified by the third argument.
+ The third argument must be one of the strings
+ <span class="quote">“<span class="quote"><code class="literal">()</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal">(]</code></span>”</span>,
+ <span class="quote">“<span class="quote"><code class="literal">[)</code></span>”</span>, or
+ <span class="quote">“<span class="quote"><code class="literal">[]</code></span>”</span>.
+ For example:
+
+</p><pre class="programlisting">
+-- The full form is: lower bound, upper bound, and text argument indicating
+-- inclusivity/exclusivity of bounds.
+SELECT numrange(1.0, 14.0, '(]');
+
+-- If the third argument is omitted, '[)' is assumed.
+SELECT numrange(1.0, 14.0);
+
+-- Although '(]' is specified here, on display the value will be converted to
+-- canonical form, since int8range is a discrete range type (see below).
+SELECT int8range(1, 14, '(]');
+
+-- Using NULL for either bound causes the range to be unbounded on that side.
+SELECT numrange(NULL, 2.2);
+</pre><p>
+ </p><p>
+ Each range type also has a multirange constructor with the same name as the
+ multirange type. The constructor function takes zero or more arguments
+ which are all ranges of the appropriate type.
+ For example:
+
+</p><pre class="programlisting">
+SELECT nummultirange();
+SELECT nummultirange(numrange(1.0, 14.0));
+SELECT nummultirange(numrange(1.0, 14.0), numrange(20.0, 25.0));
+</pre><p>
+ </p></div><div class="sect2" id="RANGETYPES-DISCRETE"><div class="titlepage"><div><div><h3 class="title">8.17.7. Discrete Range Types</h3></div></div></div><p>
+ A discrete range is one whose element type has a well-defined
+ <span class="quote">“<span class="quote">step</span>”</span>, such as <code class="type">integer</code> or <code class="type">date</code>.
+ In these types two elements can be said to be adjacent, when there are
+ no valid values between them. This contrasts with continuous ranges,
+ where it's always (or almost always) possible to identify other element
+ values between two given values. For example, a range over the
+ <code class="type">numeric</code> type is continuous, as is a range over <code class="type">timestamp</code>.
+ (Even though <code class="type">timestamp</code> has limited precision, and so could
+ theoretically be treated as discrete, it's better to consider it continuous
+ since the step size is normally not of interest.)
+ </p><p>
+ Another way to think about a discrete range type is that there is a clear
+ idea of a <span class="quote">“<span class="quote">next</span>”</span> or <span class="quote">“<span class="quote">previous</span>”</span> value for each element value.
+ Knowing that, it is possible to convert between inclusive and exclusive
+ representations of a range's bounds, by choosing the next or previous
+ element value instead of the one originally given.
+ For example, in an integer range type <code class="literal">[4,8]</code> and
+ <code class="literal">(3,9)</code> denote the same set of values; but this would not be so
+ for a range over numeric.
+ </p><p>
+ A discrete range type should have a <em class="firstterm">canonicalization</em>
+ function that is aware of the desired step size for the element type.
+ The canonicalization function is charged with converting equivalent values
+ of the range type to have identical representations, in particular
+ consistently inclusive or exclusive bounds.
+ If a canonicalization function is not specified, then ranges with different
+ formatting will always be treated as unequal, even though they might
+ represent the same set of values in reality.
+ </p><p>
+ The built-in range types <code class="type">int4range</code>, <code class="type">int8range</code>,
+ and <code class="type">daterange</code> all use a canonical form that includes
+ the lower bound and excludes the upper bound; that is,
+ <code class="literal">[)</code>. User-defined range types can use other conventions,
+ however.
+ </p></div><div class="sect2" id="RANGETYPES-DEFINING"><div class="titlepage"><div><div><h3 class="title">8.17.8. Defining New Range Types</h3></div></div></div><p>
+ Users can define their own range types. The most common reason to do
+ this is to use ranges over subtypes not provided among the built-in
+ range types.
+ For example, to define a new range type of subtype <code class="type">float8</code>:
+
+</p><pre class="programlisting">
+CREATE TYPE floatrange AS RANGE (
+ subtype = float8,
+ subtype_diff = float8mi
+);
+
+SELECT '[1.234, 5.678]'::floatrange;
+</pre><p>
+
+ Because <code class="type">float8</code> has no meaningful
+ <span class="quote">“<span class="quote">step</span>”</span>, we do not define a canonicalization
+ function in this example.
+ </p><p>
+ When you define your own range you automatically get a corresponding
+ multirange type.
+ </p><p>
+ Defining your own range type also allows you to specify a different
+ subtype B-tree operator class or collation to use, so as to change the sort
+ ordering that determines which values fall into a given range.
+ </p><p>
+ If the subtype is considered to have discrete rather than continuous
+ values, the <code class="command">CREATE TYPE</code> command should specify a
+ <code class="literal">canonical</code> function.
+ The canonicalization function takes an input range value, and must return
+ an equivalent range value that may have different bounds and formatting.
+ The canonical output for two ranges that represent the same set of values,
+ for example the integer ranges <code class="literal">[1, 7]</code> and <code class="literal">[1,
+ 8)</code>, must be identical. It doesn't matter which representation
+ you choose to be the canonical one, so long as two equivalent values with
+ different formattings are always mapped to the same value with the same
+ formatting. In addition to adjusting the inclusive/exclusive bounds
+ format, a canonicalization function might round off boundary values, in
+ case the desired step size is larger than what the subtype is capable of
+ storing. For instance, a range type over <code class="type">timestamp</code> could be
+ defined to have a step size of an hour, in which case the canonicalization
+ function would need to round off bounds that weren't a multiple of an hour,
+ or perhaps throw an error instead.
+ </p><p>
+ In addition, any range type that is meant to be used with GiST or SP-GiST
+ indexes should define a subtype difference, or <code class="literal">subtype_diff</code>,
+ function. (The index will still work without <code class="literal">subtype_diff</code>,
+ but it is likely to be considerably less efficient than if a difference
+ function is provided.) The subtype difference function takes two input
+ values of the subtype, and returns their difference
+ (i.e., <em class="replaceable"><code>X</code></em> minus <em class="replaceable"><code>Y</code></em>) represented as
+ a <code class="type">float8</code> value. In our example above, the
+ function <code class="function">float8mi</code> that underlies the regular <code class="type">float8</code>
+ minus operator can be used; but for any other subtype, some type
+ conversion would be necessary. Some creative thought about how to
+ represent differences as numbers might be needed, too. To the greatest
+ extent possible, the <code class="literal">subtype_diff</code> function should agree with
+ the sort ordering implied by the selected operator class and collation;
+ that is, its result should be positive whenever its first argument is
+ greater than its second according to the sort ordering.
+ </p><p>
+ A less-oversimplified example of a <code class="literal">subtype_diff</code> function is:
+ </p><pre class="programlisting">
+CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS
+'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;
+
+CREATE TYPE timerange AS RANGE (
+ subtype = time,
+ subtype_diff = time_subtype_diff
+);
+
+SELECT '[11:10, 23:00]'::timerange;
+</pre><p>
+ See <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> for more information about creating
+ range types.
+ </p></div><div class="sect2" id="RANGETYPES-INDEXING"><div class="titlepage"><div><div><h3 class="title">8.17.9. Indexing</h3></div></div></div><a id="id-1.5.7.25.15.2" class="indexterm"></a><p>
+ GiST and SP-GiST indexes can be created for table columns of range types.
+ GiST indexes can be also created for table columns of multirange types.
+ For instance, to create a GiST index:
+</p><pre class="programlisting">
+CREATE INDEX reservation_idx ON reservation USING GIST (during);
+</pre><p>
+ A GiST or SP-GiST index on ranges can accelerate queries involving these
+ range operators:
+ <code class="literal">=</code>,
+ <code class="literal">&amp;&amp;</code>,
+ <code class="literal">&lt;@</code>,
+ <code class="literal">@&gt;</code>,
+ <code class="literal">&lt;&lt;</code>,
+ <code class="literal">&gt;&gt;</code>,
+ <code class="literal">-|-</code>,
+ <code class="literal">&amp;&lt;</code>, and
+ <code class="literal">&amp;&gt;</code>.
+ A GiST index on multiranges can accelerate queries involving the same
+ set of multirange operators.
+ A GiST index on ranges and GiST index on multiranges can also accelerate
+ queries involving these cross-type range to multirange and multirange to
+ range operators correspondingly:
+ <code class="literal">&amp;&amp;</code>,
+ <code class="literal">&lt;@</code>,
+ <code class="literal">@&gt;</code>,
+ <code class="literal">&lt;&lt;</code>,
+ <code class="literal">&gt;&gt;</code>,
+ <code class="literal">-|-</code>,
+ <code class="literal">&amp;&lt;</code>, and
+ <code class="literal">&amp;&gt;</code>.
+ See <a class="xref" href="functions-range.html#RANGE-OPERATORS-TABLE" title="Table 9.54. Range Operators">Table 9.54</a> for more information.
+ </p><p>
+ In addition, B-tree and hash indexes can be created for table columns of
+ range types. For these index types, basically the only useful range
+ operation is equality. There is a B-tree sort ordering defined for range
+ values, with corresponding <code class="literal">&lt;</code> and <code class="literal">&gt;</code> operators,
+ but the ordering is rather arbitrary and not usually useful in the real
+ world. Range types' B-tree and hash support is primarily meant to
+ allow sorting and hashing internally in queries, rather than creation of
+ actual indexes.
+ </p></div><div class="sect2" id="RANGETYPES-CONSTRAINT"><div class="titlepage"><div><div><h3 class="title">8.17.10. Constraints on Ranges</h3></div></div></div><a id="id-1.5.7.25.16.2" class="indexterm"></a><p>
+ While <code class="literal">UNIQUE</code> is a natural constraint for scalar
+ values, it is usually unsuitable for range types. Instead, an
+ exclusion constraint is often more appropriate
+ (see <a class="link" href="sql-createtable.html#SQL-CREATETABLE-EXCLUDE">CREATE TABLE
+ ... CONSTRAINT ... EXCLUDE</a>). Exclusion constraints allow the
+ specification of constraints such as <span class="quote">“<span class="quote">non-overlapping</span>”</span> on a
+ range type. For example:
+
+</p><pre class="programlisting">
+CREATE TABLE reservation (
+ during tsrange,
+ EXCLUDE USING GIST (during WITH &amp;&amp;)
+);
+</pre><p>
+
+ That constraint will prevent any overlapping values from existing
+ in the table at the same time:
+
+</p><pre class="programlisting">
+INSERT INTO reservation VALUES
+ ('[2010-01-01 11:30, 2010-01-01 15:00)');
+INSERT 0 1
+
+INSERT INTO reservation VALUES
+ ('[2010-01-01 14:45, 2010-01-01 15:45)');
+ERROR: conflicting key value violates exclusion constraint "reservation_during_excl"
+DETAIL: Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts
+with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")).
+</pre><p>
+ </p><p>
+ You can use the <a class="link" href="btree-gist.html" title="F.9. btree_gist"><code class="literal">btree_gist</code></a>
+ extension to define exclusion constraints on plain scalar data types, which
+ can then be combined with range exclusions for maximum flexibility. For
+ example, after <code class="literal">btree_gist</code> is installed, the following
+ constraint will reject overlapping ranges only if the meeting room numbers
+ are equal:
+
+</p><pre class="programlisting">
+CREATE EXTENSION btree_gist;
+CREATE TABLE room_reservation (
+ room text,
+ during tsrange,
+ EXCLUDE USING GIST (room WITH =, during WITH &amp;&amp;)
+);
+
+INSERT INTO room_reservation VALUES
+ ('123A', '[2010-01-01 14:00, 2010-01-01 15:00)');
+INSERT 0 1
+
+INSERT INTO room_reservation VALUES
+ ('123A', '[2010-01-01 14:30, 2010-01-01 15:30)');
+ERROR: conflicting key value violates exclusion constraint "room_reservation_room_during_excl"
+DETAIL: Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts
+with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")).
+
+INSERT INTO room_reservation VALUES
+ ('123B', '[2010-01-01 14:30, 2010-01-01 15:30)');
+INSERT 0 1
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rowtypes.html" title="8.16. Composite Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="domains.html" title="8.18. Domain Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.16. Composite Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.18. Domain Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/recovery-config.html b/doc/src/sgml/html/recovery-config.html
new file mode 100644
index 0000000..fd40408
--- /dev/null
+++ b/doc/src/sgml/html/recovery-config.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>O.1. recovery.conf file merged into postgresql.conf</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features" /><link rel="next" href="default-roles.html" title="O.2. Default Roles Renamed to Predefined Roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">O.1. <code class="filename">recovery.conf</code> file merged into <code class="filename">postgresql.conf</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><th width="60%" align="center">Appendix O. Obsolete or Renamed Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="default-roles.html" title="O.2. Default Roles Renamed to Predefined Roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="RECOVERY-CONFIG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">O.1. <code class="filename">recovery.conf</code> file merged into <code class="filename">postgresql.conf</code></h2></div></div></div><a id="id-1.11.16.3.2" class="indexterm"></a><p>
+ PostgreSQL 11 and below used a configuration file named
+ <code class="filename">recovery.conf</code>
+ <a id="id-1.11.16.3.3.2" class="indexterm"></a>
+ to manage replicas and standbys. Support for this file was removed in PostgreSQL 12. See
+ <a class="link" href="release-prior.html" title="E.6. Prior Releases">the release notes for PostgreSQL 12</a> for details
+ on this change.
+ </p><p>
+ On PostgreSQL 12 and above,
+ <a class="link" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">archive recovery, streaming replication, and PITR</a>
+ are configured using
+ <a class="link" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY" title="20.6.3. Standby Servers">normal server configuration parameters</a>.
+ These are set in <code class="filename">postgresql.conf</code> or via
+ <a class="link" href="sql-altersystem.html" title="ALTER SYSTEM">ALTER SYSTEM</a>
+ like any other parameter.
+ </p><p>
+ The server will not start if a <code class="filename">recovery.conf</code> exists.
+ </p><p>
+ The
+ <code class="literal">trigger_file</code>
+ <a id="id-1.11.16.3.6.2" class="indexterm"></a>
+ setting has been renamed to
+ <a class="xref" href="runtime-config-replication.html#GUC-PROMOTE-TRIGGER-FILE">promote_trigger_file</a>.
+ </p><p>
+ The
+ <code class="literal">standby_mode</code>
+ <a id="id-1.11.16.3.7.2" class="indexterm"></a>
+ setting has been removed. A <code class="filename">standby.signal</code> file in the data directory
+ is used instead. See <a class="xref" href="warm-standby.html#STANDBY-SERVER-OPERATION" title="27.2.2. Standby Server Operation">Standby Server Operation</a> for details.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendix-obsolete.html" title="Appendix O. Obsolete or Renamed Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="default-roles.html" title="O.2. Default Roles Renamed to Predefined Roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix O. Obsolete or Renamed Features </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> O.2. Default Roles Renamed to Predefined Roles</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/reference-client.html b/doc/src/sgml/html/reference-client.html
new file mode 100644
index 0000000..323832a
--- /dev/null
+++ b/doc/src/sgml/html/reference-client.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PostgreSQL Client Applications</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-values.html" title="VALUES" /><link rel="next" href="app-clusterdb.html" title="clusterdb" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">PostgreSQL Client Applications</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-values.html" title="VALUES">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference.html" title="Part VI. Reference">Up</a></td><th width="60%" align="center">Part VI. Reference</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-clusterdb.html" title="clusterdb">Next</a></td></tr></table><hr /></div><div class="reference" id="REFERENCE-CLIENT"><div class="titlepage"><div><div><h1 class="title">PostgreSQL Client Applications</h1></div></div><hr /></div><div class="partintro" id="id-1.9.4.2"><div></div><p>
+ This part contains reference information for
+ <span class="productname">PostgreSQL</span> client applications and
+ utilities. Not all of these commands are of general utility; some
+ might require special privileges. The common feature of these
+ applications is that they can be run on any host, independent of
+ where the database server resides.
+ </p><p>
+ When specified on the command line, user and database names have
+ their case preserved — the presence of spaces or special
+ characters might require quoting. Table names and other identifiers
+ do not have their case preserved, except where documented, and
+ might require quoting.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="refentrytitle"><a href="app-clusterdb.html"><span class="application">clusterdb</span></a></span><span class="refpurpose"> — cluster a <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-createdb.html"><span class="application">createdb</span></a></span><span class="refpurpose"> — create a new <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-createuser.html"><span class="application">createuser</span></a></span><span class="refpurpose"> — define a new <span class="productname">PostgreSQL</span> user account</span></dt><dt><span class="refentrytitle"><a href="app-dropdb.html"><span class="application">dropdb</span></a></span><span class="refpurpose"> — remove a <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-dropuser.html"><span class="application">dropuser</span></a></span><span class="refpurpose"> — remove a <span class="productname">PostgreSQL</span> user account</span></dt><dt><span class="refentrytitle"><a href="app-ecpg.html"><span class="application">ecpg</span></a></span><span class="refpurpose"> — embedded SQL C preprocessor</span></dt><dt><span class="refentrytitle"><a href="app-pgamcheck.html"><span class="application">pg_amcheck</span></a></span><span class="refpurpose"> — checks for corruption in one or more
+ <span class="productname">PostgreSQL</span> databases</span></dt><dt><span class="refentrytitle"><a href="app-pgbasebackup.html"><span class="application">pg_basebackup</span></a></span><span class="refpurpose"> — take a base backup of a <span class="productname">PostgreSQL</span> cluster</span></dt><dt><span class="refentrytitle"><a href="pgbench.html"><span class="application">pgbench</span></a></span><span class="refpurpose"> — run a benchmark test on <span class="productname">PostgreSQL</span></span></dt><dt><span class="refentrytitle"><a href="app-pgconfig.html"><span class="application">pg_config</span></a></span><span class="refpurpose"> — retrieve information about the installed version of <span class="productname">PostgreSQL</span></span></dt><dt><span class="refentrytitle"><a href="app-pgdump.html"><span class="application">pg_dump</span></a></span><span class="refpurpose"> —
+ extract a <span class="productname">PostgreSQL</span> database into a script file or other archive file
+ </span></dt><dt><span class="refentrytitle"><a href="app-pg-dumpall.html"><span class="application">pg_dumpall</span></a></span><span class="refpurpose"> — extract a <span class="productname">PostgreSQL</span> database cluster into a script file</span></dt><dt><span class="refentrytitle"><a href="app-pg-isready.html"><span class="application">pg_isready</span></a></span><span class="refpurpose"> — check the connection status of a <span class="productname">PostgreSQL</span> server</span></dt><dt><span class="refentrytitle"><a href="app-pgreceivewal.html"><span class="application">pg_receivewal</span></a></span><span class="refpurpose"> — stream write-ahead logs from a <span class="productname">PostgreSQL</span> server</span></dt><dt><span class="refentrytitle"><a href="app-pgrecvlogical.html"><span class="application">pg_recvlogical</span></a></span><span class="refpurpose"> — control <span class="productname">PostgreSQL</span> logical decoding streams</span></dt><dt><span class="refentrytitle"><a href="app-pgrestore.html"><span class="application">pg_restore</span></a></span><span class="refpurpose"> —
+ restore a <span class="productname">PostgreSQL</span> database from an
+ archive file created by <span class="application">pg_dump</span>
+ </span></dt><dt><span class="refentrytitle"><a href="app-pgverifybackup.html"><span class="application">pg_verifybackup</span></a></span><span class="refpurpose"> — verify the integrity of a base backup of a
+ <span class="productname">PostgreSQL</span> cluster</span></dt><dt><span class="refentrytitle"><a href="app-psql.html"><span class="application">psql</span></a></span><span class="refpurpose"> —
+ <span class="productname">PostgreSQL</span> interactive terminal
+ </span></dt><dt><span class="refentrytitle"><a href="app-reindexdb.html"><span class="application">reindexdb</span></a></span><span class="refpurpose"> — reindex a <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-vacuumdb.html"><span class="application">vacuumdb</span></a></span><span class="refpurpose"> — garbage-collect and analyze a <span class="productname">PostgreSQL</span> database</span></dt></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-values.html" title="VALUES">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference.html" title="Part VI. Reference">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-clusterdb.html" title="clusterdb">Next</a></td></tr><tr><td width="40%" align="left" valign="top">VALUES </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">clusterdb</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/reference-server.html b/doc/src/sgml/html/reference-server.html
new file mode 100644
index 0000000..abdb19e
--- /dev/null
+++ b/doc/src/sgml/html/reference-server.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PostgreSQL Server Applications</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="app-vacuumdb.html" title="vacuumdb" /><link rel="next" href="app-initdb.html" title="initdb" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">PostgreSQL Server Applications</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="app-vacuumdb.html" title="vacuumdb">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference.html" title="Part VI. Reference">Up</a></td><th width="60%" align="center">Part VI. Reference</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="app-initdb.html" title="initdb">Next</a></td></tr></table><hr /></div><div class="reference" id="REFERENCE-SERVER"><div class="titlepage"><div><div><h1 class="title">PostgreSQL Server Applications</h1></div></div><hr /></div><div class="partintro" id="id-1.9.5.2"><div></div><p>
+ This part contains reference information for
+ <span class="productname">PostgreSQL</span> server applications and
+ support utilities. These commands can only be run usefully on the
+ host where the database server resides. Other utility programs
+ are listed in <a class="xref" href="reference-client.html" title="PostgreSQL Client Applications">PostgreSQL Client Applications</a>.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="refentrytitle"><a href="app-initdb.html"><span class="application">initdb</span></a></span><span class="refpurpose"> — create a new <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="pgarchivecleanup.html"><span class="application">pg_archivecleanup</span></a></span><span class="refpurpose"> — clean up <span class="productname">PostgreSQL</span> WAL archive files</span></dt><dt><span class="refentrytitle"><a href="app-pgchecksums.html"><span class="application">pg_checksums</span></a></span><span class="refpurpose"> — enable, disable or check data checksums in a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-pgcontroldata.html"><span class="application">pg_controldata</span></a></span><span class="refpurpose"> — display control information of a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-pg-ctl.html"><span class="application">pg_ctl</span></a></span><span class="refpurpose"> — initialize, start, stop, or control a <span class="productname">PostgreSQL</span> server</span></dt><dt><span class="refentrytitle"><a href="app-pgresetwal.html"><span class="application">pg_resetwal</span></a></span><span class="refpurpose"> — reset the write-ahead log and other control information of a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-pgrewind.html"><span class="application">pg_rewind</span></a></span><span class="refpurpose"> — synchronize a <span class="productname">PostgreSQL</span> data directory with another data directory that was forked from it</span></dt><dt><span class="refentrytitle"><a href="pgtestfsync.html"><span class="application">pg_test_fsync</span></a></span><span class="refpurpose"> — determine fastest <code class="varname">wal_sync_method</code> for <span class="productname">PostgreSQL</span></span></dt><dt><span class="refentrytitle"><a href="pgtesttiming.html"><span class="application">pg_test_timing</span></a></span><span class="refpurpose"> — measure timing overhead</span></dt><dt><span class="refentrytitle"><a href="pgupgrade.html"><span class="application">pg_upgrade</span></a></span><span class="refpurpose"> — upgrade a <span class="productname">PostgreSQL</span> server instance</span></dt><dt><span class="refentrytitle"><a href="pgwaldump.html"><span class="application">pg_waldump</span></a></span><span class="refpurpose"> — display a human-readable rendering of the write-ahead log of a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-postgres.html"><span class="application">postgres</span></a></span><span class="refpurpose"> — <span class="productname">PostgreSQL</span> database server</span></dt><dt><span class="refentrytitle"><a href="app-postmaster.html"><span class="application">postmaster</span></a></span><span class="refpurpose"> — <span class="productname">PostgreSQL</span> database server</span></dt></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="app-vacuumdb.html" title="vacuumdb">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference.html" title="Part VI. Reference">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="app-initdb.html" title="initdb">Next</a></td></tr><tr><td width="40%" align="left" valign="top"><span class="application">vacuumdb</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> <span class="application">initdb</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/reference.html b/doc/src/sgml/html/reference.html
new file mode 100644
index 0000000..0736c10
--- /dev/null
+++ b/doc/src/sgml/html/reference.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part VI. Reference</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks" /><link rel="next" href="sql-commands.html" title="SQL Commands" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part VI. Reference</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-commands.html" title="SQL Commands">Next</a></td></tr></table><hr /></div><div class="part" id="REFERENCE"><div class="titlepage"><div><div><h1 class="title">Part VI. Reference</h1></div></div></div><div class="partintro" id="id-1.9.2"><div></div><p>
+ The entries in this Reference are meant to provide in reasonable
+ length an authoritative, complete, and formal summary about their
+ respective subjects. More information about the use of
+ <span class="productname">PostgreSQL</span>, in narrative, tutorial, or
+ example form, can be found in other parts of this book. See the
+ cross-references listed on each reference page.
+ </p><p>
+ The reference entries are also available as traditional
+ <span class="quote">“<span class="quote">man</span>”</span> pages.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="reference"><a href="sql-commands.html">I. SQL Commands</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="sql-abort.html">ABORT</a></span><span class="refpurpose"> — abort the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-alteraggregate.html">ALTER AGGREGATE</a></span><span class="refpurpose"> — change the definition of an aggregate function</span></dt><dt><span class="refentrytitle"><a href="sql-altercollation.html">ALTER COLLATION</a></span><span class="refpurpose"> — change the definition of a collation</span></dt><dt><span class="refentrytitle"><a href="sql-alterconversion.html">ALTER CONVERSION</a></span><span class="refpurpose"> — change the definition of a conversion</span></dt><dt><span class="refentrytitle"><a href="sql-alterdatabase.html">ALTER DATABASE</a></span><span class="refpurpose"> — change a database</span></dt><dt><span class="refentrytitle"><a href="sql-alterdefaultprivileges.html">ALTER DEFAULT PRIVILEGES</a></span><span class="refpurpose"> — define default access privileges</span></dt><dt><span class="refentrytitle"><a href="sql-alterdomain.html">ALTER DOMAIN</a></span><span class="refpurpose"> —
+ change the definition of a domain
+ </span></dt><dt><span class="refentrytitle"><a href="sql-altereventtrigger.html">ALTER EVENT TRIGGER</a></span><span class="refpurpose"> — change the definition of an event trigger</span></dt><dt><span class="refentrytitle"><a href="sql-alterextension.html">ALTER EXTENSION</a></span><span class="refpurpose"> —
+ change the definition of an extension
+ </span></dt><dt><span class="refentrytitle"><a href="sql-alterforeigndatawrapper.html">ALTER FOREIGN DATA WRAPPER</a></span><span class="refpurpose"> — change the definition of a foreign-data wrapper</span></dt><dt><span class="refentrytitle"><a href="sql-alterforeigntable.html">ALTER FOREIGN TABLE</a></span><span class="refpurpose"> — change the definition of a foreign table</span></dt><dt><span class="refentrytitle"><a href="sql-alterfunction.html">ALTER FUNCTION</a></span><span class="refpurpose"> — change the definition of a function</span></dt><dt><span class="refentrytitle"><a href="sql-altergroup.html">ALTER GROUP</a></span><span class="refpurpose"> — change role name or membership</span></dt><dt><span class="refentrytitle"><a href="sql-alterindex.html">ALTER INDEX</a></span><span class="refpurpose"> — change the definition of an index</span></dt><dt><span class="refentrytitle"><a href="sql-alterlanguage.html">ALTER LANGUAGE</a></span><span class="refpurpose"> — change the definition of a procedural language</span></dt><dt><span class="refentrytitle"><a href="sql-alterlargeobject.html">ALTER LARGE OBJECT</a></span><span class="refpurpose"> — change the definition of a large object</span></dt><dt><span class="refentrytitle"><a href="sql-altermaterializedview.html">ALTER MATERIALIZED VIEW</a></span><span class="refpurpose"> — change the definition of a materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-alteroperator.html">ALTER OPERATOR</a></span><span class="refpurpose"> — change the definition of an operator</span></dt><dt><span class="refentrytitle"><a href="sql-alteropclass.html">ALTER OPERATOR CLASS</a></span><span class="refpurpose"> — change the definition of an operator class</span></dt><dt><span class="refentrytitle"><a href="sql-alteropfamily.html">ALTER OPERATOR FAMILY</a></span><span class="refpurpose"> — change the definition of an operator family</span></dt><dt><span class="refentrytitle"><a href="sql-alterpolicy.html">ALTER POLICY</a></span><span class="refpurpose"> — change the definition of a row-level security policy</span></dt><dt><span class="refentrytitle"><a href="sql-alterprocedure.html">ALTER PROCEDURE</a></span><span class="refpurpose"> — change the definition of a procedure</span></dt><dt><span class="refentrytitle"><a href="sql-alterpublication.html">ALTER PUBLICATION</a></span><span class="refpurpose"> — change the definition of a publication</span></dt><dt><span class="refentrytitle"><a href="sql-alterrole.html">ALTER ROLE</a></span><span class="refpurpose"> — change a database role</span></dt><dt><span class="refentrytitle"><a href="sql-alterroutine.html">ALTER ROUTINE</a></span><span class="refpurpose"> — change the definition of a routine</span></dt><dt><span class="refentrytitle"><a href="sql-alterrule.html">ALTER RULE</a></span><span class="refpurpose"> — change the definition of a rule</span></dt><dt><span class="refentrytitle"><a href="sql-alterschema.html">ALTER SCHEMA</a></span><span class="refpurpose"> — change the definition of a schema</span></dt><dt><span class="refentrytitle"><a href="sql-altersequence.html">ALTER SEQUENCE</a></span><span class="refpurpose"> —
+ change the definition of a sequence generator
+ </span></dt><dt><span class="refentrytitle"><a href="sql-alterserver.html">ALTER SERVER</a></span><span class="refpurpose"> — change the definition of a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-alterstatistics.html">ALTER STATISTICS</a></span><span class="refpurpose"> —
+ change the definition of an extended statistics object
+ </span></dt><dt><span class="refentrytitle"><a href="sql-altersubscription.html">ALTER SUBSCRIPTION</a></span><span class="refpurpose"> — change the definition of a subscription</span></dt><dt><span class="refentrytitle"><a href="sql-altersystem.html">ALTER SYSTEM</a></span><span class="refpurpose"> — change a server configuration parameter</span></dt><dt><span class="refentrytitle"><a href="sql-altertable.html">ALTER TABLE</a></span><span class="refpurpose"> — change the definition of a table</span></dt><dt><span class="refentrytitle"><a href="sql-altertablespace.html">ALTER TABLESPACE</a></span><span class="refpurpose"> — change the definition of a tablespace</span></dt><dt><span class="refentrytitle"><a href="sql-altertsconfig.html">ALTER TEXT SEARCH CONFIGURATION</a></span><span class="refpurpose"> — change the definition of a text search configuration</span></dt><dt><span class="refentrytitle"><a href="sql-altertsdictionary.html">ALTER TEXT SEARCH DICTIONARY</a></span><span class="refpurpose"> — change the definition of a text search dictionary</span></dt><dt><span class="refentrytitle"><a href="sql-altertsparser.html">ALTER TEXT SEARCH PARSER</a></span><span class="refpurpose"> — change the definition of a text search parser</span></dt><dt><span class="refentrytitle"><a href="sql-altertstemplate.html">ALTER TEXT SEARCH TEMPLATE</a></span><span class="refpurpose"> — change the definition of a text search template</span></dt><dt><span class="refentrytitle"><a href="sql-altertrigger.html">ALTER TRIGGER</a></span><span class="refpurpose"> — change the definition of a trigger</span></dt><dt><span class="refentrytitle"><a href="sql-altertype.html">ALTER TYPE</a></span><span class="refpurpose"> —
+ change the definition of a type
+ </span></dt><dt><span class="refentrytitle"><a href="sql-alteruser.html">ALTER USER</a></span><span class="refpurpose"> — change a database role</span></dt><dt><span class="refentrytitle"><a href="sql-alterusermapping.html">ALTER USER MAPPING</a></span><span class="refpurpose"> — change the definition of a user mapping</span></dt><dt><span class="refentrytitle"><a href="sql-alterview.html">ALTER VIEW</a></span><span class="refpurpose"> — change the definition of a view</span></dt><dt><span class="refentrytitle"><a href="sql-analyze.html">ANALYZE</a></span><span class="refpurpose"> — collect statistics about a database</span></dt><dt><span class="refentrytitle"><a href="sql-begin.html">BEGIN</a></span><span class="refpurpose"> — start a transaction block</span></dt><dt><span class="refentrytitle"><a href="sql-call.html">CALL</a></span><span class="refpurpose"> — invoke a procedure</span></dt><dt><span class="refentrytitle"><a href="sql-checkpoint.html">CHECKPOINT</a></span><span class="refpurpose"> — force a write-ahead log checkpoint</span></dt><dt><span class="refentrytitle"><a href="sql-close.html">CLOSE</a></span><span class="refpurpose"> — close a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-cluster.html">CLUSTER</a></span><span class="refpurpose"> — cluster a table according to an index</span></dt><dt><span class="refentrytitle"><a href="sql-comment.html">COMMENT</a></span><span class="refpurpose"> — define or change the comment of an object</span></dt><dt><span class="refentrytitle"><a href="sql-commit.html">COMMIT</a></span><span class="refpurpose"> — commit the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-commit-prepared.html">COMMIT PREPARED</a></span><span class="refpurpose"> — commit a transaction that was earlier prepared for two-phase commit</span></dt><dt><span class="refentrytitle"><a href="sql-copy.html">COPY</a></span><span class="refpurpose"> — copy data between a file and a table</span></dt><dt><span class="refentrytitle"><a href="sql-create-access-method.html">CREATE ACCESS METHOD</a></span><span class="refpurpose"> — define a new access method</span></dt><dt><span class="refentrytitle"><a href="sql-createaggregate.html">CREATE AGGREGATE</a></span><span class="refpurpose"> — define a new aggregate function</span></dt><dt><span class="refentrytitle"><a href="sql-createcast.html">CREATE CAST</a></span><span class="refpurpose"> — define a new cast</span></dt><dt><span class="refentrytitle"><a href="sql-createcollation.html">CREATE COLLATION</a></span><span class="refpurpose"> — define a new collation</span></dt><dt><span class="refentrytitle"><a href="sql-createconversion.html">CREATE CONVERSION</a></span><span class="refpurpose"> — define a new encoding conversion</span></dt><dt><span class="refentrytitle"><a href="sql-createdatabase.html">CREATE DATABASE</a></span><span class="refpurpose"> — create a new database</span></dt><dt><span class="refentrytitle"><a href="sql-createdomain.html">CREATE DOMAIN</a></span><span class="refpurpose"> — define a new domain</span></dt><dt><span class="refentrytitle"><a href="sql-createeventtrigger.html">CREATE EVENT TRIGGER</a></span><span class="refpurpose"> — define a new event trigger</span></dt><dt><span class="refentrytitle"><a href="sql-createextension.html">CREATE EXTENSION</a></span><span class="refpurpose"> — install an extension</span></dt><dt><span class="refentrytitle"><a href="sql-createforeigndatawrapper.html">CREATE FOREIGN DATA WRAPPER</a></span><span class="refpurpose"> — define a new foreign-data wrapper</span></dt><dt><span class="refentrytitle"><a href="sql-createforeigntable.html">CREATE FOREIGN TABLE</a></span><span class="refpurpose"> — define a new foreign table</span></dt><dt><span class="refentrytitle"><a href="sql-createfunction.html">CREATE FUNCTION</a></span><span class="refpurpose"> — define a new function</span></dt><dt><span class="refentrytitle"><a href="sql-creategroup.html">CREATE GROUP</a></span><span class="refpurpose"> — define a new database role</span></dt><dt><span class="refentrytitle"><a href="sql-createindex.html">CREATE INDEX</a></span><span class="refpurpose"> — define a new index</span></dt><dt><span class="refentrytitle"><a href="sql-createlanguage.html">CREATE LANGUAGE</a></span><span class="refpurpose"> — define a new procedural language</span></dt><dt><span class="refentrytitle"><a href="sql-creatematerializedview.html">CREATE MATERIALIZED VIEW</a></span><span class="refpurpose"> — define a new materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-createoperator.html">CREATE OPERATOR</a></span><span class="refpurpose"> — define a new operator</span></dt><dt><span class="refentrytitle"><a href="sql-createopclass.html">CREATE OPERATOR CLASS</a></span><span class="refpurpose"> — define a new operator class</span></dt><dt><span class="refentrytitle"><a href="sql-createopfamily.html">CREATE OPERATOR FAMILY</a></span><span class="refpurpose"> — define a new operator family</span></dt><dt><span class="refentrytitle"><a href="sql-createpolicy.html">CREATE POLICY</a></span><span class="refpurpose"> — define a new row-level security policy for a table</span></dt><dt><span class="refentrytitle"><a href="sql-createprocedure.html">CREATE PROCEDURE</a></span><span class="refpurpose"> — define a new procedure</span></dt><dt><span class="refentrytitle"><a href="sql-createpublication.html">CREATE PUBLICATION</a></span><span class="refpurpose"> — define a new publication</span></dt><dt><span class="refentrytitle"><a href="sql-createrole.html">CREATE ROLE</a></span><span class="refpurpose"> — define a new database role</span></dt><dt><span class="refentrytitle"><a href="sql-createrule.html">CREATE RULE</a></span><span class="refpurpose"> — define a new rewrite rule</span></dt><dt><span class="refentrytitle"><a href="sql-createschema.html">CREATE SCHEMA</a></span><span class="refpurpose"> — define a new schema</span></dt><dt><span class="refentrytitle"><a href="sql-createsequence.html">CREATE SEQUENCE</a></span><span class="refpurpose"> — define a new sequence generator</span></dt><dt><span class="refentrytitle"><a href="sql-createserver.html">CREATE SERVER</a></span><span class="refpurpose"> — define a new foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-createstatistics.html">CREATE STATISTICS</a></span><span class="refpurpose"> — define extended statistics</span></dt><dt><span class="refentrytitle"><a href="sql-createsubscription.html">CREATE SUBSCRIPTION</a></span><span class="refpurpose"> — define a new subscription</span></dt><dt><span class="refentrytitle"><a href="sql-createtable.html">CREATE TABLE</a></span><span class="refpurpose"> — define a new table</span></dt><dt><span class="refentrytitle"><a href="sql-createtableas.html">CREATE TABLE AS</a></span><span class="refpurpose"> — define a new table from the results of a query</span></dt><dt><span class="refentrytitle"><a href="sql-createtablespace.html">CREATE TABLESPACE</a></span><span class="refpurpose"> — define a new tablespace</span></dt><dt><span class="refentrytitle"><a href="sql-createtsconfig.html">CREATE TEXT SEARCH CONFIGURATION</a></span><span class="refpurpose"> — define a new text search configuration</span></dt><dt><span class="refentrytitle"><a href="sql-createtsdictionary.html">CREATE TEXT SEARCH DICTIONARY</a></span><span class="refpurpose"> — define a new text search dictionary</span></dt><dt><span class="refentrytitle"><a href="sql-createtsparser.html">CREATE TEXT SEARCH PARSER</a></span><span class="refpurpose"> — define a new text search parser</span></dt><dt><span class="refentrytitle"><a href="sql-createtstemplate.html">CREATE TEXT SEARCH TEMPLATE</a></span><span class="refpurpose"> — define a new text search template</span></dt><dt><span class="refentrytitle"><a href="sql-createtransform.html">CREATE TRANSFORM</a></span><span class="refpurpose"> — define a new transform</span></dt><dt><span class="refentrytitle"><a href="sql-createtrigger.html">CREATE TRIGGER</a></span><span class="refpurpose"> — define a new trigger</span></dt><dt><span class="refentrytitle"><a href="sql-createtype.html">CREATE TYPE</a></span><span class="refpurpose"> — define a new data type</span></dt><dt><span class="refentrytitle"><a href="sql-createuser.html">CREATE USER</a></span><span class="refpurpose"> — define a new database role</span></dt><dt><span class="refentrytitle"><a href="sql-createusermapping.html">CREATE USER MAPPING</a></span><span class="refpurpose"> — define a new mapping of a user to a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-createview.html">CREATE VIEW</a></span><span class="refpurpose"> — define a new view</span></dt><dt><span class="refentrytitle"><a href="sql-deallocate.html">DEALLOCATE</a></span><span class="refpurpose"> — deallocate a prepared statement</span></dt><dt><span class="refentrytitle"><a href="sql-declare.html">DECLARE</a></span><span class="refpurpose"> — define a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-delete.html">DELETE</a></span><span class="refpurpose"> — delete rows of a table</span></dt><dt><span class="refentrytitle"><a href="sql-discard.html">DISCARD</a></span><span class="refpurpose"> — discard session state</span></dt><dt><span class="refentrytitle"><a href="sql-do.html">DO</a></span><span class="refpurpose"> — execute an anonymous code block</span></dt><dt><span class="refentrytitle"><a href="sql-drop-access-method.html">DROP ACCESS METHOD</a></span><span class="refpurpose"> — remove an access method</span></dt><dt><span class="refentrytitle"><a href="sql-dropaggregate.html">DROP AGGREGATE</a></span><span class="refpurpose"> — remove an aggregate function</span></dt><dt><span class="refentrytitle"><a href="sql-dropcast.html">DROP CAST</a></span><span class="refpurpose"> — remove a cast</span></dt><dt><span class="refentrytitle"><a href="sql-dropcollation.html">DROP COLLATION</a></span><span class="refpurpose"> — remove a collation</span></dt><dt><span class="refentrytitle"><a href="sql-dropconversion.html">DROP CONVERSION</a></span><span class="refpurpose"> — remove a conversion</span></dt><dt><span class="refentrytitle"><a href="sql-dropdatabase.html">DROP DATABASE</a></span><span class="refpurpose"> — remove a database</span></dt><dt><span class="refentrytitle"><a href="sql-dropdomain.html">DROP DOMAIN</a></span><span class="refpurpose"> — remove a domain</span></dt><dt><span class="refentrytitle"><a href="sql-dropeventtrigger.html">DROP EVENT TRIGGER</a></span><span class="refpurpose"> — remove an event trigger</span></dt><dt><span class="refentrytitle"><a href="sql-dropextension.html">DROP EXTENSION</a></span><span class="refpurpose"> — remove an extension</span></dt><dt><span class="refentrytitle"><a href="sql-dropforeigndatawrapper.html">DROP FOREIGN DATA WRAPPER</a></span><span class="refpurpose"> — remove a foreign-data wrapper</span></dt><dt><span class="refentrytitle"><a href="sql-dropforeigntable.html">DROP FOREIGN TABLE</a></span><span class="refpurpose"> — remove a foreign table</span></dt><dt><span class="refentrytitle"><a href="sql-dropfunction.html">DROP FUNCTION</a></span><span class="refpurpose"> — remove a function</span></dt><dt><span class="refentrytitle"><a href="sql-dropgroup.html">DROP GROUP</a></span><span class="refpurpose"> — remove a database role</span></dt><dt><span class="refentrytitle"><a href="sql-dropindex.html">DROP INDEX</a></span><span class="refpurpose"> — remove an index</span></dt><dt><span class="refentrytitle"><a href="sql-droplanguage.html">DROP LANGUAGE</a></span><span class="refpurpose"> — remove a procedural language</span></dt><dt><span class="refentrytitle"><a href="sql-dropmaterializedview.html">DROP MATERIALIZED VIEW</a></span><span class="refpurpose"> — remove a materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-dropoperator.html">DROP OPERATOR</a></span><span class="refpurpose"> — remove an operator</span></dt><dt><span class="refentrytitle"><a href="sql-dropopclass.html">DROP OPERATOR CLASS</a></span><span class="refpurpose"> — remove an operator class</span></dt><dt><span class="refentrytitle"><a href="sql-dropopfamily.html">DROP OPERATOR FAMILY</a></span><span class="refpurpose"> — remove an operator family</span></dt><dt><span class="refentrytitle"><a href="sql-drop-owned.html">DROP OWNED</a></span><span class="refpurpose"> — remove database objects owned by a database role</span></dt><dt><span class="refentrytitle"><a href="sql-droppolicy.html">DROP POLICY</a></span><span class="refpurpose"> — remove a row-level security policy from a table</span></dt><dt><span class="refentrytitle"><a href="sql-dropprocedure.html">DROP PROCEDURE</a></span><span class="refpurpose"> — remove a procedure</span></dt><dt><span class="refentrytitle"><a href="sql-droppublication.html">DROP PUBLICATION</a></span><span class="refpurpose"> — remove a publication</span></dt><dt><span class="refentrytitle"><a href="sql-droprole.html">DROP ROLE</a></span><span class="refpurpose"> — remove a database role</span></dt><dt><span class="refentrytitle"><a href="sql-droproutine.html">DROP ROUTINE</a></span><span class="refpurpose"> — remove a routine</span></dt><dt><span class="refentrytitle"><a href="sql-droprule.html">DROP RULE</a></span><span class="refpurpose"> — remove a rewrite rule</span></dt><dt><span class="refentrytitle"><a href="sql-dropschema.html">DROP SCHEMA</a></span><span class="refpurpose"> — remove a schema</span></dt><dt><span class="refentrytitle"><a href="sql-dropsequence.html">DROP SEQUENCE</a></span><span class="refpurpose"> — remove a sequence</span></dt><dt><span class="refentrytitle"><a href="sql-dropserver.html">DROP SERVER</a></span><span class="refpurpose"> — remove a foreign server descriptor</span></dt><dt><span class="refentrytitle"><a href="sql-dropstatistics.html">DROP STATISTICS</a></span><span class="refpurpose"> — remove extended statistics</span></dt><dt><span class="refentrytitle"><a href="sql-dropsubscription.html">DROP SUBSCRIPTION</a></span><span class="refpurpose"> — remove a subscription</span></dt><dt><span class="refentrytitle"><a href="sql-droptable.html">DROP TABLE</a></span><span class="refpurpose"> — remove a table</span></dt><dt><span class="refentrytitle"><a href="sql-droptablespace.html">DROP TABLESPACE</a></span><span class="refpurpose"> — remove a tablespace</span></dt><dt><span class="refentrytitle"><a href="sql-droptsconfig.html">DROP TEXT SEARCH CONFIGURATION</a></span><span class="refpurpose"> — remove a text search configuration</span></dt><dt><span class="refentrytitle"><a href="sql-droptsdictionary.html">DROP TEXT SEARCH DICTIONARY</a></span><span class="refpurpose"> — remove a text search dictionary</span></dt><dt><span class="refentrytitle"><a href="sql-droptsparser.html">DROP TEXT SEARCH PARSER</a></span><span class="refpurpose"> — remove a text search parser</span></dt><dt><span class="refentrytitle"><a href="sql-droptstemplate.html">DROP TEXT SEARCH TEMPLATE</a></span><span class="refpurpose"> — remove a text search template</span></dt><dt><span class="refentrytitle"><a href="sql-droptransform.html">DROP TRANSFORM</a></span><span class="refpurpose"> — remove a transform</span></dt><dt><span class="refentrytitle"><a href="sql-droptrigger.html">DROP TRIGGER</a></span><span class="refpurpose"> — remove a trigger</span></dt><dt><span class="refentrytitle"><a href="sql-droptype.html">DROP TYPE</a></span><span class="refpurpose"> — remove a data type</span></dt><dt><span class="refentrytitle"><a href="sql-dropuser.html">DROP USER</a></span><span class="refpurpose"> — remove a database role</span></dt><dt><span class="refentrytitle"><a href="sql-dropusermapping.html">DROP USER MAPPING</a></span><span class="refpurpose"> — remove a user mapping for a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-dropview.html">DROP VIEW</a></span><span class="refpurpose"> — remove a view</span></dt><dt><span class="refentrytitle"><a href="sql-end.html">END</a></span><span class="refpurpose"> — commit the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-execute.html">EXECUTE</a></span><span class="refpurpose"> — execute a prepared statement</span></dt><dt><span class="refentrytitle"><a href="sql-explain.html">EXPLAIN</a></span><span class="refpurpose"> — show the execution plan of a statement</span></dt><dt><span class="refentrytitle"><a href="sql-fetch.html">FETCH</a></span><span class="refpurpose"> — retrieve rows from a query using a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-grant.html">GRANT</a></span><span class="refpurpose"> — define access privileges</span></dt><dt><span class="refentrytitle"><a href="sql-importforeignschema.html">IMPORT FOREIGN SCHEMA</a></span><span class="refpurpose"> — import table definitions from a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-insert.html">INSERT</a></span><span class="refpurpose"> — create new rows in a table</span></dt><dt><span class="refentrytitle"><a href="sql-listen.html">LISTEN</a></span><span class="refpurpose"> — listen for a notification</span></dt><dt><span class="refentrytitle"><a href="sql-load.html">LOAD</a></span><span class="refpurpose"> — load a shared library file</span></dt><dt><span class="refentrytitle"><a href="sql-lock.html">LOCK</a></span><span class="refpurpose"> — lock a table</span></dt><dt><span class="refentrytitle"><a href="sql-merge.html">MERGE</a></span><span class="refpurpose"> — conditionally insert, update, or delete rows of a table</span></dt><dt><span class="refentrytitle"><a href="sql-move.html">MOVE</a></span><span class="refpurpose"> — position a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-notify.html">NOTIFY</a></span><span class="refpurpose"> — generate a notification</span></dt><dt><span class="refentrytitle"><a href="sql-prepare.html">PREPARE</a></span><span class="refpurpose"> — prepare a statement for execution</span></dt><dt><span class="refentrytitle"><a href="sql-prepare-transaction.html">PREPARE TRANSACTION</a></span><span class="refpurpose"> — prepare the current transaction for two-phase commit</span></dt><dt><span class="refentrytitle"><a href="sql-reassign-owned.html">REASSIGN OWNED</a></span><span class="refpurpose"> — change the ownership of database objects owned by a database role</span></dt><dt><span class="refentrytitle"><a href="sql-refreshmaterializedview.html">REFRESH MATERIALIZED VIEW</a></span><span class="refpurpose"> — replace the contents of a materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-reindex.html">REINDEX</a></span><span class="refpurpose"> — rebuild indexes</span></dt><dt><span class="refentrytitle"><a href="sql-release-savepoint.html">RELEASE SAVEPOINT</a></span><span class="refpurpose"> — destroy a previously defined savepoint</span></dt><dt><span class="refentrytitle"><a href="sql-reset.html">RESET</a></span><span class="refpurpose"> — restore the value of a run-time parameter to the default value</span></dt><dt><span class="refentrytitle"><a href="sql-revoke.html">REVOKE</a></span><span class="refpurpose"> — remove access privileges</span></dt><dt><span class="refentrytitle"><a href="sql-rollback.html">ROLLBACK</a></span><span class="refpurpose"> — abort the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-rollback-prepared.html">ROLLBACK PREPARED</a></span><span class="refpurpose"> — cancel a transaction that was earlier prepared for two-phase commit</span></dt><dt><span class="refentrytitle"><a href="sql-rollback-to.html">ROLLBACK TO SAVEPOINT</a></span><span class="refpurpose"> — roll back to a savepoint</span></dt><dt><span class="refentrytitle"><a href="sql-savepoint.html">SAVEPOINT</a></span><span class="refpurpose"> — define a new savepoint within the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-security-label.html">SECURITY LABEL</a></span><span class="refpurpose"> — define or change a security label applied to an object</span></dt><dt><span class="refentrytitle"><a href="sql-select.html">SELECT</a></span><span class="refpurpose"> — retrieve rows from a table or view</span></dt><dt><span class="refentrytitle"><a href="sql-selectinto.html">SELECT INTO</a></span><span class="refpurpose"> — define a new table from the results of a query</span></dt><dt><span class="refentrytitle"><a href="sql-set.html">SET</a></span><span class="refpurpose"> — change a run-time parameter</span></dt><dt><span class="refentrytitle"><a href="sql-set-constraints.html">SET CONSTRAINTS</a></span><span class="refpurpose"> — set constraint check timing for the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-set-role.html">SET ROLE</a></span><span class="refpurpose"> — set the current user identifier of the current session</span></dt><dt><span class="refentrytitle"><a href="sql-set-session-authorization.html">SET SESSION AUTHORIZATION</a></span><span class="refpurpose"> — set the session user identifier and the current user identifier of the current session</span></dt><dt><span class="refentrytitle"><a href="sql-set-transaction.html">SET TRANSACTION</a></span><span class="refpurpose"> — set the characteristics of the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-show.html">SHOW</a></span><span class="refpurpose"> — show the value of a run-time parameter</span></dt><dt><span class="refentrytitle"><a href="sql-start-transaction.html">START TRANSACTION</a></span><span class="refpurpose"> — start a transaction block</span></dt><dt><span class="refentrytitle"><a href="sql-truncate.html">TRUNCATE</a></span><span class="refpurpose"> — empty a table or set of tables</span></dt><dt><span class="refentrytitle"><a href="sql-unlisten.html">UNLISTEN</a></span><span class="refpurpose"> — stop listening for a notification</span></dt><dt><span class="refentrytitle"><a href="sql-update.html">UPDATE</a></span><span class="refpurpose"> — update rows of a table</span></dt><dt><span class="refentrytitle"><a href="sql-vacuum.html">VACUUM</a></span><span class="refpurpose"> — garbage-collect and optionally analyze a database</span></dt><dt><span class="refentrytitle"><a href="sql-values.html">VALUES</a></span><span class="refpurpose"> — compute a set of rows</span></dt></dl></dd><dt><span class="reference"><a href="reference-client.html">II. PostgreSQL Client Applications</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="app-clusterdb.html"><span class="application">clusterdb</span></a></span><span class="refpurpose"> — cluster a <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-createdb.html"><span class="application">createdb</span></a></span><span class="refpurpose"> — create a new <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-createuser.html"><span class="application">createuser</span></a></span><span class="refpurpose"> — define a new <span class="productname">PostgreSQL</span> user account</span></dt><dt><span class="refentrytitle"><a href="app-dropdb.html"><span class="application">dropdb</span></a></span><span class="refpurpose"> — remove a <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-dropuser.html"><span class="application">dropuser</span></a></span><span class="refpurpose"> — remove a <span class="productname">PostgreSQL</span> user account</span></dt><dt><span class="refentrytitle"><a href="app-ecpg.html"><span class="application">ecpg</span></a></span><span class="refpurpose"> — embedded SQL C preprocessor</span></dt><dt><span class="refentrytitle"><a href="app-pgamcheck.html"><span class="application">pg_amcheck</span></a></span><span class="refpurpose"> — checks for corruption in one or more
+ <span class="productname">PostgreSQL</span> databases</span></dt><dt><span class="refentrytitle"><a href="app-pgbasebackup.html"><span class="application">pg_basebackup</span></a></span><span class="refpurpose"> — take a base backup of a <span class="productname">PostgreSQL</span> cluster</span></dt><dt><span class="refentrytitle"><a href="pgbench.html"><span class="application">pgbench</span></a></span><span class="refpurpose"> — run a benchmark test on <span class="productname">PostgreSQL</span></span></dt><dt><span class="refentrytitle"><a href="app-pgconfig.html"><span class="application">pg_config</span></a></span><span class="refpurpose"> — retrieve information about the installed version of <span class="productname">PostgreSQL</span></span></dt><dt><span class="refentrytitle"><a href="app-pgdump.html"><span class="application">pg_dump</span></a></span><span class="refpurpose"> —
+ extract a <span class="productname">PostgreSQL</span> database into a script file or other archive file
+ </span></dt><dt><span class="refentrytitle"><a href="app-pg-dumpall.html"><span class="application">pg_dumpall</span></a></span><span class="refpurpose"> — extract a <span class="productname">PostgreSQL</span> database cluster into a script file</span></dt><dt><span class="refentrytitle"><a href="app-pg-isready.html"><span class="application">pg_isready</span></a></span><span class="refpurpose"> — check the connection status of a <span class="productname">PostgreSQL</span> server</span></dt><dt><span class="refentrytitle"><a href="app-pgreceivewal.html"><span class="application">pg_receivewal</span></a></span><span class="refpurpose"> — stream write-ahead logs from a <span class="productname">PostgreSQL</span> server</span></dt><dt><span class="refentrytitle"><a href="app-pgrecvlogical.html"><span class="application">pg_recvlogical</span></a></span><span class="refpurpose"> — control <span class="productname">PostgreSQL</span> logical decoding streams</span></dt><dt><span class="refentrytitle"><a href="app-pgrestore.html"><span class="application">pg_restore</span></a></span><span class="refpurpose"> —
+ restore a <span class="productname">PostgreSQL</span> database from an
+ archive file created by <span class="application">pg_dump</span>
+ </span></dt><dt><span class="refentrytitle"><a href="app-pgverifybackup.html"><span class="application">pg_verifybackup</span></a></span><span class="refpurpose"> — verify the integrity of a base backup of a
+ <span class="productname">PostgreSQL</span> cluster</span></dt><dt><span class="refentrytitle"><a href="app-psql.html"><span class="application">psql</span></a></span><span class="refpurpose"> —
+ <span class="productname">PostgreSQL</span> interactive terminal
+ </span></dt><dt><span class="refentrytitle"><a href="app-reindexdb.html"><span class="application">reindexdb</span></a></span><span class="refpurpose"> — reindex a <span class="productname">PostgreSQL</span> database</span></dt><dt><span class="refentrytitle"><a href="app-vacuumdb.html"><span class="application">vacuumdb</span></a></span><span class="refpurpose"> — garbage-collect and analyze a <span class="productname">PostgreSQL</span> database</span></dt></dl></dd><dt><span class="reference"><a href="reference-server.html">III. PostgreSQL Server Applications</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="app-initdb.html"><span class="application">initdb</span></a></span><span class="refpurpose"> — create a new <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="pgarchivecleanup.html"><span class="application">pg_archivecleanup</span></a></span><span class="refpurpose"> — clean up <span class="productname">PostgreSQL</span> WAL archive files</span></dt><dt><span class="refentrytitle"><a href="app-pgchecksums.html"><span class="application">pg_checksums</span></a></span><span class="refpurpose"> — enable, disable or check data checksums in a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-pgcontroldata.html"><span class="application">pg_controldata</span></a></span><span class="refpurpose"> — display control information of a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-pg-ctl.html"><span class="application">pg_ctl</span></a></span><span class="refpurpose"> — initialize, start, stop, or control a <span class="productname">PostgreSQL</span> server</span></dt><dt><span class="refentrytitle"><a href="app-pgresetwal.html"><span class="application">pg_resetwal</span></a></span><span class="refpurpose"> — reset the write-ahead log and other control information of a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-pgrewind.html"><span class="application">pg_rewind</span></a></span><span class="refpurpose"> — synchronize a <span class="productname">PostgreSQL</span> data directory with another data directory that was forked from it</span></dt><dt><span class="refentrytitle"><a href="pgtestfsync.html"><span class="application">pg_test_fsync</span></a></span><span class="refpurpose"> — determine fastest <code class="varname">wal_sync_method</code> for <span class="productname">PostgreSQL</span></span></dt><dt><span class="refentrytitle"><a href="pgtesttiming.html"><span class="application">pg_test_timing</span></a></span><span class="refpurpose"> — measure timing overhead</span></dt><dt><span class="refentrytitle"><a href="pgupgrade.html"><span class="application">pg_upgrade</span></a></span><span class="refpurpose"> — upgrade a <span class="productname">PostgreSQL</span> server instance</span></dt><dt><span class="refentrytitle"><a href="pgwaldump.html"><span class="application">pg_waldump</span></a></span><span class="refpurpose"> — display a human-readable rendering of the write-ahead log of a <span class="productname">PostgreSQL</span> database cluster</span></dt><dt><span class="refentrytitle"><a href="app-postgres.html"><span class="application">postgres</span></a></span><span class="refpurpose"> — <span class="productname">PostgreSQL</span> database server</span></dt><dt><span class="refentrytitle"><a href="app-postmaster.html"><span class="application">postmaster</span></a></span><span class="refpurpose"> — <span class="productname">PostgreSQL</span> database server</span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="archive-module-callbacks.html" title="51.2. Archive Module Callbacks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-commands.html" title="SQL Commands">Next</a></td></tr><tr><td width="40%" align="left" valign="top">51.2. Archive Module Callbacks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SQL Commands</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/regress-coverage.html b/doc/src/sgml/html/regress-coverage.html
new file mode 100644
index 0000000..da573c7
--- /dev/null
+++ b/doc/src/sgml/html/regress-coverage.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>33.5. Test Coverage Examination</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="regress-tap.html" title="33.4. TAP Tests" /><link rel="next" href="client-interfaces.html" title="Part IV. Client Interfaces" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">33.5. Test Coverage Examination</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="regress-tap.html" title="33.4. TAP Tests">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><th width="60%" align="center">Chapter 33. Regression Tests</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="client-interfaces.html" title="Part IV. Client Interfaces">Next</a></td></tr></table><hr /></div><div class="sect1" id="REGRESS-COVERAGE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">33.5. Test Coverage Examination</h2></div></div></div><p>
+ The PostgreSQL source code can be compiled with coverage testing
+ instrumentation, so that it becomes possible to examine which
+ parts of the code are covered by the regression tests or any other
+ test suite that is run with the code. This is currently supported
+ when compiling with GCC, and it requires the <code class="command">gcov</code>
+ and <code class="command">lcov</code> programs.
+ </p><p>
+ A typical workflow looks like this:
+</p><pre class="screen">
+./configure --enable-coverage ... OTHER OPTIONS ...
+make
+make check # or other test suite
+make coverage-html
+</pre><p>
+ Then point your HTML browser
+ to <code class="filename">coverage/index.html</code>.
+ </p><p>
+ If you don't have <code class="command">lcov</code> or prefer text output over an
+ HTML report, you can run
+</p><pre class="screen">
+make coverage
+</pre><p>
+ instead of <code class="literal">make coverage-html</code>, which will
+ produce <code class="filename">.gcov</code> output files for each source file
+ relevant to the test. (<code class="literal">make coverage</code> and <code class="literal">make
+ coverage-html</code> will overwrite each other's files, so mixing them
+ might be confusing.)
+ </p><p>
+ You can run several different tests before making the coverage report;
+ the execution counts will accumulate. If you want
+ to reset the execution counts between test runs, run:
+</p><pre class="screen">
+make coverage-clean
+</pre><p>
+ </p><p>
+ You can run the <code class="literal">make coverage-html</code> or <code class="literal">make
+ coverage</code> command in a subdirectory if you want a coverage
+ report for only a portion of the code tree.
+ </p><p>
+ Use <code class="literal">make distclean</code> to clean up when done.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="regress-tap.html" title="33.4. TAP Tests">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="client-interfaces.html" title="Part IV. Client Interfaces">Next</a></td></tr><tr><td width="40%" align="left" valign="top">33.4. TAP Tests </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part IV. Client Interfaces</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/regress-evaluation.html b/doc/src/sgml/html/regress-evaluation.html
new file mode 100644
index 0000000..6b4c7ca
--- /dev/null
+++ b/doc/src/sgml/html/regress-evaluation.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>33.2. Test Evaluation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="regress-run.html" title="33.1. Running the Tests" /><link rel="next" href="regress-variant.html" title="33.3. Variant Comparison Files" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">33.2. Test Evaluation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="regress-run.html" title="33.1. Running the Tests">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><th width="60%" align="center">Chapter 33. Regression Tests</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="regress-variant.html" title="33.3. Variant Comparison Files">Next</a></td></tr></table><hr /></div><div class="sect1" id="REGRESS-EVALUATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">33.2. Test Evaluation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.6">33.2.1. Error Message Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.7">33.2.2. Locale Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.8">33.2.3. Date and Time Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.9">33.2.4. Floating-Point Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.10">33.2.5. Row Ordering Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.11">33.2.6. Insufficient Stack Depth</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.12">33.2.7. The <span class="quote">“<span class="quote">random</span>”</span> Test</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.13">33.2.8. Configuration Parameters</a></span></dt></dl></div><p>
+ Some properly installed and fully functional
+ <span class="productname">PostgreSQL</span> installations can
+ <span class="quote">“<span class="quote">fail</span>”</span> some of these regression tests due to
+ platform-specific artifacts such as varying floating-point representation
+ and message wording. The tests are currently evaluated using a simple
+ <code class="command">diff</code> comparison against the outputs
+ generated on a reference system, so the results are sensitive to
+ small system differences. When a test is reported as
+ <span class="quote">“<span class="quote">failed</span>”</span>, always examine the differences between
+ expected and actual results; you might find that the
+ differences are not significant. Nonetheless, we still strive to
+ maintain accurate reference files across all supported platforms,
+ so it can be expected that all tests pass.
+ </p><p>
+ The actual outputs of the regression tests are in files in the
+ <code class="filename">src/test/regress/results</code> directory. The test
+ script uses <code class="command">diff</code> to compare each output
+ file against the reference outputs stored in the
+ <code class="filename">src/test/regress/expected</code> directory. Any
+ differences are saved for your inspection in
+ <code class="filename">src/test/regress/regression.diffs</code>.
+ (When running a test suite other than the core tests, these files
+ of course appear in the relevant subdirectory,
+ not <code class="filename">src/test/regress</code>.)
+ </p><p>
+ If you don't
+ like the <code class="command">diff</code> options that are used by default, set the
+ environment variable <code class="envar">PG_REGRESS_DIFF_OPTS</code>, for
+ instance <code class="literal">PG_REGRESS_DIFF_OPTS='-c'</code>. (Or you
+ can run <code class="command">diff</code> yourself, if you prefer.)
+ </p><p>
+ If for some reason a particular platform generates a <span class="quote">“<span class="quote">failure</span>”</span>
+ for a given test, but inspection of the output convinces you that
+ the result is valid, you can add a new comparison file to silence
+ the failure report in future test runs. See
+ <a class="xref" href="regress-variant.html" title="33.3. Variant Comparison Files">Section 33.3</a> for details.
+ </p><div class="sect2" id="id-1.6.20.6.6"><div class="titlepage"><div><div><h3 class="title">33.2.1. Error Message Differences</h3></div></div></div><p>
+ Some of the regression tests involve intentional invalid input
+ values. Error messages can come from either the
+ <span class="productname">PostgreSQL</span> code or from the host
+ platform system routines. In the latter case, the messages can
+ vary between platforms, but should reflect similar
+ information. These differences in messages will result in a
+ <span class="quote">“<span class="quote">failed</span>”</span> regression test that can be validated by
+ inspection.
+ </p></div><div class="sect2" id="id-1.6.20.6.7"><div class="titlepage"><div><div><h3 class="title">33.2.2. Locale Differences</h3></div></div></div><p>
+ If you run the tests against a server that was
+ initialized with a collation-order locale other than C, then
+ there might be differences due to sort order and subsequent
+ failures. The regression test suite is set up to handle this
+ problem by providing alternate result files that together are
+ known to handle a large number of locales.
+ </p><p>
+ To run the tests in a different locale when using the
+ temporary-installation method, pass the appropriate
+ locale-related environment variables on
+ the <code class="command">make</code> command line, for example:
+</p><pre class="programlisting">
+make check LANG=de_DE.utf8
+</pre><p>
+ (The regression test driver unsets <code class="envar">LC_ALL</code>, so it
+ does not work to choose the locale using that variable.) To use
+ no locale, either unset all locale-related environment variables
+ (or set them to <code class="literal">C</code>) or use the following
+ special invocation:
+</p><pre class="programlisting">
+make check NO_LOCALE=1
+</pre><p>
+ When running the tests against an existing installation, the
+ locale setup is determined by the existing installation. To
+ change it, initialize the database cluster with a different
+ locale by passing the appropriate options
+ to <code class="command">initdb</code>.
+ </p><p>
+ In general, it is advisable to try to run the
+ regression tests in the locale setup that is wanted for
+ production use, as this will exercise the locale- and
+ encoding-related code portions that will actually be used in
+ production. Depending on the operating system environment, you
+ might get failures, but then you will at least know what
+ locale-specific behaviors to expect when running real
+ applications.
+ </p></div><div class="sect2" id="id-1.6.20.6.8"><div class="titlepage"><div><div><h3 class="title">33.2.3. Date and Time Differences</h3></div></div></div><p>
+ Most of the date and time results are dependent on the time zone
+ environment. The reference files are generated for time zone
+ <code class="literal">PST8PDT</code> (Berkeley, California), and there will be
+ apparent failures if the tests are not run with that time zone setting.
+ The regression test driver sets environment variable
+ <code class="envar">PGTZ</code> to <code class="literal">PST8PDT</code>, which normally
+ ensures proper results.
+ </p></div><div class="sect2" id="id-1.6.20.6.9"><div class="titlepage"><div><div><h3 class="title">33.2.4. Floating-Point Differences</h3></div></div></div><p>
+ Some of the tests involve computing 64-bit floating-point numbers (<code class="type">double
+ precision</code>) from table columns. Differences in
+ results involving mathematical functions of <code class="type">double
+ precision</code> columns have been observed. The <code class="literal">float8</code> and
+ <code class="literal">geometry</code> tests are particularly prone to small differences
+ across platforms, or even with different compiler optimization settings.
+ Human eyeball comparison is needed to determine the real
+ significance of these differences which are usually 10 places to
+ the right of the decimal point.
+ </p><p>
+ Some systems display minus zero as <code class="literal">-0</code>, while others
+ just show <code class="literal">0</code>.
+ </p><p>
+ Some systems signal errors from <code class="function">pow()</code> and
+ <code class="function">exp()</code> differently from the mechanism
+ expected by the current <span class="productname">PostgreSQL</span>
+ code.
+ </p></div><div class="sect2" id="id-1.6.20.6.10"><div class="titlepage"><div><div><h3 class="title">33.2.5. Row Ordering Differences</h3></div></div></div><p>
+You might see differences in which the same rows are output in a
+different order than what appears in the expected file. In most cases
+this is not, strictly speaking, a bug. Most of the regression test
+scripts are not so pedantic as to use an <code class="literal">ORDER BY</code> for every single
+<code class="literal">SELECT</code>, and so their result row orderings are not well-defined
+according to the SQL specification. In practice, since we are
+looking at the same queries being executed on the same data by the same
+software, we usually get the same result ordering on all platforms,
+so the lack of <code class="literal">ORDER BY</code> is not a problem. Some queries do exhibit
+cross-platform ordering differences, however. When testing against an
+already-installed server, ordering differences can also be caused by
+non-C locale settings or non-default parameter settings, such as custom values
+of <code class="varname">work_mem</code> or the planner cost parameters.
+ </p><p>
+Therefore, if you see an ordering difference, it's not something to
+worry about, unless the query does have an <code class="literal">ORDER BY</code> that your
+result is violating. However, please report it anyway, so that we can add an
+<code class="literal">ORDER BY</code> to that particular query to eliminate the bogus
+<span class="quote">“<span class="quote">failure</span>”</span> in future releases.
+ </p><p>
+You might wonder why we don't order all the regression test queries explicitly
+to get rid of this issue once and for all. The reason is that that would
+make the regression tests less useful, not more, since they'd tend
+to exercise query plan types that produce ordered results to the
+exclusion of those that don't.
+ </p></div><div class="sect2" id="id-1.6.20.6.11"><div class="titlepage"><div><div><h3 class="title">33.2.6. Insufficient Stack Depth</h3></div></div></div><p>
+ If the <code class="literal">errors</code> test results in a server crash
+ at the <code class="literal">select infinite_recurse()</code> command, it means that
+ the platform's limit on process stack size is smaller than the
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-STACK-DEPTH">max_stack_depth</a> parameter indicates. This
+ can be fixed by running the server under a higher stack
+ size limit (4MB is recommended with the default value of
+ <code class="varname">max_stack_depth</code>). If you are unable to do that, an
+ alternative is to reduce the value of <code class="varname">max_stack_depth</code>.
+ </p><p>
+ On platforms supporting <code class="function">getrlimit()</code>, the server should
+ automatically choose a safe value of <code class="varname">max_stack_depth</code>;
+ so unless you've manually overridden this setting, a failure of this
+ kind is a reportable bug.
+ </p></div><div class="sect2" id="id-1.6.20.6.12"><div class="titlepage"><div><div><h3 class="title">33.2.7. The <span class="quote">“<span class="quote">random</span>”</span> Test</h3></div></div></div><p>
+ The <code class="literal">random</code> test script is intended to produce
+ random results. In very rare cases, this causes that regression
+ test to fail. Typing:
+</p><pre class="programlisting">
+diff results/random.out expected/random.out
+</pre><p>
+ should produce only one or a few lines of differences. You need
+ not worry unless the random test fails repeatedly.
+ </p></div><div class="sect2" id="id-1.6.20.6.13"><div class="titlepage"><div><div><h3 class="title">33.2.8. Configuration Parameters</h3></div></div></div><p>
+ When running the tests against an existing installation, some non-default
+ parameter settings could cause the tests to fail. For example, changing
+ parameters such as <code class="varname">enable_seqscan</code> or
+ <code class="varname">enable_indexscan</code> could cause plan changes that would
+ affect the results of tests that use <code class="command">EXPLAIN</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="regress-run.html" title="33.1. Running the Tests">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="regress-variant.html" title="33.3. Variant Comparison Files">Next</a></td></tr><tr><td width="40%" align="left" valign="top">33.1. Running the Tests </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 33.3. Variant Comparison Files</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/regress-run.html b/doc/src/sgml/html/regress-run.html
new file mode 100644
index 0000000..cc63484
--- /dev/null
+++ b/doc/src/sgml/html/regress-run.html
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>33.1. Running the Tests</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="regress.html" title="Chapter 33. Regression Tests" /><link rel="next" href="regress-evaluation.html" title="33.2. Test Evaluation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">33.1. Running the Tests</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="regress.html" title="Chapter 33. Regression Tests">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><th width="60%" align="center">Chapter 33. Regression Tests</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="regress-evaluation.html" title="33.2. Test Evaluation">Next</a></td></tr></table><hr /></div><div class="sect1" id="REGRESS-RUN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">33.1. Running the Tests</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.3">33.1.1. Running the Tests Against a Temporary Installation</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.4">33.1.2. Running the Tests Against an Existing Installation</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.5">33.1.3. Additional Test Suites</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.6">33.1.4. Locale and Encoding</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.7">33.1.5. Custom Server Settings</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.8">33.1.6. Extra Tests</a></span></dt></dl></div><p>
+ The regression tests can be run against an already installed and
+ running server, or using a temporary installation within the build
+ tree. Furthermore, there is a <span class="quote">“<span class="quote">parallel</span>”</span> and a
+ <span class="quote">“<span class="quote">sequential</span>”</span> mode for running the tests. The
+ sequential method runs each test script alone, while the
+ parallel method starts up multiple server processes to run groups
+ of tests in parallel. Parallel testing adds confidence that
+ interprocess communication and locking are working correctly.
+ </p><div class="sect2" id="id-1.6.20.5.3"><div class="titlepage"><div><div><h3 class="title">33.1.1. Running the Tests Against a Temporary Installation</h3></div></div></div><p>
+ To run the parallel regression tests after building but before installation,
+ type:
+</p><pre class="screen">
+make check
+</pre><p>
+ in the top-level directory. (Or you can change to
+ <code class="filename">src/test/regress</code> and run the command there.)
+ At the end you should see something like:
+</p><pre class="screen">
+<code class="computeroutput">
+=======================
+ All 193 tests passed.
+=======================
+</code>
+</pre><p>
+ or otherwise a note about which tests failed. See <a class="xref" href="regress-evaluation.html" title="33.2. Test Evaluation">Section 33.2</a> below before assuming that a
+ <span class="quote">“<span class="quote">failure</span>”</span> represents a serious problem.
+ </p><p>
+ Because this test method runs a temporary server, it will not work
+ if you did the build as the root user, since the server will not start as
+ root. Recommended procedure is not to do the build as root, or else to
+ perform testing after completing the installation.
+ </p><p>
+ If you have configured <span class="productname">PostgreSQL</span> to install
+ into a location where an older <span class="productname">PostgreSQL</span>
+ installation already exists, and you perform <code class="literal">make check</code>
+ before installing the new version, you might find that the tests fail
+ because the new programs try to use the already-installed shared
+ libraries. (Typical symptoms are complaints about undefined symbols.)
+ If you wish to run the tests before overwriting the old installation,
+ you'll need to build with <code class="literal">configure --disable-rpath</code>.
+ It is not recommended that you use this option for the final installation,
+ however.
+ </p><p>
+ The parallel regression test starts quite a few processes under your
+ user ID. Presently, the maximum concurrency is twenty parallel test
+ scripts, which means forty processes: there's a server process and a
+ <span class="application">psql</span> process for each test script.
+ So if your system enforces a per-user limit on the number of processes,
+ make sure this limit is at least fifty or so, else you might get
+ random-seeming failures in the parallel test. If you are not in
+ a position to raise the limit, you can cut down the degree of parallelism
+ by setting the <code class="literal">MAX_CONNECTIONS</code> parameter. For example:
+</p><pre class="screen">
+make MAX_CONNECTIONS=10 check
+</pre><p>
+ runs no more than ten tests concurrently.
+ </p></div><div class="sect2" id="id-1.6.20.5.4"><div class="titlepage"><div><div><h3 class="title">33.1.2. Running the Tests Against an Existing Installation</h3></div></div></div><p>
+ To run the tests after installation (see <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a>),
+ initialize a data directory and start the
+ server as explained in <a class="xref" href="runtime.html" title="Chapter 19. Server Setup and Operation">Chapter 19</a>, then type:
+</p><pre class="screen">
+make installcheck
+</pre><p>
+or for a parallel test:
+</p><pre class="screen">
+make installcheck-parallel
+</pre><p>
+ The tests will expect to contact the server at the local host and the
+ default port number, unless directed otherwise by <code class="envar">PGHOST</code> and
+ <code class="envar">PGPORT</code> environment variables. The tests will be run in a
+ database named <code class="literal">regression</code>; any existing database by this name
+ will be dropped.
+ </p><p>
+ The tests will also transiently create some cluster-wide objects, such as
+ roles, tablespaces, and subscriptions. These objects will have names
+ beginning with <code class="literal">regress_</code>. Beware of
+ using <code class="literal">installcheck</code> mode with an installation that has
+ any actual global objects named that way.
+ </p></div><div class="sect2" id="id-1.6.20.5.5"><div class="titlepage"><div><div><h3 class="title">33.1.3. Additional Test Suites</h3></div></div></div><p>
+ The <code class="literal">make check</code> and <code class="literal">make installcheck</code> commands
+ run only the <span class="quote">“<span class="quote">core</span>”</span> regression tests, which test built-in
+ functionality of the <span class="productname">PostgreSQL</span> server. The source
+ distribution contains many additional test suites, most of them having
+ to do with add-on functionality such as optional procedural languages.
+ </p><p>
+ To run all test suites applicable to the modules that have been selected
+ to be built, including the core tests, type one of these commands at the
+ top of the build tree:
+</p><pre class="screen">
+make check-world
+make installcheck-world
+</pre><p>
+ These commands run the tests using temporary servers or an
+ already-installed server, respectively, just as previously explained
+ for <code class="literal">make check</code> and <code class="literal">make installcheck</code>. Other
+ considerations are the same as previously explained for each method.
+ Note that <code class="literal">make check-world</code> builds a separate instance
+ (temporary data directory) for each tested module, so it requires more
+ time and disk space than <code class="literal">make installcheck-world</code>.
+ </p><p>
+ On a modern machine with multiple CPU cores and no tight operating-system
+ limits, you can make things go substantially faster with parallelism.
+ The recipe that most PostgreSQL developers actually use for running all
+ tests is something like
+</p><pre class="screen">
+make check-world -j8 &gt;/dev/null
+</pre><p>
+ with a <code class="option">-j</code> limit near to or a bit more than the number
+ of available cores. Discarding <span class="systemitem">stdout</span>
+ eliminates chatter that's not interesting when you just want to verify
+ success. (In case of failure, the <span class="systemitem">stderr</span>
+ messages are usually enough to determine where to look closer.)
+ </p><p>
+ Alternatively, you can run individual test suites by typing
+ <code class="literal">make check</code> or <code class="literal">make installcheck</code> in the appropriate
+ subdirectory of the build tree. Keep in mind that <code class="literal">make
+ installcheck</code> assumes you've installed the relevant module(s), not
+ only the core server.
+ </p><p>
+ The additional tests that can be invoked this way include:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Regression tests for optional procedural languages.
+ These are located under <code class="filename">src/pl</code>.
+ </p></li><li class="listitem"><p>
+ Regression tests for <code class="filename">contrib</code> modules,
+ located under <code class="filename">contrib</code>.
+ Not all <code class="filename">contrib</code> modules have tests.
+ </p></li><li class="listitem"><p>
+ Regression tests for the ECPG interface library,
+ located in <code class="filename">src/interfaces/ecpg/test</code>.
+ </p></li><li class="listitem"><p>
+ Tests for core-supported authentication methods,
+ located in <code class="filename">src/test/authentication</code>.
+ (See below for additional authentication-related tests.)
+ </p></li><li class="listitem"><p>
+ Tests stressing behavior of concurrent sessions,
+ located in <code class="filename">src/test/isolation</code>.
+ </p></li><li class="listitem"><p>
+ Tests for crash recovery and physical replication,
+ located in <code class="filename">src/test/recovery</code>.
+ </p></li><li class="listitem"><p>
+ Tests for logical replication,
+ located in <code class="filename">src/test/subscription</code>.
+ </p></li><li class="listitem"><p>
+ Tests of client programs, located under <code class="filename">src/bin</code>.
+ </p></li></ul></div><p>
+ When using <code class="literal">installcheck</code> mode, these tests will create
+ and destroy test databases whose names
+ include <code class="literal">regression</code>, for
+ example <code class="literal">pl_regression</code>
+ or <code class="literal">contrib_regression</code>. Beware of
+ using <code class="literal">installcheck</code> mode with an installation that has
+ any non-test databases named that way.
+ </p><p>
+ Some of these auxiliary test suites use the TAP infrastructure explained
+ in <a class="xref" href="regress-tap.html" title="33.4. TAP Tests">Section 33.4</a>.
+ The TAP-based tests are run only when PostgreSQL was configured with the
+ option <code class="option">--enable-tap-tests</code>. This is recommended for
+ development, but can be omitted if there is no suitable Perl installation.
+ </p><p>
+ Some test suites are not run by default, either because they are not secure
+ to run on a multiuser system or because they require special software. You
+ can decide which test suites to run additionally by setting the
+ <code class="command">make</code> or environment variable
+ <code class="varname">PG_TEST_EXTRA</code> to a whitespace-separated list, for
+ example:
+</p><pre class="programlisting">
+make check-world PG_TEST_EXTRA='kerberos ldap ssl'
+</pre><p>
+ The following values are currently supported:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">kerberos</code></span></dt><dd><p>
+ Runs the test suite under <code class="filename">src/test/kerberos</code>. This
+ requires an MIT Kerberos installation and opens TCP/IP listen sockets.
+ </p></dd><dt><span class="term"><code class="literal">ldap</code></span></dt><dd><p>
+ Runs the test suite under <code class="filename">src/test/ldap</code>. This
+ requires an <span class="productname">OpenLDAP</span> installation and opens
+ TCP/IP listen sockets.
+ </p></dd><dt><span class="term"><code class="literal">ssl</code></span></dt><dd><p>
+ Runs the test suite under <code class="filename">src/test/ssl</code>. This opens TCP/IP listen sockets.
+ </p></dd><dt><span class="term"><code class="literal">wal_consistency_checking</code></span></dt><dd><p>
+ Uses <code class="literal">wal_consistency_checking=all</code> while running
+ certain tests under <code class="filename">src/test/recovery</code>. Not
+ enabled by default because it is resource intensive.
+ </p></dd></dl></div><p>
+
+ Tests for features that are not supported by the current build
+ configuration are not run even if they are mentioned in
+ <code class="varname">PG_TEST_EXTRA</code>.
+ </p><p>
+ In addition, there are tests in <code class="filename">src/test/modules</code>
+ which will be run by <code class="literal">make check-world</code> but not
+ by <code class="literal">make installcheck-world</code>. This is because they
+ install non-production extensions or have other side-effects that are
+ considered undesirable for a production installation. You can
+ use <code class="literal">make install</code> and <code class="literal">make
+ installcheck</code> in one of those subdirectories if you wish,
+ but it's not recommended to do so with a non-test server.
+ </p></div><div class="sect2" id="id-1.6.20.5.6"><div class="titlepage"><div><div><h3 class="title">33.1.4. Locale and Encoding</h3></div></div></div><p>
+ By default, tests using a temporary installation use the
+ locale defined in the current environment and the corresponding
+ database encoding as determined by <code class="command">initdb</code>. It
+ can be useful to test different locales by setting the appropriate
+ environment variables, for example:
+</p><pre class="screen">
+make check LANG=C
+make check LC_COLLATE=en_US.utf8 LC_CTYPE=fr_CA.utf8
+</pre><p>
+ For implementation reasons, setting <code class="envar">LC_ALL</code> does not
+ work for this purpose; all the other locale-related environment
+ variables do work.
+ </p><p>
+ When testing against an existing installation, the locale is
+ determined by the existing database cluster and cannot be set
+ separately for the test run.
+ </p><p>
+ You can also choose the database encoding explicitly by setting
+ the variable <code class="envar">ENCODING</code>, for example:
+</p><pre class="screen">
+make check LANG=C ENCODING=EUC_JP
+</pre><p>
+ Setting the database encoding this way typically only makes sense
+ if the locale is C; otherwise the encoding is chosen automatically
+ from the locale, and specifying an encoding that does not match
+ the locale will result in an error.
+ </p><p>
+ The database encoding can be set for tests against either a temporary or
+ an existing installation, though in the latter case it must be
+ compatible with the installation's locale.
+ </p></div><div class="sect2" id="id-1.6.20.5.7"><div class="titlepage"><div><div><h3 class="title">33.1.5. Custom Server Settings</h3></div></div></div><p>
+ Custom server settings to use when running a regression test suite can be
+ set in the <code class="varname">PGOPTIONS</code> environment variable (for settings
+ that allow this):
+</p><pre class="screen">
+make check PGOPTIONS="-c force_parallel_mode=regress -c work_mem=50MB"
+</pre><p>
+ When running against a temporary installation, custom settings can also be
+ set by supplying a pre-written <code class="filename">postgresql.conf</code>:
+</p><pre class="screen">
+echo 'log_checkpoints = on' &gt; test_postgresql.conf
+echo 'work_mem = 50MB' &gt;&gt; test_postgresql.conf
+make check EXTRA_REGRESS_OPTS="--temp-config=test_postgresql.conf"
+</pre><p>
+ </p><p>
+ This can be useful to enable additional logging, adjust resource limits,
+ or enable extra run-time checks such as <a class="xref" href="runtime-config-developer.html#GUC-DEBUG-DISCARD-CACHES">debug_discard_caches</a>.
+ </p></div><div class="sect2" id="id-1.6.20.5.8"><div class="titlepage"><div><div><h3 class="title">33.1.6. Extra Tests</h3></div></div></div><p>
+ The core regression test suite contains a few test files that are not
+ run by default, because they might be platform-dependent or take a
+ very long time to run. You can run these or other extra test
+ files by setting the variable <code class="envar">EXTRA_TESTS</code>. For
+ example, to run the <code class="literal">numeric_big</code> test:
+</p><pre class="screen">
+make check EXTRA_TESTS=numeric_big
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="regress.html" title="Chapter 33. Regression Tests">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="regress-evaluation.html" title="33.2. Test Evaluation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 33. Regression Tests </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 33.2. Test Evaluation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/regress-tap.html b/doc/src/sgml/html/regress-tap.html
new file mode 100644
index 0000000..eb95c0f
--- /dev/null
+++ b/doc/src/sgml/html/regress-tap.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>33.4. TAP Tests</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="regress-variant.html" title="33.3. Variant Comparison Files" /><link rel="next" href="regress-coverage.html" title="33.5. Test Coverage Examination" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">33.4. TAP Tests</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="regress-variant.html" title="33.3. Variant Comparison Files">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><th width="60%" align="center">Chapter 33. Regression Tests</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="regress-coverage.html" title="33.5. Test Coverage Examination">Next</a></td></tr></table><hr /></div><div class="sect1" id="REGRESS-TAP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">33.4. TAP Tests</h2></div></div></div><p>
+ Various tests, particularly the client program tests
+ under <code class="filename">src/bin</code>, use the Perl TAP tools and are run
+ using the Perl testing program <code class="command">prove</code>. You can pass
+ command-line options to <code class="command">prove</code> by setting
+ the <code class="command">make</code> variable <code class="varname">PROVE_FLAGS</code>, for example:
+</p><pre class="programlisting">
+make -C src/bin check PROVE_FLAGS='--timer'
+</pre><p>
+ See the manual page of <code class="command">prove</code> for more information.
+ </p><p>
+ The <code class="command">make</code> variable <code class="varname">PROVE_TESTS</code>
+ can be used to define a whitespace-separated list of paths relative
+ to the <code class="filename">Makefile</code> invoking <code class="command">prove</code>
+ to run the specified subset of tests instead of the default
+ <code class="filename">t/*.pl</code>. For example:
+</p><pre class="programlisting">
+make check PROVE_TESTS='t/001_test1.pl t/003_test3.pl'
+</pre><p>
+ </p><p>
+ The TAP tests require the Perl module <code class="literal">IPC::Run</code>.
+ This module is available from CPAN or an operating system package.
+ They also require <span class="productname">PostgreSQL</span> to be
+ configured with the option <code class="option">--enable-tap-tests</code>.
+ </p><p>
+ Generically speaking, the TAP tests will test the executables in a
+ previously-installed installation tree if you say <code class="literal">make
+ installcheck</code>, or will build a new local installation tree from
+ current sources if you say <code class="literal">make check</code>. In either
+ case they will initialize a local instance (data directory) and
+ transiently run a server in it. Some of these tests run more than one
+ server. Thus, these tests can be fairly resource-intensive.
+ </p><p>
+ It's important to realize that the TAP tests will start test server(s)
+ even when you say <code class="literal">make installcheck</code>; this is unlike
+ the traditional non-TAP testing infrastructure, which expects to use an
+ already-running test server in that case. Some PostgreSQL
+ subdirectories contain both traditional-style and TAP-style tests,
+ meaning that <code class="literal">make installcheck</code> will produce a mix of
+ results from temporary servers and the already-running test server.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="regress-variant.html" title="33.3. Variant Comparison Files">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="regress-coverage.html" title="33.5. Test Coverage Examination">Next</a></td></tr><tr><td width="40%" align="left" valign="top">33.3. Variant Comparison Files </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 33.5. Test Coverage Examination</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/regress-variant.html b/doc/src/sgml/html/regress-variant.html
new file mode 100644
index 0000000..fd158cb
--- /dev/null
+++ b/doc/src/sgml/html/regress-variant.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>33.3. Variant Comparison Files</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="regress-evaluation.html" title="33.2. Test Evaluation" /><link rel="next" href="regress-tap.html" title="33.4. TAP Tests" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">33.3. Variant Comparison Files</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="regress-evaluation.html" title="33.2. Test Evaluation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><th width="60%" align="center">Chapter 33. Regression Tests</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="regress-tap.html" title="33.4. TAP Tests">Next</a></td></tr></table><hr /></div><div class="sect1" id="REGRESS-VARIANT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">33.3. Variant Comparison Files</h2></div></div></div><p>
+ Since some of the tests inherently produce environment-dependent
+ results, we have provided ways to specify alternate <span class="quote">“<span class="quote">expected</span>”</span>
+ result files. Each regression test can have several comparison files
+ showing possible results on different platforms. There are two
+ independent mechanisms for determining which comparison file is used
+ for each test.
+ </p><p>
+ The first mechanism allows comparison files to be selected for
+ specific platforms. There is a mapping file,
+ <code class="filename">src/test/regress/resultmap</code>, that defines
+ which comparison file to use for each platform.
+ To eliminate bogus test <span class="quote">“<span class="quote">failures</span>”</span> for a particular platform,
+ you first choose or make a variant result file, and then add a line to the
+ <code class="filename">resultmap</code> file.
+ </p><p>
+ Each line in the mapping file is of the form
+</p><pre class="synopsis">
+testname:output:platformpattern=comparisonfilename
+</pre><p>
+ The test name is just the name of the particular regression test
+ module. The output value indicates which output file to check. For the
+ standard regression tests, this is always <code class="literal">out</code>. The
+ value corresponds to the file extension of the output file.
+ The platform pattern is a pattern in the style of the Unix
+ tool <code class="command">expr</code> (that is, a regular expression with an implicit
+ <code class="literal">^</code> anchor at the start). It is matched against the
+ platform name as printed by <code class="command">config.guess</code>.
+ The comparison file name is the base name of the substitute result
+ comparison file.
+ </p><p>
+ For example: some systems lack a working <code class="literal">strtof</code> function,
+ for which our workaround causes rounding errors in the
+ <code class="filename">float4</code> regression test.
+ Therefore, we provide a variant comparison file,
+ <code class="filename">float4-misrounded-input.out</code>, which includes
+ the results to be expected on these systems. To silence the bogus
+ <span class="quote">“<span class="quote">failure</span>”</span> message on <span class="systemitem">HP-UX 10</span>
+ platforms, <code class="filename">resultmap</code> includes:
+</p><pre class="programlisting">
+float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out
+</pre><p>
+ which will trigger on any machine where the output of
+ <code class="command">config.guess</code> matches <code class="literal">hppa.*-hp-hpux10.*</code>.
+ Other lines in <code class="filename">resultmap</code> select the variant comparison
+ file for other platforms where it's appropriate.
+ </p><p>
+ The second selection mechanism for variant comparison files is
+ much more automatic: it simply uses the <span class="quote">“<span class="quote">best match</span>”</span> among
+ several supplied comparison files. The regression test driver
+ script considers both the standard comparison file for a test,
+ <code class="literal"><em class="replaceable"><code>testname</code></em>.out</code>, and variant files named
+ <code class="literal"><em class="replaceable"><code>testname</code></em>_<em class="replaceable"><code>digit</code></em>.out</code>
+ (where the <em class="replaceable"><code>digit</code></em> is any single digit
+ <code class="literal">0</code>-<code class="literal">9</code>). If any such file is an exact match,
+ the test is considered to pass; otherwise, the one that generates
+ the shortest diff is used to create the failure report. (If
+ <code class="filename">resultmap</code> includes an entry for the particular
+ test, then the base <em class="replaceable"><code>testname</code></em> is the substitute
+ name given in <code class="filename">resultmap</code>.)
+ </p><p>
+ For example, for the <code class="literal">char</code> test, the comparison file
+ <code class="filename">char.out</code> contains results that are expected
+ in the <code class="literal">C</code> and <code class="literal">POSIX</code> locales, while
+ the file <code class="filename">char_1.out</code> contains results sorted as
+ they appear in many other locales.
+ </p><p>
+ The best-match mechanism was devised to cope with locale-dependent
+ results, but it can be used in any situation where the test results
+ cannot be predicted easily from the platform name alone. A limitation of
+ this mechanism is that the test driver cannot tell which variant is
+ actually <span class="quote">“<span class="quote">correct</span>”</span> for the current environment; it will just pick
+ the variant that seems to work best. Therefore it is safest to use this
+ mechanism only for variant results that you are willing to consider
+ equally valid in all contexts.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="regress-evaluation.html" title="33.2. Test Evaluation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="regress.html" title="Chapter 33. Regression Tests">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="regress-tap.html" title="33.4. TAP Tests">Next</a></td></tr><tr><td width="40%" align="left" valign="top">33.2. Test Evaluation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 33.4. TAP Tests</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/regress.html b/doc/src/sgml/html/regress.html
new file mode 100644
index 0000000..d1322de
--- /dev/null
+++ b/doc/src/sgml/html/regress.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 33. Regression Tests</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="jit-extensibility.html" title="32.4. Extensibility" /><link rel="next" href="regress-run.html" title="33.1. Running the Tests" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 33. Regression Tests</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="jit-extensibility.html" title="32.4. Extensibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="regress-run.html" title="33.1. Running the Tests">Next</a></td></tr></table><hr /></div><div class="chapter" id="REGRESS"><div class="titlepage"><div><div><h2 class="title">Chapter 33. Regression Tests</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="regress-run.html">33.1. Running the Tests</a></span></dt><dd><dl><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.3">33.1.1. Running the Tests Against a Temporary Installation</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.4">33.1.2. Running the Tests Against an Existing Installation</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.5">33.1.3. Additional Test Suites</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.6">33.1.4. Locale and Encoding</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.7">33.1.5. Custom Server Settings</a></span></dt><dt><span class="sect2"><a href="regress-run.html#id-1.6.20.5.8">33.1.6. Extra Tests</a></span></dt></dl></dd><dt><span class="sect1"><a href="regress-evaluation.html">33.2. Test Evaluation</a></span></dt><dd><dl><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.6">33.2.1. Error Message Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.7">33.2.2. Locale Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.8">33.2.3. Date and Time Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.9">33.2.4. Floating-Point Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.10">33.2.5. Row Ordering Differences</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.11">33.2.6. Insufficient Stack Depth</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.12">33.2.7. The <span class="quote">“<span class="quote">random</span>”</span> Test</a></span></dt><dt><span class="sect2"><a href="regress-evaluation.html#id-1.6.20.6.13">33.2.8. Configuration Parameters</a></span></dt></dl></dd><dt><span class="sect1"><a href="regress-variant.html">33.3. Variant Comparison Files</a></span></dt><dt><span class="sect1"><a href="regress-tap.html">33.4. TAP Tests</a></span></dt><dt><span class="sect1"><a href="regress-coverage.html">33.5. Test Coverage Examination</a></span></dt></dl></div><a id="id-1.6.20.2" class="indexterm"></a><a id="id-1.6.20.3" class="indexterm"></a><p>
+ The regression tests are a comprehensive set of tests for the SQL
+ implementation in <span class="productname">PostgreSQL</span>. They test
+ standard SQL operations as well as the extended capabilities of
+ <span class="productname">PostgreSQL</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jit-extensibility.html" title="32.4. Extensibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="regress-run.html" title="33.1. Running the Tests">Next</a></td></tr><tr><td width="40%" align="left" valign="top">32.4. Extensibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 33.1. Running the Tests</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release-15-1.html b/doc/src/sgml/html/release-15-1.html
new file mode 100644
index 0000000..e594db5
--- /dev/null
+++ b/doc/src/sgml/html/release-15-1.html
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>E.4. Release 15.1</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release-15-2.html" title="E.3. Release 15.2" /><link rel="next" href="release-15.html" title="E.5. Release 15" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">E.4. Release 15.1</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release-15-2.html" title="E.3. Release 15.2">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><th width="60%" align="center">Appendix E. Release Notes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release-15.html" title="E.5. Release 15">Next</a></td></tr></table><hr /></div><div class="sect1" id="RELEASE-15-1"><div class="titlepage"><div><div><h2 class="title" style="clear: both">E.4. Release 15.1</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="release-15-1.html#id-1.11.6.8.4">E.4.1. Migration to Version 15.1</a></span></dt><dt><span class="sect2"><a href="release-15-1.html#id-1.11.6.8.5">E.4.2. Changes</a></span></dt></dl></div><p><strong>Release date: </strong>2022-11-10</p><p>
+ This release contains a variety of fixes from 15.0.
+ For information about new features in major release 15, see
+ <a class="xref" href="release-15.html" title="E.5. Release 15">Section E.5</a>.
+ </p><div class="sect2" id="id-1.11.6.8.4"><div class="titlepage"><div><div><h3 class="title">E.4.1. Migration to Version 15.1</h3></div></div></div><p>
+ A dump/restore is not required for those running 15.X.
+ </p><p>
+ However, if you regularly create and drop tables exceeding 1GB,
+ see the first changelog entry below.
+ </p></div><div class="sect2" id="id-1.11.6.8.5"><div class="titlepage"><div><div><h3 class="title">E.4.2. Changes</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Fix failure to remove non-first segments of large tables
+ (Tom Lane)
+ </p><p>
+ <span class="productname">PostgreSQL</span> splits large tables into
+ multiple files (normally with 1GB per file). The logic for dropping
+ a table was broken and would miss removing all but the first such
+ file, in two cases: drops of temporary tables and WAL replay of
+ drops of regular tables. Applications that routinely create
+ multi-gigabyte temporary tables could suffer significant disk space
+ leakage.
+ </p><p>
+ Orphaned temporary-table files are removed during postmaster start,
+ so the mere act of updating to 15.1 is sufficient to clear any
+ leaked temporary-table storage. However, if you suffered any
+ database crashes while using 15.0, and there might have been
+ large tables dropped just before such crashes, it's advisable
+ to check the database directories for files named according to the
+ pattern
+ <code class="literal"><em class="replaceable"><code>NNNN</code></em>.<em class="replaceable"><code>NN</code></em></code>.
+ If there is no matching file named
+ just <code class="literal"><em class="replaceable"><code>NNNN</code></em></code> (without
+ the <code class="literal">.<em class="replaceable"><code>NN</code></em></code> suffix), these
+ files should be removed manually.
+ </p></li><li class="listitem"><p>
+ Fix handling of <code class="literal">DEFAULT</code> tokens that appear
+ in a multi-row <code class="literal">VALUES</code> clause of an
+ <code class="command">INSERT</code> on an updatable view (Tom Lane)
+ </p><p>
+ This oversight could lead to <span class="quote">“<span class="quote">cache lookup failed for
+ type</span>”</span> errors, or in older branches even to crashes.
+ </p></li><li class="listitem"><p>
+ Disallow rules named <code class="literal">_RETURN</code> that are
+ not <code class="literal">ON SELECT</code> (Tom Lane)
+ </p><p>
+ This avoids confusion between a view's <code class="literal">ON SELECT</code>
+ rule and any other rules it may have.
+ </p></li><li class="listitem"><p>
+ Avoid failure in <code class="command">EXPLAIN VERBOSE</code> for a query
+ using <code class="literal">SEARCH BREADTH FIRST</code> with constant
+ initial values (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Prevent use of <code class="command">MERGE</code> on a partitioned table with
+ foreign-table partitions (Álvaro Herrera)
+ </p><p>
+ The case isn't supported, and previously threw an incomprehensible
+ error.
+ </p></li><li class="listitem"><p>
+ Fix construction of per-partition foreign key constraints while
+ doing <code class="command">ALTER TABLE ATTACH PARTITION</code>
+ (Jehan-Guillaume de Rorthais, Álvaro Herrera)
+ </p><p>
+ Previously, incorrect or duplicate constraints could be constructed
+ for the newly-added partition.
+ </p></li><li class="listitem"><p>
+ Fix planner failure with extended statistics on partitioned or
+ inherited tables (Richard Guo, Justin Pryzby)
+ </p><p>
+ Some cases failed with <span class="quote">“<span class="quote">cache lookup failed for statistics
+ object</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Fix mis-ordering of WAL operations in fast insert path for GIN
+ indexes (Matthias van de Meent, Zhang Mingli)
+ </p><p>
+ This mistake is not known to have any negative consequences within
+ core <span class="productname">PostgreSQL</span>, but it did cause issues
+ for some extensions.
+ </p></li><li class="listitem"><p>
+ Fix bugs in logical decoding when replay starts from a point
+ between the beginning of a transaction and the beginning of its
+ subtransaction (Masahiko Sawada, Kuroda Hayato)
+ </p><p>
+ These errors could lead to assertion failures in debug builds, and
+ otherwise to memory leaks.
+ </p></li><li class="listitem"><p>
+ Accept interrupts in more places during logical decoding (Amit
+ Kapila, Masahiko Sawada)
+ </p><p>
+ This ameliorates problems with slow shutdown of replication workers.
+ </p></li><li class="listitem"><p>
+ Prevent attempts to replicate into a foreign-table partition in
+ replication workers (Shi Yu, Tom Lane)
+ </p><p>
+ Although partitioned tables can have foreign tables as partitions,
+ replicating into such a partition isn't currently supported.
+ The logical replication worker process would crash if it was
+ attempted. Now, an error is thrown.
+ </p></li><li class="listitem"><p>
+ Avoid crash after function syntax error in replication workers
+ (Maxim Orlov, Anton Melnikov, Masahiko Sawada, Tom Lane)
+ </p><p>
+ If a syntax error occurred in a SQL-language or PL/pgSQL-language
+ <code class="command">CREATE FUNCTION</code> or <code class="command">DO</code> command
+ executed in a logical replication worker, the worker process would
+ crash with a null pointer dereference or assertion failure.
+ </p></li><li class="listitem"><p>
+ Avoid double call of the shutdown callback of an archiver module
+ (Nathan Bossart, Bharath Rupireddy)
+ </p></li><li class="listitem"><p>
+ Add plan-time check for attempted access to a table that has no
+ table access method (Tom Lane)
+ </p><p>
+ This prevents a crash in some catalog-corruption scenarios, for
+ example use of a view whose <code class="literal">ON SELECT</code> rule is
+ missing.
+ </p></li><li class="listitem"><p>
+ Prevent postmaster crash when shared-memory state is corrupted
+ (Tom Lane)
+ </p><p>
+ The postmaster process is supposed to survive and initiate a
+ database restart if shared memory becomes corrupted, but one
+ bit of code was being insufficiently cautious about that.
+ </p></li><li class="listitem"><p>
+ In <span class="application">libpq</span>, handle single-row mode
+ correctly when pipelining (Denis Laxalde)
+ </p><p>
+ The single-row flag was not reset at the correct time if pipeline
+ mode was also active.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">psql</span>'s exit status when a
+ command-line query is canceled (Peter Eisentraut)
+ </p><p>
+ <code class="literal">psql -c <em class="replaceable"><code>query</code></em></code> would
+ exit successfully if the query was canceled. Fix it to exit with
+ nonzero status, as in other error cases.
+ </p></li><li class="listitem"><p>
+ Allow cross-platform tablespace relocation
+ in <span class="application">pg_basebackup</span> (Robert Haas)
+ </p><p>
+ Allow the remote path in <code class="option">--tablespace-mapping</code> to be
+ either a Unix-style or Windows-style absolute path, since the source
+ server could be on a different OS than the local system.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">pg_dump</span>'s failure to dump comments
+ attached to some <code class="literal">CHECK</code> constraints (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix <code class="command">CREATE DATABASE</code> to allow
+ its <code class="literal">oid</code> parameter to exceed
+ 2<sup>31</sup> (Tom Lane)
+ </p><p>
+ This oversight prevented <span class="application">pg_upgrade</span> from
+ succeeding when the source installation contained databases with
+ OIDs larger than that.
+ </p></li><li class="listitem"><p>
+ In <span class="application">pg_stat_statements</span>, fix access to
+ already-freed memory (zhaoqigui)
+ </p><p>
+ This occurred if <span class="application">pg_stat_statements</span>
+ tracked a <code class="command">ROLLBACK</code> command issued via extended
+ query protocol. In debug builds it consistently led to an assertion
+ failure. In production builds there would often be no visible ill
+ effect; but if the freed memory had already been reused, the likely
+ result would be to store garbage for the query string.
+ </p></li><li class="listitem"><p>
+ Fix incompatibilities with LLVM 15 (Thomas Munro, Andres Freund)
+ </p></li><li class="listitem"><p>
+ Allow use of <code class="function">__sync_lock_test_and_set()</code> for
+ spinlocks on any machine (Tom Lane)
+ </p><p>
+ This eases porting to new machine architectures, at least if you're
+ using a compiler that supports this GCC builtin function.
+ </p></li><li class="listitem"><p>
+ Rename symbol <code class="literal">REF</code> to <code class="literal">REF_P</code> to
+ avoid compile failure on recent macOS (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Avoid using <code class="function">sprintf</code>, to avoid compile-time
+ deprecation warnings (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Update time zone data files to <span class="application">tzdata</span>
+ release 2022f for DST law changes in Chile, Fiji, Iran, Jordan,
+ Mexico, Palestine, and Syria, plus historical corrections for Chile,
+ Crimea, Iran, and Mexico.
+ </p><p>
+ Also, the Europe/Kiev zone has been renamed to Europe/Kyiv.
+ Also, the following zones have been merged into nearby,
+ more-populous zones whose clocks have agreed with them since 1970:
+ Antarctica/Vostok, Asia/Brunei,
+ Asia/Kuala_Lumpur, Atlantic/Reykjavik, Europe/Amsterdam,
+ Europe/Copenhagen, Europe/Luxembourg, Europe/Monaco, Europe/Oslo,
+ Europe/Stockholm, Indian/Christmas, Indian/Cocos, Indian/Kerguelen,
+ Indian/Mahe, Indian/Reunion, Pacific/Chuuk, Pacific/Funafuti,
+ Pacific/Majuro, Pacific/Pohnpei, Pacific/Wake and Pacific/Wallis.
+ (This indirectly affects zones that were already links to one of
+ these: Arctic/Longyearbyen, Atlantic/Jan_Mayen, Iceland,
+ Pacific/Ponape, Pacific/Truk, and Pacific/Yap.) America/Nipigon,
+ America/Rainy_River, America/Thunder_Bay, Europe/Uzhgorod, and
+ Europe/Zaporozhye were also merged into nearby zones after
+ discovering that their claimed post-1970 differences from those
+ zones seem to have been errors.
+ In all these cases, the previous zone name remains as an alias;
+ but the actual data is that of the zone that was merged into.
+ </p><p>
+ These zone mergers result in loss of pre-1970 timezone history for
+ the merged zones, which may be troublesome for applications
+ expecting consistency of <code class="type">timestamptz</code> display. As an
+ example, the stored value <code class="literal">1944-06-01 12:00 UTC</code>
+ would previously display as <code class="literal">1944-06-01
+ 13:00:00+01</code> if the Europe/Stockholm zone is selected, but
+ now it will read out as <code class="literal">1944-06-01 14:00:00+02</code>.
+ </p><p>
+ It is possible to build the time zone data files with options that
+ will restore the older zone data, but that choice also inserts a lot
+ of other old (and typically poorly-attested) zone data, resulting in
+ more total changes from the previous release than accepting these
+ upstream changes does. <span class="productname">PostgreSQL</span> has
+ chosen to ship the <span class="productname">tzdb</span> data
+ as-recommended, and so far as we are aware most major operating
+ system distributions are doing likewise. However, if these changes
+ cause significant problems for your application, a possible solution
+ is to install a local build of the time zone data files using
+ <span class="productname">tzdb</span>'s backwards-compatibility options
+ (see their <code class="literal">PACKRATDATA</code>
+ and <code class="literal">PACKRATLIST</code> options).
+ </p></li></ul></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release-15-2.html" title="E.3. Release 15.2">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release-15.html" title="E.5. Release 15">Next</a></td></tr><tr><td width="40%" align="left" valign="top">E.3. Release 15.2 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> E.5. Release 15</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release-15-2.html b/doc/src/sgml/html/release-15-2.html
new file mode 100644
index 0000000..63e98fa
--- /dev/null
+++ b/doc/src/sgml/html/release-15-2.html
@@ -0,0 +1,433 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>E.3. Release 15.2</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release-15-3.html" title="E.2. Release 15.3" /><link rel="next" href="release-15-1.html" title="E.4. Release 15.1" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">E.3. Release 15.2</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release-15-3.html" title="E.2. Release 15.3">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><th width="60%" align="center">Appendix E. Release Notes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release-15-1.html" title="E.4. Release 15.1">Next</a></td></tr></table><hr /></div><div class="sect1" id="RELEASE-15-2"><div class="titlepage"><div><div><h2 class="title" style="clear: both">E.3. Release 15.2</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="release-15-2.html#id-1.11.6.7.4">E.3.1. Migration to Version 15.2</a></span></dt><dt><span class="sect2"><a href="release-15-2.html#id-1.11.6.7.5">E.3.2. Changes</a></span></dt></dl></div><p><strong>Release date: </strong>2023-02-09</p><p>
+ This release contains a variety of fixes from 15.1.
+ For information about new features in major release 15, see
+ <a class="xref" href="release-15.html" title="E.5. Release 15">Section E.5</a>.
+ </p><div class="sect2" id="id-1.11.6.7.4"><div class="titlepage"><div><div><h3 class="title">E.3.1. Migration to Version 15.2</h3></div></div></div><p>
+ A dump/restore is not required for those running 15.X.
+ </p><p>
+ However, if you are upgrading from a version earlier than 15.1,
+ see <a class="xref" href="release-15-1.html" title="E.4. Release 15.1">Section E.4</a>.
+ </p></div><div class="sect2" id="id-1.11.6.7.5"><div class="titlepage"><div><div><h3 class="title">E.3.2. Changes</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <span class="application">libpq</span> can leak memory contents after
+ GSSAPI transport encryption initiation fails (Jacob Champion)
+ </p><p>
+ A modified server, or an unauthenticated man-in-the-middle, can
+ send a not-zero-terminated error message during setup of GSSAPI
+ (Kerberos) transport encryption. <span class="application">libpq</span>
+ will then copy that string, as well as following bytes in
+ application memory up to the next zero byte, to its error report.
+ Depending on what the calling application does with the error
+ report, this could result in disclosure of application memory
+ contents. There is also a small probability of a crash due to
+ reading beyond the end of memory. Fix by properly zero-terminating
+ the server message.
+ (CVE-2022-41862)
+ </p></li><li class="listitem"><p>
+ Fix calculation of which <code class="literal">GENERATED</code> columns need
+ to be updated in child tables during an <code class="command">UPDATE</code> on
+ a partitioned table or inheritance tree (Amit Langote, Tom Lane)
+ </p><p>
+ This fixes failure to update <code class="literal">GENERATED</code> columns
+ that do not exist in the parent table, or that have different
+ dependencies than are in the parent column's generation expression.
+ </p></li><li class="listitem"><p>
+ Fix possible failure of <code class="command">MERGE</code> to compute
+ <code class="literal">GENERATED</code> columns (Dean Rasheed)
+ </p><p>
+ When the first row-level action of the <code class="command">MERGE</code> was
+ an <code class="literal">UPDATE</code>, any
+ subsequent <code class="literal">INSERT</code> actions would fail to
+ compute <code class="literal">GENERATED</code> columns that were deemed
+ unnecessary to compute for the <code class="literal">UPDATE</code> action
+ (due to not depending on any of the <code class="literal">UPDATE</code> target
+ columns).
+ </p></li><li class="listitem"><p>
+ Fix <code class="command">MERGE</code>'s check for
+ unreachable <code class="literal">WHEN</code> clauses (Dean Rasheed)
+ </p><p>
+ A <code class="literal">WHEN</code> clause following an
+ unconditional <code class="literal">WHEN</code> clause should be rejected as
+ unreachable, but this case was not always detected.
+ </p></li><li class="listitem"><p>
+ Fix <code class="command">MERGE</code>'s rule-detection test (Dean Rasheed)
+ </p><p>
+ <code class="command">MERGE</code> is not supported on tables with rules;
+ but it also failed on tables that once had rules but no longer do.
+ </p></li><li class="listitem"><p>
+ In <code class="command">MERGE</code>, don't count a <code class="literal">DO
+ NOTHING</code> action as a processed tuple (Álvaro Herrera)
+ </p><p>
+ This makes the code's behavior match the documentation.
+ </p></li><li class="listitem"><p>
+ Allow a <code class="literal">WITH RECURSIVE ... CYCLE</code> CTE
+ to access its output column (Tom Lane)
+ </p><p>
+ A reference to the <code class="literal">SET</code> column from within the CTE
+ would fail with <span class="quote">“<span class="quote">cache lookup failed for type 0</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Fix handling of pending inserts when doing a bulk insertion to a
+ foreign table (Etsuro Fujita)
+ </p><p>
+ In some cases pending insertions were not flushed to the FDW soon
+ enough, leading to logical inconsistencies, for
+ example <code class="literal">BEFORE ROW</code> triggers not seeing rows they
+ should be able to see.
+ </p></li><li class="listitem"><p>
+ Allow <code class="literal">REPLICA IDENTITY</code>
+ to be set on an index that's not (yet) valid (Tom Lane)
+ </p><p>
+ When <span class="application">pg_dump</span> dumps a partitioned index
+ that's marked <code class="literal">REPLICA IDENTITY</code>, it generates a
+ command sequence that applies <code class="literal">REPLICA IDENTITY</code>
+ before the partitioned index has been marked valid, causing restore
+ to fail. There seems no very good reason to prohibit doing it in
+ that order, so allow it. The marking will have no effect anyway
+ until the index becomes valid.
+ </p></li><li class="listitem"><p>
+ Fix handling of <code class="literal">DEFAULT</code> markers in rules that
+ perform an <code class="command">INSERT</code> from a
+ multi-row <code class="literal">VALUES</code> list (Dean Rasheed)
+ </p><p>
+ In some cases a <code class="literal">DEFAULT</code> marker would not get
+ replaced with the proper default-value expression, leading to
+ an <span class="quote">“<span class="quote">unrecognized node type</span>”</span> error.
+ </p></li><li class="listitem"><p>
+ Reject uses of undefined variables in <code class="type">jsonpath</code>
+ existence checks (Alexander Korotkov, David G. Johnston)
+ </p><p>
+ While <code class="type">jsonpath</code> match operators threw an error for an
+ undefined variable in the path pattern, the existence operators
+ silently treated it as a match.
+ </p></li><li class="listitem"><p>
+ Fix <code class="type">jsonb</code> subscripting to cope with toasted subscript
+ values (Tom Lane, David G. Johnston)
+ </p><p>
+ Using a text value fetched directly from a table as
+ a <code class="type">jsonb</code> subscript was likely to fail.
+ Fetches would usually not find any matching element.
+ Assignments could store the value with a garbage key,
+ although keys long enough to cause that problem are probably rare in
+ the field.
+ </p></li><li class="listitem"><p>
+ Fix edge-case data corruption in parallel hash joins (Dmitry Astapov)
+ </p><p>
+ If the final chunk of a large tuple being written out to a temporary
+ file was exactly 32760 bytes, it would be corrupted due to a
+ fencepost bug. The query would typically fail later with
+ corrupted-data symptoms.
+ </p></li><li class="listitem"><p>
+ Honor non-default settings
+ of <code class="varname">checkpoint_completion_target</code>
+ (Bharath Rupireddy)
+ </p><p>
+ Internal state was not updated after a change
+ in <code class="varname">checkpoint_completion_target</code>, possibly
+ resulting in performing checkpoint I/O faster or slower than
+ desired, especially if that setting was changed on-the-fly.
+ </p></li><li class="listitem"><p>
+ Log the correct ending timestamp
+ in <code class="varname">recovery_target_xid</code> mode (Tom Lane)
+ </p><p>
+ When ending recovery based on the <code class="varname">recovery_target_xid</code>
+ setting with <code class="varname">recovery_target_inclusive</code>
+ = <code class="literal">off</code>, we printed an incorrect timestamp (always
+ 2000-01-01) in the <span class="quote">“<span class="quote">recovery stopping before
+ ... transaction</span>”</span> log message.
+ </p></li><li class="listitem"><p>
+ Improve error reporting for some buffered file read failures
+ (Peter Eisentraut)
+ </p><p>
+ Correctly report a short read, giving the numbers of bytes desired
+ and actually read, instead of reporting an irrelevant error code.
+ Most places got this right already, but some recently-written
+ replication logic did not.
+ </p></li><li class="listitem"><p>
+ Remove arbitrary limit on number of elements
+ in <code class="type">int2vector</code> and <code class="type">oidvector</code> (Tom Lane)
+ </p><p>
+ The input functions for these types previously rejected more than
+ 100 elements. With the introduction of the logical replication
+ column list feature, it's necessary to
+ accept <code class="type">int2vector</code>s having up to 1600 columns,
+ otherwise long column lists cause logical-replication failures.
+ </p></li><li class="listitem"><p>
+ In extended query protocol, avoid an immediate commit
+ after <code class="command">ANALYZE</code> if we're running a pipeline
+ (Tom Lane)
+ </p><p>
+ If there's not been an explicit <code class="command">BEGIN
+ TRANSACTION</code>, <code class="command">ANALYZE</code> would take it on
+ itself to commit, which should not happen within a pipelined series
+ of commands.
+ </p></li><li class="listitem"><p>
+ Reject cancel request packets having the wrong length
+ (Andrey Borodin)
+ </p><p>
+ The server would process a cancel request even if its length word
+ was too small. This led to reading beyond the end of the allocated
+ buffer. In theory that could cause a segfault, but it seems quite
+ unlikely to happen in practice, since the buffer would have to be
+ very close to the end of memory. The more likely outcome was a bogus
+ log message about wrong backend PID or cancel code. Complain about
+ the wrong length, instead.
+ </p></li><li class="listitem"><p>
+ Fix planner preprocessing oversights for window function run-condition
+ expressions (Richard Guo, David Rowley)
+ </p><p>
+ This could lead to planner errors such as <span class="quote">“<span class="quote">WindowFunc not
+ found in subplan target lists</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Fix possible dangling-pointer access during execution of window
+ function run-condition expressions (David Rowley)
+ </p><p>
+ In practice, because the run-condition optimization is only applied
+ to certain window functions that happen to all
+ return <code class="type">int8</code>, this only manifested as a problem on
+ 32-bit builds.
+ </p></li><li class="listitem"><p>
+ Add recursion and looping defenses in subquery pullup (Tom Lane)
+ </p><p>
+ A contrived query can result in deep recursion and unreasonable
+ amounts of time spent trying to flatten subqueries. A proper fix
+ for that seems unduly invasive for a back-patch, but we can at least
+ add stack depth checks and an interrupt check to allow the query to
+ be cancelled.
+ </p></li><li class="listitem"><p>
+ Fix planner issues when combining Memoize nodes with partitionwise
+ joins or parameterized nestloops (Richard Guo)
+ </p><p>
+ These errors could lead to not using Memoize in contexts where it
+ would be useful, or possibly to wrong query plans.
+ </p></li><li class="listitem"><p>
+ Fix partitionwise-join code to tolerate failure to produce a plan for
+ each partition (Tom Lane)
+ </p><p>
+ This could result in <span class="quote">“<span class="quote">could not devise a query plan for the
+ given query</span>”</span> errors.
+ </p></li><li class="listitem"><p>
+ Limit the amount of cleanup work done
+ by <code class="function">get_actual_variable_range</code> (Simon Riggs)
+ </p><p>
+ Planner runs occurring just after deletion of a large number of
+ tuples appearing at the end of an index could expend significant
+ amounts of work setting the <span class="quote">“<span class="quote">killed</span>”</span> bits for those
+ index entries. Limit the amount of work done in any one query by
+ giving up on this process after examining 100 heap pages. All the
+ cleanup will still happen eventually, but without so large a
+ performance hiccup.
+ </p></li><li class="listitem"><p>
+ Prevent the statistics machinery from getting confused when a
+ relation's relkind changes (Andres Freund)
+ </p><p>
+ Converting a table to a view could lead to crashes or assertion
+ failures.
+ </p></li><li class="listitem"><p>
+ Fix under-parenthesized display of <code class="literal">AT TIME ZONE</code>
+ constructs (Tom Lane)
+ </p><p>
+ This could result in dump/restore failures for rules or views in
+ which an argument of <code class="literal">AT TIME ZONE</code> is itself an
+ expression.
+ </p></li><li class="listitem"><p>
+ Prevent clobbering of cached parsetrees for utility statements in
+ SQL functions (Tom Lane, Daniel Gustafsson)
+ </p><p>
+ If a SQL-language function executes the same utility command more
+ than once within a single calling query, it could crash or report
+ strange errors such as <span class="quote">“<span class="quote">unrecognized node type</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Ensure that execution of full-text-search queries can be cancelled
+ while they are performing phrase matches (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix memory leak in hashing strings with nondeterministic collations
+ (Jeff Davis)
+ </p></li><li class="listitem"><p>
+ Fix deadlock between <code class="command">DROP DATABASE</code> and logical
+ replication worker process (Hou Zhijie)
+ </p><p>
+ This was caused by an ill-advised choice to block interrupts while
+ creating a logical replication slot in the worker. In version 15
+ that could lead to an undetected deadlock. In version 14, no
+ deadlock has been observed, but it's still a bad idea to block
+ interrupts while waiting for network I/O.
+ </p></li><li class="listitem"><p>
+ Clean up the <span class="application">libpq</span> connection object
+ after a failed replication connection attempt (Andres Freund)
+ </p><p>
+ The previous coding leaked the connection object. In background
+ code paths that's pretty harmless because the calling process will
+ give up and exit. But in commands such as <code class="command">CREATE
+ SUBSCRIPTION</code>, such a failure resulted in a small
+ session-lifespan memory leak.
+ </p></li><li class="listitem"><p>
+ In hot-standby servers, reduce processing effort for tracking XIDs
+ known to be active on the primary (Simon Riggs, Michail Nikolaev)
+ </p><p>
+ Insufficiently-aggressive cleanup of the KnownAssignedXids array
+ could lead to poor performance, particularly
+ when <code class="varname">max_connections</code> is set to a large value on
+ the standby.
+ </p></li><li class="listitem"><p>
+ Ignore invalidated logical-replication slots while determining
+ oldest catalog xmin (Sirisha Chamarthi)
+ </p><p>
+ A replication slot could prevent cleanup of dead tuples in the
+ system catalogs even after it becomes invalidated due to
+ exceeding <code class="varname">max_slot_wal_keep_size</code>. Thus, failure
+ of a replication consumer could lead to indefinitely-large catalog
+ bloat.
+ </p></li><li class="listitem"><p>
+ In logical decoding, notify the remote node when a transaction is
+ detected to have crashed (Hou Zhijie)
+ </p><p>
+ After a server restart, we'll re-stream the changes for transactions
+ occurring shortly before the restart. Some of these transactions
+ probably never completed; when we realize that one didn't we throw
+ away the relevant decoding state locally, but we neglected to tell
+ the subscriber about it. That led to the subscriber keeping useless
+ streaming files until it's next restarted.
+ </p></li><li class="listitem"><p>
+ Fix uninitialized-memory usage in logical decoding (Masahiko Sawada)
+ </p><p>
+ In certain cases, resumption of logical decoding could try to re-use
+ XID data that had already been freed, leading to unpredictable
+ behavior.
+ </p></li><li class="listitem"><p>
+ Acquire spinlock while updating shared state during logical decoding
+ context creation (Masahiko Sawada)
+ </p><p>
+ We neglected to acquire the appropriate lock while updating data
+ about two-phase transactions, potentially allowing other processes
+ to see inconsistent data.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">pgoutput</span> replication plug-in to not
+ send columns not listed in a table's replication column list
+ (Hou Zhijie)
+ </p><p>
+ <code class="literal">UPDATE</code> and <code class="literal">DELETE</code> events did
+ not pay attention to the configured column list, thus sending more
+ data than expected. This did not cause a problem when the receiver
+ is our built-in logical replication code, but it might confuse other
+ receivers, and in any case it wasted network bandwidth.
+ </p></li><li class="listitem"><p>
+ Avoid rare <span class="quote">“<span class="quote">failed to acquire cleanup lock</span>”</span> panic
+ during WAL replay of hash-index page split operations (Robert Haas)
+ </p></li><li class="listitem"><p>
+ Advance a heap page's LSN when setting its all-visible bit during
+ WAL replay (Jeff Davis)
+ </p><p>
+ Failure to do this left the page possibly different on standby
+ servers than the primary, and violated some other expectations about
+ when the LSN changes. This seems only a theoretical hazard so
+ far as <span class="productname">PostgreSQL</span> itself is concerned,
+ but it could upset third-party tools.
+ </p></li><li class="listitem"><p>
+ Fix <code class="function">int64_div_fast_to_numeric()</code> to work for a
+ wider range of inputs (Dean Rasheed)
+ </p><p>
+ This function misbehaved with some values of its second argument.
+ No such usages exist in core <span class="productname">PostgreSQL</span>,
+ but it's clearly a hazard for external modules, so repair.
+ </p></li><li class="listitem"><p>
+ Fix latent buffer-overrun problem in <code class="literal">WaitEventSet</code>
+ logic (Thomas Munro)
+ </p><p>
+ The <code class="function">epoll</code>-based
+ and <code class="function">kqueue</code>-based implementations could ask the
+ kernel for too many events if the size of their internal buffer was
+ different from the size of the caller's output buffer. That case is
+ not known to occur in released <span class="productname">PostgreSQL</span>
+ versions, but this error is a hazard for external modules and future
+ bug fixes.
+ </p></li><li class="listitem"><p>
+ Avoid nominally-undefined behavior when accessing shared memory in
+ 32-bit builds (Andres Freund)
+ </p><p>
+ clang's undefined-behavior sanitizer complained about use of a
+ pointer that was less aligned than it should be. It's very unlikely
+ that this would cause a problem in non-debug builds, but it's worth
+ fixing for testing purposes.
+ </p></li><li class="listitem"><p>
+ Fix assertion failure in BRIN minmax-multi opclasses (Tomas Vondra)
+ </p><p>
+ The assertion was overly strict, so this mistake was harmless in
+ non-assert builds.
+ </p></li><li class="listitem"><p>
+ Remove faulty assertion in useless-RESULT-RTE optimization logic
+ (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix copy-and-paste errors in cache-lookup-failure messages for ACL
+ checks (Justin Pryzby)
+ </p><p>
+ In principle these errors should never be reached. But if they are,
+ some of them reported the wrong type of object.
+ </p></li><li class="listitem"><p>
+ Fix possible corruption of very large tablespace map files
+ in <span class="application">pg_basebackup</span> (Antonin Houska)
+ </p></li><li class="listitem"><p>
+ Avoid harmless warning from <span class="application">pg_dump</span>
+ in <code class="option">--if-exists</code> mode (Tom Lane)
+ </p><p>
+ If the <code class="literal">public</code> schema has a non-default owner then
+ use of <span class="application">pg_dump</span>'s <code class="option">--if-exists</code>
+ option resulted in a warning message <span class="quote">“<span class="quote">warning: could not find
+ where to insert IF EXISTS in statement "-- *not* dropping schema,
+ since initdb creates it"</span>”</span>. The dump output was okay, though.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">psql</span>'s <code class="literal">\sf</code>
+ and <code class="literal">\ef</code> commands to handle SQL-language functions
+ that have <acronym class="acronym">SQL</acronym>-standard function bodies (Tom Lane)
+ </p><p>
+ These commands misidentified the start of the function body when it
+ used new-style syntax.
+ </p></li><li class="listitem"><p>
+ Fix tab completion of <code class="command">ALTER
+ FUNCTION/PROCEDURE/ROUTINE</code> ... <code class="command">SET
+ SCHEMA</code> (Dean Rasheed)
+ </p></li><li class="listitem"><p>
+ Update <code class="filename">contrib/pageinspect</code> to mark its
+ disk-accessing functions as <code class="literal">PARALLEL RESTRICTED</code>
+ (Tom Lane)
+ </p><p>
+ This avoids possible failure if one of these functions is used to
+ examine a temporary table, since a session's temporary tables are not
+ accessible from parallel workers.
+ </p></li><li class="listitem"><p>
+ Fix <code class="filename">contrib/seg</code> to not crash or print garbage
+ if an input number has more than 127 digits (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix build on Microsoft Visual Studio 2013 (Tom Lane)
+ </p><p>
+ A previous patch supposed that all platforms of interest
+ have <code class="function">snprintf()</code>, but MSVC 2013 isn't quite
+ there yet. Revert to using <code class="function">sprintf()</code> on that
+ platform.
+ </p></li><li class="listitem"><p>
+ Fix compile failure in building PL/Perl with MSVC when using
+ Strawberry Perl (Andrew Dunstan)
+ </p></li><li class="listitem"><p>
+ Fix mismatch of PL/Perl built with MSVC versus a Perl library built
+ with gcc (Andrew Dunstan)
+ </p><p>
+ Such combinations could previously fail with <span class="quote">“<span class="quote">loadable library
+ and perl binaries are mismatched</span>”</span> errors.
+ </p></li><li class="listitem"><p>
+ Suppress compiler warnings from Perl's header files (Andres Freund)
+ </p><p>
+ Our preferred compiler options provoke warnings about constructs
+ appearing in recent versions of Perl's header files. When using
+ <span class="application">gcc</span>, we can suppress these warnings with
+ a pragma.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">pg_waldump</span> to build on compilers that
+ don't discard unused static-inline functions (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Update time zone data files to <span class="application">tzdata</span>
+ release 2022g for DST law changes in Greenland and Mexico,
+ plus historical corrections for northern Canada, Colombia, and
+ Singapore.
+ </p><p>
+ Notably, a new timezone America/Ciudad_Juarez has been split off
+ from America/Ojinaga.
+ </p></li></ul></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release-15-3.html" title="E.2. Release 15.3">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release-15-1.html" title="E.4. Release 15.1">Next</a></td></tr><tr><td width="40%" align="left" valign="top">E.2. Release 15.3 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> E.4. Release 15.1</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release-15-3.html b/doc/src/sgml/html/release-15-3.html
new file mode 100644
index 0000000..f4f0e9d
--- /dev/null
+++ b/doc/src/sgml/html/release-15-3.html
@@ -0,0 +1,603 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>E.2. Release 15.3</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release-15-4.html" title="E.1. Release 15.4" /><link rel="next" href="release-15-2.html" title="E.3. Release 15.2" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">E.2. Release 15.3</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release-15-4.html" title="E.1. Release 15.4">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><th width="60%" align="center">Appendix E. Release Notes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release-15-2.html" title="E.3. Release 15.2">Next</a></td></tr></table><hr /></div><div class="sect1" id="RELEASE-15-3"><div class="titlepage"><div><div><h2 class="title" style="clear: both">E.2. Release 15.3</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="release-15-3.html#id-1.11.6.6.4">E.2.1. Migration to Version 15.3</a></span></dt><dt><span class="sect2"><a href="release-15-3.html#id-1.11.6.6.5">E.2.2. Changes</a></span></dt></dl></div><p><strong>Release date: </strong>2023-05-11</p><p>
+ This release contains a variety of fixes from 15.2.
+ For information about new features in major release 15, see
+ <a class="xref" href="release-15.html" title="E.5. Release 15">Section E.5</a>.
+ </p><div class="sect2" id="id-1.11.6.6.4"><div class="titlepage"><div><div><h3 class="title">E.2.1. Migration to Version 15.3</h3></div></div></div><p>
+ A dump/restore is not required for those running 15.X.
+ </p><p>
+ However, if you are upgrading from a version earlier than 15.1,
+ see <a class="xref" href="release-15-1.html" title="E.4. Release 15.1">Section E.4</a>.
+ </p></div><div class="sect2" id="id-1.11.6.6.5"><div class="titlepage"><div><div><h3 class="title">E.2.2. Changes</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Prevent <code class="command">CREATE SCHEMA</code> from defeating changes
+ in <code class="varname">search_path</code> (Alexander Lakhin)
+ </p><p>
+ Within a <code class="command">CREATE SCHEMA</code> command, objects in the
+ prevailing <code class="varname">search_path</code>, as well as those in the
+ newly-created schema, would be visible even within a called
+ function or script that attempted to set a
+ secure <code class="varname">search_path</code>. This could allow any user
+ having permission to create a schema to hijack the privileges of a
+ security definer function or extension script.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> Project thanks
+ Alexander Lakhin for reporting this problem.
+ (CVE-2023-2454)
+ </p></li><li class="listitem"><p>
+ Enforce row-level security policies correctly after inlining a
+ set-returning function (Stephen Frost, Tom Lane)
+ </p><p>
+ If a set-returning SQL-language function refers to a table having
+ row-level security policies, and it can be inlined into a calling
+ query, those RLS policies would not get enforced properly in some
+ cases involving re-using a cached plan under a different role.
+ This could allow a user to see or modify rows that should have been
+ invisible.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> Project thanks
+ Wolfgang Walther for reporting this problem.
+ (CVE-2023-2455)
+ </p></li><li class="listitem"><p>
+ Fix potential corruption of the template (source) database after
+ <code class="command">CREATE DATABASE</code> with the <code class="literal">STRATEGY
+ WAL_LOG</code> option (Nathan Bossart, Ryo Matsumura)
+ </p><p>
+ Improper buffer handling created a risk that any later modification
+ of the template's <code class="structname">pg_class</code> catalog would be
+ lost.
+ </p></li><li class="listitem"><p>
+ Fix memory leakage and unnecessary disk reads
+ during <code class="command">CREATE DATABASE</code> with the <code class="literal">STRATEGY
+ WAL_LOG</code> option (Andres Freund)
+ </p></li><li class="listitem"><p>
+ Avoid crash when the new schema name is omitted
+ in <code class="command">CREATE SCHEMA</code> (Michael Paquier)
+ </p><p>
+ The SQL standard allows writing <code class="literal">CREATE SCHEMA AUTHORIZATION
+ <em class="replaceable"><code>owner_name</code></em></code>, with the schema
+ name defaulting to <em class="replaceable"><code>owner_name</code></em>. However
+ some code paths expected the schema name to be present and would
+ fail.
+ </p></li><li class="listitem"><p>
+ Fix various planner failures with <code class="command">MERGE</code>
+ commands (Tom Lane)
+ </p><p>
+ Planning could fail with errors like <span class="quote">“<span class="quote">variable not found in
+ subplan target list</span>”</span> or <span class="quote">“<span class="quote">PlaceHolderVar found where not
+ expected</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Fix the row count reported by <code class="command">MERGE</code> for some
+ corner cases (Dean Rasheed)
+ </p><p>
+ The row count reported in the command tag counted rows that actually
+ hadn't been modified due to a <code class="literal">BEFORE ROW</code> trigger
+ returning NULL. This is inconsistent with what happens in
+ plain <code class="command">UPDATE</code> or <code class="command">DELETE</code>, so
+ change it to not count such rows. Also, avoid counting a row twice
+ when <code class="command">MERGE</code> moves it into a different partition of
+ a partitioned table.
+ </p></li><li class="listitem"><p>
+ Fix <code class="command">MERGE</code> problems with concurrent updates
+ (Dean Rasheed, Álvaro Herrera)
+ </p><p>
+ Some cases misbehaved if a row to be updated or deleted
+ by <code class="command">MERGE</code> had just been updated by a concurrent
+ transaction. This could lead to a crash, or the wrong merge action
+ being executed, or no action at all.
+ </p></li><li class="listitem"><p>
+ Add support for decompiling <code class="command">MERGE</code>
+ commands (Álvaro Herrera)
+ </p><p>
+ This was overlooked when <code class="command">MERGE</code> was added, but
+ it's essential support for <code class="command">MERGE</code> in new-style SQL
+ functions.
+ </p></li><li class="listitem"><p>
+ Fix enabling/disabling of foreign-key triggers in partitioned tables
+ (Tom Lane)
+ </p><p>
+ <code class="command">ALTER TABLE ... ENABLE/DISABLE TRIGGER</code> failed if
+ applied to a partitioned table's foreign-key enforcement triggers,
+ because it tried to locate the clone triggers for the partitions by
+ name, and they do not have the same name. Locate them by
+ parent-trigger OID instead.
+ </p></li><li class="listitem"><p>
+ Disallow altering composite types that are stored in indexes
+ (Tom Lane)
+ </p><p>
+ <code class="command">ALTER TYPE</code> disallows non-binary-compatible
+ modifications of composite types if they are stored in any table
+ columns. (Perhaps that will be allowed someday, but it hasn't
+ happened yet; the locking implications of rewriting many tables are
+ daunting.) We overlooked the possibility that an index might
+ contain a composite type that doesn't also appear in its table.
+ </p></li><li class="listitem"><p>
+ Disallow system columns as elements of foreign keys (Tom Lane)
+ </p><p>
+ Since the removal of OID as a system column, there is no plausible
+ use-case for this, and various bits of code no longer support it.
+ Disallow it rather than trying to fix all the cases.
+ </p></li><li class="listitem"><p>
+ Ensure that <code class="command">COPY TO</code> from an RLS-enabled parent
+ table does not copy any rows from child tables (Antonin Houska)
+ </p><p>
+ The documentation is quite clear that <code class="command">COPY TO</code>
+ copies rows from only the named table, not any inheritance children
+ it may have. However, if row-level security was enabled on the table
+ then this stopped being true.
+ </p></li><li class="listitem"><p>
+ Avoid possible crash when <code class="function">array_position()</code>
+ or <code class="function">array_positions()</code> is passed an empty array
+ (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix possible out-of-bounds fetch in <code class="function">to_char()</code>
+ (Tom Lane)
+ </p><p>
+ With bad luck this could have resulted in a server crash.
+ </p></li><li class="listitem"><p>
+ Avoid buffer overread in <code class="function">translate()</code> function
+ (Daniil Anisimov)
+ </p><p>
+ When using the deletion feature, the function might fetch the byte
+ just after the input string, creating a small risk of crash.
+ </p></li><li class="listitem"><p>
+ Adjust text-search-related character classification logic to
+ correctly detect whether the prevailing locale
+ is <code class="literal">C</code> (Jeff Davis)
+ </p><p>
+ This code got confused if the database's default collation uses ICU.
+ </p></li><li class="listitem"><p>
+ Avoid possible crash on empty input for type <code class="type">interval</code>
+ (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Re-allow exponential notation in ISO-8601 interval fields
+ (Tom Lane)
+ </p><p>
+ Interval input like <code class="literal">P0.1e10D</code> isn't officially
+ sanctioned by ISO-8601, but we accepted it for a long time before
+ version 15, so re-allow it.
+ </p></li><li class="listitem"><p>
+ Fix error cursor setting for parse errors in JSON string literals
+ (Tom Lane)
+ </p><p>
+ Most cases in which a syntax error is detected in a string literal
+ within a JSON value failed to set the error cursor appropriately.
+ This led at least to an unhelpful error message (pointing to the
+ token before the string, rather than the actual trouble spot), and
+ could even result in a crash in v14 and later.
+ </p></li><li class="listitem"><p>
+ Fix data corruption due to <code class="varname">vacuum_defer_cleanup_age</code>
+ being larger than the current 64-bit xid (Andres Freund)
+ </p><p>
+ In v14 and later with non-default settings
+ of <code class="varname">vacuum_defer_cleanup_age</code>, it was possible to
+ compute a very large vacuum cleanup horizon xid, leading to vacuum
+ removing rows that are still live. v12 and v13 have a lesser form
+ of the same problem affecting only GiST indexes, which could lead to
+ index pages getting recycled too early.
+ </p></li><li class="listitem"><p>
+ Fix parser's failure to detect some cases of improperly-nested
+ aggregates (Tom Lane)
+ </p><p>
+ This oversight could lead to executor failures for queries that
+ should have been rejected as invalid.
+ </p></li><li class="listitem"><p>
+ Fix data structure corruption during parsing of
+ serial <code class="literal">SEQUENCE NAME</code> options (David Rowley)
+ </p><p>
+ This can lead to trouble if an event trigger captures the corrupted
+ parse tree.
+ </p></li><li class="listitem"><p>
+ Correctly update plan nodes' parallel-safety markings when moving
+ initplans from one node to another (Tom Lane)
+ </p><p>
+ This planner oversight could lead to <span class="quote">“<span class="quote">subplan was not
+ initialized</span>”</span> errors at runtime.
+ </p></li><li class="listitem"><p>
+ Avoid failure with PlaceHolderVars in extended-statistics code
+ (Tom Lane)
+ </p><p>
+ Use of dependency-type extended statistics could fail with
+ <span class="quote">“<span class="quote">PlaceHolderVar found where not expected</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Fix incorrect tests for whether a qual clause applied to a subquery
+ can be transformed into a window aggregate <span class="quote">“<span class="quote">run
+ condition</span>”</span> within the subquery (David Rowley)
+ </p><p>
+ A SubPlan within such a clause would cause assertion failures or
+ incorrect answers, as would some other unusual cases.
+ </p></li><li class="listitem"><p>
+ Disable the inverse-transition optimization for window aggregates
+ when the call contains sub-SELECTs (David Rowley)
+ </p><p>
+ This optimization requires that the aggregate's argument expressions
+ have repeatable results, which might not hold for a sub-SELECT.
+ </p></li><li class="listitem"><p>
+ Fix oversights in execution of nested <code class="literal">ARRAY[]</code>
+ constructs (Alexander Lakhin, Tom Lane)
+ </p><p>
+ Correctly detect overflow of the total space needed for the result
+ array, avoiding a possible crash due to undersized output
+ allocation. Also ensure that any trailing padding space in the
+ result array is zeroed; while leaving garbage there is harmless for
+ most purposes, it can result in odd behavior later.
+ </p></li><li class="listitem"><p>
+ Prevent crash when updating a field within an
+ array-of-domain-over-composite-type column (Dmitry Dolgov)
+ </p></li><li class="listitem"><p>
+ Fix partition pruning logic for partitioning on boolean columns
+ (David Rowley)
+ </p><p>
+ Pruning with a condition like <code class="literal">boolcol IS NOT TRUE</code>
+ was done incorrectly, leading to possibly not returning rows in
+ which <code class="literal">boolcol</code> is NULL. Also, the rather unlikely
+ case of partitioning on <code class="literal">NOT boolcol</code> was handled
+ incorrectly.
+ </p></li><li class="listitem"><p>
+ Fix race condition in per-batch cleanup during parallel hash join
+ (Thomas Munro, Melanie Plageman)
+ </p><p>
+ A crash was possible given unlucky timing and
+ <code class="varname">parallel_leader_participation</code>
+ = <code class="literal">off</code> (which is not the default).
+ </p></li><li class="listitem"><p>
+ Recalculate <code class="literal">GENERATED</code> columns after an
+ EvalPlanQual check (Tom Lane)
+ </p><p>
+ In <code class="literal">READ COMMITTED</code> isolation mode, the effects of
+ a row update might need to get reapplied to a newer version of the
+ row than the query found originally. If so, we need to recompute
+ any <code class="literal">GENERATED</code> columns, in case they depend on
+ columns that were changed by the concurrent update.
+ </p></li><li class="listitem"><p>
+ Fix memory leak in Memoize plan execution (David Rowley)
+ </p></li><li class="listitem"><p>
+ Fix buffer refcount leak when using batched inserts for a foreign
+ table included in a partitioned tree (Alexander Pyhalov)
+ </p></li><li class="listitem"><p>
+ Restore support for
+ sub-millisecond <code class="varname">vacuum_cost_delay</code> settings
+ (Thomas Munro)
+ </p></li><li class="listitem"><p>
+ Don't balance vacuum cost delay when a table has a
+ per-relation <code class="varname">vacuum_cost_delay</code> setting of zero
+ (Masahiko Sawada)
+ </p><p>
+ Delay balancing is supposed to be disabled whenever autovacuum is
+ processing a table with a
+ per-relation <code class="varname">vacuum_cost_delay</code> setting, but this
+ was done only for positive settings, not zero.
+ </p></li><li class="listitem"><p>
+ Fix corner-case crashes when columns have been added to the end of a
+ view (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Repair rare failure of MULTIEXPR_SUBLINK subplans in partitioned
+ updates (Andres Freund, Tom Lane)
+ </p><p>
+ Use of the syntax <code class="literal">INSERT ... ON CONFLICT DO UPDATE SET (c1,
+ ...) = (SELECT ...)</code> with a partitioned target table could
+ result in failure if any child table is dissimilar from the parent
+ (for example, different physical column order).
+ This typically manifested as failure of consistency checks in the
+ executor; but a crash or incorrect data updates are also possible.
+ </p></li><li class="listitem"><p>
+ Fix handling of <code class="literal">DEFAULT</code> markers within a
+ multi-row <code class="literal">INSERT ... VALUES</code> query on a view that
+ has a <code class="literal">DO ALSO INSERT ... SELECT</code> rule (Dean
+ Rasheed)
+ </p><p>
+ Such cases typically failed with <span class="quote">“<span class="quote">unrecognized node
+ type</span>”</span> errors or assertion failures.
+ </p></li><li class="listitem"><p>
+ Support references to <code class="literal">OLD</code>
+ and <code class="literal">NEW</code> within subqueries in rule actions
+ (Dean Rasheed, Tom Lane)
+ </p><p>
+ Such references are really lateral references, but the server could
+ crash if the subquery wasn't explicitly marked
+ with <code class="literal">LATERAL</code>. Arrange to do that implicitly when
+ necessary.
+ </p></li><li class="listitem"><p>
+ When decompiling a rule or SQL function body
+ containing <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code>
+ within <code class="command">WITH</code>, take care to print the correct alias
+ for the target table (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix glitches in <code class="literal">SERIALIZABLE READ ONLY</code>
+ optimization (Thomas Munro)
+ </p><p>
+ Transactions already marked as <span class="quote">“<span class="quote">doomed</span>”</span> confused the
+ safe-snapshot optimization for <code class="literal">SERIALIZABLE READ
+ ONLY</code> transactions. The optimization was unnecessarily
+ skipped in some cases. In other cases an assertion failure occurred
+ (but there was no problem in non-assert builds).
+ </p></li><li class="listitem"><p>
+ Avoid leaking cache callback slots in
+ the <code class="literal">pgoutput</code> logical decoding plugin (Shi Yu)
+ </p><p>
+ Multiple cycles of starting up and shutting down the plugin within a
+ single session would eventually lead to an <span class="quote">“<span class="quote">out of
+ relcache_callback_list slots</span>”</span> error.
+ </p></li><li class="listitem"><p>
+ Avoid unnecessary calls to custom validators for index operator
+ class options (Alexander Korotkov)
+ </p><p>
+ This change fixes some cases where an unexpected error was thrown.
+ </p></li><li class="listitem"><p>
+ Avoid useless work while scanning a multi-column BRIN index with
+ multiple scan keys (Tomas Vondra)
+ </p><p>
+ The existing code effectively considered only the last scan key
+ while deciding whether a range matched, thus usually scanning more
+ of the index than it needed to.
+ </p></li><li class="listitem"><p>
+ Fix netmask handling in BRIN inet_minmax_multi_ops opclass
+ (Tomas Vondra)
+ </p><p>
+ This error triggered an assertion failure in assert-enabled builds,
+ but is mostly harmless in production builds.
+ </p></li><li class="listitem"><p>
+ Fix dereference of dangling pointer during buffering build of a GiST
+ index (Alexander Lakhin)
+ </p><p>
+ This error seems to usually be harmless in production builds, as the
+ fetched value is noncritical; but in principle it could cause a
+ server crash.
+ </p></li><li class="listitem"><p>
+ Ignore dropped columns and generated columns during logical
+ replication of an update or delete action (Onder Kalaci, Shi Yu)
+ </p><p>
+ Replication with the <code class="literal">REPLICA IDENTITY FULL</code> option
+ failed if the table contained such columns.
+ </p></li><li class="listitem"><p>
+ Correct the name of the wait event for SLRU buffer I/O for commit
+ timestamps (Alexander Lakhin)
+ </p><p>
+ This wait event is named <code class="literal">CommitTsBuffer</code> according
+ to the documentation, but the code had it
+ as <code class="literal">CommitTSBuffer</code>. Change the code to match the
+ documentation, as that way is more consistent with the naming of
+ related wait events.
+ </p></li><li class="listitem"><p>
+ Re-activate reporting of wait event <code class="literal">SLRUFlushSync</code>
+ (Thomas Munro)
+ </p><p>
+ Reporting of this type of wait was accidentally removed in code
+ refactoring.
+ </p></li><li class="listitem"><p>
+ Avoid possible underflow when calculating how many WAL segments to
+ keep (Kyotaro Horiguchi)
+ </p><p>
+ This could result in not honoring <code class="varname">wal_keep_size</code>
+ accurately.
+ </p></li><li class="listitem"><p>
+ Disable startup progress reporting overhead in standby mode
+ (Bharath Rupireddy)
+ </p><p>
+ In standby mode, we don't actually report progress of recovery,
+ but we were doing work to track it anyway.
+ </p></li><li class="listitem"><p>
+ Support RSA-PSS certificates with SCRAM-SHA-256 channel binding
+ (Jacob Champion, Heikki Linnakangas)
+ </p><p>
+ This feature requires building with OpenSSL 1.1.1 or newer. Both
+ the server and <span class="application">libpq</span> are affected.
+ </p></li><li class="listitem"><p>
+ Avoid race condition with process ID tracking on Windows (Thomas Munro)
+ </p><p>
+ The operating system could recycle a PID before the postmaster
+ observed that that child process was gone. This could lead to
+ tracking more than one child with the same PID, resulting in
+ confusion.
+ </p></li><li class="listitem"><p>
+ Fix <code class="function">list_copy_head()</code> to work correctly on an
+ empty List (David Rowley)
+ </p><p>
+ This case is not known to be reached by any
+ core <span class="productname">PostgreSQL</span> code, but extensions
+ might rely on it working.
+ </p></li><li class="listitem"><p>
+ Add missing cases to <code class="function">SPI_result_code_string()</code>
+ (Dean Rasheed)
+ </p></li><li class="listitem"><p>
+ Fix erroneous Valgrind markings
+ in <code class="function">AllocSetRealloc()</code> (Karina Litskevich)
+ </p><p>
+ In the unusual case where the size of a large (&gt;8kB) palloc chunk
+ is decreased, a Valgrind-aware build would mismark the defined-ness
+ state of the memory released from the chunk, possibly causing
+ incorrect results during Valgrind testing.
+ </p></li><li class="listitem"><p>
+ Fix assertion failure for <code class="command">MERGE</code> into a
+ partitioned table with row-level security enabled (Dean Rasheed)
+ </p></li><li class="listitem"><p>
+ Avoid assertion failure when decoding a transactional logical
+ replication message (Tomas Vondra)
+ </p></li><li class="listitem"><p>
+ Avoid locale sensitivity when processing regular expression escapes
+ (Jeff Davis)
+ </p><p>
+ A backslash followed by a non-ASCII character could sometimes cause
+ an assertion failure, depending on the prevailing locale.
+ </p></li><li class="listitem"><p>
+ Avoid trying to write an empty WAL record
+ in <code class="function">log_newpage_range()</code> when the last few pages
+ in the specified range are empty (Matthias van de Meent)
+ </p><p>
+ It is not entirely clear whether this case is reachable in released
+ branches, but if it is then an assertion failure could occur.
+ </p></li><li class="listitem"><p>
+ Fix session-lifespan memory leakage in <span class="application">plpgsql</span>
+ <code class="literal">DO</code> blocks that use cast expressions
+ (Ajit Awekar, Tom Lane)
+ </p></li><li class="listitem"><p>
+ Tighten array dimensionality checks when converting Perl
+ list structures to multi-dimensional SQL arrays (Tom Lane)
+ </p><p>
+ <span class="application">plperl</span> could misbehave when the nesting
+ of sub-lists is inconsistent so that the data does not represent a
+ rectangular array of values. Such cases now produce errors, but
+ previously they could result in a crash or garbage output.
+ </p></li><li class="listitem"><p>
+ Tighten array dimensionality checks when converting Python
+ list structures to multi-dimensional SQL arrays (Tom Lane)
+ </p><p>
+ <span class="application">plpython</span> could misbehave when dealing
+ with empty sub-lists, or when the nesting of sub-lists is
+ inconsistent so that the data does not represent a rectangular array
+ of values. The former should result in an empty output array, and
+ the latter in an error. But some cases resulted in a crash, and
+ others in unexpected output.
+ </p></li><li class="listitem"><p>
+ Fix unwinding of exception stack
+ in <span class="application">plpython</span> (Xing Guo)
+ </p><p>
+ Some rare failure cases could return without cleaning up the PG_TRY
+ exception stack, risking a crash if another error was raised before
+ the next stack level was unwound.
+ </p></li><li class="listitem"><p>
+ Fix inconsistent GSS-encryption error handling
+ in <span class="application">libpq</span>'s
+ <code class="function">PQconnectPoll()</code>
+ (Michael Paquier)
+ </p><p>
+ With <code class="option">gssencmode</code> set to <code class="literal">require</code>,
+ the connection was not marked dead after a GSS initialization
+ failure. Make it fail immediately, as the equivalent case for TLS
+ encryption has long done.
+ </p></li><li class="listitem"><p>
+ Fix possible data corruption in <span class="application">ecpg</span>
+ programs built with the <code class="option">-C ORACLE</code> option
+ (Kyotaro Horiguchi)
+ </p><p>
+ When <code class="function">ecpg_get_data()</code> is called
+ with <code class="varname">varcharsize</code> set to zero, it could write a
+ terminating zero character into the last byte of the preceding
+ field, truncating the data in that field.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">pg_dump</span> so that partitioned tables
+ that are hash-partitioned on an enum-type column can be restored
+ successfully (Tom Lane)
+ </p><p>
+ Since the hash codes for enum values depend on the OIDs assigned to
+ the enum, they are typically different after a dump and restore,
+ meaning that rows often need to go into a different partition than
+ they were in originally. Users can work around that by specifying
+ the <code class="option">--load-via-partition-root</code> option; but since
+ there is very little chance of success without that,
+ teach <span class="application">pg_dump</span> to apply it automatically
+ to such tables.
+ </p><p>
+ Also, fix <span class="application">pg_restore</span> to not try
+ to <code class="command">TRUNCATE</code> target tables before restoring into
+ them when <code class="option">--load-via-partition-root</code> mode is used.
+ This avoids a hazard of deadlocks and lost data.
+ </p></li><li class="listitem"><p>
+ Correctly detect non-seekable files on Windows
+ (Juan José Santamaría Flecha, Michael Paquier, Daniel Watzinger)
+ </p><p>
+ This bug led to misbehavior when <span class="application">pg_dump</span>
+ writes to a pipe or <span class="application">pg_restore</span> reads from
+ one.
+ </p></li><li class="listitem"><p>
+ In <span class="application">pgbench</span>'s <span class="quote">“<span class="quote">prepared</span>”</span>
+ mode, prepare all the commands in a pipeline before starting the
+ pipeline (Álvaro Herrera)
+ </p><p>
+ This avoids a failure when a pgbench script tries to
+ start a serializable transaction inside a pipeline.
+ </p></li><li class="listitem"><p>
+ In <code class="filename">contrib/amcheck</code>'s heap checking code, deal
+ correctly with tuples having zero xmin or xmax (Robert Haas)
+ </p></li><li class="listitem"><p>
+ In <code class="filename">contrib/amcheck</code>, deal sanely with xids that
+ appear to be before epoch zero (Andres Freund)
+ </p><p>
+ In cases of corruption we might see a wrapped-around 32-bit xid that
+ appears to be before the first xid epoch. Promoting such a value to
+ 64-bit form produced a value far in the future, resulting in wrong
+ reports. Return FirstNormalFullTransactionId in such cases so that
+ things work reasonably sanely.
+ </p></li><li class="listitem"><p>
+ In <code class="filename">contrib/basebackup_to_shell</code>, properly detect
+ failure to open a pipe (Robert Haas)
+ </p></li><li class="listitem"><p>
+ In <code class="filename">contrib/hstore_plpython</code>, avoid crashing if
+ the Python value to be transformed isn't a mapping (Dmitry Dolgov,
+ Tom Lane)
+ </p><p>
+ This should give an error, but Python 3 changed some APIs in a way
+ that caused the check to misbehave, allowing a crash to ensue.
+ </p></li><li class="listitem"><p>
+ Require the <code class="literal">siglen</code> option of a GiST index on
+ an <code class="type">ltree</code> column, if specified, to be a multiple of 4
+ (Alexander Korotkov)
+ </p><p>
+ Other values result in misaligned accesses to index content, which
+ is harmless on Intel-compatible hardware but can cause a crash on
+ some other architectures.
+ </p></li><li class="listitem"><p>
+ In <code class="filename">contrib/pageinspect</code>, add defenses against
+ incorrect input for the <code class="function">gist_page_items()</code> function
+ (Dmitry Koval)
+ </p></li><li class="listitem"><p>
+ Fix misbehavior in <code class="filename">contrib/pg_trgm</code> with an
+ unsatisfiable regular expression (Tom Lane)
+ </p><p>
+ A regex such as <code class="literal">$foo</code> is legal but unsatisfiable;
+ the regex compiler recognizes that and produces an empty NFA graph.
+ Attempting to optimize such a graph into a pg_trgm GIN or GiST index
+ qualification resulted in accessing off the end of a work array,
+ possibly leading to crashes.
+ </p></li><li class="listitem"><p>
+ Fix handling of escape sequences
+ in <code class="filename">contrib/postgres_fdw</code>'s
+ <code class="varname">application_name</code> parameter (Kyotaro Horiguchi,
+ Michael Paquier)
+ </p><p>
+ The code to expand these could fail if executed in a background
+ process, as for example during auto-analyze of a foreign table.
+ </p></li><li class="listitem"><p>
+ In <code class="filename">contrib/pg_walinspect</code>, limit memory usage
+ of <code class="function">pg_get_wal_records_info()</code> (Bharath Rupireddy)
+ </p></li><li class="listitem"><p>
+ Use the <code class="option">--strip-unneeded</code> option when stripping
+ static libraries with
+ GNU-compatible <span class="application">strip</span> (Tom Lane)
+ </p><p>
+ Previously, <code class="literal">make install-strip</code> used
+ the <code class="option">-x</code> option in this case. This change avoids
+ misbehavior of <span class="application">llvm-strip</span>, and gives
+ slightly smaller output as well.
+ </p></li><li class="listitem"><p>
+ Stop recommending auto-download of DTD files for building the
+ documentation, and indeed disable it (Aleksander Alekseev, Peter
+ Eisentraut, Tom Lane)
+ </p><p>
+ It appears no longer possible to build the SGML documentation
+ without a local installation of the DocBook DTD files.
+ Formerly <span class="application">xsltproc</span> could download those
+ files on-the-fly from sourceforge.net; but sourceforge.net now
+ permits only HTTPS access, and no common version
+ of <span class="application">xsltproc</span> supports that. Hence, remove
+ the bits of our documentation suggesting that that's possible or
+ useful, and instead
+ add <span class="application">xsltproc</span>'s <code class="option">--nonet</code>
+ option to the build recipes.
+ </p></li><li class="listitem"><p>
+ When running TAP tests in PGXS builds, use a saner location for the
+ temporary <code class="filename">portlock</code> directory (Peter Eisentraut)
+ </p><p>
+ Place it under <code class="filename">tmp_check</code> in the build
+ directory. With the previous coding, a PGXS build would try to place
+ it in the installation directory, which is not necessarily writable.
+ </p></li><li class="listitem"><p>
+ Update time zone data files to <span class="application">tzdata</span>
+ release 2023c for DST law changes in Egypt, Greenland, Morocco, and
+ Palestine.
+ </p><p>
+ When observing Moscow time, Europe/Kirov and Europe/Volgograd now
+ use the abbreviations MSK/MSD instead of numeric abbreviations,
+ for consistency with other timezones observing Moscow time.
+ Also, America/Yellowknife is no longer distinct from America/Edmonton;
+ this affects some pre-1948 timestamps in that area.
+ </p></li></ul></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release-15-4.html" title="E.1. Release 15.4">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release-15-2.html" title="E.3. Release 15.2">Next</a></td></tr><tr><td width="40%" align="left" valign="top">E.1. Release 15.4 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> E.3. Release 15.2</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release-15-4.html b/doc/src/sgml/html/release-15-4.html
new file mode 100644
index 0000000..a891e2a
--- /dev/null
+++ b/doc/src/sgml/html/release-15-4.html
@@ -0,0 +1,351 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>E.1. Release 15.4</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release.html" title="Appendix E. Release Notes" /><link rel="next" href="release-15-3.html" title="E.2. Release 15.3" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">E.1. Release 15.4</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release.html" title="Appendix E. Release Notes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><th width="60%" align="center">Appendix E. Release Notes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release-15-3.html" title="E.2. Release 15.3">Next</a></td></tr></table><hr /></div><div class="sect1" id="RELEASE-15-4"><div class="titlepage"><div><div><h2 class="title" style="clear: both">E.1. Release 15.4</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="release-15-4.html#id-1.11.6.5.4">E.1.1. Migration to Version 15.4</a></span></dt><dt><span class="sect2"><a href="release-15-4.html#id-1.11.6.5.5">E.1.2. Changes</a></span></dt></dl></div><p><strong>Release date: </strong>2023-08-10</p><p>
+ This release contains a variety of fixes from 15.3.
+ For information about new features in major release 15, see
+ <a class="xref" href="release-15.html" title="E.5. Release 15">Section E.5</a>.
+ </p><div class="sect2" id="id-1.11.6.5.4"><div class="titlepage"><div><div><h3 class="title">E.1.1. Migration to Version 15.4</h3></div></div></div><p>
+ A dump/restore is not required for those running 15.X.
+ </p><p>
+ However, if you use BRIN indexes, it may be advisable to reindex them;
+ see the third changelog entry below.
+ </p><p>
+ Also, if you are upgrading from a version earlier than 15.1,
+ see <a class="xref" href="release-15-1.html" title="E.4. Release 15.1">Section E.4</a>.
+ </p></div><div class="sect2" id="id-1.11.6.5.5"><div class="titlepage"><div><div><h3 class="title">E.1.2. Changes</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Disallow substituting a schema or owner name into an extension script
+ if the name contains a quote, backslash, or dollar sign (Noah Misch)
+ </p><p>
+ This restriction guards against SQL-injection hazards for trusted
+ extensions.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> Project thanks Micah Gate,
+ Valerie Woolard, Tim Carey-Smith, and Christoph Berg for reporting
+ this problem.
+ (CVE-2023-39417)
+ </p></li><li class="listitem"><p>
+ Fix <code class="command">MERGE</code> to enforce row security policies
+ properly (Dean Rasheed)
+ </p><p>
+ When <code class="command">MERGE</code> performs an <code class="literal">UPDATE</code>
+ action, it should enforce any <code class="literal">UPDATE</code> or
+ <code class="literal">SELECT</code> RLS policies defined on the target table,
+ to be consistent with the way that a plain <code class="command">UPDATE</code>
+ with a <code class="literal">WHERE</code> clause works. Instead it was
+ enforcing <code class="literal">INSERT</code> RLS policies for both
+ <code class="literal">INSERT</code> and <code class="literal">UPDATE</code> actions.
+ </p><p>
+ In addition, when <code class="command">MERGE</code> performs a <code class="literal">DO
+ NOTHING</code> action, it applied the target table's
+ <code class="literal">DELETE</code> RLS policies to existing rows, even though
+ those rows are not being deleted. While it's not a security
+ problem, this could result in unwanted errors.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> Project thanks
+ Dean Rasheed for reporting this problem.
+ (CVE-2023-39418)
+ </p></li><li class="listitem"><p>
+ Fix confusion between empty (no rows) ranges and all-NULL ranges in
+ BRIN indexes, as well as incorrect merging of all-NULL summaries
+ (Tomas Vondra)
+ </p><p>
+ Each of these oversights could result in forgetting that a BRIN
+ index range contains any NULL values, potentially allowing
+ subsequent queries that should return NULL values to miss doing so.
+ </p><p>
+ This fix will not in itself correct faulty BRIN entries.
+ It's recommended to <code class="command">REINDEX</code> any BRIN indexes that
+ may be used to search for nulls.
+ </p></li><li class="listitem"><p>
+ Avoid leaving a corrupted database behind when <code class="command">DROP
+ DATABASE</code> is interrupted (Andres Freund)
+ </p><p>
+ If <code class="command">DROP DATABASE</code> was interrupted after it had
+ already begun taking irreversible steps, the target database
+ remained accessible (because the removal of
+ its <code class="structname">pg_database</code> row would roll back),
+ but it would have corrupt contents. Fix by marking the database
+ as inaccessible before we begin to perform irreversible operations.
+ A failure after that will leave the database still partially
+ present, but nothing can be done with it except to issue
+ another <code class="command">DROP DATABASE</code>.
+ </p></li><li class="listitem"><p>
+ Ensure that partitioned indexes are correctly marked as valid or not
+ at creation (Michael Paquier)
+ </p><p>
+ If a new partitioned index matches an existing but invalid index on
+ one of the partitions, the partitioned index could end up being
+ marked valid prematurely. This could lead to misbehavior or
+ assertion failures in subsequent queries on the partitioned table.
+ </p></li><li class="listitem"><p>
+ Ignore invalid child indexes when matching partitioned indexes to
+ child indexes during <code class="command">ALTER TABLE ATTACH PARTITION</code>
+ (Michael Paquier)
+ </p><p>
+ Such an index will now be ignored, and a new child index created
+ instead.
+ </p></li><li class="listitem"><p>
+ Fix possible failure when marking a partitioned index valid after
+ all of its partitions have been attached (Michael Paquier)
+ </p><p>
+ The update of the index's <code class="structname">pg_index</code> entry
+ could use stale data for other columns. One reported symptom is
+ an <span class="quote">“<span class="quote">attempted to update invisible tuple</span>”</span> error.
+ </p></li><li class="listitem"><p>
+ Fix <code class="command">ALTER EXTENSION SET SCHEMA</code> to complain if the
+ extension contains any objects outside the extension's schema
+ (Michael Paquier, Heikki Linnakangas)
+ </p><p>
+ Erroring out if the extension contains objects in multiple schemas
+ was always intended; but the check was mis-coded so that it would
+ fail to detect some cases, leading to surprising behavior.
+ </p></li><li class="listitem"><p>
+ Fix tracking of tables' access method dependencies (Michael Paquier)
+ </p><p>
+ <code class="command">ALTER TABLE ... SET ACCESS METHOD</code> failed to
+ update relevant <code class="structname">pg_depend</code> entries when
+ changing a table's access method. When using non-built-in access
+ methods, this creates a risk that an access method could be dropped
+ even though tables still depend on it. This fix corrects the logic
+ in <code class="command">ALTER TABLE</code>, but it will not adjust any
+ already-missing <code class="structname">pg_depend</code> entries.
+ </p></li><li class="listitem"><p>
+ Don't use partial unique indexes for uniqueness proofs in the
+ planner (David Rowley)
+ </p><p>
+ This could give rise to incorrect plans, since the presumed
+ uniqueness of rows read from a table might not hold if the index in
+ question isn't used to scan the table.
+ </p></li><li class="listitem"><p>
+ Don't Memoize lateral joins with volatile join conditions
+ (Richard Guo)
+ </p><p>
+ Applying Memoize to a sub-plan that contains volatile filter
+ conditions is likely to lead to wrong answers. The check to avoid
+ doing this missed some cases that can arise when
+ using <code class="literal">LATERAL</code>.
+ </p></li><li class="listitem"><p>
+ Avoid producing incorrect plans for foreign joins with
+ pseudoconstant join clauses (Etsuro Fujita)
+ </p><p>
+ The planner currently lacks support for attaching pseudoconstant
+ join clauses to a pushed-down remote join, so disable generation
+ of remote joins in such cases. (A better solution will require
+ ABI-breaking changes of planner data structures, so it will have to
+ wait for a future major release.)
+ </p></li><li class="listitem"><p>
+ Correctly handle sub-SELECTs in RLS policy expressions and
+ security-barrier views when expanding rule actions (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix race conditions in conflict detection
+ for <code class="literal">SERIALIZABLE</code> isolation mode
+ (Thomas Munro)
+ </p><p>
+ Conflicts could be missed when using bitmap heap scans, when using
+ GIN indexes, and when examining an initially-empty btree index.
+ All these cases could lead to serializability failures due to
+ improperly allowing conflicting transactions to commit.
+ </p></li><li class="listitem"><p>
+ Fix misbehavior of EvalPlanQual checks with inherited or partitioned
+ target tables (Tom Lane)
+ </p><p>
+ This oversight could lead to update or delete actions
+ in <code class="literal">READ COMMITTED</code> isolation mode getting
+ performed when they should have been skipped because of a
+ conflicting concurrent update.
+ </p></li><li class="listitem"><p>
+ Fix hash join with an inner-side hash key that contains Params
+ coming from an outer nested loop (Tom Lane)
+ </p><p>
+ When rescanning the join after the values of such Params have
+ changed, we must rebuild the hash table, but neglected to do so.
+ This could result in missing join output rows.
+ </p></li><li class="listitem"><p>
+ Fix intermittent failures when trying to update a field of a
+ composite column (Tom Lane)
+ </p><p>
+ If the overall value of the composite column is wide enough to
+ require out-of-line toasting, then an unluckily-timed cache flush
+ could cause errors or server crashes.
+ </p></li><li class="listitem"><p>
+ Prevent query-lifespan memory leaks in some <code class="command">UPDATE</code>
+ queries with triggers (Tomas Vondra)
+ </p></li><li class="listitem"><p>
+ Prevent query-lifespan memory leaks when an Incremental Sort plan
+ node is rescanned (James Coleman, Laurenz Albe, Tom Lane)
+ </p></li><li class="listitem"><p>
+ Accept fractional seconds in the input to <code class="type">jsonpath</code>'s
+ <code class="function">datetime()</code> method (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Prevent stack-overflow crashes with very complex text search
+ patterns (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Allow tokens up to 10240 bytes long
+ in <code class="filename">pg_hba.conf</code>
+ and <code class="filename">pg_ident.conf</code> (Tom Lane)
+ </p><p>
+ The previous limit of 256 bytes has been found insufficient for some
+ use-cases.
+ </p></li><li class="listitem"><p>
+ Ensure that all existing placeholders are checked for matches when
+ an extension declares its GUC prefix to be reserved (Karina
+ Litskevich, Ekaterina Sokolova)
+ </p><p>
+ Faulty loop logic could cause some entries to be skipped.
+ </p></li><li class="listitem"><p>
+ Fix mishandling of C++ out-of-memory conditions (Heikki Linnakangas)
+ </p><p>
+ If JIT is in use, running out of memory in a
+ C++ <code class="function">new</code> call would lead to
+ a <span class="productname">PostgreSQL</span> FATAL error, instead of the
+ expected C++ exception.
+ </p></li><li class="listitem"><p>
+ Fix rare null-pointer crash in <code class="filename">plancache.c</code>
+ (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Avoid leaking a stats entry for a subscription when it is dropped
+ (Masahiko Sawada)
+ </p></li><li class="listitem"><p>
+ Avoid losing track of possibly-useful shared memory segments when a
+ page free results in coalescing ranges of free space (Dongming Liu)
+ </p><p>
+ Ensure that the segment is moved into the
+ appropriate <span class="quote">“<span class="quote">bin</span>”</span> for its new amount of free space, so
+ that it will be found by subsequent searches.
+ </p></li><li class="listitem"><p>
+ Allow <code class="command">VACUUM</code> to continue after detecting certain
+ types of b-tree index corruption (Peter Geoghegan)
+ </p><p>
+ If an invalid sibling-page link is detected, log the issue and press
+ on, rather than throwing an error as before. Nothing short
+ of <code class="command">REINDEX</code> will fix the broken index, but
+ preventing <code class="command">VACUUM</code> from completing until that is
+ done risks making matters far worse.
+ </p></li><li class="listitem"><p>
+ Ensure that <code class="varname">WrapLimitsVacuumLock</code> is released
+ after <code class="command">VACUUM</code> detects invalid data
+ in <code class="structname">pg_database</code>.<code class="structfield">datfrozenxid</code>
+ or <code class="structname">pg_database</code>.<code class="structfield">datminmxid</code>
+ (Andres Freund)
+ </p><p>
+ Failure to release this lock could lead to a deadlock later,
+ although the lock would be cleaned up if the session exits or
+ encounters some other error.
+ </p></li><li class="listitem"><p>
+ Avoid double replay of prepared transactions during crash
+ recovery (suyu.cmj, Michael Paquier)
+ </p><p>
+ After a crash partway through a checkpoint with some two-phase
+ transaction state data already flushed to disk by this checkpoint,
+ crash recovery could attempt to replay the prepared transaction(s)
+ twice, leading to a fatal error such as <span class="quote">“<span class="quote">lock is already
+ held</span>”</span> in the startup process.
+ </p></li><li class="listitem"><p>
+ Ensure that a newly created, but still empty table
+ is <code class="function">fsync</code>'ed at the next checkpoint (Heikki
+ Linnakangas)
+ </p><p>
+ Without this, if there is an operating system crash causing the
+ empty file to disappear, subsequent operations on the table might
+ fail with <span class="quote">“<span class="quote">could not open file</span>”</span> errors.
+ </p></li><li class="listitem"><p>
+ Ensure that creation of the init fork of an unlogged index is
+ WAL-logged (Heikki Linnakangas)
+ </p><p>
+ While an unlogged index's main data fork is not WAL-logged, its init
+ fork should be, to ensure that we have a consistent state to restore
+ the index to after a crash. This step was missed if the init fork
+ contains no data, which is a case not used by any standard index AM;
+ but perhaps some extension behaves that way.
+ </p></li><li class="listitem"><p>
+ Silence bogus <span class="quote">“<span class="quote">missing contrecord</span>”</span> errors (Thomas Munro)
+ </p><p>
+ Treat this case as plain end-of-WAL to avoid logging inaccurate
+ complaints from <span class="application">pg_waldump</span>
+ and <span class="application">walsender</span>.
+ </p></li><li class="listitem"><p>
+ Fix overly strict assertion in <code class="type">jsonpath</code> code
+ (David Rowley)
+ </p><p>
+ This assertion failed if a query applied
+ the <code class="literal">.type()</code> operator to
+ a <code class="literal">like_regex</code> result.
+ There was no bug in non-assert builds.
+ </p></li><li class="listitem"><p>
+ Avoid assertion failure when processing an empty statement via the
+ extended query protocol in an already-aborted transaction (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Avoid assertion failure when
+ the <code class="varname">stats_fetch_consistency</code> setting is changed
+ intra-transaction (Kyotaro Horiguchi)
+ </p></li><li class="listitem"><p>
+ Fix <code class="filename">contrib/fuzzystrmatch</code>'s
+ Soundex <code class="function">difference()</code> function to handle empty
+ input sanely (Alexander Lakhin, Tom Lane)
+ </p><p>
+ An input string containing no alphabetic characters resulted in
+ unpredictable output.
+ </p></li><li class="listitem"><p>
+ Tighten whitespace checks in <code class="filename">contrib/hstore</code>
+ input (Evan Jones)
+ </p><p>
+ In some cases, characters would be falsely recognized as whitespace
+ and hence discarded.
+ </p></li><li class="listitem"><p>
+ Disallow oversize input arrays
+ with <code class="filename">contrib/intarray</code>'s
+ <code class="literal">gist__int_ops</code> index opclass (Ankit Kumar Pandey,
+ Alexander Lakhin)
+ </p><p>
+ Previously this code would report a <code class="literal">NOTICE</code> but
+ press on anyway, creating an invalid index entry that presents a
+ risk of crashes when the index is read.
+ </p></li><li class="listitem"><p>
+ Avoid useless double decompression of GiST index entries
+ in <code class="filename">contrib/intarray</code> (Konstantin Knizhnik,
+ Matthias van de Meent, Tom Lane)
+ </p></li><li class="listitem"><p>
+ Fix <code class="filename">contrib/pageinspect</code>'s
+ <code class="function">gist_page_items()</code> function to work when there
+ are included index columns (Alexander Lakhin, Michael Paquier)
+ </p><p>
+ Previously, if the index has included
+ columns, <code class="function">gist_page_items()</code> would fail to
+ display those values on index leaf pages, or crash outright on
+ non-leaf pages.
+ </p></li><li class="listitem"><p>
+ In <span class="application">psql</span>, ignore
+ the <code class="envar">PSQL_WATCH_PAGER</code> environment variable when
+ stdin/stdout are not a terminal (Tom Lane)
+ </p><p>
+ This corresponds to the treatment of <code class="envar">PSQL_PAGER</code> in
+ commands besides <code class="command">\watch</code>.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">pg_dump</span> to correctly handle new-style
+ SQL-language functions whose bodies require parse-time dependencies
+ on unique indexes (Tom Lane)
+ </p><p>
+ Such cases can arise from <code class="literal">GROUP BY</code>
+ and <code class="literal">ON CONFLICT</code> clauses, for example. The
+ function must then be postponed until after the unique index in the
+ dump output, but <span class="application">pg_dump</span> did not do that
+ and instead printed a warning about <span class="quote">“<span class="quote">could not resolve
+ dependency loop</span>”</span>.
+ </p></li><li class="listitem"><p>
+ Improve <span class="application">pg_dump</span>'s display of details
+ about dependency-loop problems (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Avoid crash in <span class="application">pgbench</span> with an empty
+ pipeline and prepared mode (Álvaro Herrera)
+ </p></li><li class="listitem"><p>
+ Ensure
+ that <code class="structname">pg_index</code>.<code class="structfield">indisreplident</code>
+ is kept up-to-date in relation cache entries (Shruthi Gowda)
+ </p><p>
+ This value could be stale in some cases. There is no core code that
+ relies on the relation cache's copy, so this is only a latent bug as
+ far as Postgres itself is concerned; but there may be extensions for
+ which it is a live bug.
+ </p></li><li class="listitem"><p>
+ Fix <span class="application">make_etags</span> script to work with
+ non-Exuberant <span class="application">ctags</span> (Masahiko Sawada)
+ </p></li></ul></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release.html" title="Appendix E. Release Notes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release-15-3.html" title="E.2. Release 15.3">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Appendix E. Release Notes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> E.2. Release 15.3</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release-15.html b/doc/src/sgml/html/release-15.html
new file mode 100644
index 0000000..5f14523
--- /dev/null
+++ b/doc/src/sgml/html/release-15.html
@@ -0,0 +1,1113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>E.5. Release 15</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release-15-1.html" title="E.4. Release 15.1" /><link rel="next" href="release-prior.html" title="E.6. Prior Releases" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">E.5. Release 15</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release-15-1.html" title="E.4. Release 15.1">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><th width="60%" align="center">Appendix E. Release Notes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release-prior.html" title="E.6. Prior Releases">Next</a></td></tr></table><hr /></div><div class="sect1" id="RELEASE-15"><div class="titlepage"><div><div><h2 class="title" style="clear: both">E.5. Release 15</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="release-15.html#id-1.11.6.9.3">E.5.1. Overview</a></span></dt><dt><span class="sect2"><a href="release-15.html#id-1.11.6.9.4">E.5.2. Migration to Version 15</a></span></dt><dt><span class="sect2"><a href="release-15.html#id-1.11.6.9.5">E.5.3. Changes</a></span></dt><dt><span class="sect2"><a href="release-15.html#RELEASE-15-ACKNOWLEDGEMENTS">E.5.4. Acknowledgments</a></span></dt></dl></div><p><strong>Release date: </strong>2022-10-13</p><div class="sect2" id="id-1.11.6.9.3"><div class="titlepage"><div><div><h3 class="title">E.5.1. Overview</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> 15 contains many new features
+ and enhancements, including:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Support for the <acronym class="acronym">SQL</acronym>
+ <a class="link" href="sql-merge.html" title="MERGE"><code class="command">MERGE</code></a> command.
+ </p></li><li class="listitem"><p>
+ Selective publication of tables' contents within
+ <a class="link" href="logical-replication.html" title="Chapter 31. Logical Replication">logical replication</a>
+ publications, through the ability to specify column lists and
+ row filter conditions.
+ </p></li><li class="listitem"><p>
+ More options for compression, including support for Zstandard (zstd)
+ compression. This includes support for performing compression on
+ the server side during
+ <a class="link" href="app-pgbasebackup.html" title="pg_basebackup"><span class="application">pg_basebackup</span></a>.
+ </p></li><li class="listitem"><p>
+ Support for structured <a class="link" href="runtime-config-logging.html#GUC-LOG-DESTINATION">server
+ log output</a> using the <acronym class="acronym">JSON</acronym> format.
+ </p></li><li class="listitem"><p>
+ Performance improvements, particularly for in-memory and on-disk
+ sorting.
+ </p></li></ul></div><p>
+ The above items and other new features of
+ <span class="productname">PostgreSQL</span> 15 are explained in more detail
+ in the sections below.
+ </p></div><div class="sect2" id="id-1.11.6.9.4"><div class="titlepage"><div><div><h3 class="title">E.5.2. Migration to Version 15</h3></div></div></div><p>
+ A dump/restore using <a class="xref" href="app-pg-dumpall.html" title="pg_dumpall"><span class="refentrytitle"><span class="application">pg_dumpall</span></span></a> or use of
+ <a class="xref" href="pgupgrade.html" title="pg_upgrade"><span class="refentrytitle"><span class="application">pg_upgrade</span></span></a> or logical replication is required for
+ those wishing to migrate data from any previous release. See <a class="xref" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster">Section 19.6</a> for general information on migrating to new
+ major releases.
+ </p><p>
+ Version 15 contains a number of changes that may affect compatibility
+ with previous releases. Observe the following incompatibilities:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Remove <code class="literal">PUBLIC</code> creation permission on the <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PUBLIC" title="5.9.2. The Public Schema"><code class="literal">public</code> schema</a>
+ (Noah Misch)
+ </p><p>
+ The new default is one of the secure schema usage patterns that <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">Section 5.9.6</a> has recommended since the security
+ release for CVE-2018-1058. The change applies to new database
+ clusters and to newly-created databases in existing clusters.
+ Upgrading a cluster or restoring a database dump will preserve
+ <code class="literal">public</code>'s existing permissions.
+ </p><p>
+ For existing databases, especially those having multiple users,
+ consider revoking <code class="literal">CREATE</code> permission on
+ the <code class="literal">public</code> schema to adopt this new default.
+ For new databases having no need to defend against insider threats,
+ granting <code class="literal">CREATE</code> permission will yield the behavior
+ of prior releases.
+ </p></li><li class="listitem"><p>
+ Change the owner of the <code class="literal">public</code> schema to be the
+ new <code class="literal">pg_database_owner</code> role (Noah Misch)
+ </p><p>
+ This allows each database's owner to have ownership privileges on
+ the <code class="literal">public</code> schema within their database.
+ Previously it was owned by the bootstrap superuser, so that
+ non-superuser database owners could not do anything with it.
+ </p><p>
+ This change applies to new database clusters and to newly-created
+ databases in existing clusters.
+ Upgrading a cluster or restoring a database dump will preserve
+ <code class="literal">public</code>'s existing ownership specification.
+ </p></li><li class="listitem"><p>
+ Remove long-deprecated <a class="link" href="continuous-archiving.html#BACKUP-BASE-BACKUP" title="26.3.2. Making a Base Backup">exclusive
+ backup mode</a> (David Steele, Nathan Bossart)
+ </p><p>
+ If the database server stops abruptly while in this mode, the
+ server could fail to start. The non-exclusive backup mode is
+ considered superior for all purposes. Functions
+ <code class="function">pg_start_backup()</code>/<code class="function">pg_stop_backup()</code>
+ have been renamed to
+ <code class="function">pg_backup_start()</code>/<code class="function">pg_backup_stop()</code>,
+ and the functions <code class="function">pg_backup_start_time()</code>
+ and <code class="function">pg_is_in_backup()</code> have been removed.
+ </p></li><li class="listitem"><p>
+ Increase <a class="link" href="runtime-config-resource.html#GUC-HASH-MEM-MULTIPLIER"><code class="varname">hash_mem_multiplier</code></a>
+ default to 2.0 (Peter Geoghegan)
+ </p><p>
+ This allows query hash operations to use more
+ <a class="link" href="runtime-config-resource.html#GUC-WORK-MEM"><code class="varname">work_mem</code></a>
+ memory than other operations.
+ </p></li><li class="listitem"><p>
+ Remove server-side language <a class="link" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language"><code class="literal">plpython2u</code></a> and generic
+ Python language <code class="literal">plpythonu</code> (Andres Freund)
+ </p><p>
+ Python 2.x is no longer supported. While the original intent of
+ <code class="literal">plpythonu</code> was that it could eventually refer
+ to <code class="literal">plpython3u</code>, changing it now seems more likely
+ to cause problems than solve them, so it's just been removed.
+ </p></li><li class="listitem"><p>
+ Generate an error if <a class="link" href="functions-textsearch.html#TEXTSEARCH-FUNCTIONS-TABLE" title="Table 9.43. Text Search Functions"><code class="function">array_to_tsvector()</code></a>
+ is passed an empty-string array element (Jean-Christophe Arnu)
+ </p><p>
+ This is prohibited because lexemes should never be empty. Users of
+ previous Postgres releases should verify that no empty lexemes
+ are stored because they can lead to dump/restore failures and
+ inconsistent results.
+ </p></li><li class="listitem"><p>
+ Generate an error when <a class="link" href="functions-string.html#FUNCTIONS-STRING-OTHER" title="Table 9.10. Other String Functions and Operators"><code class="function">chr()</code></a>
+ is supplied with a negative argument (Peter Eisentraut)
+ </p></li><li class="listitem"><p>
+ Prevent <a class="link" href="sql-createview.html" title="CREATE VIEW"><code class="command">CREATE OR REPLACE
+ VIEW</code></a> from changing the collation of an output column
+ (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Disallow zero-length <a class="link" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS" title="4.1.1. Identifiers and Key Words">Unicode identifiers</a>,
+ e.g., <code class="literal">U&amp;""</code>
+ (Peter Eisentraut)
+ </p><p>
+ Non-Unicode zero-length identifiers were already disallowed.
+ </p></li><li class="listitem"><p>
+ Prevent <a class="link" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-NUMERIC" title="4.1.2.6. Numeric Constants">numeric
+ literals</a> from having non-numeric trailing characters (Peter
+ Eisentraut)
+ </p><p>
+ Previously, query text like <code class="literal">123abc</code> would be
+ interpreted as <code class="literal">123</code> followed
+ by a separate token <code class="literal">abc</code>.
+ </p></li><li class="listitem"><p>
+ Adjust <a class="link" href="datatype-json.html" title="8.14. JSON Types"><acronym class="acronym">JSON</acronym></a>
+ numeric literal processing to match the
+ <acronym class="acronym">SQL</acronym>/<acronym class="acronym">JSON</acronym>-standard (Peter
+ Eisentraut)
+ </p><p>
+ This accepts numeric formats like <code class="literal">.1</code> and
+ <code class="literal">1.</code>, and disallows trailing junk after numeric
+ literals, like <code class="literal">1.type()</code>.
+ </p></li><li class="listitem"><p>
+ When <a class="link" href="datatype-datetime.html" title="8.5. Date/Time Types"><code class="type">interval</code></a>
+ input provides a fractional value for a unit greater than months,
+ round to the nearest month (Bruce Momjian)
+ </p><p>
+ For example, convert <code class="literal">1.99 years</code> to <code class="literal">2
+ years</code>, not <code class="literal">1 year 11 months</code> as before.
+ </p></li><li class="listitem"><p>
+ Improve consistency of <code class="type">interval</code> parsing with trailing
+ periods (Tom Lane)
+ </p><p>
+ Numbers with trailing periods were rejected on some platforms.
+ </p></li><li class="listitem"><p>
+ Mark the <code class="type">interval</code> output
+ function as stable, not immutable, since it depends on <a class="link" href="runtime-config-client.html#GUC-INTERVALSTYLE"><code class="varname">IntervalStyle</code></a>
+ (Tom Lane)
+ </p><p>
+ This will, for example, cause creation of indexes relying on the
+ text output of <code class="type">interval</code> values to fail.
+ </p></li><li class="listitem"><p>
+ Detect integer overflow in <a class="link" href="functions-datetime.html#FUNCTIONS-DATETIME-TABLE" title="Table 9.33. Date/Time Functions">interval justification
+ functions</a> (Joe Koshakow)
+ </p><p>
+ The affected functions are <code class="function">justify_interval()</code>,
+ <code class="function">justify_hours()</code>, and
+ <code class="function">justify_days()</code>.
+ </p></li><li class="listitem"><p>
+ Change the I/O format of type <code class="type">"char"</code> for non-ASCII
+ characters (Tom Lane)
+ </p><p>
+ Bytes with the high bit set are now output as a backslash and three
+ octal digits, to avoid encoding issues.
+ </p></li><li class="listitem"><p>
+ Remove the default <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="literal">ADMIN
+ OPTION</code></a> privilege a login role has on its own role
+ membership (Robert Haas)
+ </p><p>
+ Previously, a login role could add/remove members of its own role,
+ even without <code class="literal">ADMIN OPTION</code> privilege.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="logical-replication.html" title="Chapter 31. Logical Replication">logical replication</a>
+ to run as the owner of the subscription (Mark Dilger)
+ </p><p>
+ Because row-level security policies are not checked, only superusers,
+ roles with <code class="literal">bypassrls</code>, and table owners can
+ replicate into tables with row-level security policies.
+ </p></li><li class="listitem"><p>
+ Prevent <code class="command">UPDATE</code> and <code class="command">DELETE</code>
+ <a class="link" href="logical-replication.html" title="Chapter 31. Logical Replication">logical replication</a>
+ operations on tables where the subscription owner does not have
+ <code class="command">SELECT</code> permission on the table (Jeff Davis)
+ </p><p>
+ <code class="command">UPDATE</code> and <code class="command">DELETE</code> commands
+ typically involve reading the table as well, so require the
+ subscription owner to have table <code class="command">SELECT</code>
+ permission.
+ </p></li><li class="listitem"><p>
+ When <a class="link" href="sql-explain.html" title="EXPLAIN"><code class="command">EXPLAIN</code></a>
+ references the session's temporary object schema, refer to it as
+ <code class="literal">pg_temp</code> (Amul Sul)
+ </p><p>
+ Previously the actual schema name was reported, leading to
+ inconsistencies across sessions.
+ </p></li><li class="listitem"><p>
+ Fix <a class="link" href="monitoring-stats.html#MONITORING-PG-STATIO-ALL-TABLES-VIEW" title="28.2.19. pg_statio_all_tables"><code class="structname">pg_statio_all_tables</code></a>
+ to sum values for the rare case of <acronym class="acronym">TOAST</acronym> tables
+ with multiple indexes (Andrei Zubkov)
+ </p><p>
+ Previously such cases would show one row for each index.
+ </p></li><li class="listitem"><p>
+ Disallow setting <a class="link" href="runtime-config-custom.html" title="20.16. Customized Options">custom
+ options</a> that match the name of an installed extension, but
+ are not one of the extension's declared variables
+ (Florin Irion, Tom Lane)
+ </p><p>
+ This change causes any such pre-existing variables to be deleted
+ during extension load, and then prevents new ones from being created
+ later in the session. The intent is to prevent confusion about
+ whether a variable is associated with an extension or not.
+ </p></li><li class="listitem"><p>
+ Remove obsolete server variable
+ <code class="varname">stats_temp_directory</code> (Andres Freund, Kyotaro
+ Horiguchi)
+ </p></li><li class="listitem"><p>
+ Improve the algorithm used to compute <a class="link" href="functions-math.html#FUNCTIONS-MATH-RANDOM-TABLE" title="Table 9.6. Random Functions"><code class="function">random()</code></a>
+ (Fabien Coelho)
+ </p><p>
+ This will cause <code class="function">random()</code>'s results to differ
+ from what was emitted by prior versions, even for the same seed
+ value.
+ </p></li><li class="listitem"><p>
+ <span class="application">libpq</span>'s <a class="link" href="libpq-async.html#LIBPQ-PQSENDQUERY"><code class="function">PQsendQuery()</code></a>
+ function is no longer supported in pipeline mode (Álvaro Herrera)
+ </p><p>
+ Applications that are using that combination will need to be
+ modified to use <code class="function">PQsendQueryParams()</code> instead.
+ </p></li><li class="listitem"><p>
+ On non-Windows platforms, consult the <code class="envar">HOME</code> environment
+ variable to find the user's home directory (Anders Kaseorg)
+ </p><p>
+ If <code class="envar">HOME</code> is empty or unset, fall back to the previous
+ method of checking the <code class="literal">&lt;pwd.h&gt;</code> database.
+ This change affects <span class="application">libpq</span> (for example,
+ while looking up <code class="filename">~/.pgpass</code>) as well as various
+ client application programs.
+ </p></li><li class="listitem"><p>
+ Remove <a class="link" href="app-pgdump.html" title="pg_dump"><span class="application">pg_dump</span></a>'s
+ <code class="option">--no-synchronized-snapshots</code> option (Tom Lane)
+ </p><p>
+ All still-supported server versions support synchronized snapshots,
+ so there's no longer a need for this option.
+ </p></li><li class="listitem"><p>
+ After an error is detected in <a class="link" href="app-psql.html" title="psql"><span class="application">psql</span></a>'s
+ <code class="option">--single-transaction</code> mode, change the
+ final <code class="command">COMMIT</code> command
+ to <code class="command">ROLLBACK</code> only
+ if <code class="varname">ON_ERROR_STOP</code> is set (Michael Paquier)
+ </p></li><li class="listitem"><p>
+ Avoid unnecessary casting of constants in queries sent by <a class="link" href="postgres-fdw.html" title="F.38. postgres_fdw">postgres_fdw</a> (Dian Fay)
+ </p><p>
+ When column types are intentionally different between local and
+ remote databases, such casts could cause errors.
+ </p></li><li class="listitem"><p>
+ Remove <a class="link" href="xml2.html" title="F.50. xml2">xml2</a>'s
+ <code class="function">xml_is_well_formed()</code> function (Tom Lane)
+ </p><p>
+ This function has been implemented in the core backend since
+ Postgres 9.1.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">custom scan providers</a>
+ to indicate if they support projections (Sven Klemm)
+ </p><p>
+ The default is now that custom scan providers are assumed to not
+ support projections; those that do will need to be updated for
+ this release.
+ </p></li></ul></div></div><div class="sect2" id="id-1.11.6.9.5"><div class="titlepage"><div><div><h3 class="title">E.5.3. Changes</h3></div></div></div><p>
+ Below you will find a detailed account of the changes between
+ <span class="productname">PostgreSQL</span> 15 and the previous major
+ release.
+ </p><div class="sect3" id="id-1.11.6.9.5.3"><div class="titlepage"><div><div><h4 class="title">E.5.3.1. Server</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Record and check the collation version of each <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE">database</a> (Peter Eisentraut)
+ </p><p>
+ This feature is designed to detect collation version
+ changes to avoid index corruption. Function
+ <code class="function">pg_database_collation_actual_version()</code>
+ reports the underlying operating system collation version, and
+ <code class="command">ALTER DATABASE ... REFRESH</code> sets the recorded
+ database collation version to match the operating system collation
+ version.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="locale.html" title="24.1. Locale Support"><acronym class="acronym">ICU</acronym></a>
+ collations to be set as the default for clusters and databases
+ (Peter Eisentraut)
+ </p><p>
+ Previously, only <span class="application">libc</span>-based
+ collations could be selected at the cluster and database levels.
+ <acronym class="acronym">ICU</acronym> collations could only be used via explicit
+ <code class="literal">COLLATE</code> clauses.
+ </p></li><li class="listitem"><p>
+ Add system view <a class="link" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings"><code class="structname">pg_ident_file_mappings</code></a>
+ to report <code class="filename">pg_ident.conf</code> information (Julien
+ Rouhaud)
+ </p></li></ul></div><div class="sect4" id="id-1.11.6.9.5.3.3"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.1. <a class="link" href="ddl-partitioning.html" title="5.11. Table Partitioning">Partitioning</a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Improve planning time for queries referencing partitioned tables
+ (David Rowley)
+ </p><p>
+ This change helps when only a few of many partitions are relevant.
+ </p></li><li class="listitem"><p>
+ Allow ordered scans of partitions to avoid sorting in more cases
+ (David Rowley)
+ </p><p>
+ Previously, a partitioned table with a <code class="literal">DEFAULT</code>
+ partition or a <code class="literal">LIST</code> partition containing
+ multiple values could not be used for ordered partition scans.
+ Now they can be used if such partitions are pruned during planning.
+ </p></li><li class="listitem"><p>
+ Improve foreign key behavior of updates on partitioned tables
+ that move rows between partitions (Amit Langote)
+ </p><p>
+ Previously, such updates ran a delete action on the source
+ partition and an insert action on the target partition.
+ <span class="productname">PostgreSQL</span> will now run an update action
+ on the partition root, providing cleaner semantics.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="sql-cluster.html" title="CLUSTER"><code class="command">CLUSTER</code></a>
+ on partitioned tables (Justin Pryzby)
+ </p></li><li class="listitem"><p>
+ Fix <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TRIGGER
+ RENAME</code></a> on partitioned tables to properly rename
+ triggers on all partitions (Arne Roland, Álvaro Herrera)
+ </p><p>
+ Also prohibit cloned triggers from being renamed.
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.3.4"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.2. Indexes</h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow btree indexes on system and <a class="link" href="storage-toast.html" title="73.2. TOAST"><acronym class="acronym">TOAST</acronym></a>
+ tables to efficiently store duplicates (Peter Geoghegan)
+ </p><p>
+ Previously de-duplication was disabled for these types of indexes.
+ </p></li><li class="listitem"><p>
+ Improve lookup performance
+ of <a class="link" href="gist.html" title="Chapter 68. GiST Indexes"><acronym class="acronym">GiST</acronym></a> indexes
+ that were built using sorting (Aliaksandr Kalenik, Sergei
+ Shoulbakov, Andrey Borodin)
+ </p></li><li class="listitem"><p>
+ Allow unique constraints and indexes to treat
+ <code class="literal">NULL</code> values as not distinct (Peter Eisentraut)
+ </p><p>
+ Previously <code class="literal">NULL</code> entries were always treated
+ as distinct values, but this can now be changed by creating
+ constraints and indexes using <code class="literal">UNIQUE NULLS NOT
+ DISTINCT</code>.
+ </p></li><li class="listitem"><p>
+ Allow the <a class="link" href="functions-string.html#FUNCTIONS-STRING-OTHER" title="Table 9.10. Other String Functions and Operators"><code class="literal">^@</code></a>
+ starts-with operator and the <code class="function">starts_with()</code>
+ function to use btree indexes if using the C collation (Tom Lane)
+ </p><p>
+ Previously these could only use <a class="link" href="spgist.html" title="Chapter 69. SP-GiST Indexes"><acronym class="acronym">SP-GiST</acronym></a> indexes.
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.3.5"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.3. Optimizer</h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow <a class="link" href="sql-createstatistics.html" title="CREATE STATISTICS">extended
+ statistics</a> to record statistics for a parent with all its
+ children (Tomas Vondra, Justin Pryzby)
+ </p><p>
+ Regular statistics already tracked parent and
+ parent-plus-all-children statistics separately.
+ </p></li><li class="listitem"><p>
+ Add server variable <a class="link" href="runtime-config-query.html#GUC-RECURSIVE-WORKTABLE-FACTOR"><code class="varname">recursive_worktable_factor</code></a>
+ to allow the user to specify the expected size of the working
+ table of a <a class="link" href="queries-with.html#QUERIES-WITH-RECURSIVE" title="7.8.2. Recursive Queries">recursive
+ query</a> (Simon Riggs)
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.3.6"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.4. General Performance</h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow hash lookup for <a class="link" href="functions-subquery.html#FUNCTIONS-SUBQUERY-NOTIN" title="9.23.3. NOT IN"><code class="literal">NOT IN</code></a>
+ clauses with many constants (David Rowley, James Coleman)
+ </p><p>
+ Previously the code always sequentially scanned the list of values.
+ </p></li><li class="listitem"><p>
+ Allow <code class="command">SELECT DISTINCT</code> to be parallelized
+ (David Rowley)
+ </p></li><li class="listitem"><p>
+ Speed up encoding validation of <acronym class="acronym">UTF</acronym>-8 text
+ by processing 16 bytes at a time
+ (John Naylor, Heikki Linnakangas)
+ </p><p>
+ This will improve text-heavy operations like <a class="link" href="sql-copy.html" title="COPY"><code class="command">COPY FROM</code></a>.
+ </p></li><li class="listitem"><p>
+ Improve performance for sorts that exceed <a class="link" href="runtime-config-resource.html#GUC-WORK-MEM"><code class="varname">work_mem</code></a>
+ (Heikki Linnakangas)
+ </p><p>
+ When the sort data no longer fits in <code class="varname">work_mem</code>,
+ switch to a batch sorting algorithm that uses more output streams
+ than before.
+ </p></li><li class="listitem"><p>
+ Improve performance and reduce memory consumption of in-memory
+ sorts (Ronan Dunklau, David Rowley, Thomas Munro, John Naylor)
+ </p></li><li class="listitem"><p>
+ Allow <acronym class="acronym">WAL</acronym> <a class="link" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full page writes</a> to use
+ LZ4 and Zstandard compression (Andrey Borodin, Justin Pryzby)
+ </p><p>
+ This is controlled by the <a class="link" href="runtime-config-wal.html#GUC-WAL-COMPRESSION"><code class="varname">wal_compression</code></a>
+ server setting.
+ </p></li><li class="listitem"><p>
+ Add support for writing <acronym class="acronym">WAL</acronym>
+ using <a class="link" href="runtime-config-wal.html#GUC-WAL-SYNC-METHOD">direct I/O</a> on
+ macOS (Thomas Munro)
+ </p><p>
+ This only works if <code class="literal">max_wal_senders = 0</code>
+ and <code class="literal">wal_level = minimal</code>.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">vacuum</a> to be more
+ aggressive in setting the oldest frozen and multi transaction id
+ (Peter Geoghegan)
+ </p></li><li class="listitem"><p>
+ Allow a query referencing multiple <a class="link" href="ddl-foreign-data.html" title="5.12. Foreign Data">foreign tables</a> to perform
+ parallel foreign table scans in more cases (Andrey Lepikhov,
+ Etsuro Fujita)
+ </p></li><li class="listitem"><p>
+ Improve the performance of <a class="link" href="functions-window.html" title="9.22. Window Functions">window
+ functions</a> that use <code class="function">row_number()</code>,
+ <code class="function">rank()</code>, <code class="function">dense_rank()</code> and
+ <code class="function">count()</code>
+ (David Rowley)
+ </p></li><li class="listitem"><p>
+ Improve the performance of spinlocks on high-core-count ARM64
+ systems (Geoffrey Blake)
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.3.7"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.5. Monitoring</h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Enable default logging of checkpoints and slow autovacuum
+ operations (Bharath Rupireddy)
+ </p><p>
+ This changes the default of <a class="link" href="runtime-config-logging.html#GUC-LOG-CHECKPOINTS"><code class="varname">log_checkpoints</code></a>
+ to <code class="literal">on</code> and that of <a class="link" href="runtime-config-logging.html#GUC-LOG-AUTOVACUUM-MIN-DURATION"><code class="varname">log_autovacuum_min_duration</code></a>
+ to 10 minutes. This will cause even an idle server to generate
+ some log output, which might cause problems on
+ resource-constrained servers without log file rotation. These
+ defaults should be changed in such cases.
+ </p></li><li class="listitem"><p>
+ Generate progress messages in the server log during slow server
+ starts (Nitin Jadhav, Robert Haas)
+ </p><p>
+ The messages report the cause of the delay. The time interval for
+ notification is controlled by the new server variable <a class="link" href="runtime-config-logging.html#GUC-LOG-STARTUP-PROGRESS-INTERVAL"><code class="varname">log_startup_progress_interval</code></a>.
+ </p></li><li class="listitem"><p>
+ Store <a class="link" href="monitoring-stats.html" title="28.2. The Cumulative Statistics System">cumulative statistics
+ system</a> data in shared memory (Kyotaro Horiguchi, Andres
+ Freund, Melanie Plageman)
+ </p><p>
+ Previously this data was sent to a statistics collector process
+ via <acronym class="acronym">UDP</acronym> packets, and could only be read by
+ sessions after transferring it via the file system. There is no
+ longer a separate statistics collector process.
+ </p></li><li class="listitem"><p>
+ Add additional information to <code class="command">VACUUM VERBOSE</code>
+ and autovacuum logging messages (Peter Geoghegan)
+ </p></li><li class="listitem"><p>
+ Add <a class="link" href="sql-explain.html" title="EXPLAIN"><code class="command">EXPLAIN
+ (BUFFERS)</code></a> output for temporary file block I/O
+ (Masahiko Sawada)
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="runtime-config-logging.html#GUC-LOG-DESTINATION">log output</a> in
+ <acronym class="acronym">JSON</acronym> format (Sehrope Sarkuni, Michael Paquier)
+ </p><p>
+ The new setting is <code class="literal">log_destination = jsonlog</code>.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="monitoring-stats.html#MONITORING-STATS-FUNCS-TABLE" title="Table 28.34. Additional Statistics Functions"><code class="function">pg_stat_reset_single_table_counters()</code></a>
+ to reset the counters of relations shared across all databases
+ (Sadhuprasad Patro)
+ </p></li><li class="listitem"><p>
+ Add <a class="link" href="monitoring-stats.html#WAIT-EVENT-TABLE" title="Table 28.4. Wait Event Types">wait events</a> for local
+ shell commands (Fujii Masao)
+ </p><p>
+ The new wait events are used when calling
+ <code class="varname">archive_command</code>,
+ <code class="varname">archive_cleanup_command</code>,
+ <code class="varname">restore_command</code> and
+ <code class="varname">recovery_end_command</code>.
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.3.8"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.6. Privileges</h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow table accesses done by
+ a <a class="link" href="sql-createview.html" title="CREATE VIEW">view</a> to optionally be
+ controlled by privileges of the view's caller (Christoph Heiss)
+ </p><p>
+ Previously, view accesses were always treated as being done by the
+ view's owner. That's still the default.
+ </p></li><li class="listitem"><p>
+ Allow members of the <a class="link" href="predefined-roles.html#PREDEFINED-ROLES-TABLE" title="Table 22.1. Predefined Roles"><code class="literal">pg_write_server_files</code></a>
+ predefined role to perform server-side base backups (Dagfinn
+ Ilmari Mannsåker)
+ </p><p>
+ Previously only superusers could perform such backups.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a>
+ to grant permissions to change individual server variables via
+ <code class="command">SET</code> and <code class="command">ALTER SYSTEM</code>
+ (Mark Dilger)
+ </p><p>
+ The new function <code class="function">has_parameter_privilege()</code>
+ reports on this privilege.
+ </p></li><li class="listitem"><p>
+ Add predefined role <a class="link" href="predefined-roles.html#PREDEFINED-ROLES-TABLE" title="Table 22.1. Predefined Roles"><code class="literal">pg_checkpoint</code></a>
+ that allows members to run <code class="command">CHECKPOINT</code>
+ (Jeff Davis)
+ </p><p>
+ Previously checkpoints could only be run by superusers.
+ </p></li><li class="listitem"><p>
+ Allow members of the <a class="link" href="predefined-roles.html#PREDEFINED-ROLES-TABLE" title="Table 22.1. Predefined Roles"><code class="literal">pg_read_all_stats</code></a>
+ predefined role to access the views <a class="link" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts"><code class="structname">pg_backend_memory_contexts</code></a>
+ and <a class="link" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations"><code class="structname">pg_shmem_allocations</code></a>
+ (Bharath Rupireddy)
+ </p><p>
+ Previously these views could only be accessed by superusers.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a>
+ to grant permissions on <a class="link" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL" title="9.27.2. Server Signaling Functions"><code class="function">pg_log_backend_memory_contexts()</code></a>
+ (Jeff Davis)
+ </p><p>
+ Previously this function could only be run by superusers.
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.3.9"><div class="titlepage"><div><div><h5 class="title">E.5.3.1.7. Server Configuration</h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add server variable <a class="link" href="runtime-config-preset.html#GUC-SHARED-MEMORY-SIZE"><code class="varname">shared_memory_size</code></a>
+ to report the size of allocated shared memory (Nathan Bossart)
+ </p></li><li class="listitem"><p>
+ Add server variable <a class="link" href="runtime-config-preset.html#GUC-SHARED-MEMORY-SIZE-IN-HUGE-PAGES"><code class="varname">shared_memory_size_in_huge_pages</code></a>
+ to report the number of huge memory pages required (Nathan Bossart)
+ </p><p>
+ This is only supported on Linux.
+ </p></li><li class="listitem"><p>
+ Honor server variable <a class="link" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES"><code class="varname">shared_preload_libraries</code></a>
+ in single-user mode (Jeff Davis)
+ </p><p>
+ This change supports use
+ of <code class="varname">shared_preload_libraries</code> to load custom
+ access methods and WAL resource managers, which would be essential
+ for database access even in single-user mode.
+ </p></li><li class="listitem"><p>
+ On Solaris, make the default setting of <a class="link" href="runtime-config-resource.html#GUC-DYNAMIC-SHARED-MEMORY-TYPE"><code class="varname">dynamic_shared_memory_type</code></a>
+ be <code class="literal">sysv</code> (Thomas Munro)
+ </p><p>
+ The previous default choice, <code class="literal">posix</code>, can result
+ in spurious failures on this platform.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="app-postgres.html" title="postgres"><code class="command">postgres
+ -C</code></a> to properly report runtime-computed values
+ (Nathan Bossart)
+ </p><p>
+ Previously runtime-computed values <a class="link" href="runtime-config-preset.html#GUC-DATA-CHECKSUMS"><code class="varname">data_checksums</code></a>,
+ <a class="link" href="runtime-config-preset.html#GUC-WAL-SEGMENT-SIZE"><code class="varname">wal_segment_size</code></a>,
+ and <a class="link" href="runtime-config-preset.html#GUC-DATA-DIRECTORY-MODE"><code class="varname">data_directory_mode</code></a>
+ would report values that would not be accurate on the running
+ server. However, this does not work on a running server.
+ </p></li></ul></div></div></div><div class="sect3" id="id-1.11.6.9.5.4"><div class="titlepage"><div><div><h4 class="title">E.5.3.2. Streaming Replication and Recovery</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add support for LZ4 and Zstandard compression of server-side <a class="link" href="continuous-archiving.html#BACKUP-BASE-BACKUP" title="26.3.2. Making a Base Backup">base backups</a> (Jeevan Ladhe,
+ Robert Haas)
+ </p></li><li class="listitem"><p>
+ Run the checkpointer and bgwriter processes during crash recovery
+ (Thomas Munro)
+ </p><p>
+ This helps to speed up long crash recoveries.
+ </p></li><li class="listitem"><p>
+ Allow <acronym class="acronym">WAL</acronym> processing to pre-fetch needed file
+ contents (Thomas Munro)
+ </p><p>
+ This is controlled by the server variable <a class="link" href="runtime-config-wal.html#GUC-RECOVERY-PREFETCH"><code class="varname">recovery_prefetch</code></a>.
+ </p></li><li class="listitem"><p>
+ Allow archiving via loadable modules (Nathan Bossart)
+ </p><p>
+ Previously, archiving was only done by calling shell commands.
+ The new server variable <a class="link" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY"><code class="varname">archive_library</code></a>
+ can be set to specify a library to be called for archiving.
+ </p></li><li class="listitem"><p>
+ No longer require <a class="link" href="protocol-replication.html" title="55.4. Streaming Replication Protocol"><code class="literal">IDENTIFY_SYSTEM</code></a>
+ to be run before <code class="literal">START_REPLICATION</code> (Jeff Davis)
+ </p></li></ul></div><div class="sect4" id="id-1.11.6.9.5.4.3"><div class="titlepage"><div><div><h5 class="title">E.5.3.2.1. <a class="link" href="logical-replication.html" title="Chapter 31. Logical Replication">Logical Replication</a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow <a class="link" href="sql-createpublication.html" title="CREATE PUBLICATION">publication</a> of
+ all tables in a schema (Vignesh C, Hou Zhijie, Amit Kapila)
+ </p><p>
+ For example, this syntax is now supported: <code class="literal">CREATE
+ PUBLICATION pub1 FOR TABLES IN SCHEMA s1,s2</code>.
+ <code class="command">ALTER PUBLICATION</code> supports a similar syntax.
+ Tables added later to the listed schemas will also be replicated.
+ </p></li><li class="listitem"><p>
+ Allow publication content to be filtered using a
+ <code class="literal">WHERE</code> clause (Hou Zhijie, Euler Taveira,
+ Peter Smith, Ajin Cherian, Tomas Vondra, Amit Kapila)
+ </p><p>
+ Rows not satisfying the <code class="literal">WHERE</code> clause are not
+ published.
+ </p></li><li class="listitem"><p>
+ Allow publication content to
+ be restricted to specific columns (Tomas Vondra, Álvaro Herrera,
+ Rahila Syed)
+ </p></li><li class="listitem"><p>
+ Allow skipping of transactions on a subscriber using <a class="link" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><code class="command">ALTER SUBSCRIPTION
+ ... SKIP</code></a> (Masahiko Sawada)
+ </p></li><li class="listitem"><p>
+ Add support for prepared (two-phase) transactions to logical
+ replication (Peter Smith, Ajin Cherian, Amit Kapila, Nikhil
+ Sontakke, Stas Kelvich)
+ </p><p>
+ The new <a class="link" href="protocol-replication.html" title="55.4. Streaming Replication Protocol"><code class="literal">CREATE_REPLICATION_SLOT</code></a>
+ option is called <code class="literal">TWO_PHASE</code>.
+ <span class="application">pg_recvlogical</span> now supports a new
+ <code class="option">--two-phase</code> option during slot creation.
+ </p></li><li class="listitem"><p>
+ Prevent logical replication of empty transactions (Ajin Cherian,
+ Hou Zhijie, Euler Taveira)
+ </p><p>
+ Previously, publishers would send empty transactions to
+ subscribers if subscribed tables were not modified.
+ </p></li><li class="listitem"><p>
+ Add <acronym class="acronym">SQL</acronym> functions to monitor the directory
+ contents of logical replication slots (Bharath Rupireddy)
+ </p><p>
+ The new functions are <a class="link" href="functions-admin.html#FUNCTIONS-ADMIN-GENFILE-TABLE" title="Table 9.99. Generic File Access Functions"><code class="function">pg_ls_logicalsnapdir()</code></a>,
+ <code class="function">pg_ls_logicalmapdir()</code>, and
+ <code class="function">pg_ls_replslotdir()</code>. They can be run by
+ members of the predefined <code class="literal">pg_monitor</code> role.
+ </p></li><li class="listitem"><p>
+ Allow subscribers to stop the application of logical replication changes on error
+ (Osumi Takamichi, Mark Dilger)
+ </p><p>
+ This is enabled with the subscriber option <a class="link" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><code class="literal">disable_on_error</code></a>
+ and avoids possible infinite error loops during stream application.
+ </p></li><li class="listitem"><p>
+ Adjust subscriber server variables to match the publisher so
+ datetime and float8 values are interpreted consistently (Japin Li)
+ </p><p>
+ Some publishers might be relying on inconsistent behavior.
+ </p></li><li class="listitem"><p>
+ Add system view <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SUBSCRIPTION-STATS" title="28.2.9. pg_stat_subscription_stats"><code class="structname">pg_stat_subscription_stats</code></a>
+ to report on subscriber activity (Masahiko Sawada)
+ </p><p>
+ The new function <a class="link" href="monitoring-stats.html#MONITORING-STATS-FUNCTIONS" title="28.2.24. Statistics Functions"><code class="function">pg_stat_reset_subscription_stats()</code></a>
+ allows resetting these statistics counters.
+ </p></li><li class="listitem"><p>
+ Suppress duplicate entries in the <a class="link" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables"><code class="structname">pg_publication_tables</code></a>
+ system view (Hou Zhijie)
+ </p><p>
+ In some cases a partition could appear more than once.
+ </p></li></ul></div></div></div><div class="sect3" id="id-1.11.6.9.5.5"><div class="titlepage"><div><div><h4 class="title">E.5.3.3. Utility Commands</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add <acronym class="acronym">SQL</acronym> <a class="link" href="sql-merge.html" title="MERGE"><code class="command">MERGE</code></a>
+ command to adjust one table to match another (Simon Riggs, Pavan
+ Deolasee, Álvaro Herrera, Amit Langote)
+ </p><p>
+ This is similar to <code class="command">INSERT ... ON CONFLICT</code>
+ but more batch-oriented.
+ </p></li><li class="listitem"><p>
+ Add support for <code class="literal">HEADER</code> option in <a class="link" href="sql-copy.html" title="COPY"><code class="command">COPY</code></a> text format
+ (Rémi Lapeyre)
+ </p><p>
+ The new option causes the column names to be output, and optionally
+ verified on input.
+ </p></li><li class="listitem"><p>
+ Add new <acronym class="acronym">WAL</acronym>-logged method for <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE">database creation</a> (Dilip Kumar)
+ </p><p>
+ This is the new default method for copying the template database,
+ as it avoids the need for checkpoints during database creation.
+ However, it might be slow if the template database is large, so
+ the old method is still available.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE"><code class="command">CREATE
+ DATABASE</code></a> to set the database <acronym class="acronym">OID</acronym>
+ (Shruthi Gowda, Antonin Houska)
+ </p></li><li class="listitem"><p>
+ Prevent <a class="link" href="sql-dropdatabase.html" title="DROP DATABASE"><code class="command">DROP
+ DATABASE</code></a>, <a class="link" href="sql-droptablespace.html" title="DROP TABLESPACE"><code class="command">DROP
+ TABLESPACE</code></a>, and <a class="link" href="sql-alterdatabase.html" title="ALTER DATABASE"><code class="command">ALTER DATABASE SET
+ TABLESPACE</code></a> from occasionally failing during
+ concurrent use on Windows (Thomas Munro)
+ </p></li><li class="listitem"><p>
+ Allow foreign key <a class="link" href="ddl-constraints.html#DDL-CONSTRAINTS-FK" title="5.4.5. Foreign Keys"><code class="literal">ON
+ DELETE SET</code></a> actions to affect only specified columns
+ (Paul Martinez)
+ </p><p>
+ Previously, all of the columns in the foreign key were always
+ affected.
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER
+ TABLE</code></a> to modify a table's <code class="literal">ACCESS
+ METHOD</code> (Justin Pryzby, Jeff Davis)
+ </p></li><li class="listitem"><p>
+ Properly call object access hooks when <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>
+ causes table rewrites (Michael Paquier)
+ </p></li><li class="listitem"><p>
+ Allow creation of unlogged <a class="link" href="sql-createsequence.html" title="CREATE SEQUENCE">sequences</a> (Peter Eisentraut)
+ </p></li><li class="listitem"><p>
+ Track dependencies on individual columns in the results of
+ functions returning composite types (Tom Lane)
+ </p><p>
+ Previously, if a view or rule contained a reference to a specific
+ column within the result of a composite-returning function, that
+ was not noted as a dependency; the view or rule was only considered
+ to depend on the composite type as a whole. This meant that
+ dropping the individual column would be allowed, causing problems
+ in later use of the view or rule. The column-level dependency is
+ now also noted, so that dropping such a column will be rejected
+ unless the view is changed or dropped.
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.6"><div class="titlepage"><div><div><h4 class="title">E.5.3.4. Data Types</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow the scale of
+ a <a class="link" href="datatype-numeric.html" title="8.1. Numeric Types"><code class="type">numeric</code></a>
+ value to be negative, or greater than its precision (Dean Rasheed,
+ Tom Lane)
+ </p><p>
+ This allows rounding of values to the left of the decimal point,
+ e.g., <code class="literal">'1234'::numeric(4, -2)</code> returns 1200.
+ </p></li><li class="listitem"><p>
+ Improve overflow detection when casting values to <a class="link" href="datatype-datetime.html" title="8.5. Date/Time Types">interval</a> (Joe Koshakow)
+ </p></li><li class="listitem"><p>
+ Change the I/O format of type <code class="type">"char"</code> for non-ASCII
+ characters (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Update the display width information of modern Unicode characters,
+ like emojis (Jacob Champion)
+ </p><p>
+ Also update from Unicode 5.0 to 14.0.0. There is now an automated
+ way to keep Postgres updated with Unicode releases.
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.7"><div class="titlepage"><div><div><h4 class="title">E.5.3.5. Functions</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add multirange input to <a class="link" href="functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE" title="Table 9.58. General-Purpose Aggregate Functions"><code class="function">range_agg()</code></a>
+ (Paul Jungwirth)
+ </p></li><li class="listitem"><p>
+ Add <a class="link" href="tutorial-agg.html" title="2.7. Aggregate Functions"><code class="function">MIN()</code></a>
+ and <code class="function">MAX()</code> aggregates for the <a class="link" href="datatype-numeric.html#DATATYPE-INT" title="8.1.1. Integer Types"><code class="type">xid8</code></a> data type (Ken Kato)
+ </p></li><li class="listitem"><p>
+ Add regular expression functions for compatibility with other
+ relational systems (Gilles Darold, Tom Lane)
+ </p><p>
+ The new functions are <a class="link" href="functions-string.html#FUNCTIONS-STRING-OTHER" title="Table 9.10. Other String Functions and Operators"><code class="function">regexp_count()</code></a>,
+ <code class="function">regexp_instr()</code>,
+ <code class="function">regexp_like()</code>, and
+ <code class="function">regexp_substr()</code>. Some new optional arguments
+ were also added to <code class="function">regexp_replace()</code>.
+ </p></li><li class="listitem"><p>
+ Add the ability to compute the distance between <a class="link" href="datatype-geometric.html#DATATYPE-POLYGON" title="8.8.6. Polygons"><code class="type">polygons</code></a> (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Add <a class="link" href="functions-formatting.html#FUNCTIONS-FORMATTING-TABLE" title="Table 9.26. Formatting Functions"><code class="function">to_char()</code></a>
+ format codes <code class="literal">of</code>, <code class="literal">tzh</code>, and
+ <code class="literal">tzm</code> (Nitin Jadhav)
+ </p><p>
+ The upper-case equivalents of these were already supported.
+ </p></li><li class="listitem"><p>
+ When applying <a class="link" href="functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT" title="9.9.4. AT TIME ZONE"><code class="literal">AT
+ TIME ZONE</code></a> to a <code class="type">time with time zone</code>
+ value, use the transaction start time rather than wall clock time
+ to determine whether DST applies (Aleksander Alekseev, Tom Lane)
+ </p><p>
+ This allows the conversion to be considered stable rather than
+ volatile, and it saves a kernel call per invocation.
+ </p></li><li class="listitem"><p>
+ Ignore NULL array elements in <a class="link" href="functions-textsearch.html#TEXTSEARCH-FUNCTIONS-TABLE" title="Table 9.43. Text Search Functions"><code class="function">ts_delete()</code></a> and
+ <code class="function">setweight()</code> functions with array arguments
+ (Jean-Christophe Arnu)
+ </p><p>
+ These functions effectively ignore empty-string array elements
+ (since those could never match a valid lexeme). It seems
+ consistent to let them ignore NULL elements too, instead of
+ failing.
+ </p></li><li class="listitem"><p>
+ Add support for petabyte units to <a class="link" href="functions-admin.html#FUNCTIONS-ADMIN-DBSIZE" title="Table 9.94. Database Object Size Functions"><code class="function">pg_size_pretty()</code></a>
+ and <code class="function">pg_size_bytes()</code> (David Christensen)
+ </p></li><li class="listitem"><p>
+ Change <a class="link" href="functions-event-triggers.html#PG-EVENT-TRIGGER-DDL-COMMAND-END-FUNCTIONS" title="9.29.1. Capturing Changes at Command End"><code class="function">pg_event_trigger_ddl_commands()</code></a>
+ to output references to other sessions' temporary schemas using the
+ actual schema name (Tom Lane)
+ </p><p>
+ Previously this function reported all temporary schemas as
+ <code class="literal">pg_temp</code>, but it's misleading to use that for any
+ but the current session's temporary schema.
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.8"><div class="titlepage"><div><div><h4 class="title">E.5.3.6. <a class="link" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">PL/pgSQL</a></h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Fix enforcement of PL/pgSQL variable <code class="literal">CONSTANT</code>
+ markings (Tom Lane)
+ </p><p>
+ Previously, a variable could be used as a <a class="link" href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-CALLING-PROCEDURE" title="43.6.3. Calling a Procedure"><code class="command">CALL</code></a>
+ output parameter or refcursor <code class="command">OPEN</code> variable
+ despite being marked <code class="literal">CONSTANT</code>.
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.9"><div class="titlepage"><div><div><h4 class="title">E.5.3.7. <a class="link" href="libpq.html" title="Chapter 34. libpq — C Library">libpq</a></h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow <acronym class="acronym">IP</acronym> address matching against a server
+ certificate's Subject Alternative Name (Jacob Champion)
+ </p></li><li class="listitem"><p>
+ Allow <code class="function">PQsslAttribute()</code> to report the
+ <acronym class="acronym">SSL</acronym> library type without requiring a libpq
+ connection (Jacob Champion)
+ </p></li><li class="listitem"><p>
+ Change query cancellations sent by the client to use the same
+ <acronym class="acronym">TCP</acronym> settings as normal client connections
+ (Jelte Fennema)
+ </p><p>
+ This allows configured <acronym class="acronym">TCP</acronym> timeouts to apply
+ to query cancel connections.
+ </p></li><li class="listitem"><p>
+ Prevent libpq event callback failures from forcing an error result
+ (Tom Lane)
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.10"><div class="titlepage"><div><div><h4 class="title">E.5.3.8. Client Applications</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow <a class="link" href="pgbench.html" title="pgbench"><span class="application">pgbench</span></a> to
+ retry after serialization and deadlock failures (Yugo Nagata,
+ Marina Polyakova)
+ </p></li></ul></div><div class="sect4" id="id-1.11.6.9.5.10.3"><div class="titlepage"><div><div><h5 class="title">E.5.3.8.1. <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Improve performance
+ of <span class="application">psql</span>'s <code class="command">\copy</code>
+ command, by sending data in larger chunks (Heikki Linnakangas)
+ </p></li><li class="listitem"><p>
+ Add <code class="command">\dconfig</code> command to report server variables
+ (Mark Dilger, Tom Lane)
+ </p><p>
+ This is similar to the server-side <code class="command">SHOW</code>
+ command, but it can process patterns to show multiple variables
+ conveniently.
+ </p></li><li class="listitem"><p>
+ Add <code class="command">\getenv</code> command
+ to assign the value of an environment variable to a
+ <span class="application">psql</span> variable (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Add <code class="literal">+</code> option to the
+ <code class="literal">\lo_list</code> and <code class="literal">\dl</code> commands to
+ show large-object privileges (Pavel Luzanov)
+ </p></li><li class="listitem"><p>
+ Add a pager option for the <code class="command">\watch</code>
+ command (Pavel Stehule, Thomas Munro)
+ </p><p>
+ This is only supported on Unix and is controlled by the
+ <code class="envar">PSQL_WATCH_PAGER</code> environment variable.
+ </p></li><li class="listitem"><p>
+ Make <span class="application">psql</span> include intra-query double-hyphen
+ comments in queries sent to the server (Tom Lane, Greg Nancarrow)
+ </p><p>
+ Previously such comments were removed from the query
+ before being sent. Double-hyphen comments that are before any
+ query text are not sent, and are not recorded as separate
+ <span class="application">psql</span> history entries.
+ </p></li><li class="listitem"><p>
+ Adjust <span class="application">psql</span> so
+ that <span class="application">Readline</span>'s
+ meta-<code class="literal">#</code> command will insert a double-hyphen
+ comment marker (Tom Lane)
+ </p><p>
+ Previously a pound marker was inserted, unless the user had taken
+ the trouble to configure a non-default comment marker.
+ </p></li><li class="listitem"><p>
+ Make <span class="application">psql</span> output all results when multiple
+ queries are passed to the server at once (Fabien Coelho)
+ </p><p>
+ Previously, only the last query result was displayed. The old
+ behavior can be restored by setting
+ the <code class="literal">SHOW_ALL_RESULTS</code> <span class="application">psql</span>
+ variable to <code class="literal">off</code>.
+ </p></li><li class="listitem"><p>
+ After an error is detected
+ in <code class="option">--single-transaction</code> mode, change the
+ final <code class="command">COMMIT</code> command
+ to <code class="command">ROLLBACK</code> only
+ if <code class="varname">ON_ERROR_STOP</code> is set (Michael Paquier)
+ </p><p>
+ Previously, detection of an error in a <code class="option">-c</code> command
+ or <code class="option">-f</code> script file would lead to
+ issuing <code class="command">ROLLBACK</code> at the end, regardless of the
+ value of <code class="varname">ON_ERROR_STOP</code>.
+ </p></li><li class="listitem"><p>
+ Improve <span class="application">psql</span>'s tab completion (Shinya
+ Kato, Dagfinn Ilmari Mannsåker, Peter Smith, Koyu Tanigawa,
+ Ken Kato, David Fetter, Haiying Tang, Peter Eisentraut, Álvaro
+ Herrera, Tom Lane, Masahiko Sawada)
+ </p></li><li class="listitem"><p>
+ Limit support of <span class="application">psql</span>'s backslash
+ commands to servers running <span class="productname">PostgreSQL</span>
+ 9.2 or later (Tom Lane)
+ </p><p>
+ Remove code that was only used when running with an older server.
+ Commands that do not require any version-specific adjustments
+ compared to 9.2 will still work.
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.10.4"><div class="titlepage"><div><div><h5 class="title">E.5.3.8.2. <a class="link" href="app-pgdump.html" title="pg_dump"><span class="application">pg_dump</span></a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Make <span class="application">pg_dump</span> dump
+ <code class="literal">public</code> schema ownership changes and security
+ labels (Noah Misch)
+ </p></li><li class="listitem"><p>
+ Improve performance of dumping databases with many objects
+ (Tom Lane)
+ </p><p>
+ This will also improve the performance of <a class="link" href="pgupgrade.html" title="pg_upgrade"><span class="application">pg_upgrade</span></a>.
+ </p></li><li class="listitem"><p>
+ Improve parallel <span class="application">pg_dump</span>'s performance
+ for tables with large <acronym class="acronym">TOAST</acronym> tables (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Add dump/restore option <code class="option">--no-table-access-method</code>
+ to force restore to only use the default table access method
+ (Justin Pryzby)
+ </p></li><li class="listitem"><p>
+ Limit support of <span class="application">pg_dump</span> and <a class="link" href="app-pg-dumpall.html" title="pg_dumpall"><span class="application">pg_dumpall</span></a>
+ to servers running <span class="productname">PostgreSQL</span> 9.2 or
+ later (Tom Lane)
+ </p></li></ul></div></div></div><div class="sect3" id="id-1.11.6.9.5.11"><div class="titlepage"><div><div><h4 class="title">E.5.3.9. Server Applications</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add new <a class="link" href="app-pgbasebackup.html" title="pg_basebackup"><span class="application">pg_basebackup</span></a>
+ option <code class="option">--target</code> to control the base backup location
+ (Robert Haas)
+ </p><p>
+ The new options are <code class="literal">server</code> to write the
+ backup locally and <code class="literal">blackhole</code> to discard the
+ backup (for testing).
+ </p></li><li class="listitem"><p>
+ Allow <span class="application">pg_basebackup</span> to do server-side
+ gzip, LZ4, and Zstandard compression and client-side LZ4 and
+ Zstandard compression of base backup files (Dipesh Pandit,
+ Jeevan Ladhe)
+ </p><p>
+ Client-side <code class="literal">gzip</code> compression was already
+ supported.
+ </p></li><li class="listitem"><p>
+ Allow <span class="application">pg_basebackup</span> to compress on
+ the server side and decompress on the client side before storage
+ (Dipesh Pandit)
+ </p><p>
+ This is accomplished by specifying compression on the server side
+ and plain output format.
+ </p></li><li class="listitem"><p>
+ Allow <span class="application">pg_basebackup</span>'s
+ <code class="option">--compress</code> option to control the compression
+ location (server or client), compression method, and compression
+ options (Michael Paquier, Robert Haas)
+ </p></li><li class="listitem"><p>
+ Add the LZ4 compression method to <a class="link" href="app-pgreceivewal.html" title="pg_receivewal"><span class="application">pg_receivewal</span></a>
+ (Georgios Kokolatos)
+ </p><p>
+ This is enabled via <code class="literal">--compress=lz4</code> and requires
+ binaries to be built using <code class="option">--with-lz4</code>.
+ </p></li><li class="listitem"><p>
+ Add additional capabilities to
+ <span class="application">pg_receivewal</span>'s
+ <code class="option">--compress</code> option (Georgios Kokolatos)
+ </p></li><li class="listitem"><p>
+ Improve <span class="application">pg_receivewal</span>'s ability to
+ restart at the proper <acronym class="acronym">WAL</acronym> location (Ronan
+ Dunklau)
+ </p><p>
+ Previously, <span class="application">pg_receivewal</span> would start
+ based on the <acronym class="acronym">WAL</acronym> file stored in the local archive
+ directory, or at the sending server's current <acronym class="acronym">WAL</acronym>
+ flush location. With this change, if the sending server is running
+ Postgres 15 or later, the local archive directory is empty, and
+ a replication slot is specified, the replication slot's restart
+ point will be used.
+ </p></li><li class="listitem"><p>
+ Add <a class="link" href="app-pgrewind.html" title="pg_rewind"><span class="application">pg_rewind</span></a>
+ option <code class="option">--config-file</code> to simplify use when server
+ configuration files are stored outside the data directory (Gunnar
+ Bluth)
+ </p></li></ul></div><div class="sect4" id="id-1.11.6.9.5.11.3"><div class="titlepage"><div><div><h5 class="title">E.5.3.9.1. <a class="link" href="pgupgrade.html" title="pg_upgrade"><span class="application">pg_upgrade</span></a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Store <span class="application">pg_upgrade</span>'s log and
+ temporary files in a subdirectory of the new cluster called
+ <code class="filename">pg_upgrade_output.d</code> (Justin Pryzby)
+ </p><p>
+ Previously such files were left in the current directory,
+ requiring manual cleanup. Now they are automatically removed on
+ successful completion of <span class="application">pg_upgrade</span>.
+ </p></li><li class="listitem"><p>
+ Disable default status reporting during
+ <span class="application">pg_upgrade</span> operation if the output is
+ not a terminal (Andres Freund)
+ </p><p>
+ The status reporting output can be enabled for non-tty usage by
+ using <code class="option">--verbose</code>.
+ </p></li><li class="listitem"><p>
+ Make <span class="application">pg_upgrade</span> report all databases
+ with invalid connection settings (Jeevan Ladhe)
+ </p><p>
+ Previously only the first database with an invalid connection
+ setting was reported.
+ </p></li><li class="listitem"><p>
+ Make <span class="application">pg_upgrade</span> preserve tablespace
+ and database OIDs, as well as relation relfilenode numbers
+ (Shruthi Gowda, Antonin Houska)
+ </p></li><li class="listitem"><p>
+ Add a <code class="option">--no-sync</code> option to
+ <span class="application">pg_upgrade</span> (Michael Paquier)
+ </p><p>
+ This is recommended only for testing.
+ </p></li><li class="listitem"><p>
+ Limit support of <span class="application">pg_upgrade</span> to old
+ servers running <span class="productname">PostgreSQL</span> 9.2 or later
+ (Tom Lane)
+ </p></li></ul></div></div><div class="sect4" id="id-1.11.6.9.5.11.4"><div class="titlepage"><div><div><h5 class="title">E.5.3.9.2. <a class="link" href="pgwaldump.html" title="pg_waldump"><span class="application">pg_waldump</span></a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow <span class="application">pg_waldump</span> output to be filtered by
+ relation file node, block number, fork number, and full page images
+ (David Christensen, Thomas Munro)
+ </p></li><li class="listitem"><p>
+ Make <span class="application">pg_waldump</span> report statistics
+ before an interrupted exit (Bharath Rupireddy)
+ </p><p>
+ For example, issuing a control-C in a terminal running
+ <code class="command">pg_waldump --stats --follow</code> will report the
+ current statistics before exiting. This does not work on Windows.
+ </p></li><li class="listitem"><p>
+ Improve descriptions of some transaction <acronym class="acronym">WAL</acronym>
+ records reported by <span class="application">pg_waldump</span>
+ (Masahiko Sawada, Michael Paquier)
+ </p></li><li class="listitem"><p>
+ Allow <span class="application">pg_waldump</span> to dump information
+ about multiple resource managers (Heikki Linnakangas)
+ </p><p>
+ This is enabled by specifying the <code class="option">--rmgr</code> option
+ multiple times.
+ </p></li></ul></div></div></div><div class="sect3" id="id-1.11.6.9.5.12"><div class="titlepage"><div><div><h4 class="title">E.5.3.10. Documentation</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add documentation for <a class="link" href="functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE" title="Table 9.71. System Catalog Information Functions"><code class="function">pg_encoding_to_char()</code></a>
+ and <code class="function">pg_char_to_encoding()</code> (Ian Lawrence
+ Barwick)
+ </p></li><li class="listitem"><p>
+ Document the <a class="link" href="functions-string.html#FUNCTIONS-STRING-OTHER" title="Table 9.10. Other String Functions and Operators"><code class="literal">^@</code></a>
+ starts-with operator (Tom Lane)
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.13"><div class="titlepage"><div><div><h4 class="title">E.5.3.11. Source Code</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Add support for continuous integration testing using cirrus-ci
+ (Andres Freund, Thomas Munro, Melanie Plageman)
+ </p></li><li class="listitem"><p>
+ Add configure option <a class="link" href="install-procedure.html#CONFIGURE-OPTIONS-FEATURES" title="17.4.1.2. PostgreSQL Features"><code class="option">--with-zstd</code></a>
+ to enable Zstandard builds (Jeevan Ladhe, Robert Haas, Michael
+ Paquier)
+ </p></li><li class="listitem"><p>
+ Add an ABI identifier field to the magic block in loadable
+ libraries, allowing
+ non-community <span class="productname">PostgreSQL</span> distributions
+ to identify libraries that are not compatible with other builds
+ (Peter Eisentraut)
+ </p><p>
+ An ABI field mismatch will generate an error at load time.
+ </p></li><li class="listitem"><p>
+ Create a new <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structfield">pg_type.typcategory</code></a>
+ value for <code class="type">"char"</code> (Tom Lane)
+ </p><p>
+ Some other internal-use-only types have also been assigned to this
+ category.
+ </p></li><li class="listitem"><p>
+ Add new protocol message <a class="link" href="protocol-replication.html#PROTOCOL-REPLICATION-BASE-BACKUP"><code class="literal">TARGET</code></a>
+ to specify a new <code class="command">COPY</code> method to be used for base
+ backups (Robert Haas)
+ </p><p>
+ <a class="link" href="app-pgbasebackup.html" title="pg_basebackup"><span class="application">pg_basebackup</span></a>
+ now uses this method.
+ </p></li><li class="listitem"><p>
+ Add new protocol message <a class="link" href="protocol-replication.html#PROTOCOL-REPLICATION-BASE-BACKUP"><code class="literal">COMPRESSION</code></a>
+ and <code class="literal">COMPRESSION_DETAIL</code> to specify the compression
+ method and options (Robert Haas)
+ </p></li><li class="listitem"><p>
+ Remove server support for old <code class="literal">BASE_BACKUP</code>
+ command syntax and base backup protocol (Robert Haas)
+ </p></li><li class="listitem"><p>
+ Add support for extensions to set custom backup targets (Robert
+ Haas)
+ </p></li><li class="listitem"><p>
+ Allow extensions to define custom <acronym class="acronym">WAL</acronym>
+ resource managers (Jeff Davis)
+ </p></li><li class="listitem"><p>
+ Add function <a class="link" href="functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE" title="Table 9.71. System Catalog Information Functions"><code class="function">pg_settings_get_flags()</code></a>
+ to get the flags of server variables (Justin Pryzby)
+ </p></li><li class="listitem"><p>
+ On Windows, export all the server's global variables using
+ <code class="literal">PGDLLIMPORT</code> markers (Robert Haas)
+ </p><p>
+ Previously, only specific variables were accessible to extensions
+ on Windows.
+ </p></li><li class="listitem"><p>
+ Require GNU <span class="application">make</span> version 3.81 or later
+ to build <span class="productname">PostgreSQL</span> (Tom Lane)
+ </p></li><li class="listitem"><p>
+ Require OpenSSL to build the <a class="link" href="pgcrypto.html" title="F.28. pgcrypto"><span class="application">pgcrypto</span></a>
+ extension (Peter Eisentraut)
+ </p></li><li class="listitem"><p>
+ Require <span class="application">Perl</span>
+ version 5.8.3 or later (Dagfinn Ilmari Mannsåker)
+ </p></li><li class="listitem"><p>
+ Require <span class="application">Python</span>
+ version 3.2 or later (Andres Freund)
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.6.9.5.14"><div class="titlepage"><div><div><h4 class="title">E.5.3.12. Additional Modules</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow <a class="link" href="amcheck.html" title="F.2. amcheck"><span class="application">amcheck</span></a> to
+ check sequences (Mark Dilger)
+ </p></li><li class="listitem"><p>
+ Improve <span class="application">amcheck</span> sanity checks for
+ <acronym class="acronym">TOAST</acronym> tables (Mark Dilger)
+ </p></li><li class="listitem"><p>
+ Add new module <span class="application"><a class="link" href="basebackup-to-shell.html" title="F.5. basebackup_to_shell">basebackup_to_shell</a></span>
+ as an example of a custom backup target (Robert Haas)
+ </p></li><li class="listitem"><p>
+ Add new module <a class="link" href="basic-archive.html" title="F.6. basic_archive"><span class="application">basic_archive</span></a>
+ as an example of performing archiving via a library (Nathan Bossart)
+ </p></li><li class="listitem"><p>
+ Allow <a class="link" href="btree-gist.html" title="F.9. btree_gist"><span class="application">btree_gist</span></a>
+ indexes on boolean columns (Emre Hasegeli)
+ </p><p>
+ These can be used for exclusion constraints.
+ </p></li><li class="listitem"><p>
+ Fix <a class="link" href="pageinspect.html" title="F.25. pageinspect"><span class="application">pageinspect</span></a>'s
+ <code class="function">page_header()</code> to handle 32-kilobyte page sizes
+ (Quan Zongliang)
+ </p><p>
+ Previously, improper negative values could be returned in certain
+ cases.
+ </p></li><li class="listitem"><p>
+ Add counters for temporary file block I/O to <a class="link" href="pgstatstatements.html" title="F.32. pg_stat_statements"><span class="application">pg_stat_statements</span></a>
+ (Masahiko Sawada)
+ </p></li><li class="listitem"><p>
+ Add <acronym class="acronym">JIT</acronym> counters to pg_stat_statements (Magnus
+ Hagander)
+ </p></li><li class="listitem"><p>
+ Add new module <a class="link" href="pgwalinspect.html" title="F.37. pg_walinspect"><span class="application">pg_walinspect</span></a>
+ (Bharath Rupireddy)
+ </p><p>
+ This gives <acronym class="acronym">SQL</acronym>-level output similar to <a class="link" href="pgwaldump.html" title="pg_waldump"><span class="application">pg_waldump</span></a>.
+ </p></li><li class="listitem"><p>
+ Indicate the permissive/enforcing state in <a class="link" href="sepgsql.html" title="F.40. sepgsql"><span class="application">sepgsql</span></a> log
+ messages (Dave Page)
+ </p></li></ul></div><div class="sect4" id="id-1.11.6.9.5.14.3"><div class="titlepage"><div><div><h5 class="title">E.5.3.12.1. <a class="link" href="postgres-fdw.html" title="F.38. postgres_fdw"><span class="application">postgres_fdw</span></a></h5></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Allow postgres_fdw to push down <code class="literal">CASE</code> expressions
+ (Alexander Pyhalov)
+ </p></li><li class="listitem"><p>
+ Add server variable
+ <code class="varname">postgres_fdw.application_name</code> to control the
+ application name of postgres_fdw connections (Hayato Kuroda)
+ </p><p>
+ Previously the remote session's <a class="link" href="runtime-config-logging.html#GUC-APPLICATION-NAME"><code class="varname">application_name</code></a>
+ could only be set on the remote server or via a
+ <span class="application">postgres_fdw</span> connection specification.
+ <code class="varname">postgres_fdw.application_name</code> supports some
+ escape sequences for customization, making it easier to tell such
+ connections apart on the remote server.
+ </p></li><li class="listitem"><p>
+ Allow parallel commit on <span class="application">postgres_fdw</span>
+ servers (Etsuro Fujita)
+ </p><p>
+ This is enabled with the <code class="literal">CREATE SERVER</code> option
+ <code class="literal">parallel_commit</code>.
+ </p></li></ul></div></div></div></div><div class="sect2" id="RELEASE-15-ACKNOWLEDGEMENTS"><div class="titlepage"><div><div><h3 class="title">E.5.4. Acknowledgments</h3></div></div></div><p>
+ The following individuals (in alphabetical order) have contributed
+ to this release as patch authors, committers, reviewers, testers,
+ or reporters of issues.
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td>Abhijit Menon-Sen</td></tr><tr><td>Adam Brusselback</td></tr><tr><td>Adam Mackler</td></tr><tr><td>Adrian Ho</td></tr><tr><td>Ahsan Hadi</td></tr><tr><td>Ajin Cherian</td></tr><tr><td>Alastair McKinley</td></tr><tr><td>Aleksander Alekseev</td></tr><tr><td>Ales Zeleny</td></tr><tr><td>Alex Kingsborough</td></tr><tr><td>Alex Kozhemyakin</td></tr><tr><td>Alexander Korotkov</td></tr><tr><td>Alexander Kukushkin</td></tr><tr><td>Alexander Lakhin</td></tr><tr><td>Alexander Nawratil</td></tr><tr><td>Alexander Pyhalov</td></tr><tr><td>Alexey Borzov</td></tr><tr><td>Alexey Ermakov</td></tr><tr><td>Aliaksandr Kalenik</td></tr><tr><td>Álvaro Herrera</td></tr><tr><td>Amit Kapila</td></tr><tr><td>Amit Khandekar</td></tr><tr><td>Amit Langote</td></tr><tr><td>Amul Sul</td></tr><tr><td>Anastasia Lubennikova</td></tr><tr><td>Anders Kaseorg</td></tr><tr><td>Andreas Dijkman</td></tr><tr><td>Andreas Grob</td></tr><tr><td>Andreas Seltenreich</td></tr><tr><td>Andrei Zubkov</td></tr><tr><td>Andres Freund</td></tr><tr><td>Andrew Alsup</td></tr><tr><td>Andrew Bille</td></tr><tr><td>Andrew Dunstan</td></tr><tr><td>Andrew Gierth</td></tr><tr><td>Andrew Kesper</td></tr><tr><td>Andrey Borodin</td></tr><tr><td>Andrey Lepikhov</td></tr><tr><td>Andrey Sokolov</td></tr><tr><td>Andy Fan</td></tr><tr><td>Anton Melnikov</td></tr><tr><td>Anton Voloshin</td></tr><tr><td>Antonin Houska</td></tr><tr><td>Arjan van de Ven</td></tr><tr><td>Arne Roland</td></tr><tr><td>Arthur Zakirov</td></tr><tr><td>Ashutosh Bapat</td></tr><tr><td>Ashutosh Sharma</td></tr><tr><td>Ashwin Agrawal</td></tr><tr><td>Asif Rehman</td></tr><tr><td>Asim Praveen</td></tr><tr><td>Atsushi Torikoshi</td></tr><tr><td>Aya Iwata</td></tr><tr><td>Bauyrzhan Sakhariyev</td></tr><tr><td>Benoit Lobréau</td></tr><tr><td>Bernd Dorn</td></tr><tr><td>Bertrand Drouvot</td></tr><tr><td>Bharath Rupireddy</td></tr><tr><td>Björn Harrtell</td></tr><tr><td>Boris Kolpackov</td></tr><tr><td>Boris Korzun</td></tr><tr><td>Brad Nicholson</td></tr><tr><td>Brar Piening</td></tr><tr><td>Bruce Momjian</td></tr><tr><td>Bruno da Silva</td></tr><tr><td>Bryn Llewellyn</td></tr><tr><td>Carl Sopchak</td></tr><tr><td>Cary Huang</td></tr><tr><td>Chapman Flack</td></tr><tr><td>Chen Jiaoqian</td></tr><tr><td>Chris Bandy</td></tr><tr><td>Chris Lowder</td></tr><tr><td>Christian Quest</td></tr><tr><td>Christoph Berg</td></tr><tr><td>Christoph Heiss</td></tr><tr><td>Christophe Pettus</td></tr><tr><td>Christopher Painter-Wakefield</td></tr><tr><td>Claudio Freire</td></tr><tr><td>Clemens Zeidler</td></tr><tr><td>Corey Huinker</td></tr><tr><td>Dag Lem</td></tr><tr><td>Dagfinn Ilmari Mannsåker</td></tr><tr><td>Dan Kubb</td></tr><tr><td>Daniel Cherniy</td></tr><tr><td>Daniel Gustafsson</td></tr><tr><td>Daniel Polski</td></tr><tr><td>Daniel Vérité</td></tr><tr><td>Daniel Westermann</td></tr><tr><td>Daniele Varrazzo</td></tr><tr><td>Daniil Anisimov</td></tr><tr><td>Danny Shemesh</td></tr><tr><td>Darafei Praliaskouski</td></tr><tr><td>Daria Lepikhova</td></tr><tr><td>Dave Cramer</td></tr><tr><td>Dave Page</td></tr><tr><td>David Christensen</td></tr><tr><td>David Fetter</td></tr><tr><td>David G. Johnston</td></tr><tr><td>David Rowley</td></tr><tr><td>David Steele</td></tr><tr><td>David Zhang</td></tr><tr><td>Dean Rasheed</td></tr><tr><td>Dian Fay</td></tr><tr><td>Dilip Kumar</td></tr><tr><td>Dipesh Pandit</td></tr><tr><td>Dmitry Dolgov</td></tr><tr><td>Dmitry Koval</td></tr><tr><td>Dmitry Marakasov</td></tr><tr><td>Dominique Devienne</td></tr><tr><td>Dong Wook</td></tr><tr><td>Drew DeVault</td></tr><tr><td>Eduard Català</td></tr><tr><td>Egor Chindyaskin</td></tr><tr><td>Egor Rogov</td></tr><tr><td>Ekaterina Kiryanova</td></tr><tr><td>Elena Indrupskaya</td></tr><tr><td>Elvis Pranskevichus</td></tr><tr><td>Emmanuel Quincerot</td></tr><tr><td>Emre Hasegeli</td></tr><tr><td>Eric Mutta</td></tr><tr><td>Erica Zhang</td></tr><tr><td>Erik Rijkers</td></tr><tr><td>Erki Eessaar</td></tr><tr><td>Etsuro Fujita</td></tr><tr><td>Euler Taveira</td></tr><tr><td>Fabien Coelho</td></tr><tr><td>Fabrice Chapuis</td></tr><tr><td>Fabrice Fontaine</td></tr><tr><td>Fabrízio de Royes Mello</td></tr><tr><td>Feike Steenbergen</td></tr><tr><td>Filip Gospodinov</td></tr><tr><td>Florin Irion</td></tr><tr><td>Floris Van Nee</td></tr><tr><td>Frédéric Yhuel</td></tr><tr><td>Gabriela Serventi</td></tr><tr><td>Gaurab Dey</td></tr><tr><td>Geoff Winkless</td></tr><tr><td>Geoffrey Blake</td></tr><tr><td>Georgios Kokolatos</td></tr><tr><td>Gilles Darold</td></tr><tr><td>Greg Nancarrow</td></tr><tr><td>Greg Rychlewski</td></tr><tr><td>Greg Sabino Mullane</td></tr><tr><td>Greg Stark</td></tr><tr><td>Gregory Smith</td></tr><tr><td>Guillaume Lelarge</td></tr><tr><td>Gunnar Bluth</td></tr><tr><td>Gurjeet Singh</td></tr><tr><td>Haiyang Wang</td></tr><tr><td>Haiying Tang</td></tr><tr><td>Hannu Krosing</td></tr><tr><td>Hans Buschmann</td></tr><tr><td>Hayato Kuroda</td></tr><tr><td>Heath Lord</td></tr><tr><td>Heikki Linnakangas</td></tr><tr><td>Herwig Goemans</td></tr><tr><td>Himanshu Upadhyaya</td></tr><tr><td>Holly Roberts</td></tr><tr><td>Hou Zhijie</td></tr><tr><td>Hubert Lubaczewski</td></tr><tr><td>Ian Barwick</td></tr><tr><td>Ian Campbell</td></tr><tr><td>Ibrar Ahmed</td></tr><tr><td>Ildus Kurbangaliev</td></tr><tr><td>Ilya Anfimov</td></tr><tr><td>Itamar Gafni</td></tr><tr><td>Jacob Champion</td></tr><tr><td>Jaime Casanova</td></tr><tr><td>Jakub Wartak</td></tr><tr><td>James Coleman</td></tr><tr><td>James Hilliard</td></tr><tr><td>James Inform</td></tr><tr><td>Jan Piotrowski</td></tr><tr><td>Japin Li</td></tr><tr><td>Jason Harvey</td></tr><tr><td>Jason Kim</td></tr><tr><td>Jean-Christophe Arnu</td></tr><tr><td>Jeevan Ladhe</td></tr><tr><td>Jeff Davis</td></tr><tr><td>Jeff Janes</td></tr><tr><td>Jehan-Guillaume de Rorthais</td></tr><tr><td>Jelte Fennema</td></tr><tr><td>Jeremy Evans</td></tr><tr><td>Jeremy Schneider</td></tr><tr><td>Jian Guo</td></tr><tr><td>Jian He</td></tr><tr><td>Jimmy Yih</td></tr><tr><td>Jiri Fejfar</td></tr><tr><td>Jitka Plesníková</td></tr><tr><td>Joe Conway</td></tr><tr><td>Joe Wildish</td></tr><tr><td>Joel Jacobson</td></tr><tr><td>Joey Bodoia</td></tr><tr><td>John Naylor</td></tr><tr><td>Jonathan Katz</td></tr><tr><td>Josef Simanek</td></tr><tr><td>Joseph Koshakow</td></tr><tr><td>Josh Soref</td></tr><tr><td>Joshua Brindle</td></tr><tr><td>Juan José Santamaría Flecha</td></tr><tr><td>Julien Rouhaud</td></tr><tr><td>Julien Roze</td></tr><tr><td>Junwang Zhao</td></tr><tr><td>Jürgen Purtz</td></tr><tr><td>Justin Pryzby</td></tr><tr><td>Ken Kato</td></tr><tr><td>Kevin Burke</td></tr><tr><td>Kevin Grittner</td></tr><tr><td>Kevin Humphreys</td></tr><tr><td>Kevin McKibbin</td></tr><tr><td>Kevin Sweet</td></tr><tr><td>Kevin Zheng</td></tr><tr><td>Klaudie Willis</td></tr><tr><td>Konstantin Knizhnik</td></tr><tr><td>Konstantina Skovola</td></tr><tr><td>Kosei Masumura</td></tr><tr><td>Kotaro Kawamoto</td></tr><tr><td>Koyu Tanigawa</td></tr><tr><td>Kuntal Ghosh</td></tr><tr><td>Kyotaro Horiguchi</td></tr><tr><td>Lars Kanis</td></tr><tr><td>Lauren Fliksteen</td></tr><tr><td>Laurent Hasson</td></tr><tr><td>Laurenz Albe</td></tr><tr><td>Leslie Lemaire</td></tr><tr><td>Liam Bowen</td></tr><tr><td>Lingjie Qiang</td></tr><tr><td>Liu Huailing</td></tr><tr><td>Louis Jachiet</td></tr><tr><td>Lukas Fittl</td></tr><tr><td>Ma Liangzhu</td></tr><tr><td>Maciek Sakrejda</td></tr><tr><td>Magnus Hagander</td></tr><tr><td>Mahendra Singh Thalor</td></tr><tr><td>Maksim Milyutin</td></tr><tr><td>Marc Bachmann</td></tr><tr><td>Marcin Krupowicz</td></tr><tr><td>Marcus Gartner</td></tr><tr><td>Marek Szuba</td></tr><tr><td>Marina Polyakova</td></tr><tr><td>Mario Emmenlauer</td></tr><tr><td>Mark Dilger</td></tr><tr><td>Mark Murawski</td></tr><tr><td>Mark Wong</td></tr><tr><td>Markus Wanner</td></tr><tr><td>Markus Winand</td></tr><tr><td>Martijn van Oosterhout</td></tr><tr><td>Martin Jurca</td></tr><tr><td>Martin Kalcher</td></tr><tr><td>Martín Marqués</td></tr><tr><td>Masahiko Sawada</td></tr><tr><td>Masahiro Ikeda</td></tr><tr><td>Masao Fujii</td></tr><tr><td>Masaya Kawamoto</td></tr><tr><td>Masayuki Hirose</td></tr><tr><td>Matthias van de Meent</td></tr><tr><td>Matthijs van der Vleuten</td></tr><tr><td>Maxim Orlov</td></tr><tr><td>Maxim Yablokov</td></tr><tr><td>Melanie Plageman</td></tr><tr><td>Michael Banck</td></tr><tr><td>Michael Harris</td></tr><tr><td>Michael J. Sullivan</td></tr><tr><td>Michael Meskes</td></tr><tr><td>Michael Mühlbeyer</td></tr><tr><td>Michael Paquier</td></tr><tr><td>Michael Powers</td></tr><tr><td>Mike Fiedler</td></tr><tr><td>Mike Oh</td></tr><tr><td>Mikhail Kulagin</td></tr><tr><td>Miles Delahunty</td></tr><tr><td>Naoki Okano</td></tr><tr><td>Nathan Bossart</td></tr><tr><td>Nathan Long</td></tr><tr><td>Nazir Bilal Yavuz</td></tr><tr><td>Neha Sharma</td></tr><tr><td>Neil Chen</td></tr><tr><td>Nicola Contu</td></tr><tr><td>Nicolas Lutic</td></tr><tr><td>Nikhil Benesch</td></tr><tr><td>Nikhil Shetty</td></tr><tr><td>Nikhil Sontakke</td></tr><tr><td>Nikita Glukhov</td></tr><tr><td>Nikolai Berkoff</td></tr><tr><td>Nikolay Samokhvalov</td></tr><tr><td>Nikolay Shaplov</td></tr><tr><td>Nitin Jadhav</td></tr><tr><td>Noah Misch</td></tr><tr><td>Noboru Saito</td></tr><tr><td>Noriyoshi Shinoda</td></tr><tr><td>Olaf Bohlen</td></tr><tr><td>Olly Betts</td></tr><tr><td>Onder Kalaci</td></tr><tr><td>Oskar Stenberg</td></tr><tr><td>Otto Kekalainen</td></tr><tr><td>Paul Guo</td></tr><tr><td>Paul Jungwirth</td></tr><tr><td>Paul Martinez</td></tr><tr><td>Pavan Deolasee</td></tr><tr><td>Pavel Borisov</td></tr><tr><td>Pavel Luzanov</td></tr><tr><td>Pavel Stehule</td></tr><tr><td>Peter Eisentraut</td></tr><tr><td>Peter Geoghegan</td></tr><tr><td>Peter Slavov</td></tr><tr><td>Peter Smith</td></tr><tr><td>Petr Jelínek</td></tr><tr><td>Phil Florent</td></tr><tr><td>Phil Krylov</td></tr><tr><td>Pierre-Aurélien Georges</td></tr><tr><td>Prabhat Sahu</td></tr><tr><td>Quan Zongliang</td></tr><tr><td>Rachel Heaton</td></tr><tr><td>Rahila Syed</td></tr><tr><td>Rajakavitha Kodhandapani</td></tr><tr><td>Rajkumar Raghuwanshi</td></tr><tr><td>Ranier Vilela</td></tr><tr><td>Rei Kamigishi</td></tr><tr><td>Reid Thompson</td></tr><tr><td>Rémi Lapeyre</td></tr><tr><td>Renan Soares Lopes</td></tr><tr><td>Richard Guo</td></tr><tr><td>Richard Wesley</td></tr><tr><td>RKN Sai Krishna</td></tr><tr><td>Robert Haas</td></tr><tr><td>Robert Treat</td></tr><tr><td>Roberto Mello</td></tr><tr><td>Robins Tharakan</td></tr><tr><td>Roger Mason</td></tr><tr><td>Roman Zharkov</td></tr><tr><td>Ronan Dunklau</td></tr><tr><td>Rui Zhao</td></tr><tr><td>Ryan Kelly</td></tr><tr><td>Ryo Matsumura</td></tr><tr><td>Ryohei Takahashi</td></tr><tr><td>Sadhuprasad Patro</td></tr><tr><td>Sait Talha Nisanci</td></tr><tr><td>Sami Imseih</td></tr><tr><td>Sandeep Thakkar</td></tr><tr><td>Sebastian Kemper</td></tr><tr><td>Sehrope Sarkuni</td></tr><tr><td>Sergei Kornilov</td></tr><tr><td>Sergei Shoulbakov</td></tr><tr><td>Sergey Shinderuk</td></tr><tr><td>Shay Rojansky</td></tr><tr><td>Shenhao Wang</td></tr><tr><td>Shi Yu</td></tr><tr><td>Shinya Kato</td></tr><tr><td>Shruthi Gowda</td></tr><tr><td>Simon Perepelitsa</td></tr><tr><td>Simon Riggs</td></tr><tr><td>Sirisha Chamarthi</td></tr><tr><td>Soumyadeep Chakraborty</td></tr><tr><td>Stan Hu</td></tr><tr><td>Stas Kelvich</td></tr><tr><td>Stefen Hillman</td></tr><tr><td>Stephen Frost</td></tr><tr><td>Steve Chavez</td></tr><tr><td>Sumanta Mukherjee</td></tr><tr><td>Suraj Khamkar</td></tr><tr><td>Suraj Kharage</td></tr><tr><td>Sven Klemm</td></tr><tr><td>Takamichi Osumi</td></tr><tr><td>Takayuki Tsunakawa</td></tr><tr><td>Takeshi Ideriha</td></tr><tr><td>Tatsuhiro Nakamori</td></tr><tr><td>Tatsuhito Kasahara</td></tr><tr><td>Tatsuo Ishii</td></tr><tr><td>Tatsuro Yamada</td></tr><tr><td>Teja Mupparti</td></tr><tr><td>Teodor Sigaev</td></tr><tr><td>Thibaud Walkowiak</td></tr><tr><td>Thom Brown</td></tr><tr><td>Thomas McKay</td></tr><tr><td>Thomas Munro</td></tr><tr><td>Tim McNamara</td></tr><tr><td>Timo Stolz</td></tr><tr><td>Timur Khanjanov</td></tr><tr><td>Tom Lane</td></tr><tr><td>Tomas Barton</td></tr><tr><td>Tomas Vondra</td></tr><tr><td>Tony Reix</td></tr><tr><td>Troy Frericks</td></tr><tr><td>Tushar Ahuja</td></tr><tr><td>Victor Wagner</td></tr><tr><td>Victor Yegorov</td></tr><tr><td>Vignesh C</td></tr><tr><td>Vik Fearing</td></tr><tr><td>Vincas Dargis</td></tr><tr><td>Vitaly Burovoy</td></tr><tr><td>Vitaly Voronov</td></tr><tr><td>Vladimir Sitnikov</td></tr><tr><td>Wang Ke</td></tr><tr><td>Wei Sun</td></tr><tr><td>Wei Wang</td></tr><tr><td>Whale Song</td></tr><tr><td>Will Mortensen</td></tr><tr><td>Wolfgang Walther</td></tr><tr><td>Yanliang Lei</td></tr><tr><td>Yaoguang Chen</td></tr><tr><td>Yogendra Suralkar</td></tr><tr><td>YoungHwan Joo</td></tr><tr><td>Yugo Nagata</td></tr><tr><td>Yukun Wang</td></tr><tr><td>Yura Sokolov</td></tr><tr><td>Yusuke Egashira</td></tr><tr><td>Yuzuko Hosoya</td></tr><tr><td>Zhang Mingli</td></tr><tr><td>Zhang Wenjie</td></tr><tr><td>Zhihong Yu</td></tr><tr><td>Zhiyong Wu</td></tr></table></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release-15-1.html" title="E.4. Release 15.1">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release-prior.html" title="E.6. Prior Releases">Next</a></td></tr><tr><td width="40%" align="left" valign="top">E.4. Release 15.1 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> E.6. Prior Releases</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release-prior.html b/doc/src/sgml/html/release-prior.html
new file mode 100644
index 0000000..5638e69
--- /dev/null
+++ b/doc/src/sgml/html/release-prior.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>E.6. Prior Releases</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="release-15.html" title="E.5. Release 15" /><link rel="next" href="contrib.html" title="Appendix F. Additional Supplied Modules" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">E.6. Prior Releases</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="release-15.html" title="E.5. Release 15">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><th width="60%" align="center">Appendix E. Release Notes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib.html" title="Appendix F. Additional Supplied Modules">Next</a></td></tr></table><hr /></div><div class="sect1" id="RELEASE-PRIOR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">E.6. Prior Releases</h2></div></div></div><p>
+ Release notes for prior release branches can be found at
+ <a class="ulink" href="https://www.postgresql.org/docs/release/" target="_top"><code class="literal">https://www.postgresql.org/docs/release/</code></a>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="release-15.html" title="E.5. Release 15">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="release.html" title="Appendix E. Release Notes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib.html" title="Appendix F. Additional Supplied Modules">Next</a></td></tr><tr><td width="40%" align="left" valign="top">E.5. Release 15 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix F. Additional Supplied Modules</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/release.html b/doc/src/sgml/html/release.html
new file mode 100644
index 0000000..8879983
--- /dev/null
+++ b/doc/src/sgml/html/release.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix E. Release Notes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML" /><link rel="next" href="release-15-4.html" title="E.1. Release 15.4" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix E. Release Notes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release-15-4.html" title="E.1. Release 15.4">Next</a></td></tr></table><hr /></div><div class="appendix" id="RELEASE"><div class="titlepage"><div><div><h2 class="title">Appendix E. Release Notes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="release-15-4.html">E.1. Release 15.4</a></span></dt><dd><dl><dt><span class="sect2"><a href="release-15-4.html#id-1.11.6.5.4">E.1.1. Migration to Version 15.4</a></span></dt><dt><span class="sect2"><a href="release-15-4.html#id-1.11.6.5.5">E.1.2. Changes</a></span></dt></dl></dd><dt><span class="sect1"><a href="release-15-3.html">E.2. Release 15.3</a></span></dt><dd><dl><dt><span class="sect2"><a href="release-15-3.html#id-1.11.6.6.4">E.2.1. Migration to Version 15.3</a></span></dt><dt><span class="sect2"><a href="release-15-3.html#id-1.11.6.6.5">E.2.2. Changes</a></span></dt></dl></dd><dt><span class="sect1"><a href="release-15-2.html">E.3. Release 15.2</a></span></dt><dd><dl><dt><span class="sect2"><a href="release-15-2.html#id-1.11.6.7.4">E.3.1. Migration to Version 15.2</a></span></dt><dt><span class="sect2"><a href="release-15-2.html#id-1.11.6.7.5">E.3.2. Changes</a></span></dt></dl></dd><dt><span class="sect1"><a href="release-15-1.html">E.4. Release 15.1</a></span></dt><dd><dl><dt><span class="sect2"><a href="release-15-1.html#id-1.11.6.8.4">E.4.1. Migration to Version 15.1</a></span></dt><dt><span class="sect2"><a href="release-15-1.html#id-1.11.6.8.5">E.4.2. Changes</a></span></dt></dl></dd><dt><span class="sect1"><a href="release-15.html">E.5. Release 15</a></span></dt><dd><dl><dt><span class="sect2"><a href="release-15.html#id-1.11.6.9.3">E.5.1. Overview</a></span></dt><dt><span class="sect2"><a href="release-15.html#id-1.11.6.9.4">E.5.2. Migration to Version 15</a></span></dt><dt><span class="sect2"><a href="release-15.html#id-1.11.6.9.5">E.5.3. Changes</a></span></dt><dt><span class="sect2"><a href="release-15.html#RELEASE-15-ACKNOWLEDGEMENTS">E.5.4. Acknowledgments</a></span></dt></dl></dd><dt><span class="sect1"><a href="release-prior.html">E.6. Prior Releases</a></span></dt></dl></div><p>
+ The release notes contain the significant changes in each
+ <span class="productname">PostgreSQL</span> release, with major features and migration
+ issues listed at the top. The release notes do not contain changes
+ that affect only a few users or changes that are internal and therefore not
+ user-visible. For example, the optimizer is improved in almost every
+ release, but the improvements are usually observed by users as simply
+ faster queries.
+ </p><p>
+ A complete list of changes for each release can be obtained by
+ viewing the <a class="link" href="git.html" title="I.1. Getting the Source via Git">Git</a> logs for each release.
+ The <a class="ulink" href="https://www.postgresql.org/list/pgsql-committers/" target="_top"><code class="literal">pgsql-committers</code>
+ email list</a> records all source code changes as well. There is also
+ a <a class="ulink" href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=summary" target="_top">web
+ interface</a> that shows changes to specific files.
+ </p><p>
+ The name appearing next to each item represents the major developer for
+ that item. Of course all changes involve community discussion and patch
+ review, so each item is truly a community effort.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release-15-4.html" title="E.1. Release 15.4">Next</a></td></tr><tr><td width="40%" align="left" valign="top">D.3. XML Limits and Conformance to SQL/XML </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> E.1. Release 15.4</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/replication-origins.html b/doc/src/sgml/html/replication-origins.html
new file mode 100644
index 0000000..209efb6
--- /dev/null
+++ b/doc/src/sgml/html/replication-origins.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 50. Replication Progress Tracking</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding" /><link rel="next" href="archive-modules.html" title="Chapter 51. Archive Modules" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 50. Replication Progress Tracking</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="archive-modules.html" title="Chapter 51. Archive Modules">Next</a></td></tr></table><hr /></div><div class="chapter" id="REPLICATION-ORIGINS"><div class="titlepage"><div><div><h2 class="title">Chapter 50. Replication Progress Tracking</h2></div></div></div><a id="id-1.8.15.2" class="indexterm"></a><a id="id-1.8.15.3" class="indexterm"></a><p>
+ Replication origins are intended to make it easier to implement
+ logical replication solutions on top
+ of <a class="link" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">logical decoding</a>.
+ They provide a solution to two common problems:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>How to safely keep track of replication progress</p></li><li class="listitem"><p>How to change replication behavior based on the
+ origin of a row; for example, to prevent loops in bi-directional
+ replication setups</p></li></ul></div><p>
+ </p><p>
+ Replication origins have just two properties, a name and an ID. The name,
+ which is what should be used to refer to the origin across systems, is
+ free-form <code class="type">text</code>. It should be used in a way that makes conflicts
+ between replication origins created by different replication solutions
+ unlikely; e.g., by prefixing the replication solution's name to it.
+ The ID is used only to avoid having to store the long version
+ in situations where space efficiency is important. It should never be shared
+ across systems.
+ </p><p>
+ Replication origins can be created using the function
+ <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-CREATE"><code class="function">pg_replication_origin_create()</code></a>;
+ dropped using
+ <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-DROP"><code class="function">pg_replication_origin_drop()</code></a>;
+ and seen in the
+ <a class="link" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin"><code class="structname">pg_replication_origin</code></a>
+ system catalog.
+ </p><p>
+ One nontrivial part of building a replication solution is to keep track of
+ replay progress in a safe manner. When the applying process, or the whole
+ cluster, dies, it needs to be possible to find out up to where data has
+ successfully been replicated. Naive solutions to this, such as updating a
+ row in a table for every replayed transaction, have problems like run-time
+ overhead and database bloat.
+ </p><p>
+ Using the replication origin infrastructure a session can be
+ marked as replaying from a remote node (using the
+ <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-SESSION-SETUP"><code class="function">pg_replication_origin_session_setup()</code></a>
+ function). Additionally the <acronym class="acronym">LSN</acronym> and commit
+ time stamp of every source transaction can be configured on a per
+ transaction basis using
+ <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-XACT-SETUP"><code class="function">pg_replication_origin_xact_setup()</code></a>.
+ If that's done replication progress will persist in a crash safe
+ manner. Replay progress for all replication origins can be seen in the
+ <a class="link" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">
+ <code class="structname">pg_replication_origin_status</code>
+ </a> view. An individual origin's progress, e.g., when resuming
+ replication, can be acquired using
+ <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-PROGRESS"><code class="function">pg_replication_origin_progress()</code></a>
+ for any origin or
+ <a class="link" href="functions-admin.html#PG-REPLICATION-ORIGIN-SESSION-PROGRESS"><code class="function">pg_replication_origin_session_progress()</code></a>
+ for the origin configured in the current session.
+ </p><p>
+ In replication topologies more complex than replication from exactly one
+ system to one other system, another problem can be that it is hard to avoid
+ replicating replayed rows again. That can lead both to cycles in the
+ replication and inefficiencies. Replication origins provide an optional
+ mechanism to recognize and prevent that. When configured using the functions
+ referenced in the previous paragraph, every change and transaction passed to
+ output plugin callbacks (see <a class="xref" href="logicaldecoding-output-plugin.html" title="49.6. Logical Decoding Output Plugins">Section 49.6</a>)
+ generated by the session is tagged with the replication origin of the
+ generating session. This allows treating them differently in the output
+ plugin, e.g., ignoring all but locally-originating rows. Additionally
+ the <a class="link" href="logicaldecoding-output-plugin.html#LOGICALDECODING-OUTPUT-PLUGIN-FILTER-ORIGIN" title="49.6.4.7. Origin Filter Callback">
+ <code class="function">filter_by_origin_cb</code></a> callback can be used
+ to filter the logical decoding change stream based on the
+ source. While less flexible, filtering via that callback is
+ considerably more efficient than doing it in the output plugin.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="logicaldecoding-two-phase-commits.html" title="49.10. Two-phase Commit Support for Logical Decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="archive-modules.html" title="Chapter 51. Archive Modules">Next</a></td></tr><tr><td width="40%" align="left" valign="top">49.10. Two-phase Commit Support for Logical Decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 51. Archive Modules</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/resources.html b/doc/src/sgml/html/resources.html
new file mode 100644
index 0000000..6f810d4
--- /dev/null
+++ b/doc/src/sgml/html/resources.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>4. Further Information</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="notation.html" title="3. Conventions" /><link rel="next" href="bug-reporting.html" title="5. Bug Reporting Guidelines" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">4. Further Information</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="notation.html" title="3. Conventions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><th width="60%" align="center">Preface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bug-reporting.html" title="5. Bug Reporting Guidelines">Next</a></td></tr></table><hr /></div><div class="sect1" id="RESOURCES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">4. Further Information</h2></div></div></div><p>
+ Besides the documentation, that is, this book, there are other
+ resources about <span class="productname">PostgreSQL</span>:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Wiki</span></dt><dd><p>
+ The <span class="productname">PostgreSQL</span> <a class="ulink" href="https://wiki.postgresql.org" target="_top">wiki</a> contains the project's <a class="ulink" href="https://wiki.postgresql.org/wiki/Frequently_Asked_Questions" target="_top">FAQ</a>
+ (Frequently Asked Questions) list, <a class="ulink" href="https://wiki.postgresql.org/wiki/Todo" target="_top">TODO</a> list, and
+ detailed information about many more topics.
+ </p></dd><dt><span class="term">Web Site</span></dt><dd><p>
+ The <span class="productname">PostgreSQL</span>
+ <a class="ulink" href="https://www.postgresql.org" target="_top">web site</a>
+ carries details on the latest release and other
+ information to make your work or play with
+ <span class="productname">PostgreSQL</span> more productive.
+ </p></dd><dt><span class="term">Mailing Lists</span></dt><dd><p>
+ The mailing lists are a good place to have your questions
+ answered, to share experiences with other users, and to contact
+ the developers. Consult the <span class="productname">PostgreSQL</span> web site
+ for details.
+ </p></dd><dt><span class="term">Yourself!</span></dt><dd><p>
+ <span class="productname">PostgreSQL</span> is an open-source project.
+ As such, it depends on the user community for ongoing support.
+ As you begin to use <span class="productname">PostgreSQL</span>, you
+ will rely on others for help, either through the documentation
+ or through the mailing lists. Consider contributing your
+ knowledge back. Read the mailing lists and answer questions. If
+ you learn something which is not in the documentation, write it
+ up and contribute it. If you add features to the code,
+ contribute them.
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="notation.html" title="3. Conventions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="preface.html" title="Preface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bug-reporting.html" title="5. Bug Reporting Guidelines">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3. Conventions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 5. Bug Reporting Guidelines</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/role-attributes.html b/doc/src/sgml/html/role-attributes.html
new file mode 100644
index 0000000..3c48608
--- /dev/null
+++ b/doc/src/sgml/html/role-attributes.html
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>22.2. Role Attributes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="database-roles.html" title="22.1. Database Roles" /><link rel="next" href="role-membership.html" title="22.3. Role Membership" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">22.2. Role Attributes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="database-roles.html" title="22.1. Database Roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><th width="60%" align="center">Chapter 22. Database Roles</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="role-membership.html" title="22.3. Role Membership">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROLE-ATTRIBUTES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">22.2. Role Attributes</h2></div></div></div><p>
+ A database role can have a number of attributes that define its
+ privileges and interact with the client authentication system.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">login privilege<a id="id-1.6.9.6.2.1.1.1.1" class="indexterm"></a></span></dt><dd><p>
+ Only roles that have the <code class="literal">LOGIN</code> attribute can be used
+ as the initial role name for a database connection. A role with
+ the <code class="literal">LOGIN</code> attribute can be considered the same
+ as a <span class="quote">“<span class="quote">database user</span>”</span>. To create a role with login privilege,
+ use either:
+</p><pre class="programlisting">
+CREATE ROLE <em class="replaceable"><code>name</code></em> LOGIN;
+CREATE USER <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ (<code class="command">CREATE USER</code> is equivalent to <code class="command">CREATE ROLE</code>
+ except that <code class="command">CREATE USER</code> includes <code class="literal">LOGIN</code> by
+ default, while <code class="command">CREATE ROLE</code> does not.)
+ </p></dd><dt><span class="term">superuser status<a id="id-1.6.9.6.2.1.2.1.1" class="indexterm"></a></span></dt><dd><p>
+ A database superuser bypasses all permission checks, except the right
+ to log in. This is a dangerous privilege and should not be used
+ carelessly; it is best to do most of your work as a role that is not a
+ superuser. To create a new database superuser, use <code class="literal">CREATE
+ ROLE <em class="replaceable"><code>name</code></em> SUPERUSER</code>. You must do
+ this as a role that is already a superuser.
+ </p></dd><dt><span class="term">database creation<a id="id-1.6.9.6.2.1.3.1.1" class="indexterm"></a></span></dt><dd><p>
+ A role must be explicitly given permission to create databases
+ (except for superusers, since those bypass all permission
+ checks). To create such a role, use <code class="literal">CREATE ROLE
+ <em class="replaceable"><code>name</code></em> CREATEDB</code>.
+ </p></dd><dt><span class="term" id="ROLE-CREATION">role creation<a id="id-1.6.9.6.2.1.4.1.1" class="indexterm"></a></span></dt><dd><p>
+ A role must be explicitly given permission to create more roles
+ (except for superusers, since those bypass all permission
+ checks). To create such a role, use <code class="literal">CREATE ROLE
+ <em class="replaceable"><code>name</code></em> CREATEROLE</code>.
+ A role with <code class="literal">CREATEROLE</code> privilege can alter and drop
+ other roles, too, as well as grant or revoke membership in them.
+ Altering a role includes most changes that can be made using
+ <code class="literal">ALTER ROLE</code>, including, for example, changing
+ passwords. It also includes modifications to a role that can
+ be made using the <code class="literal">COMMENT</code> and
+ <code class="literal">SECURITY LABEL</code> commands.
+ </p><p>
+ However, <code class="literal">CREATEROLE</code> does not convey the ability to
+ create <code class="literal">SUPERUSER</code> roles, nor does it convey any
+ power over <code class="literal">SUPERUSER</code> roles that already exist.
+ Furthermore, <code class="literal">CREATEROLE</code> does not convey the power
+ to create <code class="literal">REPLICATION</code> users, nor the ability to
+ grant or revoke the <code class="literal">REPLICATION</code> privilege, nor the
+ ability to modify the role properties of such users. However, it does
+ allow <code class="literal">ALTER ROLE ... SET</code> and
+ <code class="literal">ALTER ROLE ... RENAME</code> to be used on
+ <code class="literal">REPLICATION</code> roles, as well as the use of
+ <code class="literal">COMMENT ON ROLE</code>,
+ <code class="literal">SECURITY LABEL ON ROLE</code>,
+ and <code class="literal">DROP ROLE</code>.
+ Finally, <code class="literal">CREATEROLE</code> does not
+ confer the ability to grant or revoke the <code class="literal">BYPASSRLS</code>
+ privilege.
+ </p><p>
+ Because the <code class="literal">CREATEROLE</code> privilege allows a user
+ to grant or revoke membership even in roles to which it does not (yet)
+ have any access, a <code class="literal">CREATEROLE</code> user can obtain access
+ to the capabilities of every predefined role in the system, including
+ highly privileged roles such as
+ <code class="literal">pg_execute_server_program</code> and
+ <code class="literal">pg_write_server_files</code>.
+ </p></dd><dt><span class="term">initiating replication<a id="id-1.6.9.6.2.1.5.1.1" class="indexterm"></a></span></dt><dd><p>
+ A role must explicitly be given permission to initiate streaming
+ replication (except for superusers, since those bypass all permission
+ checks). A role used for streaming replication must
+ have <code class="literal">LOGIN</code> permission as well. To create such a role, use
+ <code class="literal">CREATE ROLE <em class="replaceable"><code>name</code></em> REPLICATION
+ LOGIN</code>.
+ </p></dd><dt><span class="term">password<a id="id-1.6.9.6.2.1.6.1.1" class="indexterm"></a></span></dt><dd><p>
+ A password is only significant if the client authentication
+ method requires the user to supply a password when connecting
+ to the database. The <code class="option">password</code> and
+ <code class="option">md5</code> authentication methods
+ make use of passwords. Database passwords are separate from
+ operating system passwords. Specify a password upon role
+ creation with <code class="literal">CREATE ROLE
+ <em class="replaceable"><code>name</code></em> PASSWORD '<em class="replaceable"><code>string</code></em>'</code>.
+ </p></dd><dt><span class="term">inheritance of privileges<a id="id-1.6.9.6.2.1.7.1.1" class="indexterm"></a></span></dt><dd><p>
+ A role is given permission to inherit the privileges of roles it is a
+ member of, by default. However, to create a role without the permission,
+ use <code class="literal">CREATE ROLE <em class="replaceable"><code>name</code></em> NOINHERIT</code>.
+ </p></dd><dt><span class="term">bypassing row-level security<a id="id-1.6.9.6.2.1.8.1.1" class="indexterm"></a></span></dt><dd><p>
+ A role must be explicitly given permission to bypass every row-level security (RLS) policy
+ (except for superusers, since those bypass all permission checks).
+ To create such a role, use <code class="literal">CREATE ROLE <em class="replaceable"><code>name</code></em> BYPASSRLS</code> as a superuser.
+ </p></dd><dt><span class="term">connection limit<a id="id-1.6.9.6.2.1.9.1.1" class="indexterm"></a></span></dt><dd><p>
+ Connection limit can specify how many concurrent connections a role can make.
+ -1 (the default) means no limit. Specify connection limit upon role creation with
+ <code class="literal">CREATE ROLE <em class="replaceable"><code>name</code></em> CONNECTION LIMIT '<em class="replaceable"><code>integer</code></em>'</code>.
+ </p></dd></dl></div><p>
+
+ A role's attributes can be modified after creation with
+ <code class="command">ALTER ROLE</code>.<a id="id-1.6.9.6.2.3" class="indexterm"></a>
+ See the reference pages for the <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>
+ and <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a> commands for details.
+ </p><p>
+ A role can also have role-specific defaults for many of the run-time
+ configuration settings described in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>. For example, if for some reason you
+ want to disable index scans (hint: not a good idea) anytime you
+ connect, you can use:
+</p><pre class="programlisting">
+ALTER ROLE myname SET enable_indexscan TO off;
+</pre><p>
+ This will save the setting (but not set it immediately). In
+ subsequent connections by this role it will appear as though
+ <code class="literal">SET enable_indexscan TO off</code> had been executed
+ just before the session started.
+ You can still alter this setting during the session; it will only
+ be the default. To remove a role-specific default setting, use
+ <code class="literal">ALTER ROLE <em class="replaceable"><code>rolename</code></em> RESET <em class="replaceable"><code>varname</code></em></code>.
+ Note that role-specific defaults attached to roles without
+ <code class="literal">LOGIN</code> privilege are fairly useless, since they will never
+ be invoked.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="database-roles.html" title="22.1. Database Roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="role-membership.html" title="22.3. Role Membership">Next</a></td></tr><tr><td width="40%" align="left" valign="top">22.1. Database Roles </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 22.3. Role Membership</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/role-membership.html b/doc/src/sgml/html/role-membership.html
new file mode 100644
index 0000000..a16bab5
--- /dev/null
+++ b/doc/src/sgml/html/role-membership.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>22.3. Role Membership</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="role-attributes.html" title="22.2. Role Attributes" /><link rel="next" href="role-removal.html" title="22.4. Dropping Roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">22.3. Role Membership</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="role-attributes.html" title="22.2. Role Attributes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><th width="60%" align="center">Chapter 22. Database Roles</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="role-removal.html" title="22.4. Dropping Roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROLE-MEMBERSHIP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">22.3. Role Membership</h2></div></div></div><a id="id-1.6.9.7.2" class="indexterm"></a><p>
+ It is frequently convenient to group users together to ease
+ management of privileges: that way, privileges can be granted to, or
+ revoked from, a group as a whole. In <span class="productname">PostgreSQL</span>
+ this is done by creating a role that represents the group, and then
+ granting <em class="firstterm">membership</em> in the group role to individual user
+ roles.
+ </p><p>
+ To set up a group role, first create the role:
+</p><pre class="synopsis">
+CREATE ROLE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ Typically a role being used as a group would not have the <code class="literal">LOGIN</code>
+ attribute, though you can set it if you wish.
+ </p><p>
+ Once the group role exists, you can add and remove members using the
+ <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> and
+ <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a> commands:
+</p><pre class="synopsis">
+GRANT <em class="replaceable"><code>group_role</code></em> TO <em class="replaceable"><code>role1</code></em>, ... ;
+REVOKE <em class="replaceable"><code>group_role</code></em> FROM <em class="replaceable"><code>role1</code></em>, ... ;
+</pre><p>
+ You can grant membership to other group roles, too (since there isn't
+ really any distinction between group roles and non-group roles). The
+ database will not let you set up circular membership loops. Also,
+ it is not permitted to grant membership in a role to
+ <code class="literal">PUBLIC</code>.
+ </p><p>
+ The members of a group role can use the privileges of the role in two
+ ways. First, every member of a group can explicitly do
+ <a class="link" href="sql-set-role.html" title="SET ROLE"><code class="command">SET ROLE</code></a> to
+ temporarily <span class="quote">“<span class="quote">become</span>”</span> the group role. In this state, the
+ database session has access to the privileges of the group role rather
+ than the original login role, and any database objects created are
+ considered owned by the group role not the login role. Second, member
+ roles that have the <code class="literal">INHERIT</code> attribute automatically have use
+ of the privileges of roles of which they are members, including any
+ privileges inherited by those roles.
+ As an example, suppose we have done:
+</p><pre class="programlisting">
+CREATE ROLE joe LOGIN INHERIT;
+CREATE ROLE admin NOINHERIT;
+CREATE ROLE wheel NOINHERIT;
+GRANT admin TO joe;
+GRANT wheel TO admin;
+</pre><p>
+ Immediately after connecting as role <code class="literal">joe</code>, a database
+ session will have use of privileges granted directly to <code class="literal">joe</code>
+ plus any privileges granted to <code class="literal">admin</code>, because <code class="literal">joe</code>
+ <span class="quote">“<span class="quote">inherits</span>”</span> <code class="literal">admin</code>'s privileges. However, privileges
+ granted to <code class="literal">wheel</code> are not available, because even though
+ <code class="literal">joe</code> is indirectly a member of <code class="literal">wheel</code>, the
+ membership is via <code class="literal">admin</code> which has the <code class="literal">NOINHERIT</code>
+ attribute. After:
+</p><pre class="programlisting">
+SET ROLE admin;
+</pre><p>
+ the session would have use of only those privileges granted to
+ <code class="literal">admin</code>, and not those granted to <code class="literal">joe</code>. After:
+</p><pre class="programlisting">
+SET ROLE wheel;
+</pre><p>
+ the session would have use of only those privileges granted to
+ <code class="literal">wheel</code>, and not those granted to either <code class="literal">joe</code>
+ or <code class="literal">admin</code>. The original privilege state can be restored
+ with any of:
+</p><pre class="programlisting">
+SET ROLE joe;
+SET ROLE NONE;
+RESET ROLE;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="command">SET ROLE</code> command always allows selecting any role
+ that the original login role is directly or indirectly a member of.
+ Thus, in the above example, it is not necessary to become
+ <code class="literal">admin</code> before becoming <code class="literal">wheel</code>.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ In the SQL standard, there is a clear distinction between users and roles,
+ and users do not automatically inherit privileges while roles do. This
+ behavior can be obtained in <span class="productname">PostgreSQL</span> by giving
+ roles being used as SQL roles the <code class="literal">INHERIT</code> attribute, while
+ giving roles being used as SQL users the <code class="literal">NOINHERIT</code> attribute.
+ However, <span class="productname">PostgreSQL</span> defaults to giving all roles
+ the <code class="literal">INHERIT</code> attribute, for backward compatibility with pre-8.1
+ releases in which users always had use of permissions granted to groups
+ they were members of.
+ </p></div><p>
+ The role attributes <code class="literal">LOGIN</code>, <code class="literal">SUPERUSER</code>,
+ <code class="literal">CREATEDB</code>, and <code class="literal">CREATEROLE</code> can be thought of as
+ special privileges, but they are never inherited as ordinary privileges
+ on database objects are. You must actually <code class="command">SET ROLE</code> to a
+ specific role having one of these attributes in order to make use of
+ the attribute. Continuing the above example, we might choose to
+ grant <code class="literal">CREATEDB</code> and <code class="literal">CREATEROLE</code> to the
+ <code class="literal">admin</code> role. Then a session connecting as role <code class="literal">joe</code>
+ would not have these privileges immediately, only after doing
+ <code class="command">SET ROLE admin</code>.
+ </p><p>
+ </p><p>
+ To destroy a group role, use <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a>:
+</p><pre class="synopsis">
+DROP ROLE <em class="replaceable"><code>name</code></em>;
+</pre><p>
+ Any memberships in the group role are automatically revoked (but the
+ member roles are not otherwise affected).
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="role-attributes.html" title="22.2. Role Attributes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="role-removal.html" title="22.4. Dropping Roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">22.2. Role Attributes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 22.4. Dropping Roles</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/role-removal.html b/doc/src/sgml/html/role-removal.html
new file mode 100644
index 0000000..223f7ec
--- /dev/null
+++ b/doc/src/sgml/html/role-removal.html
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>22.4. Dropping Roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="role-membership.html" title="22.3. Role Membership" /><link rel="next" href="predefined-roles.html" title="22.5. Predefined Roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">22.4. Dropping Roles</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="role-membership.html" title="22.3. Role Membership">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><th width="60%" align="center">Chapter 22. Database Roles</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="predefined-roles.html" title="22.5. Predefined Roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROLE-REMOVAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">22.4. Dropping Roles</h2></div></div></div><p>
+ Because roles can own database objects and can hold privileges
+ to access other objects, dropping a role is often not just a matter of a
+ quick <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a>. Any objects owned by the role must
+ first be dropped or reassigned to other owners; and any permissions
+ granted to the role must be revoked.
+ </p><p>
+ Ownership of objects can be transferred one at a time
+ using <code class="command">ALTER</code> commands, for example:
+</p><pre class="programlisting">
+ALTER TABLE bobs_table OWNER TO alice;
+</pre><p>
+ Alternatively, the <a class="link" href="sql-reassign-owned.html" title="REASSIGN OWNED"><code class="command">REASSIGN OWNED</code></a> command can be
+ used to reassign ownership of all objects owned by the role-to-be-dropped
+ to a single other role. Because <code class="command">REASSIGN OWNED</code> cannot access
+ objects in other databases, it is necessary to run it in each database
+ that contains objects owned by the role. (Note that the first
+ such <code class="command">REASSIGN OWNED</code> will change the ownership of any
+ shared-across-databases objects, that is databases or tablespaces, that
+ are owned by the role-to-be-dropped.)
+ </p><p>
+ Once any valuable objects have been transferred to new owners, any
+ remaining objects owned by the role-to-be-dropped can be dropped with
+ the <a class="link" href="sql-drop-owned.html" title="DROP OWNED"><code class="command">DROP OWNED</code></a> command. Again, this command cannot
+ access objects in other databases, so it is necessary to run it in each
+ database that contains objects owned by the role. Also, <code class="command">DROP
+ OWNED</code> will not drop entire databases or tablespaces, so it is
+ necessary to do that manually if the role owns any databases or
+ tablespaces that have not been transferred to new owners.
+ </p><p>
+ <code class="command">DROP OWNED</code> also takes care of removing any privileges granted
+ to the target role for objects that do not belong to it.
+ Because <code class="command">REASSIGN OWNED</code> does not touch such objects, it's
+ typically necessary to run both <code class="command">REASSIGN OWNED</code>
+ and <code class="command">DROP OWNED</code> (in that order!) to fully remove the
+ dependencies of a role to be dropped.
+ </p><p>
+ In short then, the most general recipe for removing a role that has been
+ used to own objects is:
+ </p><pre class="programlisting">
+REASSIGN OWNED BY doomed_role TO successor_role;
+DROP OWNED BY doomed_role;
+-- repeat the above commands in each database of the cluster
+DROP ROLE doomed_role;
+</pre><p>
+ When not all owned objects are to be transferred to the same successor
+ owner, it's best to handle the exceptions manually and then perform
+ the above steps to mop up.
+ </p><p>
+ If <code class="command">DROP ROLE</code> is attempted while dependent objects still
+ remain, it will issue messages identifying which objects need to be
+ reassigned or dropped.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="role-membership.html" title="22.3. Role Membership">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="user-manag.html" title="Chapter 22. Database Roles">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="predefined-roles.html" title="22.5. Predefined Roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">22.3. Role Membership </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 22.5. Predefined Roles</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/routine-reindex.html b/doc/src/sgml/html/routine-reindex.html
new file mode 100644
index 0000000..2c30755
--- /dev/null
+++ b/doc/src/sgml/html/routine-reindex.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>25.2. Routine Reindexing</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="routine-vacuuming.html" title="25.1. Routine Vacuuming" /><link rel="next" href="logfile-maintenance.html" title="25.3. Log File Maintenance" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">25.2. Routine Reindexing</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Up</a></td><th width="60%" align="center">Chapter 25. Routine Database Maintenance Tasks</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROUTINE-REINDEX"><div class="titlepage"><div><div><h2 class="title" style="clear: both">25.2. Routine Reindexing</h2></div></div></div><a id="id-1.6.12.11.2" class="indexterm"></a><p>
+ In some situations it is worthwhile to rebuild indexes periodically
+ with the <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a> command or a series of individual
+ rebuilding steps.
+
+ </p><p>
+ B-tree index pages that have become completely empty are reclaimed for
+ re-use. However, there is still a possibility
+ of inefficient use of space: if all but a few index keys on a page have
+ been deleted, the page remains allocated. Therefore, a usage
+ pattern in which most, but not all, keys in each range are eventually
+ deleted will see poor use of space. For such usage patterns,
+ periodic reindexing is recommended.
+ </p><p>
+ The potential for bloat in non-B-tree indexes has not been well
+ researched. It is a good idea to periodically monitor the index's physical
+ size when using any non-B-tree index type.
+ </p><p>
+ Also, for B-tree indexes, a freshly-constructed index is slightly faster to
+ access than one that has been updated many times because logically
+ adjacent pages are usually also physically adjacent in a newly built index.
+ (This consideration does not apply to non-B-tree indexes.) It
+ might be worthwhile to reindex periodically just to improve access speed.
+ </p><p>
+ <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a> can be used safely and easily in all cases.
+ This command requires an <code class="literal">ACCESS EXCLUSIVE</code> lock by
+ default, hence it is often preferable to execute it with its
+ <code class="literal">CONCURRENTLY</code> option, which requires only a
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Next</a></td></tr><tr><td width="40%" align="left" valign="top">25.1. Routine Vacuuming </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 25.3. Log File Maintenance</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/routine-vacuuming.html b/doc/src/sgml/html/routine-vacuuming.html
new file mode 100644
index 0000000..a0d38c8
--- /dev/null
+++ b/doc/src/sgml/html/routine-vacuuming.html
@@ -0,0 +1,643 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>25.1. Routine Vacuuming</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks" /><link rel="next" href="routine-reindex.html" title="25.2. Routine Reindexing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">25.1. Routine Vacuuming</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Up</a></td><th width="60%" align="center">Chapter 25. Routine Database Maintenance Tasks</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="routine-reindex.html" title="25.2. Routine Reindexing">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROUTINE-VACUUMING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">25.1. Routine Vacuuming</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-BASICS">25.1.1. Vacuuming Basics</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-SPACE-RECOVERY">25.1.2. Recovering Disk Space</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-STATISTICS">25.1.3. Updating Planner Statistics</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-VISIBILITY-MAP">25.1.4. Updating the Visibility Map</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND">25.1.5. Preventing Transaction ID Wraparound Failures</a></span></dt><dt><span class="sect2"><a href="routine-vacuuming.html#AUTOVACUUM">25.1.6. The Autovacuum Daemon</a></span></dt></dl></div><a id="id-1.6.12.10.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> databases require periodic
+ maintenance known as <em class="firstterm">vacuuming</em>. For many installations, it
+ is sufficient to let vacuuming be performed by the <em class="firstterm">autovacuum
+ daemon</em>, which is described in <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>. You might
+ need to adjust the autovacuuming parameters described there to obtain best
+ results for your situation. Some database administrators will want to
+ supplement or replace the daemon's activities with manually-managed
+ <code class="command">VACUUM</code> commands, which typically are executed according to a
+ schedule by <span class="application">cron</span> or <span class="application">Task
+ Scheduler</span> scripts. To set up manually-managed vacuuming properly,
+ it is essential to understand the issues discussed in the next few
+ subsections. Administrators who rely on autovacuuming may still wish
+ to skim this material to help them understand and adjust autovacuuming.
+ </p><div class="sect2" id="VACUUM-BASICS"><div class="titlepage"><div><div><h3 class="title">25.1.1. Vacuuming Basics</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span>'s
+ <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a> command has to
+ process each table on a regular basis for several reasons:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem">To recover or reuse disk space occupied by updated or deleted
+ rows.</li><li class="listitem">To update data statistics used by the
+ <span class="productname">PostgreSQL</span> query planner.</li><li class="listitem">To update the visibility map, which speeds
+ up <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">index-only
+ scans</a>.</li><li class="listitem">To protect against loss of very old data due to
+ <em class="firstterm">transaction ID wraparound</em> or
+ <em class="firstterm">multixact ID wraparound</em>.</li></ol></div><p>
+
+ Each of these reasons dictates performing <code class="command">VACUUM</code> operations
+ of varying frequency and scope, as explained in the following subsections.
+ </p><p>
+ There are two variants of <code class="command">VACUUM</code>: standard <code class="command">VACUUM</code>
+ and <code class="command">VACUUM FULL</code>. <code class="command">VACUUM FULL</code> can reclaim more
+ disk space but runs much more slowly. Also,
+ the standard form of <code class="command">VACUUM</code> can run in parallel with production
+ database operations. (Commands such as <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> will continue to function normally, though you
+ will not be able to modify the definition of a table with commands such as
+ <code class="command">ALTER TABLE</code> while it is being vacuumed.)
+ <code class="command">VACUUM FULL</code> requires an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the table it is
+ working on, and therefore cannot be done in parallel with other use
+ of the table. Generally, therefore,
+ administrators should strive to use standard <code class="command">VACUUM</code> and
+ avoid <code class="command">VACUUM FULL</code>.
+ </p><p>
+ <code class="command">VACUUM</code> creates a substantial amount of I/O
+ traffic, which can cause poor performance for other active sessions.
+ There are configuration parameters that can be adjusted to reduce the
+ performance impact of background vacuuming — see
+ <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST" title="20.4.4. Cost-based Vacuum Delay">Section 20.4.4</a>.
+ </p></div><div class="sect2" id="VACUUM-FOR-SPACE-RECOVERY"><div class="titlepage"><div><div><h3 class="title">25.1.2. Recovering Disk Space</h3></div></div></div><a id="id-1.6.12.10.5.2" class="indexterm"></a><p>
+ In <span class="productname">PostgreSQL</span>, an
+ <code class="command">UPDATE</code> or <code class="command">DELETE</code> of a row does not
+ immediately remove the old version of the row.
+ This approach is necessary to gain the benefits of multiversion
+ concurrency control (<acronym class="acronym">MVCC</acronym>, see <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>): the row version
+ must not be deleted while it is still potentially visible to other
+ transactions. But eventually, an outdated or deleted row version is no
+ longer of interest to any transaction. The space it occupies must then be
+ reclaimed for reuse by new rows, to avoid unbounded growth of disk
+ space requirements. This is done by running <code class="command">VACUUM</code>.
+ </p><p>
+ The standard form of <code class="command">VACUUM</code> removes dead row
+ versions in tables and indexes and marks the space available for
+ future reuse. However, it will not return the space to the operating
+ system, except in the special case where one or more pages at the
+ end of a table become entirely free and an exclusive table lock can be
+ easily obtained. In contrast, <code class="command">VACUUM FULL</code> actively compacts
+ tables by writing a complete new version of the table file with no dead
+ space. This minimizes the size of the table, but can take a long time.
+ It also requires extra disk space for the new copy of the table, until
+ the operation completes.
+ </p><p>
+ The usual goal of routine vacuuming is to do standard <code class="command">VACUUM</code>s
+ often enough to avoid needing <code class="command">VACUUM FULL</code>. The
+ autovacuum daemon attempts to work this way, and in fact will
+ never issue <code class="command">VACUUM FULL</code>. In this approach, the idea
+ is not to keep tables at their minimum size, but to maintain steady-state
+ usage of disk space: each table occupies space equivalent to its
+ minimum size plus however much space gets used up between vacuum runs.
+ Although <code class="command">VACUUM FULL</code> can be used to shrink a table back
+ to its minimum size and return the disk space to the operating system,
+ there is not much point in this if the table will just grow again in the
+ future. Thus, moderately-frequent standard <code class="command">VACUUM</code> runs are a
+ better approach than infrequent <code class="command">VACUUM FULL</code> runs for
+ maintaining heavily-updated tables.
+ </p><p>
+ Some administrators prefer to schedule vacuuming themselves, for example
+ doing all the work at night when load is low.
+ The difficulty with doing vacuuming according to a fixed schedule
+ is that if a table has an unexpected spike in update activity, it may
+ get bloated to the point that <code class="command">VACUUM FULL</code> is really necessary
+ to reclaim space. Using the autovacuum daemon alleviates this problem,
+ since the daemon schedules vacuuming dynamically in response to update
+ activity. It is unwise to disable the daemon completely unless you
+ have an extremely predictable workload. One possible compromise is
+ to set the daemon's parameters so that it will only react to unusually
+ heavy update activity, thus keeping things from getting out of hand,
+ while scheduled <code class="command">VACUUM</code>s are expected to do the bulk of the
+ work when the load is typical.
+ </p><p>
+ For those not using autovacuum, a typical approach is to schedule a
+ database-wide <code class="command">VACUUM</code> once a day during a low-usage period,
+ supplemented by more frequent vacuuming of heavily-updated tables as
+ necessary. (Some installations with extremely high update rates vacuum
+ their busiest tables as often as once every few minutes.) If you have
+ multiple databases in a cluster, don't forget to
+ <code class="command">VACUUM</code> each one; the program <a class="xref" href="app-vacuumdb.html" title="vacuumdb"><span class="refentrytitle"><span class="application">vacuumdb</span></span></a> might be helpful.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Plain <code class="command">VACUUM</code> may not be satisfactory when
+ a table contains large numbers of dead row versions as a result of
+ massive update or delete activity. If you have such a table and
+ you need to reclaim the excess disk space it occupies, you will need
+ to use <code class="command">VACUUM FULL</code>, or alternatively
+ <a class="link" href="sql-cluster.html" title="CLUSTER"><code class="command">CLUSTER</code></a>
+ or one of the table-rewriting variants of
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>.
+ These commands rewrite an entire new copy of the table and build
+ new indexes for it. All these options require an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock. Note that
+ they also temporarily use extra disk space approximately equal to the size
+ of the table, since the old copies of the table and indexes can't be
+ released until the new ones are complete.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ If you have a table whose entire contents are deleted on a periodic
+ basis, consider doing it with
+ <a class="link" href="sql-truncate.html" title="TRUNCATE"><code class="command">TRUNCATE</code></a> rather
+ than using <code class="command">DELETE</code> followed by
+ <code class="command">VACUUM</code>. <code class="command">TRUNCATE</code> removes the
+ entire content of the table immediately, without requiring a
+ subsequent <code class="command">VACUUM</code> or <code class="command">VACUUM
+ FULL</code> to reclaim the now-unused disk space.
+ The disadvantage is that strict MVCC semantics are violated.
+ </p></div></div><div class="sect2" id="VACUUM-FOR-STATISTICS"><div class="titlepage"><div><div><h3 class="title">25.1.3. Updating Planner Statistics</h3></div></div></div><a id="id-1.6.12.10.6.2" class="indexterm"></a><a id="id-1.6.12.10.6.3" class="indexterm"></a><p>
+ The <span class="productname">PostgreSQL</span> query planner relies on
+ statistical information about the contents of tables in order to
+ generate good plans for queries. These statistics are gathered by
+ the <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> command,
+ which can be invoked by itself or
+ as an optional step in <code class="command">VACUUM</code>. It is important to have
+ reasonably accurate statistics, otherwise poor choices of plans might
+ degrade database performance.
+ </p><p>
+ The autovacuum daemon, if enabled, will automatically issue
+ <code class="command">ANALYZE</code> commands whenever the content of a table has
+ changed sufficiently. However, administrators might prefer to rely
+ on manually-scheduled <code class="command">ANALYZE</code> operations, particularly
+ if it is known that update activity on a table will not affect the
+ statistics of <span class="quote">“<span class="quote">interesting</span>”</span> columns. The daemon schedules
+ <code class="command">ANALYZE</code> strictly as a function of the number of rows
+ inserted or updated; it has no knowledge of whether that will lead
+ to meaningful statistical changes.
+ </p><p>
+ Tuples changed in partitions and inheritance children do not trigger
+ analyze on the parent table. If the parent table is empty or rarely
+ changed, it may never be processed by autovacuum, and the statistics for
+ the inheritance tree as a whole won't be collected. It is necessary to
+ run <code class="command">ANALYZE</code> on the parent table manually in order to
+ keep the statistics up to date.
+ </p><p>
+ As with vacuuming for space recovery, frequent updates of statistics
+ are more useful for heavily-updated tables than for seldom-updated
+ ones. But even for a heavily-updated table, there might be no need for
+ statistics updates if the statistical distribution of the data is
+ not changing much. A simple rule of thumb is to think about how much
+ the minimum and maximum values of the columns in the table change.
+ For example, a <code class="type">timestamp</code> column that contains the time
+ of row update will have a constantly-increasing maximum value as
+ rows are added and updated; such a column will probably need more
+ frequent statistics updates than, say, a column containing URLs for
+ pages accessed on a website. The URL column might receive changes just
+ as often, but the statistical distribution of its values probably
+ changes relatively slowly.
+ </p><p>
+ It is possible to run <code class="command">ANALYZE</code> on specific tables and even
+ just specific columns of a table, so the flexibility exists to update some
+ statistics more frequently than others if your application requires it.
+ In practice, however, it is usually best to just analyze the entire
+ database, because it is a fast operation. <code class="command">ANALYZE</code> uses a
+ statistically random sampling of the rows of a table rather than reading
+ every single row.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Although per-column tweaking of <code class="command">ANALYZE</code> frequency might not be
+ very productive, you might find it worthwhile to do per-column
+ adjustment of the level of detail of the statistics collected by
+ <code class="command">ANALYZE</code>. Columns that are heavily used in <code class="literal">WHERE</code>
+ clauses and have highly irregular data distributions might require a
+ finer-grain data histogram than other columns. See <code class="command">ALTER TABLE
+ SET STATISTICS</code>, or change the database-wide default using the <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> configuration parameter.
+ </p><p>
+ Also, by default there is limited information available about
+ the selectivity of functions. However, if you create a statistics
+ object or an expression
+ index that uses a function call, useful statistics will be
+ gathered about the function, which can greatly improve query
+ plans that use the expression index.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ The autovacuum daemon does not issue <code class="command">ANALYZE</code> commands for
+ foreign tables, since it has no means of determining how often that
+ might be useful. If your queries require statistics on foreign tables
+ for proper planning, it's a good idea to run manually-managed
+ <code class="command">ANALYZE</code> commands on those tables on a suitable schedule.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ The autovacuum daemon does not issue <code class="command">ANALYZE</code> commands
+ for partitioned tables. Inheritance parents will only be analyzed if the
+ parent itself is changed - changes to child tables do not trigger
+ autoanalyze on the parent table. If your queries require statistics on
+ parent tables for proper planning, it is necessary to periodically run
+ a manual <code class="command">ANALYZE</code> on those tables to keep the statistics
+ up to date.
+ </p></div></div><div class="sect2" id="VACUUM-FOR-VISIBILITY-MAP"><div class="titlepage"><div><div><h3 class="title">25.1.4. Updating the Visibility Map</h3></div></div></div><p>
+ Vacuum maintains a <a class="link" href="storage-vm.html" title="73.4. Visibility Map">visibility map</a> for each
+ table to keep track of which pages contain only tuples that are known to be
+ visible to all active transactions (and all future transactions, until the
+ page is again modified). This has two purposes. First, vacuum
+ itself can skip such pages on the next run, since there is nothing to
+ clean up.
+ </p><p>
+ Second, it allows <span class="productname">PostgreSQL</span> to answer some
+ queries using only the index, without reference to the underlying table.
+ Since <span class="productname">PostgreSQL</span> indexes don't contain tuple
+ visibility information, a normal index scan fetches the heap tuple for each
+ matching index entry, to check whether it should be seen by the current
+ transaction.
+ An <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes"><em class="firstterm">index-only
+ scan</em></a>, on the other hand, checks the visibility map first.
+ If it's known that all tuples on the page are
+ visible, the heap fetch can be skipped. This is most useful on
+ large data sets where the visibility map can prevent disk accesses.
+ The visibility map is vastly smaller than the heap, so it can easily be
+ cached even when the heap is very large.
+ </p></div><div class="sect2" id="VACUUM-FOR-WRAPAROUND"><div class="titlepage"><div><div><h3 class="title">25.1.5. Preventing Transaction ID Wraparound Failures</h3></div></div></div><a id="id-1.6.12.10.8.2" class="indexterm"></a><a id="id-1.6.12.10.8.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span>'s
+ <a class="link" href="mvcc-intro.html" title="13.1. Introduction">MVCC</a> transaction semantics
+ depend on being able to compare transaction ID (<acronym class="acronym">XID</acronym>)
+ numbers: a row version with an insertion XID greater than the current
+ transaction's XID is <span class="quote">“<span class="quote">in the future</span>”</span> and should not be visible
+ to the current transaction. But since transaction IDs have limited size
+ (32 bits) a cluster that runs for a long time (more
+ than 4 billion transactions) would suffer <em class="firstterm">transaction ID
+ wraparound</em>: the XID counter wraps around to zero, and all of a sudden
+ transactions that were in the past appear to be in the future — which
+ means their output become invisible. In short, catastrophic data loss.
+ (Actually the data is still there, but that's cold comfort if you cannot
+ get at it.) To avoid this, it is necessary to vacuum every table
+ in every database at least once every two billion transactions.
+ </p><p>
+ The reason that periodic vacuuming solves the problem is that
+ <code class="command">VACUUM</code> will mark rows as <span class="emphasis"><em>frozen</em></span>, indicating that
+ they were inserted by a transaction that committed sufficiently far in
+ the past that the effects of the inserting transaction are certain to be
+ visible to all current and future transactions.
+ Normal XIDs are
+ compared using modulo-2<sup>32</sup> arithmetic. This means
+ that for every normal XID, there are two billion XIDs that are
+ <span class="quote">“<span class="quote">older</span>”</span> and two billion that are <span class="quote">“<span class="quote">newer</span>”</span>; another
+ way to say it is that the normal XID space is circular with no
+ endpoint. Therefore, once a row version has been created with a particular
+ normal XID, the row version will appear to be <span class="quote">“<span class="quote">in the past</span>”</span> for
+ the next two billion transactions, no matter which normal XID we are
+ talking about. If the row version still exists after more than two billion
+ transactions, it will suddenly appear to be in the future. To
+ prevent this, <span class="productname">PostgreSQL</span> reserves a special XID,
+ <code class="literal">FrozenTransactionId</code>, which does not follow the normal XID
+ comparison rules and is always considered older
+ than every normal XID.
+ Frozen row versions are treated as if the inserting XID were
+ <code class="literal">FrozenTransactionId</code>, so that they will appear to be
+ <span class="quote">“<span class="quote">in the past</span>”</span> to all normal transactions regardless of wraparound
+ issues, and so such row versions will be valid until deleted, no matter
+ how long that is.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In <span class="productname">PostgreSQL</span> versions before 9.4, freezing was
+ implemented by actually replacing a row's insertion XID
+ with <code class="literal">FrozenTransactionId</code>, which was visible in the
+ row's <code class="structname">xmin</code> system column. Newer versions just set a flag
+ bit, preserving the row's original <code class="structname">xmin</code> for possible
+ forensic use. However, rows with <code class="structname">xmin</code> equal
+ to <code class="literal">FrozenTransactionId</code> (2) may still be found
+ in databases <span class="application">pg_upgrade</span>'d from pre-9.4 versions.
+ </p><p>
+ Also, system catalogs may contain rows with <code class="structname">xmin</code> equal
+ to <code class="literal">BootstrapTransactionId</code> (1), indicating that they were
+ inserted during the first phase of <span class="application">initdb</span>.
+ Like <code class="literal">FrozenTransactionId</code>, this special XID is treated as
+ older than every normal XID.
+ </p></div><p>
+ <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FREEZE-MIN-AGE">vacuum_freeze_min_age</a>
+ controls how old an XID value has to be before rows bearing that XID will be
+ frozen. Increasing this setting may avoid unnecessary work if the
+ rows that would otherwise be frozen will soon be modified again,
+ but decreasing this setting increases
+ the number of transactions that can elapse before the table must be
+ vacuumed again.
+ </p><p>
+ <code class="command">VACUUM</code> uses the <a class="link" href="storage-vm.html" title="73.4. Visibility Map">visibility map</a>
+ to determine which pages of a table must be scanned. Normally, it
+ will skip pages that don't have any dead row versions even if those pages
+ might still have row versions with old XID values. Therefore, normal
+ <code class="command">VACUUM</code>s won't always freeze every old row version in the table.
+ When that happens, <code class="command">VACUUM</code> will eventually need to perform an
+ <em class="firstterm">aggressive vacuum</em>, which will freeze all eligible unfrozen
+ XID and MXID values, including those from all-visible but not all-frozen pages.
+ In practice most tables require periodic aggressive vacuuming.
+ <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FREEZE-TABLE-AGE">vacuum_freeze_table_age</a>
+ controls when <code class="command">VACUUM</code> does that: all-visible but not all-frozen
+ pages are scanned if the number of transactions that have passed since the
+ last such scan is greater than <code class="varname">vacuum_freeze_table_age</code> minus
+ <code class="varname">vacuum_freeze_min_age</code>. Setting
+ <code class="varname">vacuum_freeze_table_age</code> to 0 forces <code class="command">VACUUM</code> to
+ always use its aggressive strategy.
+ </p><p>
+ The maximum time that a table can go unvacuumed is two billion
+ transactions minus the <code class="varname">vacuum_freeze_min_age</code> value at
+ the time of the last aggressive vacuum. If it were to go
+ unvacuumed for longer than
+ that, data loss could result. To ensure that this does not happen,
+ autovacuum is invoked on any table that might contain unfrozen rows with
+ XIDs older than the age specified by the configuration parameter <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a>. (This will happen even if
+ autovacuum is disabled.)
+ </p><p>
+ This implies that if a table is not otherwise vacuumed,
+ autovacuum will be invoked on it approximately once every
+ <code class="varname">autovacuum_freeze_max_age</code> minus
+ <code class="varname">vacuum_freeze_min_age</code> transactions.
+ For tables that are regularly vacuumed for space reclamation purposes,
+ this is of little importance. However, for static tables
+ (including tables that receive inserts, but no updates or deletes),
+ there is no need to vacuum for space reclamation, so it can
+ be useful to try to maximize the interval between forced autovacuums
+ on very large static tables. Obviously one can do this either by
+ increasing <code class="varname">autovacuum_freeze_max_age</code> or decreasing
+ <code class="varname">vacuum_freeze_min_age</code>.
+ </p><p>
+ The effective maximum for <code class="varname">vacuum_freeze_table_age</code> is 0.95 *
+ <code class="varname">autovacuum_freeze_max_age</code>; a setting higher than that will be
+ capped to the maximum. A value higher than
+ <code class="varname">autovacuum_freeze_max_age</code> wouldn't make sense because an
+ anti-wraparound autovacuum would be triggered at that point anyway, and
+ the 0.95 multiplier leaves some breathing room to run a manual
+ <code class="command">VACUUM</code> before that happens. As a rule of thumb,
+ <code class="command">vacuum_freeze_table_age</code> should be set to a value somewhat
+ below <code class="varname">autovacuum_freeze_max_age</code>, leaving enough gap so that
+ a regularly scheduled <code class="command">VACUUM</code> or an autovacuum triggered by
+ normal delete and update activity is run in that window. Setting it too
+ close could lead to anti-wraparound autovacuums, even though the table
+ was recently vacuumed to reclaim space, whereas lower values lead to more
+ frequent aggressive vacuuming.
+ </p><p>
+ The sole disadvantage of increasing <code class="varname">autovacuum_freeze_max_age</code>
+ (and <code class="varname">vacuum_freeze_table_age</code> along with it) is that
+ the <code class="filename">pg_xact</code> and <code class="filename">pg_commit_ts</code>
+ subdirectories of the database cluster will take more space, because it
+ must store the commit status and (if <code class="varname">track_commit_timestamp</code> is
+ enabled) timestamp of all transactions back to
+ the <code class="varname">autovacuum_freeze_max_age</code> horizon. The commit status uses
+ two bits per transaction, so if
+ <code class="varname">autovacuum_freeze_max_age</code> is set to its maximum allowed value
+ of two billion, <code class="filename">pg_xact</code> can be expected to grow to about half
+ a gigabyte and <code class="filename">pg_commit_ts</code> to about 20GB. If this
+ is trivial compared to your total database size,
+ setting <code class="varname">autovacuum_freeze_max_age</code> to its maximum allowed value
+ is recommended. Otherwise, set it depending on what you are willing to
+ allow for <code class="filename">pg_xact</code> and <code class="filename">pg_commit_ts</code> storage.
+ (The default, 200 million transactions, translates to about 50MB
+ of <code class="filename">pg_xact</code> storage and about 2GB of <code class="filename">pg_commit_ts</code>
+ storage.)
+ </p><p>
+ One disadvantage of decreasing <code class="varname">vacuum_freeze_min_age</code> is that
+ it might cause <code class="command">VACUUM</code> to do useless work: freezing a row
+ version is a waste of time if the row is modified
+ soon thereafter (causing it to acquire a new XID). So the setting should
+ be large enough that rows are not frozen until they are unlikely to change
+ any more.
+ </p><p>
+ To track the age of the oldest unfrozen XIDs in a database,
+ <code class="command">VACUUM</code> stores XID
+ statistics in the system tables <code class="structname">pg_class</code> and
+ <code class="structname">pg_database</code>. In particular,
+ the <code class="structfield">relfrozenxid</code> column of a table's
+ <code class="structname">pg_class</code> row contains the oldest remaining unfrozen
+ XID at the end of the most recent <code class="command">VACUUM</code> that successfully
+ advanced <code class="structfield">relfrozenxid</code> (typically the most recent
+ aggressive VACUUM). Similarly, the
+ <code class="structfield">datfrozenxid</code> column of a database's
+ <code class="structname">pg_database</code> row is a lower bound on the unfrozen XIDs
+ appearing in that database — it is just the minimum of the
+ per-table <code class="structfield">relfrozenxid</code> values within the database.
+ A convenient way to
+ examine this information is to execute queries such as:
+
+</p><pre class="programlisting">
+SELECT c.oid::regclass as table_name,
+ greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age
+FROM pg_class c
+LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
+WHERE c.relkind IN ('r', 'm');
+
+SELECT datname, age(datfrozenxid) FROM pg_database;
+</pre><p>
+
+ The <code class="literal">age</code> column measures the number of transactions from the
+ cutoff XID to the current transaction's XID.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ When the <code class="command">VACUUM</code> command's <code class="literal">VERBOSE</code>
+ parameter is specified, <code class="command">VACUUM</code> prints various
+ statistics about the table. This includes information about how
+ <code class="structfield">relfrozenxid</code> and
+ <code class="structfield">relminmxid</code> advanced. The same details appear
+ in the server log when autovacuum logging (controlled by <a class="xref" href="runtime-config-logging.html#GUC-LOG-AUTOVACUUM-MIN-DURATION">log_autovacuum_min_duration</a>) reports on a
+ <code class="command">VACUUM</code> operation executed by autovacuum.
+ </p></div><p>
+ <code class="command">VACUUM</code> normally only scans pages that have been modified
+ since the last vacuum, but <code class="structfield">relfrozenxid</code> can only be
+ advanced when every page of the table
+ that might contain unfrozen XIDs is scanned. This happens when
+ <code class="structfield">relfrozenxid</code> is more than
+ <code class="varname">vacuum_freeze_table_age</code> transactions old, when
+ <code class="command">VACUUM</code>'s <code class="literal">FREEZE</code> option is used, or when all
+ pages that are not already all-frozen happen to
+ require vacuuming to remove dead row versions. When <code class="command">VACUUM</code>
+ scans every page in the table that is not already all-frozen, it should
+ set <code class="literal">age(relfrozenxid)</code> to a value just a little more than the
+ <code class="varname">vacuum_freeze_min_age</code> setting
+ that was used (more by the number of transactions started since the
+ <code class="command">VACUUM</code> started). <code class="command">VACUUM</code>
+ will set <code class="structfield">relfrozenxid</code> to the oldest XID
+ that remains in the table, so it's possible that the final value
+ will be much more recent than strictly required.
+ If no <code class="structfield">relfrozenxid</code>-advancing
+ <code class="command">VACUUM</code> is issued on the table until
+ <code class="varname">autovacuum_freeze_max_age</code> is reached, an autovacuum will soon
+ be forced for the table.
+ </p><p>
+ If for some reason autovacuum fails to clear old XIDs from a table, the
+ system will begin to emit warning messages like this when the database's
+ oldest XIDs reach forty million transactions from the wraparound point:
+
+</p><pre class="programlisting">
+WARNING: database "mydb" must be vacuumed within 39985967 transactions
+HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database.
+</pre><p>
+
+ (A manual <code class="command">VACUUM</code> should fix the problem, as suggested by the
+ hint; but note that the <code class="command">VACUUM</code> must be performed by a
+ superuser, else it will fail to process system catalogs and thus not
+ be able to advance the database's <code class="structfield">datfrozenxid</code>.)
+ If these warnings are
+ ignored, the system will shut down and refuse to start any new
+ transactions once there are fewer than three million transactions left
+ until wraparound:
+
+</p><pre class="programlisting">
+ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb"
+HINT: Stop the postmaster and vacuum that database in single-user mode.
+</pre><p>
+
+ The three-million-transaction safety margin exists to let the
+ administrator recover without data loss, by manually executing the
+ required <code class="command">VACUUM</code> commands. However, since the system will not
+ execute commands once it has gone into the safety shutdown mode,
+ the only way to do this is to stop the server and start the server in single-user
+ mode to execute <code class="command">VACUUM</code>. The shutdown mode is not enforced
+ in single-user mode. See the <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a> reference
+ page for details about using single-user mode.
+ </p><div class="sect3" id="VACUUM-FOR-MULTIXACT-WRAPAROUND"><div class="titlepage"><div><div><h4 class="title">25.1.5.1. Multixacts and Wraparound</h4></div></div></div><a id="id-1.6.12.10.8.18.2" class="indexterm"></a><a id="id-1.6.12.10.8.18.3" class="indexterm"></a><p>
+ <em class="firstterm">Multixact IDs</em> are used to support row locking by
+ multiple transactions. Since there is only limited space in a tuple
+ header to store lock information, that information is encoded as
+ a <span class="quote">“<span class="quote">multiple transaction ID</span>”</span>, or multixact ID for short,
+ whenever there is more than one transaction concurrently locking a
+ row. Information about which transaction IDs are included in any
+ particular multixact ID is stored separately in
+ the <code class="filename">pg_multixact</code> subdirectory, and only the multixact ID
+ appears in the <code class="structfield">xmax</code> field in the tuple header.
+ Like transaction IDs, multixact IDs are implemented as a
+ 32-bit counter and corresponding storage, all of which requires
+ careful aging management, storage cleanup, and wraparound handling.
+ There is a separate storage area which holds the list of members in
+ each multixact, which also uses a 32-bit counter and which must also
+ be managed.
+ </p><p>
+ Whenever <code class="command">VACUUM</code> scans any part of a table, it will replace
+ any multixact ID it encounters which is older than
+ <a class="xref" href="runtime-config-client.html#GUC-VACUUM-MULTIXACT-FREEZE-MIN-AGE">vacuum_multixact_freeze_min_age</a>
+ by a different value, which can be the zero value, a single
+ transaction ID, or a newer multixact ID. For each table,
+ <code class="structname">pg_class</code>.<code class="structfield">relminmxid</code> stores the oldest
+ possible multixact ID still appearing in any tuple of that table.
+ If this value is older than
+ <a class="xref" href="runtime-config-client.html#GUC-VACUUM-MULTIXACT-FREEZE-TABLE-AGE">vacuum_multixact_freeze_table_age</a>, an aggressive
+ vacuum is forced. As discussed in the previous section, an aggressive
+ vacuum means that only those pages which are known to be all-frozen will
+ be skipped. <code class="function">mxid_age()</code> can be used on
+ <code class="structname">pg_class</code>.<code class="structfield">relminmxid</code> to find its age.
+ </p><p>
+ Aggressive <code class="command">VACUUM</code>s, regardless of what causes
+ them, are <span class="emphasis"><em>guaranteed</em></span> to be able to advance
+ the table's <code class="structfield">relminmxid</code>.
+ Eventually, as all tables in all databases are scanned and their
+ oldest multixact values are advanced, on-disk storage for older
+ multixacts can be removed.
+ </p><p>
+ As a safety device, an aggressive vacuum scan will
+ occur for any table whose multixact-age is greater than <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE">autovacuum_multixact_freeze_max_age</a>. Also, if the
+ storage occupied by multixacts members exceeds 2GB, aggressive vacuum
+ scans will occur more often for all tables, starting with those that
+ have the oldest multixact-age. Both of these kinds of aggressive
+ scans will occur even if autovacuum is nominally disabled.
+ </p></div></div><div class="sect2" id="AUTOVACUUM"><div class="titlepage"><div><div><h3 class="title">25.1.6. The Autovacuum Daemon</h3></div></div></div><a id="id-1.6.12.10.9.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> has an optional but highly
+ recommended feature called <em class="firstterm">autovacuum</em>,
+ whose purpose is to automate the execution of
+ <code class="command">VACUUM</code> and <code class="command">ANALYZE</code> commands.
+ When enabled, autovacuum checks for
+ tables that have had a large number of inserted, updated or deleted
+ tuples. These checks use the statistics collection facility;
+ therefore, autovacuum cannot be used unless <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-COUNTS">track_counts</a> is set to <code class="literal">true</code>.
+ In the default configuration, autovacuuming is enabled and the related
+ configuration parameters are appropriately set.
+ </p><p>
+ The <span class="quote">“<span class="quote">autovacuum daemon</span>”</span> actually consists of multiple processes.
+ There is a persistent daemon process, called the
+ <em class="firstterm">autovacuum launcher</em>, which is in charge of starting
+ <em class="firstterm">autovacuum worker</em> processes for all databases. The
+ launcher will distribute the work across time, attempting to start one
+ worker within each database every <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-NAPTIME">autovacuum_naptime</a>
+ seconds. (Therefore, if the installation has <em class="replaceable"><code>N</code></em> databases,
+ a new worker will be launched every
+ <code class="varname">autovacuum_naptime</code>/<em class="replaceable"><code>N</code></em> seconds.)
+ A maximum of <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS">autovacuum_max_workers</a> worker processes
+ are allowed to run at the same time. If there are more than
+ <code class="varname">autovacuum_max_workers</code> databases to be processed,
+ the next database will be processed as soon as the first worker finishes.
+ Each worker process will check each table within its database and
+ execute <code class="command">VACUUM</code> and/or <code class="command">ANALYZE</code> as needed.
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-AUTOVACUUM-MIN-DURATION">log_autovacuum_min_duration</a> can be set to monitor
+ autovacuum workers' activity.
+ </p><p>
+ If several large tables all become eligible for vacuuming in a short
+ amount of time, all autovacuum workers might become occupied with
+ vacuuming those tables for a long period. This would result
+ in other tables and databases not being vacuumed until a worker becomes
+ available. There is no limit on how many workers might be in a
+ single database, but workers do try to avoid repeating work that has
+ already been done by other workers. Note that the number of running
+ workers does not count towards <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a> or
+ <a class="xref" href="runtime-config-connection.html#GUC-SUPERUSER-RESERVED-CONNECTIONS">superuser_reserved_connections</a> limits.
+ </p><p>
+ Tables whose <code class="structfield">relfrozenxid</code> value is more than
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a> transactions old are always
+ vacuumed (this also applies to those tables whose freeze max age has
+ been modified via storage parameters; see below). Otherwise, if the
+ number of tuples obsoleted since the last
+ <code class="command">VACUUM</code> exceeds the <span class="quote">“<span class="quote">vacuum threshold</span>”</span>, the
+ table is vacuumed. The vacuum threshold is defined as:
+</p><pre class="programlisting">
+vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples
+</pre><p>
+ where the vacuum base threshold is
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-THRESHOLD">autovacuum_vacuum_threshold</a>,
+ the vacuum scale factor is
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-SCALE-FACTOR">autovacuum_vacuum_scale_factor</a>,
+ and the number of tuples is
+ <code class="structname">pg_class</code>.<code class="structfield">reltuples</code>.
+ </p><p>
+ The table is also vacuumed if the number of tuples inserted since the last
+ vacuum has exceeded the defined insert threshold, which is defined as:
+</p><pre class="programlisting">
+vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples
+</pre><p>
+ where the vacuum insert base threshold is
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-INSERT-THRESHOLD">autovacuum_vacuum_insert_threshold</a>,
+ and vacuum insert scale factor is
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-INSERT-SCALE-FACTOR">autovacuum_vacuum_insert_scale_factor</a>.
+ Such vacuums may allow portions of the table to be marked as
+ <em class="firstterm">all visible</em> and also allow tuples to be frozen, which
+ can reduce the work required in subsequent vacuums.
+ For tables which receive <code class="command">INSERT</code> operations but no or
+ almost no <code class="command">UPDATE</code>/<code class="command">DELETE</code> operations,
+ it may be beneficial to lower the table's
+ <a class="xref" href="sql-createtable.html#RELOPTION-AUTOVACUUM-FREEZE-MIN-AGE">autovacuum_freeze_min_age</a> as this may allow
+ tuples to be frozen by earlier vacuums. The number of obsolete tuples and
+ the number of inserted tuples are obtained from the cumulative statistics system;
+ it is a semi-accurate count updated by each <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code> and <code class="command">INSERT</code> operation. (It is
+ only semi-accurate because some information might be lost under heavy
+ load.) If the <code class="structfield">relfrozenxid</code> value of the table
+ is more than <code class="varname">vacuum_freeze_table_age</code> transactions old,
+ an aggressive vacuum is performed to freeze old tuples and advance
+ <code class="structfield">relfrozenxid</code>; otherwise, only pages that have been modified
+ since the last vacuum are scanned.
+ </p><p>
+ For analyze, a similar condition is used: the threshold, defined as:
+</p><pre class="programlisting">
+analyze threshold = analyze base threshold + analyze scale factor * number of tuples
+</pre><p>
+ is compared to the total number of tuples inserted, updated, or deleted
+ since the last <code class="command">ANALYZE</code>.
+ </p><p>
+ Partitioned tables are not processed by autovacuum. Statistics
+ should be collected by running a manual <code class="command">ANALYZE</code> when it is
+ first populated, and again whenever the distribution of data in its
+ partitions changes significantly.
+ </p><p>
+ Temporary tables cannot be accessed by autovacuum. Therefore,
+ appropriate vacuum and analyze operations should be performed via
+ session SQL commands.
+ </p><p>
+ The default thresholds and scale factors are taken from
+ <code class="filename">postgresql.conf</code>, but it is possible to override them
+ (and many other autovacuum control parameters) on a per-table basis; see
+ <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" title="Storage Parameters">Storage Parameters</a> for more information.
+ If a setting has been changed via a table's storage parameters, that value
+ is used when processing that table; otherwise the global settings are
+ used. See <a class="xref" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming">Section 20.10</a> for more details on
+ the global settings.
+ </p><p>
+ When multiple workers are running, the autovacuum cost delay parameters
+ (see <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST" title="20.4.4. Cost-based Vacuum Delay">Section 20.4.4</a>) are
+ <span class="quote">“<span class="quote">balanced</span>”</span> among all the running workers, so that the
+ total I/O impact on the system is the same regardless of the number
+ of workers actually running. However, any workers processing tables whose
+ per-table <code class="literal">autovacuum_vacuum_cost_delay</code> or
+ <code class="literal">autovacuum_vacuum_cost_limit</code> storage parameters have been set
+ are not considered in the balancing algorithm.
+ </p><p>
+ Autovacuum workers generally don't block other commands. If a process
+ attempts to acquire a lock that conflicts with the
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock held by autovacuum, lock
+ acquisition will interrupt the autovacuum. For conflicting lock modes,
+ see <a class="xref" href="explicit-locking.html#TABLE-LOCK-COMPATIBILITY" title="Table 13.2. Conflicting Lock Modes">Table 13.2</a>. However, if the autovacuum
+ is running to prevent transaction ID wraparound (i.e., the autovacuum query
+ name in the <code class="structname">pg_stat_activity</code> view ends with
+ <code class="literal">(to prevent wraparound)</code>), the autovacuum is not
+ automatically interrupted.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ Regularly running commands that acquire locks conflicting with a
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock (e.g., ANALYZE) can
+ effectively prevent autovacuums from ever completing.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="routine-reindex.html" title="25.2. Routine Reindexing">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 25. Routine Database Maintenance Tasks </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 25.2. Routine Reindexing</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/row-estimation-examples.html b/doc/src/sgml/html/row-estimation-examples.html
new file mode 100644
index 0000000..e62d2c4
--- /dev/null
+++ b/doc/src/sgml/html/row-estimation-examples.html
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>75.1. Row Estimation Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics" /><link rel="next" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">75.1. Row Estimation Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Up</a></td><th width="60%" align="center">Chapter 75. How the Planner Uses Statistics</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROW-ESTIMATION-EXAMPLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">75.1. Row Estimation Examples</h2></div></div></div><a id="id-1.10.26.4.2" class="indexterm"></a><p>
+ The examples shown below use tables in the <span class="productname">PostgreSQL</span>
+ regression test database.
+ The outputs shown are taken from version 8.3.
+ The behavior of earlier (or later) versions might vary.
+ Note also that since <code class="command">ANALYZE</code> uses random sampling
+ while producing statistics, the results will change slightly after
+ any new <code class="command">ANALYZE</code>.
+ </p><p>
+ Let's start with a very simple query:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1;
+
+ QUERY PLAN
+-------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
+</pre><p>
+
+ How the planner determines the cardinality of <code class="structname">tenk1</code>
+ is covered in <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>, but is repeated here for
+ completeness. The number of pages and rows is looked up in
+ <code class="structname">pg_class</code>:
+
+</p><pre class="programlisting">
+SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
+
+ relpages | reltuples
+----------+-----------
+ 358 | 10000
+</pre><p>
+
+ These numbers are current as of the last <code class="command">VACUUM</code> or
+ <code class="command">ANALYZE</code> on the table. The planner then fetches the
+ actual current number of pages in the table (this is a cheap operation,
+ not requiring a table scan). If that is different from
+ <code class="structfield">relpages</code> then
+ <code class="structfield">reltuples</code> is scaled accordingly to
+ arrive at a current number-of-rows estimate. In the example above, the value of
+ <code class="structfield">relpages</code> is up-to-date so the rows estimate is
+ the same as <code class="structfield">reltuples</code>.
+ </p><p>
+ Let's move on to an example with a range condition in its
+ <code class="literal">WHERE</code> clause:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 1000;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------
+ Bitmap Heap Scan on tenk1 (cost=24.06..394.64 rows=1007 width=244)
+ Recheck Cond: (unique1 &lt; 1000)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
+ Index Cond: (unique1 &lt; 1000)
+</pre><p>
+
+ The planner examines the <code class="literal">WHERE</code> clause condition
+ and looks up the selectivity function for the operator
+ <code class="literal">&lt;</code> in <code class="structname">pg_operator</code>.
+ This is held in the column <code class="structfield">oprrest</code>,
+ and the entry in this case is <code class="function">scalarltsel</code>.
+ The <code class="function">scalarltsel</code> function retrieves the histogram for
+ <code class="structfield">unique1</code> from
+ <code class="structname">pg_statistic</code>. For manual queries it is more
+ convenient to look in the simpler <code class="structname">pg_stats</code>
+ view:
+
+</p><pre class="programlisting">
+SELECT histogram_bounds FROM pg_stats
+WHERE tablename='tenk1' AND attname='unique1';
+
+ histogram_bounds
+------------------------------------------------------
+ {0,993,1997,3050,4040,5036,5957,7057,8029,9016,9995}
+</pre><p>
+
+ Next the fraction of the histogram occupied by <span class="quote">“<span class="quote">&lt; 1000</span>”</span>
+ is worked out. This is the selectivity. The histogram divides the range
+ into equal frequency buckets, so all we have to do is locate the bucket
+ that our value is in and count <span class="emphasis"><em>part</em></span> of it and
+ <span class="emphasis"><em>all</em></span> of the ones before. The value 1000 is clearly in
+ the second bucket (993–1997). Assuming a linear distribution of
+ values inside each bucket, we can calculate the selectivity as:
+
+</p><pre class="programlisting">
+selectivity = (1 + (1000 - bucket[2].min)/(bucket[2].max - bucket[2].min))/num_buckets
+ = (1 + (1000 - 993)/(1997 - 993))/10
+ = 0.100697
+</pre><p>
+
+ that is, one whole bucket plus a linear fraction of the second, divided by
+ the number of buckets. The estimated number of rows can now be calculated as
+ the product of the selectivity and the cardinality of
+ <code class="structname">tenk1</code>:
+
+</p><pre class="programlisting">
+rows = rel_cardinality * selectivity
+ = 10000 * 0.100697
+ = 1007 (rounding off)
+</pre><p>
+ </p><p>
+ Next let's consider an example with an equality condition in its
+ <code class="literal">WHERE</code> clause:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'CRAAAA';
+
+ QUERY PLAN
+----------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=30 width=244)
+ Filter: (stringu1 = 'CRAAAA'::name)
+</pre><p>
+
+ Again the planner examines the <code class="literal">WHERE</code> clause condition
+ and looks up the selectivity function for <code class="literal">=</code>, which is
+ <code class="function">eqsel</code>. For equality estimation the histogram is
+ not useful; instead the list of <em class="firstterm">most
+ common values</em> (<acronym class="acronym">MCV</acronym>s) is used to determine the
+ selectivity. Let's have a look at the MCVs, with some additional columns
+ that will be useful later:
+
+</p><pre class="programlisting">
+SELECT null_frac, n_distinct, most_common_vals, most_common_freqs FROM pg_stats
+WHERE tablename='tenk1' AND attname='stringu1';
+
+null_frac | 0
+n_distinct | 676
+most_common_vals | {EJAAAA,BBAAAA,CRAAAA,FCAAAA,FEAAAA,GSAAAA,​JOAAAA,MCAAAA,NAAAAA,WGAAAA}
+most_common_freqs | {0.00333333,0.003,0.003,0.003,0.003,0.003,​0.003,0.003,0.003,0.003}
+
+</pre><p>
+
+ Since <code class="literal">CRAAAA</code> appears in the list of MCVs, the selectivity is
+ merely the corresponding entry in the list of most common frequencies
+ (<acronym class="acronym">MCF</acronym>s):
+
+</p><pre class="programlisting">
+selectivity = mcf[3]
+ = 0.003
+</pre><p>
+
+ As before, the estimated number of rows is just the product of this with the
+ cardinality of <code class="structname">tenk1</code>:
+
+</p><pre class="programlisting">
+rows = 10000 * 0.003
+ = 30
+</pre><p>
+ </p><p>
+ Now consider the same query, but with a constant that is not in the
+ <acronym class="acronym">MCV</acronym> list:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'xxx';
+
+ QUERY PLAN
+----------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=15 width=244)
+ Filter: (stringu1 = 'xxx'::name)
+</pre><p>
+
+ This is quite a different problem: how to estimate the selectivity when the
+ value is <span class="emphasis"><em>not</em></span> in the <acronym class="acronym">MCV</acronym> list.
+ The approach is to use the fact that the value is not in the list,
+ combined with the knowledge of the frequencies for all of the
+ <acronym class="acronym">MCV</acronym>s:
+
+</p><pre class="programlisting">
+selectivity = (1 - sum(mvf))/(num_distinct - num_mcv)
+ = (1 - (0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003 +
+ 0.003 + 0.003 + 0.003 + 0.003))/(676 - 10)
+ = 0.0014559
+</pre><p>
+
+ That is, add up all the frequencies for the <acronym class="acronym">MCV</acronym>s and
+ subtract them from one, then
+ divide by the number of <span class="emphasis"><em>other</em></span> distinct values.
+ This amounts to assuming that the fraction of the column that is not any
+ of the MCVs is evenly distributed among all the other distinct values.
+ Notice that there are no null values so we don't have to worry about those
+ (otherwise we'd subtract the null fraction from the numerator as well).
+ The estimated number of rows is then calculated as usual:
+
+</p><pre class="programlisting">
+rows = 10000 * 0.0014559
+ = 15 (rounding off)
+</pre><p>
+ </p><p>
+ The previous example with <code class="literal">unique1 &lt; 1000</code> was an
+ oversimplification of what <code class="function">scalarltsel</code> really does;
+ now that we have seen an example of the use of MCVs, we can fill in some
+ more detail. The example was correct as far as it went, because since
+ <code class="structfield">unique1</code> is a unique column it has no MCVs (obviously, no
+ value is any more common than any other value). For a non-unique
+ column, there will normally be both a histogram and an MCV list, and
+ <span class="emphasis"><em>the histogram does not include the portion of the column
+ population represented by the MCVs</em></span>. We do things this way because
+ it allows more precise estimation. In this situation
+ <code class="function">scalarltsel</code> directly applies the condition (e.g.,
+ <span class="quote">“<span class="quote">&lt; 1000</span>”</span>) to each value of the MCV list, and adds up the
+ frequencies of the MCVs for which the condition is true. This gives
+ an exact estimate of the selectivity within the portion of the table
+ that is MCVs. The histogram is then used in the same way as above
+ to estimate the selectivity in the portion of the table that is not
+ MCVs, and then the two numbers are combined to estimate the overall
+ selectivity. For example, consider
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1 WHERE stringu1 &lt; 'IAAAAA';
+
+ QUERY PLAN
+------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=3077 width=244)
+ Filter: (stringu1 &lt; 'IAAAAA'::name)
+</pre><p>
+
+ We already saw the MCV information for <code class="structfield">stringu1</code>,
+ and here is its histogram:
+
+</p><pre class="programlisting">
+SELECT histogram_bounds FROM pg_stats
+WHERE tablename='tenk1' AND attname='stringu1';
+
+ histogram_bounds
+-------------------------------------------------------------------​-------------
+ {AAAAAA,CQAAAA,FRAAAA,IBAAAA,KRAAAA,NFAAAA,PSAAAA,SGAAAA,VAAAAA,​XLAAAA,ZZAAAA}
+</pre><p>
+
+ Checking the MCV list, we find that the condition <code class="literal">stringu1 &lt;
+ 'IAAAAA'</code> is satisfied by the first six entries and not the last four,
+ so the selectivity within the MCV part of the population is
+
+</p><pre class="programlisting">
+selectivity = sum(relevant mvfs)
+ = 0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003
+ = 0.01833333
+</pre><p>
+
+ Summing all the MCFs also tells us that the total fraction of the
+ population represented by MCVs is 0.03033333, and therefore the
+ fraction represented by the histogram is 0.96966667 (again, there
+ are no nulls, else we'd have to exclude them here). We can see
+ that the value <code class="literal">IAAAAA</code> falls nearly at the end of the
+ third histogram bucket. Using some rather cheesy assumptions
+ about the frequency of different characters, the planner arrives
+ at the estimate 0.298387 for the portion of the histogram population
+ that is less than <code class="literal">IAAAAA</code>. We then combine the estimates
+ for the MCV and non-MCV populations:
+
+</p><pre class="programlisting">
+selectivity = mcv_selectivity + histogram_selectivity * histogram_fraction
+ = 0.01833333 + 0.298387 * 0.96966667
+ = 0.307669
+
+rows = 10000 * 0.307669
+ = 3077 (rounding off)
+</pre><p>
+
+ In this particular example, the correction from the MCV list is fairly
+ small, because the column distribution is actually quite flat (the
+ statistics showing these particular values as being more common than
+ others are mostly due to sampling error). In a more typical case where
+ some values are significantly more common than others, this complicated
+ process gives a useful improvement in accuracy because the selectivity
+ for the most common values is found exactly.
+ </p><p>
+ Now let's consider a case with more than one
+ condition in the <code class="literal">WHERE</code> clause:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 1000 AND stringu1 = 'xxx';
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------
+ Bitmap Heap Scan on tenk1 (cost=23.80..396.91 rows=1 width=244)
+ Recheck Cond: (unique1 &lt; 1000)
+ Filter: (stringu1 = 'xxx'::name)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
+ Index Cond: (unique1 &lt; 1000)
+</pre><p>
+
+ The planner assumes that the two conditions are independent, so that
+ the individual selectivities of the clauses can be multiplied together:
+
+</p><pre class="programlisting">
+selectivity = selectivity(unique1 &lt; 1000) * selectivity(stringu1 = 'xxx')
+ = 0.100697 * 0.0014559
+ = 0.0001466
+
+rows = 10000 * 0.0001466
+ = 1 (rounding off)
+</pre><p>
+
+ Notice that the number of rows estimated to be returned from the bitmap
+ index scan reflects only the condition used with the index; this is
+ important since it affects the cost estimate for the subsequent heap
+ fetches.
+ </p><p>
+ Finally we will examine a query that involves a join:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 50 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------
+ Nested Loop (cost=4.64..456.23 rows=50 width=488)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.64..142.17 rows=50 width=244)
+ Recheck Cond: (unique1 &lt; 50)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.63 rows=50 width=0)
+ Index Cond: (unique1 &lt; 50)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..6.27 rows=1 width=244)
+ Index Cond: (unique2 = t1.unique2)
+</pre><p>
+
+ The restriction on <code class="structname">tenk1</code>,
+ <code class="literal">unique1 &lt; 50</code>,
+ is evaluated before the nested-loop join.
+ This is handled analogously to the previous range example. This time the
+ value 50 falls into the first bucket of the
+ <code class="structfield">unique1</code> histogram:
+
+</p><pre class="programlisting">
+selectivity = (0 + (50 - bucket[1].min)/(bucket[1].max - bucket[1].min))/num_buckets
+ = (0 + (50 - 0)/(993 - 0))/10
+ = 0.005035
+
+rows = 10000 * 0.005035
+ = 50 (rounding off)
+</pre><p>
+
+ The restriction for the join is <code class="literal">t2.unique2 = t1.unique2</code>.
+ The operator is just
+ our familiar <code class="literal">=</code>, however the selectivity function is
+ obtained from the <code class="structfield">oprjoin</code> column of
+ <code class="structname">pg_operator</code>, and is <code class="function">eqjoinsel</code>.
+ <code class="function">eqjoinsel</code> looks up the statistical information for both
+ <code class="structname">tenk2</code> and <code class="structname">tenk1</code>:
+
+</p><pre class="programlisting">
+SELECT tablename, null_frac,n_distinct, most_common_vals FROM pg_stats
+WHERE tablename IN ('tenk1', 'tenk2') AND attname='unique2';
+
+tablename | null_frac | n_distinct | most_common_vals
+-----------+-----------+------------+------------------
+ tenk1 | 0 | -1 |
+ tenk2 | 0 | -1 |
+</pre><p>
+
+ In this case there is no <acronym class="acronym">MCV</acronym> information for
+ <code class="structfield">unique2</code> because all the values appear to be
+ unique, so we use an algorithm that relies only on the number of
+ distinct values for both relations together with their null fractions:
+
+</p><pre class="programlisting">
+selectivity = (1 - null_frac1) * (1 - null_frac2) * min(1/num_distinct1, 1/num_distinct2)
+ = (1 - 0) * (1 - 0) / max(10000, 10000)
+ = 0.0001
+</pre><p>
+
+ This is, subtract the null fraction from one for each of the relations,
+ and divide by the maximum of the numbers of distinct values.
+ The number of rows
+ that the join is likely to emit is calculated as the cardinality of the
+ Cartesian product of the two inputs, multiplied by the
+ selectivity:
+
+</p><pre class="programlisting">
+rows = (outer_cardinality * inner_cardinality) * selectivity
+ = (50 * 10000) * 0.0001
+ = 50
+</pre><p>
+ </p><p>
+ Had there been MCV lists for the two columns,
+ <code class="function">eqjoinsel</code> would have used direct comparison of the MCV
+ lists to determine the join selectivity within the part of the column
+ populations represented by the MCVs. The estimate for the remainder of the
+ populations follows the same approach shown here.
+ </p><p>
+ Notice that we showed <code class="literal">inner_cardinality</code> as 10000, that is,
+ the unmodified size of <code class="structname">tenk2</code>. It might appear from
+ inspection of the <code class="command">EXPLAIN</code> output that the estimate of
+ join rows comes from 50 * 1, that is, the number of outer rows times
+ the estimated number of rows obtained by each inner index scan on
+ <code class="structname">tenk2</code>. But this is not the case: the join relation size
+ is estimated before any particular join plan has been considered. If
+ everything is working well then the two ways of estimating the join
+ size will produce about the same answer, but due to round-off error and
+ other factors they sometimes diverge significantly.
+ </p><p>
+ For those interested in further details, estimation of the size of
+ a table (before any <code class="literal">WHERE</code> clauses) is done in
+ <code class="filename">src/backend/optimizer/util/plancat.c</code>. The generic
+ logic for clause selectivities is in
+ <code class="filename">src/backend/optimizer/path/clausesel.c</code>. The
+ operator-specific selectivity functions are mostly found
+ in <code class="filename">src/backend/utils/adt/selfuncs.c</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="planner-stats-details.html" title="Chapter 75. How the Planner Uses Statistics">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 75. How the Planner Uses Statistics </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 75.2. Multivariate Statistics Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rowtypes.html b/doc/src/sgml/html/rowtypes.html
new file mode 100644
index 0000000..8a059dc
--- /dev/null
+++ b/doc/src/sgml/html/rowtypes.html
@@ -0,0 +1,424 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>8.16. Composite Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="arrays.html" title="8.15. Arrays" /><link rel="next" href="rangetypes.html" title="8.17. Range Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">8.16. Composite Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="arrays.html" title="8.15. Arrays">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><th width="60%" align="center">Chapter 8. Data Types</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rangetypes.html" title="8.17. Range Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="ROWTYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">8.16. Composite Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-DECLARING">8.16.1. Declaration of Composite Types</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#id-1.5.7.24.6">8.16.2. Constructing Composite Values</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-ACCESSING">8.16.3. Accessing Composite Types</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#id-1.5.7.24.8">8.16.4. Modifying Composite Types</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-USAGE">8.16.5. Using Composite Types in Queries</a></span></dt><dt><span class="sect2"><a href="rowtypes.html#ROWTYPES-IO-SYNTAX">8.16.6. Composite Type Input and Output Syntax</a></span></dt></dl></div><a id="id-1.5.7.24.2" class="indexterm"></a><a id="id-1.5.7.24.3" class="indexterm"></a><p>
+ A <em class="firstterm">composite type</em> represents the structure of a row or record;
+ it is essentially just a list of field names and their data types.
+ <span class="productname">PostgreSQL</span> allows composite types to be
+ used in many of the same ways that simple types can be used. For example, a
+ column of a table can be declared to be of a composite type.
+ </p><div class="sect2" id="ROWTYPES-DECLARING"><div class="titlepage"><div><div><h3 class="title">8.16.1. Declaration of Composite Types</h3></div></div></div><p>
+ Here are two simple examples of defining composite types:
+</p><pre class="programlisting">
+CREATE TYPE complex AS (
+ r double precision,
+ i double precision
+);
+
+CREATE TYPE inventory_item AS (
+ name text,
+ supplier_id integer,
+ price numeric
+);
+</pre><p>
+ The syntax is comparable to <code class="command">CREATE TABLE</code>, except that only
+ field names and types can be specified; no constraints (such as <code class="literal">NOT
+ NULL</code>) can presently be included. Note that the <code class="literal">AS</code> keyword
+ is essential; without it, the system will think a different kind
+ of <code class="command">CREATE TYPE</code> command is meant, and you will get odd syntax
+ errors.
+ </p><p>
+ Having defined the types, we can use them to create tables:
+
+</p><pre class="programlisting">
+CREATE TABLE on_hand (
+ item inventory_item,
+ count integer
+);
+
+INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
+</pre><p>
+
+ or functions:
+
+</p><pre class="programlisting">
+CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric
+AS 'SELECT $1.price * $2' LANGUAGE SQL;
+
+SELECT price_extension(item, 10) FROM on_hand;
+</pre><p>
+
+ </p><p>
+ Whenever you create a table, a composite type is also automatically
+ created, with the same name as the table, to represent the table's
+ row type. For example, had we said:
+</p><pre class="programlisting">
+CREATE TABLE inventory_item (
+ name text,
+ supplier_id integer REFERENCES suppliers,
+ price numeric CHECK (price &gt; 0)
+);
+</pre><p>
+ then the same <code class="literal">inventory_item</code> composite type shown above would
+ come into being as a
+ byproduct, and could be used just as above. Note however an important
+ restriction of the current implementation: since no constraints are
+ associated with a composite type, the constraints shown in the table
+ definition <span class="emphasis"><em>do not apply</em></span> to values of the composite type
+ outside the table. (To work around this, create a
+ <a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN"><em class="glossterm"><a class="glossterm" href="glossary.html#GLOSSARY-DOMAIN" title="Domain">domain</a></em></a> over the composite
+ type, and apply the desired constraints as <code class="literal">CHECK</code>
+ constraints of the domain.)
+ </p></div><div class="sect2" id="id-1.5.7.24.6"><div class="titlepage"><div><div><h3 class="title">8.16.2. Constructing Composite Values</h3></div></div></div><a id="id-1.5.7.24.6.2" class="indexterm"></a><p>
+ To write a composite value as a literal constant, enclose the field
+ values within parentheses and separate them by commas. You can put double
+ quotes around any field value, and must do so if it contains commas or
+ parentheses. (More details appear <a class="link" href="rowtypes.html#ROWTYPES-IO-SYNTAX" title="8.16.6. Composite Type Input and Output Syntax">below</a>.) Thus, the general format of
+ a composite constant is the following:
+</p><pre class="synopsis">
+'( <em class="replaceable"><code>val1</code></em> , <em class="replaceable"><code>val2</code></em> , ... )'
+</pre><p>
+ An example is:
+</p><pre class="programlisting">
+'("fuzzy dice",42,1.99)'
+</pre><p>
+ which would be a valid value of the <code class="literal">inventory_item</code> type
+ defined above. To make a field be NULL, write no characters at all
+ in its position in the list. For example, this constant specifies
+ a NULL third field:
+</p><pre class="programlisting">
+'("fuzzy dice",42,)'
+</pre><p>
+ If you want an empty string rather than NULL, write double quotes:
+</p><pre class="programlisting">
+'("",42,)'
+</pre><p>
+ Here the first field is a non-NULL empty string, the third is NULL.
+ </p><p>
+ (These constants are actually only a special case of
+ the generic type constants discussed in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC" title="4.1.2.7. Constants of Other Types">Section 4.1.2.7</a>. The constant is initially
+ treated as a string and passed to the composite-type input conversion
+ routine. An explicit type specification might be necessary to tell
+ which type to convert the constant to.)
+ </p><p>
+ The <code class="literal">ROW</code> expression syntax can also be used to
+ construct composite values. In most cases this is considerably
+ simpler to use than the string-literal syntax since you don't have
+ to worry about multiple layers of quoting. We already used this
+ method above:
+</p><pre class="programlisting">
+ROW('fuzzy dice', 42, 1.99)
+ROW('', 42, NULL)
+</pre><p>
+ The ROW keyword is actually optional as long as you have more than one
+ field in the expression, so these can be simplified to:
+</p><pre class="programlisting">
+('fuzzy dice', 42, 1.99)
+('', 42, NULL)
+</pre><p>
+ The <code class="literal">ROW</code> expression syntax is discussed in more detail in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">Section 4.2.13</a>.
+ </p></div><div class="sect2" id="ROWTYPES-ACCESSING"><div class="titlepage"><div><div><h3 class="title">8.16.3. Accessing Composite Types</h3></div></div></div><p>
+ To access a field of a composite column, one writes a dot and the field
+ name, much like selecting a field from a table name. In fact, it's so
+ much like selecting from a table name that you often have to use parentheses
+ to keep from confusing the parser. For example, you might try to select
+ some subfields from our <code class="literal">on_hand</code> example table with something
+ like:
+
+</p><pre class="programlisting">
+SELECT item.name FROM on_hand WHERE item.price &gt; 9.99;
+</pre><p>
+
+ This will not work since the name <code class="literal">item</code> is taken to be a table
+ name, not a column name of <code class="literal">on_hand</code>, per SQL syntax rules.
+ You must write it like this:
+
+</p><pre class="programlisting">
+SELECT (item).name FROM on_hand WHERE (item).price &gt; 9.99;
+</pre><p>
+
+ or if you need to use the table name as well (for instance in a multitable
+ query), like this:
+
+</p><pre class="programlisting">
+SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price &gt; 9.99;
+</pre><p>
+
+ Now the parenthesized object is correctly interpreted as a reference to
+ the <code class="literal">item</code> column, and then the subfield can be selected from it.
+ </p><p>
+ Similar syntactic issues apply whenever you select a field from a composite
+ value. For instance, to select just one field from the result of a function
+ that returns a composite value, you'd need to write something like:
+
+</p><pre class="programlisting">
+SELECT (my_func(...)).field FROM ...
+</pre><p>
+
+ Without the extra parentheses, this will generate a syntax error.
+ </p><p>
+ The special field name <code class="literal">*</code> means <span class="quote">“<span class="quote">all fields</span>”</span>, as
+ further explained in <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a>.
+ </p></div><div class="sect2" id="id-1.5.7.24.8"><div class="titlepage"><div><div><h3 class="title">8.16.4. Modifying Composite Types</h3></div></div></div><p>
+ Here are some examples of the proper syntax for inserting and updating
+ composite columns.
+ First, inserting or updating a whole column:
+
+</p><pre class="programlisting">
+INSERT INTO mytab (complex_col) VALUES((1.1,2.2));
+
+UPDATE mytab SET complex_col = ROW(1.1,2.2) WHERE ...;
+</pre><p>
+
+ The first example omits <code class="literal">ROW</code>, the second uses it; we
+ could have done it either way.
+ </p><p>
+ We can update an individual subfield of a composite column:
+
+</p><pre class="programlisting">
+UPDATE mytab SET complex_col.r = (complex_col).r + 1 WHERE ...;
+</pre><p>
+
+ Notice here that we don't need to (and indeed cannot)
+ put parentheses around the column name appearing just after
+ <code class="literal">SET</code>, but we do need parentheses when referencing the same
+ column in the expression to the right of the equal sign.
+ </p><p>
+ And we can specify subfields as targets for <code class="command">INSERT</code>, too:
+
+</p><pre class="programlisting">
+INSERT INTO mytab (complex_col.r, complex_col.i) VALUES(1.1, 2.2);
+</pre><p>
+
+ Had we not supplied values for all the subfields of the column, the
+ remaining subfields would have been filled with null values.
+ </p></div><div class="sect2" id="ROWTYPES-USAGE"><div class="titlepage"><div><div><h3 class="title">8.16.5. Using Composite Types in Queries</h3></div></div></div><p>
+ There are various special syntax rules and behaviors associated with
+ composite types in queries. These rules provide useful shortcuts,
+ but can be confusing if you don't know the logic behind them.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, a reference to a table name (or alias)
+ in a query is effectively a reference to the composite value of the
+ table's current row. For example, if we had a table
+ <code class="structname">inventory_item</code> as shown
+ <a class="link" href="rowtypes.html#ROWTYPES-DECLARING" title="8.16.1. Declaration of Composite Types">above</a>, we could write:
+</p><pre class="programlisting">
+SELECT c FROM inventory_item c;
+</pre><p>
+ This query produces a single composite-valued column, so we might get
+ output like:
+</p><pre class="programlisting">
+ c
+------------------------
+ ("fuzzy dice",42,1.99)
+(1 row)
+</pre><p>
+ Note however that simple names are matched to column names before table
+ names, so this example works only because there is no column
+ named <code class="structfield">c</code> in the query's tables.
+ </p><p>
+ The ordinary qualified-column-name
+ syntax <em class="replaceable"><code>table_name</code></em><code class="literal">.</code><em class="replaceable"><code>column_name</code></em>
+ can be understood as applying <a class="link" href="sql-expressions.html#FIELD-SELECTION" title="4.2.4. Field Selection">field
+ selection</a> to the composite value of the table's current row.
+ (For efficiency reasons, it's not actually implemented that way.)
+ </p><p>
+ When we write
+</p><pre class="programlisting">
+SELECT c.* FROM inventory_item c;
+</pre><p>
+ then, according to the SQL standard, we should get the contents of the
+ table expanded into separate columns:
+</p><pre class="programlisting">
+ name | supplier_id | price
+------------+-------------+-------
+ fuzzy dice | 42 | 1.99
+(1 row)
+</pre><p>
+ as if the query were
+</p><pre class="programlisting">
+SELECT c.name, c.supplier_id, c.price FROM inventory_item c;
+</pre><p>
+ <span class="productname">PostgreSQL</span> will apply this expansion behavior to
+ any composite-valued expression, although as shown <a class="link" href="rowtypes.html#ROWTYPES-ACCESSING" title="8.16.3. Accessing Composite Types">above</a>, you need to write parentheses
+ around the value that <code class="literal">.*</code> is applied to whenever it's not a
+ simple table name. For example, if <code class="function">myfunc()</code> is a function
+ returning a composite type with columns <code class="structfield">a</code>,
+ <code class="structfield">b</code>, and <code class="structfield">c</code>, then these two queries have the
+ same result:
+</p><pre class="programlisting">
+SELECT (myfunc(x)).* FROM some_table;
+SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table;
+</pre><p>
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <span class="productname">PostgreSQL</span> handles column expansion by
+ actually transforming the first form into the second. So, in this
+ example, <code class="function">myfunc()</code> would get invoked three times per row
+ with either syntax. If it's an expensive function you may wish to
+ avoid that, which you can do with a query like:
+</p><pre class="programlisting">
+SELECT m.* FROM some_table, LATERAL myfunc(x) AS m;
+</pre><p>
+ Placing the function in
+ a <code class="literal">LATERAL</code> <code class="literal">FROM</code> item keeps it from
+ being invoked more than once per row. <code class="literal">m.*</code> is still
+ expanded into <code class="literal">m.a, m.b, m.c</code>, but now those variables
+ are just references to the output of the <code class="literal">FROM</code> item.
+ (The <code class="literal">LATERAL</code> keyword is optional here, but we show it
+ to clarify that the function is getting <code class="structfield">x</code>
+ from <code class="structname">some_table</code>.)
+ </p></div><p>
+ The <em class="replaceable"><code>composite_value</code></em><code class="literal">.*</code> syntax results in
+ column expansion of this kind when it appears at the top level of
+ a <a class="link" href="queries-select-lists.html" title="7.3. Select Lists"><code class="command">SELECT</code> output
+ list</a>, a <a class="link" href="dml-returning.html" title="6.4. Returning Data from Modified Rows"><code class="literal">RETURNING</code>
+ list</a> in <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code>,
+ a <a class="link" href="queries-values.html" title="7.7. VALUES Lists"><code class="literal">VALUES</code> clause</a>, or
+ a <a class="link" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">row constructor</a>.
+ In all other contexts (including when nested inside one of those
+ constructs), attaching <code class="literal">.*</code> to a composite value does not
+ change the value, since it means <span class="quote">“<span class="quote">all columns</span>”</span> and so the
+ same composite value is produced again. For example,
+ if <code class="function">somefunc()</code> accepts a composite-valued argument,
+ these queries are the same:
+
+</p><pre class="programlisting">
+SELECT somefunc(c.*) FROM inventory_item c;
+SELECT somefunc(c) FROM inventory_item c;
+</pre><p>
+
+ In both cases, the current row of <code class="structname">inventory_item</code> is
+ passed to the function as a single composite-valued argument.
+ Even though <code class="literal">.*</code> does nothing in such cases, using it is good
+ style, since it makes clear that a composite value is intended. In
+ particular, the parser will consider <code class="literal">c</code> in <code class="literal">c.*</code> to
+ refer to a table name or alias, not to a column name, so that there is
+ no ambiguity; whereas without <code class="literal">.*</code>, it is not clear
+ whether <code class="literal">c</code> means a table name or a column name, and in fact
+ the column-name interpretation will be preferred if there is a column
+ named <code class="literal">c</code>.
+ </p><p>
+ Another example demonstrating these concepts is that all these queries
+ mean the same thing:
+</p><pre class="programlisting">
+SELECT * FROM inventory_item c ORDER BY c;
+SELECT * FROM inventory_item c ORDER BY c.*;
+SELECT * FROM inventory_item c ORDER BY ROW(c.*);
+</pre><p>
+ All of these <code class="literal">ORDER BY</code> clauses specify the row's composite
+ value, resulting in sorting the rows according to the rules described
+ in <a class="xref" href="functions-comparisons.html#COMPOSITE-TYPE-COMPARISON" title="9.24.6. Composite Type Comparison">Section 9.24.6</a>. However,
+ if <code class="structname">inventory_item</code> contained a column
+ named <code class="structfield">c</code>, the first case would be different from the
+ others, as it would mean to sort by that column only. Given the column
+ names previously shown, these queries are also equivalent to those above:
+</p><pre class="programlisting">
+SELECT * FROM inventory_item c ORDER BY ROW(c.name, c.supplier_id, c.price);
+SELECT * FROM inventory_item c ORDER BY (c.name, c.supplier_id, c.price);
+</pre><p>
+ (The last case uses a row constructor with the key word <code class="literal">ROW</code>
+ omitted.)
+ </p><p>
+ Another special syntactical behavior associated with composite values is
+ that we can use <em class="firstterm">functional notation</em> for extracting a field
+ of a composite value. The simple way to explain this is that
+ the notations <code class="literal"><em class="replaceable"><code>field</code></em>(<em class="replaceable"><code>table</code></em>)</code>
+ and <code class="literal"><em class="replaceable"><code>table</code></em>.<em class="replaceable"><code>field</code></em></code>
+ are interchangeable. For example, these queries are equivalent:
+
+</p><pre class="programlisting">
+SELECT c.name FROM inventory_item c WHERE c.price &gt; 1000;
+SELECT name(c) FROM inventory_item c WHERE price(c) &gt; 1000;
+</pre><p>
+
+ Moreover, if we have a function that accepts a single argument of a
+ composite type, we can call it with either notation. These queries are
+ all equivalent:
+
+</p><pre class="programlisting">
+SELECT somefunc(c) FROM inventory_item c;
+SELECT somefunc(c.*) FROM inventory_item c;
+SELECT c.somefunc FROM inventory_item c;
+</pre><p>
+ </p><p>
+ This equivalence between functional notation and field notation
+ makes it possible to use functions on composite types to implement
+ <span class="quote">“<span class="quote">computed fields</span>”</span>.
+ <a id="id-1.5.7.24.9.10.2" class="indexterm"></a>
+ <a id="id-1.5.7.24.9.10.3" class="indexterm"></a>
+ An application using the last query above wouldn't need to be directly
+ aware that <code class="literal">somefunc</code> isn't a real column of the table.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Because of this behavior, it's unwise to give a function that takes a
+ single composite-type argument the same name as any of the fields of
+ that composite type. If there is ambiguity, the field-name
+ interpretation will be chosen if field-name syntax is used, while the
+ function will be chosen if function-call syntax is used. However,
+ <span class="productname">PostgreSQL</span> versions before 11 always chose the
+ field-name interpretation, unless the syntax of the call required it to
+ be a function call. One way to force the function interpretation in
+ older versions is to schema-qualify the function name, that is, write
+ <code class="literal"><em class="replaceable"><code>schema</code></em>.<em class="replaceable"><code>func</code></em>(<em class="replaceable"><code>compositevalue</code></em>)</code>.
+ </p></div></div><div class="sect2" id="ROWTYPES-IO-SYNTAX"><div class="titlepage"><div><div><h3 class="title">8.16.6. Composite Type Input and Output Syntax</h3></div></div></div><p>
+ The external text representation of a composite value consists of items that
+ are interpreted according to the I/O conversion rules for the individual
+ field types, plus decoration that indicates the composite structure.
+ The decoration consists of parentheses (<code class="literal">(</code> and <code class="literal">)</code>)
+ around the whole value, plus commas (<code class="literal">,</code>) between adjacent
+ items. Whitespace outside the parentheses is ignored, but within the
+ parentheses it is considered part of the field value, and might or might not be
+ significant depending on the input conversion rules for the field data type.
+ For example, in:
+</p><pre class="programlisting">
+'( 42)'
+</pre><p>
+ the whitespace will be ignored if the field type is integer, but not if
+ it is text.
+ </p><p>
+ As shown previously, when writing a composite value you can write double
+ quotes around any individual field value.
+ You <span class="emphasis"><em>must</em></span> do so if the field value would otherwise
+ confuse the composite-value parser. In particular, fields containing
+ parentheses, commas, double quotes, or backslashes must be double-quoted.
+ To put a double quote or backslash in a quoted composite field value,
+ precede it with a backslash. (Also, a pair of double quotes within a
+ double-quoted field value is taken to represent a double quote character,
+ analogously to the rules for single quotes in SQL literal strings.)
+ Alternatively, you can avoid quoting and use backslash-escaping to
+ protect all data characters
+ that would otherwise be taken as composite syntax.
+ </p><p>
+ A completely empty field value (no characters at all between the commas
+ or parentheses) represents a NULL. To write a value that is an empty
+ string rather than NULL, write <code class="literal">""</code>.
+ </p><p>
+ The composite output routine will put double quotes around field values
+ if they are empty strings or contain parentheses, commas,
+ double quotes, backslashes, or white space. (Doing so for white space
+ is not essential, but aids legibility.) Double quotes and backslashes
+ embedded in field values will be doubled.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Remember that what you write in an SQL command will first be interpreted
+ as a string literal, and then as a composite. This doubles the number of
+ backslashes you need (assuming escape string syntax is used).
+ For example, to insert a <code class="type">text</code> field
+ containing a double quote and a backslash in a composite
+ value, you'd need to write:
+</p><pre class="programlisting">
+INSERT ... VALUES ('("\"\\")');
+</pre><p>
+ The string-literal processor removes one level of backslashes, so that
+ what arrives at the composite-value parser looks like
+ <code class="literal">("\"\\")</code>. In turn, the string
+ fed to the <code class="type">text</code> data type's input routine
+ becomes <code class="literal">"\</code>. (If we were working
+ with a data type whose input routine also treated backslashes specially,
+ <code class="type">bytea</code> for example, we might need as many as eight backslashes
+ in the command to get one backslash into the stored composite field.)
+ Dollar quoting (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>) can be
+ used to avoid the need to double backslashes.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ The <code class="literal">ROW</code> constructor syntax is usually easier to work with
+ than the composite-literal syntax when writing composite values in SQL
+ commands.
+ In <code class="literal">ROW</code>, individual field values are written the same way
+ they would be written when not members of a composite.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="arrays.html" title="8.15. Arrays">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="datatype.html" title="Chapter 8. Data Types">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rangetypes.html" title="8.17. Range Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8.15. Arrays </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 8.17. Range Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rule-system.html b/doc/src/sgml/html/rule-system.html
new file mode 100644
index 0000000..923c2f1
--- /dev/null
+++ b/doc/src/sgml/html/rule-system.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>52.4. The PostgreSQL Rule System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="parser-stage.html" title="52.3. The Parser Stage" /><link rel="next" href="planner-optimizer.html" title="52.5. Planner/Optimizer" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">52.4. The <span class="productname">PostgreSQL</span> Rule System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="parser-stage.html" title="52.3. The Parser Stage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><th width="60%" align="center">Chapter 52. Overview of PostgreSQL Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="planner-optimizer.html" title="52.5. Planner/Optimizer">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULE-SYSTEM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">52.4. The <span class="productname">PostgreSQL</span> Rule System</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> supports a powerful
+ <em class="firstterm">rule system</em> for the specification
+ of <em class="firstterm">views</em> and ambiguous <em class="firstterm">view updates</em>.
+ Originally the <span class="productname">PostgreSQL</span>
+ rule system consisted of two implementations:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The first one worked using <em class="firstterm">row level</em> processing and was
+ implemented deep in the <em class="firstterm">executor</em>. The rule system was
+ called whenever an individual row had been accessed. This
+ implementation was removed in 1995 when the last official release
+ of the <span class="productname">Berkeley Postgres</span> project was
+ transformed into <span class="productname">Postgres95</span>.
+ </p></li><li class="listitem"><p>
+ The second implementation of the rule system is a technique
+ called <em class="firstterm">query rewriting</em>.
+ The <em class="firstterm">rewrite system</em> is a module
+ that exists between the <em class="firstterm">parser stage</em> and the
+ <em class="firstterm">planner/optimizer</em>. This technique is still implemented.
+ </p></li></ul></div><p>
+ </p><p>
+ The query rewriter is discussed in some detail in
+ <a class="xref" href="rules.html" title="Chapter 41. The Rule System">Chapter 41</a>, so there is no need to cover it here.
+ We will only point out that both the input and the output of the
+ rewriter are query trees, that is, there is no change in the
+ representation or level of semantic detail in the trees. Rewriting
+ can be thought of as a form of macro expansion.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="parser-stage.html" title="52.3. The Parser Stage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="overview.html" title="Chapter 52. Overview of PostgreSQL Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="planner-optimizer.html" title="52.5. Planner/Optimizer">Next</a></td></tr><tr><td width="40%" align="left" valign="top">52.3. The Parser Stage </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 52.5. Planner/Optimizer</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules-materializedviews.html b/doc/src/sgml/html/rules-materializedviews.html
new file mode 100644
index 0000000..0e670e1
--- /dev/null
+++ b/doc/src/sgml/html/rules-materializedviews.html
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.3. Materialized Views</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules-views.html" title="41.2. Views and the Rule System" /><link rel="next" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.3. Materialized Views</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules-views.html" title="41.2. Views and the Rule System">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-MATERIALIZEDVIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.3. Materialized Views</h2></div></div></div><a id="id-1.8.6.8.2" class="indexterm"></a><a id="id-1.8.6.8.3" class="indexterm"></a><a id="id-1.8.6.8.4" class="indexterm"></a><p>
+ Materialized views in <span class="productname">PostgreSQL</span> use the
+ rule system like views do, but persist the results in a table-like form.
+ The main differences between:
+
+</p><pre class="programlisting">
+CREATE MATERIALIZED VIEW mymatview AS SELECT * FROM mytab;
+</pre><p>
+
+ and:
+
+</p><pre class="programlisting">
+CREATE TABLE mymatview AS SELECT * FROM mytab;
+</pre><p>
+
+ are that the materialized view cannot subsequently be directly updated
+ and that the query used to create the materialized view is stored in
+ exactly the same way that a view's query is stored, so that fresh data
+ can be generated for the materialized view with:
+
+</p><pre class="programlisting">
+REFRESH MATERIALIZED VIEW mymatview;
+</pre><p>
+
+ The information about a materialized view in the
+ <span class="productname">PostgreSQL</span> system catalogs is exactly
+ the same as it is for a table or view. So for the parser, a
+ materialized view is a relation, just like a table or a view. When
+ a materialized view is referenced in a query, the data is returned
+ directly from the materialized view, like from a table; the rule is
+ only used for populating the materialized view.
+</p><p>
+ While access to the data stored in a materialized view is often much
+ faster than accessing the underlying tables directly or through a view,
+ the data is not always current; yet sometimes current data is not needed.
+ Consider a table which records sales:
+
+</p><pre class="programlisting">
+CREATE TABLE invoice (
+ invoice_no integer PRIMARY KEY,
+ seller_no integer, -- ID of salesperson
+ invoice_date date, -- date of sale
+ invoice_amt numeric(13,2) -- amount of sale
+);
+</pre><p>
+
+ If people want to be able to quickly graph historical sales data, they
+ might want to summarize, and they may not care about the incomplete data
+ for the current date:
+
+</p><pre class="programlisting">
+CREATE MATERIALIZED VIEW sales_summary AS
+ SELECT
+ seller_no,
+ invoice_date,
+ sum(invoice_amt)::numeric(13,2) as sales_amt
+ FROM invoice
+ WHERE invoice_date &lt; CURRENT_DATE
+ GROUP BY
+ seller_no,
+ invoice_date;
+
+CREATE UNIQUE INDEX sales_summary_seller
+ ON sales_summary (seller_no, invoice_date);
+</pre><p>
+
+ This materialized view might be useful for displaying a graph in the
+ dashboard created for salespeople. A job could be scheduled to update
+ the statistics each night using this SQL statement:
+
+</p><pre class="programlisting">
+REFRESH MATERIALIZED VIEW sales_summary;
+</pre><p>
+</p><p>
+ Another use for a materialized view is to allow faster access to data
+ brought across from a remote system through a foreign data wrapper.
+ A simple example using <code class="literal">file_fdw</code> is below, with timings,
+ but since this is using cache on the local system the performance
+ difference compared to access to a remote system would usually be greater
+ than shown here. Notice we are also exploiting the ability to put an
+ index on the materialized view, whereas <code class="literal">file_fdw</code> does
+ not support indexes; this advantage might not apply for other sorts of
+ foreign data access.
+</p><p>
+ Setup:
+
+</p><pre class="programlisting">
+CREATE EXTENSION file_fdw;
+CREATE SERVER local_file FOREIGN DATA WRAPPER file_fdw;
+CREATE FOREIGN TABLE words (word text NOT NULL)
+ SERVER local_file
+ OPTIONS (filename '/usr/share/dict/words');
+CREATE MATERIALIZED VIEW wrd AS SELECT * FROM words;
+CREATE UNIQUE INDEX wrd_word ON wrd (word);
+CREATE EXTENSION pg_trgm;
+CREATE INDEX wrd_trgm ON wrd USING gist (word gist_trgm_ops);
+VACUUM ANALYZE wrd;
+</pre><p>
+
+ Now let's spell-check a word. Using <code class="literal">file_fdw</code> directly:
+
+</p><pre class="programlisting">
+SELECT count(*) FROM words WHERE word = 'caterpiler';
+
+ count
+-------
+ 0
+(1 row)
+</pre><p>
+
+ With <code class="command">EXPLAIN ANALYZE</code>, we see:
+
+</p><pre class="programlisting">
+ Aggregate (cost=21763.99..21764.00 rows=1 width=0) (actual time=188.180..188.181 rows=1 loops=1)
+ -&gt; Foreign Scan on words (cost=0.00..21761.41 rows=1032 width=0) (actual time=188.177..188.177 rows=0 loops=1)
+ Filter: (word = 'caterpiler'::text)
+ Rows Removed by Filter: 479829
+ Foreign File: /usr/share/dict/words
+ Foreign File Size: 4953699
+ Planning time: 0.118 ms
+ Execution time: 188.273 ms
+</pre><p>
+
+ If the materialized view is used instead, the query is much faster:
+
+</p><pre class="programlisting">
+ Aggregate (cost=4.44..4.45 rows=1 width=0) (actual time=0.042..0.042 rows=1 loops=1)
+ -&gt; Index Only Scan using wrd_word on wrd (cost=0.42..4.44 rows=1 width=0) (actual time=0.039..0.039 rows=0 loops=1)
+ Index Cond: (word = 'caterpiler'::text)
+ Heap Fetches: 0
+ Planning time: 0.164 ms
+ Execution time: 0.117 ms
+</pre><p>
+
+ Either way, the word is spelled wrong, so let's look for what we might
+ have wanted. Again using <code class="literal">file_fdw</code> and
+ <code class="literal">pg_trgm</code>:
+
+</p><pre class="programlisting">
+SELECT word FROM words ORDER BY word &lt;-&gt; 'caterpiler' LIMIT 10;
+
+ word
+---------------
+ cater
+ caterpillar
+ Caterpillar
+ caterpillars
+ caterpillar's
+ Caterpillar's
+ caterer
+ caterer's
+ caters
+ catered
+(10 rows)
+</pre><p>
+
+</p><pre class="programlisting">
+ Limit (cost=11583.61..11583.64 rows=10 width=32) (actual time=1431.591..1431.594 rows=10 loops=1)
+ -&gt; Sort (cost=11583.61..11804.76 rows=88459 width=32) (actual time=1431.589..1431.591 rows=10 loops=1)
+ Sort Key: ((word &lt;-&gt; 'caterpiler'::text))
+ Sort Method: top-N heapsort Memory: 25kB
+ -&gt; Foreign Scan on words (cost=0.00..9672.05 rows=88459 width=32) (actual time=0.057..1286.455 rows=479829 loops=1)
+ Foreign File: /usr/share/dict/words
+ Foreign File Size: 4953699
+ Planning time: 0.128 ms
+ Execution time: 1431.679 ms
+</pre><p>
+
+ Using the materialized view:
+
+</p><pre class="programlisting">
+ Limit (cost=0.29..1.06 rows=10 width=10) (actual time=187.222..188.257 rows=10 loops=1)
+ -&gt; Index Scan using wrd_trgm on wrd (cost=0.29..37020.87 rows=479829 width=10) (actual time=187.219..188.252 rows=10 loops=1)
+ Order By: (word &lt;-&gt; 'caterpiler'::text)
+ Planning time: 0.196 ms
+ Execution time: 198.640 ms
+</pre><p>
+
+ If you can tolerate periodic update of the remote data to the local
+ database, the performance benefit can be substantial.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules-views.html" title="41.2. Views and the Rule System">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.2. Views and the Rule System </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.4. Rules on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules-privileges.html b/doc/src/sgml/html/rules-privileges.html
new file mode 100644
index 0000000..81ac971
--- /dev/null
+++ b/doc/src/sgml/html/rules-privileges.html
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.5. Rules and Privileges</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE" /><link rel="next" href="rules-status.html" title="41.6. Rules and Command Status" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.5. Rules and Privileges</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-status.html" title="41.6. Rules and Command Status">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-PRIVILEGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.5. Rules and Privileges</h2></div></div></div><a id="id-1.8.6.10.2" class="indexterm"></a><a id="id-1.8.6.10.3" class="indexterm"></a><p>
+ Due to rewriting of queries by the <span class="productname">PostgreSQL</span>
+ rule system, other tables/views than those used in the original
+ query get accessed. When update rules are used, this can include write access
+ to tables.
+</p><p>
+ Rewrite rules don't have a separate owner. The owner of
+ a relation (table or view) is automatically the owner of the
+ rewrite rules that are defined for it.
+ The <span class="productname">PostgreSQL</span> rule system changes the
+ behavior of the default access control system. With the exception of
+ <code class="literal">SELECT</code> rules associated with security invoker views
+ (see <a class="link" href="sql-createview.html" title="CREATE VIEW"><code class="command">CREATE VIEW</code></a>),
+ all relations that are used due to rules get checked against the
+ privileges of the rule owner, not the user invoking the rule.
+ This means that, except for security invoker views, users only need the
+ required privileges for the tables/views that are explicitly named in
+ their queries.
+</p><p>
+ For example: A user has a list of phone numbers where some of
+ them are private, the others are of interest for the assistant of the office.
+ The user can construct the following:
+
+</p><pre class="programlisting">
+CREATE TABLE phone_data (person text, phone text, private boolean);
+CREATE VIEW phone_number AS
+ SELECT person, CASE WHEN NOT private THEN phone END AS phone
+ FROM phone_data;
+GRANT SELECT ON phone_number TO assistant;
+</pre><p>
+
+ Nobody except that user (and the database superusers) can access the
+ <code class="literal">phone_data</code> table. But because of the <code class="command">GRANT</code>,
+ the assistant can run a <code class="command">SELECT</code> on the
+ <code class="literal">phone_number</code> view. The rule system will rewrite the
+ <code class="command">SELECT</code> from <code class="literal">phone_number</code> into a
+ <code class="command">SELECT</code> from <code class="literal">phone_data</code>.
+ Since the user is the owner of
+ <code class="literal">phone_number</code> and therefore the owner of the rule, the
+ read access to <code class="literal">phone_data</code> is now checked against the user's
+ privileges and the query is permitted. The check for accessing
+ <code class="literal">phone_number</code> is also performed, but this is done
+ against the invoking user, so nobody but the user and the
+ assistant can use it.
+</p><p>
+ The privileges are checked rule by rule. So the assistant is for now the
+ only one who can see the public phone numbers. But the assistant can set up
+ another view and grant access to that to the public. Then, anyone
+ can see the <code class="literal">phone_number</code> data through the assistant's view.
+ What the assistant cannot do is to create a view that directly
+ accesses <code class="literal">phone_data</code>. (Actually the assistant can, but it will not work since
+ every access will be denied during the permission checks.)
+ And as soon as the user notices that the assistant opened
+ their <code class="literal">phone_number</code> view, the user can revoke the assistant's access. Immediately, any
+ access to the assistant's view would fail.
+</p><p>
+ One might think that this rule-by-rule checking is a security
+ hole, but in fact it isn't. But if it did not work this way, the assistant
+ could set up a table with the same columns as <code class="literal">phone_number</code> and
+ copy the data to there once per day. Then it's the assistant's own data and
+ the assistant can grant access to everyone they want. A
+ <code class="command">GRANT</code> command means, <span class="quote">“<span class="quote">I trust you</span>”</span>.
+ If someone you trust does the thing above, it's time to
+ think it over and then use <code class="command">REVOKE</code>.
+</p><p>
+ Note that while views can be used to hide the contents of certain
+ columns using the technique shown above, they cannot be used to reliably
+ conceal the data in unseen rows unless the
+ <code class="literal">security_barrier</code> flag has been set. For example,
+ the following view is insecure:
+</p><pre class="programlisting">
+CREATE VIEW phone_number AS
+ SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
+</pre><p>
+ This view might seem secure, since the rule system will rewrite any
+ <code class="command">SELECT</code> from <code class="literal">phone_number</code> into a
+ <code class="command">SELECT</code> from <code class="literal">phone_data</code> and add the
+ qualification that only entries where <code class="literal">phone</code> does not begin
+ with 412 are wanted. But if the user can create their own functions,
+ it is not difficult to convince the planner to execute the user-defined
+ function prior to the <code class="function">NOT LIKE</code> expression.
+ For example:
+</p><pre class="programlisting">
+CREATE FUNCTION tricky(text, text) RETURNS bool AS $$
+BEGIN
+ RAISE NOTICE '% =&gt; %', $1, $2;
+ RETURN true;
+END;
+$$ LANGUAGE plpgsql COST 0.0000000000000000000001;
+
+SELECT * FROM phone_number WHERE tricky(person, phone);
+</pre><p>
+ Every person and phone number in the <code class="literal">phone_data</code> table will be
+ printed as a <code class="literal">NOTICE</code>, because the planner will choose to
+ execute the inexpensive <code class="function">tricky</code> function before the
+ more expensive <code class="function">NOT LIKE</code>. Even if the user is
+ prevented from defining new functions, built-in functions can be used in
+ similar attacks. (For example, most casting functions include their
+ input values in the error messages they produce.)
+</p><p>
+ Similar considerations apply to update rules. In the examples of
+ the previous section, the owner of the tables in the example
+ database could grant the privileges <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, and <code class="literal">DELETE</code> on
+ the <code class="literal">shoelace</code> view to someone else, but only
+ <code class="literal">SELECT</code> on <code class="literal">shoelace_log</code>. The rule action to
+ write log entries will still be executed successfully, and that
+ other user could see the log entries. But they could not create fake
+ entries, nor could they manipulate or remove existing ones. In this
+ case, there is no possibility of subverting the rules by convincing
+ the planner to alter the order of operations, because the only rule
+ which references <code class="literal">shoelace_log</code> is an unqualified
+ <code class="literal">INSERT</code>. This might not be true in more complex scenarios.
+</p><p>
+ When it is necessary for a view to provide row-level security, the
+ <code class="literal">security_barrier</code> attribute should be applied to
+ the view. This prevents maliciously-chosen functions and operators from
+ being passed values from rows until after the view has done its work. For
+ example, if the view shown above had been created like this, it would
+ be secure:
+</p><pre class="programlisting">
+CREATE VIEW phone_number WITH (security_barrier) AS
+ SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
+</pre><p>
+ Views created with the <code class="literal">security_barrier</code> may perform
+ far worse than views created without this option. In general, there is
+ no way to avoid this: the fastest possible plan must be rejected
+ if it may compromise security. For this reason, this option is not
+ enabled by default.
+</p><p>
+ The query planner has more flexibility when dealing with functions that
+ have no side effects. Such functions are referred to as <code class="literal">LEAKPROOF</code>, and
+ include many simple, commonly used operators, such as many equality
+ operators. The query planner can safely allow such functions to be evaluated
+ at any point in the query execution process, since invoking them on rows
+ invisible to the user will not leak any information about the unseen rows.
+ Further, functions which do not take arguments or which are not passed any
+ arguments from the security barrier view do not have to be marked as
+ <code class="literal">LEAKPROOF</code> to be pushed down, as they never receive data
+ from the view. In contrast, a function that might throw an error depending
+ on the values received as arguments (such as one that throws an error in the
+ event of overflow or division by zero) is not leak-proof, and could provide
+ significant information about the unseen rows if applied before the security
+ view's row filters.
+</p><p>
+ It is important to understand that even a view created with the
+ <code class="literal">security_barrier</code> option is intended to be secure only
+ in the limited sense that the contents of the invisible tuples will not be
+ passed to possibly-insecure functions. The user may well have other means
+ of making inferences about the unseen data; for example, they can see the
+ query plan using <code class="command">EXPLAIN</code>, or measure the run time of
+ queries against the view. A malicious attacker might be able to infer
+ something about the amount of unseen data, or even gain some information
+ about the data distribution or most common values (since these things may
+ affect the run time of the plan; or even, since they are also reflected in
+ the optimizer statistics, the choice of plan). If these types of "covert
+ channel" attacks are of concern, it is probably unwise to grant any access
+ to the data at all.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-status.html" title="41.6. Rules and Command Status">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.4. Rules on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.6. Rules and Command Status</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules-status.html b/doc/src/sgml/html/rules-status.html
new file mode 100644
index 0000000..eb895b2
--- /dev/null
+++ b/doc/src/sgml/html/rules-status.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.6. Rules and Command Status</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules-privileges.html" title="41.5. Rules and Privileges" /><link rel="next" href="rules-triggers.html" title="41.7. Rules Versus Triggers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.6. Rules and Command Status</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules-privileges.html" title="41.5. Rules and Privileges">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-triggers.html" title="41.7. Rules Versus Triggers">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-STATUS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.6. Rules and Command Status</h2></div></div></div><p>
+ The <span class="productname">PostgreSQL</span> server returns a command
+ status string, such as <code class="literal">INSERT 149592 1</code>, for each
+ command it receives. This is simple enough when there are no rules
+ involved, but what happens when the query is rewritten by rules?
+</p><p>
+ Rules affect the command status as follows:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ If there is no unconditional <code class="literal">INSTEAD</code> rule for the query, then
+ the originally given query will be executed, and its command
+ status will be returned as usual. (But note that if there were
+ any conditional <code class="literal">INSTEAD</code> rules, the negation of their qualifications
+ will have been added to the original query. This might reduce the
+ number of rows it processes, and if so the reported status will
+ be affected.)
+ </p></li><li class="listitem"><p>
+ If there is any unconditional <code class="literal">INSTEAD</code> rule for the query, then
+ the original query will not be executed at all. In this case,
+ the server will return the command status for the last query
+ that was inserted by an <code class="literal">INSTEAD</code> rule (conditional or
+ unconditional) and is of the same command type
+ (<code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code>) as the original query. If no query
+ meeting those requirements is added by any rule, then the
+ returned command status shows the original query type and
+ zeroes for the row-count and OID fields.
+ </p></li></ul></div><p>
+</p><p>
+ The programmer can ensure that any desired <code class="literal">INSTEAD</code> rule is the one
+ that sets the command status in the second case, by giving it the
+ alphabetically last rule name among the active rules, so that it
+ gets applied last.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules-privileges.html" title="41.5. Rules and Privileges">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-triggers.html" title="41.7. Rules Versus Triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.5. Rules and Privileges </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.7. Rules Versus Triggers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules-triggers.html b/doc/src/sgml/html/rules-triggers.html
new file mode 100644
index 0000000..10e1909
--- /dev/null
+++ b/doc/src/sgml/html/rules-triggers.html
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.7. Rules Versus Triggers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules-status.html" title="41.6. Rules and Command Status" /><link rel="next" href="xplang.html" title="Chapter 42. Procedural Languages" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.7. Rules Versus Triggers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules-status.html" title="41.6. Rules and Command Status">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xplang.html" title="Chapter 42. Procedural Languages">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-TRIGGERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.7. Rules Versus Triggers</h2></div></div></div><a id="id-1.8.6.12.2" class="indexterm"></a><a id="id-1.8.6.12.3" class="indexterm"></a><p>
+ Many things that can be done using triggers can also be
+ implemented using the <span class="productname">PostgreSQL</span>
+ rule system. One of the things that cannot be implemented by
+ rules are some kinds of constraints, especially foreign keys. It is possible
+ to place a qualified rule that rewrites a command to <code class="literal">NOTHING</code>
+ if the value of a column does not appear in another table.
+ But then the data is silently thrown away and that's
+ not a good idea. If checks for valid values are required,
+ and in the case of an invalid value an error message should
+ be generated, it must be done by a trigger.
+</p><p>
+ In this chapter, we focused on using rules to update views. All of
+ the update rule examples in this chapter can also be implemented
+ using <code class="literal">INSTEAD OF</code> triggers on the views. Writing such
+ triggers is often easier than writing rules, particularly if complex
+ logic is required to perform the update.
+</p><p>
+ For the things that can be implemented by both, which is best
+ depends on the usage of the database.
+ A trigger is fired once for each affected row. A rule modifies
+ the query or generates an additional query. So if many
+ rows are affected in one statement, a rule issuing one extra
+ command is likely to be faster than a trigger that is
+ called for every single row and must re-determine what to do
+ many times. However, the trigger approach is conceptually far
+ simpler than the rule approach, and is easier for novices to get right.
+</p><p>
+ Here we show an example of how the choice of rules versus triggers
+ plays out in one situation. There are two tables:
+
+</p><pre class="programlisting">
+CREATE TABLE computer (
+ hostname text, -- indexed
+ manufacturer text -- indexed
+);
+
+CREATE TABLE software (
+ software text, -- indexed
+ hostname text -- indexed
+);
+</pre><p>
+
+ Both tables have many thousands of rows and the indexes on
+ <code class="structfield">hostname</code> are unique. The rule or trigger should
+ implement a constraint that deletes rows from <code class="literal">software</code>
+ that reference a deleted computer. The trigger would use this command:
+
+</p><pre class="programlisting">
+DELETE FROM software WHERE hostname = $1;
+</pre><p>
+
+ Since the trigger is called for each individual row deleted from
+ <code class="literal">computer</code>, it can prepare and save the plan for this
+ command and pass the <code class="structfield">hostname</code> value in the
+ parameter. The rule would be written as:
+
+</p><pre class="programlisting">
+CREATE RULE computer_del AS ON DELETE TO computer
+ DO DELETE FROM software WHERE hostname = OLD.hostname;
+</pre><p>
+ </p><p>
+ Now we look at different types of deletes. In the case of a:
+
+</p><pre class="programlisting">
+DELETE FROM computer WHERE hostname = 'mypc.local.net';
+</pre><p>
+
+ the table <code class="literal">computer</code> is scanned by index (fast), and the
+ command issued by the trigger would also use an index scan (also fast).
+ The extra command from the rule would be:
+
+</p><pre class="programlisting">
+DELETE FROM software WHERE computer.hostname = 'mypc.local.net'
+ AND software.hostname = computer.hostname;
+</pre><p>
+
+ Since there are appropriate indexes set up, the planner
+ will create a plan of
+
+</p><pre class="literallayout">
+Nestloop
+ -&gt; Index Scan using comp_hostidx on computer
+ -&gt; Index Scan using soft_hostidx on software
+</pre><p>
+
+ So there would be not that much difference in speed between
+ the trigger and the rule implementation.
+ </p><p>
+ With the next delete we want to get rid of all the 2000 computers
+ where the <code class="structfield">hostname</code> starts with
+ <code class="literal">old</code>. There are two possible commands to do that. One
+ is:
+
+</p><pre class="programlisting">
+DELETE FROM computer WHERE hostname &gt;= 'old'
+ AND hostname &lt; 'ole'
+</pre><p>
+
+ The command added by the rule will be:
+
+</p><pre class="programlisting">
+DELETE FROM software WHERE computer.hostname &gt;= 'old' AND computer.hostname &lt; 'ole'
+ AND software.hostname = computer.hostname;
+</pre><p>
+
+ with the plan
+
+</p><pre class="literallayout">
+Hash Join
+ -&gt; Seq Scan on software
+ -&gt; Hash
+ -&gt; Index Scan using comp_hostidx on computer
+</pre><p>
+
+ The other possible command is:
+
+</p><pre class="programlisting">
+DELETE FROM computer WHERE hostname ~ '^old';
+</pre><p>
+
+ which results in the following executing plan for the command
+ added by the rule:
+
+</p><pre class="literallayout">
+Nestloop
+ -&gt; Index Scan using comp_hostidx on computer
+ -&gt; Index Scan using soft_hostidx on software
+</pre><p>
+
+ This shows, that the planner does not realize that the
+ qualification for <code class="structfield">hostname</code> in
+ <code class="literal">computer</code> could also be used for an index scan on
+ <code class="literal">software</code> when there are multiple qualification
+ expressions combined with <code class="literal">AND</code>, which is what it does
+ in the regular-expression version of the command. The trigger will
+ get invoked once for each of the 2000 old computers that have to be
+ deleted, and that will result in one index scan over
+ <code class="literal">computer</code> and 2000 index scans over
+ <code class="literal">software</code>. The rule implementation will do it with two
+ commands that use indexes. And it depends on the overall size of
+ the table <code class="literal">software</code> whether the rule will still be faster in the
+ sequential scan situation. 2000 command executions from the trigger over the SPI
+ manager take some time, even if all the index blocks will soon be in the cache.
+</p><p>
+ The last command we look at is:
+
+</p><pre class="programlisting">
+DELETE FROM computer WHERE manufacturer = 'bim';
+</pre><p>
+
+ Again this could result in many rows to be deleted from
+ <code class="literal">computer</code>. So the trigger will again run many commands
+ through the executor. The command generated by the rule will be:
+
+</p><pre class="programlisting">
+DELETE FROM software WHERE computer.manufacturer = 'bim'
+ AND software.hostname = computer.hostname;
+</pre><p>
+
+ The plan for that command will again be the nested loop over two
+ index scans, only using a different index on <code class="literal">computer</code>:
+
+</p><pre class="programlisting">
+Nestloop
+ -&gt; Index Scan using comp_manufidx on computer
+ -&gt; Index Scan using soft_hostidx on software
+</pre><p>
+
+ In any of these cases, the extra commands from the rule system
+ will be more or less independent from the number of affected rows
+ in a command.
+</p><p>
+ The summary is, rules will only be significantly slower than
+ triggers if their actions result in large and badly qualified
+ joins, a situation where the planner fails.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules-status.html" title="41.6. Rules and Command Status">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xplang.html" title="Chapter 42. Procedural Languages">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.6. Rules and Command Status </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 42. Procedural Languages</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules-update.html b/doc/src/sgml/html/rules-update.html
new file mode 100644
index 0000000..8b6ef12
--- /dev/null
+++ b/doc/src/sgml/html/rules-update.html
@@ -0,0 +1,750 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.4. Rules on INSERT, UPDATE, and DELETE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules-materializedviews.html" title="41.3. Materialized Views" /><link rel="next" href="rules-privileges.html" title="41.5. Rules and Privileges" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.4. Rules on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules-materializedviews.html" title="41.3. Materialized Views">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-privileges.html" title="41.5. Rules and Privileges">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-UPDATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.4. Rules on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="rules-update.html#id-1.8.6.9.7">41.4.1. How Update Rules Work</a></span></dt><dt><span class="sect2"><a href="rules-update.html#RULES-UPDATE-VIEWS">41.4.2. Cooperation with Views</a></span></dt></dl></div><a id="id-1.8.6.9.2" class="indexterm"></a><a id="id-1.8.6.9.3" class="indexterm"></a><a id="id-1.8.6.9.4" class="indexterm"></a><p>
+ Rules that are defined on <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ and <code class="command">DELETE</code> are significantly different from the view rules
+ described in the previous section. First, their <code class="command">CREATE
+ RULE</code> command allows more:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ They are allowed to have no action.
+ </p></li><li class="listitem"><p>
+ They can have multiple actions.
+ </p></li><li class="listitem"><p>
+ They can be <code class="literal">INSTEAD</code> or <code class="literal">ALSO</code> (the default).
+ </p></li><li class="listitem"><p>
+ The pseudorelations <code class="literal">NEW</code> and <code class="literal">OLD</code> become useful.
+ </p></li><li class="listitem"><p>
+ They can have rule qualifications.
+ </p></li></ul></div><p>
+
+ Second, they don't modify the query tree in place. Instead they
+ create zero or more new query trees and can throw away the
+ original one.
+</p><div class="caution"><h3 class="title">Caution</h3><p>
+ In many cases, tasks that could be performed by rules
+ on <code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code> are better done
+ with triggers. Triggers are notationally a bit more complicated, but their
+ semantics are much simpler to understand. Rules tend to have surprising
+ results when the original query contains volatile functions: volatile
+ functions may get executed more times than expected in the process of
+ carrying out the rules.
+ </p><p>
+ Also, there are some cases that are not supported by these types of rules at
+ all, notably including <code class="literal">WITH</code> clauses in the original query and
+ multiple-assignment sub-<code class="literal">SELECT</code>s in the <code class="literal">SET</code> list
+ of <code class="command">UPDATE</code> queries. This is because copying these constructs
+ into a rule query would result in multiple evaluations of the sub-query,
+ contrary to the express intent of the query's author.
+ </p></div><div class="sect2" id="id-1.8.6.9.7"><div class="titlepage"><div><div><h3 class="title">41.4.1. How Update Rules Work</h3></div></div></div><p>
+ Keep the syntax:
+
+</p><pre class="programlisting">
+CREATE [ OR REPLACE ] RULE <em class="replaceable"><code>name</code></em> AS ON <em class="replaceable"><code>event</code></em>
+ TO <em class="replaceable"><code>table</code></em> [ WHERE <em class="replaceable"><code>condition</code></em> ]
+ DO [ ALSO | INSTEAD ] { NOTHING | <em class="replaceable"><code>command</code></em> | ( <em class="replaceable"><code>command</code></em> ; <em class="replaceable"><code>command</code></em> ... ) }
+</pre><p>
+
+ in mind.
+ In the following, <em class="firstterm">update rules</em> means rules that are defined
+ on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or <code class="command">DELETE</code>.
+</p><p>
+ Update rules get applied by the rule system when the result
+ relation and the command type of a query tree are equal to the
+ object and event given in the <code class="command">CREATE RULE</code> command.
+ For update rules, the rule system creates a list of query trees.
+ Initially the query-tree list is empty.
+ There can be zero (<code class="literal">NOTHING</code> key word), one, or multiple actions.
+ To simplify, we will look at a rule with one action. This rule
+ can have a qualification or not and it can be <code class="literal">INSTEAD</code> or
+ <code class="literal">ALSO</code> (the default).
+</p><p>
+ What is a rule qualification? It is a restriction that tells
+ when the actions of the rule should be done and when not. This
+ qualification can only reference the pseudorelations <code class="literal">NEW</code> and/or <code class="literal">OLD</code>,
+ which basically represent the relation that was given as object (but with a
+ special meaning).
+</p><p>
+ So we have three cases that produce the following query trees for
+ a one-action rule.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">No qualification, with either <code class="literal">ALSO</code> or
+ <code class="literal">INSTEAD</code></span></dt><dd><p>
+ the query tree from the rule action with the original query
+ tree's qualification added
+ </p></dd><dt><span class="term">Qualification given and <code class="literal">ALSO</code></span></dt><dd><p>
+ the query tree from the rule action with the rule
+ qualification and the original query tree's qualification
+ added
+ </p></dd><dt><span class="term">Qualification given and <code class="literal">INSTEAD</code></span></dt><dd><p>
+ the query tree from the rule action with the rule
+ qualification and the original query tree's qualification; and
+ the original query tree with the negated rule qualification
+ added
+ </p></dd></dl></div><p>
+
+ Finally, if the rule is <code class="literal">ALSO</code>, the unchanged original query tree is
+ added to the list. Since only qualified <code class="literal">INSTEAD</code> rules already add the
+ original query tree, we end up with either one or two output query trees
+ for a rule with one action.
+</p><p>
+ For <code class="literal">ON INSERT</code> rules, the original query (if not suppressed by <code class="literal">INSTEAD</code>)
+ is done before any actions added by rules. This allows the actions to
+ see the inserted row(s). But for <code class="literal">ON UPDATE</code> and <code class="literal">ON
+ DELETE</code> rules, the original query is done after the actions added by rules.
+ This ensures that the actions can see the to-be-updated or to-be-deleted
+ rows; otherwise, the actions might do nothing because they find no rows
+ matching their qualifications.
+</p><p>
+ The query trees generated from rule actions are thrown into the
+ rewrite system again, and maybe more rules get applied resulting
+ in additional or fewer query trees.
+ So a rule's actions must have either a different
+ command type or a different result relation than the rule itself is
+ on, otherwise this recursive process will end up in an infinite loop.
+ (Recursive expansion of a rule will be detected and reported as an
+ error.)
+</p><p>
+ The query trees found in the actions of the
+ <code class="structname">pg_rewrite</code> system catalog are only
+ templates. Since they can reference the range-table entries for
+ <code class="literal">NEW</code> and <code class="literal">OLD</code>, some substitutions have to be made before they can be
+ used. For any reference to <code class="literal">NEW</code>, the target list of the original
+ query is searched for a corresponding entry. If found, that
+ entry's expression replaces the reference. Otherwise, <code class="literal">NEW</code> means the
+ same as <code class="literal">OLD</code> (for an <code class="command">UPDATE</code>) or is replaced by
+ a null value (for an <code class="command">INSERT</code>). Any reference to <code class="literal">OLD</code> is
+ replaced by a reference to the range-table entry that is the
+ result relation.
+</p><p>
+ After the system is done applying update rules, it applies view rules to the
+ produced query tree(s). Views cannot insert new update actions so
+ there is no need to apply update rules to the output of view rewriting.
+</p><div class="sect3" id="id-1.8.6.9.7.10"><div class="titlepage"><div><div><h4 class="title">41.4.1.1. A First Rule Step by Step</h4></div></div></div><p>
+ Say we want to trace changes to the <code class="literal">sl_avail</code> column in the
+ <code class="literal">shoelace_data</code> relation. So we set up a log table
+ and a rule that conditionally writes a log entry when an
+ <code class="command">UPDATE</code> is performed on
+ <code class="literal">shoelace_data</code>.
+
+</p><pre class="programlisting">
+CREATE TABLE shoelace_log (
+ sl_name text, -- shoelace changed
+ sl_avail integer, -- new available value
+ log_who text, -- who did it
+ log_when timestamp -- when
+);
+
+CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data
+ WHERE NEW.sl_avail &lt;&gt; OLD.sl_avail
+ DO INSERT INTO shoelace_log VALUES (
+ NEW.sl_name,
+ NEW.sl_avail,
+ current_user,
+ current_timestamp
+ );
+</pre><p>
+</p><p>
+ Now someone does:
+
+</p><pre class="programlisting">
+UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';
+</pre><p>
+
+ and we look at the log table:
+
+</p><pre class="programlisting">
+SELECT * FROM shoelace_log;
+
+ sl_name | sl_avail | log_who | log_when
+---------+----------+---------+----------------------------------
+ sl7 | 6 | Al | Tue Oct 20 16:14:45 1998 MET DST
+(1 row)
+</pre><p>
+ </p><p>
+ That's what we expected. What happened in the background is the following.
+ The parser created the query tree:
+
+</p><pre class="programlisting">
+UPDATE shoelace_data SET sl_avail = 6
+ FROM shoelace_data shoelace_data
+ WHERE shoelace_data.sl_name = 'sl7';
+</pre><p>
+
+ There is a rule <code class="literal">log_shoelace</code> that is <code class="literal">ON UPDATE</code> with the rule
+ qualification expression:
+
+</p><pre class="programlisting">
+NEW.sl_avail &lt;&gt; OLD.sl_avail
+</pre><p>
+
+ and the action:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old;
+</pre><p>
+
+ (This looks a little strange since you cannot normally write
+ <code class="literal">INSERT ... VALUES ... FROM</code>. The <code class="literal">FROM</code>
+ clause here is just to indicate that there are range-table entries
+ in the query tree for <code class="literal">new</code> and <code class="literal">old</code>.
+ These are needed so that they can be referenced by variables in
+ the <code class="command">INSERT</code> command's query tree.)
+</p><p>
+ The rule is a qualified <code class="literal">ALSO</code> rule, so the rule system
+ has to return two query trees: the modified rule action and the original
+ query tree. In step 1, the range table of the original query is
+ incorporated into the rule's action query tree. This results in:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ <span class="emphasis"><strong>shoelace_data shoelace_data</strong></span>;
+</pre><p>
+
+ In step 2, the rule qualification is added to it, so the result set
+ is restricted to rows where <code class="literal">sl_avail</code> changes:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ <span class="emphasis"><strong>WHERE new.sl_avail &lt;&gt; old.sl_avail</strong></span>;
+</pre><p>
+
+ (This looks even stranger, since <code class="literal">INSERT ... VALUES</code> doesn't have
+ a <code class="literal">WHERE</code> clause either, but the planner and executor will have no
+ difficulty with it. They need to support this same functionality
+ anyway for <code class="literal">INSERT ... SELECT</code>.)
+ </p><p>
+ In step 3, the original query tree's qualification is added,
+ restricting the result set further to only the rows that would have been touched
+ by the original query:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ WHERE new.sl_avail &lt;&gt; old.sl_avail
+ <span class="emphasis"><strong>AND shoelace_data.sl_name = 'sl7'</strong></span>;
+</pre><p>
+ </p><p>
+ Step 4 replaces references to <code class="literal">NEW</code> by the target list entries from the
+ original query tree or by the matching variable references
+ from the result relation:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ <span class="emphasis"><strong>shoelace_data.sl_name</strong></span>, <span class="emphasis"><strong>6</strong></span>,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ WHERE <span class="emphasis"><strong>6</strong></span> &lt;&gt; old.sl_avail
+ AND shoelace_data.sl_name = 'sl7';
+</pre><p>
+
+ </p><p>
+ Step 5 changes <code class="literal">OLD</code> references into result relation references:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ shoelace_data.sl_name, 6,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ WHERE 6 &lt;&gt; <span class="emphasis"><strong>shoelace_data.sl_avail</strong></span>
+ AND shoelace_data.sl_name = 'sl7';
+</pre><p>
+ </p><p>
+ That's it. Since the rule is <code class="literal">ALSO</code>, we also output the
+ original query tree. In short, the output from the rule system
+ is a list of two query trees that correspond to these statements:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ shoelace_data.sl_name, 6,
+ current_user, current_timestamp )
+ FROM shoelace_data
+ WHERE 6 &lt;&gt; shoelace_data.sl_avail
+ AND shoelace_data.sl_name = 'sl7';
+
+UPDATE shoelace_data SET sl_avail = 6
+ WHERE sl_name = 'sl7';
+</pre><p>
+
+ These are executed in this order, and that is exactly what
+ the rule was meant to do.
+ </p><p>
+ The substitutions and the added qualifications
+ ensure that, if the original query would be, say:
+
+</p><pre class="programlisting">
+UPDATE shoelace_data SET sl_color = 'green'
+ WHERE sl_name = 'sl7';
+</pre><p>
+
+ no log entry would get written. In that case, the original query
+ tree does not contain a target list entry for
+ <code class="literal">sl_avail</code>, so <code class="literal">NEW.sl_avail</code> will get
+ replaced by <code class="literal">shoelace_data.sl_avail</code>. Thus, the extra
+ command generated by the rule is:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log VALUES (
+ shoelace_data.sl_name, <span class="emphasis"><strong>shoelace_data.sl_avail</strong></span>,
+ current_user, current_timestamp )
+ FROM shoelace_data
+ WHERE <span class="emphasis"><strong>shoelace_data.sl_avail</strong></span> &lt;&gt; shoelace_data.sl_avail
+ AND shoelace_data.sl_name = 'sl7';
+</pre><p>
+
+ and that qualification will never be true.
+ </p><p>
+ It will also work if the original query modifies multiple rows. So
+ if someone issued the command:
+
+</p><pre class="programlisting">
+UPDATE shoelace_data SET sl_avail = 0
+ WHERE sl_color = 'black';
+</pre><p>
+
+ four rows in fact get updated (<code class="literal">sl1</code>, <code class="literal">sl2</code>, <code class="literal">sl3</code>, and <code class="literal">sl4</code>).
+ But <code class="literal">sl3</code> already has <code class="literal">sl_avail = 0</code>. In this case, the original
+ query trees qualification is different and that results
+ in the extra query tree:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log
+SELECT shoelace_data.sl_name, 0,
+ current_user, current_timestamp
+ FROM shoelace_data
+ WHERE 0 &lt;&gt; shoelace_data.sl_avail
+ AND <span class="emphasis"><strong>shoelace_data.sl_color = 'black'</strong></span>;
+</pre><p>
+
+ being generated by the rule. This query tree will surely insert
+ three new log entries. And that's absolutely correct.
+</p><p>
+ Here we can see why it is important that the original query tree
+ is executed last. If the <code class="command">UPDATE</code> had been
+ executed first, all the rows would have already been set to zero, so the
+ logging <code class="command">INSERT</code> would not find any row where
+ <code class="literal">0 &lt;&gt; shoelace_data.sl_avail</code>.
+</p></div></div><div class="sect2" id="RULES-UPDATE-VIEWS"><div class="titlepage"><div><div><h3 class="title">41.4.2. Cooperation with Views</h3></div></div></div><a id="id-1.8.6.9.8.2" class="indexterm"></a><p>
+ A simple way to protect view relations from the mentioned
+ possibility that someone can try to run <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, or <code class="command">DELETE</code> on them is
+ to let those query trees get thrown away. So we could create the rules:
+
+</p><pre class="programlisting">
+CREATE RULE shoe_ins_protect AS ON INSERT TO shoe
+ DO INSTEAD NOTHING;
+CREATE RULE shoe_upd_protect AS ON UPDATE TO shoe
+ DO INSTEAD NOTHING;
+CREATE RULE shoe_del_protect AS ON DELETE TO shoe
+ DO INSTEAD NOTHING;
+</pre><p>
+
+ If someone now tries to do any of these operations on the view
+ relation <code class="literal">shoe</code>, the rule system will
+ apply these rules. Since the rules have
+ no actions and are <code class="literal">INSTEAD</code>, the resulting list of
+ query trees will be empty and the whole query will become
+ nothing because there is nothing left to be optimized or
+ executed after the rule system is done with it.
+</p><p>
+ A more sophisticated way to use the rule system is to
+ create rules that rewrite the query tree into one that
+ does the right operation on the real tables. To do that
+ on the <code class="literal">shoelace</code> view, we create
+ the following rules:
+
+</p><pre class="programlisting">
+CREATE RULE shoelace_ins AS ON INSERT TO shoelace
+ DO INSTEAD
+ INSERT INTO shoelace_data VALUES (
+ NEW.sl_name,
+ NEW.sl_avail,
+ NEW.sl_color,
+ NEW.sl_len,
+ NEW.sl_unit
+ );
+
+CREATE RULE shoelace_upd AS ON UPDATE TO shoelace
+ DO INSTEAD
+ UPDATE shoelace_data
+ SET sl_name = NEW.sl_name,
+ sl_avail = NEW.sl_avail,
+ sl_color = NEW.sl_color,
+ sl_len = NEW.sl_len,
+ sl_unit = NEW.sl_unit
+ WHERE sl_name = OLD.sl_name;
+
+CREATE RULE shoelace_del AS ON DELETE TO shoelace
+ DO INSTEAD
+ DELETE FROM shoelace_data
+ WHERE sl_name = OLD.sl_name;
+</pre><p>
+ </p><p>
+ If you want to support <code class="literal">RETURNING</code> queries on the view,
+ you need to make the rules include <code class="literal">RETURNING</code> clauses that
+ compute the view rows. This is usually pretty trivial for views on a
+ single table, but it's a bit tedious for join views such as
+ <code class="literal">shoelace</code>. An example for the insert case is:
+
+</p><pre class="programlisting">
+CREATE RULE shoelace_ins AS ON INSERT TO shoelace
+ DO INSTEAD
+ INSERT INTO shoelace_data VALUES (
+ NEW.sl_name,
+ NEW.sl_avail,
+ NEW.sl_color,
+ NEW.sl_len,
+ NEW.sl_unit
+ )
+ RETURNING
+ shoelace_data.*,
+ (SELECT shoelace_data.sl_len * u.un_fact
+ FROM unit u WHERE shoelace_data.sl_unit = u.un_name);
+</pre><p>
+
+ Note that this one rule supports both <code class="command">INSERT</code> and
+ <code class="command">INSERT RETURNING</code> queries on the view — the
+ <code class="literal">RETURNING</code> clause is simply ignored for <code class="command">INSERT</code>.
+ </p><p>
+ Now assume that once in a while, a pack of shoelaces arrives at
+ the shop and a big parts list along with it. But you don't want
+ to manually update the <code class="literal">shoelace</code> view every
+ time. Instead we set up two little tables: one where you can
+ insert the items from the part list, and one with a special
+ trick. The creation commands for these are:
+
+</p><pre class="programlisting">
+CREATE TABLE shoelace_arrive (
+ arr_name text,
+ arr_quant integer
+);
+
+CREATE TABLE shoelace_ok (
+ ok_name text,
+ ok_quant integer
+);
+
+CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok
+ DO INSTEAD
+ UPDATE shoelace
+ SET sl_avail = sl_avail + NEW.ok_quant
+ WHERE sl_name = NEW.ok_name;
+</pre><p>
+
+ Now you can fill the table <code class="literal">shoelace_arrive</code> with
+ the data from the parts list:
+
+</p><pre class="programlisting">
+SELECT * FROM shoelace_arrive;
+
+ arr_name | arr_quant
+----------+-----------
+ sl3 | 10
+ sl6 | 20
+ sl8 | 20
+(3 rows)
+</pre><p>
+
+ Take a quick look at the current data:
+
+</p><pre class="programlisting">
+SELECT * FROM shoelace;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+----------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 6 | brown | 60 | cm | 60
+ sl3 | 0 | black | 35 | inch | 88.9
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl8 | 1 | brown | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 0 | brown | 0.9 | m | 90
+(8 rows)
+</pre><p>
+
+ Now move the arrived shoelaces in:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_ok SELECT * FROM shoelace_arrive;
+</pre><p>
+
+ and check the results:
+
+</p><pre class="programlisting">
+SELECT * FROM shoelace ORDER BY sl_name;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+----------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 6 | brown | 60 | cm | 60
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl3 | 10 | black | 35 | inch | 88.9
+ sl8 | 21 | brown | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 20 | brown | 0.9 | m | 90
+(8 rows)
+
+SELECT * FROM shoelace_log;
+
+ sl_name | sl_avail | log_who| log_when
+---------+----------+--------+----------------------------------
+ sl7 | 6 | Al | Tue Oct 20 19:14:45 1998 MET DST
+ sl3 | 10 | Al | Tue Oct 20 19:25:16 1998 MET DST
+ sl6 | 20 | Al | Tue Oct 20 19:25:16 1998 MET DST
+ sl8 | 21 | Al | Tue Oct 20 19:25:16 1998 MET DST
+(4 rows)
+</pre><p>
+ </p><p>
+ It's a long way from the one <code class="literal">INSERT ... SELECT</code>
+ to these results. And the description of the query-tree
+ transformation will be the last in this chapter. First, there is
+ the parser's output:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_ok
+SELECT shoelace_arrive.arr_name, shoelace_arrive.arr_quant
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok;
+</pre><p>
+
+ Now the first rule <code class="literal">shoelace_ok_ins</code> is applied and turns this
+ into:
+
+</p><pre class="programlisting">
+UPDATE shoelace
+ SET sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace
+ WHERE shoelace.sl_name = shoelace_arrive.arr_name;
+</pre><p>
+
+ and throws away the original <code class="command">INSERT</code> on
+ <code class="literal">shoelace_ok</code>. This rewritten query is passed to
+ the rule system again, and the second applied rule
+ <code class="literal">shoelace_upd</code> produces:
+
+</p><pre class="programlisting">
+UPDATE shoelace_data
+ SET sl_name = shoelace.sl_name,
+ sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant,
+ sl_color = shoelace.sl_color,
+ sl_len = shoelace.sl_len,
+ sl_unit = shoelace.sl_unit
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace, shoelace old,
+ shoelace new, shoelace_data shoelace_data
+ WHERE shoelace.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = shoelace.sl_name;
+</pre><p>
+
+ Again it's an <code class="literal">INSTEAD</code> rule and the previous query tree is trashed.
+ Note that this query still uses the view <code class="literal">shoelace</code>.
+ But the rule system isn't finished with this step, so it continues
+ and applies the <code class="literal">_RETURN</code> rule on it, and we get:
+
+</p><pre class="programlisting">
+UPDATE shoelace_data
+ SET sl_name = s.sl_name,
+ sl_avail = s.sl_avail + shoelace_arrive.arr_quant,
+ sl_color = s.sl_color,
+ sl_len = s.sl_len,
+ sl_unit = s.sl_unit
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace, shoelace old,
+ shoelace new, shoelace_data shoelace_data,
+ shoelace old, shoelace new,
+ shoelace_data s, unit u
+ WHERE s.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = s.sl_name;
+</pre><p>
+
+ Finally, the rule <code class="literal">log_shoelace</code> gets applied,
+ producing the extra query tree:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log
+SELECT s.sl_name,
+ s.sl_avail + shoelace_arrive.arr_quant,
+ current_user,
+ current_timestamp
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace, shoelace old,
+ shoelace new, shoelace_data shoelace_data,
+ shoelace old, shoelace new,
+ shoelace_data s, unit u,
+ shoelace_data old, shoelace_data new
+ shoelace_log shoelace_log
+ WHERE s.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = s.sl_name
+ AND (s.sl_avail + shoelace_arrive.arr_quant) &lt;&gt; s.sl_avail;
+</pre><p>
+
+ After that the rule system runs out of rules and returns the
+ generated query trees.
+ </p><p>
+ So we end up with two final query trees that are equivalent to the
+ <acronym class="acronym">SQL</acronym> statements:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace_log
+SELECT s.sl_name,
+ s.sl_avail + shoelace_arrive.arr_quant,
+ current_user,
+ current_timestamp
+ FROM shoelace_arrive shoelace_arrive, shoelace_data shoelace_data,
+ shoelace_data s
+ WHERE s.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = s.sl_name
+ AND s.sl_avail + shoelace_arrive.arr_quant &lt;&gt; s.sl_avail;
+
+UPDATE shoelace_data
+ SET sl_avail = shoelace_data.sl_avail + shoelace_arrive.arr_quant
+ FROM shoelace_arrive shoelace_arrive,
+ shoelace_data shoelace_data,
+ shoelace_data s
+ WHERE s.sl_name = shoelace_arrive.sl_name
+ AND shoelace_data.sl_name = s.sl_name;
+</pre><p>
+
+ The result is that data coming from one relation inserted into another,
+ changed into updates on a third, changed into updating
+ a fourth plus logging that final update in a fifth
+ gets reduced into two queries.
+</p><p>
+ There is a little detail that's a bit ugly. Looking at the two
+ queries, it turns out that the <code class="literal">shoelace_data</code>
+ relation appears twice in the range table where it could
+ definitely be reduced to one. The planner does not handle it and
+ so the execution plan for the rule systems output of the
+ <code class="command">INSERT</code> will be
+
+</p><pre class="literallayout">
+Nested Loop
+ -&gt; Merge Join
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on s
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on shoelace_arrive
+ -&gt; Seq Scan on shoelace_data
+</pre><p>
+
+ while omitting the extra range table entry would result in a
+
+</p><pre class="literallayout">
+Merge Join
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on s
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on shoelace_arrive
+</pre><p>
+
+ which produces exactly the same entries in the log table. Thus,
+ the rule system caused one extra scan on the table
+ <code class="literal">shoelace_data</code> that is absolutely not
+ necessary. And the same redundant scan is done once more in the
+ <code class="command">UPDATE</code>. But it was a really hard job to make
+ that all possible at all.
+</p><p>
+ Now we make a final demonstration of the
+ <span class="productname">PostgreSQL</span> rule system and its power.
+ Say you add some shoelaces with extraordinary colors to your
+ database:
+
+</p><pre class="programlisting">
+INSERT INTO shoelace VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0);
+INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0);
+</pre><p>
+
+ We would like to make a view to check which
+ <code class="literal">shoelace</code> entries do not fit any shoe in color.
+ The view for this is:
+
+</p><pre class="programlisting">
+CREATE VIEW shoelace_mismatch AS
+ SELECT * FROM shoelace WHERE NOT EXISTS
+ (SELECT shoename FROM shoe WHERE slcolor = sl_color);
+</pre><p>
+
+ Its output is:
+
+</p><pre class="programlisting">
+SELECT * FROM shoelace_mismatch;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+---------+----------+----------+--------+---------+-----------
+ sl9 | 0 | pink | 35 | inch | 88.9
+ sl10 | 1000 | magenta | 40 | inch | 101.6
+</pre><p>
+ </p><p>
+ Now we want to set it up so that mismatching shoelaces that are
+ not in stock are deleted from the database.
+ To make it a little harder for <span class="productname">PostgreSQL</span>,
+ we don't delete it directly. Instead we create one more view:
+
+</p><pre class="programlisting">
+CREATE VIEW shoelace_can_delete AS
+ SELECT * FROM shoelace_mismatch WHERE sl_avail = 0;
+</pre><p>
+
+ and do it this way:
+
+</p><pre class="programlisting">
+DELETE FROM shoelace WHERE EXISTS
+ (SELECT * FROM shoelace_can_delete
+ WHERE sl_name = shoelace.sl_name);
+</pre><p>
+
+ The results are:
+
+</p><pre class="programlisting">
+SELECT * FROM shoelace;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+---------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 6 | brown | 60 | cm | 60
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl3 | 10 | black | 35 | inch | 88.9
+ sl8 | 21 | brown | 40 | inch | 101.6
+ sl10 | 1000 | magenta | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 20 | brown | 0.9 | m | 90
+(9 rows)
+</pre><p>
+ </p><p>
+ A <code class="command">DELETE</code> on a view, with a subquery qualification that
+ in total uses 4 nesting/joined views, where one of them
+ itself has a subquery qualification containing a view
+ and where calculated view columns are used,
+ gets rewritten into
+ one single query tree that deletes the requested data
+ from a real table.
+</p><p>
+ There are probably only a few situations out in the real world
+ where such a construct is necessary. But it makes you feel
+ comfortable that it works.
+</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules-materializedviews.html" title="41.3. Materialized Views">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-privileges.html" title="41.5. Rules and Privileges">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.3. Materialized Views </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.5. Rules and Privileges</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules-views.html b/doc/src/sgml/html/rules-views.html
new file mode 100644
index 0000000..96d01bf
--- /dev/null
+++ b/doc/src/sgml/html/rules-views.html
@@ -0,0 +1,506 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>41.2. Views and the Rule System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="querytree.html" title="41.1. The Query Tree" /><link rel="next" href="rules-materializedviews.html" title="41.3. Materialized Views" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">41.2. Views and the Rule System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="querytree.html" title="41.1. The Query Tree">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><th width="60%" align="center">Chapter 41. The Rule System</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="rules-materializedviews.html" title="41.3. Materialized Views">Next</a></td></tr></table><hr /></div><div class="sect1" id="RULES-VIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">41.2. Views and the Rule System</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="rules-views.html#RULES-SELECT">41.2.1. How <code class="command">SELECT</code> Rules Work</a></span></dt><dt><span class="sect2"><a href="rules-views.html#id-1.8.6.7.6">41.2.2. View Rules in Non-<code class="command">SELECT</code> Statements</a></span></dt><dt><span class="sect2"><a href="rules-views.html#id-1.8.6.7.7">41.2.3. The Power of Views in <span class="productname">PostgreSQL</span></a></span></dt><dt><span class="sect2"><a href="rules-views.html#RULES-VIEWS-UPDATE">41.2.4. Updating a View</a></span></dt></dl></div><a id="id-1.8.6.7.2" class="indexterm"></a><a id="id-1.8.6.7.3" class="indexterm"></a><p>
+ Views in <span class="productname">PostgreSQL</span> are implemented
+ using the rule system. In fact, there is essentially no difference
+ between:
+
+</p><pre class="programlisting">
+CREATE VIEW myview AS SELECT * FROM mytab;
+</pre><p>
+
+ compared against the two commands:
+
+</p><pre class="programlisting">
+CREATE TABLE myview (<em class="replaceable"><code>same column list as mytab</code></em>);
+CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD
+ SELECT * FROM mytab;
+</pre><p>
+
+ because this is exactly what the <code class="command">CREATE VIEW</code>
+ command does internally. This has some side effects. One of them
+ is that the information about a view in the
+ <span class="productname">PostgreSQL</span> system catalogs is exactly
+ the same as it is for a table. So for the parser, there is
+ absolutely no difference between a table and a view. They are the
+ same thing: relations.
+</p><div class="sect2" id="RULES-SELECT"><div class="titlepage"><div><div><h3 class="title">41.2.1. How <code class="command">SELECT</code> Rules Work</h3></div></div></div><a id="id-1.8.6.7.5.2" class="indexterm"></a><p>
+ Rules <code class="literal">ON SELECT</code> are applied to all queries as the last step, even
+ if the command given is an <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code> or <code class="command">DELETE</code>. And they
+ have different semantics from rules on the other command types in that they modify the
+ query tree in place instead of creating a new one. So
+ <code class="command">SELECT</code> rules are described first.
+</p><p>
+ Currently, there can be only one action in an <code class="literal">ON SELECT</code> rule, and it must
+ be an unconditional <code class="command">SELECT</code> action that is <code class="literal">INSTEAD</code>. This restriction was
+ required to make rules safe enough to open them for ordinary users, and
+ it restricts <code class="literal">ON SELECT</code> rules to act like views.
+</p><p>
+ The examples for this chapter are two join views that do some
+ calculations and some more views using them in turn. One of the
+ two first views is customized later by adding rules for
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> operations so that the final result will
+ be a view that behaves like a real table with some magic
+ functionality. This is not such a simple example to start from and
+ this makes things harder to get into. But it's better to have one
+ example that covers all the points discussed step by step rather
+ than having many different ones that might mix up in mind.
+</p><p>
+ The real tables we need in the first two rule system descriptions
+ are these:
+
+</p><pre class="programlisting">
+CREATE TABLE shoe_data (
+ shoename text, -- primary key
+ sh_avail integer, -- available number of pairs
+ slcolor text, -- preferred shoelace color
+ slminlen real, -- minimum shoelace length
+ slmaxlen real, -- maximum shoelace length
+ slunit text -- length unit
+);
+
+CREATE TABLE shoelace_data (
+ sl_name text, -- primary key
+ sl_avail integer, -- available number of pairs
+ sl_color text, -- shoelace color
+ sl_len real, -- shoelace length
+ sl_unit text -- length unit
+);
+
+CREATE TABLE unit (
+ un_name text, -- primary key
+ un_fact real -- factor to transform to cm
+);
+</pre><p>
+
+ As you can see, they represent shoe-store data.
+</p><p>
+ The views are created as:
+
+</p><pre class="programlisting">
+CREATE VIEW shoe AS
+ SELECT sh.shoename,
+ sh.sh_avail,
+ sh.slcolor,
+ sh.slminlen,
+ sh.slminlen * un.un_fact AS slminlen_cm,
+ sh.slmaxlen,
+ sh.slmaxlen * un.un_fact AS slmaxlen_cm,
+ sh.slunit
+ FROM shoe_data sh, unit un
+ WHERE sh.slunit = un.un_name;
+
+CREATE VIEW shoelace AS
+ SELECT s.sl_name,
+ s.sl_avail,
+ s.sl_color,
+ s.sl_len,
+ s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name;
+
+CREATE VIEW shoe_ready AS
+ SELECT rsh.shoename,
+ rsh.sh_avail,
+ rsl.sl_name,
+ rsl.sl_avail,
+ least(rsh.sh_avail, rsl.sl_avail) AS total_avail
+ FROM shoe rsh, shoelace rsl
+ WHERE rsl.sl_color = rsh.slcolor
+ AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
+ AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm;
+</pre><p>
+
+ The <code class="command">CREATE VIEW</code> command for the
+ <code class="literal">shoelace</code> view (which is the simplest one we
+ have) will create a relation <code class="literal">shoelace</code> and an entry in
+ <code class="structname">pg_rewrite</code> that tells that there is a
+ rewrite rule that must be applied whenever the relation <code class="literal">shoelace</code>
+ is referenced in a query's range table. The rule has no rule
+ qualification (discussed later, with the non-<code class="command">SELECT</code> rules, since
+ <code class="command">SELECT</code> rules currently cannot have them) and it is <code class="literal">INSTEAD</code>. Note
+ that rule qualifications are not the same as query qualifications.
+ The action of our rule has a query qualification.
+ The action of the rule is one query tree that is a copy of the
+ <code class="command">SELECT</code> statement in the view creation command.
+</p><div class="note"><h3 class="title">Note</h3><p>
+ The two extra range
+ table entries for <code class="literal">NEW</code> and <code class="literal">OLD</code> that you can see in
+ the <code class="structname">pg_rewrite</code> entry aren't of interest
+ for <code class="command">SELECT</code> rules.
+ </p></div><p>
+ Now we populate <code class="literal">unit</code>, <code class="literal">shoe_data</code>
+ and <code class="literal">shoelace_data</code> and run a simple query on a view:
+
+</p><pre class="programlisting">
+INSERT INTO unit VALUES ('cm', 1.0);
+INSERT INTO unit VALUES ('m', 100.0);
+INSERT INTO unit VALUES ('inch', 2.54);
+
+INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm');
+INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch');
+INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm');
+INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch');
+
+INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm');
+INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm');
+INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch');
+INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch');
+INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm');
+INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm');
+INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm');
+INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch');
+
+SELECT * FROM shoelace;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+-----------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 7 | brown | 60 | cm | 60
+ sl3 | 0 | black | 35 | inch | 88.9
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl8 | 1 | brown | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 0 | brown | 0.9 | m | 90
+(8 rows)
+</pre><p>
+ </p><p>
+ This is the simplest <code class="command">SELECT</code> you can do on our
+ views, so we take this opportunity to explain the basics of view
+ rules. The <code class="literal">SELECT * FROM shoelace</code> was
+ interpreted by the parser and produced the query tree:
+
+</p><pre class="programlisting">
+SELECT shoelace.sl_name, shoelace.sl_avail,
+ shoelace.sl_color, shoelace.sl_len,
+ shoelace.sl_unit, shoelace.sl_len_cm
+ FROM shoelace shoelace;
+</pre><p>
+
+ and this is given to the rule system. The rule system walks through the
+ range table and checks if there are rules
+ for any relation. When processing the range table entry for
+ <code class="literal">shoelace</code> (the only one up to now) it finds the
+ <code class="literal">_RETURN</code> rule with the query tree:
+
+</p><pre class="programlisting">
+SELECT s.sl_name, s.sl_avail,
+ s.sl_color, s.sl_len, s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace old, shoelace new,
+ shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name;
+</pre><p>
+</p><p>
+ To expand the view, the rewriter simply creates a subquery range-table
+ entry containing the rule's action query tree, and substitutes this
+ range table entry for the original one that referenced the view. The
+ resulting rewritten query tree is almost the same as if you had typed:
+
+</p><pre class="programlisting">
+SELECT shoelace.sl_name, shoelace.sl_avail,
+ shoelace.sl_color, shoelace.sl_len,
+ shoelace.sl_unit, shoelace.sl_len_cm
+ FROM (SELECT s.sl_name,
+ s.sl_avail,
+ s.sl_color,
+ s.sl_len,
+ s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name) shoelace;
+</pre><p>
+
+ There is one difference however: the subquery's range table has two
+ extra entries <code class="literal">shoelace old</code> and <code class="literal">shoelace new</code>. These entries don't
+ participate directly in the query, since they aren't referenced by
+ the subquery's join tree or target list. The rewriter uses them
+ to store the access privilege check information that was originally present
+ in the range-table entry that referenced the view. In this way, the
+ executor will still check that the user has proper privileges to access
+ the view, even though there's no direct use of the view in the rewritten
+ query.
+</p><p>
+ That was the first rule applied. The rule system will continue checking
+ the remaining range-table entries in the top query (in this example there
+ are no more), and it will recursively check the range-table entries in
+ the added subquery to see if any of them reference views. (But it
+ won't expand <code class="literal">old</code> or <code class="literal">new</code> — otherwise we'd have infinite recursion!)
+ In this example, there are no rewrite rules for <code class="literal">shoelace_data</code> or <code class="literal">unit</code>,
+ so rewriting is complete and the above is the final result given to
+ the planner.
+</p><p>
+ Now we want to write a query that finds out for which shoes currently in the store
+ we have the matching shoelaces (color and length) and where the
+ total number of exactly matching pairs is greater than or equal to two.
+
+</p><pre class="programlisting">
+SELECT * FROM shoe_ready WHERE total_avail &gt;= 2;
+
+ shoename | sh_avail | sl_name | sl_avail | total_avail
+----------+----------+---------+----------+-------------
+ sh1 | 2 | sl1 | 5 | 2
+ sh3 | 4 | sl7 | 7 | 4
+(2 rows)
+</pre><p>
+</p><p>
+ The output of the parser this time is the query tree:
+
+</p><pre class="programlisting">
+SELECT shoe_ready.shoename, shoe_ready.sh_avail,
+ shoe_ready.sl_name, shoe_ready.sl_avail,
+ shoe_ready.total_avail
+ FROM shoe_ready shoe_ready
+ WHERE shoe_ready.total_avail &gt;= 2;
+</pre><p>
+
+ The first rule applied will be the one for the
+ <code class="literal">shoe_ready</code> view and it results in the
+ query tree:
+
+</p><pre class="programlisting">
+SELECT shoe_ready.shoename, shoe_ready.sh_avail,
+ shoe_ready.sl_name, shoe_ready.sl_avail,
+ shoe_ready.total_avail
+ FROM (SELECT rsh.shoename,
+ rsh.sh_avail,
+ rsl.sl_name,
+ rsl.sl_avail,
+ least(rsh.sh_avail, rsl.sl_avail) AS total_avail
+ FROM shoe rsh, shoelace rsl
+ WHERE rsl.sl_color = rsh.slcolor
+ AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
+ AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm) shoe_ready
+ WHERE shoe_ready.total_avail &gt;= 2;
+</pre><p>
+
+ Similarly, the rules for <code class="literal">shoe</code> and
+ <code class="literal">shoelace</code> are substituted into the range table of
+ the subquery, leading to a three-level final query tree:
+
+</p><pre class="programlisting">
+SELECT shoe_ready.shoename, shoe_ready.sh_avail,
+ shoe_ready.sl_name, shoe_ready.sl_avail,
+ shoe_ready.total_avail
+ FROM (SELECT rsh.shoename,
+ rsh.sh_avail,
+ rsl.sl_name,
+ rsl.sl_avail,
+ least(rsh.sh_avail, rsl.sl_avail) AS total_avail
+ FROM (SELECT sh.shoename,
+ sh.sh_avail,
+ sh.slcolor,
+ sh.slminlen,
+ sh.slminlen * un.un_fact AS slminlen_cm,
+ sh.slmaxlen,
+ sh.slmaxlen * un.un_fact AS slmaxlen_cm,
+ sh.slunit
+ FROM shoe_data sh, unit un
+ WHERE sh.slunit = un.un_name) rsh,
+ (SELECT s.sl_name,
+ s.sl_avail,
+ s.sl_color,
+ s.sl_len,
+ s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name) rsl
+ WHERE rsl.sl_color = rsh.slcolor
+ AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
+ AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm) shoe_ready
+ WHERE shoe_ready.total_avail &gt; 2;
+</pre><p>
+ </p><p>
+ This might look inefficient, but the planner will collapse this into a
+ single-level query tree by <span class="quote">“<span class="quote">pulling up</span>”</span> the subqueries,
+ and then it will plan the joins just as if we'd written them out
+ manually. So collapsing the query tree is an optimization that the
+ rewrite system doesn't have to concern itself with.
+ </p></div><div class="sect2" id="id-1.8.6.7.6"><div class="titlepage"><div><div><h3 class="title">41.2.2. View Rules in Non-<code class="command">SELECT</code> Statements</h3></div></div></div><p>
+ Two details of the query tree aren't touched in the description of
+ view rules above. These are the command type and the result relation.
+ In fact, the command type is not needed by view rules, but the result
+ relation may affect the way in which the query rewriter works, because
+ special care needs to be taken if the result relation is a view.
+</p><p>
+ There are only a few differences between a query tree for a
+ <code class="command">SELECT</code> and one for any other
+ command. Obviously, they have a different command type and for a
+ command other than a <code class="command">SELECT</code>, the result
+ relation points to the range-table entry where the result should
+ go. Everything else is absolutely the same. So having two tables
+ <code class="literal">t1</code> and <code class="literal">t2</code> with columns <code class="literal">a</code> and
+ <code class="literal">b</code>, the query trees for the two statements:
+
+</p><pre class="programlisting">
+SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a;
+
+UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a;
+</pre><p>
+
+ are nearly identical. In particular:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The range tables contain entries for the tables <code class="literal">t1</code> and <code class="literal">t2</code>.
+ </p></li><li class="listitem"><p>
+ The target lists contain one variable that points to column
+ <code class="literal">b</code> of the range table entry for table <code class="literal">t2</code>.
+ </p></li><li class="listitem"><p>
+ The qualification expressions compare the columns <code class="literal">a</code> of both
+ range-table entries for equality.
+ </p></li><li class="listitem"><p>
+ The join trees show a simple join between <code class="literal">t1</code> and <code class="literal">t2</code>.
+ </p></li></ul></div><p>
+ </p><p>
+ The consequence is, that both query trees result in similar
+ execution plans: They are both joins over the two tables. For the
+ <code class="command">UPDATE</code> the missing columns from <code class="literal">t1</code> are added to
+ the target list by the planner and the final query tree will read
+ as:
+
+</p><pre class="programlisting">
+UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a;
+</pre><p>
+
+ and thus the executor run over the join will produce exactly the
+ same result set as:
+
+</p><pre class="programlisting">
+SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a;
+</pre><p>
+
+ But there is a little problem in
+ <code class="command">UPDATE</code>: the part of the executor plan that does
+ the join does not care what the results from the join are
+ meant for. It just produces a result set of rows. The fact that
+ one is a <code class="command">SELECT</code> command and the other is an
+ <code class="command">UPDATE</code> is handled higher up in the executor, where
+ it knows that this is an <code class="command">UPDATE</code>, and it knows that
+ this result should go into table <code class="literal">t1</code>. But which of the rows
+ that are there has to be replaced by the new row?
+</p><p>
+ To resolve this problem, another entry is added to the target list
+ in <code class="command">UPDATE</code> (and also in
+ <code class="command">DELETE</code>) statements: the current tuple ID
+ (<acronym class="acronym">CTID</acronym>).<a id="id-1.8.6.7.6.5.4" class="indexterm"></a>
+ This is a system column containing the
+ file block number and position in the block for the row. Knowing
+ the table, the <acronym class="acronym">CTID</acronym> can be used to retrieve the
+ original row of <code class="literal">t1</code> to be updated. After adding the
+ <acronym class="acronym">CTID</acronym> to the target list, the query actually looks like:
+
+</p><pre class="programlisting">
+SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a;
+</pre><p>
+
+ Now another detail of <span class="productname">PostgreSQL</span> enters
+ the stage. Old table rows aren't overwritten, and this
+ is why <code class="command">ROLLBACK</code> is fast. In an <code class="command">UPDATE</code>,
+ the new result row is inserted into the table (after stripping the
+ <acronym class="acronym">CTID</acronym>) and in the row header of the old row, which the
+ <acronym class="acronym">CTID</acronym> pointed to, the <code class="literal">cmax</code> and
+ <code class="literal">xmax</code> entries are set to the current command counter
+ and current transaction ID. Thus the old row is hidden, and after
+ the transaction commits the vacuum cleaner can eventually remove
+ the dead row.
+</p><p>
+ Knowing all that, we can simply apply view rules in absolutely
+ the same way to any command. There is no difference.
+</p></div><div class="sect2" id="id-1.8.6.7.7"><div class="titlepage"><div><div><h3 class="title">41.2.3. The Power of Views in <span class="productname">PostgreSQL</span></h3></div></div></div><p>
+ The above demonstrates how the rule system incorporates view
+ definitions into the original query tree. In the second example, a
+ simple <code class="command">SELECT</code> from one view created a final
+ query tree that is a join of 4 tables (<code class="literal">unit</code> was used twice with
+ different names).
+</p><p>
+ The benefit of implementing views with the rule system is
+ that the planner has all
+ the information about which tables have to be scanned plus the
+ relationships between these tables plus the restrictive
+ qualifications from the views plus the qualifications from
+ the original query
+ in one single query tree. And this is still the situation
+ when the original query is already a join over views.
+ The planner has to decide which is
+ the best path to execute the query, and the more information
+ the planner has, the better this decision can be. And
+ the rule system as implemented in <span class="productname">PostgreSQL</span>
+ ensures that this is all information available about the query
+ up to that point.
+</p></div><div class="sect2" id="RULES-VIEWS-UPDATE"><div class="titlepage"><div><div><h3 class="title">41.2.4. Updating a View</h3></div></div></div><p>
+ What happens if a view is named as the target relation for an
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code>? Doing the substitutions
+ described above would give a query tree in which the result
+ relation points at a subquery range-table entry, which will not
+ work. There are several ways in which <span class="productname">PostgreSQL</span>
+ can support the appearance of updating a view, however.
+ In order of user-experienced complexity those are: automatically substitute
+ in the underlying table for the view, execute a user-defined trigger,
+ or rewrite the query per a user-defined rule.
+ These options are discussed below.
+</p><p>
+ If the subquery selects from a single base relation and is simple
+ enough, the rewriter can automatically replace the subquery with the
+ underlying base relation so that the <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, or <code class="command">DELETE</code> is applied to
+ the base relation in the appropriate way. Views that are
+ <span class="quote">“<span class="quote">simple enough</span>”</span> for this are called <em class="firstterm">automatically
+ updatable</em>. For detailed information on the kinds of view that can
+ be automatically updated, see <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a>.
+</p><p>
+ Alternatively, the operation may be handled by a user-provided
+ <code class="literal">INSTEAD OF</code> trigger on the view
+ (see <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>).
+ Rewriting works slightly differently
+ in this case. For <code class="command">INSERT</code>, the rewriter does
+ nothing at all with the view, leaving it as the result relation
+ for the query. For <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code>, it's still necessary to expand the
+ view query to produce the <span class="quote">“<span class="quote">old</span>”</span> rows that the command will
+ attempt to update or delete. So the view is expanded as normal,
+ but another unexpanded range-table entry is added to the query
+ to represent the view in its capacity as the result relation.
+</p><p>
+ The problem that now arises is how to identify the rows to be
+ updated in the view. Recall that when the result relation
+ is a table, a special <acronym class="acronym">CTID</acronym> entry is added to the target
+ list to identify the physical locations of the rows to be updated.
+ This does not work if the result relation is a view, because a view
+ does not have any <acronym class="acronym">CTID</acronym>, since its rows do not have
+ actual physical locations. Instead, for an <code class="command">UPDATE</code>
+ or <code class="command">DELETE</code> operation, a special <code class="literal">wholerow</code>
+ entry is added to the target list, which expands to include all
+ columns from the view. The executor uses this value to supply the
+ <span class="quote">“<span class="quote">old</span>”</span> row to the <code class="literal">INSTEAD OF</code> trigger. It is
+ up to the trigger to work out what to update based on the old and
+ new row values.
+</p><p>
+ Another possibility is for the user to define <code class="literal">INSTEAD</code>
+ rules that specify substitute actions for <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, and <code class="command">DELETE</code> commands on
+ a view. These rules will rewrite the command, typically into a command
+ that updates one or more tables, rather than views. That is the topic
+ of <a class="xref" href="rules-update.html" title="41.4. Rules on INSERT, UPDATE, and DELETE">Section 41.4</a>.
+</p><p>
+ Note that rules are evaluated first, rewriting the original query
+ before it is planned and executed. Therefore, if a view has
+ <code class="literal">INSTEAD OF</code> triggers as well as rules on <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, or <code class="command">DELETE</code>, then the rules will be
+ evaluated first, and depending on the result, the triggers may not be
+ used at all.
+</p><p>
+ Automatic rewriting of an <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, or <code class="command">DELETE</code> query on a
+ simple view is always tried last. Therefore, if a view has rules or
+ triggers, they will override the default behavior of automatically
+ updatable views.
+</p><p>
+ If there are no <code class="literal">INSTEAD</code> rules or <code class="literal">INSTEAD OF</code>
+ triggers for the view, and the rewriter cannot automatically rewrite
+ the query as an update on the underlying base relation, an error will
+ be thrown because the executor cannot update a view as such.
+</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="querytree.html" title="41.1. The Query Tree">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="rules.html" title="Chapter 41. The Rule System">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="rules-materializedviews.html" title="41.3. Materialized Views">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.1. The Query Tree </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.3. Materialized Views</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/rules.html b/doc/src/sgml/html/rules.html
new file mode 100644
index 0000000..9f59f5c
--- /dev/null
+++ b/doc/src/sgml/html/rules.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 41. The Rule System</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-trigger-table-rewrite-example.html" title="40.5. A Table Rewrite Event Trigger Example" /><link rel="next" href="querytree.html" title="41.1. The Query Tree" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 41. The Rule System</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-trigger-table-rewrite-example.html" title="40.5. A Table Rewrite Event Trigger Example">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="querytree.html" title="41.1. The Query Tree">Next</a></td></tr></table><hr /></div><div class="chapter" id="RULES"><div class="titlepage"><div><div><h2 class="title">Chapter 41. The Rule System</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="querytree.html">41.1. The Query Tree</a></span></dt><dt><span class="sect1"><a href="rules-views.html">41.2. Views and the Rule System</a></span></dt><dd><dl><dt><span class="sect2"><a href="rules-views.html#RULES-SELECT">41.2.1. How <code class="command">SELECT</code> Rules Work</a></span></dt><dt><span class="sect2"><a href="rules-views.html#id-1.8.6.7.6">41.2.2. View Rules in Non-<code class="command">SELECT</code> Statements</a></span></dt><dt><span class="sect2"><a href="rules-views.html#id-1.8.6.7.7">41.2.3. The Power of Views in <span class="productname">PostgreSQL</span></a></span></dt><dt><span class="sect2"><a href="rules-views.html#RULES-VIEWS-UPDATE">41.2.4. Updating a View</a></span></dt></dl></dd><dt><span class="sect1"><a href="rules-materializedviews.html">41.3. Materialized Views</a></span></dt><dt><span class="sect1"><a href="rules-update.html">41.4. Rules on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code></a></span></dt><dd><dl><dt><span class="sect2"><a href="rules-update.html#id-1.8.6.9.7">41.4.1. How Update Rules Work</a></span></dt><dt><span class="sect2"><a href="rules-update.html#RULES-UPDATE-VIEWS">41.4.2. Cooperation with Views</a></span></dt></dl></dd><dt><span class="sect1"><a href="rules-privileges.html">41.5. Rules and Privileges</a></span></dt><dt><span class="sect1"><a href="rules-status.html">41.6. Rules and Command Status</a></span></dt><dt><span class="sect1"><a href="rules-triggers.html">41.7. Rules Versus Triggers</a></span></dt></dl></div><a id="id-1.8.6.2" class="indexterm"></a><p>
+ This chapter discusses the rule system in
+ <span class="productname">PostgreSQL</span>. Production rule systems
+ are conceptually simple, but there are many subtle points
+ involved in actually using them.
+</p><p>
+ Some other database systems define active database rules, which
+ are usually stored procedures and triggers. In
+ <span class="productname">PostgreSQL</span>, these can be implemented
+ using functions and triggers as well.
+</p><p>
+ The rule system (more precisely speaking, the query rewrite rule
+ system) is totally different from stored procedures and triggers.
+ It modifies queries to take rules into consideration, and then
+ passes the modified query to the query planner for planning and
+ execution. It is very powerful, and can be used for many things
+ such as query language procedures, views, and versions. The
+ theoretical foundations and the power of this rule system are
+ also discussed in <a class="xref" href="biblio.html#STON90B">[ston90b]</a> and <a class="xref" href="biblio.html#ONG90">[ong90]</a>.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-trigger-table-rewrite-example.html" title="40.5. A Table Rewrite Event Trigger Example">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="querytree.html" title="41.1. The Query Tree">Next</a></td></tr><tr><td width="40%" align="left" valign="top">40.5. A Table Rewrite Event Trigger Example </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 41.1. The Query Tree</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-autovacuum.html b/doc/src/sgml/html/runtime-config-autovacuum.html
new file mode 100644
index 0000000..245551d
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-autovacuum.html
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.10. Automatic Vacuuming</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-statistics.html" title="20.9. Run-time Statistics" /><link rel="next" href="runtime-config-client.html" title="20.11. Client Connection Defaults" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.10. Automatic Vacuuming</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-statistics.html" title="20.9. Run-time Statistics">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-client.html" title="20.11. Client Connection Defaults">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-AUTOVACUUM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.10. Automatic Vacuuming</h2></div></div></div><a id="id-1.6.7.13.2" class="indexterm"></a><p>
+ These settings control the behavior of the <em class="firstterm">autovacuum</em>
+ feature. Refer to <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a> for more information.
+ Note that many of these settings can be overridden on a per-table
+ basis; see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" title="Storage Parameters">Storage Parameters</a>.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-AUTOVACUUM"><span class="term"><code class="varname">autovacuum</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.13.4.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls whether the server should run the
+ autovacuum launcher daemon. This is on by default; however,
+ <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-COUNTS">track_counts</a> must also be enabled for
+ autovacuum to work.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line; however, autovacuuming can be
+ disabled for individual tables by changing table storage parameters.
+ </p><p>
+ Note that even when this parameter is disabled, the system
+ will launch autovacuum processes if necessary to
+ prevent transaction ID wraparound. See <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a> for more information.
+ </p></dd><dt id="GUC-AUTOVACUUM-MAX-WORKERS"><span class="term"><code class="varname">autovacuum_max_workers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum number of autovacuum processes (other than the
+ autovacuum launcher) that may be running at any one time. The default
+ is three. This parameter can only be set at server start.
+ </p></dd><dt id="GUC-AUTOVACUUM-NAPTIME"><span class="term"><code class="varname">autovacuum_naptime</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the minimum delay between autovacuum runs on any given
+ database. In each round the daemon examines the
+ database and issues <code class="command">VACUUM</code> and <code class="command">ANALYZE</code> commands
+ as needed for tables in that database.
+ If this value is specified without units, it is taken as seconds.
+ The default is one minute (<code class="literal">1min</code>).
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-AUTOVACUUM-VACUUM-THRESHOLD"><span class="term"><code class="varname">autovacuum_vacuum_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the minimum number of updated or deleted tuples needed
+ to trigger a <code class="command">VACUUM</code> in any one table.
+ The default is 50 tuples.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-VACUUM-INSERT-THRESHOLD"><span class="term"><code class="varname">autovacuum_vacuum_insert_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the number of inserted tuples needed to trigger a
+ <code class="command">VACUUM</code> in any one table.
+ The default is 1000 tuples. If -1 is specified, autovacuum will not
+ trigger a <code class="command">VACUUM</code> operation on any tables based on
+ the number of inserts.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-ANALYZE-THRESHOLD"><span class="term"><code class="varname">autovacuum_analyze_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the minimum number of inserted, updated or deleted tuples
+ needed to trigger an <code class="command">ANALYZE</code> in any one table.
+ The default is 50 tuples.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-VACUUM-SCALE-FACTOR"><span class="term"><code class="varname">autovacuum_vacuum_scale_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.13.4.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a fraction of the table size to add to
+ <code class="varname">autovacuum_vacuum_threshold</code>
+ when deciding whether to trigger a <code class="command">VACUUM</code>.
+ The default is 0.2 (20% of table size).
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-VACUUM-INSERT-SCALE-FACTOR"><span class="term"><code class="varname">autovacuum_vacuum_insert_scale_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.13.4.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a fraction of the table size to add to
+ <code class="varname">autovacuum_vacuum_insert_threshold</code>
+ when deciding whether to trigger a <code class="command">VACUUM</code>.
+ The default is 0.2 (20% of table size).
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-ANALYZE-SCALE-FACTOR"><span class="term"><code class="varname">autovacuum_analyze_scale_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.13.4.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a fraction of the table size to add to
+ <code class="varname">autovacuum_analyze_threshold</code>
+ when deciding whether to trigger an <code class="command">ANALYZE</code>.
+ The default is 0.1 (10% of table size).
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-FREEZE-MAX-AGE"><span class="term"><code class="varname">autovacuum_freeze_max_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum age (in transactions) that a table's
+ <code class="structname">pg_class</code>.<code class="structfield">relfrozenxid</code> field can
+ attain before a <code class="command">VACUUM</code> operation is forced
+ to prevent transaction ID wraparound within the table.
+ Note that the system will launch autovacuum processes to
+ prevent wraparound even when autovacuum is otherwise disabled.
+ </p><p>
+ Vacuum also allows removal of old files from the
+ <code class="filename">pg_xact</code> subdirectory, which is why the default
+ is a relatively low 200 million transactions.
+ This parameter can only be set at server start, but the setting
+ can be reduced for individual tables by
+ changing table storage parameters.
+ For more information see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>.
+ </p></dd><dt id="GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE"><span class="term"><code class="varname">autovacuum_multixact_freeze_max_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum age (in multixacts) that a table's
+ <code class="structname">pg_class</code>.<code class="structfield">relminmxid</code> field can
+ attain before a <code class="command">VACUUM</code> operation is forced to
+ prevent multixact ID wraparound within the table.
+ Note that the system will launch autovacuum processes to
+ prevent wraparound even when autovacuum is otherwise disabled.
+ </p><p>
+ Vacuuming multixacts also allows removal of old files from the
+ <code class="filename">pg_multixact/members</code> and <code class="filename">pg_multixact/offsets</code>
+ subdirectories, which is why the default is a relatively low
+ 400 million multixacts.
+ This parameter can only be set at server start, but the setting can
+ be reduced for individual tables by changing table storage parameters.
+ For more information see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND" title="25.1.5.1. Multixacts and Wraparound">Section 25.1.5.1</a>.
+ </p></dd><dt id="GUC-AUTOVACUUM-VACUUM-COST-DELAY"><span class="term"><code class="varname">autovacuum_vacuum_cost_delay</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.13.4.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the cost delay value that will be used in automatic
+ <code class="command">VACUUM</code> operations. If -1 is specified, the regular
+ <a class="xref" href="runtime-config-resource.html#GUC-VACUUM-COST-DELAY">vacuum_cost_delay</a> value will be used.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 2 milliseconds.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd><dt id="GUC-AUTOVACUUM-VACUUM-COST-LIMIT"><span class="term"><code class="varname">autovacuum_vacuum_cost_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.13.4.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the cost limit value that will be used in automatic
+ <code class="command">VACUUM</code> operations. If -1 is specified (which is the
+ default), the regular
+ <a class="xref" href="runtime-config-resource.html#GUC-VACUUM-COST-LIMIT">vacuum_cost_limit</a> value will be used. Note that
+ the value is distributed proportionally among the running autovacuum
+ workers, if there is more than one, so that the sum of the limits for
+ each worker does not exceed the value of this variable.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line;
+ but the setting can be overridden for individual tables by
+ changing table storage parameters.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-statistics.html" title="20.9. Run-time Statistics">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-client.html" title="20.11. Client Connection Defaults">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.9. Run-time Statistics </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.11. Client Connection Defaults</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-client.html b/doc/src/sgml/html/runtime-config-client.html
new file mode 100644
index 0000000..ba1128e
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-client.html
@@ -0,0 +1,854 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.11. Client Connection Defaults</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming" /><link rel="next" href="runtime-config-locks.html" title="20.12. Lock Management" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.11. Client Connection Defaults</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-locks.html" title="20.12. Lock Management">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-CLIENT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.11. Client Connection Defaults</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">20.11.1. Statement Behavior</a></span></dt><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">20.11.2. Locale and Formatting</a></span></dt><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">20.11.3. Shared Library Preloading</a></span></dt><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-OTHER">20.11.4. Other Defaults</a></span></dt></dl></div><div class="sect2" id="RUNTIME-CONFIG-CLIENT-STATEMENT"><div class="titlepage"><div><div><h3 class="title">20.11.1. Statement Behavior</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-CLIENT-MIN-MESSAGES"><span class="term"><code class="varname">client_min_messages</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls which
+ <a class="link" href="runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS" title="Table 20.2. Message Severity Levels">message levels</a>
+ are sent to the client.
+ Valid values are <code class="literal">DEBUG5</code>,
+ <code class="literal">DEBUG4</code>, <code class="literal">DEBUG3</code>, <code class="literal">DEBUG2</code>,
+ <code class="literal">DEBUG1</code>, <code class="literal">LOG</code>, <code class="literal">NOTICE</code>,
+ <code class="literal">WARNING</code>, and <code class="literal">ERROR</code>.
+ Each level includes all the levels that follow it. The later the level,
+ the fewer messages are sent. The default is
+ <code class="literal">NOTICE</code>. Note that <code class="literal">LOG</code> has a different
+ rank here than in <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a>.
+ </p><p>
+ <code class="literal">INFO</code> level messages are always sent to the client.
+ </p></dd><dt id="GUC-SEARCH-PATH"><span class="term"><code class="varname">search_path</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.2.2.2.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.2.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable specifies the order in which schemas are searched
+ when an object (table, data type, function, etc.) is referenced by a
+ simple name with no schema specified. When there are objects of
+ identical names in different schemas, the one found first
+ in the search path is used. An object that is not in any of the
+ schemas in the search path can only be referenced by specifying
+ its containing schema with a qualified (dotted) name.
+ </p><p>
+ The value for <code class="varname">search_path</code> must be a comma-separated
+ list of schema names. Any name that is not an existing schema, or is
+ a schema for which the user does not have <code class="literal">USAGE</code>
+ permission, is silently ignored.
+ </p><p>
+ If one of the list items is the special name
+ <code class="literal">$user</code>, then the schema having the name returned by
+ <code class="function">CURRENT_USER</code> is substituted, if there is such a schema
+ and the user has <code class="literal">USAGE</code> permission for it.
+ (If not, <code class="literal">$user</code> is ignored.)
+ </p><p>
+ The system catalog schema, <code class="literal">pg_catalog</code>, is always
+ searched, whether it is mentioned in the path or not. If it is
+ mentioned in the path then it will be searched in the specified
+ order. If <code class="literal">pg_catalog</code> is not in the path then it will
+ be searched <span class="emphasis"><em>before</em></span> searching any of the path items.
+ </p><p>
+ Likewise, the current session's temporary-table schema,
+ <code class="literal">pg_temp_<em class="replaceable"><code>nnn</code></em></code>, is always searched if it
+ exists. It can be explicitly listed in the path by using the
+ alias <code class="literal">pg_temp</code><a id="id-1.6.7.14.2.2.2.2.5.3" class="indexterm"></a>. If it is not listed in the path then
+ it is searched first (even before <code class="literal">pg_catalog</code>). However,
+ the temporary schema is only searched for relation (table, view,
+ sequence, etc.) and data type names. It is never searched for
+ function or operator names.
+ </p><p>
+ When objects are created without specifying a particular target
+ schema, they will be placed in the first valid schema named in
+ <code class="varname">search_path</code>. An error is reported if the search
+ path is empty.
+ </p><p>
+ The default value for this parameter is
+ <code class="literal">"$user", public</code>.
+ This setting supports shared use of a database (where no users
+ have private schemas, and all share use of <code class="literal">public</code>),
+ private per-user schemas, and combinations of these. Other
+ effects can be obtained by altering the default search path
+ setting, either globally or per-user.
+ </p><p>
+ For more information on schema handling, see
+ <a class="xref" href="ddl-schemas.html" title="5.9. Schemas">Section 5.9</a>. In particular, the default
+ configuration is suitable only when the database has a single user or
+ a few mutually-trusting users.
+ </p><p>
+ The current effective value of the search path can be examined
+ via the <acronym class="acronym">SQL</acronym> function
+ <code class="function">current_schemas</code>
+ (see <a class="xref" href="functions-info.html" title="9.26. System Information Functions and Operators">Section 9.26</a>).
+ This is not quite the same as
+ examining the value of <code class="varname">search_path</code>, since
+ <code class="function">current_schemas</code> shows how the items
+ appearing in <code class="varname">search_path</code> were resolved.
+ </p></dd><dt id="GUC-ROW-SECURITY"><span class="term"><code class="varname">row_security</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.14.2.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable controls whether to raise an error in lieu of applying a
+ row security policy. When set to <code class="literal">on</code>, policies apply
+ normally. When set to <code class="literal">off</code>, queries fail which would
+ otherwise apply at least one policy. The default is <code class="literal">on</code>.
+ Change to <code class="literal">off</code> where limited row visibility could cause
+ incorrect results; for example, <span class="application">pg_dump</span> makes that
+ change by default. This variable has no effect on roles which bypass
+ every row security policy, to wit, superusers and roles with
+ the <code class="literal">BYPASSRLS</code> attribute.
+ </p><p>
+ For more information on row security policies,
+ see <a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a>.
+ </p></dd><dt id="GUC-DEFAULT-TABLE-ACCESS-METHOD"><span class="term"><code class="varname">default_table_access_method</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.2.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies the default table access method to use when
+ creating tables or materialized views if the <code class="command">CREATE</code>
+ command does not explicitly specify an access method, or when
+ <code class="command">SELECT ... INTO</code> is used, which does not allow
+ specifying a table access method. The default is <code class="literal">heap</code>.
+ </p></dd><dt id="GUC-DEFAULT-TABLESPACE"><span class="term"><code class="varname">default_tablespace</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.2.2.5.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.5.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable specifies the default tablespace in which to create
+ objects (tables and indexes) when a <code class="command">CREATE</code> command does
+ not explicitly specify a tablespace.
+ </p><p>
+ The value is either the name of a tablespace, or an empty string
+ to specify using the default tablespace of the current database.
+ If the value does not match the name of any existing tablespace,
+ <span class="productname">PostgreSQL</span> will automatically use the default
+ tablespace of the current database. If a nondefault tablespace
+ is specified, the user must have <code class="literal">CREATE</code> privilege
+ for it, or creation attempts will fail.
+ </p><p>
+ This variable is not used for temporary tables; for them,
+ <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> is consulted instead.
+ </p><p>
+ This variable is also not used when creating databases.
+ By default, a new database inherits its tablespace setting from
+ the template database it is copied from.
+ </p><p>
+ If this parameter is set to a value other than the empty string
+ when a partitioned table is created, the partitioned table's
+ tablespace will be set to that value, which will be used as
+ the default tablespace for partitions created in the future,
+ even if <code class="varname">default_tablespace</code> has changed since then.
+ </p><p>
+ For more information on tablespaces,
+ see <a class="xref" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Section 23.6</a>.
+ </p></dd><dt id="GUC-DEFAULT-TOAST-COMPRESSION"><span class="term"><code class="varname">default_toast_compression</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable sets the default
+ <a class="link" href="storage-toast.html" title="73.2. TOAST">TOAST</a>
+ compression method for values of compressible columns.
+ (This can be overridden for individual columns by setting
+ the <code class="literal">COMPRESSION</code> column option in
+ <code class="command">CREATE TABLE</code> or
+ <code class="command">ALTER TABLE</code>.)
+ The supported compression methods are <code class="literal">pglz</code> and
+ (if <span class="productname">PostgreSQL</span> was compiled with
+ <code class="option">--with-lz4</code>) <code class="literal">lz4</code>.
+ The default is <code class="literal">pglz</code>.
+ </p></dd><dt id="GUC-TEMP-TABLESPACES"><span class="term"><code class="varname">temp_tablespaces</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.2.2.7.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.7.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable specifies tablespaces in which to create temporary
+ objects (temp tables and indexes on temp tables) when a
+ <code class="command">CREATE</code> command does not explicitly specify a tablespace.
+ Temporary files for purposes such as sorting large data sets
+ are also created in these tablespaces.
+ </p><p>
+ The value is a list of names of tablespaces. When there is more than
+ one name in the list, <span class="productname">PostgreSQL</span> chooses a random
+ member of the list each time a temporary object is to be created;
+ except that within a transaction, successively created temporary
+ objects are placed in successive tablespaces from the list.
+ If the selected element of the list is an empty string,
+ <span class="productname">PostgreSQL</span> will automatically use the default
+ tablespace of the current database instead.
+ </p><p>
+ When <code class="varname">temp_tablespaces</code> is set interactively, specifying a
+ nonexistent tablespace is an error, as is specifying a tablespace for
+ which the user does not have <code class="literal">CREATE</code> privilege. However,
+ when using a previously set value, nonexistent tablespaces are
+ ignored, as are tablespaces for which the user lacks
+ <code class="literal">CREATE</code> privilege. In particular, this rule applies when
+ using a value set in <code class="filename">postgresql.conf</code>.
+ </p><p>
+ The default value is an empty string, which results in all temporary
+ objects being created in the default tablespace of the current
+ database.
+ </p><p>
+ See also <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a>.
+ </p></dd><dt id="GUC-CHECK-FUNCTION-BODIES"><span class="term"><code class="varname">check_function_bodies</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.14.2.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter is normally on. When set to <code class="literal">off</code>, it
+ disables validation of the routine body string during <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> and <a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a>. Disabling validation avoids side
+ effects of the validation process, in particular preventing false
+ positives due to problems such as forward references.
+ Set this parameter
+ to <code class="literal">off</code> before loading functions on behalf of other
+ users; <span class="application">pg_dump</span> does so automatically.
+ </p></dd><dt id="GUC-DEFAULT-TRANSACTION-ISOLATION"><span class="term"><code class="varname">default_transaction_isolation</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.9.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.9.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Each SQL transaction has an isolation level, which can be
+ either <span class="quote">“<span class="quote">read uncommitted</span>”</span>, <span class="quote">“<span class="quote">read
+ committed</span>”</span>, <span class="quote">“<span class="quote">repeatable read</span>”</span>, or
+ <span class="quote">“<span class="quote">serializable</span>”</span>. This parameter controls the
+ default isolation level of each new transaction. The default
+ is <span class="quote">“<span class="quote">read committed</span>”</span>.
+ </p><p>
+ Consult <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a> and <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> for more information.
+ </p></dd><dt id="GUC-DEFAULT-TRANSACTION-READ-ONLY"><span class="term"><code class="varname">default_transaction_read_only</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.14.2.2.10.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.10.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ A read-only SQL transaction cannot alter non-temporary tables.
+ This parameter controls the default read-only status of each new
+ transaction. The default is <code class="literal">off</code> (read/write).
+ </p><p>
+ Consult <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> for more information.
+ </p></dd><dt id="GUC-DEFAULT-TRANSACTION-DEFERRABLE"><span class="term"><code class="varname">default_transaction_deferrable</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.14.2.2.11.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.11.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ When running at the <code class="literal">serializable</code> isolation level,
+ a deferrable read-only SQL transaction may be delayed before
+ it is allowed to proceed. However, once it begins executing
+ it does not incur any of the overhead required to ensure
+ serializability; so serialization code will have no reason to
+ force it to abort because of concurrent updates, making this
+ option suitable for long-running read-only transactions.
+ </p><p>
+ This parameter controls the default deferrable status of each
+ new transaction. It currently has no effect on read-write
+ transactions or those operating at isolation levels lower
+ than <code class="literal">serializable</code>. The default is <code class="literal">off</code>.
+ </p><p>
+ Consult <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> for more information.
+ </p></dd><dt id="GUC-TRANSACTION-ISOLATION"><span class="term"><code class="varname">transaction_isolation</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.12.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.12.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter reflects the current transaction's isolation level.
+ At the beginning of each transaction, it is set to the current value
+ of <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TRANSACTION-ISOLATION">default_transaction_isolation</a>.
+ Any subsequent attempt to change it is equivalent to a <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> command.
+ </p></dd><dt id="GUC-TRANSACTION-READ-ONLY"><span class="term"><code class="varname">transaction_read_only</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.14.2.2.13.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.13.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter reflects the current transaction's read-only status.
+ At the beginning of each transaction, it is set to the current value
+ of <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TRANSACTION-READ-ONLY">default_transaction_read_only</a>.
+ Any subsequent attempt to change it is equivalent to a <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> command.
+ </p></dd><dt id="GUC-TRANSACTION-DEFERRABLE"><span class="term"><code class="varname">transaction_deferrable</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.14.2.2.14.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.14.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter reflects the current transaction's deferrability status.
+ At the beginning of each transaction, it is set to the current value
+ of <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TRANSACTION-DEFERRABLE">default_transaction_deferrable</a>.
+ Any subsequent attempt to change it is equivalent to a <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> command.
+ </p></dd><dt id="GUC-SESSION-REPLICATION-ROLE"><span class="term"><code class="varname">session_replication_role</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.15.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls firing of replication-related triggers and rules for the
+ current session.
+ Possible values are <code class="literal">origin</code> (the default),
+ <code class="literal">replica</code> and <code class="literal">local</code>.
+ Setting this parameter results in discarding any previously cached
+ query plans.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ The intended use of this setting is that logical replication systems
+ set it to <code class="literal">replica</code> when they are applying replicated
+ changes. The effect of that will be that triggers and rules (that
+ have not been altered from their default configuration) will not fire
+ on the replica. See the <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a> clauses
+ <code class="literal">ENABLE TRIGGER</code> and <code class="literal">ENABLE RULE</code>
+ for more information.
+ </p><p>
+ PostgreSQL treats the settings <code class="literal">origin</code> and
+ <code class="literal">local</code> the same internally. Third-party replication
+ systems may use these two values for their internal purposes, for
+ example using <code class="literal">local</code> to designate a session whose
+ changes should not be replicated.
+ </p><p>
+ Since foreign keys are implemented as triggers, setting this parameter
+ to <code class="literal">replica</code> also disables all foreign key checks,
+ which can leave data in an inconsistent state if improperly used.
+ </p></dd><dt id="GUC-STATEMENT-TIMEOUT"><span class="term"><code class="varname">statement_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.16.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Abort any statement that takes more than the specified amount of time.
+ If <code class="varname">log_min_error_statement</code> is set
+ to <code class="literal">ERROR</code> or lower, the statement that timed out
+ will also be logged.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </p><p>
+ The timeout is measured from the time a command arrives at the
+ server until it is completed by the server. If multiple SQL
+ statements appear in a single simple-Query message, the timeout
+ is applied to each statement separately.
+ (<span class="productname">PostgreSQL</span> versions before 13 usually
+ treated the timeout as applying to the whole query string.)
+ In extended query protocol, the timeout starts running when any
+ query-related message (Parse, Bind, Execute, Describe) arrives, and
+ it is canceled by completion of an Execute or Sync message.
+ </p><p>
+ Setting <code class="varname">statement_timeout</code> in
+ <code class="filename">postgresql.conf</code> is not recommended because it would
+ affect all sessions.
+ </p></dd><dt id="GUC-LOCK-TIMEOUT"><span class="term"><code class="varname">lock_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.17.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Abort any statement that waits longer than the specified amount of
+ time while attempting to acquire a lock on a table, index,
+ row, or other database object. The time limit applies separately to
+ each lock acquisition attempt. The limit applies both to explicit
+ locking requests (such as <code class="command">LOCK TABLE</code>, or <code class="command">SELECT
+ FOR UPDATE</code> without <code class="literal">NOWAIT</code>) and to implicitly-acquired
+ locks.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </p><p>
+ Unlike <code class="varname">statement_timeout</code>, this timeout can only occur
+ while waiting for locks. Note that if <code class="varname">statement_timeout</code>
+ is nonzero, it is rather pointless to set <code class="varname">lock_timeout</code> to
+ the same or larger value, since the statement timeout would always
+ trigger first. If <code class="varname">log_min_error_statement</code> is set to
+ <code class="literal">ERROR</code> or lower, the statement that timed out will be
+ logged.
+ </p><p>
+ Setting <code class="varname">lock_timeout</code> in
+ <code class="filename">postgresql.conf</code> is not recommended because it would
+ affect all sessions.
+ </p></dd><dt id="GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT"><span class="term"><code class="varname">idle_in_transaction_session_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.18.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Terminate any session that has been idle (that is, waiting for a
+ client query) within an open transaction for longer than the
+ specified amount of time.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </p><p>
+ This option can be used to ensure that idle sessions do not hold
+ locks for an unreasonable amount of time. Even when no significant
+ locks are held, an open transaction prevents vacuuming away
+ recently-dead tuples that may be visible only to this transaction;
+ so remaining idle for a long time can contribute to table bloat.
+ See <a class="xref" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Section 25.1</a> for more details.
+ </p></dd><dt id="GUC-IDLE-SESSION-TIMEOUT"><span class="term"><code class="varname">idle_session_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.19.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Terminate any session that has been idle (that is, waiting for a
+ client query), but not within an open transaction, for longer than
+ the specified amount of time.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of zero (the default) disables the timeout.
+ </p><p>
+ Unlike the case with an open transaction, an idle session without a
+ transaction imposes no large costs on the server, so there is less
+ need to enable this timeout
+ than <code class="varname">idle_in_transaction_session_timeout</code>.
+ </p><p>
+ Be wary of enforcing this timeout on connections made through
+ connection-pooling software or other middleware, as such a layer
+ may not react well to unexpected connection closure. It may be
+ helpful to enable this timeout only for interactive sessions,
+ perhaps by applying it only to particular users.
+ </p></dd><dt id="GUC-VACUUM-FREEZE-TABLE-AGE"><span class="term"><code class="varname">vacuum_freeze_table_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.20.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="command">VACUUM</code> performs an aggressive scan if the table's
+ <code class="structname">pg_class</code>.<code class="structfield">relfrozenxid</code> field has reached
+ the age specified by this setting. An aggressive scan differs from
+ a regular <code class="command">VACUUM</code> in that it visits every page that might
+ contain unfrozen XIDs or MXIDs, not just those that might contain dead
+ tuples. The default is 150 million transactions. Although users can
+ set this value anywhere from zero to two billion, <code class="command">VACUUM</code>
+ will silently limit the effective value to 95% of
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a>, so that a
+ periodic manual <code class="command">VACUUM</code> has a chance to run before an
+ anti-wraparound autovacuum is launched for the table. For more
+ information see
+ <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>.
+ </p></dd><dt id="GUC-VACUUM-FREEZE-MIN-AGE"><span class="term"><code class="varname">vacuum_freeze_min_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.21.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the cutoff age (in transactions) that <code class="command">VACUUM</code>
+ should use to decide whether to freeze row versions
+ while scanning a table.
+ The default is 50 million transactions. Although
+ users can set this value anywhere from zero to one billion,
+ <code class="command">VACUUM</code> will silently limit the effective value to half
+ the value of <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a>, so
+ that there is not an unreasonably short time between forced
+ autovacuums. For more information see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>.
+ </p></dd><dt id="GUC-VACUUM-FAILSAFE-AGE"><span class="term"><code class="varname">vacuum_failsafe_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.22.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum age (in transactions) that a table's
+ <code class="structname">pg_class</code>.<code class="structfield">relfrozenxid</code>
+ field can attain before <code class="command">VACUUM</code> takes
+ extraordinary measures to avoid system-wide transaction ID
+ wraparound failure. This is <code class="command">VACUUM</code>'s
+ strategy of last resort. The failsafe typically triggers
+ when an autovacuum to prevent transaction ID wraparound has
+ already been running for some time, though it's possible for
+ the failsafe to trigger during any <code class="command">VACUUM</code>.
+ </p><p>
+ When the failsafe is triggered, any cost-based delay that is
+ in effect will no longer be applied, and further non-essential
+ maintenance tasks (such as index vacuuming) are bypassed.
+ </p><p>
+ The default is 1.6 billion transactions. Although users can
+ set this value anywhere from zero to 2.1 billion,
+ <code class="command">VACUUM</code> will silently adjust the effective
+ value to no less than 105% of <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a>.
+ </p></dd><dt id="GUC-VACUUM-MULTIXACT-FREEZE-TABLE-AGE"><span class="term"><code class="varname">vacuum_multixact_freeze_table_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.23.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="command">VACUUM</code> performs an aggressive scan if the table's
+ <code class="structname">pg_class</code>.<code class="structfield">relminmxid</code> field has reached
+ the age specified by this setting. An aggressive scan differs from
+ a regular <code class="command">VACUUM</code> in that it visits every page that might
+ contain unfrozen XIDs or MXIDs, not just those that might contain dead
+ tuples. The default is 150 million multixacts.
+ Although users can set this value anywhere from zero to two billion,
+ <code class="command">VACUUM</code> will silently limit the effective value to 95% of
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE">autovacuum_multixact_freeze_max_age</a>, so that a
+ periodic manual <code class="command">VACUUM</code> has a chance to run before an
+ anti-wraparound is launched for the table.
+ For more information see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND" title="25.1.5.1. Multixacts and Wraparound">Section 25.1.5.1</a>.
+ </p></dd><dt id="GUC-VACUUM-MULTIXACT-FREEZE-MIN-AGE"><span class="term"><code class="varname">vacuum_multixact_freeze_min_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.24.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the cutoff age (in multixacts) that <code class="command">VACUUM</code>
+ should use to decide whether to replace multixact IDs with a newer
+ transaction ID or multixact ID while scanning a table. The default
+ is 5 million multixacts.
+ Although users can set this value anywhere from zero to one billion,
+ <code class="command">VACUUM</code> will silently limit the effective value to half
+ the value of <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE">autovacuum_multixact_freeze_max_age</a>,
+ so that there is not an unreasonably short time between forced
+ autovacuums.
+ For more information see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND" title="25.1.5.1. Multixacts and Wraparound">Section 25.1.5.1</a>.
+ </p></dd><dt id="GUC-VACUUM-MULTIXACT-FAILSAFE-AGE"><span class="term"><code class="varname">vacuum_multixact_failsafe_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.25.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum age (in multixacts) that a table's
+ <code class="structname">pg_class</code>.<code class="structfield">relminmxid</code>
+ field can attain before <code class="command">VACUUM</code> takes
+ extraordinary measures to avoid system-wide multixact ID
+ wraparound failure. This is <code class="command">VACUUM</code>'s
+ strategy of last resort. The failsafe typically triggers when
+ an autovacuum to prevent transaction ID wraparound has already
+ been running for some time, though it's possible for the
+ failsafe to trigger during any <code class="command">VACUUM</code>.
+ </p><p>
+ When the failsafe is triggered, any cost-based delay that is
+ in effect will no longer be applied, and further non-essential
+ maintenance tasks (such as index vacuuming) are bypassed.
+ </p><p>
+ The default is 1.6 billion multixacts. Although users can set
+ this value anywhere from zero to 2.1 billion,
+ <code class="command">VACUUM</code> will silently adjust the effective
+ value to no less than 105% of <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE">autovacuum_multixact_freeze_max_age</a>.
+ </p></dd><dt id="GUC-BYTEA-OUTPUT"><span class="term"><code class="varname">bytea_output</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.26.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the output format for values of type <code class="type">bytea</code>.
+ Valid values are <code class="literal">hex</code> (the default)
+ and <code class="literal">escape</code> (the traditional PostgreSQL
+ format). See <a class="xref" href="datatype-binary.html" title="8.4. Binary Data Types">Section 8.4</a> for more
+ information. The <code class="type">bytea</code> type always
+ accepts both formats on input, regardless of this setting.
+ </p></dd><dt id="GUC-XMLBINARY"><span class="term"><code class="varname">xmlbinary</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.27.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets how binary values are to be encoded in XML. This applies
+ for example when <code class="type">bytea</code> values are converted to
+ XML by the functions <code class="function">xmlelement</code> or
+ <code class="function">xmlforest</code>. Possible values are
+ <code class="literal">base64</code> and <code class="literal">hex</code>, which
+ are both defined in the XML Schema standard. The default is
+ <code class="literal">base64</code>. For further information about
+ XML-related functions, see <a class="xref" href="functions-xml.html" title="9.15. XML Functions">Section 9.15</a>.
+ </p><p>
+ The actual choice here is mostly a matter of taste,
+ constrained only by possible restrictions in client
+ applications. Both methods support all possible values,
+ although the hex encoding will be somewhat larger than the
+ base64 encoding.
+ </p></dd><dt id="GUC-XMLOPTION"><span class="term"><code class="varname">xmloption</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.2.2.28.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.28.1.4" class="indexterm"></a>
+ <a id="id-1.6.7.14.2.2.28.1.5" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets whether <code class="literal">DOCUMENT</code> or
+ <code class="literal">CONTENT</code> is implicit when converting between
+ XML and character string values. See <a class="xref" href="datatype-xml.html" title="8.13. XML Type">Section 8.13</a> for a description of this. Valid
+ values are <code class="literal">DOCUMENT</code> and
+ <code class="literal">CONTENT</code>. The default is
+ <code class="literal">CONTENT</code>.
+ </p><p>
+ According to the SQL standard, the command to set this option is
+</p><pre class="synopsis">
+SET XML OPTION { DOCUMENT | CONTENT };
+</pre><p>
+ This syntax is also available in PostgreSQL.
+ </p></dd><dt id="GUC-GIN-PENDING-LIST-LIMIT"><span class="term"><code class="varname">gin_pending_list_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.2.2.29.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum size of a GIN index's pending list, which is used
+ when <code class="literal">fastupdate</code> is enabled. If the list grows
+ larger than this maximum size, it is cleaned up by moving
+ the entries in it to the index's main GIN data structure in bulk.
+ If this value is specified without units, it is taken as kilobytes.
+ The default is four megabytes (<code class="literal">4MB</code>). This setting
+ can be overridden for individual GIN indexes by changing
+ index storage parameters.
+ See <a class="xref" href="gin-implementation.html#GIN-FAST-UPDATE" title="70.4.1. GIN Fast Update Technique">Section 70.4.1</a> and <a class="xref" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Section 70.5</a>
+ for more information.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-CLIENT-FORMAT"><div class="titlepage"><div><div><h3 class="title">20.11.2. Locale and Formatting</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-DATESTYLE"><span class="term"><code class="varname">DateStyle</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the display format for date and time values, as well as the
+ rules for interpreting ambiguous date input values. For
+ historical reasons, this variable contains two independent
+ components: the output format specification (<code class="literal">ISO</code>,
+ <code class="literal">Postgres</code>, <code class="literal">SQL</code>, or <code class="literal">German</code>)
+ and the input/output specification for year/month/day ordering
+ (<code class="literal">DMY</code>, <code class="literal">MDY</code>, or <code class="literal">YMD</code>). These
+ can be set separately or together. The keywords <code class="literal">Euro</code>
+ and <code class="literal">European</code> are synonyms for <code class="literal">DMY</code>; the
+ keywords <code class="literal">US</code>, <code class="literal">NonEuro</code>, and
+ <code class="literal">NonEuropean</code> are synonyms for <code class="literal">MDY</code>. See
+ <a class="xref" href="datatype-datetime.html" title="8.5. Date/Time Types">Section 8.5</a> for more information. The
+ built-in default is <code class="literal">ISO, MDY</code>, but
+ <span class="application">initdb</span> will initialize the
+ configuration file with a setting that corresponds to the
+ behavior of the chosen <code class="varname">lc_time</code> locale.
+ </p></dd><dt id="GUC-INTERVALSTYLE"><span class="term"><code class="varname">IntervalStyle</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.14.3.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the display format for interval values.
+ The value <code class="literal">sql_standard</code> will produce
+ output matching <acronym class="acronym">SQL</acronym> standard interval literals.
+ The value <code class="literal">postgres</code> (which is the default) will produce
+ output matching <span class="productname">PostgreSQL</span> releases prior to 8.4
+ when the <a class="xref" href="runtime-config-client.html#GUC-DATESTYLE">DateStyle</a>
+ parameter was set to <code class="literal">ISO</code>.
+ The value <code class="literal">postgres_verbose</code> will produce output
+ matching <span class="productname">PostgreSQL</span> releases prior to 8.4
+ when the <code class="varname">DateStyle</code>
+ parameter was set to non-<code class="literal">ISO</code> output.
+ The value <code class="literal">iso_8601</code> will produce output matching the time
+ interval <span class="quote">“<span class="quote">format with designators</span>”</span> defined in section
+ 4.4.3.2 of ISO 8601.
+ </p><p>
+ The <code class="varname">IntervalStyle</code> parameter also affects the
+ interpretation of ambiguous interval input. See
+ <a class="xref" href="datatype-datetime.html#DATATYPE-INTERVAL-INPUT" title="8.5.4. Interval Input">Section 8.5.4</a> for more information.
+ </p></dd><dt id="GUC-TIMEZONE"><span class="term"><code class="varname">TimeZone</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.3.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.3.2.3.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the time zone for displaying and interpreting time stamps.
+ The built-in default is <code class="literal">GMT</code>, but that is typically
+ overridden in <code class="filename">postgresql.conf</code>; <span class="application">initdb</span>
+ will install a setting there corresponding to its system environment.
+ See <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a> for more information.
+ </p></dd><dt id="GUC-TIMEZONE-ABBREVIATIONS"><span class="term"><code class="varname">timezone_abbreviations</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.4.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.3.2.4.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the collection of time zone abbreviations that will be accepted
+ by the server for datetime input. The default is <code class="literal">'Default'</code>,
+ which is a collection that works in most of the world; there are
+ also <code class="literal">'Australia'</code> and <code class="literal">'India'</code>,
+ and other collections can be defined for a particular installation.
+ See <a class="xref" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Section B.4</a> for more information.
+ </p></dd><dt id="GUC-EXTRA-FLOAT-DIGITS"><span class="term"><code class="varname">extra_float_digits</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.3.2.5.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.3.2.5.1.4" class="indexterm"></a>
+ <a id="id-1.6.7.14.3.2.5.1.5" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter adjusts the number of digits used for textual output of
+ floating-point values, including <code class="type">float4</code>, <code class="type">float8</code>,
+ and geometric data types.
+ </p><p>
+ If the value is 1 (the default) or above, float values are output in
+ shortest-precise format; see <a class="xref" href="datatype-numeric.html#DATATYPE-FLOAT" title="8.1.3. Floating-Point Types">Section 8.1.3</a>. The
+ actual number of digits generated depends only on the value being
+ output, not on the value of this parameter. At most 17 digits are
+ required for <code class="type">float8</code> values, and 9 for <code class="type">float4</code>
+ values. This format is both fast and precise, preserving the original
+ binary float value exactly when correctly read. For historical
+ compatibility, values up to 3 are permitted.
+ </p><p>
+ If the value is zero or negative, then the output is rounded to a
+ given decimal precision. The precision used is the standard number of
+ digits for the type (<code class="literal">FLT_DIG</code>
+ or <code class="literal">DBL_DIG</code> as appropriate) reduced according to the
+ value of this parameter. (For example, specifying -1 will cause
+ <code class="type">float4</code> values to be output rounded to 5 significant
+ digits, and <code class="type">float8</code> values
+ rounded to 14 digits.) This format is slower and does not preserve all
+ the bits of the binary float value, but may be more human-readable.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The meaning of this parameter, and its default value, changed
+ in <span class="productname">PostgreSQL</span> 12;
+ see <a class="xref" href="datatype-numeric.html#DATATYPE-FLOAT" title="8.1.3. Floating-Point Types">Section 8.1.3</a> for further discussion.
+ </p></div></dd><dt id="GUC-CLIENT-ENCODING"><span class="term"><code class="varname">client_encoding</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.6.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.3.2.6.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the client-side encoding (character set).
+ The default is to use the database encoding.
+ The character sets supported by the <span class="productname">PostgreSQL</span>
+ server are described in <a class="xref" href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED" title="24.3.1. Supported Character Sets">Section 24.3.1</a>.
+ </p></dd><dt id="GUC-LC-MESSAGES"><span class="term"><code class="varname">lc_messages</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the language in which messages are displayed. Acceptable
+ values are system-dependent; see <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> for
+ more information. If this variable is set to the empty string
+ (which is the default) then the value is inherited from the
+ execution environment of the server in a system-dependent way.
+ </p><p>
+ On some systems, this locale category does not exist. Setting
+ this variable will still work, but there will be no effect.
+ Also, there is a chance that no translated messages for the
+ desired language exist. In that case you will continue to see
+ the English messages.
+ </p><p>
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LC-MONETARY"><span class="term"><code class="varname">lc_monetary</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the locale to use for formatting monetary amounts, for
+ example with the <code class="function">to_char</code> family of
+ functions. Acceptable values are system-dependent; see <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> for more information. If this variable is
+ set to the empty string (which is the default) then the value
+ is inherited from the execution environment of the server in a
+ system-dependent way.
+ </p></dd><dt id="GUC-LC-NUMERIC"><span class="term"><code class="varname">lc_numeric</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the locale to use for formatting numbers, for example
+ with the <code class="function">to_char</code> family of
+ functions. Acceptable values are system-dependent; see <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> for more information. If this variable is
+ set to the empty string (which is the default) then the value
+ is inherited from the execution environment of the server in a
+ system-dependent way.
+ </p></dd><dt id="GUC-LC-TIME"><span class="term"><code class="varname">lc_time</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the locale to use for formatting dates and times, for example
+ with the <code class="function">to_char</code> family of
+ functions. Acceptable values are system-dependent; see <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> for more information. If this variable is
+ set to the empty string (which is the default) then the value
+ is inherited from the execution environment of the server in a
+ system-dependent way.
+ </p></dd><dt id="GUC-DEFAULT-TEXT-SEARCH-CONFIG"><span class="term"><code class="varname">default_text_search_config</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.3.2.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Selects the text search configuration that is used by those variants
+ of the text search functions that do not have an explicit argument
+ specifying the configuration.
+ See <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for further information.
+ The built-in default is <code class="literal">pg_catalog.simple</code>, but
+ <span class="application">initdb</span> will initialize the
+ configuration file with a setting that corresponds to the
+ chosen <code class="varname">lc_ctype</code> locale, if a configuration
+ matching that locale can be identified.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-CLIENT-PRELOAD"><div class="titlepage"><div><div><h3 class="title">20.11.3. Shared Library Preloading</h3></div></div></div><p>
+ Several settings are available for preloading shared libraries into the
+ server, in order to load additional functionality or achieve performance
+ benefits. For example, a setting of
+ <code class="literal">'$libdir/mylib'</code> would cause
+ <code class="literal">mylib.so</code> (or on some platforms,
+ <code class="literal">mylib.sl</code>) to be preloaded from the installation's standard
+ library directory. The differences between the settings are when they
+ take effect and what privileges are required to change them.
+ </p><p>
+ <span class="productname">PostgreSQL</span> procedural language libraries can
+ be preloaded in this way, typically by using the
+ syntax <code class="literal">'$libdir/plXXX'</code> where
+ <code class="literal">XXX</code> is <code class="literal">pgsql</code>, <code class="literal">perl</code>,
+ <code class="literal">tcl</code>, or <code class="literal">python</code>.
+ </p><p>
+ Only shared libraries specifically intended to be used with PostgreSQL
+ can be loaded this way. Every PostgreSQL-supported library has
+ a <span class="quote">“<span class="quote">magic block</span>”</span> that is checked to guarantee compatibility. For
+ this reason, non-PostgreSQL libraries cannot be loaded in this way. You
+ might be able to use operating-system facilities such
+ as <code class="envar">LD_PRELOAD</code> for that.
+ </p><p>
+ In general, refer to the documentation of a specific module for the
+ recommended way to load that module.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-LOCAL-PRELOAD-LIBRARIES"><span class="term"><code class="varname">local_preload_libraries</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.4.6.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.4.6.1.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable specifies one or more shared libraries that are to be
+ preloaded at connection start.
+ It contains a comma-separated list of library names, where each name
+ is interpreted as for the <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command.
+ Whitespace between entries is ignored; surround a library name with
+ double quotes if you need to include whitespace or commas in the name.
+ The parameter value only takes effect at the start of the connection.
+ Subsequent changes have no effect. If a specified library is not
+ found, the connection attempt will fail.
+ </p><p>
+ This option can be set by any user. Because of that, the libraries
+ that can be loaded are restricted to those appearing in the
+ <code class="filename">plugins</code> subdirectory of the installation's
+ standard library directory. (It is the database administrator's
+ responsibility to ensure that only <span class="quote">“<span class="quote">safe</span>”</span> libraries
+ are installed there.) Entries in <code class="varname">local_preload_libraries</code>
+ can specify this directory explicitly, for example
+ <code class="literal">$libdir/plugins/mylib</code>, or just specify
+ the library name — <code class="literal">mylib</code> would have
+ the same effect as <code class="literal">$libdir/plugins/mylib</code>.
+ </p><p>
+ The intent of this feature is to allow unprivileged users to load
+ debugging or performance-measurement libraries into specific sessions
+ without requiring an explicit <code class="command">LOAD</code> command. To that end,
+ it would be typical to set this parameter using
+ the <code class="envar">PGOPTIONS</code> environment variable on the client or by
+ using
+ <code class="command">ALTER ROLE SET</code>.
+ </p><p>
+ However, unless a module is specifically designed to be used in this way by
+ non-superusers, this is usually not the right setting to use. Look
+ at <a class="xref" href="runtime-config-client.html#GUC-SESSION-PRELOAD-LIBRARIES">session_preload_libraries</a> instead.
+ </p></dd><dt id="GUC-SESSION-PRELOAD-LIBRARIES"><span class="term"><code class="varname">session_preload_libraries</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.4.6.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable specifies one or more shared libraries that are to be
+ preloaded at connection start.
+ It contains a comma-separated list of library names, where each name
+ is interpreted as for the <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command.
+ Whitespace between entries is ignored; surround a library name with
+ double quotes if you need to include whitespace or commas in the name.
+ The parameter value only takes effect at the start of the connection.
+ Subsequent changes have no effect. If a specified library is not
+ found, the connection attempt will fail.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ The intent of this feature is to allow debugging or
+ performance-measurement libraries to be loaded into specific sessions
+ without an explicit
+ <code class="command">LOAD</code> command being given. For
+ example, <a class="xref" href="auto-explain.html" title="F.4. auto_explain">auto_explain</a> could be enabled for all
+ sessions under a given user name by setting this parameter
+ with <code class="command">ALTER ROLE SET</code>. Also, this parameter can be changed
+ without restarting the server (but changes only take effect when a new
+ session is started), so it is easier to add new modules this way, even
+ if they should apply to all sessions.
+ </p><p>
+ Unlike <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a>, there is no large
+ performance advantage to loading a library at session start rather than
+ when it is first used. There is some advantage, however, when
+ connection pooling is used.
+ </p></dd><dt id="GUC-SHARED-PRELOAD-LIBRARIES"><span class="term"><code class="varname">shared_preload_libraries</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.4.6.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable specifies one or more shared libraries to be preloaded at
+ server start.
+ It contains a comma-separated list of library names, where each name
+ is interpreted as for the <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command.
+ Whitespace between entries is ignored; surround a library name with
+ double quotes if you need to include whitespace or commas in the name.
+ This parameter can only be set at server start. If a specified
+ library is not found, the server will fail to start.
+ </p><p>
+ Some libraries need to perform certain operations that can only take
+ place at postmaster start, such as allocating shared memory, reserving
+ light-weight locks, or starting background workers. Those libraries
+ must be loaded at server start through this parameter. See the
+ documentation of each library for details.
+ </p><p>
+ Other libraries can also be preloaded. By preloading a shared library,
+ the library startup time is avoided when the library is first used.
+ However, the time to start each new server process might increase
+ slightly, even if that process never uses the library. So this
+ parameter is recommended only for libraries that will be used in most
+ sessions. Also, changing this parameter requires a server restart, so
+ this is not the right setting to use for short-term debugging tasks,
+ say. Use <a class="xref" href="runtime-config-client.html#GUC-SESSION-PRELOAD-LIBRARIES">session_preload_libraries</a> for that
+ instead.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ On Windows hosts, preloading a library at server start will not reduce
+ the time required to start each new server process; each server process
+ will re-load all preload libraries. However, <code class="varname">shared_preload_libraries
+ </code> is still useful on Windows hosts for libraries that need to
+ perform operations at postmaster start time.
+ </p></div></dd><dt id="GUC-JIT-PROVIDER"><span class="term"><code class="varname">jit_provider</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.4.6.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This variable is the name of the JIT provider library to be used
+ (see <a class="xref" href="jit-extensibility.html#JIT-PLUGGABLE" title="32.4.2. Pluggable JIT Providers">Section 32.4.2</a>).
+ The default is <code class="literal">llvmjit</code>.
+ This parameter can only be set at server start.
+ </p><p>
+ If set to a non-existent library, <acronym class="acronym">JIT</acronym> will not be
+ available, but no error will be raised. This allows JIT support to be
+ installed separately from the main
+ <span class="productname">PostgreSQL</span> package.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-CLIENT-OTHER"><div class="titlepage"><div><div><h3 class="title">20.11.4. Other Defaults</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-DYNAMIC-LIBRARY-PATH"><span class="term"><code class="varname">dynamic_library_path</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.14.5.2.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.14.5.2.1.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ If a dynamically loadable module needs to be opened and the
+ file name specified in the <code class="command">CREATE FUNCTION</code> or
+ <code class="command">LOAD</code> command
+ does not have a directory component (i.e., the
+ name does not contain a slash), the system will search this
+ path for the required file.
+ </p><p>
+ The value for <code class="varname">dynamic_library_path</code> must be a
+ list of absolute directory paths separated by colons (or semi-colons
+ on Windows). If a list element starts
+ with the special string <code class="literal">$libdir</code>, the
+ compiled-in <span class="productname">PostgreSQL</span> package
+ library directory is substituted for <code class="literal">$libdir</code>; this
+ is where the modules provided by the standard
+ <span class="productname">PostgreSQL</span> distribution are installed.
+ (Use <code class="literal">pg_config --pkglibdir</code> to find out the name of
+ this directory.) For example:
+</p><pre class="programlisting">
+dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
+</pre><p>
+ or, in a Windows environment:
+</p><pre class="programlisting">
+dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
+</pre><p>
+ </p><p>
+ The default value for this parameter is
+ <code class="literal">'$libdir'</code>. If the value is set to an empty
+ string, the automatic path search is turned off.
+ </p><p>
+ This parameter can be changed at run time by superusers and users
+ with the appropriate <code class="literal">SET</code> privilege, but a
+ setting done that way will only persist until the end of the
+ client connection, so this method should be reserved for
+ development purposes. The recommended way to set this parameter
+ is in the <code class="filename">postgresql.conf</code> configuration
+ file.
+ </p></dd><dt id="GUC-GIN-FUZZY-SEARCH-LIMIT"><span class="term"><code class="varname">gin_fuzzy_search_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.14.5.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Soft upper limit of the size of the set returned by GIN index scans. For more
+ information see <a class="xref" href="gin-tips.html" title="70.5. GIN Tips and Tricks">Section 70.5</a>.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-locks.html" title="20.12. Lock Management">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.10. Automatic Vacuuming </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.12. Lock Management</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-compatible.html b/doc/src/sgml/html/runtime-config-compatible.html
new file mode 100644
index 0000000..04639fe
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-compatible.html
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.13. Version and Platform Compatibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-locks.html" title="20.12. Lock Management" /><link rel="next" href="runtime-config-error-handling.html" title="20.14. Error Handling" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.13. Version and Platform Compatibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-locks.html" title="20.12. Lock Management">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-error-handling.html" title="20.14. Error Handling">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-COMPATIBLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.13. Version and Platform Compatibility</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">20.13.1. Previous PostgreSQL Versions</a></span></dt><dt><span class="sect2"><a href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-CLIENTS">20.13.2. Platform and Client Compatibility</a></span></dt></dl></div><div class="sect2" id="RUNTIME-CONFIG-COMPATIBLE-VERSION"><div class="titlepage"><div><div><h3 class="title">20.13.1. Previous PostgreSQL Versions</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-ARRAY-NULLS"><span class="term"><code class="varname">array_nulls</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.2.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This controls whether the array input parser recognizes
+ unquoted <code class="literal">NULL</code> as specifying a null array element.
+ By default, this is <code class="literal">on</code>, allowing array values containing
+ null values to be entered. However, <span class="productname">PostgreSQL</span> versions
+ before 8.2 did not support null values in arrays, and therefore would
+ treat <code class="literal">NULL</code> as specifying a normal array element with
+ the string value <span class="quote">“<span class="quote">NULL</span>”</span>. For backward compatibility with
+ applications that require the old behavior, this variable can be
+ turned <code class="literal">off</code>.
+ </p><p>
+ Note that it is possible to create array values containing null values
+ even when this variable is <code class="literal">off</code>.
+ </p></dd><dt id="GUC-BACKSLASH-QUOTE"><span class="term"><code class="varname">backslash_quote</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.16.2.2.2.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.16.2.2.2.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This controls whether a quote mark can be represented by
+ <code class="literal">\'</code> in a string literal. The preferred, SQL-standard way
+ to represent a quote mark is by doubling it (<code class="literal">''</code>) but
+ <span class="productname">PostgreSQL</span> has historically also accepted
+ <code class="literal">\'</code>. However, use of <code class="literal">\'</code> creates security risks
+ because in some client character set encodings, there are multibyte
+ characters in which the last byte is numerically equivalent to ASCII
+ <code class="literal">\</code>. If client-side code does escaping incorrectly then an
+ SQL-injection attack is possible. This risk can be prevented by
+ making the server reject queries in which a quote mark appears to be
+ escaped by a backslash.
+ The allowed values of <code class="varname">backslash_quote</code> are
+ <code class="literal">on</code> (allow <code class="literal">\'</code> always),
+ <code class="literal">off</code> (reject always), and
+ <code class="literal">safe_encoding</code> (allow only if client encoding does not
+ allow ASCII <code class="literal">\</code> within a multibyte character).
+ <code class="literal">safe_encoding</code> is the default setting.
+ </p><p>
+ Note that in a standard-conforming string literal, <code class="literal">\</code> just
+ means <code class="literal">\</code> anyway. This parameter only affects the handling of
+ non-standard-conforming literals, including
+ escape string syntax (<code class="literal">E'...'</code>).
+ </p></dd><dt id="GUC-ESCAPE-STRING-WARNING"><span class="term"><code class="varname">escape_string_warning</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.2.2.3.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.16.2.2.3.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ When on, a warning is issued if a backslash (<code class="literal">\</code>)
+ appears in an ordinary string literal (<code class="literal">'...'</code>
+ syntax) and <code class="varname">standard_conforming_strings</code> is off.
+ The default is <code class="literal">on</code>.
+ </p><p>
+ Applications that wish to use backslash as escape should be
+ modified to use escape string syntax (<code class="literal">E'...'</code>),
+ because the default behavior of ordinary strings is now to treat
+ backslash as an ordinary character, per SQL standard. This variable
+ can be enabled to help locate code that needs to be changed.
+ </p></dd><dt id="GUC-LO-COMPAT-PRIVILEGES"><span class="term"><code class="varname">lo_compat_privileges</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.2.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ In <span class="productname">PostgreSQL</span> releases prior to 9.0, large objects
+ did not have access privileges and were, therefore, always readable
+ and writable by all users. Setting this variable to <code class="literal">on</code>
+ disables the new privilege checks, for compatibility with prior
+ releases. The default is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ Setting this variable does not disable all security checks related to
+ large objects — only those for which the default behavior has
+ changed in <span class="productname">PostgreSQL</span> 9.0.
+ </p></dd><dt id="GUC-QUOTE-ALL-IDENTIFIERS"><span class="term"><code class="varname">quote_all_identifiers</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.2.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When the database generates SQL, force all identifiers to be quoted,
+ even if they are not (currently) keywords. This will affect the
+ output of <code class="command">EXPLAIN</code> as well as the results of functions
+ like <code class="function">pg_get_viewdef</code>. See also the
+ <code class="option">--quote-all-identifiers</code> option of
+ <a class="xref" href="app-pgdump.html" title="pg_dump"><span class="refentrytitle"><span class="application">pg_dump</span></span></a> and <a class="xref" href="app-pg-dumpall.html" title="pg_dumpall"><span class="refentrytitle"><span class="application">pg_dumpall</span></span></a>.
+ </p></dd><dt id="GUC-STANDARD-CONFORMING-STRINGS"><span class="term"><code class="varname">standard_conforming_strings</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.2.2.6.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.16.2.2.6.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ This controls whether ordinary string literals
+ (<code class="literal">'...'</code>) treat backslashes literally, as specified in
+ the SQL standard.
+ Beginning in <span class="productname">PostgreSQL</span> 9.1, the default is
+ <code class="literal">on</code> (prior releases defaulted to <code class="literal">off</code>).
+ Applications can check this
+ parameter to determine how string literals will be processed.
+ The presence of this parameter can also be taken as an indication
+ that the escape string syntax (<code class="literal">E'...'</code>) is supported.
+ Escape string syntax (<a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE" title="4.1.2.2. String Constants with C-Style Escapes">Section 4.1.2.2</a>)
+ should be used if an application desires
+ backslashes to be treated as escape characters.
+ </p></dd><dt id="GUC-SYNCHRONIZE-SEQSCANS"><span class="term"><code class="varname">synchronize_seqscans</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.2.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This allows sequential scans of large tables to synchronize with each
+ other, so that concurrent scans read the same block at about the
+ same time and hence share the I/O workload. When this is enabled,
+ a scan might start in the middle of the table and then <span class="quote">“<span class="quote">wrap
+ around</span>”</span> the end to cover all rows, so as to synchronize with the
+ activity of scans already in progress. This can result in
+ unpredictable changes in the row ordering returned by queries that
+ have no <code class="literal">ORDER BY</code> clause. Setting this parameter to
+ <code class="literal">off</code> ensures the pre-8.3 behavior in which a sequential
+ scan always starts from the beginning of the table. The default
+ is <code class="literal">on</code>.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-COMPATIBLE-CLIENTS"><div class="titlepage"><div><div><h3 class="title">20.13.2. Platform and Client Compatibility</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-TRANSFORM-NULL-EQUALS"><span class="term"><code class="varname">transform_null_equals</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.16.3.2.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.16.3.2.1.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ When on, expressions of the form <code class="literal"><em class="replaceable"><code>expr</code></em> =
+ NULL</code> (or <code class="literal">NULL =
+ <em class="replaceable"><code>expr</code></em></code>) are treated as
+ <code class="literal"><em class="replaceable"><code>expr</code></em> IS NULL</code>, that is, they
+ return true if <em class="replaceable"><code>expr</code></em> evaluates to the null value,
+ and false otherwise. The correct SQL-spec-compliant behavior of
+ <code class="literal"><em class="replaceable"><code>expr</code></em> = NULL</code> is to always
+ return null (unknown). Therefore this parameter defaults to
+ <code class="literal">off</code>.
+ </p><p>
+ However, filtered forms in <span class="productname">Microsoft
+ Access</span> generate queries that appear to use
+ <code class="literal"><em class="replaceable"><code>expr</code></em> = NULL</code> to test for
+ null values, so if you use that interface to access the database you
+ might want to turn this option on. Since expressions of the
+ form <code class="literal"><em class="replaceable"><code>expr</code></em> = NULL</code> always
+ return the null value (using the SQL standard interpretation), they are not
+ very useful and do not appear often in normal applications so
+ this option does little harm in practice. But new users are
+ frequently confused about the semantics of expressions
+ involving null values, so this option is off by default.
+ </p><p>
+ Note that this option only affects the exact form <code class="literal">= NULL</code>,
+ not other comparison operators or other expressions
+ that are computationally equivalent to some expression
+ involving the equals operator (such as <code class="literal">IN</code>).
+ Thus, this option is not a general fix for bad programming.
+ </p><p>
+ Refer to <a class="xref" href="functions-comparison.html" title="9.2. Comparison Functions and Operators">Section 9.2</a> for related information.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-locks.html" title="20.12. Lock Management">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-error-handling.html" title="20.14. Error Handling">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.12. Lock Management </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.14. Error Handling</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-connection.html b/doc/src/sgml/html/runtime-config-connection.html
new file mode 100644
index 0000000..554befe
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-connection.html
@@ -0,0 +1,542 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.3. Connections and Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-file-locations.html" title="20.2. File Locations" /><link rel="next" href="runtime-config-resource.html" title="20.4. Resource Consumption" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.3. Connections and Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-file-locations.html" title="20.2. File Locations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-resource.html" title="20.4. Resource Consumption">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-CONNECTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.3. Connections and Authentication</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">20.3.1. Connection Settings</a></span></dt><dt><span class="sect2"><a href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">20.3.2. Authentication</a></span></dt><dt><span class="sect2"><a href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">20.3.3. SSL</a></span></dt></dl></div><div class="sect2" id="RUNTIME-CONFIG-CONNECTION-SETTINGS"><div class="titlepage"><div><div><h3 class="title">20.3.1. Connection Settings</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-LISTEN-ADDRESSES"><span class="term"><code class="varname">listen_addresses</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.2.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the TCP/IP address(es) on which the server is
+ to listen for connections from client applications.
+ The value takes the form of a comma-separated list of host names
+ and/or numeric IP addresses. The special entry <code class="literal">*</code>
+ corresponds to all available IP interfaces. The entry
+ <code class="literal">0.0.0.0</code> allows listening for all IPv4 addresses and
+ <code class="literal">::</code> allows listening for all IPv6 addresses.
+ If the list is empty, the server does not listen on any IP interface
+ at all, in which case only Unix-domain sockets can be used to connect
+ to it.
+ The default value is <span class="systemitem">localhost</span>,
+ which allows only local TCP/IP <span class="quote">“<span class="quote">loopback</span>”</span> connections to be
+ made. While client authentication (<a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a>) allows fine-grained control
+ over who can access the server, <code class="varname">listen_addresses</code>
+ controls which interfaces accept connection attempts, which
+ can help prevent repeated malicious connection requests on
+ insecure network interfaces. This parameter can only be set
+ at server start.
+ </p></dd><dt id="GUC-PORT"><span class="term"><code class="varname">port</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The TCP port the server listens on; 5432 by default. Note that the
+ same port number is used for all IP addresses the server listens on.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-MAX-CONNECTIONS"><span class="term"><code class="varname">max_connections</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines the maximum number of concurrent connections to the
+ database server. The default is typically 100 connections, but
+ might be less if your kernel settings will not support it (as
+ determined during <span class="application">initdb</span>). This parameter can
+ only be set at server start.
+ </p><p>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </p></dd><dt id="GUC-SUPERUSER-RESERVED-CONNECTIONS"><span class="term"><code class="varname">superuser_reserved_connections</code>
+ (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines the number of connection <span class="quote">“<span class="quote">slots</span>”</span> that
+ are reserved for connections by <span class="productname">PostgreSQL</span>
+ superusers. At most <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>
+ connections can ever be active simultaneously. Whenever the
+ number of active concurrent connections is at least
+ <code class="varname">max_connections</code> minus
+ <code class="varname">superuser_reserved_connections</code>, new
+ connections will be accepted only for superusers, and no
+ new replication connections will be accepted.
+ </p><p>
+ The default value is three connections. The value must be less
+ than <code class="varname">max_connections</code>.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-UNIX-SOCKET-DIRECTORIES"><span class="term"><code class="varname">unix_socket_directories</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.2.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the directory of the Unix-domain socket(s) on which the
+ server is to listen for connections from client applications.
+ Multiple sockets can be created by listing multiple directories
+ separated by commas. Whitespace between entries is
+ ignored; surround a directory name with double quotes if you need
+ to include whitespace or commas in the name.
+ An empty value
+ specifies not listening on any Unix-domain sockets, in which case
+ only TCP/IP sockets can be used to connect to the server.
+ </p><p>
+ A value that starts with <code class="literal">@</code> specifies that a
+ Unix-domain socket in the abstract namespace should be created
+ (currently supported on Linux only). In that case, this value
+ does not specify a <span class="quote">“<span class="quote">directory</span>”</span> but a prefix from which
+ the actual socket name is computed in the same manner as for the
+ file-system namespace. While the abstract socket name prefix can be
+ chosen freely, since it is not a file-system location, the convention
+ is to nonetheless use file-system-like values such as
+ <code class="literal">@/tmp</code>.
+ </p><p>
+ The default value is normally
+ <code class="filename">/tmp</code>, but that can be changed at build time.
+ On Windows, the default is empty, which means no Unix-domain socket is
+ created by default.
+ This parameter can only be set at server start.
+ </p><p>
+ In addition to the socket file itself, which is named
+ <code class="literal">.s.PGSQL.<em class="replaceable"><code>nnnn</code></em></code> where
+ <em class="replaceable"><code>nnnn</code></em> is the server's port number, an ordinary file
+ named <code class="literal">.s.PGSQL.<em class="replaceable"><code>nnnn</code></em>.lock</code> will be
+ created in each of the <code class="varname">unix_socket_directories</code> directories.
+ Neither file should ever be removed manually.
+ For sockets in the abstract namespace, no lock file is created.
+ </p></dd><dt id="GUC-UNIX-SOCKET-GROUP"><span class="term"><code class="varname">unix_socket_group</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.2.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the owning group of the Unix-domain socket(s). (The owning
+ user of the sockets is always the user that starts the
+ server.) In combination with the parameter
+ <code class="varname">unix_socket_permissions</code> this can be used as
+ an additional access control mechanism for Unix-domain connections.
+ By default this is the empty string, which uses the default
+ group of the server user. This parameter can only be set at
+ server start.
+ </p><p>
+ This parameter is not supported on Windows. Any setting will be
+ ignored. Also, sockets in the abstract namespace have no file owner,
+ so this setting is also ignored in that case.
+ </p></dd><dt id="GUC-UNIX-SOCKET-PERMISSIONS"><span class="term"><code class="varname">unix_socket_permissions</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the access permissions of the Unix-domain socket(s). Unix-domain
+ sockets use the usual Unix file system permission set.
+ The parameter value is expected to be a numeric mode
+ specified in the format accepted by the
+ <code class="function">chmod</code> and <code class="function">umask</code>
+ system calls. (To use the customary octal format the number
+ must start with a <code class="literal">0</code> (zero).)
+ </p><p>
+ The default permissions are <code class="literal">0777</code>, meaning
+ anyone can connect. Reasonable alternatives are
+ <code class="literal">0770</code> (only user and group, see also
+ <code class="varname">unix_socket_group</code>) and <code class="literal">0700</code>
+ (only user). (Note that for a Unix-domain socket, only write
+ permission matters, so there is no point in setting or revoking
+ read or execute permissions.)
+ </p><p>
+ This access control mechanism is independent of the one
+ described in <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a>.
+ </p><p>
+ This parameter can only be set at server start.
+ </p><p>
+ This parameter is irrelevant on systems, notably Solaris as of Solaris
+ 10, that ignore socket permissions entirely. There, one can achieve a
+ similar effect by pointing <code class="varname">unix_socket_directories</code> to a
+ directory having search permission limited to the desired audience.
+ </p><p>
+ Sockets in the abstract namespace have no file permissions, so this
+ setting is also ignored in that case.
+ </p></dd><dt id="GUC-BONJOUR"><span class="term"><code class="varname">bonjour</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.6.2.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables advertising the server's existence via
+ <span class="productname">Bonjour</span>. The default is off.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-BONJOUR-NAME"><span class="term"><code class="varname">bonjour_name</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.2.2.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the <span class="productname">Bonjour</span> service
+ name. The computer name is used if this parameter is set to the
+ empty string <code class="literal">''</code> (which is the default). This parameter is
+ ignored if the server was not compiled with
+ <span class="productname">Bonjour</span> support.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-TCP-KEEPALIVES-IDLE"><span class="term"><code class="varname">tcp_keepalives_idle</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the amount of time with no network activity after which
+ the operating system should send a TCP keepalive message to the client.
+ If this value is specified without units, it is taken as seconds.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <code class="symbol">TCP_KEEPIDLE</code> or an equivalent socket option, and on
+ Windows; on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ On Windows, setting a value of 0 will set this parameter to 2 hours,
+ since Windows does not provide a way to read the system default value.
+ </p></div></dd><dt id="GUC-TCP-KEEPALIVES-INTERVAL"><span class="term"><code class="varname">tcp_keepalives_interval</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the amount of time after which a TCP keepalive message
+ that has not been acknowledged by the client should be retransmitted.
+ If this value is specified without units, it is taken as seconds.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <code class="symbol">TCP_KEEPINTVL</code> or an equivalent socket option, and on
+ Windows; on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ On Windows, setting a value of 0 will set this parameter to 1 second,
+ since Windows does not provide a way to read the system default value.
+ </p></div></dd><dt id="GUC-TCP-KEEPALIVES-COUNT"><span class="term"><code class="varname">tcp_keepalives_count</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the number of TCP keepalive messages that can be lost before
+ the server's connection to the client is considered dead.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <code class="symbol">TCP_KEEPCNT</code> or an equivalent socket option;
+ on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This parameter is not supported on Windows, and must be zero.
+ </p></div></dd><dt id="GUC-TCP-USER-TIMEOUT"><span class="term"><code class="varname">tcp_user_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the amount of time that transmitted data may
+ remain unacknowledged before the TCP connection is forcibly closed.
+ If this value is specified without units, it is taken as milliseconds.
+ A value of 0 (the default) selects the operating system's default.
+ This parameter is supported only on systems that support
+ <code class="symbol">TCP_USER_TIMEOUT</code>; on other systems, it must be zero.
+ In sessions connected via a Unix-domain socket, this parameter is
+ ignored and always reads as zero.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This parameter is not supported on Windows, and must be zero.
+ </p></div></dd><dt id="GUC-CLIENT-CONNECTION-CHECK-INTERVAL"><span class="term"><code class="varname">client_connection_check_interval</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.2.2.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the time interval between optional checks that the client is still
+ connected, while running queries. The check is performed by polling
+ the socket, and allows long running queries to be aborted sooner if
+ the kernel reports that the connection is closed.
+ </p><p>
+ This option relies on kernel events exposed by Linux, macOS, illumos
+ and the BSD family of operating systems, and is not currently available
+ on other systems.
+ </p><p>
+ If the value is specified without units, it is taken as milliseconds.
+ The default value is <code class="literal">0</code>, which disables connection
+ checks. Without connection checks, the server will detect the loss of
+ the connection only at the next interaction with the socket, when it
+ waits for, receives or sends data.
+ </p><p>
+ For the kernel itself to detect lost TCP connections reliably and within
+ a known timeframe in all scenarios including network failure, it may
+ also be necessary to adjust the TCP keepalive settings of the operating
+ system, or the <a class="xref" href="runtime-config-connection.html#GUC-TCP-KEEPALIVES-IDLE">tcp_keepalives_idle</a>,
+ <a class="xref" href="runtime-config-connection.html#GUC-TCP-KEEPALIVES-INTERVAL">tcp_keepalives_interval</a> and
+ <a class="xref" href="runtime-config-connection.html#GUC-TCP-KEEPALIVES-COUNT">tcp_keepalives_count</a> settings of
+ <span class="productname">PostgreSQL</span>.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-CONNECTION-AUTHENTICATION"><div class="titlepage"><div><div><h3 class="title">20.3.2. Authentication</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-AUTHENTICATION-TIMEOUT"><span class="term"><code class="varname">authentication_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.6.3.2.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.6.3.2.1.1.4" class="indexterm"></a>
+ <a id="id-1.6.7.6.3.2.1.1.5" class="indexterm"></a>
+ </span></dt><dd><p>
+ Maximum amount of time allowed to complete client authentication. If a
+ would-be client has not completed the authentication protocol in
+ this much time, the server closes the connection. This prevents
+ hung clients from occupying a connection indefinitely.
+ If this value is specified without units, it is taken as seconds.
+ The default is one minute (<code class="literal">1m</code>).
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-PASSWORD-ENCRYPTION"><span class="term"><code class="varname">password_encryption</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.6.3.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When a password is specified in <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a> or
+ <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>, this parameter determines the
+ algorithm to use to encrypt the password. Possible values are
+ <code class="literal">scram-sha-256</code>, which will encrypt the password with
+ SCRAM-SHA-256, and <code class="literal">md5</code>, which stores the password
+ as an MD5 hash. The default is <code class="literal">scram-sha-256</code>.
+ </p><p>
+ Note that older clients might lack support for the SCRAM authentication
+ mechanism, and hence not work with passwords encrypted with
+ SCRAM-SHA-256. See <a class="xref" href="auth-password.html" title="21.5. Password Authentication">Section 21.5</a> for more details.
+ </p></dd><dt id="GUC-KRB-SERVER-KEYFILE"><span class="term"><code class="varname">krb_server_keyfile</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.3.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the location of the server's Kerberos key file. The default is
+ <code class="filename">FILE:/usr/local/pgsql/etc/krb5.keytab</code>
+ (where the directory part is whatever was specified
+ as <code class="varname">sysconfdir</code> at build time; use
+ <code class="literal">pg_config --sysconfdir</code> to determine that).
+ If this parameter is set to an empty string, it is ignored and a
+ system-dependent default is used.
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ See <a class="xref" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Section 21.6</a> for more information.
+ </p></dd><dt id="GUC-KRB-CASEINS-USERS"><span class="term"><code class="varname">krb_caseins_users</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.6.3.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets whether GSSAPI user names should be treated
+ case-insensitively.
+ The default is <code class="literal">off</code> (case sensitive). This parameter can only be
+ set in the <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-DB-USER-NAMESPACE"><span class="term"><code class="varname">db_user_namespace</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.6.3.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter enables per-database user names. It is off by default.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ If this is on, you should create users as <em class="replaceable"><code>username@dbname</code></em>.
+ When <em class="replaceable"><code>username</code></em> is passed by a connecting client,
+ <code class="literal">@</code> and the database name are appended to the user
+ name and that database-specific user name is looked up by the
+ server. Note that when you create users with names containing
+ <code class="literal">@</code> within the SQL environment, you will need to
+ quote the user name.
+ </p><p>
+ With this parameter enabled, you can still create ordinary global
+ users. Simply append <code class="literal">@</code> when specifying the user
+ name in the client, e.g., <code class="literal">joe@</code>. The <code class="literal">@</code>
+ will be stripped off before the user name is looked up by the
+ server.
+ </p><p>
+ <code class="varname">db_user_namespace</code> causes the client's and
+ server's user name representation to differ.
+ Authentication checks are always done with the server's user name
+ so authentication methods must be configured for the
+ server's user name, not the client's. Because
+ <code class="literal">md5</code> uses the user name as salt on both the
+ client and server, <code class="literal">md5</code> cannot be used with
+ <code class="varname">db_user_namespace</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This feature is intended as a temporary measure until a
+ complete solution is found. At that time, this option will
+ be removed.
+ </p></div></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-CONNECTION-SSL"><div class="titlepage"><div><div><h3 class="title">20.3.3. SSL</h3></div></div></div><p>
+ See <a class="xref" href="ssl-tcp.html" title="19.9. Secure TCP/IP Connections with SSL">Section 19.9</a> for more information about setting up
+ <acronym class="acronym">SSL</acronym>. The configuration parameters for controlling
+ transfer encryption using <acronym class="acronym">TLS</acronym> protocols are named
+ <code class="literal">ssl</code> for historic reasons, even though support for
+ the <acronym class="acronym">SSL</acronym> protocol has been deprecated.
+ <acronym class="acronym">SSL</acronym> is in this context used interchangeably with
+ <acronym class="acronym">TLS</acronym>.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-SSL"><span class="term"><code class="varname">ssl</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.6.4.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables <acronym class="acronym">SSL</acronym> connections.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="literal">off</code>.
+ </p></dd><dt id="GUC-SSL-CA-FILE"><span class="term"><code class="varname">ssl_ca_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the file containing the SSL server certificate
+ authority (CA).
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is empty, meaning no CA file is loaded,
+ and client certificate verification is not performed.
+ </p></dd><dt id="GUC-SSL-CERT-FILE"><span class="term"><code class="varname">ssl_cert_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the file containing the SSL server certificate.
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="filename">server.crt</code>.
+ </p></dd><dt id="GUC-SSL-CRL-FILE"><span class="term"><code class="varname">ssl_crl_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the file containing the SSL client certificate
+ revocation list (CRL).
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is empty, meaning no CRL file is loaded (unless
+ <a class="xref" href="runtime-config-connection.html#GUC-SSL-CRL-DIR">ssl_crl_dir</a> is set).
+ </p></dd><dt id="GUC-SSL-CRL-DIR"><span class="term"><code class="varname">ssl_crl_dir</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the directory containing the SSL client
+ certificate revocation list (CRL). Relative paths are relative to the
+ data directory. This parameter can only be set in
+ the <code class="filename">postgresql.conf</code> file or on the server command
+ line. The default is empty, meaning no CRLs are used (unless
+ <a class="xref" href="runtime-config-connection.html#GUC-SSL-CRL-FILE">ssl_crl_file</a> is set).
+ </p><p>
+ The directory needs to be prepared with the
+ <span class="productname">OpenSSL</span> command
+ <code class="literal">openssl rehash</code> or <code class="literal">c_rehash</code>. See
+ its documentation for details.
+ </p><p>
+ When using this setting, CRLs in the specified directory are loaded
+ on-demand at connection time. New CRLs can be added to the directory
+ and will be used immediately. This is unlike <a class="xref" href="runtime-config-connection.html#GUC-SSL-CRL-FILE">ssl_crl_file</a>, which causes the CRL in the file to be
+ loaded at server start time or when the configuration is reloaded.
+ Both settings can be used together.
+ </p></dd><dt id="GUC-SSL-KEY-FILE"><span class="term"><code class="varname">ssl_key_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the file containing the SSL server private key.
+ Relative paths are relative to the data directory.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="filename">server.key</code>.
+ </p></dd><dt id="GUC-SSL-CIPHERS"><span class="term"><code class="varname">ssl_ciphers</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a list of <acronym class="acronym">SSL</acronym> cipher suites that are
+ allowed to be used by SSL connections. See the
+ <span class="citerefentry"><span class="refentrytitle">ciphers</span></span>
+ manual page in the <span class="productname">OpenSSL</span> package for the
+ syntax of this setting and a list of supported values. Only
+ connections using TLS version 1.2 and lower are affected. There is
+ currently no setting that controls the cipher choices used by TLS
+ version 1.3 connections. The default value is
+ <code class="literal">HIGH:MEDIUM:+3DES:!aNULL</code>. The default is usually a
+ reasonable choice unless you have specific security requirements.
+ </p><p>
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command
+ line.
+ </p><p>
+ Explanation of the default value:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">HIGH</code></span></dt><dd><p>
+ Cipher suites that use ciphers from <code class="literal">HIGH</code> group (e.g.,
+ AES, Camellia, 3DES)
+ </p></dd><dt><span class="term"><code class="literal">MEDIUM</code></span></dt><dd><p>
+ Cipher suites that use ciphers from <code class="literal">MEDIUM</code> group
+ (e.g., RC4, SEED)
+ </p></dd><dt><span class="term"><code class="literal">+3DES</code></span></dt><dd><p>
+ The <span class="productname">OpenSSL</span> default order for
+ <code class="literal">HIGH</code> is problematic because it orders 3DES
+ higher than AES128. This is wrong because 3DES offers less
+ security than AES128, and it is also much slower.
+ <code class="literal">+3DES</code> reorders it after all other
+ <code class="literal">HIGH</code> and <code class="literal">MEDIUM</code> ciphers.
+ </p></dd><dt><span class="term"><code class="literal">!aNULL</code></span></dt><dd><p>
+ Disables anonymous cipher suites that do no authentication. Such
+ cipher suites are vulnerable to <acronym class="acronym">MITM</acronym> attacks and
+ therefore should not be used.
+ </p></dd></dl></div><p>
+ </p><p>
+ Available cipher suite details will vary across
+ <span class="productname">OpenSSL</span> versions. Use the command
+ <code class="literal">openssl ciphers -v 'HIGH:MEDIUM:+3DES:!aNULL'</code> to
+ see actual details for the currently installed
+ <span class="productname">OpenSSL</span> version. Note that this list is
+ filtered at run time based on the server key type.
+ </p></dd><dt id="GUC-SSL-PREFER-SERVER-CIPHERS"><span class="term"><code class="varname">ssl_prefer_server_ciphers</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.6.4.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies whether to use the server's SSL cipher preferences, rather
+ than the client's.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="literal">on</code>.
+ </p><p>
+ Older PostgreSQL versions do not have this setting and always use the
+ client's preferences. This setting is mainly for backward
+ compatibility with those versions. Using the server's preferences is
+ usually better because it is more likely that the server is appropriately
+ configured.
+ </p></dd><dt id="GUC-SSL-ECDH-CURVE"><span class="term"><code class="varname">ssl_ecdh_curve</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the curve to use in <acronym class="acronym">ECDH</acronym> key
+ exchange. It needs to be supported by all clients that connect.
+ It does not need to be the same curve used by the server's Elliptic
+ Curve key.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="literal">prime256v1</code>.
+ </p><p>
+ <span class="productname">OpenSSL</span> names for the most common curves
+ are:
+ <code class="literal">prime256v1</code> (NIST P-256),
+ <code class="literal">secp384r1</code> (NIST P-384),
+ <code class="literal">secp521r1</code> (NIST P-521).
+ The full list of available curves can be shown with the command
+ <code class="command">openssl ecparam -list_curves</code>. Not all of them
+ are usable in <acronym class="acronym">TLS</acronym> though.
+ </p></dd><dt id="GUC-SSL-MIN-PROTOCOL-VERSION"><span class="term"><code class="varname">ssl_min_protocol_version</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.6.4.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the minimum SSL/TLS protocol version to use. Valid values are
+ currently: <code class="literal">TLSv1</code>, <code class="literal">TLSv1.1</code>,
+ <code class="literal">TLSv1.2</code>, <code class="literal">TLSv1.3</code>. Older
+ versions of the <span class="productname">OpenSSL</span> library do not
+ support all values; an error will be raised if an unsupported setting
+ is chosen. Protocol versions before TLS 1.0, namely SSL version 2 and
+ 3, are always disabled.
+ </p><p>
+ The default is <code class="literal">TLSv1.2</code>, which satisfies industry
+ best practices as of this writing.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SSL-MAX-PROTOCOL-VERSION"><span class="term"><code class="varname">ssl_max_protocol_version</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.6.4.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum SSL/TLS protocol version to use. Valid values are as
+ for <a class="xref" href="runtime-config-connection.html#GUC-SSL-MIN-PROTOCOL-VERSION">ssl_min_protocol_version</a>, with addition of
+ an empty string, which allows any protocol version. The default is to
+ allow any version. Setting the maximum protocol version is mainly
+ useful for testing or if some component has issues working with a
+ newer protocol.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SSL-DH-PARAMS-FILE"><span class="term"><code class="varname">ssl_dh_params_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of the file containing Diffie-Hellman parameters
+ used for so-called ephemeral DH family of SSL ciphers. The default is
+ empty, in which case compiled-in default DH parameters used. Using
+ custom DH parameters reduces the exposure if an attacker manages to
+ crack the well-known compiled-in DH parameters. You can create your own
+ DH parameters file with the command
+ <code class="command">openssl dhparam -out dhparams.pem 2048</code>.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SSL-PASSPHRASE-COMMAND"><span class="term"><code class="varname">ssl_passphrase_command</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.6.4.3.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets an external command to be invoked when a passphrase for
+ decrypting an SSL file such as a private key needs to be obtained. By
+ default, this parameter is empty, which means the built-in prompting
+ mechanism is used.
+ </p><p>
+ The command must print the passphrase to the standard output and exit
+ with code 0. In the parameter value, <code class="literal">%p</code> is
+ replaced by a prompt string. (Write <code class="literal">%%</code> for a
+ literal <code class="literal">%</code>.) Note that the prompt string will
+ probably contain whitespace, so be sure to quote adequately. A single
+ newline is stripped from the end of the output if present.
+ </p><p>
+ The command does not actually have to prompt the user for a
+ passphrase. It can read it from a file, obtain it from a keychain
+ facility, or similar. It is up to the user to make sure the chosen
+ mechanism is adequately secure.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SSL-PASSPHRASE-COMMAND-SUPPORTS-RELOAD"><span class="term"><code class="varname">ssl_passphrase_command_supports_reload</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.6.4.3.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter determines whether the passphrase command set by
+ <code class="varname">ssl_passphrase_command</code> will also be called during a
+ configuration reload if a key file needs a passphrase. If this
+ parameter is off (the default), then
+ <code class="varname">ssl_passphrase_command</code> will be ignored during a
+ reload and the SSL configuration will not be reloaded if a passphrase
+ is needed. That setting is appropriate for a command that requires a
+ TTY for prompting, which might not be available when the server is
+ running. Setting this parameter to on might be appropriate if the
+ passphrase is obtained from a file, for example.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-file-locations.html" title="20.2. File Locations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-resource.html" title="20.4. Resource Consumption">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.2. File Locations </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.4. Resource Consumption</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-custom.html b/doc/src/sgml/html/runtime-config-custom.html
new file mode 100644
index 0000000..9651181
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-custom.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.16. Customized Options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-preset.html" title="20.15. Preset Options" /><link rel="next" href="runtime-config-developer.html" title="20.17. Developer Options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.16. Customized Options</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-preset.html" title="20.15. Preset Options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-developer.html" title="20.17. Developer Options">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-CUSTOM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.16. Customized Options</h2></div></div></div><p>
+ This feature was designed to allow parameters not normally known to
+ <span class="productname">PostgreSQL</span> to be added by add-on modules
+ (such as procedural languages). This allows extension modules to be
+ configured in the standard ways.
+ </p><p>
+ Custom options have two-part names: an extension name, then a dot, then
+ the parameter name proper, much like qualified names in SQL. An example
+ is <code class="literal">plpgsql.variable_conflict</code>.
+ </p><p>
+ Because custom options may need to be set in processes that have not
+ loaded the relevant extension module, <span class="productname">PostgreSQL</span>
+ will accept a setting for any two-part parameter name. Such variables
+ are treated as placeholders and have no function until the module that
+ defines them is loaded. When an extension module is loaded, it will add
+ its variable definitions and convert any placeholder values according to
+ those definitions. If there are any unrecognized placeholders
+ that begin with its extension name, warnings are issued and those
+ placeholders are removed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-preset.html" title="20.15. Preset Options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-developer.html" title="20.17. Developer Options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.15. Preset Options </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.17. Developer Options</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-developer.html b/doc/src/sgml/html/runtime-config-developer.html
new file mode 100644
index 0000000..2e12d2d
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-developer.html
@@ -0,0 +1,377 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.17. Developer Options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-custom.html" title="20.16. Customized Options" /><link rel="next" href="runtime-config-short.html" title="20.18. Short Options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.17. Developer Options</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-custom.html" title="20.16. Customized Options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-short.html" title="20.18. Short Options">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-DEVELOPER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.17. Developer Options</h2></div></div></div><p>
+ The following parameters are intended for developer testing, and
+ should never be used on a production database. However, some of
+ them can be used to assist with the recovery of severely damaged
+ databases. As such, they have been excluded from the sample
+ <code class="filename">postgresql.conf</code> file. Note that many of these
+ parameters require special source compilation flags to work at all.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-ALLOW-IN-PLACE-TABLESPACES"><span class="term"><code class="varname">allow_in_place_tablespaces</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Allows tablespaces to be created as directories inside
+ <code class="filename">pg_tblspc</code>, when an empty location string
+ is provided to the <code class="command">CREATE TABLESPACE</code> command. This
+ is intended to allow testing replication scenarios where primary and
+ standby servers are running on the same machine. Such directories
+ are likely to confuse backup tools that expect to find only symbolic
+ links in that location.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-ALLOW-SYSTEM-TABLE-MODS"><span class="term"><code class="varname">allow_system_table_mods</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Allows modification of the structure of system tables as well as
+ certain other risky actions on system tables. This is otherwise not
+ allowed even for superusers. Ill-advised use of this setting can
+ cause irretrievable data loss or seriously corrupt the database
+ system.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-BACKTRACE-FUNCTIONS"><span class="term"><code class="varname">backtrace_functions</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.20.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter contains a comma-separated list of C function names.
+ If an error is raised and the name of the internal C function where
+ the error happens matches a value in the list, then a backtrace is
+ written to the server log together with the error message. This can
+ be used to debug specific areas of the source code.
+ </p><p>
+ Backtrace support is not available on all platforms, and the quality
+ of the backtraces depends on compilation options.
+ </p><p>
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-DEBUG-DISCARD-CACHES"><span class="term"><code class="varname">debug_discard_caches</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.20.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set to <code class="literal">1</code>, each system catalog cache entry is
+ invalidated at the first possible opportunity, whether or not
+ anything that would render it invalid really occurred. Caching of
+ system catalogs is effectively disabled as a result, so the server
+ will run extremely slowly. Higher values run the cache invalidation
+ recursively, which is even slower and only useful for testing
+ the caching logic itself. The default value of <code class="literal">0</code>
+ selects normal catalog caching behavior.
+ </p><p>
+ This parameter can be very helpful when trying to trigger
+ hard-to-reproduce bugs involving concurrent catalog changes, but it
+ is otherwise rarely needed. See the source code files
+ <code class="filename">inval.c</code> and
+ <code class="filename">pg_config_manual.h</code> for details.
+ </p><p>
+ This parameter is supported when
+ <code class="symbol">DISCARD_CACHES_ENABLED</code> was defined at compile time
+ (which happens automatically when using the
+ <span class="application">configure</span> option
+ <code class="option">--enable-cassert</code>). In production builds, its value
+ will always be <code class="literal">0</code> and attempts to set it to another
+ value will raise an error.
+ </p></dd><dt id="GUC-FORCE-PARALLEL-MODE"><span class="term"><code class="varname">force_parallel_mode</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.20.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Allows the use of parallel queries for testing purposes even in cases
+ where no performance benefit is expected.
+ The allowed values of <code class="varname">force_parallel_mode</code> are
+ <code class="literal">off</code> (use parallel mode only when it is expected to improve
+ performance), <code class="literal">on</code> (force parallel query for all queries
+ for which it is thought to be safe), and <code class="literal">regress</code> (like
+ <code class="literal">on</code>, but with additional behavior changes as explained
+ below).
+ </p><p>
+ More specifically, setting this value to <code class="literal">on</code> will add
+ a <code class="literal">Gather</code> node to the top of any query plan for which this
+ appears to be safe, so that the query runs inside of a parallel worker.
+ Even when a parallel worker is not available or cannot be used,
+ operations such as starting a subtransaction that would be prohibited
+ in a parallel query context will be prohibited unless the planner
+ believes that this will cause the query to fail. If failures or
+ unexpected results occur when this option is set, some functions used
+ by the query may need to be marked <code class="literal">PARALLEL UNSAFE</code>
+ (or, possibly, <code class="literal">PARALLEL RESTRICTED</code>).
+ </p><p>
+ Setting this value to <code class="literal">regress</code> has all of the same effects
+ as setting it to <code class="literal">on</code> plus some additional effects that are
+ intended to facilitate automated regression testing. Normally,
+ messages from a parallel worker include a context line indicating that,
+ but a setting of <code class="literal">regress</code> suppresses this line so that the
+ output is the same as in non-parallel execution. Also,
+ the <code class="literal">Gather</code> nodes added to plans by this setting are hidden
+ in <code class="literal">EXPLAIN</code> output so that the output matches what
+ would be obtained if this setting were turned <code class="literal">off</code>.
+ </p></dd><dt id="GUC-IGNORE-SYSTEM-INDEXES"><span class="term"><code class="varname">ignore_system_indexes</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Ignore system indexes when reading system tables (but still
+ update the indexes when modifying the tables). This is useful
+ when recovering from damaged system indexes.
+ This parameter cannot be changed after session start.
+ </p></dd><dt id="GUC-POST-AUTH-DELAY"><span class="term"><code class="varname">post_auth_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.20.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The amount of time to delay when a new
+ server process is started, after it conducts the
+ authentication procedure. This is intended to give developers an
+ opportunity to attach to the server process with a debugger.
+ If this value is specified without units, it is taken as seconds.
+ A value of zero (the default) disables the delay.
+ This parameter cannot be changed after session start.
+ </p></dd><dt id="GUC-PRE-AUTH-DELAY"><span class="term"><code class="varname">pre_auth_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.20.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The amount of time to delay just after a
+ new server process is forked, before it conducts the
+ authentication procedure. This is intended to give developers an
+ opportunity to attach to the server process with a debugger to
+ trace down misbehavior in authentication.
+ If this value is specified without units, it is taken as seconds.
+ A value of zero (the default) disables the delay.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-TRACE-NOTIFY"><span class="term"><code class="varname">trace_notify</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Generates a great amount of debugging output for the
+ <code class="command">LISTEN</code> and <code class="command">NOTIFY</code>
+ commands. <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> or
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a> must be
+ <code class="literal">DEBUG1</code> or lower to send this output to the
+ client or server logs, respectively.
+ </p></dd><dt id="GUC-TRACE-RECOVERY-MESSAGES"><span class="term"><code class="varname">trace_recovery_messages</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.20.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables logging of recovery-related debugging output that otherwise
+ would not be logged. This parameter allows the user to override the
+ normal setting of <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a>, but only for
+ specific messages. This is intended for use in debugging hot standby.
+ Valid values are <code class="literal">DEBUG5</code>, <code class="literal">DEBUG4</code>,
+ <code class="literal">DEBUG3</code>, <code class="literal">DEBUG2</code>, <code class="literal">DEBUG1</code>, and
+ <code class="literal">LOG</code>. The default, <code class="literal">LOG</code>, does not affect
+ logging decisions at all. The other values cause recovery-related
+ debug messages of that priority or higher to be logged as though they
+ had <code class="literal">LOG</code> priority; for common settings of
+ <code class="varname">log_min_messages</code> this results in unconditionally sending
+ them to the server log.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-TRACE-SORT"><span class="term"><code class="varname">trace_sort</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If on, emit information about resource usage during sort operations.
+ This parameter is only available if the <code class="symbol">TRACE_SORT</code> macro
+ was defined when <span class="productname">PostgreSQL</span> was compiled.
+ (However, <code class="symbol">TRACE_SORT</code> is currently defined by default.)
+ </p></dd><dt id="GUC-TRACE-LOCKS"><span class="term"><code class="varname">trace_locks</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If on, emit information about lock usage. Information dumped
+ includes the type of lock operation, the type of lock and the unique
+ identifier of the object being locked or unlocked. Also included
+ are bit masks for the lock types already granted on this object as
+ well as for the lock types awaited on this object. For each lock
+ type a count of the number of granted locks and waiting locks is
+ also dumped as well as the totals. An example of the log file output
+ is shown here:
+</p><pre class="screen">
+LOG: LockAcquire: new: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
+ wait(0) type(AccessShareLock)
+LOG: GrantLock: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(2) req(1,0,0,0,0,0,0)=1 grant(1,0,0,0,0,0,0)=1
+ wait(0) type(AccessShareLock)
+LOG: UnGrantLock: updated: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
+ wait(0) type(AccessShareLock)
+LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
+ grantMask(0) req(0,0,0,0,0,0,0)=0 grant(0,0,0,0,0,0,0)=0
+ wait(0) type(INVALID)
+</pre><p>
+ Details of the structure being dumped may be found in
+ <code class="filename">src/include/storage/lock.h</code>.
+ </p><p>
+ This parameter is only available if the <code class="symbol">LOCK_DEBUG</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-TRACE-LWLOCKS"><span class="term"><code class="varname">trace_lwlocks</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If on, emit information about lightweight lock usage. Lightweight
+ locks are intended primarily to provide mutual exclusion of access
+ to shared-memory data structures.
+ </p><p>
+ This parameter is only available if the <code class="symbol">LOCK_DEBUG</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-TRACE-USERLOCKS"><span class="term"><code class="varname">trace_userlocks</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If on, emit information about user lock usage. Output is the same
+ as for <code class="symbol">trace_locks</code>, only for advisory locks.
+ </p><p>
+ This parameter is only available if the <code class="symbol">LOCK_DEBUG</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-TRACE-LOCK-OIDMIN"><span class="term"><code class="varname">trace_lock_oidmin</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.20.3.15.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If set, do not trace locks for tables below this OID (used to avoid
+ output on system tables).
+ </p><p>
+ This parameter is only available if the <code class="symbol">LOCK_DEBUG</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-TRACE-LOCK-TABLE"><span class="term"><code class="varname">trace_lock_table</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.20.3.16.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Unconditionally trace locks on this table (OID).
+ </p><p>
+ This parameter is only available if the <code class="symbol">LOCK_DEBUG</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-DEBUG-DEADLOCKS"><span class="term"><code class="varname">debug_deadlocks</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.17.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If set, dumps information about all current locks when a
+ deadlock timeout occurs.
+ </p><p>
+ This parameter is only available if the <code class="symbol">LOCK_DEBUG</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-LOG-BTREE-BUILD-STATS"><span class="term"><code class="varname">log_btree_build_stats</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.18.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If set, logs system resource usage statistics (memory and CPU) on
+ various B-tree operations.
+ </p><p>
+ This parameter is only available if the <code class="symbol">BTREE_BUILD_STATS</code>
+ macro was defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-WAL-CONSISTENCY-CHECKING"><span class="term"><code class="varname">wal_consistency_checking</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.20.3.19.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter is intended to be used to check for bugs in the WAL
+ redo routines. When enabled, full-page images of any buffers modified
+ in conjunction with the WAL record are added to the record.
+ If the record is subsequently replayed, the system will first apply
+ each record and then test whether the buffers modified by the record
+ match the stored images. In certain cases (such as hint bits), minor
+ variations are acceptable, and will be ignored. Any unexpected
+ differences will result in a fatal error, terminating recovery.
+ </p><p>
+ The default value of this setting is the empty string, which disables
+ the feature. It can be set to <code class="literal">all</code> to check all
+ records, or to a comma-separated list of resource managers to check
+ only records originating from those resource managers. Currently,
+ the supported resource managers are <code class="literal">heap</code>,
+ <code class="literal">heap2</code>, <code class="literal">btree</code>, <code class="literal">hash</code>,
+ <code class="literal">gin</code>, <code class="literal">gist</code>, <code class="literal">sequence</code>,
+ <code class="literal">spgist</code>, <code class="literal">brin</code>, and <code class="literal">generic</code>.
+ Extensions may define additional resource managers. Only superusers and users with
+ the appropriate <code class="literal">SET</code> privilege can change this setting.
+ </p></dd><dt id="GUC-WAL-DEBUG"><span class="term"><code class="varname">wal_debug</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.20.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If on, emit WAL-related debugging output. This parameter is
+ only available if the <code class="symbol">WAL_DEBUG</code> macro was
+ defined when <span class="productname">PostgreSQL</span> was
+ compiled.
+ </p></dd><dt id="GUC-IGNORE-CHECKSUM-FAILURE"><span class="term"><code class="varname">ignore_checksum_failure</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.21.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Only has effect if <a class="xref" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS">data checksums</a> are enabled.
+ </p><p>
+ Detection of a checksum failure during a read normally causes
+ <span class="productname">PostgreSQL</span> to report an error, aborting the current
+ transaction. Setting <code class="varname">ignore_checksum_failure</code> to on causes
+ the system to ignore the failure (but still report a warning), and
+ continue processing. This behavior may <span class="emphasis"><em>cause crashes, propagate
+ or hide corruption, or other serious problems</em></span>. However, it may allow
+ you to get past the error and retrieve undamaged tuples that might still be
+ present in the table if the block header is still sane. If the header is
+ corrupt an error will be reported even if this option is enabled. The
+ default setting is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-ZERO-DAMAGED-PAGES"><span class="term"><code class="varname">zero_damaged_pages</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.22.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Detection of a damaged page header normally causes
+ <span class="productname">PostgreSQL</span> to report an error, aborting the current
+ transaction. Setting <code class="varname">zero_damaged_pages</code> to on causes
+ the system to instead report a warning, zero out the damaged
+ page in memory, and continue processing. This behavior <span class="emphasis"><em>will destroy data</em></span>,
+ namely all the rows on the damaged page. However, it does allow you to get
+ past the error and retrieve rows from any undamaged pages that might
+ be present in the table. It is useful for recovering data if
+ corruption has occurred due to a hardware or software error. You should
+ generally not set this on until you have given up hope of recovering
+ data from the damaged pages of a table. Zeroed-out pages are not
+ forced to disk so it is recommended to recreate the table or
+ the index before turning this parameter off again. The
+ default setting is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-IGNORE-INVALID-PAGES"><span class="term"><code class="varname">ignore_invalid_pages</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.23.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If set to <code class="literal">off</code> (the default), detection of
+ WAL records having references to invalid pages during
+ recovery causes <span class="productname">PostgreSQL</span> to
+ raise a PANIC-level error, aborting the recovery. Setting
+ <code class="varname">ignore_invalid_pages</code> to <code class="literal">on</code>
+ causes the system to ignore invalid page references in WAL records
+ (but still report a warning), and continue the recovery.
+ This behavior may <span class="emphasis"><em>cause crashes, data loss,
+ propagate or hide corruption, or other serious problems</em></span>.
+ However, it may allow you to get past the PANIC-level error,
+ to finish the recovery, and to cause the server to start up.
+ The parameter can only be set at server start. It only has effect
+ during recovery or in standby mode.
+ </p></dd><dt id="GUC-JIT-DEBUGGING-SUPPORT"><span class="term"><code class="varname">jit_debugging_support</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.24.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If LLVM has the required functionality, register generated functions
+ with <span class="productname">GDB</span>. This makes debugging easier.
+ The default setting is <code class="literal">off</code>.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-JIT-DUMP-BITCODE"><span class="term"><code class="varname">jit_dump_bitcode</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.25.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Writes the generated <span class="productname">LLVM</span> IR out to the
+ file system, inside <a class="xref" href="runtime-config-file-locations.html#GUC-DATA-DIRECTORY">data_directory</a>. This is only
+ useful for working on the internals of the JIT implementation.
+ The default setting is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-JIT-EXPRESSIONS"><span class="term"><code class="varname">jit_expressions</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.26.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines whether expressions are JIT compiled, when JIT compilation
+ is activated (see <a class="xref" href="jit-decision.html" title="32.2. When to JIT?">Section 32.2</a>). The default is
+ <code class="literal">on</code>.
+ </p></dd><dt id="GUC-JIT-PROFILING-SUPPORT"><span class="term"><code class="varname">jit_profiling_support</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.27.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If LLVM has the required functionality, emit the data needed to allow
+ <span class="productname">perf</span> to profile functions generated by JIT.
+ This writes out files to <code class="filename">~/.debug/jit/</code>; the
+ user is responsible for performing cleanup when desired.
+ The default setting is <code class="literal">off</code>.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-JIT-TUPLE-DEFORMING"><span class="term"><code class="varname">jit_tuple_deforming</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.28.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines whether tuple deforming is JIT compiled, when JIT
+ compilation is activated (see <a class="xref" href="jit-decision.html" title="32.2. When to JIT?">Section 32.2</a>).
+ The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-REMOVE-TEMP-FILES-AFTER-CRASH"><span class="term"><code class="varname">remove_temp_files_after_crash</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.20.3.29.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set to <code class="literal">on</code>, which is the default,
+ <span class="productname">PostgreSQL</span> will automatically remove
+ temporary files after a backend crash. If disabled, the files will be
+ retained and may be used for debugging, for example. Repeated crashes
+ may however result in accumulation of useless files. This parameter
+ can only be set in the <code class="filename">postgresql.conf</code> file or on
+ the server command line.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-custom.html" title="20.16. Customized Options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-short.html" title="20.18. Short Options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.16. Customized Options </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.18. Short Options</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-error-handling.html b/doc/src/sgml/html/runtime-config-error-handling.html
new file mode 100644
index 0000000..e0c5115
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-error-handling.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.14. Error Handling</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-compatible.html" title="20.13. Version and Platform Compatibility" /><link rel="next" href="runtime-config-preset.html" title="20.15. Preset Options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.14. Error Handling</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-compatible.html" title="20.13. Version and Platform Compatibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-preset.html" title="20.15. Preset Options">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-ERROR-HANDLING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.14. Error Handling</h2></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-EXIT-ON-ERROR"><span class="term"><code class="varname">exit_on_error</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.17.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If on, any error will terminate the current session. By default,
+ this is set to off, so that only FATAL errors will terminate the
+ session.
+ </p></dd><dt id="GUC-RESTART-AFTER-CRASH"><span class="term"><code class="varname">restart_after_crash</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.17.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set to on, which is the default, <span class="productname">PostgreSQL</span>
+ will automatically reinitialize after a backend crash. Leaving this
+ value set to on is normally the best way to maximize the availability
+ of the database. However, in some circumstances, such as when
+ <span class="productname">PostgreSQL</span> is being invoked by clusterware, it may be
+ useful to disable the restart so that the clusterware can gain
+ control and take any actions it deems appropriate.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-DATA-SYNC-RETRY"><span class="term"><code class="varname">data_sync_retry</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.17.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set to off, which is the default, <span class="productname">PostgreSQL</span>
+ will raise a PANIC-level error on failure to flush modified data files
+ to the file system. This causes the database server to crash. This
+ parameter can only be set at server start.
+ </p><p>
+ On some operating systems, the status of data in the kernel's page
+ cache is unknown after a write-back failure. In some cases it might
+ have been entirely forgotten, making it unsafe to retry; the second
+ attempt may be reported as successful, when in fact the data has been
+ lost. In these circumstances, the only way to avoid data loss is to
+ recover from the WAL after any failure is reported, preferably
+ after investigating the root cause of the failure and replacing any
+ faulty hardware.
+ </p><p>
+ If set to on, <span class="productname">PostgreSQL</span> will instead
+ report an error but continue to run so that the data flushing
+ operation can be retried in a later checkpoint. Only set it to on
+ after investigating the operating system's treatment of buffered data
+ in case of write-back failure.
+ </p></dd><dt id="GUC-RECOVERY-INIT-SYNC-METHOD"><span class="term"><code class="varname">recovery_init_sync_method</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.17.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set to <code class="literal">fsync</code>, which is the default,
+ <span class="productname">PostgreSQL</span> will recursively open and
+ synchronize all files in the data directory before crash recovery
+ begins. The search for files will follow symbolic links for the WAL
+ directory and each configured tablespace (but not any other symbolic
+ links). This is intended to make sure that all WAL and data files are
+ durably stored on disk before replaying changes. This applies whenever
+ starting a database cluster that did not shut down cleanly, including
+ copies created with <span class="application">pg_basebackup</span>.
+ </p><p>
+ On Linux, <code class="literal">syncfs</code> may be used instead, to ask the
+ operating system to synchronize the whole file systems that contain the
+ data directory, the WAL files and each tablespace (but not any other
+ file systems that may be reachable through symbolic links). This may
+ be a lot faster than the <code class="literal">fsync</code> setting, because it
+ doesn't need to open each file one by one. On the other hand, it may
+ be slower if a file system is shared by other applications that
+ modify a lot of files, since those files will also be written to disk.
+ Furthermore, on versions of Linux before 5.8, I/O errors encountered
+ while writing data to disk may not be reported to
+ <span class="productname">PostgreSQL</span>, and relevant error messages may
+ appear only in kernel logs.
+ </p><p>
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-compatible.html" title="20.13. Version and Platform Compatibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-preset.html" title="20.15. Preset Options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.13. Version and Platform Compatibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.15. Preset Options</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-file-locations.html b/doc/src/sgml/html/runtime-config-file-locations.html
new file mode 100644
index 0000000..73cf1b2
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-file-locations.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.2. File Locations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="config-setting.html" title="20.1. Setting Parameters" /><link rel="next" href="runtime-config-connection.html" title="20.3. Connections and Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.2. File Locations</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="config-setting.html" title="20.1. Setting Parameters">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-connection.html" title="20.3. Connections and Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-FILE-LOCATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.2. File Locations</h2></div></div></div><p>
+ In addition to the <code class="filename">postgresql.conf</code> file
+ already mentioned, <span class="productname">PostgreSQL</span> uses
+ two other manually-edited configuration files, which control
+ client authentication (their use is discussed in <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a>). By default, all three
+ configuration files are stored in the database cluster's data
+ directory. The parameters described in this section allow the
+ configuration files to be placed elsewhere. (Doing so can ease
+ administration. In particular it is often easier to ensure that
+ the configuration files are properly backed-up when they are
+ kept separate.)
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-DATA-DIRECTORY"><span class="term"><code class="varname">data_directory</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.5.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the directory to use for data storage.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-CONFIG-FILE"><span class="term"><code class="varname">config_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.5.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the main server configuration file
+ (customarily called <code class="filename">postgresql.conf</code>).
+ This parameter can only be set on the <code class="command">postgres</code> command line.
+ </p></dd><dt id="GUC-HBA-FILE"><span class="term"><code class="varname">hba_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.5.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the configuration file for host-based authentication
+ (customarily called <code class="filename">pg_hba.conf</code>).
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-IDENT-FILE"><span class="term"><code class="varname">ident_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.5.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the configuration file for user name mapping
+ (customarily called <code class="filename">pg_ident.conf</code>).
+ This parameter can only be set at server start.
+ See also <a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a>.
+ </p></dd><dt id="GUC-EXTERNAL-PID-FILE"><span class="term"><code class="varname">external_pid_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.5.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the name of an additional process-ID (PID) file that the
+ server should create for use by server administration programs.
+ This parameter can only be set at server start.
+ </p></dd></dl></div><p>
+ In a default installation, none of the above parameters are set
+ explicitly. Instead, the
+ data directory is specified by the <code class="option">-D</code> command-line
+ option or the <code class="envar">PGDATA</code> environment variable, and the
+ configuration files are all found within the data directory.
+ </p><p>
+ If you wish to keep the configuration files elsewhere than the
+ data directory, the <code class="command">postgres</code> <code class="option">-D</code>
+ command-line option or <code class="envar">PGDATA</code> environment variable
+ must point to the directory containing the configuration files,
+ and the <code class="varname">data_directory</code> parameter must be set in
+ <code class="filename">postgresql.conf</code> (or on the command line) to show
+ where the data directory is actually located. Notice that
+ <code class="varname">data_directory</code> overrides <code class="option">-D</code> and
+ <code class="envar">PGDATA</code> for the location
+ of the data directory, but not for the location of the configuration
+ files.
+ </p><p>
+ If you wish, you can specify the configuration file names and locations
+ individually using the parameters <code class="varname">config_file</code>,
+ <code class="varname">hba_file</code> and/or <code class="varname">ident_file</code>.
+ <code class="varname">config_file</code> can only be specified on the
+ <code class="command">postgres</code> command line, but the others can be
+ set within the main configuration file. If all three parameters plus
+ <code class="varname">data_directory</code> are explicitly set, then it is not necessary
+ to specify <code class="option">-D</code> or <code class="envar">PGDATA</code>.
+ </p><p>
+ When setting any of these parameters, a relative path will be interpreted
+ with respect to the directory in which <code class="command">postgres</code>
+ is started.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="config-setting.html" title="20.1. Setting Parameters">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-connection.html" title="20.3. Connections and Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.1. Setting Parameters </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.3. Connections and Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-locks.html b/doc/src/sgml/html/runtime-config-locks.html
new file mode 100644
index 0000000..8091c87
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-locks.html
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.12. Lock Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-client.html" title="20.11. Client Connection Defaults" /><link rel="next" href="runtime-config-compatible.html" title="20.13. Version and Platform Compatibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.12. Lock Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-client.html" title="20.11. Client Connection Defaults">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-compatible.html" title="20.13. Version and Platform Compatibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-LOCKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.12. Lock Management</h2></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-DEADLOCK-TIMEOUT"><span class="term"><code class="varname">deadlock_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.15.2.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.15.2.1.1.4" class="indexterm"></a>
+ <a id="id-1.6.7.15.2.1.1.5" class="indexterm"></a>
+ </span></dt><dd><p>
+ This is the amount of time to wait on a lock
+ before checking to see if there is a deadlock condition. The
+ check for deadlock is relatively expensive, so the server doesn't run
+ it every time it waits for a lock. We optimistically assume
+ that deadlocks are not common in production applications and
+ just wait on the lock for a while before checking for a
+ deadlock. Increasing this value reduces the amount of time
+ wasted in needless deadlock checks, but slows down reporting of
+ real deadlock errors.
+ If this value is specified without units, it is taken as milliseconds.
+ The default is one second (<code class="literal">1s</code>),
+ which is probably about the smallest value you would want in
+ practice. On a heavily loaded server you might want to raise it.
+ Ideally the setting should exceed your typical transaction time,
+ so as to improve the odds that a lock will be released before
+ the waiter decides to check for deadlock.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ When <a class="xref" href="runtime-config-logging.html#GUC-LOG-LOCK-WAITS">log_lock_waits</a> is set,
+ this parameter also determines the amount of time to wait before
+ a log message is issued about the lock wait. If you are trying
+ to investigate locking delays you might want to set a shorter than
+ normal <code class="varname">deadlock_timeout</code>.
+ </p></dd><dt id="GUC-MAX-LOCKS-PER-TRANSACTION"><span class="term"><code class="varname">max_locks_per_transaction</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.15.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The shared lock table tracks locks on
+ <code class="varname">max_locks_per_transaction</code> * (<a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a> + <a class="xref" href="runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS">max_prepared_transactions</a>) objects (e.g., tables);
+ hence, no more than this many distinct objects can be locked at
+ any one time. This parameter controls the average number of object
+ locks allocated for each transaction; individual transactions
+ can lock more objects as long as the locks of all transactions
+ fit in the lock table. This is <span class="emphasis"><em>not</em></span> the number of
+ rows that can be locked; that value is unlimited. The default,
+ 64, has historically proven sufficient, but you might need to
+ raise this value if you have queries that touch many different
+ tables in a single transaction, e.g., query of a parent table with
+ many children. This parameter can only be set at server start.
+ </p><p>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </p></dd><dt id="GUC-MAX-PRED-LOCKS-PER-TRANSACTION"><span class="term"><code class="varname">max_pred_locks_per_transaction</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.15.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The shared predicate lock table tracks locks on
+ <code class="varname">max_pred_locks_per_transaction</code> * (<a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a> + <a class="xref" href="runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS">max_prepared_transactions</a>) objects (e.g., tables);
+ hence, no more than this many distinct objects can be locked at
+ any one time. This parameter controls the average number of object
+ locks allocated for each transaction; individual transactions
+ can lock more objects as long as the locks of all transactions
+ fit in the lock table. This is <span class="emphasis"><em>not</em></span> the number of
+ rows that can be locked; that value is unlimited. The default,
+ 64, has generally been sufficient in testing, but you might need to
+ raise this value if you have clients that touch many different
+ tables in a single serializable transaction. This parameter can
+ only be set at server start.
+ </p></dd><dt id="GUC-MAX-PRED-LOCKS-PER-RELATION"><span class="term"><code class="varname">max_pred_locks_per_relation</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.15.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This controls how many pages or tuples of a single relation can be
+ predicate-locked before the lock is promoted to covering the whole
+ relation. Values greater than or equal to zero mean an absolute
+ limit, while negative values
+ mean <a class="xref" href="runtime-config-locks.html#GUC-MAX-PRED-LOCKS-PER-TRANSACTION">max_pred_locks_per_transaction</a> divided by
+ the absolute value of this setting. The default is -2, which keeps
+ the behavior from previous versions of <span class="productname">PostgreSQL</span>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-MAX-PRED-LOCKS-PER-PAGE"><span class="term"><code class="varname">max_pred_locks_per_page</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.15.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This controls how many rows on a single page can be predicate-locked
+ before the lock is promoted to covering the whole page. The default
+ is 2. This parameter can only be set in
+ the <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-client.html" title="20.11. Client Connection Defaults">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-compatible.html" title="20.13. Version and Platform Compatibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.11. Client Connection Defaults </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.13. Version and Platform Compatibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-logging.html b/doc/src/sgml/html/runtime-config-logging.html
new file mode 100644
index 0000000..11351c3
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-logging.html
@@ -0,0 +1,938 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.8. Error Reporting and Logging</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-query.html" title="20.7. Query Planning" /><link rel="next" href="runtime-config-statistics.html" title="20.9. Run-time Statistics" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.8. Error Reporting and Logging</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-query.html" title="20.7. Query Planning">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-statistics.html" title="20.9. Run-time Statistics">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-LOGGING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.8. Error Reporting and Logging</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">20.8.1. Where to Log</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">20.8.2. When to Log</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">20.8.3. What to Log</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-CSVLOG">20.8.4. Using CSV-Format Log Output</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-JSONLOG">20.8.5. Using JSON-Format Log Output</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#id-1.6.7.11.8">20.8.6. Process Title</a></span></dt></dl></div><a id="id-1.6.7.11.2" class="indexterm"></a><div class="sect2" id="RUNTIME-CONFIG-LOGGING-WHERE"><div class="titlepage"><div><div><h3 class="title">20.8.1. Where to Log</h3></div></div></div><a id="id-1.6.7.11.3.2" class="indexterm"></a><a id="id-1.6.7.11.3.3" class="indexterm"></a><div class="variablelist"><dl class="variablelist"><dt id="GUC-LOG-DESTINATION"><span class="term"><code class="varname">log_destination</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.3.4.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <span class="productname">PostgreSQL</span> supports several methods
+ for logging server messages, including
+ <span class="systemitem">stderr</span>, <span class="systemitem">csvlog</span>,
+ <span class="systemitem">jsonlog</span>, and
+ <span class="systemitem">syslog</span>. On Windows,
+ <span class="systemitem">eventlog</span> is also supported. Set this
+ parameter to a list of desired log destinations separated by
+ commas. The default is to log to <span class="systemitem">stderr</span>
+ only.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ If <span class="systemitem">csvlog</span> is included in <code class="varname">log_destination</code>,
+ log entries are output in <span class="quote">“<span class="quote">comma separated
+ value</span>”</span> (<acronym class="acronym">CSV</acronym>) format, which is convenient for
+ loading logs into programs.
+ See <a class="xref" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-CSVLOG" title="20.8.4. Using CSV-Format Log Output">Section 20.8.4</a> for details.
+ <a class="xref" href="runtime-config-logging.html#GUC-LOGGING-COLLECTOR">logging_collector</a> must be enabled to generate
+ CSV-format log output.
+ </p><p>
+ If <span class="systemitem">jsonlog</span> is included in
+ <code class="varname">log_destination</code>, log entries are output in
+ <acronym class="acronym">JSON</acronym> format, which is convenient for loading logs
+ into programs.
+ See <a class="xref" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-JSONLOG" title="20.8.5. Using JSON-Format Log Output">Section 20.8.5</a> for details.
+ <a class="xref" href="runtime-config-logging.html#GUC-LOGGING-COLLECTOR">logging_collector</a> must be enabled to generate
+ JSON-format log output.
+ </p><p>
+ When either <span class="systemitem">stderr</span>,
+ <span class="systemitem">csvlog</span> or <span class="systemitem">jsonlog</span> are
+ included, the file <code class="filename">current_logfiles</code> is created to
+ record the location of the log file(s) currently in use by the logging
+ collector and the associated logging destination. This provides a
+ convenient way to find the logs currently in use by the instance. Here
+ is an example of this file's content:
+</p><pre class="programlisting">
+stderr log/postgresql.log
+csvlog log/postgresql.csv
+jsonlog log/postgresql.json
+</pre><p>
+
+ <code class="filename">current_logfiles</code> is recreated when a new log file
+ is created as an effect of rotation, and
+ when <code class="varname">log_destination</code> is reloaded. It is removed when
+ none of <span class="systemitem">stderr</span>,
+ <span class="systemitem">csvlog</span> or <span class="systemitem">jsonlog</span> are
+ included in <code class="varname">log_destination</code>, and when the logging
+ collector is disabled.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ On most Unix systems, you will need to alter the configuration of
+ your system's <span class="application">syslog</span> daemon in order
+ to make use of the <span class="systemitem">syslog</span> option for
+ <code class="varname">log_destination</code>. <span class="productname">PostgreSQL</span>
+ can log to <span class="application">syslog</span> facilities
+ <code class="literal">LOCAL0</code> through <code class="literal">LOCAL7</code> (see <a class="xref" href="runtime-config-logging.html#GUC-SYSLOG-FACILITY">syslog_facility</a>), but the default
+ <span class="application">syslog</span> configuration on most platforms
+ will discard all such messages. You will need to add something like:
+</p><pre class="programlisting">
+local0.* /var/log/postgresql
+</pre><p>
+ to the <span class="application">syslog</span> daemon's configuration file
+ to make it work.
+ </p><p>
+ On Windows, when you use the <code class="literal">eventlog</code>
+ option for <code class="varname">log_destination</code>, you should
+ register an event source and its library with the operating
+ system so that the Windows Event Viewer can display event
+ log messages cleanly.
+ See <a class="xref" href="event-log-registration.html" title="19.12. Registering Event Log on Windows">Section 19.12</a> for details.
+ </p></div></dd><dt id="GUC-LOGGING-COLLECTOR"><span class="term"><code class="varname">logging_collector</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.3.4.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter enables the <em class="firstterm">logging collector</em>, which
+ is a background process that captures log messages
+ sent to <span class="systemitem">stderr</span> and redirects them into log files.
+ This approach is often more useful than
+ logging to <span class="application">syslog</span>, since some types of messages
+ might not appear in <span class="application">syslog</span> output. (One common
+ example is dynamic-linker failure messages; another is error messages
+ produced by scripts such as <code class="varname">archive_command</code>.)
+ This parameter can only be set at server start.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ It is possible to log to <span class="systemitem">stderr</span> without using the
+ logging collector; the log messages will just go to wherever the
+ server's <span class="systemitem">stderr</span> is directed. However, that method is
+ only suitable for low log volumes, since it provides no convenient
+ way to rotate log files. Also, on some platforms not using the
+ logging collector can result in lost or garbled log output, because
+ multiple processes writing concurrently to the same log file can
+ overwrite each other's output.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ The logging collector is designed to never lose messages. This means
+ that in case of extremely high load, server processes could be
+ blocked while trying to send additional log messages when the
+ collector has fallen behind. In contrast, <span class="application">syslog</span>
+ prefers to drop messages if it cannot write them, which means it
+ may fail to log some messages in such cases but it will not block
+ the rest of the system.
+ </p></div></dd><dt id="GUC-LOG-DIRECTORY"><span class="term"><code class="varname">log_directory</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.3.4.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">logging_collector</code> is enabled,
+ this parameter determines the directory in which log files will be created.
+ It can be specified as an absolute path, or relative to the
+ cluster data directory.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="literal">log</code>.
+ </p></dd><dt id="GUC-LOG-FILENAME"><span class="term"><code class="varname">log_filename</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.3.4.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">logging_collector</code> is enabled,
+ this parameter sets the file names of the created log files. The value
+ is treated as a <code class="function">strftime</code> pattern,
+ so <code class="literal">%</code>-escapes can be used to specify time-varying
+ file names. (Note that if there are
+ any time-zone-dependent <code class="literal">%</code>-escapes, the computation
+ is done in the zone specified
+ by <a class="xref" href="runtime-config-logging.html#GUC-LOG-TIMEZONE">log_timezone</a>.)
+ The supported <code class="literal">%</code>-escapes are similar to those
+ listed in the Open Group's <a class="ulink" href="https://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html" target="_top">strftime
+ </a> specification.
+ Note that the system's <code class="function">strftime</code> is not used
+ directly, so platform-specific (nonstandard) extensions do not work.
+ The default is <code class="literal">postgresql-%Y-%m-%d_%H%M%S.log</code>.
+ </p><p>
+ If you specify a file name without escapes, you should plan to
+ use a log rotation utility to avoid eventually filling the
+ entire disk. In releases prior to 8.4, if
+ no <code class="literal">%</code> escapes were
+ present, <span class="productname">PostgreSQL</span> would append
+ the epoch of the new log file's creation time, but this is no
+ longer the case.
+ </p><p>
+ If CSV-format output is enabled in <code class="varname">log_destination</code>,
+ <code class="literal">.csv</code> will be appended to the timestamped
+ log file name to create the file name for CSV-format output.
+ (If <code class="varname">log_filename</code> ends in <code class="literal">.log</code>, the suffix is
+ replaced instead.)
+ </p><p>
+ If JSON-format output is enabled in <code class="varname">log_destination</code>,
+ <code class="literal">.json</code> will be appended to the timestamped
+ log file name to create the file name for JSON-format output.
+ (If <code class="varname">log_filename</code> ends in <code class="literal">.log</code>, the suffix is
+ replaced instead.)
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-LOG-FILE-MODE"><span class="term"><code class="varname">log_file_mode</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.3.4.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ On Unix systems this parameter sets the permissions for log files
+ when <code class="varname">logging_collector</code> is enabled. (On Microsoft
+ Windows this parameter is ignored.)
+ The parameter value is expected to be a numeric mode
+ specified in the format accepted by the
+ <code class="function">chmod</code> and <code class="function">umask</code>
+ system calls. (To use the customary octal format the number
+ must start with a <code class="literal">0</code> (zero).)
+ </p><p>
+ The default permissions are <code class="literal">0600</code>, meaning only the
+ server owner can read or write the log files. The other commonly
+ useful setting is <code class="literal">0640</code>, allowing members of the owner's
+ group to read the files. Note however that to make use of such a
+ setting, you'll need to alter <a class="xref" href="runtime-config-logging.html#GUC-LOG-DIRECTORY">log_directory</a> to
+ store the files somewhere outside the cluster data directory. In
+ any case, it's unwise to make the log files world-readable, since
+ they might contain sensitive data.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-LOG-ROTATION-AGE"><span class="term"><code class="varname">log_rotation_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.3.4.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">logging_collector</code> is enabled,
+ this parameter determines the maximum amount of time to use an
+ individual log file, after which a new log file will be created.
+ If this value is specified without units, it is taken as minutes.
+ The default is 24 hours.
+ Set to zero to disable time-based creation of new log files.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-LOG-ROTATION-SIZE"><span class="term"><code class="varname">log_rotation_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.3.4.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">logging_collector</code> is enabled,
+ this parameter determines the maximum size of an individual log file.
+ After this amount of data has been emitted into a log file,
+ a new log file will be created.
+ If this value is specified without units, it is taken as kilobytes.
+ The default is 10 megabytes.
+ Set to zero to disable size-based creation of new log files.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-LOG-TRUNCATE-ON-ROTATION"><span class="term"><code class="varname">log_truncate_on_rotation</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.3.4.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">logging_collector</code> is enabled,
+ this parameter will cause <span class="productname">PostgreSQL</span> to truncate (overwrite),
+ rather than append to, any existing log file of the same name.
+ However, truncation will occur only when a new file is being opened
+ due to time-based rotation, not during server startup or size-based
+ rotation. When off, pre-existing files will be appended to in
+ all cases. For example, using this setting in combination with
+ a <code class="varname">log_filename</code> like <code class="literal">postgresql-%H.log</code>
+ would result in generating twenty-four hourly log files and then
+ cyclically overwriting them.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ Example: To keep 7 days of logs, one log file per day named
+ <code class="literal">server_log.Mon</code>, <code class="literal">server_log.Tue</code>,
+ etc., and automatically overwrite last week's log with this week's log,
+ set <code class="varname">log_filename</code> to <code class="literal">server_log.%a</code>,
+ <code class="varname">log_truncate_on_rotation</code> to <code class="literal">on</code>, and
+ <code class="varname">log_rotation_age</code> to <code class="literal">1440</code>.
+ </p><p>
+ Example: To keep 24 hours of logs, one log file per hour, but
+ also rotate sooner if the log file size exceeds 1GB, set
+ <code class="varname">log_filename</code> to <code class="literal">server_log.%H%M</code>,
+ <code class="varname">log_truncate_on_rotation</code> to <code class="literal">on</code>,
+ <code class="varname">log_rotation_age</code> to <code class="literal">60</code>, and
+ <code class="varname">log_rotation_size</code> to <code class="literal">1000000</code>.
+ Including <code class="literal">%M</code> in <code class="varname">log_filename</code> allows
+ any size-driven rotations that might occur to select a file name
+ different from the hour's initial file name.
+ </p></dd><dt id="GUC-SYSLOG-FACILITY"><span class="term"><code class="varname">syslog_facility</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.11.3.4.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When logging to <span class="application">syslog</span> is enabled, this parameter
+ determines the <span class="application">syslog</span>
+ <span class="quote">“<span class="quote">facility</span>”</span> to be used. You can choose
+ from <code class="literal">LOCAL0</code>, <code class="literal">LOCAL1</code>,
+ <code class="literal">LOCAL2</code>, <code class="literal">LOCAL3</code>, <code class="literal">LOCAL4</code>,
+ <code class="literal">LOCAL5</code>, <code class="literal">LOCAL6</code>, <code class="literal">LOCAL7</code>;
+ the default is <code class="literal">LOCAL0</code>. See also the
+ documentation of your system's
+ <span class="application">syslog</span> daemon.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SYSLOG-IDENT"><span class="term"><code class="varname">syslog_ident</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.3.4.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When logging to <span class="application">syslog</span> is enabled, this parameter
+ determines the program name used to identify
+ <span class="productname">PostgreSQL</span> messages in
+ <span class="application">syslog</span> logs. The default is
+ <code class="literal">postgres</code>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SYSLOG-SEQUENCE-NUMBERS"><span class="term"><code class="varname">syslog_sequence_numbers</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.3.4.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When logging to <span class="application">syslog</span> and this is on (the
+ default), then each message will be prefixed by an increasing
+ sequence number (such as <code class="literal">[2]</code>). This circumvents
+ the <span class="quote">“<span class="quote">--- last message repeated N times ---</span>”</span> suppression
+ that many syslog implementations perform by default. In more modern
+ syslog implementations, repeated message suppression can be configured
+ (for example, <code class="literal">$RepeatedMsgReduction</code>
+ in <span class="productname">rsyslog</span>), so this might not be
+ necessary. Also, you could turn this off if you actually want to
+ suppress repeated messages.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-SYSLOG-SPLIT-MESSAGES"><span class="term"><code class="varname">syslog_split_messages</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.3.4.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When logging to <span class="application">syslog</span> is enabled, this parameter
+ determines how messages are delivered to syslog. When on (the
+ default), messages are split by lines, and long lines are split so
+ that they will fit into 1024 bytes, which is a typical size limit for
+ traditional syslog implementations. When off, PostgreSQL server log
+ messages are delivered to the syslog service as is, and it is up to
+ the syslog service to cope with the potentially bulky messages.
+ </p><p>
+ If syslog is ultimately logging to a text file, then the effect will
+ be the same either way, and it is best to leave the setting on, since
+ most syslog implementations either cannot handle large messages or
+ would need to be specially configured to handle them. But if syslog
+ is ultimately writing into some other medium, it might be necessary or
+ more useful to keep messages logically together.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-EVENT-SOURCE"><span class="term"><code class="varname">event_source</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.3.4.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When logging to <span class="application">event log</span> is enabled, this parameter
+ determines the program name used to identify
+ <span class="productname">PostgreSQL</span> messages in
+ the log. The default is <code class="literal">PostgreSQL</code>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-LOGGING-WHEN"><div class="titlepage"><div><div><h3 class="title">20.8.2. When to Log</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-LOG-MIN-MESSAGES"><span class="term"><code class="varname">log_min_messages</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.11.4.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls which <a class="link" href="runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS" title="Table 20.2. Message Severity Levels">message
+ levels</a> are written to the server log.
+ Valid values are <code class="literal">DEBUG5</code>, <code class="literal">DEBUG4</code>,
+ <code class="literal">DEBUG3</code>, <code class="literal">DEBUG2</code>, <code class="literal">DEBUG1</code>,
+ <code class="literal">INFO</code>, <code class="literal">NOTICE</code>, <code class="literal">WARNING</code>,
+ <code class="literal">ERROR</code>, <code class="literal">LOG</code>, <code class="literal">FATAL</code>, and
+ <code class="literal">PANIC</code>. Each level includes all the levels that
+ follow it. The later the level, the fewer messages are sent
+ to the log. The default is <code class="literal">WARNING</code>. Note that
+ <code class="literal">LOG</code> has a different rank here than in
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-MIN-ERROR-STATEMENT"><span class="term"><code class="varname">log_min_error_statement</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.11.4.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls which SQL statements that cause an error
+ condition are recorded in the server log. The current
+ SQL statement is included in the log entry for any message of
+ the specified
+ <a class="link" href="runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS" title="Table 20.2. Message Severity Levels">severity</a>
+ or higher.
+ Valid values are <code class="literal">DEBUG5</code>,
+ <code class="literal">DEBUG4</code>, <code class="literal">DEBUG3</code>,
+ <code class="literal">DEBUG2</code>, <code class="literal">DEBUG1</code>,
+ <code class="literal">INFO</code>, <code class="literal">NOTICE</code>,
+ <code class="literal">WARNING</code>, <code class="literal">ERROR</code>,
+ <code class="literal">LOG</code>,
+ <code class="literal">FATAL</code>, and <code class="literal">PANIC</code>.
+ The default is <code class="literal">ERROR</code>, which means statements
+ causing errors, log messages, fatal errors, or panics will be logged.
+ To effectively turn off logging of failing statements,
+ set this parameter to <code class="literal">PANIC</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-MIN-DURATION-STATEMENT"><span class="term"><code class="varname">log_min_duration_statement</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.4.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes the duration of each completed statement to be logged
+ if the statement ran for at least the specified amount of time.
+ For example, if you set it to <code class="literal">250ms</code>
+ then all SQL statements that run 250ms or longer will be
+ logged. Enabling this parameter can be helpful in tracking down
+ unoptimized queries in your applications.
+ If this value is specified without units, it is taken as milliseconds.
+ Setting this to zero prints all statement durations.
+ <code class="literal">-1</code> (the default) disables logging statement
+ durations.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ This overrides <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-DURATION-SAMPLE">log_min_duration_sample</a>,
+ meaning that queries with duration exceeding this setting are not
+ subject to sampling and are always logged.
+ </p><p>
+ For clients using extended query protocol, durations of the Parse,
+ Bind, and Execute steps are logged independently.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When using this option together with
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-STATEMENT">log_statement</a>,
+ the text of statements that are logged because of
+ <code class="varname">log_statement</code> will not be repeated in the
+ duration log message.
+ If you are not using <span class="application">syslog</span>, it is recommended
+ that you log the PID or session ID using
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-LINE-PREFIX">log_line_prefix</a>
+ so that you can link the statement message to the later
+ duration message using the process ID or session ID.
+ </p></div></dd><dt id="GUC-LOG-MIN-DURATION-SAMPLE"><span class="term"><code class="varname">log_min_duration_sample</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.4.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Allows sampling the duration of completed statements that ran for
+ at least the specified amount of time. This produces the same
+ kind of log entries as
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-DURATION-STATEMENT">log_min_duration_statement</a>, but only for a
+ subset of the executed statements, with sample rate controlled by
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-STATEMENT-SAMPLE-RATE">log_statement_sample_rate</a>.
+ For example, if you set it to <code class="literal">100ms</code> then all
+ SQL statements that run 100ms or longer will be considered for
+ sampling. Enabling this parameter can be helpful when the
+ traffic is too high to log all queries.
+ If this value is specified without units, it is taken as milliseconds.
+ Setting this to zero samples all statement durations.
+ <code class="literal">-1</code> (the default) disables sampling statement
+ durations.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ This setting has lower priority
+ than <code class="varname">log_min_duration_statement</code>, meaning that
+ statements with durations
+ exceeding <code class="varname">log_min_duration_statement</code> are not
+ subject to sampling and are always logged.
+ </p><p>
+ Other notes for <code class="varname">log_min_duration_statement</code>
+ apply also to this setting.
+ </p></dd><dt id="GUC-LOG-STATEMENT-SAMPLE-RATE"><span class="term"><code class="varname">log_statement_sample_rate</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.11.4.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines the fraction of statements with duration exceeding
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-DURATION-SAMPLE">log_min_duration_sample</a> that will be logged.
+ Sampling is stochastic, for example <code class="literal">0.5</code> means
+ there is statistically one chance in two that any given statement
+ will be logged.
+ The default is <code class="literal">1.0</code>, meaning to log all sampled
+ statements.
+ Setting this to zero disables sampled statement-duration logging,
+ the same as setting
+ <code class="varname">log_min_duration_sample</code> to
+ <code class="literal">-1</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-TRANSACTION-SAMPLE-RATE"><span class="term"><code class="varname">log_transaction_sample_rate</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.11.4.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the fraction of transactions whose statements are all logged,
+ in addition to statements logged for other reasons. It applies to
+ each new transaction regardless of its statements' durations.
+ Sampling is stochastic, for example <code class="literal">0.1</code> means
+ there is statistically one chance in ten that any given transaction
+ will be logged.
+ <code class="varname">log_transaction_sample_rate</code> can be helpful to
+ construct a sample of transactions.
+ The default is <code class="literal">0</code>, meaning not to log
+ statements from any additional transactions. Setting this
+ to <code class="literal">1</code> logs all statements of all transactions.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Like all statement-logging options, this option can add significant
+ overhead.
+ </p></div></dd><dt id="GUC-LOG-STARTUP-PROGRESS-INTERVAL"><span class="term"><code class="varname">log_startup_progress_interval</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.4.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the amount of time after which the startup process will log
+ a message about a long-running operation that is still in progress,
+ as well as the interval between further progress messages for that
+ operation. The default is 10 seconds. A setting of <code class="literal">0</code>
+ disables the feature. If this value is specified without units,
+ it is taken as milliseconds. This setting is applied separately to
+ each operation.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ For example, if syncing the data directory takes 25 seconds and
+ thereafter resetting unlogged relations takes 8 seconds, and if this
+ setting has the default value of 10 seconds, then a messages will be
+ logged for syncing the data directory after it has been in progress
+ for 10 seconds and again after it has been in progress for 20 seconds,
+ but nothing will be logged for resetting unlogged relations.
+ </p></dd></dl></div><p>
+ <a class="xref" href="runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS" title="Table 20.2. Message Severity Levels">Table 20.2</a> explains the message
+ severity levels used by <span class="productname">PostgreSQL</span>. If logging output
+ is sent to <span class="systemitem">syslog</span> or Windows'
+ <span class="systemitem">eventlog</span>, the severity levels are translated
+ as shown in the table.
+ </p><div class="table" id="RUNTIME-CONFIG-SEVERITY-LEVELS"><p class="title"><strong>Table 20.2. Message Severity Levels</strong></p><div class="table-contents"><table class="table" summary="Message Severity Levels" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Severity</th><th>Usage</th><th><span class="systemitem">syslog</span></th><th><span class="systemitem">eventlog</span></th></tr></thead><tbody><tr><td><code class="literal">DEBUG1 .. DEBUG5</code></td><td>Provides successively-more-detailed information for use by
+ developers.</td><td><code class="literal">DEBUG</code></td><td><code class="literal">INFORMATION</code></td></tr><tr><td><code class="literal">INFO</code></td><td>Provides information implicitly requested by the user,
+ e.g., output from <code class="command">VACUUM VERBOSE</code>.</td><td><code class="literal">INFO</code></td><td><code class="literal">INFORMATION</code></td></tr><tr><td><code class="literal">NOTICE</code></td><td>Provides information that might be helpful to users, e.g.,
+ notice of truncation of long identifiers.</td><td><code class="literal">NOTICE</code></td><td><code class="literal">INFORMATION</code></td></tr><tr><td><code class="literal">WARNING</code></td><td>Provides warnings of likely problems, e.g., <code class="command">COMMIT</code>
+ outside a transaction block.</td><td><code class="literal">NOTICE</code></td><td><code class="literal">WARNING</code></td></tr><tr><td><code class="literal">ERROR</code></td><td>Reports an error that caused the current command to
+ abort.</td><td><code class="literal">WARNING</code></td><td><code class="literal">ERROR</code></td></tr><tr><td><code class="literal">LOG</code></td><td>Reports information of interest to administrators, e.g.,
+ checkpoint activity.</td><td><code class="literal">INFO</code></td><td><code class="literal">INFORMATION</code></td></tr><tr><td><code class="literal">FATAL</code></td><td>Reports an error that caused the current session to
+ abort.</td><td><code class="literal">ERR</code></td><td><code class="literal">ERROR</code></td></tr><tr><td><code class="literal">PANIC</code></td><td>Reports an error that caused all database sessions to abort.</td><td><code class="literal">CRIT</code></td><td><code class="literal">ERROR</code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="RUNTIME-CONFIG-LOGGING-WHAT"><div class="titlepage"><div><div><h3 class="title">20.8.3. What to Log</h3></div></div></div><div class="note"><h3 class="title">Note</h3><p>
+ What you choose to log can have security implications; see
+ <a class="xref" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Section 25.3</a>.
+ </p></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-APPLICATION-NAME"><span class="term"><code class="varname">application_name</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.5.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The <code class="varname">application_name</code> can be any string of less than
+ <code class="symbol">NAMEDATALEN</code> characters (64 characters in a standard build).
+ It is typically set by an application upon connection to the server.
+ The name will be displayed in the <code class="structname">pg_stat_activity</code> view
+ and included in CSV log entries. It can also be included in regular
+ log entries via the <a class="xref" href="runtime-config-logging.html#GUC-LOG-LINE-PREFIX">log_line_prefix</a> parameter.
+ Only printable ASCII characters may be used in the
+ <code class="varname">application_name</code> value. Other characters will be
+ replaced with question marks (<code class="literal">?</code>).
+ </p></dd><dt><span class="term"><code class="varname">debug_print_parse</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.2.1.3" class="indexterm"></a>
+ <br /></span><span class="term"><code class="varname">debug_print_rewritten</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.2.2.3" class="indexterm"></a>
+ <br /></span><span class="term"><code class="varname">debug_print_plan</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.2.3.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ These parameters enable various debugging output to be emitted.
+ When set, they print the resulting parse tree, the query rewriter
+ output, or the execution plan for each executed query.
+ These messages are emitted at <code class="literal">LOG</code> message level, so by
+ default they will appear in the server log but will not be sent to the
+ client. You can change that by adjusting
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> and/or
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-MESSAGES">log_min_messages</a>.
+ These parameters are off by default.
+ </p></dd><dt><span class="term"><code class="varname">debug_pretty_print</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When set, <code class="varname">debug_pretty_print</code> indents the messages
+ produced by <code class="varname">debug_print_parse</code>,
+ <code class="varname">debug_print_rewritten</code>, or
+ <code class="varname">debug_print_plan</code>. This results in more readable
+ but much longer output than the <span class="quote">“<span class="quote">compact</span>”</span> format used when
+ it is off. It is on by default.
+ </p></dd><dt id="GUC-LOG-AUTOVACUUM-MIN-DURATION"><span class="term"><code class="varname">log_autovacuum_min_duration</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.5.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes each action executed by autovacuum to be logged if it ran for at
+ least the specified amount of time. Setting this to zero logs
+ all autovacuum actions. <code class="literal">-1</code> disables logging autovacuum
+ actions. If this value is specified without units, it is taken as milliseconds.
+ For example, if you set this to
+ <code class="literal">250ms</code> then all automatic vacuums and analyzes that run
+ 250ms or longer will be logged. In addition, when this parameter is
+ set to any value other than <code class="literal">-1</code>, a message will be
+ logged if an autovacuum action is skipped due to a conflicting lock or a
+ concurrently dropped relation. The default is <code class="literal">10min</code>.
+ Enabling this parameter can be helpful in tracking autovacuum activity.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line; but the setting can be overridden for
+ individual tables by changing table storage parameters.
+ </p></dd><dt id="GUC-LOG-CHECKPOINTS"><span class="term"><code class="varname">log_checkpoints</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes checkpoints and restartpoints to be logged in the server log.
+ Some statistics are included in the log messages, including the number
+ of buffers written and the time spent writing them.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line. The default is on.
+ </p></dd><dt id="GUC-LOG-CONNECTIONS"><span class="term"><code class="varname">log_connections</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes each attempted connection to the server to be logged,
+ as well as successful completion of both client authentication (if
+ necessary) and authorization.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this parameter at session start,
+ and it cannot be changed at all within a session.
+ The default is <code class="literal">off</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Some client programs, like <span class="application">psql</span>, attempt
+ to connect twice while determining if a password is required, so
+ duplicate <span class="quote">“<span class="quote">connection received</span>”</span> messages do not
+ necessarily indicate a problem.
+ </p></div></dd><dt id="GUC-LOG-DISCONNECTIONS"><span class="term"><code class="varname">log_disconnections</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes session terminations to be logged. The log output
+ provides information similar to <code class="varname">log_connections</code>,
+ plus the duration of the session.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this parameter at session start,
+ and it cannot be changed at all within a session.
+ The default is <code class="literal">off</code>.
+ </p></dd><dt id="GUC-LOG-DURATION"><span class="term"><code class="varname">log_duration</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes the duration of every completed statement to be logged.
+ The default is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ For clients using extended query protocol, durations of the Parse,
+ Bind, and Execute steps are logged independently.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The difference between enabling <code class="varname">log_duration</code> and setting
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-MIN-DURATION-STATEMENT">log_min_duration_statement</a> to zero is that
+ exceeding <code class="varname">log_min_duration_statement</code> forces the text of
+ the query to be logged, but this option doesn't. Thus, if
+ <code class="varname">log_duration</code> is <code class="literal">on</code> and
+ <code class="varname">log_min_duration_statement</code> has a positive value, all
+ durations are logged but the query text is included only for
+ statements exceeding the threshold. This behavior can be useful for
+ gathering statistics in high-load installations.
+ </p></div></dd><dt id="GUC-LOG-ERROR-VERBOSITY"><span class="term"><code class="varname">log_error_verbosity</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.11.5.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the amount of detail written in the server log for each
+ message that is logged. Valid values are <code class="literal">TERSE</code>,
+ <code class="literal">DEFAULT</code>, and <code class="literal">VERBOSE</code>, each adding more
+ fields to displayed messages. <code class="literal">TERSE</code> excludes
+ the logging of <code class="literal">DETAIL</code>, <code class="literal">HINT</code>,
+ <code class="literal">QUERY</code>, and <code class="literal">CONTEXT</code> error information.
+ <code class="literal">VERBOSE</code> output includes the <code class="symbol">SQLSTATE</code> error
+ code (see also <a class="xref" href="errcodes-appendix.html" title="Appendix A. PostgreSQL Error Codes">Appendix A</a>) and the source code file name, function name,
+ and line number that generated the error.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-HOSTNAME"><span class="term"><code class="varname">log_hostname</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ By default, connection log messages only show the IP address of the
+ connecting host. Turning this parameter on causes logging of the
+ host name as well. Note that depending on your host name resolution
+ setup this might impose a non-negligible performance penalty.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-LOG-LINE-PREFIX"><span class="term"><code class="varname">log_line_prefix</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.5.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This is a <code class="function">printf</code>-style string that is output at the
+ beginning of each log line.
+ <code class="literal">%</code> characters begin <span class="quote">“<span class="quote">escape sequences</span>”</span>
+ that are replaced with status information as outlined below.
+ Unrecognized escapes are ignored. Other
+ characters are copied straight to the log line. Some escapes are
+ only recognized by session processes, and will be treated as empty by
+ background processes such as the main server process. Status
+ information may be aligned either left or right by specifying a
+ numeric literal after the % and before the option. A negative
+ value will cause the status information to be padded on the
+ right with spaces to give it a minimum width, whereas a positive
+ value will pad on the left. Padding can be useful to aid human
+ readability in log files.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line. The default is
+ <code class="literal">'%m [%p] '</code> which logs a time stamp and the process ID.
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Escape</th><th>Effect</th><th>Session only</th></tr></thead><tbody><tr><td><code class="literal">%a</code></td><td>Application name</td><td>yes</td></tr><tr><td><code class="literal">%u</code></td><td>User name</td><td>yes</td></tr><tr><td><code class="literal">%d</code></td><td>Database name</td><td>yes</td></tr><tr><td><code class="literal">%r</code></td><td>Remote host name or IP address, and remote port</td><td>yes</td></tr><tr><td><code class="literal">%h</code></td><td>Remote host name or IP address</td><td>yes</td></tr><tr><td><code class="literal">%b</code></td><td>Backend type</td><td>no</td></tr><tr><td><code class="literal">%p</code></td><td>Process ID</td><td>no</td></tr><tr><td><code class="literal">%P</code></td><td>Process ID of the parallel group leader, if this process
+ is a parallel query worker</td><td>no</td></tr><tr><td><code class="literal">%t</code></td><td>Time stamp without milliseconds</td><td>no</td></tr><tr><td><code class="literal">%m</code></td><td>Time stamp with milliseconds</td><td>no</td></tr><tr><td><code class="literal">%n</code></td><td>Time stamp with milliseconds (as a Unix epoch)</td><td>no</td></tr><tr><td><code class="literal">%i</code></td><td>Command tag: type of session's current command</td><td>yes</td></tr><tr><td><code class="literal">%e</code></td><td>SQLSTATE error code</td><td>no</td></tr><tr><td><code class="literal">%c</code></td><td>Session ID: see below</td><td>no</td></tr><tr><td><code class="literal">%l</code></td><td>Number of the log line for each session or process, starting at 1</td><td>no</td></tr><tr><td><code class="literal">%s</code></td><td>Process start time stamp</td><td>no</td></tr><tr><td><code class="literal">%v</code></td><td>Virtual transaction ID (backendID/localXID)</td><td>no</td></tr><tr><td><code class="literal">%x</code></td><td>Transaction ID (0 if none is assigned)</td><td>no</td></tr><tr><td><code class="literal">%q</code></td><td>Produces no output, but tells non-session
+ processes to stop at this point in the string; ignored by
+ session processes</td><td>no</td></tr><tr><td><code class="literal">%Q</code></td><td>Query identifier of the current query. Query
+ identifiers are not computed by default, so this field
+ will be zero unless <a class="xref" href="runtime-config-statistics.html#GUC-COMPUTE-QUERY-ID">compute_query_id</a>
+ parameter is enabled or a third-party module that computes
+ query identifiers is configured.</td><td>yes</td></tr><tr><td><code class="literal">%%</code></td><td>Literal <code class="literal">%</code></td><td>no</td></tr></tbody></table></div><p>
+ The backend type corresponds to the column
+ <code class="structfield">backend_type</code> in the view
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW" title="28.2.3. pg_stat_activity">
+ <code class="structname">pg_stat_activity</code></a>,
+ but additional types can appear
+ in the log that don't show in that view.
+ </p><p>
+ The <code class="literal">%c</code> escape prints a quasi-unique session identifier,
+ consisting of two 4-byte hexadecimal numbers (without leading zeros)
+ separated by a dot. The numbers are the process start time and the
+ process ID, so <code class="literal">%c</code> can also be used as a space saving way
+ of printing those items. For example, to generate the session
+ identifier from <code class="literal">pg_stat_activity</code>, use this query:
+</p><pre class="programlisting">
+SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' ||
+ to_hex(pid)
+FROM pg_stat_activity;
+</pre><p>
+
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ If you set a nonempty value for <code class="varname">log_line_prefix</code>,
+ you should usually make its last character be a space, to provide
+ visual separation from the rest of the log line. A punctuation
+ character can be used too.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ <span class="application">Syslog</span> produces its own
+ time stamp and process ID information, so you probably do not want to
+ include those escapes if you are logging to <span class="application">syslog</span>.
+ </p></div><div class="tip"><h3 class="title">Tip</h3><p>
+ The <code class="literal">%q</code> escape is useful when including information that is
+ only available in session (backend) context like user or database
+ name. For example:
+</p><pre class="programlisting">
+log_line_prefix = '%m [%p] %q%u@%d/%a '
+</pre><p>
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="literal">%Q</code> escape always reports a zero identifier
+ for lines output by <a class="xref" href="runtime-config-logging.html#GUC-LOG-STATEMENT">log_statement</a> because
+ <code class="varname">log_statement</code> generates output before an
+ identifier can be calculated, including invalid statements for
+ which an identifier cannot be calculated.
+ </p></div></dd><dt id="GUC-LOG-LOCK-WAITS"><span class="term"><code class="varname">log_lock_waits</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls whether a log message is produced when a session waits
+ longer than <a class="xref" href="runtime-config-locks.html#GUC-DEADLOCK-TIMEOUT">deadlock_timeout</a> to acquire a
+ lock. This is useful in determining if lock waits are causing
+ poor performance. The default is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-RECOVERY-CONFLICT-WAITS"><span class="term"><code class="varname">log_recovery_conflict_waits</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls whether a log message is produced when the startup process
+ waits longer than <code class="varname">deadlock_timeout</code>
+ for recovery conflicts. This is useful in determining if recovery
+ conflicts prevent the recovery from applying WAL.
+ </p><p>
+ The default is <code class="literal">off</code>. This parameter can only be set
+ in the <code class="filename">postgresql.conf</code> file or on the server
+ command line.
+ </p></dd><dt id="GUC-LOG-PARAMETER-MAX-LENGTH"><span class="term"><code class="varname">log_parameter_max_length</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.5.3.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If greater than zero, each bind parameter value logged with a
+ non-error statement-logging message is trimmed to this many bytes.
+ Zero disables logging of bind parameters for non-error statement logs.
+ <code class="literal">-1</code> (the default) allows bind parameters to be
+ logged in full.
+ If this value is specified without units, it is taken as bytes.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ This setting only affects log messages printed as a result of
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-STATEMENT">log_statement</a>,
+ <a class="xref" href="runtime-config-logging.html#GUC-LOG-DURATION">log_duration</a>, and related settings. Non-zero
+ values of this setting add some overhead, particularly if parameters
+ are sent in binary form, since then conversion to text is required.
+ </p></dd><dt id="GUC-LOG-PARAMETER-MAX-LENGTH-ON-ERROR"><span class="term"><code class="varname">log_parameter_max_length_on_error</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.5.3.15.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If greater than zero, each bind parameter value reported in error
+ messages is trimmed to this many bytes.
+ Zero (the default) disables including bind parameters in error
+ messages.
+ <code class="literal">-1</code> allows bind parameters to be printed in full.
+ If this value is specified without units, it is taken as bytes.
+ </p><p>
+ Non-zero values of this setting add overhead, as
+ <span class="productname">PostgreSQL</span> will need to store textual
+ representations of parameter values in memory at the start of each
+ statement, whether or not an error eventually occurs. The overhead
+ is greater when bind parameters are sent in binary form than when
+ they are sent as text, since the former case requires data
+ conversion while the latter only requires copying the string.
+ </p></dd><dt id="GUC-LOG-STATEMENT"><span class="term"><code class="varname">log_statement</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.11.5.3.16.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls which SQL statements are logged. Valid values are
+ <code class="literal">none</code> (off), <code class="literal">ddl</code>, <code class="literal">mod</code>, and
+ <code class="literal">all</code> (all statements). <code class="literal">ddl</code> logs all data definition
+ statements, such as <code class="command">CREATE</code>, <code class="command">ALTER</code>, and
+ <code class="command">DROP</code> statements. <code class="literal">mod</code> logs all
+ <code class="literal">ddl</code> statements, plus data-modifying statements
+ such as <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, <code class="command">TRUNCATE</code>,
+ and <code class="command">COPY FROM</code>.
+ <code class="command">PREPARE</code>, <code class="command">EXECUTE</code>, and
+ <code class="command">EXPLAIN ANALYZE</code> statements are also logged if their
+ contained command is of an appropriate type. For clients using
+ extended query protocol, logging occurs when an Execute message
+ is received, and values of the Bind parameters are included
+ (with any embedded single-quote marks doubled).
+ </p><p>
+ The default is <code class="literal">none</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Statements that contain simple syntax errors are not logged
+ even by the <code class="varname">log_statement</code> = <code class="literal">all</code> setting,
+ because the log message is emitted only after basic parsing has
+ been done to determine the statement type. In the case of extended
+ query protocol, this setting likewise does not log statements that
+ fail before the Execute phase (i.e., during parse analysis or
+ planning). Set <code class="varname">log_min_error_statement</code> to
+ <code class="literal">ERROR</code> (or lower) to log such statements.
+ </p><p>
+ Logged statements might reveal sensitive data and even contain
+ plaintext passwords.
+ </p></div></dd><dt id="GUC-LOG-REPLICATION-COMMANDS"><span class="term"><code class="varname">log_replication_commands</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.5.3.17.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Causes each replication command to be logged in the server log.
+ See <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a> for more information about
+ replication command. The default value is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-TEMP-FILES"><span class="term"><code class="varname">log_temp_files</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.11.5.3.18.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls logging of temporary file names and sizes.
+ Temporary files can be
+ created for sorts, hashes, and temporary query results.
+ If enabled by this setting, a log entry is emitted for each
+ temporary file when it is deleted.
+ A value of zero logs all temporary file information, while positive
+ values log only files whose size is greater than or equal to
+ the specified amount of data.
+ If this value is specified without units, it is taken as kilobytes.
+ The default setting is -1, which disables such logging.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-LOG-TIMEZONE"><span class="term"><code class="varname">log_timezone</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.5.3.19.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the time zone used for timestamps written in the server log.
+ Unlike <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a>, this value is cluster-wide,
+ so that all sessions will report timestamps consistently.
+ The built-in default is <code class="literal">GMT</code>, but that is typically
+ overridden in <code class="filename">postgresql.conf</code>; <span class="application">initdb</span>
+ will install a setting there corresponding to its system environment.
+ See <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a> for more information.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-LOGGING-CSVLOG"><div class="titlepage"><div><div><h3 class="title">20.8.4. Using CSV-Format Log Output</h3></div></div></div><p>
+ Including <code class="literal">csvlog</code> in the <code class="varname">log_destination</code> list
+ provides a convenient way to import log files into a database table.
+ This option emits log lines in comma-separated-values
+ (<acronym class="acronym">CSV</acronym>) format,
+ with these columns:
+ time stamp with milliseconds,
+ user name,
+ database name,
+ process ID,
+ client host:port number,
+ session ID,
+ per-session line number,
+ command tag,
+ session start time,
+ virtual transaction ID,
+ regular transaction ID,
+ error severity,
+ SQLSTATE code,
+ error message,
+ error message detail,
+ hint,
+ internal query that led to the error (if any),
+ character count of the error position therein,
+ error context,
+ user query that led to the error (if any and enabled by
+ <code class="varname">log_min_error_statement</code>),
+ character count of the error position therein,
+ location of the error in the PostgreSQL source code
+ (if <code class="varname">log_error_verbosity</code> is set to <code class="literal">verbose</code>),
+ application name, backend type, process ID of parallel group leader,
+ and query id.
+ Here is a sample table definition for storing CSV-format log output:
+
+</p><pre class="programlisting">
+CREATE TABLE postgres_log
+(
+ log_time timestamp(3) with time zone,
+ user_name text,
+ database_name text,
+ process_id integer,
+ connection_from text,
+ session_id text,
+ session_line_num bigint,
+ command_tag text,
+ session_start_time timestamp with time zone,
+ virtual_transaction_id text,
+ transaction_id bigint,
+ error_severity text,
+ sql_state_code text,
+ message text,
+ detail text,
+ hint text,
+ internal_query text,
+ internal_query_pos integer,
+ context text,
+ query text,
+ query_pos integer,
+ location text,
+ application_name text,
+ backend_type text,
+ leader_pid integer,
+ query_id bigint,
+ PRIMARY KEY (session_id, session_line_num)
+);
+</pre><p>
+ </p><p>
+ To import a log file into this table, use the <code class="command">COPY FROM</code>
+ command:
+
+</p><pre class="programlisting">
+COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
+</pre><p>
+ It is also possible to access the file as a foreign table, using
+ the supplied <a class="xref" href="file-fdw.html" title="F.16. file_fdw">file_fdw</a> module.
+ </p><p>
+ There are a few things you need to do to simplify importing CSV log
+ files:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ Set <code class="varname">log_filename</code> and
+ <code class="varname">log_rotation_age</code> to provide a consistent,
+ predictable naming scheme for your log files. This lets you
+ predict what the file name will be and know when an individual log
+ file is complete and therefore ready to be imported.
+ </p></li><li class="listitem"><p>
+ Set <code class="varname">log_rotation_size</code> to 0 to disable
+ size-based log rotation, as it makes the log file name difficult
+ to predict.
+ </p></li><li class="listitem"><p>
+ Set <code class="varname">log_truncate_on_rotation</code> to <code class="literal">on</code> so
+ that old log data isn't mixed with the new in the same file.
+ </p></li><li class="listitem"><p>
+ The table definition above includes a primary key specification.
+ This is useful to protect against accidentally importing the same
+ information twice. The <code class="command">COPY</code> command commits all of the
+ data it imports at one time, so any error will cause the entire
+ import to fail. If you import a partial log file and later import
+ the file again when it is complete, the primary key violation will
+ cause the import to fail. Wait until the log is complete and
+ closed before importing. This procedure will also protect against
+ accidentally importing a partial line that hasn't been completely
+ written, which would also cause <code class="command">COPY</code> to fail.
+ </p></li></ol></div><p>
+ </p></div><div class="sect2" id="RUNTIME-CONFIG-LOGGING-JSONLOG"><div class="titlepage"><div><div><h3 class="title">20.8.5. Using JSON-Format Log Output</h3></div></div></div><p>
+ Including <code class="literal">jsonlog</code> in the
+ <code class="varname">log_destination</code> list provides a convenient way to
+ import log files into many different programs. This option emits log
+ lines in <acronym class="acronym">JSON</acronym> format.
+ </p><p>
+ String fields with null values are excluded from output.
+ Additional fields may be added in the future. User applications that
+ process <code class="literal">jsonlog</code> output should ignore unknown fields.
+ </p><p>
+ Each log line is serialized as a JSON object with the set of keys and
+ their associated values shown in <a class="xref" href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-JSONLOG-KEYS-VALUES" title="Table 20.3. Keys and Values of JSON Log Entries">Table 20.3</a>.
+ </p><div class="table" id="RUNTIME-CONFIG-LOGGING-JSONLOG-KEYS-VALUES"><p class="title"><strong>Table 20.3. Keys and Values of JSON Log Entries</strong></p><div class="table-contents"><table class="table" summary="Keys and Values of JSON Log Entries" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Key name</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code class="literal">timestamp</code></td><td>string</td><td>Time stamp with milliseconds</td></tr><tr><td><code class="literal">user</code></td><td>string</td><td>User name</td></tr><tr><td><code class="literal">dbname</code></td><td>string</td><td>Database name</td></tr><tr><td><code class="literal">pid</code></td><td>number</td><td>Process ID</td></tr><tr><td><code class="literal">remote_host</code></td><td>string</td><td>Client host</td></tr><tr><td><code class="literal">remote_port</code></td><td>number</td><td>Client port</td></tr><tr><td><code class="literal">session_id</code></td><td>string</td><td>Session ID</td></tr><tr><td><code class="literal">line_num</code></td><td>number</td><td>Per-session line number</td></tr><tr><td><code class="literal">ps</code></td><td>string</td><td>Current ps display</td></tr><tr><td><code class="literal">session_start</code></td><td>string</td><td>Session start time</td></tr><tr><td><code class="literal">vxid</code></td><td>string</td><td>Virtual transaction ID</td></tr><tr><td><code class="literal">txid</code></td><td>string</td><td>Regular transaction ID</td></tr><tr><td><code class="literal">error_severity</code></td><td>string</td><td>Error severity</td></tr><tr><td><code class="literal">state_code</code></td><td>string</td><td>SQLSTATE code</td></tr><tr><td><code class="literal">message</code></td><td>string</td><td>Error message</td></tr><tr><td><code class="literal">detail</code></td><td>string</td><td>Error message detail</td></tr><tr><td><code class="literal">hint</code></td><td>string</td><td>Error message hint</td></tr><tr><td><code class="literal">internal_query</code></td><td>string</td><td>Internal query that led to the error</td></tr><tr><td><code class="literal">internal_position</code></td><td>number</td><td>Cursor index into internal query</td></tr><tr><td><code class="literal">context</code></td><td>string</td><td>Error context</td></tr><tr><td><code class="literal">statement</code></td><td>string</td><td>Client-supplied query string</td></tr><tr><td><code class="literal">cursor_position</code></td><td>number</td><td>Cursor index into query string</td></tr><tr><td><code class="literal">func_name</code></td><td>string</td><td>Error location function name</td></tr><tr><td><code class="literal">file_name</code></td><td>string</td><td>File name of error location</td></tr><tr><td><code class="literal">file_line_num</code></td><td>number</td><td>File line number of the error location</td></tr><tr><td><code class="literal">application_name</code></td><td>string</td><td>Client application name</td></tr><tr><td><code class="literal">backend_type</code></td><td>string</td><td>Type of backend</td></tr><tr><td><code class="literal">leader_pid</code></td><td>number</td><td>Process ID of leader for active parallel workers</td></tr><tr><td><code class="literal">query_id</code></td><td>number</td><td>Query ID</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.6.7.11.8"><div class="titlepage"><div><div><h3 class="title">20.8.6. Process Title</h3></div></div></div><p>
+ These settings control how process titles of server processes are
+ modified. Process titles are typically viewed using programs like
+ <span class="application">ps</span> or, on Windows, <span class="application">Process Explorer</span>.
+ See <a class="xref" href="monitoring-ps.html" title="28.1. Standard Unix Tools">Section 28.1</a> for details.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-CLUSTER-NAME"><span class="term"><code class="varname">cluster_name</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.11.8.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets a name that identifies this database cluster (instance) for
+ various purposes. The cluster name appears in the process title for
+ all server processes in this cluster. Moreover, it is the default
+ application name for a standby connection (see <a class="xref" href="runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES">synchronous_standby_names</a>.)
+ </p><p>
+ The name can be any string of less
+ than <code class="symbol">NAMEDATALEN</code> characters (64 characters in a standard
+ build). Only printable ASCII characters may be used in the
+ <code class="varname">cluster_name</code> value. Other characters will be
+ replaced with question marks (<code class="literal">?</code>). No name is shown
+ if this parameter is set to the empty string <code class="literal">''</code> (which is
+ the default). This parameter can only be set at server start.
+ </p></dd><dt id="GUC-UPDATE-PROCESS-TITLE"><span class="term"><code class="varname">update_process_title</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.11.8.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables updating of the process title every time a new SQL command
+ is received by the server.
+ This setting defaults to <code class="literal">on</code> on most platforms, but it
+ defaults to <code class="literal">off</code> on Windows due to that platform's larger
+ overhead for updating the process title.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-query.html" title="20.7. Query Planning">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-statistics.html" title="20.9. Run-time Statistics">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.7. Query Planning </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.9. Run-time Statistics</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-preset.html b/doc/src/sgml/html/runtime-config-preset.html
new file mode 100644
index 0000000..7dc5c0b
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-preset.html
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.15. Preset Options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-error-handling.html" title="20.14. Error Handling" /><link rel="next" href="runtime-config-custom.html" title="20.16. Customized Options" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.15. Preset Options</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-error-handling.html" title="20.14. Error Handling">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-custom.html" title="20.16. Customized Options">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-PRESET"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.15. Preset Options</h2></div></div></div><p>
+ The following <span class="quote">“<span class="quote">parameters</span>”</span> are read-only.
+ As such, they have been excluded from the sample
+ <code class="filename">postgresql.conf</code> file. These options report
+ various aspects of <span class="productname">PostgreSQL</span> behavior
+ that might be of interest to certain applications, particularly
+ administrative front-ends.
+ Most of them are determined when <span class="productname">PostgreSQL</span>
+ is compiled or when it is installed.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-BLOCK-SIZE"><span class="term"><code class="varname">block_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the size of a disk block. It is determined by the value
+ of <code class="literal">BLCKSZ</code> when building the server. The default
+ value is 8192 bytes. The meaning of some configuration
+ variables (such as <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>) is
+ influenced by <code class="varname">block_size</code>. See <a class="xref" href="runtime-config-resource.html" title="20.4. Resource Consumption">Section 20.4</a> for information.
+ </p></dd><dt id="GUC-DATA-CHECKSUMS"><span class="term"><code class="varname">data_checksums</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.18.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports whether data checksums are enabled for this cluster.
+ See <a class="xref" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS">data checksums</a> for more information.
+ </p></dd><dt id="GUC-DATA-DIRECTORY-MODE"><span class="term"><code class="varname">data_directory_mode</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ On Unix systems this parameter reports the permissions the data
+ directory (defined by <a class="xref" href="runtime-config-file-locations.html#GUC-DATA-DIRECTORY">data_directory</a>)
+ had at server startup.
+ (On Microsoft Windows this parameter will always display
+ <code class="literal">0700</code>.) See
+ <a class="xref" href="app-initdb.html#APP-INITDB-ALLOW-GROUP-ACCESS">group access</a> for more information.
+ </p></dd><dt id="GUC-DEBUG-ASSERTIONS"><span class="term"><code class="varname">debug_assertions</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.18.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports whether <span class="productname">PostgreSQL</span> has been built
+ with assertions enabled. That is the case if the
+ macro <code class="symbol">USE_ASSERT_CHECKING</code> is defined
+ when <span class="productname">PostgreSQL</span> is built (accomplished
+ e.g., by the <code class="command">configure</code> option
+ <code class="option">--enable-cassert</code>). By
+ default <span class="productname">PostgreSQL</span> is built without
+ assertions.
+ </p></dd><dt id="GUC-INTEGER-DATETIMES"><span class="term"><code class="varname">integer_datetimes</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.18.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports whether <span class="productname">PostgreSQL</span> was built with support for
+ 64-bit-integer dates and times. As of <span class="productname">PostgreSQL</span> 10,
+ this is always <code class="literal">on</code>.
+ </p></dd><dt id="GUC-IN-HOT-STANDBY"><span class="term"><code class="varname">in_hot_standby</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.18.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports whether the server is currently in hot standby mode. When
+ this is <code class="literal">on</code>, all transactions are forced to be
+ read-only. Within a session, this can change only if the server is
+ promoted to be primary. See <a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a> for more
+ information.
+ </p></dd><dt id="GUC-LC-COLLATE"><span class="term"><code class="varname">lc_collate</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.18.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the locale in which sorting of textual data is done.
+ See <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> for more information.
+ This value is determined when a database is created.
+ </p></dd><dt id="GUC-LC-CTYPE"><span class="term"><code class="varname">lc_ctype</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.18.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the locale that determines character classifications.
+ See <a class="xref" href="locale.html" title="24.1. Locale Support">Section 24.1</a> for more information.
+ This value is determined when a database is created.
+ Ordinarily this will be the same as <code class="varname">lc_collate</code>,
+ but for special applications it might be set differently.
+ </p></dd><dt id="GUC-MAX-FUNCTION-ARGS"><span class="term"><code class="varname">max_function_args</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the maximum number of function arguments. It is determined by
+ the value of <code class="literal">FUNC_MAX_ARGS</code> when building the server. The
+ default value is 100 arguments.
+ </p></dd><dt id="GUC-MAX-IDENTIFIER-LENGTH"><span class="term"><code class="varname">max_identifier_length</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the maximum identifier length. It is determined as one
+ less than the value of <code class="literal">NAMEDATALEN</code> when building
+ the server. The default value of <code class="literal">NAMEDATALEN</code> is
+ 64; therefore the default
+ <code class="varname">max_identifier_length</code> is 63 bytes, which
+ can be less than 63 characters when using multibyte encodings.
+ </p></dd><dt id="GUC-MAX-INDEX-KEYS"><span class="term"><code class="varname">max_index_keys</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the maximum number of index keys. It is determined by
+ the value of <code class="literal">INDEX_MAX_KEYS</code> when building the server. The
+ default value is 32 keys.
+ </p></dd><dt id="GUC-SEGMENT-SIZE"><span class="term"><code class="varname">segment_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the number of blocks (pages) that can be stored within a file
+ segment. It is determined by the value of <code class="literal">RELSEG_SIZE</code>
+ when building the server. The maximum size of a segment file in bytes
+ is equal to <code class="varname">segment_size</code> multiplied by
+ <code class="varname">block_size</code>; by default this is 1GB.
+ </p></dd><dt id="GUC-SERVER-ENCODING"><span class="term"><code class="varname">server_encoding</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.18.3.13.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.18.3.13.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the database encoding (character set).
+ It is determined when the database is created. Ordinarily,
+ clients need only be concerned with the value of <a class="xref" href="runtime-config-client.html#GUC-CLIENT-ENCODING">client_encoding</a>.
+ </p></dd><dt id="GUC-SERVER-VERSION"><span class="term"><code class="varname">server_version</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.18.3.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the version number of the server. It is determined by the
+ value of <code class="literal">PG_VERSION</code> when building the server.
+ </p></dd><dt id="GUC-SERVER-VERSION-NUM"><span class="term"><code class="varname">server_version_num</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.15.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the version number of the server as an integer. It is determined
+ by the value of <code class="literal">PG_VERSION_NUM</code> when building the server.
+ </p></dd><dt id="GUC-SHARED-MEMORY-SIZE"><span class="term"><code class="varname">shared_memory_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.16.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the size of the main shared memory area, rounded up to the
+ nearest megabyte.
+ </p></dd><dt id="GUC-SHARED-MEMORY-SIZE-IN-HUGE-PAGES"><span class="term"><code class="varname">shared_memory_size_in_huge_pages</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.17.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the number of huge pages that are needed for the main shared
+ memory area based on the specified <a class="xref" href="runtime-config-resource.html#GUC-HUGE-PAGE-SIZE">huge_page_size</a>.
+ If huge pages are not supported, this will be <code class="literal">-1</code>.
+ </p><p>
+ This setting is supported only on <span class="productname">Linux</span>. It
+ is always set to <code class="literal">-1</code> on other platforms. For more
+ details about using huge pages on <span class="productname">Linux</span>, see
+ <a class="xref" href="kernel-resources.html#LINUX-HUGE-PAGES" title="19.4.5. Linux Huge Pages">Section 19.4.5</a>.
+ </p></dd><dt id="GUC-SSL-LIBRARY"><span class="term"><code class="varname">ssl_library</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.18.3.18.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the name of the SSL library that this
+ <span class="productname">PostgreSQL</span> server was built with (even if
+ SSL is not currently configured or in use on this instance), for
+ example <code class="literal">OpenSSL</code>, or an empty string if none.
+ </p></dd><dt id="GUC-WAL-BLOCK-SIZE"><span class="term"><code class="varname">wal_block_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.19.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the size of a WAL disk block. It is determined by the value
+ of <code class="literal">XLOG_BLCKSZ</code> when building the server. The default value
+ is 8192 bytes.
+ </p></dd><dt id="GUC-WAL-SEGMENT-SIZE"><span class="term"><code class="varname">wal_segment_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.18.3.20.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Reports the size of write ahead log segments. The default value is
+ 16MB. See <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a> for more information.
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-error-handling.html" title="20.14. Error Handling">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-custom.html" title="20.16. Customized Options">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.14. Error Handling </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.16. Customized Options</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-query.html b/doc/src/sgml/html/runtime-config-query.html
new file mode 100644
index 0000000..30d4f36
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-query.html
@@ -0,0 +1,543 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.7. Query Planning</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-replication.html" title="20.6. Replication" /><link rel="next" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.7. Query Planning</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-replication.html" title="20.6. Replication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-QUERY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.7. Query Planning</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">20.7.1. Planner Method Configuration</a></span></dt><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">20.7.2. Planner Cost Constants</a></span></dt><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">20.7.3. Genetic Query Optimizer</a></span></dt><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">20.7.4. Other Planner Options</a></span></dt></dl></div><div class="sect2" id="RUNTIME-CONFIG-QUERY-ENABLE"><div class="titlepage"><div><div><h3 class="title">20.7.1. Planner Method Configuration</h3></div></div></div><p>
+ These configuration parameters provide a crude method of
+ influencing the query plans chosen by the query optimizer. If
+ the default plan chosen by the optimizer for a particular query
+ is not optimal, a <span class="emphasis"><em>temporary</em></span> solution is to use one
+ of these configuration parameters to force the optimizer to
+ choose a different plan.
+ Better ways to improve the quality of the
+ plans chosen by the optimizer include adjusting the planner cost
+ constants (see <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS" title="20.7.2. Planner Cost Constants">Section 20.7.2</a>),
+ running <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> manually, increasing
+ the value of the <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> configuration parameter,
+ and increasing the amount of statistics collected for
+ specific columns using <code class="command">ALTER TABLE SET
+ STATISTICS</code>.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-ENABLE-ASYNC-APPEND"><span class="term"><code class="varname">enable_async_append</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of async-aware
+ append plan types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-BITMAPSCAN"><span class="term"><code class="varname">enable_bitmapscan</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.2.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.10.2.3.2.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of bitmap-scan plan
+ types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-GATHERMERGE"><span class="term"><code class="varname">enable_gathermerge</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of gather
+ merge plan types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-HASHAGG"><span class="term"><code class="varname">enable_hashagg</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of hashed
+ aggregation plan types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-HASHJOIN"><span class="term"><code class="varname">enable_hashjoin</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of hash-join plan
+ types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-INCREMENTAL-SORT"><span class="term"><code class="varname">enable_incremental_sort</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of incremental sort steps.
+ The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-INDEXSCAN"><span class="term"><code class="varname">enable_indexscan</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.7.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.10.2.3.7.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of index-scan plan
+ types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-INDEXONLYSCAN"><span class="term"><code class="varname">enable_indexonlyscan</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of index-only-scan plan
+ types (see <a class="xref" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes">Section 11.9</a>).
+ The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-MATERIAL"><span class="term"><code class="varname">enable_material</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of materialization.
+ It is impossible to suppress materialization entirely,
+ but turning this variable off prevents the planner from inserting
+ materialize nodes except in cases where it is required for correctness.
+ The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-MEMOIZE"><span class="term"><code class="varname">enable_memoize</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of memoize plans for
+ caching results from parameterized scans inside nested-loop joins.
+ This plan type allows scans to the underlying plans to be skipped when
+ the results for the current parameters are already in the cache. Less
+ commonly looked up results may be evicted from the cache when more
+ space is required for new entries. The default is
+ <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-MERGEJOIN"><span class="term"><code class="varname">enable_mergejoin</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of merge-join plan
+ types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-NESTLOOP"><span class="term"><code class="varname">enable_nestloop</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of nested-loop join
+ plans. It is impossible to suppress nested-loop joins entirely,
+ but turning this variable off discourages the planner from using
+ one if there are other methods available. The default is
+ <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-PARALLEL-APPEND"><span class="term"><code class="varname">enable_parallel_append</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of parallel-aware
+ append plan types. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-PARALLEL-HASH"><span class="term"><code class="varname">enable_parallel_hash</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of hash-join plan
+ types with parallel hash. Has no effect if hash-join plans are not
+ also enabled. The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-PARTITION-PRUNING"><span class="term"><code class="varname">enable_partition_pruning</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.15.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's ability to eliminate a
+ partitioned table's partitions from query plans. This also controls
+ the planner's ability to generate query plans which allow the query
+ executor to remove (ignore) partitions during query execution. The
+ default is <code class="literal">on</code>.
+ See <a class="xref" href="ddl-partitioning.html#DDL-PARTITION-PRUNING" title="5.11.4. Partition Pruning">Section 5.11.4</a> for details.
+ </p></dd><dt id="GUC-ENABLE-PARTITIONWISE-JOIN"><span class="term"><code class="varname">enable_partitionwise_join</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.16.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of partitionwise join,
+ which allows a join between partitioned tables to be performed by
+ joining the matching partitions. Partitionwise join currently applies
+ only when the join conditions include all the partition keys, which
+ must be of the same data type and have one-to-one matching sets of
+ child partitions. Because partitionwise join planning can use
+ significantly more CPU time and memory during planning, the default is
+ <code class="literal">off</code>.
+ </p></dd><dt id="GUC-ENABLE-PARTITIONWISE-AGGREGATE"><span class="term"><code class="varname">enable_partitionwise_aggregate</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.17.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of partitionwise grouping
+ or aggregation, which allows grouping or aggregation on a partitioned
+ tables performed separately for each partition. If the <code class="literal">GROUP
+ BY</code> clause does not include the partition keys, only partial
+ aggregation can be performed on a per-partition basis, and
+ finalization must be performed later. Because partitionwise grouping
+ or aggregation can use significantly more CPU time and memory during
+ planning, the default is <code class="literal">off</code>.
+ </p></dd><dt id="GUC-ENABLE-SEQSCAN"><span class="term"><code class="varname">enable_seqscan</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.18.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.10.2.3.18.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of sequential scan
+ plan types. It is impossible to suppress sequential scans
+ entirely, but turning this variable off discourages the planner
+ from using one if there are other methods available. The
+ default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-SORT"><span class="term"><code class="varname">enable_sort</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.19.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of explicit sort
+ steps. It is impossible to suppress explicit sorts entirely,
+ but turning this variable off discourages the planner from
+ using one if there are other methods available. The default
+ is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-ENABLE-TIDSCAN"><span class="term"><code class="varname">enable_tidscan</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.2.3.20.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the query planner's use of <acronym class="acronym">TID</acronym>
+ scan plan types. The default is <code class="literal">on</code>.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-QUERY-CONSTANTS"><div class="titlepage"><div><div><h3 class="title">20.7.2. Planner Cost Constants</h3></div></div></div><p>
+ The <em class="firstterm">cost</em> variables described in this section are measured
+ on an arbitrary scale. Only their relative values matter, hence
+ scaling them all up or down by the same factor will result in no change
+ in the planner's choices. By default, these cost variables are based on
+ the cost of sequential page fetches; that is,
+ <code class="varname">seq_page_cost</code> is conventionally set to <code class="literal">1.0</code>
+ and the other cost variables are set with reference to that. But
+ you can use a different scale if you prefer, such as actual execution
+ times in milliseconds on a particular machine.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Unfortunately, there is no well-defined method for determining ideal
+ values for the cost variables. They are best treated as averages over
+ the entire mix of queries that a particular installation will receive. This
+ means that changing them on the basis of just a few experiments is very
+ risky.
+ </p></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-SEQ-PAGE-COST"><span class="term"><code class="varname">seq_page_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of a disk page fetch
+ that is part of a series of sequential fetches. The default is 1.0.
+ This value can be overridden for tables and indexes in a particular
+ tablespace by setting the tablespace parameter of the same name
+ (see <a class="xref" href="sql-altertablespace.html" title="ALTER TABLESPACE"><span class="refentrytitle">ALTER TABLESPACE</span></a>).
+ </p></dd><dt id="GUC-RANDOM-PAGE-COST"><span class="term"><code class="varname">random_page_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of a
+ non-sequentially-fetched disk page. The default is 4.0.
+ This value can be overridden for tables and indexes in a particular
+ tablespace by setting the tablespace parameter of the same name
+ (see <a class="xref" href="sql-altertablespace.html" title="ALTER TABLESPACE"><span class="refentrytitle">ALTER TABLESPACE</span></a>).
+ </p><p>
+ Reducing this value relative to <code class="varname">seq_page_cost</code>
+ will cause the system to prefer index scans; raising it will
+ make index scans look relatively more expensive. You can raise
+ or lower both values together to change the importance of disk I/O
+ costs relative to CPU costs, which are described by the following
+ parameters.
+ </p><p>
+ Random access to mechanical disk storage is normally much more expensive
+ than four times sequential access. However, a lower default is used
+ (4.0) because the majority of random accesses to disk, such as indexed
+ reads, are assumed to be in cache. The default value can be thought of
+ as modeling random access as 40 times slower than sequential, while
+ expecting 90% of random reads to be cached.
+ </p><p>
+ If you believe a 90% cache rate is an incorrect assumption
+ for your workload, you can increase random_page_cost to better
+ reflect the true cost of random storage reads. Correspondingly,
+ if your data is likely to be completely in cache, such as when
+ the database is smaller than the total server memory, decreasing
+ random_page_cost can be appropriate. Storage that has a low random
+ read cost relative to sequential, e.g., solid-state drives, might
+ also be better modeled with a lower value for random_page_cost,
+ e.g., <code class="literal">1.1</code>.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Although the system will let you set <code class="varname">random_page_cost</code> to
+ less than <code class="varname">seq_page_cost</code>, it is not physically sensible
+ to do so. However, setting them equal makes sense if the database
+ is entirely cached in RAM, since in that case there is no penalty
+ for touching pages out of sequence. Also, in a heavily-cached
+ database you should lower both values relative to the CPU parameters,
+ since the cost of fetching a page already in RAM is much smaller
+ than it would normally be.
+ </p></div></dd><dt id="GUC-CPU-TUPLE-COST"><span class="term"><code class="varname">cpu_tuple_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of processing
+ each row during a query.
+ The default is 0.01.
+ </p></dd><dt id="GUC-CPU-INDEX-TUPLE-COST"><span class="term"><code class="varname">cpu_index_tuple_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of processing
+ each index entry during an index scan.
+ The default is 0.005.
+ </p></dd><dt id="GUC-CPU-OPERATOR-COST"><span class="term"><code class="varname">cpu_operator_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of processing each
+ operator or function executed during a query.
+ The default is 0.0025.
+ </p></dd><dt id="GUC-PARALLEL-SETUP-COST"><span class="term"><code class="varname">parallel_setup_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of launching parallel worker
+ processes.
+ The default is 1000.
+ </p></dd><dt id="GUC-PARALLEL-TUPLE-COST"><span class="term"><code class="varname">parallel_tuple_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the cost of transferring one tuple
+ from a parallel worker process to another process.
+ The default is 0.1.
+ </p></dd><dt id="GUC-MIN-PARALLEL-TABLE-SCAN-SIZE"><span class="term"><code class="varname">min_parallel_table_scan_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.3.4.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the minimum amount of table data that must be scanned in order
+ for a parallel scan to be considered. For a parallel sequential scan,
+ the amount of table data scanned is always equal to the size of the
+ table, but when indexes are used the amount of table data
+ scanned will normally be less.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The default is 8 megabytes (<code class="literal">8MB</code>).
+ </p></dd><dt id="GUC-MIN-PARALLEL-INDEX-SCAN-SIZE"><span class="term"><code class="varname">min_parallel_index_scan_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.3.4.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the minimum amount of index data that must be scanned in order
+ for a parallel scan to be considered. Note that a parallel index scan
+ typically won't touch the entire index; it is the number of pages
+ which the planner believes will actually be touched by the scan which
+ is relevant. This parameter is also used to decide whether a
+ particular index can participate in a parallel vacuum. See
+ <a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a>.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The default is 512 kilobytes (<code class="literal">512kB</code>).
+ </p></dd><dt id="GUC-EFFECTIVE-CACHE-SIZE"><span class="term"><code class="varname">effective_cache_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.3.4.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's assumption about the effective size of the
+ disk cache that is available to a single query. This is
+ factored into estimates of the cost of using an index; a
+ higher value makes it more likely index scans will be used, a
+ lower value makes it more likely sequential scans will be
+ used. When setting this parameter you should consider both
+ <span class="productname">PostgreSQL</span>'s shared buffers and the
+ portion of the kernel's disk cache that will be used for
+ <span class="productname">PostgreSQL</span> data files, though some
+ data might exist in both places. Also, take
+ into account the expected number of concurrent queries on different
+ tables, since they will have to share the available
+ space. This parameter has no effect on the size of shared
+ memory allocated by <span class="productname">PostgreSQL</span>, nor
+ does it reserve kernel disk cache; it is used only for estimation
+ purposes. The system also does not assume data remains in
+ the disk cache between queries.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The default is 4 gigabytes (<code class="literal">4GB</code>).
+ (If <code class="symbol">BLCKSZ</code> is not 8kB, the default value scales
+ proportionally to it.)
+ </p></dd><dt id="GUC-JIT-ABOVE-COST"><span class="term"><code class="varname">jit_above_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the query cost above which JIT compilation is activated, if
+ enabled (see <a class="xref" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Chapter 32</a>).
+ Performing <acronym class="acronym">JIT</acronym> costs planning time but can
+ accelerate query execution.
+ Setting this to <code class="literal">-1</code> disables JIT compilation.
+ The default is <code class="literal">100000</code>.
+ </p></dd><dt id="GUC-JIT-INLINE-ABOVE-COST"><span class="term"><code class="varname">jit_inline_above_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the query cost above which JIT compilation attempts to inline
+ functions and operators. Inlining adds planning time, but can
+ improve execution speed. It is not meaningful to set this to less
+ than <code class="varname">jit_above_cost</code>.
+ Setting this to <code class="literal">-1</code> disables inlining.
+ The default is <code class="literal">500000</code>.
+ </p></dd><dt id="GUC-JIT-OPTIMIZE-ABOVE-COST"><span class="term"><code class="varname">jit_optimize_above_cost</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.3.4.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the query cost above which JIT compilation applies expensive
+ optimizations. Such optimization adds planning time, but can improve
+ execution speed. It is not meaningful to set this to less
+ than <code class="varname">jit_above_cost</code>, and it is unlikely to be
+ beneficial to set it to more
+ than <code class="varname">jit_inline_above_cost</code>.
+ Setting this to <code class="literal">-1</code> disables expensive optimizations.
+ The default is <code class="literal">500000</code>.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-QUERY-GEQO"><div class="titlepage"><div><div><h3 class="title">20.7.3. Genetic Query Optimizer</h3></div></div></div><p>
+ The genetic query optimizer (GEQO) is an algorithm that does query
+ planning using heuristic searching. This reduces planning time for
+ complex queries (those joining many relations), at the cost of producing
+ plans that are sometimes inferior to those found by the normal
+ exhaustive-search algorithm.
+ For more information see <a class="xref" href="geqo.html" title="Chapter 62. Genetic Query Optimizer">Chapter 62</a>.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-GEQO"><span class="term"><code class="varname">geqo</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.4.3.1.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.10.4.3.1.1.4" class="indexterm"></a>
+ <a id="id-1.6.7.10.4.3.1.1.5" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables genetic query optimization.
+ This is on by default. It is usually best not to turn it off in
+ production; the <code class="varname">geqo_threshold</code> variable provides
+ more granular control of GEQO.
+ </p></dd><dt id="GUC-GEQO-THRESHOLD"><span class="term"><code class="varname">geqo_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.4.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Use genetic query optimization to plan queries with at least
+ this many <code class="literal">FROM</code> items involved. (Note that a
+ <code class="literal">FULL OUTER JOIN</code> construct counts as only one <code class="literal">FROM</code>
+ item.) The default is 12. For simpler queries it is usually best
+ to use the regular, exhaustive-search planner, but for queries with
+ many tables the exhaustive search takes too long, often
+ longer than the penalty of executing a suboptimal plan. Thus,
+ a threshold on the size of the query is a convenient way to manage
+ use of GEQO.
+ </p></dd><dt id="GUC-GEQO-EFFORT"><span class="term"><code class="varname">geqo_effort</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.4.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the trade-off between planning time and query plan
+ quality in GEQO. This variable must be an integer in the
+ range from 1 to 10. The default value is five. Larger values
+ increase the time spent doing query planning, but also
+ increase the likelihood that an efficient query plan will be
+ chosen.
+ </p><p>
+ <code class="varname">geqo_effort</code> doesn't actually do anything
+ directly; it is only used to compute the default values for
+ the other variables that influence GEQO behavior (described
+ below). If you prefer, you can set the other parameters by
+ hand instead.
+ </p></dd><dt id="GUC-GEQO-POOL-SIZE"><span class="term"><code class="varname">geqo_pool_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.4.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the pool size used by GEQO, that is the
+ number of individuals in the genetic population. It must be
+ at least two, and useful values are typically 100 to 1000. If
+ it is set to zero (the default setting) then a suitable
+ value is chosen based on <code class="varname">geqo_effort</code> and
+ the number of tables in the query.
+ </p></dd><dt id="GUC-GEQO-GENERATIONS"><span class="term"><code class="varname">geqo_generations</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.4.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the number of generations used by GEQO, that is
+ the number of iterations of the algorithm. It must
+ be at least one, and useful values are in the same range as
+ the pool size. If it is set to zero (the default setting)
+ then a suitable value is chosen based on
+ <code class="varname">geqo_pool_size</code>.
+ </p></dd><dt id="GUC-GEQO-SELECTION-BIAS"><span class="term"><code class="varname">geqo_selection_bias</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.4.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the selection bias used by GEQO. The selection bias
+ is the selective pressure within the population. Values can be
+ from 1.50 to 2.00; the latter is the default.
+ </p></dd><dt id="GUC-GEQO-SEED"><span class="term"><code class="varname">geqo_seed</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.4.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the initial value of the random number generator used
+ by GEQO to select random paths through the join order search space.
+ The value can range from zero (the default) to one. Varying the
+ value changes the set of join paths explored, and may result in a
+ better or worse best path being found.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-QUERY-OTHER"><div class="titlepage"><div><div><h3 class="title">20.7.4. Other Planner Options</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-DEFAULT-STATISTICS-TARGET"><span class="term"><code class="varname">default_statistics_target</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.5.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the default statistics target for table columns without
+ a column-specific target set via <code class="command">ALTER TABLE
+ SET STATISTICS</code>. Larger values increase the time needed to
+ do <code class="command">ANALYZE</code>, but might improve the quality of the
+ planner's estimates. The default is 100. For more information
+ on the use of statistics by the <span class="productname">PostgreSQL</span>
+ query planner, refer to <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>.
+ </p></dd><dt id="GUC-CONSTRAINT-EXCLUSION"><span class="term"><code class="varname">constraint_exclusion</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.10.5.2.2.1.3" class="indexterm"></a>
+ <a id="id-1.6.7.10.5.2.2.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the query planner's use of table constraints to
+ optimize queries.
+ The allowed values of <code class="varname">constraint_exclusion</code> are
+ <code class="literal">on</code> (examine constraints for all tables),
+ <code class="literal">off</code> (never examine constraints), and
+ <code class="literal">partition</code> (examine constraints only for inheritance
+ child tables and <code class="literal">UNION ALL</code> subqueries).
+ <code class="literal">partition</code> is the default setting.
+ It is often used with traditional inheritance trees to improve
+ performance.
+ </p><p>
+ When this parameter allows it for a particular table, the planner
+ compares query conditions with the table's <code class="literal">CHECK</code>
+ constraints, and omits scanning tables for which the conditions
+ contradict the constraints. For example:
+
+</p><pre class="programlisting">
+CREATE TABLE parent(key integer, ...);
+CREATE TABLE child1000(check (key between 1000 and 1999)) INHERITS(parent);
+CREATE TABLE child2000(check (key between 2000 and 2999)) INHERITS(parent);
+...
+SELECT * FROM parent WHERE key = 2400;
+</pre><p>
+
+ With constraint exclusion enabled, this <code class="command">SELECT</code>
+ will not scan <code class="structname">child1000</code> at all, improving performance.
+ </p><p>
+ Currently, constraint exclusion is enabled by default
+ only for cases that are often used to implement table partitioning via
+ inheritance trees. Turning it on for all tables imposes extra
+ planning overhead that is quite noticeable on simple queries, and most
+ often will yield no benefit for simple queries. If you have no
+ tables that are partitioned using traditional inheritance, you might
+ prefer to turn it off entirely. (Note that the equivalent feature for
+ partitioned tables is controlled by a separate parameter,
+ <a class="xref" href="runtime-config-query.html#GUC-ENABLE-PARTITION-PRUNING">enable_partition_pruning</a>.)
+ </p><p>
+ Refer to <a class="xref" href="ddl-partitioning.html#DDL-PARTITIONING-CONSTRAINT-EXCLUSION" title="5.11.5. Partitioning and Constraint Exclusion">Section 5.11.5</a> for
+ more information on using constraint exclusion to implement
+ partitioning.
+ </p></dd><dt id="GUC-CURSOR-TUPLE-FRACTION"><span class="term"><code class="varname">cursor_tuple_fraction</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.5.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the fraction of a cursor's rows that
+ will be retrieved. The default is 0.1. Smaller values of this
+ setting bias the planner towards using <span class="quote">“<span class="quote">fast start</span>”</span> plans
+ for cursors, which will retrieve the first few rows quickly while
+ perhaps taking a long time to fetch all rows. Larger values
+ put more emphasis on the total estimated time. At the maximum
+ setting of 1.0, cursors are planned exactly like regular queries,
+ considering only the total estimated time and not how soon the
+ first rows might be delivered.
+ </p></dd><dt id="GUC-FROM-COLLAPSE-LIMIT"><span class="term"><code class="varname">from_collapse_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.5.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The planner will merge sub-queries into upper queries if the
+ resulting <code class="literal">FROM</code> list would have no more than
+ this many items. Smaller values reduce planning time but might
+ yield inferior query plans. The default is eight.
+ For more information see <a class="xref" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Section 14.3</a>.
+ </p><p>
+ Setting this value to <a class="xref" href="runtime-config-query.html#GUC-GEQO-THRESHOLD">geqo_threshold</a> or more
+ may trigger use of the GEQO planner, resulting in non-optimal
+ plans. See <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO" title="20.7.3. Genetic Query Optimizer">Section 20.7.3</a>.
+ </p></dd><dt id="GUC-JIT"><span class="term"><code class="varname">jit</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.10.5.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines whether <acronym class="acronym">JIT</acronym> compilation may be used by
+ <span class="productname">PostgreSQL</span>, if available (see <a class="xref" href="jit.html" title="Chapter 32. Just-in-Time Compilation (JIT)">Chapter 32</a>).
+ The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-JOIN-COLLAPSE-LIMIT"><span class="term"><code class="varname">join_collapse_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.10.5.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The planner will rewrite explicit <code class="literal">JOIN</code>
+ constructs (except <code class="literal">FULL JOIN</code>s) into lists of
+ <code class="literal">FROM</code> items whenever a list of no more than this many items
+ would result. Smaller values reduce planning time but might
+ yield inferior query plans.
+ </p><p>
+ By default, this variable is set the same as
+ <code class="varname">from_collapse_limit</code>, which is appropriate
+ for most uses. Setting it to 1 prevents any reordering of
+ explicit <code class="literal">JOIN</code>s. Thus, the explicit join order
+ specified in the query will be the actual order in which the
+ relations are joined. Because the query planner does not always choose
+ the optimal join order, advanced users can elect to
+ temporarily set this variable to 1, and then specify the join
+ order they desire explicitly.
+ For more information see <a class="xref" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Section 14.3</a>.
+ </p><p>
+ Setting this value to <a class="xref" href="runtime-config-query.html#GUC-GEQO-THRESHOLD">geqo_threshold</a> or more
+ may trigger use of the GEQO planner, resulting in non-optimal
+ plans. See <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO" title="20.7.3. Genetic Query Optimizer">Section 20.7.3</a>.
+ </p></dd><dt id="GUC-PLAN-CACHE_MODE"><span class="term"><code class="varname">plan_cache_mode</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.10.5.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Prepared statements (either explicitly prepared or implicitly
+ generated, for example by PL/pgSQL) can be executed using custom or
+ generic plans. Custom plans are made afresh for each execution
+ using its specific set of parameter values, while generic plans do
+ not rely on the parameter values and can be re-used across
+ executions. Thus, use of a generic plan saves planning time, but if
+ the ideal plan depends strongly on the parameter values then a
+ generic plan may be inefficient. The choice between these options
+ is normally made automatically, but it can be overridden
+ with <code class="varname">plan_cache_mode</code>.
+ The allowed values are <code class="literal">auto</code> (the default),
+ <code class="literal">force_custom_plan</code> and
+ <code class="literal">force_generic_plan</code>.
+ This setting is considered when a cached plan is to be executed,
+ not when it is prepared.
+ For more information see <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a>.
+ </p></dd><dt id="GUC-RECURSIVE-WORKTABLE-FACTOR"><span class="term"><code class="varname">recursive_worktable_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.10.5.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the planner's estimate of the average size of the working
+ table of a <a class="link" href="queries-with.html#QUERIES-WITH-RECURSIVE" title="7.8.2. Recursive Queries">recursive
+ query</a>, as a multiple of the estimated size of the initial
+ non-recursive term of the query. This helps the planner choose
+ the most appropriate method for joining the working table to the
+ query's other tables.
+ The default value is <code class="literal">10.0</code>. A smaller value
+ such as <code class="literal">1.0</code> can be helpful when the recursion
+ has low <span class="quote">“<span class="quote">fan-out</span>”</span> from one step to the next, as for
+ example in shortest-path queries. Graph analytics queries may
+ benefit from larger-than-default values.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-replication.html" title="20.6. Replication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.6. Replication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.8. Error Reporting and Logging</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-replication.html b/doc/src/sgml/html/runtime-config-replication.html
new file mode 100644
index 0000000..d3d74ca
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-replication.html
@@ -0,0 +1,562 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.6. Replication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-wal.html" title="20.5. Write Ahead Log" /><link rel="next" href="runtime-config-query.html" title="20.7. Query Planning" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.6. Replication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-wal.html" title="20.5. Write Ahead Log">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-query.html" title="20.7. Query Planning">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-REPLICATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.6. Replication</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">20.6.1. Sending Servers</a></span></dt><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-PRIMARY">20.6.2. Primary Server</a></span></dt><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">20.6.3. Standby Servers</a></span></dt><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SUBSCRIBER">20.6.4. Subscribers</a></span></dt></dl></div><p>
+ These settings control the behavior of the built-in
+ <em class="firstterm">streaming replication</em> feature (see
+ <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>). Servers will be either a
+ primary or a standby server. Primaries can send data, while standbys
+ are always receivers of replicated data. When cascading replication
+ (see <a class="xref" href="warm-standby.html#CASCADING-REPLICATION" title="27.2.7. Cascading Replication">Section 27.2.7</a>) is used, standby servers
+ can also be senders, as well as receivers.
+ Parameters are mainly for sending and standby servers, though some
+ parameters have meaning only on the primary server. Settings may vary
+ across the cluster without problems if that is required.
+ </p><div class="sect2" id="RUNTIME-CONFIG-REPLICATION-SENDER"><div class="titlepage"><div><div><h3 class="title">20.6.1. Sending Servers</h3></div></div></div><p>
+ These parameters can be set on any server that is
+ to send replication data to one or more standby servers.
+ The primary is always a sending server, so these parameters must
+ always be set on the primary.
+ The role and meaning of these parameters does not change after a
+ standby becomes the primary.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-MAX-WAL-SENDERS"><span class="term"><code class="varname">max_wal_senders</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.3.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum number of concurrent connections from standby
+ servers or streaming base backup clients (i.e., the maximum number of
+ simultaneously running WAL sender processes). The default is
+ <code class="literal">10</code>. The value <code class="literal">0</code> means
+ replication is disabled. Abrupt disconnection of a streaming client might
+ leave an orphaned connection slot behind until a timeout is reached,
+ so this parameter should be set slightly higher than the maximum
+ number of expected clients so disconnected clients can immediately
+ reconnect. This parameter can only be set at server start. Also,
+ <code class="varname">wal_level</code> must be set to
+ <code class="literal">replica</code> or higher to allow connections from standby
+ servers.
+ </p><p>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </p></dd><dt id="GUC-MAX-REPLICATION-SLOTS"><span class="term"><code class="varname">max_replication_slots</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.3.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum number of replication slots
+ (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a>) that the server
+ can support. The default is 10. This parameter can only be set at
+ server start.
+ Setting it to a lower value than the number of currently
+ existing replication slots will prevent the server from starting.
+ Also, <code class="varname">wal_level</code> must be set
+ to <code class="literal">replica</code> or higher to allow replication slots to
+ be used.
+ </p><p>
+ On the subscriber side, specifies how many replication origins (see
+ <a class="xref" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Chapter 50</a>) can be tracked simultaneously,
+ effectively limiting how many logical replication subscriptions can
+ be created on the server. Setting it to a lower value than the current
+ number of tracked replication origins (reflected in
+ <a class="link" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">pg_replication_origin_status</a>,
+ not <a class="link" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin">pg_replication_origin</a>)
+ will prevent the server from starting.
+ </p></dd><dt id="GUC-WAL-KEEP-SIZE"><span class="term"><code class="varname">wal_keep_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.3.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the minimum size of past log file segments kept in the
+ <code class="filename">pg_wal</code>
+ directory, in case a standby server needs to fetch them for streaming
+ replication. If a standby
+ server connected to the sending server falls behind by more than
+ <code class="varname">wal_keep_size</code> megabytes, the sending server might
+ remove a WAL segment still needed by the standby, in which case the
+ replication connection will be terminated. Downstream connections
+ will also eventually fail as a result. (However, the standby
+ server can recover by fetching the segment from archive, if WAL
+ archiving is in use.)
+ </p><p>
+ This sets only the minimum size of segments retained in
+ <code class="filename">pg_wal</code>; the system might need to retain more segments
+ for WAL archival or to recover from a checkpoint. If
+ <code class="varname">wal_keep_size</code> is zero (the default), the system
+ doesn't keep any extra segments for standby purposes, so the number
+ of old WAL segments available to standby servers is a function of
+ the location of the previous checkpoint and status of WAL
+ archiving.
+ If this value is specified without units, it is taken as megabytes.
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-MAX-SLOT-WAL-KEEP-SIZE"><span class="term"><code class="varname">max_slot_wal_keep_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.3.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specify the maximum size of WAL files
+ that <a class="link" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">replication
+ slots</a> are allowed to retain in the <code class="filename">pg_wal</code>
+ directory at checkpoint time.
+ If <code class="varname">max_slot_wal_keep_size</code> is -1 (the default),
+ replication slots may retain an unlimited amount of WAL files. Otherwise, if
+ restart_lsn of a replication slot falls behind the current LSN by more
+ than the given size, the standby using the slot may no longer be able
+ to continue replication due to removal of required WAL files. You
+ can see the WAL availability of replication slots
+ in <a class="link" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots">pg_replication_slots</a>.
+ If this value is specified without units, it is taken as megabytes.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-WAL-SENDER-TIMEOUT"><span class="term"><code class="varname">wal_sender_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.3.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Terminate replication connections that are inactive for longer
+ than this amount of time. This is useful for
+ the sending server to detect a standby crash or network outage.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 60 seconds.
+ A value of zero disables the timeout mechanism.
+ </p><p>
+ With a cluster distributed across multiple geographic
+ locations, using different values per location brings more flexibility
+ in the cluster management. A smaller value is useful for faster
+ failure detection with a standby having a low-latency network
+ connection, and a larger value helps in judging better the health
+ of a standby if located on a remote location, with a high-latency
+ network connection.
+ </p></dd><dt id="GUC-TRACK-COMMIT-TIMESTAMP"><span class="term"><code class="varname">track_commit_timestamp</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.9.3.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Record commit time of transactions. This parameter
+ can only be set in <code class="filename">postgresql.conf</code> file or on the server
+ command line. The default value is <code class="literal">off</code>.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-REPLICATION-PRIMARY"><div class="titlepage"><div><div><h3 class="title">20.6.2. Primary Server</h3></div></div></div><p>
+ These parameters can be set on the primary server that is
+ to send replication data to one or more standby servers.
+ Note that in addition to these parameters,
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-LEVEL">wal_level</a> must be set appropriately on the primary
+ server, and optionally WAL archiving can be enabled as
+ well (see <a class="xref" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING" title="20.5.3. Archiving">Section 20.5.3</a>).
+ The values of these parameters on standby servers are irrelevant,
+ although you may wish to set them there in preparation for the
+ possibility of a standby becoming the primary.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-SYNCHRONOUS-STANDBY-NAMES"><span class="term"><code class="varname">synchronous_standby_names</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.9.4.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a list of standby servers that can support
+ <em class="firstterm">synchronous replication</em>, as described in
+ <a class="xref" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="27.2.8. Synchronous Replication">Section 27.2.8</a>.
+ There will be one or more active synchronous standbys;
+ transactions waiting for commit will be allowed to proceed after
+ these standby servers confirm receipt of their data.
+ The synchronous standbys will be those whose names appear
+ in this list, and
+ that are both currently connected and streaming data in real-time
+ (as shown by a state of <code class="literal">streaming</code> in the
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW" title="28.2.4. pg_stat_replication">
+ <code class="structname">pg_stat_replication</code></a> view).
+ Specifying more than one synchronous standby can allow for very high
+ availability and protection against data loss.
+ </p><p>
+ The name of a standby server for this purpose is the
+ <code class="varname">application_name</code> setting of the standby, as set in the
+ standby's connection information. In case of a physical replication
+ standby, this should be set in the <code class="varname">primary_conninfo</code>
+ setting; the default is the setting of <a class="xref" href="runtime-config-logging.html#GUC-CLUSTER-NAME">cluster_name</a>
+ if set, else <code class="literal">walreceiver</code>.
+ For logical replication, this can be set in the connection
+ information of the subscription, and it defaults to the
+ subscription name. For other replication stream consumers,
+ consult their documentation.
+ </p><p>
+ This parameter specifies a list of standby servers using
+ either of the following syntaxes:
+</p><pre class="synopsis">
+[FIRST] <em class="replaceable"><code>num_sync</code></em> ( <em class="replaceable"><code>standby_name</code></em> [, ...] )
+ANY <em class="replaceable"><code>num_sync</code></em> ( <em class="replaceable"><code>standby_name</code></em> [, ...] )
+<em class="replaceable"><code>standby_name</code></em> [, ...]
+</pre><p>
+ where <em class="replaceable"><code>num_sync</code></em> is
+ the number of synchronous standbys that transactions need to
+ wait for replies from,
+ and <em class="replaceable"><code>standby_name</code></em>
+ is the name of a standby server.
+ <code class="literal">FIRST</code> and <code class="literal">ANY</code> specify the method to choose
+ synchronous standbys from the listed servers.
+ </p><p>
+ The keyword <code class="literal">FIRST</code>, coupled with
+ <em class="replaceable"><code>num_sync</code></em>, specifies a
+ priority-based synchronous replication and makes transaction commits
+ wait until their WAL records are replicated to
+ <em class="replaceable"><code>num_sync</code></em> synchronous
+ standbys chosen based on their priorities. For example, a setting of
+ <code class="literal">FIRST 3 (s1, s2, s3, s4)</code> will cause each commit to wait for
+ replies from three higher-priority standbys chosen from standby servers
+ <code class="literal">s1</code>, <code class="literal">s2</code>, <code class="literal">s3</code> and <code class="literal">s4</code>.
+ The standbys whose names appear earlier in the list are given higher
+ priority and will be considered as synchronous. Other standby servers
+ appearing later in this list represent potential synchronous standbys.
+ If any of the current synchronous standbys disconnects for whatever
+ reason, it will be replaced immediately with the next-highest-priority
+ standby. The keyword <code class="literal">FIRST</code> is optional.
+ </p><p>
+ The keyword <code class="literal">ANY</code>, coupled with
+ <em class="replaceable"><code>num_sync</code></em>, specifies a
+ quorum-based synchronous replication and makes transaction commits
+ wait until their WAL records are replicated to <span class="emphasis"><em>at least</em></span>
+ <em class="replaceable"><code>num_sync</code></em> listed standbys.
+ For example, a setting of <code class="literal">ANY 3 (s1, s2, s3, s4)</code> will cause
+ each commit to proceed as soon as at least any three standbys of
+ <code class="literal">s1</code>, <code class="literal">s2</code>, <code class="literal">s3</code> and <code class="literal">s4</code>
+ reply.
+ </p><p>
+ <code class="literal">FIRST</code> and <code class="literal">ANY</code> are case-insensitive. If these
+ keywords are used as the name of a standby server,
+ its <em class="replaceable"><code>standby_name</code></em> must
+ be double-quoted.
+ </p><p>
+ The third syntax was used before <span class="productname">PostgreSQL</span>
+ version 9.6 and is still supported. It's the same as the first syntax
+ with <code class="literal">FIRST</code> and
+ <em class="replaceable"><code>num_sync</code></em> equal to 1.
+ For example, <code class="literal">FIRST 1 (s1, s2)</code> and <code class="literal">s1, s2</code> have
+ the same meaning: either <code class="literal">s1</code> or <code class="literal">s2</code> is chosen
+ as a synchronous standby.
+ </p><p>
+ The special entry <code class="literal">*</code> matches any standby name.
+ </p><p>
+ There is no mechanism to enforce uniqueness of standby names. In case
+ of duplicates one of the matching standbys will be considered as
+ higher priority, though exactly which one is indeterminate.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Each <em class="replaceable"><code>standby_name</code></em>
+ should have the form of a valid SQL identifier, unless it
+ is <code class="literal">*</code>. You can use double-quoting if necessary. But note
+ that <em class="replaceable"><code>standby_name</code></em>s are
+ compared to standby application names case-insensitively, whether
+ double-quoted or not.
+ </p></div><p>
+ If no synchronous standby names are specified here, then synchronous
+ replication is not enabled and transaction commits will not wait for
+ replication. This is the default configuration. Even when
+ synchronous replication is enabled, individual transactions can be
+ configured not to wait for replication by setting the
+ <a class="xref" href="runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT">synchronous_commit</a> parameter to
+ <code class="literal">local</code> or <code class="literal">off</code>.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-VACUUM-DEFER-CLEANUP-AGE"><span class="term"><code class="varname">vacuum_defer_cleanup_age</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.4.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the number of transactions by which <code class="command">VACUUM</code> and
+ <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)"><acronym class="acronym">HOT</acronym> updates</a>
+ will defer cleanup of dead row versions. The
+ default is zero transactions, meaning that dead row versions can be
+ removed as soon as possible, that is, as soon as they are no longer
+ visible to any open transaction. You may wish to set this to a
+ non-zero value on a primary server that is supporting hot standby
+ servers, as described in <a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a>. This allows
+ more time for queries on the standby to complete without incurring
+ conflicts due to early cleanup of rows. However, since the value
+ is measured in terms of number of write transactions occurring on the
+ primary server, it is difficult to predict just how much additional
+ grace time will be made available to standby queries.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ You should also consider setting <code class="varname">hot_standby_feedback</code>
+ on standby server(s) as an alternative to using this parameter.
+ </p><p>
+ This does not prevent cleanup of dead rows which have reached the age
+ specified by <code class="varname">old_snapshot_threshold</code>.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-REPLICATION-STANDBY"><div class="titlepage"><div><div><h3 class="title">20.6.3. Standby Servers</h3></div></div></div><p>
+ These settings control the behavior of a
+ <a class="link" href="warm-standby.html#STANDBY-SERVER-OPERATION" title="27.2.2. Standby Server Operation">standby server</a>
+ that is
+ to receive replication data. Their values on the primary server
+ are irrelevant.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-PRIMARY-CONNINFO"><span class="term"><code class="varname">primary_conninfo</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.9.5.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a connection string to be used for the standby server
+ to connect with a sending server. This string is in the format
+ described in <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a>. If any option is
+ unspecified in this string, then the corresponding environment
+ variable (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>) is checked. If the
+ environment variable is not set either, then
+ defaults are used.
+ </p><p>
+ The connection string should specify the host name (or address)
+ of the sending server, as well as the port number if it is not
+ the same as the standby server's default.
+ Also specify a user name corresponding to a suitably-privileged role
+ on the sending server (see
+ <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-AUTHENTICATION" title="27.2.5.1. Authentication">Section 27.2.5.1</a>).
+ A password needs to be provided too, if the sender demands password
+ authentication. It can be provided in the
+ <code class="varname">primary_conninfo</code> string, or in a separate
+ <code class="filename">~/.pgpass</code> file on the standby server (use
+ <code class="literal">replication</code> as the database name).
+ Do not specify a database name in the
+ <code class="varname">primary_conninfo</code> string.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ If this parameter is changed while the WAL receiver process is
+ running, that process is signaled to shut down and expected to
+ restart with the new setting (except if <code class="varname">primary_conninfo</code>
+ is an empty string).
+ This setting has no effect if the server is not in standby mode.
+ </p></dd><dt id="GUC-PRIMARY-SLOT-NAME"><span class="term"><code class="varname">primary_slot_name</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.9.5.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Optionally specifies an existing replication slot to be used when
+ connecting to the sending server via streaming replication to control
+ resource removal on the upstream node
+ (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a>).
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ If this parameter is changed while the WAL receiver process is running,
+ that process is signaled to shut down and expected to restart with the
+ new setting.
+ This setting has no effect if <code class="varname">primary_conninfo</code> is not
+ set or the server is not in standby mode.
+ </p></dd><dt id="GUC-PROMOTE-TRIGGER-FILE"><span class="term"><code class="varname">promote_trigger_file</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.9.5.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies a trigger file whose presence ends recovery in the
+ standby. Even if this value is not set, you can still promote
+ the standby using <code class="command">pg_ctl promote</code> or calling
+ <code class="function">pg_promote()</code>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-HOT-STANDBY"><span class="term"><code class="varname">hot_standby</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.9.5.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies whether or not you can connect and run queries during
+ recovery, as described in <a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a>.
+ The default value is <code class="literal">on</code>.
+ This parameter can only be set at server start. It only has effect
+ during archive recovery or in standby mode.
+ </p></dd><dt id="GUC-MAX-STANDBY-ARCHIVE-DELAY"><span class="term"><code class="varname">max_standby_archive_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.5.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When hot standby is active, this parameter determines how long the
+ standby server should wait before canceling standby queries that
+ conflict with about-to-be-applied WAL entries, as described in
+ <a class="xref" href="hot-standby.html#HOT-STANDBY-CONFLICT" title="27.4.2. Handling Query Conflicts">Section 27.4.2</a>.
+ <code class="varname">max_standby_archive_delay</code> applies when WAL data is
+ being read from WAL archive (and is therefore not current).
+ If this value is specified without units, it is taken as milliseconds.
+ The default is 30 seconds.
+ A value of -1 allows the standby to wait forever for conflicting
+ queries to complete.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ Note that <code class="varname">max_standby_archive_delay</code> is not the same as the
+ maximum length of time a query can run before cancellation; rather it
+ is the maximum total time allowed to apply any one WAL segment's data.
+ Thus, if one query has resulted in significant delay earlier in the
+ WAL segment, subsequent conflicting queries will have much less grace
+ time.
+ </p></dd><dt id="GUC-MAX-STANDBY-STREAMING-DELAY"><span class="term"><code class="varname">max_standby_streaming_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.5.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When hot standby is active, this parameter determines how long the
+ standby server should wait before canceling standby queries that
+ conflict with about-to-be-applied WAL entries, as described in
+ <a class="xref" href="hot-standby.html#HOT-STANDBY-CONFLICT" title="27.4.2. Handling Query Conflicts">Section 27.4.2</a>.
+ <code class="varname">max_standby_streaming_delay</code> applies when WAL data is
+ being received via streaming replication.
+ If this value is specified without units, it is taken as milliseconds.
+ The default is 30 seconds.
+ A value of -1 allows the standby to wait forever for conflicting
+ queries to complete.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ Note that <code class="varname">max_standby_streaming_delay</code> is not the same as
+ the maximum length of time a query can run before cancellation; rather
+ it is the maximum total time allowed to apply WAL data once it has
+ been received from the primary server. Thus, if one query has
+ resulted in significant delay, subsequent conflicting queries will
+ have much less grace time until the standby server has caught up
+ again.
+ </p></dd><dt id="GUC-WAL-RECEIVER-CREATE-TEMP-SLOT"><span class="term"><code class="varname">wal_receiver_create_temp_slot</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.9.5.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies whether the WAL receiver process should create a temporary replication
+ slot on the remote instance when no permanent replication slot to use
+ has been configured (using <a class="xref" href="runtime-config-replication.html#GUC-PRIMARY-SLOT-NAME">primary_slot_name</a>).
+ The default is off. This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ If this parameter is changed while the WAL receiver process is running,
+ that process is signaled to shut down and expected to restart with
+ the new setting.
+ </p></dd><dt id="GUC-WAL-RECEIVER-STATUS-INTERVAL"><span class="term"><code class="varname">wal_receiver_status_interval</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.5.3.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the minimum frequency for the WAL receiver
+ process on the standby to send information about replication progress
+ to the primary or upstream standby, where it can be seen using the
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW" title="28.2.4. pg_stat_replication">
+ <code class="structname">pg_stat_replication</code></a>
+ view. The standby will report
+ the last write-ahead log location it has written, the last position it
+ has flushed to disk, and the last position it has applied.
+ This parameter's value is the maximum amount of time between reports.
+ Updates are sent each time the write or flush positions change, or as
+ often as specified by this parameter if set to a non-zero value.
+ There are additional cases where updates are sent while ignoring this
+ parameter; for example, when processing of the existing WAL completes
+ or when <code class="varname">synchronous_commit</code> is set to
+ <code class="literal">remote_apply</code>.
+ Thus, the apply position may lag slightly behind the true position.
+ If this value is specified without units, it is taken as seconds.
+ The default value is 10 seconds. This parameter can only be set in
+ the <code class="filename">postgresql.conf</code> file or on the server
+ command line.
+ </p></dd><dt id="GUC-HOT-STANDBY-FEEDBACK"><span class="term"><code class="varname">hot_standby_feedback</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.9.5.3.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies whether or not a hot standby will send feedback to the primary
+ or upstream standby
+ about queries currently executing on the standby. This parameter can
+ be used to eliminate query cancels caused by cleanup records, but
+ can cause database bloat on the primary for some workloads.
+ Feedback messages will not be sent more frequently than once per
+ <code class="varname">wal_receiver_status_interval</code>. The default value is
+ <code class="literal">off</code>. This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p><p>
+ If cascaded replication is in use the feedback is passed upstream
+ until it eventually reaches the primary. Standbys make no other use
+ of feedback they receive other than to pass upstream.
+ </p><p>
+ This setting does not override the behavior of
+ <code class="varname">old_snapshot_threshold</code> on the primary; a snapshot on the
+ standby which exceeds the primary's age threshold can become invalid,
+ resulting in cancellation of transactions on the standby. This is
+ because <code class="varname">old_snapshot_threshold</code> is intended to provide an
+ absolute limit on the time which dead rows can contribute to bloat,
+ which would otherwise be violated because of the configuration of a
+ standby.
+ </p></dd><dt id="GUC-WAL-RECEIVER-TIMEOUT"><span class="term"><code class="varname">wal_receiver_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.5.3.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Terminate replication connections that are inactive for longer
+ than this amount of time. This is useful for
+ the receiving standby server to detect a primary node crash or network
+ outage.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 60 seconds.
+ A value of zero disables the timeout mechanism.
+ This parameter can only be set in
+ the <code class="filename">postgresql.conf</code> file or on the server
+ command line.
+ </p></dd><dt id="GUC-WAL-RETRIEVE-RETRY-INTERVAL"><span class="term"><code class="varname">wal_retrieve_retry_interval</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.5.3.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies how long the standby server should wait when WAL data is not
+ available from any sources (streaming replication,
+ local <code class="filename">pg_wal</code> or WAL archive) before trying
+ again to retrieve WAL data.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 5 seconds.
+ This parameter can only be set in
+ the <code class="filename">postgresql.conf</code> file or on the server
+ command line.
+ </p><p>
+ This parameter is useful in configurations where a node in recovery
+ needs to control the amount of time to wait for new WAL data to be
+ available. For example, in archive recovery, it is possible to
+ make the recovery more responsive in the detection of a new WAL
+ log file by reducing the value of this parameter. On a system with
+ low WAL activity, increasing it reduces the amount of requests necessary
+ to access WAL archives, something useful for example in cloud
+ environments where the number of times an infrastructure is accessed
+ is taken into account.
+ </p></dd><dt id="GUC-RECOVERY-MIN-APPLY-DELAY"><span class="term"><code class="varname">recovery_min_apply_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.5.3.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ By default, a standby server restores WAL records from the
+ sending server as soon as possible. It may be useful to have a time-delayed
+ copy of the data, offering opportunities to correct data loss errors.
+ This parameter allows you to delay recovery by a specified amount
+ of time. For example, if
+ you set this parameter to <code class="literal">5min</code>, the standby will
+ replay each transaction commit only when the system time on the standby
+ is at least five minutes past the commit time reported by the primary.
+ If this value is specified without units, it is taken as milliseconds.
+ The default is zero, adding no delay.
+ </p><p>
+ It is possible that the replication delay between servers exceeds the
+ value of this parameter, in which case no delay is added.
+ Note that the delay is calculated between the WAL time stamp as written
+ on primary and the current time on the standby. Delays in transfer
+ because of network lag or cascading replication configurations
+ may reduce the actual wait time significantly. If the system
+ clocks on primary and standby are not synchronized, this may lead to
+ recovery applying records earlier than expected; but that is not a
+ major issue because useful settings of this parameter are much larger
+ than typical time deviations between servers.
+ </p><p>
+ The delay occurs only on WAL records for transaction commits.
+ Other records are replayed as quickly as possible, which
+ is not a problem because MVCC visibility rules ensure their effects
+ are not visible until the corresponding commit record is applied.
+ </p><p>
+ The delay occurs once the database in recovery has reached a consistent
+ state, until the standby is promoted or triggered. After that the standby
+ will end recovery without further waiting.
+ </p><p>
+ WAL records must be kept on the standby until they are ready to be
+ applied. Therefore, longer delays will result in a greater accumulation
+ of WAL files, increasing disk space requirements for the standby's
+ <code class="filename">pg_wal</code> directory.
+ </p><p>
+ This parameter is intended for use with streaming replication deployments;
+ however, if the parameter is specified it will be honored in all cases
+ except crash recovery.
+
+ <code class="varname">hot_standby_feedback</code> will be delayed by use of this feature
+ which could lead to bloat on the primary; use both together with care.
+
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ Synchronous replication is affected by this setting when <code class="varname">synchronous_commit</code>
+ is set to <code class="literal">remote_apply</code>; every <code class="literal">COMMIT</code>
+ will need to wait to be applied.
+ </p></div><p>
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-REPLICATION-SUBSCRIBER"><div class="titlepage"><div><div><h3 class="title">20.6.4. Subscribers</h3></div></div></div><p>
+ These settings control the behavior of a logical replication subscriber.
+ Their values on the publisher are irrelevant.
+ </p><p>
+ Note that <code class="varname">wal_receiver_timeout</code>,
+ <code class="varname">wal_receiver_status_interval</code> and
+ <code class="varname">wal_retrieve_retry_interval</code> configuration parameters
+ affect the logical replication workers as well.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-MAX-LOGICAL-REPLICATION-WORKERS"><span class="term"><code class="varname">max_logical_replication_workers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.6.4.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies maximum number of logical replication workers. This includes
+ both apply workers and table synchronization workers.
+ </p><p>
+ Logical replication workers are taken from the pool defined by
+ <code class="varname">max_worker_processes</code>.
+ </p><p>
+ The default value is 4. This parameter can only be set at server
+ start.
+ </p></dd><dt id="GUC-MAX-SYNC-WORKERS-PER-SUBSCRIPTION"><span class="term"><code class="varname">max_sync_workers_per_subscription</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.9.6.4.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Maximum number of synchronization workers per subscription. This
+ parameter controls the amount of parallelism of the initial data copy
+ during the subscription initialization or when new tables are added.
+ </p><p>
+ Currently, there can be only one synchronization worker per table.
+ </p><p>
+ The synchronization workers are taken from the pool defined by
+ <code class="varname">max_logical_replication_workers</code>.
+ </p><p>
+ The default value is 2. This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command
+ line.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-wal.html" title="20.5. Write Ahead Log">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-query.html" title="20.7. Query Planning">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.5. Write Ahead Log </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.7. Query Planning</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-resource.html b/doc/src/sgml/html/runtime-config-resource.html
new file mode 100644
index 0000000..ed3126c
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-resource.html
@@ -0,0 +1,713 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.4. Resource Consumption</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-connection.html" title="20.3. Connections and Authentication" /><link rel="next" href="runtime-config-wal.html" title="20.5. Write Ahead Log" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.4. Resource Consumption</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-connection.html" title="20.3. Connections and Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-wal.html" title="20.5. Write Ahead Log">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-RESOURCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.4. Resource Consumption</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">20.4.1. Memory</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK">20.4.2. Disk</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-KERNEL">20.4.3. Kernel Resource Usage</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">20.4.4. Cost-based Vacuum Delay</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER">20.4.5. Background Writer</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">20.4.6. Asynchronous Behavior</a></span></dt></dl></div><div class="sect2" id="RUNTIME-CONFIG-RESOURCE-MEMORY"><div class="titlepage"><div><div><h3 class="title">20.4.1. Memory</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-SHARED-BUFFERS"><span class="term"><code class="varname">shared_buffers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the amount of memory the database server uses for shared
+ memory buffers. The default is typically 128 megabytes
+ (<code class="literal">128MB</code>), but might be less if your kernel settings will
+ not support it (as determined during <span class="application">initdb</span>).
+ This setting must be at least 128 kilobytes. However,
+ settings significantly higher than the minimum are usually needed
+ for good performance.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ (Non-default values of <code class="symbol">BLCKSZ</code> change the minimum
+ value.)
+ This parameter can only be set at server start.
+ </p><p>
+ If you have a dedicated database server with 1GB or more of RAM, a
+ reasonable starting value for <code class="varname">shared_buffers</code> is 25%
+ of the memory in your system. There are some workloads where even
+ larger settings for <code class="varname">shared_buffers</code> are effective, but
+ because <span class="productname">PostgreSQL</span> also relies on the
+ operating system cache, it is unlikely that an allocation of more than
+ 40% of RAM to <code class="varname">shared_buffers</code> will work better than a
+ smaller amount. Larger settings for <code class="varname">shared_buffers</code>
+ usually require a corresponding increase in
+ <code class="varname">max_wal_size</code>, in order to spread out the
+ process of writing large quantities of new or changed data over a
+ longer period of time.
+ </p><p>
+ On systems with less than 1GB of RAM, a smaller percentage of RAM is
+ appropriate, so as to leave adequate space for the operating system.
+ </p></dd><dt id="GUC-HUGE-PAGES"><span class="term"><code class="varname">huge_pages</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.7.2.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls whether huge pages are requested for the main shared memory
+ area. Valid values are <code class="literal">try</code> (the default),
+ <code class="literal">on</code>, and <code class="literal">off</code>. With
+ <code class="varname">huge_pages</code> set to <code class="literal">try</code>, the
+ server will try to request huge pages, but fall back to the default if
+ that fails. With <code class="literal">on</code>, failure to request huge pages
+ will prevent the server from starting up. With <code class="literal">off</code>,
+ huge pages will not be requested.
+ </p><p>
+ At present, this setting is supported only on Linux and Windows. The
+ setting is ignored on other systems when set to
+ <code class="literal">try</code>. On Linux, it is only supported when
+ <code class="varname">shared_memory_type</code> is set to <code class="literal">mmap</code>
+ (the default).
+ </p><p>
+ The use of huge pages results in smaller page tables and less CPU time
+ spent on memory management, increasing performance. For more details about
+ using huge pages on Linux, see <a class="xref" href="kernel-resources.html#LINUX-HUGE-PAGES" title="19.4.5. Linux Huge Pages">Section 19.4.5</a>.
+ </p><p>
+ Huge pages are known as large pages on Windows. To use them, you need to
+ assign the user right <span class="quote">“<span class="quote">Lock pages in memory</span>”</span> to the Windows user account
+ that runs <span class="productname">PostgreSQL</span>.
+ You can use Windows Group Policy tool (gpedit.msc) to assign the user right
+ <span class="quote">“<span class="quote">Lock pages in memory</span>”</span>.
+ To start the database server on the command prompt as a standalone process,
+ not as a Windows service, the command prompt must be run as an administrator or
+ User Access Control (UAC) must be disabled. When the UAC is enabled, the normal
+ command prompt revokes the user right <span class="quote">“<span class="quote">Lock pages in memory</span>”</span> when started.
+ </p><p>
+ Note that this setting only affects the main shared memory area.
+ Operating systems such as Linux, FreeBSD, and Illumos can also use
+ huge pages (also known as <span class="quote">“<span class="quote">super</span>”</span> pages or
+ <span class="quote">“<span class="quote">large</span>”</span> pages) automatically for normal memory
+ allocation, without an explicit request from
+ <span class="productname">PostgreSQL</span>. On Linux, this is called
+ <span class="quote">“<span class="quote">transparent huge pages</span>”</span><a id="id-1.6.7.7.2.2.2.2.5.5" class="indexterm"></a> (THP). That feature has been known to
+ cause performance degradation with
+ <span class="productname">PostgreSQL</span> for some users on some Linux
+ versions, so its use is currently discouraged (unlike explicit use of
+ <code class="varname">huge_pages</code>).
+ </p></dd><dt id="GUC-HUGE-PAGE-SIZE"><span class="term"><code class="varname">huge_page_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls the size of huge pages, when they are enabled with
+ <a class="xref" href="runtime-config-resource.html#GUC-HUGE-PAGES">huge_pages</a>.
+ The default is zero (<code class="literal">0</code>).
+ When set to <code class="literal">0</code>, the default huge page size on the
+ system will be used. This parameter can only be set at server start.
+ </p><p>
+ Some commonly available page sizes on modern 64 bit server architectures include:
+ <code class="literal">2MB</code> and <code class="literal">1GB</code> (Intel and AMD), <code class="literal">16MB</code> and
+ <code class="literal">16GB</code> (IBM POWER), and <code class="literal">64kB</code>, <code class="literal">2MB</code>,
+ <code class="literal">32MB</code> and <code class="literal">1GB</code> (ARM). For more information
+ about usage and support, see <a class="xref" href="kernel-resources.html#LINUX-HUGE-PAGES" title="19.4.5. Linux Huge Pages">Section 19.4.5</a>.
+ </p><p>
+ Non-default settings are currently supported only on Linux.
+ </p></dd><dt id="GUC-TEMP-BUFFERS"><span class="term"><code class="varname">temp_buffers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum amount of memory used for temporary buffers within
+ each database session. These are session-local buffers used only
+ for access to temporary tables.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The default is eight megabytes (<code class="literal">8MB</code>).
+ (If <code class="symbol">BLCKSZ</code> is not 8kB, the default value scales
+ proportionally to it.)
+ This setting can be changed within individual
+ sessions, but only before the first use of temporary tables
+ within the session; subsequent attempts to change the value will
+ have no effect on that session.
+ </p><p>
+ A session will allocate temporary buffers as needed up to the limit
+ given by <code class="varname">temp_buffers</code>. The cost of setting a large
+ value in sessions that do not actually need many temporary
+ buffers is only a buffer descriptor, or about 64 bytes, per
+ increment in <code class="varname">temp_buffers</code>. However if a buffer is
+ actually used an additional 8192 bytes will be consumed for it
+ (or in general, <code class="symbol">BLCKSZ</code> bytes).
+ </p></dd><dt id="GUC-MAX-PREPARED-TRANSACTIONS"><span class="term"><code class="varname">max_prepared_transactions</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum number of transactions that can be in the
+ <span class="quote">“<span class="quote">prepared</span>”</span> state simultaneously (see <a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a>).
+ Setting this parameter to zero (which is the default)
+ disables the prepared-transaction feature.
+ This parameter can only be set at server start.
+ </p><p>
+ If you are not planning to use prepared transactions, this parameter
+ should be set to zero to prevent accidental creation of prepared
+ transactions. If you are using prepared transactions, you will
+ probably want <code class="varname">max_prepared_transactions</code> to be at
+ least as large as <a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>, so that every
+ session can have a prepared transaction pending.
+ </p><p>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </p></dd><dt id="GUC-WORK-MEM"><span class="term"><code class="varname">work_mem</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the base maximum amount of memory to be used by a query operation
+ (such as a sort or hash table) before writing to temporary disk files.
+ If this value is specified without units, it is taken as kilobytes.
+ The default value is four megabytes (<code class="literal">4MB</code>).
+ Note that for a complex query, several sort or hash operations might be
+ running in parallel; each operation will generally be allowed
+ to use as much memory as this value specifies before it starts
+ to write data into temporary files. Also, several running
+ sessions could be doing such operations concurrently.
+ Therefore, the total memory used could be many times the value
+ of <code class="varname">work_mem</code>; it is necessary to keep this
+ fact in mind when choosing the value. Sort operations are used
+ for <code class="literal">ORDER BY</code>, <code class="literal">DISTINCT</code>,
+ and merge joins.
+ Hash tables are used in hash joins, hash-based aggregation, memoize
+ nodes and hash-based processing of <code class="literal">IN</code> subqueries.
+ </p><p>
+ Hash-based operations are generally more sensitive to memory
+ availability than equivalent sort-based operations. The
+ memory available for hash tables is computed by multiplying
+ <code class="varname">work_mem</code> by
+ <code class="varname">hash_mem_multiplier</code>. This makes it
+ possible for hash-based operations to use an amount of memory
+ that exceeds the usual <code class="varname">work_mem</code> base
+ amount.
+ </p></dd><dt id="GUC-HASH-MEM-MULTIPLIER"><span class="term"><code class="varname">hash_mem_multiplier</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.7.2.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Used to compute the maximum amount of memory that hash-based
+ operations can use. The final limit is determined by
+ multiplying <code class="varname">work_mem</code> by
+ <code class="varname">hash_mem_multiplier</code>. The default value is
+ 2.0, which makes hash-based operations use twice the usual
+ <code class="varname">work_mem</code> base amount.
+ </p><p>
+ Consider increasing <code class="varname">hash_mem_multiplier</code> in
+ environments where spilling by query operations is a regular
+ occurrence, especially when simply increasing
+ <code class="varname">work_mem</code> results in memory pressure (memory
+ pressure typically takes the form of intermittent out of
+ memory errors). The default setting of 2.0 is often effective with
+ mixed workloads. Higher settings in the range of 2.0 - 8.0 or
+ more may be effective in environments where
+ <code class="varname">work_mem</code> has already been increased to 40MB
+ or more.
+ </p></dd><dt id="GUC-MAINTENANCE-WORK-MEM"><span class="term"><code class="varname">maintenance_work_mem</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum amount of memory to be used by maintenance
+ operations, such as <code class="command">VACUUM</code>, <code class="command">CREATE
+ INDEX</code>, and <code class="command">ALTER TABLE ADD FOREIGN KEY</code>.
+ If this value is specified without units, it is taken as kilobytes.
+ It defaults
+ to 64 megabytes (<code class="literal">64MB</code>). Since only one of these
+ operations can be executed at a time by a database session, and
+ an installation normally doesn't have many of them running
+ concurrently, it's safe to set this value significantly larger
+ than <code class="varname">work_mem</code>. Larger settings might improve
+ performance for vacuuming and for restoring database dumps.
+ </p><p>
+ Note that when autovacuum runs, up to
+ <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS">autovacuum_max_workers</a> times this memory
+ may be allocated, so be careful not to set the default value
+ too high. It may be useful to control for this by separately
+ setting <a class="xref" href="runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM">autovacuum_work_mem</a>.
+ </p><p>
+ Note that for the collection of dead tuple identifiers,
+ <code class="command">VACUUM</code> is only able to utilize up to a maximum of
+ <code class="literal">1GB</code> of memory.
+ </p></dd><dt id="GUC-AUTOVACUUM-WORK-MEM"><span class="term"><code class="varname">autovacuum_work_mem</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum amount of memory to be used by each
+ autovacuum worker process.
+ If this value is specified without units, it is taken as kilobytes.
+ It defaults to -1, indicating that
+ the value of <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a> should
+ be used instead. The setting has no effect on the behavior of
+ <code class="command">VACUUM</code> when run in other contexts.
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command
+ line.
+ </p><p>
+ For the collection of dead tuple identifiers, autovacuum is only able
+ to utilize up to a maximum of <code class="literal">1GB</code> of memory, so
+ setting <code class="varname">autovacuum_work_mem</code> to a value higher than
+ that has no effect on the number of dead tuples that autovacuum can
+ collect while scanning a table.
+ </p></dd><dt id="GUC-LOGICAL-DECODING-WORK-MEM"><span class="term"><code class="varname">logical_decoding_work_mem</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum amount of memory to be used by logical decoding,
+ before some of the decoded changes are written to local disk. This
+ limits the amount of memory used by logical streaming replication
+ connections. It defaults to 64 megabytes (<code class="literal">64MB</code>).
+ Since each replication connection only uses a single buffer of this size,
+ and an installation normally doesn't have many such connections
+ concurrently (as limited by <code class="varname">max_wal_senders</code>), it's
+ safe to set this value significantly higher than <code class="varname">work_mem</code>,
+ reducing the amount of decoded changes written to disk.
+ </p></dd><dt id="GUC-MAX-STACK-DEPTH"><span class="term"><code class="varname">max_stack_depth</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum safe depth of the server's execution stack.
+ The ideal setting for this parameter is the actual stack size limit
+ enforced by the kernel (as set by <code class="literal">ulimit -s</code> or local
+ equivalent), less a safety margin of a megabyte or so. The safety
+ margin is needed because the stack depth is not checked in every
+ routine in the server, but only in key potentially-recursive routines.
+ If this value is specified without units, it is taken as kilobytes.
+ The default setting is two megabytes (<code class="literal">2MB</code>), which
+ is conservatively small and unlikely to risk crashes. However,
+ it might be too small to allow execution of complex functions.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ Setting <code class="varname">max_stack_depth</code> higher than
+ the actual kernel limit will mean that a runaway recursive function
+ can crash an individual backend process. On platforms where
+ <span class="productname">PostgreSQL</span> can determine the kernel limit,
+ the server will not allow this variable to be set to an unsafe
+ value. However, not all platforms provide the information,
+ so caution is recommended in selecting a value.
+ </p></dd><dt id="GUC-SHARED-MEMORY-TYPE"><span class="term"><code class="varname">shared_memory_type</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.7.2.2.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the shared memory implementation that the server
+ should use for the main shared memory region that holds
+ <span class="productname">PostgreSQL</span>'s shared buffers and other
+ shared data. Possible values are <code class="literal">mmap</code> (for
+ anonymous shared memory allocated using <code class="function">mmap</code>),
+ <code class="literal">sysv</code> (for System V shared memory allocated via
+ <code class="function">shmget</code>) and <code class="literal">windows</code> (for Windows
+ shared memory). Not all values are supported on all platforms; the
+ first supported option is the default for that platform. The use of
+ the <code class="literal">sysv</code> option, which is not the default on any
+ platform, is generally discouraged because it typically requires
+ non-default kernel settings to allow for large allocations (see <a class="xref" href="kernel-resources.html#SYSVIPC" title="19.4.1. Shared Memory and Semaphores">Section 19.4.1</a>).
+ </p></dd><dt id="GUC-DYNAMIC-SHARED-MEMORY-TYPE"><span class="term"><code class="varname">dynamic_shared_memory_type</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.7.2.2.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the dynamic shared memory implementation that the server
+ should use. Possible values are <code class="literal">posix</code> (for POSIX shared
+ memory allocated using <code class="literal">shm_open</code>), <code class="literal">sysv</code>
+ (for System V shared memory allocated via <code class="literal">shmget</code>),
+ <code class="literal">windows</code> (for Windows shared memory),
+ and <code class="literal">mmap</code> (to simulate shared memory using
+ memory-mapped files stored in the data directory).
+ Not all values are supported on all platforms; the first supported
+ option is usually the default for that platform. The use of the
+ <code class="literal">mmap</code> option, which is not the default on any platform,
+ is generally discouraged because the operating system may write
+ modified pages back to disk repeatedly, increasing system I/O load;
+ however, it may be useful for debugging, when the
+ <code class="literal">pg_dynshmem</code> directory is stored on a RAM disk, or when
+ other shared memory facilities are not available.
+ </p></dd><dt id="GUC-MIN-DYNAMIC-SHARED-MEMORY"><span class="term"><code class="varname">min_dynamic_shared_memory</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.2.2.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the amount of memory that should be allocated at server
+ startup for use by parallel queries. When this memory region is
+ insufficient or exhausted by concurrent queries, new parallel queries
+ try to allocate extra shared memory temporarily from the operating
+ system using the method configured with
+ <code class="varname">dynamic_shared_memory_type</code>, which may be slower due
+ to memory management overheads. Memory that is allocated at startup
+ with <code class="varname">min_dynamic_shared_memory</code> is affected by
+ the <code class="varname">huge_pages</code> setting on operating systems where
+ that is supported, and may be more likely to benefit from larger pages
+ on operating systems where that is managed automatically.
+ The default value is <code class="literal">0</code> (none). This parameter can
+ only be set at server start.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-RESOURCE-DISK"><div class="titlepage"><div><div><h3 class="title">20.4.2. Disk</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-TEMP-FILE-LIMIT"><span class="term"><code class="varname">temp_file_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.3.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the maximum amount of disk space that a process can use
+ for temporary files, such as sort and hash temporary files, or the
+ storage file for a held cursor. A transaction attempting to exceed
+ this limit will be canceled.
+ If this value is specified without units, it is taken as kilobytes.
+ <code class="literal">-1</code> (the default) means no limit.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ This setting constrains the total space used at any instant by all
+ temporary files used by a given <span class="productname">PostgreSQL</span> process.
+ It should be noted that disk space used for explicit temporary
+ tables, as opposed to temporary files used behind-the-scenes in query
+ execution, does <span class="emphasis"><em>not</em></span> count against this limit.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-RESOURCE-KERNEL"><div class="titlepage"><div><div><h3 class="title">20.4.3. Kernel Resource Usage</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-MAX-FILES-PER-PROCESS"><span class="term"><code class="varname">max_files_per_process</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.4.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum number of simultaneously open files allowed to each
+ server subprocess. The default is one thousand files. If the kernel is enforcing
+ a safe per-process limit, you don't need to worry about this setting.
+ But on some platforms (notably, most BSD systems), the kernel will
+ allow individual processes to open many more files than the system
+ can actually support if many processes all try to open
+ that many files. If you find yourself seeing <span class="quote">“<span class="quote">Too many open
+ files</span>”</span> failures, try reducing this setting.
+ This parameter can only be set at server start.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-RESOURCE-VACUUM-COST"><div class="titlepage"><div><div><h3 class="title">20.4.4. Cost-based Vacuum Delay</h3></div></div></div><p>
+ During the execution of <a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a>
+ and <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a>
+ commands, the system maintains an
+ internal counter that keeps track of the estimated cost of the
+ various I/O operations that are performed. When the accumulated
+ cost reaches a limit (specified by
+ <code class="varname">vacuum_cost_limit</code>), the process performing
+ the operation will sleep for a short period of time, as specified by
+ <code class="varname">vacuum_cost_delay</code>. Then it will reset the
+ counter and continue execution.
+ </p><p>
+ The intent of this feature is to allow administrators to reduce
+ the I/O impact of these commands on concurrent database
+ activity. There are many situations where it is not
+ important that maintenance commands like
+ <code class="command">VACUUM</code> and <code class="command">ANALYZE</code> finish
+ quickly; however, it is usually very important that these
+ commands do not significantly interfere with the ability of the
+ system to perform other database operations. Cost-based vacuum
+ delay provides a way for administrators to achieve this.
+ </p><p>
+ This feature is disabled by default for manually issued
+ <code class="command">VACUUM</code> commands. To enable it, set the
+ <code class="varname">vacuum_cost_delay</code> variable to a nonzero
+ value.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-VACUUM-COST-DELAY"><span class="term"><code class="varname">vacuum_cost_delay</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.7.5.5.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The amount of time that the process will sleep
+ when the cost limit has been exceeded.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is zero, which disables the cost-based vacuum
+ delay feature. Positive values enable cost-based vacuuming.
+ </p><p>
+ When using cost-based vacuuming, appropriate values for
+ <code class="varname">vacuum_cost_delay</code> are usually quite small, perhaps
+ less than 1 millisecond. While <code class="varname">vacuum_cost_delay</code>
+ can be set to fractional-millisecond values, such delays may not be
+ measured accurately on older platforms. On such platforms,
+ increasing <code class="command">VACUUM</code>'s throttled resource consumption
+ above what you get at 1ms will require changing the other vacuum cost
+ parameters. You should, nonetheless,
+ keep <code class="varname">vacuum_cost_delay</code> as small as your platform
+ will consistently measure; large delays are not helpful.
+ </p></dd><dt id="GUC-VACUUM-COST-PAGE-HIT"><span class="term"><code class="varname">vacuum_cost_page_hit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.5.5.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The estimated cost for vacuuming a buffer found in the shared buffer
+ cache. It represents the cost to lock the buffer pool, lookup
+ the shared hash table and scan the content of the page. The
+ default value is one.
+ </p></dd><dt id="GUC-VACUUM-COST-PAGE-MISS"><span class="term"><code class="varname">vacuum_cost_page_miss</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.5.5.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The estimated cost for vacuuming a buffer that has to be read from
+ disk. This represents the effort to lock the buffer pool,
+ lookup the shared hash table, read the desired block in from
+ the disk and scan its content. The default value is 2.
+ </p></dd><dt id="GUC-VACUUM-COST-PAGE-DIRTY"><span class="term"><code class="varname">vacuum_cost_page_dirty</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.5.5.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The estimated cost charged when vacuum modifies a block that was
+ previously clean. It represents the extra I/O required to
+ flush the dirty block out to disk again. The default value is
+ 20.
+ </p></dd><dt id="GUC-VACUUM-COST-LIMIT"><span class="term"><code class="varname">vacuum_cost_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.5.5.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The accumulated cost that will cause the vacuuming process to sleep.
+ The default value is 200.
+ </p></dd></dl></div><div class="note"><h3 class="title">Note</h3><p>
+ There are certain operations that hold critical locks and should
+ therefore complete as quickly as possible. Cost-based vacuum
+ delays do not occur during such operations. Therefore it is
+ possible that the cost accumulates far higher than the specified
+ limit. To avoid uselessly long delays in such cases, the actual
+ delay is calculated as <code class="varname">vacuum_cost_delay</code> *
+ <code class="varname">accumulated_balance</code> /
+ <code class="varname">vacuum_cost_limit</code> with a maximum of
+ <code class="varname">vacuum_cost_delay</code> * 4.
+ </p></div></div><div class="sect2" id="RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER"><div class="titlepage"><div><div><h3 class="title">20.4.5. Background Writer</h3></div></div></div><p>
+ There is a separate server
+ process called the <em class="firstterm">background writer</em>, whose function
+ is to issue writes of <span class="quote">“<span class="quote">dirty</span>”</span> (new or modified) shared
+ buffers. When the number of clean shared buffers appears to be
+ insufficient, the background writer writes some dirty buffers to the
+ file system and marks them as clean. This reduces the likelihood
+ that server processes handling user queries will be unable to find
+ clean buffers and have to write dirty buffers themselves.
+ However, the background writer does cause a net overall
+ increase in I/O load, because while a repeatedly-dirtied page might
+ otherwise be written only once per checkpoint interval, the
+ background writer might write it several times as it is dirtied
+ in the same interval. The parameters discussed in this subsection
+ can be used to tune the behavior for local needs.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-BGWRITER-DELAY"><span class="term"><code class="varname">bgwriter_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.6.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the delay between activity rounds for the
+ background writer. In each round the writer issues writes
+ for some number of dirty buffers (controllable by the
+ following parameters). It then sleeps for
+ the length of <code class="varname">bgwriter_delay</code>, and repeats.
+ When there are no dirty buffers in the
+ buffer pool, though, it goes into a longer sleep regardless of
+ <code class="varname">bgwriter_delay</code>.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 200
+ milliseconds (<code class="literal">200ms</code>). Note that on many systems, the
+ effective resolution of sleep delays is 10 milliseconds; setting
+ <code class="varname">bgwriter_delay</code> to a value that is not a multiple of 10
+ might have the same results as setting it to the next higher multiple
+ of 10. This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-BGWRITER-LRU-MAXPAGES"><span class="term"><code class="varname">bgwriter_lru_maxpages</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.6.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ In each round, no more than this many buffers will be written
+ by the background writer. Setting this to zero disables
+ background writing. (Note that checkpoints, which are managed by
+ a separate, dedicated auxiliary process, are unaffected.)
+ The default value is 100 buffers.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-BGWRITER-LRU-MULTIPLIER"><span class="term"><code class="varname">bgwriter_lru_multiplier</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.7.6.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The number of dirty buffers written in each round is based on the
+ number of new buffers that have been needed by server processes
+ during recent rounds. The average recent need is multiplied by
+ <code class="varname">bgwriter_lru_multiplier</code> to arrive at an estimate of the
+ number of buffers that will be needed during the next round. Dirty
+ buffers are written until there are that many clean, reusable buffers
+ available. (However, no more than <code class="varname">bgwriter_lru_maxpages</code>
+ buffers will be written per round.)
+ Thus, a setting of 1.0 represents a <span class="quote">“<span class="quote">just in time</span>”</span> policy
+ of writing exactly the number of buffers predicted to be needed.
+ Larger values provide some cushion against spikes in demand,
+ while smaller values intentionally leave writes to be done by
+ server processes.
+ The default is 2.0.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-BGWRITER-FLUSH-AFTER"><span class="term"><code class="varname">bgwriter_flush_after</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.6.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Whenever more than this amount of data has
+ been written by the background writer, attempt to force the OS to issue these
+ writes to the underlying storage. Doing so will limit the amount of
+ dirty data in the kernel's page cache, reducing the likelihood of
+ stalls when an <code class="function">fsync</code> is issued at the end of a checkpoint, or when
+ the OS writes data back in larger batches in the background. Often
+ that will result in greatly reduced transaction latency, but there
+ also are some cases, especially with workloads that are bigger than
+ <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>, but smaller than the OS's page
+ cache, where performance might degrade. This setting may have no
+ effect on some platforms.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The valid range is between
+ <code class="literal">0</code>, which disables forced writeback, and
+ <code class="literal">2MB</code>. The default is <code class="literal">512kB</code> on Linux,
+ <code class="literal">0</code> elsewhere. (If <code class="symbol">BLCKSZ</code> is not 8kB,
+ the default and maximum values scale proportionally to it.)
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div><p>
+ Smaller values of <code class="varname">bgwriter_lru_maxpages</code> and
+ <code class="varname">bgwriter_lru_multiplier</code> reduce the extra I/O load
+ caused by the background writer, but make it more likely that server
+ processes will have to issue writes for themselves, delaying interactive
+ queries.
+ </p></div><div class="sect2" id="RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR"><div class="titlepage"><div><div><h3 class="title">20.4.6. Asynchronous Behavior</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-BACKEND-FLUSH-AFTER"><span class="term"><code class="varname">backend_flush_after</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Whenever more than this amount of data has
+ been written by a single backend, attempt to force the OS to issue
+ these writes to the underlying storage. Doing so will limit the
+ amount of dirty data in the kernel's page cache, reducing the
+ likelihood of stalls when an <code class="function">fsync</code> is issued at the end of a
+ checkpoint, or when the OS writes data back in larger batches in the
+ background. Often that will result in greatly reduced transaction
+ latency, but there also are some cases, especially with workloads
+ that are bigger than <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>, but smaller
+ than the OS's page cache, where performance might degrade. This
+ setting may have no effect on some platforms.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The valid range is
+ between <code class="literal">0</code>, which disables forced writeback,
+ and <code class="literal">2MB</code>. The default is <code class="literal">0</code>, i.e., no
+ forced writeback. (If <code class="symbol">BLCKSZ</code> is not 8kB,
+ the maximum value scales proportionally to it.)
+ </p></dd><dt id="GUC-EFFECTIVE-IO-CONCURRENCY"><span class="term"><code class="varname">effective_io_concurrency</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the number of concurrent disk I/O operations that
+ <span class="productname">PostgreSQL</span> expects can be executed
+ simultaneously. Raising this value will increase the number of I/O
+ operations that any individual <span class="productname">PostgreSQL</span> session
+ attempts to initiate in parallel. The allowed range is 1 to 1000,
+ or zero to disable issuance of asynchronous I/O requests. Currently,
+ this setting only affects bitmap heap scans.
+ </p><p>
+ For magnetic drives, a good starting point for this setting is the
+ number of separate
+ drives comprising a RAID 0 stripe or RAID 1 mirror being used for the
+ database. (For RAID 5 the parity drive should not be counted.)
+ However, if the database is often busy with multiple queries issued in
+ concurrent sessions, lower values may be sufficient to keep the disk
+ array busy. A value higher than needed to keep the disks busy will
+ only result in extra CPU overhead.
+ SSDs and other memory-based storage can often process many
+ concurrent requests, so the best value might be in the hundreds.
+ </p><p>
+ Asynchronous I/O depends on an effective <code class="function">posix_fadvise</code>
+ function, which some operating systems lack. If the function is not
+ present then setting this parameter to anything but zero will result
+ in an error. On some operating systems (e.g., Solaris), the function
+ is present but does not actually do anything.
+ </p><p>
+ The default is 1 on supported systems, otherwise 0. This value can
+ be overridden for tables in a particular tablespace by setting the
+ tablespace parameter of the same name (see
+ <a class="xref" href="sql-altertablespace.html" title="ALTER TABLESPACE"><span class="refentrytitle">ALTER TABLESPACE</span></a>).
+ </p></dd><dt id="GUC-MAINTENANCE-IO-CONCURRENCY"><span class="term"><code class="varname">maintenance_io_concurrency</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Similar to <code class="varname">effective_io_concurrency</code>, but used
+ for maintenance work that is done on behalf of many client sessions.
+ </p><p>
+ The default is 10 on supported systems, otherwise 0. This value can
+ be overridden for tables in a particular tablespace by setting the
+ tablespace parameter of the same name (see
+ <a class="xref" href="sql-altertablespace.html" title="ALTER TABLESPACE"><span class="refentrytitle">ALTER TABLESPACE</span></a>).
+ </p></dd><dt id="GUC-MAX-WORKER-PROCESSES"><span class="term"><code class="varname">max_worker_processes</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum number of background processes that the system
+ can support. This parameter can only be set at server start. The
+ default is 8.
+ </p><p>
+ When running a standby server, you must set this parameter to the
+ same or higher value than on the primary server. Otherwise, queries
+ will not be allowed in the standby server.
+ </p><p>
+ When changing this value, consider also adjusting
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS">max_parallel_workers</a>,
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-MAINTENANCE-WORKERS">max_parallel_maintenance_workers</a>, and
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER">max_parallel_workers_per_gather</a>.
+ </p></dd><dt id="GUC-MAX-PARALLEL-WORKERS-PER-GATHER"><span class="term"><code class="varname">max_parallel_workers_per_gather</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum number of workers that can be started by a single
+ <code class="literal">Gather</code> or <code class="literal">Gather Merge</code> node.
+ Parallel workers are taken from the pool of processes established by
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>, limited by
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS">max_parallel_workers</a>. Note that the requested
+ number of workers may not actually be available at run time. If this
+ occurs, the plan will run with fewer workers than expected, which may
+ be inefficient. The default value is 2. Setting this value to 0
+ disables parallel query execution.
+ </p><p>
+ Note that parallel queries may consume very substantially more
+ resources than non-parallel queries, because each worker process is
+ a completely separate process which has roughly the same impact on the
+ system as an additional user session. This should be taken into
+ account when choosing a value for this setting, as well as when
+ configuring other settings that control resource utilization, such
+ as <a class="xref" href="runtime-config-resource.html#GUC-WORK-MEM">work_mem</a>. Resource limits such as
+ <code class="varname">work_mem</code> are applied individually to each worker,
+ which means the total utilization may be much higher across all
+ processes than it would normally be for any single process.
+ For example, a parallel query using 4 workers may use up to 5 times
+ as much CPU time, memory, I/O bandwidth, and so forth as a query which
+ uses no workers at all.
+ </p><p>
+ For more information on parallel query, see
+ <a class="xref" href="parallel-query.html" title="Chapter 15. Parallel Query">Chapter 15</a>.
+ </p></dd><dt id="GUC-MAX-PARALLEL-MAINTENANCE-WORKERS"><span class="term"><code class="varname">max_parallel_maintenance_workers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum number of parallel workers that can be
+ started by a single utility command. Currently, the parallel
+ utility commands that support the use of parallel workers are
+ <code class="command">CREATE INDEX</code> only when building a B-tree index,
+ and <code class="command">VACUUM</code> without <code class="literal">FULL</code>
+ option. Parallel workers are taken from the pool of processes
+ established by <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>, limited
+ by <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS">max_parallel_workers</a>. Note that the requested
+ number of workers may not actually be available at run time.
+ If this occurs, the utility operation will run with fewer
+ workers than expected. The default value is 2. Setting this
+ value to 0 disables the use of parallel workers by utility
+ commands.
+ </p><p>
+ Note that parallel utility commands should not consume
+ substantially more memory than equivalent non-parallel
+ operations. This strategy differs from that of parallel
+ query, where resource limits generally apply per worker
+ process. Parallel utility commands treat the resource limit
+ <code class="varname">maintenance_work_mem</code> as a limit to be applied to
+ the entire utility command, regardless of the number of
+ parallel worker processes. However, parallel utility
+ commands may still consume substantially more CPU resources
+ and I/O bandwidth.
+ </p></dd><dt id="GUC-MAX-PARALLEL-WORKERS"><span class="term"><code class="varname">max_parallel_workers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the maximum number of workers that the system can support for
+ parallel operations. The default value is 8. When increasing or
+ decreasing this value, consider also adjusting
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-MAINTENANCE-WORKERS">max_parallel_maintenance_workers</a> and
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER">max_parallel_workers_per_gather</a>.
+ Also, note that a setting for this value which is higher than
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a> will have no effect,
+ since parallel workers are taken from the pool of worker processes
+ established by that setting.
+ </p></dd><dt id="GUC-PARALLEL-LEADER-PARTICIPATION"><span class="term">
+ <code class="varname">parallel_leader_participation</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.7.7.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Allows the leader process to execute the query plan under
+ <code class="literal">Gather</code> and <code class="literal">Gather Merge</code> nodes
+ instead of waiting for worker processes. The default is
+ <code class="literal">on</code>. Setting this value to <code class="literal">off</code>
+ reduces the likelihood that workers will become blocked because the
+ leader is not reading tuples fast enough, but requires the leader
+ process to wait for worker processes to start up before the first
+ tuples can be produced. The degree to which the leader can help or
+ hinder performance depends on the plan type, number of workers and
+ query duration.
+ </p></dd><dt id="GUC-OLD-SNAPSHOT-THRESHOLD"><span class="term"><code class="varname">old_snapshot_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.7.7.2.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Sets the minimum amount of time that a query snapshot can be used
+ without risk of a <span class="quote">“<span class="quote">snapshot too old</span>”</span> error occurring
+ when using the snapshot. Data that has been dead for longer than
+ this threshold is allowed to be vacuumed away. This can help
+ prevent bloat in the face of snapshots which remain in use for a
+ long time. To prevent incorrect results due to cleanup of data which
+ would otherwise be visible to the snapshot, an error is generated
+ when the snapshot is older than this threshold and the snapshot is
+ used to read a page which has been modified since the snapshot was
+ built.
+ </p><p>
+ If this value is specified without units, it is taken as minutes.
+ A value of <code class="literal">-1</code> (the default) disables this feature,
+ effectively setting the snapshot age limit to infinity.
+ This parameter can only be set at server start.
+ </p><p>
+ Useful values for production work probably range from a small number
+ of hours to a few days. Small values (such as <code class="literal">0</code> or
+ <code class="literal">1min</code>) are only allowed because they may sometimes be
+ useful for testing. While a setting as high as <code class="literal">60d</code> is
+ allowed, please note that in many workloads extreme bloat or
+ transaction ID wraparound may occur in much shorter time frames.
+ </p><p>
+ When this feature is enabled, freed space at the end of a relation
+ cannot be released to the operating system, since that could remove
+ information needed to detect the <span class="quote">“<span class="quote">snapshot too old</span>”</span>
+ condition. All space allocated to a relation remains associated with
+ that relation for reuse only within that relation unless explicitly
+ freed (for example, with <code class="command">VACUUM FULL</code>).
+ </p><p>
+ This setting does not attempt to guarantee that an error will be
+ generated under any particular circumstances. In fact, if the
+ correct results can be generated from (for example) a cursor which
+ has materialized a result set, no error will be generated even if the
+ underlying rows in the referenced table have been vacuumed away.
+ Some tables cannot safely be vacuumed early, and so will not be
+ affected by this setting, such as system catalogs. For such tables
+ this setting will neither reduce bloat nor create a possibility
+ of a <span class="quote">“<span class="quote">snapshot too old</span>”</span> error on scanning.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-connection.html" title="20.3. Connections and Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-wal.html" title="20.5. Write Ahead Log">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.3. Connections and Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.5. Write Ahead Log</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-short.html b/doc/src/sgml/html/runtime-config-short.html
new file mode 100644
index 0000000..14347db
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-short.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.18. Short Options</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-developer.html" title="20.17. Developer Options" /><link rel="next" href="client-authentication.html" title="Chapter 21. Client Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.18. Short Options</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-developer.html" title="20.17. Developer Options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="client-authentication.html" title="Chapter 21. Client Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-SHORT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.18. Short Options</h2></div></div></div><p>
+ For convenience there are also single letter command-line option
+ switches available for some parameters. They are described in
+ <a class="xref" href="runtime-config-short.html#RUNTIME-CONFIG-SHORT-TABLE" title="Table 20.4. Short Option Key">Table 20.4</a>. Some of these
+ options exist for historical reasons, and their presence as a
+ single-letter option does not necessarily indicate an endorsement
+ to use the option heavily.
+ </p><div class="table" id="RUNTIME-CONFIG-SHORT-TABLE"><p class="title"><strong>Table 20.4. Short Option Key</strong></p><div class="table-contents"><table class="table" summary="Short Option Key" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Short Option</th><th>Equivalent</th></tr></thead><tbody><tr><td><code class="option">-B <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">shared_buffers = <em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-d <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">log_min_messages = DEBUG<em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-e</code></td><td><code class="literal">datestyle = euro</code></td></tr><tr><td>
+ <code class="option">-fb</code>, <code class="option">-fh</code>, <code class="option">-fi</code>,
+ <code class="option">-fm</code>, <code class="option">-fn</code>, <code class="option">-fo</code>,
+ <code class="option">-fs</code>, <code class="option">-ft</code>
+ </td><td>
+ <code class="literal">enable_bitmapscan = off</code>,
+ <code class="literal">enable_hashjoin = off</code>,
+ <code class="literal">enable_indexscan = off</code>,
+ <code class="literal">enable_mergejoin = off</code>,
+ <code class="literal">enable_nestloop = off</code>,
+ <code class="literal">enable_indexonlyscan = off</code>,
+ <code class="literal">enable_seqscan = off</code>,
+ <code class="literal">enable_tidscan = off</code>
+ </td></tr><tr><td><code class="option">-F</code></td><td><code class="literal">fsync = off</code></td></tr><tr><td><code class="option">-h <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">listen_addresses = <em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-i</code></td><td><code class="literal">listen_addresses = '*'</code></td></tr><tr><td><code class="option">-k <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">unix_socket_directories = <em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-l</code></td><td><code class="literal">ssl = on</code></td></tr><tr><td><code class="option">-N <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">max_connections = <em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-O</code></td><td><code class="literal">allow_system_table_mods = on</code></td></tr><tr><td><code class="option">-p <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">port = <em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-P</code></td><td><code class="literal">ignore_system_indexes = on</code></td></tr><tr><td><code class="option">-s</code></td><td><code class="literal">log_statement_stats = on</code></td></tr><tr><td><code class="option">-S <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">work_mem = <em class="replaceable"><code>x</code></em></code></td></tr><tr><td><code class="option">-tpa</code>, <code class="option">-tpl</code>, <code class="option">-te</code></td><td><code class="literal">log_parser_stats = on</code>,
+ <code class="literal">log_planner_stats = on</code>,
+ <code class="literal">log_executor_stats = on</code></td></tr><tr><td><code class="option">-W <em class="replaceable"><code>x</code></em></code></td><td><code class="literal">post_auth_delay = <em class="replaceable"><code>x</code></em></code></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-developer.html" title="20.17. Developer Options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="client-authentication.html" title="Chapter 21. Client Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.17. Developer Options </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 21. Client Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-statistics.html b/doc/src/sgml/html/runtime-config-statistics.html
new file mode 100644
index 0000000..ba28f7f
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-statistics.html
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.9. Run-time Statistics</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging" /><link rel="next" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.9. Run-time Statistics</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-STATISTICS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.9. Run-time Statistics</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">20.9.1. Cumulative Query and Index Statistics</a></span></dt><dt><span class="sect2"><a href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">20.9.2. Statistics Monitoring</a></span></dt></dl></div><div class="sect2" id="RUNTIME-CONFIG-CUMULATIVE-STATISTICS"><div class="titlepage"><div><div><h3 class="title">20.9.1. Cumulative Query and Index Statistics</h3></div></div></div><p>
+ These parameters control the server-wide cumulative statistics system.
+ When enabled, the data that is collected can be accessed via the
+ <code class="structname">pg_stat</code> and <code class="structname">pg_statio</code>
+ family of system views. Refer to <a class="xref" href="monitoring.html" title="Chapter 28. Monitoring Database Activity">Chapter 28</a> for more
+ information.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-TRACK-ACTIVITIES"><span class="term"><code class="varname">track_activities</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.2.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables the collection of information on the currently
+ executing command of each session, along with its identifier and the
+ time when that command began execution. This parameter is on by
+ default. Note that even when enabled, this information is only
+ visible to superusers, roles with privileges of the
+ <code class="literal">pg_read_all_stats</code> role and the user owning the
+ sessions being reported on (including sessions belonging to a role they
+ have the privileges of), so it should not represent a security risk.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-TRACK-ACTIVITY-QUERY-SIZE"><span class="term"><code class="varname">track_activity_query_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.12.2.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the amount of memory reserved to store the text of the
+ currently executing command for each active session, for the
+ <code class="structname">pg_stat_activity</code>.<code class="structfield">query</code> field.
+ If this value is specified without units, it is taken as bytes.
+ The default value is 1024 bytes.
+ This parameter can only be set at server start.
+ </p></dd><dt id="GUC-TRACK-COUNTS"><span class="term"><code class="varname">track_counts</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.2.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables collection of statistics on database activity.
+ This parameter is on by default, because the autovacuum
+ daemon needs the collected information.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-TRACK-IO-TIMING"><span class="term"><code class="varname">track_io_timing</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.2.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables timing of database I/O calls. This parameter is off by
+ default, as it will repeatedly query the operating system for
+ the current time, which may cause significant overhead on some
+ platforms. You can use the <a class="xref" href="pgtesttiming.html" title="pg_test_timing"><span class="refentrytitle"><span class="application">pg_test_timing</span></span></a> tool to
+ measure the overhead of timing on your system.
+ I/O timing information is
+ displayed in <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW" title="28.2.15. pg_stat_database">
+ <code class="structname">pg_stat_database</code></a>, in the output of
+ <a class="xref" href="sql-explain.html" title="EXPLAIN"><span class="refentrytitle">EXPLAIN</span></a> when the <code class="literal">BUFFERS</code> option
+ is used, in the output of <a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a> when
+ the <code class="literal">VERBOSE</code> option is used, by autovacuum
+ for auto-vacuums and auto-analyzes, when <a class="xref" href="runtime-config-logging.html#GUC-LOG-AUTOVACUUM-MIN-DURATION">log_autovacuum_min_duration</a> is set and by
+ <a class="xref" href="pgstatstatements.html" title="F.32. pg_stat_statements">pg_stat_statements</a>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-TRACK-WAL-IO-TIMING"><span class="term"><code class="varname">track_wal_io_timing</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.2.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables timing of WAL I/O calls. This parameter is off by default,
+ as it will repeatedly query the operating system for the current time,
+ which may cause significant overhead on some platforms.
+ You can use the <span class="application">pg_test_timing</span> tool to
+ measure the overhead of timing on your system.
+ I/O timing information is
+ displayed in <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-WAL-VIEW" title="28.2.14. pg_stat_wal">
+ <code class="structname">pg_stat_wal</code></a>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p></dd><dt id="GUC-TRACK-FUNCTIONS"><span class="term"><code class="varname">track_functions</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.12.2.3.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables tracking of function call counts and time used. Specify
+ <code class="literal">pl</code> to track only procedural-language functions,
+ <code class="literal">all</code> to also track SQL and C language functions.
+ The default is <code class="literal">none</code>, which disables function
+ statistics tracking.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ SQL-language functions that are simple enough to be <span class="quote">“<span class="quote">inlined</span>”</span>
+ into the calling query will not be tracked, regardless of this
+ setting.
+ </p></div></dd><dt id="GUC-STATS-FETCH-CONSISTENCY"><span class="term"><code class="varname">stats_fetch_consistency</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.12.2.3.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines the behavior when cumulative statistics are accessed
+ multiple times within a transaction. When set to
+ <code class="literal">none</code>, each access re-fetches counters from shared
+ memory. When set to <code class="literal">cache</code>, the first access to
+ statistics for an object caches those statistics until the end of the
+ transaction unless <code class="function">pg_stat_clear_snapshot()</code> is
+ called. When set to <code class="literal">snapshot</code>, the first statistics
+ access caches all statistics accessible in the current database, until
+ the end of the transaction unless
+ <code class="function">pg_stat_clear_snapshot()</code> is called. Changing this
+ parameter in a transaction discards the statistics snapshot.
+ The default is <code class="literal">cache</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="literal">none</code> is most suitable for monitoring systems. If
+ values are only accessed once, it is the most
+ efficient. <code class="literal">cache</code> ensures repeat accesses yield the
+ same values, which is important for queries involving
+ e.g. self-joins. <code class="literal">snapshot</code> can be useful when
+ interactively inspecting statistics, but has higher overhead,
+ particularly if many database objects exist.
+ </p></div></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-STATISTICS-MONITOR"><div class="titlepage"><div><div><h3 class="title">20.9.2. Statistics Monitoring</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-COMPUTE-QUERY-ID"><span class="term"><code class="varname">compute_query_id</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.12.3.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables in-core computation of a query identifier.
+ Query identifiers can be displayed in the <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW" title="28.2.3. pg_stat_activity"><code class="structname">pg_stat_activity</code></a>
+ view, using <code class="command">EXPLAIN</code>, or emitted in the log if
+ configured via the <a class="xref" href="runtime-config-logging.html#GUC-LOG-LINE-PREFIX">log_line_prefix</a> parameter.
+ The <a class="xref" href="pgstatstatements.html" title="F.32. pg_stat_statements">pg_stat_statements</a> extension also requires a query
+ identifier to be computed. Note that an external module can
+ alternatively be used if the in-core query identifier computation
+ method is not acceptable. In this case, in-core computation
+ must be always disabled.
+ Valid values are <code class="literal">off</code> (always disabled),
+ <code class="literal">on</code> (always enabled), <code class="literal">auto</code>,
+ which lets modules such as <a class="xref" href="pgstatstatements.html" title="F.32. pg_stat_statements">pg_stat_statements</a>
+ automatically enable it, and <code class="literal">regress</code> which
+ has the same effect as <code class="literal">auto</code>, except that the
+ query identifier is not shown in the <code class="literal">EXPLAIN</code> output
+ in order to facilitate automated regression testing.
+ The default is <code class="literal">auto</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ To ensure that only one query identifier is calculated and
+ displayed, extensions that calculate query identifiers should
+ throw an error if a query identifier has already been computed.
+ </p></div></dd><dt><span class="term"><code class="varname">log_statement_stats</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.3.2.2.1.3" class="indexterm"></a>
+ <br /></span><span class="term"><code class="varname">log_parser_stats</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.3.2.2.2.3" class="indexterm"></a>
+ <br /></span><span class="term"><code class="varname">log_planner_stats</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.3.2.2.3.3" class="indexterm"></a>
+ <br /></span><span class="term"><code class="varname">log_executor_stats</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.12.3.2.2.4.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ For each query, output performance statistics of the respective
+ module to the server log. This is a crude profiling
+ instrument, similar to the Unix <code class="function">getrusage()</code> operating
+ system facility. <code class="varname">log_statement_stats</code> reports total
+ statement statistics, while the others report per-module statistics.
+ <code class="varname">log_statement_stats</code> cannot be enabled together with
+ any of the per-module options. All of these options are disabled by
+ default.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change these settings.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-logging.html" title="20.8. Error Reporting and Logging">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-autovacuum.html" title="20.10. Automatic Vacuuming">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.8. Error Reporting and Logging </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.10. Automatic Vacuuming</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config-wal.html b/doc/src/sgml/html/runtime-config-wal.html
new file mode 100644
index 0000000..a95d4cd
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config-wal.html
@@ -0,0 +1,830 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>20.5. Write Ahead Log</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="runtime-config-resource.html" title="20.4. Resource Consumption" /><link rel="next" href="runtime-config-replication.html" title="20.6. Replication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">20.5. Write Ahead Log</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="runtime-config-resource.html" title="20.4. Resource Consumption">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><th width="60%" align="center">Chapter 20. Server Configuration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="runtime-config-replication.html" title="20.6. Replication">Next</a></td></tr></table><hr /></div><div class="sect1" id="RUNTIME-CONFIG-WAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">20.5. Write Ahead Log</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">20.5.1. Settings</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">20.5.2. Checkpoints</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING">20.5.3. Archiving</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY">20.5.4. Recovery</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">20.5.5. Archive Recovery</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">20.5.6. Recovery Target</a></span></dt></dl></div><p>
+ For additional information on tuning these settings,
+ see <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a>.
+ </p><div class="sect2" id="RUNTIME-CONFIG-WAL-SETTINGS"><div class="titlepage"><div><div><h3 class="title">20.5.1. Settings</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-WAL-LEVEL"><span class="term"><code class="varname">wal_level</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.3.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ <code class="varname">wal_level</code> determines how much information is written to
+ the WAL. The default value is <code class="literal">replica</code>, which writes enough
+ data to support WAL archiving and replication, including running
+ read-only queries on a standby server. <code class="literal">minimal</code> removes all
+ logging except the information required to recover from a crash or
+ immediate shutdown. Finally,
+ <code class="literal">logical</code> adds information necessary to support logical
+ decoding. Each level includes the information logged at all lower
+ levels. This parameter can only be set at server start.
+ </p><p>
+ The <code class="literal">minimal</code> level generates the least WAL
+ volume. It logs no row information for permanent relations
+ in transactions that create or
+ rewrite them. This can make operations much faster (see
+ <a class="xref" href="populate.html#POPULATE-PITR" title="14.4.7. Disable WAL Archival and Streaming Replication">Section 14.4.7</a>). Operations that initiate this
+ optimization include:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="command">ALTER ... SET TABLESPACE</code></td></tr><tr><td><code class="command">CLUSTER</code></td></tr><tr><td><code class="command">CREATE TABLE</code></td></tr><tr><td><code class="command">REFRESH MATERIALIZED VIEW</code>
+ (without <code class="option">CONCURRENTLY</code>)</td></tr><tr><td><code class="command">REINDEX</code></td></tr><tr><td><code class="command">TRUNCATE</code></td></tr></table><p>
+ However, minimal WAL does not contain sufficient information for
+ point-in-time recovery, so <code class="literal">replica</code> or
+ higher must be used to enable continuous archiving
+ (<a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-MODE">archive_mode</a>) and streaming binary replication.
+ In fact, the server will not even start in this mode if
+ <code class="varname">max_wal_senders</code> is non-zero.
+ Note that changing <code class="varname">wal_level</code> to
+ <code class="literal">minimal</code> makes previous base backups unusable
+ for point-in-time recovery and standby servers.
+ </p><p>
+ In <code class="literal">logical</code> level, the same information is logged as
+ with <code class="literal">replica</code>, plus information needed to
+ extract logical change sets from the WAL. Using a level of
+ <code class="literal">logical</code> will increase the WAL volume, particularly if many
+ tables are configured for <code class="literal">REPLICA IDENTITY FULL</code> and
+ many <code class="command">UPDATE</code> and <code class="command">DELETE</code> statements are
+ executed.
+ </p><p>
+ In releases prior to 9.6, this parameter also allowed the
+ values <code class="literal">archive</code> and <code class="literal">hot_standby</code>.
+ These are still accepted but mapped to <code class="literal">replica</code>.
+ </p></dd><dt id="GUC-FSYNC"><span class="term"><code class="varname">fsync</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.8.3.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If this parameter is on, the <span class="productname">PostgreSQL</span> server
+ will try to make sure that updates are physically written to
+ disk, by issuing <code class="function">fsync()</code> system calls or various
+ equivalent methods (see <a class="xref" href="runtime-config-wal.html#GUC-WAL-SYNC-METHOD">wal_sync_method</a>).
+ This ensures that the database cluster can recover to a
+ consistent state after an operating system or hardware crash.
+ </p><p>
+ While turning off <code class="varname">fsync</code> is often a performance
+ benefit, this can result in unrecoverable data corruption in
+ the event of a power failure or system crash. Thus it
+ is only advisable to turn off <code class="varname">fsync</code> if
+ you can easily recreate your entire database from external
+ data.
+ </p><p>
+ Examples of safe circumstances for turning off
+ <code class="varname">fsync</code> include the initial loading of a new
+ database cluster from a backup file, using a database cluster
+ for processing a batch of data after which the database
+ will be thrown away and recreated,
+ or for a read-only database clone which
+ gets recreated frequently and is not used for failover. High
+ quality hardware alone is not a sufficient justification for
+ turning off <code class="varname">fsync</code>.
+ </p><p>
+ For reliable recovery when changing <code class="varname">fsync</code>
+ off to on, it is necessary to force all modified buffers in the
+ kernel to durable storage. This can be done while the cluster
+ is shutdown or while <code class="varname">fsync</code> is on by running <code class="command">initdb
+ --sync-only</code>, running <code class="command">sync</code>, unmounting the
+ file system, or rebooting the server.
+ </p><p>
+ In many situations, turning off <a class="xref" href="runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT">synchronous_commit</a>
+ for noncritical transactions can provide much of the potential
+ performance benefit of turning off <code class="varname">fsync</code>, without
+ the attendant risks of data corruption.
+ </p><p>
+ <code class="varname">fsync</code> can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ If you turn this parameter off, also consider turning off
+ <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a>.
+ </p></dd><dt id="GUC-SYNCHRONOUS-COMMIT"><span class="term"><code class="varname">synchronous_commit</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.3.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies how much WAL processing must complete before
+ the database server returns a <span class="quote">“<span class="quote">success</span>”</span>
+ indication to the client. Valid values are
+ <code class="literal">remote_apply</code>, <code class="literal">on</code>
+ (the default), <code class="literal">remote_write</code>,
+ <code class="literal">local</code>, and <code class="literal">off</code>.
+ </p><p>
+ If <code class="varname">synchronous_standby_names</code> is empty,
+ the only meaningful settings are <code class="literal">on</code> and
+ <code class="literal">off</code>; <code class="literal">remote_apply</code>,
+ <code class="literal">remote_write</code> and <code class="literal">local</code>
+ all provide the same local synchronization level
+ as <code class="literal">on</code>. The local behavior of all
+ non-<code class="literal">off</code> modes is to wait for local flush of WAL
+ to disk. In <code class="literal">off</code> mode, there is no waiting,
+ so there can be a delay between when success is reported to the
+ client and when the transaction is later guaranteed to be safe
+ against a server crash. (The maximum
+ delay is three times <a class="xref" href="runtime-config-wal.html#GUC-WAL-WRITER-DELAY">wal_writer_delay</a>.) Unlike
+ <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a>, setting this parameter to <code class="literal">off</code>
+ does not create any risk of database inconsistency: an operating
+ system or database crash might
+ result in some recent allegedly-committed transactions being lost, but
+ the database state will be just the same as if those transactions had
+ been aborted cleanly. So, turning <code class="varname">synchronous_commit</code> off
+ can be a useful alternative when performance is more important than
+ exact certainty about the durability of a transaction. For more
+ discussion see <a class="xref" href="wal-async-commit.html" title="30.4. Asynchronous Commit">Section 30.4</a>.
+ </p><p>
+ If <a class="xref" href="runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES">synchronous_standby_names</a> is non-empty,
+ <code class="varname">synchronous_commit</code> also controls whether
+ transaction commits will wait for their WAL records to be
+ processed on the standby server(s).
+ </p><p>
+ When set to <code class="literal">remote_apply</code>, commits will wait
+ until replies from the current synchronous standby(s) indicate they
+ have received the commit record of the transaction and applied
+ it, so that it has become visible to queries on the standby(s),
+ and also written to durable storage on the standbys. This will
+ cause much larger commit delays than previous settings since
+ it waits for WAL replay. When set to <code class="literal">on</code>,
+ commits wait until replies
+ from the current synchronous standby(s) indicate they have received
+ the commit record of the transaction and flushed it to durable storage. This
+ ensures the transaction will not be lost unless both the primary and
+ all synchronous standbys suffer corruption of their database storage.
+ When set to <code class="literal">remote_write</code>, commits will wait until replies
+ from the current synchronous standby(s) indicate they have
+ received the commit record of the transaction and written it to
+ their file systems. This setting ensures data preservation if a standby instance of
+ <span class="productname">PostgreSQL</span> crashes, but not if the standby
+ suffers an operating-system-level crash because the data has not
+ necessarily reached durable storage on the standby.
+ The setting <code class="literal">local</code> causes commits to wait for
+ local flush to disk, but not for replication. This is usually not
+ desirable when synchronous replication is in use, but is provided for
+ completeness.
+ </p><p>
+ This parameter can be changed at any time; the behavior for any
+ one transaction is determined by the setting in effect when it
+ commits. It is therefore possible, and useful, to have some
+ transactions commit synchronously and others asynchronously.
+ For example, to make a single multistatement transaction commit
+ asynchronously when the default is the opposite, issue <code class="command">SET
+ LOCAL synchronous_commit TO OFF</code> within the transaction.
+ </p><p>
+ <a class="xref" href="runtime-config-wal.html#SYNCHRONOUS-COMMIT-MATRIX" title="Table 20.1. synchronous_commit Modes">Table 20.1</a> summarizes the
+ capabilities of the <code class="varname">synchronous_commit</code> settings.
+ </p><div class="table" id="SYNCHRONOUS-COMMIT-MATRIX"><p class="title"><strong>Table 20.1. synchronous_commit Modes</strong></p><div class="table-contents"><table class="table" summary="synchronous_commit Modes" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /></colgroup><thead><tr><th>synchronous_commit setting</th><th>local durable commit</th><th>standby durable commit after PG crash</th><th>standby durable commit after OS crash</th><th>standby query consistency</th></tr></thead><tbody><tr><td>remote_apply</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center">•</td></tr><tr><td>on</td><td align="center">•</td><td align="center">•</td><td align="center">•</td><td align="center"> </td></tr><tr><td>remote_write</td><td align="center">•</td><td align="center">•</td><td align="center"> </td><td align="center"> </td></tr><tr><td>local</td><td align="center">•</td><td align="center"> </td><td align="center"> </td><td align="center"> </td></tr><tr><td>off</td><td align="center"> </td><td align="center"> </td><td align="center"> </td><td align="center"> </td></tr></tbody></table></div></div><br class="table-break" /></dd><dt id="GUC-WAL-SYNC-METHOD"><span class="term"><code class="varname">wal_sync_method</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.3.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Method used for forcing WAL updates out to disk.
+ If <code class="varname">fsync</code> is off then this setting is irrelevant,
+ since WAL file updates will not be forced out at all.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">open_datasync</code> (write WAL files with <code class="function">open()</code> option <code class="symbol">O_DSYNC</code>)
+ </p></li><li class="listitem"><p>
+ <code class="literal">fdatasync</code> (call <code class="function">fdatasync()</code> at each commit)
+ </p></li><li class="listitem"><p>
+ <code class="literal">fsync</code> (call <code class="function">fsync()</code> at each commit)
+ </p></li><li class="listitem"><p>
+ <code class="literal">fsync_writethrough</code> (call <code class="function">fsync()</code> at each commit, forcing write-through of any disk write cache)
+ </p></li><li class="listitem"><p>
+ <code class="literal">open_sync</code> (write WAL files with <code class="function">open()</code> option <code class="symbol">O_SYNC</code>)
+ </p></li></ul></div><p>
+ The <code class="literal">open_</code>* options also use <code class="literal">O_DIRECT</code> if available.
+ Not all of these choices are available on all platforms.
+ The default is the first method in the above list that is supported
+ by the platform, except that <code class="literal">fdatasync</code> is the default on
+ Linux and FreeBSD. The default is not necessarily ideal; it might be
+ necessary to change this setting or other aspects of your system
+ configuration in order to create a crash-safe configuration or
+ achieve optimal performance.
+ These aspects are discussed in <a class="xref" href="wal-reliability.html" title="30.1. Reliability">Section 30.1</a>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-FULL-PAGE-WRITES"><span class="term"><code class="varname">full_page_writes</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.8.3.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When this parameter is on, the <span class="productname">PostgreSQL</span> server
+ writes the entire content of each disk page to WAL during the
+ first modification of that page after a checkpoint.
+ This is needed because
+ a page write that is in process during an operating system crash might
+ be only partially completed, leading to an on-disk page
+ that contains a mix of old and new data. The row-level change data
+ normally stored in WAL will not be enough to completely restore
+ such a page during post-crash recovery. Storing the full page image
+ guarantees that the page can be correctly restored, but at the price
+ of increasing the amount of data that must be written to WAL.
+ (Because WAL replay always starts from a checkpoint, it is sufficient
+ to do this during the first change of each page after a checkpoint.
+ Therefore, one way to reduce the cost of full-page writes is to
+ increase the checkpoint interval parameters.)
+ </p><p>
+ Turning this parameter off speeds normal operation, but
+ might lead to either unrecoverable data corruption, or silent
+ data corruption, after a system failure. The risks are similar to turning off
+ <code class="varname">fsync</code>, though smaller, and it should be turned off
+ only based on the same circumstances recommended for that parameter.
+ </p><p>
+ Turning off this parameter does not affect use of
+ WAL archiving for point-in-time recovery (PITR)
+ (see <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>).
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ The default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-WAL-LOG-HINTS"><span class="term"><code class="varname">wal_log_hints</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.8.3.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When this parameter is <code class="literal">on</code>, the <span class="productname">PostgreSQL</span>
+ server writes the entire content of each disk page to WAL during the
+ first modification of that page after a checkpoint, even for
+ non-critical modifications of so-called hint bits.
+ </p><p>
+ If data checksums are enabled, hint bit updates are always WAL-logged
+ and this setting is ignored. You can use this setting to test how much
+ extra WAL-logging would occur if your database had data checksums
+ enabled.
+ </p><p>
+ This parameter can only be set at server start. The default value is <code class="literal">off</code>.
+ </p></dd><dt id="GUC-WAL-COMPRESSION"><span class="term"><code class="varname">wal_compression</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.3.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter enables compression of WAL using the specified
+ compression method.
+ When enabled, the <span class="productname">PostgreSQL</span>
+ server compresses full page images written to WAL when
+ <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a> is on or during a base backup.
+ A compressed page image will be decompressed during WAL replay.
+ The supported methods are <code class="literal">pglz</code>,
+ <code class="literal">lz4</code> (if <span class="productname">PostgreSQL</span>
+ was compiled with <code class="option">--with-lz4</code>) and
+ <code class="literal">zstd</code> (if <span class="productname">PostgreSQL</span>
+ was compiled with <code class="option">--with-zstd</code>).
+ The default value is <code class="literal">off</code>.
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ Enabling compression can reduce the WAL volume without
+ increasing the risk of unrecoverable data corruption,
+ but at the cost of some extra CPU spent on the compression during
+ WAL logging and on the decompression during WAL replay.
+ </p></dd><dt id="GUC-WAL-INIT-ZERO"><span class="term"><code class="varname">wal_init_zero</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.8.3.2.8.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If set to <code class="literal">on</code> (the default), this option causes new
+ WAL files to be filled with zeroes. On some file systems, this ensures
+ that space is allocated before we need to write WAL records. However,
+ <em class="firstterm">Copy-On-Write</em> (COW) file systems may not benefit
+ from this technique, so the option is given to skip the unnecessary
+ work. If set to <code class="literal">off</code>, only the final byte is written
+ when the file is created so that it has the expected size.
+ </p></dd><dt id="GUC-WAL-RECYCLE"><span class="term"><code class="varname">wal_recycle</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.8.3.2.9.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ If set to <code class="literal">on</code> (the default), this option causes WAL
+ files to be recycled by renaming them, avoiding the need to create new
+ ones. On COW file systems, it may be faster to create new ones, so the
+ option is given to disable this behavior.
+ </p></dd><dt id="GUC-WAL-BUFFERS"><span class="term"><code class="varname">wal_buffers</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.3.2.10.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The amount of shared memory used for WAL data that has not yet been
+ written to disk. The default setting of -1 selects a size equal to
+ 1/32nd (about 3%) of <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>, but not less
+ than <code class="literal">64kB</code> nor more than the size of one WAL
+ segment, typically <code class="literal">16MB</code>. This value can be set
+ manually if the automatic choice is too large or too small,
+ but any positive value less than <code class="literal">32kB</code> will be
+ treated as <code class="literal">32kB</code>.
+ If this value is specified without units, it is taken as WAL blocks,
+ that is <code class="symbol">XLOG_BLCKSZ</code> bytes, typically 8kB.
+ This parameter can only be set at server start.
+ </p><p>
+ The contents of the WAL buffers are written out to disk at every
+ transaction commit, so extremely large values are unlikely to
+ provide a significant benefit. However, setting this value to at
+ least a few megabytes can improve write performance on a busy
+ server where many clients are committing at once. The auto-tuning
+ selected by the default setting of -1 should give reasonable
+ results in most cases.
+ </p></dd><dt id="GUC-WAL-WRITER-DELAY"><span class="term"><code class="varname">wal_writer_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.3.2.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies how often the WAL writer flushes WAL, in time terms.
+ After flushing WAL the writer sleeps for the length of time given
+ by <code class="varname">wal_writer_delay</code>, unless woken up sooner
+ by an asynchronously committing transaction. If the last flush
+ happened less than <code class="varname">wal_writer_delay</code> ago and less
+ than <code class="varname">wal_writer_flush_after</code> worth of WAL has been
+ produced since, then WAL is only written to the operating system, not
+ flushed to disk.
+ If this value is specified without units, it is taken as milliseconds.
+ The default value is 200 milliseconds (<code class="literal">200ms</code>). Note that
+ on many systems, the effective resolution of sleep delays is 10
+ milliseconds; setting <code class="varname">wal_writer_delay</code> to a value that is
+ not a multiple of 10 might have the same results as setting it to the
+ next higher multiple of 10. This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-WAL-WRITER-FLUSH-AFTER"><span class="term"><code class="varname">wal_writer_flush_after</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.3.2.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies how often the WAL writer flushes WAL, in volume terms.
+ If the last flush happened less
+ than <code class="varname">wal_writer_delay</code> ago and less
+ than <code class="varname">wal_writer_flush_after</code> worth of WAL has been
+ produced since, then WAL is only written to the operating system, not
+ flushed to disk. If <code class="varname">wal_writer_flush_after</code> is set
+ to <code class="literal">0</code> then WAL data is always flushed immediately.
+ If this value is specified without units, it is taken as WAL blocks,
+ that is <code class="symbol">XLOG_BLCKSZ</code> bytes, typically 8kB.
+ The default is <code class="literal">1MB</code>.
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-WAL-SKIP-THRESHOLD"><span class="term"><code class="varname">wal_skip_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.3.2.13.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">wal_level</code> is <code class="literal">minimal</code> and a
+ transaction commits after creating or rewriting a permanent relation,
+ this setting determines how to persist the new data. If the data is
+ smaller than this setting, write it to the WAL log; otherwise, use an
+ fsync of affected files. Depending on the properties of your storage,
+ raising or lowering this value might help if such commits are slowing
+ concurrent transactions. If this value is specified without units, it
+ is taken as kilobytes. The default is two megabytes
+ (<code class="literal">2MB</code>).
+ </p></dd><dt id="GUC-COMMIT-DELAY"><span class="term"><code class="varname">commit_delay</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.3.2.14.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Setting <code class="varname">commit_delay</code> adds a time delay
+ before a WAL flush is initiated. This can improve
+ group commit throughput by allowing a larger number of transactions
+ to commit via a single WAL flush, if system load is high enough
+ that additional transactions become ready to commit within the
+ given interval. However, it also increases latency by up to the
+ <code class="varname">commit_delay</code> for each WAL
+ flush. Because the delay is just wasted if no other transactions
+ become ready to commit, a delay is only performed if at least
+ <code class="varname">commit_siblings</code> other transactions are active
+ when a flush is about to be initiated. Also, no delays are
+ performed if <code class="varname">fsync</code> is disabled.
+ If this value is specified without units, it is taken as microseconds.
+ The default <code class="varname">commit_delay</code> is zero (no delay).
+ Only superusers and users with the appropriate <code class="literal">SET</code>
+ privilege can change this setting.
+ </p><p>
+ In <span class="productname">PostgreSQL</span> releases prior to 9.3,
+ <code class="varname">commit_delay</code> behaved differently and was much
+ less effective: it affected only commits, rather than all WAL flushes,
+ and waited for the entire configured delay even if the WAL flush
+ was completed sooner. Beginning in <span class="productname">PostgreSQL</span> 9.3,
+ the first process that becomes ready to flush waits for the configured
+ interval, while subsequent processes wait only until the leader
+ completes the flush operation.
+ </p></dd><dt id="GUC-COMMIT-SIBLINGS"><span class="term"><code class="varname">commit_siblings</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.3.2.15.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Minimum number of concurrent open transactions to require
+ before performing the <code class="varname">commit_delay</code> delay. A larger
+ value makes it more probable that at least one other
+ transaction will become ready to commit during the delay
+ interval. The default is five transactions.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-WAL-CHECKPOINTS"><div class="titlepage"><div><div><h3 class="title">20.5.2. Checkpoints</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-CHECKPOINT-TIMEOUT"><span class="term"><code class="varname">checkpoint_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.4.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Maximum time between automatic WAL checkpoints.
+ If this value is specified without units, it is taken as seconds.
+ The valid range is between 30 seconds and one day.
+ The default is five minutes (<code class="literal">5min</code>).
+ Increasing this parameter can increase the amount of time needed
+ for crash recovery.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-CHECKPOINT-COMPLETION-TARGET"><span class="term"><code class="varname">checkpoint_completion_target</code> (<code class="type">floating point</code>)
+ <a id="id-1.6.7.8.4.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies the target of checkpoint completion, as a fraction of
+ total time between checkpoints. The default is 0.9, which spreads the
+ checkpoint across almost all of the available interval, providing fairly
+ consistent I/O load while also leaving some time for checkpoint
+ completion overhead. Reducing this parameter is not recommended because
+ it causes the checkpoint to complete faster. This results in a higher
+ rate of I/O during the checkpoint followed by a period of less I/O between
+ the checkpoint completion and the next scheduled checkpoint. This
+ parameter can only be set in the <code class="filename">postgresql.conf</code> file
+ or on the server command line.
+ </p></dd><dt id="GUC-CHECKPOINT-FLUSH-AFTER"><span class="term"><code class="varname">checkpoint_flush_after</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.4.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Whenever more than this amount of data has been
+ written while performing a checkpoint, attempt to force the
+ OS to issue these writes to the underlying storage. Doing so will
+ limit the amount of dirty data in the kernel's page cache, reducing
+ the likelihood of stalls when an <code class="function">fsync</code> is issued at the end of the
+ checkpoint, or when the OS writes data back in larger batches in the
+ background. Often that will result in greatly reduced transaction
+ latency, but there also are some cases, especially with workloads
+ that are bigger than <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>, but smaller
+ than the OS's page cache, where performance might degrade. This
+ setting may have no effect on some platforms.
+ If this value is specified without units, it is taken as blocks,
+ that is <code class="symbol">BLCKSZ</code> bytes, typically 8kB.
+ The valid range is
+ between <code class="literal">0</code>, which disables forced writeback,
+ and <code class="literal">2MB</code>. The default is <code class="literal">256kB</code> on
+ Linux, <code class="literal">0</code> elsewhere. (If <code class="symbol">BLCKSZ</code> is not
+ 8kB, the default and maximum values scale proportionally to it.)
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-CHECKPOINT-WARNING"><span class="term"><code class="varname">checkpoint_warning</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.4.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Write a message to the server log if checkpoints caused by
+ the filling of WAL segment files happen closer together
+ than this amount of time (which suggests that
+ <code class="varname">max_wal_size</code> ought to be raised).
+ If this value is specified without units, it is taken as seconds.
+ The default is 30 seconds (<code class="literal">30s</code>).
+ Zero disables the warning.
+ No warnings will be generated if <code class="varname">checkpoint_timeout</code>
+ is less than <code class="varname">checkpoint_warning</code>.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-MAX-WAL-SIZE"><span class="term"><code class="varname">max_wal_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.4.2.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Maximum size to let the WAL grow during automatic
+ checkpoints. This is a soft limit; WAL size can exceed
+ <code class="varname">max_wal_size</code> under special circumstances, such as
+ heavy load, a failing <code class="varname">archive_command</code> or <code class="varname">archive_library</code>, or a high
+ <code class="varname">wal_keep_size</code> setting.
+ If this value is specified without units, it is taken as megabytes.
+ The default is 1 GB.
+ Increasing this parameter can increase the amount of time needed for
+ crash recovery.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-MIN-WAL-SIZE"><span class="term"><code class="varname">min_wal_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.4.2.6.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ As long as WAL disk usage stays below this setting, old WAL files are
+ always recycled for future use at a checkpoint, rather than removed.
+ This can be used to ensure that enough WAL space is reserved to
+ handle spikes in WAL usage, for example when running large batch
+ jobs.
+ If this value is specified without units, it is taken as megabytes.
+ The default is 80 MB.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-WAL-ARCHIVING"><div class="titlepage"><div><div><h3 class="title">20.5.3. Archiving</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-ARCHIVE-MODE"><span class="term"><code class="varname">archive_mode</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.5.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ When <code class="varname">archive_mode</code> is enabled, completed WAL segments
+ are sent to archive storage by setting
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> or
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a>. In addition to <code class="literal">off</code>,
+ to disable, there are two modes: <code class="literal">on</code>, and
+ <code class="literal">always</code>. During normal operation, there is no
+ difference between the two modes, but when set to <code class="literal">always</code>
+ the WAL archiver is enabled also during archive recovery or standby
+ mode. In <code class="literal">always</code> mode, all files restored from the archive
+ or streamed with streaming replication will be archived (again). See
+ <a class="xref" href="warm-standby.html#CONTINUOUS-ARCHIVING-IN-STANDBY" title="27.2.9. Continuous Archiving in Standby">Section 27.2.9</a> for details.
+ </p><p>
+ <code class="varname">archive_mode</code> is a separate setting from
+ <code class="varname">archive_command</code> and
+ <code class="varname">archive_library</code> so that
+ <code class="varname">archive_command</code> and
+ <code class="varname">archive_library</code> can be changed without leaving
+ archiving mode.
+ This parameter can only be set at server start.
+ <code class="varname">archive_mode</code> cannot be enabled when
+ <code class="varname">wal_level</code> is set to <code class="literal">minimal</code>.
+ </p></dd><dt id="GUC-ARCHIVE-COMMAND"><span class="term"><code class="varname">archive_command</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.5.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The local shell command to execute to archive a completed WAL file
+ segment. Any <code class="literal">%p</code> in the string is
+ replaced by the path name of the file to archive, and any
+ <code class="literal">%f</code> is replaced by only the file name.
+ (The path name is relative to the working directory of the server,
+ i.e., the cluster's data directory.)
+ Use <code class="literal">%%</code> to embed an actual <code class="literal">%</code> character in the
+ command. It is important for the command to return a zero
+ exit status only if it succeeds. For more information see
+ <a class="xref" href="continuous-archiving.html#BACKUP-ARCHIVING-WAL" title="26.3.1. Setting Up WAL Archiving">Section 26.3.1</a>.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line. It is ignored unless
+ <code class="varname">archive_mode</code> was enabled at server start and
+ <code class="varname">archive_library</code> is set to an empty string.
+ If <code class="varname">archive_command</code> is an empty string (the default) while
+ <code class="varname">archive_mode</code> is enabled (and <code class="varname">archive_library</code>
+ is set to an empty string), WAL archiving is temporarily
+ disabled, but the server continues to accumulate WAL segment files in
+ the expectation that a command will soon be provided. Setting
+ <code class="varname">archive_command</code> to a command that does nothing but
+ return true, e.g., <code class="literal">/bin/true</code> (<code class="literal">REM</code> on
+ Windows), effectively disables
+ archiving, but also breaks the chain of WAL files needed for
+ archive recovery, so it should only be used in unusual circumstances.
+ </p></dd><dt id="GUC-ARCHIVE-LIBRARY"><span class="term"><code class="varname">archive_library</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.5.2.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The library to use for archiving completed WAL file segments. If set to
+ an empty string (the default), archiving via shell is enabled, and
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> is used. Otherwise, the specified
+ shared library is used for archiving. The WAL archiver process is
+ restarted by the postmaster when this parameter changes. For more
+ information, see <a class="xref" href="continuous-archiving.html#BACKUP-ARCHIVING-WAL" title="26.3.1. Setting Up WAL Archiving">Section 26.3.1</a> and
+ <a class="xref" href="archive-modules.html" title="Chapter 51. Archive Modules">Chapter 51</a>.
+ </p><p>
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd><dt id="GUC-ARCHIVE-TIMEOUT"><span class="term"><code class="varname">archive_timeout</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.5.2.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> or <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a> is only invoked for
+ completed WAL segments. Hence, if your server generates little WAL
+ traffic (or has slack periods where it does so), there could be a
+ long delay between the completion of a transaction and its safe
+ recording in archive storage. To limit how old unarchived
+ data can be, you can set <code class="varname">archive_timeout</code> to force the
+ server to switch to a new WAL segment file periodically. When this
+ parameter is greater than zero, the server will switch to a new
+ segment file whenever this amount of time has elapsed since the last
+ segment file switch, and there has been any database activity,
+ including a single checkpoint (checkpoints are skipped if there is
+ no database activity). Note that archived files that are closed
+ early due to a forced switch are still the same length as completely
+ full files. Therefore, it is unwise to use a very short
+ <code class="varname">archive_timeout</code> — it will bloat your archive
+ storage. <code class="varname">archive_timeout</code> settings of a minute or so are
+ usually reasonable. You should consider using streaming replication,
+ instead of archiving, if you want data to be copied off the primary
+ server more quickly than that.
+ If this value is specified without units, it is taken as seconds.
+ This parameter can only be set in the
+ <code class="filename">postgresql.conf</code> file or on the server command line.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-WAL-RECOVERY"><div class="titlepage"><div><div><h3 class="title">20.5.4. Recovery</h3></div></div></div><a id="id-1.6.7.8.6.2" class="indexterm"></a><p>
+ This section describes the settings that apply to recovery in general,
+ affecting crash recovery, streaming replication and archive-based
+ replication.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-RECOVERY-PREFETCH"><span class="term"><code class="varname">recovery_prefetch</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.6.4.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Whether to try to prefetch blocks that are referenced in the WAL that
+ are not yet in the buffer pool, during recovery. Valid values are
+ <code class="literal">off</code>, <code class="literal">on</code> and
+ <code class="literal">try</code> (the default). The setting
+ <code class="literal">try</code> enables
+ prefetching only if the operating system provides the
+ <code class="function">posix_fadvise</code> function, which is currently used
+ to implement prefetching. Note that some operating systems provide the
+ function, but it doesn't do anything.
+ </p><p>
+ Prefetching blocks that will soon be needed can reduce I/O wait times
+ during recovery with some workloads.
+ See also the <a class="xref" href="runtime-config-wal.html#GUC-WAL-DECODE-BUFFER-SIZE">wal_decode_buffer_size</a> and
+ <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-IO-CONCURRENCY">maintenance_io_concurrency</a> settings, which limit
+ prefetching activity.
+ </p></dd><dt id="GUC-WAL-DECODE-BUFFER-SIZE"><span class="term"><code class="varname">wal_decode_buffer_size</code> (<code class="type">integer</code>)
+ <a id="id-1.6.7.8.6.4.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ A limit on how far ahead the server can look in the WAL, to find
+ blocks to prefetch. If this value is specified without units, it is
+ taken as bytes.
+ The default is 512kB.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY"><div class="titlepage"><div><div><h3 class="title">20.5.5. Archive Recovery</h3></div></div></div><a id="id-1.6.7.8.7.2" class="indexterm"></a><p>
+ This section describes the settings that apply only for the duration of
+ the recovery. They must be reset for any subsequent recovery you wish to
+ perform.
+ </p><p>
+ <span class="quote">“<span class="quote">Recovery</span>”</span> covers using the server as a standby or for
+ executing a targeted recovery. Typically, standby mode would be used to
+ provide high availability and/or read scalability, whereas a targeted
+ recovery is used to recover from data loss.
+ </p><p>
+ To start the server in standby mode, create a file called
+ <code class="filename">standby.signal</code><a id="id-1.6.7.8.7.5.2" class="indexterm"></a>
+ in the data directory. The server will enter recovery and will not stop
+ recovery when the end of archived WAL is reached, but will keep trying to
+ continue recovery by connecting to the sending server as specified by the
+ <code class="varname">primary_conninfo</code> setting and/or by fetching new WAL
+ segments using <code class="varname">restore_command</code>. For this mode, the
+ parameters from this section and <a class="xref" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY" title="20.6.3. Standby Servers">Section 20.6.3</a> are of interest.
+ Parameters from <a class="xref" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET" title="20.5.6. Recovery Target">Section 20.5.6</a> will
+ also be applied but are typically not useful in this mode.
+ </p><p>
+ To start the server in targeted recovery mode, create a file called
+ <code class="filename">recovery.signal</code><a id="id-1.6.7.8.7.6.2" class="indexterm"></a>
+ in the data directory. If both <code class="filename">standby.signal</code> and
+ <code class="filename">recovery.signal</code> files are created, standby mode
+ takes precedence. Targeted recovery mode ends when the archived WAL is
+ fully replayed, or when <code class="varname">recovery_target</code> is reached.
+ In this mode, the parameters from both this section and <a class="xref" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET" title="20.5.6. Recovery Target">Section 20.5.6</a> will be used.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-RESTORE-COMMAND"><span class="term"><code class="varname">restore_command</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.7.7.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The local shell command to execute to retrieve an archived segment of
+ the WAL file series. This parameter is required for archive recovery,
+ but optional for streaming replication.
+ Any <code class="literal">%f</code> in the string is
+ replaced by the name of the file to retrieve from the archive,
+ and any <code class="literal">%p</code> is replaced by the copy destination path name
+ on the server.
+ (The path name is relative to the current working directory,
+ i.e., the cluster's data directory.)
+ Any <code class="literal">%r</code> is replaced by the name of the file containing the
+ last valid restart point. That is the earliest file that must be kept
+ to allow a restore to be restartable, so this information can be used
+ to truncate the archive to just the minimum required to support
+ restarting from the current restore. <code class="literal">%r</code> is typically only
+ used by warm-standby configurations
+ (see <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>).
+ Write <code class="literal">%%</code> to embed an actual <code class="literal">%</code> character.
+ </p><p>
+ It is important for the command to return a zero exit status
+ only if it succeeds. The command <span class="emphasis"><em>will</em></span> be asked for file
+ names that are not present in the archive; it must return nonzero
+ when so asked. Examples:
+</p><pre class="programlisting">
+restore_command = 'cp /mnt/server/archivedir/%f "%p"'
+restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
+</pre><p>
+ An exception is that if the command was terminated by a signal (other
+ than <span class="systemitem">SIGTERM</span>, which is used as part of a
+ database server shutdown) or an error by the shell (such as command
+ not found), then recovery will abort and the server will not start up.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-ARCHIVE-CLEANUP-COMMAND"><span class="term"><code class="varname">archive_cleanup_command</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.7.7.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This optional parameter specifies a shell command that will be executed
+ at every restartpoint. The purpose of
+ <code class="varname">archive_cleanup_command</code> is to provide a mechanism for
+ cleaning up old archived WAL files that are no longer needed by the
+ standby server.
+ Any <code class="literal">%r</code> is replaced by the name of the file containing the
+ last valid restart point.
+ That is the earliest file that must be <span class="emphasis"><em>kept</em></span> to allow a
+ restore to be restartable, and so all files earlier than <code class="literal">%r</code>
+ may be safely removed.
+ This information can be used to truncate the archive to just the
+ minimum required to support restart from the current restore.
+ The <a class="xref" href="pgarchivecleanup.html" title="pg_archivecleanup"><span class="refentrytitle"><span class="application">pg_archivecleanup</span></span></a> module
+ is often used in <code class="varname">archive_cleanup_command</code> for
+ single-standby configurations, for example:
+</p><pre class="programlisting">archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r'</pre><p>
+ Note however that if multiple standby servers are restoring from the
+ same archive directory, you will need to ensure that you do not delete
+ WAL files until they are no longer needed by any of the servers.
+ <code class="varname">archive_cleanup_command</code> would typically be used in a
+ warm-standby configuration (see <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>).
+ Write <code class="literal">%%</code> to embed an actual <code class="literal">%</code> character in the
+ command.
+ </p><p>
+ If the command returns a nonzero exit status then a warning log
+ message will be written. An exception is that if the command was
+ terminated by a signal or an error by the shell (such as command not
+ found), a fatal error will be raised.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd><dt id="GUC-RECOVERY-END-COMMAND"><span class="term"><code class="varname">recovery_end_command</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.7.7.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies a shell command that will be executed once only
+ at the end of recovery. This parameter is optional. The purpose of the
+ <code class="varname">recovery_end_command</code> is to provide a mechanism for cleanup
+ following replication or recovery.
+ Any <code class="literal">%r</code> is replaced by the name of the file containing the
+ last valid restart point, like in <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-CLEANUP-COMMAND">archive_cleanup_command</a>.
+ </p><p>
+ If the command returns a nonzero exit status then a warning log
+ message will be written and the database will proceed to start up
+ anyway. An exception is that if the command was terminated by a
+ signal or an error by the shell (such as command not found), the
+ database will not proceed with startup.
+ </p><p>
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p></dd></dl></div></div><div class="sect2" id="RUNTIME-CONFIG-WAL-RECOVERY-TARGET"><div class="titlepage"><div><div><h3 class="title">20.5.6. Recovery Target</h3></div></div></div><p>
+ By default, recovery will recover to the end of the WAL log. The
+ following parameters can be used to specify an earlier stopping point.
+ At most one of <code class="varname">recovery_target</code>,
+ <code class="varname">recovery_target_lsn</code>, <code class="varname">recovery_target_name</code>,
+ <code class="varname">recovery_target_time</code>, or <code class="varname">recovery_target_xid</code>
+ can be used; if more than one of these is specified in the configuration
+ file, an error will be raised.
+ These parameters can only be set at server start.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-RECOVERY-TARGET"><span class="term"><code class="varname">recovery_target</code><code class="literal"> = 'immediate'</code>
+ <a id="id-1.6.7.8.8.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies that recovery should end as soon as a
+ consistent state is reached, i.e., as early as possible. When restoring
+ from an online backup, this means the point where taking the backup
+ ended.
+ </p><p>
+ Technically, this is a string parameter, but <code class="literal">'immediate'</code>
+ is currently the only allowed value.
+ </p></dd><dt id="GUC-RECOVERY-TARGET-NAME"><span class="term"><code class="varname">recovery_target_name</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.8.3.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies the named restore point (created with
+ <code class="function">pg_create_restore_point()</code>) to which recovery will proceed.
+ </p></dd><dt id="GUC-RECOVERY-TARGET-TIME"><span class="term"><code class="varname">recovery_target_time</code> (<code class="type">timestamp</code>)
+ <a id="id-1.6.7.8.8.3.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies the time stamp up to which recovery
+ will proceed.
+ The precise stopping point is also influenced by
+ <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-INCLUSIVE">recovery_target_inclusive</a>.
+ </p><p>
+ The value of this parameter is a time stamp in the same format
+ accepted by the <code class="type">timestamp with time zone</code> data type,
+ except that you cannot use a time zone abbreviation (unless the
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE-ABBREVIATIONS">timezone_abbreviations</a> variable has been set
+ earlier in the configuration file). Preferred style is to use a
+ numeric offset from UTC, or you can write a full time zone name,
+ e.g., <code class="literal">Europe/Helsinki</code> not <code class="literal">EEST</code>.
+ </p></dd><dt id="GUC-RECOVERY-TARGET-XID"><span class="term"><code class="varname">recovery_target_xid</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.8.3.4.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies the transaction ID up to which recovery
+ will proceed. Keep in mind
+ that while transaction IDs are assigned sequentially at transaction
+ start, transactions can complete in a different numeric order.
+ The transactions that will be recovered are those that committed
+ before (and optionally including) the specified one.
+ The precise stopping point is also influenced by
+ <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-INCLUSIVE">recovery_target_inclusive</a>.
+ </p></dd><dt id="GUC-RECOVERY-TARGET-LSN"><span class="term"><code class="varname">recovery_target_lsn</code> (<code class="type">pg_lsn</code>)
+ <a id="id-1.6.7.8.8.3.5.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter specifies the LSN of the write-ahead log location up
+ to which recovery will proceed. The precise stopping point is also
+ influenced by <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-INCLUSIVE">recovery_target_inclusive</a>. This
+ parameter is parsed using the system data type
+ <a class="link" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type"><code class="type">pg_lsn</code></a>.
+ </p></dd></dl></div><p>
+ The following options further specify the recovery target, and affect
+ what happens when the target is reached:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="GUC-RECOVERY-TARGET-INCLUSIVE"><span class="term"><code class="varname">recovery_target_inclusive</code> (<code class="type">boolean</code>)
+ <a id="id-1.6.7.8.8.5.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies whether to stop just after the specified recovery target
+ (<code class="literal">on</code>), or just before the recovery target
+ (<code class="literal">off</code>).
+ Applies when <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-LSN">recovery_target_lsn</a>,
+ <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-TIME">recovery_target_time</a>, or
+ <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-TARGET-XID">recovery_target_xid</a> is specified.
+ This setting controls whether transactions
+ having exactly the target WAL location (LSN), commit time, or transaction ID, respectively, will
+ be included in the recovery. Default is <code class="literal">on</code>.
+ </p></dd><dt id="GUC-RECOVERY-TARGET-TIMELINE"><span class="term"><code class="varname">recovery_target_timeline</code> (<code class="type">string</code>)
+ <a id="id-1.6.7.8.8.5.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies recovering into a particular timeline. The value can be a
+ numeric timeline ID or a special value. The value
+ <code class="literal">current</code> recovers along the same timeline that was
+ current when the base backup was taken. The
+ value <code class="literal">latest</code> recovers
+ to the latest timeline found in the archive, which is useful in
+ a standby server. <code class="literal">latest</code> is the default.
+ </p><p>
+ You usually only need to set this parameter
+ in complex re-recovery situations, where you need to return to
+ a state that itself was reached after a point-in-time recovery.
+ See <a class="xref" href="continuous-archiving.html#BACKUP-TIMELINES" title="26.3.5. Timelines">Section 26.3.5</a> for discussion.
+ </p></dd><dt id="GUC-RECOVERY-TARGET-ACTION"><span class="term"><code class="varname">recovery_target_action</code> (<code class="type">enum</code>)
+ <a id="id-1.6.7.8.8.5.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Specifies what action the server should take once the recovery target is
+ reached. The default is <code class="literal">pause</code>, which means recovery will
+ be paused. <code class="literal">promote</code> means the recovery process will finish
+ and the server will start to accept connections.
+ Finally <code class="literal">shutdown</code> will stop the server after reaching the
+ recovery target.
+ </p><p>
+ The intended use of the <code class="literal">pause</code> setting is to allow queries
+ to be executed against the database to check if this recovery target
+ is the most desirable point for recovery.
+ The paused state can be resumed by
+ using <code class="function">pg_wal_replay_resume()</code> (see
+ <a class="xref" href="functions-admin.html#FUNCTIONS-RECOVERY-CONTROL-TABLE" title="Table 9.91. Recovery Control Functions">Table 9.91</a>), which then
+ causes recovery to end. If this recovery target is not the
+ desired stopping point, then shut down the server, change the
+ recovery target settings to a later target and restart to
+ continue recovery.
+ </p><p>
+ The <code class="literal">shutdown</code> setting is useful to have the instance ready
+ at the exact replay point desired. The instance will still be able to
+ replay more WAL records (and in fact will have to replay WAL records
+ since the last checkpoint next time it is started).
+ </p><p>
+ Note that because <code class="filename">recovery.signal</code> will not be
+ removed when <code class="varname">recovery_target_action</code> is set to <code class="literal">shutdown</code>,
+ any subsequent start will end with immediate shutdown unless the
+ configuration is changed or the <code class="filename">recovery.signal</code>
+ file is removed manually.
+ </p><p>
+ This setting has no effect if no recovery target is set.
+ If <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY">hot_standby</a> is not enabled, a setting of
+ <code class="literal">pause</code> will act the same as <code class="literal">shutdown</code>.
+ If the recovery target is reached while a promotion is ongoing,
+ a setting of <code class="literal">pause</code> will act the same as
+ <code class="literal">promote</code>.
+ </p><p>
+ In any case, if a recovery target is configured but the archive
+ recovery ends before the target is reached, the server will shut down
+ with a fatal error.
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="runtime-config-resource.html" title="20.4. Resource Consumption">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime-config.html" title="Chapter 20. Server Configuration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="runtime-config-replication.html" title="20.6. Replication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">20.4. Resource Consumption </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.6. Replication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime-config.html b/doc/src/sgml/html/runtime-config.html
new file mode 100644
index 0000000..d3ae023
--- /dev/null
+++ b/doc/src/sgml/html/runtime-config.html
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 20. Server Configuration</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="event-log-registration.html" title="19.12. Registering Event Log on Windows" /><link rel="next" href="config-setting.html" title="20.1. Setting Parameters" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 20. Server Configuration</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="event-log-registration.html" title="19.12. Registering Event Log on Windows">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="config-setting.html" title="20.1. Setting Parameters">Next</a></td></tr></table><hr /></div><div class="chapter" id="RUNTIME-CONFIG"><div class="titlepage"><div><div><h2 class="title">Chapter 20. Server Configuration</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="config-setting.html">20.1. Setting Parameters</a></span></dt><dd><dl><dt><span class="sect2"><a href="config-setting.html#CONFIG-SETTING-NAMES-VALUES">20.1.1. Parameter Names and Values</a></span></dt><dt><span class="sect2"><a href="config-setting.html#CONFIG-SETTING-CONFIGURATION-FILE">20.1.2. Parameter Interaction via the Configuration File</a></span></dt><dt><span class="sect2"><a href="config-setting.html#CONFIG-SETTING-SQL-COMMAND-INTERACTION">20.1.3. Parameter Interaction via SQL</a></span></dt><dt><span class="sect2"><a href="config-setting.html#id-1.6.7.4.5">20.1.4. Parameter Interaction via the Shell</a></span></dt><dt><span class="sect2"><a href="config-setting.html#CONFIG-INCLUDES">20.1.5. Managing Configuration File Contents</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-file-locations.html">20.2. File Locations</a></span></dt><dt><span class="sect1"><a href="runtime-config-connection.html">20.3. Connections and Authentication</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SETTINGS">20.3.1. Connection Settings</a></span></dt><dt><span class="sect2"><a href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-AUTHENTICATION">20.3.2. Authentication</a></span></dt><dt><span class="sect2"><a href="runtime-config-connection.html#RUNTIME-CONFIG-CONNECTION-SSL">20.3.3. SSL</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-resource.html">20.4. Resource Consumption</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY">20.4.1. Memory</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK">20.4.2. Disk</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-KERNEL">20.4.3. Kernel Resource Usage</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST">20.4.4. Cost-based Vacuum Delay</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER">20.4.5. Background Writer</a></span></dt><dt><span class="sect2"><a href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR">20.4.6. Asynchronous Behavior</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-wal.html">20.5. Write Ahead Log</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS">20.5.1. Settings</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS">20.5.2. Checkpoints</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVING">20.5.3. Archiving</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY">20.5.4. Recovery</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-ARCHIVE-RECOVERY">20.5.5. Archive Recovery</a></span></dt><dt><span class="sect2"><a href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-RECOVERY-TARGET">20.5.6. Recovery Target</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-replication.html">20.6. Replication</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SENDER">20.6.1. Sending Servers</a></span></dt><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-PRIMARY">20.6.2. Primary Server</a></span></dt><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-STANDBY">20.6.3. Standby Servers</a></span></dt><dt><span class="sect2"><a href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-SUBSCRIBER">20.6.4. Subscribers</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-query.html">20.7. Query Planning</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE">20.7.1. Planner Method Configuration</a></span></dt><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS">20.7.2. Planner Cost Constants</a></span></dt><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-GEQO">20.7.3. Genetic Query Optimizer</a></span></dt><dt><span class="sect2"><a href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-OTHER">20.7.4. Other Planner Options</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-logging.html">20.8. Error Reporting and Logging</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHERE">20.8.1. Where to Log</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN">20.8.2. When to Log</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHAT">20.8.3. What to Log</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-CSVLOG">20.8.4. Using CSV-Format Log Output</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-JSONLOG">20.8.5. Using JSON-Format Log Output</a></span></dt><dt><span class="sect2"><a href="runtime-config-logging.html#id-1.6.7.11.8">20.8.6. Process Title</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-statistics.html">20.9. Run-time Statistics</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-statistics.html#RUNTIME-CONFIG-CUMULATIVE-STATISTICS">20.9.1. Cumulative Query and Index Statistics</a></span></dt><dt><span class="sect2"><a href="runtime-config-statistics.html#RUNTIME-CONFIG-STATISTICS-MONITOR">20.9.2. Statistics Monitoring</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-autovacuum.html">20.10. Automatic Vacuuming</a></span></dt><dt><span class="sect1"><a href="runtime-config-client.html">20.11. Client Connection Defaults</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-STATEMENT">20.11.1. Statement Behavior</a></span></dt><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-FORMAT">20.11.2. Locale and Formatting</a></span></dt><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-PRELOAD">20.11.3. Shared Library Preloading</a></span></dt><dt><span class="sect2"><a href="runtime-config-client.html#RUNTIME-CONFIG-CLIENT-OTHER">20.11.4. Other Defaults</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-locks.html">20.12. Lock Management</a></span></dt><dt><span class="sect1"><a href="runtime-config-compatible.html">20.13. Version and Platform Compatibility</a></span></dt><dd><dl><dt><span class="sect2"><a href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-VERSION">20.13.1. Previous PostgreSQL Versions</a></span></dt><dt><span class="sect2"><a href="runtime-config-compatible.html#RUNTIME-CONFIG-COMPATIBLE-CLIENTS">20.13.2. Platform and Client Compatibility</a></span></dt></dl></dd><dt><span class="sect1"><a href="runtime-config-error-handling.html">20.14. Error Handling</a></span></dt><dt><span class="sect1"><a href="runtime-config-preset.html">20.15. Preset Options</a></span></dt><dt><span class="sect1"><a href="runtime-config-custom.html">20.16. Customized Options</a></span></dt><dt><span class="sect1"><a href="runtime-config-developer.html">20.17. Developer Options</a></span></dt><dt><span class="sect1"><a href="runtime-config-short.html">20.18. Short Options</a></span></dt></dl></div><a id="id-1.6.7.2" class="indexterm"></a><p>
+ There are many configuration parameters that affect the behavior of
+ the database system. In the first section of this chapter we
+ describe how to interact with configuration parameters. The subsequent sections
+ discuss each parameter in detail.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="event-log-registration.html" title="19.12. Registering Event Log on Windows">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="config-setting.html" title="20.1. Setting Parameters">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.12. Registering <span class="application">Event Log</span> on <span class="systemitem">Windows</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 20.1. Setting Parameters</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/runtime.html b/doc/src/sgml/html/runtime.html
new file mode 100644
index 0000000..bb36516
--- /dev/null
+++ b/doc/src/sgml/html/runtime.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 19. Server Setup and Operation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-windows-full.html" title="18.1. Building with Visual C++ or the Microsoft Windows SDK" /><link rel="next" href="postgres-user.html" title="19.1. The PostgreSQL User Account" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 19. Server Setup and Operation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-windows-full.html" title="18.1. Building with Visual C++ or the&#10; Microsoft Windows SDK">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="postgres-user.html" title="19.1. The PostgreSQL User Account">Next</a></td></tr></table><hr /></div><div class="chapter" id="RUNTIME"><div class="titlepage"><div><div><h2 class="title">Chapter 19. Server Setup and Operation</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="postgres-user.html">19.1. The <span class="productname">PostgreSQL</span> User Account</a></span></dt><dt><span class="sect1"><a href="creating-cluster.html">19.2. Creating a Database Cluster</a></span></dt><dd><dl><dt><span class="sect2"><a href="creating-cluster.html#CREATING-CLUSTER-MOUNT-POINTS">19.2.1. Use of Secondary File Systems</a></span></dt><dt><span class="sect2"><a href="creating-cluster.html#CREATING-CLUSTER-FILESYSTEM">19.2.2. File Systems</a></span></dt></dl></dd><dt><span class="sect1"><a href="server-start.html">19.3. Starting the Database Server</a></span></dt><dd><dl><dt><span class="sect2"><a href="server-start.html#SERVER-START-FAILURES">19.3.1. Server Start-up Failures</a></span></dt><dt><span class="sect2"><a href="server-start.html#CLIENT-CONNECTION-PROBLEMS">19.3.2. Client Connection Problems</a></span></dt></dl></dd><dt><span class="sect1"><a href="kernel-resources.html">19.4. Managing Kernel Resources</a></span></dt><dd><dl><dt><span class="sect2"><a href="kernel-resources.html#SYSVIPC">19.4.1. Shared Memory and Semaphores</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#SYSTEMD-REMOVEIPC">19.4.2. systemd RemoveIPC</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#id-1.6.6.7.5">19.4.3. Resource Limits</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#LINUX-MEMORY-OVERCOMMIT">19.4.4. Linux Memory Overcommit</a></span></dt><dt><span class="sect2"><a href="kernel-resources.html#LINUX-HUGE-PAGES">19.4.5. Linux Huge Pages</a></span></dt></dl></dd><dt><span class="sect1"><a href="server-shutdown.html">19.5. Shutting Down the Server</a></span></dt><dt><span class="sect1"><a href="upgrading.html">19.6. Upgrading a <span class="productname">PostgreSQL</span> Cluster</a></span></dt><dd><dl><dt><span class="sect2"><a href="upgrading.html#UPGRADING-VIA-PGDUMPALL">19.6.1. Upgrading Data via <span class="application">pg_dumpall</span></a></span></dt><dt><span class="sect2"><a href="upgrading.html#UPGRADING-VIA-PG-UPGRADE">19.6.2. Upgrading Data via <span class="application">pg_upgrade</span></a></span></dt><dt><span class="sect2"><a href="upgrading.html#UPGRADING-VIA-REPLICATION">19.6.3. Upgrading Data via Replication</a></span></dt></dl></dd><dt><span class="sect1"><a href="preventing-server-spoofing.html">19.7. Preventing Server Spoofing</a></span></dt><dt><span class="sect1"><a href="encryption-options.html">19.8. Encryption Options</a></span></dt><dt><span class="sect1"><a href="ssl-tcp.html">19.9. Secure TCP/IP Connections with SSL</a></span></dt><dd><dl><dt><span class="sect2"><a href="ssl-tcp.html#SSL-SETUP">19.9.1. Basic Setup</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-OPENSSL-CONFIG">19.9.2. OpenSSL Configuration</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-CLIENT-CERTIFICATES">19.9.3. Using Client Certificates</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-SERVER-FILES">19.9.4. SSL Server File Usage</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-CERTIFICATE-CREATION">19.9.5. Creating Certificates</a></span></dt></dl></dd><dt><span class="sect1"><a href="gssapi-enc.html">19.10. Secure TCP/IP Connections with GSSAPI Encryption</a></span></dt><dd><dl><dt><span class="sect2"><a href="gssapi-enc.html#GSSAPI-SETUP">19.10.1. Basic Setup</a></span></dt></dl></dd><dt><span class="sect1"><a href="ssh-tunnels.html">19.11. Secure TCP/IP Connections with <span class="application">SSH</span> Tunnels</a></span></dt><dt><span class="sect1"><a href="event-log-registration.html">19.12. Registering <span class="application">Event Log</span> on <span class="systemitem">Windows</span></a></span></dt></dl></div><p>
+ This chapter discusses how to set up and run the database server,
+ and its interactions with the operating system.
+ </p><p>
+ The directions in this chapter assume that you are working with
+ plain <span class="productname">PostgreSQL</span> without any additional
+ infrastructure, for example a copy that you built from source
+ according to the directions in the preceding chapters.
+ If you are working with a pre-packaged or vendor-supplied
+ version of <span class="productname">PostgreSQL</span>, it is likely that
+ the packager has made special provisions for installing and starting
+ the database server according to your system's conventions.
+ Consult the package-level documentation for details.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-windows-full.html" title="18.1. Building with Visual C++ or the&#10; Microsoft Windows SDK">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="postgres-user.html" title="19.1. The PostgreSQL User Account">Next</a></td></tr><tr><td width="40%" align="left" valign="top">18.1. Building with <span class="productname">Visual C++</span> or the
+ <span class="productname">Microsoft Windows SDK</span> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.1. The <span class="productname">PostgreSQL</span> User Account</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sasl-authentication.html b/doc/src/sgml/html/sasl-authentication.html
new file mode 100644
index 0000000..5790ed6
--- /dev/null
+++ b/doc/src/sgml/html/sasl-authentication.html
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>55.3. SASL Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-flow.html" title="55.2. Message Flow" /><link rel="next" href="protocol-replication.html" title="55.4. Streaming Replication Protocol" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">55.3. SASL Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-flow.html" title="55.2. Message Flow">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><th width="60%" align="center">Chapter 55. Frontend/Backend Protocol</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Next</a></td></tr></table><hr /></div><div class="sect1" id="SASL-AUTHENTICATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">55.3. SASL Authentication</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="sasl-authentication.html#SASL-SCRAM-SHA-256">55.3.1. SCRAM-SHA-256 Authentication</a></span></dt></dl></div><p>
+ <em class="firstterm">SASL</em> is a framework for authentication in connection-oriented
+ protocols. At the moment, <span class="productname">PostgreSQL</span> implements two SASL
+ authentication mechanisms, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. More
+ might be added in the future. The below steps illustrate how SASL
+ authentication is performed in general, while the next subsection gives
+ more details on SCRAM-SHA-256 and SCRAM-SHA-256-PLUS.
+ </p><div class="procedure" id="id-1.10.6.8.3"><p class="title"><strong>SASL Authentication Message Flow</strong></p><ol class="procedure" type="1"><li class="step" id="SASL-AUTH-BEGIN"><p>
+ To begin a SASL authentication exchange, the server sends an
+ AuthenticationSASL message. It includes a list of SASL authentication
+ mechanisms that the server can accept, in the server's preferred order.
+ </p></li><li class="step" id="SASL-AUTH-INITIAL-RESPONSE"><p>
+ The client selects one of the supported mechanisms from the list, and sends
+ a SASLInitialResponse message to the server. The message includes the name
+ of the selected mechanism, and an optional Initial Client Response, if the
+ selected mechanism uses that.
+ </p></li><li class="step" id="SASL-AUTH-CONTINUE"><p>
+ One or more server-challenge and client-response message will follow. Each
+ server-challenge is sent in an AuthenticationSASLContinue message, followed
+ by a response from client in a SASLResponse message. The particulars of
+ the messages are mechanism specific.
+ </p></li><li class="step" id="SASL-AUTH-END"><p>
+ Finally, when the authentication exchange is completed successfully, the
+ server sends an AuthenticationSASLFinal message, followed
+ immediately by an AuthenticationOk message. The AuthenticationSASLFinal
+ contains additional server-to-client data, whose content is particular to the
+ selected authentication mechanism. If the authentication mechanism doesn't
+ use additional data that's sent at completion, the AuthenticationSASLFinal
+ message is not sent.
+ </p></li></ol></div><p>
+ On error, the server can abort the authentication at any stage, and send an
+ ErrorMessage.
+ </p><div class="sect2" id="SASL-SCRAM-SHA-256"><div class="titlepage"><div><div><h3 class="title">55.3.1. SCRAM-SHA-256 Authentication</h3></div></div></div><p>
+ The implemented SASL mechanisms at the moment
+ are <code class="literal">SCRAM-SHA-256</code> and its variant with channel
+ binding <code class="literal">SCRAM-SHA-256-PLUS</code>. They are described in
+ detail in <a class="ulink" href="https://tools.ietf.org/html/rfc7677" target="_top">RFC 7677</a>
+ and <a class="ulink" href="https://tools.ietf.org/html/rfc5802" target="_top">RFC 5802</a>.
+ </p><p>
+ When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the user name
+ that the client sends in the <code class="structname">client-first-message</code>. The user name
+ that was already sent in the startup message is used instead.
+ <span class="productname">PostgreSQL</span> supports multiple character encodings, while SCRAM
+ dictates UTF-8 to be used for the user name, so it might be impossible to
+ represent the PostgreSQL user name in UTF-8.
+ </p><p>
+ The SCRAM specification dictates that the password is also in UTF-8, and is
+ processed with the <em class="firstterm">SASLprep</em> algorithm.
+ <span class="productname">PostgreSQL</span>, however, does not require UTF-8 to be used for
+ the password. When a user's password is set, it is processed with SASLprep
+ as if it was in UTF-8, regardless of the actual encoding used. However, if
+ it is not a legal UTF-8 byte sequence, or it contains UTF-8 byte sequences
+ that are prohibited by the SASLprep algorithm, the raw password will be used
+ without SASLprep processing, instead of throwing an error. This allows the
+ password to be normalized when it is in UTF-8, but still allows a non-UTF-8
+ password to be used, and doesn't require the system to know which encoding
+ the password is in.
+ </p><p>
+ <em class="firstterm">Channel binding</em> is supported in PostgreSQL builds with
+ SSL support. The SASL mechanism name for SCRAM with channel binding is
+ <code class="literal">SCRAM-SHA-256-PLUS</code>. The channel binding type used by
+ PostgreSQL is <code class="literal">tls-server-end-point</code>.
+ </p><p>
+ In <acronym class="acronym">SCRAM</acronym> without channel binding, the server chooses
+ a random number that is transmitted to the client to be mixed with the
+ user-supplied password in the transmitted password hash. While this
+ prevents the password hash from being successfully retransmitted in
+ a later session, it does not prevent a fake server between the real
+ server and client from passing through the server's random value
+ and successfully authenticating.
+ </p><p>
+ <acronym class="acronym">SCRAM</acronym> with channel binding prevents such
+ man-in-the-middle attacks by mixing the signature of the server's
+ certificate into the transmitted password hash. While a fake server can
+ retransmit the real server's certificate, it doesn't have access to the
+ private key matching that certificate, and therefore cannot prove it is
+ the owner, causing SSL connection failure.
+ </p><div class="procedure" id="id-1.10.6.8.5.8"><p class="title"><strong>Example</strong></p><ol class="procedure" type="1"><li class="step" id="SCRAM-BEGIN"><p>
+ The server sends an AuthenticationSASL message. It includes a list of
+ SASL authentication mechanisms that the server can accept.
+ This will be <code class="literal">SCRAM-SHA-256-PLUS</code>
+ and <code class="literal">SCRAM-SHA-256</code> if the server is built with SSL
+ support, or else just the latter.
+ </p></li><li class="step" id="SCRAM-CLIENT-FIRST"><p>
+ The client responds by sending a SASLInitialResponse message, which
+ indicates the chosen mechanism, <code class="literal">SCRAM-SHA-256</code> or
+ <code class="literal">SCRAM-SHA-256-PLUS</code>. (A client is free to choose either
+ mechanism, but for better security it should choose the channel-binding
+ variant if it can support it.) In the Initial Client response field, the
+ message contains the SCRAM <code class="structname">client-first-message</code>.
+ The <code class="structname">client-first-message</code> also contains the channel
+ binding type chosen by the client.
+ </p></li><li class="step" id="SCRAM-SERVER-FIRST"><p>
+ Server sends an AuthenticationSASLContinue message, with a SCRAM
+ <code class="structname">server-first-message</code> as the content.
+ </p></li><li class="step" id="SCRAM-CLIENT-FINAL"><p>
+ Client sends a SASLResponse message, with SCRAM
+ <code class="structname">client-final-message</code> as the content.
+ </p></li><li class="step" id="SCRAM-SERVER-FINAL"><p>
+ Server sends an AuthenticationSASLFinal message, with the SCRAM
+ <code class="structname">server-final-message</code>, followed immediately by
+ an AuthenticationOk message.
+ </p></li></ol></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-flow.html" title="55.2. Message Flow">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.2. Message Flow </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 55.4. Streaming Replication Protocol</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/seg.html b/doc/src/sgml/html/seg.html
new file mode 100644
index 0000000..3572641
--- /dev/null
+++ b/doc/src/sgml/html/seg.html
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.39. seg</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="postgres-fdw.html" title="F.38. postgres_fdw" /><link rel="next" href="sepgsql.html" title="F.40. sepgsql" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.39. seg</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="postgres-fdw.html" title="F.38. postgres_fdw">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sepgsql.html" title="F.40. sepgsql">Next</a></td></tr></table><hr /></div><div class="sect1" id="SEG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.39. seg</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.5">F.39.1. Rationale</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.6">F.39.2. Syntax</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.7">F.39.3. Precision</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.8">F.39.4. Usage</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.9">F.39.5. Notes</a></span></dt><dt><span class="sect2"><a href="seg.html#id-1.11.7.48.10">F.39.6. Credits</a></span></dt></dl></div><a id="id-1.11.7.48.2" class="indexterm"></a><p>
+ This module implements a data type <code class="type">seg</code> for
+ representing line segments, or floating point intervals.
+ <code class="type">seg</code> can represent uncertainty in the interval endpoints,
+ making it especially useful for representing laboratory measurements.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.48.5"><div class="titlepage"><div><div><h3 class="title">F.39.1. Rationale</h3></div></div></div><p>
+ The geometry of measurements is usually more complex than that of a
+ point in a numeric continuum. A measurement is usually a segment of
+ that continuum with somewhat fuzzy limits. The measurements come out
+ as intervals because of uncertainty and randomness, as well as because
+ the value being measured may naturally be an interval indicating some
+ condition, such as the temperature range of stability of a protein.
+ </p><p>
+ Using just common sense, it appears more convenient to store such data
+ as intervals, rather than pairs of numbers. In practice, it even turns
+ out more efficient in most applications.
+ </p><p>
+ Further along the line of common sense, the fuzziness of the limits
+ suggests that the use of traditional numeric data types leads to a
+ certain loss of information. Consider this: your instrument reads
+ 6.50, and you input this reading into the database. What do you get
+ when you fetch it? Watch:
+
+</p><pre class="screen">
+test=&gt; select 6.50 :: float8 as "pH";
+ pH
+---
+6.5
+(1 row)
+</pre><p>
+
+ In the world of measurements, 6.50 is not the same as 6.5. It may
+ sometimes be critically different. The experimenters usually write
+ down (and publish) the digits they trust. 6.50 is actually a fuzzy
+ interval contained within a bigger and even fuzzier interval, 6.5,
+ with their center points being (probably) the only common feature they
+ share. We definitely do not want such different data items to appear the
+ same.
+ </p><p>
+ Conclusion? It is nice to have a special data type that can record the
+ limits of an interval with arbitrarily variable precision. Variable in
+ the sense that each data element records its own precision.
+ </p><p>
+ Check this out:
+
+</p><pre class="screen">
+test=&gt; select '6.25 .. 6.50'::seg as "pH";
+ pH
+------------
+6.25 .. 6.50
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.7.48.6"><div class="titlepage"><div><div><h3 class="title">F.39.2. Syntax</h3></div></div></div><p>
+ The external representation of an interval is formed using one or two
+ floating-point numbers joined by the range operator (<code class="literal">..</code>
+ or <code class="literal">...</code>). Alternatively, it can be specified as a
+ center point plus or minus a deviation.
+ Optional certainty indicators (<code class="literal">&lt;</code>,
+ <code class="literal">&gt;</code> or <code class="literal">~</code>) can be stored as well.
+ (Certainty indicators are ignored by all the built-in operators, however.)
+ <a class="xref" href="seg.html#SEG-REPR-TABLE" title="Table F.26. seg External Representations">Table F.26</a> gives an overview of allowed
+ representations; <a class="xref" href="seg.html#SEG-INPUT-EXAMPLES" title="Table F.27. Examples of Valid seg Input">Table F.27</a> shows some
+ examples.
+ </p><p>
+ In <a class="xref" href="seg.html#SEG-REPR-TABLE" title="Table F.26. seg External Representations">Table F.26</a>, <em class="replaceable"><code>x</code></em>, <em class="replaceable"><code>y</code></em>, and
+ <em class="replaceable"><code>delta</code></em> denote
+ floating-point numbers. <em class="replaceable"><code>x</code></em> and <em class="replaceable"><code>y</code></em>, but
+ not <em class="replaceable"><code>delta</code></em>, can be preceded by a certainty indicator.
+ </p><div class="table" id="SEG-REPR-TABLE"><p class="title"><strong>Table F.26. <code class="type">seg</code> External Representations</strong></p><div class="table-contents"><table class="table" summary="seg External Representations" border="1"><colgroup><col /><col /></colgroup><tbody><tr><td><code class="literal"><em class="replaceable"><code>x</code></em></code></td><td>Single value (zero-length interval)
+ </td></tr><tr><td><code class="literal"><em class="replaceable"><code>x</code></em> .. <em class="replaceable"><code>y</code></em></code></td><td>Interval from <em class="replaceable"><code>x</code></em> to <em class="replaceable"><code>y</code></em>
+ </td></tr><tr><td><code class="literal"><em class="replaceable"><code>x</code></em> (+-) <em class="replaceable"><code>delta</code></em></code></td><td>Interval from <em class="replaceable"><code>x</code></em> - <em class="replaceable"><code>delta</code></em> to
+ <em class="replaceable"><code>x</code></em> + <em class="replaceable"><code>delta</code></em>
+ </td></tr><tr><td><code class="literal"><em class="replaceable"><code>x</code></em> ..</code></td><td>Open interval with lower bound <em class="replaceable"><code>x</code></em>
+ </td></tr><tr><td><code class="literal">.. <em class="replaceable"><code>x</code></em></code></td><td>Open interval with upper bound <em class="replaceable"><code>x</code></em>
+ </td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="SEG-INPUT-EXAMPLES"><p class="title"><strong>Table F.27. Examples of Valid <code class="type">seg</code> Input</strong></p><div class="table-contents"><table class="table" summary="Examples of Valid seg Input" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><tbody><tr><td><code class="literal">5.0</code></td><td>
+ Creates a zero-length segment (a point, if you will)
+ </td></tr><tr><td><code class="literal">~5.0</code></td><td>
+ Creates a zero-length segment and records
+ <code class="literal">~</code> in the data. <code class="literal">~</code> is ignored
+ by <code class="type">seg</code> operations, but
+ is preserved as a comment.
+ </td></tr><tr><td><code class="literal">&lt;5.0</code></td><td>
+ Creates a point at 5.0. <code class="literal">&lt;</code> is ignored but
+ is preserved as a comment.
+ </td></tr><tr><td><code class="literal">&gt;5.0</code></td><td>
+ Creates a point at 5.0. <code class="literal">&gt;</code> is ignored but
+ is preserved as a comment.
+ </td></tr><tr><td><code class="literal">5(+-)0.3</code></td><td>
+ Creates an interval <code class="literal">4.7 .. 5.3</code>.
+ Note that the <code class="literal">(+-)</code> notation isn't preserved.
+ </td></tr><tr><td><code class="literal">50 .. </code></td><td>Everything that is greater than or equal to 50</td></tr><tr><td><code class="literal">.. 0</code></td><td>Everything that is less than or equal to 0</td></tr><tr><td><code class="literal">1.5e-2 .. 2E-2 </code></td><td>Creates an interval <code class="literal">0.015 .. 0.02</code></td></tr><tr><td><code class="literal">1 ... 2</code></td><td>
+ The same as <code class="literal">1...2</code>, or <code class="literal">1 .. 2</code>,
+ or <code class="literal">1..2</code>
+ (spaces around the range operator are ignored)
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Because the <code class="literal">...</code> operator is widely used in data sources, it is allowed
+ as an alternative spelling of the <code class="literal">..</code> operator. Unfortunately, this
+ creates a parsing ambiguity: it is not clear whether the upper bound
+ in <code class="literal">0...23</code> is meant to be <code class="literal">23</code> or <code class="literal">0.23</code>.
+ This is resolved by requiring at least one digit before the decimal
+ point in all numbers in <code class="type">seg</code> input.
+ </p><p>
+ As a sanity check, <code class="type">seg</code> rejects intervals with the lower bound
+ greater than the upper, for example <code class="literal">5 .. 2</code>.
+ </p></div><div class="sect2" id="id-1.11.7.48.7"><div class="titlepage"><div><div><h3 class="title">F.39.3. Precision</h3></div></div></div><p>
+ <code class="type">seg</code> values are stored internally as pairs of 32-bit floating point
+ numbers. This means that numbers with more than 7 significant digits
+ will be truncated.
+ </p><p>
+ Numbers with 7 or fewer significant digits retain their
+ original precision. That is, if your query returns 0.00, you will be
+ sure that the trailing zeroes are not the artifacts of formatting: they
+ reflect the precision of the original data. The number of leading
+ zeroes does not affect precision: the value 0.0067 is considered to
+ have just 2 significant digits.
+ </p></div><div class="sect2" id="id-1.11.7.48.8"><div class="titlepage"><div><div><h3 class="title">F.39.4. Usage</h3></div></div></div><p>
+ The <code class="filename">seg</code> module includes a GiST index operator class for
+ <code class="type">seg</code> values.
+ The operators supported by the GiST operator class are shown in <a class="xref" href="seg.html#SEG-GIST-OPERATORS" title="Table F.28. Seg GiST Operators">Table F.28</a>.
+ </p><div class="table" id="SEG-GIST-OPERATORS"><p class="title"><strong>Table F.28. Seg GiST Operators</strong></p><div class="table-contents"><table class="table" summary="Seg GiST Operators" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Operator
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">&lt;&lt;</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first <code class="type">seg</code> entirely to the left of the second?
+ [a, b] &lt;&lt; [c, d] is true if b &lt; c.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">&gt;&gt;</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first <code class="type">seg</code> entirely to the right of the second?
+ [a, b] &gt;&gt; [c, d] is true if a &gt; d.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">&amp;&lt;</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first <code class="type">seg</code> not extend to the right of the
+ second?
+ [a, b] &amp;&lt; [c, d] is true if b &lt;= d.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">&amp;&gt;</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first <code class="type">seg</code> not extend to the left of the
+ second?
+ [a, b] &amp;&gt; [c, d] is true if a &gt;= c.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">=</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Are the two <code class="type">seg</code>s equal?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">&amp;&amp;</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Do the two <code class="type">seg</code>s overlap?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">@&gt;</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Does the first <code class="type">seg</code> contain the second?
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="type">seg</code> <code class="literal">&lt;@</code> <code class="type">seg</code>
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Is the first <code class="type">seg</code> contained in the second?
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In addition to the above operators, the usual comparison
+ operators shown in <a class="xref" href="functions-comparison.html#FUNCTIONS-COMPARISON-OP-TABLE" title="Table 9.1. Comparison Operators">Table 9.1</a> are
+ available for type <code class="type">seg</code>. These operators
+ first compare (a) to (c),
+ and if these are equal, compare (b) to (d). That results in
+ reasonably good sorting in most cases, which is useful if
+ you want to use ORDER BY with this type.
+ </p></div><div class="sect2" id="id-1.11.7.48.9"><div class="titlepage"><div><div><h3 class="title">F.39.5. Notes</h3></div></div></div><p>
+ For examples of usage, see the regression test <code class="filename">sql/seg.sql</code>.
+ </p><p>
+ The mechanism that converts <code class="literal">(+-)</code> to regular ranges
+ isn't completely accurate in determining the number of significant digits
+ for the boundaries. For example, it adds an extra digit to the lower
+ boundary if the resulting interval includes a power of ten:
+
+</p><pre class="screen">
+postgres=&gt; select '10(+-)1'::seg as seg;
+ seg
+---------
+9.0 .. 11 -- should be: 9 .. 11
+</pre><p>
+ </p><p>
+ The performance of an R-tree index can largely depend on the initial
+ order of input values. It may be very helpful to sort the input table
+ on the <code class="type">seg</code> column; see the script <code class="filename">sort-segments.pl</code>
+ for an example.
+ </p></div><div class="sect2" id="id-1.11.7.48.10"><div class="titlepage"><div><div><h3 class="title">F.39.6. Credits</h3></div></div></div><p>
+ Original author: Gene Selkov, Jr. <code class="email">&lt;<a class="email" href="mailto:selkovjr@mcs.anl.gov">selkovjr@mcs.anl.gov</a>&gt;</code>,
+ Mathematics and Computer Science Division, Argonne National Laboratory.
+ </p><p>
+ My thanks are primarily to Prof. Joe Hellerstein
+ (<a class="ulink" href="https://dsf.berkeley.edu/jmh/" target="_top">https://dsf.berkeley.edu/jmh/</a>) for elucidating the
+ gist of the GiST (<a class="ulink" href="http://gist.cs.berkeley.edu/" target="_top">http://gist.cs.berkeley.edu/</a>). I am
+ also grateful to all Postgres developers, present and past, for enabling
+ myself to create my own world and live undisturbed in it. And I would like
+ to acknowledge my gratitude to Argonne Lab and to the U.S. Department of
+ Energy for the years of faithful support of my database research.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="postgres-fdw.html" title="F.38. postgres_fdw">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sepgsql.html" title="F.40. sepgsql">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.38. postgres_fdw </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.40. sepgsql</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sepgsql.html b/doc/src/sgml/html/sepgsql.html
new file mode 100644
index 0000000..11f619c
--- /dev/null
+++ b/doc/src/sgml/html/sepgsql.html
@@ -0,0 +1,520 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.40. sepgsql</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="seg.html" title="F.39. seg" /><link rel="next" href="contrib-spi.html" title="F.41. spi" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.40. sepgsql</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="seg.html" title="F.39. seg">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-spi.html" title="F.41. spi">Next</a></td></tr></table><hr /></div><div class="sect1" id="SEPGSQL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.40. sepgsql</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-OVERVIEW">F.40.1. Overview</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-INSTALLATION">F.40.2. Installation</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-REGRESSION">F.40.3. Regression Tests</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-PARAMETERS">F.40.4. GUC Parameters</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-FEATURES">F.40.5. Features</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-FUNCTIONS">F.40.6. Sepgsql Functions</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-LIMITATIONS">F.40.7. Limitations</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-RESOURCES">F.40.8. External Resources</a></span></dt><dt><span class="sect2"><a href="sepgsql.html#SEPGSQL-AUTHOR">F.40.9. Author</a></span></dt></dl></div><a id="id-1.11.7.49.2" class="indexterm"></a><p>
+ <code class="filename">sepgsql</code> is a loadable module that supports label-based
+ mandatory access control (MAC) based on <span class="productname">SELinux</span> security
+ policy.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ The current implementation has significant limitations, and does not
+ enforce mandatory access control for all actions. See
+ <a class="xref" href="sepgsql.html#SEPGSQL-LIMITATIONS" title="F.40.7. Limitations">Section F.40.7</a>.
+ </p></div><div class="sect2" id="SEPGSQL-OVERVIEW"><div class="titlepage"><div><div><h3 class="title">F.40.1. Overview</h3></div></div></div><p>
+ This module integrates with <span class="productname">SELinux</span> to provide an
+ additional layer of security checking above and beyond what is normally
+ provided by <span class="productname">PostgreSQL</span>. From the perspective of
+ <span class="productname">SELinux</span>, this module allows
+ <span class="productname">PostgreSQL</span> to function as a user-space object
+ manager. Each table or function access initiated by a DML query will be
+ checked against the system security policy. This check is in addition to
+ the usual SQL permissions checking performed by
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ <span class="productname">SELinux</span> access control decisions are made using
+ security labels, which are represented by strings such as
+ <code class="literal">system_u:object_r:sepgsql_table_t:s0</code>. Each access control
+ decision involves two labels: the label of the subject attempting to
+ perform the action, and the label of the object on which the operation is
+ to be performed. Since these labels can be applied to any sort of object,
+ access control decisions for objects stored within the database can be
+ (and, with this module, are) subjected to the same general criteria used
+ for objects of any other type, such as files. This design is intended to
+ allow a centralized security policy to protect information assets
+ independent of the particulars of how those assets are stored.
+ </p><p>
+ The <a class="link" href="sql-security-label.html" title="SECURITY LABEL"><code class="command">SECURITY LABEL</code></a> statement allows assignment of
+ a security label to a database object.
+ </p></div><div class="sect2" id="SEPGSQL-INSTALLATION"><div class="titlepage"><div><div><h3 class="title">F.40.2. Installation</h3></div></div></div><p>
+ <code class="filename">sepgsql</code> can only be used on <span class="productname">Linux</span>
+ 2.6.28 or higher with <span class="productname">SELinux</span> enabled.
+ It is not available on any other platform. You will also need
+ <span class="productname">libselinux</span> 2.1.10 or higher and
+ <span class="productname">selinux-policy</span> 3.9.13 or higher (although some
+ distributions may backport the necessary rules into older policy
+ versions).
+ </p><p>
+ The <code class="command">sestatus</code> command allows you to check the status of
+ <span class="productname">SELinux</span>. A typical display is:
+</p><pre class="screen">
+$ sestatus
+SELinux status: enabled
+SELinuxfs mount: /selinux
+Current mode: enforcing
+Mode from config file: enforcing
+Policy version: 24
+Policy from config file: targeted
+</pre><p>
+ If <span class="productname">SELinux</span> is disabled or not installed, you must set
+ that product up first before installing this module.
+ </p><p>
+ To build this module, include the option <code class="literal">--with-selinux</code> in
+ your PostgreSQL <code class="literal">configure</code> command. Be sure that the
+ <code class="filename">libselinux-devel</code> RPM is installed at build time.
+ </p><p>
+ To use this module, you must include <code class="literal">sepgsql</code>
+ in the <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a> parameter in
+ <code class="filename">postgresql.conf</code>. The module will not function correctly
+ if loaded in any other manner. Once the module is loaded, you
+ should execute <code class="filename">sepgsql.sql</code> in each database.
+ This will install functions needed for security label management, and
+ assign initial security labels.
+ </p><p>
+ Here is an example showing how to initialize a fresh database cluster
+ with <code class="filename">sepgsql</code> functions and security labels installed.
+ Adjust the paths shown as appropriate for your installation:
+ </p><pre class="screen">
+$ export PGDATA=/path/to/data/directory
+$ initdb
+$ vi $PGDATA/postgresql.conf
+ change
+ #shared_preload_libraries = '' # (change requires restart)
+ to
+ shared_preload_libraries = 'sepgsql' # (change requires restart)
+$ for DBNAME in template0 template1 postgres; do
+ postgres --single -F -c exit_on_error=true $DBNAME \
+ &lt;/usr/local/pgsql/share/contrib/sepgsql.sql &gt;/dev/null
+ done
+</pre><p>
+ Please note that you may see some or all of the following notifications
+ depending on the particular versions you have of
+ <span class="productname">libselinux</span> and <span class="productname">selinux-policy</span>:
+</p><pre class="screen">
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 33 has invalid object type db_blobs
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 36 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 37 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 38 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 39 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 40 has invalid object type db_language
+</pre><p>
+ These messages are harmless and should be ignored.
+ </p><p>
+ If the installation process completes without error, you can now start the
+ server normally.
+ </p></div><div class="sect2" id="SEPGSQL-REGRESSION"><div class="titlepage"><div><div><h3 class="title">F.40.3. Regression Tests</h3></div></div></div><p>
+ Due to the nature of <span class="productname">SELinux</span>, running the
+ regression tests for <code class="filename">sepgsql</code> requires several extra
+ configuration steps, some of which must be done as root.
+ The regression tests will not be run by an ordinary
+ <code class="literal">make check</code> or <code class="literal">make installcheck</code> command; you must
+ set up the configuration and then invoke the test script manually.
+ The tests must be run in the <code class="filename">contrib/sepgsql</code> directory
+ of a configured PostgreSQL build tree. Although they require a build tree,
+ the tests are designed to be executed against an installed server,
+ that is they are comparable to <code class="literal">make installcheck</code> not
+ <code class="literal">make check</code>.
+ </p><p>
+ First, set up <code class="filename">sepgsql</code> in a working database
+ according to the instructions in <a class="xref" href="sepgsql.html#SEPGSQL-INSTALLATION" title="F.40.2. Installation">Section F.40.2</a>.
+ Note that the current operating system user must be able to connect to the
+ database as superuser without password authentication.
+ </p><p>
+ Second, build and install the policy package for the regression test.
+ The <code class="filename">sepgsql-regtest</code> policy is a special purpose policy package
+ which provides a set of rules to be allowed during the regression tests.
+ It should be built from the policy source file
+ <code class="filename">sepgsql-regtest.te</code>, which is done using
+ <code class="command">make</code> with a Makefile supplied by SELinux.
+ You will need to locate the appropriate
+ Makefile on your system; the path shown below is only an example.
+ (This Makefile is usually supplied by the
+ <code class="filename">selinux-policy-devel</code> or
+ <code class="filename">selinux-policy</code> RPM.)
+ Once built, install this policy package using the
+ <code class="command">semodule</code> command, which loads supplied policy packages
+ into the kernel. If the package is correctly installed,
+ <code class="literal"><code class="command">semodule</code> -l</code> should list <code class="literal">sepgsql-regtest</code> as an
+ available policy package:
+ </p><pre class="screen">
+$ cd .../contrib/sepgsql
+$ make -f /usr/share/selinux/devel/Makefile
+$ sudo semodule -u sepgsql-regtest.pp
+$ sudo semodule -l | grep sepgsql
+sepgsql-regtest 1.07
+</pre><p>
+ Third, turn on <code class="literal">sepgsql_regression_test_mode</code>.
+ For security reasons, the rules in <code class="filename">sepgsql-regtest</code>
+ are not enabled by default;
+ the <code class="literal">sepgsql_regression_test_mode</code> parameter enables
+ the rules needed to launch the regression tests.
+ It can be turned on using the <code class="command">setsebool</code> command:
+ </p><pre class="screen">
+$ sudo setsebool sepgsql_regression_test_mode on
+$ getsebool sepgsql_regression_test_mode
+sepgsql_regression_test_mode --&gt; on
+</pre><p>
+ Fourth, verify your shell is operating in the <code class="literal">unconfined_t</code>
+ domain:
+ </p><pre class="screen">
+$ id -Z
+unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+</pre><p>
+ See <a class="xref" href="sepgsql.html#SEPGSQL-RESOURCES" title="F.40.8. External Resources">Section F.40.8</a> for details on adjusting your
+ working domain, if necessary.
+ </p><p>
+ Finally, run the regression test script:
+ </p><pre class="screen">
+$ ./test_sepgsql
+</pre><p>
+ This script will attempt to verify that you have done all the configuration
+ steps correctly, and then it will run the regression tests for the
+ <code class="filename">sepgsql</code> module.
+ </p><p>
+ After completing the tests, it's recommended you disable
+ the <code class="literal">sepgsql_regression_test_mode</code> parameter:
+ </p><pre class="screen">
+$ sudo setsebool sepgsql_regression_test_mode off
+</pre><p>
+ You might prefer to remove the <code class="filename">sepgsql-regtest</code> policy
+ entirely:
+ </p><pre class="screen">
+$ sudo semodule -r sepgsql-regtest
+</pre></div><div class="sect2" id="SEPGSQL-PARAMETERS"><div class="titlepage"><div><div><h3 class="title">F.40.4. GUC Parameters</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt id="GUC-SEPGSQL-PERMISSIVE"><span class="term">
+ <code class="varname">sepgsql.permissive</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.49.8.2.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter enables <code class="filename">sepgsql</code> to function
+ in permissive mode, regardless of the system setting.
+ The default is off.
+ This parameter can only be set in the <code class="filename">postgresql.conf</code>
+ file or on the server command line.
+ </p><p>
+ When this parameter is on, <code class="filename">sepgsql</code> functions
+ in permissive mode, even if SELinux in general is working in enforcing
+ mode. This parameter is primarily useful for testing purposes.
+ </p></dd><dt id="GUC-SEPGSQL-DEBUG-AUDIT"><span class="term">
+ <code class="varname">sepgsql.debug_audit</code> (<code class="type">boolean</code>)
+ <a id="id-1.11.7.49.8.2.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This parameter enables the printing of audit messages regardless of
+ the system policy settings.
+ The default is off, which means that messages will be printed according
+ to the system settings.
+ </p><p>
+ The security policy of <span class="productname">SELinux</span> also has rules to
+ control whether or not particular accesses are logged.
+ By default, access violations are logged, but allowed
+ accesses are not.
+ </p><p>
+ This parameter forces all possible logging to be turned on, regardless
+ of the system policy.
+ </p></dd></dl></div></div><div class="sect2" id="SEPGSQL-FEATURES"><div class="titlepage"><div><div><h3 class="title">F.40.5. Features</h3></div></div></div><div class="sect3" id="id-1.11.7.49.9.2"><div class="titlepage"><div><div><h4 class="title">F.40.5.1. Controlled Object Classes</h4></div></div></div><p>
+ The security model of <span class="productname">SELinux</span> describes all the access
+ control rules as relationships between a subject entity (typically,
+ a client of the database) and an object entity (such as a database
+ object), each of which is
+ identified by a security label. If access to an unlabeled object is
+ attempted, the object is treated as if it were assigned the label
+ <code class="literal">unlabeled_t</code>.
+ </p><p>
+ Currently, <code class="filename">sepgsql</code> allows security labels to be
+ assigned to schemas, tables, columns, sequences, views, and functions.
+ When <code class="filename">sepgsql</code> is in use, security labels are
+ automatically assigned to supported database objects at creation time.
+ This label is called a default security label, and is decided according
+ to the system security policy, which takes as input the creator's label,
+ the label assigned to the new object's parent object and optionally name
+ of the constructed object.
+ </p><p>
+ A new database object basically inherits the security label of the parent
+ object, except when the security policy has special rules known as
+ type-transition rules, in which case a different label may be applied.
+ For schemas, the parent object is the current database; for tables,
+ sequences, views, and functions, it is the containing schema; for columns,
+ it is the containing table.
+ </p></div><div class="sect3" id="id-1.11.7.49.9.3"><div class="titlepage"><div><div><h4 class="title">F.40.5.2. DML Permissions</h4></div></div></div><p>
+ For tables, <code class="literal">db_table:select</code>, <code class="literal">db_table:insert</code>,
+ <code class="literal">db_table:update</code> or <code class="literal">db_table:delete</code> are
+ checked for all the referenced target tables depending on the kind of
+ statement; in addition, <code class="literal">db_table:select</code> is also checked for
+ all the tables that contain columns referenced in the
+ <code class="literal">WHERE</code> or <code class="literal">RETURNING</code> clause, as a data source
+ for <code class="literal">UPDATE</code>, and so on.
+ </p><p>
+ Column-level permissions will also be checked for each referenced column.
+ <code class="literal">db_column:select</code> is checked on not only the columns being
+ read using <code class="literal">SELECT</code>, but those being referenced in other DML
+ statements; <code class="literal">db_column:update</code> or <code class="literal">db_column:insert</code>
+ will also be checked for columns being modified by <code class="literal">UPDATE</code> or
+ <code class="literal">INSERT</code>.
+ </p><p>
+ For example, consider:
+</p><pre class="synopsis">
+UPDATE t1 SET x = 2, y = func1(y) WHERE z = 100;
+</pre><p>
+
+ Here, <code class="literal">db_column:update</code> will be checked for
+ <code class="literal">t1.x</code>, since it is being updated,
+ <code class="literal">db_column:{select update}</code> will be checked for
+ <code class="literal">t1.y</code>, since it is both updated and referenced, and
+ <code class="literal">db_column:select</code> will be checked for <code class="literal">t1.z</code>, since
+ it is only referenced.
+ <code class="literal">db_table:{select update}</code> will also be checked
+ at the table level.
+ </p><p>
+ For sequences, <code class="literal">db_sequence:get_value</code> is checked when we
+ reference a sequence object using <code class="literal">SELECT</code>; however, note that we
+ do not currently check permissions on execution of corresponding functions
+ such as <code class="literal">lastval()</code>.
+ </p><p>
+ For views, <code class="literal">db_view:expand</code> will be checked, then any other
+ required permissions will be checked on the objects being
+ expanded from the view, individually.
+ </p><p>
+ For functions, <code class="literal">db_procedure:{execute}</code> will be checked when
+ user tries to execute a function as a part of query, or using fast-path
+ invocation. If this function is a trusted procedure, it also checks
+ <code class="literal">db_procedure:{entrypoint}</code> permission to check whether it
+ can perform as entry point of trusted procedure.
+ </p><p>
+ In order to access any schema object, <code class="literal">db_schema:search</code>
+ permission is required on the containing schema. When an object is
+ referenced without schema qualification, schemas on which this
+ permission is not present will not be searched (just as if the user did
+ not have <code class="literal">USAGE</code> privilege on the schema). If an explicit schema
+ qualification is present, an error will occur if the user does not have
+ the requisite permission on the named schema.
+ </p><p>
+ The client must be allowed to access all referenced tables and
+ columns, even if they originated from views which were then expanded,
+ so that we apply consistent access control rules independent of the manner
+ in which the table contents are referenced.
+ </p><p>
+ The default database privilege system allows database superusers to
+ modify system catalogs using DML commands, and reference or modify
+ toast tables. These operations are prohibited when
+ <code class="filename">sepgsql</code> is enabled.
+ </p></div><div class="sect3" id="id-1.11.7.49.9.4"><div class="titlepage"><div><div><h4 class="title">F.40.5.3. DDL Permissions</h4></div></div></div><p>
+ <span class="productname">SELinux</span> defines several permissions to control common
+ operations for each object type; such as creation, alter, drop and
+ relabel of security label. In addition, several object types have
+ special permissions to control their characteristic operations; such as
+ addition or deletion of name entries within a particular schema.
+ </p><p>
+ Creating a new database object requires <code class="literal">create</code> permission.
+ <span class="productname">SELinux</span> will grant or deny this permission based on the
+ client's security label and the proposed security label for the new
+ object. In some cases, additional privileges are required:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="link" href="sql-createdatabase.html" title="CREATE DATABASE"><code class="command">CREATE DATABASE</code></a> additionally requires
+ <code class="literal">getattr</code> permission for the source or template database.
+ </p></li><li class="listitem"><p>
+ Creating a schema object additionally requires <code class="literal">add_name</code>
+ permission on the parent schema.
+ </p></li><li class="listitem"><p>
+ Creating a table additionally requires permission to create each
+ individual table column, just as if each table column were a
+ separate top-level object.
+ </p></li><li class="listitem"><p>
+ Creating a function marked as <code class="literal">LEAKPROOF</code> additionally
+ requires <code class="literal">install</code> permission. (This permission is also
+ checked when <code class="literal">LEAKPROOF</code> is set for an existing function.)
+ </p></li></ul></div><p>
+ When <code class="literal">DROP</code> command is executed, <code class="literal">drop</code> will be
+ checked on the object being removed. Permissions will be also checked for
+ objects dropped indirectly via <code class="literal">CASCADE</code>. Deletion of objects
+ contained within a particular schema (tables, views, sequences and
+ procedures) additionally requires <code class="literal">remove_name</code> on the schema.
+ </p><p>
+ When <code class="literal">ALTER</code> command is executed, <code class="literal">setattr</code> will be
+ checked on the object being modified for each object types, except for
+ subsidiary objects such as the indexes or triggers of a table, where
+ permissions are instead checked on the parent object. In some cases,
+ additional permissions are required:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Moving an object to a new schema additionally requires
+ <code class="literal">remove_name</code> permission on the old schema and
+ <code class="literal">add_name</code> permission on the new one.
+ </p></li><li class="listitem"><p>
+ Setting the <code class="literal">LEAKPROOF</code> attribute on a function requires
+ <code class="literal">install</code> permission.
+ </p></li><li class="listitem"><p>
+ Using <a class="link" href="sql-security-label.html" title="SECURITY LABEL"><code class="command">SECURITY LABEL</code></a> on an object additionally
+ requires <code class="literal">relabelfrom</code> permission for the object in
+ conjunction with its old security label and <code class="literal">relabelto</code>
+ permission for the object in conjunction with its new security label.
+ (In cases where multiple label providers are installed and the user
+ tries to set a security label, but it is not managed by
+ <span class="productname">SELinux</span>, only <code class="literal">setattr</code> should be checked here.
+ This is currently not done due to implementation restrictions.)
+ </p></li></ul></div></div><div class="sect3" id="id-1.11.7.49.9.5"><div class="titlepage"><div><div><h4 class="title">F.40.5.4. Trusted Procedures</h4></div></div></div><p>
+ Trusted procedures are similar to security definer functions or setuid
+ commands. <span class="productname">SELinux</span> provides a feature to allow trusted
+ code to run using a security label different from that of the client,
+ generally for the purpose of providing highly controlled access to
+ sensitive data (e.g., rows might be omitted, or the precision of stored
+ values might be reduced). Whether or not a function acts as a trusted
+ procedure is controlled by its security label and the operating system
+ security policy. For example:
+ </p><pre class="screen">
+postgres=# CREATE TABLE customer (
+ cid int primary key,
+ cname text,
+ credit text
+ );
+CREATE TABLE
+postgres=# SECURITY LABEL ON COLUMN customer.credit
+ IS 'system_u:object_r:sepgsql_secret_table_t:s0';
+SECURITY LABEL
+postgres=# CREATE FUNCTION show_credit(int) RETURNS text
+ AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'')
+ FROM customer WHERE cid = $1'
+ LANGUAGE sql;
+CREATE FUNCTION
+postgres=# SECURITY LABEL ON FUNCTION show_credit(int)
+ IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0';
+SECURITY LABEL
+</pre><p>
+ The above operations should be performed by an administrative user.
+ </p><pre class="screen">
+postgres=# SELECT * FROM customer;
+ERROR: SELinux: security policy violation
+postgres=# SELECT cid, cname, show_credit(cid) FROM customer;
+ cid | cname | show_credit
+-----+--------+---------------------
+ 1 | taro | 1111-2222-3333-xxxx
+ 2 | hanako | 5555-6666-7777-xxxx
+(2 rows)
+</pre><p>
+ In this case, a regular user cannot reference <code class="literal">customer.credit</code>
+ directly, but a trusted procedure <code class="literal">show_credit</code> allows the user
+ to print the credit card numbers of customers with some of the digits
+ masked out.
+ </p></div><div class="sect3" id="id-1.11.7.49.9.6"><div class="titlepage"><div><div><h4 class="title">F.40.5.5. Dynamic Domain Transitions</h4></div></div></div><p>
+ It is possible to use SELinux's dynamic domain transition feature
+ to switch the security label of the client process, the client domain,
+ to a new context, if that is allowed by the security policy.
+ The client domain needs the <code class="literal">setcurrent</code> permission and also
+ <code class="literal">dyntransition</code> from the old to the new domain.
+ </p><p>
+ Dynamic domain transitions should be considered carefully, because they
+ allow users to switch their label, and therefore their privileges,
+ at their option, rather than (as in the case of a trusted procedure)
+ as mandated by the system.
+ Thus, the <code class="literal">dyntransition</code> permission is only considered
+ safe when used to switch to a domain with a smaller set of privileges than
+ the original one. For example:
+ </p><pre class="screen">
+regression=# select sepgsql_getcon();
+ sepgsql_getcon
+-------------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+(1 row)
+
+regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c4');
+ sepgsql_setcon
+----------------
+ t
+(1 row)
+
+regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c1023');
+ERROR: SELinux: security policy violation
+</pre><p>
+ In this example above we were allowed to switch from the larger MCS
+ range <code class="literal">c1.c1023</code> to the smaller range <code class="literal">c1.c4</code>, but
+ switching back was denied.
+ </p><p>
+ A combination of dynamic domain transition and trusted procedure
+ enables an interesting use case that fits the typical process life-cycle
+ of connection pooling software.
+ Even if your connection pooling software is not allowed to run most
+ of SQL commands, you can allow it to switch the security label
+ of the client using the <code class="literal">sepgsql_setcon()</code> function
+ from within a trusted procedure; that should take some
+ credential to authorize the request to switch the client label.
+ After that, this session will have the privileges of the target user,
+ rather than the connection pooler.
+ The connection pooler can later revert the security label change by
+ again using <code class="literal">sepgsql_setcon()</code> with
+ <code class="literal">NULL</code> argument, again invoked from within a trusted
+ procedure with appropriate permissions checks.
+ The point here is that only the trusted procedure actually has permission
+ to change the effective security label, and only does so when given proper
+ credentials. Of course, for secure operation, the credential store
+ (table, procedure definition, or whatever) must be protected from
+ unauthorized access.
+ </p></div><div class="sect3" id="id-1.11.7.49.9.7"><div class="titlepage"><div><div><h4 class="title">F.40.5.6. Miscellaneous</h4></div></div></div><p>
+ We reject the <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command across the board, because
+ any module loaded could easily circumvent security policy enforcement.
+ </p></div></div><div class="sect2" id="SEPGSQL-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">F.40.6. Sepgsql Functions</h3></div></div></div><p>
+ <a class="xref" href="sepgsql.html#SEPGSQL-FUNCTIONS-TABLE" title="Table F.29. Sepgsql Functions">Table F.29</a> shows the available functions.
+ </p><div class="table" id="SEPGSQL-FUNCTIONS-TABLE"><p class="title"><strong>Table F.29. Sepgsql Functions</strong></p><div class="table-contents"><table class="table" summary="Sepgsql Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sepgsql_getcon</code> ()
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Returns the client domain, the current security label of the client.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sepgsql_setcon</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Switches the client domain of the current session to the new domain,
+ if allowed by the security policy.
+ It also accepts <code class="literal">NULL</code> input as a request to transition
+ to the client's original domain.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sepgsql_mcstrans_in</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Translates the given qualified MLS/MCS range into raw format if
+ the mcstrans daemon is running.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sepgsql_mcstrans_out</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Translates the given raw MLS/MCS range into qualified format if
+ the mcstrans daemon is running.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">sepgsql_restorecon</code> ( <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Sets up initial security labels for all objects within the
+ current database. The argument may be <code class="literal">NULL</code>, or the
+ name of a specfile to be used as alternative of the system default.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="SEPGSQL-LIMITATIONS"><div class="titlepage"><div><div><h3 class="title">F.40.7. Limitations</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">Data Definition Language (DDL) Permissions</span></dt><dd><p>
+ Due to implementation restrictions, some DDL operations do not
+ check permissions.
+ </p></dd><dt><span class="term">Data Control Language (DCL) Permissions</span></dt><dd><p>
+ Due to implementation restrictions, DCL operations do not check
+ permissions.
+ </p></dd><dt><span class="term">Row-level access control</span></dt><dd><p>
+ <span class="productname">PostgreSQL</span> supports row-level access, but
+ <code class="filename">sepgsql</code> does not.
+ </p></dd><dt><span class="term">Covert channels</span></dt><dd><p>
+ <code class="filename">sepgsql</code> does not try to hide the existence of
+ a certain object, even if the user is not allowed to reference it.
+ For example, we can infer the existence of an invisible object as
+ a result of primary key conflicts, foreign key violations, and so on,
+ even if we cannot obtain the contents of the object. The existence
+ of a top secret table cannot be hidden; we only hope to conceal its
+ contents.
+ </p></dd></dl></div></div><div class="sect2" id="SEPGSQL-RESOURCES"><div class="titlepage"><div><div><h3 class="title">F.40.8. External Resources</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><a class="ulink" href="https://wiki.postgresql.org/wiki/SEPostgreSQL" target="_top">SE-PostgreSQL Introduction</a></span></dt><dd><p>
+ This wiki page provides a brief overview, security design, architecture,
+ administration and upcoming features.
+ </p></dd><dt><span class="term"><a class="ulink" href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/index" target="_top">SELinux User's and Administrator's Guide</a></span></dt><dd><p>
+ This document provides a wide spectrum of knowledge to administer
+ <span class="productname">SELinux</span> on your systems.
+ It focuses primarily on Red Hat operating systems, but is not limited to them.
+ </p></dd><dt><span class="term"><a class="ulink" href="https://fedoraproject.org/wiki/SELinux_FAQ" target="_top">Fedora SELinux FAQ</a></span></dt><dd><p>
+ This document answers frequently asked questions about
+ <span class="productname">SELinux</span>.
+ It focuses primarily on Fedora, but is not limited to Fedora.
+ </p></dd></dl></div></div><div class="sect2" id="SEPGSQL-AUTHOR"><div class="titlepage"><div><div><h3 class="title">F.40.9. Author</h3></div></div></div><p>
+ KaiGai Kohei <code class="email">&lt;<a class="email" href="mailto:kaigai@ak.jp.nec.com">kaigai@ak.jp.nec.com</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="seg.html" title="F.39. seg">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-spi.html" title="F.41. spi">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.39. seg </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.41. spi</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/server-programming.html b/doc/src/sgml/html/server-programming.html
new file mode 100644
index 0000000..a243ede
--- /dev/null
+++ b/doc/src/sgml/html/server-programming.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part V. Server Programming</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="infoschema-views.html" title="37.66. views" /><link rel="next" href="extend.html" title="Chapter 38. Extending SQL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part V. Server Programming</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="infoschema-views.html" title="37.66. views">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="extend.html" title="Chapter 38. Extending SQL">Next</a></td></tr></table><hr /></div><div class="part" id="SERVER-PROGRAMMING"><div class="titlepage"><div><div><h1 class="title">Part V. Server Programming</h1></div></div></div><div class="partintro" id="id-1.8.2"><div></div><p>
+ This part is about extending the server functionality with
+ user-defined functions, data types, triggers, etc. These are
+ advanced topics which should probably be approached only after all
+ the other user documentation about <span class="productname">PostgreSQL</span> has
+ been understood. Later chapters in this part describe the server-side
+ programming languages available in the
+ <span class="productname">PostgreSQL</span> distribution as well as
+ general issues concerning server-side programming languages. It
+ is essential to read at least the earlier sections of <a class="xref" href="extend.html" title="Chapter 38. Extending SQL">Chapter 38</a> (covering functions) before diving into the
+ material about server-side programming languages.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="extend.html">38. Extending <acronym class="acronym">SQL</acronym></a></span></dt><dd><dl><dt><span class="sect1"><a href="extend-how.html">38.1. How Extensibility Works</a></span></dt><dt><span class="sect1"><a href="extend-type-system.html">38.2. The <span class="productname">PostgreSQL</span> Type System</a></span></dt><dt><span class="sect1"><a href="xfunc.html">38.3. User-Defined Functions</a></span></dt><dt><span class="sect1"><a href="xproc.html">38.4. User-Defined Procedures</a></span></dt><dt><span class="sect1"><a href="xfunc-sql.html">38.5. Query Language (<acronym class="acronym">SQL</acronym>) Functions</a></span></dt><dt><span class="sect1"><a href="xfunc-overload.html">38.6. Function Overloading</a></span></dt><dt><span class="sect1"><a href="xfunc-volatility.html">38.7. Function Volatility Categories</a></span></dt><dt><span class="sect1"><a href="xfunc-pl.html">38.8. Procedural Language Functions</a></span></dt><dt><span class="sect1"><a href="xfunc-internal.html">38.9. Internal Functions</a></span></dt><dt><span class="sect1"><a href="xfunc-c.html">38.10. C-Language Functions</a></span></dt><dt><span class="sect1"><a href="xfunc-optimization.html">38.11. Function Optimization Information</a></span></dt><dt><span class="sect1"><a href="xaggr.html">38.12. User-Defined Aggregates</a></span></dt><dt><span class="sect1"><a href="xtypes.html">38.13. User-Defined Types</a></span></dt><dt><span class="sect1"><a href="xoper.html">38.14. User-Defined Operators</a></span></dt><dt><span class="sect1"><a href="xoper-optimization.html">38.15. Operator Optimization Information</a></span></dt><dt><span class="sect1"><a href="xindex.html">38.16. Interfacing Extensions to Indexes</a></span></dt><dt><span class="sect1"><a href="extend-extensions.html">38.17. Packaging Related Objects into an Extension</a></span></dt><dt><span class="sect1"><a href="extend-pgxs.html">38.18. Extension Building Infrastructure</a></span></dt></dl></dd><dt><span class="chapter"><a href="triggers.html">39. Triggers</a></span></dt><dd><dl><dt><span class="sect1"><a href="trigger-definition.html">39.1. Overview of Trigger Behavior</a></span></dt><dt><span class="sect1"><a href="trigger-datachanges.html">39.2. Visibility of Data Changes</a></span></dt><dt><span class="sect1"><a href="trigger-interface.html">39.3. Writing Trigger Functions in C</a></span></dt><dt><span class="sect1"><a href="trigger-example.html">39.4. A Complete Trigger Example</a></span></dt></dl></dd><dt><span class="chapter"><a href="event-triggers.html">40. Event Triggers</a></span></dt><dd><dl><dt><span class="sect1"><a href="event-trigger-definition.html">40.1. Overview of Event Trigger Behavior</a></span></dt><dt><span class="sect1"><a href="event-trigger-matrix.html">40.2. Event Trigger Firing Matrix</a></span></dt><dt><span class="sect1"><a href="event-trigger-interface.html">40.3. Writing Event Trigger Functions in C</a></span></dt><dt><span class="sect1"><a href="event-trigger-example.html">40.4. A Complete Event Trigger Example</a></span></dt><dt><span class="sect1"><a href="event-trigger-table-rewrite-example.html">40.5. A Table Rewrite Event Trigger Example</a></span></dt></dl></dd><dt><span class="chapter"><a href="rules.html">41. The Rule System</a></span></dt><dd><dl><dt><span class="sect1"><a href="querytree.html">41.1. The Query Tree</a></span></dt><dt><span class="sect1"><a href="rules-views.html">41.2. Views and the Rule System</a></span></dt><dt><span class="sect1"><a href="rules-materializedviews.html">41.3. Materialized Views</a></span></dt><dt><span class="sect1"><a href="rules-update.html">41.4. Rules on <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and <code class="command">DELETE</code></a></span></dt><dt><span class="sect1"><a href="rules-privileges.html">41.5. Rules and Privileges</a></span></dt><dt><span class="sect1"><a href="rules-status.html">41.6. Rules and Command Status</a></span></dt><dt><span class="sect1"><a href="rules-triggers.html">41.7. Rules Versus Triggers</a></span></dt></dl></dd><dt><span class="chapter"><a href="xplang.html">42. Procedural Languages</a></span></dt><dd><dl><dt><span class="sect1"><a href="xplang-install.html">42.1. Installing Procedural Languages</a></span></dt></dl></dd><dt><span class="chapter"><a href="plpgsql.html">43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</a></span></dt><dd><dl><dt><span class="sect1"><a href="plpgsql-overview.html">43.1. Overview</a></span></dt><dt><span class="sect1"><a href="plpgsql-structure.html">43.2. Structure of <span class="application">PL/pgSQL</span></a></span></dt><dt><span class="sect1"><a href="plpgsql-declarations.html">43.3. Declarations</a></span></dt><dt><span class="sect1"><a href="plpgsql-expressions.html">43.4. Expressions</a></span></dt><dt><span class="sect1"><a href="plpgsql-statements.html">43.5. Basic Statements</a></span></dt><dt><span class="sect1"><a href="plpgsql-control-structures.html">43.6. Control Structures</a></span></dt><dt><span class="sect1"><a href="plpgsql-cursors.html">43.7. Cursors</a></span></dt><dt><span class="sect1"><a href="plpgsql-transactions.html">43.8. Transaction Management</a></span></dt><dt><span class="sect1"><a href="plpgsql-errors-and-messages.html">43.9. Errors and Messages</a></span></dt><dt><span class="sect1"><a href="plpgsql-trigger.html">43.10. Trigger Functions</a></span></dt><dt><span class="sect1"><a href="plpgsql-implementation.html">43.11. <span class="application">PL/pgSQL</span> under the Hood</a></span></dt><dt><span class="sect1"><a href="plpgsql-development-tips.html">43.12. Tips for Developing in <span class="application">PL/pgSQL</span></a></span></dt><dt><span class="sect1"><a href="plpgsql-porting.html">43.13. Porting from <span class="productname">Oracle</span> PL/SQL</a></span></dt></dl></dd><dt><span class="chapter"><a href="pltcl.html">44. PL/Tcl — Tcl Procedural Language</a></span></dt><dd><dl><dt><span class="sect1"><a href="pltcl-overview.html">44.1. Overview</a></span></dt><dt><span class="sect1"><a href="pltcl-functions.html">44.2. PL/Tcl Functions and Arguments</a></span></dt><dt><span class="sect1"><a href="pltcl-data.html">44.3. Data Values in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-global.html">44.4. Global Data in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-dbaccess.html">44.5. Database Access from PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-trigger.html">44.6. Trigger Functions in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-event-trigger.html">44.7. Event Trigger Functions in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-error-handling.html">44.8. Error Handling in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-subtransactions.html">44.9. Explicit Subtransactions in PL/Tcl</a></span></dt><dt><span class="sect1"><a href="pltcl-transactions.html">44.10. Transaction Management</a></span></dt><dt><span class="sect1"><a href="pltcl-config.html">44.11. PL/Tcl Configuration</a></span></dt><dt><span class="sect1"><a href="pltcl-procnames.html">44.12. Tcl Procedure Names</a></span></dt></dl></dd><dt><span class="chapter"><a href="plperl.html">45. PL/Perl — Perl Procedural Language</a></span></dt><dd><dl><dt><span class="sect1"><a href="plperl-funcs.html">45.1. PL/Perl Functions and Arguments</a></span></dt><dt><span class="sect1"><a href="plperl-data.html">45.2. Data Values in PL/Perl</a></span></dt><dt><span class="sect1"><a href="plperl-builtins.html">45.3. Built-in Functions</a></span></dt><dt><span class="sect1"><a href="plperl-global.html">45.4. Global Values in PL/Perl</a></span></dt><dt><span class="sect1"><a href="plperl-trusted.html">45.5. Trusted and Untrusted PL/Perl</a></span></dt><dt><span class="sect1"><a href="plperl-triggers.html">45.6. PL/Perl Triggers</a></span></dt><dt><span class="sect1"><a href="plperl-event-triggers.html">45.7. PL/Perl Event Triggers</a></span></dt><dt><span class="sect1"><a href="plperl-under-the-hood.html">45.8. PL/Perl Under the Hood</a></span></dt></dl></dd><dt><span class="chapter"><a href="plpython.html">46. PL/Python — Python Procedural Language</a></span></dt><dd><dl><dt><span class="sect1"><a href="plpython-funcs.html">46.1. PL/Python Functions</a></span></dt><dt><span class="sect1"><a href="plpython-data.html">46.2. Data Values</a></span></dt><dt><span class="sect1"><a href="plpython-sharing.html">46.3. Sharing Data</a></span></dt><dt><span class="sect1"><a href="plpython-do.html">46.4. Anonymous Code Blocks</a></span></dt><dt><span class="sect1"><a href="plpython-trigger.html">46.5. Trigger Functions</a></span></dt><dt><span class="sect1"><a href="plpython-database.html">46.6. Database Access</a></span></dt><dt><span class="sect1"><a href="plpython-subtransaction.html">46.7. Explicit Subtransactions</a></span></dt><dt><span class="sect1"><a href="plpython-transactions.html">46.8. Transaction Management</a></span></dt><dt><span class="sect1"><a href="plpython-util.html">46.9. Utility Functions</a></span></dt><dt><span class="sect1"><a href="plpython-python23.html">46.10. Python 2 vs. Python 3</a></span></dt><dt><span class="sect1"><a href="plpython-envar.html">46.11. Environment Variables</a></span></dt></dl></dd><dt><span class="chapter"><a href="spi.html">47. Server Programming Interface</a></span></dt><dd><dl><dt><span class="sect1"><a href="spi-interface.html">47.1. Interface Functions</a></span></dt><dt><span class="sect1"><a href="spi-interface-support.html">47.2. Interface Support Functions</a></span></dt><dt><span class="sect1"><a href="spi-memory.html">47.3. Memory Management</a></span></dt><dt><span class="sect1"><a href="spi-transaction.html">47.4. Transaction Management</a></span></dt><dt><span class="sect1"><a href="spi-visibility.html">47.5. Visibility of Data Changes</a></span></dt><dt><span class="sect1"><a href="spi-examples.html">47.6. Examples</a></span></dt></dl></dd><dt><span class="chapter"><a href="bgworker.html">48. Background Worker Processes</a></span></dt><dt><span class="chapter"><a href="logicaldecoding.html">49. Logical Decoding</a></span></dt><dd><dl><dt><span class="sect1"><a href="logicaldecoding-example.html">49.1. Logical Decoding Examples</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-explanation.html">49.2. Logical Decoding Concepts</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-walsender.html">49.3. Streaming Replication Protocol Interface</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-sql.html">49.4. Logical Decoding <acronym class="acronym">SQL</acronym> Interface</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-catalogs.html">49.5. System Catalogs Related to Logical Decoding</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-output-plugin.html">49.6. Logical Decoding Output Plugins</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-writer.html">49.7. Logical Decoding Output Writers</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-synchronous.html">49.8. Synchronous Replication Support for Logical Decoding</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-streaming.html">49.9. Streaming of Large Transactions for Logical Decoding</a></span></dt><dt><span class="sect1"><a href="logicaldecoding-two-phase-commits.html">49.10. Two-phase Commit Support for Logical Decoding</a></span></dt></dl></dd><dt><span class="chapter"><a href="replication-origins.html">50. Replication Progress Tracking</a></span></dt><dt><span class="chapter"><a href="archive-modules.html">51. Archive Modules</a></span></dt><dd><dl><dt><span class="sect1"><a href="archive-module-init.html">51.1. Initialization Functions</a></span></dt><dt><span class="sect1"><a href="archive-module-callbacks.html">51.2. Archive Module Callbacks</a></span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="infoschema-views.html" title="37.66. views">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="extend.html" title="Chapter 38. Extending SQL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.66. <code class="literal">views</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 38. Extending <acronym class="acronym">SQL</acronym></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/server-shutdown.html b/doc/src/sgml/html/server-shutdown.html
new file mode 100644
index 0000000..72cf29f
--- /dev/null
+++ b/doc/src/sgml/html/server-shutdown.html
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.5. Shutting Down the Server</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="kernel-resources.html" title="19.4. Managing Kernel Resources" /><link rel="next" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.5. Shutting Down the Server</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="kernel-resources.html" title="19.4. Managing Kernel Resources">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster">Next</a></td></tr></table><hr /></div><div class="sect1" id="SERVER-SHUTDOWN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.5. Shutting Down the Server</h2></div></div></div><a id="id-1.6.6.8.2" class="indexterm"></a><p>
+ There are several ways to shut down the database server.
+ Under the hood, they all reduce to sending a signal to the supervisor
+ <code class="command">postgres</code> process.
+ </p><p>
+ If you are using a pre-packaged version
+ of <span class="productname">PostgreSQL</span>, and you used its provisions
+ for starting the server, then you should also use its provisions for
+ stopping the server. Consult the package-level documentation for
+ details.
+ </p><p>
+ When managing the server directly, you can control the type of shutdown
+ by sending different signals to the <code class="command">postgres</code>
+ process:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><span class="systemitem">SIGTERM</span><a id="id-1.6.6.8.5.2.1.1.2" class="indexterm"></a></span></dt><dd><p>
+ This is the <em class="firstterm">Smart Shutdown</em> mode.
+ After receiving <span class="systemitem">SIGTERM</span>, the server
+ disallows new connections, but lets existing sessions end their
+ work normally. It shuts down only after all of the sessions terminate.
+ If the server is in recovery when a smart
+ shutdown is requested, recovery and streaming replication will be
+ stopped only after all regular sessions have terminated.
+ </p></dd><dt><span class="term"><span class="systemitem">SIGINT</span><a id="id-1.6.6.8.5.2.2.1.2" class="indexterm"></a></span></dt><dd><p>
+ This is the <em class="firstterm">Fast Shutdown</em> mode.
+ The server disallows new connections and sends all existing
+ server processes <span class="systemitem">SIGTERM</span>, which will cause them
+ to abort their current transactions and exit promptly. It then
+ waits for all server processes to exit and finally shuts down.
+ </p></dd><dt><span class="term"><span class="systemitem">SIGQUIT</span><a id="id-1.6.6.8.5.2.3.1.2" class="indexterm"></a></span></dt><dd><p>
+ This is the <em class="firstterm">Immediate Shutdown</em> mode.
+ The server will send <span class="systemitem">SIGQUIT</span> to all child
+ processes and wait for them to terminate. If any do not terminate
+ within 5 seconds, they will be sent <span class="systemitem">SIGKILL</span>.
+ The supervisor server process exits as soon as all child processes have
+ exited, without doing normal database shutdown processing.
+ This will lead to recovery (by
+ replaying the WAL log) upon next start-up. This is recommended
+ only in emergencies.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a> program provides a convenient
+ interface for sending these signals to shut down the server.
+ Alternatively, you can send the signal directly using <code class="command">kill</code>
+ on non-Windows systems.
+ The <acronym class="acronym">PID</acronym> of the <code class="command">postgres</code> process can be
+ found using the <code class="command">ps</code> program, or from the file
+ <code class="filename">postmaster.pid</code> in the data directory. For
+ example, to do a fast shutdown:
+</p><pre class="screen">
+$ <strong class="userinput"><code>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</code></strong>
+</pre><p>
+ </p><div class="important"><h3 class="title">Important</h3><p>
+ It is best not to use <span class="systemitem">SIGKILL</span> to shut down the
+ server. Doing so will prevent the server from releasing shared memory and
+ semaphores. Furthermore, <span class="systemitem">SIGKILL</span> kills
+ the <code class="command">postgres</code> process without letting it relay the
+ signal to its subprocesses, so it might be necessary to kill the
+ individual subprocesses by hand as well.
+ </p></div><p>
+ To terminate an individual session while allowing other sessions to
+ continue, use <code class="function">pg_terminate_backend()</code> (see <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL-TABLE" title="Table 9.88. Server Signaling Functions">Table 9.88</a>) or send a
+ <span class="systemitem">SIGTERM</span> signal to the child process associated with
+ the session.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="kernel-resources.html" title="19.4. Managing Kernel Resources">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="upgrading.html" title="19.6. Upgrading a PostgreSQL Cluster">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.4. Managing Kernel Resources </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.6. Upgrading a <span class="productname">PostgreSQL</span> Cluster</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/server-start.html b/doc/src/sgml/html/server-start.html
new file mode 100644
index 0000000..a9398d1
--- /dev/null
+++ b/doc/src/sgml/html/server-start.html
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.3. Starting the Database Server</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="creating-cluster.html" title="19.2. Creating a Database Cluster" /><link rel="next" href="kernel-resources.html" title="19.4. Managing Kernel Resources" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.3. Starting the Database Server</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="kernel-resources.html" title="19.4. Managing Kernel Resources">Next</a></td></tr></table><hr /></div><div class="sect1" id="SERVER-START"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.3. Starting the Database Server</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="server-start.html#SERVER-START-FAILURES">19.3.1. Server Start-up Failures</a></span></dt><dt><span class="sect2"><a href="server-start.html#CLIENT-CONNECTION-PROBLEMS">19.3.2. Client Connection Problems</a></span></dt></dl></div><p>
+ Before anyone can access the database, you must start the database
+ server. The database server program is called
+ <code class="command">postgres</code>.<a id="id-1.6.6.6.2.2" class="indexterm"></a>
+ </p><p>
+ If you are using a pre-packaged version
+ of <span class="productname">PostgreSQL</span>, it almost certainly includes
+ provisions for running the server as a background task according to the
+ conventions of your operating system. Using the package's
+ infrastructure to start the server will be much less work than figuring
+ out how to do this yourself. Consult the package-level documentation
+ for details.
+ </p><p>
+ The bare-bones way to start the server manually is just to invoke
+ <code class="command">postgres</code> directly, specifying the location of the
+ data directory with the <code class="option">-D</code> option, for example:
+</p><pre class="screen">
+$ <strong class="userinput"><code>postgres -D /usr/local/pgsql/data</code></strong>
+</pre><p>
+ which will leave the server running in the foreground. This must be
+ done while logged into the <span class="productname">PostgreSQL</span> user
+ account. Without <code class="option">-D</code>, the server will try to use
+ the data directory named by the environment variable <code class="envar">PGDATA</code>.
+ If that variable is not provided either, it will fail.
+ </p><p>
+ Normally it is better to start <code class="command">postgres</code> in the
+ background. For this, use the usual Unix shell syntax:
+</p><pre class="screen">
+$ <strong class="userinput"><code>postgres -D /usr/local/pgsql/data &gt;logfile 2&gt;&amp;1 &amp;</code></strong>
+</pre><p>
+ It is important to store the server's <span class="systemitem">stdout</span> and
+ <span class="systemitem">stderr</span> output somewhere, as shown above. It will help
+ for auditing purposes and to diagnose problems. (See <a class="xref" href="logfile-maintenance.html" title="25.3. Log File Maintenance">Section 25.3</a> for a more thorough discussion of log
+ file handling.)
+ </p><p>
+ The <code class="command">postgres</code> program also takes a number of other
+ command-line options. For more information, see the
+ <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a> reference page
+ and <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> below.
+ </p><p>
+ This shell syntax can get tedious quickly. Therefore the wrapper
+ program
+ <a class="xref" href="app-pg-ctl.html" title="pg_ctl"><span class="refentrytitle"><span class="application">pg_ctl</span></span></a><a id="id-1.6.6.6.7.2" class="indexterm"></a>
+ is provided to simplify some tasks. For example:
+</p><pre class="programlisting">
+pg_ctl start -l logfile
+</pre><p>
+ will start the server in the background and put the output into the
+ named log file. The <code class="option">-D</code> option has the same meaning
+ here as for <code class="command">postgres</code>. <code class="command">pg_ctl</code>
+ is also capable of stopping the server.
+ </p><p>
+ Normally, you will want to start the database server when the
+ computer boots.<a id="id-1.6.6.6.8.1" class="indexterm"></a>
+ Autostart scripts are operating-system-specific.
+ There are a few example scripts distributed with
+ <span class="productname">PostgreSQL</span> in the
+ <code class="filename">contrib/start-scripts</code> directory. Installing one will require
+ root privileges.
+ </p><p>
+ Different systems have different conventions for starting up daemons
+ at boot time. Many systems have a file
+ <code class="filename">/etc/rc.local</code> or
+ <code class="filename">/etc/rc.d/rc.local</code>. Others use <code class="filename">init.d</code> or
+ <code class="filename">rc.d</code> directories. Whatever you do, the server must be
+ run by the <span class="productname">PostgreSQL</span> user account
+ <span class="emphasis"><em>and not by root</em></span> or any other user. Therefore you
+ probably should form your commands using
+ <code class="literal">su postgres -c '...'</code>. For example:
+</p><pre class="programlisting">
+su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog'
+</pre><p>
+ </p><p>
+ Here are a few more operating-system-specific suggestions. (In each
+ case be sure to use the proper installation directory and user
+ name where we show generic values.)
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ For <span class="productname">FreeBSD</span>, look at the file
+ <code class="filename">contrib/start-scripts/freebsd</code> in the
+ <span class="productname">PostgreSQL</span> source distribution.
+ <a id="id-1.6.6.6.10.1.1.1.4" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ On <span class="productname">OpenBSD</span>, add the following lines
+ to the file <code class="filename">/etc/rc.local</code>:
+ <a id="id-1.6.6.6.10.1.2.1.3" class="indexterm"></a>
+</p><pre class="programlisting">
+if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then
+ su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data'
+ echo -n ' postgresql'
+fi
+</pre><p>
+ </p></li><li class="listitem"><p>
+ On <span class="productname">Linux</span> systems either add
+ <a id="id-1.6.6.6.10.1.3.1.2" class="indexterm"></a>
+</p><pre class="programlisting">
+/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data
+</pre><p>
+ to <code class="filename">/etc/rc.d/rc.local</code>
+ or <code class="filename">/etc/rc.local</code> or look at the file
+ <code class="filename">contrib/start-scripts/linux</code> in the
+ <span class="productname">PostgreSQL</span> source distribution.
+ </p><p>
+ When using <span class="application">systemd</span>, you can use the following
+ service unit file (e.g.,
+ at <code class="filename">/etc/systemd/system/postgresql.service</code>):<a id="id-1.6.6.6.10.1.3.2.3" class="indexterm"></a>
+</p><pre class="programlisting">
+[Unit]
+Description=PostgreSQL database server
+Documentation=man:postgres(1)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=notify
+User=postgres
+ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
+ExecReload=/bin/kill -HUP $MAINPID
+KillMode=mixed
+KillSignal=SIGINT
+TimeoutSec=infinity
+
+[Install]
+WantedBy=multi-user.target
+</pre><p>
+ Using <code class="literal">Type=notify</code> requires that the server binary was
+ built with <code class="literal">configure --with-systemd</code>.
+ </p><p>
+ Consider carefully the timeout
+ setting. <span class="application">systemd</span> has a default timeout of 90
+ seconds as of this writing and will kill a process that does not report
+ readiness within that time. But a <span class="productname">PostgreSQL</span>
+ server that might have to perform crash recovery at startup could take
+ much longer to become ready. The suggested value
+ of <code class="literal">infinity</code> disables the timeout logic.
+ </p></li><li class="listitem"><p>
+ On <span class="productname">NetBSD</span>, use either the
+ <span class="productname">FreeBSD</span> or
+ <span class="productname">Linux</span> start scripts, depending on
+ preference.
+ <a id="id-1.6.6.6.10.1.4.1.4" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ On <span class="productname">Solaris</span>, create a file called
+ <code class="filename">/etc/init.d/postgresql</code> that contains
+ the following line:
+ <a id="id-1.6.6.6.10.1.5.1.3" class="indexterm"></a>
+</p><pre class="programlisting">
+su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data"
+</pre><p>
+ Then, create a symbolic link to it in <code class="filename">/etc/rc3.d</code> as
+ <code class="filename">S99postgresql</code>.
+ </p></li></ul></div><p>
+
+ </p><p>
+ While the server is running, its
+ <acronym class="acronym">PID</acronym> is stored in the file
+ <code class="filename">postmaster.pid</code> in the data directory. This is
+ used to prevent multiple server instances from
+ running in the same data directory and can also be used for
+ shutting down the server.
+ </p><div class="sect2" id="SERVER-START-FAILURES"><div class="titlepage"><div><div><h3 class="title">19.3.1. Server Start-up Failures</h3></div></div></div><p>
+ There are several common reasons the server might fail to
+ start. Check the server's log file, or start it by hand (without
+ redirecting standard output or standard error) and see what error
+ messages appear. Below we explain some of the most common error
+ messages in more detail.
+ </p><p>
+</p><pre class="screen">
+LOG: could not bind IPv4 address "127.0.0.1": Address already in use
+HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
+FATAL: could not create any TCP/IP sockets
+</pre><p>
+ This usually means just what it suggests: you tried to start
+ another server on the same port where one is already running.
+ However, if the kernel error message is not <code class="computeroutput">Address
+ already in use</code> or some variant of that, there might
+ be a different problem. For example, trying to start a server
+ on a reserved port number might draw something like:
+</p><pre class="screen">
+$ <strong class="userinput"><code>postgres -p 666</code></strong>
+LOG: could not bind IPv4 address "127.0.0.1": Permission denied
+HINT: Is another postmaster already running on port 666? If not, wait a few seconds and retry.
+FATAL: could not create any TCP/IP sockets
+</pre><p>
+ </p><p>
+ A message like:
+</p><pre class="screen">
+FATAL: could not create shared memory segment: Invalid argument
+DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600).
+</pre><p>
+ probably means your kernel's limit on the size of shared memory is
+ smaller than the work area <span class="productname">PostgreSQL</span>
+ is trying to create (4011376640 bytes in this example).
+ This is only likely to happen if you have set <code class="literal">shared_memory_type</code>
+ to <code class="literal">sysv</code>. In that case, you
+ can try starting the server with a smaller-than-normal number of
+ buffers (<a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>), or
+ reconfigure your kernel to increase the allowed shared memory
+ size. You might also see this message when trying to start multiple
+ servers on the same machine, if their total space requested
+ exceeds the kernel limit.
+ </p><p>
+ An error like:
+</p><pre class="screen">
+FATAL: could not create semaphores: No space left on device
+DETAIL: Failed system call was semget(5440126, 17, 03600).
+</pre><p>
+ does <span class="emphasis"><em>not</em></span> mean you've run out of disk
+ space. It means your kernel's limit on the number of <span class="systemitem">System V</span> semaphores is smaller than the number
+ <span class="productname">PostgreSQL</span> wants to create. As above,
+ you might be able to work around the problem by starting the
+ server with a reduced number of allowed connections
+ (<a class="xref" href="runtime-config-connection.html#GUC-MAX-CONNECTIONS">max_connections</a>), but you'll eventually want to
+ increase the kernel limit.
+ </p><p>
+ Details about configuring <span class="systemitem">System V</span>
+ <acronym class="acronym">IPC</acronym> facilities are given in <a class="xref" href="kernel-resources.html#SYSVIPC" title="19.4.1. Shared Memory and Semaphores">Section 19.4.1</a>.
+ </p></div><div class="sect2" id="CLIENT-CONNECTION-PROBLEMS"><div class="titlepage"><div><div><h3 class="title">19.3.2. Client Connection Problems</h3></div></div></div><p>
+ Although the error conditions possible on the client side are quite
+ varied and application-dependent, a few of them might be directly
+ related to how the server was started. Conditions other than
+ those shown below should be documented with the respective client
+ application.
+ </p><p>
+</p><pre class="screen">
+psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused
+ Is the server running on that host and accepting TCP/IP connections?
+</pre><p>
+ This is the generic <span class="quote">“<span class="quote">I couldn't find a server to talk
+ to</span>”</span> failure. It looks like the above when TCP/IP
+ communication is attempted. A common mistake is to forget to
+ configure the server to allow TCP/IP connections.
+ </p><p>
+ Alternatively, you might get this when attempting Unix-domain socket
+ communication to a local server:
+</p><pre class="screen">
+psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
+ Is the server running locally and accepting connections on that socket?
+</pre><p>
+ If the server is indeed running, check that the client's idea of the
+ socket path (here <code class="literal">/tmp</code>) agrees with the server's
+ <a class="xref" href="runtime-config-connection.html#GUC-UNIX-SOCKET-DIRECTORIES">unix_socket_directories</a> setting.
+ </p><p>
+ A connection failure message always shows the server address or socket
+ path name, which is useful in verifying that the client is trying to
+ connect to the right place. If there is in fact no server
+ listening there, the kernel error message will typically be either
+ <code class="computeroutput">Connection refused</code> or
+ <code class="computeroutput">No such file or directory</code>, as
+ illustrated. (It is important to realize that
+ <code class="computeroutput">Connection refused</code> in this context
+ does <span class="emphasis"><em>not</em></span> mean that the server got your
+ connection request and rejected it. That case will produce a
+ different message, as shown in <a class="xref" href="client-authentication-problems.html" title="21.15. Authentication Problems">Section 21.15</a>.) Other error messages
+ such as <code class="computeroutput">Connection timed out</code> might
+ indicate more fundamental problems, like lack of network
+ connectivity, or a firewall blocking the connection.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="kernel-resources.html" title="19.4. Managing Kernel Resources">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.2. Creating a Database Cluster </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.4. Managing Kernel Resources</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/source-conventions.html b/doc/src/sgml/html/source-conventions.html
new file mode 100644
index 0000000..23f8f7d
--- /dev/null
+++ b/doc/src/sgml/html/source-conventions.html
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>56.4. Miscellaneous Coding Conventions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="error-style-guide.html" title="56.3. Error Message Style Guide" /><link rel="next" href="nls.html" title="Chapter 57. Native Language Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">56.4. Miscellaneous Coding Conventions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="error-style-guide.html" title="56.3. Error Message Style Guide">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><th width="60%" align="center">Chapter 56. PostgreSQL Coding Conventions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="nls.html" title="Chapter 57. Native Language Support">Next</a></td></tr></table><hr /></div><div class="sect1" id="SOURCE-CONVENTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">56.4. Miscellaneous Coding Conventions</h2></div></div></div><div class="simplesect" id="id-1.10.7.5.2"><div class="titlepage"><div><div><h3 class="title">C Standard</h3></div></div></div><p>
+ Code in <span class="productname">PostgreSQL</span> should only rely on language
+ features available in the C99 standard. That means a conforming
+ C99 compiler has to be able to compile postgres, at least aside
+ from a few platform dependent pieces.
+ </p><p>
+ A few features included in the C99 standard are, at this time, not
+ permitted to be used in core <span class="productname">PostgreSQL</span>
+ code. This currently includes variable length arrays, intermingled
+ declarations and code, <code class="literal">//</code> comments, universal
+ character names. Reasons for that include portability and historical
+ practices.
+ </p><p>
+ Features from later revisions of the C standard or compiler specific
+ features can be used, if a fallback is provided.
+ </p><p>
+ For example <code class="literal">_Static_assert()</code> and
+ <code class="literal">__builtin_constant_p</code> are currently used, even though
+ they are from newer revisions of the C standard and a
+ <span class="productname">GCC</span> extension respectively. If not available
+ we respectively fall back to using a C99 compatible replacement that
+ performs the same checks, but emits rather cryptic messages and do not
+ use <code class="literal">__builtin_constant_p</code>.
+ </p></div><div class="simplesect" id="id-1.10.7.5.3"><div class="titlepage"><div><div><h3 class="title">Function-Like Macros and Inline Functions</h3></div></div></div><p>
+ Both macros with arguments and <code class="literal">static inline</code>
+ functions may be used. The latter are preferable if there are
+ multiple-evaluation hazards when written as a macro, as e.g., the
+ case with
+</p><pre class="programlisting">
+#define Max(x, y) ((x) &gt; (y) ? (x) : (y))
+</pre><p>
+ or when the macro would be very long. In other cases it's only
+ possible to use macros, or at least easier. For example because
+ expressions of various types need to be passed to the macro.
+ </p><p>
+ When the definition of an inline function references symbols
+ (i.e., variables, functions) that are only available as part of the
+ backend, the function may not be visible when included from frontend
+ code.
+</p><pre class="programlisting">
+#ifndef FRONTEND
+static inline MemoryContext
+MemoryContextSwitchTo(MemoryContext context)
+{
+ MemoryContext old = CurrentMemoryContext;
+
+ CurrentMemoryContext = context;
+ return old;
+}
+#endif /* FRONTEND */
+</pre><p>
+ In this example <code class="literal">CurrentMemoryContext</code>, which is only
+ available in the backend, is referenced and the function thus
+ hidden with a <code class="literal">#ifndef FRONTEND</code>. This rule
+ exists because some compilers emit references to symbols
+ contained in inline functions even if the function is not used.
+ </p></div><div class="simplesect" id="id-1.10.7.5.4"><div class="titlepage"><div><div><h3 class="title">Writing Signal Handlers</h3></div></div></div><p>
+ To be suitable to run inside a signal handler code has to be
+ written very carefully. The fundamental problem is that, unless
+ blocked, a signal handler can interrupt code at any time. If code
+ inside the signal handler uses the same state as code outside
+ chaos may ensue. As an example consider what happens if a signal
+ handler tries to acquire a lock that's already held in the
+ interrupted code.
+ </p><p>
+ Barring special arrangements code in signal handlers may only
+ call async-signal safe functions (as defined in POSIX) and access
+ variables of type <code class="literal">volatile sig_atomic_t</code>. A few
+ functions in <code class="command">postgres</code> are also deemed signal safe, importantly
+ <code class="function">SetLatch()</code>.
+ </p><p>
+ In most cases signal handlers should do nothing more than note
+ that a signal has arrived, and wake up code running outside of
+ the handler using a latch. An example of such a handler is the
+ following:
+</p><pre class="programlisting">
+static void
+handle_sighup(SIGNAL_ARGS)
+{
+ int save_errno = errno;
+
+ got_SIGHUP = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
+</pre><p>
+ <code class="varname">errno</code> is saved and restored because
+ <code class="function">SetLatch()</code> might change it. If that were not done
+ interrupted code that's currently inspecting <code class="varname">errno</code> might see the wrong
+ value.
+ </p></div><div class="simplesect" id="id-1.10.7.5.5"><div class="titlepage"><div><div><h3 class="title">Calling Function Pointers</h3></div></div></div><p>
+ For clarity, it is preferred to explicitly dereference a function pointer
+ when calling the pointed-to function if the pointer is a simple variable,
+ for example:
+</p><pre class="programlisting">
+(*emit_log_hook) (edata);
+</pre><p>
+ (even though <code class="literal">emit_log_hook(edata)</code> would also work).
+ When the function pointer is part of a structure, then the extra
+ punctuation can and usually should be omitted, for example:
+</p><pre class="programlisting">
+paramInfo-&gt;paramFetch(paramInfo, paramId);
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="error-style-guide.html" title="56.3. Error Message Style Guide">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="nls.html" title="Chapter 57. Native Language Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">56.3. Error Message Style Guide </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 57. Native Language Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/source-format.html b/doc/src/sgml/html/source-format.html
new file mode 100644
index 0000000..8485bd6
--- /dev/null
+++ b/doc/src/sgml/html/source-format.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>56.1. Formatting</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions" /><link rel="next" href="error-message-reporting.html" title="56.2. Reporting Errors Within the Server" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">56.1. Formatting</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><th width="60%" align="center">Chapter 56. PostgreSQL Coding Conventions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="error-message-reporting.html" title="56.2. Reporting Errors Within the Server">Next</a></td></tr></table><hr /></div><div class="sect1" id="SOURCE-FORMAT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">56.1. Formatting</h2></div></div></div><p>
+ Source code formatting uses 4 column tab spacing, with
+ tabs preserved (i.e., tabs are not expanded to spaces).
+ Each logical indentation level is one additional tab stop.
+ </p><p>
+ Layout rules (brace positioning, etc.) follow BSD conventions. In
+ particular, curly braces for the controlled blocks of <code class="literal">if</code>,
+ <code class="literal">while</code>, <code class="literal">switch</code>, etc. go on their own lines.
+ </p><p>
+ Limit line lengths so that the code is readable in an 80-column window.
+ (This doesn't mean that you must never go past 80 columns. For instance,
+ breaking a long error message string in arbitrary places just to keep the
+ code within 80 columns is probably not a net gain in readability.)
+ </p><p>
+ To maintain a consistent coding style, do not use C++ style comments
+ (<code class="literal">//</code> comments). <span class="application">pgindent</span>
+ will replace them with <code class="literal">/* ... */</code>.
+ </p><p>
+ The preferred style for multi-line comment blocks is
+</p><pre class="programlisting">
+/*
+ * comment text begins here
+ * and continues here
+ */
+</pre><p>
+ Note that comment blocks that begin in column 1 will be preserved as-is
+ by <span class="application">pgindent</span>, but it will re-flow indented comment blocks
+ as though they were plain text. If you want to preserve the line breaks
+ in an indented block, add dashes like this:
+</p><pre class="programlisting">
+ /*----------
+ * comment text begins here
+ * and continues here
+ *----------
+ */
+</pre><p>
+ </p><p>
+ While submitted patches do not absolutely have to follow these formatting
+ rules, it's a good idea to do so. Your code will get run through
+ <span class="application">pgindent</span> before the next release, so there's no point in
+ making it look nice under some other set of formatting conventions.
+ A good rule of thumb for patches is <span class="quote">“<span class="quote">make the new code look like
+ the existing code around it</span>”</span>.
+ </p><p>
+ The <code class="filename">src/tools/editors</code> directory contains sample settings
+ files that can be used with the <span class="productname">Emacs</span>,
+ <span class="productname">xemacs</span> or <span class="productname">vim</span>
+ editors to help ensure that they format code according to these
+ conventions.
+ </p><p>
+ If you'd like to run <span class="application">pgindent</span> locally
+ to help make your code match project style, see
+ the <code class="filename">src/tools/pgindent</code> directory.
+ </p><p>
+ The text browsing tools <span class="application">more</span> and
+ <span class="application">less</span> can be invoked as:
+</p><pre class="programlisting">
+more -x4
+less -x4
+</pre><p>
+ to make them show tabs appropriately.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="source.html" title="Chapter 56. PostgreSQL Coding Conventions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="error-message-reporting.html" title="56.2. Reporting Errors Within the Server">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 56. PostgreSQL Coding Conventions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 56.2. Reporting Errors Within the Server</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/source.html b/doc/src/sgml/html/source.html
new file mode 100644
index 0000000..bd8c493
--- /dev/null
+++ b/doc/src/sgml/html/source.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 56. PostgreSQL Coding Conventions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="protocol-changes.html" title="55.10. Summary of Changes since Protocol 2.0" /><link rel="next" href="source-format.html" title="56.1. Formatting" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 56. PostgreSQL Coding Conventions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="protocol-changes.html" title="55.10. Summary of Changes since Protocol 2.0">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="source-format.html" title="56.1. Formatting">Next</a></td></tr></table><hr /></div><div class="chapter" id="SOURCE"><div class="titlepage"><div><div><h2 class="title">Chapter 56. PostgreSQL Coding Conventions</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="source-format.html">56.1. Formatting</a></span></dt><dt><span class="sect1"><a href="error-message-reporting.html">56.2. Reporting Errors Within the Server</a></span></dt><dt><span class="sect1"><a href="error-style-guide.html">56.3. Error Message Style Guide</a></span></dt><dt><span class="sect1"><a href="source-conventions.html">56.4. Miscellaneous Coding Conventions</a></span></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="protocol-changes.html" title="55.10. Summary of Changes since Protocol 2.0">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="source-format.html" title="56.1. Formatting">Next</a></td></tr><tr><td width="40%" align="left" valign="top">55.10. Summary of Changes since Protocol 2.0 </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 56.1. Formatting</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sourcerepo.html b/doc/src/sgml/html/sourcerepo.html
new file mode 100644
index 0000000..b0f4837
--- /dev/null
+++ b/doc/src/sgml/html/sourcerepo.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix I. The Source Code Repository</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="external-extensions.html" title="H.4. Extensions" /><link rel="next" href="git.html" title="I.1. Getting the Source via Git" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix I. The Source Code Repository</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="external-extensions.html" title="H.4. Extensions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="git.html" title="I.1. Getting the Source via Git">Next</a></td></tr></table><hr /></div><div class="appendix" id="SOURCEREPO"><div class="titlepage"><div><div><h2 class="title">Appendix I. The Source Code Repository</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="git.html">I.1. Getting the Source via <span class="productname">Git</span></a></span></dt></dl></div><p>
+ The <span class="productname">PostgreSQL</span> source code is stored and managed
+ using the <span class="productname">Git</span> version control system. A public
+ mirror of the master repository is available; it is updated within a minute
+ of any change to the master repository.
+ </p><p>
+ Our wiki, <a class="ulink" href="https://wiki.postgresql.org/wiki/Working_with_Git" target="_top">https://wiki.postgresql.org/wiki/Working_with_Git</a>,
+ has some discussion on working with Git.
+ </p><p>
+ Note that building <span class="productname">PostgreSQL</span> from the source
+ repository requires reasonably up-to-date versions of <span class="application">bison</span>,
+ <span class="application">flex</span>, and <span class="application">Perl</span>. These tools are not needed
+ to build from a distribution tarball, because the files that these tools
+ are used to build are included in the tarball. Other tool requirements
+ are the same as shown in <a class="xref" href="install-requirements.html" title="17.2. Requirements">Section 17.2</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="external-extensions.html" title="H.4. Extensions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="git.html" title="I.1. Getting the Source via Git">Next</a></td></tr><tr><td width="40%" align="left" valign="top">H.4. Extensions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> I.1. Getting the Source via <span class="productname">Git</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spgist-builtin-opclasses.html b/doc/src/sgml/html/spgist-builtin-opclasses.html
new file mode 100644
index 0000000..58750a6
--- /dev/null
+++ b/doc/src/sgml/html/spgist-builtin-opclasses.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>69.2. Built-in Operator Classes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spgist-intro.html" title="69.1. Introduction" /><link rel="next" href="spgist-extensibility.html" title="69.3. Extensibility" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">69.2. Built-in Operator Classes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spgist-intro.html" title="69.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 69. SP-GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spgist-extensibility.html" title="69.3. Extensibility">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPGIST-BUILTIN-OPCLASSES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">69.2. Built-in Operator Classes</h2></div></div></div><p>
+ The core <span class="productname">PostgreSQL</span> distribution
+ includes the <acronym class="acronym">SP-GiST</acronym> operator classes shown in
+ <a class="xref" href="spgist-builtin-opclasses.html#SPGIST-BUILTIN-OPCLASSES-TABLE" title="Table 69.1. Built-in SP-GiST Operator Classes">Table 69.1</a>.
+ </p><div class="table" id="SPGIST-BUILTIN-OPCLASSES-TABLE"><p class="title"><strong>Table 69.1. Built-in <acronym class="acronym">SP-GiST</acronym> Operator Classes</strong></p><div class="table-contents"><table class="table" summary="Built-in SP-GiST Operator Classes" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>Name</th><th>Indexable Operators</th><th>Ordering Operators</th></tr></thead><tbody><tr><td rowspan="12" valign="middle"><code class="literal">box_ops</code></td><td><code class="literal">&lt;&lt; (box,box)</code></td><td rowspan="12" valign="middle"><code class="literal">&lt;-&gt; (box,point)</code></td></tr><tr><td><code class="literal">&amp;&lt; (box,box)</code></td></tr><tr><td><code class="literal">&amp;&gt; (box,box)</code></td></tr><tr><td><code class="literal">&gt;&gt; (box,box)</code></td></tr><tr><td><code class="literal">&lt;@ (box,box)</code></td></tr><tr><td><code class="literal">@&gt; (box,box)</code></td></tr><tr><td><code class="literal">~= (box,box)</code></td></tr><tr><td><code class="literal">&amp;&amp; (box,box)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (box,box)</code></td></tr><tr><td><code class="literal">&amp;&lt;| (box,box)</code></td></tr><tr><td><code class="literal">|&amp;&gt; (box,box)</code></td></tr><tr><td><code class="literal">|&gt;&gt; (box,box)</code></td></tr><tr><td rowspan="11" valign="middle"><code class="literal">inet_ops</code></td><td><code class="literal">&lt;&lt; (inet,inet)</code></td><td rowspan="11" valign="middle"> </td></tr><tr><td><code class="literal">&lt;&lt;= (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;&gt; (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;&gt;= (inet,inet)</code></td></tr><tr><td><code class="literal">= (inet,inet)</code></td></tr><tr><td><code class="literal">&lt;&gt; (inet,inet)</code></td></tr><tr><td><code class="literal">&lt; (inet,inet)</code></td></tr><tr><td><code class="literal">&lt;= (inet,inet)</code></td></tr><tr><td><code class="literal">&gt; (inet,inet)</code></td></tr><tr><td><code class="literal">&gt;= (inet,inet)</code></td></tr><tr><td><code class="literal">&amp;&amp; (inet,inet)</code></td></tr><tr><td rowspan="6" valign="middle"><code class="literal">kd_point_ops</code></td><td><code class="literal">|&gt;&gt; (point,point)</code></td><td rowspan="6" valign="middle"><code class="literal">&lt;-&gt; (point,point)</code></td></tr><tr><td><code class="literal">&lt;&lt; (point,point)</code></td></tr><tr><td><code class="literal">&gt;&gt; (point,point)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (point,point)</code></td></tr><tr><td><code class="literal">~= (point,point)</code></td></tr><tr><td><code class="literal">&lt;@ (point,box)</code></td></tr><tr><td rowspan="12" valign="middle"><code class="literal">poly_ops</code></td><td><code class="literal">&lt;&lt; (polygon,polygon)</code></td><td rowspan="12" valign="middle"><code class="literal">&lt;-&gt; (polygon,point)</code></td></tr><tr><td><code class="literal">&amp;&lt; (polygon,polygon)</code></td></tr><tr><td><code class="literal">&amp;&gt; (polygon,polygon)</code></td></tr><tr><td><code class="literal">&gt;&gt; (polygon,polygon)</code></td></tr><tr><td><code class="literal">&lt;@ (polygon,polygon)</code></td></tr><tr><td><code class="literal">@&gt; (polygon,polygon)</code></td></tr><tr><td><code class="literal">~= (polygon,polygon)</code></td></tr><tr><td><code class="literal">&amp;&amp; (polygon,polygon)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (polygon,polygon)</code></td></tr><tr><td><code class="literal">&amp;&lt;| (polygon,polygon)</code></td></tr><tr><td><code class="literal">|&gt;&gt; (polygon,polygon)</code></td></tr><tr><td><code class="literal">|&amp;&gt; (polygon,polygon)</code></td></tr><tr><td rowspan="6" valign="middle"><code class="literal">quad_point_ops</code></td><td><code class="literal">|&gt;&gt; (point,point)</code></td><td rowspan="6" valign="middle"><code class="literal">&lt;-&gt; (point,point)</code></td></tr><tr><td><code class="literal">&lt;&lt; (point,point)</code></td></tr><tr><td><code class="literal">&gt;&gt; (point,point)</code></td></tr><tr><td><code class="literal">&lt;&lt;| (point,point)</code></td></tr><tr><td><code class="literal">~= (point,point)</code></td></tr><tr><td><code class="literal">&lt;@ (point,box)</code></td></tr><tr><td rowspan="10" valign="middle"><code class="literal">range_ops</code></td><td><code class="literal">= (anyrange,anyrange)</code></td><td rowspan="10" valign="middle"> </td></tr><tr><td><code class="literal">&amp;&amp; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange,anyelement)</code></td></tr><tr><td><code class="literal">@&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&lt;@ (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&lt;&lt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&gt;&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&amp;&lt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">&amp;&gt; (anyrange,anyrange)</code></td></tr><tr><td><code class="literal">-|- (anyrange,anyrange)</code></td></tr><tr><td rowspan="10" valign="middle"><code class="literal">text_ops</code></td><td><code class="literal">= (text,text)</code></td><td rowspan="10" valign="middle"> </td></tr><tr><td><code class="literal">&lt; (text,text)</code></td></tr><tr><td><code class="literal">&lt;= (text,text)</code></td></tr><tr><td><code class="literal">&gt; (text,text)</code></td></tr><tr><td><code class="literal">&gt;= (text,text)</code></td></tr><tr><td><code class="literal">~&lt;~ (text,text)</code></td></tr><tr><td><code class="literal">~&lt;=~ (text,text)</code></td></tr><tr><td><code class="literal">~&gt;=~ (text,text)</code></td></tr><tr><td><code class="literal">~&gt;~ (text,text)</code></td></tr><tr><td><code class="literal">^@ (text,text)</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Of the two operator classes for type <code class="type">point</code>,
+ <code class="literal">quad_point_ops</code> is the default. <code class="literal">kd_point_ops</code>
+ supports the same operators but uses a different index data structure that
+ may offer better performance in some applications.
+ </p><p>
+ The <code class="literal">quad_point_ops</code>, <code class="literal">kd_point_ops</code> and
+ <code class="literal">poly_ops</code> operator classes support the <code class="literal">&lt;-&gt;</code>
+ ordering operator, which enables the k-nearest neighbor (<code class="literal">k-NN</code>)
+ search over indexed point or polygon data sets.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spgist-intro.html" title="69.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spgist-extensibility.html" title="69.3. Extensibility">Next</a></td></tr><tr><td width="40%" align="left" valign="top">69.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 69.3. Extensibility</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spgist-examples.html b/doc/src/sgml/html/spgist-examples.html
new file mode 100644
index 0000000..26d2a98
--- /dev/null
+++ b/doc/src/sgml/html/spgist-examples.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>69.5. Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spgist-implementation.html" title="69.4. Implementation" /><link rel="next" href="gin.html" title="Chapter 70. GIN Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">69.5. Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spgist-implementation.html" title="69.4. Implementation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 69. SP-GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gin.html" title="Chapter 70. GIN Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPGIST-EXAMPLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">69.5. Examples</h2></div></div></div><p>
+ The <span class="productname">PostgreSQL</span> source distribution includes
+ several examples of index operator classes for <acronym class="acronym">SP-GiST</acronym>,
+ as described in <a class="xref" href="spgist-builtin-opclasses.html#SPGIST-BUILTIN-OPCLASSES-TABLE" title="Table 69.1. Built-in SP-GiST Operator Classes">Table 69.1</a>. Look
+ into <code class="filename">src/backend/access/spgist/</code>
+ and <code class="filename">src/backend/utils/adt/</code> to see the code.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spgist-implementation.html" title="69.4. Implementation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gin.html" title="Chapter 70. GIN Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">69.4. Implementation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 70. GIN Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spgist-extensibility.html b/doc/src/sgml/html/spgist-extensibility.html
new file mode 100644
index 0000000..7229f22
--- /dev/null
+++ b/doc/src/sgml/html/spgist-extensibility.html
@@ -0,0 +1,621 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>69.3. Extensibility</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spgist-builtin-opclasses.html" title="69.2. Built-in Operator Classes" /><link rel="next" href="spgist-implementation.html" title="69.4. Implementation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">69.3. Extensibility</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spgist-builtin-opclasses.html" title="69.2. Built-in Operator Classes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 69. SP-GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spgist-implementation.html" title="69.4. Implementation">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPGIST-EXTENSIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">69.3. Extensibility</h2></div></div></div><p>
+ <acronym class="acronym">SP-GiST</acronym> offers an interface with a high level of
+ abstraction, requiring the access method developer to implement only
+ methods specific to a given data type. The <acronym class="acronym">SP-GiST</acronym> core
+ is responsible for efficient disk mapping and searching the tree structure.
+ It also takes care of concurrency and logging considerations.
+ </p><p>
+ Leaf tuples of an <acronym class="acronym">SP-GiST</acronym> tree usually contain values
+ of the same data type as the indexed column, although it is also possible
+ for them to contain lossy representations of the indexed column.
+ Leaf tuples stored at the root level will directly represent
+ the original indexed data value, but leaf tuples at lower
+ levels might contain only a partial value, such as a suffix.
+ In that case the operator class support functions must be able to
+ reconstruct the original value using information accumulated from the
+ inner tuples that are passed through to reach the leaf level.
+ </p><p>
+ When an <acronym class="acronym">SP-GiST</acronym> index is created with
+ <code class="literal">INCLUDE</code> columns, the values of those columns are also
+ stored in leaf tuples. The <code class="literal">INCLUDE</code> columns are of no
+ concern to the <acronym class="acronym">SP-GiST</acronym> operator class, so they are
+ not discussed further here.
+ </p><p>
+ Inner tuples are more complex, since they are branching points in the
+ search tree. Each inner tuple contains a set of one or more
+ <em class="firstterm">nodes</em>, which represent groups of similar leaf values.
+ A node contains a downlink that leads either to another, lower-level inner
+ tuple, or to a short list of leaf tuples that all lie on the same index page.
+ Each node normally has a <em class="firstterm">label</em> that describes it; for example,
+ in a radix tree the node label could be the next character of the string
+ value. (Alternatively, an operator class can omit the node labels, if it
+ works with a fixed set of nodes for all inner tuples;
+ see <a class="xref" href="spgist-implementation.html#SPGIST-NULL-LABELS" title="69.4.2. SP-GiST Without Node Labels">Section 69.4.2</a>.)
+ Optionally, an inner tuple can have a <em class="firstterm">prefix</em> value
+ that describes all its members. In a radix tree this could be the common
+ prefix of the represented strings. The prefix value is not necessarily
+ really a prefix, but can be any data needed by the operator class;
+ for example, in a quad-tree it can store the central point that the four
+ quadrants are measured with respect to. A quad-tree inner tuple would
+ then also contain four nodes corresponding to the quadrants around this
+ central point.
+ </p><p>
+ Some tree algorithms require knowledge of level (or depth) of the current
+ tuple, so the <acronym class="acronym">SP-GiST</acronym> core provides the possibility for
+ operator classes to manage level counting while descending the tree.
+ There is also support for incrementally reconstructing the represented
+ value when that is needed, and for passing down additional data (called
+ <em class="firstterm">traverse values</em>) during a tree descent.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <acronym class="acronym">SP-GiST</acronym> core code takes care of null entries.
+ Although <acronym class="acronym">SP-GiST</acronym> indexes do store entries for nulls
+ in indexed columns, this is hidden from the index operator class code:
+ no null index entries or search conditions will ever be passed to the
+ operator class methods. (It is assumed that <acronym class="acronym">SP-GiST</acronym>
+ operators are strict and so cannot succeed for null values.) Null values
+ are therefore not discussed further here.
+ </p></div><p>
+ There are five user-defined methods that an index operator class for
+ <acronym class="acronym">SP-GiST</acronym> must provide, and two are optional. All five
+ mandatory methods follow the convention of accepting two <code class="type">internal</code>
+ arguments, the first of which is a pointer to a C struct containing input
+ values for the support method, while the second argument is a pointer to a
+ C struct where output values must be placed. Four of the mandatory methods just
+ return <code class="type">void</code>, since all their results appear in the output struct; but
+ <code class="function">leaf_consistent</code> returns a <code class="type">boolean</code> result.
+ The methods must not modify any fields of their input structs. In all
+ cases, the output struct is initialized to zeroes before calling the
+ user-defined method. The optional sixth method <code class="function">compress</code>
+ accepts a <code class="type">datum</code> to be indexed as the only argument and returns a value suitable
+ for physical storage in a leaf tuple. The optional seventh method
+ <code class="function">options</code> accepts an <code class="type">internal</code> pointer to a C struct, where
+ opclass-specific parameters should be placed, and returns <code class="type">void</code>.
+ </p><p>
+ The five mandatory user-defined methods are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">config</code></span></dt><dd><p>
+ Returns static information about the index implementation, including
+ the data type OIDs of the prefix and node label data types.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+</p><pre class="programlisting">
+CREATE FUNCTION my_config(internal, internal) RETURNS void ...
+</pre><p>
+ The first argument is a pointer to a <code class="structname">spgConfigIn</code>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <code class="structname">spgConfigOut</code>
+ C struct, which the function must fill with result data.
+</p><pre class="programlisting">
+typedef struct spgConfigIn
+{
+ Oid attType; /* Data type to be indexed */
+} spgConfigIn;
+
+typedef struct spgConfigOut
+{
+ Oid prefixType; /* Data type of inner-tuple prefixes */
+ Oid labelType; /* Data type of inner-tuple node labels */
+ Oid leafType; /* Data type of leaf-tuple values */
+ bool canReturnData; /* Opclass can reconstruct original data */
+ bool longValuesOK; /* Opclass can cope with values &gt; 1 page */
+} spgConfigOut;
+</pre><p>
+
+ <code class="structfield">attType</code> is passed in order to support polymorphic
+ index operator classes; for ordinary fixed-data-type operator classes, it
+ will always have the same value and so can be ignored.
+ </p><p>
+ For operator classes that do not use prefixes,
+ <code class="structfield">prefixType</code> can be set to <code class="literal">VOIDOID</code>.
+ Likewise, for operator classes that do not use node labels,
+ <code class="structfield">labelType</code> can be set to <code class="literal">VOIDOID</code>.
+ <code class="structfield">canReturnData</code> should be set true if the operator class
+ is capable of reconstructing the originally-supplied index value.
+ <code class="structfield">longValuesOK</code> should be set true only when the
+ <code class="structfield">attType</code> is of variable length and the operator
+ class is capable of segmenting long values by repeated suffixing
+ (see <a class="xref" href="spgist-implementation.html#SPGIST-LIMITS" title="69.4.1. SP-GiST Limits">Section 69.4.1</a>).
+ </p><p>
+ <code class="structfield">leafType</code> should match the index storage type
+ defined by the operator class's <code class="structfield">opckeytype</code>
+ catalog entry.
+ (Note that <code class="structfield">opckeytype</code> can be zero,
+ implying the storage type is the same as the operator class's input
+ type, which is the most common situation.)
+ For reasons of backward compatibility, the <code class="function">config</code>
+ method can set <code class="structfield">leafType</code> to some other value,
+ and that value will be used; but this is deprecated since the index
+ contents are then incorrectly identified in the catalogs.
+ Also, it's permissible to
+ leave <code class="structfield">leafType</code> uninitialized (zero);
+ that is interpreted as meaning the index storage type derived from
+ <code class="structfield">opckeytype</code>.
+ </p><p>
+ When <code class="structfield">attType</code>
+ and <code class="structfield">leafType</code> are different, the optional
+ method <code class="function">compress</code> must be provided.
+ Method <code class="function">compress</code> is responsible
+ for transformation of datums to be indexed from <code class="structfield">attType</code>
+ to <code class="structfield">leafType</code>.
+ </p></dd><dt><span class="term"><code class="function">choose</code></span></dt><dd><p>
+ Chooses a method for inserting a new value into an inner tuple.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+</p><pre class="programlisting">
+CREATE FUNCTION my_choose(internal, internal) RETURNS void ...
+</pre><p>
+ The first argument is a pointer to a <code class="structname">spgChooseIn</code>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <code class="structname">spgChooseOut</code>
+ C struct, which the function must fill with result data.
+</p><pre class="programlisting">
+typedef struct spgChooseIn
+{
+ Datum datum; /* original datum to be indexed */
+ Datum leafDatum; /* current datum to be stored at leaf */
+ int level; /* current level (counting from zero) */
+
+ /* Data from current inner tuple */
+ bool allTheSame; /* tuple is marked all-the-same? */
+ bool hasPrefix; /* tuple has a prefix? */
+ Datum prefixDatum; /* if so, the prefix value */
+ int nNodes; /* number of nodes in the inner tuple */
+ Datum *nodeLabels; /* node label values (NULL if none) */
+} spgChooseIn;
+
+typedef enum spgChooseResultType
+{
+ spgMatchNode = 1, /* descend into existing node */
+ spgAddNode, /* add a node to the inner tuple */
+ spgSplitTuple /* split inner tuple (change its prefix) */
+} spgChooseResultType;
+
+typedef struct spgChooseOut
+{
+ spgChooseResultType resultType; /* action code, see above */
+ union
+ {
+ struct /* results for spgMatchNode */
+ {
+ int nodeN; /* descend to this node (index from 0) */
+ int levelAdd; /* increment level by this much */
+ Datum restDatum; /* new leaf datum */
+ } matchNode;
+ struct /* results for spgAddNode */
+ {
+ Datum nodeLabel; /* new node's label */
+ int nodeN; /* where to insert it (index from 0) */
+ } addNode;
+ struct /* results for spgSplitTuple */
+ {
+ /* Info to form new upper-level inner tuple with one child tuple */
+ bool prefixHasPrefix; /* tuple should have a prefix? */
+ Datum prefixPrefixDatum; /* if so, its value */
+ int prefixNNodes; /* number of nodes */
+ Datum *prefixNodeLabels; /* their labels (or NULL for
+ * no labels) */
+ int childNodeN; /* which node gets child tuple */
+
+ /* Info to form new lower-level inner tuple with all old nodes */
+ bool postfixHasPrefix; /* tuple should have a prefix? */
+ Datum postfixPrefixDatum; /* if so, its value */
+ } splitTuple;
+ } result;
+} spgChooseOut;
+</pre><p>
+
+ <code class="structfield">datum</code> is the original datum of
+ <code class="structname">spgConfigIn</code>.<code class="structfield">attType</code>
+ type that was to be inserted into the index.
+ <code class="structfield">leafDatum</code> is a value of
+ <code class="structname">spgConfigOut</code>.<code class="structfield">leafType</code>
+ type, which is initially a result of method
+ <code class="function">compress</code> applied to <code class="structfield">datum</code>
+ when method <code class="function">compress</code> is provided, or the same value as
+ <code class="structfield">datum</code> otherwise.
+ <code class="structfield">leafDatum</code> can change at lower levels of the tree
+ if the <code class="function">choose</code> or <code class="function">picksplit</code>
+ methods change it. When the insertion search reaches a leaf page,
+ the current value of <code class="structfield">leafDatum</code> is what will be stored
+ in the newly created leaf tuple.
+ <code class="structfield">level</code> is the current inner tuple's level, starting at
+ zero for the root level.
+ <code class="structfield">allTheSame</code> is true if the current inner tuple is
+ marked as containing multiple equivalent nodes
+ (see <a class="xref" href="spgist-implementation.html#SPGIST-ALL-THE-SAME" title="69.4.3. “All-the-Same” Inner Tuples">Section 69.4.3</a>).
+ <code class="structfield">hasPrefix</code> is true if the current inner tuple contains
+ a prefix; if so,
+ <code class="structfield">prefixDatum</code> is its value.
+ <code class="structfield">nNodes</code> is the number of child nodes contained in the
+ inner tuple, and
+ <code class="structfield">nodeLabels</code> is an array of their label values, or
+ NULL if there are no labels.
+ </p><p>
+ The <code class="function">choose</code> function can determine either that
+ the new value matches one of the existing child nodes, or that a new
+ child node must be added, or that the new value is inconsistent with
+ the tuple prefix and so the inner tuple must be split to create a
+ less restrictive prefix.
+ </p><p>
+ If the new value matches one of the existing child nodes,
+ set <code class="structfield">resultType</code> to <code class="literal">spgMatchNode</code>.
+ Set <code class="structfield">nodeN</code> to the index (from zero) of that node in
+ the node array.
+ Set <code class="structfield">levelAdd</code> to the increment in
+ <code class="structfield">level</code> caused by descending through that node,
+ or leave it as zero if the operator class does not use levels.
+ Set <code class="structfield">restDatum</code> to equal <code class="structfield">leafDatum</code>
+ if the operator class does not modify datums from one level to the
+ next, or otherwise set it to the modified value to be used as
+ <code class="structfield">leafDatum</code> at the next level.
+ </p><p>
+ If a new child node must be added,
+ set <code class="structfield">resultType</code> to <code class="literal">spgAddNode</code>.
+ Set <code class="structfield">nodeLabel</code> to the label to be used for the new
+ node, and set <code class="structfield">nodeN</code> to the index (from zero) at which
+ to insert the node in the node array.
+ After the node has been added, the <code class="function">choose</code>
+ function will be called again with the modified inner tuple;
+ that call should result in an <code class="literal">spgMatchNode</code> result.
+ </p><p>
+ If the new value is inconsistent with the tuple prefix,
+ set <code class="structfield">resultType</code> to <code class="literal">spgSplitTuple</code>.
+ This action moves all the existing nodes into a new lower-level
+ inner tuple, and replaces the existing inner tuple with a tuple
+ having a single downlink pointing to the new lower-level inner tuple.
+ Set <code class="structfield">prefixHasPrefix</code> to indicate whether the new
+ upper tuple should have a prefix, and if so set
+ <code class="structfield">prefixPrefixDatum</code> to the prefix value. This new
+ prefix value must be sufficiently less restrictive than the original
+ to accept the new value to be indexed.
+ Set <code class="structfield">prefixNNodes</code> to the number of nodes needed in the
+ new tuple, and set <code class="structfield">prefixNodeLabels</code> to a palloc'd array
+ holding their labels, or to NULL if node labels are not required.
+ Note that the total size of the new upper tuple must be no more
+ than the total size of the tuple it is replacing; this constrains
+ the lengths of the new prefix and new labels.
+ Set <code class="structfield">childNodeN</code> to the index (from zero) of the node
+ that will downlink to the new lower-level inner tuple.
+ Set <code class="structfield">postfixHasPrefix</code> to indicate whether the new
+ lower-level inner tuple should have a prefix, and if so set
+ <code class="structfield">postfixPrefixDatum</code> to the prefix value. The
+ combination of these two prefixes and the downlink node's label
+ (if any) must have the same meaning as the original prefix, because
+ there is no opportunity to alter the node labels that are moved to
+ the new lower-level tuple, nor to change any child index entries.
+ After the node has been split, the <code class="function">choose</code>
+ function will be called again with the replacement inner tuple.
+ That call may return an <code class="literal">spgAddNode</code> result, if no suitable
+ node was created by the <code class="literal">spgSplitTuple</code> action. Eventually
+ <code class="function">choose</code> must return <code class="literal">spgMatchNode</code> to
+ allow the insertion to descend to the next level.
+ </p></dd><dt><span class="term"><code class="function">picksplit</code></span></dt><dd><p>
+ Decides how to create a new inner tuple over a set of leaf tuples.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+</p><pre class="programlisting">
+CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ...
+</pre><p>
+ The first argument is a pointer to a <code class="structname">spgPickSplitIn</code>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <code class="structname">spgPickSplitOut</code>
+ C struct, which the function must fill with result data.
+</p><pre class="programlisting">
+typedef struct spgPickSplitIn
+{
+ int nTuples; /* number of leaf tuples */
+ Datum *datums; /* their datums (array of length nTuples) */
+ int level; /* current level (counting from zero) */
+} spgPickSplitIn;
+
+typedef struct spgPickSplitOut
+{
+ bool hasPrefix; /* new inner tuple should have a prefix? */
+ Datum prefixDatum; /* if so, its value */
+
+ int nNodes; /* number of nodes for new inner tuple */
+ Datum *nodeLabels; /* their labels (or NULL for no labels) */
+
+ int *mapTuplesToNodes; /* node index for each leaf tuple */
+ Datum *leafTupleDatums; /* datum to store in each new leaf tuple */
+} spgPickSplitOut;
+</pre><p>
+
+ <code class="structfield">nTuples</code> is the number of leaf tuples provided.
+ <code class="structfield">datums</code> is an array of their datum values of
+ <code class="structname">spgConfigOut</code>.<code class="structfield">leafType</code>
+ type.
+ <code class="structfield">level</code> is the current level that all the leaf tuples
+ share, which will become the level of the new inner tuple.
+ </p><p>
+ Set <code class="structfield">hasPrefix</code> to indicate whether the new inner
+ tuple should have a prefix, and if so set
+ <code class="structfield">prefixDatum</code> to the prefix value.
+ Set <code class="structfield">nNodes</code> to indicate the number of nodes that
+ the new inner tuple will contain, and
+ set <code class="structfield">nodeLabels</code> to an array of their label values,
+ or to NULL if node labels are not required.
+ Set <code class="structfield">mapTuplesToNodes</code> to an array that gives the index
+ (from zero) of the node that each leaf tuple should be assigned to.
+ Set <code class="structfield">leafTupleDatums</code> to an array of the values to
+ be stored in the new leaf tuples (these will be the same as the
+ input <code class="structfield">datums</code> if the operator class does not modify
+ datums from one level to the next).
+ Note that the <code class="function">picksplit</code> function is
+ responsible for palloc'ing the
+ <code class="structfield">nodeLabels</code>, <code class="structfield">mapTuplesToNodes</code> and
+ <code class="structfield">leafTupleDatums</code> arrays.
+ </p><p>
+ If more than one leaf tuple is supplied, it is expected that the
+ <code class="function">picksplit</code> function will classify them into more than
+ one node; otherwise it is not possible to split the leaf tuples
+ across multiple pages, which is the ultimate purpose of this
+ operation. Therefore, if the <code class="function">picksplit</code> function
+ ends up placing all the leaf tuples in the same node, the core
+ SP-GiST code will override that decision and generate an inner
+ tuple in which the leaf tuples are assigned at random to several
+ identically-labeled nodes. Such a tuple is marked
+ <code class="literal">allTheSame</code> to signify that this has happened. The
+ <code class="function">choose</code> and <code class="function">inner_consistent</code> functions
+ must take suitable care with such inner tuples.
+ See <a class="xref" href="spgist-implementation.html#SPGIST-ALL-THE-SAME" title="69.4.3. “All-the-Same” Inner Tuples">Section 69.4.3</a> for more information.
+ </p><p>
+ <code class="function">picksplit</code> can be applied to a single leaf tuple only
+ in the case that the <code class="function">config</code> function set
+ <code class="structfield">longValuesOK</code> to true and a larger-than-a-page input
+ value has been supplied. In this case the point of the operation is
+ to strip off a prefix and produce a new, shorter leaf datum value.
+ The call will be repeated until a leaf datum short enough to fit on
+ a page has been produced. See <a class="xref" href="spgist-implementation.html#SPGIST-LIMITS" title="69.4.1. SP-GiST Limits">Section 69.4.1</a> for
+ more information.
+ </p></dd><dt><span class="term"><code class="function">inner_consistent</code></span></dt><dd><p>
+ Returns set of nodes (branches) to follow during tree search.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+</p><pre class="programlisting">
+CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ...
+</pre><p>
+ The first argument is a pointer to a <code class="structname">spgInnerConsistentIn</code>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <code class="structname">spgInnerConsistentOut</code>
+ C struct, which the function must fill with result data.
+
+</p><pre class="programlisting">
+typedef struct spgInnerConsistentIn
+{
+ ScanKey scankeys; /* array of operators and comparison values */
+ ScanKey orderbys; /* array of ordering operators and comparison
+ * values */
+ int nkeys; /* length of scankeys array */
+ int norderbys; /* length of orderbys array */
+
+ Datum reconstructedValue; /* value reconstructed at parent */
+ void *traversalValue; /* opclass-specific traverse value */
+ MemoryContext traversalMemoryContext; /* put new traverse values here */
+ int level; /* current level (counting from zero) */
+ bool returnData; /* original data must be returned? */
+
+ /* Data from current inner tuple */
+ bool allTheSame; /* tuple is marked all-the-same? */
+ bool hasPrefix; /* tuple has a prefix? */
+ Datum prefixDatum; /* if so, the prefix value */
+ int nNodes; /* number of nodes in the inner tuple */
+ Datum *nodeLabels; /* node label values (NULL if none) */
+} spgInnerConsistentIn;
+
+typedef struct spgInnerConsistentOut
+{
+ int nNodes; /* number of child nodes to be visited */
+ int *nodeNumbers; /* their indexes in the node array */
+ int *levelAdds; /* increment level by this much for each */
+ Datum *reconstructedValues; /* associated reconstructed values */
+ void **traversalValues; /* opclass-specific traverse values */
+ double **distances; /* associated distances */
+} spgInnerConsistentOut;
+</pre><p>
+
+ The array <code class="structfield">scankeys</code>, of length <code class="structfield">nkeys</code>,
+ describes the index search condition(s). These conditions are
+ combined with AND — only index entries that satisfy all of
+ them are interesting. (Note that <code class="structfield">nkeys</code> = 0 implies
+ that all index entries satisfy the query.) Usually the consistent
+ function only cares about the <code class="structfield">sk_strategy</code> and
+ <code class="structfield">sk_argument</code> fields of each array entry, which
+ respectively give the indexable operator and comparison value.
+ In particular it is not necessary to check <code class="structfield">sk_flags</code> to
+ see if the comparison value is NULL, because the SP-GiST core code
+ will filter out such conditions.
+ The array <code class="structfield">orderbys</code>, of length <code class="structfield">norderbys</code>,
+ describes ordering operators (if any) in the same manner.
+ <code class="structfield">reconstructedValue</code> is the value reconstructed for the
+ parent tuple; it is <code class="literal">(Datum) 0</code> at the root level or if the
+ <code class="function">inner_consistent</code> function did not provide a value at the
+ parent level.
+ <code class="structfield">traversalValue</code> is a pointer to any traverse data
+ passed down from the previous call of <code class="function">inner_consistent</code>
+ on the parent index tuple, or NULL at the root level.
+ <code class="structfield">traversalMemoryContext</code> is the memory context in which
+ to store output traverse values (see below).
+ <code class="structfield">level</code> is the current inner tuple's level, starting at
+ zero for the root level.
+ <code class="structfield">returnData</code> is <code class="literal">true</code> if reconstructed data is
+ required for this query; this will only be so if the
+ <code class="function">config</code> function asserted <code class="structfield">canReturnData</code>.
+ <code class="structfield">allTheSame</code> is true if the current inner tuple is
+ marked <span class="quote">“<span class="quote">all-the-same</span>”</span>; in this case all the nodes have the
+ same label (if any) and so either all or none of them match the query
+ (see <a class="xref" href="spgist-implementation.html#SPGIST-ALL-THE-SAME" title="69.4.3. “All-the-Same” Inner Tuples">Section 69.4.3</a>).
+ <code class="structfield">hasPrefix</code> is true if the current inner tuple contains
+ a prefix; if so,
+ <code class="structfield">prefixDatum</code> is its value.
+ <code class="structfield">nNodes</code> is the number of child nodes contained in the
+ inner tuple, and
+ <code class="structfield">nodeLabels</code> is an array of their label values, or
+ NULL if the nodes do not have labels.
+ </p><p>
+ <code class="structfield">nNodes</code> must be set to the number of child nodes that
+ need to be visited by the search, and
+ <code class="structfield">nodeNumbers</code> must be set to an array of their indexes.
+ If the operator class keeps track of levels, set
+ <code class="structfield">levelAdds</code> to an array of the level increments
+ required when descending to each node to be visited. (Often these
+ increments will be the same for all the nodes, but that's not
+ necessarily so, so an array is used.)
+ If value reconstruction is needed, set
+ <code class="structfield">reconstructedValues</code> to an array of the values
+ reconstructed for each child node to be visited; otherwise, leave
+ <code class="structfield">reconstructedValues</code> as NULL.
+ The reconstructed values are assumed to be of type
+ <code class="structname">spgConfigOut</code>.<code class="structfield">leafType</code>.
+ (However, since the core system will do nothing with them except
+ possibly copy them, it is sufficient for them to have the
+ same <code class="literal">typlen</code> and <code class="literal">typbyval</code>
+ properties as <code class="structfield">leafType</code>.)
+ If ordered search is performed, set <code class="structfield">distances</code>
+ to an array of distance values according to <code class="structfield">orderbys</code>
+ array (nodes with lowest distances will be processed first). Leave it
+ NULL otherwise.
+ If it is desired to pass down additional out-of-band information
+ (<span class="quote">“<span class="quote">traverse values</span>”</span>) to lower levels of the tree search,
+ set <code class="structfield">traversalValues</code> to an array of the appropriate
+ traverse values, one for each child node to be visited; otherwise,
+ leave <code class="structfield">traversalValues</code> as NULL.
+ Note that the <code class="function">inner_consistent</code> function is
+ responsible for palloc'ing the
+ <code class="structfield">nodeNumbers</code>, <code class="structfield">levelAdds</code>,
+ <code class="structfield">distances</code>,
+ <code class="structfield">reconstructedValues</code>, and
+ <code class="structfield">traversalValues</code> arrays in the current memory context.
+ However, any output traverse values pointed to by
+ the <code class="structfield">traversalValues</code> array should be allocated
+ in <code class="structfield">traversalMemoryContext</code>.
+ Each traverse value must be a single palloc'd chunk.
+ </p></dd><dt><span class="term"><code class="function">leaf_consistent</code></span></dt><dd><p>
+ Returns true if a leaf tuple satisfies a query.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+</p><pre class="programlisting">
+CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ...
+</pre><p>
+ The first argument is a pointer to a <code class="structname">spgLeafConsistentIn</code>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <code class="structname">spgLeafConsistentOut</code>
+ C struct, which the function must fill with result data.
+</p><pre class="programlisting">
+typedef struct spgLeafConsistentIn
+{
+ ScanKey scankeys; /* array of operators and comparison values */
+ ScanKey orderbys; /* array of ordering operators and comparison
+ * values */
+ int nkeys; /* length of scankeys array */
+ int norderbys; /* length of orderbys array */
+
+ Datum reconstructedValue; /* value reconstructed at parent */
+ void *traversalValue; /* opclass-specific traverse value */
+ int level; /* current level (counting from zero) */
+ bool returnData; /* original data must be returned? */
+
+ Datum leafDatum; /* datum in leaf tuple */
+} spgLeafConsistentIn;
+
+typedef struct spgLeafConsistentOut
+{
+ Datum leafValue; /* reconstructed original data, if any */
+ bool recheck; /* set true if operator must be rechecked */
+ bool recheckDistances; /* set true if distances must be rechecked */
+ double *distances; /* associated distances */
+} spgLeafConsistentOut;
+</pre><p>
+
+ The array <code class="structfield">scankeys</code>, of length <code class="structfield">nkeys</code>,
+ describes the index search condition(s). These conditions are
+ combined with AND — only index entries that satisfy all of
+ them satisfy the query. (Note that <code class="structfield">nkeys</code> = 0 implies
+ that all index entries satisfy the query.) Usually the consistent
+ function only cares about the <code class="structfield">sk_strategy</code> and
+ <code class="structfield">sk_argument</code> fields of each array entry, which
+ respectively give the indexable operator and comparison value.
+ In particular it is not necessary to check <code class="structfield">sk_flags</code> to
+ see if the comparison value is NULL, because the SP-GiST core code
+ will filter out such conditions.
+ The array <code class="structfield">orderbys</code>, of length <code class="structfield">norderbys</code>,
+ describes the ordering operators in the same manner.
+ <code class="structfield">reconstructedValue</code> is the value reconstructed for the
+ parent tuple; it is <code class="literal">(Datum) 0</code> at the root level or if the
+ <code class="function">inner_consistent</code> function did not provide a value at the
+ parent level.
+ <code class="structfield">traversalValue</code> is a pointer to any traverse data
+ passed down from the previous call of <code class="function">inner_consistent</code>
+ on the parent index tuple, or NULL at the root level.
+ <code class="structfield">level</code> is the current leaf tuple's level, starting at
+ zero for the root level.
+ <code class="structfield">returnData</code> is <code class="literal">true</code> if reconstructed data is
+ required for this query; this will only be so if the
+ <code class="function">config</code> function asserted <code class="structfield">canReturnData</code>.
+ <code class="structfield">leafDatum</code> is the key value of
+ <code class="structname">spgConfigOut</code>.<code class="structfield">leafType</code>
+ stored in the current leaf tuple.
+ </p><p>
+ The function must return <code class="literal">true</code> if the leaf tuple matches the
+ query, or <code class="literal">false</code> if not. In the <code class="literal">true</code> case,
+ if <code class="structfield">returnData</code> is <code class="literal">true</code> then
+ <code class="structfield">leafValue</code> must be set to the value (of type
+ <code class="structname">spgConfigIn</code>.<code class="structfield">attType</code>)
+ originally supplied to be indexed for this leaf tuple. Also,
+ <code class="structfield">recheck</code> may be set to <code class="literal">true</code> if the match
+ is uncertain and so the operator(s) must be re-applied to the actual
+ heap tuple to verify the match.
+ If ordered search is performed, set <code class="structfield">distances</code>
+ to an array of distance values according to <code class="structfield">orderbys</code>
+ array. Leave it NULL otherwise. If at least one of returned distances
+ is not exact, set <code class="structfield">recheckDistances</code> to true.
+ In this case, the executor will calculate the exact distances after
+ fetching the tuple from the heap, and will reorder the tuples if needed.
+ </p></dd></dl></div><p>
+ The optional user-defined methods are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="function">Datum compress(Datum in)</code></span></dt><dd><p>
+ Converts a data item into a format suitable for physical storage in
+ a leaf tuple of the index. It accepts a value of type
+ <code class="structname">spgConfigIn</code>.<code class="structfield">attType</code>
+ and returns a value of type
+ <code class="structname">spgConfigOut</code>.<code class="structfield">leafType</code>.
+ The output value must not contain an out-of-line TOAST pointer.
+ </p><p>
+ Note: the <code class="function">compress</code> method is only applied to
+ values to be stored. The consistent methods receive query
+ <code class="structfield">scankeys</code> unchanged, without transformation
+ using <code class="function">compress</code>.
+ </p></dd><dt><span class="term"><code class="function">options</code></span></dt><dd><p>
+ Defines a set of user-visible parameters that control operator class
+ behavior.
+ </p><p>
+ The <acronym class="acronym">SQL</acronym> declaration of the function must look like this:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION my_options(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</pre><p>
+ </p><p>
+ The function is passed a pointer to a <code class="structname">local_relopts</code>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using the <code class="literal">PG_HAS_OPCLASS_OPTIONS()</code> and
+ <code class="literal">PG_GET_OPCLASS_OPTIONS()</code> macros.
+ </p><p>
+ Since the representation of the key in <acronym class="acronym">SP-GiST</acronym> is
+ flexible, it may depend on user-specified parameters.
+ </p></dd></dl></div><p>
+ All the SP-GiST support methods are normally called in a short-lived
+ memory context; that is, <code class="varname">CurrentMemoryContext</code> will be reset
+ after processing of each tuple. It is therefore not very important to
+ worry about pfree'ing everything you palloc. (The <code class="function">config</code>
+ method is an exception: it should try to avoid leaking memory. But
+ usually the <code class="function">config</code> method need do nothing but assign
+ constants into the passed parameter struct.)
+ </p><p>
+ If the indexed column is of a collatable data type, the index collation
+ will be passed to all the support methods, using the standard
+ <code class="function">PG_GET_COLLATION()</code> mechanism.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spgist-builtin-opclasses.html" title="69.2. Built-in Operator Classes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spgist-implementation.html" title="69.4. Implementation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">69.2. Built-in Operator Classes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 69.4. Implementation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spgist-implementation.html b/doc/src/sgml/html/spgist-implementation.html
new file mode 100644
index 0000000..103fb6a
--- /dev/null
+++ b/doc/src/sgml/html/spgist-implementation.html
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>69.4. Implementation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spgist-extensibility.html" title="69.3. Extensibility" /><link rel="next" href="spgist-examples.html" title="69.5. Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">69.4. Implementation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spgist-extensibility.html" title="69.3. Extensibility">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 69. SP-GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spgist-examples.html" title="69.5. Examples">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPGIST-IMPLEMENTATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">69.4. Implementation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="spgist-implementation.html#SPGIST-LIMITS">69.4.1. SP-GiST Limits</a></span></dt><dt><span class="sect2"><a href="spgist-implementation.html#SPGIST-NULL-LABELS">69.4.2. SP-GiST Without Node Labels</a></span></dt><dt><span class="sect2"><a href="spgist-implementation.html#SPGIST-ALL-THE-SAME">69.4.3. <span class="quote">“<span class="quote">All-the-Same</span>”</span> Inner Tuples</a></span></dt></dl></div><p>
+ This section covers implementation details and other tricks that are
+ useful for implementers of <acronym class="acronym">SP-GiST</acronym> operator classes to
+ know.
+ </p><div class="sect2" id="SPGIST-LIMITS"><div class="titlepage"><div><div><h3 class="title">69.4.1. SP-GiST Limits</h3></div></div></div><p>
+ Individual leaf tuples and inner tuples must fit on a single index page
+ (8kB by default). Therefore, when indexing values of variable-length
+ data types, long values can only be supported by methods such as radix
+ trees, in which each level of the tree includes a prefix that is short
+ enough to fit on a page, and the final leaf level includes a suffix also
+ short enough to fit on a page. The operator class should set
+ <code class="structfield">longValuesOK</code> to true only if it is prepared to arrange for
+ this to happen. Otherwise, the <acronym class="acronym">SP-GiST</acronym> core will
+ reject any request to index a value that is too large to fit
+ on an index page.
+ </p><p>
+ Likewise, it is the operator class's responsibility that inner tuples
+ do not grow too large to fit on an index page; this limits the number
+ of child nodes that can be used in one inner tuple, as well as the
+ maximum size of a prefix value.
+ </p><p>
+ Another limitation is that when an inner tuple's node points to a set
+ of leaf tuples, those tuples must all be in the same index page.
+ (This is a design decision to reduce seeking and save space in the
+ links that chain such tuples together.) If the set of leaf tuples
+ grows too large for a page, a split is performed and an intermediate
+ inner tuple is inserted. For this to fix the problem, the new inner
+ tuple <span class="emphasis"><em>must</em></span> divide the set of leaf values into more than one
+ node group. If the operator class's <code class="function">picksplit</code> function
+ fails to do that, the <acronym class="acronym">SP-GiST</acronym> core resorts to
+ extraordinary measures described in <a class="xref" href="spgist-implementation.html#SPGIST-ALL-THE-SAME" title="69.4.3. “All-the-Same” Inner Tuples">Section 69.4.3</a>.
+ </p><p>
+ When <code class="structfield">longValuesOK</code> is true, it is expected
+ that successive levels of the <acronym class="acronym">SP-GiST</acronym> tree will
+ absorb more and more information into the prefixes and node labels of
+ the inner tuples, making the required leaf datum smaller and smaller,
+ so that eventually it will fit on a page.
+ To prevent bugs in operator classes from causing infinite insertion
+ loops, the <acronym class="acronym">SP-GiST</acronym> core will raise an error if the
+ leaf datum does not become any smaller within ten cycles
+ of <code class="function">choose</code> method calls.
+ </p></div><div class="sect2" id="SPGIST-NULL-LABELS"><div class="titlepage"><div><div><h3 class="title">69.4.2. SP-GiST Without Node Labels</h3></div></div></div><p>
+ Some tree algorithms use a fixed set of nodes for each inner tuple;
+ for example, in a quad-tree there are always exactly four nodes
+ corresponding to the four quadrants around the inner tuple's centroid
+ point. In such a case the code typically works with the nodes by
+ number, and there is no need for explicit node labels. To suppress
+ node labels (and thereby save some space), the <code class="function">picksplit</code>
+ function can return NULL for the <code class="structfield">nodeLabels</code> array,
+ and likewise the <code class="function">choose</code> function can return NULL for
+ the <code class="structfield">prefixNodeLabels</code> array during
+ a <code class="literal">spgSplitTuple</code> action.
+ This will in turn result in <code class="structfield">nodeLabels</code> being NULL during
+ subsequent calls to <code class="function">choose</code> and <code class="function">inner_consistent</code>.
+ In principle, node labels could be used for some inner tuples and omitted
+ for others in the same index.
+ </p><p>
+ When working with an inner tuple having unlabeled nodes, it is an error
+ for <code class="function">choose</code> to return <code class="literal">spgAddNode</code>, since the set
+ of nodes is supposed to be fixed in such cases.
+ </p></div><div class="sect2" id="SPGIST-ALL-THE-SAME"><div class="titlepage"><div><div><h3 class="title">69.4.3. <span class="quote">“<span class="quote">All-the-Same</span>”</span> Inner Tuples</h3></div></div></div><p>
+ The <acronym class="acronym">SP-GiST</acronym> core can override the results of the
+ operator class's <code class="function">picksplit</code> function when
+ <code class="function">picksplit</code> fails to divide the supplied leaf values into
+ at least two node categories. When this happens, the new inner tuple
+ is created with multiple nodes that each have the same label (if any)
+ that <code class="function">picksplit</code> gave to the one node it did use, and the
+ leaf values are divided at random among these equivalent nodes.
+ The <code class="literal">allTheSame</code> flag is set on the inner tuple to warn the
+ <code class="function">choose</code> and <code class="function">inner_consistent</code> functions that the
+ tuple does not have the node set that they might otherwise expect.
+ </p><p>
+ When dealing with an <code class="literal">allTheSame</code> tuple, a <code class="function">choose</code>
+ result of <code class="literal">spgMatchNode</code> is interpreted to mean that the new
+ value can be assigned to any of the equivalent nodes; the core code will
+ ignore the supplied <code class="structfield">nodeN</code> value and descend into one
+ of the nodes at random (so as to keep the tree balanced). It is an
+ error for <code class="function">choose</code> to return <code class="literal">spgAddNode</code>, since
+ that would make the nodes not all equivalent; the
+ <code class="literal">spgSplitTuple</code> action must be used if the value to be inserted
+ doesn't match the existing nodes.
+ </p><p>
+ When dealing with an <code class="literal">allTheSame</code> tuple, the
+ <code class="function">inner_consistent</code> function should return either all or none
+ of the nodes as targets for continuing the index search, since they are
+ all equivalent. This may or may not require any special-case code,
+ depending on how much the <code class="function">inner_consistent</code> function normally
+ assumes about the meaning of the nodes.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spgist-extensibility.html" title="69.3. Extensibility">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spgist-examples.html" title="69.5. Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">69.3. Extensibility </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 69.5. Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spgist-intro.html b/doc/src/sgml/html/spgist-intro.html
new file mode 100644
index 0000000..15f5ff5
--- /dev/null
+++ b/doc/src/sgml/html/spgist-intro.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>69.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spgist.html" title="Chapter 69. SP-GiST Indexes" /><link rel="next" href="spgist-builtin-opclasses.html" title="69.2. Built-in Operator Classes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">69.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><th width="60%" align="center">Chapter 69. SP-GiST Indexes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spgist-builtin-opclasses.html" title="69.2. Built-in Operator Classes">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPGIST-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">69.1. Introduction</h2></div></div></div><p>
+ <acronym class="acronym">SP-GiST</acronym> is an abbreviation for space-partitioned
+ <acronym class="acronym">GiST</acronym>. <acronym class="acronym">SP-GiST</acronym> supports partitioned
+ search trees, which facilitate development of a wide range of different
+ non-balanced data structures, such as quad-trees, k-d trees, and radix
+ trees (tries). The common feature of these structures is that they
+ repeatedly divide the search space into partitions that need not be
+ of equal size. Searches that are well matched to the partitioning rule
+ can be very fast.
+ </p><p>
+ These popular data structures were originally developed for in-memory
+ usage. In main memory, they are usually designed as a set of dynamically
+ allocated nodes linked by pointers. This is not suitable for direct
+ storing on disk, since these chains of pointers can be rather long which
+ would require too many disk accesses. In contrast, disk-based data
+ structures should have a high fanout to minimize I/O. The challenge
+ addressed by <acronym class="acronym">SP-GiST</acronym> is to map search tree nodes to
+ disk pages in such a way that a search need access only a few disk pages,
+ even if it traverses many nodes.
+ </p><p>
+ Like <acronym class="acronym">GiST</acronym>, <acronym class="acronym">SP-GiST</acronym> is meant to allow
+ the development of custom data types with the appropriate access methods,
+ by an expert in the domain of the data type, rather than a database expert.
+ </p><p>
+ Some of the information here is derived from Purdue University's
+ SP-GiST Indexing Project
+ <a class="ulink" href="https://www.cs.purdue.edu/spgist/" target="_top">web site</a>.
+ The <acronym class="acronym">SP-GiST</acronym> implementation in
+ <span class="productname">PostgreSQL</span> is primarily maintained by Teodor
+ Sigaev and Oleg Bartunov, and there is more information on their
+
+ <a class="ulink" href="http://www.sai.msu.su/~megera/wiki/spgist_dev" target="_top">web site</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spgist-builtin-opclasses.html" title="69.2. Built-in Operator Classes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 69. SP-GiST Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 69.2. Built-in Operator Classes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spgist.html b/doc/src/sgml/html/spgist.html
new file mode 100644
index 0000000..1d3e4ee
--- /dev/null
+++ b/doc/src/sgml/html/spgist.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 69. SP-GiST Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gist-examples.html" title="68.5. Examples" /><link rel="next" href="spgist-intro.html" title="69.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 69. SP-GiST Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gist-examples.html" title="68.5. Examples">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spgist-intro.html" title="69.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="SPGIST"><div class="titlepage"><div><div><h2 class="title">Chapter 69. SP-GiST Indexes</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="spgist-intro.html">69.1. Introduction</a></span></dt><dt><span class="sect1"><a href="spgist-builtin-opclasses.html">69.2. Built-in Operator Classes</a></span></dt><dt><span class="sect1"><a href="spgist-extensibility.html">69.3. Extensibility</a></span></dt><dt><span class="sect1"><a href="spgist-implementation.html">69.4. Implementation</a></span></dt><dd><dl><dt><span class="sect2"><a href="spgist-implementation.html#SPGIST-LIMITS">69.4.1. SP-GiST Limits</a></span></dt><dt><span class="sect2"><a href="spgist-implementation.html#SPGIST-NULL-LABELS">69.4.2. SP-GiST Without Node Labels</a></span></dt><dt><span class="sect2"><a href="spgist-implementation.html#SPGIST-ALL-THE-SAME">69.4.3. <span class="quote">“<span class="quote">All-the-Same</span>”</span> Inner Tuples</a></span></dt></dl></dd><dt><span class="sect1"><a href="spgist-examples.html">69.5. Examples</a></span></dt></dl></div><a id="id-1.10.20.2" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gist-examples.html" title="68.5. Examples">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spgist-intro.html" title="69.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.5. Examples </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 69.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-examples.html b/doc/src/sgml/html/spi-examples.html
new file mode 100644
index 0000000..6214bcb
--- /dev/null
+++ b/doc/src/sgml/html/spi-examples.html
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>47.6. Examples</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-visibility.html" title="47.5. Visibility of Data Changes" /><link rel="next" href="bgworker.html" title="Chapter 48. Background Worker Processes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">47.6. Examples</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-visibility.html" title="47.5. Visibility of Data Changes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><th width="60%" align="center">Chapter 47. Server Programming Interface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bgworker.html" title="Chapter 48. Background Worker Processes">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPI-EXAMPLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">47.6. Examples</h2></div></div></div><p>
+ This section contains a very simple example of SPI usage. The
+ C function <code class="function">execq</code> takes an SQL command as its
+ first argument and a row count as its second, executes the command
+ using <code class="function">SPI_exec</code> and returns the number of rows
+ that were processed by the command. You can find more complex
+ examples for SPI in the source tree in
+ <code class="filename">src/test/regress/regress.c</code> and in the
+ <a class="xref" href="contrib-spi.html" title="F.41. spi">spi</a> module.
+ </p><pre class="programlisting">
+#include "postgres.h"
+
+#include "executor/spi.h"
+#include "utils/builtins.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(execq);
+
+Datum
+execq(PG_FUNCTION_ARGS)
+{
+ char *command;
+ int cnt;
+ int ret;
+ uint64 proc;
+
+ /* Convert given text object to a C string */
+ command = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ cnt = PG_GETARG_INT32(1);
+
+ SPI_connect();
+
+ ret = SPI_exec(command, cnt);
+
+ proc = SPI_processed;
+
+ /*
+ * If some rows were fetched, print them via elog(INFO).
+ */
+ if (ret &gt; 0 &amp;&amp; SPI_tuptable != NULL)
+ {
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable-&gt;tupdesc;
+ char buf[8192];
+ uint64 j;
+
+ for (j = 0; j &lt; tuptable-&gt;numvals; j++)
+ {
+ HeapTuple tuple = tuptable-&gt;vals[j];
+ int i;
+
+ for (i = 1, buf[0] = 0; i &lt;= tupdesc-&gt;natts; i++)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s%s",
+ SPI_getvalue(tuple, tupdesc, i),
+ (i == tupdesc-&gt;natts) ? " " : " |");
+ elog(INFO, "EXECQ: %s", buf);
+ }
+ }
+
+ SPI_finish();
+ pfree(command);
+
+ PG_RETURN_INT64(proc);
+}
+</pre><p>
+ This is how you declare the function after having compiled it into
+ a shared library (details are in <a class="xref" href="xfunc-c.html#DFUNC" title="38.10.5. Compiling and Linking Dynamically-Loaded Functions">Section 38.10.5</a>.):
+
+</p><pre class="programlisting">
+CREATE FUNCTION execq(text, integer) RETURNS int8
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C STRICT;
+</pre><p>
+ </p><p>
+ Here is a sample session:
+
+</p><pre class="programlisting">
+=&gt; SELECT execq('CREATE TABLE a (x integer)', 0);
+ execq
+-------
+ 0
+(1 row)
+
+=&gt; INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
+INSERT 0 1
+=&gt; SELECT execq('SELECT * FROM a', 0);
+INFO: EXECQ: 0 <em class="lineannotation"><span class="lineannotation">-- inserted by execq</span></em>
+INFO: EXECQ: 1 <em class="lineannotation"><span class="lineannotation">-- returned by execq and inserted by upper INSERT</span></em>
+
+ execq
+-------
+ 2
+(1 row)
+
+=&gt; SELECT execq('INSERT INTO a SELECT x + 2 FROM a RETURNING *', 1);
+INFO: EXECQ: 2 <em class="lineannotation"><span class="lineannotation">-- 0 + 2, then execution was stopped by count</span></em>
+ execq
+-------
+ 1
+(1 row)
+
+=&gt; SELECT execq('SELECT * FROM a', 10);
+INFO: EXECQ: 0
+INFO: EXECQ: 1
+INFO: EXECQ: 2
+
+ execq
+-------
+ 3 <em class="lineannotation"><span class="lineannotation">-- 10 is the max value only, 3 is the real number of rows</span></em>
+(1 row)
+
+=&gt; SELECT execq('INSERT INTO a SELECT x + 10 FROM a', 1);
+ execq
+-------
+ 3 <em class="lineannotation"><span class="lineannotation">-- all rows processed; count does not stop it, because nothing is returned</span></em>
+(1 row)
+
+=&gt; SELECT * FROM a;
+ x
+----
+ 0
+ 1
+ 2
+ 10
+ 11
+ 12
+(6 rows)
+
+=&gt; DELETE FROM a;
+DELETE 6
+=&gt; INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
+INSERT 0 1
+=&gt; SELECT * FROM a;
+ x
+---
+ 1 <em class="lineannotation"><span class="lineannotation">-- 0 (no rows in a) + 1</span></em>
+(1 row)
+
+=&gt; INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
+INFO: EXECQ: 1
+INSERT 0 1
+=&gt; SELECT * FROM a;
+ x
+---
+ 1
+ 2 <em class="lineannotation"><span class="lineannotation">-- 1 (there was one row in a) + 1</span></em>
+(2 rows)
+
+<em class="lineannotation"><span class="lineannotation">-- This demonstrates the data changes visibility rule.</span></em>
+<em class="lineannotation"><span class="lineannotation">-- execq is called twice and sees different numbers of rows each time:</span></em>
+
+=&gt; INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
+INFO: EXECQ: 1 <em class="lineannotation"><span class="lineannotation">-- results from first execq</span></em>
+INFO: EXECQ: 2
+INFO: EXECQ: 1 <em class="lineannotation"><span class="lineannotation">-- results from second execq</span></em>
+INFO: EXECQ: 2
+INFO: EXECQ: 2
+INSERT 0 2
+=&gt; SELECT * FROM a;
+ x
+---
+ 1
+ 2
+ 2 <em class="lineannotation"><span class="lineannotation">-- 2 rows * 1 (x in first row)</span></em>
+ 6 <em class="lineannotation"><span class="lineannotation">-- 3 rows (2 + 1 just inserted) * 2 (x in second row)</span></em>
+(4 rows)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-visibility.html" title="47.5. Visibility of Data Changes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bgworker.html" title="Chapter 48. Background Worker Processes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">47.5. Visibility of Data Changes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 48. Background Worker Processes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-interface-support.html b/doc/src/sgml/html/spi-interface-support.html
new file mode 100644
index 0000000..02e3e2c
--- /dev/null
+++ b/doc/src/sgml/html/spi-interface-support.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>47.2. Interface Support Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data" /><link rel="next" href="spi-spi-fname.html" title="SPI_fname" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">47.2. Interface Support Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><th width="60%" align="center">Chapter 47. Server Programming Interface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-fname.html" title="SPI_fname">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPI-INTERFACE-SUPPORT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">47.2. Interface Support Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="spi-spi-fname.html">SPI_fname</a></span><span class="refpurpose"> — determine the column name for the specified column number</span></dt><dt><span class="refentrytitle"><a href="spi-spi-fnumber.html">SPI_fnumber</a></span><span class="refpurpose"> — determine the column number for the specified column name</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getvalue.html">SPI_getvalue</a></span><span class="refpurpose"> — return the string value of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getbinval.html">SPI_getbinval</a></span><span class="refpurpose"> — return the binary value of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-gettype.html">SPI_gettype</a></span><span class="refpurpose"> — return the data type name of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-gettypeid.html">SPI_gettypeid</a></span><span class="refpurpose"> — return the data type <acronym class="acronym">OID</acronym> of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getrelname.html">SPI_getrelname</a></span><span class="refpurpose"> — return the name of the specified relation</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getnspname.html">SPI_getnspname</a></span><span class="refpurpose"> — return the namespace of the specified relation</span></dt><dt><span class="refentrytitle"><a href="spi-spi-result-code-string.html">SPI_result_code_string</a></span><span class="refpurpose"> — return error code as string</span></dt></dl></div><p>
+ The functions described here provide an interface for extracting
+ information from result sets returned by <code class="function">SPI_execute</code> and
+ other SPI functions.
+ </p><p>
+ All functions described in this section can be used by both
+ connected and unconnected C functions.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-fname.html" title="SPI_fname">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_register_trigger_data </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_fname</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-interface.html b/doc/src/sgml/html/spi-interface.html
new file mode 100644
index 0000000..9e6f704
--- /dev/null
+++ b/doc/src/sgml/html/spi-interface.html
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>47.1. Interface Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi.html" title="Chapter 47. Server Programming Interface" /><link rel="next" href="spi-spi-connect.html" title="SPI_connect" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">47.1. Interface Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi.html" title="Chapter 47. Server Programming Interface">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><th width="60%" align="center">Chapter 47. Server Programming Interface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-connect.html" title="SPI_connect">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPI-INTERFACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">47.1. Interface Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="spi-spi-connect.html">SPI_connect</a></span><span class="refpurpose"> — connect a C function to the SPI manager</span></dt><dt><span class="refentrytitle"><a href="spi-spi-finish.html">SPI_finish</a></span><span class="refpurpose"> — disconnect a C function from the SPI manager</span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute.html">SPI_execute</a></span><span class="refpurpose"> — execute a command</span></dt><dt><span class="refentrytitle"><a href="spi-spi-exec.html">SPI_exec</a></span><span class="refpurpose"> — execute a read/write command</span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-extended.html">SPI_execute_extended</a></span><span class="refpurpose"> — execute a command with out-of-line parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-with-args.html">SPI_execute_with_args</a></span><span class="refpurpose"> — execute a command with out-of-line parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare.html">SPI_prepare</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare-cursor.html">SPI_prepare_cursor</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare-extended.html">SPI_prepare_extended</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare-params.html">SPI_prepare_params</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getargcount.html">SPI_getargcount</a></span><span class="refpurpose"> — return the number of arguments needed by a statement
+ prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-getargtypeid.html">SPI_getargtypeid</a></span><span class="refpurpose"> — return the data type OID for an argument of
+ a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-is-cursor-plan.html">SPI_is_cursor_plan</a></span><span class="refpurpose"> — return <code class="symbol">true</code> if a statement
+ prepared by <code class="function">SPI_prepare</code> can be used with
+ <code class="function">SPI_cursor_open</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-plan.html">SPI_execute_plan</a></span><span class="refpurpose"> — execute a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-plan-extended.html">SPI_execute_plan_extended</a></span><span class="refpurpose"> — execute a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-plan-with-paramlist.html">SPI_execute_plan_with_paramlist</a></span><span class="refpurpose"> — execute a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execp.html">SPI_execp</a></span><span class="refpurpose"> — execute a statement in read/write mode</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-open.html">SPI_cursor_open</a></span><span class="refpurpose"> — set up a cursor using a statement created with <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-open-with-args.html">SPI_cursor_open_with_args</a></span><span class="refpurpose"> — set up a cursor using a query and parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-open-with-paramlist.html">SPI_cursor_open_with_paramlist</a></span><span class="refpurpose"> — set up a cursor using parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-parse-open.html">SPI_cursor_parse_open</a></span><span class="refpurpose"> — set up a cursor using a query string and parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-find.html">SPI_cursor_find</a></span><span class="refpurpose"> — find an existing cursor by name</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-fetch.html">SPI_cursor_fetch</a></span><span class="refpurpose"> — fetch some rows from a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-move.html">SPI_cursor_move</a></span><span class="refpurpose"> — move a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-scroll-cursor-fetch.html">SPI_scroll_cursor_fetch</a></span><span class="refpurpose"> — fetch some rows from a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-scroll-cursor-move.html">SPI_scroll_cursor_move</a></span><span class="refpurpose"> — move a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-close.html">SPI_cursor_close</a></span><span class="refpurpose"> — close a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-keepplan.html">SPI_keepplan</a></span><span class="refpurpose"> — save a prepared statement</span></dt><dt><span class="refentrytitle"><a href="spi-spi-saveplan.html">SPI_saveplan</a></span><span class="refpurpose"> — save a prepared statement</span></dt><dt><span class="refentrytitle"><a href="spi-spi-register-relation.html">SPI_register_relation</a></span><span class="refpurpose"> — make an ephemeral named relation available by name in SPI queries</span></dt><dt><span class="refentrytitle"><a href="spi-spi-unregister-relation.html">SPI_unregister_relation</a></span><span class="refpurpose"> — remove an ephemeral named relation from the registry</span></dt><dt><span class="refentrytitle"><a href="spi-spi-register-trigger-data.html">SPI_register_trigger_data</a></span><span class="refpurpose"> — make ephemeral trigger data available in SPI queries</span></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi.html" title="Chapter 47. Server Programming Interface">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-connect.html" title="SPI_connect">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 47. Server Programming Interface </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_connect</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-memory.html b/doc/src/sgml/html/spi-memory.html
new file mode 100644
index 0000000..9ab7b91
--- /dev/null
+++ b/doc/src/sgml/html/spi-memory.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>47.3. Memory Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-result-code-string.html" title="SPI_result_code_string" /><link rel="next" href="spi-spi-palloc.html" title="SPI_palloc" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">47.3. Memory Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-result-code-string.html" title="SPI_result_code_string">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><th width="60%" align="center">Chapter 47. Server Programming Interface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-palloc.html" title="SPI_palloc">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPI-MEMORY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">47.3. Memory Management</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="spi-spi-palloc.html">SPI_palloc</a></span><span class="refpurpose"> — allocate memory in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-realloc.html">SPI_repalloc</a></span><span class="refpurpose"> — reallocate memory in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-pfree.html">SPI_pfree</a></span><span class="refpurpose"> — free memory in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-copytuple.html">SPI_copytuple</a></span><span class="refpurpose"> — make a copy of a row in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-returntuple.html">SPI_returntuple</a></span><span class="refpurpose"> — prepare to return a tuple as a Datum</span></dt><dt><span class="refentrytitle"><a href="spi-spi-modifytuple.html">SPI_modifytuple</a></span><span class="refpurpose"> — create a row by replacing selected fields of a given row</span></dt><dt><span class="refentrytitle"><a href="spi-spi-freetuple.html">SPI_freetuple</a></span><span class="refpurpose"> — free a row allocated in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-freetupletable.html">SPI_freetuptable</a></span><span class="refpurpose"> — free a row set created by <code class="function">SPI_execute</code> or a similar
+ function</span></dt><dt><span class="refentrytitle"><a href="spi-spi-freeplan.html">SPI_freeplan</a></span><span class="refpurpose"> — free a previously saved prepared statement</span></dt></dl></div><p>
+ <a id="id-1.8.12.10.2.1" class="indexterm"></a>
+ <span class="productname">PostgreSQL</span> allocates memory within
+ <em class="firstterm">memory contexts</em>, which provide a convenient method of
+ managing allocations made in many different places that need to
+ live for differing amounts of time. Destroying a context releases
+ all the memory that was allocated in it. Thus, it is not necessary
+ to keep track of individual objects to avoid memory leaks; instead
+ only a relatively small number of contexts have to be managed.
+ <code class="function">palloc</code> and related functions allocate memory
+ from the <span class="quote">“<span class="quote">current</span>”</span> context.
+ </p><p>
+ <code class="function">SPI_connect</code> creates a new memory context and
+ makes it current. <code class="function">SPI_finish</code> restores the
+ previous current memory context and destroys the context created by
+ <code class="function">SPI_connect</code>. These actions ensure that
+ transient memory allocations made inside your C function are
+ reclaimed at C function exit, avoiding memory leakage.
+ </p><p>
+ However, if your C function needs to return an object in allocated
+ memory (such as a value of a pass-by-reference data type), you
+ cannot allocate that memory using <code class="function">palloc</code>, at
+ least not while you are connected to SPI. If you try, the object
+ will be deallocated by <code class="function">SPI_finish</code>, and your
+ C function will not work reliably. To solve this problem, use
+ <code class="function">SPI_palloc</code> to allocate memory for your return
+ object. <code class="function">SPI_palloc</code> allocates memory in the
+ <span class="quote">“<span class="quote">upper executor context</span>”</span>, that is, the memory context
+ that was current when <code class="function">SPI_connect</code> was called,
+ which is precisely the right context for a value returned from your
+ C function. Several of the other utility functions described in
+ this section also return objects created in the upper executor context.
+ </p><p>
+ When <code class="function">SPI_connect</code> is called, the private
+ context of the C function, which is created by
+ <code class="function">SPI_connect</code>, is made the current context. All
+ allocations made by <code class="function">palloc</code>,
+ <code class="function">repalloc</code>, or SPI utility functions (except as
+ described in this section) are made in this context. When a
+ C function disconnects from the SPI manager (via
+ <code class="function">SPI_finish</code>) the current context is restored to
+ the upper executor context, and all allocations made in the
+ C function memory context are freed and cannot be used any more.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-result-code-string.html" title="SPI_result_code_string">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-palloc.html" title="SPI_palloc">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_result_code_string </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_palloc</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-realloc.html b/doc/src/sgml/html/spi-realloc.html
new file mode 100644
index 0000000..8c16d1f
--- /dev/null
+++ b/doc/src/sgml/html/spi-realloc.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_repalloc</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-palloc.html" title="SPI_palloc" /><link rel="next" href="spi-spi-pfree.html" title="SPI_pfree" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_repalloc</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-palloc.html" title="SPI_palloc">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-pfree.html" title="SPI_pfree">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-REALLOC"><div class="titlepage"></div><a id="id-1.8.12.10.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_repalloc</span></h2><p>SPI_repalloc — reallocate memory in the upper executor context</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void * SPI_repalloc(void * <em class="parameter"><code>pointer</code></em>, Size <em class="parameter"><code>size</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.7.5"><h2>Description</h2><p>
+ <code class="function">SPI_repalloc</code> changes the size of a memory
+ segment previously allocated using <code class="function">SPI_palloc</code>.
+ </p><p>
+ This function is no longer different from plain
+ <code class="function">repalloc</code>. It's kept just for backward
+ compatibility of existing code.
+ </p></div><div class="refsect1" id="id-1.8.12.10.7.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">void * <em class="parameter"><code>pointer</code></em></code></span></dt><dd><p>
+ pointer to existing storage to change
+ </p></dd><dt><span class="term"><code class="literal">Size <em class="parameter"><code>size</code></em></code></span></dt><dd><p>
+ size in bytes of storage to allocate
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.10.7.7"><h2>Return Value</h2><p>
+ pointer to new storage space of specified size with the contents
+ copied from the existing area
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-palloc.html" title="SPI_palloc">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-pfree.html" title="SPI_pfree">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_palloc </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_pfree</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-commit.html b/doc/src/sgml/html/spi-spi-commit.html
new file mode 100644
index 0000000..a8d7dff
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-commit.html
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_commit</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-transaction.html" title="47.4. Transaction Management" /><link rel="next" href="spi-spi-rollback.html" title="SPI_rollback" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_commit</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-transaction.html" title="47.4. Transaction Management">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-transaction.html" title="47.4. Transaction Management">Up</a></td><th width="60%" align="center">47.4. Transaction Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-rollback.html" title="SPI_rollback">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-COMMIT"><div class="titlepage"></div><a id="id-1.8.12.11.4.1" class="indexterm"></a><a id="id-1.8.12.11.4.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_commit</span></h2><p>SPI_commit, SPI_commit_and_chain — commit the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_commit(void)
+</pre><pre class="synopsis">
+void SPI_commit_and_chain(void)
+</pre></div><div class="refsect1" id="id-1.8.12.11.4.6"><h2>Description</h2><p>
+ <code class="function">SPI_commit</code> commits the current transaction. It is
+ approximately equivalent to running the SQL
+ command <code class="command">COMMIT</code>. After the transaction is committed, a
+ new transaction is automatically started using default transaction
+ characteristics, so that the caller can continue using SPI facilities.
+ If there is a failure during commit, the current transaction is instead
+ rolled back and a new transaction is started, after which the error is
+ thrown in the usual way.
+ </p><p>
+ <code class="function">SPI_commit_and_chain</code> is the same, but the new
+ transaction is started with the same transaction
+ characteristics as the just finished one, like with the SQL command
+ <code class="command">COMMIT AND CHAIN</code>.
+ </p><p>
+ These functions can only be executed if the SPI connection has been set as
+ nonatomic in the call to <code class="function">SPI_connect_ext</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-transaction.html" title="47.4. Transaction Management">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-transaction.html" title="47.4. Transaction Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-rollback.html" title="SPI_rollback">Next</a></td></tr><tr><td width="40%" align="left" valign="top">47.4. Transaction Management </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_rollback</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-connect.html b/doc/src/sgml/html/spi-spi-connect.html
new file mode 100644
index 0000000..925b521
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-connect.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_connect</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-interface.html" title="47.1. Interface Functions" /><link rel="next" href="spi-spi-finish.html" title="SPI_finish" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_connect</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-interface.html" title="47.1. Interface Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-finish.html" title="SPI_finish">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CONNECT"><div class="titlepage"></div><a id="id-1.8.12.8.2.1" class="indexterm"></a><a id="id-1.8.12.8.2.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_connect</span></h2><p>SPI_connect, SPI_connect_ext — connect a C function to the SPI manager</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_connect(void)
+</pre><pre class="synopsis">
+int SPI_connect_ext(int <em class="parameter"><code>options</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.2.6"><h2>Description</h2><p>
+ <code class="function">SPI_connect</code> opens a connection from a
+ C function invocation to the SPI manager. You must call this
+ function if you want to execute commands through SPI. Some utility
+ SPI functions can be called from unconnected C functions.
+ </p><p>
+ <code class="function">SPI_connect_ext</code> does the same but has an argument that
+ allows passing option flags. Currently, the following option values are
+ available:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OPT_NONATOMIC</code></span></dt><dd><p>
+ Sets the SPI connection to be <em class="firstterm">nonatomic</em>, which
+ means that transaction control calls (<code class="function">SPI_commit</code>,
+ <code class="function">SPI_rollback</code>) are allowed. Otherwise,
+ calling those functions will result in an immediate error.
+ </p></dd></dl></div><p>
+ </p><p>
+ <code class="literal">SPI_connect()</code> is equivalent to
+ <code class="literal">SPI_connect_ext(0)</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.2.7"><h2>Return Value</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_CONNECT</code></span></dt><dd><p>
+ on success
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_CONNECT</code></span></dt><dd><p>
+ on error
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-interface.html" title="47.1. Interface Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-finish.html" title="SPI_finish">Next</a></td></tr><tr><td width="40%" align="left" valign="top">47.1. Interface Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_finish</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-copytuple.html b/doc/src/sgml/html/spi-spi-copytuple.html
new file mode 100644
index 0000000..4f8344b
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-copytuple.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_copytuple</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-pfree.html" title="SPI_pfree" /><link rel="next" href="spi-spi-returntuple.html" title="SPI_returntuple" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_copytuple</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-pfree.html" title="SPI_pfree">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-returntuple.html" title="SPI_returntuple">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-COPYTUPLE"><div class="titlepage"></div><a id="id-1.8.12.10.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_copytuple</span></h2><p>SPI_copytuple — make a copy of a row in the upper executor context</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+HeapTuple SPI_copytuple(HeapTuple <em class="parameter"><code>row</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.9.5"><h2>Description</h2><p>
+ <code class="function">SPI_copytuple</code> makes a copy of a row in the
+ upper executor context. This is normally used to return a modified
+ row from a trigger. In a function declared to return a composite
+ type, use <code class="function">SPI_returntuple</code> instead.
+ </p><p>
+ This function can only be used while connected to SPI.
+ Otherwise, it returns NULL and sets <code class="varname">SPI_result</code> to
+ <code class="symbol">SPI_ERROR_UNCONNECTED</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.10.9.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">HeapTuple <em class="parameter"><code>row</code></em></code></span></dt><dd><p>
+ row to be copied
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.10.9.7"><h2>Return Value</h2><p>
+ the copied row, or <code class="symbol">NULL</code> on error
+ (see <code class="varname">SPI_result</code> for an error indication)
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-pfree.html" title="SPI_pfree">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-returntuple.html" title="SPI_returntuple">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_pfree </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_returntuple</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-close.html b/doc/src/sgml/html/spi-spi-cursor-close.html
new file mode 100644
index 0000000..2afeade
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-close.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_close</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-scroll-cursor-move.html" title="SPI_scroll_cursor_move" /><link rel="next" href="spi-spi-keepplan.html" title="SPI_keepplan" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_close</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-scroll-cursor-move.html" title="SPI_scroll_cursor_move">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-keepplan.html" title="SPI_keepplan">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-CLOSE"><div class="titlepage"></div><a id="id-1.8.12.8.28.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_close</span></h2><p>SPI_cursor_close — close a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_cursor_close(Portal <em class="parameter"><code>portal</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.28.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_close</code> closes a previously created
+ cursor and releases its portal storage.
+ </p><p>
+ All open cursors are closed automatically at the end of a
+ transaction. <code class="function">SPI_cursor_close</code> need only be
+ invoked if it is desirable to release resources sooner.
+ </p></div><div class="refsect1" id="id-1.8.12.8.28.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Portal <em class="parameter"><code>portal</code></em></code></span></dt><dd><p>
+ portal containing the cursor
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-scroll-cursor-move.html" title="SPI_scroll_cursor_move">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-keepplan.html" title="SPI_keepplan">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_scroll_cursor_move </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_keepplan</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-fetch.html b/doc/src/sgml/html/spi-spi-cursor-fetch.html
new file mode 100644
index 0000000..a602837
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-fetch.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_fetch</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-find.html" title="SPI_cursor_find" /><link rel="next" href="spi-spi-cursor-move.html" title="SPI_cursor_move" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_fetch</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-find.html" title="SPI_cursor_find">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-move.html" title="SPI_cursor_move">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-FETCH"><div class="titlepage"></div><a id="id-1.8.12.8.24.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_fetch</span></h2><p>SPI_cursor_fetch — fetch some rows from a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_cursor_fetch(Portal <em class="parameter"><code>portal</code></em>, bool <em class="parameter"><code>forward</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.24.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_fetch</code> fetches some rows from a
+ cursor. This is equivalent to a subset of the SQL command
+ <code class="command">FETCH</code> (see <code class="function">SPI_scroll_cursor_fetch</code>
+ for more functionality).
+ </p></div><div class="refsect1" id="id-1.8.12.8.24.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Portal <em class="parameter"><code>portal</code></em></code></span></dt><dd><p>
+ portal containing the cursor
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>forward</code></em></code></span></dt><dd><p>
+ true for fetch forward, false for fetch backward
+ </p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to fetch
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.24.7"><h2>Return Value</h2><p>
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute</code> if successful.
+ </p></div><div class="refsect1" id="id-1.8.12.8.24.8"><h2>Notes</h2><p>
+ Fetching backward may fail if the cursor's plan was not created
+ with the <code class="symbol">CURSOR_OPT_SCROLL</code> option.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-find.html" title="SPI_cursor_find">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-move.html" title="SPI_cursor_move">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_find </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_move</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-find.html b/doc/src/sgml/html/spi-spi-cursor-find.html
new file mode 100644
index 0000000..4560d68
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-find.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_find</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-parse-open.html" title="SPI_cursor_parse_open" /><link rel="next" href="spi-spi-cursor-fetch.html" title="SPI_cursor_fetch" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_find</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-parse-open.html" title="SPI_cursor_parse_open">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-fetch.html" title="SPI_cursor_fetch">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-FIND"><div class="titlepage"></div><a id="id-1.8.12.8.23.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_find</span></h2><p>SPI_cursor_find — find an existing cursor by name</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Portal SPI_cursor_find(const char * <em class="parameter"><code>name</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.23.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_find</code> finds an existing portal by
+ name. This is primarily useful to resolve a cursor name returned
+ as text by some other function.
+ </p></div><div class="refsect1" id="id-1.8.12.8.23.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>name</code></em></code></span></dt><dd><p>
+ name of the portal
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.23.7"><h2>Return Value</h2><p>
+ pointer to the portal with the specified name, or
+ <code class="symbol">NULL</code> if none was found
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-parse-open.html" title="SPI_cursor_parse_open">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-fetch.html" title="SPI_cursor_fetch">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_parse_open </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_fetch</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-move.html b/doc/src/sgml/html/spi-spi-cursor-move.html
new file mode 100644
index 0000000..1ddba48
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-move.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_move</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-fetch.html" title="SPI_cursor_fetch" /><link rel="next" href="spi-spi-scroll-cursor-fetch.html" title="SPI_scroll_cursor_fetch" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_move</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-fetch.html" title="SPI_cursor_fetch">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-scroll-cursor-fetch.html" title="SPI_scroll_cursor_fetch">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-MOVE"><div class="titlepage"></div><a id="id-1.8.12.8.25.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_move</span></h2><p>SPI_cursor_move — move a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_cursor_move(Portal <em class="parameter"><code>portal</code></em>, bool <em class="parameter"><code>forward</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.25.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_move</code> skips over some number of rows
+ in a cursor. This is equivalent to a subset of the SQL command
+ <code class="command">MOVE</code> (see <code class="function">SPI_scroll_cursor_move</code>
+ for more functionality).
+ </p></div><div class="refsect1" id="id-1.8.12.8.25.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Portal <em class="parameter"><code>portal</code></em></code></span></dt><dd><p>
+ portal containing the cursor
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>forward</code></em></code></span></dt><dd><p>
+ true for move forward, false for move backward
+ </p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to move
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.25.7"><h2>Notes</h2><p>
+ Moving backward may fail if the cursor's plan was not created
+ with the <code class="symbol">CURSOR_OPT_SCROLL</code> option.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-fetch.html" title="SPI_cursor_fetch">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-scroll-cursor-fetch.html" title="SPI_scroll_cursor_fetch">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_fetch </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_scroll_cursor_fetch</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-open-with-args.html b/doc/src/sgml/html/spi-spi-cursor-open-with-args.html
new file mode 100644
index 0000000..d829d61
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-open-with-args.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_open_with_args</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-open.html" title="SPI_cursor_open" /><link rel="next" href="spi-spi-cursor-open-with-paramlist.html" title="SPI_cursor_open_with_paramlist" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_open_with_args</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-open.html" title="SPI_cursor_open">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-open-with-paramlist.html" title="SPI_cursor_open_with_paramlist">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-OPEN-WITH-ARGS"><div class="titlepage"></div><a id="id-1.8.12.8.20.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_open_with_args</span></h2><p>SPI_cursor_open_with_args — set up a cursor using a query and parameters</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Portal SPI_cursor_open_with_args(const char *<em class="parameter"><code>name</code></em>,
+ const char *<em class="parameter"><code>command</code></em>,
+ int <em class="parameter"><code>nargs</code></em>, Oid *<em class="parameter"><code>argtypes</code></em>,
+ Datum *<em class="parameter"><code>values</code></em>, const char *<em class="parameter"><code>nulls</code></em>,
+ bool <em class="parameter"><code>read_only</code></em>, int <em class="parameter"><code>cursorOptions</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.20.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_open_with_args</code> sets up a cursor
+ (internally, a portal) that will execute the specified query.
+ Most of the parameters have the same meanings as the corresponding
+ parameters to <code class="function">SPI_prepare_cursor</code>
+ and <code class="function">SPI_cursor_open</code>.
+ </p><p>
+ For one-time query execution, this function should be preferred
+ over <code class="function">SPI_prepare_cursor</code> followed by
+ <code class="function">SPI_cursor_open</code>.
+ If the same command is to be executed with many different parameters,
+ either method might be faster, depending on the cost of re-planning
+ versus the benefit of custom plans.
+ </p><p>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </p><p>
+ This function is now deprecated in favor
+ of <code class="function">SPI_cursor_parse_open</code>, which provides equivalent
+ functionality using a more modern API for handling query parameters.
+ </p></div><div class="refsect1" id="id-1.8.12.8.20.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>name</code></em></code></span></dt><dd><p>
+ name for portal, or <code class="symbol">NULL</code> to let the system
+ select a name
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>nargs</code></em></code></span></dt><dd><p>
+ number of input parameters (<code class="literal">$1</code>, <code class="literal">$2</code>, etc.)
+ </p></dd><dt><span class="term"><code class="literal">Oid * <em class="parameter"><code>argtypes</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>nargs</code></em>, containing the
+ <acronym class="acronym">OID</acronym>s of the data types of the parameters
+ </p></dd><dt><span class="term"><code class="literal">Datum * <em class="parameter"><code>values</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>nargs</code></em>, containing the actual
+ parameter values
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>nulls</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>nargs</code></em>, describing which
+ parameters are null
+ </p><p>
+ If <em class="parameter"><code>nulls</code></em> is <code class="symbol">NULL</code> then
+ <code class="function">SPI_cursor_open_with_args</code> assumes that no parameters
+ are null. Otherwise, each entry of the <em class="parameter"><code>nulls</code></em>
+ array should be <code class="literal">' '</code> if the corresponding parameter
+ value is non-null, or <code class="literal">'n'</code> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <em class="parameter"><code>values</code></em> entry doesn't matter.) Note
+ that <em class="parameter"><code>nulls</code></em> is not a text string, just an array:
+ it does not need a <code class="literal">'\0'</code> terminator.
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>cursorOptions</code></em></code></span></dt><dd><p>
+ integer bit mask of cursor options; zero produces default behavior
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.20.7"><h2>Return Value</h2><p>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <code class="function">elog</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-open.html" title="SPI_cursor_open">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-open-with-paramlist.html" title="SPI_cursor_open_with_paramlist">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_open </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_open_with_paramlist</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-open-with-paramlist.html b/doc/src/sgml/html/spi-spi-cursor-open-with-paramlist.html
new file mode 100644
index 0000000..71f2bce
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-open-with-paramlist.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_open_with_paramlist</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-open-with-args.html" title="SPI_cursor_open_with_args" /><link rel="next" href="spi-spi-cursor-parse-open.html" title="SPI_cursor_parse_open" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_open_with_paramlist</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-open-with-args.html" title="SPI_cursor_open_with_args">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-parse-open.html" title="SPI_cursor_parse_open">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-OPEN-WITH-PARAMLIST"><div class="titlepage"></div><a id="id-1.8.12.8.21.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_open_with_paramlist</span></h2><p>SPI_cursor_open_with_paramlist — set up a cursor using parameters</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Portal SPI_cursor_open_with_paramlist(const char *<em class="parameter"><code>name</code></em>,
+ SPIPlanPtr <em class="parameter"><code>plan</code></em>,
+ ParamListInfo <em class="parameter"><code>params</code></em>,
+ bool <em class="parameter"><code>read_only</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.21.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_open_with_paramlist</code> sets up a cursor
+ (internally, a portal) that will execute a statement prepared by
+ <code class="function">SPI_prepare</code>.
+ This function is equivalent to <code class="function">SPI_cursor_open</code>
+ except that information about the parameter values to be passed to the
+ query is presented differently. The <code class="literal">ParamListInfo</code>
+ representation can be convenient for passing down values that are
+ already available in that format. It also supports use of dynamic
+ parameter sets via hook functions specified in <code class="literal">ParamListInfo</code>.
+ </p><p>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </p></div><div class="refsect1" id="id-1.8.12.8.21.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>name</code></em></code></span></dt><dd><p>
+ name for portal, or <code class="symbol">NULL</code> to let the system
+ select a name
+ </p></dd><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">ParamListInfo <em class="parameter"><code>params</code></em></code></span></dt><dd><p>
+ data structure containing parameter types and values; NULL if none
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.21.7"><h2>Return Value</h2><p>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <code class="function">elog</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-open-with-args.html" title="SPI_cursor_open_with_args">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-parse-open.html" title="SPI_cursor_parse_open">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_open_with_args </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_parse_open</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-open.html b/doc/src/sgml/html/spi-spi-cursor-open.html
new file mode 100644
index 0000000..b474efa
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-open.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_open</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execp.html" title="SPI_execp" /><link rel="next" href="spi-spi-cursor-open-with-args.html" title="SPI_cursor_open_with_args" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_open</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execp.html" title="SPI_execp">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-open-with-args.html" title="SPI_cursor_open_with_args">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-OPEN"><div class="titlepage"></div><a id="id-1.8.12.8.19.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_open</span></h2><p>SPI_cursor_open — set up a cursor using a statement created with <code class="function">SPI_prepare</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Portal SPI_cursor_open(const char * <em class="parameter"><code>name</code></em>, SPIPlanPtr <em class="parameter"><code>plan</code></em>,
+ Datum * <em class="parameter"><code>values</code></em>, const char * <em class="parameter"><code>nulls</code></em>,
+ bool <em class="parameter"><code>read_only</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.19.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_open</code> sets up a cursor (internally,
+ a portal) that will execute a statement prepared by
+ <code class="function">SPI_prepare</code>. The parameters have the same
+ meanings as the corresponding parameters to
+ <code class="function">SPI_execute_plan</code>.
+ </p><p>
+ Using a cursor instead of executing the statement directly has two
+ benefits. First, the result rows can be retrieved a few at a time,
+ avoiding memory overrun for queries that return many rows. Second,
+ a portal can outlive the current C function (it can, in fact, live
+ to the end of the current transaction). Returning the portal name
+ to the C function's caller provides a way of returning a row set as
+ result.
+ </p><p>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </p></div><div class="refsect1" id="id-1.8.12.8.19.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>name</code></em></code></span></dt><dd><p>
+ name for portal, or <code class="symbol">NULL</code> to let the system
+ select a name
+ </p></dd><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">Datum * <em class="parameter"><code>values</code></em></code></span></dt><dd><p>
+ An array of actual parameter values. Must have same length as the
+ statement's number of arguments.
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>nulls</code></em></code></span></dt><dd><p>
+ An array describing which parameters are null. Must have same length as
+ the statement's number of arguments.
+ </p><p>
+ If <em class="parameter"><code>nulls</code></em> is <code class="symbol">NULL</code> then
+ <code class="function">SPI_cursor_open</code> assumes that no parameters
+ are null. Otherwise, each entry of the <em class="parameter"><code>nulls</code></em>
+ array should be <code class="literal">' '</code> if the corresponding parameter
+ value is non-null, or <code class="literal">'n'</code> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <em class="parameter"><code>values</code></em> entry doesn't matter.) Note
+ that <em class="parameter"><code>nulls</code></em> is not a text string, just an array:
+ it does not need a <code class="literal">'\0'</code> terminator.
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.19.7"><h2>Return Value</h2><p>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <code class="function">elog</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execp.html" title="SPI_execp">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-open-with-args.html" title="SPI_cursor_open_with_args">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execp </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_open_with_args</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-cursor-parse-open.html b/doc/src/sgml/html/spi-spi-cursor-parse-open.html
new file mode 100644
index 0000000..2f4c3bc
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-cursor-parse-open.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_cursor_parse_open</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-open-with-paramlist.html" title="SPI_cursor_open_with_paramlist" /><link rel="next" href="spi-spi-cursor-find.html" title="SPI_cursor_find" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_cursor_parse_open</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-open-with-paramlist.html" title="SPI_cursor_open_with_paramlist">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-find.html" title="SPI_cursor_find">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-CURSOR-PARSE-OPEN"><div class="titlepage"></div><a id="id-1.8.12.8.22.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_cursor_parse_open</span></h2><p>SPI_cursor_parse_open — set up a cursor using a query string and parameters</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Portal SPI_cursor_parse_open(const char *<em class="parameter"><code>name</code></em>,
+ const char *<em class="parameter"><code>command</code></em>,
+ const SPIParseOpenOptions * <em class="parameter"><code>options</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.22.5"><h2>Description</h2><p>
+ <code class="function">SPI_cursor_parse_open</code> sets up a cursor
+ (internally, a portal) that will execute the specified query string.
+ This is comparable to <code class="function">SPI_prepare_cursor</code> followed
+ by <code class="function">SPI_cursor_open_with_paramlist</code>, except that
+ parameter references within the query string are handled entirely by
+ supplying a <code class="literal">ParamListInfo</code> object.
+ </p><p>
+ For one-time query execution, this function should be preferred
+ over <code class="function">SPI_prepare_cursor</code> followed by
+ <code class="function">SPI_cursor_open_with_paramlist</code>.
+ If the same command is to be executed with many different parameters,
+ either method might be faster, depending on the cost of re-planning
+ versus the benefit of custom plans.
+ </p><p>
+ The <em class="parameter"><code>options-&gt;params</code></em> object should normally
+ mark each parameter with the <code class="literal">PARAM_FLAG_CONST</code> flag,
+ since a one-shot plan is always used for the query.
+ </p><p>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </p></div><div class="refsect1" id="id-1.8.12.8.22.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>name</code></em></code></span></dt><dd><p>
+ name for portal, or <code class="symbol">NULL</code> to let the system
+ select a name
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">const SPIParseOpenOptions * <em class="parameter"><code>options</code></em></code></span></dt><dd><p>
+ struct containing optional arguments
+ </p></dd></dl></div><p>
+ Callers should always zero out the entire <em class="parameter"><code>options</code></em>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <em class="parameter"><code>options</code></em> fields are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ParamListInfo <em class="parameter"><code>params</code></em></code></span></dt><dd><p>
+ data structure containing query parameter types and values; NULL if none
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>cursorOptions</code></em></code></span></dt><dd><p>
+ integer bit mask of cursor options; zero produces default behavior
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.22.7"><h2>Return Value</h2><p>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <code class="function">elog</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-open-with-paramlist.html" title="SPI_cursor_open_with_paramlist">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-find.html" title="SPI_cursor_find">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_open_with_paramlist </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_find</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-exec.html b/doc/src/sgml/html/spi-spi-exec.html
new file mode 100644
index 0000000..8e9631b
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-exec.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_exec</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execute.html" title="SPI_execute" /><link rel="next" href="spi-spi-execute-extended.html" title="SPI_execute_extended" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_exec</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execute.html" title="SPI_execute">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execute-extended.html" title="SPI_execute_extended">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXEC"><div class="titlepage"></div><a id="id-1.8.12.8.5.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_exec</span></h2><p>SPI_exec — execute a read/write command</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_exec(const char * <em class="parameter"><code>command</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.5.5"><h2>Description</h2><p>
+ <code class="function">SPI_exec</code> is the same as
+ <code class="function">SPI_execute</code>, with the latter's
+ <em class="parameter"><code>read_only</code></em> parameter always taken as
+ <code class="literal">false</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.5.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ string containing command to execute
+ </p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.5.7"><h2>Return Value</h2><p>
+ See <code class="function">SPI_execute</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execute.html" title="SPI_execute">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execute-extended.html" title="SPI_execute_extended">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execute </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execute_extended</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execp.html b/doc/src/sgml/html/spi-spi-execp.html
new file mode 100644
index 0000000..7c957f1
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execp.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execp</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execute-plan-with-paramlist.html" title="SPI_execute_plan_with_paramlist" /><link rel="next" href="spi-spi-cursor-open.html" title="SPI_cursor_open" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execp</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execute-plan-with-paramlist.html" title="SPI_execute_plan_with_paramlist">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-open.html" title="SPI_cursor_open">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECP"><div class="titlepage"></div><a id="id-1.8.12.8.18.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execp</span></h2><p>SPI_execp — execute a statement in read/write mode</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execp(SPIPlanPtr <em class="parameter"><code>plan</code></em>, Datum * <em class="parameter"><code>values</code></em>, const char * <em class="parameter"><code>nulls</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.18.5"><h2>Description</h2><p>
+ <code class="function">SPI_execp</code> is the same as
+ <code class="function">SPI_execute_plan</code>, with the latter's
+ <em class="parameter"><code>read_only</code></em> parameter always taken as
+ <code class="literal">false</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.18.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">Datum * <em class="parameter"><code>values</code></em></code></span></dt><dd><p>
+ An array of actual parameter values. Must have same length as the
+ statement's number of arguments.
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>nulls</code></em></code></span></dt><dd><p>
+ An array describing which parameters are null. Must have same length as
+ the statement's number of arguments.
+ </p><p>
+ If <em class="parameter"><code>nulls</code></em> is <code class="symbol">NULL</code> then
+ <code class="function">SPI_execp</code> assumes that no parameters
+ are null. Otherwise, each entry of the <em class="parameter"><code>nulls</code></em>
+ array should be <code class="literal">' '</code> if the corresponding parameter
+ value is non-null, or <code class="literal">'n'</code> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <em class="parameter"><code>values</code></em> entry doesn't matter.) Note
+ that <em class="parameter"><code>nulls</code></em> is not a text string, just an array:
+ it does not need a <code class="literal">'\0'</code> terminator.
+ </p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.18.7"><h2>Return Value</h2><p>
+ See <code class="function">SPI_execute_plan</code>.
+ </p><p>
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute</code> if successful.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execute-plan-with-paramlist.html" title="SPI_execute_plan_with_paramlist">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-open.html" title="SPI_cursor_open">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execute_plan_with_paramlist </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_open</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execute-extended.html b/doc/src/sgml/html/spi-spi-execute-extended.html
new file mode 100644
index 0000000..b412645
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execute-extended.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute_extended</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-exec.html" title="SPI_exec" /><link rel="next" href="spi-spi-execute-with-args.html" title="SPI_execute_with_args" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute_extended</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-exec.html" title="SPI_exec">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execute-with-args.html" title="SPI_execute_with_args">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE-EXTENDED"><div class="titlepage"></div><a id="id-1.8.12.8.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute_extended</span></h2><p>SPI_execute_extended — execute a command with out-of-line parameters</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execute_extended(const char *<em class="parameter"><code>command</code></em>,
+ const SPIExecuteOptions * <em class="parameter"><code>options</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.6.5"><h2>Description</h2><p>
+ <code class="function">SPI_execute_extended</code> executes a command that might
+ include references to externally supplied parameters. The command text
+ refers to a parameter as <code class="literal">$<em class="replaceable"><code>n</code></em></code>,
+ and the <em class="parameter"><code>options-&gt;params</code></em> object (if supplied)
+ provides values and type information for each such symbol.
+ Various execution options can be specified
+ in the <em class="parameter"><code>options</code></em> struct, too.
+ </p><p>
+ The <em class="parameter"><code>options-&gt;params</code></em> object should normally
+ mark each parameter with the <code class="literal">PARAM_FLAG_CONST</code> flag,
+ since a one-shot plan is always used for the query.
+ </p><p>
+ If <em class="parameter"><code>options-&gt;dest</code></em> is not NULL, then result
+ tuples are passed to that object as they are generated by the executor,
+ instead of being accumulated in <code class="varname">SPI_tuptable</code>. Using
+ a caller-supplied <code class="literal">DestReceiver</code> object is particularly
+ helpful for queries that might generate many tuples, since the data can
+ be processed on-the-fly instead of being accumulated in memory.
+ </p></div><div class="refsect1" id="id-1.8.12.8.6.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">const SPIExecuteOptions * <em class="parameter"><code>options</code></em></code></span></dt><dd><p>
+ struct containing optional arguments
+ </p></dd></dl></div><p>
+ Callers should always zero out the entire <em class="parameter"><code>options</code></em>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <em class="parameter"><code>options</code></em> fields are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ParamListInfo <em class="parameter"><code>params</code></em></code></span></dt><dd><p>
+ data structure containing query parameter types and values; NULL if none
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>allow_nonatomic</code></em></code></span></dt><dd><p>
+ <code class="literal">true</code> allows non-atomic execution of CALL and DO
+ statements
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>must_return_tuples</code></em></code></span></dt><dd><p>
+ if <code class="literal">true</code>, raise error if the query is not of a kind
+ that returns tuples (this does not forbid the case where it happens to
+ return zero tuples)
+ </p></dd><dt><span class="term"><code class="literal">uint64 <em class="parameter"><code>tcount</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd><dt><span class="term"><code class="literal">DestReceiver * <em class="parameter"><code>dest</code></em></code></span></dt><dd><p>
+ <code class="literal">DestReceiver</code> object that will receive any tuples
+ emitted by the query; if NULL, result tuples are accumulated into
+ a <code class="varname">SPI_tuptable</code> structure, as
+ in <code class="function">SPI_execute</code>
+ </p></dd><dt><span class="term"><code class="literal">ResourceOwner <em class="parameter"><code>owner</code></em></code></span></dt><dd><p>
+ This field is present for consistency
+ with <code class="function">SPI_execute_plan_extended</code>, but it is
+ ignored, since the plan used
+ by <code class="function">SPI_execute_extended</code> is never saved.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.6.7"><h2>Return Value</h2><p>
+ The return value is the same as for <code class="function">SPI_execute</code>.
+ </p><p>
+ When <em class="parameter"><code>options-&gt;dest</code></em> is NULL,
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute</code>.
+ When <em class="parameter"><code>options-&gt;dest</code></em> is not NULL,
+ <code class="varname">SPI_processed</code> is set to zero and
+ <code class="varname">SPI_tuptable</code> is set to NULL. If a tuple count
+ is required, the caller's <code class="literal">DestReceiver</code> object must
+ calculate it.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-exec.html" title="SPI_exec">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execute-with-args.html" title="SPI_execute_with_args">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_exec </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execute_with_args</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execute-plan-extended.html b/doc/src/sgml/html/spi-spi-execute-plan-extended.html
new file mode 100644
index 0000000..ba6f026
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execute-plan-extended.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute_plan_extended</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execute-plan.html" title="SPI_execute_plan" /><link rel="next" href="spi-spi-execute-plan-with-paramlist.html" title="SPI_execute_plan_with_paramlist" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute_plan_extended</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execute-plan.html" title="SPI_execute_plan">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execute-plan-with-paramlist.html" title="SPI_execute_plan_with_paramlist">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE-PLAN-EXTENDED"><div class="titlepage"></div><a id="id-1.8.12.8.16.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute_plan_extended</span></h2><p>SPI_execute_plan_extended — execute a statement prepared by <code class="function">SPI_prepare</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execute_plan_extended(SPIPlanPtr <em class="parameter"><code>plan</code></em>,
+ const SPIExecuteOptions * <em class="parameter"><code>options</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.16.5"><h2>Description</h2><p>
+ <code class="function">SPI_execute_plan_extended</code> executes a statement
+ prepared by <code class="function">SPI_prepare</code> or one of its siblings.
+ This function is equivalent to <code class="function">SPI_execute_plan</code>,
+ except that information about the parameter values to be passed to the
+ query is presented differently, and additional execution-controlling
+ options can be passed.
+ </p><p>
+ Query parameter values are represented by
+ a <code class="literal">ParamListInfo</code> struct, which is convenient for passing
+ down values that are already available in that format. Dynamic parameter
+ sets can also be used, via hook functions specified
+ in <code class="literal">ParamListInfo</code>.
+ </p><p>
+ Also, instead of always accumulating the result tuples into a
+ <code class="varname">SPI_tuptable</code> structure, tuples can be passed to a
+ caller-supplied <code class="literal">DestReceiver</code> object as they are
+ generated by the executor. This is particularly helpful for queries
+ that might generate many tuples, since the data can be processed
+ on-the-fly instead of being accumulated in memory.
+ </p></div><div class="refsect1" id="id-1.8.12.8.16.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">const SPIExecuteOptions * <em class="parameter"><code>options</code></em></code></span></dt><dd><p>
+ struct containing optional arguments
+ </p></dd></dl></div><p>
+ Callers should always zero out the entire <em class="parameter"><code>options</code></em>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <em class="parameter"><code>options</code></em> fields are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ParamListInfo <em class="parameter"><code>params</code></em></code></span></dt><dd><p>
+ data structure containing query parameter types and values; NULL if none
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>allow_nonatomic</code></em></code></span></dt><dd><p>
+ <code class="literal">true</code> allows non-atomic execution of CALL and DO
+ statements
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>must_return_tuples</code></em></code></span></dt><dd><p>
+ if <code class="literal">true</code>, raise error if the query is not of a kind
+ that returns tuples (this does not forbid the case where it happens to
+ return zero tuples)
+ </p></dd><dt><span class="term"><code class="literal">uint64 <em class="parameter"><code>tcount</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd><dt><span class="term"><code class="literal">DestReceiver * <em class="parameter"><code>dest</code></em></code></span></dt><dd><p>
+ <code class="literal">DestReceiver</code> object that will receive any tuples
+ emitted by the query; if NULL, result tuples are accumulated into
+ a <code class="varname">SPI_tuptable</code> structure, as
+ in <code class="function">SPI_execute_plan</code>
+ </p></dd><dt><span class="term"><code class="literal">ResourceOwner <em class="parameter"><code>owner</code></em></code></span></dt><dd><p>
+ The resource owner that will hold a reference count on the plan while
+ it is executed. If NULL, CurrentResourceOwner is used. Ignored for
+ non-saved plans, as SPI does not acquire reference counts on those.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.16.7"><h2>Return Value</h2><p>
+ The return value is the same as for <code class="function">SPI_execute_plan</code>.
+ </p><p>
+ When <em class="parameter"><code>options-&gt;dest</code></em> is NULL,
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute_plan</code>.
+ When <em class="parameter"><code>options-&gt;dest</code></em> is not NULL,
+ <code class="varname">SPI_processed</code> is set to zero and
+ <code class="varname">SPI_tuptable</code> is set to NULL. If a tuple count
+ is required, the caller's <code class="literal">DestReceiver</code> object must
+ calculate it.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execute-plan.html" title="SPI_execute_plan">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execute-plan-with-paramlist.html" title="SPI_execute_plan_with_paramlist">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execute_plan </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execute_plan_with_paramlist</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execute-plan-with-paramlist.html b/doc/src/sgml/html/spi-spi-execute-plan-with-paramlist.html
new file mode 100644
index 0000000..01f0718
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execute-plan-with-paramlist.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute_plan_with_paramlist</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execute-plan-extended.html" title="SPI_execute_plan_extended" /><link rel="next" href="spi-spi-execp.html" title="SPI_execp" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute_plan_with_paramlist</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execute-plan-extended.html" title="SPI_execute_plan_extended">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execp.html" title="SPI_execp">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE-PLAN-WITH-PARAMLIST"><div class="titlepage"></div><a id="id-1.8.12.8.17.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute_plan_with_paramlist</span></h2><p>SPI_execute_plan_with_paramlist — execute a statement prepared by <code class="function">SPI_prepare</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execute_plan_with_paramlist(SPIPlanPtr <em class="parameter"><code>plan</code></em>,
+ ParamListInfo <em class="parameter"><code>params</code></em>,
+ bool <em class="parameter"><code>read_only</code></em>,
+ long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.17.5"><h2>Description</h2><p>
+ <code class="function">SPI_execute_plan_with_paramlist</code> executes a statement
+ prepared by <code class="function">SPI_prepare</code>.
+ This function is equivalent to <code class="function">SPI_execute_plan</code>
+ except that information about the parameter values to be passed to the
+ query is presented differently. The <code class="literal">ParamListInfo</code>
+ representation can be convenient for passing down values that are
+ already available in that format. It also supports use of dynamic
+ parameter sets via hook functions specified in <code class="literal">ParamListInfo</code>.
+ </p><p>
+ This function is now deprecated in favor
+ of <code class="function">SPI_execute_plan_extended</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.17.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">ParamListInfo <em class="parameter"><code>params</code></em></code></span></dt><dd><p>
+ data structure containing parameter types and values; NULL if none
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.17.7"><h2>Return Value</h2><p>
+ The return value is the same as for <code class="function">SPI_execute_plan</code>.
+ </p><p>
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute_plan</code> if successful.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execute-plan-extended.html" title="SPI_execute_plan_extended">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execp.html" title="SPI_execp">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execute_plan_extended </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execp</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execute-plan.html b/doc/src/sgml/html/spi-spi-execute-plan.html
new file mode 100644
index 0000000..2eefd0d
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execute-plan.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute_plan</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-is-cursor-plan.html" title="SPI_is_cursor_plan" /><link rel="next" href="spi-spi-execute-plan-extended.html" title="SPI_execute_plan_extended" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute_plan</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-is-cursor-plan.html" title="SPI_is_cursor_plan">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execute-plan-extended.html" title="SPI_execute_plan_extended">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE-PLAN"><div class="titlepage"></div><a id="id-1.8.12.8.15.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute_plan</span></h2><p>SPI_execute_plan — execute a statement prepared by <code class="function">SPI_prepare</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execute_plan(SPIPlanPtr <em class="parameter"><code>plan</code></em>, Datum * <em class="parameter"><code>values</code></em>, const char * <em class="parameter"><code>nulls</code></em>,
+ bool <em class="parameter"><code>read_only</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.15.5"><h2>Description</h2><p>
+ <code class="function">SPI_execute_plan</code> executes a statement prepared by
+ <code class="function">SPI_prepare</code> or one of its siblings.
+ <em class="parameter"><code>read_only</code></em> and
+ <em class="parameter"><code>count</code></em> have the same interpretation as in
+ <code class="function">SPI_execute</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.15.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">Datum * <em class="parameter"><code>values</code></em></code></span></dt><dd><p>
+ An array of actual parameter values. Must have same length as the
+ statement's number of arguments.
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>nulls</code></em></code></span></dt><dd><p>
+ An array describing which parameters are null. Must have same length as
+ the statement's number of arguments.
+ </p><p>
+ If <em class="parameter"><code>nulls</code></em> is <code class="symbol">NULL</code> then
+ <code class="function">SPI_execute_plan</code> assumes that no parameters
+ are null. Otherwise, each entry of the <em class="parameter"><code>nulls</code></em>
+ array should be <code class="literal">' '</code> if the corresponding parameter
+ value is non-null, or <code class="literal">'n'</code> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <em class="parameter"><code>values</code></em> entry doesn't matter.) Note
+ that <em class="parameter"><code>nulls</code></em> is not a text string, just an array:
+ it does not need a <code class="literal">'\0'</code> terminator.
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.15.7"><h2>Return Value</h2><p>
+ The return value is the same as for <code class="function">SPI_execute</code>,
+ with the following additional possible error (negative) results:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>plan</code></em> is <code class="symbol">NULL</code> or invalid,
+ or <em class="parameter"><code>count</code></em> is less than 0
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_PARAM</code></span></dt><dd><p>
+ if <em class="parameter"><code>values</code></em> is <code class="symbol">NULL</code> and
+ <em class="parameter"><code>plan</code></em> was prepared with some parameters
+ </p></dd></dl></div><p>
+ </p><p>
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute</code> if successful.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-is-cursor-plan.html" title="SPI_is_cursor_plan">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execute-plan-extended.html" title="SPI_execute_plan_extended">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_is_cursor_plan </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execute_plan_extended</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execute-with-args.html b/doc/src/sgml/html/spi-spi-execute-with-args.html
new file mode 100644
index 0000000..2427159
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execute-with-args.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute_with_args</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execute-extended.html" title="SPI_execute_extended" /><link rel="next" href="spi-spi-prepare.html" title="SPI_prepare" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute_with_args</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execute-extended.html" title="SPI_execute_extended">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-prepare.html" title="SPI_prepare">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE-WITH-ARGS"><div class="titlepage"></div><a id="id-1.8.12.8.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute_with_args</span></h2><p>SPI_execute_with_args — execute a command with out-of-line parameters</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execute_with_args(const char *<em class="parameter"><code>command</code></em>,
+ int <em class="parameter"><code>nargs</code></em>, Oid *<em class="parameter"><code>argtypes</code></em>,
+ Datum *<em class="parameter"><code>values</code></em>, const char *<em class="parameter"><code>nulls</code></em>,
+ bool <em class="parameter"><code>read_only</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.7.5"><h2>Description</h2><p>
+ <code class="function">SPI_execute_with_args</code> executes a command that might
+ include references to externally supplied parameters. The command text
+ refers to a parameter as <code class="literal">$<em class="replaceable"><code>n</code></em></code>, and
+ the call specifies data types and values for each such symbol.
+ <em class="parameter"><code>read_only</code></em> and <em class="parameter"><code>count</code></em> have
+ the same interpretation as in <code class="function">SPI_execute</code>.
+ </p><p>
+ The main advantage of this routine compared to
+ <code class="function">SPI_execute</code> is that data values can be inserted
+ into the command without tedious quoting/escaping, and thus with much
+ less risk of SQL-injection attacks.
+ </p><p>
+ Similar results can be achieved with <code class="function">SPI_prepare</code> followed by
+ <code class="function">SPI_execute_plan</code>; however, when using this function
+ the query plan is always customized to the specific parameter values
+ provided.
+ For one-time query execution, this function should be preferred.
+ If the same command is to be executed with many different parameters,
+ either method might be faster, depending on the cost of re-planning
+ versus the benefit of custom plans.
+ </p></div><div class="refsect1" id="id-1.8.12.8.7.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>nargs</code></em></code></span></dt><dd><p>
+ number of input parameters (<code class="literal">$1</code>, <code class="literal">$2</code>, etc.)
+ </p></dd><dt><span class="term"><code class="literal">Oid * <em class="parameter"><code>argtypes</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>nargs</code></em>, containing the
+ <acronym class="acronym">OID</acronym>s of the data types of the parameters
+ </p></dd><dt><span class="term"><code class="literal">Datum * <em class="parameter"><code>values</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>nargs</code></em>, containing the actual
+ parameter values
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>nulls</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>nargs</code></em>, describing which
+ parameters are null
+ </p><p>
+ If <em class="parameter"><code>nulls</code></em> is <code class="symbol">NULL</code> then
+ <code class="function">SPI_execute_with_args</code> assumes that no parameters
+ are null. Otherwise, each entry of the <em class="parameter"><code>nulls</code></em>
+ array should be <code class="literal">' '</code> if the corresponding parameter
+ value is non-null, or <code class="literal">'n'</code> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <em class="parameter"><code>values</code></em> entry doesn't matter.) Note
+ that <em class="parameter"><code>nulls</code></em> is not a text string, just an array:
+ it does not need a <code class="literal">'\0'</code> terminator.
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.7.7"><h2>Return Value</h2><p>
+ The return value is the same as for <code class="function">SPI_execute</code>.
+ </p><p>
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute</code> if successful.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execute-extended.html" title="SPI_execute_extended">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-prepare.html" title="SPI_prepare">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execute_extended </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_prepare</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-execute.html b/doc/src/sgml/html/spi-spi-execute.html
new file mode 100644
index 0000000..dfb3096
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-execute.html
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-finish.html" title="SPI_finish" /><link rel="next" href="spi-spi-exec.html" title="SPI_exec" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-finish.html" title="SPI_finish">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-exec.html" title="SPI_exec">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE"><div class="titlepage"></div><a id="id-1.8.12.8.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute</span></h2><p>SPI_execute — execute a command</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_execute(const char * <em class="parameter"><code>command</code></em>, bool <em class="parameter"><code>read_only</code></em>, long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.4.5"><h2>Description</h2><p>
+ <code class="function">SPI_execute</code> executes the specified SQL command
+ for <em class="parameter"><code>count</code></em> rows. If <em class="parameter"><code>read_only</code></em>
+ is <code class="literal">true</code>, the command must be read-only, and execution overhead
+ is somewhat reduced.
+ </p><p>
+ This function can only be called from a connected C function.
+ </p><p>
+ If <em class="parameter"><code>count</code></em> is zero then the command is executed
+ for all rows that it applies to. If <em class="parameter"><code>count</code></em>
+ is greater than zero, then no more than <em class="parameter"><code>count</code></em> rows
+ will be retrieved; execution stops when the count is reached, much like
+ adding a <code class="literal">LIMIT</code> clause to the query. For example,
+</p><pre class="programlisting">
+SPI_execute("SELECT * FROM foo", true, 5);
+</pre><p>
+ will retrieve at most 5 rows from the table. Note that such a limit
+ is only effective when the command actually returns rows. For example,
+</p><pre class="programlisting">
+SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
+</pre><p>
+ inserts all rows from <code class="structname">bar</code>, ignoring the
+ <em class="parameter"><code>count</code></em> parameter. However, with
+</p><pre class="programlisting">
+SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);
+</pre><p>
+ at most 5 rows would be inserted, since execution would stop after the
+ fifth <code class="literal">RETURNING</code> result row is retrieved.
+ </p><p>
+ You can pass multiple commands in one string;
+ <code class="function">SPI_execute</code> returns the
+ result for the command executed last. The <em class="parameter"><code>count</code></em>
+ limit applies to each command separately (even though only the last
+ result will actually be returned). The limit is not applied to any
+ hidden commands generated by rules.
+ </p><p>
+ When <em class="parameter"><code>read_only</code></em> is <code class="literal">false</code>,
+ <code class="function">SPI_execute</code> increments the command
+ counter and computes a new <em class="firstterm">snapshot</em> before executing each
+ command in the string. The snapshot does not actually change if the
+ current transaction isolation level is <code class="literal">SERIALIZABLE</code> or <code class="literal">REPEATABLE READ</code>, but in
+ <code class="literal">READ COMMITTED</code> mode the snapshot update allows each command to
+ see the results of newly committed transactions from other sessions.
+ This is essential for consistent behavior when the commands are modifying
+ the database.
+ </p><p>
+ When <em class="parameter"><code>read_only</code></em> is <code class="literal">true</code>,
+ <code class="function">SPI_execute</code> does not update either the snapshot
+ or the command counter, and it allows only plain <code class="command">SELECT</code>
+ commands to appear in the command string. The commands are executed
+ using the snapshot previously established for the surrounding query.
+ This execution mode is somewhat faster than the read/write mode due
+ to eliminating per-command overhead. It also allows genuinely
+ <em class="firstterm">stable</em> functions to be built: since successive executions
+ will all use the same snapshot, there will be no change in the results.
+ </p><p>
+ It is generally unwise to mix read-only and read-write commands within
+ a single function using SPI; that could result in very confusing behavior,
+ since the read-only queries would not see the results of any database
+ updates done by the read-write queries.
+ </p><p>
+ The actual number of rows for which the (last) command was executed
+ is returned in the global variable <code class="varname">SPI_processed</code>.
+ If the return value of the function is <code class="symbol">SPI_OK_SELECT</code>,
+ <code class="symbol">SPI_OK_INSERT_RETURNING</code>,
+ <code class="symbol">SPI_OK_DELETE_RETURNING</code>, or
+ <code class="symbol">SPI_OK_UPDATE_RETURNING</code>,
+ then you can use the
+ global pointer <code class="literal">SPITupleTable *SPI_tuptable</code> to
+ access the result rows. Some utility commands (such as
+ <code class="command">EXPLAIN</code>) also return row sets, and <code class="literal">SPI_tuptable</code>
+ will contain the result in these cases too. Some utility commands
+ (<code class="command">COPY</code>, <code class="command">CREATE TABLE AS</code>) don't return a row set, so
+ <code class="literal">SPI_tuptable</code> is NULL, but they still return the number of
+ rows processed in <code class="varname">SPI_processed</code>.
+ </p><p>
+ The structure <code class="structname">SPITupleTable</code> is defined
+ thus:
+</p><pre class="programlisting">
+typedef struct SPITupleTable
+{
+ /* Public members */
+ TupleDesc tupdesc; /* tuple descriptor */
+ HeapTuple *vals; /* array of tuples */
+ uint64 numvals; /* number of valid tuples */
+
+ /* Private members, not intended for external callers */
+ uint64 alloced; /* allocated length of vals array */
+ MemoryContext tuptabcxt; /* memory context of result table */
+ slist_node next; /* link for internal bookkeeping */
+ SubTransactionId subid; /* subxact in which tuptable was created */
+} SPITupleTable;
+</pre><p>
+ The fields <code class="structfield">tupdesc</code>,
+ <code class="structfield">vals</code>, and
+ <code class="structfield">numvals</code>
+ can be used by SPI callers; the remaining fields are internal.
+ <code class="structfield">vals</code> is an array of pointers to rows.
+ The number of rows is given by <code class="structfield">numvals</code>
+ (for somewhat historical reasons, this count is also returned
+ in <code class="varname">SPI_processed</code>).
+ <code class="structfield">tupdesc</code> is a row descriptor which you can pass to
+ SPI functions dealing with rows.
+ </p><p>
+ <code class="function">SPI_finish</code> frees all
+ <code class="structname">SPITupleTable</code>s allocated during the current
+ C function. You can free a particular result table earlier, if you
+ are done with it, by calling <code class="function">SPI_freetuptable</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.4.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ string containing command to execute
+ </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ maximum number of rows to return,
+ or <code class="literal">0</code> for no limit
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.4.7"><h2>Return Value</h2><p>
+ If the execution of the command was successful then one of the
+ following (nonnegative) values will be returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_SELECT</code></span></dt><dd><p>
+ if a <code class="command">SELECT</code> (but not <code class="command">SELECT
+ INTO</code>) was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_SELINTO</code></span></dt><dd><p>
+ if a <code class="command">SELECT INTO</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_INSERT</code></span></dt><dd><p>
+ if an <code class="command">INSERT</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_DELETE</code></span></dt><dd><p>
+ if a <code class="command">DELETE</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_UPDATE</code></span></dt><dd><p>
+ if an <code class="command">UPDATE</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_MERGE</code></span></dt><dd><p>
+ if a <code class="command">MERGE</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_INSERT_RETURNING</code></span></dt><dd><p>
+ if an <code class="command">INSERT RETURNING</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_DELETE_RETURNING</code></span></dt><dd><p>
+ if a <code class="command">DELETE RETURNING</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_UPDATE_RETURNING</code></span></dt><dd><p>
+ if an <code class="command">UPDATE RETURNING</code> was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_UTILITY</code></span></dt><dd><p>
+ if a utility command (e.g., <code class="command">CREATE TABLE</code>)
+ was executed
+ </p></dd><dt><span class="term"><code class="symbol">SPI_OK_REWRITTEN</code></span></dt><dd><p>
+ if the command was rewritten into another kind of command (e.g.,
+ <code class="command">UPDATE</code> became an <code class="command">INSERT</code>) by a <a class="link" href="rules.html" title="Chapter 41. The Rule System">rule</a>.
+ </p></dd></dl></div><p>
+ </p><p>
+ On error, one of the following negative values is returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>command</code></em> is <code class="symbol">NULL</code> or
+ <em class="parameter"><code>count</code></em> is less than 0
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_COPY</code></span></dt><dd><p>
+ if <code class="command">COPY TO stdout</code> or <code class="command">COPY FROM stdin</code>
+ was attempted
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_TRANSACTION</code></span></dt><dd><p>
+ if a transaction manipulation command was attempted
+ (<code class="command">BEGIN</code>,
+ <code class="command">COMMIT</code>,
+ <code class="command">ROLLBACK</code>,
+ <code class="command">SAVEPOINT</code>,
+ <code class="command">PREPARE TRANSACTION</code>,
+ <code class="command">COMMIT PREPARED</code>,
+ <code class="command">ROLLBACK PREPARED</code>,
+ or any variant thereof)
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_OPUNKNOWN</code></span></dt><dd><p>
+ if the command type is unknown (shouldn't happen)
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if called from an unconnected C function
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.8.12.8.4.8"><h2>Notes</h2><p>
+ All SPI query-execution functions set both
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> (just the pointer, not the contents
+ of the structure). Save these two global variables into local
+ C function variables if you need to access the result table of
+ <code class="function">SPI_execute</code> or another query-execution function
+ across later calls.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-finish.html" title="SPI_finish">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-exec.html" title="SPI_exec">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_finish </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_exec</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-finish.html b/doc/src/sgml/html/spi-spi-finish.html
new file mode 100644
index 0000000..f7dddec
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-finish.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_finish</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-connect.html" title="SPI_connect" /><link rel="next" href="spi-spi-execute.html" title="SPI_execute" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_finish</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-connect.html" title="SPI_connect">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execute.html" title="SPI_execute">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-FINISH"><div class="titlepage"></div><a id="id-1.8.12.8.3.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_finish</span></h2><p>SPI_finish — disconnect a C function from the SPI manager</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_finish(void)
+</pre></div><div class="refsect1" id="id-1.8.12.8.3.5"><h2>Description</h2><p>
+ <code class="function">SPI_finish</code> closes an existing connection to
+ the SPI manager. You must call this function after completing the
+ SPI operations needed during your C function's current invocation.
+ You do not need to worry about making this happen, however, if you
+ abort the transaction via <code class="literal">elog(ERROR)</code>. In that
+ case SPI will clean itself up automatically.
+ </p></div><div class="refsect1" id="id-1.8.12.8.3.6"><h2>Return Value</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_FINISH</code></span></dt><dd><p>
+ if properly disconnected
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if called from an unconnected C function
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-connect.html" title="SPI_connect">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execute.html" title="SPI_execute">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_connect </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execute</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-fname.html b/doc/src/sgml/html/spi-spi-fname.html
new file mode 100644
index 0000000..f80604e
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-fname.html
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_fname</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-interface-support.html" title="47.2. Interface Support Functions" /><link rel="next" href="spi-spi-fnumber.html" title="SPI_fnumber" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_fname</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-interface-support.html" title="47.2. Interface Support Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-fnumber.html" title="SPI_fnumber">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-FNAME"><div class="titlepage"></div><a id="id-1.8.12.9.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_fname</span></h2><p>SPI_fname — determine the column name for the specified column number</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+char * SPI_fname(TupleDesc <em class="parameter"><code>rowdesc</code></em>, int <em class="parameter"><code>colnumber</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.4.5"><h2>Description</h2><p>
+ <code class="function">SPI_fname</code> returns a copy of the column name of the
+ specified column. (You can use <code class="function">pfree</code> to
+ release the copy of the name when you don't need it anymore.)
+ </p></div><div class="refsect1" id="id-1.8.12.9.4.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ input row description
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>colnumber</code></em></code></span></dt><dd><p>
+ column number (count starts at 1)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.4.7"><h2>Return Value</h2><p>
+ The column name; <code class="symbol">NULL</code> if
+ <em class="parameter"><code>colnumber</code></em> is out of range.
+ <code class="varname">SPI_result</code> set to
+ <code class="symbol">SPI_ERROR_NOATTRIBUTE</code> on error.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-interface-support.html" title="47.2. Interface Support Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-fnumber.html" title="SPI_fnumber">Next</a></td></tr><tr><td width="40%" align="left" valign="top">47.2. Interface Support Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_fnumber</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-fnumber.html b/doc/src/sgml/html/spi-spi-fnumber.html
new file mode 100644
index 0000000..ead1d66
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-fnumber.html
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_fnumber</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-fname.html" title="SPI_fname" /><link rel="next" href="spi-spi-getvalue.html" title="SPI_getvalue" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_fnumber</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-fname.html" title="SPI_fname">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-getvalue.html" title="SPI_getvalue">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-FNUMBER"><div class="titlepage"></div><a id="id-1.8.12.9.5.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_fnumber</span></h2><p>SPI_fnumber — determine the column number for the specified column name</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_fnumber(TupleDesc <em class="parameter"><code>rowdesc</code></em>, const char * <em class="parameter"><code>colname</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.5.5"><h2>Description</h2><p>
+ <code class="function">SPI_fnumber</code> returns the column number for the
+ column with the specified name.
+ </p><p>
+ If <em class="parameter"><code>colname</code></em> refers to a system column (e.g.,
+ <code class="literal">ctid</code>) then the appropriate negative column number will
+ be returned. The caller should be careful to test the return value
+ for exact equality to <code class="symbol">SPI_ERROR_NOATTRIBUTE</code> to
+ detect an error; testing the result for less than or equal to 0 is
+ not correct unless system columns should be rejected.
+ </p></div><div class="refsect1" id="id-1.8.12.9.5.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ input row description
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>colname</code></em></code></span></dt><dd><p>
+ column name
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.5.7"><h2>Return Value</h2><p>
+ Column number (count starts at 1 for user-defined columns), or
+ <code class="symbol">SPI_ERROR_NOATTRIBUTE</code> if the named column was not
+ found.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-fname.html" title="SPI_fname">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-getvalue.html" title="SPI_getvalue">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_fname </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_getvalue</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-freeplan.html b/doc/src/sgml/html/spi-spi-freeplan.html
new file mode 100644
index 0000000..354725b
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-freeplan.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_freeplan</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-freetupletable.html" title="SPI_freetuptable" /><link rel="next" href="spi-transaction.html" title="47.4. Transaction Management" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_freeplan</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-freetupletable.html" title="SPI_freetuptable">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-transaction.html" title="47.4. Transaction Management">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-FREEPLAN"><div class="titlepage"></div><a id="id-1.8.12.10.14.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_freeplan</span></h2><p>SPI_freeplan — free a previously saved prepared statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_freeplan(SPIPlanPtr <em class="parameter"><code>plan</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.14.5"><h2>Description</h2><p>
+ <code class="function">SPI_freeplan</code> releases a prepared statement
+ previously returned by <code class="function">SPI_prepare</code> or saved by
+ <code class="function">SPI_keepplan</code> or <code class="function">SPI_saveplan</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.10.14.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ pointer to statement to free
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.10.14.7"><h2>Return Value</h2><p>
+ 0 on success;
+ <code class="symbol">SPI_ERROR_ARGUMENT</code> if <em class="parameter"><code>plan</code></em>
+ is <code class="symbol">NULL</code> or invalid
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-freetupletable.html" title="SPI_freetuptable">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-transaction.html" title="47.4. Transaction Management">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_freetuptable </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 47.4. Transaction Management</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-freetuple.html b/doc/src/sgml/html/spi-spi-freetuple.html
new file mode 100644
index 0000000..63df190
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-freetuple.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_freetuple</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-modifytuple.html" title="SPI_modifytuple" /><link rel="next" href="spi-spi-freetupletable.html" title="SPI_freetuptable" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_freetuple</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-modifytuple.html" title="SPI_modifytuple">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-freetupletable.html" title="SPI_freetuptable">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-FREETUPLE"><div class="titlepage"></div><a id="id-1.8.12.10.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_freetuple</span></h2><p>SPI_freetuple — free a row allocated in the upper executor context</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_freetuple(HeapTuple <em class="parameter"><code>row</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.12.5"><h2>Description</h2><p>
+ <code class="function">SPI_freetuple</code> frees a row previously allocated
+ in the upper executor context.
+ </p><p>
+ This function is no longer different from plain
+ <code class="function">heap_freetuple</code>. It's kept just for backward
+ compatibility of existing code.
+ </p></div><div class="refsect1" id="id-1.8.12.10.12.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">HeapTuple <em class="parameter"><code>row</code></em></code></span></dt><dd><p>
+ row to free
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-modifytuple.html" title="SPI_modifytuple">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-freetupletable.html" title="SPI_freetuptable">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_modifytuple </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_freetuptable</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-freetupletable.html b/doc/src/sgml/html/spi-spi-freetupletable.html
new file mode 100644
index 0000000..06e9b4d
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-freetupletable.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_freetuptable</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-freetuple.html" title="SPI_freetuple" /><link rel="next" href="spi-spi-freeplan.html" title="SPI_freeplan" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_freetuptable</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-freetuple.html" title="SPI_freetuple">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-freeplan.html" title="SPI_freeplan">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-FREETUPLETABLE"><div class="titlepage"></div><a id="id-1.8.12.10.13.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_freetuptable</span></h2><p>SPI_freetuptable — free a row set created by <code class="function">SPI_execute</code> or a similar
+ function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_freetuptable(SPITupleTable * <em class="parameter"><code>tuptable</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.13.5"><h2>Description</h2><p>
+ <code class="function">SPI_freetuptable</code> frees a row set created by a
+ prior SPI command execution function, such as
+ <code class="function">SPI_execute</code>. Therefore, this function is often called
+ with the global variable <code class="varname">SPI_tuptable</code> as
+ argument.
+ </p><p>
+ This function is useful if an SPI-using C function needs to execute
+ multiple commands and does not want to keep the results of earlier
+ commands around until it ends. Note that any unfreed row sets will
+ be freed anyway at <code class="function">SPI_finish</code>.
+ Also, if a subtransaction is started and then aborted within execution
+ of an SPI-using C function, SPI automatically frees any row sets created while
+ the subtransaction was running.
+ </p><p>
+ Beginning in <span class="productname">PostgreSQL</span> 9.3,
+ <code class="function">SPI_freetuptable</code> contains guard logic to protect
+ against duplicate deletion requests for the same row set. In previous
+ releases, duplicate deletions would lead to crashes.
+ </p></div><div class="refsect1" id="id-1.8.12.10.13.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPITupleTable * <em class="parameter"><code>tuptable</code></em></code></span></dt><dd><p>
+ pointer to row set to free, or NULL to do nothing
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-freetuple.html" title="SPI_freetuple">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-freeplan.html" title="SPI_freeplan">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_freetuple </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_freeplan</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-getargcount.html b/doc/src/sgml/html/spi-spi-getargcount.html
new file mode 100644
index 0000000..2839909
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-getargcount.html
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_getargcount</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-prepare-params.html" title="SPI_prepare_params" /><link rel="next" href="spi-spi-getargtypeid.html" title="SPI_getargtypeid" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_getargcount</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-prepare-params.html" title="SPI_prepare_params">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-getargtypeid.html" title="SPI_getargtypeid">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETARGCOUNT"><div class="titlepage"></div><a id="id-1.8.12.8.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_getargcount</span></h2><p>SPI_getargcount — return the number of arguments needed by a statement
+ prepared by <code class="function">SPI_prepare</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_getargcount(SPIPlanPtr <em class="parameter"><code>plan</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.12.5"><h2>Description</h2><p>
+ <code class="function">SPI_getargcount</code> returns the number of arguments needed
+ to execute a statement prepared by <code class="function">SPI_prepare</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.12.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.12.7"><h2>Return Value</h2><p>
+ The count of expected arguments for the <em class="parameter"><code>plan</code></em>.
+ If the <em class="parameter"><code>plan</code></em> is <code class="symbol">NULL</code> or invalid,
+ <code class="varname">SPI_result</code> is set to <code class="symbol">SPI_ERROR_ARGUMENT</code>
+ and -1 is returned.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-prepare-params.html" title="SPI_prepare_params">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-getargtypeid.html" title="SPI_getargtypeid">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_prepare_params </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_getargtypeid</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-getargtypeid.html b/doc/src/sgml/html/spi-spi-getargtypeid.html
new file mode 100644
index 0000000..0aa0e34
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-getargtypeid.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_getargtypeid</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-getargcount.html" title="SPI_getargcount" /><link rel="next" href="spi-spi-is-cursor-plan.html" title="SPI_is_cursor_plan" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_getargtypeid</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-getargcount.html" title="SPI_getargcount">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-is-cursor-plan.html" title="SPI_is_cursor_plan">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETARGTYPEID"><div class="titlepage"></div><a id="id-1.8.12.8.13.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_getargtypeid</span></h2><p>SPI_getargtypeid — return the data type OID for an argument of
+ a statement prepared by <code class="function">SPI_prepare</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Oid SPI_getargtypeid(SPIPlanPtr <em class="parameter"><code>plan</code></em>, int <em class="parameter"><code>argIndex</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.13.5"><h2>Description</h2><p>
+ <code class="function">SPI_getargtypeid</code> returns the OID representing the type
+ for the <em class="parameter"><code>argIndex</code></em>'th argument of a statement prepared by
+ <code class="function">SPI_prepare</code>. First argument is at index zero.
+ </p></div><div class="refsect1" id="id-1.8.12.8.13.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>argIndex</code></em></code></span></dt><dd><p>
+ zero based index of the argument
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.13.7"><h2>Return Value</h2><p>
+ The type OID of the argument at the given index.
+ If the <em class="parameter"><code>plan</code></em> is <code class="symbol">NULL</code> or invalid,
+ or <em class="parameter"><code>argIndex</code></em> is less than 0 or
+ not less than the number of arguments declared for the
+ <em class="parameter"><code>plan</code></em>,
+ <code class="varname">SPI_result</code> is set to <code class="symbol">SPI_ERROR_ARGUMENT</code>
+ and <code class="symbol">InvalidOid</code> is returned.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-getargcount.html" title="SPI_getargcount">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-is-cursor-plan.html" title="SPI_is_cursor_plan">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_getargcount </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_is_cursor_plan</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-getbinval.html b/doc/src/sgml/html/spi-spi-getbinval.html
new file mode 100644
index 0000000..57a0af6
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-getbinval.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_getbinval</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-getvalue.html" title="SPI_getvalue" /><link rel="next" href="spi-spi-gettype.html" title="SPI_gettype" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_getbinval</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-getvalue.html" title="SPI_getvalue">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-gettype.html" title="SPI_gettype">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETBINVAL"><div class="titlepage"></div><a id="id-1.8.12.9.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_getbinval</span></h2><p>SPI_getbinval — return the binary value of the specified column</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Datum SPI_getbinval(HeapTuple <em class="parameter"><code>row</code></em>, TupleDesc <em class="parameter"><code>rowdesc</code></em>, int <em class="parameter"><code>colnumber</code></em>,
+ bool * <em class="parameter"><code>isnull</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.7.5"><h2>Description</h2><p>
+ <code class="function">SPI_getbinval</code> returns the value of the
+ specified column in the internal form (as type <code class="type">Datum</code>).
+ </p><p>
+ This function does not allocate new space for the datum. In the
+ case of a pass-by-reference data type, the return value will be a
+ pointer into the passed row.
+ </p></div><div class="refsect1" id="id-1.8.12.9.7.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">HeapTuple <em class="parameter"><code>row</code></em></code></span></dt><dd><p>
+ input row to be examined
+ </p></dd><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ input row description
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>colnumber</code></em></code></span></dt><dd><p>
+ column number (count starts at 1)
+ </p></dd><dt><span class="term"><code class="literal">bool * <em class="parameter"><code>isnull</code></em></code></span></dt><dd><p>
+ flag for a null value in the column
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.7.7"><h2>Return Value</h2><p>
+ The binary value of the column is returned. The variable pointed
+ to by <em class="parameter"><code>isnull</code></em> is set to true if the column is
+ null, else to false.
+ </p><p>
+ <code class="varname">SPI_result</code> is set to
+ <code class="symbol">SPI_ERROR_NOATTRIBUTE</code> on error.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-getvalue.html" title="SPI_getvalue">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-gettype.html" title="SPI_gettype">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_getvalue </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_gettype</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-getnspname.html b/doc/src/sgml/html/spi-spi-getnspname.html
new file mode 100644
index 0000000..1bc7908
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-getnspname.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_getnspname</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-getrelname.html" title="SPI_getrelname" /><link rel="next" href="spi-spi-result-code-string.html" title="SPI_result_code_string" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_getnspname</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-getrelname.html" title="SPI_getrelname">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-result-code-string.html" title="SPI_result_code_string">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETNSPNAME"><div class="titlepage"></div><a id="id-1.8.12.9.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_getnspname</span></h2><p>SPI_getnspname — return the namespace of the specified relation</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+char * SPI_getnspname(Relation <em class="parameter"><code>rel</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.11.5"><h2>Description</h2><p>
+ <code class="function">SPI_getnspname</code> returns a copy of the name of
+ the namespace that the specified <code class="structname">Relation</code>
+ belongs to. This is equivalent to the relation's schema. You should
+ <code class="function">pfree</code> the return value of this function when
+ you are finished with it.
+ </p></div><div class="refsect1" id="id-1.8.12.9.11.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Relation <em class="parameter"><code>rel</code></em></code></span></dt><dd><p>
+ input relation
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.11.7"><h2>Return Value</h2><p>
+ The name of the specified relation's namespace.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-getrelname.html" title="SPI_getrelname">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-result-code-string.html" title="SPI_result_code_string">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_getrelname </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_result_code_string</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-getrelname.html b/doc/src/sgml/html/spi-spi-getrelname.html
new file mode 100644
index 0000000..a00a9fb
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-getrelname.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_getrelname</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-gettypeid.html" title="SPI_gettypeid" /><link rel="next" href="spi-spi-getnspname.html" title="SPI_getnspname" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_getrelname</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-gettypeid.html" title="SPI_gettypeid">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-getnspname.html" title="SPI_getnspname">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETRELNAME"><div class="titlepage"></div><a id="id-1.8.12.9.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_getrelname</span></h2><p>SPI_getrelname — return the name of the specified relation</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+char * SPI_getrelname(Relation <em class="parameter"><code>rel</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.10.5"><h2>Description</h2><p>
+ <code class="function">SPI_getrelname</code> returns a copy of the name of the
+ specified relation. (You can use <code class="function">pfree</code> to
+ release the copy of the name when you don't need it anymore.)
+ </p></div><div class="refsect1" id="id-1.8.12.9.10.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Relation <em class="parameter"><code>rel</code></em></code></span></dt><dd><p>
+ input relation
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.10.7"><h2>Return Value</h2><p>
+ The name of the specified relation.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-gettypeid.html" title="SPI_gettypeid">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-getnspname.html" title="SPI_getnspname">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_gettypeid </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_getnspname</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-gettype.html b/doc/src/sgml/html/spi-spi-gettype.html
new file mode 100644
index 0000000..83d2ae3
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-gettype.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_gettype</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-getbinval.html" title="SPI_getbinval" /><link rel="next" href="spi-spi-gettypeid.html" title="SPI_gettypeid" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_gettype</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-getbinval.html" title="SPI_getbinval">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-gettypeid.html" title="SPI_gettypeid">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETTYPE"><div class="titlepage"></div><a id="id-1.8.12.9.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_gettype</span></h2><p>SPI_gettype — return the data type name of the specified column</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+char * SPI_gettype(TupleDesc <em class="parameter"><code>rowdesc</code></em>, int <em class="parameter"><code>colnumber</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.8.5"><h2>Description</h2><p>
+ <code class="function">SPI_gettype</code> returns a copy of the data type name of the
+ specified column. (You can use <code class="function">pfree</code> to
+ release the copy of the name when you don't need it anymore.)
+ </p></div><div class="refsect1" id="id-1.8.12.9.8.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ input row description
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>colnumber</code></em></code></span></dt><dd><p>
+ column number (count starts at 1)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.8.7"><h2>Return Value</h2><p>
+ The data type name of the specified column, or
+ <code class="symbol">NULL</code> on error. <code class="varname">SPI_result</code> is
+ set to <code class="symbol">SPI_ERROR_NOATTRIBUTE</code> on error.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-getbinval.html" title="SPI_getbinval">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-gettypeid.html" title="SPI_gettypeid">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_getbinval </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_gettypeid</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-gettypeid.html b/doc/src/sgml/html/spi-spi-gettypeid.html
new file mode 100644
index 0000000..f4b6a3d
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-gettypeid.html
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_gettypeid</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-gettype.html" title="SPI_gettype" /><link rel="next" href="spi-spi-getrelname.html" title="SPI_getrelname" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_gettypeid</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-gettype.html" title="SPI_gettype">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-getrelname.html" title="SPI_getrelname">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETTYPEID"><div class="titlepage"></div><a id="id-1.8.12.9.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_gettypeid</span></h2><p>SPI_gettypeid — return the data type <acronym class="acronym">OID</acronym> of the specified column</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+Oid SPI_gettypeid(TupleDesc <em class="parameter"><code>rowdesc</code></em>, int <em class="parameter"><code>colnumber</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.9.5"><h2>Description</h2><p>
+ <code class="function">SPI_gettypeid</code> returns the
+ <acronym class="acronym">OID</acronym> of the data type of the specified column.
+ </p></div><div class="refsect1" id="id-1.8.12.9.9.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ input row description
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>colnumber</code></em></code></span></dt><dd><p>
+ column number (count starts at 1)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.9.7"><h2>Return Value</h2><p>
+ The <acronym class="acronym">OID</acronym> of the data type of the specified column
+ or <code class="symbol">InvalidOid</code> on error. On error,
+ <code class="varname">SPI_result</code> is set to
+ <code class="symbol">SPI_ERROR_NOATTRIBUTE</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-gettype.html" title="SPI_gettype">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-getrelname.html" title="SPI_getrelname">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_gettype </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_getrelname</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-getvalue.html b/doc/src/sgml/html/spi-spi-getvalue.html
new file mode 100644
index 0000000..56ed644
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-getvalue.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_getvalue</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-fnumber.html" title="SPI_fnumber" /><link rel="next" href="spi-spi-getbinval.html" title="SPI_getbinval" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_getvalue</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-fnumber.html" title="SPI_fnumber">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-getbinval.html" title="SPI_getbinval">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-GETVALUE"><div class="titlepage"></div><a id="id-1.8.12.9.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_getvalue</span></h2><p>SPI_getvalue — return the string value of the specified column</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+char * SPI_getvalue(HeapTuple <em class="parameter"><code>row</code></em>, TupleDesc <em class="parameter"><code>rowdesc</code></em>, int <em class="parameter"><code>colnumber</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.9.6.5"><h2>Description</h2><p>
+ <code class="function">SPI_getvalue</code> returns the string representation
+ of the value of the specified column.
+ </p><p>
+ The result is returned in memory allocated using
+ <code class="function">palloc</code>. (You can use
+ <code class="function">pfree</code> to release the memory when you don't
+ need it anymore.)
+ </p></div><div class="refsect1" id="id-1.8.12.9.6.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">HeapTuple <em class="parameter"><code>row</code></em></code></span></dt><dd><p>
+ input row to be examined
+ </p></dd><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ input row description
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>colnumber</code></em></code></span></dt><dd><p>
+ column number (count starts at 1)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.6.7"><h2>Return Value</h2><p>
+ Column value, or <code class="symbol">NULL</code> if the column is null,
+ <em class="parameter"><code>colnumber</code></em> is out of range
+ (<code class="varname">SPI_result</code> is set to
+ <code class="symbol">SPI_ERROR_NOATTRIBUTE</code>), or no output function is
+ available (<code class="varname">SPI_result</code> is set to
+ <code class="symbol">SPI_ERROR_NOOUTFUNC</code>).
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-fnumber.html" title="SPI_fnumber">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-getbinval.html" title="SPI_getbinval">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_fnumber </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_getbinval</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-is-cursor-plan.html b/doc/src/sgml/html/spi-spi-is-cursor-plan.html
new file mode 100644
index 0000000..73ce2fd
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-is-cursor-plan.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_is_cursor_plan</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-getargtypeid.html" title="SPI_getargtypeid" /><link rel="next" href="spi-spi-execute-plan.html" title="SPI_execute_plan" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_is_cursor_plan</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-getargtypeid.html" title="SPI_getargtypeid">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-execute-plan.html" title="SPI_execute_plan">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-IS-CURSOR-PLAN"><div class="titlepage"></div><a id="id-1.8.12.8.14.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_is_cursor_plan</span></h2><p>SPI_is_cursor_plan — return <code class="symbol">true</code> if a statement
+ prepared by <code class="function">SPI_prepare</code> can be used with
+ <code class="function">SPI_cursor_open</code></p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+bool SPI_is_cursor_plan(SPIPlanPtr <em class="parameter"><code>plan</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.14.5"><h2>Description</h2><p>
+ <code class="function">SPI_is_cursor_plan</code> returns <code class="symbol">true</code>
+ if a statement prepared by <code class="function">SPI_prepare</code> can be passed
+ as an argument to <code class="function">SPI_cursor_open</code>, or
+ <code class="symbol">false</code> if that is not the case. The criteria are that the
+ <em class="parameter"><code>plan</code></em> represents one single command and that this
+ command returns tuples to the caller; for example, <code class="command">SELECT</code>
+ is allowed unless it contains an <code class="literal">INTO</code> clause, and
+ <code class="command">UPDATE</code> is allowed only if it contains a <code class="literal">RETURNING</code>
+ clause.
+ </p></div><div class="refsect1" id="id-1.8.12.8.14.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ prepared statement (returned by <code class="function">SPI_prepare</code>)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.14.7"><h2>Return Value</h2><p>
+ <code class="symbol">true</code> or <code class="symbol">false</code> to indicate if the
+ <em class="parameter"><code>plan</code></em> can produce a cursor or not, with
+ <code class="varname">SPI_result</code> set to zero.
+ If it is not possible to determine the answer (for example,
+ if the <em class="parameter"><code>plan</code></em> is <code class="symbol">NULL</code> or invalid,
+ or if called when not connected to SPI), then
+ <code class="varname">SPI_result</code> is set to a suitable error code
+ and <code class="symbol">false</code> is returned.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-getargtypeid.html" title="SPI_getargtypeid">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-execute-plan.html" title="SPI_execute_plan">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_getargtypeid </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_execute_plan</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-keepplan.html b/doc/src/sgml/html/spi-spi-keepplan.html
new file mode 100644
index 0000000..283626e
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-keepplan.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_keepplan</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-close.html" title="SPI_cursor_close" /><link rel="next" href="spi-spi-saveplan.html" title="SPI_saveplan" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_keepplan</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-close.html" title="SPI_cursor_close">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-saveplan.html" title="SPI_saveplan">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-KEEPPLAN"><div class="titlepage"></div><a id="id-1.8.12.8.29.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_keepplan</span></h2><p>SPI_keepplan — save a prepared statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_keepplan(SPIPlanPtr <em class="parameter"><code>plan</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.29.5"><h2>Description</h2><p>
+ <code class="function">SPI_keepplan</code> saves a passed statement (prepared by
+ <code class="function">SPI_prepare</code>) so that it will not be freed
+ by <code class="function">SPI_finish</code> nor by the transaction manager.
+ This gives you the ability to reuse prepared statements in the subsequent
+ invocations of your C function in the current session.
+ </p></div><div class="refsect1" id="id-1.8.12.8.29.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ the prepared statement to be saved
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.29.7"><h2>Return Value</h2><p>
+ 0 on success;
+ <code class="symbol">SPI_ERROR_ARGUMENT</code> if <em class="parameter"><code>plan</code></em>
+ is <code class="symbol">NULL</code> or invalid
+ </p></div><div class="refsect1" id="id-1.8.12.8.29.8"><h2>Notes</h2><p>
+ The passed-in statement is relocated to permanent storage by means
+ of pointer adjustment (no data copying is required). If you later
+ wish to delete it, use <code class="function">SPI_freeplan</code> on it.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-close.html" title="SPI_cursor_close">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-saveplan.html" title="SPI_saveplan">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_close </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_saveplan</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-modifytuple.html b/doc/src/sgml/html/spi-spi-modifytuple.html
new file mode 100644
index 0000000..80ae575
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-modifytuple.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_modifytuple</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-returntuple.html" title="SPI_returntuple" /><link rel="next" href="spi-spi-freetuple.html" title="SPI_freetuple" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_modifytuple</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-returntuple.html" title="SPI_returntuple">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-freetuple.html" title="SPI_freetuple">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-MODIFYTUPLE"><div class="titlepage"></div><a id="id-1.8.12.10.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_modifytuple</span></h2><p>SPI_modifytuple — create a row by replacing selected fields of a given row</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+HeapTuple SPI_modifytuple(Relation <em class="parameter"><code>rel</code></em>, HeapTuple <em class="parameter"><code>row</code></em>, int <em class="parameter"><code>ncols</code></em>,
+ int * <em class="parameter"><code>colnum</code></em>, Datum * <em class="parameter"><code>values</code></em>, const char * <em class="parameter"><code>nulls</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.11.5"><h2>Description</h2><p>
+ <code class="function">SPI_modifytuple</code> creates a new row by
+ substituting new values for selected columns, copying the original
+ row's columns at other positions. The input row is not modified.
+ The new row is returned in the upper executor context.
+ </p><p>
+ This function can only be used while connected to SPI.
+ Otherwise, it returns NULL and sets <code class="varname">SPI_result</code> to
+ <code class="symbol">SPI_ERROR_UNCONNECTED</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.10.11.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Relation <em class="parameter"><code>rel</code></em></code></span></dt><dd><p>
+ Used only as the source of the row descriptor for the row.
+ (Passing a relation rather than a row descriptor is a
+ misfeature.)
+ </p></dd><dt><span class="term"><code class="literal">HeapTuple <em class="parameter"><code>row</code></em></code></span></dt><dd><p>
+ row to be modified
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>ncols</code></em></code></span></dt><dd><p>
+ number of columns to be changed
+ </p></dd><dt><span class="term"><code class="literal">int * <em class="parameter"><code>colnum</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>ncols</code></em>, containing the numbers
+ of the columns that are to be changed (column numbers start at 1)
+ </p></dd><dt><span class="term"><code class="literal">Datum * <em class="parameter"><code>values</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>ncols</code></em>, containing the
+ new values for the specified columns
+ </p></dd><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>nulls</code></em></code></span></dt><dd><p>
+ an array of length <em class="parameter"><code>ncols</code></em>, describing which
+ new values are null
+ </p><p>
+ If <em class="parameter"><code>nulls</code></em> is <code class="symbol">NULL</code> then
+ <code class="function">SPI_modifytuple</code> assumes that no new values
+ are null. Otherwise, each entry of the <em class="parameter"><code>nulls</code></em>
+ array should be <code class="literal">' '</code> if the corresponding new value is
+ non-null, or <code class="literal">'n'</code> if the corresponding new value is
+ null. (In the latter case, the actual value in the corresponding
+ <em class="parameter"><code>values</code></em> entry doesn't matter.) Note that
+ <em class="parameter"><code>nulls</code></em> is not a text string, just an array: it
+ does not need a <code class="literal">'\0'</code> terminator.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.10.11.7"><h2>Return Value</h2><p>
+ new row with modifications, allocated in the upper executor
+ context, or <code class="symbol">NULL</code> on error
+ (see <code class="varname">SPI_result</code> for an error indication)
+ </p><p>
+ On error, <code class="varname">SPI_result</code> is set as follows:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>rel</code></em> is <code class="symbol">NULL</code>, or if
+ <em class="parameter"><code>row</code></em> is <code class="symbol">NULL</code>, or if <em class="parameter"><code>ncols</code></em>
+ is less than or equal to 0, or if <em class="parameter"><code>colnum</code></em> is
+ <code class="symbol">NULL</code>, or if <em class="parameter"><code>values</code></em> is <code class="symbol">NULL</code>.
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_NOATTRIBUTE</code></span></dt><dd><p>
+ if <em class="parameter"><code>colnum</code></em> contains an invalid column number (less
+ than or equal to 0 or greater than the number of columns in
+ <em class="parameter"><code>row</code></em>)
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if SPI is not active
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-returntuple.html" title="SPI_returntuple">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-freetuple.html" title="SPI_freetuple">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_returntuple </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_freetuple</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-palloc.html b/doc/src/sgml/html/spi-spi-palloc.html
new file mode 100644
index 0000000..20bf879
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-palloc.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_palloc</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-memory.html" title="47.3. Memory Management" /><link rel="next" href="spi-realloc.html" title="SPI_repalloc" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_palloc</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-memory.html" title="47.3. Memory Management">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-realloc.html" title="SPI_repalloc">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-PALLOC"><div class="titlepage"></div><a id="id-1.8.12.10.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_palloc</span></h2><p>SPI_palloc — allocate memory in the upper executor context</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void * SPI_palloc(Size <em class="parameter"><code>size</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.6.5"><h2>Description</h2><p>
+ <code class="function">SPI_palloc</code> allocates memory in the upper
+ executor context.
+ </p><p>
+ This function can only be used while connected to SPI.
+ Otherwise, it throws an error.
+ </p></div><div class="refsect1" id="id-1.8.12.10.6.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Size <em class="parameter"><code>size</code></em></code></span></dt><dd><p>
+ size in bytes of storage to allocate
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.10.6.7"><h2>Return Value</h2><p>
+ pointer to new storage space of the specified size
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-memory.html" title="47.3. Memory Management">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-realloc.html" title="SPI_repalloc">Next</a></td></tr><tr><td width="40%" align="left" valign="top">47.3. Memory Management </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_repalloc</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-pfree.html b/doc/src/sgml/html/spi-spi-pfree.html
new file mode 100644
index 0000000..6fd7438
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-pfree.html
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_pfree</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-realloc.html" title="SPI_repalloc" /><link rel="next" href="spi-spi-copytuple.html" title="SPI_copytuple" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_pfree</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-realloc.html" title="SPI_repalloc">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-copytuple.html" title="SPI_copytuple">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-PFREE"><div class="titlepage"></div><a id="id-1.8.12.10.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_pfree</span></h2><p>SPI_pfree — free memory in the upper executor context</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_pfree(void * <em class="parameter"><code>pointer</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.8.5"><h2>Description</h2><p>
+ <code class="function">SPI_pfree</code> frees memory previously allocated
+ using <code class="function">SPI_palloc</code> or
+ <code class="function">SPI_repalloc</code>.
+ </p><p>
+ This function is no longer different from plain
+ <code class="function">pfree</code>. It's kept just for backward
+ compatibility of existing code.
+ </p></div><div class="refsect1" id="id-1.8.12.10.8.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">void * <em class="parameter"><code>pointer</code></em></code></span></dt><dd><p>
+ pointer to existing storage to free
+ </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-realloc.html" title="SPI_repalloc">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-copytuple.html" title="SPI_copytuple">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_repalloc </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_copytuple</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-prepare-cursor.html b/doc/src/sgml/html/spi-spi-prepare-cursor.html
new file mode 100644
index 0000000..582374a
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-prepare-cursor.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_prepare_cursor</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-prepare.html" title="SPI_prepare" /><link rel="next" href="spi-spi-prepare-extended.html" title="SPI_prepare_extended" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_prepare_cursor</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-prepare.html" title="SPI_prepare">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-prepare-extended.html" title="SPI_prepare_extended">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-PREPARE-CURSOR"><div class="titlepage"></div><a id="id-1.8.12.8.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_prepare_cursor</span></h2><p>SPI_prepare_cursor — prepare a statement, without executing it yet</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SPIPlanPtr SPI_prepare_cursor(const char * <em class="parameter"><code>command</code></em>, int <em class="parameter"><code>nargs</code></em>,
+ Oid * <em class="parameter"><code>argtypes</code></em>, int <em class="parameter"><code>cursorOptions</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.9.5"><h2>Description</h2><p>
+ <code class="function">SPI_prepare_cursor</code> is identical to
+ <code class="function">SPI_prepare</code>, except that it also allows specification
+ of the planner's <span class="quote">“<span class="quote">cursor options</span>”</span> parameter. This is a bit mask
+ having the values shown in <code class="filename">nodes/parsenodes.h</code>
+ for the <code class="structfield">options</code> field of <code class="structname">DeclareCursorStmt</code>.
+ <code class="function">SPI_prepare</code> always takes the cursor options as zero.
+ </p><p>
+ This function is now deprecated in favor
+ of <code class="function">SPI_prepare_extended</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.9.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>nargs</code></em></code></span></dt><dd><p>
+ number of input parameters (<code class="literal">$1</code>, <code class="literal">$2</code>, etc.)
+ </p></dd><dt><span class="term"><code class="literal">Oid * <em class="parameter"><code>argtypes</code></em></code></span></dt><dd><p>
+ pointer to an array containing the <acronym class="acronym">OID</acronym>s of
+ the data types of the parameters
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>cursorOptions</code></em></code></span></dt><dd><p>
+ integer bit mask of cursor options; zero produces default behavior
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.9.7"><h2>Return Value</h2><p>
+ <code class="function">SPI_prepare_cursor</code> has the same return conventions as
+ <code class="function">SPI_prepare</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.9.8"><h2>Notes</h2><p>
+ Useful bits to set in <em class="parameter"><code>cursorOptions</code></em> include
+ <code class="symbol">CURSOR_OPT_SCROLL</code>,
+ <code class="symbol">CURSOR_OPT_NO_SCROLL</code>,
+ <code class="symbol">CURSOR_OPT_FAST_PLAN</code>,
+ <code class="symbol">CURSOR_OPT_GENERIC_PLAN</code>, and
+ <code class="symbol">CURSOR_OPT_CUSTOM_PLAN</code>. Note in particular that
+ <code class="symbol">CURSOR_OPT_HOLD</code> is ignored.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-prepare.html" title="SPI_prepare">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-prepare-extended.html" title="SPI_prepare_extended">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_prepare </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_prepare_extended</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-prepare-extended.html b/doc/src/sgml/html/spi-spi-prepare-extended.html
new file mode 100644
index 0000000..77cb3d0
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-prepare-extended.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_prepare_extended</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-prepare-cursor.html" title="SPI_prepare_cursor" /><link rel="next" href="spi-spi-prepare-params.html" title="SPI_prepare_params" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_prepare_extended</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-prepare-cursor.html" title="SPI_prepare_cursor">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-prepare-params.html" title="SPI_prepare_params">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-PREPARE-EXTENDED"><div class="titlepage"></div><a id="id-1.8.12.8.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_prepare_extended</span></h2><p>SPI_prepare_extended — prepare a statement, without executing it yet</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SPIPlanPtr SPI_prepare_extended(const char * <em class="parameter"><code>command</code></em>,
+ const SPIPrepareOptions * <em class="parameter"><code>options</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.10.5"><h2>Description</h2><p>
+ <code class="function">SPI_prepare_extended</code> creates and returns a prepared
+ statement for the specified command, but doesn't execute the command.
+ This function is equivalent to <code class="function">SPI_prepare</code>,
+ with the addition that the caller can specify options to control
+ the parsing of external parameter references, as well as other facets
+ of query parsing and planning.
+ </p></div><div class="refsect1" id="id-1.8.12.8.10.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">const SPIPrepareOptions * <em class="parameter"><code>options</code></em></code></span></dt><dd><p>
+ struct containing optional arguments
+ </p></dd></dl></div><p>
+ Callers should always zero out the entire <em class="parameter"><code>options</code></em>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <em class="parameter"><code>options</code></em> fields are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ParserSetupHook <em class="parameter"><code>parserSetup</code></em></code></span></dt><dd><p>
+ Parser hook setup function
+ </p></dd><dt><span class="term"><code class="literal">void * <em class="parameter"><code>parserSetupArg</code></em></code></span></dt><dd><p>
+ pass-through argument for <em class="parameter"><code>parserSetup</code></em>
+ </p></dd><dt><span class="term"><code class="literal">RawParseMode <em class="parameter"><code>parseMode</code></em></code></span></dt><dd><p>
+ mode for raw parsing; <code class="literal">RAW_PARSE_DEFAULT</code> (zero)
+ produces default behavior
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>cursorOptions</code></em></code></span></dt><dd><p>
+ integer bit mask of cursor options; zero produces default behavior
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.10.7"><h2>Return Value</h2><p>
+ <code class="function">SPI_prepare_extended</code> has the same return conventions as
+ <code class="function">SPI_prepare</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-prepare-cursor.html" title="SPI_prepare_cursor">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-prepare-params.html" title="SPI_prepare_params">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_prepare_cursor </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_prepare_params</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-prepare-params.html b/doc/src/sgml/html/spi-spi-prepare-params.html
new file mode 100644
index 0000000..dea788e
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-prepare-params.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_prepare_params</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-prepare-extended.html" title="SPI_prepare_extended" /><link rel="next" href="spi-spi-getargcount.html" title="SPI_getargcount" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_prepare_params</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-prepare-extended.html" title="SPI_prepare_extended">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-getargcount.html" title="SPI_getargcount">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-PREPARE-PARAMS"><div class="titlepage"></div><a id="id-1.8.12.8.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_prepare_params</span></h2><p>SPI_prepare_params — prepare a statement, without executing it yet</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SPIPlanPtr SPI_prepare_params(const char * <em class="parameter"><code>command</code></em>,
+ ParserSetupHook <em class="parameter"><code>parserSetup</code></em>,
+ void * <em class="parameter"><code>parserSetupArg</code></em>,
+ int <em class="parameter"><code>cursorOptions</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.11.5"><h2>Description</h2><p>
+ <code class="function">SPI_prepare_params</code> creates and returns a prepared
+ statement for the specified command, but doesn't execute the command.
+ This function is equivalent to <code class="function">SPI_prepare_cursor</code>,
+ with the addition that the caller can specify parser hook functions
+ to control the parsing of external parameter references.
+ </p><p>
+ This function is now deprecated in favor
+ of <code class="function">SPI_prepare_extended</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.11.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">ParserSetupHook <em class="parameter"><code>parserSetup</code></em></code></span></dt><dd><p>
+ Parser hook setup function
+ </p></dd><dt><span class="term"><code class="literal">void * <em class="parameter"><code>parserSetupArg</code></em></code></span></dt><dd><p>
+ pass-through argument for <em class="parameter"><code>parserSetup</code></em>
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>cursorOptions</code></em></code></span></dt><dd><p>
+ integer bit mask of cursor options; zero produces default behavior
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.11.7"><h2>Return Value</h2><p>
+ <code class="function">SPI_prepare_params</code> has the same return conventions as
+ <code class="function">SPI_prepare</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-prepare-extended.html" title="SPI_prepare_extended">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-getargcount.html" title="SPI_getargcount">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_prepare_extended </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_getargcount</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-prepare.html b/doc/src/sgml/html/spi-spi-prepare.html
new file mode 100644
index 0000000..4fc0bb8
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-prepare.html
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_prepare</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-execute-with-args.html" title="SPI_execute_with_args" /><link rel="next" href="spi-spi-prepare-cursor.html" title="SPI_prepare_cursor" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_prepare</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-execute-with-args.html" title="SPI_execute_with_args">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-prepare-cursor.html" title="SPI_prepare_cursor">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-PREPARE"><div class="titlepage"></div><a id="id-1.8.12.8.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_prepare</span></h2><p>SPI_prepare — prepare a statement, without executing it yet</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SPIPlanPtr SPI_prepare(const char * <em class="parameter"><code>command</code></em>, int <em class="parameter"><code>nargs</code></em>, Oid * <em class="parameter"><code>argtypes</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.8.5"><h2>Description</h2><p>
+ <code class="function">SPI_prepare</code> creates and returns a prepared
+ statement for the specified command, but doesn't execute the command.
+ The prepared statement can later be executed repeatedly using
+ <code class="function">SPI_execute_plan</code>.
+ </p><p>
+ When the same or a similar command is to be executed repeatedly, it
+ is generally advantageous to perform parse analysis only once, and
+ might furthermore be advantageous to re-use an execution plan for the
+ command.
+ <code class="function">SPI_prepare</code> converts a command string into a
+ prepared statement that encapsulates the results of parse analysis.
+ The prepared statement also provides a place for caching an execution plan
+ if it is found that generating a custom plan for each execution is not
+ helpful.
+ </p><p>
+ A prepared command can be generalized by writing parameters
+ (<code class="literal">$1</code>, <code class="literal">$2</code>, etc.) in place of what would be
+ constants in a normal command. The actual values of the parameters
+ are then specified when <code class="function">SPI_execute_plan</code> is called.
+ This allows the prepared command to be used over a wider range of
+ situations than would be possible without parameters.
+ </p><p>
+ The statement returned by <code class="function">SPI_prepare</code> can be used
+ only in the current invocation of the C function, since
+ <code class="function">SPI_finish</code> frees memory allocated for such a
+ statement. But the statement can be saved for longer using the functions
+ <code class="function">SPI_keepplan</code> or <code class="function">SPI_saveplan</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.8.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p>
+ command string
+ </p></dd><dt><span class="term"><code class="literal">int <em class="parameter"><code>nargs</code></em></code></span></dt><dd><p>
+ number of input parameters (<code class="literal">$1</code>, <code class="literal">$2</code>, etc.)
+ </p></dd><dt><span class="term"><code class="literal">Oid * <em class="parameter"><code>argtypes</code></em></code></span></dt><dd><p>
+ pointer to an array containing the <acronym class="acronym">OID</acronym>s of
+ the data types of the parameters
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.8.7"><h2>Return Value</h2><p>
+ <code class="function">SPI_prepare</code> returns a non-null pointer to an
+ <code class="type">SPIPlan</code>, which is an opaque struct representing a prepared
+ statement. On error, <code class="symbol">NULL</code> will be returned,
+ and <code class="varname">SPI_result</code> will be set to one of the same
+ error codes used by <code class="function">SPI_execute</code>, except that
+ it is set to <code class="symbol">SPI_ERROR_ARGUMENT</code> if
+ <em class="parameter"><code>command</code></em> is <code class="symbol">NULL</code>, or if
+ <em class="parameter"><code>nargs</code></em> is less than 0, or if <em class="parameter"><code>nargs</code></em> is
+ greater than 0 and <em class="parameter"><code>argtypes</code></em> is <code class="symbol">NULL</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.8.8"><h2>Notes</h2><p>
+ If no parameters are defined, a generic plan will be created at the
+ first use of <code class="function">SPI_execute_plan</code>, and used for all
+ subsequent executions as well. If there are parameters, the first few uses
+ of <code class="function">SPI_execute_plan</code> will generate custom plans
+ that are specific to the supplied parameter values. After enough uses
+ of the same prepared statement, <code class="function">SPI_execute_plan</code> will
+ build a generic plan, and if that is not too much more expensive than the
+ custom plans, it will start using the generic plan instead of re-planning
+ each time. If this default behavior is unsuitable, you can alter it by
+ passing the <code class="literal">CURSOR_OPT_GENERIC_PLAN</code> or
+ <code class="literal">CURSOR_OPT_CUSTOM_PLAN</code> flag to
+ <code class="function">SPI_prepare_cursor</code>, to force use of generic or custom
+ plans respectively.
+ </p><p>
+ Although the main point of a prepared statement is to avoid repeated parse
+ analysis and planning of the statement, <span class="productname">PostgreSQL</span> will
+ force re-analysis and re-planning of the statement before using it
+ whenever database objects used in the statement have undergone
+ definitional (DDL) changes since the previous use of the prepared
+ statement. Also, if the value of <a class="xref" href="runtime-config-client.html#GUC-SEARCH-PATH">search_path</a> changes
+ from one use to the next, the statement will be re-parsed using the new
+ <code class="varname">search_path</code>. (This latter behavior is new as of
+ <span class="productname">PostgreSQL</span> 9.3.) See <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a> for more information about the behavior of prepared
+ statements.
+ </p><p>
+ This function should only be called from a connected C function.
+ </p><p>
+ <code class="type">SPIPlanPtr</code> is declared as a pointer to an opaque struct type in
+ <code class="filename">spi.h</code>. It is unwise to try to access its contents
+ directly, as that makes your code much more likely to break in
+ future revisions of <span class="productname">PostgreSQL</span>.
+ </p><p>
+ The name <code class="type">SPIPlanPtr</code> is somewhat historical, since the data
+ structure no longer necessarily contains an execution plan.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-execute-with-args.html" title="SPI_execute_with_args">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-prepare-cursor.html" title="SPI_prepare_cursor">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_execute_with_args </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_prepare_cursor</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-register-relation.html b/doc/src/sgml/html/spi-spi-register-relation.html
new file mode 100644
index 0000000..21e4b2e
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-register-relation.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_register_relation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-saveplan.html" title="SPI_saveplan" /><link rel="next" href="spi-spi-unregister-relation.html" title="SPI_unregister_relation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_register_relation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-saveplan.html" title="SPI_saveplan">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-unregister-relation.html" title="SPI_unregister_relation">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-REGISTER-RELATION"><div class="titlepage"></div><a id="id-1.8.12.8.31.1" class="indexterm"></a><a id="id-1.8.12.8.31.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_register_relation</span></h2><p>SPI_register_relation — make an ephemeral named relation available by name in SPI queries</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_register_relation(EphemeralNamedRelation <em class="parameter"><code>enr</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.31.6"><h2>Description</h2><p>
+ <code class="function">SPI_register_relation</code> makes an ephemeral named
+ relation, with associated information, available to queries planned and
+ executed through the current SPI connection.
+ </p></div><div class="refsect1" id="id-1.8.12.8.31.7"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">EphemeralNamedRelation <em class="parameter"><code>enr</code></em></code></span></dt><dd><p>
+ the ephemeral named relation registry entry
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.31.8"><h2>Return Value</h2><p>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_REL_REGISTER</code></span></dt><dd><p>
+ if the relation has been successfully registered by name
+ </p></dd></dl></div><p>
+ </p><p>
+ On error, one of the following negative values is returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>enr</code></em> is <code class="symbol">NULL</code> or its
+ <code class="varname">name</code> field is <code class="symbol">NULL</code>
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if called from an unconnected C function
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_REL_DUPLICATE</code></span></dt><dd><p>
+ if the name specified in the <code class="varname">name</code> field of
+ <em class="parameter"><code>enr</code></em> is already registered for this connection
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-saveplan.html" title="SPI_saveplan">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-unregister-relation.html" title="SPI_unregister_relation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_saveplan </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_unregister_relation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-register-trigger-data.html b/doc/src/sgml/html/spi-spi-register-trigger-data.html
new file mode 100644
index 0000000..57577bb
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-register-trigger-data.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_register_trigger_data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-unregister-relation.html" title="SPI_unregister_relation" /><link rel="next" href="spi-interface-support.html" title="47.2. Interface Support Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_register_trigger_data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-unregister-relation.html" title="SPI_unregister_relation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-interface-support.html" title="47.2. Interface Support Functions">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-REGISTER-TRIGGER-DATA"><div class="titlepage"></div><a id="id-1.8.12.8.33.1" class="indexterm"></a><a id="id-1.8.12.8.33.2" class="indexterm"></a><a id="id-1.8.12.8.33.3" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_register_trigger_data</span></h2><p>SPI_register_trigger_data — make ephemeral trigger data available in SPI queries</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_register_trigger_data(TriggerData *<em class="parameter"><code>tdata</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.33.7"><h2>Description</h2><p>
+ <code class="function">SPI_register_trigger_data</code> makes any ephemeral
+ relations captured by a trigger available to queries planned and executed
+ through the current SPI connection. Currently, this means the transition
+ tables captured by an <code class="literal">AFTER</code> trigger defined with a
+ <code class="literal">REFERENCING OLD/NEW TABLE AS</code> ... clause. This function
+ should be called by a PL trigger handler function after connecting.
+ </p></div><div class="refsect1" id="id-1.8.12.8.33.8"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TriggerData *<em class="parameter"><code>tdata</code></em></code></span></dt><dd><p>
+ the <code class="structname">TriggerData</code> object passed to a trigger
+ handler function as <code class="literal">fcinfo-&gt;context</code>
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.33.9"><h2>Return Value</h2><p>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_TD_REGISTER</code></span></dt><dd><p>
+ if the captured trigger data (if any) has been successfully registered
+ </p></dd></dl></div><p>
+ </p><p>
+ On error, one of the following negative values is returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>tdata</code></em> is <code class="symbol">NULL</code>
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if called from an unconnected C function
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_REL_DUPLICATE</code></span></dt><dd><p>
+ if the name of any trigger data transient relation is already
+ registered for this connection
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-unregister-relation.html" title="SPI_unregister_relation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-interface-support.html" title="47.2. Interface Support Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_unregister_relation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 47.2. Interface Support Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-result-code-string.html b/doc/src/sgml/html/spi-spi-result-code-string.html
new file mode 100644
index 0000000..3566271
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-result-code-string.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_result_code_string</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-getnspname.html" title="SPI_getnspname" /><link rel="next" href="spi-memory.html" title="47.3. Memory Management" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_result_code_string</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-getnspname.html" title="SPI_getnspname">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><th width="60%" align="center">47.2. Interface Support Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-memory.html" title="47.3. Memory Management">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-RESULT-CODE-STRING"><div class="titlepage"></div><a id="id-1.8.12.9.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_result_code_string</span></h2><p>SPI_result_code_string — return error code as string</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+const char * SPI_result_code_string(int <em class="parameter"><code>code</code></em>);
+</pre></div><div class="refsect1" id="id-1.8.12.9.12.5"><h2>Description</h2><p>
+ <code class="function">SPI_result_code_string</code> returns a string representation
+ of the result code returned by various SPI functions or stored
+ in <code class="varname">SPI_result</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.9.12.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">int <em class="parameter"><code>code</code></em></code></span></dt><dd><p>
+ result code
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.9.12.7"><h2>Return Value</h2><p>
+ A string representation of the result code.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-getnspname.html" title="SPI_getnspname">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface-support.html" title="47.2. Interface Support Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-memory.html" title="47.3. Memory Management">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_getnspname </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 47.3. Memory Management</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-returntuple.html b/doc/src/sgml/html/spi-spi-returntuple.html
new file mode 100644
index 0000000..dbbdc75
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-returntuple.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_returntuple</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-copytuple.html" title="SPI_copytuple" /><link rel="next" href="spi-spi-modifytuple.html" title="SPI_modifytuple" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_returntuple</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-copytuple.html" title="SPI_copytuple">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><th width="60%" align="center">47.3. Memory Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-modifytuple.html" title="SPI_modifytuple">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-RETURNTUPLE"><div class="titlepage"></div><a id="id-1.8.12.10.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_returntuple</span></h2><p>SPI_returntuple — prepare to return a tuple as a Datum</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+HeapTupleHeader SPI_returntuple(HeapTuple <em class="parameter"><code>row</code></em>, TupleDesc <em class="parameter"><code>rowdesc</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.10.10.5"><h2>Description</h2><p>
+ <code class="function">SPI_returntuple</code> makes a copy of a row in
+ the upper executor context, returning it in the form of a row type <code class="type">Datum</code>.
+ The returned pointer need only be converted to <code class="type">Datum</code> via <code class="function">PointerGetDatum</code>
+ before returning.
+ </p><p>
+ This function can only be used while connected to SPI.
+ Otherwise, it returns NULL and sets <code class="varname">SPI_result</code> to
+ <code class="symbol">SPI_ERROR_UNCONNECTED</code>.
+ </p><p>
+ Note that this should be used for functions that are declared to return
+ composite types. It is not used for triggers; use
+ <code class="function">SPI_copytuple</code> for returning a modified row in a trigger.
+ </p></div><div class="refsect1" id="id-1.8.12.10.10.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">HeapTuple <em class="parameter"><code>row</code></em></code></span></dt><dd><p>
+ row to be copied
+ </p></dd><dt><span class="term"><code class="literal">TupleDesc <em class="parameter"><code>rowdesc</code></em></code></span></dt><dd><p>
+ descriptor for row (pass the same descriptor each time for most
+ effective caching)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.10.10.7"><h2>Return Value</h2><p>
+ <code class="type">HeapTupleHeader</code> pointing to copied row,
+ or <code class="symbol">NULL</code> on error
+ (see <code class="varname">SPI_result</code> for an error indication)
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-copytuple.html" title="SPI_copytuple">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-memory.html" title="47.3. Memory Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-modifytuple.html" title="SPI_modifytuple">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_copytuple </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_modifytuple</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-rollback.html b/doc/src/sgml/html/spi-spi-rollback.html
new file mode 100644
index 0000000..4f6ca99
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-rollback.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_rollback</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-commit.html" title="SPI_commit" /><link rel="next" href="spi-spi-start-transaction.html" title="SPI_start_transaction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_rollback</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-commit.html" title="SPI_commit">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-transaction.html" title="47.4. Transaction Management">Up</a></td><th width="60%" align="center">47.4. Transaction Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-ROLLBACK"><div class="titlepage"></div><a id="id-1.8.12.11.5.1" class="indexterm"></a><a id="id-1.8.12.11.5.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_rollback</span></h2><p>SPI_rollback, SPI_rollback_and_chain — abort the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_rollback(void)
+</pre><pre class="synopsis">
+void SPI_rollback_and_chain(void)
+</pre></div><div class="refsect1" id="id-1.8.12.11.5.6"><h2>Description</h2><p>
+ <code class="function">SPI_rollback</code> rolls back the current transaction. It
+ is approximately equivalent to running the SQL
+ command <code class="command">ROLLBACK</code>. After the transaction is rolled back,
+ a new transaction is automatically started using default transaction
+ characteristics, so that the caller can continue using SPI facilities.
+ </p><p>
+ <code class="function">SPI_rollback_and_chain</code> is the same, but the new
+ transaction is started with the same transaction
+ characteristics as the just finished one, like with the SQL command
+ <code class="command">ROLLBACK AND CHAIN</code>.
+ </p><p>
+ These functions can only be executed if the SPI connection has been set as
+ nonatomic in the call to <code class="function">SPI_connect_ext</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-commit.html" title="SPI_commit">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-transaction.html" title="47.4. Transaction Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_commit </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_start_transaction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-saveplan.html b/doc/src/sgml/html/spi-spi-saveplan.html
new file mode 100644
index 0000000..6a95e0f
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-saveplan.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_saveplan</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-keepplan.html" title="SPI_keepplan" /><link rel="next" href="spi-spi-register-relation.html" title="SPI_register_relation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_saveplan</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-keepplan.html" title="SPI_keepplan">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-register-relation.html" title="SPI_register_relation">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-SAVEPLAN"><div class="titlepage"></div><a id="id-1.8.12.8.30.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_saveplan</span></h2><p>SPI_saveplan — save a prepared statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SPIPlanPtr SPI_saveplan(SPIPlanPtr <em class="parameter"><code>plan</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.30.5"><h2>Description</h2><p>
+ <code class="function">SPI_saveplan</code> copies a passed statement (prepared by
+ <code class="function">SPI_prepare</code>) into memory that will not be freed
+ by <code class="function">SPI_finish</code> nor by the transaction manager,
+ and returns a pointer to the copied statement. This gives you the
+ ability to reuse prepared statements in the subsequent invocations of
+ your C function in the current session.
+ </p></div><div class="refsect1" id="id-1.8.12.8.30.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SPIPlanPtr <em class="parameter"><code>plan</code></em></code></span></dt><dd><p>
+ the prepared statement to be saved
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.30.7"><h2>Return Value</h2><p>
+ Pointer to the copied statement; or <code class="symbol">NULL</code> if unsuccessful.
+ On error, <code class="varname">SPI_result</code> is set thus:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>plan</code></em> is <code class="symbol">NULL</code> or invalid
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if called from an unconnected C function
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.8.12.8.30.8"><h2>Notes</h2><p>
+ The originally passed-in statement is not freed, so you might wish to do
+ <code class="function">SPI_freeplan</code> on it to avoid leaking memory
+ until <code class="function">SPI_finish</code>.
+ </p><p>
+ In most cases, <code class="function">SPI_keepplan</code> is preferred to this
+ function, since it accomplishes largely the same result without needing
+ to physically copy the prepared statement's data structures.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-keepplan.html" title="SPI_keepplan">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-register-relation.html" title="SPI_register_relation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_keepplan </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_register_relation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-scroll-cursor-fetch.html b/doc/src/sgml/html/spi-spi-scroll-cursor-fetch.html
new file mode 100644
index 0000000..92e8f47
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-scroll-cursor-fetch.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_scroll_cursor_fetch</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-cursor-move.html" title="SPI_cursor_move" /><link rel="next" href="spi-spi-scroll-cursor-move.html" title="SPI_scroll_cursor_move" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_scroll_cursor_fetch</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-cursor-move.html" title="SPI_cursor_move">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-scroll-cursor-move.html" title="SPI_scroll_cursor_move">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-SCROLL-CURSOR-FETCH"><div class="titlepage"></div><a id="id-1.8.12.8.26.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_scroll_cursor_fetch</span></h2><p>SPI_scroll_cursor_fetch — fetch some rows from a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_scroll_cursor_fetch(Portal <em class="parameter"><code>portal</code></em>, FetchDirection <em class="parameter"><code>direction</code></em>,
+ long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.26.5"><h2>Description</h2><p>
+ <code class="function">SPI_scroll_cursor_fetch</code> fetches some rows from a
+ cursor. This is equivalent to the SQL command <code class="command">FETCH</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.26.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Portal <em class="parameter"><code>portal</code></em></code></span></dt><dd><p>
+ portal containing the cursor
+ </p></dd><dt><span class="term"><code class="literal">FetchDirection <em class="parameter"><code>direction</code></em></code></span></dt><dd><p>
+ one of <code class="symbol">FETCH_FORWARD</code>,
+ <code class="symbol">FETCH_BACKWARD</code>,
+ <code class="symbol">FETCH_ABSOLUTE</code> or
+ <code class="symbol">FETCH_RELATIVE</code>
+ </p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ number of rows to fetch for
+ <code class="symbol">FETCH_FORWARD</code> or
+ <code class="symbol">FETCH_BACKWARD</code>; absolute row number to fetch for
+ <code class="symbol">FETCH_ABSOLUTE</code>; or relative row number to fetch for
+ <code class="symbol">FETCH_RELATIVE</code>
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.26.7"><h2>Return Value</h2><p>
+ <code class="varname">SPI_processed</code> and
+ <code class="varname">SPI_tuptable</code> are set as in
+ <code class="function">SPI_execute</code> if successful.
+ </p></div><div class="refsect1" id="id-1.8.12.8.26.8"><h2>Notes</h2><p>
+ See the SQL <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a> command
+ for details of the interpretation of the
+ <em class="parameter"><code>direction</code></em> and
+ <em class="parameter"><code>count</code></em> parameters.
+ </p><p>
+ Direction values other than <code class="symbol">FETCH_FORWARD</code>
+ may fail if the cursor's plan was not created
+ with the <code class="symbol">CURSOR_OPT_SCROLL</code> option.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-cursor-move.html" title="SPI_cursor_move">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-scroll-cursor-move.html" title="SPI_scroll_cursor_move">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_cursor_move </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_scroll_cursor_move</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-scroll-cursor-move.html b/doc/src/sgml/html/spi-spi-scroll-cursor-move.html
new file mode 100644
index 0000000..26c566e
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-scroll-cursor-move.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_scroll_cursor_move</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-scroll-cursor-fetch.html" title="SPI_scroll_cursor_fetch" /><link rel="next" href="spi-spi-cursor-close.html" title="SPI_cursor_close" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_scroll_cursor_move</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-scroll-cursor-fetch.html" title="SPI_scroll_cursor_fetch">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-cursor-close.html" title="SPI_cursor_close">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-SCROLL-CURSOR-MOVE"><div class="titlepage"></div><a id="id-1.8.12.8.27.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_scroll_cursor_move</span></h2><p>SPI_scroll_cursor_move — move a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_scroll_cursor_move(Portal <em class="parameter"><code>portal</code></em>, FetchDirection <em class="parameter"><code>direction</code></em>,
+ long <em class="parameter"><code>count</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.27.5"><h2>Description</h2><p>
+ <code class="function">SPI_scroll_cursor_move</code> skips over some number of rows
+ in a cursor. This is equivalent to the SQL command
+ <code class="command">MOVE</code>.
+ </p></div><div class="refsect1" id="id-1.8.12.8.27.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">Portal <em class="parameter"><code>portal</code></em></code></span></dt><dd><p>
+ portal containing the cursor
+ </p></dd><dt><span class="term"><code class="literal">FetchDirection <em class="parameter"><code>direction</code></em></code></span></dt><dd><p>
+ one of <code class="symbol">FETCH_FORWARD</code>,
+ <code class="symbol">FETCH_BACKWARD</code>,
+ <code class="symbol">FETCH_ABSOLUTE</code> or
+ <code class="symbol">FETCH_RELATIVE</code>
+ </p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p>
+ number of rows to move for
+ <code class="symbol">FETCH_FORWARD</code> or
+ <code class="symbol">FETCH_BACKWARD</code>; absolute row number to move to for
+ <code class="symbol">FETCH_ABSOLUTE</code>; or relative row number to move to for
+ <code class="symbol">FETCH_RELATIVE</code>
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.27.7"><h2>Return Value</h2><p>
+ <code class="varname">SPI_processed</code> is set as in
+ <code class="function">SPI_execute</code> if successful.
+ <code class="varname">SPI_tuptable</code> is set to <code class="symbol">NULL</code>, since
+ no rows are returned by this function.
+ </p></div><div class="refsect1" id="id-1.8.12.8.27.8"><h2>Notes</h2><p>
+ See the SQL <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a> command
+ for details of the interpretation of the
+ <em class="parameter"><code>direction</code></em> and
+ <em class="parameter"><code>count</code></em> parameters.
+ </p><p>
+ Direction values other than <code class="symbol">FETCH_FORWARD</code>
+ may fail if the cursor's plan was not created
+ with the <code class="symbol">CURSOR_OPT_SCROLL</code> option.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-scroll-cursor-fetch.html" title="SPI_scroll_cursor_fetch">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-cursor-close.html" title="SPI_cursor_close">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_scroll_cursor_fetch </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_cursor_close</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-start-transaction.html b/doc/src/sgml/html/spi-spi-start-transaction.html
new file mode 100644
index 0000000..0cf7838
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-start-transaction.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_start_transaction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-rollback.html" title="SPI_rollback" /><link rel="next" href="spi-visibility.html" title="47.5. Visibility of Data Changes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_start_transaction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-rollback.html" title="SPI_rollback">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-transaction.html" title="47.4. Transaction Management">Up</a></td><th width="60%" align="center">47.4. Transaction Management</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-visibility.html" title="47.5. Visibility of Data Changes">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-START-TRANSACTION"><div class="titlepage"></div><a id="id-1.8.12.11.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_start_transaction</span></h2><p>SPI_start_transaction — obsolete function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+void SPI_start_transaction(void)
+</pre></div><div class="refsect1" id="id-1.8.12.11.6.5"><h2>Description</h2><p>
+ <code class="function">SPI_start_transaction</code> does nothing, and exists
+ only for code compatibility with
+ earlier <span class="productname">PostgreSQL</span> releases. It used to
+ be required after calling <code class="function">SPI_commit</code>
+ or <code class="function">SPI_rollback</code>, but now those functions start
+ a new transaction automatically.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-rollback.html" title="SPI_rollback">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-transaction.html" title="47.4. Transaction Management">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-visibility.html" title="47.5. Visibility of Data Changes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_rollback </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 47.5. Visibility of Data Changes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-spi-unregister-relation.html b/doc/src/sgml/html/spi-spi-unregister-relation.html
new file mode 100644
index 0000000..4c0d701
--- /dev/null
+++ b/doc/src/sgml/html/spi-spi-unregister-relation.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_unregister_relation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-register-relation.html" title="SPI_register_relation" /><link rel="next" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_unregister_relation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-register-relation.html" title="SPI_register_relation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-UNREGISTER-RELATION"><div class="titlepage"></div><a id="id-1.8.12.8.32.1" class="indexterm"></a><a id="id-1.8.12.8.32.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_unregister_relation</span></h2><p>SPI_unregister_relation — remove an ephemeral named relation from the registry</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+int SPI_unregister_relation(const char * <em class="parameter"><code>name</code></em>)
+</pre></div><div class="refsect1" id="id-1.8.12.8.32.6"><h2>Description</h2><p>
+ <code class="function">SPI_unregister_relation</code> removes an ephemeral named
+ relation from the registry for the current connection.
+ </p></div><div class="refsect1" id="id-1.8.12.8.32.7"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>name</code></em></code></span></dt><dd><p>
+ the relation registry entry name
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.32.8"><h2>Return Value</h2><p>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_REL_UNREGISTER</code></span></dt><dd><p>
+ if the tuplestore has been successfully removed from the registry
+ </p></dd></dl></div><p>
+ </p><p>
+ On error, one of the following negative values is returned:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p>
+ if <em class="parameter"><code>name</code></em> is <code class="symbol">NULL</code>
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p>
+ if called from an unconnected C function
+ </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_REL_NOT_FOUND</code></span></dt><dd><p>
+ if <em class="parameter"><code>name</code></em> is not found in the registry for the
+ current connection
+ </p></dd></dl></div><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-register-relation.html" title="SPI_register_relation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_register_relation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_register_trigger_data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-transaction.html b/doc/src/sgml/html/spi-transaction.html
new file mode 100644
index 0000000..f5c7d93
--- /dev/null
+++ b/doc/src/sgml/html/spi-transaction.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>47.4. Transaction Management</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-freeplan.html" title="SPI_freeplan" /><link rel="next" href="spi-spi-commit.html" title="SPI_commit" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">47.4. Transaction Management</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-freeplan.html" title="SPI_freeplan">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><th width="60%" align="center">Chapter 47. Server Programming Interface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-commit.html" title="SPI_commit">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPI-TRANSACTION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">47.4. Transaction Management</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="refentrytitle"><a href="spi-spi-commit.html">SPI_commit</a></span><span class="refpurpose"> — commit the current transaction</span></dt><dt><span class="refentrytitle"><a href="spi-spi-rollback.html">SPI_rollback</a></span><span class="refpurpose"> — abort the current transaction</span></dt><dt><span class="refentrytitle"><a href="spi-spi-start-transaction.html">SPI_start_transaction</a></span><span class="refpurpose"> — obsolete function</span></dt></dl></div><p>
+ It is not possible to run transaction control commands such
+ as <code class="command">COMMIT</code> and <code class="command">ROLLBACK</code> through SPI
+ functions such as <code class="function">SPI_execute</code>. There are, however,
+ separate interface functions that allow transaction control through SPI.
+ </p><p>
+ It is not generally safe and sensible to start and end transactions in
+ arbitrary user-defined SQL-callable functions without taking into account
+ the context in which they are called. For example, a transaction boundary
+ in the middle of a function that is part of a complex SQL expression that
+ is part of some SQL command will probably result in obscure internal errors
+ or crashes. The interface functions presented here are primarily intended
+ to be used by procedural language implementations to support transaction
+ management in SQL-level procedures that are invoked by the <code class="command">CALL</code>
+ command, taking the context of the <code class="command">CALL</code> invocation into
+ account. SPI-using procedures implemented in C can implement the same logic, but
+ the details of that are beyond the scope of this documentation.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-freeplan.html" title="SPI_freeplan">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-commit.html" title="SPI_commit">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_freeplan </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_commit</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi-visibility.html b/doc/src/sgml/html/spi-visibility.html
new file mode 100644
index 0000000..b2076f9
--- /dev/null
+++ b/doc/src/sgml/html/spi-visibility.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>47.5. Visibility of Data Changes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-start-transaction.html" title="SPI_start_transaction" /><link rel="next" href="spi-examples.html" title="47.6. Examples" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">47.5. Visibility of Data Changes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><th width="60%" align="center">Chapter 47. Server Programming Interface</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-examples.html" title="47.6. Examples">Next</a></td></tr></table><hr /></div><div class="sect1" id="SPI-VISIBILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">47.5. Visibility of Data Changes</h2></div></div></div><p>
+ The following rules govern the visibility of data changes in
+ functions that use SPI (or any other C function):
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ During the execution of an SQL command, any data changes made by
+ the command are invisible to the command itself. For
+ example, in:
+</p><pre class="programlisting">
+INSERT INTO a SELECT * FROM a;
+</pre><p>
+ the inserted rows are invisible to the <code class="command">SELECT</code>
+ part.
+ </p></li><li class="listitem"><p>
+ Changes made by a command C are visible to all commands that are
+ started after C, no matter whether they are started inside C
+ (during the execution of C) or after C is done.
+ </p></li><li class="listitem"><p>
+ Commands executed via SPI inside a function called by an SQL command
+ (either an ordinary function or a trigger) follow one or the
+ other of the above rules depending on the read/write flag passed
+ to SPI. Commands executed in read-only mode follow the first
+ rule: they cannot see changes of the calling command. Commands executed
+ in read-write mode follow the second rule: they can see all changes made
+ so far.
+ </p></li><li class="listitem"><p>
+ All standard procedural languages set the SPI read-write mode
+ depending on the volatility attribute of the function. Commands of
+ <code class="literal">STABLE</code> and <code class="literal">IMMUTABLE</code> functions are done in
+ read-only mode, while commands of <code class="literal">VOLATILE</code> functions are
+ done in read-write mode. While authors of C functions are able to
+ violate this convention, it's unlikely to be a good idea to do so.
+ </p></li></ul></div><p>
+ </p><p>
+ The next section contains an example that illustrates the
+ application of these rules.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-start-transaction.html" title="SPI_start_transaction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi.html" title="Chapter 47. Server Programming Interface">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-examples.html" title="47.6. Examples">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_start_transaction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 47.6. Examples</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/spi.html b/doc/src/sgml/html/spi.html
new file mode 100644
index 0000000..2fcfd84
--- /dev/null
+++ b/doc/src/sgml/html/spi.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 47. Server Programming Interface</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="plpython-envar.html" title="46.11. Environment Variables" /><link rel="next" href="spi-interface.html" title="47.1. Interface Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 47. Server Programming Interface</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="plpython-envar.html" title="46.11. Environment Variables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-interface.html" title="47.1. Interface Functions">Next</a></td></tr></table><hr /></div><div class="chapter" id="SPI"><div class="titlepage"><div><div><h2 class="title">Chapter 47. Server Programming Interface</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="spi-interface.html">47.1. Interface Functions</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="spi-spi-connect.html">SPI_connect</a></span><span class="refpurpose"> — connect a C function to the SPI manager</span></dt><dt><span class="refentrytitle"><a href="spi-spi-finish.html">SPI_finish</a></span><span class="refpurpose"> — disconnect a C function from the SPI manager</span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute.html">SPI_execute</a></span><span class="refpurpose"> — execute a command</span></dt><dt><span class="refentrytitle"><a href="spi-spi-exec.html">SPI_exec</a></span><span class="refpurpose"> — execute a read/write command</span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-extended.html">SPI_execute_extended</a></span><span class="refpurpose"> — execute a command with out-of-line parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-with-args.html">SPI_execute_with_args</a></span><span class="refpurpose"> — execute a command with out-of-line parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare.html">SPI_prepare</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare-cursor.html">SPI_prepare_cursor</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare-extended.html">SPI_prepare_extended</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-prepare-params.html">SPI_prepare_params</a></span><span class="refpurpose"> — prepare a statement, without executing it yet</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getargcount.html">SPI_getargcount</a></span><span class="refpurpose"> — return the number of arguments needed by a statement
+ prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-getargtypeid.html">SPI_getargtypeid</a></span><span class="refpurpose"> — return the data type OID for an argument of
+ a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-is-cursor-plan.html">SPI_is_cursor_plan</a></span><span class="refpurpose"> — return <code class="symbol">true</code> if a statement
+ prepared by <code class="function">SPI_prepare</code> can be used with
+ <code class="function">SPI_cursor_open</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-plan.html">SPI_execute_plan</a></span><span class="refpurpose"> — execute a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-plan-extended.html">SPI_execute_plan_extended</a></span><span class="refpurpose"> — execute a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execute-plan-with-paramlist.html">SPI_execute_plan_with_paramlist</a></span><span class="refpurpose"> — execute a statement prepared by <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-execp.html">SPI_execp</a></span><span class="refpurpose"> — execute a statement in read/write mode</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-open.html">SPI_cursor_open</a></span><span class="refpurpose"> — set up a cursor using a statement created with <code class="function">SPI_prepare</code></span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-open-with-args.html">SPI_cursor_open_with_args</a></span><span class="refpurpose"> — set up a cursor using a query and parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-open-with-paramlist.html">SPI_cursor_open_with_paramlist</a></span><span class="refpurpose"> — set up a cursor using parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-parse-open.html">SPI_cursor_parse_open</a></span><span class="refpurpose"> — set up a cursor using a query string and parameters</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-find.html">SPI_cursor_find</a></span><span class="refpurpose"> — find an existing cursor by name</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-fetch.html">SPI_cursor_fetch</a></span><span class="refpurpose"> — fetch some rows from a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-move.html">SPI_cursor_move</a></span><span class="refpurpose"> — move a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-scroll-cursor-fetch.html">SPI_scroll_cursor_fetch</a></span><span class="refpurpose"> — fetch some rows from a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-scroll-cursor-move.html">SPI_scroll_cursor_move</a></span><span class="refpurpose"> — move a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-cursor-close.html">SPI_cursor_close</a></span><span class="refpurpose"> — close a cursor</span></dt><dt><span class="refentrytitle"><a href="spi-spi-keepplan.html">SPI_keepplan</a></span><span class="refpurpose"> — save a prepared statement</span></dt><dt><span class="refentrytitle"><a href="spi-spi-saveplan.html">SPI_saveplan</a></span><span class="refpurpose"> — save a prepared statement</span></dt><dt><span class="refentrytitle"><a href="spi-spi-register-relation.html">SPI_register_relation</a></span><span class="refpurpose"> — make an ephemeral named relation available by name in SPI queries</span></dt><dt><span class="refentrytitle"><a href="spi-spi-unregister-relation.html">SPI_unregister_relation</a></span><span class="refpurpose"> — remove an ephemeral named relation from the registry</span></dt><dt><span class="refentrytitle"><a href="spi-spi-register-trigger-data.html">SPI_register_trigger_data</a></span><span class="refpurpose"> — make ephemeral trigger data available in SPI queries</span></dt></dl></dd><dt><span class="sect1"><a href="spi-interface-support.html">47.2. Interface Support Functions</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="spi-spi-fname.html">SPI_fname</a></span><span class="refpurpose"> — determine the column name for the specified column number</span></dt><dt><span class="refentrytitle"><a href="spi-spi-fnumber.html">SPI_fnumber</a></span><span class="refpurpose"> — determine the column number for the specified column name</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getvalue.html">SPI_getvalue</a></span><span class="refpurpose"> — return the string value of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getbinval.html">SPI_getbinval</a></span><span class="refpurpose"> — return the binary value of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-gettype.html">SPI_gettype</a></span><span class="refpurpose"> — return the data type name of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-gettypeid.html">SPI_gettypeid</a></span><span class="refpurpose"> — return the data type <acronym class="acronym">OID</acronym> of the specified column</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getrelname.html">SPI_getrelname</a></span><span class="refpurpose"> — return the name of the specified relation</span></dt><dt><span class="refentrytitle"><a href="spi-spi-getnspname.html">SPI_getnspname</a></span><span class="refpurpose"> — return the namespace of the specified relation</span></dt><dt><span class="refentrytitle"><a href="spi-spi-result-code-string.html">SPI_result_code_string</a></span><span class="refpurpose"> — return error code as string</span></dt></dl></dd><dt><span class="sect1"><a href="spi-memory.html">47.3. Memory Management</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="spi-spi-palloc.html">SPI_palloc</a></span><span class="refpurpose"> — allocate memory in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-realloc.html">SPI_repalloc</a></span><span class="refpurpose"> — reallocate memory in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-pfree.html">SPI_pfree</a></span><span class="refpurpose"> — free memory in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-copytuple.html">SPI_copytuple</a></span><span class="refpurpose"> — make a copy of a row in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-returntuple.html">SPI_returntuple</a></span><span class="refpurpose"> — prepare to return a tuple as a Datum</span></dt><dt><span class="refentrytitle"><a href="spi-spi-modifytuple.html">SPI_modifytuple</a></span><span class="refpurpose"> — create a row by replacing selected fields of a given row</span></dt><dt><span class="refentrytitle"><a href="spi-spi-freetuple.html">SPI_freetuple</a></span><span class="refpurpose"> — free a row allocated in the upper executor context</span></dt><dt><span class="refentrytitle"><a href="spi-spi-freetupletable.html">SPI_freetuptable</a></span><span class="refpurpose"> — free a row set created by <code class="function">SPI_execute</code> or a similar
+ function</span></dt><dt><span class="refentrytitle"><a href="spi-spi-freeplan.html">SPI_freeplan</a></span><span class="refpurpose"> — free a previously saved prepared statement</span></dt></dl></dd><dt><span class="sect1"><a href="spi-transaction.html">47.4. Transaction Management</a></span></dt><dd><dl><dt><span class="refentrytitle"><a href="spi-spi-commit.html">SPI_commit</a></span><span class="refpurpose"> — commit the current transaction</span></dt><dt><span class="refentrytitle"><a href="spi-spi-rollback.html">SPI_rollback</a></span><span class="refpurpose"> — abort the current transaction</span></dt><dt><span class="refentrytitle"><a href="spi-spi-start-transaction.html">SPI_start_transaction</a></span><span class="refpurpose"> — obsolete function</span></dt></dl></dd><dt><span class="sect1"><a href="spi-visibility.html">47.5. Visibility of Data Changes</a></span></dt><dt><span class="sect1"><a href="spi-examples.html">47.6. Examples</a></span></dt></dl></div><a id="id-1.8.12.2" class="indexterm"></a><p>
+ The <em class="firstterm">Server Programming Interface</em>
+ (<acronym class="acronym">SPI</acronym>) gives writers of user-defined
+ <acronym class="acronym">C</acronym> functions the ability to run
+ <acronym class="acronym">SQL</acronym> commands inside their functions or procedures.
+ <acronym class="acronym">SPI</acronym> is a set of
+ interface functions to simplify access to the parser, planner,
+ and executor. <acronym class="acronym">SPI</acronym> also does some
+ memory management.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The available procedural languages provide various means to
+ execute SQL commands from functions. Most of these facilities are
+ based on SPI, so this documentation might be of use for users
+ of those languages as well.
+ </p></div><p>
+ Note that if a command invoked via SPI fails, then control will not be
+ returned to your C function. Rather, the
+ transaction or subtransaction in which your C function executes will be
+ rolled back. (This might seem surprising given that the SPI functions mostly
+ have documented error-return conventions. Those conventions only apply
+ for errors detected within the SPI functions themselves, however.)
+ It is possible to recover control after an error by establishing your own
+ subtransaction surrounding SPI calls that might fail.
+ </p><p>
+ <acronym class="acronym">SPI</acronym> functions return a nonnegative result on
+ success (either via a returned integer value or in the global
+ variable <code class="varname">SPI_result</code>, as described below). On
+ error, a negative result or <code class="symbol">NULL</code> will be returned.
+ </p><p>
+ Source code files that use SPI must include the header file
+ <code class="filename">executor/spi.h</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="plpython-envar.html" title="46.11. Environment Variables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-interface.html" title="47.1. Interface Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">46.11. Environment Variables </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 47.1. Interface Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-abort.html b/doc/src/sgml/html/sql-abort.html
new file mode 100644
index 0000000..8913a5d
--- /dev/null
+++ b/doc/src/sgml/html/sql-abort.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ABORT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-commands.html" title="SQL Commands" /><link rel="next" href="sql-alteraggregate.html" title="ALTER AGGREGATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ABORT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-commands.html" title="SQL Commands">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alteraggregate.html" title="ALTER AGGREGATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ABORT"><div class="titlepage"></div><a id="id-1.9.3.3.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ABORT</span></h2><p>ABORT — abort the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</pre></div><div class="refsect1" id="id-1.9.3.3.5"><h2>Description</h2><p>
+ <code class="command">ABORT</code> rolls back the current transaction and causes
+ all the updates made by the transaction to be discarded.
+ This command is identical
+ in behavior to the standard <acronym class="acronym">SQL</acronym> command
+ <a class="link" href="sql-rollback.html" title="ROLLBACK"><code class="command">ROLLBACK</code></a>,
+ and is present only for historical reasons.
+ </p></div><div class="refsect1" id="id-1.9.3.3.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">WORK</code><br /></span><span class="term"><code class="literal">TRANSACTION</code></span></dt><dd><p>
+ Optional key words. They have no effect.
+ </p></dd><dt><span class="term"><code class="literal">AND CHAIN</code></span></dt><dd><p>
+ If <code class="literal">AND CHAIN</code> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <a class="link" href="sql-set-transaction.html" title="SET TRANSACTION"><code class="command">SET TRANSACTION</code></a>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.3.7"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a> to
+ successfully terminate a transaction.
+ </p><p>
+ Issuing <code class="command">ABORT</code> outside of a transaction block
+ emits a warning and otherwise has no effect.
+ </p></div><div class="refsect1" id="id-1.9.3.3.8"><h2>Examples</h2><p>
+ To abort all changes:
+</p><pre class="programlisting">
+ABORT;
+</pre></div><div class="refsect1" id="id-1.9.3.3.9"><h2>Compatibility</h2><p>
+ This command is a <span class="productname">PostgreSQL</span> extension
+ present for historical reasons. <code class="command">ROLLBACK</code> is the
+ equivalent standard SQL command.
+ </p></div><div class="refsect1" id="id-1.9.3.3.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-commands.html" title="SQL Commands">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alteraggregate.html" title="ALTER AGGREGATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SQL Commands </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER AGGREGATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alteraggregate.html b/doc/src/sgml/html/sql-alteraggregate.html
new file mode 100644
index 0000000..929f91a
--- /dev/null
+++ b/doc/src/sgml/html/sql-alteraggregate.html
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER AGGREGATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-abort.html" title="ABORT" /><link rel="next" href="sql-altercollation.html" title="ALTER COLLATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER AGGREGATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-abort.html" title="ABORT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altercollation.html" title="ALTER COLLATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERAGGREGATE"><div class="titlepage"></div><a id="id-1.9.3.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER AGGREGATE</span></h2><p>ALTER AGGREGATE — change the definition of an aggregate function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER AGGREGATE <em class="replaceable"><code>name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> ) RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER AGGREGATE <em class="replaceable"><code>name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> )
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER AGGREGATE <em class="replaceable"><code>name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> ) SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>aggregate_signature</code></em> is:</span>
+
+* |
+[ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] |
+[ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] ] ORDER BY [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.4.5"><h2>Description</h2><p>
+ <code class="command">ALTER AGGREGATE</code> changes the definition of an
+ aggregate function.
+ </p><p>
+ You must own the aggregate function to use <code class="command">ALTER AGGREGATE</code>.
+ To change the schema of an aggregate function, you must also have
+ <code class="literal">CREATE</code> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the aggregate function's schema. (These restrictions enforce that altering
+ the owner doesn't do anything you couldn't do by dropping and recreating
+ the aggregate function. However, a superuser can alter ownership of any
+ aggregate function anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.4.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing aggregate function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code> or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ Note that <code class="command">ALTER AGGREGATE</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the aggregate function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ An input data type on which the aggregate function operates.
+ To reference a zero-argument aggregate function, write <code class="literal">*</code>
+ in place of the list of argument specifications.
+ To reference an ordered-set aggregate function, write
+ <code class="literal">ORDER BY</code> between the direct and aggregated argument
+ specifications.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the aggregate function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the aggregate function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the aggregate function.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.4.7"><h2>Notes</h2><p>
+ The recommended syntax for referencing an ordered-set aggregate
+ is to write <code class="literal">ORDER BY</code> between the direct and aggregated
+ argument specifications, in the same style as in
+ <a class="link" href="sql-createaggregate.html" title="CREATE AGGREGATE"><code class="command">CREATE AGGREGATE</code></a>. However, it will also work to
+ omit <code class="literal">ORDER BY</code> and just run the direct and aggregated
+ argument specifications into a single list. In this abbreviated form,
+ if <code class="literal">VARIADIC "any"</code> was used in both the direct and
+ aggregated argument lists, write <code class="literal">VARIADIC "any"</code> only once.
+ </p></div><div class="refsect1" id="id-1.9.3.4.8"><h2>Examples</h2><p>
+ To rename the aggregate function <code class="literal">myavg</code> for type
+ <code class="type">integer</code> to <code class="literal">my_average</code>:
+</p><pre class="programlisting">
+ALTER AGGREGATE myavg(integer) RENAME TO my_average;
+</pre><p>
+ </p><p>
+ To change the owner of the aggregate function <code class="literal">myavg</code> for type
+ <code class="type">integer</code> to <code class="literal">joe</code>:
+</p><pre class="programlisting">
+ALTER AGGREGATE myavg(integer) OWNER TO joe;
+</pre><p>
+ </p><p>
+ To move the ordered-set aggregate <code class="literal">mypercentile</code> with
+ direct argument of type <code class="type">float8</code> and aggregated argument
+ of type <code class="type">integer</code> into schema <code class="literal">myschema</code>:
+</p><pre class="programlisting">
+ALTER AGGREGATE mypercentile(float8 ORDER BY integer) SET SCHEMA myschema;
+</pre><p>
+ This will work too:
+</p><pre class="programlisting">
+ALTER AGGREGATE mypercentile(float8, integer) SET SCHEMA myschema;
+</pre></div><div class="refsect1" id="id-1.9.3.4.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER AGGREGATE</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.4.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a>, <a class="xref" href="sql-dropaggregate.html" title="DROP AGGREGATE"><span class="refentrytitle">DROP AGGREGATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-abort.html" title="ABORT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altercollation.html" title="ALTER COLLATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ABORT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER COLLATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altercollation.html b/doc/src/sgml/html/sql-altercollation.html
new file mode 100644
index 0000000..a8b8625
--- /dev/null
+++ b/doc/src/sgml/html/sql-altercollation.html
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER COLLATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alteraggregate.html" title="ALTER AGGREGATE" /><link rel="next" href="sql-alterconversion.html" title="ALTER CONVERSION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER COLLATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alteraggregate.html" title="ALTER AGGREGATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterconversion.html" title="ALTER CONVERSION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERCOLLATION"><div class="titlepage"></div><a id="id-1.9.3.5.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER COLLATION</span></h2><p>ALTER COLLATION — change the definition of a collation</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER COLLATION <em class="replaceable"><code>name</code></em> REFRESH VERSION
+
+ALTER COLLATION <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER COLLATION <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER COLLATION <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.5.5"><h2>Description</h2><p>
+ <code class="command">ALTER COLLATION</code> changes the definition of a
+ collation.
+ </p><p>
+ You must own the collation to use <code class="command">ALTER COLLATION</code>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the collation's schema. (These restrictions enforce that altering the
+ owner doesn't do anything you couldn't do by dropping and recreating the
+ collation. However, a superuser can alter ownership of any collation
+ anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.5.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing collation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the collation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the collation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the collation.
+ </p></dd><dt><span class="term"><code class="literal">REFRESH VERSION</code></span></dt><dd><p>
+ Update the collation's version.
+ See <a class="xref" href="sql-altercollation.html#SQL-ALTERCOLLATION-NOTES" title="Notes">Notes</a> below.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-ALTERCOLLATION-NOTES"><h2>Notes</h2><p>
+ When a collation object is created, the provider-specific version of the
+ collation is recorded in the system catalog. When the collation is used,
+ the current version is
+ checked against the recorded version, and a warning is issued when there is
+ a mismatch, for example:
+</p><pre class="screen">
+WARNING: collation "xx-x-icu" has version mismatch
+DETAIL: The collation in the database was created using version 1.2.3.4, but the operating system provides version 2.3.4.5.
+HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg_catalog."xx-x-icu" REFRESH VERSION, or build PostgreSQL with the right library version.
+</pre><p>
+ A change in collation definitions can lead to corrupt indexes and other
+ problems because the database system relies on stored objects having a
+ certain sort order. Generally, this should be avoided, but it can happen
+ in legitimate circumstances, such as when upgrading the operating system
+ to a new major version or when
+ using <code class="command">pg_upgrade</code> to upgrade to server binaries linked
+ with a newer version of ICU. When this happens, all objects depending on
+ the collation should be rebuilt, for example,
+ using <code class="command">REINDEX</code>. When that is done, the collation version
+ can be refreshed using the command <code class="literal">ALTER COLLATION ... REFRESH
+ VERSION</code>. This will update the system catalog to record the
+ current collation version and will make the warning go away. Note that this
+ does not actually check whether all affected objects have been rebuilt
+ correctly.
+ </p><p>
+ When using collations provided by <code class="literal">libc</code>, version
+ information is recorded on systems using the GNU C library (most Linux
+ systems), FreeBSD and Windows. When using collations provided by ICU, the
+ version information is provided by the ICU library and is available on all
+ platforms.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When using the GNU C library for collations, the C library's version
+ is used as a proxy for the collation version. Many Linux distributions
+ change collation definitions only when upgrading the C library, but this
+ approach is imperfect as maintainers are free to back-port newer
+ collation definitions to older C library releases.
+ </p><p>
+ When using Windows for collations, version information is only available
+ for collations defined with BCP 47 language tags such as
+ <code class="literal">en-US</code>.
+ </p></div><p>
+ For the database default collation, there is an analogous command
+ <code class="literal">ALTER DATABASE ... REFRESH COLLATION VERSION</code>.
+ </p><p>
+ The following query can be used to identify all collations in the current
+ database that need to be refreshed and the objects that depend on them:
+</p><pre class="programlisting">
+SELECT pg_describe_object(refclassid, refobjid, refobjsubid) AS "Collation",
+ pg_describe_object(classid, objid, objsubid) AS "Object"
+ FROM pg_depend d JOIN pg_collation c
+ ON refclassid = 'pg_collation'::regclass AND refobjid = c.oid
+ WHERE c.collversion &lt;&gt; pg_collation_actual_version(c.oid)
+ ORDER BY 1, 2;
+</pre></div><div class="refsect1" id="id-1.9.3.5.8"><h2>Examples</h2><p>
+ To rename the collation <code class="literal">de_DE</code> to
+ <code class="literal">german</code>:
+</p><pre class="programlisting">
+ALTER COLLATION "de_DE" RENAME TO german;
+</pre><p>
+ </p><p>
+ To change the owner of the collation <code class="literal">en_US</code> to
+ <code class="literal">joe</code>:
+</p><pre class="programlisting">
+ALTER COLLATION "en_US" OWNER TO joe;
+</pre></div><div class="refsect1" id="id-1.9.3.5.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER COLLATION</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.5.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createcollation.html" title="CREATE COLLATION"><span class="refentrytitle">CREATE COLLATION</span></a>, <a class="xref" href="sql-dropcollation.html" title="DROP COLLATION"><span class="refentrytitle">DROP COLLATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alteraggregate.html" title="ALTER AGGREGATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterconversion.html" title="ALTER CONVERSION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER AGGREGATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER CONVERSION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterconversion.html b/doc/src/sgml/html/sql-alterconversion.html
new file mode 100644
index 0000000..e405074
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterconversion.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER CONVERSION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altercollation.html" title="ALTER COLLATION" /><link rel="next" href="sql-alterdatabase.html" title="ALTER DATABASE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER CONVERSION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altercollation.html" title="ALTER COLLATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterdatabase.html" title="ALTER DATABASE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERCONVERSION"><div class="titlepage"></div><a id="id-1.9.3.6.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER CONVERSION</span></h2><p>ALTER CONVERSION — change the definition of a conversion</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER CONVERSION <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER CONVERSION <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER CONVERSION <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.6.5"><h2>Description</h2><p>
+ <code class="command">ALTER CONVERSION</code> changes the definition of a
+ conversion.
+ </p><p>
+ You must own the conversion to use <code class="command">ALTER CONVERSION</code>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the conversion's schema. (These restrictions enforce that altering the
+ owner doesn't do anything you couldn't do by dropping and recreating the
+ conversion. However, a superuser can alter ownership of any conversion
+ anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.6.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing conversion.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the conversion.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the conversion.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the conversion.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.6.7"><h2>Examples</h2><p>
+ To rename the conversion <code class="literal">iso_8859_1_to_utf8</code> to
+ <code class="literal">latin1_to_unicode</code>:
+</p><pre class="programlisting">
+ALTER CONVERSION iso_8859_1_to_utf8 RENAME TO latin1_to_unicode;
+</pre><p>
+ </p><p>
+ To change the owner of the conversion <code class="literal">iso_8859_1_to_utf8</code> to
+ <code class="literal">joe</code>:
+</p><pre class="programlisting">
+ALTER CONVERSION iso_8859_1_to_utf8 OWNER TO joe;
+</pre></div><div class="refsect1" id="id-1.9.3.6.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER CONVERSION</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.6.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createconversion.html" title="CREATE CONVERSION"><span class="refentrytitle">CREATE CONVERSION</span></a>, <a class="xref" href="sql-dropconversion.html" title="DROP CONVERSION"><span class="refentrytitle">DROP CONVERSION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altercollation.html" title="ALTER COLLATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterdatabase.html" title="ALTER DATABASE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER COLLATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER DATABASE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterdatabase.html b/doc/src/sgml/html/sql-alterdatabase.html
new file mode 100644
index 0000000..0e9096d
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterdatabase.html
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER DATABASE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterconversion.html" title="ALTER CONVERSION" /><link rel="next" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER DATABASE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterconversion.html" title="ALTER CONVERSION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERDATABASE"><div class="titlepage"></div><a id="id-1.9.3.7.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER DATABASE</span></h2><p>ALTER DATABASE — change a database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER DATABASE <em class="replaceable"><code>name</code></em> [ [ WITH ] <em class="replaceable"><code>option</code></em> [ ... ] ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ ALLOW_CONNECTIONS <em class="replaceable"><code>allowconn</code></em>
+ CONNECTION LIMIT <em class="replaceable"><code>connlimit</code></em>
+ IS_TEMPLATE <em class="replaceable"><code>istemplate</code></em>
+
+ALTER DATABASE <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+ALTER DATABASE <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER DATABASE <em class="replaceable"><code>name</code></em> SET TABLESPACE <em class="replaceable"><code>new_tablespace</code></em>
+
+ALTER DATABASE <em class="replaceable"><code>name</code></em> REFRESH COLLATION VERSION
+
+ALTER DATABASE <em class="replaceable"><code>name</code></em> SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | DEFAULT }
+ALTER DATABASE <em class="replaceable"><code>name</code></em> SET <em class="replaceable"><code>configuration_parameter</code></em> FROM CURRENT
+ALTER DATABASE <em class="replaceable"><code>name</code></em> RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ALTER DATABASE <em class="replaceable"><code>name</code></em> RESET ALL
+</pre></div><div class="refsect1" id="id-1.9.3.7.5"><h2>Description</h2><p>
+ <code class="command">ALTER DATABASE</code> changes the attributes
+ of a database.
+ </p><p>
+ The first form changes certain per-database settings. (See below for
+ details.) Only the database owner or a superuser can change these settings.
+ </p><p>
+ The second form changes the name of the database. Only the database
+ owner or a superuser can rename a database; non-superuser owners must
+ also have the
+ <code class="literal">CREATEDB</code> privilege. The current database cannot
+ be renamed. (Connect to a different database if you need to do
+ that.)
+ </p><p>
+ The third form changes the owner of the database.
+ To alter the owner, you must own the database and also be a direct or
+ indirect member of the new owning role, and you must have the
+ <code class="literal">CREATEDB</code> privilege.
+ (Note that superusers have all these privileges automatically.)
+ </p><p>
+ The fourth form changes the default tablespace of the database.
+ Only the database owner or a superuser can do this; you must also have
+ create privilege for the new tablespace.
+ This command physically moves any tables or indexes in the database's old
+ default tablespace to the new tablespace. The new default tablespace
+ must be empty for this database, and no one can be connected to
+ the database. Tables and indexes in non-default tablespaces are
+ unaffected.
+ </p><p>
+ The remaining forms change the session default for a run-time
+ configuration variable for a <span class="productname">PostgreSQL</span>
+ database. Whenever a new session is subsequently started in that
+ database, the specified value becomes the session default value.
+ The database-specific default overrides whatever setting is present
+ in <code class="filename">postgresql.conf</code> or has been received from the
+ <code class="command">postgres</code> command line. Only the database
+ owner or a superuser can change the session defaults for a
+ database. Certain variables cannot be set this way, or can only be
+ set by a superuser.
+ </p></div><div class="refsect1" id="id-1.9.3.7.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the database whose attributes are to be altered.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>allowconn</code></em></span></dt><dd><p>
+ If false then no one can connect to this database.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>connlimit</code></em></span></dt><dd><p>
+ How many concurrent connections can be made
+ to this database. -1 means no limit.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>istemplate</code></em></span></dt><dd><p>
+ If true, then this database can be cloned by any user with <code class="literal">CREATEDB</code>
+ privileges; if false, then only superusers or the owner of the
+ database can clone it.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the database.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the database.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_tablespace</code></em></span></dt><dd><p>
+ The new default tablespace of the database.
+ </p><p>
+ This form of the command cannot be executed inside a transaction block.
+ </p></dd><dt><span class="term"><code class="literal">REFRESH COLLATION VERSION</code></span></dt><dd><p>
+ Update the database collation version. See <a class="xref" href="sql-altercollation.html#SQL-ALTERCOLLATION-NOTES" title="Notes">Notes</a> for background.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em><br /></span><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ Set this database's session default for the specified configuration
+ parameter to the given value. If
+ <em class="replaceable"><code>value</code></em> is <code class="literal">DEFAULT</code>
+ or, equivalently, <code class="literal">RESET</code> is used, the
+ database-specific setting is removed, so the system-wide default
+ setting will be inherited in new sessions. Use <code class="literal">RESET
+ ALL</code> to clear all database-specific settings.
+ <code class="literal">SET FROM CURRENT</code> saves the session's current value of
+ the parameter as the database-specific value.
+ </p><p>
+ See <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> and <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ for more information about allowed parameter names
+ and values.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.7.7"><h2>Notes</h2><p>
+ It is also possible to tie a session default to a specific role
+ rather than to a database; see
+ <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>.
+ Role-specific settings override database-specific
+ ones if there is a conflict.
+ </p></div><div class="refsect1" id="id-1.9.3.7.8"><h2>Examples</h2><p>
+ To disable index scans by default in the database
+ <code class="literal">test</code>:
+
+</p><pre class="programlisting">
+ALTER DATABASE test SET enable_indexscan TO off;
+</pre></div><div class="refsect1" id="id-1.9.3.7.9"><h2>Compatibility</h2><p>
+ The <code class="command">ALTER DATABASE</code> statement is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.7.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a>, <a class="xref" href="sql-dropdatabase.html" title="DROP DATABASE"><span class="refentrytitle">DROP DATABASE</span></a>, <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a>, <a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterconversion.html" title="ALTER CONVERSION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER CONVERSION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER DEFAULT PRIVILEGES</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterdefaultprivileges.html b/doc/src/sgml/html/sql-alterdefaultprivileges.html
new file mode 100644
index 0000000..edfbd60
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterdefaultprivileges.html
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER DEFAULT PRIVILEGES</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterdatabase.html" title="ALTER DATABASE" /><link rel="next" href="sql-alterdomain.html" title="ALTER DOMAIN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER DEFAULT PRIVILEGES</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterdatabase.html" title="ALTER DATABASE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterdomain.html" title="ALTER DOMAIN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERDEFAULTPRIVILEGES"><div class="titlepage"></div><a id="id-1.9.3.8.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER DEFAULT PRIVILEGES</span></h2><p>ALTER DEFAULT PRIVILEGES — define default access privileges</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER DEFAULT PRIVILEGES
+ [ FOR { ROLE | USER } <em class="replaceable"><code>target_role</code></em> [, ...] ]
+ [ IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] ]
+ <em class="replaceable"><code>abbreviated_grant_or_revoke</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>abbreviated_grant_or_revoke</code></em> is one of:</span>
+
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON TABLES
+ TO { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON SEQUENCES
+ TO { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { FUNCTIONS | ROUTINES }
+ TO { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPES
+ TO { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { USAGE | CREATE | ALL [ PRIVILEGES ] }
+ ON SCHEMAS
+ TO { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON TABLES
+ FROM { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON SEQUENCES
+ FROM { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { FUNCTIONS | ROUTINES }
+ FROM { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPES
+ FROM { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | CREATE | ALL [ PRIVILEGES ] }
+ ON SCHEMAS
+ FROM { [ GROUP ] <em class="replaceable"><code>role_name</code></em> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="SQL-ALTERDEFAULTPRIVILEGES-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">ALTER DEFAULT PRIVILEGES</code> allows you to set the privileges
+ that will be applied to objects created in the future. (It does not
+ affect privileges assigned to already-existing objects.) Currently,
+ only the privileges for schemas, tables (including views and foreign
+ tables), sequences, functions, and types (including domains) can be
+ altered. For this command, functions include aggregates and procedures.
+ The words <code class="literal">FUNCTIONS</code> and <code class="literal">ROUTINES</code> are
+ equivalent in this command. (<code class="literal">ROUTINES</code> is preferred
+ going forward as the standard term for functions and procedures taken
+ together. In earlier PostgreSQL releases, only the
+ word <code class="literal">FUNCTIONS</code> was allowed. It is not possible to set
+ default privileges for functions and procedures separately.)
+ </p><p>
+ You can change default privileges only for objects that will be created by
+ yourself or by roles that you are a member of. The privileges can be set
+ globally (i.e., for all objects created in the current database),
+ or just for objects created in specified schemas.
+ </p><p>
+ As explained in <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>,
+ the default privileges for any object type normally grant all grantable
+ permissions to the object owner, and may grant some privileges to
+ <code class="literal">PUBLIC</code> as well. However, this behavior can be changed by
+ altering the global default privileges with
+ <code class="command">ALTER DEFAULT PRIVILEGES</code>.
+ </p><p>
+ Default privileges that are specified per-schema are added to whatever
+ the global default privileges are for the particular object type.
+ This means you cannot revoke privileges per-schema if they are granted
+ globally (either by default, or according to a previous <code class="command">ALTER
+ DEFAULT PRIVILEGES</code> command that did not specify a schema).
+ Per-schema <code class="literal">REVOKE</code> is only useful to reverse the
+ effects of a previous per-schema <code class="literal">GRANT</code>.
+ </p><div class="refsect2" id="id-1.9.3.8.5.6"><h3>Parameters</h3><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>target_role</code></em></span></dt><dd><p>
+ The name of an existing role of which the current role is a member.
+ If <code class="literal">FOR ROLE</code> is omitted, the current role is assumed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>schema_name</code></em></span></dt><dd><p>
+ The name of an existing schema. If specified, the default privileges
+ are altered for objects later created in that schema.
+ If <code class="literal">IN SCHEMA</code> is omitted, the global default privileges
+ are altered.
+ <code class="literal">IN SCHEMA</code> is not allowed when setting privileges
+ for schemas, since schemas can't be nested.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The name of an existing role to grant or revoke privileges for.
+ This parameter, and all the other parameters in
+ <em class="replaceable"><code>abbreviated_grant_or_revoke</code></em>,
+ act as described under
+ <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a> or
+ <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a>,
+ except that one is setting permissions for a whole class of objects
+ rather than specific named objects.
+ </p></dd></dl></div></div></div><div class="refsect1" id="SQL-ALTERDEFAULTPRIVILEGES-NOTES"><h2>Notes</h2><p>
+ Use <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>'s <code class="command">\ddp</code> command
+ to obtain information about existing assignments of default privileges.
+ The meaning of the privilege display is the same as explained for
+ <code class="command">\dp</code> in <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>.
+ </p><p>
+ If you wish to drop a role for which the default privileges have been
+ altered, it is necessary to reverse the changes in its default privileges
+ or use <code class="command">DROP OWNED BY</code> to get rid of the default privileges entry
+ for the role.
+ </p></div><div class="refsect1" id="SQL-ALTERDEFAULTPRIVILEGES-EXAMPLES"><h2>Examples</h2><p>
+ Grant SELECT privilege to everyone for all tables (and views) you
+ subsequently create in schema <code class="literal">myschema</code>, and allow
+ role <code class="literal">webuser</code> to INSERT into them too:
+
+</p><pre class="programlisting">
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO PUBLIC;
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT INSERT ON TABLES TO webuser;
+</pre><p>
+ </p><p>
+ Undo the above, so that subsequently-created tables won't have any
+ more permissions than normal:
+
+</p><pre class="programlisting">
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE SELECT ON TABLES FROM PUBLIC;
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE INSERT ON TABLES FROM webuser;
+</pre><p>
+ </p><p>
+ Remove the public EXECUTE permission that is normally granted on functions,
+ for all functions subsequently created by role <code class="literal">admin</code>:
+</p><pre class="programlisting">
+ALTER DEFAULT PRIVILEGES FOR ROLE admin REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
+</pre><p>
+ Note however that you <span class="emphasis"><em>cannot</em></span> accomplish that effect
+ with a command limited to a single schema. This command has no effect,
+ unless it is undoing a matching <code class="literal">GRANT</code>:
+</p><pre class="programlisting">
+ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
+</pre><p>
+ That's because per-schema default privileges can only add privileges to
+ the global setting, not remove privileges granted by it.
+ </p></div><div class="refsect1" id="id-1.9.3.8.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER DEFAULT PRIVILEGES</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.8.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>, <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterdatabase.html" title="ALTER DATABASE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterdomain.html" title="ALTER DOMAIN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER DATABASE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER DOMAIN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterdomain.html b/doc/src/sgml/html/sql-alterdomain.html
new file mode 100644
index 0000000..3362b46
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterdomain.html
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER DOMAIN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES" /><link rel="next" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER DOMAIN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERDOMAIN"><div class="titlepage"></div><a id="id-1.9.3.9.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER DOMAIN</span></h2><p>ALTER DOMAIN —
+ change the definition of a domain
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ { SET DEFAULT <em class="replaceable"><code>expression</code></em> | DROP DEFAULT }
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ { SET | DROP } NOT NULL
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ ADD <em class="replaceable"><code>domain_constraint</code></em> [ NOT VALID ]
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ DROP CONSTRAINT [ IF EXISTS ] <em class="replaceable"><code>constraint_name</code></em> [ RESTRICT | CASCADE ]
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ RENAME CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> TO <em class="replaceable"><code>new_constraint_name</code></em>
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ VALIDATE CONSTRAINT <em class="replaceable"><code>constraint_name</code></em>
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER DOMAIN <em class="replaceable"><code>name</code></em>
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.9.5"><h2>Description</h2><p>
+ <code class="command">ALTER DOMAIN</code> changes the definition of an existing domain.
+ There are several sub-forms:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP DEFAULT</code></span></dt><dd><p>
+ These forms set or remove the default value for a domain. Note
+ that defaults only apply to subsequent <code class="command">INSERT</code>
+ commands; they do not affect rows already in a table using the domain.
+ </p></dd><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP NOT NULL</code></span></dt><dd><p>
+ These forms change whether a domain is marked to allow NULL
+ values or to reject NULL values. You can only <code class="literal">SET NOT NULL</code>
+ when the columns using the domain contain no null values.
+ </p></dd><dt><span class="term"><code class="literal">ADD <em class="replaceable"><code>domain_constraint</code></em> [ NOT VALID ]</code></span></dt><dd><p>
+ This form adds a new constraint to a domain using the same syntax as
+ <a class="link" href="sql-createdomain.html" title="CREATE DOMAIN"><code class="command">CREATE DOMAIN</code></a>.
+ When a new constraint is added to a domain, all columns using that
+ domain will be checked against the newly added constraint. These
+ checks can be suppressed by adding the new constraint using the
+ <code class="literal">NOT VALID</code> option; the constraint can later be made
+ valid using <code class="command">ALTER DOMAIN ... VALIDATE CONSTRAINT</code>.
+ Newly inserted or updated rows are always checked against all
+ constraints, even those marked <code class="literal">NOT VALID</code>.
+ <code class="literal">NOT VALID</code> is only accepted for <code class="literal">CHECK</code> constraints.
+ </p></dd><dt><span class="term"><code class="literal">DROP CONSTRAINT [ IF EXISTS ]</code></span></dt><dd><p>
+ This form drops constraints on a domain.
+ If <code class="literal">IF EXISTS</code> is specified and the constraint
+ does not exist, no error is thrown. In this case a notice is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">RENAME CONSTRAINT</code></span></dt><dd><p>
+ This form changes the name of a constraint on a domain.
+ </p></dd><dt><span class="term"><code class="literal">VALIDATE CONSTRAINT</code></span></dt><dd><p>
+ This form validates a constraint previously added as
+ <code class="literal">NOT VALID</code>, that is, it verifies that all values in
+ table columns of the domain type satisfy the specified constraint.
+ </p></dd><dt><span class="term"><code class="literal">OWNER</code></span></dt><dd><p>
+ This form changes the owner of the domain to the specified user.
+ </p></dd><dt><span class="term"><code class="literal">RENAME</code></span></dt><dd><p>
+ This form changes the name of the domain.
+ </p></dd><dt><span class="term"><code class="literal">SET SCHEMA</code></span></dt><dd><p>
+ This form changes the schema of the domain. Any constraints
+ associated with the domain are moved into the new schema as well.
+ </p></dd></dl></div><p>
+ You must own the domain to use <code class="command">ALTER DOMAIN</code>.
+ To change the schema of a domain, you must also have
+ <code class="literal">CREATE</code> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the domain's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the domain.
+ However, a superuser can alter ownership of any domain anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.9.6"><h2>Parameters</h2><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of an existing domain to
+ alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>domain_constraint</code></em></span></dt><dd><p>
+ New domain constraint for the domain.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>constraint_name</code></em></span></dt><dd><p>
+ Name of an existing constraint to drop or rename.
+ </p></dd><dt><span class="term"><code class="literal">NOT VALID</code></span></dt><dd><p>
+ Do not verify existing stored data for constraint validity.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the constraint,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the constraint if there are any dependent
+ objects. This is the default behavior.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the domain.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_constraint_name</code></em></span></dt><dd><p>
+ The new name for the constraint.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the domain.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the domain.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.9.7"><h2>Notes</h2><p>
+ Although <code class="command">ALTER DOMAIN ADD CONSTRAINT</code> attempts to verify
+ that existing stored data satisfies the new constraint, this check is not
+ bulletproof, because the command cannot <span class="quote">“<span class="quote">see</span>”</span> table rows that
+ are newly inserted or updated and not yet committed. If there is a hazard
+ that concurrent operations might insert bad data, the way to proceed is to
+ add the constraint using the <code class="literal">NOT VALID</code> option, commit
+ that command, wait until all transactions started before that commit have
+ finished, and then issue <code class="command">ALTER DOMAIN VALIDATE
+ CONSTRAINT</code> to search for data violating the constraint. This
+ method is reliable because once the constraint is committed, all new
+ transactions are guaranteed to enforce it against new values of the domain
+ type.
+ </p><p>
+ Currently, <code class="command">ALTER DOMAIN ADD CONSTRAINT</code>, <code class="command">ALTER
+ DOMAIN VALIDATE CONSTRAINT</code>, and <code class="command">ALTER DOMAIN SET NOT
+ NULL</code> will fail if the named domain or any derived domain is used
+ within a container-type column (a composite, array, or range column) in
+ any table in the database. They should eventually be improved to be able
+ to verify the new constraint for such nested values.
+ </p></div><div class="refsect1" id="id-1.9.3.9.8"><h2>Examples</h2><p>
+ To add a <code class="literal">NOT NULL</code> constraint to a domain:
+</p><pre class="programlisting">
+ALTER DOMAIN zipcode SET NOT NULL;
+</pre><p>
+ To remove a <code class="literal">NOT NULL</code> constraint from a domain:
+</p><pre class="programlisting">
+ALTER DOMAIN zipcode DROP NOT NULL;
+</pre><p>
+ </p><p>
+ To add a check constraint to a domain:
+</p><pre class="programlisting">
+ALTER DOMAIN zipcode ADD CONSTRAINT zipchk CHECK (char_length(VALUE) = 5);
+</pre><p>
+ </p><p>
+ To remove a check constraint from a domain:
+</p><pre class="programlisting">
+ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
+</pre><p>
+ </p><p>
+ To rename a check constraint on a domain:
+</p><pre class="programlisting">
+ALTER DOMAIN zipcode RENAME CONSTRAINT zipchk TO zip_check;
+</pre><p>
+ </p><p>
+ To move the domain into a different schema:
+</p><pre class="programlisting">
+ALTER DOMAIN zipcode SET SCHEMA customers;
+</pre></div><div class="refsect1" id="SQL-ALTERDOMAIN-COMPATIBILITY"><h2>Compatibility</h2><p>
+ <code class="command">ALTER DOMAIN</code> conforms to the <acronym class="acronym">SQL</acronym>
+ standard, except for the <code class="literal">OWNER</code>, <code class="literal">RENAME</code>, <code class="literal">SET SCHEMA</code>, and
+ <code class="literal">VALIDATE CONSTRAINT</code> variants, which are
+ <span class="productname">PostgreSQL</span> extensions. The <code class="literal">NOT VALID</code>
+ clause of the <code class="literal">ADD CONSTRAINT</code> variant is also a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="SQL-ALTERDOMAIN-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createdomain.html" title="CREATE DOMAIN"><span class="refentrytitle">CREATE DOMAIN</span></a>, <a class="xref" href="sql-dropdomain.html" title="DROP DOMAIN"><span class="refentrytitle">DROP DOMAIN</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER DEFAULT PRIVILEGES </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER EVENT TRIGGER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altereventtrigger.html b/doc/src/sgml/html/sql-altereventtrigger.html
new file mode 100644
index 0000000..0a86ba1
--- /dev/null
+++ b/doc/src/sgml/html/sql-altereventtrigger.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER EVENT TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterdomain.html" title="ALTER DOMAIN" /><link rel="next" href="sql-alterextension.html" title="ALTER EXTENSION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER EVENT TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterdomain.html" title="ALTER DOMAIN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterextension.html" title="ALTER EXTENSION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTEREVENTTRIGGER"><div class="titlepage"></div><a id="id-1.9.3.10.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER EVENT TRIGGER</span></h2><p>ALTER EVENT TRIGGER — change the definition of an event trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER EVENT TRIGGER <em class="replaceable"><code>name</code></em> DISABLE
+ALTER EVENT TRIGGER <em class="replaceable"><code>name</code></em> ENABLE [ REPLICA | ALWAYS ]
+ALTER EVENT TRIGGER <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER EVENT TRIGGER <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.10.5"><h2>Description</h2><p>
+ <code class="command">ALTER EVENT TRIGGER</code> changes properties of an
+ existing event trigger.
+ </p><p>
+ You must be superuser to alter an event trigger.
+ </p></div><div class="refsect1" id="id-1.9.3.10.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing trigger to alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the event trigger.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the event trigger.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE</code>/<code class="literal">ENABLE [ REPLICA | ALWAYS ] TRIGGER</code></span></dt><dd><p>
+ These forms configure the firing of event triggers. A disabled trigger
+ is still known to the system, but is not executed when its triggering
+ event occurs. See also <a class="xref" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE">session_replication_role</a>.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-ALTERVENTTRIGGER-COMPATIBILITY"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER EVENT TRIGGER</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.10.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER"><span class="refentrytitle">CREATE EVENT TRIGGER</span></a>, <a class="xref" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER"><span class="refentrytitle">DROP EVENT TRIGGER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterdomain.html" title="ALTER DOMAIN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterextension.html" title="ALTER EXTENSION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER DOMAIN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER EXTENSION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterextension.html b/doc/src/sgml/html/sql-alterextension.html
new file mode 100644
index 0000000..5c691c3
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterextension.html
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER EXTENSION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER" /><link rel="next" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER EXTENSION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTEREXTENSION"><div class="titlepage"></div><a id="id-1.9.3.11.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER EXTENSION</span></h2><p>ALTER EXTENSION —
+ change the definition of an extension
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER EXTENSION <em class="replaceable"><code>name</code></em> UPDATE [ TO <em class="replaceable"><code>new_version</code></em> ]
+ALTER EXTENSION <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER EXTENSION <em class="replaceable"><code>name</code></em> ADD <em class="replaceable"><code>member_object</code></em>
+ALTER EXTENSION <em class="replaceable"><code>name</code></em> DROP <em class="replaceable"><code>member_object</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>member_object</code></em> is:</span>
+
+ ACCESS METHOD <em class="replaceable"><code>object_name</code></em> |
+ AGGREGATE <em class="replaceable"><code>aggregate_name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> ) |
+ CAST (<em class="replaceable"><code>source_type</code></em> AS <em class="replaceable"><code>target_type</code></em>) |
+ COLLATION <em class="replaceable"><code>object_name</code></em> |
+ CONVERSION <em class="replaceable"><code>object_name</code></em> |
+ DOMAIN <em class="replaceable"><code>object_name</code></em> |
+ EVENT TRIGGER <em class="replaceable"><code>object_name</code></em> |
+ FOREIGN DATA WRAPPER <em class="replaceable"><code>object_name</code></em> |
+ FOREIGN TABLE <em class="replaceable"><code>object_name</code></em> |
+ FUNCTION <em class="replaceable"><code>function_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ MATERIALIZED VIEW <em class="replaceable"><code>object_name</code></em> |
+ OPERATOR <em class="replaceable"><code>operator_name</code></em> (<em class="replaceable"><code>left_type</code></em>, <em class="replaceable"><code>right_type</code></em>) |
+ OPERATOR CLASS <em class="replaceable"><code>object_name</code></em> USING <em class="replaceable"><code>index_method</code></em> |
+ OPERATOR FAMILY <em class="replaceable"><code>object_name</code></em> USING <em class="replaceable"><code>index_method</code></em> |
+ [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>object_name</code></em> |
+ PROCEDURE <em class="replaceable"><code>procedure_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ ROUTINE <em class="replaceable"><code>routine_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ SCHEMA <em class="replaceable"><code>object_name</code></em> |
+ SEQUENCE <em class="replaceable"><code>object_name</code></em> |
+ SERVER <em class="replaceable"><code>object_name</code></em> |
+ TABLE <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH CONFIGURATION <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH DICTIONARY <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH PARSER <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH TEMPLATE <em class="replaceable"><code>object_name</code></em> |
+ TRANSFORM FOR <em class="replaceable"><code>type_name</code></em> LANGUAGE <em class="replaceable"><code>lang_name</code></em> |
+ TYPE <em class="replaceable"><code>object_name</code></em> |
+ VIEW <em class="replaceable"><code>object_name</code></em>
+
+<span class="phrase">and <em class="replaceable"><code>aggregate_signature</code></em> is:</span>
+
+* |
+[ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] |
+[ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] ] ORDER BY [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.11.5"><h2>Description</h2><p>
+ <code class="command">ALTER EXTENSION</code> changes the definition of an installed
+ extension. There are several subforms:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">UPDATE</code></span></dt><dd><p>
+ This form updates the extension to a newer version. The extension
+ must supply a suitable update script (or series of scripts) that can
+ modify the currently-installed version into the requested version.
+ </p></dd><dt><span class="term"><code class="literal">SET SCHEMA</code></span></dt><dd><p>
+ This form moves the extension's objects into another schema. The
+ extension has to be <em class="firstterm">relocatable</em> for this command to
+ succeed.
+ </p></dd><dt><span class="term"><code class="literal">ADD <em class="replaceable"><code>member_object</code></em></code></span></dt><dd><p>
+ This form adds an existing object to the extension. This is mainly
+ useful in extension update scripts. The object will subsequently
+ be treated as a member of the extension; notably, it can only be
+ dropped by dropping the extension.
+ </p></dd><dt><span class="term"><code class="literal">DROP <em class="replaceable"><code>member_object</code></em></code></span></dt><dd><p>
+ This form removes a member object from the extension. This is mainly
+ useful in extension update scripts. The object is not dropped, only
+ disassociated from the extension.
+ </p></dd></dl></div><p>
+
+ See <a class="xref" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Section 38.17</a> for more information about these
+ operations.
+ </p><p>
+ You must own the extension to use <code class="command">ALTER EXTENSION</code>.
+ The <code class="literal">ADD</code>/<code class="literal">DROP</code> forms require ownership of the
+ added/dropped object as well.
+ </p></div><div class="refsect1" id="id-1.9.3.11.6"><h2>Parameters</h2><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an installed extension.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_version</code></em></span></dt><dd><p>
+ The desired new version of the extension. This can be written as
+ either an identifier or a string literal. If not specified,
+ <code class="command">ALTER EXTENSION UPDATE</code> attempts to update to whatever is
+ shown as the default version in the extension's control file.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the extension.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>object_name</code></em><br /></span><span class="term"><em class="replaceable"><code>aggregate_name</code></em><br /></span><span class="term"><em class="replaceable"><code>function_name</code></em><br /></span><span class="term"><em class="replaceable"><code>operator_name</code></em><br /></span><span class="term"><em class="replaceable"><code>procedure_name</code></em><br /></span><span class="term"><em class="replaceable"><code>routine_name</code></em></span></dt><dd><p>
+ The name of an object to be added to or removed from the extension.
+ Names of tables,
+ aggregates, domains, foreign tables, functions, operators,
+ operator classes, operator families, procedures, routines, sequences, text search objects,
+ types, and views can be schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_type</code></em></span></dt><dd><p>
+ The name of the source data type of the cast.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>target_type</code></em></span></dt><dd><p>
+ The name of the target data type of the cast.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of a function, procedure, or aggregate
+ argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ Note that <code class="command">ALTER EXTENSION</code> does not actually pay
+ any attention to <code class="literal">OUT</code> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <code class="literal">IN</code>, <code class="literal">INOUT</code>,
+ and <code class="literal">VARIADIC</code> arguments.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of a function, procedure, or aggregate argument.
+ Note that <code class="command">ALTER EXTENSION</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type of a function, procedure, or aggregate argument.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>left_type</code></em><br /></span><span class="term"><em class="replaceable"><code>right_type</code></em></span></dt><dd><p>
+ The data type(s) of the operator's arguments (optionally
+ schema-qualified). Write <code class="literal">NONE</code> for the missing argument
+ of a prefix operator.
+ </p></dd><dt><span class="term"><code class="literal">PROCEDURAL</code></span></dt><dd><p>
+ This is a noise word.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>type_name</code></em></span></dt><dd><p>
+ The name of the data type of the transform.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the language of the transform.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.11.7"><h2>Examples</h2><p>
+ To update the <code class="literal">hstore</code> extension to version 2.0:
+</p><pre class="programlisting">
+ALTER EXTENSION hstore UPDATE TO '2.0';
+</pre><p>
+ </p><p>
+ To change the schema of the <code class="literal">hstore</code> extension
+ to <code class="literal">utils</code>:
+</p><pre class="programlisting">
+ALTER EXTENSION hstore SET SCHEMA utils;
+</pre><p>
+ </p><p>
+ To add an existing function to the <code class="literal">hstore</code> extension:
+</p><pre class="programlisting">
+ALTER EXTENSION hstore ADD FUNCTION populate_record(anyelement, hstore);
+</pre></div><div class="refsect1" id="id-1.9.3.11.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER EXTENSION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="SQL-ALTEREXTENSION-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createextension.html" title="CREATE EXTENSION"><span class="refentrytitle">CREATE EXTENSION</span></a>, <a class="xref" href="sql-dropextension.html" title="DROP EXTENSION"><span class="refentrytitle">DROP EXTENSION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER EVENT TRIGGER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER FOREIGN DATA WRAPPER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterforeigndatawrapper.html b/doc/src/sgml/html/sql-alterforeigndatawrapper.html
new file mode 100644
index 0000000..fcbbb79
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterforeigndatawrapper.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER FOREIGN DATA WRAPPER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterextension.html" title="ALTER EXTENSION" /><link rel="next" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER FOREIGN DATA WRAPPER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterextension.html" title="ALTER EXTENSION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERFOREIGNDATAWRAPPER"><div class="titlepage"></div><a id="id-1.9.3.12.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER FOREIGN DATA WRAPPER</span></h2><p>ALTER FOREIGN DATA WRAPPER — change the definition of a foreign-data wrapper</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER FOREIGN DATA WRAPPER <em class="replaceable"><code>name</code></em>
+ [ HANDLER <em class="replaceable"><code>handler_function</code></em> | NO HANDLER ]
+ [ VALIDATOR <em class="replaceable"><code>validator_function</code></em> | NO VALIDATOR ]
+ [ OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ]) ]
+ALTER FOREIGN DATA WRAPPER <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER FOREIGN DATA WRAPPER <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.12.5"><h2>Description</h2><p>
+ <code class="command">ALTER FOREIGN DATA WRAPPER</code> changes the
+ definition of a foreign-data wrapper. The first form of the
+ command changes the support functions or the generic options of the
+ foreign-data wrapper (at least one clause is required). The second
+ form changes the owner of the foreign-data wrapper.
+ </p><p>
+ Only superusers can alter foreign-data wrappers. Additionally,
+ only superusers can own foreign-data wrappers.
+ </p></div><div class="refsect1" id="id-1.9.3.12.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing foreign-data wrapper.
+ </p></dd><dt><span class="term"><code class="literal">HANDLER <em class="replaceable"><code>handler_function</code></em></code></span></dt><dd><p>
+ Specifies a new handler function for the foreign-data wrapper.
+ </p></dd><dt><span class="term"><code class="literal">NO HANDLER</code></span></dt><dd><p>
+ This is used to specify that the foreign-data wrapper should no
+ longer have a handler function.
+ </p><p>
+ Note that foreign tables that use a foreign-data wrapper with no
+ handler cannot be accessed.
+ </p></dd><dt><span class="term"><code class="literal">VALIDATOR <em class="replaceable"><code>validator_function</code></em></code></span></dt><dd><p>
+ Specifies a new validator function for the foreign-data wrapper.
+ </p><p>
+ Note that it is possible that pre-existing options of the foreign-data
+ wrapper, or of dependent servers, user mappings, or foreign tables, are
+ invalid according to the new validator. <span class="productname">PostgreSQL</span> does
+ not check for this. It is up to the user to make sure that these
+ options are correct before using the modified foreign-data wrapper.
+ However, any options specified in this <code class="command">ALTER FOREIGN DATA
+ WRAPPER</code> command will be checked using the new validator.
+ </p></dd><dt><span class="term"><code class="literal">NO VALIDATOR</code></span></dt><dd><p>
+ This is used to specify that the foreign-data wrapper should no
+ longer have a validator function.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ] )</code></span></dt><dd><p>
+ Change options for the foreign-data
+ wrapper. <code class="literal">ADD</code>, <code class="literal">SET</code>, and <code class="literal">DROP</code>
+ specify the action to be performed. <code class="literal">ADD</code> is assumed
+ if no operation is explicitly specified. Option names must be
+ unique; names and values are also validated using the foreign
+ data wrapper's validator function, if any.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the foreign-data wrapper.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the foreign-data wrapper.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.12.7"><h2>Examples</h2><p>
+ Change a foreign-data wrapper <code class="literal">dbi</code>, add
+ option <code class="literal">foo</code>, drop <code class="literal">bar</code>:
+</p><pre class="programlisting">
+ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo '1', DROP 'bar');
+</pre><p>
+ </p><p>
+ Change the foreign-data wrapper <code class="literal">dbi</code> validator
+ to <code class="literal">bob.myvalidator</code>:
+</p><pre class="programlisting">
+ALTER FOREIGN DATA WRAPPER dbi VALIDATOR bob.myvalidator;
+</pre></div><div class="refsect1" id="id-1.9.3.12.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER FOREIGN DATA WRAPPER</code> conforms to ISO/IEC
+ 9075-9 (SQL/MED), except that the <code class="literal">HANDLER</code>,
+ <code class="literal">VALIDATOR</code>, <code class="literal">OWNER TO</code>, and <code class="literal">RENAME</code>
+ clauses are extensions.
+ </p></div><div class="refsect1" id="id-1.9.3.12.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a>, <a class="xref" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER"><span class="refentrytitle">DROP FOREIGN DATA WRAPPER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterextension.html" title="ALTER EXTENSION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER EXTENSION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER FOREIGN TABLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterforeigntable.html b/doc/src/sgml/html/sql-alterforeigntable.html
new file mode 100644
index 0000000..2eaaeb8
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterforeigntable.html
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER FOREIGN TABLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER" /><link rel="next" href="sql-alterfunction.html" title="ALTER FUNCTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER FOREIGN TABLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterfunction.html" title="ALTER FUNCTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERFOREIGNTABLE"><div class="titlepage"></div><a id="id-1.9.3.13.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER FOREIGN TABLE</span></h2><p>ALTER FOREIGN TABLE — change the definition of a foreign table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ]
+ <em class="replaceable"><code>action</code></em> [, ... ]
+ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ]
+ RENAME [ COLUMN ] <em class="replaceable"><code>column_name</code></em> TO <em class="replaceable"><code>new_column_name</code></em>
+ALTER FOREIGN TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER FOREIGN TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ ADD [ COLUMN ] <em class="replaceable"><code>column_name</code></em> <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ DROP [ COLUMN ] [ IF EXISTS ] <em class="replaceable"><code>column_name</code></em> [ RESTRICT | CASCADE ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> [ SET DATA ] TYPE <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET DEFAULT <em class="replaceable"><code>expression</code></em>
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> DROP DEFAULT
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> { SET | DROP } NOT NULL
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET STATISTICS <em class="replaceable"><code>integer</code></em>
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET ( <em class="replaceable"><code>attribute_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> RESET ( <em class="replaceable"><code>attribute_option</code></em> [, ... ] )
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ])
+ ADD <em class="replaceable"><code>table_constraint</code></em> [ NOT VALID ]
+ VALIDATE CONSTRAINT <em class="replaceable"><code>constraint_name</code></em>
+ DROP CONSTRAINT [ IF EXISTS ] <em class="replaceable"><code>constraint_name</code></em> [ RESTRICT | CASCADE ]
+ DISABLE TRIGGER [ <em class="replaceable"><code>trigger_name</code></em> | ALL | USER ]
+ ENABLE TRIGGER [ <em class="replaceable"><code>trigger_name</code></em> | ALL | USER ]
+ ENABLE REPLICA TRIGGER <em class="replaceable"><code>trigger_name</code></em>
+ ENABLE ALWAYS TRIGGER <em class="replaceable"><code>trigger_name</code></em>
+ SET WITHOUT OIDS
+ INHERIT <em class="replaceable"><code>parent_table</code></em>
+ NO INHERIT <em class="replaceable"><code>parent_table</code></em>
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ])
+</pre></div><div class="refsect1" id="id-1.9.3.13.5"><h2>Description</h2><p>
+ <code class="command">ALTER FOREIGN TABLE</code> changes the definition of an
+ existing foreign table. There are several subforms:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ADD COLUMN</code></span></dt><dd><p>
+ This form adds a new column to the foreign table, using the same syntax as
+ <a class="link" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><code class="command">CREATE FOREIGN TABLE</code></a>.
+ Unlike the case when adding a column to a regular table, nothing happens
+ to the underlying storage: this action simply declares that
+ some new column is now accessible through the foreign table.
+ </p></dd><dt><span class="term"><code class="literal">DROP COLUMN [ IF EXISTS ]</code></span></dt><dd><p>
+ This form drops a column from a foreign table.
+ You will need to say <code class="literal">CASCADE</code> if
+ anything outside the table depends on the column; for example,
+ views.
+ If <code class="literal">IF EXISTS</code> is specified and the column
+ does not exist, no error is thrown. In this case a notice
+ is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">SET DATA TYPE</code></span></dt><dd><p>
+ This form changes the type of a column of a foreign table.
+ Again, this has no effect on any underlying storage: this action simply
+ changes the type that <span class="productname">PostgreSQL</span> believes the column to
+ have.
+ </p></dd><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP DEFAULT</code></span></dt><dd><p>
+ These forms set or remove the default value for a column.
+ Default values only apply in subsequent <code class="command">INSERT</code>
+ or <code class="command">UPDATE</code> commands; they do not cause rows already in the
+ table to change.
+ </p></dd><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP NOT NULL</code></span></dt><dd><p>
+ Mark a column as allowing, or not allowing, null values.
+ </p></dd><dt><span class="term"><code class="literal">SET STATISTICS</code></span></dt><dd><p>
+ This form
+ sets the per-column statistics-gathering target for subsequent
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> operations.
+ See the similar form of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>
+ for more details.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>attribute_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )</code><br /></span><span class="term"><code class="literal">RESET ( <em class="replaceable"><code>attribute_option</code></em> [, ... ] )</code></span></dt><dd><p>
+ This form sets or resets per-attribute options.
+ See the similar form of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>
+ for more details.
+ </p></dd><dt><span class="term">
+ <code class="literal">SET STORAGE</code>
+ </span></dt><dd><p>
+ This form sets the storage mode for a column.
+ See the similar form of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>
+ for more details.
+ Note that the storage mode has no effect unless the table's
+ foreign-data wrapper chooses to pay attention to it.
+ </p></dd><dt><span class="term"><code class="literal">ADD <em class="replaceable"><code>table_constraint</code></em> [ NOT VALID ]</code></span></dt><dd><p>
+ This form adds a new constraint to a foreign table, using the same
+ syntax as <a class="link" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><code class="command">CREATE FOREIGN TABLE</code></a>.
+ Currently only <code class="literal">CHECK</code> constraints are supported.
+ </p><p>
+ Unlike the case when adding a constraint to a regular table, nothing is
+ done to verify the constraint is correct; rather, this action simply
+ declares that some new condition should be assumed to hold for all rows
+ in the foreign table. (See the discussion
+ in <a class="link" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><code class="command">CREATE FOREIGN TABLE</code></a>.)
+ If the constraint is marked <code class="literal">NOT VALID</code>, then it isn't
+ assumed to hold, but is only recorded for possible future use.
+ </p></dd><dt><span class="term"><code class="literal">VALIDATE CONSTRAINT</code></span></dt><dd><p>
+ This form marks as valid a constraint that was previously marked
+ as <code class="literal">NOT VALID</code>. No action is taken to verify the
+ constraint, but future queries will assume that it holds.
+ </p></dd><dt><span class="term"><code class="literal">DROP CONSTRAINT [ IF EXISTS ]</code></span></dt><dd><p>
+ This form drops the specified constraint on a foreign table.
+ If <code class="literal">IF EXISTS</code> is specified and the constraint
+ does not exist, no error is thrown.
+ In this case a notice is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE</code>/<code class="literal">ENABLE [ REPLICA | ALWAYS ] TRIGGER</code></span></dt><dd><p>
+ These forms configure the firing of trigger(s) belonging to the foreign
+ table. See the similar form of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a> for more
+ details.
+ </p></dd><dt><span class="term"><code class="literal">SET WITHOUT OIDS</code></span></dt><dd><p>
+ Backward compatibility syntax for removing the <code class="literal">oid</code>
+ system column. As <code class="literal">oid</code> system columns cannot be added
+ anymore, this never has an effect.
+ </p></dd><dt><span class="term"><code class="literal">INHERIT <em class="replaceable"><code>parent_table</code></em></code></span></dt><dd><p>
+ This form adds the target foreign table as a new child of the specified
+ parent table.
+ See the similar form of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>
+ for more details.
+ </p></dd><dt><span class="term"><code class="literal">NO INHERIT <em class="replaceable"><code>parent_table</code></em></code></span></dt><dd><p>
+ This form removes the target foreign table from the list of children of
+ the specified parent table.
+ </p></dd><dt><span class="term"><code class="literal">OWNER</code></span></dt><dd><p>
+ This form changes the owner of the foreign table to the
+ specified user.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ] )</code></span></dt><dd><p>
+ Change options for the foreign table or one of its columns.
+ <code class="literal">ADD</code>, <code class="literal">SET</code>, and <code class="literal">DROP</code>
+ specify the action to be performed. <code class="literal">ADD</code> is assumed
+ if no operation is explicitly specified. Duplicate option names are not
+ allowed (although it's OK for a table option and a column option to have
+ the same name). Option names and values are also validated using the
+ foreign data wrapper library.
+ </p></dd><dt><span class="term"><code class="literal">RENAME</code></span></dt><dd><p>
+ The <code class="literal">RENAME</code> forms change the name of a foreign table
+ or the name of an individual column in a foreign table.
+ </p></dd><dt><span class="term"><code class="literal">SET SCHEMA</code></span></dt><dd><p>
+ This form moves the foreign table into another schema.
+ </p></dd></dl></div><p>
+ </p><p>
+ All the actions except <code class="literal">RENAME</code> and <code class="literal">SET SCHEMA</code>
+ can be combined into
+ a list of multiple alterations to apply in parallel. For example, it
+ is possible to add several columns and/or alter the type of several
+ columns in a single command.
+ </p><p>
+ If the command is written as <code class="literal">ALTER FOREIGN TABLE IF EXISTS ...</code>
+ and the foreign table does not exist, no error is thrown. A notice is
+ issued in this case.
+ </p><p>
+ You must own the table to use <code class="command">ALTER FOREIGN TABLE</code>.
+ To change the schema of a foreign table, you must also have
+ <code class="literal">CREATE</code> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the table's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the table.
+ However, a superuser can alter ownership of any table anyway.)
+ To add a column or alter a column type, you must also
+ have <code class="literal">USAGE</code> privilege on the data type.
+ </p></div><div class="refsect1" id="id-1.9.3.13.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of an existing foreign table to
+ alter. If <code class="literal">ONLY</code> is specified before the table name, only
+ that table is altered. If <code class="literal">ONLY</code> is not specified, the table
+ and all its descendant tables (if any) are altered. Optionally,
+ <code class="literal">*</code> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ Name of a new or existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_column_name</code></em></span></dt><dd><p>
+ New name for an existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ New name for the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ Data type of the new column, or new data type for an existing
+ column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_constraint</code></em></span></dt><dd><p>
+ New table constraint for the foreign table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>constraint_name</code></em></span></dt><dd><p>
+ Name of an existing constraint to drop.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the dropped column
+ or constraint (for example, views referencing the column),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the column or constraint if there are any dependent
+ objects. This is the default behavior.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>trigger_name</code></em></span></dt><dd><p>
+ Name of a single trigger to disable or enable.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Disable or enable all triggers belonging to the foreign table. (This
+ requires superuser privilege if any of the triggers are internally
+ generated triggers. The core system does not add such triggers to
+ foreign tables, but add-on code could do so.)
+ </p></dd><dt><span class="term"><code class="literal">USER</code></span></dt><dd><p>
+ Disable or enable all triggers belonging to the foreign table except
+ for internally generated triggers.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>parent_table</code></em></span></dt><dd><p>
+ A parent table to associate or de-associate with this foreign table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The name of the schema to which the table will be moved.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.13.7"><h2>Notes</h2><p>
+ The key word <code class="literal">COLUMN</code> is noise and can be omitted.
+ </p><p>
+ Consistency with the foreign server is not checked when a column is added
+ or removed with <code class="literal">ADD COLUMN</code> or
+ <code class="literal">DROP COLUMN</code>, a <code class="literal">NOT NULL</code>
+ or <code class="literal">CHECK</code> constraint is added, or a column type is changed
+ with <code class="literal">SET DATA TYPE</code>. It is the user's responsibility to ensure
+ that the table definition matches the remote side.
+ </p><p>
+ Refer to <a class="link" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><code class="command">CREATE FOREIGN TABLE</code></a> for a further description of valid
+ parameters.
+ </p></div><div class="refsect1" id="id-1.9.3.13.8"><h2>Examples</h2><p>
+ To mark a column as not-null:
+</p><pre class="programlisting">
+ALTER FOREIGN TABLE distributors ALTER COLUMN street SET NOT NULL;
+</pre><p>
+ </p><p>
+ To change options of a foreign table:
+</p><pre class="programlisting">
+ALTER FOREIGN TABLE myschema.distributors OPTIONS (ADD opt1 'value', SET opt2 'value2', DROP opt3);
+</pre></div><div class="refsect1" id="id-1.9.3.13.9"><h2>Compatibility</h2><p>
+ The forms <code class="literal">ADD</code>, <code class="literal">DROP</code>,
+ and <code class="literal">SET DATA TYPE</code>
+ conform with the SQL standard. The other forms are
+ <span class="productname">PostgreSQL</span> extensions of the SQL standard.
+ Also, the ability to specify more than one manipulation in a single
+ <code class="command">ALTER FOREIGN TABLE</code> command is an extension.
+ </p><p>
+ <code class="command">ALTER FOREIGN TABLE DROP COLUMN</code> can be used to drop the only
+ column of a foreign table, leaving a zero-column table. This is an
+ extension of SQL, which disallows zero-column foreign tables.
+ </p></div><div class="refsect1" id="id-1.9.3.13.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>, <a class="xref" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE"><span class="refentrytitle">DROP FOREIGN TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterfunction.html" title="ALTER FUNCTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER FOREIGN DATA WRAPPER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER FUNCTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterfunction.html b/doc/src/sgml/html/sql-alterfunction.html
new file mode 100644
index 0000000..2bc2629
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterfunction.html
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER FUNCTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE" /><link rel="next" href="sql-altergroup.html" title="ALTER GROUP" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER FUNCTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altergroup.html" title="ALTER GROUP">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERFUNCTION"><div class="titlepage"></div><a id="id-1.9.3.14.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER FUNCTION</span></h2><p>ALTER FUNCTION — change the definition of a function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER FUNCTION <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ <em class="replaceable"><code>action</code></em> [ ... ] [ RESTRICT ]
+ALTER FUNCTION <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER FUNCTION <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER FUNCTION <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER FUNCTION <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
+ IMMUTABLE | STABLE | VOLATILE
+ [ NOT ] LEAKPROOF
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ COST <em class="replaceable"><code>execution_cost</code></em>
+ ROWS <em class="replaceable"><code>result_rows</code></em>
+ SUPPORT <em class="replaceable"><code>support_function</code></em>
+ SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | DEFAULT }
+ SET <em class="replaceable"><code>configuration_parameter</code></em> FROM CURRENT
+ RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ RESET ALL
+</pre></div><div class="refsect1" id="id-1.9.3.14.5"><h2>Description</h2><p>
+ <code class="command">ALTER FUNCTION</code> changes the definition of a
+ function.
+ </p><p>
+ You must own the function to use <code class="command">ALTER FUNCTION</code>.
+ To change a function's schema, you must also have <code class="literal">CREATE</code>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the function's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the function.
+ However, a superuser can alter ownership of any function anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.14.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing function. If no
+ argument list is specified, the name must be unique in its schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ Note that <code class="command">ALTER FUNCTION</code> does not actually pay
+ any attention to <code class="literal">OUT</code> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <code class="literal">IN</code>, <code class="literal">INOUT</code>,
+ and <code class="literal">VARIADIC</code> arguments.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ Note that <code class="command">ALTER FUNCTION</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type(s) of the function's arguments (optionally
+ schema-qualified), if any.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the function. Note that if the function is
+ marked <code class="literal">SECURITY DEFINER</code>, it will subsequently
+ execute as the new owner.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the function.
+ </p></dd><dt><span class="term"><code class="literal">DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em></code><br /></span><span class="term"><code class="literal">NO DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em></code></span></dt><dd><p>
+ This form marks the function as dependent on the extension, or no longer
+ dependent on that extension if <code class="literal">NO</code> is specified.
+ A function that's marked as dependent on an extension is dropped when the
+ extension is dropped, even if <code class="literal">CASCADE</code> is not specified.
+ A function can depend upon multiple extensions, and will be dropped when
+ any one of those extensions is dropped.
+ </p></dd><dt><span class="term"><code class="literal">CALLED ON NULL INPUT</code><br /></span><span class="term"><code class="literal">RETURNS NULL ON NULL INPUT</code><br /></span><span class="term"><code class="literal">STRICT</code></span></dt><dd><p><code class="literal">CALLED ON NULL INPUT</code> changes the function so
+ that it will be invoked when some or all of its arguments are
+ null. <code class="literal">RETURNS NULL ON NULL INPUT</code> or
+ <code class="literal">STRICT</code> changes the function so that it is not
+ invoked if any of its arguments are null; instead, a null result
+ is assumed automatically. See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>
+ for more information.
+ </p></dd><dt><span class="term"><code class="literal">IMMUTABLE</code><br /></span><span class="term"><code class="literal">STABLE</code><br /></span><span class="term"><code class="literal">VOLATILE</code></span></dt><dd><p>
+ Change the volatility of the function to the specified setting.
+ See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for details.
+ </p></dd><dt><span class="term"><code class="literal">[<span class="optional"> EXTERNAL </span>] SECURITY INVOKER</code><br /></span><span class="term"><code class="literal">[<span class="optional"> EXTERNAL </span>] SECURITY DEFINER</code></span></dt><dd><p>
+ Change whether the function is a security definer or not. The
+ key word <code class="literal">EXTERNAL</code> is ignored for SQL
+ conformance. See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for more information about
+ this capability.
+ </p></dd><dt><span class="term"><code class="literal">PARALLEL</code></span></dt><dd><p>
+ Change whether the function is deemed safe for parallelism.
+ See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for details.
+ </p></dd><dt><span class="term"><code class="literal">LEAKPROOF</code></span></dt><dd><p>
+ Change whether the function is considered leakproof or not.
+ See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for more information about
+ this capability.
+ </p></dd><dt><span class="term"><code class="literal">COST</code> <em class="replaceable"><code>execution_cost</code></em></span></dt><dd><p>
+ Change the estimated execution cost of the function.
+ See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for more information.
+ </p></dd><dt><span class="term"><code class="literal">ROWS</code> <em class="replaceable"><code>result_rows</code></em></span></dt><dd><p>
+ Change the estimated number of rows returned by a set-returning
+ function. See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for more information.
+ </p></dd><dt><span class="term"><code class="literal">SUPPORT</code> <em class="replaceable"><code>support_function</code></em></span></dt><dd><p>
+ Set or change the planner support function to use for this function.
+ See <a class="xref" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Section 38.11</a> for details. You must be
+ superuser to use this option.
+ </p><p>
+ This option cannot be used to remove the support function altogether,
+ since it must name a new support function. Use <code class="command">CREATE OR
+ REPLACE FUNCTION</code> if you need to do that.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em><br /></span><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ Add or change the assignment to be made to a configuration parameter
+ when the function is called. If
+ <em class="replaceable"><code>value</code></em> is <code class="literal">DEFAULT</code>
+ or, equivalently, <code class="literal">RESET</code> is used, the function-local
+ setting is removed, so that the function executes with the value
+ present in its environment. Use <code class="literal">RESET
+ ALL</code> to clear all function-local settings.
+ <code class="literal">SET FROM CURRENT</code> saves the value of the parameter that
+ is current when <code class="command">ALTER FUNCTION</code> is executed as the value
+ to be applied when the function is entered.
+ </p><p>
+ See <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> and
+ <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ for more information about allowed parameter names and values.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Ignored for conformance with the SQL standard.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.14.7"><h2>Examples</h2><p>
+ To rename the function <code class="literal">sqrt</code> for type
+ <code class="type">integer</code> to <code class="literal">square_root</code>:
+</p><pre class="programlisting">
+ALTER FUNCTION sqrt(integer) RENAME TO square_root;
+</pre><p>
+ </p><p>
+ To change the owner of the function <code class="literal">sqrt</code> for type
+ <code class="type">integer</code> to <code class="literal">joe</code>:
+</p><pre class="programlisting">
+ALTER FUNCTION sqrt(integer) OWNER TO joe;
+</pre><p>
+ </p><p>
+ To change the schema of the function <code class="literal">sqrt</code> for type
+ <code class="type">integer</code> to <code class="literal">maths</code>:
+</p><pre class="programlisting">
+ALTER FUNCTION sqrt(integer) SET SCHEMA maths;
+</pre><p>
+ </p><p>
+ To mark the function <code class="literal">sqrt</code> for type
+ <code class="type">integer</code> as being dependent on the extension
+ <code class="literal">mathlib</code>:
+</p><pre class="programlisting">
+ALTER FUNCTION sqrt(integer) DEPENDS ON EXTENSION mathlib;
+</pre><p>
+ </p><p>
+ To adjust the search path that is automatically set for a function:
+</p><pre class="programlisting">
+ALTER FUNCTION check_password(text) SET search_path = admin, pg_temp;
+</pre><p>
+ </p><p>
+ To disable automatic setting of <code class="varname">search_path</code> for a function:
+</p><pre class="programlisting">
+ALTER FUNCTION check_password(text) RESET search_path;
+</pre><p>
+ The function will now execute with whatever search path is used by its
+ caller.
+ </p></div><div class="refsect1" id="id-1.9.3.14.8"><h2>Compatibility</h2><p>
+ This statement is partially compatible with the <code class="command">ALTER
+ FUNCTION</code> statement in the SQL standard. The standard allows more
+ properties of a function to be modified, but does not provide the
+ ability to rename a function, make a function a security definer,
+ attach configuration parameter values to a function,
+ or change the owner, schema, or volatility of a function. The standard also
+ requires the <code class="literal">RESTRICT</code> key word, which is optional in
+ <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect1" id="id-1.9.3.14.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-dropfunction.html" title="DROP FUNCTION"><span class="refentrytitle">DROP FUNCTION</span></a>, <a class="xref" href="sql-alterprocedure.html" title="ALTER PROCEDURE"><span class="refentrytitle">ALTER PROCEDURE</span></a>, <a class="xref" href="sql-alterroutine.html" title="ALTER ROUTINE"><span class="refentrytitle">ALTER ROUTINE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altergroup.html" title="ALTER GROUP">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER FOREIGN TABLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER GROUP</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altergroup.html b/doc/src/sgml/html/sql-altergroup.html
new file mode 100644
index 0000000..05e5308
--- /dev/null
+++ b/doc/src/sgml/html/sql-altergroup.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER GROUP</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterfunction.html" title="ALTER FUNCTION" /><link rel="next" href="sql-alterindex.html" title="ALTER INDEX" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER GROUP</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterfunction.html" title="ALTER FUNCTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterindex.html" title="ALTER INDEX">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERGROUP"><div class="titlepage"></div><a id="id-1.9.3.15.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER GROUP</span></h2><p>ALTER GROUP — change role name or membership</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER GROUP <em class="replaceable"><code>role_specification</code></em> ADD USER <em class="replaceable"><code>user_name</code></em> [, ... ]
+ALTER GROUP <em class="replaceable"><code>role_specification</code></em> DROP USER <em class="replaceable"><code>user_name</code></em> [, ... ]
+
+<span class="phrase">where <em class="replaceable"><code>role_specification</code></em> can be:</span>
+
+ <em class="replaceable"><code>role_name</code></em>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+
+ALTER GROUP <em class="replaceable"><code>group_name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.15.5"><h2>Description</h2><p>
+ <code class="command">ALTER GROUP</code> changes the attributes of a user group.
+ This is an obsolete command, though still accepted for backwards
+ compatibility, because groups (and users too) have been superseded by the
+ more general concept of roles.
+ </p><p>
+ The first two variants add users to a group or remove them from a group.
+ (Any role can play the part of either a <span class="quote">“<span class="quote">user</span>”</span> or a
+ <span class="quote">“<span class="quote">group</span>”</span> for this purpose.) These variants are effectively
+ equivalent to granting or revoking membership in the role named as the
+ <span class="quote">“<span class="quote">group</span>”</span>; so the preferred way to do this is to use
+ <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> or
+ <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a>.
+ </p><p>
+ The third variant changes the name of the group. This is exactly
+ equivalent to renaming the role with
+ <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.15.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>group_name</code></em></span></dt><dd><p>
+ The name of the group (role) to modify.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ Users (roles) that are to be added to or removed from the group.
+ The users must already exist; <code class="command">ALTER GROUP</code> does not
+ create or drop users.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the group.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.15.7"><h2>Examples</h2><p>
+ Add users to a group:
+
+</p><pre class="programlisting">
+ALTER GROUP staff ADD USER karl, john;
+</pre><p>
+
+ Remove a user from a group:
+
+</p><pre class="programlisting">
+ALTER GROUP workers DROP USER beth;
+</pre></div><div class="refsect1" id="id-1.9.3.15.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER GROUP</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.15.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>, <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a>, <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterfunction.html" title="ALTER FUNCTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterindex.html" title="ALTER INDEX">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER FUNCTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER INDEX</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterindex.html b/doc/src/sgml/html/sql-alterindex.html
new file mode 100644
index 0000000..7b1c776
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterindex.html
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER INDEX</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altergroup.html" title="ALTER GROUP" /><link rel="next" href="sql-alterlanguage.html" title="ALTER LANGUAGE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER INDEX</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altergroup.html" title="ALTER GROUP">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterlanguage.html" title="ALTER LANGUAGE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERINDEX"><div class="titlepage"></div><a id="id-1.9.3.16.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER INDEX</span></h2><p>ALTER INDEX — change the definition of an index</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER INDEX [ IF EXISTS ] <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER INDEX [ IF EXISTS ] <em class="replaceable"><code>name</code></em> SET TABLESPACE <em class="replaceable"><code>tablespace_name</code></em>
+ALTER INDEX <em class="replaceable"><code>name</code></em> ATTACH PARTITION <em class="replaceable"><code>index_name</code></em>
+ALTER INDEX <em class="replaceable"><code>name</code></em> [ NO ] DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+ALTER INDEX [ IF EXISTS ] <em class="replaceable"><code>name</code></em> SET ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )
+ALTER INDEX [ IF EXISTS ] <em class="replaceable"><code>name</code></em> RESET ( <em class="replaceable"><code>storage_parameter</code></em> [, ... ] )
+ALTER INDEX [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ALTER [ COLUMN ] <em class="replaceable"><code>column_number</code></em>
+ SET STATISTICS <em class="replaceable"><code>integer</code></em>
+ALTER INDEX ALL IN TABLESPACE <em class="replaceable"><code>name</code></em> [ OWNED BY <em class="replaceable"><code>role_name</code></em> [, ... ] ]
+ SET TABLESPACE <em class="replaceable"><code>new_tablespace</code></em> [ NOWAIT ]
+</pre></div><div class="refsect1" id="id-1.9.3.16.5"><h2>Description</h2><p>
+ <code class="command">ALTER INDEX</code> changes the definition of an existing index.
+ There are several subforms described below. Note that the lock level required
+ may differ for each subform. An <code class="literal">ACCESS EXCLUSIVE</code> lock is held
+ unless explicitly noted. When multiple subcommands are listed, the lock
+ held will be the strictest one required from any subcommand.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">RENAME</code></span></dt><dd><p>
+ The <code class="literal">RENAME</code> form changes the name of the index.
+ If the index is associated with a table constraint (either
+ <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY KEY</code>,
+ or <code class="literal">EXCLUDE</code>), the constraint is renamed as well.
+ There is no effect on the stored data.
+ </p><p>
+ Renaming an index acquires a <code class="literal">SHARE UPDATE EXCLUSIVE</code>
+ lock.
+ </p></dd><dt><span class="term"><code class="literal">SET TABLESPACE</code></span></dt><dd><p>
+ This form changes the index's tablespace to the specified tablespace and
+ moves the data file(s) associated with the index to the new tablespace.
+ To change the tablespace of an index, you must own the index and have
+ <code class="literal">CREATE</code> privilege on the new tablespace.
+ All indexes in the current database in a tablespace can be moved by using
+ the <code class="literal">ALL IN TABLESPACE</code> form, which will lock all
+ indexes to be moved and then move each one. This form also supports
+ <code class="literal">OWNED BY</code>, which will only move indexes owned by the
+ roles specified. If the <code class="literal">NOWAIT</code> option is specified
+ then the command will fail if it is unable to acquire all of the locks
+ required immediately. Note that system catalogs will not be moved by
+ this command, use <code class="command">ALTER DATABASE</code> or explicit
+ <code class="command">ALTER INDEX</code> invocations instead if desired.
+ See also
+ <a class="link" href="sql-createtablespace.html" title="CREATE TABLESPACE"><code class="command">CREATE TABLESPACE</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">ATTACH PARTITION</code></span></dt><dd><p>
+ Causes the named index to become attached to the altered index.
+ The named index must be on a partition of the table containing the
+ index being altered, and have an equivalent definition. An attached
+ index cannot be dropped by itself, and will automatically be dropped
+ if its parent index is dropped.
+ </p></dd><dt><span class="term"><code class="literal">DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em></code><br /></span><span class="term"><code class="literal">NO DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em></code></span></dt><dd><p>
+ This form marks the index as dependent on the extension, or no longer
+ dependent on that extension if <code class="literal">NO</code> is specified.
+ An index that's marked as dependent on an extension is automatically
+ dropped when the extension is dropped.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This form changes one or more index-method-specific storage parameters
+ for the index. See
+ <a class="link" href="sql-createindex.html" title="CREATE INDEX"><code class="command">CREATE INDEX</code></a>
+ for details on the available parameters. Note that the index contents
+ will not be modified immediately by this command; depending on the
+ parameter you might need to rebuild the index with
+ <a class="link" href="sql-reindex.html" title="REINDEX"><code class="command">REINDEX</code></a>
+ to get the desired effects.
+ </p></dd><dt><span class="term"><code class="literal">RESET ( <em class="replaceable"><code>storage_parameter</code></em> [, ... ] )</code></span></dt><dd><p>
+ This form resets one or more index-method-specific storage parameters to
+ their defaults. As with <code class="literal">SET</code>, a <code class="literal">REINDEX</code>
+ might be needed to update the index entirely.
+ </p></dd><dt><span class="term"><code class="literal">ALTER [ COLUMN ] <em class="replaceable"><code>column_number</code></em> SET STATISTICS <em class="replaceable"><code>integer</code></em></code></span></dt><dd><p>
+ This form sets the per-column statistics-gathering target for
+ subsequent <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> operations, though can
+ be used only on index columns that are defined as an expression.
+ Since expressions lack a unique name, we refer to them using the
+ ordinal number of the index column.
+ The target can be set in the range 0 to 10000; alternatively, set it
+ to -1 to revert to using the system default statistics
+ target (<a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a>).
+ For more information on the use of statistics by the
+ <span class="productname">PostgreSQL</span> query planner, refer to
+ <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.16.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the index does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_number</code></em></span></dt><dd><p>
+ The ordinal number refers to the ordinal (left-to-right) position
+ of the index column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of an existing index to
+ alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the index.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>tablespace_name</code></em></span></dt><dd><p>
+ The tablespace to which the index will be moved.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>extension_name</code></em></span></dt><dd><p>
+ The name of the extension that the index is to depend on.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>storage_parameter</code></em></span></dt><dd><p>
+ The name of an index-method-specific storage parameter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ The new value for an index-method-specific storage parameter.
+ This might be a number or a word depending on the parameter.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.16.7"><h2>Notes</h2><p>
+ These operations are also possible using
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>.
+ <code class="command">ALTER INDEX</code> is in fact just an alias for the forms
+ of <code class="command">ALTER TABLE</code> that apply to indexes.
+ </p><p>
+ There was formerly an <code class="command">ALTER INDEX OWNER</code> variant, but
+ this is now ignored (with a warning). An index cannot have an owner
+ different from its table's owner. Changing the table's owner
+ automatically changes the index as well.
+ </p><p>
+ Changing any part of a system catalog index is not permitted.
+ </p></div><div class="refsect1" id="id-1.9.3.16.8"><h2>Examples</h2><p>
+ To rename an existing index:
+</p><pre class="programlisting">
+ALTER INDEX distributors RENAME TO suppliers;
+</pre><p>
+ </p><p>
+ To move an index to a different tablespace:
+</p><pre class="programlisting">
+ALTER INDEX distributors SET TABLESPACE fasttablespace;
+</pre><p>
+ </p><p>
+ To change an index's fill factor (assuming that the index method
+ supports it):
+</p><pre class="programlisting">
+ALTER INDEX distributors SET (fillfactor = 75);
+REINDEX INDEX distributors;
+</pre><p>
+ Set the statistics-gathering target for an expression index:
+</p><pre class="programlisting">
+CREATE INDEX coord_idx ON measured (x, y, (z + t));
+ALTER INDEX coord_idx ALTER COLUMN 3 SET STATISTICS 1000;
+</pre></div><div class="refsect1" id="id-1.9.3.16.9"><h2>Compatibility</h2><p>
+ <code class="command">ALTER INDEX</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.16.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>, <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altergroup.html" title="ALTER GROUP">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterlanguage.html" title="ALTER LANGUAGE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER GROUP </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER LANGUAGE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterlanguage.html b/doc/src/sgml/html/sql-alterlanguage.html
new file mode 100644
index 0000000..20b474e
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterlanguage.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER LANGUAGE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterindex.html" title="ALTER INDEX" /><link rel="next" href="sql-alterlargeobject.html" title="ALTER LARGE OBJECT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER LANGUAGE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterindex.html" title="ALTER INDEX">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterlargeobject.html" title="ALTER LARGE OBJECT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERLANGUAGE"><div class="titlepage"></div><a id="id-1.9.3.17.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER LANGUAGE</span></h2><p>ALTER LANGUAGE — change the definition of a procedural language</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</pre></div><div class="refsect1" id="id-1.9.3.17.5"><h2>Description</h2><p>
+ <code class="command">ALTER LANGUAGE</code> changes the definition of a
+ procedural language. The only functionality is to rename the language or
+ assign a new owner. You must be superuser or owner of the language to
+ use <code class="command">ALTER LANGUAGE</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.17.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ Name of a language
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the language
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the language
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.17.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER LANGUAGE</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.17.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createlanguage.html" title="CREATE LANGUAGE"><span class="refentrytitle">CREATE LANGUAGE</span></a>, <a class="xref" href="sql-droplanguage.html" title="DROP LANGUAGE"><span class="refentrytitle">DROP LANGUAGE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterindex.html" title="ALTER INDEX">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterlargeobject.html" title="ALTER LARGE OBJECT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER INDEX </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER LARGE OBJECT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterlargeobject.html b/doc/src/sgml/html/sql-alterlargeobject.html
new file mode 100644
index 0000000..9172895
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterlargeobject.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER LARGE OBJECT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterlanguage.html" title="ALTER LANGUAGE" /><link rel="next" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER LARGE OBJECT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterlanguage.html" title="ALTER LANGUAGE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERLARGEOBJECT"><div class="titlepage"></div><a id="id-1.9.3.18.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER LARGE OBJECT</span></h2><p>ALTER LARGE OBJECT — change the definition of a large object</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER LARGE OBJECT <em class="replaceable"><code>large_object_oid</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</pre></div><div class="refsect1" id="id-1.9.3.18.5"><h2>Description</h2><p>
+ <code class="command">ALTER LARGE OBJECT</code> changes the definition of a
+ large object.
+ </p><p>
+ You must own the large object to use <code class="command">ALTER LARGE OBJECT</code>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role. (However, a superuser can alter any large object anyway.)
+ Currently, the only functionality is to assign a new owner, so both
+ restrictions always apply.
+ </p></div><div class="refsect1" id="id-1.9.3.18.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>large_object_oid</code></em></span></dt><dd><p>
+ OID of the large object to be altered
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the large object
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.18.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER LARGE OBJECT</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.18.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="largeobjects.html" title="Chapter 35. Large Objects">Chapter 35</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterlanguage.html" title="ALTER LANGUAGE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER LANGUAGE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER MATERIALIZED VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altermaterializedview.html b/doc/src/sgml/html/sql-altermaterializedview.html
new file mode 100644
index 0000000..3f58270
--- /dev/null
+++ b/doc/src/sgml/html/sql-altermaterializedview.html
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER MATERIALIZED VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterlargeobject.html" title="ALTER LARGE OBJECT" /><link rel="next" href="sql-alteroperator.html" title="ALTER OPERATOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER MATERIALIZED VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterlargeobject.html" title="ALTER LARGE OBJECT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alteroperator.html" title="ALTER OPERATOR">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERMATERIALIZEDVIEW"><div class="titlepage"></div><a id="id-1.9.3.19.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER MATERIALIZED VIEW</span></h2><p>ALTER MATERIALIZED VIEW — change the definition of a materialized view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ <em class="replaceable"><code>action</code></em> [, ... ]
+ALTER MATERIALIZED VIEW <em class="replaceable"><code>name</code></em>
+ [ NO ] DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ RENAME [ COLUMN ] <em class="replaceable"><code>column_name</code></em> TO <em class="replaceable"><code>new_column_name</code></em>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER MATERIALIZED VIEW ALL IN TABLESPACE <em class="replaceable"><code>name</code></em> [ OWNED BY <em class="replaceable"><code>role_name</code></em> [, ... ] ]
+ SET TABLESPACE <em class="replaceable"><code>new_tablespace</code></em> [ NOWAIT ]
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET STATISTICS <em class="replaceable"><code>integer</code></em>
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET ( <em class="replaceable"><code>attribute_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> RESET ( <em class="replaceable"><code>attribute_option</code></em> [, ... ] )
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET COMPRESSION <em class="replaceable"><code>compression_method</code></em>
+ CLUSTER ON <em class="replaceable"><code>index_name</code></em>
+ SET WITHOUT CLUSTER
+ SET ACCESS METHOD <em class="replaceable"><code>new_access_method</code></em>
+ SET TABLESPACE <em class="replaceable"><code>new_tablespace</code></em>
+ SET ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )
+ RESET ( <em class="replaceable"><code>storage_parameter</code></em> [, ... ] )
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</pre></div><div class="refsect1" id="id-1.9.3.19.5"><h2>Description</h2><p>
+ <code class="command">ALTER MATERIALIZED VIEW</code> changes various auxiliary
+ properties of an existing materialized view.
+ </p><p>
+ You must own the materialized view to use <code class="command">ALTER MATERIALIZED
+ VIEW</code>. To change a materialized view's schema, you must also have
+ <code class="literal">CREATE</code> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the materialized view's schema. (These restrictions enforce that altering
+ the owner doesn't do anything you couldn't do by dropping and recreating the
+ materialized view. However, a superuser can alter ownership of any view
+ anyway.)
+ </p><p>
+ The statement subforms and actions available for
+ <code class="command">ALTER MATERIALIZED VIEW</code> are a subset of those available
+ for <code class="command">ALTER TABLE</code>, and have the same meaning when used for
+ materialized views. See the descriptions for
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>
+ for details.
+ </p></div><div class="refsect1" id="id-1.9.3.19.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing materialized view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ Name of a new or existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>extension_name</code></em></span></dt><dd><p>
+ The name of the extension that the materialized view is to depend on (or no longer
+ dependent on, if <code class="literal">NO</code> is specified). A materialized view
+ that's marked as dependent on an extension is automatically dropped when
+ the extension is dropped.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_column_name</code></em></span></dt><dd><p>
+ New name for an existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the materialized view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the materialized view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the materialized view.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.19.7"><h2>Examples</h2><p>
+ To rename the materialized view <code class="literal">foo</code> to
+ <code class="literal">bar</code>:
+</p><pre class="programlisting">
+ALTER MATERIALIZED VIEW foo RENAME TO bar;
+</pre></div><div class="refsect1" id="id-1.9.3.19.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER MATERIALIZED VIEW</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.19.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW"><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW"><span class="refentrytitle">DROP MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW"><span class="refentrytitle">REFRESH MATERIALIZED VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterlargeobject.html" title="ALTER LARGE OBJECT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alteroperator.html" title="ALTER OPERATOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER LARGE OBJECT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER OPERATOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alteropclass.html b/doc/src/sgml/html/sql-alteropclass.html
new file mode 100644
index 0000000..41f93e6
--- /dev/null
+++ b/doc/src/sgml/html/sql-alteropclass.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER OPERATOR CLASS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alteroperator.html" title="ALTER OPERATOR" /><link rel="next" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER OPERATOR CLASS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alteroperator.html" title="ALTER OPERATOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTEROPCLASS"><div class="titlepage"></div><a id="id-1.9.3.21.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER OPERATOR CLASS</span></h2><p>ALTER OPERATOR CLASS — change the definition of an operator class</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER OPERATOR CLASS <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+ALTER OPERATOR CLASS <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR CLASS <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.21.5"><h2>Description</h2><p>
+ <code class="command">ALTER OPERATOR CLASS</code> changes the definition of
+ an operator class.
+ </p><p>
+ You must own the operator class to use <code class="command">ALTER OPERATOR CLASS</code>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the operator class's schema. (These restrictions enforce that altering the
+ owner doesn't do anything you couldn't do by dropping and recreating the
+ operator class. However, a superuser can alter ownership of any operator
+ class anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.21.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing operator
+ class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_method</code></em></span></dt><dd><p>
+ The name of the index method this operator class is for.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the operator class.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.21.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER OPERATOR CLASS</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.21.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropopclass.html" title="DROP OPERATOR CLASS"><span class="refentrytitle">DROP OPERATOR CLASS</span></a>, <a class="xref" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY"><span class="refentrytitle">ALTER OPERATOR FAMILY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alteroperator.html" title="ALTER OPERATOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER OPERATOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER OPERATOR FAMILY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alteroperator.html b/doc/src/sgml/html/sql-alteroperator.html
new file mode 100644
index 0000000..886409c
--- /dev/null
+++ b/doc/src/sgml/html/sql-alteroperator.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER OPERATOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW" /><link rel="next" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER OPERATOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTEROPERATOR"><div class="titlepage"></div><a id="id-1.9.3.20.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER OPERATOR</span></h2><p>ALTER OPERATOR — change the definition of an operator</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER OPERATOR <em class="replaceable"><code>name</code></em> ( { <em class="replaceable"><code>left_type</code></em> | NONE } , <em class="replaceable"><code>right_type</code></em> )
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR <em class="replaceable"><code>name</code></em> ( { <em class="replaceable"><code>left_type</code></em> | NONE } , <em class="replaceable"><code>right_type</code></em> )
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+
+ALTER OPERATOR <em class="replaceable"><code>name</code></em> ( { <em class="replaceable"><code>left_type</code></em> | NONE } , <em class="replaceable"><code>right_type</code></em> )
+ SET ( { RESTRICT = { <em class="replaceable"><code>res_proc</code></em> | NONE }
+ | JOIN = { <em class="replaceable"><code>join_proc</code></em> | NONE }
+ } [, ... ] )
+</pre></div><div class="refsect1" id="id-1.9.3.20.5"><h2>Description</h2><p>
+ <code class="command">ALTER OPERATOR</code> changes the definition of
+ an operator.
+ </p><p>
+ You must own the operator to use <code class="command">ALTER OPERATOR</code>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the operator's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the operator.
+ However, a superuser can alter ownership of any operator anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.20.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>left_type</code></em></span></dt><dd><p>
+ The data type of the operator's left operand; write
+ <code class="literal">NONE</code> if the operator has no left operand.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>right_type</code></em></span></dt><dd><p>
+ The data type of the operator's right operand.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>res_proc</code></em></span></dt><dd><p>
+ The restriction selectivity estimator function for this operator; write NONE to remove existing selectivity estimator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>join_proc</code></em></span></dt><dd><p>
+ The join selectivity estimator function for this operator; write NONE to remove existing selectivity estimator.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.20.7"><h2>Examples</h2><p>
+ Change the owner of a custom operator <code class="literal">a @@ b</code> for type <code class="type">text</code>:
+</p><pre class="programlisting">
+ALTER OPERATOR @@ (text, text) OWNER TO joe;
+</pre><p>
+ Change the restriction and join selectivity estimator functions of a custom operator <code class="literal">a &amp;&amp; b</code> for type <code class="type">int[]</code>:
+</p><pre class="programlisting">
+ALTER OPERATOR &amp;&amp; (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel);
+</pre></div><div class="refsect1" id="id-1.9.3.20.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER OPERATOR</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.20.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createoperator.html" title="CREATE OPERATOR"><span class="refentrytitle">CREATE OPERATOR</span></a>, <a class="xref" href="sql-dropoperator.html" title="DROP OPERATOR"><span class="refentrytitle">DROP OPERATOR</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER MATERIALIZED VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER OPERATOR CLASS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alteropfamily.html b/doc/src/sgml/html/sql-alteropfamily.html
new file mode 100644
index 0000000..1eae682
--- /dev/null
+++ b/doc/src/sgml/html/sql-alteropfamily.html
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER OPERATOR FAMILY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS" /><link rel="next" href="sql-alterpolicy.html" title="ALTER POLICY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER OPERATOR FAMILY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterpolicy.html" title="ALTER POLICY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTEROPFAMILY"><div class="titlepage"></div><a id="id-1.9.3.22.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER OPERATOR FAMILY</span></h2><p>ALTER OPERATOR FAMILY — change the definition of an operator family</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER OPERATOR FAMILY <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em> ADD
+ { OPERATOR <em class="replaceable"><code>strategy_number</code></em> <em class="replaceable"><code>operator_name</code></em> ( <em class="replaceable"><code>op_type</code></em>, <em class="replaceable"><code>op_type</code></em> )
+ [ FOR SEARCH | FOR ORDER BY <em class="replaceable"><code>sort_family_name</code></em> ]
+ | FUNCTION <em class="replaceable"><code>support_number</code></em> [ ( <em class="replaceable"><code>op_type</code></em> [ , <em class="replaceable"><code>op_type</code></em> ] ) ]
+ <em class="replaceable"><code>function_name</code></em> [ ( <em class="replaceable"><code>argument_type</code></em> [, ...] ) ]
+ } [, ... ]
+
+ALTER OPERATOR FAMILY <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em> DROP
+ { OPERATOR <em class="replaceable"><code>strategy_number</code></em> ( <em class="replaceable"><code>op_type</code></em> [ , <em class="replaceable"><code>op_type</code></em> ] )
+ | FUNCTION <em class="replaceable"><code>support_number</code></em> ( <em class="replaceable"><code>op_type</code></em> [ , <em class="replaceable"><code>op_type</code></em> ] )
+ } [, ... ]
+
+ALTER OPERATOR FAMILY <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+ALTER OPERATOR FAMILY <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR FAMILY <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.22.5"><h2>Description</h2><p>
+ <code class="command">ALTER OPERATOR FAMILY</code> changes the definition of
+ an operator family. You can add operators and support functions
+ to the family, remove them from the family,
+ or change the family's name or owner.
+ </p><p>
+ When operators and support functions are added to a family with
+ <code class="command">ALTER OPERATOR FAMILY</code>, they are not part of any
+ specific operator class within the family, but are just <span class="quote">“<span class="quote">loose</span>”</span>
+ within the family. This indicates that these operators and functions
+ are compatible with the family's semantics, but are not required for
+ correct functioning of any specific index. (Operators and functions
+ that are so required should be declared as part of an operator class,
+ instead; see <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>.)
+ <span class="productname">PostgreSQL</span> will allow loose members of a
+ family to be dropped from the family at any time, but members of an
+ operator class cannot be dropped without dropping the whole class and
+ any indexes that depend on it.
+ Typically, single-data-type operators
+ and functions are part of operator classes because they are needed to
+ support an index on that specific data type, while cross-data-type
+ operators and functions are made loose members of the family.
+ </p><p>
+ You must be a superuser to use <code class="command">ALTER OPERATOR FAMILY</code>.
+ (This restriction is made because an erroneous operator family definition
+ could confuse or even crash the server.)
+ </p><p>
+ <code class="command">ALTER OPERATOR FAMILY</code> does not presently check
+ whether the operator family definition includes all the operators and
+ functions required by the index method, nor whether the operators and
+ functions form a self-consistent set. It is the user's
+ responsibility to define a valid operator family.
+ </p><p>
+ Refer to <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.22.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing operator
+ family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_method</code></em></span></dt><dd><p>
+ The name of the index method this operator family is for.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>strategy_number</code></em></span></dt><dd><p>
+ The index method's strategy number for an operator
+ associated with the operator family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>operator_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an operator associated
+ with the operator family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>op_type</code></em></span></dt><dd><p>
+ In an <code class="literal">OPERATOR</code> clause,
+ the operand data type(s) of the operator, or <code class="literal">NONE</code> to
+ signify a prefix operator. Unlike the comparable
+ syntax in <code class="command">CREATE OPERATOR CLASS</code>, the operand data types
+ must always be specified.
+ </p><p>
+ In an <code class="literal">ADD FUNCTION</code> clause, the operand data type(s) the
+ function is intended to support, if different from
+ the input data type(s) of the function. For B-tree comparison functions
+ and hash functions it is not necessary to specify <em class="replaceable"><code>op_type</code></em> since the function's input
+ data type(s) are always the correct ones to use. For B-tree sort
+ support functions, B-Tree equal image functions, and all
+ functions in GiST, SP-GiST and GIN operator classes, it is
+ necessary to specify the operand data type(s) the function is to
+ be used with.
+ </p><p>
+ In a <code class="literal">DROP FUNCTION</code> clause, the operand data type(s) the
+ function is intended to support must be specified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sort_family_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing <code class="literal">btree</code> operator
+ family that describes the sort ordering associated with an ordering
+ operator.
+ </p><p>
+ If neither <code class="literal">FOR SEARCH</code> nor <code class="literal">FOR ORDER BY</code> is
+ specified, <code class="literal">FOR SEARCH</code> is the default.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>support_number</code></em></span></dt><dd><p>
+ The index method's support function number for a
+ function associated with the operator family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a function that is an index
+ method support function for the operator family. If no argument list
+ is specified, the name must be unique in its schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argument_type</code></em></span></dt><dd><p>
+ The parameter data type(s) of the function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the operator family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the operator family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the operator family.
+ </p></dd></dl></div><p>
+ The <code class="literal">OPERATOR</code> and <code class="literal">FUNCTION</code>
+ clauses can appear in any order.
+ </p></div><div class="refsect1" id="id-1.9.3.22.7"><h2>Notes</h2><p>
+ Notice that the <code class="literal">DROP</code> syntax only specifies the <span class="quote">“<span class="quote">slot</span>”</span>
+ in the operator family, by strategy or support number and input data
+ type(s). The name of the operator or function occupying the slot is not
+ mentioned. Also, for <code class="literal">DROP FUNCTION</code> the type(s) to specify
+ are the input data type(s) the function is intended to support; for
+ GiST, SP-GiST and GIN indexes this might have nothing to do with the actual
+ input argument types of the function.
+ </p><p>
+ Because the index machinery does not check access permissions on functions
+ before using them, including a function or operator in an operator family
+ is tantamount to granting public execute permission on it. This is usually
+ not an issue for the sorts of functions that are useful in an operator
+ family.
+ </p><p>
+ The operators should not be defined by SQL functions. An SQL function
+ is likely to be inlined into the calling query, which will prevent
+ the optimizer from recognizing that the query matches an index.
+ </p><p>
+ Before <span class="productname">PostgreSQL</span> 8.4, the <code class="literal">OPERATOR</code>
+ clause could include a <code class="literal">RECHECK</code> option. This is no longer
+ supported because whether an index operator is <span class="quote">“<span class="quote">lossy</span>”</span> is now
+ determined on-the-fly at run time. This allows efficient handling of
+ cases where an operator might or might not be lossy.
+ </p></div><div class="refsect1" id="id-1.9.3.22.8"><h2>Examples</h2><p>
+ The following example command adds cross-data-type operators and
+ support functions to an operator family that already contains B-tree
+ operator classes for data types <code class="type">int4</code> and <code class="type">int2</code>.
+ </p><pre class="programlisting">
+ALTER OPERATOR FAMILY integer_ops USING btree ADD
+
+ -- int4 vs int2
+ OPERATOR 1 &lt; (int4, int2) ,
+ OPERATOR 2 &lt;= (int4, int2) ,
+ OPERATOR 3 = (int4, int2) ,
+ OPERATOR 4 &gt;= (int4, int2) ,
+ OPERATOR 5 &gt; (int4, int2) ,
+ FUNCTION 1 btint42cmp(int4, int2) ,
+
+ -- int2 vs int4
+ OPERATOR 1 &lt; (int2, int4) ,
+ OPERATOR 2 &lt;= (int2, int4) ,
+ OPERATOR 3 = (int2, int4) ,
+ OPERATOR 4 &gt;= (int2, int4) ,
+ OPERATOR 5 &gt; (int2, int4) ,
+ FUNCTION 1 btint24cmp(int2, int4) ;
+</pre><p>
+ To remove these entries again:
+ </p><pre class="programlisting">
+ALTER OPERATOR FAMILY integer_ops USING btree DROP
+
+ -- int4 vs int2
+ OPERATOR 1 (int4, int2) ,
+ OPERATOR 2 (int4, int2) ,
+ OPERATOR 3 (int4, int2) ,
+ OPERATOR 4 (int4, int2) ,
+ OPERATOR 5 (int4, int2) ,
+ FUNCTION 1 (int4, int2) ,
+
+ -- int2 vs int4
+ OPERATOR 1 (int2, int4) ,
+ OPERATOR 2 (int2, int4) ,
+ OPERATOR 3 (int2, int4) ,
+ OPERATOR 4 (int2, int4) ,
+ OPERATOR 5 (int2, int4) ,
+ FUNCTION 1 (int2, int4) ;
+</pre></div><div class="refsect1" id="id-1.9.3.22.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER OPERATOR FAMILY</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.22.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY"><span class="refentrytitle">CREATE OPERATOR FAMILY</span></a>, <a class="xref" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY"><span class="refentrytitle">DROP OPERATOR FAMILY</span></a>, <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS"><span class="refentrytitle">ALTER OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropopclass.html" title="DROP OPERATOR CLASS"><span class="refentrytitle">DROP OPERATOR CLASS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterpolicy.html" title="ALTER POLICY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER OPERATOR CLASS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER POLICY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterpolicy.html b/doc/src/sgml/html/sql-alterpolicy.html
new file mode 100644
index 0000000..163b779
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterpolicy.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER POLICY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY" /><link rel="next" href="sql-alterprocedure.html" title="ALTER PROCEDURE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER POLICY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterprocedure.html" title="ALTER PROCEDURE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERPOLICY"><div class="titlepage"></div><a id="id-1.9.3.23.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER POLICY</span></h2><p>ALTER POLICY — change the definition of a row-level security policy</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER POLICY <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+ALTER POLICY <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em>
+ [ TO { <em class="replaceable"><code>role_name</code></em> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
+ [ USING ( <em class="replaceable"><code>using_expression</code></em> ) ]
+ [ WITH CHECK ( <em class="replaceable"><code>check_expression</code></em> ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.23.5"><h2>Description</h2><p>
+ <code class="command">ALTER POLICY</code> changes the definition of an existing
+ row-level security policy. Note that <code class="command">ALTER POLICY</code>
+ only allows the set of roles to which the policy applies and the
+ <code class="literal">USING</code> and <code class="literal">WITH CHECK</code> expressions to
+ be modified. To change other properties of a policy, such as the command
+ to which it applies or whether it is permissive or restrictive, the policy
+ must be dropped and recreated.
+ </p><p>
+ To use <code class="command">ALTER POLICY</code>, you must own the table that
+ the policy applies to.
+ </p><p>
+ In the second form of <code class="command">ALTER POLICY</code>, the role list,
+ <em class="replaceable"><code>using_expression</code></em>, and
+ <em class="replaceable"><code>check_expression</code></em> are replaced
+ independently if specified. When one of those clauses is omitted, the
+ corresponding part of the policy is unchanged.
+ </p></div><div class="refsect1" id="id-1.9.3.23.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing policy to alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table that the
+ policy is on.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the policy.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The role(s) to which the policy applies. Multiple roles can be
+ specified at one time. To apply the policy to all roles,
+ use <code class="literal">PUBLIC</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>using_expression</code></em></span></dt><dd><p>
+ The <code class="literal">USING</code> expression for the policy.
+ See <a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a> for details.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>check_expression</code></em></span></dt><dd><p>
+ The <code class="literal">WITH CHECK</code> expression for the policy.
+ See <a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a> for details.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.23.7"><h2>Compatibility</h2><p>
+ <code class="command">ALTER POLICY</code> is a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.23.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a>, <a class="xref" href="sql-droppolicy.html" title="DROP POLICY"><span class="refentrytitle">DROP POLICY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterprocedure.html" title="ALTER PROCEDURE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER OPERATOR FAMILY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER PROCEDURE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterprocedure.html b/doc/src/sgml/html/sql-alterprocedure.html
new file mode 100644
index 0000000..6ae55e3
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterprocedure.html
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER PROCEDURE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterpolicy.html" title="ALTER POLICY" /><link rel="next" href="sql-alterpublication.html" title="ALTER PUBLICATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER PROCEDURE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterpolicy.html" title="ALTER POLICY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterpublication.html" title="ALTER PUBLICATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERPROCEDURE"><div class="titlepage"></div><a id="id-1.9.3.24.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER PROCEDURE</span></h2><p>ALTER PROCEDURE — change the definition of a procedure</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER PROCEDURE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ <em class="replaceable"><code>action</code></em> [ ... ] [ RESTRICT ]
+ALTER PROCEDURE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER PROCEDURE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER PROCEDURE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER PROCEDURE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | DEFAULT }
+ SET <em class="replaceable"><code>configuration_parameter</code></em> FROM CURRENT
+ RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ RESET ALL
+</pre></div><div class="refsect1" id="id-1.9.3.24.5"><h2>Description</h2><p>
+ <code class="command">ALTER PROCEDURE</code> changes the definition of a
+ procedure.
+ </p><p>
+ You must own the procedure to use <code class="command">ALTER PROCEDURE</code>.
+ To change a procedure's schema, you must also have <code class="literal">CREATE</code>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the procedure's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the procedure.
+ However, a superuser can alter ownership of any procedure anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.24.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing procedure. If no
+ argument list is specified, the name must be unique in its schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>. If omitted,
+ the default is <code class="literal">IN</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ Note that <code class="command">ALTER PROCEDURE</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are used to determine the procedure's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type(s) of the procedure's arguments (optionally
+ schema-qualified), if any.
+ See <a class="xref" href="sql-dropprocedure.html" title="DROP PROCEDURE"><span class="refentrytitle">DROP PROCEDURE</span></a> for the details of how
+ the procedure is looked up using the argument data type(s).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the procedure.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the procedure. Note that if the procedure is
+ marked <code class="literal">SECURITY DEFINER</code>, it will subsequently
+ execute as the new owner.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the procedure.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>extension_name</code></em></span></dt><dd><p>
+ This form marks the procedure as dependent on the extension, or no longer
+ dependent on the extension if <code class="literal">NO</code> is specified.
+ A procedure that's marked as dependent on an extension is dropped when the
+ extension is dropped, even if cascade is not specified.
+ A procedure can depend upon multiple extensions, and will be dropped when
+ any one of those extensions is dropped.
+ </p></dd><dt><span class="term"><code class="literal">[<span class="optional"> EXTERNAL </span>] SECURITY INVOKER</code><br /></span><span class="term"><code class="literal">[<span class="optional"> EXTERNAL </span>] SECURITY DEFINER</code></span></dt><dd><p>
+ Change whether the procedure is a security definer or not. The
+ key word <code class="literal">EXTERNAL</code> is ignored for SQL
+ conformance. See <a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a> for more information about
+ this capability.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em><br /></span><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ Add or change the assignment to be made to a configuration parameter
+ when the procedure is called. If
+ <em class="replaceable"><code>value</code></em> is <code class="literal">DEFAULT</code>
+ or, equivalently, <code class="literal">RESET</code> is used, the procedure-local
+ setting is removed, so that the procedure executes with the value
+ present in its environment. Use <code class="literal">RESET
+ ALL</code> to clear all procedure-local settings.
+ <code class="literal">SET FROM CURRENT</code> saves the value of the parameter that
+ is current when <code class="command">ALTER PROCEDURE</code> is executed as the value
+ to be applied when the procedure is entered.
+ </p><p>
+ See <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> and
+ <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ for more information about allowed parameter names and values.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Ignored for conformance with the SQL standard.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.24.7"><h2>Examples</h2><p>
+ To rename the procedure <code class="literal">insert_data</code> with two arguments
+ of type <code class="type">integer</code> to <code class="literal">insert_record</code>:
+</p><pre class="programlisting">
+ALTER PROCEDURE insert_data(integer, integer) RENAME TO insert_record;
+</pre><p>
+ </p><p>
+ To change the owner of the procedure <code class="literal">insert_data</code> with
+ two arguments of type <code class="type">integer</code> to <code class="literal">joe</code>:
+</p><pre class="programlisting">
+ALTER PROCEDURE insert_data(integer, integer) OWNER TO joe;
+</pre><p>
+ </p><p>
+ To change the schema of the procedure <code class="literal">insert_data</code> with
+ two arguments of type <code class="type">integer</code>
+ to <code class="literal">accounting</code>:
+</p><pre class="programlisting">
+ALTER PROCEDURE insert_data(integer, integer) SET SCHEMA accounting;
+</pre><p>
+ </p><p>
+ To mark the procedure <code class="literal">insert_data(integer, integer)</code> as
+ being dependent on the extension <code class="literal">myext</code>:
+</p><pre class="programlisting">
+ALTER PROCEDURE insert_data(integer, integer) DEPENDS ON EXTENSION myext;
+</pre><p>
+ </p><p>
+ To adjust the search path that is automatically set for a procedure:
+</p><pre class="programlisting">
+ALTER PROCEDURE check_password(text) SET search_path = admin, pg_temp;
+</pre><p>
+ </p><p>
+ To disable automatic setting of <code class="varname">search_path</code> for a procedure:
+</p><pre class="programlisting">
+ALTER PROCEDURE check_password(text) RESET search_path;
+</pre><p>
+ The procedure will now execute with whatever search path is used by its
+ caller.
+ </p></div><div class="refsect1" id="id-1.9.3.24.8"><h2>Compatibility</h2><p>
+ This statement is partially compatible with the <code class="command">ALTER
+ PROCEDURE</code> statement in the SQL standard. The standard allows more
+ properties of a procedure to be modified, but does not provide the
+ ability to rename a procedure, make a procedure a security definer,
+ attach configuration parameter values to a procedure,
+ or change the owner, schema, or volatility of a procedure. The standard also
+ requires the <code class="literal">RESTRICT</code> key word, which is optional in
+ <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect1" id="id-1.9.3.24.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a>, <a class="xref" href="sql-dropprocedure.html" title="DROP PROCEDURE"><span class="refentrytitle">DROP PROCEDURE</span></a>, <a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>, <a class="xref" href="sql-alterroutine.html" title="ALTER ROUTINE"><span class="refentrytitle">ALTER ROUTINE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterpolicy.html" title="ALTER POLICY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterpublication.html" title="ALTER PUBLICATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER POLICY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER PUBLICATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterpublication.html b/doc/src/sgml/html/sql-alterpublication.html
new file mode 100644
index 0000000..94a155a
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterpublication.html
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER PUBLICATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterprocedure.html" title="ALTER PROCEDURE" /><link rel="next" href="sql-alterrole.html" title="ALTER ROLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER PUBLICATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterprocedure.html" title="ALTER PROCEDURE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterrole.html" title="ALTER ROLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERPUBLICATION"><div class="titlepage"></div><a id="id-1.9.3.25.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER PUBLICATION</span></h2><p>ALTER PUBLICATION — change the definition of a publication</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER PUBLICATION <em class="replaceable"><code>name</code></em> ADD <em class="replaceable"><code>publication_object</code></em> [, ...]
+ALTER PUBLICATION <em class="replaceable"><code>name</code></em> SET <em class="replaceable"><code>publication_object</code></em> [, ...]
+ALTER PUBLICATION <em class="replaceable"><code>name</code></em> DROP <em class="replaceable"><code>publication_object</code></em> [, ...]
+ALTER PUBLICATION <em class="replaceable"><code>name</code></em> SET ( <em class="replaceable"><code>publication_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )
+ALTER PUBLICATION <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER PUBLICATION <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>publication_object</code></em> is one of:</span>
+
+ TABLE [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ * ] [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ] [ WHERE ( <em class="replaceable"><code>expression</code></em> ) ] [, ... ]
+ TABLES IN SCHEMA { <em class="replaceable"><code>schema_name</code></em> | CURRENT_SCHEMA } [, ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.25.5"><h2>Description</h2><p>
+ The command <code class="command">ALTER PUBLICATION</code> can change the attributes
+ of a publication.
+ </p><p>
+ The first three variants change which tables/schemas are part of the
+ publication. The <code class="literal">SET</code> clause will replace the list of
+ tables/schemas in the publication with the specified list; the existing
+ tables/schemas that were present in the publication will be removed. The
+ <code class="literal">ADD</code> and <code class="literal">DROP</code> clauses will add and
+ remove one or more tables/schemas from the publication. Note that adding
+ tables/schemas to a publication that is already subscribed to will require an
+ <code class="literal">ALTER SUBSCRIPTION ... REFRESH PUBLICATION</code> action on the
+ subscribing side in order to become effective. Note also that
+ <code class="literal">DROP TABLES IN SCHEMA</code> will not drop any schema tables
+ that were specified using <code class="literal">FOR TABLE</code>/
+ <code class="literal">ADD TABLE</code>, and the combination of <code class="literal">DROP</code>
+ with a <code class="literal">WHERE</code> clause is not allowed.
+ </p><p>
+ The fourth variant of this command listed in the synopsis can change
+ all of the publication properties specified in
+ <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a>. Properties not mentioned in the
+ command retain their previous settings.
+ </p><p>
+ The remaining variants change the owner and the name of the publication.
+ </p><p>
+ You must own the publication to use <code class="command">ALTER PUBLICATION</code>.
+ Adding a table to a publication additionally requires owning that table.
+ The <code class="literal">ADD TABLES IN SCHEMA</code> and
+ <code class="literal">SET TABLES IN SCHEMA</code> to a publication requires the
+ invoking user to be a superuser. To alter the owner, you must also be a
+ direct or indirect member of the new owning role. The new owner must have
+ <code class="literal">CREATE</code> privilege on the database. Also, the new owner
+ of a <code class="literal">FOR ALL TABLES</code> or <code class="literal">FOR TABLES IN SCHEMA</code>
+ publication must be a superuser. However, a superuser can
+ change the ownership of a publication regardless of these restrictions.
+ </p><p>
+ Adding/Setting any schema when the publication also publishes a table with a
+ column list, and vice versa is not supported.
+ </p></div><div class="refsect1" id="id-1.9.3.25.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing publication whose definition is to be altered.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ Name of an existing table. If <code class="literal">ONLY</code> is specified before the
+ table name, only that table is affected. If <code class="literal">ONLY</code> is not
+ specified, the table and all its descendant tables (if any) are
+ affected. Optionally, <code class="literal">*</code> can be specified after the table
+ name to explicitly indicate that descendant tables are included.
+ </p><p>
+ Optionally, a column list can be specified. See <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a> for details. Note that a subscription
+ having several publications in which the same table has been published
+ with different column lists is not supported. See
+ <a class="xref" href="logical-replication-col-lists.html#LOGICAL-REPLICATION-COL-LIST-COMBINING" title="Warning: Combining Column Lists from Multiple Publications">Warning: Combining Column Lists from Multiple Publications</a> for details of
+ potential problems when altering column lists.
+ </p><p>
+ If the optional <code class="literal">WHERE</code> clause is specified, rows for
+ which the <em class="replaceable"><code>expression</code></em>
+ evaluates to false or null will not be published. Note that parentheses
+ are required around the expression. The
+ <em class="replaceable"><code>expression</code></em> is evaluated with
+ the role used for the replication connection.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>schema_name</code></em></span></dt><dd><p>
+ Name of an existing schema.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>publication_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause alters publication parameters originally set by
+ <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a>. See there for more information.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the publication.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the publication.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.25.7"><h2>Examples</h2><p>
+ Change the publication to publish only deletes and updates:
+</p><pre class="programlisting">
+ALTER PUBLICATION noinsert SET (publish = 'update, delete');
+</pre><p>
+ </p><p>
+ Add some tables to the publication:
+</p><pre class="programlisting">
+ALTER PUBLICATION mypublication ADD TABLE users (user_id, firstname), departments;
+</pre><p>
+ Change the set of columns published for a table:
+</p><pre class="programlisting">
+ALTER PUBLICATION mypublication SET TABLE users (user_id, firstname, lastname), TABLE departments;
+</pre><p>
+ Add schemas <code class="structname">marketing</code> and
+ <code class="structname">sales</code> to the publication
+ <code class="structname">sales_publication</code>:
+</p><pre class="programlisting">
+ALTER PUBLICATION sales_publication ADD TABLES IN SCHEMA marketing, sales;
+</pre><p>
+ </p><p>
+ Add tables <code class="structname">users</code>,
+ <code class="structname">departments</code> and schema
+ <code class="structname">production</code> to the publication
+ <code class="structname">production_publication</code>:
+</p><pre class="programlisting">
+ALTER PUBLICATION production_publication ADD TABLE users, departments, TABLES IN SCHEMA production;
+</pre></div><div class="refsect1" id="id-1.9.3.25.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER PUBLICATION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.25.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a>, <a class="xref" href="sql-droppublication.html" title="DROP PUBLICATION"><span class="refentrytitle">DROP PUBLICATION</span></a>, <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>, <a class="xref" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><span class="refentrytitle">ALTER SUBSCRIPTION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterprocedure.html" title="ALTER PROCEDURE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterrole.html" title="ALTER ROLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER PROCEDURE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER ROLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterrole.html b/doc/src/sgml/html/sql-alterrole.html
new file mode 100644
index 0000000..3da698a
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterrole.html
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER ROLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterpublication.html" title="ALTER PUBLICATION" /><link rel="next" href="sql-alterroutine.html" title="ALTER ROUTINE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER ROLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterpublication.html" title="ALTER PUBLICATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterroutine.html" title="ALTER ROUTINE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERROLE"><div class="titlepage"></div><a id="id-1.9.3.26.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER ROLE</span></h2><p>ALTER ROLE — change a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER ROLE <em class="replaceable"><code>role_specification</code></em> [ WITH ] <em class="replaceable"><code>option</code></em> [ ... ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <em class="replaceable"><code>connlimit</code></em>
+ | [ ENCRYPTED ] PASSWORD '<em class="replaceable"><code>password</code></em>' | PASSWORD NULL
+ | VALID UNTIL '<em class="replaceable"><code>timestamp</code></em>'
+
+ALTER ROLE <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+ALTER ROLE { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | DEFAULT }
+ALTER ROLE { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] SET <em class="replaceable"><code>configuration_parameter</code></em> FROM CURRENT
+ALTER ROLE { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ALTER ROLE { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] RESET ALL
+
+<span class="phrase">where <em class="replaceable"><code>role_specification</code></em> can be:</span>
+
+ <em class="replaceable"><code>role_name</code></em>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</pre></div><div class="refsect1" id="id-1.9.3.26.5"><h2>Description</h2><p>
+ <code class="command">ALTER ROLE</code> changes the attributes of a
+ <span class="productname">PostgreSQL</span> role.
+ </p><p>
+ The first variant of this command listed in the synopsis can change
+ many of the role attributes that can be specified in
+ <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="command">CREATE ROLE</code></a>.
+ (All the possible attributes are covered,
+ except that there are no options for adding or removing memberships; use
+ <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> and
+ <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a> for that.)
+ Attributes not mentioned in the command retain their previous settings.
+ Database superusers can change any of these settings for any role.
+ Roles having <code class="literal">CREATEROLE</code> privilege can change any of these
+ settings except <code class="literal">SUPERUSER</code>, <code class="literal">REPLICATION</code>,
+ and <code class="literal">BYPASSRLS</code>; but only for non-superuser and
+ non-replication roles.
+ Ordinary roles can only change their own password.
+ </p><p>
+ The second variant changes the name of the role.
+ Database superusers can rename any role.
+ Roles having <code class="literal">CREATEROLE</code> privilege can rename non-superuser
+ roles.
+ The current session user cannot be renamed.
+ (Connect as a different user if you need to do that.)
+ Because <code class="literal">MD5</code>-encrypted passwords use the role name as
+ cryptographic salt, renaming a role clears its password if the
+ password is <code class="literal">MD5</code>-encrypted.
+ </p><p>
+ The remaining variants change a role's session default for a configuration
+ variable, either for all databases or, when the <code class="literal">IN
+ DATABASE</code> clause is specified, only for sessions in the named
+ database. If <code class="literal">ALL</code> is specified instead of a role name,
+ this changes the setting for all roles. Using <code class="literal">ALL</code>
+ with <code class="literal">IN DATABASE</code> is effectively the same as using the
+ command <code class="literal">ALTER DATABASE ... SET ...</code>.
+ </p><p>
+ Whenever the role subsequently
+ starts a new session, the specified value becomes the session
+ default, overriding whatever setting is present in
+ <code class="filename">postgresql.conf</code> or has been received from the <code class="command">postgres</code>
+ command line. This only happens at login time; executing
+ <a class="link" href="sql-set-role.html" title="SET ROLE"><code class="command">SET ROLE</code></a> or
+ <a class="link" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION"><code class="command">SET SESSION AUTHORIZATION</code></a> does not cause new
+ configuration values to be set.
+ Settings set for all databases are overridden by database-specific settings
+ attached to a role. Settings for specific databases or specific roles override
+ settings for all roles.
+ </p><p>
+ Superusers can change anyone's session defaults. Roles having
+ <code class="literal">CREATEROLE</code> privilege can change defaults for non-superuser
+ roles. Ordinary roles can only set defaults for themselves.
+ Certain configuration variables cannot be set this way, or can only be
+ set if a superuser issues the command. Only superusers can change a setting
+ for all roles in all databases.
+ </p></div><div class="refsect1" id="id-1.9.3.26.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the role whose attributes are to be altered.
+ </p></dd><dt><span class="term"><code class="literal">CURRENT_ROLE</code><br /></span><span class="term"><code class="literal">CURRENT_USER</code></span></dt><dd><p>
+ Alter the current user instead of an explicitly identified role.
+ </p></dd><dt><span class="term"><code class="literal">SESSION_USER</code></span></dt><dd><p>
+ Alter the current session user instead of an explicitly identified
+ role.
+ </p></dd><dt><span class="term"><code class="literal">SUPERUSER</code><br /></span><span class="term"><code class="literal">NOSUPERUSER</code><br /></span><span class="term"><code class="literal">CREATEDB</code><br /></span><span class="term"><code class="literal">NOCREATEDB</code><br /></span><span class="term"><code class="literal">CREATEROLE</code><br /></span><span class="term"><code class="literal">NOCREATEROLE</code><br /></span><span class="term"><code class="literal">INHERIT</code><br /></span><span class="term"><code class="literal">NOINHERIT</code><br /></span><span class="term"><code class="literal">LOGIN</code><br /></span><span class="term"><code class="literal">NOLOGIN</code><br /></span><span class="term"><code class="literal">REPLICATION</code><br /></span><span class="term"><code class="literal">NOREPLICATION</code><br /></span><span class="term"><code class="literal">BYPASSRLS</code><br /></span><span class="term"><code class="literal">NOBYPASSRLS</code><br /></span><span class="term"><code class="literal">CONNECTION LIMIT</code> <em class="replaceable"><code>connlimit</code></em><br /></span><span class="term">[ <code class="literal">ENCRYPTED</code> ] <code class="literal">PASSWORD</code> '<em class="replaceable"><code>password</code></em>'<br /></span><span class="term"><code class="literal">PASSWORD NULL</code><br /></span><span class="term"><code class="literal">VALID UNTIL</code> '<em class="replaceable"><code>timestamp</code></em>'</span></dt><dd><p>
+ These clauses alter attributes originally set by
+ <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="command">CREATE ROLE</code></a>. For more information, see the
+ <code class="command">CREATE ROLE</code> reference page.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the role.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>database_name</code></em></span></dt><dd><p>
+ The name of the database the configuration variable should be set in.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em><br /></span><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ Set this role's session default for the specified configuration
+ parameter to the given value. If
+ <em class="replaceable"><code>value</code></em> is <code class="literal">DEFAULT</code>
+ or, equivalently, <code class="literal">RESET</code> is used, the
+ role-specific variable setting is removed, so the role will
+ inherit the system-wide default setting in new sessions. Use
+ <code class="literal">RESET ALL</code> to clear all role-specific settings.
+ <code class="literal">SET FROM CURRENT</code> saves the session's current value of
+ the parameter as the role-specific value.
+ If <code class="literal">IN DATABASE</code> is specified, the configuration
+ parameter is set or removed for the given role and database only.
+ </p><p>
+ Role-specific variable settings take effect only at login;
+ <a class="link" href="sql-set-role.html" title="SET ROLE"><code class="command">SET ROLE</code></a> and
+ <a class="link" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION"><code class="command">SET SESSION AUTHORIZATION</code></a>
+ do not process role-specific variable settings.
+ </p><p>
+ See <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> and <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for more information about allowed
+ parameter names and values.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.26.7"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="command">CREATE ROLE</code></a>
+ to add new roles, and <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a> to remove a role.
+ </p><p>
+ <code class="command">ALTER ROLE</code> cannot change a role's memberships.
+ Use <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> and
+ <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a>
+ to do that.
+ </p><p>
+ Caution must be exercised when specifying an unencrypted password
+ with this command. The password will be transmitted to the server
+ in cleartext, and it might also be logged in the client's command
+ history or the server log. <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>
+ contains a command
+ <code class="command">\password</code> that can be used to change a
+ role's password without exposing the cleartext password.
+ </p><p>
+ It is also possible to tie a
+ session default to a specific database rather than to a role; see
+ <a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a>.
+ If there is a conflict, database-role-specific settings override role-specific
+ ones, which in turn override database-specific ones.
+ </p></div><div class="refsect1" id="id-1.9.3.26.8"><h2>Examples</h2><p>
+ Change a role's password:
+
+</p><pre class="programlisting">
+ALTER ROLE davide WITH PASSWORD 'hu8jmn3';
+</pre><p>
+ </p><p>
+ Remove a role's password:
+
+</p><pre class="programlisting">
+ALTER ROLE davide WITH PASSWORD NULL;
+</pre><p>
+ </p><p>
+ Change a password expiration date, specifying that the password
+ should expire at midday on 4th May 2015 using
+ the time zone which is one hour ahead of <acronym class="acronym">UTC</acronym>:
+</p><pre class="programlisting">
+ALTER ROLE chris VALID UNTIL 'May 4 12:00:00 2015 +1';
+</pre><p>
+ </p><p>
+ Make a password valid forever:
+</p><pre class="programlisting">
+ALTER ROLE fred VALID UNTIL 'infinity';
+</pre><p>
+ </p><p>
+ Give a role the ability to manage other roles and create new databases:
+
+</p><pre class="programlisting">
+ALTER ROLE miriam CREATEROLE CREATEDB;
+</pre><p>
+ </p><p>
+ Give a role a non-default setting of the
+ <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a> parameter:
+
+</p><pre class="programlisting">
+ALTER ROLE worker_bee SET maintenance_work_mem = 100000;
+</pre><p>
+ </p><p>
+ Give a role a non-default, database-specific setting of the
+ <a class="xref" href="runtime-config-client.html#GUC-CLIENT-MIN-MESSAGES">client_min_messages</a> parameter:
+
+</p><pre class="programlisting">
+ALTER ROLE fred IN DATABASE devel SET client_min_messages = DEBUG;
+</pre></div><div class="refsect1" id="id-1.9.3.26.9"><h2>Compatibility</h2><p>
+ The <code class="command">ALTER ROLE</code> statement is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.26.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>, <a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a>, <a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a>, <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterpublication.html" title="ALTER PUBLICATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterroutine.html" title="ALTER ROUTINE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER PUBLICATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER ROUTINE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterroutine.html b/doc/src/sgml/html/sql-alterroutine.html
new file mode 100644
index 0000000..1522ec3
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterroutine.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER ROUTINE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterrole.html" title="ALTER ROLE" /><link rel="next" href="sql-alterrule.html" title="ALTER RULE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER ROUTINE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterrole.html" title="ALTER ROLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterrule.html" title="ALTER RULE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERROUTINE"><div class="titlepage"></div><a id="id-1.9.3.27.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER ROUTINE</span></h2><p>ALTER ROUTINE — change the definition of a routine</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER ROUTINE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ <em class="replaceable"><code>action</code></em> [ ... ] [ RESTRICT ]
+ALTER ROUTINE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER ROUTINE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER ROUTINE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER ROUTINE <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ IMMUTABLE | STABLE | VOLATILE
+ [ NOT ] LEAKPROOF
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ COST <em class="replaceable"><code>execution_cost</code></em>
+ ROWS <em class="replaceable"><code>result_rows</code></em>
+ SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | DEFAULT }
+ SET <em class="replaceable"><code>configuration_parameter</code></em> FROM CURRENT
+ RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ RESET ALL
+</pre></div><div class="refsect1" id="id-1.9.3.27.5"><h2>Description</h2><p>
+ <code class="command">ALTER ROUTINE</code> changes the definition of a routine, which
+ can be an aggregate function, a normal function, or a procedure. See
+ under <a class="xref" href="sql-alteraggregate.html" title="ALTER AGGREGATE"><span class="refentrytitle">ALTER AGGREGATE</span></a>, <a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>,
+ and <a class="xref" href="sql-alterprocedure.html" title="ALTER PROCEDURE"><span class="refentrytitle">ALTER PROCEDURE</span></a> for the description of the
+ parameters, more examples, and further details.
+ </p></div><div class="refsect1" id="id-1.9.3.27.6"><h2>Examples</h2><p>
+ To rename the routine <code class="literal">foo</code> for type
+ <code class="type">integer</code> to <code class="literal">foobar</code>:
+</p><pre class="programlisting">
+ALTER ROUTINE foo(integer) RENAME TO foobar;
+</pre><p>
+ This command will work independent of whether <code class="literal">foo</code> is an
+ aggregate, function, or procedure.
+ </p></div><div class="refsect1" id="id-1.9.3.27.7"><h2>Compatibility</h2><p>
+ This statement is partially compatible with the <code class="command">ALTER
+ ROUTINE</code> statement in the SQL standard. See
+ under <a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>
+ and <a class="xref" href="sql-alterprocedure.html" title="ALTER PROCEDURE"><span class="refentrytitle">ALTER PROCEDURE</span></a> for more details. Allowing
+ routine names to refer to aggregate functions is
+ a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.27.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteraggregate.html" title="ALTER AGGREGATE"><span class="refentrytitle">ALTER AGGREGATE</span></a>, <a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>, <a class="xref" href="sql-alterprocedure.html" title="ALTER PROCEDURE"><span class="refentrytitle">ALTER PROCEDURE</span></a>, <a class="xref" href="sql-droproutine.html" title="DROP ROUTINE"><span class="refentrytitle">DROP ROUTINE</span></a></span><p>
+ Note that there is no <code class="literal">CREATE ROUTINE</code> command.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterrole.html" title="ALTER ROLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterrule.html" title="ALTER RULE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER ROLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER RULE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterrule.html b/doc/src/sgml/html/sql-alterrule.html
new file mode 100644
index 0000000..ed5cd01
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterrule.html
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER RULE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterroutine.html" title="ALTER ROUTINE" /><link rel="next" href="sql-alterschema.html" title="ALTER SCHEMA" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER RULE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterroutine.html" title="ALTER ROUTINE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterschema.html" title="ALTER SCHEMA">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERRULE"><div class="titlepage"></div><a id="id-1.9.3.28.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER RULE</span></h2><p>ALTER RULE — change the definition of a rule</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER RULE <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.28.5"><h2>Description</h2><p>
+ <code class="command">ALTER RULE</code> changes properties of an existing
+ rule. Currently, the only available action is to change the rule's name.
+ </p><p>
+ To use <code class="command">ALTER RULE</code>, you must own the table or view that
+ the rule applies to.
+ </p></div><div class="refsect1" id="id-1.9.3.28.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing rule to alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table or view that the
+ rule applies to.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the rule.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.28.7"><h2>Examples</h2><p>
+ To rename an existing rule:
+</p><pre class="programlisting">
+ALTER RULE notify_all ON emp RENAME TO notify_me;
+</pre></div><div class="refsect1" id="id-1.9.3.28.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER RULE</code> is a
+ <span class="productname">PostgreSQL</span> language extension, as is the
+ entire query rewrite system.
+ </p></div><div class="refsect1" id="id-1.9.3.28.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createrule.html" title="CREATE RULE"><span class="refentrytitle">CREATE RULE</span></a>, <a class="xref" href="sql-droprule.html" title="DROP RULE"><span class="refentrytitle">DROP RULE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterroutine.html" title="ALTER ROUTINE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterschema.html" title="ALTER SCHEMA">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER ROUTINE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER SCHEMA</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterschema.html b/doc/src/sgml/html/sql-alterschema.html
new file mode 100644
index 0000000..4eb78f8
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterschema.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER SCHEMA</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterrule.html" title="ALTER RULE" /><link rel="next" href="sql-altersequence.html" title="ALTER SEQUENCE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER SCHEMA</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterrule.html" title="ALTER RULE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altersequence.html" title="ALTER SEQUENCE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERSCHEMA"><div class="titlepage"></div><a id="id-1.9.3.29.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER SCHEMA</span></h2><p>ALTER SCHEMA — change the definition of a schema</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER SCHEMA <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER SCHEMA <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</pre></div><div class="refsect1" id="id-1.9.3.29.5"><h2>Description</h2><p>
+ <code class="command">ALTER SCHEMA</code> changes the definition of a schema.
+ </p><p>
+ You must own the schema to use <code class="command">ALTER SCHEMA</code>.
+ To rename a schema you must also have the
+ <code class="literal">CREATE</code> privilege for the database.
+ To alter the owner, you must also be a direct or
+ indirect member of the new owning role, and you must have the
+ <code class="literal">CREATE</code> privilege for the database.
+ (Note that superusers have all these privileges automatically.)
+ </p></div><div class="refsect1" id="id-1.9.3.29.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the schema. The new name cannot
+ begin with <code class="literal">pg_</code>, as such names
+ are reserved for system schemas.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the schema.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.29.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER SCHEMA</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.29.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createschema.html" title="CREATE SCHEMA"><span class="refentrytitle">CREATE SCHEMA</span></a>, <a class="xref" href="sql-dropschema.html" title="DROP SCHEMA"><span class="refentrytitle">DROP SCHEMA</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterrule.html" title="ALTER RULE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altersequence.html" title="ALTER SEQUENCE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER RULE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER SEQUENCE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altersequence.html b/doc/src/sgml/html/sql-altersequence.html
new file mode 100644
index 0000000..21a4ac3
--- /dev/null
+++ b/doc/src/sgml/html/sql-altersequence.html
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER SEQUENCE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterschema.html" title="ALTER SCHEMA" /><link rel="next" href="sql-alterserver.html" title="ALTER SERVER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER SEQUENCE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterschema.html" title="ALTER SCHEMA">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterserver.html" title="ALTER SERVER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERSEQUENCE"><div class="titlepage"></div><a id="id-1.9.3.30.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER SEQUENCE</span></h2><p>ALTER SEQUENCE —
+ change the definition of a sequence generator
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER SEQUENCE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ [ AS <em class="replaceable"><code>data_type</code></em> ]
+ [ INCREMENT [ BY ] <em class="replaceable"><code>increment</code></em> ]
+ [ MINVALUE <em class="replaceable"><code>minvalue</code></em> | NO MINVALUE ] [ MAXVALUE <em class="replaceable"><code>maxvalue</code></em> | NO MAXVALUE ]
+ [ START [ WITH ] <em class="replaceable"><code>start</code></em> ]
+ [ RESTART [ [ WITH ] <em class="replaceable"><code>restart</code></em> ] ]
+ [ CACHE <em class="replaceable"><code>cache</code></em> ] [ [ NO ] CYCLE ]
+ [ OWNED BY { <em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em> | NONE } ]
+ALTER SEQUENCE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> SET { LOGGED | UNLOGGED }
+ALTER SEQUENCE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SEQUENCE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER SEQUENCE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.30.5"><h2>Description</h2><p>
+ <code class="command">ALTER SEQUENCE</code> changes the parameters of an existing
+ sequence generator. Any parameters not specifically set in the
+ <code class="command">ALTER SEQUENCE</code> command retain their prior settings.
+ </p><p>
+ You must own the sequence to use <code class="command">ALTER SEQUENCE</code>.
+ To change a sequence's schema, you must also have <code class="literal">CREATE</code>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the sequence's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the sequence.
+ However, a superuser can alter ownership of any sequence anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.30.6"><h2>Parameters</h2><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a sequence to be altered.
+ </p></dd><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the sequence does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The optional
+ clause <code class="literal">AS <em class="replaceable"><code>data_type</code></em></code>
+ changes the data type of the sequence. Valid types are
+ <code class="literal">smallint</code>, <code class="literal">integer</code>,
+ and <code class="literal">bigint</code>.
+ </p><p>
+ Changing the data type automatically changes the minimum and maximum
+ values of the sequence if and only if the previous minimum and maximum
+ values were the minimum or maximum value of the old data type (in
+ other words, if the sequence had been created using <code class="literal">NO
+ MINVALUE</code> or <code class="literal">NO MAXVALUE</code>, implicitly or
+ explicitly). Otherwise, the minimum and maximum values are preserved,
+ unless new values are given as part of the same command. If the
+ minimum and maximum values do not fit into the new data type, an error
+ will be generated.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>increment</code></em></span></dt><dd><p>
+ The clause <code class="literal">INCREMENT BY <em class="replaceable"><code>increment</code></em></code> is
+ optional. A positive value will make an ascending sequence, a
+ negative one a descending sequence. If unspecified, the old
+ increment value will be maintained.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>minvalue</code></em><br /></span><span class="term"><code class="literal">NO MINVALUE</code></span></dt><dd><p>
+ The optional clause <code class="literal">MINVALUE <em class="replaceable"><code>minvalue</code></em></code> determines
+ the minimum value a sequence can generate. If <code class="literal">NO
+ MINVALUE</code> is specified, the defaults of 1 and
+ the minimum value of the data type for ascending and descending sequences,
+ respectively, will be used. If neither option is specified,
+ the current minimum value will be maintained.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>maxvalue</code></em><br /></span><span class="term"><code class="literal">NO MAXVALUE</code></span></dt><dd><p>
+ The optional clause <code class="literal">MAXVALUE <em class="replaceable"><code>maxvalue</code></em></code> determines
+ the maximum value for the sequence. If <code class="literal">NO
+ MAXVALUE</code> is specified, the defaults of
+ the maximum value of the data type and -1 for ascending and descending
+ sequences, respectively, will be used. If neither option is
+ specified, the current maximum value will be maintained.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>start</code></em></span></dt><dd><p>
+ The optional clause <code class="literal">START WITH <em class="replaceable"><code>start</code></em></code> changes the
+ recorded start value of the sequence. This has no effect on the
+ <span class="emphasis"><em>current</em></span> sequence value; it simply sets the value
+ that future <code class="command">ALTER SEQUENCE RESTART</code> commands will use.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>restart</code></em></span></dt><dd><p>
+ The optional clause <code class="literal">RESTART [ WITH <em class="replaceable"><code>restart</code></em> ]</code> changes the
+ current value of the sequence. This is similar to calling the
+ <code class="function">setval</code> function with <code class="literal">is_called</code> =
+ <code class="literal">false</code>: the specified value will be returned by the
+ <span class="emphasis"><em>next</em></span> call of <code class="function">nextval</code>.
+ Writing <code class="literal">RESTART</code> with no <em class="replaceable"><code>restart</code></em> value is equivalent to supplying
+ the start value that was recorded by <code class="command">CREATE SEQUENCE</code>
+ or last set by <code class="command">ALTER SEQUENCE START WITH</code>.
+ </p><p>
+ In contrast to a <code class="function">setval</code> call,
+ a <code class="literal">RESTART</code> operation on a sequence is transactional
+ and blocks concurrent transactions from obtaining numbers from the
+ same sequence. If that's not the desired mode of
+ operation, <code class="function">setval</code> should be used.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>cache</code></em></span></dt><dd><p>
+ The clause <code class="literal">CACHE <em class="replaceable"><code>cache</code></em></code> enables
+ sequence numbers to be preallocated and stored in memory for
+ faster access. The minimum value is 1 (only one value can be
+ generated at a time, i.e., no cache). If unspecified, the old
+ cache value will be maintained.
+ </p></dd><dt><span class="term"><code class="literal">CYCLE</code></span></dt><dd><p>
+ The optional <code class="literal">CYCLE</code> key word can be used to enable
+ the sequence to wrap around when the
+ <em class="replaceable"><code>maxvalue</code></em> or
+ <em class="replaceable"><code>minvalue</code></em> has been
+ reached by
+ an ascending or descending sequence respectively. If the limit is
+ reached, the next number generated will be the
+ <em class="replaceable"><code>minvalue</code></em> or
+ <em class="replaceable"><code>maxvalue</code></em>,
+ respectively.
+ </p></dd><dt><span class="term"><code class="literal">NO CYCLE</code></span></dt><dd><p>
+ If the optional <code class="literal">NO CYCLE</code> key word is
+ specified, any calls to <code class="function">nextval</code> after the
+ sequence has reached its maximum value will return an error.
+ If neither <code class="literal">CYCLE</code> or <code class="literal">NO
+ CYCLE</code> are specified, the old cycle behavior will be
+ maintained.
+ </p></dd><dt><span class="term"><code class="literal">SET { LOGGED | UNLOGGED }</code></span></dt><dd><p>
+ This form changes the sequence from unlogged to logged or vice-versa
+ (see <a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a>). It cannot be applied to a
+ temporary sequence.
+ </p></dd><dt><span class="term"><code class="literal">OWNED BY</code> <em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em><br /></span><span class="term"><code class="literal">OWNED BY NONE</code></span></dt><dd><p>
+ The <code class="literal">OWNED BY</code> option causes the sequence to be
+ associated with a specific table column, such that if that column
+ (or its whole table) is dropped, the sequence will be automatically
+ dropped as well. If specified, this association replaces any
+ previously specified association for the sequence. The specified
+ table must have the same owner and be in the same schema as the
+ sequence.
+ Specifying <code class="literal">OWNED BY NONE</code> removes any existing
+ association, making the sequence <span class="quote">“<span class="quote">free-standing</span>”</span>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the sequence.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the sequence.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the sequence.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.30.7"><h2>Notes</h2><p>
+ <code class="command">ALTER SEQUENCE</code> will not immediately affect
+ <code class="function">nextval</code> results in backends,
+ other than the current one, that have preallocated (cached) sequence
+ values. They will use up all cached values prior to noticing the changed
+ sequence generation parameters. The current backend will be affected
+ immediately.
+ </p><p>
+ <code class="command">ALTER SEQUENCE</code> does not affect the <code class="function">currval</code>
+ status for the sequence. (Before <span class="productname">PostgreSQL</span>
+ 8.3, it sometimes did.)
+ </p><p>
+ <code class="command">ALTER SEQUENCE</code> blocks
+ concurrent <code class="function">nextval</code>, <code class="function">currval</code>,
+ <code class="function">lastval</code>, and <code class="command">setval</code> calls.
+ </p><p>
+ For historical reasons, <code class="command">ALTER TABLE</code> can be used with
+ sequences too; but the only variants of <code class="command">ALTER TABLE</code>
+ that are allowed with sequences are equivalent to the forms shown above.
+ </p></div><div class="refsect1" id="id-1.9.3.30.8"><h2>Examples</h2><p>
+ Restart a sequence called <code class="literal">serial</code>, at 105:
+</p><pre class="programlisting">
+ALTER SEQUENCE serial RESTART WITH 105;
+</pre></div><div class="refsect1" id="id-1.9.3.30.9"><h2>Compatibility</h2><p>
+ <code class="command">ALTER SEQUENCE</code> conforms to the <acronym class="acronym">SQL</acronym>
+ standard, except for the <code class="literal">AS</code>, <code class="literal">START WITH</code>,
+ <code class="literal">OWNED BY</code>, <code class="literal">OWNER TO</code>, <code class="literal">RENAME TO</code>, and
+ <code class="literal">SET SCHEMA</code> clauses, which are
+ <span class="productname">PostgreSQL</span> extensions.
+ </p></div><div class="refsect1" id="id-1.9.3.30.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a>, <a class="xref" href="sql-dropsequence.html" title="DROP SEQUENCE"><span class="refentrytitle">DROP SEQUENCE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterschema.html" title="ALTER SCHEMA">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterserver.html" title="ALTER SERVER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER SCHEMA </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER SERVER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterserver.html b/doc/src/sgml/html/sql-alterserver.html
new file mode 100644
index 0000000..504ac4b
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterserver.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER SERVER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altersequence.html" title="ALTER SEQUENCE" /><link rel="next" href="sql-alterstatistics.html" title="ALTER STATISTICS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER SERVER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altersequence.html" title="ALTER SEQUENCE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterstatistics.html" title="ALTER STATISTICS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERSERVER"><div class="titlepage"></div><a id="id-1.9.3.31.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER SERVER</span></h2><p>ALTER SERVER — change the definition of a foreign server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER SERVER <em class="replaceable"><code>name</code></em> [ VERSION '<em class="replaceable"><code>new_version</code></em>' ]
+ [ OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ] ) ]
+ALTER SERVER <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SERVER <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.31.5"><h2>Description</h2><p>
+ <code class="command">ALTER SERVER</code> changes the definition of a foreign
+ server. The first form changes the server version string or the
+ generic options of the server (at least one clause is required).
+ The second form changes the owner of the server.
+ </p><p>
+ To alter the server you must be the owner of the server.
+ Additionally to alter the owner, you must own the server and also
+ be a direct or indirect member of the new owning role, and you must
+ have <code class="literal">USAGE</code> privilege on the server's foreign-data
+ wrapper. (Note that superusers satisfy all these criteria
+ automatically.)
+ </p></div><div class="refsect1" id="id-1.9.3.31.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing server.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_version</code></em></span></dt><dd><p>
+ New server version.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ] )</code></span></dt><dd><p>
+ Change options for the
+ server. <code class="literal">ADD</code>, <code class="literal">SET</code>, and <code class="literal">DROP</code>
+ specify the action to be performed. <code class="literal">ADD</code> is assumed
+ if no operation is explicitly specified. Option names must be
+ unique; names and values are also validated using the server's
+ foreign-data wrapper library.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the foreign server.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the foreign server.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.31.7"><h2>Examples</h2><p>
+ Alter server <code class="literal">foo</code>, add connection options:
+</p><pre class="programlisting">
+ALTER SERVER foo OPTIONS (host 'foo', dbname 'foodb');
+</pre><p>
+ </p><p>
+ Alter server <code class="literal">foo</code>, change version,
+ change <code class="literal">host</code> option:
+</p><pre class="programlisting">
+ALTER SERVER foo VERSION '8.4' OPTIONS (SET host 'baz');
+</pre></div><div class="refsect1" id="id-1.9.3.31.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER SERVER</code> conforms to ISO/IEC 9075-9 (SQL/MED).
+ The <code class="literal">OWNER TO</code> and <code class="literal">RENAME</code> forms are
+ PostgreSQL extensions.
+ </p></div><div class="refsect1" id="id-1.9.3.31.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>, <a class="xref" href="sql-dropserver.html" title="DROP SERVER"><span class="refentrytitle">DROP SERVER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altersequence.html" title="ALTER SEQUENCE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterstatistics.html" title="ALTER STATISTICS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER SEQUENCE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER STATISTICS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterstatistics.html b/doc/src/sgml/html/sql-alterstatistics.html
new file mode 100644
index 0000000..dd03c34
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterstatistics.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER STATISTICS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterserver.html" title="ALTER SERVER" /><link rel="next" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER STATISTICS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterserver.html" title="ALTER SERVER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERSTATISTICS"><div class="titlepage"></div><a id="id-1.9.3.32.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER STATISTICS</span></h2><p>ALTER STATISTICS —
+ change the definition of an extended statistics object
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER STATISTICS <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER STATISTICS <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER STATISTICS <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER STATISTICS <em class="replaceable"><code>name</code></em> SET STATISTICS <em class="replaceable"><code>new_target</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.32.5"><h2>Description</h2><p>
+ <code class="command">ALTER STATISTICS</code> changes the parameters of an existing
+ extended statistics object. Any parameters not specifically set in the
+ <code class="command">ALTER STATISTICS</code> command retain their prior settings.
+ </p><p>
+ You must own the statistics object to use <code class="command">ALTER STATISTICS</code>.
+ To change a statistics object's schema, you must also
+ have <code class="literal">CREATE</code> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the statistics object's schema. (These restrictions enforce that altering
+ the owner doesn't do anything you couldn't do by dropping and recreating
+ the statistics object. However, a superuser can alter ownership of any
+ statistics object anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.32.6"><h2>Parameters</h2><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the statistics object to be
+ altered.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the statistics object.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the statistics object.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the statistics object.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_target</code></em></span></dt><dd><p>
+ The statistic-gathering target for this statistics object for subsequent
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> operations.
+ The target can be set in the range 0 to 10000; alternatively, set it
+ to -1 to revert to using the maximum of the statistics target of the
+ referenced columns, if set, or the system default statistics
+ target (<a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a>).
+ For more information on the use of statistics by the
+ <span class="productname">PostgreSQL</span> query planner, refer to
+ <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.32.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER STATISTICS</code> command in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.32.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createstatistics.html" title="CREATE STATISTICS"><span class="refentrytitle">CREATE STATISTICS</span></a>, <a class="xref" href="sql-dropstatistics.html" title="DROP STATISTICS"><span class="refentrytitle">DROP STATISTICS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterserver.html" title="ALTER SERVER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER SERVER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER SUBSCRIPTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altersubscription.html b/doc/src/sgml/html/sql-altersubscription.html
new file mode 100644
index 0000000..d0a34af
--- /dev/null
+++ b/doc/src/sgml/html/sql-altersubscription.html
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER SUBSCRIPTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterstatistics.html" title="ALTER STATISTICS" /><link rel="next" href="sql-altersystem.html" title="ALTER SYSTEM" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER SUBSCRIPTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterstatistics.html" title="ALTER STATISTICS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altersystem.html" title="ALTER SYSTEM">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERSUBSCRIPTION"><div class="titlepage"></div><a id="id-1.9.3.33.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER SUBSCRIPTION</span></h2><p>ALTER SUBSCRIPTION — change the definition of a subscription</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> CONNECTION '<em class="replaceable"><code>conninfo</code></em>'
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> SET PUBLICATION <em class="replaceable"><code>publication_name</code></em> [, ...] [ WITH ( <em class="replaceable"><code>publication_option</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> ADD PUBLICATION <em class="replaceable"><code>publication_name</code></em> [, ...] [ WITH ( <em class="replaceable"><code>publication_option</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> DROP PUBLICATION <em class="replaceable"><code>publication_name</code></em> [, ...] [ WITH ( <em class="replaceable"><code>publication_option</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> REFRESH PUBLICATION [ WITH ( <em class="replaceable"><code>refresh_option</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> ENABLE
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> DISABLE
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> SET ( <em class="replaceable"><code>subscription_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> SKIP ( <em class="replaceable"><code>skip_option</code></em> = <em class="replaceable"><code>value</code></em> )
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SUBSCRIPTION <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.33.5"><h2>Description</h2><p>
+ <code class="command">ALTER SUBSCRIPTION</code> can change most of the subscription
+ properties that can be specified
+ in <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>.
+ </p><p>
+ You must own the subscription to use <code class="command">ALTER SUBSCRIPTION</code>.
+ To alter the owner, you must also be a direct or indirect member of the
+ new owning role. The new owner has to be a superuser.
+ (Currently, all subscription owners must be superusers, so the owner checks
+ will be bypassed in practice. But this might change in the future.)
+ </p><p>
+ When refreshing a publication we remove the relations that are no longer
+ part of the publication and we also remove the table synchronization slots
+ if there are any. It is necessary to remove these slots so that the resources
+ allocated for the subscription on the remote host are released. If due to
+ network breakdown or some other error, <span class="productname">PostgreSQL</span>
+ is unable to remove the slots, an error will be reported. To proceed in this
+ situation, the user either needs to retry the operation or disassociate the
+ slot from the subscription and drop the subscription as explained in
+ <a class="xref" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION"><span class="refentrytitle">DROP SUBSCRIPTION</span></a>.
+ </p><p>
+ Commands <code class="command">ALTER SUBSCRIPTION ... REFRESH PUBLICATION</code> and
+ <code class="command">ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...</code>
+ with <code class="literal">refresh</code> option as <code class="literal">true</code> cannot be
+ executed inside a transaction block.
+
+ These commands also cannot be executed when the subscription has
+ <code class="literal">two_phase</code> commit enabled,
+ unless <code class="literal">copy_data</code> is <code class="literal">false</code>.
+ See column <code class="structfield">subtwophasestate</code> of
+ <a class="link" href="catalog-pg-subscription.html" title="53.54. pg_subscription"><code class="structname">pg_subscription</code></a>
+ to know the actual two-phase state.
+ </p></div><div class="refsect1" id="id-1.9.3.33.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a subscription whose properties are to be altered.
+ </p></dd><dt><span class="term"><code class="literal">CONNECTION '<em class="replaceable"><code>conninfo</code></em>'</code></span></dt><dd><p>
+ This clause replaces the connection string originally set by
+ <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>. See there for more
+ information.
+ </p></dd><dt><span class="term"><code class="literal">SET PUBLICATION <em class="replaceable"><code>publication_name</code></em></code><br /></span><span class="term"><code class="literal">ADD PUBLICATION <em class="replaceable"><code>publication_name</code></em></code><br /></span><span class="term"><code class="literal">DROP PUBLICATION <em class="replaceable"><code>publication_name</code></em></code></span></dt><dd><p>
+ These forms change the list of subscribed publications.
+ <code class="literal">SET</code>
+ replaces the entire list of publications with a new list,
+ <code class="literal">ADD</code> adds additional publications to the list of
+ publications, and <code class="literal">DROP</code> removes the publications from
+ the list of publications. We allow non-existent publications to be
+ specified in <code class="literal">ADD</code> and <code class="literal">SET</code> variants
+ so that users can add those later. See <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>
+ for more information. By default, this command will also act like
+ <code class="literal">REFRESH PUBLICATION</code>.
+ </p><p>
+ <em class="replaceable"><code>publication_option</code></em> specifies additional
+ options for this operation. The supported options are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">refresh</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ When false, the command will not try to refresh table information.
+ <code class="literal">REFRESH PUBLICATION</code> should then be executed separately.
+ The default is <code class="literal">true</code>.
+ </p></dd></dl></div><p>
+
+ Additionally, the options described under
+ <code class="literal">REFRESH PUBLICATION</code> may be specified, to control the
+ implicit refresh operation.
+ </p></dd><dt><span class="term"><code class="literal">REFRESH PUBLICATION</code></span></dt><dd><p>
+ Fetch missing table information from publisher. This will start
+ replication of tables that were added to the subscribed-to publications
+ since <code class="command">CREATE SUBSCRIPTION</code> or
+ the last invocation of <code class="command">REFRESH PUBLICATION</code>.
+ </p><p>
+ <em class="replaceable"><code>refresh_option</code></em> specifies additional options for the
+ refresh operation. The supported options are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">copy_data</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether to copy pre-existing data in the publications
+ that are being subscribed to when the replication starts.
+ The default is <code class="literal">true</code>.
+ </p><p>
+ Previously subscribed tables are not copied, even if a table's row
+ filter <code class="literal">WHERE</code> clause has since been modified.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="literal">ENABLE</code></span></dt><dd><p>
+ Enables a previously disabled subscription, starting the logical
+ replication worker at the end of the transaction.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE</code></span></dt><dd><p>
+ Disables a running subscription, stopping the logical replication
+ worker at the end of the transaction.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>subscription_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause alters parameters originally set by
+ <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>. See there for more
+ information. The parameters that can be altered
+ are <code class="literal">slot_name</code>,
+ <code class="literal">synchronous_commit</code>,
+ <code class="literal">binary</code>, <code class="literal">streaming</code>, and
+ <code class="literal">disable_on_error</code>.
+ </p></dd><dt><span class="term"><code class="literal">SKIP ( <em class="replaceable"><code>skip_option</code></em> = <em class="replaceable"><code>value</code></em> )</code></span></dt><dd><p>
+ Skips applying all changes of the remote transaction. If incoming data
+ violates any constraints, logical replication will stop until it is
+ resolved. By using the <code class="command">ALTER SUBSCRIPTION ... SKIP</code> command,
+ the logical replication worker skips all data modification changes within
+ the transaction. This option has no effect on the transactions that are
+ already prepared by enabling <code class="literal">two_phase</code> on
+ subscriber.
+ After the logical replication worker successfully skips the transaction or
+ finishes a transaction, the LSN (stored in
+ <code class="structname">pg_subscription</code>.<code class="structfield">subskiplsn</code>)
+ is cleared. See <a class="xref" href="logical-replication-conflicts.html" title="31.5. Conflicts">Section 31.5</a> for
+ the details of logical replication conflicts. Using this command requires
+ superuser privilege.
+ </p><p>
+ <em class="replaceable"><code>skip_option</code></em> specifies options for this operation.
+ The supported option is:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">lsn</code> (<code class="type">pg_lsn</code>)</span></dt><dd><p>
+ Specifies the finish LSN of the remote transaction whose changes
+ are to be skipped by the logical replication worker. The finish LSN
+ is the LSN at which the transaction is either committed or prepared.
+ Skipping individual subtransactions is not supported. Setting
+ <code class="literal">NONE</code> resets the LSN.
+ </p></dd></dl></div></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the subscription.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the subscription.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.33.7"><h2>Examples</h2><p>
+ Change the publication subscribed by a subscription to
+ <code class="literal">insert_only</code>:
+</p><pre class="programlisting">
+ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only;
+</pre><p>
+ </p><p>
+ Disable (stop) the subscription:
+</p><pre class="programlisting">
+ALTER SUBSCRIPTION mysub DISABLE;
+</pre></div><div class="refsect1" id="id-1.9.3.33.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER SUBSCRIPTION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.33.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>, <a class="xref" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION"><span class="refentrytitle">DROP SUBSCRIPTION</span></a>, <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a>, <a class="xref" href="sql-alterpublication.html" title="ALTER PUBLICATION"><span class="refentrytitle">ALTER PUBLICATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterstatistics.html" title="ALTER STATISTICS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altersystem.html" title="ALTER SYSTEM">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER STATISTICS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER SYSTEM</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altersystem.html b/doc/src/sgml/html/sql-altersystem.html
new file mode 100644
index 0000000..7293ea4
--- /dev/null
+++ b/doc/src/sgml/html/sql-altersystem.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER SYSTEM</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION" /><link rel="next" href="sql-altertable.html" title="ALTER TABLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER SYSTEM</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertable.html" title="ALTER TABLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERSYSTEM"><div class="titlepage"></div><a id="id-1.9.3.34.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER SYSTEM</span></h2><p>ALTER SYSTEM — change a server configuration parameter</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER SYSTEM SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | '<em class="replaceable"><code>value</code></em>' | DEFAULT }
+
+ALTER SYSTEM RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ALTER SYSTEM RESET ALL
+</pre></div><div class="refsect1" id="id-1.9.3.34.5"><h2>Description</h2><p>
+ <code class="command">ALTER SYSTEM</code> is used for changing server configuration
+ parameters across the entire database cluster. It can be more convenient
+ than the traditional method of manually editing
+ the <code class="filename">postgresql.conf</code> file.
+ <code class="command">ALTER SYSTEM</code> writes the given parameter setting to
+ the <code class="filename">postgresql.auto.conf</code> file, which is read in
+ addition to <code class="filename">postgresql.conf</code>.
+ Setting a parameter to <code class="literal">DEFAULT</code>, or using the
+ <code class="command">RESET</code> variant, removes that configuration entry from the
+ <code class="filename">postgresql.auto.conf</code> file. Use <code class="literal">RESET
+ ALL</code> to remove all such configuration entries.
+ </p><p>
+ Values set with <code class="command">ALTER SYSTEM</code> will be effective after
+ the next server configuration reload, or after the next server restart
+ in the case of parameters that can only be changed at server start.
+ A server configuration reload can be commanded by calling the SQL
+ function <code class="function">pg_reload_conf()</code>, running <code class="literal">pg_ctl reload</code>,
+ or sending a <span class="systemitem">SIGHUP</span> signal to the main server process.
+ </p><p>
+ Only superusers and users granted <code class="literal">ALTER SYSTEM</code> privilege
+ on a parameter can change it using <code class="command">ALTER SYSTEM</code>. Also, since
+ this command acts directly on the file system and cannot be rolled back,
+ it is not allowed inside a transaction block or function.
+ </p></div><div class="refsect1" id="id-1.9.3.34.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em></span></dt><dd><p>
+ Name of a settable configuration parameter. Available parameters are
+ documented in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ New value of the parameter. Values can be specified as string
+ constants, identifiers, numbers, or comma-separated lists of
+ these, as appropriate for the particular parameter.
+ <code class="literal">DEFAULT</code> can be written to specify removing the
+ parameter and its value from <code class="filename">postgresql.auto.conf</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.34.7"><h2>Notes</h2><p>
+ This command can't be used to set <a class="xref" href="runtime-config-file-locations.html#GUC-DATA-DIRECTORY">data_directory</a>,
+ nor parameters that are not allowed in <code class="filename">postgresql.conf</code>
+ (e.g., <a class="link" href="runtime-config-preset.html" title="20.15. Preset Options">preset options</a>).
+ </p><p>
+ See <a class="xref" href="config-setting.html" title="20.1. Setting Parameters">Section 20.1</a> for other ways to set the parameters.
+ </p></div><div class="refsect1" id="id-1.9.3.34.8"><h2>Examples</h2><p>
+ Set the <code class="literal">wal_level</code>:
+</p><pre class="programlisting">
+ALTER SYSTEM SET wal_level = replica;
+</pre><p>
+ </p><p>
+ Undo that, restoring whatever setting was effective
+ in <code class="filename">postgresql.conf</code>:
+</p><pre class="programlisting">
+ALTER SYSTEM RESET wal_level;
+</pre></div><div class="refsect1" id="id-1.9.3.34.9"><h2>Compatibility</h2><p>
+ The <code class="command">ALTER SYSTEM</code> statement is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.34.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a>, <a class="xref" href="sql-show.html" title="SHOW"><span class="refentrytitle">SHOW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertable.html" title="ALTER TABLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER SUBSCRIPTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TABLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertable.html b/doc/src/sgml/html/sql-altertable.html
new file mode 100644
index 0000000..9c23a3c
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertable.html
@@ -0,0 +1,1094 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TABLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altersystem.html" title="ALTER SYSTEM" /><link rel="next" href="sql-altertablespace.html" title="ALTER TABLESPACE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TABLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altersystem.html" title="ALTER SYSTEM">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertablespace.html" title="ALTER TABLESPACE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTABLE"><div class="titlepage"></div><a id="id-1.9.3.35.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TABLE</span></h2><p>ALTER TABLE — change the definition of a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TABLE [ IF EXISTS ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ]
+ <em class="replaceable"><code>action</code></em> [, ... ]
+ALTER TABLE [ IF EXISTS ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ]
+ RENAME [ COLUMN ] <em class="replaceable"><code>column_name</code></em> TO <em class="replaceable"><code>new_column_name</code></em>
+ALTER TABLE [ IF EXISTS ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ]
+ RENAME CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> TO <em class="replaceable"><code>new_constraint_name</code></em>
+ALTER TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER TABLE ALL IN TABLESPACE <em class="replaceable"><code>name</code></em> [ OWNED BY <em class="replaceable"><code>role_name</code></em> [, ... ] ]
+ SET TABLESPACE <em class="replaceable"><code>new_tablespace</code></em> [ NOWAIT ]
+ALTER TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ ATTACH PARTITION <em class="replaceable"><code>partition_name</code></em> { FOR VALUES <em class="replaceable"><code>partition_bound_spec</code></em> | DEFAULT }
+ALTER TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+ DETACH PARTITION <em class="replaceable"><code>partition_name</code></em> [ CONCURRENTLY | FINALIZE ]
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ ADD [ COLUMN ] [ IF NOT EXISTS ] <em class="replaceable"><code>column_name</code></em> <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ DROP [ COLUMN ] [ IF EXISTS ] <em class="replaceable"><code>column_name</code></em> [ RESTRICT | CASCADE ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> [ SET DATA ] TYPE <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ USING <em class="replaceable"><code>expression</code></em> ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET DEFAULT <em class="replaceable"><code>expression</code></em>
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> DROP DEFAULT
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> { SET | DROP } NOT NULL
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> DROP EXPRESSION [ IF EXISTS ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <em class="replaceable"><code>sequence_options</code></em> ) ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> { SET GENERATED { ALWAYS | BY DEFAULT } | SET <em class="replaceable"><code>sequence_option</code></em> | RESTART [ [ WITH ] <em class="replaceable"><code>restart</code></em> ] } [...]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> DROP IDENTITY [ IF EXISTS ]
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET STATISTICS <em class="replaceable"><code>integer</code></em>
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET ( <em class="replaceable"><code>attribute_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> RESET ( <em class="replaceable"><code>attribute_option</code></em> [, ... ] )
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET COMPRESSION <em class="replaceable"><code>compression_method</code></em>
+ ADD <em class="replaceable"><code>table_constraint</code></em> [ NOT VALID ]
+ ADD <em class="replaceable"><code>table_constraint_using_index</code></em>
+ ALTER CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+ VALIDATE CONSTRAINT <em class="replaceable"><code>constraint_name</code></em>
+ DROP CONSTRAINT [ IF EXISTS ] <em class="replaceable"><code>constraint_name</code></em> [ RESTRICT | CASCADE ]
+ DISABLE TRIGGER [ <em class="replaceable"><code>trigger_name</code></em> | ALL | USER ]
+ ENABLE TRIGGER [ <em class="replaceable"><code>trigger_name</code></em> | ALL | USER ]
+ ENABLE REPLICA TRIGGER <em class="replaceable"><code>trigger_name</code></em>
+ ENABLE ALWAYS TRIGGER <em class="replaceable"><code>trigger_name</code></em>
+ DISABLE RULE <em class="replaceable"><code>rewrite_rule_name</code></em>
+ ENABLE RULE <em class="replaceable"><code>rewrite_rule_name</code></em>
+ ENABLE REPLICA RULE <em class="replaceable"><code>rewrite_rule_name</code></em>
+ ENABLE ALWAYS RULE <em class="replaceable"><code>rewrite_rule_name</code></em>
+ DISABLE ROW LEVEL SECURITY
+ ENABLE ROW LEVEL SECURITY
+ FORCE ROW LEVEL SECURITY
+ NO FORCE ROW LEVEL SECURITY
+ CLUSTER ON <em class="replaceable"><code>index_name</code></em>
+ SET WITHOUT CLUSTER
+ SET WITHOUT OIDS
+ SET ACCESS METHOD <em class="replaceable"><code>new_access_method</code></em>
+ SET TABLESPACE <em class="replaceable"><code>new_tablespace</code></em>
+ SET { LOGGED | UNLOGGED }
+ SET ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )
+ RESET ( <em class="replaceable"><code>storage_parameter</code></em> [, ... ] )
+ INHERIT <em class="replaceable"><code>parent_table</code></em>
+ NO INHERIT <em class="replaceable"><code>parent_table</code></em>
+ OF <em class="replaceable"><code>type_name</code></em>
+ NOT OF
+ OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ REPLICA IDENTITY { DEFAULT | USING INDEX <em class="replaceable"><code>index_name</code></em> | FULL | NOTHING }
+
+<span class="phrase">and <em class="replaceable"><code>partition_bound_spec</code></em> is:</span>
+
+IN ( <em class="replaceable"><code>partition_bound_expr</code></em> [, ...] ) |
+FROM ( { <em class="replaceable"><code>partition_bound_expr</code></em> | MINVALUE | MAXVALUE } [, ...] )
+ TO ( { <em class="replaceable"><code>partition_bound_expr</code></em> | MINVALUE | MAXVALUE } [, ...] ) |
+WITH ( MODULUS <em class="replaceable"><code>numeric_literal</code></em>, REMAINDER <em class="replaceable"><code>numeric_literal</code></em> )
+
+<span class="phrase">and <em class="replaceable"><code>column_constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+{ NOT NULL |
+ NULL |
+ CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] |
+ DEFAULT <em class="replaceable"><code>default_expr</code></em> |
+ GENERATED ALWAYS AS ( <em class="replaceable"><code>generation_expr</code></em> ) STORED |
+ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <em class="replaceable"><code>sequence_options</code></em> ) ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] <em class="replaceable"><code>index_parameters</code></em> |
+ PRIMARY KEY <em class="replaceable"><code>index_parameters</code></em> |
+ REFERENCES <em class="replaceable"><code>reftable</code></em> [ ( <em class="replaceable"><code>refcolumn</code></em> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+ [ ON DELETE <em class="replaceable"><code>referential_action</code></em> ] [ ON UPDATE <em class="replaceable"><code>referential_action</code></em> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<span class="phrase">and <em class="replaceable"><code>table_constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+{ CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> |
+ PRIMARY KEY ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> |
+ EXCLUDE [ USING <em class="replaceable"><code>index_method</code></em> ] ( <em class="replaceable"><code>exclude_element</code></em> WITH <em class="replaceable"><code>operator</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> [ WHERE ( <em class="replaceable"><code>predicate</code></em> ) ] |
+ FOREIGN KEY ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) REFERENCES <em class="replaceable"><code>reftable</code></em> [ ( <em class="replaceable"><code>refcolumn</code></em> [, ... ] ) ]
+ [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <em class="replaceable"><code>referential_action</code></em> ] [ ON UPDATE <em class="replaceable"><code>referential_action</code></em> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<span class="phrase">and <em class="replaceable"><code>table_constraint_using_index</code></em> is:</span>
+
+ [ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+ { UNIQUE | PRIMARY KEY } USING INDEX <em class="replaceable"><code>index_name</code></em>
+ [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<span class="phrase"><em class="replaceable"><code>index_parameters</code></em> in <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY KEY</code>, and <code class="literal">EXCLUDE</code> constraints are:</span>
+
+[ INCLUDE ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ]
+[ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+[ USING INDEX TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+
+<span class="phrase"><em class="replaceable"><code>exclude_element</code></em> in an <code class="literal">EXCLUDE</code> constraint is:</span>
+
+{ <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ <em class="replaceable"><code>opclass</code></em> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
+
+<span class="phrase"><em class="replaceable"><code>referential_action</code></em> in a <code class="literal">FOREIGN KEY</code>/<code class="literal">REFERENCES</code> constraint is:</span>
+
+{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ] | SET DEFAULT [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ] }
+</pre></div><div class="refsect1" id="id-1.9.3.35.5"><h2>Description</h2><p>
+ <code class="command">ALTER TABLE</code> changes the definition of an existing table.
+ There are several subforms described below. Note that the lock level required
+ may differ for each subform. An <code class="literal">ACCESS EXCLUSIVE</code> lock is
+ acquired unless explicitly noted. When multiple subcommands are given, the
+ lock acquired will be the strictest one required by any subcommand.
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ADD COLUMN [ IF NOT EXISTS ]</code></span></dt><dd><p>
+ This form adds a new column to the table, using the same syntax as
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>. If <code class="literal">IF NOT EXISTS</code>
+ is specified and a column already exists with this name,
+ no error is thrown.
+ </p></dd><dt><span class="term"><code class="literal">DROP COLUMN [ IF EXISTS ]</code></span></dt><dd><p>
+ This form drops a column from a table. Indexes and
+ table constraints involving the column will be automatically
+ dropped as well.
+ Multivariate statistics referencing the dropped column will also be
+ removed if the removal of the column would cause the statistics to
+ contain data for only a single column.
+ You will need to say <code class="literal">CASCADE</code> if anything outside the table
+ depends on the column, for example, foreign key references or views.
+ If <code class="literal">IF EXISTS</code> is specified and the column
+ does not exist, no error is thrown. In this case a notice
+ is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">SET DATA TYPE</code></span></dt><dd><p>
+ This form changes the type of a column of a table. Indexes and
+ simple table constraints involving the column will be automatically
+ converted to use the new column type by reparsing the originally
+ supplied expression.
+ The optional <code class="literal">COLLATE</code> clause specifies a collation
+ for the new column; if omitted, the collation is the default for the
+ new column type.
+ The optional <code class="literal">USING</code>
+ clause specifies how to compute the new column value from the old;
+ if omitted, the default conversion is the same as an assignment
+ cast from old data type to new. A <code class="literal">USING</code>
+ clause must be provided if there is no implicit or assignment
+ cast from old to new type.
+ </p><p>
+ When this form is used, the column's statistics are removed,
+ so running <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>
+ on the table afterwards is recommended.
+ </p></dd><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP DEFAULT</code></span></dt><dd><p>
+ These forms set or remove the default value for a column (where
+ removal is equivalent to setting the default value to NULL). The new
+ default value will only apply in subsequent <code class="command">INSERT</code>
+ or <code class="command">UPDATE</code> commands; it does not cause rows already
+ in the table to change.
+ </p></dd><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP NOT NULL</code></span></dt><dd><p>
+ These forms change whether a column is marked to allow null
+ values or to reject null values.
+ </p><p>
+ <code class="literal">SET NOT NULL</code> may only be applied to a column
+ provided none of the records in the table contain a
+ <code class="literal">NULL</code> value for the column. Ordinarily this is
+ checked during the <code class="literal">ALTER TABLE</code> by scanning the
+ entire table; however, if a valid <code class="literal">CHECK</code> constraint is
+ found which proves no <code class="literal">NULL</code> can exist, then the
+ table scan is skipped.
+ </p><p>
+ If this table is a partition, one cannot perform <code class="literal">DROP NOT NULL</code>
+ on a column if it is marked <code class="literal">NOT NULL</code> in the parent
+ table. To drop the <code class="literal">NOT NULL</code> constraint from all the
+ partitions, perform <code class="literal">DROP NOT NULL</code> on the parent
+ table. Even if there is no <code class="literal">NOT NULL</code> constraint on the
+ parent, such a constraint can still be added to individual partitions,
+ if desired; that is, the children can disallow nulls even if the parent
+ allows them, but not the other way around.
+ </p></dd><dt><span class="term"><code class="literal">DROP EXPRESSION [ IF EXISTS ]</code></span></dt><dd><p>
+ This form turns a stored generated column into a normal base column.
+ Existing data in the columns is retained, but future changes will no
+ longer apply the generation expression.
+ </p><p>
+ If <code class="literal">DROP EXPRESSION IF EXISTS</code> is specified and the
+ column is not a stored generated column, no error is thrown. In this
+ case a notice is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY</code><br /></span><span class="term"><code class="literal">SET GENERATED { ALWAYS | BY DEFAULT }</code><br /></span><span class="term"><code class="literal">DROP IDENTITY [ IF EXISTS ]</code></span></dt><dd><p>
+ These forms change whether a column is an identity column or change the
+ generation attribute of an existing identity column.
+ See <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a> for details.
+ Like <code class="literal">SET DEFAULT</code>, these forms only affect the
+ behavior of subsequent <code class="command">INSERT</code>
+ and <code class="command">UPDATE</code> commands; they do not cause rows
+ already in the table to change.
+ </p><p>
+ If <code class="literal">DROP IDENTITY IF EXISTS</code> is specified and the
+ column is not an identity column, no error is thrown. In this case a
+ notice is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">SET <em class="replaceable"><code>sequence_option</code></em></code><br /></span><span class="term"><code class="literal">RESTART</code></span></dt><dd><p>
+ These forms alter the sequence that underlies an existing identity
+ column. <em class="replaceable"><code>sequence_option</code></em> is an option
+ supported by <a class="link" href="sql-altersequence.html" title="ALTER SEQUENCE"><code class="command">ALTER SEQUENCE</code></a> such
+ as <code class="literal">INCREMENT BY</code>.
+ </p></dd><dt><span class="term"><code class="literal">SET STATISTICS</code></span></dt><dd><p>
+ This form
+ sets the per-column statistics-gathering target for subsequent
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> operations.
+ The target can be set in the range 0 to 10000; alternatively, set it
+ to -1 to revert to using the system default statistics
+ target (<a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a>).
+ For more information on the use of statistics by the
+ <span class="productname">PostgreSQL</span> query planner, refer to
+ <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>.
+ </p><p>
+ <code class="literal">SET STATISTICS</code> acquires a
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>attribute_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )</code><br /></span><span class="term"><code class="literal">RESET ( <em class="replaceable"><code>attribute_option</code></em> [, ... ] )</code></span></dt><dd><p>
+ This form sets or resets per-attribute options. Currently, the only
+ defined per-attribute options are <code class="literal">n_distinct</code> and
+ <code class="literal">n_distinct_inherited</code>, which override the
+ number-of-distinct-values estimates made by subsequent
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>
+ operations. <code class="literal">n_distinct</code> affects the statistics for the table
+ itself, while <code class="literal">n_distinct_inherited</code> affects the statistics
+ gathered for the table plus its inheritance children. When set to a
+ positive value, <code class="command">ANALYZE</code> will assume that the column contains
+ exactly the specified number of distinct nonnull values. When set to a
+ negative value, which must be greater
+ than or equal to -1, <code class="command">ANALYZE</code> will assume that the number of
+ distinct nonnull values in the column is linear in the size of the
+ table; the exact count is to be computed by multiplying the estimated
+ table size by the absolute value of the given number. For example,
+ a value of -1 implies that all values in the column are distinct, while
+ a value of -0.5 implies that each value appears twice on the average.
+ This can be useful when the size of the table changes over time, since
+ the multiplication by the number of rows in the table is not performed
+ until query planning time. Specify a value of 0 to revert to estimating
+ the number of distinct values normally. For more information on the use
+ of statistics by the <span class="productname">PostgreSQL</span> query
+ planner, refer to <a class="xref" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Section 14.2</a>.
+ </p><p>
+ Changing per-attribute options acquires a
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock.
+ </p></dd><dt><span class="term">
+ <code class="literal">SET STORAGE</code>
+ <a id="id-1.9.3.35.5.2.3.11.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ This form sets the storage mode for a column. This controls whether this
+ column is held inline or in a secondary <acronym class="acronym">TOAST</acronym> table, and
+ whether the data
+ should be compressed or not. <code class="literal">PLAIN</code> must be used
+ for fixed-length values such as <code class="type">integer</code> and is
+ inline, uncompressed. <code class="literal">MAIN</code> is for inline,
+ compressible data. <code class="literal">EXTERNAL</code> is for external,
+ uncompressed data, and <code class="literal">EXTENDED</code> is for external,
+ compressed data. <code class="literal">EXTENDED</code> is the default for most
+ data types that support non-<code class="literal">PLAIN</code> storage.
+ Use of <code class="literal">EXTERNAL</code> will make substring operations on
+ very large <code class="type">text</code> and <code class="type">bytea</code> values run faster,
+ at the penalty of increased storage space. Note that
+ <code class="literal">SET STORAGE</code> doesn't itself change anything in the table,
+ it just sets the strategy to be pursued during future table updates.
+ See <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a> for more information.
+ </p></dd><dt><span class="term">
+ <code class="literal">SET COMPRESSION <em class="replaceable"><code>compression_method</code></em></code>
+ </span></dt><dd><p>
+ This form sets the compression method for a column, determining how
+ values inserted in future will be compressed (if the storage mode
+ permits compression at all).
+ This does not cause the table to be rewritten, so existing data may still
+ be compressed with other compression methods. If the table is restored
+ with <span class="application">pg_restore</span>, then all values are rewritten
+ with the configured compression method.
+ However, when data is inserted from another relation (for example,
+ by <code class="command">INSERT ... SELECT</code>), values from the source table are
+ not necessarily detoasted, so any previously compressed data may retain
+ its existing compression method, rather than being recompressed with the
+ compression method of the target column.
+ The supported compression
+ methods are <code class="literal">pglz</code> and <code class="literal">lz4</code>.
+ (<code class="literal">lz4</code> is available only if <code class="option">--with-lz4</code>
+ was used when building <span class="productname">PostgreSQL</span>.) In
+ addition, <em class="replaceable"><code>compression_method</code></em>
+ can be <code class="literal">default</code>, which selects the default behavior of
+ consulting the <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TOAST-COMPRESSION">default_toast_compression</a> setting
+ at the time of data insertion to determine the method to use.
+ </p></dd><dt><span class="term"><code class="literal">ADD <em class="replaceable"><code>table_constraint</code></em> [ NOT VALID ]</code></span></dt><dd><p>
+ This form adds a new constraint to a table using the same constraint
+ syntax as <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>, plus the option <code class="literal">NOT
+ VALID</code>, which is currently only allowed for foreign key
+ and CHECK constraints.
+ </p><p>
+ Normally, this form will cause a scan of the table to verify that all
+ existing rows in the table satisfy the new constraint. But if
+ the <code class="literal">NOT VALID</code> option is used, this
+ potentially-lengthy scan is skipped. The constraint will still be
+ enforced against subsequent inserts or updates (that is, they'll fail
+ unless there is a matching row in the referenced table, in the case
+ of foreign keys, or they'll fail unless the new row matches the
+ specified check condition). But the
+ database will not assume that the constraint holds for all rows in
+ the table, until it is validated by using the <code class="literal">VALIDATE
+ CONSTRAINT</code> option.
+ See <a class="xref" href="sql-altertable.html#SQL-ALTERTABLE-NOTES" title="Notes">Notes</a> below for more information
+ about using the <code class="literal">NOT VALID</code> option.
+ </p><p>
+ Although most forms of <code class="literal">ADD
+ <em class="replaceable"><code>table_constraint</code></em></code>
+ require an <code class="literal">ACCESS EXCLUSIVE</code> lock, <code class="literal">ADD
+ FOREIGN KEY</code> requires only a <code class="literal">SHARE ROW
+ EXCLUSIVE</code> lock. Note that <code class="literal">ADD FOREIGN KEY</code>
+ also acquires a <code class="literal">SHARE ROW EXCLUSIVE</code> lock on the
+ referenced table, in addition to the lock on the table on which the
+ constraint is declared.
+ </p><p>
+ Additional restrictions apply when unique or primary key constraints
+ are added to partitioned tables; see <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>.
+ Also, foreign key constraints on partitioned
+ tables may not be declared <code class="literal">NOT VALID</code> at present.
+ </p></dd><dt><span class="term"><code class="literal">ADD <em class="replaceable"><code>table_constraint_using_index</code></em></code></span></dt><dd><p>
+ This form adds a new <code class="literal">PRIMARY KEY</code> or <code class="literal">UNIQUE</code>
+ constraint to a table based on an existing unique index. All the
+ columns of the index will be included in the constraint.
+ </p><p>
+ The index cannot have expression columns nor be a partial index.
+ Also, it must be a b-tree index with default sort ordering. These
+ restrictions ensure that the index is equivalent to one that would be
+ built by a regular <code class="literal">ADD PRIMARY KEY</code> or <code class="literal">ADD UNIQUE</code>
+ command.
+ </p><p>
+ If <code class="literal">PRIMARY KEY</code> is specified, and the index's columns are not
+ already marked <code class="literal">NOT NULL</code>, then this command will attempt to
+ do <code class="literal">ALTER COLUMN SET NOT NULL</code> against each such column.
+ That requires a full table scan to verify the column(s) contain no
+ nulls. In all other cases, this is a fast operation.
+ </p><p>
+ If a constraint name is provided then the index will be renamed to match
+ the constraint name. Otherwise the constraint will be named the same as
+ the index.
+ </p><p>
+ After this command is executed, the index is <span class="quote">“<span class="quote">owned</span>”</span> by the
+ constraint, in the same way as if the index had been built by
+ a regular <code class="literal">ADD PRIMARY KEY</code> or <code class="literal">ADD UNIQUE</code>
+ command. In particular, dropping the constraint will make the index
+ disappear too.
+ </p><p>
+ This form is not currently supported on partitioned tables.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Adding a constraint using an existing index can be helpful in
+ situations where a new constraint needs to be added without blocking
+ table updates for a long time. To do that, create the index using
+ <code class="command">CREATE INDEX CONCURRENTLY</code>, and then install it as an
+ official constraint using this syntax. See the example below.
+ </p></div></dd><dt><span class="term"><code class="literal">ALTER CONSTRAINT</code></span></dt><dd><p>
+ This form alters the attributes of a constraint that was previously
+ created. Currently only foreign key constraints may be altered.
+ </p></dd><dt><span class="term"><code class="literal">VALIDATE CONSTRAINT</code></span></dt><dd><p>
+ This form validates a foreign key or check constraint that was
+ previously created as <code class="literal">NOT VALID</code>, by scanning the
+ table to ensure there are no rows for which the constraint is not
+ satisfied. Nothing happens if the constraint is already marked valid.
+ (See <a class="xref" href="sql-altertable.html#SQL-ALTERTABLE-NOTES" title="Notes">Notes</a> below for an explanation
+ of the usefulness of this command.)
+ </p><p>
+ This command acquires a <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock.
+ </p></dd><dt><span class="term"><code class="literal">DROP CONSTRAINT [ IF EXISTS ]</code></span></dt><dd><p>
+ This form drops the specified constraint on a table, along with
+ any index underlying the constraint.
+ If <code class="literal">IF EXISTS</code> is specified and the constraint
+ does not exist, no error is thrown. In this case a notice is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE</code>/<code class="literal">ENABLE [ REPLICA | ALWAYS ] TRIGGER</code></span></dt><dd><p>
+ These forms configure the firing of trigger(s) belonging to the table.
+ A disabled trigger is still known to the system, but is not executed
+ when its triggering event occurs. (For a deferred trigger, the enable
+ status is checked when the event occurs, not when the trigger function
+ is actually executed.) One can disable or enable a single
+ trigger specified by name, or all triggers on the table, or only
+ user triggers (this option excludes internally generated constraint
+ triggers, such as those that are used to implement foreign key
+ constraints or deferrable uniqueness and exclusion constraints).
+ Disabling or enabling internally generated constraint triggers
+ requires superuser privileges; it should be done with caution since
+ of course the integrity of the constraint cannot be guaranteed if the
+ triggers are not executed.
+ </p><p>
+ The trigger firing mechanism is also affected by the configuration
+ variable <a class="xref" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE">session_replication_role</a>. Simply enabled
+ triggers (the default) will fire when the replication role is <span class="quote">“<span class="quote">origin</span>”</span>
+ (the default) or <span class="quote">“<span class="quote">local</span>”</span>. Triggers configured as <code class="literal">ENABLE
+ REPLICA</code> will only fire if the session is in <span class="quote">“<span class="quote">replica</span>”</span>
+ mode, and triggers configured as <code class="literal">ENABLE ALWAYS</code> will
+ fire regardless of the current replication role.
+ </p><p>
+ The effect of this mechanism is that in the default configuration,
+ triggers do not fire on replicas. This is useful because if a trigger
+ is used on the origin to propagate data between tables, then the
+ replication system will also replicate the propagated data; so the
+ trigger should not fire a second time on the replica, because that would
+ lead to duplication. However, if a trigger is used for another purpose
+ such as creating external alerts, then it might be appropriate to set it
+ to <code class="literal">ENABLE ALWAYS</code> so that it is also fired on
+ replicas.
+ </p><p>
+ When this command is applied to a partitioned table, the states of
+ corresponding clone triggers in the partitions are updated too,
+ unless <code class="literal">ONLY</code> is specified.
+ </p><p>
+ This command acquires a <code class="literal">SHARE ROW EXCLUSIVE</code> lock.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE</code>/<code class="literal">ENABLE [ REPLICA | ALWAYS ] RULE</code></span></dt><dd><p>
+ These forms configure the firing of rewrite rules belonging to the table.
+ A disabled rule is still known to the system, but is not applied
+ during query rewriting. The semantics are as for disabled/enabled
+ triggers. This configuration is ignored for <code class="literal">ON SELECT</code> rules, which
+ are always applied in order to keep views working even if the current
+ session is in a non-default replication role.
+ </p><p>
+ The rule firing mechanism is also affected by the configuration variable
+ <a class="xref" href="runtime-config-client.html#GUC-SESSION-REPLICATION-ROLE">session_replication_role</a>, analogous to triggers as
+ described above.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE</code>/<code class="literal">ENABLE ROW LEVEL SECURITY</code></span></dt><dd><p>
+ These forms control the application of row security policies belonging
+ to the table. If enabled and no policies exist for the table, then a
+ default-deny policy is applied. Note that policies can exist for a table
+ even if row-level security is disabled. In this case, the policies will
+ <span class="emphasis"><em>not</em></span> be applied and the policies will be ignored.
+ See also
+ <a class="link" href="sql-createpolicy.html" title="CREATE POLICY"><code class="command">CREATE POLICY</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">NO FORCE</code>/<code class="literal">FORCE ROW LEVEL SECURITY</code></span></dt><dd><p>
+ These forms control the application of row security policies belonging
+ to the table when the user is the table owner. If enabled, row-level
+ security policies will be applied when the user is the table owner. If
+ disabled (the default) then row-level security will not be applied when
+ the user is the table owner.
+ See also
+ <a class="link" href="sql-createpolicy.html" title="CREATE POLICY"><code class="command">CREATE POLICY</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">CLUSTER ON</code></span></dt><dd><p>
+ This form selects the default index for future
+ <a class="link" href="sql-cluster.html" title="CLUSTER"><code class="command">CLUSTER</code></a>
+ operations. It does not actually re-cluster the table.
+ </p><p>
+ Changing cluster options acquires a <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock.
+ </p></dd><dt><span class="term"><code class="literal">SET WITHOUT CLUSTER</code></span></dt><dd><p>
+ This form removes the most recently used
+ <a class="link" href="sql-cluster.html" title="CLUSTER"><code class="command">CLUSTER</code></a>
+ index specification from the table. This affects
+ future cluster operations that don't specify an index.
+ </p><p>
+ Changing cluster options acquires a <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock.
+ </p></dd><dt><span class="term"><code class="literal">SET WITHOUT OIDS</code></span></dt><dd><p>
+ Backward-compatible syntax for removing the <code class="literal">oid</code>
+ system column. As <code class="literal">oid</code> system columns cannot be
+ added anymore, this never has an effect.
+ </p></dd><dt><span class="term"><code class="literal">SET ACCESS METHOD</code></span></dt><dd><p>
+ This form changes the access method of the table by rewriting it. See
+ <a class="xref" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Chapter 63</a> for more information.
+ </p></dd><dt><span class="term"><code class="literal">SET TABLESPACE</code></span></dt><dd><p>
+ This form changes the table's tablespace to the specified tablespace and
+ moves the data file(s) associated with the table to the new tablespace.
+ Indexes on the table, if any, are not moved; but they can be moved
+ separately with additional <code class="literal">SET TABLESPACE</code> commands.
+ When applied to a partitioned table, nothing is moved, but any
+ partitions created afterwards with
+ <code class="command">CREATE TABLE PARTITION OF</code> will use that tablespace,
+ unless overridden by a <code class="literal">TABLESPACE</code> clause.
+ </p><p>
+ All tables in the current database in a tablespace can be moved by using
+ the <code class="literal">ALL IN TABLESPACE</code> form, which will lock all tables
+ to be moved first and then move each one. This form also supports
+ <code class="literal">OWNED BY</code>, which will only move tables owned by the
+ roles specified. If the <code class="literal">NOWAIT</code> option is specified
+ then the command will fail if it is unable to acquire all of the locks
+ required immediately. Note that system catalogs are not moved by this
+ command; use <code class="command">ALTER DATABASE</code> or explicit
+ <code class="command">ALTER TABLE</code> invocations instead if desired. The
+ <code class="literal">information_schema</code> relations are not considered part
+ of the system catalogs and will be moved.
+ See also
+ <a class="link" href="sql-createtablespace.html" title="CREATE TABLESPACE"><code class="command">CREATE TABLESPACE</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">SET { LOGGED | UNLOGGED }</code></span></dt><dd><p>
+ This form changes the table from unlogged to logged or vice-versa
+ (see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-UNLOGGED"><code class="literal">UNLOGGED</code></a>). It cannot be applied
+ to a temporary table.
+ </p><p>
+ This also changes the persistence of any sequences linked to the table
+ (for identity or serial columns). However, it is also possible to
+ change the persistence of such sequences separately.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This form changes one or more storage parameters for the table. See
+ <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" title="Storage Parameters">Storage Parameters</a> in the
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a> documentation
+ for details on the available parameters. Note that the table contents
+ will not be modified immediately by this command; depending on the
+ parameter you might need to rewrite the table to get the desired effects.
+ That can be done with <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM
+ FULL</code></a>, <a class="link" href="sql-cluster.html" title="CLUSTER"><code class="command">CLUSTER</code></a> or one of the forms
+ of <code class="command">ALTER TABLE</code> that forces a table rewrite.
+ For planner related parameters, changes will take effect from the next
+ time the table is locked so currently executing queries will not be
+ affected.
+ </p><p>
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock will be taken for
+ fillfactor, toast and autovacuum storage parameters, as well as the
+ planner parameter <code class="varname">parallel_workers</code>.
+ </p></dd><dt><span class="term"><code class="literal">RESET ( <em class="replaceable"><code>storage_parameter</code></em> [, ... ] )</code></span></dt><dd><p>
+ This form resets one or more storage parameters to their
+ defaults. As with <code class="literal">SET</code>, a table rewrite might be
+ needed to update the table entirely.
+ </p></dd><dt><span class="term"><code class="literal">INHERIT <em class="replaceable"><code>parent_table</code></em></code></span></dt><dd><p>
+ This form adds the target table as a new child of the specified parent
+ table. Subsequently, queries against the parent will include records
+ of the target table. To be added as a child, the target table must
+ already contain all the same columns as the parent (it could have
+ additional columns, too). The columns must have matching data types,
+ and if they have <code class="literal">NOT NULL</code> constraints in the parent
+ then they must also have <code class="literal">NOT NULL</code> constraints in the
+ child.
+ </p><p>
+ There must also be matching child-table constraints for all
+ <code class="literal">CHECK</code> constraints of the parent, except those
+ marked non-inheritable (that is, created with <code class="literal">ALTER TABLE ... ADD CONSTRAINT ... NO INHERIT</code>)
+ in the parent, which are ignored; all child-table constraints matched
+ must not be marked non-inheritable.
+ Currently
+ <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY KEY</code>, and
+ <code class="literal">FOREIGN KEY</code> constraints are not considered, but
+ this might change in the future.
+ </p></dd><dt><span class="term"><code class="literal">NO INHERIT <em class="replaceable"><code>parent_table</code></em></code></span></dt><dd><p>
+ This form removes the target table from the list of children of the
+ specified parent table.
+ Queries against the parent table will no longer include records drawn
+ from the target table.
+ </p></dd><dt><span class="term"><code class="literal">OF <em class="replaceable"><code>type_name</code></em></code></span></dt><dd><p>
+ This form links the table to a composite type as though <code class="command">CREATE
+ TABLE OF</code> had formed it. The table's list of column names and types
+ must precisely match that of the composite type. The table must
+ not inherit from any other table. These restrictions ensure
+ that <code class="command">CREATE TABLE OF</code> would permit an equivalent table
+ definition.
+ </p></dd><dt><span class="term"><code class="literal">NOT OF</code></span></dt><dd><p>
+ This form dissociates a typed table from its type.
+ </p></dd><dt><span class="term"><code class="literal">OWNER TO</code></span></dt><dd><p>
+ This form changes the owner of the table, sequence, view, materialized view,
+ or foreign table to the specified user.
+ </p></dd><dt id="SQL-ALTERTABLE-REPLICA-IDENTITY"><span class="term"><code class="literal">REPLICA IDENTITY</code></span></dt><dd><p>
+ This form changes the information which is written to the write-ahead log
+ to identify rows which are updated or deleted.
+ In most cases, the old value of each column is only logged if it differs
+ from the new value; however, if the old value is stored externally, it is
+ always logged regardless of whether it changed.
+ This option has no effect except when logical replication is in use.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Records the old values of the columns of the primary key, if any.
+ This is the default for non-system tables.
+ </p></dd><dt><span class="term"><code class="literal">USING INDEX <em class="replaceable"><code>index_name</code></em></code></span></dt><dd><p>
+ Records the old values of the columns covered by the named index,
+ that must be unique, not partial, not deferrable, and include only
+ columns marked <code class="literal">NOT NULL</code>. If this index is
+ dropped, the behavior is the same as <code class="literal">NOTHING</code>.
+ </p></dd><dt><span class="term"><code class="literal">FULL</code></span></dt><dd><p>
+ Records the old values of all columns in the row.
+ </p></dd><dt><span class="term"><code class="literal">NOTHING</code></span></dt><dd><p>
+ Records no information about the old row. This is the default for
+ system tables.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="literal">RENAME</code></span></dt><dd><p>
+ The <code class="literal">RENAME</code> forms change the name of a table
+ (or an index, sequence, view, materialized view, or foreign table), the
+ name of an individual column in a table, or the name of a constraint of
+ the table. When renaming a constraint that has an underlying index,
+ the index is renamed as well.
+ There is no effect on the stored data.
+ </p></dd><dt><span class="term"><code class="literal">SET SCHEMA</code></span></dt><dd><p>
+ This form moves the table into another schema. Associated indexes,
+ constraints, and sequences owned by table columns are moved as well.
+ </p></dd><dt id="SQL-ALTERTABLE-ATTACH-PARTITION"><span class="term"><code class="literal">ATTACH PARTITION <em class="replaceable"><code>partition_name</code></em> { FOR VALUES <em class="replaceable"><code>partition_bound_spec</code></em> | DEFAULT }</code></span></dt><dd><p>
+ This form attaches an existing table (which might itself be partitioned)
+ as a partition of the target table. The table can be attached
+ as a partition for specific values using <code class="literal">FOR VALUES</code>
+ or as a default partition by using <code class="literal">DEFAULT</code>.
+ For each index in the target table, a corresponding
+ one will be created in the attached table; or, if an equivalent
+ index already exists, it will be attached to the target table's index,
+ as if <code class="command">ALTER INDEX ATTACH PARTITION</code> had been executed.
+ Note that if the existing table is a foreign table, it is currently not
+ allowed to attach the table as a partition of the target table if there
+ are <code class="literal">UNIQUE</code> indexes on the target table. (See also
+ <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>.) For each user-defined
+ row-level trigger that exists in the target table, a corresponding one
+ is created in the attached table.
+ </p><p>
+ A partition using <code class="literal">FOR VALUES</code> uses same syntax for
+ <em class="replaceable"><code>partition_bound_spec</code></em> as
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>. The partition bound specification
+ must correspond to the partitioning strategy and partition key of the
+ target table. The table to be attached must have all the same columns
+ as the target table and no more; moreover, the column types must also
+ match. Also, it must have all the <code class="literal">NOT NULL</code> and
+ <code class="literal">CHECK</code> constraints of the target table. Currently
+ <code class="literal">FOREIGN KEY</code> constraints are not considered.
+ <code class="literal">UNIQUE</code> and <code class="literal">PRIMARY KEY</code> constraints
+ from the parent table will be created in the partition, if they don't
+ already exist.
+ If any of the <code class="literal">CHECK</code> constraints of the table being
+ attached are marked <code class="literal">NO INHERIT</code>, the command will fail;
+ such constraints must be recreated without the
+ <code class="literal">NO INHERIT</code> clause.
+ </p><p>
+ If the new partition is a regular table, a full table scan is performed
+ to check that existing rows in the table do not violate the partition
+ constraint. It is possible to avoid this scan by adding a valid
+ <code class="literal">CHECK</code> constraint to the table that allows only
+ rows satisfying the desired partition constraint before running this
+ command. The <code class="literal">CHECK</code> constraint will be used to
+ determine that the table need not be scanned to validate the partition
+ constraint. This does not work, however, if any of the partition keys
+ is an expression and the partition does not accept
+ <code class="literal">NULL</code> values. If attaching a list partition that will
+ not accept <code class="literal">NULL</code> values, also add a
+ <code class="literal">NOT NULL</code> constraint to the partition key column,
+ unless it's an expression.
+ </p><p>
+ If the new partition is a foreign table, nothing is done to verify
+ that all the rows in the foreign table obey the partition constraint.
+ (See the discussion in <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a> about
+ constraints on the foreign table.)
+ </p><p>
+ When a table has a default partition, defining a new partition changes
+ the partition constraint for the default partition. The default
+ partition can't contain any rows that would need to be moved to the new
+ partition, and will be scanned to verify that none are present. This
+ scan, like the scan of the new partition, can be avoided if an
+ appropriate <code class="literal">CHECK</code> constraint is present. Also like
+ the scan of the new partition, it is always skipped when the default
+ partition is a foreign table.
+ </p><p>
+ Attaching a partition acquires a
+ <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock on the parent table,
+ in addition to the <code class="literal">ACCESS EXCLUSIVE</code> locks on the table
+ being attached and on the default partition (if any).
+ </p><p>
+ Further locks must also be held on all sub-partitions if the table being
+ attached is itself a partitioned table. Likewise if the default
+ partition is itself a partitioned table. The locking of the
+ sub-partitions can be avoided by adding a <code class="literal">CHECK</code>
+ constraint as described in
+ <a class="xref" href="ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE-MAINTENANCE" title="5.11.2.2. Partition Maintenance">Section 5.11.2.2</a>.
+ </p></dd><dt id="SQL-ALTERTABLE-DETACH-PARTITION"><span class="term"><code class="literal">DETACH PARTITION <em class="replaceable"><code>partition_name</code></em> [ CONCURRENTLY | FINALIZE ]</code></span></dt><dd><p>
+ This form detaches the specified partition of the target table. The detached
+ partition continues to exist as a standalone table, but no longer has any
+ ties to the table from which it was detached. Any indexes that were
+ attached to the target table's indexes are detached. Any triggers that
+ were created as clones of those in the target table are removed.
+ <code class="literal">SHARE</code> lock is obtained on any tables that reference
+ this partitioned table in foreign key constraints.
+ </p><p>
+ If <code class="literal">CONCURRENTLY</code> is specified, it runs using a reduced
+ lock level to avoid blocking other sessions that might be accessing the
+ partitioned table. In this mode, two transactions are used internally.
+ During the first transaction, a <code class="literal">SHARE UPDATE EXCLUSIVE</code>
+ lock is taken on both parent table and partition, and the partition is
+ marked as undergoing detach; at that point, the transaction is committed
+ and all other transactions using the partitioned table are waited for.
+ Once all those transactions have completed, the second transaction
+ acquires <code class="literal">SHARE UPDATE EXCLUSIVE</code> on the partitioned
+ table and <code class="literal">ACCESS EXCLUSIVE</code> on the partition,
+ and the detach process completes. A <code class="literal">CHECK</code> constraint
+ that duplicates the partition constraint is added to the partition.
+ <code class="literal">CONCURRENTLY</code> cannot be run in a transaction block and
+ is not allowed if the partitioned table contains a default partition.
+ </p><p>
+ If <code class="literal">FINALIZE</code> is specified, a previous
+ <code class="literal">DETACH CONCURRENTLY</code> invocation that was canceled or
+ interrupted is completed.
+ At most one partition in a partitioned table can be pending detach at
+ a time.
+ </p></dd></dl></div><p>
+ </p><p>
+ All the forms of ALTER TABLE that act on a single table, except
+ <code class="literal">RENAME</code>, <code class="literal">SET SCHEMA</code>,
+ <code class="literal">ATTACH PARTITION</code>, and
+ <code class="literal">DETACH PARTITION</code> can be combined into
+ a list of multiple alterations to be applied together. For example, it
+ is possible to add several columns and/or alter the type of several
+ columns in a single command. This is particularly useful with large
+ tables, since only one pass over the table need be made.
+ </p><p>
+ You must own the table to use <code class="command">ALTER TABLE</code>.
+ To change the schema or tablespace of a table, you must also have
+ <code class="literal">CREATE</code> privilege on the new schema or tablespace.
+ To add the table as a new child of a parent table, you must own the parent
+ table as well. Also, to attach a table as a new partition of the table,
+ you must own the table being attached.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the table's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the table.
+ However, a superuser can alter ownership of any table anyway.)
+ To add a column or alter a column type or use the <code class="literal">OF</code>
+ clause, you must also have <code class="literal">USAGE</code> privilege on the data
+ type.
+ </p></div><div class="refsect1" id="id-1.9.3.35.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the table does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing table to
+ alter. If <code class="literal">ONLY</code> is specified before the table name, only
+ that table is altered. If <code class="literal">ONLY</code> is not specified, the table
+ and all its descendant tables (if any) are altered. Optionally,
+ <code class="literal">*</code> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ Name of a new or existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_column_name</code></em></span></dt><dd><p>
+ New name for an existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ New name for the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ Data type of the new column, or new data type for an existing
+ column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_constraint</code></em></span></dt><dd><p>
+ New table constraint for the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>constraint_name</code></em></span></dt><dd><p>
+ Name of a new or existing constraint.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the dropped column
+ or constraint (for example, views referencing the column),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the column or constraint if there are any dependent
+ objects. This is the default behavior.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>trigger_name</code></em></span></dt><dd><p>
+ Name of a single trigger to disable or enable.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Disable or enable all triggers belonging to the table.
+ (This requires superuser privilege if any of the triggers are
+ internally generated constraint triggers, such as those that are used
+ to implement foreign key constraints or deferrable uniqueness and
+ exclusion constraints.)
+ </p></dd><dt><span class="term"><code class="literal">USER</code></span></dt><dd><p>
+ Disable or enable all triggers belonging to the table except for
+ internally generated constraint triggers, such as those that are used
+ to implement foreign key constraints or deferrable uniqueness and
+ exclusion constraints.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_name</code></em></span></dt><dd><p>
+ The name of an existing index.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>storage_parameter</code></em></span></dt><dd><p>
+ The name of a table storage parameter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ The new value for a table storage parameter.
+ This might be a number or a word depending on the parameter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>parent_table</code></em></span></dt><dd><p>
+ A parent table to associate or de-associate with this table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_access_method</code></em></span></dt><dd><p>
+ The name of the access method to which the table will be converted.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_tablespace</code></em></span></dt><dd><p>
+ The name of the tablespace to which the table will be moved.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The name of the schema to which the table will be moved.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>partition_name</code></em></span></dt><dd><p>
+ The name of the table to attach as a new partition or to detach from this table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>partition_bound_spec</code></em></span></dt><dd><p>
+ The partition bound specification for a new partition. Refer to
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for more details on the syntax of the same.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-ALTERTABLE-NOTES"><h2>Notes</h2><p>
+ The key word <code class="literal">COLUMN</code> is noise and can be omitted.
+ </p><p>
+ When a column is added with <code class="literal">ADD COLUMN</code> and a
+ non-volatile <code class="literal">DEFAULT</code> is specified, the default is
+ evaluated at the time of the statement and the result stored in the
+ table's metadata. That value will be used for the column for all existing
+ rows. If no <code class="literal">DEFAULT</code> is specified, NULL is used. In
+ neither case is a rewrite of the table required.
+ </p><p>
+ Adding a column with a volatile <code class="literal">DEFAULT</code> or
+ changing the type of an existing column will require the entire table and
+ its indexes to be rewritten. As an exception, when changing the type of an
+ existing column, if the <code class="literal">USING</code> clause does not change
+ the column contents and the old type is either binary coercible to the new
+ type or an unconstrained domain over the new type, a table rewrite is not
+ needed. However, indexes must always be rebuilt unless the system can
+ verify that the new index would be logically equivalent to the existing
+ one. For example, if the collation for a column has been changed, an index
+ rebuild is always required because the new sort order might be different.
+ However, in the absence of a collation change, a column can be changed
+ from <code class="type">text</code> to <code class="type">varchar</code> (or vice versa) without
+ rebuilding the indexes because these data types sort identically.
+ Table and/or index rebuilds may take a
+ significant amount of time for a large table; and will temporarily require
+ as much as double the disk space.
+ </p><p>
+ Adding a <code class="literal">CHECK</code> or <code class="literal">NOT NULL</code> constraint requires
+ scanning the table to verify that existing rows meet the constraint,
+ but does not require a table rewrite.
+ </p><p>
+ Similarly, when attaching a new partition it may be scanned to verify that
+ existing rows meet the partition constraint.
+ </p><p>
+ The main reason for providing the option to specify multiple changes
+ in a single <code class="command">ALTER TABLE</code> is that multiple table scans or
+ rewrites can thereby be combined into a single pass over the table.
+ </p><p>
+ Scanning a large table to verify a new foreign key or check constraint
+ can take a long time, and other updates to the table are locked out
+ until the <code class="command">ALTER TABLE ADD CONSTRAINT</code> command is
+ committed. The main purpose of the <code class="literal">NOT VALID</code>
+ constraint option is to reduce the impact of adding a constraint on
+ concurrent updates. With <code class="literal">NOT VALID</code>,
+ the <code class="command">ADD CONSTRAINT</code> command does not scan the table
+ and can be committed immediately. After that, a <code class="literal">VALIDATE
+ CONSTRAINT</code> command can be issued to verify that existing rows
+ satisfy the constraint. The validation step does not need to lock out
+ concurrent updates, since it knows that other transactions will be
+ enforcing the constraint for rows that they insert or update; only
+ pre-existing rows need to be checked. Hence, validation acquires only
+ a <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock on the table being
+ altered. (If the constraint is a foreign key then a <code class="literal">ROW
+ SHARE</code> lock is also required on the table referenced by the
+ constraint.) In addition to improving concurrency, it can be useful to
+ use <code class="literal">NOT VALID</code> and <code class="literal">VALIDATE
+ CONSTRAINT</code> in cases where the table is known to contain
+ pre-existing violations. Once the constraint is in place, no new
+ violations can be inserted, and the existing problems can be corrected
+ at leisure until <code class="literal">VALIDATE CONSTRAINT</code> finally
+ succeeds.
+ </p><p>
+ The <code class="literal">DROP COLUMN</code> form does not physically remove
+ the column, but simply makes it invisible to SQL operations. Subsequent
+ insert and update operations in the table will store a null value for the
+ column. Thus, dropping a column is quick but it will not immediately
+ reduce the on-disk size of your table, as the space occupied
+ by the dropped column is not reclaimed. The space will be
+ reclaimed over time as existing rows are updated.
+ </p><p>
+ To force immediate reclamation of space occupied by a dropped column,
+ you can execute one of the forms of <code class="command">ALTER TABLE</code> that
+ performs a rewrite of the whole table. This results in reconstructing
+ each row with the dropped column replaced by a null value.
+ </p><p>
+ The rewriting forms of <code class="command">ALTER TABLE</code> are not MVCC-safe.
+ After a table rewrite, the table will appear empty to concurrent
+ transactions, if they are using a snapshot taken before the rewrite
+ occurred. See <a class="xref" href="mvcc-caveats.html" title="13.6. Caveats">Section 13.6</a> for more details.
+ </p><p>
+ The <code class="literal">USING</code> option of <code class="literal">SET DATA TYPE</code> can actually
+ specify any expression involving the old values of the row; that is, it
+ can refer to other columns as well as the one being converted. This allows
+ very general conversions to be done with the <code class="literal">SET DATA TYPE</code>
+ syntax. Because of this flexibility, the <code class="literal">USING</code>
+ expression is not applied to the column's default value (if any); the
+ result might not be a constant expression as required for a default.
+ This means that when there is no implicit or assignment cast from old to
+ new type, <code class="literal">SET DATA TYPE</code> might fail to convert the default even
+ though a <code class="literal">USING</code> clause is supplied. In such cases,
+ drop the default with <code class="literal">DROP DEFAULT</code>, perform the <code class="literal">ALTER
+ TYPE</code>, and then use <code class="literal">SET DEFAULT</code> to add a suitable new
+ default. Similar considerations apply to indexes and constraints involving
+ the column.
+ </p><p>
+ If a table has any descendant tables, it is not permitted to add,
+ rename, or change the type of a column in the parent table without doing
+ the same to the descendants. This ensures that the descendants always
+ have columns matching the parent. Similarly, a <code class="literal">CHECK</code>
+ constraint cannot be renamed in the parent without also renaming it in
+ all descendants, so that <code class="literal">CHECK</code> constraints also match
+ between the parent and its descendants. (That restriction does not apply
+ to index-based constraints, however.)
+ Also, because selecting from the parent also selects from its descendants,
+ a constraint on the parent cannot be marked valid unless it is also marked
+ valid for those descendants. In all of these cases, <code class="command">ALTER TABLE
+ ONLY</code> will be rejected.
+ </p><p>
+ A recursive <code class="literal">DROP COLUMN</code> operation will remove a
+ descendant table's column only if the descendant does not inherit
+ that column from any other parents and never had an independent
+ definition of the column. A nonrecursive <code class="literal">DROP
+ COLUMN</code> (i.e., <code class="command">ALTER TABLE ONLY ... DROP
+ COLUMN</code>) never removes any descendant columns, but
+ instead marks them as independently defined rather than inherited.
+ A nonrecursive <code class="literal">DROP COLUMN</code> command will fail for a
+ partitioned table, because all partitions of a table must have the same
+ columns as the partitioning root.
+ </p><p>
+ The actions for identity columns (<code class="literal">ADD
+ GENERATED</code>, <code class="literal">SET</code> etc., <code class="literal">DROP
+ IDENTITY</code>), as well as the actions
+ <code class="literal">CLUSTER</code>, <code class="literal">OWNER</code>,
+ and <code class="literal">TABLESPACE</code> never recurse to descendant tables;
+ that is, they always act as though <code class="literal">ONLY</code> were specified.
+ Actions affecting trigger states recurse to partitions of partitioned
+ tables (unless <code class="literal">ONLY</code> is specified), but never to
+ traditional-inheritance descendants.
+ Adding a constraint recurses only for <code class="literal">CHECK</code> constraints
+ that are not marked <code class="literal">NO INHERIT</code>.
+ </p><p>
+ Changing any part of a system catalog table is not permitted.
+ </p><p>
+ Refer to <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for a further description of valid
+ parameters. <a class="xref" href="ddl.html" title="Chapter 5. Data Definition">Chapter 5</a> has further information on
+ inheritance.
+ </p></div><div class="refsect1" id="id-1.9.3.35.8"><h2>Examples</h2><p>
+ To add a column of type <code class="type">varchar</code> to a table:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD COLUMN address varchar(30);
+</pre><p>
+ That will cause all existing rows in the table to be filled with null
+ values for the new column.
+ </p><p>
+ To add a column with a non-null default:
+</p><pre class="programlisting">
+ALTER TABLE measurements
+ ADD COLUMN mtime timestamp with time zone DEFAULT now();
+</pre><p>
+ Existing rows will be filled with the current time as the value of the
+ new column, and then new rows will receive the time of their insertion.
+ </p><p>
+ To add a column and fill it with a value different from the default to
+ be used later:
+</p><pre class="programlisting">
+ALTER TABLE transactions
+ ADD COLUMN status varchar(30) DEFAULT 'old',
+ ALTER COLUMN status SET default 'current';
+</pre><p>
+ Existing rows will be filled with <code class="literal">old</code>, but then
+ the default for subsequent commands will be <code class="literal">current</code>.
+ The effects are the same as if the two sub-commands had been issued
+ in separate <code class="command">ALTER TABLE</code> commands.
+ </p><p>
+ To drop a column from a table:
+</p><pre class="programlisting">
+ALTER TABLE distributors DROP COLUMN address RESTRICT;
+</pre><p>
+ </p><p>
+ To change the types of two existing columns in one operation:
+</p><pre class="programlisting">
+ALTER TABLE distributors
+ ALTER COLUMN address TYPE varchar(80),
+ ALTER COLUMN name TYPE varchar(100);
+</pre><p>
+ </p><p>
+ To change an integer column containing Unix timestamps to <code class="type">timestamp
+ with time zone</code> via a <code class="literal">USING</code> clause:
+</p><pre class="programlisting">
+ALTER TABLE foo
+ ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
+ USING
+ timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';
+</pre><p>
+ </p><p>
+ The same, when the column has a default expression that won't automatically
+ cast to the new data type:
+</p><pre class="programlisting">
+ALTER TABLE foo
+ ALTER COLUMN foo_timestamp DROP DEFAULT,
+ ALTER COLUMN foo_timestamp TYPE timestamp with time zone
+ USING
+ timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
+ ALTER COLUMN foo_timestamp SET DEFAULT now();
+</pre><p>
+ </p><p>
+ To rename an existing column:
+</p><pre class="programlisting">
+ALTER TABLE distributors RENAME COLUMN address TO city;
+</pre><p>
+ </p><p>
+ To rename an existing table:
+</p><pre class="programlisting">
+ALTER TABLE distributors RENAME TO suppliers;
+</pre><p>
+ </p><p>
+ To rename an existing constraint:
+</p><pre class="programlisting">
+ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
+</pre><p>
+ </p><p>
+ To add a not-null constraint to a column:
+</p><pre class="programlisting">
+ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
+</pre><p>
+ To remove a not-null constraint from a column:
+</p><pre class="programlisting">
+ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
+</pre><p>
+ </p><p>
+ To add a check constraint to a table and all its children:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
+</pre><p>
+ </p><p>
+ To add a check constraint only to a table and not to its children:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;
+</pre><p>
+ (The check constraint will not be inherited by future children, either.)
+ </p><p>
+ To remove a check constraint from a table and all its children:
+</p><pre class="programlisting">
+ALTER TABLE distributors DROP CONSTRAINT zipchk;
+</pre><p>
+ </p><p>
+ To remove a check constraint from one table only:
+</p><pre class="programlisting">
+ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
+</pre><p>
+ (The check constraint remains in place for any child tables.)
+ </p><p>
+ To add a foreign key constraint to a table:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address);
+</pre><p>
+ </p><p>
+ To add a foreign key constraint to a table with the least impact on other work:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) NOT VALID;
+ALTER TABLE distributors VALIDATE CONSTRAINT distfk;
+</pre><p>
+ </p><p>
+ To add a (multicolumn) unique constraint to a table:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
+</pre><p>
+ </p><p>
+ To add an automatically named primary key constraint to a table, noting
+ that a table can only ever have one primary key:
+</p><pre class="programlisting">
+ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
+</pre><p>
+ </p><p>
+ To move a table to a different tablespace:
+</p><pre class="programlisting">
+ALTER TABLE distributors SET TABLESPACE fasttablespace;
+</pre><p>
+ </p><p>
+ To move a table to a different schema:
+</p><pre class="programlisting">
+ALTER TABLE myschema.distributors SET SCHEMA yourschema;
+</pre><p>
+ </p><p>
+ To recreate a primary key constraint, without blocking updates while the
+ index is rebuilt:
+</p><pre class="programlisting">
+CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
+ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
+ ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
+</pre><p>
+ To attach a partition to a range-partitioned table:
+</p><pre class="programlisting">
+ALTER TABLE measurement
+ ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
+</pre><p>
+ To attach a partition to a list-partitioned table:
+</p><pre class="programlisting">
+ALTER TABLE cities
+ ATTACH PARTITION cities_ab FOR VALUES IN ('a', 'b');
+</pre><p>
+ To attach a partition to a hash-partitioned table:
+</p><pre class="programlisting">
+ALTER TABLE orders
+ ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3);
+</pre><p>
+ To attach a default partition to a partitioned table:
+</p><pre class="programlisting">
+ALTER TABLE cities
+ ATTACH PARTITION cities_partdef DEFAULT;
+</pre><p>
+ To detach a partition from a partitioned table:
+</p><pre class="programlisting">
+ALTER TABLE measurement
+ DETACH PARTITION measurement_y2015m12;
+</pre></div><div class="refsect1" id="id-1.9.3.35.9"><h2>Compatibility</h2><p>
+ The forms <code class="literal">ADD</code> (without <code class="literal">USING INDEX</code>),
+ <code class="literal">DROP [COLUMN]</code>, <code class="literal">DROP IDENTITY</code>, <code class="literal">RESTART</code>,
+ <code class="literal">SET DEFAULT</code>, <code class="literal">SET DATA TYPE</code> (without <code class="literal">USING</code>),
+ <code class="literal">SET GENERATED</code>, and <code class="literal">SET <em class="replaceable"><code>sequence_option</code></em></code>
+ conform with the SQL standard. The other forms are
+ <span class="productname">PostgreSQL</span> extensions of the SQL standard.
+ Also, the ability to specify more than one manipulation in a single
+ <code class="command">ALTER TABLE</code> command is an extension.
+ </p><p>
+ <code class="command">ALTER TABLE DROP COLUMN</code> can be used to drop the only
+ column of a table, leaving a zero-column table. This is an
+ extension of SQL, which disallows zero-column tables.
+ </p></div><div class="refsect1" id="id-1.9.3.35.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altersystem.html" title="ALTER SYSTEM">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertablespace.html" title="ALTER TABLESPACE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER SYSTEM </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TABLESPACE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertablespace.html b/doc/src/sgml/html/sql-altertablespace.html
new file mode 100644
index 0000000..87b101e
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertablespace.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TABLESPACE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertable.html" title="ALTER TABLE" /><link rel="next" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TABLESPACE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertable.html" title="ALTER TABLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTABLESPACE"><div class="titlepage"></div><a id="id-1.9.3.36.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TABLESPACE</span></h2><p>ALTER TABLESPACE — change the definition of a tablespace</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TABLESPACE <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TABLESPACE <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TABLESPACE <em class="replaceable"><code>name</code></em> SET ( <em class="replaceable"><code>tablespace_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )
+ALTER TABLESPACE <em class="replaceable"><code>name</code></em> RESET ( <em class="replaceable"><code>tablespace_option</code></em> [, ... ] )
+</pre></div><div class="refsect1" id="id-1.9.3.36.5"><h2>Description</h2><p>
+ <code class="command">ALTER TABLESPACE</code> can be used to change the definition of
+ a tablespace.
+ </p><p>
+ You must own the tablespace to change the definition of a tablespace.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role.
+ (Note that superusers have these privileges automatically.)
+ </p></div><div class="refsect1" id="id-1.9.3.36.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing tablespace.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the tablespace. The new name cannot
+ begin with <code class="literal">pg_</code>, as such names
+ are reserved for system tablespaces.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the tablespace.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>tablespace_option</code></em></span></dt><dd><p>
+ A tablespace parameter to be set or reset. Currently, the only
+ available parameters are <code class="varname">seq_page_cost</code>,
+ <code class="varname">random_page_cost</code>, <code class="varname">effective_io_concurrency</code>
+ and <code class="varname">maintenance_io_concurrency</code>.
+ Setting these values for a particular tablespace will override the
+ planner's usual estimate of the cost of reading pages from tables in
+ that tablespace, and the executor's prefetching behavior, as established
+ by the configuration parameters of the
+ same name (see <a class="xref" href="runtime-config-query.html#GUC-SEQ-PAGE-COST">seq_page_cost</a>,
+ <a class="xref" href="runtime-config-query.html#GUC-RANDOM-PAGE-COST">random_page_cost</a>,
+ <a class="xref" href="runtime-config-resource.html#GUC-EFFECTIVE-IO-CONCURRENCY">effective_io_concurrency</a>,
+ <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-IO-CONCURRENCY">maintenance_io_concurrency</a>). This may be useful if
+ one tablespace is located on a disk which is faster or slower than the
+ remainder of the I/O subsystem.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.36.7"><h2>Examples</h2><p>
+ Rename tablespace <code class="literal">index_space</code> to <code class="literal">fast_raid</code>:
+</p><pre class="programlisting">
+ALTER TABLESPACE index_space RENAME TO fast_raid;
+</pre><p>
+ </p><p>
+ Change the owner of tablespace <code class="literal">index_space</code>:
+</p><pre class="programlisting">
+ALTER TABLESPACE index_space OWNER TO mary;
+</pre></div><div class="refsect1" id="id-1.9.3.36.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER TABLESPACE</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.36.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a>, <a class="xref" href="sql-droptablespace.html" title="DROP TABLESPACE"><span class="refentrytitle">DROP TABLESPACE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertable.html" title="ALTER TABLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TABLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TEXT SEARCH CONFIGURATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertrigger.html b/doc/src/sgml/html/sql-altertrigger.html
new file mode 100644
index 0000000..233e535
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertrigger.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE" /><link rel="next" href="sql-altertype.html" title="ALTER TYPE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertype.html" title="ALTER TYPE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTRIGGER"><div class="titlepage"></div><a id="id-1.9.3.41.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TRIGGER</span></h2><p>ALTER TRIGGER — change the definition of a trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TRIGGER <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TRIGGER <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> [ NO ] DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.41.5"><h2>Description</h2><p>
+ <code class="command">ALTER TRIGGER</code> changes properties of an existing
+ trigger.
+ </p><p>
+ The <code class="literal">RENAME</code> clause changes the name of
+ the given trigger without otherwise changing the trigger
+ definition.
+ If the table that the trigger is on is a partitioned table,
+ then corresponding clone triggers in the partitions are
+ renamed too.
+ </p><p>
+ The <code class="literal">DEPENDS ON EXTENSION</code> clause marks
+ the trigger as dependent on an extension, such that if the extension is
+ dropped, the trigger will automatically be dropped as well.
+ </p><p>
+ You must own the table on which the trigger acts to be allowed to change its properties.
+ </p></div><div class="refsect1" id="id-1.9.3.41.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing trigger to alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name of the table on which this trigger acts.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the trigger.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>extension_name</code></em></span></dt><dd><p>
+ The name of the extension that the trigger is to depend on (or no longer
+ dependent on, if <code class="literal">NO</code> is specified). A trigger
+ that's marked as dependent on an extension is automatically dropped when
+ the extension is dropped.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.41.7"><h2>Notes</h2><p>
+ The ability to temporarily enable or disable a trigger is provided by
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a>, not by
+ <code class="command">ALTER TRIGGER</code>, because <code class="command">ALTER TRIGGER</code> has no
+ convenient way to express the option of enabling or disabling all of
+ a table's triggers at once.
+ </p></div><div class="refsect1" id="id-1.9.3.41.8"><h2>Examples</h2><p>
+ To rename an existing trigger:
+</p><pre class="programlisting">
+ALTER TRIGGER emp_stamp ON emp RENAME TO emp_track_chgs;
+</pre><p>
+ To mark a trigger as being dependent on an extension:
+</p><pre class="programlisting">
+ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib;
+</pre></div><div class="refsect1" id="id-1.9.3.41.9"><h2>Compatibility</h2><p>
+ <code class="command">ALTER TRIGGER</code> is a <span class="productname">PostgreSQL</span>
+ extension of the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.41.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertype.html" title="ALTER TYPE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TEXT SEARCH TEMPLATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TYPE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertsconfig.html b/doc/src/sgml/html/sql-altertsconfig.html
new file mode 100644
index 0000000..05cb5fa
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertsconfig.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TEXT SEARCH CONFIGURATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertablespace.html" title="ALTER TABLESPACE" /><link rel="next" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TEXT SEARCH CONFIGURATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertablespace.html" title="ALTER TABLESPACE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTSCONFIG"><div class="titlepage"></div><a id="id-1.9.3.37.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TEXT SEARCH CONFIGURATION</span></h2><p>ALTER TEXT SEARCH CONFIGURATION — change the definition of a text search configuration</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em>
+ ADD MAPPING FOR <em class="replaceable"><code>token_type</code></em> [, ... ] WITH <em class="replaceable"><code>dictionary_name</code></em> [, ... ]
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em>
+ ALTER MAPPING FOR <em class="replaceable"><code>token_type</code></em> [, ... ] WITH <em class="replaceable"><code>dictionary_name</code></em> [, ... ]
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em>
+ ALTER MAPPING REPLACE <em class="replaceable"><code>old_dictionary</code></em> WITH <em class="replaceable"><code>new_dictionary</code></em>
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em>
+ ALTER MAPPING FOR <em class="replaceable"><code>token_type</code></em> [, ... ] REPLACE <em class="replaceable"><code>old_dictionary</code></em> WITH <em class="replaceable"><code>new_dictionary</code></em>
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em>
+ DROP MAPPING [ IF EXISTS ] FOR <em class="replaceable"><code>token_type</code></em> [, ... ]
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.37.5"><h2>Description</h2><p>
+ <code class="command">ALTER TEXT SEARCH CONFIGURATION</code> changes the definition of
+ a text search configuration. You can modify
+ its mappings from token types to dictionaries,
+ or change the configuration's name or owner.
+ </p><p>
+ You must be the owner of the configuration to use
+ <code class="command">ALTER TEXT SEARCH CONFIGURATION</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.37.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search
+ configuration.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>token_type</code></em></span></dt><dd><p>
+ The name of a token type that is emitted by the configuration's
+ parser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>dictionary_name</code></em></span></dt><dd><p>
+ The name of a text search dictionary to be consulted for the
+ specified token type(s). If multiple dictionaries are listed,
+ they are consulted in the specified order.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>old_dictionary</code></em></span></dt><dd><p>
+ The name of a text search dictionary to be replaced in the mapping.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_dictionary</code></em></span></dt><dd><p>
+ The name of a text search dictionary to be substituted for
+ <em class="replaceable"><code>old_dictionary</code></em>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the text search configuration.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the text search configuration.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the text search configuration.
+ </p></dd></dl></div><p>
+ The <code class="literal">ADD MAPPING FOR</code> form installs a list of dictionaries to be
+ consulted for the specified token type(s); it is an error if there is
+ already a mapping for any of the token types.
+ The <code class="literal">ALTER MAPPING FOR</code> form does the same, but first removing
+ any existing mapping for those token types.
+ The <code class="literal">ALTER MAPPING REPLACE</code> forms substitute <em class="replaceable"><code>new_dictionary</code></em> for <em class="replaceable"><code>old_dictionary</code></em> anywhere the latter appears.
+ This is done for only the specified token types when <code class="literal">FOR</code>
+ appears, or for all mappings of the configuration when it doesn't.
+ The <code class="literal">DROP MAPPING</code> form removes all dictionaries for the
+ specified token type(s), causing tokens of those types to be ignored
+ by the text search configuration. It is an error if there is no mapping
+ for the token types, unless <code class="literal">IF EXISTS</code> appears.
+ </p></div><div class="refsect1" id="id-1.9.3.37.7"><h2>Examples</h2><p>
+ The following example replaces the <code class="literal">english</code> dictionary
+ with the <code class="literal">swedish</code> dictionary anywhere that <code class="literal">english</code>
+ is used within <code class="literal">my_config</code>.
+ </p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION my_config
+ ALTER MAPPING REPLACE english WITH swedish;
+</pre></div><div class="refsect1" id="id-1.9.3.37.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER TEXT SEARCH CONFIGURATION</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.37.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION"><span class="refentrytitle">CREATE TEXT SEARCH CONFIGURATION</span></a>, <a class="xref" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION"><span class="refentrytitle">DROP TEXT SEARCH CONFIGURATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertablespace.html" title="ALTER TABLESPACE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TABLESPACE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TEXT SEARCH DICTIONARY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertsdictionary.html b/doc/src/sgml/html/sql-altertsdictionary.html
new file mode 100644
index 0000000..091ad86
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertsdictionary.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TEXT SEARCH DICTIONARY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION" /><link rel="next" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TEXT SEARCH DICTIONARY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTSDICTIONARY"><div class="titlepage"></div><a id="id-1.9.3.38.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TEXT SEARCH DICTIONARY</span></h2><p>ALTER TEXT SEARCH DICTIONARY — change the definition of a text search dictionary</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TEXT SEARCH DICTIONARY <em class="replaceable"><code>name</code></em> (
+ <em class="replaceable"><code>option</code></em> [ = <em class="replaceable"><code>value</code></em> ] [, ... ]
+)
+ALTER TEXT SEARCH DICTIONARY <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TEXT SEARCH DICTIONARY <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TEXT SEARCH DICTIONARY <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.38.5"><h2>Description</h2><p>
+ <code class="command">ALTER TEXT SEARCH DICTIONARY</code> changes the definition of
+ a text search dictionary. You can change the dictionary's
+ template-specific options, or change the dictionary's name or owner.
+ </p><p>
+ You must be the owner of the dictionary to use
+ <code class="command">ALTER TEXT SEARCH DICTIONARY</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.38.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search
+ dictionary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>option</code></em></span></dt><dd><p>
+ The name of a template-specific option to be set for this dictionary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ The new value to use for a template-specific option.
+ If the equal sign and value are omitted, then any previous
+ setting for the option is removed from the dictionary,
+ allowing the default to be used.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the text search dictionary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The new owner of the text search dictionary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the text search dictionary.
+ </p></dd></dl></div><p>
+ Template-specific options can appear in any order.
+ </p></div><div class="refsect1" id="id-1.9.3.38.7"><h2>Examples</h2><p>
+ The following example command changes the stopword list
+ for a Snowball-based dictionary. Other parameters remain unchanged.
+ </p><pre class="programlisting">
+ALTER TEXT SEARCH DICTIONARY my_dict ( StopWords = newrussian );
+</pre><p>
+ The following example command changes the language option to <code class="literal">dutch</code>,
+ and removes the stopword option entirely.
+ </p><pre class="programlisting">
+ALTER TEXT SEARCH DICTIONARY my_dict ( language = dutch, StopWords );
+</pre><p>
+ The following example command <span class="quote">“<span class="quote">updates</span>”</span> the dictionary's
+ definition without actually changing anything.
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH DICTIONARY my_dict ( dummy );
+</pre><p>
+
+ (The reason this works is that the option removal code doesn't complain
+ if there is no such option.) This trick is useful when changing
+ configuration files for the dictionary: the <code class="command">ALTER</code> will
+ force existing database sessions to re-read the configuration files,
+ which otherwise they would never do if they had read them earlier.
+ </p></div><div class="refsect1" id="id-1.9.3.38.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER TEXT SEARCH DICTIONARY</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.38.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY"><span class="refentrytitle">CREATE TEXT SEARCH DICTIONARY</span></a>, <a class="xref" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY"><span class="refentrytitle">DROP TEXT SEARCH DICTIONARY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TEXT SEARCH CONFIGURATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TEXT SEARCH PARSER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertsparser.html b/doc/src/sgml/html/sql-altertsparser.html
new file mode 100644
index 0000000..76331a3
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertsparser.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TEXT SEARCH PARSER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY" /><link rel="next" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TEXT SEARCH PARSER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTSPARSER"><div class="titlepage"></div><a id="id-1.9.3.39.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TEXT SEARCH PARSER</span></h2><p>ALTER TEXT SEARCH PARSER — change the definition of a text search parser</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TEXT SEARCH PARSER <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TEXT SEARCH PARSER <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.39.5"><h2>Description</h2><p>
+ <code class="command">ALTER TEXT SEARCH PARSER</code> changes the definition of
+ a text search parser. Currently, the only supported functionality
+ is to change the parser's name.
+ </p><p>
+ You must be a superuser to use <code class="command">ALTER TEXT SEARCH PARSER</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.39.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search parser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the text search parser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the text search parser.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.39.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER TEXT SEARCH PARSER</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.39.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER"><span class="refentrytitle">CREATE TEXT SEARCH PARSER</span></a>, <a class="xref" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER"><span class="refentrytitle">DROP TEXT SEARCH PARSER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TEXT SEARCH DICTIONARY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TEXT SEARCH TEMPLATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertstemplate.html b/doc/src/sgml/html/sql-altertstemplate.html
new file mode 100644
index 0000000..f844e6a
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertstemplate.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TEXT SEARCH TEMPLATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER" /><link rel="next" href="sql-altertrigger.html" title="ALTER TRIGGER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TEXT SEARCH TEMPLATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-altertrigger.html" title="ALTER TRIGGER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTSTEMPLATE"><div class="titlepage"></div><a id="id-1.9.3.40.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TEXT SEARCH TEMPLATE</span></h2><p>ALTER TEXT SEARCH TEMPLATE — change the definition of a text search template</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TEXT SEARCH TEMPLATE <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TEXT SEARCH TEMPLATE <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.40.5"><h2>Description</h2><p>
+ <code class="command">ALTER TEXT SEARCH TEMPLATE</code> changes the definition of
+ a text search template. Currently, the only supported functionality
+ is to change the template's name.
+ </p><p>
+ You must be a superuser to use <code class="command">ALTER TEXT SEARCH TEMPLATE</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.40.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search template.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name of the text search template.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the text search template.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.40.7"><h2>Compatibility</h2><p>
+ There is no <code class="command">ALTER TEXT SEARCH TEMPLATE</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.40.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE"><span class="refentrytitle">CREATE TEXT SEARCH TEMPLATE</span></a>, <a class="xref" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE"><span class="refentrytitle">DROP TEXT SEARCH TEMPLATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-altertrigger.html" title="ALTER TRIGGER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TEXT SEARCH PARSER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER TRIGGER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-altertype.html b/doc/src/sgml/html/sql-altertype.html
new file mode 100644
index 0000000..db213a8
--- /dev/null
+++ b/doc/src/sgml/html/sql-altertype.html
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER TYPE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertrigger.html" title="ALTER TRIGGER" /><link rel="next" href="sql-alteruser.html" title="ALTER USER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER TYPE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertrigger.html" title="ALTER TRIGGER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alteruser.html" title="ALTER USER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERTYPE"><div class="titlepage"></div><a id="id-1.9.3.42.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER TYPE</span></h2><p>ALTER TYPE —
+ change the definition of a type
+ </p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER TYPE <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TYPE <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER TYPE <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER TYPE <em class="replaceable"><code>name</code></em> RENAME ATTRIBUTE <em class="replaceable"><code>attribute_name</code></em> TO <em class="replaceable"><code>new_attribute_name</code></em> [ CASCADE | RESTRICT ]
+ALTER TYPE <em class="replaceable"><code>name</code></em> <em class="replaceable"><code>action</code></em> [, ... ]
+ALTER TYPE <em class="replaceable"><code>name</code></em> ADD VALUE [ IF NOT EXISTS ] <em class="replaceable"><code>new_enum_value</code></em> [ { BEFORE | AFTER } <em class="replaceable"><code>neighbor_enum_value</code></em> ]
+ALTER TYPE <em class="replaceable"><code>name</code></em> RENAME VALUE <em class="replaceable"><code>existing_enum_value</code></em> TO <em class="replaceable"><code>new_enum_value</code></em>
+ALTER TYPE <em class="replaceable"><code>name</code></em> SET ( <em class="replaceable"><code>property</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )
+
+<span class="phrase">where <em class="replaceable"><code>action</code></em> is one of:</span>
+
+ ADD ATTRIBUTE <em class="replaceable"><code>attribute_name</code></em> <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ CASCADE | RESTRICT ]
+ DROP ATTRIBUTE [ IF EXISTS ] <em class="replaceable"><code>attribute_name</code></em> [ CASCADE | RESTRICT ]
+ ALTER ATTRIBUTE <em class="replaceable"><code>attribute_name</code></em> [ SET DATA ] TYPE <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.42.5"><h2>Description</h2><p>
+ <code class="command">ALTER TYPE</code> changes the definition of an existing type.
+ There are several subforms:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">OWNER</code></span></dt><dd><p>
+ This form changes the owner of the type.
+ </p></dd><dt><span class="term"><code class="literal">RENAME</code></span></dt><dd><p>
+ This form changes the name of the type.
+ </p></dd><dt><span class="term"><code class="literal">SET SCHEMA</code></span></dt><dd><p>
+ This form moves the type into another schema.
+ </p></dd><dt><span class="term"><code class="literal">RENAME ATTRIBUTE</code></span></dt><dd><p>
+ This form is only usable with composite types.
+ It changes the name of an individual attribute of the type.
+ </p></dd><dt><span class="term"><code class="literal">ADD ATTRIBUTE</code></span></dt><dd><p>
+ This form adds a new attribute to a composite type, using the same syntax as
+ <a class="link" href="sql-createtype.html" title="CREATE TYPE"><code class="command">CREATE TYPE</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">DROP ATTRIBUTE [ IF EXISTS ]</code></span></dt><dd><p>
+ This form drops an attribute from a composite type.
+ If <code class="literal">IF EXISTS</code> is specified and the attribute
+ does not exist, no error is thrown. In this case a notice
+ is issued instead.
+ </p></dd><dt><span class="term"><code class="literal">ALTER ATTRIBUTE ... SET DATA TYPE</code></span></dt><dd><p>
+ This form changes the type of an attribute of a composite type.
+ </p></dd><dt><span class="term"><code class="literal">ADD VALUE [ IF NOT EXISTS ] [ BEFORE | AFTER ]</code></span></dt><dd><p>
+ This form adds a new value to an enum type. The new value's place in
+ the enum's ordering can be specified as being <code class="literal">BEFORE</code>
+ or <code class="literal">AFTER</code> one of the existing values. Otherwise,
+ the new item is added at the end of the list of values.
+ </p><p>
+ If <code class="literal">IF NOT EXISTS</code> is specified, it is not an error if
+ the type already contains the new value: a notice is issued but no other
+ action is taken. Otherwise, an error will occur if the new value is
+ already present.
+ </p></dd><dt><span class="term"><code class="literal">RENAME VALUE</code></span></dt><dd><p>
+ This form renames a value of an enum type.
+ The value's place in the enum's ordering is not affected.
+ An error will occur if the specified value is not present or the new
+ name is already present.
+ </p></dd><dt><span class="term">
+ <code class="literal">SET ( <em class="replaceable"><code>property</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] )</code>
+ </span></dt><dd><p>
+ This form is only applicable to base types. It allows adjustment of a
+ subset of the base-type properties that can be set in <code class="command">CREATE
+ TYPE</code>. Specifically, these properties can be changed:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">RECEIVE</code> can be set to the name of a binary input
+ function, or <code class="literal">NONE</code> to remove the type's binary
+ input function. Using this option requires superuser privilege.
+ </p></li><li class="listitem"><p>
+ <code class="literal">SEND</code> can be set to the name of a binary output
+ function, or <code class="literal">NONE</code> to remove the type's binary
+ output function. Using this option requires superuser privilege.
+ </p></li><li class="listitem"><p>
+ <code class="literal">TYPMOD_IN</code> can be set to the name of a type
+ modifier input function, or <code class="literal">NONE</code> to remove the
+ type's type modifier input function. Using this option requires
+ superuser privilege.
+ </p></li><li class="listitem"><p>
+ <code class="literal">TYPMOD_OUT</code> can be set to the name of a type
+ modifier output function, or <code class="literal">NONE</code> to remove the
+ type's type modifier output function. Using this option requires
+ superuser privilege.
+ </p></li><li class="listitem"><p>
+ <code class="literal">ANALYZE</code> can be set to the name of a type-specific
+ statistics collection function, or <code class="literal">NONE</code> to remove
+ the type's statistics collection function. Using this option
+ requires superuser privilege.
+ </p></li><li class="listitem"><p>
+ <code class="literal">SUBSCRIPT</code> can be set to the name of a type-specific
+ subscripting handler function, or <code class="literal">NONE</code> to remove
+ the type's subscripting handler function. Using this option
+ requires superuser privilege.
+ </p></li><li class="listitem"><p>
+ <code class="literal">STORAGE</code><a id="id-1.9.3.42.5.2.2.10.2.1.2.7.1.2" class="indexterm"></a>
+ can be set to <code class="literal">plain</code>,
+ <code class="literal">extended</code>, <code class="literal">external</code>,
+ or <code class="literal">main</code> (see <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a> for
+ more information about what these mean). However, changing
+ from <code class="literal">plain</code> to another setting requires superuser
+ privilege (because it requires that the type's C functions all be
+ TOAST-ready), and changing to <code class="literal">plain</code> from another
+ setting is not allowed at all (since the type may already have
+ TOASTed values present in the database). Note that changing this
+ option doesn't by itself change any stored data, it just sets the
+ default TOAST strategy to be used for table columns created in the
+ future. See <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a> to change the TOAST
+ strategy for existing table columns.
+ </p></li></ul></div><p>
+ See <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> for more details about these
+ type properties. Note that where appropriate, a change in these
+ properties for a base type will be propagated automatically to domains
+ based on that type.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <code class="literal">ADD ATTRIBUTE</code>, <code class="literal">DROP
+ ATTRIBUTE</code>, and <code class="literal">ALTER ATTRIBUTE</code> actions
+ can be combined into a list of multiple alterations to apply in
+ parallel. For example, it is possible to add several attributes
+ and/or alter the type of several attributes in a single command.
+ </p><p>
+ You must own the type to use <code class="command">ALTER TYPE</code>.
+ To change the schema of a type, you must also have
+ <code class="literal">CREATE</code> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the type's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the type.
+ However, a superuser can alter ownership of any type anyway.)
+ To add an attribute or alter an attribute type, you must also
+ have <code class="literal">USAGE</code> privilege on the attribute's data type.
+ </p></div><div class="refsect1" id="id-1.9.3.42.6"><h2>Parameters</h2><p>
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of an existing type to
+ alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>attribute_name</code></em></span></dt><dd><p>
+ The name of the attribute to add, alter, or drop.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_attribute_name</code></em></span></dt><dd><p>
+ The new name of the attribute to be renamed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The data type of the attribute to add, or the new type of the
+ attribute to alter.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_enum_value</code></em></span></dt><dd><p>
+ The new value to be added to an enum type's list of values,
+ or the new name to be given to an existing value.
+ Like all enum literals, it needs to be quoted.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>neighbor_enum_value</code></em></span></dt><dd><p>
+ The existing enum value that the new value should be added immediately
+ before or after in the enum type's sort ordering.
+ Like all enum literals, it needs to be quoted.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>existing_enum_value</code></em></span></dt><dd><p>
+ The existing enum value that should be renamed.
+ Like all enum literals, it needs to be quoted.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>property</code></em></span></dt><dd><p>
+ The name of a base-type property to be modified; see above for
+ possible values.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically propagate the operation to typed tables of the
+ type being altered, and their descendants.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse the operation if the type being altered is the type of a
+ typed table. This is the default.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.42.7"><h2>Notes</h2><p>
+ If <code class="command">ALTER TYPE ... ADD VALUE</code> (the form that adds a new
+ value to an enum type) is executed inside a transaction block, the new
+ value cannot be used until after the transaction has been committed.
+ </p><p>
+ Comparisons involving an added enum value will sometimes be slower than
+ comparisons involving only original members of the enum type. This will
+ usually only occur if <code class="literal">BEFORE</code> or <code class="literal">AFTER</code>
+ is used to set the new value's sort position somewhere other than at the
+ end of the list. However, sometimes it will happen even though the new
+ value is added at the end (this occurs if the OID counter <span class="quote">“<span class="quote">wrapped
+ around</span>”</span> since the original creation of the enum type). The slowdown is
+ usually insignificant; but if it matters, optimal performance can be
+ regained by dropping and recreating the enum type, or by dumping and
+ restoring the database.
+ </p></div><div class="refsect1" id="id-1.9.3.42.8"><h2>Examples</h2><p>
+ To rename a data type:
+</p><pre class="programlisting">
+ALTER TYPE electronic_mail RENAME TO email;
+</pre><p>
+ </p><p>
+ To change the owner of the type <code class="literal">email</code>
+ to <code class="literal">joe</code>:
+</p><pre class="programlisting">
+ALTER TYPE email OWNER TO joe;
+</pre><p>
+ </p><p>
+ To change the schema of the type <code class="literal">email</code>
+ to <code class="literal">customers</code>:
+</p><pre class="programlisting">
+ALTER TYPE email SET SCHEMA customers;
+</pre><p>
+ </p><p>
+ To add a new attribute to a composite type:
+</p><pre class="programlisting">
+ALTER TYPE compfoo ADD ATTRIBUTE f3 int;
+</pre><p>
+ </p><p>
+ To add a new value to an enum type in a particular sort position:
+</p><pre class="programlisting">
+ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';
+</pre><p>
+ </p><p>
+ To rename an enum value:
+</p><pre class="programlisting">
+ALTER TYPE colors RENAME VALUE 'purple' TO 'mauve';
+</pre><p>
+ </p><p>
+ To create binary I/O functions for an existing base type:
+</p><pre class="programlisting">
+CREATE FUNCTION mytypesend(mytype) RETURNS bytea ...;
+CREATE FUNCTION mytyperecv(internal, oid, integer) RETURNS mytype ...;
+ALTER TYPE mytype SET (
+ SEND = mytypesend,
+ RECEIVE = mytyperecv
+);
+</pre></div><div class="refsect1" id="id-1.9.3.42.9"><h2>Compatibility</h2><p>
+ The variants to add and drop attributes are part of the SQL
+ standard; the other variants are PostgreSQL extensions.
+ </p></div><div class="refsect1" id="SQL-ALTERTYPE-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a>, <a class="xref" href="sql-droptype.html" title="DROP TYPE"><span class="refentrytitle">DROP TYPE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertrigger.html" title="ALTER TRIGGER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alteruser.html" title="ALTER USER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TRIGGER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER USER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alteruser.html b/doc/src/sgml/html/sql-alteruser.html
new file mode 100644
index 0000000..bb5fbf4
--- /dev/null
+++ b/doc/src/sgml/html/sql-alteruser.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER USER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-altertype.html" title="ALTER TYPE" /><link rel="next" href="sql-alterusermapping.html" title="ALTER USER MAPPING" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER USER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-altertype.html" title="ALTER TYPE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterusermapping.html" title="ALTER USER MAPPING">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERUSER"><div class="titlepage"></div><a id="id-1.9.3.43.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER USER</span></h2><p>ALTER USER — change a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER USER <em class="replaceable"><code>role_specification</code></em> [ WITH ] <em class="replaceable"><code>option</code></em> [ ... ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <em class="replaceable"><code>connlimit</code></em>
+ | [ ENCRYPTED ] PASSWORD '<em class="replaceable"><code>password</code></em>' | PASSWORD NULL
+ | VALID UNTIL '<em class="replaceable"><code>timestamp</code></em>'
+
+ALTER USER <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+
+ALTER USER { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] SET <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | DEFAULT }
+ALTER USER { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] SET <em class="replaceable"><code>configuration_parameter</code></em> FROM CURRENT
+ALTER USER { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] RESET <em class="replaceable"><code>configuration_parameter</code></em>
+ALTER USER { <em class="replaceable"><code>role_specification</code></em> | ALL } [ IN DATABASE <em class="replaceable"><code>database_name</code></em> ] RESET ALL
+
+<span class="phrase">where <em class="replaceable"><code>role_specification</code></em> can be:</span>
+
+ <em class="replaceable"><code>role_name</code></em>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</pre></div><div class="refsect1" id="id-1.9.3.43.5"><h2>Description</h2><p>
+ <code class="command">ALTER USER</code> is now an alias for
+ <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.43.6"><h2>Compatibility</h2><p>
+ The <code class="command">ALTER USER</code> statement is a
+ <span class="productname">PostgreSQL</span> extension. The SQL standard
+ leaves the definition of users to the implementation.
+ </p></div><div class="refsect1" id="id-1.9.3.43.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-altertype.html" title="ALTER TYPE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterusermapping.html" title="ALTER USER MAPPING">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER TYPE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER USER MAPPING</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterusermapping.html b/doc/src/sgml/html/sql-alterusermapping.html
new file mode 100644
index 0000000..b33f442
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterusermapping.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER USER MAPPING</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alteruser.html" title="ALTER USER" /><link rel="next" href="sql-alterview.html" title="ALTER VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER USER MAPPING</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alteruser.html" title="ALTER USER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-alterview.html" title="ALTER VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERUSERMAPPING"><div class="titlepage"></div><a id="id-1.9.3.44.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER USER MAPPING</span></h2><p>ALTER USER MAPPING — change the definition of a user mapping</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER USER MAPPING FOR { <em class="replaceable"><code>user_name</code></em> | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC }
+ SERVER <em class="replaceable"><code>server_name</code></em>
+ OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ] )
+</pre></div><div class="refsect1" id="id-1.9.3.44.5"><h2>Description</h2><p>
+ <code class="command">ALTER USER MAPPING</code> changes the definition of a
+ user mapping.
+ </p><p>
+ The owner of a foreign server can alter user mappings for that
+ server for any user. Also, a user can alter a user mapping for
+ their own user name if <code class="literal">USAGE</code> privilege on the server has
+ been granted to the user.
+ </p></div><div class="refsect1" id="id-1.9.3.44.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ User name of the mapping. <code class="literal">CURRENT_ROLE</code>, <code class="literal">CURRENT_USER</code>,
+ and <code class="literal">USER</code> match the name of the current
+ user. <code class="literal">PUBLIC</code> is used to match all present and future
+ user names in the system.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_name</code></em></span></dt><dd><p>
+ Server name of the user mapping.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( [ ADD | SET | DROP ] <em class="replaceable"><code>option</code></em> ['<em class="replaceable"><code>value</code></em>'] [, ... ] )</code></span></dt><dd><p>
+ Change options for the user mapping. The new options override
+ any previously specified
+ options. <code class="literal">ADD</code>, <code class="literal">SET</code>, and <code class="literal">DROP</code>
+ specify the action to be performed. <code class="literal">ADD</code> is assumed
+ if no operation is explicitly specified. Option names must be
+ unique; options are also validated by the server's foreign-data
+ wrapper.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.44.7"><h2>Examples</h2><p>
+ Change the password for user mapping <code class="literal">bob</code>, server <code class="literal">foo</code>:
+</p><pre class="programlisting">
+ALTER USER MAPPING FOR bob SERVER foo OPTIONS (SET password 'public');
+</pre></div><div class="refsect1" id="id-1.9.3.44.8"><h2>Compatibility</h2><p>
+ <code class="command">ALTER USER MAPPING</code> conforms to ISO/IEC 9075-9
+ (SQL/MED). There is a subtle syntax issue: The standard omits
+ the <code class="literal">FOR</code> key word. Since both <code class="literal">CREATE
+ USER MAPPING</code> and <code class="literal">DROP USER MAPPING</code> use
+ <code class="literal">FOR</code> in analogous positions, and IBM DB2 (being
+ the other major SQL/MED implementation) also requires it
+ for <code class="literal">ALTER USER MAPPING</code>, PostgreSQL diverges from
+ the standard here in the interest of consistency and
+ interoperability.
+ </p></div><div class="refsect1" id="id-1.9.3.44.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>, <a class="xref" href="sql-dropusermapping.html" title="DROP USER MAPPING"><span class="refentrytitle">DROP USER MAPPING</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alteruser.html" title="ALTER USER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-alterview.html" title="ALTER VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER USER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ALTER VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-alterview.html b/doc/src/sgml/html/sql-alterview.html
new file mode 100644
index 0000000..4b52927
--- /dev/null
+++ b/doc/src/sgml/html/sql-alterview.html
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ALTER VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterusermapping.html" title="ALTER USER MAPPING" /><link rel="next" href="sql-analyze.html" title="ANALYZE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ALTER VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterusermapping.html" title="ALTER USER MAPPING">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-analyze.html" title="ANALYZE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ALTERVIEW"><div class="titlepage"></div><a id="id-1.9.3.45.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ALTER VIEW</span></h2><p>ALTER VIEW — change the definition of a view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> SET DEFAULT <em class="replaceable"><code>expression</code></em>
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ALTER [ COLUMN ] <em class="replaceable"><code>column_name</code></em> DROP DEFAULT
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> OWNER TO { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> RENAME [ COLUMN ] <em class="replaceable"><code>column_name</code></em> TO <em class="replaceable"><code>new_column_name</code></em>
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> RENAME TO <em class="replaceable"><code>new_name</code></em>
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> SET SCHEMA <em class="replaceable"><code>new_schema</code></em>
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> SET ( <em class="replaceable"><code>view_option_name</code></em> [= <em class="replaceable"><code>view_option_value</code></em>] [, ... ] )
+ALTER VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> RESET ( <em class="replaceable"><code>view_option_name</code></em> [, ... ] )
+</pre></div><div class="refsect1" id="id-1.9.3.45.5"><h2>Description</h2><p>
+ <code class="command">ALTER VIEW</code> changes various auxiliary properties
+ of a view. (If you want to modify the view's defining query,
+ use <code class="command">CREATE OR REPLACE VIEW</code>.)
+ </p><p>
+ You must own the view to use <code class="command">ALTER VIEW</code>.
+ To change a view's schema, you must also have <code class="literal">CREATE</code>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <code class="literal">CREATE</code> privilege on
+ the view's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the view.
+ However, a superuser can alter ownership of any view anyway.)
+ </p></div><div class="refsect1" id="id-1.9.3.45.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ Name of an existing column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_column_name</code></em></span></dt><dd><p>
+ New name for an existing column.
+ </p></dd><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the view does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><code class="literal">SET</code>/<code class="literal">DROP DEFAULT</code></span></dt><dd><p>
+ These forms set or remove the default value for a column.
+ A view column's default value is substituted into any
+ <code class="command">INSERT</code> or <code class="command">UPDATE</code> command whose target is the
+ view, before applying any rules or triggers for the view. The view's
+ default will therefore take precedence over any default values from
+ underlying relations.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_owner</code></em></span></dt><dd><p>
+ The user name of the new owner of the view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_name</code></em></span></dt><dd><p>
+ The new name for the view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_schema</code></em></span></dt><dd><p>
+ The new schema for the view.
+ </p></dd><dt><span class="term"><code class="literal">SET ( <em class="replaceable"><code>view_option_name</code></em> [= <em class="replaceable"><code>view_option_value</code></em>] [, ... ] )</code><br /></span><span class="term"><code class="literal">RESET ( <em class="replaceable"><code>view_option_name</code></em> [, ... ] )</code></span></dt><dd><p>
+ Sets or resets a view option. Currently supported options are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">check_option</code> (<code class="type">enum</code>)</span></dt><dd><p>
+ Changes the check option of the view. The value must
+ be <code class="literal">local</code> or <code class="literal">cascaded</code>.
+ </p></dd><dt><span class="term"><code class="literal">security_barrier</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Changes the security-barrier property of the view. The value must
+ be a Boolean value, such as <code class="literal">true</code>
+ or <code class="literal">false</code>.
+ </p></dd><dt><span class="term"><code class="literal">security_invoker</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Changes the security-invoker property of the view. The value must
+ be a Boolean value, such as <code class="literal">true</code>
+ or <code class="literal">false</code>.
+ </p></dd></dl></div></dd></dl></div></div><div class="refsect1" id="id-1.9.3.45.7"><h2>Notes</h2><p>
+ For historical reasons, <code class="command">ALTER TABLE</code> can be used with
+ views too; but the only variants of <code class="command">ALTER TABLE</code>
+ that are allowed with views are equivalent to the ones shown above.
+ </p></div><div class="refsect1" id="id-1.9.3.45.8"><h2>Examples</h2><p>
+ To rename the view <code class="literal">foo</code> to
+ <code class="literal">bar</code>:
+</p><pre class="programlisting">
+ALTER VIEW foo RENAME TO bar;
+</pre><p>
+ </p><p>
+ To attach a default column value to an updatable view:
+</p><pre class="programlisting">
+CREATE TABLE base_table (id int, ts timestamptz);
+CREATE VIEW a_view AS SELECT * FROM base_table;
+ALTER VIEW a_view ALTER COLUMN ts SET DEFAULT now();
+INSERT INTO base_table(id) VALUES(1); -- ts will receive a NULL
+INSERT INTO a_view(id) VALUES(2); -- ts will receive the current time
+</pre></div><div class="refsect1" id="id-1.9.3.45.9"><h2>Compatibility</h2><p>
+ <code class="command">ALTER VIEW</code> is a <span class="productname">PostgreSQL</span>
+ extension of the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.45.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a>, <a class="xref" href="sql-dropview.html" title="DROP VIEW"><span class="refentrytitle">DROP VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterusermapping.html" title="ALTER USER MAPPING">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-analyze.html" title="ANALYZE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER USER MAPPING </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ANALYZE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-analyze.html b/doc/src/sgml/html/sql-analyze.html
new file mode 100644
index 0000000..f2f5ad1
--- /dev/null
+++ b/doc/src/sgml/html/sql-analyze.html
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ANALYZE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-alterview.html" title="ALTER VIEW" /><link rel="next" href="sql-begin.html" title="BEGIN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ANALYZE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-alterview.html" title="ALTER VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-begin.html" title="BEGIN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ANALYZE"><div class="titlepage"></div><a id="id-1.9.3.46.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ANALYZE</span></h2><p>ANALYZE — collect statistics about a database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ANALYZE [ ( <em class="replaceable"><code>option</code></em> [, ...] ) ] [ <em class="replaceable"><code>table_and_columns</code></em> [, ...] ]
+ANALYZE [ VERBOSE ] [ <em class="replaceable"><code>table_and_columns</code></em> [, ...] ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be one of:</span>
+
+ VERBOSE [ <em class="replaceable"><code>boolean</code></em> ]
+ SKIP_LOCKED [ <em class="replaceable"><code>boolean</code></em> ]
+
+<span class="phrase">and <em class="replaceable"><code>table_and_columns</code></em> is:</span>
+
+ <em class="replaceable"><code>table_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.46.5"><h2>Description</h2><p>
+ <code class="command">ANALYZE</code> collects statistics about the contents
+ of tables in the database, and stores the results in the <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a>
+ system catalog. Subsequently, the query planner uses these
+ statistics to help determine the most efficient execution plans for
+ queries.
+ </p><p>
+ Without a <em class="replaceable"><code>table_and_columns</code></em>
+ list, <code class="command">ANALYZE</code> processes every table and materialized view
+ in the current database that the current user has permission to analyze.
+ With a list, <code class="command">ANALYZE</code> processes only those table(s).
+ It is further possible to give a list of column names for a table,
+ in which case only the statistics for those columns are collected.
+ </p><p>
+ When the option list is surrounded by parentheses, the options can be
+ written in any order. The parenthesized syntax was added in
+ <span class="productname">PostgreSQL</span> 11; the unparenthesized syntax
+ is deprecated.
+ </p></div><div class="refsect1" id="id-1.9.3.46.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">VERBOSE</code></span></dt><dd><p>
+ Enables display of progress messages.
+ </p></dd><dt><span class="term"><code class="literal">SKIP_LOCKED</code></span></dt><dd><p>
+ Specifies that <code class="command">ANALYZE</code> should not wait for any
+ conflicting locks to be released when beginning work on a relation:
+ if a relation cannot be locked immediately without waiting, the relation
+ is skipped. Note that even with this option, <code class="command">ANALYZE</code>
+ may still block when opening the relation's indexes or when acquiring
+ sample rows from partitions, table inheritance children, and some
+ types of foreign tables. Also, while <code class="command">ANALYZE</code>
+ ordinarily processes all partitions of specified partitioned tables,
+ this option will cause <code class="command">ANALYZE</code> to skip all
+ partitions if there is a conflicting lock on the partitioned table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>boolean</code></em></span></dt><dd><p>
+ Specifies whether the selected option should be turned on or off.
+ You can write <code class="literal">TRUE</code>, <code class="literal">ON</code>, or
+ <code class="literal">1</code> to enable the option, and <code class="literal">FALSE</code>,
+ <code class="literal">OFF</code>, or <code class="literal">0</code> to disable it. The
+ <em class="replaceable"><code>boolean</code></em> value can also
+ be omitted, in which case <code class="literal">TRUE</code> is assumed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of a specific table to
+ analyze. If omitted, all regular tables, partitioned tables, and
+ materialized views in the current database are analyzed (but not
+ foreign tables). If the specified table is a partitioned table, both the
+ inheritance statistics of the partitioned table as a whole and
+ statistics of the individual partitions are updated.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a specific column to analyze. Defaults to all columns.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.46.7"><h2>Outputs</h2><p>
+ When <code class="literal">VERBOSE</code> is specified, <code class="command">ANALYZE</code> emits
+ progress messages to indicate which table is currently being
+ processed. Various statistics about the tables are printed as well.
+ </p></div><div class="refsect1" id="id-1.9.3.46.8"><h2>Notes</h2><p>
+ To analyze a table, one must ordinarily be the table's owner or a
+ superuser. However, database owners are allowed to
+ analyze all tables in their databases, except shared catalogs.
+ (The restriction for shared catalogs means that a true database-wide
+ <code class="command">ANALYZE</code> can only be performed by a superuser.)
+ <code class="command">ANALYZE</code> will skip over any tables that the calling user
+ does not have permission to analyze.
+ </p><p>
+ Foreign tables are analyzed only when explicitly selected. Not all
+ foreign data wrappers support <code class="command">ANALYZE</code>. If the table's
+ wrapper does not support <code class="command">ANALYZE</code>, the command prints a
+ warning and does nothing.
+ </p><p>
+ In the default <span class="productname">PostgreSQL</span> configuration,
+ the autovacuum daemon (see <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>)
+ takes care of automatic analyzing of tables when they are first loaded
+ with data, and as they change throughout regular operation.
+ When autovacuum is disabled,
+ it is a good idea to run <code class="command">ANALYZE</code> periodically, or
+ just after making major changes in the contents of a table. Accurate
+ statistics will help the planner to choose the most appropriate query
+ plan, and thereby improve the speed of query processing. A common
+ strategy for read-mostly databases is to run <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>
+ and <code class="command">ANALYZE</code> once a day during a low-usage time of day.
+ (This will not be sufficient if there is heavy update activity.)
+ </p><p>
+ <code class="command">ANALYZE</code>
+ requires only a read lock on the target table, so it can run in
+ parallel with other activity on the table.
+ </p><p>
+ The statistics collected by <code class="command">ANALYZE</code> usually
+ include a list of some of the most common values in each column and
+ a histogram showing the approximate data distribution in each
+ column. One or both of these can be omitted if
+ <code class="command">ANALYZE</code> deems them uninteresting (for example,
+ in a unique-key column, there are no common values) or if the
+ column data type does not support the appropriate operators. There
+ is more information about the statistics in <a class="xref" href="maintenance.html" title="Chapter 25. Routine Database Maintenance Tasks">Chapter 25</a>.
+ </p><p>
+ For large tables, <code class="command">ANALYZE</code> takes a random sample
+ of the table contents, rather than examining every row. This
+ allows even very large tables to be analyzed in a small amount of
+ time. Note, however, that the statistics are only approximate, and
+ will change slightly each time <code class="command">ANALYZE</code> is run,
+ even if the actual table contents did not change. This might result
+ in small changes in the planner's estimated costs shown by
+ <a class="link" href="sql-explain.html" title="EXPLAIN"><code class="command">EXPLAIN</code></a>.
+ In rare situations, this non-determinism will cause the planner's
+ choices of query plans to change after <code class="command">ANALYZE</code> is run.
+ To avoid this, raise the amount of statistics collected by
+ <code class="command">ANALYZE</code>, as described below.
+ </p><p>
+ The extent of analysis can be controlled by adjusting the
+ <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> configuration variable, or
+ on a column-by-column basis by setting the per-column statistics
+ target with <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ... ALTER COLUMN ... SET
+ STATISTICS</code></a>.
+ The target value sets the
+ maximum number of entries in the most-common-value list and the
+ maximum number of bins in the histogram. The default target value
+ is 100, but this can be adjusted up or down to trade off accuracy of
+ planner estimates against the time taken for
+ <code class="command">ANALYZE</code> and the amount of space occupied in
+ <code class="literal">pg_statistic</code>. In particular, setting the
+ statistics target to zero disables collection of statistics for
+ that column. It might be useful to do that for columns that are
+ never used as part of the <code class="literal">WHERE</code>, <code class="literal">GROUP BY</code>,
+ or <code class="literal">ORDER BY</code> clauses of queries, since the planner will
+ have no use for statistics on such columns.
+ </p><p>
+ The largest statistics target among the columns being analyzed determines
+ the number of table rows sampled to prepare the statistics. Increasing
+ the target causes a proportional increase in the time and space needed
+ to do <code class="command">ANALYZE</code>.
+ </p><p>
+ One of the values estimated by <code class="command">ANALYZE</code> is the number of
+ distinct values that appear in each column. Because only a subset of the
+ rows are examined, this estimate can sometimes be quite inaccurate, even
+ with the largest possible statistics target. If this inaccuracy leads to
+ bad query plans, a more accurate value can be determined manually and then
+ installed with
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)</code></a>.
+ </p><p>
+ If the table being analyzed has inheritance children,
+ <code class="command">ANALYZE</code> gathers two sets of statistics: one on the rows
+ of the parent table only, and a second including rows of both the parent
+ table and all of its children. This second set of statistics is needed when
+ planning queries that process the inheritance tree as a whole. The child
+ tables themselves are not individually analyzed in this case.
+ The autovacuum daemon, however, will only consider inserts or
+ updates on the parent table itself when deciding whether to trigger an
+ automatic analyze for that table. If that table is rarely inserted into
+ or updated, the inheritance statistics will not be up to date unless you
+ run <code class="command">ANALYZE</code> manually.
+ </p><p>
+ For partitioned tables, <code class="command">ANALYZE</code> gathers statistics by
+ sampling rows from all partitions; in addition, it will recurse into each
+ partition and update its statistics. Each leaf partition is analyzed only
+ once, even with multi-level partitioning. No statistics are collected for
+ only the parent table (without data from its partitions), because with
+ partitioning it's guaranteed to be empty.
+ </p><p>
+ The autovacuum daemon does not process partitioned tables, nor does it
+ process inheritance parents if only the children are ever modified.
+ It is usually necessary to periodically run a manual
+ <code class="command">ANALYZE</code> to keep the statistics of the table hierarchy
+ up to date.
+ </p><p>
+ If any child tables or partitions are foreign tables whose foreign
+ data wrappers do not support <code class="command">ANALYZE</code>, those tables are
+ ignored while gathering inheritance statistics.
+ </p><p>
+ If the table being analyzed is completely empty, <code class="command">ANALYZE</code>
+ will not record new statistics for that table. Any existing statistics
+ will be retained.
+ </p><p>
+ Each backend running <code class="command">ANALYZE</code> will report its progress
+ in the <code class="structname">pg_stat_progress_analyze</code> view. See
+ <a class="xref" href="progress-reporting.html#ANALYZE-PROGRESS-REPORTING" title="28.4.1. ANALYZE Progress Reporting">Section 28.4.1</a> for details.
+ </p></div><div class="refsect1" id="id-1.9.3.46.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">ANALYZE</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.46.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-vacuum.html" title="VACUUM"><span class="refentrytitle">VACUUM</span></a>, <a class="xref" href="app-vacuumdb.html" title="vacuumdb"><span class="refentrytitle"><span class="application">vacuumdb</span></span></a>, <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST" title="20.4.4. Cost-based Vacuum Delay">Section 20.4.4</a>, <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>, <a class="xref" href="progress-reporting.html#ANALYZE-PROGRESS-REPORTING" title="28.4.1. ANALYZE Progress Reporting">Section 28.4.1</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-alterview.html" title="ALTER VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-begin.html" title="BEGIN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ALTER VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> BEGIN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-begin.html b/doc/src/sgml/html/sql-begin.html
new file mode 100644
index 0000000..0b1794f
--- /dev/null
+++ b/doc/src/sgml/html/sql-begin.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>BEGIN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-analyze.html" title="ANALYZE" /><link rel="next" href="sql-call.html" title="CALL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">BEGIN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-analyze.html" title="ANALYZE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-call.html" title="CALL">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-BEGIN"><div class="titlepage"></div><a id="id-1.9.3.47.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">BEGIN</span></h2><p>BEGIN — start a transaction block</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+BEGIN [ WORK | TRANSACTION ] [ <em class="replaceable"><code>transaction_mode</code></em> [, ...] ]
+
+<span class="phrase">where <em class="replaceable"><code>transaction_mode</code></em> is one of:</span>
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+</pre></div><div class="refsect1" id="id-1.9.3.47.5"><h2>Description</h2><p>
+ <code class="command">BEGIN</code> initiates a transaction block, that is,
+ all statements after a <code class="command">BEGIN</code> command will be
+ executed in a single transaction until an explicit <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a> or <a class="link" href="sql-rollback.html" title="ROLLBACK"><code class="command">ROLLBACK</code></a> is given.
+ By default (without <code class="command">BEGIN</code>),
+ <span class="productname">PostgreSQL</span> executes
+ transactions in <span class="quote">“<span class="quote">autocommit</span>”</span> mode, that is, each
+ statement is executed in its own transaction and a commit is
+ implicitly performed at the end of the statement (if execution was
+ successful, otherwise a rollback is done).
+ </p><p>
+ Statements are executed more quickly in a transaction block, because
+ transaction start/commit requires significant CPU and disk
+ activity. Execution of multiple statements inside a transaction is
+ also useful to ensure consistency when making several related changes:
+ other sessions will be unable to see the intermediate states
+ wherein not all the related updates have been done.
+ </p><p>
+ If the isolation level, read/write mode, or deferrable mode is specified, the new
+ transaction has those characteristics, as if
+ <a class="link" href="sql-set-transaction.html" title="SET TRANSACTION"><code class="command">SET TRANSACTION</code></a>
+ was executed.
+ </p></div><div class="refsect1" id="id-1.9.3.47.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">WORK</code><br /></span><span class="term"><code class="literal">TRANSACTION</code></span></dt><dd><p>
+ Optional key words. They have no effect.
+ </p></dd></dl></div><p>
+ Refer to <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> for information on the meaning
+ of the other parameters to this statement.
+ </p></div><div class="refsect1" id="id-1.9.3.47.7"><h2>Notes</h2><p>
+ <a class="link" href="sql-start-transaction.html" title="START TRANSACTION"><code class="command">START TRANSACTION</code></a> has the same functionality
+ as <code class="command">BEGIN</code>.
+ </p><p>
+ Use <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a> or
+ <a class="link" href="sql-rollback.html" title="ROLLBACK"><code class="command">ROLLBACK</code></a>
+ to terminate a transaction block.
+ </p><p>
+ Issuing <code class="command">BEGIN</code> when already inside a transaction block will
+ provoke a warning message. The state of the transaction is not affected.
+ To nest transactions within a transaction block, use savepoints
+ (see <a class="xref" href="sql-savepoint.html" title="SAVEPOINT"><span class="refentrytitle">SAVEPOINT</span></a>).
+ </p><p>
+ For reasons of backwards compatibility, the commas between successive
+ <em class="replaceable"><code>transaction_modes</code></em> can be
+ omitted.
+ </p></div><div class="refsect1" id="id-1.9.3.47.8"><h2>Examples</h2><p>
+ To begin a transaction block:
+
+</p><pre class="programlisting">
+BEGIN;
+</pre></div><div class="refsect1" id="id-1.9.3.47.9"><h2>Compatibility</h2><p>
+ <code class="command">BEGIN</code> is a <span class="productname">PostgreSQL</span>
+ language extension. It is equivalent to the SQL-standard command
+ <a class="link" href="sql-start-transaction.html" title="START TRANSACTION"><code class="command">START TRANSACTION</code></a>, whose reference page
+ contains additional compatibility information.
+ </p><p>
+ The <code class="literal">DEFERRABLE</code>
+ <em class="replaceable"><code>transaction_mode</code></em>
+ is a <span class="productname">PostgreSQL</span> language extension.
+ </p><p>
+ Incidentally, the <code class="literal">BEGIN</code> key word is used for a
+ different purpose in embedded SQL. You are advised to be careful
+ about the transaction semantics when porting database applications.
+ </p></div><div class="refsect1" id="id-1.9.3.47.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a>, <a class="xref" href="sql-start-transaction.html" title="START TRANSACTION"><span class="refentrytitle">START TRANSACTION</span></a>, <a class="xref" href="sql-savepoint.html" title="SAVEPOINT"><span class="refentrytitle">SAVEPOINT</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-analyze.html" title="ANALYZE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-call.html" title="CALL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ANALYZE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CALL</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-call.html b/doc/src/sgml/html/sql-call.html
new file mode 100644
index 0000000..5e326b0
--- /dev/null
+++ b/doc/src/sgml/html/sql-call.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CALL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-begin.html" title="BEGIN" /><link rel="next" href="sql-checkpoint.html" title="CHECKPOINT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CALL</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-begin.html" title="BEGIN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-checkpoint.html" title="CHECKPOINT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CALL"><div class="titlepage"></div><a id="id-1.9.3.48.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CALL</span></h2><p>CALL — invoke a procedure</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CALL <em class="replaceable"><code>name</code></em> ( [ <em class="replaceable"><code>argument</code></em> ] [, ...] )
+</pre></div><div class="refsect1" id="id-1.9.3.48.5"><h2>Description</h2><p>
+ <code class="command">CALL</code> executes a procedure.
+ </p><p>
+ If the procedure has any output parameters, then a result row will be
+ returned, containing the values of those parameters.
+ </p></div><div class="refsect1" id="id-1.9.3.48.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the procedure.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argument</code></em></span></dt><dd><p>
+ An argument expression for the procedure call.
+ </p><p>
+ Arguments can include parameter names, using the syntax
+ <code class="literal"><em class="replaceable"><code>name</code></em> =&gt; <em class="replaceable"><code>value</code></em></code>.
+ This works the same as in ordinary function calls; see
+ <a class="xref" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Section 4.3</a> for details.
+ </p><p>
+ Arguments must be supplied for all procedure parameters that lack
+ defaults, including <code class="literal">OUT</code> parameters. However,
+ arguments matching <code class="literal">OUT</code> parameters are not evaluated,
+ so it's customary to just write <code class="literal">NULL</code> for them.
+ (Writing something else for an <code class="literal">OUT</code> parameter
+ might cause compatibility problems with
+ future <span class="productname">PostgreSQL</span> versions.)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.48.7"><h2>Notes</h2><p>
+ The user must have <code class="literal">EXECUTE</code> privilege on the procedure in
+ order to be allowed to invoke it.
+ </p><p>
+ To call a function (not a procedure), use <code class="command">SELECT</code> instead.
+ </p><p>
+ If <code class="command">CALL</code> is executed in a transaction block, then the
+ called procedure cannot execute transaction control statements.
+ Transaction control statements are only allowed if <code class="command">CALL</code>
+ is executed in its own transaction.
+ </p><p>
+ <span class="application">PL/pgSQL</span> handles output parameters
+ in <code class="command">CALL</code> commands differently;
+ see <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-CALLING-PROCEDURE" title="43.6.3. Calling a Procedure">Section 43.6.3</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.48.8"><h2>Examples</h2><pre class="programlisting">
+CALL do_db_maintenance();
+</pre></div><div class="refsect1" id="id-1.9.3.48.9"><h2>Compatibility</h2><p>
+ <code class="command">CALL</code> conforms to the SQL standard,
+ except for the handling of output parameters. The standard
+ says that users should write variables to receive the values
+ of output parameters.
+ </p></div><div class="refsect1" id="id-1.9.3.48.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-begin.html" title="BEGIN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-checkpoint.html" title="CHECKPOINT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">BEGIN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CHECKPOINT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-checkpoint.html b/doc/src/sgml/html/sql-checkpoint.html
new file mode 100644
index 0000000..e5d0d10
--- /dev/null
+++ b/doc/src/sgml/html/sql-checkpoint.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CHECKPOINT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-call.html" title="CALL" /><link rel="next" href="sql-close.html" title="CLOSE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CHECKPOINT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-call.html" title="CALL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-close.html" title="CLOSE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CHECKPOINT"><div class="titlepage"></div><a id="id-1.9.3.49.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CHECKPOINT</span></h2><p>CHECKPOINT — force a write-ahead log checkpoint</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CHECKPOINT
+</pre></div><div class="refsect1" id="id-1.9.3.49.5"><h2>Description</h2><p>
+ A checkpoint is a point in the write-ahead log sequence at which
+ all data files have been updated to reflect the information in the
+ log. All data files will be flushed to disk. Refer to
+ <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a> for more details about what happens
+ during a checkpoint.
+ </p><p>
+ The <code class="command">CHECKPOINT</code> command forces an immediate
+ checkpoint when the command is issued, without waiting for a
+ regular checkpoint scheduled by the system (controlled by the settings in
+ <a class="xref" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-CHECKPOINTS" title="20.5.2. Checkpoints">Section 20.5.2</a>).
+ <code class="command">CHECKPOINT</code> is not intended for use during normal
+ operation.
+ </p><p>
+ If executed during recovery, the <code class="command">CHECKPOINT</code> command
+ will force a restartpoint (see <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a>)
+ rather than writing a new checkpoint.
+ </p><p>
+ Only superusers or users with the privileges of
+ the <a class="link" href="predefined-roles.html#PREDEFINED-ROLES-TABLE" title="Table 22.1. Predefined Roles"><code class="literal">pg_checkpoint</code></a>
+ role can call <code class="command">CHECKPOINT</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.49.6"><h2>Compatibility</h2><p>
+ The <code class="command">CHECKPOINT</code> command is a
+ <span class="productname">PostgreSQL</span> language extension.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-call.html" title="CALL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-close.html" title="CLOSE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CALL </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CLOSE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-close.html b/doc/src/sgml/html/sql-close.html
new file mode 100644
index 0000000..542005d
--- /dev/null
+++ b/doc/src/sgml/html/sql-close.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CLOSE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-checkpoint.html" title="CHECKPOINT" /><link rel="next" href="sql-cluster.html" title="CLUSTER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CLOSE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-checkpoint.html" title="CHECKPOINT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-cluster.html" title="CLUSTER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CLOSE"><div class="titlepage"></div><a id="id-1.9.3.50.1" class="indexterm"></a><a id="id-1.9.3.50.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CLOSE</span></h2><p>CLOSE — close a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CLOSE { <em class="replaceable"><code>name</code></em> | ALL }
+</pre></div><div class="refsect1" id="id-1.9.3.50.6"><h2>Description</h2><p>
+ <code class="command">CLOSE</code> frees the resources associated with an open cursor.
+ After the cursor is closed, no subsequent operations
+ are allowed on it. A cursor should be closed when it is
+ no longer needed.
+ </p><p>
+ Every non-holdable open cursor is implicitly closed when a
+ transaction is terminated by <code class="command">COMMIT</code> or
+ <code class="command">ROLLBACK</code>. A holdable cursor is implicitly
+ closed if the transaction that created it aborts via
+ <code class="command">ROLLBACK</code>. If the creating transaction
+ successfully commits, the holdable cursor remains open until an
+ explicit <code class="command">CLOSE</code> is executed, or the client
+ disconnects.
+ </p></div><div class="refsect1" id="id-1.9.3.50.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an open cursor to close.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Close all open cursors.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.50.8"><h2>Notes</h2><p>
+ <span class="productname">PostgreSQL</span> does not have an explicit
+ <code class="command">OPEN</code> cursor statement; a cursor is considered
+ open when it is declared. Use the
+ <a class="link" href="sql-declare.html" title="DECLARE"><code class="command">DECLARE</code></a>
+ statement to declare a cursor.
+ </p><p>
+ You can see all available cursors by querying the <a class="link" href="view-pg-cursors.html" title="54.6. pg_cursors"><code class="structname">pg_cursors</code></a> system view.
+ </p><p>
+ If a cursor is closed after a savepoint which is later rolled back,
+ the <code class="command">CLOSE</code> is not rolled back; that is, the cursor
+ remains closed.
+ </p></div><div class="refsect1" id="id-1.9.3.50.9"><h2>Examples</h2><p>
+ Close the cursor <code class="literal">liahona</code>:
+</p><pre class="programlisting">
+CLOSE liahona;
+</pre></div><div class="refsect1" id="id-1.9.3.50.10"><h2>Compatibility</h2><p>
+ <code class="command">CLOSE</code> is fully conforming with the SQL
+ standard. <code class="command">CLOSE ALL</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.50.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>, <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a>, <a class="xref" href="sql-move.html" title="MOVE"><span class="refentrytitle">MOVE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-checkpoint.html" title="CHECKPOINT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-cluster.html" title="CLUSTER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CHECKPOINT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CLUSTER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-cluster.html b/doc/src/sgml/html/sql-cluster.html
new file mode 100644
index 0000000..d5d6052
--- /dev/null
+++ b/doc/src/sgml/html/sql-cluster.html
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CLUSTER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-close.html" title="CLOSE" /><link rel="next" href="sql-comment.html" title="COMMENT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CLUSTER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-close.html" title="CLOSE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-comment.html" title="COMMENT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CLUSTER"><div class="titlepage"></div><a id="id-1.9.3.51.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CLUSTER</span></h2><p>CLUSTER — cluster a table according to an index</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CLUSTER [VERBOSE] <em class="replaceable"><code>table_name</code></em> [ USING <em class="replaceable"><code>index_name</code></em> ]
+CLUSTER ( <em class="replaceable"><code>option</code></em> [, ...] ) <em class="replaceable"><code>table_name</code></em> [ USING <em class="replaceable"><code>index_name</code></em> ]
+CLUSTER [VERBOSE]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be one of:</span>
+
+ VERBOSE [ <em class="replaceable"><code>boolean</code></em> ]
+</pre></div><div class="refsect1" id="id-1.9.3.51.5"><h2>Description</h2><p>
+ <code class="command">CLUSTER</code> instructs <span class="productname">PostgreSQL</span>
+ to cluster the table specified
+ by <em class="replaceable"><code>table_name</code></em>
+ based on the index specified by
+ <em class="replaceable"><code>index_name</code></em>. The index must
+ already have been defined on
+ <em class="replaceable"><code>table_name</code></em>.
+ </p><p>
+ When a table is clustered, it is physically reordered
+ based on the index information. Clustering is a one-time operation:
+ when the table is subsequently updated, the changes are
+ not clustered. That is, no attempt is made to store new or
+ updated rows according to their index order. (If one wishes, one can
+ periodically recluster by issuing the command again. Also, setting
+ the table's <code class="literal">fillfactor</code> storage parameter to less than
+ 100% can aid in preserving cluster ordering during updates, since updated
+ rows are kept on the same page if enough space is available there.)
+ </p><p>
+ When a table is clustered, <span class="productname">PostgreSQL</span>
+ remembers which index it was clustered by. The form
+ <code class="command">CLUSTER <em class="replaceable"><code>table_name</code></em></code>
+ reclusters the table using the same index as before. You can also
+ use the <code class="literal">CLUSTER</code> or <code class="literal">SET WITHOUT CLUSTER</code>
+ forms of <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a> to set the index to be used for
+ future cluster operations, or to clear any previous setting.
+ </p><p>
+ <code class="command">CLUSTER</code> without any parameter reclusters all the
+ previously-clustered tables in the current database that the calling user
+ owns, or all such tables if called by a superuser. This
+ form of <code class="command">CLUSTER</code> cannot be executed inside a transaction
+ block.
+ </p><p>
+ When a table is being clustered, an <code class="literal">ACCESS
+ EXCLUSIVE</code> lock is acquired on it. This prevents any other
+ database operations (both reads and writes) from operating on the
+ table until the <code class="command">CLUSTER</code> is finished.
+ </p></div><div class="refsect1" id="id-1.9.3.51.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of a table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_name</code></em></span></dt><dd><p>
+ The name of an index.
+ </p></dd><dt><span class="term"><code class="literal">VERBOSE</code></span></dt><dd><p>
+ Prints a progress report as each table is clustered.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>boolean</code></em></span></dt><dd><p>
+ Specifies whether the selected option should be turned on or off.
+ You can write <code class="literal">TRUE</code>, <code class="literal">ON</code>, or
+ <code class="literal">1</code> to enable the option, and <code class="literal">FALSE</code>,
+ <code class="literal">OFF</code>, or <code class="literal">0</code> to disable it. The
+ <em class="replaceable"><code>boolean</code></em> value can also
+ be omitted, in which case <code class="literal">TRUE</code> is assumed.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.51.7"><h2>Notes</h2><p>
+ In cases where you are accessing single rows randomly
+ within a table, the actual order of the data in the
+ table is unimportant. However, if you tend to access some
+ data more than others, and there is an index that groups
+ them together, you will benefit from using <code class="command">CLUSTER</code>.
+ If you are requesting a range of indexed values from a table, or a
+ single indexed value that has multiple rows that match,
+ <code class="command">CLUSTER</code> will help because once the index identifies the
+ table page for the first row that matches, all other rows
+ that match are probably already on the same table page,
+ and so you save disk accesses and speed up the query.
+ </p><p>
+ <code class="command">CLUSTER</code> can re-sort the table using either an index scan
+ on the specified index, or (if the index is a b-tree) a sequential
+ scan followed by sorting. It will attempt to choose the method that
+ will be faster, based on planner cost parameters and available statistical
+ information.
+ </p><p>
+ When an index scan is used, a temporary copy of the table is created that
+ contains the table data in the index order. Temporary copies of each
+ index on the table are created as well. Therefore, you need free space on
+ disk at least equal to the sum of the table size and the index sizes.
+ </p><p>
+ When a sequential scan and sort is used, a temporary sort file is
+ also created, so that the peak temporary space requirement is as much
+ as double the table size, plus the index sizes. This method is often
+ faster than the index scan method, but if the disk space requirement is
+ intolerable, you can disable this choice by temporarily setting <a class="xref" href="runtime-config-query.html#GUC-ENABLE-SORT">enable_sort</a> to <code class="literal">off</code>.
+ </p><p>
+ It is advisable to set <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a> to
+ a reasonably large value (but not more than the amount of RAM you can
+ dedicate to the <code class="command">CLUSTER</code> operation) before clustering.
+ </p><p>
+ Because the planner records statistics about the ordering of
+ tables, it is advisable to run <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a>
+ on the newly clustered table.
+ Otherwise, the planner might make poor choices of query plans.
+ </p><p>
+ Because <code class="command">CLUSTER</code> remembers which indexes are clustered,
+ one can cluster the tables one wants clustered manually the first time,
+ then set up a periodic maintenance script that executes
+ <code class="command">CLUSTER</code> without any parameters, so that the desired tables
+ are periodically reclustered.
+ </p><p>
+ Each backend running <code class="command">CLUSTER</code> will report its progress
+ in the <code class="structname">pg_stat_progress_cluster</code> view. See
+ <a class="xref" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING" title="28.4.4. CLUSTER Progress Reporting">Section 28.4.4</a> for details.
+ </p><p>
+ Clustering a partitioned table clusters each of its partitions using the
+ partition of the specified partitioned index. When clustering a partitioned
+ table, the index may not be omitted.
+ </p></div><div class="refsect1" id="id-1.9.3.51.8"><h2>Examples</h2><p>
+ Cluster the table <code class="literal">employees</code> on the basis of
+ its index <code class="literal">employees_ind</code>:
+</p><pre class="programlisting">
+CLUSTER employees USING employees_ind;
+</pre><p>
+ </p><p>
+ Cluster the <code class="literal">employees</code> table using the same
+ index that was used before:
+</p><pre class="programlisting">
+CLUSTER employees;
+</pre><p>
+ </p><p>
+ Cluster all tables in the database that have previously been clustered:
+</p><pre class="programlisting">
+CLUSTER;
+</pre></div><div class="refsect1" id="id-1.9.3.51.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">CLUSTER</code> statement in the SQL standard.
+ </p><p>
+ The syntax
+</p><pre class="synopsis">
+CLUSTER <em class="replaceable"><code>index_name</code></em> ON <em class="replaceable"><code>table_name</code></em>
+</pre><p>
+ is also supported for compatibility with pre-8.3 <span class="productname">PostgreSQL</span>
+ versions.
+ </p></div><div class="refsect1" id="id-1.9.3.51.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-clusterdb.html" title="clusterdb"><span class="refentrytitle"><span class="application">clusterdb</span></span></a>, <a class="xref" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING" title="28.4.4. CLUSTER Progress Reporting">Section 28.4.4</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-close.html" title="CLOSE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-comment.html" title="COMMENT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CLOSE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> COMMENT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-commands.html b/doc/src/sgml/html/sql-commands.html
new file mode 100644
index 0000000..b2deaa9
--- /dev/null
+++ b/doc/src/sgml/html/sql-commands.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SQL Commands</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="reference.html" title="Part VI. Reference" /><link rel="next" href="sql-abort.html" title="ABORT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SQL Commands</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="reference.html" title="Part VI. Reference">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="reference.html" title="Part VI. Reference">Up</a></td><th width="60%" align="center">Part VI. Reference</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-abort.html" title="ABORT">Next</a></td></tr></table><hr /></div><div class="reference" id="SQL-COMMANDS"><div class="titlepage"><div><div><h1 class="title">SQL Commands</h1></div></div><hr /></div><div class="partintro" id="id-1.9.3.2"><div></div><p>
+ This part contains reference information for the
+ <acronym class="acronym">SQL</acronym> commands supported by
+ <span class="productname">PostgreSQL</span>. By <span class="quote">“<span class="quote">SQL</span>”</span> the
+ language in general is meant; information about the standards
+ conformance and compatibility of each command can be found on the
+ respective reference page.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="refentrytitle"><a href="sql-abort.html">ABORT</a></span><span class="refpurpose"> — abort the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-alteraggregate.html">ALTER AGGREGATE</a></span><span class="refpurpose"> — change the definition of an aggregate function</span></dt><dt><span class="refentrytitle"><a href="sql-altercollation.html">ALTER COLLATION</a></span><span class="refpurpose"> — change the definition of a collation</span></dt><dt><span class="refentrytitle"><a href="sql-alterconversion.html">ALTER CONVERSION</a></span><span class="refpurpose"> — change the definition of a conversion</span></dt><dt><span class="refentrytitle"><a href="sql-alterdatabase.html">ALTER DATABASE</a></span><span class="refpurpose"> — change a database</span></dt><dt><span class="refentrytitle"><a href="sql-alterdefaultprivileges.html">ALTER DEFAULT PRIVILEGES</a></span><span class="refpurpose"> — define default access privileges</span></dt><dt><span class="refentrytitle"><a href="sql-alterdomain.html">ALTER DOMAIN</a></span><span class="refpurpose"> —
+ change the definition of a domain
+ </span></dt><dt><span class="refentrytitle"><a href="sql-altereventtrigger.html">ALTER EVENT TRIGGER</a></span><span class="refpurpose"> — change the definition of an event trigger</span></dt><dt><span class="refentrytitle"><a href="sql-alterextension.html">ALTER EXTENSION</a></span><span class="refpurpose"> —
+ change the definition of an extension
+ </span></dt><dt><span class="refentrytitle"><a href="sql-alterforeigndatawrapper.html">ALTER FOREIGN DATA WRAPPER</a></span><span class="refpurpose"> — change the definition of a foreign-data wrapper</span></dt><dt><span class="refentrytitle"><a href="sql-alterforeigntable.html">ALTER FOREIGN TABLE</a></span><span class="refpurpose"> — change the definition of a foreign table</span></dt><dt><span class="refentrytitle"><a href="sql-alterfunction.html">ALTER FUNCTION</a></span><span class="refpurpose"> — change the definition of a function</span></dt><dt><span class="refentrytitle"><a href="sql-altergroup.html">ALTER GROUP</a></span><span class="refpurpose"> — change role name or membership</span></dt><dt><span class="refentrytitle"><a href="sql-alterindex.html">ALTER INDEX</a></span><span class="refpurpose"> — change the definition of an index</span></dt><dt><span class="refentrytitle"><a href="sql-alterlanguage.html">ALTER LANGUAGE</a></span><span class="refpurpose"> — change the definition of a procedural language</span></dt><dt><span class="refentrytitle"><a href="sql-alterlargeobject.html">ALTER LARGE OBJECT</a></span><span class="refpurpose"> — change the definition of a large object</span></dt><dt><span class="refentrytitle"><a href="sql-altermaterializedview.html">ALTER MATERIALIZED VIEW</a></span><span class="refpurpose"> — change the definition of a materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-alteroperator.html">ALTER OPERATOR</a></span><span class="refpurpose"> — change the definition of an operator</span></dt><dt><span class="refentrytitle"><a href="sql-alteropclass.html">ALTER OPERATOR CLASS</a></span><span class="refpurpose"> — change the definition of an operator class</span></dt><dt><span class="refentrytitle"><a href="sql-alteropfamily.html">ALTER OPERATOR FAMILY</a></span><span class="refpurpose"> — change the definition of an operator family</span></dt><dt><span class="refentrytitle"><a href="sql-alterpolicy.html">ALTER POLICY</a></span><span class="refpurpose"> — change the definition of a row-level security policy</span></dt><dt><span class="refentrytitle"><a href="sql-alterprocedure.html">ALTER PROCEDURE</a></span><span class="refpurpose"> — change the definition of a procedure</span></dt><dt><span class="refentrytitle"><a href="sql-alterpublication.html">ALTER PUBLICATION</a></span><span class="refpurpose"> — change the definition of a publication</span></dt><dt><span class="refentrytitle"><a href="sql-alterrole.html">ALTER ROLE</a></span><span class="refpurpose"> — change a database role</span></dt><dt><span class="refentrytitle"><a href="sql-alterroutine.html">ALTER ROUTINE</a></span><span class="refpurpose"> — change the definition of a routine</span></dt><dt><span class="refentrytitle"><a href="sql-alterrule.html">ALTER RULE</a></span><span class="refpurpose"> — change the definition of a rule</span></dt><dt><span class="refentrytitle"><a href="sql-alterschema.html">ALTER SCHEMA</a></span><span class="refpurpose"> — change the definition of a schema</span></dt><dt><span class="refentrytitle"><a href="sql-altersequence.html">ALTER SEQUENCE</a></span><span class="refpurpose"> —
+ change the definition of a sequence generator
+ </span></dt><dt><span class="refentrytitle"><a href="sql-alterserver.html">ALTER SERVER</a></span><span class="refpurpose"> — change the definition of a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-alterstatistics.html">ALTER STATISTICS</a></span><span class="refpurpose"> —
+ change the definition of an extended statistics object
+ </span></dt><dt><span class="refentrytitle"><a href="sql-altersubscription.html">ALTER SUBSCRIPTION</a></span><span class="refpurpose"> — change the definition of a subscription</span></dt><dt><span class="refentrytitle"><a href="sql-altersystem.html">ALTER SYSTEM</a></span><span class="refpurpose"> — change a server configuration parameter</span></dt><dt><span class="refentrytitle"><a href="sql-altertable.html">ALTER TABLE</a></span><span class="refpurpose"> — change the definition of a table</span></dt><dt><span class="refentrytitle"><a href="sql-altertablespace.html">ALTER TABLESPACE</a></span><span class="refpurpose"> — change the definition of a tablespace</span></dt><dt><span class="refentrytitle"><a href="sql-altertsconfig.html">ALTER TEXT SEARCH CONFIGURATION</a></span><span class="refpurpose"> — change the definition of a text search configuration</span></dt><dt><span class="refentrytitle"><a href="sql-altertsdictionary.html">ALTER TEXT SEARCH DICTIONARY</a></span><span class="refpurpose"> — change the definition of a text search dictionary</span></dt><dt><span class="refentrytitle"><a href="sql-altertsparser.html">ALTER TEXT SEARCH PARSER</a></span><span class="refpurpose"> — change the definition of a text search parser</span></dt><dt><span class="refentrytitle"><a href="sql-altertstemplate.html">ALTER TEXT SEARCH TEMPLATE</a></span><span class="refpurpose"> — change the definition of a text search template</span></dt><dt><span class="refentrytitle"><a href="sql-altertrigger.html">ALTER TRIGGER</a></span><span class="refpurpose"> — change the definition of a trigger</span></dt><dt><span class="refentrytitle"><a href="sql-altertype.html">ALTER TYPE</a></span><span class="refpurpose"> —
+ change the definition of a type
+ </span></dt><dt><span class="refentrytitle"><a href="sql-alteruser.html">ALTER USER</a></span><span class="refpurpose"> — change a database role</span></dt><dt><span class="refentrytitle"><a href="sql-alterusermapping.html">ALTER USER MAPPING</a></span><span class="refpurpose"> — change the definition of a user mapping</span></dt><dt><span class="refentrytitle"><a href="sql-alterview.html">ALTER VIEW</a></span><span class="refpurpose"> — change the definition of a view</span></dt><dt><span class="refentrytitle"><a href="sql-analyze.html">ANALYZE</a></span><span class="refpurpose"> — collect statistics about a database</span></dt><dt><span class="refentrytitle"><a href="sql-begin.html">BEGIN</a></span><span class="refpurpose"> — start a transaction block</span></dt><dt><span class="refentrytitle"><a href="sql-call.html">CALL</a></span><span class="refpurpose"> — invoke a procedure</span></dt><dt><span class="refentrytitle"><a href="sql-checkpoint.html">CHECKPOINT</a></span><span class="refpurpose"> — force a write-ahead log checkpoint</span></dt><dt><span class="refentrytitle"><a href="sql-close.html">CLOSE</a></span><span class="refpurpose"> — close a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-cluster.html">CLUSTER</a></span><span class="refpurpose"> — cluster a table according to an index</span></dt><dt><span class="refentrytitle"><a href="sql-comment.html">COMMENT</a></span><span class="refpurpose"> — define or change the comment of an object</span></dt><dt><span class="refentrytitle"><a href="sql-commit.html">COMMIT</a></span><span class="refpurpose"> — commit the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-commit-prepared.html">COMMIT PREPARED</a></span><span class="refpurpose"> — commit a transaction that was earlier prepared for two-phase commit</span></dt><dt><span class="refentrytitle"><a href="sql-copy.html">COPY</a></span><span class="refpurpose"> — copy data between a file and a table</span></dt><dt><span class="refentrytitle"><a href="sql-create-access-method.html">CREATE ACCESS METHOD</a></span><span class="refpurpose"> — define a new access method</span></dt><dt><span class="refentrytitle"><a href="sql-createaggregate.html">CREATE AGGREGATE</a></span><span class="refpurpose"> — define a new aggregate function</span></dt><dt><span class="refentrytitle"><a href="sql-createcast.html">CREATE CAST</a></span><span class="refpurpose"> — define a new cast</span></dt><dt><span class="refentrytitle"><a href="sql-createcollation.html">CREATE COLLATION</a></span><span class="refpurpose"> — define a new collation</span></dt><dt><span class="refentrytitle"><a href="sql-createconversion.html">CREATE CONVERSION</a></span><span class="refpurpose"> — define a new encoding conversion</span></dt><dt><span class="refentrytitle"><a href="sql-createdatabase.html">CREATE DATABASE</a></span><span class="refpurpose"> — create a new database</span></dt><dt><span class="refentrytitle"><a href="sql-createdomain.html">CREATE DOMAIN</a></span><span class="refpurpose"> — define a new domain</span></dt><dt><span class="refentrytitle"><a href="sql-createeventtrigger.html">CREATE EVENT TRIGGER</a></span><span class="refpurpose"> — define a new event trigger</span></dt><dt><span class="refentrytitle"><a href="sql-createextension.html">CREATE EXTENSION</a></span><span class="refpurpose"> — install an extension</span></dt><dt><span class="refentrytitle"><a href="sql-createforeigndatawrapper.html">CREATE FOREIGN DATA WRAPPER</a></span><span class="refpurpose"> — define a new foreign-data wrapper</span></dt><dt><span class="refentrytitle"><a href="sql-createforeigntable.html">CREATE FOREIGN TABLE</a></span><span class="refpurpose"> — define a new foreign table</span></dt><dt><span class="refentrytitle"><a href="sql-createfunction.html">CREATE FUNCTION</a></span><span class="refpurpose"> — define a new function</span></dt><dt><span class="refentrytitle"><a href="sql-creategroup.html">CREATE GROUP</a></span><span class="refpurpose"> — define a new database role</span></dt><dt><span class="refentrytitle"><a href="sql-createindex.html">CREATE INDEX</a></span><span class="refpurpose"> — define a new index</span></dt><dt><span class="refentrytitle"><a href="sql-createlanguage.html">CREATE LANGUAGE</a></span><span class="refpurpose"> — define a new procedural language</span></dt><dt><span class="refentrytitle"><a href="sql-creatematerializedview.html">CREATE MATERIALIZED VIEW</a></span><span class="refpurpose"> — define a new materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-createoperator.html">CREATE OPERATOR</a></span><span class="refpurpose"> — define a new operator</span></dt><dt><span class="refentrytitle"><a href="sql-createopclass.html">CREATE OPERATOR CLASS</a></span><span class="refpurpose"> — define a new operator class</span></dt><dt><span class="refentrytitle"><a href="sql-createopfamily.html">CREATE OPERATOR FAMILY</a></span><span class="refpurpose"> — define a new operator family</span></dt><dt><span class="refentrytitle"><a href="sql-createpolicy.html">CREATE POLICY</a></span><span class="refpurpose"> — define a new row-level security policy for a table</span></dt><dt><span class="refentrytitle"><a href="sql-createprocedure.html">CREATE PROCEDURE</a></span><span class="refpurpose"> — define a new procedure</span></dt><dt><span class="refentrytitle"><a href="sql-createpublication.html">CREATE PUBLICATION</a></span><span class="refpurpose"> — define a new publication</span></dt><dt><span class="refentrytitle"><a href="sql-createrole.html">CREATE ROLE</a></span><span class="refpurpose"> — define a new database role</span></dt><dt><span class="refentrytitle"><a href="sql-createrule.html">CREATE RULE</a></span><span class="refpurpose"> — define a new rewrite rule</span></dt><dt><span class="refentrytitle"><a href="sql-createschema.html">CREATE SCHEMA</a></span><span class="refpurpose"> — define a new schema</span></dt><dt><span class="refentrytitle"><a href="sql-createsequence.html">CREATE SEQUENCE</a></span><span class="refpurpose"> — define a new sequence generator</span></dt><dt><span class="refentrytitle"><a href="sql-createserver.html">CREATE SERVER</a></span><span class="refpurpose"> — define a new foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-createstatistics.html">CREATE STATISTICS</a></span><span class="refpurpose"> — define extended statistics</span></dt><dt><span class="refentrytitle"><a href="sql-createsubscription.html">CREATE SUBSCRIPTION</a></span><span class="refpurpose"> — define a new subscription</span></dt><dt><span class="refentrytitle"><a href="sql-createtable.html">CREATE TABLE</a></span><span class="refpurpose"> — define a new table</span></dt><dt><span class="refentrytitle"><a href="sql-createtableas.html">CREATE TABLE AS</a></span><span class="refpurpose"> — define a new table from the results of a query</span></dt><dt><span class="refentrytitle"><a href="sql-createtablespace.html">CREATE TABLESPACE</a></span><span class="refpurpose"> — define a new tablespace</span></dt><dt><span class="refentrytitle"><a href="sql-createtsconfig.html">CREATE TEXT SEARCH CONFIGURATION</a></span><span class="refpurpose"> — define a new text search configuration</span></dt><dt><span class="refentrytitle"><a href="sql-createtsdictionary.html">CREATE TEXT SEARCH DICTIONARY</a></span><span class="refpurpose"> — define a new text search dictionary</span></dt><dt><span class="refentrytitle"><a href="sql-createtsparser.html">CREATE TEXT SEARCH PARSER</a></span><span class="refpurpose"> — define a new text search parser</span></dt><dt><span class="refentrytitle"><a href="sql-createtstemplate.html">CREATE TEXT SEARCH TEMPLATE</a></span><span class="refpurpose"> — define a new text search template</span></dt><dt><span class="refentrytitle"><a href="sql-createtransform.html">CREATE TRANSFORM</a></span><span class="refpurpose"> — define a new transform</span></dt><dt><span class="refentrytitle"><a href="sql-createtrigger.html">CREATE TRIGGER</a></span><span class="refpurpose"> — define a new trigger</span></dt><dt><span class="refentrytitle"><a href="sql-createtype.html">CREATE TYPE</a></span><span class="refpurpose"> — define a new data type</span></dt><dt><span class="refentrytitle"><a href="sql-createuser.html">CREATE USER</a></span><span class="refpurpose"> — define a new database role</span></dt><dt><span class="refentrytitle"><a href="sql-createusermapping.html">CREATE USER MAPPING</a></span><span class="refpurpose"> — define a new mapping of a user to a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-createview.html">CREATE VIEW</a></span><span class="refpurpose"> — define a new view</span></dt><dt><span class="refentrytitle"><a href="sql-deallocate.html">DEALLOCATE</a></span><span class="refpurpose"> — deallocate a prepared statement</span></dt><dt><span class="refentrytitle"><a href="sql-declare.html">DECLARE</a></span><span class="refpurpose"> — define a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-delete.html">DELETE</a></span><span class="refpurpose"> — delete rows of a table</span></dt><dt><span class="refentrytitle"><a href="sql-discard.html">DISCARD</a></span><span class="refpurpose"> — discard session state</span></dt><dt><span class="refentrytitle"><a href="sql-do.html">DO</a></span><span class="refpurpose"> — execute an anonymous code block</span></dt><dt><span class="refentrytitle"><a href="sql-drop-access-method.html">DROP ACCESS METHOD</a></span><span class="refpurpose"> — remove an access method</span></dt><dt><span class="refentrytitle"><a href="sql-dropaggregate.html">DROP AGGREGATE</a></span><span class="refpurpose"> — remove an aggregate function</span></dt><dt><span class="refentrytitle"><a href="sql-dropcast.html">DROP CAST</a></span><span class="refpurpose"> — remove a cast</span></dt><dt><span class="refentrytitle"><a href="sql-dropcollation.html">DROP COLLATION</a></span><span class="refpurpose"> — remove a collation</span></dt><dt><span class="refentrytitle"><a href="sql-dropconversion.html">DROP CONVERSION</a></span><span class="refpurpose"> — remove a conversion</span></dt><dt><span class="refentrytitle"><a href="sql-dropdatabase.html">DROP DATABASE</a></span><span class="refpurpose"> — remove a database</span></dt><dt><span class="refentrytitle"><a href="sql-dropdomain.html">DROP DOMAIN</a></span><span class="refpurpose"> — remove a domain</span></dt><dt><span class="refentrytitle"><a href="sql-dropeventtrigger.html">DROP EVENT TRIGGER</a></span><span class="refpurpose"> — remove an event trigger</span></dt><dt><span class="refentrytitle"><a href="sql-dropextension.html">DROP EXTENSION</a></span><span class="refpurpose"> — remove an extension</span></dt><dt><span class="refentrytitle"><a href="sql-dropforeigndatawrapper.html">DROP FOREIGN DATA WRAPPER</a></span><span class="refpurpose"> — remove a foreign-data wrapper</span></dt><dt><span class="refentrytitle"><a href="sql-dropforeigntable.html">DROP FOREIGN TABLE</a></span><span class="refpurpose"> — remove a foreign table</span></dt><dt><span class="refentrytitle"><a href="sql-dropfunction.html">DROP FUNCTION</a></span><span class="refpurpose"> — remove a function</span></dt><dt><span class="refentrytitle"><a href="sql-dropgroup.html">DROP GROUP</a></span><span class="refpurpose"> — remove a database role</span></dt><dt><span class="refentrytitle"><a href="sql-dropindex.html">DROP INDEX</a></span><span class="refpurpose"> — remove an index</span></dt><dt><span class="refentrytitle"><a href="sql-droplanguage.html">DROP LANGUAGE</a></span><span class="refpurpose"> — remove a procedural language</span></dt><dt><span class="refentrytitle"><a href="sql-dropmaterializedview.html">DROP MATERIALIZED VIEW</a></span><span class="refpurpose"> — remove a materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-dropoperator.html">DROP OPERATOR</a></span><span class="refpurpose"> — remove an operator</span></dt><dt><span class="refentrytitle"><a href="sql-dropopclass.html">DROP OPERATOR CLASS</a></span><span class="refpurpose"> — remove an operator class</span></dt><dt><span class="refentrytitle"><a href="sql-dropopfamily.html">DROP OPERATOR FAMILY</a></span><span class="refpurpose"> — remove an operator family</span></dt><dt><span class="refentrytitle"><a href="sql-drop-owned.html">DROP OWNED</a></span><span class="refpurpose"> — remove database objects owned by a database role</span></dt><dt><span class="refentrytitle"><a href="sql-droppolicy.html">DROP POLICY</a></span><span class="refpurpose"> — remove a row-level security policy from a table</span></dt><dt><span class="refentrytitle"><a href="sql-dropprocedure.html">DROP PROCEDURE</a></span><span class="refpurpose"> — remove a procedure</span></dt><dt><span class="refentrytitle"><a href="sql-droppublication.html">DROP PUBLICATION</a></span><span class="refpurpose"> — remove a publication</span></dt><dt><span class="refentrytitle"><a href="sql-droprole.html">DROP ROLE</a></span><span class="refpurpose"> — remove a database role</span></dt><dt><span class="refentrytitle"><a href="sql-droproutine.html">DROP ROUTINE</a></span><span class="refpurpose"> — remove a routine</span></dt><dt><span class="refentrytitle"><a href="sql-droprule.html">DROP RULE</a></span><span class="refpurpose"> — remove a rewrite rule</span></dt><dt><span class="refentrytitle"><a href="sql-dropschema.html">DROP SCHEMA</a></span><span class="refpurpose"> — remove a schema</span></dt><dt><span class="refentrytitle"><a href="sql-dropsequence.html">DROP SEQUENCE</a></span><span class="refpurpose"> — remove a sequence</span></dt><dt><span class="refentrytitle"><a href="sql-dropserver.html">DROP SERVER</a></span><span class="refpurpose"> — remove a foreign server descriptor</span></dt><dt><span class="refentrytitle"><a href="sql-dropstatistics.html">DROP STATISTICS</a></span><span class="refpurpose"> — remove extended statistics</span></dt><dt><span class="refentrytitle"><a href="sql-dropsubscription.html">DROP SUBSCRIPTION</a></span><span class="refpurpose"> — remove a subscription</span></dt><dt><span class="refentrytitle"><a href="sql-droptable.html">DROP TABLE</a></span><span class="refpurpose"> — remove a table</span></dt><dt><span class="refentrytitle"><a href="sql-droptablespace.html">DROP TABLESPACE</a></span><span class="refpurpose"> — remove a tablespace</span></dt><dt><span class="refentrytitle"><a href="sql-droptsconfig.html">DROP TEXT SEARCH CONFIGURATION</a></span><span class="refpurpose"> — remove a text search configuration</span></dt><dt><span class="refentrytitle"><a href="sql-droptsdictionary.html">DROP TEXT SEARCH DICTIONARY</a></span><span class="refpurpose"> — remove a text search dictionary</span></dt><dt><span class="refentrytitle"><a href="sql-droptsparser.html">DROP TEXT SEARCH PARSER</a></span><span class="refpurpose"> — remove a text search parser</span></dt><dt><span class="refentrytitle"><a href="sql-droptstemplate.html">DROP TEXT SEARCH TEMPLATE</a></span><span class="refpurpose"> — remove a text search template</span></dt><dt><span class="refentrytitle"><a href="sql-droptransform.html">DROP TRANSFORM</a></span><span class="refpurpose"> — remove a transform</span></dt><dt><span class="refentrytitle"><a href="sql-droptrigger.html">DROP TRIGGER</a></span><span class="refpurpose"> — remove a trigger</span></dt><dt><span class="refentrytitle"><a href="sql-droptype.html">DROP TYPE</a></span><span class="refpurpose"> — remove a data type</span></dt><dt><span class="refentrytitle"><a href="sql-dropuser.html">DROP USER</a></span><span class="refpurpose"> — remove a database role</span></dt><dt><span class="refentrytitle"><a href="sql-dropusermapping.html">DROP USER MAPPING</a></span><span class="refpurpose"> — remove a user mapping for a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-dropview.html">DROP VIEW</a></span><span class="refpurpose"> — remove a view</span></dt><dt><span class="refentrytitle"><a href="sql-end.html">END</a></span><span class="refpurpose"> — commit the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-execute.html">EXECUTE</a></span><span class="refpurpose"> — execute a prepared statement</span></dt><dt><span class="refentrytitle"><a href="sql-explain.html">EXPLAIN</a></span><span class="refpurpose"> — show the execution plan of a statement</span></dt><dt><span class="refentrytitle"><a href="sql-fetch.html">FETCH</a></span><span class="refpurpose"> — retrieve rows from a query using a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-grant.html">GRANT</a></span><span class="refpurpose"> — define access privileges</span></dt><dt><span class="refentrytitle"><a href="sql-importforeignschema.html">IMPORT FOREIGN SCHEMA</a></span><span class="refpurpose"> — import table definitions from a foreign server</span></dt><dt><span class="refentrytitle"><a href="sql-insert.html">INSERT</a></span><span class="refpurpose"> — create new rows in a table</span></dt><dt><span class="refentrytitle"><a href="sql-listen.html">LISTEN</a></span><span class="refpurpose"> — listen for a notification</span></dt><dt><span class="refentrytitle"><a href="sql-load.html">LOAD</a></span><span class="refpurpose"> — load a shared library file</span></dt><dt><span class="refentrytitle"><a href="sql-lock.html">LOCK</a></span><span class="refpurpose"> — lock a table</span></dt><dt><span class="refentrytitle"><a href="sql-merge.html">MERGE</a></span><span class="refpurpose"> — conditionally insert, update, or delete rows of a table</span></dt><dt><span class="refentrytitle"><a href="sql-move.html">MOVE</a></span><span class="refpurpose"> — position a cursor</span></dt><dt><span class="refentrytitle"><a href="sql-notify.html">NOTIFY</a></span><span class="refpurpose"> — generate a notification</span></dt><dt><span class="refentrytitle"><a href="sql-prepare.html">PREPARE</a></span><span class="refpurpose"> — prepare a statement for execution</span></dt><dt><span class="refentrytitle"><a href="sql-prepare-transaction.html">PREPARE TRANSACTION</a></span><span class="refpurpose"> — prepare the current transaction for two-phase commit</span></dt><dt><span class="refentrytitle"><a href="sql-reassign-owned.html">REASSIGN OWNED</a></span><span class="refpurpose"> — change the ownership of database objects owned by a database role</span></dt><dt><span class="refentrytitle"><a href="sql-refreshmaterializedview.html">REFRESH MATERIALIZED VIEW</a></span><span class="refpurpose"> — replace the contents of a materialized view</span></dt><dt><span class="refentrytitle"><a href="sql-reindex.html">REINDEX</a></span><span class="refpurpose"> — rebuild indexes</span></dt><dt><span class="refentrytitle"><a href="sql-release-savepoint.html">RELEASE SAVEPOINT</a></span><span class="refpurpose"> — destroy a previously defined savepoint</span></dt><dt><span class="refentrytitle"><a href="sql-reset.html">RESET</a></span><span class="refpurpose"> — restore the value of a run-time parameter to the default value</span></dt><dt><span class="refentrytitle"><a href="sql-revoke.html">REVOKE</a></span><span class="refpurpose"> — remove access privileges</span></dt><dt><span class="refentrytitle"><a href="sql-rollback.html">ROLLBACK</a></span><span class="refpurpose"> — abort the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-rollback-prepared.html">ROLLBACK PREPARED</a></span><span class="refpurpose"> — cancel a transaction that was earlier prepared for two-phase commit</span></dt><dt><span class="refentrytitle"><a href="sql-rollback-to.html">ROLLBACK TO SAVEPOINT</a></span><span class="refpurpose"> — roll back to a savepoint</span></dt><dt><span class="refentrytitle"><a href="sql-savepoint.html">SAVEPOINT</a></span><span class="refpurpose"> — define a new savepoint within the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-security-label.html">SECURITY LABEL</a></span><span class="refpurpose"> — define or change a security label applied to an object</span></dt><dt><span class="refentrytitle"><a href="sql-select.html">SELECT</a></span><span class="refpurpose"> — retrieve rows from a table or view</span></dt><dt><span class="refentrytitle"><a href="sql-selectinto.html">SELECT INTO</a></span><span class="refpurpose"> — define a new table from the results of a query</span></dt><dt><span class="refentrytitle"><a href="sql-set.html">SET</a></span><span class="refpurpose"> — change a run-time parameter</span></dt><dt><span class="refentrytitle"><a href="sql-set-constraints.html">SET CONSTRAINTS</a></span><span class="refpurpose"> — set constraint check timing for the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-set-role.html">SET ROLE</a></span><span class="refpurpose"> — set the current user identifier of the current session</span></dt><dt><span class="refentrytitle"><a href="sql-set-session-authorization.html">SET SESSION AUTHORIZATION</a></span><span class="refpurpose"> — set the session user identifier and the current user identifier of the current session</span></dt><dt><span class="refentrytitle"><a href="sql-set-transaction.html">SET TRANSACTION</a></span><span class="refpurpose"> — set the characteristics of the current transaction</span></dt><dt><span class="refentrytitle"><a href="sql-show.html">SHOW</a></span><span class="refpurpose"> — show the value of a run-time parameter</span></dt><dt><span class="refentrytitle"><a href="sql-start-transaction.html">START TRANSACTION</a></span><span class="refpurpose"> — start a transaction block</span></dt><dt><span class="refentrytitle"><a href="sql-truncate.html">TRUNCATE</a></span><span class="refpurpose"> — empty a table or set of tables</span></dt><dt><span class="refentrytitle"><a href="sql-unlisten.html">UNLISTEN</a></span><span class="refpurpose"> — stop listening for a notification</span></dt><dt><span class="refentrytitle"><a href="sql-update.html">UPDATE</a></span><span class="refpurpose"> — update rows of a table</span></dt><dt><span class="refentrytitle"><a href="sql-vacuum.html">VACUUM</a></span><span class="refpurpose"> — garbage-collect and optionally analyze a database</span></dt><dt><span class="refentrytitle"><a href="sql-values.html">VALUES</a></span><span class="refpurpose"> — compute a set of rows</span></dt></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="reference.html" title="Part VI. Reference">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="reference.html" title="Part VI. Reference">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-abort.html" title="ABORT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part VI. Reference </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ABORT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-comment.html b/doc/src/sgml/html/sql-comment.html
new file mode 100644
index 0000000..bfd2066
--- /dev/null
+++ b/doc/src/sgml/html/sql-comment.html
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>COMMENT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-cluster.html" title="CLUSTER" /><link rel="next" href="sql-commit.html" title="COMMIT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">COMMENT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-cluster.html" title="CLUSTER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-commit.html" title="COMMIT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-COMMENT"><div class="titlepage"></div><a id="id-1.9.3.52.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">COMMENT</span></h2><p>COMMENT — define or change the comment of an object</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+COMMENT ON
+{
+ ACCESS METHOD <em class="replaceable"><code>object_name</code></em> |
+ AGGREGATE <em class="replaceable"><code>aggregate_name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> ) |
+ CAST (<em class="replaceable"><code>source_type</code></em> AS <em class="replaceable"><code>target_type</code></em>) |
+ COLLATION <em class="replaceable"><code>object_name</code></em> |
+ COLUMN <em class="replaceable"><code>relation_name</code></em>.<em class="replaceable"><code>column_name</code></em> |
+ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ON <em class="replaceable"><code>table_name</code></em> |
+ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ON DOMAIN <em class="replaceable"><code>domain_name</code></em> |
+ CONVERSION <em class="replaceable"><code>object_name</code></em> |
+ DATABASE <em class="replaceable"><code>object_name</code></em> |
+ DOMAIN <em class="replaceable"><code>object_name</code></em> |
+ EXTENSION <em class="replaceable"><code>object_name</code></em> |
+ EVENT TRIGGER <em class="replaceable"><code>object_name</code></em> |
+ FOREIGN DATA WRAPPER <em class="replaceable"><code>object_name</code></em> |
+ FOREIGN TABLE <em class="replaceable"><code>object_name</code></em> |
+ FUNCTION <em class="replaceable"><code>function_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ INDEX <em class="replaceable"><code>object_name</code></em> |
+ LARGE OBJECT <em class="replaceable"><code>large_object_oid</code></em> |
+ MATERIALIZED VIEW <em class="replaceable"><code>object_name</code></em> |
+ OPERATOR <em class="replaceable"><code>operator_name</code></em> (<em class="replaceable"><code>left_type</code></em>, <em class="replaceable"><code>right_type</code></em>) |
+ OPERATOR CLASS <em class="replaceable"><code>object_name</code></em> USING <em class="replaceable"><code>index_method</code></em> |
+ OPERATOR FAMILY <em class="replaceable"><code>object_name</code></em> USING <em class="replaceable"><code>index_method</code></em> |
+ POLICY <em class="replaceable"><code>policy_name</code></em> ON <em class="replaceable"><code>table_name</code></em> |
+ [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>object_name</code></em> |
+ PROCEDURE <em class="replaceable"><code>procedure_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ PUBLICATION <em class="replaceable"><code>object_name</code></em> |
+ ROLE <em class="replaceable"><code>object_name</code></em> |
+ ROUTINE <em class="replaceable"><code>routine_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ RULE <em class="replaceable"><code>rule_name</code></em> ON <em class="replaceable"><code>table_name</code></em> |
+ SCHEMA <em class="replaceable"><code>object_name</code></em> |
+ SEQUENCE <em class="replaceable"><code>object_name</code></em> |
+ SERVER <em class="replaceable"><code>object_name</code></em> |
+ STATISTICS <em class="replaceable"><code>object_name</code></em> |
+ SUBSCRIPTION <em class="replaceable"><code>object_name</code></em> |
+ TABLE <em class="replaceable"><code>object_name</code></em> |
+ TABLESPACE <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH CONFIGURATION <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH DICTIONARY <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH PARSER <em class="replaceable"><code>object_name</code></em> |
+ TEXT SEARCH TEMPLATE <em class="replaceable"><code>object_name</code></em> |
+ TRANSFORM FOR <em class="replaceable"><code>type_name</code></em> LANGUAGE <em class="replaceable"><code>lang_name</code></em> |
+ TRIGGER <em class="replaceable"><code>trigger_name</code></em> ON <em class="replaceable"><code>table_name</code></em> |
+ TYPE <em class="replaceable"><code>object_name</code></em> |
+ VIEW <em class="replaceable"><code>object_name</code></em>
+} IS { <em class="replaceable"><code>string_literal</code></em> | NULL }
+
+<span class="phrase">where <em class="replaceable"><code>aggregate_signature</code></em> is:</span>
+
+* |
+[ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] |
+[ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] ] ORDER BY [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.52.5"><h2>Description</h2><p>
+ <code class="command">COMMENT</code> stores a comment about a database object.
+ </p><p>
+ Only one comment string is stored for each object, so to modify a comment,
+ issue a new <code class="command">COMMENT</code> command for the same object. To remove a
+ comment, write <code class="literal">NULL</code> in place of the text string.
+ Comments are automatically dropped when their object is dropped.
+ </p><p>
+ A <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock is acquired on the
+ object to be commented.
+ </p><p>
+ For most kinds of object, only the object's owner can set the comment.
+ Roles don't have owners, so the rule for <code class="literal">COMMENT ON ROLE</code> is
+ that you must be superuser to comment on a superuser role, or have the
+ <code class="literal">CREATEROLE</code> privilege to comment on non-superuser roles.
+ Likewise, access methods don't have owners either; you must be superuser
+ to comment on an access method.
+ Of course, a superuser can comment on anything.
+ </p><p>
+ Comments can be viewed using <span class="application">psql</span>'s
+ <code class="command">\d</code> family of commands.
+ Other user interfaces to retrieve comments can be built atop
+ the same built-in functions that <span class="application">psql</span> uses, namely
+ <code class="function">obj_description</code>, <code class="function">col_description</code>,
+ and <code class="function">shobj_description</code>
+ (see <a class="xref" href="functions-info.html#FUNCTIONS-INFO-COMMENT-TABLE" title="Table 9.77. Comment Information Functions">Table 9.77</a>).
+ </p></div><div class="refsect1" id="id-1.9.3.52.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>object_name</code></em><br /></span><span class="term"><em class="replaceable"><code>relation_name</code></em>.<em class="replaceable"><code>column_name</code></em><br /></span><span class="term"><em class="replaceable"><code>aggregate_name</code></em><br /></span><span class="term"><em class="replaceable"><code>constraint_name</code></em><br /></span><span class="term"><em class="replaceable"><code>function_name</code></em><br /></span><span class="term"><em class="replaceable"><code>operator_name</code></em><br /></span><span class="term"><em class="replaceable"><code>policy_name</code></em><br /></span><span class="term"><em class="replaceable"><code>procedure_name</code></em><br /></span><span class="term"><em class="replaceable"><code>routine_name</code></em><br /></span><span class="term"><em class="replaceable"><code>rule_name</code></em><br /></span><span class="term"><em class="replaceable"><code>trigger_name</code></em></span></dt><dd><p>
+ The name of the object to be commented. Names of objects that reside in
+ schemas (tables, functions, etc.) can be
+ schema-qualified. When commenting on a column,
+ <em class="replaceable"><code>relation_name</code></em> must refer
+ to a table, view, composite type, or foreign table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em><br /></span><span class="term"><em class="replaceable"><code>domain_name</code></em></span></dt><dd><p>
+ When creating a comment on a constraint, a trigger, a rule or
+ a policy these parameters specify the name of the table or domain on
+ which that object is defined.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_type</code></em></span></dt><dd><p>
+ The name of the source data type of the cast.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>target_type</code></em></span></dt><dd><p>
+ The name of the target data type of the cast.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of a function, procedure, or aggregate
+ argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ Note that <code class="command">COMMENT</code> does not actually pay
+ any attention to <code class="literal">OUT</code> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <code class="literal">IN</code>, <code class="literal">INOUT</code>,
+ and <code class="literal">VARIADIC</code> arguments.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of a function, procedure, or aggregate argument.
+ Note that <code class="command">COMMENT</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type of a function, procedure, or aggregate argument.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>large_object_oid</code></em></span></dt><dd><p>
+ The OID of the large object.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>left_type</code></em><br /></span><span class="term"><em class="replaceable"><code>right_type</code></em></span></dt><dd><p>
+ The data type(s) of the operator's arguments (optionally
+ schema-qualified). Write <code class="literal">NONE</code> for the missing argument
+ of a prefix operator.
+ </p></dd><dt><span class="term"><code class="literal">PROCEDURAL</code></span></dt><dd><p>
+ This is a noise word.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>type_name</code></em></span></dt><dd><p>
+ The name of the data type of the transform.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the language of the transform.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>string_literal</code></em></span></dt><dd><p>
+ The new comment contents, written as a string literal.
+ </p></dd><dt><span class="term"><code class="literal">NULL</code></span></dt><dd><p>
+ Write <code class="literal">NULL</code> to drop the comment.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.52.7"><h2>Notes</h2><p>
+ There is presently no security mechanism for viewing comments: any user
+ connected to a database can see all the comments for objects in
+ that database. For shared objects such as
+ databases, roles, and tablespaces, comments are stored globally so any
+ user connected to any database in the cluster can see all the comments
+ for shared objects. Therefore, don't put security-critical
+ information in comments.
+ </p></div><div class="refsect1" id="id-1.9.3.52.8"><h2>Examples</h2><p>
+ Attach a comment to the table <code class="literal">mytable</code>:
+
+</p><pre class="programlisting">
+COMMENT ON TABLE mytable IS 'This is my table.';
+</pre><p>
+
+ Remove it again:
+
+</p><pre class="programlisting">
+COMMENT ON TABLE mytable IS NULL;
+</pre><p>
+ </p><p>
+ Some more examples:
+
+</p><pre class="programlisting">
+COMMENT ON ACCESS METHOD gin IS 'GIN index access method';
+COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
+COMMENT ON CAST (text AS int4) IS 'Allow casts from text to int4';
+COMMENT ON COLLATION "fr_CA" IS 'Canadian French';
+COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
+COMMENT ON CONVERSION my_conv IS 'Conversion to UTF8';
+COMMENT ON CONSTRAINT bar_col_cons ON bar IS 'Constrains column col';
+COMMENT ON CONSTRAINT dom_col_constr ON DOMAIN dom IS 'Constrains col of domain';
+COMMENT ON DATABASE my_database IS 'Development Database';
+COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
+COMMENT ON EVENT TRIGGER abort_ddl IS 'Aborts all DDL commands';
+COMMENT ON EXTENSION hstore IS 'implements the hstore data type';
+COMMENT ON FOREIGN DATA WRAPPER mywrapper IS 'my foreign data wrapper';
+COMMENT ON FOREIGN TABLE my_foreign_table IS 'Employee Information in other database';
+COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral';
+COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee ID';
+COMMENT ON LANGUAGE plpython IS 'Python support for stored procedures';
+COMMENT ON LARGE OBJECT 346344 IS 'Planning document';
+COMMENT ON MATERIALIZED VIEW my_matview IS 'Summary of order history';
+COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts';
+COMMENT ON OPERATOR - (NONE, integer) IS 'Unary minus';
+COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for btrees';
+COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'all integer operators for btrees';
+COMMENT ON POLICY my_policy ON mytable IS 'Filter rows by users';
+COMMENT ON PROCEDURE my_proc (integer, integer) IS 'Runs a report';
+COMMENT ON PUBLICATION alltables IS 'Publishes all operations on all tables';
+COMMENT ON ROLE my_role IS 'Administration group for finance tables';
+COMMENT ON ROUTINE my_routine (integer, integer) IS 'Runs a routine (which is a function or procedure)';
+COMMENT ON RULE my_rule ON my_table IS 'Logs updates of employee records';
+COMMENT ON SCHEMA my_schema IS 'Departmental data';
+COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
+COMMENT ON SERVER myserver IS 'my foreign server';
+COMMENT ON STATISTICS my_statistics IS 'Improves planner row estimations';
+COMMENT ON SUBSCRIPTION alltables IS 'Subscription for all operations on all tables';
+COMMENT ON TABLE my_schema.my_table IS 'Employee Information';
+COMMENT ON TABLESPACE my_tablespace IS 'Tablespace for indexes';
+COMMENT ON TEXT SEARCH CONFIGURATION my_config IS 'Special word filtering';
+COMMENT ON TEXT SEARCH DICTIONARY swedish IS 'Snowball stemmer for Swedish language';
+COMMENT ON TEXT SEARCH PARSER my_parser IS 'Splits text into words';
+COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'Snowball stemmer';
+COMMENT ON TRANSFORM FOR hstore LANGUAGE plpython3u IS 'Transform between hstore and Python dict';
+COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for RI';
+COMMENT ON TYPE complex IS 'Complex number data type';
+COMMENT ON VIEW my_view IS 'View of departmental costs';
+</pre></div><div class="refsect1" id="id-1.9.3.52.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">COMMENT</code> command in the SQL standard.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-cluster.html" title="CLUSTER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-commit.html" title="COMMIT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CLUSTER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> COMMIT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-commit-prepared.html b/doc/src/sgml/html/sql-commit-prepared.html
new file mode 100644
index 0000000..2df89a1
--- /dev/null
+++ b/doc/src/sgml/html/sql-commit-prepared.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>COMMIT PREPARED</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-commit.html" title="COMMIT" /><link rel="next" href="sql-copy.html" title="COPY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">COMMIT PREPARED</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-commit.html" title="COMMIT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-copy.html" title="COPY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-COMMIT-PREPARED"><div class="titlepage"></div><a id="id-1.9.3.54.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">COMMIT PREPARED</span></h2><p>COMMIT PREPARED — commit a transaction that was earlier prepared for two-phase commit</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+COMMIT PREPARED <em class="replaceable"><code>transaction_id</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.54.5"><h2>Description</h2><p>
+ <code class="command">COMMIT PREPARED</code> commits a transaction that is in
+ prepared state.
+ </p></div><div class="refsect1" id="id-1.9.3.54.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>transaction_id</code></em></span></dt><dd><p>
+ The transaction identifier of the transaction that is to be
+ committed.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.54.7"><h2>Notes</h2><p>
+ To commit a prepared transaction, you must be either the same user that
+ executed the transaction originally, or a superuser. But you do not
+ have to be in the same session that executed the transaction.
+ </p><p>
+ This command cannot be executed inside a transaction block. The prepared
+ transaction is committed immediately.
+ </p><p>
+ All currently available prepared transactions are listed in the
+ <a class="link" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts"><code class="structname">pg_prepared_xacts</code></a>
+ system view.
+ </p></div><div class="refsect1" id="SQL-COMMIT-PREPARED-EXAMPLES"><h2>Examples</h2><p>
+ Commit the transaction identified by the transaction
+ identifier <code class="literal">foobar</code>:
+
+</p><pre class="programlisting">
+COMMIT PREPARED 'foobar';
+</pre></div><div class="refsect1" id="id-1.9.3.54.9"><h2>Compatibility</h2><p>
+ <code class="command">COMMIT PREPARED</code> is a
+ <span class="productname">PostgreSQL</span> extension. It is intended for use by
+ external transaction management systems, some of which are covered by
+ standards (such as X/Open XA), but the SQL side of those systems is not
+ standardized.
+ </p></div><div class="refsect1" id="id-1.9.3.54.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a>, <a class="xref" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED"><span class="refentrytitle">ROLLBACK PREPARED</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-commit.html" title="COMMIT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-copy.html" title="COPY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">COMMIT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> COPY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-commit.html b/doc/src/sgml/html/sql-commit.html
new file mode 100644
index 0000000..85c4bc0
--- /dev/null
+++ b/doc/src/sgml/html/sql-commit.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>COMMIT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-comment.html" title="COMMENT" /><link rel="next" href="sql-commit-prepared.html" title="COMMIT PREPARED" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">COMMIT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-comment.html" title="COMMENT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-commit-prepared.html" title="COMMIT PREPARED">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-COMMIT"><div class="titlepage"></div><a id="id-1.9.3.53.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">COMMIT</span></h2><p>COMMIT — commit the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</pre></div><div class="refsect1" id="id-1.9.3.53.5"><h2>Description</h2><p>
+ <code class="command">COMMIT</code> commits the current transaction. All
+ changes made by the transaction become visible to others
+ and are guaranteed to be durable if a crash occurs.
+ </p></div><div class="refsect1" id="id-1.9.3.53.6"><h2>Parameters</h2><a id="id-1.9.3.53.6.2" class="indexterm"></a><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">WORK</code><br /></span><span class="term"><code class="literal">TRANSACTION</code></span></dt><dd><p>
+ Optional key words. They have no effect.
+ </p></dd><dt id="SQL-COMMIT-CHAIN"><span class="term"><code class="literal">AND CHAIN</code></span></dt><dd><p>
+ If <code class="literal">AND CHAIN</code> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.53.7"><h2>Notes</h2><p>
+ Use <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a> to
+ abort a transaction.
+ </p><p>
+ Issuing <code class="command">COMMIT</code> when not inside a transaction does
+ no harm, but it will provoke a warning message. <code class="command">COMMIT AND
+ CHAIN</code> when not inside a transaction is an error.
+ </p></div><div class="refsect1" id="id-1.9.3.53.8"><h2>Examples</h2><p>
+ To commit the current transaction and make all changes permanent:
+</p><pre class="programlisting">
+COMMIT;
+</pre></div><div class="refsect1" id="id-1.9.3.53.9"><h2>Compatibility</h2><p>
+ The command <code class="command">COMMIT</code> conforms to the SQL standard. The
+ form <code class="literal">COMMIT TRANSACTION</code> is a PostgreSQL extension.
+ </p></div><div class="refsect1" id="id-1.9.3.53.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-comment.html" title="COMMENT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-commit-prepared.html" title="COMMIT PREPARED">Next</a></td></tr><tr><td width="40%" align="left" valign="top">COMMENT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> COMMIT PREPARED</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-copy.html b/doc/src/sgml/html/sql-copy.html
new file mode 100644
index 0000000..4014358
--- /dev/null
+++ b/doc/src/sgml/html/sql-copy.html
@@ -0,0 +1,641 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>COPY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-commit-prepared.html" title="COMMIT PREPARED" /><link rel="next" href="sql-create-access-method.html" title="CREATE ACCESS METHOD" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">COPY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-commit-prepared.html" title="COMMIT PREPARED">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-create-access-method.html" title="CREATE ACCESS METHOD">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-COPY"><div class="titlepage"></div><a id="id-1.9.3.55.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">COPY</span></h2><p>COPY — copy data between a file and a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+COPY <em class="replaceable"><code>table_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ FROM { '<em class="replaceable"><code>filename</code></em>' | PROGRAM '<em class="replaceable"><code>command</code></em>' | STDIN }
+ [ [ WITH ] ( <em class="replaceable"><code>option</code></em> [, ...] ) ]
+ [ WHERE <em class="replaceable"><code>condition</code></em> ]
+
+COPY { <em class="replaceable"><code>table_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ] | ( <em class="replaceable"><code>query</code></em> ) }
+ TO { '<em class="replaceable"><code>filename</code></em>' | PROGRAM '<em class="replaceable"><code>command</code></em>' | STDOUT }
+ [ [ WITH ] ( <em class="replaceable"><code>option</code></em> [, ...] ) ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be one of:</span>
+
+ FORMAT <em class="replaceable"><code>format_name</code></em>
+ FREEZE [ <em class="replaceable"><code>boolean</code></em> ]
+ DELIMITER '<em class="replaceable"><code>delimiter_character</code></em>'
+ NULL '<em class="replaceable"><code>null_string</code></em>'
+ HEADER [ <em class="replaceable"><code>boolean</code></em> | MATCH ]
+ QUOTE '<em class="replaceable"><code>quote_character</code></em>'
+ ESCAPE '<em class="replaceable"><code>escape_character</code></em>'
+ FORCE_QUOTE { ( <em class="replaceable"><code>column_name</code></em> [, ...] ) | * }
+ FORCE_NOT_NULL ( <em class="replaceable"><code>column_name</code></em> [, ...] )
+ FORCE_NULL ( <em class="replaceable"><code>column_name</code></em> [, ...] )
+ ENCODING '<em class="replaceable"><code>encoding_name</code></em>'
+</pre></div><div class="refsect1" id="id-1.9.3.55.5"><h2>Description</h2><p>
+ <code class="command">COPY</code> moves data between
+ <span class="productname">PostgreSQL</span> tables and standard file-system
+ files. <code class="command">COPY TO</code> copies the contents of a table
+ <span class="emphasis"><em>to</em></span> a file, while <code class="command">COPY FROM</code> copies
+ data <span class="emphasis"><em>from</em></span> a file to a table (appending the data to
+ whatever is in the table already). <code class="command">COPY TO</code>
+ can also copy the results of a <code class="command">SELECT</code> query.
+ </p><p>
+ If a column list is specified, <code class="command">COPY TO</code> copies only
+ the data in the specified columns to the file. For <code class="command">COPY
+ FROM</code>, each field in the file is inserted, in order, into the
+ specified column. Table columns not specified in the <code class="command">COPY
+ FROM</code> column list will receive their default values.
+ </p><p>
+ <code class="command">COPY</code> with a file name instructs the
+ <span class="productname">PostgreSQL</span> server to directly read from
+ or write to a file. The file must be accessible by the
+ <span class="productname">PostgreSQL</span> user (the user ID the server
+ runs as) and the name must be specified from the viewpoint of the
+ server. When <code class="literal">PROGRAM</code> is specified, the server
+ executes the given command and reads from the standard output of the
+ program, or writes to the standard input of the program. The command
+ must be specified from the viewpoint of the server, and be executable
+ by the <span class="productname">PostgreSQL</span> user. When
+ <code class="literal">STDIN</code> or <code class="literal">STDOUT</code> is
+ specified, data is transmitted via the connection between the
+ client and the server.
+ </p><p>
+ Each backend running <code class="command">COPY</code> will report its progress
+ in the <code class="structname">pg_stat_progress_copy</code> view. See
+ <a class="xref" href="progress-reporting.html#COPY-PROGRESS-REPORTING" title="28.4.6. COPY Progress Reporting">Section 28.4.6</a> for details.
+ </p></div><div class="refsect1" id="id-1.9.3.55.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ An optional list of columns to be copied. If no column list is
+ specified, all columns of the table except generated columns will be
+ copied.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a>,
+ <a class="link" href="sql-values.html" title="VALUES"><code class="command">VALUES</code></a>,
+ <a class="link" href="sql-insert.html" title="INSERT"><code class="command">INSERT</code></a>,
+ <a class="link" href="sql-update.html" title="UPDATE"><code class="command">UPDATE</code></a>, or
+ <a class="link" href="sql-delete.html" title="DELETE"><code class="command">DELETE</code></a> command whose results are to be
+ copied. Note that parentheses are required around the query.
+ </p><p>
+ For <code class="command">INSERT</code>, <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code> queries a RETURNING clause must be provided,
+ and the target relation must not have a conditional rule, nor
+ an <code class="literal">ALSO</code> rule, nor an <code class="literal">INSTEAD</code> rule
+ that expands to multiple statements.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>filename</code></em></span></dt><dd><p>
+ The path name of the input or output file. An input file name can be
+ an absolute or relative path, but an output file name must be an absolute
+ path. Windows users might need to use an <code class="literal">E''</code> string and
+ double any backslashes used in the path name.
+ </p></dd><dt><span class="term"><code class="literal">PROGRAM</code></span></dt><dd><p>
+ A command to execute. In <code class="command">COPY FROM</code>, the input is
+ read from standard output of the command, and in <code class="command">COPY TO</code>,
+ the output is written to the standard input of the command.
+ </p><p>
+ Note that the command is invoked by the shell, so if you need to pass
+ any arguments to shell command that come from an untrusted source, you
+ must be careful to strip or escape any special characters that might
+ have a special meaning for the shell. For security reasons, it is best
+ to use a fixed command string, or at least avoid passing any user input
+ in it.
+ </p></dd><dt><span class="term"><code class="literal">STDIN</code></span></dt><dd><p>
+ Specifies that input comes from the client application.
+ </p></dd><dt><span class="term"><code class="literal">STDOUT</code></span></dt><dd><p>
+ Specifies that output goes to the client application.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>boolean</code></em></span></dt><dd><p>
+ Specifies whether the selected option should be turned on or off.
+ You can write <code class="literal">TRUE</code>, <code class="literal">ON</code>, or
+ <code class="literal">1</code> to enable the option, and <code class="literal">FALSE</code>,
+ <code class="literal">OFF</code>, or <code class="literal">0</code> to disable it. The
+ <em class="replaceable"><code>boolean</code></em> value can also
+ be omitted, in which case <code class="literal">TRUE</code> is assumed.
+ </p></dd><dt><span class="term"><code class="literal">FORMAT</code></span></dt><dd><p>
+ Selects the data format to be read or written:
+ <code class="literal">text</code>,
+ <code class="literal">csv</code> (Comma Separated Values),
+ or <code class="literal">binary</code>.
+ The default is <code class="literal">text</code>.
+ </p></dd><dt><span class="term"><code class="literal">FREEZE</code></span></dt><dd><p>
+ Requests copying the data with rows already frozen, just as they
+ would be after running the <code class="command">VACUUM FREEZE</code> command.
+ This is intended as a performance option for initial data loading.
+ Rows will be frozen only if the table being loaded has been created
+ or truncated in the current subtransaction, there are no cursors
+ open and there are no older snapshots held by this transaction. It is
+ currently not possible to perform a <code class="command">COPY FREEZE</code> on
+ a partitioned table.
+ </p><p>
+ Note that all other sessions will immediately be able to see the data
+ once it has been successfully loaded. This violates the normal rules
+ of MVCC visibility and users specifying should be aware of the
+ potential problems this might cause.
+ </p></dd><dt><span class="term"><code class="literal">DELIMITER</code></span></dt><dd><p>
+ Specifies the character that separates columns within each row
+ (line) of the file. The default is a tab character in text format,
+ a comma in <code class="literal">CSV</code> format.
+ This must be a single one-byte character.
+ This option is not allowed when using <code class="literal">binary</code> format.
+ </p></dd><dt><span class="term"><code class="literal">NULL</code></span></dt><dd><p>
+ Specifies the string that represents a null value. The default is
+ <code class="literal">\N</code> (backslash-N) in text format, and an unquoted empty
+ string in <code class="literal">CSV</code> format. You might prefer an
+ empty string even in text format for cases where you don't want to
+ distinguish nulls from empty strings.
+ This option is not allowed when using <code class="literal">binary</code> format.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When using <code class="command">COPY FROM</code>, any data item that matches
+ this string will be stored as a null value, so you should make
+ sure that you use the same string as you used with
+ <code class="command">COPY TO</code>.
+ </p></div></dd><dt><span class="term"><code class="literal">HEADER</code></span></dt><dd><p>
+ Specifies that the file contains a header line with the names of each
+ column in the file. On output, the first line contains the column
+ names from the table. On input, the first line is discarded when this
+ option is set to <code class="literal">true</code> (or equivalent Boolean value).
+ If this option is set to <code class="literal">MATCH</code>, the number and names
+ of the columns in the header line must match the actual column names of
+ the table, in order; otherwise an error is raised.
+ This option is not allowed when using <code class="literal">binary</code> format.
+ The <code class="literal">MATCH</code> option is only valid for <code class="command">COPY
+ FROM</code> commands.
+ </p></dd><dt><span class="term"><code class="literal">QUOTE</code></span></dt><dd><p>
+ Specifies the quoting character to be used when a data value is quoted.
+ The default is double-quote.
+ This must be a single one-byte character.
+ This option is allowed only when using <code class="literal">CSV</code> format.
+ </p></dd><dt><span class="term"><code class="literal">ESCAPE</code></span></dt><dd><p>
+ Specifies the character that should appear before a
+ data character that matches the <code class="literal">QUOTE</code> value.
+ The default is the same as the <code class="literal">QUOTE</code> value (so that
+ the quoting character is doubled if it appears in the data).
+ This must be a single one-byte character.
+ This option is allowed only when using <code class="literal">CSV</code> format.
+ </p></dd><dt><span class="term"><code class="literal">FORCE_QUOTE</code></span></dt><dd><p>
+ Forces quoting to be
+ used for all non-<code class="literal">NULL</code> values in each specified column.
+ <code class="literal">NULL</code> output is never quoted. If <code class="literal">*</code> is specified,
+ non-<code class="literal">NULL</code> values will be quoted in all columns.
+ This option is allowed only in <code class="command">COPY TO</code>, and only when
+ using <code class="literal">CSV</code> format.
+ </p></dd><dt><span class="term"><code class="literal">FORCE_NOT_NULL</code></span></dt><dd><p>
+ Do not match the specified columns' values against the null string.
+ In the default case where the null string is empty, this means that
+ empty values will be read as zero-length strings rather than nulls,
+ even when they are not quoted.
+ This option is allowed only in <code class="command">COPY FROM</code>, and only when
+ using <code class="literal">CSV</code> format.
+ </p></dd><dt><span class="term"><code class="literal">FORCE_NULL</code></span></dt><dd><p>
+ Match the specified columns' values against the null string, even
+ if it has been quoted, and if a match is found set the value to
+ <code class="literal">NULL</code>. In the default case where the null string is empty,
+ this converts a quoted empty string into NULL.
+ This option is allowed only in <code class="command">COPY FROM</code>, and only when
+ using <code class="literal">CSV</code> format.
+ </p></dd><dt><span class="term"><code class="literal">ENCODING</code></span></dt><dd><p>
+ Specifies that the file is encoded in the <em class="replaceable"><code>encoding_name</code></em>. If this option is
+ omitted, the current client encoding is used. See the Notes below
+ for more details.
+ </p></dd><dt><span class="term"><code class="literal">WHERE</code></span></dt><dd><p>
+ The optional <code class="literal">WHERE</code> clause has the general form
+</p><pre class="synopsis">
+WHERE <em class="replaceable"><code>condition</code></em>
+</pre><p>
+ where <em class="replaceable"><code>condition</code></em> is
+ any expression that evaluates to a result of type
+ <code class="type">boolean</code>. Any row that does not satisfy this
+ condition will not be inserted to the table. A row satisfies the
+ condition if it returns true when the actual row values are
+ substituted for any variable references.
+ </p><p>
+ Currently, subqueries are not allowed in <code class="literal">WHERE</code>
+ expressions, and the evaluation does not see any changes made by the
+ <code class="command">COPY</code> itself (this matters when the expression
+ contains calls to <code class="literal">VOLATILE</code> functions).
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.55.7"><h2>Outputs</h2><p>
+ On successful completion, a <code class="command">COPY</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+COPY <em class="replaceable"><code>count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>count</code></em> is the number
+ of rows copied.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="application">psql</span> will print this command tag only if the command
+ was not <code class="literal">COPY ... TO STDOUT</code>, or the
+ equivalent <span class="application">psql</span> meta-command
+ <code class="literal">\copy ... to stdout</code>. This is to prevent confusing the
+ command tag with the data that was just printed.
+ </p></div></div><div class="refsect1" id="id-1.9.3.55.8"><h2>Notes</h2><p>
+ <code class="command">COPY TO</code> can be used only with plain
+ tables, not views, and does not copy rows from child tables
+ or child partitions. For example, <code class="literal">COPY <em class="replaceable"><code>table</code></em> TO</code> copies
+ the same rows as <code class="literal">SELECT * FROM ONLY <em class="replaceable"><code>table</code></em></code>.
+ The syntax <code class="literal">COPY (SELECT * FROM <em class="replaceable"><code>table</code></em>) TO ...</code> can be used to
+ dump all of the rows in an inheritance hierarchy, partitioned table,
+ or view.
+ </p><p>
+ <code class="command">COPY FROM</code> can be used with plain, foreign, or
+ partitioned tables or with views that have
+ <code class="literal">INSTEAD OF INSERT</code> triggers.
+ </p><p>
+ You must have select privilege on the table
+ whose values are read by <code class="command">COPY TO</code>, and
+ insert privilege on the table into which values
+ are inserted by <code class="command">COPY FROM</code>. It is sufficient
+ to have column privileges on the column(s) listed in the command.
+ </p><p>
+ If row-level security is enabled for the table, the relevant
+ <code class="command">SELECT</code> policies will apply to <code class="literal">COPY
+ <em class="replaceable"><code>table</code></em> TO</code> statements.
+ Currently, <code class="command">COPY FROM</code> is not supported for tables
+ with row-level security. Use equivalent <code class="command">INSERT</code>
+ statements instead.
+ </p><p>
+ Files named in a <code class="command">COPY</code> command are read or written
+ directly by the server, not by the client application. Therefore,
+ they must reside on or be accessible to the database server machine,
+ not the client. They must be accessible to and readable or writable
+ by the <span class="productname">PostgreSQL</span> user (the user ID the
+ server runs as), not the client. Similarly,
+ the command specified with <code class="literal">PROGRAM</code> is executed directly
+ by the server, not by the client application, must be executable by the
+ <span class="productname">PostgreSQL</span> user.
+ <code class="command">COPY</code> naming a file or command is only allowed to
+ database superusers or users who are granted one of the roles
+ <code class="literal">pg_read_server_files</code>,
+ <code class="literal">pg_write_server_files</code>,
+ or <code class="literal">pg_execute_server_program</code>, since it allows reading
+ or writing any file or running a program that the server has privileges to
+ access.
+ </p><p>
+ Do not confuse <code class="command">COPY</code> with the
+ <span class="application">psql</span> instruction
+ <code class="command"><a class="link" href="app-psql.html#APP-PSQL-META-COMMANDS-COPY">\copy</a></code>. <code class="command">\copy</code> invokes
+ <code class="command">COPY FROM STDIN</code> or <code class="command">COPY TO
+ STDOUT</code>, and then fetches/stores the data in a file
+ accessible to the <span class="application">psql</span> client. Thus,
+ file accessibility and access rights depend on the client rather
+ than the server when <code class="command">\copy</code> is used.
+ </p><p>
+ It is recommended that the file name used in <code class="command">COPY</code>
+ always be specified as an absolute path. This is enforced by the
+ server in the case of <code class="command">COPY TO</code>, but for
+ <code class="command">COPY FROM</code> you do have the option of reading from
+ a file specified by a relative path. The path will be interpreted
+ relative to the working directory of the server process (normally
+ the cluster's data directory), not the client's working directory.
+ </p><p>
+ Executing a command with <code class="literal">PROGRAM</code> might be restricted
+ by the operating system's access control mechanisms, such as SELinux.
+ </p><p>
+ <code class="command">COPY FROM</code> will invoke any triggers and check
+ constraints on the destination table. However, it will not invoke rules.
+ </p><p>
+ For identity columns, the <code class="command">COPY FROM</code> command will always
+ write the column values provided in the input data, like
+ the <code class="command">INSERT</code> option <code class="literal">OVERRIDING SYSTEM
+ VALUE</code>.
+ </p><p>
+ <code class="command">COPY</code> input and output is affected by
+ <code class="varname">DateStyle</code>. To ensure portability to other
+ <span class="productname">PostgreSQL</span> installations that might use
+ non-default <code class="varname">DateStyle</code> settings,
+ <code class="varname">DateStyle</code> should be set to <code class="literal">ISO</code> before
+ using <code class="command">COPY TO</code>. It is also a good idea to avoid dumping
+ data with <code class="varname">IntervalStyle</code> set to
+ <code class="literal">sql_standard</code>, because negative interval values might be
+ misinterpreted by a server that has a different setting for
+ <code class="varname">IntervalStyle</code>.
+ </p><p>
+ Input data is interpreted according to <code class="literal">ENCODING</code>
+ option or the current client encoding, and output data is encoded
+ in <code class="literal">ENCODING</code> or the current client encoding, even
+ if the data does not pass through the client but is read from or
+ written to a file directly by the server.
+ </p><p>
+ <code class="command">COPY</code> stops operation at the first error. This
+ should not lead to problems in the event of a <code class="command">COPY
+ TO</code>, but the target table will already have received
+ earlier rows in a <code class="command">COPY FROM</code>. These rows will not
+ be visible or accessible, but they still occupy disk space. This might
+ amount to a considerable amount of wasted disk space if the failure
+ happened well into a large copy operation. You might wish to invoke
+ <code class="command">VACUUM</code> to recover the wasted space.
+ </p><p>
+ <code class="literal">FORCE_NULL</code> and <code class="literal">FORCE_NOT_NULL</code> can be used
+ simultaneously on the same column. This results in converting quoted
+ null strings to null values and unquoted null strings to empty strings.
+ </p></div><div class="refsect1" id="id-1.9.3.55.9"><h2>File Formats</h2><div class="refsect2" id="id-1.9.3.55.9.2"><h3>Text Format</h3><p>
+ When the <code class="literal">text</code> format is used,
+ the data read or written is a text file with one line per table row.
+ Columns in a row are separated by the delimiter character.
+ The column values themselves are strings generated by the
+ output function, or acceptable to the input function, of each
+ attribute's data type. The specified null string is used in
+ place of columns that are null.
+ <code class="command">COPY FROM</code> will raise an error if any line of the
+ input file contains more or fewer columns than are expected.
+ </p><p>
+ End of data can be represented by a single line containing just
+ backslash-period (<code class="literal">\.</code>). An end-of-data marker is
+ not necessary when reading from a file, since the end of file
+ serves perfectly well; it is needed only when copying data to or from
+ client applications using pre-3.0 client protocol.
+ </p><p>
+ Backslash characters (<code class="literal">\</code>) can be used in the
+ <code class="command">COPY</code> data to quote data characters that might
+ otherwise be taken as row or column delimiters. In particular, the
+ following characters <span class="emphasis"><em>must</em></span> be preceded by a backslash if
+ they appear as part of a column value: backslash itself,
+ newline, carriage return, and the current delimiter character.
+ </p><p>
+ The specified null string is sent by <code class="command">COPY TO</code> without
+ adding any backslashes; conversely, <code class="command">COPY FROM</code> matches
+ the input against the null string before removing backslashes. Therefore,
+ a null string such as <code class="literal">\N</code> cannot be confused with
+ the actual data value <code class="literal">\N</code> (which would be represented
+ as <code class="literal">\\N</code>).
+ </p><p>
+ The following special backslash sequences are recognized by
+ <code class="command">COPY FROM</code>:
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Sequence</th><th>Represents</th></tr></thead><tbody><tr><td><code class="literal">\b</code></td><td>Backspace (ASCII 8)</td></tr><tr><td><code class="literal">\f</code></td><td>Form feed (ASCII 12)</td></tr><tr><td><code class="literal">\n</code></td><td>Newline (ASCII 10)</td></tr><tr><td><code class="literal">\r</code></td><td>Carriage return (ASCII 13)</td></tr><tr><td><code class="literal">\t</code></td><td>Tab (ASCII 9)</td></tr><tr><td><code class="literal">\v</code></td><td>Vertical tab (ASCII 11)</td></tr><tr><td><code class="literal">\</code><em class="replaceable"><code>digits</code></em></td><td>Backslash followed by one to three octal digits specifies
+ the byte with that numeric code</td></tr><tr><td><code class="literal">\x</code><em class="replaceable"><code>digits</code></em></td><td>Backslash <code class="literal">x</code> followed by one or two hex digits specifies
+ the byte with that numeric code</td></tr></tbody></table></div><p>
+
+ Presently, <code class="command">COPY TO</code> will never emit an octal or
+ hex-digits backslash sequence, but it does use the other sequences
+ listed above for those control characters.
+ </p><p>
+ Any other backslashed character that is not mentioned in the above table
+ will be taken to represent itself. However, beware of adding backslashes
+ unnecessarily, since that might accidentally produce a string matching the
+ end-of-data marker (<code class="literal">\.</code>) or the null string (<code class="literal">\N</code> by
+ default). These strings will be recognized before any other backslash
+ processing is done.
+ </p><p>
+ It is strongly recommended that applications generating <code class="command">COPY</code> data convert
+ data newlines and carriage returns to the <code class="literal">\n</code> and
+ <code class="literal">\r</code> sequences respectively. At present it is
+ possible to represent a data carriage return by a backslash and carriage
+ return, and to represent a data newline by a backslash and newline.
+ However, these representations might not be accepted in future releases.
+ They are also highly vulnerable to corruption if the <code class="command">COPY</code> file is
+ transferred across different machines (for example, from Unix to Windows
+ or vice versa).
+ </p><p>
+ All backslash sequences are interpreted after encoding conversion.
+ The bytes specified with the octal and hex-digit backslash sequences must
+ form valid characters in the database encoding.
+ </p><p>
+ <code class="command">COPY TO</code> will terminate each row with a Unix-style
+ newline (<span class="quote">“<span class="quote"><code class="literal">\n</code></span>”</span>). Servers running on Microsoft Windows instead
+ output carriage return/newline (<span class="quote">“<span class="quote"><code class="literal">\r\n</code></span>”</span>), but only for
+ <code class="command">COPY</code> to a server file; for consistency across platforms,
+ <code class="command">COPY TO STDOUT</code> always sends <span class="quote">“<span class="quote"><code class="literal">\n</code></span>”</span>
+ regardless of server platform.
+ <code class="command">COPY FROM</code> can handle lines ending with newlines,
+ carriage returns, or carriage return/newlines. To reduce the risk of
+ error due to un-backslashed newlines or carriage returns that were
+ meant as data, <code class="command">COPY FROM</code> will complain if the line
+ endings in the input are not all alike.
+ </p></div><div class="refsect2" id="id-1.9.3.55.9.3"><h3>CSV Format</h3><p>
+ This format option is used for importing and exporting the Comma
+ Separated Value (<code class="literal">CSV</code>) file format used by many other
+ programs, such as spreadsheets. Instead of the escaping rules used by
+ <span class="productname">PostgreSQL</span>'s standard text format, it
+ produces and recognizes the common CSV escaping mechanism.
+ </p><p>
+ The values in each record are separated by the <code class="literal">DELIMITER</code>
+ character. If the value contains the delimiter character, the
+ <code class="literal">QUOTE</code> character, the <code class="literal">NULL</code> string, a carriage
+ return, or line feed character, then the whole value is prefixed and
+ suffixed by the <code class="literal">QUOTE</code> character, and any occurrence
+ within the value of a <code class="literal">QUOTE</code> character or the
+ <code class="literal">ESCAPE</code> character is preceded by the escape character.
+ You can also use <code class="literal">FORCE_QUOTE</code> to force quotes when outputting
+ non-<code class="literal">NULL</code> values in specific columns.
+ </p><p>
+ The <code class="literal">CSV</code> format has no standard way to distinguish a
+ <code class="literal">NULL</code> value from an empty string.
+ <span class="productname">PostgreSQL</span>'s <code class="command">COPY</code> handles this by quoting.
+ A <code class="literal">NULL</code> is output as the <code class="literal">NULL</code> parameter string
+ and is not quoted, while a non-<code class="literal">NULL</code> value matching the
+ <code class="literal">NULL</code> parameter string is quoted. For example, with the
+ default settings, a <code class="literal">NULL</code> is written as an unquoted empty
+ string, while an empty string data value is written with double quotes
+ (<code class="literal">""</code>). Reading values follows similar rules. You can
+ use <code class="literal">FORCE_NOT_NULL</code> to prevent <code class="literal">NULL</code> input
+ comparisons for specific columns. You can also use
+ <code class="literal">FORCE_NULL</code> to convert quoted null string data values to
+ <code class="literal">NULL</code>.
+ </p><p>
+ Because backslash is not a special character in the <code class="literal">CSV</code>
+ format, <code class="literal">\.</code>, the end-of-data marker, could also appear
+ as a data value. To avoid any misinterpretation, a <code class="literal">\.</code>
+ data value appearing as a lone entry on a line is automatically
+ quoted on output, and on input, if quoted, is not interpreted as the
+ end-of-data marker. If you are loading a file created by another
+ application that has a single unquoted column and might have a
+ value of <code class="literal">\.</code>, you might need to quote that value in the
+ input file.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In <code class="literal">CSV</code> format, all characters are significant. A quoted value
+ surrounded by white space, or any characters other than
+ <code class="literal">DELIMITER</code>, will include those characters. This can cause
+ errors if you import data from a system that pads <code class="literal">CSV</code>
+ lines with white space out to some fixed width. If such a situation
+ arises you might need to preprocess the <code class="literal">CSV</code> file to remove
+ the trailing white space, before importing the data into
+ <span class="productname">PostgreSQL</span>.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ CSV format will both recognize and produce CSV files with quoted
+ values containing embedded carriage returns and line feeds. Thus
+ the files are not strictly one line per table row like text-format
+ files.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Many programs produce strange and occasionally perverse CSV files,
+ so the file format is more a convention than a standard. Thus you
+ might encounter some files that cannot be imported using this
+ mechanism, and <code class="command">COPY</code> might produce files that other
+ programs cannot process.
+ </p></div></div><div class="refsect2" id="id-1.9.3.55.9.4"><h3>Binary Format</h3><p>
+ The <code class="literal">binary</code> format option causes all data to be
+ stored/read as binary format rather than as text. It is
+ somewhat faster than the text and <code class="literal">CSV</code> formats,
+ but a binary-format file is less portable across machine architectures and
+ <span class="productname">PostgreSQL</span> versions.
+ Also, the binary format is very data type specific; for example
+ it will not work to output binary data from a <code class="type">smallint</code> column
+ and read it into an <code class="type">integer</code> column, even though that would work
+ fine in text format.
+ </p><p>
+ The <code class="literal">binary</code> file format consists
+ of a file header, zero or more tuples containing the row data, and
+ a file trailer. Headers and data are in network byte order.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> releases before 7.4 used a
+ different binary file format.
+ </p></div><div class="refsect3" id="id-1.9.3.55.9.4.5"><h4>File Header</h4><p>
+ The file header consists of 15 bytes of fixed fields, followed
+ by a variable-length header extension area. The fixed fields are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Signature</span></dt><dd><p>
+11-byte sequence <code class="literal">PGCOPY\n\377\r\n\0</code> — note that the zero byte
+is a required part of the signature. (The signature is designed to allow
+easy identification of files that have been munged by a non-8-bit-clean
+transfer. This signature will be changed by end-of-line-translation
+filters, dropped zero bytes, dropped high bits, or parity changes.)
+ </p></dd><dt><span class="term">Flags field</span></dt><dd><p>
+32-bit integer bit mask to denote important aspects of the file format. Bits
+are numbered from 0 (<acronym class="acronym">LSB</acronym>) to 31 (<acronym class="acronym">MSB</acronym>). Note that
+this field is stored in network byte order (most significant byte first),
+as are all the integer fields used in the file format. Bits
+16–31 are reserved to denote critical file format issues; a reader
+should abort if it finds an unexpected bit set in this range. Bits 0–15
+are reserved to signal backwards-compatible format issues; a reader
+should simply ignore any unexpected bits set in this range. Currently
+only one flag bit is defined, and the rest must be zero:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Bit 16</span></dt><dd><p>
+ If 1, OIDs are included in the data; if 0, not. Oid system columns
+ are not supported in <span class="productname">PostgreSQL</span>
+ anymore, but the format still contains the indicator.
+ </p></dd></dl></div></dd><dt><span class="term">Header extension area length</span></dt><dd><p>
+32-bit integer, length in bytes of remainder of header, not including self.
+Currently, this is zero, and the first tuple follows
+immediately. Future changes to the format might allow additional data
+to be present in the header. A reader should silently skip over any header
+extension data it does not know what to do with.
+ </p></dd></dl></div><p>
+ </p><p>
+The header extension area is envisioned to contain a sequence of
+self-identifying chunks. The flags field is not intended to tell readers
+what is in the extension area. Specific design of header extension contents
+is left for a later release.
+ </p><p>
+ This design allows for both backwards-compatible header additions (add
+ header extension chunks, or set low-order flag bits) and
+ non-backwards-compatible changes (set high-order flag bits to signal such
+ changes, and add supporting data to the extension area if needed).
+ </p></div><div class="refsect3" id="id-1.9.3.55.9.4.6"><h4>Tuples</h4><p>
+Each tuple begins with a 16-bit integer count of the number of fields in the
+tuple. (Presently, all tuples in a table will have the same count, but that
+might not always be true.) Then, repeated for each field in the tuple, there
+is a 32-bit length word followed by that many bytes of field data. (The
+length word does not include itself, and can be zero.) As a special case,
+-1 indicates a NULL field value. No value bytes follow in the NULL case.
+ </p><p>
+There is no alignment padding or any other extra data between fields.
+ </p><p>
+Presently, all data values in a binary-format file are
+assumed to be in binary format (format code one). It is anticipated that a
+future extension might add a header field that allows per-column format codes
+to be specified.
+ </p><p>
+To determine the appropriate binary format for the actual tuple data you
+should consult the <span class="productname">PostgreSQL</span> source, in
+particular the <code class="function">*send</code> and <code class="function">*recv</code> functions for
+each column's data type (typically these functions are found in the
+<code class="filename">src/backend/utils/adt/</code> directory of the source
+distribution).
+ </p><p>
+If OIDs are included in the file, the OID field immediately follows the
+field-count word. It is a normal field except that it's not included in the
+field-count. Note that oid system columns are not supported in current
+versions of <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect3" id="id-1.9.3.55.9.4.7"><h4>File Trailer</h4><p>
+ The file trailer consists of a 16-bit integer word containing -1. This
+ is easily distinguished from a tuple's field-count word.
+ </p><p>
+ A reader should report an error if a field-count word is neither -1
+ nor the expected number of columns. This provides an extra
+ check against somehow getting out of sync with the data.
+ </p></div></div></div><div class="refsect1" id="id-1.9.3.55.10"><h2>Examples</h2><p>
+ The following example copies a table to the client
+ using the vertical bar (<code class="literal">|</code>) as the field delimiter:
+</p><pre class="programlisting">
+COPY country TO STDOUT (DELIMITER '|');
+</pre><p>
+ </p><p>
+ To copy data from a file into the <code class="literal">country</code> table:
+</p><pre class="programlisting">
+COPY country FROM '/usr1/proj/bray/sql/country_data';
+</pre><p>
+ </p><p>
+ To copy into a file just the countries whose names start with 'A':
+</p><pre class="programlisting">
+COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy';
+</pre><p>
+ </p><p>
+ To copy into a compressed file, you can pipe the output through an external
+ compression program:
+</p><pre class="programlisting">
+COPY country TO PROGRAM 'gzip &gt; /usr1/proj/bray/sql/country_data.gz';
+</pre><p>
+ </p><p>
+ Here is a sample of data suitable for copying into a table from
+ <code class="literal">STDIN</code>:
+</p><pre class="programlisting">
+AF AFGHANISTAN
+AL ALBANIA
+DZ ALGERIA
+ZM ZAMBIA
+ZW ZIMBABWE
+</pre><p>
+ Note that the white space on each line is actually a tab character.
+ </p><p>
+ The following is the same data, output in binary format.
+ The data is shown after filtering through the
+ Unix utility <code class="command">od -c</code>. The table has three columns;
+ the first has type <code class="type">char(2)</code>, the second has type <code class="type">text</code>,
+ and the third has type <code class="type">integer</code>. All the rows have a null value
+ in the third column.
+</p><pre class="programlisting">
+0000000 P G C O P Y \n 377 \r \n \0 \0 \0 \0 \0 \0
+0000020 \0 \0 \0 \0 003 \0 \0 \0 002 A F \0 \0 \0 013 A
+0000040 F G H A N I S T A N 377 377 377 377 \0 003
+0000060 \0 \0 \0 002 A L \0 \0 \0 007 A L B A N I
+0000100 A 377 377 377 377 \0 003 \0 \0 \0 002 D Z \0 \0 \0
+0000120 007 A L G E R I A 377 377 377 377 \0 003 \0 \0
+0000140 \0 002 Z M \0 \0 \0 006 Z A M B I A 377 377
+0000160 377 377 \0 003 \0 \0 \0 002 Z W \0 \0 \0 \b Z I
+0000200 M B A B W E 377 377 377 377 377 377
+</pre></div><div class="refsect1" id="id-1.9.3.55.11"><h2>Compatibility</h2><p>
+ There is no <code class="command">COPY</code> statement in the SQL standard.
+ </p><p>
+ The following syntax was used before <span class="productname">PostgreSQL</span>
+ version 9.0 and is still supported:
+
+</p><pre class="synopsis">
+COPY <em class="replaceable"><code>table_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ FROM { '<em class="replaceable"><code>filename</code></em>' | STDIN }
+ [ [ WITH ]
+ [ BINARY ]
+ [ DELIMITER [ AS ] '<em class="replaceable"><code>delimiter_character</code></em>' ]
+ [ NULL [ AS ] '<em class="replaceable"><code>null_string</code></em>' ]
+ [ CSV [ HEADER ]
+ [ QUOTE [ AS ] '<em class="replaceable"><code>quote_character</code></em>' ]
+ [ ESCAPE [ AS ] '<em class="replaceable"><code>escape_character</code></em>' ]
+ [ FORCE NOT NULL <em class="replaceable"><code>column_name</code></em> [, ...] ] ] ]
+
+COPY { <em class="replaceable"><code>table_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ] | ( <em class="replaceable"><code>query</code></em> ) }
+ TO { '<em class="replaceable"><code>filename</code></em>' | STDOUT }
+ [ [ WITH ]
+ [ BINARY ]
+ [ DELIMITER [ AS ] '<em class="replaceable"><code>delimiter_character</code></em>' ]
+ [ NULL [ AS ] '<em class="replaceable"><code>null_string</code></em>' ]
+ [ CSV [ HEADER ]
+ [ QUOTE [ AS ] '<em class="replaceable"><code>quote_character</code></em>' ]
+ [ ESCAPE [ AS ] '<em class="replaceable"><code>escape_character</code></em>' ]
+ [ FORCE QUOTE { <em class="replaceable"><code>column_name</code></em> [, ...] | * } ] ] ]
+</pre><p>
+
+ Note that in this syntax, <code class="literal">BINARY</code> and <code class="literal">CSV</code> are
+ treated as independent keywords, not as arguments of a <code class="literal">FORMAT</code>
+ option.
+ </p><p>
+ The following syntax was used before <span class="productname">PostgreSQL</span>
+ version 7.3 and is still supported:
+
+</p><pre class="synopsis">
+COPY [ BINARY ] <em class="replaceable"><code>table_name</code></em>
+ FROM { '<em class="replaceable"><code>filename</code></em>' | STDIN }
+ [ [USING] DELIMITERS '<em class="replaceable"><code>delimiter_character</code></em>' ]
+ [ WITH NULL AS '<em class="replaceable"><code>null_string</code></em>' ]
+
+COPY [ BINARY ] <em class="replaceable"><code>table_name</code></em>
+ TO { '<em class="replaceable"><code>filename</code></em>' | STDOUT }
+ [ [USING] DELIMITERS '<em class="replaceable"><code>delimiter_character</code></em>' ]
+ [ WITH NULL AS '<em class="replaceable"><code>null_string</code></em>' ]
+</pre></div><div class="refsect1" id="id-1.9.3.55.12"><h2>See Also</h2><span class="simplelist"><a class="xref" href="progress-reporting.html#COPY-PROGRESS-REPORTING" title="28.4.6. COPY Progress Reporting">Section 28.4.6</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-commit-prepared.html" title="COMMIT PREPARED">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-create-access-method.html" title="CREATE ACCESS METHOD">Next</a></td></tr><tr><td width="40%" align="left" valign="top">COMMIT PREPARED </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE ACCESS METHOD</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-create-access-method.html b/doc/src/sgml/html/sql-create-access-method.html
new file mode 100644
index 0000000..a6f7bd7
--- /dev/null
+++ b/doc/src/sgml/html/sql-create-access-method.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE ACCESS METHOD</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-copy.html" title="COPY" /><link rel="next" href="sql-createaggregate.html" title="CREATE AGGREGATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE ACCESS METHOD</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-copy.html" title="COPY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createaggregate.html" title="CREATE AGGREGATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATE-ACCESS-METHOD"><div class="titlepage"></div><a id="id-1.9.3.56.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE ACCESS METHOD</span></h2><p>CREATE ACCESS METHOD — define a new access method</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE ACCESS METHOD <em class="replaceable"><code>name</code></em>
+ TYPE <em class="replaceable"><code>access_method_type</code></em>
+ HANDLER <em class="replaceable"><code>handler_function</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.56.5"><h2>Description</h2><p>
+ <code class="command">CREATE ACCESS METHOD</code> creates a new access method.
+ </p><p>
+ The access method name must be unique within the database.
+ </p><p>
+ Only superusers can define new access methods.
+ </p></div><div class="refsect1" id="id-1.9.3.56.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the access method to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>access_method_type</code></em></span></dt><dd><p>
+ This clause specifies the type of access method to define.
+ Only <code class="literal">TABLE</code> and <code class="literal">INDEX</code>
+ are supported at present.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>handler_function</code></em></span></dt><dd><p>
+ <em class="replaceable"><code>handler_function</code></em> is the
+ name (possibly schema-qualified) of a previously registered function
+ that represents the access method. The handler function must be
+ declared to take a single argument of type <code class="type">internal</code>,
+ and its return type depends on the type of access method;
+ for <code class="literal">TABLE</code> access methods, it must
+ be <code class="type">table_am_handler</code> and for <code class="literal">INDEX</code>
+ access methods, it must be <code class="type">index_am_handler</code>.
+ The C-level API that the handler function must implement varies
+ depending on the type of access method. The table access method API
+ is described in <a class="xref" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Chapter 63</a> and the index access method
+ API is described in <a class="xref" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Chapter 64</a>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.56.7"><h2>Examples</h2><p>
+ Create an index access method <code class="literal">heptree</code> with
+ handler function <code class="literal">heptree_handler</code>:
+</p><pre class="programlisting">
+CREATE ACCESS METHOD heptree TYPE INDEX HANDLER heptree_handler;
+</pre></div><div class="refsect1" id="id-1.9.3.56.8"><h2>Compatibility</h2><p>
+ <code class="command">CREATE ACCESS METHOD</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.56.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-drop-access-method.html" title="DROP ACCESS METHOD"><span class="refentrytitle">DROP ACCESS METHOD</span></a>, <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY"><span class="refentrytitle">CREATE OPERATOR FAMILY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-copy.html" title="COPY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createaggregate.html" title="CREATE AGGREGATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">COPY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE AGGREGATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createaggregate.html b/doc/src/sgml/html/sql-createaggregate.html
new file mode 100644
index 0000000..04d1d44
--- /dev/null
+++ b/doc/src/sgml/html/sql-createaggregate.html
@@ -0,0 +1,510 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE AGGREGATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-create-access-method.html" title="CREATE ACCESS METHOD" /><link rel="next" href="sql-createcast.html" title="CREATE CAST" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE AGGREGATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-create-access-method.html" title="CREATE ACCESS METHOD">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createcast.html" title="CREATE CAST">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEAGGREGATE"><div class="titlepage"></div><a id="id-1.9.3.57.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE AGGREGATE</span></h2><p>CREATE AGGREGATE — define a new aggregate function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] AGGREGATE <em class="replaceable"><code>name</code></em> ( [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>arg_data_type</code></em> [ , ... ] ) (
+ SFUNC = <em class="replaceable"><code>sfunc</code></em>,
+ STYPE = <em class="replaceable"><code>state_data_type</code></em>
+ [ , SSPACE = <em class="replaceable"><code>state_data_size</code></em> ]
+ [ , FINALFUNC = <em class="replaceable"><code>ffunc</code></em> ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , COMBINEFUNC = <em class="replaceable"><code>combinefunc</code></em> ]
+ [ , SERIALFUNC = <em class="replaceable"><code>serialfunc</code></em> ]
+ [ , DESERIALFUNC = <em class="replaceable"><code>deserialfunc</code></em> ]
+ [ , INITCOND = <em class="replaceable"><code>initial_condition</code></em> ]
+ [ , MSFUNC = <em class="replaceable"><code>msfunc</code></em> ]
+ [ , MINVFUNC = <em class="replaceable"><code>minvfunc</code></em> ]
+ [ , MSTYPE = <em class="replaceable"><code>mstate_data_type</code></em> ]
+ [ , MSSPACE = <em class="replaceable"><code>mstate_data_size</code></em> ]
+ [ , MFINALFUNC = <em class="replaceable"><code>mffunc</code></em> ]
+ [ , MFINALFUNC_EXTRA ]
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , MINITCOND = <em class="replaceable"><code>minitial_condition</code></em> ]
+ [ , SORTOP = <em class="replaceable"><code>sort_operator</code></em> ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+)
+
+CREATE [ OR REPLACE ] AGGREGATE <em class="replaceable"><code>name</code></em> ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>arg_data_type</code></em> [ , ... ] ]
+ ORDER BY [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>arg_data_type</code></em> [ , ... ] ) (
+ SFUNC = <em class="replaceable"><code>sfunc</code></em>,
+ STYPE = <em class="replaceable"><code>state_data_type</code></em>
+ [ , SSPACE = <em class="replaceable"><code>state_data_size</code></em> ]
+ [ , FINALFUNC = <em class="replaceable"><code>ffunc</code></em> ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , INITCOND = <em class="replaceable"><code>initial_condition</code></em> ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+ [ , HYPOTHETICAL ]
+)
+
+<span class="phrase">or the old syntax</span>
+
+CREATE [ OR REPLACE ] AGGREGATE <em class="replaceable"><code>name</code></em> (
+ BASETYPE = <em class="replaceable"><code>base_type</code></em>,
+ SFUNC = <em class="replaceable"><code>sfunc</code></em>,
+ STYPE = <em class="replaceable"><code>state_data_type</code></em>
+ [ , SSPACE = <em class="replaceable"><code>state_data_size</code></em> ]
+ [ , FINALFUNC = <em class="replaceable"><code>ffunc</code></em> ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , COMBINEFUNC = <em class="replaceable"><code>combinefunc</code></em> ]
+ [ , SERIALFUNC = <em class="replaceable"><code>serialfunc</code></em> ]
+ [ , DESERIALFUNC = <em class="replaceable"><code>deserialfunc</code></em> ]
+ [ , INITCOND = <em class="replaceable"><code>initial_condition</code></em> ]
+ [ , MSFUNC = <em class="replaceable"><code>msfunc</code></em> ]
+ [ , MINVFUNC = <em class="replaceable"><code>minvfunc</code></em> ]
+ [ , MSTYPE = <em class="replaceable"><code>mstate_data_type</code></em> ]
+ [ , MSSPACE = <em class="replaceable"><code>mstate_data_size</code></em> ]
+ [ , MFINALFUNC = <em class="replaceable"><code>mffunc</code></em> ]
+ [ , MFINALFUNC_EXTRA ]
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , MINITCOND = <em class="replaceable"><code>minitial_condition</code></em> ]
+ [ , SORTOP = <em class="replaceable"><code>sort_operator</code></em> ]
+)
+</pre></div><div class="refsect1" id="id-1.9.3.57.5"><h2>Description</h2><p>
+ <code class="command">CREATE AGGREGATE</code> defines a new aggregate function.
+ <code class="command">CREATE OR REPLACE AGGREGATE</code> will either define a new
+ aggregate function or replace an existing definition. Some basic and
+ commonly-used aggregate functions are included with the distribution; they
+ are documented in <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a>. If one defines new
+ types or needs an aggregate function not already provided, then
+ <code class="command">CREATE AGGREGATE</code> can be used to provide the desired
+ features.
+ </p><p>
+ When replacing an existing definition, the argument types, result type,
+ and number of direct arguments may not be changed. Also, the new definition
+ must be of the same kind (ordinary aggregate, ordered-set aggregate, or
+ hypothetical-set aggregate) as the old one.
+ </p><p>
+ If a schema name is given (for example, <code class="literal">CREATE AGGREGATE
+ myschema.myagg ...</code>) then the aggregate function is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </p><p>
+ An aggregate function is identified by its name and input data type(s).
+ Two aggregates in the same schema can have the same name if they operate on
+ different input types. The
+ name and input data type(s) of an aggregate must also be distinct from
+ the name and input data type(s) of every ordinary function in the same
+ schema.
+ This behavior is identical to overloading of ordinary function names
+ (see <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>).
+ </p><p>
+ A simple aggregate function is made from one or two ordinary
+ functions:
+ a state transition function
+ <em class="replaceable"><code>sfunc</code></em>,
+ and an optional final calculation function
+ <em class="replaceable"><code>ffunc</code></em>.
+ These are used as follows:
+</p><pre class="programlisting">
+<em class="replaceable"><code>sfunc</code></em>( internal-state, next-data-values ) ---&gt; next-internal-state
+<em class="replaceable"><code>ffunc</code></em>( internal-state ) ---&gt; aggregate-value
+</pre><p>
+ </p><p>
+ <span class="productname">PostgreSQL</span> creates a temporary variable
+ of data type <em class="replaceable"><code>stype</code></em>
+ to hold the current internal state of the aggregate. At each input row,
+ the aggregate argument value(s) are calculated and
+ the state transition function is invoked with the current state value
+ and the new argument value(s) to calculate a new
+ internal state value. After all the rows have been processed,
+ the final function is invoked once to calculate the aggregate's return
+ value. If there is no final function then the ending state value
+ is returned as-is.
+ </p><p>
+ An aggregate function can provide an initial condition,
+ that is, an initial value for the internal state value.
+ This is specified and stored in the database as a value of type
+ <code class="type">text</code>, but it must be a valid external representation
+ of a constant of the state value data type. If it is not supplied
+ then the state value starts out null.
+ </p><p>
+ If the state transition function is declared <span class="quote">“<span class="quote">strict</span>”</span>,
+ then it cannot be called with null inputs. With such a transition
+ function, aggregate execution behaves as follows. Rows with any null input
+ values are ignored (the function is not called and the previous state value
+ is retained). If the initial state value is null, then at the first row
+ with all-nonnull input values, the first argument value replaces the state
+ value, and the transition function is invoked at each subsequent row with
+ all-nonnull input values.
+ This is handy for implementing aggregates like <code class="function">max</code>.
+ Note that this behavior is only available when
+ <em class="replaceable"><code>state_data_type</code></em>
+ is the same as the first
+ <em class="replaceable"><code>arg_data_type</code></em>.
+ When these types are different, you must supply a nonnull initial
+ condition or use a nonstrict transition function.
+ </p><p>
+ If the state transition function is not strict, then it will be called
+ unconditionally at each input row, and must deal with null inputs
+ and null state values for itself. This allows the aggregate
+ author to have full control over the aggregate's handling of null values.
+ </p><p>
+ If the final function is declared <span class="quote">“<span class="quote">strict</span>”</span>, then it will not
+ be called when the ending state value is null; instead a null result
+ will be returned automatically. (Of course this is just the normal
+ behavior of strict functions.) In any case the final function has
+ the option of returning a null value. For example, the final function for
+ <code class="function">avg</code> returns null when it sees there were zero
+ input rows.
+ </p><p>
+ Sometimes it is useful to declare the final function as taking not just
+ the state value, but extra parameters corresponding to the aggregate's
+ input values. The main reason for doing this is if the final function
+ is polymorphic and the state value's data type would be inadequate to
+ pin down the result type. These extra parameters are always passed as
+ NULL (and so the final function must not be strict when
+ the <code class="literal">FINALFUNC_EXTRA</code> option is used), but nonetheless they
+ are valid parameters. The final function could for example make use
+ of <code class="function">get_fn_expr_argtype</code> to identify the actual argument type
+ in the current call.
+ </p><p>
+ An aggregate can optionally support <em class="firstterm">moving-aggregate mode</em>,
+ as described in <a class="xref" href="xaggr.html#XAGGR-MOVING-AGGREGATES" title="38.12.1. Moving-Aggregate Mode">Section 38.12.1</a>. This requires
+ specifying the <code class="literal">MSFUNC</code>, <code class="literal">MINVFUNC</code>,
+ and <code class="literal">MSTYPE</code> parameters, and optionally
+ the <code class="literal">MSSPACE</code>, <code class="literal">MFINALFUNC</code>,
+ <code class="literal">MFINALFUNC_EXTRA</code>, <code class="literal">MFINALFUNC_MODIFY</code>,
+ and <code class="literal">MINITCOND</code> parameters. Except for <code class="literal">MINVFUNC</code>,
+ these parameters work like the corresponding simple-aggregate parameters
+ without <code class="literal">M</code>; they define a separate implementation of the
+ aggregate that includes an inverse transition function.
+ </p><p>
+ The syntax with <code class="literal">ORDER BY</code> in the parameter list creates
+ a special type of aggregate called an <em class="firstterm">ordered-set
+ aggregate</em>; or if <code class="literal">HYPOTHETICAL</code> is specified, then
+ a <em class="firstterm">hypothetical-set aggregate</em> is created. These
+ aggregates operate over groups of sorted values in order-dependent ways,
+ so that specification of an input sort order is an essential part of a
+ call. Also, they can have <em class="firstterm">direct</em> arguments, which are
+ arguments that are evaluated only once per aggregation rather than once
+ per input row. Hypothetical-set aggregates are a subclass of ordered-set
+ aggregates in which some of the direct arguments are required to match,
+ in number and data types, the aggregated argument columns. This allows
+ the values of those direct arguments to be added to the collection of
+ aggregate-input rows as an additional <span class="quote">“<span class="quote">hypothetical</span>”</span> row.
+ </p><p>
+ An aggregate can optionally support <em class="firstterm">partial aggregation</em>,
+ as described in <a class="xref" href="xaggr.html#XAGGR-PARTIAL-AGGREGATES" title="38.12.4. Partial Aggregation">Section 38.12.4</a>.
+ This requires specifying the <code class="literal">COMBINEFUNC</code> parameter.
+ If the <em class="replaceable"><code>state_data_type</code></em>
+ is <code class="type">internal</code>, it's usually also appropriate to provide the
+ <code class="literal">SERIALFUNC</code> and <code class="literal">DESERIALFUNC</code> parameters so that
+ parallel aggregation is possible. Note that the aggregate must also be
+ marked <code class="literal">PARALLEL SAFE</code> to enable parallel aggregation.
+ </p><p>
+ Aggregates that behave like <code class="function">MIN</code> or <code class="function">MAX</code> can
+ sometimes be optimized by looking into an index instead of scanning every
+ input row. If this aggregate can be so optimized, indicate it by
+ specifying a <em class="firstterm">sort operator</em>. The basic requirement is that
+ the aggregate must yield the first element in the sort ordering induced by
+ the operator; in other words:
+</p><pre class="programlisting">
+SELECT agg(col) FROM tab;
+</pre><p>
+ must be equivalent to:
+</p><pre class="programlisting">
+SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
+</pre><p>
+ Further assumptions are that the aggregate ignores null inputs, and that
+ it delivers a null result if and only if there were no non-null inputs.
+ Ordinarily, a data type's <code class="literal">&lt;</code> operator is the proper sort
+ operator for <code class="function">MIN</code>, and <code class="literal">&gt;</code> is the proper sort
+ operator for <code class="function">MAX</code>. Note that the optimization will never
+ actually take effect unless the specified operator is the <span class="quote">“<span class="quote">less
+ than</span>”</span> or <span class="quote">“<span class="quote">greater than</span>”</span> strategy member of a B-tree
+ index operator class.
+ </p><p>
+ To be able to create an aggregate function, you must
+ have <code class="literal">USAGE</code> privilege on the argument types, the state
+ type(s), and the return type, as well as <code class="literal">EXECUTE</code>
+ privilege on the supporting functions.
+ </p></div><div class="refsect1" id="id-1.9.3.57.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the aggregate function
+ to create.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code> or <code class="literal">VARIADIC</code>.
+ (Aggregate functions do not support <code class="literal">OUT</code> arguments.)
+ If omitted, the default is <code class="literal">IN</code>. Only the last argument
+ can be marked <code class="literal">VARIADIC</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument. This is currently only useful for
+ documentation purposes. If omitted, the argument has no name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>arg_data_type</code></em></span></dt><dd><p>
+ An input data type on which this aggregate function operates.
+ To create a zero-argument aggregate function, write <code class="literal">*</code>
+ in place of the list of argument specifications. (An example of such an
+ aggregate is <code class="function">count(*)</code>.)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>base_type</code></em></span></dt><dd><p>
+ In the old syntax for <code class="command">CREATE AGGREGATE</code>, the input data type
+ is specified by a <code class="literal">basetype</code> parameter rather than being
+ written next to the aggregate name. Note that this syntax allows
+ only one input parameter. To define a zero-argument aggregate function
+ with this syntax, specify the <code class="literal">basetype</code> as
+ <code class="literal">"ANY"</code> (not <code class="literal">*</code>).
+ Ordered-set aggregates cannot be defined with the old syntax.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sfunc</code></em></span></dt><dd><p>
+ The name of the state transition function to be called for each
+ input row. For a normal <em class="replaceable"><code>N</code></em>-argument
+ aggregate function, the <em class="replaceable"><code>sfunc</code></em>
+ must take <em class="replaceable"><code>N</code></em>+1 arguments,
+ the first being of type <em class="replaceable"><code>state_data_type</code></em> and the rest
+ matching the declared input data type(s) of the aggregate.
+ The function must return a value of type <em class="replaceable"><code>state_data_type</code></em>. This function
+ takes the current state value and the current input data value(s),
+ and returns the next state value.
+ </p><p>
+ For ordered-set (including hypothetical-set) aggregates, the state
+ transition function receives only the current state value and the
+ aggregated arguments, not the direct arguments. Otherwise it is the
+ same.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>state_data_type</code></em></span></dt><dd><p>
+ The data type for the aggregate's state value.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>state_data_size</code></em></span></dt><dd><p>
+ The approximate average size (in bytes) of the aggregate's state value.
+ If this parameter is omitted or is zero, a default estimate is used
+ based on the <em class="replaceable"><code>state_data_type</code></em>.
+ The planner uses this value to estimate the memory required for a
+ grouped aggregate query.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>ffunc</code></em></span></dt><dd><p>
+ The name of the final function called to compute the aggregate's
+ result after all input rows have been traversed.
+ For a normal aggregate, this function
+ must take a single argument of type <em class="replaceable"><code>state_data_type</code></em>. The return
+ data type of the aggregate is defined as the return type of this
+ function. If <em class="replaceable"><code>ffunc</code></em>
+ is not specified, then the ending state value is used as the
+ aggregate's result, and the return type is <em class="replaceable"><code>state_data_type</code></em>.
+ </p><p>
+ For ordered-set (including hypothetical-set) aggregates, the
+ final function receives not only the final state value,
+ but also the values of all the direct arguments.
+ </p><p>
+ If <code class="literal">FINALFUNC_EXTRA</code> is specified, then in addition to the
+ final state value and any direct arguments, the final function
+ receives extra NULL values corresponding to the aggregate's regular
+ (aggregated) arguments. This is mainly useful to allow correct
+ resolution of the aggregate result type when a polymorphic aggregate
+ is being defined.
+ </p></dd><dt><span class="term"><code class="literal">FINALFUNC_MODIFY</code> = { <code class="literal">READ_ONLY</code> | <code class="literal">SHAREABLE</code> | <code class="literal">READ_WRITE</code> }</span></dt><dd><p>
+ This option specifies whether the final function is a pure function
+ that does not modify its arguments. <code class="literal">READ_ONLY</code> indicates
+ it does not; the other two values indicate that it may change the
+ transition state value. See <a class="xref" href="sql-createaggregate.html#SQL-CREATEAGGREGATE-NOTES" title="Notes">Notes</a>
+ below for more detail. The
+ default is <code class="literal">READ_ONLY</code>, except for ordered-set aggregates,
+ for which the default is <code class="literal">READ_WRITE</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>combinefunc</code></em></span></dt><dd><p>
+ The <em class="replaceable"><code>combinefunc</code></em> function
+ may optionally be specified to allow the aggregate function to support
+ partial aggregation. If provided,
+ the <em class="replaceable"><code>combinefunc</code></em> must
+ combine two <em class="replaceable"><code>state_data_type</code></em>
+ values, each containing the result of aggregation over some subset of
+ the input values, to produce a
+ new <em class="replaceable"><code>state_data_type</code></em> that
+ represents the result of aggregating over both sets of inputs. This
+ function can be thought of as
+ an <em class="replaceable"><code>sfunc</code></em>, where instead of
+ acting upon an individual input row and adding it to the running
+ aggregate state, it adds another aggregate state to the running state.
+ </p><p>
+ The <em class="replaceable"><code>combinefunc</code></em> must be
+ declared as taking two arguments of
+ the <em class="replaceable"><code>state_data_type</code></em> and
+ returning a value of
+ the <em class="replaceable"><code>state_data_type</code></em>.
+ Optionally this function may be <span class="quote">“<span class="quote">strict</span>”</span>. In this case the
+ function will not be called when either of the input states are null;
+ the other state will be taken as the correct result.
+ </p><p>
+ For aggregate functions
+ whose <em class="replaceable"><code>state_data_type</code></em>
+ is <code class="type">internal</code>,
+ the <em class="replaceable"><code>combinefunc</code></em> must not
+ be strict. In this case
+ the <em class="replaceable"><code>combinefunc</code></em> must
+ ensure that null states are handled correctly and that the state being
+ returned is properly stored in the aggregate memory context.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>serialfunc</code></em></span></dt><dd><p>
+ An aggregate function
+ whose <em class="replaceable"><code>state_data_type</code></em>
+ is <code class="type">internal</code> can participate in parallel aggregation only if it
+ has a <em class="replaceable"><code>serialfunc</code></em> function,
+ which must serialize the aggregate state into a <code class="type">bytea</code> value for
+ transmission to another process. This function must take a single
+ argument of type <code class="type">internal</code> and return type <code class="type">bytea</code>. A
+ corresponding <em class="replaceable"><code>deserialfunc</code></em>
+ is also required.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>deserialfunc</code></em></span></dt><dd><p>
+ Deserialize a previously serialized aggregate state back into
+ <em class="replaceable"><code>state_data_type</code></em>. This
+ function must take two arguments of types <code class="type">bytea</code>
+ and <code class="type">internal</code>, and produce a result of type <code class="type">internal</code>.
+ (Note: the second, <code class="type">internal</code> argument is unused, but is required
+ for type safety reasons.)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>initial_condition</code></em></span></dt><dd><p>
+ The initial setting for the state value. This must be a string
+ constant in the form accepted for the data type <em class="replaceable"><code>state_data_type</code></em>. If not
+ specified, the state value starts out null.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>msfunc</code></em></span></dt><dd><p>
+ The name of the forward state transition function to be called for each
+ input row in moving-aggregate mode. This is exactly like the regular
+ transition function, except that its first argument and result are of
+ type <em class="replaceable"><code>mstate_data_type</code></em>, which might be different
+ from <em class="replaceable"><code>state_data_type</code></em>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>minvfunc</code></em></span></dt><dd><p>
+ The name of the inverse state transition function to be used in
+ moving-aggregate mode. This function has the same argument and
+ result types as <em class="replaceable"><code>msfunc</code></em>, but it is used to remove
+ a value from the current aggregate state, rather than add a value to
+ it. The inverse transition function must have the same strictness
+ attribute as the forward state transition function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>mstate_data_type</code></em></span></dt><dd><p>
+ The data type for the aggregate's state value, when using
+ moving-aggregate mode.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>mstate_data_size</code></em></span></dt><dd><p>
+ The approximate average size (in bytes) of the aggregate's state
+ value, when using moving-aggregate mode. This works the same as
+ <em class="replaceable"><code>state_data_size</code></em>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>mffunc</code></em></span></dt><dd><p>
+ The name of the final function called to compute the aggregate's
+ result after all input rows have been traversed, when using
+ moving-aggregate mode. This works the same as <em class="replaceable"><code>ffunc</code></em>,
+ except that its first argument's type
+ is <em class="replaceable"><code>mstate_data_type</code></em> and extra dummy arguments are
+ specified by writing <code class="literal">MFINALFUNC_EXTRA</code>.
+ The aggregate result type determined by <em class="replaceable"><code>mffunc</code></em>
+ or <em class="replaceable"><code>mstate_data_type</code></em> must match that determined by the
+ aggregate's regular implementation.
+ </p></dd><dt><span class="term"><code class="literal">MFINALFUNC_MODIFY</code> = { <code class="literal">READ_ONLY</code> | <code class="literal">SHAREABLE</code> | <code class="literal">READ_WRITE</code> }</span></dt><dd><p>
+ This option is like <code class="literal">FINALFUNC_MODIFY</code>, but it describes
+ the behavior of the moving-aggregate final function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>minitial_condition</code></em></span></dt><dd><p>
+ The initial setting for the state value, when using moving-aggregate
+ mode. This works the same as <em class="replaceable"><code>initial_condition</code></em>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sort_operator</code></em></span></dt><dd><p>
+ The associated sort operator for a <code class="function">MIN</code>- or
+ <code class="function">MAX</code>-like aggregate.
+ This is just an operator name (possibly schema-qualified).
+ The operator is assumed to have the same input data types as
+ the aggregate (which must be a single-argument normal aggregate).
+ </p></dd><dt><span class="term"><code class="literal">PARALLEL =</code> { <code class="literal">SAFE</code> | <code class="literal">RESTRICTED</code> | <code class="literal">UNSAFE</code> }</span></dt><dd><p>
+ The meanings of <code class="literal">PARALLEL SAFE</code>, <code class="literal">PARALLEL
+ RESTRICTED</code>, and <code class="literal">PARALLEL UNSAFE</code> are the same as
+ in <a class="link" href="sql-createfunction.html" title="CREATE FUNCTION"><code class="command">CREATE FUNCTION</code></a>. An aggregate will not be
+ considered for parallelization if it is marked <code class="literal">PARALLEL
+ UNSAFE</code> (which is the default!) or <code class="literal">PARALLEL RESTRICTED</code>.
+ Note that the parallel-safety markings of the aggregate's support
+ functions are not consulted by the planner, only the marking of the
+ aggregate itself.
+ </p></dd><dt><span class="term"><code class="literal">HYPOTHETICAL</code></span></dt><dd><p>
+ For ordered-set aggregates only, this flag specifies that the aggregate
+ arguments are to be processed according to the requirements for
+ hypothetical-set aggregates: that is, the last few direct arguments must
+ match the data types of the aggregated (<code class="literal">WITHIN GROUP</code>)
+ arguments. The <code class="literal">HYPOTHETICAL</code> flag has no effect on
+ run-time behavior, only on parse-time resolution of the data types and
+ collations of the aggregate's arguments.
+ </p></dd></dl></div><p>
+ The parameters of <code class="command">CREATE AGGREGATE</code> can be
+ written in any order, not just the order illustrated above.
+ </p></div><div class="refsect1" id="SQL-CREATEAGGREGATE-NOTES"><h2>Notes</h2><p>
+ In parameters that specify support function names, you can write
+ a schema name if needed, for example <code class="literal">SFUNC = public.sum</code>.
+ Do not write argument types there, however — the argument types
+ of the support functions are determined from other parameters.
+ </p><p>
+ Ordinarily, PostgreSQL functions are expected to be true functions that
+ do not modify their input values. However, an aggregate transition
+ function, <span class="emphasis"><em>when used in the context of an aggregate</em></span>,
+ is allowed to cheat and modify its transition-state argument in place.
+ This can provide substantial performance benefits compared to making
+ a fresh copy of the transition state each time.
+ </p><p>
+ Likewise, while an aggregate final function is normally expected not to
+ modify its input values, sometimes it is impractical to avoid modifying
+ the transition-state argument. Such behavior must be declared using
+ the <code class="literal">FINALFUNC_MODIFY</code> parameter.
+ The <code class="literal">READ_WRITE</code>
+ value indicates that the final function modifies the transition state in
+ unspecified ways. This value prevents use of the aggregate as a window
+ function, and it also prevents merging of transition states for aggregate
+ calls that share the same input values and transition functions.
+ The <code class="literal">SHAREABLE</code> value indicates that the transition function
+ cannot be applied after the final function, but multiple final-function
+ calls can be performed on the ending transition state value. This value
+ prevents use of the aggregate as a window function, but it allows merging
+ of transition states. (That is, the optimization of interest here is not
+ applying the same final function repeatedly, but applying different final
+ functions to the same ending transition state value. This is allowed as
+ long as none of the final functions are marked <code class="literal">READ_WRITE</code>.)
+ </p><p>
+ If an aggregate supports moving-aggregate mode, it will improve
+ calculation efficiency when the aggregate is used as a window function
+ for a window with moving frame start (that is, a frame start mode other
+ than <code class="literal">UNBOUNDED PRECEDING</code>). Conceptually, the forward
+ transition function adds input values to the aggregate's state when
+ they enter the window frame from the bottom, and the inverse transition
+ function removes them again when they leave the frame at the top. So,
+ when values are removed, they are always removed in the same order they
+ were added. Whenever the inverse transition function is invoked, it will
+ thus receive the earliest added but not yet removed argument value(s).
+ The inverse transition function can assume that at least one row will
+ remain in the current state after it removes the oldest row. (When this
+ would not be the case, the window function mechanism simply starts a
+ fresh aggregation, rather than using the inverse transition function.)
+ </p><p>
+ The forward transition function for moving-aggregate mode is not
+ allowed to return NULL as the new state value. If the inverse
+ transition function returns NULL, this is taken as an indication that
+ the inverse function cannot reverse the state calculation for this
+ particular input, and so the aggregate calculation will be redone from
+ scratch for the current frame starting position. This convention
+ allows moving-aggregate mode to be used in situations where there are
+ some infrequent cases that are impractical to reverse out of the
+ running state value.
+ </p><p>
+ If no moving-aggregate implementation is supplied,
+ the aggregate can still be used with moving frames,
+ but <span class="productname">PostgreSQL</span> will recompute the whole
+ aggregation whenever the start of the frame moves.
+ Note that whether or not the aggregate supports moving-aggregate
+ mode, <span class="productname">PostgreSQL</span> can handle a moving frame
+ end without recalculation; this is done by continuing to add new values
+ to the aggregate's state. This is why use of an aggregate as a window
+ function requires that the final function be read-only: it must
+ not damage the aggregate's state value, so that the aggregation can be
+ continued even after an aggregate result value has been obtained for
+ one set of frame boundaries.
+ </p><p>
+ The syntax for ordered-set aggregates allows <code class="literal">VARIADIC</code>
+ to be specified for both the last direct parameter and the last
+ aggregated (<code class="literal">WITHIN GROUP</code>) parameter. However, the
+ current implementation restricts use of <code class="literal">VARIADIC</code>
+ in two ways. First, ordered-set aggregates can only use
+ <code class="literal">VARIADIC "any"</code>, not other variadic array types.
+ Second, if the last direct parameter is <code class="literal">VARIADIC "any"</code>,
+ then there can be only one aggregated parameter and it must also
+ be <code class="literal">VARIADIC "any"</code>. (In the representation used in the
+ system catalogs, these two parameters are merged into a single
+ <code class="literal">VARIADIC "any"</code> item, since <code class="structname">pg_proc</code> cannot
+ represent functions with more than one <code class="literal">VARIADIC</code> parameter.)
+ If the aggregate is a hypothetical-set aggregate, the direct arguments
+ that match the <code class="literal">VARIADIC "any"</code> parameter are the hypothetical
+ ones; any preceding parameters represent additional direct arguments
+ that are not constrained to match the aggregated arguments.
+ </p><p>
+ Currently, ordered-set aggregates do not need to support
+ moving-aggregate mode, since they cannot be used as window functions.
+ </p><p>
+ Partial (including parallel) aggregation is currently not supported for
+ ordered-set aggregates. Also, it will never be used for aggregate calls
+ that include <code class="literal">DISTINCT</code> or <code class="literal">ORDER BY</code> clauses, since
+ those semantics cannot be supported during partial aggregation.
+ </p></div><div class="refsect1" id="id-1.9.3.57.8"><h2>Examples</h2><p>
+ See <a class="xref" href="xaggr.html" title="38.12. User-Defined Aggregates">Section 38.12</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.57.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE AGGREGATE</code> is a
+ <span class="productname">PostgreSQL</span> language extension. The SQL
+ standard does not provide for user-defined aggregate functions.
+ </p></div><div class="refsect1" id="id-1.9.3.57.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteraggregate.html" title="ALTER AGGREGATE"><span class="refentrytitle">ALTER AGGREGATE</span></a>, <a class="xref" href="sql-dropaggregate.html" title="DROP AGGREGATE"><span class="refentrytitle">DROP AGGREGATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-create-access-method.html" title="CREATE ACCESS METHOD">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createcast.html" title="CREATE CAST">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE ACCESS METHOD </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE CAST</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createcast.html b/doc/src/sgml/html/sql-createcast.html
new file mode 100644
index 0000000..9d2938f
--- /dev/null
+++ b/doc/src/sgml/html/sql-createcast.html
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE CAST</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createaggregate.html" title="CREATE AGGREGATE" /><link rel="next" href="sql-createcollation.html" title="CREATE COLLATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE CAST</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createaggregate.html" title="CREATE AGGREGATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createcollation.html" title="CREATE COLLATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATECAST"><div class="titlepage"></div><a id="id-1.9.3.58.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE CAST</span></h2><p>CREATE CAST — define a new cast</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE CAST (<em class="replaceable"><code>source_type</code></em> AS <em class="replaceable"><code>target_type</code></em>)
+ WITH FUNCTION <em class="replaceable"><code>function_name</code></em> [ (<em class="replaceable"><code>argument_type</code></em> [, ...]) ]
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (<em class="replaceable"><code>source_type</code></em> AS <em class="replaceable"><code>target_type</code></em>)
+ WITHOUT FUNCTION
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (<em class="replaceable"><code>source_type</code></em> AS <em class="replaceable"><code>target_type</code></em>)
+ WITH INOUT
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+</pre></div><div class="refsect1" id="SQL-CREATECAST-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE CAST</code> defines a new cast. A cast
+ specifies how to perform a conversion between
+ two data types. For example,
+</p><pre class="programlisting">
+SELECT CAST(42 AS float8);
+</pre><p>
+ converts the integer constant 42 to type <code class="type">float8</code> by
+ invoking a previously specified function, in this case
+ <code class="literal">float8(int4)</code>. (If no suitable cast has been defined, the
+ conversion fails.)
+ </p><p>
+ Two types can be <em class="firstterm">binary coercible</em>, which
+ means that the conversion can be performed <span class="quote">“<span class="quote">for free</span>”</span>
+ without invoking any function. This requires that corresponding
+ values use the same internal representation. For instance, the
+ types <code class="type">text</code> and <code class="type">varchar</code> are binary
+ coercible both ways. Binary coercibility is not necessarily a
+ symmetric relationship. For example, the cast
+ from <code class="type">xml</code> to <code class="type">text</code> can be performed for
+ free in the present implementation, but the reverse direction
+ requires a function that performs at least a syntax check. (Two
+ types that are binary coercible both ways are also referred to as
+ binary compatible.)
+ </p><p>
+ You can define a cast as an <em class="firstterm">I/O conversion cast</em> by using
+ the <code class="literal">WITH INOUT</code> syntax. An I/O conversion cast is
+ performed by invoking the output function of the source data type, and
+ passing the resulting string to the input function of the target data type.
+ In many common cases, this feature avoids the need to write a separate
+ cast function for conversion. An I/O conversion cast acts the same as
+ a regular function-based cast; only the implementation is different.
+ </p><p>
+ By default, a cast can be invoked only by an explicit cast request,
+ that is an explicit <code class="literal">CAST(<em class="replaceable"><code>x</code></em> AS
+ <em class="replaceable"><code>typename</code></em>)</code> or
+ <em class="replaceable"><code>x</code></em><code class="literal">::</code><em class="replaceable"><code>typename</code></em>
+ construct.
+ </p><p>
+ If the cast is marked <code class="literal">AS ASSIGNMENT</code> then it can be invoked
+ implicitly when assigning a value to a column of the target data type.
+ For example, supposing that <code class="literal">foo.f1</code> is a column of
+ type <code class="type">text</code>, then:
+</p><pre class="programlisting">
+INSERT INTO foo (f1) VALUES (42);
+</pre><p>
+ will be allowed if the cast from type <code class="type">integer</code> to type
+ <code class="type">text</code> is marked <code class="literal">AS ASSIGNMENT</code>, otherwise not.
+ (We generally use the term <em class="firstterm">assignment
+ cast</em> to describe this kind of cast.)
+ </p><p>
+ If the cast is marked <code class="literal">AS IMPLICIT</code> then it can be invoked
+ implicitly in any context, whether assignment or internally in an
+ expression. (We generally use the term <em class="firstterm">implicit
+ cast</em> to describe this kind of cast.)
+ For example, consider this query:
+</p><pre class="programlisting">
+SELECT 2 + 4.0;
+</pre><p>
+ The parser initially marks the constants as being of type <code class="type">integer</code>
+ and <code class="type">numeric</code> respectively. There is no <code class="type">integer</code>
+ <code class="literal">+</code> <code class="type">numeric</code> operator in the system catalogs,
+ but there is a <code class="type">numeric</code> <code class="literal">+</code> <code class="type">numeric</code> operator.
+ The query will therefore succeed if a cast from <code class="type">integer</code> to
+ <code class="type">numeric</code> is available and is marked <code class="literal">AS IMPLICIT</code> —
+ which in fact it is. The parser will apply the implicit cast and resolve
+ the query as if it had been written
+</p><pre class="programlisting">
+SELECT CAST ( 2 AS numeric ) + 4.0;
+</pre><p>
+ </p><p>
+ Now, the catalogs also provide a cast from <code class="type">numeric</code> to
+ <code class="type">integer</code>. If that cast were marked <code class="literal">AS IMPLICIT</code> —
+ which it is not — then the parser would be faced with choosing
+ between the above interpretation and the alternative of casting the
+ <code class="type">numeric</code> constant to <code class="type">integer</code> and applying the
+ <code class="type">integer</code> <code class="literal">+</code> <code class="type">integer</code> operator. Lacking any
+ knowledge of which choice to prefer, it would give up and declare the
+ query ambiguous. The fact that only one of the two casts is
+ implicit is the way in which we teach the parser to prefer resolution
+ of a mixed <code class="type">numeric</code>-and-<code class="type">integer</code> expression as
+ <code class="type">numeric</code>; there is no built-in knowledge about that.
+ </p><p>
+ It is wise to be conservative about marking casts as implicit. An
+ overabundance of implicit casting paths can cause
+ <span class="productname">PostgreSQL</span> to choose surprising
+ interpretations of commands, or to be unable to resolve commands at
+ all because there are multiple possible interpretations. A good
+ rule of thumb is to make a cast implicitly invokable only for
+ information-preserving transformations between types in the same
+ general type category. For example, the cast from <code class="type">int2</code> to
+ <code class="type">int4</code> can reasonably be implicit, but the cast from
+ <code class="type">float8</code> to <code class="type">int4</code> should probably be
+ assignment-only. Cross-type-category casts, such as <code class="type">text</code>
+ to <code class="type">int4</code>, are best made explicit-only.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Sometimes it is necessary for usability or standards-compliance reasons
+ to provide multiple implicit casts among a set of types, resulting in
+ ambiguity that cannot be avoided as above. The parser has a fallback
+ heuristic based on <em class="firstterm">type categories</em> and <em class="firstterm">preferred
+ types</em> that can help to provide desired behavior in such cases. See
+ <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> for
+ more information.
+ </p></div><p>
+ To be able to create a cast, you must own the source or the target data type
+ and have <code class="literal">USAGE</code> privilege on the other type. To create a
+ binary-coercible cast, you must be superuser. (This restriction is made
+ because an erroneous binary-coercible cast conversion can easily crash the
+ server.)
+ </p></div><div class="refsect1" id="id-1.9.3.58.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>source_type</code></em></span></dt><dd><p>
+ The name of the source data type of the cast.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>target_type</code></em></span></dt><dd><p>
+ The name of the target data type of the cast.
+ </p></dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>function_name</code></em>[(<em class="replaceable"><code>argument_type</code></em> [, ...])]</code></span></dt><dd><p>
+ The function used to perform the cast. The function name can
+ be schema-qualified. If it is not, the function will be looked
+ up in the schema search path. The function's result data type must
+ match the target type of the cast. Its arguments are discussed below.
+ If no argument list is specified, the function name must be unique in
+ its schema.
+ </p></dd><dt><span class="term"><code class="literal">WITHOUT FUNCTION</code></span></dt><dd><p>
+ Indicates that the source type is binary-coercible to the target type,
+ so no function is required to perform the cast.
+ </p></dd><dt><span class="term"><code class="literal">WITH INOUT</code></span></dt><dd><p>
+ Indicates that the cast is an I/O conversion cast, performed by
+ invoking the output function of the source data type, and passing the
+ resulting string to the input function of the target data type.
+ </p></dd><dt><span class="term"><code class="literal">AS ASSIGNMENT</code></span></dt><dd><p>
+ Indicates that the cast can be invoked implicitly in assignment
+ contexts.
+ </p></dd><dt><span class="term"><code class="literal">AS IMPLICIT</code></span></dt><dd><p>
+ Indicates that the cast can be invoked implicitly in any context.
+ </p></dd></dl></div><p>
+ Cast implementation functions can have one to three arguments.
+ The first argument type must be identical to or binary-coercible from
+ the cast's source type. The second argument,
+ if present, must be type <code class="type">integer</code>; it receives the type
+ modifier associated with the destination type, or <code class="literal">-1</code>
+ if there is none. The third argument,
+ if present, must be type <code class="type">boolean</code>; it receives <code class="literal">true</code>
+ if the cast is an explicit cast, <code class="literal">false</code> otherwise.
+ (Bizarrely, the SQL standard demands different behaviors for explicit and
+ implicit casts in some cases. This argument is supplied for functions
+ that must implement such casts. It is not recommended that you design
+ your own data types so that this matters.)
+ </p><p>
+ The return type of a cast function must be identical to or
+ binary-coercible to the cast's target type.
+ </p><p>
+ Ordinarily a cast must have different source and target data types.
+ However, it is allowed to declare a cast with identical source and
+ target types if it has a cast implementation function with more than one
+ argument. This is used to represent type-specific length coercion
+ functions in the system catalogs. The named function is used to
+ coerce a value of the type to the type modifier value given by its
+ second argument.
+ </p><p>
+ When a cast has different source and
+ target types and a function that takes more than one argument, it
+ supports converting from one type to another and applying a length
+ coercion in a single step. When no such entry is available, coercion
+ to a type that uses a type modifier involves two cast steps, one to
+ convert between data types and a second to apply the modifier.
+ </p><p>
+ A cast to or from a domain type currently has no effect. Casting
+ to or from a domain uses the casts associated with its underlying type.
+ </p></div><div class="refsect1" id="SQL-CREATECAST-NOTES"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-dropcast.html" title="DROP CAST"><code class="command">DROP CAST</code></a> to remove user-defined casts.
+ </p><p>
+ Remember that if you want to be able to convert types both ways you
+ need to declare casts both ways explicitly.
+ </p><a id="id-1.9.3.58.7.4" class="indexterm"></a><p>
+ It is normally not necessary to create casts between user-defined types
+ and the standard string types (<code class="type">text</code>, <code class="type">varchar</code>, and
+ <code class="type">char(<em class="replaceable"><code>n</code></em>)</code>, as well as user-defined types that
+ are defined to be in the string category). <span class="productname">PostgreSQL</span>
+ provides automatic I/O conversion casts for that. The automatic casts to
+ string types are treated as assignment casts, while the automatic casts
+ from string types are
+ explicit-only. You can override this behavior by declaring your own
+ cast to replace an automatic cast, but usually the only reason to
+ do so is if you want the conversion to be more easily invokable than the
+ standard assignment-only or explicit-only setting. Another possible
+ reason is that you want the conversion to behave differently from the
+ type's I/O function; but that is sufficiently surprising that you
+ should think twice about whether it's a good idea. (A small number of
+ the built-in types do indeed have different behaviors for conversions,
+ mostly because of requirements of the SQL standard.)
+ </p><p>
+ While not required, it is recommended that you continue to follow this old
+ convention of naming cast implementation functions after the target data
+ type. Many users are used to being able to cast data types using a
+ function-style notation, that is
+ <em class="replaceable"><code>typename</code></em>(<em class="replaceable"><code>x</code></em>). This notation is in fact
+ nothing more nor less than a call of the cast implementation function; it
+ is not specially treated as a cast. If your conversion functions are not
+ named to support this convention then you will have surprised users.
+ Since <span class="productname">PostgreSQL</span> allows overloading of the same function
+ name with different argument types, there is no difficulty in having
+ multiple conversion functions from different types that all use the
+ target type's name.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Actually the preceding paragraph is an oversimplification: there are
+ two cases in which a function-call construct will be treated as a cast
+ request without having matched it to an actual function.
+ If a function call <em class="replaceable"><code>name</code></em>(<em class="replaceable"><code>x</code></em>) does not
+ exactly match any existing function, but <em class="replaceable"><code>name</code></em> is the name
+ of a data type and <code class="structname">pg_cast</code> provides a binary-coercible cast
+ to this type from the type of <em class="replaceable"><code>x</code></em>, then the call will be
+ construed as a binary-coercible cast. This exception is made so that
+ binary-coercible casts can be invoked using functional syntax, even
+ though they lack any function. Likewise, if there is no
+ <code class="structname">pg_cast</code> entry but the cast would be to or from a string
+ type, the call will be construed as an I/O conversion cast. This
+ exception allows I/O conversion casts to be invoked using functional
+ syntax.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ There is also an exception to the exception: I/O conversion casts from
+ composite types to string types cannot be invoked using functional
+ syntax, but must be written in explicit cast syntax (either
+ <code class="literal">CAST</code> or <code class="literal">::</code> notation). This exception was added
+ because after the introduction of automatically-provided I/O conversion
+ casts, it was found too easy to accidentally invoke such a cast when
+ a function or column reference was intended.
+ </p></div></div><div class="refsect1" id="SQL-CREATECAST-EXAMPLES"><h2>Examples</h2><p>
+ To create an assignment cast from type <code class="type">bigint</code> to type
+ <code class="type">int4</code> using the function <code class="literal">int4(bigint)</code>:
+</p><pre class="programlisting">
+CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
+</pre><p>
+ (This cast is already predefined in the system.)
+ </p></div><div class="refsect1" id="SQL-CREATECAST-COMPAT"><h2>Compatibility</h2><p>
+ The <code class="command">CREATE CAST</code> command conforms to the
+ <acronym class="acronym">SQL</acronym> standard,
+ except that SQL does not make provisions for binary-coercible
+ types or extra arguments to implementation functions.
+ <code class="literal">AS IMPLICIT</code> is a <span class="productname">PostgreSQL</span>
+ extension, too.
+ </p></div><div class="refsect1" id="SQL-CREATECAST-SEEALSO"><h2>See Also</h2><p>
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>,
+ <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a>,
+ <a class="xref" href="sql-dropcast.html" title="DROP CAST"><span class="refentrytitle">DROP CAST</span></a>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createaggregate.html" title="CREATE AGGREGATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createcollation.html" title="CREATE COLLATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE AGGREGATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE COLLATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createcollation.html b/doc/src/sgml/html/sql-createcollation.html
new file mode 100644
index 0000000..85f3e49
--- /dev/null
+++ b/doc/src/sgml/html/sql-createcollation.html
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE COLLATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createcast.html" title="CREATE CAST" /><link rel="next" href="sql-createconversion.html" title="CREATE CONVERSION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE COLLATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createcast.html" title="CREATE CAST">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createconversion.html" title="CREATE CONVERSION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATECOLLATION"><div class="titlepage"></div><a id="id-1.9.3.59.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE COLLATION</span></h2><p>CREATE COLLATION — define a new collation</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE COLLATION [ IF NOT EXISTS ] <em class="replaceable"><code>name</code></em> (
+ [ LOCALE = <em class="replaceable"><code>locale</code></em>, ]
+ [ LC_COLLATE = <em class="replaceable"><code>lc_collate</code></em>, ]
+ [ LC_CTYPE = <em class="replaceable"><code>lc_ctype</code></em>, ]
+ [ PROVIDER = <em class="replaceable"><code>provider</code></em>, ]
+ [ DETERMINISTIC = <em class="replaceable"><code>boolean</code></em>, ]
+ [ VERSION = <em class="replaceable"><code>version</code></em> ]
+)
+CREATE COLLATION [ IF NOT EXISTS ] <em class="replaceable"><code>name</code></em> FROM <em class="replaceable"><code>existing_collation</code></em>
+</pre></div><div class="refsect1" id="SQL-CREATECOLLATION-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE COLLATION</code> defines a new collation using
+ the specified operating system locale settings,
+ or by copying an existing collation.
+ </p><p>
+ To be able to create a collation, you must
+ have <code class="literal">CREATE</code> privilege on the destination schema.
+ </p></div><div class="refsect1" id="id-1.9.3.59.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a collation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing collation is anything like the one that would have been created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the collation. The collation name can be
+ schema-qualified. If it is not, the collation is defined in the
+ current schema. The collation name must be unique within that
+ schema. (The system catalogs can contain collations with the
+ same name for other encodings, but these are ignored if the
+ database encoding does not match.)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>locale</code></em></span></dt><dd><p>
+ This is a shortcut for setting <code class="symbol">LC_COLLATE</code>
+ and <code class="symbol">LC_CTYPE</code> at once. If you specify this,
+ you cannot specify either of those parameters.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lc_collate</code></em></span></dt><dd><p>
+ Use the specified operating system locale for
+ the <code class="symbol">LC_COLLATE</code> locale category.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lc_ctype</code></em></span></dt><dd><p>
+ Use the specified operating system locale for
+ the <code class="symbol">LC_CTYPE</code> locale category.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>provider</code></em></span></dt><dd><p>
+ Specifies the provider to use for locale services associated with this
+ collation. Possible values
+ are: <code class="literal">icu</code>,<a id="id-1.9.3.59.6.2.6.2.1.2" class="indexterm"></a>
+ <code class="literal">libc</code>.
+ <code class="literal">libc</code> is the default.
+ The available choices depend on the operating system and build options.
+ </p></dd><dt><span class="term"><code class="literal">DETERMINISTIC</code></span></dt><dd><p>
+ Specifies whether the collation should use deterministic comparisons.
+ The default is true. A deterministic comparison considers strings that
+ are not byte-wise equal to be unequal even if they are considered
+ logically equal by the comparison. PostgreSQL breaks ties using a
+ byte-wise comparison. Comparison that is not deterministic can make the
+ collation be, say, case- or accent-insensitive. For that, you need to
+ choose an appropriate <code class="literal">LC_COLLATE</code> setting
+ <span class="emphasis"><em>and</em></span> set the collation to not deterministic here.
+ </p><p>
+ Nondeterministic collations are only supported with the ICU provider.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>version</code></em></span></dt><dd><p>
+ Specifies the version string to store with the collation. Normally,
+ this should be omitted, which will cause the version to be computed
+ from the actual version of the collation as provided by the operating
+ system. This option is intended to be used
+ by <code class="command">pg_upgrade</code> for copying the version from an
+ existing installation.
+ </p><p>
+ See also <a class="xref" href="sql-altercollation.html" title="ALTER COLLATION"><span class="refentrytitle">ALTER COLLATION</span></a> for how to handle
+ collation version mismatches.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>existing_collation</code></em></span></dt><dd><p>
+ The name of an existing collation to copy. The new collation
+ will have the same properties as the existing one, but it
+ will be an independent object.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATECOLLATION-NOTES"><h2>Notes</h2><p>
+ <code class="command">CREATE COLLATION</code> takes a <code class="literal">SHARE ROW
+ EXCLUSIVE</code> lock, which is self-conflicting, on the
+ <code class="structname">pg_collation</code> system catalog, so only one
+ <code class="command">CREATE COLLATION</code> command can run at a time.
+ </p><p>
+ Use <code class="command">DROP COLLATION</code> to remove user-defined collations.
+ </p><p>
+ See <a class="xref" href="collation.html#COLLATION-CREATE" title="24.2.2.3. Creating New Collation Objects">Section 24.2.2.3</a> for more information on how to create collations.
+ </p><p>
+ When using the <code class="literal">libc</code> collation provider, the locale must
+ be applicable to the current database encoding.
+ See <a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a> for the precise rules.
+ </p></div><div class="refsect1" id="SQL-CREATECOLLATION-EXAMPLES"><h2>Examples</h2><p>
+ To create a collation from the operating system locale
+ <code class="literal">fr_FR.utf8</code>
+ (assuming the current database encoding is <code class="literal">UTF8</code>):
+</p><pre class="programlisting">
+CREATE COLLATION french (locale = 'fr_FR.utf8');
+</pre><p>
+ </p><p>
+ To create a collation using the ICU provider using German phone book sort order:
+</p><pre class="programlisting">
+CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk');
+</pre><p>
+ </p><p>
+ To create a collation from an existing collation:
+</p><pre class="programlisting">
+CREATE COLLATION german FROM "de_DE";
+</pre><p>
+ This can be convenient to be able to use operating-system-independent
+ collation names in applications.
+ </p></div><div class="refsect1" id="SQL-CREATECOLLATION-COMPAT"><h2>Compatibility</h2><p>
+ There is a <code class="command">CREATE COLLATION</code> statement in the SQL
+ standard, but it is limited to copying an existing collation. The
+ syntax to create a new collation is
+ a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="SQL-CREATECOLLATION-SEEALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altercollation.html" title="ALTER COLLATION"><span class="refentrytitle">ALTER COLLATION</span></a>, <a class="xref" href="sql-dropcollation.html" title="DROP COLLATION"><span class="refentrytitle">DROP COLLATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createcast.html" title="CREATE CAST">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createconversion.html" title="CREATE CONVERSION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE CAST </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE CONVERSION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createconversion.html b/doc/src/sgml/html/sql-createconversion.html
new file mode 100644
index 0000000..77271a6
--- /dev/null
+++ b/doc/src/sgml/html/sql-createconversion.html
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE CONVERSION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createcollation.html" title="CREATE COLLATION" /><link rel="next" href="sql-createdatabase.html" title="CREATE DATABASE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE CONVERSION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createcollation.html" title="CREATE COLLATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createdatabase.html" title="CREATE DATABASE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATECONVERSION"><div class="titlepage"></div><a id="id-1.9.3.60.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE CONVERSION</span></h2><p>CREATE CONVERSION — define a new encoding conversion</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ DEFAULT ] CONVERSION <em class="replaceable"><code>name</code></em>
+ FOR <em class="replaceable"><code>source_encoding</code></em> TO <em class="replaceable"><code>dest_encoding</code></em> FROM <em class="replaceable"><code>function_name</code></em>
+</pre></div><div class="refsect1" id="SQL-CREATECONVERSION-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE CONVERSION</code> defines a new conversion between
+ two character set encodings.
+ </p><p>
+ Conversions that are marked <code class="literal">DEFAULT</code> can be used for
+ automatic encoding conversion between client and server. To support that
+ usage, two conversions, from encoding A to B <span class="emphasis"><em>and</em></span>
+ from encoding B to A, must be defined.
+ </p><p>
+ To be able to create a conversion, you must have <code class="literal">EXECUTE</code> privilege
+ on the function and <code class="literal">CREATE</code> privilege on the destination schema.
+ </p></div><div class="refsect1" id="id-1.9.3.60.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ The <code class="literal">DEFAULT</code> clause indicates that this conversion
+ is the default for this particular source to destination
+ encoding. There should be only one default encoding in a schema
+ for the encoding pair.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the conversion. The conversion name can be
+ schema-qualified. If it is not, the conversion is defined in the
+ current schema. The conversion name must be unique within a
+ schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_encoding</code></em></span></dt><dd><p>
+ The source encoding name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>dest_encoding</code></em></span></dt><dd><p>
+ The destination encoding name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ The function used to perform the conversion. The function name can
+ be schema-qualified. If it is not, the function will be looked
+ up in the path.
+ </p><p>
+ The function must have the following signature:
+
+</p><pre class="programlisting">
+conv_proc(
+ integer, -- source encoding ID
+ integer, -- destination encoding ID
+ cstring, -- source string (null terminated C string)
+ internal, -- destination (fill with a null terminated C string)
+ integer, -- source string length
+ boolean -- if true, don't throw an error if conversion fails
+) RETURNS integer;
+</pre><p>
+ The return value is the number of source bytes that were successfully
+ converted. If the last argument is false, the function must throw an
+ error on invalid input, and the return value is always equal to the
+ source string length.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATECONVERSION-NOTES"><h2>Notes</h2><p>
+ Neither the source nor the destination encoding can
+ be <code class="literal">SQL_ASCII</code>, as the server's behavior for cases
+ involving the <code class="literal">SQL_ASCII</code> <span class="quote">“<span class="quote">encoding</span>”</span> is
+ hard-wired.
+ </p><p>
+ Use <code class="command">DROP CONVERSION</code> to remove user-defined conversions.
+ </p><p>
+ The privileges required to create a conversion might be changed in a future
+ release.
+ </p></div><div class="refsect1" id="SQL-CREATECONVERSION-EXAMPLES"><h2>Examples</h2><p>
+ To create a conversion from encoding <code class="literal">UTF8</code> to
+ <code class="literal">LATIN1</code> using <code class="function">myfunc</code>:
+</p><pre class="programlisting">
+CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;
+</pre></div><div class="refsect1" id="SQL-CREATECONVERSION-COMPAT"><h2>Compatibility</h2><p>
+ <code class="command">CREATE CONVERSION</code>
+ is a <span class="productname">PostgreSQL</span> extension.
+ There is no <code class="command">CREATE CONVERSION</code>
+ statement in the SQL standard, but a <code class="command">CREATE TRANSLATION</code>
+ statement that is very similar in purpose and syntax.
+ </p></div><div class="refsect1" id="SQL-CREATECONVERSION-SEEALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterconversion.html" title="ALTER CONVERSION"><span class="refentrytitle">ALTER CONVERSION</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-dropconversion.html" title="DROP CONVERSION"><span class="refentrytitle">DROP CONVERSION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createcollation.html" title="CREATE COLLATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createdatabase.html" title="CREATE DATABASE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE COLLATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE DATABASE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createdatabase.html b/doc/src/sgml/html/sql-createdatabase.html
new file mode 100644
index 0000000..e22840b
--- /dev/null
+++ b/doc/src/sgml/html/sql-createdatabase.html
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE DATABASE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createconversion.html" title="CREATE CONVERSION" /><link rel="next" href="sql-createdomain.html" title="CREATE DOMAIN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE DATABASE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createconversion.html" title="CREATE CONVERSION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createdomain.html" title="CREATE DOMAIN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEDATABASE"><div class="titlepage"></div><a id="id-1.9.3.61.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE DATABASE</span></h2><p>CREATE DATABASE — create a new database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE DATABASE <em class="replaceable"><code>name</code></em>
+ [ WITH ] [ OWNER [=] <em class="replaceable"><code>user_name</code></em> ]
+ [ TEMPLATE [=] <em class="replaceable"><code>template</code></em> ]
+ [ ENCODING [=] <em class="replaceable"><code>encoding</code></em> ]
+ [ STRATEGY [=] <em class="replaceable"><code>strategy</code></em> ] ]
+ [ LOCALE [=] <em class="replaceable"><code>locale</code></em> ]
+ [ LC_COLLATE [=] <em class="replaceable"><code>lc_collate</code></em> ]
+ [ LC_CTYPE [=] <em class="replaceable"><code>lc_ctype</code></em> ]
+ [ ICU_LOCALE [=] <em class="replaceable"><code>icu_locale</code></em> ]
+ [ LOCALE_PROVIDER [=] <em class="replaceable"><code>locale_provider</code></em> ]
+ [ COLLATION_VERSION = <em class="replaceable"><code>collation_version</code></em> ]
+ [ TABLESPACE [=] <em class="replaceable"><code>tablespace_name</code></em> ]
+ [ ALLOW_CONNECTIONS [=] <em class="replaceable"><code>allowconn</code></em> ]
+ [ CONNECTION LIMIT [=] <em class="replaceable"><code>connlimit</code></em> ]
+ [ IS_TEMPLATE [=] <em class="replaceable"><code>istemplate</code></em> ]
+ [ OID [=] <em class="replaceable"><code>oid</code></em> ]
+</pre></div><div class="refsect1" id="id-1.9.3.61.5"><h2>Description</h2><p>
+ <code class="command">CREATE DATABASE</code> creates a new
+ <span class="productname">PostgreSQL</span> database.
+ </p><p>
+ To create a database, you must be a superuser or have the special
+ <code class="literal">CREATEDB</code> privilege.
+ See <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>.
+ </p><p>
+ By default, the new database will be created by cloning the standard
+ system database <code class="literal">template1</code>. A different template can be
+ specified by writing <code class="literal">TEMPLATE
+ <em class="replaceable"><code>name</code></em></code>. In particular,
+ by writing <code class="literal">TEMPLATE template0</code>, you can create a pristine
+ database (one where no user-defined objects exist and where the system
+ objects have not been altered)
+ containing only the standard objects predefined by your
+ version of <span class="productname">PostgreSQL</span>. This is useful
+ if you wish to avoid copying
+ any installation-local objects that might have been added to
+ <code class="literal">template1</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.61.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a database to create.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ The role name of the user who will own the new database,
+ or <code class="literal">DEFAULT</code> to use the default (namely, the
+ user executing the command). To create a database owned by another
+ role, you must be a direct or indirect member of that role,
+ or be a superuser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>template</code></em></span></dt><dd><p>
+ The name of the template from which to create the new database,
+ or <code class="literal">DEFAULT</code> to use the default template
+ (<code class="literal">template1</code>).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>encoding</code></em></span></dt><dd><p>
+ Character set encoding to use in the new database. Specify
+ a string constant (e.g., <code class="literal">'SQL_ASCII'</code>),
+ or an integer encoding number, or <code class="literal">DEFAULT</code>
+ to use the default encoding (namely, the encoding of the
+ template database). The character sets supported by the
+ <span class="productname">PostgreSQL</span> server are described in
+ <a class="xref" href="multibyte.html#MULTIBYTE-CHARSET-SUPPORTED" title="24.3.1. Supported Character Sets">Section 24.3.1</a>. See below for
+ additional restrictions.
+ </p></dd><dt id="CREATE-DATABASE-STRATEGY"><span class="term"><em class="replaceable"><code>strategy</code></em></span></dt><dd><p>
+ Strategy to be used in creating the new database. If
+ the <code class="literal">WAL_LOG</code> strategy is used, the database will be
+ copied block by block and each block will be separately written
+ to the write-ahead log. This is the most efficient strategy in
+ cases where the template database is small, and therefore it is the
+ default. The older <code class="literal">FILE_COPY</code> strategy is also
+ available. This strategy writes a small record to the write-ahead log
+ for each tablespace used by the target database. Each such record
+ represents copying an entire directory to a new location at the
+ filesystem level. While this does reduce the write-ahead
+ log volume substantially, especially if the template database is large,
+ it also forces the system to perform a checkpoint both before and
+ after the creation of the new database. In some situations, this may
+ have a noticeable negative impact on overall system performance.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>locale</code></em></span></dt><dd><p>
+ This is a shortcut for setting <code class="symbol">LC_COLLATE</code>
+ and <code class="symbol">LC_CTYPE</code> at once.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ The other locale settings <a class="xref" href="runtime-config-client.html#GUC-LC-MESSAGES">lc_messages</a>, <a class="xref" href="runtime-config-client.html#GUC-LC-MONETARY">lc_monetary</a>, <a class="xref" href="runtime-config-client.html#GUC-LC-NUMERIC">lc_numeric</a>, and
+ <a class="xref" href="runtime-config-client.html#GUC-LC-TIME">lc_time</a> are not fixed per database and are not
+ set by this command. If you want to make them the default for a
+ specific database, you can use <code class="literal">ALTER DATABASE
+ ... SET</code>.
+ </p></div></dd><dt><span class="term"><em class="replaceable"><code>lc_collate</code></em></span></dt><dd><p>
+ Collation order (<code class="literal">LC_COLLATE</code>) to use in the new database.
+ This affects the sort order applied to strings, e.g., in queries with
+ ORDER BY, as well as the order used in indexes on text columns.
+ The default is to use the collation order of the template database.
+ See below for additional restrictions.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lc_ctype</code></em></span></dt><dd><p>
+ Character classification (<code class="literal">LC_CTYPE</code>) to use in the new
+ database. This affects the categorization of characters, e.g., lower,
+ upper and digit. The default is to use the character classification of
+ the template database. See below for additional restrictions.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>icu_locale</code></em></span></dt><dd><p>
+ Specifies the ICU locale ID if the ICU locale provider is used.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>locale_provider</code></em></span></dt><dd><p>
+ Specifies the provider to use for the default collation in this
+ database. Possible values are:
+ <code class="literal">icu</code>,<a id="id-1.9.3.61.6.2.10.2.1.2" class="indexterm"></a>
+ <code class="literal">libc</code>. <code class="literal">libc</code> is the default. The
+ available choices depend on the operating system and build options.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>collation_version</code></em></span></dt><dd><p>
+ Specifies the collation version string to store with the database.
+ Normally, this should be omitted, which will cause the version to be
+ computed from the actual version of the database collation as provided
+ by the operating system. This option is intended to be used by
+ <code class="command">pg_upgrade</code> for copying the version from an existing
+ installation.
+ </p><p>
+ See also <a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a> for how to handle
+ database collation version mismatches.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>tablespace_name</code></em></span></dt><dd><p>
+ The name of the tablespace that will be associated with the
+ new database, or <code class="literal">DEFAULT</code> to use the
+ template database's tablespace. This
+ tablespace will be the default tablespace used for objects
+ created in this database. See
+ <a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a>
+ for more information.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>allowconn</code></em></span></dt><dd><p>
+ If false then no one can connect to this database. The default is
+ true, allowing connections (except as restricted by other mechanisms,
+ such as <code class="literal">GRANT</code>/<code class="literal">REVOKE CONNECT</code>).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>connlimit</code></em></span></dt><dd><p>
+ How many concurrent connections can be made
+ to this database. -1 (the default) means no limit.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>istemplate</code></em></span></dt><dd><p>
+ If true, then this database can be cloned by any user with <code class="literal">CREATEDB</code>
+ privileges; if false (the default), then only superusers or the owner
+ of the database can clone it.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>oid</code></em></span></dt><dd><p>
+ The object identifier to be used for the new database. If this
+ parameter is not specified, <span class="productname">PostgreSQL</span>
+ will choose a suitable OID automatically. This parameter is primarily
+ intended for internal use by <span class="application">pg_upgrade</span>,
+ and only <span class="application">pg_upgrade</span> can specify a value
+ less than 16384.
+ </p></dd></dl></div><p>
+ Optional parameters can be written in any order, not only the order
+ illustrated above.
+ </p></div><div class="refsect1" id="id-1.9.3.61.7"><h2>Notes</h2><p>
+ <code class="command">CREATE DATABASE</code> cannot be executed inside a transaction
+ block.
+ </p><p>
+ Errors along the line of <span class="quote">“<span class="quote">could not initialize database directory</span>”</span>
+ are most likely related to insufficient permissions on the data
+ directory, a full disk, or other file system problems.
+ </p><p>
+ Use <a class="link" href="sql-dropdatabase.html" title="DROP DATABASE"><code class="command">DROP DATABASE</code></a> to remove a database.
+ </p><p>
+ The program <a class="xref" href="app-createdb.html" title="createdb"><span class="refentrytitle"><span class="application">createdb</span></span></a> is a
+ wrapper program around this command, provided for convenience.
+ </p><p>
+ Database-level configuration parameters (set via <a class="link" href="sql-alterdatabase.html" title="ALTER DATABASE"><code class="command">ALTER DATABASE</code></a>) and database-level permissions (set via
+ <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a>) are not copied from the template database.
+ </p><p>
+ Although it is possible to copy a database other than <code class="literal">template1</code>
+ by specifying its name as the template, this is not (yet) intended as
+ a general-purpose <span class="quote">“<span class="quote"><code class="command">COPY DATABASE</code></span>”</span> facility.
+ The principal limitation is that no other sessions can be connected to
+ the template database while it is being copied. <code class="command">CREATE
+ DATABASE</code> will fail if any other connection exists when it starts;
+ otherwise, new connections to the template database are locked out
+ until <code class="command">CREATE DATABASE</code> completes.
+ See <a class="xref" href="manage-ag-templatedbs.html" title="23.3. Template Databases">Section 23.3</a> for more information.
+ </p><p>
+ The character set encoding specified for the new database must be
+ compatible with the chosen locale settings (<code class="literal">LC_COLLATE</code> and
+ <code class="literal">LC_CTYPE</code>). If the locale is <code class="literal">C</code> (or equivalently
+ <code class="literal">POSIX</code>), then all encodings are allowed, but for other
+ locale settings there is only one encoding that will work properly.
+ (On Windows, however, UTF-8 encoding can be used with any locale.)
+ <code class="command">CREATE DATABASE</code> will allow superusers to specify
+ <code class="literal">SQL_ASCII</code> encoding regardless of the locale settings,
+ but this choice is deprecated and may result in misbehavior of
+ character-string functions if data that is not encoding-compatible
+ with the locale is stored in the database.
+ </p><p>
+ The encoding and locale settings must match those of the template database,
+ except when <code class="literal">template0</code> is used as template. This is because
+ other databases might contain data that does not match the specified
+ encoding, or might contain indexes whose sort ordering is affected by
+ <code class="literal">LC_COLLATE</code> and <code class="literal">LC_CTYPE</code>. Copying such data would
+ result in a database that is corrupt according to the new settings.
+ <code class="literal">template0</code>, however, is known to not contain any data or
+ indexes that would be affected.
+ </p><p>
+ There is currently no option to use a database locale with nondeterministic
+ comparisons (see <a class="link" href="sql-createcollation.html" title="CREATE COLLATION"><code class="command">CREATE
+ COLLATION</code></a> for an explanation). If this is needed, then
+ per-column collations would need to be used.
+ </p><p>
+ The <code class="literal">CONNECTION LIMIT</code> option is only enforced approximately;
+ if two new sessions start at about the same time when just one
+ connection <span class="quote">“<span class="quote">slot</span>”</span> remains for the database, it is possible that
+ both will fail. Also, the limit is not enforced against superusers or
+ background worker processes.
+ </p></div><div class="refsect1" id="id-1.9.3.61.8"><h2>Examples</h2><p>
+ To create a new database:
+
+</p><pre class="programlisting">
+CREATE DATABASE lusiadas;
+</pre><p>
+ </p><p>
+ To create a database <code class="literal">sales</code> owned by user <code class="literal">salesapp</code>
+ with a default tablespace of <code class="literal">salesspace</code>:
+
+</p><pre class="programlisting">
+CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;
+</pre><p>
+ </p><p>
+ To create a database <code class="literal">music</code> with a different locale:
+</p><pre class="programlisting">
+CREATE DATABASE music
+ LOCALE 'sv_SE.utf8'
+ TEMPLATE template0;
+</pre><p>
+ In this example, the <code class="literal">TEMPLATE template0</code> clause is required if
+ the specified locale is different from the one in <code class="literal">template1</code>.
+ (If it is not, then specifying the locale explicitly is redundant.)
+ </p><p>
+ To create a database <code class="literal">music2</code> with a different locale and a
+ different character set encoding:
+</p><pre class="programlisting">
+CREATE DATABASE music2
+ LOCALE 'sv_SE.iso885915'
+ ENCODING LATIN9
+ TEMPLATE template0;
+</pre><p>
+ The specified locale and encoding settings must match, or an error will be
+ reported.
+ </p><p>
+ Note that locale names are specific to the operating system, so that the
+ above commands might not work in the same way everywhere.
+ </p></div><div class="refsect1" id="id-1.9.3.61.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">CREATE DATABASE</code> statement in the SQL
+ standard. Databases are equivalent to catalogs, whose creation is
+ implementation-defined.
+ </p></div><div class="refsect1" id="id-1.9.3.61.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a>, <a class="xref" href="sql-dropdatabase.html" title="DROP DATABASE"><span class="refentrytitle">DROP DATABASE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createconversion.html" title="CREATE CONVERSION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createdomain.html" title="CREATE DOMAIN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE CONVERSION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE DOMAIN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createdomain.html b/doc/src/sgml/html/sql-createdomain.html
new file mode 100644
index 0000000..591922c
--- /dev/null
+++ b/doc/src/sgml/html/sql-createdomain.html
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE DOMAIN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createdatabase.html" title="CREATE DATABASE" /><link rel="next" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE DOMAIN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createdatabase.html" title="CREATE DATABASE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEDOMAIN"><div class="titlepage"></div><a id="id-1.9.3.62.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE DOMAIN</span></h2><p>CREATE DOMAIN — define a new domain</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE DOMAIN <em class="replaceable"><code>name</code></em> [ AS ] <em class="replaceable"><code>data_type</code></em>
+ [ COLLATE <em class="replaceable"><code>collation</code></em> ]
+ [ DEFAULT <em class="replaceable"><code>expression</code></em> ]
+ [ <em class="replaceable"><code>constraint</code></em> [ ... ] ]
+
+<span class="phrase">where <em class="replaceable"><code>constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+{ NOT NULL | NULL | CHECK (<em class="replaceable"><code>expression</code></em>) }
+</pre></div><div class="refsect1" id="id-1.9.3.62.5"><h2>Description</h2><p>
+ <code class="command">CREATE DOMAIN</code> creates a new domain. A domain is
+ essentially a data type with optional constraints (restrictions on
+ the allowed set of values).
+ The user who defines a domain becomes its owner.
+ </p><p>
+ If a schema name is given (for example, <code class="literal">CREATE DOMAIN
+ myschema.mydomain ...</code>) then the domain is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The domain name must be unique among the types and domains existing
+ in its schema.
+ </p><p>
+ Domains are useful for abstracting common constraints on fields into
+ a single location for maintenance. For example, several tables might
+ contain email address columns, all requiring the same CHECK constraint
+ to verify the address syntax.
+ Define a domain rather than setting up each table's constraint
+ individually.
+ </p><p>
+ To be able to create a domain, you must have <code class="literal">USAGE</code>
+ privilege on the underlying type.
+ </p></div><div class="refsect1" id="id-1.9.3.62.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a domain to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The underlying data type of the domain. This can include array
+ specifiers.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>collation</code></em></span></dt><dd><p>
+ An optional collation for the domain. If no collation is
+ specified, the domain has the same collation behavior as its
+ underlying data type.
+ The underlying type must be collatable if <code class="literal">COLLATE</code>
+ is specified.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT <em class="replaceable"><code>expression</code></em></code></span></dt><dd><p>
+ The <code class="literal">DEFAULT</code> clause specifies a default value for
+ columns of the domain data type. The value is any
+ variable-free expression (but subqueries are not allowed).
+ The data type of the default expression must match the data
+ type of the domain. If no default value is specified, then
+ the default value is the null value.
+ </p><p>
+ The default expression will be used in any insert operation
+ that does not specify a value for the column. If a default
+ value is defined for a particular column, it overrides any
+ default associated with the domain. In turn, the domain
+ default overrides any default value associated with the
+ underlying data type.
+ </p></dd><dt><span class="term"><code class="literal">CONSTRAINT <em class="replaceable"><code>constraint_name</code></em></code></span></dt><dd><p>
+ An optional name for a constraint. If not specified,
+ the system generates a name.
+ </p></dd><dt><span class="term"><code class="literal">NOT NULL</code></span></dt><dd><p>
+ Values of this domain are prevented from being null
+ (but see notes below).
+ </p></dd><dt><span class="term"><code class="literal">NULL</code></span></dt><dd><p>
+ Values of this domain are allowed to be null. This is the default.
+ </p><p>
+ This clause is only intended for compatibility with
+ nonstandard SQL databases. Its use is discouraged in new
+ applications.
+ </p></dd><dt><span class="term"><code class="literal">CHECK (<em class="replaceable"><code>expression</code></em>)</code></span></dt><dd><p><code class="literal">CHECK</code> clauses specify integrity constraints or tests
+ which values of the domain must satisfy.
+ Each constraint must be an expression
+ producing a Boolean result. It should use the key word <code class="literal">VALUE</code>
+ to refer to the value being tested. Expressions evaluating
+ to TRUE or UNKNOWN succeed. If the expression produces a FALSE result,
+ an error is reported and the value is not allowed to be converted
+ to the domain type.
+ </p><p>
+ Currently, <code class="literal">CHECK</code> expressions cannot contain
+ subqueries nor refer to variables other than <code class="literal">VALUE</code>.
+ </p><p>
+ When a domain has multiple <code class="literal">CHECK</code> constraints,
+ they will be tested in alphabetical order by name.
+ (<span class="productname">PostgreSQL</span> versions before 9.5 did not honor any
+ particular firing order for <code class="literal">CHECK</code> constraints.)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.62.7"><h2>Notes</h2><p>
+ Domain constraints, particularly <code class="literal">NOT NULL</code>, are checked when
+ converting a value to the domain type. It is possible for a column that
+ is nominally of the domain type to read as null despite there being such
+ a constraint. For example, this can happen in an outer-join query, if
+ the domain column is on the nullable side of the outer join. A more
+ subtle example is
+</p><pre class="programlisting">
+INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));
+</pre><p>
+ The empty scalar sub-SELECT will produce a null value that is considered
+ to be of the domain type, so no further constraint checking is applied
+ to it, and the insertion will succeed.
+ </p><p>
+ It is very difficult to avoid such problems, because of SQL's general
+ assumption that a null value is a valid value of every data type. Best practice
+ therefore is to design a domain's constraints so that a null value is allowed,
+ and then to apply column <code class="literal">NOT NULL</code> constraints to columns of
+ the domain type as needed, rather than directly to the domain type.
+ </p><p>
+ <span class="productname">PostgreSQL</span> assumes that
+ <code class="literal">CHECK</code> constraints' conditions are immutable, that is,
+ they will always give the same result for the same input value. This
+ assumption is what justifies examining <code class="literal">CHECK</code>
+ constraints only when a value is first converted to be of a domain type,
+ and not at other times. (This is essentially the same as the treatment
+ of table <code class="literal">CHECK</code> constraints, as described in
+ <a class="xref" href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS" title="5.4.1. Check Constraints">Section 5.4.1</a>.)
+ </p><p>
+ An example of a common way to break this assumption is to reference a
+ user-defined function in a <code class="literal">CHECK</code> expression, and then
+ change the behavior of that
+ function. <span class="productname">PostgreSQL</span> does not disallow that,
+ but it will not notice if there are stored values of the domain type that
+ now violate the <code class="literal">CHECK</code> constraint. That would cause a
+ subsequent database dump and restore to fail. The recommended way to
+ handle such a change is to drop the constraint (using <code class="command">ALTER
+ DOMAIN</code>), adjust the function definition, and re-add the
+ constraint, thereby rechecking it against stored data.
+ </p></div><div class="refsect1" id="id-1.9.3.62.8"><h2>Examples</h2><p>
+ This example creates the <code class="type">us_postal_code</code> data type and
+ then uses the type in a table definition. A regular expression test
+ is used to verify that the value looks like a valid US postal code:
+
+</p><pre class="programlisting">
+CREATE DOMAIN us_postal_code AS TEXT
+CHECK(
+ VALUE ~ '^\d{5}$'
+OR VALUE ~ '^\d{5}-\d{4}$'
+);
+
+CREATE TABLE us_snail_addy (
+ address_id SERIAL PRIMARY KEY,
+ street1 TEXT NOT NULL,
+ street2 TEXT,
+ street3 TEXT,
+ city TEXT NOT NULL,
+ postal us_postal_code NOT NULL
+);
+</pre></div><div class="refsect1" id="SQL-CREATEDOMAIN-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The command <code class="command">CREATE DOMAIN</code> conforms to the SQL
+ standard.
+ </p></div><div class="refsect1" id="SQL-CREATEDOMAIN-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterdomain.html" title="ALTER DOMAIN"><span class="refentrytitle">ALTER DOMAIN</span></a>, <a class="xref" href="sql-dropdomain.html" title="DROP DOMAIN"><span class="refentrytitle">DROP DOMAIN</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createdatabase.html" title="CREATE DATABASE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE DATABASE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE EVENT TRIGGER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createeventtrigger.html b/doc/src/sgml/html/sql-createeventtrigger.html
new file mode 100644
index 0000000..28a1a81
--- /dev/null
+++ b/doc/src/sgml/html/sql-createeventtrigger.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE EVENT TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createdomain.html" title="CREATE DOMAIN" /><link rel="next" href="sql-createextension.html" title="CREATE EXTENSION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE EVENT TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createdomain.html" title="CREATE DOMAIN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createextension.html" title="CREATE EXTENSION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEEVENTTRIGGER"><div class="titlepage"></div><a id="id-1.9.3.63.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE EVENT TRIGGER</span></h2><p>CREATE EVENT TRIGGER — define a new event trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE EVENT TRIGGER <em class="replaceable"><code>name</code></em>
+ ON <em class="replaceable"><code>event</code></em>
+ [ WHEN <em class="replaceable"><code>filter_variable</code></em> IN (<em class="replaceable"><code>filter_value</code></em> [, ... ]) [ AND ... ] ]
+ EXECUTE { FUNCTION | PROCEDURE } <em class="replaceable"><code>function_name</code></em>()
+</pre></div><div class="refsect1" id="id-1.9.3.63.5"><h2>Description</h2><p>
+ <code class="command">CREATE EVENT TRIGGER</code> creates a new event trigger.
+ Whenever the designated event occurs and the <code class="literal">WHEN</code> condition
+ associated with the trigger, if any, is satisfied, the trigger function
+ will be executed. For a general introduction to event triggers, see
+ <a class="xref" href="event-triggers.html" title="Chapter 40. Event Triggers">Chapter 40</a>. The user who creates an event trigger
+ becomes its owner.
+ </p></div><div class="refsect1" id="id-1.9.3.63.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name to give the new trigger. This name must be unique within
+ the database.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>event</code></em></span></dt><dd><p>
+ The name of the event that triggers a call to the given function.
+ See <a class="xref" href="event-trigger-definition.html" title="40.1. Overview of Event Trigger Behavior">Section 40.1</a> for more information
+ on event names.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>filter_variable</code></em></span></dt><dd><p>
+ The name of a variable used to filter events. This makes it possible
+ to restrict the firing of the trigger to a subset of the cases in which
+ it is supported. Currently the only supported
+ <em class="replaceable"><code>filter_variable</code></em>
+ is <code class="literal">TAG</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>filter_value</code></em></span></dt><dd><p>
+ A list of values for the
+ associated <em class="replaceable"><code>filter_variable</code></em>
+ for which the trigger should fire. For <code class="literal">TAG</code>, this means a
+ list of command tags (e.g., <code class="literal">'DROP FUNCTION'</code>).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ A user-supplied function that is declared as taking no argument and
+ returning type <code class="literal">event_trigger</code>.
+ </p><p>
+ In the syntax of <code class="literal">CREATE EVENT TRIGGER</code>, the keywords
+ <code class="literal">FUNCTION</code> and <code class="literal">PROCEDURE</code> are
+ equivalent, but the referenced function must in any case be a function,
+ not a procedure. The use of the keyword <code class="literal">PROCEDURE</code>
+ here is historical and deprecated.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATEEVENTTRIGGER-NOTES"><h2>Notes</h2><p>
+ Only superusers can create event triggers.
+ </p><p>
+ Event triggers are disabled in single-user mode (see <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a>). If an erroneous event trigger disables the
+ database so much that you can't even drop the trigger, restart in
+ single-user mode and you'll be able to do that.
+ </p></div><div class="refsect1" id="SQL-CREATEEVENTTRIGGER-EXAMPLES"><h2>Examples</h2><p>
+ Forbid the execution of any <a class="link" href="ddl.html" title="Chapter 5. Data Definition">DDL</a> command:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION abort_any_command()
+ RETURNS event_trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+ RAISE EXCEPTION 'command % is disabled', tg_tag;
+END;
+$$;
+
+CREATE EVENT TRIGGER abort_ddl ON ddl_command_start
+ EXECUTE FUNCTION abort_any_command();
+</pre></div><div class="refsect1" id="SQL-CREATEEVENTTRIGGER-COMPATIBILITY"><h2>Compatibility</h2><p>
+ There is no <code class="command">CREATE EVENT TRIGGER</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.63.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER"><span class="refentrytitle">ALTER EVENT TRIGGER</span></a>, <a class="xref" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER"><span class="refentrytitle">DROP EVENT TRIGGER</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createdomain.html" title="CREATE DOMAIN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createextension.html" title="CREATE EXTENSION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE DOMAIN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE EXTENSION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createextension.html b/doc/src/sgml/html/sql-createextension.html
new file mode 100644
index 0000000..be39c35
--- /dev/null
+++ b/doc/src/sgml/html/sql-createextension.html
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE EXTENSION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER" /><link rel="next" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE EXTENSION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEEXTENSION"><div class="titlepage"></div><a id="id-1.9.3.64.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE EXTENSION</span></h2><p>CREATE EXTENSION — install an extension</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE EXTENSION [ IF NOT EXISTS ] <em class="replaceable"><code>extension_name</code></em>
+ [ WITH ] [ SCHEMA <em class="replaceable"><code>schema_name</code></em> ]
+ [ VERSION <em class="replaceable"><code>version</code></em> ]
+ [ CASCADE ]
+</pre></div><div class="refsect1" id="id-1.9.3.64.5"><h2>Description</h2><p>
+ <code class="command">CREATE EXTENSION</code> loads a new extension into the current
+ database. There must not be an extension of the same name already loaded.
+ </p><p>
+ Loading an extension essentially amounts to running the extension's script
+ file. The script will typically create new <acronym class="acronym">SQL</acronym> objects such as
+ functions, data types, operators and index support methods.
+ <code class="command">CREATE EXTENSION</code> additionally records the identities
+ of all the created objects, so that they can be dropped again if
+ <code class="command">DROP EXTENSION</code> is issued.
+ </p><p>
+ The user who runs <code class="command">CREATE EXTENSION</code> becomes the
+ owner of the extension for purposes of later privilege checks, and
+ normally also becomes the owner of any objects created by the
+ extension's script.
+ </p><p>
+ Loading an extension ordinarily requires the same privileges that would
+ be required to create its component objects. For many extensions this
+ means superuser privileges are needed.
+ However, if the extension is marked <em class="firstterm">trusted</em> in
+ its control file, then it can be installed by any user who has
+ <code class="literal">CREATE</code> privilege on the current database.
+ In this case the extension object itself will be owned by the calling
+ user, but the contained objects will be owned by the bootstrap superuser
+ (unless the extension's script explicitly assigns them to the calling
+ user). This configuration gives the calling user the right to drop the
+ extension, but not to modify individual objects within it.
+ </p></div><div class="refsect1" id="id-1.9.3.64.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if an extension with the same name already
+ exists. A notice is issued in this case. Note that there is no
+ guarantee that the existing extension is anything like the one that
+ would have been created from the currently-available script file.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>extension_name</code></em></span></dt><dd><p>
+ The name of the extension to be
+ installed. <span class="productname">PostgreSQL</span> will create the
+ extension using details from the file
+ <code class="literal">SHAREDIR/extension/</code><em class="replaceable"><code>extension_name</code></em><code class="literal">.control</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>schema_name</code></em></span></dt><dd><p>
+ The name of the schema in which to install the extension's
+ objects, given that the extension allows its contents to be
+ relocated. The named schema must already exist.
+ If not specified, and the extension's control file does not specify a
+ schema either, the current default object creation schema is used.
+ </p><p>
+ If the extension specifies a <code class="literal">schema</code> parameter in its
+ control file, then that schema cannot be overridden with
+ a <code class="literal">SCHEMA</code> clause. Normally, an error will be raised if
+ a <code class="literal">SCHEMA</code> clause is given and it conflicts with the
+ extension's <code class="literal">schema</code> parameter. However, if
+ the <code class="literal">CASCADE</code> clause is also given,
+ then <em class="replaceable"><code>schema_name</code></em> is
+ ignored when it conflicts. The
+ given <em class="replaceable"><code>schema_name</code></em> will be
+ used for installation of any needed extensions that do not
+ specify <code class="literal">schema</code> in their control files.
+ </p><p>
+ Remember that the extension itself is not considered to be within any
+ schema: extensions have unqualified names that must be unique
+ database-wide. But objects belonging to the extension can be within
+ schemas.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>version</code></em></span></dt><dd><p>
+ The version of the extension to install. This can be written as
+ either an identifier or a string literal. The default version is
+ whatever is specified in the extension's control file.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically install any extensions that this extension depends on
+ that are not already installed. Their dependencies are likewise
+ automatically installed, recursively. The <code class="literal">SCHEMA</code> clause,
+ if given, applies to all extensions that get installed this way.
+ Other options of the statement are not applied to
+ automatically-installed extensions; in particular, their default
+ versions are always selected.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.64.7"><h2>Notes</h2><p>
+ Before you can use <code class="command">CREATE EXTENSION</code> to load an extension
+ into a database, the extension's supporting files must be installed.
+ Information about installing the extensions supplied with
+ <span class="productname">PostgreSQL</span> can be found in
+ <a class="link" href="contrib.html" title="Appendix F. Additional Supplied Modules">Additional Supplied Modules</a>.
+ </p><p>
+ The extensions currently available for loading can be identified from the
+ <a class="link" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions"><code class="structname">pg_available_extensions</code></a>
+ or
+ <a class="link" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions"><code class="structname">pg_available_extension_versions</code></a>
+ system views.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ Installing an extension as superuser requires trusting that the
+ extension's author wrote the extension installation script in a secure
+ fashion. It is not terribly difficult for a malicious user to create
+ trojan-horse objects that will compromise later execution of a
+ carelessly-written extension script, allowing that user to acquire
+ superuser privileges. However, trojan-horse objects are only hazardous
+ if they are in the <code class="varname">search_path</code> during script
+ execution, meaning that they are in the extension's installation target
+ schema or in the schema of some extension it depends on. Therefore, a
+ good rule of thumb when dealing with extensions whose scripts have not
+ been carefully vetted is to install them only into schemas for which
+ CREATE privilege has not been and will not be granted to any untrusted
+ users. Likewise for any extensions they depend on.
+ </p><p>
+ The extensions supplied with <span class="productname">PostgreSQL</span> are
+ believed to be secure against installation-time attacks of this sort,
+ except for a few that depend on other extensions. As stated in the
+ documentation for those extensions, they should be installed into secure
+ schemas, or installed into the same schemas as the extensions they
+ depend on, or both.
+ </p></div><p>
+ For information about writing new extensions, see
+ <a class="xref" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Section 38.17</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.64.8"><h2>Examples</h2><p>
+ Install the <a class="link" href="hstore.html" title="F.18. hstore">hstore</a> extension into the
+ current database, placing its objects in schema <code class="literal">addons</code>:
+</p><pre class="programlisting">
+CREATE EXTENSION hstore SCHEMA addons;
+</pre><p>
+ Another way to accomplish the same thing:
+</p><pre class="programlisting">
+SET search_path = addons;
+CREATE EXTENSION hstore;
+</pre></div><div class="refsect1" id="id-1.9.3.64.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE EXTENSION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.64.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterextension.html" title="ALTER EXTENSION"><span class="refentrytitle">ALTER EXTENSION</span></a>, <a class="xref" href="sql-dropextension.html" title="DROP EXTENSION"><span class="refentrytitle">DROP EXTENSION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE EVENT TRIGGER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE FOREIGN DATA WRAPPER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createforeigndatawrapper.html b/doc/src/sgml/html/sql-createforeigndatawrapper.html
new file mode 100644
index 0000000..d45b8df
--- /dev/null
+++ b/doc/src/sgml/html/sql-createforeigndatawrapper.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE FOREIGN DATA WRAPPER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createextension.html" title="CREATE EXTENSION" /><link rel="next" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE FOREIGN DATA WRAPPER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createextension.html" title="CREATE EXTENSION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEFOREIGNDATAWRAPPER"><div class="titlepage"></div><a id="id-1.9.3.65.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></h2><p>CREATE FOREIGN DATA WRAPPER — define a new foreign-data wrapper</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE FOREIGN DATA WRAPPER <em class="replaceable"><code>name</code></em>
+ [ HANDLER <em class="replaceable"><code>handler_function</code></em> | NO HANDLER ]
+ [ VALIDATOR <em class="replaceable"><code>validator_function</code></em> | NO VALIDATOR ]
+ [ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.65.5"><h2>Description</h2><p>
+ <code class="command">CREATE FOREIGN DATA WRAPPER</code> creates a new
+ foreign-data wrapper. The user who defines a foreign-data wrapper
+ becomes its owner.
+ </p><p>
+ The foreign-data wrapper name must be unique within the database.
+ </p><p>
+ Only superusers can create foreign-data wrappers.
+ </p></div><div class="refsect1" id="id-1.9.3.65.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the foreign-data wrapper to be created.
+ </p></dd><dt><span class="term"><code class="literal">HANDLER <em class="replaceable"><code>handler_function</code></em></code></span></dt><dd><p><em class="replaceable"><code>handler_function</code></em> is the
+ name of a previously registered function that will be called to
+ retrieve the execution functions for foreign tables.
+ The handler function must take no arguments, and
+ its return type must be <code class="type">fdw_handler</code>.
+ </p><p>
+ It is possible to create a foreign-data wrapper with no handler
+ function, but foreign tables using such a wrapper can only be declared,
+ not accessed.
+ </p></dd><dt><span class="term"><code class="literal">VALIDATOR <em class="replaceable"><code>validator_function</code></em></code></span></dt><dd><p><em class="replaceable"><code>validator_function</code></em>
+ is the name of a previously registered function that will be called to
+ check the generic options given to the foreign-data wrapper, as
+ well as options for foreign servers, user mappings and foreign tables
+ using the foreign-data wrapper. If no validator function or <code class="literal">NO
+ VALIDATOR</code> is specified, then options will not be
+ checked at creation time. (Foreign-data wrappers will possibly
+ ignore or reject invalid option specifications at run time,
+ depending on the implementation.) The validator function must
+ take two arguments: one of type <code class="type">text[]</code>, which will
+ contain the array of options as stored in the system catalogs,
+ and one of type <code class="type">oid</code>, which will be the OID of the
+ system catalog containing the options. The return type is ignored;
+ the function should report invalid options using the
+ <code class="function">ereport(ERROR)</code> function.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] )</code></span></dt><dd><p>
+ This clause specifies options for the new foreign-data wrapper.
+ The allowed option names and values are specific to each foreign
+ data wrapper and are validated using the foreign-data wrapper's
+ validator function. Option names must be unique.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.65.7"><h2>Notes</h2><p>
+ <span class="productname">PostgreSQL</span>'s foreign-data functionality is still under
+ active development. Optimization of queries is primitive (and mostly left
+ to the wrapper, too). Thus, there is considerable room for future
+ performance improvements.
+ </p></div><div class="refsect1" id="id-1.9.3.65.8"><h2>Examples</h2><p>
+ Create a useless foreign-data wrapper <code class="literal">dummy</code>:
+</p><pre class="programlisting">
+CREATE FOREIGN DATA WRAPPER dummy;
+</pre><p>
+ </p><p>
+ Create a foreign-data wrapper <code class="literal">file</code> with
+ handler function <code class="literal">file_fdw_handler</code>:
+</p><pre class="programlisting">
+CREATE FOREIGN DATA WRAPPER file HANDLER file_fdw_handler;
+</pre><p>
+ </p><p>
+ Create a foreign-data wrapper <code class="literal">mywrapper</code> with some
+ options:
+</p><pre class="programlisting">
+CREATE FOREIGN DATA WRAPPER mywrapper
+ OPTIONS (debug 'true');
+</pre></div><div class="refsect1" id="id-1.9.3.65.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE FOREIGN DATA WRAPPER</code> conforms to ISO/IEC
+ 9075-9 (SQL/MED), with the exception that the <code class="literal">HANDLER</code>
+ and <code class="literal">VALIDATOR</code> clauses are extensions and the standard
+ clauses <code class="literal">LIBRARY</code> and <code class="literal">LANGUAGE</code>
+ are not implemented in <span class="productname">PostgreSQL</span>.
+ </p><p>
+ Note, however, that the SQL/MED functionality as a whole is not yet
+ conforming.
+ </p></div><div class="refsect1" id="id-1.9.3.65.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER"><span class="refentrytitle">ALTER FOREIGN DATA WRAPPER</span></a>, <a class="xref" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER"><span class="refentrytitle">DROP FOREIGN DATA WRAPPER</span></a>, <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>, <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>, <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createextension.html" title="CREATE EXTENSION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE EXTENSION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE FOREIGN TABLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createforeigntable.html b/doc/src/sgml/html/sql-createforeigntable.html
new file mode 100644
index 0000000..8df4b65
--- /dev/null
+++ b/doc/src/sgml/html/sql-createforeigntable.html
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE FOREIGN TABLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER" /><link rel="next" href="sql-createfunction.html" title="CREATE FUNCTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE FOREIGN TABLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createfunction.html" title="CREATE FUNCTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEFOREIGNTABLE"><div class="titlepage"></div><a id="id-1.9.3.66.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE FOREIGN TABLE</span></h2><p>CREATE FOREIGN TABLE — define a new foreign table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE FOREIGN TABLE [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em> ( [
+ { <em class="replaceable"><code>column_name</code></em> <em class="replaceable"><code>data_type</code></em> [ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] ) ] [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ | <em class="replaceable"><code>table_constraint</code></em> }
+ [, ... ]
+] )
+[ INHERITS ( <em class="replaceable"><code>parent_table</code></em> [, ... ] ) ]
+ SERVER <em class="replaceable"><code>server_name</code></em>
+[ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] ) ]
+
+CREATE FOREIGN TABLE [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em>
+ PARTITION OF <em class="replaceable"><code>parent_table</code></em> [ (
+ { <em class="replaceable"><code>column_name</code></em> [ WITH OPTIONS ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ | <em class="replaceable"><code>table_constraint</code></em> }
+ [, ... ]
+) ]
+{ FOR VALUES <em class="replaceable"><code>partition_bound_spec</code></em> | DEFAULT }
+ SERVER <em class="replaceable"><code>server_name</code></em>
+[ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] ) ]
+
+<span class="phrase">where <em class="replaceable"><code>column_constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+{ NOT NULL |
+ NULL |
+ CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] |
+ DEFAULT <em class="replaceable"><code>default_expr</code></em> |
+ GENERATED ALWAYS AS ( <em class="replaceable"><code>generation_expr</code></em> ) STORED }
+
+<span class="phrase">and <em class="replaceable"><code>table_constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ]
+
+<span class="phrase">and <em class="replaceable"><code>partition_bound_spec</code></em> is:</span>
+
+IN ( <em class="replaceable"><code>partition_bound_expr</code></em> [, ...] ) |
+FROM ( { <em class="replaceable"><code>partition_bound_expr</code></em> | MINVALUE | MAXVALUE } [, ...] )
+ TO ( { <em class="replaceable"><code>partition_bound_expr</code></em> | MINVALUE | MAXVALUE } [, ...] ) |
+WITH ( MODULUS <em class="replaceable"><code>numeric_literal</code></em>, REMAINDER <em class="replaceable"><code>numeric_literal</code></em> )
+</pre></div><div class="refsect1" id="SQL-CREATEFOREIGNTABLE-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE FOREIGN TABLE</code> creates a new foreign table
+ in the current database. The table will be owned by the user issuing the
+ command.
+ </p><p>
+ If a schema name is given (for example, <code class="literal">CREATE FOREIGN TABLE
+ myschema.mytable ...</code>) then the table is created in the specified
+ schema. Otherwise it is created in the current schema.
+ The name of the foreign table must be
+ distinct from the name of any other relation (table, sequence, index, view,
+ materialized view, or foreign table) in the same schema.
+ </p><p>
+ <code class="command">CREATE FOREIGN TABLE</code> also automatically creates a data
+ type that represents the composite type corresponding to one row of
+ the foreign table. Therefore, foreign tables cannot have the same
+ name as any existing data type in the same schema.
+ </p><p>
+ If <code class="literal">PARTITION OF</code> clause is specified then the table is
+ created as a partition of <code class="literal">parent_table</code> with specified
+ bounds.
+ </p><p>
+ To be able to create a foreign table, you must have <code class="literal">USAGE</code>
+ privilege on the foreign server, as well as <code class="literal">USAGE</code>
+ privilege on all column types used in the table.
+ </p></div><div class="refsect1" id="id-1.9.3.66.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing relation is anything like the one that would have been
+ created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column to be created in the new table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The data type of the column. This can include array
+ specifiers. For more information on the data types supported by
+ <span class="productname">PostgreSQL</span>, refer to <a class="xref" href="datatype.html" title="Chapter 8. Data Types">Chapter 8</a>.
+ </p></dd><dt><span class="term"><code class="literal">COLLATE <em class="replaceable"><code>collation</code></em></code></span></dt><dd><p>
+ The <code class="literal">COLLATE</code> clause assigns a collation to
+ the column (which must be of a collatable data type).
+ If not specified, the column data type's default collation is used.
+ </p></dd><dt><span class="term"><code class="literal">INHERITS ( <em class="replaceable"><code>parent_table</code></em> [, ... ] )</code></span></dt><dd><p>
+ The optional <code class="literal">INHERITS</code> clause specifies a list of
+ tables from which the new foreign table automatically inherits
+ all columns. Parent tables can be plain tables or foreign tables.
+ See the similar form of
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a> for more details.
+ </p></dd><dt><span class="term"><code class="literal">PARTITION OF <em class="replaceable"><code>parent_table</code></em> { FOR VALUES <em class="replaceable"><code>partition_bound_spec</code></em> | DEFAULT }</code></span></dt><dd><p>
+ This form can be used to create the foreign table as partition of
+ the given parent table with specified partition bound values.
+ See the similar form of
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a> for more details.
+ Note that it is currently not allowed to create the foreign table as a
+ partition of the parent table if there are <code class="literal">UNIQUE</code>
+ indexes on the parent table. (See also
+ <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ATTACH PARTITION</code></a>.)
+ </p></dd><dt><span class="term"><code class="literal">CONSTRAINT <em class="replaceable"><code>constraint_name</code></em></code></span></dt><dd><p>
+ An optional name for a column or table constraint. If the
+ constraint is violated, the constraint name is present in error messages,
+ so constraint names like <code class="literal">col must be positive</code> can be used
+ to communicate helpful constraint information to client applications.
+ (Double-quotes are needed to specify constraint names that contain spaces.)
+ If a constraint name is not specified, the system generates a name.
+ </p></dd><dt><span class="term"><code class="literal">NOT NULL</code></span></dt><dd><p>
+ The column is not allowed to contain null values.
+ </p></dd><dt><span class="term"><code class="literal">NULL</code></span></dt><dd><p>
+ The column is allowed to contain null values. This is the default.
+ </p><p>
+ This clause is only provided for compatibility with
+ non-standard SQL databases. Its use is discouraged in new
+ applications.
+ </p></dd><dt><span class="term"><code class="literal">CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] </code></span></dt><dd><p>
+ The <code class="literal">CHECK</code> clause specifies an expression producing a
+ Boolean result which each row in the foreign table is expected
+ to satisfy; that is, the expression should produce TRUE or UNKNOWN,
+ never FALSE, for all rows in the foreign table.
+ A check constraint specified as a column constraint should
+ reference that column's value only, while an expression
+ appearing in a table constraint can reference multiple columns.
+ </p><p>
+ Currently, <code class="literal">CHECK</code> expressions cannot contain
+ subqueries nor refer to variables other than columns of the
+ current row. The system column <code class="literal">tableoid</code>
+ may be referenced, but not any other system column.
+ </p><p>
+ A constraint marked with <code class="literal">NO INHERIT</code> will not propagate to
+ child tables.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT
+ <em class="replaceable"><code>default_expr</code></em></code></span></dt><dd><p>
+ The <code class="literal">DEFAULT</code> clause assigns a default data value for
+ the column whose column definition it appears within. The value
+ is any variable-free expression (subqueries and cross-references
+ to other columns in the current table are not allowed). The
+ data type of the default expression must match the data type of the
+ column.
+ </p><p>
+ The default expression will be used in any insert operation that
+ does not specify a value for the column. If there is no default
+ for a column, then the default is null.
+ </p></dd><dt><span class="term"><code class="literal">GENERATED ALWAYS AS ( <em class="replaceable"><code>generation_expr</code></em> ) STORED</code><a id="id-1.9.3.66.6.2.13.1.2" class="indexterm"></a></span></dt><dd><p>
+ This clause creates the column as a <em class="firstterm">generated
+ column</em>. The column cannot be written to, and when read the
+ result of the specified expression will be returned.
+ </p><p>
+ The keyword <code class="literal">STORED</code> is required to signify that the
+ column will be computed on write. (The computed value will be presented
+ to the foreign-data wrapper for storage and must be returned on
+ reading.)
+ </p><p>
+ The generation expression can refer to other columns in the table, but
+ not other generated columns. Any functions and operators used must be
+ immutable. References to other tables are not allowed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_name</code></em></span></dt><dd><p>
+ The name of an existing foreign server to use for the foreign table.
+ For details on defining a server, see <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ...] )</code></span></dt><dd><p>
+ Options to be associated with the new foreign table or one of its
+ columns.
+ The allowed option names and values are specific to each foreign
+ data wrapper and are validated using the foreign-data wrapper's
+ validator function. Duplicate option names are not allowed (although
+ it's OK for a table option and a column option to have the same name).
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.66.7"><h2>Notes</h2><p>
+ Constraints on foreign tables (such as <code class="literal">CHECK</code>
+ or <code class="literal">NOT NULL</code> clauses) are not enforced by the
+ core <span class="productname">PostgreSQL</span> system, and most foreign data wrappers
+ do not attempt to enforce them either; that is, the constraint is
+ simply assumed to hold true. There would be little point in such
+ enforcement since it would only apply to rows inserted or updated via
+ the foreign table, and not to rows modified by other means, such as
+ directly on the remote server. Instead, a constraint attached to a
+ foreign table should represent a constraint that is being enforced by
+ the remote server.
+ </p><p>
+ Some special-purpose foreign data wrappers might be the only access
+ mechanism for the data they access, and in that case it might be
+ appropriate for the foreign data wrapper itself to perform constraint
+ enforcement. But you should not assume that a wrapper does that
+ unless its documentation says so.
+ </p><p>
+ Although <span class="productname">PostgreSQL</span> does not attempt to enforce
+ constraints on foreign tables, it does assume that they are correct
+ for purposes of query optimization. If there are rows visible in the
+ foreign table that do not satisfy a declared constraint, queries on
+ the table might produce errors or incorrect answers. It is the user's
+ responsibility to ensure that the constraint definition matches
+ reality.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ When a foreign table is used as a partition of a partitioned table,
+ there is an implicit constraint that its contents must satisfy the
+ partitioning rule. Again, it is the user's responsibility to ensure
+ that that is true, which is best done by installing a matching
+ constraint on the remote server.
+ </p></div><p>
+ Within a partitioned table containing foreign-table partitions,
+ an <code class="command">UPDATE</code> that changes the partition key value can
+ cause a row to be moved from a local partition to a foreign-table
+ partition, provided the foreign data wrapper supports tuple routing.
+ However it is not currently possible to move a row from a
+ foreign-table partition to another partition.
+ An <code class="command">UPDATE</code> that would require doing that will fail
+ due to the partitioning constraint, assuming that that is properly
+ enforced by the remote server.
+ </p><p>
+ Similar considerations apply to generated columns. Stored generated
+ columns are computed on insert or update on the local
+ <span class="productname">PostgreSQL</span> server and handed to the
+ foreign-data wrapper for writing out to the foreign data store, but it is
+ not enforced that a query of the foreign table returns values for stored
+ generated columns that are consistent with the generation expression.
+ Again, this might result in incorrect query results.
+ </p></div><div class="refsect1" id="SQL-CREATEFOREIGNTABLE-EXAMPLES"><h2>Examples</h2><p>
+ Create foreign table <code class="structname">films</code>, which will be accessed through
+ the server <code class="structname">film_server</code>:
+
+</p><pre class="programlisting">
+CREATE FOREIGN TABLE films (
+ code char(5) NOT NULL,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+)
+SERVER film_server;
+</pre><p>
+ Create foreign table <code class="structname">measurement_y2016m07</code>, which will be
+ accessed through the server <code class="structname">server_07</code>, as a partition
+ of the range partitioned table <code class="structname">measurement</code>:
+
+</p><pre class="programlisting">
+CREATE FOREIGN TABLE measurement_y2016m07
+ PARTITION OF measurement FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')
+ SERVER server_07;
+</pre></div><div class="refsect1" id="SQL-CREATEFOREIGNTABLE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The <code class="command">CREATE FOREIGN TABLE</code> command largely conforms to the
+ <acronym class="acronym">SQL</acronym> standard; however, much as with
+ <a class="link" href="sql-createtable.html" title="CREATE TABLE"><code class="command">CREATE TABLE</code></a>,
+ <code class="literal">NULL</code> constraints and zero-column foreign tables are permitted.
+ The ability to specify column default values is also
+ a <span class="productname">PostgreSQL</span> extension. Table inheritance, in the form
+ defined by <span class="productname">PostgreSQL</span>, is nonstandard.
+ </p></div><div class="refsect1" id="id-1.9.3.66.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE"><span class="refentrytitle">ALTER FOREIGN TABLE</span></a>, <a class="xref" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE"><span class="refentrytitle">DROP FOREIGN TABLE</span></a>, <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>, <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>, <a class="xref" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA"><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createfunction.html" title="CREATE FUNCTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE FOREIGN DATA WRAPPER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE FUNCTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createfunction.html b/doc/src/sgml/html/sql-createfunction.html
new file mode 100644
index 0000000..1f43d48
--- /dev/null
+++ b/doc/src/sgml/html/sql-createfunction.html
@@ -0,0 +1,554 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE FUNCTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE" /><link rel="next" href="sql-creategroup.html" title="CREATE GROUP" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE FUNCTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-creategroup.html" title="CREATE GROUP">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEFUNCTION"><div class="titlepage"></div><a id="id-1.9.3.67.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE FUNCTION</span></h2><p>CREATE FUNCTION — define a new function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] FUNCTION
+ <em class="replaceable"><code>name</code></em> ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ { DEFAULT | = } <em class="replaceable"><code>default_expr</code></em> ] [, ...] ] )
+ [ RETURNS <em class="replaceable"><code>rettype</code></em>
+ | RETURNS TABLE ( <em class="replaceable"><code>column_name</code></em> <em class="replaceable"><code>column_type</code></em> [, ...] ) ]
+ { LANGUAGE <em class="replaceable"><code>lang_name</code></em>
+ | TRANSFORM { FOR TYPE <em class="replaceable"><code>type_name</code></em> } [, ... ]
+ | WINDOW
+ | { IMMUTABLE | STABLE | VOLATILE }
+ | [ NOT ] LEAKPROOF
+ | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
+ | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
+ | PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ | COST <em class="replaceable"><code>execution_cost</code></em>
+ | ROWS <em class="replaceable"><code>result_rows</code></em>
+ | SUPPORT <em class="replaceable"><code>support_function</code></em>
+ | SET <em class="replaceable"><code>configuration_parameter</code></em> { TO <em class="replaceable"><code>value</code></em> | = <em class="replaceable"><code>value</code></em> | FROM CURRENT }
+ | AS '<em class="replaceable"><code>definition</code></em>'
+ | AS '<em class="replaceable"><code>obj_file</code></em>', '<em class="replaceable"><code>link_symbol</code></em>'
+ | <em class="replaceable"><code>sql_body</code></em>
+ } ...
+</pre></div><div class="refsect1" id="SQL-CREATEFUNCTION-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE FUNCTION</code> defines a new function.
+ <code class="command">CREATE OR REPLACE FUNCTION</code> will either create a
+ new function, or replace an existing definition.
+ To be able to define a function, the user must have the
+ <code class="literal">USAGE</code> privilege on the language.
+ </p><p>
+ If a schema name is included, then the function is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The name of the new function must not match any existing function or procedure
+ with the same input argument types in the same schema. However,
+ functions and procedures of different argument types can share a name (this is
+ called <em class="firstterm">overloading</em>).
+ </p><p>
+ To replace the current definition of an existing function, use
+ <code class="command">CREATE OR REPLACE FUNCTION</code>. It is not possible
+ to change the name or argument types of a function this way (if you
+ tried, you would actually be creating a new, distinct function).
+ Also, <code class="command">CREATE OR REPLACE FUNCTION</code> will not let
+ you change the return type of an existing function. To do that,
+ you must drop and recreate the function. (When using <code class="literal">OUT</code>
+ parameters, that means you cannot change the types of any
+ <code class="literal">OUT</code> parameters except by dropping the function.)
+ </p><p>
+ When <code class="command">CREATE OR REPLACE FUNCTION</code> is used to replace an
+ existing function, the ownership and permissions of the function
+ do not change. All other function properties are assigned the
+ values specified or implied in the command. You must own the function
+ to replace it (this includes being a member of the owning role).
+ </p><p>
+ If you drop and then recreate a function, the new function is not
+ the same entity as the old; you will have to drop existing rules, views,
+ triggers, etc. that refer to the old function. Use
+ <code class="command">CREATE OR REPLACE FUNCTION</code> to change a function
+ definition without breaking objects that refer to the function.
+ Also, <code class="command">ALTER FUNCTION</code> can be used to change most of the
+ auxiliary properties of an existing function.
+ </p><p>
+ The user that creates the function becomes the owner of the function.
+ </p><p>
+ To be able to create a function, you must have <code class="literal">USAGE</code>
+ privilege on the argument types and the return type.
+ </p><p>
+ Refer to <a class="xref" href="xfunc.html" title="38.3. User-Defined Functions">Section 38.3</a> for further information on writing
+ functions.
+ </p></div><div class="refsect1" id="id-1.9.3.67.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the function to create.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ Only <code class="literal">OUT</code> arguments can follow a <code class="literal">VARIADIC</code> one.
+ Also, <code class="literal">OUT</code> and <code class="literal">INOUT</code> arguments cannot be used
+ together with the <code class="literal">RETURNS TABLE</code> notation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument. Some languages (including SQL and PL/pgSQL)
+ let you use the name in the function body. For other languages the
+ name of an input argument is just extra documentation, so far as
+ the function itself is concerned; but you can use input argument names
+ when calling a function to improve readability (see <a class="xref" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Section 4.3</a>). In any case, the name
+ of an output argument is significant, because it defines the column
+ name in the result row type. (If you omit the name for an output
+ argument, the system will choose a default column name.)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type(s) of the function's arguments (optionally
+ schema-qualified), if any. The argument types can be base, composite,
+ or domain types, or can reference the type of a table column.
+ </p><p>
+ Depending on the implementation language it might also be allowed
+ to specify <span class="quote">“<span class="quote">pseudo-types</span>”</span> such as <code class="type">cstring</code>.
+ Pseudo-types indicate that the actual argument type is either
+ incompletely specified, or outside the set of ordinary SQL data types.
+ </p><p>
+ The type of a column is referenced by writing
+ <code class="literal"><em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em>%TYPE</code>.
+ Using this feature can sometimes help make a function independent of
+ changes to the definition of a table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>default_expr</code></em></span></dt><dd><p>
+ An expression to be used as default value if the parameter is
+ not specified. The expression has to be coercible to the
+ argument type of the parameter.
+ Only input (including <code class="literal">INOUT</code>) parameters can have a default
+ value. All input parameters following a
+ parameter with a default value must have default values as well.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>rettype</code></em></span></dt><dd><p>
+ The return data type (optionally schema-qualified). The return type
+ can be a base, composite, or domain type,
+ or can reference the type of a table column.
+ Depending on the implementation language it might also be allowed
+ to specify <span class="quote">“<span class="quote">pseudo-types</span>”</span> such as <code class="type">cstring</code>.
+ If the function is not supposed to return a value, specify
+ <code class="type">void</code> as the return type.
+ </p><p>
+ When there are <code class="literal">OUT</code> or <code class="literal">INOUT</code> parameters,
+ the <code class="literal">RETURNS</code> clause can be omitted. If present, it
+ must agree with the result type implied by the output parameters:
+ <code class="literal">RECORD</code> if there are multiple output parameters, or
+ the same type as the single output parameter.
+ </p><p>
+ The <code class="literal">SETOF</code>
+ modifier indicates that the function will return a set of
+ items, rather than a single item.
+ </p><p>
+ The type of a column is referenced by writing
+ <code class="literal"><em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em>%TYPE</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of an output column in the <code class="literal">RETURNS TABLE</code>
+ syntax. This is effectively another way of declaring a named
+ <code class="literal">OUT</code> parameter, except that <code class="literal">RETURNS TABLE</code>
+ also implies <code class="literal">RETURNS SETOF</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_type</code></em></span></dt><dd><p>
+ The data type of an output column in the <code class="literal">RETURNS TABLE</code>
+ syntax.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the language that the function is implemented in.
+ It can be <code class="literal">sql</code>, <code class="literal">c</code>,
+ <code class="literal">internal</code>, or the name of a user-defined
+ procedural language, e.g., <code class="literal">plpgsql</code>. The default is
+ <code class="literal">sql</code> if <em class="replaceable"><code>sql_body</code></em> is specified. Enclosing the
+ name in single quotes is deprecated and requires matching case.
+ </p></dd><dt><span class="term"><code class="literal">TRANSFORM { FOR TYPE <em class="replaceable"><code>type_name</code></em> } [, ... ] }</code></span></dt><dd><p>
+ Lists which transforms a call to the function should apply. Transforms
+ convert between SQL types and language-specific data types;
+ see <a class="xref" href="sql-createtransform.html" title="CREATE TRANSFORM"><span class="refentrytitle">CREATE TRANSFORM</span></a>. Procedural language
+ implementations usually have hardcoded knowledge of the built-in types,
+ so those don't need to be listed here. If a procedural language
+ implementation does not know how to handle a type and no transform is
+ supplied, it will fall back to a default behavior for converting data
+ types, but this depends on the implementation.
+ </p></dd><dt><span class="term"><code class="literal">WINDOW</code></span></dt><dd><p><code class="literal">WINDOW</code> indicates that the function is a
+ <em class="firstterm">window function</em> rather than a plain function.
+ This is currently only useful for functions written in C.
+ The <code class="literal">WINDOW</code> attribute cannot be changed when
+ replacing an existing function definition.
+ </p></dd><dt><span class="term"><code class="literal">IMMUTABLE</code><br /></span><span class="term"><code class="literal">STABLE</code><br /></span><span class="term"><code class="literal">VOLATILE</code></span></dt><dd><p>
+ These attributes inform the query optimizer about the behavior
+ of the function. At most one choice
+ can be specified. If none of these appear,
+ <code class="literal">VOLATILE</code> is the default assumption.
+ </p><p><code class="literal">IMMUTABLE</code> indicates that the function
+ cannot modify the database and always
+ returns the same result when given the same argument values; that
+ is, it does not do database lookups or otherwise use information not
+ directly present in its argument list. If this option is given,
+ any call of the function with all-constant arguments can be
+ immediately replaced with the function value.
+ </p><p><code class="literal">STABLE</code> indicates that the function
+ cannot modify the database,
+ and that within a single table scan it will consistently
+ return the same result for the same argument values, but that its
+ result could change across SQL statements. This is the appropriate
+ selection for functions whose results depend on database lookups,
+ parameter variables (such as the current time zone), etc. (It is
+ inappropriate for <code class="literal">AFTER</code> triggers that wish to
+ query rows modified by the current command.) Also note
+ that the <code class="function">current_timestamp</code> family of functions qualify
+ as stable, since their values do not change within a transaction.
+ </p><p><code class="literal">VOLATILE</code> indicates that the function value can
+ change even within a single table scan, so no optimizations can be
+ made. Relatively few database functions are volatile in this sense;
+ some examples are <code class="literal">random()</code>, <code class="literal">currval()</code>,
+ <code class="literal">timeofday()</code>. But note that any function that has
+ side-effects must be classified volatile, even if its result is quite
+ predictable, to prevent calls from being optimized away; an example is
+ <code class="literal">setval()</code>.
+ </p><p>
+ For additional details see <a class="xref" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Section 38.7</a>.
+ </p></dd><dt><span class="term"><code class="literal">LEAKPROOF</code></span></dt><dd><p>
+ <code class="literal">LEAKPROOF</code> indicates that the function has no side
+ effects. It reveals no information about its arguments other than by
+ its return value. For example, a function which throws an error message
+ for some argument values but not others, or which includes the argument
+ values in any error message, is not leakproof. This affects how the
+ system executes queries against views created with the
+ <code class="literal">security_barrier</code> option or tables with row level
+ security enabled. The system will enforce conditions from security
+ policies and security barrier views before any user-supplied conditions
+ from the query itself that contain non-leakproof functions, in order to
+ prevent the inadvertent exposure of data. Functions and operators
+ marked as leakproof are assumed to be trustworthy, and may be executed
+ before conditions from security policies and security barrier views.
+ In addition, functions which do not take arguments or which are not
+ passed any arguments from the security barrier view or table do not have
+ to be marked as leakproof to be executed before security conditions. See
+ <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a> and <a class="xref" href="rules-privileges.html" title="41.5. Rules and Privileges">Section 41.5</a>.
+ This option can only be set by the superuser.
+ </p></dd><dt><span class="term"><code class="literal">CALLED ON NULL INPUT</code><br /></span><span class="term"><code class="literal">RETURNS NULL ON NULL INPUT</code><br /></span><span class="term"><code class="literal">STRICT</code></span></dt><dd><p><code class="literal">CALLED ON NULL INPUT</code> (the default) indicates
+ that the function will be called normally when some of its
+ arguments are null. It is then the function author's
+ responsibility to check for null values if necessary and respond
+ appropriately.
+ </p><p><code class="literal">RETURNS NULL ON NULL INPUT</code> or
+ <code class="literal">STRICT</code> indicates that the function always
+ returns null whenever any of its arguments are null. If this
+ parameter is specified, the function is not executed when there
+ are null arguments; instead a null result is assumed
+ automatically.
+ </p></dd><dt><span class="term"><code class="literal">[<span class="optional">EXTERNAL</span>] SECURITY INVOKER</code><br /></span><span class="term"><code class="literal">[<span class="optional">EXTERNAL</span>] SECURITY DEFINER</code></span></dt><dd><p><code class="literal">SECURITY INVOKER</code> indicates that the function
+ is to be executed with the privileges of the user that calls it.
+ That is the default. <code class="literal">SECURITY DEFINER</code>
+ specifies that the function is to be executed with the
+ privileges of the user that owns it.
+ </p><p>
+ The key word <code class="literal">EXTERNAL</code> is allowed for SQL
+ conformance, but it is optional since, unlike in SQL, this feature
+ applies to all functions not only external ones.
+ </p></dd><dt><span class="term"><code class="literal">PARALLEL</code></span></dt><dd><p><code class="literal">PARALLEL UNSAFE</code> indicates that the function
+ can't be executed in parallel mode and the presence of such a
+ function in an SQL statement forces a serial execution plan. This is
+ the default. <code class="literal">PARALLEL RESTRICTED</code> indicates that
+ the function can be executed in parallel mode, but the execution is
+ restricted to parallel group leader. <code class="literal">PARALLEL SAFE</code>
+ indicates that the function is safe to run in parallel mode without
+ restriction.
+ </p><p>
+ Functions should be labeled parallel unsafe if they modify any database
+ state, or if they make changes to the transaction such as using
+ sub-transactions, or if they access sequences or attempt to make
+ persistent changes to settings (e.g., <code class="literal">setval</code>). They should
+ be labeled as parallel restricted if they access temporary tables,
+ client connection state, cursors, prepared statements, or miscellaneous
+ backend-local state which the system cannot synchronize in parallel mode
+ (e.g., <code class="literal">setseed</code> cannot be executed other than by the group
+ leader because a change made by another process would not be reflected
+ in the leader). In general, if a function is labeled as being safe when
+ it is restricted or unsafe, or if it is labeled as being restricted when
+ it is in fact unsafe, it may throw errors or produce wrong answers
+ when used in a parallel query. C-language functions could in theory
+ exhibit totally undefined behavior if mislabeled, since there is no way
+ for the system to protect itself against arbitrary C code, but in most
+ likely cases the result will be no worse than for any other function.
+ If in doubt, functions should be labeled as <code class="literal">UNSAFE</code>, which is
+ the default.
+ </p></dd><dt><span class="term"><code class="literal">COST</code> <em class="replaceable"><code>execution_cost</code></em></span></dt><dd><p>
+ A positive number giving the estimated execution cost for the function,
+ in units of <a class="xref" href="runtime-config-query.html#GUC-CPU-OPERATOR-COST">cpu_operator_cost</a>. If the function
+ returns a set, this is the cost per returned row. If the cost is
+ not specified, 1 unit is assumed for C-language and internal functions,
+ and 100 units for functions in all other languages. Larger values
+ cause the planner to try to avoid evaluating the function more often
+ than necessary.
+ </p></dd><dt><span class="term"><code class="literal">ROWS</code> <em class="replaceable"><code>result_rows</code></em></span></dt><dd><p>
+ A positive number giving the estimated number of rows that the planner
+ should expect the function to return. This is only allowed when the
+ function is declared to return a set. The default assumption is
+ 1000 rows.
+ </p></dd><dt><span class="term"><code class="literal">SUPPORT</code> <em class="replaceable"><code>support_function</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a <em class="firstterm">planner support
+ function</em> to use for this function. See
+ <a class="xref" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Section 38.11</a> for details.
+ You must be superuser to use this option.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em><br /></span><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ The <code class="literal">SET</code> clause causes the specified configuration
+ parameter to be set to the specified value when the function is
+ entered, and then restored to its prior value when the function exits.
+ <code class="literal">SET FROM CURRENT</code> saves the value of the parameter that
+ is current when <code class="command">CREATE FUNCTION</code> is executed as the value
+ to be applied when the function is entered.
+ </p><p>
+ If a <code class="literal">SET</code> clause is attached to a function, then
+ the effects of a <code class="command">SET LOCAL</code> command executed inside the
+ function for the same variable are restricted to the function: the
+ configuration parameter's prior value is still restored at function exit.
+ However, an ordinary
+ <code class="command">SET</code> command (without <code class="literal">LOCAL</code>) overrides the
+ <code class="literal">SET</code> clause, much as it would do for a previous <code class="command">SET
+ LOCAL</code> command: the effects of such a command will persist after
+ function exit, unless the current transaction is rolled back.
+ </p><p>
+ See <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> and
+ <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ for more information about allowed parameter names and values.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>definition</code></em></span></dt><dd><p>
+ A string constant defining the function; the meaning depends on the
+ language. It can be an internal function name, the path to an
+ object file, an SQL command, or text in a procedural language.
+ </p><p>
+ It is often helpful to use dollar quoting (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>) to write the function definition
+ string, rather than the normal single quote syntax. Without dollar
+ quoting, any single quotes or backslashes in the function definition must
+ be escaped by doubling them.
+ </p></dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>obj_file</code></em>, <em class="replaceable"><code>link_symbol</code></em></code></span></dt><dd><p>
+ This form of the <code class="literal">AS</code> clause is used for
+ dynamically loadable C language functions when the function name
+ in the C language source code is not the same as the name of
+ the SQL function. The string <em class="replaceable"><code>obj_file</code></em> is the name of the shared
+ library file containing the compiled C function, and is interpreted
+ as for the <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command. The string
+ <em class="replaceable"><code>link_symbol</code></em> is the
+ function's link symbol, that is, the name of the function in the C
+ language source code. If the link symbol is omitted, it is assumed to
+ be the same as the name of the SQL function being defined. The C names
+ of all functions must be different, so you must give overloaded C
+ functions different C names (for example, use the argument types as
+ part of the C names).
+ </p><p>
+ When repeated <code class="command">CREATE FUNCTION</code> calls refer to
+ the same object file, the file is only loaded once per session.
+ To unload and
+ reload the file (perhaps during development), start a new session.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sql_body</code></em></span></dt><dd><p>
+ The body of a <code class="literal">LANGUAGE SQL</code> function. This can
+ either be a single statement
+</p><pre class="programlisting">
+RETURN <em class="replaceable"><code>expression</code></em>
+</pre><p>
+ or a block
+</p><pre class="programlisting">
+BEGIN ATOMIC
+ <em class="replaceable"><code>statement</code></em>;
+ <em class="replaceable"><code>statement</code></em>;
+ ...
+ <em class="replaceable"><code>statement</code></em>;
+END
+</pre><p>
+ </p><p>
+ This is similar to writing the text of the function body as a string
+ constant (see <em class="replaceable"><code>definition</code></em> above), but there
+ are some differences: This form only works for <code class="literal">LANGUAGE
+ SQL</code>, the string constant form works for all languages. This
+ form is parsed at function definition time, the string constant form is
+ parsed at execution time; therefore this form cannot support
+ polymorphic argument types and other constructs that are not resolvable
+ at function definition time. This form tracks dependencies between the
+ function and objects used in the function body, so <code class="literal">DROP
+ ... CASCADE</code> will work correctly, whereas the form using
+ string literals may leave dangling functions. Finally, this form is
+ more compatible with the SQL standard and other SQL implementations.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATEFUNCTION-OVERLOADING"><h2>Overloading</h2><p>
+ <span class="productname">PostgreSQL</span> allows function
+ <em class="firstterm">overloading</em>; that is, the same name can be
+ used for several different functions so long as they have distinct
+ input argument types. Whether or not you use it, this capability entails
+ security precautions when calling functions in databases where some users
+ mistrust other users; see <a class="xref" href="typeconv-func.html" title="10.3. Functions">Section 10.3</a>.
+ </p><p>
+ Two functions are considered the same if they have the same names and
+ <span class="emphasis"><em>input</em></span> argument types, ignoring any <code class="literal">OUT</code>
+ parameters. Thus for example these declarations conflict:
+</p><pre class="programlisting">
+CREATE FUNCTION foo(int) ...
+CREATE FUNCTION foo(int, out text) ...
+</pre><p>
+ </p><p>
+ Functions that have different argument type lists will not be considered
+ to conflict at creation time, but if defaults are provided they might
+ conflict in use. For example, consider
+</p><pre class="programlisting">
+CREATE FUNCTION foo(int) ...
+CREATE FUNCTION foo(int, int default 42) ...
+</pre><p>
+ A call <code class="literal">foo(10)</code> will fail due to the ambiguity about which
+ function should be called.
+ </p></div><div class="refsect1" id="SQL-CREATEFUNCTION-NOTES"><h2>Notes</h2><p>
+ The full <acronym class="acronym">SQL</acronym> type syntax is allowed for
+ declaring a function's arguments and return value. However,
+ parenthesized type modifiers (e.g., the precision field for
+ type <code class="type">numeric</code>) are discarded by <code class="command">CREATE FUNCTION</code>.
+ Thus for example
+ <code class="literal">CREATE FUNCTION foo (varchar(10)) ...</code>
+ is exactly the same as
+ <code class="literal">CREATE FUNCTION foo (varchar) ...</code>.
+ </p><p>
+ When replacing an existing function with <code class="command">CREATE OR REPLACE
+ FUNCTION</code>, there are restrictions on changing parameter names.
+ You cannot change the name already assigned to any input parameter
+ (although you can add names to parameters that had none before).
+ If there is more than one output parameter, you cannot change the
+ names of the output parameters, because that would change the
+ column names of the anonymous composite type that describes the
+ function's result. These restrictions are made to ensure that
+ existing calls of the function do not stop working when it is replaced.
+ </p><p>
+ If a function is declared <code class="literal">STRICT</code> with a <code class="literal">VARIADIC</code>
+ argument, the strictness check tests that the variadic array <span class="emphasis"><em>as
+ a whole</em></span> is non-null. The function will still be called if the
+ array has null elements.
+ </p></div><div class="refsect1" id="SQL-CREATEFUNCTION-EXAMPLES"><h2>Examples</h2><p>
+ Add two integers using an SQL function:
+</p><pre class="programlisting">
+CREATE FUNCTION add(integer, integer) RETURNS integer
+ AS 'select $1 + $2;'
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT;
+</pre><p>
+ The same function written in a more SQL-conforming style, using argument
+ names and an unquoted body:
+</p><pre class="programlisting">
+CREATE FUNCTION add(a integer, b integer) RETURNS integer
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT
+ RETURN a + b;
+</pre><p>
+ </p><p>
+ Increment an integer, making use of an argument name, in
+ <span class="application">PL/pgSQL</span>:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
+ BEGIN
+ RETURN i + 1;
+ END;
+$$ LANGUAGE plpgsql;
+</pre><p>
+ </p><p>
+ Return a record containing multiple output parameters:
+</p><pre class="programlisting">
+CREATE FUNCTION dup(in int, out f1 int, out f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+</pre><p>
+ You can do the same thing more verbosely with an explicitly named
+ composite type:
+</p><pre class="programlisting">
+CREATE TYPE dup_result AS (f1 int, f2 text);
+
+CREATE FUNCTION dup(int) RETURNS dup_result
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+</pre><p>
+ Another way to return multiple columns is to use a <code class="literal">TABLE</code>
+ function:
+</p><pre class="programlisting">
+CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+</pre><p>
+ However, a <code class="literal">TABLE</code> function is different from the
+ preceding examples, because it actually returns a <span class="emphasis"><em>set</em></span>
+ of records, not just one record.
+ </p></div><div class="refsect1" id="SQL-CREATEFUNCTION-SECURITY"><h2>Writing <code class="literal">SECURITY DEFINER</code> Functions Safely</h2><a id="id-1.9.3.67.10.2" class="indexterm"></a><p>
+ Because a <code class="literal">SECURITY DEFINER</code> function is executed
+ with the privileges of the user that owns it, care is needed to
+ ensure that the function cannot be misused. For security,
+ <a class="xref" href="runtime-config-client.html#GUC-SEARCH-PATH">search_path</a> should be set to exclude any schemas
+ writable by untrusted users. This prevents
+ malicious users from creating objects (e.g., tables, functions, and
+ operators) that mask objects intended to be used by the function.
+ Particularly important in this regard is the
+ temporary-table schema, which is searched first by default, and
+ is normally writable by anyone. A secure arrangement can be obtained
+ by forcing the temporary schema to be searched last. To do this,
+ write <code class="literal">pg_temp</code><a id="id-1.9.3.67.10.3.4" class="indexterm"></a> as the last entry in <code class="varname">search_path</code>.
+ This function illustrates safe usage:
+
+</p><pre class="programlisting">
+CREATE FUNCTION check_password(uname TEXT, pass TEXT)
+RETURNS BOOLEAN AS $$
+DECLARE passed BOOLEAN;
+BEGIN
+ SELECT (pwd = $2) INTO passed
+ FROM pwds
+ WHERE username = $1;
+
+ RETURN passed;
+END;
+$$ LANGUAGE plpgsql
+ SECURITY DEFINER
+ -- Set a secure search_path: trusted schema(s), then 'pg_temp'.
+ SET search_path = admin, pg_temp;
+</pre><p>
+
+ This function's intention is to access a table <code class="literal">admin.pwds</code>.
+ But without the <code class="literal">SET</code> clause, or with a <code class="literal">SET</code> clause
+ mentioning only <code class="literal">admin</code>, the function could be subverted by
+ creating a temporary table named <code class="literal">pwds</code>.
+ </p><p>
+ Before <span class="productname">PostgreSQL</span> version 8.3, the
+ <code class="literal">SET</code> clause was not available, and so older functions may
+ contain rather complicated logic to save, set, and restore
+ <code class="varname">search_path</code>. The <code class="literal">SET</code> clause is far easier
+ to use for this purpose.
+ </p><p>
+ Another point to keep in mind is that by default, execute privilege
+ is granted to <code class="literal">PUBLIC</code> for newly created functions
+ (see <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for more
+ information). Frequently you will wish to restrict use of a security
+ definer function to only some users. To do that, you must revoke
+ the default <code class="literal">PUBLIC</code> privileges and then grant execute
+ privilege selectively. To avoid having a window where the new function
+ is accessible to all, create it and set the privileges within a single
+ transaction. For example:
+ </p><pre class="programlisting">
+BEGIN;
+CREATE FUNCTION check_password(uname TEXT, pass TEXT) ... SECURITY DEFINER;
+REVOKE ALL ON FUNCTION check_password(uname TEXT, pass TEXT) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION check_password(uname TEXT, pass TEXT) TO admins;
+COMMIT;
+</pre></div><div class="refsect1" id="SQL-CREATEFUNCTION-COMPAT"><h2>Compatibility</h2><p>
+ A <code class="command">CREATE FUNCTION</code> command is defined in the SQL
+ standard. The <span class="productname">PostgreSQL</span> implementation can be
+ used in a compatible way but has many extensions. Conversely, the SQL
+ standard specifies a number of optional features that are not implemented
+ in <span class="productname">PostgreSQL</span>.
+ </p><p>
+ The following are important compatibility issues:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">OR REPLACE</code> is a PostgreSQL extension.
+ </p></li><li class="listitem"><p>
+ For compatibility with some other database systems, <em class="replaceable"><code>argmode</code></em> can be written either before or
+ after <em class="replaceable"><code>argname</code></em>. But only
+ the first way is standard-compliant.
+ </p></li><li class="listitem"><p>
+ For parameter defaults, the SQL standard specifies only the syntax with
+ the <code class="literal">DEFAULT</code> key word. The syntax with
+ <code class="literal">=</code> is used in T-SQL and Firebird.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">SETOF</code> modifier is a PostgreSQL extension.
+ </p></li><li class="listitem"><p>
+ Only <code class="literal">SQL</code> is standardized as a language.
+ </p></li><li class="listitem"><p>
+ All other attributes except <code class="literal">CALLED ON NULL INPUT</code> and
+ <code class="literal">RETURNS NULL ON NULL INPUT</code> are not standardized.
+ </p></li><li class="listitem"><p>
+ For the body of <code class="literal">LANGUAGE SQL</code> functions, the SQL
+ standard only specifies the <em class="replaceable"><code>sql_body</code></em> form.
+ </p></li></ul></div><p>
+ </p><p>
+ Simple <code class="literal">LANGUAGE SQL</code> functions can be written in a way
+ that is both standard-conforming and portable to other implementations.
+ More complex functions using advanced features, optimization attributes, or
+ other languages will necessarily be specific to PostgreSQL in a significant
+ way.
+ </p></div><div class="refsect1" id="id-1.9.3.67.12"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>, <a class="xref" href="sql-dropfunction.html" title="DROP FUNCTION"><span class="refentrytitle">DROP FUNCTION</span></a>, <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>, <a class="xref" href="sql-load.html" title="LOAD"><span class="refentrytitle">LOAD</span></a>, <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-creategroup.html" title="CREATE GROUP">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE FOREIGN TABLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE GROUP</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-creategroup.html b/doc/src/sgml/html/sql-creategroup.html
new file mode 100644
index 0000000..43a814f
--- /dev/null
+++ b/doc/src/sgml/html/sql-creategroup.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE GROUP</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createfunction.html" title="CREATE FUNCTION" /><link rel="next" href="sql-createindex.html" title="CREATE INDEX" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE GROUP</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createfunction.html" title="CREATE FUNCTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createindex.html" title="CREATE INDEX">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEGROUP"><div class="titlepage"></div><a id="id-1.9.3.68.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE GROUP</span></h2><p>CREATE GROUP — define a new database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE GROUP <em class="replaceable"><code>name</code></em> [ [ WITH ] <em class="replaceable"><code>option</code></em> [ ... ] ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <em class="replaceable"><code>connlimit</code></em>
+ | [ ENCRYPTED ] PASSWORD '<em class="replaceable"><code>password</code></em>' | PASSWORD NULL
+ | VALID UNTIL '<em class="replaceable"><code>timestamp</code></em>'
+ | IN ROLE <em class="replaceable"><code>role_name</code></em> [, ...]
+ | IN GROUP <em class="replaceable"><code>role_name</code></em> [, ...]
+ | ROLE <em class="replaceable"><code>role_name</code></em> [, ...]
+ | ADMIN <em class="replaceable"><code>role_name</code></em> [, ...]
+ | USER <em class="replaceable"><code>role_name</code></em> [, ...]
+ | SYSID <em class="replaceable"><code>uid</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.68.5"><h2>Description</h2><p>
+ <code class="command">CREATE GROUP</code> is now an alias for
+ <a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.68.6"><h2>Compatibility</h2><p>
+ There is no <code class="command">CREATE GROUP</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.68.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createfunction.html" title="CREATE FUNCTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createindex.html" title="CREATE INDEX">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE FUNCTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE INDEX</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createindex.html b/doc/src/sgml/html/sql-createindex.html
new file mode 100644
index 0000000..80d3c1f
--- /dev/null
+++ b/doc/src/sgml/html/sql-createindex.html
@@ -0,0 +1,580 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE INDEX</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-creategroup.html" title="CREATE GROUP" /><link rel="next" href="sql-createlanguage.html" title="CREATE LANGUAGE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE INDEX</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-creategroup.html" title="CREATE GROUP">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createlanguage.html" title="CREATE LANGUAGE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEINDEX"><div class="titlepage"></div><a id="id-1.9.3.69.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE INDEX</span></h2><p>CREATE INDEX — define a new index</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <em class="replaceable"><code>name</code></em> ] ON [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ USING <em class="replaceable"><code>method</code></em> ]
+ ( { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>opclass</code></em> [ ( <em class="replaceable"><code>opclass_parameter</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
+ [ INCLUDE ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ [ NULLS [ NOT ] DISTINCT ]
+ [ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+ [ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+ [ WHERE <em class="replaceable"><code>predicate</code></em> ]
+</pre></div><div class="refsect1" id="id-1.9.3.69.5"><h2>Description</h2><p>
+ <code class="command">CREATE INDEX</code> constructs an index on the specified column(s)
+ of the specified relation, which can be a table or a materialized view.
+ Indexes are primarily used to enhance database performance (though
+ inappropriate use can result in slower performance).
+ </p><p>
+ The key field(s) for the index are specified as column names,
+ or alternatively as expressions written in parentheses.
+ Multiple fields can be specified if the index method supports
+ multicolumn indexes.
+ </p><p>
+ An index field can be an expression computed from the values of
+ one or more columns of the table row. This feature can be used
+ to obtain fast access to data based on some transformation of
+ the basic data. For example, an index computed on
+ <code class="literal">upper(col)</code> would allow the clause
+ <code class="literal">WHERE upper(col) = 'JIM'</code> to use an index.
+ </p><p>
+ <span class="productname">PostgreSQL</span> provides the index methods
+ B-tree, hash, GiST, SP-GiST, GIN, and BRIN. Users can also define their own
+ index methods, but that is fairly complicated.
+ </p><p>
+ When the <code class="literal">WHERE</code> clause is present, a
+ <em class="firstterm">partial index</em> is created.
+ A partial index is an index that contains entries for only a portion of
+ a table, usually a portion that is more useful for indexing than the
+ rest of the table. For example, if you have a table that contains both
+ billed and unbilled orders where the unbilled orders take up a small
+ fraction of the total table and yet that is an often used section, you
+ can improve performance by creating an index on just that portion.
+ Another possible application is to use <code class="literal">WHERE</code> with
+ <code class="literal">UNIQUE</code> to enforce uniqueness over a subset of a
+ table. See <a class="xref" href="indexes-partial.html" title="11.8. Partial Indexes">Section 11.8</a> for more discussion.
+ </p><p>
+ The expression used in the <code class="literal">WHERE</code> clause can refer
+ only to columns of the underlying table, but it can use all columns,
+ not just the ones being indexed. Presently, subqueries and
+ aggregate expressions are also forbidden in <code class="literal">WHERE</code>.
+ The same restrictions apply to index fields that are expressions.
+ </p><p>
+ All functions and operators used in an index definition must be
+ <span class="quote">“<span class="quote">immutable</span>”</span>, that is, their results must depend only on
+ their arguments and never on any outside influence (such as
+ the contents of another table or the current time). This restriction
+ ensures that the behavior of the index is well-defined. To use a
+ user-defined function in an index expression or <code class="literal">WHERE</code>
+ clause, remember to mark the function immutable when you create it.
+ </p></div><div class="refsect1" id="id-1.9.3.69.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">UNIQUE</code></span></dt><dd><p>
+ Causes the system to check for
+ duplicate values in the table when the index is created (if data
+ already exist) and each time data is added. Attempts to
+ insert or update data which would result in duplicate entries
+ will generate an error.
+ </p><p>
+ Additional restrictions apply when unique indexes are applied to
+ partitioned tables; see <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>.
+ </p></dd><dt><span class="term"><code class="literal">CONCURRENTLY</code></span></dt><dd><p>
+ When this option is used, <span class="productname">PostgreSQL</span> will build the
+ index without taking any locks that prevent concurrent inserts,
+ updates, or deletes on the table; whereas a standard index build
+ locks out writes (but not reads) on the table until it's done.
+ There are several caveats to be aware of when using this option
+ — see <a class="xref" href="sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY" title="Building Indexes Concurrently">Building Indexes Concurrently</a> below.
+ </p><p>
+ For temporary tables, <code class="command">CREATE INDEX</code> is always
+ non-concurrent, as no other session can access them, and
+ non-concurrent index creation is cheaper.
+ </p></dd><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing index is anything like the one that would have been created.
+ Index name is required when <code class="literal">IF NOT EXISTS</code> is specified.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDE</code></span></dt><dd><p>
+ The optional <code class="literal">INCLUDE</code> clause specifies a
+ list of columns which will be included in the index
+ as <em class="firstterm">non-key</em> columns. A non-key column cannot
+ be used in an index scan search qualification, and it is disregarded
+ for purposes of any uniqueness or exclusion constraint enforced by
+ the index. However, an index-only scan can return the contents of
+ non-key columns without having to visit the index's table, since
+ they are available directly from the index entry. Thus, addition of
+ non-key columns allows index-only scans to be used for queries that
+ otherwise could not use them.
+ </p><p>
+ It's wise to be conservative about adding non-key columns to an
+ index, especially wide columns. If an index tuple exceeds the
+ maximum size allowed for the index type, data insertion will fail.
+ In any case, non-key columns duplicate data from the index's table
+ and bloat the size of the index, thus potentially slowing searches.
+ Furthermore, B-tree deduplication is never used with indexes
+ that have a non-key column.
+ </p><p>
+ Columns listed in the <code class="literal">INCLUDE</code> clause don't need
+ appropriate operator classes; the clause can include
+ columns whose data types don't have operator classes defined for
+ a given access method.
+ </p><p>
+ Expressions are not supported as included columns since they cannot be
+ used in index-only scans.
+ </p><p>
+ Currently, the B-tree, GiST and SP-GiST index access methods support
+ this feature. In these indexes, the values of columns listed
+ in the <code class="literal">INCLUDE</code> clause are included in leaf tuples
+ which correspond to heap tuples, but are not included in upper-level
+ index entries used for tree navigation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the index to be created. No schema name can be included
+ here; the index is always created in the same schema as its parent
+ table. The name of the index must be distinct from the name of any
+ other relation (table, sequence, index, view, materialized view, or
+ foreign table) in that schema.
+ If the name is omitted, <span class="productname">PostgreSQL</span> chooses a
+ suitable name based on the parent table's name and the indexed column
+ name(s).
+ </p></dd><dt><span class="term"><code class="literal">ONLY</code></span></dt><dd><p>
+ Indicates not to recurse creating indexes on partitions, if the
+ table is partitioned. The default is to recurse.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (possibly schema-qualified) of the table to be indexed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>method</code></em></span></dt><dd><p>
+ The name of the index method to be used. Choices are
+ <code class="literal">btree</code>, <code class="literal">hash</code>,
+ <code class="literal">gist</code>, <code class="literal">spgist</code>, <code class="literal">gin</code>,
+ <code class="literal">brin</code>, or user-installed access methods like
+ <a class="link" href="bloom.html" title="F.7. bloom">bloom</a>.
+ The default method is <code class="literal">btree</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column of the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
+ An expression based on one or more columns of the table. The
+ expression usually must be written with surrounding parentheses,
+ as shown in the syntax. However, the parentheses can be omitted
+ if the expression has the form of a function call.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>collation</code></em></span></dt><dd><p>
+ The name of the collation to use for the index. By default,
+ the index uses the collation declared for the column to be
+ indexed or the result collation of the expression to be
+ indexed. Indexes with non-default collations can be useful for
+ queries that involve expressions using non-default collations.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>opclass</code></em></span></dt><dd><p>
+ The name of an operator class. See below for details.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>opclass_parameter</code></em></span></dt><dd><p>
+ The name of an operator class parameter. See below for details.
+ </p></dd><dt><span class="term"><code class="literal">ASC</code></span></dt><dd><p>
+ Specifies ascending sort order (which is the default).
+ </p></dd><dt><span class="term"><code class="literal">DESC</code></span></dt><dd><p>
+ Specifies descending sort order.
+ </p></dd><dt><span class="term"><code class="literal">NULLS FIRST</code></span></dt><dd><p>
+ Specifies that nulls sort before non-nulls. This is the default
+ when <code class="literal">DESC</code> is specified.
+ </p></dd><dt><span class="term"><code class="literal">NULLS LAST</code></span></dt><dd><p>
+ Specifies that nulls sort after non-nulls. This is the default
+ when <code class="literal">DESC</code> is not specified.
+ </p></dd><dt><span class="term"><code class="literal">NULLS DISTINCT</code><br /></span><span class="term"><code class="literal">NULLS NOT DISTINCT</code></span></dt><dd><p>
+ Specifies whether for a unique index, null values should be considered
+ distinct (not equal). The default is that they are distinct, so that
+ a unique index could contain multiple null values in a column.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>storage_parameter</code></em></span></dt><dd><p>
+ The name of an index-method-specific storage parameter. See
+ <a class="xref" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS" title="Index Storage Parameters">Index Storage Parameters</a> below
+ for details.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>tablespace_name</code></em></span></dt><dd><p>
+ The tablespace in which to create the index. If not specified,
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> is consulted, or
+ <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> for indexes on temporary
+ tables.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>predicate</code></em></span></dt><dd><p>
+ The constraint expression for a partial index.
+ </p></dd></dl></div><div class="refsect2" id="SQL-CREATEINDEX-STORAGE-PARAMETERS"><h3>Index Storage Parameters</h3><p>
+ The optional <code class="literal">WITH</code> clause specifies <em class="firstterm">storage
+ parameters</em> for the index. Each index method has its own set of allowed
+ storage parameters. The B-tree, hash, GiST and SP-GiST index methods all
+ accept this parameter:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-FILLFACTOR"><span class="term"><code class="literal">fillfactor</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.69.6.3.3.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The fillfactor for an index is a percentage that determines how full
+ the index method will try to pack index pages. For B-trees, leaf pages
+ are filled to this percentage during initial index builds, and also
+ when extending the index at the right (adding new largest key values).
+ If pages
+ subsequently become completely full, they will be split, leading to
+ fragmentation of the on-disk index structure. B-trees use a default
+ fillfactor of 90, but any integer value from 10 to 100 can be selected.
+ </p><p>
+ B-tree indexes on tables where many inserts and/or updates are
+ anticipated can benefit from lower fillfactor settings at
+ <code class="command">CREATE INDEX</code> time (following bulk loading into the
+ table). Values in the range of 50 - 90 can usefully <span class="quote">“<span class="quote">smooth
+ out</span>”</span> the <span class="emphasis"><em>rate</em></span> of page splits during the
+ early life of the B-tree index (lowering fillfactor like this may even
+ lower the absolute number of page splits, though this effect is highly
+ workload dependent). The B-tree bottom-up index deletion technique
+ described in <a class="xref" href="btree-implementation.html#BTREE-DELETION" title="67.4.2. Bottom-up Index Deletion">Section 67.4.2</a> is dependent on having
+ some <span class="quote">“<span class="quote">extra</span>”</span> space on pages to store <span class="quote">“<span class="quote">extra</span>”</span>
+ tuple versions, and so can be affected by fillfactor (though the effect
+ is usually not significant).
+ </p><p>
+ In other specific cases it might be useful to increase fillfactor to
+ 100 at <code class="command">CREATE INDEX</code> time as a way of maximizing
+ space utilization. You should only consider this when you are
+ completely sure that the table is static (i.e. that it will never be
+ affected by either inserts or updates). A fillfactor setting of 100
+ otherwise risks <span class="emphasis"><em>harming</em></span> performance: even a few
+ updates or inserts will cause a sudden flood of page splits.
+ </p><p>
+ The other index methods use fillfactor in different but roughly
+ analogous ways; the default fillfactor varies between methods.
+ </p></dd></dl></div><p>
+ B-tree indexes additionally accept this parameter:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-DEDUPLICATE-ITEMS"><span class="term"><code class="literal">deduplicate_items</code> (<code class="type">boolean</code>)
+ <a id="id-1.9.3.69.6.3.5.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Controls usage of the B-tree deduplication technique described
+ in <a class="xref" href="btree-implementation.html#BTREE-DEDUPLICATION" title="67.4.3. Deduplication">Section 67.4.3</a>. Set to
+ <code class="literal">ON</code> or <code class="literal">OFF</code> to enable or
+ disable the optimization. (Alternative spellings of
+ <code class="literal">ON</code> and <code class="literal">OFF</code> are allowed as
+ described in <a class="xref" href="config-setting.html" title="20.1. Setting Parameters">Section 20.1</a>.) The default is
+ <code class="literal">ON</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Turning <code class="literal">deduplicate_items</code> off via
+ <code class="command">ALTER INDEX</code> prevents future insertions from
+ triggering deduplication, but does not in itself make existing
+ posting list tuples use the standard tuple representation.
+ </p></div></dd></dl></div><p>
+ GiST indexes additionally accept this parameter:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-BUFFERING"><span class="term"><code class="literal">buffering</code> (<code class="type">enum</code>)
+ <a id="id-1.9.3.69.6.3.7.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Determines whether the buffered build technique described in
+ <a class="xref" href="gist-implementation.html#GIST-BUFFERING-BUILD" title="68.4.1. GiST Index Build Methods">Section 68.4.1</a> is used to build the index. With
+ <code class="literal">OFF</code> buffering is disabled, with <code class="literal">ON</code>
+ it is enabled, and with <code class="literal">AUTO</code> it is initially disabled,
+ but is turned on on-the-fly once the index size reaches
+ <a class="xref" href="runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE">effective_cache_size</a>. The default
+ is <code class="literal">AUTO</code>.
+ Note that if sorted build is possible, it will be used instead of
+ buffered build unless <code class="literal">buffering=ON</code> is specified.
+ </p></dd></dl></div><p>
+ GIN indexes accept different parameters:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-FASTUPDATE"><span class="term"><code class="literal">fastupdate</code> (<code class="type">boolean</code>)
+ <a id="id-1.9.3.69.6.3.9.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This setting controls usage of the fast update technique described in
+ <a class="xref" href="gin-implementation.html#GIN-FAST-UPDATE" title="70.4.1. GIN Fast Update Technique">Section 70.4.1</a>. It is a Boolean parameter:
+ <code class="literal">ON</code> enables fast update, <code class="literal">OFF</code> disables it.
+ The default is <code class="literal">ON</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Turning <code class="literal">fastupdate</code> off via <code class="command">ALTER INDEX</code> prevents
+ future insertions from going into the list of pending index entries,
+ but does not in itself flush previous entries. You might want to
+ <code class="command">VACUUM</code> the table or call <code class="function">gin_clean_pending_list</code>
+ function afterward to ensure the pending list is emptied.
+ </p></div></dd></dl></div><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-GIN-PENDING-LIST-LIMIT"><span class="term"><code class="literal">gin_pending_list_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.69.6.3.10.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Custom <a class="xref" href="runtime-config-client.html#GUC-GIN-PENDING-LIST-LIMIT">gin_pending_list_limit</a> parameter.
+ This value is specified in kilobytes.
+ </p></dd></dl></div><p>
+ <acronym class="acronym">BRIN</acronym> indexes accept different parameters:
+ </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-PAGES-PER-RANGE"><span class="term"><code class="literal">pages_per_range</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.69.6.3.12.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Defines the number of table blocks that make up one block range for
+ each entry of a <acronym class="acronym">BRIN</acronym> index (see <a class="xref" href="brin-intro.html" title="71.1. Introduction">Section 71.1</a>
+ for more details). The default is <code class="literal">128</code>.
+ </p></dd><dt id="INDEX-RELOPTION-AUTOSUMMARIZE"><span class="term"><code class="literal">autosummarize</code> (<code class="type">boolean</code>)
+ <a id="id-1.9.3.69.6.3.12.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Defines whether a summarization run is queued for the previous page
+ range whenever an insertion is detected on the next one.
+ See <a class="xref" href="brin-intro.html#BRIN-OPERATION" title="71.1.1. Index Maintenance">Section 71.1.1</a> for more details.
+ The default is <code class="literal">off</code>.
+ </p></dd></dl></div></div><div class="refsect2" id="SQL-CREATEINDEX-CONCURRENTLY"><h3>Building Indexes Concurrently</h3><a id="id-1.9.3.69.6.4.2" class="indexterm"></a><p>
+ Creating an index can interfere with regular operation of a database.
+ Normally <span class="productname">PostgreSQL</span> locks the table to be indexed against
+ writes and performs the entire index build with a single scan of the
+ table. Other transactions can still read the table, but if they try to
+ insert, update, or delete rows in the table they will block until the
+ index build is finished. This could have a severe effect if the system is
+ a live production database. Very large tables can take many hours to be
+ indexed, and even for smaller tables, an index build can lock out writers
+ for periods that are unacceptably long for a production system.
+ </p><p>
+ <span class="productname">PostgreSQL</span> supports building indexes without locking
+ out writes. This method is invoked by specifying the
+ <code class="literal">CONCURRENTLY</code> option of <code class="command">CREATE INDEX</code>.
+ When this option is used,
+ <span class="productname">PostgreSQL</span> must perform two scans of the table, and in
+ addition it must wait for all existing transactions that could potentially
+ modify or use the index to terminate. Thus
+ this method requires more total work than a standard index build and takes
+ significantly longer to complete. However, since it allows normal
+ operations to continue while the index is built, this method is useful for
+ adding new indexes in a production environment. Of course, the extra CPU
+ and I/O load imposed by the index creation might slow other operations.
+ </p><p>
+ In a concurrent index build, the index is actually entered as an
+ <span class="quote">“<span class="quote">invalid</span>”</span> index into
+ the system catalogs in one transaction, then two table scans occur in
+ two more transactions. Before each table scan, the index build must
+ wait for existing transactions that have modified the table to terminate.
+ After the second scan, the index build must wait for any transactions
+ that have a snapshot (see <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>) predating the second
+ scan to terminate, including transactions used by any phase of concurrent
+ index builds on other tables, if the indexes involved are partial or have
+ columns that are not simple column references.
+ Then finally the index can be marked <span class="quote">“<span class="quote">valid</span>”</span> and ready for use,
+ and the <code class="command">CREATE INDEX</code> command terminates.
+ Even then, however, the index may not be immediately usable for queries:
+ in the worst case, it cannot be used as long as transactions exist that
+ predate the start of the index build.
+ </p><p>
+ If a problem arises while scanning the table, such as a deadlock or a
+ uniqueness violation in a unique index, the <code class="command">CREATE INDEX</code>
+ command will fail but leave behind an <span class="quote">“<span class="quote">invalid</span>”</span> index. This index
+ will be ignored for querying purposes because it might be incomplete;
+ however it will still consume update overhead. The <span class="application">psql</span>
+ <code class="command">\d</code> command will report such an index as <code class="literal">INVALID</code>:
+
+</p><pre class="programlisting">
+postgres=# \d tab
+ Table "public.tab"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ col | integer | | |
+Indexes:
+ "idx" btree (col) INVALID
+</pre><p>
+
+ The recommended recovery
+ method in such cases is to drop the index and try again to perform
+ <code class="command">CREATE INDEX CONCURRENTLY</code>. (Another possibility is
+ to rebuild the index with <code class="command">REINDEX INDEX CONCURRENTLY</code>).
+ </p><p>
+ Another caveat when building a unique index concurrently is that the
+ uniqueness constraint is already being enforced against other transactions
+ when the second table scan begins. This means that constraint violations
+ could be reported in other queries prior to the index becoming available
+ for use, or even in cases where the index build eventually fails. Also,
+ if a failure does occur in the second scan, the <span class="quote">“<span class="quote">invalid</span>”</span> index
+ continues to enforce its uniqueness constraint afterwards.
+ </p><p>
+ Concurrent builds of expression indexes and partial indexes are supported.
+ Errors occurring in the evaluation of these expressions could cause
+ behavior similar to that described above for unique constraint violations.
+ </p><p>
+ Regular index builds permit other regular index builds on the
+ same table to occur simultaneously, but only one concurrent index build
+ can occur on a table at a time. In either case, schema modification of the
+ table is not allowed while the index is being built. Another difference is
+ that a regular <code class="command">CREATE INDEX</code> command can be performed
+ within a transaction block, but <code class="command">CREATE INDEX CONCURRENTLY</code>
+ cannot.
+ </p><p>
+ Concurrent builds for indexes on partitioned tables are currently not
+ supported. However, you may concurrently build the index on each
+ partition individually and then finally create the partitioned index
+ non-concurrently in order to reduce the time where writes to the
+ partitioned table will be locked out. In this case, building the
+ partitioned index is a metadata only operation.
+ </p></div></div><div class="refsect1" id="id-1.9.3.69.7"><h2>Notes</h2><p>
+ See <a class="xref" href="indexes.html" title="Chapter 11. Indexes">Chapter 11</a> for information about when indexes can
+ be used, when they are not used, and in which particular situations
+ they can be useful.
+ </p><p>
+ Currently, only the B-tree, GiST, GIN, and BRIN index methods support
+ multiple-key-column indexes. Whether there can be multiple key
+ columns is independent of whether <code class="literal">INCLUDE</code> columns
+ can be added to the index. Indexes can have up to 32 columns,
+ including <code class="literal">INCLUDE</code> columns.
+ (This limit can be altered when building
+ <span class="productname">PostgreSQL</span>.) Only B-tree currently
+ supports unique indexes.
+ </p><p>
+ An <em class="firstterm">operator class</em> with optional parameters
+ can be specified for each column of an index.
+ The operator class identifies the operators to be
+ used by the index for that column. For example, a B-tree index on
+ four-byte integers would use the <code class="literal">int4_ops</code> class;
+ this operator class includes comparison functions for four-byte
+ integers. In practice the default operator class for the column's data
+ type is usually sufficient. The main point of having operator classes
+ is that for some data types, there could be more than one meaningful
+ ordering. For example, we might want to sort a complex-number data
+ type either by absolute value or by real part. We could do this by
+ defining two operator classes for the data type and then selecting
+ the proper class when creating an index. More information about
+ operator classes is in <a class="xref" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Section 11.10</a> and in <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a>.
+ </p><p>
+ When <code class="literal">CREATE INDEX</code> is invoked on a partitioned
+ table, the default behavior is to recurse to all partitions to ensure
+ they all have matching indexes.
+ Each partition is first checked to determine whether an equivalent
+ index already exists, and if so, that index will become attached as a
+ partition index to the index being created, which will become its
+ parent index.
+ If no matching index exists, a new index will be created and
+ automatically attached; the name of the new index in each partition
+ will be determined as if no index name had been specified in the
+ command.
+ If the <code class="literal">ONLY</code> option is specified, no recursion
+ is done, and the index is marked invalid.
+ (<code class="command">ALTER INDEX ... ATTACH PARTITION</code> marks the index
+ valid, once all partitions acquire matching indexes.) Note, however,
+ that any partition that is created in the future using
+ <code class="command">CREATE TABLE ... PARTITION OF</code> will automatically
+ have a matching index, regardless of whether <code class="literal">ONLY</code> is
+ specified.
+ </p><p>
+ For index methods that support ordered scans (currently, only B-tree),
+ the optional clauses <code class="literal">ASC</code>, <code class="literal">DESC</code>, <code class="literal">NULLS
+ FIRST</code>, and/or <code class="literal">NULLS LAST</code> can be specified to modify
+ the sort ordering of the index. Since an ordered index can be
+ scanned either forward or backward, it is not normally useful to create a
+ single-column <code class="literal">DESC</code> index — that sort ordering is already
+ available with a regular index. The value of these options is that
+ multicolumn indexes can be created that match the sort ordering requested
+ by a mixed-ordering query, such as <code class="literal">SELECT ... ORDER BY x ASC, y
+ DESC</code>. The <code class="literal">NULLS</code> options are useful if you need to support
+ <span class="quote">“<span class="quote">nulls sort low</span>”</span> behavior, rather than the default <span class="quote">“<span class="quote">nulls
+ sort high</span>”</span>, in queries that depend on indexes to avoid sorting steps.
+ </p><p>
+ The system regularly collects statistics on all of a table's
+ columns. Newly-created non-expression indexes can immediately
+ use these statistics to determine an index's usefulness.
+ For new expression indexes, it is necessary to run <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> or wait for
+ the <a class="link" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">autovacuum daemon</a> to analyze
+ the table to generate statistics for these indexes.
+ </p><p>
+ For most index methods, the speed of creating an index is
+ dependent on the setting of <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a>.
+ Larger values will reduce the time needed for index creation, so long
+ as you don't make it larger than the amount of memory really available,
+ which would drive the machine into swapping.
+ </p><p>
+ <span class="productname">PostgreSQL</span> can build indexes while
+ leveraging multiple CPUs in order to process the table rows faster.
+ This feature is known as <em class="firstterm">parallel index
+ build</em>. For index methods that support building indexes
+ in parallel (currently, only B-tree),
+ <code class="varname">maintenance_work_mem</code> specifies the maximum
+ amount of memory that can be used by each index build operation as
+ a whole, regardless of how many worker processes were started.
+ Generally, a cost model automatically determines how many worker
+ processes should be requested, if any.
+ </p><p>
+ Parallel index builds may benefit from increasing
+ <code class="varname">maintenance_work_mem</code> where an equivalent serial
+ index build will see little or no benefit. Note that
+ <code class="varname">maintenance_work_mem</code> may influence the number of
+ worker processes requested, since parallel workers must have at
+ least a <code class="literal">32MB</code> share of the total
+ <code class="varname">maintenance_work_mem</code> budget. There must also be
+ a remaining <code class="literal">32MB</code> share for the leader process.
+ Increasing <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-MAINTENANCE-WORKERS">max_parallel_maintenance_workers</a>
+ may allow more workers to be used, which will reduce the time
+ needed for index creation, so long as the index build is not
+ already I/O bound. Of course, there should also be sufficient
+ CPU capacity that would otherwise lie idle.
+ </p><p>
+ Setting a value for <code class="literal">parallel_workers</code> via <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE</code></a> directly controls how many parallel
+ worker processes will be requested by a <code class="command">CREATE
+ INDEX</code> against the table. This bypasses the cost model
+ completely, and prevents <code class="varname">maintenance_work_mem</code>
+ from affecting how many parallel workers are requested. Setting
+ <code class="literal">parallel_workers</code> to 0 via <code class="command">ALTER
+ TABLE</code> will disable parallel index builds on the table in
+ all cases.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ You might want to reset <code class="literal">parallel_workers</code> after
+ setting it as part of tuning an index build. This avoids
+ inadvertent changes to query plans, since
+ <code class="literal">parallel_workers</code> affects
+ <span class="emphasis"><em>all</em></span> parallel table scans.
+ </p></div><p>
+ While <code class="command">CREATE INDEX</code> with the
+ <code class="literal">CONCURRENTLY</code> option supports parallel builds
+ without special restrictions, only the first table scan is actually
+ performed in parallel.
+ </p><p>
+ Use <a class="link" href="sql-dropindex.html" title="DROP INDEX"><code class="command">DROP INDEX</code></a>
+ to remove an index.
+ </p><p>
+ Like any long-running transaction, <code class="command">CREATE INDEX</code> on a
+ table can affect which tuples can be removed by concurrent
+ <code class="command">VACUUM</code> on any other table.
+ </p><p>
+ Prior releases of <span class="productname">PostgreSQL</span> also had an
+ R-tree index method. This method has been removed because
+ it had no significant advantages over the GiST method.
+ If <code class="literal">USING rtree</code> is specified, <code class="command">CREATE INDEX</code>
+ will interpret it as <code class="literal">USING gist</code>, to simplify conversion
+ of old databases to GiST.
+ </p><p>
+ Each backend running <code class="command">CREATE INDEX</code> will report its
+ progress in the <code class="structname">pg_stat_progress_create_index</code>
+ view. See <a class="xref" href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING" title="28.4.2. CREATE INDEX Progress Reporting">Section 28.4.2</a> for details.
+ </p></div><div class="refsect1" id="id-1.9.3.69.8"><h2>Examples</h2><p>
+ To create a unique B-tree index on the column <code class="literal">title</code> in
+ the table <code class="literal">films</code>:
+</p><pre class="programlisting">
+CREATE UNIQUE INDEX title_idx ON films (title);
+</pre><p>
+ </p><p>
+ To create a unique B-tree index on the column <code class="literal">title</code>
+ with included columns <code class="literal">director</code>
+ and <code class="literal">rating</code> in the table <code class="literal">films</code>:
+</p><pre class="programlisting">
+CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);
+</pre><p>
+ </p><p>
+ To create a B-Tree index with deduplication disabled:
+</p><pre class="programlisting">
+CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off);
+</pre><p>
+ </p><p>
+ To create an index on the expression <code class="literal">lower(title)</code>,
+ allowing efficient case-insensitive searches:
+</p><pre class="programlisting">
+CREATE INDEX ON films ((lower(title)));
+</pre><p>
+ (In this example we have chosen to omit the index name, so the system
+ will choose a name, typically <code class="literal">films_lower_idx</code>.)
+ </p><p>
+ To create an index with non-default collation:
+</p><pre class="programlisting">
+CREATE INDEX title_idx_german ON films (title COLLATE "de_DE");
+</pre><p>
+ </p><p>
+ To create an index with non-default sort ordering of nulls:
+</p><pre class="programlisting">
+CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);
+</pre><p>
+ </p><p>
+ To create an index with non-default fill factor:
+</p><pre class="programlisting">
+CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70);
+</pre><p>
+ </p><p>
+ To create a <acronym class="acronym">GIN</acronym> index with fast updates disabled:
+</p><pre class="programlisting">
+CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off);
+</pre><p>
+ </p><p>
+ To create an index on the column <code class="literal">code</code> in the table
+ <code class="literal">films</code> and have the index reside in the tablespace
+ <code class="literal">indexspace</code>:
+</p><pre class="programlisting">
+CREATE INDEX code_idx ON films (code) TABLESPACE indexspace;
+</pre><p>
+ </p><p>
+ To create a GiST index on a point attribute so that we
+ can efficiently use box operators on the result of the
+ conversion function:
+</p><pre class="programlisting">
+CREATE INDEX pointloc
+ ON points USING gist (box(location,location));
+SELECT * FROM points
+ WHERE box(location,location) &amp;&amp; '(0,0),(1,1)'::box;
+</pre><p>
+ </p><p>
+ To create an index without locking out writes to the table:
+</p><pre class="programlisting">
+CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);
+</pre></div><div class="refsect1" id="id-1.9.3.69.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE INDEX</code> is a
+ <span class="productname">PostgreSQL</span> language extension. There
+ are no provisions for indexes in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.69.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterindex.html" title="ALTER INDEX"><span class="refentrytitle">ALTER INDEX</span></a>, <a class="xref" href="sql-dropindex.html" title="DROP INDEX"><span class="refentrytitle">DROP INDEX</span></a>, <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a>, <a class="xref" href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING" title="28.4.2. CREATE INDEX Progress Reporting">Section 28.4.2</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-creategroup.html" title="CREATE GROUP">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createlanguage.html" title="CREATE LANGUAGE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE GROUP </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE LANGUAGE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createlanguage.html b/doc/src/sgml/html/sql-createlanguage.html
new file mode 100644
index 0000000..3334969
--- /dev/null
+++ b/doc/src/sgml/html/sql-createlanguage.html
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE LANGUAGE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createindex.html" title="CREATE INDEX" /><link rel="next" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE LANGUAGE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createindex.html" title="CREATE INDEX">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATELANGUAGE"><div class="titlepage"></div><a id="id-1.9.3.70.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE LANGUAGE</span></h2><p>CREATE LANGUAGE — define a new procedural language</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>name</code></em>
+ HANDLER <em class="replaceable"><code>call_handler</code></em> [ INLINE <em class="replaceable"><code>inline_handler</code></em> ] [ VALIDATOR <em class="replaceable"><code>valfunction</code></em> ]
+CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>name</code></em>
+</pre></div><div class="refsect1" id="SQL-CREATELANGUAGE-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE LANGUAGE</code> registers a new
+ procedural language with a <span class="productname">PostgreSQL</span>
+ database. Subsequently, functions and procedures can be
+ defined in this new language.
+ </p><p>
+ <code class="command">CREATE LANGUAGE</code> effectively associates the
+ language name with handler function(s) that are responsible for executing
+ functions written in the language. Refer to <a class="xref" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Chapter 58</a>
+ for more information about language handlers.
+ </p><p>
+ <code class="command">CREATE OR REPLACE LANGUAGE</code> will either create a
+ new language, or replace an existing definition. If the language
+ already exists, its parameters are updated according to the command,
+ but the language's ownership and permissions settings do not change,
+ and any existing functions written in the language are assumed to still
+ be valid.
+ </p><p>
+ One must have the
+ <span class="productname">PostgreSQL</span> superuser privilege to
+ register a new language or change an existing language's parameters.
+ However, once the language is created it is valid to assign ownership of
+ it to a non-superuser, who may then drop it, change its permissions,
+ rename it, or assign it to a new owner. (Do not, however, assign
+ ownership of the underlying C functions to a non-superuser; that would
+ create a privilege escalation path for that user.)
+ </p><p>
+ The form of <code class="command">CREATE LANGUAGE</code> that does not supply
+ any handler function is obsolete. For backwards compatibility with
+ old dump files, it is interpreted as <code class="command">CREATE EXTENSION</code>.
+ That will work if the language has been packaged into an extension of
+ the same name, which is the conventional way to set up procedural
+ languages.
+ </p></div><div class="refsect1" id="SQL-CREATELANGUAGE-PARAMETERS"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TRUSTED</code></span></dt><dd><p><code class="literal">TRUSTED</code> specifies that the language does
+ not grant access to data that the user would not otherwise
+ have. If this key word is omitted
+ when registering the language, only users with the
+ <span class="productname">PostgreSQL</span> superuser privilege can
+ use this language to create new functions.
+ </p></dd><dt><span class="term"><code class="literal">PROCEDURAL</code></span></dt><dd><p>
+ This is a noise word.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the new procedural language.
+ The name must be unique among the languages in the database.
+ </p></dd><dt><span class="term"><code class="literal">HANDLER</code> <em class="replaceable"><code>call_handler</code></em></span></dt><dd><p><em class="replaceable"><code>call_handler</code></em> is
+ the name of a previously registered function that will be
+ called to execute the procedural language's functions. The call
+ handler for a procedural language must be written in a compiled
+ language such as C with version 1 call convention and
+ registered with <span class="productname">PostgreSQL</span> as a
+ function taking no arguments and returning the
+ <code class="type">language_handler</code> type, a placeholder type that is
+ simply used to identify the function as a call handler.
+ </p></dd><dt><span class="term"><code class="literal">INLINE</code> <em class="replaceable"><code>inline_handler</code></em></span></dt><dd><p><em class="replaceable"><code>inline_handler</code></em> is the
+ name of a previously registered function that will be called
+ to execute an anonymous code block
+ (<a class="link" href="sql-do.html" title="DO"><code class="command">DO</code></a> command)
+ in this language.
+ If no <em class="replaceable"><code>inline_handler</code></em>
+ function is specified, the language does not support anonymous code
+ blocks.
+ The handler function must take one argument of
+ type <code class="type">internal</code>, which will be the <code class="command">DO</code> command's
+ internal representation, and it will typically return
+ <code class="type">void</code>. The return value of the handler is ignored.
+ </p></dd><dt><span class="term"><code class="literal">VALIDATOR</code> <em class="replaceable"><code>valfunction</code></em></span></dt><dd><p><em class="replaceable"><code>valfunction</code></em> is the
+ name of a previously registered function that will be called
+ when a new function in the language is created, to validate the
+ new function.
+ If no
+ validator function is specified, then a new function will not
+ be checked when it is created.
+ The validator function must take one argument of
+ type <code class="type">oid</code>, which will be the OID of the
+ to-be-created function, and will typically return <code class="type">void</code>.
+ </p><p>
+ A validator function would typically inspect the function body
+ for syntactical correctness, but it can also look at other
+ properties of the function, for example if the language cannot
+ handle certain argument types. To signal an error, the
+ validator function should use the <code class="function">ereport()</code>
+ function. The return value of the function is ignored.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATELANGUAGE-NOTES"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-droplanguage.html" title="DROP LANGUAGE"><code class="command">DROP LANGUAGE</code></a> to drop procedural languages.
+ </p><p>
+ The system catalog <code class="classname">pg_language</code> (see <a class="xref" href="catalog-pg-language.html" title="53.29. pg_language">Section 53.29</a>) records information about the
+ currently installed languages. Also, the <span class="application">psql</span>
+ command <code class="command">\dL</code> lists the installed languages.
+ </p><p>
+ To create functions in a procedural language, a user must have the
+ <code class="literal">USAGE</code> privilege for the language. By default,
+ <code class="literal">USAGE</code> is granted to <code class="literal">PUBLIC</code> (i.e., everyone)
+ for trusted languages. This can be revoked if desired.
+ </p><p>
+ Procedural languages are local to individual databases.
+ However, a language can be installed into the <code class="literal">template1</code>
+ database, which will cause it to be available automatically in
+ all subsequently-created databases.
+ </p></div><div class="refsect1" id="SQL-CREATELANGUAGE-EXAMPLES"><h2>Examples</h2><p>
+ A minimal sequence for creating a new procedural language is:
+</p><pre class="programlisting">
+CREATE FUNCTION plsample_call_handler() RETURNS language_handler
+ AS '$libdir/plsample'
+ LANGUAGE C;
+CREATE LANGUAGE plsample
+ HANDLER plsample_call_handler;
+</pre><p>
+ Typically that would be written in an extension's creation script,
+ and users would do this to install the extension:
+</p><pre class="programlisting">
+CREATE EXTENSION plsample;
+</pre></div><div class="refsect1" id="SQL-CREATELANGUAGE-COMPAT"><h2>Compatibility</h2><p>
+ <code class="command">CREATE LANGUAGE</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.70.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterlanguage.html" title="ALTER LANGUAGE"><span class="refentrytitle">ALTER LANGUAGE</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-droplanguage.html" title="DROP LANGUAGE"><span class="refentrytitle">DROP LANGUAGE</span></a>, <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>, <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createindex.html" title="CREATE INDEX">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE INDEX </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE MATERIALIZED VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-creatematerializedview.html b/doc/src/sgml/html/sql-creatematerializedview.html
new file mode 100644
index 0000000..91ed26a
--- /dev/null
+++ b/doc/src/sgml/html/sql-creatematerializedview.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE MATERIALIZED VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createlanguage.html" title="CREATE LANGUAGE" /><link rel="next" href="sql-createoperator.html" title="CREATE OPERATOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE MATERIALIZED VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createlanguage.html" title="CREATE LANGUAGE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createoperator.html" title="CREATE OPERATOR">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEMATERIALIZEDVIEW"><div class="titlepage"></div><a id="id-1.9.3.71.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></h2><p>CREATE MATERIALIZED VIEW — define a new materialized view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em>
+ [ (<em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ [ USING <em class="replaceable"><code>method</code></em> ]
+ [ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+ [ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+ AS <em class="replaceable"><code>query</code></em>
+ [ WITH [ NO ] DATA ]
+</pre></div><div class="refsect1" id="id-1.9.3.71.5"><h2>Description</h2><p>
+ <code class="command">CREATE MATERIALIZED VIEW</code> defines a materialized view of
+ a query. The query is executed and used to populate the view at the time
+ the command is issued (unless <code class="command">WITH NO DATA</code> is used) and may be
+ refreshed later using <code class="command">REFRESH MATERIALIZED VIEW</code>.
+ </p><p>
+ <code class="command">CREATE MATERIALIZED VIEW</code> is similar to
+ <code class="command">CREATE TABLE AS</code>, except that it also remembers the query used
+ to initialize the view, so that it can be refreshed later upon demand.
+ A materialized view has many of the same properties as a table, but there
+ is no support for temporary materialized views.
+ </p><p>
+ <code class="command">CREATE MATERIALIZED VIEW</code> requires
+ <code class="literal">CREATE</code> privilege on the schema used for the materialized
+ view.
+ </p></div><div class="refsect1" id="id-1.9.3.71.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a materialized view with the same name already
+ exists. A notice is issued in this case. Note that there is no guarantee
+ that the existing materialized view is anything like the one that would
+ have been created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the materialized view to be
+ created. The name must be distinct from the name of any other relation
+ (table, sequence, index, view, materialized view, or foreign table) in
+ the same schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column in the new materialized view. If column names are
+ not provided, they are taken from the output column names of the query.
+ </p></dd><dt><span class="term"><code class="literal">USING <em class="replaceable"><code>method</code></em></code></span></dt><dd><p>
+ This optional clause specifies the table access method to use to store
+ the contents for the new materialized view; the method needs be an
+ access method of type <code class="literal">TABLE</code>. See <a class="xref" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Chapter 63</a> for more information. If this option is not
+ specified, the default table access method is chosen for the new
+ materialized view. See <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLE-ACCESS-METHOD">default_table_access_method</a>
+ for more information.
+ </p></dd><dt><span class="term"><code class="literal">WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause specifies optional storage parameters for the new
+ materialized view; see
+ <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" title="Storage Parameters">Storage Parameters</a> in the
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> documentation for more
+ information. All parameters supported for <code class="literal">CREATE
+ TABLE</code> are also supported for <code class="literal">CREATE MATERIALIZED
+ VIEW</code>.
+ See <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for more information.
+ </p></dd><dt><span class="term"><code class="literal">TABLESPACE <em class="replaceable"><code>tablespace_name</code></em></code></span></dt><dd><p>
+ The <em class="replaceable"><code>tablespace_name</code></em> is the name
+ of the tablespace in which the new materialized view is to be created.
+ If not specified, <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> is consulted.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a>, <a class="link" href="sql-select.html#SQL-TABLE" title="TABLE Command"><code class="command">TABLE</code></a>,
+ or <a class="link" href="sql-values.html" title="VALUES"><code class="command">VALUES</code></a> command. This query will run within a
+ security-restricted operation; in particular, calls to functions that
+ themselves create temporary tables will fail.
+ </p></dd><dt><span class="term"><code class="literal">WITH [ NO ] DATA</code></span></dt><dd><p>
+ This clause specifies whether or not the materialized view should be
+ populated at creation time. If not, the materialized view will be
+ flagged as unscannable and cannot be queried until <code class="command">REFRESH
+ MATERIALIZED VIEW</code> is used.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.71.7"><h2>Compatibility</h2><p>
+ <code class="command">CREATE MATERIALIZED VIEW</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.71.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW"><span class="refentrytitle">ALTER MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-createtableas.html" title="CREATE TABLE AS"><span class="refentrytitle">CREATE TABLE AS</span></a>, <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a>, <a class="xref" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW"><span class="refentrytitle">DROP MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW"><span class="refentrytitle">REFRESH MATERIALIZED VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createlanguage.html" title="CREATE LANGUAGE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createoperator.html" title="CREATE OPERATOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE LANGUAGE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE OPERATOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createopclass.html b/doc/src/sgml/html/sql-createopclass.html
new file mode 100644
index 0000000..1ab9cc2
--- /dev/null
+++ b/doc/src/sgml/html/sql-createopclass.html
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE OPERATOR CLASS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createoperator.html" title="CREATE OPERATOR" /><link rel="next" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE OPERATOR CLASS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createoperator.html" title="CREATE OPERATOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEOPCLASS"><div class="titlepage"></div><a id="id-1.9.3.73.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE OPERATOR CLASS</span></h2><p>CREATE OPERATOR CLASS — define a new operator class</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE OPERATOR CLASS <em class="replaceable"><code>name</code></em> [ DEFAULT ] FOR TYPE <em class="replaceable"><code>data_type</code></em>
+ USING <em class="replaceable"><code>index_method</code></em> [ FAMILY <em class="replaceable"><code>family_name</code></em> ] AS
+ { OPERATOR <em class="replaceable"><code>strategy_number</code></em> <em class="replaceable"><code>operator_name</code></em> [ ( <em class="replaceable"><code>op_type</code></em>, <em class="replaceable"><code>op_type</code></em> ) ] [ FOR SEARCH | FOR ORDER BY <em class="replaceable"><code>sort_family_name</code></em> ]
+ | FUNCTION <em class="replaceable"><code>support_number</code></em> [ ( <em class="replaceable"><code>op_type</code></em> [ , <em class="replaceable"><code>op_type</code></em> ] ) ] <em class="replaceable"><code>function_name</code></em> ( <em class="replaceable"><code>argument_type</code></em> [, ...] )
+ | STORAGE <em class="replaceable"><code>storage_type</code></em>
+ } [, ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.73.5"><h2>Description</h2><p>
+ <code class="command">CREATE OPERATOR CLASS</code> creates a new operator class.
+ An operator class defines how a particular data type can be used with
+ an index. The operator class specifies that certain operators will fill
+ particular roles or <span class="quote">“<span class="quote">strategies</span>”</span> for this data type and this
+ index method. The operator class also specifies the support functions to
+ be used by
+ the index method when the operator class is selected for an
+ index column. All the operators and functions used by an operator
+ class must be defined before the operator class can be created.
+ </p><p>
+ If a schema name is given then the operator class is created in the
+ specified schema. Otherwise it is created in the current schema.
+ Two operator classes in the same schema can have the same name only if they
+ are for different index methods.
+ </p><p>
+ The user who defines an operator class becomes its owner. Presently,
+ the creating user must be a superuser. (This restriction is made because
+ an erroneous operator class definition could confuse or even crash the
+ server.)
+ </p><p>
+ <code class="command">CREATE OPERATOR CLASS</code> does not presently check
+ whether the operator class definition includes all the operators and
+ functions required by the index method, nor whether the operators and
+ functions form a self-consistent set. It is the user's
+ responsibility to define a valid operator class.
+ </p><p>
+ Related operator classes can be grouped into <em class="firstterm">operator
+ families</em>. To add a new operator class to an existing family,
+ specify the <code class="literal">FAMILY</code> option in <code class="command">CREATE OPERATOR
+ CLASS</code>. Without this option, the new class is placed into
+ a family named the same as the new class (creating that family if
+ it doesn't already exist).
+ </p><p>
+ Refer to <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.73.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the operator class to be created. The name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ If present, the operator class will become the default
+ operator class for its data type. At most one operator class
+ can be the default for a specific data type and index method.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The column data type that this operator class is for.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_method</code></em></span></dt><dd><p>
+ The name of the index method this operator class is for.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>family_name</code></em></span></dt><dd><p>
+ The name of the existing operator family to add this operator class to.
+ If not specified, a family named the same as the operator class is
+ used (creating it, if it doesn't already exist).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>strategy_number</code></em></span></dt><dd><p>
+ The index method's strategy number for an operator
+ associated with the operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>operator_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an operator associated
+ with the operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>op_type</code></em></span></dt><dd><p>
+ In an <code class="literal">OPERATOR</code> clause,
+ the operand data type(s) of the operator, or <code class="literal">NONE</code> to
+ signify a prefix operator. The operand data
+ types can be omitted in the normal case where they are the same
+ as the operator class's data type.
+ </p><p>
+ In a <code class="literal">FUNCTION</code> clause, the operand data type(s) the
+ function is intended to support, if different from
+ the input data type(s) of the function (for B-tree comparison functions
+ and hash functions)
+ or the class's data type (for B-tree sort support functions,
+ B-tree equal image functions, and all functions in GiST,
+ SP-GiST, GIN and BRIN operator classes). These defaults are
+ correct, and so <em class="replaceable"><code>op_type</code></em> need not be specified
+ in <code class="literal">FUNCTION</code> clauses, except for the case of a
+ B-tree sort support function that is meant to support
+ cross-data-type comparisons.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sort_family_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing <code class="literal">btree</code> operator
+ family that describes the sort ordering associated with an ordering
+ operator.
+ </p><p>
+ If neither <code class="literal">FOR SEARCH</code> nor <code class="literal">FOR ORDER BY</code> is
+ specified, <code class="literal">FOR SEARCH</code> is the default.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>support_number</code></em></span></dt><dd><p>
+ The index method's support function number for a
+ function associated with the operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a function that is an
+ index method support function for the operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argument_type</code></em></span></dt><dd><p>
+ The parameter data type(s) of the function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>storage_type</code></em></span></dt><dd><p>
+ The data type actually stored in the index. Normally this is
+ the same as the column data type, but some index methods
+ (currently GiST, GIN, SP-GiST and BRIN) allow it to be different. The
+ <code class="literal">STORAGE</code> clause must be omitted unless the index
+ method allows a different type to be used.
+ If the column <em class="replaceable"><code>data_type</code></em> is specified
+ as <code class="type">anyarray</code>, the <em class="replaceable"><code>storage_type</code></em>
+ can be declared as <code class="type">anyelement</code> to indicate that the index
+ entries are members of the element type belonging to the actual array
+ type that each particular index is created for.
+ </p></dd></dl></div><p>
+ The <code class="literal">OPERATOR</code>, <code class="literal">FUNCTION</code>, and <code class="literal">STORAGE</code>
+ clauses can appear in any order.
+ </p></div><div class="refsect1" id="id-1.9.3.73.7"><h2>Notes</h2><p>
+ Because the index machinery does not check access permissions on functions
+ before using them, including a function or operator in an operator class
+ is tantamount to granting public execute permission on it. This is usually
+ not an issue for the sorts of functions that are useful in an operator
+ class.
+ </p><p>
+ The operators should not be defined by SQL functions. An SQL function
+ is likely to be inlined into the calling query, which will prevent
+ the optimizer from recognizing that the query matches an index.
+ </p><p>
+ Before <span class="productname">PostgreSQL</span> 8.4, the <code class="literal">OPERATOR</code>
+ clause could include a <code class="literal">RECHECK</code> option. This is no longer
+ supported because whether an index operator is <span class="quote">“<span class="quote">lossy</span>”</span> is now
+ determined on-the-fly at run time. This allows efficient handling of
+ cases where an operator might or might not be lossy.
+ </p></div><div class="refsect1" id="id-1.9.3.73.8"><h2>Examples</h2><p>
+ The following example command defines a GiST index operator class
+ for the data type <code class="literal">_int4</code> (array of <code class="type">int4</code>). See the
+ <a class="xref" href="intarray.html" title="F.20. intarray">intarray</a> module for the complete example.
+ </p><pre class="programlisting">
+CREATE OPERATOR CLASS gist__int_ops
+ DEFAULT FOR TYPE _int4 USING gist AS
+ OPERATOR 3 &amp;&amp;,
+ OPERATOR 6 = (anyarray, anyarray),
+ OPERATOR 7 @&gt;,
+ OPERATOR 8 &lt;@,
+ OPERATOR 20 @@ (_int4, query_int),
+ FUNCTION 1 g_int_consistent (internal, _int4, smallint, oid, internal),
+ FUNCTION 2 g_int_union (internal, internal),
+ FUNCTION 3 g_int_compress (internal),
+ FUNCTION 4 g_int_decompress (internal),
+ FUNCTION 5 g_int_penalty (internal, internal, internal),
+ FUNCTION 6 g_int_picksplit (internal, internal),
+ FUNCTION 7 g_int_same (_int4, _int4, internal);
+</pre></div><div class="refsect1" id="id-1.9.3.73.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE OPERATOR CLASS</code> is a
+ <span class="productname">PostgreSQL</span> extension. There is no
+ <code class="command">CREATE OPERATOR CLASS</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.73.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS"><span class="refentrytitle">ALTER OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropopclass.html" title="DROP OPERATOR CLASS"><span class="refentrytitle">DROP OPERATOR CLASS</span></a>, <a class="xref" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY"><span class="refentrytitle">CREATE OPERATOR FAMILY</span></a>, <a class="xref" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY"><span class="refentrytitle">ALTER OPERATOR FAMILY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createoperator.html" title="CREATE OPERATOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE OPERATOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE OPERATOR FAMILY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createoperator.html b/doc/src/sgml/html/sql-createoperator.html
new file mode 100644
index 0000000..a2d0e9b
--- /dev/null
+++ b/doc/src/sgml/html/sql-createoperator.html
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE OPERATOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW" /><link rel="next" href="sql-createopclass.html" title="CREATE OPERATOR CLASS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE OPERATOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createopclass.html" title="CREATE OPERATOR CLASS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEOPERATOR"><div class="titlepage"></div><a id="id-1.9.3.72.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE OPERATOR</span></h2><p>CREATE OPERATOR — define a new operator</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE OPERATOR <em class="replaceable"><code>name</code></em> (
+ {FUNCTION|PROCEDURE} = <em class="replaceable"><code>function_name</code></em>
+ [, LEFTARG = <em class="replaceable"><code>left_type</code></em> ] [, RIGHTARG = <em class="replaceable"><code>right_type</code></em> ]
+ [, COMMUTATOR = <em class="replaceable"><code>com_op</code></em> ] [, NEGATOR = <em class="replaceable"><code>neg_op</code></em> ]
+ [, RESTRICT = <em class="replaceable"><code>res_proc</code></em> ] [, JOIN = <em class="replaceable"><code>join_proc</code></em> ]
+ [, HASHES ] [, MERGES ]
+)
+</pre></div><div class="refsect1" id="id-1.9.3.72.5"><h2>Description</h2><p>
+ <code class="command">CREATE OPERATOR</code> defines a new operator,
+ <em class="replaceable"><code>name</code></em>. The user who
+ defines an operator becomes its owner. If a schema name is given
+ then the operator is created in the specified schema. Otherwise it
+ is created in the current schema.
+ </p><p>
+ The operator name is a sequence of up to <code class="symbol">NAMEDATALEN</code>-1
+ (63 by default) characters from the following list:
+</p><div class="literallayout"><p><br />
++ - * / &lt; &gt; = ~ ! @ # % ^ &amp; | ` ?<br />
+</p></div><p>
+
+ There are a few restrictions on your choice of name:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">--</code> and <code class="literal">/*</code> cannot appear anywhere in an operator name,
+ since they will be taken as the start of a comment.
+ </p></li><li class="listitem"><p>
+ A multicharacter operator name cannot end in <code class="literal">+</code> or
+ <code class="literal">-</code>,
+ unless the name also contains at least one of these characters:
+</p><div class="literallayout"><p><br />
+~ ! @ # % ^ &amp; | ` ?<br />
+</p></div><p>
+ For example, <code class="literal">@-</code> is an allowed operator name,
+ but <code class="literal">*-</code> is not.
+ This restriction allows <span class="productname">PostgreSQL</span> to
+ parse SQL-compliant commands without requiring spaces between tokens.
+ </p></li><li class="listitem"><p>
+ The use of <code class="literal">=&gt;</code> as an operator name is deprecated. It may
+ be disallowed altogether in a future release.
+ </p></li></ul></div><p>
+ </p><p>
+ The operator <code class="literal">!=</code> is mapped to
+ <code class="literal">&lt;&gt;</code> on input, so these two names are always
+ equivalent.
+ </p><p>
+ For binary operators, both <code class="literal">LEFTARG</code> and
+ <code class="literal">RIGHTARG</code> must be defined. For prefix operators only
+ <code class="literal">RIGHTARG</code> should be defined.
+ The <em class="replaceable"><code>function_name</code></em>
+ function must have been previously defined using <code class="command">CREATE
+ FUNCTION</code> and must be defined to accept the correct number
+ of arguments (either one or two) of the indicated types.
+ </p><p>
+ In the syntax of <code class="literal">CREATE OPERATOR</code>, the keywords
+ <code class="literal">FUNCTION</code> and <code class="literal">PROCEDURE</code> are
+ equivalent, but the referenced function must in any case be a function, not
+ a procedure. The use of the keyword <code class="literal">PROCEDURE</code> here is
+ historical and deprecated.
+ </p><p>
+ The other clauses specify optional operator optimization clauses.
+ Their meaning is detailed in <a class="xref" href="xoper-optimization.html" title="38.15. Operator Optimization Information">Section 38.15</a>.
+ </p><p>
+ To be able to create an operator, you must have <code class="literal">USAGE</code>
+ privilege on the argument types and the return type, as well
+ as <code class="literal">EXECUTE</code> privilege on the underlying function. If a
+ commutator or negator operator is specified, you must own these operators.
+ </p></div><div class="refsect1" id="id-1.9.3.72.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the operator to be defined. See above for allowable
+ characters. The name can be schema-qualified, for example
+ <code class="literal">CREATE OPERATOR myschema.+ (...)</code>. If not, then
+ the operator is created in the current schema. Two operators
+ in the same schema can have the same name if they operate on
+ different data types. This is called
+ <em class="firstterm">overloading</em>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ The function used to implement this operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>left_type</code></em></span></dt><dd><p>
+ The data type of the operator's left operand, if any.
+ This option would be omitted for a prefix operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>right_type</code></em></span></dt><dd><p>
+ The data type of the operator's right operand.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>com_op</code></em></span></dt><dd><p>
+ The commutator of this operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>neg_op</code></em></span></dt><dd><p>
+ The negator of this operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>res_proc</code></em></span></dt><dd><p>
+ The restriction selectivity estimator function for this operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>join_proc</code></em></span></dt><dd><p>
+ The join selectivity estimator function for this operator.
+ </p></dd><dt><span class="term"><code class="literal">HASHES</code></span></dt><dd><p>
+ Indicates this operator can support a hash join.
+ </p></dd><dt><span class="term"><code class="literal">MERGES</code></span></dt><dd><p>
+ Indicates this operator can support a merge join.
+ </p></dd></dl></div><p>
+ To give a schema-qualified operator name in <em class="replaceable"><code>com_op</code></em> or the other optional
+ arguments, use the <code class="literal">OPERATOR()</code> syntax, for example:
+</p><pre class="programlisting">
+COMMUTATOR = OPERATOR(myschema.===) ,
+</pre></div><div class="refsect1" id="id-1.9.3.72.7"><h2>Notes</h2><p>
+ Refer to <a class="xref" href="xoper.html" title="38.14. User-Defined Operators">Section 38.14</a> for further information.
+ </p><p>
+ It is not possible to specify an operator's lexical precedence in
+ <code class="command">CREATE OPERATOR</code>, because the parser's precedence behavior
+ is hard-wired. See <a class="xref" href="sql-syntax-lexical.html#SQL-PRECEDENCE" title="4.1.6. Operator Precedence">Section 4.1.6</a> for precedence details.
+ </p><p>
+ The obsolete options <code class="literal">SORT1</code>, <code class="literal">SORT2</code>,
+ <code class="literal">LTCMP</code>, and <code class="literal">GTCMP</code> were formerly used to
+ specify the names of sort operators associated with a merge-joinable
+ operator. This is no longer necessary, since information about
+ associated operators is found by looking at B-tree operator families
+ instead. If one of these options is given, it is ignored except
+ for implicitly setting <code class="literal">MERGES</code> true.
+ </p><p>
+ Use <a class="link" href="sql-dropoperator.html" title="DROP OPERATOR"><code class="command">DROP OPERATOR</code></a> to delete user-defined operators
+ from a database. Use <a class="link" href="sql-alteroperator.html" title="ALTER OPERATOR"><code class="command">ALTER OPERATOR</code></a> to modify operators in a
+ database.
+ </p></div><div class="refsect1" id="id-1.9.3.72.8"><h2>Examples</h2><p>
+ The following command defines a new operator, area-equality, for
+ the data type <code class="type">box</code>:
+</p><pre class="programlisting">
+CREATE OPERATOR === (
+ LEFTARG = box,
+ RIGHTARG = box,
+ FUNCTION = area_equal_function,
+ COMMUTATOR = ===,
+ NEGATOR = !==,
+ RESTRICT = area_restriction_function,
+ JOIN = area_join_function,
+ HASHES, MERGES
+);
+</pre></div><div class="refsect1" id="id-1.9.3.72.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE OPERATOR</code> is a
+ <span class="productname">PostgreSQL</span> extension. There are no
+ provisions for user-defined operators in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.72.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteroperator.html" title="ALTER OPERATOR"><span class="refentrytitle">ALTER OPERATOR</span></a>, <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropoperator.html" title="DROP OPERATOR"><span class="refentrytitle">DROP OPERATOR</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createopclass.html" title="CREATE OPERATOR CLASS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE MATERIALIZED VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE OPERATOR CLASS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createopfamily.html b/doc/src/sgml/html/sql-createopfamily.html
new file mode 100644
index 0000000..37aa080
--- /dev/null
+++ b/doc/src/sgml/html/sql-createopfamily.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE OPERATOR FAMILY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createopclass.html" title="CREATE OPERATOR CLASS" /><link rel="next" href="sql-createpolicy.html" title="CREATE POLICY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE OPERATOR FAMILY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createopclass.html" title="CREATE OPERATOR CLASS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createpolicy.html" title="CREATE POLICY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEOPFAMILY"><div class="titlepage"></div><a id="id-1.9.3.74.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE OPERATOR FAMILY</span></h2><p>CREATE OPERATOR FAMILY — define a new operator family</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE OPERATOR FAMILY <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.74.5"><h2>Description</h2><p>
+ <code class="command">CREATE OPERATOR FAMILY</code> creates a new operator family.
+ An operator family defines a collection of related operator classes,
+ and perhaps some additional operators and support functions that are
+ compatible with these operator classes but not essential for the
+ functioning of any individual index. (Operators and functions that
+ are essential to indexes should be grouped within the relevant operator
+ class, rather than being <span class="quote">“<span class="quote">loose</span>”</span> in the operator family.
+ Typically, single-data-type operators are bound to operator classes,
+ while cross-data-type operators can be loose in an operator family
+ containing operator classes for both data types.)
+ </p><p>
+ The new operator family is initially empty. It should be populated
+ by issuing subsequent <code class="command">CREATE OPERATOR CLASS</code> commands
+ to add contained operator classes, and optionally
+ <code class="command">ALTER OPERATOR FAMILY</code> commands to add <span class="quote">“<span class="quote">loose</span>”</span>
+ operators and their corresponding support functions.
+ </p><p>
+ If a schema name is given then the operator family is created in the
+ specified schema. Otherwise it is created in the current schema.
+ Two operator families in the same schema can have the same name only if they
+ are for different index methods.
+ </p><p>
+ The user who defines an operator family becomes its owner. Presently,
+ the creating user must be a superuser. (This restriction is made because
+ an erroneous operator family definition could confuse or even crash the
+ server.)
+ </p><p>
+ Refer to <a class="xref" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Section 38.16</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.74.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the operator family to be created. The name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_method</code></em></span></dt><dd><p>
+ The name of the index method this operator family is for.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.74.7"><h2>Compatibility</h2><p>
+ <code class="command">CREATE OPERATOR FAMILY</code> is a
+ <span class="productname">PostgreSQL</span> extension. There is no
+ <code class="command">CREATE OPERATOR FAMILY</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.74.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY"><span class="refentrytitle">ALTER OPERATOR FAMILY</span></a>, <a class="xref" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY"><span class="refentrytitle">DROP OPERATOR FAMILY</span></a>, <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS"><span class="refentrytitle">ALTER OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropopclass.html" title="DROP OPERATOR CLASS"><span class="refentrytitle">DROP OPERATOR CLASS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createopclass.html" title="CREATE OPERATOR CLASS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createpolicy.html" title="CREATE POLICY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE OPERATOR CLASS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE POLICY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createpolicy.html b/doc/src/sgml/html/sql-createpolicy.html
new file mode 100644
index 0000000..9977dcd
--- /dev/null
+++ b/doc/src/sgml/html/sql-createpolicy.html
@@ -0,0 +1,361 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE POLICY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY" /><link rel="next" href="sql-createprocedure.html" title="CREATE PROCEDURE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE POLICY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createprocedure.html" title="CREATE PROCEDURE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEPOLICY"><div class="titlepage"></div><a id="id-1.9.3.75.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE POLICY</span></h2><p>CREATE POLICY — define a new row-level security policy for a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE POLICY <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em>
+ [ AS { PERMISSIVE | RESTRICTIVE } ]
+ [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+ [ TO { <em class="replaceable"><code>role_name</code></em> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
+ [ USING ( <em class="replaceable"><code>using_expression</code></em> ) ]
+ [ WITH CHECK ( <em class="replaceable"><code>check_expression</code></em> ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.75.5"><h2>Description</h2><p>
+ The <code class="command">CREATE POLICY</code> command defines a new row-level
+ security policy for a table. Note that row-level security must be
+ enabled on the table (using <code class="command">ALTER TABLE ... ENABLE ROW LEVEL
+ SECURITY</code>) in order for created policies to be applied.
+ </p><p>
+ A policy grants the permission to select, insert, update, or delete rows
+ that match the relevant policy expression. Existing table rows are
+ checked against the expression specified in <code class="literal">USING</code>,
+ while new rows that would be created via <code class="literal">INSERT</code>
+ or <code class="literal">UPDATE</code> are checked against the expression specified
+ in <code class="literal">WITH CHECK</code>. When a <code class="literal">USING</code>
+ expression returns true for a given row then that row is visible to the
+ user, while if false or null is returned then the row is not visible.
+ When a <code class="literal">WITH CHECK</code> expression returns true for a row
+ then that row is inserted or updated, while if false or null is returned
+ then an error occurs.
+ </p><p>
+ For <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">MERGE</code> statements,
+ <code class="literal">WITH CHECK</code> expressions are enforced after
+ <code class="literal">BEFORE</code> triggers are fired, and before any actual data
+ modifications are made. Thus a <code class="literal">BEFORE ROW</code> trigger may
+ modify the data to be inserted, affecting the result of the security
+ policy check. <code class="literal">WITH CHECK</code> expressions are enforced
+ before any other constraints.
+ </p><p>
+ Policy names are per-table. Therefore, one policy name can be used for many
+ different tables and have a definition for each table which is appropriate to
+ that table.
+ </p><p>
+ Policies can be applied for specific commands or for specific roles. The
+ default for newly created policies is that they apply for all commands and
+ roles, unless otherwise specified. Multiple policies may apply to a single
+ command; see below for more details.
+ <a class="xref" href="sql-createpolicy.html#SQL-CREATEPOLICY-SUMMARY" title="Table 287. Policies Applied by Command Type">Table 287</a> summarizes how the different types
+ of policy apply to specific commands.
+ </p><p>
+ For policies that can have both <code class="literal">USING</code>
+ and <code class="literal">WITH CHECK</code> expressions (<code class="literal">ALL</code>
+ and <code class="literal">UPDATE</code>), if no <code class="literal">WITH CHECK</code>
+ expression is defined, then the <code class="literal">USING</code> expression will be
+ used both to determine which rows are visible (normal
+ <code class="literal">USING</code> case) and which new rows will be allowed to be
+ added (<code class="literal">WITH CHECK</code> case).
+ </p><p>
+ If row-level security is enabled for a table, but no applicable policies
+ exist, a <span class="quote">“<span class="quote">default deny</span>”</span> policy is assumed, so that no rows will
+ be visible or updatable.
+ </p></div><div class="refsect1" id="id-1.9.3.75.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the policy to be created. This must be distinct from the
+ name of any other policy for the table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table the
+ policy applies to.
+ </p></dd><dt><span class="term"><code class="literal">PERMISSIVE</code></span></dt><dd><p>
+ Specify that the policy is to be created as a permissive policy.
+ All permissive policies which are applicable to a given query will
+ be combined together using the Boolean <span class="quote">“<span class="quote">OR</span>”</span> operator. By creating
+ permissive policies, administrators can add to the set of records
+ which can be accessed. Policies are permissive by default.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICTIVE</code></span></dt><dd><p>
+ Specify that the policy is to be created as a restrictive policy.
+ All restrictive policies which are applicable to a given query will
+ be combined together using the Boolean <span class="quote">“<span class="quote">AND</span>”</span> operator. By creating
+ restrictive policies, administrators can reduce the set of records
+ which can be accessed as all restrictive policies must be passed for
+ each record.
+ </p><p>
+ Note that there needs to be at least one permissive policy to grant
+ access to records before restrictive policies can be usefully used to
+ reduce that access. If only restrictive policies exist, then no records
+ will be accessible. When a mix of permissive and restrictive policies
+ are present, a record is only accessible if at least one of the
+ permissive policies passes, in addition to all the restrictive
+ policies.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>command</code></em></span></dt><dd><p>
+ The command to which the policy applies. Valid options are
+ <code class="command">ALL</code>, <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ and <code class="command">DELETE</code>.
+ <code class="command">ALL</code> is the default.
+ See below for specifics regarding how these are applied.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The role(s) to which the policy is to be applied. The default is
+ <code class="literal">PUBLIC</code>, which will apply the policy to all roles.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>using_expression</code></em></span></dt><dd><p>
+ Any <acronym class="acronym">SQL</acronym> conditional expression (returning
+ <code class="type">boolean</code>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be added
+ to queries that refer to the table if row-level security is enabled.
+ Rows for which the expression returns true will be visible. Any
+ rows for which the expression returns false or null will not be
+ visible to the user (in a <code class="command">SELECT</code>), and will not be
+ available for modification (in an <code class="command">UPDATE</code>
+ or <code class="command">DELETE</code>). Such rows are silently suppressed; no error
+ is reported.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>check_expression</code></em></span></dt><dd><p>
+ Any <acronym class="acronym">SQL</acronym> conditional expression (returning
+ <code class="type">boolean</code>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be used in
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> queries against
+ the table if row-level security is enabled. Only rows for which the
+ expression evaluates to true will be allowed. An error will be thrown
+ if the expression evaluates to false or null for any of the records
+ inserted or any of the records that result from the update. Note that
+ the <em class="replaceable"><code>check_expression</code></em> is
+ evaluated against the proposed new contents of the row, not the
+ original contents.
+ </p></dd></dl></div><div class="refsect2" id="id-1.9.3.75.6.3"><h3>Per-Command Policies</h3><div class="variablelist"><dl class="variablelist"><dt id="SQL-CREATEPOLICY-ALL"><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Using <code class="literal">ALL</code> for a policy means that it will apply
+ to all commands, regardless of the type of command. If an
+ <code class="literal">ALL</code> policy exists and more specific policies
+ exist, then both the <code class="literal">ALL</code> policy and the more
+ specific policy (or policies) will be applied.
+ Additionally, <code class="literal">ALL</code> policies will be applied to
+ both the selection side of a query and the modification side, using
+ the <code class="literal">USING</code> expression for both cases if only
+ a <code class="literal">USING</code> expression has been defined.
+ </p><p>
+ As an example, if an <code class="literal">UPDATE</code> is issued, then the
+ <code class="literal">ALL</code> policy will be applicable both to what the
+ <code class="literal">UPDATE</code> will be able to select as rows to be
+ updated (applying the <code class="literal">USING</code> expression),
+ and to the resulting updated rows, to check if they are permitted
+ to be added to the table (applying the <code class="literal">WITH CHECK</code>
+ expression, if defined, and the <code class="literal">USING</code> expression
+ otherwise). If an <code class="command">INSERT</code>
+ or <code class="command">UPDATE</code> command attempts to add rows to the
+ table that do not pass the <code class="literal">ALL</code>
+ policy's <code class="literal">WITH CHECK</code> expression, the entire
+ command will be aborted.
+ </p></dd><dt id="SQL-CREATEPOLICY-SELECT"><span class="term"><code class="literal">SELECT</code></span></dt><dd><p>
+ Using <code class="literal">SELECT</code> for a policy means that it will apply
+ to <code class="literal">SELECT</code> queries and whenever
+ <code class="literal">SELECT</code> permissions are required on the relation the
+ policy is defined for. The result is that only those records from the
+ relation that pass the <code class="literal">SELECT</code> policy will be
+ returned during a <code class="literal">SELECT</code> query, and that queries
+ that require <code class="literal">SELECT</code> permissions, such as
+ <code class="literal">UPDATE</code>, will also only see those records
+ that are allowed by the <code class="literal">SELECT</code> policy.
+ A <code class="literal">SELECT</code> policy cannot have a <code class="literal">WITH
+ CHECK</code> expression, as it only applies in cases where
+ records are being retrieved from the relation.
+ </p></dd><dt id="SQL-CREATEPOLICY-INSERT"><span class="term"><code class="literal">INSERT</code></span></dt><dd><p>
+ Using <code class="literal">INSERT</code> for a policy means that it will apply
+ to <code class="literal">INSERT</code> commands and <code class="literal">MERGE</code>
+ commands that contain <code class="literal">INSERT</code> actions.
+ Rows being inserted that do
+ not pass this policy will result in a policy violation error, and the
+ entire <code class="literal">INSERT</code> command will be aborted.
+ An <code class="literal">INSERT</code> policy cannot have
+ a <code class="literal">USING</code> expression, as it only applies in cases
+ where records are being added to the relation.
+ </p><p>
+ Note that <code class="literal">INSERT</code> with <code class="literal">ON CONFLICT DO
+ UPDATE</code> checks <code class="literal">INSERT</code> policies'
+ <code class="literal">WITH CHECK</code> expressions only for rows appended
+ to the relation by the <code class="literal">INSERT</code> path.
+ </p></dd><dt id="SQL-CREATEPOLICY-UPDATE"><span class="term"><code class="literal">UPDATE</code></span></dt><dd><p>
+ Using <code class="literal">UPDATE</code> for a policy means that it will apply
+ to <code class="literal">UPDATE</code>, <code class="literal">SELECT FOR UPDATE</code>
+ and <code class="literal">SELECT FOR SHARE</code> commands, as well as
+ auxiliary <code class="literal">ON CONFLICT DO UPDATE</code> clauses of
+ <code class="literal">INSERT</code> commands.
+ <code class="literal">MERGE</code> commands containing <code class="literal">UPDATE</code>
+ actions are affected as well. Since <code class="literal">UPDATE</code>
+ involves pulling an existing record and replacing it with a new
+ modified record, <code class="literal">UPDATE</code>
+ policies accept both a <code class="literal">USING</code> expression and
+ a <code class="literal">WITH CHECK</code> expression.
+ The <code class="literal">USING</code> expression determines which records
+ the <code class="literal">UPDATE</code> command will see to operate against,
+ while the <code class="literal">WITH CHECK</code> expression defines which
+ modified rows are allowed to be stored back into the relation.
+ </p><p>
+ Any rows whose updated values do not pass the
+ <code class="literal">WITH CHECK</code> expression will cause an error, and the
+ entire command will be aborted. If only a <code class="literal">USING</code>
+ clause is specified, then that clause will be used for both
+ <code class="literal">USING</code> and <code class="literal">WITH CHECK</code> cases.
+ </p><p>
+ Typically an <code class="literal">UPDATE</code> command also needs to read
+ data from columns in the relation being updated (e.g., in a
+ <code class="literal">WHERE</code> clause or a <code class="literal">RETURNING</code>
+ clause, or in an expression on the right hand side of the
+ <code class="literal">SET</code> clause). In this case,
+ <code class="literal">SELECT</code> rights are also required on the relation
+ being updated, and the appropriate <code class="literal">SELECT</code> or
+ <code class="literal">ALL</code> policies will be applied in addition to
+ the <code class="literal">UPDATE</code> policies. Thus the user must have
+ access to the row(s) being updated through a <code class="literal">SELECT</code>
+ or <code class="literal">ALL</code> policy in addition to being granted
+ permission to update the row(s) via an <code class="literal">UPDATE</code>
+ or <code class="literal">ALL</code> policy.
+ </p><p>
+ When an <code class="literal">INSERT</code> command has an auxiliary
+ <code class="literal">ON CONFLICT DO UPDATE</code> clause, if the
+ <code class="literal">UPDATE</code> path is taken, the row to be updated is
+ first checked against the <code class="literal">USING</code> expressions of
+ any <code class="literal">UPDATE</code> policies, and then the new updated row
+ is checked against the <code class="literal">WITH CHECK</code> expressions.
+ Note, however, that unlike a standalone <code class="literal">UPDATE</code>
+ command, if the existing row does not pass the
+ <code class="literal">USING</code> expressions, an error will be thrown (the
+ <code class="literal">UPDATE</code> path will <span class="emphasis"><em>never</em></span> be silently
+ avoided).
+ </p></dd><dt id="SQL-CREATEPOLICY-DELETE"><span class="term"><code class="literal">DELETE</code></span></dt><dd><p>
+ Using <code class="literal">DELETE</code> for a policy means that it will apply
+ to <code class="literal">DELETE</code> commands. Only rows that pass this
+ policy will be seen by a <code class="literal">DELETE</code> command. There can
+ be rows that are visible through a <code class="literal">SELECT</code> that are
+ not available for deletion, if they do not pass the
+ <code class="literal">USING</code> expression for
+ the <code class="literal">DELETE</code> policy.
+ </p><p>
+ In most cases a <code class="literal">DELETE</code> command also needs to read
+ data from columns in the relation that it is deleting from (e.g.,
+ in a <code class="literal">WHERE</code> clause or a
+ <code class="literal">RETURNING</code> clause). In this case,
+ <code class="literal">SELECT</code> rights are also required on the relation,
+ and the appropriate <code class="literal">SELECT</code> or
+ <code class="literal">ALL</code> policies will be applied in addition to
+ the <code class="literal">DELETE</code> policies. Thus the user must have
+ access to the row(s) being deleted through a <code class="literal">SELECT</code>
+ or <code class="literal">ALL</code> policy in addition to being granted
+ permission to delete the row(s) via a <code class="literal">DELETE</code> or
+ <code class="literal">ALL</code> policy.
+ </p><p>
+ A <code class="literal">DELETE</code> policy cannot have a <code class="literal">WITH
+ CHECK</code> expression, as it only applies in cases where
+ records are being deleted from the relation, so that there is no
+ new row to check.
+ </p></dd></dl></div><div class="table" id="SQL-CREATEPOLICY-SUMMARY"><p class="title"><strong>Table 287. Policies Applied by Command Type</strong></p><div class="table-contents"><table class="table" summary="Policies Applied by Command Type" border="1"><colgroup><col /><col /><col /><col class="update-using" /><col class="update-check" /><col /></colgroup><thead><tr><th rowspan="2">Command</th><th><code class="literal">SELECT/ALL policy</code></th><th><code class="literal">INSERT/ALL policy</code></th><th colspan="2"><code class="literal">UPDATE/ALL policy</code></th><th><code class="literal">DELETE/ALL policy</code></th></tr><tr><th><code class="literal">USING expression</code></th><th><code class="literal">WITH CHECK expression</code></th><th><code class="literal">USING expression</code></th><th><code class="literal">WITH CHECK expression</code></th><th><code class="literal">USING expression</code></th></tr></thead><tbody><tr><td><code class="command">SELECT</code></td><td>Existing row</td><td>—</td><td>—</td><td>—</td><td>—</td></tr><tr><td><code class="command">SELECT FOR UPDATE/SHARE</code></td><td>Existing row</td><td>—</td><td>Existing row</td><td>—</td><td>—</td></tr><tr><td><code class="command">INSERT</code> / <code class="command">MERGE ... THEN INSERT</code></td><td>—</td><td>New row</td><td>—</td><td>—</td><td>—</td></tr><tr><td><code class="command">INSERT ... RETURNING</code></td><td>
+ New row <a href="#ftn.RLS-SELECT-PRIV" class="footnote"><sup class="footnote" id="RLS-SELECT-PRIV">[a]</sup></a>
+ </td><td>New row</td><td>—</td><td>—</td><td>—</td></tr><tr><td><code class="command">UPDATE</code> / <code class="command">MERGE ... THEN UPDATE</code></td><td>
+ Existing &amp; new rows <a href="sql-createpolicy.html#ftn.RLS-SELECT-PRIV" class="footnoteref"><sup class="footnoteref">[a]</sup></a>
+ </td><td>—</td><td>Existing row</td><td>New row</td><td>—</td></tr><tr><td><code class="command">DELETE</code></td><td>
+ Existing row <a href="sql-createpolicy.html#ftn.RLS-SELECT-PRIV" class="footnoteref"><sup class="footnoteref">[a]</sup></a>
+ </td><td>—</td><td>—</td><td>—</td><td>Existing row</td></tr><tr><td><code class="command">ON CONFLICT DO UPDATE</code></td><td>Existing &amp; new rows</td><td>—</td><td>Existing row</td><td>New row</td><td>—</td></tr></tbody><tbody class="footnotes"><tr><td colspan="6"><div id="ftn.RLS-SELECT-PRIV" class="footnote"><p><a href="#RLS-SELECT-PRIV" class="para"><sup class="para">[a] </sup></a>
+ If read access is required to the existing or new row (for example,
+ a <code class="literal">WHERE</code> or <code class="literal">RETURNING</code> clause
+ that refers to columns from the relation).
+ </p></div></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="refsect2" id="id-1.9.3.75.6.4"><h3>Application of Multiple Policies</h3><p>
+ When multiple policies of different command types apply to the same command
+ (for example, <code class="literal">SELECT</code> and <code class="literal">UPDATE</code>
+ policies applied to an <code class="literal">UPDATE</code> command), then the user
+ must have both types of permissions (for example, permission to select rows
+ from the relation as well as permission to update them). Thus the
+ expressions for one type of policy are combined with the expressions for
+ the other type of policy using the <code class="literal">AND</code> operator.
+ </p><p>
+ When multiple policies of the same command type apply to the same command,
+ then there must be at least one <code class="literal">PERMISSIVE</code> policy
+ granting access to the relation, and all of the
+ <code class="literal">RESTRICTIVE</code> policies must pass. Thus all the
+ <code class="literal">PERMISSIVE</code> policy expressions are combined using
+ <code class="literal">OR</code>, all the <code class="literal">RESTRICTIVE</code> policy
+ expressions are combined using <code class="literal">AND</code>, and the results are
+ combined using <code class="literal">AND</code>. If there are no
+ <code class="literal">PERMISSIVE</code> policies, then access is denied.
+ </p><p>
+ Note that, for the purposes of combining multiple policies,
+ <code class="literal">ALL</code> policies are treated as having the same type as
+ whichever other type of policy is being applied.
+ </p><p>
+ For example, in an <code class="literal">UPDATE</code> command requiring both
+ <code class="literal">SELECT</code> and <code class="literal">UPDATE</code> permissions, if
+ there are multiple applicable policies of each type, they will be combined
+ as follows:
+
+</p><pre class="programlisting">
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 1
+AND
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE SELECT/ALL policy 2
+AND
+...
+AND
+(
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 1
+ OR
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE SELECT/ALL policy 2
+ OR
+ ...
+)
+AND
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 1
+AND
+<em class="replaceable"><code>expression</code></em> from RESTRICTIVE UPDATE/ALL policy 2
+AND
+...
+AND
+(
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 1
+ OR
+ <em class="replaceable"><code>expression</code></em> from PERMISSIVE UPDATE/ALL policy 2
+ OR
+ ...
+)
+</pre></div></div><div class="refsect1" id="id-1.9.3.75.7"><h2>Notes</h2><p>
+ You must be the owner of a table to create or change policies for it.
+ </p><p>
+ While policies will be applied for explicit queries against tables
+ in the database, they are not applied when the system is performing internal
+ referential integrity checks or validating constraints. This means there are
+ indirect ways to determine that a given value exists. An example of this is
+ attempting to insert a duplicate value into a column that is a primary key
+ or has a unique constraint. If the insert fails then the user can infer that
+ the value already exists. (This example assumes that the user is permitted by
+ policy to insert records which they are not allowed to see.) Another example
+ is where a user is allowed to insert into a table which references another,
+ otherwise hidden table. Existence can be determined by the user inserting
+ values into the referencing table, where success would indicate that the
+ value exists in the referenced table. These issues can be addressed by
+ carefully crafting policies to prevent users from being able to insert,
+ delete, or update records at all which might possibly indicate a value they
+ are not otherwise able to see, or by using generated values (e.g., surrogate
+ keys) instead of keys with external meanings.
+ </p><p>
+ Generally, the system will enforce filter conditions imposed using
+ security policies prior to qualifications that appear in user queries,
+ in order to prevent inadvertent exposure of the protected data to
+ user-defined functions which might not be trustworthy. However,
+ functions and operators marked by the system (or the system
+ administrator) as <code class="literal">LEAKPROOF</code> may be evaluated before
+ policy expressions, as they are assumed to be trustworthy.
+ </p><p>
+ Since policy expressions
+ are added to the user's query directly, they will be run with the rights of
+ the user running the overall query. Therefore, users who are using a given
+ policy must be able to access any tables or functions referenced in the
+ expression or they will simply receive a permission denied error when
+ attempting to query the table that has row-level security enabled.
+ This does not change how views
+ work, however. As with normal queries and views, permission checks and
+ policies for the tables which are referenced by a view will use the view
+ owner's rights and any policies which apply to the view owner, except if
+ the view is defined using the <code class="literal">security_invoker</code> option
+ (see <a class="link" href="sql-createview.html" title="CREATE VIEW"><code class="command">CREATE VIEW</code></a>).
+ </p><p>
+ No separate policy exists for <code class="command">MERGE</code>. Instead, the policies
+ defined for <code class="command">SELECT</code>, <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, and <code class="command">DELETE</code> are applied
+ while executing <code class="command">MERGE</code>, depending on the actions that are
+ performed.
+ </p><p>
+ Additional discussion and practical examples can be found
+ in <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.75.8"><h2>Compatibility</h2><p>
+ <code class="command">CREATE POLICY</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.75.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterpolicy.html" title="ALTER POLICY"><span class="refentrytitle">ALTER POLICY</span></a>, <a class="xref" href="sql-droppolicy.html" title="DROP POLICY"><span class="refentrytitle">DROP POLICY</span></a>, <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createprocedure.html" title="CREATE PROCEDURE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE OPERATOR FAMILY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE PROCEDURE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createprocedure.html b/doc/src/sgml/html/sql-createprocedure.html
new file mode 100644
index 0000000..9247be1
--- /dev/null
+++ b/doc/src/sgml/html/sql-createprocedure.html
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE PROCEDURE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createpolicy.html" title="CREATE POLICY" /><link rel="next" href="sql-createpublication.html" title="CREATE PUBLICATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE PROCEDURE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createpolicy.html" title="CREATE POLICY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createpublication.html" title="CREATE PUBLICATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEPROCEDURE"><div class="titlepage"></div><a id="id-1.9.3.76.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE PROCEDURE</span></h2><p>CREATE PROCEDURE — define a new procedure</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] PROCEDURE
+ <em class="replaceable"><code>name</code></em> ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ { DEFAULT | = } <em class="replaceable"><code>default_expr</code></em> ] [, ...] ] )
+ { LANGUAGE <em class="replaceable"><code>lang_name</code></em>
+ | TRANSFORM { FOR TYPE <em class="replaceable"><code>type_name</code></em> } [, ... ]
+ | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ | SET <em class="replaceable"><code>configuration_parameter</code></em> { TO <em class="replaceable"><code>value</code></em> | = <em class="replaceable"><code>value</code></em> | FROM CURRENT }
+ | AS '<em class="replaceable"><code>definition</code></em>'
+ | AS '<em class="replaceable"><code>obj_file</code></em>', '<em class="replaceable"><code>link_symbol</code></em>'
+ | <em class="replaceable"><code>sql_body</code></em>
+ } ...
+</pre></div><div class="refsect1" id="SQL-CREATEPROCEDURE-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE PROCEDURE</code> defines a new procedure.
+ <code class="command">CREATE OR REPLACE PROCEDURE</code> will either create a
+ new procedure, or replace an existing definition.
+ To be able to define a procedure, the user must have the
+ <code class="literal">USAGE</code> privilege on the language.
+ </p><p>
+ If a schema name is included, then the procedure is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The name of the new procedure must not match any existing procedure or function
+ with the same input argument types in the same schema. However,
+ procedures and functions of different argument types can share a name (this is
+ called <em class="firstterm">overloading</em>).
+ </p><p>
+ To replace the current definition of an existing procedure, use
+ <code class="command">CREATE OR REPLACE PROCEDURE</code>. It is not possible
+ to change the name or argument types of a procedure this way (if you
+ tried, you would actually be creating a new, distinct procedure).
+ </p><p>
+ When <code class="command">CREATE OR REPLACE PROCEDURE</code> is used to replace an
+ existing procedure, the ownership and permissions of the procedure
+ do not change. All other procedure properties are assigned the
+ values specified or implied in the command. You must own the procedure
+ to replace it (this includes being a member of the owning role).
+ </p><p>
+ The user that creates the procedure becomes the owner of the procedure.
+ </p><p>
+ To be able to create a procedure, you must have <code class="literal">USAGE</code>
+ privilege on the argument types.
+ </p><p>
+ Refer to <a class="xref" href="xproc.html" title="38.4. User-Defined Procedures">Section 38.4</a> for further information on writing
+ procedures.
+ </p></div><div class="refsect1" id="id-1.9.3.76.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the procedure to create.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>. If omitted,
+ the default is <code class="literal">IN</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type(s) of the procedure's arguments (optionally
+ schema-qualified), if any. The argument types can be base, composite,
+ or domain types, or can reference the type of a table column.
+ </p><p>
+ Depending on the implementation language it might also be allowed
+ to specify <span class="quote">“<span class="quote">pseudo-types</span>”</span> such as <code class="type">cstring</code>.
+ Pseudo-types indicate that the actual argument type is either
+ incompletely specified, or outside the set of ordinary SQL data types.
+ </p><p>
+ The type of a column is referenced by writing
+ <code class="literal"><em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em>%TYPE</code>.
+ Using this feature can sometimes help make a procedure independent of
+ changes to the definition of a table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>default_expr</code></em></span></dt><dd><p>
+ An expression to be used as default value if the parameter is
+ not specified. The expression has to be coercible to the
+ argument type of the parameter.
+ All input parameters following a
+ parameter with a default value must have default values as well.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the language that the procedure is implemented in.
+ It can be <code class="literal">sql</code>, <code class="literal">c</code>,
+ <code class="literal">internal</code>, or the name of a user-defined
+ procedural language, e.g., <code class="literal">plpgsql</code>. The default is
+ <code class="literal">sql</code> if <em class="replaceable"><code>sql_body</code></em> is specified. Enclosing the
+ name in single quotes is deprecated and requires matching case.
+ </p></dd><dt><span class="term"><code class="literal">TRANSFORM { FOR TYPE <em class="replaceable"><code>type_name</code></em> } [, ... ] }</code></span></dt><dd><p>
+ Lists which transforms a call to the procedure should apply. Transforms
+ convert between SQL types and language-specific data types;
+ see <a class="xref" href="sql-createtransform.html" title="CREATE TRANSFORM"><span class="refentrytitle">CREATE TRANSFORM</span></a>. Procedural language
+ implementations usually have hardcoded knowledge of the built-in types,
+ so those don't need to be listed here. If a procedural language
+ implementation does not know how to handle a type and no transform is
+ supplied, it will fall back to a default behavior for converting data
+ types, but this depends on the implementation.
+ </p></dd><dt><span class="term"><code class="literal">[<span class="optional">EXTERNAL</span>] SECURITY INVOKER</code><br /></span><span class="term"><code class="literal">[<span class="optional">EXTERNAL</span>] SECURITY DEFINER</code></span></dt><dd><p><code class="literal">SECURITY INVOKER</code> indicates that the procedure
+ is to be executed with the privileges of the user that calls it.
+ That is the default. <code class="literal">SECURITY DEFINER</code>
+ specifies that the procedure is to be executed with the
+ privileges of the user that owns it.
+ </p><p>
+ The key word <code class="literal">EXTERNAL</code> is allowed for SQL
+ conformance, but it is optional since, unlike in SQL, this feature
+ applies to all procedures not only external ones.
+ </p><p>
+ A <code class="literal">SECURITY DEFINER</code> procedure cannot execute
+ transaction control statements (for example, <code class="command">COMMIT</code>
+ and <code class="command">ROLLBACK</code>, depending on the language).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em><br /></span><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ The <code class="literal">SET</code> clause causes the specified configuration
+ parameter to be set to the specified value when the procedure is
+ entered, and then restored to its prior value when the procedure exits.
+ <code class="literal">SET FROM CURRENT</code> saves the value of the parameter that
+ is current when <code class="command">CREATE PROCEDURE</code> is executed as the value
+ to be applied when the procedure is entered.
+ </p><p>
+ If a <code class="literal">SET</code> clause is attached to a procedure, then
+ the effects of a <code class="command">SET LOCAL</code> command executed inside the
+ procedure for the same variable are restricted to the procedure: the
+ configuration parameter's prior value is still restored at procedure exit.
+ However, an ordinary
+ <code class="command">SET</code> command (without <code class="literal">LOCAL</code>) overrides the
+ <code class="literal">SET</code> clause, much as it would do for a previous <code class="command">SET
+ LOCAL</code> command: the effects of such a command will persist after
+ procedure exit, unless the current transaction is rolled back.
+ </p><p>
+ If a <code class="literal">SET</code> clause is attached to a procedure, then
+ that procedure cannot execute transaction control statements (for
+ example, <code class="command">COMMIT</code> and <code class="command">ROLLBACK</code>,
+ depending on the language).
+ </p><p>
+ See <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> and
+ <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ for more information about allowed parameter names and values.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>definition</code></em></span></dt><dd><p>
+ A string constant defining the procedure; the meaning depends on the
+ language. It can be an internal procedure name, the path to an
+ object file, an SQL command, or text in a procedural language.
+ </p><p>
+ It is often helpful to use dollar quoting (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>) to write the procedure definition
+ string, rather than the normal single quote syntax. Without dollar
+ quoting, any single quotes or backslashes in the procedure definition must
+ be escaped by doubling them.
+ </p></dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>obj_file</code></em>, <em class="replaceable"><code>link_symbol</code></em></code></span></dt><dd><p>
+ This form of the <code class="literal">AS</code> clause is used for
+ dynamically loadable C language procedures when the procedure name
+ in the C language source code is not the same as the name of
+ the SQL procedure. The string <em class="replaceable"><code>obj_file</code></em> is the name of the shared
+ library file containing the compiled C procedure, and is interpreted
+ as for the <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command. The string
+ <em class="replaceable"><code>link_symbol</code></em> is the
+ procedure's link symbol, that is, the name of the procedure in the C
+ language source code. If the link symbol is omitted, it is assumed
+ to be the same as the name of the SQL procedure being defined.
+ </p><p>
+ When repeated <code class="command">CREATE PROCEDURE</code> calls refer to
+ the same object file, the file is only loaded once per session.
+ To unload and
+ reload the file (perhaps during development), start a new session.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sql_body</code></em></span></dt><dd><p>
+ The body of a <code class="literal">LANGUAGE SQL</code> procedure. This should
+ be a block
+</p><pre class="programlisting">
+BEGIN ATOMIC
+ <em class="replaceable"><code>statement</code></em>;
+ <em class="replaceable"><code>statement</code></em>;
+ ...
+ <em class="replaceable"><code>statement</code></em>;
+END
+</pre><p>
+ </p><p>
+ This is similar to writing the text of the procedure body as a string
+ constant (see <em class="replaceable"><code>definition</code></em> above), but there
+ are some differences: This form only works for <code class="literal">LANGUAGE
+ SQL</code>, the string constant form works for all languages. This
+ form is parsed at procedure definition time, the string constant form is
+ parsed at execution time; therefore this form cannot support
+ polymorphic argument types and other constructs that are not resolvable
+ at procedure definition time. This form tracks dependencies between the
+ procedure and objects used in the procedure body, so <code class="literal">DROP
+ ... CASCADE</code> will work correctly, whereas the form using
+ string literals may leave dangling procedures. Finally, this form is
+ more compatible with the SQL standard and other SQL implementations.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATEPROCEDURE-NOTES"><h2>Notes</h2><p>
+ See <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a> for more details on function
+ creation that also apply to procedures.
+ </p><p>
+ Use <a class="xref" href="sql-call.html" title="CALL"><span class="refentrytitle">CALL</span></a> to execute a procedure.
+ </p></div><div class="refsect1" id="SQL-CREATEPROCEDURE-EXAMPLES"><h2>Examples</h2><p>
+</p><pre class="programlisting">
+CREATE PROCEDURE insert_data(a integer, b integer)
+LANGUAGE SQL
+AS $$
+INSERT INTO tbl VALUES (a);
+INSERT INTO tbl VALUES (b);
+$$;
+</pre><p>
+ or
+</p><pre class="programlisting">
+CREATE PROCEDURE insert_data(a integer, b integer)
+LANGUAGE SQL
+BEGIN ATOMIC
+ INSERT INTO tbl VALUES (a);
+ INSERT INTO tbl VALUES (b);
+END;
+</pre><p>
+ and call like this:
+</p><pre class="programlisting">
+CALL insert_data(1, 2);
+</pre></div><div class="refsect1" id="SQL-CREATEPROCEDURE-COMPAT"><h2>Compatibility</h2><p>
+ A <code class="command">CREATE PROCEDURE</code> command is defined in the SQL
+ standard. The <span class="productname">PostgreSQL</span> implementation can be
+ used in a compatible way but has many extensions. For details see also
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.76.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterprocedure.html" title="ALTER PROCEDURE"><span class="refentrytitle">ALTER PROCEDURE</span></a>, <a class="xref" href="sql-dropprocedure.html" title="DROP PROCEDURE"><span class="refentrytitle">DROP PROCEDURE</span></a>, <a class="xref" href="sql-call.html" title="CALL"><span class="refentrytitle">CALL</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createpolicy.html" title="CREATE POLICY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createpublication.html" title="CREATE PUBLICATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE POLICY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE PUBLICATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createpublication.html b/doc/src/sgml/html/sql-createpublication.html
new file mode 100644
index 0000000..d205ff4
--- /dev/null
+++ b/doc/src/sgml/html/sql-createpublication.html
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE PUBLICATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createprocedure.html" title="CREATE PROCEDURE" /><link rel="next" href="sql-createrole.html" title="CREATE ROLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE PUBLICATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createprocedure.html" title="CREATE PROCEDURE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createrole.html" title="CREATE ROLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEPUBLICATION"><div class="titlepage"></div><a id="id-1.9.3.77.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE PUBLICATION</span></h2><p>CREATE PUBLICATION — define a new publication</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE PUBLICATION <em class="replaceable"><code>name</code></em>
+ [ FOR ALL TABLES
+ | FOR <em class="replaceable"><code>publication_object</code></em> [, ... ] ]
+ [ WITH ( <em class="replaceable"><code>publication_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+
+<span class="phrase">where <em class="replaceable"><code>publication_object</code></em> is one of:</span>
+
+ TABLE [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ * ] [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ] [ WHERE ( <em class="replaceable"><code>expression</code></em> ) ] [, ... ]
+ TABLES IN SCHEMA { <em class="replaceable"><code>schema_name</code></em> | CURRENT_SCHEMA } [, ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.77.5"><h2>Description</h2><p>
+ <code class="command">CREATE PUBLICATION</code> adds a new publication
+ into the current database. The publication name must be distinct from
+ the name of any existing publication in the current database.
+ </p><p>
+ A publication is essentially a group of tables whose data changes are
+ intended to be replicated through logical replication. See
+ <a class="xref" href="logical-replication-publication.html" title="31.1. Publication">Section 31.1</a> for details about how
+ publications fit into the logical replication setup.
+ </p></div><div class="refsect1" id="id-1.9.3.77.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the new publication.
+ </p></dd><dt><span class="term"><code class="literal">FOR TABLE</code></span></dt><dd><p>
+ Specifies a list of tables to add to the publication. If
+ <code class="literal">ONLY</code> is specified before the table name, only
+ that table is added to the publication. If <code class="literal">ONLY</code> is not
+ specified, the table and all its descendant tables (if any) are added.
+ Optionally, <code class="literal">*</code> can be specified after the table name to
+ explicitly indicate that descendant tables are included.
+ This does not apply to a partitioned table, however. The partitions of
+ a partitioned table are always implicitly considered part of the
+ publication, so they are never explicitly added to the publication.
+ </p><p>
+ If the optional <code class="literal">WHERE</code> clause is specified, it defines a
+ <em class="firstterm">row filter</em> expression. Rows for
+ which the <em class="replaceable"><code>expression</code></em>
+ evaluates to false or null will not be published. Note that parentheses
+ are required around the expression. It has no effect on
+ <code class="literal">TRUNCATE</code> commands.
+ </p><p>
+ When a column list is specified, only the named columns are replicated.
+ If no column list is specified, all columns of the table are replicated
+ through this publication, including any columns added later. It has no
+ effect on <code class="literal">TRUNCATE</code> commands. See
+ <a class="xref" href="logical-replication-col-lists.html" title="31.4. Column Lists">Section 31.4</a> for details about column
+ lists.
+ </p><p>
+ Only persistent base tables and partitioned tables can be part of a
+ publication. Temporary tables, unlogged tables, foreign tables,
+ materialized views, and regular views cannot be part of a publication.
+ </p><p>
+ Specifying a column list when the publication also publishes
+ <code class="literal">FOR TABLES IN SCHEMA</code> is not supported.
+ </p><p>
+ When a partitioned table is added to a publication, all of its existing
+ and future partitions are implicitly considered to be part of the
+ publication. So, even operations that are performed directly on a
+ partition are also published via publications that its ancestors are
+ part of.
+ </p></dd><dt><span class="term"><code class="literal">FOR ALL TABLES</code></span></dt><dd><p>
+ Marks the publication as one that replicates changes for all tables in
+ the database, including tables created in the future.
+ </p></dd><dt><span class="term"><code class="literal">FOR TABLES IN SCHEMA</code></span></dt><dd><p>
+ Marks the publication as one that replicates changes for all tables in
+ the specified list of schemas, including tables created in the future.
+ </p><p>
+ Specifying a schema when the publication also publishes a table with a
+ column list is not supported.
+ </p><p>
+ Only persistent base tables and partitioned tables present in the schema
+ will be included as part of the publication. Temporary tables, unlogged
+ tables, foreign tables, materialized views, and regular views from the
+ schema will not be part of the publication.
+ </p><p>
+ When a partitioned table is published via schema level publication, all
+ of its existing and future partitions are implicitly considered to be part of the
+ publication, regardless of whether they are from the publication schema or not.
+ So, even operations that are performed directly on a
+ partition are also published via publications that its ancestors are
+ part of.
+ </p></dd><dt><span class="term"><code class="literal">WITH ( <em class="replaceable"><code>publication_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause specifies optional parameters for a publication. The
+ following parameters are supported:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">publish</code> (<code class="type">string</code>)</span></dt><dd><p>
+ This parameter determines which DML operations will be published by
+ the new publication to the subscribers. The value is
+ comma-separated list of operations. The allowed operations are
+ <code class="literal">insert</code>, <code class="literal">update</code>,
+ <code class="literal">delete</code>, and <code class="literal">truncate</code>.
+ The default is to publish all actions,
+ and so the default value for this option is
+ <code class="literal">'insert, update, delete, truncate'</code>.
+ </p><p>
+ This parameter only affects DML operations. In particular, the initial
+ data synchronization (see <a class="xref" href="logical-replication-architecture.html#LOGICAL-REPLICATION-SNAPSHOT" title="31.7.1. Initial Snapshot">Section 31.7.1</a>)
+ for logical replication does not take this parameter into account when
+ copying existing table data.
+ </p></dd><dt><span class="term"><code class="literal">publish_via_partition_root</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This parameter determines whether changes in a partitioned table (or
+ on its partitions) contained in the publication will be published
+ using the identity and schema of the partitioned table rather than
+ that of the individual partitions that are actually changed; the
+ latter is the default. Enabling this allows the changes to be
+ replicated into a non-partitioned table or a partitioned table
+ consisting of a different set of partitions.
+ </p><p>
+ This parameter also affects how row filters and column lists are
+ chosen for partitions; see below for details.
+ </p><p>
+ If this is enabled, <code class="literal">TRUNCATE</code> operations performed
+ directly on partitions are not replicated.
+ </p></dd></dl></div></dd></dl></div></div><div class="refsect1" id="id-1.9.3.77.7"><h2>Notes</h2><p>
+ If <code class="literal">FOR TABLE</code>, <code class="literal">FOR ALL TABLES</code> or
+ <code class="literal">FOR TABLES IN SCHEMA</code> are not specified, then the
+ publication starts out with an empty set of tables. That is useful if
+ tables or schemas are to be added later.
+ </p><p>
+ The creation of a publication does not start replication. It only defines
+ a grouping and filtering logic for future subscribers.
+ </p><p>
+ To create a publication, the invoking user must have the
+ <code class="literal">CREATE</code> privilege for the current database.
+ (Of course, superusers bypass this check.)
+ </p><p>
+ To add a table to a publication, the invoking user must have ownership
+ rights on the table. The <code class="command">FOR ALL TABLES</code> and
+ <code class="command">FOR TABLES IN SCHEMA</code> clauses require the invoking
+ user to be a superuser.
+ </p><p>
+ The tables added to a publication that publishes <code class="command">UPDATE</code>
+ and/or <code class="command">DELETE</code> operations must have
+ <code class="literal">REPLICA IDENTITY</code> defined. Otherwise those operations will be
+ disallowed on those tables.
+ </p><p>
+ Any column list must include the <code class="literal">REPLICA IDENTITY</code> columns
+ in order for <code class="command">UPDATE</code> or <code class="command">DELETE</code>
+ operations to be published. There are no column list restrictions if the
+ publication publishes only <code class="command">INSERT</code> operations.
+ </p><p>
+ A row filter expression (i.e., the <code class="literal">WHERE</code> clause) must contain only
+ columns that are covered by the <code class="literal">REPLICA IDENTITY</code>, in
+ order for <code class="command">UPDATE</code> and <code class="command">DELETE</code> operations
+ to be published. For publication of <code class="command">INSERT</code> operations,
+ any column may be used in the <code class="literal">WHERE</code> expression. The
+ row filter allows simple expressions that don't have
+ user-defined functions, user-defined operators, user-defined types,
+ user-defined collations, non-immutable built-in functions, or references to
+ system columns.
+ </p><p>
+ The row filter on a table becomes redundant if
+ <code class="literal">FOR TABLES IN SCHEMA</code> is specified and the table
+ belongs to the referred schema.
+ </p><p>
+ For published partitioned tables, the row filter for each
+ partition is taken from the published partitioned table if the
+ publication parameter <code class="literal">publish_via_partition_root</code> is true,
+ or from the partition itself if it is false (the default).
+ See <a class="xref" href="logical-replication-row-filter.html" title="31.3. Row Filters">Section 31.3</a> for details about row
+ filters.
+ Similarly, for published partitioned tables, the column list for each
+ partition is taken from the published partitioned table if the
+ publication parameter <code class="literal">publish_via_partition_root</code> is true,
+ or from the partition itself if it is false.
+ </p><p>
+ For an <code class="command">INSERT ... ON CONFLICT</code> command, the publication will
+ publish the operation that results from the command. Depending
+ on the outcome, it may be published as either <code class="command">INSERT</code> or
+ <code class="command">UPDATE</code>, or it may not be published at all.
+ </p><p>
+ For a <code class="command">MERGE</code> command, the publication will publish an
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or <code class="command">DELETE</code>
+ for each row inserted, updated, or deleted.
+ </p><p>
+ <code class="command">ATTACH</code>ing a table into a partition tree whose root is
+ published using a publication with <code class="literal">publish_via_partition_root</code>
+ set to <code class="literal">true</code> does not result in the table's existing contents
+ being replicated.
+ </p><p>
+ <code class="command">COPY ... FROM</code> commands are published
+ as <code class="command">INSERT</code> operations.
+ </p><p>
+ <acronym class="acronym">DDL</acronym> operations are not published.
+ </p><p>
+ The <code class="literal">WHERE</code> clause expression is executed with the role used
+ for the replication connection.
+ </p></div><div class="refsect1" id="id-1.9.3.77.8"><h2>Examples</h2><p>
+ Create a publication that publishes all changes in two tables:
+</p><pre class="programlisting">
+CREATE PUBLICATION mypublication FOR TABLE users, departments;
+</pre><p>
+ </p><p>
+ Create a publication that publishes all changes from active departments:
+</p><pre class="programlisting">
+CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE);
+</pre><p>
+ </p><p>
+ Create a publication that publishes all changes in all tables:
+</p><pre class="programlisting">
+CREATE PUBLICATION alltables FOR ALL TABLES;
+</pre><p>
+ </p><p>
+ Create a publication that only publishes <code class="command">INSERT</code>
+ operations in one table:
+</p><pre class="programlisting">
+CREATE PUBLICATION insert_only FOR TABLE mydata
+ WITH (publish = 'insert');
+</pre><p>
+ </p><p>
+ Create a publication that publishes all changes for tables
+ <code class="structname">users</code>, <code class="structname">departments</code> and
+ all changes for all the tables present in the schema
+ <code class="structname">production</code>:
+</p><pre class="programlisting">
+CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;
+</pre><p>
+ </p><p>
+ Create a publication that publishes all changes for all the tables present in
+ the schemas <code class="structname">marketing</code> and
+ <code class="structname">sales</code>:
+</p><pre class="programlisting">
+CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;
+</pre><p>
+ Create a publication that publishes all changes for table <code class="structname">users</code>,
+ but replicates only columns <code class="structname">user_id</code> and
+ <code class="structname">firstname</code>:
+</p><pre class="programlisting">
+CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);
+</pre></div><div class="refsect1" id="id-1.9.3.77.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE PUBLICATION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.77.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterpublication.html" title="ALTER PUBLICATION"><span class="refentrytitle">ALTER PUBLICATION</span></a>, <a class="xref" href="sql-droppublication.html" title="DROP PUBLICATION"><span class="refentrytitle">DROP PUBLICATION</span></a>, <a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>, <a class="xref" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><span class="refentrytitle">ALTER SUBSCRIPTION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createprocedure.html" title="CREATE PROCEDURE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createrole.html" title="CREATE ROLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE PROCEDURE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE ROLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createrole.html b/doc/src/sgml/html/sql-createrole.html
new file mode 100644
index 0000000..58a92b8
--- /dev/null
+++ b/doc/src/sgml/html/sql-createrole.html
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE ROLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createpublication.html" title="CREATE PUBLICATION" /><link rel="next" href="sql-createrule.html" title="CREATE RULE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE ROLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createpublication.html" title="CREATE PUBLICATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createrule.html" title="CREATE RULE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEROLE"><div class="titlepage"></div><a id="id-1.9.3.78.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE ROLE</span></h2><p>CREATE ROLE — define a new database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE ROLE <em class="replaceable"><code>name</code></em> [ [ WITH ] <em class="replaceable"><code>option</code></em> [ ... ] ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <em class="replaceable"><code>connlimit</code></em>
+ | [ ENCRYPTED ] PASSWORD '<em class="replaceable"><code>password</code></em>' | PASSWORD NULL
+ | VALID UNTIL '<em class="replaceable"><code>timestamp</code></em>'
+ | IN ROLE <em class="replaceable"><code>role_name</code></em> [, ...]
+ | IN GROUP <em class="replaceable"><code>role_name</code></em> [, ...]
+ | ROLE <em class="replaceable"><code>role_name</code></em> [, ...]
+ | ADMIN <em class="replaceable"><code>role_name</code></em> [, ...]
+ | USER <em class="replaceable"><code>role_name</code></em> [, ...]
+ | SYSID <em class="replaceable"><code>uid</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.78.5"><h2>Description</h2><p>
+ <code class="command">CREATE ROLE</code> adds a new role to a
+ <span class="productname">PostgreSQL</span> database cluster. A role is
+ an entity that can own database objects and have database privileges;
+ a role can be considered a <span class="quote">“<span class="quote">user</span>”</span>, a <span class="quote">“<span class="quote">group</span>”</span>, or both
+ depending on how it is used. Refer to
+ <a class="xref" href="user-manag.html" title="Chapter 22. Database Roles">Chapter 22</a> and <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a> for information about managing
+ users and authentication. You must have <code class="literal">CREATEROLE</code>
+ privilege or be a database superuser to use this command.
+ </p><p>
+ Note that roles are defined at the database cluster
+ level, and so are valid in all databases in the cluster.
+ </p></div><div class="refsect1" id="id-1.9.3.78.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the new role.
+ </p></dd><dt><span class="term"><code class="literal">SUPERUSER</code><br /></span><span class="term"><code class="literal">NOSUPERUSER</code></span></dt><dd><p>
+ These clauses determine whether the new role is a <span class="quote">“<span class="quote">superuser</span>”</span>,
+ who can override all access restrictions within the database.
+ Superuser status is dangerous and should be used only when really
+ needed. You must yourself be a superuser to create a new superuser.
+ If not specified,
+ <code class="literal">NOSUPERUSER</code> is the default.
+ </p></dd><dt><span class="term"><code class="literal">CREATEDB</code><br /></span><span class="term"><code class="literal">NOCREATEDB</code></span></dt><dd><p>
+ These clauses define a role's ability to create databases. If
+ <code class="literal">CREATEDB</code> is specified, the role being
+ defined will be allowed to create new databases. Specifying
+ <code class="literal">NOCREATEDB</code> will deny a role the ability to
+ create databases. If not specified,
+ <code class="literal">NOCREATEDB</code> is the default.
+ </p></dd><dt><span class="term"><code class="literal">CREATEROLE</code><br /></span><span class="term"><code class="literal">NOCREATEROLE</code></span></dt><dd><p>
+ These clauses determine whether a role will be permitted to
+ create, alter, drop, comment on, change the security label for,
+ and grant or revoke membership in other roles.
+ See <a class="xref" href="role-attributes.html#ROLE-CREATION">role creation</a> for more details about what
+ capabilities are conferred by this privilege.
+ If not specified, <code class="literal">NOCREATEROLE</code> is the default.
+ </p></dd><dt><span class="term"><code class="literal">INHERIT</code><br /></span><span class="term"><code class="literal">NOINHERIT</code></span></dt><dd><p>
+ These clauses determine whether a role <span class="quote">“<span class="quote">inherits</span>”</span> the
+ privileges of roles it is a member of.
+ A role with the <code class="literal">INHERIT</code> attribute can automatically
+ use whatever database privileges have been granted to all roles
+ it is directly or indirectly a member of.
+ Without <code class="literal">INHERIT</code>, membership in another role
+ only grants the ability to <code class="command">SET ROLE</code> to that other role;
+ the privileges of the other role are only available after having
+ done so.
+ If not specified,
+ <code class="literal">INHERIT</code> is the default.
+ </p></dd><dt><span class="term"><code class="literal">LOGIN</code><br /></span><span class="term"><code class="literal">NOLOGIN</code></span></dt><dd><p>
+ These clauses determine whether a role is allowed to log in;
+ that is, whether the role can be given as the initial session
+ authorization name during client connection. A role having
+ the <code class="literal">LOGIN</code> attribute can be thought of as a user.
+ Roles without this attribute are useful for managing database
+ privileges, but are not users in the usual sense of the word.
+ If not specified,
+ <code class="literal">NOLOGIN</code> is the default, except when
+ <code class="command">CREATE ROLE</code> is invoked through its alternative spelling
+ <a class="link" href="sql-createuser.html" title="CREATE USER"><code class="command">CREATE USER</code></a>.
+ </p></dd><dt><span class="term"><code class="literal">REPLICATION</code><br /></span><span class="term"><code class="literal">NOREPLICATION</code></span></dt><dd><p>
+ These clauses determine whether a role is a replication role. A role
+ must have this attribute (or be a superuser) in order to be able to
+ connect to the server in replication mode (physical or logical
+ replication) and in order to be able to create or drop replication
+ slots.
+ A role having the <code class="literal">REPLICATION</code> attribute is a very
+ highly privileged role, and should only be used on roles actually
+ used for replication. If not specified,
+ <code class="literal">NOREPLICATION</code> is the default.
+ You must be a superuser to create a new role having the
+ <code class="literal">REPLICATION</code> attribute.
+ </p></dd><dt><span class="term"><code class="literal">BYPASSRLS</code><br /></span><span class="term"><code class="literal">NOBYPASSRLS</code></span></dt><dd><p>
+ These clauses determine whether a role bypasses every row-level
+ security (RLS) policy. <code class="literal">NOBYPASSRLS</code> is the default.
+ You must be a superuser to create a new role having
+ the <code class="literal">BYPASSRLS</code> attribute.
+ </p><p>
+ Note that pg_dump will set <code class="literal">row_security</code> to
+ <code class="literal">OFF</code> by default, to ensure all contents of a table are
+ dumped out. If the user running pg_dump does not have appropriate
+ permissions, an error will be returned. However, superusers and the
+ owner of the table being dumped always bypass RLS.
+ </p></dd><dt><span class="term"><code class="literal">CONNECTION LIMIT</code> <em class="replaceable"><code>connlimit</code></em></span></dt><dd><p>
+ If role can log in, this specifies how many concurrent connections
+ the role can make. -1 (the default) means no limit. Note that only
+ normal connections are counted towards this limit. Neither prepared
+ transactions nor background worker connections are counted towards
+ this limit.
+ </p></dd><dt><span class="term">[ <code class="literal">ENCRYPTED</code> ] <code class="literal">PASSWORD</code> '<em class="replaceable"><code>password</code></em>'<br /></span><span class="term"><code class="literal">PASSWORD NULL</code></span></dt><dd><p>
+ Sets the role's password. (A password is only of use for
+ roles having the <code class="literal">LOGIN</code> attribute, but you
+ can nonetheless define one for roles without it.) If you do
+ not plan to use password authentication you can omit this
+ option. If no password is specified, the password will be set
+ to null and password authentication will always fail for that
+ user. A null password can optionally be written explicitly as
+ <code class="literal">PASSWORD NULL</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Specifying an empty string will also set the password to null,
+ but that was not the case before <span class="productname">PostgreSQL</span>
+ version 10. In earlier versions, an empty string could be used,
+ or not, depending on the authentication method and the exact
+ version, and libpq would refuse to use it in any case.
+ To avoid the ambiguity, specifying an empty string should be
+ avoided.
+ </p></div><p>
+ The password is always stored encrypted in the system catalogs. The
+ <code class="literal">ENCRYPTED</code> keyword has no effect, but is accepted for
+ backwards compatibility. The method of encryption is determined
+ by the configuration parameter <a class="xref" href="runtime-config-connection.html#GUC-PASSWORD-ENCRYPTION">password_encryption</a>.
+ If the presented password string is already in MD5-encrypted or
+ SCRAM-encrypted format, then it is stored as-is regardless of
+ <code class="varname">password_encryption</code> (since the system cannot decrypt
+ the specified encrypted password string, to encrypt it in a
+ different format). This allows reloading of encrypted passwords
+ during dump/restore.
+ </p></dd><dt><span class="term"><code class="literal">VALID UNTIL</code> '<em class="replaceable"><code>timestamp</code></em>'</span></dt><dd><p>
+ The <code class="literal">VALID UNTIL</code> clause sets a date and
+ time after which the role's password is no longer valid. If
+ this clause is omitted the password will be valid for all time.
+ </p></dd><dt><span class="term"><code class="literal">IN ROLE</code> <em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The <code class="literal">IN ROLE</code> clause lists one or more existing
+ roles to which the new role will be immediately added as a new
+ member. (Note that there is no option to add the new role as an
+ administrator; use a separate <code class="command">GRANT</code> command to do that.)
+ </p></dd><dt><span class="term"><code class="literal">IN GROUP</code> <em class="replaceable"><code>role_name</code></em></span></dt><dd><p><code class="literal">IN GROUP</code> is an obsolete spelling of
+ <code class="literal">IN ROLE</code>.
+ </p></dd><dt><span class="term"><code class="literal">ROLE</code> <em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The <code class="literal">ROLE</code> clause lists one or more existing
+ roles which are automatically added as members of the new role.
+ (This in effect makes the new role a <span class="quote">“<span class="quote">group</span>”</span>.)
+ </p></dd><dt><span class="term"><code class="literal">ADMIN</code> <em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The <code class="literal">ADMIN</code> clause is like <code class="literal">ROLE</code>,
+ but the named roles are added to the new role <code class="literal">WITH ADMIN
+ OPTION</code>, giving them the right to grant membership in this role
+ to others.
+ </p></dd><dt><span class="term"><code class="literal">USER</code> <em class="replaceable"><code>role_name</code></em></span></dt><dd><p>
+ The <code class="literal">USER</code> clause is an obsolete spelling of
+ the <code class="literal">ROLE</code> clause.
+ </p></dd><dt><span class="term"><code class="literal">SYSID</code> <em class="replaceable"><code>uid</code></em></span></dt><dd><p>
+ The <code class="literal">SYSID</code> clause is ignored, but is accepted
+ for backwards compatibility.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.78.7"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a> to
+ change the attributes of a role, and <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a>
+ to remove a role. All the attributes
+ specified by <code class="command">CREATE ROLE</code> can be modified by later
+ <code class="command">ALTER ROLE</code> commands.
+ </p><p>
+ The preferred way to add and remove members of roles that are being
+ used as groups is to use
+ <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> and
+ <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a>.
+ </p><p>
+ The <code class="literal">VALID UNTIL</code> clause defines an expiration time for a
+ password only, not for the role per se. In
+ particular, the expiration time is not enforced when logging in using
+ a non-password-based authentication method.
+ </p><p>
+ The <code class="literal">INHERIT</code> attribute governs inheritance of grantable
+ privileges (that is, access privileges for database objects and role
+ memberships). It does not apply to the special role attributes set by
+ <code class="command">CREATE ROLE</code> and <code class="command">ALTER ROLE</code>. For example, being
+ a member of a role with <code class="literal">CREATEDB</code> privilege does not immediately
+ grant the ability to create databases, even if <code class="literal">INHERIT</code> is set;
+ it would be necessary to become that role via
+ <a class="link" href="sql-set-role.html" title="SET ROLE"><code class="command">SET ROLE</code></a> before
+ creating a database.
+ </p><p>
+ The <code class="literal">INHERIT</code> attribute is the default for reasons of backwards
+ compatibility: in prior releases of <span class="productname">PostgreSQL</span>,
+ users always had access to all privileges of groups they were members of.
+ However, <code class="literal">NOINHERIT</code> provides a closer match to the semantics
+ specified in the SQL standard.
+ </p><p>
+ Be careful with the <code class="literal">CREATEROLE</code> privilege. There is no concept of
+ inheritance for the privileges of a <code class="literal">CREATEROLE</code>-role. That
+ means that even if a role does not have a certain privilege but is allowed
+ to create other roles, it can easily create another role with different
+ privileges than its own (except for creating roles with superuser
+ privileges). For example, if the role <span class="quote">“<span class="quote">user</span>”</span> has the
+ <code class="literal">CREATEROLE</code> privilege but not the <code class="literal">CREATEDB</code> privilege,
+ nonetheless it can create a new role with the <code class="literal">CREATEDB</code>
+ privilege. Therefore, regard roles that have the <code class="literal">CREATEROLE</code>
+ privilege as almost-superuser-roles.
+ </p><p>
+ <span class="productname">PostgreSQL</span> includes a program <a class="xref" href="app-createuser.html" title="createuser"><span class="refentrytitle"><span class="application">createuser</span></span></a> that has
+ the same functionality as <code class="command">CREATE ROLE</code> (in fact,
+ it calls this command) but can be run from the command shell.
+ </p><p>
+ The <code class="literal">CONNECTION LIMIT</code> option is only enforced approximately;
+ if two new sessions start at about the same time when just one
+ connection <span class="quote">“<span class="quote">slot</span>”</span> remains for the role, it is possible that
+ both will fail. Also, the limit is never enforced for superusers.
+ </p><p>
+ Caution must be exercised when specifying an unencrypted password
+ with this command. The password will be transmitted to the server
+ in cleartext, and it might also be logged in the client's command
+ history or the server log. The command <a class="xref" href="app-createuser.html" title="createuser"><span class="refentrytitle"><span class="application">createuser</span></span></a>, however, transmits
+ the password encrypted. Also, <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>
+ contains a command
+ <code class="command">\password</code> that can be used to safely change the
+ password later.
+ </p></div><div class="refsect1" id="id-1.9.3.78.8"><h2>Examples</h2><p>
+ Create a role that can log in, but don't give it a password:
+</p><pre class="programlisting">
+CREATE ROLE jonathan LOGIN;
+</pre><p>
+ </p><p>
+ Create a role with a password:
+</p><pre class="programlisting">
+CREATE USER davide WITH PASSWORD 'jw8s0F4';
+</pre><p>
+ (<code class="command">CREATE USER</code> is the same as <code class="command">CREATE ROLE</code> except
+ that it implies <code class="literal">LOGIN</code>.)
+ </p><p>
+ Create a role with a password that is valid until the end of 2004.
+ After one second has ticked in 2005, the password is no longer
+ valid.
+
+</p><pre class="programlisting">
+CREATE ROLE miriam WITH LOGIN PASSWORD 'jw8s0F4' VALID UNTIL '2005-01-01';
+</pre><p>
+ </p><p>
+ Create a role that can create databases and manage roles:
+</p><pre class="programlisting">
+CREATE ROLE admin WITH CREATEDB CREATEROLE;
+</pre></div><div class="refsect1" id="id-1.9.3.78.9"><h2>Compatibility</h2><p>
+ The <code class="command">CREATE ROLE</code> statement is in the SQL standard,
+ but the standard only requires the syntax
+</p><pre class="synopsis">
+CREATE ROLE <em class="replaceable"><code>name</code></em> [ WITH ADMIN <em class="replaceable"><code>role_name</code></em> ]
+</pre><p>
+ Multiple initial administrators, and all the other options of
+ <code class="command">CREATE ROLE</code>, are
+ <span class="productname">PostgreSQL</span> extensions.
+ </p><p>
+ The SQL standard defines the concepts of users and roles, but it
+ regards them as distinct concepts and leaves all commands defining
+ users to be specified by each database implementation. In
+ <span class="productname">PostgreSQL</span> we have chosen to unify
+ users and roles into a single kind of entity. Roles therefore
+ have many more optional attributes than they do in the standard.
+ </p><p>
+ The behavior specified by the SQL standard is most closely approximated
+ by giving users the <code class="literal">NOINHERIT</code> attribute, while roles are
+ given the <code class="literal">INHERIT</code> attribute.
+ </p></div><div class="refsect1" id="id-1.9.3.78.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-set-role.html" title="SET ROLE"><span class="refentrytitle">SET ROLE</span></a>, <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>, <a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a>, <a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>, <a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a>, <a class="xref" href="app-createuser.html" title="createuser"><span class="refentrytitle"><span class="application">createuser</span></span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createpublication.html" title="CREATE PUBLICATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createrule.html" title="CREATE RULE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE PUBLICATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE RULE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createrule.html b/doc/src/sgml/html/sql-createrule.html
new file mode 100644
index 0000000..f50b69f
--- /dev/null
+++ b/doc/src/sgml/html/sql-createrule.html
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE RULE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createrole.html" title="CREATE ROLE" /><link rel="next" href="sql-createschema.html" title="CREATE SCHEMA" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE RULE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createrole.html" title="CREATE ROLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createschema.html" title="CREATE SCHEMA">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATERULE"><div class="titlepage"></div><a id="id-1.9.3.79.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE RULE</span></h2><p>CREATE RULE — define a new rewrite rule</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] RULE <em class="replaceable"><code>name</code></em> AS ON <em class="replaceable"><code>event</code></em>
+ TO <em class="replaceable"><code>table_name</code></em> [ WHERE <em class="replaceable"><code>condition</code></em> ]
+ DO [ ALSO | INSTEAD ] { NOTHING | <em class="replaceable"><code>command</code></em> | ( <em class="replaceable"><code>command</code></em> ; <em class="replaceable"><code>command</code></em> ... ) }
+
+<span class="phrase">where <em class="replaceable"><code>event</code></em> can be one of:</span>
+
+ SELECT | INSERT | UPDATE | DELETE
+</pre></div><div class="refsect1" id="id-1.9.3.79.5"><h2>Description</h2><p>
+ <code class="command">CREATE RULE</code> defines a new rule applying to a specified
+ table or view.
+ <code class="command">CREATE OR REPLACE RULE</code> will either create a
+ new rule, or replace an existing rule of the same name for the same
+ table.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> rule system allows one to
+ define an alternative action to be performed on insertions, updates,
+ or deletions in database tables. Roughly speaking, a rule causes
+ additional commands to be executed when a given command on a given
+ table is executed. Alternatively, an <code class="literal">INSTEAD</code>
+ rule can replace a given command by another, or cause a command
+ not to be executed at all. Rules are used to implement SQL
+ views as well. It is important to realize that a rule is really
+ a command transformation mechanism, or command macro. The
+ transformation happens before the execution of the command starts.
+ If you actually want an operation that fires independently for each
+ physical row, you probably want to use a trigger, not a rule.
+ More information about the rules system is in <a class="xref" href="rules.html" title="Chapter 41. The Rule System">Chapter 41</a>.
+ </p><p>
+ Presently, <code class="literal">ON SELECT</code> rules must be unconditional
+ <code class="literal">INSTEAD</code> rules and must have actions that consist
+ of a single <code class="command">SELECT</code> command. Thus, an
+ <code class="literal">ON SELECT</code> rule effectively turns the table into
+ a view, whose visible contents are the rows returned by the rule's
+ <code class="command">SELECT</code> command rather than whatever had been
+ stored in the table (if anything). It is considered better style
+ to write a <code class="command">CREATE VIEW</code> command than to create a
+ real table and define an <code class="literal">ON SELECT</code> rule for it.
+ </p><p>
+ You can create the illusion of an updatable view by defining
+ <code class="literal">ON INSERT</code>, <code class="literal">ON UPDATE</code>, and
+ <code class="literal">ON DELETE</code> rules (or any subset of those that's
+ sufficient for your purposes) to replace update actions on the view
+ with appropriate updates on other tables. If you want to support
+ <code class="command">INSERT RETURNING</code> and so on, then be sure to put a suitable
+ <code class="literal">RETURNING</code> clause into each of these rules.
+ </p><p>
+ There is a catch if you try to use conditional rules for complex view
+ updates: there <span class="emphasis"><em>must</em></span> be an unconditional
+ <code class="literal">INSTEAD</code> rule for each action you wish to allow
+ on the view. If the rule is conditional, or is not
+ <code class="literal">INSTEAD</code>, then the system will still reject
+ attempts to perform the update action, because it thinks it might
+ end up trying to perform the action on the dummy table of the view
+ in some cases. If you want to handle all the useful cases in
+ conditional rules, add an unconditional <code class="literal">DO
+ INSTEAD NOTHING</code> rule to ensure that the system
+ understands it will never be called on to update the dummy table.
+ Then make the conditional rules non-<code class="literal">INSTEAD</code>; in
+ the cases where they are applied, they add to the default
+ <code class="literal">INSTEAD NOTHING</code> action. (This method does not
+ currently work to support <code class="literal">RETURNING</code> queries, however.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ A view that is simple enough to be automatically updatable (see <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a>) does not require a user-created rule in
+ order to be updatable. While you can create an explicit rule anyway,
+ the automatic update transformation will generally outperform an
+ explicit rule.
+ </p><p>
+ Another alternative worth considering is to use <code class="literal">INSTEAD OF</code>
+ triggers (see <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>) in place of rules.
+ </p></div></div><div class="refsect1" id="id-1.9.3.79.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a rule to create. This must be distinct from the
+ name of any other rule for the same table. Multiple rules on
+ the same table and same event type are applied in alphabetical
+ name order.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>event</code></em></span></dt><dd><p>
+ The event is one of <code class="literal">SELECT</code>,
+ <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, or
+ <code class="literal">DELETE</code>. Note that an
+ <code class="command">INSERT</code> containing an <code class="literal">ON
+ CONFLICT</code> clause cannot be used on tables that have
+ either <code class="literal">INSERT</code> or <code class="literal">UPDATE</code>
+ rules. Consider using an updatable view instead.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table or view the
+ rule applies to.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
+ Any <acronym class="acronym">SQL</acronym> conditional expression (returning
+ <code class="type">boolean</code>). The condition expression cannot refer
+ to any tables except <code class="literal">NEW</code> and <code class="literal">OLD</code>, and
+ cannot contain aggregate functions.
+ </p></dd><dt><span class="term"><code class="option">INSTEAD</code></span></dt><dd><p><code class="literal">INSTEAD</code> indicates that the commands should be
+ executed <span class="emphasis"><em>instead of</em></span> the original command.
+ </p></dd><dt><span class="term"><code class="option">ALSO</code></span></dt><dd><p><code class="literal">ALSO</code> indicates that the commands should be
+ executed <span class="emphasis"><em>in addition to</em></span> the original
+ command.
+ </p><p>
+ If neither <code class="literal">ALSO</code> nor
+ <code class="literal">INSTEAD</code> is specified, <code class="literal">ALSO</code>
+ is the default.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>command</code></em></span></dt><dd><p>
+ The command or commands that make up the rule action. Valid
+ commands are <code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, or <code class="command">NOTIFY</code>.
+ </p></dd></dl></div><p>
+ Within <em class="replaceable"><code>condition</code></em> and
+ <em class="replaceable"><code>command</code></em>, the special
+ table names <code class="literal">NEW</code> and <code class="literal">OLD</code> can
+ be used to refer to values in the referenced table.
+ <code class="literal">NEW</code> is valid in <code class="literal">ON INSERT</code> and
+ <code class="literal">ON UPDATE</code> rules to refer to the new row being
+ inserted or updated. <code class="literal">OLD</code> is valid in
+ <code class="literal">ON UPDATE</code> and <code class="literal">ON DELETE</code> rules
+ to refer to the existing row being updated or deleted.
+ </p></div><div class="refsect1" id="id-1.9.3.79.7"><h2>Notes</h2><p>
+ You must be the owner of a table to create or change rules for it.
+ </p><p>
+ In a rule for <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, or
+ <code class="literal">DELETE</code> on a view, you can add a <code class="literal">RETURNING</code>
+ clause that emits the view's columns. This clause will be used to compute
+ the outputs if the rule is triggered by an <code class="command">INSERT RETURNING</code>,
+ <code class="command">UPDATE RETURNING</code>, or <code class="command">DELETE RETURNING</code> command
+ respectively. When the rule is triggered by a command without
+ <code class="literal">RETURNING</code>, the rule's <code class="literal">RETURNING</code> clause will be
+ ignored. The current implementation allows only unconditional
+ <code class="literal">INSTEAD</code> rules to contain <code class="literal">RETURNING</code>; furthermore
+ there can be at most one <code class="literal">RETURNING</code> clause among all the rules
+ for the same event. (This ensures that there is only one candidate
+ <code class="literal">RETURNING</code> clause to be used to compute the results.)
+ <code class="literal">RETURNING</code> queries on the view will be rejected if
+ there is no <code class="literal">RETURNING</code> clause in any available rule.
+ </p><p>
+ It is very important to take care to avoid circular rules. For
+ example, though each of the following two rule definitions are
+ accepted by <span class="productname">PostgreSQL</span>, the
+ <code class="command">SELECT</code> command would cause
+ <span class="productname">PostgreSQL</span> to report an error because
+ of recursive expansion of a rule:
+
+</p><pre class="programlisting">
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t1
+ DO INSTEAD
+ SELECT * FROM t2;
+
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t2
+ DO INSTEAD
+ SELECT * FROM t1;
+
+SELECT * FROM t1;
+</pre><p>
+ </p><p>
+ Presently, if a rule action contains a <code class="command">NOTIFY</code>
+ command, the <code class="command">NOTIFY</code> command will be executed
+ unconditionally, that is, the <code class="command">NOTIFY</code> will be
+ issued even if there are not any rows that the rule should apply
+ to. For example, in:
+</p><pre class="programlisting">
+CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;
+
+UPDATE mytable SET name = 'foo' WHERE id = 42;
+</pre><p>
+ one <code class="command">NOTIFY</code> event will be sent during the
+ <code class="command">UPDATE</code>, whether or not there are any rows that
+ match the condition <code class="literal">id = 42</code>. This is an
+ implementation restriction that might be fixed in future releases.
+ </p></div><div class="refsect1" id="id-1.9.3.79.8"><h2>Compatibility</h2><p>
+ <code class="command">CREATE RULE</code> is a
+ <span class="productname">PostgreSQL</span> language extension, as is the
+ entire query rewrite system.
+ </p></div><div class="refsect1" id="id-1.9.3.79.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterrule.html" title="ALTER RULE"><span class="refentrytitle">ALTER RULE</span></a>, <a class="xref" href="sql-droprule.html" title="DROP RULE"><span class="refentrytitle">DROP RULE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createrole.html" title="CREATE ROLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createschema.html" title="CREATE SCHEMA">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE ROLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE SCHEMA</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createschema.html b/doc/src/sgml/html/sql-createschema.html
new file mode 100644
index 0000000..8ab91df
--- /dev/null
+++ b/doc/src/sgml/html/sql-createschema.html
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE SCHEMA</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createrule.html" title="CREATE RULE" /><link rel="next" href="sql-createsequence.html" title="CREATE SEQUENCE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE SCHEMA</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createrule.html" title="CREATE RULE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createsequence.html" title="CREATE SEQUENCE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATESCHEMA"><div class="titlepage"></div><a id="id-1.9.3.80.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE SCHEMA</span></h2><p>CREATE SCHEMA — define a new schema</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE SCHEMA <em class="replaceable"><code>schema_name</code></em> [ AUTHORIZATION <em class="replaceable"><code>role_specification</code></em> ] [ <em class="replaceable"><code>schema_element</code></em> [ ... ] ]
+CREATE SCHEMA AUTHORIZATION <em class="replaceable"><code>role_specification</code></em> [ <em class="replaceable"><code>schema_element</code></em> [ ... ] ]
+CREATE SCHEMA IF NOT EXISTS <em class="replaceable"><code>schema_name</code></em> [ AUTHORIZATION <em class="replaceable"><code>role_specification</code></em> ]
+CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <em class="replaceable"><code>role_specification</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>role_specification</code></em> can be:</span>
+
+ <em class="replaceable"><code>user_name</code></em>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</pre></div><div class="refsect1" id="id-1.9.3.80.5"><h2>Description</h2><p>
+ <code class="command">CREATE SCHEMA</code> enters a new schema
+ into the current database.
+ The schema name must be distinct from the name of any existing schema
+ in the current database.
+ </p><p>
+ A schema is essentially a namespace:
+ it contains named objects (tables, data types, functions, and operators)
+ whose names can duplicate those of other objects existing in other
+ schemas. Named objects are accessed either by <span class="quote">“<span class="quote">qualifying</span>”</span>
+ their names with the schema name as a prefix, or by setting a search
+ path that includes the desired schema(s). A <code class="literal">CREATE</code> command
+ specifying an unqualified object name creates the object
+ in the current schema (the one at the front of the search path,
+ which can be determined with the function <code class="function">current_schema</code>).
+ </p><p>
+ Optionally, <code class="command">CREATE SCHEMA</code> can include subcommands
+ to create objects within the new schema. The subcommands are treated
+ essentially the same as separate commands issued after creating the
+ schema, except that if the <code class="literal">AUTHORIZATION</code> clause is used,
+ all the created objects will be owned by that user.
+ </p></div><div class="refsect1" id="id-1.9.3.80.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>schema_name</code></em></span></dt><dd><p>
+ The name of a schema to be created. If this is omitted, the
+ <em class="replaceable"><code>user_name</code></em>
+ is used as the schema name. The name cannot
+ begin with <code class="literal">pg_</code>, as such names
+ are reserved for system schemas.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ The role name of the user who will own the new schema. If omitted,
+ defaults to the user executing the command. To create a schema
+ owned by another role, you must be a direct or indirect member of
+ that role, or be a superuser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>schema_element</code></em></span></dt><dd><p>
+ An SQL statement defining an object to be created within the
+ schema. Currently, only <code class="command">CREATE
+ TABLE</code>, <code class="command">CREATE VIEW</code>, <code class="command">CREATE
+ INDEX</code>, <code class="command">CREATE SEQUENCE</code>, <code class="command">CREATE
+ TRIGGER</code> and <code class="command">GRANT</code> are accepted as clauses
+ within <code class="command">CREATE SCHEMA</code>. Other kinds of objects may
+ be created in separate commands after the schema is created.
+ </p></dd><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do nothing (except issuing a notice) if a schema with the same name
+ already exists. <em class="replaceable"><code>schema_element</code></em>
+ subcommands cannot be included when this option is used.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.80.7"><h2>Notes</h2><p>
+ To create a schema, the invoking user must have the
+ <code class="literal">CREATE</code> privilege for the current database.
+ (Of course, superusers bypass this check.)
+ </p></div><div class="refsect1" id="id-1.9.3.80.8"><h2>Examples</h2><p>
+ Create a schema:
+</p><pre class="programlisting">
+CREATE SCHEMA myschema;
+</pre><p>
+ </p><p>
+ Create a schema for user <code class="literal">joe</code>; the schema will also be
+ named <code class="literal">joe</code>:
+</p><pre class="programlisting">
+CREATE SCHEMA AUTHORIZATION joe;
+</pre><p>
+ </p><p>
+ Create a schema named <code class="literal">test</code> that will be owned by user
+ <code class="literal">joe</code>, unless there already is a schema named <code class="literal">test</code>.
+ (It does not matter whether <code class="literal">joe</code> owns the pre-existing schema.)
+</p><pre class="programlisting">
+CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe;
+</pre><p>
+ </p><p>
+ Create a schema and create a table and view within it:
+</p><pre class="programlisting">
+CREATE SCHEMA hollywood
+ CREATE TABLE films (title text, release date, awards text[])
+ CREATE VIEW winners AS
+ SELECT title, release FROM films WHERE awards IS NOT NULL;
+</pre><p>
+ Notice that the individual subcommands do not end with semicolons.
+ </p><p>
+ The following is an equivalent way of accomplishing the same result:
+</p><pre class="programlisting">
+CREATE SCHEMA hollywood;
+CREATE TABLE hollywood.films (title text, release date, awards text[]);
+CREATE VIEW hollywood.winners AS
+ SELECT title, release FROM hollywood.films WHERE awards IS NOT NULL;
+</pre></div><div class="refsect1" id="id-1.9.3.80.9"><h2>Compatibility</h2><p>
+ The SQL standard allows a <code class="literal">DEFAULT CHARACTER SET</code> clause
+ in <code class="command">CREATE SCHEMA</code>, as well as more subcommand
+ types than are presently accepted by
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ The SQL standard specifies that the subcommands in <code class="command">CREATE
+ SCHEMA</code> can appear in any order. The present
+ <span class="productname">PostgreSQL</span> implementation does not
+ handle all cases of forward references in subcommands; it might
+ sometimes be necessary to reorder the subcommands in order to avoid
+ forward references.
+ </p><p>
+ According to the SQL standard, the owner of a schema always owns
+ all objects within it. <span class="productname">PostgreSQL</span>
+ allows schemas to contain objects owned by users other than the
+ schema owner. This can happen only if the schema owner grants the
+ <code class="literal">CREATE</code> privilege on their schema to someone else, or a
+ superuser chooses to create objects in it.
+ </p><p>
+ The <code class="literal">IF NOT EXISTS</code> option is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.80.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterschema.html" title="ALTER SCHEMA"><span class="refentrytitle">ALTER SCHEMA</span></a>, <a class="xref" href="sql-dropschema.html" title="DROP SCHEMA"><span class="refentrytitle">DROP SCHEMA</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createrule.html" title="CREATE RULE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createsequence.html" title="CREATE SEQUENCE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE RULE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE SEQUENCE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createsequence.html b/doc/src/sgml/html/sql-createsequence.html
new file mode 100644
index 0000000..d1e2737
--- /dev/null
+++ b/doc/src/sgml/html/sql-createsequence.html
@@ -0,0 +1,214 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE SEQUENCE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createschema.html" title="CREATE SCHEMA" /><link rel="next" href="sql-createserver.html" title="CREATE SERVER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE SEQUENCE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createschema.html" title="CREATE SCHEMA">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createserver.html" title="CREATE SERVER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATESEQUENCE"><div class="titlepage"></div><a id="id-1.9.3.81.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE SEQUENCE</span></h2><p>CREATE SEQUENCE — define a new sequence generator</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] <em class="replaceable"><code>name</code></em>
+ [ AS <em class="replaceable"><code>data_type</code></em> ]
+ [ INCREMENT [ BY ] <em class="replaceable"><code>increment</code></em> ]
+ [ MINVALUE <em class="replaceable"><code>minvalue</code></em> | NO MINVALUE ] [ MAXVALUE <em class="replaceable"><code>maxvalue</code></em> | NO MAXVALUE ]
+ [ START [ WITH ] <em class="replaceable"><code>start</code></em> ] [ CACHE <em class="replaceable"><code>cache</code></em> ] [ [ NO ] CYCLE ]
+ [ OWNED BY { <em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em> | NONE } ]
+</pre></div><div class="refsect1" id="id-1.9.3.81.5"><h2>Description</h2><p>
+ <code class="command">CREATE SEQUENCE</code> creates a new sequence number
+ generator. This involves creating and initializing a new special
+ single-row table with the name <em class="replaceable"><code>name</code></em>. The generator will be
+ owned by the user issuing the command.
+ </p><p>
+ If a schema name is given then the sequence is created in the
+ specified schema. Otherwise it is created in the current schema.
+ Temporary sequences exist in a special schema, so a schema name cannot be
+ given when creating a temporary sequence.
+ The sequence name must be distinct from the name of any other relation
+ (table, sequence, index, view, materialized view, or foreign table) in
+ the same schema.
+ </p><p>
+ After a sequence is created, you use the functions
+ <code class="function">nextval</code>,
+ <code class="function">currval</code>, and
+ <code class="function">setval</code>
+ to operate on the sequence. These functions are documented in
+ <a class="xref" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Section 9.17</a>.
+ </p><p>
+ Although you cannot update a sequence directly, you can use a query like:
+
+</p><pre class="programlisting">
+SELECT * FROM <em class="replaceable"><code>name</code></em>;
+</pre><p>
+
+ to examine the parameters and current state of a sequence. In particular,
+ the <code class="literal">last_value</code> field of the sequence shows the last value
+ allocated by any session. (Of course, this value might be obsolete
+ by the time it's printed, if other sessions are actively doing
+ <code class="function">nextval</code> calls.)
+ </p></div><div class="refsect1" id="id-1.9.3.81.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></span></dt><dd><p>
+ If specified, the sequence object is created only for this
+ session, and is automatically dropped on session exit. Existing
+ permanent sequences with the same name are not visible (in this
+ session) while the temporary sequence exists, unless they are
+ referenced with schema-qualified names.
+ </p></dd><dt><span class="term"><code class="literal">UNLOGGED</code></span></dt><dd><p>
+ If specified, the sequence is created as an unlogged sequence. Changes
+ to unlogged sequences are not written to the write-ahead log. They are
+ not crash-safe: an unlogged sequence is automatically reset to its
+ initial state after a crash or unclean shutdown. Unlogged sequences are
+ also not replicated to standby servers.
+ </p><p>
+ Unlike unlogged tables, unlogged sequences do not offer a significant
+ performance advantage. This option is mainly intended for sequences
+ associated with unlogged tables via identity columns or serial columns.
+ In those cases, it usually wouldn't make sense to have the sequence
+ WAL-logged and replicated but not its associated table.
+ </p></dd><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing relation is anything like the sequence that would have
+ been created — it might not even be a sequence.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the sequence to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The optional
+ clause <code class="literal">AS <em class="replaceable"><code>data_type</code></em></code>
+ specifies the data type of the sequence. Valid types are
+ <code class="literal">smallint</code>, <code class="literal">integer</code>,
+ and <code class="literal">bigint</code>. <code class="literal">bigint</code> is the
+ default. The data type determines the default minimum and maximum
+ values of the sequence.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>increment</code></em></span></dt><dd><p>
+ The optional clause <code class="literal">INCREMENT BY <em class="replaceable"><code>increment</code></em></code> specifies
+ which value is added to the current sequence value to create a
+ new value. A positive value will make an ascending sequence, a
+ negative one a descending sequence. The default value is 1.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>minvalue</code></em><br /></span><span class="term"><code class="literal">NO MINVALUE</code></span></dt><dd><p>
+ The optional clause <code class="literal">MINVALUE <em class="replaceable"><code>minvalue</code></em></code> determines
+ the minimum value a sequence can generate. If this clause is not
+ supplied or <code class="option">NO MINVALUE</code> is specified, then
+ defaults will be used. The default for an ascending sequence is 1. The
+ default for a descending sequence is the minimum value of the data type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>maxvalue</code></em><br /></span><span class="term"><code class="literal">NO MAXVALUE</code></span></dt><dd><p>
+ The optional clause <code class="literal">MAXVALUE <em class="replaceable"><code>maxvalue</code></em></code> determines
+ the maximum value for the sequence. If this clause is not
+ supplied or <code class="option">NO MAXVALUE</code> is specified, then
+ default values will be used. The default for an ascending sequence is
+ the maximum value of the data type. The default for a descending
+ sequence is -1.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>start</code></em></span></dt><dd><p>
+ The optional clause <code class="literal">START WITH <em class="replaceable"><code>start</code></em> </code> allows the
+ sequence to begin anywhere. The default starting value is
+ <em class="replaceable"><code>minvalue</code></em> for
+ ascending sequences and <em class="replaceable"><code>maxvalue</code></em> for descending ones.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>cache</code></em></span></dt><dd><p>
+ The optional clause <code class="literal">CACHE <em class="replaceable"><code>cache</code></em></code> specifies how
+ many sequence numbers are to be preallocated and stored in
+ memory for faster access. The minimum value is 1 (only one value
+ can be generated at a time, i.e., no cache), and this is also the
+ default.
+ </p></dd><dt><span class="term"><code class="literal">CYCLE</code><br /></span><span class="term"><code class="literal">NO CYCLE</code></span></dt><dd><p>
+ The <code class="literal">CYCLE</code> option allows the sequence to wrap
+ around when the <em class="replaceable"><code>maxvalue</code></em> or <em class="replaceable"><code>minvalue</code></em> has been reached by an
+ ascending or descending sequence respectively. If the limit is
+ reached, the next number generated will be the <em class="replaceable"><code>minvalue</code></em> or <em class="replaceable"><code>maxvalue</code></em>, respectively.
+ </p><p>
+ If <code class="literal">NO CYCLE</code> is specified, any calls to
+ <code class="function">nextval</code> after the sequence has reached its
+ maximum value will return an error. If neither
+ <code class="literal">CYCLE</code> or <code class="literal">NO CYCLE</code> are
+ specified, <code class="literal">NO CYCLE</code> is the default.
+ </p></dd><dt><span class="term"><code class="literal">OWNED BY</code> <em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em><br /></span><span class="term"><code class="literal">OWNED BY NONE</code></span></dt><dd><p>
+ The <code class="literal">OWNED BY</code> option causes the sequence to be
+ associated with a specific table column, such that if that column
+ (or its whole table) is dropped, the sequence will be automatically
+ dropped as well. The specified table must have the same owner and be in
+ the same schema as the sequence.
+ <code class="literal">OWNED BY NONE</code>, the default, specifies that there
+ is no such association.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.81.7"><h2>Notes</h2><p>
+ Use <code class="command">DROP SEQUENCE</code> to remove a sequence.
+ </p><p>
+ Sequences are based on <code class="type">bigint</code> arithmetic, so the range
+ cannot exceed the range of an eight-byte integer
+ (-9223372036854775808 to 9223372036854775807).
+ </p><p>
+ Because <code class="function">nextval</code> and <code class="function">setval</code> calls are never
+ rolled back, sequence objects cannot be used if <span class="quote">“<span class="quote">gapless</span>”</span>
+ assignment of sequence numbers is needed. It is possible to build
+ gapless assignment by using exclusive locking of a table containing a
+ counter; but this solution is much more expensive than sequence
+ objects, especially if many transactions need sequence numbers
+ concurrently.
+ </p><p>
+ Unexpected results might be obtained if a <em class="replaceable"><code>cache</code></em> setting greater than one is
+ used for a sequence object that will be used concurrently by
+ multiple sessions. Each session will allocate and cache successive
+ sequence values during one access to the sequence object and
+ increase the sequence object's <code class="literal">last_value</code> accordingly.
+ Then, the next <em class="replaceable"><code>cache</code></em>-1
+ uses of <code class="function">nextval</code> within that session simply return the
+ preallocated values without touching the sequence object. So, any
+ numbers allocated but not used within a session will be lost when
+ that session ends, resulting in <span class="quote">“<span class="quote">holes</span>”</span> in the
+ sequence.
+ </p><p>
+ Furthermore, although multiple sessions are guaranteed to allocate
+ distinct sequence values, the values might be generated out of
+ sequence when all the sessions are considered. For example, with
+ a <em class="replaceable"><code>cache</code></em> setting of 10,
+ session A might reserve values 1..10 and return
+ <code class="function">nextval</code>=1, then session B might reserve values
+ 11..20 and return <code class="function">nextval</code>=11 before session A
+ has generated <code class="function">nextval</code>=2. Thus, with a
+ <em class="replaceable"><code>cache</code></em> setting of one
+ it is safe to assume that <code class="function">nextval</code> values are generated
+ sequentially; with a <em class="replaceable"><code>cache</code></em> setting greater than one you
+ should only assume that the <code class="function">nextval</code> values are all
+ distinct, not that they are generated purely sequentially. Also,
+ <code class="literal">last_value</code> will reflect the latest value reserved by
+ any session, whether or not it has yet been returned by
+ <code class="function">nextval</code>.
+ </p><p>
+ Another consideration is that a <code class="function">setval</code> executed on
+ such a sequence will not be noticed by other sessions until they
+ have used up any preallocated values they have cached.
+ </p></div><div class="refsect1" id="id-1.9.3.81.8"><h2>Examples</h2><p>
+ Create an ascending sequence called <code class="literal">serial</code>, starting at 101:
+</p><pre class="programlisting">
+CREATE SEQUENCE serial START 101;
+</pre><p>
+ </p><p>
+ Select the next number from this sequence:
+</p><pre class="programlisting">
+SELECT nextval('serial');
+
+ nextval
+---------
+ 101
+</pre><p>
+ </p><p>
+ Select the next number from this sequence:
+</p><pre class="programlisting">
+SELECT nextval('serial');
+
+ nextval
+---------
+ 102
+</pre><p>
+ </p><p>
+ Use this sequence in an <code class="command">INSERT</code> command:
+</p><pre class="programlisting">
+INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
+</pre><p>
+ </p><p>
+ Update the sequence value after a <code class="command">COPY FROM</code>:
+</p><pre class="programlisting">
+BEGIN;
+COPY distributors FROM 'input_file';
+SELECT setval('serial', max(id)) FROM distributors;
+END;
+</pre></div><div class="refsect1" id="id-1.9.3.81.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE SEQUENCE</code> conforms to the <acronym class="acronym">SQL</acronym>
+ standard, with the following exceptions:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Obtaining the next value is done using the <code class="function">nextval()</code>
+ function instead of the standard's <code class="command">NEXT VALUE FOR</code>
+ expression.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">OWNED BY</code> clause is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></li></ul></div></div><div class="refsect1" id="id-1.9.3.81.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altersequence.html" title="ALTER SEQUENCE"><span class="refentrytitle">ALTER SEQUENCE</span></a>, <a class="xref" href="sql-dropsequence.html" title="DROP SEQUENCE"><span class="refentrytitle">DROP SEQUENCE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createschema.html" title="CREATE SCHEMA">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createserver.html" title="CREATE SERVER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE SCHEMA </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE SERVER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createserver.html b/doc/src/sgml/html/sql-createserver.html
new file mode 100644
index 0000000..0403ea9
--- /dev/null
+++ b/doc/src/sgml/html/sql-createserver.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE SERVER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createsequence.html" title="CREATE SEQUENCE" /><link rel="next" href="sql-createstatistics.html" title="CREATE STATISTICS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE SERVER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createsequence.html" title="CREATE SEQUENCE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createstatistics.html" title="CREATE STATISTICS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATESERVER"><div class="titlepage"></div><a id="id-1.9.3.82.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE SERVER</span></h2><p>CREATE SERVER — define a new foreign server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE SERVER [ IF NOT EXISTS ] <em class="replaceable"><code>server_name</code></em> [ TYPE '<em class="replaceable"><code>server_type</code></em>' ] [ VERSION '<em class="replaceable"><code>server_version</code></em>' ]
+ FOREIGN DATA WRAPPER <em class="replaceable"><code>fdw_name</code></em>
+ [ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.82.5"><h2>Description</h2><p>
+ <code class="command">CREATE SERVER</code> defines a new foreign server. The
+ user who defines the server becomes its owner.
+ </p><p>
+ A foreign server typically encapsulates connection information that
+ a foreign-data wrapper uses to access an external data resource.
+ Additional user-specific connection information may be specified by
+ means of user mappings.
+ </p><p>
+ The server name must be unique within the database.
+ </p><p>
+ Creating a server requires <code class="literal">USAGE</code> privilege on the
+ foreign-data wrapper being used.
+ </p></div><div class="refsect1" id="id-1.9.3.82.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a server with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing server is anything like the one that would have been
+ created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_name</code></em></span></dt><dd><p>
+ The name of the foreign server to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_type</code></em></span></dt><dd><p>
+ Optional server type, potentially useful to foreign-data wrappers.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_version</code></em></span></dt><dd><p>
+ Optional server version, potentially useful to foreign-data wrappers.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>fdw_name</code></em></span></dt><dd><p>
+ The name of the foreign-data wrapper that manages the server.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] )</code></span></dt><dd><p>
+ This clause specifies the options for the server. The options
+ typically define the connection details of the server, but the
+ actual names and values are dependent on the server's
+ foreign-data wrapper.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.82.7"><h2>Notes</h2><p>
+ When using the <a class="xref" href="dblink.html" title="F.12. dblink">dblink</a> module,
+ a foreign server's name can be used
+ as an argument of the <a class="xref" href="contrib-dblink-connect.html" title="dblink_connect"><span class="refentrytitle">dblink_connect</span></a>
+ function to indicate the connection parameters. It is necessary to have
+ the <code class="literal">USAGE</code> privilege on the foreign server to be
+ able to use it in this way.
+ </p></div><div class="refsect1" id="id-1.9.3.82.8"><h2>Examples</h2><p>
+ Create a server <code class="literal">myserver</code> that uses the
+ foreign-data wrapper <code class="literal">postgres_fdw</code>:
+</p><pre class="programlisting">
+CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foo', dbname 'foodb', port '5432');
+</pre><p>
+ See <a class="xref" href="postgres-fdw.html" title="F.38. postgres_fdw">postgres_fdw</a> for more details.
+ </p></div><div class="refsect1" id="id-1.9.3.82.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE SERVER</code> conforms to ISO/IEC 9075-9 (SQL/MED).
+ </p></div><div class="refsect1" id="id-1.9.3.82.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterserver.html" title="ALTER SERVER"><span class="refentrytitle">ALTER SERVER</span></a>, <a class="xref" href="sql-dropserver.html" title="DROP SERVER"><span class="refentrytitle">DROP SERVER</span></a>, <a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a>, <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>, <a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createsequence.html" title="CREATE SEQUENCE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createstatistics.html" title="CREATE STATISTICS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE SEQUENCE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE STATISTICS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createstatistics.html b/doc/src/sgml/html/sql-createstatistics.html
new file mode 100644
index 0000000..65828c9
--- /dev/null
+++ b/doc/src/sgml/html/sql-createstatistics.html
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE STATISTICS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createserver.html" title="CREATE SERVER" /><link rel="next" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE STATISTICS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createserver.html" title="CREATE SERVER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATESTATISTICS"><div class="titlepage"></div><a id="id-1.9.3.83.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE STATISTICS</span></h2><p>CREATE STATISTICS — define extended statistics</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE STATISTICS [ IF NOT EXISTS ] <em class="replaceable"><code>statistics_name</code></em>
+ ON ( <em class="replaceable"><code>expression</code></em> )
+ FROM <em class="replaceable"><code>table_name</code></em>
+
+CREATE STATISTICS [ IF NOT EXISTS ] <em class="replaceable"><code>statistics_name</code></em>
+ [ ( <em class="replaceable"><code>statistics_kind</code></em> [, ... ] ) ]
+ ON { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) }, { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [, ...]
+ FROM <em class="replaceable"><code>table_name</code></em>
+</pre></div><div class="refsect1" id="SQL-CREATESTATISTICS-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE STATISTICS</code> will create a new extended statistics
+ object tracking data about the specified table, foreign table or
+ materialized view. The statistics object will be created in the current
+ database and will be owned by the user issuing the command.
+ </p><p>
+ The <code class="command">CREATE STATISTICS</code> command has two basic forms. The
+ first form allows univariate statistics for a single expression to be
+ collected, providing benefits similar to an expression index without the
+ overhead of index maintenance. This form does not allow the statistics
+ kind to be specified, since the various statistics kinds refer only to
+ multivariate statistics. The second form of the command allows
+ multivariate statistics on multiple columns and/or expressions to be
+ collected, optionally specifying which statistics kinds to include. This
+ form will also automatically cause univariate statistics to be collected on
+ any expressions included in the list.
+ </p><p>
+ If a schema name is given (for example, <code class="literal">CREATE STATISTICS
+ myschema.mystat ...</code>) then the statistics object is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The name of the statistics object must be distinct from the name of any
+ other statistics object in the same schema.
+ </p></div><div class="refsect1" id="id-1.9.3.83.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a statistics object with the same name already
+ exists. A notice is issued in this case. Note that only the name of
+ the statistics object is considered here, not the details of its
+ definition.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>statistics_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the statistics object to be
+ created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>statistics_kind</code></em></span></dt><dd><p>
+ A multivariate statistics kind to be computed in this statistics object.
+ Currently supported kinds are
+ <code class="literal">ndistinct</code>, which enables n-distinct statistics,
+ <code class="literal">dependencies</code>, which enables functional
+ dependency statistics, and <code class="literal">mcv</code> which enables
+ most-common values lists.
+ If this clause is omitted, all supported statistics kinds are
+ included in the statistics object. Univariate expression statistics are
+ built automatically if the statistics definition includes any complex
+ expressions rather than just simple column references.
+ For more information, see <a class="xref" href="planner-stats.html#PLANNER-STATS-EXTENDED" title="14.2.2. Extended Statistics">Section 14.2.2</a>
+ and <a class="xref" href="multivariate-statistics-examples.html" title="75.2. Multivariate Statistics Examples">Section 75.2</a>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a table column to be covered by the computed statistics.
+ This is only allowed when building multivariate statistics. At least
+ two column names or expressions must be specified, and their order is
+ not significant.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
+ An expression to be covered by the computed statistics. This may be
+ used to build univariate statistics on a single expression, or as part
+ of a list of multiple column names and/or expressions to build
+ multivariate statistics. In the latter case, separate univariate
+ statistics are built automatically for each expression in the list.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table containing the
+ column(s) the statistics are computed on; see <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a> for an explanation of the handling of
+ inheritance and partitions.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.83.7"><h2>Notes</h2><p>
+ You must be the owner of a table to create a statistics object
+ reading it. Once created, however, the ownership of the statistics
+ object is independent of the underlying table(s).
+ </p><p>
+ Expression statistics are per-expression and are similar to creating an
+ index on the expression, except that they avoid the overhead of index
+ maintenance. Expression statistics are built automatically for each
+ expression in the statistics object definition.
+ </p><p>
+ Extended statistics are not currently used by the planner for selectivity
+ estimations made for table joins. This limitation will likely be removed
+ in a future version of <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect1" id="SQL-CREATESTATISTICS-EXAMPLES"><h2>Examples</h2><p>
+ Create table <code class="structname">t1</code> with two functionally dependent columns, i.e.,
+ knowledge of a value in the first column is sufficient for determining the
+ value in the other column. Then functional dependency statistics are built
+ on those columns:
+
+</p><pre class="programlisting">
+CREATE TABLE t1 (
+ a int,
+ b int
+);
+
+INSERT INTO t1 SELECT i/100, i/500
+ FROM generate_series(1,1000000) s(i);
+
+ANALYZE t1;
+
+-- the number of matching rows will be drastically underestimated:
+EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
+
+CREATE STATISTICS s1 (dependencies) ON a, b FROM t1;
+
+ANALYZE t1;
+
+-- now the row count estimate is more accurate:
+EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
+</pre><p>
+
+ Without functional-dependency statistics, the planner would assume
+ that the two <code class="literal">WHERE</code> conditions are independent, and would
+ multiply their selectivities together to arrive at a much-too-small
+ row count estimate.
+ With such statistics, the planner recognizes that the <code class="literal">WHERE</code>
+ conditions are redundant and does not underestimate the row count.
+ </p><p>
+ Create table <code class="structname">t2</code> with two perfectly correlated columns
+ (containing identical data), and an MCV list on those columns:
+
+</p><pre class="programlisting">
+CREATE TABLE t2 (
+ a int,
+ b int
+);
+
+INSERT INTO t2 SELECT mod(i,100), mod(i,100)
+ FROM generate_series(1,1000000) s(i);
+
+CREATE STATISTICS s2 (mcv) ON a, b FROM t2;
+
+ANALYZE t2;
+
+-- valid combination (found in MCV)
+EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1);
+
+-- invalid combination (not found in MCV)
+EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);
+</pre><p>
+
+ The MCV list gives the planner more detailed information about the
+ specific values that commonly appear in the table, as well as an upper
+ bound on the selectivities of combinations of values that do not appear
+ in the table, allowing it to generate better estimates in both cases.
+ </p><p>
+ Create table <code class="structname">t3</code> with a single timestamp column,
+ and run queries using expressions on that column. Without extended
+ statistics, the planner has no information about the data distribution for
+ the expressions, and uses default estimates. The planner also does not
+ realize that the value of the date truncated to the month is fully
+ determined by the value of the date truncated to the day. Then expression
+ and ndistinct statistics are built on those two expressions:
+
+</p><pre class="programlisting">
+CREATE TABLE t3 (
+ a timestamp
+);
+
+INSERT INTO t3 SELECT i FROM generate_series('2020-01-01'::timestamp,
+ '2020-12-31'::timestamp,
+ '1 minute'::interval) s(i);
+
+ANALYZE t3;
+
+-- the number of matching rows will be drastically underestimated:
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('month', a) = '2020-01-01'::timestamp;
+
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp
+ AND '2020-06-30'::timestamp;
+
+EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a)
+ FROM t3 GROUP BY 1, 2;
+
+-- build ndistinct statistics on the pair of expressions (per-expression
+-- statistics are built automatically)
+CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3;
+
+ANALYZE t3;
+
+-- now the row count estimates are more accurate:
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('month', a) = '2020-01-01'::timestamp;
+
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp
+ AND '2020-06-30'::timestamp;
+
+EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a)
+ FROM t3 GROUP BY 1, 2;
+</pre><p>
+
+ Without expression and ndistinct statistics, the planner has no information
+ about the number of distinct values for the expressions, and has to rely
+ on default estimates. The equality and range conditions are assumed to have
+ 0.5% selectivity, and the number of distinct values in the expression is
+ assumed to be the same as for the column (i.e. unique). This results in a
+ significant underestimate of the row count in the first two queries. Moreover,
+ the planner has no information about the relationship between the expressions,
+ so it assumes the two <code class="literal">WHERE</code> and <code class="literal">GROUP BY</code>
+ conditions are independent, and multiplies their selectivities together to
+ arrive at a severe overestimate of the group count in the aggregate query.
+ This is further exacerbated by the lack of accurate statistics for the
+ expressions, forcing the planner to use a default ndistinct estimate for the
+ expression derived from ndistinct for the column. With such statistics, the
+ planner recognizes that the conditions are correlated, and arrives at much
+ more accurate estimates.
+ </p></div><div class="refsect1" id="id-1.9.3.83.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">CREATE STATISTICS</code> command in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.83.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterstatistics.html" title="ALTER STATISTICS"><span class="refentrytitle">ALTER STATISTICS</span></a>, <a class="xref" href="sql-dropstatistics.html" title="DROP STATISTICS"><span class="refentrytitle">DROP STATISTICS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createserver.html" title="CREATE SERVER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE SERVER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE SUBSCRIPTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createsubscription.html b/doc/src/sgml/html/sql-createsubscription.html
new file mode 100644
index 0000000..84e7d30
--- /dev/null
+++ b/doc/src/sgml/html/sql-createsubscription.html
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE SUBSCRIPTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createstatistics.html" title="CREATE STATISTICS" /><link rel="next" href="sql-createtable.html" title="CREATE TABLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE SUBSCRIPTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createstatistics.html" title="CREATE STATISTICS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtable.html" title="CREATE TABLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATESUBSCRIPTION"><div class="titlepage"></div><a id="id-1.9.3.84.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE SUBSCRIPTION</span></h2><p>CREATE SUBSCRIPTION — define a new subscription</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE SUBSCRIPTION <em class="replaceable"><code>subscription_name</code></em>
+ CONNECTION '<em class="replaceable"><code>conninfo</code></em>'
+ PUBLICATION <em class="replaceable"><code>publication_name</code></em> [, ...]
+ [ WITH ( <em class="replaceable"><code>subscription_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.84.5"><h2>Description</h2><p>
+ <code class="command">CREATE SUBSCRIPTION</code> adds a new logical-replication
+ subscription. The subscription name must be distinct from the name of
+ any existing subscription in the current database.
+ </p><p>
+ A subscription represents a replication connection to the publisher.
+ Hence, in addition to adding definitions in the local catalogs, this
+ command normally creates a replication slot on the publisher.
+ </p><p>
+ A logical replication worker will be started to replicate data for the new
+ subscription at the commit of the transaction where this command is run,
+ unless the subscription is initially disabled.
+ </p><p>
+ Additional information about subscriptions and logical replication as a
+ whole is available at <a class="xref" href="logical-replication-subscription.html" title="31.2. Subscription">Section 31.2</a> and
+ <a class="xref" href="logical-replication.html" title="Chapter 31. Logical Replication">Chapter 31</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.84.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>subscription_name</code></em></span></dt><dd><p>
+ The name of the new subscription.
+ </p></dd><dt><span class="term"><code class="literal">CONNECTION '<em class="replaceable"><code>conninfo</code></em>'</code></span></dt><dd><p>
+ The <span class="application">libpq</span> connection string defining how
+ to connect to the publisher database. For details see
+ <a class="xref" href="libpq-connect.html#LIBPQ-CONNSTRING" title="34.1.1. Connection Strings">Section 34.1.1</a>.
+ </p></dd><dt><span class="term"><code class="literal">PUBLICATION <em class="replaceable"><code>publication_name</code></em> [, ...]</code></span></dt><dd><p>
+ Names of the publications on the publisher to subscribe to.
+ </p></dd><dt><span class="term"><code class="literal">WITH ( <em class="replaceable"><code>subscription_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause specifies optional parameters for a subscription.
+ </p><p>
+ The following parameters control what happens during subscription creation:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">connect</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether the <code class="command">CREATE SUBSCRIPTION</code>
+ command should connect to the publisher at all. The default
+ is <code class="literal">true</code>. Setting this to
+ <code class="literal">false</code> will force the values of
+ <code class="literal">create_slot</code>, <code class="literal">enabled</code> and
+ <code class="literal">copy_data</code> to <code class="literal">false</code>.
+ (You cannot combine setting <code class="literal">connect</code>
+ to <code class="literal">false</code> with
+ setting <code class="literal">create_slot</code>, <code class="literal">enabled</code>,
+ or <code class="literal">copy_data</code> to <code class="literal">true</code>.)
+ </p><p>
+ Since no connection is made when this option is
+ <code class="literal">false</code>, no tables are subscribed, and so
+ after you enable the subscription nothing will be replicated.
+ You will need to then run
+ <code class="literal">ALTER SUBSCRIPTION ... REFRESH PUBLICATION</code>
+ for tables to be subscribed.
+ </p></dd><dt><span class="term"><code class="literal">create_slot</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether the command should create the replication slot on
+ the publisher. The default is <code class="literal">true</code>.
+ If set to <code class="literal">false</code>, you are responsible for
+ creating the publisher's slot in some other way.
+ </p></dd><dt><span class="term"><code class="literal">enabled</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether the subscription should be actively replicating
+ or whether it should just be set up but not started yet. The default
+ is <code class="literal">true</code>.
+ </p></dd><dt><span class="term"><code class="literal">slot_name</code> (<code class="type">string</code>)</span></dt><dd><p>
+ Name of the publisher's replication slot to use. The default is
+ to use the name of the subscription for the slot name.
+ </p><p>
+ Setting <code class="literal">slot_name</code> to <code class="literal">NONE</code>
+ means there will be no replication slot
+ associated with the subscription. Use this when you will be
+ creating the replication slot later manually. Such
+ subscriptions must also have both <code class="literal">enabled</code> and
+ <code class="literal">create_slot</code> set to <code class="literal">false</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ The following parameters control the subscription's replication
+ behavior after it has been created:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">binary</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether the subscription will request the publisher to
+ send the data in binary format (as opposed to text).
+ The default is <code class="literal">false</code>.
+ Even when this option is enabled, only data types having
+ binary send and receive functions will be transferred in binary.
+ </p><p>
+ When doing cross-version replication, it could be that the
+ publisher has a binary send function for some data type, but the
+ subscriber lacks a binary receive function for that type. In
+ such a case, data transfer will fail, and
+ the <code class="literal">binary</code> option cannot be used.
+ </p></dd><dt><span class="term"><code class="literal">copy_data</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether to copy pre-existing data in the publications
+ that are being subscribed to when the replication starts.
+ The default is <code class="literal">true</code>.
+ </p><p>
+ If the publications contain <code class="literal">WHERE</code> clauses, it
+ will affect what data is copied. Refer to the
+ <a class="xref" href="sql-createsubscription.html#SQL-CREATESUBSCRIPTION-NOTES" title="Notes">Notes</a> for details.
+ </p></dd><dt><span class="term"><code class="literal">streaming</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether to enable streaming of in-progress transactions
+ for this subscription. By default, all transactions
+ are fully decoded on the publisher and only then sent to the
+ subscriber as a whole.
+ </p></dd><dt><span class="term"><code class="literal">synchronous_commit</code> (<code class="type">enum</code>)</span></dt><dd><p>
+ The value of this parameter overrides the
+ <a class="xref" href="runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT">synchronous_commit</a> setting within this
+ subscription's apply worker processes. The default value
+ is <code class="literal">off</code>.
+ </p><p>
+ It is safe to use <code class="literal">off</code> for logical replication:
+ If the subscriber loses transactions because of missing
+ synchronization, the data will be sent again from the publisher.
+ </p><p>
+ A different setting might be appropriate when doing synchronous
+ logical replication. The logical replication workers report the
+ positions of writes and flushes to the publisher, and when using
+ synchronous replication, the publisher will wait for the actual
+ flush. This means that setting
+ <code class="literal">synchronous_commit</code> for the subscriber to
+ <code class="literal">off</code> when the subscription is used for
+ synchronous replication might increase the latency for
+ <code class="command">COMMIT</code> on the publisher. In this scenario, it
+ can be advantageous to set <code class="literal">synchronous_commit</code>
+ to <code class="literal">local</code> or higher.
+ </p></dd><dt><span class="term"><code class="literal">two_phase</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether two-phase commit is enabled for this subscription.
+ The default is <code class="literal">false</code>.
+ </p><p>
+ When two-phase commit is enabled, prepared transactions are sent
+ to the subscriber at the time of <code class="command">PREPARE
+ TRANSACTION</code>, and are processed as two-phase
+ transactions on the subscriber too. Otherwise, prepared
+ transactions are sent to the subscriber only when committed, and
+ are then processed immediately by the subscriber.
+ </p><p>
+ The implementation of two-phase commit requires that replication
+ has successfully finished the initial table synchronization
+ phase. So even when <code class="literal">two_phase</code> is enabled for a
+ subscription, the internal two-phase state remains
+ temporarily <span class="quote">“<span class="quote">pending</span>”</span> until the initialization phase
+ completes. See column <code class="structfield">subtwophasestate</code>
+ of <a class="link" href="catalog-pg-subscription.html" title="53.54. pg_subscription"><code class="structname">pg_subscription</code></a>
+ to know the actual two-phase state.
+ </p></dd><dt><span class="term"><code class="literal">disable_on_error</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ Specifies whether the subscription should be automatically disabled
+ if any errors are detected by subscription workers during data
+ replication from the publisher. The default is
+ <code class="literal">false</code>.
+ </p></dd></dl></div></dd></dl></div></div><div class="refsect1" id="SQL-CREATESUBSCRIPTION-NOTES"><h2>Notes</h2><p>
+ See <a class="xref" href="logical-replication-security.html" title="31.9. Security">Section 31.9</a> for details on
+ how to configure access control between the subscription and the
+ publication instance.
+ </p><p>
+ When creating a replication slot (the default behavior), <code class="command">CREATE
+ SUBSCRIPTION</code> cannot be executed inside a transaction block.
+ </p><p>
+ Creating a subscription that connects to the same database cluster (for
+ example, to replicate between databases in the same cluster or to replicate
+ within the same database) will only succeed if the replication slot is not
+ created as part of the same command. Otherwise, the <code class="command">CREATE
+ SUBSCRIPTION</code> call will hang. To make this work, create the
+ replication slot separately (using the
+ function <code class="function">pg_create_logical_replication_slot</code> with the
+ plugin name <code class="literal">pgoutput</code>) and create the subscription using
+ the parameter <code class="literal">create_slot = false</code>. This is an
+ implementation restriction that might be lifted in a future release.
+ </p><p>
+ If any table in the publication has a <code class="literal">WHERE</code> clause, rows
+ for which the <em class="replaceable"><code>expression</code></em>
+ evaluates to false or null will not be published. If the subscription has
+ several publications in which the same table has been published with
+ different <code class="literal">WHERE</code> clauses, a row will be published if any
+ of the expressions (referring to that publish operation) are satisfied. In
+ the case of different <code class="literal">WHERE</code> clauses, if one of the
+ publications has no <code class="literal">WHERE</code> clause (referring to that
+ publish operation) or the publication is declared as
+ <code class="literal">FOR ALL TABLES</code> or
+ <code class="literal">FOR TABLES IN SCHEMA</code>, rows are always published
+ regardless of the definition of the other expressions.
+ If the subscriber is a <span class="productname">PostgreSQL</span> version before
+ 15, then any row filtering is ignored during the initial data synchronization
+ phase. For this case, the user might want to consider deleting any initially
+ copied data that would be incompatible with subsequent filtering.
+ Because initial data synchronization does not take into account the publication
+ <code class="literal">publish</code> parameter when copying existing table data, some rows
+ may be copied that would not be replicated using DML. See
+ <a class="xref" href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-EXAMPLES" title="31.2.2. Examples">Section 31.2.2</a> for examples.
+ </p><p>
+ Subscriptions having several publications in which the same table has been
+ published with different column lists are not supported.
+ </p><p>
+ We allow non-existent publications to be specified so that users can add
+ those later. This means
+ <a class="link" href="catalog-pg-subscription.html" title="53.54. pg_subscription"><code class="structname">pg_subscription</code></a>
+ can have non-existent publications.
+ </p></div><div class="refsect1" id="id-1.9.3.84.8"><h2>Examples</h2><p>
+ Create a subscription to a remote server that replicates tables in
+ the publications <code class="literal">mypublication</code> and
+ <code class="literal">insert_only</code> and starts replicating immediately on
+ commit:
+</p><pre class="programlisting">
+CREATE SUBSCRIPTION mysub
+ CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
+ PUBLICATION mypublication, insert_only;
+</pre><p>
+ </p><p>
+ Create a subscription to a remote server that replicates tables in
+ the <code class="literal">insert_only</code> publication and does not start replicating
+ until enabled at a later time.
+</p><pre class="programlisting">
+CREATE SUBSCRIPTION mysub
+ CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
+ PUBLICATION insert_only
+ WITH (enabled = false);
+</pre></div><div class="refsect1" id="id-1.9.3.84.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE SUBSCRIPTION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.84.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><span class="refentrytitle">ALTER SUBSCRIPTION</span></a>, <a class="xref" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION"><span class="refentrytitle">DROP SUBSCRIPTION</span></a>, <a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a>, <a class="xref" href="sql-alterpublication.html" title="ALTER PUBLICATION"><span class="refentrytitle">ALTER PUBLICATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createstatistics.html" title="CREATE STATISTICS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtable.html" title="CREATE TABLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE STATISTICS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TABLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtable.html b/doc/src/sgml/html/sql-createtable.html
new file mode 100644
index 0000000..b6c4be0
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtable.html
@@ -0,0 +1,1470 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TABLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION" /><link rel="next" href="sql-createtableas.html" title="CREATE TABLE AS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TABLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtableas.html" title="CREATE TABLE AS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETABLE"><div class="titlepage"></div><a id="id-1.9.3.85.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TABLE</span></h2><p>CREATE TABLE — define a new table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em> ( [
+ { <em class="replaceable"><code>column_name</code></em> <em class="replaceable"><code>data_type</code></em> [ COMPRESSION <em class="replaceable"><code>compression_method</code></em> ] [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ | <em class="replaceable"><code>table_constraint</code></em>
+ | LIKE <em class="replaceable"><code>source_table</code></em> [ <em class="replaceable"><code>like_option</code></em> ... ] }
+ [, ... ]
+] )
+[ INHERITS ( <em class="replaceable"><code>parent_table</code></em> [, ... ] ) ]
+[ PARTITION BY { RANGE | LIST | HASH } ( { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>opclass</code></em> ] [, ... ] ) ]
+[ USING <em class="replaceable"><code>method</code></em> ]
+[ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em>
+ OF <em class="replaceable"><code>type_name</code></em> [ (
+ { <em class="replaceable"><code>column_name</code></em> [ WITH OPTIONS ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ | <em class="replaceable"><code>table_constraint</code></em> }
+ [, ... ]
+) ]
+[ PARTITION BY { RANGE | LIST | HASH } ( { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>opclass</code></em> ] [, ... ] ) ]
+[ USING <em class="replaceable"><code>method</code></em> ]
+[ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em>
+ PARTITION OF <em class="replaceable"><code>parent_table</code></em> [ (
+ { <em class="replaceable"><code>column_name</code></em> [ WITH OPTIONS ] [ <em class="replaceable"><code>column_constraint</code></em> [ ... ] ]
+ | <em class="replaceable"><code>table_constraint</code></em> }
+ [, ... ]
+) ] { FOR VALUES <em class="replaceable"><code>partition_bound_spec</code></em> | DEFAULT }
+[ PARTITION BY { RANGE | LIST | HASH } ( { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>opclass</code></em> ] [, ... ] ) ]
+[ USING <em class="replaceable"><code>method</code></em> ]
+[ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+
+<span class="phrase">where <em class="replaceable"><code>column_constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+{ NOT NULL |
+ NULL |
+ CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] |
+ DEFAULT <em class="replaceable"><code>default_expr</code></em> |
+ GENERATED ALWAYS AS ( <em class="replaceable"><code>generation_expr</code></em> ) STORED |
+ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <em class="replaceable"><code>sequence_options</code></em> ) ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] <em class="replaceable"><code>index_parameters</code></em> |
+ PRIMARY KEY <em class="replaceable"><code>index_parameters</code></em> |
+ REFERENCES <em class="replaceable"><code>reftable</code></em> [ ( <em class="replaceable"><code>refcolumn</code></em> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+ [ ON DELETE <em class="replaceable"><code>referential_action</code></em> ] [ ON UPDATE <em class="replaceable"><code>referential_action</code></em> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<span class="phrase">and <em class="replaceable"><code>table_constraint</code></em> is:</span>
+
+[ CONSTRAINT <em class="replaceable"><code>constraint_name</code></em> ]
+{ CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> |
+ PRIMARY KEY ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> |
+ EXCLUDE [ USING <em class="replaceable"><code>index_method</code></em> ] ( <em class="replaceable"><code>exclude_element</code></em> WITH <em class="replaceable"><code>operator</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> [ WHERE ( <em class="replaceable"><code>predicate</code></em> ) ] |
+ FOREIGN KEY ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) REFERENCES <em class="replaceable"><code>reftable</code></em> [ ( <em class="replaceable"><code>refcolumn</code></em> [, ... ] ) ]
+ [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <em class="replaceable"><code>referential_action</code></em> ] [ ON UPDATE <em class="replaceable"><code>referential_action</code></em> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<span class="phrase">and <em class="replaceable"><code>like_option</code></em> is:</span>
+
+{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+
+<span class="phrase">and <em class="replaceable"><code>partition_bound_spec</code></em> is:</span>
+
+IN ( <em class="replaceable"><code>partition_bound_expr</code></em> [, ...] ) |
+FROM ( { <em class="replaceable"><code>partition_bound_expr</code></em> | MINVALUE | MAXVALUE } [, ...] )
+ TO ( { <em class="replaceable"><code>partition_bound_expr</code></em> | MINVALUE | MAXVALUE } [, ...] ) |
+WITH ( MODULUS <em class="replaceable"><code>numeric_literal</code></em>, REMAINDER <em class="replaceable"><code>numeric_literal</code></em> )
+
+<span class="phrase"><em class="replaceable"><code>index_parameters</code></em> in <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY KEY</code>, and <code class="literal">EXCLUDE</code> constraints are:</span>
+
+[ INCLUDE ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ]
+[ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
+[ USING INDEX TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+
+<span class="phrase"><em class="replaceable"><code>exclude_element</code></em> in an <code class="literal">EXCLUDE</code> constraint is:</span>
+
+{ <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ <em class="replaceable"><code>opclass</code></em> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
+
+<span class="phrase"><em class="replaceable"><code>referential_action</code></em> in a <code class="literal">FOREIGN KEY</code>/<code class="literal">REFERENCES</code> constraint is:</span>
+
+{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ] | SET DEFAULT [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ] }
+</pre></div><div class="refsect1" id="SQL-CREATETABLE-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE TABLE</code> will create a new, initially empty table
+ in the current database. The table will be owned by the user issuing the
+ command.
+ </p><p>
+ If a schema name is given (for example, <code class="literal">CREATE TABLE
+ myschema.mytable ...</code>) then the table is created in the specified
+ schema. Otherwise it is created in the current schema. Temporary
+ tables exist in a special schema, so a schema name cannot be given
+ when creating a temporary table. The name of the table must be
+ distinct from the name of any other relation (table, sequence, index, view,
+ materialized view, or foreign table) in the same schema.
+ </p><p>
+ <code class="command">CREATE TABLE</code> also automatically creates a data
+ type that represents the composite type corresponding
+ to one row of the table. Therefore, tables cannot have the same
+ name as any existing data type in the same schema.
+ </p><p>
+ The optional constraint clauses specify constraints (tests) that
+ new or updated rows must satisfy for an insert or update operation
+ to succeed. A constraint is an SQL object that helps define the
+ set of valid values in the table in various ways.
+ </p><p>
+ There are two ways to define constraints: table constraints and
+ column constraints. A column constraint is defined as part of a
+ column definition. A table constraint definition is not tied to a
+ particular column, and it can encompass more than one column.
+ Every column constraint can also be written as a table constraint;
+ a column constraint is only a notational convenience for use when the
+ constraint only affects one column.
+ </p><p>
+ To be able to create a table, you must have <code class="literal">USAGE</code>
+ privilege on all column types or the type in the <code class="literal">OF</code>
+ clause, respectively.
+ </p></div><div class="refsect1" id="id-1.9.3.85.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt id="SQL-CREATETABLE-TEMPORARY"><span class="term"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></span></dt><dd><p>
+ If specified, the table is created as a temporary table.
+ Temporary tables are automatically dropped at the end of a
+ session, or optionally at the end of the current transaction
+ (see <code class="literal">ON COMMIT</code> below). The default
+ search_path includes the temporary schema first and so identically
+ named existing permanent tables are not chosen for new plans
+ while the temporary table exists, unless they are referenced
+ with schema-qualified names. Any indexes created on a temporary
+ table are automatically temporary as well.
+ </p><p>
+ The <a class="link" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">autovacuum daemon</a> cannot
+ access and therefore cannot vacuum or analyze temporary tables.
+ For this reason, appropriate vacuum and analyze operations should be
+ performed via session SQL commands. For example, if a temporary
+ table is going to be used in complex queries, it is wise to run
+ <code class="command">ANALYZE</code> on the temporary table after it is populated.
+ </p><p>
+ Optionally, <code class="literal">GLOBAL</code> or <code class="literal">LOCAL</code>
+ can be written before <code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code>.
+ This presently makes no difference in <span class="productname">PostgreSQL</span>
+ and is deprecated; see
+ <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-COMPATIBILITY" title="Compatibility">Compatibility</a> below.
+ </p></dd><dt id="SQL-CREATETABLE-UNLOGGED"><span class="term"><code class="literal">UNLOGGED</code></span></dt><dd><p>
+ If specified, the table is created as an unlogged table. Data written
+ to unlogged tables is not written to the write-ahead log (see <a class="xref" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Chapter 30</a>), which makes them considerably faster than ordinary
+ tables. However, they are not crash-safe: an unlogged table is
+ automatically truncated after a crash or unclean shutdown. The contents
+ of an unlogged table are also not replicated to standby servers.
+ Any indexes created on an unlogged table are automatically unlogged as
+ well.
+ </p><p>
+ If this is specified, any sequences created together with the unlogged
+ table (for identity or serial columns) are also created as unlogged.
+ </p></dd><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing relation is anything like the one that would have been
+ created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to be created.
+ </p></dd><dt><span class="term"><code class="literal">OF <em class="replaceable"><code>type_name</code></em></code></span></dt><dd><p>
+ Creates a <em class="firstterm">typed table</em>, which takes its
+ structure from the specified composite type (name optionally
+ schema-qualified). A typed table is tied to its type; for
+ example the table will be dropped if the type is dropped
+ (with <code class="literal">DROP TYPE ... CASCADE</code>).
+ </p><p>
+ When a typed table is created, then the data types of the
+ columns are determined by the underlying composite type and are
+ not specified by the <code class="literal">CREATE TABLE</code> command.
+ But the <code class="literal">CREATE TABLE</code> command can add defaults
+ and constraints to the table and can specify storage parameters.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column to be created in the new table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The data type of the column. This can include array
+ specifiers. For more information on the data types supported by
+ <span class="productname">PostgreSQL</span>, refer to <a class="xref" href="datatype.html" title="Chapter 8. Data Types">Chapter 8</a>.
+ </p></dd><dt><span class="term"><code class="literal">COLLATE <em class="replaceable"><code>collation</code></em></code></span></dt><dd><p>
+ The <code class="literal">COLLATE</code> clause assigns a collation to
+ the column (which must be of a collatable data type).
+ If not specified, the column data type's default collation is used.
+ </p></dd><dt><span class="term"><code class="literal">COMPRESSION <em class="replaceable"><code>compression_method</code></em></code></span></dt><dd><p>
+ The <code class="literal">COMPRESSION</code> clause sets the compression method
+ for the column. Compression is supported only for variable-width data
+ types, and is used only when the column's storage mode
+ is <code class="literal">main</code> or <code class="literal">extended</code>.
+ (See <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a> for information on
+ column storage modes.) Setting this property for a partitioned table
+ has no direct effect, because such tables have no storage of their own,
+ but the configured value will be inherited by newly-created partitions.
+ The supported compression methods are <code class="literal">pglz</code> and
+ <code class="literal">lz4</code>. (<code class="literal">lz4</code> is available only if
+ <code class="option">--with-lz4</code> was used when building
+ <span class="productname">PostgreSQL</span>.) In addition,
+ <em class="replaceable"><code>compression_method</code></em>
+ can be <code class="literal">default</code> to explicitly specify the default
+ behavior, which is to consult the
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TOAST-COMPRESSION">default_toast_compression</a> setting at the time of
+ data insertion to determine the method to use.
+ </p></dd><dt><span class="term"><code class="literal">INHERITS ( <em class="replaceable"><code>parent_table</code></em> [, ... ] )</code></span></dt><dd><p>
+ The optional <code class="literal">INHERITS</code> clause specifies a list of
+ tables from which the new table automatically inherits all
+ columns. Parent tables can be plain tables or foreign tables.
+ </p><p>
+ Use of <code class="literal">INHERITS</code> creates a persistent relationship
+ between the new child table and its parent table(s). Schema
+ modifications to the parent(s) normally propagate to children
+ as well, and by default the data of the child table is included in
+ scans of the parent(s).
+ </p><p>
+ If the same column name exists in more than one parent
+ table, an error is reported unless the data types of the columns
+ match in each of the parent tables. If there is no conflict,
+ then the duplicate columns are merged to form a single column in
+ the new table. If the column name list of the new table
+ contains a column name that is also inherited, the data type must
+ likewise match the inherited column(s), and the column
+ definitions are merged into one. If the
+ new table explicitly specifies a default value for the column,
+ this default overrides any defaults from inherited declarations
+ of the column. Otherwise, any parents that specify default
+ values for the column must all specify the same default, or an
+ error will be reported.
+ </p><p>
+ <code class="literal">CHECK</code> constraints are merged in essentially the same way as
+ columns: if multiple parent tables and/or the new table definition
+ contain identically-named <code class="literal">CHECK</code> constraints, these
+ constraints must all have the same check expression, or an error will be
+ reported. Constraints having the same name and expression will
+ be merged into one copy. A constraint marked <code class="literal">NO INHERIT</code> in a
+ parent will not be considered. Notice that an unnamed <code class="literal">CHECK</code>
+ constraint in the new table will never be merged, since a unique name
+ will always be chosen for it.
+ </p><p>
+ Column <code class="literal">STORAGE</code> settings are also copied from parent tables.
+ </p><p>
+ If a column in the parent table is an identity column, that property is
+ not inherited. A column in the child table can be declared identity
+ column if desired.
+ </p></dd><dt><span class="term"><code class="literal">PARTITION BY { RANGE | LIST | HASH } ( { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ <em class="replaceable"><code>opclass</code></em> ] [, ...] ) </code></span></dt><dd><p>
+ The optional <code class="literal">PARTITION BY</code> clause specifies a strategy
+ of partitioning the table. The table thus created is called a
+ <em class="firstterm">partitioned</em> table. The parenthesized list of
+ columns or expressions forms the <em class="firstterm">partition key</em>
+ for the table. When using range or hash partitioning, the partition key
+ can include multiple columns or expressions (up to 32, but this limit can
+ be altered when building <span class="productname">PostgreSQL</span>), but for
+ list partitioning, the partition key must consist of a single column or
+ expression.
+ </p><p>
+ Range and list partitioning require a btree operator class, while hash
+ partitioning requires a hash operator class. If no operator class is
+ specified explicitly, the default operator class of the appropriate
+ type will be used; if no default operator class exists, an error will
+ be raised. When hash partitioning is used, the operator class used
+ must implement support function 2 (see <a class="xref" href="xindex.html#XINDEX-SUPPORT" title="38.16.3. Index Method Support Routines">Section 38.16.3</a>
+ for details).
+ </p><p>
+ A partitioned table is divided into sub-tables (called partitions),
+ which are created using separate <code class="literal">CREATE TABLE</code> commands.
+ The partitioned table is itself empty. A data row inserted into the
+ table is routed to a partition based on the value of columns or
+ expressions in the partition key. If no existing partition matches
+ the values in the new row, an error will be reported.
+ </p><p>
+ Partitioned tables do not support <code class="literal">EXCLUDE</code> constraints;
+ however, you can define these constraints on individual partitions.
+ </p><p>
+ See <a class="xref" href="ddl-partitioning.html" title="5.11. Table Partitioning">Section 5.11</a> for more discussion on table
+ partitioning.
+ </p></dd><dt id="SQL-CREATETABLE-PARTITION"><span class="term"><code class="literal">PARTITION OF <em class="replaceable"><code>parent_table</code></em> { FOR VALUES <em class="replaceable"><code>partition_bound_spec</code></em> | DEFAULT }</code></span></dt><dd><p>
+ Creates the table as a <em class="firstterm">partition</em> of the specified
+ parent table. The table can be created either as a partition for specific
+ values using <code class="literal">FOR VALUES</code> or as a default partition
+ using <code class="literal">DEFAULT</code>. Any indexes, constraints and
+ user-defined row-level triggers that exist in the parent table are cloned
+ on the new partition.
+ </p><p>
+ The <em class="replaceable"><code>partition_bound_spec</code></em>
+ must correspond to the partitioning method and partition key of the
+ parent table, and must not overlap with any existing partition of that
+ parent. The form with <code class="literal">IN</code> is used for list partitioning,
+ the form with <code class="literal">FROM</code> and <code class="literal">TO</code> is used
+ for range partitioning, and the form with <code class="literal">WITH</code> is used
+ for hash partitioning.
+ </p><p>
+ <em class="replaceable"><code>partition_bound_expr</code></em> is
+ any variable-free expression (subqueries, window functions, aggregate
+ functions, and set-returning functions are not allowed). Its data type
+ must match the data type of the corresponding partition key column.
+ The expression is evaluated once at table creation time, so it can
+ even contain volatile expressions such as
+ <code class="literal"><code class="function">CURRENT_TIMESTAMP</code></code>.
+ </p><p>
+ When creating a list partition, <code class="literal">NULL</code> can be
+ specified to signify that the partition allows the partition key
+ column to be null. However, there cannot be more than one such
+ list partition for a given parent table. <code class="literal">NULL</code>
+ cannot be specified for range partitions.
+ </p><p>
+ When creating a range partition, the lower bound specified with
+ <code class="literal">FROM</code> is an inclusive bound, whereas the upper
+ bound specified with <code class="literal">TO</code> is an exclusive bound.
+ That is, the values specified in the <code class="literal">FROM</code> list
+ are valid values of the corresponding partition key columns for this
+ partition, whereas those in the <code class="literal">TO</code> list are
+ not. Note that this statement must be understood according to the
+ rules of row-wise comparison (<a class="xref" href="functions-comparisons.html#ROW-WISE-COMPARISON" title="9.24.5. Row Constructor Comparison">Section 9.24.5</a>).
+ For example, given <code class="literal">PARTITION BY RANGE (x,y)</code>, a partition
+ bound <code class="literal">FROM (1, 2) TO (3, 4)</code>
+ allows <code class="literal">x=1</code> with any <code class="literal">y&gt;=2</code>,
+ <code class="literal">x=2</code> with any non-null <code class="literal">y</code>,
+ and <code class="literal">x=3</code> with any <code class="literal">y&lt;4</code>.
+ </p><p>
+ The special values <code class="literal">MINVALUE</code> and <code class="literal">MAXVALUE</code>
+ may be used when creating a range partition to indicate that there
+ is no lower or upper bound on the column's value. For example, a
+ partition defined using <code class="literal">FROM (MINVALUE) TO (10)</code> allows
+ any values less than 10, and a partition defined using
+ <code class="literal">FROM (10) TO (MAXVALUE)</code> allows any values greater than
+ or equal to 10.
+ </p><p>
+ When creating a range partition involving more than one column, it
+ can also make sense to use <code class="literal">MAXVALUE</code> as part of the lower
+ bound, and <code class="literal">MINVALUE</code> as part of the upper bound. For
+ example, a partition defined using
+ <code class="literal">FROM (0, MAXVALUE) TO (10, MAXVALUE)</code> allows any rows
+ where the first partition key column is greater than 0 and less than
+ or equal to 10. Similarly, a partition defined using
+ <code class="literal">FROM ('a', MINVALUE) TO ('b', MINVALUE)</code> allows any rows
+ where the first partition key column starts with "a".
+ </p><p>
+ Note that if <code class="literal">MINVALUE</code> or <code class="literal">MAXVALUE</code> is used for
+ one column of a partitioning bound, the same value must be used for all
+ subsequent columns. For example, <code class="literal">(10, MINVALUE, 0)</code> is not
+ a valid bound; you should write <code class="literal">(10, MINVALUE, MINVALUE)</code>.
+ </p><p>
+ Also note that some element types, such as <code class="literal">timestamp</code>,
+ have a notion of "infinity", which is just another value that can
+ be stored. This is different from <code class="literal">MINVALUE</code> and
+ <code class="literal">MAXVALUE</code>, which are not real values that can be stored,
+ but rather they are ways of saying that the value is unbounded.
+ <code class="literal">MAXVALUE</code> can be thought of as being greater than any
+ other value, including "infinity" and <code class="literal">MINVALUE</code> as being
+ less than any other value, including "minus infinity". Thus the range
+ <code class="literal">FROM ('infinity') TO (MAXVALUE)</code> is not an empty range; it
+ allows precisely one value to be stored — "infinity".
+ </p><p>
+ If <code class="literal">DEFAULT</code> is specified, the table will be
+ created as the default partition of the parent table. This option
+ is not available for hash-partitioned tables. A partition key value
+ not fitting into any other partition of the given parent will be
+ routed to the default partition.
+ </p><p>
+ When a table has an existing <code class="literal">DEFAULT</code> partition and
+ a new partition is added to it, the default partition must
+ be scanned to verify that it does not contain any rows which properly
+ belong in the new partition. If the default partition contains a
+ large number of rows, this may be slow. The scan will be skipped if
+ the default partition is a foreign table or if it has a constraint which
+ proves that it cannot contain rows which should be placed in the new
+ partition.
+ </p><p>
+ When creating a hash partition, a modulus and remainder must be specified.
+ The modulus must be a positive integer, and the remainder must be a
+ non-negative integer less than the modulus. Typically, when initially
+ setting up a hash-partitioned table, you should choose a modulus equal to
+ the number of partitions and assign every table the same modulus and a
+ different remainder (see examples, below). However, it is not required
+ that every partition have the same modulus, only that every modulus which
+ occurs among the partitions of a hash-partitioned table is a factor of the
+ next larger modulus. This allows the number of partitions to be increased
+ incrementally without needing to move all the data at once. For example,
+ suppose you have a hash-partitioned table with 8 partitions, each of which
+ has modulus 8, but find it necessary to increase the number of partitions
+ to 16. You can detach one of the modulus-8 partitions, create two new
+ modulus-16 partitions covering the same portion of the key space (one with
+ a remainder equal to the remainder of the detached partition, and the
+ other with a remainder equal to that value plus 8), and repopulate them
+ with data. You can then repeat this -- perhaps at a later time -- for
+ each modulus-8 partition until none remain. While this may still involve
+ a large amount of data movement at each step, it is still better than
+ having to create a whole new table and move all the data at once.
+ </p><p>
+ A partition must have the same column names and types as the partitioned
+ table to which it belongs. Modifications to the column names or types of
+ a partitioned table will automatically propagate to all partitions.
+ <code class="literal">CHECK</code> constraints will be inherited automatically by
+ every partition, but an individual partition may specify additional
+ <code class="literal">CHECK</code> constraints; additional constraints with the
+ same name and condition as in the parent will be merged with the parent
+ constraint. Defaults may be specified separately for each partition.
+ But note that a partition's default value is not applied when inserting
+ a tuple through a partitioned table.
+ </p><p>
+ Rows inserted into a partitioned table will be automatically routed to
+ the correct partition. If no suitable partition exists, an error will
+ occur.
+ </p><p>
+ Operations such as <code class="command">TRUNCATE</code>
+ which normally affect a table and all of its
+ inheritance children will cascade to all partitions, but may also be
+ performed on an individual partition.
+ </p><p>
+ Note that creating a partition using <code class="literal">PARTITION OF</code>
+ requires taking an <code class="literal">ACCESS EXCLUSIVE</code> lock on the
+ parent partitioned table. Likewise, dropping a partition
+ with <code class="command">DROP TABLE</code> requires taking
+ an <code class="literal">ACCESS EXCLUSIVE</code> lock on the parent table.
+ It is possible to use <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER
+ TABLE ATTACH/DETACH PARTITION</code></a> to perform these
+ operations with a weaker lock, thus reducing interference with
+ concurrent operations on the partitioned table.
+ </p></dd><dt><span class="term"><code class="literal">LIKE <em class="replaceable"><code>source_table</code></em> [ <em class="replaceable"><code>like_option</code></em> ... ]</code></span></dt><dd><p>
+ The <code class="literal">LIKE</code> clause specifies a table from which
+ the new table automatically copies all column names, their data types,
+ and their not-null constraints.
+ </p><p>
+ Unlike <code class="literal">INHERITS</code>, the new table and original table
+ are completely decoupled after creation is complete. Changes to the
+ original table will not be applied to the new table, and it is not
+ possible to include data of the new table in scans of the original
+ table.
+ </p><p>
+ Also unlike <code class="literal">INHERITS</code>, columns and
+ constraints copied by <code class="literal">LIKE</code> are not merged with similarly
+ named columns and constraints.
+ If the same name is specified explicitly or in another
+ <code class="literal">LIKE</code> clause, an error is signaled.
+ </p><p>
+ The optional <em class="replaceable"><code>like_option</code></em> clauses specify
+ which additional properties of the original table to copy. Specifying
+ <code class="literal">INCLUDING</code> copies the property, specifying
+ <code class="literal">EXCLUDING</code> omits the property.
+ <code class="literal">EXCLUDING</code> is the default. If multiple specifications
+ are made for the same kind of object, the last one is used. The
+ available options are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">INCLUDING COMMENTS</code></span></dt><dd><p>
+ Comments for the copied columns, constraints, and indexes will be
+ copied. The default behavior is to exclude comments, resulting in
+ the copied columns and constraints in the new table having no
+ comments.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING COMPRESSION</code></span></dt><dd><p>
+ Compression method of the columns will be copied. The default
+ behavior is to exclude compression methods, resulting in columns
+ having the default compression method.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING CONSTRAINTS</code></span></dt><dd><p>
+ <code class="literal">CHECK</code> constraints will be copied. No distinction
+ is made between column constraints and table constraints. Not-null
+ constraints are always copied to the new table.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING DEFAULTS</code></span></dt><dd><p>
+ Default expressions for the copied column definitions will be
+ copied. Otherwise, default expressions are not copied, resulting in
+ the copied columns in the new table having null defaults. Note that
+ copying defaults that call database-modification functions, such as
+ <code class="function">nextval</code>, may create a functional linkage
+ between the original and new tables.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING GENERATED</code></span></dt><dd><p>
+ Any generation expressions of copied column definitions will be
+ copied. By default, new columns will be regular base columns.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING IDENTITY</code></span></dt><dd><p>
+ Any identity specifications of copied column definitions will be
+ copied. A new sequence is created for each identity column of the
+ new table, separate from the sequences associated with the old
+ table.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING INDEXES</code></span></dt><dd><p>
+ Indexes, <code class="literal">PRIMARY KEY</code>, <code class="literal">UNIQUE</code>,
+ and <code class="literal">EXCLUDE</code> constraints on the original table
+ will be created on the new table. Names for the new indexes and
+ constraints are chosen according to the default rules, regardless of
+ how the originals were named. (This behavior avoids possible
+ duplicate-name failures for the new indexes.)
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING STATISTICS</code></span></dt><dd><p>
+ Extended statistics are copied to the new table.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING STORAGE</code></span></dt><dd><p>
+ <code class="literal">STORAGE</code> settings for the copied column
+ definitions will be copied. The default behavior is to exclude
+ <code class="literal">STORAGE</code> settings, resulting in the copied columns
+ in the new table having type-specific default settings. For more on
+ <code class="literal">STORAGE</code> settings, see <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a>.
+ </p></dd><dt><span class="term"><code class="literal">INCLUDING ALL</code></span></dt><dd><p>
+ <code class="literal">INCLUDING ALL</code> is an abbreviated form selecting
+ all the available individual options. (It could be useful to write
+ individual <code class="literal">EXCLUDING</code> clauses after
+ <code class="literal">INCLUDING ALL</code> to select all but some specific
+ options.)
+ </p></dd></dl></div><p>
+ </p><p>
+ The <code class="literal">LIKE</code> clause can also be used to copy column
+ definitions from views, foreign tables, or composite types.
+ Inapplicable options (e.g., <code class="literal">INCLUDING INDEXES</code> from
+ a view) are ignored.
+ </p></dd><dt><span class="term"><code class="literal">CONSTRAINT <em class="replaceable"><code>constraint_name</code></em></code></span></dt><dd><p>
+ An optional name for a column or table constraint. If the
+ constraint is violated, the constraint name is present in error messages,
+ so constraint names like <code class="literal">col must be positive</code> can be used
+ to communicate helpful constraint information to client applications.
+ (Double-quotes are needed to specify constraint names that contain spaces.)
+ If a constraint name is not specified, the system generates a name.
+ </p></dd><dt><span class="term"><code class="literal">NOT NULL</code></span></dt><dd><p>
+ The column is not allowed to contain null values.
+ </p></dd><dt><span class="term"><code class="literal">NULL</code></span></dt><dd><p>
+ The column is allowed to contain null values. This is the default.
+ </p><p>
+ This clause is only provided for compatibility with
+ non-standard SQL databases. Its use is discouraged in new
+ applications.
+ </p></dd><dt><span class="term"><code class="literal">CHECK ( <em class="replaceable"><code>expression</code></em> ) [ NO INHERIT ] </code></span></dt><dd><p>
+ The <code class="literal">CHECK</code> clause specifies an expression producing a
+ Boolean result which new or updated rows must satisfy for an
+ insert or update operation to succeed. Expressions evaluating
+ to TRUE or UNKNOWN succeed. Should any row of an insert or
+ update operation produce a FALSE result, an error exception is
+ raised and the insert or update does not alter the database. A
+ check constraint specified as a column constraint should
+ reference that column's value only, while an expression
+ appearing in a table constraint can reference multiple columns.
+ </p><p>
+ Currently, <code class="literal">CHECK</code> expressions cannot contain
+ subqueries nor refer to variables other than columns of the
+ current row (see <a class="xref" href="ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS" title="5.4.1. Check Constraints">Section 5.4.1</a>).
+ The system column <code class="literal">tableoid</code>
+ may be referenced, but not any other system column.
+ </p><p>
+ A constraint marked with <code class="literal">NO INHERIT</code> will not propagate to
+ child tables.
+ </p><p>
+ When a table has multiple <code class="literal">CHECK</code> constraints,
+ they will be tested for each row in alphabetical order by name,
+ after checking <code class="literal">NOT NULL</code> constraints.
+ (<span class="productname">PostgreSQL</span> versions before 9.5 did not honor any
+ particular firing order for <code class="literal">CHECK</code> constraints.)
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT
+ <em class="replaceable"><code>default_expr</code></em></code></span></dt><dd><p>
+ The <code class="literal">DEFAULT</code> clause assigns a default data value for
+ the column whose column definition it appears within. The value
+ is any variable-free expression (in particular, cross-references
+ to other columns in the current table are not allowed). Subqueries
+ are not allowed either. The data type of the default expression must
+ match the data type of the column.
+ </p><p>
+ The default expression will be used in any insert operation that
+ does not specify a value for the column. If there is no default
+ for a column, then the default is null.
+ </p></dd><dt><span class="term"><code class="literal">GENERATED ALWAYS AS ( <em class="replaceable"><code>generation_expr</code></em> ) STORED</code><a id="id-1.9.3.85.6.2.19.1.2" class="indexterm"></a></span></dt><dd><p>
+ This clause creates the column as a <em class="firstterm">generated
+ column</em>. The column cannot be written to, and when read the
+ result of the specified expression will be returned.
+ </p><p>
+ The keyword <code class="literal">STORED</code> is required to signify that the
+ column will be computed on write and will be stored on disk.
+ </p><p>
+ The generation expression can refer to other columns in the table, but
+ not other generated columns. Any functions and operators used must be
+ immutable. References to other tables are not allowed.
+ </p></dd><dt><span class="term"><code class="literal">GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <em class="replaceable"><code>sequence_options</code></em> ) ]</code></span></dt><dd><p>
+ This clause creates the column as an <em class="firstterm">identity
+ column</em>. It will have an implicit sequence attached to it
+ and the column in new rows will automatically have values from the
+ sequence assigned to it.
+ Such a column is implicitly <code class="literal">NOT NULL</code>.
+ </p><p>
+ The clauses <code class="literal">ALWAYS</code> and <code class="literal">BY DEFAULT</code>
+ determine how explicitly user-specified values are handled in
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> commands.
+ </p><p>
+ In an <code class="command">INSERT</code> command, if <code class="literal">ALWAYS</code> is
+ selected, a user-specified value is only accepted if the
+ <code class="command">INSERT</code> statement specifies <code class="literal">OVERRIDING SYSTEM
+ VALUE</code>. If <code class="literal">BY DEFAULT</code> is selected, then the
+ user-specified value takes precedence. See <a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>
+ for details. (In the <code class="command">COPY</code> command, user-specified
+ values are always used regardless of this setting.)
+ </p><p>
+ In an <code class="command">UPDATE</code> command, if <code class="literal">ALWAYS</code> is
+ selected, any update of the column to any value other than
+ <code class="literal">DEFAULT</code> will be rejected. If <code class="literal">BY
+ DEFAULT</code> is selected, the column can be updated normally.
+ (There is no <code class="literal">OVERRIDING</code> clause for the
+ <code class="command">UPDATE</code> command.)
+ </p><p>
+ The optional <em class="replaceable"><code>sequence_options</code></em> clause can be
+ used to override the options of the sequence.
+ See <a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a> for details.
+ </p></dd><dt><span class="term"><code class="literal">UNIQUE [ NULLS [ NOT ] DISTINCT ]</code> (column constraint)<br /></span><span class="term"><code class="literal">UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <em class="replaceable"><code>column_name</code></em> [, ... ] )</code>
+ [<span class="optional"> <code class="literal">INCLUDE ( <em class="replaceable"><code>column_name</code></em> [, ...])</code> </span>] (table constraint)</span></dt><dd><p>
+ The <code class="literal">UNIQUE</code> constraint specifies that a
+ group of one or more columns of a table can contain
+ only unique values. The behavior of a unique table constraint
+ is the same as that of a unique column constraint, with the
+ additional capability to span multiple columns. The constraint
+ therefore enforces that any two rows must differ in at least one
+ of these columns.
+ </p><p>
+ For the purpose of a unique constraint, null values are not
+ considered equal, unless <code class="literal">NULLS NOT DISTINCT</code> is
+ specified.
+ </p><p>
+ Each unique constraint should name a set of columns that is
+ different from the set of columns named by any other unique or
+ primary key constraint defined for the table. (Otherwise, redundant
+ unique constraints will be discarded.)
+ </p><p>
+ When establishing a unique constraint for a multi-level partition
+ hierarchy, all the columns in the partition key of the target
+ partitioned table, as well as those of all its descendant partitioned
+ tables, must be included in the constraint definition.
+ </p><p>
+ Adding a unique constraint will automatically create a unique btree
+ index on the column or group of columns used in the constraint.
+ </p><p>
+ The optional <code class="literal">INCLUDE</code> clause adds to that index
+ one or more columns that are simply <span class="quote">“<span class="quote">payload</span>”</span>: uniqueness
+ is not enforced on them, and the index cannot be searched on the basis
+ of those columns. However they can be retrieved by an index-only scan.
+ Note that although the constraint is not enforced on included columns,
+ it still depends on them. Consequently, some operations on such columns
+ (e.g., <code class="literal">DROP COLUMN</code>) can cause cascaded constraint and
+ index deletion.
+ </p></dd><dt><span class="term"><code class="literal">PRIMARY KEY</code> (column constraint)<br /></span><span class="term"><code class="literal">PRIMARY KEY ( <em class="replaceable"><code>column_name</code></em> [, ... ] )</code>
+ [<span class="optional"> <code class="literal">INCLUDE ( <em class="replaceable"><code>column_name</code></em> [, ...])</code> </span>] (table constraint)</span></dt><dd><p>
+ The <code class="literal">PRIMARY KEY</code> constraint specifies that a column or
+ columns of a table can contain only unique (non-duplicate), nonnull
+ values. Only one primary key can be specified for a table, whether as a
+ column constraint or a table constraint.
+ </p><p>
+ The primary key constraint should name a set of columns that is
+ different from the set of columns named by any unique
+ constraint defined for the same table. (Otherwise, the unique
+ constraint is redundant and will be discarded.)
+ </p><p>
+ <code class="literal">PRIMARY KEY</code> enforces the same data constraints as
+ a combination of <code class="literal">UNIQUE</code> and <code class="literal">NOT
+ NULL</code>. However,
+ identifying a set of columns as the primary key also provides metadata
+ about the design of the schema, since a primary key implies that other
+ tables can rely on this set of columns as a unique identifier for rows.
+ </p><p>
+ When placed on a partitioned table, <code class="literal">PRIMARY KEY</code>
+ constraints share the restrictions previously described
+ for <code class="literal">UNIQUE</code> constraints.
+ </p><p>
+ Adding a <code class="literal">PRIMARY KEY</code> constraint will automatically
+ create a unique btree index on the column or group of columns used in the
+ constraint.
+ </p><p>
+ The optional <code class="literal">INCLUDE</code> clause adds to that index
+ one or more columns that are simply <span class="quote">“<span class="quote">payload</span>”</span>: uniqueness
+ is not enforced on them, and the index cannot be searched on the basis
+ of those columns. However they can be retrieved by an index-only scan.
+ Note that although the constraint is not enforced on included columns,
+ it still depends on them. Consequently, some operations on such columns
+ (e.g., <code class="literal">DROP COLUMN</code>) can cause cascaded constraint and
+ index deletion.
+ </p></dd><dt id="SQL-CREATETABLE-EXCLUDE"><span class="term"><code class="literal">EXCLUDE [ USING <em class="replaceable"><code>index_method</code></em> ] ( <em class="replaceable"><code>exclude_element</code></em> WITH <em class="replaceable"><code>operator</code></em> [, ... ] ) <em class="replaceable"><code>index_parameters</code></em> [ WHERE ( <em class="replaceable"><code>predicate</code></em> ) ]</code></span></dt><dd><p>
+ The <code class="literal">EXCLUDE</code> clause defines an exclusion
+ constraint, which guarantees that if
+ any two rows are compared on the specified column(s) or
+ expression(s) using the specified operator(s), not all of these
+ comparisons will return <code class="literal">TRUE</code>. If all of the
+ specified operators test for equality, this is equivalent to a
+ <code class="literal">UNIQUE</code> constraint, although an ordinary unique constraint
+ will be faster. However, exclusion constraints can specify
+ constraints that are more general than simple equality.
+ For example, you can specify a constraint that
+ no two rows in the table contain overlapping circles
+ (see <a class="xref" href="datatype-geometric.html" title="8.8. Geometric Types">Section 8.8</a>) by using the
+ <code class="literal">&amp;&amp;</code> operator.
+ </p><p>
+ Exclusion constraints are implemented using
+ an index, so each specified operator must be associated with an
+ appropriate operator class
+ (see <a class="xref" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Section 11.10</a>) for the index access
+ method <em class="replaceable"><code>index_method</code></em>.
+ The operators are required to be commutative.
+ Each <em class="replaceable"><code>exclude_element</code></em>
+ can optionally specify an operator class and/or ordering options;
+ these are described fully under
+ <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>.
+ </p><p>
+ The access method must support <code class="literal">amgettuple</code> (see <a class="xref" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Chapter 64</a>); at present this means <acronym class="acronym">GIN</acronym>
+ cannot be used. Although it's allowed, there is little point in using
+ B-tree or hash indexes with an exclusion constraint, because this
+ does nothing that an ordinary unique constraint doesn't do better.
+ So in practice the access method will always be <acronym class="acronym">GiST</acronym> or
+ <acronym class="acronym">SP-GiST</acronym>.
+ </p><p>
+ The <em class="replaceable"><code>predicate</code></em> allows you to specify an
+ exclusion constraint on a subset of the table; internally this creates a
+ partial index. Note that parentheses are required around the predicate.
+ </p></dd><dt><span class="term"><code class="literal">REFERENCES <em class="replaceable"><code>reftable</code></em> [ ( <em class="replaceable"><code>refcolumn</code></em> ) ] [ MATCH <em class="replaceable"><code>matchtype</code></em> ] [ ON DELETE <em class="replaceable"><code>referential_action</code></em> ] [ ON UPDATE <em class="replaceable"><code>referential_action</code></em> ]</code> (column constraint)<br /></span><span class="term"><code class="literal">FOREIGN KEY ( <em class="replaceable"><code>column_name</code></em> [, ... ] )
+ REFERENCES <em class="replaceable"><code>reftable</code></em> [ ( <em class="replaceable"><code>refcolumn</code></em> [, ... ] ) ]
+ [ MATCH <em class="replaceable"><code>matchtype</code></em> ]
+ [ ON DELETE <em class="replaceable"><code>referential_action</code></em> ]
+ [ ON UPDATE <em class="replaceable"><code>referential_action</code></em> ]</code>
+ (table constraint)</span></dt><dd><p>
+ These clauses specify a foreign key constraint, which requires
+ that a group of one or more columns of the new table must only
+ contain values that match values in the referenced
+ column(s) of some row of the referenced table. If the <em class="replaceable"><code>refcolumn</code></em> list is omitted, the
+ primary key of the <em class="replaceable"><code>reftable</code></em>
+ is used. The referenced columns must be the columns of a non-deferrable
+ unique or primary key constraint in the referenced table. The user
+ must have <code class="literal">REFERENCES</code> permission on the referenced table
+ (either the whole table, or the specific referenced columns). The
+ addition of a foreign key constraint requires a
+ <code class="literal">SHARE ROW EXCLUSIVE</code> lock on the referenced table.
+ Note that foreign key constraints cannot be defined between temporary
+ tables and permanent tables.
+ </p><p>
+ A value inserted into the referencing column(s) is matched against the
+ values of the referenced table and referenced columns using the
+ given match type. There are three match types: <code class="literal">MATCH
+ FULL</code>, <code class="literal">MATCH PARTIAL</code>, and <code class="literal">MATCH
+ SIMPLE</code> (which is the default). <code class="literal">MATCH
+ FULL</code> will not allow one column of a multicolumn foreign key
+ to be null unless all foreign key columns are null; if they are all
+ null, the row is not required to have a match in the referenced table.
+ <code class="literal">MATCH SIMPLE</code> allows any of the foreign key columns
+ to be null; if any of them are null, the row is not required to have a
+ match in the referenced table.
+ <code class="literal">MATCH PARTIAL</code> is not yet implemented.
+ (Of course, <code class="literal">NOT NULL</code> constraints can be applied to the
+ referencing column(s) to prevent these cases from arising.)
+ </p><p>
+ In addition, when the data in the referenced columns is changed,
+ certain actions are performed on the data in this table's
+ columns. The <code class="literal">ON DELETE</code> clause specifies the
+ action to perform when a referenced row in the referenced table is
+ being deleted. Likewise, the <code class="literal">ON UPDATE</code>
+ clause specifies the action to perform when a referenced column
+ in the referenced table is being updated to a new value. If the
+ row is updated, but the referenced column is not actually
+ changed, no action is done. Referential actions other than the
+ <code class="literal">NO ACTION</code> check cannot be deferred, even if
+ the constraint is declared deferrable. There are the following possible
+ actions for each clause:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">NO ACTION</code></span></dt><dd><p>
+ Produce an error indicating that the deletion or update
+ would create a foreign key constraint violation.
+ If the constraint is deferred, this
+ error will be produced at constraint check time if there still
+ exist any referencing rows. This is the default action.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Produce an error indicating that the deletion or update
+ would create a foreign key constraint violation.
+ This is the same as <code class="literal">NO ACTION</code> except that
+ the check is not deferrable.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Delete any rows referencing the deleted row, or update the
+ values of the referencing column(s) to the new values of the
+ referenced columns, respectively.
+ </p></dd><dt><span class="term"><code class="literal">SET NULL [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ]</code></span></dt><dd><p>
+ Set all of the referencing columns, or a specified subset of the
+ referencing columns, to null. A subset of columns can only be
+ specified for <code class="literal">ON DELETE</code> actions.
+ </p></dd><dt><span class="term"><code class="literal">SET DEFAULT [ ( <em class="replaceable"><code>column_name</code></em> [, ... ] ) ]</code></span></dt><dd><p>
+ Set all of the referencing columns, or a specified subset of the
+ referencing columns, to their default values. A subset of columns
+ can only be specified for <code class="literal">ON DELETE</code> actions.
+ (There must be a row in the referenced table matching the default
+ values, if they are not null, or the operation will fail.)
+ </p></dd></dl></div><p>
+ </p><p>
+ If the referenced column(s) are changed frequently, it might be wise to
+ add an index to the referencing column(s) so that referential actions
+ associated with the foreign key constraint can be performed more
+ efficiently.
+ </p></dd><dt><span class="term"><code class="literal">DEFERRABLE</code><br /></span><span class="term"><code class="literal">NOT DEFERRABLE</code></span></dt><dd><p>
+ This controls whether the constraint can be deferred. A
+ constraint that is not deferrable will be checked immediately
+ after every command. Checking of constraints that are
+ deferrable can be postponed until the end of the transaction
+ (using the <a class="link" href="sql-set-constraints.html" title="SET CONSTRAINTS"><code class="command">SET CONSTRAINTS</code></a> command).
+ <code class="literal">NOT DEFERRABLE</code> is the default.
+ Currently, only <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY KEY</code>,
+ <code class="literal">EXCLUDE</code>, and
+ <code class="literal">REFERENCES</code> (foreign key) constraints accept this
+ clause. <code class="literal">NOT NULL</code> and <code class="literal">CHECK</code> constraints are not
+ deferrable. Note that deferrable constraints cannot be used as
+ conflict arbitrators in an <code class="command">INSERT</code> statement that
+ includes an <code class="literal">ON CONFLICT DO UPDATE</code> clause.
+ </p></dd><dt><span class="term"><code class="literal">INITIALLY IMMEDIATE</code><br /></span><span class="term"><code class="literal">INITIALLY DEFERRED</code></span></dt><dd><p>
+ If a constraint is deferrable, this clause specifies the default
+ time to check the constraint. If the constraint is
+ <code class="literal">INITIALLY IMMEDIATE</code>, it is checked after each
+ statement. This is the default. If the constraint is
+ <code class="literal">INITIALLY DEFERRED</code>, it is checked only at the
+ end of the transaction. The constraint check time can be
+ altered with the <a class="link" href="sql-set-constraints.html" title="SET CONSTRAINTS"><code class="command">SET CONSTRAINTS</code></a> command.
+ </p></dd><dt id="SQL-CREATETABLE-METHOD"><span class="term"><code class="literal">USING <em class="replaceable"><code>method</code></em></code></span></dt><dd><p>
+ This optional clause specifies the table access method to use to store
+ the contents for the new table; the method needs be an access method of
+ type <code class="literal">TABLE</code>. See <a class="xref" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Chapter 63</a> for more
+ information. If this option is not specified, the default table access
+ method is chosen for the new table. See <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLE-ACCESS-METHOD">default_table_access_method</a> for more information.
+ </p></dd><dt><span class="term"><code class="literal">WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause specifies optional storage parameters for a table or index;
+ see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" title="Storage Parameters">Storage Parameters</a> below for more
+ information. For backward-compatibility the <code class="literal">WITH</code>
+ clause for a table can also include <code class="literal">OIDS=FALSE</code> to
+ specify that rows of the new table should not contain OIDs (object
+ identifiers), <code class="literal">OIDS=TRUE</code> is not supported anymore.
+ </p></dd><dt><span class="term"><code class="literal">WITHOUT OIDS</code></span></dt><dd><p>
+ This is backward-compatible syntax for declaring a table
+ <code class="literal">WITHOUT OIDS</code>, creating a table <code class="literal">WITH
+ OIDS</code> is not supported anymore.
+ </p></dd><dt><span class="term"><code class="literal">ON COMMIT</code></span></dt><dd><p>
+ The behavior of temporary tables at the end of a transaction
+ block can be controlled using <code class="literal">ON COMMIT</code>.
+ The three options are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">PRESERVE ROWS</code></span></dt><dd><p>
+ No special action is taken at the ends of transactions.
+ This is the default behavior.
+ </p></dd><dt><span class="term"><code class="literal">DELETE ROWS</code></span></dt><dd><p>
+ All rows in the temporary table will be deleted at the end
+ of each transaction block. Essentially, an automatic <a class="link" href="sql-truncate.html" title="TRUNCATE"><code class="command">TRUNCATE</code></a> is done
+ at each commit. When used on a partitioned table, this
+ is not cascaded to its partitions.
+ </p></dd><dt><span class="term"><code class="literal">DROP</code></span></dt><dd><p>
+ The temporary table will be dropped at the end of the current
+ transaction block. When used on a partitioned table, this action
+ drops its partitions and when used on tables with inheritance
+ children, it drops the dependent children.
+ </p></dd></dl></div></dd><dt id="SQL-CREATETABLE-TABLESPACE"><span class="term"><code class="literal">TABLESPACE <em class="replaceable"><code>tablespace_name</code></em></code></span></dt><dd><p>
+ The <em class="replaceable"><code>tablespace_name</code></em> is the name
+ of the tablespace in which the new table is to be created.
+ If not specified,
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> is consulted, or
+ <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> if the table is temporary. For
+ partitioned tables, since no storage is required for the table itself,
+ the tablespace specified overrides <code class="literal">default_tablespace</code>
+ as the default tablespace to use for any newly created partitions when no
+ other tablespace is explicitly specified.
+ </p></dd><dt><span class="term"><code class="literal">USING INDEX TABLESPACE <em class="replaceable"><code>tablespace_name</code></em></code></span></dt><dd><p>
+ This clause allows selection of the tablespace in which the index
+ associated with a <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY
+ KEY</code>, or <code class="literal">EXCLUDE</code> constraint will be created.
+ If not specified,
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> is consulted, or
+ <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> if the table is temporary.
+ </p></dd></dl></div><div class="refsect2" id="SQL-CREATETABLE-STORAGE-PARAMETERS"><h3>Storage Parameters</h3><a id="id-1.9.3.85.6.3.2" class="indexterm"></a><p>
+ The <code class="literal">WITH</code> clause can specify <em class="firstterm">storage parameters</em>
+ for tables, and for indexes associated with a <code class="literal">UNIQUE</code>,
+ <code class="literal">PRIMARY KEY</code>, or <code class="literal">EXCLUDE</code> constraint.
+ Storage parameters for
+ indexes are documented in <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>.
+ The storage parameters currently
+ available for tables are listed below. For many of these parameters, as
+ shown, there is an additional parameter with the same name prefixed with
+ <code class="literal">toast.</code>, which controls the behavior of the
+ table's secondary <acronym class="acronym">TOAST</acronym> table, if any
+ (see <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a> for more information about TOAST).
+ If a table parameter value is set and the
+ equivalent <code class="literal">toast.</code> parameter is not, the TOAST table
+ will use the table's parameter value.
+ Specifying these parameters for partitioned tables is not supported,
+ but you may specify them for individual leaf partitions.
+ </p><div class="variablelist"><dl class="variablelist"><dt id="RELOPTION-FILLFACTOR"><span class="term"><code class="varname">fillfactor</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.1.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The fillfactor for a table is a percentage between 10 and 100.
+ 100 (complete packing) is the default. When a smaller fillfactor
+ is specified, <code class="command">INSERT</code> operations pack table pages only
+ to the indicated percentage; the remaining space on each page is
+ reserved for updating rows on that page. This gives <code class="command">UPDATE</code>
+ a chance to place the updated copy of a row on the same page as the
+ original, which is more efficient than placing it on a different
+ page, and makes <a class="link" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">heap-only tuple
+ updates</a> more likely.
+ For a table whose entries are never updated, complete packing is the
+ best choice, but in heavily updated tables smaller fillfactors are
+ appropriate. This parameter cannot be set for TOAST tables.
+ </p></dd><dt id="RELOPTION-TOAST-TUPLE-TARGET"><span class="term"><code class="literal">toast_tuple_target</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.2.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ The toast_tuple_target specifies the minimum tuple length required before
+ we try to compress and/or move long column values into TOAST tables, and
+ is also the target length we try to reduce the length below once toasting
+ begins. This affects columns marked as External (for move),
+ Main (for compression), or Extended (for both) and applies only to new
+ tuples. There is no effect on existing rows.
+ By default this parameter is set to allow at least 4 tuples per block,
+ which with the default block size will be 2040 bytes. Valid values are
+ between 128 bytes and the (block size - header), by default 8160 bytes.
+ Changing this value may not be useful for very short or very long rows.
+ Note that the default setting is often close to optimal, and
+ it is possible that setting this parameter could have negative
+ effects in some cases.
+ This parameter cannot be set for TOAST tables.
+ </p></dd><dt id="RELOPTION-PARALLEL-WORKERS"><span class="term"><code class="literal">parallel_workers</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.3.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This sets the number of workers that should be used to assist a parallel
+ scan of this table. If not set, the system will determine a value based
+ on the relation size. The actual number of workers chosen by the planner
+ or by utility statements that use parallel scans may be less, for example
+ due to the setting of <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-ENABLED"><span class="term"><code class="literal">autovacuum_enabled</code>, <code class="literal">toast.autovacuum_enabled</code> (<code class="type">boolean</code>)
+ <a id="id-1.9.3.85.6.3.4.4.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables the autovacuum daemon for a particular table.
+ If true, the autovacuum daemon will perform automatic <code class="command">VACUUM</code>
+ and/or <code class="command">ANALYZE</code> operations on this table following the rules
+ discussed in <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>.
+ If false, this table will not be autovacuumed, except to prevent
+ transaction ID wraparound. See <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a> for
+ more about wraparound prevention.
+ Note that the autovacuum daemon does not run at all (except to prevent
+ transaction ID wraparound) if the <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM">autovacuum</a>
+ parameter is false; setting individual tables' storage parameters does
+ not override that. Therefore there is seldom much point in explicitly
+ setting this storage parameter to <code class="literal">true</code>, only
+ to <code class="literal">false</code>.
+ </p></dd><dt id="RELOPTION-VACUUM-INDEX-CLEANUP"><span class="term"><code class="literal">vacuum_index_cleanup</code>, <code class="literal">toast.vacuum_index_cleanup</code> (<code class="type">enum</code>)
+ <a id="id-1.9.3.85.6.3.4.5.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Forces or disables index cleanup when <code class="command">VACUUM</code>
+ is run on this table. The default value is
+ <code class="literal">AUTO</code>. With <code class="literal">OFF</code>, index
+ cleanup is disabled, with <code class="literal">ON</code> it is enabled,
+ and with <code class="literal">AUTO</code> a decision is made dynamically,
+ each time <code class="command">VACUUM</code> runs. The dynamic behavior
+ allows <code class="command">VACUUM</code> to avoid needlessly scanning
+ indexes to remove very few dead tuples. Forcibly disabling all
+ index cleanup can speed up <code class="command">VACUUM</code> very
+ significantly, but may also lead to severely bloated indexes if
+ table modifications are frequent. The
+ <code class="literal">INDEX_CLEANUP</code> parameter of <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>, if
+ specified, overrides the value of this option.
+ </p></dd><dt id="RELOPTION-VACUUM-TRUNCATE"><span class="term"><code class="literal">vacuum_truncate</code>, <code class="literal">toast.vacuum_truncate</code> (<code class="type">boolean</code>)
+ <a id="id-1.9.3.85.6.3.4.6.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Enables or disables vacuum to try to truncate off any empty pages
+ at the end of this table. The default value is <code class="literal">true</code>.
+ If <code class="literal">true</code>, <code class="command">VACUUM</code> and
+ autovacuum do the truncation and the disk space for
+ the truncated pages is returned to the operating system.
+ Note that the truncation requires <code class="literal">ACCESS EXCLUSIVE</code>
+ lock on the table. The <code class="literal">TRUNCATE</code> parameter
+ of <a class="link" href="sql-vacuum.html" title="VACUUM"><code class="command">VACUUM</code></a>, if specified, overrides the value
+ of this option.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-VACUUM-THRESHOLD"><span class="term"><code class="literal">autovacuum_vacuum_threshold</code>, <code class="literal">toast.autovacuum_vacuum_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.7.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-THRESHOLD">autovacuum_vacuum_threshold</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-VACUUM-SCALE-FACTOR"><span class="term"><code class="literal">autovacuum_vacuum_scale_factor</code>, <code class="literal">toast.autovacuum_vacuum_scale_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.9.3.85.6.3.4.8.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-SCALE-FACTOR">autovacuum_vacuum_scale_factor</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-VACUUM-INSERT-THRESHOLD"><span class="term"><code class="literal">autovacuum_vacuum_insert_threshold</code>, <code class="literal">toast.autovacuum_vacuum_insert_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.9.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-INSERT-THRESHOLD">autovacuum_vacuum_insert_threshold</a>
+ parameter. The special value of -1 may be used to disable insert vacuums on the table.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-VACUUM-INSERT-SCALE-FACTOR"><span class="term"><code class="literal">autovacuum_vacuum_insert_scale_factor</code>, <code class="literal">toast.autovacuum_vacuum_insert_scale_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.9.3.85.6.3.4.10.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-INSERT-SCALE-FACTOR">autovacuum_vacuum_insert_scale_factor</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-ANALYZE-THRESHOLD"><span class="term"><code class="literal">autovacuum_analyze_threshold</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.11.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-ANALYZE-THRESHOLD">autovacuum_analyze_threshold</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-ANALYZE-SCALE-FACTOR"><span class="term"><code class="literal">autovacuum_analyze_scale_factor</code> (<code class="type">floating point</code>)
+ <a id="id-1.9.3.85.6.3.4.12.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-ANALYZE-SCALE-FACTOR">autovacuum_analyze_scale_factor</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-VACUUM-COST-DELAY"><span class="term"><code class="literal">autovacuum_vacuum_cost_delay</code>, <code class="literal">toast.autovacuum_vacuum_cost_delay</code> (<code class="type">floating point</code>)
+ <a id="id-1.9.3.85.6.3.4.13.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY">autovacuum_vacuum_cost_delay</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-VACUUM-COST-LIMIT"><span class="term"><code class="literal">autovacuum_vacuum_cost_limit</code>, <code class="literal">toast.autovacuum_vacuum_cost_limit</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.14.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT">autovacuum_vacuum_cost_limit</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-FREEZE-MIN-AGE"><span class="term"><code class="literal">autovacuum_freeze_min_age</code>, <code class="literal">toast.autovacuum_freeze_min_age</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.15.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FREEZE-MIN-AGE">vacuum_freeze_min_age</a>
+ parameter. Note that autovacuum will ignore
+ per-table <code class="literal">autovacuum_freeze_min_age</code> parameters that are
+ larger than half the
+ system-wide <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a> setting.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-FREEZE-MAX-AGE"><span class="term"><code class="literal">autovacuum_freeze_max_age</code>, <code class="literal">toast.autovacuum_freeze_max_age</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.16.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE">autovacuum_freeze_max_age</a>
+ parameter. Note that autovacuum will ignore
+ per-table <code class="literal">autovacuum_freeze_max_age</code> parameters that are
+ larger than the system-wide setting (it can only be set smaller).
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-FREEZE-TABLE-AGE"><span class="term"><code class="literal">autovacuum_freeze_table_age</code>, <code class="literal">toast.autovacuum_freeze_table_age</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.17.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FREEZE-TABLE-AGE">vacuum_freeze_table_age</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-MULTIXACT-FREEZE-MIN-AGE"><span class="term"><code class="literal">autovacuum_multixact_freeze_min_age</code>, <code class="literal">toast.autovacuum_multixact_freeze_min_age</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.18.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-client.html#GUC-VACUUM-MULTIXACT-FREEZE-MIN-AGE">vacuum_multixact_freeze_min_age</a>
+ parameter. Note that autovacuum will ignore
+ per-table <code class="literal">autovacuum_multixact_freeze_min_age</code> parameters
+ that are larger than half the
+ system-wide <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE">autovacuum_multixact_freeze_max_age</a>
+ setting.
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE"><span class="term"><code class="literal">autovacuum_multixact_freeze_max_age</code>, <code class="literal">toast.autovacuum_multixact_freeze_max_age</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.19.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value
+ for <a class="xref" href="runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE">autovacuum_multixact_freeze_max_age</a> parameter.
+ Note that autovacuum will ignore
+ per-table <code class="literal">autovacuum_multixact_freeze_max_age</code> parameters
+ that are larger than the system-wide setting (it can only be set
+ smaller).
+ </p></dd><dt id="RELOPTION-AUTOVACUUM-MULTIXACT-FREEZE-TABLE-AGE"><span class="term"><code class="literal">autovacuum_multixact_freeze_table_age</code>, <code class="literal">toast.autovacuum_multixact_freeze_table_age</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.20.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value
+ for <a class="xref" href="runtime-config-client.html#GUC-VACUUM-MULTIXACT-FREEZE-TABLE-AGE">vacuum_multixact_freeze_table_age</a> parameter.
+ </p></dd><dt id="RELOPTION-LOG-AUTOVACUUM-MIN-DURATION"><span class="term"><code class="literal">log_autovacuum_min_duration</code>, <code class="literal">toast.log_autovacuum_min_duration</code> (<code class="type">integer</code>)
+ <a id="id-1.9.3.85.6.3.4.21.1.4" class="indexterm"></a>
+ </span></dt><dd><p>
+ Per-table value for <a class="xref" href="runtime-config-logging.html#GUC-LOG-AUTOVACUUM-MIN-DURATION">log_autovacuum_min_duration</a>
+ parameter.
+ </p></dd><dt id="RELOPTION-USER-CATALOG-TABLE"><span class="term"><code class="literal">user_catalog_table</code> (<code class="type">boolean</code>)
+ <a id="id-1.9.3.85.6.3.4.22.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ Declare the table as an additional catalog table for purposes of
+ logical replication. See
+ <a class="xref" href="logicaldecoding-output-plugin.html#LOGICALDECODING-CAPABILITIES" title="49.6.2. Capabilities">Section 49.6.2</a> for details.
+ This parameter cannot be set for TOAST tables.
+ </p></dd></dl></div></div></div><div class="refsect1" id="SQL-CREATETABLE-NOTES"><h2>Notes</h2><p>
+ <span class="productname">PostgreSQL</span> automatically creates an
+ index for each unique constraint and primary key constraint to
+ enforce uniqueness. Thus, it is not necessary to create an
+ index explicitly for primary key columns. (See <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a> for more information.)
+ </p><p>
+ Unique constraints and primary keys are not inherited in the
+ current implementation. This makes the combination of
+ inheritance and unique constraints rather dysfunctional.
+ </p><p>
+ A table cannot have more than 1600 columns. (In practice, the
+ effective limit is usually lower because of tuple-length constraints.)
+ </p></div><div class="refsect1" id="SQL-CREATETABLE-EXAMPLES"><h2>Examples</h2><p>
+ Create table <code class="structname">films</code> and table
+ <code class="structname">distributors</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE films (
+ code char(5) CONSTRAINT firstkey PRIMARY KEY,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
+ name varchar(40) NOT NULL CHECK (name &lt;&gt; '')
+);
+</pre><p>
+ </p><p>
+ Create a table with a 2-dimensional array:
+
+</p><pre class="programlisting">
+CREATE TABLE array_int (
+ vector int[][]
+);
+</pre><p>
+ </p><p>
+ Define a unique table constraint for the table
+ <code class="literal">films</code>. Unique table constraints can be defined
+ on one or more columns of the table:
+
+</p><pre class="programlisting">
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT production UNIQUE(date_prod)
+);
+</pre><p>
+ </p><p>
+ Define a check column constraint:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer CHECK (did &gt; 100),
+ name varchar(40)
+);
+</pre><p>
+ </p><p>
+ Define a check table constraint:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ CONSTRAINT con1 CHECK (did &gt; 100 AND name &lt;&gt; '')
+);
+</pre><p>
+ </p><p>
+ Define a primary key table constraint for the table
+ <code class="structname">films</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT code_title PRIMARY KEY(code,title)
+);
+</pre><p>
+ </p><p>
+ Define a primary key constraint for table
+ <code class="structname">distributors</code>. The following two examples are
+ equivalent, the first using the table constraint syntax, the second
+ the column constraint syntax:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ PRIMARY KEY(did)
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY,
+ name varchar(40)
+);
+</pre><p>
+ </p><p>
+ Assign a literal constant default value for the column
+ <code class="literal">name</code>, arrange for the default value of column
+ <code class="literal">did</code> to be generated by selecting the next value
+ of a sequence object, and make the default value of
+ <code class="literal">modtime</code> be the time at which the row is
+ inserted:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ name varchar(40) DEFAULT 'Luso Films',
+ did integer DEFAULT nextval('distributors_serial'),
+ modtime timestamp DEFAULT current_timestamp
+);
+</pre><p>
+ </p><p>
+ Define two <code class="literal">NOT NULL</code> column constraints on the table
+ <code class="classname">distributors</code>, one of which is explicitly
+ given a name:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer CONSTRAINT no_null NOT NULL,
+ name varchar(40) NOT NULL
+);
+</pre><p>
+ </p><p>
+ Define a unique constraint for the <code class="literal">name</code> column:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40) UNIQUE
+);
+</pre><p>
+
+ The same, specified as a table constraint:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name)
+);
+</pre><p>
+ </p><p>
+ Create the same table, specifying 70% fill factor for both the table
+ and its unique index:
+
+</p><pre class="programlisting">
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name) WITH (fillfactor=70)
+)
+WITH (fillfactor=70);
+</pre><p>
+ </p><p>
+ Create table <code class="structname">circles</code> with an exclusion
+ constraint that prevents any two circles from overlapping:
+
+</p><pre class="programlisting">
+CREATE TABLE circles (
+ c circle,
+ EXCLUDE USING gist (c WITH &amp;&amp;)
+);
+</pre><p>
+ </p><p>
+ Create table <code class="structname">cinemas</code> in tablespace <code class="structname">diskvol1</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE cinemas (
+ id serial,
+ name text,
+ location text
+) TABLESPACE diskvol1;
+</pre><p>
+ </p><p>
+ Create a composite type and a typed table:
+</p><pre class="programlisting">
+CREATE TYPE employee_type AS (name text, salary numeric);
+
+CREATE TABLE employees OF employee_type (
+ PRIMARY KEY (name),
+ salary WITH OPTIONS DEFAULT 1000
+);
+</pre><p>
+ Create a range partitioned table:
+</p><pre class="programlisting">
+CREATE TABLE measurement (
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (logdate);
+</pre><p>
+ Create a range partitioned table with multiple columns in the partition key:
+</p><pre class="programlisting">
+CREATE TABLE measurement_year_month (
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));
+</pre><p>
+ Create a list partitioned table:
+</p><pre class="programlisting">
+CREATE TABLE cities (
+ city_id bigserial not null,
+ name text not null,
+ population bigint
+) PARTITION BY LIST (left(lower(name), 1));
+</pre><p>
+ Create a hash partitioned table:
+</p><pre class="programlisting">
+CREATE TABLE orders (
+ order_id bigint not null,
+ cust_id bigint not null,
+ status text
+) PARTITION BY HASH (order_id);
+</pre><p>
+ Create partition of a range partitioned table:
+</p><pre class="programlisting">
+CREATE TABLE measurement_y2016m07
+ PARTITION OF measurement (
+ unitsales DEFAULT 0
+) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
+</pre><p>
+ Create a few partitions of a range partitioned table with multiple
+ columns in the partition key:
+</p><pre class="programlisting">
+CREATE TABLE measurement_ym_older
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);
+
+CREATE TABLE measurement_ym_y2016m11
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2016, 11) TO (2016, 12);
+
+CREATE TABLE measurement_ym_y2016m12
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2016, 12) TO (2017, 01);
+
+CREATE TABLE measurement_ym_y2017m01
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2017, 01) TO (2017, 02);
+</pre><p>
+ Create partition of a list partitioned table:
+</p><pre class="programlisting">
+CREATE TABLE cities_ab
+ PARTITION OF cities (
+ CONSTRAINT city_id_nonzero CHECK (city_id != 0)
+) FOR VALUES IN ('a', 'b');
+</pre><p>
+ Create partition of a list partitioned table that is itself further
+ partitioned and then add a partition to it:
+</p><pre class="programlisting">
+CREATE TABLE cities_ab
+ PARTITION OF cities (
+ CONSTRAINT city_id_nonzero CHECK (city_id != 0)
+) FOR VALUES IN ('a', 'b') PARTITION BY RANGE (population);
+
+CREATE TABLE cities_ab_10000_to_100000
+ PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);
+</pre><p>
+ Create partitions of a hash partitioned table:
+</p><pre class="programlisting">
+CREATE TABLE orders_p1 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 0);
+CREATE TABLE orders_p2 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 1);
+CREATE TABLE orders_p3 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 2);
+CREATE TABLE orders_p4 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 3);
+</pre><p>
+ Create a default partition:
+</p><pre class="programlisting">
+CREATE TABLE cities_partdef
+ PARTITION OF cities DEFAULT;
+</pre></div><div class="refsect1" id="SQL-CREATETABLE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The <code class="command">CREATE TABLE</code> command conforms to the
+ <acronym class="acronym">SQL</acronym> standard, with exceptions listed below.
+ </p><div class="refsect2" id="id-1.9.3.85.9.3"><h3>Temporary Tables</h3><p>
+ Although the syntax of <code class="literal">CREATE TEMPORARY TABLE</code>
+ resembles that of the SQL standard, the effect is not the same. In the
+ standard,
+ temporary tables are defined just once and automatically exist (starting
+ with empty contents) in every session that needs them.
+ <span class="productname">PostgreSQL</span> instead
+ requires each session to issue its own <code class="literal">CREATE TEMPORARY
+ TABLE</code> command for each temporary table to be used. This allows
+ different sessions to use the same temporary table name for different
+ purposes, whereas the standard's approach constrains all instances of a
+ given temporary table name to have the same table structure.
+ </p><p>
+ The standard's definition of the behavior of temporary tables is
+ widely ignored. <span class="productname">PostgreSQL</span>'s behavior
+ on this point is similar to that of several other SQL databases.
+ </p><p>
+ The SQL standard also distinguishes between global and local temporary
+ tables, where a local temporary table has a separate set of contents for
+ each SQL module within each session, though its definition is still shared
+ across sessions. Since <span class="productname">PostgreSQL</span> does not
+ support SQL modules, this distinction is not relevant in
+ <span class="productname">PostgreSQL</span>.
+ </p><p>
+ For compatibility's sake, <span class="productname">PostgreSQL</span> will
+ accept the <code class="literal">GLOBAL</code> and <code class="literal">LOCAL</code> keywords
+ in a temporary table declaration, but they currently have no effect.
+ Use of these keywords is discouraged, since future versions of
+ <span class="productname">PostgreSQL</span> might adopt a more
+ standard-compliant interpretation of their meaning.
+ </p><p>
+ The <code class="literal">ON COMMIT</code> clause for temporary tables
+ also resembles the SQL standard, but has some differences.
+ If the <code class="literal">ON COMMIT</code> clause is omitted, SQL specifies that the
+ default behavior is <code class="literal">ON COMMIT DELETE ROWS</code>. However, the
+ default behavior in <span class="productname">PostgreSQL</span> is
+ <code class="literal">ON COMMIT PRESERVE ROWS</code>. The <code class="literal">ON COMMIT
+ DROP</code> option does not exist in SQL.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.4"><h3>Non-Deferred Uniqueness Constraints</h3><p>
+ When a <code class="literal">UNIQUE</code> or <code class="literal">PRIMARY KEY</code> constraint is
+ not deferrable, <span class="productname">PostgreSQL</span> checks for
+ uniqueness immediately whenever a row is inserted or modified.
+ The SQL standard says that uniqueness should be enforced only at
+ the end of the statement; this makes a difference when, for example,
+ a single command updates multiple key values. To obtain
+ standard-compliant behavior, declare the constraint as
+ <code class="literal">DEFERRABLE</code> but not deferred (i.e., <code class="literal">INITIALLY
+ IMMEDIATE</code>). Be aware that this can be significantly slower than
+ immediate uniqueness checking.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.5"><h3>Column Check Constraints</h3><p>
+ The SQL standard says that <code class="literal">CHECK</code> column constraints
+ can only refer to the column they apply to; only <code class="literal">CHECK</code>
+ table constraints can refer to multiple columns.
+ <span class="productname">PostgreSQL</span> does not enforce this
+ restriction; it treats column and table check constraints alike.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.6"><h3><code class="literal">EXCLUDE</code> Constraint</h3><p>
+ The <code class="literal">EXCLUDE</code> constraint type is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.7"><h3>Foreign-Key Constraint Actions</h3><p>
+ The ability to specify column lists in the foreign-key actions
+ <code class="literal">SET DEFAULT</code> and <code class="literal">SET NULL</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.8"><h3><code class="literal">NULL</code> <span class="quote">“<span class="quote">Constraint</span>”</span></h3><p>
+ The <code class="literal">NULL</code> <span class="quote">“<span class="quote">constraint</span>”</span> (actually a
+ non-constraint) is a <span class="productname">PostgreSQL</span>
+ extension to the SQL standard that is included for compatibility with some
+ other database systems (and for symmetry with the <code class="literal">NOT
+ NULL</code> constraint). Since it is the default for any
+ column, its presence is simply noise.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.9"><h3>Constraint Naming</h3><p>
+ The SQL standard says that table and domain constraints must have names
+ that are unique across the schema containing the table or domain.
+ <span class="productname">PostgreSQL</span> is laxer: it only requires
+ constraint names to be unique across the constraints attached to a
+ particular table or domain. However, this extra freedom does not exist
+ for index-based constraints (<code class="literal">UNIQUE</code>,
+ <code class="literal">PRIMARY KEY</code>, and <code class="literal">EXCLUDE</code>
+ constraints), because the associated index is named the same as the
+ constraint, and index names must be unique across all relations within
+ the same schema.
+ </p><p>
+ Currently, <span class="productname">PostgreSQL</span> does not record names
+ for <code class="literal">NOT NULL</code> constraints at all, so they are not
+ subject to the uniqueness restriction. This might change in a future
+ release.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.10"><h3>Inheritance</h3><p>
+ Multiple inheritance via the <code class="literal">INHERITS</code> clause is
+ a <span class="productname">PostgreSQL</span> language extension.
+ SQL:1999 and later define single inheritance using a
+ different syntax and different semantics. SQL:1999-style
+ inheritance is not yet supported by
+ <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.11"><h3>Zero-Column Tables</h3><p>
+ <span class="productname">PostgreSQL</span> allows a table of no columns
+ to be created (for example, <code class="literal">CREATE TABLE foo();</code>). This
+ is an extension from the SQL standard, which does not allow zero-column
+ tables. Zero-column tables are not in themselves very useful, but
+ disallowing them creates odd special cases for <code class="command">ALTER TABLE
+ DROP COLUMN</code>, so it seems cleaner to ignore this spec restriction.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.12"><h3>Multiple Identity Columns</h3><p>
+ <span class="productname">PostgreSQL</span> allows a table to have more than one
+ identity column. The standard specifies that a table can have at most one
+ identity column. This is relaxed mainly to give more flexibility for
+ doing schema changes or migrations. Note that
+ the <code class="command">INSERT</code> command supports only one override clause
+ that applies to the entire statement, so having multiple identity columns
+ with different behaviors is not well supported.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.13"><h3>Generated Columns</h3><p>
+ The option <code class="literal">STORED</code> is not standard but is also used by
+ other SQL implementations. The SQL standard does not specify the storage
+ of generated columns.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.14"><h3><code class="literal">LIKE</code> Clause</h3><p>
+ While a <code class="literal">LIKE</code> clause exists in the SQL standard, many of the
+ options that <span class="productname">PostgreSQL</span> accepts for it are not
+ in the standard, and some of the standard's options are not implemented
+ by <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.15"><h3><code class="literal">WITH</code> Clause</h3><p>
+ The <code class="literal">WITH</code> clause is a <span class="productname">PostgreSQL</span>
+ extension; storage parameters are not in the standard.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.16"><h3>Tablespaces</h3><p>
+ The <span class="productname">PostgreSQL</span> concept of tablespaces is not
+ part of the standard. Hence, the clauses <code class="literal">TABLESPACE</code>
+ and <code class="literal">USING INDEX TABLESPACE</code> are extensions.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.17"><h3>Typed Tables</h3><p>
+ Typed tables implement a subset of the SQL standard. According to
+ the standard, a typed table has columns corresponding to the
+ underlying composite type as well as one other column that is
+ the <span class="quote">“<span class="quote">self-referencing column</span>”</span>.
+ <span class="productname">PostgreSQL</span> does not support self-referencing
+ columns explicitly.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.18"><h3><code class="literal">PARTITION BY</code> Clause</h3><p>
+ The <code class="literal">PARTITION BY</code> clause is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect2" id="id-1.9.3.85.9.19"><h3><code class="literal">PARTITION OF</code> Clause</h3><p>
+ The <code class="literal">PARTITION OF</code> clause is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div></div><div class="refsect1" id="id-1.9.3.85.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>, <a class="xref" href="sql-droptable.html" title="DROP TABLE"><span class="refentrytitle">DROP TABLE</span></a>, <a class="xref" href="sql-createtableas.html" title="CREATE TABLE AS"><span class="refentrytitle">CREATE TABLE AS</span></a>, <a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a>, <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtableas.html" title="CREATE TABLE AS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE SUBSCRIPTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TABLE AS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtableas.html b/doc/src/sgml/html/sql-createtableas.html
new file mode 100644
index 0000000..d939d7b
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtableas.html
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TABLE AS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtable.html" title="CREATE TABLE" /><link rel="next" href="sql-createtablespace.html" title="CREATE TABLESPACE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TABLE AS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtable.html" title="CREATE TABLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtablespace.html" title="CREATE TABLESPACE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETABLEAS"><div class="titlepage"></div><a id="id-1.9.3.86.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TABLE AS</span></h2><p>CREATE TABLE AS — define a new table from the results of a query</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <em class="replaceable"><code>table_name</code></em>
+ [ (<em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ [ USING <em class="replaceable"><code>method</code></em> ]
+ [ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) | WITHOUT OIDS ]
+ [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+ [ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
+ AS <em class="replaceable"><code>query</code></em>
+ [ WITH [ NO ] DATA ]
+</pre></div><div class="refsect1" id="id-1.9.3.86.5"><h2>Description</h2><p>
+ <code class="command">CREATE TABLE AS</code> creates a table and fills it
+ with data computed by a <code class="command">SELECT</code> command.
+ The table columns have the
+ names and data types associated with the output columns of the
+ <code class="command">SELECT</code> (except that you can override the column
+ names by giving an explicit list of new column names).
+ </p><p>
+ <code class="command">CREATE TABLE AS</code> bears some resemblance to
+ creating a view, but it is really quite different: it creates a new
+ table and evaluates the query just once to fill the new table
+ initially. The new table will not track subsequent changes to the
+ source tables of the query. In contrast, a view re-evaluates its
+ defining <code class="command">SELECT</code> statement whenever it is
+ queried.
+ </p><p>
+ <code class="command">CREATE TABLE AS</code> requires <code class="literal">CREATE</code>
+ privilege on the schema used for the table.
+ </p></div><div class="refsect1" id="id-1.9.3.86.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">GLOBAL</code> or <code class="literal">LOCAL</code></span></dt><dd><p>
+ Ignored for compatibility. Use of these keywords is deprecated;
+ refer to <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for details.
+ </p></dd></dl></div><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></span></dt><dd><p>
+ If specified, the table is created as a temporary table.
+ Refer to <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for details.
+ </p></dd><dt><span class="term"><code class="literal">UNLOGGED</code></span></dt><dd><p>
+ If specified, the table is created as an unlogged table.
+ Refer to <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for details.
+ </p></dd><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a relation with the same name already
+ exists; simply issue a notice and leave the table unmodified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column in the new table. If column names are not
+ provided, they are taken from the output column names of the query.
+ </p></dd><dt><span class="term"><code class="literal">USING <em class="replaceable"><code>method</code></em></code></span></dt><dd><p>
+ This optional clause specifies the table access method to use to store
+ the contents for the new table; the method needs be an access method of
+ type <code class="literal">TABLE</code>. See <a class="xref" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">Chapter 63</a> for more
+ information. If this option is not specified, the default table access
+ method is chosen for the new table. See <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLE-ACCESS-METHOD">default_table_access_method</a> for more information.
+ </p></dd><dt><span class="term"><code class="literal">WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause specifies optional storage parameters for the new table;
+ see <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS" title="Storage Parameters">Storage Parameters</a> in the
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> documentation for more
+ information. For backward-compatibility the <code class="literal">WITH</code>
+ clause for a table can also include <code class="literal">OIDS=FALSE</code> to
+ specify that rows of the new table should contain no OIDs (object
+ identifiers), <code class="literal">OIDS=TRUE</code> is not supported anymore.
+ </p></dd><dt><span class="term"><code class="literal">WITHOUT OIDS</code></span></dt><dd><p>
+ This is backward-compatible syntax for declaring a table
+ <code class="literal">WITHOUT OIDS</code>, creating a table <code class="literal">WITH
+ OIDS</code> is not supported anymore.
+ </p></dd><dt><span class="term"><code class="literal">ON COMMIT</code></span></dt><dd><p>
+ The behavior of temporary tables at the end of a transaction
+ block can be controlled using <code class="literal">ON COMMIT</code>.
+ The three options are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">PRESERVE ROWS</code></span></dt><dd><p>
+ No special action is taken at the ends of transactions.
+ This is the default behavior.
+ </p></dd><dt><span class="term"><code class="literal">DELETE ROWS</code></span></dt><dd><p>
+ All rows in the temporary table will be deleted at the end
+ of each transaction block. Essentially, an automatic <a class="link" href="sql-truncate.html" title="TRUNCATE"><code class="command">TRUNCATE</code></a> is done
+ at each commit.
+ </p></dd><dt><span class="term"><code class="literal">DROP</code></span></dt><dd><p>
+ The temporary table will be dropped at the end of the current
+ transaction block.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="literal">TABLESPACE <em class="replaceable"><code>tablespace_name</code></em></code></span></dt><dd><p>
+ The <em class="replaceable"><code>tablespace_name</code></em> is the name
+ of the tablespace in which the new table is to be created.
+ If not specified,
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> is consulted, or
+ <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> if the table is temporary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a>, <a class="link" href="sql-select.html#SQL-TABLE" title="TABLE Command"><code class="command">TABLE</code></a>, or <a class="link" href="sql-values.html" title="VALUES"><code class="command">VALUES</code></a>
+ command, or an <a class="link" href="sql-execute.html" title="EXECUTE"><code class="command">EXECUTE</code></a> command that runs a
+ prepared <code class="command">SELECT</code>, <code class="command">TABLE</code>, or
+ <code class="command">VALUES</code> query.
+ </p></dd><dt><span class="term"><code class="literal">WITH [ NO ] DATA</code></span></dt><dd><p>
+ This clause specifies whether or not the data produced by the query
+ should be copied into the new table. If not, only the table structure
+ is copied. The default is to copy the data.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.86.7"><h2>Notes</h2><p>
+ This command is functionally similar to <a class="xref" href="sql-selectinto.html" title="SELECT INTO"><span class="refentrytitle">SELECT INTO</span></a>, but it is
+ preferred since it is less likely to be confused with other uses of
+ the <code class="command">SELECT INTO</code> syntax. Furthermore, <code class="command">CREATE
+ TABLE AS</code> offers a superset of the functionality offered
+ by <code class="command">SELECT INTO</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.86.8"><h2>Examples</h2><p>
+ Create a new table <code class="literal">films_recent</code> consisting of only
+ recent entries from the table <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+CREATE TABLE films_recent AS
+ SELECT * FROM films WHERE date_prod &gt;= '2002-01-01';
+</pre><p>
+ </p><p>
+ To copy a table completely, the short form using
+ the <code class="literal">TABLE</code> command can also be used:
+
+</p><pre class="programlisting">
+CREATE TABLE films2 AS
+ TABLE films;
+</pre><p>
+ </p><p>
+ Create a new temporary table <code class="literal">films_recent</code>, consisting of
+ only recent entries from the table <code class="literal">films</code>, using a
+ prepared statement. The new table will be dropped at commit:
+
+</p><pre class="programlisting">
+PREPARE recentfilms(date) AS
+ SELECT * FROM films WHERE date_prod &gt; $1;
+CREATE TEMP TABLE films_recent ON COMMIT DROP AS
+ EXECUTE recentfilms('2002-01-01');
+</pre></div><div class="refsect1" id="id-1.9.3.86.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE TABLE AS</code> conforms to the <acronym class="acronym">SQL</acronym>
+ standard. The following are nonstandard extensions:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem"><p>
+ The standard requires parentheses around the subquery clause; in
+ <span class="productname">PostgreSQL</span>, these parentheses are
+ optional.
+ </p></li><li class="listitem"><p>
+ In the standard, the <code class="literal">WITH [ NO ] DATA</code> clause
+ is required; in PostgreSQL it is optional.
+ </p></li><li class="listitem"><p><span class="productname">PostgreSQL</span> handles temporary tables in a way
+ rather different from the standard; see
+ <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>
+ for details.
+ </p></li><li class="listitem"><p>
+ The <code class="literal">WITH</code> clause is a <span class="productname">PostgreSQL</span>
+ extension; storage parameters are not in the standard.
+ </p></li><li class="listitem"><p>
+ The <span class="productname">PostgreSQL</span> concept of tablespaces is not
+ part of the standard. Hence, the clause <code class="literal">TABLESPACE</code>
+ is an extension.
+ </p></li></ul></div></div><div class="refsect1" id="id-1.9.3.86.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW"><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>, <a class="xref" href="sql-execute.html" title="EXECUTE"><span class="refentrytitle">EXECUTE</span></a>, <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>, <a class="xref" href="sql-selectinto.html" title="SELECT INTO"><span class="refentrytitle">SELECT INTO</span></a>, <a class="xref" href="sql-values.html" title="VALUES"><span class="refentrytitle">VALUES</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtable.html" title="CREATE TABLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtablespace.html" title="CREATE TABLESPACE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TABLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TABLESPACE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtablespace.html b/doc/src/sgml/html/sql-createtablespace.html
new file mode 100644
index 0000000..7747370
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtablespace.html
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TABLESPACE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtableas.html" title="CREATE TABLE AS" /><link rel="next" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TABLESPACE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtableas.html" title="CREATE TABLE AS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETABLESPACE"><div class="titlepage"></div><a id="id-1.9.3.87.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TABLESPACE</span></h2><p>CREATE TABLESPACE — define a new tablespace</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE TABLESPACE <em class="replaceable"><code>tablespace_name</code></em>
+ [ OWNER { <em class="replaceable"><code>new_owner</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ]
+ LOCATION '<em class="replaceable"><code>directory</code></em>'
+ [ WITH ( <em class="replaceable"><code>tablespace_option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.87.5"><h2>Description</h2><p>
+ <code class="command">CREATE TABLESPACE</code> registers a new cluster-wide
+ tablespace. The tablespace name must be distinct from the name of any
+ existing tablespace in the database cluster.
+ </p><p>
+ A tablespace allows superusers to define an alternative location on
+ the file system where the data files containing database objects
+ (such as tables and indexes) can reside.
+ </p><p>
+ A user with appropriate privileges can pass
+ <em class="replaceable"><code>tablespace_name</code></em> to
+ <code class="command">CREATE DATABASE</code>, <code class="command">CREATE TABLE</code>,
+ <code class="command">CREATE INDEX</code> or <code class="command">ADD CONSTRAINT</code> to have the data
+ files for these objects stored within the specified tablespace.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ A tablespace cannot be used independently of the cluster in which it
+ is defined; see <a class="xref" href="manage-ag-tablespaces.html" title="23.6. Tablespaces">Section 23.6</a>.
+ </p></div></div><div class="refsect1" id="id-1.9.3.87.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>tablespace_name</code></em></span></dt><dd><p>
+ The name of a tablespace to be created. The name cannot
+ begin with <code class="literal">pg_</code>, as such names
+ are reserved for system tablespaces.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ The name of the user who will own the tablespace. If omitted,
+ defaults to the user executing the command. Only superusers
+ can create tablespaces, but they can assign ownership of tablespaces
+ to non-superusers.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>directory</code></em></span></dt><dd><p>
+ The directory that will be used for the tablespace. The directory
+ must exist (<code class="command">CREATE TABLESPACE</code> will not create it),
+ should be empty, and must be owned by the
+ <span class="productname">PostgreSQL</span> system user. The directory must be
+ specified by an absolute path name.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>tablespace_option</code></em></span></dt><dd><p>
+ A tablespace parameter to be set or reset. Currently, the only
+ available parameters are <code class="varname">seq_page_cost</code>,
+ <code class="varname">random_page_cost</code>, <code class="varname">effective_io_concurrency</code>
+ and <code class="varname">maintenance_io_concurrency</code>.
+ Setting these values for a particular tablespace will override the
+ planner's usual estimate of the cost of reading pages from tables in
+ that tablespace, and the executor's prefetching behavior, as established
+ by the configuration parameters of the
+ same name (see <a class="xref" href="runtime-config-query.html#GUC-SEQ-PAGE-COST">seq_page_cost</a>,
+ <a class="xref" href="runtime-config-query.html#GUC-RANDOM-PAGE-COST">random_page_cost</a>,
+ <a class="xref" href="runtime-config-resource.html#GUC-EFFECTIVE-IO-CONCURRENCY">effective_io_concurrency</a>,
+ <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-IO-CONCURRENCY">maintenance_io_concurrency</a>). This may be useful if
+ one tablespace is located on a disk which is faster or slower than the
+ remainder of the I/O subsystem.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.87.7"><h2>Notes</h2><p>
+ Tablespaces are only supported on systems that support symbolic links.
+ </p><p>
+ <code class="command">CREATE TABLESPACE</code> cannot be executed inside a transaction
+ block.
+ </p></div><div class="refsect1" id="id-1.9.3.87.8"><h2>Examples</h2><p>
+ To create a tablespace <code class="literal">dbspace</code> at file system location
+ <code class="literal">/data/dbs</code>, first create the directory using operating
+ system facilities and set the correct ownership:
+</p><pre class="programlisting">
+mkdir /data/dbs
+chown postgres:postgres /data/dbs
+</pre><p>
+ Then issue the tablespace creation command inside
+ <span class="productname">PostgreSQL</span>:
+</p><pre class="programlisting">
+CREATE TABLESPACE dbspace LOCATION '/data/dbs';
+</pre><p>
+ </p><p>
+ To create a tablespace owned by a different database user, use a command
+ like this:
+</p><pre class="programlisting">
+CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes';
+</pre></div><div class="refsect1" id="id-1.9.3.87.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE TABLESPACE</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.87.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a>, <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>, <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>, <a class="xref" href="sql-droptablespace.html" title="DROP TABLESPACE"><span class="refentrytitle">DROP TABLESPACE</span></a>, <a class="xref" href="sql-altertablespace.html" title="ALTER TABLESPACE"><span class="refentrytitle">ALTER TABLESPACE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtableas.html" title="CREATE TABLE AS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TABLE AS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TEXT SEARCH CONFIGURATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtransform.html b/doc/src/sgml/html/sql-createtransform.html
new file mode 100644
index 0000000..4020961
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtransform.html
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TRANSFORM</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE" /><link rel="next" href="sql-createtrigger.html" title="CREATE TRIGGER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TRANSFORM</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtrigger.html" title="CREATE TRIGGER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETRANSFORM"><div class="titlepage"></div><a id="id-1.9.3.92.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TRANSFORM</span></h2><p>CREATE TRANSFORM — define a new transform</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] TRANSFORM FOR <em class="replaceable"><code>type_name</code></em> LANGUAGE <em class="replaceable"><code>lang_name</code></em> (
+ FROM SQL WITH FUNCTION <em class="replaceable"><code>from_sql_function_name</code></em> [ (<em class="replaceable"><code>argument_type</code></em> [, ...]) ],
+ TO SQL WITH FUNCTION <em class="replaceable"><code>to_sql_function_name</code></em> [ (<em class="replaceable"><code>argument_type</code></em> [, ...]) ]
+);
+</pre></div><div class="refsect1" id="SQL-CREATETRANSFORM-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">CREATE TRANSFORM</code> defines a new transform.
+ <code class="command">CREATE OR REPLACE TRANSFORM</code> will either create a new
+ transform, or replace an existing definition.
+ </p><p>
+ A transform specifies how to adapt a data type to a procedural language.
+ For example, when writing a function in PL/Python using
+ the <code class="type">hstore</code> type, PL/Python has no prior knowledge how to
+ present <code class="type">hstore</code> values in the Python environment. Language
+ implementations usually default to using the text representation, but that
+ is inconvenient when, for example, an associative array or a list would be
+ more appropriate.
+ </p><p>
+ A transform specifies two functions:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A <span class="quote">“<span class="quote">from SQL</span>”</span> function that converts the type from the SQL
+ environment to the language. This function will be invoked on the
+ arguments of a function written in the language.
+ </p></li><li class="listitem"><p>
+ A <span class="quote">“<span class="quote">to SQL</span>”</span> function that converts the type from the
+ language to the SQL environment. This function will be invoked on the
+ return value of a function written in the language.
+ </p></li></ul></div><p>
+ It is not necessary to provide both of these functions. If one is not
+ specified, the language-specific default behavior will be used if
+ necessary. (To prevent a transformation in a certain direction from
+ happening at all, you could also write a transform function that always
+ errors out.)
+ </p><p>
+ To be able to create a transform, you must own and
+ have <code class="literal">USAGE</code> privilege on the type, have
+ <code class="literal">USAGE</code> privilege on the language, and own and
+ have <code class="literal">EXECUTE</code> privilege on the from-SQL and to-SQL
+ functions, if specified.
+ </p></div><div class="refsect1" id="id-1.9.3.92.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>type_name</code></em></span></dt><dd><p>
+ The name of the data type of the transform.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the language of the transform.
+ </p></dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>from_sql_function_name</code></em>[(<em class="replaceable"><code>argument_type</code></em> [, ...])]</code></span></dt><dd><p>
+ The name of the function for converting the type from the SQL
+ environment to the language. It must take one argument of
+ type <code class="type">internal</code> and return type <code class="type">internal</code>. The
+ actual argument will be of the type for the transform, and the function
+ should be coded as if it were. (But it is not allowed to declare an
+ SQL-level function returning <code class="type">internal</code> without at
+ least one argument of type <code class="type">internal</code>.) The actual return
+ value will be something specific to the language implementation.
+ If no argument list is specified, the function name must be unique in
+ its schema.
+ </p></dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>to_sql_function_name</code></em>[(<em class="replaceable"><code>argument_type</code></em> [, ...])]</code></span></dt><dd><p>
+ The name of the function for converting the type from the language to
+ the SQL environment. It must take one argument of type
+ <code class="type">internal</code> and return the type that is the type for the
+ transform. The actual argument value will be something specific to the
+ language implementation.
+ If no argument list is specified, the function name must be unique in
+ its schema.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATETRANSFORM-NOTES"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-droptransform.html" title="DROP TRANSFORM"><code class="command">DROP TRANSFORM</code></a> to remove transforms.
+ </p></div><div class="refsect1" id="SQL-CREATETRANSFORM-EXAMPLES"><h2>Examples</h2><p>
+ To create a transform for type <code class="type">hstore</code> and language
+ <code class="literal">plpython3u</code>, first set up the type and the language:
+</p><pre class="programlisting">
+CREATE TYPE hstore ...;
+
+CREATE EXTENSION plpython3u;
+</pre><p>
+ Then create the necessary functions:
+</p><pre class="programlisting">
+CREATE FUNCTION hstore_to_plpython(val internal) RETURNS internal
+LANGUAGE C STRICT IMMUTABLE
+AS ...;
+
+CREATE FUNCTION plpython_to_hstore(val internal) RETURNS hstore
+LANGUAGE C STRICT IMMUTABLE
+AS ...;
+</pre><p>
+ And finally create the transform to connect them all together:
+</p><pre class="programlisting">
+CREATE TRANSFORM FOR hstore LANGUAGE plpython3u (
+ FROM SQL WITH FUNCTION hstore_to_plpython(internal),
+ TO SQL WITH FUNCTION plpython_to_hstore(internal)
+);
+</pre><p>
+ In practice, these commands would be wrapped up in an extension.
+ </p><p>
+ The <code class="filename">contrib</code> section contains a number of extensions
+ that provide transforms, which can serve as real-world examples.
+ </p></div><div class="refsect1" id="SQL-CREATETRANSFORM-COMPAT"><h2>Compatibility</h2><p>
+ This form of <code class="command">CREATE TRANSFORM</code> is a
+ <span class="productname">PostgreSQL</span> extension. There is a <code class="command">CREATE
+ TRANSFORM</code> command in the <acronym class="acronym">SQL</acronym> standard, but it
+ is for adapting data types to client languages. That usage is not supported
+ by <span class="productname">PostgreSQL</span>.
+ </p></div><div class="refsect1" id="SQL-CREATETRANSFORM-SEEALSO"><h2>See Also</h2><p>
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>,
+ <a class="xref" href="sql-createlanguage.html" title="CREATE LANGUAGE"><span class="refentrytitle">CREATE LANGUAGE</span></a>,
+ <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a>,
+ <a class="xref" href="sql-droptransform.html" title="DROP TRANSFORM"><span class="refentrytitle">DROP TRANSFORM</span></a>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtrigger.html" title="CREATE TRIGGER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TEXT SEARCH TEMPLATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TRIGGER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtrigger.html b/doc/src/sgml/html/sql-createtrigger.html
new file mode 100644
index 0000000..e900feb
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtrigger.html
@@ -0,0 +1,461 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtransform.html" title="CREATE TRANSFORM" /><link rel="next" href="sql-createtype.html" title="CREATE TYPE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtransform.html" title="CREATE TRANSFORM">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtype.html" title="CREATE TYPE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETRIGGER"><div class="titlepage"></div><a id="id-1.9.3.93.1" class="indexterm"></a><a id="id-1.9.3.93.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TRIGGER</span></h2><p>CREATE TRIGGER — define a new trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER <em class="replaceable"><code>name</code></em> { BEFORE | AFTER | INSTEAD OF } { <em class="replaceable"><code>event</code></em> [ OR ... ] }
+ ON <em class="replaceable"><code>table_name</code></em>
+ [ FROM <em class="replaceable"><code>referenced_table_name</code></em> ]
+ [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
+ [ REFERENCING { { OLD | NEW } TABLE [ AS ] <em class="replaceable"><code>transition_relation_name</code></em> } [ ... ] ]
+ [ FOR [ EACH ] { ROW | STATEMENT } ]
+ [ WHEN ( <em class="replaceable"><code>condition</code></em> ) ]
+ EXECUTE { FUNCTION | PROCEDURE } <em class="replaceable"><code>function_name</code></em> ( <em class="replaceable"><code>arguments</code></em> )
+
+<span class="phrase">where <em class="replaceable"><code>event</code></em> can be one of:</span>
+
+ INSERT
+ UPDATE [ OF <em class="replaceable"><code>column_name</code></em> [, ... ] ]
+ DELETE
+ TRUNCATE
+</pre></div><div class="refsect1" id="id-1.9.3.93.6"><h2>Description</h2><p>
+ <code class="command">CREATE TRIGGER</code> creates a new trigger.
+ <code class="command">CREATE OR REPLACE TRIGGER</code> will either create a
+ new trigger, or replace an existing trigger. The
+ trigger will be associated with the specified table, view, or foreign table
+ and will execute the specified
+ function <em class="replaceable"><code>function_name</code></em> when
+ certain operations are performed on that table.
+ </p><p>
+ To replace the current definition of an existing trigger, use
+ <code class="command">CREATE OR REPLACE TRIGGER</code>, specifying the existing
+ trigger's name and parent table. All other properties are replaced.
+ </p><p>
+ The trigger can be specified to fire before the
+ operation is attempted on a row (before constraints are checked and
+ the <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> is attempted); or after the operation has
+ completed (after constraints are checked and the
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> has completed); or instead of the operation
+ (in the case of inserts, updates or deletes on a view).
+ If the trigger fires before or instead of the event, the trigger can skip
+ the operation for the current row, or change the row being inserted (for
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> operations
+ only). If the trigger fires after the event, all changes, including
+ the effects of other triggers, are <span class="quote">“<span class="quote">visible</span>”</span>
+ to the trigger.
+ </p><p>
+ A trigger that is marked <code class="literal">FOR EACH ROW</code> is called
+ once for every row that the operation modifies. For example, a
+ <code class="command">DELETE</code> that affects 10 rows will cause any
+ <code class="literal">ON DELETE</code> triggers on the target relation to be
+ called 10 separate times, once for each deleted row. In contrast, a
+ trigger that is marked <code class="literal">FOR EACH STATEMENT</code> only
+ executes once for any given operation, regardless of how many rows
+ it modifies (in particular, an operation that modifies zero rows
+ will still result in the execution of any applicable <code class="literal">FOR
+ EACH STATEMENT</code> triggers).
+ </p><p>
+ Triggers that are specified to fire <code class="literal">INSTEAD OF</code> the trigger
+ event must be marked <code class="literal">FOR EACH ROW</code>, and can only be defined
+ on views. <code class="literal">BEFORE</code> and <code class="literal">AFTER</code> triggers on a view
+ must be marked as <code class="literal">FOR EACH STATEMENT</code>.
+ </p><p>
+ In addition, triggers may be defined to fire for
+ <code class="command">TRUNCATE</code>, though only
+ <code class="literal">FOR EACH STATEMENT</code>.
+ </p><p>
+ The following table summarizes which types of triggers may be used on
+ tables, views, and foreign tables:
+ </p><div class="informaltable" id="SUPPORTED-TRIGGER-TYPES"><table class="informaltable" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>When</th><th>Event</th><th>Row-level</th><th>Statement-level</th></tr></thead><tbody><tr><td rowspan="2" align="center"><code class="literal">BEFORE</code></td><td align="center"><code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code></td><td align="center">Tables and foreign tables</td><td align="center">Tables, views, and foreign tables</td></tr><tr><td align="center"><code class="command">TRUNCATE</code></td><td align="center">—</td><td align="center">Tables</td></tr><tr><td rowspan="2" align="center"><code class="literal">AFTER</code></td><td align="center"><code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code></td><td align="center">Tables and foreign tables</td><td align="center">Tables, views, and foreign tables</td></tr><tr><td align="center"><code class="command">TRUNCATE</code></td><td align="center">—</td><td align="center">Tables</td></tr><tr><td rowspan="2" align="center"><code class="literal">INSTEAD OF</code></td><td align="center"><code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code></td><td align="center">Views</td><td align="center">—</td></tr><tr><td align="center"><code class="command">TRUNCATE</code></td><td align="center">—</td><td align="center">—</td></tr></tbody></table></div><p>
+ Also, a trigger definition can specify a Boolean <code class="literal">WHEN</code>
+ condition, which will be tested to see whether the trigger should
+ be fired. In row-level triggers the <code class="literal">WHEN</code> condition can
+ examine the old and/or new values of columns of the row. Statement-level
+ triggers can also have <code class="literal">WHEN</code> conditions, although the feature
+ is not so useful for them since the condition cannot refer to any values
+ in the table.
+ </p><p>
+ If multiple triggers of the same kind are defined for the same event,
+ they will be fired in alphabetical order by name.
+ </p><p>
+ When the <code class="literal">CONSTRAINT</code> option is specified, this command creates a
+ <em class="firstterm">constraint trigger</em>.<a id="id-1.9.3.93.6.12.3" class="indexterm"></a>
+ This is the same as a regular trigger
+ except that the timing of the trigger firing can be adjusted using
+ <a class="link" href="sql-set-constraints.html" title="SET CONSTRAINTS"><code class="command">SET CONSTRAINTS</code></a>.
+ Constraint triggers must be <code class="literal">AFTER ROW</code> triggers on plain
+ tables (not foreign tables). They
+ can be fired either at the end of the statement causing the triggering
+ event, or at the end of the containing transaction; in the latter case they
+ are said to be <em class="firstterm">deferred</em>. A pending deferred-trigger firing
+ can also be forced to happen immediately by using <code class="command">SET
+ CONSTRAINTS</code>. Constraint triggers are expected to raise an exception
+ when the constraints they implement are violated.
+ </p><p>
+ The <code class="literal">REFERENCING</code> option enables collection
+ of <em class="firstterm">transition relations</em>, which are row sets that include all
+ of the rows inserted, deleted, or modified by the current SQL statement.
+ This feature lets the trigger see a global view of what the statement did,
+ not just one row at a time. This option is only allowed for
+ an <code class="literal">AFTER</code> trigger that is not a constraint trigger; also, if
+ the trigger is an <code class="literal">UPDATE</code> trigger, it must not specify
+ a <em class="replaceable"><code>column_name</code></em> list.
+ <code class="literal">OLD TABLE</code> may only be specified once, and only for a trigger
+ that can fire on <code class="literal">UPDATE</code> or <code class="literal">DELETE</code>; it creates a
+ transition relation containing the <em class="firstterm">before-images</em> of all rows
+ updated or deleted by the statement.
+ Similarly, <code class="literal">NEW TABLE</code> may only be specified once, and only for
+ a trigger that can fire on <code class="literal">UPDATE</code> or <code class="literal">INSERT</code>;
+ it creates a transition relation containing the <em class="firstterm">after-images</em>
+ of all rows updated or inserted by the statement.
+ </p><p>
+ <code class="command">SELECT</code> does not modify any rows so you cannot
+ create <code class="command">SELECT</code> triggers. Rules and views may provide
+ workable solutions to problems that seem to need <code class="command">SELECT</code>
+ triggers.
+ </p><p>
+ Refer to <a class="xref" href="triggers.html" title="Chapter 39. Triggers">Chapter 39</a> for more information about triggers.
+ </p></div><div class="refsect1" id="id-1.9.3.93.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name to give the new trigger. This must be distinct from
+ the name of any other trigger for the same table.
+ The name cannot be schema-qualified — the trigger inherits the
+ schema of its table. For a constraint trigger, this is also the name to
+ use when modifying the trigger's behavior using
+ <code class="command">SET CONSTRAINTS</code>.
+ </p></dd><dt><span class="term"><code class="literal">BEFORE</code><br /></span><span class="term"><code class="literal">AFTER</code><br /></span><span class="term"><code class="literal">INSTEAD OF</code></span></dt><dd><p>
+ Determines whether the function is called before, after, or instead of
+ the event. A constraint trigger can only be specified as
+ <code class="literal">AFTER</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>event</code></em></span></dt><dd><p>
+ One of <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
+ <code class="literal">DELETE</code>, or <code class="literal">TRUNCATE</code>;
+ this specifies the event that will fire the trigger. Multiple
+ events can be specified using <code class="literal">OR</code>, except when
+ transition relations are requested.
+ </p><p>
+ For <code class="literal">UPDATE</code> events, it is possible to
+ specify a list of columns using this syntax:
+</p><pre class="synopsis">
+UPDATE OF <em class="replaceable"><code>column_name1</code></em> [, <em class="replaceable"><code>column_name2</code></em> ... ]
+</pre><p>
+ The trigger will only fire if at least one of the listed columns
+ is mentioned as a target of the <code class="command">UPDATE</code> command
+ or if one of the listed columns is a generated column that depends on a
+ column that is the target of the <code class="command">UPDATE</code>.
+ </p><p>
+ <code class="literal">INSTEAD OF UPDATE</code> events do not allow a list of columns.
+ A column list cannot be specified when requesting transition relations,
+ either.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table, view, or foreign
+ table the trigger is for.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>referenced_table_name</code></em></span></dt><dd><p>
+ The (possibly schema-qualified) name of another table referenced by the
+ constraint. This option is used for foreign-key constraints and is not
+ recommended for general use. This can only be specified for
+ constraint triggers.
+ </p></dd><dt><span class="term"><code class="literal">DEFERRABLE</code><br /></span><span class="term"><code class="literal">NOT DEFERRABLE</code><br /></span><span class="term"><code class="literal">INITIALLY IMMEDIATE</code><br /></span><span class="term"><code class="literal">INITIALLY DEFERRED</code></span></dt><dd><p>
+ The default timing of the trigger.
+ See the <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> documentation for details of
+ these constraint options. This can only be specified for constraint
+ triggers.
+ </p></dd><dt><span class="term"><code class="literal">REFERENCING</code></span></dt><dd><p>
+ This keyword immediately precedes the declaration of one or two
+ relation names that provide access to the transition relations of the
+ triggering statement.
+ </p></dd><dt><span class="term"><code class="literal">OLD TABLE</code><br /></span><span class="term"><code class="literal">NEW TABLE</code></span></dt><dd><p>
+ This clause indicates whether the following relation name is for the
+ before-image transition relation or the after-image transition
+ relation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>transition_relation_name</code></em></span></dt><dd><p>
+ The (unqualified) name to be used within the trigger for this
+ transition relation.
+ </p></dd><dt><span class="term"><code class="literal">FOR EACH ROW</code><br /></span><span class="term"><code class="literal">FOR EACH STATEMENT</code></span></dt><dd><p>
+ This specifies whether the trigger function should be fired
+ once for every row affected by the trigger event, or just once
+ per SQL statement. If neither is specified, <code class="literal">FOR EACH
+ STATEMENT</code> is the default. Constraint triggers can only
+ be specified <code class="literal">FOR EACH ROW</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
+ A Boolean expression that determines whether the trigger function
+ will actually be executed. If <code class="literal">WHEN</code> is specified, the
+ function will only be called if the <em class="replaceable"><code>condition</code></em> returns <code class="literal">true</code>.
+ In <code class="literal">FOR EACH ROW</code> triggers, the <code class="literal">WHEN</code>
+ condition can refer to columns of the old and/or new row values
+ by writing <code class="literal">OLD.<em class="replaceable"><code>column_name</code></em></code> or
+ <code class="literal">NEW.<em class="replaceable"><code>column_name</code></em></code> respectively.
+ Of course, <code class="literal">INSERT</code> triggers cannot refer to <code class="literal">OLD</code>
+ and <code class="literal">DELETE</code> triggers cannot refer to <code class="literal">NEW</code>.
+ </p><p><code class="literal">INSTEAD OF</code> triggers do not support <code class="literal">WHEN</code>
+ conditions.
+ </p><p>
+ Currently, <code class="literal">WHEN</code> expressions cannot contain
+ subqueries.
+ </p><p>
+ Note that for constraint triggers, evaluation of the <code class="literal">WHEN</code>
+ condition is not deferred, but occurs immediately after the row update
+ operation is performed. If the condition does not evaluate to true then
+ the trigger is not queued for deferred execution.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ A user-supplied function that is declared as taking no arguments
+ and returning type <code class="literal">trigger</code>, which is executed when
+ the trigger fires.
+ </p><p>
+ In the syntax of <code class="literal">CREATE TRIGGER</code>, the keywords
+ <code class="literal">FUNCTION</code> and <code class="literal">PROCEDURE</code> are
+ equivalent, but the referenced function must in any case be a function,
+ not a procedure. The use of the keyword <code class="literal">PROCEDURE</code>
+ here is historical and deprecated.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>arguments</code></em></span></dt><dd><p>
+ An optional comma-separated list of arguments to be provided to
+ the function when the trigger is executed. The arguments are
+ literal string constants. Simple names and numeric constants
+ can be written here, too, but they will all be converted to
+ strings. Please check the description of the implementation
+ language of the trigger function to find out how these arguments
+ can be accessed within the function; it might be different from
+ normal function arguments.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATETRIGGER-NOTES"><h2>Notes</h2><p>
+ To create or replace a trigger on a table, the user must have the
+ <code class="literal">TRIGGER</code> privilege on the table. The user must
+ also have <code class="literal">EXECUTE</code> privilege on the trigger function.
+ </p><p>
+ Use <a class="link" href="sql-droptrigger.html" title="DROP TRIGGER"><code class="command">DROP TRIGGER</code></a> to remove a trigger.
+ </p><p>
+ Creating a row-level trigger on a partitioned table will cause an
+ identical <span class="quote">“<span class="quote">clone</span>”</span> trigger to be created on each of its
+ existing partitions; and any partitions created or attached later will have
+ an identical trigger, too. If there is a conflictingly-named trigger on a
+ child partition already, an error occurs unless <code class="command">CREATE OR REPLACE
+ TRIGGER</code> is used, in which case that trigger is replaced with a
+ clone trigger. When a partition is detached from its parent, its clone
+ triggers are removed.
+ </p><p>
+ A column-specific trigger (one defined using the <code class="literal">UPDATE OF
+ <em class="replaceable"><code>column_name</code></em></code> syntax) will fire when any
+ of its columns are listed as targets in the <code class="command">UPDATE</code>
+ command's <code class="literal">SET</code> list. It is possible for a column's value
+ to change even when the trigger is not fired, because changes made to the
+ row's contents by <code class="literal">BEFORE UPDATE</code> triggers are not considered.
+ Conversely, a command such as <code class="literal">UPDATE ... SET x = x ...</code>
+ will fire a trigger on column <code class="literal">x</code>, even though the column's
+ value did not change.
+ </p><p>
+ In a <code class="literal">BEFORE</code> trigger, the <code class="literal">WHEN</code> condition is
+ evaluated just before the function is or would be executed, so using
+ <code class="literal">WHEN</code> is not materially different from testing the same
+ condition at the beginning of the trigger function. Note in particular
+ that the <code class="literal">NEW</code> row seen by the condition is the current value,
+ as possibly modified by earlier triggers. Also, a <code class="literal">BEFORE</code>
+ trigger's <code class="literal">WHEN</code> condition is not allowed to examine the
+ system columns of the <code class="literal">NEW</code> row (such as <code class="literal">ctid</code>),
+ because those won't have been set yet.
+ </p><p>
+ In an <code class="literal">AFTER</code> trigger, the <code class="literal">WHEN</code> condition is
+ evaluated just after the row update occurs, and it determines whether an
+ event is queued to fire the trigger at the end of statement. So when an
+ <code class="literal">AFTER</code> trigger's <code class="literal">WHEN</code> condition does not return
+ true, it is not necessary to queue an event nor to re-fetch the row at end
+ of statement. This can result in significant speedups in statements that
+ modify many rows, if the trigger only needs to be fired for a few of the
+ rows.
+ </p><p>
+ In some cases it is possible for a single SQL command to fire more than
+ one kind of trigger. For instance an <code class="command">INSERT</code> with
+ an <code class="literal">ON CONFLICT DO UPDATE</code> clause may cause both insert and
+ update operations, so it will fire both kinds of triggers as needed.
+ The transition relations supplied to triggers are
+ specific to their event type; thus an <code class="command">INSERT</code> trigger
+ will see only the inserted rows, while an <code class="command">UPDATE</code>
+ trigger will see only the updated rows.
+ </p><p>
+ Row updates or deletions caused by foreign-key enforcement actions, such
+ as <code class="literal">ON UPDATE CASCADE</code> or <code class="literal">ON DELETE SET NULL</code>, are
+ treated as part of the SQL command that caused them (note that such
+ actions are never deferred). Relevant triggers on the affected table will
+ be fired, so that this provides another way in which an SQL command might
+ fire triggers not directly matching its type. In simple cases, triggers
+ that request transition relations will see all changes caused in their
+ table by a single original SQL command as a single transition relation.
+ However, there are cases in which the presence of an <code class="literal">AFTER ROW</code>
+ trigger that requests transition relations will cause the foreign-key
+ enforcement actions triggered by a single SQL command to be split into
+ multiple steps, each with its own transition relation(s). In such cases,
+ any statement-level triggers that are present will be fired once per
+ creation of a transition relation set, ensuring that the triggers see
+ each affected row in a transition relation once and only once.
+ </p><p>
+ Statement-level triggers on a view are fired only if the action on the
+ view is handled by a row-level <code class="literal">INSTEAD OF</code> trigger.
+ If the action is handled by an <code class="literal">INSTEAD</code> rule, then
+ whatever statements are emitted by the rule are executed in place of the
+ original statement naming the view, so that the triggers that will be
+ fired are those on tables named in the replacement statements.
+ Similarly, if the view is automatically updatable, then the action is
+ handled by automatically rewriting the statement into an action on the
+ view's base table, so that the base table's statement-level triggers are
+ the ones that are fired.
+ </p><p>
+ Modifying a partitioned table or a table with inheritance children fires
+ statement-level triggers attached to the explicitly named table, but not
+ statement-level triggers for its partitions or child tables. In contrast,
+ row-level triggers are fired on the rows in affected partitions or
+ child tables, even if they are not explicitly named in the query.
+ If a statement-level trigger has been defined with transition relations
+ named by a <code class="literal">REFERENCING</code> clause, then before and after
+ images of rows are visible from all affected partitions or child tables.
+ In the case of inheritance children, the row images include only columns
+ that are present in the table that the trigger is attached to.
+ </p><p>
+ Currently, row-level triggers with transition relations cannot be defined
+ on partitions or inheritance child tables. Also, triggers on partitioned
+ tables may not be <code class="literal">INSTEAD OF</code>.
+ </p><p>
+ Currently, the <code class="literal">OR REPLACE</code> option is not supported for
+ constraint triggers.
+ </p><p>
+ Replacing an existing trigger within a transaction that has already
+ performed updating actions on the trigger's table is not recommended.
+ Trigger firing decisions, or portions of firing decisions, that have
+ already been made will not be reconsidered, so the effects could be
+ surprising.
+ </p><p>
+ There are a few built-in trigger functions that can be used to
+ solve common problems without having to write your own trigger code;
+ see <a class="xref" href="functions-trigger.html" title="9.28. Trigger Functions">Section 9.28</a>.
+ </p></div><div class="refsect1" id="SQL-CREATETRIGGER-EXAMPLES"><h2>Examples</h2><p>
+ Execute the function <code class="function">check_account_update</code> whenever
+ a row of the table <code class="literal">accounts</code> is about to be updated:
+
+</p><pre class="programlisting">
+CREATE TRIGGER check_update
+ BEFORE UPDATE ON accounts
+ FOR EACH ROW
+ EXECUTE FUNCTION check_account_update();
+</pre><p>
+
+ Modify that trigger definition to only execute the function if
+ column <code class="literal">balance</code> is specified as a target in
+ the <code class="command">UPDATE</code> command:
+
+</p><pre class="programlisting">
+CREATE OR REPLACE TRIGGER check_update
+ BEFORE UPDATE OF balance ON accounts
+ FOR EACH ROW
+ EXECUTE FUNCTION check_account_update();
+</pre><p>
+
+ This form only executes the function if column <code class="literal">balance</code>
+ has in fact changed value:
+
+</p><pre class="programlisting">
+CREATE TRIGGER check_update
+ BEFORE UPDATE ON accounts
+ FOR EACH ROW
+ WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
+ EXECUTE FUNCTION check_account_update();
+</pre><p>
+
+ Call a function to log updates of <code class="literal">accounts</code>, but only if
+ something changed:
+
+</p><pre class="programlisting">
+CREATE TRIGGER log_update
+ AFTER UPDATE ON accounts
+ FOR EACH ROW
+ WHEN (OLD.* IS DISTINCT FROM NEW.*)
+ EXECUTE FUNCTION log_account_update();
+</pre><p>
+
+ Execute the function <code class="function">view_insert_row</code> for each row to insert
+ rows into the tables underlying a view:
+
+</p><pre class="programlisting">
+CREATE TRIGGER view_insert
+ INSTEAD OF INSERT ON my_view
+ FOR EACH ROW
+ EXECUTE FUNCTION view_insert_row();
+</pre><p>
+
+ Execute the function <code class="function">check_transfer_balances_to_zero</code> for each
+ statement to confirm that the <code class="literal">transfer</code> rows offset to a net of
+ zero:
+
+</p><pre class="programlisting">
+CREATE TRIGGER transfer_insert
+ AFTER INSERT ON transfer
+ REFERENCING NEW TABLE AS inserted
+ FOR EACH STATEMENT
+ EXECUTE FUNCTION check_transfer_balances_to_zero();
+</pre><p>
+
+ Execute the function <code class="function">check_matching_pairs</code> for each row to
+ confirm that changes are made to matching pairs at the same time (by the
+ same statement):
+
+</p><pre class="programlisting">
+CREATE TRIGGER paired_items_update
+ AFTER UPDATE ON paired_items
+ REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab
+ FOR EACH ROW
+ EXECUTE FUNCTION check_matching_pairs();
+</pre><p>
+ </p><p>
+ <a class="xref" href="trigger-example.html" title="39.4. A Complete Trigger Example">Section 39.4</a> contains a complete example of a trigger
+ function written in C.
+ </p></div><div class="refsect1" id="SQL-CREATETRIGGER-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The <code class="command">CREATE TRIGGER</code> statement in
+ <span class="productname">PostgreSQL</span> implements a subset of the
+ <acronym class="acronym">SQL</acronym> standard. The following functionalities are currently
+ missing:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ While transition table names for <code class="literal">AFTER</code> triggers are
+ specified using the <code class="literal">REFERENCING</code> clause in the standard way,
+ the row variables used in <code class="literal">FOR EACH ROW</code> triggers may not be
+ specified in a <code class="literal">REFERENCING</code> clause. They are available in a
+ manner that is dependent on the language in which the trigger function
+ is written, but is fixed for any one language. Some languages
+ effectively behave as though there is a <code class="literal">REFERENCING</code> clause
+ containing <code class="literal">OLD ROW AS OLD NEW ROW AS NEW</code>.
+ </p></li><li class="listitem"><p>
+ The standard allows transition tables to be used with
+ column-specific <code class="literal">UPDATE</code> triggers, but then the set of rows
+ that should be visible in the transition tables depends on the
+ trigger's column list. This is not currently implemented by
+ <span class="productname">PostgreSQL</span>.
+ </p></li><li class="listitem"><p>
+ <span class="productname">PostgreSQL</span> only allows the execution
+ of a user-defined function for the triggered action. The standard
+ allows the execution of a number of other SQL commands, such as
+ <code class="command">CREATE TABLE</code>, as the triggered action. This
+ limitation is not hard to work around by creating a user-defined
+ function that executes the desired commands.
+ </p></li></ul></div><p>
+ </p><p>
+ SQL specifies that multiple triggers should be fired in
+ time-of-creation order. <span class="productname">PostgreSQL</span> uses
+ name order, which was judged to be more convenient.
+ </p><p>
+ SQL specifies that <code class="literal">BEFORE DELETE</code> triggers on cascaded
+ deletes fire <span class="emphasis"><em>after</em></span> the cascaded <code class="literal">DELETE</code> completes.
+ The <span class="productname">PostgreSQL</span> behavior is for <code class="literal">BEFORE
+ DELETE</code> to always fire before the delete action, even a cascading
+ one. This is considered more consistent. There is also nonstandard
+ behavior if <code class="literal">BEFORE</code> triggers modify rows or prevent
+ updates during an update that is caused by a referential action. This can
+ lead to constraint violations or stored data that does not honor the
+ referential constraint.
+ </p><p>
+ The ability to specify multiple actions for a single trigger using
+ <code class="literal">OR</code> is a <span class="productname">PostgreSQL</span> extension of
+ the SQL standard.
+ </p><p>
+ The ability to fire triggers for <code class="command">TRUNCATE</code> is a
+ <span class="productname">PostgreSQL</span> extension of the SQL standard, as is the
+ ability to define statement-level triggers on views.
+ </p><p>
+ <code class="command">CREATE CONSTRAINT TRIGGER</code> is a
+ <span class="productname">PostgreSQL</span> extension of the <acronym class="acronym">SQL</acronym>
+ standard.
+ So is the <code class="literal">OR REPLACE</code> option.
+ </p></div><div class="refsect1" id="id-1.9.3.93.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertrigger.html" title="ALTER TRIGGER"><span class="refentrytitle">ALTER TRIGGER</span></a>, <a class="xref" href="sql-droptrigger.html" title="DROP TRIGGER"><span class="refentrytitle">DROP TRIGGER</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-set-constraints.html" title="SET CONSTRAINTS"><span class="refentrytitle">SET CONSTRAINTS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtransform.html" title="CREATE TRANSFORM">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtype.html" title="CREATE TYPE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TRANSFORM </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TYPE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtsconfig.html b/doc/src/sgml/html/sql-createtsconfig.html
new file mode 100644
index 0000000..9d32cfa
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtsconfig.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TEXT SEARCH CONFIGURATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtablespace.html" title="CREATE TABLESPACE" /><link rel="next" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TEXT SEARCH CONFIGURATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtablespace.html" title="CREATE TABLESPACE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETSCONFIG"><div class="titlepage"></div><a id="id-1.9.3.88.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TEXT SEARCH CONFIGURATION</span></h2><p>CREATE TEXT SEARCH CONFIGURATION — define a new text search configuration</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE TEXT SEARCH CONFIGURATION <em class="replaceable"><code>name</code></em> (
+ PARSER = <em class="replaceable"><code>parser_name</code></em> |
+ COPY = <em class="replaceable"><code>source_config</code></em>
+)
+</pre></div><div class="refsect1" id="id-1.9.3.88.5"><h2>Description</h2><p>
+ <code class="command">CREATE TEXT SEARCH CONFIGURATION</code> creates a new text
+ search configuration. A text search configuration specifies a text
+ search parser that can divide a string into tokens, plus dictionaries
+ that can be used to determine which tokens are of interest for searching.
+ </p><p>
+ If only the parser is specified, then the new text search configuration
+ initially has no mappings from token types to dictionaries, and therefore
+ will ignore all words. Subsequent <code class="command">ALTER TEXT SEARCH
+ CONFIGURATION</code> commands must be used to create mappings to
+ make the configuration useful. Alternatively, an existing text search
+ configuration can be copied.
+ </p><p>
+ If a schema name is given then the text search configuration is created in
+ the specified schema. Otherwise it is created in the current schema.
+ </p><p>
+ The user who defines a text search configuration becomes its owner.
+ </p><p>
+ Refer to <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.88.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the text search configuration to be created. The name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>parser_name</code></em></span></dt><dd><p>
+ The name of the text search parser to use for this configuration.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_config</code></em></span></dt><dd><p>
+ The name of an existing text search configuration to copy.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.88.7"><h2>Notes</h2><p>
+ The <code class="literal">PARSER</code> and <code class="literal">COPY</code> options are mutually
+ exclusive, because when an existing configuration is copied, its
+ parser selection is copied too.
+ </p></div><div class="refsect1" id="id-1.9.3.88.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">CREATE TEXT SEARCH CONFIGURATION</code> statement
+ in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.88.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION"><span class="refentrytitle">ALTER TEXT SEARCH CONFIGURATION</span></a>, <a class="xref" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION"><span class="refentrytitle">DROP TEXT SEARCH CONFIGURATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtablespace.html" title="CREATE TABLESPACE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TABLESPACE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TEXT SEARCH DICTIONARY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtsdictionary.html b/doc/src/sgml/html/sql-createtsdictionary.html
new file mode 100644
index 0000000..e870743
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtsdictionary.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TEXT SEARCH DICTIONARY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION" /><link rel="next" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TEXT SEARCH DICTIONARY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETSDICTIONARY"><div class="titlepage"></div><a id="id-1.9.3.89.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TEXT SEARCH DICTIONARY</span></h2><p>CREATE TEXT SEARCH DICTIONARY — define a new text search dictionary</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE TEXT SEARCH DICTIONARY <em class="replaceable"><code>name</code></em> (
+ TEMPLATE = <em class="replaceable"><code>template</code></em>
+ [, <em class="replaceable"><code>option</code></em> = <em class="replaceable"><code>value</code></em> [, ... ]]
+)
+</pre></div><div class="refsect1" id="id-1.9.3.89.5"><h2>Description</h2><p>
+ <code class="command">CREATE TEXT SEARCH DICTIONARY</code> creates a new text search
+ dictionary. A text search dictionary specifies a way of recognizing
+ interesting or uninteresting words for searching. A dictionary depends
+ on a text search template, which specifies the functions that actually
+ perform the work. Typically the dictionary provides some options that
+ control the detailed behavior of the template's functions.
+ </p><p>
+ If a schema name is given then the text search dictionary is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </p><p>
+ The user who defines a text search dictionary becomes its owner.
+ </p><p>
+ Refer to <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.89.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the text search dictionary to be created. The name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>template</code></em></span></dt><dd><p>
+ The name of the text search template that will define the basic
+ behavior of this dictionary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>option</code></em></span></dt><dd><p>
+ The name of a template-specific option to be set for this dictionary.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ The value to use for a template-specific option. If the value
+ is not a simple identifier or number, it must be quoted (but you can
+ always quote it, if you wish).
+ </p></dd></dl></div><p>
+ The options can appear in any order.
+ </p></div><div class="refsect1" id="id-1.9.3.89.7"><h2>Examples</h2><p>
+ The following example command creates a Snowball-based dictionary
+ with a nonstandard list of stop words.
+ </p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY my_russian (
+ template = snowball,
+ language = russian,
+ stopwords = myrussian
+);
+</pre></div><div class="refsect1" id="id-1.9.3.89.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">CREATE TEXT SEARCH DICTIONARY</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.89.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY"><span class="refentrytitle">ALTER TEXT SEARCH DICTIONARY</span></a>, <a class="xref" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY"><span class="refentrytitle">DROP TEXT SEARCH DICTIONARY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TEXT SEARCH CONFIGURATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TEXT SEARCH PARSER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtsparser.html b/doc/src/sgml/html/sql-createtsparser.html
new file mode 100644
index 0000000..bf89d5c
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtsparser.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TEXT SEARCH PARSER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY" /><link rel="next" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TEXT SEARCH PARSER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETSPARSER"><div class="titlepage"></div><a id="id-1.9.3.90.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TEXT SEARCH PARSER</span></h2><p>CREATE TEXT SEARCH PARSER — define a new text search parser</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE TEXT SEARCH PARSER <em class="replaceable"><code>name</code></em> (
+ START = <em class="replaceable"><code>start_function</code></em> ,
+ GETTOKEN = <em class="replaceable"><code>gettoken_function</code></em> ,
+ END = <em class="replaceable"><code>end_function</code></em> ,
+ LEXTYPES = <em class="replaceable"><code>lextypes_function</code></em>
+ [, HEADLINE = <em class="replaceable"><code>headline_function</code></em> ]
+)
+</pre></div><div class="refsect1" id="id-1.9.3.90.5"><h2>Description</h2><p>
+ <code class="command">CREATE TEXT SEARCH PARSER</code> creates a new text search
+ parser. A text search parser defines a method for splitting a text
+ string into tokens and assigning types (categories) to the tokens.
+ A parser is not particularly useful by itself, but must be bound into a
+ text search configuration along with some text search dictionaries
+ to be used for searching.
+ </p><p>
+ If a schema name is given then the text search parser is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </p><p>
+ You must be a superuser to use <code class="command">CREATE TEXT SEARCH PARSER</code>.
+ (This restriction is made because an erroneous text search parser
+ definition could confuse or even crash the server.)
+ </p><p>
+ Refer to <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.90.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the text search parser to be created. The name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>start_function</code></em></span></dt><dd><p>
+ The name of the start function for the parser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>gettoken_function</code></em></span></dt><dd><p>
+ The name of the get-next-token function for the parser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>end_function</code></em></span></dt><dd><p>
+ The name of the end function for the parser.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lextypes_function</code></em></span></dt><dd><p>
+ The name of the lextypes function for the parser (a function that
+ returns information about the set of token types it produces).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>headline_function</code></em></span></dt><dd><p>
+ The name of the headline function for the parser (a function that
+ summarizes a set of tokens).
+ </p></dd></dl></div><p>
+ The function names can be schema-qualified if necessary. Argument types
+ are not given, since the argument list for each type of function is
+ predetermined. All except the headline function are required.
+ </p><p>
+ The arguments can appear in any order, not only the one shown above.
+ </p></div><div class="refsect1" id="id-1.9.3.90.7"><h2>Compatibility</h2><p>
+ There is no
+ <code class="command">CREATE TEXT SEARCH PARSER</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.90.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER"><span class="refentrytitle">ALTER TEXT SEARCH PARSER</span></a>, <a class="xref" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER"><span class="refentrytitle">DROP TEXT SEARCH PARSER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TEXT SEARCH DICTIONARY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TEXT SEARCH TEMPLATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtstemplate.html b/doc/src/sgml/html/sql-createtstemplate.html
new file mode 100644
index 0000000..d0f2a47
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtstemplate.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TEXT SEARCH TEMPLATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER" /><link rel="next" href="sql-createtransform.html" title="CREATE TRANSFORM" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TEXT SEARCH TEMPLATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtransform.html" title="CREATE TRANSFORM">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETSTEMPLATE"><div class="titlepage"></div><a id="id-1.9.3.91.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TEXT SEARCH TEMPLATE</span></h2><p>CREATE TEXT SEARCH TEMPLATE — define a new text search template</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE TEXT SEARCH TEMPLATE <em class="replaceable"><code>name</code></em> (
+ [ INIT = <em class="replaceable"><code>init_function</code></em> , ]
+ LEXIZE = <em class="replaceable"><code>lexize_function</code></em>
+)
+</pre></div><div class="refsect1" id="id-1.9.3.91.5"><h2>Description</h2><p>
+ <code class="command">CREATE TEXT SEARCH TEMPLATE</code> creates a new text search
+ template. Text search templates define the functions that implement
+ text search dictionaries. A template is not useful by itself, but must
+ be instantiated as a dictionary to be used. The dictionary typically
+ specifies parameters to be given to the template functions.
+ </p><p>
+ If a schema name is given then the text search template is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </p><p>
+ You must be a superuser to use <code class="command">CREATE TEXT SEARCH
+ TEMPLATE</code>. This restriction is made because an erroneous text
+ search template definition could confuse or even crash the server.
+ The reason for separating templates from dictionaries is that a template
+ encapsulates the <span class="quote">“<span class="quote">unsafe</span>”</span> aspects of defining a dictionary.
+ The parameters that can be set when defining a dictionary are safe for
+ unprivileged users to set, and so creating a dictionary need not be a
+ privileged operation.
+ </p><p>
+ Refer to <a class="xref" href="textsearch.html" title="Chapter 12. Full Text Search">Chapter 12</a> for further information.
+ </p></div><div class="refsect1" id="id-1.9.3.91.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the text search template to be created. The name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>init_function</code></em></span></dt><dd><p>
+ The name of the init function for the template.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lexize_function</code></em></span></dt><dd><p>
+ The name of the lexize function for the template.
+ </p></dd></dl></div><p>
+ The function names can be schema-qualified if necessary. Argument types
+ are not given, since the argument list for each type of function is
+ predetermined. The lexize function is required, but the init function
+ is optional.
+ </p><p>
+ The arguments can appear in any order, not only the one shown above.
+ </p></div><div class="refsect1" id="id-1.9.3.91.7"><h2>Compatibility</h2><p>
+ There is no
+ <code class="command">CREATE TEXT SEARCH TEMPLATE</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.91.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE"><span class="refentrytitle">ALTER TEXT SEARCH TEMPLATE</span></a>, <a class="xref" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE"><span class="refentrytitle">DROP TEXT SEARCH TEMPLATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtransform.html" title="CREATE TRANSFORM">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TEXT SEARCH PARSER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TRANSFORM</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createtype.html b/doc/src/sgml/html/sql-createtype.html
new file mode 100644
index 0000000..80b54ae
--- /dev/null
+++ b/doc/src/sgml/html/sql-createtype.html
@@ -0,0 +1,655 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TYPE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtrigger.html" title="CREATE TRIGGER" /><link rel="next" href="sql-createuser.html" title="CREATE USER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TYPE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtrigger.html" title="CREATE TRIGGER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createuser.html" title="CREATE USER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETYPE"><div class="titlepage"></div><a id="id-1.9.3.94.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TYPE</span></h2><p>CREATE TYPE — define a new data type</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE TYPE <em class="replaceable"><code>name</code></em> AS
+ ( [ <em class="replaceable"><code>attribute_name</code></em> <em class="replaceable"><code>data_type</code></em> [ COLLATE <em class="replaceable"><code>collation</code></em> ] [, ... ] ] )
+
+CREATE TYPE <em class="replaceable"><code>name</code></em> AS ENUM
+ ( [ '<em class="replaceable"><code>label</code></em>' [, ... ] ] )
+
+CREATE TYPE <em class="replaceable"><code>name</code></em> AS RANGE (
+ SUBTYPE = <em class="replaceable"><code>subtype</code></em>
+ [ , SUBTYPE_OPCLASS = <em class="replaceable"><code>subtype_operator_class</code></em> ]
+ [ , COLLATION = <em class="replaceable"><code>collation</code></em> ]
+ [ , CANONICAL = <em class="replaceable"><code>canonical_function</code></em> ]
+ [ , SUBTYPE_DIFF = <em class="replaceable"><code>subtype_diff_function</code></em> ]
+ [ , MULTIRANGE_TYPE_NAME = <em class="replaceable"><code>multirange_type_name</code></em> ]
+)
+
+CREATE TYPE <em class="replaceable"><code>name</code></em> (
+ INPUT = <em class="replaceable"><code>input_function</code></em>,
+ OUTPUT = <em class="replaceable"><code>output_function</code></em>
+ [ , RECEIVE = <em class="replaceable"><code>receive_function</code></em> ]
+ [ , SEND = <em class="replaceable"><code>send_function</code></em> ]
+ [ , TYPMOD_IN = <em class="replaceable"><code>type_modifier_input_function</code></em> ]
+ [ , TYPMOD_OUT = <em class="replaceable"><code>type_modifier_output_function</code></em> ]
+ [ , ANALYZE = <em class="replaceable"><code>analyze_function</code></em> ]
+ [ , SUBSCRIPT = <em class="replaceable"><code>subscript_function</code></em> ]
+ [ , INTERNALLENGTH = { <em class="replaceable"><code>internallength</code></em> | VARIABLE } ]
+ [ , PASSEDBYVALUE ]
+ [ , ALIGNMENT = <em class="replaceable"><code>alignment</code></em> ]
+ [ , STORAGE = <em class="replaceable"><code>storage</code></em> ]
+ [ , LIKE = <em class="replaceable"><code>like_type</code></em> ]
+ [ , CATEGORY = <em class="replaceable"><code>category</code></em> ]
+ [ , PREFERRED = <em class="replaceable"><code>preferred</code></em> ]
+ [ , DEFAULT = <em class="replaceable"><code>default</code></em> ]
+ [ , ELEMENT = <em class="replaceable"><code>element</code></em> ]
+ [ , DELIMITER = <em class="replaceable"><code>delimiter</code></em> ]
+ [ , COLLATABLE = <em class="replaceable"><code>collatable</code></em> ]
+)
+
+CREATE TYPE <em class="replaceable"><code>name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.94.5"><h2>Description</h2><p>
+ <code class="command">CREATE TYPE</code> registers a new data type for use in
+ the current database. The user who defines a type becomes its
+ owner.
+ </p><p>
+ If a schema name is given then the type is created in the specified
+ schema. Otherwise it is created in the current schema. The type
+ name must be distinct from the name of any existing type or domain
+ in the same schema. (Because tables have associated data types,
+ the type name must also be distinct from the name of any existing
+ table in the same schema.)
+ </p><p>
+ There are five forms of <code class="command">CREATE TYPE</code>, as shown in the
+ syntax synopsis above. They respectively create a <em class="firstterm">composite
+ type</em>, an <em class="firstterm">enum type</em>, a <em class="firstterm">range type</em>, a
+ <em class="firstterm">base type</em>, or a <em class="firstterm">shell type</em>. The first four
+ of these are discussed in turn below. A shell type is simply a placeholder
+ for a type to be defined later; it is created by issuing <code class="command">CREATE
+ TYPE</code> with no parameters except for the type name. Shell types
+ are needed as forward references when creating range types and base types,
+ as discussed in those sections.
+ </p><div class="refsect2" id="id-1.9.3.94.5.5"><h3>Composite Types</h3><p>
+ The first form of <code class="command">CREATE TYPE</code>
+ creates a composite type.
+ The composite type is specified by a list of attribute names and data types.
+ An attribute's collation can be specified too, if its data type is
+ collatable. A composite type is essentially the same as the row type
+ of a table, but using <code class="command">CREATE TYPE</code> avoids the need to
+ create an actual table when all that is wanted is to define a type.
+ A stand-alone composite type is useful, for example, as the argument or
+ return type of a function.
+ </p><p>
+ To be able to create a composite type, you must
+ have <code class="literal">USAGE</code> privilege on all attribute types.
+ </p></div><div class="refsect2" id="SQL-CREATETYPE-ENUM"><h3>Enumerated Types</h3><p>
+ The second form of <code class="command">CREATE TYPE</code> creates an enumerated
+ (enum) type, as described in <a class="xref" href="datatype-enum.html" title="8.7. Enumerated Types">Section 8.7</a>.
+ Enum types take a list of quoted labels, each of which
+ must be less than <code class="symbol">NAMEDATALEN</code> bytes long (64 bytes in a
+ standard <span class="productname">PostgreSQL</span> build). (It is possible to
+ create an enumerated type with zero labels, but such a type cannot be used
+ to hold values before at least one label is added using <a class="link" href="sql-altertype.html" title="ALTER TYPE"><code class="command">ALTER TYPE</code></a>.)
+ </p></div><div class="refsect2" id="SQL-CREATETYPE-RANGE"><h3>Range Types</h3><p>
+ The third form of <code class="command">CREATE TYPE</code> creates a new
+ range type, as described in <a class="xref" href="rangetypes.html" title="8.17. Range Types">Section 8.17</a>.
+ </p><p>
+ The range type's <em class="replaceable"><code>subtype</code></em> can
+ be any type with an associated b-tree operator class (to determine the
+ ordering of values for the range type). Normally the subtype's default
+ b-tree operator class is used to determine ordering; to use a non-default
+ operator class, specify its name with <em class="replaceable"><code>subtype_opclass</code></em>. If the subtype is
+ collatable, and you want to use a non-default collation in the range's
+ ordering, specify the desired collation with the <em class="replaceable"><code>collation</code></em> option.
+ </p><p>
+ The optional <em class="replaceable"><code>canonical</code></em>
+ function must take one argument of the range type being defined, and
+ return a value of the same type. This is used to convert range values
+ to a canonical form, when applicable. See <a class="xref" href="rangetypes.html#RANGETYPES-DEFINING" title="8.17.8. Defining New Range Types">Section 8.17.8</a> for more information. Creating a
+ <em class="replaceable"><code>canonical</code></em> function
+ is a bit tricky, since it must be defined before the range type can be
+ declared. To do this, you must first create a shell type, which is a
+ placeholder type that has no properties except a name and an
+ owner. This is done by issuing the command <code class="literal">CREATE TYPE
+ <em class="replaceable"><code>name</code></em></code>, with no additional parameters. Then
+ the function can be declared using the shell type as argument and result,
+ and finally the range type can be declared using the same name. This
+ automatically replaces the shell type entry with a valid range type.
+ </p><p>
+ The optional <em class="replaceable"><code>subtype_diff</code></em>
+ function must take two values of the
+ <em class="replaceable"><code>subtype</code></em> type as argument,
+ and return a <code class="type">double precision</code> value representing the
+ difference between the two given values. While this is optional,
+ providing it allows much greater efficiency of GiST indexes on columns of
+ the range type. See <a class="xref" href="rangetypes.html#RANGETYPES-DEFINING" title="8.17.8. Defining New Range Types">Section 8.17.8</a> for more
+ information.
+ </p><p>
+ The optional <em class="replaceable"><code>multirange_type_name</code></em>
+ parameter specifies the name of the corresponding multirange type. If not
+ specified, this name is chosen automatically as follows.
+ If the range type name contains the substring <code class="literal">range</code>, then
+ the multirange type name is formed by replacement of the <code class="literal">range</code>
+ substring with <code class="literal">multirange</code> in the range
+ type name. Otherwise, the multirange type name is formed by appending a
+ <code class="literal">_multirange</code> suffix to the range type name.
+ </p></div><div class="refsect2" id="id-1.9.3.94.5.8"><h3>Base Types</h3><p>
+ The fourth form of <code class="command">CREATE TYPE</code> creates a new base type
+ (scalar type). To create a new base type, you must be a superuser.
+ (This restriction is made because an erroneous type definition could
+ confuse or even crash the server.)
+ </p><p>
+ The parameters can appear in any order, not only that
+ illustrated above, and most are optional. You must register
+ two or more functions (using <code class="command">CREATE FUNCTION</code>) before
+ defining the type. The support functions
+ <em class="replaceable"><code>input_function</code></em> and
+ <em class="replaceable"><code>output_function</code></em>
+ are required, while the functions
+ <em class="replaceable"><code>receive_function</code></em>,
+ <em class="replaceable"><code>send_function</code></em>,
+ <em class="replaceable"><code>type_modifier_input_function</code></em>,
+ <em class="replaceable"><code>type_modifier_output_function</code></em>,
+ <em class="replaceable"><code>analyze_function</code></em>, and
+ <em class="replaceable"><code>subscript_function</code></em>
+ are optional. Generally these functions have to be coded in C
+ or another low-level language.
+ </p><p>
+ The <em class="replaceable"><code>input_function</code></em>
+ converts the type's external textual representation to the internal
+ representation used by the operators and functions defined for the type.
+ <em class="replaceable"><code>output_function</code></em>
+ performs the reverse transformation. The input function can be
+ declared as taking one argument of type <code class="type">cstring</code>,
+ or as taking three arguments of types
+ <code class="type">cstring</code>, <code class="type">oid</code>, <code class="type">integer</code>.
+ The first argument is the input text as a C string, the second
+ argument is the type's own OID (except for array types, which instead
+ receive their element type's OID),
+ and the third is the <code class="literal">typmod</code> of the destination column, if known
+ (-1 will be passed if not).
+ The input function must return a value of the data type itself.
+ Usually, an input function should be declared STRICT; if it is not,
+ it will be called with a NULL first parameter when reading a NULL
+ input value. The function must still return NULL in this case, unless
+ it raises an error.
+ (This case is mainly meant to support domain input functions, which
+ might need to reject NULL inputs.)
+ The output function must be
+ declared as taking one argument of the new data type.
+ The output function must return type <code class="type">cstring</code>.
+ Output functions are not invoked for NULL values.
+ </p><p>
+ The optional <em class="replaceable"><code>receive_function</code></em>
+ converts the type's external binary representation to the internal
+ representation. If this function is not supplied, the type cannot
+ participate in binary input. The binary representation should be
+ chosen to be cheap to convert to internal form, while being reasonably
+ portable. (For example, the standard integer data types use network
+ byte order as the external binary representation, while the internal
+ representation is in the machine's native byte order.) The receive
+ function should perform adequate checking to ensure that the value is
+ valid.
+ The receive function can be declared as taking one argument of type
+ <code class="type">internal</code>, or as taking three arguments of types
+ <code class="type">internal</code>, <code class="type">oid</code>, <code class="type">integer</code>.
+ The first argument is a pointer to a <code class="type">StringInfo</code> buffer
+ holding the received byte string; the optional arguments are the
+ same as for the text input function.
+ The receive function must return a value of the data type itself.
+ Usually, a receive function should be declared STRICT; if it is not,
+ it will be called with a NULL first parameter when reading a NULL
+ input value. The function must still return NULL in this case, unless
+ it raises an error.
+ (This case is mainly meant to support domain receive functions, which
+ might need to reject NULL inputs.)
+ Similarly, the optional
+ <em class="replaceable"><code>send_function</code></em> converts
+ from the internal representation to the external binary representation.
+ If this function is not supplied, the type cannot participate in binary
+ output. The send function must be
+ declared as taking one argument of the new data type.
+ The send function must return type <code class="type">bytea</code>.
+ Send functions are not invoked for NULL values.
+ </p><p>
+ You should at this point be wondering how the input and output functions
+ can be declared to have results or arguments of the new type, when they
+ have to be created before the new type can be created. The answer is that
+ the type should first be defined as a <em class="firstterm">shell type</em>, which is a
+ placeholder type that has no properties except a name and an owner. This
+ is done by issuing the command <code class="literal">CREATE TYPE
+ <em class="replaceable"><code>name</code></em></code>, with no additional parameters. Then the
+ C I/O functions can be defined referencing the shell type. Finally,
+ <code class="command">CREATE TYPE</code> with a full definition replaces the shell entry
+ with a complete, valid type definition, after which the new type can be
+ used normally.
+ </p><p>
+ The optional
+ <em class="replaceable"><code>type_modifier_input_function</code></em>
+ and <em class="replaceable"><code>type_modifier_output_function</code></em>
+ are needed if the type supports modifiers, that is optional constraints
+ attached to a type declaration, such as <code class="literal">char(5)</code> or
+ <code class="literal">numeric(30,2)</code>. <span class="productname">PostgreSQL</span> allows
+ user-defined types to take one or more simple constants or identifiers as
+ modifiers. However, this information must be capable of being packed into a
+ single non-negative integer value for storage in the system catalogs. The
+ <em class="replaceable"><code>type_modifier_input_function</code></em>
+ is passed the declared modifier(s) in the form of a <code class="type">cstring</code>
+ array. It must check the values for validity (throwing an error if they
+ are wrong), and if they are correct, return a single non-negative
+ <code class="type">integer</code> value that will be stored as the column <span class="quote">“<span class="quote">typmod</span>”</span>.
+ Type modifiers will be rejected if the type does not have a
+ <em class="replaceable"><code>type_modifier_input_function</code></em>.
+ The <em class="replaceable"><code>type_modifier_output_function</code></em>
+ converts the internal integer typmod value back to the correct form for
+ user display. It must return a <code class="type">cstring</code> value that is the exact
+ string to append to the type name; for example <code class="type">numeric</code>'s
+ function might return <code class="literal">(30,2)</code>.
+ It is allowed to omit the
+ <em class="replaceable"><code>type_modifier_output_function</code></em>,
+ in which case the default display format is just the stored typmod integer
+ value enclosed in parentheses.
+ </p><p>
+ The optional <em class="replaceable"><code>analyze_function</code></em>
+ performs type-specific statistics collection for columns of the data type.
+ By default, <code class="command">ANALYZE</code> will attempt to gather statistics using
+ the type's <span class="quote">“<span class="quote">equals</span>”</span> and <span class="quote">“<span class="quote">less-than</span>”</span> operators, if there
+ is a default b-tree operator class for the type. For non-scalar types
+ this behavior is likely to be unsuitable, so it can be overridden by
+ specifying a custom analysis function. The analysis function must be
+ declared to take a single argument of type <code class="type">internal</code>, and return
+ a <code class="type">boolean</code> result. The detailed API for analysis functions appears
+ in <code class="filename">src/include/commands/vacuum.h</code>.
+ </p><p>
+ The optional <em class="replaceable"><code>subscript_function</code></em>
+ allows the data type to be subscripted in SQL commands. Specifying this
+ function does not cause the type to be considered a <span class="quote">“<span class="quote">true</span>”</span>
+ array type; for example, it will not be a candidate for the result type
+ of <code class="literal">ARRAY[]</code> constructs. But if subscripting a value
+ of the type is a natural notation for extracting data from it, then
+ a <em class="replaceable"><code>subscript_function</code></em> can
+ be written to define what that means. The subscript function must be
+ declared to take a single argument of type <code class="type">internal</code>, and
+ return an <code class="type">internal</code> result, which is a pointer to a struct
+ of methods (functions) that implement subscripting.
+ The detailed API for subscript functions appears
+ in <code class="filename">src/include/nodes/subscripting.h</code>.
+ It may also be useful to read the array implementation
+ in <code class="filename">src/backend/utils/adt/arraysubs.c</code>,
+ or the simpler code
+ in <code class="filename">contrib/hstore/hstore_subs.c</code>.
+ Additional information appears in
+ <a class="xref" href="sql-createtype.html#SQL-CREATETYPE-ARRAY" title="Array Types">Array Types</a> below.
+ </p><p>
+ While the details of the new type's internal representation are only
+ known to the I/O functions and other functions you create to work with
+ the type, there are several properties of the internal representation
+ that must be declared to <span class="productname">PostgreSQL</span>.
+ Foremost of these is
+ <em class="replaceable"><code>internallength</code></em>.
+ Base data types can be fixed-length, in which case
+ <em class="replaceable"><code>internallength</code></em> is a
+ positive integer, or variable-length, indicated by setting
+ <em class="replaceable"><code>internallength</code></em>
+ to <code class="literal">VARIABLE</code>. (Internally, this is represented
+ by setting <code class="literal">typlen</code> to -1.) The internal representation of all
+ variable-length types must start with a 4-byte integer giving the total
+ length of this value of the type. (Note that the length field is often
+ encoded, as described in <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a>; it's unwise
+ to access it directly.)
+ </p><p>
+ The optional flag <code class="literal">PASSEDBYVALUE</code> indicates that
+ values of this data type are passed by value, rather than by
+ reference. Types passed by value must be fixed-length, and their internal
+ representation cannot be larger than the size of the <code class="type">Datum</code> type
+ (4 bytes on some machines, 8 bytes on others).
+ </p><p>
+ The <em class="replaceable"><code>alignment</code></em> parameter
+ specifies the storage alignment required for the data type. The
+ allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries.
+ Note that variable-length types must have an alignment of at least
+ 4, since they necessarily contain an <code class="type">int4</code> as their first component.
+ </p><p>
+ The <em class="replaceable"><code>storage</code></em> parameter
+ allows selection of storage strategies for variable-length data
+ types. (Only <code class="literal">plain</code> is allowed for fixed-length
+ types.) <code class="literal">plain</code> specifies that data of the type
+ will always be stored in-line and not compressed.
+ <code class="literal">extended</code> specifies that the system will first
+ try to compress a long data value, and will move the value out of
+ the main table row if it's still too long.
+ <code class="literal">external</code> allows the value to be moved out of the
+ main table, but the system will not try to compress it.
+ <code class="literal">main</code> allows compression, but discourages moving
+ the value out of the main table. (Data items with this storage
+ strategy might still be moved out of the main table if there is no
+ other way to make a row fit, but they will be kept in the main
+ table preferentially over <code class="literal">extended</code> and
+ <code class="literal">external</code> items.)
+ </p><p>
+ All <em class="replaceable"><code>storage</code></em> values other
+ than <code class="literal">plain</code> imply that the functions of the data type
+ can handle values that have been <em class="firstterm">toasted</em>, as described
+ in <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a> and <a class="xref" href="xtypes.html#XTYPES-TOAST" title="38.13.1. TOAST Considerations">Section 38.13.1</a>.
+ The specific other value given merely determines the default TOAST
+ storage strategy for columns of a toastable data type; users can pick
+ other strategies for individual columns using <code class="literal">ALTER TABLE
+ SET STORAGE</code>.
+ </p><p>
+ The <em class="replaceable"><code>like_type</code></em> parameter
+ provides an alternative method for specifying the basic representation
+ properties of a data type: copy them from some existing type. The values of
+ <em class="replaceable"><code>internallength</code></em>,
+ <em class="replaceable"><code>passedbyvalue</code></em>,
+ <em class="replaceable"><code>alignment</code></em>, and
+ <em class="replaceable"><code>storage</code></em> are copied from the
+ named type. (It is possible, though usually undesirable, to override
+ some of these values by specifying them along with the <code class="literal">LIKE</code>
+ clause.) Specifying representation this way is especially useful when
+ the low-level implementation of the new type <span class="quote">“<span class="quote">piggybacks</span>”</span> on an
+ existing type in some fashion.
+ </p><p>
+ The <em class="replaceable"><code>category</code></em> and
+ <em class="replaceable"><code>preferred</code></em> parameters can be
+ used to help control which implicit cast will be applied in ambiguous
+ situations. Each data type belongs to a category named by a single ASCII
+ character, and each type is either <span class="quote">“<span class="quote">preferred</span>”</span> or not within its
+ category. The parser will prefer casting to preferred types (but only from
+ other types within the same category) when this rule is helpful in
+ resolving overloaded functions or operators. For more details see <a class="xref" href="typeconv.html" title="Chapter 10. Type Conversion">Chapter 10</a>. For types that have no implicit casts to or from any
+ other types, it is sufficient to leave these settings at the defaults.
+ However, for a group of related types that have implicit casts, it is often
+ helpful to mark them all as belonging to a category and select one or two
+ of the <span class="quote">“<span class="quote">most general</span>”</span> types as being preferred within the category.
+ The <em class="replaceable"><code>category</code></em> parameter is
+ especially useful when adding a user-defined type to an existing built-in
+ category, such as the numeric or string types. However, it is also
+ possible to create new entirely-user-defined type categories. Select any
+ ASCII character other than an upper-case letter to name such a category.
+ </p><p>
+ A default value can be specified, in case a user wants columns of the
+ data type to default to something other than the null value.
+ Specify the default with the <code class="literal">DEFAULT</code> key word.
+ (Such a default can be overridden by an explicit <code class="literal">DEFAULT</code>
+ clause attached to a particular column.)
+ </p><p>
+ To indicate that a type is a fixed-length array type,
+ specify the type of the array
+ elements using the <code class="literal">ELEMENT</code> key word. For example, to
+ define an array of 4-byte integers (<code class="type">int4</code>), specify
+ <code class="literal">ELEMENT = int4</code>. For more details,
+ see <a class="xref" href="sql-createtype.html#SQL-CREATETYPE-ARRAY" title="Array Types">Array Types</a> below.
+ </p><p>
+ To indicate the delimiter to be used between values in the external
+ representation of arrays of this type, <em class="replaceable"><code>delimiter</code></em> can be
+ set to a specific character. The default delimiter is the comma
+ (<code class="literal">,</code>). Note that the delimiter is associated
+ with the array element type, not the array type itself.
+ </p><p>
+ If the optional Boolean
+ parameter <em class="replaceable"><code>collatable</code></em>
+ is true, column definitions and expressions of the type may carry
+ collation information through use of
+ the <code class="literal">COLLATE</code> clause. It is up to the
+ implementations of the functions operating on the type to actually
+ make use of the collation information; this does not happen
+ automatically merely by marking the type collatable.
+ </p></div><div class="refsect2" id="SQL-CREATETYPE-ARRAY"><h3>Array Types</h3><p>
+ Whenever a user-defined type is created,
+ <span class="productname">PostgreSQL</span> automatically creates an
+ associated array type, whose name consists of the element type's
+ name prepended with an underscore, and truncated if necessary to keep
+ it less than <code class="symbol">NAMEDATALEN</code> bytes long. (If the name
+ so generated collides with an existing type name, the process is
+ repeated until a non-colliding name is found.)
+ This implicitly-created array type is variable length and uses the
+ built-in input and output functions <code class="literal">array_in</code> and
+ <code class="literal">array_out</code>. Furthermore, this type is what the system
+ uses for constructs such as <code class="literal">ARRAY[]</code> over the
+ user-defined type. The array type tracks any changes in its
+ element type's owner or schema, and is dropped if the element type is.
+ </p><p>
+ You might reasonably ask why there is an <code class="option">ELEMENT</code>
+ option, if the system makes the correct array type automatically.
+ The main case where it's useful to use <code class="option">ELEMENT</code> is when you are
+ making a fixed-length type that happens to be internally an array of a number of
+ identical things, and you want to allow these things to be accessed
+ directly by subscripting, in addition to whatever operations you plan
+ to provide for the type as a whole. For example, type <code class="type">point</code>
+ is represented as just two floating-point numbers, which can be accessed
+ using <code class="literal">point[0]</code> and <code class="literal">point[1]</code>.
+ Note that
+ this facility only works for fixed-length types whose internal form
+ is exactly a sequence of identical fixed-length fields.
+ For historical reasons (i.e., this is clearly wrong but it's far too
+ late to change it), subscripting of fixed-length array types starts from
+ zero, rather than from one as for variable-length arrays.
+ </p><p>
+ Specifying the <code class="option">SUBSCRIPT</code> option allows a data type to
+ be subscripted, even though the system does not otherwise regard it as
+ an array type. The behavior just described for fixed-length arrays is
+ actually implemented by the <code class="option">SUBSCRIPT</code> handler
+ function <code class="function">raw_array_subscript_handler</code>, which is
+ used automatically if you specify <code class="option">ELEMENT</code> for a
+ fixed-length type without also writing <code class="option">SUBSCRIPT</code>.
+ </p><p>
+ When specifying a custom <code class="option">SUBSCRIPT</code> function, it is
+ not necessary to specify <code class="option">ELEMENT</code> unless
+ the <code class="option">SUBSCRIPT</code> handler function needs to
+ consult <code class="structfield">typelem</code> to find out what to return.
+ Be aware that specifying <code class="option">ELEMENT</code> causes the system to
+ assume that the new type contains, or is somehow physically dependent on,
+ the element type; thus for example changing properties of the element
+ type won't be allowed if there are any columns of the dependent type.
+ </p></div></div><div class="refsect1" id="id-1.9.3.94.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a type to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>attribute_name</code></em></span></dt><dd><p>
+ The name of an attribute (column) for the composite type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The name of an existing data type to become a column of the
+ composite type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>collation</code></em></span></dt><dd><p>
+ The name of an existing collation to be associated with a column of
+ a composite type, or with a range type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>label</code></em></span></dt><dd><p>
+ A string literal representing the textual label associated with
+ one value of an enum type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>subtype</code></em></span></dt><dd><p>
+ The name of the element type that the range type will represent ranges
+ of.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>subtype_operator_class</code></em></span></dt><dd><p>
+ The name of a b-tree operator class for the subtype.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>canonical_function</code></em></span></dt><dd><p>
+ The name of the canonicalization function for the range type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>subtype_diff_function</code></em></span></dt><dd><p>
+ The name of a difference function for the subtype.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>multirange_type_name</code></em></span></dt><dd><p>
+ The name of the corresponding multirange type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>input_function</code></em></span></dt><dd><p>
+ The name of a function that converts data from the type's
+ external textual form to its internal form.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_function</code></em></span></dt><dd><p>
+ The name of a function that converts data from the type's
+ internal form to its external textual form.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>receive_function</code></em></span></dt><dd><p>
+ The name of a function that converts data from the type's
+ external binary form to its internal form.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>send_function</code></em></span></dt><dd><p>
+ The name of a function that converts data from the type's
+ internal form to its external binary form.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>type_modifier_input_function</code></em></span></dt><dd><p>
+ The name of a function that converts an array of modifier(s) for the type
+ into internal form.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>type_modifier_output_function</code></em></span></dt><dd><p>
+ The name of a function that converts the internal form of the type's
+ modifier(s) to external textual form.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>analyze_function</code></em></span></dt><dd><p>
+ The name of a function that performs statistical analysis for the
+ data type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>subscript_function</code></em></span></dt><dd><p>
+ The name of a function that defines what subscripting a value of the
+ data type does.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>internallength</code></em></span></dt><dd><p>
+ A numeric constant that specifies the length in bytes of the new
+ type's internal representation. The default assumption is that
+ it is variable-length.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>alignment</code></em></span></dt><dd><p>
+ The storage alignment requirement of the data type. If specified,
+ it must be <code class="literal">char</code>, <code class="literal">int2</code>,
+ <code class="literal">int4</code>, or <code class="literal">double</code>; the
+ default is <code class="literal">int4</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>storage</code></em></span></dt><dd><p>
+ The storage strategy for the data type. If specified, must be
+ <code class="literal">plain</code>, <code class="literal">external</code>,
+ <code class="literal">extended</code>, or <code class="literal">main</code>; the
+ default is <code class="literal">plain</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>like_type</code></em></span></dt><dd><p>
+ The name of an existing data type that the new type will have the
+ same representation as. The values of
+ <em class="replaceable"><code>internallength</code></em>,
+ <em class="replaceable"><code>passedbyvalue</code></em>,
+ <em class="replaceable"><code>alignment</code></em>, and
+ <em class="replaceable"><code>storage</code></em>
+ are copied from that type, unless overridden by explicit
+ specification elsewhere in this <code class="command">CREATE TYPE</code> command.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>category</code></em></span></dt><dd><p>
+ The category code (a single ASCII character) for this type.
+ The default is <code class="literal">'U'</code> for <span class="quote">“<span class="quote">user-defined type</span>”</span>.
+ Other standard category codes can be found in
+ <a class="xref" href="catalog-pg-type.html#CATALOG-TYPCATEGORY-TABLE" title="Table 53.65. typcategory Codes">Table 53.65</a>. You may also choose
+ other ASCII characters in order to create custom categories.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>preferred</code></em></span></dt><dd><p>
+ True if this type is a preferred type within its type category,
+ else false. The default is false. Be very careful about creating
+ a new preferred type within an existing type category, as this
+ could cause surprising changes in behavior.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>default</code></em></span></dt><dd><p>
+ The default value for the data type. If this is omitted, the
+ default is null.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>element</code></em></span></dt><dd><p>
+ The type being created is an array; this specifies the type of
+ the array elements.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>delimiter</code></em></span></dt><dd><p>
+ The delimiter character to be used between values in arrays made
+ of this type.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>collatable</code></em></span></dt><dd><p>
+ True if this type's operations can use collation information.
+ The default is false.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATETYPE-NOTES"><h2>Notes</h2><p>
+ Because there are no restrictions on use of a data type once it's been
+ created, creating a base type or range type is tantamount to granting
+ public execute permission on the functions mentioned in the type definition.
+ This is usually
+ not an issue for the sorts of functions that are useful in a type
+ definition. But you might want to think twice before designing a type
+ in a way that would require <span class="quote">“<span class="quote">secret</span>”</span> information to be used
+ while converting it to or from external form.
+ </p><p>
+ Before <span class="productname">PostgreSQL</span> version 8.3, the name of
+ a generated array type was always exactly the element type's name with one
+ underscore character (<code class="literal">_</code>) prepended. (Type names were
+ therefore restricted in length to one fewer character than other names.)
+ While this is still usually the case, the array type name may vary from
+ this in case of maximum-length names or collisions with user type names
+ that begin with underscore. Writing code that depends on this convention
+ is therefore deprecated. Instead, use
+ <code class="structname">pg_type</code>.<code class="structfield">typarray</code> to locate the array type
+ associated with a given type.
+ </p><p>
+ It may be advisable to avoid using type and table names that begin with
+ underscore. While the server will change generated array type names to
+ avoid collisions with user-given names, there is still risk of confusion,
+ particularly with old client software that may assume that type names
+ beginning with underscores always represent arrays.
+ </p><p>
+ Before <span class="productname">PostgreSQL</span> version 8.2, the shell-type
+ creation syntax
+ <code class="literal">CREATE TYPE <em class="replaceable"><code>name</code></em></code> did not exist.
+ The way to create a new base type was to create its input function first.
+ In this approach, <span class="productname">PostgreSQL</span> will first see
+ the name of the new data type as the return type of the input function.
+ The shell type is implicitly created in this situation, and then it
+ can be referenced in the definitions of the remaining I/O functions.
+ This approach still works, but is deprecated and might be disallowed in
+ some future release. Also, to avoid accidentally cluttering
+ the catalogs with shell types as a result of simple typos in function
+ definitions, a shell type will only be made this way when the input
+ function is written in C.
+ </p></div><div class="refsect1" id="id-1.9.3.94.8"><h2>Examples</h2><p>
+ This example creates a composite type and uses it in
+ a function definition:
+</p><pre class="programlisting">
+CREATE TYPE compfoo AS (f1 int, f2 text);
+
+CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
+ SELECT fooid, fooname FROM foo
+$$ LANGUAGE SQL;
+</pre><p>
+ </p><p>
+ This example creates an enumerated type and uses it in
+ a table definition:
+</p><pre class="programlisting">
+CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');
+
+CREATE TABLE bug (
+ id serial,
+ description text,
+ status bug_status
+);
+</pre><p>
+ </p><p>
+ This example creates a range type:
+</p><pre class="programlisting">
+CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
+</pre><p>
+ </p><p>
+ This example creates the base data type <code class="type">box</code> and then uses the
+ type in a table definition:
+</p><pre class="programlisting">
+CREATE TYPE box;
+
+CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS ... ;
+CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS ... ;
+
+CREATE TYPE box (
+ INTERNALLENGTH = 16,
+ INPUT = my_box_in_function,
+ OUTPUT = my_box_out_function
+);
+
+CREATE TABLE myboxes (
+ id integer,
+ description box
+);
+</pre><p>
+ </p><p>
+ If the internal structure of <code class="type">box</code> were an array of four
+ <code class="type">float4</code> elements, we might instead use:
+</p><pre class="programlisting">
+CREATE TYPE box (
+ INTERNALLENGTH = 16,
+ INPUT = my_box_in_function,
+ OUTPUT = my_box_out_function,
+ ELEMENT = float4
+);
+</pre><p>
+ which would allow a box value's component numbers to be accessed
+ by subscripting. Otherwise the type behaves the same as before.
+ </p><p>
+ This example creates a large object type and uses it in
+ a table definition:
+</p><pre class="programlisting">
+CREATE TYPE bigobj (
+ INPUT = lo_filein, OUTPUT = lo_fileout,
+ INTERNALLENGTH = VARIABLE
+);
+CREATE TABLE big_objs (
+ id integer,
+ obj bigobj
+);
+</pre><p>
+ </p><p>
+ More examples, including suitable input and output functions, are
+ in <a class="xref" href="xtypes.html" title="38.13. User-Defined Types">Section 38.13</a>.
+ </p></div><div class="refsect1" id="SQL-CREATETYPE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The first form of the <code class="command">CREATE TYPE</code> command, which
+ creates a composite type, conforms to the <acronym class="acronym">SQL</acronym> standard.
+ The other forms are <span class="productname">PostgreSQL</span>
+ extensions. The <code class="command">CREATE TYPE</code> statement in
+ the <acronym class="acronym">SQL</acronym> standard also defines other forms that are not
+ implemented in <span class="productname">PostgreSQL</span>.
+ </p><p>
+ The ability to create a composite type with zero attributes is
+ a <span class="productname">PostgreSQL</span>-specific deviation from the
+ standard (analogous to the same case in <code class="command">CREATE TABLE</code>).
+ </p></div><div class="refsect1" id="SQL-CREATETYPE-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertype.html" title="ALTER TYPE"><span class="refentrytitle">ALTER TYPE</span></a>, <a class="xref" href="sql-createdomain.html" title="CREATE DOMAIN"><span class="refentrytitle">CREATE DOMAIN</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-droptype.html" title="DROP TYPE"><span class="refentrytitle">DROP TYPE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtrigger.html" title="CREATE TRIGGER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createuser.html" title="CREATE USER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TRIGGER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE USER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createuser.html b/doc/src/sgml/html/sql-createuser.html
new file mode 100644
index 0000000..7720c0b
--- /dev/null
+++ b/doc/src/sgml/html/sql-createuser.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE USER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtype.html" title="CREATE TYPE" /><link rel="next" href="sql-createusermapping.html" title="CREATE USER MAPPING" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE USER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtype.html" title="CREATE TYPE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createusermapping.html" title="CREATE USER MAPPING">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEUSER"><div class="titlepage"></div><a id="id-1.9.3.95.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE USER</span></h2><p>CREATE USER — define a new database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE USER <em class="replaceable"><code>name</code></em> [ [ WITH ] <em class="replaceable"><code>option</code></em> [ ... ] ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <em class="replaceable"><code>connlimit</code></em>
+ | [ ENCRYPTED ] PASSWORD '<em class="replaceable"><code>password</code></em>' | PASSWORD NULL
+ | VALID UNTIL '<em class="replaceable"><code>timestamp</code></em>'
+ | IN ROLE <em class="replaceable"><code>role_name</code></em> [, ...]
+ | IN GROUP <em class="replaceable"><code>role_name</code></em> [, ...]
+ | ROLE <em class="replaceable"><code>role_name</code></em> [, ...]
+ | ADMIN <em class="replaceable"><code>role_name</code></em> [, ...]
+ | USER <em class="replaceable"><code>role_name</code></em> [, ...]
+ | SYSID <em class="replaceable"><code>uid</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.95.5"><h2>Description</h2><p>
+ <code class="command">CREATE USER</code> is now an alias for
+ <a class="link" href="sql-createrole.html" title="CREATE ROLE"><code class="command">CREATE ROLE</code></a>.
+ The only difference is that when the command is spelled
+ <code class="command">CREATE USER</code>, <code class="literal">LOGIN</code> is assumed
+ by default, whereas <code class="literal">NOLOGIN</code> is assumed when
+ the command is spelled
+ <code class="command">CREATE ROLE</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.95.6"><h2>Compatibility</h2><p>
+ The <code class="command">CREATE USER</code> statement is a
+ <span class="productname">PostgreSQL</span> extension. The SQL standard
+ leaves the definition of users to the implementation.
+ </p></div><div class="refsect1" id="id-1.9.3.95.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtype.html" title="CREATE TYPE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createusermapping.html" title="CREATE USER MAPPING">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TYPE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE USER MAPPING</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createusermapping.html b/doc/src/sgml/html/sql-createusermapping.html
new file mode 100644
index 0000000..9060fc1
--- /dev/null
+++ b/doc/src/sgml/html/sql-createusermapping.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE USER MAPPING</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createuser.html" title="CREATE USER" /><link rel="next" href="sql-createview.html" title="CREATE VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE USER MAPPING</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createuser.html" title="CREATE USER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createview.html" title="CREATE VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEUSERMAPPING"><div class="titlepage"></div><a id="id-1.9.3.96.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE USER MAPPING</span></h2><p>CREATE USER MAPPING — define a new mapping of a user to a foreign server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE USER MAPPING [ IF NOT EXISTS ] FOR { <em class="replaceable"><code>user_name</code></em> | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC }
+ SERVER <em class="replaceable"><code>server_name</code></em>
+ [ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [ , ... ] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.96.5"><h2>Description</h2><p>
+ <code class="command">CREATE USER MAPPING</code> defines a mapping of a user
+ to a foreign server. A user mapping typically encapsulates
+ connection information that a foreign-data wrapper uses together
+ with the information encapsulated by a foreign server to access an
+ external data resource.
+ </p><p>
+ The owner of a foreign server can create user mappings for that
+ server for any user. Also, a user can create a user mapping for
+ their own user name if <code class="literal">USAGE</code> privilege on the server has
+ been granted to the user.
+ </p></div><div class="refsect1" id="id-1.9.3.96.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
+ Do not throw an error if a mapping of the given user to the given foreign
+ server already exists. A notice is issued in this case. Note that there
+ is no guarantee that the existing user mapping is anything like the one
+ that would have been created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ The name of an existing user that is mapped to foreign server.
+ <code class="literal">CURRENT_ROLE</code>, <code class="literal">CURRENT_USER</code>, and <code class="literal">USER</code> match the name of
+ the current user. When <code class="literal">PUBLIC</code> is specified, a
+ so-called public mapping is created that is used when no
+ user-specific mapping is applicable.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_name</code></em></span></dt><dd><p>
+ The name of an existing server for which the user mapping is
+ to be created.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] )</code></span></dt><dd><p>
+ This clause specifies the options of the user mapping. The
+ options typically define the actual user name and password of
+ the mapping. Option names must be unique. The allowed option
+ names and values are specific to the server's foreign-data wrapper.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.96.7"><h2>Examples</h2><p>
+ Create a user mapping for user <code class="literal">bob</code>, server <code class="literal">foo</code>:
+</p><pre class="programlisting">
+CREATE USER MAPPING FOR bob SERVER foo OPTIONS (user 'bob', password 'secret');
+</pre></div><div class="refsect1" id="id-1.9.3.96.8"><h2>Compatibility</h2><p>
+ <code class="command">CREATE USER MAPPING</code> conforms to ISO/IEC 9075-9 (SQL/MED).
+ </p></div><div class="refsect1" id="id-1.9.3.96.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterusermapping.html" title="ALTER USER MAPPING"><span class="refentrytitle">ALTER USER MAPPING</span></a>, <a class="xref" href="sql-dropusermapping.html" title="DROP USER MAPPING"><span class="refentrytitle">DROP USER MAPPING</span></a>, <a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a>, <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createuser.html" title="CREATE USER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createview.html" title="CREATE VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE USER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-createview.html b/doc/src/sgml/html/sql-createview.html
new file mode 100644
index 0000000..ea1819e
--- /dev/null
+++ b/doc/src/sgml/html/sql-createview.html
@@ -0,0 +1,346 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createusermapping.html" title="CREATE USER MAPPING" /><link rel="next" href="sql-deallocate.html" title="DEALLOCATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createusermapping.html" title="CREATE USER MAPPING">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-deallocate.html" title="DEALLOCATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATEVIEW"><div class="titlepage"></div><a id="id-1.9.3.97.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE VIEW</span></h2><p>CREATE VIEW — define a new view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW <em class="replaceable"><code>name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ [ WITH ( <em class="replaceable"><code>view_option_name</code></em> [= <em class="replaceable"><code>view_option_value</code></em>] [, ... ] ) ]
+ AS <em class="replaceable"><code>query</code></em>
+ [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
+</pre></div><div class="refsect1" id="id-1.9.3.97.5"><h2>Description</h2><p>
+ <code class="command">CREATE VIEW</code> defines a view of a query. The view
+ is not physically materialized. Instead, the query is run every time
+ the view is referenced in a query.
+ </p><p>
+ <code class="command">CREATE OR REPLACE VIEW</code> is similar, but if a view
+ of the same name already exists, it is replaced. The new query must
+ generate the same columns that were generated by the existing view query
+ (that is, the same column names in the same order and with the same data
+ types), but it may add additional columns to the end of the list. The
+ calculations giving rise to the output columns may be completely different.
+ </p><p>
+ If a schema name is given (for example, <code class="literal">CREATE VIEW
+ myschema.myview ...</code>) then the view is created in the specified
+ schema. Otherwise it is created in the current schema. Temporary
+ views exist in a special schema, so a schema name cannot be given
+ when creating a temporary view. The name of the view must be
+ distinct from the name of any other relation (table, sequence, index, view,
+ materialized view, or foreign table) in the same schema.
+ </p></div><div class="refsect1" id="id-1.9.3.97.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></span></dt><dd><p>
+ If specified, the view is created as a temporary view.
+ Temporary views are automatically dropped at the end of the
+ current session. Existing
+ permanent relations with the same name are not visible to the
+ current session while the temporary view exists, unless they are
+ referenced with schema-qualified names.
+ </p><p>
+ If any of the tables referenced by the view are temporary,
+ the view is created as a temporary view (whether
+ <code class="literal">TEMPORARY</code> is specified or not).
+ </p></dd><dt><span class="term"><code class="literal">RECURSIVE</code>
+ <a id="id-1.9.3.97.6.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Creates a recursive view. The syntax
+</p><pre class="synopsis">
+CREATE RECURSIVE VIEW [ <em class="replaceable"><code>schema</code></em> . ] <em class="replaceable"><code>view_name</code></em> (<em class="replaceable"><code>column_names</code></em>) AS SELECT <em class="replaceable"><code>...</code></em>;
+</pre><p>
+ is equivalent to
+</p><pre class="synopsis">
+CREATE VIEW [ <em class="replaceable"><code>schema</code></em> . ] <em class="replaceable"><code>view_name</code></em> AS WITH RECURSIVE <em class="replaceable"><code>view_name</code></em> (<em class="replaceable"><code>column_names</code></em>) AS (SELECT <em class="replaceable"><code>...</code></em>) SELECT <em class="replaceable"><code>column_names</code></em> FROM <em class="replaceable"><code>view_name</code></em>;
+</pre><p>
+ A view column name list must be specified for a recursive view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a view to be created.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ An optional list of names to be used for columns of the view.
+ If not given, the column names are deduced from the query.
+ </p></dd><dt><span class="term"><code class="literal">WITH ( <em class="replaceable"><code>view_option_name</code></em> [= <em class="replaceable"><code>view_option_value</code></em>] [, ... ] )</code></span></dt><dd><p>
+ This clause specifies optional parameters for a view; the following
+ parameters are supported:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">check_option</code> (<code class="type">enum</code>)</span></dt><dd><p>
+ This parameter may be either <code class="literal">local</code> or
+ <code class="literal">cascaded</code>, and is equivalent to specifying
+ <code class="literal">WITH [ CASCADED | LOCAL ] CHECK OPTION</code> (see below).
+ </p></dd><dt><span class="term"><code class="literal">security_barrier</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This should be used if the view is intended to provide row-level
+ security. See <a class="xref" href="rules-privileges.html" title="41.5. Rules and Privileges">Section 41.5</a> for full details.
+ </p></dd><dt><span class="term"><code class="literal">security_invoker</code> (<code class="type">boolean</code>)</span></dt><dd><p>
+ This option causes the underlying base relations to be checked
+ against the privileges of the user of the view rather than the view
+ owner. See the notes below for full details.
+ </p></dd></dl></div><p>
+
+ All of the above options can be changed on existing views using <a class="link" href="sql-alterview.html" title="ALTER VIEW"><code class="command">ALTER VIEW</code></a>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a> or
+ <a class="link" href="sql-values.html" title="VALUES"><code class="command">VALUES</code></a> command
+ which will provide the columns and rows of the view.
+ </p></dd><dt><span class="term"><code class="literal">WITH [ CASCADED | LOCAL ] CHECK OPTION</code>
+ <a id="id-1.9.3.97.6.2.7.1.2" class="indexterm"></a>
+ <a id="id-1.9.3.97.6.2.7.1.3" class="indexterm"></a>
+ </span></dt><dd><p>
+ This option controls the behavior of automatically updatable views. When
+ this option is specified, <code class="command">INSERT</code> and <code class="command">UPDATE</code>
+ commands on the view will be checked to ensure that new rows satisfy the
+ view-defining condition (that is, the new rows are checked to ensure that
+ they are visible through the view). If they are not, the update will be
+ rejected. If the <code class="literal">CHECK OPTION</code> is not specified,
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> commands on the view are
+ allowed to create rows that are not visible through the view. The
+ following check options are supported:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">LOCAL</code></span></dt><dd><p>
+ New rows are only checked against the conditions defined directly in
+ the view itself. Any conditions defined on underlying base views are
+ not checked (unless they also specify the <code class="literal">CHECK OPTION</code>).
+ </p></dd><dt><span class="term"><code class="literal">CASCADED</code></span></dt><dd><p>
+ New rows are checked against the conditions of the view and all
+ underlying base views. If the <code class="literal">CHECK OPTION</code> is specified,
+ and neither <code class="literal">LOCAL</code> nor <code class="literal">CASCADED</code> is specified,
+ then <code class="literal">CASCADED</code> is assumed.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <code class="literal">CHECK OPTION</code> may not be used with <code class="literal">RECURSIVE</code>
+ views.
+ </p><p>
+ Note that the <code class="literal">CHECK OPTION</code> is only supported on views that
+ are automatically updatable, and do not have <code class="literal">INSTEAD OF</code>
+ triggers or <code class="literal">INSTEAD</code> rules. If an automatically updatable
+ view is defined on top of a base view that has <code class="literal">INSTEAD OF</code>
+ triggers, then the <code class="literal">LOCAL CHECK OPTION</code> may be used to check
+ the conditions on the automatically updatable view, but the conditions
+ on the base view with <code class="literal">INSTEAD OF</code> triggers will not be
+ checked (a cascaded check option will not cascade down to a
+ trigger-updatable view, and any check options defined directly on a
+ trigger-updatable view will be ignored). If the view or any of its base
+ relations has an <code class="literal">INSTEAD</code> rule that causes the
+ <code class="command">INSERT</code> or <code class="command">UPDATE</code> command to be rewritten, then
+ all check options will be ignored in the rewritten query, including any
+ checks from automatically updatable views defined on top of the relation
+ with the <code class="literal">INSTEAD</code> rule.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.97.7"><h2>Notes</h2><p>
+ Use the <a class="link" href="sql-dropview.html" title="DROP VIEW"><code class="command">DROP VIEW</code></a>
+ statement to drop views.
+ </p><p>
+ Be careful that the names and types of the view's columns will be
+ assigned the way you want. For example:
+</p><pre class="programlisting">
+CREATE VIEW vista AS SELECT 'Hello World';
+</pre><p>
+ is bad form because the column name defaults to <code class="literal">?column?</code>;
+ also, the column data type defaults to <code class="type">text</code>, which might not
+ be what you wanted. Better style for a string literal in a view's
+ result is something like:
+</p><pre class="programlisting">
+CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
+</pre><p>
+ </p><p>
+ By default, access to the underlying base relations referenced in the view
+ is determined by the permissions of the view owner. In some cases, this
+ can be used to provide secure but restricted access to the underlying
+ tables. However, not all views are secure against tampering; see <a class="xref" href="rules-privileges.html" title="41.5. Rules and Privileges">Section 41.5</a> for details.
+ </p><p>
+ If the view has the <code class="literal">security_invoker</code> property set to
+ <code class="literal">true</code>, access to the underlying base relations is
+ determined by the permissions of the user executing the query, rather than
+ the view owner. Thus, the user of a security invoker view must have the
+ relevant permissions on the view and its underlying base relations.
+ </p><p>
+ If any of the underlying base relations is a security invoker view, it
+ will be treated as if it had been accessed directly from the original
+ query. Thus, a security invoker view will always check its underlying
+ base relations using the permissions of the current user, even if it is
+ accessed from a view without the <code class="literal">security_invoker</code>
+ property.
+ </p><p>
+ If any of the underlying base relations has
+ <a class="link" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">row-level security</a> enabled, then
+ by default, the row-level security policies of the view owner are applied,
+ and access to any additional relations referred to by those policies is
+ determined by the permissions of the view owner. However, if the view has
+ <code class="literal">security_invoker</code> set to <code class="literal">true</code>, then
+ the policies and permissions of the invoking user are used instead, as if
+ the base relations had been referenced directly from the query using the
+ view.
+ </p><p>
+ Functions called in the view are treated the same as if they had been
+ called directly from the query using the view. Therefore, the user of
+ a view must have permissions to call all functions used by the view.
+ Functions in the view are executed with the privileges of the user
+ executing the query or the function owner, depending on whether the
+ functions are defined as <code class="literal">SECURITY INVOKER</code> or
+ <code class="literal">SECURITY DEFINER</code>. Thus, for example, calling
+ <code class="literal">CURRENT_USER</code> directly in a view will always return the
+ invoking user, not the view owner. This is not affected by the view's
+ <code class="literal">security_invoker</code> setting, and so a view with
+ <code class="literal">security_invoker</code> set to <code class="literal">false</code> is
+ <span class="emphasis"><em>not</em></span> equivalent to a
+ <code class="literal">SECURITY DEFINER</code> function and those concepts should not
+ be confused.
+ </p><p>
+ The user creating or replacing a view must have <code class="literal">USAGE</code>
+ privileges on any schemas referred to in the view query, in order to look
+ up the referenced objects in those schemas. Note, however, that this
+ lookup only happens when the view is created or replaced. Therefore, the
+ user of the view only requires the <code class="literal">USAGE</code> privilege on
+ the schema containing the view, not on the schemas referred to in the view
+ query, even for a security invoker view.
+ </p><p>
+ When <code class="command">CREATE OR REPLACE VIEW</code> is used on an existing
+ view, only the view's defining SELECT rule, plus any
+ <code class="literal">WITH ( ... )</code> parameters and its
+ <code class="literal">CHECK OPTION</code> are changed.
+ Other view properties, including ownership, permissions, and non-SELECT
+ rules, remain unchanged. You must own the view
+ to replace it (this includes being a member of the owning role).
+ </p><div class="refsect2" id="SQL-CREATEVIEW-UPDATABLE-VIEWS"><h3>Updatable Views</h3><a id="id-1.9.3.97.7.11.2" class="indexterm"></a><p>
+ Simple views are automatically updatable: the system will allow
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code> and <code class="command">DELETE</code> statements
+ to be used on the view in the same way as on a regular table. A view is
+ automatically updatable if it satisfies all of the following conditions:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The view must have exactly one entry in its <code class="literal">FROM</code> list,
+ which must be a table or another updatable view.
+ </p></li><li class="listitem"><p>
+ The view definition must not contain <code class="literal">WITH</code>,
+ <code class="literal">DISTINCT</code>, <code class="literal">GROUP BY</code>, <code class="literal">HAVING</code>,
+ <code class="literal">LIMIT</code>, or <code class="literal">OFFSET</code> clauses at the top level.
+ </p></li><li class="listitem"><p>
+ The view definition must not contain set operations (<code class="literal">UNION</code>,
+ <code class="literal">INTERSECT</code> or <code class="literal">EXCEPT</code>) at the top level.
+ </p></li><li class="listitem"><p>
+ The view's select list must not contain any aggregates, window functions
+ or set-returning functions.
+ </p></li></ul></div><p>
+ </p><p>
+ An automatically updatable view may contain a mix of updatable and
+ non-updatable columns. A column is updatable if it is a simple reference
+ to an updatable column of the underlying base relation; otherwise the
+ column is read-only, and an error will be raised if an <code class="command">INSERT</code>
+ or <code class="command">UPDATE</code> statement attempts to assign a value to it.
+ </p><p>
+ If the view is automatically updatable the system will convert any
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code> or <code class="command">DELETE</code> statement
+ on the view into the corresponding statement on the underlying base
+ relation. <code class="command">INSERT</code> statements that have an <code class="literal">ON
+ CONFLICT UPDATE</code> clause are fully supported.
+ </p><p>
+ If an automatically updatable view contains a <code class="literal">WHERE</code>
+ condition, the condition restricts which rows of the base relation are
+ available to be modified by <code class="command">UPDATE</code> and <code class="command">DELETE</code>
+ statements on the view. However, an <code class="command">UPDATE</code> is allowed to
+ change a row so that it no longer satisfies the <code class="literal">WHERE</code>
+ condition, and thus is no longer visible through the view. Similarly,
+ an <code class="command">INSERT</code> command can potentially insert base-relation rows
+ that do not satisfy the <code class="literal">WHERE</code> condition and thus are not
+ visible through the view (<code class="literal">ON CONFLICT UPDATE</code> may
+ similarly affect an existing row not visible through the view).
+ The <code class="literal">CHECK OPTION</code> may be used to prevent
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> commands from creating
+ such rows that are not visible through the view.
+ </p><p>
+ If an automatically updatable view is marked with the
+ <code class="literal">security_barrier</code> property then all the view's <code class="literal">WHERE</code>
+ conditions (and any conditions using operators which are marked as <code class="literal">LEAKPROOF</code>)
+ will always be evaluated before any conditions that a user of the view has
+ added. See <a class="xref" href="rules-privileges.html" title="41.5. Rules and Privileges">Section 41.5</a> for full details. Note that,
+ due to this, rows which are not ultimately returned (because they do not
+ pass the user's <code class="literal">WHERE</code> conditions) may still end up being locked.
+ <code class="command">EXPLAIN</code> can be used to see which conditions are
+ applied at the relation level (and therefore do not lock rows) and which are
+ not.
+ </p><p>
+ A more complex view that does not satisfy all these conditions is
+ read-only by default: the system will not allow an insert, update, or
+ delete on the view. You can get the effect of an updatable view by
+ creating <code class="literal">INSTEAD OF</code> triggers on the view, which must
+ convert attempted inserts, etc. on the view into appropriate actions
+ on other tables. For more information see <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>. Another possibility is to create rules
+ (see <a class="xref" href="sql-createrule.html" title="CREATE RULE"><span class="refentrytitle">CREATE RULE</span></a>), but in practice triggers are
+ easier to understand and use correctly.
+ </p><p>
+ Note that the user performing the insert, update or delete on the view
+ must have the corresponding insert, update or delete privilege on the
+ view. In addition, by default, the view's owner must have the relevant
+ privileges on the underlying base relations, whereas the user performing
+ the update does not need any permissions on the underlying base relations
+ (see <a class="xref" href="rules-privileges.html" title="41.5. Rules and Privileges">Section 41.5</a>). However, if the view has
+ <code class="literal">security_invoker</code> set to <code class="literal">true</code>, the
+ user performing the update, rather than the view owner, must have the
+ relevant privileges on the underlying base relations.
+ </p></div></div><div class="refsect1" id="id-1.9.3.97.8"><h2>Examples</h2><p>
+ Create a view consisting of all comedy films:
+
+</p><pre class="programlisting">
+CREATE VIEW comedies AS
+ SELECT *
+ FROM films
+ WHERE kind = 'Comedy';
+</pre><p>
+ This will create a view containing the columns that are in the
+ <code class="literal">film</code> table at the time of view creation. Though
+ <code class="literal">*</code> was used to create the view, columns added later to
+ the table will not be part of the view.
+ </p><p>
+ Create a view with <code class="literal">LOCAL CHECK OPTION</code>:
+
+</p><pre class="programlisting">
+CREATE VIEW universal_comedies AS
+ SELECT *
+ FROM comedies
+ WHERE classification = 'U'
+ WITH LOCAL CHECK OPTION;
+</pre><p>
+ This will create a view based on the <code class="literal">comedies</code> view, showing
+ only films with <code class="literal">kind = 'Comedy'</code> and
+ <code class="literal">classification = 'U'</code>. Any attempt to <code class="command">INSERT</code> or
+ <code class="command">UPDATE</code> a row in the view will be rejected if the new row
+ doesn't have <code class="literal">classification = 'U'</code>, but the film
+ <code class="literal">kind</code> will not be checked.
+ </p><p>
+ Create a view with <code class="literal">CASCADED CHECK OPTION</code>:
+
+</p><pre class="programlisting">
+CREATE VIEW pg_comedies AS
+ SELECT *
+ FROM comedies
+ WHERE classification = 'PG'
+ WITH CASCADED CHECK OPTION;
+</pre><p>
+ This will create a view that checks both the <code class="literal">kind</code> and
+ <code class="literal">classification</code> of new rows.
+ </p><p>
+ Create a view with a mix of updatable and non-updatable columns:
+
+</p><pre class="programlisting">
+CREATE VIEW comedies AS
+ SELECT f.*,
+ country_code_to_name(f.country_code) AS country,
+ (SELECT avg(r.rating)
+ FROM user_ratings r
+ WHERE r.film_id = f.id) AS avg_rating
+ FROM films f
+ WHERE f.kind = 'Comedy';
+</pre><p>
+ This view will support <code class="command">INSERT</code>, <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code>. All the columns from the <code class="literal">films</code> table will
+ be updatable, whereas the computed columns <code class="literal">country</code> and
+ <code class="literal">avg_rating</code> will be read-only.
+ </p><p>
+ Create a recursive view consisting of the numbers from 1 to 100:
+</p><pre class="programlisting">
+CREATE RECURSIVE VIEW public.nums_1_100 (n) AS
+ VALUES (1)
+UNION ALL
+ SELECT n+1 FROM nums_1_100 WHERE n &lt; 100;
+</pre><p>
+ Notice that although the recursive view's name is schema-qualified in this
+ <code class="command">CREATE</code>, its internal self-reference is not schema-qualified.
+ This is because the implicitly-created CTE's name cannot be
+ schema-qualified.
+ </p></div><div class="refsect1" id="id-1.9.3.97.9"><h2>Compatibility</h2><p>
+ <code class="command">CREATE OR REPLACE VIEW</code> is a
+ <span class="productname">PostgreSQL</span> language extension.
+ So is the concept of a temporary view.
+ The <code class="literal">WITH ( ... )</code> clause is an extension as well, as are
+ security barrier views and security invoker views.
+ </p></div><div class="refsect1" id="id-1.9.3.97.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterview.html" title="ALTER VIEW"><span class="refentrytitle">ALTER VIEW</span></a>, <a class="xref" href="sql-dropview.html" title="DROP VIEW"><span class="refentrytitle">DROP VIEW</span></a>, <a class="xref" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW"><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createusermapping.html" title="CREATE USER MAPPING">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-deallocate.html" title="DEALLOCATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE USER MAPPING </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DEALLOCATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-deallocate.html b/doc/src/sgml/html/sql-deallocate.html
new file mode 100644
index 0000000..86d773a
--- /dev/null
+++ b/doc/src/sgml/html/sql-deallocate.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DEALLOCATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createview.html" title="CREATE VIEW" /><link rel="next" href="sql-declare.html" title="DECLARE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DEALLOCATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createview.html" title="CREATE VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-declare.html" title="DECLARE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DEALLOCATE"><div class="titlepage"></div><a id="id-1.9.3.98.1" class="indexterm"></a><a id="id-1.9.3.98.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DEALLOCATE</span></h2><p>DEALLOCATE — deallocate a prepared statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DEALLOCATE [ PREPARE ] { <em class="replaceable"><code>name</code></em> | ALL }
+</pre></div><div class="refsect1" id="id-1.9.3.98.6"><h2>Description</h2><p>
+ <code class="command">DEALLOCATE</code> is used to deallocate a previously
+ prepared SQL statement. If you do not explicitly deallocate a
+ prepared statement, it is deallocated when the session ends.
+ </p><p>
+ For more information on prepared statements, see <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.98.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">PREPARE</code></span></dt><dd><p>
+ This key word is ignored.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the prepared statement to deallocate.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Deallocate all prepared statements.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.98.8"><h2>Compatibility</h2><p>
+ The SQL standard includes a <code class="command">DEALLOCATE</code>
+ statement, but it is only for use in embedded SQL.
+ </p></div><div class="refsect1" id="id-1.9.3.98.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-execute.html" title="EXECUTE"><span class="refentrytitle">EXECUTE</span></a>, <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createview.html" title="CREATE VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-declare.html" title="DECLARE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DECLARE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-declare.html b/doc/src/sgml/html/sql-declare.html
new file mode 100644
index 0000000..d600b61
--- /dev/null
+++ b/doc/src/sgml/html/sql-declare.html
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DECLARE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-deallocate.html" title="DEALLOCATE" /><link rel="next" href="sql-delete.html" title="DELETE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DECLARE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-deallocate.html" title="DEALLOCATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-delete.html" title="DELETE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DECLARE"><div class="titlepage"></div><a id="id-1.9.3.99.1" class="indexterm"></a><a id="id-1.9.3.99.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DECLARE</span></h2><p>DECLARE — define a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DECLARE <em class="replaceable"><code>name</code></em> [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
+ CURSOR [ { WITH | WITHOUT } HOLD ] FOR <em class="replaceable"><code>query</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.99.6"><h2>Description</h2><p>
+ <code class="command">DECLARE</code> allows a user to create cursors, which
+ can be used to retrieve
+ a small number of rows at a time out of a larger query.
+ After the cursor is created, rows are fetched from it using
+ <a class="link" href="sql-fetch.html" title="FETCH"><code class="command">FETCH</code></a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This page describes usage of cursors at the SQL command level.
+ If you are trying to use cursors inside a <span class="application">PL/pgSQL</span>
+ function, the rules are different —
+ see <a class="xref" href="plpgsql-cursors.html" title="43.7. Cursors">Section 43.7</a>.
+ </p></div></div><div class="refsect1" id="id-1.9.3.99.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the cursor to be created.
+ </p></dd><dt><span class="term"><code class="literal">BINARY</code></span></dt><dd><p>
+ Causes the cursor to return data in binary rather than in text format.
+ </p></dd><dt><span class="term"><code class="literal">ASENSITIVE</code><br /></span><span class="term"><code class="literal">INSENSITIVE</code></span></dt><dd><p>
+ Cursor sensitivity determines whether changes to the data underlying the
+ cursor, done in the same transaction, after the cursor has been
+ declared, are visible in the cursor. <code class="literal">INSENSITIVE</code>
+ means they are not visible, <code class="literal">ASENSITIVE</code> means the
+ behavior is implementation-dependent. A third behavior,
+ <code class="literal">SENSITIVE</code>, meaning that such changes are visible in
+ the cursor, is not available in <span class="productname">PostgreSQL</span>.
+ In <span class="productname">PostgreSQL</span>, all cursors are insensitive;
+ so these key words have no effect and are only accepted for
+ compatibility with the SQL standard.
+ </p><p>
+ Specifying <code class="literal">INSENSITIVE</code> together with <code class="literal">FOR
+ UPDATE</code> or <code class="literal">FOR SHARE</code> is an error.
+ </p></dd><dt><span class="term"><code class="literal">SCROLL</code><br /></span><span class="term"><code class="literal">NO SCROLL</code></span></dt><dd><p><code class="literal">SCROLL</code> specifies that the cursor can be used
+ to retrieve rows in a nonsequential fashion (e.g.,
+ backward). Depending upon the complexity of the query's
+ execution plan, specifying <code class="literal">SCROLL</code> might impose
+ a performance penalty on the query's execution time.
+ <code class="literal">NO SCROLL</code> specifies that the cursor cannot be
+ used to retrieve rows in a nonsequential fashion. The default is to
+ allow scrolling in some cases; this is not the same as specifying
+ <code class="literal">SCROLL</code>. See <a class="xref" href="sql-declare.html#SQL-DECLARE-NOTES" title="Notes">Notes</a>
+ below for details.
+ </p></dd><dt><span class="term"><code class="literal">WITH HOLD</code><br /></span><span class="term"><code class="literal">WITHOUT HOLD</code></span></dt><dd><p><code class="literal">WITH HOLD</code> specifies that the cursor can
+ continue to be used after the transaction that created it
+ successfully commits. <code class="literal">WITHOUT HOLD</code> specifies
+ that the cursor cannot be used outside of the transaction that
+ created it. If neither <code class="literal">WITHOUT HOLD</code> nor
+ <code class="literal">WITH HOLD</code> is specified, <code class="literal">WITHOUT
+ HOLD</code> is the default.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a> or
+ <a class="link" href="sql-values.html" title="VALUES"><code class="command">VALUES</code></a> command
+ which will provide the rows to be returned by the cursor.
+ </p></dd></dl></div><p>
+ The key words <code class="literal">ASENSITIVE</code>, <code class="literal">BINARY</code>,
+ <code class="literal">INSENSITIVE</code>, and <code class="literal">SCROLL</code> can
+ appear in any order.
+ </p></div><div class="refsect1" id="SQL-DECLARE-NOTES"><h2>Notes</h2><p>
+ Normal cursors return data in text format, the same as a
+ <code class="command">SELECT</code> would produce. The <code class="literal">BINARY</code> option
+ specifies that the cursor should return data in binary format.
+ This reduces conversion effort for both the server and client,
+ at the cost of more programmer effort to deal with platform-dependent
+ binary data formats.
+ As an example, if a query returns a value of one from an integer column,
+ you would get a string of <code class="literal">1</code> with a default cursor,
+ whereas with a binary cursor you would get
+ a 4-byte field containing the internal representation of the value
+ (in big-endian byte order).
+ </p><p>
+ Binary cursors should be used carefully. Many applications,
+ including <span class="application">psql</span>, are not prepared to
+ handle binary cursors and expect data to come back in the text
+ format.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ When the client application uses the <span class="quote">“<span class="quote">extended query</span>”</span> protocol
+ to issue a <code class="command">FETCH</code> command, the Bind protocol message
+ specifies whether data is to be retrieved in text or binary format.
+ This choice overrides the way that the cursor is defined. The concept
+ of a binary cursor as such is thus obsolete when using extended query
+ protocol — any cursor can be treated as either text or binary.
+ </p></div><p>
+ Unless <code class="literal">WITH HOLD</code> is specified, the cursor
+ created by this command can only be used within the current
+ transaction. Thus, <code class="command">DECLARE</code> without <code class="literal">WITH
+ HOLD</code> is useless outside a transaction block: the cursor would
+ survive only to the completion of the statement. Therefore
+ <span class="productname">PostgreSQL</span> reports an error if such a
+ command is used outside a transaction block.
+ Use
+ <a class="link" href="sql-begin.html" title="BEGIN"><code class="command">BEGIN</code></a> and
+ <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a>
+ (or <a class="link" href="sql-rollback.html" title="ROLLBACK"><code class="command">ROLLBACK</code></a>)
+ to define a transaction block.
+ </p><p>
+ If <code class="literal">WITH HOLD</code> is specified and the transaction
+ that created the cursor successfully commits, the cursor can
+ continue to be accessed by subsequent transactions in the same
+ session. (But if the creating transaction is aborted, the cursor
+ is removed.) A cursor created with <code class="literal">WITH HOLD</code>
+ is closed when an explicit <code class="command">CLOSE</code> command is
+ issued on it, or the session ends. In the current implementation,
+ the rows represented by a held cursor are copied into a temporary
+ file or memory area so that they remain available for subsequent
+ transactions.
+ </p><p>
+ <code class="literal">WITH HOLD</code> may not be specified when the query
+ includes <code class="literal">FOR UPDATE</code> or <code class="literal">FOR SHARE</code>.
+ </p><p>
+ The <code class="literal">SCROLL</code> option should be specified when defining a
+ cursor that will be used to fetch backwards. This is required by
+ the SQL standard. However, for compatibility with earlier
+ versions, <span class="productname">PostgreSQL</span> will allow
+ backward fetches without <code class="literal">SCROLL</code>, if the cursor's query
+ plan is simple enough that no extra overhead is needed to support
+ it. However, application developers are advised not to rely on
+ using backward fetches from a cursor that has not been created
+ with <code class="literal">SCROLL</code>. If <code class="literal">NO SCROLL</code> is
+ specified, then backward fetches are disallowed in any case.
+ </p><p>
+ Backward fetches are also disallowed when the query
+ includes <code class="literal">FOR UPDATE</code> or <code class="literal">FOR SHARE</code>; therefore
+ <code class="literal">SCROLL</code> may not be specified in this case.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ Scrollable cursors may give unexpected
+ results if they invoke any volatile functions (see <a class="xref" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Section 38.7</a>). When a previously fetched row is
+ re-fetched, the functions might be re-executed, perhaps leading to
+ results different from the first time. It's best to
+ specify <code class="literal">NO SCROLL</code> for a query involving volatile
+ functions. If that is not practical, one workaround
+ is to declare the cursor <code class="literal">SCROLL WITH HOLD</code> and commit the
+ transaction before reading any rows from it. This will force the
+ entire output of the cursor to be materialized in temporary storage,
+ so that volatile functions are executed exactly once for each row.
+ </p></div><p>
+ If the cursor's query includes <code class="literal">FOR UPDATE</code> or <code class="literal">FOR
+ SHARE</code>, then returned rows are locked at the time they are first
+ fetched, in the same way as for a regular
+ <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a> command with
+ these options.
+ In addition, the returned rows will be the most up-to-date versions.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is generally recommended to use <code class="literal">FOR UPDATE</code> if the cursor
+ is intended to be used with <code class="command">UPDATE ... WHERE CURRENT OF</code> or
+ <code class="command">DELETE ... WHERE CURRENT OF</code>. Using <code class="literal">FOR UPDATE</code>
+ prevents other sessions from changing the rows between the time they are
+ fetched and the time they are updated. Without <code class="literal">FOR UPDATE</code>,
+ a subsequent <code class="literal">WHERE CURRENT OF</code> command will have no effect if
+ the row was changed since the cursor was created.
+ </p><p>
+ Another reason to use <code class="literal">FOR UPDATE</code> is that without it, a
+ subsequent <code class="literal">WHERE CURRENT OF</code> might fail if the cursor query
+ does not meet the SQL standard's rules for being <span class="quote">“<span class="quote">simply
+ updatable</span>”</span> (in particular, the cursor must reference just one table
+ and not use grouping or <code class="literal">ORDER BY</code>). Cursors
+ that are not simply updatable might work, or might not, depending on plan
+ choice details; so in the worst case, an application might work in testing
+ and then fail in production. If <code class="literal">FOR UPDATE</code> is
+ specified, the cursor is guaranteed to be updatable.
+ </p><p>
+ The main reason not to use <code class="literal">FOR UPDATE</code> with <code class="literal">WHERE
+ CURRENT OF</code> is if you need the cursor to be scrollable, or to be
+ isolated from concurrent updates (that is, continue to show the old
+ data). If this is a requirement, pay close heed to the caveats shown
+ above.
+ </p></div><p>
+ The SQL standard only makes provisions for cursors in embedded
+ <acronym class="acronym">SQL</acronym>. The <span class="productname">PostgreSQL</span>
+ server does not implement an <code class="command">OPEN</code> statement for
+ cursors; a cursor is considered to be open when it is declared.
+ However, <span class="application">ECPG</span>, the embedded SQL
+ preprocessor for <span class="productname">PostgreSQL</span>, supports
+ the standard SQL cursor conventions, including those involving
+ <code class="command">DECLARE</code> and <code class="command">OPEN</code> statements.
+ </p><p>
+ You can see all available cursors by querying the <a class="link" href="view-pg-cursors.html" title="54.6. pg_cursors"><code class="structname">pg_cursors</code></a>
+ system view.
+ </p></div><div class="refsect1" id="id-1.9.3.99.9"><h2>Examples</h2><p>
+ To declare a cursor:
+</p><pre class="programlisting">
+DECLARE liahona CURSOR FOR SELECT * FROM films;
+</pre><p>
+ See <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a> for more
+ examples of cursor usage.
+ </p></div><div class="refsect1" id="id-1.9.3.99.10"><h2>Compatibility</h2><p>
+ The SQL standard allows cursors only in embedded
+ <acronym class="acronym">SQL</acronym> and in modules. <span class="productname">PostgreSQL</span>
+ permits cursors to be used interactively.
+ </p><p>
+ According to the SQL standard, changes made to insensitive cursors by
+ <code class="literal">UPDATE ... WHERE CURRENT OF</code> and <code class="literal">DELETE
+ ... WHERE CURRENT OF</code> statements are visible in that same
+ cursor. <span class="productname">PostgreSQL</span> treats these statements like
+ all other data changing statements in that they are not visible in
+ insensitive cursors.
+ </p><p>
+ Binary cursors are a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.99.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-close.html" title="CLOSE"><span class="refentrytitle">CLOSE</span></a>, <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a>, <a class="xref" href="sql-move.html" title="MOVE"><span class="refentrytitle">MOVE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-deallocate.html" title="DEALLOCATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-delete.html" title="DELETE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DEALLOCATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DELETE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-delete.html b/doc/src/sgml/html/sql-delete.html
new file mode 100644
index 0000000..3f156a6
--- /dev/null
+++ b/doc/src/sgml/html/sql-delete.html
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DELETE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-declare.html" title="DECLARE" /><link rel="next" href="sql-discard.html" title="DISCARD" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DELETE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-declare.html" title="DECLARE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-discard.html" title="DISCARD">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DELETE"><div class="titlepage"></div><a id="id-1.9.3.100.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DELETE</span></h2><p>DELETE — delete rows of a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+[ WITH [ RECURSIVE ] <em class="replaceable"><code>with_query</code></em> [, ...] ]
+DELETE FROM [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ * ] [ [ AS ] <em class="replaceable"><code>alias</code></em> ]
+ [ USING <em class="replaceable"><code>from_item</code></em> [, ...] ]
+ [ WHERE <em class="replaceable"><code>condition</code></em> | WHERE CURRENT OF <em class="replaceable"><code>cursor_name</code></em> ]
+ [ RETURNING * | <em class="replaceable"><code>output_expression</code></em> [ [ AS ] <em class="replaceable"><code>output_name</code></em> ] [, ...] ]
+</pre></div><div class="refsect1" id="id-1.9.3.100.5"><h2>Description</h2><p>
+ <code class="command">DELETE</code> deletes rows that satisfy the
+ <code class="literal">WHERE</code> clause from the specified table. If the
+ <code class="literal">WHERE</code> clause is absent, the effect is to delete
+ all rows in the table. The result is a valid, but empty table.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <a class="link" href="sql-truncate.html" title="TRUNCATE"><code class="command">TRUNCATE</code></a> provides a
+ faster mechanism to remove all rows from a table.
+ </p></div><p>
+ There are two ways to delete rows in a table using information
+ contained in other tables in the database: using sub-selects, or
+ specifying additional tables in the <code class="literal">USING</code> clause.
+ Which technique is more appropriate depends on the specific
+ circumstances.
+ </p><p>
+ The optional <code class="literal">RETURNING</code> clause causes <code class="command">DELETE</code>
+ to compute and return value(s) based on each row actually deleted.
+ Any expression using the table's columns, and/or columns of other
+ tables mentioned in <code class="literal">USING</code>, can be computed.
+ The syntax of the <code class="literal">RETURNING</code> list is identical to that of the
+ output list of <code class="command">SELECT</code>.
+ </p><p>
+ You must have the <code class="literal">DELETE</code> privilege on the table
+ to delete from it, as well as the <code class="literal">SELECT</code>
+ privilege for any table in the <code class="literal">USING</code> clause or
+ whose values are read in the <em class="replaceable"><code>condition</code></em>.
+ </p></div><div class="refsect1" id="id-1.9.3.100.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>with_query</code></em></span></dt><dd><p>
+ The <code class="literal">WITH</code> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <code class="command">DELETE</code>
+ query. See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a> and <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>
+ for details.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to delete rows
+ from. If <code class="literal">ONLY</code> is specified before the table name,
+ matching rows are deleted from the named table only. If
+ <code class="literal">ONLY</code> is not specified, matching rows are also deleted
+ from any tables inheriting from the named table. Optionally,
+ <code class="literal">*</code> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>alias</code></em></span></dt><dd><p>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <code class="literal">DELETE FROM foo AS f</code>, the remainder
+ of the <code class="command">DELETE</code> statement must refer to this
+ table as <code class="literal">f</code> not <code class="literal">foo</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>from_item</code></em></span></dt><dd><p>
+ A table expression allowing columns from other tables to appear
+ in the <code class="literal">WHERE</code> condition. This uses the same
+ syntax as the <a class="link" href="sql-select.html#SQL-FROM" title="FROM Clause"><code class="literal">FROM</code></a>
+ clause of a <code class="command">SELECT</code> statement; for example, an alias
+ for the table name can be specified. Do not repeat the target
+ table as a <em class="replaceable"><code>from_item</code></em>
+ unless you wish to set up a self-join (in which case it must appear
+ with an alias in the <em class="replaceable"><code>from_item</code></em>).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
+ An expression that returns a value of type <code class="type">boolean</code>.
+ Only rows for which this expression returns <code class="literal">true</code>
+ will be deleted.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>cursor_name</code></em></span></dt><dd><p>
+ The name of the cursor to use in a <code class="literal">WHERE CURRENT OF</code>
+ condition. The row to be deleted is the one most recently fetched
+ from this cursor. The cursor must be a non-grouping
+ query on the <code class="command">DELETE</code>'s target table.
+ Note that <code class="literal">WHERE CURRENT OF</code> cannot be
+ specified together with a Boolean condition. See
+ <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>
+ for more information about using cursors with
+ <code class="literal">WHERE CURRENT OF</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_expression</code></em></span></dt><dd><p>
+ An expression to be computed and returned by the <code class="command">DELETE</code>
+ command after each row is deleted. The expression can use any
+ column names of the table named by <em class="replaceable"><code>table_name</code></em>
+ or table(s) listed in <code class="literal">USING</code>.
+ Write <code class="literal">*</code> to return all columns.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_name</code></em></span></dt><dd><p>
+ A name to use for a returned column.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.100.7"><h2>Outputs</h2><p>
+ On successful completion, a <code class="command">DELETE</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+DELETE <em class="replaceable"><code>count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>count</code></em> is the number
+ of rows deleted. Note that the number may be less than the number of
+ rows that matched the <em class="replaceable"><code>condition</code></em> when deletes were
+ suppressed by a <code class="literal">BEFORE DELETE</code> trigger. If <em class="replaceable"><code>count</code></em> is 0, no rows were deleted by
+ the query (this is not considered an error).
+ </p><p>
+ If the <code class="command">DELETE</code> command contains a <code class="literal">RETURNING</code>
+ clause, the result will be similar to that of a <code class="command">SELECT</code>
+ statement containing the columns and values defined in the
+ <code class="literal">RETURNING</code> list, computed over the row(s) deleted by the
+ command.
+ </p></div><div class="refsect1" id="id-1.9.3.100.8"><h2>Notes</h2><p>
+ <span class="productname">PostgreSQL</span> lets you reference columns of
+ other tables in the <code class="literal">WHERE</code> condition by specifying the
+ other tables in the <code class="literal">USING</code> clause. For example,
+ to delete all films produced by a given producer, one can do:
+</p><pre class="programlisting">
+DELETE FROM films USING producers
+ WHERE producer_id = producers.id AND producers.name = 'foo';
+</pre><p>
+ What is essentially happening here is a join between <code class="structname">films</code>
+ and <code class="structname">producers</code>, with all successfully joined
+ <code class="structname">films</code> rows being marked for deletion.
+ This syntax is not standard. A more standard way to do it is:
+</p><pre class="programlisting">
+DELETE FROM films
+ WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
+</pre><p>
+ In some cases the join style is easier to write or faster to
+ execute than the sub-select style.
+ </p></div><div class="refsect1" id="id-1.9.3.100.9"><h2>Examples</h2><p>
+ Delete all films but musicals:
+</p><pre class="programlisting">
+DELETE FROM films WHERE kind &lt;&gt; 'Musical';
+</pre><p>
+ </p><p>
+ Clear the table <code class="literal">films</code>:
+</p><pre class="programlisting">
+DELETE FROM films;
+</pre><p>
+ </p><p>
+ Delete completed tasks, returning full details of the deleted rows:
+</p><pre class="programlisting">
+DELETE FROM tasks WHERE status = 'DONE' RETURNING *;
+</pre><p>
+ </p><p>
+ Delete the row of <code class="structname">tasks</code> on which the cursor
+ <code class="literal">c_tasks</code> is currently positioned:
+</p><pre class="programlisting">
+DELETE FROM tasks WHERE CURRENT OF c_tasks;
+</pre></div><div class="refsect1" id="id-1.9.3.100.10"><h2>Compatibility</h2><p>
+ This command conforms to the <acronym class="acronym">SQL</acronym> standard, except
+ that the <code class="literal">USING</code> and <code class="literal">RETURNING</code> clauses
+ are <span class="productname">PostgreSQL</span> extensions, as is the ability
+ to use <code class="literal">WITH</code> with <code class="command">DELETE</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.100.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-truncate.html" title="TRUNCATE"><span class="refentrytitle">TRUNCATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-declare.html" title="DECLARE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-discard.html" title="DISCARD">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DECLARE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DISCARD</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-discard.html b/doc/src/sgml/html/sql-discard.html
new file mode 100644
index 0000000..d73a273
--- /dev/null
+++ b/doc/src/sgml/html/sql-discard.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DISCARD</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-delete.html" title="DELETE" /><link rel="next" href="sql-do.html" title="DO" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DISCARD</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-delete.html" title="DELETE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-do.html" title="DO">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DISCARD"><div class="titlepage"></div><a id="id-1.9.3.101.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DISCARD</span></h2><p>DISCARD — discard session state</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
+</pre></div><div class="refsect1" id="id-1.9.3.101.5"><h2>Description</h2><p>
+ <code class="command">DISCARD</code> releases internal resources associated with a
+ database session. This command is useful for partially or fully
+ resetting the session's state. There are several subcommands to
+ release different types of resources; the <code class="command">DISCARD ALL</code>
+ variant subsumes all the others, and also resets additional state.
+ </p></div><div class="refsect1" id="id-1.9.3.101.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">PLANS</code></span></dt><dd><p>
+ Releases all cached query plans, forcing re-planning to occur
+ the next time the associated prepared statement is used.
+ </p></dd><dt><span class="term"><code class="literal">SEQUENCES</code></span></dt><dd><p>
+ Discards all cached sequence-related state,
+ including <code class="function">currval()</code>/<code class="function">lastval()</code>
+ information and any preallocated sequence values that have not
+ yet been returned by <code class="function">nextval()</code>.
+ (See <a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a> for a description of
+ preallocated sequence values.)
+ </p></dd><dt><span class="term"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></span></dt><dd><p>
+ Drops all temporary tables created in the current session.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Releases all temporary resources associated with the current
+ session and resets the session to its initial state.
+ Currently, this has the same effect as executing the following sequence
+ of statements:
+</p><pre class="programlisting">
+CLOSE ALL;
+SET SESSION AUTHORIZATION DEFAULT;
+RESET ALL;
+DEALLOCATE ALL;
+UNLISTEN *;
+SELECT pg_advisory_unlock_all();
+DISCARD PLANS;
+DISCARD TEMP;
+DISCARD SEQUENCES;
+</pre></dd></dl></div></div><div class="refsect1" id="id-1.9.3.101.7"><h2>Notes</h2><p>
+ <code class="command">DISCARD ALL</code> cannot be executed inside a transaction block.
+ </p></div><div class="refsect1" id="id-1.9.3.101.8"><h2>Compatibility</h2><p>
+ <code class="command">DISCARD</code> is a <span class="productname">PostgreSQL</span> extension.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-delete.html" title="DELETE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-do.html" title="DO">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DELETE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DO</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-do.html b/doc/src/sgml/html/sql-do.html
new file mode 100644
index 0000000..185814f
--- /dev/null
+++ b/doc/src/sgml/html/sql-do.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DO</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-discard.html" title="DISCARD" /><link rel="next" href="sql-drop-access-method.html" title="DROP ACCESS METHOD" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DO</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-discard.html" title="DISCARD">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-drop-access-method.html" title="DROP ACCESS METHOD">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DO"><div class="titlepage"></div><a id="id-1.9.3.102.1" class="indexterm"></a><a id="id-1.9.3.102.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DO</span></h2><p>DO — execute an anonymous code block</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DO [ LANGUAGE <em class="replaceable"><code>lang_name</code></em> ] <em class="replaceable"><code>code</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.102.6"><h2>Description</h2><p>
+ <code class="command">DO</code> executes an anonymous code block, or in other
+ words a transient anonymous function in a procedural language.
+ </p><p>
+ The code block is treated as though it were the body of a function
+ with no parameters, returning <code class="type">void</code>. It is parsed and
+ executed a single time.
+ </p><p>
+ The optional <code class="literal">LANGUAGE</code> clause can be written either
+ before or after the code block.
+ </p></div><div class="refsect1" id="id-1.9.3.102.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>code</code></em></span></dt><dd><p>
+ The procedural language code to be executed. This must be specified
+ as a string literal, just as in <code class="command">CREATE FUNCTION</code>.
+ Use of a dollar-quoted literal is recommended.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the procedural language the code is written in.
+ If omitted, the default is <code class="literal">plpgsql</code>.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.102.8"><h2>Notes</h2><p>
+ The procedural language to be used must already have been installed
+ into the current database by means of <code class="command">CREATE EXTENSION</code>.
+ <code class="literal">plpgsql</code> is installed by default, but other languages are not.
+ </p><p>
+ The user must have <code class="literal">USAGE</code> privilege for the procedural
+ language, or must be a superuser if the language is untrusted.
+ This is the same privilege requirement as for creating a function
+ in the language.
+ </p><p>
+ If <code class="command">DO</code> is executed in a transaction block, then the
+ procedure code cannot execute transaction control statements. Transaction
+ control statements are only allowed if <code class="command">DO</code> is executed in
+ its own transaction.
+ </p></div><div class="refsect1" id="SQL-DO-EXAMPLES"><h2>Examples</h2><p>
+ Grant all privileges on all views in schema <code class="literal">public</code> to
+ role <code class="literal">webuser</code>:
+</p><pre class="programlisting">
+DO $$DECLARE r record;
+BEGIN
+ FOR r IN SELECT table_schema, table_name FROM information_schema.tables
+ WHERE table_type = 'VIEW' AND table_schema = 'public'
+ LOOP
+ EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
+ END LOOP;
+END$$;
+</pre></div><div class="refsect1" id="id-1.9.3.102.10"><h2>Compatibility</h2><p>
+ There is no <code class="command">DO</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.102.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createlanguage.html" title="CREATE LANGUAGE"><span class="refentrytitle">CREATE LANGUAGE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-discard.html" title="DISCARD">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-drop-access-method.html" title="DROP ACCESS METHOD">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DISCARD </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP ACCESS METHOD</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-drop-access-method.html b/doc/src/sgml/html/sql-drop-access-method.html
new file mode 100644
index 0000000..691a565
--- /dev/null
+++ b/doc/src/sgml/html/sql-drop-access-method.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP ACCESS METHOD</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-do.html" title="DO" /><link rel="next" href="sql-dropaggregate.html" title="DROP AGGREGATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP ACCESS METHOD</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-do.html" title="DO">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropaggregate.html" title="DROP AGGREGATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROP-ACCESS-METHOD"><div class="titlepage"></div><a id="id-1.9.3.103.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP ACCESS METHOD</span></h2><p>DROP ACCESS METHOD — remove an access method</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP ACCESS METHOD [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.103.5"><h2>Description</h2><p>
+ <code class="command">DROP ACCESS METHOD</code> removes an existing access method.
+ Only superusers can drop access methods.
+ </p></div><div class="refsect1" id="id-1.9.3.103.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the access method does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing access method.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the access method
+ (such as operator classes, operator families, and indexes),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the access method if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.103.7"><h2>Examples</h2><p>
+ Drop the access method <code class="literal">heptree</code>:
+</p><pre class="programlisting">
+DROP ACCESS METHOD heptree;
+</pre></div><div class="refsect1" id="id-1.9.3.103.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP ACCESS METHOD</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.103.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-create-access-method.html" title="CREATE ACCESS METHOD"><span class="refentrytitle">CREATE ACCESS METHOD</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-do.html" title="DO">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropaggregate.html" title="DROP AGGREGATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DO </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP AGGREGATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-drop-owned.html b/doc/src/sgml/html/sql-drop-owned.html
new file mode 100644
index 0000000..b8ea125
--- /dev/null
+++ b/doc/src/sgml/html/sql-drop-owned.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP OWNED</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY" /><link rel="next" href="sql-droppolicy.html" title="DROP POLICY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP OWNED</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droppolicy.html" title="DROP POLICY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROP-OWNED"><div class="titlepage"></div><a id="id-1.9.3.122.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP OWNED</span></h2><p>DROP OWNED — remove database objects owned by a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP OWNED BY { <em class="replaceable"><code>name</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.122.5"><h2>Description</h2><p>
+ <code class="command">DROP OWNED</code> drops all the objects within the current
+ database that are owned by one of the specified roles. Any
+ privileges granted to the given roles on objects in the current
+ database or on shared objects (databases, tablespaces, configuration
+ parameters) will also be revoked.
+ </p></div><div class="refsect1" id="id-1.9.3.122.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a role whose objects will be dropped, and whose
+ privileges will be revoked.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the affected objects,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the objects owned by a role if any other database
+ objects depend on one of the affected objects. This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.122.7"><h2>Notes</h2><p>
+ <code class="command">DROP OWNED</code> is often used to prepare for the
+ removal of one or more roles. Because <code class="command">DROP OWNED</code>
+ only affects the objects in the current database, it is usually
+ necessary to execute this command in each database that contains
+ objects owned by a role that is to be removed.
+ </p><p>
+ Using the <code class="literal">CASCADE</code> option might make the command
+ recurse to objects owned by other users.
+ </p><p>
+ The <a class="link" href="sql-reassign-owned.html" title="REASSIGN OWNED"><code class="command">REASSIGN OWNED</code></a> command is an alternative that
+ reassigns the ownership of all the database objects owned by one or
+ more roles. However, <code class="command">REASSIGN OWNED</code> does not deal with
+ privileges for other objects.
+ </p><p>
+ Databases and tablespaces owned by the role(s) will not be removed.
+ </p><p>
+ See <a class="xref" href="role-removal.html" title="22.4. Dropping Roles">Section 22.4</a> for more discussion.
+ </p></div><div class="refsect1" id="id-1.9.3.122.8"><h2>Compatibility</h2><p>
+ The <code class="command">DROP OWNED</code> command is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.122.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-reassign-owned.html" title="REASSIGN OWNED"><span class="refentrytitle">REASSIGN OWNED</span></a>, <a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droppolicy.html" title="DROP POLICY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP OPERATOR FAMILY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP POLICY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropaggregate.html b/doc/src/sgml/html/sql-dropaggregate.html
new file mode 100644
index 0000000..02ebfc3
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropaggregate.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP AGGREGATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-drop-access-method.html" title="DROP ACCESS METHOD" /><link rel="next" href="sql-dropcast.html" title="DROP CAST" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP AGGREGATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-drop-access-method.html" title="DROP ACCESS METHOD">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropcast.html" title="DROP CAST">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPAGGREGATE"><div class="titlepage"></div><a id="id-1.9.3.104.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP AGGREGATE</span></h2><p>DROP AGGREGATE — remove an aggregate function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP AGGREGATE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> ) [, ...] [ CASCADE | RESTRICT ]
+
+<span class="phrase">where <em class="replaceable"><code>aggregate_signature</code></em> is:</span>
+
+* |
+[ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] |
+[ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] ] ORDER BY [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.104.5"><h2>Description</h2><p>
+ <code class="command">DROP AGGREGATE</code> removes an existing
+ aggregate function. To execute this command the current
+ user must be the owner of the aggregate function.
+ </p></div><div class="refsect1" id="id-1.9.3.104.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the aggregate does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing aggregate function.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code> or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ Note that <code class="command">DROP AGGREGATE</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the aggregate function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ An input data type on which the aggregate function operates.
+ To reference a zero-argument aggregate function, write <code class="literal">*</code>
+ in place of the list of argument specifications.
+ To reference an ordered-set aggregate function, write
+ <code class="literal">ORDER BY</code> between the direct and aggregated argument
+ specifications.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the aggregate function
+ (such as views using it),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the aggregate function if any objects depend on
+ it. This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.104.7"><h2>Notes</h2><p>
+ Alternative syntaxes for referencing ordered-set aggregates
+ are described under <a class="xref" href="sql-alteraggregate.html" title="ALTER AGGREGATE"><span class="refentrytitle">ALTER AGGREGATE</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.104.8"><h2>Examples</h2><p>
+ To remove the aggregate function <code class="literal">myavg</code> for type
+ <code class="type">integer</code>:
+</p><pre class="programlisting">
+DROP AGGREGATE myavg(integer);
+</pre><p>
+ </p><p>
+ To remove the hypothetical-set aggregate function <code class="literal">myrank</code>,
+ which takes an arbitrary list of ordering columns and a matching list
+ of direct arguments:
+</p><pre class="programlisting">
+DROP AGGREGATE myrank(VARIADIC "any" ORDER BY VARIADIC "any");
+</pre><p>
+ </p><p>
+ To remove multiple aggregate functions in one command:
+</p><pre class="programlisting">
+DROP AGGREGATE myavg(integer), myavg(bigint);
+</pre></div><div class="refsect1" id="id-1.9.3.104.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP AGGREGATE</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.104.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteraggregate.html" title="ALTER AGGREGATE"><span class="refentrytitle">ALTER AGGREGATE</span></a>, <a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-drop-access-method.html" title="DROP ACCESS METHOD">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropcast.html" title="DROP CAST">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP ACCESS METHOD </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP CAST</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropcast.html b/doc/src/sgml/html/sql-dropcast.html
new file mode 100644
index 0000000..8b93dba
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropcast.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP CAST</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropaggregate.html" title="DROP AGGREGATE" /><link rel="next" href="sql-dropcollation.html" title="DROP COLLATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP CAST</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropaggregate.html" title="DROP AGGREGATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropcollation.html" title="DROP COLLATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPCAST"><div class="titlepage"></div><a id="id-1.9.3.105.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP CAST</span></h2><p>DROP CAST — remove a cast</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP CAST [ IF EXISTS ] (<em class="replaceable"><code>source_type</code></em> AS <em class="replaceable"><code>target_type</code></em>) [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="SQL-DROPCAST-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">DROP CAST</code> removes a previously defined cast.
+ </p><p>
+ To be able to drop a cast, you must own the source or the target
+ data type. These are the same privileges that are required to
+ create a cast.
+ </p></div><div class="refsect1" id="id-1.9.3.105.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the cast does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_type</code></em></span></dt><dd><p>
+ The name of the source data type of the cast.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>target_type</code></em></span></dt><dd><p>
+ The name of the target data type of the cast.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code><br /></span><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ These key words do not have any effect, since there are no
+ dependencies on casts.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPCAST-EXAMPLES"><h2>Examples</h2><p>
+ To drop the cast from type <code class="type">text</code> to type <code class="type">int</code>:
+</p><pre class="programlisting">
+DROP CAST (text AS int);
+</pre></div><div class="refsect1" id="SQL-DROPCAST-COMPAT"><h2>Compatibility</h2><p>
+ The <code class="command">DROP CAST</code> command conforms to the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.105.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropaggregate.html" title="DROP AGGREGATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropcollation.html" title="DROP COLLATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP AGGREGATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP COLLATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropcollation.html b/doc/src/sgml/html/sql-dropcollation.html
new file mode 100644
index 0000000..bec097f
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropcollation.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP COLLATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropcast.html" title="DROP CAST" /><link rel="next" href="sql-dropconversion.html" title="DROP CONVERSION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP COLLATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropcast.html" title="DROP CAST">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropconversion.html" title="DROP CONVERSION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPCOLLATION"><div class="titlepage"></div><a id="id-1.9.3.106.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP COLLATION</span></h2><p>DROP COLLATION — remove a collation</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP COLLATION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="SQL-DROPCOLLATION-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">DROP COLLATION</code> removes a previously defined collation.
+ To be able to drop a collation, you must own the collation.
+ </p></div><div class="refsect1" id="id-1.9.3.106.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the collation does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the collation. The collation name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the collation,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the collation if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPCOLLATION-EXAMPLES"><h2>Examples</h2><p>
+ To drop the collation named <code class="literal">german</code>:
+</p><pre class="programlisting">
+DROP COLLATION german;
+</pre></div><div class="refsect1" id="SQL-DROPCOLLATION-COMPAT"><h2>Compatibility</h2><p>
+ The <code class="command">DROP COLLATION</code> command conforms to the
+ <acronym class="acronym">SQL</acronym> standard, apart from the <code class="literal">IF
+ EXISTS</code> option, which is a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.106.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altercollation.html" title="ALTER COLLATION"><span class="refentrytitle">ALTER COLLATION</span></a>, <a class="xref" href="sql-createcollation.html" title="CREATE COLLATION"><span class="refentrytitle">CREATE COLLATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropcast.html" title="DROP CAST">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropconversion.html" title="DROP CONVERSION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP CAST </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP CONVERSION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropconversion.html b/doc/src/sgml/html/sql-dropconversion.html
new file mode 100644
index 0000000..8c592b0
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropconversion.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP CONVERSION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropcollation.html" title="DROP COLLATION" /><link rel="next" href="sql-dropdatabase.html" title="DROP DATABASE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP CONVERSION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropcollation.html" title="DROP COLLATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropdatabase.html" title="DROP DATABASE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPCONVERSION"><div class="titlepage"></div><a id="id-1.9.3.107.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP CONVERSION</span></h2><p>DROP CONVERSION — remove a conversion</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP CONVERSION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="SQL-DROPCONVERSION-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">DROP CONVERSION</code> removes a previously defined conversion.
+ To be able to drop a conversion, you must own the conversion.
+ </p></div><div class="refsect1" id="id-1.9.3.107.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the conversion does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the conversion. The conversion name can be
+ schema-qualified.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code><br /></span><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ These key words do not have any effect, since there are no
+ dependencies on conversions.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPCONVERSION-EXAMPLES"><h2>Examples</h2><p>
+ To drop the conversion named <code class="literal">myname</code>:
+</p><pre class="programlisting">
+DROP CONVERSION myname;
+</pre></div><div class="refsect1" id="SQL-DROPCONVERSION-COMPAT"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP CONVERSION</code> statement in the SQL
+ standard, but a <code class="command">DROP TRANSLATION</code> statement that
+ goes along with the <code class="command">CREATE TRANSLATION</code> statement
+ that is similar to the <code class="command">CREATE CONVERSION</code>
+ statement in PostgreSQL.
+ </p></div><div class="refsect1" id="id-1.9.3.107.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterconversion.html" title="ALTER CONVERSION"><span class="refentrytitle">ALTER CONVERSION</span></a>, <a class="xref" href="sql-createconversion.html" title="CREATE CONVERSION"><span class="refentrytitle">CREATE CONVERSION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropcollation.html" title="DROP COLLATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropdatabase.html" title="DROP DATABASE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP COLLATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP DATABASE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropdatabase.html b/doc/src/sgml/html/sql-dropdatabase.html
new file mode 100644
index 0000000..07c8423
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropdatabase.html
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP DATABASE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropconversion.html" title="DROP CONVERSION" /><link rel="next" href="sql-dropdomain.html" title="DROP DOMAIN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP DATABASE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropconversion.html" title="DROP CONVERSION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropdomain.html" title="DROP DOMAIN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPDATABASE"><div class="titlepage"></div><a id="id-1.9.3.108.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP DATABASE</span></h2><p>DROP DATABASE — remove a database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP DATABASE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ [ WITH ] ( <em class="replaceable"><code>option</code></em> [, ...] ) ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be:</span>
+
+ FORCE
+</pre></div><div class="refsect1" id="id-1.9.3.108.5"><h2>Description</h2><p>
+ <code class="command">DROP DATABASE</code> drops a database. It removes the
+ catalog entries for the database and deletes the directory
+ containing the data. It can only be executed by the database owner.
+ It cannot be executed while you are connected to the target database.
+ (Connect to <code class="literal">postgres</code> or any other database to issue this
+ command.)
+ Also, if anyone else is connected to the target database, this command will
+ fail unless you use the <code class="literal">FORCE</code> option described below.
+ </p><p>
+ <code class="command">DROP DATABASE</code> cannot be undone. Use it with care!
+ </p></div><div class="refsect1" id="id-1.9.3.108.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the database does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the database to remove.
+ </p></dd><dt><span class="term"><code class="literal">FORCE</code></span></dt><dd><p>
+ Attempt to terminate all existing connections to the target database.
+ It doesn't terminate if prepared transactions, active logical replication
+ slots or subscriptions are present in the target database.
+ </p><p>
+ This will fail if the current user has no permissions to terminate other
+ connections. Required permissions are the same as with
+ <code class="literal">pg_terminate_backend</code>, described in
+ <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SIGNAL" title="9.27.2. Server Signaling Functions">Section 9.27.2</a>. This will also fail if we
+ are not able to terminate connections.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.108.7"><h2>Notes</h2><p>
+ <code class="command">DROP DATABASE</code> cannot be executed inside a transaction
+ block.
+ </p><p>
+ This command cannot be executed while connected to the target
+ database. Thus, it might be more convenient to use the program
+ <a class="xref" href="app-dropdb.html" title="dropdb"><span class="refentrytitle"><span class="application">dropdb</span></span></a> instead,
+ which is a wrapper around this command.
+ </p></div><div class="refsect1" id="id-1.9.3.108.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP DATABASE</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.108.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createdatabase.html" title="CREATE DATABASE"><span class="refentrytitle">CREATE DATABASE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropconversion.html" title="DROP CONVERSION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropdomain.html" title="DROP DOMAIN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP CONVERSION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP DOMAIN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropdomain.html b/doc/src/sgml/html/sql-dropdomain.html
new file mode 100644
index 0000000..26c0352
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropdomain.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP DOMAIN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropdatabase.html" title="DROP DATABASE" /><link rel="next" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP DOMAIN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropdatabase.html" title="DROP DATABASE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPDOMAIN"><div class="titlepage"></div><a id="id-1.9.3.109.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP DOMAIN</span></h2><p>DROP DOMAIN — remove a domain</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP DOMAIN [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.109.5"><h2>Description</h2><p>
+ <code class="command">DROP DOMAIN</code> removes a domain. Only the owner of
+ a domain can remove it.
+ </p></div><div class="refsect1" id="id-1.9.3.109.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the domain does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing domain.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the domain (such as
+ table columns),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the domain if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPDOMAIN-EXAMPLES"><h2>Examples</h2><p>
+ To remove the domain <code class="type">box</code>:
+
+</p><pre class="programlisting">
+DROP DOMAIN box;
+</pre></div><div class="refsect1" id="SQL-DROPDOMAIN-COMPATIBILITY"><h2>Compatibility</h2><p>
+ This command conforms to the SQL standard, except for the
+ <code class="literal">IF EXISTS</code> option, which is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="SQL-DROPDOMAIN-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createdomain.html" title="CREATE DOMAIN"><span class="refentrytitle">CREATE DOMAIN</span></a>, <a class="xref" href="sql-alterdomain.html" title="ALTER DOMAIN"><span class="refentrytitle">ALTER DOMAIN</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropdatabase.html" title="DROP DATABASE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP DATABASE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP EVENT TRIGGER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropeventtrigger.html b/doc/src/sgml/html/sql-dropeventtrigger.html
new file mode 100644
index 0000000..06efdfe
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropeventtrigger.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP EVENT TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropdomain.html" title="DROP DOMAIN" /><link rel="next" href="sql-dropextension.html" title="DROP EXTENSION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP EVENT TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropdomain.html" title="DROP DOMAIN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropextension.html" title="DROP EXTENSION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPEVENTTRIGGER"><div class="titlepage"></div><a id="id-1.9.3.110.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP EVENT TRIGGER</span></h2><p>DROP EVENT TRIGGER — remove an event trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP EVENT TRIGGER [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.110.5"><h2>Description</h2><p>
+ <code class="command">DROP EVENT TRIGGER</code> removes an existing event trigger.
+ To execute this command, the current user must be the owner of the event
+ trigger.
+ </p></div><div class="refsect1" id="id-1.9.3.110.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the event trigger does not exist. A notice
+ is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the event trigger to remove.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the trigger,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the trigger if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPEVENTTRIGGER-EXAMPLES"><h2>Examples</h2><p>
+ Destroy the trigger <code class="literal">snitch</code>:
+
+</p><pre class="programlisting">
+DROP EVENT TRIGGER snitch;
+</pre></div><div class="refsect1" id="SQL-DROPEVENTTRIGGER-COMPATIBILITY"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP EVENT TRIGGER</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.110.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createeventtrigger.html" title="CREATE EVENT TRIGGER"><span class="refentrytitle">CREATE EVENT TRIGGER</span></a>, <a class="xref" href="sql-altereventtrigger.html" title="ALTER EVENT TRIGGER"><span class="refentrytitle">ALTER EVENT TRIGGER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropdomain.html" title="DROP DOMAIN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropextension.html" title="DROP EXTENSION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP DOMAIN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP EXTENSION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropextension.html b/doc/src/sgml/html/sql-dropextension.html
new file mode 100644
index 0000000..85f25d4
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropextension.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP EXTENSION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER" /><link rel="next" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP EXTENSION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPEXTENSION"><div class="titlepage"></div><a id="id-1.9.3.111.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP EXTENSION</span></h2><p>DROP EXTENSION — remove an extension</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP EXTENSION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.111.5"><h2>Description</h2><p>
+ <code class="command">DROP EXTENSION</code> removes extensions from the database.
+ Dropping an extension causes its member objects, and other explicitly
+ dependent routines (see <a class="xref" href="sql-alterroutine.html" title="ALTER ROUTINE"><span class="refentrytitle">ALTER ROUTINE</span></a>,
+ the <code class="literal">DEPENDS ON EXTENSION <em class="replaceable"><code>extension_name</code></em>
+ </code> action), to be dropped as well.
+ </p><p>
+ You must own the extension to use <code class="command">DROP EXTENSION</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.111.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the extension does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an installed extension.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the extension,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ This option prevents the specified extensions from being dropped if
+ other objects, besides these extensions, their members, and their
+ explicitly dependent routines, depend on them.  This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.111.7"><h2>Examples</h2><p>
+ To remove the extension <code class="literal">hstore</code> from the current
+ database:
+</p><pre class="programlisting">
+DROP EXTENSION hstore;
+</pre><p>
+ This command will fail if any of <code class="literal">hstore</code>'s objects
+ are in use in the database, for example if any tables have columns
+ of the <code class="type">hstore</code> type. Add the <code class="literal">CASCADE</code> option to
+ forcibly remove those dependent objects as well.
+ </p></div><div class="refsect1" id="id-1.9.3.111.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP EXTENSION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.111.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createextension.html" title="CREATE EXTENSION"><span class="refentrytitle">CREATE EXTENSION</span></a>, <a class="xref" href="sql-alterextension.html" title="ALTER EXTENSION"><span class="refentrytitle">ALTER EXTENSION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropeventtrigger.html" title="DROP EVENT TRIGGER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP EVENT TRIGGER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP FOREIGN DATA WRAPPER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropforeigndatawrapper.html b/doc/src/sgml/html/sql-dropforeigndatawrapper.html
new file mode 100644
index 0000000..718fa79
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropforeigndatawrapper.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP FOREIGN DATA WRAPPER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropextension.html" title="DROP EXTENSION" /><link rel="next" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP FOREIGN DATA WRAPPER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropextension.html" title="DROP EXTENSION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPFOREIGNDATAWRAPPER"><div class="titlepage"></div><a id="id-1.9.3.112.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP FOREIGN DATA WRAPPER</span></h2><p>DROP FOREIGN DATA WRAPPER — remove a foreign-data wrapper</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP FOREIGN DATA WRAPPER [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.112.5"><h2>Description</h2><p>
+ <code class="command">DROP FOREIGN DATA WRAPPER</code> removes an existing
+ foreign-data wrapper. To execute this command, the current user
+ must be the owner of the foreign-data wrapper.
+ </p></div><div class="refsect1" id="id-1.9.3.112.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the foreign-data wrapper does not
+ exist. A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing foreign-data wrapper.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the foreign-data
+ wrapper (such as foreign tables and servers),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the foreign-data wrapper if any objects depend
+ on it. This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.112.7"><h2>Examples</h2><p>
+ Drop the foreign-data wrapper <code class="literal">dbi</code>:
+</p><pre class="programlisting">
+DROP FOREIGN DATA WRAPPER dbi;
+</pre></div><div class="refsect1" id="id-1.9.3.112.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP FOREIGN DATA WRAPPER</code> conforms to ISO/IEC
+ 9075-9 (SQL/MED). The <code class="literal">IF EXISTS</code> clause is
+ a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.112.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createforeigndatawrapper.html" title="CREATE FOREIGN DATA WRAPPER"><span class="refentrytitle">CREATE FOREIGN DATA WRAPPER</span></a>, <a class="xref" href="sql-alterforeigndatawrapper.html" title="ALTER FOREIGN DATA WRAPPER"><span class="refentrytitle">ALTER FOREIGN DATA WRAPPER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropextension.html" title="DROP EXTENSION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP EXTENSION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP FOREIGN TABLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropforeigntable.html b/doc/src/sgml/html/sql-dropforeigntable.html
new file mode 100644
index 0000000..6d7b2e0
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropforeigntable.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP FOREIGN TABLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER" /><link rel="next" href="sql-dropfunction.html" title="DROP FUNCTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP FOREIGN TABLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropfunction.html" title="DROP FUNCTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPFOREIGNTABLE"><div class="titlepage"></div><a id="id-1.9.3.113.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP FOREIGN TABLE</span></h2><p>DROP FOREIGN TABLE — remove a foreign table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP FOREIGN TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.113.5"><h2>Description</h2><p>
+ <code class="command">DROP FOREIGN TABLE</code> removes a foreign table.
+ Only the owner of a foreign table can remove it.
+ </p></div><div class="refsect1" id="id-1.9.3.113.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the foreign table does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the foreign table to drop.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the foreign table (such as
+ views), and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the foreign table if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.113.7"><h2>Examples</h2><p>
+ To destroy two foreign tables, <code class="literal">films</code> and
+ <code class="literal">distributors</code>:
+
+</p><pre class="programlisting">
+DROP FOREIGN TABLE films, distributors;
+</pre></div><div class="refsect1" id="id-1.9.3.113.8"><h2>Compatibility</h2><p>
+ This command conforms to ISO/IEC 9075-9 (SQL/MED), except that the
+ standard only allows one foreign table to be dropped per command, and apart
+ from the <code class="literal">IF EXISTS</code> option, which is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.113.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterforeigntable.html" title="ALTER FOREIGN TABLE"><span class="refentrytitle">ALTER FOREIGN TABLE</span></a>, <a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropforeigndatawrapper.html" title="DROP FOREIGN DATA WRAPPER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropfunction.html" title="DROP FUNCTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP FOREIGN DATA WRAPPER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP FUNCTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropfunction.html b/doc/src/sgml/html/sql-dropfunction.html
new file mode 100644
index 0000000..4e98b37
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropfunction.html
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP FUNCTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE" /><link rel="next" href="sql-dropgroup.html" title="DROP GROUP" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP FUNCTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropgroup.html" title="DROP GROUP">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPFUNCTION"><div class="titlepage"></div><a id="id-1.9.3.114.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP FUNCTION</span></h2><p>DROP FUNCTION — remove a function</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP FUNCTION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] [, ...]
+ [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.114.5"><h2>Description</h2><p>
+ <code class="command">DROP FUNCTION</code> removes the definition of an existing
+ function. To execute this command the user must be the
+ owner of the function. The argument types to the
+ function must be specified, since several different functions
+ can exist with the same name and different argument lists.
+ </p></div><div class="refsect1" id="id-1.9.3.114.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the function does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing function. If no
+ argument list is specified, the name must be unique in its schema.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ Note that <code class="command">DROP FUNCTION</code> does not actually pay
+ any attention to <code class="literal">OUT</code> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <code class="literal">IN</code>, <code class="literal">INOUT</code>,
+ and <code class="literal">VARIADIC</code> arguments.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ Note that <code class="command">DROP FUNCTION</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type(s) of the function's arguments (optionally
+ schema-qualified), if any.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the function (such as
+ operators or triggers),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the function if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPFUNCTION-EXAMPLES"><h2>Examples</h2><p>
+ This command removes the square root function:
+
+</p><pre class="programlisting">
+DROP FUNCTION sqrt(integer);
+</pre><p>
+ Drop multiple functions in one command:
+</p><pre class="programlisting">
+DROP FUNCTION sqrt(integer), sqrt(bigint);
+</pre><p>
+ If the function name is unique in its schema, it can be referred to without
+ an argument list:
+</p><pre class="programlisting">
+DROP FUNCTION update_employee_salaries;
+</pre><p>
+ Note that this is different from
+</p><pre class="programlisting">
+DROP FUNCTION update_employee_salaries();
+</pre><p>
+ which refers to a function with zero arguments, whereas the first variant
+ can refer to a function with any number of arguments, including zero, as
+ long as the name is unique.
+ </p></div><div class="refsect1" id="SQL-DROPFUNCTION-COMPATIBILITY"><h2>Compatibility</h2><p>
+ This command conforms to the SQL standard, with
+ these <span class="productname">PostgreSQL</span> extensions:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>The standard only allows one function to be dropped per command.</p></li><li class="listitem"><p>The <code class="literal">IF EXISTS</code> option</p></li><li class="listitem"><p>The ability to specify argument modes and names</p></li></ul></div></div><div class="refsect1" id="id-1.9.3.114.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-alterfunction.html" title="ALTER FUNCTION"><span class="refentrytitle">ALTER FUNCTION</span></a>, <a class="xref" href="sql-dropprocedure.html" title="DROP PROCEDURE"><span class="refentrytitle">DROP PROCEDURE</span></a>, <a class="xref" href="sql-droproutine.html" title="DROP ROUTINE"><span class="refentrytitle">DROP ROUTINE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropforeigntable.html" title="DROP FOREIGN TABLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropgroup.html" title="DROP GROUP">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP FOREIGN TABLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP GROUP</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropgroup.html b/doc/src/sgml/html/sql-dropgroup.html
new file mode 100644
index 0000000..8950c43
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropgroup.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP GROUP</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropfunction.html" title="DROP FUNCTION" /><link rel="next" href="sql-dropindex.html" title="DROP INDEX" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP GROUP</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropfunction.html" title="DROP FUNCTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropindex.html" title="DROP INDEX">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPGROUP"><div class="titlepage"></div><a id="id-1.9.3.115.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP GROUP</span></h2><p>DROP GROUP — remove a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP GROUP [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...]
+</pre></div><div class="refsect1" id="id-1.9.3.115.5"><h2>Description</h2><p>
+ <code class="command">DROP GROUP</code> is now an alias for
+ <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.115.6"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP GROUP</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.115.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropfunction.html" title="DROP FUNCTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropindex.html" title="DROP INDEX">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP FUNCTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP INDEX</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropindex.html b/doc/src/sgml/html/sql-dropindex.html
new file mode 100644
index 0000000..4ccd599
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropindex.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP INDEX</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropgroup.html" title="DROP GROUP" /><link rel="next" href="sql-droplanguage.html" title="DROP LANGUAGE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP INDEX</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropgroup.html" title="DROP GROUP">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droplanguage.html" title="DROP LANGUAGE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPINDEX"><div class="titlepage"></div><a id="id-1.9.3.116.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP INDEX</span></h2><p>DROP INDEX — remove an index</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.116.5"><h2>Description</h2><p>
+ <code class="command">DROP INDEX</code> drops an existing index from the database
+ system. To execute this command you must be the owner of
+ the index.
+ </p></div><div class="refsect1" id="id-1.9.3.116.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">CONCURRENTLY</code></span></dt><dd><p>
+ Drop the index without locking out concurrent selects, inserts, updates,
+ and deletes on the index's table. A normal <code class="command">DROP INDEX</code>
+ acquires an <code class="literal">ACCESS EXCLUSIVE</code> lock on the table,
+ blocking other accesses until the index drop can be completed. With
+ this option, the command instead waits until conflicting transactions
+ have completed.
+ </p><p>
+ There are several caveats to be aware of when using this option.
+ Only one index name can be specified, and the <code class="literal">CASCADE</code> option
+ is not supported. (Thus, an index that supports a <code class="literal">UNIQUE</code> or
+ <code class="literal">PRIMARY KEY</code> constraint cannot be dropped this way.)
+ Also, regular <code class="command">DROP INDEX</code> commands can be
+ performed within a transaction block, but
+ <code class="command">DROP INDEX CONCURRENTLY</code> cannot.
+ Lastly, indexes on partitioned tables cannot be dropped using this
+ option.
+ </p><p>
+ For temporary tables, <code class="command">DROP INDEX</code> is always
+ non-concurrent, as no other session can access them, and
+ non-concurrent index drop is cheaper.
+ </p></dd><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the index does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an index to remove.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the index,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the index if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.116.7"><h2>Examples</h2><p>
+ This command will remove the index <code class="literal">title_idx</code>:
+
+</p><pre class="programlisting">
+DROP INDEX title_idx;
+</pre></div><div class="refsect1" id="id-1.9.3.116.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP INDEX</code> is a
+ <span class="productname">PostgreSQL</span> language extension. There
+ are no provisions for indexes in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.116.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropgroup.html" title="DROP GROUP">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droplanguage.html" title="DROP LANGUAGE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP GROUP </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP LANGUAGE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droplanguage.html b/doc/src/sgml/html/sql-droplanguage.html
new file mode 100644
index 0000000..e86b0a8
--- /dev/null
+++ b/doc/src/sgml/html/sql-droplanguage.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP LANGUAGE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropindex.html" title="DROP INDEX" /><link rel="next" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP LANGUAGE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropindex.html" title="DROP INDEX">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPLANGUAGE"><div class="titlepage"></div><a id="id-1.9.3.117.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP LANGUAGE</span></h2><p>DROP LANGUAGE — remove a procedural language</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.117.5"><h2>Description</h2><p>
+ <code class="command">DROP LANGUAGE</code> removes the definition of a
+ previously registered procedural language. You must be a superuser
+ or the owner of the language to use <code class="command">DROP LANGUAGE</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ As of <span class="productname">PostgreSQL</span> 9.1, most procedural
+ languages have been made into <span class="quote">“<span class="quote">extensions</span>”</span>, and should
+ therefore be removed with <a class="link" href="sql-dropextension.html" title="DROP EXTENSION"><code class="command">DROP EXTENSION</code></a>
+ not <code class="command">DROP LANGUAGE</code>.
+ </p></div></div><div class="refsect1" id="id-1.9.3.117.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the language does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing procedural language.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the language (such as
+ functions in the language),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the language if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.117.7"><h2>Examples</h2><p>
+ This command removes the procedural language
+ <code class="literal">plsample</code>:
+
+</p><pre class="programlisting">
+DROP LANGUAGE plsample;
+</pre></div><div class="refsect1" id="id-1.9.3.117.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP LANGUAGE</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.117.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterlanguage.html" title="ALTER LANGUAGE"><span class="refentrytitle">ALTER LANGUAGE</span></a>, <a class="xref" href="sql-createlanguage.html" title="CREATE LANGUAGE"><span class="refentrytitle">CREATE LANGUAGE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropindex.html" title="DROP INDEX">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP INDEX </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP MATERIALIZED VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropmaterializedview.html b/doc/src/sgml/html/sql-dropmaterializedview.html
new file mode 100644
index 0000000..600d847
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropmaterializedview.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP MATERIALIZED VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droplanguage.html" title="DROP LANGUAGE" /><link rel="next" href="sql-dropoperator.html" title="DROP OPERATOR" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP MATERIALIZED VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droplanguage.html" title="DROP LANGUAGE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropoperator.html" title="DROP OPERATOR">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPMATERIALIZEDVIEW"><div class="titlepage"></div><a id="id-1.9.3.118.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP MATERIALIZED VIEW</span></h2><p>DROP MATERIALIZED VIEW — remove a materialized view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP MATERIALIZED VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.118.5"><h2>Description</h2><p>
+ <code class="command">DROP MATERIALIZED VIEW</code> drops an existing materialized
+ view. To execute this command you must be the owner of the materialized
+ view.
+ </p></div><div class="refsect1" id="id-1.9.3.118.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the materialized view does not exist. A notice
+ is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the materialized view to
+ remove.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the materialized view (such as
+ other materialized views, or regular views),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the materialized view if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.118.7"><h2>Examples</h2><p>
+ This command will remove the materialized view called
+ <code class="literal">order_summary</code>:
+</p><pre class="programlisting">
+DROP MATERIALIZED VIEW order_summary;
+</pre></div><div class="refsect1" id="id-1.9.3.118.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP MATERIALIZED VIEW</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.118.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW"><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW"><span class="refentrytitle">ALTER MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW"><span class="refentrytitle">REFRESH MATERIALIZED VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droplanguage.html" title="DROP LANGUAGE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropoperator.html" title="DROP OPERATOR">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP LANGUAGE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP OPERATOR</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropopclass.html b/doc/src/sgml/html/sql-dropopclass.html
new file mode 100644
index 0000000..ca129ae
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropopclass.html
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP OPERATOR CLASS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropoperator.html" title="DROP OPERATOR" /><link rel="next" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP OPERATOR CLASS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropoperator.html" title="DROP OPERATOR">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPOPCLASS"><div class="titlepage"></div><a id="id-1.9.3.120.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP OPERATOR CLASS</span></h2><p>DROP OPERATOR CLASS — remove an operator class</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP OPERATOR CLASS [ IF EXISTS ] <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.120.5"><h2>Description</h2><p>
+ <code class="command">DROP OPERATOR CLASS</code> drops an existing operator class.
+ To execute this command you must be the owner of the operator class.
+ </p><p>
+ <code class="command">DROP OPERATOR CLASS</code> does not drop any of the operators
+ or functions referenced by the class. If there are any indexes depending
+ on the operator class, you will need to specify
+ <code class="literal">CASCADE</code> for the drop to complete.
+ </p></div><div class="refsect1" id="id-1.9.3.120.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the operator class does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing operator class.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_method</code></em></span></dt><dd><p>
+ The name of the index access method the operator class is for.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the operator class (such as
+ indexes), and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the operator class if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.120.7"><h2>Notes</h2><p>
+ <code class="command">DROP OPERATOR CLASS</code> will not drop the operator family
+ containing the class, even if there is nothing else left in the
+ family (in particular, in the case where the family was implicitly
+ created by <code class="command">CREATE OPERATOR CLASS</code>). An empty operator
+ family is harmless, but for the sake of tidiness you might wish to
+ remove the family with <code class="command">DROP OPERATOR FAMILY</code>; or perhaps
+ better, use <code class="command">DROP OPERATOR FAMILY</code> in the first place.
+ </p></div><div class="refsect1" id="id-1.9.3.120.8"><h2>Examples</h2><p>
+ Remove the B-tree operator class <code class="literal">widget_ops</code>:
+
+</p><pre class="programlisting">
+DROP OPERATOR CLASS widget_ops USING btree;
+</pre><p>
+
+ This command will not succeed if there are any existing indexes
+ that use the operator class. Add <code class="literal">CASCADE</code> to drop
+ such indexes along with the operator class.
+ </p></div><div class="refsect1" id="id-1.9.3.120.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP OPERATOR CLASS</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.120.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS"><span class="refentrytitle">ALTER OPERATOR CLASS</span></a>, <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY"><span class="refentrytitle">DROP OPERATOR FAMILY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropoperator.html" title="DROP OPERATOR">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropopfamily.html" title="DROP OPERATOR FAMILY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP OPERATOR </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP OPERATOR FAMILY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropoperator.html b/doc/src/sgml/html/sql-dropoperator.html
new file mode 100644
index 0000000..b6a2b70
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropoperator.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP OPERATOR</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW" /><link rel="next" href="sql-dropopclass.html" title="DROP OPERATOR CLASS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP OPERATOR</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropopclass.html" title="DROP OPERATOR CLASS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPOPERATOR"><div class="titlepage"></div><a id="id-1.9.3.119.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP OPERATOR</span></h2><p>DROP OPERATOR — remove an operator</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP OPERATOR [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ( { <em class="replaceable"><code>left_type</code></em> | NONE } , <em class="replaceable"><code>right_type</code></em> ) [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.119.5"><h2>Description</h2><p>
+ <code class="command">DROP OPERATOR</code> drops an existing operator from
+ the database system. To execute this command you must be the owner
+ of the operator.
+ </p></div><div class="refsect1" id="id-1.9.3.119.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the operator does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing operator.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>left_type</code></em></span></dt><dd><p>
+ The data type of the operator's left operand; write
+ <code class="literal">NONE</code> if the operator has no left operand.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>right_type</code></em></span></dt><dd><p>
+ The data type of the operator's right operand.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the operator (such as views
+ using it), and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the operator if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.119.7"><h2>Examples</h2><p>
+ Remove the power operator <code class="literal">a^b</code> for type <code class="type">integer</code>:
+</p><pre class="programlisting">
+DROP OPERATOR ^ (integer, integer);
+</pre><p>
+ </p><p>
+ Remove the bitwise-complement prefix operator
+ <code class="literal">~b</code> for type <code class="type">bit</code>:
+</p><pre class="programlisting">
+DROP OPERATOR ~ (none, bit);
+</pre><p>
+ </p><p>
+ Remove multiple operators in one command:
+</p><pre class="programlisting">
+DROP OPERATOR ~ (none, bit), ^ (integer, integer);
+</pre></div><div class="refsect1" id="id-1.9.3.119.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP OPERATOR</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.119.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createoperator.html" title="CREATE OPERATOR"><span class="refentrytitle">CREATE OPERATOR</span></a>, <a class="xref" href="sql-alteroperator.html" title="ALTER OPERATOR"><span class="refentrytitle">ALTER OPERATOR</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropopclass.html" title="DROP OPERATOR CLASS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP MATERIALIZED VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP OPERATOR CLASS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropopfamily.html b/doc/src/sgml/html/sql-dropopfamily.html
new file mode 100644
index 0000000..7067d60
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropopfamily.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP OPERATOR FAMILY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropopclass.html" title="DROP OPERATOR CLASS" /><link rel="next" href="sql-drop-owned.html" title="DROP OWNED" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP OPERATOR FAMILY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropopclass.html" title="DROP OPERATOR CLASS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-drop-owned.html" title="DROP OWNED">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPOPFAMILY"><div class="titlepage"></div><a id="id-1.9.3.121.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP OPERATOR FAMILY</span></h2><p>DROP OPERATOR FAMILY — remove an operator family</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP OPERATOR FAMILY [ IF EXISTS ] <em class="replaceable"><code>name</code></em> USING <em class="replaceable"><code>index_method</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.121.5"><h2>Description</h2><p>
+ <code class="command">DROP OPERATOR FAMILY</code> drops an existing operator family.
+ To execute this command you must be the owner of the operator family.
+ </p><p>
+ <code class="command">DROP OPERATOR FAMILY</code> includes dropping any operator
+ classes contained in the family, but it does not drop any of the operators
+ or functions referenced by the family. If there are any indexes depending
+ on operator classes within the family, you will need to specify
+ <code class="literal">CASCADE</code> for the drop to complete.
+ </p></div><div class="refsect1" id="id-1.9.3.121.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the operator family does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing operator family.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_method</code></em></span></dt><dd><p>
+ The name of the index access method the operator family is for.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the operator family,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the operator family if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.121.7"><h2>Examples</h2><p>
+ Remove the B-tree operator family <code class="literal">float_ops</code>:
+
+</p><pre class="programlisting">
+DROP OPERATOR FAMILY float_ops USING btree;
+</pre><p>
+
+ This command will not succeed if there are any existing indexes
+ that use operator classes within the family. Add <code class="literal">CASCADE</code> to
+ drop such indexes along with the operator family.
+ </p></div><div class="refsect1" id="id-1.9.3.121.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP OPERATOR FAMILY</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.121.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alteropfamily.html" title="ALTER OPERATOR FAMILY"><span class="refentrytitle">ALTER OPERATOR FAMILY</span></a>, <a class="xref" href="sql-createopfamily.html" title="CREATE OPERATOR FAMILY"><span class="refentrytitle">CREATE OPERATOR FAMILY</span></a>, <a class="xref" href="sql-alteropclass.html" title="ALTER OPERATOR CLASS"><span class="refentrytitle">ALTER OPERATOR CLASS</span></a>, <a class="xref" href="sql-createopclass.html" title="CREATE OPERATOR CLASS"><span class="refentrytitle">CREATE OPERATOR CLASS</span></a>, <a class="xref" href="sql-dropopclass.html" title="DROP OPERATOR CLASS"><span class="refentrytitle">DROP OPERATOR CLASS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropopclass.html" title="DROP OPERATOR CLASS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-drop-owned.html" title="DROP OWNED">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP OPERATOR CLASS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP OWNED</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droppolicy.html b/doc/src/sgml/html/sql-droppolicy.html
new file mode 100644
index 0000000..40f2745
--- /dev/null
+++ b/doc/src/sgml/html/sql-droppolicy.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP POLICY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-drop-owned.html" title="DROP OWNED" /><link rel="next" href="sql-dropprocedure.html" title="DROP PROCEDURE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP POLICY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-drop-owned.html" title="DROP OWNED">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropprocedure.html" title="DROP PROCEDURE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPPOLICY"><div class="titlepage"></div><a id="id-1.9.3.123.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP POLICY</span></h2><p>DROP POLICY — remove a row-level security policy from a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP POLICY [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.123.5"><h2>Description</h2><p>
+ <code class="command">DROP POLICY</code> removes the specified policy from the table.
+ Note that if the last policy is removed for a table and the table still has
+ row-level security enabled via <code class="command">ALTER TABLE</code>, then the
+ default-deny policy will be used. <code class="literal">ALTER TABLE ... DISABLE ROW
+ LEVEL SECURITY</code> can be used to disable row-level security for a
+ table, whether policies for the table exist or not.
+ </p></div><div class="refsect1" id="id-1.9.3.123.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the policy does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the policy to drop.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table that
+ the policy is on.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code><br /></span><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ These key words do not have any effect, since there are no
+ dependencies on policies.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.123.7"><h2>Examples</h2><p>
+ To drop the policy called <code class="literal">p1</code> on the table named
+ <code class="literal">my_table</code>:
+
+</p><pre class="programlisting">
+DROP POLICY p1 ON my_table;
+</pre></div><div class="refsect1" id="id-1.9.3.123.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP POLICY</code> is a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.123.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createpolicy.html" title="CREATE POLICY"><span class="refentrytitle">CREATE POLICY</span></a>, <a class="xref" href="sql-alterpolicy.html" title="ALTER POLICY"><span class="refentrytitle">ALTER POLICY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-drop-owned.html" title="DROP OWNED">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropprocedure.html" title="DROP PROCEDURE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP OWNED </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP PROCEDURE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropprocedure.html b/doc/src/sgml/html/sql-dropprocedure.html
new file mode 100644
index 0000000..36902eb
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropprocedure.html
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP PROCEDURE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droppolicy.html" title="DROP POLICY" /><link rel="next" href="sql-droppublication.html" title="DROP PUBLICATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP PROCEDURE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droppolicy.html" title="DROP POLICY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droppublication.html" title="DROP PUBLICATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPPROCEDURE"><div class="titlepage"></div><a id="id-1.9.3.124.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP PROCEDURE</span></h2><p>DROP PROCEDURE — remove a procedure</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP PROCEDURE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] [, ...]
+ [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.124.5"><h2>Description</h2><p>
+ <code class="command">DROP PROCEDURE</code> removes the definition of one or more
+ existing procedures. To execute this command the user must be the
+ owner of the procedure(s). The argument types to the
+ procedure(s) usually must be specified, since several different procedures
+ can exist with the same name and different argument lists.
+ </p></div><div class="refsect1" id="id-1.9.3.124.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the procedure does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing procedure.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of an argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>. If omitted,
+ the default is <code class="literal">IN</code> (but see below).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of an argument.
+ Note that <code class="command">DROP PROCEDURE</code> does not actually pay
+ any attention to argument names, since only the argument data
+ types are used to determine the procedure's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type(s) of the procedure's arguments (optionally
+ schema-qualified), if any.
+ See below for details.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the procedure,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the procedure if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPPROCEDURE-NOTES"><h2>Notes</h2><p>
+ If there is only one procedure of the given name, the argument list
+ can be omitted. Omit the parentheses too in this case.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, it's sufficient to list the
+ input (including <code class="literal">INOUT</code>) arguments,
+ because no two routines of the same name are allowed to share the same
+ input-argument list. Moreover, the <code class="command">DROP</code> command
+ will not actually check that you wrote the types
+ of <code class="literal">OUT</code> arguments correctly; so any arguments that
+ are explicitly marked <code class="literal">OUT</code> are just noise. But
+ writing them is recommendable for consistency with the
+ corresponding <code class="command">CREATE</code> command.
+ </p><p>
+ For compatibility with the SQL standard, it is also allowed to write
+ all the argument data types (including those of <code class="literal">OUT</code>
+ arguments) without
+ any <em class="replaceable"><code>argmode</code></em> markers.
+ When this is done, the types of the procedure's <code class="literal">OUT</code>
+ argument(s) <span class="emphasis"><em>will</em></span> be verified against the command.
+ This provision creates an ambiguity, in that when the argument list
+ contains no <em class="replaceable"><code>argmode</code></em>
+ markers, it's unclear which rule is intended.
+ The <code class="command">DROP</code> command will attempt the lookup both ways,
+ and will throw an error if two different procedures are found.
+ To avoid the risk of such ambiguity, it's recommendable to
+ write <code class="literal">IN</code> markers explicitly rather than letting them
+ be defaulted, thus forcing the
+ traditional <span class="productname">PostgreSQL</span> interpretation to be
+ used.
+ </p><p>
+ The lookup rules just explained are also used by other commands that
+ act on existing procedures, such as <code class="command">ALTER PROCEDURE</code>
+ and <code class="command">COMMENT ON PROCEDURE</code>.
+ </p></div><div class="refsect1" id="SQL-DROPPROCEDURE-EXAMPLES"><h2>Examples</h2><p>
+ If there is only one procedure <code class="literal">do_db_maintenance</code>,
+ this command is sufficient to drop it:
+</p><pre class="programlisting">
+DROP PROCEDURE do_db_maintenance;
+</pre><p>
+ </p><p>
+ Given this procedure definition:
+</p><pre class="programlisting">
+CREATE PROCEDURE do_db_maintenance(IN target_schema text, OUT results text) ...
+</pre><p>
+ any one of these commands would work to drop it:
+</p><pre class="programlisting">
+DROP PROCEDURE do_db_maintenance(IN target_schema text, OUT results text);
+DROP PROCEDURE do_db_maintenance(IN text, OUT text);
+DROP PROCEDURE do_db_maintenance(IN text);
+DROP PROCEDURE do_db_maintenance(text);
+DROP PROCEDURE do_db_maintenance(text, text); -- potentially ambiguous
+</pre><p>
+ However, the last example would be ambiguous if there is also, say,
+</p><pre class="programlisting">
+CREATE PROCEDURE do_db_maintenance(IN target_schema text, IN options text) ...
+</pre></div><div class="refsect1" id="SQL-DROPPROCEDURE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ This command conforms to the SQL standard, with
+ these <span class="productname">PostgreSQL</span> extensions:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>The standard only allows one procedure to be dropped per command.</p></li><li class="listitem"><p>The <code class="literal">IF EXISTS</code> option is an extension.</p></li><li class="listitem"><p>The ability to specify argument modes and names is an
+ extension, and the lookup rules differ when modes are given.</p></li></ul></div></div><div class="refsect1" id="id-1.9.3.124.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createprocedure.html" title="CREATE PROCEDURE"><span class="refentrytitle">CREATE PROCEDURE</span></a>, <a class="xref" href="sql-alterprocedure.html" title="ALTER PROCEDURE"><span class="refentrytitle">ALTER PROCEDURE</span></a>, <a class="xref" href="sql-dropfunction.html" title="DROP FUNCTION"><span class="refentrytitle">DROP FUNCTION</span></a>, <a class="xref" href="sql-droproutine.html" title="DROP ROUTINE"><span class="refentrytitle">DROP ROUTINE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droppolicy.html" title="DROP POLICY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droppublication.html" title="DROP PUBLICATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP POLICY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP PUBLICATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droppublication.html b/doc/src/sgml/html/sql-droppublication.html
new file mode 100644
index 0000000..ca5d717
--- /dev/null
+++ b/doc/src/sgml/html/sql-droppublication.html
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP PUBLICATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropprocedure.html" title="DROP PROCEDURE" /><link rel="next" href="sql-droprole.html" title="DROP ROLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP PUBLICATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropprocedure.html" title="DROP PROCEDURE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droprole.html" title="DROP ROLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPPUBLICATION"><div class="titlepage"></div><a id="id-1.9.3.125.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP PUBLICATION</span></h2><p>DROP PUBLICATION — remove a publication</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP PUBLICATION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.125.5"><h2>Description</h2><p>
+ <code class="command">DROP PUBLICATION</code> removes an existing publication from
+ the database.
+ </p><p>
+ A publication can only be dropped by its owner or a superuser.
+ </p></div><div class="refsect1" id="id-1.9.3.125.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the publication does not exist. A notice is
+ issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing publication.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code><br /></span><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ These key words do not have any effect, since there are no dependencies
+ on publications.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.125.7"><h2>Examples</h2><p>
+ Drop a publication:
+</p><pre class="programlisting">
+DROP PUBLICATION mypublication;
+</pre></div><div class="refsect1" id="id-1.9.3.125.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP PUBLICATION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.125.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createpublication.html" title="CREATE PUBLICATION"><span class="refentrytitle">CREATE PUBLICATION</span></a>, <a class="xref" href="sql-alterpublication.html" title="ALTER PUBLICATION"><span class="refentrytitle">ALTER PUBLICATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropprocedure.html" title="DROP PROCEDURE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droprole.html" title="DROP ROLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP PROCEDURE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP ROLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droprole.html b/doc/src/sgml/html/sql-droprole.html
new file mode 100644
index 0000000..e482778
--- /dev/null
+++ b/doc/src/sgml/html/sql-droprole.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP ROLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droppublication.html" title="DROP PUBLICATION" /><link rel="next" href="sql-droproutine.html" title="DROP ROUTINE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP ROLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droppublication.html" title="DROP PUBLICATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droproutine.html" title="DROP ROUTINE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPROLE"><div class="titlepage"></div><a id="id-1.9.3.126.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP ROLE</span></h2><p>DROP ROLE — remove a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP ROLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...]
+</pre></div><div class="refsect1" id="id-1.9.3.126.5"><h2>Description</h2><p>
+ <code class="command">DROP ROLE</code> removes the specified role(s).
+ To drop a superuser role, you must be a superuser yourself;
+ to drop non-superuser roles, you must have <code class="literal">CREATEROLE</code>
+ privilege.
+ </p><p>
+ A role cannot be removed if it is still referenced in any database
+ of the cluster; an error will be raised if so. Before dropping the role,
+ you must drop all the objects it owns (or reassign their ownership)
+ and revoke any privileges the role has been granted on other objects.
+ The <a class="link" href="sql-reassign-owned.html" title="REASSIGN OWNED"><code class="command">REASSIGN
+ OWNED</code></a> and <a class="link" href="sql-drop-owned.html" title="DROP OWNED"><code class="command">DROP
+ OWNED</code></a>
+ commands can be useful for this purpose; see <a class="xref" href="role-removal.html" title="22.4. Dropping Roles">Section 22.4</a>
+ for more discussion.
+ </p><p>
+ However, it is not necessary to remove role memberships involving
+ the role; <code class="command">DROP ROLE</code> automatically revokes any memberships
+ of the target role in other roles, and of other roles in the target role.
+ The other roles are not dropped nor otherwise affected.
+ </p></div><div class="refsect1" id="id-1.9.3.126.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the role does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the role to remove.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.126.7"><h2>Notes</h2><p>
+ <span class="productname">PostgreSQL</span> includes a program <a class="xref" href="app-dropuser.html" title="dropuser"><span class="refentrytitle"><span class="application">dropuser</span></span></a> that has the
+ same functionality as this command (in fact, it calls this command)
+ but can be run from the command shell.
+ </p></div><div class="refsect1" id="id-1.9.3.126.8"><h2>Examples</h2><p>
+ To drop a role:
+</p><pre class="programlisting">
+DROP ROLE jonathan;
+</pre></div><div class="refsect1" id="id-1.9.3.126.9"><h2>Compatibility</h2><p>
+ The SQL standard defines <code class="command">DROP ROLE</code>, but it allows
+ only one role to be dropped at a time, and it specifies different
+ privilege requirements than <span class="productname">PostgreSQL</span> uses.
+ </p></div><div class="refsect1" id="id-1.9.3.126.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createrole.html" title="CREATE ROLE"><span class="refentrytitle">CREATE ROLE</span></a>, <a class="xref" href="sql-alterrole.html" title="ALTER ROLE"><span class="refentrytitle">ALTER ROLE</span></a>, <a class="xref" href="sql-set-role.html" title="SET ROLE"><span class="refentrytitle">SET ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droppublication.html" title="DROP PUBLICATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droproutine.html" title="DROP ROUTINE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP PUBLICATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP ROUTINE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droproutine.html b/doc/src/sgml/html/sql-droproutine.html
new file mode 100644
index 0000000..7bd9cf3
--- /dev/null
+++ b/doc/src/sgml/html/sql-droproutine.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP ROUTINE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droprole.html" title="DROP ROLE" /><link rel="next" href="sql-droprule.html" title="DROP RULE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP ROUTINE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droprole.html" title="DROP ROLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droprule.html" title="DROP RULE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPROUTINE"><div class="titlepage"></div><a id="id-1.9.3.127.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP ROUTINE</span></h2><p>DROP ROUTINE — remove a routine</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP ROUTINE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] [, ...]
+ [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.127.5"><h2>Description</h2><p>
+ <code class="command">DROP ROUTINE</code> removes the definition of one or more
+ existing routines. The term <span class="quote">“<span class="quote">routine</span>”</span> includes
+ aggregate functions, normal functions, and procedures. See
+ under <a class="xref" href="sql-dropaggregate.html" title="DROP AGGREGATE"><span class="refentrytitle">DROP AGGREGATE</span></a>, <a class="xref" href="sql-dropfunction.html" title="DROP FUNCTION"><span class="refentrytitle">DROP FUNCTION</span></a>,
+ and <a class="xref" href="sql-dropprocedure.html" title="DROP PROCEDURE"><span class="refentrytitle">DROP PROCEDURE</span></a> for the description of the
+ parameters, more examples, and further details.
+ </p></div><div class="refsect1" id="SQL-DROPROUTINE-NOTES"><h2>Notes</h2><p>
+ The lookup rules used by <code class="command">DROP ROUTINE</code> are
+ fundamentally the same as for <code class="command">DROP PROCEDURE</code>; in
+ particular, <code class="command">DROP ROUTINE</code> shares that command's
+ behavior of considering an argument list that has
+ no <em class="replaceable"><code>argmode</code></em> markers to be
+ possibly using the SQL standard's definition that <code class="literal">OUT</code>
+ arguments are included in the list. (<code class="command">DROP AGGREGATE</code>
+ and <code class="command">DROP FUNCTION</code> do not do that.)
+ </p><p>
+ In some cases where the same name is shared by routines of different
+ kinds, it is possible for <code class="command">DROP ROUTINE</code> to fail with
+ an ambiguity error when a more specific command (<code class="command">DROP
+ FUNCTION</code>, etc.) would work. Specifying the argument type
+ list more carefully will also resolve such problems.
+ </p><p>
+ These lookup rules are also used by other commands that
+ act on existing routines, such as <code class="command">ALTER ROUTINE</code>
+ and <code class="command">COMMENT ON ROUTINE</code>.
+ </p></div><div class="refsect1" id="SQL-DROPROUTINE-EXAMPLES"><h2>Examples</h2><p>
+ To drop the routine <code class="literal">foo</code> for type
+ <code class="type">integer</code>:
+</p><pre class="programlisting">
+DROP ROUTINE foo(integer);
+</pre><p>
+ This command will work independent of whether <code class="literal">foo</code> is an
+ aggregate, function, or procedure.
+ </p></div><div class="refsect1" id="SQL-DROPROUTINE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ This command conforms to the SQL standard, with
+ these <span class="productname">PostgreSQL</span> extensions:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>The standard only allows one routine to be dropped per command.</p></li><li class="listitem"><p>The <code class="literal">IF EXISTS</code> option is an extension.</p></li><li class="listitem"><p>The ability to specify argument modes and names is an
+ extension, and the lookup rules differ when modes are given.</p></li><li class="listitem"><p>User-definable aggregate functions are an extension.</p></li></ul></div></div><div class="refsect1" id="id-1.9.3.127.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-dropaggregate.html" title="DROP AGGREGATE"><span class="refentrytitle">DROP AGGREGATE</span></a>, <a class="xref" href="sql-dropfunction.html" title="DROP FUNCTION"><span class="refentrytitle">DROP FUNCTION</span></a>, <a class="xref" href="sql-dropprocedure.html" title="DROP PROCEDURE"><span class="refentrytitle">DROP PROCEDURE</span></a>, <a class="xref" href="sql-alterroutine.html" title="ALTER ROUTINE"><span class="refentrytitle">ALTER ROUTINE</span></a></span><p>
+ Note that there is no <code class="literal">CREATE ROUTINE</code> command.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droprole.html" title="DROP ROLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droprule.html" title="DROP RULE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP ROLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP RULE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droprule.html b/doc/src/sgml/html/sql-droprule.html
new file mode 100644
index 0000000..cfd6ad3
--- /dev/null
+++ b/doc/src/sgml/html/sql-droprule.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP RULE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droproutine.html" title="DROP ROUTINE" /><link rel="next" href="sql-dropschema.html" title="DROP SCHEMA" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP RULE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droproutine.html" title="DROP ROUTINE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropschema.html" title="DROP SCHEMA">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPRULE"><div class="titlepage"></div><a id="id-1.9.3.128.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP RULE</span></h2><p>DROP RULE — remove a rewrite rule</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP RULE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.128.5"><h2>Description</h2><p>
+ <code class="command">DROP RULE</code> drops a rewrite rule.
+ </p></div><div class="refsect1" id="id-1.9.3.128.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the rule does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the rule to drop.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table or view that
+ the rule applies to.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the rule,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the rule if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.128.7"><h2>Examples</h2><p>
+ To drop the rewrite rule <code class="literal">newrule</code>:
+
+</p><pre class="programlisting">
+DROP RULE newrule ON mytable;
+</pre></div><div class="refsect1" id="id-1.9.3.128.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP RULE</code> is a
+ <span class="productname">PostgreSQL</span> language extension, as is the
+ entire query rewrite system.
+ </p></div><div class="refsect1" id="id-1.9.3.128.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createrule.html" title="CREATE RULE"><span class="refentrytitle">CREATE RULE</span></a>, <a class="xref" href="sql-alterrule.html" title="ALTER RULE"><span class="refentrytitle">ALTER RULE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droproutine.html" title="DROP ROUTINE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropschema.html" title="DROP SCHEMA">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP ROUTINE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP SCHEMA</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropschema.html b/doc/src/sgml/html/sql-dropschema.html
new file mode 100644
index 0000000..08cde3e
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropschema.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP SCHEMA</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droprule.html" title="DROP RULE" /><link rel="next" href="sql-dropsequence.html" title="DROP SEQUENCE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP SCHEMA</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droprule.html" title="DROP RULE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropsequence.html" title="DROP SEQUENCE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPSCHEMA"><div class="titlepage"></div><a id="id-1.9.3.129.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP SCHEMA</span></h2><p>DROP SCHEMA — remove a schema</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP SCHEMA [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.129.5"><h2>Description</h2><p>
+ <code class="command">DROP SCHEMA</code> removes schemas from the database.
+ </p><p>
+ A schema can only be dropped by its owner or a superuser. Note that
+ the owner can drop the schema (and thereby all contained objects)
+ even if they do not own some of the objects within the schema.
+ </p></div><div class="refsect1" id="id-1.9.3.129.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the schema does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a schema.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects (tables, functions, etc.) that are
+ contained in the schema,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the schema if it contains any objects. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.129.7"><h2>Notes</h2><p>
+ Using the <code class="literal">CASCADE</code> option might make the command
+ remove objects in other schemas besides the one(s) named.
+ </p></div><div class="refsect1" id="id-1.9.3.129.8"><h2>Examples</h2><p>
+ To remove schema <code class="literal">mystuff</code> from the database,
+ along with everything it contains:
+
+</p><pre class="programlisting">
+DROP SCHEMA mystuff CASCADE;
+</pre></div><div class="refsect1" id="id-1.9.3.129.9"><h2>Compatibility</h2><p>
+ <code class="command">DROP SCHEMA</code> is fully conforming with the SQL
+ standard, except that the standard only allows one schema to be
+ dropped per command, and apart from the
+ <code class="literal">IF EXISTS</code> option, which is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.129.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterschema.html" title="ALTER SCHEMA"><span class="refentrytitle">ALTER SCHEMA</span></a>, <a class="xref" href="sql-createschema.html" title="CREATE SCHEMA"><span class="refentrytitle">CREATE SCHEMA</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droprule.html" title="DROP RULE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropsequence.html" title="DROP SEQUENCE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP RULE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP SEQUENCE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropsequence.html b/doc/src/sgml/html/sql-dropsequence.html
new file mode 100644
index 0000000..424c17f
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropsequence.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP SEQUENCE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropschema.html" title="DROP SCHEMA" /><link rel="next" href="sql-dropserver.html" title="DROP SERVER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP SEQUENCE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropschema.html" title="DROP SCHEMA">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropserver.html" title="DROP SERVER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPSEQUENCE"><div class="titlepage"></div><a id="id-1.9.3.130.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP SEQUENCE</span></h2><p>DROP SEQUENCE — remove a sequence</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP SEQUENCE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.130.5"><h2>Description</h2><p>
+ <code class="command">DROP SEQUENCE</code> removes sequence number
+ generators. A sequence can only be dropped by its owner or a superuser.
+ </p></div><div class="refsect1" id="id-1.9.3.130.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the sequence does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a sequence.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the sequence,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the sequence if any objects depend on it. This
+ is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.130.7"><h2>Examples</h2><p>
+ To remove the sequence <code class="literal">serial</code>:
+
+</p><pre class="programlisting">
+DROP SEQUENCE serial;
+</pre></div><div class="refsect1" id="id-1.9.3.130.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP SEQUENCE</code> conforms to the <acronym class="acronym">SQL</acronym>
+ standard, except that the standard only allows one
+ sequence to be dropped per command, and apart from the
+ <code class="literal">IF EXISTS</code> option, which is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.130.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createsequence.html" title="CREATE SEQUENCE"><span class="refentrytitle">CREATE SEQUENCE</span></a>, <a class="xref" href="sql-altersequence.html" title="ALTER SEQUENCE"><span class="refentrytitle">ALTER SEQUENCE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropschema.html" title="DROP SCHEMA">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropserver.html" title="DROP SERVER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP SCHEMA </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP SERVER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropserver.html b/doc/src/sgml/html/sql-dropserver.html
new file mode 100644
index 0000000..18e1dde
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropserver.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP SERVER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropsequence.html" title="DROP SEQUENCE" /><link rel="next" href="sql-dropstatistics.html" title="DROP STATISTICS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP SERVER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropsequence.html" title="DROP SEQUENCE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropstatistics.html" title="DROP STATISTICS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPSERVER"><div class="titlepage"></div><a id="id-1.9.3.131.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP SERVER</span></h2><p>DROP SERVER — remove a foreign server descriptor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP SERVER [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.131.5"><h2>Description</h2><p>
+ <code class="command">DROP SERVER</code> removes an existing foreign server
+ descriptor. To execute this command, the current user must be the
+ owner of the server.
+ </p></div><div class="refsect1" id="id-1.9.3.131.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the server does not exist. A notice is
+ issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of an existing server.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the server (such as
+ user mappings),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the server if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.131.7"><h2>Examples</h2><p>
+ Drop a server <code class="literal">foo</code> if it exists:
+</p><pre class="programlisting">
+DROP SERVER IF EXISTS foo;
+</pre></div><div class="refsect1" id="id-1.9.3.131.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP SERVER</code> conforms to ISO/IEC 9075-9
+ (SQL/MED). The <code class="literal">IF EXISTS</code> clause is
+ a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.131.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a>, <a class="xref" href="sql-alterserver.html" title="ALTER SERVER"><span class="refentrytitle">ALTER SERVER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropsequence.html" title="DROP SEQUENCE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropstatistics.html" title="DROP STATISTICS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP SEQUENCE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP STATISTICS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropstatistics.html b/doc/src/sgml/html/sql-dropstatistics.html
new file mode 100644
index 0000000..dc92d5e
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropstatistics.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP STATISTICS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropserver.html" title="DROP SERVER" /><link rel="next" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP STATISTICS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropserver.html" title="DROP SERVER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPSTATISTICS"><div class="titlepage"></div><a id="id-1.9.3.132.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP STATISTICS</span></h2><p>DROP STATISTICS — remove extended statistics</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP STATISTICS [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.132.5"><h2>Description</h2><p>
+ <code class="command">DROP STATISTICS</code> removes statistics object(s) from the
+ database. Only the statistics object's owner, the schema owner, or a
+ superuser can drop a statistics object.
+ </p></div><div class="refsect1" id="id-1.9.3.132.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the statistics object does not exist. A notice
+ is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the statistics object to drop.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code><br /></span><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ These key words do not have any effect, since there are no dependencies
+ on statistics.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.132.7"><h2>Examples</h2><p>
+ To destroy two statistics objects in different schemas, without failing
+ if they don't exist:
+
+</p><pre class="programlisting">
+DROP STATISTICS IF EXISTS
+ accounting.users_uid_creation,
+ public.grants_user_role;
+</pre></div><div class="refsect1" id="id-1.9.3.132.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP STATISTICS</code> command in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.132.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterstatistics.html" title="ALTER STATISTICS"><span class="refentrytitle">ALTER STATISTICS</span></a>, <a class="xref" href="sql-createstatistics.html" title="CREATE STATISTICS"><span class="refentrytitle">CREATE STATISTICS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropserver.html" title="DROP SERVER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP SERVER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP SUBSCRIPTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropsubscription.html b/doc/src/sgml/html/sql-dropsubscription.html
new file mode 100644
index 0000000..db55710
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropsubscription.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP SUBSCRIPTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropstatistics.html" title="DROP STATISTICS" /><link rel="next" href="sql-droptable.html" title="DROP TABLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP SUBSCRIPTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropstatistics.html" title="DROP STATISTICS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptable.html" title="DROP TABLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPSUBSCRIPTION"><div class="titlepage"></div><a id="id-1.9.3.133.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP SUBSCRIPTION</span></h2><p>DROP SUBSCRIPTION — remove a subscription</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP SUBSCRIPTION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.133.5"><h2>Description</h2><p>
+ <code class="command">DROP SUBSCRIPTION</code> removes a subscription from the
+ database cluster.
+ </p><p>
+ A subscription can only be dropped by a superuser.
+ </p><p>
+ <code class="command">DROP SUBSCRIPTION</code> cannot be executed inside a
+ transaction block if the subscription is associated with a replication
+ slot. (You can use <code class="command">ALTER SUBSCRIPTION</code> to unset the
+ slot.)
+ </p></div><div class="refsect1" id="id-1.9.3.133.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a subscription to be dropped.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code><br /></span><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ These key words do not have any effect, since there are no dependencies
+ on subscriptions.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.133.7"><h2>Notes</h2><p>
+ When dropping a subscription that is associated with a replication slot on
+ the remote host (the normal state), <code class="command">DROP SUBSCRIPTION</code>
+ will connect to the remote host and try to drop the replication slot (and
+ any remaining table synchronization slots) as
+ part of its operation. This is necessary so that the resources allocated
+ for the subscription on the remote host are released. If this fails,
+ either because the remote host is not reachable or because the remote
+ replication slot cannot be dropped or does not exist or never existed,
+ the <code class="command">DROP SUBSCRIPTION</code> command will fail. To proceed
+ in this situation, first disable the subscription by executing
+ <code class="literal">ALTER SUBSCRIPTION ... DISABLE</code>, and then disassociate
+ it from the replication slot by executing
+ <code class="literal">ALTER SUBSCRIPTION ... SET (slot_name = NONE)</code>.
+ After that, <code class="command">DROP SUBSCRIPTION</code> will no longer attempt any
+ actions on a remote host. Note that if the remote replication slot still
+ exists, it (and any related table synchronization slots) should then be
+ dropped manually; otherwise it/they will continue to
+ reserve WAL and might eventually cause the disk to fill up. See
+ also <a class="xref" href="logical-replication-subscription.html#LOGICAL-REPLICATION-SUBSCRIPTION-SLOT" title="31.2.1. Replication Slot Management">Section 31.2.1</a>.
+ </p><p>
+ If a subscription is associated with a replication slot, then <code class="command">DROP
+ SUBSCRIPTION</code> cannot be executed inside a transaction block.
+ </p></div><div class="refsect1" id="id-1.9.3.133.8"><h2>Examples</h2><p>
+ Drop a subscription:
+</p><pre class="programlisting">
+DROP SUBSCRIPTION mysub;
+</pre></div><div class="refsect1" id="id-1.9.3.133.9"><h2>Compatibility</h2><p>
+ <code class="command">DROP SUBSCRIPTION</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.133.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createsubscription.html" title="CREATE SUBSCRIPTION"><span class="refentrytitle">CREATE SUBSCRIPTION</span></a>, <a class="xref" href="sql-altersubscription.html" title="ALTER SUBSCRIPTION"><span class="refentrytitle">ALTER SUBSCRIPTION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropstatistics.html" title="DROP STATISTICS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptable.html" title="DROP TABLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP STATISTICS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TABLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptable.html b/doc/src/sgml/html/sql-droptable.html
new file mode 100644
index 0000000..edc3c89
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptable.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TABLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION" /><link rel="next" href="sql-droptablespace.html" title="DROP TABLESPACE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TABLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptablespace.html" title="DROP TABLESPACE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTABLE"><div class="titlepage"></div><a id="id-1.9.3.134.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TABLE</span></h2><p>DROP TABLE — remove a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TABLE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.134.5"><h2>Description</h2><p>
+ <code class="command">DROP TABLE</code> removes tables from the database.
+ Only the table owner, the schema owner, and superuser can drop a
+ table. To empty a table of rows
+ without destroying the table, use <a class="link" href="sql-delete.html" title="DELETE"><code class="command">DELETE</code></a>
+ or <a class="link" href="sql-truncate.html" title="TRUNCATE"><code class="command">TRUNCATE</code></a>.
+ </p><p>
+ <code class="command">DROP TABLE</code> always removes any indexes, rules,
+ triggers, and constraints that exist for the target table.
+ However, to drop a table that is referenced by a view or a foreign-key
+ constraint of another table, <code class="literal">CASCADE</code> must be
+ specified. (<code class="literal">CASCADE</code> will remove a dependent view entirely,
+ but in the foreign-key case it will only remove the foreign-key
+ constraint, not the other table entirely.)
+ </p></div><div class="refsect1" id="id-1.9.3.134.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the table does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to drop.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the table (such as
+ views),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the table if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.134.7"><h2>Examples</h2><p>
+ To destroy two tables, <code class="literal">films</code> and
+ <code class="literal">distributors</code>:
+
+</p><pre class="programlisting">
+DROP TABLE films, distributors;
+</pre></div><div class="refsect1" id="id-1.9.3.134.8"><h2>Compatibility</h2><p>
+ This command conforms to the SQL standard, except that the standard only
+ allows one table to be dropped per command, and apart from the
+ <code class="literal">IF EXISTS</code> option, which is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.134.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a>, <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropsubscription.html" title="DROP SUBSCRIPTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptablespace.html" title="DROP TABLESPACE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP SUBSCRIPTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TABLESPACE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptablespace.html b/doc/src/sgml/html/sql-droptablespace.html
new file mode 100644
index 0000000..d98ef2c
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptablespace.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TABLESPACE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptable.html" title="DROP TABLE" /><link rel="next" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TABLESPACE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptable.html" title="DROP TABLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTABLESPACE"><div class="titlepage"></div><a id="id-1.9.3.135.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TABLESPACE</span></h2><p>DROP TABLESPACE — remove a tablespace</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TABLESPACE [ IF EXISTS ] <em class="replaceable"><code>name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.135.5"><h2>Description</h2><p>
+ <code class="command">DROP TABLESPACE</code> removes a tablespace from the system.
+ </p><p>
+ A tablespace can only be dropped by its owner or a superuser.
+ The tablespace must be empty of all database objects before it can be
+ dropped. It is possible that objects in other databases might still reside
+ in the tablespace even if no objects in the current database are using
+ the tablespace. Also, if the tablespace is listed in the <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> setting of any active session, the
+ <code class="command">DROP</code> might fail due to temporary files residing in the
+ tablespace.
+ </p></div><div class="refsect1" id="id-1.9.3.135.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the tablespace does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a tablespace.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.135.7"><h2>Notes</h2><p>
+ <code class="command">DROP TABLESPACE</code> cannot be executed inside a transaction block.
+ </p></div><div class="refsect1" id="id-1.9.3.135.8"><h2>Examples</h2><p>
+ To remove tablespace <code class="literal">mystuff</code> from the system:
+</p><pre class="programlisting">
+DROP TABLESPACE mystuff;
+</pre></div><div class="refsect1" id="id-1.9.3.135.9"><h2>Compatibility</h2><p>
+ <code class="command">DROP TABLESPACE</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.135.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a>, <a class="xref" href="sql-altertablespace.html" title="ALTER TABLESPACE"><span class="refentrytitle">ALTER TABLESPACE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptable.html" title="DROP TABLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TABLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TEXT SEARCH CONFIGURATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptransform.html b/doc/src/sgml/html/sql-droptransform.html
new file mode 100644
index 0000000..7470f96
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptransform.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TRANSFORM</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE" /><link rel="next" href="sql-droptrigger.html" title="DROP TRIGGER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TRANSFORM</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptrigger.html" title="DROP TRIGGER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTRANSFORM"><div class="titlepage"></div><a id="id-1.9.3.140.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TRANSFORM</span></h2><p>DROP TRANSFORM — remove a transform</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TRANSFORM [ IF EXISTS ] FOR <em class="replaceable"><code>type_name</code></em> LANGUAGE <em class="replaceable"><code>lang_name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="SQL-DROPTRANSFORM-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">DROP TRANSFORM</code> removes a previously defined transform.
+ </p><p>
+ To be able to drop a transform, you must own the type and the language.
+ These are the same privileges that are required to create a transform.
+ </p></div><div class="refsect1" id="id-1.9.3.140.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the transform does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>type_name</code></em></span></dt><dd><p>
+ The name of the data type of the transform.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lang_name</code></em></span></dt><dd><p>
+ The name of the language of the transform.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the transform,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the transform if any objects depend on it. This is the
+ default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPTRANSFORM-EXAMPLES"><h2>Examples</h2><p>
+ To drop the transform for type <code class="type">hstore</code> and language
+ <code class="literal">plpython3u</code>:
+</p><pre class="programlisting">
+DROP TRANSFORM FOR hstore LANGUAGE plpython3u;
+</pre></div><div class="refsect1" id="SQL-DROPTRANSFORM-COMPAT"><h2>Compatibility</h2><p>
+ This form of <code class="command">DROP TRANSFORM</code> is a
+ <span class="productname">PostgreSQL</span> extension. See <a class="xref" href="sql-createtransform.html" title="CREATE TRANSFORM"><span class="refentrytitle">CREATE TRANSFORM</span></a> for details.
+ </p></div><div class="refsect1" id="id-1.9.3.140.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtransform.html" title="CREATE TRANSFORM"><span class="refentrytitle">CREATE TRANSFORM</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptrigger.html" title="DROP TRIGGER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TEXT SEARCH TEMPLATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TRIGGER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptrigger.html b/doc/src/sgml/html/sql-droptrigger.html
new file mode 100644
index 0000000..3452225
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptrigger.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptransform.html" title="DROP TRANSFORM" /><link rel="next" href="sql-droptype.html" title="DROP TYPE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptransform.html" title="DROP TRANSFORM">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptype.html" title="DROP TYPE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTRIGGER"><div class="titlepage"></div><a id="id-1.9.3.141.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TRIGGER</span></h2><p>DROP TRIGGER — remove a trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TRIGGER [ IF EXISTS ] <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table_name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.141.5"><h2>Description</h2><p>
+ <code class="command">DROP TRIGGER</code> removes an existing
+ trigger definition. To execute this command, the current
+ user must be the owner of the table for which the trigger is defined.
+ </p></div><div class="refsect1" id="id-1.9.3.141.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the trigger does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the trigger to remove.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table for which
+ the trigger is defined.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the trigger,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the trigger if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPTRIGGER-EXAMPLES"><h2>Examples</h2><p>
+ Destroy the trigger <code class="literal">if_dist_exists</code> on the table
+ <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+DROP TRIGGER if_dist_exists ON films;
+</pre></div><div class="refsect1" id="SQL-DROPTRIGGER-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The <code class="command">DROP TRIGGER</code> statement in
+ <span class="productname">PostgreSQL</span> is incompatible with the SQL
+ standard. In the SQL standard, trigger names are not local to
+ tables, so the command is simply <code class="literal">DROP TRIGGER
+ <em class="replaceable"><code>name</code></em></code>.
+ </p></div><div class="refsect1" id="id-1.9.3.141.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptransform.html" title="DROP TRANSFORM">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptype.html" title="DROP TYPE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TRANSFORM </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TYPE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptsconfig.html b/doc/src/sgml/html/sql-droptsconfig.html
new file mode 100644
index 0000000..ede0154
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptsconfig.html
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TEXT SEARCH CONFIGURATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptablespace.html" title="DROP TABLESPACE" /><link rel="next" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TEXT SEARCH CONFIGURATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptablespace.html" title="DROP TABLESPACE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTSCONFIG"><div class="titlepage"></div><a id="id-1.9.3.136.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TEXT SEARCH CONFIGURATION</span></h2><p>DROP TEXT SEARCH CONFIGURATION — remove a text search configuration</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.136.5"><h2>Description</h2><p>
+ <code class="command">DROP TEXT SEARCH CONFIGURATION</code> drops an existing text
+ search configuration. To execute this command you must be the owner of the
+ configuration.
+ </p></div><div class="refsect1" id="id-1.9.3.136.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the text search configuration does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search
+ configuration.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the text search configuration,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the text search configuration if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.136.7"><h2>Examples</h2><p>
+ Remove the text search configuration <code class="literal">my_english</code>:
+
+</p><pre class="programlisting">
+DROP TEXT SEARCH CONFIGURATION my_english;
+</pre><p>
+
+ This command will not succeed if there are any existing indexes
+ that reference the configuration in <code class="function">to_tsvector</code> calls.
+ Add <code class="literal">CASCADE</code> to
+ drop such indexes along with the text search configuration.
+ </p></div><div class="refsect1" id="id-1.9.3.136.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP TEXT SEARCH CONFIGURATION</code> statement in
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.136.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertsconfig.html" title="ALTER TEXT SEARCH CONFIGURATION"><span class="refentrytitle">ALTER TEXT SEARCH CONFIGURATION</span></a>, <a class="xref" href="sql-createtsconfig.html" title="CREATE TEXT SEARCH CONFIGURATION"><span class="refentrytitle">CREATE TEXT SEARCH CONFIGURATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptablespace.html" title="DROP TABLESPACE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TABLESPACE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TEXT SEARCH DICTIONARY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptsdictionary.html b/doc/src/sgml/html/sql-droptsdictionary.html
new file mode 100644
index 0000000..60ecb19
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptsdictionary.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TEXT SEARCH DICTIONARY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION" /><link rel="next" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TEXT SEARCH DICTIONARY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTSDICTIONARY"><div class="titlepage"></div><a id="id-1.9.3.137.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TEXT SEARCH DICTIONARY</span></h2><p>DROP TEXT SEARCH DICTIONARY — remove a text search dictionary</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.137.5"><h2>Description</h2><p>
+ <code class="command">DROP TEXT SEARCH DICTIONARY</code> drops an existing text
+ search dictionary. To execute this command you must be the owner of the
+ dictionary.
+ </p></div><div class="refsect1" id="id-1.9.3.137.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the text search dictionary does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search
+ dictionary.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the text search dictionary,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the text search dictionary if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.137.7"><h2>Examples</h2><p>
+ Remove the text search dictionary <code class="literal">english</code>:
+
+</p><pre class="programlisting">
+DROP TEXT SEARCH DICTIONARY english;
+</pre><p>
+
+ This command will not succeed if there are any existing text search
+ configurations that use the dictionary. Add <code class="literal">CASCADE</code> to
+ drop such configurations along with the dictionary.
+ </p></div><div class="refsect1" id="id-1.9.3.137.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP TEXT SEARCH DICTIONARY</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.137.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertsdictionary.html" title="ALTER TEXT SEARCH DICTIONARY"><span class="refentrytitle">ALTER TEXT SEARCH DICTIONARY</span></a>, <a class="xref" href="sql-createtsdictionary.html" title="CREATE TEXT SEARCH DICTIONARY"><span class="refentrytitle">CREATE TEXT SEARCH DICTIONARY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptsconfig.html" title="DROP TEXT SEARCH CONFIGURATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TEXT SEARCH CONFIGURATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TEXT SEARCH PARSER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptsparser.html b/doc/src/sgml/html/sql-droptsparser.html
new file mode 100644
index 0000000..c8fc08d
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptsparser.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TEXT SEARCH PARSER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY" /><link rel="next" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TEXT SEARCH PARSER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTSPARSER"><div class="titlepage"></div><a id="id-1.9.3.138.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TEXT SEARCH PARSER</span></h2><p>DROP TEXT SEARCH PARSER — remove a text search parser</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TEXT SEARCH PARSER [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.138.5"><h2>Description</h2><p>
+ <code class="command">DROP TEXT SEARCH PARSER</code> drops an existing text search
+ parser. You must be a superuser to use this command.
+ </p></div><div class="refsect1" id="id-1.9.3.138.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the text search parser does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search parser.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the text search parser,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the text search parser if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.138.7"><h2>Examples</h2><p>
+ Remove the text search parser <code class="literal">my_parser</code>:
+
+</p><pre class="programlisting">
+DROP TEXT SEARCH PARSER my_parser;
+</pre><p>
+
+ This command will not succeed if there are any existing text search
+ configurations that use the parser. Add <code class="literal">CASCADE</code> to
+ drop such configurations along with the parser.
+ </p></div><div class="refsect1" id="id-1.9.3.138.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP TEXT SEARCH PARSER</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.138.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertsparser.html" title="ALTER TEXT SEARCH PARSER"><span class="refentrytitle">ALTER TEXT SEARCH PARSER</span></a>, <a class="xref" href="sql-createtsparser.html" title="CREATE TEXT SEARCH PARSER"><span class="refentrytitle">CREATE TEXT SEARCH PARSER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptsdictionary.html" title="DROP TEXT SEARCH DICTIONARY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptstemplate.html" title="DROP TEXT SEARCH TEMPLATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TEXT SEARCH DICTIONARY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TEXT SEARCH TEMPLATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptstemplate.html b/doc/src/sgml/html/sql-droptstemplate.html
new file mode 100644
index 0000000..60f9858
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptstemplate.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TEXT SEARCH TEMPLATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER" /><link rel="next" href="sql-droptransform.html" title="DROP TRANSFORM" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TEXT SEARCH TEMPLATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-droptransform.html" title="DROP TRANSFORM">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTSTEMPLATE"><div class="titlepage"></div><a id="id-1.9.3.139.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TEXT SEARCH TEMPLATE</span></h2><p>DROP TEXT SEARCH TEMPLATE — remove a text search template</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.139.5"><h2>Description</h2><p>
+ <code class="command">DROP TEXT SEARCH TEMPLATE</code> drops an existing text search
+ template. You must be a superuser to use this command.
+ </p></div><div class="refsect1" id="id-1.9.3.139.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the text search template does not exist.
+ A notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing text search
+ template.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the text search template,
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the text search template if any objects depend on it.
+ This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.139.7"><h2>Examples</h2><p>
+ Remove the text search template <code class="literal">thesaurus</code>:
+
+</p><pre class="programlisting">
+DROP TEXT SEARCH TEMPLATE thesaurus;
+</pre><p>
+
+ This command will not succeed if there are any existing text search
+ dictionaries that use the template. Add <code class="literal">CASCADE</code> to
+ drop such dictionaries along with the template.
+ </p></div><div class="refsect1" id="id-1.9.3.139.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">DROP TEXT SEARCH TEMPLATE</code> statement in the
+ SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.139.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertstemplate.html" title="ALTER TEXT SEARCH TEMPLATE"><span class="refentrytitle">ALTER TEXT SEARCH TEMPLATE</span></a>, <a class="xref" href="sql-createtstemplate.html" title="CREATE TEXT SEARCH TEMPLATE"><span class="refentrytitle">CREATE TEXT SEARCH TEMPLATE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptsparser.html" title="DROP TEXT SEARCH PARSER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-droptransform.html" title="DROP TRANSFORM">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TEXT SEARCH PARSER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP TRANSFORM</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-droptype.html b/doc/src/sgml/html/sql-droptype.html
new file mode 100644
index 0000000..aa9109e
--- /dev/null
+++ b/doc/src/sgml/html/sql-droptype.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP TYPE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptrigger.html" title="DROP TRIGGER" /><link rel="next" href="sql-dropuser.html" title="DROP USER" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP TYPE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptrigger.html" title="DROP TRIGGER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropuser.html" title="DROP USER">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPTYPE"><div class="titlepage"></div><a id="id-1.9.3.142.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP TYPE</span></h2><p>DROP TYPE — remove a data type</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP TYPE [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.142.5"><h2>Description</h2><p>
+ <code class="command">DROP TYPE</code> removes a user-defined data type.
+ Only the owner of a type can remove it.
+ </p></div><div class="refsect1" id="id-1.9.3.142.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the type does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the data type to remove.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the type (such as
+ table columns, functions, and operators),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the type if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-DROPTYPE-EXAMPLES"><h2>Examples</h2><p>
+ To remove the data type <code class="type">box</code>:
+</p><pre class="programlisting">
+DROP TYPE box;
+</pre></div><div class="refsect1" id="SQL-DROPTYPE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ This command is similar to the corresponding command in the SQL
+ standard, apart from the <code class="literal">IF EXISTS</code>
+ option, which is a <span class="productname">PostgreSQL</span> extension.
+ But note that much of the <code class="command">CREATE TYPE</code> command
+ and the data type extension mechanisms in
+ <span class="productname">PostgreSQL</span> differ from the SQL standard.
+ </p></div><div class="refsect1" id="SQL-DROPTYPE-SEE-ALSO"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertype.html" title="ALTER TYPE"><span class="refentrytitle">ALTER TYPE</span></a>, <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptrigger.html" title="DROP TRIGGER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropuser.html" title="DROP USER">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TRIGGER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP USER</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropuser.html b/doc/src/sgml/html/sql-dropuser.html
new file mode 100644
index 0000000..90bc7b4
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropuser.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP USER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-droptype.html" title="DROP TYPE" /><link rel="next" href="sql-dropusermapping.html" title="DROP USER MAPPING" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP USER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-droptype.html" title="DROP TYPE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropusermapping.html" title="DROP USER MAPPING">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPUSER"><div class="titlepage"></div><a id="id-1.9.3.143.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP USER</span></h2><p>DROP USER — remove a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP USER [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...]
+</pre></div><div class="refsect1" id="id-1.9.3.143.5"><h2>Description</h2><p>
+ <code class="command">DROP USER</code> is simply an alternate spelling of
+ <a class="link" href="sql-droprole.html" title="DROP ROLE"><code class="command">DROP ROLE</code></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.143.6"><h2>Compatibility</h2><p>
+ The <code class="command">DROP USER</code> statement is a
+ <span class="productname">PostgreSQL</span> extension. The SQL standard
+ leaves the definition of users to the implementation.
+ </p></div><div class="refsect1" id="id-1.9.3.143.7"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-droptype.html" title="DROP TYPE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropusermapping.html" title="DROP USER MAPPING">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP TYPE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP USER MAPPING</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropusermapping.html b/doc/src/sgml/html/sql-dropusermapping.html
new file mode 100644
index 0000000..8641a42
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropusermapping.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP USER MAPPING</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropuser.html" title="DROP USER" /><link rel="next" href="sql-dropview.html" title="DROP VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP USER MAPPING</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropuser.html" title="DROP USER">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-dropview.html" title="DROP VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPUSERMAPPING"><div class="titlepage"></div><a id="id-1.9.3.144.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP USER MAPPING</span></h2><p>DROP USER MAPPING — remove a user mapping for a foreign server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP USER MAPPING [ IF EXISTS ] FOR { <em class="replaceable"><code>user_name</code></em> | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER <em class="replaceable"><code>server_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.144.5"><h2>Description</h2><p>
+ <code class="command">DROP USER MAPPING</code> removes an existing user
+ mapping from foreign server.
+ </p><p>
+ The owner of a foreign server can drop user mappings for that server
+ for any user. Also, a user can drop a user mapping for their own
+ user name if <code class="literal">USAGE</code> privilege on the server has been
+ granted to the user.
+ </p></div><div class="refsect1" id="id-1.9.3.144.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the user mapping does not exist. A
+ notice is issued in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>user_name</code></em></span></dt><dd><p>
+ User name of the mapping. <code class="literal">CURRENT_ROLE</code>, <code class="literal">CURRENT_USER</code>,
+ and <code class="literal">USER</code> match the name of the current
+ user. <code class="literal">PUBLIC</code> is used to match all present and
+ future user names in the system.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_name</code></em></span></dt><dd><p>
+ Server name of the user mapping.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.144.7"><h2>Examples</h2><p>
+ Drop a user mapping <code class="literal">bob</code>, server <code class="literal">foo</code> if it exists:
+</p><pre class="programlisting">
+DROP USER MAPPING IF EXISTS FOR bob SERVER foo;
+</pre></div><div class="refsect1" id="id-1.9.3.144.8"><h2>Compatibility</h2><p>
+ <code class="command">DROP USER MAPPING</code> conforms to ISO/IEC 9075-9
+ (SQL/MED). The <code class="literal">IF EXISTS</code> clause is
+ a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.144.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createusermapping.html" title="CREATE USER MAPPING"><span class="refentrytitle">CREATE USER MAPPING</span></a>, <a class="xref" href="sql-alterusermapping.html" title="ALTER USER MAPPING"><span class="refentrytitle">ALTER USER MAPPING</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropuser.html" title="DROP USER">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-dropview.html" title="DROP VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP USER </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> DROP VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-dropview.html b/doc/src/sgml/html/sql-dropview.html
new file mode 100644
index 0000000..832c447
--- /dev/null
+++ b/doc/src/sgml/html/sql-dropview.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>DROP VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropusermapping.html" title="DROP USER MAPPING" /><link rel="next" href="sql-end.html" title="END" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">DROP VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropusermapping.html" title="DROP USER MAPPING">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-end.html" title="END">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-DROPVIEW"><div class="titlepage"></div><a id="id-1.9.3.145.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">DROP VIEW</span></h2><p>DROP VIEW — remove a view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+DROP VIEW [ IF EXISTS ] <em class="replaceable"><code>name</code></em> [, ...] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.145.5"><h2>Description</h2><p>
+ <code class="command">DROP VIEW</code> drops an existing view. To execute
+ this command you must be the owner of the view.
+ </p></div><div class="refsect1" id="id-1.9.3.145.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">IF EXISTS</code></span></dt><dd><p>
+ Do not throw an error if the view does not exist. A notice is issued
+ in this case.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the view to remove.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically drop objects that depend on the view (such as
+ other views),
+ and in turn all objects that depend on those objects
+ (see <a class="xref" href="ddl-depend.html" title="5.14. Dependency Tracking">Section 5.14</a>).
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to drop the view if any objects depend on it. This is
+ the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.145.7"><h2>Examples</h2><p>
+ This command will remove the view called <code class="literal">kinds</code>:
+</p><pre class="programlisting">
+DROP VIEW kinds;
+</pre></div><div class="refsect1" id="id-1.9.3.145.8"><h2>Compatibility</h2><p>
+ This command conforms to the SQL standard, except that the standard only
+ allows one view to be dropped per command, and apart from the
+ <code class="literal">IF EXISTS</code> option, which is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.145.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterview.html" title="ALTER VIEW"><span class="refentrytitle">ALTER VIEW</span></a>, <a class="xref" href="sql-createview.html" title="CREATE VIEW"><span class="refentrytitle">CREATE VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropusermapping.html" title="DROP USER MAPPING">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-end.html" title="END">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP USER MAPPING </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> END</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-end.html b/doc/src/sgml/html/sql-end.html
new file mode 100644
index 0000000..10f9102
--- /dev/null
+++ b/doc/src/sgml/html/sql-end.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>END</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-dropview.html" title="DROP VIEW" /><link rel="next" href="sql-execute.html" title="EXECUTE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">END</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-dropview.html" title="DROP VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-execute.html" title="EXECUTE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-END"><div class="titlepage"></div><a id="id-1.9.3.146.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">END</span></h2><p>END — commit the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</pre></div><div class="refsect1" id="id-1.9.3.146.5"><h2>Description</h2><p>
+ <code class="command">END</code> commits the current transaction. All changes
+ made by the transaction become visible to others and are guaranteed
+ to be durable if a crash occurs. This command is a
+ <span class="productname">PostgreSQL</span> extension
+ that is equivalent to <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.146.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">WORK</code><br /></span><span class="term"><code class="literal">TRANSACTION</code></span></dt><dd><p>
+ Optional key words. They have no effect.
+ </p></dd><dt><span class="term"><code class="literal">AND CHAIN</code></span></dt><dd><p>
+ If <code class="literal">AND CHAIN</code> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.146.7"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-rollback.html" title="ROLLBACK"><code class="command">ROLLBACK</code></a> to
+ abort a transaction.
+ </p><p>
+ Issuing <code class="command">END</code> when not inside a transaction does
+ no harm, but it will provoke a warning message.
+ </p></div><div class="refsect1" id="id-1.9.3.146.8"><h2>Examples</h2><p>
+ To commit the current transaction and make all changes permanent:
+</p><pre class="programlisting">
+END;
+</pre></div><div class="refsect1" id="id-1.9.3.146.9"><h2>Compatibility</h2><p>
+ <code class="command">END</code> is a <span class="productname">PostgreSQL</span>
+ extension that provides functionality equivalent to <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a>, which is
+ specified in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.146.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-dropview.html" title="DROP VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-execute.html" title="EXECUTE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">DROP VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> EXECUTE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-execute.html b/doc/src/sgml/html/sql-execute.html
new file mode 100644
index 0000000..220e182
--- /dev/null
+++ b/doc/src/sgml/html/sql-execute.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>EXECUTE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-end.html" title="END" /><link rel="next" href="sql-explain.html" title="EXPLAIN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">EXECUTE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-end.html" title="END">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-explain.html" title="EXPLAIN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-EXECUTE"><div class="titlepage"></div><a id="id-1.9.3.147.1" class="indexterm"></a><a id="id-1.9.3.147.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">EXECUTE</span></h2><p>EXECUTE — execute a prepared statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+EXECUTE <em class="replaceable"><code>name</code></em> [ ( <em class="replaceable"><code>parameter</code></em> [, ...] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.147.6"><h2>Description</h2><p>
+ <code class="command">EXECUTE</code> is used to execute a previously prepared
+ statement. Since prepared statements only exist for the duration of a
+ session, the prepared statement must have been created by a
+ <code class="command">PREPARE</code> statement executed earlier in the
+ current session.
+ </p><p>
+ If the <code class="command">PREPARE</code> statement that created the statement
+ specified some parameters, a compatible set of parameters must be
+ passed to the <code class="command">EXECUTE</code> statement, or else an
+ error is raised. Note that (unlike functions) prepared statements are
+ not overloaded based on the type or number of their parameters; the
+ name of a prepared statement must be unique within a database session.
+ </p><p>
+ For more information on the creation and usage of prepared statements,
+ see <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.147.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the prepared statement to execute.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>parameter</code></em></span></dt><dd><p>
+ The actual value of a parameter to the prepared statement. This
+ must be an expression yielding a value that is compatible with
+ the data type of this parameter, as was determined when the
+ prepared statement was created.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.147.8"><h2>Outputs</h2><p>
+ The command tag returned by <code class="command">EXECUTE</code>
+ is that of the prepared statement, and not <code class="literal">EXECUTE</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.147.9"><h2>Examples</h2><p>
+ Examples are given in <a class="xref" href="sql-prepare.html#SQL-PREPARE-EXAMPLES" title="Examples">Examples</a>
+ in the <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a> documentation.
+ </p></div><div class="refsect1" id="id-1.9.3.147.10"><h2>Compatibility</h2><p>
+ The SQL standard includes an <code class="command">EXECUTE</code> statement,
+ but it is only for use in embedded SQL. This version of the
+ <code class="command">EXECUTE</code> statement also uses a somewhat different
+ syntax.
+ </p></div><div class="refsect1" id="id-1.9.3.147.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-deallocate.html" title="DEALLOCATE"><span class="refentrytitle">DEALLOCATE</span></a>, <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-end.html" title="END">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-explain.html" title="EXPLAIN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">END </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> EXPLAIN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-explain.html b/doc/src/sgml/html/sql-explain.html
new file mode 100644
index 0000000..e9033f6
--- /dev/null
+++ b/doc/src/sgml/html/sql-explain.html
@@ -0,0 +1,306 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>EXPLAIN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-execute.html" title="EXECUTE" /><link rel="next" href="sql-fetch.html" title="FETCH" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">EXPLAIN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-execute.html" title="EXECUTE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-fetch.html" title="FETCH">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-EXPLAIN"><div class="titlepage"></div><a id="id-1.9.3.148.1" class="indexterm"></a><a id="id-1.9.3.148.2" class="indexterm"></a><a id="id-1.9.3.148.3" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">EXPLAIN</span></h2><p>EXPLAIN — show the execution plan of a statement</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+EXPLAIN [ ( <em class="replaceable"><code>option</code></em> [, ...] ) ] <em class="replaceable"><code>statement</code></em>
+EXPLAIN [ ANALYZE ] [ VERBOSE ] <em class="replaceable"><code>statement</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be one of:</span>
+
+ ANALYZE [ <em class="replaceable"><code>boolean</code></em> ]
+ VERBOSE [ <em class="replaceable"><code>boolean</code></em> ]
+ COSTS [ <em class="replaceable"><code>boolean</code></em> ]
+ SETTINGS [ <em class="replaceable"><code>boolean</code></em> ]
+ BUFFERS [ <em class="replaceable"><code>boolean</code></em> ]
+ WAL [ <em class="replaceable"><code>boolean</code></em> ]
+ TIMING [ <em class="replaceable"><code>boolean</code></em> ]
+ SUMMARY [ <em class="replaceable"><code>boolean</code></em> ]
+ FORMAT { TEXT | XML | JSON | YAML }
+</pre></div><div class="refsect1" id="id-1.9.3.148.7"><h2>Description</h2><p>
+ This command displays the execution plan that the
+ <span class="productname">PostgreSQL</span> planner generates for the
+ supplied statement. The execution plan shows how the table(s)
+ referenced by the statement will be scanned — by plain sequential scan,
+ index scan, etc. — and if multiple tables are referenced, what join
+ algorithms will be used to bring together the required rows from
+ each input table.
+ </p><p>
+ The most critical part of the display is the estimated statement execution
+ cost, which is the planner's guess at how long it will take to run the
+ statement (measured in cost units that are arbitrary, but conventionally
+ mean disk page fetches). Actually two numbers
+ are shown: the start-up cost before the first row can be returned, and
+ the total cost to return all the rows. For most queries the total cost
+ is what matters, but in contexts such as a subquery in <code class="literal">EXISTS</code>, the planner
+ will choose the smallest start-up cost instead of the smallest total cost
+ (since the executor will stop after getting one row, anyway).
+ Also, if you limit the number of rows to return with a <code class="literal">LIMIT</code> clause,
+ the planner makes an appropriate interpolation between the endpoint
+ costs to estimate which plan is really the cheapest.
+ </p><p>
+ The <code class="literal">ANALYZE</code> option causes the statement to be actually
+ executed, not only planned. Then actual run time statistics are added to
+ the display, including the total elapsed time expended within each plan
+ node (in milliseconds) and the total number of rows it actually returned.
+ This is useful for seeing whether the planner's estimates
+ are close to reality.
+ </p><div class="important"><h3 class="title">Important</h3><p>
+ Keep in mind that the statement is actually executed when
+ the <code class="literal">ANALYZE</code> option is used. Although
+ <code class="command">EXPLAIN</code> will discard any output that a
+ <code class="command">SELECT</code> would return, other side effects of the
+ statement will happen as usual. If you wish to use
+ <code class="command">EXPLAIN ANALYZE</code> on an
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">MERGE</code>,
+ <code class="command">CREATE TABLE AS</code>,
+ or <code class="command">EXECUTE</code> statement
+ without letting the command affect your data, use this approach:
+</p><pre class="programlisting">
+BEGIN;
+EXPLAIN ANALYZE ...;
+ROLLBACK;
+</pre><p>
+ </p></div><p>
+ Only the <code class="literal">ANALYZE</code> and <code class="literal">VERBOSE</code> options
+ can be specified, and only in that order, without surrounding the option
+ list in parentheses. Prior to <span class="productname">PostgreSQL</span> 9.0,
+ the unparenthesized syntax was the only one supported. It is expected that
+ all new options will be supported only in the parenthesized syntax.
+ </p></div><div class="refsect1" id="id-1.9.3.148.8"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">ANALYZE</code></span></dt><dd><p>
+ Carry out the command and show actual run times and other statistics.
+ This parameter defaults to <code class="literal">FALSE</code>.
+ </p></dd><dt><span class="term"><code class="literal">VERBOSE</code></span></dt><dd><p>
+ Display additional information regarding the plan. Specifically, include
+ the output column list for each node in the plan tree, schema-qualify
+ table and function names, always label variables in expressions with
+ their range table alias, and always print the name of each trigger for
+ which statistics are displayed. The query identifier will also be
+ displayed if one has been computed, see <a class="xref" href="runtime-config-statistics.html#GUC-COMPUTE-QUERY-ID">compute_query_id</a> for more details. This parameter
+ defaults to <code class="literal">FALSE</code>.
+ </p></dd><dt><span class="term"><code class="literal">COSTS</code></span></dt><dd><p>
+ Include information on the estimated startup and total cost of each
+ plan node, as well as the estimated number of rows and the estimated
+ width of each row.
+ This parameter defaults to <code class="literal">TRUE</code>.
+ </p></dd><dt><span class="term"><code class="literal">SETTINGS</code></span></dt><dd><p>
+ Include information on configuration parameters. Specifically, include
+ options affecting query planning with value different from the built-in
+ default value. This parameter defaults to <code class="literal">FALSE</code>.
+ </p></dd><dt><span class="term"><code class="literal">BUFFERS</code></span></dt><dd><p>
+ Include information on buffer usage. Specifically, include the number of
+ shared blocks hit, read, dirtied, and written, the number of local blocks
+ hit, read, dirtied, and written, the number of temp blocks read and
+ written, and the time spent reading and writing data file blocks and
+ temporary file blocks (in milliseconds) if
+ <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-IO-TIMING">track_io_timing</a> is enabled. A
+ <span class="emphasis"><em>hit</em></span> means that a read was avoided because the block
+ was found already in cache when needed.
+ Shared blocks contain data from regular tables and indexes;
+ local blocks contain data from temporary tables and indexes;
+ while temporary blocks contain short-term working data used in sorts,
+ hashes, Materialize plan nodes, and similar cases.
+ The number of blocks <span class="emphasis"><em>dirtied</em></span> indicates the number of
+ previously unmodified blocks that were changed by this query; while the
+ number of blocks <span class="emphasis"><em>written</em></span> indicates the number of
+ previously-dirtied blocks evicted from cache by this backend during
+ query processing.
+ The number of blocks shown for an
+ upper-level node includes those used by all its child nodes. In text
+ format, only non-zero values are printed. It defaults to
+ <code class="literal">FALSE</code>.
+ </p></dd><dt><span class="term"><code class="literal">WAL</code></span></dt><dd><p>
+ Include information on WAL record generation. Specifically, include the
+ number of records, number of full page images (fpi) and the amount of WAL
+ generated in bytes. In text format, only non-zero values are printed.
+ This parameter may only be used when <code class="literal">ANALYZE</code> is also
+ enabled. It defaults to <code class="literal">FALSE</code>.
+ </p></dd><dt><span class="term"><code class="literal">TIMING</code></span></dt><dd><p>
+ Include actual startup time and time spent in each node in the output.
+ The overhead of repeatedly reading the system clock can slow down the
+ query significantly on some systems, so it may be useful to set this
+ parameter to <code class="literal">FALSE</code> when only actual row counts, and
+ not exact times, are needed. Run time of the entire statement is
+ always measured, even when node-level timing is turned off with this
+ option.
+ This parameter may only be used when <code class="literal">ANALYZE</code> is also
+ enabled. It defaults to <code class="literal">TRUE</code>.
+ </p></dd><dt><span class="term"><code class="literal">SUMMARY</code></span></dt><dd><p>
+ Include summary information (e.g., totaled timing information) after the
+ query plan. Summary information is included by default when
+ <code class="literal">ANALYZE</code> is used but otherwise is not included by
+ default, but can be enabled using this option. Planning time in
+ <code class="command">EXPLAIN EXECUTE</code> includes the time required to fetch
+ the plan from the cache and the time required for re-planning, if
+ necessary.
+ </p></dd><dt><span class="term"><code class="literal">FORMAT</code></span></dt><dd><p>
+ Specify the output format, which can be TEXT, XML, JSON, or YAML.
+ Non-text output contains the same information as the text output
+ format, but is easier for programs to parse. This parameter defaults to
+ <code class="literal">TEXT</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>boolean</code></em></span></dt><dd><p>
+ Specifies whether the selected option should be turned on or off.
+ You can write <code class="literal">TRUE</code>, <code class="literal">ON</code>, or
+ <code class="literal">1</code> to enable the option, and <code class="literal">FALSE</code>,
+ <code class="literal">OFF</code>, or <code class="literal">0</code> to disable it. The
+ <em class="replaceable"><code>boolean</code></em> value can also
+ be omitted, in which case <code class="literal">TRUE</code> is assumed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>statement</code></em></span></dt><dd><p>
+ Any <code class="command">SELECT</code>, <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">MERGE</code>,
+ <code class="command">VALUES</code>, <code class="command">EXECUTE</code>,
+ <code class="command">DECLARE</code>, <code class="command">CREATE TABLE AS</code>, or
+ <code class="command">CREATE MATERIALIZED VIEW AS</code> statement, whose execution
+ plan you wish to see.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.148.9"><h2>Outputs</h2><p>
+ The command's result is a textual description of the plan selected
+ for the <em class="replaceable"><code>statement</code></em>,
+ optionally annotated with execution statistics.
+ <a class="xref" href="using-explain.html" title="14.1. Using EXPLAIN">Section 14.1</a> describes the information provided.
+ </p></div><div class="refsect1" id="id-1.9.3.148.10"><h2>Notes</h2><p>
+ In order to allow the <span class="productname">PostgreSQL</span> query
+ planner to make reasonably informed decisions when optimizing
+ queries, the <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a>
+ data should be up-to-date for all tables used in the query. Normally
+ the <a class="link" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">autovacuum daemon</a> will take care
+ of that automatically. But if a table has recently had substantial
+ changes in its contents, you might need to do a manual
+ <a class="link" href="sql-analyze.html" title="ANALYZE"><code class="command">ANALYZE</code></a> rather than wait for autovacuum to catch up
+ with the changes.
+ </p><p>
+ In order to measure the run-time cost of each node in the execution
+ plan, the current implementation of <code class="command">EXPLAIN
+ ANALYZE</code> adds profiling overhead to query execution.
+ As a result, running <code class="command">EXPLAIN ANALYZE</code>
+ on a query can sometimes take significantly longer than executing
+ the query normally. The amount of overhead depends on the nature of
+ the query, as well as the platform being used. The worst case occurs
+ for plan nodes that in themselves require very little time per
+ execution, and on machines that have relatively slow operating
+ system calls for obtaining the time of day.
+ </p></div><div class="refsect1" id="id-1.9.3.148.11"><h2>Examples</h2><p>
+ To show the plan for a simple query on a table with a single
+ <code class="type">integer</code> column and 10000 rows:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM foo;
+
+ QUERY PLAN
+---------------------------------------------------------
+ Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4)
+(1 row)
+</pre><p>
+ </p><p>
+ Here is the same query, with JSON output formatting:
+</p><pre class="programlisting">
+EXPLAIN (FORMAT JSON) SELECT * FROM foo;
+ QUERY PLAN
+--------------------------------
+ [ +
+ { +
+ "Plan": { +
+ "Node Type": "Seq Scan",+
+ "Relation Name": "foo", +
+ "Alias": "foo", +
+ "Startup Cost": 0.00, +
+ "Total Cost": 155.00, +
+ "Plan Rows": 10000, +
+ "Plan Width": 4 +
+ } +
+ } +
+ ]
+(1 row)
+</pre><p>
+ </p><p>
+ If there is an index and we use a query with an indexable
+ <code class="literal">WHERE</code> condition, <code class="command">EXPLAIN</code>
+ might show a different plan:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT * FROM foo WHERE i = 4;
+
+ QUERY PLAN
+--------------------------------------------------------------
+ Index Scan using fi on foo (cost=0.00..5.98 rows=1 width=4)
+ Index Cond: (i = 4)
+(2 rows)
+</pre><p>
+ </p><p>
+ Here is the same query, but in YAML format:
+</p><pre class="programlisting">
+EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i='4';
+ QUERY PLAN
+-------------------------------
+ - Plan: +
+ Node Type: "Index Scan" +
+ Scan Direction: "Forward"+
+ Index Name: "fi" +
+ Relation Name: "foo" +
+ Alias: "foo" +
+ Startup Cost: 0.00 +
+ Total Cost: 5.98 +
+ Plan Rows: 1 +
+ Plan Width: 4 +
+ Index Cond: "(i = 4)"
+(1 row)
+</pre><p>
+
+ XML format is left as an exercise for the reader.
+ </p><p>
+ Here is the same plan with cost estimates suppressed:
+
+</p><pre class="programlisting">
+EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4;
+
+ QUERY PLAN
+----------------------------
+ Index Scan using fi on foo
+ Index Cond: (i = 4)
+(2 rows)
+</pre><p>
+ </p><p>
+ Here is an example of a query plan for a query using an aggregate
+ function:
+
+</p><pre class="programlisting">
+EXPLAIN SELECT sum(i) FROM foo WHERE i &lt; 10;
+
+ QUERY PLAN
+-------------------------------------------------------------------​--
+ Aggregate (cost=23.93..23.93 rows=1 width=4)
+ -&gt; Index Scan using fi on foo (cost=0.00..23.92 rows=6 width=4)
+ Index Cond: (i &lt; 10)
+(3 rows)
+</pre><p>
+ </p><p>
+ Here is an example of using <code class="command">EXPLAIN EXECUTE</code> to
+ display the execution plan for a prepared query:
+
+</p><pre class="programlisting">
+PREPARE query(int, int) AS SELECT sum(bar) FROM test
+ WHERE id &gt; $1 AND id &lt; $2
+ GROUP BY foo;
+
+EXPLAIN ANALYZE EXECUTE query(100, 200);
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------------------------------------
+ HashAggregate (cost=9.54..9.54 rows=1 width=8) (actual time=0.156..0.161 rows=11 loops=1)
+ Group Key: foo
+ -&gt; Index Scan using test_pkey on test (cost=0.29..9.29 rows=50 width=8) (actual time=0.039..0.091 rows=99 loops=1)
+ Index Cond: ((id &gt; $1) AND (id &lt; $2))
+ Planning time: 0.197 ms
+ Execution time: 0.225 ms
+(6 rows)
+</pre><p>
+ </p><p>
+ Of course, the specific numbers shown here depend on the actual
+ contents of the tables involved. Also note that the numbers, and
+ even the selected query strategy, might vary between
+ <span class="productname">PostgreSQL</span> releases due to planner
+ improvements. In addition, the <code class="command">ANALYZE</code> command
+ uses random sampling to estimate data statistics; therefore, it is
+ possible for cost estimates to change after a fresh run of
+ <code class="command">ANALYZE</code>, even if the actual distribution of data
+ in the table has not changed.
+ </p></div><div class="refsect1" id="id-1.9.3.148.12"><h2>Compatibility</h2><p>
+ There is no <code class="command">EXPLAIN</code> statement defined in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.148.13"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-execute.html" title="EXECUTE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-fetch.html" title="FETCH">Next</a></td></tr><tr><td width="40%" align="left" valign="top">EXECUTE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> FETCH</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-expressions.html b/doc/src/sgml/html/sql-expressions.html
new file mode 100644
index 0000000..1b4d32c
--- /dev/null
+++ b/doc/src/sgml/html/sql-expressions.html
@@ -0,0 +1,995 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>4.2. Value Expressions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-syntax-lexical.html" title="4.1. Lexical Structure" /><link rel="next" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">4.2. Value Expressions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-syntax-lexical.html" title="4.1. Lexical Structure">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Up</a></td><th width="60%" align="center">Chapter 4. SQL Syntax</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="SQL-EXPRESSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">4.2. Value Expressions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-COLUMN-REFS">4.2.1. Column References</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-PARAMETERS-POSITIONAL">4.2.2. Positional Parameters</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-SUBSCRIPTS">4.2.3. Subscripts</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#FIELD-SELECTION">4.2.4. Field Selection</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS">4.2.5. Operator Invocations</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-FUNCTION-CALLS">4.2.6. Function Calls</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SYNTAX-AGGREGATES">4.2.7. Aggregate Expressions</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS">4.2.8. Window Function Calls</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS">4.2.9. Type Casts</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS">4.2.10. Collation Expressions</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES">4.2.11. Scalar Subqueries</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS">4.2.12. Array Constructors</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">4.2.13. Row Constructors</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SYNTAX-EXPRESS-EVAL">4.2.14. Expression Evaluation Rules</a></span></dt></dl></div><a id="id-1.5.3.6.2" class="indexterm"></a><a id="id-1.5.3.6.3" class="indexterm"></a><a id="id-1.5.3.6.4" class="indexterm"></a><p>
+ Value expressions are used in a variety of contexts, such
+ as in the target list of the <code class="command">SELECT</code> command, as
+ new column values in <code class="command">INSERT</code> or
+ <code class="command">UPDATE</code>, or in search conditions in a number of
+ commands. The result of a value expression is sometimes called a
+ <em class="firstterm">scalar</em>, to distinguish it from the result of
+ a table expression (which is a table). Value expressions are
+ therefore also called <em class="firstterm">scalar expressions</em> (or
+ even simply <em class="firstterm">expressions</em>). The expression
+ syntax allows the calculation of values from primitive parts using
+ arithmetic, logical, set, and other operations.
+ </p><p>
+ A value expression is one of the following:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A constant or literal value
+ </p></li><li class="listitem"><p>
+ A column reference
+ </p></li><li class="listitem"><p>
+ A positional parameter reference, in the body of a function definition
+ or prepared statement
+ </p></li><li class="listitem"><p>
+ A subscripted expression
+ </p></li><li class="listitem"><p>
+ A field selection expression
+ </p></li><li class="listitem"><p>
+ An operator invocation
+ </p></li><li class="listitem"><p>
+ A function call
+ </p></li><li class="listitem"><p>
+ An aggregate expression
+ </p></li><li class="listitem"><p>
+ A window function call
+ </p></li><li class="listitem"><p>
+ A type cast
+ </p></li><li class="listitem"><p>
+ A collation expression
+ </p></li><li class="listitem"><p>
+ A scalar subquery
+ </p></li><li class="listitem"><p>
+ An array constructor
+ </p></li><li class="listitem"><p>
+ A row constructor
+ </p></li><li class="listitem"><p>
+ Another value expression in parentheses (used to group
+ subexpressions and override
+ precedence<a id="id-1.5.3.6.6.1.15.1.1" class="indexterm"></a>)
+ </p></li></ul></div><p>
+ </p><p>
+ In addition to this list, there are a number of constructs that can
+ be classified as an expression but do not follow any general syntax
+ rules. These generally have the semantics of a function or
+ operator and are explained in the appropriate location in <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a>. An example is the <code class="literal">IS NULL</code>
+ clause.
+ </p><p>
+ We have already discussed constants in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS" title="4.1.2. Constants">Section 4.1.2</a>. The following sections discuss
+ the remaining options.
+ </p><div class="sect2" id="SQL-EXPRESSIONS-COLUMN-REFS"><div class="titlepage"><div><div><h3 class="title">4.2.1. Column References</h3></div></div></div><a id="id-1.5.3.6.9.2" class="indexterm"></a><p>
+ A column can be referenced in the form:
+</p><pre class="synopsis">
+<em class="replaceable"><code>correlation</code></em>.<em class="replaceable"><code>columnname</code></em>
+</pre><p>
+ </p><p>
+ <em class="replaceable"><code>correlation</code></em> is the name of a
+ table (possibly qualified with a schema name), or an alias for a table
+ defined by means of a <code class="literal">FROM</code> clause.
+ The correlation name and separating dot can be omitted if the column name
+ is unique across all the tables being used in the current query. (See also <a class="xref" href="queries.html" title="Chapter 7. Queries">Chapter 7</a>.)
+ </p></div><div class="sect2" id="SQL-EXPRESSIONS-PARAMETERS-POSITIONAL"><div class="titlepage"><div><div><h3 class="title">4.2.2. Positional Parameters</h3></div></div></div><a id="id-1.5.3.6.10.2" class="indexterm"></a><a id="id-1.5.3.6.10.3" class="indexterm"></a><p>
+ A positional parameter reference is used to indicate a value
+ that is supplied externally to an SQL statement. Parameters are
+ used in SQL function definitions and in prepared queries. Some
+ client libraries also support specifying data values separately
+ from the SQL command string, in which case parameters are used to
+ refer to the out-of-line data values.
+ The form of a parameter reference is:
+</p><pre class="synopsis">
+$<em class="replaceable"><code>number</code></em>
+</pre><p>
+ </p><p>
+ For example, consider the definition of a function,
+ <code class="function">dept</code>, as:
+
+</p><pre class="programlisting">
+CREATE FUNCTION dept(text) RETURNS dept
+ AS $$ SELECT * FROM dept WHERE name = $1 $$
+ LANGUAGE SQL;
+</pre><p>
+
+ Here the <code class="literal">$1</code> references the value of the first
+ function argument whenever the function is invoked.
+ </p></div><div class="sect2" id="SQL-EXPRESSIONS-SUBSCRIPTS"><div class="titlepage"><div><div><h3 class="title">4.2.3. Subscripts</h3></div></div></div><a id="id-1.5.3.6.11.2" class="indexterm"></a><p>
+ If an expression yields a value of an array type, then a specific
+ element of the array value can be extracted by writing
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em>[<em class="replaceable"><code>subscript</code></em>]
+</pre><p>
+ or multiple adjacent elements (an <span class="quote">“<span class="quote">array slice</span>”</span>) can be extracted
+ by writing
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em>[<em class="replaceable"><code>lower_subscript</code></em>:<em class="replaceable"><code>upper_subscript</code></em>]
+</pre><p>
+ (Here, the brackets <code class="literal">[ ]</code> are meant to appear literally.)
+ Each <em class="replaceable"><code>subscript</code></em> is itself an expression,
+ which will be rounded to the nearest integer value.
+ </p><p>
+ In general the array <em class="replaceable"><code>expression</code></em> must be
+ parenthesized, but the parentheses can be omitted when the expression
+ to be subscripted is just a column reference or positional parameter.
+ Also, multiple subscripts can be concatenated when the original array
+ is multidimensional.
+ For example:
+
+</p><pre class="programlisting">
+mytable.arraycolumn[4]
+mytable.two_d_column[17][34]
+$1[10:42]
+(arrayfunction(a,b))[42]
+</pre><p>
+
+ The parentheses in the last example are required.
+ See <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a> for more about arrays.
+ </p></div><div class="sect2" id="FIELD-SELECTION"><div class="titlepage"><div><div><h3 class="title">4.2.4. Field Selection</h3></div></div></div><a id="id-1.5.3.6.12.2" class="indexterm"></a><p>
+ If an expression yields a value of a composite type (row type), then a
+ specific field of the row can be extracted by writing
+</p><pre class="synopsis">
+<em class="replaceable"><code>expression</code></em>.<em class="replaceable"><code>fieldname</code></em>
+</pre><p>
+ </p><p>
+ In general the row <em class="replaceable"><code>expression</code></em> must be
+ parenthesized, but the parentheses can be omitted when the expression
+ to be selected from is just a table reference or positional parameter.
+ For example:
+
+</p><pre class="programlisting">
+mytable.mycolumn
+$1.somecolumn
+(rowfunction(a,b)).col3
+</pre><p>
+
+ (Thus, a qualified column reference is actually just a special case
+ of the field selection syntax.) An important special case is
+ extracting a field from a table column that is of a composite type:
+
+</p><pre class="programlisting">
+(compositecol).somefield
+(mytable.compositecol).somefield
+</pre><p>
+
+ The parentheses are required here to show that
+ <code class="structfield">compositecol</code> is a column name not a table name,
+ or that <code class="structname">mytable</code> is a table name not a schema name
+ in the second case.
+ </p><p>
+ You can ask for all fields of a composite value by
+ writing <code class="literal">.*</code>:
+</p><pre class="programlisting">
+(compositecol).*
+</pre><p>
+ This notation behaves differently depending on context;
+ see <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a> for details.
+ </p></div><div class="sect2" id="SQL-EXPRESSIONS-OPERATOR-CALLS"><div class="titlepage"><div><div><h3 class="title">4.2.5. Operator Invocations</h3></div></div></div><a id="id-1.5.3.6.13.2" class="indexterm"></a><p>
+ There are two possible syntaxes for an operator invocation:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><em class="replaceable"><code>expression</code></em> <em class="replaceable"><code>operator</code></em> <em class="replaceable"><code>expression</code></em> (binary infix operator)</td></tr><tr><td><em class="replaceable"><code>operator</code></em> <em class="replaceable"><code>expression</code></em> (unary prefix operator)</td></tr></table><p>
+ where the <em class="replaceable"><code>operator</code></em> token follows the syntax
+ rules of <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS" title="4.1.3. Operators">Section 4.1.3</a>, or is one of the
+ key words <code class="token">AND</code>, <code class="token">OR</code>, and
+ <code class="token">NOT</code>, or is a qualified operator name in the form:
+</p><pre class="synopsis">
+<code class="literal">OPERATOR(</code><em class="replaceable"><code>schema</code></em><code class="literal">.</code><em class="replaceable"><code>operatorname</code></em><code class="literal">)</code>
+</pre><p>
+ Which particular operators exist and whether
+ they are unary or binary depends on what operators have been
+ defined by the system or the user. <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a>
+ describes the built-in operators.
+ </p></div><div class="sect2" id="SQL-EXPRESSIONS-FUNCTION-CALLS"><div class="titlepage"><div><div><h3 class="title">4.2.6. Function Calls</h3></div></div></div><a id="id-1.5.3.6.14.2" class="indexterm"></a><p>
+ The syntax for a function call is the name of a function
+ (possibly qualified with a schema name), followed by its argument list
+ enclosed in parentheses:
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>function_name</code></em> ([<span class="optional"><em class="replaceable"><code>expression</code></em> [<span class="optional">, <em class="replaceable"><code>expression</code></em> ... </span>]</span>] )
+</pre><p>
+ </p><p>
+ For example, the following computes the square root of 2:
+</p><pre class="programlisting">
+sqrt(2)
+</pre><p>
+ </p><p>
+ The list of built-in functions is in <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a>.
+ Other functions can be added by the user.
+ </p><p>
+ When issuing queries in a database where some users mistrust other users,
+ observe security precautions from <a class="xref" href="typeconv-func.html" title="10.3. Functions">Section 10.3</a> when
+ writing function calls.
+ </p><p>
+ The arguments can optionally have names attached.
+ See <a class="xref" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Section 4.3</a> for details.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ A function that takes a single argument of composite type can
+ optionally be called using field-selection syntax, and conversely
+ field selection can be written in functional style. That is, the
+ notations <code class="literal">col(table)</code> and <code class="literal">table.col</code> are
+ interchangeable. This behavior is not SQL-standard but is provided
+ in <span class="productname">PostgreSQL</span> because it allows use of functions to
+ emulate <span class="quote">“<span class="quote">computed fields</span>”</span>. For more information see
+ <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a>.
+ </p></div></div><div class="sect2" id="SYNTAX-AGGREGATES"><div class="titlepage"><div><div><h3 class="title">4.2.7. Aggregate Expressions</h3></div></div></div><a id="id-1.5.3.6.15.2" class="indexterm"></a><a id="id-1.5.3.6.15.3" class="indexterm"></a><a id="id-1.5.3.6.15.4" class="indexterm"></a><a id="id-1.5.3.6.15.5" class="indexterm"></a><p>
+ An <em class="firstterm">aggregate expression</em> represents the
+ application of an aggregate function across the rows selected by a
+ query. An aggregate function reduces multiple inputs to a single
+ output value, such as the sum or average of the inputs. The
+ syntax of an aggregate expression is one of the following:
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>aggregate_name</code></em> (<em class="replaceable"><code>expression</code></em> [ , ... ] [ <em class="replaceable"><code>order_by_clause</code></em> ] ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ]
+<em class="replaceable"><code>aggregate_name</code></em> (ALL <em class="replaceable"><code>expression</code></em> [ , ... ] [ <em class="replaceable"><code>order_by_clause</code></em> ] ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ]
+<em class="replaceable"><code>aggregate_name</code></em> (DISTINCT <em class="replaceable"><code>expression</code></em> [ , ... ] [ <em class="replaceable"><code>order_by_clause</code></em> ] ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ]
+<em class="replaceable"><code>aggregate_name</code></em> ( * ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ]
+<em class="replaceable"><code>aggregate_name</code></em> ( [ <em class="replaceable"><code>expression</code></em> [ , ... ] ] ) WITHIN GROUP ( <em class="replaceable"><code>order_by_clause</code></em> ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ]
+</pre><p>
+
+ where <em class="replaceable"><code>aggregate_name</code></em> is a previously
+ defined aggregate (possibly qualified with a schema name) and
+ <em class="replaceable"><code>expression</code></em> is
+ any value expression that does not itself contain an aggregate
+ expression or a window function call. The optional
+ <em class="replaceable"><code>order_by_clause</code></em> and
+ <em class="replaceable"><code>filter_clause</code></em> are described below.
+ </p><p>
+ The first form of aggregate expression invokes the aggregate
+ once for each input row.
+ The second form is the same as the first, since
+ <code class="literal">ALL</code> is the default.
+ The third form invokes the aggregate once for each distinct value
+ of the expression (or distinct set of values, for multiple expressions)
+ found in the input rows.
+ The fourth form invokes the aggregate once for each input row; since no
+ particular input value is specified, it is generally only useful
+ for the <code class="function">count(*)</code> aggregate function.
+ The last form is used with <em class="firstterm">ordered-set</em> aggregate
+ functions, which are described below.
+ </p><p>
+ Most aggregate functions ignore null inputs, so that rows in which
+ one or more of the expression(s) yield null are discarded. This
+ can be assumed to be true, unless otherwise specified, for all
+ built-in aggregates.
+ </p><p>
+ For example, <code class="literal">count(*)</code> yields the total number
+ of input rows; <code class="literal">count(f1)</code> yields the number of
+ input rows in which <code class="literal">f1</code> is non-null, since
+ <code class="function">count</code> ignores nulls; and
+ <code class="literal">count(distinct f1)</code> yields the number of
+ distinct non-null values of <code class="literal">f1</code>.
+ </p><p>
+ Ordinarily, the input rows are fed to the aggregate function in an
+ unspecified order. In many cases this does not matter; for example,
+ <code class="function">min</code> produces the same result no matter what order it
+ receives the inputs in. However, some aggregate functions
+ (such as <code class="function">array_agg</code> and <code class="function">string_agg</code>) produce
+ results that depend on the ordering of the input rows. When using
+ such an aggregate, the optional <em class="replaceable"><code>order_by_clause</code></em> can be
+ used to specify the desired ordering. The <em class="replaceable"><code>order_by_clause</code></em>
+ has the same syntax as for a query-level <code class="literal">ORDER BY</code> clause, as
+ described in <a class="xref" href="queries-order.html" title="7.5. Sorting Rows (ORDER BY)">Section 7.5</a>, except that its expressions
+ are always just expressions and cannot be output-column names or numbers.
+ For example:
+</p><pre class="programlisting">
+SELECT array_agg(a ORDER BY b DESC) FROM table;
+</pre><p>
+ </p><p>
+ When dealing with multiple-argument aggregate functions, note that the
+ <code class="literal">ORDER BY</code> clause goes after all the aggregate arguments.
+ For example, write this:
+</p><pre class="programlisting">
+SELECT string_agg(a, ',' ORDER BY a) FROM table;
+</pre><p>
+ not this:
+</p><pre class="programlisting">
+SELECT string_agg(a ORDER BY a, ',') FROM table; -- incorrect
+</pre><p>
+ The latter is syntactically valid, but it represents a call of a
+ single-argument aggregate function with two <code class="literal">ORDER BY</code> keys
+ (the second one being rather useless since it's a constant).
+ </p><p>
+ If <code class="literal">DISTINCT</code> is specified in addition to an
+ <em class="replaceable"><code>order_by_clause</code></em>, then all the <code class="literal">ORDER BY</code>
+ expressions must match regular arguments of the aggregate; that is,
+ you cannot sort on an expression that is not included in the
+ <code class="literal">DISTINCT</code> list.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The ability to specify both <code class="literal">DISTINCT</code> and <code class="literal">ORDER BY</code>
+ in an aggregate function is a <span class="productname">PostgreSQL</span> extension.
+ </p></div><p>
+ Placing <code class="literal">ORDER BY</code> within the aggregate's regular argument
+ list, as described so far, is used when ordering the input rows for
+ general-purpose and statistical aggregates, for which ordering is
+ optional. There is a
+ subclass of aggregate functions called <em class="firstterm">ordered-set
+ aggregates</em> for which an <em class="replaceable"><code>order_by_clause</code></em>
+ is <span class="emphasis"><em>required</em></span>, usually because the aggregate's computation is
+ only sensible in terms of a specific ordering of its input rows.
+ Typical examples of ordered-set aggregates include rank and percentile
+ calculations. For an ordered-set aggregate,
+ the <em class="replaceable"><code>order_by_clause</code></em> is written
+ inside <code class="literal">WITHIN GROUP (...)</code>, as shown in the final syntax
+ alternative above. The expressions in
+ the <em class="replaceable"><code>order_by_clause</code></em> are evaluated once per
+ input row just like regular aggregate arguments, sorted as per
+ the <em class="replaceable"><code>order_by_clause</code></em>'s requirements, and fed
+ to the aggregate function as input arguments. (This is unlike the case
+ for a non-<code class="literal">WITHIN GROUP</code> <em class="replaceable"><code>order_by_clause</code></em>,
+ which is not treated as argument(s) to the aggregate function.) The
+ argument expressions preceding <code class="literal">WITHIN GROUP</code>, if any, are
+ called <em class="firstterm">direct arguments</em> to distinguish them from
+ the <em class="firstterm">aggregated arguments</em> listed in
+ the <em class="replaceable"><code>order_by_clause</code></em>. Unlike regular aggregate
+ arguments, direct arguments are evaluated only once per aggregate call,
+ not once per input row. This means that they can contain variables only
+ if those variables are grouped by <code class="literal">GROUP BY</code>; this restriction
+ is the same as if the direct arguments were not inside an aggregate
+ expression at all. Direct arguments are typically used for things like
+ percentile fractions, which only make sense as a single value per
+ aggregation calculation. The direct argument list can be empty; in this
+ case, write just <code class="literal">()</code> not <code class="literal">(*)</code>.
+ (<span class="productname">PostgreSQL</span> will actually accept either spelling, but
+ only the first way conforms to the SQL standard.)
+ </p><p>
+ <a id="id-1.5.3.6.15.15.1" class="indexterm"></a>
+ An example of an ordered-set aggregate call is:
+
+</p><pre class="programlisting">
+SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY income) FROM households;
+ percentile_cont
+-----------------
+ 50489
+</pre><p>
+
+ which obtains the 50th percentile, or median, value of
+ the <code class="structfield">income</code> column from table <code class="structname">households</code>.
+ Here, <code class="literal">0.5</code> is a direct argument; it would make no sense
+ for the percentile fraction to be a value varying across rows.
+ </p><p>
+ If <code class="literal">FILTER</code> is specified, then only the input
+ rows for which the <em class="replaceable"><code>filter_clause</code></em>
+ evaluates to true are fed to the aggregate function; other rows
+ are discarded. For example:
+</p><pre class="programlisting">
+SELECT
+ count(*) AS unfiltered,
+ count(*) FILTER (WHERE i &lt; 5) AS filtered
+FROM generate_series(1,10) AS s(i);
+ unfiltered | filtered
+------------+----------
+ 10 | 4
+(1 row)
+</pre><p>
+ </p><p>
+ The predefined aggregate functions are described in <a class="xref" href="functions-aggregate.html" title="9.21. Aggregate Functions">Section 9.21</a>. Other aggregate functions can be added
+ by the user.
+ </p><p>
+ An aggregate expression can only appear in the result list or
+ <code class="literal">HAVING</code> clause of a <code class="command">SELECT</code> command.
+ It is forbidden in other clauses, such as <code class="literal">WHERE</code>,
+ because those clauses are logically evaluated before the results
+ of aggregates are formed.
+ </p><p>
+ When an aggregate expression appears in a subquery (see
+ <a class="xref" href="sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES" title="4.2.11. Scalar Subqueries">Section 4.2.11</a> and
+ <a class="xref" href="functions-subquery.html" title="9.23. Subquery Expressions">Section 9.23</a>), the aggregate is normally
+ evaluated over the rows of the subquery. But an exception occurs
+ if the aggregate's arguments (and <em class="replaceable"><code>filter_clause</code></em>
+ if any) contain only outer-level variables:
+ the aggregate then belongs to the nearest such outer level, and is
+ evaluated over the rows of that query. The aggregate expression
+ as a whole is then an outer reference for the subquery it appears in,
+ and acts as a constant over any one evaluation of that subquery.
+ The restriction about
+ appearing only in the result list or <code class="literal">HAVING</code> clause
+ applies with respect to the query level that the aggregate belongs to.
+ </p></div><div class="sect2" id="SYNTAX-WINDOW-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">4.2.8. Window Function Calls</h3></div></div></div><a id="id-1.5.3.6.16.2" class="indexterm"></a><a id="id-1.5.3.6.16.3" class="indexterm"></a><p>
+ A <em class="firstterm">window function call</em> represents the application
+ of an aggregate-like function over some portion of the rows selected
+ by a query. Unlike non-window aggregate calls, this is not tied
+ to grouping of the selected rows into a single output row — each
+ row remains separate in the query output. However the window function
+ has access to all the rows that would be part of the current row's
+ group according to the grouping specification (<code class="literal">PARTITION BY</code>
+ list) of the window function call.
+ The syntax of a window function call is one of the following:
+
+</p><pre class="synopsis">
+<em class="replaceable"><code>function_name</code></em> ([<span class="optional"><em class="replaceable"><code>expression</code></em> [<span class="optional">, <em class="replaceable"><code>expression</code></em> ... </span>]</span>]) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ] OVER <em class="replaceable"><code>window_name</code></em>
+<em class="replaceable"><code>function_name</code></em> ([<span class="optional"><em class="replaceable"><code>expression</code></em> [<span class="optional">, <em class="replaceable"><code>expression</code></em> ... </span>]</span>]) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ] OVER ( <em class="replaceable"><code>window_definition</code></em> )
+<em class="replaceable"><code>function_name</code></em> ( * ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ] OVER <em class="replaceable"><code>window_name</code></em>
+<em class="replaceable"><code>function_name</code></em> ( * ) [ FILTER ( WHERE <em class="replaceable"><code>filter_clause</code></em> ) ] OVER ( <em class="replaceable"><code>window_definition</code></em> )
+</pre><p>
+ where <em class="replaceable"><code>window_definition</code></em>
+ has the syntax
+</p><pre class="synopsis">
+[ <em class="replaceable"><code>existing_window_name</code></em> ]
+[ PARTITION BY <em class="replaceable"><code>expression</code></em> [, ...] ]
+[ ORDER BY <em class="replaceable"><code>expression</code></em> [ ASC | DESC | USING <em class="replaceable"><code>operator</code></em> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+[ <em class="replaceable"><code>frame_clause</code></em> ]
+</pre><p>
+ The optional <em class="replaceable"><code>frame_clause</code></em>
+ can be one of
+</p><pre class="synopsis">
+{ RANGE | ROWS | GROUPS } <em class="replaceable"><code>frame_start</code></em> [ <em class="replaceable"><code>frame_exclusion</code></em> ]
+{ RANGE | ROWS | GROUPS } BETWEEN <em class="replaceable"><code>frame_start</code></em> AND <em class="replaceable"><code>frame_end</code></em> [ <em class="replaceable"><code>frame_exclusion</code></em> ]
+</pre><p>
+ where <em class="replaceable"><code>frame_start</code></em>
+ and <em class="replaceable"><code>frame_end</code></em> can be one of
+</p><pre class="synopsis">
+UNBOUNDED PRECEDING
+<em class="replaceable"><code>offset</code></em> PRECEDING
+CURRENT ROW
+<em class="replaceable"><code>offset</code></em> FOLLOWING
+UNBOUNDED FOLLOWING
+</pre><p>
+ and <em class="replaceable"><code>frame_exclusion</code></em> can be one of
+</p><pre class="synopsis">
+EXCLUDE CURRENT ROW
+EXCLUDE GROUP
+EXCLUDE TIES
+EXCLUDE NO OTHERS
+</pre><p>
+ </p><p>
+ Here, <em class="replaceable"><code>expression</code></em> represents any value
+ expression that does not itself contain window function calls.
+ </p><p>
+ <em class="replaceable"><code>window_name</code></em> is a reference to a named window
+ specification defined in the query's <code class="literal">WINDOW</code> clause.
+ Alternatively, a full <em class="replaceable"><code>window_definition</code></em> can
+ be given within parentheses, using the same syntax as for defining a
+ named window in the <code class="literal">WINDOW</code> clause; see the
+ <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> reference page for details. It's worth
+ pointing out that <code class="literal">OVER wname</code> is not exactly equivalent to
+ <code class="literal">OVER (wname ...)</code>; the latter implies copying and modifying the
+ window definition, and will be rejected if the referenced window
+ specification includes a frame clause.
+ </p><p>
+ The <code class="literal">PARTITION BY</code> clause groups the rows of the query into
+ <em class="firstterm">partitions</em>, which are processed separately by the window
+ function. <code class="literal">PARTITION BY</code> works similarly to a query-level
+ <code class="literal">GROUP BY</code> clause, except that its expressions are always just
+ expressions and cannot be output-column names or numbers.
+ Without <code class="literal">PARTITION BY</code>, all rows produced by the query are
+ treated as a single partition.
+ The <code class="literal">ORDER BY</code> clause determines the order in which the rows
+ of a partition are processed by the window function. It works similarly
+ to a query-level <code class="literal">ORDER BY</code> clause, but likewise cannot use
+ output-column names or numbers. Without <code class="literal">ORDER BY</code>, rows are
+ processed in an unspecified order.
+ </p><p>
+ The <em class="replaceable"><code>frame_clause</code></em> specifies
+ the set of rows constituting the <em class="firstterm">window frame</em>, which is a
+ subset of the current partition, for those window functions that act on
+ the frame instead of the whole partition. The set of rows in the frame
+ can vary depending on which row is the current row. The frame can be
+ specified in <code class="literal">RANGE</code>, <code class="literal">ROWS</code>
+ or <code class="literal">GROUPS</code> mode; in each case, it runs from
+ the <em class="replaceable"><code>frame_start</code></em> to
+ the <em class="replaceable"><code>frame_end</code></em>.
+ If <em class="replaceable"><code>frame_end</code></em> is omitted, the end defaults
+ to <code class="literal">CURRENT ROW</code>.
+ </p><p>
+ A <em class="replaceable"><code>frame_start</code></em> of <code class="literal">UNBOUNDED PRECEDING</code> means
+ that the frame starts with the first row of the partition, and similarly
+ a <em class="replaceable"><code>frame_end</code></em> of <code class="literal">UNBOUNDED FOLLOWING</code> means
+ that the frame ends with the last row of the partition.
+ </p><p>
+ In <code class="literal">RANGE</code> or <code class="literal">GROUPS</code> mode,
+ a <em class="replaceable"><code>frame_start</code></em> of
+ <code class="literal">CURRENT ROW</code> means the frame starts with the current
+ row's first <em class="firstterm">peer</em> row (a row that the
+ window's <code class="literal">ORDER BY</code> clause sorts as equivalent to the
+ current row), while a <em class="replaceable"><code>frame_end</code></em> of
+ <code class="literal">CURRENT ROW</code> means the frame ends with the current
+ row's last peer row.
+ In <code class="literal">ROWS</code> mode, <code class="literal">CURRENT ROW</code> simply
+ means the current row.
+ </p><p>
+ In the <em class="replaceable"><code>offset</code></em> <code class="literal">PRECEDING</code>
+ and <em class="replaceable"><code>offset</code></em> <code class="literal">FOLLOWING</code> frame
+ options, the <em class="replaceable"><code>offset</code></em> must be an expression not
+ containing any variables, aggregate functions, or window functions.
+ The meaning of the <em class="replaceable"><code>offset</code></em> depends on the
+ frame mode:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ In <code class="literal">ROWS</code> mode,
+ the <em class="replaceable"><code>offset</code></em> must yield a non-null,
+ non-negative integer, and the option means that the frame starts or
+ ends the specified number of rows before or after the current row.
+ </p></li><li class="listitem"><p>
+ In <code class="literal">GROUPS</code> mode,
+ the <em class="replaceable"><code>offset</code></em> again must yield a non-null,
+ non-negative integer, and the option means that the frame starts or
+ ends the specified number of <em class="firstterm">peer groups</em>
+ before or after the current row's peer group, where a peer group is a
+ set of rows that are equivalent in the <code class="literal">ORDER BY</code>
+ ordering. (There must be an <code class="literal">ORDER BY</code> clause
+ in the window definition to use <code class="literal">GROUPS</code> mode.)
+ </p></li><li class="listitem"><p>
+ In <code class="literal">RANGE</code> mode, these options require that
+ the <code class="literal">ORDER BY</code> clause specify exactly one column.
+ The <em class="replaceable"><code>offset</code></em> specifies the maximum
+ difference between the value of that column in the current row and
+ its value in preceding or following rows of the frame. The data type
+ of the <em class="replaceable"><code>offset</code></em> expression varies depending
+ on the data type of the ordering column. For numeric ordering
+ columns it is typically of the same type as the ordering column,
+ but for datetime ordering columns it is an <code class="type">interval</code>.
+ For example, if the ordering column is of type <code class="type">date</code>
+ or <code class="type">timestamp</code>, one could write <code class="literal">RANGE BETWEEN
+ '1 day' PRECEDING AND '10 days' FOLLOWING</code>.
+ The <em class="replaceable"><code>offset</code></em> is still required to be
+ non-null and non-negative, though the meaning
+ of <span class="quote">“<span class="quote">non-negative</span>”</span> depends on its data type.
+ </p></li></ul></div><p>
+ In any case, the distance to the end of the frame is limited by the
+ distance to the end of the partition, so that for rows near the partition
+ ends the frame might contain fewer rows than elsewhere.
+ </p><p>
+ Notice that in both <code class="literal">ROWS</code> and <code class="literal">GROUPS</code>
+ mode, <code class="literal">0 PRECEDING</code> and <code class="literal">0 FOLLOWING</code>
+ are equivalent to <code class="literal">CURRENT ROW</code>. This normally holds
+ in <code class="literal">RANGE</code> mode as well, for an appropriate
+ data-type-specific meaning of <span class="quote">“<span class="quote">zero</span>”</span>.
+ </p><p>
+ The <em class="replaceable"><code>frame_exclusion</code></em> option allows rows around
+ the current row to be excluded from the frame, even if they would be
+ included according to the frame start and frame end options.
+ <code class="literal">EXCLUDE CURRENT ROW</code> excludes the current row from the
+ frame.
+ <code class="literal">EXCLUDE GROUP</code> excludes the current row and its
+ ordering peers from the frame.
+ <code class="literal">EXCLUDE TIES</code> excludes any peers of the current
+ row from the frame, but not the current row itself.
+ <code class="literal">EXCLUDE NO OTHERS</code> simply specifies explicitly the
+ default behavior of not excluding the current row or its peers.
+ </p><p>
+ The default framing option is <code class="literal">RANGE UNBOUNDED PRECEDING</code>,
+ which is the same as <code class="literal">RANGE BETWEEN UNBOUNDED PRECEDING AND
+ CURRENT ROW</code>. With <code class="literal">ORDER BY</code>, this sets the frame to be
+ all rows from the partition start up through the current row's last
+ <code class="literal">ORDER BY</code> peer. Without <code class="literal">ORDER BY</code>,
+ this means all rows of the partition are included in the window frame,
+ since all rows become peers of the current row.
+ </p><p>
+ Restrictions are that
+ <em class="replaceable"><code>frame_start</code></em> cannot be <code class="literal">UNBOUNDED FOLLOWING</code>,
+ <em class="replaceable"><code>frame_end</code></em> cannot be <code class="literal">UNBOUNDED PRECEDING</code>,
+ and the <em class="replaceable"><code>frame_end</code></em> choice cannot appear earlier in the
+ above list of <em class="replaceable"><code>frame_start</code></em>
+ and <em class="replaceable"><code>frame_end</code></em> options than
+ the <em class="replaceable"><code>frame_start</code></em> choice does — for example
+ <code class="literal">RANGE BETWEEN CURRENT ROW AND <em class="replaceable"><code>offset</code></em>
+ PRECEDING</code> is not allowed.
+ But, for example, <code class="literal">ROWS BETWEEN 7 PRECEDING AND 8
+ PRECEDING</code> is allowed, even though it would never select any
+ rows.
+ </p><p>
+ If <code class="literal">FILTER</code> is specified, then only the input
+ rows for which the <em class="replaceable"><code>filter_clause</code></em>
+ evaluates to true are fed to the window function; other rows
+ are discarded. Only window functions that are aggregates accept
+ a <code class="literal">FILTER</code> clause.
+ </p><p>
+ The built-in window functions are described in <a class="xref" href="functions-window.html#FUNCTIONS-WINDOW-TABLE" title="Table 9.63. General-Purpose Window Functions">Table 9.63</a>. Other window functions can be added by
+ the user. Also, any built-in or user-defined general-purpose or
+ statistical aggregate can be used as a window function. (Ordered-set
+ and hypothetical-set aggregates cannot presently be used as window functions.)
+ </p><p>
+ The syntaxes using <code class="literal">*</code> are used for calling parameter-less
+ aggregate functions as window functions, for example
+ <code class="literal">count(*) OVER (PARTITION BY x ORDER BY y)</code>.
+ The asterisk (<code class="literal">*</code>) is customarily not used for
+ window-specific functions. Window-specific functions do not
+ allow <code class="literal">DISTINCT</code> or <code class="literal">ORDER BY</code> to be used within the
+ function argument list.
+ </p><p>
+ Window function calls are permitted only in the <code class="literal">SELECT</code>
+ list and the <code class="literal">ORDER BY</code> clause of the query.
+ </p><p>
+ More information about window functions can be found in
+ <a class="xref" href="tutorial-window.html" title="3.5. Window Functions">Section 3.5</a>,
+ <a class="xref" href="functions-window.html" title="9.22. Window Functions">Section 9.22</a>, and
+ <a class="xref" href="queries-table-expressions.html#QUERIES-WINDOW" title="7.2.5. Window Function Processing">Section 7.2.5</a>.
+ </p></div><div class="sect2" id="SQL-SYNTAX-TYPE-CASTS"><div class="titlepage"><div><div><h3 class="title">4.2.9. Type Casts</h3></div></div></div><a id="id-1.5.3.6.17.2" class="indexterm"></a><a id="id-1.5.3.6.17.3" class="indexterm"></a><a id="id-1.5.3.6.17.4" class="indexterm"></a><p>
+ A type cast specifies a conversion from one data type to another.
+ <span class="productname">PostgreSQL</span> accepts two equivalent syntaxes
+ for type casts:
+</p><pre class="synopsis">
+CAST ( <em class="replaceable"><code>expression</code></em> AS <em class="replaceable"><code>type</code></em> )
+<em class="replaceable"><code>expression</code></em>::<em class="replaceable"><code>type</code></em>
+</pre><p>
+ The <code class="literal">CAST</code> syntax conforms to SQL; the syntax with
+ <code class="literal">::</code> is historical <span class="productname">PostgreSQL</span>
+ usage.
+ </p><p>
+ When a cast is applied to a value expression of a known type, it
+ represents a run-time type conversion. The cast will succeed only
+ if a suitable type conversion operation has been defined. Notice that this
+ is subtly different from the use of casts with constants, as shown in
+ <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC" title="4.1.2.7. Constants of Other Types">Section 4.1.2.7</a>. A cast applied to an
+ unadorned string literal represents the initial assignment of a type
+ to a literal constant value, and so it will succeed for any type
+ (if the contents of the string literal are acceptable input syntax for the
+ data type).
+ </p><p>
+ An explicit type cast can usually be omitted if there is no ambiguity as
+ to the type that a value expression must produce (for example, when it is
+ assigned to a table column); the system will automatically apply a
+ type cast in such cases. However, automatic casting is only done for
+ casts that are marked <span class="quote">“<span class="quote">OK to apply implicitly</span>”</span>
+ in the system catalogs. Other casts must be invoked with
+ explicit casting syntax. This restriction is intended to prevent
+ surprising conversions from being applied silently.
+ </p><p>
+ It is also possible to specify a type cast using a function-like
+ syntax:
+</p><pre class="synopsis">
+<em class="replaceable"><code>typename</code></em> ( <em class="replaceable"><code>expression</code></em> )
+</pre><p>
+ However, this only works for types whose names are also valid as
+ function names. For example, <code class="literal">double precision</code>
+ cannot be used this way, but the equivalent <code class="literal">float8</code>
+ can. Also, the names <code class="literal">interval</code>, <code class="literal">time</code>, and
+ <code class="literal">timestamp</code> can only be used in this fashion if they are
+ double-quoted, because of syntactic conflicts. Therefore, the use of
+ the function-like cast syntax leads to inconsistencies and should
+ probably be avoided.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The function-like syntax is in fact just a function call. When
+ one of the two standard cast syntaxes is used to do a run-time
+ conversion, it will internally invoke a registered function to
+ perform the conversion. By convention, these conversion functions
+ have the same name as their output type, and thus the <span class="quote">“<span class="quote">function-like
+ syntax</span>”</span> is nothing more than a direct invocation of the underlying
+ conversion function. Obviously, this is not something that a portable
+ application should rely on. For further details see
+ <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a>.
+ </p></div></div><div class="sect2" id="SQL-SYNTAX-COLLATE-EXPRS"><div class="titlepage"><div><div><h3 class="title">4.2.10. Collation Expressions</h3></div></div></div><a id="id-1.5.3.6.18.2" class="indexterm"></a><p>
+ The <code class="literal">COLLATE</code> clause overrides the collation of
+ an expression. It is appended to the expression it applies to:
+</p><pre class="synopsis">
+<em class="replaceable"><code>expr</code></em> COLLATE <em class="replaceable"><code>collation</code></em>
+</pre><p>
+ where <em class="replaceable"><code>collation</code></em> is a possibly
+ schema-qualified identifier. The <code class="literal">COLLATE</code>
+ clause binds tighter than operators; parentheses can be used when
+ necessary.
+ </p><p>
+ If no collation is explicitly specified, the database system
+ either derives a collation from the columns involved in the
+ expression, or it defaults to the default collation of the
+ database if no column is involved in the expression.
+ </p><p>
+ The two common uses of the <code class="literal">COLLATE</code> clause are
+ overriding the sort order in an <code class="literal">ORDER BY</code> clause, for
+ example:
+</p><pre class="programlisting">
+SELECT a, b, c FROM tbl WHERE ... ORDER BY a COLLATE "C";
+</pre><p>
+ and overriding the collation of a function or operator call that
+ has locale-sensitive results, for example:
+</p><pre class="programlisting">
+SELECT * FROM tbl WHERE a &gt; 'foo' COLLATE "C";
+</pre><p>
+ Note that in the latter case the <code class="literal">COLLATE</code> clause is
+ attached to an input argument of the operator we wish to affect.
+ It doesn't matter which argument of the operator or function call the
+ <code class="literal">COLLATE</code> clause is attached to, because the collation that is
+ applied by the operator or function is derived by considering all
+ arguments, and an explicit <code class="literal">COLLATE</code> clause will override the
+ collations of all other arguments. (Attaching non-matching
+ <code class="literal">COLLATE</code> clauses to more than one argument, however, is an
+ error. For more details see <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>.)
+ Thus, this gives the same result as the previous example:
+</p><pre class="programlisting">
+SELECT * FROM tbl WHERE a COLLATE "C" &gt; 'foo';
+</pre><p>
+ But this is an error:
+</p><pre class="programlisting">
+SELECT * FROM tbl WHERE (a &gt; 'foo') COLLATE "C";
+</pre><p>
+ because it attempts to apply a collation to the result of the
+ <code class="literal">&gt;</code> operator, which is of the non-collatable data type
+ <code class="type">boolean</code>.
+ </p></div><div class="sect2" id="SQL-SYNTAX-SCALAR-SUBQUERIES"><div class="titlepage"><div><div><h3 class="title">4.2.11. Scalar Subqueries</h3></div></div></div><a id="id-1.5.3.6.19.2" class="indexterm"></a><p>
+ A scalar subquery is an ordinary
+ <code class="command">SELECT</code> query in parentheses that returns exactly one
+ row with one column. (See <a class="xref" href="queries.html" title="Chapter 7. Queries">Chapter 7</a> for information about writing queries.)
+ The <code class="command">SELECT</code> query is executed
+ and the single returned value is used in the surrounding value expression.
+ It is an error to use a query that
+ returns more than one row or more than one column as a scalar subquery.
+ (But if, during a particular execution, the subquery returns no rows,
+ there is no error; the scalar result is taken to be null.)
+ The subquery can refer to variables from the surrounding query,
+ which will act as constants during any one evaluation of the subquery.
+ See also <a class="xref" href="functions-subquery.html" title="9.23. Subquery Expressions">Section 9.23</a> for other expressions involving subqueries.
+ </p><p>
+ For example, the following finds the largest city population in each
+ state:
+</p><pre class="programlisting">
+SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)
+ FROM states;
+</pre><p>
+ </p></div><div class="sect2" id="SQL-SYNTAX-ARRAY-CONSTRUCTORS"><div class="titlepage"><div><div><h3 class="title">4.2.12. Array Constructors</h3></div></div></div><a id="id-1.5.3.6.20.2" class="indexterm"></a><a id="id-1.5.3.6.20.3" class="indexterm"></a><p>
+ An array constructor is an expression that builds an
+ array value using values for its member elements. A simple array
+ constructor
+ consists of the key word <code class="literal">ARRAY</code>, a left square bracket
+ <code class="literal">[</code>, a list of expressions (separated by commas) for the
+ array element values, and finally a right square bracket <code class="literal">]</code>.
+ For example:
+</p><pre class="programlisting">
+SELECT ARRAY[1,2,3+4];
+ array
+---------
+ {1,2,7}
+(1 row)
+</pre><p>
+ By default,
+ the array element type is the common type of the member expressions,
+ determined using the same rules as for <code class="literal">UNION</code> or
+ <code class="literal">CASE</code> constructs (see <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a>).
+ You can override this by explicitly casting the array constructor to the
+ desired type, for example:
+</p><pre class="programlisting">
+SELECT ARRAY[1,2,22.7]::integer[];
+ array
+----------
+ {1,2,23}
+(1 row)
+</pre><p>
+ This has the same effect as casting each expression to the array
+ element type individually.
+ For more on casting, see <a class="xref" href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS" title="4.2.9. Type Casts">Section 4.2.9</a>.
+ </p><p>
+ Multidimensional array values can be built by nesting array
+ constructors.
+ In the inner constructors, the key word <code class="literal">ARRAY</code> can
+ be omitted. For example, these produce the same result:
+
+</p><pre class="programlisting">
+SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
+ array
+---------------
+ {{1,2},{3,4}}
+(1 row)
+
+SELECT ARRAY[[1,2],[3,4]];
+ array
+---------------
+ {{1,2},{3,4}}
+(1 row)
+</pre><p>
+
+ Since multidimensional arrays must be rectangular, inner constructors
+ at the same level must produce sub-arrays of identical dimensions.
+ Any cast applied to the outer <code class="literal">ARRAY</code> constructor propagates
+ automatically to all the inner constructors.
+ </p><p>
+ Multidimensional array constructor elements can be anything yielding
+ an array of the proper kind, not only a sub-<code class="literal">ARRAY</code> construct.
+ For example:
+</p><pre class="programlisting">
+CREATE TABLE arr(f1 int[], f2 int[]);
+
+INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);
+
+SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr;
+ array
+------------------------------------------------
+ {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}
+(1 row)
+</pre><p>
+ </p><p>
+ You can construct an empty array, but since it's impossible to have an
+ array with no type, you must explicitly cast your empty array to the
+ desired type. For example:
+</p><pre class="programlisting">
+SELECT ARRAY[]::integer[];
+ array
+-------
+ {}
+(1 row)
+</pre><p>
+ </p><p>
+ It is also possible to construct an array from the results of a
+ subquery. In this form, the array constructor is written with the
+ key word <code class="literal">ARRAY</code> followed by a parenthesized (not
+ bracketed) subquery. For example:
+</p><pre class="programlisting">
+SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
+ array
+------------------------------------------------------------------
+ {2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31,2412}
+(1 row)
+
+SELECT ARRAY(SELECT ARRAY[i, i*2] FROM generate_series(1,5) AS a(i));
+ array
+----------------------------------
+ {{1,2},{2,4},{3,6},{4,8},{5,10}}
+(1 row)
+</pre><p>
+ The subquery must return a single column.
+ If the subquery's output column is of a non-array type, the resulting
+ one-dimensional array will have an element for each row in the
+ subquery result, with an element type matching that of the
+ subquery's output column.
+ If the subquery's output column is of an array type, the result will be
+ an array of the same type but one higher dimension; in this case all
+ the subquery rows must yield arrays of identical dimensionality, else
+ the result would not be rectangular.
+ </p><p>
+ The subscripts of an array value built with <code class="literal">ARRAY</code>
+ always begin with one. For more information about arrays, see
+ <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a>.
+ </p></div><div class="sect2" id="SQL-SYNTAX-ROW-CONSTRUCTORS"><div class="titlepage"><div><div><h3 class="title">4.2.13. Row Constructors</h3></div></div></div><a id="id-1.5.3.6.21.2" class="indexterm"></a><a id="id-1.5.3.6.21.3" class="indexterm"></a><a id="id-1.5.3.6.21.4" class="indexterm"></a><p>
+ A row constructor is an expression that builds a row value (also
+ called a composite value) using values
+ for its member fields. A row constructor consists of the key word
+ <code class="literal">ROW</code>, a left parenthesis, zero or more
+ expressions (separated by commas) for the row field values, and finally
+ a right parenthesis. For example:
+</p><pre class="programlisting">
+SELECT ROW(1,2.5,'this is a test');
+</pre><p>
+ The key word <code class="literal">ROW</code> is optional when there is more than one
+ expression in the list.
+ </p><p>
+ A row constructor can include the syntax
+ <em class="replaceable"><code>rowvalue</code></em><code class="literal">.*</code>,
+ which will be expanded to a list of the elements of the row value,
+ just as occurs when the <code class="literal">.*</code> syntax is used at the top level
+ of a <code class="command">SELECT</code> list (see <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a>).
+ For example, if table <code class="literal">t</code> has
+ columns <code class="literal">f1</code> and <code class="literal">f2</code>, these are the same:
+</p><pre class="programlisting">
+SELECT ROW(t.*, 42) FROM t;
+SELECT ROW(t.f1, t.f2, 42) FROM t;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> 8.2, the
+ <code class="literal">.*</code> syntax was not expanded in row constructors, so
+ that writing <code class="literal">ROW(t.*, 42)</code> created a two-field row whose first
+ field was another row value. The new behavior is usually more useful.
+ If you need the old behavior of nested row values, write the inner
+ row value without <code class="literal">.*</code>, for instance
+ <code class="literal">ROW(t, 42)</code>.
+ </p></div><p>
+ By default, the value created by a <code class="literal">ROW</code> expression is of
+ an anonymous record type. If necessary, it can be cast to a named
+ composite type — either the row type of a table, or a composite type
+ created with <code class="command">CREATE TYPE AS</code>. An explicit cast might be needed
+ to avoid ambiguity. For example:
+</p><pre class="programlisting">
+CREATE TABLE mytable(f1 int, f2 float, f3 text);
+
+CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
+
+-- No cast needed since only one getf1() exists
+SELECT getf1(ROW(1,2.5,'this is a test'));
+ getf1
+-------
+ 1
+(1 row)
+
+CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
+
+CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
+
+-- Now we need a cast to indicate which function to call:
+SELECT getf1(ROW(1,2.5,'this is a test'));
+ERROR: function getf1(record) is not unique
+
+SELECT getf1(ROW(1,2.5,'this is a test')::mytable);
+ getf1
+-------
+ 1
+(1 row)
+
+SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
+ getf1
+-------
+ 11
+(1 row)
+</pre><p>
+ </p><p>
+ Row constructors can be used to build composite values to be stored
+ in a composite-type table column, or to be passed to a function that
+ accepts a composite parameter. Also,
+ it is possible to compare two row values or test a row with
+ <code class="literal">IS NULL</code> or <code class="literal">IS NOT NULL</code>, for example:
+</p><pre class="programlisting">
+SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');
+
+SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows
+</pre><p>
+ For more detail see <a class="xref" href="functions-comparisons.html" title="9.24. Row and Array Comparisons">Section 9.24</a>.
+ Row constructors can also be used in connection with subqueries,
+ as discussed in <a class="xref" href="functions-subquery.html" title="9.23. Subquery Expressions">Section 9.23</a>.
+ </p></div><div class="sect2" id="SYNTAX-EXPRESS-EVAL"><div class="titlepage"><div><div><h3 class="title">4.2.14. Expression Evaluation Rules</h3></div></div></div><a id="id-1.5.3.6.22.2" class="indexterm"></a><p>
+ The order of evaluation of subexpressions is not defined. In
+ particular, the inputs of an operator or function are not necessarily
+ evaluated left-to-right or in any other fixed order.
+ </p><p>
+ Furthermore, if the result of an expression can be determined by
+ evaluating only some parts of it, then other subexpressions
+ might not be evaluated at all. For instance, if one wrote:
+</p><pre class="programlisting">
+SELECT true OR somefunc();
+</pre><p>
+ then <code class="literal">somefunc()</code> would (probably) not be called
+ at all. The same would be the case if one wrote:
+</p><pre class="programlisting">
+SELECT somefunc() OR true;
+</pre><p>
+ Note that this is not the same as the left-to-right
+ <span class="quote">“<span class="quote">short-circuiting</span>”</span> of Boolean operators that is found
+ in some programming languages.
+ </p><p>
+ As a consequence, it is unwise to use functions with side effects
+ as part of complex expressions. It is particularly dangerous to
+ rely on side effects or evaluation order in <code class="literal">WHERE</code> and <code class="literal">HAVING</code> clauses,
+ since those clauses are extensively reprocessed as part of
+ developing an execution plan. Boolean
+ expressions (<code class="literal">AND</code>/<code class="literal">OR</code>/<code class="literal">NOT</code> combinations) in those clauses can be reorganized
+ in any manner allowed by the laws of Boolean algebra.
+ </p><p>
+ When it is essential to force evaluation order, a <code class="literal">CASE</code>
+ construct (see <a class="xref" href="functions-conditional.html" title="9.18. Conditional Expressions">Section 9.18</a>) can be
+ used. For example, this is an untrustworthy way of trying to
+ avoid division by zero in a <code class="literal">WHERE</code> clause:
+</p><pre class="programlisting">
+SELECT ... WHERE x &gt; 0 AND y/x &gt; 1.5;
+</pre><p>
+ But this is safe:
+</p><pre class="programlisting">
+SELECT ... WHERE CASE WHEN x &gt; 0 THEN y/x &gt; 1.5 ELSE false END;
+</pre><p>
+ A <code class="literal">CASE</code> construct used in this fashion will defeat optimization
+ attempts, so it should only be done when necessary. (In this particular
+ example, it would be better to sidestep the problem by writing
+ <code class="literal">y &gt; 1.5*x</code> instead.)
+ </p><p>
+ <code class="literal">CASE</code> is not a cure-all for such issues, however.
+ One limitation of the technique illustrated above is that it does not
+ prevent early evaluation of constant subexpressions.
+ As described in <a class="xref" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Section 38.7</a>, functions and
+ operators marked <code class="literal">IMMUTABLE</code> can be evaluated when
+ the query is planned rather than when it is executed. Thus for example
+</p><pre class="programlisting">
+SELECT CASE WHEN x &gt; 0 THEN x ELSE 1/0 END FROM tab;
+</pre><p>
+ is likely to result in a division-by-zero failure due to the planner
+ trying to simplify the constant subexpression,
+ even if every row in the table has <code class="literal">x &gt; 0</code> so that the
+ <code class="literal">ELSE</code> arm would never be entered at run time.
+ </p><p>
+ While that particular example might seem silly, related cases that don't
+ obviously involve constants can occur in queries executed within
+ functions, since the values of function arguments and local variables
+ can be inserted into queries as constants for planning purposes.
+ Within <span class="application">PL/pgSQL</span> functions, for example, using an
+ <code class="literal">IF</code>-<code class="literal">THEN</code>-<code class="literal">ELSE</code> statement to protect
+ a risky computation is much safer than just nesting it in a
+ <code class="literal">CASE</code> expression.
+ </p><p>
+ Another limitation of the same kind is that a <code class="literal">CASE</code> cannot
+ prevent evaluation of an aggregate expression contained within it,
+ because aggregate expressions are computed before other
+ expressions in a <code class="literal">SELECT</code> list or <code class="literal">HAVING</code> clause
+ are considered. For example, the following query can cause a
+ division-by-zero error despite seemingly having protected against it:
+</p><pre class="programlisting">
+SELECT CASE WHEN min(employees) &gt; 0
+ THEN avg(expenses / employees)
+ END
+ FROM departments;
+</pre><p>
+ The <code class="function">min()</code> and <code class="function">avg()</code> aggregates are computed
+ concurrently over all the input rows, so if any row
+ has <code class="structfield">employees</code> equal to zero, the division-by-zero error
+ will occur before there is any opportunity to test the result of
+ <code class="function">min()</code>. Instead, use a <code class="literal">WHERE</code>
+ or <code class="literal">FILTER</code> clause to prevent problematic input rows from
+ reaching an aggregate function in the first place.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-syntax-lexical.html" title="4.1. Lexical Structure">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.1. Lexical Structure </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 4.3. Calling Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-fetch.html b/doc/src/sgml/html/sql-fetch.html
new file mode 100644
index 0000000..834dbc3
--- /dev/null
+++ b/doc/src/sgml/html/sql-fetch.html
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>FETCH</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-explain.html" title="EXPLAIN" /><link rel="next" href="sql-grant.html" title="GRANT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">FETCH</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-explain.html" title="EXPLAIN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-grant.html" title="GRANT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-FETCH"><div class="titlepage"></div><a id="id-1.9.3.149.1" class="indexterm"></a><a id="id-1.9.3.149.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">FETCH</span></h2><p>FETCH — retrieve rows from a query using a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+FETCH [ <em class="replaceable"><code>direction</code></em> ] [ FROM | IN ] <em class="replaceable"><code>cursor_name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>direction</code></em> can be one of:</span>
+
+ NEXT
+ PRIOR
+ FIRST
+ LAST
+ ABSOLUTE <em class="replaceable"><code>count</code></em>
+ RELATIVE <em class="replaceable"><code>count</code></em>
+ <em class="replaceable"><code>count</code></em>
+ ALL
+ FORWARD
+ FORWARD <em class="replaceable"><code>count</code></em>
+ FORWARD ALL
+ BACKWARD
+ BACKWARD <em class="replaceable"><code>count</code></em>
+ BACKWARD ALL
+</pre></div><div class="refsect1" id="id-1.9.3.149.6"><h2>Description</h2><p>
+ <code class="command">FETCH</code> retrieves rows using a previously-created cursor.
+ </p><p>
+ A cursor has an associated position, which is used by
+ <code class="command">FETCH</code>. The cursor position can be before the first row of the
+ query result, on any particular row of the result, or after the last row
+ of the result. When created, a cursor is positioned before the first row.
+ After fetching some rows, the cursor is positioned on the row most recently
+ retrieved. If <code class="command">FETCH</code> runs off the end of the available rows
+ then the cursor is left positioned after the last row, or before the first
+ row if fetching backward. <code class="command">FETCH ALL</code> or <code class="command">FETCH BACKWARD
+ ALL</code> will always leave the cursor positioned after the last row or before
+ the first row.
+ </p><p>
+ The forms <code class="literal">NEXT</code>, <code class="literal">PRIOR</code>, <code class="literal">FIRST</code>,
+ <code class="literal">LAST</code>, <code class="literal">ABSOLUTE</code>, <code class="literal">RELATIVE</code> fetch
+ a single row after moving the cursor appropriately. If there is no
+ such row, an empty result is returned, and the cursor is left
+ positioned before the first row or after the last row as
+ appropriate.
+ </p><p>
+ The forms using <code class="literal">FORWARD</code> and <code class="literal">BACKWARD</code>
+ retrieve the indicated number of rows moving in the forward or
+ backward direction, leaving the cursor positioned on the
+ last-returned row (or after/before all rows, if the <em class="replaceable"><code>count</code></em> exceeds the number of rows
+ available).
+ </p><p>
+ <code class="literal">RELATIVE 0</code>, <code class="literal">FORWARD 0</code>, and
+ <code class="literal">BACKWARD 0</code> all request fetching the current row without
+ moving the cursor, that is, re-fetching the most recently fetched
+ row. This will succeed unless the cursor is positioned before the
+ first row or after the last row; in which case, no row is returned.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ This page describes usage of cursors at the SQL command level.
+ If you are trying to use cursors inside a <span class="application">PL/pgSQL</span>
+ function, the rules are different —
+ see <a class="xref" href="plpgsql-cursors.html#PLPGSQL-CURSOR-USING" title="43.7.3. Using Cursors">Section 43.7.3</a>.
+ </p></div></div><div class="refsect1" id="id-1.9.3.149.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>direction</code></em></span></dt><dd><p><em class="replaceable"><code>direction</code></em> defines
+ the fetch direction and number of rows to fetch. It can be one
+ of the following:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">NEXT</code></span></dt><dd><p>
+ Fetch the next row. This is the default if <em class="replaceable"><code>direction</code></em> is omitted.
+ </p></dd><dt><span class="term"><code class="literal">PRIOR</code></span></dt><dd><p>
+ Fetch the prior row.
+ </p></dd><dt><span class="term"><code class="literal">FIRST</code></span></dt><dd><p>
+ Fetch the first row of the query (same as <code class="literal">ABSOLUTE 1</code>).
+ </p></dd><dt><span class="term"><code class="literal">LAST</code></span></dt><dd><p>
+ Fetch the last row of the query (same as <code class="literal">ABSOLUTE -1</code>).
+ </p></dd><dt><span class="term"><code class="literal">ABSOLUTE <em class="replaceable"><code>count</code></em></code></span></dt><dd><p>
+ Fetch the <em class="replaceable"><code>count</code></em>'th row of the query,
+ or the <code class="literal">abs(<em class="replaceable"><code>count</code></em>)</code>'th row from
+ the end if <em class="replaceable"><code>count</code></em> is negative. Position
+ before first row or after last row if <em class="replaceable"><code>count</code></em> is out of range; in
+ particular, <code class="literal">ABSOLUTE 0</code> positions before
+ the first row.
+ </p></dd><dt><span class="term"><code class="literal">RELATIVE <em class="replaceable"><code>count</code></em></code></span></dt><dd><p>
+ Fetch the <em class="replaceable"><code>count</code></em>'th succeeding row, or
+ the <code class="literal">abs(<em class="replaceable"><code>count</code></em>)</code>'th prior
+ row if <em class="replaceable"><code>count</code></em> is
+ negative. <code class="literal">RELATIVE 0</code> re-fetches the
+ current row, if any.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>count</code></em></span></dt><dd><p>
+ Fetch the next <em class="replaceable"><code>count</code></em> rows (same as
+ <code class="literal">FORWARD <em class="replaceable"><code>count</code></em></code>).
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Fetch all remaining rows (same as <code class="literal">FORWARD ALL</code>).
+ </p></dd><dt><span class="term"><code class="literal">FORWARD</code></span></dt><dd><p>
+ Fetch the next row (same as <code class="literal">NEXT</code>).
+ </p></dd><dt><span class="term"><code class="literal">FORWARD <em class="replaceable"><code>count</code></em></code></span></dt><dd><p>
+ Fetch the next <em class="replaceable"><code>count</code></em> rows.
+ <code class="literal">FORWARD 0</code> re-fetches the current row.
+ </p></dd><dt><span class="term"><code class="literal">FORWARD ALL</code></span></dt><dd><p>
+ Fetch all remaining rows.
+ </p></dd><dt><span class="term"><code class="literal">BACKWARD</code></span></dt><dd><p>
+ Fetch the prior row (same as <code class="literal">PRIOR</code>).
+ </p></dd><dt><span class="term"><code class="literal">BACKWARD <em class="replaceable"><code>count</code></em></code></span></dt><dd><p>
+ Fetch the prior <em class="replaceable"><code>count</code></em> rows (scanning
+ backwards). <code class="literal">BACKWARD 0</code> re-fetches the
+ current row.
+ </p></dd><dt><span class="term"><code class="literal">BACKWARD ALL</code></span></dt><dd><p>
+ Fetch all prior rows (scanning backwards).
+ </p></dd></dl></div></dd><dt><span class="term"><em class="replaceable"><code>count</code></em></span></dt><dd><p><em class="replaceable"><code>count</code></em> is a
+ possibly-signed integer constant, determining the location or
+ number of rows to fetch. For <code class="literal">FORWARD</code> and
+ <code class="literal">BACKWARD</code> cases, specifying a negative <em class="replaceable"><code>count</code></em> is equivalent to changing
+ the sense of <code class="literal">FORWARD</code> and <code class="literal">BACKWARD</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>cursor_name</code></em></span></dt><dd><p>
+ An open cursor's name.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.149.8"><h2>Outputs</h2><p>
+ On successful completion, a <code class="command">FETCH</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+FETCH <em class="replaceable"><code>count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>count</code></em> is the number
+ of rows fetched (possibly zero). Note that in
+ <span class="application">psql</span>, the command tag will not actually be
+ displayed, since <span class="application">psql</span> displays the fetched
+ rows instead.
+ </p></div><div class="refsect1" id="id-1.9.3.149.9"><h2>Notes</h2><p>
+ The cursor should be declared with the <code class="literal">SCROLL</code>
+ option if one intends to use any variants of <code class="command">FETCH</code>
+ other than <code class="command">FETCH NEXT</code> or <code class="command">FETCH FORWARD</code> with
+ a positive count. For simple queries
+ <span class="productname">PostgreSQL</span> will allow backwards fetch
+ from cursors not declared with <code class="literal">SCROLL</code>, but this
+ behavior is best not relied on. If the cursor is declared with
+ <code class="literal">NO SCROLL</code>, no backward fetches are allowed.
+ </p><p>
+ <code class="literal">ABSOLUTE</code> fetches are not any faster than
+ navigating to the desired row with a relative move: the underlying
+ implementation must traverse all the intermediate rows anyway.
+ Negative absolute fetches are even worse: the query must be read to
+ the end to find the last row, and then traversed backward from
+ there. However, rewinding to the start of the query (as with
+ <code class="literal">FETCH ABSOLUTE 0</code>) is fast.
+ </p><p>
+ <a class="link" href="sql-declare.html" title="DECLARE"><code class="command">DECLARE</code></a>
+ is used to define a cursor. Use
+ <a class="link" href="sql-move.html" title="MOVE"><code class="command">MOVE</code></a>
+ to change cursor position without retrieving data.
+ </p></div><div class="refsect1" id="id-1.9.3.149.10"><h2>Examples</h2><p>
+ The following example traverses a table using a cursor:
+
+</p><pre class="programlisting">
+BEGIN WORK;
+
+-- Set up a cursor:
+DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;
+
+-- Fetch the first 5 rows in the cursor liahona:
+FETCH FORWARD 5 FROM liahona;
+
+ code | title | did | date_prod | kind | len
+-------+-------------------------+-----+------------+----------+-------
+ BL101 | The Third Man | 101 | 1949-12-23 | Drama | 01:44
+ BL102 | The African Queen | 101 | 1951-08-11 | Romantic | 01:43
+ JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
+ P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
+ P_302 | Becket | 103 | 1964-02-03 | Drama | 02:28
+
+-- Fetch the previous row:
+FETCH PRIOR FROM liahona;
+
+ code | title | did | date_prod | kind | len
+-------+---------+-----+------------+--------+-------
+ P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
+
+-- Close the cursor and end the transaction:
+CLOSE liahona;
+COMMIT WORK;
+</pre></div><div class="refsect1" id="id-1.9.3.149.11"><h2>Compatibility</h2><p>
+ The SQL standard defines <code class="command">FETCH</code> for use in
+ embedded SQL only. The variant of <code class="command">FETCH</code>
+ described here returns the data as if it were a
+ <code class="command">SELECT</code> result rather than placing it in host
+ variables. Other than this point, <code class="command">FETCH</code> is
+ fully upward-compatible with the SQL standard.
+ </p><p>
+ The <code class="command">FETCH</code> forms involving
+ <code class="literal">FORWARD</code> and <code class="literal">BACKWARD</code>, as well
+ as the forms <code class="literal">FETCH <em class="replaceable"><code>count</code></em></code> and <code class="literal">FETCH
+ ALL</code>, in which <code class="literal">FORWARD</code> is implicit, are
+ <span class="productname">PostgreSQL</span> extensions.
+ </p><p>
+ The SQL standard allows only <code class="literal">FROM</code> preceding the cursor
+ name; the option to use <code class="literal">IN</code>, or to leave them out altogether, is
+ an extension.
+ </p></div><div class="refsect1" id="id-1.9.3.149.12"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-close.html" title="CLOSE"><span class="refentrytitle">CLOSE</span></a>, <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>, <a class="xref" href="sql-move.html" title="MOVE"><span class="refentrytitle">MOVE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-explain.html" title="EXPLAIN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-grant.html" title="GRANT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">EXPLAIN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> GRANT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-grant.html b/doc/src/sgml/html/sql-grant.html
new file mode 100644
index 0000000..e34040b
--- /dev/null
+++ b/doc/src/sgml/html/sql-grant.html
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>GRANT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-fetch.html" title="FETCH" /><link rel="next" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">GRANT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-fetch.html" title="FETCH">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-GRANT"><div class="titlepage"></div><a id="id-1.9.3.150.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">GRANT</span></h2><p>GRANT — define access privileges</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { [ TABLE ] <em class="replaceable"><code>table_name</code></em> [, ...]
+ | ALL TABLES IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] }
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <em class="replaceable"><code>column_name</code></em> [, ...] )
+ [, ...] | ALL [ PRIVILEGES ] ( <em class="replaceable"><code>column_name</code></em> [, ...] ) }
+ ON [ TABLE ] <em class="replaceable"><code>table_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { SEQUENCE <em class="replaceable"><code>sequence_name</code></em> [, ...]
+ | ALL SEQUENCES IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] }
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
+ ON DATABASE <em class="replaceable"><code>database_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON DOMAIN <em class="replaceable"><code>domain_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN DATA WRAPPER <em class="replaceable"><code>fdw_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN SERVER <em class="replaceable"><code>server_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { { FUNCTION | PROCEDURE | ROUTINE } <em class="replaceable"><code>routine_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>arg_name</code></em> ] <em class="replaceable"><code>arg_type</code></em> [, ...] ] ) ] [, ...]
+ | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] }
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON LANGUAGE <em class="replaceable"><code>lang_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
+ ON LARGE OBJECT <em class="replaceable"><code>loid</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { { SET | ALTER SYSTEM } [, ... ] | ALL [ PRIVILEGES ] }
+ ON PARAMETER <em class="replaceable"><code>configuration_parameter</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
+ ON SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { CREATE | ALL [ PRIVILEGES ] }
+ ON TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPE <em class="replaceable"><code>type_name</code></em> [, ...]
+ TO <em class="replaceable"><code>role_specification</code></em> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+GRANT <em class="replaceable"><code>role_name</code></em> [, ...] TO <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ WITH ADMIN OPTION ]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+
+<span class="phrase">where <em class="replaceable"><code>role_specification</code></em> can be:</span>
+
+ [ GROUP ] <em class="replaceable"><code>role_name</code></em>
+ | PUBLIC
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</pre></div><div class="refsect1" id="SQL-GRANT-DESCRIPTION"><h2>Description</h2><p>
+ The <code class="command">GRANT</code> command has two basic variants: one
+ that grants privileges on a database object (table, column, view,
+ foreign table, sequence, database, foreign-data wrapper, foreign server,
+ function, procedure, procedural language, large object, configuration
+ parameter, schema, tablespace, or type), and one that grants
+ membership in a role. These variants are similar in many ways, but
+ they are different enough to be described separately.
+ </p><div class="refsect2" id="SQL-GRANT-DESCRIPTION-OBJECTS"><h3>GRANT on Database Objects</h3><p>
+ This variant of the <code class="command">GRANT</code> command gives specific
+ privileges on a database object to
+ one or more roles. These privileges are added
+ to those already granted, if any.
+ </p><p>
+ The key word <code class="literal">PUBLIC</code> indicates that the
+ privileges are to be granted to all roles, including those that might
+ be created later. <code class="literal">PUBLIC</code> can be thought of as an
+ implicitly defined group that always includes all roles.
+ Any particular role will have the sum
+ of privileges granted directly to it, privileges granted to any role it
+ is presently a member of, and privileges granted to
+ <code class="literal">PUBLIC</code>.
+ </p><p>
+ If <code class="literal">WITH GRANT OPTION</code> is specified, the recipient
+ of the privilege can in turn grant it to others. Without a grant
+ option, the recipient cannot do that. Grant options cannot be granted
+ to <code class="literal">PUBLIC</code>.
+ </p><p>
+ If <code class="literal">GRANTED BY</code> is specified, the specified grantor must
+ be the current user. This clause is currently present in this form only
+ for SQL compatibility.
+ </p><p>
+ There is no need to grant privileges to the owner of an object
+ (usually the user that created it),
+ as the owner has all privileges by default. (The owner could,
+ however, choose to revoke some of their own privileges for safety.)
+ </p><p>
+ The right to drop an object, or to alter its definition in any way, is
+ not treated as a grantable privilege; it is inherent in the owner,
+ and cannot be granted or revoked. (However, a similar effect can be
+ obtained by granting or revoking membership in the role that owns
+ the object; see below.) The owner implicitly has all grant
+ options for the object, too.
+ </p><p>
+ The possible privileges are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SELECT</code><br /></span><span class="term"><code class="literal">INSERT</code><br /></span><span class="term"><code class="literal">UPDATE</code><br /></span><span class="term"><code class="literal">DELETE</code><br /></span><span class="term"><code class="literal">TRUNCATE</code><br /></span><span class="term"><code class="literal">REFERENCES</code><br /></span><span class="term"><code class="literal">TRIGGER</code><br /></span><span class="term"><code class="literal">CREATE</code><br /></span><span class="term"><code class="literal">CONNECT</code><br /></span><span class="term"><code class="literal">TEMPORARY</code><br /></span><span class="term"><code class="literal">EXECUTE</code><br /></span><span class="term"><code class="literal">USAGE</code><br /></span><span class="term"><code class="literal">SET</code><br /></span><span class="term"><code class="literal">ALTER SYSTEM</code></span></dt><dd><p>
+ Specific types of privileges, as defined in <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>.
+ </p></dd><dt><span class="term"><code class="literal">TEMP</code></span></dt><dd><p>
+ Alternative spelling for <code class="literal">TEMPORARY</code>.
+ </p></dd><dt><span class="term"><code class="literal">ALL PRIVILEGES</code></span></dt><dd><p>
+ Grant all of the privileges available for the object's type.
+ The <code class="literal">PRIVILEGES</code> key word is optional in
+ <span class="productname">PostgreSQL</span>, though it is required by
+ strict SQL.
+ </p></dd></dl></div><p>
+ </p><p>
+ The <code class="literal">FUNCTION</code> syntax works for plain functions,
+ aggregate functions, and window functions, but not for procedures;
+ use <code class="literal">PROCEDURE</code> for those.
+ Alternatively, use <code class="literal">ROUTINE</code> to refer to a function,
+ aggregate function, window function, or procedure regardless of its
+ precise type.
+ </p><p>
+ There is also an option to grant privileges on all objects of the same
+ type within one or more schemas. This functionality is currently supported
+ only for tables, sequences, functions, and procedures. <code class="literal">ALL
+ TABLES</code> also affects views and foreign tables, just like the
+ specific-object <code class="command">GRANT</code> command. <code class="literal">ALL
+ FUNCTIONS</code> also affects aggregate and window functions, but not
+ procedures, again just like the specific-object <code class="command">GRANT</code>
+ command. Use <code class="literal">ALL ROUTINES</code> to include procedures.
+ </p></div><div class="refsect2" id="SQL-GRANT-DESCRIPTION-ROLES"><h3>GRANT on Roles</h3><p>
+ This variant of the <code class="command">GRANT</code> command grants membership
+ in a role to one or more other roles. Membership in a role is significant
+ because it conveys the privileges granted to a role to each of its
+ members.
+ </p><p>
+ If <code class="literal">WITH ADMIN OPTION</code> is specified, the member can
+ in turn grant membership in the role to others, and revoke membership
+ in the role as well. Without the admin option, ordinary users cannot
+ do that. A role is not considered to hold <code class="literal">WITH ADMIN
+ OPTION</code> on itself. Database superusers can grant or revoke
+ membership in any role to anyone. Roles having
+ <code class="literal">CREATEROLE</code> privilege can grant or revoke membership
+ in any role that is not a superuser.
+ </p><p>
+ If <code class="literal">GRANTED BY</code> is specified, the grant is recorded as
+ having been done by the specified role. Only database superusers may
+ use this option, except when it names the same role executing the command.
+ </p><p>
+ Unlike the case with privileges, membership in a role cannot be granted
+ to <code class="literal">PUBLIC</code>. Note also that this form of the command
+ does not allow the noise word <code class="literal">GROUP</code>
+ in <em class="replaceable"><code>role_specification</code></em>.
+ </p></div></div><div class="refsect1" id="SQL-GRANT-NOTES"><h2>Notes</h2><p>
+ The <a class="link" href="sql-revoke.html" title="REVOKE"><code class="command">REVOKE</code></a> command is used
+ to revoke access privileges.
+ </p><p>
+ Since <span class="productname">PostgreSQL</span> 8.1, the concepts of users and
+ groups have been unified into a single kind of entity called a role.
+ It is therefore no longer necessary to use the keyword <code class="literal">GROUP</code>
+ to identify whether a grantee is a user or a group. <code class="literal">GROUP</code>
+ is still allowed in the command, but it is a noise word.
+ </p><p>
+ A user may perform <code class="command">SELECT</code>, <code class="command">INSERT</code>, etc. on a
+ column if they hold that privilege for either the specific column or
+ its whole table. Granting the privilege at the table level and then
+ revoking it for one column will not do what one might wish: the
+ table-level grant is unaffected by a column-level operation.
+ </p><p>
+ When a non-owner of an object attempts to <code class="command">GRANT</code> privileges
+ on the object, the command will fail outright if the user has no
+ privileges whatsoever on the object. As long as some privilege is
+ available, the command will proceed, but it will grant only those
+ privileges for which the user has grant options. The <code class="command">GRANT ALL
+ PRIVILEGES</code> forms will issue a warning message if no grant options are
+ held, while the other forms will issue a warning if grant options for
+ any of the privileges specifically named in the command are not held.
+ (In principle these statements apply to the object owner as well, but
+ since the owner is always treated as holding all grant options, the
+ cases can never occur.)
+ </p><p>
+ It should be noted that database superusers can access
+ all objects regardless of object privilege settings. This
+ is comparable to the rights of <code class="literal">root</code> in a Unix system.
+ As with <code class="literal">root</code>, it's unwise to operate as a superuser
+ except when absolutely necessary.
+ </p><p>
+ If a superuser chooses to issue a <code class="command">GRANT</code> or <code class="command">REVOKE</code>
+ command, the command is performed as though it were issued by the
+ owner of the affected object. In particular, privileges granted via
+ such a command will appear to have been granted by the object owner.
+ (For role membership, the membership appears to have been granted
+ by the containing role itself.)
+ </p><p>
+ <code class="command">GRANT</code> and <code class="command">REVOKE</code> can also be done by a role
+ that is not the owner of the affected object, but is a member of the role
+ that owns the object, or is a member of a role that holds privileges
+ <code class="literal">WITH GRANT OPTION</code> on the object. In this case the
+ privileges will be recorded as having been granted by the role that
+ actually owns the object or holds the privileges
+ <code class="literal">WITH GRANT OPTION</code>. For example, if table
+ <code class="literal">t1</code> is owned by role <code class="literal">g1</code>, of which role
+ <code class="literal">u1</code> is a member, then <code class="literal">u1</code> can grant privileges
+ on <code class="literal">t1</code> to <code class="literal">u2</code>, but those privileges will appear
+ to have been granted directly by <code class="literal">g1</code>. Any other member
+ of role <code class="literal">g1</code> could revoke them later.
+ </p><p>
+ If the role executing <code class="command">GRANT</code> holds the required privileges
+ indirectly via more than one role membership path, it is unspecified
+ which containing role will be recorded as having done the grant. In such
+ cases it is best practice to use <code class="command">SET ROLE</code> to become the
+ specific role you want to do the <code class="command">GRANT</code> as.
+ </p><p>
+ Granting permission on a table does not automatically extend
+ permissions to any sequences used by the table, including
+ sequences tied to <code class="type">SERIAL</code> columns. Permissions on
+ sequences must be set separately.
+ </p><p>
+ See <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for more information about specific
+ privilege types, as well as how to inspect objects' privileges.
+ </p></div><div class="refsect1" id="SQL-GRANT-EXAMPLES"><h2>Examples</h2><p>
+ Grant insert privilege to all users on table <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+GRANT INSERT ON films TO PUBLIC;
+</pre><p>
+ </p><p>
+ Grant all available privileges to user <code class="literal">manuel</code> on view
+ <code class="literal">kinds</code>:
+
+</p><pre class="programlisting">
+GRANT ALL PRIVILEGES ON kinds TO manuel;
+</pre><p>
+
+ Note that while the above will indeed grant all privileges if executed by a
+ superuser or the owner of <code class="literal">kinds</code>, when executed by someone
+ else it will only grant those permissions for which the someone else has
+ grant options.
+ </p><p>
+ Grant membership in role <code class="literal">admins</code> to user <code class="literal">joe</code>:
+
+</p><pre class="programlisting">
+GRANT admins TO joe;
+</pre></div><div class="refsect1" id="SQL-GRANT-COMPATIBILITY"><h2>Compatibility</h2><p>
+ According to the SQL standard, the <code class="literal">PRIVILEGES</code>
+ key word in <code class="literal">ALL PRIVILEGES</code> is required. The
+ SQL standard does not support setting the privileges on more than
+ one object per command.
+ </p><p>
+ <span class="productname">PostgreSQL</span> allows an object owner to revoke their
+ own ordinary privileges: for example, a table owner can make the table
+ read-only to themselves by revoking their own <code class="literal">INSERT</code>,
+ <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>, and <code class="literal">TRUNCATE</code>
+ privileges. This is not possible according to the SQL standard. The
+ reason is that <span class="productname">PostgreSQL</span> treats the owner's
+ privileges as having been granted by the owner to themselves; therefore they
+ can revoke them too. In the SQL standard, the owner's privileges are
+ granted by an assumed entity <span class="quote">“<span class="quote">_SYSTEM</span>”</span>. Not being
+ <span class="quote">“<span class="quote">_SYSTEM</span>”</span>, the owner cannot revoke these rights.
+ </p><p>
+ According to the SQL standard, grant options can be granted to
+ <code class="literal">PUBLIC</code>; PostgreSQL only supports granting grant options
+ to roles.
+ </p><p>
+ The SQL standard allows the <code class="literal">GRANTED BY</code> option to
+ specify only <code class="literal">CURRENT_USER</code> or
+ <code class="literal">CURRENT_ROLE</code>. The other variants are PostgreSQL
+ extensions.
+ </p><p>
+ The SQL standard provides for a <code class="literal">USAGE</code> privilege
+ on other kinds of objects: character sets, collations,
+ translations.
+ </p><p>
+ In the SQL standard, sequences only have a <code class="literal">USAGE</code>
+ privilege, which controls the use of the <code class="literal">NEXT VALUE FOR</code>
+ expression, which is equivalent to the
+ function <code class="function">nextval</code> in PostgreSQL. The sequence
+ privileges <code class="literal">SELECT</code> and <code class="literal">UPDATE</code> are
+ PostgreSQL extensions. The application of the
+ sequence <code class="literal">USAGE</code> privilege to
+ the <code class="literal">currval</code> function is also a PostgreSQL extension (as
+ is the function itself).
+ </p><p>
+ Privileges on databases, tablespaces, schemas, languages, and
+ configuration parameters are
+ <span class="productname">PostgreSQL</span> extensions.
+ </p></div><div class="refsect1" id="id-1.9.3.150.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-revoke.html" title="REVOKE"><span class="refentrytitle">REVOKE</span></a>, <a class="xref" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES"><span class="refentrytitle">ALTER DEFAULT PRIVILEGES</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-fetch.html" title="FETCH">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA">Next</a></td></tr><tr><td width="40%" align="left" valign="top">FETCH </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> IMPORT FOREIGN SCHEMA</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-importforeignschema.html b/doc/src/sgml/html/sql-importforeignschema.html
new file mode 100644
index 0000000..602da28
--- /dev/null
+++ b/doc/src/sgml/html/sql-importforeignschema.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>IMPORT FOREIGN SCHEMA</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-grant.html" title="GRANT" /><link rel="next" href="sql-insert.html" title="INSERT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">IMPORT FOREIGN SCHEMA</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-grant.html" title="GRANT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-insert.html" title="INSERT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-IMPORTFOREIGNSCHEMA"><div class="titlepage"></div><a id="id-1.9.3.151.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">IMPORT FOREIGN SCHEMA</span></h2><p>IMPORT FOREIGN SCHEMA — import table definitions from a foreign server</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+IMPORT FOREIGN SCHEMA <em class="replaceable"><code>remote_schema</code></em>
+ [ { LIMIT TO | EXCEPT } ( <em class="replaceable"><code>table_name</code></em> [, ...] ) ]
+ FROM SERVER <em class="replaceable"><code>server_name</code></em>
+ INTO <em class="replaceable"><code>local_schema</code></em>
+ [ OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ... ] ) ]
+</pre></div><div class="refsect1" id="SQL-IMPORTFOREIGNSCHEMA-DESCRIPTION"><h2>Description</h2><p>
+ <code class="command">IMPORT FOREIGN SCHEMA</code> creates foreign tables that
+ represent tables existing on a foreign server. The new foreign tables
+ will be owned by the user issuing the command and are created with
+ the correct column definitions and options to match the remote tables.
+ </p><p>
+ By default, all tables and views existing in a particular schema on the
+ foreign server are imported. Optionally, the list of tables can be limited
+ to a specified subset, or specific tables can be excluded. The new foreign
+ tables are all created in the target schema, which must already exist.
+ </p><p>
+ To use <code class="command">IMPORT FOREIGN SCHEMA</code>, the user must have
+ <code class="literal">USAGE</code> privilege on the foreign server, as well as
+ <code class="literal">CREATE</code> privilege on the target schema.
+ </p></div><div class="refsect1" id="id-1.9.3.151.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>remote_schema</code></em></span></dt><dd><p>
+ The remote schema to import from. The specific meaning of a remote schema
+ depends on the foreign data wrapper in use.
+ </p></dd><dt><span class="term"><code class="literal">LIMIT TO ( <em class="replaceable"><code>table_name</code></em> [, ...] )</code></span></dt><dd><p>
+ Import only foreign tables matching one of the given table names.
+ Other tables existing in the foreign schema will be ignored.
+ </p></dd><dt><span class="term"><code class="literal">EXCEPT ( <em class="replaceable"><code>table_name</code></em> [, ...] )</code></span></dt><dd><p>
+ Exclude specified foreign tables from the import. All tables
+ existing in the foreign schema will be imported except the
+ ones listed here.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>server_name</code></em></span></dt><dd><p>
+ The foreign server to import from.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>local_schema</code></em></span></dt><dd><p>
+ The schema in which the imported foreign tables will be created.
+ </p></dd><dt><span class="term"><code class="literal">OPTIONS ( <em class="replaceable"><code>option</code></em> '<em class="replaceable"><code>value</code></em>' [, ...] )</code></span></dt><dd><p>
+ Options to be used during the import.
+ The allowed option names and values are specific to each foreign
+ data wrapper.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-IMPORTFOREIGNSCHEMA-EXAMPLES"><h2>Examples</h2><p>
+ Import table definitions from a remote schema <code class="structname">foreign_films</code>
+ on server <code class="structname">film_server</code>, creating the foreign tables in
+ local schema <code class="structname">films</code>:
+
+</p><pre class="programlisting">
+IMPORT FOREIGN SCHEMA foreign_films
+ FROM SERVER film_server INTO films;
+</pre><p>
+ </p><p>
+ As above, but import only the two tables <code class="structname">actors</code> and
+ <code class="literal">directors</code> (if they exist):
+
+</p><pre class="programlisting">
+IMPORT FOREIGN SCHEMA foreign_films LIMIT TO (actors, directors)
+ FROM SERVER film_server INTO films;
+</pre></div><div class="refsect1" id="SQL-IMPORTFOREIGNSCHEMA-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The <code class="command">IMPORT FOREIGN SCHEMA</code> command conforms to the
+ <acronym class="acronym">SQL</acronym> standard, except that the <code class="literal">OPTIONS</code>
+ clause is a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.151.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createforeigntable.html" title="CREATE FOREIGN TABLE"><span class="refentrytitle">CREATE FOREIGN TABLE</span></a>, <a class="xref" href="sql-createserver.html" title="CREATE SERVER"><span class="refentrytitle">CREATE SERVER</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-grant.html" title="GRANT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-insert.html" title="INSERT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">GRANT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> INSERT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-insert.html b/doc/src/sgml/html/sql-insert.html
new file mode 100644
index 0000000..9bfed50
--- /dev/null
+++ b/doc/src/sgml/html/sql-insert.html
@@ -0,0 +1,488 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>INSERT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA" /><link rel="next" href="sql-listen.html" title="LISTEN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">INSERT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-listen.html" title="LISTEN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-INSERT"><div class="titlepage"></div><a id="id-1.9.3.152.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">INSERT</span></h2><p>INSERT — create new rows in a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+[ WITH [ RECURSIVE ] <em class="replaceable"><code>with_query</code></em> [, ...] ]
+INSERT INTO <em class="replaceable"><code>table_name</code></em> [ AS <em class="replaceable"><code>alias</code></em> ] [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+ [ OVERRIDING { SYSTEM | USER } VALUE ]
+ { DEFAULT VALUES | VALUES ( { <em class="replaceable"><code>expression</code></em> | DEFAULT } [, ...] ) [, ...] | <em class="replaceable"><code>query</code></em> }
+ [ ON CONFLICT [ <em class="replaceable"><code>conflict_target</code></em> ] <em class="replaceable"><code>conflict_action</code></em> ]
+ [ RETURNING * | <em class="replaceable"><code>output_expression</code></em> [ [ AS ] <em class="replaceable"><code>output_name</code></em> ] [, ...] ]
+
+<span class="phrase">where <em class="replaceable"><code>conflict_target</code></em> can be one of:</span>
+
+ ( { <em class="replaceable"><code>index_column_name</code></em> | ( <em class="replaceable"><code>index_expression</code></em> ) } [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>opclass</code></em> ] [, ...] ) [ WHERE <em class="replaceable"><code>index_predicate</code></em> ]
+ ON CONSTRAINT <em class="replaceable"><code>constraint_name</code></em>
+
+<span class="phrase">and <em class="replaceable"><code>conflict_action</code></em> is one of:</span>
+
+ DO NOTHING
+ DO UPDATE SET { <em class="replaceable"><code>column_name</code></em> = { <em class="replaceable"><code>expression</code></em> | DEFAULT } |
+ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) = [ ROW ] ( { <em class="replaceable"><code>expression</code></em> | DEFAULT } [, ...] ) |
+ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) = ( <em class="replaceable"><code>sub-SELECT</code></em> )
+ } [, ...]
+ [ WHERE <em class="replaceable"><code>condition</code></em> ]
+</pre></div><div class="refsect1" id="id-1.9.3.152.5"><h2>Description</h2><p>
+ <code class="command">INSERT</code> inserts new rows into a table.
+ One can insert one or more rows specified by value expressions,
+ or zero or more rows resulting from a query.
+ </p><p>
+ The target column names can be listed in any order. If no list of
+ column names is given at all, the default is all the columns of the
+ table in their declared order; or the first <em class="replaceable"><code>N</code></em> column
+ names, if there are only <em class="replaceable"><code>N</code></em> columns supplied by the
+ <code class="literal">VALUES</code> clause or <em class="replaceable"><code>query</code></em>. The values
+ supplied by the <code class="literal">VALUES</code> clause or <em class="replaceable"><code>query</code></em> are
+ associated with the explicit or implicit column list left-to-right.
+ </p><p>
+ Each column not present in the explicit or implicit column list will be
+ filled with a default value, either its declared default value
+ or null if there is none.
+ </p><p>
+ If the expression for any column is not of the correct data type,
+ automatic type conversion will be attempted.
+ </p><p>
+ <code class="command">INSERT</code> into tables that lack unique indexes will
+ not be blocked by concurrent activity. Tables with unique indexes
+ might block if concurrent sessions perform actions that lock or modify
+ rows matching the unique index values being inserted; the details
+ are covered in <a class="xref" href="index-unique-checks.html" title="64.5. Index Uniqueness Checks">Section 64.5</a>.
+ <code class="literal">ON CONFLICT</code> can be used to specify an alternative
+ action to raising a unique constraint or exclusion constraint
+ violation error. (See <a class="xref" href="sql-insert.html#SQL-ON-CONFLICT" title="ON CONFLICT Clause">ON CONFLICT Clause</a> below.)
+ </p><p>
+ The optional <code class="literal">RETURNING</code> clause causes <code class="command">INSERT</code>
+ to compute and return value(s) based on each row actually inserted
+ (or updated, if an <code class="literal">ON CONFLICT DO UPDATE</code> clause was
+ used). This is primarily useful for obtaining values that were
+ supplied by defaults, such as a serial sequence number. However,
+ any expression using the table's columns is allowed. The syntax of
+ the <code class="literal">RETURNING</code> list is identical to that of the output
+ list of <code class="command">SELECT</code>. Only rows that were successfully
+ inserted or updated will be returned. For example, if a row was
+ locked but not updated because an <code class="literal">ON CONFLICT DO UPDATE
+ ... WHERE</code> clause <em class="replaceable"><code>condition</code></em> was not satisfied, the
+ row will not be returned.
+ </p><p>
+ You must have <code class="literal">INSERT</code> privilege on a table in
+ order to insert into it. If <code class="literal">ON CONFLICT DO UPDATE</code> is
+ present, <code class="literal">UPDATE</code> privilege on the table is also
+ required.
+ </p><p>
+ If a column list is specified, you only need
+ <code class="literal">INSERT</code> privilege on the listed columns.
+ Similarly, when <code class="literal">ON CONFLICT DO UPDATE</code> is specified, you
+ only need <code class="literal">UPDATE</code> privilege on the column(s) that are
+ listed to be updated. However, <code class="literal">ON CONFLICT DO UPDATE</code>
+ also requires <code class="literal">SELECT</code> privilege on any column whose
+ values are read in the <code class="literal">ON CONFLICT DO UPDATE</code>
+ expressions or <em class="replaceable"><code>condition</code></em>.
+ </p><p>
+ Use of the <code class="literal">RETURNING</code> clause requires <code class="literal">SELECT</code>
+ privilege on all columns mentioned in <code class="literal">RETURNING</code>.
+ If you use the <em class="replaceable"><code>query</code></em> clause to insert rows from a
+ query, you of course need to have <code class="literal">SELECT</code> privilege on
+ any table or column used in the query.
+ </p></div><div class="refsect1" id="id-1.9.3.152.6"><h2>Parameters</h2><div class="refsect2" id="id-1.9.3.152.6.2"><h3>Inserting</h3><p>
+ This section covers parameters that may be used when only
+ inserting new rows. Parameters <span class="emphasis"><em>exclusively</em></span>
+ used with the <code class="literal">ON CONFLICT</code> clause are described
+ separately.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>with_query</code></em></span></dt><dd><p>
+ The <code class="literal">WITH</code> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <code class="command">INSERT</code>
+ query. See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a> and <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>
+ for details.
+ </p><p>
+ It is possible for the <em class="replaceable"><code>query</code></em>
+ (<code class="command">SELECT</code> statement)
+ to also contain a <code class="literal">WITH</code> clause. In such a case both
+ sets of <em class="replaceable"><code>with_query</code></em> can be referenced within
+ the <em class="replaceable"><code>query</code></em>, but the
+ second one takes precedence since it is more closely nested.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>alias</code></em></span></dt><dd><p>
+ A substitute name for <em class="replaceable"><code>table_name</code></em>. When an alias is
+ provided, it completely hides the actual name of the table.
+ This is particularly useful when <code class="literal">ON CONFLICT DO UPDATE</code>
+ targets a table named <code class="varname">excluded</code>, since that will otherwise
+ be taken as the name of the special table representing the row proposed
+ for insertion.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column in the table named by <em class="replaceable"><code>table_name</code></em>. The column name
+ can be qualified with a subfield name or array subscript, if
+ needed. (Inserting into only some fields of a composite
+ column leaves the other fields null.) When referencing a
+ column with <code class="literal">ON CONFLICT DO UPDATE</code>, do not include
+ the table's name in the specification of a target column. For
+ example, <code class="literal">INSERT INTO table_name ... ON CONFLICT DO UPDATE
+ SET table_name.col = 1</code> is invalid (this follows the general
+ behavior for <code class="command">UPDATE</code>).
+ </p></dd><dt><span class="term"><code class="literal">OVERRIDING SYSTEM VALUE</code></span></dt><dd><p>
+ If this clause is specified, then any values supplied for identity
+ columns will override the default sequence-generated values.
+ </p><p>
+ For an identity column defined as <code class="literal">GENERATED ALWAYS</code>,
+ it is an error to insert an explicit value (other than
+ <code class="literal">DEFAULT</code>) without specifying either
+ <code class="literal">OVERRIDING SYSTEM VALUE</code> or <code class="literal">OVERRIDING USER
+ VALUE</code>. (For an identity column defined as
+ <code class="literal">GENERATED BY DEFAULT</code>, <code class="literal">OVERRIDING SYSTEM
+ VALUE</code> is the normal behavior and specifying it does nothing,
+ but <span class="productname">PostgreSQL</span> allows it as an extension.)
+ </p></dd><dt><span class="term"><code class="literal">OVERRIDING USER VALUE</code></span></dt><dd><p>
+ If this clause is specified, then any values supplied for identity
+ columns are ignored and the default sequence-generated values are
+ applied.
+ </p><p>
+ This clause is useful for example when copying values between tables.
+ Writing <code class="literal">INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM
+ tbl1</code> will copy from <code class="literal">tbl1</code> all columns that
+ are not identity columns in <code class="literal">tbl2</code> while values for
+ the identity columns in <code class="literal">tbl2</code> will be generated by
+ the sequences associated with <code class="literal">tbl2</code>.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT VALUES</code></span></dt><dd><p>
+ All columns will be filled with their default values, as if
+ <code class="literal">DEFAULT</code> were explicitly specified for each column.
+ (An <code class="literal">OVERRIDING</code> clause is not permitted in this
+ form.)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
+ An expression or value to assign to the corresponding column.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ The corresponding column will be filled with its default value. An
+ identity column will be filled with a new value generated by the
+ associated sequence. For a generated column, specifying this is
+ permitted but merely specifies the normal behavior of computing the
+ column from its generation expression.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>query</code></em></span></dt><dd><p>
+ A query (<code class="command">SELECT</code> statement) that supplies the
+ rows to be inserted. Refer to the
+ <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>
+ statement for a description of the syntax.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_expression</code></em></span></dt><dd><p>
+ An expression to be computed and returned by the
+ <code class="command">INSERT</code> command after each row is inserted or
+ updated. The expression can use any column names of the table
+ named by <em class="replaceable"><code>table_name</code></em>. Write
+ <code class="literal">*</code> to return all columns of the inserted or updated
+ row(s).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_name</code></em></span></dt><dd><p>
+ A name to use for a returned column.
+ </p></dd></dl></div></div><div class="refsect2" id="SQL-ON-CONFLICT"><h3><code class="literal">ON CONFLICT</code> Clause</h3><a id="id-1.9.3.152.6.3.2" class="indexterm"></a><a id="id-1.9.3.152.6.3.3" class="indexterm"></a><p>
+ The optional <code class="literal">ON CONFLICT</code> clause specifies an
+ alternative action to raising a unique violation or exclusion
+ constraint violation error. For each individual row proposed for
+ insertion, either the insertion proceeds, or, if an
+ <span class="emphasis"><em>arbiter</em></span> constraint or index specified by
+ <em class="parameter"><code>conflict_target</code></em> is violated, the
+ alternative <em class="parameter"><code>conflict_action</code></em> is taken.
+ <code class="literal">ON CONFLICT DO NOTHING</code> simply avoids inserting
+ a row as its alternative action. <code class="literal">ON CONFLICT DO
+ UPDATE</code> updates the existing row that conflicts with the
+ row proposed for insertion as its alternative action.
+ </p><p>
+ <em class="parameter"><code>conflict_target</code></em> can perform
+ <span class="emphasis"><em>unique index inference</em></span>. When performing
+ inference, it consists of one or more <em class="replaceable"><code>index_column_name</code></em> columns and/or
+ <em class="replaceable"><code>index_expression</code></em>
+ expressions, and an optional <em class="replaceable"><code>index_predicate</code></em>. All <em class="replaceable"><code>table_name</code></em> unique indexes that,
+ without regard to order, contain exactly the
+ <em class="parameter"><code>conflict_target</code></em>-specified
+ columns/expressions are inferred (chosen) as arbiter indexes. If
+ an <em class="replaceable"><code>index_predicate</code></em> is
+ specified, it must, as a further requirement for inference,
+ satisfy arbiter indexes. Note that this means a non-partial
+ unique index (a unique index without a predicate) will be inferred
+ (and thus used by <code class="literal">ON CONFLICT</code>) if such an index
+ satisfying every other criteria is available. If an attempt at
+ inference is unsuccessful, an error is raised.
+ </p><p>
+ <code class="literal">ON CONFLICT DO UPDATE</code> guarantees an atomic
+ <code class="command">INSERT</code> or <code class="command">UPDATE</code> outcome;
+ provided there is no independent error, one of those two outcomes
+ is guaranteed, even under high concurrency. This is also known as
+ <em class="firstterm">UPSERT</em> — <span class="quote">“<span class="quote">UPDATE or
+ INSERT</span>”</span>.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>conflict_target</code></em></span></dt><dd><p>
+ Specifies which conflicts <code class="literal">ON CONFLICT</code> takes
+ the alternative action on by choosing <em class="firstterm">arbiter
+ indexes</em>. Either performs <span class="emphasis"><em>unique index
+ inference</em></span>, or names a constraint explicitly. For
+ <code class="literal">ON CONFLICT DO NOTHING</code>, it is optional to
+ specify a <em class="parameter"><code>conflict_target</code></em>; when
+ omitted, conflicts with all usable constraints (and unique
+ indexes) are handled. For <code class="literal">ON CONFLICT DO
+ UPDATE</code>, a <em class="parameter"><code>conflict_target</code></em>
+ <span class="emphasis"><em>must</em></span> be provided.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>conflict_action</code></em></span></dt><dd><p>
+ <em class="parameter"><code>conflict_action</code></em> specifies an
+ alternative <code class="literal">ON CONFLICT</code> action. It can be
+ either <code class="literal">DO NOTHING</code>, or a <code class="literal">DO
+ UPDATE</code> clause specifying the exact details of the
+ <code class="literal">UPDATE</code> action to be performed in case of a
+ conflict. The <code class="literal">SET</code> and
+ <code class="literal">WHERE</code> clauses in <code class="literal">ON CONFLICT DO
+ UPDATE</code> have access to the existing row using the
+ table's name (or an alias), and to the row proposed for insertion
+ using the special <code class="varname">excluded</code> table.
+ <code class="literal">SELECT</code> privilege is required on any column in the
+ target table where corresponding <code class="varname">excluded</code>
+ columns are read.
+ </p><p>
+ Note that the effects of all per-row <code class="literal">BEFORE
+ INSERT</code> triggers are reflected in
+ <code class="varname">excluded</code> values, since those effects may
+ have contributed to the row being excluded from insertion.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_column_name</code></em></span></dt><dd><p>
+ The name of a <em class="replaceable"><code>table_name</code></em> column. Used to
+ infer arbiter indexes. Follows <code class="command">CREATE
+ INDEX</code> format. <code class="literal">SELECT</code> privilege on
+ <em class="replaceable"><code>index_column_name</code></em>
+ is required.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_expression</code></em></span></dt><dd><p>
+ Similar to <em class="replaceable"><code>index_column_name</code></em>, but used to
+ infer expressions on <em class="replaceable"><code>table_name</code></em> columns appearing
+ within index definitions (not simple columns). Follows
+ <code class="command">CREATE INDEX</code> format. <code class="literal">SELECT</code>
+ privilege on any column appearing within <em class="replaceable"><code>index_expression</code></em> is required.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>collation</code></em></span></dt><dd><p>
+ When specified, mandates that corresponding <em class="replaceable"><code>index_column_name</code></em> or
+ <em class="replaceable"><code>index_expression</code></em>
+ use a particular collation in order to be matched during
+ inference. Typically this is omitted, as collations usually
+ do not affect whether or not a constraint violation occurs.
+ Follows <code class="command">CREATE INDEX</code> format.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>opclass</code></em></span></dt><dd><p>
+ When specified, mandates that corresponding <em class="replaceable"><code>index_column_name</code></em> or
+ <em class="replaceable"><code>index_expression</code></em>
+ use particular operator class in order to be matched during
+ inference. Typically this is omitted, as the
+ <span class="emphasis"><em>equality</em></span> semantics are often equivalent
+ across a type's operator classes anyway, or because it's
+ sufficient to trust that the defined unique indexes have the
+ pertinent definition of equality. Follows <code class="command">CREATE
+ INDEX</code> format.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>index_predicate</code></em></span></dt><dd><p>
+ Used to allow inference of partial unique indexes. Any
+ indexes that satisfy the predicate (which need not actually be
+ partial indexes) can be inferred. Follows <code class="command">CREATE
+ INDEX</code> format. <code class="literal">SELECT</code> privilege on any
+ column appearing within <em class="replaceable"><code>index_predicate</code></em> is required.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>constraint_name</code></em></span></dt><dd><p>
+ Explicitly specifies an arbiter
+ <span class="emphasis"><em>constraint</em></span> by name, rather than inferring
+ a constraint or index.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
+ An expression that returns a value of type
+ <code class="type">boolean</code>. Only rows for which this expression
+ returns <code class="literal">true</code> will be updated, although all
+ rows will be locked when the <code class="literal">ON CONFLICT DO UPDATE</code>
+ action is taken. Note that
+ <em class="replaceable"><code>condition</code></em> is evaluated last, after
+ a conflict has been identified as a candidate to update.
+ </p></dd></dl></div><p>
+ Note that exclusion constraints are not supported as arbiters with
+ <code class="literal">ON CONFLICT DO UPDATE</code>. In all cases, only
+ <code class="literal">NOT DEFERRABLE</code> constraints and unique indexes
+ are supported as arbiters.
+ </p><p>
+ <code class="command">INSERT</code> with an <code class="literal">ON CONFLICT DO UPDATE</code>
+ clause is a <span class="quote">“<span class="quote">deterministic</span>”</span> statement. This means
+ that the command will not be allowed to affect any single existing
+ row more than once; a cardinality violation error will be raised
+ when this situation arises. Rows proposed for insertion should
+ not duplicate each other in terms of attributes constrained by an
+ arbiter index or constraint.
+ </p><p>
+ Note that it is currently not supported for the
+ <code class="literal">ON CONFLICT DO UPDATE</code> clause of an
+ <code class="command">INSERT</code> applied to a partitioned table to update the
+ partition key of a conflicting row such that it requires the row be moved
+ to a new partition.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ It is often preferable to use unique index inference rather than
+ naming a constraint directly using <code class="literal">ON CONFLICT ON
+ CONSTRAINT</code> <em class="replaceable"><code>
+ constraint_name</code></em>. Inference will continue to work
+ correctly when the underlying index is replaced by another more
+ or less equivalent index in an overlapping way, for example when
+ using <code class="literal">CREATE UNIQUE INDEX ... CONCURRENTLY</code>
+ before dropping the index being replaced.
+ </p></div></div></div><div class="refsect1" id="id-1.9.3.152.7"><h2>Outputs</h2><p>
+ On successful completion, an <code class="command">INSERT</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+INSERT <em class="replaceable"><code>oid</code></em> <em class="replaceable"><code>count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>count</code></em> is the number of
+ rows inserted or updated. <em class="replaceable"><code>oid</code></em> is always 0 (it
+ used to be the <acronym class="acronym">OID</acronym> assigned to the inserted row if
+ <em class="replaceable"><code>count</code></em> was exactly one and the target table was
+ declared <code class="literal">WITH OIDS</code> and 0 otherwise, but creating a table
+ <code class="literal">WITH OIDS</code> is not supported anymore).
+ </p><p>
+ If the <code class="command">INSERT</code> command contains a <code class="literal">RETURNING</code>
+ clause, the result will be similar to that of a <code class="command">SELECT</code>
+ statement containing the columns and values defined in the
+ <code class="literal">RETURNING</code> list, computed over the row(s) inserted or
+ updated by the command.
+ </p></div><div class="refsect1" id="id-1.9.3.152.8"><h2>Notes</h2><p>
+ If the specified table is a partitioned table, each row is routed to
+ the appropriate partition and inserted into it. If the specified table
+ is a partition, an error will occur if one of the input rows violates
+ the partition constraint.
+ </p><p>
+ You may also wish to consider using <code class="command">MERGE</code>, since that
+ allows mixing <code class="command">INSERT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> within a single statement.
+ See <a class="xref" href="sql-merge.html" title="MERGE"><span class="refentrytitle">MERGE</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.152.9"><h2>Examples</h2><p>
+ Insert a single row into table <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+INSERT INTO films VALUES
+ ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');
+</pre><p>
+ </p><p>
+ In this example, the <code class="literal">len</code> column is
+ omitted and therefore it will have the default value:
+
+</p><pre class="programlisting">
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
+</pre><p>
+ </p><p>
+ This example uses the <code class="literal">DEFAULT</code> clause for
+ the date columns rather than specifying a value:
+
+</p><pre class="programlisting">
+INSERT INTO films VALUES
+ ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes');
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');
+</pre><p>
+ </p><p>
+ To insert a row consisting entirely of default values:
+
+</p><pre class="programlisting">
+INSERT INTO films DEFAULT VALUES;
+</pre><p>
+ </p><p>
+ To insert multiple rows using the multirow <code class="command">VALUES</code> syntax:
+
+</p><pre class="programlisting">
+INSERT INTO films (code, title, did, date_prod, kind) VALUES
+ ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
+ ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
+</pre><p>
+ </p><p>
+ This example inserts some rows into table
+ <code class="literal">films</code> from a table <code class="literal">tmp_films</code>
+ with the same column layout as <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+INSERT INTO films SELECT * FROM tmp_films WHERE date_prod &lt; '2004-05-07';
+</pre><p>
+ </p><p>
+ This example inserts into array columns:
+
+</p><pre class="programlisting">
+-- Create an empty 3x3 gameboard for noughts-and-crosses
+INSERT INTO tictactoe (game, board[1:3][1:3])
+ VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
+-- The subscripts in the above example aren't really needed
+INSERT INTO tictactoe (game, board)
+ VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');
+</pre><p>
+ </p><p>
+ Insert a single row into table <code class="literal">distributors</code>, returning
+ the sequence number generated by the <code class="literal">DEFAULT</code> clause:
+
+</p><pre class="programlisting">
+INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')
+ RETURNING did;
+</pre><p>
+ </p><p>
+ Increment the sales count of the salesperson who manages the
+ account for Acme Corporation, and record the whole updated row
+ along with current time in a log table:
+</p><pre class="programlisting">
+WITH upd AS (
+ UPDATE employees SET sales_count = sales_count + 1 WHERE id =
+ (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
+ RETURNING *
+)
+INSERT INTO employees_log SELECT *, current_timestamp FROM upd;
+</pre><p>
+ </p><p>
+ Insert or update new distributors as appropriate. Assumes a unique
+ index has been defined that constrains values appearing in the
+ <code class="literal">did</code> column. Note that the special
+ <code class="varname">excluded</code> table is used to reference values originally
+ proposed for insertion:
+</p><pre class="programlisting">
+INSERT INTO distributors (did, dname)
+ VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
+ ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
+</pre><p>
+ </p><p>
+ Insert a distributor, or do nothing for rows proposed for insertion
+ when an existing, excluded row (a row with a matching constrained
+ column or columns after before row insert triggers fire) exists.
+ Example assumes a unique index has been defined that constrains
+ values appearing in the <code class="literal">did</code> column:
+</p><pre class="programlisting">
+INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH')
+ ON CONFLICT (did) DO NOTHING;
+</pre><p>
+ </p><p>
+ Insert or update new distributors as appropriate. Example assumes
+ a unique index has been defined that constrains values appearing in
+ the <code class="literal">did</code> column. <code class="literal">WHERE</code> clause is
+ used to limit the rows actually updated (any existing row not
+ updated will still be locked, though):
+</p><pre class="programlisting">
+-- Don't update existing distributors based in a certain ZIP code
+INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
+ ON CONFLICT (did) DO UPDATE
+ SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
+ WHERE d.zipcode &lt;&gt; '21201';
+
+-- Name a constraint directly in the statement (uses associated
+-- index to arbitrate taking the DO NOTHING action)
+INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design')
+ ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;
+</pre><p>
+ </p><p>
+ Insert new distributor if possible; otherwise
+ <code class="literal">DO NOTHING</code>. Example assumes a unique index has been
+ defined that constrains values appearing in the
+ <code class="literal">did</code> column on a subset of rows where the
+ <code class="literal">is_active</code> Boolean column evaluates to
+ <code class="literal">true</code>:
+</p><pre class="programlisting">
+-- This statement could infer a partial unique index on "did"
+-- with a predicate of "WHERE is_active", but it could also
+-- just use a regular unique constraint on "did"
+INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
+ ON CONFLICT (did) WHERE is_active DO NOTHING;
+</pre></div><div class="refsect1" id="id-1.9.3.152.10"><h2>Compatibility</h2><p>
+ <code class="command">INSERT</code> conforms to the SQL standard, except that
+ the <code class="literal">RETURNING</code> clause is a
+ <span class="productname">PostgreSQL</span> extension, as is the ability
+ to use <code class="literal">WITH</code> with <code class="command">INSERT</code>, and the ability to
+ specify an alternative action with <code class="literal">ON CONFLICT</code>.
+ Also, the case in
+ which a column name list is omitted, but not all the columns are
+ filled from the <code class="literal">VALUES</code> clause or <em class="replaceable"><code>query</code></em>,
+ is disallowed by the standard. If you prefer a more SQL standard
+ conforming statement than <code class="literal">ON CONFLICT</code>, see
+ <a class="xref" href="sql-merge.html" title="MERGE"><span class="refentrytitle">MERGE</span></a>.
+ </p><p>
+ The SQL standard specifies that <code class="literal">OVERRIDING SYSTEM VALUE</code>
+ can only be specified if an identity column that is generated always
+ exists. PostgreSQL allows the clause in any case and ignores it if it is
+ not applicable.
+ </p><p>
+ Possible limitations of the <em class="replaceable"><code>query</code></em> clause are documented under
+ <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-importforeignschema.html" title="IMPORT FOREIGN SCHEMA">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-listen.html" title="LISTEN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">IMPORT FOREIGN SCHEMA </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> LISTEN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-keywords-appendix.html b/doc/src/sgml/html/sql-keywords-appendix.html
new file mode 100644
index 0000000..1ea4cf8
--- /dev/null
+++ b/doc/src/sgml/html/sql-keywords-appendix.html
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Appendix C. SQL Key Words</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="datetime-julian-dates.html" title="B.7. Julian Dates" /><link rel="next" href="features.html" title="Appendix D. SQL Conformance" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Appendix C. <acronym class="acronym">SQL</acronym> Key Words</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="datetime-julian-dates.html" title="B.7. Julian Dates">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><th width="60%" align="center">Part VIII. Appendixes</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="features.html" title="Appendix D. SQL Conformance">Next</a></td></tr></table><hr /></div><div class="appendix" id="SQL-KEYWORDS-APPENDIX"><div class="titlepage"><div><div><h2 class="title">Appendix C. <acronym class="acronym">SQL</acronym> Key Words</h2></div></div></div><a id="id-1.11.4.2" class="indexterm"></a><p>
+ <a class="xref" href="sql-keywords-appendix.html#KEYWORDS-TABLE" title="Table C.1. SQL Key Words">Table C.1</a> lists all tokens that are key words
+ in the SQL standard and in <span class="productname">PostgreSQL</span>
+ 15.4. Background information can be found in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS" title="4.1.1. Identifiers and Key Words">Section 4.1.1</a>.
+ (For space reasons, only the latest two versions of the SQL standard, and
+ SQL-92 for historical comparison, are included. The differences between
+ those and the other intermediate standard versions are small.)
+ </p><p>
+ SQL distinguishes between <em class="firstterm">reserved</em> and
+ <em class="firstterm">non-reserved</em> key words. According to the standard,
+ reserved key words
+ are the only real key words; they are never allowed as identifiers.
+ Non-reserved key words only have a special meaning in particular
+ contexts and can be used as identifiers in other contexts. Most
+ non-reserved key words are actually the names of built-in tables
+ and functions specified by SQL. The concept of non-reserved key
+ words essentially only exists to declare that some predefined meaning
+ is attached to a word in some contexts.
+ </p><p>
+ In the <span class="productname">PostgreSQL</span> parser, life is a bit
+ more complicated. There are several different classes of tokens
+ ranging from those that can never be used as an identifier to those
+ that have absolutely no special status in the parser, but are considered
+ ordinary identifiers. (The latter is usually the case for
+ functions specified by SQL.) Even reserved key words are not
+ completely reserved in <span class="productname">PostgreSQL</span>, but
+ can be used as column labels (for example, <code class="literal">SELECT 55 AS
+ CHECK</code>, even though <code class="token">CHECK</code> is a reserved key
+ word).
+ </p><p>
+ In <a class="xref" href="sql-keywords-appendix.html#KEYWORDS-TABLE" title="Table C.1. SQL Key Words">Table C.1</a> in the column for
+ <span class="productname">PostgreSQL</span> we classify as
+ <span class="quote">“<span class="quote">non-reserved</span>”</span> those key words that are explicitly
+ known to the parser but are allowed as column or table names.
+ Some key words that are otherwise
+ non-reserved cannot be used as function or data type names and are
+ marked accordingly. (Most of these words represent built-in
+ functions or data types with special syntax. The function or type
+ is still available but it cannot be redefined by the user.) Labeled
+ <span class="quote">“<span class="quote">reserved</span>”</span> are those tokens that are not allowed as
+ column or table names. Some reserved key words are
+ allowable as names for functions or data types; this is also shown in the
+ table. If not so marked, a reserved key word is only allowed as a
+ column label.
+ A blank entry in this column means that the word is treated as an
+ ordinary identifier by <span class="productname">PostgreSQL</span>.
+ </p><p>
+ Furthermore, while most key words can be used as <span class="quote">“<span class="quote">bare</span>”</span>
+ column labels without writing <code class="literal">AS</code> before them (as
+ described in <a class="xref" href="queries-select-lists.html#QUERIES-COLUMN-LABELS" title="7.3.2. Column Labels">Section 7.3.2</a>), there are a few
+ that require a leading <code class="literal">AS</code> to avoid ambiguity. These
+ are marked in the table as <span class="quote">“<span class="quote">requires <code class="literal">AS</code></span>”</span>.
+ </p><p>
+ As a general rule, if you get spurious parser errors for commands
+ that use any of the listed key words as an identifier, you should
+ try quoting the identifier to see if the problem goes away.
+ </p><p>
+ It is important to understand before studying <a class="xref" href="sql-keywords-appendix.html#KEYWORDS-TABLE" title="Table C.1. SQL Key Words">Table C.1</a> that the fact that a key word is not
+ reserved in <span class="productname">PostgreSQL</span> does not mean that
+ the feature related to the word is not implemented. Conversely, the
+ presence of a key word does not indicate the existence of a feature.
+ </p><div class="table" id="KEYWORDS-TABLE"><p class="title"><strong>Table C.1. <acronym class="acronym">SQL</acronym> Key Words</strong></p><div class="table-contents"><table class="table" summary="SQL Key Words" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /><col class="col5" /></colgroup><thead><tr><th>Key Word</th><th><span class="productname">PostgreSQL</span></th><th>SQL:2016</th><th>SQL:2011</th><th>SQL-92</th></tr></thead><tbody><tr><td><code class="token">A</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ABORT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ABS</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ABSENT</code></td><td> </td><td>reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ABSOLUTE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">ACCESS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ACCORDING</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ACOS</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">ACTION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">ADA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">ADD</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">ADMIN</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">AFTER</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">AGGREGATE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ALL</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ALLOCATE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ALSO</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ALTER</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ALWAYS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ANALYSE</code></td><td>reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ANALYZE</code></td><td>reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">AND</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ANY</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ARE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ARRAY</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ARRAY_AGG</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ARRAY_​MAX_​CARDINALITY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">AS</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ASC</code></td><td>reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">ASENSITIVE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ASIN</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">ASSERTION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">ASSIGNMENT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ASYMMETRIC</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">AT</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ATAN</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">ATOMIC</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ATTACH</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ATTRIBUTE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ATTRIBUTES</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">AUTHORIZATION</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">AVG</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">BACKWARD</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">BASE64</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">BEFORE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">BEGIN</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">BEGIN_FRAME</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">BEGIN_PARTITION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">BERNOULLI</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">BETWEEN</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">BIGINT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">BINARY</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">BIT</code></td><td>non-reserved (cannot be function or type)</td><td> </td><td> </td><td>reserved</td></tr><tr><td><code class="token">BIT_LENGTH</code></td><td> </td><td> </td><td> </td><td>reserved</td></tr><tr><td><code class="token">BLOB</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">BLOCKED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">BOM</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">BOOLEAN</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">BOTH</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">BREADTH</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">BY</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">C</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CACHE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CALL</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CALLED</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CARDINALITY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CASCADE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">CASCADED</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CASE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CAST</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CATALOG</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">CATALOG_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CEIL</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CEILING</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CHAIN</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">CHAINING</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">CHAR</code></td><td>non-reserved (cannot be function or type), requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CHARACTER</code></td><td>non-reserved (cannot be function or type), requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CHARACTERISTICS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">CHARACTERS</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">CHARACTER_LENGTH</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CHARACTER_​SET_​CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CHARACTER_SET_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CHARACTER_SET_SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CHAR_LENGTH</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CHECK</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CHECKPOINT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CLASS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CLASSIFIER</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">CLASS_ORIGIN</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CLOB</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CLOSE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CLUSTER</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">COALESCE</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COBOL</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COLLATE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COLLATION</code></td><td>reserved (can be function or type)</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">COLLATION_CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COLLATION_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COLLATION_SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COLLECT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">COLUMN</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COLUMNS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">COLUMN_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COMMAND_FUNCTION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COMMAND_​FUNCTION_​CODE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">COMMENT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">COMMENTS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">COMMIT</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COMMITTED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">COMPRESSION</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CONCURRENTLY</code></td><td>reserved (can be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CONDITION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CONDITIONAL</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">CONDITION_NUMBER</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CONFIGURATION</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CONFLICT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CONNECT</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CONNECTION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">CONNECTION_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CONSTRAINT</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CONSTRAINTS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">CONSTRAINT_CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CONSTRAINT_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CONSTRAINT_SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CONSTRUCTOR</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">CONTAINS</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CONTENT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">CONTINUE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">CONTROL</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">CONVERSION</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CONVERT</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COPY</code></td><td>non-reserved</td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">CORR</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CORRESPONDING</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COS</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">COSH</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">COST</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">COUNT</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">COVAR_POP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">COVAR_SAMP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CREATE</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CROSS</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CSV</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">CUBE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CUME_DIST</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CURRENT_CATALOG</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_DATE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CURRENT_​DEFAULT_​TRANSFORM_​GROUP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_PATH</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_ROLE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_ROW</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_SCHEMA</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_TIME</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CURRENT_TIMESTAMP</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CURRENT_​TRANSFORM_​GROUP_​FOR_​TYPE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">CURRENT_USER</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CURSOR</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">CURSOR_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">CYCLE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DATA</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">DATABASE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DATALINK</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DATE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DATETIME_​INTERVAL_​CODE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">DATETIME_​INTERVAL_​PRECISION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">DAY</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DB</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DEALLOCATE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DEC</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DECFLOAT</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">DECIMAL</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DECLARE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DEFAULT</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DEFAULTS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DEFERRABLE</code></td><td>reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">DEFERRED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">DEFINE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">DEFINED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DEFINER</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DEGREE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DELETE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DELIMITER</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DELIMITERS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DENSE_RANK</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DEPENDS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DEPTH</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DEREF</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DERIVED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DESC</code></td><td>reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">DESCRIBE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DESCRIPTOR</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">DETACH</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DETERMINISTIC</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DIAGNOSTICS</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">DICTIONARY</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DISABLE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DISCARD</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DISCONNECT</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DISPATCH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DISTINCT</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DLNEWCOPY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLPREVIOUSCOPY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLCOMPLETE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLCOMPLETEONLY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLCOMPLETEWRITE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLPATH</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLPATHONLY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLPATHWRITE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLSCHEME</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLURLSERVER</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DLVALUE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DO</code></td><td>reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">DOCUMENT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">DOMAIN</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">DOUBLE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DROP</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">DYNAMIC</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">DYNAMIC_FUNCTION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">DYNAMIC_​FUNCTION_​CODE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">EACH</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ELEMENT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ELSE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EMPTY</code></td><td> </td><td>reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ENABLE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ENCODING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ENCRYPTED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">END</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">END-EXEC</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">END_FRAME</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">END_PARTITION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ENFORCED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ENUM</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">EQUALS</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ERROR</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">ESCAPE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EVENT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">EVERY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">EXCEPT</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EXCEPTION</code></td><td> </td><td> </td><td> </td><td>reserved</td></tr><tr><td><code class="token">EXCLUDE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">EXCLUDING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">EXCLUSIVE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">EXEC</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EXECUTE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EXISTS</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EXP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">EXPLAIN</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">EXPRESSION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">EXTENSION</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">EXTERNAL</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">EXTRACT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FALSE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FAMILY</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">FETCH</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FILE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">FILTER</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">FINAL</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">FINALIZE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">FINISH</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">FIRST</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">FIRST_VALUE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">FLAG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">FLOAT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FLOOR</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">FOLLOWING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">FOR</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FORCE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">FOREIGN</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FORMAT</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">FORTRAN</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">FORWARD</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">FOUND</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">FRAME_ROW</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">FREE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">FREEZE</code></td><td>reserved (can be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">FROM</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FS</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">FULFILL</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">FULL</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">FUNCTION</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">FUNCTIONS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">FUSION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">G</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">GENERAL</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">GENERATED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">GET</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">GLOBAL</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">GO</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">GOTO</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">GRANT</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">GRANTED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">GREATEST</code></td><td>non-reserved (cannot be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">GROUP</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">GROUPING</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">GROUPS</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">HANDLER</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">HAVING</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">HEADER</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">HEX</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">HIERARCHY</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">HOLD</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">HOUR</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ID</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">IDENTITY</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">IF</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">IGNORE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ILIKE</code></td><td>reserved (can be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">IMMEDIATE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">IMMEDIATELY</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">IMMUTABLE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">IMPLEMENTATION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">IMPLICIT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">IMPORT</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">IN</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INCLUDE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">INCLUDING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INCREMENT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INDENT</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INDEX</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">INDEXES</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">INDICATOR</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INHERIT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">INHERITS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">INITIAL</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">INITIALLY</code></td><td>reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">INLINE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">INNER</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INOUT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">INPUT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">INSENSITIVE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INSERT</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INSTANCE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INSTANTIABLE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INSTEAD</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INTEGER</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INTEGRITY</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">INTERSECT</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INTERSECTION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">INTERVAL</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INTO</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">INVOKER</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">IS</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ISNULL</code></td><td>reserved (can be function or type), requires <code class="literal">AS</code></td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ISOLATION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">JOIN</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">JSON_ARRAY</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_ARRAYAGG</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_EXISTS</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_OBJECT</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_OBJECTAGG</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_QUERY</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_TABLE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_TABLE_PRIMITIVE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">JSON_VALUE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">K</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">KEEP</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">KEY</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">KEYS</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">KEY_MEMBER</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">KEY_TYPE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">LABEL</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LAG</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LANGUAGE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">LARGE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LAST</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">LAST_VALUE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LATERAL</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LEAD</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LEADING</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">LEAKPROOF</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LEAST</code></td><td>non-reserved (cannot be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LEFT</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">LENGTH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">LEVEL</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">LIBRARY</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">LIKE</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">LIKE_REGEX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LIMIT</code></td><td>reserved, requires <code class="literal">AS</code></td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">LINK</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">LISTAGG</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">LISTEN</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LN</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LOAD</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LOCAL</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">LOCALTIME</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LOCALTIMESTAMP</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">LOCATION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">LOCATOR</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">LOCK</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LOCKED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LOG</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">LOG10</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">LOGGED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">LOWER</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">M</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">MAP</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">MAPPING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">MATCH</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">MATCHED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">MATCHES</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">MATCH_NUMBER</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">MATCH_RECOGNIZE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">MATERIALIZED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">MAX</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">MAXVALUE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">MEASURES</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">MEMBER</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">MERGE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">MESSAGE_LENGTH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">MESSAGE_OCTET_LENGTH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">MESSAGE_TEXT</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">METHOD</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">MIN</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">MINUTE</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">MINVALUE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">MOD</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">MODE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">MODIFIES</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">MODULE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">MONTH</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">MORE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">MOVE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">MULTISET</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">MUMPS</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">NAME</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">NAMES</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">NAMESPACE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NATIONAL</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NATURAL</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NCHAR</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NCLOB</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">NESTED</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">NESTING</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NEW</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">NEXT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">NFC</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NFD</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NFKC</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NFKD</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NIL</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NO</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NONE</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">NORMALIZE</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">NORMALIZED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NOT</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NOTHING</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">NOTIFY</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">NOTNULL</code></td><td>reserved (can be function or type), requires <code class="literal">AS</code></td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">NOWAIT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">NTH_VALUE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">NTILE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">NULL</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NULLABLE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">NULLIF</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">NULLS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">NULL_ORDERING</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">NUMBER</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">NUMERIC</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OBJECT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OCCURRENCE</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">OCCURRENCES_REGEX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">OCTETS</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OCTET_LENGTH</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OF</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OFF</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OFFSET</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">OIDS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">OLD</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">OMIT</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">ON</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ONE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">ONLY</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OPEN</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OPERATOR</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">OPTION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">OPTIONS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OR</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ORDER</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ORDERING</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ORDINALITY</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OTHERS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OUT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">OUTER</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OUTPUT</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">OVER</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">OVERFLOW</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">OVERLAPS</code></td><td>reserved (can be function or type), requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">OVERLAY</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">OVERRIDING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">OWNED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">OWNER</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">P</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PAD</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">PARALLEL</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PARAMETER</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PARAMETER_MODE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PARAMETER_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PARAMETER_​ORDINAL_​POSITION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PARAMETER_​SPECIFIC_​CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PARAMETER_​SPECIFIC_​NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PARAMETER_​SPECIFIC_​SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PARSER</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PARTIAL</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">PARTITION</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PASCAL</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">PASS</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PASSING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PASSTHROUGH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PASSWORD</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PAST</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PATH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PATTERN</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PER</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PERCENT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PERCENTILE_CONT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PERCENTILE_DISC</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PERCENT_RANK</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PERIOD</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PERMISSION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PERMUTE</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PIPE</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PLACING</code></td><td>reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PLAN</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PLANS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PLI</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">POLICY</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PORTION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">POSITION</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">POSITION_REGEX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">POWER</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PRECEDES</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">PRECEDING</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">PRECISION</code></td><td>non-reserved (cannot be function or type), requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">PREPARE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">PREPARED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PRESERVE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">PREV</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PRIMARY</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">PRIOR</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">PRIVATE</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PRIVILEGES</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">PROCEDURAL</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PROCEDURE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">PROCEDURES</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PROGRAM</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">PRUNE</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PTF</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">PUBLIC</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">PUBLICATION</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">QUOTE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">QUOTES</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">RANGE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">RANK</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">READ</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">READS</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REAL</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">REASSIGN</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">RECHECK</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">RECOVERY</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RECURSIVE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REF</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REFERENCES</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">REFERENCING</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REFRESH</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">REGR_AVGX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_AVGY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_COUNT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_INTERCEPT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_R2</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_SLOPE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_SXX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_SXY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REGR_SYY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REINDEX</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">RELATIVE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">RELEASE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">RENAME</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">REPEATABLE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">REPLACE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">REPLICA</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">REQUIRING</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RESET</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">RESPECT</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RESTART</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RESTORE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RESTRICT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">RESULT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">RETURN</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">RETURNED_CARDINALITY</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RETURNED_LENGTH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">RETURNED_​OCTET_​LENGTH</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">RETURNED_SQLSTATE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">RETURNING</code></td><td>reserved, requires <code class="literal">AS</code></td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">RETURNS</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">REVOKE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">RIGHT</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ROLE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ROLLBACK</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ROLLUP</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ROUTINE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ROUTINES</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">ROUTINE_CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ROUTINE_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ROUTINE_SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ROW</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">ROWS</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">ROW_COUNT</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">ROW_NUMBER</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">RULE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">RUNNING</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SAVEPOINT</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SCALAR</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SCALE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">SCHEMA</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">SCHEMAS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SCHEMA_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">SCOPE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SCOPE_CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SCOPE_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SCOPE_SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SCROLL</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SEARCH</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SECOND</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SECTION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">SECURITY</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SEEK</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SELECT</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SELECTIVE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SELF</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SEMANTICS</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SENSITIVE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SEQUENCE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SEQUENCES</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SERIALIZABLE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">SERVER</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SERVER_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">SESSION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">SESSION_USER</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SET</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SETOF</code></td><td>non-reserved (cannot be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SETS</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SHARE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SHOW</code></td><td>non-reserved</td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SIMILAR</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SIMPLE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SIN</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SINH</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SIZE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">SKIP</code></td><td>non-reserved</td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SMALLINT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SNAPSHOT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SOME</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SORT_DIRECTION</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SOURCE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SPACE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">SPECIFIC</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SPECIFICTYPE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SPECIFIC_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SQL</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SQLCODE</code></td><td> </td><td> </td><td> </td><td>reserved</td></tr><tr><td><code class="token">SQLERROR</code></td><td> </td><td> </td><td> </td><td>reserved</td></tr><tr><td><code class="token">SQLEXCEPTION</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SQLSTATE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SQLWARNING</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SQRT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">STABLE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STANDALONE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">START</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">STATE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">STATEMENT</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">STATIC</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">STATISTICS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STDDEV_POP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">STDDEV_SAMP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">STDIN</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STDOUT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STORAGE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STORED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STRICT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">STRING</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">STRIP</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">STRUCTURE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">STYLE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">SUBCLASS_ORIGIN</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">SUBMULTISET</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SUBSCRIPTION</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SUBSET</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">SUBSTRING</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SUBSTRING_REGEX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SUCCEEDS</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SUM</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">SUPPORT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SYMMETRIC</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SYSID</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">SYSTEM</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SYSTEM_TIME</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">SYSTEM_USER</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">T</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TABLE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TABLES</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">TABLESAMPLE</code></td><td>reserved (can be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">TABLESPACE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">TABLE_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">TAN</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">TANH</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">TEMP</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">TEMPLATE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">TEMPORARY</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">TEXT</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">THEN</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">THROUGH</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">TIES</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TIME</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TIMESTAMP</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TIMEZONE_HOUR</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TIMEZONE_MINUTE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TO</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TOKEN</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TOP_LEVEL_COUNT</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRAILING</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TRANSACTION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">TRANSACTIONS_​COMMITTED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRANSACTIONS_​ROLLED_​BACK</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRANSACTION_ACTIVE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRANSFORM</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRANSFORMS</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRANSLATE</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TRANSLATE_REGEX</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">TRANSLATION</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TREAT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">TRIGGER</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">TRIGGER_CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRIGGER_NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRIGGER_SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">TRIM</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TRIM_ARRAY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">TRUE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">TRUNCATE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">TRUSTED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">TYPE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">TYPES</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">UESCAPE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">UNBOUNDED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">UNCOMMITTED</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">UNCONDITIONAL</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">UNDER</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">UNENCRYPTED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">UNION</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">UNIQUE</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">UNKNOWN</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">UNLINK</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">UNLISTEN</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">UNLOGGED</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">UNMATCHED</code></td><td> </td><td>reserved</td><td> </td><td> </td></tr><tr><td><code class="token">UNNAMED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td></tr><tr><td><code class="token">UNNEST</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">UNTIL</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">UNTYPED</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">UPDATE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">UPPER</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">URI</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">USAGE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">USER</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">USER_​DEFINED_​TYPE_​CATALOG</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">USER_​DEFINED_​TYPE_​CODE</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">USER_​DEFINED_​TYPE_​NAME</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">USER_​DEFINED_​TYPE_​SCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">USING</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">UTF16</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">UTF32</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">UTF8</code></td><td> </td><td>non-reserved</td><td> </td><td> </td></tr><tr><td><code class="token">VACUUM</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">VALID</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">VALIDATE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">VALIDATOR</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">VALUE</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">VALUES</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">VALUE_OF</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">VARBINARY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">VARCHAR</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">VARIADIC</code></td><td>reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">VARYING</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">VAR_POP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">VAR_SAMP</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">VERBOSE</code></td><td>reserved (can be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">VERSION</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">VERSIONING</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">VIEW</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">VIEWS</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">VOLATILE</code></td><td>non-reserved</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">WHEN</code></td><td>reserved</td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">WHENEVER</code></td><td> </td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">WHERE</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">WHITESPACE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">WIDTH_BUCKET</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">WINDOW</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">WITH</code></td><td>reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">WITHIN</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">WITHOUT</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">WORK</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">WRAPPER</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">WRITE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr><tr><td><code class="token">XML</code></td><td>non-reserved</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLAGG</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLATTRIBUTES</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLBINARY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLCAST</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLCOMMENT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLCONCAT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLDECLARATION</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">XMLDOCUMENT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLELEMENT</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLEXISTS</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLFOREST</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLITERATE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLNAMESPACES</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLPARSE</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLPI</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLQUERY</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLROOT</code></td><td>non-reserved (cannot be function or type)</td><td> </td><td> </td><td> </td></tr><tr><td><code class="token">XMLSCHEMA</code></td><td> </td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">XMLSERIALIZE</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLTABLE</code></td><td>non-reserved (cannot be function or type)</td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLTEXT</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">XMLVALIDATE</code></td><td> </td><td>reserved</td><td>reserved</td><td> </td></tr><tr><td><code class="token">YEAR</code></td><td>non-reserved, requires <code class="literal">AS</code></td><td>reserved</td><td>reserved</td><td>reserved</td></tr><tr><td><code class="token">YES</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td> </td></tr><tr><td><code class="token">ZONE</code></td><td>non-reserved</td><td>non-reserved</td><td>non-reserved</td><td>reserved</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="datetime-julian-dates.html" title="B.7. Julian Dates">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="appendixes.html" title="Part VIII. Appendixes">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="features.html" title="Appendix D. SQL Conformance">Next</a></td></tr><tr><td width="40%" align="left" valign="top">B.7. Julian Dates </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix D. SQL Conformance</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-listen.html b/doc/src/sgml/html/sql-listen.html
new file mode 100644
index 0000000..01da103
--- /dev/null
+++ b/doc/src/sgml/html/sql-listen.html
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>LISTEN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-insert.html" title="INSERT" /><link rel="next" href="sql-load.html" title="LOAD" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">LISTEN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-insert.html" title="INSERT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-load.html" title="LOAD">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-LISTEN"><div class="titlepage"></div><a id="id-1.9.3.153.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">LISTEN</span></h2><p>LISTEN — listen for a notification</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+LISTEN <em class="replaceable"><code>channel</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.153.5"><h2>Description</h2><p>
+ <code class="command">LISTEN</code> registers the current session as a
+ listener on the notification channel named <em class="replaceable"><code>channel</code></em>.
+ If the current session is already registered as a listener for
+ this notification channel, nothing is done.
+ </p><p>
+ Whenever the command <code class="command">NOTIFY <em class="replaceable"><code>channel</code></em></code> is invoked, either
+ by this session or another one connected to the same database, all
+ the sessions currently listening on that notification channel are
+ notified, and each will in turn notify its connected client
+ application.
+ </p><p>
+ A session can be unregistered for a given notification channel with the
+ <code class="command">UNLISTEN</code> command. A session's listen
+ registrations are automatically cleared when the session ends.
+ </p><p>
+ The method a client application must use to detect notification events depends on
+ which <span class="productname">PostgreSQL</span> application programming interface it
+ uses. With the <span class="application">libpq</span> library, the application issues
+ <code class="command">LISTEN</code> as an ordinary SQL command, and then must
+ periodically call the function <code class="function">PQnotifies</code> to find out
+ whether any notification events have been received. Other interfaces such as
+ <span class="application">libpgtcl</span> provide higher-level methods for handling notify events; indeed,
+ with <span class="application">libpgtcl</span> the application programmer should not even issue
+ <code class="command">LISTEN</code> or <code class="command">UNLISTEN</code> directly. See the
+ documentation for the interface you are using for more details.
+ </p></div><div class="refsect1" id="id-1.9.3.153.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>channel</code></em></span></dt><dd><p>
+ Name of a notification channel (any identifier).
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.153.7"><h2>Notes</h2><p>
+ <code class="command">LISTEN</code> takes effect at transaction commit.
+ If <code class="command">LISTEN</code> or <code class="command">UNLISTEN</code> is executed
+ within a transaction that later rolls back, the set of notification
+ channels being listened to is unchanged.
+ </p><p>
+ A transaction that has executed <code class="command">LISTEN</code> cannot be
+ prepared for two-phase commit.
+ </p><p>
+ There is a race condition when first setting up a listening session:
+ if concurrently-committing transactions are sending notify events,
+ exactly which of those will the newly listening session receive?
+ The answer is that the session will receive all events committed after
+ an instant during the transaction's commit step. But that is slightly
+ later than any database state that the transaction could have observed
+ in queries. This leads to the following rule for
+ using <code class="command">LISTEN</code>: first execute (and commit!) that
+ command, then in a new transaction inspect the database state as needed
+ by the application logic, then rely on notifications to find out about
+ subsequent changes to the database state. The first few received
+ notifications might refer to updates already observed in the initial
+ database inspection, but this is usually harmless.
+ </p><p>
+ <a class="xref" href="sql-notify.html" title="NOTIFY"><span class="refentrytitle">NOTIFY</span></a>
+ contains a more extensive
+ discussion of the use of <code class="command">LISTEN</code> and
+ <code class="command">NOTIFY</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.153.8"><h2>Examples</h2><p>
+ Configure and execute a listen/notify sequence from
+ <span class="application">psql</span>:
+
+</p><pre class="programlisting">
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448.
+</pre></div><div class="refsect1" id="id-1.9.3.153.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">LISTEN</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.153.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-notify.html" title="NOTIFY"><span class="refentrytitle">NOTIFY</span></a>, <a class="xref" href="sql-unlisten.html" title="UNLISTEN"><span class="refentrytitle">UNLISTEN</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-insert.html" title="INSERT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-load.html" title="LOAD">Next</a></td></tr><tr><td width="40%" align="left" valign="top">INSERT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> LOAD</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-load.html b/doc/src/sgml/html/sql-load.html
new file mode 100644
index 0000000..a188124
--- /dev/null
+++ b/doc/src/sgml/html/sql-load.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>LOAD</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-listen.html" title="LISTEN" /><link rel="next" href="sql-lock.html" title="LOCK" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">LOAD</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-listen.html" title="LISTEN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-lock.html" title="LOCK">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-LOAD"><div class="titlepage"></div><a id="id-1.9.3.154.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">LOAD</span></h2><p>LOAD — load a shared library file</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+LOAD '<em class="replaceable"><code>filename</code></em>'
+</pre></div><div class="refsect1" id="SQL-LOAD-DESCRIPTION"><h2>Description</h2><p>
+ This command loads a shared library file into the <span class="productname">PostgreSQL</span>
+ server's address space. If the file has been loaded already,
+ the command does nothing. Shared library files that contain C functions
+ are automatically loaded whenever one of their functions is called.
+ Therefore, an explicit <code class="command">LOAD</code> is usually only needed to
+ load a library that modifies the server's behavior through <span class="quote">“<span class="quote">hooks</span>”</span>
+ rather than providing a set of functions.
+ </p><p>
+ The library file name is typically given as just a bare file name,
+ which is sought in the server's library search path (set
+ by <a class="xref" href="runtime-config-client.html#GUC-DYNAMIC-LIBRARY-PATH">dynamic_library_path</a>). Alternatively it can be
+ given as a full path name. In either case the platform's standard shared
+ library file name extension may be omitted.
+ See <a class="xref" href="xfunc-c.html#XFUNC-C-DYNLOAD" title="38.10.1. Dynamic Loading">Section 38.10.1</a> for more information on this topic.
+ </p><a id="id-1.9.3.154.5.4" class="indexterm"></a><p>
+ Non-superusers can only apply <code class="command">LOAD</code> to library files
+ located in <code class="filename">$libdir/plugins/</code> — the specified
+ <em class="replaceable"><code>filename</code></em> must begin
+ with exactly that string. (It is the database administrator's
+ responsibility to ensure that only <span class="quote">“<span class="quote">safe</span>”</span> libraries
+ are installed there.)
+ </p></div><div class="refsect1" id="SQL-LOAD-COMPAT"><h2>Compatibility</h2><p>
+ <code class="command">LOAD</code> is a <span class="productname">PostgreSQL</span>
+ extension.
+ </p></div><div class="refsect1" id="id-1.9.3.154.7"><h2>See Also</h2><p>
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-listen.html" title="LISTEN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-lock.html" title="LOCK">Next</a></td></tr><tr><td width="40%" align="left" valign="top">LISTEN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> LOCK</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-lock.html b/doc/src/sgml/html/sql-lock.html
new file mode 100644
index 0000000..f2b9145
--- /dev/null
+++ b/doc/src/sgml/html/sql-lock.html
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>LOCK</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-load.html" title="LOAD" /><link rel="next" href="sql-merge.html" title="MERGE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">LOCK</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-load.html" title="LOAD">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-merge.html" title="MERGE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-LOCK"><div class="titlepage"></div><a id="id-1.9.3.155.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">LOCK</span></h2><p>LOCK — lock a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+LOCK [ TABLE ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ] [, ...] [ IN <em class="replaceable"><code>lockmode</code></em> MODE ] [ NOWAIT ]
+
+<span class="phrase">where <em class="replaceable"><code>lockmode</code></em> is one of:</span>
+
+ ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
+ | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
+</pre></div><div class="refsect1" id="id-1.9.3.155.5"><h2>Description</h2><p>
+ <code class="command">LOCK TABLE</code> obtains a table-level lock, waiting
+ if necessary for any conflicting locks to be released. If
+ <code class="literal">NOWAIT</code> is specified, <code class="command">LOCK
+ TABLE</code> does not wait to acquire the desired lock: if it
+ cannot be acquired immediately, the command is aborted and an
+ error is emitted. Once obtained, the lock is held for the
+ remainder of the current transaction. (There is no <code class="command">UNLOCK
+ TABLE</code> command; locks are always released at transaction
+ end.)
+ </p><p>
+ When a view is locked, all relations appearing in the view definition
+ query are also locked recursively with the same lock mode.
+ </p><p>
+ When acquiring locks automatically for commands that reference
+ tables, <span class="productname">PostgreSQL</span> always uses the least
+ restrictive lock mode possible. <code class="command">LOCK TABLE</code>
+ provides for cases when you might need more restrictive locking.
+ For example, suppose an application runs a transaction at the
+ <code class="literal">READ COMMITTED</code> isolation level and needs to ensure that
+ data in a table remains stable for the duration of the transaction.
+ To achieve this you could obtain <code class="literal">SHARE</code> lock mode over the
+ table before querying. This will prevent concurrent data changes
+ and ensure subsequent reads of the table see a stable view of
+ committed data, because <code class="literal">SHARE</code> lock mode conflicts with
+ the <code class="literal">ROW EXCLUSIVE</code> lock acquired by writers, and your
+ <code class="command">LOCK TABLE <em class="replaceable"><code>name</code></em> IN SHARE MODE</code>
+ statement will wait until any concurrent holders of <code class="literal">ROW
+ EXCLUSIVE</code> mode locks commit or roll back. Thus, once you
+ obtain the lock, there are no uncommitted writes outstanding;
+ furthermore none can begin until you release the lock.
+ </p><p>
+ To achieve a similar effect when running a transaction at the
+ <code class="literal">REPEATABLE READ</code> or <code class="literal">SERIALIZABLE</code>
+ isolation level, you have to execute the <code class="command">LOCK TABLE</code> statement
+ before executing any <code class="command">SELECT</code> or data modification statement.
+ A <code class="literal">REPEATABLE READ</code> or <code class="literal">SERIALIZABLE</code> transaction's
+ view of data will be frozen when its first
+ <code class="command">SELECT</code> or data modification statement begins. A <code class="command">LOCK
+ TABLE</code> later in the transaction will still prevent concurrent writes
+ — but it won't ensure that what the transaction reads corresponds to
+ the latest committed values.
+ </p><p>
+ If a transaction of this sort is going to change the data in the
+ table, then it should use <code class="literal">SHARE ROW EXCLUSIVE</code> lock mode
+ instead of <code class="literal">SHARE</code> mode. This ensures that only one
+ transaction of this type runs at a time. Without this, a deadlock
+ is possible: two transactions might both acquire <code class="literal">SHARE</code>
+ mode, and then be unable to also acquire <code class="literal">ROW EXCLUSIVE</code>
+ mode to actually perform their updates. (Note that a transaction's
+ own locks never conflict, so a transaction can acquire <code class="literal">ROW
+ EXCLUSIVE</code> mode when it holds <code class="literal">SHARE</code> mode — but not
+ if anyone else holds <code class="literal">SHARE</code> mode.) To avoid deadlocks,
+ make sure all transactions acquire locks on the same objects in the
+ same order, and if multiple lock modes are involved for a single
+ object, then transactions should always acquire the most
+ restrictive mode first.
+ </p><p>
+ More information about the lock modes and locking strategies can be
+ found in <a class="xref" href="explicit-locking.html" title="13.3. Explicit Locking">Section 13.3</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.155.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing table to
+ lock. If <code class="literal">ONLY</code> is specified before the table name, only that
+ table is locked. If <code class="literal">ONLY</code> is not specified, the table and all
+ its descendant tables (if any) are locked. Optionally, <code class="literal">*</code>
+ can be specified after the table name to explicitly indicate that
+ descendant tables are included.
+ </p><p>
+ The command <code class="literal">LOCK TABLE a, b;</code> is equivalent to
+ <code class="literal">LOCK TABLE a; LOCK TABLE b;</code>. The tables are locked
+ one-by-one in the order specified in the <code class="command">LOCK
+ TABLE</code> command.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>lockmode</code></em></span></dt><dd><p>
+ The lock mode specifies which locks this lock conflicts with.
+ Lock modes are described in <a class="xref" href="explicit-locking.html" title="13.3. Explicit Locking">Section 13.3</a>.
+ </p><p>
+ If no lock mode is specified, then <code class="literal">ACCESS
+ EXCLUSIVE</code>, the most restrictive mode, is used.
+ </p></dd><dt><span class="term"><code class="literal">NOWAIT</code></span></dt><dd><p>
+ Specifies that <code class="command">LOCK TABLE</code> should not wait for
+ any conflicting locks to be released: if the specified lock(s)
+ cannot be acquired immediately without waiting, the transaction
+ is aborted.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.155.7"><h2>Notes</h2><p>
+ <code class="literal">LOCK TABLE ... IN ACCESS SHARE MODE</code> requires <code class="literal">SELECT</code>
+ privileges on the target table. <code class="literal">LOCK TABLE ... IN ROW EXCLUSIVE
+ MODE</code> requires <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
+ or <code class="literal">TRUNCATE</code> privileges on the target table. All other forms of
+ <code class="command">LOCK</code> require table-level <code class="literal">UPDATE</code>, <code class="literal">DELETE</code>,
+ or <code class="literal">TRUNCATE</code> privileges.
+ </p><p>
+ The user performing the lock on the view must have the corresponding
+ privilege on the view. In addition, by default, the view's owner must
+ have the relevant privileges on the underlying base relations, whereas the
+ user performing the lock does not need any permissions on the underlying
+ base relations. However, if the view has
+ <code class="literal">security_invoker</code> set to <code class="literal">true</code>
+ (see <a class="link" href="sql-createview.html" title="CREATE VIEW"><code class="command">CREATE VIEW</code></a>),
+ the user performing the lock, rather than the view owner, must have the
+ relevant privileges on the underlying base relations.
+ </p><p>
+ <code class="command">LOCK TABLE</code> is useless outside a transaction block: the lock
+ would remain held only to the completion of the statement. Therefore
+ <span class="productname">PostgreSQL</span> reports an error if <code class="command">LOCK</code>
+ is used outside a transaction block.
+ Use
+ <a class="link" href="sql-begin.html" title="BEGIN"><code class="command">BEGIN</code></a> and
+ <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a>
+ (or <a class="link" href="sql-rollback.html" title="ROLLBACK"><code class="command">ROLLBACK</code></a>)
+ to define a transaction block.
+ </p><p>
+ <code class="command">LOCK TABLE</code> only deals with table-level locks, and so
+ the mode names involving <code class="literal">ROW</code> are all misnomers. These
+ mode names should generally be read as indicating the intention of
+ the user to acquire row-level locks within the locked table. Also,
+ <code class="literal">ROW EXCLUSIVE</code> mode is a shareable table lock. Keep in
+ mind that all the lock modes have identical semantics so far as
+ <code class="command">LOCK TABLE</code> is concerned, differing only in the rules
+ about which modes conflict with which. For information on how to
+ acquire an actual row-level lock, see <a class="xref" href="explicit-locking.html#LOCKING-ROWS" title="13.3.2. Row-Level Locks">Section 13.3.2</a>
+ and <a class="xref" href="sql-select.html#SQL-FOR-UPDATE-SHARE" title="The Locking Clause">The Locking Clause</a>
+ in the <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> documentation.
+ </p></div><div class="refsect1" id="id-1.9.3.155.8"><h2>Examples</h2><p>
+ Obtain a <code class="literal">SHARE</code> lock on a primary key table when going to perform
+ inserts into a foreign key table:
+
+</p><pre class="programlisting">
+BEGIN WORK;
+LOCK TABLE films IN SHARE MODE;
+SELECT id FROM films
+ WHERE name = 'Star Wars: Episode I - The Phantom Menace';
+-- Do ROLLBACK if record was not returned
+INSERT INTO films_user_comments VALUES
+ (_id_, 'GREAT! I was waiting for it for so long!');
+COMMIT WORK;
+</pre><p>
+ </p><p>
+ Take a <code class="literal">SHARE ROW EXCLUSIVE</code> lock on a primary key table when going to perform
+ a delete operation:
+
+</p><pre class="programlisting">
+BEGIN WORK;
+LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
+DELETE FROM films_user_comments WHERE id IN
+ (SELECT id FROM films WHERE rating &lt; 5);
+DELETE FROM films WHERE rating &lt; 5;
+COMMIT WORK;
+</pre></div><div class="refsect1" id="id-1.9.3.155.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">LOCK TABLE</code> in the SQL standard,
+ which instead uses <code class="command">SET TRANSACTION</code> to specify
+ concurrency levels on transactions. <span class="productname">PostgreSQL</span> supports that too;
+ see <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> for details.
+ </p><p>
+ Except for <code class="literal">ACCESS SHARE</code>, <code class="literal">ACCESS EXCLUSIVE</code>,
+ and <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock modes, the
+ <span class="productname">PostgreSQL</span> lock modes and the
+ <code class="command">LOCK TABLE</code> syntax are compatible with those
+ present in <span class="productname">Oracle</span>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-load.html" title="LOAD">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-merge.html" title="MERGE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">LOAD </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> MERGE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-merge.html b/doc/src/sgml/html/sql-merge.html
new file mode 100644
index 0000000..03f7ae1
--- /dev/null
+++ b/doc/src/sgml/html/sql-merge.html
@@ -0,0 +1,380 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>MERGE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-lock.html" title="LOCK" /><link rel="next" href="sql-move.html" title="MOVE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">MERGE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-lock.html" title="LOCK">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-move.html" title="MOVE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-MERGE"><div class="titlepage"></div><a id="id-1.9.3.156.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">MERGE</span></h2><p>MERGE — conditionally insert, update, or delete rows of a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+[ WITH <em class="replaceable"><code>with_query</code></em> [, ...] ]
+MERGE INTO [ ONLY ] <em class="replaceable"><code>target_table_name</code></em> [ * ] [ [ AS ] <em class="replaceable"><code>target_alias</code></em> ]
+USING <em class="replaceable"><code>data_source</code></em> ON <em class="replaceable"><code>join_condition</code></em>
+<em class="replaceable"><code>when_clause</code></em> [...]
+
+<span class="phrase">where <em class="replaceable"><code>data_source</code></em> is:</span>
+
+{ [ ONLY ] <em class="replaceable"><code>source_table_name</code></em> [ * ] | ( <em class="replaceable"><code>source_query</code></em> ) } [ [ AS ] <em class="replaceable"><code>source_alias</code></em> ]
+
+<span class="phrase">and <em class="replaceable"><code>when_clause</code></em> is:</span>
+
+{ WHEN MATCHED [ AND <em class="replaceable"><code>condition</code></em> ] THEN { <em class="replaceable"><code>merge_update</code></em> | <em class="replaceable"><code>merge_delete</code></em> | DO NOTHING } |
+ WHEN NOT MATCHED [ AND <em class="replaceable"><code>condition</code></em> ] THEN { <em class="replaceable"><code>merge_insert</code></em> | DO NOTHING } }
+
+<span class="phrase">and <em class="replaceable"><code>merge_insert</code></em> is:</span>
+
+INSERT [( <em class="replaceable"><code>column_name</code></em> [, ...] )]
+[ OVERRIDING { SYSTEM | USER } VALUE ]
+{ VALUES ( { <em class="replaceable"><code>expression</code></em> | DEFAULT } [, ...] ) | DEFAULT VALUES }
+
+<span class="phrase">and <em class="replaceable"><code>merge_update</code></em> is:</span>
+
+UPDATE SET { <em class="replaceable"><code>column_name</code></em> = { <em class="replaceable"><code>expression</code></em> | DEFAULT } |
+ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) = ( { <em class="replaceable"><code>expression</code></em> | DEFAULT } [, ...] ) } [, ...]
+
+<span class="phrase">and <em class="replaceable"><code>merge_delete</code></em> is:</span>
+
+DELETE
+</pre></div><div class="refsect1" id="id-1.9.3.156.5"><h2>Description</h2><p>
+ <code class="command">MERGE</code> performs actions that modify rows in the
+ <em class="replaceable"><code>target_table_name</code></em>,
+ using the <em class="replaceable"><code>data_source</code></em>.
+ <code class="command">MERGE</code> provides a single <acronym class="acronym">SQL</acronym>
+ statement that can conditionally <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code> or <code class="command">DELETE</code> rows, a task
+ that would otherwise require multiple procedural language statements.
+ </p><p>
+ First, the <code class="command">MERGE</code> command performs a join
+ from <em class="replaceable"><code>data_source</code></em> to
+ <em class="replaceable"><code>target_table_name</code></em>
+ producing zero or more candidate change rows. For each candidate change
+ row, the status of <code class="literal">MATCHED</code> or <code class="literal">NOT MATCHED</code>
+ is set just once, after which <code class="literal">WHEN</code> clauses are evaluated
+ in the order specified. For each candidate change row, the first clause to
+ evaluate as true is executed. No more than one <code class="literal">WHEN</code>
+ clause is executed for any candidate change row.
+ </p><p>
+ <code class="command">MERGE</code> actions have the same effect as
+ regular <code class="command">UPDATE</code>, <code class="command">INSERT</code>, or
+ <code class="command">DELETE</code> commands of the same names. The syntax of
+ those commands is different, notably that there is no <code class="literal">WHERE</code>
+ clause and no table name is specified. All actions refer to the
+ <em class="replaceable"><code>target_table_name</code></em>,
+ though modifications to other tables may be made using triggers.
+ </p><p>
+ When <code class="literal">DO NOTHING</code> is specified, the source row is
+ skipped. Since actions are evaluated in their specified order, <code class="literal">DO
+ NOTHING</code> can be handy to skip non-interesting source rows before
+ more fine-grained handling.
+ </p><p>
+ There is no separate <code class="literal">MERGE</code> privilege.
+ If you specify an update action, you must have the
+ <code class="literal">UPDATE</code> privilege on the column(s)
+ of the <em class="replaceable"><code>target_table_name</code></em>
+ that are referred to in the <code class="literal">SET</code> clause.
+ If you specify an insert action, you must have the <code class="literal">INSERT</code>
+ privilege on the <em class="replaceable"><code>target_table_name</code></em>.
+ If you specify an delete action, you must have the <code class="literal">DELETE</code>
+ privilege on the <em class="replaceable"><code>target_table_name</code></em>.
+ Privileges are tested once at statement start and are checked
+ whether or not particular <code class="literal">WHEN</code> clauses are executed.
+ You will require the <code class="literal">SELECT</code> privilege on the
+ <em class="replaceable"><code>data_source</code></em> and any column(s)
+ of the <em class="replaceable"><code>target_table_name</code></em>
+ referred to in a <code class="literal">condition</code>.
+ </p><p>
+ <code class="command">MERGE</code> is not supported if the
+ <em class="replaceable"><code>target_table_name</code></em> is a
+ materialized view, foreign table, or if it has any
+ rules defined on it.
+ </p></div><div class="refsect1" id="id-1.9.3.156.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>target_table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the target table to merge into.
+ If <code class="literal">ONLY</code> is specified before the table name, matching
+ rows are updated or deleted in the named table only. If
+ <code class="literal">ONLY</code> is not specified, matching rows are also updated
+ or deleted in any tables inheriting from the named table. Optionally,
+ <code class="literal">*</code> can be specified after the table name to explicitly
+ indicate that descendant tables are included. The
+ <code class="literal">ONLY</code> keyword and <code class="literal">*</code> option do not
+ affect insert actions, which always insert into the named table only.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>target_alias</code></em></span></dt><dd><p>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <code class="literal">MERGE INTO foo AS f</code>, the remainder of the
+ <code class="command">MERGE</code> statement must refer to this table as
+ <code class="literal">f</code> not <code class="literal">foo</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the source table, view, or
+ transition table. If <code class="literal">ONLY</code> is specified before the
+ table name, matching rows are included from the named table only. If
+ <code class="literal">ONLY</code> is not specified, matching rows are also included
+ from any tables inheriting from the named table. Optionally,
+ <code class="literal">*</code> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_query</code></em></span></dt><dd><p>
+ A query (<code class="command">SELECT</code> statement or <code class="command">VALUES</code>
+ statement) that supplies the rows to be merged into the
+ <em class="replaceable"><code>target_table_name</code></em>.
+ Refer to the <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>
+ statement or <a class="xref" href="sql-values.html" title="VALUES"><span class="refentrytitle">VALUES</span></a>
+ statement for a description of the syntax.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>source_alias</code></em></span></dt><dd><p>
+ A substitute name for the data source. When an alias is
+ provided, it completely hides the actual name of the table or the fact
+ that a query was issued.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>join_condition</code></em></span></dt><dd><p>
+ <em class="replaceable"><code>join_condition</code></em> is
+ an expression resulting in a value of type
+ <code class="type">boolean</code> (similar to a <code class="literal">WHERE</code>
+ clause) that specifies which rows in the
+ <em class="replaceable"><code>data_source</code></em>
+ match rows in the
+ <em class="replaceable"><code>target_table_name</code></em>.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ Only columns from <em class="replaceable"><code>target_table_name</code></em>
+ that attempt to match <em class="replaceable"><code>data_source</code></em>
+ rows should appear in <em class="replaceable"><code>join_condition</code></em>.
+ <em class="replaceable"><code>join_condition</code></em> subexpressions that
+ only reference <em class="replaceable"><code>target_table_name</code></em>
+ columns can affect which action is taken, often in surprising ways.
+ </p></div></dd><dt><span class="term"><em class="replaceable"><code>when_clause</code></em></span></dt><dd><p>
+ At least one <code class="literal">WHEN</code> clause is required.
+ </p><p>
+ If the <code class="literal">WHEN</code> clause specifies <code class="literal">WHEN MATCHED</code>
+ and the candidate change row matches a row in the
+ <em class="replaceable"><code>target_table_name</code></em>,
+ the <code class="literal">WHEN</code> clause is executed if the
+ <em class="replaceable"><code>condition</code></em> is
+ absent or it evaluates to <code class="literal">true</code>.
+ </p><p>
+ Conversely, if the <code class="literal">WHEN</code> clause specifies
+ <code class="literal">WHEN NOT MATCHED</code>
+ and the candidate change row does not match a row in the
+ <em class="replaceable"><code>target_table_name</code></em>,
+ the <code class="literal">WHEN</code> clause is executed if the
+ <em class="replaceable"><code>condition</code></em> is
+ absent or it evaluates to <code class="literal">true</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
+ An expression that returns a value of type <code class="type">boolean</code>.
+ If this expression for a <code class="literal">WHEN</code> clause
+ returns <code class="literal">true</code>, then the action for that clause
+ is executed for that row.
+ </p><p>
+ A condition on a <code class="literal">WHEN MATCHED</code> clause can refer to columns
+ in both the source and the target relations. A condition on a
+ <code class="literal">WHEN NOT MATCHED</code> clause can only refer to columns from
+ the source relation, since by definition there is no matching target row.
+ Only the system attributes from the target table are accessible.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>merge_insert</code></em></span></dt><dd><p>
+ The specification of an <code class="literal">INSERT</code> action that inserts
+ one row into the target table.
+ The target column names can be listed in any order. If no list of
+ column names is given at all, the default is all the columns of the
+ table in their declared order.
+ </p><p>
+ Each column not present in the explicit or implicit column list will be
+ filled with a default value, either its declared default value
+ or null if there is none.
+ </p><p>
+ If <em class="replaceable"><code>target_table_name</code></em>
+ is a partitioned table, each row is routed to the appropriate partition
+ and inserted into it.
+ If <em class="replaceable"><code>target_table_name</code></em>
+ is a partition, an error will occur if any input row violates the
+ partition constraint.
+ </p><p>
+ Column names may not be specified more than once.
+ <code class="command">INSERT</code> actions cannot contain sub-selects.
+ </p><p>
+ Only one <code class="literal">VALUES</code> clause can be specified.
+ The <code class="literal">VALUES</code> clause can only refer to columns from
+ the source relation, since by definition there is no matching target row.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>merge_update</code></em></span></dt><dd><p>
+ The specification of an <code class="literal">UPDATE</code> action that updates
+ the current row of the <em class="replaceable"><code>target_table_name</code></em>.
+ Column names may not be specified more than once.
+ </p><p>
+ Neither a table name nor a <code class="literal">WHERE</code> clause are allowed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>merge_delete</code></em></span></dt><dd><p>
+ Specifies a <code class="literal">DELETE</code> action that deletes the current row
+ of the <em class="replaceable"><code>target_table_name</code></em>.
+ Do not include the table name or any other clauses, as you would normally
+ do with a <a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a> command.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column in the <em class="replaceable"><code>target_table_name</code></em>. The column name
+ can be qualified with a subfield name or array subscript, if
+ needed. (Inserting into only some fields of a composite
+ column leaves the other fields null.)
+ Do not include the table's name in the specification
+ of a target column.
+ </p></dd><dt><span class="term"><code class="literal">OVERRIDING SYSTEM VALUE</code></span></dt><dd><p>
+ Without this clause, it is an error to specify an explicit value
+ (other than <code class="literal">DEFAULT</code>) for an identity column defined
+ as <code class="literal">GENERATED ALWAYS</code>. This clause overrides that
+ restriction.
+ </p></dd><dt><span class="term"><code class="literal">OVERRIDING USER VALUE</code></span></dt><dd><p>
+ If this clause is specified, then any values supplied for identity
+ columns defined as <code class="literal">GENERATED BY DEFAULT</code> are ignored
+ and the default sequence-generated values are applied.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT VALUES</code></span></dt><dd><p>
+ All columns will be filled with their default values.
+ (An <code class="literal">OVERRIDING</code> clause is not permitted in this
+ form.)
+ </p></dd><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
+ An expression to assign to the column. If used in a
+ <code class="literal">WHEN MATCHED</code> clause, the expression can use values
+ from the original row in the target table, and values from the
+ <code class="literal">data_source</code> row.
+ If used in a <code class="literal">WHEN NOT MATCHED</code> clause, the
+ expression can use values from the <code class="literal">data_source</code>.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Set the column to its default value (which will be <code class="literal">NULL</code>
+ if no specific default expression has been assigned to it).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>with_query</code></em></span></dt><dd><p>
+ The <code class="literal">WITH</code> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <code class="command">MERGE</code>
+ query. See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a> and <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>
+ for details.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.156.7"><h2>Outputs</h2><p>
+ On successful completion, a <code class="command">MERGE</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+MERGE <em class="replaceable"><code>total_count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>total_count</code></em> is the total
+ number of rows changed (whether inserted, updated, or deleted).
+ If <em class="replaceable"><code>total_count</code></em> is 0, no rows
+ were changed in any way.
+ </p></div><div class="refsect1" id="id-1.9.3.156.8"><h2>Notes</h2><p>
+ The following steps take place during the execution of
+ <code class="command">MERGE</code>.
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ Perform any <code class="literal">BEFORE STATEMENT</code> triggers for all
+ actions specified, whether or not their <code class="literal">WHEN</code>
+ clauses match.
+ </p></li><li class="listitem"><p>
+ Perform a join from source to target table.
+ The resulting query will be optimized normally and will produce
+ a set of candidate change rows. For each candidate change row,
+ </p><div class="orderedlist"><ol class="orderedlist" type="a"><li class="listitem"><p>
+ Evaluate whether each row is <code class="literal">MATCHED</code> or
+ <code class="literal">NOT MATCHED</code>.
+ </p></li><li class="listitem"><p>
+ Test each <code class="literal">WHEN</code> condition in the order
+ specified until one returns true.
+ </p></li><li class="listitem"><p>
+ When a condition returns true, perform the following actions:
+ </p><div class="orderedlist"><ol class="orderedlist" type="i"><li class="listitem"><p>
+ Perform any <code class="literal">BEFORE ROW</code> triggers that fire
+ for the action's event type.
+ </p></li><li class="listitem"><p>
+ Perform the specified action, invoking any check constraints on the
+ target table.
+ </p></li><li class="listitem"><p>
+ Perform any <code class="literal">AFTER ROW</code> triggers that fire for
+ the action's event type.
+ </p></li></ol></div></li></ol></div></li><li class="listitem"><p>
+ Perform any <code class="literal">AFTER STATEMENT</code> triggers for actions
+ specified, whether or not they actually occur. This is similar to the
+ behavior of an <code class="command">UPDATE</code> statement that modifies no rows.
+ </p></li></ol></div><p>
+ In summary, statement triggers for an event type (say,
+ <code class="command">INSERT</code>) will be fired whenever we
+ <span class="emphasis"><em>specify</em></span> an action of that kind.
+ In contrast, row-level triggers will fire only for the specific event type
+ being <span class="emphasis"><em>executed</em></span>.
+ So a <code class="command">MERGE</code> command might fire statement triggers for both
+ <code class="command">UPDATE</code> and <code class="command">INSERT</code>, even though only
+ <code class="command">UPDATE</code> row triggers were fired.
+ </p><p>
+ You should ensure that the join produces at most one candidate change row
+ for each target row. In other words, a target row shouldn't join to more
+ than one data source row. If it does, then only one of the candidate change
+ rows will be used to modify the target row; later attempts to modify the
+ row will cause an error.
+ This can also occur if row triggers make changes to the target table
+ and the rows so modified are then subsequently also modified by
+ <code class="command">MERGE</code>.
+ If the repeated action is an <code class="command">INSERT</code>, this will
+ cause a uniqueness violation, while a repeated <code class="command">UPDATE</code>
+ or <code class="command">DELETE</code> will cause a cardinality violation; the
+ latter behavior is required by the <acronym class="acronym">SQL</acronym> standard.
+ This differs from historical <span class="productname">PostgreSQL</span>
+ behavior of joins in <code class="command">UPDATE</code> and
+ <code class="command">DELETE</code> statements where second and subsequent
+ attempts to modify the same row are simply ignored.
+ </p><p>
+ If a <code class="literal">WHEN</code> clause omits an <code class="literal">AND</code>
+ sub-clause, it becomes the final reachable clause of that
+ kind (<code class="literal">MATCHED</code> or <code class="literal">NOT MATCHED</code>).
+ If a later <code class="literal">WHEN</code> clause of that kind
+ is specified it would be provably unreachable and an error is raised.
+ If no final reachable clause is specified of either kind, it is
+ possible that no action will be taken for a candidate change row.
+ </p><p>
+ The order in which rows are generated from the data source is
+ indeterminate by default.
+ A <em class="replaceable"><code>source_query</code></em> can be
+ used to specify a consistent ordering, if required, which might be
+ needed to avoid deadlocks between concurrent transactions.
+ </p><p>
+ There is no <code class="literal">RETURNING</code> clause with
+ <code class="command">MERGE</code>. Actions of <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code> and <code class="command">DELETE</code> cannot contain
+ <code class="literal">RETURNING</code> or <code class="literal">WITH</code> clauses.
+ </p><p>
+ When <code class="command">MERGE</code> is run concurrently with other commands
+ that modify the target table, the usual transaction isolation rules
+ apply; see <a class="xref" href="transaction-iso.html" title="13.2. Transaction Isolation">Section 13.2</a> for an explanation
+ on the behavior at each isolation level.
+ You may also wish to consider using <code class="command">INSERT ... ON CONFLICT</code>
+ as an alternative statement which offers the ability to run an
+ <code class="command">UPDATE</code> if a concurrent <code class="command">INSERT</code>
+ occurs. There are a variety of differences and restrictions between
+ the two statement types and they are not interchangeable.
+ </p></div><div class="refsect1" id="id-1.9.3.156.9"><h2>Examples</h2><p>
+ Perform maintenance on <code class="literal">customer_accounts</code> based
+ upon new <code class="literal">recent_transactions</code>.
+
+</p><pre class="programlisting">
+MERGE INTO customer_account ca
+USING recent_transactions t
+ON t.customer_id = ca.customer_id
+WHEN MATCHED THEN
+ UPDATE SET balance = balance + transaction_value
+WHEN NOT MATCHED THEN
+ INSERT (customer_id, balance)
+ VALUES (t.customer_id, t.transaction_value);
+</pre><p>
+ </p><p>
+ Notice that this would be exactly equivalent to the following
+ statement because the <code class="literal">MATCHED</code> result does not change
+ during execution.
+
+</p><pre class="programlisting">
+MERGE INTO customer_account ca
+USING (SELECT customer_id, transaction_value FROM recent_transactions) AS t
+ON t.customer_id = ca.customer_id
+WHEN MATCHED THEN
+ UPDATE SET balance = balance + transaction_value
+WHEN NOT MATCHED THEN
+ INSERT (customer_id, balance)
+ VALUES (t.customer_id, t.transaction_value);
+</pre><p>
+ </p><p>
+ Attempt to insert a new stock item along with the quantity of stock. If
+ the item already exists, instead update the stock count of the existing
+ item. Don't allow entries that have zero stock.
+</p><pre class="programlisting">
+MERGE INTO wines w
+USING wine_stock_changes s
+ON s.winename = w.winename
+WHEN NOT MATCHED AND s.stock_delta &gt; 0 THEN
+ INSERT VALUES(s.winename, s.stock_delta)
+WHEN MATCHED AND w.stock + s.stock_delta &gt; 0 THEN
+ UPDATE SET stock = w.stock + s.stock_delta
+WHEN MATCHED THEN
+ DELETE;
+</pre><p>
+
+ The <code class="literal">wine_stock_changes</code> table might be, for example, a
+ temporary table recently loaded into the database.
+ </p></div><div class="refsect1" id="id-1.9.3.156.10"><h2>Compatibility</h2><p>
+ This command conforms to the <acronym class="acronym">SQL</acronym> standard.
+ </p><p>
+ The WITH clause and <code class="literal">DO NOTHING</code> action are extensions to
+ the <acronym class="acronym">SQL</acronym> standard.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-lock.html" title="LOCK">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-move.html" title="MOVE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">LOCK </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> MOVE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-move.html b/doc/src/sgml/html/sql-move.html
new file mode 100644
index 0000000..e37ba09
--- /dev/null
+++ b/doc/src/sgml/html/sql-move.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>MOVE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-merge.html" title="MERGE" /><link rel="next" href="sql-notify.html" title="NOTIFY" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">MOVE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-merge.html" title="MERGE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-notify.html" title="NOTIFY">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-MOVE"><div class="titlepage"></div><a id="id-1.9.3.157.1" class="indexterm"></a><a id="id-1.9.3.157.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">MOVE</span></h2><p>MOVE — position a cursor</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+MOVE [ <em class="replaceable"><code>direction</code></em> ] [ FROM | IN ] <em class="replaceable"><code>cursor_name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>direction</code></em> can be one of:</span>
+
+ NEXT
+ PRIOR
+ FIRST
+ LAST
+ ABSOLUTE <em class="replaceable"><code>count</code></em>
+ RELATIVE <em class="replaceable"><code>count</code></em>
+ <em class="replaceable"><code>count</code></em>
+ ALL
+ FORWARD
+ FORWARD <em class="replaceable"><code>count</code></em>
+ FORWARD ALL
+ BACKWARD
+ BACKWARD <em class="replaceable"><code>count</code></em>
+ BACKWARD ALL
+</pre></div><div class="refsect1" id="id-1.9.3.157.6"><h2>Description</h2><p>
+ <code class="command">MOVE</code> repositions a cursor without retrieving any data.
+ <code class="command">MOVE</code> works exactly like the <code class="command">FETCH</code>
+ command, except it only positions the cursor and does not return rows.
+ </p><p>
+ The parameters for the <code class="command">MOVE</code> command are identical to
+ those of the <code class="command">FETCH</code> command; refer to
+ <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a>
+ for details on syntax and usage.
+ </p></div><div class="refsect1" id="id-1.9.3.157.7"><h2>Outputs</h2><p>
+ On successful completion, a <code class="command">MOVE</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+MOVE <em class="replaceable"><code>count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>count</code></em> is the number
+ of rows that a <code class="command">FETCH</code> command with the same parameters
+ would have returned (possibly zero).
+ </p></div><div class="refsect1" id="id-1.9.3.157.8"><h2>Examples</h2><pre class="programlisting">
+BEGIN WORK;
+DECLARE liahona CURSOR FOR SELECT * FROM films;
+
+-- Skip the first 5 rows:
+MOVE FORWARD 5 IN liahona;
+MOVE 5
+
+-- Fetch the 6th row from the cursor liahona:
+FETCH 1 FROM liahona;
+ code | title | did | date_prod | kind | len
+-------+--------+-----+------------+--------+-------
+ P_303 | 48 Hrs | 103 | 1982-10-22 | Action | 01:37
+(1 row)
+
+-- Close the cursor liahona and end the transaction:
+CLOSE liahona;
+COMMIT WORK;
+</pre></div><div class="refsect1" id="id-1.9.3.157.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">MOVE</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.157.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-close.html" title="CLOSE"><span class="refentrytitle">CLOSE</span></a>, <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>, <a class="xref" href="sql-fetch.html" title="FETCH"><span class="refentrytitle">FETCH</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-merge.html" title="MERGE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-notify.html" title="NOTIFY">Next</a></td></tr><tr><td width="40%" align="left" valign="top">MERGE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> NOTIFY</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-notify.html b/doc/src/sgml/html/sql-notify.html
new file mode 100644
index 0000000..9852412
--- /dev/null
+++ b/doc/src/sgml/html/sql-notify.html
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>NOTIFY</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-move.html" title="MOVE" /><link rel="next" href="sql-prepare.html" title="PREPARE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">NOTIFY</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-move.html" title="MOVE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-prepare.html" title="PREPARE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-NOTIFY"><div class="titlepage"></div><a id="id-1.9.3.158.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">NOTIFY</span></h2><p>NOTIFY — generate a notification</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+NOTIFY <em class="replaceable"><code>channel</code></em> [ , <em class="replaceable"><code>payload</code></em> ]
+</pre></div><div class="refsect1" id="id-1.9.3.158.5"><h2>Description</h2><p>
+ The <code class="command">NOTIFY</code> command sends a notification event together
+ with an optional <span class="quote">“<span class="quote">payload</span>”</span> string to each client application that
+ has previously executed
+ <code class="command">LISTEN <em class="replaceable"><code>channel</code></em></code>
+ for the specified channel name in the current database.
+ Notifications are visible to all users.
+ </p><p>
+ <code class="command">NOTIFY</code> provides a simple
+ interprocess communication mechanism for a collection of processes
+ accessing the same <span class="productname">PostgreSQL</span> database.
+ A payload string can be sent along with the notification, and
+ higher-level mechanisms for passing structured data can be built by using
+ tables in the database to pass additional data from notifier to listener(s).
+ </p><p>
+ The information passed to the client for a notification event includes the
+ notification channel
+ name, the notifying session's server process <acronym class="acronym">PID</acronym>, and the
+ payload string, which is an empty string if it has not been specified.
+ </p><p>
+ It is up to the database designer to define the channel names that will
+ be used in a given database and what each one means.
+ Commonly, the channel name is the same as the name of some table in
+ the database, and the notify event essentially means, <span class="quote">“<span class="quote">I changed this table,
+ take a look at it to see what's new</span>”</span>. But no such association is enforced by
+ the <code class="command">NOTIFY</code> and <code class="command">LISTEN</code> commands. For
+ example, a database designer could use several different channel names
+ to signal different sorts of changes to a single table. Alternatively,
+ the payload string could be used to differentiate various cases.
+ </p><p>
+ When <code class="command">NOTIFY</code> is used to signal the occurrence of changes
+ to a particular table, a useful programming technique is to put the
+ <code class="command">NOTIFY</code> in a statement trigger that is triggered by table updates.
+ In this way, notification happens automatically when the table is changed,
+ and the application programmer cannot accidentally forget to do it.
+ </p><p>
+ <code class="command">NOTIFY</code> interacts with SQL transactions in some important
+ ways. Firstly, if a <code class="command">NOTIFY</code> is executed inside a
+ transaction, the notify events are not delivered until and unless the
+ transaction is committed. This is appropriate, since if the transaction
+ is aborted, all the commands within it have had no
+ effect, including <code class="command">NOTIFY</code>. But it can be disconcerting if one
+ is expecting the notification events to be delivered immediately. Secondly, if
+ a listening session receives a notification signal while it is within a transaction,
+ the notification event will not be delivered to its connected client until just
+ after the transaction is completed (either committed or aborted). Again, the
+ reasoning is that if a notification were delivered within a transaction that was
+ later aborted, one would want the notification to be undone somehow —
+ but
+ the server cannot <span class="quote">“<span class="quote">take back</span>”</span> a notification once it has sent it to the client.
+ So notification events are only delivered between transactions. The upshot of this
+ is that applications using <code class="command">NOTIFY</code> for real-time signaling
+ should try to keep their transactions short.
+ </p><p>
+ If the same channel name is signaled multiple times with identical
+ payload strings within the same transaction, only one instance of the
+ notification event is delivered to listeners.
+ On the other hand, notifications with distinct payload strings will
+ always be delivered as distinct notifications. Similarly, notifications from
+ different transactions will never get folded into one notification.
+ Except for dropping later instances of duplicate notifications,
+ <code class="command">NOTIFY</code> guarantees that notifications from the same
+ transaction get delivered in the order they were sent. It is also
+ guaranteed that messages from different transactions are delivered in
+ the order in which the transactions committed.
+ </p><p>
+ It is common for a client that executes <code class="command">NOTIFY</code>
+ to be listening on the same notification channel itself. In that case
+ it will get back a notification event, just like all the other
+ listening sessions. Depending on the application logic, this could
+ result in useless work, for example, reading a database table to
+ find the same updates that that session just wrote out. It is
+ possible to avoid such extra work by noticing whether the notifying
+ session's server process <acronym class="acronym">PID</acronym> (supplied in the
+ notification event message) is the same as one's own session's
+ <acronym class="acronym">PID</acronym> (available from <span class="application">libpq</span>). When they
+ are the same, the notification event is one's own work bouncing
+ back, and can be ignored.
+ </p></div><div class="refsect1" id="id-1.9.3.158.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>channel</code></em></span></dt><dd><p>
+ Name of the notification channel to be signaled (any identifier).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>payload</code></em></span></dt><dd><p>
+ The <span class="quote">“<span class="quote">payload</span>”</span> string to be communicated along with the
+ notification. This must be specified as a simple string literal.
+ In the default configuration it must be shorter than 8000 bytes.
+ (If binary data or large amounts of information need to be communicated,
+ it's best to put it in a database table and send the key of the record.)
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.158.7"><h2>Notes</h2><p>
+ There is a queue that holds notifications that have been sent but not
+ yet processed by all listening sessions. If this queue becomes full,
+ transactions calling <code class="command">NOTIFY</code> will fail at commit.
+ The queue is quite large (8GB in a standard installation) and should be
+ sufficiently sized for almost every use case. However, no cleanup can take
+ place if a session executes <code class="command">LISTEN</code> and then enters a
+ transaction for a very long time. Once the queue is half full you will see
+ warnings in the log file pointing you to the session that is preventing
+ cleanup. In this case you should make sure that this session ends its
+ current transaction so that cleanup can proceed.
+ </p><p>
+ The function <code class="function">pg_notification_queue_usage</code> returns the
+ fraction of the queue that is currently occupied by pending notifications.
+ See <a class="xref" href="functions-info.html" title="9.26. System Information Functions and Operators">Section 9.26</a> for more information.
+ </p><p>
+ A transaction that has executed <code class="command">NOTIFY</code> cannot be
+ prepared for two-phase commit.
+ </p><div class="refsect2" id="id-1.9.3.158.7.5"><h3>pg_notify</h3><a id="id-1.9.3.158.7.5.2" class="indexterm"></a><p>
+ To send a notification you can also use the function
+ <code class="literal"><code class="function">pg_notify</code>(<code class="type">text</code>,
+ <code class="type">text</code>)</code>. The function takes the channel name as the
+ first argument and the payload as the second. The function is much easier
+ to use than the <code class="command">NOTIFY</code> command if you need to work with
+ non-constant channel names and payloads.
+ </p></div></div><div class="refsect1" id="id-1.9.3.158.8"><h2>Examples</h2><p>
+ Configure and execute a listen/notify sequence from
+ <span class="application">psql</span>:
+
+</p><pre class="programlisting">
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448.
+NOTIFY virtual, 'This is the payload';
+Asynchronous notification "virtual" with payload "This is the payload" received from server process with PID 8448.
+
+LISTEN foo;
+SELECT pg_notify('fo' || 'o', 'pay' || 'load');
+Asynchronous notification "foo" with payload "payload" received from server process with PID 14728.
+</pre></div><div class="refsect1" id="id-1.9.3.158.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">NOTIFY</code> statement in the SQL
+ standard.
+ </p></div><div class="refsect1" id="id-1.9.3.158.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-listen.html" title="LISTEN"><span class="refentrytitle">LISTEN</span></a>, <a class="xref" href="sql-unlisten.html" title="UNLISTEN"><span class="refentrytitle">UNLISTEN</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-move.html" title="MOVE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-prepare.html" title="PREPARE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">MOVE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> PREPARE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-prepare-transaction.html b/doc/src/sgml/html/sql-prepare-transaction.html
new file mode 100644
index 0000000..289d007
--- /dev/null
+++ b/doc/src/sgml/html/sql-prepare-transaction.html
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PREPARE TRANSACTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-prepare.html" title="PREPARE" /><link rel="next" href="sql-reassign-owned.html" title="REASSIGN OWNED" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">PREPARE TRANSACTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-prepare.html" title="PREPARE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-reassign-owned.html" title="REASSIGN OWNED">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-PREPARE-TRANSACTION"><div class="titlepage"></div><a id="id-1.9.3.160.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">PREPARE TRANSACTION</span></h2><p>PREPARE TRANSACTION — prepare the current transaction for two-phase commit</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+PREPARE TRANSACTION <em class="replaceable"><code>transaction_id</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.160.5"><h2>Description</h2><p>
+ <code class="command">PREPARE TRANSACTION</code> prepares the current transaction
+ for two-phase commit. After this command, the transaction is no longer
+ associated with the current session; instead, its state is fully stored on
+ disk, and there is a very high probability that it can be committed
+ successfully, even if a database crash occurs before the commit is
+ requested.
+ </p><p>
+ Once prepared, a transaction can later be committed or rolled back
+ with <a class="link" href="sql-commit-prepared.html" title="COMMIT PREPARED"><code class="command">COMMIT PREPARED</code></a>
+ or <a class="link" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED"><code class="command">ROLLBACK PREPARED</code></a>,
+ respectively. Those commands can be issued from any session, not
+ only the one that executed the original transaction.
+ </p><p>
+ From the point of view of the issuing session, <code class="command">PREPARE
+ TRANSACTION</code> is not unlike a <code class="command">ROLLBACK</code> command:
+ after executing it, there is no active current transaction, and the
+ effects of the prepared transaction are no longer visible. (The effects
+ will become visible again if the transaction is committed.)
+ </p><p>
+ If the <code class="command">PREPARE TRANSACTION</code> command fails for any
+ reason, it becomes a <code class="command">ROLLBACK</code>: the current transaction
+ is canceled.
+ </p></div><div class="refsect1" id="id-1.9.3.160.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>transaction_id</code></em></span></dt><dd><p>
+ An arbitrary identifier that later identifies this transaction for
+ <code class="command">COMMIT PREPARED</code> or <code class="command">ROLLBACK PREPARED</code>.
+ The identifier must be written as a string literal, and must be
+ less than 200 bytes long. It must not be the same as the identifier
+ used for any currently prepared transaction.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.160.7"><h2>Notes</h2><p>
+ <code class="command">PREPARE TRANSACTION</code> is not intended for use in applications
+ or interactive sessions. Its purpose is to allow an external
+ transaction manager to perform atomic global transactions across multiple
+ databases or other transactional resources. Unless you're writing a
+ transaction manager, you probably shouldn't be using <code class="command">PREPARE
+ TRANSACTION</code>.
+ </p><p>
+ This command must be used inside a transaction block. Use <a class="link" href="sql-begin.html" title="BEGIN"><code class="command">BEGIN</code></a> to start one.
+ </p><p>
+ It is not currently allowed to <code class="command">PREPARE</code> a transaction that
+ has executed any operations involving temporary tables or the session's
+ temporary namespace, created any cursors <code class="literal">WITH HOLD</code>, or
+ executed <code class="command">LISTEN</code>, <code class="command">UNLISTEN</code>, or
+ <code class="command">NOTIFY</code>.
+ Those features are too tightly
+ tied to the current session to be useful in a transaction to be prepared.
+ </p><p>
+ If the transaction modified any run-time parameters with <code class="command">SET</code>
+ (without the <code class="literal">LOCAL</code> option),
+ those effects persist after <code class="command">PREPARE TRANSACTION</code>, and will not
+ be affected by any later <code class="command">COMMIT PREPARED</code> or
+ <code class="command">ROLLBACK PREPARED</code>. Thus, in this one respect
+ <code class="command">PREPARE TRANSACTION</code> acts more like <code class="command">COMMIT</code> than
+ <code class="command">ROLLBACK</code>.
+ </p><p>
+ All currently available prepared transactions are listed in the
+ <a class="link" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts"><code class="structname">pg_prepared_xacts</code></a>
+ system view.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is unwise to leave transactions in the prepared state for a long time.
+ This will interfere with the ability of <code class="command">VACUUM</code> to reclaim
+ storage, and in extreme cases could cause the database to shut down
+ to prevent transaction ID wraparound (see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>). Keep in mind also that the transaction
+ continues to hold whatever locks it held. The intended usage of the
+ feature is that a prepared transaction will normally be committed or
+ rolled back as soon as an external transaction manager has verified that
+ other databases are also prepared to commit.
+ </p><p>
+ If you have not set up an external transaction manager to track prepared
+ transactions and ensure they get closed out promptly, it is best to keep
+ the prepared-transaction feature disabled by setting
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PREPARED-TRANSACTIONS">max_prepared_transactions</a> to zero. This will
+ prevent accidental creation of prepared transactions that might then
+ be forgotten and eventually cause problems.
+ </p></div></div><div class="refsect1" id="SQL-PREPARE-TRANSACTION-EXAMPLES"><h2>Examples</h2><p>
+ Prepare the current transaction for two-phase commit, using
+ <code class="literal">foobar</code> as the transaction identifier:
+
+</p><pre class="programlisting">
+PREPARE TRANSACTION 'foobar';
+</pre></div><div class="refsect1" id="id-1.9.3.160.9"><h2>Compatibility</h2><p>
+ <code class="command">PREPARE TRANSACTION</code> is a
+ <span class="productname">PostgreSQL</span> extension. It is intended for use by
+ external transaction management systems, some of which are covered by
+ standards (such as X/Open XA), but the SQL side of those systems is not
+ standardized.
+ </p></div><div class="refsect1" id="id-1.9.3.160.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-commit-prepared.html" title="COMMIT PREPARED"><span class="refentrytitle">COMMIT PREPARED</span></a>, <a class="xref" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED"><span class="refentrytitle">ROLLBACK PREPARED</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-prepare.html" title="PREPARE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-reassign-owned.html" title="REASSIGN OWNED">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PREPARE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> REASSIGN OWNED</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-prepare.html b/doc/src/sgml/html/sql-prepare.html
new file mode 100644
index 0000000..cbc1307
--- /dev/null
+++ b/doc/src/sgml/html/sql-prepare.html
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>PREPARE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-notify.html" title="NOTIFY" /><link rel="next" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">PREPARE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-notify.html" title="NOTIFY">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-PREPARE"><div class="titlepage"></div><a id="id-1.9.3.159.1" class="indexterm"></a><a id="id-1.9.3.159.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">PREPARE</span></h2><p>PREPARE — prepare a statement for execution</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+PREPARE <em class="replaceable"><code>name</code></em> [ ( <em class="replaceable"><code>data_type</code></em> [, ...] ) ] AS <em class="replaceable"><code>statement</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.159.6"><h2>Description</h2><p>
+ <code class="command">PREPARE</code> creates a prepared statement. A prepared
+ statement is a server-side object that can be used to optimize
+ performance. When the <code class="command">PREPARE</code> statement is
+ executed, the specified statement is parsed, analyzed, and rewritten.
+ When an <code class="command">EXECUTE</code> command is subsequently
+ issued, the prepared statement is planned and executed. This division
+ of labor avoids repetitive parse analysis work, while allowing
+ the execution plan to depend on the specific parameter values supplied.
+ </p><p>
+ Prepared statements can take parameters: values that are
+ substituted into the statement when it is executed. When creating
+ the prepared statement, refer to parameters by position, using
+ <code class="literal">$1</code>, <code class="literal">$2</code>, etc. A corresponding list of
+ parameter data types can optionally be specified. When a
+ parameter's data type is not specified or is declared as
+ <code class="literal">unknown</code>, the type is inferred from the context
+ in which the parameter is first referenced (if possible). When executing the
+ statement, specify the actual values for these parameters in the
+ <code class="command">EXECUTE</code> statement. Refer to <a class="xref" href="sql-execute.html" title="EXECUTE"><span class="refentrytitle">EXECUTE</span></a> for more
+ information about that.
+ </p><p>
+ Prepared statements only last for the duration of the current
+ database session. When the session ends, the prepared statement is
+ forgotten, so it must be recreated before being used again. This
+ also means that a single prepared statement cannot be used by
+ multiple simultaneous database clients; however, each client can create
+ their own prepared statement to use. Prepared statements can be
+ manually cleaned up using the <a class="link" href="sql-deallocate.html" title="DEALLOCATE"><code class="command">DEALLOCATE</code></a> command.
+ </p><p>
+ Prepared statements potentially have the largest performance advantage
+ when a single session is being used to execute a large number of similar
+ statements. The performance difference will be particularly
+ significant if the statements are complex to plan or rewrite, e.g.,
+ if the query involves a join of many tables or requires
+ the application of several rules. If the statement is relatively simple
+ to plan and rewrite but relatively expensive to execute, the
+ performance advantage of prepared statements will be less noticeable.
+ </p></div><div class="refsect1" id="id-1.9.3.159.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ An arbitrary name given to this particular prepared
+ statement. It must be unique within a single session and is
+ subsequently used to execute or deallocate a previously prepared
+ statement.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>data_type</code></em></span></dt><dd><p>
+ The data type of a parameter to the prepared statement. If the
+ data type of a particular parameter is unspecified or is
+ specified as <code class="literal">unknown</code>, it will be inferred
+ from the context in which the parameter is first referenced. To refer to the
+ parameters in the prepared statement itself, use
+ <code class="literal">$1</code>, <code class="literal">$2</code>, etc.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>statement</code></em></span></dt><dd><p>
+ Any <code class="command">SELECT</code>, <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">MERGE</code>, or <code class="command">VALUES</code>
+ statement.
+ </p></dd></dl></div></div><div class="refsect1" id="SQL-PREPARE-NOTES"><h2>Notes</h2><p>
+ A prepared statement can be executed with either a <em class="firstterm">generic
+ plan</em> or a <em class="firstterm">custom plan</em>. A generic
+ plan is the same across all executions, while a custom plan is generated
+ for a specific execution using the parameter values given in that call.
+ Use of a generic plan avoids planning overhead, but in some situations
+ a custom plan will be much more efficient to execute because the planner
+ can make use of knowledge of the parameter values. (Of course, if the
+ prepared statement has no parameters, then this is moot and a generic
+ plan is always used.)
+ </p><p>
+ By default (that is, when <a class="xref" href="runtime-config-query.html#GUC-PLAN-CACHE_MODE">plan_cache_mode</a> is set
+ to <code class="literal">auto</code>), the server will automatically choose
+ whether to use a generic or custom plan for a prepared statement that
+ has parameters. The current rule for this is that the first five
+ executions are done with custom plans and the average estimated cost of
+ those plans is calculated. Then a generic plan is created and its
+ estimated cost is compared to the average custom-plan cost. Subsequent
+ executions use the generic plan if its cost is not so much higher than
+ the average custom-plan cost as to make repeated replanning seem
+ preferable.
+ </p><p>
+ This heuristic can be overridden, forcing the server to use either
+ generic or custom plans, by setting <code class="varname">plan_cache_mode</code>
+ to <code class="literal">force_generic_plan</code>
+ or <code class="literal">force_custom_plan</code> respectively.
+ This setting is primarily useful if the generic plan's cost estimate
+ is badly off for some reason, allowing it to be chosen even though
+ its actual cost is much more than that of a custom plan.
+ </p><p>
+ To examine the query plan <span class="productname">PostgreSQL</span> is using
+ for a prepared statement, use <a class="link" href="sql-explain.html" title="EXPLAIN"><code class="command">EXPLAIN</code></a>, for example
+</p><pre class="programlisting">
+EXPLAIN EXECUTE <em class="replaceable"><code>name</code></em>(<em class="replaceable"><code>parameter_values</code></em>);
+</pre><p>
+ If a generic plan is in use, it will contain parameter symbols
+ <code class="literal">$<em class="replaceable"><code>n</code></em></code>, while a custom plan
+ will have the supplied parameter values substituted into it.
+ </p><p>
+ For more information on query planning and the statistics collected
+ by <span class="productname">PostgreSQL</span> for that purpose, see
+ the <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a>
+ documentation.
+ </p><p>
+ Although the main point of a prepared statement is to avoid repeated parse
+ analysis and planning of the statement, <span class="productname">PostgreSQL</span> will
+ force re-analysis and re-planning of the statement before using it
+ whenever database objects used in the statement have undergone
+ definitional (DDL) changes or their planner statistics have
+ been updated since the previous use of the prepared
+ statement. Also, if the value of <a class="xref" href="runtime-config-client.html#GUC-SEARCH-PATH">search_path</a> changes
+ from one use to the next, the statement will be re-parsed using the new
+ <code class="varname">search_path</code>. (This latter behavior is new as of
+ <span class="productname">PostgreSQL</span> 9.3.) These rules make use of a
+ prepared statement semantically almost equivalent to re-submitting the
+ same query text over and over, but with a performance benefit if no object
+ definitions are changed, especially if the best plan remains the same
+ across uses. An example of a case where the semantic equivalence is not
+ perfect is that if the statement refers to a table by an unqualified name,
+ and then a new table of the same name is created in a schema appearing
+ earlier in the <code class="varname">search_path</code>, no automatic re-parse will occur
+ since no object used in the statement changed. However, if some other
+ change forces a re-parse, the new table will be referenced in subsequent
+ uses.
+ </p><p>
+ You can see all prepared statements available in the session by querying the
+ <a class="link" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements"><code class="structname">pg_prepared_statements</code></a>
+ system view.
+ </p></div><div class="refsect1" id="SQL-PREPARE-EXAMPLES"><h2>Examples</h2><p>
+ Create a prepared statement for an <code class="command">INSERT</code>
+ statement, and then execute it:
+</p><pre class="programlisting">
+PREPARE fooplan (int, text, bool, numeric) AS
+ INSERT INTO foo VALUES($1, $2, $3, $4);
+EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
+</pre><p>
+ </p><p>
+ Create a prepared statement for a <code class="command">SELECT</code>
+ statement, and then execute it:
+</p><pre class="programlisting">
+PREPARE usrrptplan (int) AS
+ SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid
+ AND l.date = $2;
+EXECUTE usrrptplan(1, current_date);
+</pre><p>
+
+ In this example, the data type of the second parameter is not specified,
+ so it is inferred from the context in which <code class="literal">$2</code> is used.
+ </p></div><div class="refsect1" id="id-1.9.3.159.10"><h2>Compatibility</h2><p>
+ The SQL standard includes a <code class="command">PREPARE</code> statement,
+ but it is only for use in embedded SQL. This version of the
+ <code class="command">PREPARE</code> statement also uses a somewhat different
+ syntax.
+ </p></div><div class="refsect1" id="id-1.9.3.159.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-deallocate.html" title="DEALLOCATE"><span class="refentrytitle">DEALLOCATE</span></a>, <a class="xref" href="sql-execute.html" title="EXECUTE"><span class="refentrytitle">EXECUTE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-notify.html" title="NOTIFY">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">NOTIFY </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> PREPARE TRANSACTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-reassign-owned.html b/doc/src/sgml/html/sql-reassign-owned.html
new file mode 100644
index 0000000..f8c4380
--- /dev/null
+++ b/doc/src/sgml/html/sql-reassign-owned.html
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>REASSIGN OWNED</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION" /><link rel="next" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">REASSIGN OWNED</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-REASSIGN-OWNED"><div class="titlepage"></div><a id="id-1.9.3.161.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">REASSIGN OWNED</span></h2><p>REASSIGN OWNED — change the ownership of database objects owned by a database role</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+REASSIGN OWNED BY { <em class="replaceable"><code>old_role</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...]
+ TO { <em class="replaceable"><code>new_role</code></em> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</pre></div><div class="refsect1" id="id-1.9.3.161.5"><h2>Description</h2><p>
+ <code class="command">REASSIGN OWNED</code> instructs the system to change
+ the ownership of database objects owned by any of the
+ <em class="replaceable"><code>old_roles</code></em> to
+ <em class="replaceable"><code>new_role</code></em>.
+ </p></div><div class="refsect1" id="id-1.9.3.161.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>old_role</code></em></span></dt><dd><p>
+ The name of a role. The ownership of all the objects within the
+ current database, and of all shared objects (databases, tablespaces),
+ owned by this role will be reassigned to
+ <em class="replaceable"><code>new_role</code></em>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_role</code></em></span></dt><dd><p>
+ The name of the role that will be made the new owner of the
+ affected objects.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.161.7"><h2>Notes</h2><p>
+ <code class="command">REASSIGN OWNED</code> is often used to prepare for the
+ removal of one or more roles. Because <code class="command">REASSIGN
+ OWNED</code> does not affect objects within other databases,
+ it is usually necessary to execute this command in each database
+ that contains objects owned by a role that is to be removed.
+ </p><p>
+ <code class="command">REASSIGN OWNED</code> requires membership on both the
+ source role(s) and the target role.
+ </p><p>
+ The <a class="link" href="sql-drop-owned.html" title="DROP OWNED"><code class="command">DROP OWNED</code></a> command is an alternative that
+ simply drops all the database objects owned by one or more roles.
+ </p><p>
+ The <code class="command">REASSIGN OWNED</code> command does not affect any
+ privileges granted to
+ the <em class="replaceable"><code>old_roles</code></em> on objects
+ that are not owned by them. Likewise, it does not affect default
+ privileges created with <code class="command">ALTER DEFAULT PRIVILEGES</code>.
+ Use <code class="command">DROP OWNED</code> to revoke such privileges.
+ </p><p>
+ See <a class="xref" href="role-removal.html" title="22.4. Dropping Roles">Section 22.4</a> for more discussion.
+ </p></div><div class="refsect1" id="id-1.9.3.161.8"><h2>Compatibility</h2><p>
+ The <code class="command">REASSIGN OWNED</code> command is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.161.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-drop-owned.html" title="DROP OWNED"><span class="refentrytitle">DROP OWNED</span></a>, <a class="xref" href="sql-droprole.html" title="DROP ROLE"><span class="refentrytitle">DROP ROLE</span></a>, <a class="xref" href="sql-alterdatabase.html" title="ALTER DATABASE"><span class="refentrytitle">ALTER DATABASE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">PREPARE TRANSACTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> REFRESH MATERIALIZED VIEW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-refreshmaterializedview.html b/doc/src/sgml/html/sql-refreshmaterializedview.html
new file mode 100644
index 0000000..403c8a8
--- /dev/null
+++ b/doc/src/sgml/html/sql-refreshmaterializedview.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>REFRESH MATERIALIZED VIEW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-reassign-owned.html" title="REASSIGN OWNED" /><link rel="next" href="sql-reindex.html" title="REINDEX" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">REFRESH MATERIALIZED VIEW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-reassign-owned.html" title="REASSIGN OWNED">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-reindex.html" title="REINDEX">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-REFRESHMATERIALIZEDVIEW"><div class="titlepage"></div><a id="id-1.9.3.162.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">REFRESH MATERIALIZED VIEW</span></h2><p>REFRESH MATERIALIZED VIEW — replace the contents of a materialized view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] <em class="replaceable"><code>name</code></em>
+ [ WITH [ NO ] DATA ]
+</pre></div><div class="refsect1" id="id-1.9.3.162.5"><h2>Description</h2><p>
+ <code class="command">REFRESH MATERIALIZED VIEW</code> completely replaces the
+ contents of a materialized view. To execute this command you must be the
+ owner of the materialized view. The old contents are discarded. If
+ <code class="literal">WITH DATA</code> is specified (or defaults) the backing query
+ is executed to provide the new data, and the materialized view is left in a
+ scannable state. If <code class="literal">WITH NO DATA</code> is specified no new
+ data is generated and the materialized view is left in an unscannable
+ state.
+ </p><p>
+ <code class="literal">CONCURRENTLY</code> and <code class="literal">WITH NO DATA</code> may not
+ be specified together.
+ </p></div><div class="refsect1" id="id-1.9.3.162.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">CONCURRENTLY</code></span></dt><dd><p>
+ Refresh the materialized view without locking out concurrent selects on
+ the materialized view. Without this option a refresh which affects a
+ lot of rows will tend to use fewer resources and complete more quickly,
+ but could block other connections which are trying to read from the
+ materialized view. This option may be faster in cases where a small
+ number of rows are affected.
+ </p><p>
+ This option is only allowed if there is at least one
+ <code class="literal">UNIQUE</code> index on the materialized view which uses only
+ column names and includes all rows; that is, it must not be an
+ expression index or include a <code class="literal">WHERE</code> clause.
+ </p><p>
+ This option may not be used when the materialized view is not already
+ populated.
+ </p><p>
+ Even with this option only one <code class="literal">REFRESH</code> at a time may
+ run against any one materialized view.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the materialized view to
+ refresh.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.162.7"><h2>Notes</h2><p>
+ If there is an <code class="literal">ORDER BY</code> clause in the materialized
+ view's defining query, the original contents of the materialized view
+ will be ordered that way; but <code class="command">REFRESH MATERIALIZED
+ VIEW</code> does not guarantee to preserve that ordering.
+ </p></div><div class="refsect1" id="id-1.9.3.162.8"><h2>Examples</h2><p>
+ This command will replace the contents of the materialized view called
+ <code class="literal">order_summary</code> using the query from the materialized
+ view's definition, and leave it in a scannable state:
+</p><pre class="programlisting">
+REFRESH MATERIALIZED VIEW order_summary;
+</pre><p>
+ </p><p>
+ This command will free storage associated with the materialized view
+ <code class="literal">annual_statistics_basis</code> and leave it in an unscannable
+ state:
+</p><pre class="programlisting">
+REFRESH MATERIALIZED VIEW annual_statistics_basis WITH NO DATA;
+</pre></div><div class="refsect1" id="id-1.9.3.162.9"><h2>Compatibility</h2><p>
+ <code class="command">REFRESH MATERIALIZED VIEW</code> is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.162.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-creatematerializedview.html" title="CREATE MATERIALIZED VIEW"><span class="refentrytitle">CREATE MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-altermaterializedview.html" title="ALTER MATERIALIZED VIEW"><span class="refentrytitle">ALTER MATERIALIZED VIEW</span></a>, <a class="xref" href="sql-dropmaterializedview.html" title="DROP MATERIALIZED VIEW"><span class="refentrytitle">DROP MATERIALIZED VIEW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-reassign-owned.html" title="REASSIGN OWNED">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-reindex.html" title="REINDEX">Next</a></td></tr><tr><td width="40%" align="left" valign="top">REASSIGN OWNED </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> REINDEX</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-reindex.html b/doc/src/sgml/html/sql-reindex.html
new file mode 100644
index 0000000..76a6c21
--- /dev/null
+++ b/doc/src/sgml/html/sql-reindex.html
@@ -0,0 +1,327 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>REINDEX</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW" /><link rel="next" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">REINDEX</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-REINDEX"><div class="titlepage"></div><a id="id-1.9.3.163.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">REINDEX</span></h2><p>REINDEX — rebuild indexes</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+REINDEX [ ( <em class="replaceable"><code>option</code></em> [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] <em class="replaceable"><code>name</code></em>
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be one of:</span>
+
+ CONCURRENTLY [ <em class="replaceable"><code>boolean</code></em> ]
+ TABLESPACE <em class="replaceable"><code>new_tablespace</code></em>
+ VERBOSE [ <em class="replaceable"><code>boolean</code></em> ]
+</pre></div><div class="refsect1" id="id-1.9.3.163.5"><h2>Description</h2><p>
+ <code class="command">REINDEX</code> rebuilds an index using the data
+ stored in the index's table, replacing the old copy of the index. There are
+ several scenarios in which to use <code class="command">REINDEX</code>:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ An index has become corrupted, and no longer contains valid
+ data. Although in theory this should never happen, in
+ practice indexes can become corrupted due to software bugs or
+ hardware failures. <code class="command">REINDEX</code> provides a
+ recovery method.
+ </p></li><li class="listitem"><p>
+ An index has become <span class="quote">“<span class="quote">bloated</span>”</span>, that is it contains many
+ empty or nearly-empty pages. This can occur with B-tree indexes in
+ <span class="productname">PostgreSQL</span> under certain uncommon access
+ patterns. <code class="command">REINDEX</code> provides a way to reduce
+ the space consumption of the index by writing a new version of
+ the index without the dead pages. See <a class="xref" href="routine-reindex.html" title="25.2. Routine Reindexing">Section 25.2</a> for more information.
+ </p></li><li class="listitem"><p>
+ You have altered a storage parameter (such as fillfactor)
+ for an index, and wish to ensure that the change has taken full effect.
+ </p></li><li class="listitem"><p>
+ If an index build fails with the <code class="literal">CONCURRENTLY</code> option,
+ this index is left as <span class="quote">“<span class="quote">invalid</span>”</span>. Such indexes are useless
+ but it can be convenient to use <code class="command">REINDEX</code> to rebuild
+ them. Note that only <code class="command">REINDEX INDEX</code> is able
+ to perform a concurrent build on an invalid index.
+ </p></li></ul></div></div><div class="refsect1" id="id-1.9.3.163.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">INDEX</code></span></dt><dd><p>
+ Recreate the specified index. This form of <code class="command">REINDEX</code>
+ cannot be executed inside a transaction block when used with a
+ partitioned index.
+ </p></dd><dt><span class="term"><code class="literal">TABLE</code></span></dt><dd><p>
+ Recreate all indexes of the specified table. If the table has a
+ secondary <span class="quote">“<span class="quote">TOAST</span>”</span> table, that is reindexed as well.
+ This form of <code class="command">REINDEX</code> cannot be executed inside a
+ transaction block when used with a partitioned table.
+ </p></dd><dt><span class="term"><code class="literal">SCHEMA</code></span></dt><dd><p>
+ Recreate all indexes of the specified schema. If a table of this
+ schema has a secondary <span class="quote">“<span class="quote">TOAST</span>”</span> table, that is reindexed as
+ well. Indexes on shared system catalogs are also processed.
+ This form of <code class="command">REINDEX</code> cannot be executed inside a
+ transaction block.
+ </p></dd><dt><span class="term"><code class="literal">DATABASE</code></span></dt><dd><p>
+ Recreate all indexes within the current database.
+ Indexes on shared system catalogs are also processed.
+ This form of <code class="command">REINDEX</code> cannot be executed inside a
+ transaction block.
+ </p></dd><dt><span class="term"><code class="literal">SYSTEM</code></span></dt><dd><p>
+ Recreate all indexes on system catalogs within the current database.
+ Indexes on shared system catalogs are included.
+ Indexes on user tables are not processed.
+ This form of <code class="command">REINDEX</code> cannot be executed inside a
+ transaction block.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of the specific index, table, or database to be
+ reindexed. Index and table names can be schema-qualified.
+ Presently, <code class="command">REINDEX DATABASE</code> and <code class="command">REINDEX SYSTEM</code>
+ can only reindex the current database, so their parameter must match
+ the current database's name.
+ </p></dd><dt><span class="term"><code class="literal">CONCURRENTLY</code></span></dt><dd><p>
+ When this option is used, <span class="productname">PostgreSQL</span> will rebuild the
+ index without taking any locks that prevent concurrent inserts,
+ updates, or deletes on the table; whereas a standard index rebuild
+ locks out writes (but not reads) on the table until it's done.
+ There are several caveats to be aware of when using this option
+ — see <a class="xref" href="sql-reindex.html#SQL-REINDEX-CONCURRENTLY" title="Rebuilding Indexes Concurrently">Rebuilding Indexes Concurrently</a> below.
+ </p><p>
+ For temporary tables, <code class="command">REINDEX</code> is always
+ non-concurrent, as no other session can access them, and
+ non-concurrent reindex is cheaper.
+ </p></dd><dt><span class="term"><code class="literal">TABLESPACE</code></span></dt><dd><p>
+ Specifies that indexes will be rebuilt on a new tablespace.
+ </p></dd><dt><span class="term"><code class="literal">VERBOSE</code></span></dt><dd><p>
+ Prints a progress report as each index is reindexed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>boolean</code></em></span></dt><dd><p>
+ Specifies whether the selected option should be turned on or off.
+ You can write <code class="literal">TRUE</code>, <code class="literal">ON</code>, or
+ <code class="literal">1</code> to enable the option, and <code class="literal">FALSE</code>,
+ <code class="literal">OFF</code>, or <code class="literal">0</code> to disable it. The
+ <em class="replaceable"><code>boolean</code></em> value can also
+ be omitted, in which case <code class="literal">TRUE</code> is assumed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_tablespace</code></em></span></dt><dd><p>
+ The tablespace where indexes will be rebuilt.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.163.7"><h2>Notes</h2><p>
+ If you suspect corruption of an index on a user table, you can
+ simply rebuild that index, or all indexes on the table, using
+ <code class="command">REINDEX INDEX</code> or <code class="command">REINDEX TABLE</code>.
+ </p><p>
+ Things are more difficult if you need to recover from corruption of
+ an index on a system table. In this case it's important for the
+ system to not have used any of the suspect indexes itself.
+ (Indeed, in this sort of scenario you might find that server
+ processes are crashing immediately at start-up, due to reliance on
+ the corrupted indexes.) To recover safely, the server must be started
+ with the <code class="option">-P</code> option, which prevents it from using
+ indexes for system catalog lookups.
+ </p><p>
+ One way to do this is to shut down the server and start a single-user
+ <span class="productname">PostgreSQL</span> server
+ with the <code class="option">-P</code> option included on its command line.
+ Then, <code class="command">REINDEX DATABASE</code>, <code class="command">REINDEX SYSTEM</code>,
+ <code class="command">REINDEX TABLE</code>, or <code class="command">REINDEX INDEX</code> can be
+ issued, depending on how much you want to reconstruct. If in
+ doubt, use <code class="command">REINDEX SYSTEM</code> to select
+ reconstruction of all system indexes in the database. Then quit
+ the single-user server session and restart the regular server.
+ See the <a class="xref" href="app-postgres.html" title="postgres"><span class="refentrytitle"><span class="application">postgres</span></span></a> reference page for more
+ information about how to interact with the single-user server
+ interface.
+ </p><p>
+ Alternatively, a regular server session can be started with
+ <code class="option">-P</code> included in its command line options.
+ The method for doing this varies across clients, but in all
+ <span class="application">libpq</span>-based clients, it is possible to set
+ the <code class="envar">PGOPTIONS</code> environment variable to <code class="literal">-P</code>
+ before starting the client. Note that while this method does not
+ require locking out other clients, it might still be wise to prevent
+ other users from connecting to the damaged database until repairs
+ have been completed.
+ </p><p>
+ <code class="command">REINDEX</code> is similar to a drop and recreate of the index
+ in that the index contents are rebuilt from scratch. However, the locking
+ considerations are rather different. <code class="command">REINDEX</code> locks out writes
+ but not reads of the index's parent table. It also takes an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the specific index being processed,
+ which will block reads that attempt to use that index. In particular,
+ the query planner tries to take an <code class="literal">ACCESS SHARE</code>
+ lock on every index of the table, regardless of the query, and so
+ <code class="command">REINDEX</code> blocks virtually any queries except for some
+ prepared queries whose plan has been cached and which don't use this very
+ index. In contrast,
+ <code class="command">DROP INDEX</code> momentarily takes an
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the parent table, blocking both
+ writes and reads. The subsequent <code class="command">CREATE INDEX</code> locks out
+ writes but not reads; since the index is not there, no read will attempt to
+ use it, meaning that there will be no blocking but reads might be forced
+ into expensive sequential scans.
+ </p><p>
+ Reindexing a single index or table requires being the owner of that
+ index or table. Reindexing a schema or database requires being the
+ owner of that schema or database. Note specifically that it's thus
+ possible for non-superusers to rebuild indexes of tables owned by
+ other users. However, as a special exception, when
+ <code class="command">REINDEX DATABASE</code>, <code class="command">REINDEX SCHEMA</code>
+ or <code class="command">REINDEX SYSTEM</code> is issued by a non-superuser,
+ indexes on shared catalogs will be skipped unless the user owns the
+ catalog (which typically won't be the case). Of course, superusers
+ can always reindex anything.
+ </p><p>
+ Reindexing partitioned indexes or partitioned tables is supported
+ with <code class="command">REINDEX INDEX</code> or <code class="command">REINDEX TABLE</code>,
+ respectively. Each partition of the specified partitioned relation is
+ reindexed in a separate transaction. Those commands cannot be used inside
+ a transaction block when working on a partitioned table or index.
+ </p><p>
+ When using the <code class="literal">TABLESPACE</code> clause with
+ <code class="command">REINDEX</code> on a partitioned index or table, only the
+ tablespace references of the leaf partitions are updated. As partitioned
+ indexes are not updated, it is recommended to separately use
+ <code class="command">ALTER TABLE ONLY</code> on them so as any new partitions
+ attached inherit the new tablespace. On failure, it may not have moved
+ all the indexes to the new tablespace. Re-running the command will rebuild
+ all the leaf partitions and move previously-unprocessed indexes to the new
+ tablespace.
+ </p><p>
+ If <code class="literal">SCHEMA</code>, <code class="literal">DATABASE</code> or
+ <code class="literal">SYSTEM</code> is used with <code class="literal">TABLESPACE</code>,
+ system relations are skipped and a single <code class="literal">WARNING</code>
+ will be generated. Indexes on TOAST tables are rebuilt, but not moved
+ to the new tablespace.
+ </p><div class="refsect2" id="SQL-REINDEX-CONCURRENTLY"><h3>Rebuilding Indexes Concurrently</h3><a id="id-1.9.3.163.7.11.2" class="indexterm"></a><p>
+ Rebuilding an index can interfere with regular operation of a database.
+ Normally <span class="productname">PostgreSQL</span> locks the table whose index is rebuilt
+ against writes and performs the entire index build with a single scan of the
+ table. Other transactions can still read the table, but if they try to
+ insert, update, or delete rows in the table they will block until the
+ index rebuild is finished. This could have a severe effect if the system is
+ a live production database. Very large tables can take many hours to be
+ indexed, and even for smaller tables, an index rebuild can lock out writers
+ for periods that are unacceptably long for a production system.
+ </p><p>
+ <span class="productname">PostgreSQL</span> supports rebuilding indexes with minimum locking
+ of writes. This method is invoked by specifying the
+ <code class="literal">CONCURRENTLY</code> option of <code class="command">REINDEX</code>. When this option
+ is used, <span class="productname">PostgreSQL</span> must perform two scans of the table
+ for each index that needs to be rebuilt and wait for termination of
+ all existing transactions that could potentially use the index.
+ This method requires more total work than a standard index
+ rebuild and takes significantly longer to complete as it needs to wait
+ for unfinished transactions that might modify the index. However, since
+ it allows normal operations to continue while the index is being rebuilt, this
+ method is useful for rebuilding indexes in a production environment. Of
+ course, the extra CPU, memory and I/O load imposed by the index rebuild
+ may slow down other operations.
+ </p><p>
+ The following steps occur in a concurrent reindex. Each step is run in a
+ separate transaction. If there are multiple indexes to be rebuilt, then
+ each step loops through all the indexes before moving to the next step.
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ A new transient index definition is added to the catalog
+ <code class="literal">pg_index</code>. This definition will be used to replace
+ the old index. A <code class="literal">SHARE UPDATE EXCLUSIVE</code> lock at
+ session level is taken on the indexes being reindexed as well as their
+ associated tables to prevent any schema modification while processing.
+ </p></li><li class="listitem"><p>
+ A first pass to build the index is done for each new index. Once the
+ index is built, its flag <code class="literal">pg_index.indisready</code> is
+ switched to <span class="quote">“<span class="quote">true</span>”</span> to make it ready for inserts, making it
+ visible to other sessions once the transaction that performed the build
+ is finished. This step is done in a separate transaction for each
+ index.
+ </p></li><li class="listitem"><p>
+ Then a second pass is performed to add tuples that were added while the
+ first pass was running. This step is also done in a separate
+ transaction for each index.
+ </p></li><li class="listitem"><p>
+ All the constraints that refer to the index are changed to refer to the
+ new index definition, and the names of the indexes are changed. At
+ this point, <code class="literal">pg_index.indisvalid</code> is switched to
+ <span class="quote">“<span class="quote">true</span>”</span> for the new index and to <span class="quote">“<span class="quote">false</span>”</span> for
+ the old, and a cache invalidation is done causing all sessions that
+ referenced the old index to be invalidated.
+ </p></li><li class="listitem"><p>
+ The old indexes have <code class="literal">pg_index.indisready</code> switched to
+ <span class="quote">“<span class="quote">false</span>”</span> to prevent any new tuple insertions, after waiting
+ for running queries that might reference the old index to complete.
+ </p></li><li class="listitem"><p>
+ The old indexes are dropped. The <code class="literal">SHARE UPDATE
+ EXCLUSIVE</code> session locks for the indexes and the table are
+ released.
+ </p></li></ol></div><p>
+ </p><p>
+ If a problem arises while rebuilding the indexes, such as a
+ uniqueness violation in a unique index, the <code class="command">REINDEX</code>
+ command will fail but leave behind an <span class="quote">“<span class="quote">invalid</span>”</span> new index in addition to
+ the pre-existing one. This index will be ignored for querying purposes
+ because it might be incomplete; however it will still consume update
+ overhead. The <span class="application">psql</span> <code class="command">\d</code> command will report
+ such an index as <code class="literal">INVALID</code>:
+
+</p><pre class="programlisting">
+postgres=# \d tab
+ Table "public.tab"
+ Column | Type | Modifiers
+--------+---------+-----------
+ col | integer |
+Indexes:
+ "idx" btree (col)
+ "idx_ccnew" btree (col) INVALID
+</pre><p>
+
+ If the index marked <code class="literal">INVALID</code> is suffixed
+ <code class="literal">ccnew</code>, then it corresponds to the transient
+ index created during the concurrent operation, and the recommended
+ recovery method is to drop it using <code class="literal">DROP INDEX</code>,
+ then attempt <code class="command">REINDEX CONCURRENTLY</code> again.
+ If the invalid index is instead suffixed <code class="literal">ccold</code>,
+ it corresponds to the original index which could not be dropped;
+ the recommended recovery method is to just drop said index, since the
+ rebuild proper has been successful.
+ </p><p>
+ Regular index builds permit other regular index builds on the same table
+ to occur simultaneously, but only one concurrent index build can occur on a
+ table at a time. In both cases, no other types of schema modification on
+ the table are allowed meanwhile. Another difference is that a regular
+ <code class="command">REINDEX TABLE</code> or <code class="command">REINDEX INDEX</code>
+ command can be performed within a transaction block, but <code class="command">REINDEX
+ CONCURRENTLY</code> cannot.
+ </p><p>
+ Like any long-running transaction, <code class="command">REINDEX</code> on a table
+ can affect which tuples can be removed by concurrent
+ <code class="command">VACUUM</code> on any other table.
+ </p><p>
+ <code class="command">REINDEX SYSTEM</code> does not support
+ <code class="command">CONCURRENTLY</code> since system catalogs cannot be reindexed
+ concurrently.
+ </p><p>
+ Furthermore, indexes for exclusion constraints cannot be reindexed
+ concurrently. If such an index is named directly in this command, an
+ error is raised. If a table or database with exclusion constraint indexes
+ is reindexed concurrently, those indexes will be skipped. (It is possible
+ to reindex such indexes without the <code class="command">CONCURRENTLY</code> option.)
+ </p><p>
+ Each backend running <code class="command">REINDEX</code> will report its progress
+ in the <code class="structname">pg_stat_progress_create_index</code> view. See
+ <a class="xref" href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING" title="28.4.2. CREATE INDEX Progress Reporting">Section 28.4.2</a> for details.
+ </p></div></div><div class="refsect1" id="id-1.9.3.163.8"><h2>Examples</h2><p>
+ Rebuild a single index:
+
+</p><pre class="programlisting">
+REINDEX INDEX my_index;
+</pre><p>
+ </p><p>
+ Rebuild all the indexes on the table <code class="literal">my_table</code>:
+
+</p><pre class="programlisting">
+REINDEX TABLE my_table;
+</pre><p>
+ </p><p>
+ Rebuild all indexes in a particular database, without trusting the
+ system indexes to be valid already:
+
+</p><pre class="programlisting">
+$ <strong class="userinput"><code>export PGOPTIONS="-P"</code></strong>
+$ <strong class="userinput"><code>psql broken_db</code></strong>
+...
+broken_db=&gt; REINDEX DATABASE broken_db;
+broken_db=&gt; \q
+</pre><p>
+ Rebuild indexes for a table, without blocking read and write operations
+ on involved relations while reindexing is in progress:
+
+</p><pre class="programlisting">
+REINDEX TABLE CONCURRENTLY my_broken_table;
+</pre></div><div class="refsect1" id="id-1.9.3.163.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">REINDEX</code> command in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.163.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>, <a class="xref" href="sql-dropindex.html" title="DROP INDEX"><span class="refentrytitle">DROP INDEX</span></a>, <a class="xref" href="app-reindexdb.html" title="reindexdb"><span class="refentrytitle"><span class="application">reindexdb</span></span></a>, <a class="xref" href="progress-reporting.html#CREATE-INDEX-PROGRESS-REPORTING" title="28.4.2. CREATE INDEX Progress Reporting">Section 28.4.2</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-refreshmaterializedview.html" title="REFRESH MATERIALIZED VIEW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">REFRESH MATERIALIZED VIEW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> RELEASE SAVEPOINT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-release-savepoint.html b/doc/src/sgml/html/sql-release-savepoint.html
new file mode 100644
index 0000000..56bca34
--- /dev/null
+++ b/doc/src/sgml/html/sql-release-savepoint.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>RELEASE SAVEPOINT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-reindex.html" title="REINDEX" /><link rel="next" href="sql-reset.html" title="RESET" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">RELEASE SAVEPOINT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-reindex.html" title="REINDEX">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-reset.html" title="RESET">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-RELEASE-SAVEPOINT"><div class="titlepage"></div><a id="id-1.9.3.164.1" class="indexterm"></a><a id="id-1.9.3.164.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">RELEASE SAVEPOINT</span></h2><p>RELEASE SAVEPOINT — destroy a previously defined savepoint</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+RELEASE [ SAVEPOINT ] <em class="replaceable"><code>savepoint_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.164.6"><h2>Description</h2><p>
+ <code class="command">RELEASE SAVEPOINT</code> destroys a savepoint previously defined
+ in the current transaction.
+ </p><p>
+ Destroying a savepoint makes it unavailable as a rollback point,
+ but it has no other user visible behavior. It does not undo the
+ effects of commands executed after the savepoint was established.
+ (To do that, see <a class="xref" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT"><span class="refentrytitle">ROLLBACK TO SAVEPOINT</span></a>.)
+ Destroying a savepoint when
+ it is no longer needed allows the system to reclaim some resources
+ earlier than transaction end.
+ </p><p>
+ <code class="command">RELEASE SAVEPOINT</code> also destroys all savepoints that were
+ established after the named savepoint was established.
+ </p></div><div class="refsect1" id="id-1.9.3.164.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>savepoint_name</code></em></span></dt><dd><p>
+ The name of the savepoint to destroy.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.164.8"><h2>Notes</h2><p>
+ Specifying a savepoint name that was not previously defined is an error.
+ </p><p>
+ It is not possible to release a savepoint when the transaction is in
+ an aborted state.
+ </p><p>
+ If multiple savepoints have the same name, only the most recently defined
+ unreleased one is released. Repeated commands will release progressively
+ older savepoints.
+ </p></div><div class="refsect1" id="id-1.9.3.164.9"><h2>Examples</h2><p>
+ To establish and later destroy a savepoint:
+</p><pre class="programlisting">
+BEGIN;
+ INSERT INTO table1 VALUES (3);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (4);
+ RELEASE SAVEPOINT my_savepoint;
+COMMIT;
+</pre><p>
+ The above transaction will insert both 3 and 4.
+ </p></div><div class="refsect1" id="id-1.9.3.164.10"><h2>Compatibility</h2><p>
+ This command conforms to the <acronym class="acronym">SQL</acronym> standard. The standard
+ specifies that the key word <code class="literal">SAVEPOINT</code> is
+ mandatory, but <span class="productname">PostgreSQL</span> allows it to
+ be omitted.
+ </p></div><div class="refsect1" id="id-1.9.3.164.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a>, <a class="xref" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT"><span class="refentrytitle">ROLLBACK TO SAVEPOINT</span></a>, <a class="xref" href="sql-savepoint.html" title="SAVEPOINT"><span class="refentrytitle">SAVEPOINT</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-reindex.html" title="REINDEX">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-reset.html" title="RESET">Next</a></td></tr><tr><td width="40%" align="left" valign="top">REINDEX </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> RESET</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-reset.html b/doc/src/sgml/html/sql-reset.html
new file mode 100644
index 0000000..fe8e934
--- /dev/null
+++ b/doc/src/sgml/html/sql-reset.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>RESET</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT" /><link rel="next" href="sql-revoke.html" title="REVOKE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">RESET</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-revoke.html" title="REVOKE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-RESET"><div class="titlepage"></div><a id="id-1.9.3.165.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">RESET</span></h2><p>RESET — restore the value of a run-time parameter to the default value</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+RESET <em class="replaceable"><code>configuration_parameter</code></em>
+RESET ALL
+</pre></div><div class="refsect1" id="id-1.9.3.165.5"><h2>Description</h2><p>
+ <code class="command">RESET</code> restores run-time parameters to their
+ default values. <code class="command">RESET</code> is an alternative
+ spelling for
+</p><pre class="synopsis">
+SET <em class="replaceable"><code>configuration_parameter</code></em> TO DEFAULT
+</pre><p>
+ Refer to <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> for
+ details.
+ </p><p>
+ The default value is defined as the value that the parameter would
+ have had, if no <code class="command">SET</code> had ever been issued for it in the
+ current session. The actual source of this value might be a
+ compiled-in default, the configuration file, command-line options,
+ or per-database or per-user default settings. This is subtly different
+ from defining it as <span class="quote">“<span class="quote">the value that the parameter had at session
+ start</span>”</span>, because if the value came from the configuration file, it
+ will be reset to whatever is specified by the configuration file now.
+ See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for details.
+ </p><p>
+ The transactional behavior of <code class="command">RESET</code> is the same as
+ <code class="command">SET</code>: its effects will be undone by transaction rollback.
+ </p></div><div class="refsect1" id="id-1.9.3.165.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em></span></dt><dd><p>
+ Name of a settable run-time parameter. Available parameters are
+ documented in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> and on the
+ <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> reference page.
+ </p></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Resets all settable run-time parameters to default values.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.165.7"><h2>Examples</h2><p>
+ Set the <code class="varname">timezone</code> configuration variable to its default value:
+</p><pre class="screen">
+RESET timezone;
+</pre></div><div class="refsect1" id="id-1.9.3.165.8"><h2>Compatibility</h2><p>
+ <code class="command">RESET</code> is a <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.165.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a>, <a class="xref" href="sql-show.html" title="SHOW"><span class="refentrytitle">SHOW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-revoke.html" title="REVOKE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">RELEASE SAVEPOINT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> REVOKE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-revoke.html b/doc/src/sgml/html/sql-revoke.html
new file mode 100644
index 0000000..f2e9514
--- /dev/null
+++ b/doc/src/sgml/html/sql-revoke.html
@@ -0,0 +1,249 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>REVOKE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-reset.html" title="RESET" /><link rel="next" href="sql-rollback.html" title="ROLLBACK" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">REVOKE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-reset.html" title="RESET">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-rollback.html" title="ROLLBACK">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-REVOKE"><div class="titlepage"></div><a id="id-1.9.3.166.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">REVOKE</span></h2><p>REVOKE — remove access privileges</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { [ TABLE ] <em class="replaceable"><code>table_name</code></em> [, ...]
+ | ALL TABLES IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] }
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | REFERENCES } ( <em class="replaceable"><code>column_name</code></em> [, ...] )
+ [, ...] | ALL [ PRIVILEGES ] ( <em class="replaceable"><code>column_name</code></em> [, ...] ) }
+ ON [ TABLE ] <em class="replaceable"><code>table_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { SEQUENCE <em class="replaceable"><code>sequence_name</code></em> [, ...]
+ | ALL SEQUENCES IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] }
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
+ ON DATABASE <em class="replaceable"><code>database_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON DOMAIN <em class="replaceable"><code>domain_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN DATA WRAPPER <em class="replaceable"><code>fdw_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN SERVER <em class="replaceable"><code>server_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { { FUNCTION | PROCEDURE | ROUTINE } <em class="replaceable"><code>function_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>arg_name</code></em> ] <em class="replaceable"><code>arg_type</code></em> [, ...] ] ) ] [, ...]
+ | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...] }
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON LANGUAGE <em class="replaceable"><code>lang_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
+ ON LARGE OBJECT <em class="replaceable"><code>loid</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SET | ALTER SYSTEM } [, ...] | ALL [ PRIVILEGES ] }
+ ON PARAMETER <em class="replaceable"><code>configuration_parameter</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
+ ON SCHEMA <em class="replaceable"><code>schema_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { CREATE | ALL [ PRIVILEGES ] }
+ ON TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPE <em class="replaceable"><code>type_name</code></em> [, ...]
+ FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ ADMIN OPTION FOR ]
+ <em class="replaceable"><code>role_name</code></em> [, ...] FROM <em class="replaceable"><code>role_specification</code></em> [, ...]
+ [ GRANTED BY <em class="replaceable"><code>role_specification</code></em> ]
+ [ CASCADE | RESTRICT ]
+
+<span class="phrase">where <em class="replaceable"><code>role_specification</code></em> can be:</span>
+
+ [ GROUP ] <em class="replaceable"><code>role_name</code></em>
+ | PUBLIC
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</pre></div><div class="refsect1" id="SQL-REVOKE-DESCRIPTION"><h2>Description</h2><p>
+ The <code class="command">REVOKE</code> command revokes previously granted
+ privileges from one or more roles. The key word
+ <code class="literal">PUBLIC</code> refers to the implicitly defined group of
+ all roles.
+ </p><p>
+ See the description of the <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> command for
+ the meaning of the privilege types.
+ </p><p>
+ Note that any particular role will have the sum
+ of privileges granted directly to it, privileges granted to any role it
+ is presently a member of, and privileges granted to
+ <code class="literal">PUBLIC</code>. Thus, for example, revoking <code class="literal">SELECT</code> privilege
+ from <code class="literal">PUBLIC</code> does not necessarily mean that all roles
+ have lost <code class="literal">SELECT</code> privilege on the object: those who have it granted
+ directly or via another role will still have it. Similarly, revoking
+ <code class="literal">SELECT</code> from a user might not prevent that user from using
+ <code class="literal">SELECT</code> if <code class="literal">PUBLIC</code> or another membership
+ role still has <code class="literal">SELECT</code> rights.
+ </p><p>
+ If <code class="literal">GRANT OPTION FOR</code> is specified, only the grant
+ option for the privilege is revoked, not the privilege itself.
+ Otherwise, both the privilege and the grant option are revoked.
+ </p><p>
+ If a user holds a privilege with grant option and has granted it to
+ other users then the privileges held by those other users are
+ called dependent privileges. If the privilege or the grant option
+ held by the first user is being revoked and dependent privileges
+ exist, those dependent privileges are also revoked if
+ <code class="literal">CASCADE</code> is specified; if it is not, the revoke action
+ will fail. This recursive revocation only affects privileges that
+ were granted through a chain of users that is traceable to the user
+ that is the subject of this <code class="literal">REVOKE</code> command.
+ Thus, the affected users might effectively keep the privilege if it
+ was also granted through other users.
+ </p><p>
+ When revoking privileges on a table, the corresponding column privileges
+ (if any) are automatically revoked on each column of the table, as well.
+ On the other hand, if a role has been granted privileges on a table, then
+ revoking the same privileges from individual columns will have no effect.
+ </p><p>
+ When revoking membership in a role, <code class="literal">GRANT OPTION</code> is instead
+ called <code class="literal">ADMIN OPTION</code>, but the behavior is similar.
+ This form of the command also allows a <code class="literal">GRANTED BY</code>
+ option, but that option is currently ignored (except for checking
+ the existence of the named role).
+ Note also that this form of the command does not
+ allow the noise word <code class="literal">GROUP</code>
+ in <em class="replaceable"><code>role_specification</code></em>.
+ </p></div><div class="refsect1" id="SQL-REVOKE-NOTES"><h2>Notes</h2><p>
+ A user can only revoke privileges that were granted directly by
+ that user. If, for example, user A has granted a privilege with
+ grant option to user B, and user B has in turn granted it to user
+ C, then user A cannot revoke the privilege directly from C.
+ Instead, user A could revoke the grant option from user B and use
+ the <code class="literal">CASCADE</code> option so that the privilege is
+ in turn revoked from user C. For another example, if both A and B
+ have granted the same privilege to C, A can revoke their own grant
+ but not B's grant, so C will still effectively have the privilege.
+ </p><p>
+ When a non-owner of an object attempts to <code class="command">REVOKE</code> privileges
+ on the object, the command will fail outright if the user has no
+ privileges whatsoever on the object. As long as some privilege is
+ available, the command will proceed, but it will revoke only those
+ privileges for which the user has grant options. The <code class="command">REVOKE ALL
+ PRIVILEGES</code> forms will issue a warning message if no grant options are
+ held, while the other forms will issue a warning if grant options for
+ any of the privileges specifically named in the command are not held.
+ (In principle these statements apply to the object owner as well, but
+ since the owner is always treated as holding all grant options, the
+ cases can never occur.)
+ </p><p>
+ If a superuser chooses to issue a <code class="command">GRANT</code> or <code class="command">REVOKE</code>
+ command, the command is performed as though it were issued by the
+ owner of the affected object. Since all privileges ultimately come
+ from the object owner (possibly indirectly via chains of grant options),
+ it is possible for a superuser to revoke all privileges, but this might
+ require use of <code class="literal">CASCADE</code> as stated above.
+ </p><p>
+ <code class="command">REVOKE</code> can also be done by a role
+ that is not the owner of the affected object, but is a member of the role
+ that owns the object, or is a member of a role that holds privileges
+ <code class="literal">WITH GRANT OPTION</code> on the object. In this case the
+ command is performed as though it were issued by the containing role that
+ actually owns the object or holds the privileges
+ <code class="literal">WITH GRANT OPTION</code>. For example, if table
+ <code class="literal">t1</code> is owned by role <code class="literal">g1</code>, of which role
+ <code class="literal">u1</code> is a member, then <code class="literal">u1</code> can revoke privileges
+ on <code class="literal">t1</code> that are recorded as being granted by <code class="literal">g1</code>.
+ This would include grants made by <code class="literal">u1</code> as well as by other
+ members of role <code class="literal">g1</code>.
+ </p><p>
+ If the role executing <code class="command">REVOKE</code> holds privileges
+ indirectly via more than one role membership path, it is unspecified
+ which containing role will be used to perform the command. In such cases
+ it is best practice to use <code class="command">SET ROLE</code> to become the specific
+ role you want to do the <code class="command">REVOKE</code> as. Failure to do so might
+ lead to revoking privileges other than the ones you intended, or not
+ revoking anything at all.
+ </p><p>
+ See <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a> for more information about specific
+ privilege types, as well as how to inspect objects' privileges.
+ </p></div><div class="refsect1" id="SQL-REVOKE-EXAMPLES"><h2>Examples</h2><p>
+ Revoke insert privilege for the public on table
+ <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+REVOKE INSERT ON films FROM PUBLIC;
+</pre><p>
+ </p><p>
+ Revoke all privileges from user <code class="literal">manuel</code> on view
+ <code class="literal">kinds</code>:
+
+</p><pre class="programlisting">
+REVOKE ALL PRIVILEGES ON kinds FROM manuel;
+</pre><p>
+
+ Note that this actually means <span class="quote">“<span class="quote">revoke all privileges that I
+ granted</span>”</span>.
+ </p><p>
+ Revoke membership in role <code class="literal">admins</code> from user <code class="literal">joe</code>:
+
+</p><pre class="programlisting">
+REVOKE admins FROM joe;
+</pre></div><div class="refsect1" id="SQL-REVOKE-COMPATIBILITY"><h2>Compatibility</h2><p>
+ The compatibility notes of the <a class="link" href="sql-grant.html" title="GRANT"><code class="command">GRANT</code></a> command
+ apply analogously to <code class="command">REVOKE</code>.
+ The keyword <code class="literal">RESTRICT</code> or <code class="literal">CASCADE</code>
+ is required according to the standard, but <span class="productname">PostgreSQL</span>
+ assumes <code class="literal">RESTRICT</code> by default.
+ </p></div><div class="refsect1" id="id-1.9.3.166.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-grant.html" title="GRANT"><span class="refentrytitle">GRANT</span></a>, <a class="xref" href="sql-alterdefaultprivileges.html" title="ALTER DEFAULT PRIVILEGES"><span class="refentrytitle">ALTER DEFAULT PRIVILEGES</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-reset.html" title="RESET">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-rollback.html" title="ROLLBACK">Next</a></td></tr><tr><td width="40%" align="left" valign="top">RESET </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ROLLBACK</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-rollback-prepared.html b/doc/src/sgml/html/sql-rollback-prepared.html
new file mode 100644
index 0000000..051e69b
--- /dev/null
+++ b/doc/src/sgml/html/sql-rollback-prepared.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ROLLBACK PREPARED</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-rollback.html" title="ROLLBACK" /><link rel="next" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ROLLBACK PREPARED</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-rollback.html" title="ROLLBACK">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ROLLBACK-PREPARED"><div class="titlepage"></div><a id="id-1.9.3.168.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ROLLBACK PREPARED</span></h2><p>ROLLBACK PREPARED — cancel a transaction that was earlier prepared for two-phase commit</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ROLLBACK PREPARED <em class="replaceable"><code>transaction_id</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.168.5"><h2>Description</h2><p>
+ <code class="command">ROLLBACK PREPARED</code> rolls back a transaction that is in
+ prepared state.
+ </p></div><div class="refsect1" id="id-1.9.3.168.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>transaction_id</code></em></span></dt><dd><p>
+ The transaction identifier of the transaction that is to be
+ rolled back.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.168.7"><h2>Notes</h2><p>
+ To roll back a prepared transaction, you must be either the same user that
+ executed the transaction originally, or a superuser. But you do not
+ have to be in the same session that executed the transaction.
+ </p><p>
+ This command cannot be executed inside a transaction block. The prepared
+ transaction is rolled back immediately.
+ </p><p>
+ All currently available prepared transactions are listed in the
+ <a class="link" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts"><code class="structname">pg_prepared_xacts</code></a>
+ system view.
+ </p></div><div class="refsect1" id="SQL-ROLLBACK-PREPARED-EXAMPLES"><h2>Examples</h2><p>
+ Roll back the transaction identified by the transaction
+ identifier <code class="literal">foobar</code>:
+
+</p><pre class="programlisting">
+ROLLBACK PREPARED 'foobar';
+</pre></div><div class="refsect1" id="id-1.9.3.168.9"><h2>Compatibility</h2><p>
+ <code class="command">ROLLBACK PREPARED</code> is a
+ <span class="productname">PostgreSQL</span> extension. It is intended for use by
+ external transaction management systems, some of which are covered by
+ standards (such as X/Open XA), but the SQL side of those systems is not
+ standardized.
+ </p></div><div class="refsect1" id="id-1.9.3.168.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a>, <a class="xref" href="sql-commit-prepared.html" title="COMMIT PREPARED"><span class="refentrytitle">COMMIT PREPARED</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-rollback.html" title="ROLLBACK">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ROLLBACK </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ROLLBACK TO SAVEPOINT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-rollback-to.html b/doc/src/sgml/html/sql-rollback-to.html
new file mode 100644
index 0000000..8e617f6
--- /dev/null
+++ b/doc/src/sgml/html/sql-rollback-to.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ROLLBACK TO SAVEPOINT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED" /><link rel="next" href="sql-savepoint.html" title="SAVEPOINT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ROLLBACK TO SAVEPOINT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-savepoint.html" title="SAVEPOINT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ROLLBACK-TO"><div class="titlepage"></div><a id="id-1.9.3.169.1" class="indexterm"></a><a id="id-1.9.3.169.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ROLLBACK TO SAVEPOINT</span></h2><p>ROLLBACK TO SAVEPOINT — roll back to a savepoint</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] <em class="replaceable"><code>savepoint_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.169.6"><h2>Description</h2><p>
+ Roll back all commands that were executed after the savepoint was
+ established. The savepoint remains valid and can be rolled back to
+ again later, if needed.
+ </p><p>
+ <code class="command">ROLLBACK TO SAVEPOINT</code> implicitly destroys all savepoints that
+ were established after the named savepoint.
+ </p></div><div class="refsect1" id="id-1.9.3.169.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>savepoint_name</code></em></span></dt><dd><p>
+ The savepoint to roll back to.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.169.8"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT"><code class="command">RELEASE SAVEPOINT</code></a> to destroy a savepoint
+ without discarding the effects of commands executed after it was
+ established.
+ </p><p>
+ Specifying a savepoint name that has not been established is an error.
+ </p><p>
+ Cursors have somewhat non-transactional behavior with respect to
+ savepoints. Any cursor that is opened inside a savepoint will be closed
+ when the savepoint is rolled back. If a previously opened cursor is
+ affected by a <code class="command">FETCH</code> or <code class="command">MOVE</code> command inside a
+ savepoint that is later rolled back, the cursor remains at the
+ position that <code class="command">FETCH</code> left it pointing to (that is, the cursor
+ motion caused by <code class="command">FETCH</code> is not rolled back).
+ Closing a cursor is not undone by rolling back, either.
+ However, other side-effects caused by the cursor's query (such as
+ side-effects of volatile functions called by the query) <span class="emphasis"><em>are</em></span>
+ rolled back if they occur during a savepoint that is later rolled back.
+ A cursor whose execution causes a transaction to abort is put in a
+ cannot-execute state, so while the transaction can be restored using
+ <code class="command">ROLLBACK TO SAVEPOINT</code>, the cursor can no longer be used.
+ </p></div><div class="refsect1" id="id-1.9.3.169.9"><h2>Examples</h2><p>
+ To undo the effects of the commands executed after <code class="literal">my_savepoint</code>
+ was established:
+</p><pre class="programlisting">
+ROLLBACK TO SAVEPOINT my_savepoint;
+</pre><p>
+ </p><p>
+ Cursor positions are not affected by savepoint rollback:
+</p><pre class="programlisting">
+BEGIN;
+
+DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2;
+
+SAVEPOINT foo;
+
+FETCH 1 FROM foo;
+ ?column?
+----------
+ 1
+
+ROLLBACK TO SAVEPOINT foo;
+
+FETCH 1 FROM foo;
+ ?column?
+----------
+ 2
+
+COMMIT;
+</pre></div><div class="refsect1" id="id-1.9.3.169.10"><h2>Compatibility</h2><p>
+ The <acronym class="acronym">SQL</acronym> standard specifies that the key word
+ <code class="literal">SAVEPOINT</code> is mandatory, but <span class="productname">PostgreSQL</span>
+ and <span class="productname">Oracle</span> allow it to be omitted. SQL allows
+ only <code class="literal">WORK</code>, not <code class="literal">TRANSACTION</code>, as a noise word
+ after <code class="literal">ROLLBACK</code>. Also, SQL has an optional clause
+ <code class="literal">AND [ NO ] CHAIN</code> which is not currently supported by
+ <span class="productname">PostgreSQL</span>. Otherwise, this command conforms to
+ the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.169.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT"><span class="refentrytitle">RELEASE SAVEPOINT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a>, <a class="xref" href="sql-savepoint.html" title="SAVEPOINT"><span class="refentrytitle">SAVEPOINT</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-savepoint.html" title="SAVEPOINT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ROLLBACK PREPARED </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SAVEPOINT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-rollback.html b/doc/src/sgml/html/sql-rollback.html
new file mode 100644
index 0000000..5cf7bc7
--- /dev/null
+++ b/doc/src/sgml/html/sql-rollback.html
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>ROLLBACK</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-revoke.html" title="REVOKE" /><link rel="next" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">ROLLBACK</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-revoke.html" title="REVOKE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-ROLLBACK"><div class="titlepage"></div><a id="id-1.9.3.167.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">ROLLBACK</span></h2><p>ROLLBACK — abort the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</pre></div><div class="refsect1" id="id-1.9.3.167.5"><h2>Description</h2><p>
+ <code class="command">ROLLBACK</code> rolls back the current transaction and causes
+ all the updates made by the transaction to be discarded.
+ </p></div><div class="refsect1" id="id-1.9.3.167.6"><h2>Parameters</h2><a id="id-1.9.3.167.6.2" class="indexterm"></a><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">WORK</code><br /></span><span class="term"><code class="literal">TRANSACTION</code></span></dt><dd><p>
+ Optional key words. They have no effect.
+ </p></dd><dt id="SQL-ROLLBACK-CHAIN"><span class="term"><code class="literal">AND CHAIN</code></span></dt><dd><p>
+ If <code class="literal">AND CHAIN</code> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.167.7"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-commit.html" title="COMMIT"><code class="command">COMMIT</code></a> to
+ successfully terminate a transaction.
+ </p><p>
+ Issuing <code class="command">ROLLBACK</code> outside of a transaction
+ block emits a warning and otherwise has no effect. <code class="command">ROLLBACK AND
+ CHAIN</code> outside of a transaction block is an error.
+ </p></div><div class="refsect1" id="id-1.9.3.167.8"><h2>Examples</h2><p>
+ To abort all changes:
+</p><pre class="programlisting">
+ROLLBACK;
+</pre></div><div class="refsect1" id="id-1.9.3.167.9"><h2>Compatibility</h2><p>
+ The command <code class="command">ROLLBACK</code> conforms to the SQL standard. The
+ form <code class="literal">ROLLBACK TRANSACTION</code> is a PostgreSQL extension.
+ </p></div><div class="refsect1" id="id-1.9.3.167.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT"><span class="refentrytitle">ROLLBACK TO SAVEPOINT</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-revoke.html" title="REVOKE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-rollback-prepared.html" title="ROLLBACK PREPARED">Next</a></td></tr><tr><td width="40%" align="left" valign="top">REVOKE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> ROLLBACK PREPARED</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-savepoint.html b/doc/src/sgml/html/sql-savepoint.html
new file mode 100644
index 0000000..79dcdd8
--- /dev/null
+++ b/doc/src/sgml/html/sql-savepoint.html
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SAVEPOINT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT" /><link rel="next" href="sql-security-label.html" title="SECURITY LABEL" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SAVEPOINT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-security-label.html" title="SECURITY LABEL">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SAVEPOINT"><div class="titlepage"></div><a id="id-1.9.3.170.1" class="indexterm"></a><a id="id-1.9.3.170.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SAVEPOINT</span></h2><p>SAVEPOINT — define a new savepoint within the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SAVEPOINT <em class="replaceable"><code>savepoint_name</code></em>
+</pre></div><div class="refsect1" id="id-1.9.3.170.6"><h2>Description</h2><p>
+ <code class="command">SAVEPOINT</code> establishes a new savepoint within
+ the current transaction.
+ </p><p>
+ A savepoint is a special mark inside a transaction that allows all commands
+ that are executed after it was established to be rolled back, restoring
+ the transaction state to what it was at the time of the savepoint.
+ </p></div><div class="refsect1" id="id-1.9.3.170.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>savepoint_name</code></em></span></dt><dd><p>
+ The name to give to the new savepoint. If savepoints with the
+ same name already exist, they will be inaccessible until newer
+ identically-named savepoints are released.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.170.8"><h2>Notes</h2><p>
+ Use <a class="link" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT"><code class="command">ROLLBACK TO</code></a> to
+ rollback to a savepoint. Use <a class="link" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT"><code class="command">RELEASE SAVEPOINT</code></a>
+ to destroy a savepoint, keeping
+ the effects of commands executed after it was established.
+ </p><p>
+ Savepoints can only be established when inside a transaction block.
+ There can be multiple savepoints defined within a transaction.
+ </p></div><div class="refsect1" id="id-1.9.3.170.9"><h2>Examples</h2><p>
+ To establish a savepoint and later undo the effects of all commands executed
+ after it was established:
+</p><pre class="programlisting">
+BEGIN;
+ INSERT INTO table1 VALUES (1);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (2);
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (3);
+COMMIT;
+</pre><p>
+ The above transaction will insert the values 1 and 3, but not 2.
+ </p><p>
+ To establish and later destroy a savepoint:
+</p><pre class="programlisting">
+BEGIN;
+ INSERT INTO table1 VALUES (3);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (4);
+ RELEASE SAVEPOINT my_savepoint;
+COMMIT;
+</pre><p>
+ The above transaction will insert both 3 and 4.
+ </p><p>
+ To use a single savepoint name:
+</p><pre class="programlisting">
+BEGIN;
+ INSERT INTO table1 VALUES (1);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (2);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (3);
+
+ -- rollback to the second savepoint
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ SELECT * FROM table1; -- shows rows 1 and 2
+
+ -- release the second savepoint
+ RELEASE SAVEPOINT my_savepoint;
+
+ -- rollback to the first savepoint
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ SELECT * FROM table1; -- shows only row 1
+COMMIT;
+</pre><p>
+ The above transaction shows row 3 being rolled back first, then row 2.
+ </p></div><div class="refsect1" id="id-1.9.3.170.10"><h2>Compatibility</h2><p>
+ SQL requires a savepoint to be destroyed automatically when another
+ savepoint with the same name is established. In
+ <span class="productname">PostgreSQL</span>, the old savepoint is kept, though only the more
+ recent one will be used when rolling back or releasing. (Releasing the
+ newer savepoint with <code class="command">RELEASE SAVEPOINT</code> will cause the older one
+ to again become accessible to <code class="command">ROLLBACK TO SAVEPOINT</code> and
+ <code class="command">RELEASE SAVEPOINT</code>.) Otherwise, <code class="command">SAVEPOINT</code> is
+ fully SQL conforming.
+ </p></div><div class="refsect1" id="id-1.9.3.170.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-release-savepoint.html" title="RELEASE SAVEPOINT"><span class="refentrytitle">RELEASE SAVEPOINT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a>, <a class="xref" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT"><span class="refentrytitle">ROLLBACK TO SAVEPOINT</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-rollback-to.html" title="ROLLBACK TO SAVEPOINT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-security-label.html" title="SECURITY LABEL">Next</a></td></tr><tr><td width="40%" align="left" valign="top">ROLLBACK TO SAVEPOINT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SECURITY LABEL</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-security-label.html b/doc/src/sgml/html/sql-security-label.html
new file mode 100644
index 0000000..7afce28
--- /dev/null
+++ b/doc/src/sgml/html/sql-security-label.html
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SECURITY LABEL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-savepoint.html" title="SAVEPOINT" /><link rel="next" href="sql-select.html" title="SELECT" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SECURITY LABEL</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-savepoint.html" title="SAVEPOINT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-select.html" title="SELECT">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SECURITY-LABEL"><div class="titlepage"></div><a id="id-1.9.3.171.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SECURITY LABEL</span></h2><p>SECURITY LABEL — define or change a security label applied to an object</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SECURITY LABEL [ FOR <em class="replaceable"><code>provider</code></em> ] ON
+{
+ TABLE <em class="replaceable"><code>object_name</code></em> |
+ COLUMN <em class="replaceable"><code>table_name</code></em>.<em class="replaceable"><code>column_name</code></em> |
+ AGGREGATE <em class="replaceable"><code>aggregate_name</code></em> ( <em class="replaceable"><code>aggregate_signature</code></em> ) |
+ DATABASE <em class="replaceable"><code>object_name</code></em> |
+ DOMAIN <em class="replaceable"><code>object_name</code></em> |
+ EVENT TRIGGER <em class="replaceable"><code>object_name</code></em> |
+ FOREIGN TABLE <em class="replaceable"><code>object_name</code></em>
+ FUNCTION <em class="replaceable"><code>function_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ LARGE OBJECT <em class="replaceable"><code>large_object_oid</code></em> |
+ MATERIALIZED VIEW <em class="replaceable"><code>object_name</code></em> |
+ [ PROCEDURAL ] LANGUAGE <em class="replaceable"><code>object_name</code></em> |
+ PROCEDURE <em class="replaceable"><code>procedure_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ PUBLICATION <em class="replaceable"><code>object_name</code></em> |
+ ROLE <em class="replaceable"><code>object_name</code></em> |
+ ROUTINE <em class="replaceable"><code>routine_name</code></em> [ ( [ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [, ...] ] ) ] |
+ SCHEMA <em class="replaceable"><code>object_name</code></em> |
+ SEQUENCE <em class="replaceable"><code>object_name</code></em> |
+ SUBSCRIPTION <em class="replaceable"><code>object_name</code></em> |
+ TABLESPACE <em class="replaceable"><code>object_name</code></em> |
+ TYPE <em class="replaceable"><code>object_name</code></em> |
+ VIEW <em class="replaceable"><code>object_name</code></em>
+} IS { <em class="replaceable"><code>string_literal</code></em> | NULL }
+
+<span class="phrase">where <em class="replaceable"><code>aggregate_signature</code></em> is:</span>
+
+* |
+[ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] |
+[ [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ] ] ORDER BY [ <em class="replaceable"><code>argmode</code></em> ] [ <em class="replaceable"><code>argname</code></em> ] <em class="replaceable"><code>argtype</code></em> [ , ... ]
+</pre></div><div class="refsect1" id="id-1.9.3.171.5"><h2>Description</h2><p>
+ <code class="command">SECURITY LABEL</code> applies a security label to a database
+ object. An arbitrary number of security labels, one per label provider, can
+ be associated with a given database object. Label providers are loadable
+ modules which register themselves by using the function
+ <code class="function">register_label_provider</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="function">register_label_provider</code> is not an SQL function; it can
+ only be called from C code loaded into the backend.
+ </p></div><p>
+ The label provider determines whether a given label is valid and whether
+ it is permissible to assign that label to a given object. The meaning of a
+ given label is likewise at the discretion of the label provider.
+ <span class="productname">PostgreSQL</span> places no restrictions on whether or how a
+ label provider must interpret security labels; it merely provides a
+ mechanism for storing them. In practice, this facility is intended to allow
+ integration with label-based mandatory access control (MAC) systems such as
+ <span class="productname">SELinux</span>. Such systems make all access control decisions
+ based on object labels, rather than traditional discretionary access control
+ (DAC) concepts such as users and groups.
+ </p></div><div class="refsect1" id="id-1.9.3.171.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>object_name</code></em><br /></span><span class="term"><em class="replaceable"><code>table_name.column_name</code></em><br /></span><span class="term"><em class="replaceable"><code>aggregate_name</code></em><br /></span><span class="term"><em class="replaceable"><code>function_name</code></em><br /></span><span class="term"><em class="replaceable"><code>procedure_name</code></em><br /></span><span class="term"><em class="replaceable"><code>routine_name</code></em></span></dt><dd><p>
+ The name of the object to be labeled. Names of objects that reside in
+ schemas (tables, functions, etc.) can be schema-qualified.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>provider</code></em></span></dt><dd><p>
+ The name of the provider with which this label is to be associated. The
+ named provider must be loaded and must consent to the proposed labeling
+ operation. If exactly one provider is loaded, the provider name may be
+ omitted for brevity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argmode</code></em></span></dt><dd><p>
+ The mode of a function, procedure, or aggregate
+ argument: <code class="literal">IN</code>, <code class="literal">OUT</code>,
+ <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ If omitted, the default is <code class="literal">IN</code>.
+ Note that <code class="command">SECURITY LABEL</code> does not actually
+ pay any attention to <code class="literal">OUT</code> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <code class="literal">IN</code>, <code class="literal">INOUT</code>,
+ and <code class="literal">VARIADIC</code> arguments.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argname</code></em></span></dt><dd><p>
+ The name of a function, procedure, or aggregate argument.
+ Note that <code class="command">SECURITY LABEL</code> does not actually
+ pay any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>argtype</code></em></span></dt><dd><p>
+ The data type of a function, procedure, or aggregate argument.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>large_object_oid</code></em></span></dt><dd><p>
+ The OID of the large object.
+ </p></dd><dt><span class="term"><code class="literal">PROCEDURAL</code></span></dt><dd><p>
+ This is a noise word.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>string_literal</code></em></span></dt><dd><p>
+ The new setting of the security label, written as a string literal.
+ </p></dd><dt><span class="term"><code class="literal">NULL</code></span></dt><dd><p>
+ Write <code class="literal">NULL</code> to drop the security label.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.171.7"><h2>Examples</h2><p>
+ The following example shows how the security label of a table could
+ be set or changed:
+
+</p><pre class="programlisting">
+SECURITY LABEL FOR selinux ON TABLE mytable IS 'system_u:object_r:sepgsql_table_t:s0';
+</pre><p>
+
+ To remove the label:
+
+</p><pre class="programlisting">
+SECURITY LABEL FOR selinux ON TABLE mytable IS NULL;
+</pre><p>
+ </p></div><div class="refsect1" id="id-1.9.3.171.8"><h2>Compatibility</h2><p>
+ There is no <code class="command">SECURITY LABEL</code> command in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.171.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sepgsql.html" title="F.40. sepgsql">sepgsql</a>, <code class="filename">src/test/modules/dummy_seclabel</code></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-savepoint.html" title="SAVEPOINT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-select.html" title="SELECT">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SAVEPOINT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SELECT</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-select.html b/doc/src/sgml/html/sql-select.html
new file mode 100644
index 0000000..3c96350
--- /dev/null
+++ b/doc/src/sgml/html/sql-select.html
@@ -0,0 +1,1603 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SELECT</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-security-label.html" title="SECURITY LABEL" /><link rel="next" href="sql-selectinto.html" title="SELECT INTO" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SELECT</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-security-label.html" title="SECURITY LABEL">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-selectinto.html" title="SELECT INTO">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SELECT"><div class="titlepage"></div><a id="id-1.9.3.172.1" class="indexterm"></a><a id="id-1.9.3.172.2" class="indexterm"></a><a id="id-1.9.3.172.3" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SELECT</span></h2><p>SELECT, TABLE, WITH — retrieve rows from a table or view</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+[ WITH [ RECURSIVE ] <em class="replaceable"><code>with_query</code></em> [, ...] ]
+SELECT [ ALL | DISTINCT [ ON ( <em class="replaceable"><code>expression</code></em> [, ...] ) ] ]
+ [ * | <em class="replaceable"><code>expression</code></em> [ [ AS ] <em class="replaceable"><code>output_name</code></em> ] [, ...] ]
+ [ FROM <em class="replaceable"><code>from_item</code></em> [, ...] ]
+ [ WHERE <em class="replaceable"><code>condition</code></em> ]
+ [ GROUP BY [ ALL | DISTINCT ] <em class="replaceable"><code>grouping_element</code></em> [, ...] ]
+ [ HAVING <em class="replaceable"><code>condition</code></em> ]
+ [ WINDOW <em class="replaceable"><code>window_name</code></em> AS ( <em class="replaceable"><code>window_definition</code></em> ) [, ...] ]
+ [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] <em class="replaceable"><code>select</code></em> ]
+ [ ORDER BY <em class="replaceable"><code>expression</code></em> [ ASC | DESC | USING <em class="replaceable"><code>operator</code></em> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+ [ LIMIT { <em class="replaceable"><code>count</code></em> | ALL } ]
+ [ OFFSET <em class="replaceable"><code>start</code></em> [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ <em class="replaceable"><code>count</code></em> ] { ROW | ROWS } { ONLY | WITH TIES } ]
+ [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF <em class="replaceable"><code>table_name</code></em> [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]
+
+<span class="phrase">where <em class="replaceable"><code>from_item</code></em> can be one of:</span>
+
+ [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ * ] [ [ AS ] <em class="replaceable"><code>alias</code></em> [ ( <em class="replaceable"><code>column_alias</code></em> [, ...] ) ] ]
+ [ TABLESAMPLE <em class="replaceable"><code>sampling_method</code></em> ( <em class="replaceable"><code>argument</code></em> [, ...] ) [ REPEATABLE ( <em class="replaceable"><code>seed</code></em> ) ] ]
+ [ LATERAL ] ( <em class="replaceable"><code>select</code></em> ) [ AS ] <em class="replaceable"><code>alias</code></em> [ ( <em class="replaceable"><code>column_alias</code></em> [, ...] ) ]
+ <em class="replaceable"><code>with_query_name</code></em> [ [ AS ] <em class="replaceable"><code>alias</code></em> [ ( <em class="replaceable"><code>column_alias</code></em> [, ...] ) ] ]
+ [ LATERAL ] <em class="replaceable"><code>function_name</code></em> ( [ <em class="replaceable"><code>argument</code></em> [, ...] ] )
+ [ WITH ORDINALITY ] [ [ AS ] <em class="replaceable"><code>alias</code></em> [ ( <em class="replaceable"><code>column_alias</code></em> [, ...] ) ] ]
+ [ LATERAL ] <em class="replaceable"><code>function_name</code></em> ( [ <em class="replaceable"><code>argument</code></em> [, ...] ] ) [ AS ] <em class="replaceable"><code>alias</code></em> ( <em class="replaceable"><code>column_definition</code></em> [, ...] )
+ [ LATERAL ] <em class="replaceable"><code>function_name</code></em> ( [ <em class="replaceable"><code>argument</code></em> [, ...] ] ) AS ( <em class="replaceable"><code>column_definition</code></em> [, ...] )
+ [ LATERAL ] ROWS FROM( <em class="replaceable"><code>function_name</code></em> ( [ <em class="replaceable"><code>argument</code></em> [, ...] ] ) [ AS ( <em class="replaceable"><code>column_definition</code></em> [, ...] ) ] [, ...] )
+ [ WITH ORDINALITY ] [ [ AS ] <em class="replaceable"><code>alias</code></em> [ ( <em class="replaceable"><code>column_alias</code></em> [, ...] ) ] ]
+ <em class="replaceable"><code>from_item</code></em> <em class="replaceable"><code>join_type</code></em> <em class="replaceable"><code>from_item</code></em> { ON <em class="replaceable"><code>join_condition</code></em> | USING ( <em class="replaceable"><code>join_column</code></em> [, ...] ) [ AS <em class="replaceable"><code>join_using_alias</code></em> ] }
+ <em class="replaceable"><code>from_item</code></em> NATURAL <em class="replaceable"><code>join_type</code></em> <em class="replaceable"><code>from_item</code></em>
+ <em class="replaceable"><code>from_item</code></em> CROSS JOIN <em class="replaceable"><code>from_item</code></em>
+
+<span class="phrase">and <em class="replaceable"><code>grouping_element</code></em> can be one of:</span>
+
+ ( )
+ <em class="replaceable"><code>expression</code></em>
+ ( <em class="replaceable"><code>expression</code></em> [, ...] )
+ ROLLUP ( { <em class="replaceable"><code>expression</code></em> | ( <em class="replaceable"><code>expression</code></em> [, ...] ) } [, ...] )
+ CUBE ( { <em class="replaceable"><code>expression</code></em> | ( <em class="replaceable"><code>expression</code></em> [, ...] ) } [, ...] )
+ GROUPING SETS ( <em class="replaceable"><code>grouping_element</code></em> [, ...] )
+
+<span class="phrase">and <em class="replaceable"><code>with_query</code></em> is:</span>
+
+ <em class="replaceable"><code>with_query_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( <em class="replaceable"><code>select</code></em> | <em class="replaceable"><code>values</code></em> | <em class="replaceable"><code>insert</code></em> | <em class="replaceable"><code>update</code></em> | <em class="replaceable"><code>delete</code></em> )
+ [ SEARCH { BREADTH | DEPTH } FIRST BY <em class="replaceable"><code>column_name</code></em> [, ...] SET <em class="replaceable"><code>search_seq_col_name</code></em> ]
+ [ CYCLE <em class="replaceable"><code>column_name</code></em> [, ...] SET <em class="replaceable"><code>cycle_mark_col_name</code></em> [ TO <em class="replaceable"><code>cycle_mark_value</code></em> DEFAULT <em class="replaceable"><code>cycle_mark_default</code></em> ] USING <em class="replaceable"><code>cycle_path_col_name</code></em> ]
+
+TABLE [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ * ]
+</pre></div><div class="refsect1" id="id-1.9.3.172.7"><h2>Description</h2><p>
+ <code class="command">SELECT</code> retrieves rows from zero or more tables.
+ The general processing of <code class="command">SELECT</code> is as follows:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ All queries in the <code class="literal">WITH</code> list are computed.
+ These effectively serve as temporary tables that can be referenced
+ in the <code class="literal">FROM</code> list. A <code class="literal">WITH</code> query
+ that is referenced more than once in <code class="literal">FROM</code> is
+ computed only once,
+ unless specified otherwise with <code class="literal">NOT MATERIALIZED</code>.
+ (See <a class="xref" href="sql-select.html#SQL-WITH" title="WITH Clause">WITH Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ All elements in the <code class="literal">FROM</code> list are computed.
+ (Each element in the <code class="literal">FROM</code> list is a real or
+ virtual table.) If more than one element is specified in the
+ <code class="literal">FROM</code> list, they are cross-joined together.
+ (See <a class="xref" href="sql-select.html#SQL-FROM" title="FROM Clause">FROM Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ If the <code class="literal">WHERE</code> clause is specified, all rows
+ that do not satisfy the condition are eliminated from the
+ output. (See <a class="xref" href="sql-select.html#SQL-WHERE" title="WHERE Clause">WHERE Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ If the <code class="literal">GROUP BY</code> clause is specified,
+ or if there are aggregate function calls, the
+ output is combined into groups of rows that match on one or more
+ values, and the results of aggregate functions are computed.
+ If the <code class="literal">HAVING</code> clause is present, it
+ eliminates groups that do not satisfy the given condition. (See
+ <a class="xref" href="sql-select.html#SQL-GROUPBY" title="GROUP BY Clause">GROUP BY Clause</a> and
+ <a class="xref" href="sql-select.html#SQL-HAVING" title="HAVING Clause">HAVING Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ The actual output rows are computed using the
+ <code class="command">SELECT</code> output expressions for each selected
+ row or row group. (See <a class="xref" href="sql-select.html#SQL-SELECT-LIST" title="SELECT List">SELECT List</a> below.)
+ </p></li><li class="listitem"><p><code class="literal">SELECT DISTINCT</code> eliminates duplicate rows from the
+ result. <code class="literal">SELECT DISTINCT ON</code> eliminates rows that
+ match on all the specified expressions. <code class="literal">SELECT ALL</code>
+ (the default) will return all candidate rows, including
+ duplicates. (See <a class="xref" href="sql-select.html#SQL-DISTINCT" title="DISTINCT Clause">DISTINCT Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ Using the operators <code class="literal">UNION</code>,
+ <code class="literal">INTERSECT</code>, and <code class="literal">EXCEPT</code>, the
+ output of more than one <code class="command">SELECT</code> statement can
+ be combined to form a single result set. The
+ <code class="literal">UNION</code> operator returns all rows that are in
+ one or both of the result sets. The
+ <code class="literal">INTERSECT</code> operator returns all rows that are
+ strictly in both result sets. The <code class="literal">EXCEPT</code>
+ operator returns the rows that are in the first result set but
+ not in the second. In all three cases, duplicate rows are
+ eliminated unless <code class="literal">ALL</code> is specified. The noise
+ word <code class="literal">DISTINCT</code> can be added to explicitly specify
+ eliminating duplicate rows. Notice that <code class="literal">DISTINCT</code> is
+ the default behavior here, even though <code class="literal">ALL</code> is
+ the default for <code class="command">SELECT</code> itself. (See
+ <a class="xref" href="sql-select.html#SQL-UNION" title="UNION Clause">UNION Clause</a>, <a class="xref" href="sql-select.html#SQL-INTERSECT" title="INTERSECT Clause">INTERSECT Clause</a>, and
+ <a class="xref" href="sql-select.html#SQL-EXCEPT" title="EXCEPT Clause">EXCEPT Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ If the <code class="literal">ORDER BY</code> clause is specified, the
+ returned rows are sorted in the specified order. If
+ <code class="literal">ORDER BY</code> is not given, the rows are returned
+ in whatever order the system finds fastest to produce. (See
+ <a class="xref" href="sql-select.html#SQL-ORDERBY" title="ORDER BY Clause">ORDER BY Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ If the <code class="literal">LIMIT</code> (or <code class="literal">FETCH FIRST</code>) or <code class="literal">OFFSET</code>
+ clause is specified, the <code class="command">SELECT</code> statement
+ only returns a subset of the result rows. (See <a class="xref" href="sql-select.html#SQL-LIMIT" title="LIMIT Clause">LIMIT Clause</a> below.)
+ </p></li><li class="listitem"><p>
+ If <code class="literal">FOR UPDATE</code>, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR SHARE</code>
+ or <code class="literal">FOR KEY SHARE</code>
+ is specified, the
+ <code class="command">SELECT</code> statement locks the selected rows
+ against concurrent updates. (See <a class="xref" href="sql-select.html#SQL-FOR-UPDATE-SHARE" title="The Locking Clause">The Locking Clause</a>
+ below.)
+ </p></li></ol></div><p>
+ </p><p>
+ You must have <code class="literal">SELECT</code> privilege on each column used
+ in a <code class="command">SELECT</code> command. The use of <code class="literal">FOR NO KEY UPDATE</code>,
+ <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code> or <code class="literal">FOR KEY SHARE</code> requires
+ <code class="literal">UPDATE</code> privilege as well (for at least one column
+ of each table so selected).
+ </p></div><div class="refsect1" id="id-1.9.3.172.8"><h2>Parameters</h2><div class="refsect2" id="SQL-WITH"><h3><code class="literal">WITH</code> Clause</h3><p>
+ The <code class="literal">WITH</code> clause allows you to specify one or more
+ subqueries that can be referenced by name in the primary query.
+ The subqueries effectively act as temporary tables or views
+ for the duration of the primary query.
+ Each subquery can be a <code class="command">SELECT</code>, <code class="command">TABLE</code>, <code class="command">VALUES</code>,
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> statement.
+ When writing a data-modifying statement (<code class="command">INSERT</code>,
+ <code class="command">UPDATE</code> or <code class="command">DELETE</code>) in
+ <code class="literal">WITH</code>, it is usual to include a <code class="literal">RETURNING</code> clause.
+ It is the output of <code class="literal">RETURNING</code>, <span class="emphasis"><em>not</em></span> the underlying
+ table that the statement modifies, that forms the temporary table that is
+ read by the primary query. If <code class="literal">RETURNING</code> is omitted, the
+ statement is still executed, but it produces no output so it cannot be
+ referenced as a table by the primary query.
+ </p><p>
+ A name (without schema qualification) must be specified for each
+ <code class="literal">WITH</code> query. Optionally, a list of column names
+ can be specified; if this is omitted,
+ the column names are inferred from the subquery.
+ </p><p>
+ If <code class="literal">RECURSIVE</code> is specified, it allows a
+ <code class="command">SELECT</code> subquery to reference itself by name. Such a
+ subquery must have the form
+</p><pre class="synopsis">
+<em class="replaceable"><code>non_recursive_term</code></em> UNION [ ALL | DISTINCT ] <em class="replaceable"><code>recursive_term</code></em>
+</pre><p>
+ where the recursive self-reference must appear on the right-hand
+ side of the <code class="literal">UNION</code>. Only one recursive self-reference
+ is permitted per query. Recursive data-modifying statements are not
+ supported, but you can use the results of a recursive
+ <code class="command">SELECT</code> query in
+ a data-modifying statement. See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a> for
+ an example.
+ </p><p>
+ Another effect of <code class="literal">RECURSIVE</code> is that
+ <code class="literal">WITH</code> queries need not be ordered: a query
+ can reference another one that is later in the list. (However,
+ circular references, or mutual recursion, are not implemented.)
+ Without <code class="literal">RECURSIVE</code>, <code class="literal">WITH</code> queries
+ can only reference sibling <code class="literal">WITH</code> queries
+ that are earlier in the <code class="literal">WITH</code> list.
+ </p><p>
+ When there are multiple queries in the <code class="literal">WITH</code>
+ clause, <code class="literal">RECURSIVE</code> should be written only once,
+ immediately after <code class="literal">WITH</code>. It applies to all queries
+ in the <code class="literal">WITH</code> clause, though it has no effect on
+ queries that do not use recursion or forward references.
+ </p><p>
+ The optional <code class="literal">SEARCH</code> clause computes a <em class="firstterm">search
+ sequence column</em> that can be used for ordering the results of a
+ recursive query in either breadth-first or depth-first order. The
+ supplied column name list specifies the row key that is to be used for
+ keeping track of visited rows. A column named
+ <em class="replaceable"><code>search_seq_col_name</code></em> will be added to the result
+ column list of the <code class="literal">WITH</code> query. This column can be
+ ordered by in the outer query to achieve the respective ordering. See
+ <a class="xref" href="queries-with.html#QUERIES-WITH-SEARCH" title="7.8.2.1. Search Order">Section 7.8.2.1</a> for examples.
+ </p><p>
+ The optional <code class="literal">CYCLE</code> clause is used to detect cycles in
+ recursive queries. The supplied column name list specifies the row key
+ that is to be used for keeping track of visited rows. A column named
+ <em class="replaceable"><code>cycle_mark_col_name</code></em> will be added to the result
+ column list of the <code class="literal">WITH</code> query. This column will be set
+ to <em class="replaceable"><code>cycle_mark_value</code></em> when a cycle has been
+ detected, else to <em class="replaceable"><code>cycle_mark_default</code></em>.
+ Furthermore, processing of the recursive union will stop when a cycle has
+ been detected. <em class="replaceable"><code>cycle_mark_value</code></em> and
+ <em class="replaceable"><code>cycle_mark_default</code></em> must be constants and they
+ must be coercible to a common data type, and the data type must have an
+ inequality operator. (The SQL standard requires that they be Boolean
+ constants or character strings, but PostgreSQL does not require that.) By
+ default, <code class="literal">TRUE</code> and <code class="literal">FALSE</code> (of type
+ <code class="type">boolean</code>) are used. Furthermore, a column
+ named <em class="replaceable"><code>cycle_path_col_name</code></em> will be added to the
+ result column list of the <code class="literal">WITH</code> query. This column is
+ used internally for tracking visited rows. See <a class="xref" href="queries-with.html#QUERIES-WITH-CYCLE" title="7.8.2.2. Cycle Detection">Section 7.8.2.2</a> for examples.
+ </p><p>
+ Both the <code class="literal">SEARCH</code> and the <code class="literal">CYCLE</code> clause
+ are only valid for recursive <code class="literal">WITH</code> queries. The
+ <em class="replaceable"><code>with_query</code></em> must be a <code class="literal">UNION</code>
+ (or <code class="literal">UNION ALL</code>) of two <code class="literal">SELECT</code> (or
+ equivalent) commands (no nested <code class="literal">UNION</code>s). If both
+ clauses are used, the column added by the <code class="literal">SEARCH</code> clause
+ appears before the columns added by the <code class="literal">CYCLE</code> clause.
+ </p><p>
+ The primary query and the <code class="literal">WITH</code> queries are all
+ (notionally) executed at the same time. This implies that the effects of
+ a data-modifying statement in <code class="literal">WITH</code> cannot be seen from
+ other parts of the query, other than by reading its <code class="literal">RETURNING</code>
+ output. If two such data-modifying statements attempt to modify the same
+ row, the results are unspecified.
+ </p><p>
+ A key property of <code class="literal">WITH</code> queries is that they
+ are normally evaluated only once per execution of the primary query,
+ even if the primary query refers to them more than once.
+ In particular, data-modifying statements are guaranteed to be
+ executed once and only once, regardless of whether the primary query
+ reads all or any of their output.
+ </p><p>
+ However, a <code class="literal">WITH</code> query can be marked
+ <code class="literal">NOT MATERIALIZED</code> to remove this guarantee. In that
+ case, the <code class="literal">WITH</code> query can be folded into the primary
+ query much as though it were a simple sub-<code class="literal">SELECT</code> in
+ the primary query's <code class="literal">FROM</code> clause. This results in
+ duplicate computations if the primary query refers to
+ that <code class="literal">WITH</code> query more than once; but if each such use
+ requires only a few rows of the <code class="literal">WITH</code> query's total
+ output, <code class="literal">NOT MATERIALIZED</code> can provide a net savings by
+ allowing the queries to be optimized jointly.
+ <code class="literal">NOT MATERIALIZED</code> is ignored if it is attached to
+ a <code class="literal">WITH</code> query that is recursive or is not
+ side-effect-free (i.e., is not a plain <code class="literal">SELECT</code>
+ containing no volatile functions).
+ </p><p>
+ By default, a side-effect-free <code class="literal">WITH</code> query is folded
+ into the primary query if it is used exactly once in the primary
+ query's <code class="literal">FROM</code> clause. This allows joint optimization
+ of the two query levels in situations where that should be semantically
+ invisible. However, such folding can be prevented by marking the
+ <code class="literal">WITH</code> query as <code class="literal">MATERIALIZED</code>.
+ That might be useful, for example, if the <code class="literal">WITH</code> query
+ is being used as an optimization fence to prevent the planner from
+ choosing a bad plan.
+ <span class="productname">PostgreSQL</span> versions before v12 never did
+ such folding, so queries written for older versions might rely on
+ <code class="literal">WITH</code> to act as an optimization fence.
+ </p><p>
+ See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a> for additional information.
+ </p></div><div class="refsect2" id="SQL-FROM"><h3><code class="literal">FROM</code> Clause</h3><p>
+ The <code class="literal">FROM</code> clause specifies one or more source
+ tables for the <code class="command">SELECT</code>. If multiple sources are
+ specified, the result is the Cartesian product (cross join) of all
+ the sources. But usually qualification conditions are added (via
+ <code class="literal">WHERE</code>) to restrict the returned rows to a small subset of the
+ Cartesian product.
+ </p><p>
+ The <code class="literal">FROM</code> clause can contain the following
+ elements:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of an existing table or view.
+ If <code class="literal">ONLY</code> is specified before the table name, only that
+ table is scanned. If <code class="literal">ONLY</code> is not specified, the table
+ and all its descendant tables (if any) are scanned. Optionally,
+ <code class="literal">*</code> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>alias</code></em></span></dt><dd><p>
+ A substitute name for the <code class="literal">FROM</code> item containing the
+ alias. An alias is used for brevity or to eliminate ambiguity
+ for self-joins (where the same table is scanned multiple
+ times). When an alias is provided, it completely hides the
+ actual name of the table or function; for example given
+ <code class="literal">FROM foo AS f</code>, the remainder of the
+ <code class="command">SELECT</code> must refer to this <code class="literal">FROM</code>
+ item as <code class="literal">f</code> not <code class="literal">foo</code>. If an alias is
+ written, a column alias list can also be written to provide
+ substitute names for one or more columns of the table.
+ </p></dd><dt><span class="term"><code class="literal">TABLESAMPLE <em class="replaceable"><code>sampling_method</code></em> ( <em class="replaceable"><code>argument</code></em> [, ...] ) [ REPEATABLE ( <em class="replaceable"><code>seed</code></em> ) ]</code></span></dt><dd><p>
+ A <code class="literal">TABLESAMPLE</code> clause after
+ a <em class="replaceable"><code>table_name</code></em> indicates that the
+ specified <em class="replaceable"><code>sampling_method</code></em>
+ should be used to retrieve a subset of the rows in that table.
+ This sampling precedes the application of any other filters such
+ as <code class="literal">WHERE</code> clauses.
+ The standard <span class="productname">PostgreSQL</span> distribution
+ includes two sampling methods, <code class="literal">BERNOULLI</code>
+ and <code class="literal">SYSTEM</code>, and other sampling methods can be
+ installed in the database via extensions.
+ </p><p>
+ The <code class="literal">BERNOULLI</code> and <code class="literal">SYSTEM</code> sampling methods
+ each accept a single <em class="replaceable"><code>argument</code></em>
+ which is the fraction of the table to sample, expressed as a
+ percentage between 0 and 100. This argument can be
+ any <code class="type">real</code>-valued expression. (Other sampling methods might
+ accept more or different arguments.) These two methods each return
+ a randomly-chosen sample of the table that will contain
+ approximately the specified percentage of the table's rows.
+ The <code class="literal">BERNOULLI</code> method scans the whole table and
+ selects or ignores individual rows independently with the specified
+ probability.
+ The <code class="literal">SYSTEM</code> method does block-level sampling with
+ each block having the specified chance of being selected; all rows
+ in each selected block are returned.
+ The <code class="literal">SYSTEM</code> method is significantly faster than
+ the <code class="literal">BERNOULLI</code> method when small sampling
+ percentages are specified, but it may return a less-random sample of
+ the table as a result of clustering effects.
+ </p><p>
+ The optional <code class="literal">REPEATABLE</code> clause specifies
+ a <em class="replaceable"><code>seed</code></em> number or expression to use
+ for generating random numbers within the sampling method. The seed
+ value can be any non-null floating-point value. Two queries that
+ specify the same seed and <em class="replaceable"><code>argument</code></em>
+ values will select the same sample of the table, if the table has
+ not been changed meanwhile. But different seed values will usually
+ produce different samples.
+ If <code class="literal">REPEATABLE</code> is not given then a new random
+ sample is selected for each query, based upon a system-generated seed.
+ Note that some add-on sampling methods do not
+ accept <code class="literal">REPEATABLE</code>, and will always produce new
+ samples on each use.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>select</code></em></span></dt><dd><p>
+ A sub-<code class="command">SELECT</code> can appear in the
+ <code class="literal">FROM</code> clause. This acts as though its
+ output were created as a temporary table for the duration of
+ this single <code class="command">SELECT</code> command. Note that the
+ sub-<code class="command">SELECT</code> must be surrounded by
+ parentheses, and an alias <span class="emphasis"><em>must</em></span> be
+ provided for it. A
+ <a class="link" href="sql-values.html" title="VALUES"><code class="command">VALUES</code></a> command
+ can also be used here.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>with_query_name</code></em></span></dt><dd><p>
+ A <code class="literal">WITH</code> query is referenced by writing its name,
+ just as though the query's name were a table name. (In fact,
+ the <code class="literal">WITH</code> query hides any real table of the same name
+ for the purposes of the primary query. If necessary, you can
+ refer to a real table of the same name by schema-qualifying
+ the table's name.)
+ An alias can be provided in the same way as for a table.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
+ Function calls can appear in the <code class="literal">FROM</code>
+ clause. (This is especially useful for functions that return
+ result sets, but any function can be used.) This acts as
+ though the function's output were created as a temporary table for the
+ duration of this single <code class="command">SELECT</code> command.
+ If the function's result type is composite (including the case of a
+ function with multiple <code class="literal">OUT</code> parameters), each
+ attribute becomes a separate column in the implicit table.
+ </p><p>
+ When the optional <code class="command">WITH ORDINALITY</code> clause is added
+ to the function call, an additional column of type <code class="type">bigint</code>
+ will be appended to the function's result column(s). This column
+ numbers the rows of the function's result set, starting from 1.
+ By default, this column is named <code class="literal">ordinality</code>.
+ </p><p>
+ An alias can be provided in the same way as for a table.
+ If an alias is written, a column
+ alias list can also be written to provide substitute names for
+ one or more attributes of the function's composite return
+ type, including the ordinality column if present.
+ </p><p>
+ Multiple function calls can be combined into a
+ single <code class="literal">FROM</code>-clause item by surrounding them
+ with <code class="literal">ROWS FROM( ... )</code>. The output of such an item is the
+ concatenation of the first row from each function, then the second
+ row from each function, etc. If some of the functions produce fewer
+ rows than others, null values are substituted for the missing data, so
+ that the total number of rows returned is always the same as for the
+ function that produced the most rows.
+ </p><p>
+ If the function has been defined as returning the
+ <code class="type">record</code> data type, then an alias or the key word
+ <code class="literal">AS</code> must be present, followed by a column
+ definition list in the form <code class="literal">( <em class="replaceable"><code>column_name</code></em> <em class="replaceable"><code>data_type</code></em> [<span class="optional">, ...
+ </span>])</code>. The column definition list must match the
+ actual number and types of columns returned by the function.
+ </p><p>
+ When using the <code class="literal">ROWS FROM( ... )</code> syntax, if one of the
+ functions requires a column definition list, it's preferred to put
+ the column definition list after the function call inside
+ <code class="literal">ROWS FROM( ... )</code>. A column definition list can be placed
+ after the <code class="literal">ROWS FROM( ... )</code> construct only if there's just
+ a single function and no <code class="literal">WITH ORDINALITY</code> clause.
+ </p><p>
+ To use <code class="literal">ORDINALITY</code> together with a column definition
+ list, you must use the <code class="literal">ROWS FROM( ... )</code> syntax and put the
+ column definition list inside <code class="literal">ROWS FROM( ... )</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>join_type</code></em></span></dt><dd><p>
+ One of
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">[ INNER ] JOIN</code></p></li><li class="listitem"><p><code class="literal">LEFT [ OUTER ] JOIN</code></p></li><li class="listitem"><p><code class="literal">RIGHT [ OUTER ] JOIN</code></p></li><li class="listitem"><p><code class="literal">FULL [ OUTER ] JOIN</code></p></li></ul></div><p>
+
+ For the <code class="literal">INNER</code> and <code class="literal">OUTER</code> join types, a
+ join condition must be specified, namely exactly one of
+ <code class="literal">ON <em class="replaceable"><code>join_condition</code></em></code>,
+ <code class="literal">USING (<em class="replaceable"><code>join_column</code></em> [, ...])</code>,
+ or <code class="literal">NATURAL</code>. See below for the meaning.
+ </p><p>
+ A <code class="literal">JOIN</code> clause combines two <code class="literal">FROM</code>
+ items, which for convenience we will refer to as <span class="quote">“<span class="quote">tables</span>”</span>,
+ though in reality they can be any type of <code class="literal">FROM</code> item.
+ Use parentheses if necessary to determine the order of nesting.
+ In the absence of parentheses, <code class="literal">JOIN</code>s nest
+ left-to-right. In any case <code class="literal">JOIN</code> binds more
+ tightly than the commas separating <code class="literal">FROM</code>-list items.
+ All the <code class="literal">JOIN</code> options are just a notational
+ convenience, since they do nothing you couldn't do with plain
+ <code class="literal">FROM</code> and <code class="literal">WHERE</code>.
+ </p><p><code class="literal">LEFT OUTER JOIN</code> returns all rows in the qualified
+ Cartesian product (i.e., all combined rows that pass its join
+ condition), plus one copy of each row in the left-hand table
+ for which there was no right-hand row that passed the join
+ condition. This left-hand row is extended to the full width
+ of the joined table by inserting null values for the
+ right-hand columns. Note that only the <code class="literal">JOIN</code>
+ clause's own condition is considered while deciding which rows
+ have matches. Outer conditions are applied afterwards.
+ </p><p>
+ Conversely, <code class="literal">RIGHT OUTER JOIN</code> returns all the
+ joined rows, plus one row for each unmatched right-hand row
+ (extended with nulls on the left). This is just a notational
+ convenience, since you could convert it to a <code class="literal">LEFT
+ OUTER JOIN</code> by switching the left and right tables.
+ </p><p><code class="literal">FULL OUTER JOIN</code> returns all the joined rows, plus
+ one row for each unmatched left-hand row (extended with nulls
+ on the right), plus one row for each unmatched right-hand row
+ (extended with nulls on the left).
+ </p></dd><dt><span class="term"><code class="literal">ON <em class="replaceable"><code>join_condition</code></em></code></span></dt><dd><p><em class="replaceable"><code>join_condition</code></em> is
+ an expression resulting in a value of type
+ <code class="type">boolean</code> (similar to a <code class="literal">WHERE</code>
+ clause) that specifies which rows in a join are considered to
+ match.
+ </p></dd><dt><span class="term"><code class="literal">USING ( <em class="replaceable"><code>join_column</code></em> [, ...] ) [ AS <em class="replaceable"><code>join_using_alias</code></em> ]</code></span></dt><dd><p>
+ A clause of the form <code class="literal">USING ( a, b, ... )</code> is
+ shorthand for <code class="literal">ON left_table.a = right_table.a AND
+ left_table.b = right_table.b ...</code>. Also,
+ <code class="literal">USING</code> implies that only one of each pair of
+ equivalent columns will be included in the join output, not
+ both.
+ </p><p>
+ If a <em class="replaceable"><code>join_using_alias</code></em>
+ name is specified, it provides a table alias for the join columns.
+ Only the join columns listed in the <code class="literal">USING</code> clause
+ are addressable by this name. Unlike a regular <em class="replaceable"><code>alias</code></em>, this does not hide the names of
+ the joined tables from the rest of the query. Also unlike a regular
+ <em class="replaceable"><code>alias</code></em>, you cannot write a
+ column alias list — the output names of the join columns are the
+ same as they appear in the <code class="literal">USING</code> list.
+ </p></dd><dt><span class="term"><code class="literal">NATURAL</code></span></dt><dd><p>
+ <code class="literal">NATURAL</code> is shorthand for a
+ <code class="literal">USING</code> list that mentions all columns in the two
+ tables that have matching names. If there are no common
+ column names, <code class="literal">NATURAL</code> is equivalent
+ to <code class="literal">ON TRUE</code>.
+ </p></dd><dt><span class="term"><code class="literal">CROSS JOIN</code></span></dt><dd><p>
+ <code class="literal">CROSS JOIN</code> is equivalent to <code class="literal">INNER JOIN ON
+ (TRUE)</code>, that is, no rows are removed by qualification.
+ They produce a simple Cartesian product, the same result as you get from
+ listing the two tables at the top level of <code class="literal">FROM</code>,
+ but restricted by the join condition (if any).
+ </p></dd><dt><span class="term"><code class="literal">LATERAL</code></span></dt><dd><p>
+ The <code class="literal">LATERAL</code> key word can precede a
+ sub-<code class="command">SELECT</code> <code class="literal">FROM</code> item. This allows the
+ sub-<code class="command">SELECT</code> to refer to columns of <code class="literal">FROM</code>
+ items that appear before it in the <code class="literal">FROM</code> list. (Without
+ <code class="literal">LATERAL</code>, each sub-<code class="command">SELECT</code> is
+ evaluated independently and so cannot cross-reference any other
+ <code class="literal">FROM</code> item.)
+ </p><p><code class="literal">LATERAL</code> can also precede a function-call
+ <code class="literal">FROM</code> item, but in this case it is a noise word, because
+ the function expression can refer to earlier <code class="literal">FROM</code> items
+ in any case.
+ </p><p>
+ A <code class="literal">LATERAL</code> item can appear at top level in the
+ <code class="literal">FROM</code> list, or within a <code class="literal">JOIN</code> tree. In the
+ latter case it can also refer to any items that are on the left-hand
+ side of a <code class="literal">JOIN</code> that it is on the right-hand side of.
+ </p><p>
+ When a <code class="literal">FROM</code> item contains <code class="literal">LATERAL</code>
+ cross-references, evaluation proceeds as follows: for each row of the
+ <code class="literal">FROM</code> item providing the cross-referenced column(s), or
+ set of rows of multiple <code class="literal">FROM</code> items providing the
+ columns, the <code class="literal">LATERAL</code> item is evaluated using that
+ row or row set's values of the columns. The resulting row(s) are
+ joined as usual with the rows they were computed from. This is
+ repeated for each row or set of rows from the column source table(s).
+ </p><p>
+ The column source table(s) must be <code class="literal">INNER</code> or
+ <code class="literal">LEFT</code> joined to the <code class="literal">LATERAL</code> item, else
+ there would not be a well-defined set of rows from which to compute
+ each set of rows for the <code class="literal">LATERAL</code> item. Thus,
+ although a construct such as <code class="literal"><em class="replaceable"><code>X</code></em> RIGHT JOIN
+ LATERAL <em class="replaceable"><code>Y</code></em></code> is syntactically valid, it is
+ not actually allowed for <em class="replaceable"><code>Y</code></em> to reference
+ <em class="replaceable"><code>X</code></em>.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect2" id="SQL-WHERE"><h3><code class="literal">WHERE</code> Clause</h3><p>
+ The optional <code class="literal">WHERE</code> clause has the general form
+</p><pre class="synopsis">
+WHERE <em class="replaceable"><code>condition</code></em>
+</pre><p>
+ where <em class="replaceable"><code>condition</code></em> is
+ any expression that evaluates to a result of type
+ <code class="type">boolean</code>. Any row that does not satisfy this
+ condition will be eliminated from the output. A row satisfies the
+ condition if it returns true when the actual row values are
+ substituted for any variable references.
+ </p></div><div class="refsect2" id="SQL-GROUPBY"><h3><code class="literal">GROUP BY</code> Clause</h3><p>
+ The optional <code class="literal">GROUP BY</code> clause has the general form
+</p><pre class="synopsis">
+GROUP BY [ ALL | DISTINCT ] <em class="replaceable"><code>grouping_element</code></em> [, ...]
+</pre><p>
+ </p><p>
+ <code class="literal">GROUP BY</code> will condense into a single row all
+ selected rows that share the same values for the grouped
+ expressions. An <em class="replaceable"><code>expression</code></em> used inside a
+ <em class="replaceable"><code>grouping_element</code></em>
+ can be an input column name, or the name or ordinal number of an
+ output column (<code class="command">SELECT</code> list item), or an arbitrary
+ expression formed from input-column values. In case of ambiguity,
+ a <code class="literal">GROUP BY</code> name will be interpreted as an
+ input-column name rather than an output column name.
+ </p><p>
+ If any of <code class="literal">GROUPING SETS</code>, <code class="literal">ROLLUP</code> or
+ <code class="literal">CUBE</code> are present as grouping elements, then the
+ <code class="literal">GROUP BY</code> clause as a whole defines some number of
+ independent <em class="replaceable"><code>grouping sets</code></em>. The effect of this is
+ equivalent to constructing a <code class="literal">UNION ALL</code> between
+ subqueries with the individual grouping sets as their
+ <code class="literal">GROUP BY</code> clauses. The optional <code class="literal">DISTINCT</code>
+ clause removes duplicate sets before processing; it does <span class="emphasis"><em>not</em></span>
+ transform the <code class="literal">UNION ALL</code> into a <code class="literal">UNION DISTINCT</code>.
+ For further details on the handling
+ of grouping sets see <a class="xref" href="queries-table-expressions.html#QUERIES-GROUPING-SETS" title="7.2.4. GROUPING SETS, CUBE, and ROLLUP">Section 7.2.4</a>.
+ </p><p>
+ Aggregate functions, if any are used, are computed across all rows
+ making up each group, producing a separate value for each group.
+ (If there are aggregate functions but no <code class="literal">GROUP BY</code>
+ clause, the query is treated as having a single group comprising all
+ the selected rows.)
+ The set of rows fed to each aggregate function can be further filtered by
+ attaching a <code class="literal">FILTER</code> clause to the aggregate function
+ call; see <a class="xref" href="sql-expressions.html#SYNTAX-AGGREGATES" title="4.2.7. Aggregate Expressions">Section 4.2.7</a> for more information. When
+ a <code class="literal">FILTER</code> clause is present, only those rows matching it
+ are included in the input to that aggregate function.
+ </p><p>
+ When <code class="literal">GROUP BY</code> is present,
+ or any aggregate functions are present, it is not valid for
+ the <code class="command">SELECT</code> list expressions to refer to
+ ungrouped columns except within aggregate functions or when the
+ ungrouped column is functionally dependent on the grouped columns,
+ since there would otherwise be more than one possible value to
+ return for an ungrouped column. A functional dependency exists if
+ the grouped columns (or a subset thereof) are the primary key of
+ the table containing the ungrouped column.
+ </p><p>
+ Keep in mind that all aggregate functions are evaluated before
+ evaluating any <span class="quote">“<span class="quote">scalar</span>”</span> expressions in the <code class="literal">HAVING</code>
+ clause or <code class="literal">SELECT</code> list. This means that, for example,
+ a <code class="literal">CASE</code> expression cannot be used to skip evaluation of
+ an aggregate function; see <a class="xref" href="sql-expressions.html#SYNTAX-EXPRESS-EVAL" title="4.2.14. Expression Evaluation Rules">Section 4.2.14</a>.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code> and <code class="literal">FOR KEY SHARE</code> cannot be
+ specified with <code class="literal">GROUP BY</code>.
+ </p></div><div class="refsect2" id="SQL-HAVING"><h3><code class="literal">HAVING</code> Clause</h3><p>
+ The optional <code class="literal">HAVING</code> clause has the general form
+</p><pre class="synopsis">
+HAVING <em class="replaceable"><code>condition</code></em>
+</pre><p>
+ where <em class="replaceable"><code>condition</code></em> is
+ the same as specified for the <code class="literal">WHERE</code> clause.
+ </p><p>
+ <code class="literal">HAVING</code> eliminates group rows that do not
+ satisfy the condition. <code class="literal">HAVING</code> is different
+ from <code class="literal">WHERE</code>: <code class="literal">WHERE</code> filters
+ individual rows before the application of <code class="literal">GROUP
+ BY</code>, while <code class="literal">HAVING</code> filters group rows
+ created by <code class="literal">GROUP BY</code>. Each column referenced in
+ <em class="replaceable"><code>condition</code></em> must
+ unambiguously reference a grouping column, unless the reference
+ appears within an aggregate function or the ungrouped column is
+ functionally dependent on the grouping columns.
+ </p><p>
+ The presence of <code class="literal">HAVING</code> turns a query into a grouped
+ query even if there is no <code class="literal">GROUP BY</code> clause. This is the
+ same as what happens when the query contains aggregate functions but
+ no <code class="literal">GROUP BY</code> clause. All the selected rows are considered to
+ form a single group, and the <code class="command">SELECT</code> list and
+ <code class="literal">HAVING</code> clause can only reference table columns from
+ within aggregate functions. Such a query will emit a single row if the
+ <code class="literal">HAVING</code> condition is true, zero rows if it is not true.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code> and <code class="literal">FOR KEY SHARE</code> cannot be
+ specified with <code class="literal">HAVING</code>.
+ </p></div><div class="refsect2" id="SQL-WINDOW"><h3><code class="literal">WINDOW</code> Clause</h3><p>
+ The optional <code class="literal">WINDOW</code> clause has the general form
+</p><pre class="synopsis">
+WINDOW <em class="replaceable"><code>window_name</code></em> AS ( <em class="replaceable"><code>window_definition</code></em> ) [, ...]
+</pre><p>
+ where <em class="replaceable"><code>window_name</code></em> is
+ a name that can be referenced from <code class="literal">OVER</code> clauses or
+ subsequent window definitions, and
+ <em class="replaceable"><code>window_definition</code></em> is
+</p><pre class="synopsis">
+[ <em class="replaceable"><code>existing_window_name</code></em> ]
+[ PARTITION BY <em class="replaceable"><code>expression</code></em> [, ...] ]
+[ ORDER BY <em class="replaceable"><code>expression</code></em> [ ASC | DESC | USING <em class="replaceable"><code>operator</code></em> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+[ <em class="replaceable"><code>frame_clause</code></em> ]
+</pre><p>
+ </p><p>
+ If an <em class="replaceable"><code>existing_window_name</code></em>
+ is specified it must refer to an earlier entry in the <code class="literal">WINDOW</code>
+ list; the new window copies its partitioning clause from that entry,
+ as well as its ordering clause if any. In this case the new window cannot
+ specify its own <code class="literal">PARTITION BY</code> clause, and it can specify
+ <code class="literal">ORDER BY</code> only if the copied window does not have one.
+ The new window always uses its own frame clause; the copied window
+ must not specify a frame clause.
+ </p><p>
+ The elements of the <code class="literal">PARTITION BY</code> list are interpreted in
+ much the same fashion as elements of a <a class="link" href="sql-select.html#SQL-GROUPBY" title="GROUP BY Clause"><code class="literal">GROUP BY</code></a> clause, except that
+ they are always simple expressions and never the name or number of an
+ output column.
+ Another difference is that these expressions can contain aggregate
+ function calls, which are not allowed in a regular <code class="literal">GROUP BY</code>
+ clause. They are allowed here because windowing occurs after grouping
+ and aggregation.
+ </p><p>
+ Similarly, the elements of the <code class="literal">ORDER BY</code> list are interpreted
+ in much the same fashion as elements of a statement-level <a class="link" href="sql-select.html#SQL-ORDERBY" title="ORDER BY Clause"><code class="literal">ORDER BY</code></a> clause, except that
+ the expressions are always taken as simple expressions and never the name
+ or number of an output column.
+ </p><p>
+ The optional <em class="replaceable"><code>frame_clause</code></em> defines
+ the <em class="firstterm">window frame</em> for window functions that depend on the
+ frame (not all do). The window frame is a set of related rows for
+ each row of the query (called the <em class="firstterm">current row</em>).
+ The <em class="replaceable"><code>frame_clause</code></em> can be one of
+
+</p><pre class="synopsis">
+{ RANGE | ROWS | GROUPS } <em class="replaceable"><code>frame_start</code></em> [ <em class="replaceable"><code>frame_exclusion</code></em> ]
+{ RANGE | ROWS | GROUPS } BETWEEN <em class="replaceable"><code>frame_start</code></em> AND <em class="replaceable"><code>frame_end</code></em> [ <em class="replaceable"><code>frame_exclusion</code></em> ]
+</pre><p>
+
+ where <em class="replaceable"><code>frame_start</code></em>
+ and <em class="replaceable"><code>frame_end</code></em> can be one of
+
+</p><pre class="synopsis">
+UNBOUNDED PRECEDING
+<em class="replaceable"><code>offset</code></em> PRECEDING
+CURRENT ROW
+<em class="replaceable"><code>offset</code></em> FOLLOWING
+UNBOUNDED FOLLOWING
+</pre><p>
+
+ and <em class="replaceable"><code>frame_exclusion</code></em> can be one of
+
+</p><pre class="synopsis">
+EXCLUDE CURRENT ROW
+EXCLUDE GROUP
+EXCLUDE TIES
+EXCLUDE NO OTHERS
+</pre><p>
+
+ If <em class="replaceable"><code>frame_end</code></em> is omitted it defaults to <code class="literal">CURRENT
+ ROW</code>. Restrictions are that
+ <em class="replaceable"><code>frame_start</code></em> cannot be <code class="literal">UNBOUNDED FOLLOWING</code>,
+ <em class="replaceable"><code>frame_end</code></em> cannot be <code class="literal">UNBOUNDED PRECEDING</code>,
+ and the <em class="replaceable"><code>frame_end</code></em> choice cannot appear earlier in the
+ above list of <em class="replaceable"><code>frame_start</code></em>
+ and <em class="replaceable"><code>frame_end</code></em> options than
+ the <em class="replaceable"><code>frame_start</code></em> choice does — for example
+ <code class="literal">RANGE BETWEEN CURRENT ROW AND <em class="replaceable"><code>offset</code></em>
+ PRECEDING</code> is not allowed.
+ </p><p>
+ The default framing option is <code class="literal">RANGE UNBOUNDED PRECEDING</code>,
+ which is the same as <code class="literal">RANGE BETWEEN UNBOUNDED PRECEDING AND
+ CURRENT ROW</code>; it sets the frame to be all rows from the partition start
+ up through the current row's last <em class="firstterm">peer</em> (a row
+ that the window's <code class="literal">ORDER BY</code> clause considers
+ equivalent to the current row; all rows are peers if there
+ is no <code class="literal">ORDER BY</code>).
+ In general, <code class="literal">UNBOUNDED PRECEDING</code> means that the frame
+ starts with the first row of the partition, and similarly
+ <code class="literal">UNBOUNDED FOLLOWING</code> means that the frame ends with the last
+ row of the partition, regardless
+ of <code class="literal">RANGE</code>, <code class="literal">ROWS</code>
+ or <code class="literal">GROUPS</code> mode.
+ In <code class="literal">ROWS</code> mode, <code class="literal">CURRENT ROW</code> means
+ that the frame starts or ends with the current row; but
+ in <code class="literal">RANGE</code> or <code class="literal">GROUPS</code> mode it means
+ that the frame starts or ends with the current row's first or last peer
+ in the <code class="literal">ORDER BY</code> ordering.
+ The <em class="replaceable"><code>offset</code></em> <code class="literal">PRECEDING</code> and
+ <em class="replaceable"><code>offset</code></em> <code class="literal">FOLLOWING</code> options
+ vary in meaning depending on the frame mode.
+ In <code class="literal">ROWS</code> mode, the <em class="replaceable"><code>offset</code></em>
+ is an integer indicating that the frame starts or ends that many rows
+ before or after the current row.
+ In <code class="literal">GROUPS</code> mode, the <em class="replaceable"><code>offset</code></em>
+ is an integer indicating that the frame starts or ends that many peer
+ groups before or after the current row's peer group, where
+ a <em class="firstterm">peer group</em> is a group of rows that are
+ equivalent according to the window's <code class="literal">ORDER BY</code> clause.
+ In <code class="literal">RANGE</code> mode, use of
+ an <em class="replaceable"><code>offset</code></em> option requires that there be
+ exactly one <code class="literal">ORDER BY</code> column in the window definition.
+ Then the frame contains those rows whose ordering column value is no
+ more than <em class="replaceable"><code>offset</code></em> less than
+ (for <code class="literal">PRECEDING</code>) or more than
+ (for <code class="literal">FOLLOWING</code>) the current row's ordering column
+ value. In these cases the data type of
+ the <em class="replaceable"><code>offset</code></em> expression depends on the data
+ type of the ordering column. For numeric ordering columns it is
+ typically of the same type as the ordering column, but for datetime
+ ordering columns it is an <code class="type">interval</code>.
+ In all these cases, the value of the <em class="replaceable"><code>offset</code></em>
+ must be non-null and non-negative. Also, while
+ the <em class="replaceable"><code>offset</code></em> does not have to be a simple
+ constant, it cannot contain variables, aggregate functions, or window
+ functions.
+ </p><p>
+ The <em class="replaceable"><code>frame_exclusion</code></em> option allows rows around
+ the current row to be excluded from the frame, even if they would be
+ included according to the frame start and frame end options.
+ <code class="literal">EXCLUDE CURRENT ROW</code> excludes the current row from the
+ frame.
+ <code class="literal">EXCLUDE GROUP</code> excludes the current row and its
+ ordering peers from the frame.
+ <code class="literal">EXCLUDE TIES</code> excludes any peers of the current
+ row from the frame, but not the current row itself.
+ <code class="literal">EXCLUDE NO OTHERS</code> simply specifies explicitly the
+ default behavior of not excluding the current row or its peers.
+ </p><p>
+ Beware that the <code class="literal">ROWS</code> mode can produce unpredictable
+ results if the <code class="literal">ORDER BY</code> ordering does not order the rows
+ uniquely. The <code class="literal">RANGE</code> and <code class="literal">GROUPS</code>
+ modes are designed to ensure that rows that are peers in
+ the <code class="literal">ORDER BY</code> ordering are treated alike: all rows of
+ a given peer group will be in the frame or excluded from it.
+ </p><p>
+ The purpose of a <code class="literal">WINDOW</code> clause is to specify the
+ behavior of <em class="firstterm">window functions</em> appearing in the query's
+ <a class="link" href="sql-select.html#SQL-SELECT-LIST" title="SELECT List"><code class="command">SELECT</code> list</a> or
+ <a class="link" href="sql-select.html#SQL-ORDERBY" title="ORDER BY Clause"><code class="literal">ORDER BY</code></a> clause.
+ These functions
+ can reference the <code class="literal">WINDOW</code> clause entries by name
+ in their <code class="literal">OVER</code> clauses. A <code class="literal">WINDOW</code> clause
+ entry does not have to be referenced anywhere, however; if it is not
+ used in the query it is simply ignored. It is possible to use window
+ functions without any <code class="literal">WINDOW</code> clause at all, since
+ a window function call can specify its window definition directly in
+ its <code class="literal">OVER</code> clause. However, the <code class="literal">WINDOW</code>
+ clause saves typing when the same window definition is needed for more
+ than one window function.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code> and <code class="literal">FOR KEY SHARE</code> cannot be
+ specified with <code class="literal">WINDOW</code>.
+ </p><p>
+ Window functions are described in detail in
+ <a class="xref" href="tutorial-window.html" title="3.5. Window Functions">Section 3.5</a>,
+ <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a>, and
+ <a class="xref" href="queries-table-expressions.html#QUERIES-WINDOW" title="7.2.5. Window Function Processing">Section 7.2.5</a>.
+ </p></div><div class="refsect2" id="SQL-SELECT-LIST"><h3><code class="command">SELECT</code> List</h3><p>
+ The <code class="command">SELECT</code> list (between the key words
+ <code class="literal">SELECT</code> and <code class="literal">FROM</code>) specifies expressions
+ that form the output rows of the <code class="command">SELECT</code>
+ statement. The expressions can (and usually do) refer to columns
+ computed in the <code class="literal">FROM</code> clause.
+ </p><p>
+ Just as in a table, every output column of a <code class="command">SELECT</code>
+ has a name. In a simple <code class="command">SELECT</code> this name is just
+ used to label the column for display, but when the <code class="command">SELECT</code>
+ is a sub-query of a larger query, the name is seen by the larger query
+ as the column name of the virtual table produced by the sub-query.
+ To specify the name to use for an output column, write
+ <code class="literal">AS</code> <em class="replaceable"><code>output_name</code></em>
+ after the column's expression. (You can omit <code class="literal">AS</code>,
+ but only if the desired output name does not match any
+ <span class="productname">PostgreSQL</span> keyword (see <a class="xref" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Appendix C</a>). For protection against possible
+ future keyword additions, it is recommended that you always either
+ write <code class="literal">AS</code> or double-quote the output name.)
+ If you do not specify a column name, a name is chosen automatically
+ by <span class="productname">PostgreSQL</span>. If the column's expression
+ is a simple column reference then the chosen name is the same as that
+ column's name. In more complex cases a function or type name may be
+ used, or the system may fall back on a generated name such as
+ <code class="literal">?column?</code>.
+ </p><p>
+ An output column's name can be used to refer to the column's value in
+ <code class="literal">ORDER BY</code> and <code class="literal">GROUP BY</code> clauses, but not in the
+ <code class="literal">WHERE</code> or <code class="literal">HAVING</code> clauses; there you must write
+ out the expression instead.
+ </p><p>
+ Instead of an expression, <code class="literal">*</code> can be written in
+ the output list as a shorthand for all the columns of the selected
+ rows. Also, you can write <code class="literal"><em class="replaceable"><code>table_name</code></em>.*</code> as a
+ shorthand for the columns coming from just that table. In these
+ cases it is not possible to specify new names with <code class="literal">AS</code>;
+ the output column names will be the same as the table columns' names.
+ </p><p>
+ According to the SQL standard, the expressions in the output list should
+ be computed before applying <code class="literal">DISTINCT</code>, <code class="literal">ORDER
+ BY</code>, or <code class="literal">LIMIT</code>. This is obviously necessary
+ when using <code class="literal">DISTINCT</code>, since otherwise it's not clear
+ what values are being made distinct. However, in many cases it is
+ convenient if output expressions are computed after <code class="literal">ORDER
+ BY</code> and <code class="literal">LIMIT</code>; particularly if the output list
+ contains any volatile or expensive functions. With that behavior, the
+ order of function evaluations is more intuitive and there will not be
+ evaluations corresponding to rows that never appear in the output.
+ <span class="productname">PostgreSQL</span> will effectively evaluate output expressions
+ after sorting and limiting, so long as those expressions are not
+ referenced in <code class="literal">DISTINCT</code>, <code class="literal">ORDER BY</code>
+ or <code class="literal">GROUP BY</code>. (As a counterexample, <code class="literal">SELECT
+ f(x) FROM tab ORDER BY 1</code> clearly must evaluate <code class="function">f(x)</code>
+ before sorting.) Output expressions that contain set-returning functions
+ are effectively evaluated after sorting and before limiting, so
+ that <code class="literal">LIMIT</code> will act to cut off the output from a
+ set-returning function.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> versions before 9.6 did not provide any
+ guarantees about the timing of evaluation of output expressions versus
+ sorting and limiting; it depended on the form of the chosen query plan.
+ </p></div></div><div class="refsect2" id="SQL-DISTINCT"><h3><code class="literal">DISTINCT</code> Clause</h3><p>
+ If <code class="literal">SELECT DISTINCT</code> is specified, all duplicate rows are
+ removed from the result set (one row is kept from each group of
+ duplicates). <code class="literal">SELECT ALL</code> specifies the opposite: all rows are
+ kept; that is the default.
+ </p><p>
+ <code class="literal">SELECT DISTINCT ON ( <em class="replaceable"><code>expression</code></em> [, ...] )</code>
+ keeps only the first row of each set of rows where the given
+ expressions evaluate to equal. The <code class="literal">DISTINCT ON</code>
+ expressions are interpreted using the same rules as for
+ <code class="literal">ORDER BY</code> (see above). Note that the <span class="quote">“<span class="quote">first
+ row</span>”</span> of each set is unpredictable unless <code class="literal">ORDER
+ BY</code> is used to ensure that the desired row appears first. For
+ example:
+</p><pre class="programlisting">
+SELECT DISTINCT ON (location) location, time, report
+ FROM weather_reports
+ ORDER BY location, time DESC;
+</pre><p>
+ retrieves the most recent weather report for each location. But
+ if we had not used <code class="literal">ORDER BY</code> to force descending order
+ of time values for each location, we'd have gotten a report from
+ an unpredictable time for each location.
+ </p><p>
+ The <code class="literal">DISTINCT ON</code> expression(s) must match the leftmost
+ <code class="literal">ORDER BY</code> expression(s). The <code class="literal">ORDER BY</code> clause
+ will normally contain additional expression(s) that determine the
+ desired precedence of rows within each <code class="literal">DISTINCT ON</code> group.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code> and <code class="literal">FOR KEY SHARE</code> cannot be
+ specified with <code class="literal">DISTINCT</code>.
+ </p></div><div class="refsect2" id="SQL-UNION"><h3><code class="literal">UNION</code> Clause</h3><p>
+ The <code class="literal">UNION</code> clause has this general form:
+</p><pre class="synopsis">
+<em class="replaceable"><code>select_statement</code></em> UNION [ ALL | DISTINCT ] <em class="replaceable"><code>select_statement</code></em>
+</pre><p><em class="replaceable"><code>select_statement</code></em> is
+ any <code class="command">SELECT</code> statement without an <code class="literal">ORDER
+ BY</code>, <code class="literal">LIMIT</code>, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code>, or <code class="literal">FOR KEY SHARE</code> clause.
+ (<code class="literal">ORDER BY</code> and <code class="literal">LIMIT</code> can be attached to a
+ subexpression if it is enclosed in parentheses. Without
+ parentheses, these clauses will be taken to apply to the result of
+ the <code class="literal">UNION</code>, not to its right-hand input
+ expression.)
+ </p><p>
+ The <code class="literal">UNION</code> operator computes the set union of
+ the rows returned by the involved <code class="command">SELECT</code>
+ statements. A row is in the set union of two result sets if it
+ appears in at least one of the result sets. The two
+ <code class="command">SELECT</code> statements that represent the direct
+ operands of the <code class="literal">UNION</code> must produce the same
+ number of columns, and corresponding columns must be of compatible
+ data types.
+ </p><p>
+ The result of <code class="literal">UNION</code> does not contain any duplicate
+ rows unless the <code class="literal">ALL</code> option is specified.
+ <code class="literal">ALL</code> prevents elimination of duplicates. (Therefore,
+ <code class="literal">UNION ALL</code> is usually significantly quicker than
+ <code class="literal">UNION</code>; use <code class="literal">ALL</code> when you can.)
+ <code class="literal">DISTINCT</code> can be written to explicitly specify the
+ default behavior of eliminating duplicate rows.
+ </p><p>
+ Multiple <code class="literal">UNION</code> operators in the same
+ <code class="command">SELECT</code> statement are evaluated left to right,
+ unless otherwise indicated by parentheses.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>, <code class="literal">FOR SHARE</code> and
+ <code class="literal">FOR KEY SHARE</code> cannot be
+ specified either for a <code class="literal">UNION</code> result or for any input of a
+ <code class="literal">UNION</code>.
+ </p></div><div class="refsect2" id="SQL-INTERSECT"><h3><code class="literal">INTERSECT</code> Clause</h3><p>
+ The <code class="literal">INTERSECT</code> clause has this general form:
+</p><pre class="synopsis">
+<em class="replaceable"><code>select_statement</code></em> INTERSECT [ ALL | DISTINCT ] <em class="replaceable"><code>select_statement</code></em>
+</pre><p><em class="replaceable"><code>select_statement</code></em> is
+ any <code class="command">SELECT</code> statement without an <code class="literal">ORDER
+ BY</code>, <code class="literal">LIMIT</code>, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code>, or <code class="literal">FOR KEY SHARE</code> clause.
+ </p><p>
+ The <code class="literal">INTERSECT</code> operator computes the set
+ intersection of the rows returned by the involved
+ <code class="command">SELECT</code> statements. A row is in the
+ intersection of two result sets if it appears in both result sets.
+ </p><p>
+ The result of <code class="literal">INTERSECT</code> does not contain any
+ duplicate rows unless the <code class="literal">ALL</code> option is specified.
+ With <code class="literal">ALL</code>, a row that has <em class="replaceable"><code>m</code></em> duplicates in the
+ left table and <em class="replaceable"><code>n</code></em> duplicates in the right table will appear
+ min(<em class="replaceable"><code>m</code></em>,<em class="replaceable"><code>n</code></em>) times in the result set.
+ <code class="literal">DISTINCT</code> can be written to explicitly specify the
+ default behavior of eliminating duplicate rows.
+ </p><p>
+ Multiple <code class="literal">INTERSECT</code> operators in the same
+ <code class="command">SELECT</code> statement are evaluated left to right,
+ unless parentheses dictate otherwise.
+ <code class="literal">INTERSECT</code> binds more tightly than
+ <code class="literal">UNION</code>. That is, <code class="literal">A UNION B INTERSECT
+ C</code> will be read as <code class="literal">A UNION (B INTERSECT
+ C)</code>.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>, <code class="literal">FOR SHARE</code> and
+ <code class="literal">FOR KEY SHARE</code> cannot be
+ specified either for an <code class="literal">INTERSECT</code> result or for any input of
+ an <code class="literal">INTERSECT</code>.
+ </p></div><div class="refsect2" id="SQL-EXCEPT"><h3><code class="literal">EXCEPT</code> Clause</h3><p>
+ The <code class="literal">EXCEPT</code> clause has this general form:
+</p><pre class="synopsis">
+<em class="replaceable"><code>select_statement</code></em> EXCEPT [ ALL | DISTINCT ] <em class="replaceable"><code>select_statement</code></em>
+</pre><p><em class="replaceable"><code>select_statement</code></em> is
+ any <code class="command">SELECT</code> statement without an <code class="literal">ORDER
+ BY</code>, <code class="literal">LIMIT</code>, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>,
+ <code class="literal">FOR SHARE</code>, or <code class="literal">FOR KEY SHARE</code> clause.
+ </p><p>
+ The <code class="literal">EXCEPT</code> operator computes the set of rows
+ that are in the result of the left <code class="command">SELECT</code>
+ statement but not in the result of the right one.
+ </p><p>
+ The result of <code class="literal">EXCEPT</code> does not contain any
+ duplicate rows unless the <code class="literal">ALL</code> option is specified.
+ With <code class="literal">ALL</code>, a row that has <em class="replaceable"><code>m</code></em> duplicates in the
+ left table and <em class="replaceable"><code>n</code></em> duplicates in the right table will appear
+ max(<em class="replaceable"><code>m</code></em>-<em class="replaceable"><code>n</code></em>,0) times in the result set.
+ <code class="literal">DISTINCT</code> can be written to explicitly specify the
+ default behavior of eliminating duplicate rows.
+ </p><p>
+ Multiple <code class="literal">EXCEPT</code> operators in the same
+ <code class="command">SELECT</code> statement are evaluated left to right,
+ unless parentheses dictate otherwise. <code class="literal">EXCEPT</code> binds at
+ the same level as <code class="literal">UNION</code>.
+ </p><p>
+ Currently, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>, <code class="literal">FOR SHARE</code> and
+ <code class="literal">FOR KEY SHARE</code> cannot be
+ specified either for an <code class="literal">EXCEPT</code> result or for any input of
+ an <code class="literal">EXCEPT</code>.
+ </p></div><div class="refsect2" id="SQL-ORDERBY"><h3><code class="literal">ORDER BY</code> Clause</h3><p>
+ The optional <code class="literal">ORDER BY</code> clause has this general form:
+</p><pre class="synopsis">
+ORDER BY <em class="replaceable"><code>expression</code></em> [ ASC | DESC | USING <em class="replaceable"><code>operator</code></em> ] [ NULLS { FIRST | LAST } ] [, ...]
+</pre><p>
+ The <code class="literal">ORDER BY</code> clause causes the result rows to
+ be sorted according to the specified expression(s). If two rows are
+ equal according to the leftmost expression, they are compared
+ according to the next expression and so on. If they are equal
+ according to all specified expressions, they are returned in
+ an implementation-dependent order.
+ </p><p>
+ Each <em class="replaceable"><code>expression</code></em> can be the
+ name or ordinal number of an output column
+ (<code class="command">SELECT</code> list item), or it can be an arbitrary
+ expression formed from input-column values.
+ </p><p>
+ The ordinal number refers to the ordinal (left-to-right) position
+ of the output column. This feature makes it possible to define an
+ ordering on the basis of a column that does not have a unique
+ name. This is never absolutely necessary because it is always
+ possible to assign a name to an output column using the
+ <code class="literal">AS</code> clause.
+ </p><p>
+ It is also possible to use arbitrary expressions in the
+ <code class="literal">ORDER BY</code> clause, including columns that do not
+ appear in the <code class="command">SELECT</code> output list. Thus the
+ following statement is valid:
+</p><pre class="programlisting">
+SELECT name FROM distributors ORDER BY code;
+</pre><p>
+ A limitation of this feature is that an <code class="literal">ORDER BY</code>
+ clause applying to the result of a <code class="literal">UNION</code>,
+ <code class="literal">INTERSECT</code>, or <code class="literal">EXCEPT</code> clause can only
+ specify an output column name or number, not an expression.
+ </p><p>
+ If an <code class="literal">ORDER BY</code> expression is a simple name that
+ matches both an output column name and an input column name,
+ <code class="literal">ORDER BY</code> will interpret it as the output column name.
+ This is the opposite of the choice that <code class="literal">GROUP BY</code> will
+ make in the same situation. This inconsistency is made to be
+ compatible with the SQL standard.
+ </p><p>
+ Optionally one can add the key word <code class="literal">ASC</code> (ascending) or
+ <code class="literal">DESC</code> (descending) after any expression in the
+ <code class="literal">ORDER BY</code> clause. If not specified, <code class="literal">ASC</code> is
+ assumed by default. Alternatively, a specific ordering operator
+ name can be specified in the <code class="literal">USING</code> clause.
+ An ordering operator must be a less-than or greater-than
+ member of some B-tree operator family.
+ <code class="literal">ASC</code> is usually equivalent to <code class="literal">USING &lt;</code> and
+ <code class="literal">DESC</code> is usually equivalent to <code class="literal">USING &gt;</code>.
+ (But the creator of a user-defined data type can define exactly what the
+ default sort ordering is, and it might correspond to operators with other
+ names.)
+ </p><p>
+ If <code class="literal">NULLS LAST</code> is specified, null values sort after all
+ non-null values; if <code class="literal">NULLS FIRST</code> is specified, null values
+ sort before all non-null values. If neither is specified, the default
+ behavior is <code class="literal">NULLS LAST</code> when <code class="literal">ASC</code> is specified
+ or implied, and <code class="literal">NULLS FIRST</code> when <code class="literal">DESC</code> is specified
+ (thus, the default is to act as though nulls are larger than non-nulls).
+ When <code class="literal">USING</code> is specified, the default nulls ordering depends
+ on whether the operator is a less-than or greater-than operator.
+ </p><p>
+ Note that ordering options apply only to the expression they follow;
+ for example <code class="literal">ORDER BY x, y DESC</code> does not mean
+ the same thing as <code class="literal">ORDER BY x DESC, y DESC</code>.
+ </p><p>
+ Character-string data is sorted according to the collation that applies
+ to the column being sorted. That can be overridden at need by including
+ a <code class="literal">COLLATE</code> clause in the
+ <em class="replaceable"><code>expression</code></em>, for example
+ <code class="literal">ORDER BY mycolumn COLLATE "en_US"</code>.
+ For more information see <a class="xref" href="sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS" title="4.2.10. Collation Expressions">Section 4.2.10</a> and
+ <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>.
+ </p></div><div class="refsect2" id="SQL-LIMIT"><h3><code class="literal">LIMIT</code> Clause</h3><p>
+ The <code class="literal">LIMIT</code> clause consists of two independent
+ sub-clauses:
+</p><pre class="synopsis">
+LIMIT { <em class="replaceable"><code>count</code></em> | ALL }
+OFFSET <em class="replaceable"><code>start</code></em>
+</pre><p>
+ The parameter <em class="replaceable"><code>count</code></em> specifies the
+ maximum number of rows to return, while <em class="replaceable"><code>start</code></em> specifies the number of rows
+ to skip before starting to return rows. When both are specified,
+ <em class="replaceable"><code>start</code></em> rows are skipped
+ before starting to count the <em class="replaceable"><code>count</code></em> rows to be returned.
+ </p><p>
+ If the <em class="replaceable"><code>count</code></em> expression
+ evaluates to NULL, it is treated as <code class="literal">LIMIT ALL</code>, i.e., no
+ limit. If <em class="replaceable"><code>start</code></em> evaluates
+ to NULL, it is treated the same as <code class="literal">OFFSET 0</code>.
+ </p><p>
+ SQL:2008 introduced a different syntax to achieve the same result,
+ which <span class="productname">PostgreSQL</span> also supports. It is:
+</p><pre class="synopsis">
+OFFSET <em class="replaceable"><code>start</code></em> { ROW | ROWS }
+FETCH { FIRST | NEXT } [ <em class="replaceable"><code>count</code></em> ] { ROW | ROWS } { ONLY | WITH TIES }
+</pre><p>
+ In this syntax, the <em class="replaceable"><code>start</code></em>
+ or <em class="replaceable"><code>count</code></em> value is required by
+ the standard to be a literal constant, a parameter, or a variable name;
+ as a <span class="productname">PostgreSQL</span> extension, other expressions
+ are allowed, but will generally need to be enclosed in parentheses to avoid
+ ambiguity.
+ If <em class="replaceable"><code>count</code></em> is
+ omitted in a <code class="literal">FETCH</code> clause, it defaults to 1.
+ The <code class="literal">WITH TIES</code> option is used to return any additional
+ rows that tie for the last place in the result set according to
+ the <code class="literal">ORDER BY</code> clause; <code class="literal">ORDER BY</code>
+ is mandatory in this case, and <code class="literal">SKIP LOCKED</code> is
+ not allowed.
+ <code class="literal">ROW</code> and <code class="literal">ROWS</code> as well as
+ <code class="literal">FIRST</code> and <code class="literal">NEXT</code> are noise
+ words that don't influence the effects of these clauses.
+ According to the standard, the <code class="literal">OFFSET</code> clause must come
+ before the <code class="literal">FETCH</code> clause if both are present; but
+ <span class="productname">PostgreSQL</span> is laxer and allows either order.
+ </p><p>
+ When using <code class="literal">LIMIT</code>, it is a good idea to use an
+ <code class="literal">ORDER BY</code> clause that constrains the result rows into a
+ unique order. Otherwise you will get an unpredictable subset of
+ the query's rows — you might be asking for the tenth through
+ twentieth rows, but tenth through twentieth in what ordering? You
+ don't know what ordering unless you specify <code class="literal">ORDER BY</code>.
+ </p><p>
+ The query planner takes <code class="literal">LIMIT</code> into account when
+ generating a query plan, so you are very likely to get different
+ plans (yielding different row orders) depending on what you use
+ for <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code>. Thus, using
+ different <code class="literal">LIMIT</code>/<code class="literal">OFFSET</code> values to select
+ different subsets of a query result <span class="emphasis"><em>will give
+ inconsistent results</em></span> unless you enforce a predictable
+ result ordering with <code class="literal">ORDER BY</code>. This is not a bug; it
+ is an inherent consequence of the fact that SQL does not promise
+ to deliver the results of a query in any particular order unless
+ <code class="literal">ORDER BY</code> is used to constrain the order.
+ </p><p>
+ It is even possible for repeated executions of the same <code class="literal">LIMIT</code>
+ query to return different subsets of the rows of a table, if there
+ is not an <code class="literal">ORDER BY</code> to enforce selection of a deterministic
+ subset. Again, this is not a bug; determinism of the results is
+ simply not guaranteed in such a case.
+ </p></div><div class="refsect2" id="SQL-FOR-UPDATE-SHARE"><h3>The Locking Clause</h3><p>
+ <code class="literal">FOR UPDATE</code>, <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR SHARE</code>
+ and <code class="literal">FOR KEY SHARE</code>
+ are <em class="firstterm">locking clauses</em>; they affect how <code class="literal">SELECT</code>
+ locks rows as they are obtained from the table.
+ </p><p>
+ The locking clause has the general form
+
+</p><pre class="synopsis">
+FOR <em class="replaceable"><code>lock_strength</code></em> [ OF <em class="replaceable"><code>table_name</code></em> [, ...] ] [ NOWAIT | SKIP LOCKED ]
+</pre><p>
+
+ where <em class="replaceable"><code>lock_strength</code></em> can be one of
+
+</p><pre class="synopsis">
+UPDATE
+NO KEY UPDATE
+SHARE
+KEY SHARE
+</pre><p>
+ </p><p>
+ For more information on each row-level lock mode, refer to
+ <a class="xref" href="explicit-locking.html#LOCKING-ROWS" title="13.3.2. Row-Level Locks">Section 13.3.2</a>.
+ </p><p>
+ To prevent the operation from waiting for other transactions to commit,
+ use either the <code class="literal">NOWAIT</code> or <code class="literal">SKIP LOCKED</code>
+ option. With <code class="literal">NOWAIT</code>, the statement reports an error, rather
+ than waiting, if a selected row cannot be locked immediately.
+ With <code class="literal">SKIP LOCKED</code>, any selected rows that cannot be
+ immediately locked are skipped. Skipping locked rows provides an
+ inconsistent view of the data, so this is not suitable for general purpose
+ work, but can be used to avoid lock contention with multiple consumers
+ accessing a queue-like table.
+ Note that <code class="literal">NOWAIT</code> and <code class="literal">SKIP LOCKED</code> apply only
+ to the row-level lock(s) — the required <code class="literal">ROW SHARE</code>
+ table-level lock is still taken in the ordinary way (see
+ <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>). You can use
+ <a class="link" href="sql-lock.html" title="LOCK"><code class="command">LOCK</code></a>
+ with the <code class="literal">NOWAIT</code> option first,
+ if you need to acquire the table-level lock without waiting.
+ </p><p>
+ If specific tables are named in a locking clause,
+ then only rows coming from those tables are locked; any other
+ tables used in the <code class="command">SELECT</code> are simply read as
+ usual. A locking
+ clause without a table list affects all tables used in the statement.
+ If a locking clause is
+ applied to a view or sub-query, it affects all tables used in
+ the view or sub-query.
+ However, these clauses
+ do not apply to <code class="literal">WITH</code> queries referenced by the primary query.
+ If you want row locking to occur within a <code class="literal">WITH</code> query, specify
+ a locking clause within the <code class="literal">WITH</code> query.
+ </p><p>
+ Multiple locking
+ clauses can be written if it is necessary to specify different locking
+ behavior for different tables. If the same table is mentioned (or
+ implicitly affected) by more than one locking clause,
+ then it is processed as if it was only specified by the strongest one.
+ Similarly, a table is processed
+ as <code class="literal">NOWAIT</code> if that is specified in any of the clauses
+ affecting it. Otherwise, it is processed
+ as <code class="literal">SKIP LOCKED</code> if that is specified in any of the
+ clauses affecting it.
+ </p><p>
+ The locking clauses cannot be
+ used in contexts where returned rows cannot be clearly identified with
+ individual table rows; for example they cannot be used with aggregation.
+ </p><p>
+ When a locking clause
+ appears at the top level of a <code class="command">SELECT</code> query, the rows that
+ are locked are exactly those that are returned by the query; in the
+ case of a join query, the rows locked are those that contribute to
+ returned join rows. In addition, rows that satisfied the query
+ conditions as of the query snapshot will be locked, although they
+ will not be returned if they were updated after the snapshot
+ and no longer satisfy the query conditions. If a
+ <code class="literal">LIMIT</code> is used, locking stops
+ once enough rows have been returned to satisfy the limit (but note that
+ rows skipped over by <code class="literal">OFFSET</code> will get locked). Similarly,
+ if a locking clause
+ is used in a cursor's query, only rows actually fetched or stepped past
+ by the cursor will be locked.
+ </p><p>
+ When a locking clause
+ appears in a sub-<code class="command">SELECT</code>, the rows locked are those
+ returned to the outer query by the sub-query. This might involve
+ fewer rows than inspection of the sub-query alone would suggest,
+ since conditions from the outer query might be used to optimize
+ execution of the sub-query. For example,
+</p><pre class="programlisting">
+SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;
+</pre><p>
+ will lock only rows having <code class="literal">col1 = 5</code>, even though that
+ condition is not textually within the sub-query.
+ </p><p>
+ Previous releases failed to preserve a lock which is upgraded by a later
+ savepoint. For example, this code:
+</p><pre class="programlisting">
+BEGIN;
+SELECT * FROM mytable WHERE key = 1 FOR UPDATE;
+SAVEPOINT s;
+UPDATE mytable SET ... WHERE key = 1;
+ROLLBACK TO s;
+</pre><p>
+ would fail to preserve the <code class="literal">FOR UPDATE</code> lock after the
+ <code class="command">ROLLBACK TO</code>. This has been fixed in release 9.3.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ It is possible for a <code class="command">SELECT</code> command running at the <code class="literal">READ
+ COMMITTED</code> transaction isolation level and using <code class="literal">ORDER
+ BY</code> and a locking clause to return rows out of
+ order. This is because <code class="literal">ORDER BY</code> is applied first.
+ The command sorts the result, but might then block trying to obtain a lock
+ on one or more of the rows. Once the <code class="literal">SELECT</code> unblocks, some
+ of the ordering column values might have been modified, leading to those
+ rows appearing to be out of order (though they are in order in terms
+ of the original column values). This can be worked around at need by
+ placing the <code class="literal">FOR UPDATE/SHARE</code> clause in a sub-query,
+ for example
+</p><pre class="programlisting">
+SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
+</pre><p>
+ Note that this will result in locking all rows of <code class="structname">mytable</code>,
+ whereas <code class="literal">FOR UPDATE</code> at the top level would lock only the
+ actually returned rows. This can make for a significant performance
+ difference, particularly if the <code class="literal">ORDER BY</code> is combined with
+ <code class="literal">LIMIT</code> or other restrictions. So this technique is recommended
+ only if concurrent updates of the ordering columns are expected and a
+ strictly sorted result is required.
+ </p><p>
+ At the <code class="literal">REPEATABLE READ</code> or <code class="literal">SERIALIZABLE</code>
+ transaction isolation level this would cause a serialization failure (with
+ an <code class="literal">SQLSTATE</code> of <code class="literal">'40001'</code>), so there is
+ no possibility of receiving rows out of order under these isolation levels.
+ </p></div></div><div class="refsect2" id="SQL-TABLE"><h3><code class="literal">TABLE</code> Command</h3><p>
+ The command
+</p><pre class="programlisting">
+TABLE <em class="replaceable"><code>name</code></em>
+</pre><p>
+ is equivalent to
+</p><pre class="programlisting">
+SELECT * FROM <em class="replaceable"><code>name</code></em>
+</pre><p>
+ It can be used as a top-level command or as a space-saving syntax
+ variant in parts of complex queries. Only the <code class="literal">WITH</code>,
+ <code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>,
+ <code class="literal">ORDER BY</code>, <code class="literal">LIMIT</code>, <code class="literal">OFFSET</code>,
+ <code class="literal">FETCH</code> and <code class="literal">FOR</code> locking clauses can be used
+ with <code class="command">TABLE</code>; the <code class="literal">WHERE</code> clause and any form of
+ aggregation cannot
+ be used.
+ </p></div></div><div class="refsect1" id="id-1.9.3.172.9"><h2>Examples</h2><p>
+ To join the table <code class="literal">films</code> with the table
+ <code class="literal">distributors</code>:
+
+</p><pre class="programlisting">
+SELECT f.title, f.did, d.name, f.date_prod, f.kind
+ FROM distributors d JOIN films f USING (did);
+
+ title | did | name | date_prod | kind
+-------------------+-----+--------------+------------+----------
+ The Third Man | 101 | British Lion | 1949-12-23 | Drama
+ The African Queen | 101 | British Lion | 1951-08-11 | Romantic
+ ...
+</pre><p>
+ </p><p>
+ To sum the column <code class="literal">len</code> of all films and group
+ the results by <code class="literal">kind</code>:
+
+</p><pre class="programlisting">
+SELECT kind, sum(len) AS total FROM films GROUP BY kind;
+
+ kind | total
+----------+-------
+ Action | 07:34
+ Comedy | 02:58
+ Drama | 14:28
+ Musical | 06:42
+ Romantic | 04:38
+</pre><p>
+ </p><p>
+ To sum the column <code class="literal">len</code> of all films, group
+ the results by <code class="literal">kind</code> and show those group totals
+ that are less than 5 hours:
+
+</p><pre class="programlisting">
+SELECT kind, sum(len) AS total
+ FROM films
+ GROUP BY kind
+ HAVING sum(len) &lt; interval '5 hours';
+
+ kind | total
+----------+-------
+ Comedy | 02:58
+ Romantic | 04:38
+</pre><p>
+ </p><p>
+ The following two examples are identical ways of sorting the individual
+ results according to the contents of the second column
+ (<code class="literal">name</code>):
+
+</p><pre class="programlisting">
+SELECT * FROM distributors ORDER BY name;
+SELECT * FROM distributors ORDER BY 2;
+
+ did | name
+-----+------------------
+ 109 | 20th Century Fox
+ 110 | Bavaria Atelier
+ 101 | British Lion
+ 107 | Columbia
+ 102 | Jean Luc Godard
+ 113 | Luso films
+ 104 | Mosfilm
+ 103 | Paramount
+ 106 | Toho
+ 105 | United Artists
+ 111 | Walt Disney
+ 112 | Warner Bros.
+ 108 | Westward
+</pre><p>
+ </p><p>
+ The next example shows how to obtain the union of the tables
+ <code class="literal">distributors</code> and
+ <code class="literal">actors</code>, restricting the results to those that begin
+ with the letter W in each table. Only distinct rows are wanted, so the
+ key word <code class="literal">ALL</code> is omitted.
+
+</p><pre class="programlisting">
+distributors: actors:
+ did | name id | name
+-----+-------------- ----+----------------
+ 108 | Westward 1 | Woody Allen
+ 111 | Walt Disney 2 | Warren Beatty
+ 112 | Warner Bros. 3 | Walter Matthau
+ ... ...
+
+SELECT distributors.name
+ FROM distributors
+ WHERE distributors.name LIKE 'W%'
+UNION
+SELECT actors.name
+ FROM actors
+ WHERE actors.name LIKE 'W%';
+
+ name
+----------------
+ Walt Disney
+ Walter Matthau
+ Warner Bros.
+ Warren Beatty
+ Westward
+ Woody Allen
+</pre><p>
+ </p><p>
+ This example shows how to use a function in the <code class="literal">FROM</code>
+ clause, both with and without a column definition list:
+
+</p><pre class="programlisting">
+CREATE FUNCTION distributors(int) RETURNS SETOF distributors AS $$
+ SELECT * FROM distributors WHERE did = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM distributors(111);
+ did | name
+-----+-------------
+ 111 | Walt Disney
+
+CREATE FUNCTION distributors_2(int) RETURNS SETOF record AS $$
+ SELECT * FROM distributors WHERE did = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM distributors_2(111) AS (f1 int, f2 text);
+ f1 | f2
+-----+-------------
+ 111 | Walt Disney
+</pre><p>
+ </p><p>
+ Here is an example of a function with an ordinality column added:
+
+</p><pre class="programlisting">
+SELECT * FROM unnest(ARRAY['a','b','c','d','e','f']) WITH ORDINALITY;
+ unnest | ordinality
+--------+----------
+ a | 1
+ b | 2
+ c | 3
+ d | 4
+ e | 5
+ f | 6
+(6 rows)
+</pre><p>
+ </p><p>
+ This example shows how to use a simple <code class="literal">WITH</code> clause:
+
+</p><pre class="programlisting">
+WITH t AS (
+ SELECT random() as x FROM generate_series(1, 3)
+ )
+SELECT * FROM t
+UNION ALL
+SELECT * FROM t
+
+ x
+--------------------
+ 0.534150459803641
+ 0.520092216785997
+ 0.0735620250925422
+ 0.534150459803641
+ 0.520092216785997
+ 0.0735620250925422
+</pre><p>
+
+ Notice that the <code class="literal">WITH</code> query was evaluated only once,
+ so that we got two sets of the same three random values.
+ </p><p>
+ This example uses <code class="literal">WITH RECURSIVE</code> to find all
+ subordinates (direct or indirect) of the employee Mary, and their
+ level of indirectness, from a table that shows only direct
+ subordinates:
+
+</p><pre class="programlisting">
+WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (
+ SELECT 1, employee_name, manager_name
+ FROM employee
+ WHERE manager_name = 'Mary'
+ UNION ALL
+ SELECT er.distance + 1, e.employee_name, e.manager_name
+ FROM employee_recursive er, employee e
+ WHERE er.employee_name = e.manager_name
+ )
+SELECT distance, employee_name FROM employee_recursive;
+</pre><p>
+
+ Notice the typical form of recursive queries:
+ an initial condition, followed by <code class="literal">UNION</code>,
+ followed by the recursive part of the query. Be sure that the
+ recursive part of the query will eventually return no tuples, or
+ else the query will loop indefinitely. (See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a>
+ for more examples.)
+ </p><p>
+ This example uses <code class="literal">LATERAL</code> to apply a set-returning function
+ <code class="function">get_product_names()</code> for each row of the
+ <code class="structname">manufacturers</code> table:
+
+</p><pre class="programlisting">
+SELECT m.name AS mname, pname
+FROM manufacturers m, LATERAL get_product_names(m.id) pname;
+</pre><p>
+
+ Manufacturers not currently having any products would not appear in the
+ result, since it is an inner join. If we wished to include the names of
+ such manufacturers in the result, we could do:
+
+</p><pre class="programlisting">
+SELECT m.name AS mname, pname
+FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;
+</pre></div><div class="refsect1" id="id-1.9.3.172.10"><h2>Compatibility</h2><p>
+ Of course, the <code class="command">SELECT</code> statement is compatible
+ with the SQL standard. But there are some extensions and some
+ missing features.
+ </p><div class="refsect2" id="id-1.9.3.172.10.3"><h3>Omitted <code class="literal">FROM</code> Clauses</h3><p>
+ <span class="productname">PostgreSQL</span> allows one to omit the
+ <code class="literal">FROM</code> clause. It has a straightforward use to
+ compute the results of simple expressions:
+</p><pre class="programlisting">
+SELECT 2+2;
+
+ ?column?
+----------
+ 4
+</pre><p>
+ Some other <acronym class="acronym">SQL</acronym> databases cannot do this except
+ by introducing a dummy one-row table from which to do the
+ <code class="command">SELECT</code>.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.4"><h3>Empty <code class="literal">SELECT</code> Lists</h3><p>
+ The list of output expressions after <code class="literal">SELECT</code> can be
+ empty, producing a zero-column result table.
+ This is not valid syntax according to the SQL standard.
+ <span class="productname">PostgreSQL</span> allows it to be consistent with
+ allowing zero-column tables.
+ However, an empty list is not allowed when <code class="literal">DISTINCT</code> is used.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.5"><h3>Omitting the <code class="literal">AS</code> Key Word</h3><p>
+ In the SQL standard, the optional key word <code class="literal">AS</code> can be
+ omitted before an output column name whenever the new column name
+ is a valid column name (that is, not the same as any reserved
+ keyword). <span class="productname">PostgreSQL</span> is slightly more
+ restrictive: <code class="literal">AS</code> is required if the new column name
+ matches any keyword at all, reserved or not. Recommended practice is
+ to use <code class="literal">AS</code> or double-quote output column names, to prevent
+ any possible conflict against future keyword additions.
+ </p><p>
+ In <code class="literal">FROM</code> items, both the standard and
+ <span class="productname">PostgreSQL</span> allow <code class="literal">AS</code> to
+ be omitted before an alias that is an unreserved keyword. But
+ this is impractical for output column names, because of syntactic
+ ambiguities.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.6"><h3><code class="literal">ONLY</code> and Inheritance</h3><p>
+ The SQL standard requires parentheses around the table name when
+ writing <code class="literal">ONLY</code>, for example <code class="literal">SELECT * FROM ONLY
+ (tab1), ONLY (tab2) WHERE ...</code>. <span class="productname">PostgreSQL</span>
+ considers these parentheses to be optional.
+ </p><p>
+ <span class="productname">PostgreSQL</span> allows a trailing <code class="literal">*</code> to be written to
+ explicitly specify the non-<code class="literal">ONLY</code> behavior of including
+ child tables. The standard does not allow this.
+ </p><p>
+ (These points apply equally to all SQL commands supporting the
+ <code class="literal">ONLY</code> option.)
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.7"><h3><code class="literal">TABLESAMPLE</code> Clause Restrictions</h3><p>
+ The <code class="literal">TABLESAMPLE</code> clause is currently accepted only on
+ regular tables and materialized views. According to the SQL standard
+ it should be possible to apply it to any <code class="literal">FROM</code> item.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.8"><h3>Function Calls in <code class="literal">FROM</code></h3><p>
+ <span class="productname">PostgreSQL</span> allows a function call to be
+ written directly as a member of the <code class="literal">FROM</code> list. In the SQL
+ standard it would be necessary to wrap such a function call in a
+ sub-<code class="command">SELECT</code>; that is, the syntax
+ <code class="literal">FROM <em class="replaceable"><code>func</code></em>(...) <em class="replaceable"><code>alias</code></em></code>
+ is approximately equivalent to
+ <code class="literal">FROM LATERAL (SELECT <em class="replaceable"><code>func</code></em>(...)) <em class="replaceable"><code>alias</code></em></code>.
+ Note that <code class="literal">LATERAL</code> is considered to be implicit; this is
+ because the standard requires <code class="literal">LATERAL</code> semantics for an
+ <code class="literal">UNNEST()</code> item in <code class="literal">FROM</code>.
+ <span class="productname">PostgreSQL</span> treats <code class="literal">UNNEST()</code> the
+ same as other set-returning functions.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.9"><h3>Namespace Available to <code class="literal">GROUP BY</code> and <code class="literal">ORDER BY</code></h3><p>
+ In the SQL-92 standard, an <code class="literal">ORDER BY</code> clause can
+ only use output column names or numbers, while a <code class="literal">GROUP
+ BY</code> clause can only use expressions based on input column
+ names. <span class="productname">PostgreSQL</span> extends each of
+ these clauses to allow the other choice as well (but it uses the
+ standard's interpretation if there is ambiguity).
+ <span class="productname">PostgreSQL</span> also allows both clauses to
+ specify arbitrary expressions. Note that names appearing in an
+ expression will always be taken as input-column names, not as
+ output-column names.
+ </p><p>
+ SQL:1999 and later use a slightly different definition which is not
+ entirely upward compatible with SQL-92.
+ In most cases, however, <span class="productname">PostgreSQL</span>
+ will interpret an <code class="literal">ORDER BY</code> or <code class="literal">GROUP
+ BY</code> expression the same way SQL:1999 does.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.10"><h3>Functional Dependencies</h3><p>
+ <span class="productname">PostgreSQL</span> recognizes functional dependency
+ (allowing columns to be omitted from <code class="literal">GROUP BY</code>) only when
+ a table's primary key is included in the <code class="literal">GROUP BY</code> list.
+ The SQL standard specifies additional conditions that should be
+ recognized.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.11"><h3><code class="literal">LIMIT</code> and <code class="literal">OFFSET</code></h3><p>
+ The clauses <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code>
+ are <span class="productname">PostgreSQL</span>-specific syntax, also
+ used by <span class="productname">MySQL</span>. The SQL:2008 standard
+ has introduced the clauses <code class="literal">OFFSET ... FETCH {FIRST|NEXT}
+ ...</code> for the same functionality, as shown above
+ in <a class="xref" href="sql-select.html#SQL-LIMIT" title="LIMIT Clause">LIMIT Clause</a>. This
+ syntax is also used by <span class="productname">IBM DB2</span>.
+ (Applications written for <span class="productname">Oracle</span>
+ frequently use a workaround involving the automatically
+ generated <code class="literal">rownum</code> column, which is not available in
+ PostgreSQL, to implement the effects of these clauses.)
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.12"><h3><code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR UPDATE</code>, <code class="literal">FOR SHARE</code>, <code class="literal">FOR KEY SHARE</code></h3><p>
+ Although <code class="literal">FOR UPDATE</code> appears in the SQL standard, the
+ standard allows it only as an option of <code class="command">DECLARE CURSOR</code>.
+ <span class="productname">PostgreSQL</span> allows it in any <code class="command">SELECT</code>
+ query as well as in sub-<code class="command">SELECT</code>s, but this is an extension.
+ The <code class="literal">FOR NO KEY UPDATE</code>, <code class="literal">FOR SHARE</code> and
+ <code class="literal">FOR KEY SHARE</code> variants, as well as the <code class="literal">NOWAIT</code>
+ and <code class="literal">SKIP LOCKED</code> options, do not appear in the
+ standard.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.13"><h3>Data-Modifying Statements in <code class="literal">WITH</code></h3><p>
+ <span class="productname">PostgreSQL</span> allows <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, and <code class="command">DELETE</code> to be used as <code class="literal">WITH</code>
+ queries. This is not found in the SQL standard.
+ </p></div><div class="refsect2" id="id-1.9.3.172.10.14"><h3>Nonstandard Clauses</h3><p>
+ <code class="literal">DISTINCT ON ( ... )</code> is an extension of the
+ SQL standard.
+ </p><p>
+ <code class="literal">ROWS FROM( ... )</code> is an extension of the SQL standard.
+ </p><p>
+ The <code class="literal">MATERIALIZED</code> and <code class="literal">NOT
+ MATERIALIZED</code> options of <code class="literal">WITH</code> are extensions
+ of the SQL standard.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-security-label.html" title="SECURITY LABEL">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-selectinto.html" title="SELECT INTO">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SECURITY LABEL </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SELECT INTO</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-selectinto.html b/doc/src/sgml/html/sql-selectinto.html
new file mode 100644
index 0000000..9c23436
--- /dev/null
+++ b/doc/src/sgml/html/sql-selectinto.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SELECT INTO</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-select.html" title="SELECT" /><link rel="next" href="sql-set.html" title="SET" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SELECT INTO</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-select.html" title="SELECT">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-set.html" title="SET">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SELECTINTO"><div class="titlepage"></div><a id="id-1.9.3.173.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SELECT INTO</span></h2><p>SELECT INTO — define a new table from the results of a query</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+[ WITH [ RECURSIVE ] <em class="replaceable"><code>with_query</code></em> [, ...] ]
+SELECT [ ALL | DISTINCT [ ON ( <em class="replaceable"><code>expression</code></em> [, ...] ) ] ]
+ * | <em class="replaceable"><code>expression</code></em> [ [ AS ] <em class="replaceable"><code>output_name</code></em> ] [, ...]
+ INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] <em class="replaceable"><code>new_table</code></em>
+ [ FROM <em class="replaceable"><code>from_item</code></em> [, ...] ]
+ [ WHERE <em class="replaceable"><code>condition</code></em> ]
+ [ GROUP BY <em class="replaceable"><code>expression</code></em> [, ...] ]
+ [ HAVING <em class="replaceable"><code>condition</code></em> ]
+ [ WINDOW <em class="replaceable"><code>window_name</code></em> AS ( <em class="replaceable"><code>window_definition</code></em> ) [, ...] ]
+ [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] <em class="replaceable"><code>select</code></em> ]
+ [ ORDER BY <em class="replaceable"><code>expression</code></em> [ ASC | DESC | USING <em class="replaceable"><code>operator</code></em> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+ [ LIMIT { <em class="replaceable"><code>count</code></em> | ALL } ]
+ [ OFFSET <em class="replaceable"><code>start</code></em> [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ <em class="replaceable"><code>count</code></em> ] { ROW | ROWS } ONLY ]
+ [ FOR { UPDATE | SHARE } [ OF <em class="replaceable"><code>table_name</code></em> [, ...] ] [ NOWAIT ] [...] ]
+</pre></div><div class="refsect1" id="id-1.9.3.173.5"><h2>Description</h2><p>
+ <code class="command">SELECT INTO</code> creates a new table and fills it
+ with data computed by a query. The data is not returned to the
+ client, as it is with a normal <code class="command">SELECT</code>. The new
+ table's columns have the names and data types associated with the
+ output columns of the <code class="command">SELECT</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.173.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TEMPORARY</code> or <code class="literal">TEMP</code></span></dt><dd><p>
+ If specified, the table is created as a temporary table. Refer
+ to <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for details.
+ </p></dd><dt><span class="term"><code class="literal">UNLOGGED</code></span></dt><dd><p>
+ If specified, the table is created as an unlogged table. Refer
+ to <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> for details.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>new_table</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to be created.
+ </p></dd></dl></div><p>
+ All other parameters are described in detail under <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.173.7"><h2>Notes</h2><p>
+ <a class="link" href="sql-createtableas.html" title="CREATE TABLE AS"><code class="command">CREATE TABLE AS</code></a> is functionally similar to
+ <code class="command">SELECT INTO</code>. <code class="command">CREATE TABLE AS</code>
+ is the recommended syntax, since this form of <code class="command">SELECT
+ INTO</code> is not available in <span class="application">ECPG</span>
+ or <span class="application">PL/pgSQL</span>, because they interpret the
+ <code class="literal">INTO</code> clause differently. Furthermore,
+ <code class="command">CREATE TABLE AS</code> offers a superset of the
+ functionality provided by <code class="command">SELECT INTO</code>.
+ </p><p>
+ In contrast to <code class="command">CREATE TABLE AS</code>, <code class="command">SELECT
+ INTO</code> does not allow specifying properties like a table's access
+ method with <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-METHOD"><code class="literal">USING <em class="replaceable"><code>method</code></em></code></a> or the table's
+ tablespace with <a class="xref" href="sql-createtable.html#SQL-CREATETABLE-TABLESPACE"><code class="literal">TABLESPACE <em class="replaceable"><code>tablespace_name</code></em></code></a>. Use
+ <code class="command">CREATE TABLE AS</code> if necessary. Therefore, the default table
+ access method is chosen for the new table. See <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLE-ACCESS-METHOD">default_table_access_method</a> for more information.
+ </p></div><div class="refsect1" id="id-1.9.3.173.8"><h2>Examples</h2><p>
+ Create a new table <code class="literal">films_recent</code> consisting of only
+ recent entries from the table <code class="literal">films</code>:
+
+</p><pre class="programlisting">
+SELECT * INTO films_recent FROM films WHERE date_prod &gt;= '2002-01-01';
+</pre></div><div class="refsect1" id="id-1.9.3.173.9"><h2>Compatibility</h2><p>
+ The SQL standard uses <code class="command">SELECT INTO</code> to
+ represent selecting values into scalar variables of a host program,
+ rather than creating a new table. This indeed is the usage found
+ in <span class="application">ECPG</span> (see <a class="xref" href="ecpg.html" title="Chapter 36. ECPG — Embedded SQL in C">Chapter 36</a>) and
+ <span class="application">PL/pgSQL</span> (see <a class="xref" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Chapter 43</a>).
+ The <span class="productname">PostgreSQL</span> usage of <code class="command">SELECT
+ INTO</code> to represent table creation is historical. Some other SQL
+ implementations also use <code class="command">SELECT INTO</code> in this way (but
+ most SQL implementations support <code class="command">CREATE TABLE AS</code>
+ instead). Apart from such compatibility considerations, it is best to use
+ <code class="command">CREATE TABLE AS</code> for this purpose in new code.
+ </p></div><div class="refsect1" id="id-1.9.3.173.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-createtableas.html" title="CREATE TABLE AS"><span class="refentrytitle">CREATE TABLE AS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-select.html" title="SELECT">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-set.html" title="SET">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SELECT </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-set-constraints.html b/doc/src/sgml/html/sql-set-constraints.html
new file mode 100644
index 0000000..16aeeab
--- /dev/null
+++ b/doc/src/sgml/html/sql-set-constraints.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET CONSTRAINTS</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-set.html" title="SET" /><link rel="next" href="sql-set-role.html" title="SET ROLE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET CONSTRAINTS</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-set.html" title="SET">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-set-role.html" title="SET ROLE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SET-CONSTRAINTS"><div class="titlepage"></div><a id="id-1.9.3.175.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SET CONSTRAINTS</span></h2><p>SET CONSTRAINTS — set constraint check timing for the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET CONSTRAINTS { ALL | <em class="replaceable"><code>name</code></em> [, ...] } { DEFERRED | IMMEDIATE }
+</pre></div><div class="refsect1" id="id-1.9.3.175.5"><h2>Description</h2><p>
+ <code class="command">SET CONSTRAINTS</code> sets the behavior of constraint
+ checking within the current transaction. <code class="literal">IMMEDIATE</code>
+ constraints are checked at the end of each
+ statement. <code class="literal">DEFERRED</code> constraints are not checked until
+ transaction commit. Each constraint has its own
+ <code class="literal">IMMEDIATE</code> or <code class="literal">DEFERRED</code> mode.
+ </p><p>
+ Upon creation, a constraint is given one of three
+ characteristics: <code class="literal">DEFERRABLE INITIALLY DEFERRED</code>,
+ <code class="literal">DEFERRABLE INITIALLY IMMEDIATE</code>, or
+ <code class="literal">NOT DEFERRABLE</code>. The third
+ class is always <code class="literal">IMMEDIATE</code> and is not affected by the
+ <code class="command">SET CONSTRAINTS</code> command. The first two classes start
+ every transaction in the indicated mode, but their behavior can be changed
+ within a transaction by <code class="command">SET CONSTRAINTS</code>.
+ </p><p>
+ <code class="command">SET CONSTRAINTS</code> with a list of constraint names changes
+ the mode of just those constraints (which must all be deferrable). Each
+ constraint name can be schema-qualified. The
+ current schema search path is used to find the first matching name if
+ no schema name is specified. <code class="command">SET CONSTRAINTS ALL</code>
+ changes the mode of all deferrable constraints.
+ </p><p>
+ When <code class="command">SET CONSTRAINTS</code> changes the mode of a constraint
+ from <code class="literal">DEFERRED</code>
+ to <code class="literal">IMMEDIATE</code>, the new mode takes effect
+ retroactively: any outstanding data modifications that would have
+ been checked at the end of the transaction are instead checked during the
+ execution of the <code class="command">SET CONSTRAINTS</code> command.
+ If any such constraint is violated, the <code class="command">SET CONSTRAINTS</code>
+ fails (and does not change the constraint mode). Thus, <code class="command">SET
+ CONSTRAINTS</code> can be used to force checking of constraints to
+ occur at a specific point in a transaction.
+ </p><p>
+ Currently, only <code class="literal">UNIQUE</code>, <code class="literal">PRIMARY KEY</code>,
+ <code class="literal">REFERENCES</code> (foreign key), and <code class="literal">EXCLUDE</code>
+ constraints are affected by this setting.
+ <code class="literal">NOT NULL</code> and <code class="literal">CHECK</code> constraints are
+ always checked immediately when a row is inserted or modified
+ (<span class="emphasis"><em>not</em></span> at the end of the statement).
+ Uniqueness and exclusion constraints that have not been declared
+ <code class="literal">DEFERRABLE</code> are also checked immediately.
+ </p><p>
+ The firing of triggers that are declared as <span class="quote">“<span class="quote">constraint triggers</span>”</span>
+ is also controlled by this setting — they fire at the same time
+ that the associated constraint should be checked.
+ </p></div><div class="refsect1" id="id-1.9.3.175.6"><h2>Notes</h2><p>
+ Because <span class="productname">PostgreSQL</span> does not require constraint
+ names to be unique within a schema (but only per-table), it is possible
+ that there is more than one match for a specified constraint name.
+ In this case <code class="command">SET CONSTRAINTS</code> will act on all matches.
+ For a non-schema-qualified name, once a match or matches have been found in
+ some schema in the search path, schemas appearing later in the path are not
+ searched.
+ </p><p>
+ This command only alters the behavior of constraints within the
+ current transaction. Issuing this outside of a transaction block
+ emits a warning and otherwise has no effect.
+ </p></div><div class="refsect1" id="id-1.9.3.175.7"><h2>Compatibility</h2><p>
+ This command complies with the behavior defined in the SQL
+ standard, except for the limitation that, in
+ <span class="productname">PostgreSQL</span>, it does not apply to
+ <code class="literal">NOT NULL</code> and <code class="literal">CHECK</code> constraints.
+ Also, <span class="productname">PostgreSQL</span> checks non-deferrable
+ uniqueness constraints immediately, not at end of statement as the
+ standard would suggest.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-set.html" title="SET">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-set-role.html" title="SET ROLE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET ROLE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-set-role.html b/doc/src/sgml/html/sql-set-role.html
new file mode 100644
index 0000000..80ae70f
--- /dev/null
+++ b/doc/src/sgml/html/sql-set-role.html
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET ROLE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-set-constraints.html" title="SET CONSTRAINTS" /><link rel="next" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET ROLE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-set-constraints.html" title="SET CONSTRAINTS">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SET-ROLE"><div class="titlepage"></div><a id="id-1.9.3.176.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SET ROLE</span></h2><p>SET ROLE — set the current user identifier of the current session</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET [ SESSION | LOCAL ] ROLE <em class="replaceable"><code>role_name</code></em>
+SET [ SESSION | LOCAL ] ROLE NONE
+RESET ROLE
+</pre></div><div class="refsect1" id="id-1.9.3.176.5"><h2>Description</h2><p>
+ This command sets the current user
+ identifier of the current SQL session to be <em class="replaceable"><code>role_name</code></em>. The role name can be
+ written as either an identifier or a string literal.
+ After <code class="command">SET ROLE</code>, permissions checking for SQL commands
+ is carried out as though the named role were the one that had logged
+ in originally.
+ </p><p>
+ The specified <em class="replaceable"><code>role_name</code></em>
+ must be a role that the current session user is a member of.
+ (If the session user is a superuser, any role can be selected.)
+ </p><p>
+ The <code class="literal">SESSION</code> and <code class="literal">LOCAL</code> modifiers act the same
+ as for the regular <a class="link" href="sql-set.html" title="SET"><code class="command">SET</code></a>
+ command.
+ </p><p>
+ <code class="literal">SET ROLE NONE</code> sets the current user identifier to the
+ current session user identifier, as returned by
+ <code class="function">session_user</code>. <code class="literal">RESET ROLE</code> sets the
+ current user identifier to the connection-time setting specified by the
+ <a class="link" href="libpq-connect.html#LIBPQ-CONNECT-OPTIONS">command-line options</a>,
+ <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a>, or
+ <a class="link" href="sql-alterdatabase.html" title="ALTER DATABASE"><code class="command">ALTER DATABASE</code></a>,
+ if any such settings exist. Otherwise, <code class="literal">RESET ROLE</code> sets
+ the current user identifier to the current session user identifier. These
+ forms can be executed by any user.
+ </p></div><div class="refsect1" id="id-1.9.3.176.6"><h2>Notes</h2><p>
+ Using this command, it is possible to either add privileges or restrict
+ one's privileges. If the session user role has the <code class="literal">INHERIT</code>
+ attribute, then it automatically has all the privileges of every role that
+ it could <code class="command">SET ROLE</code> to; in this case <code class="command">SET ROLE</code>
+ effectively drops all the privileges assigned directly to the session user
+ and to the other roles it is a member of, leaving only the privileges
+ available to the named role. On the other hand, if the session user role
+ has the <code class="literal">NOINHERIT</code> attribute, <code class="command">SET ROLE</code> drops the
+ privileges assigned directly to the session user and instead acquires the
+ privileges available to the named role.
+ </p><p>
+ In particular, when a superuser chooses to <code class="command">SET ROLE</code> to a
+ non-superuser role, they lose their superuser privileges.
+ </p><p>
+ <code class="command">SET ROLE</code> has effects comparable to
+ <a class="link" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION"><code class="command">SET SESSION AUTHORIZATION</code></a>, but the privilege
+ checks involved are quite different. Also,
+ <code class="command">SET SESSION AUTHORIZATION</code> determines which roles are
+ allowable for later <code class="command">SET ROLE</code> commands, whereas changing
+ roles with <code class="command">SET ROLE</code> does not change the set of roles
+ allowed to a later <code class="command">SET ROLE</code>.
+ </p><p>
+ <code class="command">SET ROLE</code> does not process session variables as specified by
+ the role's <a class="link" href="sql-alterrole.html" title="ALTER ROLE"><code class="command">ALTER ROLE</code></a> settings; this only happens during
+ login.
+ </p><p>
+ <code class="command">SET ROLE</code> cannot be used within a
+ <code class="literal">SECURITY DEFINER</code> function.
+ </p></div><div class="refsect1" id="id-1.9.3.176.7"><h2>Examples</h2><pre class="programlisting">
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ peter | peter
+
+SET ROLE 'paul';
+
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ peter | paul
+</pre></div><div class="refsect1" id="id-1.9.3.176.8"><h2>Compatibility</h2><p>
+ <span class="productname">PostgreSQL</span>
+ allows identifier syntax (<code class="literal">"<em class="replaceable"><code>rolename</code></em>"</code>), while
+ the SQL standard requires the role name to be written as a string
+ literal. SQL does not allow this command during a transaction;
+ <span class="productname">PostgreSQL</span> does not make this
+ restriction because there is no reason to.
+ The <code class="literal">SESSION</code> and <code class="literal">LOCAL</code> modifiers are a
+ <span class="productname">PostgreSQL</span> extension, as is the
+ <code class="literal">RESET</code> syntax.
+ </p></div><div class="refsect1" id="id-1.9.3.176.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION"><span class="refentrytitle">SET SESSION AUTHORIZATION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-set-constraints.html" title="SET CONSTRAINTS">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET CONSTRAINTS </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET SESSION AUTHORIZATION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-set-session-authorization.html b/doc/src/sgml/html/sql-set-session-authorization.html
new file mode 100644
index 0000000..d4c843b
--- /dev/null
+++ b/doc/src/sgml/html/sql-set-session-authorization.html
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET SESSION AUTHORIZATION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-set-role.html" title="SET ROLE" /><link rel="next" href="sql-set-transaction.html" title="SET TRANSACTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET SESSION AUTHORIZATION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-set-role.html" title="SET ROLE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-set-transaction.html" title="SET TRANSACTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SET-SESSION-AUTHORIZATION"><div class="titlepage"></div><a id="id-1.9.3.177.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SET SESSION AUTHORIZATION</span></h2><p>SET SESSION AUTHORIZATION — set the session user identifier and the current user identifier of the current session</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET [ SESSION | LOCAL ] SESSION AUTHORIZATION <em class="replaceable"><code>user_name</code></em>
+SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT
+RESET SESSION AUTHORIZATION
+</pre></div><div class="refsect1" id="id-1.9.3.177.5"><h2>Description</h2><p>
+ This command sets the session user identifier and the current user
+ identifier of the current SQL session to be <em class="replaceable"><code>user_name</code></em>. The user name can be
+ written as either an identifier or a string literal. Using this
+ command, it is possible, for example, to temporarily become an
+ unprivileged user and later switch back to being a superuser.
+ </p><p>
+ The session user identifier is initially set to be the (possibly
+ authenticated) user name provided by the client. The current user
+ identifier is normally equal to the session user identifier, but
+ might change temporarily in the context of <code class="literal">SECURITY DEFINER</code>
+ functions and similar mechanisms; it can also be changed by
+ <a class="link" href="sql-set-role.html" title="SET ROLE"><code class="command">SET ROLE</code></a>.
+ The current user identifier is relevant for permission checking.
+ </p><p>
+ The session user identifier can be changed only if the initial session
+ user (the <em class="firstterm">authenticated user</em>) had the
+ superuser privilege. Otherwise, the command is accepted only if it
+ specifies the authenticated user name.
+ </p><p>
+ The <code class="literal">SESSION</code> and <code class="literal">LOCAL</code> modifiers act the same
+ as for the regular <a class="link" href="sql-set.html" title="SET"><code class="command">SET</code></a>
+ command.
+ </p><p>
+ The <code class="literal">DEFAULT</code> and <code class="literal">RESET</code> forms reset the session
+ and current user identifiers to be the originally authenticated user
+ name. These forms can be executed by any user.
+ </p></div><div class="refsect1" id="id-1.9.3.177.6"><h2>Notes</h2><p>
+ <code class="command">SET SESSION AUTHORIZATION</code> cannot be used within a
+ <code class="literal">SECURITY DEFINER</code> function.
+ </p></div><div class="refsect1" id="id-1.9.3.177.7"><h2>Examples</h2><pre class="programlisting">
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ peter | peter
+
+SET SESSION AUTHORIZATION 'paul';
+
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ paul | paul
+</pre></div><div class="refsect1" id="id-1.9.3.177.8"><h2>Compatibility</h2><p>
+ The SQL standard allows some other expressions to appear in place
+ of the literal <em class="replaceable"><code>user_name</code></em>, but these options
+ are not important in practice. <span class="productname">PostgreSQL</span>
+ allows identifier syntax (<code class="literal">"<em class="replaceable"><code>username</code></em>"</code>), which SQL
+ does not. SQL does not allow this command during a transaction;
+ <span class="productname">PostgreSQL</span> does not make this
+ restriction because there is no reason to.
+ The <code class="literal">SESSION</code> and <code class="literal">LOCAL</code> modifiers are a
+ <span class="productname">PostgreSQL</span> extension, as is the
+ <code class="literal">RESET</code> syntax.
+ </p><p>
+ The privileges necessary to execute this command are left
+ implementation-defined by the standard.
+ </p></div><div class="refsect1" id="id-1.9.3.177.9"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-set-role.html" title="SET ROLE"><span class="refentrytitle">SET ROLE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-set-role.html" title="SET ROLE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-set-transaction.html" title="SET TRANSACTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET ROLE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET TRANSACTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-set-transaction.html b/doc/src/sgml/html/sql-set-transaction.html
new file mode 100644
index 0000000..10876e1
--- /dev/null
+++ b/doc/src/sgml/html/sql-set-transaction.html
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET TRANSACTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION" /><link rel="next" href="sql-show.html" title="SHOW" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET TRANSACTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-show.html" title="SHOW">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SET-TRANSACTION"><div class="titlepage"></div><a id="id-1.9.3.178.1" class="indexterm"></a><a id="id-1.9.3.178.2" class="indexterm"></a><a id="id-1.9.3.178.3" class="indexterm"></a><a id="id-1.9.3.178.4" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SET TRANSACTION</span></h2><p>SET TRANSACTION — set the characteristics of the current transaction</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET TRANSACTION <em class="replaceable"><code>transaction_mode</code></em> [, ...]
+SET TRANSACTION SNAPSHOT <em class="replaceable"><code>snapshot_id</code></em>
+SET SESSION CHARACTERISTICS AS TRANSACTION <em class="replaceable"><code>transaction_mode</code></em> [, ...]
+
+<span class="phrase">where <em class="replaceable"><code>transaction_mode</code></em> is one of:</span>
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+</pre></div><div class="refsect1" id="id-1.9.3.178.8"><h2>Description</h2><p>
+ The <code class="command">SET TRANSACTION</code> command sets the
+ characteristics of the current transaction. It has no effect on any
+ subsequent transactions. <code class="command">SET SESSION
+ CHARACTERISTICS</code> sets the default transaction
+ characteristics for subsequent transactions of a session. These
+ defaults can be overridden by <code class="command">SET TRANSACTION</code>
+ for an individual transaction.
+ </p><p>
+ The available transaction characteristics are the transaction
+ isolation level, the transaction access mode (read/write or
+ read-only), and the deferrable mode.
+ In addition, a snapshot can be selected, though only for the current
+ transaction, not as a session default.
+ </p><p>
+ The isolation level of a transaction determines what data the
+ transaction can see when other transactions are running concurrently:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">READ COMMITTED</code></span></dt><dd><p>
+ A statement can only see rows committed before it began. This
+ is the default.
+ </p></dd><dt><span class="term"><code class="literal">REPEATABLE READ</code></span></dt><dd><p>
+ All statements of the current transaction can only see rows committed
+ before the first query or data-modification statement was executed in
+ this transaction.
+ </p></dd><dt><span class="term"><code class="literal">SERIALIZABLE</code></span></dt><dd><p>
+ All statements of the current transaction can only see rows committed
+ before the first query or data-modification statement was executed in
+ this transaction. If a pattern of reads and writes among concurrent
+ serializable transactions would create a situation which could not
+ have occurred for any serial (one-at-a-time) execution of those
+ transactions, one of them will be rolled back with a
+ <code class="literal">serialization_failure</code> error.
+ </p></dd></dl></div><p>
+
+ The SQL standard defines one additional level, <code class="literal">READ
+ UNCOMMITTED</code>.
+ In <span class="productname">PostgreSQL</span> <code class="literal">READ
+ UNCOMMITTED</code> is treated as <code class="literal">READ COMMITTED</code>.
+ </p><p>
+ The transaction isolation level cannot be changed after the first query or
+ data-modification statement (<code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">DELETE</code>,
+ <code class="command">UPDATE</code>, <code class="command">MERGE</code>,
+ <code class="command">FETCH</code>, or
+ <code class="command">COPY</code>) of a transaction has been executed. See
+ <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a> for more information about transaction
+ isolation and concurrency control.
+ </p><p>
+ The transaction access mode determines whether the transaction is
+ read/write or read-only. Read/write is the default. When a
+ transaction is read-only, the following SQL commands are
+ disallowed: <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, <code class="command">MERGE</code>, and
+ <code class="command">COPY FROM</code> if the
+ table they would write to is not a temporary table; all
+ <code class="literal">CREATE</code>, <code class="literal">ALTER</code>, and
+ <code class="literal">DROP</code> commands; <code class="literal">COMMENT</code>,
+ <code class="literal">GRANT</code>, <code class="literal">REVOKE</code>,
+ <code class="literal">TRUNCATE</code>; and <code class="literal">EXPLAIN ANALYZE</code>
+ and <code class="literal">EXECUTE</code> if the command they would execute is
+ among those listed. This is a high-level notion of read-only that
+ does not prevent all writes to disk.
+ </p><p>
+ The <code class="literal">DEFERRABLE</code> transaction property has no effect
+ unless the transaction is also <code class="literal">SERIALIZABLE</code> and
+ <code class="literal">READ ONLY</code>. When all three of these properties are
+ selected for a
+ transaction, the transaction may block when first acquiring its snapshot,
+ after which it is able to run without the normal overhead of a
+ <code class="literal">SERIALIZABLE</code> transaction and without any risk of
+ contributing to or being canceled by a serialization failure. This mode
+ is well suited for long-running reports or backups.
+ </p><p>
+ The <code class="literal">SET TRANSACTION SNAPSHOT</code> command allows a new
+ transaction to run with the same <em class="firstterm">snapshot</em> as an existing
+ transaction. The pre-existing transaction must have exported its snapshot
+ with the <code class="literal">pg_export_snapshot</code> function (see <a class="xref" href="functions-admin.html#FUNCTIONS-SNAPSHOT-SYNCHRONIZATION" title="9.27.5. Snapshot Synchronization Functions">Section 9.27.5</a>). That function returns a
+ snapshot identifier, which must be given to <code class="literal">SET TRANSACTION
+ SNAPSHOT</code> to specify which snapshot is to be imported. The
+ identifier must be written as a string literal in this command, for example
+ <code class="literal">'00000003-0000001B-1'</code>.
+ <code class="literal">SET TRANSACTION SNAPSHOT</code> can only be executed at the
+ start of a transaction, before the first query or
+ data-modification statement (<code class="command">SELECT</code>,
+ <code class="command">INSERT</code>, <code class="command">DELETE</code>,
+ <code class="command">UPDATE</code>, <code class="command">MERGE</code>,
+ <code class="command">FETCH</code>, or
+ <code class="command">COPY</code>) of the transaction. Furthermore, the transaction
+ must already be set to <code class="literal">SERIALIZABLE</code> or
+ <code class="literal">REPEATABLE READ</code> isolation level (otherwise, the snapshot
+ would be discarded immediately, since <code class="literal">READ COMMITTED</code> mode takes
+ a new snapshot for each command). If the importing transaction uses
+ <code class="literal">SERIALIZABLE</code> isolation level, then the transaction that
+ exported the snapshot must also use that isolation level. Also, a
+ non-read-only serializable transaction cannot import a snapshot from a
+ read-only transaction.
+ </p></div><div class="refsect1" id="id-1.9.3.178.9"><h2>Notes</h2><p>
+ If <code class="command">SET TRANSACTION</code> is executed without a prior
+ <code class="command">START TRANSACTION</code> or <code class="command">BEGIN</code>,
+ it emits a warning and otherwise has no effect.
+ </p><p>
+ It is possible to dispense with <code class="command">SET TRANSACTION</code>
+ by instead specifying the desired <em class="replaceable"><code>transaction_modes</code></em> in
+ <code class="command">BEGIN</code> or <code class="command">START TRANSACTION</code>.
+ But that option is not available for <code class="command">SET TRANSACTION
+ SNAPSHOT</code>.
+ </p><p>
+ The session default transaction modes can also be set or examined via the
+ configuration parameters <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TRANSACTION-ISOLATION">default_transaction_isolation</a>,
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TRANSACTION-READ-ONLY">default_transaction_read_only</a>, and
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TRANSACTION-DEFERRABLE">default_transaction_deferrable</a>.
+ (In fact <code class="command">SET SESSION CHARACTERISTICS</code> is just a
+ verbose equivalent for setting these variables with <code class="command">SET</code>.)
+ This means the defaults can be set in the configuration file, via
+ <code class="command">ALTER DATABASE</code>, etc. Consult <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>
+ for more information.
+ </p><p>
+ The current transaction's modes can similarly be set or examined via the
+ configuration parameters <a class="xref" href="runtime-config-client.html#GUC-TRANSACTION-ISOLATION">transaction_isolation</a>,
+ <a class="xref" href="runtime-config-client.html#GUC-TRANSACTION-READ-ONLY">transaction_read_only</a>, and
+ <a class="xref" href="runtime-config-client.html#GUC-TRANSACTION-DEFERRABLE">transaction_deferrable</a>. Setting one of these
+ parameters acts the same as the corresponding <code class="command">SET
+ TRANSACTION</code> option, with the same restrictions on when it can
+ be done. However, these parameters cannot be set in the configuration
+ file, or from any source other than live SQL.
+ </p></div><div class="refsect1" id="id-1.9.3.178.10"><h2>Examples</h2><p>
+ To begin a new transaction with the same snapshot as an already
+ existing transaction, first export the snapshot from the existing
+ transaction. That will return the snapshot identifier, for example:
+
+</p><pre class="programlisting">
+BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SELECT pg_export_snapshot();
+ pg_export_snapshot
+---------------------
+ 00000003-0000001B-1
+(1 row)
+</pre><p>
+
+ Then give the snapshot identifier in a <code class="command">SET TRANSACTION
+ SNAPSHOT</code> command at the beginning of the newly opened
+ transaction:
+
+</p><pre class="programlisting">
+BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SET TRANSACTION SNAPSHOT '00000003-0000001B-1';
+</pre></div><div class="refsect1" id="R1-SQL-SET-TRANSACTION-3"><h2>Compatibility</h2><p>
+ These commands are defined in the <acronym class="acronym">SQL</acronym> standard,
+ except for the <code class="literal">DEFERRABLE</code> transaction mode
+ and the <code class="command">SET TRANSACTION SNAPSHOT</code> form, which are
+ <span class="productname">PostgreSQL</span> extensions.
+ </p><p>
+ <code class="literal">SERIALIZABLE</code> is the default transaction
+ isolation level in the standard. In
+ <span class="productname">PostgreSQL</span> the default is ordinarily
+ <code class="literal">READ COMMITTED</code>, but you can change it as
+ mentioned above.
+ </p><p>
+ In the SQL standard, there is one other transaction characteristic
+ that can be set with these commands: the size of the diagnostics
+ area. This concept is specific to embedded SQL, and therefore is
+ not implemented in the <span class="productname">PostgreSQL</span> server.
+ </p><p>
+ The SQL standard requires commas between successive <em class="replaceable"><code>transaction_modes</code></em>, but for historical
+ reasons <span class="productname">PostgreSQL</span> allows the commas to be
+ omitted.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-set-session-authorization.html" title="SET SESSION AUTHORIZATION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-show.html" title="SHOW">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET SESSION AUTHORIZATION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SHOW</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-set.html b/doc/src/sgml/html/sql-set.html
new file mode 100644
index 0000000..ae5aca4
--- /dev/null
+++ b/doc/src/sgml/html/sql-set.html
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SET</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-selectinto.html" title="SELECT INTO" /><link rel="next" href="sql-set-constraints.html" title="SET CONSTRAINTS" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SET</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-selectinto.html" title="SELECT INTO">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-set-constraints.html" title="SET CONSTRAINTS">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SET"><div class="titlepage"></div><a id="id-1.9.3.174.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SET</span></h2><p>SET — change a run-time parameter</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SET [ SESSION | LOCAL ] <em class="replaceable"><code>configuration_parameter</code></em> { TO | = } { <em class="replaceable"><code>value</code></em> | '<em class="replaceable"><code>value</code></em>' | DEFAULT }
+SET [ SESSION | LOCAL ] TIME ZONE { <em class="replaceable"><code>value</code></em> | '<em class="replaceable"><code>value</code></em>' | LOCAL | DEFAULT }
+</pre></div><div class="refsect1" id="id-1.9.3.174.5"><h2>Description</h2><p>
+ The <code class="command">SET</code> command changes run-time configuration
+ parameters. Many of the run-time parameters listed in
+ <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> can be changed on-the-fly with
+ <code class="command">SET</code>.
+ (Some parameters can only be changed by superusers and users who
+ have been granted <code class="literal">SET</code> privilege on that parameter.
+ There are also parameters that cannot be changed after server or
+ session start.)
+ <code class="command">SET</code> only affects the value used by the current
+ session.
+ </p><p>
+ If <code class="command">SET</code> (or equivalently <code class="command">SET SESSION</code>)
+ is issued within a transaction that is later aborted, the effects of the
+ <code class="command">SET</code> command disappear when the transaction is rolled
+ back. Once the surrounding transaction is committed, the effects
+ will persist until the end of the session, unless overridden by another
+ <code class="command">SET</code>.
+ </p><p>
+ The effects of <code class="command">SET LOCAL</code> last only till the end of
+ the current transaction, whether committed or not. A special case is
+ <code class="command">SET</code> followed by <code class="command">SET LOCAL</code> within
+ a single transaction: the <code class="command">SET LOCAL</code> value will be
+ seen until the end of the transaction, but afterwards (if the transaction
+ is committed) the <code class="command">SET</code> value will take effect.
+ </p><p>
+ The effects of <code class="command">SET</code> or <code class="command">SET LOCAL</code> are
+ also canceled by rolling back to a savepoint that is earlier than the
+ command.
+ </p><p>
+ If <code class="command">SET LOCAL</code> is used within a function that has a
+ <code class="literal">SET</code> option for the same variable (see
+ <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>),
+ the effects of the <code class="command">SET LOCAL</code> command disappear at
+ function exit; that is, the value in effect when the function was called is
+ restored anyway. This allows <code class="command">SET LOCAL</code> to be used for
+ dynamic or repeated changes of a parameter within a function, while still
+ having the convenience of using the <code class="literal">SET</code> option to save and
+ restore the caller's value. However, a regular <code class="command">SET</code> command
+ overrides any surrounding function's <code class="literal">SET</code> option; its effects
+ will persist unless rolled back.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In <span class="productname">PostgreSQL</span> versions 8.0 through 8.2,
+ the effects of a <code class="command">SET LOCAL</code> would be canceled by
+ releasing an earlier savepoint, or by successful exit from a
+ <span class="application">PL/pgSQL</span> exception block. This behavior
+ has been changed because it was deemed unintuitive.
+ </p></div></div><div class="refsect1" id="id-1.9.3.174.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SESSION</code></span></dt><dd><p>
+ Specifies that the command takes effect for the current session.
+ (This is the default if neither <code class="literal">SESSION</code> nor
+ <code class="literal">LOCAL</code> appears.)
+ </p></dd><dt><span class="term"><code class="literal">LOCAL</code></span></dt><dd><p>
+ Specifies that the command takes effect for only the current
+ transaction. After <code class="command">COMMIT</code> or <code class="command">ROLLBACK</code>,
+ the session-level setting takes effect again. Issuing this
+ outside of a transaction block emits a warning and otherwise has
+ no effect.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>configuration_parameter</code></em></span></dt><dd><p>
+ Name of a settable run-time parameter. Available parameters are
+ documented in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> and below.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>value</code></em></span></dt><dd><p>
+ New value of parameter. Values can be specified as string
+ constants, identifiers, numbers, or comma-separated lists of
+ these, as appropriate for the particular parameter.
+ <code class="literal">DEFAULT</code> can be written to specify
+ resetting the parameter to its default value (that is, whatever
+ value it would have had if no <code class="command">SET</code> had been executed
+ in the current session).
+ </p></dd></dl></div><p>
+ Besides the configuration parameters documented in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a>, there are a few that can only be
+ adjusted using the <code class="command">SET</code> command or that have a
+ special syntax:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SCHEMA</code></span></dt><dd><p><code class="literal">SET SCHEMA '<em class="replaceable"><code>value</code></em>'</code> is an alias for
+ <code class="literal">SET search_path TO <em class="replaceable"><code>value</code></em></code>. Only one
+ schema can be specified using this syntax.
+ </p></dd><dt><span class="term"><code class="literal">NAMES</code></span></dt><dd><p><code class="literal">SET NAMES <em class="replaceable"><code>value</code></em></code> is an alias for
+ <code class="literal">SET client_encoding TO <em class="replaceable"><code>value</code></em></code>.
+ </p></dd><dt><span class="term"><code class="literal">SEED</code></span></dt><dd><p>
+ Sets the internal seed for the random number generator (the
+ function <code class="function">random</code>). Allowed values are
+ floating-point numbers between -1 and 1 inclusive.
+ </p><p>
+ The seed can also be set by invoking the function
+ <code class="function">setseed</code>:
+</p><pre class="programlisting">
+SELECT setseed(<em class="replaceable"><code>value</code></em>);
+</pre></dd><dt><span class="term"><code class="literal">TIME ZONE</code></span></dt><dd><p><code class="literal">SET TIME ZONE '<em class="replaceable"><code>value</code></em>'</code> is an alias
+ for <code class="literal">SET timezone TO '<em class="replaceable"><code>value</code></em>'</code>. The
+ syntax <code class="literal">SET TIME ZONE</code> allows special syntax
+ for the time zone specification. Here are examples of valid
+ values:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">'PST8PDT'</code></span></dt><dd><p>
+ The time zone for Berkeley, California.
+ </p></dd><dt><span class="term"><code class="literal">'Europe/Rome'</code></span></dt><dd><p>
+ The time zone for Italy.
+ </p></dd><dt><span class="term"><code class="literal">-7</code></span></dt><dd><p>
+ The time zone 7 hours west from UTC (equivalent
+ to PDT). Positive values are east from UTC.
+ </p></dd><dt><span class="term"><code class="literal">INTERVAL '-08:00' HOUR TO MINUTE</code></span></dt><dd><p>
+ The time zone 8 hours west from UTC (equivalent
+ to PST).
+ </p></dd><dt><span class="term"><code class="literal">LOCAL</code><br /></span><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Set the time zone to your local time zone (that is, the
+ server's default value of <code class="varname">timezone</code>).
+ </p></dd></dl></div><p>
+ </p><p>
+ Timezone settings given as numbers or intervals are internally
+ translated to POSIX timezone syntax. For example, after
+ <code class="literal">SET TIME ZONE -7</code>, <code class="command">SHOW TIME ZONE</code> would
+ report <code class="literal">&lt;-07&gt;+07</code>.
+ </p><p>
+ Time zone abbreviations are not supported by <code class="command">SET</code>;
+ see <a class="xref" href="datatype-datetime.html#DATATYPE-TIMEZONES" title="8.5.3. Time Zones">Section 8.5.3</a> for more information
+ about time zones.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.9.3.174.7"><h2>Notes</h2><p>
+ The function <code class="function">set_config</code> provides equivalent
+ functionality; see <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SET" title="9.27.1. Configuration Settings Functions">Section 9.27.1</a>.
+ Also, it is possible to UPDATE the
+ <a class="link" href="view-pg-settings.html" title="54.24. pg_settings"><code class="structname">pg_settings</code></a>
+ system view to perform the equivalent of <code class="command">SET</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.174.8"><h2>Examples</h2><p>
+ Set the schema search path:
+</p><pre class="programlisting">
+SET search_path TO my_schema, public;
+</pre><p>
+ </p><p>
+ Set the style of date to traditional
+ <span class="productname">POSTGRES</span> with <span class="quote">“<span class="quote">day before month</span>”</span>
+ input convention:
+</p><pre class="screen">
+SET datestyle TO postgres, dmy;
+</pre><p>
+ </p><p>
+ Set the time zone for Berkeley, California:
+</p><pre class="screen">
+SET TIME ZONE 'PST8PDT';
+</pre><p>
+ </p><p>
+ Set the time zone for Italy:
+</p><pre class="screen">
+SET TIME ZONE 'Europe/Rome';
+</pre></div><div class="refsect1" id="id-1.9.3.174.9"><h2>Compatibility</h2><p>
+ <code class="literal">SET TIME ZONE</code> extends syntax defined in the SQL
+ standard. The standard allows only numeric time zone offsets while
+ <span class="productname">PostgreSQL</span> allows more flexible
+ time-zone specifications. All other <code class="literal">SET</code>
+ features are <span class="productname">PostgreSQL</span> extensions.
+ </p></div><div class="refsect1" id="id-1.9.3.174.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-reset.html" title="RESET"><span class="refentrytitle">RESET</span></a>, <a class="xref" href="sql-show.html" title="SHOW"><span class="refentrytitle">SHOW</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-selectinto.html" title="SELECT INTO">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-set-constraints.html" title="SET CONSTRAINTS">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SELECT INTO </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SET CONSTRAINTS</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-show.html b/doc/src/sgml/html/sql-show.html
new file mode 100644
index 0000000..ee4bcc3
--- /dev/null
+++ b/doc/src/sgml/html/sql-show.html
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SHOW</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-set-transaction.html" title="SET TRANSACTION" /><link rel="next" href="sql-start-transaction.html" title="START TRANSACTION" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SHOW</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-set-transaction.html" title="SET TRANSACTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-start-transaction.html" title="START TRANSACTION">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-SHOW"><div class="titlepage"></div><a id="id-1.9.3.179.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SHOW</span></h2><p>SHOW — show the value of a run-time parameter</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+SHOW <em class="replaceable"><code>name</code></em>
+SHOW ALL
+</pre></div><div class="refsect1" id="id-1.9.3.179.5"><h2>Description</h2><p>
+ <code class="command">SHOW</code> will display the current setting of
+ run-time parameters. These variables can be set using the
+ <code class="command">SET</code> statement, by editing the
+ <code class="filename">postgresql.conf</code> configuration file, through
+ the <code class="envar">PGOPTIONS</code> environmental variable (when using
+ <span class="application">libpq</span> or a <span class="application">libpq</span>-based
+ application), or through command-line flags when starting the
+ <code class="command">postgres</code> server. See <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for details.
+ </p></div><div class="refsect1" id="id-1.9.3.179.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name of a run-time parameter. Available parameters are
+ documented in <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> and on the <a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a> reference page. In
+ addition, there are a few parameters that can be shown but not
+ set:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">SERVER_VERSION</code></span></dt><dd><p>
+ Shows the server's version number.
+ </p></dd><dt><span class="term"><code class="literal">SERVER_ENCODING</code></span></dt><dd><p>
+ Shows the server-side character set encoding. At present,
+ this parameter can be shown but not set, because the
+ encoding is determined at database creation time.
+ </p></dd><dt><span class="term"><code class="literal">LC_COLLATE</code></span></dt><dd><p>
+ Shows the database's locale setting for collation (text
+ ordering). At present, this parameter can be shown but not
+ set, because the setting is determined at database creation
+ time.
+ </p></dd><dt><span class="term"><code class="literal">LC_CTYPE</code></span></dt><dd><p>
+ Shows the database's locale setting for character
+ classification. At present, this parameter can be shown but
+ not set, because the setting is determined at database creation
+ time.
+ </p></dd><dt><span class="term"><code class="literal">IS_SUPERUSER</code></span></dt><dd><p>
+ True if the current role has superuser privileges.
+ </p></dd></dl></div></dd><dt><span class="term"><code class="literal">ALL</code></span></dt><dd><p>
+ Show the values of all configuration parameters, with descriptions.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.179.7"><h2>Notes</h2><p>
+ The function <code class="function">current_setting</code> produces
+ equivalent output; see <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-SET" title="9.27.1. Configuration Settings Functions">Section 9.27.1</a>.
+ Also, the
+ <a class="link" href="view-pg-settings.html" title="54.24. pg_settings"><code class="structname">pg_settings</code></a>
+ system view produces the same information.
+
+ </p></div><div class="refsect1" id="id-1.9.3.179.8"><h2>Examples</h2><p>
+ Show the current setting of the parameter <code class="varname">DateStyle</code>:
+
+</p><pre class="programlisting">
+SHOW DateStyle;
+ DateStyle
+-----------
+ ISO, MDY
+(1 row)
+</pre><p>
+ </p><p>
+ Show the current setting of the parameter <code class="varname">geqo</code>:
+</p><pre class="programlisting">
+SHOW geqo;
+ geqo
+------
+ on
+(1 row)
+</pre><p>
+ </p><p>
+ Show all settings:
+</p><pre class="programlisting">
+SHOW ALL;
+ name | setting | description
+-------------------------+---------+-------------------------------------------------
+ allow_system_table_mods | off | Allows modifications of the structure of ...
+ .
+ .
+ .
+ xmloption | content | Sets whether XML data in implicit parsing ...
+ zero_damaged_pages | off | Continues processing past damaged page headers.
+(196 rows)
+</pre></div><div class="refsect1" id="id-1.9.3.179.9"><h2>Compatibility</h2><p>
+ The <code class="command">SHOW</code> command is a
+ <span class="productname">PostgreSQL</span> extension.
+ </p></div><div class="refsect1" id="id-1.9.3.179.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-set.html" title="SET"><span class="refentrytitle">SET</span></a>, <a class="xref" href="sql-reset.html" title="RESET"><span class="refentrytitle">RESET</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-set-transaction.html" title="SET TRANSACTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-start-transaction.html" title="START TRANSACTION">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SET TRANSACTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> START TRANSACTION</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-start-transaction.html b/doc/src/sgml/html/sql-start-transaction.html
new file mode 100644
index 0000000..04c1638
--- /dev/null
+++ b/doc/src/sgml/html/sql-start-transaction.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>START TRANSACTION</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-show.html" title="SHOW" /><link rel="next" href="sql-truncate.html" title="TRUNCATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">START TRANSACTION</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-show.html" title="SHOW">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-truncate.html" title="TRUNCATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-START-TRANSACTION"><div class="titlepage"></div><a id="id-1.9.3.180.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">START TRANSACTION</span></h2><p>START TRANSACTION — start a transaction block</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+START TRANSACTION [ <em class="replaceable"><code>transaction_mode</code></em> [, ...] ]
+
+<span class="phrase">where <em class="replaceable"><code>transaction_mode</code></em> is one of:</span>
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+</pre></div><div class="refsect1" id="id-1.9.3.180.5"><h2>Description</h2><p>
+ This command begins a new transaction block. If the isolation level,
+ read/write mode, or deferrable mode is specified, the new transaction has those
+ characteristics, as if <a class="link" href="sql-set-transaction.html" title="SET TRANSACTION"><code class="command">SET TRANSACTION</code></a> was executed. This is the same
+ as the <a class="link" href="sql-begin.html" title="BEGIN"><code class="command">BEGIN</code></a> command.
+ </p></div><div class="refsect1" id="id-1.9.3.180.6"><h2>Parameters</h2><p>
+ Refer to <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a> for information on the meaning
+ of the parameters to this statement.
+ </p></div><div class="refsect1" id="id-1.9.3.180.7"><h2>Compatibility</h2><p>
+ In the standard, it is not necessary to issue <code class="command">START TRANSACTION</code>
+ to start a transaction block: any SQL command implicitly begins a block.
+ <span class="productname">PostgreSQL</span>'s behavior can be seen as implicitly
+ issuing a <code class="command">COMMIT</code> after each command that does not
+ follow <code class="command">START TRANSACTION</code> (or <code class="command">BEGIN</code>),
+ and it is therefore often called <span class="quote">“<span class="quote">autocommit</span>”</span>.
+ Other relational database systems might offer an autocommit feature
+ as a convenience.
+ </p><p>
+ The <code class="literal">DEFERRABLE</code>
+ <em class="replaceable"><code>transaction_mode</code></em>
+ is a <span class="productname">PostgreSQL</span> language extension.
+ </p><p>
+ The SQL standard requires commas between successive <em class="replaceable"><code>transaction_modes</code></em>, but for historical
+ reasons <span class="productname">PostgreSQL</span> allows the commas to be
+ omitted.
+ </p><p>
+ See also the compatibility section of <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.180.8"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-begin.html" title="BEGIN"><span class="refentrytitle">BEGIN</span></a>, <a class="xref" href="sql-commit.html" title="COMMIT"><span class="refentrytitle">COMMIT</span></a>, <a class="xref" href="sql-rollback.html" title="ROLLBACK"><span class="refentrytitle">ROLLBACK</span></a>, <a class="xref" href="sql-savepoint.html" title="SAVEPOINT"><span class="refentrytitle">SAVEPOINT</span></a>, <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-show.html" title="SHOW">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-truncate.html" title="TRUNCATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SHOW </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> TRUNCATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-syntax-calling-funcs.html b/doc/src/sgml/html/sql-syntax-calling-funcs.html
new file mode 100644
index 0000000..232fb7a
--- /dev/null
+++ b/doc/src/sgml/html/sql-syntax-calling-funcs.html
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>4.3. Calling Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-expressions.html" title="4.2. Value Expressions" /><link rel="next" href="ddl.html" title="Chapter 5. Data Definition" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">4.3. Calling Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-expressions.html" title="4.2. Value Expressions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Up</a></td><th width="60%" align="center">Chapter 4. SQL Syntax</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="ddl.html" title="Chapter 5. Data Definition">Next</a></td></tr></table><hr /></div><div class="sect1" id="SQL-SYNTAX-CALLING-FUNCS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">4.3. Calling Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-POSITIONAL">4.3.1. Using Positional Notation</a></span></dt><dt><span class="sect2"><a href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-NAMED">4.3.2. Using Named Notation</a></span></dt><dt><span class="sect2"><a href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-MIXED">4.3.3. Using Mixed Notation</a></span></dt></dl></div><a id="id-1.5.3.7.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> allows functions that have named
+ parameters to be called using either <em class="firstterm">positional</em> or
+ <em class="firstterm">named</em> notation. Named notation is especially
+ useful for functions that have a large number of parameters, since it
+ makes the associations between parameters and actual arguments more
+ explicit and reliable.
+ In positional notation, a function call is written with
+ its argument values in the same order as they are defined in the function
+ declaration. In named notation, the arguments are matched to the
+ function parameters by name and can be written in any order.
+ For each notation, also consider the effect of function argument types,
+ documented in <a class="xref" href="typeconv-func.html" title="10.3. Functions">Section 10.3</a>.
+ </p><p>
+ In either notation, parameters that have default values given in the
+ function declaration need not be written in the call at all. But this
+ is particularly useful in named notation, since any combination of
+ parameters can be omitted; while in positional notation parameters can
+ only be omitted from right to left.
+ </p><p>
+ <span class="productname">PostgreSQL</span> also supports
+ <em class="firstterm">mixed</em> notation, which combines positional and
+ named notation. In this case, positional parameters are written first
+ and named parameters appear after them.
+ </p><p>
+ The following examples will illustrate the usage of all three
+ notations, using the following function definition:
+</p><pre class="programlisting">
+CREATE FUNCTION concat_lower_or_upper(a text, b text, uppercase boolean DEFAULT false)
+RETURNS text
+AS
+$$
+ SELECT CASE
+ WHEN $3 THEN UPPER($1 || ' ' || $2)
+ ELSE LOWER($1 || ' ' || $2)
+ END;
+$$
+LANGUAGE SQL IMMUTABLE STRICT;
+</pre><p>
+ Function <code class="function">concat_lower_or_upper</code> has two mandatory
+ parameters, <code class="literal">a</code> and <code class="literal">b</code>. Additionally
+ there is one optional parameter <code class="literal">uppercase</code> which defaults
+ to <code class="literal">false</code>. The <code class="literal">a</code> and
+ <code class="literal">b</code> inputs will be concatenated, and forced to either
+ upper or lower case depending on the <code class="literal">uppercase</code>
+ parameter. The remaining details of this function
+ definition are not important here (see <a class="xref" href="extend.html" title="Chapter 38. Extending SQL">Chapter 38</a> for
+ more information).
+ </p><div class="sect2" id="SQL-SYNTAX-CALLING-FUNCS-POSITIONAL"><div class="titlepage"><div><div><h3 class="title">4.3.1. Using Positional Notation</h3></div></div></div><a id="id-1.5.3.7.7.2" class="indexterm"></a><p>
+ Positional notation is the traditional mechanism for passing arguments
+ to functions in <span class="productname">PostgreSQL</span>. An example is:
+</p><pre class="screen">
+SELECT concat_lower_or_upper('Hello', 'World', true);
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</pre><p>
+ All arguments are specified in order. The result is upper case since
+ <code class="literal">uppercase</code> is specified as <code class="literal">true</code>.
+ Another example is:
+</p><pre class="screen">
+SELECT concat_lower_or_upper('Hello', 'World');
+ concat_lower_or_upper
+-----------------------
+ hello world
+(1 row)
+</pre><p>
+ Here, the <code class="literal">uppercase</code> parameter is omitted, so it
+ receives its default value of <code class="literal">false</code>, resulting in
+ lower case output. In positional notation, arguments can be omitted
+ from right to left so long as they have defaults.
+ </p></div><div class="sect2" id="SQL-SYNTAX-CALLING-FUNCS-NAMED"><div class="titlepage"><div><div><h3 class="title">4.3.2. Using Named Notation</h3></div></div></div><a id="id-1.5.3.7.8.2" class="indexterm"></a><p>
+ In named notation, each argument's name is specified using
+ <code class="literal">=&gt;</code> to separate it from the argument expression.
+ For example:
+</p><pre class="screen">
+SELECT concat_lower_or_upper(a =&gt; 'Hello', b =&gt; 'World');
+ concat_lower_or_upper
+-----------------------
+ hello world
+(1 row)
+</pre><p>
+ Again, the argument <code class="literal">uppercase</code> was omitted
+ so it is set to <code class="literal">false</code> implicitly. One advantage of
+ using named notation is that the arguments may be specified in any
+ order, for example:
+</p><pre class="screen">
+SELECT concat_lower_or_upper(a =&gt; 'Hello', b =&gt; 'World', uppercase =&gt; true);
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+
+SELECT concat_lower_or_upper(a =&gt; 'Hello', uppercase =&gt; true, b =&gt; 'World');
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</pre><p>
+ </p><p>
+ An older syntax based on ":=" is supported for backward compatibility:
+</p><pre class="screen">
+SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="SQL-SYNTAX-CALLING-FUNCS-MIXED"><div class="titlepage"><div><div><h3 class="title">4.3.3. Using Mixed Notation</h3></div></div></div><a id="id-1.5.3.7.9.2" class="indexterm"></a><p>
+ The mixed notation combines positional and named notation. However, as
+ already mentioned, named arguments cannot precede positional arguments.
+ For example:
+</p><pre class="screen">
+SELECT concat_lower_or_upper('Hello', 'World', uppercase =&gt; true);
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</pre><p>
+ In the above query, the arguments <code class="literal">a</code> and
+ <code class="literal">b</code> are specified positionally, while
+ <code class="literal">uppercase</code> is specified by name. In this example,
+ that adds little except documentation. With a more complex function
+ having numerous parameters that have default values, named or mixed
+ notation can save a great deal of writing and reduce chances for error.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Named and mixed call notations currently cannot be used when calling an
+ aggregate function (but they do work when an aggregate function is used
+ as a window function).
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-expressions.html" title="4.2. Value Expressions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ddl.html" title="Chapter 5. Data Definition">Next</a></td></tr><tr><td width="40%" align="left" valign="top">4.2. Value Expressions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 5. Data Definition</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-syntax-lexical.html b/doc/src/sgml/html/sql-syntax-lexical.html
new file mode 100644
index 0000000..d72d7b9
--- /dev/null
+++ b/doc/src/sgml/html/sql-syntax-lexical.html
@@ -0,0 +1,647 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>4.1. Lexical Structure</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-syntax.html" title="Chapter 4. SQL Syntax" /><link rel="next" href="sql-expressions.html" title="4.2. Value Expressions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">4.1. Lexical Structure</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Up</a></td><th width="60%" align="center">Chapter 4. SQL Syntax</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-expressions.html" title="4.2. Value Expressions">Next</a></td></tr></table><hr /></div><div class="sect1" id="SQL-SYNTAX-LEXICAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">4.1. Lexical Structure</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">4.1.1. Identifiers and Key Words</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS">4.1.2. Constants</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS">4.1.3. Operators</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-SPECIAL-CHARS">4.1.4. Special Characters</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-COMMENTS">4.1.5. Comments</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-PRECEDENCE">4.1.6. Operator Precedence</a></span></dt></dl></div><a id="id-1.5.3.5.2" class="indexterm"></a><p>
+ SQL input consists of a sequence of
+ <em class="firstterm">commands</em>. A command is composed of a
+ sequence of <em class="firstterm">tokens</em>, terminated by a
+ semicolon (<span class="quote">“<span class="quote">;</span>”</span>). The end of the input stream also
+ terminates a command. Which tokens are valid depends on the syntax
+ of the particular command.
+ </p><p>
+ A token can be a <em class="firstterm">key word</em>, an
+ <em class="firstterm">identifier</em>, a <em class="firstterm">quoted
+ identifier</em>, a <em class="firstterm">literal</em> (or
+ constant), or a special character symbol. Tokens are normally
+ separated by whitespace (space, tab, newline), but need not be if
+ there is no ambiguity (which is generally only the case if a
+ special character is adjacent to some other token type).
+ </p><p>
+ For example, the following is (syntactically) valid SQL input:
+</p><pre class="programlisting">
+SELECT * FROM MY_TABLE;
+UPDATE MY_TABLE SET A = 5;
+INSERT INTO MY_TABLE VALUES (3, 'hi there');
+</pre><p>
+ This is a sequence of three commands, one per line (although this
+ is not required; more than one command can be on a line, and
+ commands can usefully be split across lines).
+ </p><p>
+ Additionally, <em class="firstterm">comments</em> can occur in SQL
+ input. They are not tokens, they are effectively equivalent to
+ whitespace.
+ </p><p>
+ The SQL syntax is not very consistent regarding what tokens
+ identify commands and which are operands or parameters. The first
+ few tokens are generally the command name, so in the above example
+ we would usually speak of a <span class="quote">“<span class="quote">SELECT</span>”</span>, an
+ <span class="quote">“<span class="quote">UPDATE</span>”</span>, and an <span class="quote">“<span class="quote">INSERT</span>”</span> command. But
+ for instance the <code class="command">UPDATE</code> command always requires
+ a <code class="token">SET</code> token to appear in a certain position, and
+ this particular variation of <code class="command">INSERT</code> also
+ requires a <code class="token">VALUES</code> in order to be complete. The
+ precise syntax rules for each command are described in <a class="xref" href="reference.html" title="Part VI. Reference">Part VI</a>.
+ </p><div class="sect2" id="SQL-SYNTAX-IDENTIFIERS"><div class="titlepage"><div><div><h3 class="title">4.1.1. Identifiers and Key Words</h3></div></div></div><a id="id-1.5.3.5.8.2" class="indexterm"></a><a id="id-1.5.3.5.8.3" class="indexterm"></a><a id="id-1.5.3.5.8.4" class="indexterm"></a><p>
+ Tokens such as <code class="token">SELECT</code>, <code class="token">UPDATE</code>, or
+ <code class="token">VALUES</code> in the example above are examples of
+ <em class="firstterm">key words</em>, that is, words that have a fixed
+ meaning in the SQL language. The tokens <code class="token">MY_TABLE</code>
+ and <code class="token">A</code> are examples of
+ <em class="firstterm">identifiers</em>. They identify names of
+ tables, columns, or other database objects, depending on the
+ command they are used in. Therefore they are sometimes simply
+ called <span class="quote">“<span class="quote">names</span>”</span>. Key words and identifiers have the
+ same lexical structure, meaning that one cannot know whether a
+ token is an identifier or a key word without knowing the language.
+ A complete list of key words can be found in <a class="xref" href="sql-keywords-appendix.html" title="Appendix C. SQL Key Words">Appendix C</a>.
+ </p><p>
+ SQL identifiers and key words must begin with a letter
+ (<code class="literal">a</code>-<code class="literal">z</code>, but also letters with
+ diacritical marks and non-Latin letters) or an underscore
+ (<code class="literal">_</code>). Subsequent characters in an identifier or
+ key word can be letters, underscores, digits
+ (<code class="literal">0</code>-<code class="literal">9</code>), or dollar signs
+ (<code class="literal">$</code>). Note that dollar signs are not allowed in identifiers
+ according to the letter of the SQL standard, so their use might render
+ applications less portable.
+ The SQL standard will not define a key word that contains
+ digits or starts or ends with an underscore, so identifiers of this
+ form are safe against possible conflict with future extensions of the
+ standard.
+ </p><p>
+ <a id="id-1.5.3.5.8.7.1" class="indexterm"></a>
+ The system uses no more than <code class="symbol">NAMEDATALEN</code>-1
+ bytes of an identifier; longer names can be written in
+ commands, but they will be truncated. By default,
+ <code class="symbol">NAMEDATALEN</code> is 64 so the maximum identifier
+ length is 63 bytes. If this limit is problematic, it can be raised by
+ changing the <code class="symbol">NAMEDATALEN</code> constant in
+ <code class="filename">src/include/pg_config_manual.h</code>.
+ </p><p>
+ <a id="id-1.5.3.5.8.8.1" class="indexterm"></a>
+ Key words and unquoted identifiers are case insensitive. Therefore:
+</p><pre class="programlisting">
+UPDATE MY_TABLE SET A = 5;
+</pre><p>
+ can equivalently be written as:
+</p><pre class="programlisting">
+uPDaTE my_TabLE SeT a = 5;
+</pre><p>
+ A convention often used is to write key words in upper
+ case and names in lower case, e.g.:
+</p><pre class="programlisting">
+UPDATE my_table SET a = 5;
+</pre><p>
+ </p><p>
+ <a id="id-1.5.3.5.8.9.1" class="indexterm"></a>
+ There is a second kind of identifier: the <em class="firstterm">delimited
+ identifier</em> or <em class="firstterm">quoted
+ identifier</em>. It is formed by enclosing an arbitrary
+ sequence of characters in double-quotes
+ (<code class="literal">"</code>). A delimited
+ identifier is always an identifier, never a key word. So
+ <code class="literal">"select"</code> could be used to refer to a column or
+ table named <span class="quote">“<span class="quote">select</span>”</span>, whereas an unquoted
+ <code class="literal">select</code> would be taken as a key word and
+ would therefore provoke a parse error when used where a table or
+ column name is expected. The example can be written with quoted
+ identifiers like this:
+</p><pre class="programlisting">
+UPDATE "my_table" SET "a" = 5;
+</pre><p>
+ </p><p>
+ Quoted identifiers can contain any character, except the character
+ with code zero. (To include a double quote, write two double quotes.)
+ This allows constructing table or column names that would
+ otherwise not be possible, such as ones containing spaces or
+ ampersands. The length limitation still applies.
+ </p><p>
+ Quoting an identifier also makes it case-sensitive, whereas
+ unquoted names are always folded to lower case. For example, the
+ identifiers <code class="literal">FOO</code>, <code class="literal">foo</code>, and
+ <code class="literal">"foo"</code> are considered the same by
+ <span class="productname">PostgreSQL</span>, but
+ <code class="literal">"Foo"</code> and <code class="literal">"FOO"</code> are
+ different from these three and each other. (The folding of
+ unquoted names to lower case in <span class="productname">PostgreSQL</span> is
+ incompatible with the SQL standard, which says that unquoted names
+ should be folded to upper case. Thus, <code class="literal">foo</code>
+ should be equivalent to <code class="literal">"FOO"</code> not
+ <code class="literal">"foo"</code> according to the standard. If you want
+ to write portable applications you are advised to always quote a
+ particular name or never quote it.)
+ </p><a id="id-1.5.3.5.8.12" class="indexterm"></a><p>
+ A variant of quoted
+ identifiers allows including escaped Unicode characters identified
+ by their code points. This variant starts
+ with <code class="literal">U&amp;</code> (upper or lower case U followed by
+ ampersand) immediately before the opening double quote, without
+ any spaces in between, for example <code class="literal">U&amp;"foo"</code>.
+ (Note that this creates an ambiguity with the
+ operator <code class="literal">&amp;</code>. Use spaces around the operator to
+ avoid this problem.) Inside the quotes, Unicode characters can be
+ specified in escaped form by writing a backslash followed by the
+ four-digit hexadecimal code point number or alternatively a
+ backslash followed by a plus sign followed by a six-digit
+ hexadecimal code point number. For example, the
+ identifier <code class="literal">"data"</code> could be written as
+</p><pre class="programlisting">
+U&amp;"d\0061t\+000061"
+</pre><p>
+ The following less trivial example writes the Russian
+ word <span class="quote">“<span class="quote">slon</span>”</span> (elephant) in Cyrillic letters:
+</p><pre class="programlisting">
+U&amp;"\0441\043B\043E\043D"
+</pre><p>
+ </p><p>
+ If a different escape character than backslash is desired, it can
+ be specified using
+ the <code class="literal">UESCAPE</code><a id="id-1.5.3.5.8.14.2" class="indexterm"></a>
+ clause after the string, for example:
+</p><pre class="programlisting">
+U&amp;"d!0061t!+000061" UESCAPE '!'
+</pre><p>
+ The escape character can be any single character other than a
+ hexadecimal digit, the plus sign, a single quote, a double quote,
+ or a whitespace character. Note that the escape character is
+ written in single quotes, not double quotes,
+ after <code class="literal">UESCAPE</code>.
+ </p><p>
+ To include the escape character in the identifier literally, write
+ it twice.
+ </p><p>
+ Either the 4-digit or the 6-digit escape form can be used to
+ specify UTF-16 surrogate pairs to compose characters with code
+ points larger than U+FFFF, although the availability of the
+ 6-digit form technically makes this unnecessary. (Surrogate
+ pairs are not stored directly, but are combined into a single
+ code point.)
+ </p><p>
+ If the server encoding is not UTF-8, the Unicode code point identified
+ by one of these escape sequences is converted to the actual server
+ encoding; an error is reported if that's not possible.
+ </p></div><div class="sect2" id="SQL-SYNTAX-CONSTANTS"><div class="titlepage"><div><div><h3 class="title">4.1.2. Constants</h3></div></div></div><a id="id-1.5.3.5.9.2" class="indexterm"></a><p>
+ There are three kinds of <em class="firstterm">implicitly-typed
+ constants</em> in <span class="productname">PostgreSQL</span>:
+ strings, bit strings, and numbers.
+ Constants can also be specified with explicit types, which can
+ enable more accurate representation and more efficient handling by
+ the system. These alternatives are discussed in the following
+ subsections.
+ </p><div class="sect3" id="SQL-SYNTAX-STRINGS"><div class="titlepage"><div><div><h4 class="title">4.1.2.1. String Constants</h4></div></div></div><a id="id-1.5.3.5.9.4.2" class="indexterm"></a><p>
+ <a id="id-1.5.3.5.9.4.3.1" class="indexterm"></a>
+ A string constant in SQL is an arbitrary sequence of characters
+ bounded by single quotes (<code class="literal">'</code>), for example
+ <code class="literal">'This is a string'</code>. To include
+ a single-quote character within a string constant,
+ write two adjacent single quotes, e.g.,
+ <code class="literal">'Dianne''s horse'</code>.
+ Note that this is <span class="emphasis"><em>not</em></span> the same as a double-quote
+ character (<code class="literal">"</code>).
+ </p><p>
+ Two string constants that are only separated by whitespace
+ <span class="emphasis"><em>with at least one newline</em></span> are concatenated
+ and effectively treated as if the string had been written as one
+ constant. For example:
+</p><pre class="programlisting">
+SELECT 'foo'
+'bar';
+</pre><p>
+ is equivalent to:
+</p><pre class="programlisting">
+SELECT 'foobar';
+</pre><p>
+ but:
+</p><pre class="programlisting">
+SELECT 'foo' 'bar';
+</pre><p>
+ is not valid syntax. (This slightly bizarre behavior is specified
+ by <acronym class="acronym">SQL</acronym>; <span class="productname">PostgreSQL</span> is
+ following the standard.)
+ </p></div><div class="sect3" id="SQL-SYNTAX-STRINGS-ESCAPE"><div class="titlepage"><div><div><h4 class="title">4.1.2.2. String Constants with C-Style Escapes</h4></div></div></div><a id="id-1.5.3.5.9.5.2" class="indexterm"></a><a id="id-1.5.3.5.9.5.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> also accepts <span class="quote">“<span class="quote">escape</span>”</span>
+ string constants, which are an extension to the SQL standard.
+ An escape string constant is specified by writing the letter
+ <code class="literal">E</code> (upper or lower case) just before the opening single
+ quote, e.g., <code class="literal">E'foo'</code>. (When continuing an escape string
+ constant across lines, write <code class="literal">E</code> only before the first opening
+ quote.)
+ Within an escape string, a backslash character (<code class="literal">\</code>) begins a
+ C-like <em class="firstterm">backslash escape</em> sequence, in which the combination
+ of backslash and following character(s) represent a special byte
+ value, as shown in <a class="xref" href="sql-syntax-lexical.html#SQL-BACKSLASH-TABLE" title="Table 4.1. Backslash Escape Sequences">Table 4.1</a>.
+ </p><div class="table" id="SQL-BACKSLASH-TABLE"><p class="title"><strong>Table 4.1. Backslash Escape Sequences</strong></p><div class="table-contents"><table class="table" summary="Backslash Escape Sequences" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Backslash Escape Sequence</th><th>Interpretation</th></tr></thead><tbody><tr><td><code class="literal">\b</code></td><td>backspace</td></tr><tr><td><code class="literal">\f</code></td><td>form feed</td></tr><tr><td><code class="literal">\n</code></td><td>newline</td></tr><tr><td><code class="literal">\r</code></td><td>carriage return</td></tr><tr><td><code class="literal">\t</code></td><td>tab</td></tr><tr><td>
+ <code class="literal">\<em class="replaceable"><code>o</code></em></code>,
+ <code class="literal">\<em class="replaceable"><code>oo</code></em></code>,
+ <code class="literal">\<em class="replaceable"><code>ooo</code></em></code>
+ (<em class="replaceable"><code>o</code></em> = 0–7)
+ </td><td>octal byte value</td></tr><tr><td>
+ <code class="literal">\x<em class="replaceable"><code>h</code></em></code>,
+ <code class="literal">\x<em class="replaceable"><code>hh</code></em></code>
+ (<em class="replaceable"><code>h</code></em> = 0–9, A–F)
+ </td><td>hexadecimal byte value</td></tr><tr><td>
+ <code class="literal">\u<em class="replaceable"><code>xxxx</code></em></code>,
+ <code class="literal">\U<em class="replaceable"><code>xxxxxxxx</code></em></code>
+ (<em class="replaceable"><code>x</code></em> = 0–9, A–F)
+ </td><td>16 or 32-bit hexadecimal Unicode character value</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Any other
+ character following a backslash is taken literally. Thus, to
+ include a backslash character, write two backslashes (<code class="literal">\\</code>).
+ Also, a single quote can be included in an escape string by writing
+ <code class="literal">\'</code>, in addition to the normal way of <code class="literal">''</code>.
+ </p><p>
+ It is your responsibility that the byte sequences you create,
+ especially when using the octal or hexadecimal escapes, compose
+ valid characters in the server character set encoding.
+ A useful alternative is to use Unicode escapes or the
+ alternative Unicode escape syntax, explained
+ in <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-UESCAPE" title="4.1.2.3. String Constants with Unicode Escapes">Section 4.1.2.3</a>; then the server
+ will check that the character conversion is possible.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ If the configuration parameter
+ <a class="xref" href="runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS">standard_conforming_strings</a> is <code class="literal">off</code>,
+ then <span class="productname">PostgreSQL</span> recognizes backslash escapes
+ in both regular and escape string constants. However, as of
+ <span class="productname">PostgreSQL</span> 9.1, the default is <code class="literal">on</code>, meaning
+ that backslash escapes are recognized only in escape string constants.
+ This behavior is more standards-compliant, but might break applications
+ which rely on the historical behavior, where backslash escapes
+ were always recognized. As a workaround, you can set this parameter
+ to <code class="literal">off</code>, but it is better to migrate away from using backslash
+ escapes. If you need to use a backslash escape to represent a special
+ character, write the string constant with an <code class="literal">E</code>.
+ </p><p>
+ In addition to <code class="varname">standard_conforming_strings</code>, the configuration
+ parameters <a class="xref" href="runtime-config-compatible.html#GUC-ESCAPE-STRING-WARNING">escape_string_warning</a> and
+ <a class="xref" href="runtime-config-compatible.html#GUC-BACKSLASH-QUOTE">backslash_quote</a> govern treatment of backslashes
+ in string constants.
+ </p></div><p>
+ The character with the code zero cannot be in a string constant.
+ </p></div><div class="sect3" id="SQL-SYNTAX-STRINGS-UESCAPE"><div class="titlepage"><div><div><h4 class="title">4.1.2.3. String Constants with Unicode Escapes</h4></div></div></div><a id="id-1.5.3.5.9.6.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> also supports another type
+ of escape syntax for strings that allows specifying arbitrary
+ Unicode characters by code point. A Unicode escape string
+ constant starts with <code class="literal">U&amp;</code> (upper or lower case
+ letter U followed by ampersand) immediately before the opening
+ quote, without any spaces in between, for
+ example <code class="literal">U&amp;'foo'</code>. (Note that this creates an
+ ambiguity with the operator <code class="literal">&amp;</code>. Use spaces
+ around the operator to avoid this problem.) Inside the quotes,
+ Unicode characters can be specified in escaped form by writing a
+ backslash followed by the four-digit hexadecimal code point
+ number or alternatively a backslash followed by a plus sign
+ followed by a six-digit hexadecimal code point number. For
+ example, the string <code class="literal">'data'</code> could be written as
+</p><pre class="programlisting">
+U&amp;'d\0061t\+000061'
+</pre><p>
+ The following less trivial example writes the Russian
+ word <span class="quote">“<span class="quote">slon</span>”</span> (elephant) in Cyrillic letters:
+</p><pre class="programlisting">
+U&amp;'\0441\043B\043E\043D'
+</pre><p>
+ </p><p>
+ If a different escape character than backslash is desired, it can
+ be specified using
+ the <code class="literal">UESCAPE</code><a id="id-1.5.3.5.9.6.4.2" class="indexterm"></a>
+ clause after the string, for example:
+</p><pre class="programlisting">
+U&amp;'d!0061t!+000061' UESCAPE '!'
+</pre><p>
+ The escape character can be any single character other than a
+ hexadecimal digit, the plus sign, a single quote, a double quote,
+ or a whitespace character.
+ </p><p>
+ To include the escape character in the string literally, write
+ it twice.
+ </p><p>
+ Either the 4-digit or the 6-digit escape form can be used to
+ specify UTF-16 surrogate pairs to compose characters with code
+ points larger than U+FFFF, although the availability of the
+ 6-digit form technically makes this unnecessary. (Surrogate
+ pairs are not stored directly, but are combined into a single
+ code point.)
+ </p><p>
+ If the server encoding is not UTF-8, the Unicode code point identified
+ by one of these escape sequences is converted to the actual server
+ encoding; an error is reported if that's not possible.
+ </p><p>
+ Also, the Unicode escape syntax for string constants only works
+ when the configuration
+ parameter <a class="xref" href="runtime-config-compatible.html#GUC-STANDARD-CONFORMING-STRINGS">standard_conforming_strings</a> is
+ turned on. This is because otherwise this syntax could confuse
+ clients that parse the SQL statements to the point that it could
+ lead to SQL injections and similar security issues. If the
+ parameter is set to off, this syntax will be rejected with an
+ error message.
+ </p></div><div class="sect3" id="SQL-SYNTAX-DOLLAR-QUOTING"><div class="titlepage"><div><div><h4 class="title">4.1.2.4. Dollar-Quoted String Constants</h4></div></div></div><a id="id-1.5.3.5.9.7.2" class="indexterm"></a><p>
+ While the standard syntax for specifying string constants is usually
+ convenient, it can be difficult to understand when the desired string
+ contains many single quotes or backslashes, since each of those must
+ be doubled. To allow more readable queries in such situations,
+ <span class="productname">PostgreSQL</span> provides another way, called
+ <span class="quote">“<span class="quote">dollar quoting</span>”</span>, to write string constants.
+ A dollar-quoted string constant
+ consists of a dollar sign (<code class="literal">$</code>), an optional
+ <span class="quote">“<span class="quote">tag</span>”</span> of zero or more characters, another dollar
+ sign, an arbitrary sequence of characters that makes up the
+ string content, a dollar sign, the same tag that began this
+ dollar quote, and a dollar sign. For example, here are two
+ different ways to specify the string <span class="quote">“<span class="quote">Dianne's horse</span>”</span>
+ using dollar quoting:
+</p><pre class="programlisting">
+$$Dianne's horse$$
+$SomeTag$Dianne's horse$SomeTag$
+</pre><p>
+ Notice that inside the dollar-quoted string, single quotes can be
+ used without needing to be escaped. Indeed, no characters inside
+ a dollar-quoted string are ever escaped: the string content is always
+ written literally. Backslashes are not special, and neither are
+ dollar signs, unless they are part of a sequence matching the opening
+ tag.
+ </p><p>
+ It is possible to nest dollar-quoted string constants by choosing
+ different tags at each nesting level. This is most commonly used in
+ writing function definitions. For example:
+</p><pre class="programlisting">
+$function$
+BEGIN
+ RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
+END;
+$function$
+</pre><p>
+ Here, the sequence <code class="literal">$q$[\t\r\n\v\\]$q$</code> represents a
+ dollar-quoted literal string <code class="literal">[\t\r\n\v\\]</code>, which will
+ be recognized when the function body is executed by
+ <span class="productname">PostgreSQL</span>. But since the sequence does not match
+ the outer dollar quoting delimiter <code class="literal">$function$</code>, it is
+ just some more characters within the constant so far as the outer
+ string is concerned.
+ </p><p>
+ The tag, if any, of a dollar-quoted string follows the same rules
+ as an unquoted identifier, except that it cannot contain a dollar sign.
+ Tags are case sensitive, so <code class="literal">$tag$String content$tag$</code>
+ is correct, but <code class="literal">$TAG$String content$tag$</code> is not.
+ </p><p>
+ A dollar-quoted string that follows a keyword or identifier must
+ be separated from it by whitespace; otherwise the dollar quoting
+ delimiter would be taken as part of the preceding identifier.
+ </p><p>
+ Dollar quoting is not part of the SQL standard, but it is often a more
+ convenient way to write complicated string literals than the
+ standard-compliant single quote syntax. It is particularly useful when
+ representing string constants inside other constants, as is often needed
+ in procedural function definitions. With single-quote syntax, each
+ backslash in the above example would have to be written as four
+ backslashes, which would be reduced to two backslashes in parsing the
+ original string constant, and then to one when the inner string constant
+ is re-parsed during function execution.
+ </p></div><div class="sect3" id="SQL-SYNTAX-BIT-STRINGS"><div class="titlepage"><div><div><h4 class="title">4.1.2.5. Bit-String Constants</h4></div></div></div><a id="id-1.5.3.5.9.8.2" class="indexterm"></a><p>
+ Bit-string constants look like regular string constants with a
+ <code class="literal">B</code> (upper or lower case) immediately before the
+ opening quote (no intervening whitespace), e.g.,
+ <code class="literal">B'1001'</code>. The only characters allowed within
+ bit-string constants are <code class="literal">0</code> and
+ <code class="literal">1</code>.
+ </p><p>
+ Alternatively, bit-string constants can be specified in hexadecimal
+ notation, using a leading <code class="literal">X</code> (upper or lower case),
+ e.g., <code class="literal">X'1FF'</code>. This notation is equivalent to
+ a bit-string constant with four binary digits for each hexadecimal digit.
+ </p><p>
+ Both forms of bit-string constant can be continued
+ across lines in the same way as regular string constants.
+ Dollar quoting cannot be used in a bit-string constant.
+ </p></div><div class="sect3" id="SQL-SYNTAX-CONSTANTS-NUMERIC"><div class="titlepage"><div><div><h4 class="title">4.1.2.6. Numeric Constants</h4></div></div></div><a id="id-1.5.3.5.9.9.2" class="indexterm"></a><p>
+ Numeric constants are accepted in these general forms:
+</p><pre class="synopsis">
+<em class="replaceable"><code>digits</code></em>
+<em class="replaceable"><code>digits</code></em>.[<span class="optional"><em class="replaceable"><code>digits</code></em></span>][<span class="optional">e[<span class="optional">+-</span>]<em class="replaceable"><code>digits</code></em></span>]
+[<span class="optional"><em class="replaceable"><code>digits</code></em></span>].<em class="replaceable"><code>digits</code></em>[<span class="optional">e[<span class="optional">+-</span>]<em class="replaceable"><code>digits</code></em></span>]
+<em class="replaceable"><code>digits</code></em>e[<span class="optional">+-</span>]<em class="replaceable"><code>digits</code></em>
+</pre><p>
+ where <em class="replaceable"><code>digits</code></em> is one or more decimal
+ digits (0 through 9). At least one digit must be before or after the
+ decimal point, if one is used. At least one digit must follow the
+ exponent marker (<code class="literal">e</code>), if one is present.
+ There cannot be any spaces or other characters embedded in the
+ constant. Note that any leading plus or minus sign is not actually
+ considered part of the constant; it is an operator applied to the
+ constant.
+ </p><p>
+ These are some examples of valid numeric constants:
+</p><div class="literallayout"><p><br />
+42<br />
+3.5<br />
+4.<br />
+.001<br />
+5e2<br />
+1.925e-3<br />
+</p></div><p>
+ </p><p>
+ <a id="id-1.5.3.5.9.9.5.1" class="indexterm"></a>
+ <a id="id-1.5.3.5.9.9.5.2" class="indexterm"></a>
+ <a id="id-1.5.3.5.9.9.5.3" class="indexterm"></a>
+ A numeric constant that contains neither a decimal point nor an
+ exponent is initially presumed to be type <code class="type">integer</code> if its
+ value fits in type <code class="type">integer</code> (32 bits); otherwise it is
+ presumed to be type <code class="type">bigint</code> if its
+ value fits in type <code class="type">bigint</code> (64 bits); otherwise it is
+ taken to be type <code class="type">numeric</code>. Constants that contain decimal
+ points and/or exponents are always initially presumed to be type
+ <code class="type">numeric</code>.
+ </p><p>
+ The initially assigned data type of a numeric constant is just a
+ starting point for the type resolution algorithms. In most cases
+ the constant will be automatically coerced to the most
+ appropriate type depending on context. When necessary, you can
+ force a numeric value to be interpreted as a specific data type
+ by casting it.<a id="id-1.5.3.5.9.9.6.1" class="indexterm"></a>
+ For example, you can force a numeric value to be treated as type
+ <code class="type">real</code> (<code class="type">float4</code>) by writing:
+
+</p><pre class="programlisting">
+REAL '1.23' -- string style
+1.23::REAL -- PostgreSQL (historical) style
+</pre><p>
+
+ These are actually just special cases of the general casting
+ notations discussed next.
+ </p></div><div class="sect3" id="SQL-SYNTAX-CONSTANTS-GENERIC"><div class="titlepage"><div><div><h4 class="title">4.1.2.7. Constants of Other Types</h4></div></div></div><a id="id-1.5.3.5.9.10.2" class="indexterm"></a><p>
+ A constant of an <span class="emphasis"><em>arbitrary</em></span> type can be
+ entered using any one of the following notations:
+</p><pre class="synopsis">
+<em class="replaceable"><code>type</code></em> '<em class="replaceable"><code>string</code></em>'
+'<em class="replaceable"><code>string</code></em>'::<em class="replaceable"><code>type</code></em>
+CAST ( '<em class="replaceable"><code>string</code></em>' AS <em class="replaceable"><code>type</code></em> )
+</pre><p>
+ The string constant's text is passed to the input conversion
+ routine for the type called <em class="replaceable"><code>type</code></em>. The
+ result is a constant of the indicated type. The explicit type
+ cast can be omitted if there is no ambiguity as to the type the
+ constant must be (for example, when it is assigned directly to a
+ table column), in which case it is automatically coerced.
+ </p><p>
+ The string constant can be written using either regular SQL
+ notation or dollar-quoting.
+ </p><p>
+ It is also possible to specify a type coercion using a function-like
+ syntax:
+</p><pre class="synopsis">
+<em class="replaceable"><code>typename</code></em> ( '<em class="replaceable"><code>string</code></em>' )
+</pre><p>
+ but not all type names can be used in this way; see <a class="xref" href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS" title="4.2.9. Type Casts">Section 4.2.9</a> for details.
+ </p><p>
+ The <code class="literal">::</code>, <code class="literal">CAST()</code>, and
+ function-call syntaxes can also be used to specify run-time type
+ conversions of arbitrary expressions, as discussed in <a class="xref" href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS" title="4.2.9. Type Casts">Section 4.2.9</a>. To avoid syntactic ambiguity, the
+ <code class="literal"><em class="replaceable"><code>type</code></em> '<em class="replaceable"><code>string</code></em>'</code>
+ syntax can only be used to specify the type of a simple literal constant.
+ Another restriction on the
+ <code class="literal"><em class="replaceable"><code>type</code></em> '<em class="replaceable"><code>string</code></em>'</code>
+ syntax is that it does not work for array types; use <code class="literal">::</code>
+ or <code class="literal">CAST()</code> to specify the type of an array constant.
+ </p><p>
+ The <code class="literal">CAST()</code> syntax conforms to SQL. The
+ <code class="literal"><em class="replaceable"><code>type</code></em> '<em class="replaceable"><code>string</code></em>'</code>
+ syntax is a generalization of the standard: SQL specifies this syntax only
+ for a few data types, but <span class="productname">PostgreSQL</span> allows it
+ for all types. The syntax with
+ <code class="literal">::</code> is historical <span class="productname">PostgreSQL</span>
+ usage, as is the function-call syntax.
+ </p></div></div><div class="sect2" id="SQL-SYNTAX-OPERATORS"><div class="titlepage"><div><div><h3 class="title">4.1.3. Operators</h3></div></div></div><a id="id-1.5.3.5.10.2" class="indexterm"></a><p>
+ An operator name is a sequence of up to <code class="symbol">NAMEDATALEN</code>-1
+ (63 by default) characters from the following list:
+</p><div class="literallayout"><p><br />
++ - * / &lt; &gt; = ~ ! @ # % ^ &amp; | ` ?<br />
+</p></div><p>
+
+ There are a few restrictions on operator names, however:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">--</code> and <code class="literal">/*</code> cannot appear
+ anywhere in an operator name, since they will be taken as the
+ start of a comment.
+ </p></li><li class="listitem"><p>
+ A multiple-character operator name cannot end in <code class="literal">+</code> or <code class="literal">-</code>,
+ unless the name also contains at least one of these characters:
+</p><div class="literallayout"><p><br />
+~ ! @ # % ^ &amp; | ` ?<br />
+</p></div><p>
+ For example, <code class="literal">@-</code> is an allowed operator name,
+ but <code class="literal">*-</code> is not. This restriction allows
+ <span class="productname">PostgreSQL</span> to parse SQL-compliant
+ queries without requiring spaces between tokens.
+ </p></li></ul></div><p>
+ </p><p>
+ When working with non-SQL-standard operator names, you will usually
+ need to separate adjacent operators with spaces to avoid ambiguity.
+ For example, if you have defined a prefix operator named <code class="literal">@</code>,
+ you cannot write <code class="literal">X*@Y</code>; you must write
+ <code class="literal">X* @Y</code> to ensure that
+ <span class="productname">PostgreSQL</span> reads it as two operator names
+ not one.
+ </p></div><div class="sect2" id="SQL-SYNTAX-SPECIAL-CHARS"><div class="titlepage"><div><div><h3 class="title">4.1.4. Special Characters</h3></div></div></div><p>
+ Some characters that are not alphanumeric have a special meaning
+ that is different from being an operator. Details on the usage can
+ be found at the location where the respective syntax element is
+ described. This section only exists to advise the existence and
+ summarize the purposes of these characters.
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A dollar sign (<code class="literal">$</code>) followed by digits is used
+ to represent a positional parameter in the body of a function
+ definition or a prepared statement. In other contexts the
+ dollar sign can be part of an identifier or a dollar-quoted string
+ constant.
+ </p></li><li class="listitem"><p>
+ Parentheses (<code class="literal">()</code>) have their usual meaning to
+ group expressions and enforce precedence. In some cases
+ parentheses are required as part of the fixed syntax of a
+ particular SQL command.
+ </p></li><li class="listitem"><p>
+ Brackets (<code class="literal">[]</code>) are used to select the elements
+ of an array. See <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a> for more information
+ on arrays.
+ </p></li><li class="listitem"><p>
+ Commas (<code class="literal">,</code>) are used in some syntactical
+ constructs to separate the elements of a list.
+ </p></li><li class="listitem"><p>
+ The semicolon (<code class="literal">;</code>) terminates an SQL command.
+ It cannot appear anywhere within a command, except within a
+ string constant or quoted identifier.
+ </p></li><li class="listitem"><p>
+ The colon (<code class="literal">:</code>) is used to select
+ <span class="quote">“<span class="quote">slices</span>”</span> from arrays. (See <a class="xref" href="arrays.html" title="8.15. Arrays">Section 8.15</a>.) In certain SQL dialects (such as Embedded
+ SQL), the colon is used to prefix variable names.
+ </p></li><li class="listitem"><p>
+ The asterisk (<code class="literal">*</code>) is used in some contexts to denote
+ all the fields of a table row or composite value. It also
+ has a special meaning when used as the argument of an
+ aggregate function, namely that the aggregate does not require
+ any explicit parameter.
+ </p></li><li class="listitem"><p>
+ The period (<code class="literal">.</code>) is used in numeric
+ constants, and to separate schema, table, and column names.
+ </p></li></ul></div><p>
+
+ </p></div><div class="sect2" id="SQL-SYNTAX-COMMENTS"><div class="titlepage"><div><div><h3 class="title">4.1.5. Comments</h3></div></div></div><a id="id-1.5.3.5.12.2" class="indexterm"></a><p>
+ A comment is a sequence of characters beginning with
+ double dashes and extending to the end of the line, e.g.:
+</p><pre class="programlisting">
+-- This is a standard SQL comment
+</pre><p>
+ </p><p>
+ Alternatively, C-style block comments can be used:
+</p><pre class="programlisting">
+/* multiline comment
+ * with nesting: /* nested block comment */
+ */
+</pre><p>
+ where the comment begins with <code class="literal">/*</code> and extends to
+ the matching occurrence of <code class="literal">*/</code>. These block
+ comments nest, as specified in the SQL standard but unlike C, so that one can
+ comment out larger blocks of code that might contain existing block
+ comments.
+ </p><p>
+ A comment is removed from the input stream before further syntax
+ analysis and is effectively replaced by whitespace.
+ </p></div><div class="sect2" id="SQL-PRECEDENCE"><div class="titlepage"><div><div><h3 class="title">4.1.6. Operator Precedence</h3></div></div></div><a id="id-1.5.3.5.13.2" class="indexterm"></a><p>
+ <a class="xref" href="sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE" title="Table 4.2. Operator Precedence (highest to lowest)">Table 4.2</a> shows the precedence and
+ associativity of the operators in <span class="productname">PostgreSQL</span>.
+ Most operators have the same precedence and are left-associative.
+ The precedence and associativity of the operators is hard-wired
+ into the parser.
+ Add parentheses if you want an expression with multiple operators
+ to be parsed in some other way than what the precedence rules imply.
+ </p><div class="table" id="SQL-PRECEDENCE-TABLE"><p class="title"><strong>Table 4.2. Operator Precedence (highest to lowest)</strong></p><div class="table-contents"><table class="table" summary="Operator Precedence (highest to lowest)" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Operator/Element</th><th>Associativity</th><th>Description</th></tr></thead><tbody><tr><td><code class="token">.</code></td><td>left</td><td>table/column name separator</td></tr><tr><td><code class="token">::</code></td><td>left</td><td><span class="productname">PostgreSQL</span>-style typecast</td></tr><tr><td><code class="token">[</code> <code class="token">]</code></td><td>left</td><td>array element selection</td></tr><tr><td><code class="token">+</code> <code class="token">-</code></td><td>right</td><td>unary plus, unary minus</td></tr><tr><td><code class="token">^</code></td><td>left</td><td>exponentiation</td></tr><tr><td><code class="token">*</code> <code class="token">/</code> <code class="token">%</code></td><td>left</td><td>multiplication, division, modulo</td></tr><tr><td><code class="token">+</code> <code class="token">-</code></td><td>left</td><td>addition, subtraction</td></tr><tr><td>(any other operator)</td><td>left</td><td>all other native and user-defined operators</td></tr><tr><td><code class="token">BETWEEN</code> <code class="token">IN</code> <code class="token">LIKE</code> <code class="token">ILIKE</code> <code class="token">SIMILAR</code></td><td> </td><td>range containment, set membership, string matching</td></tr><tr><td><code class="token">&lt;</code> <code class="token">&gt;</code> <code class="token">=</code> <code class="token">&lt;=</code> <code class="token">&gt;=</code> <code class="token">&lt;&gt;</code>
+</td><td> </td><td>comparison operators</td></tr><tr><td><code class="token">IS</code> <code class="token">ISNULL</code> <code class="token">NOTNULL</code></td><td> </td><td><code class="literal">IS TRUE</code>, <code class="literal">IS FALSE</code>, <code class="literal">IS
+ NULL</code>, <code class="literal">IS DISTINCT FROM</code>, etc.</td></tr><tr><td><code class="token">NOT</code></td><td>right</td><td>logical negation</td></tr><tr><td><code class="token">AND</code></td><td>left</td><td>logical conjunction</td></tr><tr><td><code class="token">OR</code></td><td>left</td><td>logical disjunction</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Note that the operator precedence rules also apply to user-defined
+ operators that have the same names as the built-in operators
+ mentioned above. For example, if you define a
+ <span class="quote">“<span class="quote">+</span>”</span> operator for some custom data type it will have
+ the same precedence as the built-in <span class="quote">“<span class="quote">+</span>”</span> operator, no
+ matter what yours does.
+ </p><p>
+ When a schema-qualified operator name is used in the
+ <code class="literal">OPERATOR</code> syntax, as for example in:
+</p><pre class="programlisting">
+SELECT 3 OPERATOR(pg_catalog.+) 4;
+</pre><p>
+ the <code class="literal">OPERATOR</code> construct is taken to have the default precedence
+ shown in <a class="xref" href="sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE" title="Table 4.2. Operator Precedence (highest to lowest)">Table 4.2</a> for
+ <span class="quote">“<span class="quote">any other operator</span>”</span>. This is true no matter
+ which specific operator appears inside <code class="literal">OPERATOR()</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> versions before 9.5 used slightly different
+ operator precedence rules. In particular, <code class="token">&lt;=</code>
+ <code class="token">&gt;=</code> and <code class="token">&lt;&gt;</code> used to be treated as
+ generic operators; <code class="literal">IS</code> tests used to have higher priority;
+ and <code class="literal">NOT BETWEEN</code> and related constructs acted inconsistently,
+ being taken in some cases as having the precedence of <code class="literal">NOT</code>
+ rather than <code class="literal">BETWEEN</code>. These rules were changed for better
+ compliance with the SQL standard and to reduce confusion from
+ inconsistent treatment of logically equivalent constructs. In most
+ cases, these changes will result in no behavioral change, or perhaps
+ in <span class="quote">“<span class="quote">no such operator</span>”</span> failures which can be resolved by adding
+ parentheses. However there are corner cases in which a query might
+ change behavior without any parsing error being reported.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-expressions.html" title="4.2. Value Expressions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 4. SQL Syntax </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 4.2. Value Expressions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-syntax.html b/doc/src/sgml/html/sql-syntax.html
new file mode 100644
index 0000000..2034dd6
--- /dev/null
+++ b/doc/src/sgml/html/sql-syntax.html
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 4. SQL Syntax</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql.html" title="Part II. The SQL Language" /><link rel="next" href="sql-syntax-lexical.html" title="4.1. Lexical Structure" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 4. SQL Syntax</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql.html" title="Part II. The SQL Language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-syntax-lexical.html" title="4.1. Lexical Structure">Next</a></td></tr></table><hr /></div><div class="chapter" id="SQL-SYNTAX"><div class="titlepage"><div><div><h2 class="title">Chapter 4. SQL Syntax</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="sql-syntax-lexical.html">4.1. Lexical Structure</a></span></dt><dd><dl><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS">4.1.1. Identifiers and Key Words</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS">4.1.2. Constants</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS">4.1.3. Operators</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-SPECIAL-CHARS">4.1.4. Special Characters</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-SYNTAX-COMMENTS">4.1.5. Comments</a></span></dt><dt><span class="sect2"><a href="sql-syntax-lexical.html#SQL-PRECEDENCE">4.1.6. Operator Precedence</a></span></dt></dl></dd><dt><span class="sect1"><a href="sql-expressions.html">4.2. Value Expressions</a></span></dt><dd><dl><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-COLUMN-REFS">4.2.1. Column References</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-PARAMETERS-POSITIONAL">4.2.2. Positional Parameters</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-SUBSCRIPTS">4.2.3. Subscripts</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#FIELD-SELECTION">4.2.4. Field Selection</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS">4.2.5. Operator Invocations</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-EXPRESSIONS-FUNCTION-CALLS">4.2.6. Function Calls</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SYNTAX-AGGREGATES">4.2.7. Aggregate Expressions</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS">4.2.8. Window Function Calls</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-TYPE-CASTS">4.2.9. Type Casts</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS">4.2.10. Collation Expressions</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-SCALAR-SUBQUERIES">4.2.11. Scalar Subqueries</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS">4.2.12. Array Constructors</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS">4.2.13. Row Constructors</a></span></dt><dt><span class="sect2"><a href="sql-expressions.html#SYNTAX-EXPRESS-EVAL">4.2.14. Expression Evaluation Rules</a></span></dt></dl></dd><dt><span class="sect1"><a href="sql-syntax-calling-funcs.html">4.3. Calling Functions</a></span></dt><dd><dl><dt><span class="sect2"><a href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-POSITIONAL">4.3.1. Using Positional Notation</a></span></dt><dt><span class="sect2"><a href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-NAMED">4.3.2. Using Named Notation</a></span></dt><dt><span class="sect2"><a href="sql-syntax-calling-funcs.html#SQL-SYNTAX-CALLING-FUNCS-MIXED">4.3.3. Using Mixed Notation</a></span></dt></dl></dd></dl></div><a id="id-1.5.3.2" class="indexterm"></a><p>
+ This chapter describes the syntax of SQL. It forms the foundation
+ for understanding the following chapters which will go into detail
+ about how SQL commands are applied to define and modify data.
+ </p><p>
+ We also advise users who are already familiar with SQL to read this
+ chapter carefully because it contains several rules and concepts that
+ are implemented inconsistently among SQL databases or that are
+ specific to <span class="productname">PostgreSQL</span>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql.html" title="Part II. The SQL Language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-syntax-lexical.html" title="4.1. Lexical Structure">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part II. The SQL Language </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 4.1. Lexical Structure</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-truncate.html b/doc/src/sgml/html/sql-truncate.html
new file mode 100644
index 0000000..55846ff
--- /dev/null
+++ b/doc/src/sgml/html/sql-truncate.html
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>TRUNCATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-start-transaction.html" title="START TRANSACTION" /><link rel="next" href="sql-unlisten.html" title="UNLISTEN" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">TRUNCATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-start-transaction.html" title="START TRANSACTION">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-unlisten.html" title="UNLISTEN">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-TRUNCATE"><div class="titlepage"></div><a id="id-1.9.3.181.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">TRUNCATE</span></h2><p>TRUNCATE — empty a table or set of tables</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+TRUNCATE [ TABLE ] [ ONLY ] <em class="replaceable"><code>name</code></em> [ * ] [, ... ]
+ [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
+</pre></div><div class="refsect1" id="id-1.9.3.181.5"><h2>Description</h2><p>
+ <code class="command">TRUNCATE</code> quickly removes all rows from a set of
+ tables. It has the same effect as an unqualified
+ <code class="command">DELETE</code> on each table, but since it does not actually
+ scan the tables it is faster. Furthermore, it reclaims disk space
+ immediately, rather than requiring a subsequent <code class="command">VACUUM</code>
+ operation. This is most useful on large tables.
+ </p></div><div class="refsect1" id="id-1.9.3.181.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a table to truncate.
+ If <code class="literal">ONLY</code> is specified before the table name, only that table
+ is truncated. If <code class="literal">ONLY</code> is not specified, the table and all
+ its descendant tables (if any) are truncated. Optionally, <code class="literal">*</code>
+ can be specified after the table name to explicitly indicate that
+ descendant tables are included.
+ </p></dd><dt><span class="term"><code class="literal">RESTART IDENTITY</code></span></dt><dd><p>
+ Automatically restart sequences owned by columns of
+ the truncated table(s).
+ </p></dd><dt><span class="term"><code class="literal">CONTINUE IDENTITY</code></span></dt><dd><p>
+ Do not change the values of sequences. This is the default.
+ </p></dd><dt><span class="term"><code class="literal">CASCADE</code></span></dt><dd><p>
+ Automatically truncate all tables that have foreign-key references
+ to any of the named tables, or to any tables added to the group
+ due to <code class="literal">CASCADE</code>.
+ </p></dd><dt><span class="term"><code class="literal">RESTRICT</code></span></dt><dd><p>
+ Refuse to truncate if any of the tables have foreign-key references
+ from tables that are not listed in the command. This is the default.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.181.7"><h2>Notes</h2><p>
+ You must have the <code class="literal">TRUNCATE</code> privilege on a table
+ to truncate it.
+ </p><p>
+ <code class="command">TRUNCATE</code> acquires an <code class="literal">ACCESS EXCLUSIVE</code> lock on each
+ table it operates on, which blocks all other concurrent operations
+ on the table. When <code class="literal">RESTART IDENTITY</code> is specified, any
+ sequences that are to be restarted are likewise locked exclusively.
+ If concurrent access to a table is required, then
+ the <code class="command">DELETE</code> command should be used instead.
+ </p><p>
+ <code class="command">TRUNCATE</code> cannot be used on a table that has foreign-key
+ references from other tables, unless all such tables are also truncated
+ in the same command. Checking validity in such cases would require table
+ scans, and the whole point is not to do one. The <code class="literal">CASCADE</code>
+ option can be used to automatically include all dependent tables —
+ but be very careful when using this option, or else you might lose data you
+ did not intend to!
+ Note in particular that when the table to be truncated is a partition,
+ siblings partitions are left untouched, but cascading occurs to all
+ referencing tables and all their partitions with no distinction.
+ </p><p>
+ <code class="command">TRUNCATE</code> will not fire any <code class="literal">ON DELETE</code>
+ triggers that might exist for the tables. But it will fire
+ <code class="literal">ON TRUNCATE</code> triggers.
+ If <code class="literal">ON TRUNCATE</code> triggers are defined for any of
+ the tables, then all <code class="literal">BEFORE TRUNCATE</code> triggers are
+ fired before any truncation happens, and all <code class="literal">AFTER
+ TRUNCATE</code> triggers are fired after the last truncation is
+ performed and any sequences are reset.
+ The triggers will fire in the order that the tables are
+ to be processed (first those listed in the command, and then any
+ that were added due to cascading).
+ </p><p>
+ <code class="command">TRUNCATE</code> is not MVCC-safe. After truncation, the table will
+ appear empty to concurrent transactions, if they are using a snapshot
+ taken before the truncation occurred.
+ See <a class="xref" href="mvcc-caveats.html" title="13.6. Caveats">Section 13.6</a> for more details.
+ </p><p>
+ <code class="command">TRUNCATE</code> is transaction-safe with respect to the data
+ in the tables: the truncation will be safely rolled back if the surrounding
+ transaction does not commit.
+ </p><p>
+ When <code class="literal">RESTART IDENTITY</code> is specified, the implied
+ <code class="command">ALTER SEQUENCE RESTART</code> operations are also done
+ transactionally; that is, they will be rolled back if the surrounding
+ transaction does not commit. Be aware that if any additional
+ sequence operations are done on the restarted sequences before the
+ transaction rolls back, the effects of these operations on the sequences
+ will be rolled back, but not their effects on <code class="function">currval()</code>;
+ that is, after the transaction <code class="function">currval()</code> will continue to
+ reflect the last sequence value obtained inside the failed transaction,
+ even though the sequence itself may no longer be consistent with that.
+ This is similar to the usual behavior of <code class="function">currval()</code> after
+ a failed transaction.
+ </p><p>
+ <code class="command">TRUNCATE</code> can be used for foreign tables if
+ supported by the foreign data wrapper, for instance,
+ see <a class="xref" href="postgres-fdw.html" title="F.38. postgres_fdw">postgres_fdw</a>.
+ </p></div><div class="refsect1" id="id-1.9.3.181.8"><h2>Examples</h2><p>
+ Truncate the tables <code class="literal">bigtable</code> and
+ <code class="literal">fattable</code>:
+
+</p><pre class="programlisting">
+TRUNCATE bigtable, fattable;
+</pre><p>
+ </p><p>
+ The same, and also reset any associated sequence generators:
+
+</p><pre class="programlisting">
+TRUNCATE bigtable, fattable RESTART IDENTITY;
+</pre><p>
+ </p><p>
+ Truncate the table <code class="literal">othertable</code>, and cascade to any tables
+ that reference <code class="literal">othertable</code> via foreign-key
+ constraints:
+
+</p><pre class="programlisting">
+TRUNCATE othertable CASCADE;
+</pre></div><div class="refsect1" id="id-1.9.3.181.9"><h2>Compatibility</h2><p>
+ The SQL:2008 standard includes a <code class="command">TRUNCATE</code> command
+ with the syntax <code class="literal">TRUNCATE TABLE
+ <em class="replaceable"><code>tablename</code></em></code>. The clauses
+ <code class="literal">CONTINUE IDENTITY</code>/<code class="literal">RESTART IDENTITY</code>
+ also appear in that standard, but have slightly different though related
+ meanings. Some of the concurrency behavior of this command is left
+ implementation-defined by the standard, so the above notes should be
+ considered and compared with other implementations if necessary.
+ </p></div><div class="refsect1" id="id-1.9.3.181.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-delete.html" title="DELETE"><span class="refentrytitle">DELETE</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-start-transaction.html" title="START TRANSACTION">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-unlisten.html" title="UNLISTEN">Next</a></td></tr><tr><td width="40%" align="left" valign="top">START TRANSACTION </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> UNLISTEN</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-unlisten.html b/doc/src/sgml/html/sql-unlisten.html
new file mode 100644
index 0000000..801020d
--- /dev/null
+++ b/doc/src/sgml/html/sql-unlisten.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>UNLISTEN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-truncate.html" title="TRUNCATE" /><link rel="next" href="sql-update.html" title="UPDATE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">UNLISTEN</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-truncate.html" title="TRUNCATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-update.html" title="UPDATE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-UNLISTEN"><div class="titlepage"></div><a id="id-1.9.3.182.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">UNLISTEN</span></h2><p>UNLISTEN — stop listening for a notification</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+UNLISTEN { <em class="replaceable"><code>channel</code></em> | * }
+</pre></div><div class="refsect1" id="id-1.9.3.182.5"><h2>Description</h2><p>
+ <code class="command">UNLISTEN</code> is used to remove an existing
+ registration for <code class="command">NOTIFY</code> events.
+ <code class="command">UNLISTEN</code> cancels any existing registration of
+ the current <span class="productname">PostgreSQL</span> session as a
+ listener on the notification channel named <em class="replaceable"><code>channel</code></em>. The special wildcard
+ <code class="literal">*</code> cancels all listener registrations for the
+ current session.
+ </p><p>
+ <a class="xref" href="sql-notify.html" title="NOTIFY"><span class="refentrytitle">NOTIFY</span></a>
+ contains a more extensive
+ discussion of the use of <code class="command">LISTEN</code> and
+ <code class="command">NOTIFY</code>.
+ </p></div><div class="refsect1" id="id-1.9.3.182.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>channel</code></em></span></dt><dd><p>
+ Name of a notification channel (any identifier).
+ </p></dd><dt><span class="term"><code class="literal">*</code></span></dt><dd><p>
+ All current listen registrations for this session are cleared.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.182.7"><h2>Notes</h2><p>
+ You can unlisten something you were not listening for; no warning or error
+ will appear.
+ </p><p>
+ At the end of each session, <code class="command">UNLISTEN *</code> is
+ automatically executed.
+ </p><p>
+ A transaction that has executed <code class="command">UNLISTEN</code> cannot be
+ prepared for two-phase commit.
+ </p></div><div class="refsect1" id="id-1.9.3.182.8"><h2>Examples</h2><p>
+ To make a registration:
+
+</p><pre class="programlisting">
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448.
+</pre><p>
+ </p><p>
+ Once <code class="command">UNLISTEN</code> has been executed, further <code class="command">NOTIFY</code>
+ messages will be ignored:
+
+</p><pre class="programlisting">
+UNLISTEN virtual;
+NOTIFY virtual;
+-- no NOTIFY event is received
+</pre></div><div class="refsect1" id="id-1.9.3.182.9"><h2>Compatibility</h2><p>
+ There is no <code class="command">UNLISTEN</code> command in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.182.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-listen.html" title="LISTEN"><span class="refentrytitle">LISTEN</span></a>, <a class="xref" href="sql-notify.html" title="NOTIFY"><span class="refentrytitle">NOTIFY</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-truncate.html" title="TRUNCATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-update.html" title="UPDATE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">TRUNCATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> UPDATE</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-update.html b/doc/src/sgml/html/sql-update.html
new file mode 100644
index 0000000..a980363
--- /dev/null
+++ b/doc/src/sgml/html/sql-update.html
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>UPDATE</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-unlisten.html" title="UNLISTEN" /><link rel="next" href="sql-vacuum.html" title="VACUUM" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">UPDATE</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-unlisten.html" title="UNLISTEN">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-vacuum.html" title="VACUUM">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-UPDATE"><div class="titlepage"></div><a id="id-1.9.3.183.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">UPDATE</span></h2><p>UPDATE — update rows of a table</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+[ WITH [ RECURSIVE ] <em class="replaceable"><code>with_query</code></em> [, ...] ]
+UPDATE [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ * ] [ [ AS ] <em class="replaceable"><code>alias</code></em> ]
+ SET { <em class="replaceable"><code>column_name</code></em> = { <em class="replaceable"><code>expression</code></em> | DEFAULT } |
+ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) = [ ROW ] ( { <em class="replaceable"><code>expression</code></em> | DEFAULT } [, ...] ) |
+ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) = ( <em class="replaceable"><code>sub-SELECT</code></em> )
+ } [, ...]
+ [ FROM <em class="replaceable"><code>from_item</code></em> [, ...] ]
+ [ WHERE <em class="replaceable"><code>condition</code></em> | WHERE CURRENT OF <em class="replaceable"><code>cursor_name</code></em> ]
+ [ RETURNING * | <em class="replaceable"><code>output_expression</code></em> [ [ AS ] <em class="replaceable"><code>output_name</code></em> ] [, ...] ]
+</pre></div><div class="refsect1" id="id-1.9.3.183.5"><h2>Description</h2><p>
+ <code class="command">UPDATE</code> changes the values of the specified
+ columns in all rows that satisfy the condition. Only the columns to
+ be modified need be mentioned in the <code class="literal">SET</code> clause;
+ columns not explicitly modified retain their previous values.
+ </p><p>
+ There are two ways to modify a table using information contained in
+ other tables in the database: using sub-selects, or specifying
+ additional tables in the <code class="literal">FROM</code> clause. Which
+ technique is more appropriate depends on the specific
+ circumstances.
+ </p><p>
+ The optional <code class="literal">RETURNING</code> clause causes <code class="command">UPDATE</code>
+ to compute and return value(s) based on each row actually updated.
+ Any expression using the table's columns, and/or columns of other
+ tables mentioned in <code class="literal">FROM</code>, can be computed.
+ The new (post-update) values of the table's columns are used.
+ The syntax of the <code class="literal">RETURNING</code> list is identical to that of the
+ output list of <code class="command">SELECT</code>.
+ </p><p>
+ You must have the <code class="literal">UPDATE</code> privilege on the table,
+ or at least on the column(s) that are listed to be updated.
+ You must also have the <code class="literal">SELECT</code>
+ privilege on any column whose values are read in the
+ <em class="replaceable"><code>expressions</code></em> or
+ <em class="replaceable"><code>condition</code></em>.
+ </p></div><div class="refsect1" id="id-1.9.3.183.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>with_query</code></em></span></dt><dd><p>
+ The <code class="literal">WITH</code> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <code class="command">UPDATE</code>
+ query. See <a class="xref" href="queries-with.html" title="7.8. WITH Queries (Common Table Expressions)">Section 7.8</a> and <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>
+ for details.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of the table to update.
+ If <code class="literal">ONLY</code> is specified before the table name, matching rows
+ are updated in the named table only. If <code class="literal">ONLY</code> is not
+ specified, matching rows are also updated in any tables inheriting from
+ the named table. Optionally, <code class="literal">*</code> can be specified after the
+ table name to explicitly indicate that descendant tables are included.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>alias</code></em></span></dt><dd><p>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <code class="literal">UPDATE foo AS f</code>, the remainder of the
+ <code class="command">UPDATE</code> statement must refer to this table as
+ <code class="literal">f</code> not <code class="literal">foo</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a column in the table named by <em class="replaceable"><code>table_name</code></em>.
+ The column name can be qualified with a subfield name or array
+ subscript, if needed. Do not include the table's name in the
+ specification of a target column — for example,
+ <code class="literal">UPDATE table_name SET table_name.col = 1</code> is invalid.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
+ An expression to assign to the column. The expression can use the
+ old values of this and other columns in the table.
+ </p></dd><dt><span class="term"><code class="literal">DEFAULT</code></span></dt><dd><p>
+ Set the column to its default value (which will be NULL if no specific
+ default expression has been assigned to it). An identity column will be
+ set to a new value generated by the associated sequence. For a
+ generated column, specifying this is permitted but merely specifies the
+ normal behavior of computing the column from its generation expression.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sub-SELECT</code></em></span></dt><dd><p>
+ A <code class="literal">SELECT</code> sub-query that produces as many output columns
+ as are listed in the parenthesized column list preceding it. The
+ sub-query must yield no more than one row when executed. If it
+ yields one row, its column values are assigned to the target columns;
+ if it yields no rows, NULL values are assigned to the target columns.
+ The sub-query can refer to old values of the current row of the table
+ being updated.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>from_item</code></em></span></dt><dd><p>
+ A table expression allowing columns from other tables to appear in
+ the <code class="literal">WHERE</code> condition and update expressions. This
+ uses the same syntax as the <a class="link" href="sql-select.html#SQL-FROM" title="FROM Clause"><code class="literal">FROM</code></a> clause of
+ a <code class="command">SELECT</code> statement;
+ for example, an alias for the table name can be specified. Do not
+ repeat the target table as a <em class="replaceable"><code>from_item</code></em>
+ unless you intend a self-join (in which case it must appear with
+ an alias in the <em class="replaceable"><code>from_item</code></em>).
+ </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
+ An expression that returns a value of type <code class="type">boolean</code>.
+ Only rows for which this expression returns <code class="literal">true</code>
+ will be updated.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>cursor_name</code></em></span></dt><dd><p>
+ The name of the cursor to use in a <code class="literal">WHERE CURRENT OF</code>
+ condition. The row to be updated is the one most recently fetched
+ from this cursor. The cursor must be a non-grouping
+ query on the <code class="command">UPDATE</code>'s target table.
+ Note that <code class="literal">WHERE CURRENT OF</code> cannot be
+ specified together with a Boolean condition. See
+ <a class="xref" href="sql-declare.html" title="DECLARE"><span class="refentrytitle">DECLARE</span></a>
+ for more information about using cursors with
+ <code class="literal">WHERE CURRENT OF</code>.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_expression</code></em></span></dt><dd><p>
+ An expression to be computed and returned by the <code class="command">UPDATE</code>
+ command after each row is updated. The expression can use any
+ column names of the table named by <em class="replaceable"><code>table_name</code></em>
+ or table(s) listed in <code class="literal">FROM</code>.
+ Write <code class="literal">*</code> to return all columns.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>output_name</code></em></span></dt><dd><p>
+ A name to use for a returned column.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.183.7"><h2>Outputs</h2><p>
+ On successful completion, an <code class="command">UPDATE</code> command returns a command
+ tag of the form
+</p><pre class="screen">
+UPDATE <em class="replaceable"><code>count</code></em>
+</pre><p>
+ The <em class="replaceable"><code>count</code></em> is the number
+ of rows updated, including matched rows whose values did not change.
+ Note that the number may be less than the number of rows that matched
+ the <em class="replaceable"><code>condition</code></em> when
+ updates were suppressed by a <code class="literal">BEFORE UPDATE</code> trigger. If
+ <em class="replaceable"><code>count</code></em> is 0, no rows were
+ updated by the query (this is not considered an error).
+ </p><p>
+ If the <code class="command">UPDATE</code> command contains a <code class="literal">RETURNING</code>
+ clause, the result will be similar to that of a <code class="command">SELECT</code>
+ statement containing the columns and values defined in the
+ <code class="literal">RETURNING</code> list, computed over the row(s) updated by the
+ command.
+ </p></div><div class="refsect1" id="id-1.9.3.183.8"><h2>Notes</h2><p>
+ When a <code class="literal">FROM</code> clause is present, what essentially happens
+ is that the target table is joined to the tables mentioned in the
+ <em class="replaceable"><code>from_item</code></em> list, and each output row of the join
+ represents an update operation for the target table. When using
+ <code class="literal">FROM</code> you should ensure that the join
+ produces at most one output row for each row to be modified. In
+ other words, a target row shouldn't join to more than one row from
+ the other table(s). If it does, then only one of the join rows
+ will be used to update the target row, but which one will be used
+ is not readily predictable.
+ </p><p>
+ Because of this indeterminacy, referencing other tables only within
+ sub-selects is safer, though often harder to read and slower than
+ using a join.
+ </p><p>
+ In the case of a partitioned table, updating a row might cause it to no
+ longer satisfy the partition constraint of the containing partition. In that
+ case, if there is some other partition in the partition tree for which this
+ row satisfies its partition constraint, then the row is moved to that
+ partition. If there is no such partition, an error will occur. Behind the
+ scenes, the row movement is actually a <code class="command">DELETE</code> and
+ <code class="command">INSERT</code> operation.
+ </p><p>
+ There is a possibility that a concurrent <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> on the row being moved will get a serialization
+ failure error. Suppose session 1 is performing an <code class="command">UPDATE</code>
+ on a partition key, and meanwhile a concurrent session 2 for which this
+ row is visible performs an <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> operation on this row. In such case,
+ session 2's <code class="command">UPDATE</code> or <code class="command">DELETE</code> will
+ detect the row movement and raise a serialization failure error (which
+ always returns with an SQLSTATE code '40001'). Applications may wish to
+ retry the transaction if this occurs. In the usual case where the table
+ is not partitioned, or where there is no row movement, session 2 would
+ have identified the newly updated row and carried out the
+ <code class="command">UPDATE</code>/<code class="command">DELETE</code> on this new row
+ version.
+ </p><p>
+ Note that while rows can be moved from local partitions to a foreign-table
+ partition (provided the foreign data wrapper supports tuple routing), they
+ cannot be moved from a foreign-table partition to another partition.
+ </p><p>
+ An attempt of moving a row from one partition to another will fail if a
+ foreign key is found to directly reference an ancestor of the source
+ partition that is not the same as the ancestor that's mentioned in the
+ <code class="command">UPDATE</code> query.
+ </p></div><div class="refsect1" id="id-1.9.3.183.9"><h2>Examples</h2><p>
+ Change the word <code class="literal">Drama</code> to <code class="literal">Dramatic</code> in the
+ column <code class="structfield">kind</code> of the table <code class="structname">films</code>:
+
+</p><pre class="programlisting">
+UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';
+</pre><p>
+ </p><p>
+ Adjust temperature entries and reset precipitation to its default
+ value in one row of the table <code class="structname">weather</code>:
+
+</p><pre class="programlisting">
+UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
+ WHERE city = 'San Francisco' AND date = '2003-07-03';
+</pre><p>
+ </p><p>
+ Perform the same operation and return the updated entries:
+
+</p><pre class="programlisting">
+UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
+ WHERE city = 'San Francisco' AND date = '2003-07-03'
+ RETURNING temp_lo, temp_hi, prcp;
+</pre><p>
+ </p><p>
+ Use the alternative column-list syntax to do the same update:
+</p><pre class="programlisting">
+UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
+ WHERE city = 'San Francisco' AND date = '2003-07-03';
+</pre><p>
+ </p><p>
+ Increment the sales count of the salesperson who manages the
+ account for Acme Corporation, using the <code class="literal">FROM</code>
+ clause syntax:
+</p><pre class="programlisting">
+UPDATE employees SET sales_count = sales_count + 1 FROM accounts
+ WHERE accounts.name = 'Acme Corporation'
+ AND employees.id = accounts.sales_person;
+</pre><p>
+ </p><p>
+ Perform the same operation, using a sub-select in the
+ <code class="literal">WHERE</code> clause:
+</p><pre class="programlisting">
+UPDATE employees SET sales_count = sales_count + 1 WHERE id =
+ (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');
+</pre><p>
+ </p><p>
+ Update contact names in an accounts table to match the currently assigned
+ salespeople:
+</p><pre class="programlisting">
+UPDATE accounts SET (contact_first_name, contact_last_name) =
+ (SELECT first_name, last_name FROM employees
+ WHERE employees.id = accounts.sales_person);
+</pre><p>
+ A similar result could be accomplished with a join:
+</p><pre class="programlisting">
+UPDATE accounts SET contact_first_name = first_name,
+ contact_last_name = last_name
+ FROM employees WHERE employees.id = accounts.sales_person;
+</pre><p>
+ However, the second query may give unexpected results
+ if <code class="structname">employees</code>.<code class="structfield">id</code> is not a unique key, whereas
+ the first query is guaranteed to raise an error if there are multiple
+ <code class="structfield">id</code> matches. Also, if there is no match for a particular
+ <code class="structname">accounts</code>.<code class="structfield">sales_person</code> entry, the first query
+ will set the corresponding name fields to NULL, whereas the second query
+ will not update that row at all.
+ </p><p>
+ Update statistics in a summary table to match the current data:
+</p><pre class="programlisting">
+UPDATE summary s SET (sum_x, sum_y, avg_x, avg_y) =
+ (SELECT sum(x), sum(y), avg(x), avg(y) FROM data d
+ WHERE d.group_id = s.group_id);
+</pre><p>
+ </p><p>
+ Attempt to insert a new stock item along with the quantity of stock. If
+ the item already exists, instead update the stock count of the existing
+ item. To do this without failing the entire transaction, use savepoints:
+</p><pre class="programlisting">
+BEGIN;
+-- other operations
+SAVEPOINT sp1;
+INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
+-- Assume the above fails because of a unique key violation,
+-- so now we issue these commands:
+ROLLBACK TO sp1;
+UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003';
+-- continue with other operations, and eventually
+COMMIT;
+</pre><p>
+ </p><p>
+ Change the <code class="structfield">kind</code> column of the table
+ <code class="structname">films</code> in the row on which the cursor
+ <code class="literal">c_films</code> is currently positioned:
+</p><pre class="programlisting">
+UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;
+</pre></div><div class="refsect1" id="id-1.9.3.183.10"><h2>Compatibility</h2><p>
+ This command conforms to the <acronym class="acronym">SQL</acronym> standard, except
+ that the <code class="literal">FROM</code> and <code class="literal">RETURNING</code> clauses
+ are <span class="productname">PostgreSQL</span> extensions, as is the ability
+ to use <code class="literal">WITH</code> with <code class="command">UPDATE</code>.
+ </p><p>
+ Some other database systems offer a <code class="literal">FROM</code> option in which
+ the target table is supposed to be listed again within <code class="literal">FROM</code>.
+ That is not how <span class="productname">PostgreSQL</span> interprets
+ <code class="literal">FROM</code>. Be careful when porting applications that use this
+ extension.
+ </p><p>
+ According to the standard, the source value for a parenthesized sub-list of
+ target column names can be any row-valued expression yielding the correct
+ number of columns. <span class="productname">PostgreSQL</span> only allows the
+ source value to be a <a class="link" href="sql-expressions.html#SQL-SYNTAX-ROW-CONSTRUCTORS" title="4.2.13. Row Constructors">row
+ constructor</a> or a sub-<code class="literal">SELECT</code>. An individual column's
+ updated value can be specified as <code class="literal">DEFAULT</code> in the
+ row-constructor case, but not inside a sub-<code class="literal">SELECT</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-unlisten.html" title="UNLISTEN">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-vacuum.html" title="VACUUM">Next</a></td></tr><tr><td width="40%" align="left" valign="top">UNLISTEN </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> VACUUM</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-vacuum.html b/doc/src/sgml/html/sql-vacuum.html
new file mode 100644
index 0000000..6f60b6d
--- /dev/null
+++ b/doc/src/sgml/html/sql-vacuum.html
@@ -0,0 +1,258 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>VACUUM</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-update.html" title="UPDATE" /><link rel="next" href="sql-values.html" title="VALUES" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">VACUUM</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-update.html" title="UPDATE">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-values.html" title="VALUES">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-VACUUM"><div class="titlepage"></div><a id="id-1.9.3.184.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">VACUUM</span></h2><p>VACUUM — garbage-collect and optionally analyze a database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+VACUUM [ ( <em class="replaceable"><code>option</code></em> [, ...] ) ] [ <em class="replaceable"><code>table_and_columns</code></em> [, ...] ]
+VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <em class="replaceable"><code>table_and_columns</code></em> [, ...] ]
+
+<span class="phrase">where <em class="replaceable"><code>option</code></em> can be one of:</span>
+
+ FULL [ <em class="replaceable"><code>boolean</code></em> ]
+ FREEZE [ <em class="replaceable"><code>boolean</code></em> ]
+ VERBOSE [ <em class="replaceable"><code>boolean</code></em> ]
+ ANALYZE [ <em class="replaceable"><code>boolean</code></em> ]
+ DISABLE_PAGE_SKIPPING [ <em class="replaceable"><code>boolean</code></em> ]
+ SKIP_LOCKED [ <em class="replaceable"><code>boolean</code></em> ]
+ INDEX_CLEANUP { AUTO | ON | OFF }
+ PROCESS_TOAST [ <em class="replaceable"><code>boolean</code></em> ]
+ TRUNCATE [ <em class="replaceable"><code>boolean</code></em> ]
+ PARALLEL <em class="replaceable"><code>integer</code></em>
+
+<span class="phrase">and <em class="replaceable"><code>table_and_columns</code></em> is:</span>
+
+ <em class="replaceable"><code>table_name</code></em> [ ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
+</pre></div><div class="refsect1" id="id-1.9.3.184.5"><h2>Description</h2><p>
+ <code class="command">VACUUM</code> reclaims storage occupied by dead tuples.
+ In normal <span class="productname">PostgreSQL</span> operation, tuples that
+ are deleted or obsoleted by an update are not physically removed from
+ their table; they remain present until a <code class="command">VACUUM</code> is
+ done. Therefore it's necessary to do <code class="command">VACUUM</code>
+ periodically, especially on frequently-updated tables.
+ </p><p>
+ Without a <em class="replaceable"><code>table_and_columns</code></em>
+ list, <code class="command">VACUUM</code> processes every table and materialized view
+ in the current database that the current user has permission to vacuum.
+ With a list, <code class="command">VACUUM</code> processes only those table(s).
+ </p><p>
+ <code class="command">VACUUM ANALYZE</code> performs a <code class="command">VACUUM</code>
+ and then an <code class="command">ANALYZE</code> for each selected table. This
+ is a handy combination form for routine maintenance scripts. See
+ <a class="xref" href="sql-analyze.html" title="ANALYZE"><span class="refentrytitle">ANALYZE</span></a>
+ for more details about its processing.
+ </p><p>
+ Plain <code class="command">VACUUM</code> (without <code class="literal">FULL</code>) simply reclaims
+ space and makes it
+ available for re-use. This form of the command can operate in parallel
+ with normal reading and writing of the table, as an exclusive lock
+ is not obtained. However, extra space is not returned to the operating
+ system (in most cases); it's just kept available for re-use within the
+ same table. It also allows us to leverage multiple CPUs in order to process
+ indexes. This feature is known as <em class="firstterm">parallel vacuum</em>.
+ To disable this feature, one can use <code class="literal">PARALLEL</code> option and
+ specify parallel workers as zero. <code class="command">VACUUM FULL</code> rewrites
+ the entire contents of the table into a new disk file with no extra space,
+ allowing unused space to be returned to the operating system. This form is
+ much slower and requires an <code class="literal">ACCESS EXCLUSIVE</code> lock on
+ each table while it is being processed.
+ </p><p>
+ When the option list is surrounded by parentheses, the options can be
+ written in any order. Without parentheses, options must be specified
+ in exactly the order shown above.
+ The parenthesized syntax was added in
+ <span class="productname">PostgreSQL</span> 9.0; the unparenthesized
+ syntax is deprecated.
+ </p></div><div class="refsect1" id="id-1.9.3.184.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">FULL</code></span></dt><dd><p>
+ Selects <span class="quote">“<span class="quote">full</span>”</span> vacuum, which can reclaim more
+ space, but takes much longer and exclusively locks the table.
+ This method also requires extra disk space, since it writes a
+ new copy of the table and doesn't release the old copy until
+ the operation is complete. Usually this should only be used when a
+ significant amount of space needs to be reclaimed from within the table.
+ </p></dd><dt><span class="term"><code class="literal">FREEZE</code></span></dt><dd><p>
+ Selects aggressive <span class="quote">“<span class="quote">freezing</span>”</span> of tuples.
+ Specifying <code class="literal">FREEZE</code> is equivalent to performing
+ <code class="command">VACUUM</code> with the
+ <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FREEZE-MIN-AGE">vacuum_freeze_min_age</a> and
+ <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FREEZE-TABLE-AGE">vacuum_freeze_table_age</a> parameters
+ set to zero. Aggressive freezing is always performed when the
+ table is rewritten, so this option is redundant when <code class="literal">FULL</code>
+ is specified.
+ </p></dd><dt><span class="term"><code class="literal">VERBOSE</code></span></dt><dd><p>
+ Prints a detailed vacuum activity report for each table.
+ </p></dd><dt><span class="term"><code class="literal">ANALYZE</code></span></dt><dd><p>
+ Updates statistics used by the planner to determine the most
+ efficient way to execute a query.
+ </p></dd><dt><span class="term"><code class="literal">DISABLE_PAGE_SKIPPING</code></span></dt><dd><p>
+ Normally, <code class="command">VACUUM</code> will skip pages based on the <a class="link" href="routine-vacuuming.html#VACUUM-FOR-VISIBILITY-MAP" title="25.1.4. Updating the Visibility Map">visibility map</a>. Pages where
+ all tuples are known to be frozen can always be skipped, and those
+ where all tuples are known to be visible to all transactions may be
+ skipped except when performing an aggressive vacuum. Furthermore,
+ except when performing an aggressive vacuum, some pages may be skipped
+ in order to avoid waiting for other sessions to finish using them.
+ This option disables all page-skipping behavior, and is intended to
+ be used only when the contents of the visibility map are
+ suspect, which should happen only if there is a hardware or software
+ issue causing database corruption.
+ </p></dd><dt><span class="term"><code class="literal">SKIP_LOCKED</code></span></dt><dd><p>
+ Specifies that <code class="command">VACUUM</code> should not wait for any
+ conflicting locks to be released when beginning work on a relation:
+ if a relation cannot be locked immediately without waiting, the relation
+ is skipped. Note that even with this option,
+ <code class="command">VACUUM</code> may still block when opening the relation's
+ indexes. Additionally, <code class="command">VACUUM ANALYZE</code> may still
+ block when acquiring sample rows from partitions, table inheritance
+ children, and some types of foreign tables. Also, while
+ <code class="command">VACUUM</code> ordinarily processes all partitions of
+ specified partitioned tables, this option will cause
+ <code class="command">VACUUM</code> to skip all partitions if there is a
+ conflicting lock on the partitioned table.
+ </p></dd><dt><span class="term"><code class="literal">INDEX_CLEANUP</code></span></dt><dd><p>
+ Normally, <code class="command">VACUUM</code> will skip index vacuuming
+ when there are very few dead tuples in the table. The cost of
+ processing all of the table's indexes is expected to greatly
+ exceed the benefit of removing dead index tuples when this
+ happens. This option can be used to force
+ <code class="command">VACUUM</code> to process indexes when there are more
+ than zero dead tuples. The default is <code class="literal">AUTO</code>,
+ which allows <code class="command">VACUUM</code> to skip index vacuuming
+ when appropriate. If <code class="literal">INDEX_CLEANUP</code> is set to
+ <code class="literal">ON</code>, <code class="command">VACUUM</code> will
+ conservatively remove all dead tuples from indexes. This may be
+ useful for backwards compatibility with earlier releases of
+ <span class="productname">PostgreSQL</span> where this was the
+ standard behavior.
+ </p><p>
+ <code class="literal">INDEX_CLEANUP</code> can also be set to
+ <code class="literal">OFF</code> to force <code class="command">VACUUM</code> to
+ <span class="emphasis"><em>always</em></span> skip index vacuuming, even when
+ there are many dead tuples in the table. This may be useful
+ when it is necessary to make <code class="command">VACUUM</code> run as
+ quickly as possible to avoid imminent transaction ID wraparound
+ (see <a class="xref" href="routine-vacuuming.html#VACUUM-FOR-WRAPAROUND" title="25.1.5. Preventing Transaction ID Wraparound Failures">Section 25.1.5</a>). However, the
+ wraparound failsafe mechanism controlled by <a class="xref" href="runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE">vacuum_failsafe_age</a> will generally trigger
+ automatically to avoid transaction ID wraparound failure, and
+ should be preferred. If index cleanup is not performed
+ regularly, performance may suffer, because as the table is
+ modified indexes will accumulate dead tuples and the table
+ itself will accumulate dead line pointers that cannot be removed
+ until index cleanup is completed.
+ </p><p>
+ This option has no effect for tables that have no index and is
+ ignored if the <code class="literal">FULL</code> option is used. It also
+ has no effect on the transaction ID wraparound failsafe
+ mechanism. When triggered it will skip index vacuuming, even
+ when <code class="literal">INDEX_CLEANUP</code> is set to
+ <code class="literal">ON</code>.
+ </p></dd><dt><span class="term"><code class="literal">PROCESS_TOAST</code></span></dt><dd><p>
+ Specifies that <code class="command">VACUUM</code> should attempt to process the
+ corresponding <code class="literal">TOAST</code> table for each relation, if one
+ exists. This is usually the desired behavior and is the default.
+ Setting this option to false may be useful when it is only necessary to
+ vacuum the main relation. This option is required when the
+ <code class="literal">FULL</code> option is used.
+ </p></dd><dt><span class="term"><code class="literal">TRUNCATE</code></span></dt><dd><p>
+ Specifies that <code class="command">VACUUM</code> should attempt to
+ truncate off any empty pages at the end of the table and allow
+ the disk space for the truncated pages to be returned to
+ the operating system. This is normally the desired behavior
+ and is the default unless the <code class="literal">vacuum_truncate</code>
+ option has been set to false for the table to be vacuumed.
+ Setting this option to false may be useful to avoid
+ <code class="literal">ACCESS EXCLUSIVE</code> lock on the table that
+ the truncation requires. This option is ignored if the
+ <code class="literal">FULL</code> option is used.
+ </p></dd><dt><span class="term"><code class="literal">PARALLEL</code></span></dt><dd><p>
+ Perform index vacuum and index cleanup phases of <code class="command">VACUUM</code>
+ in parallel using <em class="replaceable"><code>integer</code></em>
+ background workers (for the details of each vacuum phase, please
+ refer to <a class="xref" href="progress-reporting.html#VACUUM-PHASES" title="Table 28.41. VACUUM Phases">Table 28.41</a>). The number of workers used
+ to perform the operation is equal to the number of indexes on the
+ relation that support parallel vacuum which is limited by the number of
+ workers specified with <code class="literal">PARALLEL</code> option if any which is
+ further limited by <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-MAINTENANCE-WORKERS">max_parallel_maintenance_workers</a>.
+ An index can participate in parallel vacuum if and only if the size of the
+ index is more than <a class="xref" href="runtime-config-query.html#GUC-MIN-PARALLEL-INDEX-SCAN-SIZE">min_parallel_index_scan_size</a>.
+ Please note that it is not guaranteed that the number of parallel workers
+ specified in <em class="replaceable"><code>integer</code></em> will be
+ used during execution. It is possible for a vacuum to run with fewer
+ workers than specified, or even with no workers at all. Only one worker
+ can be used per index. So parallel workers are launched only when there
+ are at least <code class="literal">2</code> indexes in the table. Workers for
+ vacuum are launched before the start of each phase and exit at the end of
+ the phase. These behaviors might change in a future release. This
+ option can't be used with the <code class="literal">FULL</code> option.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>boolean</code></em></span></dt><dd><p>
+ Specifies whether the selected option should be turned on or off.
+ You can write <code class="literal">TRUE</code>, <code class="literal">ON</code>, or
+ <code class="literal">1</code> to enable the option, and <code class="literal">FALSE</code>,
+ <code class="literal">OFF</code>, or <code class="literal">0</code> to disable it. The
+ <em class="replaceable"><code>boolean</code></em> value can also
+ be omitted, in which case <code class="literal">TRUE</code> is assumed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>integer</code></em></span></dt><dd><p>
+ Specifies a non-negative integer value passed to the selected option.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
+ The name (optionally schema-qualified) of a specific table or
+ materialized view to vacuum. If the specified table is a partitioned
+ table, all of its leaf partitions are vacuumed.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
+ The name of a specific column to analyze. Defaults to all columns.
+ If a column list is specified, <code class="literal">ANALYZE</code> must also be
+ specified.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.184.7"><h2>Outputs</h2><p>
+ When <code class="literal">VERBOSE</code> is specified, <code class="command">VACUUM</code> emits
+ progress messages to indicate which table is currently being
+ processed. Various statistics about the tables are printed as well.
+ </p></div><div class="refsect1" id="id-1.9.3.184.8"><h2>Notes</h2><p>
+ To vacuum a table, one must ordinarily be the table's owner or a
+ superuser. However, database owners are allowed to
+ vacuum all tables in their databases, except shared catalogs.
+ (The restriction for shared catalogs means that a true database-wide
+ <code class="command">VACUUM</code> can only be performed by a superuser.)
+ <code class="command">VACUUM</code> will skip over any tables that the calling user
+ does not have permission to vacuum.
+ </p><p>
+ <code class="command">VACUUM</code> cannot be executed inside a transaction block.
+ </p><p>
+ For tables with <acronym class="acronym">GIN</acronym> indexes, <code class="command">VACUUM</code> (in
+ any form) also completes any pending index insertions, by moving pending
+ index entries to the appropriate places in the main <acronym class="acronym">GIN</acronym> index
+ structure. See <a class="xref" href="gin-implementation.html#GIN-FAST-UPDATE" title="70.4.1. GIN Fast Update Technique">Section 70.4.1</a> for details.
+ </p><p>
+ We recommend that all databases be vacuumed regularly in
+ order to remove dead rows. <span class="productname">PostgreSQL</span> includes
+ an <span class="quote">“<span class="quote">autovacuum</span>”</span> facility which can automate routine vacuum
+ maintenance. For more information about automatic and manual vacuuming,
+ see <a class="xref" href="routine-vacuuming.html" title="25.1. Routine Vacuuming">Section 25.1</a>.
+ </p><p>
+ The <code class="option">FULL</code> option is not recommended for routine use,
+ but might be useful in special cases. An example is when you have deleted
+ or updated most of the rows in a table and would like the table to
+ physically shrink to occupy less disk space and allow faster table
+ scans. <code class="command">VACUUM FULL</code> will usually shrink the table
+ more than a plain <code class="command">VACUUM</code> would.
+ </p><p>
+ The <code class="option">PARALLEL</code> option is used only for vacuum purposes.
+ If this option is specified with the <code class="option">ANALYZE</code> option,
+ it does not affect <code class="option">ANALYZE</code>.
+ </p><p>
+ <code class="command">VACUUM</code> causes a substantial increase in I/O traffic,
+ which might cause poor performance for other active sessions. Therefore,
+ it is sometimes advisable to use the cost-based vacuum delay feature. For
+ parallel vacuum, each worker sleeps in proportion to the work done by that
+ worker. See <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST" title="20.4.4. Cost-based Vacuum Delay">Section 20.4.4</a> for
+ details.
+ </p><p>
+ Each backend running <code class="command">VACUUM</code> without the
+ <code class="literal">FULL</code> option will report its progress in the
+ <code class="structname">pg_stat_progress_vacuum</code> view. Backends running
+ <code class="command">VACUUM FULL</code> will instead report their progress in the
+ <code class="structname">pg_stat_progress_cluster</code> view. See
+ <a class="xref" href="progress-reporting.html#VACUUM-PROGRESS-REPORTING" title="28.4.3. VACUUM Progress Reporting">Section 28.4.3</a> and
+ <a class="xref" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING" title="28.4.4. CLUSTER Progress Reporting">Section 28.4.4</a> for details.
+ </p></div><div class="refsect1" id="id-1.9.3.184.9"><h2>Examples</h2><p>
+ To clean a single table <code class="literal">onek</code>, analyze it for
+ the optimizer and print a detailed vacuum activity report:
+
+</p><pre class="programlisting">
+VACUUM (VERBOSE, ANALYZE) onek;
+</pre></div><div class="refsect1" id="id-1.9.3.184.10"><h2>Compatibility</h2><p>
+ There is no <code class="command">VACUUM</code> statement in the SQL standard.
+ </p></div><div class="refsect1" id="id-1.9.3.184.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="app-vacuumdb.html" title="vacuumdb"><span class="refentrytitle"><span class="application">vacuumdb</span></span></a>, <a class="xref" href="runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST" title="20.4.4. Cost-based Vacuum Delay">Section 20.4.4</a>, <a class="xref" href="routine-vacuuming.html#AUTOVACUUM" title="25.1.6. The Autovacuum Daemon">Section 25.1.6</a>, <a class="xref" href="progress-reporting.html#VACUUM-PROGRESS-REPORTING" title="28.4.3. VACUUM Progress Reporting">Section 28.4.3</a>, <a class="xref" href="progress-reporting.html#CLUSTER-PROGRESS-REPORTING" title="28.4.4. CLUSTER Progress Reporting">Section 28.4.4</a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-update.html" title="UPDATE">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-values.html" title="VALUES">Next</a></td></tr><tr><td width="40%" align="left" valign="top">UPDATE </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> VALUES</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql-values.html b/doc/src/sgml/html/sql-values.html
new file mode 100644
index 0000000..92aa8db
--- /dev/null
+++ b/doc/src/sgml/html/sql-values.html
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>VALUES</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-vacuum.html" title="VACUUM" /><link rel="next" href="reference-client.html" title="PostgreSQL Client Applications" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">VALUES</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-vacuum.html" title="VACUUM">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="reference-client.html" title="PostgreSQL Client Applications">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-VALUES"><div class="titlepage"></div><a id="id-1.9.3.185.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">VALUES</span></h2><p>VALUES — compute a set of rows</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
+VALUES ( <em class="replaceable"><code>expression</code></em> [, ...] ) [, ...]
+ [ ORDER BY <em class="replaceable"><code>sort_expression</code></em> [ ASC | DESC | USING <em class="replaceable"><code>operator</code></em> ] [, ...] ]
+ [ LIMIT { <em class="replaceable"><code>count</code></em> | ALL } ]
+ [ OFFSET <em class="replaceable"><code>start</code></em> [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ <em class="replaceable"><code>count</code></em> ] { ROW | ROWS } ONLY ]
+</pre></div><div class="refsect1" id="id-1.9.3.185.5"><h2>Description</h2><p>
+ <code class="command">VALUES</code> computes a row value or set of row values
+ specified by value expressions. It is most commonly used to generate
+ a <span class="quote">“<span class="quote">constant table</span>”</span> within a larger command, but it can be
+ used on its own.
+ </p><p>
+ When more than one row is specified, all the rows must have the same
+ number of elements. The data types of the resulting table's columns are
+ determined by combining the explicit or inferred types of the expressions
+ appearing in that column, using the same rules as for <code class="literal">UNION</code>
+ (see <a class="xref" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Section 10.5</a>).
+ </p><p>
+ Within larger commands, <code class="command">VALUES</code> is syntactically allowed
+ anywhere that <code class="command">SELECT</code> is. Because it is treated like a
+ <code class="command">SELECT</code> by the grammar, it is possible to use
+ the <code class="literal">ORDER BY</code>, <code class="literal">LIMIT</code> (or
+ equivalently <code class="literal">FETCH FIRST</code>),
+ and <code class="literal">OFFSET</code> clauses with a
+ <code class="command">VALUES</code> command.
+ </p></div><div class="refsect1" id="id-1.9.3.185.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
+ A constant or expression to compute and insert at the indicated place
+ in the resulting table (set of rows). In a <code class="command">VALUES</code> list
+ appearing at the top level of an <code class="command">INSERT</code>, an
+ <em class="replaceable"><code>expression</code></em> can be replaced
+ by <code class="literal">DEFAULT</code> to indicate that the destination column's
+ default value should be inserted. <code class="literal">DEFAULT</code> cannot
+ be used when <code class="command">VALUES</code> appears in other contexts.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>sort_expression</code></em></span></dt><dd><p>
+ An expression or integer constant indicating how to sort the result
+ rows. This expression can refer to the columns of the
+ <code class="command">VALUES</code> result as <code class="literal">column1</code>, <code class="literal">column2</code>,
+ etc. For more details see
+ <a class="xref" href="sql-select.html#SQL-ORDERBY" title="ORDER BY Clause">ORDER BY Clause</a>
+ in the <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> documentation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>operator</code></em></span></dt><dd><p>
+ A sorting operator. For details see
+ <a class="xref" href="sql-select.html#SQL-ORDERBY" title="ORDER BY Clause">ORDER BY Clause</a>
+ in the <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> documentation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>count</code></em></span></dt><dd><p>
+ The maximum number of rows to return. For details see
+ <a class="xref" href="sql-select.html#SQL-LIMIT" title="LIMIT Clause">LIMIT Clause</a>
+ in the <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> documentation.
+ </p></dd><dt><span class="term"><em class="replaceable"><code>start</code></em></span></dt><dd><p>
+ The number of rows to skip before starting to return rows.
+ For details see <a class="xref" href="sql-select.html#SQL-LIMIT" title="LIMIT Clause">LIMIT Clause</a>
+ in the <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> documentation.
+ </p></dd></dl></div></div><div class="refsect1" id="id-1.9.3.185.7"><h2>Notes</h2><p>
+ <code class="command">VALUES</code> lists with very large numbers of rows should be avoided,
+ as you might encounter out-of-memory failures or poor performance.
+ <code class="command">VALUES</code> appearing within <code class="command">INSERT</code> is a special case
+ (because the desired column types are known from the <code class="command">INSERT</code>'s
+ target table, and need not be inferred by scanning the <code class="command">VALUES</code>
+ list), so it can handle larger lists than are practical in other contexts.
+ </p></div><div class="refsect1" id="id-1.9.3.185.8"><h2>Examples</h2><p>
+ A bare <code class="command">VALUES</code> command:
+
+</p><pre class="programlisting">
+VALUES (1, 'one'), (2, 'two'), (3, 'three');
+</pre><p>
+
+ This will return a table of two columns and three rows. It's effectively
+ equivalent to:
+
+</p><pre class="programlisting">
+SELECT 1 AS column1, 'one' AS column2
+UNION ALL
+SELECT 2, 'two'
+UNION ALL
+SELECT 3, 'three';
+</pre><p>
+
+ </p><p>
+ More usually, <code class="command">VALUES</code> is used within a larger SQL command.
+ The most common use is in <code class="command">INSERT</code>:
+
+</p><pre class="programlisting">
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
+</pre><p>
+ </p><p>
+ In the context of <code class="command">INSERT</code>, entries of a <code class="command">VALUES</code> list
+ can be <code class="literal">DEFAULT</code> to indicate that the column default
+ should be used here instead of specifying a value:
+
+</p><pre class="programlisting">
+INSERT INTO films VALUES
+ ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes'),
+ ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama', DEFAULT);
+</pre><p>
+ </p><p>
+ <code class="command">VALUES</code> can also be used where a sub-<code class="command">SELECT</code> might
+ be written, for example in a <code class="literal">FROM</code> clause:
+
+</p><pre class="programlisting">
+SELECT f.*
+ FROM films f, (VALUES('MGM', 'Horror'), ('UA', 'Sci-Fi')) AS t (studio, kind)
+ WHERE f.studio = t.studio AND f.kind = t.kind;
+
+UPDATE employees SET salary = salary * v.increase
+ FROM (VALUES(1, 200000, 1.2), (2, 400000, 1.4)) AS v (depno, target, increase)
+ WHERE employees.depno = v.depno AND employees.sales &gt;= v.target;
+</pre><p>
+
+ Note that an <code class="literal">AS</code> clause is required when <code class="command">VALUES</code>
+ is used in a <code class="literal">FROM</code> clause, just as is true for
+ <code class="command">SELECT</code>. It is not required that the <code class="literal">AS</code> clause
+ specify names for all the columns, but it's good practice to do so.
+ (The default column names for <code class="command">VALUES</code> are <code class="literal">column1</code>,
+ <code class="literal">column2</code>, etc. in <span class="productname">PostgreSQL</span>, but
+ these names might be different in other database systems.)
+ </p><p>
+ When <code class="command">VALUES</code> is used in <code class="command">INSERT</code>, the values are all
+ automatically coerced to the data type of the corresponding destination
+ column. When it's used in other contexts, it might be necessary to specify
+ the correct data type. If the entries are all quoted literal constants,
+ coercing the first is sufficient to determine the assumed type for all:
+
+</p><pre class="programlisting">
+SELECT * FROM machines
+WHERE ip_address IN (VALUES('192.168.0.1'::inet), ('192.168.0.10'), ('192.168.1.43'));
+</pre><div class="tip"><h3 class="title">Tip</h3><p>
+ For simple <code class="literal">IN</code> tests, it's better to rely on the
+ <a class="link" href="functions-comparisons.html#FUNCTIONS-COMPARISONS-IN-SCALAR" title="9.24.1. IN">list-of-scalars</a>
+ form of <code class="literal">IN</code> than to write a <code class="command">VALUES</code>
+ query as shown above. The list of scalars method requires less writing
+ and is often more efficient.
+ </p></div></div><div class="refsect1" id="id-1.9.3.185.9"><h2>Compatibility</h2><p><code class="command">VALUES</code> conforms to the SQL standard.
+ <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code> are
+ <span class="productname">PostgreSQL</span> extensions; see also
+ under <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a>.
+ </p></div><div class="refsect1" id="id-1.9.3.185.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-insert.html" title="INSERT"><span class="refentrytitle">INSERT</span></a>, <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-vacuum.html" title="VACUUM">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="reference-client.html" title="PostgreSQL Client Applications">Next</a></td></tr><tr><td width="40%" align="left" valign="top">VACUUM </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> PostgreSQL Client Applications</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sql.html b/doc/src/sgml/html/sql.html
new file mode 100644
index 0000000..dfb79be
--- /dev/null
+++ b/doc/src/sgml/html/sql.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part II. The SQL Language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-conclusion.html" title="3.7. Conclusion" /><link rel="next" href="sql-syntax.html" title="Chapter 4. SQL Syntax" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part II. The SQL Language</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-conclusion.html" title="3.7. Conclusion">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Next</a></td></tr></table><hr /></div><div class="part" id="SQL"><div class="titlepage"><div><div><h1 class="title">Part II. The SQL Language</h1></div></div></div><div class="partintro" id="id-1.5.2"><div></div><p>
+ This part describes the use of the <acronym class="acronym">SQL</acronym> language
+ in <span class="productname">PostgreSQL</span>. We start with
+ describing the general syntax of <acronym class="acronym">SQL</acronym>, then
+ explain how to create the structures to hold data, how to populate
+ the database, and how to query it. The middle part lists the
+ available data types and functions for use in
+ <acronym class="acronym">SQL</acronym> commands. The rest treats several
+ aspects that are important for tuning a database for optimal
+ performance.
+ </p><p>
+ The information in this part is arranged so that a novice user can
+ follow it start to end to gain a full understanding of the topics
+ without having to refer forward too many times. The chapters are
+ intended to be self-contained, so that advanced users can read the
+ chapters individually as they choose. The information in this
+ part is presented in a narrative fashion in topical units.
+ Readers looking for a complete description of a particular command
+ should see <a class="xref" href="reference.html" title="Part VI. Reference">Part VI</a>.
+ </p><p>
+ Readers of this part should know how to connect to a
+ <span class="productname">PostgreSQL</span> database and issue
+ <acronym class="acronym">SQL</acronym> commands. Readers that are unfamiliar with
+ these issues are encouraged to read <a class="xref" href="tutorial.html" title="Part I. Tutorial">Part I</a>
+ first. <acronym class="acronym">SQL</acronym> commands are typically entered
+ using the <span class="productname">PostgreSQL</span> interactive terminal
+ <span class="application">psql</span>, but other programs that have
+ similar functionality can be used as well.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="sql-syntax.html">4. SQL Syntax</a></span></dt><dd><dl><dt><span class="sect1"><a href="sql-syntax-lexical.html">4.1. Lexical Structure</a></span></dt><dt><span class="sect1"><a href="sql-expressions.html">4.2. Value Expressions</a></span></dt><dt><span class="sect1"><a href="sql-syntax-calling-funcs.html">4.3. Calling Functions</a></span></dt></dl></dd><dt><span class="chapter"><a href="ddl.html">5. Data Definition</a></span></dt><dd><dl><dt><span class="sect1"><a href="ddl-basics.html">5.1. Table Basics</a></span></dt><dt><span class="sect1"><a href="ddl-default.html">5.2. Default Values</a></span></dt><dt><span class="sect1"><a href="ddl-generated-columns.html">5.3. Generated Columns</a></span></dt><dt><span class="sect1"><a href="ddl-constraints.html">5.4. Constraints</a></span></dt><dt><span class="sect1"><a href="ddl-system-columns.html">5.5. System Columns</a></span></dt><dt><span class="sect1"><a href="ddl-alter.html">5.6. Modifying Tables</a></span></dt><dt><span class="sect1"><a href="ddl-priv.html">5.7. Privileges</a></span></dt><dt><span class="sect1"><a href="ddl-rowsecurity.html">5.8. Row Security Policies</a></span></dt><dt><span class="sect1"><a href="ddl-schemas.html">5.9. Schemas</a></span></dt><dt><span class="sect1"><a href="ddl-inherit.html">5.10. Inheritance</a></span></dt><dt><span class="sect1"><a href="ddl-partitioning.html">5.11. Table Partitioning</a></span></dt><dt><span class="sect1"><a href="ddl-foreign-data.html">5.12. Foreign Data</a></span></dt><dt><span class="sect1"><a href="ddl-others.html">5.13. Other Database Objects</a></span></dt><dt><span class="sect1"><a href="ddl-depend.html">5.14. Dependency Tracking</a></span></dt></dl></dd><dt><span class="chapter"><a href="dml.html">6. Data Manipulation</a></span></dt><dd><dl><dt><span class="sect1"><a href="dml-insert.html">6.1. Inserting Data</a></span></dt><dt><span class="sect1"><a href="dml-update.html">6.2. Updating Data</a></span></dt><dt><span class="sect1"><a href="dml-delete.html">6.3. Deleting Data</a></span></dt><dt><span class="sect1"><a href="dml-returning.html">6.4. Returning Data from Modified Rows</a></span></dt></dl></dd><dt><span class="chapter"><a href="queries.html">7. Queries</a></span></dt><dd><dl><dt><span class="sect1"><a href="queries-overview.html">7.1. Overview</a></span></dt><dt><span class="sect1"><a href="queries-table-expressions.html">7.2. Table Expressions</a></span></dt><dt><span class="sect1"><a href="queries-select-lists.html">7.3. Select Lists</a></span></dt><dt><span class="sect1"><a href="queries-union.html">7.4. Combining Queries (<code class="literal">UNION</code>, <code class="literal">INTERSECT</code>, <code class="literal">EXCEPT</code>)</a></span></dt><dt><span class="sect1"><a href="queries-order.html">7.5. Sorting Rows (<code class="literal">ORDER BY</code>)</a></span></dt><dt><span class="sect1"><a href="queries-limit.html">7.6. <code class="literal">LIMIT</code> and <code class="literal">OFFSET</code></a></span></dt><dt><span class="sect1"><a href="queries-values.html">7.7. <code class="literal">VALUES</code> Lists</a></span></dt><dt><span class="sect1"><a href="queries-with.html">7.8. <code class="literal">WITH</code> Queries (Common Table Expressions)</a></span></dt></dl></dd><dt><span class="chapter"><a href="datatype.html">8. Data Types</a></span></dt><dd><dl><dt><span class="sect1"><a href="datatype-numeric.html">8.1. Numeric Types</a></span></dt><dt><span class="sect1"><a href="datatype-money.html">8.2. Monetary Types</a></span></dt><dt><span class="sect1"><a href="datatype-character.html">8.3. Character Types</a></span></dt><dt><span class="sect1"><a href="datatype-binary.html">8.4. Binary Data Types</a></span></dt><dt><span class="sect1"><a href="datatype-datetime.html">8.5. Date/Time Types</a></span></dt><dt><span class="sect1"><a href="datatype-boolean.html">8.6. Boolean Type</a></span></dt><dt><span class="sect1"><a href="datatype-enum.html">8.7. Enumerated Types</a></span></dt><dt><span class="sect1"><a href="datatype-geometric.html">8.8. Geometric Types</a></span></dt><dt><span class="sect1"><a href="datatype-net-types.html">8.9. Network Address Types</a></span></dt><dt><span class="sect1"><a href="datatype-bit.html">8.10. Bit String Types</a></span></dt><dt><span class="sect1"><a href="datatype-textsearch.html">8.11. Text Search Types</a></span></dt><dt><span class="sect1"><a href="datatype-uuid.html">8.12. <acronym class="acronym">UUID</acronym> Type</a></span></dt><dt><span class="sect1"><a href="datatype-xml.html">8.13. <acronym class="acronym">XML</acronym> Type</a></span></dt><dt><span class="sect1"><a href="datatype-json.html">8.14. <acronym class="acronym">JSON</acronym> Types</a></span></dt><dt><span class="sect1"><a href="arrays.html">8.15. Arrays</a></span></dt><dt><span class="sect1"><a href="rowtypes.html">8.16. Composite Types</a></span></dt><dt><span class="sect1"><a href="rangetypes.html">8.17. Range Types</a></span></dt><dt><span class="sect1"><a href="domains.html">8.18. Domain Types</a></span></dt><dt><span class="sect1"><a href="datatype-oid.html">8.19. Object Identifier Types</a></span></dt><dt><span class="sect1"><a href="datatype-pg-lsn.html">8.20. <code class="type">pg_lsn</code> Type</a></span></dt><dt><span class="sect1"><a href="datatype-pseudo.html">8.21. Pseudo-Types</a></span></dt></dl></dd><dt><span class="chapter"><a href="functions.html">9. Functions and Operators</a></span></dt><dd><dl><dt><span class="sect1"><a href="functions-logical.html">9.1. Logical Operators</a></span></dt><dt><span class="sect1"><a href="functions-comparison.html">9.2. Comparison Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-math.html">9.3. Mathematical Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-string.html">9.4. String Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-binarystring.html">9.5. Binary String Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-bitstring.html">9.6. Bit String Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-matching.html">9.7. Pattern Matching</a></span></dt><dt><span class="sect1"><a href="functions-formatting.html">9.8. Data Type Formatting Functions</a></span></dt><dt><span class="sect1"><a href="functions-datetime.html">9.9. Date/Time Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-enum.html">9.10. Enum Support Functions</a></span></dt><dt><span class="sect1"><a href="functions-geometry.html">9.11. Geometric Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-net.html">9.12. Network Address Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-textsearch.html">9.13. Text Search Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-uuid.html">9.14. UUID Functions</a></span></dt><dt><span class="sect1"><a href="functions-xml.html">9.15. XML Functions</a></span></dt><dt><span class="sect1"><a href="functions-json.html">9.16. JSON Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-sequence.html">9.17. Sequence Manipulation Functions</a></span></dt><dt><span class="sect1"><a href="functions-conditional.html">9.18. Conditional Expressions</a></span></dt><dt><span class="sect1"><a href="functions-array.html">9.19. Array Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-range.html">9.20. Range/Multirange Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-aggregate.html">9.21. Aggregate Functions</a></span></dt><dt><span class="sect1"><a href="functions-window.html">9.22. Window Functions</a></span></dt><dt><span class="sect1"><a href="functions-subquery.html">9.23. Subquery Expressions</a></span></dt><dt><span class="sect1"><a href="functions-comparisons.html">9.24. Row and Array Comparisons</a></span></dt><dt><span class="sect1"><a href="functions-srf.html">9.25. Set Returning Functions</a></span></dt><dt><span class="sect1"><a href="functions-info.html">9.26. System Information Functions and Operators</a></span></dt><dt><span class="sect1"><a href="functions-admin.html">9.27. System Administration Functions</a></span></dt><dt><span class="sect1"><a href="functions-trigger.html">9.28. Trigger Functions</a></span></dt><dt><span class="sect1"><a href="functions-event-triggers.html">9.29. Event Trigger Functions</a></span></dt><dt><span class="sect1"><a href="functions-statistics.html">9.30. Statistics Information Functions</a></span></dt></dl></dd><dt><span class="chapter"><a href="typeconv.html">10. Type Conversion</a></span></dt><dd><dl><dt><span class="sect1"><a href="typeconv-overview.html">10.1. Overview</a></span></dt><dt><span class="sect1"><a href="typeconv-oper.html">10.2. Operators</a></span></dt><dt><span class="sect1"><a href="typeconv-func.html">10.3. Functions</a></span></dt><dt><span class="sect1"><a href="typeconv-query.html">10.4. Value Storage</a></span></dt><dt><span class="sect1"><a href="typeconv-union-case.html">10.5. <code class="literal">UNION</code>, <code class="literal">CASE</code>, and Related Constructs</a></span></dt><dt><span class="sect1"><a href="typeconv-select.html">10.6. <code class="literal">SELECT</code> Output Columns</a></span></dt></dl></dd><dt><span class="chapter"><a href="indexes.html">11. Indexes</a></span></dt><dd><dl><dt><span class="sect1"><a href="indexes-intro.html">11.1. Introduction</a></span></dt><dt><span class="sect1"><a href="indexes-types.html">11.2. Index Types</a></span></dt><dt><span class="sect1"><a href="indexes-multicolumn.html">11.3. Multicolumn Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-ordering.html">11.4. Indexes and <code class="literal">ORDER BY</code></a></span></dt><dt><span class="sect1"><a href="indexes-bitmap-scans.html">11.5. Combining Multiple Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-unique.html">11.6. Unique Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-expressional.html">11.7. Indexes on Expressions</a></span></dt><dt><span class="sect1"><a href="indexes-partial.html">11.8. Partial Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-index-only-scans.html">11.9. Index-Only Scans and Covering Indexes</a></span></dt><dt><span class="sect1"><a href="indexes-opclass.html">11.10. Operator Classes and Operator Families</a></span></dt><dt><span class="sect1"><a href="indexes-collations.html">11.11. Indexes and Collations</a></span></dt><dt><span class="sect1"><a href="indexes-examine.html">11.12. Examining Index Usage</a></span></dt></dl></dd><dt><span class="chapter"><a href="textsearch.html">12. Full Text Search</a></span></dt><dd><dl><dt><span class="sect1"><a href="textsearch-intro.html">12.1. Introduction</a></span></dt><dt><span class="sect1"><a href="textsearch-tables.html">12.2. Tables and Indexes</a></span></dt><dt><span class="sect1"><a href="textsearch-controls.html">12.3. Controlling Text Search</a></span></dt><dt><span class="sect1"><a href="textsearch-features.html">12.4. Additional Features</a></span></dt><dt><span class="sect1"><a href="textsearch-parsers.html">12.5. Parsers</a></span></dt><dt><span class="sect1"><a href="textsearch-dictionaries.html">12.6. Dictionaries</a></span></dt><dt><span class="sect1"><a href="textsearch-configuration.html">12.7. Configuration Example</a></span></dt><dt><span class="sect1"><a href="textsearch-debugging.html">12.8. Testing and Debugging Text Search</a></span></dt><dt><span class="sect1"><a href="textsearch-indexes.html">12.9. Preferred Index Types for Text Search</a></span></dt><dt><span class="sect1"><a href="textsearch-psql.html">12.10. <span class="application">psql</span> Support</a></span></dt><dt><span class="sect1"><a href="textsearch-limitations.html">12.11. Limitations</a></span></dt></dl></dd><dt><span class="chapter"><a href="mvcc.html">13. Concurrency Control</a></span></dt><dd><dl><dt><span class="sect1"><a href="mvcc-intro.html">13.1. Introduction</a></span></dt><dt><span class="sect1"><a href="transaction-iso.html">13.2. Transaction Isolation</a></span></dt><dt><span class="sect1"><a href="explicit-locking.html">13.3. Explicit Locking</a></span></dt><dt><span class="sect1"><a href="applevel-consistency.html">13.4. Data Consistency Checks at the Application Level</a></span></dt><dt><span class="sect1"><a href="mvcc-serialization-failure-handling.html">13.5. Serialization Failure Handling</a></span></dt><dt><span class="sect1"><a href="mvcc-caveats.html">13.6. Caveats</a></span></dt><dt><span class="sect1"><a href="locking-indexes.html">13.7. Locking and Indexes</a></span></dt></dl></dd><dt><span class="chapter"><a href="performance-tips.html">14. Performance Tips</a></span></dt><dd><dl><dt><span class="sect1"><a href="using-explain.html">14.1. Using <code class="command">EXPLAIN</code></a></span></dt><dt><span class="sect1"><a href="planner-stats.html">14.2. Statistics Used by the Planner</a></span></dt><dt><span class="sect1"><a href="explicit-joins.html">14.3. Controlling the Planner with Explicit <code class="literal">JOIN</code> Clauses</a></span></dt><dt><span class="sect1"><a href="populate.html">14.4. Populating a Database</a></span></dt><dt><span class="sect1"><a href="non-durability.html">14.5. Non-Durable Settings</a></span></dt></dl></dd><dt><span class="chapter"><a href="parallel-query.html">15. Parallel Query</a></span></dt><dd><dl><dt><span class="sect1"><a href="how-parallel-query-works.html">15.1. How Parallel Query Works</a></span></dt><dt><span class="sect1"><a href="when-can-parallel-query-be-used.html">15.2. When Can Parallel Query Be Used?</a></span></dt><dt><span class="sect1"><a href="parallel-plans.html">15.3. Parallel Plans</a></span></dt><dt><span class="sect1"><a href="parallel-safety.html">15.4. Parallel Safety</a></span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-conclusion.html" title="3.7. Conclusion">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-syntax.html" title="Chapter 4. SQL Syntax">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.7. Conclusion </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 4. SQL Syntax</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ssh-tunnels.html b/doc/src/sgml/html/ssh-tunnels.html
new file mode 100644
index 0000000..01b31d2
--- /dev/null
+++ b/doc/src/sgml/html/ssh-tunnels.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.11. Secure TCP/IP Connections with SSH Tunnels</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption" /><link rel="next" href="event-log-registration.html" title="19.12. Registering Event Log on Windows" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.11. Secure TCP/IP Connections with <span class="application">SSH</span> Tunnels</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-log-registration.html" title="19.12. Registering Event Log on Windows">Next</a></td></tr></table><hr /></div><div class="sect1" id="SSH-TUNNELS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.11. Secure TCP/IP Connections with <span class="application">SSH</span> Tunnels</h2></div></div></div><a id="id-1.6.6.14.2" class="indexterm"></a><p>
+ It is possible to use <span class="application">SSH</span> to encrypt the network
+ connection between clients and a
+ <span class="productname">PostgreSQL</span> server. Done properly, this
+ provides an adequately secure network connection, even for non-SSL-capable
+ clients.
+ </p><p>
+ First make sure that an <span class="application">SSH</span> server is
+ running properly on the same machine as the
+ <span class="productname">PostgreSQL</span> server and that you can log in using
+ <code class="command">ssh</code> as some user; you then can establish a
+ secure tunnel to the remote server. A secure tunnel listens on a
+ local port and forwards all traffic to a port on the remote machine.
+ Traffic sent to the remote port can arrive on its
+ <code class="literal">localhost</code> address, or different bind
+ address if desired; it does not appear as coming from your
+ local machine. This command creates a secure tunnel from the client
+ machine to the remote machine <code class="literal">foo.com</code>:
+</p><pre class="programlisting">
+ssh -L 63333:localhost:5432 joe@foo.com
+</pre><p>
+ The first number in the <code class="option">-L</code> argument, 63333, is the
+ local port number of the tunnel; it can be any unused port. (IANA
+ reserves ports 49152 through 65535 for private use.) The name or IP
+ address after this is the remote bind address you are connecting to,
+ i.e., <code class="literal">localhost</code>, which is the default. The second
+ number, 5432, is the remote end of the tunnel, e.g., the port number
+ your database server is using. In order to connect to the database
+ server using this tunnel, you connect to port 63333 on the local
+ machine:
+</p><pre class="programlisting">
+psql -h localhost -p 63333 postgres
+</pre><p>
+ To the database server it will then look as though you are
+ user <code class="literal">joe</code> on host <code class="literal">foo.com</code>
+ connecting to the <code class="literal">localhost</code> bind address, and it
+ will use whatever authentication procedure was configured for
+ connections by that user to that bind address. Note that the server will not
+ think the connection is SSL-encrypted, since in fact it is not
+ encrypted between the
+ <span class="application">SSH</span> server and the
+ <span class="productname">PostgreSQL</span> server. This should not pose any
+ extra security risk because they are on the same machine.
+ </p><p>
+ In order for the
+ tunnel setup to succeed you must be allowed to connect via
+ <code class="command">ssh</code> as <code class="literal">joe@foo.com</code>, just
+ as if you had attempted to use <code class="command">ssh</code> to create a
+ terminal session.
+ </p><p>
+ You could also have set up port forwarding as
+</p><pre class="programlisting">
+ssh -L 63333:foo.com:5432 joe@foo.com
+</pre><p>
+ but then the database server will see the connection as coming in
+ on its <code class="literal">foo.com</code> bind address, which is not opened by
+ the default setting <code class="literal">listen_addresses =
+ 'localhost'</code>. This is usually not what you want.
+ </p><p>
+ If you have to <span class="quote">“<span class="quote">hop</span>”</span> to the database server via some
+ login host, one possible setup could look like this:
+</p><pre class="programlisting">
+ssh -L 63333:db.foo.com:5432 joe@shell.foo.com
+</pre><p>
+ Note that this way the connection
+ from <code class="literal">shell.foo.com</code>
+ to <code class="literal">db.foo.com</code> will not be encrypted by the SSH
+ tunnel.
+ SSH offers quite a few configuration possibilities when the network
+ is restricted in various ways. Please refer to the SSH
+ documentation for details.
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Several other applications exist that can provide secure tunnels using
+ a procedure similar in concept to the one just described.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-log-registration.html" title="19.12. Registering Event Log on Windows">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.10. Secure TCP/IP Connections with GSSAPI Encryption </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.12. Registering <span class="application">Event Log</span> on <span class="systemitem">Windows</span></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/ssl-tcp.html b/doc/src/sgml/html/ssl-tcp.html
new file mode 100644
index 0000000..832f2a4
--- /dev/null
+++ b/doc/src/sgml/html/ssl-tcp.html
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.9. Secure TCP/IP Connections with SSL</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="encryption-options.html" title="19.8. Encryption Options" /><link rel="next" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.9. Secure TCP/IP Connections with SSL</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="encryption-options.html" title="19.8. Encryption Options">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption">Next</a></td></tr></table><hr /></div><div class="sect1" id="SSL-TCP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.9. Secure TCP/IP Connections with SSL</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="ssl-tcp.html#SSL-SETUP">19.9.1. Basic Setup</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-OPENSSL-CONFIG">19.9.2. OpenSSL Configuration</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-CLIENT-CERTIFICATES">19.9.3. Using Client Certificates</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-SERVER-FILES">19.9.4. SSL Server File Usage</a></span></dt><dt><span class="sect2"><a href="ssl-tcp.html#SSL-CERTIFICATE-CREATION">19.9.5. Creating Certificates</a></span></dt></dl></div><a id="id-1.6.6.12.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> has native support for using
+ <acronym class="acronym">SSL</acronym> connections to encrypt client/server communications
+ for increased security. This requires that
+ <span class="productname">OpenSSL</span> is installed on both client and
+ server systems and that support in <span class="productname">PostgreSQL</span> is
+ enabled at build time (see <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a>).
+ </p><p>
+ The terms <acronym class="acronym">SSL</acronym> and <acronym class="acronym">TLS</acronym> are often used
+ interchangeably to mean a secure encrypted connection using a
+ <acronym class="acronym">TLS</acronym> protocol. <acronym class="acronym">SSL</acronym> protocols are the
+ precursors to <acronym class="acronym">TLS</acronym> protocols, and the term
+ <acronym class="acronym">SSL</acronym> is still used for encrypted connections even though
+ <acronym class="acronym">SSL</acronym> protocols are no longer supported.
+ <acronym class="acronym">SSL</acronym> is used interchangeably with <acronym class="acronym">TLS</acronym>
+ in <span class="productname">PostgreSQL</span>.
+
+ </p><div class="sect2" id="SSL-SETUP"><div class="titlepage"><div><div><h3 class="title">19.9.1. Basic Setup</h3></div></div></div><p>
+ With <acronym class="acronym">SSL</acronym> support compiled in, the
+ <span class="productname">PostgreSQL</span> server can be started with
+ support for encrypted connections using <acronym class="acronym">TLS</acronym> protocols
+ enabled by setting the parameter
+ <a class="xref" href="runtime-config-connection.html#GUC-SSL">ssl</a> to <code class="literal">on</code> in
+ <code class="filename">postgresql.conf</code>. The server will listen for both normal
+ and <acronym class="acronym">SSL</acronym> connections on the same TCP port, and will negotiate
+ with any connecting client on whether to use <acronym class="acronym">SSL</acronym>. By
+ default, this is at the client's option; see <a class="xref" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">Section 21.1</a> about how to set up the server to require
+ use of <acronym class="acronym">SSL</acronym> for some or all connections.
+ </p><p>
+ To start in <acronym class="acronym">SSL</acronym> mode, files containing the server certificate
+ and private key must exist. By default, these files are expected to be
+ named <code class="filename">server.crt</code> and <code class="filename">server.key</code>, respectively, in
+ the server's data directory, but other names and locations can be specified
+ using the configuration parameters <a class="xref" href="runtime-config-connection.html#GUC-SSL-CERT-FILE">ssl_cert_file</a>
+ and <a class="xref" href="runtime-config-connection.html#GUC-SSL-KEY-FILE">ssl_key_file</a>.
+ </p><p>
+ On Unix systems, the permissions on <code class="filename">server.key</code> must
+ disallow any access to world or group; achieve this by the command
+ <code class="command">chmod 0600 server.key</code>. Alternatively, the file can be
+ owned by root and have group read access (that is, <code class="literal">0640</code>
+ permissions). That setup is intended for installations where certificate
+ and key files are managed by the operating system. The user under which
+ the <span class="productname">PostgreSQL</span> server runs should then be made a
+ member of the group that has access to those certificate and key files.
+ </p><p>
+ If the data directory allows group read access then certificate files may
+ need to be located outside of the data directory in order to conform to the
+ security requirements outlined above. Generally, group access is enabled
+ to allow an unprivileged user to backup the database, and in that case the
+ backup software will not be able to read the certificate files and will
+ likely error.
+ </p><p>
+ If the private key is protected with a passphrase, the
+ server will prompt for the passphrase and will not start until it has
+ been entered.
+ Using a passphrase by default disables the ability to change the server's
+ SSL configuration without a server restart, but see <a class="xref" href="runtime-config-connection.html#GUC-SSL-PASSPHRASE-COMMAND-SUPPORTS-RELOAD">ssl_passphrase_command_supports_reload</a>.
+ Furthermore, passphrase-protected private keys cannot be used at all
+ on Windows.
+ </p><p>
+ The first certificate in <code class="filename">server.crt</code> must be the
+ server's certificate because it must match the server's private key.
+ The certificates of <span class="quote">“<span class="quote">intermediate</span>”</span> certificate authorities
+ can also be appended to the file. Doing this avoids the necessity of
+ storing intermediate certificates on clients, assuming the root and
+ intermediate certificates were created with <code class="literal">v3_ca</code>
+ extensions. (This sets the certificate's basic constraint of
+ <code class="literal">CA</code> to <code class="literal">true</code>.)
+ This allows easier expiration of intermediate certificates.
+ </p><p>
+ It is not necessary to add the root certificate to
+ <code class="filename">server.crt</code>. Instead, clients must have the root
+ certificate of the server's certificate chain.
+ </p></div><div class="sect2" id="SSL-OPENSSL-CONFIG"><div class="titlepage"><div><div><h3 class="title">19.9.2. OpenSSL Configuration</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> reads the system-wide
+ <span class="productname">OpenSSL</span> configuration file. By default, this
+ file is named <code class="filename">openssl.cnf</code> and is located in the
+ directory reported by <code class="literal">openssl version -d</code>.
+ This default can be overridden by setting environment variable
+ <code class="envar">OPENSSL_CONF</code> to the name of the desired configuration file.
+ </p><p>
+ <span class="productname">OpenSSL</span> supports a wide range of ciphers
+ and authentication algorithms, of varying strength. While a list of
+ ciphers can be specified in the <span class="productname">OpenSSL</span>
+ configuration file, you can specify ciphers specifically for use by
+ the database server by modifying <a class="xref" href="runtime-config-connection.html#GUC-SSL-CIPHERS">ssl_ciphers</a> in
+ <code class="filename">postgresql.conf</code>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ It is possible to have authentication without encryption overhead by
+ using <code class="literal">NULL-SHA</code> or <code class="literal">NULL-MD5</code> ciphers. However,
+ a man-in-the-middle could read and pass communications between client
+ and server. Also, encryption overhead is minimal compared to the
+ overhead of authentication. For these reasons NULL ciphers are not
+ recommended.
+ </p></div></div><div class="sect2" id="SSL-CLIENT-CERTIFICATES"><div class="titlepage"><div><div><h3 class="title">19.9.3. Using Client Certificates</h3></div></div></div><p>
+ To require the client to supply a trusted certificate,
+ place certificates of the root certificate authorities
+ (<acronym class="acronym">CA</acronym>s) you trust in a file in the data
+ directory, set the parameter <a class="xref" href="runtime-config-connection.html#GUC-SSL-CA-FILE">ssl_ca_file</a> in
+ <code class="filename">postgresql.conf</code> to the new file name, and add the
+ authentication option <code class="literal">clientcert=verify-ca</code> or
+ <code class="literal">clientcert=verify-full</code> to the appropriate
+ <code class="literal">hostssl</code> line(s) in <code class="filename">pg_hba.conf</code>.
+ A certificate will then be requested from the client during SSL
+ connection startup. (See <a class="xref" href="libpq-ssl.html" title="34.19. SSL Support">Section 34.19</a> for a description
+ of how to set up certificates on the client.)
+ </p><p>
+ For a <code class="literal">hostssl</code> entry with
+ <code class="literal">clientcert=verify-ca</code>, the server will verify
+ that the client's certificate is signed by one of the trusted
+ certificate authorities. If <code class="literal">clientcert=verify-full</code>
+ is specified, the server will not only verify the certificate
+ chain, but it will also check whether the username or its mapping
+ matches the <code class="literal">cn</code> (Common Name) of the provided certificate.
+ Note that certificate chain validation is always ensured when the
+ <code class="literal">cert</code> authentication method is used
+ (see <a class="xref" href="auth-cert.html" title="21.12. Certificate Authentication">Section 21.12</a>).
+ </p><p>
+ Intermediate certificates that chain up to existing root certificates
+ can also appear in the <a class="xref" href="runtime-config-connection.html#GUC-SSL-CA-FILE">ssl_ca_file</a> file if
+ you wish to avoid storing them on clients (assuming the root and
+ intermediate certificates were created with <code class="literal">v3_ca</code>
+ extensions). Certificate Revocation List (CRL) entries are also
+ checked if the parameter <a class="xref" href="runtime-config-connection.html#GUC-SSL-CRL-FILE">ssl_crl_file</a> or
+ <a class="xref" href="runtime-config-connection.html#GUC-SSL-CRL-DIR">ssl_crl_dir</a> is set.
+ </p><p>
+ The <code class="literal">clientcert</code> authentication option is available for
+ all authentication methods, but only in <code class="filename">pg_hba.conf</code> lines
+ specified as <code class="literal">hostssl</code>. When <code class="literal">clientcert</code> is
+ not specified, the server verifies the client certificate against its CA
+ file only if a client certificate is presented and the CA is configured.
+ </p><p>
+ There are two approaches to enforce that users provide a certificate during login.
+ </p><p>
+ The first approach makes use of the <code class="literal">cert</code> authentication
+ method for <code class="literal">hostssl</code> entries in <code class="filename">pg_hba.conf</code>,
+ such that the certificate itself is used for authentication while also
+ providing ssl connection security. See <a class="xref" href="auth-cert.html" title="21.12. Certificate Authentication">Section 21.12</a> for details.
+ (It is not necessary to specify any <code class="literal">clientcert</code> options
+ explicitly when using the <code class="literal">cert</code> authentication method.)
+ In this case, the <code class="literal">cn</code> (Common Name) provided in
+ the certificate is checked against the user name or an applicable mapping.
+ </p><p>
+ The second approach combines any authentication method for <code class="literal">hostssl</code>
+ entries with the verification of client certificates by setting the
+ <code class="literal">clientcert</code> authentication option to <code class="literal">verify-ca</code>
+ or <code class="literal">verify-full</code>. The former option only enforces that
+ the certificate is valid, while the latter also ensures that the
+ <code class="literal">cn</code> (Common Name) in the certificate matches
+ the user name or an applicable mapping.
+ </p></div><div class="sect2" id="SSL-SERVER-FILES"><div class="titlepage"><div><div><h3 class="title">19.9.4. SSL Server File Usage</h3></div></div></div><p>
+ <a class="xref" href="ssl-tcp.html#SSL-FILE-USAGE" title="Table 19.2. SSL Server File Usage">Table 19.2</a> summarizes the files that are
+ relevant to the SSL setup on the server. (The shown file names are default
+ names. The locally configured names could be different.)
+ </p><div class="table" id="SSL-FILE-USAGE"><p class="title"><strong>Table 19.2. SSL Server File Usage</strong></p><div class="table-contents"><table class="table" summary="SSL Server File Usage" border="1"><colgroup><col /><col /><col /></colgroup><thead><tr><th>File</th><th>Contents</th><th>Effect</th></tr></thead><tbody><tr><td><a class="xref" href="runtime-config-connection.html#GUC-SSL-CERT-FILE">ssl_cert_file</a> (<code class="filename">$PGDATA/server.crt</code>)</td><td>server certificate</td><td>sent to client to indicate server's identity</td></tr><tr><td><a class="xref" href="runtime-config-connection.html#GUC-SSL-KEY-FILE">ssl_key_file</a> (<code class="filename">$PGDATA/server.key</code>)</td><td>server private key</td><td>proves server certificate was sent by the owner; does not indicate
+ certificate owner is trustworthy</td></tr><tr><td><a class="xref" href="runtime-config-connection.html#GUC-SSL-CA-FILE">ssl_ca_file</a></td><td>trusted certificate authorities</td><td>checks that client certificate is
+ signed by a trusted certificate authority</td></tr><tr><td><a class="xref" href="runtime-config-connection.html#GUC-SSL-CRL-FILE">ssl_crl_file</a></td><td>certificates revoked by certificate authorities</td><td>client certificate must not be on this list</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The server reads these files at server start and whenever the server
+ configuration is reloaded. On <span class="systemitem">Windows</span>
+ systems, they are also re-read whenever a new backend process is spawned
+ for a new client connection.
+ </p><p>
+ If an error in these files is detected at server start, the server will
+ refuse to start. But if an error is detected during a configuration
+ reload, the files are ignored and the old SSL configuration continues to
+ be used. On <span class="systemitem">Windows</span> systems, if an error in
+ these files is detected at backend start, that backend will be unable to
+ establish an SSL connection. In all these cases, the error condition is
+ reported in the server log.
+ </p></div><div class="sect2" id="SSL-CERTIFICATE-CREATION"><div class="titlepage"><div><div><h3 class="title">19.9.5. Creating Certificates</h3></div></div></div><p>
+ To create a simple self-signed certificate for the server, valid for 365
+ days, use the following <span class="productname">OpenSSL</span> command,
+ replacing <em class="replaceable"><code>dbhost.yourdomain.com</code></em> with the
+ server's host name:
+</p><pre class="programlisting">
+openssl req -new -x509 -days 365 -nodes -text -out server.crt \
+ -keyout server.key -subj "/CN=<em class="replaceable"><code>dbhost.yourdomain.com</code></em>"
+</pre><p>
+ Then do:
+</p><pre class="programlisting">
+chmod og-rwx server.key
+</pre><p>
+ because the server will reject the file if its permissions are more
+ liberal than this.
+ For more details on how to create your server private key and
+ certificate, refer to the <span class="productname">OpenSSL</span> documentation.
+ </p><p>
+ While a self-signed certificate can be used for testing, a certificate
+ signed by a certificate authority (<acronym class="acronym">CA</acronym>) (usually an
+ enterprise-wide root <acronym class="acronym">CA</acronym>) should be used in production.
+ </p><p>
+ To create a server certificate whose identity can be validated
+ by clients, first create a certificate signing request
+ (<acronym class="acronym">CSR</acronym>) and a public/private key file:
+</p><pre class="programlisting">
+openssl req -new -nodes -text -out root.csr \
+ -keyout root.key -subj "/CN=<em class="replaceable"><code>root.yourdomain.com</code></em>"
+chmod og-rwx root.key
+</pre><p>
+ Then, sign the request with the key to create a root certificate
+ authority (using the default <span class="productname">OpenSSL</span>
+ configuration file location on <span class="productname">Linux</span>):
+</p><pre class="programlisting">
+openssl x509 -req -in root.csr -text -days 3650 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -signkey root.key -out root.crt
+</pre><p>
+ Finally, create a server certificate signed by the new root certificate
+ authority:
+</p><pre class="programlisting">
+openssl req -new -nodes -text -out server.csr \
+ -keyout server.key -subj "/CN=<em class="replaceable"><code>dbhost.yourdomain.com</code></em>"
+chmod og-rwx server.key
+
+openssl x509 -req -in server.csr -text -days 365 \
+ -CA root.crt -CAkey root.key -CAcreateserial \
+ -out server.crt
+</pre><p>
+ <code class="filename">server.crt</code> and <code class="filename">server.key</code>
+ should be stored on the server, and <code class="filename">root.crt</code> should
+ be stored on the client so the client can verify that the server's leaf
+ certificate was signed by its trusted root certificate.
+ <code class="filename">root.key</code> should be stored offline for use in
+ creating future certificates.
+ </p><p>
+ It is also possible to create a chain of trust that includes
+ intermediate certificates:
+</p><pre class="programlisting">
+# root
+openssl req -new -nodes -text -out root.csr \
+ -keyout root.key -subj "/CN=<em class="replaceable"><code>root.yourdomain.com</code></em>"
+chmod og-rwx root.key
+openssl x509 -req -in root.csr -text -days 3650 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -signkey root.key -out root.crt
+
+# intermediate
+openssl req -new -nodes -text -out intermediate.csr \
+ -keyout intermediate.key -subj "/CN=<em class="replaceable"><code>intermediate.yourdomain.com</code></em>"
+chmod og-rwx intermediate.key
+openssl x509 -req -in intermediate.csr -text -days 1825 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -CA root.crt -CAkey root.key -CAcreateserial \
+ -out intermediate.crt
+
+# leaf
+openssl req -new -nodes -text -out server.csr \
+ -keyout server.key -subj "/CN=<em class="replaceable"><code>dbhost.yourdomain.com</code></em>"
+chmod og-rwx server.key
+openssl x509 -req -in server.csr -text -days 365 \
+ -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
+ -out server.crt
+</pre><p>
+ <code class="filename">server.crt</code> and
+ <code class="filename">intermediate.crt</code> should be concatenated
+ into a certificate file bundle and stored on the server.
+ <code class="filename">server.key</code> should also be stored on the server.
+ <code class="filename">root.crt</code> should be stored on the client so
+ the client can verify that the server's leaf certificate was signed
+ by a chain of certificates linked to its trusted root certificate.
+ <code class="filename">root.key</code> and <code class="filename">intermediate.key</code>
+ should be stored offline for use in creating future certificates.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="encryption-options.html" title="19.8. Encryption Options">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="gssapi-enc.html" title="19.10. Secure TCP/IP Connections with GSSAPI Encryption">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.8. Encryption Options </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.10. Secure TCP/IP Connections with GSSAPI Encryption</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sslinfo.html b/doc/src/sgml/html/sslinfo.html
new file mode 100644
index 0000000..dc99b20
--- /dev/null
+++ b/doc/src/sgml/html/sslinfo.html
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.42. sslinfo</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="contrib-spi.html" title="F.41. spi" /><link rel="next" href="tablefunc.html" title="F.43. tablefunc" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.42. sslinfo</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="contrib-spi.html" title="F.41. spi">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tablefunc.html" title="F.43. tablefunc">Next</a></td></tr></table><hr /></div><div class="sect1" id="SSLINFO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.42. sslinfo</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="sslinfo.html#id-1.11.7.51.6">F.42.1. Functions Provided</a></span></dt><dt><span class="sect2"><a href="sslinfo.html#id-1.11.7.51.7">F.42.2. Author</a></span></dt></dl></div><a id="id-1.11.7.51.2" class="indexterm"></a><p>
+ The <code class="filename">sslinfo</code> module provides information about the SSL
+ certificate that the current client provided when connecting to
+ <span class="productname">PostgreSQL</span>. The module is useless (most functions
+ will return NULL) if the current connection does not use SSL.
+ </p><p>
+ Some of the information available through this module can also be obtained
+ using the built-in system view <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-SSL-VIEW" title="28.2.10. pg_stat_ssl">
+ <code class="structname">pg_stat_ssl</code></a>.
+ </p><p>
+ This extension won't build at all unless the installation was
+ configured with <code class="literal">--with-ssl=openssl</code>.
+ </p><div class="sect2" id="id-1.11.7.51.6"><div class="titlepage"><div><div><h3 class="title">F.42.1. Functions Provided</h3></div></div></div><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="function">ssl_is_used() returns boolean</code>
+ <a id="id-1.11.7.51.6.2.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns true if current connection to server uses SSL, and false
+ otherwise.
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_version() returns text</code>
+ <a id="id-1.11.7.51.6.2.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0,
+ TLSv1.1, TLSv1.2 or TLSv1.3).
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_cipher() returns text</code>
+ <a id="id-1.11.7.51.6.2.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns the name of the cipher used for the SSL connection
+ (e.g., DHE-RSA-AES256-SHA).
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_client_cert_present() returns boolean</code>
+ <a id="id-1.11.7.51.6.2.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns true if current client has presented a valid SSL client
+ certificate to the server, and false otherwise. (The server
+ might or might not be configured to require a client certificate.)
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_client_serial() returns numeric</code>
+ <a id="id-1.11.7.51.6.2.5.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns serial number of current client certificate. The combination of
+ certificate serial number and certificate issuer is guaranteed to
+ uniquely identify a certificate (but not its owner — the owner
+ ought to regularly change their keys, and get new certificates from the
+ issuer).
+ </p><p>
+ So, if you run your own CA and allow only certificates from this CA to
+ be accepted by the server, the serial number is the most reliable (albeit
+ not very mnemonic) means to identify a user.
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_client_dn() returns text</code>
+ <a id="id-1.11.7.51.6.2.6.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns the full subject of the current client certificate, converting
+ character data into the current database encoding. It is assumed that
+ if you use non-ASCII characters in the certificate names, your
+ database is able to represent these characters, too. If your database
+ uses the SQL_ASCII encoding, non-ASCII characters in the name will be
+ represented as UTF-8 sequences.
+ </p><p>
+ The result looks like <code class="literal">/CN=Somebody /C=Some country/O=Some organization</code>.
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_issuer_dn() returns text</code>
+ <a id="id-1.11.7.51.6.2.7.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Returns the full issuer name of the current client certificate, converting
+ character data into the current database encoding. Encoding conversions
+ are handled the same as for <code class="function">ssl_client_dn</code>.
+ </p><p>
+ The combination of the return value of this function with the
+ certificate serial number uniquely identifies the certificate.
+ </p><p>
+ This function is really useful only if you have more than one trusted CA
+ certificate in your server's certificate authority file, or if this CA
+ has issued some intermediate certificate authority certificates.
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_client_dn_field(fieldname text) returns text</code>
+ <a id="id-1.11.7.51.6.2.8.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ This function returns the value of the specified field in the
+ certificate subject, or NULL if the field is not present.
+ Field names are string constants that are converted into ASN1 object
+ identifiers using the <span class="productname">OpenSSL</span> object
+ database. The following values are acceptable:
+ </p><pre class="literallayout">
+commonName (alias CN)
+surname (alias SN)
+name
+givenName (alias GN)
+countryName (alias C)
+localityName (alias L)
+stateOrProvinceName (alias ST)
+organizationName (alias O)
+organizationalUnitName (alias OU)
+title
+description
+initials
+postalCode
+streetAddress
+generationQualifier
+description
+dnQualifier
+x500UniqueIdentifier
+pseudonym
+role
+emailAddress
+</pre><p>
+ All of these fields are optional, except <code class="structfield">commonName</code>.
+ It depends
+ entirely on your CA's policy which of them would be included and which
+ wouldn't. The meaning of these fields, however, is strictly defined by
+ the X.500 and X.509 standards, so you cannot just assign arbitrary
+ meaning to them.
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_issuer_field(fieldname text) returns text</code>
+ <a id="id-1.11.7.51.6.2.9.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Same as <code class="function">ssl_client_dn_field</code>, but for the certificate issuer
+ rather than the certificate subject.
+ </p></dd><dt><span class="term">
+ <code class="function">ssl_extension_info() returns setof record</code>
+ <a id="id-1.11.7.51.6.2.10.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Provide information about extensions of client certificate: extension name,
+ extension value, and if it is a critical extension.
+ </p></dd></dl></div></div><div class="sect2" id="id-1.11.7.51.7"><div class="titlepage"><div><div><h3 class="title">F.42.2. Author</h3></div></div></div><p>
+ Victor Wagner <code class="email">&lt;<a class="email" href="mailto:vitus@cryptocom.ru">vitus@cryptocom.ru</a>&gt;</code>, Cryptocom LTD
+ </p><p>
+ Dmitry Voronin <code class="email">&lt;<a class="email" href="mailto:carriingfate92@yandex.ru">carriingfate92@yandex.ru</a>&gt;</code>
+ </p><p>
+ E-Mail of Cryptocom OpenSSL development group:
+ <code class="email">&lt;<a class="email" href="mailto:openssl@cryptocom.ru">openssl@cryptocom.ru</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="contrib-spi.html" title="F.41. spi">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tablefunc.html" title="F.43. tablefunc">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.41. spi </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.43. tablefunc</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/sspi-auth.html b/doc/src/sgml/html/sspi-auth.html
new file mode 100644
index 0000000..753ba54
--- /dev/null
+++ b/doc/src/sgml/html/sspi-auth.html
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>21.7. SSPI Authentication</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="gssapi-auth.html" title="21.6. GSSAPI Authentication" /><link rel="next" href="auth-ident.html" title="21.8. Ident Authentication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">21.7. SSPI Authentication</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><th width="60%" align="center">Chapter 21. Client Authentication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="auth-ident.html" title="21.8. Ident Authentication">Next</a></td></tr></table><hr /></div><div class="sect1" id="SSPI-AUTH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">21.7. SSPI Authentication</h2></div></div></div><a id="id-1.6.8.14.2" class="indexterm"></a><p>
+ <span class="productname">SSPI</span> is a <span class="productname">Windows</span>
+ technology for secure authentication with single sign-on.
+ <span class="productname">PostgreSQL</span> will use SSPI in
+ <code class="literal">negotiate</code> mode, which will use
+ <span class="productname">Kerberos</span> when possible and automatically
+ fall back to <span class="productname">NTLM</span> in other cases.
+ <span class="productname">SSPI</span> authentication only works when both
+ server and client are running <span class="productname">Windows</span>,
+ or, on non-Windows platforms, when <span class="productname">GSSAPI</span>
+ is available.
+ </p><p>
+ When using <span class="productname">Kerberos</span> authentication,
+ <span class="productname">SSPI</span> works the same way
+ <span class="productname">GSSAPI</span> does; see <a class="xref" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Section 21.6</a>
+ for details.
+ </p><p>
+ The following configuration options are supported for <span class="productname">SSPI</span>:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">include_realm</code></span></dt><dd><p>
+ If set to 0, the realm name from the authenticated user principal is
+ stripped off before being passed through the user name mapping
+ (<a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a>). This is discouraged and is
+ primarily available for backwards compatibility, as it is not secure
+ in multi-realm environments unless <code class="literal">krb_realm</code> is
+ also used. It is recommended to
+ leave <code class="literal">include_realm</code> set to the default (1) and to
+ provide an explicit mapping in <code class="filename">pg_ident.conf</code> to convert
+ principal names to <span class="productname">PostgreSQL</span> user names.
+ </p></dd><dt><span class="term"><code class="literal">compat_realm</code></span></dt><dd><p>
+ If set to 1, the domain's SAM-compatible name (also known as the
+ NetBIOS name) is used for the <code class="literal">include_realm</code>
+ option. This is the default. If set to 0, the true realm name from
+ the Kerberos user principal name is used.
+ </p><p>
+ Do not disable this option unless your server runs under a domain
+ account (this includes virtual service accounts on a domain member
+ system) and all clients authenticating through SSPI are also using
+ domain accounts, or authentication will fail.
+ </p></dd><dt><span class="term"><code class="literal">upn_username</code></span></dt><dd><p>
+ If this option is enabled along with <code class="literal">compat_realm</code>,
+ the user name from the Kerberos UPN is used for authentication. If
+ it is disabled (the default), the SAM-compatible user name is used.
+ By default, these two names are identical for new user accounts.
+ </p><p>
+ Note that <span class="application">libpq</span> uses the SAM-compatible name if no
+ explicit user name is specified. If you use
+ <span class="application">libpq</span> or a driver based on it, you should
+ leave this option disabled or explicitly specify user name in the
+ connection string.
+ </p></dd><dt><span class="term"><code class="literal">map</code></span></dt><dd><p>
+ Allows for mapping between system and database user names. See
+ <a class="xref" href="auth-username-maps.html" title="21.2. User Name Maps">Section 21.2</a> for details. For an SSPI/Kerberos
+ principal, such as <code class="literal">username@EXAMPLE.COM</code> (or, less
+ commonly, <code class="literal">username/hostbased@EXAMPLE.COM</code>), the
+ user name used for mapping is
+ <code class="literal">username@EXAMPLE.COM</code> (or
+ <code class="literal">username/hostbased@EXAMPLE.COM</code>, respectively),
+ unless <code class="literal">include_realm</code> has been set to 0, in which case
+ <code class="literal">username</code> (or <code class="literal">username/hostbased</code>)
+ is what is seen as the system user name when mapping.
+ </p></dd><dt><span class="term"><code class="literal">krb_realm</code></span></dt><dd><p>
+ Sets the realm to match user principal names against. If this parameter
+ is set, only users of that realm will be accepted. If it is not set,
+ users of any realm can connect, subject to whatever user name mapping
+ is done.
+ </p></dd></dl></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="gssapi-auth.html" title="21.6. GSSAPI Authentication">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="client-authentication.html" title="Chapter 21. Client Authentication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="auth-ident.html" title="21.8. Ident Authentication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.6. GSSAPI Authentication </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 21.8. Ident Authentication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-file-layout.html b/doc/src/sgml/html/storage-file-layout.html
new file mode 100644
index 0000000..5684042
--- /dev/null
+++ b/doc/src/sgml/html/storage-file-layout.html
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.1. Database File Layout</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage.html" title="Chapter 73. Database Physical Storage" /><link rel="next" href="storage-toast.html" title="73.2. TOAST" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.1. Database File Layout</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage.html" title="Chapter 73. Database Physical Storage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-toast.html" title="73.2. TOAST">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-FILE-LAYOUT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.1. Database File Layout</h2></div></div></div><p>
+This section describes the storage format at the level of files and
+directories.
+</p><p>
+Traditionally, the configuration and data files used by a database
+cluster are stored together within the cluster's data
+directory, commonly referred to as <code class="varname">PGDATA</code> (after the name of the
+environment variable that can be used to define it). A common location for
+<code class="varname">PGDATA</code> is <code class="filename">/var/lib/pgsql/data</code>. Multiple clusters,
+managed by different server instances, can exist on the same machine.
+</p><p>
+The <code class="varname">PGDATA</code> directory contains several subdirectories and control
+files, as shown in <a class="xref" href="storage-file-layout.html#PGDATA-CONTENTS-TABLE" title="Table 73.1. Contents of PGDATA">Table 73.1</a>. In addition to
+these required items, the cluster configuration files
+<code class="filename">postgresql.conf</code>, <code class="filename">pg_hba.conf</code>, and
+<code class="filename">pg_ident.conf</code> are traditionally stored in
+<code class="varname">PGDATA</code>, although it is possible to place them elsewhere.
+</p><div class="table" id="PGDATA-CONTENTS-TABLE"><p class="title"><strong>Table 73.1. Contents of <code class="varname">PGDATA</code></strong></p><div class="table-contents"><table class="table" summary="Contents of PGDATA" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>
+Item
+</th><th>Description</th></tr></thead><tbody><tr><td><code class="filename">PG_VERSION</code></td><td>A file containing the major version number of <span class="productname">PostgreSQL</span></td></tr><tr><td><code class="filename">base</code></td><td>Subdirectory containing per-database subdirectories</td></tr><tr><td><code class="filename">current_logfiles</code></td><td>File recording the log file(s) currently written to by the logging
+ collector</td></tr><tr><td><code class="filename">global</code></td><td>Subdirectory containing cluster-wide tables, such as
+ <code class="structname">pg_database</code></td></tr><tr><td><code class="filename">pg_commit_ts</code></td><td>Subdirectory containing transaction commit timestamp data</td></tr><tr><td><code class="filename">pg_dynshmem</code></td><td>Subdirectory containing files used by the dynamic shared memory
+ subsystem</td></tr><tr><td><code class="filename">pg_logical</code></td><td>Subdirectory containing status data for logical decoding</td></tr><tr><td><code class="filename">pg_multixact</code></td><td>Subdirectory containing multitransaction status data
+ (used for shared row locks)</td></tr><tr><td><code class="filename">pg_notify</code></td><td>Subdirectory containing LISTEN/NOTIFY status data</td></tr><tr><td><code class="filename">pg_replslot</code></td><td>Subdirectory containing replication slot data</td></tr><tr><td><code class="filename">pg_serial</code></td><td>Subdirectory containing information about committed serializable transactions</td></tr><tr><td><code class="filename">pg_snapshots</code></td><td>Subdirectory containing exported snapshots</td></tr><tr><td><code class="filename">pg_stat</code></td><td>Subdirectory containing permanent files for the statistics
+ subsystem</td></tr><tr><td><code class="filename">pg_stat_tmp</code></td><td>Subdirectory containing temporary files for the statistics
+ subsystem</td></tr><tr><td><code class="filename">pg_subtrans</code></td><td>Subdirectory containing subtransaction status data</td></tr><tr><td><code class="filename">pg_tblspc</code></td><td>Subdirectory containing symbolic links to tablespaces</td></tr><tr><td><code class="filename">pg_twophase</code></td><td>Subdirectory containing state files for prepared transactions</td></tr><tr><td><code class="filename">pg_wal</code></td><td>Subdirectory containing WAL (Write Ahead Log) files</td></tr><tr><td><code class="filename">pg_xact</code></td><td>Subdirectory containing transaction commit status data</td></tr><tr><td><code class="filename">postgresql.auto.conf</code></td><td>A file used for storing configuration parameters that are set by
+<code class="command">ALTER SYSTEM</code></td></tr><tr><td><code class="filename">postmaster.opts</code></td><td>A file recording the command-line options the server was
+last started with</td></tr><tr><td><code class="filename">postmaster.pid</code></td><td>A lock file recording the current postmaster process ID (PID),
+ cluster data directory path,
+ postmaster start timestamp,
+ port number,
+ Unix-domain socket directory path (could be empty),
+ first valid listen_address (IP address or <code class="literal">*</code>, or empty if
+ not listening on TCP),
+ and shared memory segment ID
+ (this file is not present after server shutdown)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+For each database in the cluster there is a subdirectory within
+<code class="varname">PGDATA</code><code class="filename">/base</code>, named after the database's OID in
+<code class="structname">pg_database</code>. This subdirectory is the default location
+for the database's files; in particular, its system catalogs are stored
+there.
+</p><p>
+ Note that the following sections describe the behavior of the builtin
+ <code class="literal">heap</code> <a class="link" href="tableam.html" title="Chapter 63. Table Access Method Interface Definition">table access method</a>,
+ and the builtin <a class="link" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">index access methods</a>. Due
+ to the extensible nature of <span class="productname">PostgreSQL</span>, other
+ access methods might work differently.
+</p><p>
+Each table and index is stored in a separate file. For ordinary relations,
+these files are named after the table or index's <em class="firstterm">filenode</em> number,
+which can be found in <code class="structname">pg_class</code>.<code class="structfield">relfilenode</code>. But
+for temporary relations, the file name is of the form
+<code class="literal">t<em class="replaceable"><code>BBB</code></em>_<em class="replaceable"><code>FFF</code></em></code>, where <em class="replaceable"><code>BBB</code></em>
+is the backend ID of the backend which created the file, and <em class="replaceable"><code>FFF</code></em>
+is the filenode number. In either case, in addition to the main file (a/k/a
+main fork), each table and index has a <em class="firstterm">free space map</em> (see <a class="xref" href="storage-fsm.html" title="73.3. Free Space Map">Section 73.3</a>), which stores information about free space available in
+the relation. The free space map is stored in a file named with the filenode
+number plus the suffix <code class="literal">_fsm</code>. Tables also have a
+<em class="firstterm">visibility map</em>, stored in a fork with the suffix <code class="literal">_vm</code>,
+to track which pages are known to have no dead tuples. The visibility map is
+described further in <a class="xref" href="storage-vm.html" title="73.4. Visibility Map">Section 73.4</a>. Unlogged tables and indexes
+have a third fork, known as the initialization fork, which is stored in a fork
+with the suffix <code class="literal">_init</code> (see <a class="xref" href="storage-init.html" title="73.5. The Initialization Fork">Section 73.5</a>).
+</p><div class="caution"><h3 class="title">Caution</h3><p>
+Note that while a table's filenode often matches its OID, this is
+<span class="emphasis"><em>not</em></span> necessarily the case; some operations, like
+<code class="command">TRUNCATE</code>, <code class="command">REINDEX</code>, <code class="command">CLUSTER</code> and some forms
+of <code class="command">ALTER TABLE</code>, can change the filenode while preserving the OID.
+Avoid assuming that filenode and table OID are the same.
+Also, for certain system catalogs including <code class="structname">pg_class</code> itself,
+<code class="structname">pg_class</code>.<code class="structfield">relfilenode</code> contains zero. The
+actual filenode number of these catalogs is stored in a lower-level data
+structure, and can be obtained using the <code class="function">pg_relation_filenode()</code>
+function.
+</p></div><p>
+When a table or index exceeds 1 GB, it is divided into gigabyte-sized
+<em class="firstterm">segments</em>. The first segment's file name is the same as the
+filenode; subsequent segments are named filenode.1, filenode.2, etc.
+This arrangement avoids problems on platforms that have file size limitations.
+(Actually, 1 GB is just the default segment size. The segment size can be
+adjusted using the configuration option <code class="option">--with-segsize</code>
+when building <span class="productname">PostgreSQL</span>.)
+In principle, free space map and visibility map forks could require multiple
+segments as well, though this is unlikely to happen in practice.
+</p><p>
+A table that has columns with potentially large entries will have an
+associated <em class="firstterm">TOAST</em> table, which is used for out-of-line storage of
+field values that are too large to keep in the table rows proper.
+<code class="structname">pg_class</code>.<code class="structfield">reltoastrelid</code> links from a table to
+its <acronym class="acronym">TOAST</acronym> table, if any.
+See <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a> for more information.
+</p><p>
+The contents of tables and indexes are discussed further in
+<a class="xref" href="storage-page-layout.html" title="73.6. Database Page Layout">Section 73.6</a>.
+</p><p>
+Tablespaces make the scenario more complicated. Each user-defined tablespace
+has a symbolic link inside the <code class="varname">PGDATA</code><code class="filename">/pg_tblspc</code>
+directory, which points to the physical tablespace directory (i.e., the
+location specified in the tablespace's <code class="command">CREATE TABLESPACE</code> command).
+This symbolic link is named after
+the tablespace's OID. Inside the physical tablespace directory there is
+a subdirectory with a name that depends on the <span class="productname">PostgreSQL</span>
+server version, such as <code class="literal">PG_9.0_201008051</code>. (The reason for using
+this subdirectory is so that successive versions of the database can use
+the same <code class="command">CREATE TABLESPACE</code> location value without conflicts.)
+Within the version-specific subdirectory, there is
+a subdirectory for each database that has elements in the tablespace, named
+after the database's OID. Tables and indexes are stored within that
+directory, using the filenode naming scheme.
+The <code class="literal">pg_default</code> tablespace is not accessed through
+<code class="filename">pg_tblspc</code>, but corresponds to
+<code class="varname">PGDATA</code><code class="filename">/base</code>. Similarly, the <code class="literal">pg_global</code>
+tablespace is not accessed through <code class="filename">pg_tblspc</code>, but corresponds to
+<code class="varname">PGDATA</code><code class="filename">/global</code>.
+</p><p>
+The <code class="function">pg_relation_filepath()</code> function shows the entire path
+(relative to <code class="varname">PGDATA</code>) of any relation. It is often useful
+as a substitute for remembering many of the above rules. But keep in
+mind that this function just gives the name of the first segment of the
+main fork of the relation — you may need to append a segment number
+and/or <code class="literal">_fsm</code>, <code class="literal">_vm</code>, or <code class="literal">_init</code> to find all
+the files associated with the relation.
+</p><p>
+Temporary files (for operations such as sorting more data than can fit in
+memory) are created within <code class="varname">PGDATA</code><code class="filename">/base/pgsql_tmp</code>,
+or within a <code class="filename">pgsql_tmp</code> subdirectory of a tablespace directory
+if a tablespace other than <code class="literal">pg_default</code> is specified for them.
+The name of a temporary file has the form
+<code class="filename">pgsql_tmp<em class="replaceable"><code>PPP</code></em>.<em class="replaceable"><code>NNN</code></em></code>,
+where <em class="replaceable"><code>PPP</code></em> is the PID of the owning backend and
+<em class="replaceable"><code>NNN</code></em> distinguishes different temporary files of that backend.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage.html" title="Chapter 73. Database Physical Storage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-toast.html" title="73.2. TOAST">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 73. Database Physical Storage </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.2. TOAST</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-fsm.html b/doc/src/sgml/html/storage-fsm.html
new file mode 100644
index 0000000..a956c41
--- /dev/null
+++ b/doc/src/sgml/html/storage-fsm.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.3. Free Space Map</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-toast.html" title="73.2. TOAST" /><link rel="next" href="storage-vm.html" title="73.4. Visibility Map" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.3. Free Space Map</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-toast.html" title="73.2. TOAST">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-vm.html" title="73.4. Visibility Map">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-FSM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.3. Free Space Map</h2></div></div></div><a id="id-1.10.24.5.2" class="indexterm"></a><a id="id-1.10.24.5.3" class="indexterm"></a><p>
+Each heap and index relation, except for hash indexes, has a Free Space Map
+(<acronym class="acronym">FSM</acronym>) to keep track of available space in the relation.
+It's stored alongside the main relation data in a separate relation fork,
+named after the filenode number of the relation, plus a <code class="literal">_fsm</code>
+suffix. For example, if the filenode of a relation is 12345, the
+<acronym class="acronym">FSM</acronym> is stored in a file called
+<code class="filename">12345_fsm</code>, in the same directory as the main relation file.
+</p><p>
+The Free Space Map is organized as a tree of <acronym class="acronym">FSM</acronym> pages. The
+bottom level <acronym class="acronym">FSM</acronym> pages store the free space available on each
+heap (or index) page, using one byte to represent each such page. The upper
+levels aggregate information from the lower levels.
+</p><p>
+Within each <acronym class="acronym">FSM</acronym> page is a binary tree, stored in an array with
+one byte per node. Each leaf node represents a heap page, or a lower level
+<acronym class="acronym">FSM</acronym> page. In each non-leaf node, the higher of its children's
+values is stored. The maximum value in the leaf nodes is therefore stored
+at the root.
+</p><p>
+See <code class="filename">src/backend/storage/freespace/README</code> for more details on
+how the <acronym class="acronym">FSM</acronym> is structured, and how it's updated and searched.
+The <a class="xref" href="pgfreespacemap.html" title="F.29. pg_freespacemap">pg_freespacemap</a> module
+can be used to examine the information stored in free space maps.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-toast.html" title="73.2. TOAST">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-vm.html" title="73.4. Visibility Map">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.2. TOAST </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.4. Visibility Map</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-hot.html b/doc/src/sgml/html/storage-hot.html
new file mode 100644
index 0000000..37f7ab4
--- /dev/null
+++ b/doc/src/sgml/html/storage-hot.html
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.7. Heap-Only Tuples (HOT)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-page-layout.html" title="73.6. Database Page Layout" /><link rel="next" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.7. Heap-Only Tuples (<acronym class="acronym">HOT</acronym>)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-page-layout.html" title="73.6. Database Page Layout">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-HOT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.7. Heap-Only Tuples (<acronym class="acronym">HOT</acronym>)</h2></div></div></div><p>
+ To allow for high concurrency, <span class="productname">PostgreSQL</span>
+ uses <a class="link" href="mvcc-intro.html" title="13.1. Introduction">multiversion concurrency
+ control</a> (<acronym class="acronym">MVCC</acronym>) to store rows. However,
+ <acronym class="acronym">MVCC</acronym> has some downsides for update queries.
+ Specifically, updates require new versions of rows to be added to
+ tables. This can also require new index entries for each updated row,
+ and removal of old versions of rows and their index entries can be
+ expensive.
+ </p><p>
+ To help reduce the overhead of updates,
+ <span class="productname">PostgreSQL</span> has an optimization called
+ heap-only tuples (<acronym class="acronym">HOT</acronym>). This optimization is
+ possible when:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The update does not modify any columns referenced by the table's
+ indexes, including expression and partial indexes.
+ </p></li><li class="listitem"><p>
+ There is sufficient free space on the page containing the old row
+ for the updated row.
+ </p></li></ul></div><p>
+
+ In such cases, heap-only tuples provide two optimizations:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ New index entries are not needed to represent updated rows.
+ </p></li><li class="listitem"><p>
+ Old versions of updated rows can be completely removed during normal
+ operation, including <code class="command">SELECT</code>s, instead of requiring
+ periodic vacuum operations. (This is possible because indexes
+ do not reference their <a class="link" href="storage-page-layout.html" title="73.6. Database Page Layout">page
+ item identifiers</a>.)
+ </p></li></ul></div><p>
+ </p><p>
+ In summary, heap-only tuple updates can only be created
+ if columns used by indexes are not updated. You can
+ increase the likelihood of sufficient page space for
+ <acronym class="acronym">HOT</acronym> updates by decreasing a table's <a class="link" href="sql-createtable.html#RELOPTION-FILLFACTOR"><code class="literal">fillfactor</code></a>.
+ If you don't, <acronym class="acronym">HOT</acronym> updates will still happen because
+ new rows will naturally migrate to new pages and existing pages with
+ sufficient free space for new row versions. The system view <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW" title="28.2.17. pg_stat_all_tables">pg_stat_all_tables</a>
+ allows monitoring of the occurrence of HOT and non-HOT updates.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-page-layout.html" title="73.6. Database Page Layout">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.6. Database Page Layout </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 74. System Catalog Declarations and Initial Contents</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-init.html b/doc/src/sgml/html/storage-init.html
new file mode 100644
index 0000000..ed31cb6
--- /dev/null
+++ b/doc/src/sgml/html/storage-init.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.5. The Initialization Fork</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-vm.html" title="73.4. Visibility Map" /><link rel="next" href="storage-page-layout.html" title="73.6. Database Page Layout" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.5. The Initialization Fork</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-vm.html" title="73.4. Visibility Map">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-page-layout.html" title="73.6. Database Page Layout">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-INIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.5. The Initialization Fork</h2></div></div></div><a id="id-1.10.24.7.2" class="indexterm"></a><p>
+Each unlogged table, and each index on an unlogged table, has an initialization
+fork. The initialization fork is an empty table or index of the appropriate
+type. When an unlogged table must be reset to empty due to a crash, the
+initialization fork is copied over the main fork, and any other forks are
+erased (they will be recreated automatically as needed).
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-vm.html" title="73.4. Visibility Map">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-page-layout.html" title="73.6. Database Page Layout">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.4. Visibility Map </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.6. Database Page Layout</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-page-layout.html b/doc/src/sgml/html/storage-page-layout.html
new file mode 100644
index 0000000..b851fdc
--- /dev/null
+++ b/doc/src/sgml/html/storage-page-layout.html
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.6. Database Page Layout</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-init.html" title="73.5. The Initialization Fork" /><link rel="next" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.6. Database Page Layout</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-init.html" title="73.5. The Initialization Fork">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-PAGE-LAYOUT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.6. Database Page Layout</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="storage-page-layout.html#STORAGE-TUPLE-LAYOUT">73.6.1. Table Row Layout</a></span></dt></dl></div><p>
+This section provides an overview of the page format used within
+<span class="productname">PostgreSQL</span> tables and indexes.<a href="#ftn.id-1.10.24.8.2.2" class="footnote"><sup class="footnote" id="id-1.10.24.8.2.2">[17]</sup></a>
+Sequences and <acronym class="acronym">TOAST</acronym> tables are formatted just like a regular table.
+</p><p>
+In the following explanation, a
+<em class="firstterm">byte</em>
+is assumed to contain 8 bits. In addition, the term
+<em class="firstterm">item</em>
+refers to an individual data value that is stored on a page. In a table,
+an item is a row; in an index, an item is an index entry.
+</p><p>
+Every table and index is stored as an array of <em class="firstterm">pages</em> of a
+fixed size (usually 8 kB, although a different page size can be selected
+when compiling the server). In a table, all the pages are logically
+equivalent, so a particular item (row) can be stored in any page. In
+indexes, the first page is generally reserved as a <em class="firstterm">metapage</em>
+holding control information, and there can be different types of pages
+within the index, depending on the index access method.
+</p><p>
+<a class="xref" href="storage-page-layout.html#PAGE-TABLE" title="Table 73.2. Overall Page Layout">Table 73.2</a> shows the overall layout of a page.
+There are five parts to each page.
+</p><div class="table" id="PAGE-TABLE"><p class="title"><strong>Table 73.2. Overall Page Layout</strong></p><div class="table-contents"><table class="table" summary="Overall Page Layout" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>
+Item
+</th><th>Description</th></tr></thead><tbody><tr><td>PageHeaderData</td><td>24 bytes long. Contains general information about the page, including
+free space pointers.</td></tr><tr><td>ItemIdData</td><td>Array of item identifiers pointing to the actual items. Each
+entry is an (offset,length) pair. 4 bytes per item.</td></tr><tr><td>Free space</td><td>The unallocated space. New item identifiers are allocated from
+the start of this area, new items from the end.</td></tr><tr><td>Items</td><td>The actual items themselves.</td></tr><tr><td>Special space</td><td>Index access method specific data. Different methods store different
+data. Empty in ordinary tables.</td></tr></tbody></table></div></div><br class="table-break" /><p>
+
+ The first 24 bytes of each page consists of a page header
+ (<code class="structname">PageHeaderData</code>). Its format is detailed in <a class="xref" href="storage-page-layout.html#PAGEHEADERDATA-TABLE" title="Table 73.3. PageHeaderData Layout">Table 73.3</a>. The first field tracks the most
+ recent WAL entry related to this page. The second field contains
+ the page checksum if <a class="xref" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS">data checksums</a> are
+ enabled. Next is a 2-byte field containing flag bits. This is followed
+ by three 2-byte integer fields (<code class="structfield">pd_lower</code>,
+ <code class="structfield">pd_upper</code>, and
+ <code class="structfield">pd_special</code>). These contain byte offsets
+ from the page start to the start of unallocated space, to the end of
+ unallocated space, and to the start of the special space. The next 2
+ bytes of the page header, <code class="structfield">pd_pagesize_version</code>,
+ store both the page size and a version indicator. Beginning with
+ <span class="productname">PostgreSQL</span> 8.3 the version number is 4;
+ <span class="productname">PostgreSQL</span> 8.1 and 8.2 used version number 3;
+ <span class="productname">PostgreSQL</span> 8.0 used version number 2;
+ <span class="productname">PostgreSQL</span> 7.3 and 7.4 used version number 1;
+ prior releases used version number 0.
+ (The basic page layout and header format has not changed in most of these
+ versions, but the layout of heap row headers has.) The page size
+ is basically only present as a cross-check; there is no support for having
+ more than one page size in an installation.
+ The last field is a hint that shows whether pruning the page is likely
+ to be profitable: it tracks the oldest un-pruned XMAX on the page.
+
+ </p><div class="table" id="PAGEHEADERDATA-TABLE"><p class="title"><strong>Table 73.3. PageHeaderData Layout</strong></p><div class="table-contents"><table class="table" summary="PageHeaderData Layout" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Type</th><th>Length</th><th>Description</th></tr></thead><tbody><tr><td>pd_lsn</td><td>PageXLogRecPtr</td><td>8 bytes</td><td>LSN: next byte after last byte of WAL record for last change
+ to this page</td></tr><tr><td>pd_checksum</td><td>uint16</td><td>2 bytes</td><td>Page checksum</td></tr><tr><td>pd_flags</td><td>uint16</td><td>2 bytes</td><td>Flag bits</td></tr><tr><td>pd_lower</td><td>LocationIndex</td><td>2 bytes</td><td>Offset to start of free space</td></tr><tr><td>pd_upper</td><td>LocationIndex</td><td>2 bytes</td><td>Offset to end of free space</td></tr><tr><td>pd_special</td><td>LocationIndex</td><td>2 bytes</td><td>Offset to start of special space</td></tr><tr><td>pd_pagesize_version</td><td>uint16</td><td>2 bytes</td><td>Page size and layout version number information</td></tr><tr><td>pd_prune_xid</td><td>TransactionId</td><td>4 bytes</td><td>Oldest unpruned XMAX on page, or zero if none</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ All the details can be found in
+ <code class="filename">src/include/storage/bufpage.h</code>.
+ </p><p>
+ Following the page header are item identifiers
+ (<code class="type">ItemIdData</code>), each requiring four bytes.
+ An item identifier contains a byte-offset to
+ the start of an item, its length in bytes, and a few attribute bits
+ which affect its interpretation.
+ New item identifiers are allocated
+ as needed from the beginning of the unallocated space.
+ The number of item identifiers present can be determined by looking at
+ <code class="structfield">pd_lower</code>, which is increased to allocate a new identifier.
+ Because an item
+ identifier is never moved until it is freed, its index can be used on a
+ long-term basis to reference an item, even when the item itself is moved
+ around on the page to compact free space. In fact, every pointer to an
+ item (<code class="type">ItemPointer</code>, also known as
+ <code class="type">CTID</code>) created by
+ <span class="productname">PostgreSQL</span> consists of a page number and the
+ index of an item identifier.
+
+ </p><p>
+
+ The items themselves are stored in space allocated backwards from the end
+ of unallocated space. The exact structure varies depending on what the
+ table is to contain. Tables and sequences both use a structure named
+ <code class="type">HeapTupleHeaderData</code>, described below.
+
+ </p><p>
+
+ The final section is the <span class="quote">“<span class="quote">special section</span>”</span> which can
+ contain anything the access method wishes to store. For example,
+ b-tree indexes store links to the page's left and right siblings,
+ as well as some other data relevant to the index structure.
+ Ordinary tables do not use a special section at all (indicated by setting
+ <code class="structfield">pd_special</code> to equal the page size).
+
+ </p><p>
+ <a class="xref" href="storage-page-layout.html#STORAGE-PAGE-LAYOUT-FIGURE" title="Figure 73.1. Page Layout">Figure 73.1</a> illustrates how these parts are
+ laid out in a page.
+ </p><div class="figure" id="STORAGE-PAGE-LAYOUT-FIGURE"><p class="title"><strong>Figure 73.1. Page Layout</strong></p><div class="figure-contents"><div class="mediaobject"><object type="image/svg+xml" data="pagelayout.svg" width="100%"></object></div></div></div><br class="figure-break" /><div class="sect2" id="STORAGE-TUPLE-LAYOUT"><div class="titlepage"><div><div><h3 class="title">73.6.1. Table Row Layout</h3></div></div></div><p>
+
+ All table rows are structured in the same way. There is a fixed-size
+ header (occupying 23 bytes on most machines), followed by an optional null
+ bitmap, an optional object ID field, and the user data. The header is
+ detailed
+ in <a class="xref" href="storage-page-layout.html#HEAPTUPLEHEADERDATA-TABLE" title="Table 73.4. HeapTupleHeaderData Layout">Table 73.4</a>. The actual user data
+ (columns of the row) begins at the offset indicated by
+ <code class="structfield">t_hoff</code>, which must always be a multiple of the MAXALIGN
+ distance for the platform.
+ The null bitmap is
+ only present if the <em class="firstterm">HEAP_HASNULL</em> bit is set in
+ <code class="structfield">t_infomask</code>. If it is present it begins just after
+ the fixed header and occupies enough bytes to have one bit per data column
+ (that is, the number of bits that equals the attribute count in
+ <code class="structfield">t_infomask2</code>). In this list of bits, a
+ 1 bit indicates not-null, a 0 bit is a null. When the bitmap is not
+ present, all columns are assumed not-null.
+ The object ID is only present if the <em class="firstterm">HEAP_HASOID_OLD</em> bit
+ is set in <code class="structfield">t_infomask</code>. If present, it appears just
+ before the <code class="structfield">t_hoff</code> boundary. Any padding needed to make
+ <code class="structfield">t_hoff</code> a MAXALIGN multiple will appear between the null
+ bitmap and the object ID. (This in turn ensures that the object ID is
+ suitably aligned.)
+
+ </p><div class="table" id="HEAPTUPLEHEADERDATA-TABLE"><p class="title"><strong>Table 73.4. HeapTupleHeaderData Layout</strong></p><div class="table-contents"><table class="table" summary="HeapTupleHeaderData Layout" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Type</th><th>Length</th><th>Description</th></tr></thead><tbody><tr><td>t_xmin</td><td>TransactionId</td><td>4 bytes</td><td>insert XID stamp</td></tr><tr><td>t_xmax</td><td>TransactionId</td><td>4 bytes</td><td>delete XID stamp</td></tr><tr><td>t_cid</td><td>CommandId</td><td>4 bytes</td><td>insert and/or delete CID stamp (overlays with t_xvac)</td></tr><tr><td>t_xvac</td><td>TransactionId</td><td>4 bytes</td><td>XID for VACUUM operation moving a row version</td></tr><tr><td>t_ctid</td><td>ItemPointerData</td><td>6 bytes</td><td>current TID of this or newer row version</td></tr><tr><td>t_infomask2</td><td>uint16</td><td>2 bytes</td><td>number of attributes, plus various flag bits</td></tr><tr><td>t_infomask</td><td>uint16</td><td>2 bytes</td><td>various flag bits</td></tr><tr><td>t_hoff</td><td>uint8</td><td>1 byte</td><td>offset to user data</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ All the details can be found in
+ <code class="filename">src/include/access/htup_details.h</code>.
+ </p><p>
+
+ Interpreting the actual data can only be done with information obtained
+ from other tables, mostly <code class="structname">pg_attribute</code>. The
+ key values needed to identify field locations are
+ <code class="structfield">attlen</code> and <code class="structfield">attalign</code>.
+ There is no way to directly get a
+ particular attribute, except when there are only fixed width fields and no
+ null values. All this trickery is wrapped up in the functions
+ <em class="firstterm">heap_getattr</em>, <em class="firstterm">fastgetattr</em>
+ and <em class="firstterm">heap_getsysattr</em>.
+
+ </p><p>
+
+ To read the data you need to examine each attribute in turn. First check
+ whether the field is NULL according to the null bitmap. If it is, go to
+ the next. Then make sure you have the right alignment. If the field is a
+ fixed width field, then all the bytes are simply placed. If it's a
+ variable length field (attlen = -1) then it's a bit more complicated.
+ All variable-length data types share the common header structure
+ <code class="type">struct varlena</code>, which includes the total length of the stored
+ value and some flag bits. Depending on the flags, the data can be either
+ inline or in a <acronym class="acronym">TOAST</acronym> table;
+ it might be compressed, too (see <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a>).
+
+ </p></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.10.24.8.2.2" class="footnote"><p><a href="#id-1.10.24.8.2.2" class="para"><sup class="para">[17] </sup></a>
+ Actually, use of this page format is not required for either table or
+ index access methods. The <code class="literal">heap</code> table access method
+ always uses this format. All the existing index methods also use the
+ basic format, but the data kept on index metapages usually doesn't follow
+ the item layout rules.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-init.html" title="73.5. The Initialization Fork">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-hot.html" title="73.7. Heap-Only Tuples (HOT)">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.5. The Initialization Fork </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.7. Heap-Only Tuples (<acronym class="acronym">HOT</acronym>)</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-toast.html b/doc/src/sgml/html/storage-toast.html
new file mode 100644
index 0000000..9541f89
--- /dev/null
+++ b/doc/src/sgml/html/storage-toast.html
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.2. TOAST</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-file-layout.html" title="73.1. Database File Layout" /><link rel="next" href="storage-fsm.html" title="73.3. Free Space Map" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.2. TOAST</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-file-layout.html" title="73.1. Database File Layout">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-fsm.html" title="73.3. Free Space Map">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-TOAST"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.2. TOAST</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="storage-toast.html#STORAGE-TOAST-ONDISK">73.2.1. Out-of-Line, On-Disk TOAST Storage</a></span></dt><dt><span class="sect2"><a href="storage-toast.html#STORAGE-TOAST-INMEMORY">73.2.2. Out-of-Line, In-Memory TOAST Storage</a></span></dt></dl></div><a id="id-1.10.24.4.2" class="indexterm"></a><a id="id-1.10.24.4.3" class="indexterm"></a><p>
+This section provides an overview of <acronym class="acronym">TOAST</acronym> (The
+Oversized-Attribute Storage Technique).
+</p><p>
+<span class="productname">PostgreSQL</span> uses a fixed page size (commonly
+8 kB), and does not allow tuples to span multiple pages. Therefore, it is
+not possible to store very large field values directly. To overcome
+this limitation, large field values are compressed and/or broken up into
+multiple physical rows. This happens transparently to the user, with only
+small impact on most of the backend code. The technique is affectionately
+known as <acronym class="acronym">TOAST</acronym> (or <span class="quote">“<span class="quote">the best thing since sliced bread</span>”</span>).
+The <acronym class="acronym">TOAST</acronym> infrastructure is also used to improve handling of
+large data values in-memory.
+</p><p>
+Only certain data types support <acronym class="acronym">TOAST</acronym> — there is no need to
+impose the overhead on data types that cannot produce large field values.
+To support <acronym class="acronym">TOAST</acronym>, a data type must have a variable-length
+(<em class="firstterm">varlena</em>) representation, in which, ordinarily, the first
+four-byte word of any stored value contains the total length of the value in
+bytes (including itself). <acronym class="acronym">TOAST</acronym> does not constrain the rest
+of the data type's representation. The special representations collectively
+called <em class="firstterm"><acronym class="acronym">TOAST</acronym>ed values</em> work by modifying or
+reinterpreting this initial length word. Therefore, the C-level functions
+supporting a <acronym class="acronym">TOAST</acronym>-able data type must be careful about how they
+handle potentially <acronym class="acronym">TOAST</acronym>ed input values: an input might not
+actually consist of a four-byte length word and contents until after it's
+been <em class="firstterm">detoasted</em>. (This is normally done by invoking
+<code class="function">PG_DETOAST_DATUM</code> before doing anything with an input value,
+but in some cases more efficient approaches are possible.
+See <a class="xref" href="xtypes.html#XTYPES-TOAST" title="38.13.1. TOAST Considerations">Section 38.13.1</a> for more detail.)
+</p><p>
+<acronym class="acronym">TOAST</acronym> usurps two bits of the varlena length word (the high-order
+bits on big-endian machines, the low-order bits on little-endian machines),
+thereby limiting the logical size of any value of a <acronym class="acronym">TOAST</acronym>-able
+data type to 1 GB (2<sup>30</sup> - 1 bytes). When both bits are zero,
+the value is an ordinary un-<acronym class="acronym">TOAST</acronym>ed value of the data type, and
+the remaining bits of the length word give the total datum size (including
+length word) in bytes. When the highest-order or lowest-order bit is set,
+the value has only a single-byte header instead of the normal four-byte
+header, and the remaining bits of that byte give the total datum size
+(including length byte) in bytes. This alternative supports space-efficient
+storage of values shorter than 127 bytes, while still allowing the data type
+to grow to 1 GB at need. Values with single-byte headers aren't aligned on
+any particular boundary, whereas values with four-byte headers are aligned on
+at least a four-byte boundary; this omission of alignment padding provides
+additional space savings that is significant compared to short values.
+As a special case, if the remaining bits of a single-byte header are all
+zero (which would be impossible for a self-inclusive length), the value is
+a pointer to out-of-line data, with several possible alternatives as
+described below. The type and size of such a <em class="firstterm">TOAST pointer</em>
+are determined by a code stored in the second byte of the datum.
+Lastly, when the highest-order or lowest-order bit is clear but the adjacent
+bit is set, the content of the datum has been compressed and must be
+decompressed before use. In this case the remaining bits of the four-byte
+length word give the total size of the compressed datum, not the
+original data. Note that compression is also possible for out-of-line data
+but the varlena header does not tell whether it has occurred —
+the content of the <acronym class="acronym">TOAST</acronym> pointer tells that, instead.
+</p><p>
+The compression technique used for either in-line or out-of-line compressed
+data can be selected for each column by setting
+the <code class="literal">COMPRESSION</code> column option in <code class="command">CREATE
+TABLE</code> or <code class="command">ALTER TABLE</code>. The default for columns
+with no explicit setting is to consult the
+<a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TOAST-COMPRESSION">default_toast_compression</a> parameter at the time data is
+inserted.
+</p><p>
+As mentioned, there are multiple types of <acronym class="acronym">TOAST</acronym> pointer datums.
+The oldest and most common type is a pointer to out-of-line data stored in
+a <em class="firstterm"><acronym class="acronym">TOAST</acronym> table</em> that is separate from, but
+associated with, the table containing the <acronym class="acronym">TOAST</acronym> pointer datum
+itself. These <em class="firstterm">on-disk</em> pointer datums are created by the
+<acronym class="acronym">TOAST</acronym> management code (in <code class="filename">access/common/toast_internals.c</code>)
+when a tuple to be stored on disk is too large to be stored as-is.
+Further details appear in <a class="xref" href="storage-toast.html#STORAGE-TOAST-ONDISK" title="73.2.1. Out-of-Line, On-Disk TOAST Storage">Section 73.2.1</a>.
+Alternatively, a <acronym class="acronym">TOAST</acronym> pointer datum can contain a pointer to
+out-of-line data that appears elsewhere in memory. Such datums are
+necessarily short-lived, and will never appear on-disk, but they are very
+useful for avoiding copying and redundant processing of large data values.
+Further details appear in <a class="xref" href="storage-toast.html#STORAGE-TOAST-INMEMORY" title="73.2.2. Out-of-Line, In-Memory TOAST Storage">Section 73.2.2</a>.
+</p><div class="sect2" id="STORAGE-TOAST-ONDISK"><div class="titlepage"><div><div><h3 class="title">73.2.1. Out-of-Line, On-Disk TOAST Storage</h3></div></div></div><p>
+If any of the columns of a table are <acronym class="acronym">TOAST</acronym>-able, the table will
+have an associated <acronym class="acronym">TOAST</acronym> table, whose OID is stored in the table's
+<code class="structname">pg_class</code>.<code class="structfield">reltoastrelid</code> entry. On-disk
+<acronym class="acronym">TOAST</acronym>ed values are kept in the <acronym class="acronym">TOAST</acronym> table, as
+described in more detail below.
+</p><p>
+Out-of-line values are divided (after compression if used) into chunks of at
+most <code class="symbol">TOAST_MAX_CHUNK_SIZE</code> bytes (by default this value is chosen
+so that four chunk rows will fit on a page, making it about 2000 bytes).
+Each chunk is stored as a separate row in the <acronym class="acronym">TOAST</acronym> table
+belonging to the owning table. Every
+<acronym class="acronym">TOAST</acronym> table has the columns <code class="structfield">chunk_id</code> (an OID
+identifying the particular <acronym class="acronym">TOAST</acronym>ed value),
+<code class="structfield">chunk_seq</code> (a sequence number for the chunk within its value),
+and <code class="structfield">chunk_data</code> (the actual data of the chunk). A unique index
+on <code class="structfield">chunk_id</code> and <code class="structfield">chunk_seq</code> provides fast
+retrieval of the values. A pointer datum representing an out-of-line on-disk
+<acronym class="acronym">TOAST</acronym>ed value therefore needs to store the OID of the
+<acronym class="acronym">TOAST</acronym> table in which to look and the OID of the specific value
+(its <code class="structfield">chunk_id</code>). For convenience, pointer datums also store the
+logical datum size (original uncompressed data length), physical stored size
+(different if compression was applied), and the compression method used, if
+any. Allowing for the varlena header bytes,
+the total size of an on-disk <acronym class="acronym">TOAST</acronym> pointer datum is therefore 18
+bytes regardless of the actual size of the represented value.
+</p><p>
+The <acronym class="acronym">TOAST</acronym> management code is triggered only
+when a row value to be stored in a table is wider than
+<code class="symbol">TOAST_TUPLE_THRESHOLD</code> bytes (normally 2 kB).
+The <acronym class="acronym">TOAST</acronym> code will compress and/or move
+field values out-of-line until the row value is shorter than
+<code class="symbol">TOAST_TUPLE_TARGET</code> bytes (also normally 2 kB, adjustable)
+or no more gains can be had. During an UPDATE
+operation, values of unchanged fields are normally preserved as-is; so an
+UPDATE of a row with out-of-line values incurs no <acronym class="acronym">TOAST</acronym> costs if
+none of the out-of-line values change.
+</p><p>
+The <acronym class="acronym">TOAST</acronym> management code recognizes four different strategies
+for storing <acronym class="acronym">TOAST</acronym>-able columns on disk:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">PLAIN</code> prevents either compression or
+ out-of-line storage; furthermore it disables use of single-byte headers
+ for varlena types.
+ This is the only possible strategy for
+ columns of non-<acronym class="acronym">TOAST</acronym>-able data types.
+ </p></li><li class="listitem"><p>
+ <code class="literal">EXTENDED</code> allows both compression and out-of-line
+ storage. This is the default for most <acronym class="acronym">TOAST</acronym>-able data types.
+ Compression will be attempted first, then out-of-line storage if
+ the row is still too big.
+ </p></li><li class="listitem"><p>
+ <code class="literal">EXTERNAL</code> allows out-of-line storage but not
+ compression. Use of <code class="literal">EXTERNAL</code> will
+ make substring operations on wide <code class="type">text</code> and
+ <code class="type">bytea</code> columns faster (at the penalty of increased storage
+ space) because these operations are optimized to fetch only the
+ required parts of the out-of-line value when it is not compressed.
+ </p></li><li class="listitem"><p>
+ <code class="literal">MAIN</code> allows compression but not out-of-line
+ storage. (Actually, out-of-line storage will still be performed
+ for such columns, but only as a last resort when there is no other
+ way to make the row small enough to fit on a page.)
+ </p></li></ul></div><p>
+
+Each <acronym class="acronym">TOAST</acronym>-able data type specifies a default strategy for columns
+of that data type, but the strategy for a given table column can be altered
+with <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ... SET STORAGE</code></a>.
+</p><p>
+<code class="symbol">TOAST_TUPLE_TARGET</code> can be adjusted for each table using
+<a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ... SET (toast_tuple_target = N)</code></a>
+</p><p>
+This scheme has a number of advantages compared to a more straightforward
+approach such as allowing row values to span pages. Assuming that queries are
+usually qualified by comparisons against relatively small key values, most of
+the work of the executor will be done using the main row entry. The big values
+of <acronym class="acronym">TOAST</acronym>ed attributes will only be pulled out (if selected at all)
+at the time the result set is sent to the client. Thus, the main table is much
+smaller and more of its rows fit in the shared buffer cache than would be the
+case without any out-of-line storage. Sort sets shrink also, and sorts will
+more often be done entirely in memory. A little test showed that a table
+containing typical HTML pages and their URLs was stored in about half of the
+raw data size including the <acronym class="acronym">TOAST</acronym> table, and that the main table
+contained only about 10% of the entire data (the URLs and some small HTML
+pages). There was no run time difference compared to an un-<acronym class="acronym">TOAST</acronym>ed
+comparison table, in which all the HTML pages were cut down to 7 kB to fit.
+</p></div><div class="sect2" id="STORAGE-TOAST-INMEMORY"><div class="titlepage"><div><div><h3 class="title">73.2.2. Out-of-Line, In-Memory TOAST Storage</h3></div></div></div><p>
+<acronym class="acronym">TOAST</acronym> pointers can point to data that is not on disk, but is
+elsewhere in the memory of the current server process. Such pointers
+obviously cannot be long-lived, but they are nonetheless useful. There
+are currently two sub-cases:
+pointers to <em class="firstterm">indirect</em> data and
+pointers to <em class="firstterm">expanded</em> data.
+</p><p>
+Indirect <acronym class="acronym">TOAST</acronym> pointers simply point at a non-indirect varlena
+value stored somewhere in memory. This case was originally created merely
+as a proof of concept, but it is currently used during logical decoding to
+avoid possibly having to create physical tuples exceeding 1 GB (as pulling
+all out-of-line field values into the tuple might do). The case is of
+limited use since the creator of the pointer datum is entirely responsible
+that the referenced data survives for as long as the pointer could exist,
+and there is no infrastructure to help with this.
+</p><p>
+Expanded <acronym class="acronym">TOAST</acronym> pointers are useful for complex data types
+whose on-disk representation is not especially suited for computational
+purposes. As an example, the standard varlena representation of a
+<span class="productname">PostgreSQL</span> array includes dimensionality information, a
+nulls bitmap if there are any null elements, then the values of all the
+elements in order. When the element type itself is variable-length, the
+only way to find the <em class="replaceable"><code>N</code></em>'th element is to scan through all the
+preceding elements. This representation is appropriate for on-disk storage
+because of its compactness, but for computations with the array it's much
+nicer to have an <span class="quote">“<span class="quote">expanded</span>”</span> or <span class="quote">“<span class="quote">deconstructed</span>”</span>
+representation in which all the element starting locations have been
+identified. The <acronym class="acronym">TOAST</acronym> pointer mechanism supports this need by
+allowing a pass-by-reference Datum to point to either a standard varlena
+value (the on-disk representation) or a <acronym class="acronym">TOAST</acronym> pointer that
+points to an expanded representation somewhere in memory. The details of
+this expanded representation are up to the data type, though it must have
+a standard header and meet the other API requirements given
+in <code class="filename">src/include/utils/expandeddatum.h</code>. C-level functions
+working with the data type can choose to handle either representation.
+Functions that do not know about the expanded representation, but simply
+apply <code class="function">PG_DETOAST_DATUM</code> to their inputs, will automatically
+receive the traditional varlena representation; so support for an expanded
+representation can be introduced incrementally, one function at a time.
+</p><p>
+<acronym class="acronym">TOAST</acronym> pointers to expanded values are further broken down
+into <em class="firstterm">read-write</em> and <em class="firstterm">read-only</em> pointers.
+The pointed-to representation is the same either way, but a function that
+receives a read-write pointer is allowed to modify the referenced value
+in-place, whereas one that receives a read-only pointer must not; it must
+first create a copy if it wants to make a modified version of the value.
+This distinction and some associated conventions make it possible to avoid
+unnecessary copying of expanded values during query execution.
+</p><p>
+For all types of in-memory <acronym class="acronym">TOAST</acronym> pointer, the <acronym class="acronym">TOAST</acronym>
+management code ensures that no such pointer datum can accidentally get
+stored on disk. In-memory <acronym class="acronym">TOAST</acronym> pointers are automatically
+expanded to normal in-line varlena values before storage — and then
+possibly converted to on-disk <acronym class="acronym">TOAST</acronym> pointers, if the containing
+tuple would otherwise be too big.
+</p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-file-layout.html" title="73.1. Database File Layout">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-fsm.html" title="73.3. Free Space Map">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.1. Database File Layout </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.3. Free Space Map</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage-vm.html b/doc/src/sgml/html/storage-vm.html
new file mode 100644
index 0000000..d0b9d3d
--- /dev/null
+++ b/doc/src/sgml/html/storage-vm.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>73.4. Visibility Map</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="storage-fsm.html" title="73.3. Free Space Map" /><link rel="next" href="storage-init.html" title="73.5. The Initialization Fork" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">73.4. Visibility Map</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-fsm.html" title="73.3. Free Space Map">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 73. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-init.html" title="73.5. The Initialization Fork">Next</a></td></tr></table><hr /></div><div class="sect1" id="STORAGE-VM"><div class="titlepage"><div><div><h2 class="title" style="clear: both">73.4. Visibility Map</h2></div></div></div><a id="id-1.10.24.6.2" class="indexterm"></a><a id="id-1.10.24.6.3" class="indexterm"></a><p>
+Each heap relation has a Visibility Map
+(VM) to keep track of which pages contain only tuples that are known to be
+visible to all active transactions; it also keeps track of which pages contain
+only frozen tuples. It's stored
+alongside the main relation data in a separate relation fork, named after the
+filenode number of the relation, plus a <code class="literal">_vm</code> suffix. For example,
+if the filenode of a relation is 12345, the VM is stored in a file called
+<code class="filename">12345_vm</code>, in the same directory as the main relation file.
+Note that indexes do not have VMs.
+</p><p>
+The visibility map stores two bits per heap page. The first bit, if set,
+indicates that the page is all-visible, or in other words that the page does
+not contain any tuples that need to be vacuumed.
+This information can also be used
+by <a class="link" href="indexes-index-only-scans.html" title="11.9. Index-Only Scans and Covering Indexes"><em class="firstterm">index-only
+scans</em></a> to answer queries using only the index tuple.
+The second bit, if set, means that all tuples on the page have been frozen.
+That means that even an anti-wraparound vacuum need not revisit the page.
+</p><p>
+The map is conservative in the sense that we make sure that whenever a bit is
+set, we know the condition is true, but if a bit is not set, it might or
+might not be true. Visibility map bits are only set by vacuum, but are
+cleared by any data-modifying operations on a page.
+</p><p>
+The <a class="xref" href="pgvisibility.html" title="F.36. pg_visibility">pg_visibility</a> module can be used to examine the
+information stored in the visibility map.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-fsm.html" title="73.3. Free Space Map">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html" title="Chapter 73. Database Physical Storage">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-init.html" title="73.5. The Initialization Fork">Next</a></td></tr><tr><td width="40%" align="left" valign="top">73.3. Free Space Map </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.5. The Initialization Fork</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/storage.html b/doc/src/sgml/html/storage.html
new file mode 100644
index 0000000..1b1b753
--- /dev/null
+++ b/doc/src/sgml/html/storage.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 73. Database Physical Storage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="hash-implementation.html" title="72.2. Implementation" /><link rel="next" href="storage-file-layout.html" title="73.1. Database File Layout" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 73. Database Physical Storage</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="hash-implementation.html" title="72.2. Implementation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="storage-file-layout.html" title="73.1. Database File Layout">Next</a></td></tr></table><hr /></div><div class="chapter" id="STORAGE"><div class="titlepage"><div><div><h2 class="title">Chapter 73. Database Physical Storage</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="storage-file-layout.html">73.1. Database File Layout</a></span></dt><dt><span class="sect1"><a href="storage-toast.html">73.2. TOAST</a></span></dt><dd><dl><dt><span class="sect2"><a href="storage-toast.html#STORAGE-TOAST-ONDISK">73.2.1. Out-of-Line, On-Disk TOAST Storage</a></span></dt><dt><span class="sect2"><a href="storage-toast.html#STORAGE-TOAST-INMEMORY">73.2.2. Out-of-Line, In-Memory TOAST Storage</a></span></dt></dl></dd><dt><span class="sect1"><a href="storage-fsm.html">73.3. Free Space Map</a></span></dt><dt><span class="sect1"><a href="storage-vm.html">73.4. Visibility Map</a></span></dt><dt><span class="sect1"><a href="storage-init.html">73.5. The Initialization Fork</a></span></dt><dt><span class="sect1"><a href="storage-page-layout.html">73.6. Database Page Layout</a></span></dt><dd><dl><dt><span class="sect2"><a href="storage-page-layout.html#STORAGE-TUPLE-LAYOUT">73.6.1. Table Row Layout</a></span></dt></dl></dd><dt><span class="sect1"><a href="storage-hot.html">73.7. Heap-Only Tuples (<acronym class="acronym">HOT</acronym>)</a></span></dt></dl></div><p>
+This chapter provides an overview of the physical storage format used by
+<span class="productname">PostgreSQL</span> databases.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="hash-implementation.html" title="72.2. Implementation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="storage-file-layout.html" title="73.1. Database File Layout">Next</a></td></tr><tr><td width="40%" align="left" valign="top">72.2. Implementation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 73.1. Database File Layout</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/stylesheet.css b/doc/src/sgml/html/stylesheet.css
new file mode 100644
index 0000000..6410a47
--- /dev/null
+++ b/doc/src/sgml/html/stylesheet.css
@@ -0,0 +1,165 @@
+/* doc/src/sgml/stylesheet.css */
+
+/* color scheme similar to www.postgresql.org */
+
+body {
+ color: #000000;
+ background: #FFFFFF;
+ font-family: verdana, sans-serif;
+}
+
+a:link { color:#0066A2; }
+a:visited { color:#004E66; }
+a:active { color:#0066A2; }
+a:hover { color:#000000; }
+
+h1 {
+ font-size: 1.4em;
+ font-weight: bold;
+ margin-top: 0em;
+ margin-bottom: 0em;
+ color: #EC5800;
+}
+
+h2 {
+ font-size: 1.2em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: bold;
+ color: #666;
+}
+
+.titlepage h2.title,
+.refnamediv h2 {
+ color: #EC5800;
+}
+
+h3 {
+ font-size: 1.1em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: bold;
+ color: #666;
+}
+
+h4 {
+ font-size: 0.95em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: normal;
+ color: #666;
+}
+
+h5 {
+ font-size: 0.9em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: normal;
+}
+
+h6 {
+ font-size: 0.85em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: normal;
+}
+
+/* center some titles */
+
+.book .title, .book .corpauthor, .book .copyright {
+ text-align: center;
+}
+
+/* decoration for formal examples */
+
+div.example {
+ padding-left: 15px;
+ border-style: solid;
+ border-width: 0px;
+ border-left-width: 2px;
+ border-color: black;
+ margin: 0.5ex;
+}
+
+/* formatting for entries in tables of functions: indent all but first line */
+
+th.func_table_entry p,
+td.func_table_entry p {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+ text-align: left;
+}
+
+p.func_signature {
+ text-indent: -3.5em;
+}
+
+td.func_table_entry pre.programlisting {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+}
+
+/* formatting for entries in tables of catalog/view columns */
+
+th.catalog_table_entry p,
+td.catalog_table_entry p {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+ text-align: left;
+}
+
+th.catalog_table_entry p.column_definition {
+ text-indent: -3.5em;
+ word-spacing: 0.25em;
+}
+
+td.catalog_table_entry p.column_definition {
+ text-indent: -3.5em;
+}
+
+p.column_definition code.type {
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+}
+
+td.catalog_table_entry pre.programlisting {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+}
+
+/* Put these here instead of inside the HTML (see unsetting of
+ admon.style in XSL) so that the web site stylesheet can set its own
+ style. */
+
+.tip,
+.note,
+.important,
+.caution,
+.warning {
+ margin-left: 0.5in;
+ margin-right: 0.5in;
+}
+
+/* miscellaneous */
+
+pre.literallayout, .screen, .synopsis, .programlisting {
+ margin-left: 4ex;
+}
+
+ul.itemizedlist {
+ margin-left: 2.5rem;
+}
+
+.comment { color: red; }
+
+var { font-family: monospace; font-style: italic; }
+/* Konqueror's standard style for ACRONYM is italic. */
+acronym { font-style: inherit; }
+
+.option { white-space: nowrap; }
+
+/* make images not too wide on larger screens */
+@media (min-width: 800px) {
+ .mediaobject {
+ width: 75%;
+ }
+}
diff --git a/doc/src/sgml/html/supported-platforms.html b/doc/src/sgml/html/supported-platforms.html
new file mode 100644
index 0000000..89041e7
--- /dev/null
+++ b/doc/src/sgml/html/supported-platforms.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>17.6. Supported Platforms</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="install-post.html" title="17.5. Post-Installation Setup" /><link rel="next" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">17.6. Supported Platforms</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="install-post.html" title="17.5. Post-Installation Setup">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><th width="60%" align="center">Chapter 17. Installation from Source Code</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes">Next</a></td></tr></table><hr /></div><div class="sect1" id="SUPPORTED-PLATFORMS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">17.6. Supported Platforms</h2></div></div></div><p>
+ A platform (that is, a CPU architecture and operating system combination)
+ is considered supported by the <span class="productname">PostgreSQL</span> development
+ community if the code contains provisions to work on that platform and
+ it has recently been verified to build and pass its regression tests
+ on that platform. Currently, most testing of platform compatibility
+ is done automatically by test machines in the
+ <a class="ulink" href="https://buildfarm.postgresql.org/" target="_top">PostgreSQL Build Farm</a>.
+ If you are interested in using <span class="productname">PostgreSQL</span> on a platform
+ that is not represented in the build farm, but on which the code works
+ or can be made to work, you are strongly encouraged to set up a build
+ farm member machine so that continued compatibility can be assured.
+ </p><p>
+ In general, <span class="productname">PostgreSQL</span> can be expected to work on
+ these CPU architectures: x86, x86_64, IA64, PowerPC,
+ PowerPC 64, S/390, S/390x, Sparc, Sparc 64, ARM, MIPS, MIPSEL,
+ and PA-RISC. Code support exists for M68K, M32R, and VAX, but these
+ architectures are not known to have been tested recently. It is often
+ possible to build on an unsupported CPU type by configuring with
+ <code class="option">--disable-spinlocks</code>, but performance will be poor.
+ </p><p>
+ <span class="productname">PostgreSQL</span> can be expected to work on these operating
+ systems: Linux (all recent distributions), Windows (XP and later),
+ FreeBSD, OpenBSD, NetBSD, macOS, AIX, HP/UX, and Solaris.
+ Other Unix-like systems may also work but are not currently
+ being tested. In most cases, all CPU architectures supported by
+ a given operating system will work. Look in
+ <a class="xref" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes">Section 17.7</a> below to see if
+ there is information
+ specific to your operating system, particularly if using an older system.
+ </p><p>
+ If you have installation problems on a platform that is known
+ to be supported according to recent build farm results, please report
+ it to <code class="email">&lt;<a class="email" href="mailto:pgsql-bugs@lists.postgresql.org">pgsql-bugs@lists.postgresql.org</a>&gt;</code>. If you are interested
+ in porting <span class="productname">PostgreSQL</span> to a new platform,
+ <code class="email">&lt;<a class="email" href="mailto:pgsql-hackers@lists.postgresql.org">pgsql-hackers@lists.postgresql.org</a>&gt;</code> is the appropriate place
+ to discuss that.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="install-post.html" title="17.5. Post-Installation Setup">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="installation.html" title="Chapter 17. Installation from Source Code">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="installation-platform-notes.html" title="17.7. Platform-Specific Notes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">17.5. Post-Installation Setup </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 17.7. Platform-Specific Notes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/system-catalog-declarations.html b/doc/src/sgml/html/system-catalog-declarations.html
new file mode 100644
index 0000000..31c751c
--- /dev/null
+++ b/doc/src/sgml/html/system-catalog-declarations.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>74.1. System Catalog Declaration Rules</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents" /><link rel="next" href="system-catalog-initial-data.html" title="74.2. System Catalog Initial Data" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">74.1. System Catalog Declaration Rules</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><th width="60%" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="system-catalog-initial-data.html" title="74.2. System Catalog Initial Data">Next</a></td></tr></table><hr /></div><div class="sect1" id="SYSTEM-CATALOG-DECLARATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">74.1. System Catalog Declaration Rules</h2></div></div></div><p>
+ The key part of a catalog header file is a C structure definition
+ describing the layout of each row of the catalog. This begins with
+ a <code class="literal">CATALOG</code> macro, which so far as the C compiler is
+ concerned is just shorthand for <code class="literal">typedef struct
+ FormData_<em class="replaceable"><code>catalogname</code></em></code>.
+ Each field in the struct gives rise to a catalog column.
+ Fields can be annotated using the BKI property macros described
+ in <code class="filename">genbki.h</code>, for example to define a default value
+ for a field or mark it as nullable or not nullable.
+ The <code class="literal">CATALOG</code> line can also be annotated, with some
+ other BKI property macros described in <code class="filename">genbki.h</code>, to
+ define other properties of the catalog as a whole, such as whether
+ it is a shared relation.
+ </p><p>
+ The system catalog cache code (and most catalog-munging code in general)
+ assumes that the fixed-length portions of all system catalog tuples are
+ in fact present, because it maps this C struct declaration onto them.
+ Thus, all variable-length fields and nullable fields must be placed at
+ the end, and they cannot be accessed as struct fields.
+ For example, if you tried to
+ set <code class="structname">pg_type</code>.<code class="structfield">typrelid</code>
+ to be NULL, it would fail when some piece of code tried to reference
+ <code class="literal">typetup-&gt;typrelid</code> (or worse,
+ <code class="literal">typetup-&gt;typelem</code>, because that follows
+ <code class="structfield">typrelid</code>). This would result in
+ random errors or even segmentation violations.
+ </p><p>
+ As a partial guard against this type of error, variable-length or
+ nullable fields should not be made directly visible to the C compiler.
+ This is accomplished by wrapping them in <code class="literal">#ifdef
+ CATALOG_VARLEN</code> ... <code class="literal">#endif</code> (where
+ <code class="literal">CATALOG_VARLEN</code> is a symbol that is never defined).
+ This prevents C code from carelessly trying to access fields that might
+ not be there or might be at some other offset.
+ As an independent guard against creating incorrect rows, we
+ require all columns that should be non-nullable to be marked so
+ in <code class="structname">pg_attribute</code>. The bootstrap code will
+ automatically mark catalog columns as <code class="literal">NOT NULL</code>
+ if they are fixed-width and are not preceded by any nullable or
+ variable-width column.
+ Where this rule is inadequate, you can force correct marking by using
+ <code class="literal">BKI_FORCE_NOT_NULL</code>
+ and <code class="literal">BKI_FORCE_NULL</code> annotations as needed.
+ </p><p>
+ Frontend code should not include any <code class="filename">pg_xxx.h</code>
+ catalog header file, as these files may contain C code that won't compile
+ outside the backend. (Typically, that happens because these files also
+ contain declarations for functions
+ in <code class="filename">src/backend/catalog/</code> files.)
+ Instead, frontend code may include the corresponding
+ generated <code class="filename">pg_xxx_d.h</code> header, which will contain
+ OID <code class="literal">#define</code>s and any other data that might be of use
+ on the client side. If you want macros or other code in a catalog header
+ to be visible to frontend code, write <code class="literal">#ifdef
+ EXPOSE_TO_CLIENT_CODE</code> ... <code class="literal">#endif</code> around that
+ section to instruct <code class="filename">genbki.pl</code> to copy that section
+ to the <code class="filename">pg_xxx_d.h</code> header.
+ </p><p>
+ A few of the catalogs are so fundamental that they can't even be created
+ by the <acronym class="acronym">BKI</acronym> <code class="literal">create</code> command that's
+ used for most catalogs, because that command needs to write information
+ into these catalogs to describe the new catalog. These are
+ called <em class="firstterm">bootstrap</em> catalogs, and defining one takes
+ a lot of extra work: you have to manually prepare appropriate entries for
+ them in the pre-loaded contents of <code class="structname">pg_class</code>
+ and <code class="structname">pg_type</code>, and those entries will need to be
+ updated for subsequent changes to the catalog's structure.
+ (Bootstrap catalogs also need pre-loaded entries
+ in <code class="structname">pg_attribute</code>, but
+ fortunately <code class="filename">genbki.pl</code> handles that chore nowadays.)
+ Avoid making new catalogs be bootstrap catalogs if at all possible.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="system-catalog-initial-data.html" title="74.2. System Catalog Initial Data">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 74. System Catalog Declarations and Initial Contents </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 74.2. System Catalog Initial Data</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/system-catalog-initial-data.html b/doc/src/sgml/html/system-catalog-initial-data.html
new file mode 100644
index 0000000..d7fbc73
--- /dev/null
+++ b/doc/src/sgml/html/system-catalog-initial-data.html
@@ -0,0 +1,404 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>74.2. System Catalog Initial Data</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="system-catalog-declarations.html" title="74.1. System Catalog Declaration Rules" /><link rel="next" href="bki-format.html" title="74.3. BKI File Format" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">74.2. System Catalog Initial Data</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="system-catalog-declarations.html" title="74.1. System Catalog Declaration Rules">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><th width="60%" align="center">Chapter 74. System Catalog Declarations and Initial Contents</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bki-format.html" title="74.3. BKI File Format">Next</a></td></tr></table><hr /></div><div class="sect1" id="SYSTEM-CATALOG-INITIAL-DATA"><div class="titlepage"><div><div><h2 class="title" style="clear: both">74.2. System Catalog Initial Data</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-INITIAL-DATA-FORMAT">74.2.1. Data File Format</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-OID-ASSIGNMENT">74.2.2. OID Assignment</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-OID-REFERENCES">74.2.3. OID Reference Lookup</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-AUTO-ARRAY-TYPES">74.2.4. Automatic Creation of Array Types</a></span></dt><dt><span class="sect2"><a href="system-catalog-initial-data.html#SYSTEM-CATALOG-RECIPES">74.2.5. Recipes for Editing Data Files</a></span></dt></dl></div><p>
+ Each catalog that has any manually-created initial data (some do not)
+ has a corresponding <code class="literal">.dat</code> file that contains its
+ initial data in an editable format.
+ </p><div class="sect2" id="SYSTEM-CATALOG-INITIAL-DATA-FORMAT"><div class="titlepage"><div><div><h3 class="title">74.2.1. Data File Format</h3></div></div></div><p>
+ Each <code class="literal">.dat</code> file contains Perl data structure literals
+ that are simply eval'd to produce an in-memory data structure consisting
+ of an array of hash references, one per catalog row.
+ A slightly modified excerpt from <code class="filename">pg_database.dat</code>
+ will demonstrate the key features:
+ </p><pre class="programlisting">
+[
+
+# A comment could appear here.
+{ oid =&gt; '1', oid_symbol =&gt; 'Template1DbOid',
+ descr =&gt; 'database\'s default template',
+ datname =&gt; 'template1', encoding =&gt; 'ENCODING',
+ datlocprovider =&gt; 'LOCALE_PROVIDER', datistemplate =&gt; 't',
+ datallowconn =&gt; 't', datconnlimit =&gt; '-1', datfrozenxid =&gt; '0',
+ datminmxid =&gt; '1', dattablespace =&gt; 'pg_default', datcollate =&gt; 'LC_COLLATE',
+ datctype =&gt; 'LC_CTYPE', daticulocale =&gt; 'ICU_LOCALE', datacl =&gt; '_null_' },
+
+]
+</pre><p>
+ Points to note:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The overall file layout is: open square bracket, one or more sets of
+ curly braces each of which represents a catalog row, close square
+ bracket. Write a comma after each closing curly brace.
+ </p></li><li class="listitem"><p>
+ Within each catalog row, write comma-separated
+ <em class="replaceable"><code>key</code></em> <code class="literal">=&gt;</code>
+ <em class="replaceable"><code>value</code></em> pairs. The
+ allowed <em class="replaceable"><code>key</code></em>s are the names of the catalog's
+ columns, plus the metadata keys <code class="literal">oid</code>,
+ <code class="literal">oid_symbol</code>,
+ <code class="literal">array_type_oid</code>, and <code class="literal">descr</code>.
+ (The use of <code class="literal">oid</code> and <code class="literal">oid_symbol</code>
+ is described in <a class="xref" href="system-catalog-initial-data.html#SYSTEM-CATALOG-OID-ASSIGNMENT" title="74.2.2. OID Assignment">Section 74.2.2</a> below,
+ while <code class="literal">array_type_oid</code> is described in
+ <a class="xref" href="system-catalog-initial-data.html#SYSTEM-CATALOG-AUTO-ARRAY-TYPES" title="74.2.4. Automatic Creation of Array Types">Section 74.2.4</a>.
+ <code class="literal">descr</code> supplies a description string for the object,
+ which will be inserted into <code class="structname">pg_description</code>
+ or <code class="structname">pg_shdescription</code> as appropriate.)
+ While the metadata keys are optional, the catalog's defined columns
+ must all be provided, except when the catalog's <code class="literal">.h</code>
+ file specifies a default value for the column.
+ (In the example above, the <code class="structfield">datdba</code> field has
+ been omitted because <code class="filename">pg_database.h</code> supplies a
+ suitable default value for it.)
+ </p></li><li class="listitem"><p>
+ All values must be single-quoted. Escape single quotes used within a
+ value with a backslash. Backslashes meant as data can, but need not,
+ be doubled; this follows Perl's rules for simple quoted literals.
+ Note that backslashes appearing as data will be treated as escapes by
+ the bootstrap scanner, according to the same rules as for escape string
+ constants (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE" title="4.1.2.2. String Constants with C-Style Escapes">Section 4.1.2.2</a>); for
+ example <code class="literal">\t</code> converts to a tab character. If you
+ actually want a backslash in the final value, you will need to write
+ four of them: Perl strips two, leaving <code class="literal">\\</code> for the
+ bootstrap scanner to see.
+ </p></li><li class="listitem"><p>
+ Null values are represented by <code class="literal">_null_</code>.
+ (Note that there is no way to create a value that is just that
+ string.)
+ </p></li><li class="listitem"><p>
+ Comments are preceded by <code class="literal">#</code>, and must be on their
+ own lines.
+ </p></li><li class="listitem"><p>
+ Field values that are OIDs of other catalog entries should be
+ represented by symbolic names rather than actual numeric OIDs.
+ (In the example above, <code class="structfield">dattablespace</code>
+ contains such a reference.)
+ This is described in <a class="xref" href="system-catalog-initial-data.html#SYSTEM-CATALOG-OID-REFERENCES" title="74.2.3. OID Reference Lookup">Section 74.2.3</a>
+ below.
+ </p></li><li class="listitem"><p>
+ Since hashes are unordered data structures, field order and line
+ layout aren't semantically significant. However, to maintain a
+ consistent appearance, we set a few rules that are applied by the
+ formatting script <code class="filename">reformat_dat_file.pl</code>:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
+ Within each pair of curly braces, the metadata
+ fields <code class="literal">oid</code>, <code class="literal">oid_symbol</code>,
+ <code class="literal">array_type_oid</code>, and <code class="literal">descr</code>
+ (if present) come first, in that order, then the catalog's own
+ fields appear in their defined order.
+ </p></li><li class="listitem"><p>
+ Newlines are inserted between fields as needed to limit line length
+ to 80 characters, if possible. A newline is also inserted between
+ the metadata fields and the regular fields.
+ </p></li><li class="listitem"><p>
+ If the catalog's <code class="literal">.h</code> file specifies a default
+ value for a column, and a data entry has that same
+ value, <code class="filename">reformat_dat_file.pl</code> will omit it from
+ the data file. This keeps the data representation compact.
+ </p></li><li class="listitem"><p>
+ <code class="filename">reformat_dat_file.pl</code> preserves blank lines
+ and comment lines as-is.
+ </p></li></ul></div><p>
+
+ It's recommended to run <code class="filename">reformat_dat_file.pl</code>
+ before submitting catalog data patches. For convenience, you can
+ simply change to <code class="filename">src/include/catalog/</code> and
+ run <code class="literal">make reformat-dat-files</code>.
+ </p></li><li class="listitem"><p>
+ If you want to add a new method of making the data representation
+ smaller, you must implement it
+ in <code class="filename">reformat_dat_file.pl</code> and also
+ teach <code class="function">Catalog::ParseData()</code> how to expand the
+ data back into the full representation.
+ </p></li></ul></div></div><div class="sect2" id="SYSTEM-CATALOG-OID-ASSIGNMENT"><div class="titlepage"><div><div><h3 class="title">74.2.2. OID Assignment</h3></div></div></div><p>
+ A catalog row appearing in the initial data can be given a
+ manually-assigned OID by writing an <code class="literal">oid
+ =&gt; <em class="replaceable"><code>nnnn</code></em></code> metadata field.
+ Furthermore, if an OID is assigned, a C macro for that OID can be
+ created by writing an <code class="literal">oid_symbol
+ =&gt; <em class="replaceable"><code>name</code></em></code> metadata field.
+ </p><p>
+ Pre-loaded catalog rows must have preassigned OIDs if there are OID
+ references to them in other pre-loaded rows. A preassigned OID is
+ also needed if the row's OID must be referenced from C code.
+ If neither case applies, the <code class="literal">oid</code> metadata field can
+ be omitted, in which case the bootstrap code assigns an OID
+ automatically.
+ In practice we usually preassign OIDs for all or none of the pre-loaded
+ rows in a given catalog, even if only some of them are actually
+ cross-referenced.
+ </p><p>
+ Writing the actual numeric value of any OID in C code is considered
+ very bad form; always use a macro, instead. Direct references
+ to <code class="structname">pg_proc</code> OIDs are common enough that there's
+ a special mechanism to create the necessary macros automatically;
+ see <code class="filename">src/backend/utils/Gen_fmgrtab.pl</code>. Similarly
+ — but, for historical reasons, not done the same way —
+ there's an automatic method for creating macros
+ for <code class="structname">pg_type</code>
+ OIDs. <code class="literal">oid_symbol</code> entries are therefore not
+ necessary in those two catalogs. Likewise, macros for
+ the <code class="structname">pg_class</code> OIDs of system catalogs and
+ indexes are set up automatically. For all other system catalogs, you
+ have to manually specify any macros you need
+ via <code class="literal">oid_symbol</code> entries.
+ </p><p>
+ To find an available OID for a new pre-loaded row, run the
+ script <code class="filename">src/include/catalog/unused_oids</code>.
+ It prints inclusive ranges of unused OIDs (e.g., the output
+ line <code class="literal">45-900</code> means OIDs 45 through 900 have not been
+ allocated yet). Currently, OIDs 1–9999 are reserved for manual
+ assignment; the <code class="filename">unused_oids</code> script simply looks
+ through the catalog headers and <code class="filename">.dat</code> files
+ to see which ones do not appear. You can also use
+ the <code class="filename">duplicate_oids</code> script to check for mistakes.
+ (<code class="filename">genbki.pl</code> will assign OIDs for any rows that
+ didn't get one hand-assigned to them, and it will also detect duplicate
+ OIDs at compile time.)
+ </p><p>
+ When choosing OIDs for a patch that is not expected to be committed
+ immediately, best practice is to use a group of more-or-less
+ consecutive OIDs starting with some random choice in the range
+ 8000—9999. This minimizes the risk of OID collisions with other
+ patches being developed concurrently. To keep the 8000—9999
+ range free for development purposes, after a patch has been committed
+ to the master git repository its OIDs should be renumbered into
+ available space below that range. Typically, this will be done
+ near the end of each development cycle, moving all OIDs consumed by
+ patches committed in that cycle at the same time. The script
+ <code class="filename">renumber_oids.pl</code> can be used for this purpose.
+ If an uncommitted patch is found to have OID conflicts with some
+ recently-committed patch, <code class="filename">renumber_oids.pl</code> may
+ also be useful for recovering from that situation.
+ </p><p>
+ Because of this convention of possibly renumbering OIDs assigned by
+ patches, the OIDs assigned by a patch should not be considered stable
+ until the patch has been included in an official release. We do not
+ change manually-assigned object OIDs once released, however, as that
+ would create assorted compatibility problems.
+ </p><p>
+ If <code class="filename">genbki.pl</code> needs to assign an OID to a catalog
+ entry that does not have a manually-assigned OID, it will use a value in
+ the range 10000—11999. The server's OID counter is set to 10000
+ at the start of a bootstrap run, so that any objects created on-the-fly
+ during bootstrap processing also receive OIDs in this range. (The
+ usual OID assignment mechanism takes care of preventing any conflicts.)
+ </p><p>
+ Objects with OIDs below <code class="symbol">FirstUnpinnedObjectId</code> (12000)
+ are considered <span class="quote">“<span class="quote">pinned</span>”</span>, preventing them from being
+ deleted. (There are a small number of exceptions, which are
+ hard-wired into <code class="function">IsPinnedObject()</code>.)
+ <span class="application">initdb</span> forces the OID counter up
+ to <code class="symbol">FirstUnpinnedObjectId</code> as soon as it's ready to
+ create unpinned objects. Thus objects created during the later phases
+ of <span class="application">initdb</span>, such as objects created while
+ running the <code class="filename">information_schema.sql</code> script, will
+ not be pinned, while all objects known
+ to <code class="filename">genbki.pl</code> will be.
+ </p><p>
+ OIDs assigned during normal database operation are constrained to be
+ 16384 or higher. This ensures that the range 10000—16383 is free
+ for OIDs assigned automatically by <code class="filename">genbki.pl</code> or
+ during <span class="application">initdb</span>. These
+ automatically-assigned OIDs are not considered stable, and may change
+ from one installation to another.
+ </p></div><div class="sect2" id="SYSTEM-CATALOG-OID-REFERENCES"><div class="titlepage"><div><div><h3 class="title">74.2.3. OID Reference Lookup</h3></div></div></div><p>
+ In principle, cross-references from one initial catalog row to another
+ could be written just by writing the preassigned OID of the referenced
+ row in the referencing field. However, that is against project
+ policy, because it is error-prone, hard to read, and subject to
+ breakage if a newly-assigned OID is renumbered. Therefore
+ <code class="filename">genbki.pl</code> provides mechanisms to write
+ symbolic references instead.
+ The rules are as follows:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Use of symbolic references is enabled in a particular catalog column
+ by attaching <code class="literal">BKI_LOOKUP(<em class="replaceable"><code>lookuprule</code></em>)</code>
+ to the column's definition, where <em class="replaceable"><code>lookuprule</code></em>
+ is the name of the referenced catalog, e.g., <code class="literal">pg_proc</code>.
+ <code class="literal">BKI_LOOKUP</code> can be attached to columns of
+ type <code class="type">Oid</code>, <code class="type">regproc</code>, <code class="type">oidvector</code>,
+ or <code class="type">Oid[]</code>; in the latter two cases it implies performing a
+ lookup on each element of the array.
+ </p></li><li class="listitem"><p>
+ It's also permissible to attach <code class="literal">BKI_LOOKUP(encoding)</code>
+ to integer columns to reference character set encodings, which are
+ not currently represented as catalog OIDs, but have a set of values
+ known to <code class="filename">genbki.pl</code>.
+ </p></li><li class="listitem"><p>
+ In some catalog columns, it's allowed for entries to be zero instead
+ of a valid reference. If this is allowed, write
+ <code class="literal">BKI_LOOKUP_OPT</code> instead
+ of <code class="literal">BKI_LOOKUP</code>. Then you can
+ write <code class="literal">0</code> for an entry. (If the column is
+ declared <code class="type">regproc</code>, you can optionally
+ write <code class="literal">-</code> instead of <code class="literal">0</code>.)
+ Except for this special case, all entries in
+ a <code class="literal">BKI_LOOKUP</code> column must be symbolic references.
+ <code class="filename">genbki.pl</code> will warn about unrecognized names.
+ </p></li><li class="listitem"><p>
+ Most kinds of catalog objects are simply referenced by their names.
+ Note that type names must exactly match the
+ referenced <code class="structname">pg_type</code>
+ entry's <code class="structfield">typname</code>; you do not get to use
+ any aliases such as <code class="literal">integer</code>
+ for <code class="literal">int4</code>.
+ </p></li><li class="listitem"><p>
+ A function can be represented by
+ its <code class="structfield">proname</code>, if that is unique among
+ the <code class="filename">pg_proc.dat</code> entries (this works like regproc
+ input). Otherwise, write it
+ as <em class="replaceable"><code>proname(argtypename,argtypename,...)</code></em>,
+ like regprocedure. The argument type names must be spelled exactly as
+ they are in the <code class="filename">pg_proc.dat</code> entry's
+ <code class="structfield">proargtypes</code> field. Do not insert any
+ spaces.
+ </p></li><li class="listitem"><p>
+ Operators are represented
+ by <em class="replaceable"><code>oprname(lefttype,righttype)</code></em>,
+ writing the type names exactly as they appear in
+ the <code class="filename">pg_operator.dat</code>
+ entry's <code class="structfield">oprleft</code>
+ and <code class="structfield">oprright</code> fields.
+ (Write <code class="literal">0</code> for the omitted operand of a unary
+ operator.)
+ </p></li><li class="listitem"><p>
+ The names of opclasses and opfamilies are only unique within an
+ access method, so they are represented
+ by <em class="replaceable"><code>access_method_name</code></em><code class="literal">/</code><em class="replaceable"><code>object_name</code></em>.
+ </p></li><li class="listitem"><p>
+ In none of these cases is there any provision for
+ schema-qualification; all objects created during bootstrap are
+ expected to be in the <code class="literal">pg_catalog</code> schema.
+ </p></li></ul></div><p>
+ <code class="filename">genbki.pl</code> resolves all symbolic references while it
+ runs, and puts simple numeric OIDs into the emitted BKI file. There is
+ therefore no need for the bootstrap backend to deal with symbolic
+ references.
+ </p><p>
+ It's desirable to mark OID reference columns
+ with <code class="literal">BKI_LOOKUP</code> or <code class="literal">BKI_LOOKUP_OPT</code>
+ even if the catalog has no initial data that requires lookup. This
+ allows <code class="filename">genbki.pl</code> to record the foreign key
+ relationships that exist in the system catalogs. That information is
+ used in the regression tests to check for incorrect entries. See also
+ the macros <code class="literal">DECLARE_FOREIGN_KEY</code>,
+ <code class="literal">DECLARE_FOREIGN_KEY_OPT</code>,
+ <code class="literal">DECLARE_ARRAY_FOREIGN_KEY</code>,
+ and <code class="literal">DECLARE_ARRAY_FOREIGN_KEY_OPT</code>, which are
+ used to declare foreign key relationships that are too complex
+ for <code class="literal">BKI_LOOKUP</code> (typically, multi-column foreign
+ keys).
+ </p></div><div class="sect2" id="SYSTEM-CATALOG-AUTO-ARRAY-TYPES"><div class="titlepage"><div><div><h3 class="title">74.2.4. Automatic Creation of Array Types</h3></div></div></div><p>
+ Most scalar data types should have a corresponding array type (that is,
+ a standard varlena array type whose element type is the scalar type, and
+ which is referenced by the <code class="structfield">typarray</code> field of
+ the scalar type's <code class="structname">pg_type</code>
+ entry). <code class="filename">genbki.pl</code> is able to generate
+ the <code class="structname">pg_type</code> entry for the array type
+ automatically in most cases.
+ </p><p>
+ To use this facility, just write an <code class="literal">array_type_oid
+ =&gt; <em class="replaceable"><code>nnnn</code></em></code> metadata field in the
+ scalar type's <code class="structname">pg_type</code> entry, specifying the OID
+ to use for the array type. You may then omit
+ the <code class="structfield">typarray</code> field, since it will be filled
+ automatically with that OID.
+ </p><p>
+ The generated array type's name is the scalar type's name with an
+ underscore prepended. The array entry's other fields are filled from
+ <code class="literal">BKI_ARRAY_DEFAULT(<em class="replaceable"><code>value</code></em>)</code>
+ annotations in <code class="filename">pg_type.h</code>, or if there isn't one,
+ copied from the scalar type. (There's also a special case
+ for <code class="structfield">typalign</code>.) Then
+ the <code class="structfield">typelem</code>
+ and <code class="structfield">typarray</code> fields of the two entries are
+ set to cross-reference each other.
+ </p></div><div class="sect2" id="SYSTEM-CATALOG-RECIPES"><div class="titlepage"><div><div><h3 class="title">74.2.5. Recipes for Editing Data Files</h3></div></div></div><p>
+ Here are some suggestions about the easiest ways to perform common tasks
+ when updating catalog data files.
+ </p><p><strong>Add a new column with a default to a catalog: </strong>
+ Add the column to the header file with
+ a <code class="literal">BKI_DEFAULT(<em class="replaceable"><code>value</code></em>)</code>
+ annotation. The data file need only be adjusted by adding the field
+ in existing rows where a non-default value is needed.
+ </p><p><strong>Add a default value to an existing column that doesn't have
+ one: </strong>
+ Add a <code class="literal">BKI_DEFAULT</code> annotation to the header file,
+ then run <code class="literal">make reformat-dat-files</code> to remove
+ now-redundant field entries.
+ </p><p><strong>Remove a column, whether it has a default or not: </strong>
+ Remove the column from the header, then run <code class="literal">make
+ reformat-dat-files</code> to remove now-useless field entries.
+ </p><p><strong>Change or remove an existing default value: </strong>
+ You cannot simply change the header file, since that will cause the
+ current data to be interpreted incorrectly. First run <code class="literal">make
+ expand-dat-files</code> to rewrite the data files with all
+ default values inserted explicitly, then change or remove
+ the <code class="literal">BKI_DEFAULT</code> annotation, then run <code class="literal">make
+ reformat-dat-files</code> to remove superfluous fields again.
+ </p><p><strong>Ad-hoc bulk editing: </strong>
+ <code class="filename">reformat_dat_file.pl</code> can be adapted to perform
+ many kinds of bulk changes. Look for its block comments showing where
+ one-off code can be inserted. In the following example, we are going
+ to consolidate two Boolean fields in <code class="structname">pg_proc</code>
+ into a char field:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ Add the new column, with a default,
+ to <code class="filename">pg_proc.h</code>:
+</p><pre class="programlisting">
++ /* see PROKIND_ categories below */
++ char prokind BKI_DEFAULT(f);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Create a new script based on <code class="filename">reformat_dat_file.pl</code>
+ to insert appropriate values on-the-fly:
+</p><pre class="programlisting">
+- # At this point we have the full row in memory as a hash
+- # and can do any operations we want. As written, it only
+- # removes default values, but this script can be adapted to
+- # do one-off bulk-editing.
++ # One-off change to migrate to prokind
++ # Default has already been filled in by now, so change to other
++ # values as appropriate
++ if ($values{proisagg} eq 't')
++ {
++ $values{prokind} = 'a';
++ }
++ elsif ($values{proiswindow} eq 't')
++ {
++ $values{prokind} = 'w';
++ }
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Run the new script:
+</p><pre class="programlisting">
+$ cd src/include/catalog
+$ perl rewrite_dat_with_prokind.pl pg_proc.dat
+</pre><p>
+ At this point <code class="filename">pg_proc.dat</code> has all three
+ columns, <code class="structfield">prokind</code>,
+ <code class="structfield">proisagg</code>,
+ and <code class="structfield">proiswindow</code>, though they will appear
+ only in rows where they have non-default values.
+ </p></li><li class="listitem"><p>
+ Remove the old columns from <code class="filename">pg_proc.h</code>:
+</p><pre class="programlisting">
+- /* is it an aggregate? */
+- bool proisagg BKI_DEFAULT(f);
+-
+- /* is it a window function? */
+- bool proiswindow BKI_DEFAULT(f);
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Finally, run <code class="literal">make reformat-dat-files</code> to remove
+ the useless old entries from <code class="filename">pg_proc.dat</code>.
+ </p></li></ol></div><p>
+
+ For further examples of scripts used for bulk editing, see
+ <code class="filename">convert_oid2name.pl</code>
+ and <code class="filename">remove_pg_type_oid_symbols.pl</code> attached to this
+ message:
+ <a class="ulink" href="https://www.postgresql.org/message-id/CAJVSVGVX8gXnPm+Xa=DxR7kFYprcQ1tNcCT5D0O3ShfnM6jehA@mail.gmail.com" target="_top">https://www.postgresql.org/message-id/CAJVSVGVX8gXnPm+Xa=DxR7kFYprcQ1tNcCT5D0O3ShfnM6jehA@mail.gmail.com</a>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="system-catalog-declarations.html" title="74.1. System Catalog Declaration Rules">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="bki.html" title="Chapter 74. System Catalog Declarations and Initial Contents">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bki-format.html" title="74.3. BKI File Format">Next</a></td></tr><tr><td width="40%" align="left" valign="top">74.1. System Catalog Declaration Rules </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 74.3. <acronym class="acronym">BKI</acronym> File Format</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tableam.html b/doc/src/sgml/html/tableam.html
new file mode 100644
index 0000000..116baa8
--- /dev/null
+++ b/doc/src/sgml/html/tableam.html
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 63. Table Access Method Interface Definition</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="geqo-biblio.html" title="62.4. Further Reading" /><link rel="next" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 63. Table Access Method Interface Definition</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="geqo-biblio.html" title="62.4. Further Reading">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Next</a></td></tr></table><hr /></div><div class="chapter" id="TABLEAM"><div class="titlepage"><div><div><h2 class="title">Chapter 63. Table Access Method Interface Definition</h2></div></div></div><a id="id-1.10.14.2" class="indexterm"></a><a id="id-1.10.14.3" class="indexterm"></a><p>
+ This chapter explains the interface between the core
+ <span class="productname">PostgreSQL</span> system and <em class="firstterm">table access
+ methods</em>, which manage the storage for tables. The core system
+ knows little about these access methods beyond what is specified here, so
+ it is possible to develop entirely new access method types by writing
+ add-on code.
+ </p><p>
+ Each table access method is described by a row in the <a class="link" href="catalog-pg-am.html" title="53.3. pg_am"><code class="structname">pg_am</code></a> system
+ catalog. The <code class="structname">pg_am</code> entry specifies a name and a
+ <em class="firstterm">handler function</em> for the table access method. These
+ entries can be created and deleted using the <a class="xref" href="sql-create-access-method.html" title="CREATE ACCESS METHOD"><span class="refentrytitle">CREATE ACCESS METHOD</span></a> and <a class="xref" href="sql-drop-access-method.html" title="DROP ACCESS METHOD"><span class="refentrytitle">DROP ACCESS METHOD</span></a> SQL commands.
+ </p><p>
+ A table access method handler function must be declared to accept a single
+ argument of type <code class="type">internal</code> and to return the pseudo-type
+ <code class="type">table_am_handler</code>. The argument is a dummy value that simply
+ serves to prevent handler functions from being called directly from SQL commands.
+
+ The result of the function must be a pointer to a struct of type
+ <code class="structname">TableAmRoutine</code>, which contains everything that the
+ core code needs to know to make use of the table access method. The return
+ value needs to be of server lifetime, which is typically achieved by
+ defining it as a <code class="literal">static const</code> variable in global
+ scope. The <code class="structname">TableAmRoutine</code> struct, also called the
+ access method's <em class="firstterm">API struct</em>, defines the behavior of
+ the access method using callbacks. These callbacks are pointers to plain C
+ functions and are not visible or callable at the SQL level. All the
+ callbacks and their behavior is defined in the
+ <code class="structname">TableAmRoutine</code> structure (with comments inside the
+ struct defining the requirements for callbacks). Most callbacks have
+ wrapper functions, which are documented from the point of view of a user
+ (rather than an implementor) of the table access method. For details,
+ please refer to the <a class="ulink" href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/access/tableam.h;hb=HEAD" target="_top">
+ <code class="filename">src/include/access/tableam.h</code></a> file.
+ </p><p>
+ To implement an access method, an implementor will typically need to
+ implement an AM-specific type of tuple table slot (see
+ <a class="ulink" href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/executor/tuptable.h;hb=HEAD" target="_top">
+ <code class="filename">src/include/executor/tuptable.h</code></a>), which allows
+ code outside the access method to hold references to tuples of the AM, and
+ to access the columns of the tuple.
+ </p><p>
+ Currently, the way an AM actually stores data is fairly unconstrained. For
+ example, it's possible, but not required, to use postgres' shared buffer
+ cache. In case it is used, it likely makes sense to use
+ <span class="productname">PostgreSQL</span>'s standard page layout as described in
+ <a class="xref" href="storage-page-layout.html" title="73.6. Database Page Layout">Section 73.6</a>.
+ </p><p>
+ One fairly large constraint of the table access method API is that,
+ currently, if the AM wants to support modifications and/or indexes, it is
+ necessary for each tuple to have a tuple identifier (<acronym class="acronym">TID</acronym>)
+ consisting of a block number and an item number (see also <a class="xref" href="storage-page-layout.html" title="73.6. Database Page Layout">Section 73.6</a>). It is not strictly necessary that the
+ sub-parts of <acronym class="acronym">TIDs</acronym> have the same meaning they e.g., have
+ for <code class="literal">heap</code>, but if bitmap scan support is desired (it is
+ optional), the block number needs to provide locality.
+ </p><p>
+ For crash safety, an AM can use postgres' <a class="link" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log"><acronym class="acronym">WAL</acronym></a>, or a custom implementation.
+ If <acronym class="acronym">WAL</acronym> is chosen, either <a class="link" href="generic-wal.html" title="Chapter 65. Generic WAL Records">Generic WAL Records</a> can be used,
+ or a <a class="link" href="custom-rmgr.html" title="Chapter 66. Custom WAL Resource Managers">Custom WAL Resource Manager</a> can be
+ implemented.
+ </p><p>
+ To implement transactional support in a manner that allows different table
+ access methods be accessed within a single transaction, it likely is
+ necessary to closely integrate with the machinery in
+ <code class="filename">src/backend/access/transam/xlog.c</code>.
+ </p><p>
+ Any developer of a new <code class="literal">table access method</code> can refer to
+ the existing <code class="literal">heap</code> implementation present in
+ <code class="filename">src/backend/access/heap/heapam_handler.c</code> for details of
+ its implementation.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="geqo-biblio.html" title="62.4. Further Reading">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Next</a></td></tr><tr><td width="40%" align="left" valign="top">62.4. Further Reading </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 64. Index Access Method Interface Definition</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tablefunc.html b/doc/src/sgml/html/tablefunc.html
new file mode 100644
index 0000000..59d95e6
--- /dev/null
+++ b/doc/src/sgml/html/tablefunc.html
@@ -0,0 +1,613 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.43. tablefunc</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sslinfo.html" title="F.42. sslinfo" /><link rel="next" href="tcn.html" title="F.44. tcn" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.43. tablefunc</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sslinfo.html" title="F.42. sslinfo">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tcn.html" title="F.44. tcn">Next</a></td></tr></table><hr /></div><div class="sect1" id="TABLEFUNC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.43. tablefunc</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="tablefunc.html#id-1.11.7.52.5">F.43.1. Functions Provided</a></span></dt><dt><span class="sect2"><a href="tablefunc.html#id-1.11.7.52.6">F.43.2. Author</a></span></dt></dl></div><a id="id-1.11.7.52.2" class="indexterm"></a><p>
+ The <code class="filename">tablefunc</code> module includes various functions that return
+ tables (that is, multiple rows). These functions are useful both in their
+ own right and as examples of how to write C functions that return
+ multiple rows.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.52.5"><div class="titlepage"><div><div><h3 class="title">F.43.1. Functions Provided</h3></div></div></div><p>
+ <a class="xref" href="tablefunc.html#TABLEFUNC-FUNCTIONS" title="Table F.30. tablefunc Functions">Table F.30</a> summarizes the functions provided
+ by the <code class="filename">tablefunc</code> module.
+ </p><div class="table" id="TABLEFUNC-FUNCTIONS"><p class="title"><strong>Table F.30. <code class="filename">tablefunc</code> Functions</strong></p><div class="table-contents"><table class="table" summary="tablefunc Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">normal_rand</code> ( <em class="parameter"><code>numvals</code></em> <code class="type">integer</code>, <em class="parameter"><code>mean</code></em> <code class="type">float8</code>, <em class="parameter"><code>stddev</code></em> <code class="type">float8</code> )
+ → <code class="returnvalue">setof float8</code>
+ </p>
+ <p>
+ Produces a set of normally distributed random values.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">crosstab</code> ( <em class="parameter"><code>sql</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Produces a <span class="quote">“<span class="quote">pivot table</span>”</span> containing
+ row names plus <em class="replaceable"><code>N</code></em> value columns, where
+ <em class="replaceable"><code>N</code></em> is determined by the row type specified
+ in the calling query.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">crosstab<em class="replaceable"><code>N</code></em></code> ( <em class="parameter"><code>sql</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof table_crosstab_<em class="replaceable"><code>N</code></em></code>
+ </p>
+ <p>
+ Produces a <span class="quote">“<span class="quote">pivot table</span>”</span> containing
+ row names plus <em class="replaceable"><code>N</code></em> value columns.
+ <code class="function">crosstab2</code>, <code class="function">crosstab3</code>, and
+ <code class="function">crosstab4</code> are predefined, but you can create additional
+ <code class="function">crosstab<em class="replaceable"><code>N</code></em></code> functions as described below.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">crosstab</code> ( <em class="parameter"><code>source_sql</code></em> <code class="type">text</code>, <em class="parameter"><code>category_sql</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Produces a <span class="quote">“<span class="quote">pivot table</span>”</span>
+ with the value columns specified by a second query.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">crosstab</code> ( <em class="parameter"><code>sql</code></em> <code class="type">text</code>, <em class="parameter"><code>N</code></em> <code class="type">integer</code> )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Obsolete version of <code class="function">crosstab(text)</code>.
+ The parameter <em class="parameter"><code>N</code></em> is now ignored, since the
+ number of value columns is always determined by the calling query.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.52.5.3.2.2.6.1.1.1" class="indexterm"></a>
+ <code class="function">connectby</code> ( <em class="parameter"><code>relname</code></em> <code class="type">text</code>, <em class="parameter"><code>keyid_fld</code></em> <code class="type">text</code>, <em class="parameter"><code>parent_keyid_fld</code></em> <code class="type">text</code>
+ [<span class="optional">, <em class="parameter"><code>orderby_fld</code></em> <code class="type">text</code> </span>], <em class="parameter"><code>start_with</code></em> <code class="type">text</code>, <em class="parameter"><code>max_depth</code></em> <code class="type">integer</code>
+ [<span class="optional">, <em class="parameter"><code>branch_delim</code></em> <code class="type">text</code> </span>] )
+ → <code class="returnvalue">setof record</code>
+ </p>
+ <p>
+ Produces a representation of a hierarchical tree structure.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="sect3" id="id-1.11.7.52.5.4"><div class="titlepage"><div><div><h4 class="title">F.43.1.1. <code class="function">normal_rand</code></h4></div></div></div><a id="id-1.11.7.52.5.4.2" class="indexterm"></a><pre class="synopsis">
+normal_rand(int numvals, float8 mean, float8 stddev) returns setof float8
+</pre><p>
+ <code class="function">normal_rand</code> produces a set of normally distributed random
+ values (Gaussian distribution).
+ </p><p>
+ <em class="parameter"><code>numvals</code></em> is the number of values to be returned
+ from the function. <em class="parameter"><code>mean</code></em> is the mean of the normal
+ distribution of values and <em class="parameter"><code>stddev</code></em> is the standard
+ deviation of the normal distribution of values.
+ </p><p>
+ For example, this call requests 1000 values with a mean of 5 and a
+ standard deviation of 3:
+ </p><pre class="screen">
+test=# SELECT * FROM normal_rand(1000, 5, 3);
+ normal_rand
+----------------------
+ 1.56556322244898
+ 9.10040991424657
+ 5.36957140345079
+ -0.369151492880995
+ 0.283600703686639
+ .
+ .
+ .
+ 4.82992125404908
+ 9.71308014517282
+ 2.49639286969028
+(1000 rows)
+</pre></div><div class="sect3" id="id-1.11.7.52.5.5"><div class="titlepage"><div><div><h4 class="title">F.43.1.2. <code class="function">crosstab(text)</code></h4></div></div></div><a id="id-1.11.7.52.5.5.2" class="indexterm"></a><pre class="synopsis">
+crosstab(text sql)
+crosstab(text sql, int N)
+</pre><p>
+ The <code class="function">crosstab</code> function is used to produce <span class="quote">“<span class="quote">pivot</span>”</span>
+ displays, wherein data is listed across the page rather than down.
+ For example, we might have data like
+</p><pre class="programlisting">
+row1 val11
+row1 val12
+row1 val13
+...
+row2 val21
+row2 val22
+row2 val23
+...
+</pre><p>
+ which we wish to display like
+</p><pre class="programlisting">
+row1 val11 val12 val13 ...
+row2 val21 val22 val23 ...
+...
+</pre><p>
+ The <code class="function">crosstab</code> function takes a text parameter that is an SQL
+ query producing raw data formatted in the first way, and produces a table
+ formatted in the second way.
+ </p><p>
+ The <em class="parameter"><code>sql</code></em> parameter is an SQL statement that produces
+ the source set of data. This statement must return one
+ <code class="structfield">row_name</code> column, one
+ <code class="structfield">category</code> column, and one
+ <code class="structfield">value</code> column. <em class="parameter"><code>N</code></em> is an
+ obsolete parameter, ignored if supplied (formerly this had to match the
+ number of output value columns, but now that is determined by the
+ calling query).
+ </p><p>
+ For example, the provided query might produce a set something like:
+</p><pre class="programlisting">
+ row_name cat value
+----------+-------+-------
+ row1 cat1 val1
+ row1 cat2 val2
+ row1 cat3 val3
+ row1 cat4 val4
+ row2 cat1 val5
+ row2 cat2 val6
+ row2 cat3 val7
+ row2 cat4 val8
+</pre><p>
+ </p><p>
+ The <code class="function">crosstab</code> function is declared to return <code class="type">setof
+ record</code>, so the actual names and types of the output columns must be
+ defined in the <code class="literal">FROM</code> clause of the calling <code class="command">SELECT</code>
+ statement, for example:
+</p><pre class="programlisting">
+SELECT * FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text);
+</pre><p>
+ This example produces a set something like:
+</p><pre class="programlisting">
+ &lt;== value columns ==&gt;
+ row_name category_1 category_2
+----------+------------+------------
+ row1 val1 val2
+ row2 val5 val6
+</pre><p>
+ </p><p>
+ The <code class="literal">FROM</code> clause must define the output as one
+ <code class="structfield">row_name</code> column (of the same data type as the first result
+ column of the SQL query) followed by N <code class="structfield">value</code> columns
+ (all of the same data type as the third result column of the SQL query).
+ You can set up as many output value columns as you wish. The names of the
+ output columns are up to you.
+ </p><p>
+ The <code class="function">crosstab</code> function produces one output row for each
+ consecutive group of input rows with the same
+ <code class="structfield">row_name</code> value. It fills the output
+ <code class="structfield">value</code> columns, left to right, with the
+ <code class="structfield">value</code> fields from these rows. If there
+ are fewer rows in a group than there are output <code class="structfield">value</code>
+ columns, the extra output columns are filled with nulls; if there are
+ more rows, the extra input rows are skipped.
+ </p><p>
+ In practice the SQL query should always specify <code class="literal">ORDER BY 1,2</code>
+ to ensure that the input rows are properly ordered, that is, values with
+ the same <code class="structfield">row_name</code> are brought together and
+ correctly ordered within the row. Notice that <code class="function">crosstab</code>
+ itself does not pay any attention to the second column of the query
+ result; it's just there to be ordered by, to control the order in which
+ the third-column values appear across the page.
+ </p><p>
+ Here is a complete example:
+</p><pre class="programlisting">
+CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3');
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att4','val4');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att1','val5');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att2','val6');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att3','val7');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att4','val8');
+
+SELECT *
+FROM crosstab(
+ 'select rowid, attribute, value
+ from ct
+ where attribute = ''att2'' or attribute = ''att3''
+ order by 1,2')
+AS ct(row_name text, category_1 text, category_2 text, category_3 text);
+
+ row_name | category_1 | category_2 | category_3
+----------+------------+------------+------------
+ test1 | val2 | val3 |
+ test2 | val6 | val7 |
+(2 rows)
+</pre><p>
+ </p><p>
+ You can avoid always having to write out a <code class="literal">FROM</code> clause to
+ define the output columns, by setting up a custom crosstab function that
+ has the desired output row type wired into its definition. This is
+ described in the next section. Another possibility is to embed the
+ required <code class="literal">FROM</code> clause in a view definition.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ See also the <code class="command"><a class="link" href="app-psql.html#APP-PSQL-META-COMMANDS-CROSSTABVIEW">\crosstabview</a></code>
+ command in <span class="application">psql</span>, which provides functionality similar
+ to <code class="function">crosstab()</code>.
+ </p></div></div><div class="sect3" id="id-1.11.7.52.5.6"><div class="titlepage"><div><div><h4 class="title">F.43.1.3. <code class="function">crosstab<em class="replaceable"><code>N</code></em>(text)</code></h4></div></div></div><a id="id-1.11.7.52.5.6.2" class="indexterm"></a><pre class="synopsis">
+crosstab<em class="replaceable"><code>N</code></em>(text sql)
+</pre><p>
+ The <code class="function">crosstab<em class="replaceable"><code>N</code></em></code> functions are examples of how
+ to set up custom wrappers for the general <code class="function">crosstab</code> function,
+ so that you need not write out column names and types in the calling
+ <code class="command">SELECT</code> query. The <code class="filename">tablefunc</code> module includes
+ <code class="function">crosstab2</code>, <code class="function">crosstab3</code>, and
+ <code class="function">crosstab4</code>, whose output row types are defined as
+ </p><pre class="programlisting">
+CREATE TYPE tablefunc_crosstab_N AS (
+ row_name TEXT,
+ category_1 TEXT,
+ category_2 TEXT,
+ .
+ .
+ .
+ category_N TEXT
+);
+</pre><p>
+ Thus, these functions can be used directly when the input query produces
+ <code class="structfield">row_name</code> and <code class="structfield">value</code> columns of type
+ <code class="type">text</code>, and you want 2, 3, or 4 output values columns.
+ In all other ways they behave exactly as described above for the
+ general <code class="function">crosstab</code> function.
+ </p><p>
+ For instance, the example given in the previous section would also
+ work as
+</p><pre class="programlisting">
+SELECT *
+FROM crosstab3(
+ 'select rowid, attribute, value
+ from ct
+ where attribute = ''att2'' or attribute = ''att3''
+ order by 1,2');
+</pre><p>
+ </p><p>
+ These functions are provided mostly for illustration purposes. You
+ can create your own return types and functions based on the
+ underlying <code class="function">crosstab()</code> function. There are two ways
+ to do it:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Create a composite type describing the desired output columns,
+ similar to the examples in
+ <code class="filename">contrib/tablefunc/tablefunc--1.0.sql</code>.
+ Then define a
+ unique function name accepting one <code class="type">text</code> parameter and returning
+ <code class="type">setof your_type_name</code>, but linking to the same underlying
+ <code class="function">crosstab</code> C function. For example, if your source data
+ produces row names that are <code class="type">text</code>, and values that are
+ <code class="type">float8</code>, and you want 5 value columns:
+</p><pre class="programlisting">
+CREATE TYPE my_crosstab_float8_5_cols AS (
+ my_row_name text,
+ my_category_1 float8,
+ my_category_2 float8,
+ my_category_3 float8,
+ my_category_4 float8,
+ my_category_5 float8
+);
+
+CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(text)
+ RETURNS setof my_crosstab_float8_5_cols
+ AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
+</pre><p>
+ </p></li><li class="listitem"><p>
+ Use <code class="literal">OUT</code> parameters to define the return type implicitly.
+ The same example could also be done this way:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(
+ IN text,
+ OUT my_row_name text,
+ OUT my_category_1 float8,
+ OUT my_category_2 float8,
+ OUT my_category_3 float8,
+ OUT my_category_4 float8,
+ OUT my_category_5 float8)
+ RETURNS setof record
+ AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
+</pre><p>
+ </p></li></ul></div><p>
+ </p></div><div class="sect3" id="id-1.11.7.52.5.7"><div class="titlepage"><div><div><h4 class="title">F.43.1.4. <code class="function">crosstab(text, text)</code></h4></div></div></div><a id="id-1.11.7.52.5.7.2" class="indexterm"></a><pre class="synopsis">
+crosstab(text source_sql, text category_sql)
+</pre><p>
+ The main limitation of the single-parameter form of <code class="function">crosstab</code>
+ is that it treats all values in a group alike, inserting each value into
+ the first available column. If you want the value
+ columns to correspond to specific categories of data, and some groups
+ might not have data for some of the categories, that doesn't work well.
+ The two-parameter form of <code class="function">crosstab</code> handles this case by
+ providing an explicit list of the categories corresponding to the
+ output columns.
+ </p><p>
+ <em class="parameter"><code>source_sql</code></em> is an SQL statement that produces the
+ source set of data. This statement must return one
+ <code class="structfield">row_name</code> column, one
+ <code class="structfield">category</code> column, and one
+ <code class="structfield">value</code> column. It may also have one or more
+ <span class="quote">“<span class="quote">extra</span>”</span> columns.
+ The <code class="structfield">row_name</code> column must be first. The
+ <code class="structfield">category</code> and <code class="structfield">value</code>
+ columns must be the last two columns, in that order. Any columns between
+ <code class="structfield">row_name</code> and
+ <code class="structfield">category</code> are treated as <span class="quote">“<span class="quote">extra</span>”</span>.
+ The <span class="quote">“<span class="quote">extra</span>”</span> columns are expected to be the same for all rows
+ with the same <code class="structfield">row_name</code> value.
+ </p><p>
+ For example, <em class="parameter"><code>source_sql</code></em> might produce a set
+ something like:
+</p><pre class="programlisting">
+SELECT row_name, extra_col, cat, value FROM foo ORDER BY 1;
+
+ row_name extra_col cat value
+----------+------------+-----+---------
+ row1 extra1 cat1 val1
+ row1 extra1 cat2 val2
+ row1 extra1 cat4 val4
+ row2 extra2 cat1 val5
+ row2 extra2 cat2 val6
+ row2 extra2 cat3 val7
+ row2 extra2 cat4 val8
+</pre><p>
+ </p><p>
+ <em class="parameter"><code>category_sql</code></em> is an SQL statement that produces
+ the set of categories. This statement must return only one column.
+ It must produce at least one row, or an error will be generated.
+ Also, it must not produce duplicate values, or an error will be
+ generated. <em class="parameter"><code>category_sql</code></em> might be something like:
+
+</p><pre class="programlisting">
+SELECT DISTINCT cat FROM foo ORDER BY 1;
+ cat
+ -------
+ cat1
+ cat2
+ cat3
+ cat4
+</pre><p>
+ </p><p>
+ The <code class="function">crosstab</code> function is declared to return <code class="type">setof
+ record</code>, so the actual names and types of the output columns must be
+ defined in the <code class="literal">FROM</code> clause of the calling <code class="command">SELECT</code>
+ statement, for example:
+
+</p><pre class="programlisting">
+SELECT * FROM crosstab('...', '...')
+ AS ct(row_name text, extra text, cat1 text, cat2 text, cat3 text, cat4 text);
+</pre><p>
+ </p><p>
+ This will produce a result something like:
+</p><pre class="programlisting">
+ &lt;== value columns ==&gt;
+row_name extra cat1 cat2 cat3 cat4
+---------+-------+------+------+------+------
+ row1 extra1 val1 val2 val4
+ row2 extra2 val5 val6 val7 val8
+</pre><p>
+ </p><p>
+ The <code class="literal">FROM</code> clause must define the proper number of output
+ columns of the proper data types. If there are <em class="replaceable"><code>N</code></em>
+ columns in the <em class="parameter"><code>source_sql</code></em> query's result, the first
+ <em class="replaceable"><code>N</code></em>-2 of them must match up with the first
+ <em class="replaceable"><code>N</code></em>-2 output columns. The remaining output columns
+ must have the type of the last column of the <em class="parameter"><code>source_sql</code></em>
+ query's result, and there must be exactly as many of them as there
+ are rows in the <em class="parameter"><code>category_sql</code></em> query's result.
+ </p><p>
+ The <code class="function">crosstab</code> function produces one output row for each
+ consecutive group of input rows with the same
+ <code class="structfield">row_name</code> value. The output
+ <code class="structfield">row_name</code> column, plus any <span class="quote">“<span class="quote">extra</span>”</span>
+ columns, are copied from the first row of the group. The output
+ <code class="structfield">value</code> columns are filled with the
+ <code class="structfield">value</code> fields from rows having matching
+ <code class="structfield">category</code> values. If a row's <code class="structfield">category</code>
+ does not match any output of the <em class="parameter"><code>category_sql</code></em>
+ query, its <code class="structfield">value</code> is ignored. Output
+ columns whose matching category is not present in any input row
+ of the group are filled with nulls.
+ </p><p>
+ In practice the <em class="parameter"><code>source_sql</code></em> query should always
+ specify <code class="literal">ORDER BY 1</code> to ensure that values with the same
+ <code class="structfield">row_name</code> are brought together. However,
+ ordering of the categories within a group is not important.
+ Also, it is essential to be sure that the order of the
+ <em class="parameter"><code>category_sql</code></em> query's output matches the specified
+ output column order.
+ </p><p>
+ Here are two complete examples:
+</p><pre class="programlisting">
+create table sales(year int, month int, qty int);
+insert into sales values(2007, 1, 1000);
+insert into sales values(2007, 2, 1500);
+insert into sales values(2007, 7, 500);
+insert into sales values(2007, 11, 1500);
+insert into sales values(2007, 12, 2000);
+insert into sales values(2008, 1, 1000);
+
+select * from crosstab(
+ 'select year, month, qty from sales order by 1',
+ 'select m from generate_series(1,12) m'
+) as (
+ year int,
+ "Jan" int,
+ "Feb" int,
+ "Mar" int,
+ "Apr" int,
+ "May" int,
+ "Jun" int,
+ "Jul" int,
+ "Aug" int,
+ "Sep" int,
+ "Oct" int,
+ "Nov" int,
+ "Dec" int
+);
+ year | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
+------+------+------+-----+-----+-----+-----+-----+-----+-----+-----+------+------
+ 2007 | 1000 | 1500 | | | | | 500 | | | | 1500 | 2000
+ 2008 | 1000 | | | | | | | | | | |
+(2 rows)
+</pre><p>
+
+</p><pre class="programlisting">
+CREATE TABLE cth(rowid text, rowdt timestamp, attribute text, val text);
+INSERT INTO cth VALUES('test1','01 March 2003','temperature','42');
+INSERT INTO cth VALUES('test1','01 March 2003','test_result','PASS');
+INSERT INTO cth VALUES('test1','01 March 2003','volts','2.6987');
+INSERT INTO cth VALUES('test2','02 March 2003','temperature','53');
+INSERT INTO cth VALUES('test2','02 March 2003','test_result','FAIL');
+INSERT INTO cth VALUES('test2','02 March 2003','test_startdate','01 March 2003');
+INSERT INTO cth VALUES('test2','02 March 2003','volts','3.1234');
+
+SELECT * FROM crosstab
+(
+ 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
+ 'SELECT DISTINCT attribute FROM cth ORDER BY 1'
+)
+AS
+(
+ rowid text,
+ rowdt timestamp,
+ temperature int4,
+ test_result text,
+ test_startdate timestamp,
+ volts float8
+);
+ rowid | rowdt | temperature | test_result | test_startdate | volts
+-------+--------------------------+-------------+-------------+--------------------------+--------
+ test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
+ test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
+(2 rows)
+</pre><p>
+ </p><p>
+ You can create predefined functions to avoid having to write out
+ the result column names and types in each query. See the examples
+ in the previous section. The underlying C function for this form
+ of <code class="function">crosstab</code> is named <code class="literal">crosstab_hash</code>.
+ </p></div><div class="sect3" id="id-1.11.7.52.5.8"><div class="titlepage"><div><div><h4 class="title">F.43.1.5. <code class="function">connectby</code></h4></div></div></div><a id="id-1.11.7.52.5.8.2" class="indexterm"></a><pre class="synopsis">
+connectby(text relname, text keyid_fld, text parent_keyid_fld
+ [, text orderby_fld ], text start_with, int max_depth
+ [, text branch_delim ])
+</pre><p>
+ The <code class="function">connectby</code> function produces a display of hierarchical
+ data that is stored in a table. The table must have a key field that
+ uniquely identifies rows, and a parent-key field that references the
+ parent (if any) of each row. <code class="function">connectby</code> can display the
+ sub-tree descending from any row.
+ </p><p>
+ <a class="xref" href="tablefunc.html#TABLEFUNC-CONNECTBY-PARAMETERS" title="Table F.31. connectby Parameters">Table F.31</a> explains the
+ parameters.
+ </p><div class="table" id="TABLEFUNC-CONNECTBY-PARAMETERS"><p class="title"><strong>Table F.31. <code class="function">connectby</code> Parameters</strong></p><div class="table-contents"><table class="table" summary="connectby Parameters" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Parameter</th><th>Description</th></tr></thead><tbody><tr><td><em class="parameter"><code>relname</code></em></td><td>Name of the source relation</td></tr><tr><td><em class="parameter"><code>keyid_fld</code></em></td><td>Name of the key field</td></tr><tr><td><em class="parameter"><code>parent_keyid_fld</code></em></td><td>Name of the parent-key field</td></tr><tr><td><em class="parameter"><code>orderby_fld</code></em></td><td>Name of the field to order siblings by (optional)</td></tr><tr><td><em class="parameter"><code>start_with</code></em></td><td>Key value of the row to start at</td></tr><tr><td><em class="parameter"><code>max_depth</code></em></td><td>Maximum depth to descend to, or zero for unlimited depth</td></tr><tr><td><em class="parameter"><code>branch_delim</code></em></td><td>String to separate keys with in branch output (optional)</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The key and parent-key fields can be any data type, but they must be
+ the same type. Note that the <em class="parameter"><code>start_with</code></em> value must be
+ entered as a text string, regardless of the type of the key field.
+ </p><p>
+ The <code class="function">connectby</code> function is declared to return <code class="type">setof
+ record</code>, so the actual names and types of the output columns must be
+ defined in the <code class="literal">FROM</code> clause of the calling <code class="command">SELECT</code>
+ statement, for example:
+ </p><pre class="programlisting">
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text, pos int);
+</pre><p>
+ The first two output columns are used for the current row's key and
+ its parent row's key; they must match the type of the table's key field.
+ The third output column is the depth in the tree and must be of type
+ <code class="type">integer</code>. If a <em class="parameter"><code>branch_delim</code></em> parameter was
+ given, the next output column is the branch display and must be of type
+ <code class="type">text</code>. Finally, if an <em class="parameter"><code>orderby_fld</code></em>
+ parameter was given, the last output column is a serial number, and must
+ be of type <code class="type">integer</code>.
+ </p><p>
+ The <span class="quote">“<span class="quote">branch</span>”</span> output column shows the path of keys taken to
+ reach the current row. The keys are separated by the specified
+ <em class="parameter"><code>branch_delim</code></em> string. If no branch display is
+ wanted, omit both the <em class="parameter"><code>branch_delim</code></em> parameter
+ and the branch column in the output column list.
+ </p><p>
+ If the ordering of siblings of the same parent is important,
+ include the <em class="parameter"><code>orderby_fld</code></em> parameter to
+ specify which field to order siblings by. This field can be of any
+ sortable data type. The output column list must include a final
+ integer serial-number column, if and only if
+ <em class="parameter"><code>orderby_fld</code></em> is specified.
+ </p><p>
+ The parameters representing table and field names are copied as-is
+ into the SQL queries that <code class="function">connectby</code> generates internally.
+ Therefore, include double quotes if the names are mixed-case or contain
+ special characters. You may also need to schema-qualify the table name.
+ </p><p>
+ In large tables, performance will be poor unless there is an index on
+ the parent-key field.
+ </p><p>
+ It is important that the <em class="parameter"><code>branch_delim</code></em> string
+ not appear in any key values, else <code class="function">connectby</code> may incorrectly
+ report an infinite-recursion error. Note that if
+ <em class="parameter"><code>branch_delim</code></em> is not provided, a default value
+ of <code class="literal">~</code> is used for recursion detection purposes.
+
+ </p><p>
+ Here is an example:
+</p><pre class="programlisting">
+CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int);
+
+INSERT INTO connectby_tree VALUES('row1',NULL, 0);
+INSERT INTO connectby_tree VALUES('row2','row1', 0);
+INSERT INTO connectby_tree VALUES('row3','row1', 0);
+INSERT INTO connectby_tree VALUES('row4','row2', 1);
+INSERT INTO connectby_tree VALUES('row5','row2', 0);
+INSERT INTO connectby_tree VALUES('row6','row4', 0);
+INSERT INTO connectby_tree VALUES('row7','row3', 0);
+INSERT INTO connectby_tree VALUES('row8','row6', 0);
+INSERT INTO connectby_tree VALUES('row9','row5', 0);
+
+-- with branch, without orderby_fld (order of results is not guaranteed)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text);
+ keyid | parent_keyid | level | branch
+-------+--------------+-------+---------------------
+ row2 | | 0 | row2
+ row4 | row2 | 1 | row2~row4
+ row6 | row4 | 2 | row2~row4~row6
+ row8 | row6 | 3 | row2~row4~row6~row8
+ row5 | row2 | 1 | row2~row5
+ row9 | row5 | 2 | row2~row5~row9
+(6 rows)
+
+-- without branch, without orderby_fld (order of results is not guaranteed)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0)
+ AS t(keyid text, parent_keyid text, level int);
+ keyid | parent_keyid | level
+-------+--------------+-------
+ row2 | | 0
+ row4 | row2 | 1
+ row6 | row4 | 2
+ row8 | row6 | 3
+ row5 | row2 | 1
+ row9 | row5 | 2
+(6 rows)
+
+-- with branch, with orderby_fld (notice that row5 comes before row4)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text, pos int);
+ keyid | parent_keyid | level | branch | pos
+-------+--------------+-------+---------------------+-----
+ row2 | | 0 | row2 | 1
+ row5 | row2 | 1 | row2~row5 | 2
+ row9 | row5 | 2 | row2~row5~row9 | 3
+ row4 | row2 | 1 | row2~row4 | 4
+ row6 | row4 | 2 | row2~row4~row6 | 5
+ row8 | row6 | 3 | row2~row4~row6~row8 | 6
+(6 rows)
+
+-- without branch, with orderby_fld (notice that row5 comes before row4)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0)
+ AS t(keyid text, parent_keyid text, level int, pos int);
+ keyid | parent_keyid | level | pos
+-------+--------------+-------+-----
+ row2 | | 0 | 1
+ row5 | row2 | 1 | 2
+ row9 | row5 | 2 | 3
+ row4 | row2 | 1 | 4
+ row6 | row4 | 2 | 5
+ row8 | row6 | 3 | 6
+(6 rows)
+</pre><p>
+ </p></div></div><div class="sect2" id="id-1.11.7.52.6"><div class="titlepage"><div><div><h3 class="title">F.43.2. Author</h3></div></div></div><p>
+ Joe Conway
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sslinfo.html" title="F.42. sslinfo">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tcn.html" title="F.44. tcn">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.42. sslinfo </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.44. tcn</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tablesample-method.html b/doc/src/sgml/html/tablesample-method.html
new file mode 100644
index 0000000..3697e6c
--- /dev/null
+++ b/doc/src/sgml/html/tablesample-method.html
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 60. Writing a Table Sampling Method</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers" /><link rel="next" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 60. Writing a Table Sampling Method</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions">Next</a></td></tr></table><hr /></div><div class="chapter" id="TABLESAMPLE-METHOD"><div class="titlepage"><div><div><h2 class="title">Chapter 60. Writing a Table Sampling Method</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="tablesample-support-functions.html">60.1. Sampling Method Support Functions</a></span></dt></dl></div><a id="id-1.10.11.2" class="indexterm"></a><a id="id-1.10.11.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span>'s implementation of the <code class="literal">TABLESAMPLE</code>
+ clause supports custom table sampling methods, in addition to
+ the <code class="literal">BERNOULLI</code> and <code class="literal">SYSTEM</code> methods that are required
+ by the SQL standard. The sampling method determines which rows of the
+ table will be selected when the <code class="literal">TABLESAMPLE</code> clause is used.
+ </p><p>
+ At the SQL level, a table sampling method is represented by a single SQL
+ function, typically implemented in C, having the signature
+</p><pre class="programlisting">
+method_name(internal) RETURNS tsm_handler
+</pre><p>
+ The name of the function is the same method name appearing in the
+ <code class="literal">TABLESAMPLE</code> clause. The <code class="type">internal</code> argument is a dummy
+ (always having value zero) that simply serves to prevent this function from
+ being called directly from an SQL command.
+ The result of the function must be a palloc'd struct of
+ type <code class="type">TsmRoutine</code>, which contains pointers to support functions for
+ the sampling method. These support functions are plain C functions and
+ are not visible or callable at the SQL level. The support functions are
+ described in <a class="xref" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions">Section 60.1</a>.
+ </p><p>
+ In addition to function pointers, the <code class="type">TsmRoutine</code> struct must
+ provide these additional fields:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">List *parameterTypes</code></span></dt><dd><p>
+ This is an OID list containing the data type OIDs of the parameter(s)
+ that will be accepted by the <code class="literal">TABLESAMPLE</code> clause when this
+ sampling method is used. For example, for the built-in methods, this
+ list contains a single item with value <code class="literal">FLOAT4OID</code>, which
+ represents the sampling percentage. Custom sampling methods can have
+ more or different parameters.
+ </p></dd><dt><span class="term"><code class="literal">bool repeatable_across_queries</code></span></dt><dd><p>
+ If <code class="literal">true</code>, the sampling method can deliver identical samples
+ across successive queries, if the same parameters
+ and <code class="literal">REPEATABLE</code> seed value are supplied each time and the
+ table contents have not changed. When this is <code class="literal">false</code>,
+ the <code class="literal">REPEATABLE</code> clause is not accepted for use with the
+ sampling method.
+ </p></dd><dt><span class="term"><code class="literal">bool repeatable_across_scans</code></span></dt><dd><p>
+ If <code class="literal">true</code>, the sampling method can deliver identical samples
+ across successive scans in the same query (assuming unchanging
+ parameters, seed value, and snapshot).
+ When this is <code class="literal">false</code>, the planner will not select plans that
+ would require scanning the sampled table more than once, since that
+ might result in inconsistent query output.
+ </p></dd></dl></div><p>
+ The <code class="type">TsmRoutine</code> struct type is declared
+ in <code class="filename">src/include/access/tsmapi.h</code>, which see for additional
+ details.
+ </p><p>
+ The table sampling methods included in the standard distribution are good
+ references when trying to write your own. Look into
+ the <code class="filename">src/backend/access/tablesample</code> subdirectory of the source
+ tree for the built-in sampling methods, and into the <code class="filename">contrib</code>
+ subdirectory for add-on methods.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-row-locking.html" title="59.5. Row Locking in Foreign Data Wrappers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tablesample-support-functions.html" title="60.1. Sampling Method Support Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">59.5. Row Locking in Foreign Data Wrappers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 60.1. Sampling Method Support Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tablesample-support-functions.html b/doc/src/sgml/html/tablesample-support-functions.html
new file mode 100644
index 0000000..6228881
--- /dev/null
+++ b/doc/src/sgml/html/tablesample-support-functions.html
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>60.1. Sampling Method Support Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method" /><link rel="next" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">60.1. Sampling Method Support Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method">Up</a></td><th width="60%" align="center">Chapter 60. Writing a Table Sampling Method</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Next</a></td></tr></table><hr /></div><div class="sect1" id="TABLESAMPLE-SUPPORT-FUNCTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">60.1. Sampling Method Support Functions</h2></div></div></div><p>
+ The TSM handler function returns a palloc'd <code class="type">TsmRoutine</code> struct
+ containing pointers to the support functions described below. Most of
+ the functions are required, but some are optional, and those pointers can
+ be NULL.
+ </p><p>
+</p><pre class="programlisting">
+void
+SampleScanGetSampleSize (PlannerInfo *root,
+ RelOptInfo *baserel,
+ List *paramexprs,
+ BlockNumber *pages,
+ double *tuples);
+</pre><p>
+
+ This function is called during planning. It must estimate the number of
+ relation pages that will be read during a sample scan, and the number of
+ tuples that will be selected by the scan. (For example, these might be
+ determined by estimating the sampling fraction, and then multiplying
+ the <code class="literal">baserel-&gt;pages</code> and <code class="literal">baserel-&gt;tuples</code>
+ numbers by that, being sure to round the results to integral values.)
+ The <code class="literal">paramexprs</code> list holds the expression(s) that are
+ parameters to the <code class="literal">TABLESAMPLE</code> clause. It is recommended to
+ use <code class="function">estimate_expression_value()</code> to try to reduce these
+ expressions to constants, if their values are needed for estimation
+ purposes; but the function must provide size estimates even if they cannot
+ be reduced, and it should not fail even if the values appear invalid
+ (remember that they're only estimates of what the run-time values will be).
+ The <code class="literal">pages</code> and <code class="literal">tuples</code> parameters are outputs.
+ </p><p>
+</p><pre class="programlisting">
+void
+InitSampleScan (SampleScanState *node,
+ int eflags);
+</pre><p>
+
+ Initialize for execution of a SampleScan plan node.
+ This is called during executor startup.
+ It should perform any initialization needed before processing can start.
+ The <code class="structname">SampleScanState</code> node has already been created, but
+ its <code class="structfield">tsm_state</code> field is NULL.
+ The <code class="function">InitSampleScan</code> function can palloc whatever internal
+ state data is needed by the sampling method, and store a pointer to
+ it in <code class="literal">node-&gt;tsm_state</code>.
+ Information about the table to scan is accessible through other fields
+ of the <code class="structname">SampleScanState</code> node (but note that the
+ <code class="literal">node-&gt;ss.ss_currentScanDesc</code> scan descriptor is not set
+ up yet).
+ <code class="literal">eflags</code> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </p><p>
+ When <code class="literal">(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</code> is true,
+ the scan will not actually be performed, so this function should only do
+ the minimum required to make the node state valid for <code class="command">EXPLAIN</code>
+ and <code class="function">EndSampleScan</code>.
+ </p><p>
+ This function can be omitted (set the pointer to NULL), in which case
+ <code class="function">BeginSampleScan</code> must perform all initialization needed
+ by the sampling method.
+ </p><p>
+</p><pre class="programlisting">
+void
+BeginSampleScan (SampleScanState *node,
+ Datum *params,
+ int nparams,
+ uint32 seed);
+</pre><p>
+
+ Begin execution of a sampling scan.
+ This is called just before the first attempt to fetch a tuple, and
+ may be called again if the scan needs to be restarted.
+ Information about the table to scan is accessible through fields
+ of the <code class="structname">SampleScanState</code> node (but note that the
+ <code class="literal">node-&gt;ss.ss_currentScanDesc</code> scan descriptor is not set
+ up yet).
+ The <code class="literal">params</code> array, of length <code class="literal">nparams</code>, contains the
+ values of the parameters supplied in the <code class="literal">TABLESAMPLE</code> clause.
+ These will have the number and types specified in the sampling
+ method's <code class="literal">parameterTypes</code> list, and have been checked
+ to not be null.
+ <code class="literal">seed</code> contains a seed to use for any random numbers generated
+ within the sampling method; it is either a hash derived from the
+ <code class="literal">REPEATABLE</code> value if one was given, or the result
+ of <code class="literal">random()</code> if not.
+ </p><p>
+ This function may adjust the fields <code class="literal">node-&gt;use_bulkread</code>
+ and <code class="literal">node-&gt;use_pagemode</code>.
+ If <code class="literal">node-&gt;use_bulkread</code> is <code class="literal">true</code>, which it is by
+ default, the scan will use a buffer access strategy that encourages
+ recycling buffers after use. It might be reasonable to set this
+ to <code class="literal">false</code> if the scan will visit only a small fraction of the
+ table's pages.
+ If <code class="literal">node-&gt;use_pagemode</code> is <code class="literal">true</code>, which it is by
+ default, the scan will perform visibility checking in a single pass for
+ all tuples on each visited page. It might be reasonable to set this
+ to <code class="literal">false</code> if the scan will select only a small fraction of the
+ tuples on each visited page. That will result in fewer tuple visibility
+ checks being performed, though each one will be more expensive because it
+ will require more locking.
+ </p><p>
+ If the sampling method is
+ marked <code class="literal">repeatable_across_scans</code>, it must be able to
+ select the same set of tuples during a rescan as it did originally, that is
+ a fresh call of <code class="function">BeginSampleScan</code> must lead to selecting the
+ same tuples as before (if the <code class="literal">TABLESAMPLE</code> parameters
+ and seed don't change).
+ </p><p>
+</p><pre class="programlisting">
+BlockNumber
+NextSampleBlock (SampleScanState *node, BlockNumber nblocks);
+</pre><p>
+
+ Returns the block number of the next page to be scanned, or
+ <code class="literal">InvalidBlockNumber</code> if no pages remain to be scanned.
+ </p><p>
+ This function can be omitted (set the pointer to NULL), in which case
+ the core code will perform a sequential scan of the entire relation.
+ Such a scan can use synchronized scanning, so that the sampling method
+ cannot assume that the relation pages are visited in the same order on
+ each scan.
+ </p><p>
+</p><pre class="programlisting">
+OffsetNumber
+NextSampleTuple (SampleScanState *node,
+ BlockNumber blockno,
+ OffsetNumber maxoffset);
+</pre><p>
+
+ Returns the offset number of the next tuple to be sampled on the
+ specified page, or <code class="literal">InvalidOffsetNumber</code> if no tuples remain to
+ be sampled. <code class="literal">maxoffset</code> is the largest offset number in use
+ on the page.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="function">NextSampleTuple</code> is not explicitly told which of the offset
+ numbers in the range <code class="literal">1 .. maxoffset</code> actually contain valid
+ tuples. This is not normally a problem since the core code ignores
+ requests to sample missing or invisible tuples; that should not result in
+ any bias in the sample. However, if necessary, the function can use
+ <code class="literal">node-&gt;donetuples</code> to examine how many of the tuples
+ it returned were valid and visible.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ <code class="function">NextSampleTuple</code> must <span class="emphasis"><em>not</em></span> assume
+ that <code class="literal">blockno</code> is the same page number returned by the most
+ recent <code class="function">NextSampleBlock</code> call. It was returned by some
+ previous <code class="function">NextSampleBlock</code> call, but the core code is allowed
+ to call <code class="function">NextSampleBlock</code> in advance of actually scanning
+ pages, so as to support prefetching. It is OK to assume that once
+ sampling of a given page begins, successive <code class="function">NextSampleTuple</code>
+ calls all refer to the same page until <code class="literal">InvalidOffsetNumber</code> is
+ returned.
+ </p></div><p>
+</p><pre class="programlisting">
+void
+EndSampleScan (SampleScanState *node);
+</pre><p>
+
+ End the scan and release resources. It is normally not important
+ to release palloc'd memory, but any externally-visible resources
+ should be cleaned up.
+ This function can be omitted (set the pointer to NULL) in the common
+ case where no such resources exist.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tablesample-method.html" title="Chapter 60. Writing a Table Sampling Method">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="custom-scan.html" title="Chapter 61. Writing a Custom Scan Provider">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 60. Writing a Table Sampling Method </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 61. Writing a Custom Scan Provider</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tcn.html b/doc/src/sgml/html/tcn.html
new file mode 100644
index 0000000..64e28a2
--- /dev/null
+++ b/doc/src/sgml/html/tcn.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.44. tcn</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tablefunc.html" title="F.43. tablefunc" /><link rel="next" href="test-decoding.html" title="F.45. test_decoding" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.44. tcn</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tablefunc.html" title="F.43. tablefunc">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="test-decoding.html" title="F.45. test_decoding">Next</a></td></tr></table><hr /></div><div class="sect1" id="TCN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.44. tcn</h2></div></div></div><a id="id-1.11.7.53.2" class="indexterm"></a><a id="id-1.11.7.53.3" class="indexterm"></a><p>
+ The <code class="filename">tcn</code> module provides a trigger function that notifies
+ listeners of changes to any table on which it is attached. It must be
+ used as an <code class="literal">AFTER</code> trigger <code class="literal">FOR EACH ROW</code>.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><p>
+ Only one parameter may be supplied to the function in a
+ <code class="literal">CREATE TRIGGER</code> statement, and that is optional. If supplied
+ it will be used for the channel name for the notifications. If omitted
+ <code class="literal">tcn</code> will be used for the channel name.
+ </p><p>
+ The payload of the notifications consists of the table name, a letter to
+ indicate which type of operation was performed, and column name/value pairs
+ for primary key columns. Each part is separated from the next by a comma.
+ For ease of parsing using regular expressions, table and column names are
+ always wrapped in double quotes, and data values are always wrapped in
+ single quotes. Embedded quotes are doubled.
+ </p><p>
+ A brief example of using the extension follows.
+
+</p><pre class="programlisting">
+test=# create table tcndata
+test-# (
+test(# a int not null,
+test(# b date not null,
+test(# c text,
+test(# primary key (a, b)
+test(# );
+CREATE TABLE
+test=# create trigger tcndata_tcn_trigger
+test-# after insert or update or delete on tcndata
+test-# for each row execute function triggered_change_notification();
+CREATE TRIGGER
+test=# listen tcn;
+LISTEN
+test=# insert into tcndata values (1, date '2012-12-22', 'one'),
+test-# (1, date '2012-12-23', 'another'),
+test-# (2, date '2012-12-23', 'two');
+INSERT 0 3
+Asynchronous notification "tcn" with payload ""tcndata",I,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.
+Asynchronous notification "tcn" with payload ""tcndata",I,"a"='1',"b"='2012-12-23'" received from server process with PID 22770.
+Asynchronous notification "tcn" with payload ""tcndata",I,"a"='2',"b"='2012-12-23'" received from server process with PID 22770.
+test=# update tcndata set c = 'uno' where a = 1;
+UPDATE 2
+Asynchronous notification "tcn" with payload ""tcndata",U,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.
+Asynchronous notification "tcn" with payload ""tcndata",U,"a"='1',"b"='2012-12-23'" received from server process with PID 22770.
+test=# delete from tcndata where a = 1 and b = date '2012-12-22';
+DELETE 1
+Asynchronous notification "tcn" with payload ""tcndata",D,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tablefunc.html" title="F.43. tablefunc">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="test-decoding.html" title="F.45. test_decoding">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.43. tablefunc </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.45. test_decoding</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/test-decoding.html b/doc/src/sgml/html/test-decoding.html
new file mode 100644
index 0000000..2e38ae6
--- /dev/null
+++ b/doc/src/sgml/html/test-decoding.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.45. test_decoding</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tcn.html" title="F.44. tcn" /><link rel="next" href="tsm-system-rows.html" title="F.46. tsm_system_rows" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.45. test_decoding</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tcn.html" title="F.44. tcn">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tsm-system-rows.html" title="F.46. tsm_system_rows">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEST-DECODING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.45. test_decoding</h2></div></div></div><a id="id-1.11.7.54.2" class="indexterm"></a><p>
+ <code class="filename">test_decoding</code> is an example of a logical decoding
+ output plugin. It doesn't do anything especially useful, but can serve as
+ a starting point for developing your own output plugin.
+ </p><p>
+ <code class="filename">test_decoding</code> receives WAL through the logical decoding
+ mechanism and decodes it into text representations of the operations
+ performed.
+ </p><p>
+ Typical output from this plugin, used over the SQL logical decoding
+ interface, might be:
+
+</p><pre class="programlisting">
+postgres=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'include-xids', '0');
+ lsn | xid | data
+-----------+-----+--------------------------------------------------
+ 0/16D30F8 | 691 | BEGIN
+ 0/16D32A0 | 691 | table public.data: INSERT: id[int4]:2 data[text]:'arg'
+ 0/16D32A0 | 691 | table public.data: INSERT: id[int4]:3 data[text]:'demo'
+ 0/16D32A0 | 691 | COMMIT
+ 0/16D32D8 | 692 | BEGIN
+ 0/16D3398 | 692 | table public.data: DELETE: id[int4]:2
+ 0/16D3398 | 692 | table public.data: DELETE: id[int4]:3
+ 0/16D3398 | 692 | COMMIT
+(8 rows)
+</pre><p>
+ </p><p>
+ We can also get the changes of the in-progress transaction, and the typical
+ output might be:
+
+</p><pre class="programlisting">
+postgres[33712]=#* SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'stream-changes', '1');
+ lsn | xid | data
+-----------+-----+--------------------------------------------------
+ 0/16B21F8 | 503 | opening a streamed block for transaction TXN 503
+ 0/16B21F8 | 503 | streaming change for TXN 503
+ 0/16B2300 | 503 | streaming change for TXN 503
+ 0/16B2408 | 503 | streaming change for TXN 503
+ 0/16BEBA0 | 503 | closing a streamed block for transaction TXN 503
+ 0/16B21F8 | 503 | opening a streamed block for transaction TXN 503
+ 0/16BECA8 | 503 | streaming change for TXN 503
+ 0/16BEDB0 | 503 | streaming change for TXN 503
+ 0/16BEEB8 | 503 | streaming change for TXN 503
+ 0/16BEBA0 | 503 | closing a streamed block for transaction TXN 503
+(10 rows)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tcn.html" title="F.44. tcn">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tsm-system-rows.html" title="F.46. tsm_system_rows">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.44. tcn </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.46. tsm_system_rows</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-configuration.html b/doc/src/sgml/html/textsearch-configuration.html
new file mode 100644
index 0000000..4dcdc93
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-configuration.html
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.7. Configuration Example</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-dictionaries.html" title="12.6. Dictionaries" /><link rel="next" href="textsearch-debugging.html" title="12.8. Testing and Debugging Text Search" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.7. Configuration Example</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-dictionaries.html" title="12.6. Dictionaries">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-debugging.html" title="12.8. Testing and Debugging Text Search">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-CONFIGURATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.7. Configuration Example</h2></div></div></div><p>
+ A text search configuration specifies all options necessary to transform a
+ document into a <code class="type">tsvector</code>: the parser to use to break text
+ into tokens, and the dictionaries to use to transform each token into a
+ lexeme. Every call of
+ <code class="function">to_tsvector</code> or <code class="function">to_tsquery</code>
+ needs a text search configuration to perform its processing.
+ The configuration parameter
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a>
+ specifies the name of the default configuration, which is the
+ one used by text search functions if an explicit configuration
+ parameter is omitted.
+ It can be set in <code class="filename">postgresql.conf</code>, or set for an
+ individual session using the <code class="command">SET</code> command.
+ </p><p>
+ Several predefined text search configurations are available, and
+ you can create custom configurations easily. To facilitate management
+ of text search objects, a set of <acronym class="acronym">SQL</acronym> commands
+ is available, and there are several <span class="application">psql</span> commands that display information
+ about text search objects (<a class="xref" href="textsearch-psql.html" title="12.10. psql Support">Section 12.10</a>).
+ </p><p>
+ As an example we will create a configuration
+ <code class="literal">pg</code>, starting by duplicating the built-in
+ <code class="literal">english</code> configuration:
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH CONFIGURATION public.pg ( COPY = pg_catalog.english );
+</pre><p>
+ </p><p>
+ We will use a PostgreSQL-specific synonym list
+ and store it in <code class="filename">$SHAREDIR/tsearch_data/pg_dict.syn</code>.
+ The file contents look like:
+
+</p><pre class="programlisting">
+postgres pg
+pgsql pg
+postgresql pg
+</pre><p>
+
+ We define the synonym dictionary like this:
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY pg_dict (
+ TEMPLATE = synonym,
+ SYNONYMS = pg_dict
+);
+</pre><p>
+
+ Next we register the <span class="productname">Ispell</span> dictionary
+ <code class="literal">english_ispell</code>, which has its own configuration files:
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY english_ispell (
+ TEMPLATE = ispell,
+ DictFile = english,
+ AffFile = english,
+ StopWords = english
+);
+</pre><p>
+
+ Now we can set up the mappings for words in configuration
+ <code class="literal">pg</code>:
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION pg
+ ALTER MAPPING FOR asciiword, asciihword, hword_asciipart,
+ word, hword, hword_part
+ WITH pg_dict, english_ispell, english_stem;
+</pre><p>
+
+ We choose not to index or search some token types that the built-in
+ configuration does handle:
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION pg
+ DROP MAPPING FOR email, url, url_path, sfloat, float;
+</pre><p>
+ </p><p>
+ Now we can test our configuration:
+
+</p><pre class="programlisting">
+SELECT * FROM ts_debug('public.pg', '
+PostgreSQL, the highly scalable, SQL compliant, open source object-relational
+database management system, is now undergoing beta testing of the next
+version of our software.
+');
+</pre><p>
+ </p><p>
+ The next step is to set the session to use the new configuration, which was
+ created in the <code class="literal">public</code> schema:
+
+</p><pre class="screen">
+=&gt; \dF
+ List of text search configurations
+ Schema | Name | Description
+---------+------+-------------
+ public | pg |
+
+SET default_text_search_config = 'public.pg';
+SET
+
+SHOW default_text_search_config;
+ default_text_search_config
+----------------------------
+ public.pg
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-dictionaries.html" title="12.6. Dictionaries">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-debugging.html" title="12.8. Testing and Debugging Text Search">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.6. Dictionaries </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.8. Testing and Debugging Text Search</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-controls.html b/doc/src/sgml/html/textsearch-controls.html
new file mode 100644
index 0000000..9321fd3
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-controls.html
@@ -0,0 +1,550 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.3. Controlling Text Search</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-tables.html" title="12.2. Tables and Indexes" /><link rel="next" href="textsearch-features.html" title="12.4. Additional Features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.3. Controlling Text Search</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-tables.html" title="12.2. Tables and Indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-features.html" title="12.4. Additional Features">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-CONTROLS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.3. Controlling Text Search</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS">12.3.1. Parsing Documents</a></span></dt><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES">12.3.2. Parsing Queries</a></span></dt><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-RANKING">12.3.3. Ranking Search Results</a></span></dt><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-HEADLINE">12.3.4. Highlighting Results</a></span></dt></dl></div><p>
+ To implement full text searching there must be a function to create a
+ <code class="type">tsvector</code> from a document and a <code class="type">tsquery</code> from a
+ user query. Also, we need to return results in a useful order, so we need
+ a function that compares documents with respect to their relevance to
+ the query. It's also important to be able to display the results nicely.
+ <span class="productname">PostgreSQL</span> provides support for all of these
+ functions.
+ </p><div class="sect2" id="TEXTSEARCH-PARSING-DOCUMENTS"><div class="titlepage"><div><div><h3 class="title">12.3.1. Parsing Documents</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> provides the
+ function <code class="function">to_tsvector</code> for converting a document to
+ the <code class="type">tsvector</code> data type.
+ </p><a id="id-1.5.11.6.3.3" class="indexterm"></a><pre class="synopsis">
+to_tsvector([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>document</code></em> <code class="type">text</code>) returns <code class="type">tsvector</code>
+</pre><p>
+ <code class="function">to_tsvector</code> parses a textual document into tokens,
+ reduces the tokens to lexemes, and returns a <code class="type">tsvector</code> which
+ lists the lexemes together with their positions in the document.
+ The document is processed according to the specified or default
+ text search configuration.
+ Here is a simple example:
+
+</p><pre class="screen">
+SELECT to_tsvector('english', 'a fat cat sat on a mat - it ate a fat rats');
+ to_tsvector
+-----------------------------------------------------
+ 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4
+</pre><p>
+ </p><p>
+ In the example above we see that the resulting <code class="type">tsvector</code> does not
+ contain the words <code class="literal">a</code>, <code class="literal">on</code>, or
+ <code class="literal">it</code>, the word <code class="literal">rats</code> became
+ <code class="literal">rat</code>, and the punctuation sign <code class="literal">-</code> was
+ ignored.
+ </p><p>
+ The <code class="function">to_tsvector</code> function internally calls a parser
+ which breaks the document text into tokens and assigns a type to
+ each token. For each token, a list of
+ dictionaries (<a class="xref" href="textsearch-dictionaries.html" title="12.6. Dictionaries">Section 12.6</a>) is consulted,
+ where the list can vary depending on the token type. The first dictionary
+ that <em class="firstterm">recognizes</em> the token emits one or more normalized
+ <em class="firstterm">lexemes</em> to represent the token. For example,
+ <code class="literal">rats</code> became <code class="literal">rat</code> because one of the
+ dictionaries recognized that the word <code class="literal">rats</code> is a plural
+ form of <code class="literal">rat</code>. Some words are recognized as
+ <em class="firstterm">stop words</em> (<a class="xref" href="textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS" title="12.6.1. Stop Words">Section 12.6.1</a>), which
+ causes them to be ignored since they occur too frequently to be useful in
+ searching. In our example these are
+ <code class="literal">a</code>, <code class="literal">on</code>, and <code class="literal">it</code>.
+ If no dictionary in the list recognizes the token then it is also ignored.
+ In this example that happened to the punctuation sign <code class="literal">-</code>
+ because there are in fact no dictionaries assigned for its token type
+ (<code class="literal">Space symbols</code>), meaning space tokens will never be
+ indexed. The choices of parser, dictionaries and which types of tokens to
+ index are determined by the selected text search configuration (<a class="xref" href="textsearch-configuration.html" title="12.7. Configuration Example">Section 12.7</a>). It is possible to have
+ many different configurations in the same database, and predefined
+ configurations are available for various languages. In our example
+ we used the default configuration <code class="literal">english</code> for the
+ English language.
+ </p><p>
+ The function <code class="function">setweight</code> can be used to label the
+ entries of a <code class="type">tsvector</code> with a given <em class="firstterm">weight</em>,
+ where a weight is one of the letters <code class="literal">A</code>, <code class="literal">B</code>,
+ <code class="literal">C</code>, or <code class="literal">D</code>.
+ This is typically used to mark entries coming from
+ different parts of a document, such as title versus body. Later, this
+ information can be used for ranking of search results.
+ </p><p>
+ Because <code class="function">to_tsvector</code>(<code class="literal">NULL</code>) will
+ return <code class="literal">NULL</code>, it is recommended to use
+ <code class="function">coalesce</code> whenever a field might be null.
+ Here is the recommended method for creating
+ a <code class="type">tsvector</code> from a structured document:
+
+</p><pre class="programlisting">
+UPDATE tt SET ti =
+ setweight(to_tsvector(coalesce(title,'')), 'A') ||
+ setweight(to_tsvector(coalesce(keyword,'')), 'B') ||
+ setweight(to_tsvector(coalesce(abstract,'')), 'C') ||
+ setweight(to_tsvector(coalesce(body,'')), 'D');
+</pre><p>
+
+ Here we have used <code class="function">setweight</code> to label the source
+ of each lexeme in the finished <code class="type">tsvector</code>, and then merged
+ the labeled <code class="type">tsvector</code> values using the <code class="type">tsvector</code>
+ concatenation operator <code class="literal">||</code>. (<a class="xref" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR" title="12.4.1. Manipulating Documents">Section 12.4.1</a> gives details about these
+ operations.)
+ </p></div><div class="sect2" id="TEXTSEARCH-PARSING-QUERIES"><div class="titlepage"><div><div><h3 class="title">12.3.2. Parsing Queries</h3></div></div></div><p>
+ <span class="productname">PostgreSQL</span> provides the
+ functions <code class="function">to_tsquery</code>,
+ <code class="function">plainto_tsquery</code>,
+ <code class="function">phraseto_tsquery</code> and
+ <code class="function">websearch_to_tsquery</code>
+ for converting a query to the <code class="type">tsquery</code> data type.
+ <code class="function">to_tsquery</code> offers access to more features
+ than either <code class="function">plainto_tsquery</code> or
+ <code class="function">phraseto_tsquery</code>, but it is less forgiving about its
+ input. <code class="function">websearch_to_tsquery</code> is a simplified version
+ of <code class="function">to_tsquery</code> with an alternative syntax, similar
+ to the one used by web search engines.
+ </p><a id="id-1.5.11.6.4.3" class="indexterm"></a><pre class="synopsis">
+to_tsquery([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>querytext</code></em> <code class="type">text</code>) returns <code class="type">tsquery</code>
+</pre><p>
+ <code class="function">to_tsquery</code> creates a <code class="type">tsquery</code> value from
+ <em class="replaceable"><code>querytext</code></em>, which must consist of single tokens
+ separated by the <code class="type">tsquery</code> operators <code class="literal">&amp;</code> (AND),
+ <code class="literal">|</code> (OR), <code class="literal">!</code> (NOT), and
+ <code class="literal">&lt;-&gt;</code> (FOLLOWED BY), possibly grouped
+ using parentheses. In other words, the input to
+ <code class="function">to_tsquery</code> must already follow the general rules for
+ <code class="type">tsquery</code> input, as described in <a class="xref" href="datatype-textsearch.html#DATATYPE-TSQUERY" title="8.11.2. tsquery">Section 8.11.2</a>. The difference is that while basic
+ <code class="type">tsquery</code> input takes the tokens at face value,
+ <code class="function">to_tsquery</code> normalizes each token into a lexeme using
+ the specified or default configuration, and discards any tokens that are
+ stop words according to the configuration. For example:
+
+</p><pre class="screen">
+SELECT to_tsquery('english', 'The &amp; Fat &amp; Rats');
+ to_tsquery
+---------------
+ 'fat' &amp; 'rat'
+</pre><p>
+
+ As in basic <code class="type">tsquery</code> input, weight(s) can be attached to each
+ lexeme to restrict it to match only <code class="type">tsvector</code> lexemes of those
+ weight(s). For example:
+
+</p><pre class="screen">
+SELECT to_tsquery('english', 'Fat | Rats:AB');
+ to_tsquery
+------------------
+ 'fat' | 'rat':AB
+</pre><p>
+
+ Also, <code class="literal">*</code> can be attached to a lexeme to specify prefix matching:
+
+</p><pre class="screen">
+SELECT to_tsquery('supern:*A &amp; star:A*B');
+ to_tsquery
+--------------------------
+ 'supern':*A &amp; 'star':*AB
+</pre><p>
+
+ Such a lexeme will match any word in a <code class="type">tsvector</code> that begins
+ with the given string.
+ </p><p>
+ <code class="function">to_tsquery</code> can also accept single-quoted
+ phrases. This is primarily useful when the configuration includes a
+ thesaurus dictionary that may trigger on such phrases.
+ In the example below, a thesaurus contains the rule <code class="literal">supernovae
+ stars : sn</code>:
+
+</p><pre class="screen">
+SELECT to_tsquery('''supernovae stars'' &amp; !crab');
+ to_tsquery
+---------------
+ 'sn' &amp; !'crab'
+</pre><p>
+
+ Without quotes, <code class="function">to_tsquery</code> will generate a syntax
+ error for tokens that are not separated by an AND, OR, or FOLLOWED BY
+ operator.
+ </p><a id="id-1.5.11.6.4.7" class="indexterm"></a><pre class="synopsis">
+plainto_tsquery([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>querytext</code></em> <code class="type">text</code>) returns <code class="type">tsquery</code>
+</pre><p>
+ <code class="function">plainto_tsquery</code> transforms the unformatted text
+ <em class="replaceable"><code>querytext</code></em> to a <code class="type">tsquery</code> value.
+ The text is parsed and normalized much as for <code class="function">to_tsvector</code>,
+ then the <code class="literal">&amp;</code> (AND) <code class="type">tsquery</code> operator is
+ inserted between surviving words.
+ </p><p>
+ Example:
+
+</p><pre class="screen">
+SELECT plainto_tsquery('english', 'The Fat Rats');
+ plainto_tsquery
+-----------------
+ 'fat' &amp; 'rat'
+</pre><p>
+
+ Note that <code class="function">plainto_tsquery</code> will not
+ recognize <code class="type">tsquery</code> operators, weight labels,
+ or prefix-match labels in its input:
+
+</p><pre class="screen">
+SELECT plainto_tsquery('english', 'The Fat &amp; Rats:C');
+ plainto_tsquery
+---------------------
+ 'fat' &amp; 'rat' &amp; 'c'
+</pre><p>
+
+ Here, all the input punctuation was discarded.
+ </p><a id="id-1.5.11.6.4.11" class="indexterm"></a><pre class="synopsis">
+phraseto_tsquery([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>querytext</code></em> <code class="type">text</code>) returns <code class="type">tsquery</code>
+</pre><p>
+ <code class="function">phraseto_tsquery</code> behaves much like
+ <code class="function">plainto_tsquery</code>, except that it inserts
+ the <code class="literal">&lt;-&gt;</code> (FOLLOWED BY) operator between
+ surviving words instead of the <code class="literal">&amp;</code> (AND) operator.
+ Also, stop words are not simply discarded, but are accounted for by
+ inserting <code class="literal">&lt;<em class="replaceable"><code>N</code></em>&gt;</code> operators rather
+ than <code class="literal">&lt;-&gt;</code> operators. This function is useful
+ when searching for exact lexeme sequences, since the FOLLOWED BY
+ operators check lexeme order not just the presence of all the lexemes.
+ </p><p>
+ Example:
+
+</p><pre class="screen">
+SELECT phraseto_tsquery('english', 'The Fat Rats');
+ phraseto_tsquery
+------------------
+ 'fat' &lt;-&gt; 'rat'
+</pre><p>
+
+ Like <code class="function">plainto_tsquery</code>, the
+ <code class="function">phraseto_tsquery</code> function will not
+ recognize <code class="type">tsquery</code> operators, weight labels,
+ or prefix-match labels in its input:
+
+</p><pre class="screen">
+SELECT phraseto_tsquery('english', 'The Fat &amp; Rats:C');
+ phraseto_tsquery
+-----------------------------
+ 'fat' &lt;-&gt; 'rat' &lt;-&gt; 'c'
+</pre><p>
+ </p><pre class="synopsis">
+websearch_to_tsquery([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>querytext</code></em> <code class="type">text</code>) returns <code class="type">tsquery</code>
+</pre><p>
+ <code class="function">websearch_to_tsquery</code> creates a <code class="type">tsquery</code>
+ value from <em class="replaceable"><code>querytext</code></em> using an alternative
+ syntax in which simple unformatted text is a valid query.
+ Unlike <code class="function">plainto_tsquery</code>
+ and <code class="function">phraseto_tsquery</code>, it also recognizes certain
+ operators. Moreover, this function will never raise syntax errors,
+ which makes it possible to use raw user-supplied input for search.
+ The following syntax is supported:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">unquoted text</code>: text not inside quote marks will be
+ converted to terms separated by <code class="literal">&amp;</code> operators, as
+ if processed by <code class="function">plainto_tsquery</code>.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">"quoted text"</code>: text inside quote marks will be
+ converted to terms separated by <code class="literal">&lt;-&gt;</code>
+ operators, as if processed by <code class="function">phraseto_tsquery</code>.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">OR</code>: the word <span class="quote">“<span class="quote">or</span>”</span> will be converted to
+ the <code class="literal">|</code> operator.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">-</code>: a dash will be converted to
+ the <code class="literal">!</code> operator.
+ </p></li></ul></div><p>
+
+ Other punctuation is ignored. So
+ like <code class="function">plainto_tsquery</code>
+ and <code class="function">phraseto_tsquery</code>,
+ the <code class="function">websearch_to_tsquery</code> function will not
+ recognize <code class="type">tsquery</code> operators, weight labels, or prefix-match
+ labels in its input.
+ </p><p>
+ Examples:
+</p><pre class="screen">
+SELECT websearch_to_tsquery('english', 'The fat rats');
+ websearch_to_tsquery
+----------------------
+ 'fat' &amp; 'rat'
+(1 row)
+
+SELECT websearch_to_tsquery('english', '"supernovae stars" -crab');
+ websearch_to_tsquery
+----------------------------------
+ 'supernova' &lt;-&gt; 'star' &amp; !'crab'
+(1 row)
+
+SELECT websearch_to_tsquery('english', '"sad cat" or "fat rat"');
+ websearch_to_tsquery
+-----------------------------------
+ 'sad' &lt;-&gt; 'cat' | 'fat' &lt;-&gt; 'rat'
+(1 row)
+
+SELECT websearch_to_tsquery('english', 'signal -"segmentation fault"');
+ websearch_to_tsquery
+---------------------------------------
+ 'signal' &amp; !( 'segment' &lt;-&gt; 'fault' )
+(1 row)
+
+SELECT websearch_to_tsquery('english', '""" )( dummy \\ query &lt;-&gt;');
+ websearch_to_tsquery
+----------------------
+ 'dummi' &amp; 'queri'
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="TEXTSEARCH-RANKING"><div class="titlepage"><div><div><h3 class="title">12.3.3. Ranking Search Results</h3></div></div></div><p>
+ Ranking attempts to measure how relevant documents are to a particular
+ query, so that when there are many matches the most relevant ones can be
+ shown first. <span class="productname">PostgreSQL</span> provides two
+ predefined ranking functions, which take into account lexical, proximity,
+ and structural information; that is, they consider how often the query
+ terms appear in the document, how close together the terms are in the
+ document, and how important is the part of the document where they occur.
+ However, the concept of relevancy is vague and very application-specific.
+ Different applications might require additional information for ranking,
+ e.g., document modification time. The built-in ranking functions are only
+ examples. You can write your own ranking functions and/or combine their
+ results with additional factors to fit your specific needs.
+ </p><p>
+ The two ranking functions currently available are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <a id="id-1.5.11.6.5.3.1.1.1.1" class="indexterm"></a>
+
+ <code class="literal">ts_rank([<span class="optional"> <em class="replaceable"><code>weights</code></em> <code class="type">float4[]</code>, </span>] <em class="replaceable"><code>vector</code></em> <code class="type">tsvector</code>, <em class="replaceable"><code>query</code></em> <code class="type">tsquery</code> [<span class="optional">, <em class="replaceable"><code>normalization</code></em> <code class="type">integer</code> </span>]) returns <code class="type">float4</code></code>
+ </span></dt><dd><p>
+ Ranks vectors based on the frequency of their matching lexemes.
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.6.5.3.1.2.1.1" class="indexterm"></a>
+
+ <code class="literal">ts_rank_cd([<span class="optional"> <em class="replaceable"><code>weights</code></em> <code class="type">float4[]</code>, </span>] <em class="replaceable"><code>vector</code></em> <code class="type">tsvector</code>, <em class="replaceable"><code>query</code></em> <code class="type">tsquery</code> [<span class="optional">, <em class="replaceable"><code>normalization</code></em> <code class="type">integer</code> </span>]) returns <code class="type">float4</code></code>
+ </span></dt><dd><p>
+ This function computes the <em class="firstterm">cover density</em>
+ ranking for the given document vector and query, as described in
+ Clarke, Cormack, and Tudhope's "Relevance Ranking for One to Three
+ Term Queries" in the journal "Information Processing and Management",
+ 1999. Cover density is similar to <code class="function">ts_rank</code> ranking
+ except that the proximity of matching lexemes to each other is
+ taken into consideration.
+ </p><p>
+ This function requires lexeme positional information to perform
+ its calculation. Therefore, it ignores any <span class="quote">“<span class="quote">stripped</span>”</span>
+ lexemes in the <code class="type">tsvector</code>. If there are no unstripped
+ lexemes in the input, the result will be zero. (See <a class="xref" href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR" title="12.4.1. Manipulating Documents">Section 12.4.1</a> for more information
+ about the <code class="function">strip</code> function and positional information
+ in <code class="type">tsvector</code>s.)
+ </p></dd></dl></div><p>
+
+ </p><p>
+ For both these functions,
+ the optional <em class="replaceable"><code>weights</code></em>
+ argument offers the ability to weigh word instances more or less
+ heavily depending on how they are labeled. The weight arrays specify
+ how heavily to weigh each category of word, in the order:
+
+</p><pre class="synopsis">
+{D-weight, C-weight, B-weight, A-weight}
+</pre><p>
+
+ If no <em class="replaceable"><code>weights</code></em> are provided,
+ then these defaults are used:
+
+</p><pre class="programlisting">
+{0.1, 0.2, 0.4, 1.0}
+</pre><p>
+
+ Typically weights are used to mark words from special areas of the
+ document, like the title or an initial abstract, so they can be
+ treated with more or less importance than words in the document body.
+ </p><p>
+ Since a longer document has a greater chance of containing a query term
+ it is reasonable to take into account document size, e.g., a hundred-word
+ document with five instances of a search word is probably more relevant
+ than a thousand-word document with five instances. Both ranking functions
+ take an integer <em class="replaceable"><code>normalization</code></em> option that
+ specifies whether and how a document's length should impact its rank.
+ The integer option controls several behaviors, so it is a bit mask:
+ you can specify one or more behaviors using
+ <code class="literal">|</code> (for example, <code class="literal">2|4</code>).
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ 0 (the default) ignores the document length
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ 1 divides the rank by 1 + the logarithm of the document length
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ 2 divides the rank by the document length
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ 4 divides the rank by the mean harmonic distance between extents
+ (this is implemented only by <code class="function">ts_rank_cd</code>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ 8 divides the rank by the number of unique words in document
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ 16 divides the rank by 1 + the logarithm of the number
+ of unique words in document
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ 32 divides the rank by itself + 1
+ </p></li></ul></div><p>
+
+ If more than one flag bit is specified, the transformations are
+ applied in the order listed.
+ </p><p>
+ It is important to note that the ranking functions do not use any global
+ information, so it is impossible to produce a fair normalization to 1% or
+ 100% as sometimes desired. Normalization option 32
+ (<code class="literal">rank/(rank+1)</code>) can be applied to scale all ranks
+ into the range zero to one, but of course this is just a cosmetic change;
+ it will not affect the ordering of the search results.
+ </p><p>
+ Here is an example that selects only the ten highest-ranked matches:
+
+</p><pre class="screen">
+SELECT title, ts_rank_cd(textsearch, query) AS rank
+FROM apod, to_tsquery('neutrino|(dark &amp; matter)') query
+WHERE query @@ textsearch
+ORDER BY rank DESC
+LIMIT 10;
+ title | rank
+-----------------------------------------------+----------
+ Neutrinos in the Sun | 3.1
+ The Sudbury Neutrino Detector | 2.4
+ A MACHO View of Galactic Dark Matter | 2.01317
+ Hot Gas and Dark Matter | 1.91171
+ The Virgo Cluster: Hot Plasma and Dark Matter | 1.90953
+ Rafting for Solar Neutrinos | 1.9
+ NGC 4650A: Strange Galaxy and Dark Matter | 1.85774
+ Hot Gas and Dark Matter | 1.6123
+ Ice Fishing for Cosmic Neutrinos | 1.6
+ Weak Lensing Distorts the Universe | 0.818218
+</pre><p>
+
+ This is the same example using normalized ranking:
+
+</p><pre class="screen">
+SELECT title, ts_rank_cd(textsearch, query, 32 /* rank/(rank+1) */ ) AS rank
+FROM apod, to_tsquery('neutrino|(dark &amp; matter)') query
+WHERE query @@ textsearch
+ORDER BY rank DESC
+LIMIT 10;
+ title | rank
+-----------------------------------------------+-------------------
+ Neutrinos in the Sun | 0.756097569485493
+ The Sudbury Neutrino Detector | 0.705882361190954
+ A MACHO View of Galactic Dark Matter | 0.668123210574724
+ Hot Gas and Dark Matter | 0.65655958650282
+ The Virgo Cluster: Hot Plasma and Dark Matter | 0.656301290640973
+ Rafting for Solar Neutrinos | 0.655172410958162
+ NGC 4650A: Strange Galaxy and Dark Matter | 0.650072921219637
+ Hot Gas and Dark Matter | 0.617195790024749
+ Ice Fishing for Cosmic Neutrinos | 0.615384618911517
+ Weak Lensing Distorts the Universe | 0.450010798361481
+</pre><p>
+ </p><p>
+ Ranking can be expensive since it requires consulting the
+ <code class="type">tsvector</code> of each matching document, which can be I/O bound and
+ therefore slow. Unfortunately, it is almost impossible to avoid since
+ practical queries often result in large numbers of matches.
+ </p></div><div class="sect2" id="TEXTSEARCH-HEADLINE"><div class="titlepage"><div><div><h3 class="title">12.3.4. Highlighting Results</h3></div></div></div><p>
+ To present search results it is ideal to show a part of each document and
+ how it is related to the query. Usually, search engines show fragments of
+ the document with marked search terms. <span class="productname">PostgreSQL</span>
+ provides a function <code class="function">ts_headline</code> that
+ implements this functionality.
+ </p><a id="id-1.5.11.6.6.3" class="indexterm"></a><pre class="synopsis">
+ts_headline([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>document</code></em> <code class="type">text</code>, <em class="replaceable"><code>query</code></em> <code class="type">tsquery</code> [<span class="optional">, <em class="replaceable"><code>options</code></em> <code class="type">text</code> </span>]) returns <code class="type">text</code>
+</pre><p>
+ <code class="function">ts_headline</code> accepts a document along
+ with a query, and returns an excerpt from
+ the document in which terms from the query are highlighted. The
+ configuration to be used to parse the document can be specified by
+ <em class="replaceable"><code>config</code></em>; if <em class="replaceable"><code>config</code></em>
+ is omitted, the
+ <code class="varname">default_text_search_config</code> configuration is used.
+ </p><p>
+ If an <em class="replaceable"><code>options</code></em> string is specified it must
+ consist of a comma-separated list of one or more
+ <em class="replaceable"><code>option</code></em><code class="literal">=</code><em class="replaceable"><code>value</code></em> pairs.
+ The available options are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">MaxWords</code>, <code class="literal">MinWords</code> (integers):
+ these numbers determine the longest and shortest headlines to output.
+ The default values are 35 and 15.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">ShortWord</code> (integer): words of this length or less
+ will be dropped at the start and end of a headline, unless they are
+ query terms. The default value of three eliminates common English
+ articles.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">HighlightAll</code> (boolean): if
+ <code class="literal">true</code> the whole document will be used as the
+ headline, ignoring the preceding three parameters. The default
+ is <code class="literal">false</code>.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">MaxFragments</code> (integer): maximum number of text
+ fragments to display. The default value of zero selects a
+ non-fragment-based headline generation method. A value greater
+ than zero selects fragment-based headline generation (see below).
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">StartSel</code>, <code class="literal">StopSel</code> (strings):
+ the strings with which to delimit query words appearing in the
+ document, to distinguish them from other excerpted words. The
+ default values are <span class="quote">“<span class="quote"><code class="literal">&lt;b&gt;</code></span>”</span> and
+ <span class="quote">“<span class="quote"><code class="literal">&lt;/b&gt;</code></span>”</span>, which can be suitable
+ for HTML output.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">FragmentDelimiter</code> (string): When more than one
+ fragment is displayed, the fragments will be separated by this string.
+ The default is <span class="quote">“<span class="quote"><code class="literal"> ... </code></span>”</span>.
+ </p></li></ul></div><p>
+
+ These option names are recognized case-insensitively.
+ You must double-quote string values if they contain spaces or commas.
+ </p><p>
+ In non-fragment-based headline
+ generation, <code class="function">ts_headline</code> locates matches for the
+ given <em class="replaceable"><code>query</code></em> and chooses a
+ single one to display, preferring matches that have more query words
+ within the allowed headline length.
+ In fragment-based headline generation, <code class="function">ts_headline</code>
+ locates the query matches and splits each match
+ into <span class="quote">“<span class="quote">fragments</span>”</span> of no more than <code class="literal">MaxWords</code>
+ words each, preferring fragments with more query words, and when
+ possible <span class="quote">“<span class="quote">stretching</span>”</span> fragments to include surrounding
+ words. The fragment-based mode is thus more useful when the query
+ matches span large sections of the document, or when it's desirable to
+ display multiple matches.
+ In either mode, if no query matches can be identified, then a single
+ fragment of the first <code class="literal">MinWords</code> words in the document
+ will be displayed.
+ </p><p>
+ For example:
+
+</p><pre class="screen">
+SELECT ts_headline('english',
+ 'The most common type of search
+is to find all documents containing given query terms
+and return them in order of their similarity to the
+query.',
+ to_tsquery('english', 'query &amp; similarity'));
+ ts_headline
+------------------------------------------------------------
+ containing given &lt;b&gt;query&lt;/b&gt; terms +
+ and return them in order of their &lt;b&gt;similarity&lt;/b&gt; to the+
+ &lt;b&gt;query&lt;/b&gt;.
+
+SELECT ts_headline('english',
+ 'Search terms may occur
+many times in a document,
+requiring ranking of the search matches to decide which
+occurrences to display in the result.',
+ to_tsquery('english', 'search &amp; term'),
+ 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=&lt;&lt;, StopSel=&gt;&gt;');
+ ts_headline
+------------------------------------------------------------
+ &lt;&lt;Search&gt;&gt; &lt;&lt;terms&gt;&gt; may occur +
+ many times ... ranking of the &lt;&lt;search&gt;&gt; matches to decide
+</pre><p>
+ </p><p>
+ <code class="function">ts_headline</code> uses the original document, not a
+ <code class="type">tsvector</code> summary, so it can be slow and should be used with
+ care.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-tables.html" title="12.2. Tables and Indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-features.html" title="12.4. Additional Features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.2. Tables and Indexes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.4. Additional Features</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-debugging.html b/doc/src/sgml/html/textsearch-debugging.html
new file mode 100644
index 0000000..bbfe459
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-debugging.html
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.8. Testing and Debugging Text Search</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-configuration.html" title="12.7. Configuration Example" /><link rel="next" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.8. Testing and Debugging Text Search</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-configuration.html" title="12.7. Configuration Example">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-DEBUGGING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.8. Testing and Debugging Text Search</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-debugging.html#TEXTSEARCH-CONFIGURATION-TESTING">12.8.1. Configuration Testing</a></span></dt><dt><span class="sect2"><a href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING">12.8.2. Parser Testing</a></span></dt><dt><span class="sect2"><a href="textsearch-debugging.html#TEXTSEARCH-DICTIONARY-TESTING">12.8.3. Dictionary Testing</a></span></dt></dl></div><p>
+ The behavior of a custom text search configuration can easily become
+ confusing. The functions described
+ in this section are useful for testing text search objects. You can
+ test a complete configuration, or test parsers and dictionaries separately.
+ </p><div class="sect2" id="TEXTSEARCH-CONFIGURATION-TESTING"><div class="titlepage"><div><div><h3 class="title">12.8.1. Configuration Testing</h3></div></div></div><p>
+ The function <code class="function">ts_debug</code> allows easy testing of a
+ text search configuration.
+ </p><a id="id-1.5.11.11.3.3" class="indexterm"></a><pre class="synopsis">
+ts_debug([<span class="optional"> <em class="replaceable"><code>config</code></em> <code class="type">regconfig</code>, </span>] <em class="replaceable"><code>document</code></em> <code class="type">text</code>,
+ OUT <em class="replaceable"><code>alias</code></em> <code class="type">text</code>,
+ OUT <em class="replaceable"><code>description</code></em> <code class="type">text</code>,
+ OUT <em class="replaceable"><code>token</code></em> <code class="type">text</code>,
+ OUT <em class="replaceable"><code>dictionaries</code></em> <code class="type">regdictionary[]</code>,
+ OUT <em class="replaceable"><code>dictionary</code></em> <code class="type">regdictionary</code>,
+ OUT <em class="replaceable"><code>lexemes</code></em> <code class="type">text[]</code>)
+ returns setof record
+</pre><p>
+ <code class="function">ts_debug</code> displays information about every token of
+ <em class="replaceable"><code>document</code></em> as produced by the
+ parser and processed by the configured dictionaries. It uses the
+ configuration specified by <em class="replaceable"><code>config</code></em>,
+ or <code class="varname">default_text_search_config</code> if that argument is
+ omitted.
+ </p><p>
+ <code class="function">ts_debug</code> returns one row for each token identified in the text
+ by the parser. The columns returned are
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>alias</code></em> <code class="type">text</code> — short name of the token type
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>description</code></em> <code class="type">text</code> — description of the
+ token type
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>token</code></em> <code class="type">text</code> — text of the token
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>dictionaries</code></em> <code class="type">regdictionary[]</code> — the
+ dictionaries selected by the configuration for this token type
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>dictionary</code></em> <code class="type">regdictionary</code> — the dictionary
+ that recognized the token, or <code class="literal">NULL</code> if none did
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>lexemes</code></em> <code class="type">text[]</code> — the lexeme(s) produced
+ by the dictionary that recognized the token, or <code class="literal">NULL</code> if
+ none did; an empty array (<code class="literal">{}</code>) means it was recognized as a
+ stop word
+ </p></li></ul></div><p>
+ </p><p>
+ Here is a simple example:
+
+</p><pre class="screen">
+SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------+----------------+--------------+---------
+ asciiword | Word, all ASCII | a | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | cat | {english_stem} | english_stem | {cat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | sat | {english_stem} | english_stem | {sat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | on | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | a | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | mat | {english_stem} | english_stem | {mat}
+ blank | Space symbols | | {} | |
+ blank | Space symbols | - | {} | |
+ asciiword | Word, all ASCII | it | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | ate | {english_stem} | english_stem | {ate}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | a | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | rats | {english_stem} | english_stem | {rat}
+</pre><p>
+ </p><p>
+ For a more extensive demonstration, we
+ first create a <code class="literal">public.english</code> configuration and
+ Ispell dictionary for the English language:
+ </p><pre class="programlisting">
+CREATE TEXT SEARCH CONFIGURATION public.english ( COPY = pg_catalog.english );
+
+CREATE TEXT SEARCH DICTIONARY english_ispell (
+ TEMPLATE = ispell,
+ DictFile = english,
+ AffFile = english,
+ StopWords = english
+);
+
+ALTER TEXT SEARCH CONFIGURATION public.english
+ ALTER MAPPING FOR asciiword WITH english_ispell, english_stem;
+</pre><pre class="screen">
+SELECT * FROM ts_debug('public.english', 'The Brightest supernovaes');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------------+-------------------------------+----------------+-------------
+ asciiword | Word, all ASCII | The | {english_ispell,english_stem} | english_ispell | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | Brightest | {english_ispell,english_stem} | english_ispell | {bright}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | supernovaes | {english_ispell,english_stem} | english_stem | {supernova}
+</pre><p>
+ In this example, the word <code class="literal">Brightest</code> was recognized by the
+ parser as an <code class="literal">ASCII word</code> (alias <code class="literal">asciiword</code>).
+ For this token type the dictionary list is
+ <code class="literal">english_ispell</code> and
+ <code class="literal">english_stem</code>. The word was recognized by
+ <code class="literal">english_ispell</code>, which reduced it to the noun
+ <code class="literal">bright</code>. The word <code class="literal">supernovaes</code> is
+ unknown to the <code class="literal">english_ispell</code> dictionary so it
+ was passed to the next dictionary, and, fortunately, was recognized (in
+ fact, <code class="literal">english_stem</code> is a Snowball dictionary which
+ recognizes everything; that is why it was placed at the end of the
+ dictionary list).
+ </p><p>
+ The word <code class="literal">The</code> was recognized by the
+ <code class="literal">english_ispell</code> dictionary as a stop word (<a class="xref" href="textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS" title="12.6.1. Stop Words">Section 12.6.1</a>) and will not be indexed.
+ The spaces are discarded too, since the configuration provides no
+ dictionaries at all for them.
+ </p><p>
+ You can reduce the width of the output by explicitly specifying which columns
+ you want to see:
+
+</p><pre class="screen">
+SELECT alias, token, dictionary, lexemes
+FROM ts_debug('public.english', 'The Brightest supernovaes');
+ alias | token | dictionary | lexemes
+-----------+-------------+----------------+-------------
+ asciiword | The | english_ispell | {}
+ blank | | |
+ asciiword | Brightest | english_ispell | {bright}
+ blank | | |
+ asciiword | supernovaes | english_stem | {supernova}
+</pre><p>
+ </p></div><div class="sect2" id="TEXTSEARCH-PARSER-TESTING"><div class="titlepage"><div><div><h3 class="title">12.8.2. Parser Testing</h3></div></div></div><p>
+ The following functions allow direct testing of a text search parser.
+ </p><a id="id-1.5.11.11.4.3" class="indexterm"></a><pre class="synopsis">
+ts_parse(<em class="replaceable"><code>parser_name</code></em> <code class="type">text</code>, <em class="replaceable"><code>document</code></em> <code class="type">text</code>,
+ OUT <em class="replaceable"><code>tokid</code></em> <code class="type">integer</code>, OUT <em class="replaceable"><code>token</code></em> <code class="type">text</code>) returns <code class="type">setof record</code>
+ts_parse(<em class="replaceable"><code>parser_oid</code></em> <code class="type">oid</code>, <em class="replaceable"><code>document</code></em> <code class="type">text</code>,
+ OUT <em class="replaceable"><code>tokid</code></em> <code class="type">integer</code>, OUT <em class="replaceable"><code>token</code></em> <code class="type">text</code>) returns <code class="type">setof record</code>
+</pre><p>
+ <code class="function">ts_parse</code> parses the given <em class="replaceable"><code>document</code></em>
+ and returns a series of records, one for each token produced by
+ parsing. Each record includes a <code class="varname">tokid</code> showing the
+ assigned token type and a <code class="varname">token</code> which is the text of the
+ token. For example:
+
+</p><pre class="screen">
+SELECT * FROM ts_parse('default', '123 - a number');
+ tokid | token
+-------+--------
+ 22 | 123
+ 12 |
+ 12 | -
+ 1 | a
+ 12 |
+ 1 | number
+</pre><p>
+ </p><a id="id-1.5.11.11.4.6" class="indexterm"></a><pre class="synopsis">
+ts_token_type(<em class="replaceable"><code>parser_name</code></em> <code class="type">text</code>, OUT <em class="replaceable"><code>tokid</code></em> <code class="type">integer</code>,
+ OUT <em class="replaceable"><code>alias</code></em> <code class="type">text</code>, OUT <em class="replaceable"><code>description</code></em> <code class="type">text</code>) returns <code class="type">setof record</code>
+ts_token_type(<em class="replaceable"><code>parser_oid</code></em> <code class="type">oid</code>, OUT <em class="replaceable"><code>tokid</code></em> <code class="type">integer</code>,
+ OUT <em class="replaceable"><code>alias</code></em> <code class="type">text</code>, OUT <em class="replaceable"><code>description</code></em> <code class="type">text</code>) returns <code class="type">setof record</code>
+</pre><p>
+ <code class="function">ts_token_type</code> returns a table which describes each type of
+ token the specified parser can recognize. For each token type, the table
+ gives the integer <code class="varname">tokid</code> that the parser uses to label a
+ token of that type, the <code class="varname">alias</code> that names the token type
+ in configuration commands, and a short <code class="varname">description</code>. For
+ example:
+
+</p><pre class="screen">
+SELECT * FROM ts_token_type('default');
+ tokid | alias | description
+-------+-----------------+------------------------------------------
+ 1 | asciiword | Word, all ASCII
+ 2 | word | Word, all letters
+ 3 | numword | Word, letters and digits
+ 4 | email | Email address
+ 5 | url | URL
+ 6 | host | Host
+ 7 | sfloat | Scientific notation
+ 8 | version | Version number
+ 9 | hword_numpart | Hyphenated word part, letters and digits
+ 10 | hword_part | Hyphenated word part, all letters
+ 11 | hword_asciipart | Hyphenated word part, all ASCII
+ 12 | blank | Space symbols
+ 13 | tag | XML tag
+ 14 | protocol | Protocol head
+ 15 | numhword | Hyphenated word, letters and digits
+ 16 | asciihword | Hyphenated word, all ASCII
+ 17 | hword | Hyphenated word, all letters
+ 18 | url_path | URL path
+ 19 | file | File or path name
+ 20 | float | Decimal notation
+ 21 | int | Signed integer
+ 22 | uint | Unsigned integer
+ 23 | entity | XML entity
+</pre><p>
+ </p></div><div class="sect2" id="TEXTSEARCH-DICTIONARY-TESTING"><div class="titlepage"><div><div><h3 class="title">12.8.3. Dictionary Testing</h3></div></div></div><p>
+ The <code class="function">ts_lexize</code> function facilitates dictionary testing.
+ </p><a id="id-1.5.11.11.5.3" class="indexterm"></a><pre class="synopsis">
+ts_lexize(<em class="replaceable"><code>dict</code></em> <code class="type">regdictionary</code>, <em class="replaceable"><code>token</code></em> <code class="type">text</code>) returns <code class="type">text[]</code>
+</pre><p>
+ <code class="function">ts_lexize</code> returns an array of lexemes if the input
+ <em class="replaceable"><code>token</code></em> is known to the dictionary,
+ or an empty array if the token
+ is known to the dictionary but it is a stop word, or
+ <code class="literal">NULL</code> if it is an unknown word.
+ </p><p>
+ Examples:
+
+</p><pre class="screen">
+SELECT ts_lexize('english_stem', 'stars');
+ ts_lexize
+-----------
+ {star}
+
+SELECT ts_lexize('english_stem', 'a');
+ ts_lexize
+-----------
+ {}
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <code class="function">ts_lexize</code> function expects a single
+ <span class="emphasis"><em>token</em></span>, not text. Here is a case
+ where this can be confusing:
+
+</p><pre class="screen">
+SELECT ts_lexize('thesaurus_astro', 'supernovae stars') is null;
+ ?column?
+----------
+ t
+</pre><p>
+
+ The thesaurus dictionary <code class="literal">thesaurus_astro</code> does know the
+ phrase <code class="literal">supernovae stars</code>, but <code class="function">ts_lexize</code>
+ fails since it does not parse the input text but treats it as a single
+ token. Use <code class="function">plainto_tsquery</code> or <code class="function">to_tsvector</code> to
+ test thesaurus dictionaries, for example:
+
+</p><pre class="screen">
+SELECT plainto_tsquery('supernovae stars');
+ plainto_tsquery
+-----------------
+ 'sn'
+</pre><p>
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-configuration.html" title="12.7. Configuration Example">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.7. Configuration Example </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.9. Preferred Index Types for Text Search</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-dictionaries.html b/doc/src/sgml/html/textsearch-dictionaries.html
new file mode 100644
index 0000000..1ba4782
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-dictionaries.html
@@ -0,0 +1,661 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.6. Dictionaries</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-parsers.html" title="12.5. Parsers" /><link rel="next" href="textsearch-configuration.html" title="12.7. Configuration Example" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.6. Dictionaries</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-parsers.html" title="12.5. Parsers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-configuration.html" title="12.7. Configuration Example">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-DICTIONARIES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.6. Dictionaries</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS">12.6.1. Stop Words</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY">12.6.2. Simple Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SYNONYM-DICTIONARY">12.6.3. Synonym Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-THESAURUS">12.6.4. Thesaurus Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-ISPELL-DICTIONARY">12.6.5. <span class="application">Ispell</span> Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SNOWBALL-DICTIONARY">12.6.6. <span class="application">Snowball</span> Dictionary</a></span></dt></dl></div><p>
+ Dictionaries are used to eliminate words that should not be considered in a
+ search (<em class="firstterm">stop words</em>), and to <em class="firstterm">normalize</em> words so
+ that different derived forms of the same word will match. A successfully
+ normalized word is called a <em class="firstterm">lexeme</em>. Aside from
+ improving search quality, normalization and removal of stop words reduce the
+ size of the <code class="type">tsvector</code> representation of a document, thereby
+ improving performance. Normalization does not always have linguistic meaning
+ and usually depends on application semantics.
+ </p><p>
+ Some examples of normalization:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ Linguistic — Ispell dictionaries try to reduce input words to a
+ normalized form; stemmer dictionaries remove word endings
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <acronym class="acronym">URL</acronym> locations can be canonicalized to make
+ equivalent URLs match:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ http://www.pgsql.ru/db/mw/index.html
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ http://www.pgsql.ru/db/mw/
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ http://www.pgsql.ru/db/../db/mw/index.html
+ </p></li></ul></div><p>
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Color names can be replaced by their hexadecimal values, e.g.,
+ <code class="literal">red, green, blue, magenta -&gt; FF0000, 00FF00, 0000FF, FF00FF</code>
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ If indexing numbers, we can
+ remove some fractional digits to reduce the range of possible
+ numbers, so for example <span class="emphasis"><em>3.14</em></span>159265359,
+ <span class="emphasis"><em>3.14</em></span>15926, <span class="emphasis"><em>3.14</em></span> will be the same
+ after normalization if only two digits are kept after the decimal point.
+ </p></li></ul></div><p>
+
+ </p><p>
+ A dictionary is a program that accepts a token as
+ input and returns:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ an array of lexemes if the input token is known to the dictionary
+ (notice that one token can produce more than one lexeme)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ a single lexeme with the <code class="literal">TSL_FILTER</code> flag set, to replace
+ the original token with a new token to be passed to subsequent
+ dictionaries (a dictionary that does this is called a
+ <em class="firstterm">filtering dictionary</em>)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ an empty array if the dictionary knows the token, but it is a stop word
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">NULL</code> if the dictionary does not recognize the input token
+ </p></li></ul></div><p>
+ </p><p>
+ <span class="productname">PostgreSQL</span> provides predefined dictionaries for
+ many languages. There are also several predefined templates that can be
+ used to create new dictionaries with custom parameters. Each predefined
+ dictionary template is described below. If no existing
+ template is suitable, it is possible to create new ones; see the
+ <code class="filename">contrib/</code> area of the <span class="productname">PostgreSQL</span> distribution
+ for examples.
+ </p><p>
+ A text search configuration binds a parser together with a set of
+ dictionaries to process the parser's output tokens. For each token
+ type that the parser can return, a separate list of dictionaries is
+ specified by the configuration. When a token of that type is found
+ by the parser, each dictionary in the list is consulted in turn,
+ until some dictionary recognizes it as a known word. If it is identified
+ as a stop word, or if no dictionary recognizes the token, it will be
+ discarded and not indexed or searched for.
+ Normally, the first dictionary that returns a non-<code class="literal">NULL</code>
+ output determines the result, and any remaining dictionaries are not
+ consulted; but a filtering dictionary can replace the given word
+ with a modified word, which is then passed to subsequent dictionaries.
+ </p><p>
+ The general rule for configuring a list of dictionaries
+ is to place first the most narrow, most specific dictionary, then the more
+ general dictionaries, finishing with a very general dictionary, like
+ a <span class="application">Snowball</span> stemmer or <code class="literal">simple</code>, which
+ recognizes everything. For example, for an astronomy-specific search
+ (<code class="literal">astro_en</code> configuration) one could bind token type
+ <code class="type">asciiword</code> (ASCII word) to a synonym dictionary of astronomical
+ terms, a general English dictionary and a <span class="application">Snowball</span> English
+ stemmer:
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION astro_en
+ ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;
+</pre><p>
+ </p><p>
+ A filtering dictionary can be placed anywhere in the list, except at the
+ end where it'd be useless. Filtering dictionaries are useful to partially
+ normalize words to simplify the task of later dictionaries. For example,
+ a filtering dictionary could be used to remove accents from accented
+ letters, as is done by the <a class="xref" href="unaccent.html" title="F.48. unaccent">unaccent</a> module.
+ </p><div class="sect2" id="TEXTSEARCH-STOPWORDS"><div class="titlepage"><div><div><h3 class="title">12.6.1. Stop Words</h3></div></div></div><p>
+ Stop words are words that are very common, appear in almost every
+ document, and have no discrimination value. Therefore, they can be ignored
+ in the context of full text searching. For example, every English text
+ contains words like <code class="literal">a</code> and <code class="literal">the</code>, so it is
+ useless to store them in an index. However, stop words do affect the
+ positions in <code class="type">tsvector</code>, which in turn affect ranking:
+
+</p><pre class="screen">
+SELECT to_tsvector('english', 'in the list of stop words');
+ to_tsvector
+----------------------------
+ 'list':3 'stop':5 'word':6
+</pre><p>
+
+ The missing positions 1,2,4 are because of stop words. Ranks
+ calculated for documents with and without stop words are quite different:
+
+</p><pre class="screen">
+SELECT ts_rank_cd (to_tsvector('english', 'in the list of stop words'), to_tsquery('list &amp; stop'));
+ ts_rank_cd
+------------
+ 0.05
+
+SELECT ts_rank_cd (to_tsvector('english', 'list stop words'), to_tsquery('list &amp; stop'));
+ ts_rank_cd
+------------
+ 0.1
+</pre><p>
+
+ </p><p>
+ It is up to the specific dictionary how it treats stop words. For example,
+ <code class="literal">ispell</code> dictionaries first normalize words and then
+ look at the list of stop words, while <code class="literal">Snowball</code> stemmers
+ first check the list of stop words. The reason for the different
+ behavior is an attempt to decrease noise.
+ </p></div><div class="sect2" id="TEXTSEARCH-SIMPLE-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.2. Simple Dictionary</h3></div></div></div><p>
+ The <code class="literal">simple</code> dictionary template operates by converting the
+ input token to lower case and checking it against a file of stop words.
+ If it is found in the file then an empty array is returned, causing
+ the token to be discarded. If not, the lower-cased form of the word
+ is returned as the normalized lexeme. Alternatively, the dictionary
+ can be configured to report non-stop-words as unrecognized, allowing
+ them to be passed on to the next dictionary in the list.
+ </p><p>
+ Here is an example of a dictionary definition using the <code class="literal">simple</code>
+ template:
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY public.simple_dict (
+ TEMPLATE = pg_catalog.simple,
+ STOPWORDS = english
+);
+</pre><p>
+
+ Here, <code class="literal">english</code> is the base name of a file of stop words.
+ The file's full name will be
+ <code class="filename">$SHAREDIR/tsearch_data/english.stop</code>,
+ where <code class="literal">$SHAREDIR</code> means the
+ <span class="productname">PostgreSQL</span> installation's shared-data directory,
+ often <code class="filename">/usr/local/share/postgresql</code> (use <code class="command">pg_config
+ --sharedir</code> to determine it if you're not sure).
+ The file format is simply a list
+ of words, one per line. Blank lines and trailing spaces are ignored,
+ and upper case is folded to lower case, but no other processing is done
+ on the file contents.
+ </p><p>
+ Now we can test our dictionary:
+
+</p><pre class="screen">
+SELECT ts_lexize('public.simple_dict', 'YeS');
+ ts_lexize
+-----------
+ {yes}
+
+SELECT ts_lexize('public.simple_dict', 'The');
+ ts_lexize
+-----------
+ {}
+</pre><p>
+ </p><p>
+ We can also choose to return <code class="literal">NULL</code>, instead of the lower-cased
+ word, if it is not found in the stop words file. This behavior is
+ selected by setting the dictionary's <code class="literal">Accept</code> parameter to
+ <code class="literal">false</code>. Continuing the example:
+
+</p><pre class="screen">
+ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false );
+
+SELECT ts_lexize('public.simple_dict', 'YeS');
+ ts_lexize
+-----------
+
+
+SELECT ts_lexize('public.simple_dict', 'The');
+ ts_lexize
+-----------
+ {}
+</pre><p>
+ </p><p>
+ With the default setting of <code class="literal">Accept</code> = <code class="literal">true</code>,
+ it is only useful to place a <code class="literal">simple</code> dictionary at the end
+ of a list of dictionaries, since it will never pass on any token to
+ a following dictionary. Conversely, <code class="literal">Accept</code> = <code class="literal">false</code>
+ is only useful when there is at least one following dictionary.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ Most types of dictionaries rely on configuration files, such as files of
+ stop words. These files <span class="emphasis"><em>must</em></span> be stored in UTF-8 encoding.
+ They will be translated to the actual database encoding, if that is
+ different, when they are read into the server.
+ </p></div><div class="caution"><h3 class="title">Caution</h3><p>
+ Normally, a database session will read a dictionary configuration file
+ only once, when it is first used within the session. If you modify a
+ configuration file and want to force existing sessions to pick up the
+ new contents, issue an <code class="command">ALTER TEXT SEARCH DICTIONARY</code> command
+ on the dictionary. This can be a <span class="quote">“<span class="quote">dummy</span>”</span> update that doesn't
+ actually change any parameter values.
+ </p></div></div><div class="sect2" id="TEXTSEARCH-SYNONYM-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.3. Synonym Dictionary</h3></div></div></div><p>
+ This dictionary template is used to create dictionaries that replace a
+ word with a synonym. Phrases are not supported (use the thesaurus
+ template (<a class="xref" href="textsearch-dictionaries.html#TEXTSEARCH-THESAURUS" title="12.6.4. Thesaurus Dictionary">Section 12.6.4</a>) for that). A synonym
+ dictionary can be used to overcome linguistic problems, for example, to
+ prevent an English stemmer dictionary from reducing the word <span class="quote">“<span class="quote">Paris</span>”</span> to
+ <span class="quote">“<span class="quote">pari</span>”</span>. It is enough to have a <code class="literal">Paris paris</code> line in the
+ synonym dictionary and put it before the <code class="literal">english_stem</code>
+ dictionary. For example:
+
+</p><pre class="screen">
+SELECT * FROM ts_debug('english', 'Paris');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------+----------------+--------------+---------
+ asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari}
+
+CREATE TEXT SEARCH DICTIONARY my_synonym (
+ TEMPLATE = synonym,
+ SYNONYMS = my_synonyms
+);
+
+ALTER TEXT SEARCH CONFIGURATION english
+ ALTER MAPPING FOR asciiword
+ WITH my_synonym, english_stem;
+
+SELECT * FROM ts_debug('english', 'Paris');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------+---------------------------+------------+---------
+ asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris}
+</pre><p>
+ </p><p>
+ The only parameter required by the <code class="literal">synonym</code> template is
+ <code class="literal">SYNONYMS</code>, which is the base name of its configuration file
+ — <code class="literal">my_synonyms</code> in the above example.
+ The file's full name will be
+ <code class="filename">$SHAREDIR/tsearch_data/my_synonyms.syn</code>
+ (where <code class="literal">$SHAREDIR</code> means the
+ <span class="productname">PostgreSQL</span> installation's shared-data directory).
+ The file format is just one line
+ per word to be substituted, with the word followed by its synonym,
+ separated by white space. Blank lines and trailing spaces are ignored.
+ </p><p>
+ The <code class="literal">synonym</code> template also has an optional parameter
+ <code class="literal">CaseSensitive</code>, which defaults to <code class="literal">false</code>. When
+ <code class="literal">CaseSensitive</code> is <code class="literal">false</code>, words in the synonym file
+ are folded to lower case, as are input tokens. When it is
+ <code class="literal">true</code>, words and tokens are not folded to lower case,
+ but are compared as-is.
+ </p><p>
+ An asterisk (<code class="literal">*</code>) can be placed at the end of a synonym
+ in the configuration file. This indicates that the synonym is a prefix.
+ The asterisk is ignored when the entry is used in
+ <code class="function">to_tsvector()</code>, but when it is used in
+ <code class="function">to_tsquery()</code>, the result will be a query item with
+ the prefix match marker (see
+ <a class="xref" href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES" title="12.3.2. Parsing Queries">Section 12.3.2</a>).
+ For example, suppose we have these entries in
+ <code class="filename">$SHAREDIR/tsearch_data/synonym_sample.syn</code>:
+</p><pre class="programlisting">
+postgres pgsql
+postgresql pgsql
+postgre pgsql
+gogle googl
+indices index*
+</pre><p>
+ Then we will get these results:
+</p><pre class="screen">
+mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample');
+mydb=# SELECT ts_lexize('syn', 'indices');
+ ts_lexize
+-----------
+ {index}
+(1 row)
+
+mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple);
+mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn;
+mydb=# SELECT to_tsvector('tst', 'indices');
+ to_tsvector
+-------------
+ 'index':1
+(1 row)
+
+mydb=# SELECT to_tsquery('tst', 'indices');
+ to_tsquery
+------------
+ 'index':*
+(1 row)
+
+mydb=# SELECT 'indexes are very useful'::tsvector;
+ tsvector
+---------------------------------
+ 'are' 'indexes' 'useful' 'very'
+(1 row)
+
+mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst', 'indices');
+ ?column?
+----------
+ t
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="TEXTSEARCH-THESAURUS"><div class="titlepage"><div><div><h3 class="title">12.6.4. Thesaurus Dictionary</h3></div></div></div><p>
+ A thesaurus dictionary (sometimes abbreviated as <acronym class="acronym">TZ</acronym>) is
+ a collection of words that includes information about the relationships
+ of words and phrases, i.e., broader terms (<acronym class="acronym">BT</acronym>), narrower
+ terms (<acronym class="acronym">NT</acronym>), preferred terms, non-preferred terms, related
+ terms, etc.
+ </p><p>
+ Basically a thesaurus dictionary replaces all non-preferred terms by one
+ preferred term and, optionally, preserves the original terms for indexing
+ as well. <span class="productname">PostgreSQL</span>'s current implementation of the
+ thesaurus dictionary is an extension of the synonym dictionary with added
+ <em class="firstterm">phrase</em> support. A thesaurus dictionary requires
+ a configuration file of the following format:
+
+</p><pre class="programlisting">
+# this is a comment
+sample word(s) : indexed word(s)
+more sample word(s) : more indexed word(s)
+...
+</pre><p>
+
+ where the colon (<code class="symbol">:</code>) symbol acts as a delimiter between a
+ phrase and its replacement.
+ </p><p>
+ A thesaurus dictionary uses a <em class="firstterm">subdictionary</em> (which
+ is specified in the dictionary's configuration) to normalize the input
+ text before checking for phrase matches. It is only possible to select one
+ subdictionary. An error is reported if the subdictionary fails to
+ recognize a word. In that case, you should remove the use of the word or
+ teach the subdictionary about it. You can place an asterisk
+ (<code class="symbol">*</code>) at the beginning of an indexed word to skip applying
+ the subdictionary to it, but all sample words <span class="emphasis"><em>must</em></span> be known
+ to the subdictionary.
+ </p><p>
+ The thesaurus dictionary chooses the longest match if there are multiple
+ phrases matching the input, and ties are broken by using the last
+ definition.
+ </p><p>
+ Specific stop words recognized by the subdictionary cannot be
+ specified; instead use <code class="literal">?</code> to mark the location where any
+ stop word can appear. For example, assuming that <code class="literal">a</code> and
+ <code class="literal">the</code> are stop words according to the subdictionary:
+
+</p><pre class="programlisting">
+? one ? two : swsw
+</pre><p>
+
+ matches <code class="literal">a one the two</code> and <code class="literal">the one a two</code>;
+ both would be replaced by <code class="literal">swsw</code>.
+ </p><p>
+ Since a thesaurus dictionary has the capability to recognize phrases it
+ must remember its state and interact with the parser. A thesaurus dictionary
+ uses these assignments to check if it should handle the next word or stop
+ accumulation. The thesaurus dictionary must be configured
+ carefully. For example, if the thesaurus dictionary is assigned to handle
+ only the <code class="literal">asciiword</code> token, then a thesaurus dictionary
+ definition like <code class="literal">one 7</code> will not work since token type
+ <code class="literal">uint</code> is not assigned to the thesaurus dictionary.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ Thesauruses are used during indexing so any change in the thesaurus
+ dictionary's parameters <span class="emphasis"><em>requires</em></span> reindexing.
+ For most other dictionary types, small changes such as adding or
+ removing stopwords does not force reindexing.
+ </p></div><div class="sect3" id="TEXTSEARCH-THESAURUS-CONFIG"><div class="titlepage"><div><div><h4 class="title">12.6.4.1. Thesaurus Configuration</h4></div></div></div><p>
+ To define a new thesaurus dictionary, use the <code class="literal">thesaurus</code>
+ template. For example:
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY thesaurus_simple (
+ TEMPLATE = thesaurus,
+ DictFile = mythesaurus,
+ Dictionary = pg_catalog.english_stem
+);
+</pre><p>
+
+ Here:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">thesaurus_simple</code> is the new dictionary's name
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">mythesaurus</code> is the base name of the thesaurus
+ configuration file.
+ (Its full name will be <code class="filename">$SHAREDIR/tsearch_data/mythesaurus.ths</code>,
+ where <code class="literal">$SHAREDIR</code> means the installation shared-data
+ directory.)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <code class="literal">pg_catalog.english_stem</code> is the subdictionary (here,
+ a Snowball English stemmer) to use for thesaurus normalization.
+ Notice that the subdictionary will have its own
+ configuration (for example, stop words), which is not shown here.
+ </p></li></ul></div><p>
+
+ Now it is possible to bind the thesaurus dictionary <code class="literal">thesaurus_simple</code>
+ to the desired token types in a configuration, for example:
+
+</p><pre class="programlisting">
+ALTER TEXT SEARCH CONFIGURATION russian
+ ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
+ WITH thesaurus_simple;
+</pre><p>
+ </p></div><div class="sect3" id="TEXTSEARCH-THESAURUS-EXAMPLES"><div class="titlepage"><div><div><h4 class="title">12.6.4.2. Thesaurus Example</h4></div></div></div><p>
+ Consider a simple astronomical thesaurus <code class="literal">thesaurus_astro</code>,
+ which contains some astronomical word combinations:
+
+</p><pre class="programlisting">
+supernovae stars : sn
+crab nebulae : crab
+</pre><p>
+
+ Below we create a dictionary and bind some token types to
+ an astronomical thesaurus and English stemmer:
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY thesaurus_astro (
+ TEMPLATE = thesaurus,
+ DictFile = thesaurus_astro,
+ Dictionary = english_stem
+);
+
+ALTER TEXT SEARCH CONFIGURATION russian
+ ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
+ WITH thesaurus_astro, english_stem;
+</pre><p>
+
+ Now we can see how it works.
+ <code class="function">ts_lexize</code> is not very useful for testing a thesaurus,
+ because it treats its input as a single token. Instead we can use
+ <code class="function">plainto_tsquery</code> and <code class="function">to_tsvector</code>
+ which will break their input strings into multiple tokens:
+
+</p><pre class="screen">
+SELECT plainto_tsquery('supernova star');
+ plainto_tsquery
+-----------------
+ 'sn'
+
+SELECT to_tsvector('supernova star');
+ to_tsvector
+-------------
+ 'sn':1
+</pre><p>
+
+ In principle, one can use <code class="function">to_tsquery</code> if you quote
+ the argument:
+
+</p><pre class="screen">
+SELECT to_tsquery('''supernova star''');
+ to_tsquery
+------------
+ 'sn'
+</pre><p>
+
+ Notice that <code class="literal">supernova star</code> matches <code class="literal">supernovae
+ stars</code> in <code class="literal">thesaurus_astro</code> because we specified
+ the <code class="literal">english_stem</code> stemmer in the thesaurus definition.
+ The stemmer removed the <code class="literal">e</code> and <code class="literal">s</code>.
+ </p><p>
+ To index the original phrase as well as the substitute, just include it
+ in the right-hand part of the definition:
+
+</p><pre class="screen">
+supernovae stars : sn supernovae stars
+
+SELECT plainto_tsquery('supernova star');
+ plainto_tsquery
+-----------------------------
+ 'sn' &amp; 'supernova' &amp; 'star'
+</pre><p>
+ </p></div></div><div class="sect2" id="TEXTSEARCH-ISPELL-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.5. <span class="application">Ispell</span> Dictionary</h3></div></div></div><p>
+ The <span class="application">Ispell</span> dictionary template supports
+ <em class="firstterm">morphological dictionaries</em>, which can normalize many
+ different linguistic forms of a word into the same lexeme. For example,
+ an English <span class="application">Ispell</span> dictionary can match all declensions and
+ conjugations of the search term <code class="literal">bank</code>, e.g.,
+ <code class="literal">banking</code>, <code class="literal">banked</code>, <code class="literal">banks</code>,
+ <code class="literal">banks'</code>, and <code class="literal">bank's</code>.
+ </p><p>
+ The standard <span class="productname">PostgreSQL</span> distribution does
+ not include any <span class="application">Ispell</span> configuration files.
+ Dictionaries for a large number of languages are available from <a class="ulink" href="https://www.cs.hmc.edu/~geoff/ispell.html" target="_top">Ispell</a>.
+ Also, some more modern dictionary file formats are supported — <a class="ulink" href="https://en.wikipedia.org/wiki/MySpell" target="_top">MySpell</a> (OO &lt; 2.0.1)
+ and <a class="ulink" href="https://hunspell.github.io/" target="_top">Hunspell</a>
+ (OO &gt;= 2.0.2). A large list of dictionaries is available on the <a class="ulink" href="https://wiki.openoffice.org/wiki/Dictionaries" target="_top">OpenOffice
+ Wiki</a>.
+ </p><p>
+ To create an <span class="application">Ispell</span> dictionary perform these steps:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ download dictionary configuration files. <span class="productname">OpenOffice</span>
+ extension files have the <code class="filename">.oxt</code> extension. It is necessary
+ to extract <code class="filename">.aff</code> and <code class="filename">.dic</code> files, change
+ extensions to <code class="filename">.affix</code> and <code class="filename">.dict</code>. For some
+ dictionary files it is also needed to convert characters to the UTF-8
+ encoding with commands (for example, for a Norwegian language dictionary):
+</p><pre class="programlisting">
+iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff
+iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic
+</pre><p>
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ copy files to the <code class="filename">$SHAREDIR/tsearch_data</code> directory
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ load files into PostgreSQL with the following command:
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY english_hunspell (
+ TEMPLATE = ispell,
+ DictFile = en_us,
+ AffFile = en_us,
+ Stopwords = english);
+</pre><p>
+ </p></li></ul></div><p>
+ Here, <code class="literal">DictFile</code>, <code class="literal">AffFile</code>, and <code class="literal">StopWords</code>
+ specify the base names of the dictionary, affixes, and stop-words files.
+ The stop-words file has the same format explained above for the
+ <code class="literal">simple</code> dictionary type. The format of the other files is
+ not specified here but is available from the above-mentioned web sites.
+ </p><p>
+ Ispell dictionaries usually recognize a limited set of words, so they
+ should be followed by another broader dictionary; for
+ example, a Snowball dictionary, which recognizes everything.
+ </p><p>
+ The <code class="filename">.affix</code> file of <span class="application">Ispell</span> has the following
+ structure:
+</p><pre class="programlisting">
+prefixes
+flag *A:
+ . &gt; RE # As in enter &gt; reenter
+suffixes
+flag T:
+ E &gt; ST # As in late &gt; latest
+ [^AEIOU]Y &gt; -Y,IEST # As in dirty &gt; dirtiest
+ [AEIOU]Y &gt; EST # As in gray &gt; grayest
+ [^EY] &gt; EST # As in small &gt; smallest
+</pre><p>
+ </p><p>
+ And the <code class="filename">.dict</code> file has the following structure:
+</p><pre class="programlisting">
+lapse/ADGRS
+lard/DGRS
+large/PRTY
+lark/MRS
+</pre><p>
+ </p><p>
+ Format of the <code class="filename">.dict</code> file is:
+</p><pre class="programlisting">
+basic_form/affix_class_name
+</pre><p>
+ </p><p>
+ In the <code class="filename">.affix</code> file every affix flag is described in the
+ following format:
+</p><pre class="programlisting">
+condition &gt; [-stripping_letters,] adding_affix
+</pre><p>
+ </p><p>
+ Here, condition has a format similar to the format of regular expressions.
+ It can use groupings <code class="literal">[...]</code> and <code class="literal">[^...]</code>.
+ For example, <code class="literal">[AEIOU]Y</code> means that the last letter of the word
+ is <code class="literal">"y"</code> and the penultimate letter is <code class="literal">"a"</code>,
+ <code class="literal">"e"</code>, <code class="literal">"i"</code>, <code class="literal">"o"</code> or <code class="literal">"u"</code>.
+ <code class="literal">[^EY]</code> means that the last letter is neither <code class="literal">"e"</code>
+ nor <code class="literal">"y"</code>.
+ </p><p>
+ Ispell dictionaries support splitting compound words;
+ a useful feature.
+ Notice that the affix file should specify a special flag using the
+ <code class="literal">compoundwords controlled</code> statement that marks dictionary
+ words that can participate in compound formation:
+
+</p><pre class="programlisting">
+compoundwords controlled z
+</pre><p>
+
+ Here are some examples for the Norwegian language:
+
+</p><pre class="programlisting">
+SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
+ {over,buljong,terning,pakk,mester,assistent}
+SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
+ {sjokoladefabrikk,sjokolade,fabrikk}
+</pre><p>
+ </p><p>
+ <span class="application">MySpell</span> format is a subset of <span class="application">Hunspell</span>.
+ The <code class="filename">.affix</code> file of <span class="application">Hunspell</span> has the following
+ structure:
+</p><pre class="programlisting">
+PFX A Y 1
+PFX A 0 re .
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+</pre><p>
+ </p><p>
+ The first line of an affix class is the header. Fields of an affix rules are
+ listed after the header:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ parameter name (PFX or SFX)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ flag (name of the affix class)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ stripping characters from beginning (at prefix) or end (at suffix) of the
+ word
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ adding affix
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ condition that has a format similar to the format of regular expressions.
+ </p></li></ul></div><p>
+ The <code class="filename">.dict</code> file looks like the <code class="filename">.dict</code> file of
+ <span class="application">Ispell</span>:
+</p><pre class="programlisting">
+larder/M
+lardy/RT
+large/RSPMYT
+largehearted
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="application">MySpell</span> does not support compound words.
+ <span class="application">Hunspell</span> has sophisticated support for compound words. At
+ present, <span class="productname">PostgreSQL</span> implements only the basic
+ compound word operations of Hunspell.
+ </p></div></div><div class="sect2" id="TEXTSEARCH-SNOWBALL-DICTIONARY"><div class="titlepage"><div><div><h3 class="title">12.6.6. <span class="application">Snowball</span> Dictionary</h3></div></div></div><p>
+ The <span class="application">Snowball</span> dictionary template is based on a project
+ by Martin Porter, inventor of the popular Porter's stemming algorithm
+ for the English language. Snowball now provides stemming algorithms for
+ many languages (see the <a class="ulink" href="https://snowballstem.org/" target="_top">Snowball
+ site</a> for more information). Each algorithm understands how to
+ reduce common variant forms of words to a base, or stem, spelling within
+ its language. A Snowball dictionary requires a <code class="literal">language</code>
+ parameter to identify which stemmer to use, and optionally can specify a
+ <code class="literal">stopword</code> file name that gives a list of words to eliminate.
+ (<span class="productname">PostgreSQL</span>'s standard stopword lists are also
+ provided by the Snowball project.)
+ For example, there is a built-in definition equivalent to
+
+</p><pre class="programlisting">
+CREATE TEXT SEARCH DICTIONARY english_stem (
+ TEMPLATE = snowball,
+ Language = english,
+ StopWords = english
+);
+</pre><p>
+
+ The stopword file format is the same as already explained.
+ </p><p>
+ A <span class="application">Snowball</span> dictionary recognizes everything, whether
+ or not it is able to simplify the word, so it should be placed
+ at the end of the dictionary list. It is useless to have it
+ before any other dictionary because a token will never pass through it to
+ the next dictionary.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-parsers.html" title="12.5. Parsers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-configuration.html" title="12.7. Configuration Example">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.5. Parsers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.7. Configuration Example</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-features.html b/doc/src/sgml/html/textsearch-features.html
new file mode 100644
index 0000000..357dc9a
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-features.html
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.4. Additional Features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-controls.html" title="12.3. Controlling Text Search" /><link rel="next" href="textsearch-parsers.html" title="12.5. Parsers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.4. Additional Features</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-controls.html" title="12.3. Controlling Text Search">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-parsers.html" title="12.5. Parsers">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-FEATURES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.4. Additional Features</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR">12.4.1. Manipulating Documents</a></span></dt><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY">12.4.2. Manipulating Queries</a></span></dt><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS">12.4.3. Triggers for Automatic Updates</a></span></dt><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-STATISTICS">12.4.4. Gathering Document Statistics</a></span></dt></dl></div><p>
+ This section describes additional functions and operators that are
+ useful in connection with text search.
+ </p><div class="sect2" id="TEXTSEARCH-MANIPULATE-TSVECTOR"><div class="titlepage"><div><div><h3 class="title">12.4.1. Manipulating Documents</h3></div></div></div><p>
+ <a class="xref" href="textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS" title="12.3.1. Parsing Documents">Section 12.3.1</a> showed how raw textual
+ documents can be converted into <code class="type">tsvector</code> values.
+ <span class="productname">PostgreSQL</span> also provides functions and
+ operators that can be used to manipulate documents that are already
+ in <code class="type">tsvector</code> form.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <a id="id-1.5.11.7.3.3.1.1.1" class="indexterm"></a>
+
+ <code class="literal"><code class="type">tsvector</code> || <code class="type">tsvector</code></code>
+ </span></dt><dd><p>
+ The <code class="type">tsvector</code> concatenation operator
+ returns a vector which combines the lexemes and positional information
+ of the two vectors given as arguments. Positions and weight labels
+ are retained during the concatenation.
+ Positions appearing in the right-hand vector are offset by the largest
+ position mentioned in the left-hand vector, so that the result is
+ nearly equivalent to the result of performing <code class="function">to_tsvector</code>
+ on the concatenation of the two original document strings. (The
+ equivalence is not exact, because any stop-words removed from the
+ end of the left-hand argument will not affect the result, whereas
+ they would have affected the positions of the lexemes in the
+ right-hand argument if textual concatenation were used.)
+ </p><p>
+ One advantage of using concatenation in the vector form, rather than
+ concatenating text before applying <code class="function">to_tsvector</code>, is that
+ you can use different configurations to parse different sections
+ of the document. Also, because the <code class="function">setweight</code> function
+ marks all lexemes of the given vector the same way, it is necessary
+ to parse the text and do <code class="function">setweight</code> before concatenating
+ if you want to label different parts of the document with different
+ weights.
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.7.3.3.2.1.1" class="indexterm"></a>
+
+ <code class="literal">setweight(<em class="replaceable"><code>vector</code></em> <code class="type">tsvector</code>, <em class="replaceable"><code>weight</code></em> <code class="type">"char"</code>) returns <code class="type">tsvector</code></code>
+ </span></dt><dd><p>
+ <code class="function">setweight</code> returns a copy of the input vector in which every
+ position has been labeled with the given <em class="replaceable"><code>weight</code></em>, either
+ <code class="literal">A</code>, <code class="literal">B</code>, <code class="literal">C</code>, or
+ <code class="literal">D</code>. (<code class="literal">D</code> is the default for new
+ vectors and as such is not displayed on output.) These labels are
+ retained when vectors are concatenated, allowing words from different
+ parts of a document to be weighted differently by ranking functions.
+ </p><p>
+ Note that weight labels apply to <span class="emphasis"><em>positions</em></span>, not
+ <span class="emphasis"><em>lexemes</em></span>. If the input vector has been stripped of
+ positions then <code class="function">setweight</code> does nothing.
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.7.3.3.3.1.1" class="indexterm"></a>
+
+ <code class="literal">length(<em class="replaceable"><code>vector</code></em> <code class="type">tsvector</code>) returns <code class="type">integer</code></code>
+ </span></dt><dd><p>
+ Returns the number of lexemes stored in the vector.
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.7.3.3.4.1.1" class="indexterm"></a>
+
+ <code class="literal">strip(<em class="replaceable"><code>vector</code></em> <code class="type">tsvector</code>) returns <code class="type">tsvector</code></code>
+ </span></dt><dd><p>
+ Returns a vector that lists the same lexemes as the given vector, but
+ lacks any position or weight information. The result is usually much
+ smaller than an unstripped vector, but it is also less useful.
+ Relevance ranking does not work as well on stripped vectors as
+ unstripped ones. Also,
+ the <code class="literal">&lt;-&gt;</code> (FOLLOWED BY) <code class="type">tsquery</code> operator
+ will never match stripped input, since it cannot determine the
+ distance between lexeme occurrences.
+ </p></dd></dl></div><p>
+ A full list of <code class="type">tsvector</code>-related functions is available
+ in <a class="xref" href="functions-textsearch.html#TEXTSEARCH-FUNCTIONS-TABLE" title="Table 9.43. Text Search Functions">Table 9.43</a>.
+ </p></div><div class="sect2" id="TEXTSEARCH-MANIPULATE-TSQUERY"><div class="titlepage"><div><div><h3 class="title">12.4.2. Manipulating Queries</h3></div></div></div><p>
+ <a class="xref" href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES" title="12.3.2. Parsing Queries">Section 12.3.2</a> showed how raw textual
+ queries can be converted into <code class="type">tsquery</code> values.
+ <span class="productname">PostgreSQL</span> also provides functions and
+ operators that can be used to manipulate queries that are already
+ in <code class="type">tsquery</code> form.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal"><code class="type">tsquery</code> &amp;&amp; <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ Returns the AND-combination of the two given queries.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="type">tsquery</code> || <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ Returns the OR-combination of the two given queries.
+ </p></dd><dt><span class="term">
+ <code class="literal">!! <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ Returns the negation (NOT) of the given query.
+ </p></dd><dt><span class="term">
+ <code class="literal"><code class="type">tsquery</code> &lt;-&gt; <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ Returns a query that searches for a match to the first given query
+ immediately followed by a match to the second given query, using
+ the <code class="literal">&lt;-&gt;</code> (FOLLOWED BY)
+ <code class="type">tsquery</code> operator. For example:
+
+</p><pre class="screen">
+SELECT to_tsquery('fat') &lt;-&gt; to_tsquery('cat | rat');
+ ?column?
+----------------------------
+ 'fat' &lt;-&gt; ( 'cat' | 'rat' )
+</pre><p>
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.7.4.3.5.1.1" class="indexterm"></a>
+
+ <code class="literal">tsquery_phrase(<em class="replaceable"><code>query1</code></em> <code class="type">tsquery</code>, <em class="replaceable"><code>query2</code></em> <code class="type">tsquery</code> [, <em class="replaceable"><code>distance</code></em> <code class="type">integer</code> ]) returns <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ Returns a query that searches for a match to the first given query
+ followed by a match to the second given query at a distance of exactly
+ <em class="replaceable"><code>distance</code></em> lexemes, using
+ the <code class="literal">&lt;<em class="replaceable"><code>N</code></em>&gt;</code>
+ <code class="type">tsquery</code> operator. For example:
+
+</p><pre class="screen">
+SELECT tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10);
+ tsquery_phrase
+------------------
+ 'fat' &lt;10&gt; 'cat'
+</pre><p>
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.7.4.3.6.1.1" class="indexterm"></a>
+
+ <code class="literal">numnode(<em class="replaceable"><code>query</code></em> <code class="type">tsquery</code>) returns <code class="type">integer</code></code>
+ </span></dt><dd><p>
+ Returns the number of nodes (lexemes plus operators) in a
+ <code class="type">tsquery</code>. This function is useful
+ to determine if the <em class="replaceable"><code>query</code></em> is meaningful
+ (returns &gt; 0), or contains only stop words (returns 0).
+ Examples:
+
+</p><pre class="screen">
+SELECT numnode(plainto_tsquery('the any'));
+NOTICE: query contains only stopword(s) or doesn't contain lexeme(s), ignored
+ numnode
+---------
+ 0
+
+SELECT numnode('foo &amp; bar'::tsquery);
+ numnode
+---------
+ 3
+</pre><p>
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.7.4.3.7.1.1" class="indexterm"></a>
+
+ <code class="literal">querytree(<em class="replaceable"><code>query</code></em> <code class="type">tsquery</code>) returns <code class="type">text</code></code>
+ </span></dt><dd><p>
+ Returns the portion of a <code class="type">tsquery</code> that can be used for
+ searching an index. This function is useful for detecting
+ unindexable queries, for example those containing only stop words
+ or only negated terms. For example:
+
+</p><pre class="screen">
+SELECT querytree(to_tsquery('defined'));
+ querytree
+-----------
+ 'defin'
+
+SELECT querytree(to_tsquery('!defined'));
+ querytree
+-----------
+ T
+</pre><p>
+ </p></dd></dl></div><div class="sect3" id="TEXTSEARCH-QUERY-REWRITING"><div class="titlepage"><div><div><h4 class="title">12.4.2.1. Query Rewriting</h4></div></div></div><a id="id-1.5.11.7.4.4.2" class="indexterm"></a><p>
+ The <code class="function">ts_rewrite</code> family of functions search a
+ given <code class="type">tsquery</code> for occurrences of a target
+ subquery, and replace each occurrence with a
+ substitute subquery. In essence this operation is a
+ <code class="type">tsquery</code>-specific version of substring replacement.
+ A target and substitute combination can be
+ thought of as a <em class="firstterm">query rewrite rule</em>. A collection
+ of such rewrite rules can be a powerful search aid.
+ For example, you can expand the search using synonyms
+ (e.g., <code class="literal">new york</code>, <code class="literal">big apple</code>, <code class="literal">nyc</code>,
+ <code class="literal">gotham</code>) or narrow the search to direct the user to some hot
+ topic. There is some overlap in functionality between this feature
+ and thesaurus dictionaries (<a class="xref" href="textsearch-dictionaries.html#TEXTSEARCH-THESAURUS" title="12.6.4. Thesaurus Dictionary">Section 12.6.4</a>).
+ However, you can modify a set of rewrite rules on-the-fly without
+ reindexing, whereas updating a thesaurus requires reindexing to be
+ effective.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <code class="literal">ts_rewrite (<em class="replaceable"><code>query</code></em> <code class="type">tsquery</code>, <em class="replaceable"><code>target</code></em> <code class="type">tsquery</code>, <em class="replaceable"><code>substitute</code></em> <code class="type">tsquery</code>) returns <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ This form of <code class="function">ts_rewrite</code> simply applies a single
+ rewrite rule: <em class="replaceable"><code>target</code></em>
+ is replaced by <em class="replaceable"><code>substitute</code></em>
+ wherever it appears in <em class="replaceable"><code>query</code></em>. For example:
+
+</p><pre class="screen">
+SELECT ts_rewrite('a &amp; b'::tsquery, 'a'::tsquery, 'c'::tsquery);
+ ts_rewrite
+------------
+ 'b' &amp; 'c'
+</pre><p>
+ </p></dd><dt><span class="term">
+ <code class="literal">ts_rewrite (<em class="replaceable"><code>query</code></em> <code class="type">tsquery</code>, <em class="replaceable"><code>select</code></em> <code class="type">text</code>) returns <code class="type">tsquery</code></code>
+ </span></dt><dd><p>
+ This form of <code class="function">ts_rewrite</code> accepts a starting
+ <em class="replaceable"><code>query</code></em> and an SQL <em class="replaceable"><code>select</code></em> command, which
+ is given as a text string. The <em class="replaceable"><code>select</code></em> must yield two
+ columns of <code class="type">tsquery</code> type. For each row of the
+ <em class="replaceable"><code>select</code></em> result, occurrences of the first column value
+ (the target) are replaced by the second column value (the substitute)
+ within the current <em class="replaceable"><code>query</code></em> value. For example:
+
+</p><pre class="screen">
+CREATE TABLE aliases (t tsquery PRIMARY KEY, s tsquery);
+INSERT INTO aliases VALUES('a', 'c');
+
+SELECT ts_rewrite('a &amp; b'::tsquery, 'SELECT t,s FROM aliases');
+ ts_rewrite
+------------
+ 'b' &amp; 'c'
+</pre><p>
+ </p><p>
+ Note that when multiple rewrite rules are applied in this way,
+ the order of application can be important; so in practice you will
+ want the source query to <code class="literal">ORDER BY</code> some ordering key.
+ </p></dd></dl></div><p>
+ Let's consider a real-life astronomical example. We'll expand query
+ <code class="literal">supernovae</code> using table-driven rewriting rules:
+
+</p><pre class="screen">
+CREATE TABLE aliases (t tsquery primary key, s tsquery);
+INSERT INTO aliases VALUES(to_tsquery('supernovae'), to_tsquery('supernovae|sn'));
+
+SELECT ts_rewrite(to_tsquery('supernovae &amp; crab'), 'SELECT * FROM aliases');
+ ts_rewrite
+---------------------------------
+ 'crab' &amp; ( 'supernova' | 'sn' )
+</pre><p>
+
+ We can change the rewriting rules just by updating the table:
+
+</p><pre class="screen">
+UPDATE aliases
+SET s = to_tsquery('supernovae|sn &amp; !nebulae')
+WHERE t = to_tsquery('supernovae');
+
+SELECT ts_rewrite(to_tsquery('supernovae &amp; crab'), 'SELECT * FROM aliases');
+ ts_rewrite
+---------------------------------------------
+ 'crab' &amp; ( 'supernova' | 'sn' &amp; !'nebula' )
+</pre><p>
+ </p><p>
+ Rewriting can be slow when there are many rewriting rules, since it
+ checks every rule for a possible match. To filter out obvious non-candidate
+ rules we can use the containment operators for the <code class="type">tsquery</code>
+ type. In the example below, we select only those rules which might match
+ the original query:
+
+</p><pre class="screen">
+SELECT ts_rewrite('a &amp; b'::tsquery,
+ 'SELECT t,s FROM aliases WHERE ''a &amp; b''::tsquery @&gt; t');
+ ts_rewrite
+------------
+ 'b' &amp; 'c'
+</pre><p>
+ </p></div></div><div class="sect2" id="TEXTSEARCH-UPDATE-TRIGGERS"><div class="titlepage"><div><div><h3 class="title">12.4.3. Triggers for Automatic Updates</h3></div></div></div><a id="id-1.5.11.7.5.2" class="indexterm"></a><div class="note"><h3 class="title">Note</h3><p>
+ The method described in this section has been obsoleted by the use of
+ stored generated columns, as described in <a class="xref" href="textsearch-tables.html#TEXTSEARCH-TABLES-INDEX" title="12.2.2. Creating Indexes">Section 12.2.2</a>.
+ </p></div><p>
+ When using a separate column to store the <code class="type">tsvector</code> representation
+ of your documents, it is necessary to create a trigger to update the
+ <code class="type">tsvector</code> column when the document content columns change.
+ Two built-in trigger functions are available for this, or you can write
+ your own.
+ </p><pre class="synopsis">
+tsvector_update_trigger(<em class="replaceable"><code>tsvector_column_name</code></em>,​ <em class="replaceable"><code>config_name</code></em>, <em class="replaceable"><code>text_column_name</code></em> [<span class="optional">, ... </span>])
+tsvector_update_trigger_column(<em class="replaceable"><code>tsvector_column_name</code></em>,​ <em class="replaceable"><code>config_column_name</code></em>, <em class="replaceable"><code>text_column_name</code></em> [<span class="optional">, ... </span>])
+</pre><p>
+ These trigger functions automatically compute a <code class="type">tsvector</code>
+ column from one or more textual columns, under the control of
+ parameters specified in the <code class="command">CREATE TRIGGER</code> command.
+ An example of their use is:
+
+</p><pre class="screen">
+CREATE TABLE messages (
+ title text,
+ body text,
+ tsv tsvector
+);
+
+CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
+ON messages FOR EACH ROW EXECUTE FUNCTION
+tsvector_update_trigger(tsv, 'pg_catalog.english', title, body);
+
+INSERT INTO messages VALUES('title here', 'the body text is here');
+
+SELECT * FROM messages;
+ title | body | tsv
+------------+-----------------------+----------------------------
+ title here | the body text is here | 'bodi':4 'text':5 'titl':1
+
+SELECT title, body FROM messages WHERE tsv @@ to_tsquery('title &amp; body');
+ title | body
+------------+-----------------------
+ title here | the body text is here
+</pre><p>
+
+ Having created this trigger, any change in <code class="structfield">title</code> or
+ <code class="structfield">body</code> will automatically be reflected into
+ <code class="structfield">tsv</code>, without the application having to worry about it.
+ </p><p>
+ The first trigger argument must be the name of the <code class="type">tsvector</code>
+ column to be updated. The second argument specifies the text search
+ configuration to be used to perform the conversion. For
+ <code class="function">tsvector_update_trigger</code>, the configuration name is simply
+ given as the second trigger argument. It must be schema-qualified as
+ shown above, so that the trigger behavior will not change with changes
+ in <code class="varname">search_path</code>. For
+ <code class="function">tsvector_update_trigger_column</code>, the second trigger argument
+ is the name of another table column, which must be of type
+ <code class="type">regconfig</code>. This allows a per-row selection of configuration
+ to be made. The remaining argument(s) are the names of textual columns
+ (of type <code class="type">text</code>, <code class="type">varchar</code>, or <code class="type">char</code>). These
+ will be included in the document in the order given. NULL values will
+ be skipped (but the other columns will still be indexed).
+ </p><p>
+ A limitation of these built-in triggers is that they treat all the
+ input columns alike. To process columns differently — for
+ example, to weight title differently from body — it is necessary
+ to write a custom trigger. Here is an example using
+ <span class="application">PL/pgSQL</span> as the trigger language:
+
+</p><pre class="programlisting">
+CREATE FUNCTION messages_trigger() RETURNS trigger AS $$
+begin
+ new.tsv :=
+ setweight(to_tsvector('pg_catalog.english', coalesce(new.title,'')), 'A') ||
+ setweight(to_tsvector('pg_catalog.english', coalesce(new.body,'')), 'D');
+ return new;
+end
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
+ ON messages FOR EACH ROW EXECUTE FUNCTION messages_trigger();
+</pre><p>
+ </p><p>
+ Keep in mind that it is important to specify the configuration name
+ explicitly when creating <code class="type">tsvector</code> values inside triggers,
+ so that the column's contents will not be affected by changes to
+ <code class="varname">default_text_search_config</code>. Failure to do this is likely to
+ lead to problems such as search results changing after a dump and restore.
+ </p></div><div class="sect2" id="TEXTSEARCH-STATISTICS"><div class="titlepage"><div><div><h3 class="title">12.4.4. Gathering Document Statistics</h3></div></div></div><a id="id-1.5.11.7.6.2" class="indexterm"></a><p>
+ The function <code class="function">ts_stat</code> is useful for checking your
+ configuration and for finding stop-word candidates.
+ </p><pre class="synopsis">
+ts_stat(<em class="replaceable"><code>sqlquery</code></em> <code class="type">text</code>, [<span class="optional"> <em class="replaceable"><code>weights</code></em> <code class="type">text</code>, </span>]
+ OUT <em class="replaceable"><code>word</code></em> <code class="type">text</code>, OUT <em class="replaceable"><code>ndoc</code></em> <code class="type">integer</code>,
+ OUT <em class="replaceable"><code>nentry</code></em> <code class="type">integer</code>) returns <code class="type">setof record</code>
+</pre><p>
+ <em class="replaceable"><code>sqlquery</code></em> is a text value containing an SQL
+ query which must return a single <code class="type">tsvector</code> column.
+ <code class="function">ts_stat</code> executes the query and returns statistics about
+ each distinct lexeme (word) contained in the <code class="type">tsvector</code>
+ data. The columns returned are
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>word</code></em> <code class="type">text</code> — the value of a lexeme
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>ndoc</code></em> <code class="type">integer</code> — number of documents
+ (<code class="type">tsvector</code>s) the word occurred in
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="replaceable"><code>nentry</code></em> <code class="type">integer</code> — total number of
+ occurrences of the word
+ </p></li></ul></div><p>
+
+ If <em class="replaceable"><code>weights</code></em> is supplied, only occurrences
+ having one of those weights are counted.
+ </p><p>
+ For example, to find the ten most frequent words in a document collection:
+
+</p><pre class="programlisting">
+SELECT * FROM ts_stat('SELECT vector FROM apod')
+ORDER BY nentry DESC, ndoc DESC, word
+LIMIT 10;
+</pre><p>
+
+ The same, but counting only word occurrences with weight <code class="literal">A</code>
+ or <code class="literal">B</code>:
+
+</p><pre class="programlisting">
+SELECT * FROM ts_stat('SELECT vector FROM apod', 'ab')
+ORDER BY nentry DESC, ndoc DESC, word
+LIMIT 10;
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-controls.html" title="12.3. Controlling Text Search">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-parsers.html" title="12.5. Parsers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.3. Controlling Text Search </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.5. Parsers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-indexes.html b/doc/src/sgml/html/textsearch-indexes.html
new file mode 100644
index 0000000..6667094
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-indexes.html
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.9. Preferred Index Types for Text Search</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-debugging.html" title="12.8. Testing and Debugging Text Search" /><link rel="next" href="textsearch-psql.html" title="12.10. psql Support" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.9. Preferred Index Types for Text Search</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-debugging.html" title="12.8. Testing and Debugging Text Search">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-psql.html" title="12.10. psql Support">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-INDEXES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.9. Preferred Index Types for Text Search</h2></div></div></div><a id="id-1.5.11.12.2" class="indexterm"></a><p>
+ There are two kinds of indexes that can be used to speed up full text
+ searches:
+ <a class="link" href="gin.html" title="Chapter 70. GIN Indexes"><acronym class="acronym">GIN</acronym></a> and
+ <a class="link" href="gist.html" title="Chapter 68. GiST Indexes"><acronym class="acronym">GiST</acronym></a>.
+ Note that indexes are not mandatory for full text searching, but in
+ cases where a column is searched on a regular basis, an index is
+ usually desirable.
+ </p><p>
+ To create such an index, do one of:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <a id="id-1.5.11.12.4.1.1.1.1" class="indexterm"></a>
+
+ <code class="literal">CREATE INDEX <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table</code></em> USING GIN (<em class="replaceable"><code>column</code></em>);</code>
+ </span></dt><dd><p>
+ Creates a GIN (Generalized Inverted Index)-based index.
+ The <em class="replaceable"><code>column</code></em> must be of <code class="type">tsvector</code> type.
+ </p></dd><dt><span class="term">
+ <a id="id-1.5.11.12.4.1.2.1.1" class="indexterm"></a>
+
+ <code class="literal">CREATE INDEX <em class="replaceable"><code>name</code></em> ON <em class="replaceable"><code>table</code></em> USING GIST (<em class="replaceable"><code>column</code></em> [ { DEFAULT | tsvector_ops } (siglen = <em class="replaceable"><code>number</code></em>) ] );</code>
+ </span></dt><dd><p>
+ Creates a GiST (Generalized Search Tree)-based index.
+ The <em class="replaceable"><code>column</code></em> can be of <code class="type">tsvector</code> or
+ <code class="type">tsquery</code> type.
+ Optional integer parameter <code class="literal">siglen</code> determines
+ signature length in bytes (see below for details).
+ </p></dd></dl></div><p>
+ </p><p>
+ GIN indexes are the preferred text search index type. As inverted
+ indexes, they contain an index entry for each word (lexeme), with a
+ compressed list of matching locations. Multi-word searches can find
+ the first match, then use the index to remove rows that are lacking
+ additional words. GIN indexes store only the words (lexemes) of
+ <code class="type">tsvector</code> values, and not their weight labels. Thus a table
+ row recheck is needed when using a query that involves weights.
+ </p><p>
+ A GiST index is <em class="firstterm">lossy</em>, meaning that the index
+ might produce false matches, and it is necessary
+ to check the actual table row to eliminate such false matches.
+ (<span class="productname">PostgreSQL</span> does this automatically when needed.)
+ GiST indexes are lossy because each document is represented in the
+ index by a fixed-length signature. The signature length in bytes is determined
+ by the value of the optional integer parameter <code class="literal">siglen</code>.
+ The default signature length (when <code class="literal">siglen</code> is not specified) is
+ 124 bytes, the maximum signature length is 2024 bytes. The signature is generated by hashing
+ each word into a single bit in an n-bit string, with all these bits OR-ed
+ together to produce an n-bit document signature. When two words hash to
+ the same bit position there will be a false match. If all words in
+ the query have matches (real or false) then the table row must be
+ retrieved to see if the match is correct. Longer signatures lead to a more
+ precise search (scanning a smaller fraction of the index and fewer heap
+ pages), at the cost of a larger index.
+ </p><p>
+ A GiST index can be covering, i.e., use the <code class="literal">INCLUDE</code>
+ clause. Included columns can have data types without any GiST operator
+ class. Included attributes will be stored uncompressed.
+ </p><p>
+ Lossiness causes performance degradation due to unnecessary fetches of table
+ records that turn out to be false matches. Since random access to table
+ records is slow, this limits the usefulness of GiST indexes. The
+ likelihood of false matches depends on several factors, in particular the
+ number of unique words, so using dictionaries to reduce this number is
+ recommended.
+ </p><p>
+ Note that <acronym class="acronym">GIN</acronym> index build time can often be improved
+ by increasing <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a>, while
+ <acronym class="acronym">GiST</acronym> index build time is not sensitive to that
+ parameter.
+ </p><p>
+ Partitioning of big collections and the proper use of GIN and GiST indexes
+ allows the implementation of very fast searches with online update.
+ Partitioning can be done at the database level using table inheritance,
+ or by distributing documents over
+ servers and collecting external search results, e.g., via <a class="link" href="ddl-foreign-data.html" title="5.12. Foreign Data">Foreign Data</a> access.
+ The latter is possible because ranking functions use
+ only local information.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-debugging.html" title="12.8. Testing and Debugging Text Search">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-psql.html" title="12.10. psql Support">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.8. Testing and Debugging Text Search </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.10. <span class="application">psql</span> Support</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-intro.html b/doc/src/sgml/html/textsearch-intro.html
new file mode 100644
index 0000000..bf11772
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-intro.html
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch.html" title="Chapter 12. Full Text Search" /><link rel="next" href="textsearch-tables.html" title="12.2. Tables and Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch.html" title="Chapter 12. Full Text Search">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-tables.html" title="12.2. Tables and Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.1. Introduction</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-intro.html#TEXTSEARCH-DOCUMENT">12.1.1. What Is a Document?</a></span></dt><dt><span class="sect2"><a href="textsearch-intro.html#TEXTSEARCH-MATCHING">12.1.2. Basic Text Matching</a></span></dt><dt><span class="sect2"><a href="textsearch-intro.html#TEXTSEARCH-INTRO-CONFIGURATIONS">12.1.3. Configurations</a></span></dt></dl></div><p>
+ Full Text Searching (or just <em class="firstterm">text search</em>) provides
+ the capability to identify natural-language <em class="firstterm">documents</em> that
+ satisfy a <em class="firstterm">query</em>, and optionally to sort them by
+ relevance to the query. The most common type of search
+ is to find all documents containing given <em class="firstterm">query terms</em>
+ and return them in order of their <em class="firstterm">similarity</em> to the
+ query. Notions of <code class="varname">query</code> and
+ <code class="varname">similarity</code> are very flexible and depend on the specific
+ application. The simplest search considers <code class="varname">query</code> as a
+ set of words and <code class="varname">similarity</code> as the frequency of query
+ words in the document.
+ </p><p>
+ Textual search operators have existed in databases for years.
+ <span class="productname">PostgreSQL</span> has
+ <code class="literal">~</code>, <code class="literal">~*</code>, <code class="literal">LIKE</code>, and
+ <code class="literal">ILIKE</code> operators for textual data types, but they lack
+ many essential properties required by modern information systems:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ There is no linguistic support, even for English. Regular expressions
+ are not sufficient because they cannot easily handle derived words, e.g.,
+ <code class="literal">satisfies</code> and <code class="literal">satisfy</code>. You might
+ miss documents that contain <code class="literal">satisfies</code>, although you
+ probably would like to find them when searching for
+ <code class="literal">satisfy</code>. It is possible to use <code class="literal">OR</code>
+ to search for multiple derived forms, but this is tedious and error-prone
+ (some words can have several thousand derivatives).
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ They provide no ordering (ranking) of search results, which makes them
+ ineffective when thousands of matching documents are found.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ They tend to be slow because there is no index support, so they must
+ process all documents for every search.
+ </p></li></ul></div><p>
+ Full text indexing allows documents to be <span class="emphasis"><em>preprocessed</em></span>
+ and an index saved for later rapid searching. Preprocessing includes:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: none; "><li class="listitem" style="list-style-type: none"><p>
+ <span class="emphasis"><em>Parsing documents into <em class="firstterm">tokens</em></em></span>. It is
+ useful to identify various classes of tokens, e.g., numbers, words,
+ complex words, email addresses, so that they can be processed
+ differently. In principle token classes depend on the specific
+ application, but for most purposes it is adequate to use a predefined
+ set of classes.
+ <span class="productname">PostgreSQL</span> uses a <em class="firstterm">parser</em> to
+ perform this step. A standard parser is provided, and custom parsers
+ can be created for specific needs.
+ </p></li><li class="listitem" style="list-style-type: none"><p>
+ <span class="emphasis"><em>Converting tokens into <em class="firstterm">lexemes</em></em></span>.
+ A lexeme is a string, just like a token, but it has been
+ <em class="firstterm">normalized</em> so that different forms of the same word
+ are made alike. For example, normalization almost always includes
+ folding upper-case letters to lower-case, and often involves removal
+ of suffixes (such as <code class="literal">s</code> or <code class="literal">es</code> in English).
+ This allows searches to find variant forms of the
+ same word, without tediously entering all the possible variants.
+ Also, this step typically eliminates <em class="firstterm">stop words</em>, which
+ are words that are so common that they are useless for searching.
+ (In short, then, tokens are raw fragments of the document text, while
+ lexemes are words that are believed useful for indexing and searching.)
+ <span class="productname">PostgreSQL</span> uses <em class="firstterm">dictionaries</em> to
+ perform this step. Various standard dictionaries are provided, and
+ custom ones can be created for specific needs.
+ </p></li><li class="listitem" style="list-style-type: none"><p>
+ <span class="emphasis"><em>Storing preprocessed documents optimized for
+ searching</em></span>. For example, each document can be represented
+ as a sorted array of normalized lexemes. Along with the lexemes it is
+ often desirable to store positional information to use for
+ <em class="firstterm">proximity ranking</em>, so that a document that
+ contains a more <span class="quote">“<span class="quote">dense</span>”</span> region of query words is
+ assigned a higher rank than one with scattered query words.
+ </p></li></ul></div><p>
+ Dictionaries allow fine-grained control over how tokens are normalized.
+ With appropriate dictionaries, you can:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ Define stop words that should not be indexed.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Map synonyms to a single word using <span class="application">Ispell</span>.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Map phrases to a single word using a thesaurus.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Map different variations of a word to a canonical form using
+ an <span class="application">Ispell</span> dictionary.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Map different variations of a word to a canonical form using
+ <span class="application">Snowball</span> stemmer rules.
+ </p></li></ul></div><p>
+ A data type <code class="type">tsvector</code> is provided for storing preprocessed
+ documents, along with a type <code class="type">tsquery</code> for representing processed
+ queries (<a class="xref" href="datatype-textsearch.html" title="8.11. Text Search Types">Section 8.11</a>). There are many
+ functions and operators available for these data types
+ (<a class="xref" href="functions-textsearch.html" title="9.13. Text Search Functions and Operators">Section 9.13</a>), the most important of which is
+ the match operator <code class="literal">@@</code>, which we introduce in
+ <a class="xref" href="textsearch-intro.html#TEXTSEARCH-MATCHING" title="12.1.2. Basic Text Matching">Section 12.1.2</a>. Full text searches can be accelerated
+ using indexes (<a class="xref" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Section 12.9</a>).
+ </p><div class="sect2" id="TEXTSEARCH-DOCUMENT"><div class="titlepage"><div><div><h3 class="title">12.1.1. What Is a Document?</h3></div></div></div><a id="id-1.5.11.4.10.2" class="indexterm"></a><p>
+ A <em class="firstterm">document</em> is the unit of searching in a full text search
+ system; for example, a magazine article or email message. The text search
+ engine must be able to parse documents and store associations of lexemes
+ (key words) with their parent document. Later, these associations are
+ used to search for documents that contain query words.
+ </p><p>
+ For searches within <span class="productname">PostgreSQL</span>,
+ a document is normally a textual field within a row of a database table,
+ or possibly a combination (concatenation) of such fields, perhaps stored
+ in several tables or obtained dynamically. In other words, a document can
+ be constructed from different parts for indexing and it might not be
+ stored anywhere as a whole. For example:
+
+</p><pre class="programlisting">
+SELECT title || ' ' || author || ' ' || abstract || ' ' || body AS document
+FROM messages
+WHERE mid = 12;
+
+SELECT m.title || ' ' || m.author || ' ' || m.abstract || ' ' || d.body AS document
+FROM messages m, docs d
+WHERE m.mid = d.did AND m.mid = 12;
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Actually, in these example queries, <code class="function">coalesce</code>
+ should be used to prevent a single <code class="literal">NULL</code> attribute from
+ causing a <code class="literal">NULL</code> result for the whole document.
+ </p></div><p>
+ Another possibility is to store the documents as simple text files in the
+ file system. In this case, the database can be used to store the full text
+ index and to execute searches, and some unique identifier can be used to
+ retrieve the document from the file system. However, retrieving files
+ from outside the database requires superuser permissions or special
+ function support, so this is usually less convenient than keeping all
+ the data inside <span class="productname">PostgreSQL</span>. Also, keeping
+ everything inside the database allows easy access
+ to document metadata to assist in indexing and display.
+ </p><p>
+ For text search purposes, each document must be reduced to the
+ preprocessed <code class="type">tsvector</code> format. Searching and ranking
+ are performed entirely on the <code class="type">tsvector</code> representation
+ of a document — the original text need only be retrieved
+ when the document has been selected for display to a user.
+ We therefore often speak of the <code class="type">tsvector</code> as being the
+ document, but of course it is only a compact representation of
+ the full document.
+ </p></div><div class="sect2" id="TEXTSEARCH-MATCHING"><div class="titlepage"><div><div><h3 class="title">12.1.2. Basic Text Matching</h3></div></div></div><p>
+ Full text searching in <span class="productname">PostgreSQL</span> is based on
+ the match operator <code class="literal">@@</code>, which returns
+ <code class="literal">true</code> if a <code class="type">tsvector</code>
+ (document) matches a <code class="type">tsquery</code> (query).
+ It doesn't matter which data type is written first:
+
+</p><pre class="programlisting">
+SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat &amp; rat'::tsquery;
+ ?column?
+----------
+ t
+
+SELECT 'fat &amp; cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat rat'::tsvector;
+ ?column?
+----------
+ f
+</pre><p>
+ </p><p>
+ As the above example suggests, a <code class="type">tsquery</code> is not just raw
+ text, any more than a <code class="type">tsvector</code> is. A <code class="type">tsquery</code>
+ contains search terms, which must be already-normalized lexemes, and
+ may combine multiple terms using AND, OR, NOT, and FOLLOWED BY operators.
+ (For syntax details see <a class="xref" href="datatype-textsearch.html#DATATYPE-TSQUERY" title="8.11.2. tsquery">Section 8.11.2</a>.) There are
+ functions <code class="function">to_tsquery</code>, <code class="function">plainto_tsquery</code>,
+ and <code class="function">phraseto_tsquery</code>
+ that are helpful in converting user-written text into a proper
+ <code class="type">tsquery</code>, primarily by normalizing words appearing in
+ the text. Similarly, <code class="function">to_tsvector</code> is used to parse and
+ normalize a document string. So in practice a text search match would
+ look more like this:
+
+</p><pre class="programlisting">
+SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat &amp; rat');
+ ?column?
+----------
+ t
+</pre><p>
+
+ Observe that this match would not succeed if written as
+
+</p><pre class="programlisting">
+SELECT 'fat cats ate fat rats'::tsvector @@ to_tsquery('fat &amp; rat');
+ ?column?
+----------
+ f
+</pre><p>
+
+ since here no normalization of the word <code class="literal">rats</code> will occur.
+ The elements of a <code class="type">tsvector</code> are lexemes, which are assumed
+ already normalized, so <code class="literal">rats</code> does not match <code class="literal">rat</code>.
+ </p><p>
+ The <code class="literal">@@</code> operator also
+ supports <code class="type">text</code> input, allowing explicit conversion of a text
+ string to <code class="type">tsvector</code> or <code class="type">tsquery</code> to be skipped
+ in simple cases. The variants available are:
+
+</p><pre class="programlisting">
+tsvector @@ tsquery
+tsquery @@ tsvector
+text @@ tsquery
+text @@ text
+</pre><p>
+ </p><p>
+ The first two of these we saw already.
+ The form <code class="type">text</code> <code class="literal">@@</code> <code class="type">tsquery</code>
+ is equivalent to <code class="literal">to_tsvector(x) @@ y</code>.
+ The form <code class="type">text</code> <code class="literal">@@</code> <code class="type">text</code>
+ is equivalent to <code class="literal">to_tsvector(x) @@ plainto_tsquery(y)</code>.
+ </p><p>
+ Within a <code class="type">tsquery</code>, the <code class="literal">&amp;</code> (AND) operator
+ specifies that both its arguments must appear in the document to have a
+ match. Similarly, the <code class="literal">|</code> (OR) operator specifies that
+ at least one of its arguments must appear, while the <code class="literal">!</code> (NOT)
+ operator specifies that its argument must <span class="emphasis"><em>not</em></span> appear in
+ order to have a match.
+ For example, the query <code class="literal">fat &amp; ! rat</code> matches documents that
+ contain <code class="literal">fat</code> but not <code class="literal">rat</code>.
+ </p><p>
+ Searching for phrases is possible with the help of
+ the <code class="literal">&lt;-&gt;</code> (FOLLOWED BY) <code class="type">tsquery</code> operator, which
+ matches only if its arguments have matches that are adjacent and in the
+ given order. For example:
+
+</p><pre class="programlisting">
+SELECT to_tsvector('fatal error') @@ to_tsquery('fatal &lt;-&gt; error');
+ ?column?
+----------
+ t
+
+SELECT to_tsvector('error is not fatal') @@ to_tsquery('fatal &lt;-&gt; error');
+ ?column?
+----------
+ f
+</pre><p>
+
+ There is a more general version of the FOLLOWED BY operator having the
+ form <code class="literal">&lt;<em class="replaceable"><code>N</code></em>&gt;</code>,
+ where <em class="replaceable"><code>N</code></em> is an integer standing for the difference between
+ the positions of the matching lexemes. <code class="literal">&lt;1&gt;</code> is
+ the same as <code class="literal">&lt;-&gt;</code>, while <code class="literal">&lt;2&gt;</code>
+ allows exactly one other lexeme to appear between the matches, and so
+ on. The <code class="literal">phraseto_tsquery</code> function makes use of this
+ operator to construct a <code class="literal">tsquery</code> that can match a multi-word
+ phrase when some of the words are stop words. For example:
+
+</p><pre class="programlisting">
+SELECT phraseto_tsquery('cats ate rats');
+ phraseto_tsquery
+-------------------------------
+ 'cat' &lt;-&gt; 'ate' &lt;-&gt; 'rat'
+
+SELECT phraseto_tsquery('the cats ate the rats');
+ phraseto_tsquery
+-------------------------------
+ 'cat' &lt;-&gt; 'ate' &lt;2&gt; 'rat'
+</pre><p>
+ </p><p>
+ A special case that's sometimes useful is that <code class="literal">&lt;0&gt;</code>
+ can be used to require that two patterns match the same word.
+ </p><p>
+ Parentheses can be used to control nesting of the <code class="type">tsquery</code>
+ operators. Without parentheses, <code class="literal">|</code> binds least tightly,
+ then <code class="literal">&amp;</code>, then <code class="literal">&lt;-&gt;</code>,
+ and <code class="literal">!</code> most tightly.
+ </p><p>
+ It's worth noticing that the AND/OR/NOT operators mean something subtly
+ different when they are within the arguments of a FOLLOWED BY operator
+ than when they are not, because within FOLLOWED BY the exact position of
+ the match is significant. For example, normally <code class="literal">!x</code> matches
+ only documents that do not contain <code class="literal">x</code> anywhere.
+ But <code class="literal">!x &lt;-&gt; y</code> matches <code class="literal">y</code> if it is not
+ immediately after an <code class="literal">x</code>; an occurrence of <code class="literal">x</code>
+ elsewhere in the document does not prevent a match. Another example is
+ that <code class="literal">x &amp; y</code> normally only requires that <code class="literal">x</code>
+ and <code class="literal">y</code> both appear somewhere in the document, but
+ <code class="literal">(x &amp; y) &lt;-&gt; z</code> requires <code class="literal">x</code>
+ and <code class="literal">y</code> to match at the same place, immediately before
+ a <code class="literal">z</code>. Thus this query behaves differently from
+ <code class="literal">x &lt;-&gt; z &amp; y &lt;-&gt; z</code>, which will match a
+ document containing two separate sequences <code class="literal">x z</code> and
+ <code class="literal">y z</code>. (This specific query is useless as written,
+ since <code class="literal">x</code> and <code class="literal">y</code> could not match at the same place;
+ but with more complex situations such as prefix-match patterns, a query
+ of this form could be useful.)
+ </p></div><div class="sect2" id="TEXTSEARCH-INTRO-CONFIGURATIONS"><div class="titlepage"><div><div><h3 class="title">12.1.3. Configurations</h3></div></div></div><p>
+ The above are all simple text search examples. As mentioned before, full
+ text search functionality includes the ability to do many more things:
+ skip indexing certain words (stop words), process synonyms, and use
+ sophisticated parsing, e.g., parse based on more than just white space.
+ This functionality is controlled by <em class="firstterm">text search
+ configurations</em>. <span class="productname">PostgreSQL</span> comes with predefined
+ configurations for many languages, and you can easily create your own
+ configurations. (<span class="application">psql</span>'s <code class="command">\dF</code> command
+ shows all available configurations.)
+ </p><p>
+ During installation an appropriate configuration is selected and
+ <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a> is set accordingly
+ in <code class="filename">postgresql.conf</code>. If you are using the same text search
+ configuration for the entire cluster you can use the value in
+ <code class="filename">postgresql.conf</code>. To use different configurations
+ throughout the cluster but the same configuration within any one database,
+ use <code class="command">ALTER DATABASE ... SET</code>. Otherwise, you can set
+ <code class="varname">default_text_search_config</code> in each session.
+ </p><p>
+ Each text search function that depends on a configuration has an optional
+ <code class="type">regconfig</code> argument, so that the configuration to use can be
+ specified explicitly. <code class="varname">default_text_search_config</code>
+ is used only when this argument is omitted.
+ </p><p>
+ To make it easier to build custom text search configurations, a
+ configuration is built up from simpler database objects.
+ <span class="productname">PostgreSQL</span>'s text search facility provides
+ four types of configuration-related database objects:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ <em class="firstterm">Text search parsers</em> break documents into tokens
+ and classify each token (for example, as words or numbers).
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="firstterm">Text search dictionaries</em> convert tokens to normalized
+ form and reject stop words.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="firstterm">Text search templates</em> provide the functions underlying
+ dictionaries. (A dictionary simply specifies a template and a set
+ of parameters for the template.)
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ <em class="firstterm">Text search configurations</em> select a parser and a set
+ of dictionaries to use to normalize the tokens produced by the parser.
+ </p></li></ul></div><p>
+ Text search parsers and templates are built from low-level C functions;
+ therefore it requires C programming ability to develop new ones, and
+ superuser privileges to install one into a database. (There are examples
+ of add-on parsers and templates in the <code class="filename">contrib/</code> area of the
+ <span class="productname">PostgreSQL</span> distribution.) Since dictionaries and
+ configurations just parameterize and connect together some underlying
+ parsers and templates, no special privilege is needed to create a new
+ dictionary or configuration. Examples of creating custom dictionaries and
+ configurations appear later in this chapter.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch.html" title="Chapter 12. Full Text Search">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-tables.html" title="12.2. Tables and Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 12. Full Text Search </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.2. Tables and Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-limitations.html b/doc/src/sgml/html/textsearch-limitations.html
new file mode 100644
index 0000000..fccf7a3
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-limitations.html
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.11. Limitations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-psql.html" title="12.10. psql Support" /><link rel="next" href="mvcc.html" title="Chapter 13. Concurrency Control" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.11. Limitations</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-psql.html" title="12.10. psql Support">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="mvcc.html" title="Chapter 13. Concurrency Control">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-LIMITATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.11. Limitations</h2></div></div></div><p>
+ The current limitations of <span class="productname">PostgreSQL</span>'s
+ text search features are:
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>The length of each lexeme must be less than 2 kilobytes</p></li><li class="listitem" style="list-style-type: disc"><p>The length of a <code class="type">tsvector</code> (lexemes + positions) must be
+ less than 1 megabyte</p></li><li class="listitem" style="list-style-type: disc"><p>The number of lexemes must be less than
+ 2<sup>64</sup></p></li><li class="listitem" style="list-style-type: disc"><p>Position values in <code class="type">tsvector</code> must be greater than 0 and
+ no more than 16,383</p></li><li class="listitem" style="list-style-type: disc"><p>The match distance in a <code class="literal">&lt;<em class="replaceable"><code>N</code></em>&gt;</code>
+ (FOLLOWED BY) <code class="type">tsquery</code> operator cannot be more than
+ 16,384</p></li><li class="listitem" style="list-style-type: disc"><p>No more than 256 positions per lexeme</p></li><li class="listitem" style="list-style-type: disc"><p>The number of nodes (lexemes + operators) in a <code class="type">tsquery</code>
+ must be less than 32,768</p></li></ul></div><p>
+ </p><p>
+ For comparison, the <span class="productname">PostgreSQL</span> 8.1 documentation
+ contained 10,441 unique words, a total of 335,420 words, and the most
+ frequent word <span class="quote">“<span class="quote">postgresql</span>”</span> was mentioned 6,127 times in 655
+ documents.
+ </p><p>
+ Another example — the <span class="productname">PostgreSQL</span> mailing
+ list archives contained 910,989 unique words with 57,491,343 lexemes in
+ 461,020 messages.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-psql.html" title="12.10. psql Support">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="mvcc.html" title="Chapter 13. Concurrency Control">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.10. <span class="application">psql</span> Support </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 13. Concurrency Control</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-parsers.html b/doc/src/sgml/html/textsearch-parsers.html
new file mode 100644
index 0000000..ec3673b
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-parsers.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.5. Parsers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-features.html" title="12.4. Additional Features" /><link rel="next" href="textsearch-dictionaries.html" title="12.6. Dictionaries" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.5. Parsers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-features.html" title="12.4. Additional Features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-dictionaries.html" title="12.6. Dictionaries">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-PARSERS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.5. Parsers</h2></div></div></div><p>
+ Text search parsers are responsible for splitting raw document text
+ into <em class="firstterm">tokens</em> and identifying each token's type, where
+ the set of possible types is defined by the parser itself.
+ Note that a parser does not modify the text at all — it simply
+ identifies plausible word boundaries. Because of this limited scope,
+ there is less need for application-specific custom parsers than there is
+ for custom dictionaries. At present <span class="productname">PostgreSQL</span>
+ provides just one built-in parser, which has been found to be useful for a
+ wide range of applications.
+ </p><p>
+ The built-in parser is named <code class="literal">pg_catalog.default</code>.
+ It recognizes 23 token types, shown in <a class="xref" href="textsearch-parsers.html#TEXTSEARCH-DEFAULT-PARSER" title="Table 12.1. Default Parser's Token Types">Table 12.1</a>.
+ </p><div class="table" id="TEXTSEARCH-DEFAULT-PARSER"><p class="title"><strong>Table 12.1. Default Parser's Token Types</strong></p><div class="table-contents"><table class="table" summary="Default Parser's Token Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Alias</th><th>Description</th><th>Example</th></tr></thead><tbody><tr><td><code class="literal">asciiword</code></td><td>Word, all ASCII letters</td><td><code class="literal">elephant</code></td></tr><tr><td><code class="literal">word</code></td><td>Word, all letters</td><td><code class="literal">mañana</code></td></tr><tr><td><code class="literal">numword</code></td><td>Word, letters and digits</td><td><code class="literal">beta1</code></td></tr><tr><td><code class="literal">asciihword</code></td><td>Hyphenated word, all ASCII</td><td><code class="literal">up-to-date</code></td></tr><tr><td><code class="literal">hword</code></td><td>Hyphenated word, all letters</td><td><code class="literal">lógico-matemática</code></td></tr><tr><td><code class="literal">numhword</code></td><td>Hyphenated word, letters and digits</td><td><code class="literal">postgresql-beta1</code></td></tr><tr><td><code class="literal">hword_asciipart</code></td><td>Hyphenated word part, all ASCII</td><td><code class="literal">postgresql</code> in the context <code class="literal">postgresql-beta1</code></td></tr><tr><td><code class="literal">hword_part</code></td><td>Hyphenated word part, all letters</td><td><code class="literal">lógico</code> or <code class="literal">matemática</code>
+ in the context <code class="literal">lógico-matemática</code></td></tr><tr><td><code class="literal">hword_numpart</code></td><td>Hyphenated word part, letters and digits</td><td><code class="literal">beta1</code> in the context
+ <code class="literal">postgresql-beta1</code></td></tr><tr><td><code class="literal">email</code></td><td>Email address</td><td><code class="literal">foo@example.com</code></td></tr><tr><td><code class="literal">protocol</code></td><td>Protocol head</td><td><code class="literal">http://</code></td></tr><tr><td><code class="literal">url</code></td><td>URL</td><td><code class="literal">example.com/stuff/index.html</code></td></tr><tr><td><code class="literal">host</code></td><td>Host</td><td><code class="literal">example.com</code></td></tr><tr><td><code class="literal">url_path</code></td><td>URL path</td><td><code class="literal">/stuff/index.html</code>, in the context of a URL</td></tr><tr><td><code class="literal">file</code></td><td>File or path name</td><td><code class="literal">/usr/local/foo.txt</code>, if not within a URL</td></tr><tr><td><code class="literal">sfloat</code></td><td>Scientific notation</td><td><code class="literal">-1.234e56</code></td></tr><tr><td><code class="literal">float</code></td><td>Decimal notation</td><td><code class="literal">-1.234</code></td></tr><tr><td><code class="literal">int</code></td><td>Signed integer</td><td><code class="literal">-1234</code></td></tr><tr><td><code class="literal">uint</code></td><td>Unsigned integer</td><td><code class="literal">1234</code></td></tr><tr><td><code class="literal">version</code></td><td>Version number</td><td><code class="literal">8.3.0</code></td></tr><tr><td><code class="literal">tag</code></td><td>XML tag</td><td><code class="literal">&lt;a href="dictionaries.html"&gt;</code></td></tr><tr><td><code class="literal">entity</code></td><td>XML entity</td><td><code class="literal">&amp;amp;</code></td></tr><tr><td><code class="literal">blank</code></td><td>Space symbols</td><td>(any whitespace or punctuation not otherwise recognized)</td></tr></tbody></table></div></div><br class="table-break" /><div class="note"><h3 class="title">Note</h3><p>
+ The parser's notion of a <span class="quote">“<span class="quote">letter</span>”</span> is determined by the database's
+ locale setting, specifically <code class="varname">lc_ctype</code>. Words containing
+ only the basic ASCII letters are reported as a separate token type,
+ since it is sometimes useful to distinguish them. In most European
+ languages, token types <code class="literal">word</code> and <code class="literal">asciiword</code>
+ should be treated alike.
+ </p><p>
+ <code class="literal">email</code> does not support all valid email characters as
+ defined by <a class="ulink" href="https://tools.ietf.org/html/rfc5322" target="_top">RFC 5322</a>.
+ Specifically, the only non-alphanumeric characters supported for
+ email user names are period, dash, and underscore.
+ </p></div><p>
+ It is possible for the parser to produce overlapping tokens from the same
+ piece of text. As an example, a hyphenated word will be reported both
+ as the entire word and as each component:
+
+</p><pre class="screen">
+SELECT alias, description, token FROM ts_debug('foo-bar-beta1');
+ alias | description | token
+-----------------+------------------------------------------+---------------
+ numhword | Hyphenated word, letters and digits | foo-bar-beta1
+ hword_asciipart | Hyphenated word part, all ASCII | foo
+ blank | Space symbols | -
+ hword_asciipart | Hyphenated word part, all ASCII | bar
+ blank | Space symbols | -
+ hword_numpart | Hyphenated word part, letters and digits | beta1
+</pre><p>
+
+ This behavior is desirable since it allows searches to work for both
+ the whole compound word and for components. Here is another
+ instructive example:
+
+</p><pre class="screen">
+SELECT alias, description, token FROM ts_debug('http://example.com/stuff/index.html');
+ alias | description | token
+----------+---------------+------------------------------
+ protocol | Protocol head | http://
+ url | URL | example.com/stuff/index.html
+ host | Host | example.com
+ url_path | URL path | /stuff/index.html
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-features.html" title="12.4. Additional Features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-dictionaries.html" title="12.6. Dictionaries">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.4. Additional Features </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.6. Dictionaries</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-psql.html b/doc/src/sgml/html/textsearch-psql.html
new file mode 100644
index 0000000..2a63713
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-psql.html
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.10. psql Support</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search" /><link rel="next" href="textsearch-limitations.html" title="12.11. Limitations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.10. <span class="application">psql</span> Support</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-limitations.html" title="12.11. Limitations">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-PSQL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.10. <span class="application">psql</span> Support</h2></div></div></div><p>
+ Information about text search configuration objects can be obtained
+ in <span class="application">psql</span> using a set of commands:
+</p><pre class="synopsis">
+\dF{d,p,t}[<span class="optional">+</span>] [<span class="optional">PATTERN</span>]
+</pre><p>
+ An optional <code class="literal">+</code> produces more details.
+ </p><p>
+ The optional parameter <em class="replaceable"><code>PATTERN</code></em> can be the name of
+ a text search object, optionally schema-qualified. If
+ <em class="replaceable"><code>PATTERN</code></em> is omitted then information about all
+ visible objects will be displayed. <em class="replaceable"><code>PATTERN</code></em> can be a
+ regular expression and can provide <span class="emphasis"><em>separate</em></span> patterns
+ for the schema and object names. The following examples illustrate this:
+
+</p><pre class="screen">
+=&gt; \dF *fulltext*
+ List of text search configurations
+ Schema | Name | Description
+--------+--------------+-------------
+ public | fulltext_cfg |
+</pre><p>
+
+</p><pre class="screen">
+=&gt; \dF *.fulltext*
+ List of text search configurations
+ Schema | Name | Description
+----------+----------------------------
+ fulltext | fulltext_cfg |
+ public | fulltext_cfg |
+</pre><p>
+
+ The available commands are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">\dF[<span class="optional">+</span>] [<span class="optional">PATTERN</span>]</code></span></dt><dd><p>
+ List text search configurations (add <code class="literal">+</code> for more detail).
+</p><pre class="screen">
+=&gt; \dF russian
+ List of text search configurations
+ Schema | Name | Description
+------------+---------+------------------------------------
+ pg_catalog | russian | configuration for russian language
+
+=&gt; \dF+ russian
+Text search configuration "pg_catalog.russian"
+Parser: "pg_catalog.default"
+ Token | Dictionaries
+-----------------+--------------
+ asciihword | english_stem
+ asciiword | english_stem
+ email | simple
+ file | simple
+ float | simple
+ host | simple
+ hword | russian_stem
+ hword_asciipart | english_stem
+ hword_numpart | simple
+ hword_part | russian_stem
+ int | simple
+ numhword | simple
+ numword | simple
+ sfloat | simple
+ uint | simple
+ url | simple
+ url_path | simple
+ version | simple
+ word | russian_stem
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">\dFd[<span class="optional">+</span>] [<span class="optional">PATTERN</span>]</code></span></dt><dd><p>
+ List text search dictionaries (add <code class="literal">+</code> for more detail).
+</p><pre class="screen">
+=&gt; \dFd
+ List of text search dictionaries
+ Schema | Name | Description
+------------+-----------------+-----------------------------------------------------------
+ pg_catalog | arabic_stem | snowball stemmer for arabic language
+ pg_catalog | armenian_stem | snowball stemmer for armenian language
+ pg_catalog | basque_stem | snowball stemmer for basque language
+ pg_catalog | catalan_stem | snowball stemmer for catalan language
+ pg_catalog | danish_stem | snowball stemmer for danish language
+ pg_catalog | dutch_stem | snowball stemmer for dutch language
+ pg_catalog | english_stem | snowball stemmer for english language
+ pg_catalog | finnish_stem | snowball stemmer for finnish language
+ pg_catalog | french_stem | snowball stemmer for french language
+ pg_catalog | german_stem | snowball stemmer for german language
+ pg_catalog | greek_stem | snowball stemmer for greek language
+ pg_catalog | hindi_stem | snowball stemmer for hindi language
+ pg_catalog | hungarian_stem | snowball stemmer for hungarian language
+ pg_catalog | indonesian_stem | snowball stemmer for indonesian language
+ pg_catalog | irish_stem | snowball stemmer for irish language
+ pg_catalog | italian_stem | snowball stemmer for italian language
+ pg_catalog | lithuanian_stem | snowball stemmer for lithuanian language
+ pg_catalog | nepali_stem | snowball stemmer for nepali language
+ pg_catalog | norwegian_stem | snowball stemmer for norwegian language
+ pg_catalog | portuguese_stem | snowball stemmer for portuguese language
+ pg_catalog | romanian_stem | snowball stemmer for romanian language
+ pg_catalog | russian_stem | snowball stemmer for russian language
+ pg_catalog | serbian_stem | snowball stemmer for serbian language
+ pg_catalog | simple | simple dictionary: just lower case and check for stopword
+ pg_catalog | spanish_stem | snowball stemmer for spanish language
+ pg_catalog | swedish_stem | snowball stemmer for swedish language
+ pg_catalog | tamil_stem | snowball stemmer for tamil language
+ pg_catalog | turkish_stem | snowball stemmer for turkish language
+ pg_catalog | yiddish_stem | snowball stemmer for yiddish language
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">\dFp[<span class="optional">+</span>] [<span class="optional">PATTERN</span>]</code></span></dt><dd><p>
+ List text search parsers (add <code class="literal">+</code> for more detail).
+</p><pre class="screen">
+=&gt; \dFp
+ List of text search parsers
+ Schema | Name | Description
+------------+---------+---------------------
+ pg_catalog | default | default word parser
+=&gt; \dFp+
+ Text search parser "pg_catalog.default"
+ Method | Function | Description
+-----------------+----------------+-------------
+ Start parse | prsd_start |
+ Get next token | prsd_nexttoken |
+ End parse | prsd_end |
+ Get headline | prsd_headline |
+ Get token types | prsd_lextype |
+
+ Token types for parser "pg_catalog.default"
+ Token name | Description
+-----------------+------------------------------------------
+ asciihword | Hyphenated word, all ASCII
+ asciiword | Word, all ASCII
+ blank | Space symbols
+ email | Email address
+ entity | XML entity
+ file | File or path name
+ float | Decimal notation
+ host | Host
+ hword | Hyphenated word, all letters
+ hword_asciipart | Hyphenated word part, all ASCII
+ hword_numpart | Hyphenated word part, letters and digits
+ hword_part | Hyphenated word part, all letters
+ int | Signed integer
+ numhword | Hyphenated word, letters and digits
+ numword | Word, letters and digits
+ protocol | Protocol head
+ sfloat | Scientific notation
+ tag | XML tag
+ uint | Unsigned integer
+ url | URL
+ url_path | URL path
+ version | Version number
+ word | Word, all letters
+(23 rows)
+</pre><p>
+ </p></dd><dt><span class="term"><code class="literal">\dFt[<span class="optional">+</span>] [<span class="optional">PATTERN</span>]</code></span></dt><dd><p>
+ List text search templates (add <code class="literal">+</code> for more detail).
+</p><pre class="screen">
+=&gt; \dFt
+ List of text search templates
+ Schema | Name | Description
+------------+-----------+-----------------------------------------------------------
+ pg_catalog | ispell | ispell dictionary
+ pg_catalog | simple | simple dictionary: just lower case and check for stopword
+ pg_catalog | snowball | snowball stemmer
+ pg_catalog | synonym | synonym dictionary: replace word by its synonym
+ pg_catalog | thesaurus | thesaurus dictionary: phrase by phrase substitution
+</pre><p>
+ </p></dd></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-limitations.html" title="12.11. Limitations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.9. Preferred Index Types for Text Search </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.11. Limitations</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch-tables.html b/doc/src/sgml/html/textsearch-tables.html
new file mode 100644
index 0000000..3e976fd
--- /dev/null
+++ b/doc/src/sgml/html/textsearch-tables.html
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>12.2. Tables and Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="textsearch-intro.html" title="12.1. Introduction" /><link rel="next" href="textsearch-controls.html" title="12.3. Controlling Text Search" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">12.2. Tables and Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="textsearch-intro.html" title="12.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><th width="60%" align="center">Chapter 12. Full Text Search</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-controls.html" title="12.3. Controlling Text Search">Next</a></td></tr></table><hr /></div><div class="sect1" id="TEXTSEARCH-TABLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">12.2. Tables and Indexes</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="textsearch-tables.html#TEXTSEARCH-TABLES-SEARCH">12.2.1. Searching a Table</a></span></dt><dt><span class="sect2"><a href="textsearch-tables.html#TEXTSEARCH-TABLES-INDEX">12.2.2. Creating Indexes</a></span></dt></dl></div><p>
+ The examples in the previous section illustrated full text matching using
+ simple constant strings. This section shows how to search table data,
+ optionally using indexes.
+ </p><div class="sect2" id="TEXTSEARCH-TABLES-SEARCH"><div class="titlepage"><div><div><h3 class="title">12.2.1. Searching a Table</h3></div></div></div><p>
+ It is possible to do a full text search without an index. A simple query
+ to print the <code class="structname">title</code> of each row that contains the word
+ <code class="literal">friend</code> in its <code class="structfield">body</code> field is:
+
+</p><pre class="programlisting">
+SELECT title
+FROM pgweb
+WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend');
+</pre><p>
+
+ This will also find related words such as <code class="literal">friends</code>
+ and <code class="literal">friendly</code>, since all these are reduced to the same
+ normalized lexeme.
+ </p><p>
+ The query above specifies that the <code class="literal">english</code> configuration
+ is to be used to parse and normalize the strings. Alternatively we
+ could omit the configuration parameters:
+
+</p><pre class="programlisting">
+SELECT title
+FROM pgweb
+WHERE to_tsvector(body) @@ to_tsquery('friend');
+</pre><p>
+
+ This query will use the configuration set by <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a>.
+ </p><p>
+ A more complex example is to
+ select the ten most recent documents that contain <code class="literal">create</code> and
+ <code class="literal">table</code> in the <code class="structname">title</code> or <code class="structname">body</code>:
+
+</p><pre class="programlisting">
+SELECT title
+FROM pgweb
+WHERE to_tsvector(title || ' ' || body) @@ to_tsquery('create &amp; table')
+ORDER BY last_mod_date DESC
+LIMIT 10;
+</pre><p>
+
+ For clarity we omitted the <code class="function">coalesce</code> function calls
+ which would be needed to find rows that contain <code class="literal">NULL</code>
+ in one of the two fields.
+ </p><p>
+ Although these queries will work without an index, most applications
+ will find this approach too slow, except perhaps for occasional ad-hoc
+ searches. Practical use of text searching usually requires creating
+ an index.
+ </p></div><div class="sect2" id="TEXTSEARCH-TABLES-INDEX"><div class="titlepage"><div><div><h3 class="title">12.2.2. Creating Indexes</h3></div></div></div><p>
+ We can create a <acronym class="acronym">GIN</acronym> index (<a class="xref" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Section 12.9</a>) to speed up text searches:
+
+</p><pre class="programlisting">
+CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', body));
+</pre><p>
+
+ Notice that the 2-argument version of <code class="function">to_tsvector</code> is
+ used. Only text search functions that specify a configuration name can
+ be used in expression indexes (<a class="xref" href="indexes-expressional.html" title="11.7. Indexes on Expressions">Section 11.7</a>).
+ This is because the index contents must be unaffected by <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TEXT-SEARCH-CONFIG">default_text_search_config</a>. If they were affected, the
+ index contents might be inconsistent because different entries could
+ contain <code class="type">tsvector</code>s that were created with different text search
+ configurations, and there would be no way to guess which was which. It
+ would be impossible to dump and restore such an index correctly.
+ </p><p>
+ Because the two-argument version of <code class="function">to_tsvector</code> was
+ used in the index above, only a query reference that uses the 2-argument
+ version of <code class="function">to_tsvector</code> with the same configuration
+ name will use that index. That is, <code class="literal">WHERE
+ to_tsvector('english', body) @@ 'a &amp; b'</code> can use the index,
+ but <code class="literal">WHERE to_tsvector(body) @@ 'a &amp; b'</code> cannot.
+ This ensures that an index will be used only with the same configuration
+ used to create the index entries.
+ </p><p>
+ It is possible to set up more complex expression indexes wherein the
+ configuration name is specified by another column, e.g.:
+
+</p><pre class="programlisting">
+CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector(config_name, body));
+</pre><p>
+
+ where <code class="literal">config_name</code> is a column in the <code class="literal">pgweb</code>
+ table. This allows mixed configurations in the same index while
+ recording which configuration was used for each index entry. This
+ would be useful, for example, if the document collection contained
+ documents in different languages. Again,
+ queries that are meant to use the index must be phrased to match, e.g.,
+ <code class="literal">WHERE to_tsvector(config_name, body) @@ 'a &amp; b'</code>.
+ </p><p>
+ Indexes can even concatenate columns:
+
+</p><pre class="programlisting">
+CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));
+</pre><p>
+ </p><p>
+ Another approach is to create a separate <code class="type">tsvector</code> column
+ to hold the output of <code class="function">to_tsvector</code>. To keep this
+ column automatically up to date with its source data, use a stored
+ generated column. This example is a
+ concatenation of <code class="literal">title</code> and <code class="literal">body</code>,
+ using <code class="function">coalesce</code> to ensure that one field will still be
+ indexed when the other is <code class="literal">NULL</code>:
+
+</p><pre class="programlisting">
+ALTER TABLE pgweb
+ ADD COLUMN textsearchable_index_col tsvector
+ GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;
+</pre><p>
+
+ Then we create a <acronym class="acronym">GIN</acronym> index to speed up the search:
+
+</p><pre class="programlisting">
+CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col);
+</pre><p>
+
+ Now we are ready to perform a fast full text search:
+
+</p><pre class="programlisting">
+SELECT title
+FROM pgweb
+WHERE textsearchable_index_col @@ to_tsquery('create &amp; table')
+ORDER BY last_mod_date DESC
+LIMIT 10;
+</pre><p>
+ </p><p>
+ One advantage of the separate-column approach over an expression index
+ is that it is not necessary to explicitly specify the text search
+ configuration in queries in order to make use of the index. As shown
+ in the example above, the query can depend on
+ <code class="varname">default_text_search_config</code>. Another advantage is that
+ searches will be faster, since it will not be necessary to redo the
+ <code class="function">to_tsvector</code> calls to verify index matches. (This is more
+ important when using a GiST index than a GIN index; see <a class="xref" href="textsearch-indexes.html" title="12.9. Preferred Index Types for Text Search">Section 12.9</a>.) The expression-index approach is
+ simpler to set up, however, and it requires less disk space since the
+ <code class="type">tsvector</code> representation is not stored explicitly.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="textsearch-intro.html" title="12.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="textsearch.html" title="Chapter 12. Full Text Search">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-controls.html" title="12.3. Controlling Text Search">Next</a></td></tr><tr><td width="40%" align="left" valign="top">12.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.3. Controlling Text Search</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/textsearch.html b/doc/src/sgml/html/textsearch.html
new file mode 100644
index 0000000..97a8fa8
--- /dev/null
+++ b/doc/src/sgml/html/textsearch.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 12. Full Text Search</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="indexes-examine.html" title="11.12. Examining Index Usage" /><link rel="next" href="textsearch-intro.html" title="12.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 12. Full Text Search</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="indexes-examine.html" title="11.12. Examining Index Usage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="textsearch-intro.html" title="12.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="TEXTSEARCH"><div class="titlepage"><div><div><h2 class="title">Chapter 12. Full Text Search</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="textsearch-intro.html">12.1. Introduction</a></span></dt><dd><dl><dt><span class="sect2"><a href="textsearch-intro.html#TEXTSEARCH-DOCUMENT">12.1.1. What Is a Document?</a></span></dt><dt><span class="sect2"><a href="textsearch-intro.html#TEXTSEARCH-MATCHING">12.1.2. Basic Text Matching</a></span></dt><dt><span class="sect2"><a href="textsearch-intro.html#TEXTSEARCH-INTRO-CONFIGURATIONS">12.1.3. Configurations</a></span></dt></dl></dd><dt><span class="sect1"><a href="textsearch-tables.html">12.2. Tables and Indexes</a></span></dt><dd><dl><dt><span class="sect2"><a href="textsearch-tables.html#TEXTSEARCH-TABLES-SEARCH">12.2.1. Searching a Table</a></span></dt><dt><span class="sect2"><a href="textsearch-tables.html#TEXTSEARCH-TABLES-INDEX">12.2.2. Creating Indexes</a></span></dt></dl></dd><dt><span class="sect1"><a href="textsearch-controls.html">12.3. Controlling Text Search</a></span></dt><dd><dl><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-PARSING-DOCUMENTS">12.3.1. Parsing Documents</a></span></dt><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-PARSING-QUERIES">12.3.2. Parsing Queries</a></span></dt><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-RANKING">12.3.3. Ranking Search Results</a></span></dt><dt><span class="sect2"><a href="textsearch-controls.html#TEXTSEARCH-HEADLINE">12.3.4. Highlighting Results</a></span></dt></dl></dd><dt><span class="sect1"><a href="textsearch-features.html">12.4. Additional Features</a></span></dt><dd><dl><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSVECTOR">12.4.1. Manipulating Documents</a></span></dt><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-MANIPULATE-TSQUERY">12.4.2. Manipulating Queries</a></span></dt><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS">12.4.3. Triggers for Automatic Updates</a></span></dt><dt><span class="sect2"><a href="textsearch-features.html#TEXTSEARCH-STATISTICS">12.4.4. Gathering Document Statistics</a></span></dt></dl></dd><dt><span class="sect1"><a href="textsearch-parsers.html">12.5. Parsers</a></span></dt><dt><span class="sect1"><a href="textsearch-dictionaries.html">12.6. Dictionaries</a></span></dt><dd><dl><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS">12.6.1. Stop Words</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY">12.6.2. Simple Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SYNONYM-DICTIONARY">12.6.3. Synonym Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-THESAURUS">12.6.4. Thesaurus Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-ISPELL-DICTIONARY">12.6.5. <span class="application">Ispell</span> Dictionary</a></span></dt><dt><span class="sect2"><a href="textsearch-dictionaries.html#TEXTSEARCH-SNOWBALL-DICTIONARY">12.6.6. <span class="application">Snowball</span> Dictionary</a></span></dt></dl></dd><dt><span class="sect1"><a href="textsearch-configuration.html">12.7. Configuration Example</a></span></dt><dt><span class="sect1"><a href="textsearch-debugging.html">12.8. Testing and Debugging Text Search</a></span></dt><dd><dl><dt><span class="sect2"><a href="textsearch-debugging.html#TEXTSEARCH-CONFIGURATION-TESTING">12.8.1. Configuration Testing</a></span></dt><dt><span class="sect2"><a href="textsearch-debugging.html#TEXTSEARCH-PARSER-TESTING">12.8.2. Parser Testing</a></span></dt><dt><span class="sect2"><a href="textsearch-debugging.html#TEXTSEARCH-DICTIONARY-TESTING">12.8.3. Dictionary Testing</a></span></dt></dl></dd><dt><span class="sect1"><a href="textsearch-indexes.html">12.9. Preferred Index Types for Text Search</a></span></dt><dt><span class="sect1"><a href="textsearch-psql.html">12.10. <span class="application">psql</span> Support</a></span></dt><dt><span class="sect1"><a href="textsearch-limitations.html">12.11. Limitations</a></span></dt></dl></div><a id="id-1.5.11.2" class="indexterm"></a><a id="id-1.5.11.3" class="indexterm"></a></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="indexes-examine.html" title="11.12. Examining Index Usage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="textsearch-intro.html" title="12.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">11.12. Examining Index Usage </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 12.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/transaction-iso.html b/doc/src/sgml/html/transaction-iso.html
new file mode 100644
index 0000000..6ab1a2a
--- /dev/null
+++ b/doc/src/sgml/html/transaction-iso.html
@@ -0,0 +1,540 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>13.2. Transaction Isolation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="mvcc-intro.html" title="13.1. Introduction" /><link rel="next" href="explicit-locking.html" title="13.3. Explicit Locking" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">13.2. Transaction Isolation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="mvcc-intro.html" title="13.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><th width="60%" align="center">Chapter 13. Concurrency Control</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="explicit-locking.html" title="13.3. Explicit Locking">Next</a></td></tr></table><hr /></div><div class="sect1" id="TRANSACTION-ISO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">13.2. Transaction Isolation</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="transaction-iso.html#XACT-READ-COMMITTED">13.2.1. Read Committed Isolation Level</a></span></dt><dt><span class="sect2"><a href="transaction-iso.html#XACT-REPEATABLE-READ">13.2.2. Repeatable Read Isolation Level</a></span></dt><dt><span class="sect2"><a href="transaction-iso.html#XACT-SERIALIZABLE">13.2.3. Serializable Isolation Level</a></span></dt></dl></div><a id="id-1.5.12.5.2" class="indexterm"></a><p>
+ The <acronym class="acronym">SQL</acronym> standard defines four levels of
+ transaction isolation. The most strict is Serializable,
+ which is defined by the standard in a paragraph which says that any
+ concurrent execution of a set of Serializable transactions is guaranteed
+ to produce the same effect as running them one at a time in some order.
+ The other three levels are defined in terms of phenomena, resulting from
+ interaction between concurrent transactions, which must not occur at
+ each level. The standard notes that due to the definition of
+ Serializable, none of these phenomena are possible at that level. (This
+ is hardly surprising -- if the effect of the transactions must be
+ consistent with having been run one at a time, how could you see any
+ phenomena caused by interactions?)
+ </p><p>
+ The phenomena which are prohibited at various levels are:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ dirty read
+ <a id="id-1.5.12.5.4.1.1.1.1" class="indexterm"></a>
+ </span></dt><dd><p>
+ A transaction reads data written by a concurrent uncommitted transaction.
+ </p></dd><dt><span class="term">
+ nonrepeatable read
+ <a id="id-1.5.12.5.4.1.2.1.1" class="indexterm"></a>
+ </span></dt><dd><p>
+ A transaction re-reads data it has previously read and finds that data
+ has been modified by another transaction (that committed since the
+ initial read).
+ </p></dd><dt><span class="term">
+ phantom read
+ <a id="id-1.5.12.5.4.1.3.1.1" class="indexterm"></a>
+ </span></dt><dd><p>
+ A transaction re-executes a query returning a set of rows that satisfy a
+ search condition and finds that the set of rows satisfying the condition
+ has changed due to another recently-committed transaction.
+ </p></dd><dt><span class="term">
+ serialization anomaly
+ <a id="id-1.5.12.5.4.1.4.1.1" class="indexterm"></a>
+ </span></dt><dd><p>
+ The result of successfully committing a group of transactions
+ is inconsistent with all possible orderings of running those
+ transactions one at a time.
+ </p></dd></dl></div><p>
+ </p><p>
+ <a id="id-1.5.12.5.5.1" class="indexterm"></a>
+ The SQL standard and PostgreSQL-implemented transaction isolation levels
+ are described in <a class="xref" href="transaction-iso.html#MVCC-ISOLEVEL-TABLE" title="Table 13.1. Transaction Isolation Levels">Table 13.1</a>.
+ </p><div class="table" id="MVCC-ISOLEVEL-TABLE"><p class="title"><strong>Table 13.1. Transaction Isolation Levels</strong></p><div class="table-contents"><table class="table" summary="Transaction Isolation Levels" border="1"><colgroup><col /><col /><col /><col /><col /></colgroup><thead><tr><th>
+ Isolation Level
+ </th><th>
+ Dirty Read
+ </th><th>
+ Nonrepeatable Read
+ </th><th>
+ Phantom Read
+ </th><th>
+ Serialization Anomaly
+ </th></tr></thead><tbody><tr><td>
+ Read uncommitted
+ </td><td>
+ Allowed, but not in PG
+ </td><td>
+ Possible
+ </td><td>
+ Possible
+ </td><td>
+ Possible
+ </td></tr><tr><td>
+ Read committed
+ </td><td>
+ Not possible
+ </td><td>
+ Possible
+ </td><td>
+ Possible
+ </td><td>
+ Possible
+ </td></tr><tr><td>
+ Repeatable read
+ </td><td>
+ Not possible
+ </td><td>
+ Not possible
+ </td><td>
+ Allowed, but not in PG
+ </td><td>
+ Possible
+ </td></tr><tr><td>
+ Serializable
+ </td><td>
+ Not possible
+ </td><td>
+ Not possible
+ </td><td>
+ Not possible
+ </td><td>
+ Not possible
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ In <span class="productname">PostgreSQL</span>, you can request any of
+ the four standard transaction isolation levels, but internally only
+ three distinct isolation levels are implemented, i.e., PostgreSQL's
+ Read Uncommitted mode behaves like Read Committed. This is because
+ it is the only sensible way to map the standard isolation levels to
+ PostgreSQL's multiversion concurrency control architecture.
+ </p><p>
+ The table also shows that PostgreSQL's Repeatable Read implementation
+ does not allow phantom reads. This is acceptable under the SQL
+ standard because the standard specifies which anomalies must
+ <span class="emphasis"><em>not</em></span> occur at certain isolation levels; higher
+ guarantees are acceptable.
+ The behavior of the available isolation levels is detailed in the
+ following subsections.
+ </p><p>
+ To set the transaction isolation level of a transaction, use the
+ command <a class="xref" href="sql-set-transaction.html" title="SET TRANSACTION"><span class="refentrytitle">SET TRANSACTION</span></a>.
+ </p><div class="important"><h3 class="title">Important</h3><p>
+ Some <span class="productname">PostgreSQL</span> data types and functions have
+ special rules regarding transactional behavior. In particular, changes
+ made to a sequence (and therefore the counter of a
+ column declared using <code class="type">serial</code>) are immediately visible
+ to all other transactions and are not rolled back if the transaction
+ that made the changes aborts. See <a class="xref" href="functions-sequence.html" title="9.17. Sequence Manipulation Functions">Section 9.17</a>
+ and <a class="xref" href="datatype-numeric.html#DATATYPE-SERIAL" title="8.1.4. Serial Types">Section 8.1.4</a>.
+ </p></div><div class="sect2" id="XACT-READ-COMMITTED"><div class="titlepage"><div><div><h3 class="title">13.2.1. Read Committed Isolation Level</h3></div></div></div><a id="id-1.5.12.5.11.2" class="indexterm"></a><a id="id-1.5.12.5.11.3" class="indexterm"></a><p>
+ <em class="firstterm">Read Committed</em> is the default isolation
+ level in <span class="productname">PostgreSQL</span>. When a transaction
+ uses this isolation level, a <code class="command">SELECT</code> query
+ (without a <code class="literal">FOR UPDATE/SHARE</code> clause) sees only data
+ committed before the query began; it never sees either uncommitted
+ data or changes committed during query execution by concurrent
+ transactions. In effect, a <code class="command">SELECT</code> query sees
+ a snapshot of the database as of the instant the query begins to
+ run. However, <code class="command">SELECT</code> does see the effects
+ of previous updates executed within its own transaction, even
+ though they are not yet committed. Also note that two successive
+ <code class="command">SELECT</code> commands can see different data, even
+ though they are within a single transaction, if other transactions
+ commit changes after the first <code class="command">SELECT</code> starts and
+ before the second <code class="command">SELECT</code> starts.
+ </p><p>
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, <code class="command">SELECT
+ FOR UPDATE</code>, and <code class="command">SELECT FOR SHARE</code> commands
+ behave the same as <code class="command">SELECT</code>
+ in terms of searching for target rows: they will only find target rows
+ that were committed as of the command start time. However, such a target
+ row might have already been updated (or deleted or locked) by
+ another concurrent transaction by the time it is found. In this case, the
+ would-be updater will wait for the first updating transaction to commit or
+ roll back (if it is still in progress). If the first updater rolls back,
+ then its effects are negated and the second updater can proceed with
+ updating the originally found row. If the first updater commits, the
+ second updater will ignore the row if the first updater deleted it,
+ otherwise it will attempt to apply its operation to the updated version of
+ the row. The search condition of the command (the <code class="literal">WHERE</code> clause) is
+ re-evaluated to see if the updated version of the row still matches the
+ search condition. If so, the second updater proceeds with its operation
+ using the updated version of the row. In the case of
+ <code class="command">SELECT FOR UPDATE</code> and <code class="command">SELECT FOR
+ SHARE</code>, this means it is the updated version of the row that is
+ locked and returned to the client.
+ </p><p>
+ <code class="command">INSERT</code> with an <code class="literal">ON CONFLICT DO UPDATE</code> clause
+ behaves similarly. In Read Committed mode, each row proposed for insertion
+ will either insert or update. Unless there are unrelated errors, one of
+ those two outcomes is guaranteed. If a conflict originates in another
+ transaction whose effects are not yet visible to the <code class="command">INSERT</code>,
+ the <code class="command">UPDATE</code> clause will affect that row,
+ even though possibly <span class="emphasis"><em>no</em></span> version of that row is
+ conventionally visible to the command.
+ </p><p>
+ <code class="command">INSERT</code> with an <code class="literal">ON CONFLICT DO
+ NOTHING</code> clause may have insertion not proceed for a row due to
+ the outcome of another transaction whose effects are not visible
+ to the <code class="command">INSERT</code> snapshot. Again, this is only
+ the case in Read Committed mode.
+ </p><p>
+ <code class="command">MERGE</code> allows the user to specify various
+ combinations of <code class="command">INSERT</code>, <code class="command">UPDATE</code>
+ and <code class="command">DELETE</code> subcommands. A <code class="command">MERGE</code>
+ command with both <code class="command">INSERT</code> and <code class="command">UPDATE</code>
+ subcommands looks similar to <code class="command">INSERT</code> with an
+ <code class="literal">ON CONFLICT DO UPDATE</code> clause but does not
+ guarantee that either <code class="command">INSERT</code> or
+ <code class="command">UPDATE</code> will occur.
+ If <code class="command">MERGE</code> attempts an <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> and the row is concurrently updated but
+ the join condition still passes for the current target and the
+ current source tuple, then <code class="command">MERGE</code> will behave
+ the same as the <code class="command">UPDATE</code> or
+ <code class="command">DELETE</code> commands and perform its action on the
+ updated version of the row. However, because <code class="command">MERGE</code>
+ can specify several actions and they can be conditional, the
+ conditions for each action are re-evaluated on the updated version of
+ the row, starting from the first action, even if the action that had
+ originally matched appears later in the list of actions.
+ On the other hand, if the row is concurrently updated or deleted so
+ that the join condition fails, then <code class="command">MERGE</code> will
+ evaluate the condition's <code class="literal">NOT MATCHED</code> actions next,
+ and execute the first one that succeeds.
+ If <code class="command">MERGE</code> attempts an <code class="command">INSERT</code>
+ and a unique index is present and a duplicate row is concurrently
+ inserted, then a uniqueness violation error is raised;
+ <code class="command">MERGE</code> does not attempt to avoid such
+ errors by restarting evaluation of <code class="literal">MATCHED</code>
+ conditions.
+ </p><p>
+ Because of the above rules, it is possible for an updating command to see
+ an inconsistent snapshot: it can see the effects of concurrent updating
+ commands on the same rows it is trying to update, but it
+ does not see effects of those commands on other rows in the database.
+ This behavior makes Read Committed mode unsuitable for commands that
+ involve complex search conditions; however, it is just right for simpler
+ cases. For example, consider updating bank balances with transactions
+ like:
+
+</p><pre class="screen">
+BEGIN;
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 12345;
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534;
+COMMIT;
+</pre><p>
+
+ If two such transactions concurrently try to change the balance of account
+ 12345, we clearly want the second transaction to start with the updated
+ version of the account's row. Because each command is affecting only a
+ predetermined row, letting it see the updated version of the row does
+ not create any troublesome inconsistency.
+ </p><p>
+ More complex usage can produce undesirable results in Read Committed
+ mode. For example, consider a <code class="command">DELETE</code> command
+ operating on data that is being both added and removed from its
+ restriction criteria by another command, e.g., assume
+ <code class="literal">website</code> is a two-row table with
+ <code class="literal">website.hits</code> equaling <code class="literal">9</code> and
+ <code class="literal">10</code>:
+
+</p><pre class="screen">
+BEGIN;
+UPDATE website SET hits = hits + 1;
+-- run from another session: DELETE FROM website WHERE hits = 10;
+COMMIT;
+</pre><p>
+
+ The <code class="command">DELETE</code> will have no effect even though
+ there is a <code class="literal">website.hits = 10</code> row before and
+ after the <code class="command">UPDATE</code>. This occurs because the
+ pre-update row value <code class="literal">9</code> is skipped, and when the
+ <code class="command">UPDATE</code> completes and <code class="command">DELETE</code>
+ obtains a lock, the new row value is no longer <code class="literal">10</code> but
+ <code class="literal">11</code>, which no longer matches the criteria.
+ </p><p>
+ Because Read Committed mode starts each command with a new snapshot
+ that includes all transactions committed up to that instant,
+ subsequent commands in the same transaction will see the effects
+ of the committed concurrent transaction in any case. The point
+ at issue above is whether or not a <span class="emphasis"><em>single</em></span> command
+ sees an absolutely consistent view of the database.
+ </p><p>
+ The partial transaction isolation provided by Read Committed mode
+ is adequate for many applications, and this mode is fast and simple
+ to use; however, it is not sufficient for all cases. Applications
+ that do complex queries and updates might require a more rigorously
+ consistent view of the database than Read Committed mode provides.
+ </p></div><div class="sect2" id="XACT-REPEATABLE-READ"><div class="titlepage"><div><div><h3 class="title">13.2.2. Repeatable Read Isolation Level</h3></div></div></div><a id="id-1.5.12.5.12.2" class="indexterm"></a><a id="id-1.5.12.5.12.3" class="indexterm"></a><p>
+ The <em class="firstterm">Repeatable Read</em> isolation level only sees
+ data committed before the transaction began; it never sees either
+ uncommitted data or changes committed during transaction execution
+ by concurrent transactions. (However, the query does see the
+ effects of previous updates executed within its own transaction,
+ even though they are not yet committed.) This is a stronger
+ guarantee than is required by the <acronym class="acronym">SQL</acronym> standard
+ for this isolation level, and prevents all of the phenomena described
+ in <a class="xref" href="transaction-iso.html#MVCC-ISOLEVEL-TABLE" title="Table 13.1. Transaction Isolation Levels">Table 13.1</a> except for serialization
+ anomalies. As mentioned above, this is
+ specifically allowed by the standard, which only describes the
+ <span class="emphasis"><em>minimum</em></span> protections each isolation level must
+ provide.
+ </p><p>
+ This level is different from Read Committed in that a query in a
+ repeatable read transaction sees a snapshot as of the start of the
+ first non-transaction-control statement in the
+ <span class="emphasis"><em>transaction</em></span>, not as of the start
+ of the current statement within the transaction. Thus, successive
+ <code class="command">SELECT</code> commands within a <span class="emphasis"><em>single</em></span>
+ transaction see the same data, i.e., they do not see changes made by
+ other transactions that committed after their own transaction started.
+ </p><p>
+ Applications using this level must be prepared to retry transactions
+ due to serialization failures.
+ </p><p>
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>,
+ <code class="command">MERGE</code>, <code class="command">SELECT FOR UPDATE</code>,
+ and <code class="command">SELECT FOR SHARE</code> commands
+ behave the same as <code class="command">SELECT</code>
+ in terms of searching for target rows: they will only find target rows
+ that were committed as of the transaction start time. However, such a
+ target row might have already been updated (or deleted or locked) by
+ another concurrent transaction by the time it is found. In this case, the
+ repeatable read transaction will wait for the first updating transaction to commit or
+ roll back (if it is still in progress). If the first updater rolls back,
+ then its effects are negated and the repeatable read transaction can proceed
+ with updating the originally found row. But if the first updater commits
+ (and actually updated or deleted the row, not just locked it)
+ then the repeatable read transaction will be rolled back with the message
+
+</p><pre class="screen">
+ERROR: could not serialize access due to concurrent update
+</pre><p>
+
+ because a repeatable read transaction cannot modify or lock rows changed by
+ other transactions after the repeatable read transaction began.
+ </p><p>
+ When an application receives this error message, it should abort
+ the current transaction and retry the whole transaction from
+ the beginning. The second time through, the transaction will see the
+ previously-committed change as part of its initial view of the database,
+ so there is no logical conflict in using the new version of the row
+ as the starting point for the new transaction's update.
+ </p><p>
+ Note that only updating transactions might need to be retried; read-only
+ transactions will never have serialization conflicts.
+ </p><p>
+ The Repeatable Read mode provides a rigorous guarantee that each
+ transaction sees a completely stable view of the database. However,
+ this view will not necessarily always be consistent with some serial
+ (one at a time) execution of concurrent transactions of the same level.
+ For example, even a read-only transaction at this level may see a
+ control record updated to show that a batch has been completed but
+ <span class="emphasis"><em>not</em></span> see one of the detail records which is logically
+ part of the batch because it read an earlier revision of the control
+ record. Attempts to enforce business rules by transactions running at
+ this isolation level are not likely to work correctly without careful use
+ of explicit locks to block conflicting transactions.
+ </p><p>
+ The Repeatable Read isolation level is implemented using a technique
+ known in academic database literature and in some other database products
+ as <em class="firstterm">Snapshot Isolation</em>. Differences in behavior
+ and performance may be observed when compared with systems that use a
+ traditional locking technique that reduces concurrency. Some other
+ systems may even offer Repeatable Read and Snapshot Isolation as distinct
+ isolation levels with different behavior. The permitted phenomena that
+ distinguish the two techniques were not formalized by database researchers
+ until after the SQL standard was developed, and are outside the scope of
+ this manual. For a full treatment, please see
+ <a class="xref" href="biblio.html#BERENSON95">[berenson95]</a>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Prior to <span class="productname">PostgreSQL</span> version 9.1, a request
+ for the Serializable transaction isolation level provided exactly the
+ same behavior described here. To retain the legacy Serializable
+ behavior, Repeatable Read should now be requested.
+ </p></div></div><div class="sect2" id="XACT-SERIALIZABLE"><div class="titlepage"><div><div><h3 class="title">13.2.3. Serializable Isolation Level</h3></div></div></div><a id="id-1.5.12.5.13.2" class="indexterm"></a><a id="id-1.5.12.5.13.3" class="indexterm"></a><a id="id-1.5.12.5.13.4" class="indexterm"></a><a id="id-1.5.12.5.13.5" class="indexterm"></a><p>
+ The <em class="firstterm">Serializable</em> isolation level provides
+ the strictest transaction isolation. This level emulates serial
+ transaction execution for all committed transactions;
+ as if transactions had been executed one after another, serially,
+ rather than concurrently. However, like the Repeatable Read level,
+ applications using this level must
+ be prepared to retry transactions due to serialization failures.
+ In fact, this isolation level works exactly the same as Repeatable
+ Read except that it also monitors for conditions which could make
+ execution of a concurrent set of serializable transactions behave
+ in a manner inconsistent with all possible serial (one at a time)
+ executions of those transactions. This monitoring does not
+ introduce any blocking beyond that present in repeatable read, but
+ there is some overhead to the monitoring, and detection of the
+ conditions which could cause a
+ <em class="firstterm">serialization anomaly</em> will trigger a
+ <em class="firstterm">serialization failure</em>.
+ </p><p>
+ As an example,
+ consider a table <code class="structname">mytab</code>, initially containing:
+</p><pre class="screen">
+ class | value
+-------+-------
+ 1 | 10
+ 1 | 20
+ 2 | 100
+ 2 | 200
+</pre><p>
+ Suppose that serializable transaction A computes:
+</p><pre class="screen">
+SELECT SUM(value) FROM mytab WHERE class = 1;
+</pre><p>
+ and then inserts the result (30) as the <code class="structfield">value</code> in a
+ new row with <code class="structfield">class</code><code class="literal"> = 2</code>. Concurrently, serializable
+ transaction B computes:
+</p><pre class="screen">
+SELECT SUM(value) FROM mytab WHERE class = 2;
+</pre><p>
+ and obtains the result 300, which it inserts in a new row with
+ <code class="structfield">class</code><code class="literal"> = 1</code>. Then both transactions try to commit.
+ If either transaction were running at the Repeatable Read isolation level,
+ both would be allowed to commit; but since there is no serial order of execution
+ consistent with the result, using Serializable transactions will allow one
+ transaction to commit and will roll the other back with this message:
+
+</p><pre class="screen">
+ERROR: could not serialize access due to read/write dependencies among transactions
+</pre><p>
+
+ This is because if A had
+ executed before B, B would have computed the sum 330, not 300, and
+ similarly the other order would have resulted in a different sum
+ computed by A.
+ </p><p>
+ When relying on Serializable transactions to prevent anomalies, it is
+ important that any data read from a permanent user table not be
+ considered valid until the transaction which read it has successfully
+ committed. This is true even for read-only transactions, except that
+ data read within a <em class="firstterm">deferrable</em> read-only
+ transaction is known to be valid as soon as it is read, because such a
+ transaction waits until it can acquire a snapshot guaranteed to be free
+ from such problems before starting to read any data. In all other cases
+ applications must not depend on results read during a transaction that
+ later aborted; instead, they should retry the transaction until it
+ succeeds.
+ </p><p>
+ To guarantee true serializability <span class="productname">PostgreSQL</span>
+ uses <em class="firstterm">predicate locking</em>, which means that it keeps locks
+ which allow it to determine when a write would have had an impact on
+ the result of a previous read from a concurrent transaction, had it run
+ first. In <span class="productname">PostgreSQL</span> these locks do not
+ cause any blocking and therefore can <span class="emphasis"><em>not</em></span> play any part in
+ causing a deadlock. They are used to identify and flag dependencies
+ among concurrent Serializable transactions which in certain combinations
+ can lead to serialization anomalies. In contrast, a Read Committed or
+ Repeatable Read transaction which wants to ensure data consistency may
+ need to take out a lock on an entire table, which could block other
+ users attempting to use that table, or it may use <code class="literal">SELECT FOR
+ UPDATE</code> or <code class="literal">SELECT FOR SHARE</code> which not only
+ can block other transactions but cause disk access.
+ </p><p>
+ Predicate locks in <span class="productname">PostgreSQL</span>, like in most
+ other database systems, are based on data actually accessed by a
+ transaction. These will show up in the
+ <a class="link" href="view-pg-locks.html" title="54.12. pg_locks"><code class="structname">pg_locks</code></a>
+ system view with a <code class="literal">mode</code> of <code class="literal">SIReadLock</code>. The
+ particular locks
+ acquired during execution of a query will depend on the plan used by
+ the query, and multiple finer-grained locks (e.g., tuple locks) may be
+ combined into fewer coarser-grained locks (e.g., page locks) during the
+ course of the transaction to prevent exhaustion of the memory used to
+ track the locks. A <code class="literal">READ ONLY</code> transaction may be able to
+ release its SIRead locks before completion, if it detects that no
+ conflicts can still occur which could lead to a serialization anomaly.
+ In fact, <code class="literal">READ ONLY</code> transactions will often be able to
+ establish that fact at startup and avoid taking any predicate locks.
+ If you explicitly request a <code class="literal">SERIALIZABLE READ ONLY DEFERRABLE</code>
+ transaction, it will block until it can establish this fact. (This is
+ the <span class="emphasis"><em>only</em></span> case where Serializable transactions block but
+ Repeatable Read transactions don't.) On the other hand, SIRead locks
+ often need to be kept past transaction commit, until overlapping read
+ write transactions complete.
+ </p><p>
+ Consistent use of Serializable transactions can simplify development.
+ The guarantee that any set of successfully committed concurrent
+ Serializable transactions will have the same effect as if they were run
+ one at a time means that if you can demonstrate that a single transaction,
+ as written, will do the right thing when run by itself, you can have
+ confidence that it will do the right thing in any mix of Serializable
+ transactions, even without any information about what those other
+ transactions might do, or it will not successfully commit. It is
+ important that an environment which uses this technique have a
+ generalized way of handling serialization failures (which always return
+ with an SQLSTATE value of '40001'), because it will be very hard to
+ predict exactly which transactions might contribute to the read/write
+ dependencies and need to be rolled back to prevent serialization
+ anomalies. The monitoring of read/write dependencies has a cost, as does
+ the restart of transactions which are terminated with a serialization
+ failure, but balanced against the cost and blocking involved in use of
+ explicit locks and <code class="literal">SELECT FOR UPDATE</code> or <code class="literal">SELECT FOR
+ SHARE</code>, Serializable transactions are the best performance choice
+ for some environments.
+ </p><p>
+ While <span class="productname">PostgreSQL</span>'s Serializable transaction isolation
+ level only allows concurrent transactions to commit if it can prove there
+ is a serial order of execution that would produce the same effect, it
+ doesn't always prevent errors from being raised that would not occur in
+ true serial execution. In particular, it is possible to see unique
+ constraint violations caused by conflicts with overlapping Serializable
+ transactions even after explicitly checking that the key isn't present
+ before attempting to insert it. This can be avoided by making sure
+ that <span class="emphasis"><em>all</em></span> Serializable transactions that insert potentially
+ conflicting keys explicitly check if they can do so first. For example,
+ imagine an application that asks the user for a new key and then checks
+ that it doesn't exist already by trying to select it first, or generates
+ a new key by selecting the maximum existing key and adding one. If some
+ Serializable transactions insert new keys directly without following this
+ protocol, unique constraints violations might be reported even in cases
+ where they could not occur in a serial execution of the concurrent
+ transactions.
+ </p><p>
+ For optimal performance when relying on Serializable transactions for
+ concurrency control, these issues should be considered:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Declare transactions as <code class="literal">READ ONLY</code> when possible.
+ </p></li><li class="listitem"><p>
+ Control the number of active connections, using a connection pool if
+ needed. This is always an important performance consideration, but
+ it can be particularly important in a busy system using Serializable
+ transactions.
+ </p></li><li class="listitem"><p>
+ Don't put more into a single transaction than needed for integrity
+ purposes.
+ </p></li><li class="listitem"><p>
+ Don't leave connections dangling <span class="quote">“<span class="quote">idle in transaction</span>”</span>
+ longer than necessary. The configuration parameter
+ <a class="xref" href="runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT">idle_in_transaction_session_timeout</a> may be used to
+ automatically disconnect lingering sessions.
+ </p></li><li class="listitem"><p>
+ Eliminate explicit locks, <code class="literal">SELECT FOR UPDATE</code>, and
+ <code class="literal">SELECT FOR SHARE</code> where no longer needed due to the
+ protections automatically provided by Serializable transactions.
+ </p></li><li class="listitem"><p>
+ When the system is forced to combine multiple page-level predicate
+ locks into a single relation-level predicate lock because the predicate
+ lock table is short of memory, an increase in the rate of serialization
+ failures may occur. You can avoid this by increasing
+ <a class="xref" href="runtime-config-locks.html#GUC-MAX-PRED-LOCKS-PER-TRANSACTION">max_pred_locks_per_transaction</a>,
+ <a class="xref" href="runtime-config-locks.html#GUC-MAX-PRED-LOCKS-PER-RELATION">max_pred_locks_per_relation</a>, and/or
+ <a class="xref" href="runtime-config-locks.html#GUC-MAX-PRED-LOCKS-PER-PAGE">max_pred_locks_per_page</a>.
+ </p></li><li class="listitem"><p>
+ A sequential scan will always necessitate a relation-level predicate
+ lock. This can result in an increased rate of serialization failures.
+ It may be helpful to encourage the use of index scans by reducing
+ <a class="xref" href="runtime-config-query.html#GUC-RANDOM-PAGE-COST">random_page_cost</a> and/or increasing
+ <a class="xref" href="runtime-config-query.html#GUC-CPU-TUPLE-COST">cpu_tuple_cost</a>. Be sure to weigh any decrease
+ in transaction rollbacks and restarts against any overall change in
+ query execution time.
+ </p></li></ul></div><p>
+ </p><p>
+ The Serializable isolation level is implemented using a technique known
+ in academic database literature as Serializable Snapshot Isolation, which
+ builds on Snapshot Isolation by adding checks for serialization anomalies.
+ Some differences in behavior and performance may be observed when compared
+ with other systems that use a traditional locking technique. Please see
+ <a class="xref" href="biblio.html#PORTS12">[ports12]</a> for detailed information.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="mvcc-intro.html" title="13.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="mvcc.html" title="Chapter 13. Concurrency Control">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="explicit-locking.html" title="13.3. Explicit Locking">Next</a></td></tr><tr><td width="40%" align="left" valign="top">13.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 13.3. Explicit Locking</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/trigger-datachanges.html b/doc/src/sgml/html/trigger-datachanges.html
new file mode 100644
index 0000000..c2ba36e
--- /dev/null
+++ b/doc/src/sgml/html/trigger-datachanges.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>39.2. Visibility of Data Changes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="trigger-definition.html" title="39.1. Overview of Trigger Behavior" /><link rel="next" href="trigger-interface.html" title="39.3. Writing Trigger Functions in C" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">39.2. Visibility of Data Changes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="trigger-definition.html" title="39.1. Overview of Trigger Behavior">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><th width="60%" align="center">Chapter 39. Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="trigger-interface.html" title="39.3. Writing Trigger Functions in C">Next</a></td></tr></table><hr /></div><div class="sect1" id="TRIGGER-DATACHANGES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">39.2. Visibility of Data Changes</h2></div></div></div><p>
+ If you execute SQL commands in your trigger function, and these
+ commands access the table that the trigger is for, then
+ you need to be aware of the data visibility rules, because they determine
+ whether these SQL commands will see the data change that the trigger
+ is fired for. Briefly:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Statement-level triggers follow simple visibility rules: none of
+ the changes made by a statement are visible to statement-level
+ <code class="literal">BEFORE</code> triggers, whereas all
+ modifications are visible to statement-level <code class="literal">AFTER</code>
+ triggers.
+ </p></li><li class="listitem"><p>
+ The data change (insertion, update, or deletion) causing the
+ trigger to fire is naturally <span class="emphasis"><em>not</em></span> visible
+ to SQL commands executed in a row-level <code class="literal">BEFORE</code> trigger,
+ because it hasn't happened yet.
+ </p></li><li class="listitem"><p>
+ However, SQL commands executed in a row-level <code class="literal">BEFORE</code>
+ trigger <span class="emphasis"><em>will</em></span> see the effects of data
+ changes for rows previously processed in the same outer
+ command. This requires caution, since the ordering of these
+ change events is not in general predictable; an SQL command that
+ affects multiple rows can visit the rows in any order.
+ </p></li><li class="listitem"><p>
+ Similarly, a row-level <code class="literal">INSTEAD OF</code> trigger will see the
+ effects of data changes made by previous firings of <code class="literal">INSTEAD
+ OF</code> triggers in the same outer command.
+ </p></li><li class="listitem"><p>
+ When a row-level <code class="literal">AFTER</code> trigger is fired, all data
+ changes made
+ by the outer command are already complete, and are visible to
+ the invoked trigger function.
+ </p></li></ul></div><p>
+ </p><p>
+ If your trigger function is written in any of the standard procedural
+ languages, then the above statements apply only if the function is
+ declared <code class="literal">VOLATILE</code>. Functions that are declared
+ <code class="literal">STABLE</code> or <code class="literal">IMMUTABLE</code> will not see changes made by
+ the calling command in any case.
+ </p><p>
+ Further information about data visibility rules can be found in
+ <a class="xref" href="spi-visibility.html" title="47.5. Visibility of Data Changes">Section 47.5</a>. The example in <a class="xref" href="trigger-example.html" title="39.4. A Complete Trigger Example">Section 39.4</a> contains a demonstration of these rules.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="trigger-definition.html" title="39.1. Overview of Trigger Behavior">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="trigger-interface.html" title="39.3. Writing Trigger Functions in C">Next</a></td></tr><tr><td width="40%" align="left" valign="top">39.1. Overview of Trigger Behavior </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 39.3. Writing Trigger Functions in C</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/trigger-definition.html b/doc/src/sgml/html/trigger-definition.html
new file mode 100644
index 0000000..654c4df
--- /dev/null
+++ b/doc/src/sgml/html/trigger-definition.html
@@ -0,0 +1,315 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>39.1. Overview of Trigger Behavior</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="triggers.html" title="Chapter 39. Triggers" /><link rel="next" href="trigger-datachanges.html" title="39.2. Visibility of Data Changes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">39.1. Overview of Trigger Behavior</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="triggers.html" title="Chapter 39. Triggers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><th width="60%" align="center">Chapter 39. Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="trigger-datachanges.html" title="39.2. Visibility of Data Changes">Next</a></td></tr></table><hr /></div><div class="sect1" id="TRIGGER-DEFINITION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">39.1. Overview of Trigger Behavior</h2></div></div></div><p>
+ A trigger is a specification that the database should automatically
+ execute a particular function whenever a certain type of operation is
+ performed. Triggers can be attached to tables (partitioned or not),
+ views, and foreign tables.
+ </p><p>
+ On tables and foreign tables, triggers can be defined to execute either
+ before or after any <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ or <code class="command">DELETE</code> operation, either once per modified row,
+ or once per <acronym class="acronym">SQL</acronym> statement.
+ <code class="command">UPDATE</code> triggers can moreover be set to fire only if
+ certain columns are mentioned in the <code class="literal">SET</code> clause of
+ the <code class="command">UPDATE</code> statement. Triggers can also fire
+ for <code class="command">TRUNCATE</code> statements. If a trigger event occurs,
+ the trigger's function is called at the appropriate time to handle the
+ event.
+ </p><p>
+ On views, triggers can be defined to execute instead of
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> operations.
+ Such <code class="literal">INSTEAD OF</code> triggers
+ are fired once for each row that needs to be modified in the view.
+ It is the responsibility of the
+ trigger's function to perform the necessary modifications to the view's
+ underlying base table(s) and, where appropriate, return the modified
+ row as it will appear in the view. Triggers on views can also be defined
+ to execute once per <acronym class="acronym">SQL</acronym> statement, before or after
+ <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
+ <code class="command">DELETE</code> operations.
+ However, such triggers are fired only if there is also
+ an <code class="literal">INSTEAD OF</code> trigger on the view. Otherwise,
+ any statement targeting the view must be rewritten into a statement
+ affecting its underlying base table(s), and then the triggers
+ that will be fired are the ones attached to the base table(s).
+ </p><p>
+ The trigger function must be defined before the trigger itself can be
+ created. The trigger function must be declared as a
+ function taking no arguments and returning type <code class="literal">trigger</code>.
+ (The trigger function receives its input through a specially-passed
+ <code class="structname">TriggerData</code> structure, not in the form of ordinary function
+ arguments.)
+ </p><p>
+ Once a suitable trigger function has been created, the trigger is
+ established with
+ <a class="xref" href="sql-createtrigger.html" title="CREATE TRIGGER"><span class="refentrytitle">CREATE TRIGGER</span></a>.
+ The same trigger function can be used for multiple triggers.
+ </p><p>
+ <span class="productname">PostgreSQL</span> offers both <em class="firstterm">per-row</em>
+ triggers and <em class="firstterm">per-statement</em> triggers. With a per-row
+ trigger, the trigger function
+ is invoked once for each row that is affected by the statement
+ that fired the trigger. In contrast, a per-statement trigger is
+ invoked only once when an appropriate statement is executed,
+ regardless of the number of rows affected by that statement. In
+ particular, a statement that affects zero rows will still result
+ in the execution of any applicable per-statement triggers. These
+ two types of triggers are sometimes called <em class="firstterm">row-level</em>
+ triggers and <em class="firstterm">statement-level</em> triggers,
+ respectively. Triggers on <code class="command">TRUNCATE</code> may only be
+ defined at statement level, not per-row.
+ </p><p>
+ Triggers are also classified according to whether they fire
+ <em class="firstterm">before</em>, <em class="firstterm">after</em>, or
+ <em class="firstterm">instead of</em> the operation. These are referred to
+ as <code class="literal">BEFORE</code> triggers, <code class="literal">AFTER</code> triggers, and
+ <code class="literal">INSTEAD OF</code> triggers respectively.
+ Statement-level <code class="literal">BEFORE</code> triggers naturally fire before the
+ statement starts to do anything, while statement-level <code class="literal">AFTER</code>
+ triggers fire at the very end of the statement. These types of
+ triggers may be defined on tables, views, or foreign tables. Row-level
+ <code class="literal">BEFORE</code> triggers fire immediately before a particular row is
+ operated on, while row-level <code class="literal">AFTER</code> triggers fire at the end of
+ the statement (but before any statement-level <code class="literal">AFTER</code> triggers).
+ These types of triggers may only be defined on tables and
+ foreign tables, not views.
+ <code class="literal">INSTEAD OF</code> triggers may only be
+ defined on views, and only at row level; they fire immediately as each
+ row in the view is identified as needing to be operated on.
+ </p><p>
+ The execution of an <code class="literal">AFTER</code> trigger can be deferred
+ to the end of the transaction, rather than the end of the statement,
+ if it was defined as a <em class="firstterm">constraint trigger</em>.
+ In all cases, a trigger is executed as part of the same transaction as
+ the statement that triggered it, so if either the statement or the
+ trigger causes an error, the effects of both will be rolled back.
+ </p><p>
+ A statement that targets a parent table in an inheritance or partitioning
+ hierarchy does not cause the statement-level triggers of affected child
+ tables to be fired; only the parent table's statement-level triggers are
+ fired. However, row-level triggers of any affected child tables will be
+ fired.
+ </p><p>
+ If an <code class="command">INSERT</code> contains an <code class="literal">ON CONFLICT
+ DO UPDATE</code> clause, it is possible that the effects of
+ row-level <code class="literal">BEFORE</code> <code class="command">INSERT</code> triggers and
+ row-level <code class="literal">BEFORE</code> <code class="command">UPDATE</code> triggers can
+ both be applied in a way that is apparent from the final state of
+ the updated row, if an <code class="varname">EXCLUDED</code> column is referenced.
+ There need not be an <code class="varname">EXCLUDED</code> column reference for
+ both sets of row-level <code class="literal">BEFORE</code> triggers to execute,
+ though. The
+ possibility of surprising outcomes should be considered when there
+ are both <code class="literal">BEFORE</code> <code class="command">INSERT</code> and
+ <code class="literal">BEFORE</code> <code class="command">UPDATE</code> row-level triggers
+ that change a row being inserted/updated (this can be
+ problematic even if the modifications are more or less equivalent, if
+ they're not also idempotent). Note that statement-level
+ <code class="command">UPDATE</code> triggers are executed when <code class="literal">ON
+ CONFLICT DO UPDATE</code> is specified, regardless of whether or not
+ any rows were affected by the <code class="command">UPDATE</code> (and
+ regardless of whether the alternative <code class="command">UPDATE</code>
+ path was ever taken). An <code class="command">INSERT</code> with an
+ <code class="literal">ON CONFLICT DO UPDATE</code> clause will execute
+ statement-level <code class="literal">BEFORE</code> <code class="command">INSERT</code>
+ triggers first, then statement-level <code class="literal">BEFORE</code>
+ <code class="command">UPDATE</code> triggers, followed by statement-level
+ <code class="literal">AFTER</code> <code class="command">UPDATE</code> triggers and finally
+ statement-level <code class="literal">AFTER</code> <code class="command">INSERT</code>
+ triggers.
+ </p><p>
+ If an <code class="command">UPDATE</code> on a partitioned table causes a row to move
+ to another partition, it will be performed as a <code class="command">DELETE</code>
+ from the original partition followed by an <code class="command">INSERT</code> into
+ the new partition. In this case, all row-level <code class="literal">BEFORE</code>
+ <code class="command">UPDATE</code> triggers and all row-level
+ <code class="literal">BEFORE</code> <code class="command">DELETE</code> triggers are fired on
+ the original partition. Then all row-level <code class="literal">BEFORE</code>
+ <code class="command">INSERT</code> triggers are fired on the destination partition.
+ The possibility of surprising outcomes should be considered when all these
+ triggers affect the row being moved. As far as <code class="literal">AFTER ROW</code>
+ triggers are concerned, <code class="literal">AFTER</code> <code class="command">DELETE</code>
+ and <code class="literal">AFTER</code> <code class="command">INSERT</code> triggers are
+ applied; but <code class="literal">AFTER</code> <code class="command">UPDATE</code> triggers
+ are not applied because the <code class="command">UPDATE</code> has been converted to
+ a <code class="command">DELETE</code> and an <code class="command">INSERT</code>. As far as
+ statement-level triggers are concerned, none of the
+ <code class="command">DELETE</code> or <code class="command">INSERT</code> triggers are fired,
+ even if row movement occurs; only the <code class="command">UPDATE</code> triggers
+ defined on the target table used in the <code class="command">UPDATE</code> statement
+ will be fired.
+ </p><p>
+ No separate triggers are defined for <code class="command">MERGE</code>. Instead,
+ statement-level or row-level <code class="command">UPDATE</code>,
+ <code class="command">DELETE</code>, and <code class="command">INSERT</code> triggers are fired
+ depending on (for statement-level triggers) what actions are specified in
+ the <code class="command">MERGE</code> query and (for row-level triggers) what
+ actions are performed.
+ </p><p>
+ While running a <code class="command">MERGE</code> command, statement-level
+ <code class="literal">BEFORE</code> and <code class="literal">AFTER</code> triggers are
+ fired for events specified in the actions of the <code class="command">MERGE</code>
+ command, irrespective of whether or not the action is ultimately performed.
+ This is the same as an <code class="command">UPDATE</code> statement that updates
+ no rows, yet statement-level triggers are fired.
+ The row-level triggers are fired only when a row is actually updated,
+ inserted or deleted. So it's perfectly legal that while statement-level
+ triggers are fired for certain types of action, no row-level triggers
+ are fired for the same kind of action.
+ </p><p>
+ Trigger functions invoked by per-statement triggers should always
+ return <code class="symbol">NULL</code>. Trigger functions invoked by per-row
+ triggers can return a table row (a value of
+ type <code class="structname">HeapTuple</code>) to the calling executor,
+ if they choose. A row-level trigger fired before an operation has
+ the following choices:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ It can return <code class="symbol">NULL</code> to skip the operation for the
+ current row. This instructs the executor to not perform the
+ row-level operation that invoked the trigger (the insertion,
+ modification, or deletion of a particular table row).
+ </p></li><li class="listitem"><p>
+ For row-level <code class="command">INSERT</code>
+ and <code class="command">UPDATE</code> triggers only, the returned row
+ becomes the row that will be inserted or will replace the row
+ being updated. This allows the trigger function to modify the
+ row being inserted or updated.
+ </p></li></ul></div><p>
+
+ A row-level <code class="literal">BEFORE</code> trigger that does not intend to cause
+ either of these behaviors must be careful to return as its result the same
+ row that was passed in (that is, the <code class="varname">NEW</code> row
+ for <code class="command">INSERT</code> and <code class="command">UPDATE</code>
+ triggers, the <code class="varname">OLD</code> row for
+ <code class="command">DELETE</code> triggers).
+ </p><p>
+ A row-level <code class="literal">INSTEAD OF</code> trigger should either return
+ <code class="symbol">NULL</code> to indicate that it did not modify any data from
+ the view's underlying base tables, or it should return the view
+ row that was passed in (the <code class="varname">NEW</code> row
+ for <code class="command">INSERT</code> and <code class="command">UPDATE</code>
+ operations, or the <code class="varname">OLD</code> row for
+ <code class="command">DELETE</code> operations). A nonnull return value is
+ used to signal that the trigger performed the necessary data
+ modifications in the view. This will cause the count of the number
+ of rows affected by the command to be incremented. For
+ <code class="command">INSERT</code> and <code class="command">UPDATE</code> operations only, the trigger
+ may modify the <code class="varname">NEW</code> row before returning it. This will
+ change the data returned by
+ <code class="command">INSERT RETURNING</code> or <code class="command">UPDATE RETURNING</code>,
+ and is useful when the view will not show exactly the same data
+ that was provided.
+ </p><p>
+ The return value is ignored for row-level triggers fired after an
+ operation, and so they can return <code class="symbol">NULL</code>.
+ </p><p>
+ Some considerations apply for generated
+ columns.<a id="id-1.8.4.5.18.1" class="indexterm"></a> Stored generated columns are computed after
+ <code class="literal">BEFORE</code> triggers and before <code class="literal">AFTER</code>
+ triggers. Therefore, the generated value can be inspected in
+ <code class="literal">AFTER</code> triggers. In <code class="literal">BEFORE</code> triggers,
+ the <code class="literal">OLD</code> row contains the old generated value, as one
+ would expect, but the <code class="literal">NEW</code> row does not yet contain the
+ new generated value and should not be accessed. In the C language
+ interface, the content of the column is undefined at this point; a
+ higher-level programming language should prevent access to a stored
+ generated column in the <code class="literal">NEW</code> row in a
+ <code class="literal">BEFORE</code> trigger. Changes to the value of a generated
+ column in a <code class="literal">BEFORE</code> trigger are ignored and will be
+ overwritten.
+ </p><p>
+ If more than one trigger is defined for the same event on the same
+ relation, the triggers will be fired in alphabetical order by
+ trigger name. In the case of <code class="literal">BEFORE</code> and
+ <code class="literal">INSTEAD OF</code> triggers, the possibly-modified row returned by
+ each trigger becomes the input to the next trigger. If any
+ <code class="literal">BEFORE</code> or <code class="literal">INSTEAD OF</code> trigger returns
+ <code class="symbol">NULL</code>, the operation is abandoned for that row and subsequent
+ triggers are not fired (for that row).
+ </p><p>
+ A trigger definition can also specify a Boolean <code class="literal">WHEN</code>
+ condition, which will be tested to see whether the trigger should
+ be fired. In row-level triggers the <code class="literal">WHEN</code> condition can
+ examine the old and/or new values of columns of the row. (Statement-level
+ triggers can also have <code class="literal">WHEN</code> conditions, although the feature
+ is not so useful for them.) In a <code class="literal">BEFORE</code> trigger, the
+ <code class="literal">WHEN</code>
+ condition is evaluated just before the function is or would be executed,
+ so using <code class="literal">WHEN</code> is not materially different from testing the
+ same condition at the beginning of the trigger function. However, in
+ an <code class="literal">AFTER</code> trigger, the <code class="literal">WHEN</code> condition is evaluated
+ just after the row update occurs, and it determines whether an event is
+ queued to fire the trigger at the end of statement. So when an
+ <code class="literal">AFTER</code> trigger's
+ <code class="literal">WHEN</code> condition does not return true, it is not necessary
+ to queue an event nor to re-fetch the row at end of statement. This
+ can result in significant speedups in statements that modify many
+ rows, if the trigger only needs to be fired for a few of the rows.
+ <code class="literal">INSTEAD OF</code> triggers do not support
+ <code class="literal">WHEN</code> conditions.
+ </p><p>
+ Typically, row-level <code class="literal">BEFORE</code> triggers are used for checking or
+ modifying the data that will be inserted or updated. For example,
+ a <code class="literal">BEFORE</code> trigger might be used to insert the current time into a
+ <code class="type">timestamp</code> column, or to check that two elements of the row are
+ consistent. Row-level <code class="literal">AFTER</code> triggers are most sensibly
+ used to propagate the updates to other tables, or make consistency
+ checks against other tables. The reason for this division of labor is
+ that an <code class="literal">AFTER</code> trigger can be certain it is seeing the final
+ value of the row, while a <code class="literal">BEFORE</code> trigger cannot; there might
+ be other <code class="literal">BEFORE</code> triggers firing after it. If you have no
+ specific reason to make a trigger <code class="literal">BEFORE</code> or
+ <code class="literal">AFTER</code>, the <code class="literal">BEFORE</code> case is more efficient, since
+ the information about
+ the operation doesn't have to be saved until end of statement.
+ </p><p>
+ If a trigger function executes SQL commands then these
+ commands might fire triggers again. This is known as cascading
+ triggers. There is no direct limitation on the number of cascade
+ levels. It is possible for cascades to cause a recursive invocation
+ of the same trigger; for example, an <code class="command">INSERT</code>
+ trigger might execute a command that inserts an additional row
+ into the same table, causing the <code class="command">INSERT</code> trigger
+ to be fired again. It is the trigger programmer's responsibility
+ to avoid infinite recursion in such scenarios.
+ </p><p>
+ <a id="id-1.8.4.5.23.1" class="indexterm"></a>
+ When a trigger is being defined, arguments can be specified for
+ it. The purpose of including arguments in the
+ trigger definition is to allow different triggers with similar
+ requirements to call the same function. As an example, there
+ could be a generalized trigger function that takes as its
+ arguments two column names and puts the current user in one and
+ the current time stamp in the other. Properly written, this
+ trigger function would be independent of the specific table it is
+ triggering on. So the same function could be used for
+ <code class="command">INSERT</code> events on any table with suitable
+ columns, to automatically track creation of records in a
+ transaction table for example. It could also be used to track
+ last-update events if defined as an <code class="command">UPDATE</code>
+ trigger.
+ </p><p>
+ Each programming language that supports triggers has its own method
+ for making the trigger input data available to the trigger function.
+ This input data includes the type of trigger event (e.g.,
+ <code class="command">INSERT</code> or <code class="command">UPDATE</code>) as well as any
+ arguments that were listed in <code class="command">CREATE TRIGGER</code>.
+ For a row-level trigger, the input data also includes the
+ <code class="varname">NEW</code> row for <code class="command">INSERT</code> and
+ <code class="command">UPDATE</code> triggers, and/or the <code class="varname">OLD</code> row
+ for <code class="command">UPDATE</code> and <code class="command">DELETE</code> triggers.
+ </p><p>
+ By default, statement-level triggers do not have any way to examine the
+ individual row(s) modified by the statement. But an <code class="literal">AFTER
+ STATEMENT</code> trigger can request that <em class="firstterm">transition tables</em>
+ be created to make the sets of affected rows available to the trigger.
+ <code class="literal">AFTER ROW</code> triggers can also request transition tables, so
+ that they can see the total changes in the table as well as the change in
+ the individual row they are currently being fired for. The method for
+ examining the transition tables again depends on the programming language
+ that is being used, but the typical approach is to make the transition
+ tables act like read-only temporary tables that can be accessed by SQL
+ commands issued within the trigger function.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="triggers.html" title="Chapter 39. Triggers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="trigger-datachanges.html" title="39.2. Visibility of Data Changes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 39. Triggers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 39.2. Visibility of Data Changes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/trigger-example.html b/doc/src/sgml/html/trigger-example.html
new file mode 100644
index 0000000..a731266
--- /dev/null
+++ b/doc/src/sgml/html/trigger-example.html
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>39.4. A Complete Trigger Example</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="trigger-interface.html" title="39.3. Writing Trigger Functions in C" /><link rel="next" href="event-triggers.html" title="Chapter 40. Event Triggers" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">39.4. A Complete Trigger Example</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="trigger-interface.html" title="39.3. Writing Trigger Functions in C">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><th width="60%" align="center">Chapter 39. Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="event-triggers.html" title="Chapter 40. Event Triggers">Next</a></td></tr></table><hr /></div><div class="sect1" id="TRIGGER-EXAMPLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">39.4. A Complete Trigger Example</h2></div></div></div><p>
+ Here is a very simple example of a trigger function written in C.
+ (Examples of triggers written in procedural languages can be found
+ in the documentation of the procedural languages.)
+ </p><p>
+ The function <code class="function">trigf</code> reports the number of rows in the
+ table <code class="structname">ttest</code> and skips the actual operation if the
+ command attempts to insert a null value into the column
+ <code class="structfield">x</code>. (So the trigger acts as a not-null constraint but
+ doesn't abort the transaction.)
+ </p><p>
+ First, the table definition:
+</p><pre class="programlisting">
+CREATE TABLE ttest (
+ x integer
+);
+</pre><p>
+ </p><p>
+ This is the source code of the trigger function:
+</p><pre class="programlisting">
+#include "postgres.h"
+#include "fmgr.h"
+#include "executor/spi.h" /* this is what you need to work with SPI */
+#include "commands/trigger.h" /* ... triggers ... */
+#include "utils/rel.h" /* ... and relations */
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(trigf);
+
+Datum
+trigf(PG_FUNCTION_ARGS)
+{
+ TriggerData *trigdata = (TriggerData *) fcinfo-&gt;context;
+ TupleDesc tupdesc;
+ HeapTuple rettuple;
+ char *when;
+ bool checknull = false;
+ bool isnull;
+ int ret, i;
+
+ /* make sure it's called as a trigger at all */
+ if (!CALLED_AS_TRIGGER(fcinfo))
+ elog(ERROR, "trigf: not called by trigger manager");
+
+ /* tuple to return to executor */
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata-&gt;tg_event))
+ rettuple = trigdata-&gt;tg_newtuple;
+ else
+ rettuple = trigdata-&gt;tg_trigtuple;
+
+ /* check for null values */
+ if (!TRIGGER_FIRED_BY_DELETE(trigdata-&gt;tg_event)
+ &amp;&amp; TRIGGER_FIRED_BEFORE(trigdata-&gt;tg_event))
+ checknull = true;
+
+ if (TRIGGER_FIRED_BEFORE(trigdata-&gt;tg_event))
+ when = "before";
+ else
+ when = "after ";
+
+ tupdesc = trigdata-&gt;tg_relation-&gt;rd_att;
+
+ /* connect to SPI manager */
+ if ((ret = SPI_connect()) &lt; 0)
+ elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret);
+
+ /* get number of rows in table */
+ ret = SPI_exec("SELECT count(*) FROM ttest", 0);
+
+ if (ret &lt; 0)
+ elog(ERROR, "trigf (fired %s): SPI_exec returned %d", when, ret);
+
+ /* count(*) returns int8, so be careful to convert */
+ i = DatumGetInt64(SPI_getbinval(SPI_tuptable-&gt;vals[0],
+ SPI_tuptable-&gt;tupdesc,
+ 1,
+ &amp;isnull));
+
+ elog (INFO, "trigf (fired %s): there are %d rows in ttest", when, i);
+
+ SPI_finish();
+
+ if (checknull)
+ {
+ SPI_getbinval(rettuple, tupdesc, 1, &amp;isnull);
+ if (isnull)
+ rettuple = NULL;
+ }
+
+ return PointerGetDatum(rettuple);
+}
+
+</pre><p>
+ </p><p>
+ After you have compiled the source code (see <a class="xref" href="xfunc-c.html#DFUNC" title="38.10.5. Compiling and Linking Dynamically-Loaded Functions">Section 38.10.5</a>), declare the function and the triggers:
+</p><pre class="programlisting">
+CREATE FUNCTION trigf() RETURNS trigger
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C;
+
+CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest
+ FOR EACH ROW EXECUTE FUNCTION trigf();
+
+CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest
+ FOR EACH ROW EXECUTE FUNCTION trigf();
+</pre><p>
+ </p><p>
+ Now you can test the operation of the trigger:
+</p><pre class="screen">
+=&gt; INSERT INTO ttest VALUES (NULL);
+INFO: trigf (fired before): there are 0 rows in ttest
+INSERT 0 0
+
+-- Insertion skipped and AFTER trigger is not fired
+
+=&gt; SELECT * FROM ttest;
+ x
+---
+(0 rows)
+
+=&gt; INSERT INTO ttest VALUES (1);
+INFO: trigf (fired before): there are 0 rows in ttest
+INFO: trigf (fired after ): there are 1 rows in ttest
+ ^^^^^^^^
+ remember what we said about visibility.
+INSERT 167793 1
+vac=&gt; SELECT * FROM ttest;
+ x
+---
+ 1
+(1 row)
+
+=&gt; INSERT INTO ttest SELECT x * 2 FROM ttest;
+INFO: trigf (fired before): there are 1 rows in ttest
+INFO: trigf (fired after ): there are 2 rows in ttest
+ ^^^^^^
+ remember what we said about visibility.
+INSERT 167794 1
+=&gt; SELECT * FROM ttest;
+ x
+---
+ 1
+ 2
+(2 rows)
+
+=&gt; UPDATE ttest SET x = NULL WHERE x = 2;
+INFO: trigf (fired before): there are 2 rows in ttest
+UPDATE 0
+=&gt; UPDATE ttest SET x = 4 WHERE x = 2;
+INFO: trigf (fired before): there are 2 rows in ttest
+INFO: trigf (fired after ): there are 2 rows in ttest
+UPDATE 1
+vac=&gt; SELECT * FROM ttest;
+ x
+---
+ 1
+ 4
+(2 rows)
+
+=&gt; DELETE FROM ttest;
+INFO: trigf (fired before): there are 2 rows in ttest
+INFO: trigf (fired before): there are 1 rows in ttest
+INFO: trigf (fired after ): there are 0 rows in ttest
+INFO: trigf (fired after ): there are 0 rows in ttest
+ ^^^^^^
+ remember what we said about visibility.
+DELETE 2
+=&gt; SELECT * FROM ttest;
+ x
+---
+(0 rows)
+</pre><p>
+
+ </p><p>
+ There are more complex examples in
+ <code class="filename">src/test/regress/regress.c</code> and
+ in <a class="xref" href="contrib-spi.html" title="F.41. spi">spi</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="trigger-interface.html" title="39.3. Writing Trigger Functions in C">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="event-triggers.html" title="Chapter 40. Event Triggers">Next</a></td></tr><tr><td width="40%" align="left" valign="top">39.3. Writing Trigger Functions in C </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 40. Event Triggers</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/trigger-interface.html b/doc/src/sgml/html/trigger-interface.html
new file mode 100644
index 0000000..1796acd
--- /dev/null
+++ b/doc/src/sgml/html/trigger-interface.html
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>39.3. Writing Trigger Functions in C</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="trigger-datachanges.html" title="39.2. Visibility of Data Changes" /><link rel="next" href="trigger-example.html" title="39.4. A Complete Trigger Example" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">39.3. Writing Trigger Functions in C</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="trigger-datachanges.html" title="39.2. Visibility of Data Changes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><th width="60%" align="center">Chapter 39. Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="trigger-example.html" title="39.4. A Complete Trigger Example">Next</a></td></tr></table><hr /></div><div class="sect1" id="TRIGGER-INTERFACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">39.3. Writing Trigger Functions in C</h2></div></div></div><a id="id-1.8.4.7.2" class="indexterm"></a><a id="id-1.8.4.7.3" class="indexterm"></a><p>
+ This section describes the low-level details of the interface to a
+ trigger function. This information is only needed when writing
+ trigger functions in C. If you are using a higher-level language then
+ these details are handled for you. In most cases you should consider
+ using a procedural language before writing your triggers in C. The
+ documentation of each procedural language explains how to write a
+ trigger in that language.
+ </p><p>
+ Trigger functions must use the <span class="quote">“<span class="quote">version 1</span>”</span> function manager
+ interface.
+ </p><p>
+ When a function is called by the trigger manager, it is not passed
+ any normal arguments, but it is passed a <span class="quote">“<span class="quote">context</span>”</span>
+ pointer pointing to a <code class="structname">TriggerData</code> structure. C
+ functions can check whether they were called from the trigger
+ manager or not by executing the macro:
+</p><pre class="programlisting">
+CALLED_AS_TRIGGER(fcinfo)
+</pre><p>
+ which expands to:
+</p><pre class="programlisting">
+((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, TriggerData))
+</pre><p>
+ If this returns true, then it is safe to cast
+ <code class="literal">fcinfo-&gt;context</code> to type <code class="literal">TriggerData
+ *</code> and make use of the pointed-to
+ <code class="structname">TriggerData</code> structure. The function must
+ <span class="emphasis"><em>not</em></span> alter the <code class="structname">TriggerData</code>
+ structure or any of the data it points to.
+ </p><p>
+ <code class="structname">struct TriggerData</code> is defined in
+ <code class="filename">commands/trigger.h</code>:
+
+</p><pre class="programlisting">
+typedef struct TriggerData
+{
+ NodeTag type;
+ TriggerEvent tg_event;
+ Relation tg_relation;
+ HeapTuple tg_trigtuple;
+ HeapTuple tg_newtuple;
+ Trigger *tg_trigger;
+ TupleTableSlot *tg_trigslot;
+ TupleTableSlot *tg_newslot;
+ Tuplestorestate *tg_oldtable;
+ Tuplestorestate *tg_newtable;
+ const Bitmapset *tg_updatedcols;
+} TriggerData;
+</pre><p>
+
+ where the members are defined as follows:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="structfield">type</code></span></dt><dd><p>
+ Always <code class="literal">T_TriggerData</code>.
+ </p></dd><dt><span class="term"><code class="structfield">tg_event</code></span></dt><dd><p>
+ Describes the event for which the function is called. You can use the
+ following macros to examine <code class="literal">tg_event</code>:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TRIGGER_FIRED_BEFORE(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger fired before the operation.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_AFTER(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger fired after the operation.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_INSTEAD(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger fired instead of the operation.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_FOR_ROW(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger fired for a row-level event.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_FOR_STATEMENT(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger fired for a statement-level event.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_INSERT(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger was fired by an <code class="command">INSERT</code> command.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_UPDATE(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger was fired by an <code class="command">UPDATE</code> command.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_DELETE(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger was fired by a <code class="command">DELETE</code> command.
+ </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_TRUNCATE(tg_event)</code></span></dt><dd><p>
+ Returns true if the trigger was fired by a <code class="command">TRUNCATE</code> command.
+ </p></dd></dl></div><p>
+ </p></dd><dt><span class="term"><code class="structfield">tg_relation</code></span></dt><dd><p>
+ A pointer to a structure describing the relation that the trigger fired for.
+ Look at <code class="filename">utils/rel.h</code> for details about
+ this structure. The most interesting things are
+ <code class="literal">tg_relation-&gt;rd_att</code> (descriptor of the relation
+ tuples) and <code class="literal">tg_relation-&gt;rd_rel-&gt;relname</code>
+ (relation name; the type is not <code class="type">char*</code> but
+ <code class="type">NameData</code>; use
+ <code class="literal">SPI_getrelname(tg_relation)</code> to get a <code class="type">char*</code> if you
+ need a copy of the name).
+ </p></dd><dt><span class="term"><code class="structfield">tg_trigtuple</code></span></dt><dd><p>
+ A pointer to the row for which the trigger was fired. This is
+ the row being inserted, updated, or deleted. If this trigger
+ was fired for an <code class="command">INSERT</code> or
+ <code class="command">DELETE</code> then this is what you should return
+ from the function if you don't want to replace the row with
+ a different one (in the case of <code class="command">INSERT</code>) or
+ skip the operation. For triggers on foreign tables, values of system
+ columns herein are unspecified.
+ </p></dd><dt><span class="term"><code class="structfield">tg_newtuple</code></span></dt><dd><p>
+ A pointer to the new version of the row, if the trigger was
+ fired for an <code class="command">UPDATE</code>, and <code class="symbol">NULL</code> if
+ it is for an <code class="command">INSERT</code> or a
+ <code class="command">DELETE</code>. This is what you have to return
+ from the function if the event is an <code class="command">UPDATE</code>
+ and you don't want to replace this row by a different one or
+ skip the operation. For triggers on foreign tables, values of system
+ columns herein are unspecified.
+ </p></dd><dt><span class="term"><code class="structfield">tg_trigger</code></span></dt><dd><p>
+ A pointer to a structure of type <code class="structname">Trigger</code>,
+ defined in <code class="filename">utils/reltrigger.h</code>:
+
+</p><pre class="programlisting">
+typedef struct Trigger
+{
+ Oid tgoid;
+ char *tgname;
+ Oid tgfoid;
+ int16 tgtype;
+ char tgenabled;
+ bool tgisinternal;
+ bool tgisclone;
+ Oid tgconstrrelid;
+ Oid tgconstrindid;
+ Oid tgconstraint;
+ bool tgdeferrable;
+ bool tginitdeferred;
+ int16 tgnargs;
+ int16 tgnattr;
+ int16 *tgattr;
+ char **tgargs;
+ char *tgqual;
+ char *tgoldtable;
+ char *tgnewtable;
+} Trigger;
+</pre><p>
+
+ where <code class="structfield">tgname</code> is the trigger's name,
+ <code class="structfield">tgnargs</code> is the number of arguments in
+ <code class="structfield">tgargs</code>, and <code class="structfield">tgargs</code> is an array of
+ pointers to the arguments specified in the <code class="command">CREATE
+ TRIGGER</code> statement. The other members are for internal use
+ only.
+ </p></dd><dt><span class="term"><code class="structfield">tg_trigslot</code></span></dt><dd><p>
+ The slot containing <code class="structfield">tg_trigtuple</code>,
+ or a <code class="symbol">NULL</code> pointer if there is no such tuple.
+ </p></dd><dt><span class="term"><code class="structfield">tg_newslot</code></span></dt><dd><p>
+ The slot containing <code class="structfield">tg_newtuple</code>,
+ or a <code class="symbol">NULL</code> pointer if there is no such tuple.
+ </p></dd><dt><span class="term"><code class="structfield">tg_oldtable</code></span></dt><dd><p>
+ A pointer to a structure of type <code class="structname">Tuplestorestate</code>
+ containing zero or more rows in the format specified by
+ <code class="structfield">tg_relation</code>, or a <code class="symbol">NULL</code> pointer
+ if there is no <code class="literal">OLD TABLE</code> transition relation.
+ </p></dd><dt><span class="term"><code class="structfield">tg_newtable</code></span></dt><dd><p>
+ A pointer to a structure of type <code class="structname">Tuplestorestate</code>
+ containing zero or more rows in the format specified by
+ <code class="structfield">tg_relation</code>, or a <code class="symbol">NULL</code> pointer
+ if there is no <code class="literal">NEW TABLE</code> transition relation.
+ </p></dd><dt><span class="term"><code class="structfield">tg_updatedcols</code></span></dt><dd><p>
+ For <code class="literal">UPDATE</code> triggers, a bitmap set indicating the
+ columns that were updated by the triggering command. Generic trigger
+ functions can use this to optimize actions by not having to deal with
+ columns that were not changed.
+ </p><p>
+ As an example, to determine whether a column with attribute number
+ <code class="varname">attnum</code> (1-based) is a member of this bitmap set,
+ call <code class="literal">bms_is_member(attnum -
+ FirstLowInvalidHeapAttributeNumber,
+ trigdata-&gt;tg_updatedcols))</code>.
+ </p><p>
+ For triggers other than <code class="literal">UPDATE</code> triggers, this will
+ be <code class="symbol">NULL</code>.
+ </p></dd></dl></div><p>
+ </p><p>
+ To allow queries issued through SPI to reference transition tables, see
+ <a class="xref" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data"><span class="refentrytitle">SPI_register_trigger_data</span></a>.
+ </p><p>
+ A trigger function must return either a
+ <code class="structname">HeapTuple</code> pointer or a <code class="symbol">NULL</code> pointer
+ (<span class="emphasis"><em>not</em></span> an SQL null value, that is, do not set <em class="parameter"><code>isNull</code></em> true).
+ Be careful to return either
+ <code class="structfield">tg_trigtuple</code> or <code class="structfield">tg_newtuple</code>,
+ as appropriate, if you don't want to modify the row being operated on.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="trigger-datachanges.html" title="39.2. Visibility of Data Changes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="triggers.html" title="Chapter 39. Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="trigger-example.html" title="39.4. A Complete Trigger Example">Next</a></td></tr><tr><td width="40%" align="left" valign="top">39.2. Visibility of Data Changes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 39.4. A Complete Trigger Example</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/triggers.html b/doc/src/sgml/html/triggers.html
new file mode 100644
index 0000000..9c707c4
--- /dev/null
+++ b/doc/src/sgml/html/triggers.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 39. Triggers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure" /><link rel="next" href="trigger-definition.html" title="39.1. Overview of Trigger Behavior" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 39. Triggers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="trigger-definition.html" title="39.1. Overview of Trigger Behavior">Next</a></td></tr></table><hr /></div><div class="chapter" id="TRIGGERS"><div class="titlepage"><div><div><h2 class="title">Chapter 39. Triggers</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="trigger-definition.html">39.1. Overview of Trigger Behavior</a></span></dt><dt><span class="sect1"><a href="trigger-datachanges.html">39.2. Visibility of Data Changes</a></span></dt><dt><span class="sect1"><a href="trigger-interface.html">39.3. Writing Trigger Functions in C</a></span></dt><dt><span class="sect1"><a href="trigger-example.html">39.4. A Complete Trigger Example</a></span></dt></dl></div><a id="id-1.8.4.2" class="indexterm"></a><p>
+ This chapter provides general information about writing trigger functions.
+ Trigger functions can be written in most of the available procedural
+ languages, including
+ <span class="application">PL/pgSQL</span> (<a class="xref" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Chapter 43</a>),
+ <span class="application">PL/Tcl</span> (<a class="xref" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Chapter 44</a>),
+ <span class="application">PL/Perl</span> (<a class="xref" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Chapter 45</a>), and
+ <span class="application">PL/Python</span> (<a class="xref" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Chapter 46</a>).
+ After reading this chapter, you should consult the chapter for
+ your favorite procedural language to find out the language-specific
+ details of writing a trigger in it.
+ </p><p>
+ It is also possible to write a trigger function in C, although
+ most people find it easier to use one of the procedural languages.
+ It is not currently possible to write a trigger function in the
+ plain SQL function language.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="extend-pgxs.html" title="38.18. Extension Building Infrastructure">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="trigger-definition.html" title="39.1. Overview of Trigger Behavior">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.18. Extension Building Infrastructure </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 39.1. Overview of Trigger Behavior</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tsm-system-rows.html b/doc/src/sgml/html/tsm-system-rows.html
new file mode 100644
index 0000000..517846c
--- /dev/null
+++ b/doc/src/sgml/html/tsm-system-rows.html
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.46. tsm_system_rows</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="test-decoding.html" title="F.45. test_decoding" /><link rel="next" href="tsm-system-time.html" title="F.47. tsm_system_time" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.46. tsm_system_rows</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="test-decoding.html" title="F.45. test_decoding">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tsm-system-time.html" title="F.47. tsm_system_time">Next</a></td></tr></table><hr /></div><div class="sect1" id="TSM-SYSTEM-ROWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.46. tsm_system_rows</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="tsm-system-rows.html#id-1.11.7.55.8">F.46.1. Examples</a></span></dt></dl></div><a id="id-1.11.7.55.2" class="indexterm"></a><p>
+ The <code class="filename">tsm_system_rows</code> module provides the table sampling method
+ <code class="literal">SYSTEM_ROWS</code>, which can be used in
+ the <code class="literal">TABLESAMPLE</code> clause of a <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a>
+ command.
+ </p><p>
+ This table sampling method accepts a single integer argument that is the
+ maximum number of rows to read. The resulting sample will always contain
+ exactly that many rows, unless the table does not contain enough rows, in
+ which case the whole table is selected.
+ </p><p>
+ Like the built-in <code class="literal">SYSTEM</code> sampling
+ method, <code class="literal">SYSTEM_ROWS</code> performs block-level sampling, so
+ that the sample is not completely random but may be subject to clustering
+ effects, especially if only a small number of rows are requested.
+ </p><p>
+ <code class="literal">SYSTEM_ROWS</code> does not support
+ the <code class="literal">REPEATABLE</code> clause.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.55.8"><div class="titlepage"><div><div><h3 class="title">F.46.1. Examples</h3></div></div></div><p>
+ Here is an example of selecting a sample of a table with
+ <code class="literal">SYSTEM_ROWS</code>. First install the extension:
+ </p><pre class="programlisting">
+CREATE EXTENSION tsm_system_rows;
+</pre><p>
+ Then you can use it in a <code class="command">SELECT</code> command, for instance:
+
+</p><pre class="programlisting">
+SELECT * FROM my_table TABLESAMPLE SYSTEM_ROWS(100);
+</pre><p>
+ </p><p>
+ This command will return a sample of 100 rows from the
+ table <code class="structname">my_table</code> (unless the table does not have 100
+ visible rows, in which case all its rows are returned).
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="test-decoding.html" title="F.45. test_decoding">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tsm-system-time.html" title="F.47. tsm_system_time">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.45. test_decoding </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.47. tsm_system_time</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tsm-system-time.html b/doc/src/sgml/html/tsm-system-time.html
new file mode 100644
index 0000000..08db18b
--- /dev/null
+++ b/doc/src/sgml/html/tsm-system-time.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.47. tsm_system_time</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tsm-system-rows.html" title="F.46. tsm_system_rows" /><link rel="next" href="unaccent.html" title="F.48. unaccent" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.47. tsm_system_time</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tsm-system-rows.html" title="F.46. tsm_system_rows">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="unaccent.html" title="F.48. unaccent">Next</a></td></tr></table><hr /></div><div class="sect1" id="TSM-SYSTEM-TIME"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.47. tsm_system_time</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="tsm-system-time.html#id-1.11.7.56.8">F.47.1. Examples</a></span></dt></dl></div><a id="id-1.11.7.56.2" class="indexterm"></a><p>
+ The <code class="filename">tsm_system_time</code> module provides the table sampling method
+ <code class="literal">SYSTEM_TIME</code>, which can be used in
+ the <code class="literal">TABLESAMPLE</code> clause of a <a class="link" href="sql-select.html" title="SELECT"><code class="command">SELECT</code></a>
+ command.
+ </p><p>
+ This table sampling method accepts a single floating-point argument that
+ is the maximum number of milliseconds to spend reading the table. This
+ gives you direct control over how long the query takes, at the price that
+ the size of the sample becomes hard to predict. The resulting sample will
+ contain as many rows as could be read in the specified time, unless the
+ whole table has been read first.
+ </p><p>
+ Like the built-in <code class="literal">SYSTEM</code> sampling
+ method, <code class="literal">SYSTEM_TIME</code> performs block-level sampling, so
+ that the sample is not completely random but may be subject to clustering
+ effects, especially if only a small number of rows are selected.
+ </p><p>
+ <code class="literal">SYSTEM_TIME</code> does not support
+ the <code class="literal">REPEATABLE</code> clause.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.56.8"><div class="titlepage"><div><div><h3 class="title">F.47.1. Examples</h3></div></div></div><p>
+ Here is an example of selecting a sample of a table with
+ <code class="literal">SYSTEM_TIME</code>. First install the extension:
+ </p><pre class="programlisting">
+CREATE EXTENSION tsm_system_time;
+</pre><p>
+ Then you can use it in a <code class="command">SELECT</code> command, for instance:
+
+</p><pre class="programlisting">
+SELECT * FROM my_table TABLESAMPLE SYSTEM_TIME(1000);
+</pre><p>
+ </p><p>
+ This command will return as large a sample of <code class="structname">my_table</code> as
+ it can read in 1 second (1000 milliseconds). Of course, if the whole
+ table can be read in under 1 second, all its rows will be returned.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tsm-system-rows.html" title="F.46. tsm_system_rows">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="unaccent.html" title="F.48. unaccent">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.46. tsm_system_rows </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.48. unaccent</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-accessdb.html b/doc/src/sgml/html/tutorial-accessdb.html
new file mode 100644
index 0000000..fcc55c3
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-accessdb.html
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>1.4. Accessing a Database</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-createdb.html" title="1.3. Creating a Database" /><link rel="next" href="tutorial-sql.html" title="Chapter 2. The SQL Language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">1.4. Accessing a Database</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-createdb.html" title="1.3. Creating a Database">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><th width="60%" align="center">Chapter 1. Getting Started</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-ACCESSDB"><div class="titlepage"><div><div><h2 class="title" style="clear: both">1.4. Accessing a Database</h2></div></div></div><a id="id-1.4.3.5.2" class="indexterm"></a><p>
+ Once you have created a database, you can access it by:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: bullet; "><li class="listitem" style="list-style-type: disc"><p>
+ Running the <span class="productname">PostgreSQL</span> interactive
+ terminal program, called <span class="application"><em class="firstterm">psql</em></span>, which allows you
+ to interactively enter, edit, and execute
+ <acronym class="acronym">SQL</acronym> commands.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Using an existing graphical frontend tool like
+ <span class="application">pgAdmin</span> or an office suite with
+ <acronym class="acronym">ODBC</acronym> or <acronym class="acronym">JDBC</acronym> support to create and manipulate a
+ database. These possibilities are not covered in this
+ tutorial.
+ </p></li><li class="listitem" style="list-style-type: disc"><p>
+ Writing a custom application, using one of the several
+ available language bindings. These possibilities are discussed
+ further in <a class="xref" href="client-interfaces.html" title="Part IV. Client Interfaces">Part IV</a>.
+ </p></li></ul></div><p>
+
+ You probably want to start up <code class="command">psql</code> to try
+ the examples in this tutorial. It can be activated for the
+ <code class="literal">mydb</code> database by typing the command:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>psql mydb</code></strong>
+</pre><p>
+ If you do not supply the database name then it will default to your
+ user account name. You already discovered this scheme in the
+ previous section using <code class="command">createdb</code>.
+ </p><p>
+ In <code class="command">psql</code>, you will be greeted with the following
+ message:
+</p><pre class="screen">
+psql (15.4)
+Type "help" for help.
+
+mydb=&gt;
+</pre><p>
+ <a id="id-1.4.3.5.4.3" class="indexterm"></a>
+ The last line could also be:
+</p><pre class="screen">
+mydb=#
+</pre><p>
+ That would mean you are a database superuser, which is most likely
+ the case if you installed the <span class="productname">PostgreSQL</span> instance
+ yourself. Being a superuser means that you are not subject to
+ access controls. For the purposes of this tutorial that is not
+ important.
+ </p><p>
+ If you encounter problems starting <code class="command">psql</code>
+ then go back to the previous section. The diagnostics of
+ <code class="command">createdb</code> and <code class="command">psql</code> are
+ similar, and if the former worked the latter should work as well.
+ </p><p>
+ The last line printed out by <code class="command">psql</code> is the
+ prompt, and it indicates that <code class="command">psql</code> is listening
+ to you and that you can type <acronym class="acronym">SQL</acronym> queries into a
+ work space maintained by <code class="command">psql</code>. Try out these
+ commands:
+ <a id="id-1.4.3.5.6.5" class="indexterm"></a>
+</p><pre class="screen">
+<code class="prompt">mydb=&gt;</code> <strong class="userinput"><code>SELECT version();</code></strong>
+ version
+-------------------------------------------------------------------​-----------------------
+ PostgreSQL 15.4 on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
+(1 row)
+
+<code class="prompt">mydb=&gt;</code> <strong class="userinput"><code>SELECT current_date;</code></strong>
+ date
+------------
+ 2016-01-07
+(1 row)
+
+<code class="prompt">mydb=&gt;</code> <strong class="userinput"><code>SELECT 2 + 2;</code></strong>
+ ?column?
+----------
+ 4
+(1 row)
+</pre><p>
+ </p><p>
+ The <code class="command">psql</code> program has a number of internal
+ commands that are not SQL commands. They begin with the backslash
+ character, <span class="quote">“<span class="quote"><code class="literal">\</code></span>”</span>.
+ For example,
+ you can get help on the syntax of various
+ <span class="productname">PostgreSQL</span> <acronym class="acronym">SQL</acronym>
+ commands by typing:
+</p><pre class="screen">
+<code class="prompt">mydb=&gt;</code> <strong class="userinput"><code>\h</code></strong>
+</pre><p>
+ </p><p>
+ To get out of <code class="command">psql</code>, type:
+</p><pre class="screen">
+<code class="prompt">mydb=&gt;</code> <strong class="userinput"><code>\q</code></strong>
+</pre><p>
+ and <code class="command">psql</code> will quit and return you to your
+ command shell. (For more internal commands, type
+ <code class="literal">\?</code> at the <code class="command">psql</code> prompt.) The
+ full capabilities of <code class="command">psql</code> are documented in
+ <a class="xref" href="app-psql.html" title="psql"><span class="refentrytitle"><span class="application">psql</span></span></a>. In this tutorial we will not use these
+ features explicitly, but you can use them yourself when it is helpful.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-createdb.html" title="1.3. Creating a Database">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1.3. Creating a Database </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 2. The <acronym class="acronym">SQL</acronym> Language</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-advanced-intro.html b/doc/src/sgml/html/tutorial-advanced-intro.html
new file mode 100644
index 0000000..c08a142
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-advanced-intro.html
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-advanced.html" title="Chapter 3. Advanced Features" /><link rel="next" href="tutorial-views.html" title="3.2. Views" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-views.html" title="3.2. Views">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-ADVANCED-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.1. Introduction</h2></div></div></div><p>
+ In the previous chapter we have covered the basics of using
+ <acronym class="acronym">SQL</acronym> to store and access your data in
+ <span class="productname">PostgreSQL</span>. We will now discuss some
+ more advanced features of <acronym class="acronym">SQL</acronym> that simplify
+ management and prevent loss or corruption of your data. Finally,
+ we will look at some <span class="productname">PostgreSQL</span>
+ extensions.
+ </p><p>
+ This chapter will on occasion refer to examples found in <a class="xref" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Chapter 2</a> to change or improve them, so it will be
+ useful to have read that chapter. Some examples from
+ this chapter can also be found in
+ <code class="filename">advanced.sql</code> in the tutorial directory. This
+ file also contains some sample data to load, which is not
+ repeated here. (Refer to <a class="xref" href="tutorial-sql-intro.html" title="2.1. Introduction">Section 2.1</a> for
+ how to use the file.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-views.html" title="3.2. Views">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 3. Advanced Features </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.2. Views</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-advanced.html b/doc/src/sgml/html/tutorial-advanced.html
new file mode 100644
index 0000000..9638b93
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-advanced.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 3. Advanced Features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-delete.html" title="2.9. Deletions" /><link rel="next" href="tutorial-advanced-intro.html" title="3.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 3. Advanced Features</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-delete.html" title="2.9. Deletions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial.html" title="Part I. Tutorial">Up</a></td><th width="60%" align="center">Part I. Tutorial</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-advanced-intro.html" title="3.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="TUTORIAL-ADVANCED"><div class="titlepage"><div><div><h2 class="title">Chapter 3. Advanced Features</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="tutorial-advanced-intro.html">3.1. Introduction</a></span></dt><dt><span class="sect1"><a href="tutorial-views.html">3.2. Views</a></span></dt><dt><span class="sect1"><a href="tutorial-fk.html">3.3. Foreign Keys</a></span></dt><dt><span class="sect1"><a href="tutorial-transactions.html">3.4. Transactions</a></span></dt><dt><span class="sect1"><a href="tutorial-window.html">3.5. Window Functions</a></span></dt><dt><span class="sect1"><a href="tutorial-inheritance.html">3.6. Inheritance</a></span></dt><dt><span class="sect1"><a href="tutorial-conclusion.html">3.7. Conclusion</a></span></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-delete.html" title="2.9. Deletions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial.html" title="Part I. Tutorial">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-advanced-intro.html" title="3.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.9. Deletions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-agg.html b/doc/src/sgml/html/tutorial-agg.html
new file mode 100644
index 0000000..ce160e7
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-agg.html
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.7. Aggregate Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-join.html" title="2.6. Joins Between Tables" /><link rel="next" href="tutorial-update.html" title="2.8. Updates" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.7. Aggregate Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-join.html" title="2.6. Joins Between Tables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-update.html" title="2.8. Updates">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-AGG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.7. Aggregate Functions</h2></div></div></div><a id="id-1.4.4.8.2" class="indexterm"></a><p>
+ Like most other relational database products,
+ <span class="productname">PostgreSQL</span> supports
+ <em class="firstterm">aggregate functions</em>.
+ An aggregate function computes a single result from multiple input rows.
+ For example, there are aggregates to compute the
+ <code class="function">count</code>, <code class="function">sum</code>,
+ <code class="function">avg</code> (average), <code class="function">max</code> (maximum) and
+ <code class="function">min</code> (minimum) over a set of rows.
+ </p><p>
+ As an example, we can find the highest low-temperature reading anywhere
+ with:
+
+</p><pre class="programlisting">
+SELECT max(temp_lo) FROM weather;
+</pre><p>
+
+</p><pre class="screen">
+ max
+-----
+ 46
+(1 row)
+</pre><p>
+ </p><p>
+ <a id="id-1.4.4.8.5.1" class="indexterm"></a>
+
+ If we wanted to know what city (or cities) that reading occurred in,
+ we might try:
+
+</p><pre class="programlisting">
+SELECT city FROM weather WHERE temp_lo = max(temp_lo); <em class="lineannotation"><span class="lineannotation">WRONG</span></em>
+</pre><p>
+
+ but this will not work since the aggregate
+ <code class="function">max</code> cannot be used in the
+ <code class="literal">WHERE</code> clause. (This restriction exists because
+ the <code class="literal">WHERE</code> clause determines which rows will be
+ included in the aggregate calculation; so obviously it has to be evaluated
+ before aggregate functions are computed.)
+ However, as is often the case
+ the query can be restated to accomplish the desired result, here
+ by using a <em class="firstterm">subquery</em>:
+
+</p><pre class="programlisting">
+SELECT city FROM weather
+ WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
+</pre><p>
+
+</p><pre class="screen">
+ city
+---------------
+ San Francisco
+(1 row)
+</pre><p>
+
+ This is OK because the subquery is an independent computation
+ that computes its own aggregate separately from what is happening
+ in the outer query.
+ </p><p>
+ <a id="id-1.4.4.8.6.1" class="indexterm"></a>
+ <a id="id-1.4.4.8.6.2" class="indexterm"></a>
+
+ Aggregates are also very useful in combination with <code class="literal">GROUP
+ BY</code> clauses. For example, we can get the number of readings
+ and the maximum low temperature observed in each city with:
+
+</p><pre class="programlisting">
+SELECT city, count(*), max(temp_lo)
+ FROM weather
+ GROUP BY city;
+</pre><p>
+
+</p><pre class="screen">
+ city | count | max
+---------------+-------+-----
+ Hayward | 1 | 37
+ San Francisco | 2 | 46
+(2 rows)
+</pre><p>
+
+ which gives us one output row per city. Each aggregate result is
+ computed over the table rows matching that city.
+ We can filter these grouped
+ rows using <code class="literal">HAVING</code>:
+
+</p><pre class="programlisting">
+SELECT city, count(*), max(temp_lo)
+ FROM weather
+ GROUP BY city
+ HAVING max(temp_lo) &lt; 40;
+</pre><p>
+
+</p><pre class="screen">
+ city | count | max
+---------+-------+-----
+ Hayward | 1 | 37
+(1 row)
+</pre><p>
+
+ which gives us the same results for only the cities that have all
+ <code class="structfield">temp_lo</code> values below 40. Finally, if we only care about
+ cities whose
+ names begin with <span class="quote">“<span class="quote"><code class="literal">S</code></span>”</span>, we might do:
+
+</p><pre class="programlisting">
+SELECT city, count(*), max(temp_lo)
+ FROM weather
+ WHERE city LIKE 'S%' -- <span id="co.tutorial-agg-like"></span>(1)
+ GROUP BY city;
+</pre><p>
+
+</p><pre class="screen">
+ city | count | max
+---------------+-------+-----
+ San Francisco | 2 | 46
+(1 row)
+</pre><p>
+ </p><div class="calloutlist"><table border="0" summary="Callout list"><tr><td width="5%" valign="top" align="left"><p><a href="#co.tutorial-agg-like">(1)</a> </p></td><td valign="top" align="left"><p>
+ The <code class="literal">LIKE</code> operator does pattern matching and
+ is explained in <a class="xref" href="functions-matching.html" title="9.7. Pattern Matching">Section 9.7</a>.
+ </p></td></tr></table></div><p>
+ </p><p>
+ It is important to understand the interaction between aggregates and
+ <acronym class="acronym">SQL</acronym>'s <code class="literal">WHERE</code> and <code class="literal">HAVING</code> clauses.
+ The fundamental difference between <code class="literal">WHERE</code> and
+ <code class="literal">HAVING</code> is this: <code class="literal">WHERE</code> selects
+ input rows before groups and aggregates are computed (thus, it controls
+ which rows go into the aggregate computation), whereas
+ <code class="literal">HAVING</code> selects group rows after groups and
+ aggregates are computed. Thus, the
+ <code class="literal">WHERE</code> clause must not contain aggregate functions;
+ it makes no sense to try to use an aggregate to determine which rows
+ will be inputs to the aggregates. On the other hand, the
+ <code class="literal">HAVING</code> clause always contains aggregate functions.
+ (Strictly speaking, you are allowed to write a <code class="literal">HAVING</code>
+ clause that doesn't use aggregates, but it's seldom useful. The same
+ condition could be used more efficiently at the <code class="literal">WHERE</code>
+ stage.)
+ </p><p>
+ In the previous example, we can apply the city name restriction in
+ <code class="literal">WHERE</code>, since it needs no aggregate. This is
+ more efficient than adding the restriction to <code class="literal">HAVING</code>,
+ because we avoid doing the grouping and aggregate calculations
+ for all rows that fail the <code class="literal">WHERE</code> check.
+ </p><p>
+ Another way to select the rows that go into an aggregate
+ computation is to use <code class="literal">FILTER</code>, which is a
+ per-aggregate option:
+
+</p><pre class="programlisting">
+SELECT city, count(*) FILTER (WHERE temp_lo &lt; 45), max(temp_lo)
+ FROM weather
+ GROUP BY city;
+</pre><p>
+
+</p><pre class="screen">
+ city | count | max
+---------------+-------+-----
+ Hayward | 1 | 37
+ San Francisco | 1 | 46
+(2 rows)
+</pre><p>
+
+ <code class="literal">FILTER</code> is much like <code class="literal">WHERE</code>,
+ except that it removes rows only from the input of the particular
+ aggregate function that it is attached to.
+ Here, the <code class="literal">count</code> aggregate counts only
+ rows with <code class="literal">temp_lo</code> below 45; but the
+ <code class="literal">max</code> aggregate is still applied to all rows,
+ so it still finds the reading of 46.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-join.html" title="2.6. Joins Between Tables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-update.html" title="2.8. Updates">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.6. Joins Between Tables </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.8. Updates</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-arch.html b/doc/src/sgml/html/tutorial-arch.html
new file mode 100644
index 0000000..d319cbc
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-arch.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>1.2. Architectural Fundamentals</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-install.html" title="1.1. Installation" /><link rel="next" href="tutorial-createdb.html" title="1.3. Creating a Database" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">1.2. Architectural Fundamentals</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-install.html" title="1.1. Installation">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><th width="60%" align="center">Chapter 1. Getting Started</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-createdb.html" title="1.3. Creating a Database">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-ARCH"><div class="titlepage"><div><div><h2 class="title" style="clear: both">1.2. Architectural Fundamentals</h2></div></div></div><p>
+ Before we proceed, you should understand the basic
+ <span class="productname">PostgreSQL</span> system architecture.
+ Understanding how the parts of
+ <span class="productname">PostgreSQL</span> interact will make this
+ chapter somewhat clearer.
+ </p><p>
+ In database jargon, <span class="productname">PostgreSQL</span> uses a
+ client/server model. A <span class="productname">PostgreSQL</span>
+ session consists of the following cooperating processes
+ (programs):
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A server process, which manages the database files, accepts
+ connections to the database from client applications, and
+ performs database actions on behalf of the clients. The
+ database server program is called
+ <code class="filename">postgres</code>.
+ <a id="id-1.4.3.3.3.3.1.1.2" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ The user's client (frontend) application that wants to perform
+ database operations. Client applications can be very diverse
+ in nature: a client could be a text-oriented tool, a graphical
+ application, a web server that accesses the database to
+ display web pages, or a specialized database maintenance tool.
+ Some client applications are supplied with the
+ <span class="productname">PostgreSQL</span> distribution; most are
+ developed by users.
+ </p></li></ul></div><p>
+ </p><p>
+ As is typical of client/server applications, the client and the
+ server can be on different hosts. In that case they communicate
+ over a TCP/IP network connection. You should keep this in mind,
+ because the files that can be accessed on a client machine might
+ not be accessible (or might only be accessible using a different
+ file name) on the database server machine.
+ </p><p>
+ The <span class="productname">PostgreSQL</span> server can handle
+ multiple concurrent connections from clients. To achieve this it
+ starts (<span class="quote">“<span class="quote">forks</span>”</span>) a new process for each connection.
+ From that point on, the client and the new server process
+ communicate without intervention by the original
+ <code class="filename">postgres</code> process. Thus, the
+ supervisor server process is always running, waiting for
+ client connections, whereas client and associated server processes
+ come and go. (All of this is of course invisible to the user. We
+ only mention it here for completeness.)
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-install.html" title="1.1. Installation">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-createdb.html" title="1.3. Creating a Database">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1.1. Installation </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 1.3. Creating a Database</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-concepts.html b/doc/src/sgml/html/tutorial-concepts.html
new file mode 100644
index 0000000..0aecc86
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-concepts.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.2. Concepts</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-sql-intro.html" title="2.1. Introduction" /><link rel="next" href="tutorial-table.html" title="2.3. Creating a New Table" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.2. Concepts</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-sql-intro.html" title="2.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-table.html" title="2.3. Creating a New Table">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-CONCEPTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.2. Concepts</h2></div></div></div><p>
+ <a id="id-1.4.4.3.2.1" class="indexterm"></a>
+ <a id="id-1.4.4.3.2.2" class="indexterm"></a>
+ <a id="id-1.4.4.3.2.3" class="indexterm"></a>
+ <a id="id-1.4.4.3.2.4" class="indexterm"></a>
+ <a id="id-1.4.4.3.2.5" class="indexterm"></a>
+
+ <span class="productname">PostgreSQL</span> is a <em class="firstterm">relational
+ database management system</em> (<acronym class="acronym">RDBMS</acronym>).
+ That means it is a system for managing data stored in
+ <em class="firstterm">relations</em>. Relation is essentially a
+ mathematical term for <em class="firstterm">table</em>. The notion of
+ storing data in tables is so commonplace today that it might
+ seem inherently obvious, but there are a number of other ways of
+ organizing databases. Files and directories on Unix-like
+ operating systems form an example of a hierarchical database. A
+ more modern development is the object-oriented database.
+ </p><p>
+ <a id="id-1.4.4.3.3.1" class="indexterm"></a>
+ <a id="id-1.4.4.3.3.2" class="indexterm"></a>
+
+ Each table is a named collection of <em class="firstterm">rows</em>.
+ Each row of a given table has the same set of named
+ <em class="firstterm">columns</em>,
+ and each column is of a specific data type. Whereas columns have
+ a fixed order in each row, it is important to remember that SQL
+ does not guarantee the order of the rows within the table in any
+ way (although they can be explicitly sorted for display).
+ </p><p>
+ <a id="id-1.4.4.3.4.1" class="indexterm"></a>
+ <a id="id-1.4.4.3.4.2" class="indexterm"></a>
+
+ Tables are grouped into databases, and a collection of databases
+ managed by a single <span class="productname">PostgreSQL</span> server
+ instance constitutes a database <em class="firstterm">cluster</em>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-sql-intro.html" title="2.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-table.html" title="2.3. Creating a New Table">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.3. Creating a New Table</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-conclusion.html b/doc/src/sgml/html/tutorial-conclusion.html
new file mode 100644
index 0000000..db80eac
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-conclusion.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.7. Conclusion</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-inheritance.html" title="3.6. Inheritance" /><link rel="next" href="sql.html" title="Part II. The SQL Language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.7. Conclusion</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-inheritance.html" title="3.6. Inheritance">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql.html" title="Part II. The SQL Language">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-CONCLUSION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.7. Conclusion</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> has many features not
+ touched upon in this tutorial introduction, which has been
+ oriented toward newer users of <acronym class="acronym">SQL</acronym>. These
+ features are discussed in more detail in the remainder of this
+ book.
+ </p><p>
+ If you feel you need more introductory material, please visit the PostgreSQL
+ <a class="ulink" href="https://www.postgresql.org" target="_top">web site</a>
+ for links to more resources.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-inheritance.html" title="3.6. Inheritance">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql.html" title="Part II. The SQL Language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.6. Inheritance </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Part II. The SQL Language</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-createdb.html b/doc/src/sgml/html/tutorial-createdb.html
new file mode 100644
index 0000000..77e6a55
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-createdb.html
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>1.3. Creating a Database</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-arch.html" title="1.2. Architectural Fundamentals" /><link rel="next" href="tutorial-accessdb.html" title="1.4. Accessing a Database" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">1.3. Creating a Database</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-arch.html" title="1.2. Architectural Fundamentals">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><th width="60%" align="center">Chapter 1. Getting Started</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-accessdb.html" title="1.4. Accessing a Database">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-CREATEDB"><div class="titlepage"><div><div><h2 class="title" style="clear: both">1.3. Creating a Database</h2></div></div></div><a id="id-1.4.3.4.2" class="indexterm"></a><a id="id-1.4.3.4.3" class="indexterm"></a><p>
+ The first test to see whether you can access the database server
+ is to try to create a database. A running
+ <span class="productname">PostgreSQL</span> server can manage many
+ databases. Typically, a separate database is used for each
+ project or for each user.
+ </p><p>
+ Possibly, your site administrator has already created a database
+ for your use. In that case you can omit this step and skip ahead
+ to the next section.
+ </p><p>
+ To create a new database, in this example named
+ <code class="literal">mydb</code>, you use the following command:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>createdb mydb</code></strong>
+</pre><p>
+ If this produces no response then this step was successful and you can skip over the
+ remainder of this section.
+ </p><p>
+ If you see a message similar to:
+</p><pre class="screen">
+createdb: command not found
+</pre><p>
+ then <span class="productname">PostgreSQL</span> was not installed properly. Either it was not
+ installed at all or your shell's search path was not set to include it.
+ Try calling the command with an absolute path instead:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>/usr/local/pgsql/bin/createdb mydb</code></strong>
+</pre><p>
+ The path at your site might be different. Contact your site
+ administrator or check the installation instructions to
+ correct the situation.
+ </p><p>
+ Another response could be this:
+</p><pre class="screen">
+createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
+ Is the server running locally and accepting connections on that socket?
+</pre><p>
+ This means that the server was not started, or it is not listening
+ where <code class="command">createdb</code> expects to contact it. Again, check the
+ installation instructions or consult the administrator.
+ </p><p>
+ Another response could be this:
+</p><pre class="screen">
+createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: role "joe" does not exist
+</pre><p>
+ where your own login name is mentioned. This will happen if the
+ administrator has not created a <span class="productname">PostgreSQL</span> user account
+ for you. (<span class="productname">PostgreSQL</span> user accounts are distinct from
+ operating system user accounts.) If you are the administrator, see
+ <a class="xref" href="user-manag.html" title="Chapter 22. Database Roles">Chapter 22</a> for help creating accounts. You will need to
+ become the operating system user under which <span class="productname">PostgreSQL</span>
+ was installed (usually <code class="literal">postgres</code>) to create the first user
+ account. It could also be that you were assigned a
+ <span class="productname">PostgreSQL</span> user name that is different from your
+ operating system user name; in that case you need to use the <code class="option">-U</code>
+ switch or set the <code class="envar">PGUSER</code> environment variable to specify your
+ <span class="productname">PostgreSQL</span> user name.
+ </p><p>
+ If you have a user account but it does not have the privileges required to
+ create a database, you will see the following:
+</p><pre class="screen">
+createdb: error: database creation failed: ERROR: permission denied to create database
+</pre><p>
+ Not every user has authorization to create new databases. If
+ <span class="productname">PostgreSQL</span> refuses to create databases
+ for you then the site administrator needs to grant you permission
+ to create databases. Consult your site administrator if this
+ occurs. If you installed <span class="productname">PostgreSQL</span>
+ yourself then you should log in for the purposes of this tutorial
+ under the user account that you started the server as.
+
+ <a href="#ftn.id-1.4.3.4.10.4" class="footnote"><sup class="footnote" id="id-1.4.3.4.10.4">[1]</sup></a>
+ </p><p>
+ You can also create databases with other names.
+ <span class="productname">PostgreSQL</span> allows you to create any
+ number of databases at a given site. Database names must have an
+ alphabetic first character and are limited to 63 bytes in
+ length. A convenient choice is to create a database with the same
+ name as your current user name. Many tools assume that database
+ name as the default, so it can save you some typing. To create
+ that database, simply type:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>createdb</code></strong>
+</pre><p>
+ </p><p>
+ If you do not want to use your database anymore you can remove it.
+ For example, if you are the owner (creator) of the database
+ <code class="literal">mydb</code>, you can destroy it using the following
+ command:
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>dropdb mydb</code></strong>
+</pre><p>
+ (For this command, the database name does not default to the user
+ account name. You always need to specify it.) This action
+ physically removes all files associated with the database and
+ cannot be undone, so this should only be done with a great deal of
+ forethought.
+ </p><p>
+ More about <code class="command">createdb</code> and <code class="command">dropdb</code> can
+ be found in <a class="xref" href="app-createdb.html" title="createdb"><span class="refentrytitle"><span class="application">createdb</span></span></a> and <a class="xref" href="app-dropdb.html" title="dropdb"><span class="refentrytitle"><span class="application">dropdb</span></span></a>
+ respectively.
+ </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.4.3.4.10.4" class="footnote"><p><a href="#id-1.4.3.4.10.4" class="para"><sup class="para">[1] </sup></a>
+ As an explanation for why this works:
+ <span class="productname">PostgreSQL</span> user names are separate
+ from operating system user accounts. When you connect to a
+ database, you can choose what
+ <span class="productname">PostgreSQL</span> user name to connect as;
+ if you don't, it will default to the same name as your current
+ operating system account. As it happens, there will always be a
+ <span class="productname">PostgreSQL</span> user account that has the
+ same name as the operating system user that started the server,
+ and it also happens that that user always has permission to
+ create databases. Instead of logging in as that user you can
+ also specify the <code class="option">-U</code> option everywhere to select
+ a <span class="productname">PostgreSQL</span> user name to connect as.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-arch.html" title="1.2. Architectural Fundamentals">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-accessdb.html" title="1.4. Accessing a Database">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1.2. Architectural Fundamentals </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 1.4. Accessing a Database</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-delete.html b/doc/src/sgml/html/tutorial-delete.html
new file mode 100644
index 0000000..d09c58e
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-delete.html
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.9. Deletions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-update.html" title="2.8. Updates" /><link rel="next" href="tutorial-advanced.html" title="Chapter 3. Advanced Features" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.9. Deletions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-update.html" title="2.8. Updates">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-DELETE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.9. Deletions</h2></div></div></div><a id="id-1.4.4.10.2" class="indexterm"></a><p>
+ Rows can be removed from a table using the <code class="command">DELETE</code>
+ command.
+ Suppose you are no longer interested in the weather of Hayward.
+ Then you can do the following to delete those rows from the table:
+</p><pre class="programlisting">
+DELETE FROM weather WHERE city = 'Hayward';
+</pre><p>
+
+ All weather records belonging to Hayward are removed.
+
+</p><pre class="programlisting">
+SELECT * FROM weather;
+</pre><p>
+
+</p><pre class="screen">
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 41 | 55 | 0 | 1994-11-29
+(2 rows)
+</pre><p>
+ </p><p>
+ One should be wary of statements of the form
+</p><pre class="synopsis">
+DELETE FROM <em class="replaceable"><code>tablename</code></em>;
+</pre><p>
+
+ Without a qualification, <code class="command">DELETE</code> will
+ remove <span class="emphasis"><em>all</em></span> rows from the given table, leaving it
+ empty. The system will not request confirmation before
+ doing this!
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-update.html" title="2.8. Updates">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.8. Updates </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 3. Advanced Features</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-fk.html b/doc/src/sgml/html/tutorial-fk.html
new file mode 100644
index 0000000..18fe17d
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-fk.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.3. Foreign Keys</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-views.html" title="3.2. Views" /><link rel="next" href="tutorial-transactions.html" title="3.4. Transactions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.3. Foreign Keys</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-views.html" title="3.2. Views">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-transactions.html" title="3.4. Transactions">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-FK"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.3. Foreign Keys</h2></div></div></div><a id="id-1.4.5.4.2" class="indexterm"></a><a id="id-1.4.5.4.3" class="indexterm"></a><p>
+ Recall the <code class="classname">weather</code> and
+ <code class="classname">cities</code> tables from <a class="xref" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Chapter 2</a>. Consider the following problem: You
+ want to make sure that no one can insert rows in the
+ <code class="classname">weather</code> table that do not have a matching
+ entry in the <code class="classname">cities</code> table. This is called
+ maintaining the <em class="firstterm">referential integrity</em> of
+ your data. In simplistic database systems this would be
+ implemented (if at all) by first looking at the
+ <code class="classname">cities</code> table to check if a matching record
+ exists, and then inserting or rejecting the new
+ <code class="classname">weather</code> records. This approach has a
+ number of problems and is very inconvenient, so
+ <span class="productname">PostgreSQL</span> can do this for you.
+ </p><p>
+ The new declaration of the tables would look like this:
+
+</p><pre class="programlisting">
+CREATE TABLE cities (
+ name varchar(80) primary key,
+ location point
+);
+
+CREATE TABLE weather (
+ city varchar(80) references cities(name),
+ temp_lo int,
+ temp_hi int,
+ prcp real,
+ date date
+);
+</pre><p>
+
+ Now try inserting an invalid record:
+
+</p><pre class="programlisting">
+INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');
+</pre><p>
+
+</p><pre class="screen">
+ERROR: insert or update on table "weather" violates foreign key constraint "weather_city_fkey"
+DETAIL: Key (city)=(Berkeley) is not present in table "cities".
+</pre><p>
+ </p><p>
+ The behavior of foreign keys can be finely tuned to your
+ application. We will not go beyond this simple example in this
+ tutorial, but just refer you to <a class="xref" href="ddl.html" title="Chapter 5. Data Definition">Chapter 5</a>
+ for more information. Making correct use of
+ foreign keys will definitely improve the quality of your database
+ applications, so you are strongly encouraged to learn about them.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-views.html" title="3.2. Views">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-transactions.html" title="3.4. Transactions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.2. Views </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.4. Transactions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-inheritance.html b/doc/src/sgml/html/tutorial-inheritance.html
new file mode 100644
index 0000000..1e38736
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-inheritance.html
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.6. Inheritance</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-window.html" title="3.5. Window Functions" /><link rel="next" href="tutorial-conclusion.html" title="3.7. Conclusion" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.6. Inheritance</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-window.html" title="3.5. Window Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-conclusion.html" title="3.7. Conclusion">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-INHERITANCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.6. Inheritance</h2></div></div></div><a id="id-1.4.5.7.2" class="indexterm"></a><p>
+ Inheritance is a concept from object-oriented databases. It opens
+ up interesting new possibilities of database design.
+ </p><p>
+ Let's create two tables: A table <code class="classname">cities</code>
+ and a table <code class="classname">capitals</code>. Naturally, capitals
+ are also cities, so you want some way to show the capitals
+ implicitly when you list all cities. If you're really clever you
+ might invent some scheme like this:
+
+</p><pre class="programlisting">
+CREATE TABLE capitals (
+ name text,
+ population real,
+ elevation int, -- (in ft)
+ state char(2)
+);
+
+CREATE TABLE non_capitals (
+ name text,
+ population real,
+ elevation int -- (in ft)
+);
+
+CREATE VIEW cities AS
+ SELECT name, population, elevation FROM capitals
+ UNION
+ SELECT name, population, elevation FROM non_capitals;
+</pre><p>
+
+ This works OK as far as querying goes, but it gets ugly when you
+ need to update several rows, for one thing.
+ </p><p>
+ A better solution is this:
+
+</p><pre class="programlisting">
+CREATE TABLE cities (
+ name text,
+ population real,
+ elevation int -- (in ft)
+);
+
+CREATE TABLE capitals (
+ state char(2) UNIQUE NOT NULL
+) INHERITS (cities);
+</pre><p>
+ </p><p>
+ In this case, a row of <code class="classname">capitals</code>
+ <em class="firstterm">inherits</em> all columns (<code class="structfield">name</code>,
+ <code class="structfield">population</code>, and <code class="structfield">elevation</code>) from its
+ <em class="firstterm">parent</em>, <code class="classname">cities</code>. The
+ type of the column <code class="structfield">name</code> is
+ <code class="type">text</code>, a native <span class="productname">PostgreSQL</span>
+ type for variable length character strings. The
+ <code class="classname">capitals</code> table has
+ an additional column, <code class="structfield">state</code>, which shows its
+ state abbreviation. In
+ <span class="productname">PostgreSQL</span>, a table can inherit from
+ zero or more other tables.
+ </p><p>
+ For example, the following query finds the names of all cities,
+ including state capitals, that are located at an elevation
+ over 500 feet:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM cities
+ WHERE elevation &gt; 500;
+</pre><p>
+
+ which returns:
+
+</p><pre class="screen">
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+ Madison | 845
+(3 rows)
+</pre><p>
+ </p><p>
+ On the other hand, the following query finds
+ all the cities that are not state capitals and
+ are situated at an elevation over 500 feet:
+
+</p><pre class="programlisting">
+SELECT name, elevation
+ FROM ONLY cities
+ WHERE elevation &gt; 500;
+</pre><p>
+
+</p><pre class="screen">
+ name | elevation
+-----------+-----------
+ Las Vegas | 2174
+ Mariposa | 1953
+(2 rows)
+</pre><p>
+ </p><p>
+ Here the <code class="literal">ONLY</code> before <code class="literal">cities</code>
+ indicates that the query should be run over only the
+ <code class="classname">cities</code> table, and not tables below
+ <code class="classname">cities</code> in the inheritance hierarchy. Many
+ of the commands that we have already discussed —
+ <code class="command">SELECT</code>, <code class="command">UPDATE</code>, and
+ <code class="command">DELETE</code> — support this <code class="literal">ONLY</code>
+ notation.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Although inheritance is frequently useful, it has not been integrated
+ with unique constraints or foreign keys, which limits its usefulness.
+ See <a class="xref" href="ddl-inherit.html" title="5.10. Inheritance">Section 5.10</a> for more detail.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-window.html" title="3.5. Window Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-conclusion.html" title="3.7. Conclusion">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.5. Window Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.7. Conclusion</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-install.html b/doc/src/sgml/html/tutorial-install.html
new file mode 100644
index 0000000..eab9a85
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-install.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>1.1. Installation</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-start.html" title="Chapter 1. Getting Started" /><link rel="next" href="tutorial-arch.html" title="1.2. Architectural Fundamentals" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">1.1. Installation</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-start.html" title="Chapter 1. Getting Started">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><th width="60%" align="center">Chapter 1. Getting Started</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-arch.html" title="1.2. Architectural Fundamentals">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-INSTALL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">1.1. Installation</h2></div></div></div><p>
+ Before you can use <span class="productname">PostgreSQL</span> you need
+ to install it, of course. It is possible that
+ <span class="productname">PostgreSQL</span> is already installed at your
+ site, either because it was included in your operating system
+ distribution or because the system administrator already installed
+ it. If that is the case, you should obtain information from the
+ operating system documentation or your system administrator about
+ how to access <span class="productname">PostgreSQL</span>.
+ </p><p>
+ If you are not sure whether <span class="productname">PostgreSQL</span>
+ is already available or whether you can use it for your
+ experimentation then you can install it yourself. Doing so is not
+ hard and it can be a good exercise.
+ <span class="productname">PostgreSQL</span> can be installed by any
+ unprivileged user; no superuser (<span class="systemitem">root</span>)
+ access is required.
+ </p><p>
+ If you are installing <span class="productname">PostgreSQL</span>
+ yourself, then refer to <a class="xref" href="installation.html" title="Chapter 17. Installation from Source Code">Chapter 17</a>
+ for instructions on installation, and return to
+ this guide when the installation is complete. Be sure to follow
+ closely the section about setting up the appropriate environment
+ variables.
+ </p><p>
+ If your site administrator has not set things up in the default
+ way, you might have some more work to do. For example, if the
+ database server machine is a remote machine, you will need to set
+ the <code class="envar">PGHOST</code> environment variable to the name of the
+ database server machine. The environment variable
+ <code class="envar">PGPORT</code> might also have to be set. The bottom line is
+ this: if you try to start an application program and it complains
+ that it cannot connect to the database, you should consult your
+ site administrator or, if that is you, the documentation to make
+ sure that your environment is properly set up. If you did not
+ understand the preceding paragraph then read the next section.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-start.html" title="Chapter 1. Getting Started">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-start.html" title="Chapter 1. Getting Started">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-arch.html" title="1.2. Architectural Fundamentals">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 1. Getting Started </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 1.2. Architectural Fundamentals</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-join.html b/doc/src/sgml/html/tutorial-join.html
new file mode 100644
index 0000000..01d123a
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-join.html
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.6. Joins Between Tables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-select.html" title="2.5. Querying a Table" /><link rel="next" href="tutorial-agg.html" title="2.7. Aggregate Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.6. Joins Between Tables</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-select.html" title="2.5. Querying a Table">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-agg.html" title="2.7. Aggregate Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-JOIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.6. Joins Between Tables</h2></div></div></div><a id="id-1.4.4.7.2" class="indexterm"></a><p>
+ Thus far, our queries have only accessed one table at a time.
+ Queries can access multiple tables at once, or access the same
+ table in such a way that multiple rows of the table are being
+ processed at the same time. Queries that access multiple tables
+ (or multiple instances of the same table) at one time are called
+ <em class="firstterm">join</em> queries. They combine rows from one table
+ with rows from a second table, with an expression specifying which rows
+ are to be paired. For example, to return all the weather records together
+ with the location of the associated city, the database needs to compare
+ the <code class="structfield">city</code>
+ column of each row of the <code class="structname">weather</code> table with the
+ <code class="structfield">name</code> column of all rows in the <code class="structname">cities</code>
+ table, and select the pairs of rows where these values match.<a href="#ftn.id-1.4.4.7.3.6" class="footnote"><sup class="footnote" id="id-1.4.4.7.3.6">[4]</sup></a>
+ This would be accomplished by the following query:
+
+</p><pre class="programlisting">
+SELECT * FROM weather JOIN cities ON city = name;
+</pre><p>
+
+</p><pre class="screen">
+ city | temp_lo | temp_hi | prcp | date | name | location
+---------------+---------+---------+------+------------+---------------+-----------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
+ San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
+(2 rows)
+</pre><p>
+
+ </p><p>
+ Observe two things about the result set:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ There is no result row for the city of Hayward. This is
+ because there is no matching entry in the
+ <code class="structname">cities</code> table for Hayward, so the join
+ ignores the unmatched rows in the <code class="structname">weather</code> table. We will see
+ shortly how this can be fixed.
+ </p></li><li class="listitem"><p>
+ There are two columns containing the city name. This is
+ correct because the lists of columns from the
+ <code class="structname">weather</code> and
+ <code class="structname">cities</code> tables are concatenated. In
+ practice this is undesirable, though, so you will probably want
+ to list the output columns explicitly rather than using
+ <code class="literal">*</code>:
+</p><pre class="programlisting">
+SELECT city, temp_lo, temp_hi, prcp, date, location
+ FROM weather JOIN cities ON city = name;
+</pre><p>
+ </p></li></ul></div><p>
+ </p><p>
+ Since the columns all had different names, the parser
+ automatically found which table they belong to. If there
+ were duplicate column names in the two tables you'd need to
+ <em class="firstterm">qualify</em> the column names to show which one you
+ meant, as in:
+
+</p><pre class="programlisting">
+SELECT weather.city, weather.temp_lo, weather.temp_hi,
+ weather.prcp, weather.date, cities.location
+ FROM weather JOIN cities ON weather.city = cities.name;
+</pre><p>
+
+ It is widely considered good style to qualify all column names
+ in a join query, so that the query won't fail if a duplicate
+ column name is later added to one of the tables.
+ </p><p>
+ Join queries of the kind seen thus far can also be written in this
+ form:
+
+</p><pre class="programlisting">
+SELECT *
+ FROM weather, cities
+ WHERE city = name;
+</pre><p>
+
+ This syntax pre-dates the <code class="literal">JOIN</code>/<code class="literal">ON</code>
+ syntax, which was introduced in SQL-92. The tables are simply listed in
+ the <code class="literal">FROM</code> clause, and the comparison expression is added
+ to the <code class="literal">WHERE</code> clause. The results from this older
+ implicit syntax and the newer explicit
+ <code class="literal">JOIN</code>/<code class="literal">ON</code> syntax are identical. But
+ for a reader of the query, the explicit syntax makes its meaning easier to
+ understand: The join condition is introduced by its own key word whereas
+ previously the condition was mixed into the <code class="literal">WHERE</code>
+ clause together with other conditions.
+ </p><a id="id-1.4.4.7.7" class="indexterm"></a><p>
+ Now we will figure out how we can get the Hayward records back in.
+ What we want the query to do is to scan the
+ <code class="structname">weather</code> table and for each row to find the
+ matching <code class="structname">cities</code> row(s). If no matching row is
+ found we want some <span class="quote">“<span class="quote">empty values</span>”</span> to be substituted
+ for the <code class="structname">cities</code> table's columns. This kind
+ of query is called an <em class="firstterm">outer join</em>. (The
+ joins we have seen so far are <em class="firstterm">inner joins</em>.)
+ The command looks like this:
+
+</p><pre class="programlisting">
+SELECT *
+ FROM weather LEFT OUTER JOIN cities ON weather.city = cities.name;
+</pre><p>
+
+</p><pre class="screen">
+ city | temp_lo | temp_hi | prcp | date | name | location
+---------------+---------+---------+------+------------+---------------+-----------
+ Hayward | 37 | 54 | | 1994-11-29 | |
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
+ San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
+(3 rows)
+</pre><p>
+
+ This query is called a <em class="firstterm">left outer
+ join</em> because the table mentioned on the left of the
+ join operator will have each of its rows in the output at least
+ once, whereas the table on the right will only have those rows
+ output that match some row of the left table. When outputting a
+ left-table row for which there is no right-table match, empty (null)
+ values are substituted for the right-table columns.
+ </p><p><strong>Exercise: </strong>
+ There are also right outer joins and full outer joins. Try to
+ find out what those do.
+ </p><a id="id-1.4.4.7.10" class="indexterm"></a><a id="id-1.4.4.7.11" class="indexterm"></a><p>
+ We can also join a table against itself. This is called a
+ <em class="firstterm">self join</em>. As an example, suppose we wish
+ to find all the weather records that are in the temperature range
+ of other weather records. So we need to compare the
+ <code class="structfield">temp_lo</code> and <code class="structfield">temp_hi</code> columns of
+ each <code class="structname">weather</code> row to the
+ <code class="structfield">temp_lo</code> and
+ <code class="structfield">temp_hi</code> columns of all other
+ <code class="structname">weather</code> rows. We can do this with the
+ following query:
+
+</p><pre class="programlisting">
+SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high,
+ w2.city, w2.temp_lo AS low, w2.temp_hi AS high
+ FROM weather w1 JOIN weather w2
+ ON w1.temp_lo &lt; w2.temp_lo AND w1.temp_hi &gt; w2.temp_hi;
+</pre><p>
+
+</p><pre class="screen">
+ city | low | high | city | low | high
+---------------+-----+------+---------------+-----+------
+ San Francisco | 43 | 57 | San Francisco | 46 | 50
+ Hayward | 37 | 54 | San Francisco | 46 | 50
+(2 rows)
+</pre><p>
+
+ Here we have relabeled the weather table as <code class="literal">w1</code> and
+ <code class="literal">w2</code> to be able to distinguish the left and right side
+ of the join. You can also use these kinds of aliases in other
+ queries to save some typing, e.g.:
+</p><pre class="programlisting">
+SELECT *
+ FROM weather w JOIN cities c ON w.city = c.name;
+</pre><p>
+ You will encounter this style of abbreviating quite frequently.
+ </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.4.4.7.3.6" class="footnote"><p><a href="#id-1.4.4.7.3.6" class="para"><sup class="para">[4] </sup></a>
+ This is only a conceptual model. The join is usually performed
+ in a more efficient manner than actually comparing each possible
+ pair of rows, but this is invisible to the user.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-select.html" title="2.5. Querying a Table">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-agg.html" title="2.7. Aggregate Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.5. Querying a Table </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.7. Aggregate Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-populate.html b/doc/src/sgml/html/tutorial-populate.html
new file mode 100644
index 0000000..b214c22
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-populate.html
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.4. Populating a Table With Rows</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-table.html" title="2.3. Creating a New Table" /><link rel="next" href="tutorial-select.html" title="2.5. Querying a Table" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.4. Populating a Table With Rows</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-table.html" title="2.3. Creating a New Table">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-select.html" title="2.5. Querying a Table">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-POPULATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.4. Populating a Table With Rows</h2></div></div></div><a id="id-1.4.4.5.2" class="indexterm"></a><p>
+ The <code class="command">INSERT</code> statement is used to populate a table with
+ rows:
+
+</p><pre class="programlisting">
+INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
+</pre><p>
+
+ Note that all data types use rather obvious input formats.
+ Constants that are not simple numeric values usually must be
+ surrounded by single quotes (<code class="literal">'</code>), as in the example.
+ The
+ <code class="type">date</code> type is actually quite flexible in what it
+ accepts, but for this tutorial we will stick to the unambiguous
+ format shown here.
+ </p><p>
+ The <code class="type">point</code> type requires a coordinate pair as input,
+ as shown here:
+</p><pre class="programlisting">
+INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
+</pre><p>
+ </p><p>
+ The syntax used so far requires you to remember the order of the
+ columns. An alternative syntax allows you to list the columns
+ explicitly:
+</p><pre class="programlisting">
+INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
+ VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');
+</pre><p>
+ You can list the columns in a different order if you wish or
+ even omit some columns, e.g., if the precipitation is unknown:
+</p><pre class="programlisting">
+INSERT INTO weather (date, city, temp_hi, temp_lo)
+ VALUES ('1994-11-29', 'Hayward', 54, 37);
+</pre><p>
+ Many developers consider explicitly listing the columns better
+ style than relying on the order implicitly.
+ </p><p>
+ Please enter all the commands shown above so you have some data to
+ work with in the following sections.
+ </p><p>
+ <a id="id-1.4.4.5.7.1" class="indexterm"></a>
+
+ You could also have used <code class="command">COPY</code> to load large
+ amounts of data from flat-text files. This is usually faster
+ because the <code class="command">COPY</code> command is optimized for this
+ application while allowing less flexibility than
+ <code class="command">INSERT</code>. An example would be:
+
+</p><pre class="programlisting">
+COPY weather FROM '/home/user/weather.txt';
+</pre><p>
+
+ where the file name for the source file must be available on the
+ machine running the backend process, not the client, since the backend process
+ reads the file directly. You can read more about the
+ <code class="command">COPY</code> command in <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-table.html" title="2.3. Creating a New Table">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-select.html" title="2.5. Querying a Table">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.3. Creating a New Table </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.5. Querying a Table</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-select.html b/doc/src/sgml/html/tutorial-select.html
new file mode 100644
index 0000000..54b2c63
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-select.html
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.5. Querying a Table</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-populate.html" title="2.4. Populating a Table With Rows" /><link rel="next" href="tutorial-join.html" title="2.6. Joins Between Tables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.5. Querying a Table</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-populate.html" title="2.4. Populating a Table With Rows">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-join.html" title="2.6. Joins Between Tables">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-SELECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.5. Querying a Table</h2></div></div></div><p>
+ <a id="id-1.4.4.6.2.1" class="indexterm"></a>
+ <a id="id-1.4.4.6.2.2" class="indexterm"></a>
+
+ To retrieve data from a table, the table is
+ <em class="firstterm">queried</em>. An <acronym class="acronym">SQL</acronym>
+ <code class="command">SELECT</code> statement is used to do this. The
+ statement is divided into a select list (the part that lists the
+ columns to be returned), a table list (the part that lists the
+ tables from which to retrieve the data), and an optional
+ qualification (the part that specifies any restrictions). For
+ example, to retrieve all the rows of table
+ <code class="structname">weather</code>, type:
+</p><pre class="programlisting">
+SELECT * FROM weather;
+</pre><p>
+ Here <code class="literal">*</code> is a shorthand for <span class="quote">“<span class="quote">all columns</span>”</span>.
+ <a href="#ftn.id-1.4.4.6.2.10" class="footnote"><sup class="footnote" id="id-1.4.4.6.2.10">[2]</sup></a>
+ So the same result would be had with:
+</p><pre class="programlisting">
+SELECT city, temp_lo, temp_hi, prcp, date FROM weather;
+</pre><p>
+
+ The output should be:
+
+</p><pre class="screen">
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 43 | 57 | 0 | 1994-11-29
+ Hayward | 37 | 54 | | 1994-11-29
+(3 rows)
+</pre><p>
+ </p><p>
+ You can write expressions, not just simple column references, in the
+ select list. For example, you can do:
+</p><pre class="programlisting">
+SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
+</pre><p>
+ This should give:
+</p><pre class="screen">
+ city | temp_avg | date
+---------------+----------+------------
+ San Francisco | 48 | 1994-11-27
+ San Francisco | 50 | 1994-11-29
+ Hayward | 45 | 1994-11-29
+(3 rows)
+</pre><p>
+ Notice how the <code class="literal">AS</code> clause is used to relabel the
+ output column. (The <code class="literal">AS</code> clause is optional.)
+ </p><p>
+ A query can be <span class="quote">“<span class="quote">qualified</span>”</span> by adding a <code class="literal">WHERE</code>
+ clause that specifies which rows are wanted. The <code class="literal">WHERE</code>
+ clause contains a Boolean (truth value) expression, and only rows for
+ which the Boolean expression is true are returned. The usual
+ Boolean operators (<code class="literal">AND</code>,
+ <code class="literal">OR</code>, and <code class="literal">NOT</code>) are allowed in
+ the qualification. For example, the following
+ retrieves the weather of San Francisco on rainy days:
+
+</p><pre class="programlisting">
+SELECT * FROM weather
+ WHERE city = 'San Francisco' AND prcp &gt; 0.0;
+</pre><p>
+ Result:
+</p><pre class="screen">
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+(1 row)
+</pre><p>
+ </p><p>
+ <a id="id-1.4.4.6.5.1" class="indexterm"></a>
+
+ You can request that the results of a query
+ be returned in sorted order:
+
+</p><pre class="programlisting">
+SELECT * FROM weather
+ ORDER BY city;
+</pre><p>
+
+</p><pre class="screen">
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ Hayward | 37 | 54 | | 1994-11-29
+ San Francisco | 43 | 57 | 0 | 1994-11-29
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+</pre><p>
+
+ In this example, the sort order isn't fully specified, and so you
+ might get the San Francisco rows in either order. But you'd always
+ get the results shown above if you do:
+
+</p><pre class="programlisting">
+SELECT * FROM weather
+ ORDER BY city, temp_lo;
+</pre><p>
+ </p><p>
+ <a id="id-1.4.4.6.6.1" class="indexterm"></a>
+ <a id="id-1.4.4.6.6.2" class="indexterm"></a>
+
+ You can request that duplicate rows be removed from the result of
+ a query:
+
+</p><pre class="programlisting">
+SELECT DISTINCT city
+ FROM weather;
+</pre><p>
+
+</p><pre class="screen">
+ city
+---------------
+ Hayward
+ San Francisco
+(2 rows)
+</pre><p>
+
+ Here again, the result row ordering might vary.
+ You can ensure consistent results by using <code class="literal">DISTINCT</code> and
+ <code class="literal">ORDER BY</code> together:
+ <a href="#ftn.id-1.4.4.6.6.7" class="footnote"><sup class="footnote" id="id-1.4.4.6.6.7">[3]</sup></a>
+
+</p><pre class="programlisting">
+SELECT DISTINCT city
+ FROM weather
+ ORDER BY city;
+</pre><p>
+ </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.4.4.6.2.10" class="footnote"><p><a href="#id-1.4.4.6.2.10" class="para"><sup class="para">[2] </sup></a>
+ While <code class="literal">SELECT *</code> is useful for off-the-cuff
+ queries, it is widely considered bad style in production code,
+ since adding a column to the table would change the results.
+ </p></div><div id="ftn.id-1.4.4.6.6.7" class="footnote"><p><a href="#id-1.4.4.6.6.7" class="para"><sup class="para">[3] </sup></a>
+ In some database systems, including older versions of
+ <span class="productname">PostgreSQL</span>, the implementation of
+ <code class="literal">DISTINCT</code> automatically orders the rows and
+ so <code class="literal">ORDER BY</code> is unnecessary. But this is not
+ required by the SQL standard, and current
+ <span class="productname">PostgreSQL</span> does not guarantee that
+ <code class="literal">DISTINCT</code> causes the rows to be ordered.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-populate.html" title="2.4. Populating a Table With Rows">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-join.html" title="2.6. Joins Between Tables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.4. Populating a Table With Rows </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.6. Joins Between Tables</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-sql-intro.html b/doc/src/sgml/html/tutorial-sql-intro.html
new file mode 100644
index 0000000..8025b5d
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-sql-intro.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.1. Introduction</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-sql.html" title="Chapter 2. The SQL Language" /><link rel="next" href="tutorial-concepts.html" title="2.2. Concepts" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.1. Introduction</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-concepts.html" title="2.2. Concepts">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-SQL-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.1. Introduction</h2></div></div></div><p>
+ This chapter provides an overview of how to use
+ <acronym class="acronym">SQL</acronym> to perform simple operations. This
+ tutorial is only intended to give you an introduction and is in no
+ way a complete tutorial on <acronym class="acronym">SQL</acronym>. Numerous books
+ have been written on <acronym class="acronym">SQL</acronym>, including <a class="xref" href="biblio.html#MELT93" title="Understanding the New SQL">[melt93]</a> and <a class="xref" href="biblio.html#DATE97" title="A Guide to the SQL Standard">[date97]</a>.
+ You should be aware that some <span class="productname">PostgreSQL</span>
+ language features are extensions to the standard.
+ </p><p>
+ In the examples that follow, we assume that you have created a
+ database named <code class="literal">mydb</code>, as described in the previous
+ chapter, and have been able to start <span class="application">psql</span>.
+ </p><p>
+ Examples in this manual can also be found in the
+ <span class="productname">PostgreSQL</span> source distribution
+ in the directory <code class="filename">src/tutorial/</code>. (Binary
+ distributions of <span class="productname">PostgreSQL</span> might not
+ provide those files.) To use those
+ files, first change to that directory and run <span class="application">make</span>:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>cd <em class="replaceable"><code>...</code></em>/src/tutorial</code></strong>
+<code class="prompt">$</code> <strong class="userinput"><code>make</code></strong>
+</pre><p>
+
+ This creates the scripts and compiles the C files containing user-defined
+ functions and types. Then, to start the tutorial, do the following:
+
+</p><pre class="screen">
+<code class="prompt">$</code> <strong class="userinput"><code>psql -s mydb</code></strong>
+<code class="computeroutput">
+...
+</code>
+<code class="prompt">mydb=&gt;</code> <strong class="userinput"><code>\i basics.sql</code></strong>
+</pre><p>
+
+ The <code class="literal">\i</code> command reads in commands from the
+ specified file. <code class="command">psql</code>'s <code class="literal">-s</code> option puts you in
+ single step mode which pauses before sending each statement to the
+ server. The commands used in this section are in the file
+ <code class="filename">basics.sql</code>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-concepts.html" title="2.2. Concepts">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. The <acronym class="acronym">SQL</acronym> Language </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.2. Concepts</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-sql.html b/doc/src/sgml/html/tutorial-sql.html
new file mode 100644
index 0000000..3f42eee
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-sql.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 2. The SQL Language</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-accessdb.html" title="1.4. Accessing a Database" /><link rel="next" href="tutorial-sql-intro.html" title="2.1. Introduction" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-accessdb.html" title="1.4. Accessing a Database">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial.html" title="Part I. Tutorial">Up</a></td><th width="60%" align="center">Part I. Tutorial</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-sql-intro.html" title="2.1. Introduction">Next</a></td></tr></table><hr /></div><div class="chapter" id="TUTORIAL-SQL"><div class="titlepage"><div><div><h2 class="title">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="tutorial-sql-intro.html">2.1. Introduction</a></span></dt><dt><span class="sect1"><a href="tutorial-concepts.html">2.2. Concepts</a></span></dt><dt><span class="sect1"><a href="tutorial-table.html">2.3. Creating a New Table</a></span></dt><dt><span class="sect1"><a href="tutorial-populate.html">2.4. Populating a Table With Rows</a></span></dt><dt><span class="sect1"><a href="tutorial-select.html">2.5. Querying a Table</a></span></dt><dt><span class="sect1"><a href="tutorial-join.html">2.6. Joins Between Tables</a></span></dt><dt><span class="sect1"><a href="tutorial-agg.html">2.7. Aggregate Functions</a></span></dt><dt><span class="sect1"><a href="tutorial-update.html">2.8. Updates</a></span></dt><dt><span class="sect1"><a href="tutorial-delete.html">2.9. Deletions</a></span></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-accessdb.html" title="1.4. Accessing a Database">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial.html" title="Part I. Tutorial">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-sql-intro.html" title="2.1. Introduction">Next</a></td></tr><tr><td width="40%" align="left" valign="top">1.4. Accessing a Database </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.1. Introduction</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-start.html b/doc/src/sgml/html/tutorial-start.html
new file mode 100644
index 0000000..2dd40e5
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-start.html
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 1. Getting Started</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial.html" title="Part I. Tutorial" /><link rel="next" href="tutorial-install.html" title="1.1. Installation" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 1. Getting Started</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial.html" title="Part I. Tutorial">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial.html" title="Part I. Tutorial">Up</a></td><th width="60%" align="center">Part I. Tutorial</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-install.html" title="1.1. Installation">Next</a></td></tr></table><hr /></div><div class="chapter" id="TUTORIAL-START"><div class="titlepage"><div><div><h2 class="title">Chapter 1. Getting Started</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="tutorial-install.html">1.1. Installation</a></span></dt><dt><span class="sect1"><a href="tutorial-arch.html">1.2. Architectural Fundamentals</a></span></dt><dt><span class="sect1"><a href="tutorial-createdb.html">1.3. Creating a Database</a></span></dt><dt><span class="sect1"><a href="tutorial-accessdb.html">1.4. Accessing a Database</a></span></dt></dl></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial.html" title="Part I. Tutorial">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial.html" title="Part I. Tutorial">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-install.html" title="1.1. Installation">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part I. Tutorial </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 1.1. Installation</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-table.html b/doc/src/sgml/html/tutorial-table.html
new file mode 100644
index 0000000..13a609e
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-table.html
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.3. Creating a New Table</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-concepts.html" title="2.2. Concepts" /><link rel="next" href="tutorial-populate.html" title="2.4. Populating a Table With Rows" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.3. Creating a New Table</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-concepts.html" title="2.2. Concepts">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-populate.html" title="2.4. Populating a Table With Rows">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-TABLE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.3. Creating a New Table</h2></div></div></div><a id="id-1.4.4.4.2" class="indexterm"></a><p>
+ You can create a new table by specifying the table
+ name, along with all column names and their types:
+
+</p><pre class="programlisting">
+CREATE TABLE weather (
+ city varchar(80),
+ temp_lo int, -- low temperature
+ temp_hi int, -- high temperature
+ prcp real, -- precipitation
+ date date
+);
+</pre><p>
+
+ You can enter this into <code class="command">psql</code> with the line
+ breaks. <code class="command">psql</code> will recognize that the command
+ is not terminated until the semicolon.
+ </p><p>
+ White space (i.e., spaces, tabs, and newlines) can be used freely
+ in SQL commands. That means you can type the command aligned
+ differently than above, or even all on one line. Two dashes
+ (<span class="quote">“<span class="quote"><code class="literal">--</code></span>”</span>) introduce comments.
+ Whatever follows them is ignored up to the end of the line. SQL
+ is case insensitive about key words and identifiers, except
+ when identifiers are double-quoted to preserve the case (not done
+ above).
+ </p><p>
+ <code class="type">varchar(80)</code> specifies a data type that can store
+ arbitrary character strings up to 80 characters in length.
+ <code class="type">int</code> is the normal integer type. <code class="type">real</code> is
+ a type for storing single precision floating-point numbers.
+ <code class="type">date</code> should be self-explanatory. (Yes, the column of
+ type <code class="type">date</code> is also named <code class="structfield">date</code>.
+ This might be convenient or confusing — you choose.)
+ </p><p>
+ <span class="productname">PostgreSQL</span> supports the standard
+ <acronym class="acronym">SQL</acronym> types <code class="type">int</code>,
+ <code class="type">smallint</code>, <code class="type">real</code>, <code class="type">double
+ precision</code>, <code class="type">char(<em class="replaceable"><code>N</code></em>)</code>,
+ <code class="type">varchar(<em class="replaceable"><code>N</code></em>)</code>, <code class="type">date</code>,
+ <code class="type">time</code>, <code class="type">timestamp</code>, and
+ <code class="type">interval</code>, as well as other types of general utility
+ and a rich set of geometric types.
+ <span class="productname">PostgreSQL</span> can be customized with an
+ arbitrary number of user-defined data types. Consequently, type
+ names are not key words in the syntax, except where required to
+ support special cases in the <acronym class="acronym">SQL</acronym> standard.
+ </p><p>
+ The second example will store cities and their associated
+ geographical location:
+</p><pre class="programlisting">
+CREATE TABLE cities (
+ name varchar(80),
+ location point
+);
+</pre><p>
+ The <code class="type">point</code> type is an example of a
+ <span class="productname">PostgreSQL</span>-specific data type.
+ </p><p>
+ <a id="id-1.4.4.4.8.1" class="indexterm"></a>
+
+ Finally, it should be mentioned that if you don't need a table any
+ longer or want to recreate it differently you can remove it using
+ the following command:
+</p><pre class="synopsis">
+DROP TABLE <em class="replaceable"><code>tablename</code></em>;
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-concepts.html" title="2.2. Concepts">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-populate.html" title="2.4. Populating a Table With Rows">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.2. Concepts </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.4. Populating a Table With Rows</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-transactions.html b/doc/src/sgml/html/tutorial-transactions.html
new file mode 100644
index 0000000..812abbc
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-transactions.html
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.4. Transactions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-fk.html" title="3.3. Foreign Keys" /><link rel="next" href="tutorial-window.html" title="3.5. Window Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.4. Transactions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-fk.html" title="3.3. Foreign Keys">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-window.html" title="3.5. Window Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-TRANSACTIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.4. Transactions</h2></div></div></div><a id="id-1.4.5.5.2" class="indexterm"></a><p>
+ <em class="firstterm">Transactions</em> are a fundamental concept of all database
+ systems. The essential point of a transaction is that it bundles
+ multiple steps into a single, all-or-nothing operation. The intermediate
+ states between the steps are not visible to other concurrent transactions,
+ and if some failure occurs that prevents the transaction from completing,
+ then none of the steps affect the database at all.
+ </p><p>
+ For example, consider a bank database that contains balances for various
+ customer accounts, as well as total deposit balances for branches.
+ Suppose that we want to record a payment of $100.00 from Alice's account
+ to Bob's account. Simplifying outrageously, the SQL commands for this
+ might look like:
+
+</p><pre class="programlisting">
+UPDATE accounts SET balance = balance - 100.00
+ WHERE name = 'Alice';
+UPDATE branches SET balance = balance - 100.00
+ WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice');
+UPDATE accounts SET balance = balance + 100.00
+ WHERE name = 'Bob';
+UPDATE branches SET balance = balance + 100.00
+ WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob');
+</pre><p>
+ </p><p>
+ The details of these commands are not important here; the important
+ point is that there are several separate updates involved to accomplish
+ this rather simple operation. Our bank's officers will want to be
+ assured that either all these updates happen, or none of them happen.
+ It would certainly not do for a system failure to result in Bob
+ receiving $100.00 that was not debited from Alice. Nor would Alice long
+ remain a happy customer if she was debited without Bob being credited.
+ We need a guarantee that if something goes wrong partway through the
+ operation, none of the steps executed so far will take effect. Grouping
+ the updates into a <em class="firstterm">transaction</em> gives us this guarantee.
+ A transaction is said to be <em class="firstterm">atomic</em>: from the point of
+ view of other transactions, it either happens completely or not at all.
+ </p><p>
+ We also want a
+ guarantee that once a transaction is completed and acknowledged by
+ the database system, it has indeed been permanently recorded
+ and won't be lost even if a crash ensues shortly thereafter.
+ For example, if we are recording a cash withdrawal by Bob,
+ we do not want any chance that the debit to his account will
+ disappear in a crash just after he walks out the bank door.
+ A transactional database guarantees that all the updates made by
+ a transaction are logged in permanent storage (i.e., on disk) before
+ the transaction is reported complete.
+ </p><p>
+ Another important property of transactional databases is closely
+ related to the notion of atomic updates: when multiple transactions
+ are running concurrently, each one should not be able to see the
+ incomplete changes made by others. For example, if one transaction
+ is busy totalling all the branch balances, it would not do for it
+ to include the debit from Alice's branch but not the credit to
+ Bob's branch, nor vice versa. So transactions must be all-or-nothing
+ not only in terms of their permanent effect on the database, but
+ also in terms of their visibility as they happen. The updates made
+ so far by an open transaction are invisible to other transactions
+ until the transaction completes, whereupon all the updates become
+ visible simultaneously.
+ </p><p>
+ In <span class="productname">PostgreSQL</span>, a transaction is set up by surrounding
+ the SQL commands of the transaction with
+ <code class="command">BEGIN</code> and <code class="command">COMMIT</code> commands. So our banking
+ transaction would actually look like:
+
+</p><pre class="programlisting">
+BEGIN;
+UPDATE accounts SET balance = balance - 100.00
+ WHERE name = 'Alice';
+-- etc etc
+COMMIT;
+</pre><p>
+ </p><p>
+ If, partway through the transaction, we decide we do not want to
+ commit (perhaps we just noticed that Alice's balance went negative),
+ we can issue the command <code class="command">ROLLBACK</code> instead of
+ <code class="command">COMMIT</code>, and all our updates so far will be canceled.
+ </p><p>
+ <span class="productname">PostgreSQL</span> actually treats every SQL statement as being
+ executed within a transaction. If you do not issue a <code class="command">BEGIN</code>
+ command,
+ then each individual statement has an implicit <code class="command">BEGIN</code> and
+ (if successful) <code class="command">COMMIT</code> wrapped around it. A group of
+ statements surrounded by <code class="command">BEGIN</code> and <code class="command">COMMIT</code>
+ is sometimes called a <em class="firstterm">transaction block</em>.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Some client libraries issue <code class="command">BEGIN</code> and <code class="command">COMMIT</code>
+ commands automatically, so that you might get the effect of transaction
+ blocks without asking. Check the documentation for the interface
+ you are using.
+ </p></div><p>
+ It's possible to control the statements in a transaction in a more
+ granular fashion through the use of <em class="firstterm">savepoints</em>. Savepoints
+ allow you to selectively discard parts of the transaction, while
+ committing the rest. After defining a savepoint with
+ <code class="command">SAVEPOINT</code>, you can if needed roll back to the savepoint
+ with <code class="command">ROLLBACK TO</code>. All the transaction's database changes
+ between defining the savepoint and rolling back to it are discarded, but
+ changes earlier than the savepoint are kept.
+ </p><p>
+ After rolling back to a savepoint, it continues to be defined, so you can
+ roll back to it several times. Conversely, if you are sure you won't need
+ to roll back to a particular savepoint again, it can be released, so the
+ system can free some resources. Keep in mind that either releasing or
+ rolling back to a savepoint
+ will automatically release all savepoints that were defined after it.
+ </p><p>
+ All this is happening within the transaction block, so none of it
+ is visible to other database sessions. When and if you commit the
+ transaction block, the committed actions become visible as a unit
+ to other sessions, while the rolled-back actions never become visible
+ at all.
+ </p><p>
+ Remembering the bank database, suppose we debit $100.00 from Alice's
+ account, and credit Bob's account, only to find later that we should
+ have credited Wally's account. We could do it using savepoints like
+ this:
+
+</p><pre class="programlisting">
+BEGIN;
+UPDATE accounts SET balance = balance - 100.00
+ WHERE name = 'Alice';
+SAVEPOINT my_savepoint;
+UPDATE accounts SET balance = balance + 100.00
+ WHERE name = 'Bob';
+-- oops ... forget that and use Wally's account
+ROLLBACK TO my_savepoint;
+UPDATE accounts SET balance = balance + 100.00
+ WHERE name = 'Wally';
+COMMIT;
+</pre><p>
+ </p><p>
+ This example is, of course, oversimplified, but there's a lot of control
+ possible in a transaction block through the use of savepoints.
+ Moreover, <code class="command">ROLLBACK TO</code> is the only way to regain control of a
+ transaction block that was put in aborted state by the
+ system due to an error, short of rolling it back completely and starting
+ again.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-fk.html" title="3.3. Foreign Keys">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-window.html" title="3.5. Window Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.3. Foreign Keys </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.5. Window Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-update.html b/doc/src/sgml/html/tutorial-update.html
new file mode 100644
index 0000000..f597e8a
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-update.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>2.8. Updates</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-agg.html" title="2.7. Aggregate Functions" /><link rel="next" href="tutorial-delete.html" title="2.9. Deletions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">2.8. Updates</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-agg.html" title="2.7. Aggregate Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><th width="60%" align="center">Chapter 2. The <acronym class="acronym">SQL</acronym> Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-delete.html" title="2.9. Deletions">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-UPDATE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2.8. Updates</h2></div></div></div><a id="id-1.4.4.9.2" class="indexterm"></a><p>
+ You can update existing rows using the
+ <code class="command">UPDATE</code> command.
+ Suppose you discover the temperature readings are
+ all off by 2 degrees after November 28. You can correct the
+ data as follows:
+
+</p><pre class="programlisting">
+UPDATE weather
+ SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
+ WHERE date &gt; '1994-11-28';
+</pre><p>
+ </p><p>
+ Look at the new state of the data:
+</p><pre class="programlisting">
+SELECT * FROM weather;
+
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 41 | 55 | 0 | 1994-11-29
+ Hayward | 35 | 52 | | 1994-11-29
+(3 rows)
+</pre><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-agg.html" title="2.7. Aggregate Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-sql.html" title="Chapter 2. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-delete.html" title="2.9. Deletions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">2.7. Aggregate Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 2.9. Deletions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-views.html b/doc/src/sgml/html/tutorial-views.html
new file mode 100644
index 0000000..607d019
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-views.html
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.2. Views</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-advanced-intro.html" title="3.1. Introduction" /><link rel="next" href="tutorial-fk.html" title="3.3. Foreign Keys" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.2. Views</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-advanced-intro.html" title="3.1. Introduction">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-fk.html" title="3.3. Foreign Keys">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-VIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.2. Views</h2></div></div></div><a id="id-1.4.5.3.2" class="indexterm"></a><p>
+ Refer back to the queries in <a class="xref" href="tutorial-join.html" title="2.6. Joins Between Tables">Section 2.6</a>.
+ Suppose the combined listing of weather records and city location
+ is of particular interest to your application, but you do not want
+ to type the query each time you need it. You can create a
+ <em class="firstterm">view</em> over the query, which gives a name to
+ the query that you can refer to like an ordinary table:
+
+</p><pre class="programlisting">
+CREATE VIEW myview AS
+ SELECT name, temp_lo, temp_hi, prcp, date, location
+ FROM weather, cities
+ WHERE city = name;
+
+SELECT * FROM myview;
+</pre><p>
+ </p><p>
+ Making liberal use of views is a key aspect of good SQL database
+ design. Views allow you to encapsulate the details of the
+ structure of your tables, which might change as your application
+ evolves, behind consistent interfaces.
+ </p><p>
+ Views can be used in almost any place a real table can be used.
+ Building views upon other views is not uncommon.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-advanced-intro.html" title="3.1. Introduction">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-fk.html" title="3.3. Foreign Keys">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.1. Introduction </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.3. Foreign Keys</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial-window.html b/doc/src/sgml/html/tutorial-window.html
new file mode 100644
index 0000000..3d31f42
--- /dev/null
+++ b/doc/src/sgml/html/tutorial-window.html
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>3.5. Window Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tutorial-transactions.html" title="3.4. Transactions" /><link rel="next" href="tutorial-inheritance.html" title="3.6. Inheritance" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">3.5. Window Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tutorial-transactions.html" title="3.4. Transactions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><th width="60%" align="center">Chapter 3. Advanced Features</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-inheritance.html" title="3.6. Inheritance">Next</a></td></tr></table><hr /></div><div class="sect1" id="TUTORIAL-WINDOW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">3.5. Window Functions</h2></div></div></div><a id="id-1.4.5.6.2" class="indexterm"></a><p>
+ A <em class="firstterm">window function</em> performs a calculation across a set of
+ table rows that are somehow related to the current row. This is comparable
+ to the type of calculation that can be done with an aggregate function.
+ However, window functions do not cause rows to become grouped into a single
+ output row like non-window aggregate calls would. Instead, the
+ rows retain their separate identities. Behind the scenes, the window
+ function is able to access more than just the current row of the query
+ result.
+ </p><p>
+ Here is an example that shows how to compare each employee's salary
+ with the average salary in his or her department:
+
+</p><pre class="programlisting">
+SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
+</pre><p>
+
+</p><pre class="screen">
+ depname | empno | salary | avg
+-----------+-------+--------+-----------------------
+ develop | 11 | 5200 | 5020.0000000000000000
+ develop | 7 | 4200 | 5020.0000000000000000
+ develop | 9 | 4500 | 5020.0000000000000000
+ develop | 8 | 6000 | 5020.0000000000000000
+ develop | 10 | 5200 | 5020.0000000000000000
+ personnel | 5 | 3500 | 3700.0000000000000000
+ personnel | 2 | 3900 | 3700.0000000000000000
+ sales | 3 | 4800 | 4866.6666666666666667
+ sales | 1 | 5000 | 4866.6666666666666667
+ sales | 4 | 4800 | 4866.6666666666666667
+(10 rows)
+</pre><p>
+
+ The first three output columns come directly from the table
+ <code class="structname">empsalary</code>, and there is one output row for each row in the
+ table. The fourth column represents an average taken across all the table
+ rows that have the same <code class="structfield">depname</code> value as the current row.
+ (This actually is the same function as the non-window <code class="function">avg</code>
+ aggregate, but the <code class="literal">OVER</code> clause causes it to be
+ treated as a window function and computed across the window frame.)
+ </p><p>
+ A window function call always contains an <code class="literal">OVER</code> clause
+ directly following the window function's name and argument(s). This is what
+ syntactically distinguishes it from a normal function or non-window
+ aggregate. The <code class="literal">OVER</code> clause determines exactly how the
+ rows of the query are split up for processing by the window function.
+ The <code class="literal">PARTITION BY</code> clause within <code class="literal">OVER</code>
+ divides the rows into groups, or partitions, that share the same
+ values of the <code class="literal">PARTITION BY</code> expression(s). For each row,
+ the window function is computed across the rows that fall into the
+ same partition as the current row.
+ </p><p>
+ You can also control the order in which rows are processed by
+ window functions using <code class="literal">ORDER BY</code> within <code class="literal">OVER</code>.
+ (The window <code class="literal">ORDER BY</code> does not even have to match the
+ order in which the rows are output.) Here is an example:
+
+</p><pre class="programlisting">
+SELECT depname, empno, salary,
+ rank() OVER (PARTITION BY depname ORDER BY salary DESC)
+FROM empsalary;
+</pre><p>
+
+</p><pre class="screen">
+ depname | empno | salary | rank
+-----------+-------+--------+------
+ develop | 8 | 6000 | 1
+ develop | 10 | 5200 | 2
+ develop | 11 | 5200 | 2
+ develop | 9 | 4500 | 4
+ develop | 7 | 4200 | 5
+ personnel | 2 | 3900 | 1
+ personnel | 5 | 3500 | 2
+ sales | 1 | 5000 | 1
+ sales | 4 | 4800 | 2
+ sales | 3 | 4800 | 2
+(10 rows)
+</pre><p>
+
+ As shown here, the <code class="function">rank</code> function produces a numerical rank
+ for each distinct <code class="literal">ORDER BY</code> value in the current row's
+ partition, using the order defined by the <code class="literal">ORDER BY</code> clause.
+ <code class="function">rank</code> needs no explicit parameter, because its behavior
+ is entirely determined by the <code class="literal">OVER</code> clause.
+ </p><p>
+ The rows considered by a window function are those of the <span class="quote">“<span class="quote">virtual
+ table</span>”</span> produced by the query's <code class="literal">FROM</code> clause as filtered by its
+ <code class="literal">WHERE</code>, <code class="literal">GROUP BY</code>, and <code class="literal">HAVING</code> clauses
+ if any. For example, a row removed because it does not meet the
+ <code class="literal">WHERE</code> condition is not seen by any window function.
+ A query can contain multiple window functions that slice up the data
+ in different ways using different <code class="literal">OVER</code> clauses, but
+ they all act on the same collection of rows defined by this virtual table.
+ </p><p>
+ We already saw that <code class="literal">ORDER BY</code> can be omitted if the ordering
+ of rows is not important. It is also possible to omit <code class="literal">PARTITION
+ BY</code>, in which case there is a single partition containing all rows.
+ </p><p>
+ There is another important concept associated with window functions:
+ for each row, there is a set of rows within its partition called its
+ <em class="firstterm">window frame</em>. Some window functions act only
+ on the rows of the window frame, rather than of the whole partition.
+ By default, if <code class="literal">ORDER BY</code> is supplied then the frame consists of
+ all rows from the start of the partition up through the current row, plus
+ any following rows that are equal to the current row according to the
+ <code class="literal">ORDER BY</code> clause. When <code class="literal">ORDER BY</code> is omitted the
+ default frame consists of all rows in the partition.
+ <a href="#ftn.id-1.4.5.6.9.5" class="footnote"><sup class="footnote" id="id-1.4.5.6.9.5">[5]</sup></a>
+ Here is an example using <code class="function">sum</code>:
+ </p><pre class="programlisting">
+SELECT salary, sum(salary) OVER () FROM empsalary;
+</pre><pre class="screen">
+ salary | sum
+--------+-------
+ 5200 | 47100
+ 5000 | 47100
+ 3500 | 47100
+ 4800 | 47100
+ 3900 | 47100
+ 4200 | 47100
+ 4500 | 47100
+ 4800 | 47100
+ 6000 | 47100
+ 5200 | 47100
+(10 rows)
+</pre><p>
+ Above, since there is no <code class="literal">ORDER BY</code> in the <code class="literal">OVER</code>
+ clause, the window frame is the same as the partition, which for lack of
+ <code class="literal">PARTITION BY</code> is the whole table; in other words each sum is
+ taken over the whole table and so we get the same result for each output
+ row. But if we add an <code class="literal">ORDER BY</code> clause, we get very different
+ results:
+ </p><pre class="programlisting">
+SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
+</pre><pre class="screen">
+ salary | sum
+--------+-------
+ 3500 | 3500
+ 3900 | 7400
+ 4200 | 11600
+ 4500 | 16100
+ 4800 | 25700
+ 4800 | 25700
+ 5000 | 30700
+ 5200 | 41100
+ 5200 | 41100
+ 6000 | 47100
+(10 rows)
+</pre><p>
+ Here the sum is taken from the first (lowest) salary up through the
+ current one, including any duplicates of the current one (notice the
+ results for the duplicated salaries).
+ </p><p>
+ Window functions are permitted only in the <code class="literal">SELECT</code> list
+ and the <code class="literal">ORDER BY</code> clause of the query. They are forbidden
+ elsewhere, such as in <code class="literal">GROUP BY</code>, <code class="literal">HAVING</code>
+ and <code class="literal">WHERE</code> clauses. This is because they logically
+ execute after the processing of those clauses. Also, window functions
+ execute after non-window aggregate functions. This means it is valid to
+ include an aggregate function call in the arguments of a window function,
+ but not vice versa.
+ </p><p>
+ If there is a need to filter or group rows after the window calculations
+ are performed, you can use a sub-select. For example:
+
+</p><pre class="programlisting">
+SELECT depname, empno, salary, enroll_date
+FROM
+ (SELECT depname, empno, salary, enroll_date,
+ rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos
+ FROM empsalary
+ ) AS ss
+WHERE pos &lt; 3;
+</pre><p>
+
+ The above query only shows the rows from the inner query having
+ <code class="literal">rank</code> less than 3.
+ </p><p>
+ When a query involves multiple window functions, it is possible to write
+ out each one with a separate <code class="literal">OVER</code> clause, but this is
+ duplicative and error-prone if the same windowing behavior is wanted
+ for several functions. Instead, each windowing behavior can be named
+ in a <code class="literal">WINDOW</code> clause and then referenced in <code class="literal">OVER</code>.
+ For example:
+
+</p><pre class="programlisting">
+SELECT sum(salary) OVER w, avg(salary) OVER w
+ FROM empsalary
+ WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
+</pre><p>
+ </p><p>
+ More details about window functions can be found in
+ <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a>,
+ <a class="xref" href="functions-window.html" title="9.22. Window Functions">Section 9.22</a>,
+ <a class="xref" href="queries-table-expressions.html#QUERIES-WINDOW" title="7.2.5. Window Function Processing">Section 7.2.5</a>, and the
+ <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> reference page.
+ </p><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.4.5.6.9.5" class="footnote"><p><a href="#id-1.4.5.6.9.5" class="para"><sup class="para">[5] </sup></a>
+ There are options to define the window frame in other ways, but
+ this tutorial does not cover them. See
+ <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a> for details.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-transactions.html" title="3.4. Transactions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="tutorial-advanced.html" title="Chapter 3. Advanced Features">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-inheritance.html" title="3.6. Inheritance">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.4. Transactions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 3.6. Inheritance</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/tutorial.html b/doc/src/sgml/html/tutorial.html
new file mode 100644
index 0000000..6ed89ba
--- /dev/null
+++ b/doc/src/sgml/html/tutorial.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Part I. Tutorial</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="bug-reporting.html" title="5. Bug Reporting Guidelines" /><link rel="next" href="tutorial-start.html" title="Chapter 1. Getting Started" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Part I. Tutorial</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="bug-reporting.html" title="5. Bug Reporting Guidelines">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><th width="60%" align="center">PostgreSQL 15.4 Documentation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tutorial-start.html" title="Chapter 1. Getting Started">Next</a></td></tr></table><hr /></div><div class="part" id="TUTORIAL"><div class="titlepage"><div><div><h1 class="title">Part I. Tutorial</h1></div></div></div><div class="partintro" id="id-1.4.2"><div></div><p>
+ Welcome to the <span class="productname">PostgreSQL</span> Tutorial. The
+ following few chapters are intended to give a simple introduction
+ to <span class="productname">PostgreSQL</span>, relational database
+ concepts, and the SQL language to those who are new to any one of
+ these aspects. We only assume some general knowledge about how to
+ use computers. No particular Unix or programming experience is
+ required. This part is mainly intended to give you some hands-on
+ experience with important aspects of the
+ <span class="productname">PostgreSQL</span> system. It makes no attempt
+ to be a complete or thorough treatment of the topics it covers.
+ </p><p>
+ After you have worked through this tutorial you might want to move
+ on to reading <a class="xref" href="sql.html" title="Part II. The SQL Language">Part II</a> to gain a more formal knowledge
+ of the SQL language, or <a class="xref" href="client-interfaces.html" title="Part IV. Client Interfaces">Part IV</a> for
+ information about developing applications for
+ <span class="productname">PostgreSQL</span>. Those who set up and
+ manage their own server should also read <a class="xref" href="admin.html" title="Part III. Server Administration">Part III</a>.
+ </p><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="chapter"><a href="tutorial-start.html">1. Getting Started</a></span></dt><dd><dl><dt><span class="sect1"><a href="tutorial-install.html">1.1. Installation</a></span></dt><dt><span class="sect1"><a href="tutorial-arch.html">1.2. Architectural Fundamentals</a></span></dt><dt><span class="sect1"><a href="tutorial-createdb.html">1.3. Creating a Database</a></span></dt><dt><span class="sect1"><a href="tutorial-accessdb.html">1.4. Accessing a Database</a></span></dt></dl></dd><dt><span class="chapter"><a href="tutorial-sql.html">2. The <acronym class="acronym">SQL</acronym> Language</a></span></dt><dd><dl><dt><span class="sect1"><a href="tutorial-sql-intro.html">2.1. Introduction</a></span></dt><dt><span class="sect1"><a href="tutorial-concepts.html">2.2. Concepts</a></span></dt><dt><span class="sect1"><a href="tutorial-table.html">2.3. Creating a New Table</a></span></dt><dt><span class="sect1"><a href="tutorial-populate.html">2.4. Populating a Table With Rows</a></span></dt><dt><span class="sect1"><a href="tutorial-select.html">2.5. Querying a Table</a></span></dt><dt><span class="sect1"><a href="tutorial-join.html">2.6. Joins Between Tables</a></span></dt><dt><span class="sect1"><a href="tutorial-agg.html">2.7. Aggregate Functions</a></span></dt><dt><span class="sect1"><a href="tutorial-update.html">2.8. Updates</a></span></dt><dt><span class="sect1"><a href="tutorial-delete.html">2.9. Deletions</a></span></dt></dl></dd><dt><span class="chapter"><a href="tutorial-advanced.html">3. Advanced Features</a></span></dt><dd><dl><dt><span class="sect1"><a href="tutorial-advanced-intro.html">3.1. Introduction</a></span></dt><dt><span class="sect1"><a href="tutorial-views.html">3.2. Views</a></span></dt><dt><span class="sect1"><a href="tutorial-fk.html">3.3. Foreign Keys</a></span></dt><dt><span class="sect1"><a href="tutorial-transactions.html">3.4. Transactions</a></span></dt><dt><span class="sect1"><a href="tutorial-window.html">3.5. Window Functions</a></span></dt><dt><span class="sect1"><a href="tutorial-inheritance.html">3.6. Inheritance</a></span></dt><dt><span class="sect1"><a href="tutorial-conclusion.html">3.7. Conclusion</a></span></dt></dl></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="bug-reporting.html" title="5. Bug Reporting Guidelines">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="index.html" title="PostgreSQL 15.4 Documentation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tutorial-start.html" title="Chapter 1. Getting Started">Next</a></td></tr><tr><td width="40%" align="left" valign="top">5. Bug Reporting Guidelines </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 1. Getting Started</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv-func.html b/doc/src/sgml/html/typeconv-func.html
new file mode 100644
index 0000000..a35429c
--- /dev/null
+++ b/doc/src/sgml/html/typeconv-func.html
@@ -0,0 +1,268 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.3. Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-oper.html" title="10.2. Operators" /><link rel="next" href="typeconv-query.html" title="10.4. Value Storage" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.3. Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-oper.html" title="10.2. Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-query.html" title="10.4. Value Storage">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-FUNC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.3. Functions</h2></div></div></div><a id="id-1.5.9.8.2" class="indexterm"></a><p>
+ The specific function that is referenced by a function call
+ is determined using the following procedure.
+ </p><div class="procedure" id="id-1.5.9.8.4"><p class="title"><strong>Function Type Resolution</strong></p><ol class="procedure" type="1"><li class="step"><p>
+Select the functions to be considered from the
+<code class="classname">pg_proc</code> system catalog. If a non-schema-qualified
+function name was used, the functions
+considered are those with the matching name and argument count that are
+visible in the current search path (see <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATH" title="5.9.3. The Schema Search Path">Section 5.9.3</a>).
+If a qualified function name was given, only functions in the specified
+schema are considered.
+</p><ol type="a" class="substeps"><li class="step"><p>
+If the search path finds multiple functions of identical argument types,
+only the one appearing earliest in the path is considered. Functions of
+different argument types are considered on an equal footing regardless of
+search path position.
+</p></li><li class="step"><p>
+If a function is declared with a <code class="literal">VARIADIC</code> array parameter, and
+the call does not use the <code class="literal">VARIADIC</code> keyword, then the function
+is treated as if the array parameter were replaced by one or more occurrences
+of its element type, as needed to match the call. After such expansion the
+function might have effective argument types identical to some non-variadic
+function. In that case the function appearing earlier in the search path is
+used, or if the two functions are in the same schema, the non-variadic one is
+preferred.
+</p><p>
+This creates a security hazard when calling, via qualified name
+ <a href="#ftn.FUNC-QUALIFIED-SECURITY" class="footnote"><sup class="footnote" id="FUNC-QUALIFIED-SECURITY">[10]</sup></a>,
+a variadic function found in a schema that permits untrusted users to create
+objects. A malicious user can take control and execute arbitrary SQL
+functions as though you executed them. Substitute a call bearing
+the <code class="literal">VARIADIC</code> keyword, which bypasses this hazard. Calls
+populating <code class="literal">VARIADIC "any"</code> parameters often have no
+equivalent formulation containing the <code class="literal">VARIADIC</code> keyword. To
+issue those calls safely, the function's schema must permit only trusted users
+to create objects.
+</p></li><li class="step"><p>
+Functions that have default values for parameters are considered to match any
+call that omits zero or more of the defaultable parameter positions. If more
+than one such function matches a call, the one appearing earliest in the
+search path is used. If there are two or more such functions in the same
+schema with identical parameter types in the non-defaulted positions (which is
+possible if they have different sets of defaultable parameters), the system
+will not be able to determine which to prefer, and so an <span class="quote">“<span class="quote">ambiguous
+function call</span>”</span> error will result if no better match to the call can be
+found.
+</p><p>
+This creates an availability hazard when calling, via qualified
+name<a href="typeconv-func.html#ftn.FUNC-QUALIFIED-SECURITY" class="footnoteref"><sup class="footnoteref">[10]</sup></a>, any function found in a
+schema that permits untrusted users to create objects. A malicious user can
+create a function with the name of an existing function, replicating that
+function's parameters and appending novel parameters having default values.
+This precludes new calls to the original function. To forestall this hazard,
+place functions in schemas that permit only trusted users to create objects.
+</p></li></ol></li><li class="step"><p>
+Check for a function accepting exactly the input argument types.
+If one exists (there can be only one exact match in the set of
+functions considered), use it. Lack of an exact match creates a security
+hazard when calling, via qualified
+name<a href="typeconv-func.html#ftn.FUNC-QUALIFIED-SECURITY" class="footnoteref"><sup class="footnoteref">[10]</sup></a>, a function found in a
+schema that permits untrusted users to create objects. In such situations,
+cast arguments to force an exact match. (Cases involving <code class="type">unknown</code>
+will never find a match at this step.)
+</p></li><li class="step"><p>
+If no exact match is found, see if the function call appears
+to be a special type conversion request. This happens if the function call
+has just one argument and the function name is the same as the (internal)
+name of some data type. Furthermore, the function argument must be either
+an unknown-type literal, or a type that is binary-coercible to the named
+data type, or a type that could be converted to the named data type by
+applying that type's I/O functions (that is, the conversion is either to or
+from one of the standard string types). When these conditions are met,
+the function call is treated as a form of <code class="literal">CAST</code> specification.
+ <a href="#ftn.id-1.5.9.8.4.4.1.2" class="footnote"><sup class="footnote" id="id-1.5.9.8.4.4.1.2">[11]</sup></a>
+</p></li><li class="step"><p>
+Look for the best match.
+</p><ol type="a" class="substeps"><li class="step"><p>
+Discard candidate functions for which the input types do not match
+and cannot be converted (using an implicit conversion) to match.
+<code class="type">unknown</code> literals are
+assumed to be convertible to anything for this purpose. If only one
+candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+If any input argument is of a domain type, treat it as being of the
+domain's base type for all subsequent steps. This ensures that domains
+act like their base types for purposes of ambiguous-function resolution.
+</p></li><li class="step"><p>
+Run through all candidates and keep those with the most exact matches
+on input types. Keep all candidates if none have exact matches.
+If only one candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+Run through all candidates and keep those that accept preferred types (of the
+input data type's type category) at the most positions where type conversion
+will be required.
+Keep all candidates if none accept preferred types.
+If only one candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+If any input arguments are <code class="type">unknown</code>, check the type categories
+accepted
+at those argument positions by the remaining candidates. At each position,
+select the <code class="type">string</code> category if any candidate accepts that category.
+(This bias towards string
+is appropriate since an unknown-type literal looks like a string.)
+Otherwise, if all the remaining candidates accept the same type category,
+select that category; otherwise fail because
+the correct choice cannot be deduced without more clues.
+Now discard candidates that do not accept the selected type category.
+Furthermore, if any candidate accepts a preferred type in that category,
+discard candidates that accept non-preferred types for that argument.
+Keep all candidates if none survive these tests.
+If only one candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+If there are both <code class="type">unknown</code> and known-type arguments, and all
+the known-type arguments have the same type, assume that the
+<code class="type">unknown</code> arguments are also of that type, and check which
+candidates can accept that type at the <code class="type">unknown</code>-argument
+positions. If exactly one candidate passes this test, use it.
+Otherwise, fail.
+</p></li></ol></li></ol></div><p>
+Note that the <span class="quote">“<span class="quote">best match</span>”</span> rules are identical for operator and
+function type resolution.
+Some examples follow.
+</p><div class="example" id="id-1.5.9.8.6"><p class="title"><strong>Example 10.6. Rounding Function Argument Type Resolution</strong></p><div class="example-contents"><p>
+There is only one <code class="function">round</code> function that takes two
+arguments; it takes a first argument of type <code class="type">numeric</code> and
+a second argument of type <code class="type">integer</code>.
+So the following query automatically converts
+the first argument of type <code class="type">integer</code> to
+<code class="type">numeric</code>:
+
+</p><pre class="screen">
+SELECT round(4, 4);
+
+ round
+--------
+ 4.0000
+(1 row)
+</pre><p>
+
+That query is actually transformed by the parser to:
+</p><pre class="screen">
+SELECT round(CAST (4 AS numeric), 4);
+</pre><p>
+</p><p>
+Since numeric constants with decimal points are initially assigned the
+type <code class="type">numeric</code>, the following query will require no type
+conversion and therefore might be slightly more efficient:
+</p><pre class="screen">
+SELECT round(4.0, 4);
+</pre><p>
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.8.7"><p class="title"><strong>Example 10.7. Variadic Function Resolution</strong></p><div class="example-contents"><p>
+</p><pre class="screen">
+CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int
+ LANGUAGE sql AS 'SELECT 1';
+CREATE FUNCTION
+</pre><p>
+
+This function accepts, but does not require, the VARIADIC keyword. It
+tolerates both integer and numeric arguments:
+
+</p><pre class="screen">
+SELECT public.variadic_example(0),
+ public.variadic_example(0.0),
+ public.variadic_example(VARIADIC array[0.0]);
+ variadic_example | variadic_example | variadic_example
+------------------+------------------+------------------
+ 1 | 1 | 1
+(1 row)
+</pre><p>
+
+However, the first and second calls will prefer more-specific functions, if
+available:
+
+</p><pre class="screen">
+CREATE FUNCTION public.variadic_example(numeric) RETURNS int
+ LANGUAGE sql AS 'SELECT 2';
+CREATE FUNCTION
+
+CREATE FUNCTION public.variadic_example(int) RETURNS int
+ LANGUAGE sql AS 'SELECT 3';
+CREATE FUNCTION
+
+SELECT public.variadic_example(0),
+ public.variadic_example(0.0),
+ public.variadic_example(VARIADIC array[0.0]);
+ variadic_example | variadic_example | variadic_example
+------------------+------------------+------------------
+ 3 | 2 | 1
+(1 row)
+</pre><p>
+
+Given the default configuration and only the first function existing, the
+first and second calls are insecure. Any user could intercept them by
+creating the second or third function. By matching the argument type exactly
+and using the <code class="literal">VARIADIC</code> keyword, the third call is secure.
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.8.8"><p class="title"><strong>Example 10.8. Substring Function Type Resolution</strong></p><div class="example-contents"><p>
+There are several <code class="function">substr</code> functions, one of which
+takes types <code class="type">text</code> and <code class="type">integer</code>. If called
+with a string constant of unspecified type, the system chooses the
+candidate function that accepts an argument of the preferred category
+<code class="literal">string</code> (namely of type <code class="type">text</code>).
+
+</p><pre class="screen">
+SELECT substr('1234', 3);
+
+ substr
+--------
+ 34
+(1 row)
+</pre><p>
+</p><p>
+If the string is declared to be of type <code class="type">varchar</code>, as might be the case
+if it comes from a table, then the parser will try to convert it to become <code class="type">text</code>:
+</p><pre class="screen">
+SELECT substr(varchar '1234', 3);
+
+ substr
+--------
+ 34
+(1 row)
+</pre><p>
+
+This is transformed by the parser to effectively become:
+</p><pre class="screen">
+SELECT substr(CAST (varchar '1234' AS text), 3);
+</pre><p>
+</p><p>
+</p><div class="note"><h3 class="title">Note</h3><p>
+The parser learns from the <code class="structname">pg_cast</code> catalog that
+<code class="type">text</code> and <code class="type">varchar</code>
+are binary-compatible, meaning that one can be passed to a function that
+accepts the other without doing any physical conversion. Therefore, no
+type conversion call is really inserted in this case.
+</p></div><p>
+</p><p>
+And, if the function is called with an argument of type <code class="type">integer</code>,
+the parser will try to convert that to <code class="type">text</code>:
+</p><pre class="screen">
+SELECT substr(1234, 3);
+ERROR: function substr(integer, integer) does not exist
+HINT: No function matches the given name and argument types. You might need
+to add explicit type casts.
+</pre><p>
+
+This does not work because <code class="type">integer</code> does not have an implicit cast
+to <code class="type">text</code>. An explicit cast will work, however:
+</p><pre class="screen">
+SELECT substr(CAST (1234 AS text), 3);
+
+ substr
+--------
+ 34
+(1 row)
+</pre><p>
+</p></div></div><br class="example-break" /><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.FUNC-QUALIFIED-SECURITY" class="footnote"><p><a href="#FUNC-QUALIFIED-SECURITY" class="para"><sup class="para">[10] </sup></a>
+ The hazard does not arise with a non-schema-qualified name, because a
+ search path containing schemas that permit untrusted users to create
+ objects is not a <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage
+ pattern</a>.
+ </p></div><div id="ftn.id-1.5.9.8.4.4.1.2" class="footnote"><p><a href="#id-1.5.9.8.4.4.1.2" class="para"><sup class="para">[11] </sup></a>
+ The reason for this step is to support function-style cast specifications
+ in cases where there is not an actual cast function. If there is a cast
+ function, it is conventionally named after its output type, and so there
+ is no need to have a special case. See
+ <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a>
+ for additional commentary.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-oper.html" title="10.2. Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-query.html" title="10.4. Value Storage">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.2. Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.4. Value Storage</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv-oper.html b/doc/src/sgml/html/typeconv-oper.html
new file mode 100644
index 0000000..293e611
--- /dev/null
+++ b/doc/src/sgml/html/typeconv-oper.html
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.2. Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-overview.html" title="10.1. Overview" /><link rel="next" href="typeconv-func.html" title="10.3. Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.2. Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-overview.html" title="10.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-func.html" title="10.3. Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-OPER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.2. Operators</h2></div></div></div><a id="id-1.5.9.7.2" class="indexterm"></a><p>
+ The specific operator that is referenced by an operator expression
+ is determined using the following procedure.
+ Note that this procedure is indirectly affected
+ by the precedence of the operators involved, since that will determine
+ which sub-expressions are taken to be the inputs of which operators.
+ See <a class="xref" href="sql-syntax-lexical.html#SQL-PRECEDENCE" title="4.1.6. Operator Precedence">Section 4.1.6</a> for more information.
+ </p><div class="procedure" id="id-1.5.9.7.4"><p class="title"><strong>Operator Type Resolution</strong></p><ol class="procedure" type="1"><li class="step" id="OP-RESOL-SELECT"><p>
+Select the operators to be considered from the
+<code class="classname">pg_operator</code> system catalog. If a non-schema-qualified
+operator name was used (the usual case), the operators
+considered are those with the matching name and argument count that are
+visible in the current search path (see <a class="xref" href="ddl-schemas.html#DDL-SCHEMAS-PATH" title="5.9.3. The Schema Search Path">Section 5.9.3</a>).
+If a qualified operator name was given, only operators in the specified
+schema are considered.
+</p><ol type="a" class="substeps"><li class="step"><p>
+If the search path finds multiple operators with identical argument types,
+only the one appearing earliest in the path is considered. Operators with
+different argument types are considered on an equal footing regardless of
+search path position.
+</p></li></ol></li><li class="step" id="OP-RESOL-EXACT-MATCH"><p>
+Check for an operator accepting exactly the input argument types.
+If one exists (there can be only one exact match in the set of
+operators considered), use it. Lack of an exact match creates a security
+hazard when calling, via qualified name
+ <a href="#ftn.OP-QUALIFIED-SECURITY" class="footnote"><sup class="footnote" id="OP-QUALIFIED-SECURITY">[9]</sup></a>
+(not typical), any operator found in a schema that permits untrusted users to
+create objects. In such situations, cast arguments to force an exact match.
+</p><ol type="a" class="substeps"><li class="step" id="OP-RESOL-EXACT-UNKNOWN"><p>
+If one argument of a binary operator invocation is of the <code class="type">unknown</code> type,
+then assume it is the same type as the other argument for this check.
+Invocations involving two <code class="type">unknown</code> inputs, or a prefix operator
+with an <code class="type">unknown</code> input, will never find a match at this step.
+</p></li><li class="step" id="OP-RESOL-EXACT-DOMAIN"><p>
+If one argument of a binary operator invocation is of the <code class="type">unknown</code>
+type and the other is of a domain type, next check to see if there is an
+operator accepting exactly the domain's base type on both sides; if so, use it.
+</p></li></ol></li><li class="step" id="OP-RESOL-BEST-MATCH"><p>
+Look for the best match.
+</p><ol type="a" class="substeps"><li class="step"><p>
+Discard candidate operators for which the input types do not match
+and cannot be converted (using an implicit conversion) to match.
+<code class="type">unknown</code> literals are
+assumed to be convertible to anything for this purpose. If only one
+candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+If any input argument is of a domain type, treat it as being of the
+domain's base type for all subsequent steps. This ensures that domains
+act like their base types for purposes of ambiguous-operator resolution.
+</p></li><li class="step"><p>
+Run through all candidates and keep those with the most exact matches
+on input types. Keep all candidates if none have exact matches.
+If only one candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+Run through all candidates and keep those that accept preferred types (of the
+input data type's type category) at the most positions where type conversion
+will be required.
+Keep all candidates if none accept preferred types.
+If only one candidate remains, use it; else continue to the next step.
+</p></li><li class="step"><p>
+If any input arguments are <code class="type">unknown</code>, check the type
+categories accepted at those argument positions by the remaining
+candidates. At each position, select the <code class="type">string</code> category
+if any
+candidate accepts that category. (This bias towards string is appropriate
+since an unknown-type literal looks like a string.) Otherwise, if
+all the remaining candidates accept the same type category, select that
+category; otherwise fail because the correct choice cannot be deduced
+without more clues. Now discard
+candidates that do not accept the selected type category. Furthermore,
+if any candidate accepts a preferred type in that category,
+discard candidates that accept non-preferred types for that argument.
+Keep all candidates if none survive these tests.
+If only one candidate remains, use it; else continue to the next step.
+</p></li><li class="step" id="OP-RESOL-LAST-UNKNOWN"><p>
+If there are both <code class="type">unknown</code> and known-type arguments, and all
+the known-type arguments have the same type, assume that the
+<code class="type">unknown</code> arguments are also of that type, and check which
+candidates can accept that type at the <code class="type">unknown</code>-argument
+positions. If exactly one candidate passes this test, use it.
+Otherwise, fail.
+</p></li></ol></li></ol></div><p>
+Some examples follow.
+</p><div class="example" id="id-1.5.9.7.6"><p class="title"><strong>Example 10.1. Square Root Operator Type Resolution</strong></p><div class="example-contents"><p>
+There is only one square root operator (prefix <code class="literal">|/</code>)
+defined in the standard catalog, and it takes an argument of type
+<code class="type">double precision</code>.
+The scanner assigns an initial type of <code class="type">integer</code> to the argument
+in this query expression:
+</p><pre class="screen">
+SELECT |/ 40 AS "square root of 40";
+ square root of 40
+-------------------
+ 6.324555320336759
+(1 row)
+</pre><p>
+
+So the parser does a type conversion on the operand and the query
+is equivalent to:
+
+</p><pre class="screen">
+SELECT |/ CAST(40 AS double precision) AS "square root of 40";
+</pre><p>
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.7"><p class="title"><strong>Example 10.2. String Concatenation Operator Type Resolution</strong></p><div class="example-contents"><p>
+A string-like syntax is used for working with string types and for
+working with complex extension types.
+Strings with unspecified type are matched with likely operator candidates.
+</p><p>
+An example with one unspecified argument:
+</p><pre class="screen">
+SELECT text 'abc' || 'def' AS "text and unknown";
+
+ text and unknown
+------------------
+ abcdef
+(1 row)
+</pre><p>
+</p><p>
+In this case the parser looks to see if there is an operator taking <code class="type">text</code>
+for both arguments. Since there is, it assumes that the second argument should
+be interpreted as type <code class="type">text</code>.
+</p><p>
+Here is a concatenation of two values of unspecified types:
+</p><pre class="screen">
+SELECT 'abc' || 'def' AS "unspecified";
+
+ unspecified
+-------------
+ abcdef
+(1 row)
+</pre><p>
+</p><p>
+In this case there is no initial hint for which type to use, since no types
+are specified in the query. So, the parser looks for all candidate operators
+and finds that there are candidates accepting both string-category and
+bit-string-category inputs. Since string category is preferred when available,
+that category is selected, and then the
+preferred type for strings, <code class="type">text</code>, is used as the specific
+type to resolve the unknown-type literals as.
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.8"><p class="title"><strong>Example 10.3. Absolute-Value and Negation Operator Type Resolution</strong></p><div class="example-contents"><p>
+The <span class="productname">PostgreSQL</span> operator catalog has several
+entries for the prefix operator <code class="literal">@</code>, all of which implement
+absolute-value operations for various numeric data types. One of these
+entries is for type <code class="type">float8</code>, which is the preferred type in
+the numeric category. Therefore, <span class="productname">PostgreSQL</span>
+will use that entry when faced with an <code class="type">unknown</code> input:
+</p><pre class="screen">
+SELECT @ '-4.5' AS "abs";
+ abs
+-----
+ 4.5
+(1 row)
+</pre><p>
+Here the system has implicitly resolved the unknown-type literal as type
+<code class="type">float8</code> before applying the chosen operator. We can verify that
+<code class="type">float8</code> and not some other type was used:
+</p><pre class="screen">
+SELECT @ '-4.5e500' AS "abs";
+
+ERROR: "-4.5e500" is out of range for type double precision
+</pre><p>
+</p><p>
+On the other hand, the prefix operator <code class="literal">~</code> (bitwise negation)
+is defined only for integer data types, not for <code class="type">float8</code>. So, if we
+try a similar case with <code class="literal">~</code>, we get:
+</p><pre class="screen">
+SELECT ~ '20' AS "negation";
+
+ERROR: operator is not unique: ~ "unknown"
+HINT: Could not choose a best candidate operator. You might need to add
+explicit type casts.
+</pre><p>
+This happens because the system cannot decide which of the several
+possible <code class="literal">~</code> operators should be preferred. We can help
+it out with an explicit cast:
+</p><pre class="screen">
+SELECT ~ CAST('20' AS int8) AS "negation";
+
+ negation
+----------
+ -21
+(1 row)
+</pre><p>
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.9"><p class="title"><strong>Example 10.4. Array Inclusion Operator Type Resolution</strong></p><div class="example-contents"><p>
+Here is another example of resolving an operator with one known and one
+unknown input:
+</p><pre class="screen">
+SELECT array[1,2] &lt;@ '{1,2,3}' as "is subset";
+
+ is subset
+-----------
+ t
+(1 row)
+</pre><p>
+The <span class="productname">PostgreSQL</span> operator catalog has several
+entries for the infix operator <code class="literal">&lt;@</code>, but the only two that
+could possibly accept an integer array on the left-hand side are
+array inclusion (<code class="type">anyarray</code> <code class="literal">&lt;@</code> <code class="type">anyarray</code>)
+and range inclusion (<code class="type">anyelement</code> <code class="literal">&lt;@</code> <code class="type">anyrange</code>).
+Since none of these polymorphic pseudo-types (see <a class="xref" href="datatype-pseudo.html" title="8.21. Pseudo-Types">Section 8.21</a>) are considered preferred, the parser cannot
+resolve the ambiguity on that basis.
+However, <a class="xref" href="typeconv-oper.html#OP-RESOL-LAST-UNKNOWN" title="Step 3.f">Step 3.f</a> tells
+it to assume that the unknown-type literal is of the same type as the other
+input, that is, integer array. Now only one of the two operators can match,
+so array inclusion is selected. (Had range inclusion been selected, we would
+have gotten an error, because the string does not have the right format to be
+a range literal.)
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.7.10"><p class="title"><strong>Example 10.5. Custom Operator on a Domain Type</strong></p><div class="example-contents"><p>
+Users sometimes try to declare operators applying just to a domain type.
+This is possible but is not nearly as useful as it might seem, because the
+operator resolution rules are designed to select operators applying to the
+domain's base type. As an example consider
+</p><pre class="screen">
+CREATE DOMAIN mytext AS text CHECK(...);
+CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...;
+CREATE OPERATOR = (procedure=mytext_eq_text, leftarg=mytext, rightarg=text);
+CREATE TABLE mytable (val mytext);
+
+SELECT * FROM mytable WHERE val = 'foo';
+</pre><p>
+This query will not use the custom operator. The parser will first see if
+there is a <code class="type">mytext</code> <code class="literal">=</code> <code class="type">mytext</code> operator
+(<a class="xref" href="typeconv-oper.html#OP-RESOL-EXACT-UNKNOWN" title="Step 2.a">Step 2.a</a>), which there is not;
+then it will consider the domain's base type <code class="type">text</code>, and see if
+there is a <code class="type">text</code> <code class="literal">=</code> <code class="type">text</code> operator
+(<a class="xref" href="typeconv-oper.html#OP-RESOL-EXACT-DOMAIN" title="Step 2.b">Step 2.b</a>), which there is;
+so it resolves the <code class="type">unknown</code>-type literal as <code class="type">text</code> and
+uses the <code class="type">text</code> <code class="literal">=</code> <code class="type">text</code> operator.
+The only way to get the custom operator to be used is to explicitly cast
+the literal:
+</p><pre class="screen">
+SELECT * FROM mytable WHERE val = text 'foo';
+</pre><p>
+so that the <code class="type">mytext</code> <code class="literal">=</code> <code class="type">text</code> operator is found
+immediately according to the exact-match rule. If the best-match rules
+are reached, they actively discriminate against operators on domain types.
+If they did not, such an operator would create too many ambiguous-operator
+failures, because the casting rules always consider a domain as castable
+to or from its base type, and so the domain operator would be considered
+usable in all the same cases as a similarly-named operator on the base type.
+</p></div></div><br class="example-break" /><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.OP-QUALIFIED-SECURITY" class="footnote"><p><a href="#OP-QUALIFIED-SECURITY" class="para"><sup class="para">[9] </sup></a>
+ The hazard does not arise with a non-schema-qualified name, because a
+ search path containing schemas that permit untrusted users to create
+ objects is not a <a class="link" href="ddl-schemas.html#DDL-SCHEMAS-PATTERNS" title="5.9.6. Usage Patterns">secure schema usage
+ pattern</a>.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-overview.html" title="10.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-func.html" title="10.3. Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.3. Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv-overview.html b/doc/src/sgml/html/typeconv-overview.html
new file mode 100644
index 0000000..6fab9b6
--- /dev/null
+++ b/doc/src/sgml/html/typeconv-overview.html
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv.html" title="Chapter 10. Type Conversion" /><link rel="next" href="typeconv-oper.html" title="10.2. Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv.html" title="Chapter 10. Type Conversion">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-oper.html" title="10.2. Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.1. Overview</h2></div></div></div><p>
+<acronym class="acronym">SQL</acronym> is a strongly typed language. That is, every data item
+has an associated data type which determines its behavior and allowed usage.
+<span class="productname">PostgreSQL</span> has an extensible type system that is
+more general and flexible than other <acronym class="acronym">SQL</acronym> implementations.
+Hence, most type conversion behavior in <span class="productname">PostgreSQL</span>
+is governed by general rules rather than by ad hoc
+heuristics. This allows the use of mixed-type expressions even with
+user-defined types.
+</p><p>
+The <span class="productname">PostgreSQL</span> scanner/parser divides lexical
+elements into five fundamental categories: integers, non-integer numbers,
+strings, identifiers, and key words. Constants of most non-numeric types are
+first classified as strings. The <acronym class="acronym">SQL</acronym> language definition
+allows specifying type names with strings, and this mechanism can be used in
+<span class="productname">PostgreSQL</span> to start the parser down the correct
+path. For example, the query:
+
+</p><pre class="screen">
+SELECT text 'Origin' AS "label", point '(0,0)' AS "value";
+
+ label | value
+--------+-------
+ Origin | (0,0)
+(1 row)
+</pre><p>
+
+has two literal constants, of type <code class="type">text</code> and <code class="type">point</code>.
+If a type is not specified for a string literal, then the placeholder type
+<code class="type">unknown</code> is assigned initially, to be resolved in later
+stages as described below.
+</p><p>
+There are four fundamental <acronym class="acronym">SQL</acronym> constructs requiring
+distinct type conversion rules in the <span class="productname">PostgreSQL</span>
+parser:
+
+</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+Function calls
+</span></dt><dd><p>
+Much of the <span class="productname">PostgreSQL</span> type system is built around a
+rich set of functions. Functions can have one or more arguments.
+Since <span class="productname">PostgreSQL</span> permits function
+overloading, the function name alone does not uniquely identify the function
+to be called; the parser must select the right function based on the data
+types of the supplied arguments.
+</p></dd><dt><span class="term">
+Operators
+</span></dt><dd><p>
+<span class="productname">PostgreSQL</span> allows expressions with
+prefix (one-argument) operators,
+as well as infix (two-argument) operators. Like functions, operators can
+be overloaded, so the same problem of selecting the right operator
+exists.
+</p></dd><dt><span class="term">
+Value Storage
+</span></dt><dd><p>
+<acronym class="acronym">SQL</acronym> <code class="command">INSERT</code> and <code class="command">UPDATE</code> statements place the results of
+expressions into a table. The expressions in the statement must be matched up
+with, and perhaps converted to, the types of the target columns.
+</p></dd><dt><span class="term">
+<code class="literal">UNION</code>, <code class="literal">CASE</code>, and related constructs
+</span></dt><dd><p>
+Since all query results from a unionized <code class="command">SELECT</code> statement
+must appear in a single set of columns, the types of the results of each
+<code class="command">SELECT</code> clause must be matched up and converted to a uniform set.
+Similarly, the result expressions of a <code class="literal">CASE</code> construct must be
+converted to a common type so that the <code class="literal">CASE</code> expression as a whole
+has a known output type. Some other constructs, such
+as <code class="literal">ARRAY[]</code> and the <code class="function">GREATEST</code>
+and <code class="function">LEAST</code> functions, likewise require determination of a
+common type for several subexpressions.
+</p></dd></dl></div><p>
+</p><p>
+The system catalogs store information about which conversions, or
+<em class="firstterm">casts</em>, exist between which data types, and how to
+perform those conversions. Additional casts can be added by the user
+with the <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a>
+command. (This is usually
+done in conjunction with defining new data types. The set of casts
+between built-in types has been carefully crafted and is best not
+altered.)
+</p><a id="id-1.5.9.6.6" class="indexterm"></a><p>
+An additional heuristic provided by the parser allows improved determination
+of the proper casting behavior among groups of types that have implicit casts.
+Data types are divided into several basic <em class="firstterm">type
+categories</em>, including <code class="type">boolean</code>, <code class="type">numeric</code>,
+<code class="type">string</code>, <code class="type">bitstring</code>, <code class="type">datetime</code>,
+<code class="type">timespan</code>, <code class="type">geometric</code>, <code class="type">network</code>, and
+user-defined. (For a list see <a class="xref" href="catalog-pg-type.html#CATALOG-TYPCATEGORY-TABLE" title="Table 53.65. typcategory Codes">Table 53.65</a>;
+but note it is also possible to create custom type categories.) Within each
+category there can be one or more <em class="firstterm">preferred types</em>, which
+are preferred when there is a choice of possible types. With careful selection
+of preferred types and available implicit casts, it is possible to ensure that
+ambiguous expressions (those with multiple candidate parsing solutions) can be
+resolved in a useful way.
+</p><p>
+All type conversion rules are designed with several principles in mind:
+
+</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+Implicit conversions should never have surprising or unpredictable outcomes.
+</p></li><li class="listitem"><p>
+There should be no extra overhead in the parser or executor
+if a query does not need implicit type conversion.
+That is, if a query is well-formed and the types already match, then the query should execute
+without spending extra time in the parser and without introducing unnecessary implicit conversion
+calls in the query.
+</p></li><li class="listitem"><p>
+Additionally, if a query usually requires an implicit conversion for a function, and
+if then the user defines a new function with the correct argument types, the parser
+should use this new function and no longer do implicit conversion to use the old function.
+</p></li></ul></div><p>
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv.html" title="Chapter 10. Type Conversion">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-oper.html" title="10.2. Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 10. Type Conversion </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.2. Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv-query.html b/doc/src/sgml/html/typeconv-query.html
new file mode 100644
index 0000000..186e355
--- /dev/null
+++ b/doc/src/sgml/html/typeconv-query.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.4. Value Storage</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-func.html" title="10.3. Functions" /><link rel="next" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.4. Value Storage</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-func.html" title="10.3. Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-QUERY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.4. Value Storage</h2></div></div></div><p>
+ Values to be inserted into a table are converted to the destination
+ column's data type according to the
+ following steps.
+ </p><div class="procedure" id="id-1.5.9.9.3"><p class="title"><strong>Value Storage Type Conversion</strong></p><ol class="procedure" type="1"><li class="step"><p>
+Check for an exact match with the target.
+</p></li><li class="step"><p>
+Otherwise, try to convert the expression to the target type. This is possible
+if an <em class="firstterm">assignment cast</em> between the two types is registered in the
+<code class="structname">pg_cast</code> catalog (see <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a>).
+Alternatively, if the expression is an unknown-type literal, the contents of
+the literal string will be fed to the input conversion routine for the target
+type.
+</p></li><li class="step"><p>
+Check to see if there is a sizing cast for the target type. A sizing
+cast is a cast from that type to itself. If one is found in the
+<code class="structname">pg_cast</code> catalog, apply it to the expression before storing
+into the destination column. The implementation function for such a cast
+always takes an extra parameter of type <code class="type">integer</code>, which receives
+the destination column's <code class="structfield">atttypmod</code> value (typically its
+declared length, although the interpretation of <code class="structfield">atttypmod</code>
+varies for different data types), and it may take a third <code class="type">boolean</code>
+parameter that says whether the cast is explicit or implicit. The cast
+function
+is responsible for applying any length-dependent semantics such as size
+checking or truncation.
+</p></li></ol></div><div class="example" id="id-1.5.9.9.4"><p class="title"><strong>Example 10.9. <code class="type">character</code> Storage Type Conversion</strong></p><div class="example-contents"><p>
+For a target column declared as <code class="type">character(20)</code> the following
+statement shows that the stored value is sized correctly:
+
+</p><pre class="screen">
+CREATE TABLE vv (v character(20));
+INSERT INTO vv SELECT 'abc' || 'def';
+SELECT v, octet_length(v) FROM vv;
+
+ v | octet_length
+----------------------+--------------
+ abcdef | 20
+(1 row)
+</pre><p>
+</p><p>
+What has really happened here is that the two unknown literals are resolved
+to <code class="type">text</code> by default, allowing the <code class="literal">||</code> operator
+to be resolved as <code class="type">text</code> concatenation. Then the <code class="type">text</code>
+result of the operator is converted to <code class="type">bpchar</code> (<span class="quote">“<span class="quote">blank-padded
+char</span>”</span>, the internal name of the <code class="type">character</code> data type) to match the target
+column type. (Since the conversion from <code class="type">text</code> to
+<code class="type">bpchar</code> is binary-coercible, this conversion does
+not insert any real function call.) Finally, the sizing function
+<code class="literal">bpchar(bpchar, integer, boolean)</code> is found in the system catalog
+and applied to the operator's result and the stored column length. This
+type-specific function performs the required length check and addition of
+padding spaces.
+</p></div></div><br class="example-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-func.html" title="10.3. Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.3. Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.5. <code class="literal">UNION</code>, <code class="literal">CASE</code>, and Related Constructs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv-select.html b/doc/src/sgml/html/typeconv-select.html
new file mode 100644
index 0000000..feb04d0
--- /dev/null
+++ b/doc/src/sgml/html/typeconv-select.html
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.6. SELECT Output Columns</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs" /><link rel="next" href="indexes.html" title="Chapter 11. Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.6. <code class="literal">SELECT</code> Output Columns</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="indexes.html" title="Chapter 11. Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-SELECT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.6. <code class="literal">SELECT</code> Output Columns</h2></div></div></div><a id="id-1.5.9.11.2" class="indexterm"></a><p>
+The rules given in the preceding sections will result in assignment
+of non-<code class="type">unknown</code> data types to all expressions in an SQL query,
+except for unspecified-type literals that appear as simple output
+columns of a <code class="command">SELECT</code> command. For example, in
+
+</p><pre class="screen">
+SELECT 'Hello World';
+</pre><p>
+
+there is nothing to identify what type the string literal should be
+taken as. In this situation <span class="productname">PostgreSQL</span> will fall back
+to resolving the literal's type as <code class="type">text</code>.
+</p><p>
+When the <code class="command">SELECT</code> is one arm of a <code class="literal">UNION</code>
+(or <code class="literal">INTERSECT</code> or <code class="literal">EXCEPT</code>) construct, or when it
+appears within <code class="command">INSERT ... SELECT</code>, this rule is not applied
+since rules given in preceding sections take precedence. The type of an
+unspecified-type literal can be taken from the other <code class="literal">UNION</code> arm
+in the first case, or from the destination column in the second case.
+</p><p>
+<code class="literal">RETURNING</code> lists are treated the same as <code class="command">SELECT</code>
+output lists for this purpose.
+</p><div class="note"><h3 class="title">Note</h3><p>
+ Prior to <span class="productname">PostgreSQL</span> 10, this rule did not exist, and
+ unspecified-type literals in a <code class="command">SELECT</code> output list were
+ left as type <code class="type">unknown</code>. That had assorted bad consequences,
+ so it's been changed.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-union-case.html" title="10.5. UNION, CASE, and Related Constructs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="indexes.html" title="Chapter 11. Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.5. <code class="literal">UNION</code>, <code class="literal">CASE</code>, and Related Constructs </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 11. Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv-union-case.html b/doc/src/sgml/html/typeconv-union-case.html
new file mode 100644
index 0000000..74f93fe
--- /dev/null
+++ b/doc/src/sgml/html/typeconv-union-case.html
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>10.5. UNION, CASE, and Related Constructs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="typeconv-query.html" title="10.4. Value Storage" /><link rel="next" href="typeconv-select.html" title="10.6. SELECT Output Columns" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">10.5. <code class="literal">UNION</code>, <code class="literal">CASE</code>, and Related Constructs</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="typeconv-query.html" title="10.4. Value Storage">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><th width="60%" align="center">Chapter 10. Type Conversion</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-select.html" title="10.6. SELECT Output Columns">Next</a></td></tr></table><hr /></div><div class="sect1" id="TYPECONV-UNION-CASE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">10.5. <code class="literal">UNION</code>, <code class="literal">CASE</code>, and Related Constructs</h2></div></div></div><a id="id-1.5.9.10.2" class="indexterm"></a><a id="id-1.5.9.10.3" class="indexterm"></a><a id="id-1.5.9.10.4" class="indexterm"></a><a id="id-1.5.9.10.5" class="indexterm"></a><a id="id-1.5.9.10.6" class="indexterm"></a><a id="id-1.5.9.10.7" class="indexterm"></a><p>
+SQL <code class="literal">UNION</code> constructs must match up possibly dissimilar
+types to become a single result set. The resolution algorithm is
+applied separately to each output column of a union query. The
+<code class="literal">INTERSECT</code> and <code class="literal">EXCEPT</code> constructs resolve
+dissimilar types in the same way as <code class="literal">UNION</code>.
+Some other constructs, including
+<code class="literal">CASE</code>, <code class="literal">ARRAY</code>, <code class="literal">VALUES</code>,
+and the <code class="function">GREATEST</code> and <code class="function">LEAST</code>
+functions, use the identical
+algorithm to match up their component expressions and select a result
+data type.
+</p><div class="procedure" id="id-1.5.9.10.9"><p class="title"><strong>Type Resolution for <code class="literal">UNION</code>, <code class="literal">CASE</code>,
+and Related Constructs</strong></p><ol class="procedure" type="1"><li class="step"><p>
+If all inputs are of the same type, and it is not <code class="type">unknown</code>,
+resolve as that type.
+</p></li><li class="step"><p>
+If any input is of a domain type, treat it as being of the
+domain's base type for all subsequent steps.
+ <a href="#ftn.id-1.5.9.10.9.3.1.1" class="footnote"><sup class="footnote" id="id-1.5.9.10.9.3.1.1">[12]</sup></a>
+</p></li><li class="step"><p>
+If all inputs are of type <code class="type">unknown</code>, resolve as type
+<code class="type">text</code> (the preferred type of the string category).
+Otherwise, <code class="type">unknown</code> inputs are ignored for the purposes
+of the remaining rules.
+</p></li><li class="step"><p>
+If the non-unknown inputs are not all of the same type category, fail.
+</p></li><li class="step"><p>
+Select the first non-unknown input type as the candidate type,
+then consider each other non-unknown input type, left to right.
+ <a href="#ftn.id-1.5.9.10.9.6.1.1" class="footnote"><sup class="footnote" id="id-1.5.9.10.9.6.1.1">[13]</sup></a>
+If the candidate type can be implicitly converted to the other type,
+but not vice-versa, select the other type as the new candidate type.
+Then continue considering the remaining inputs. If, at any stage of this
+process, a preferred type is selected, stop considering additional
+inputs.
+</p></li><li class="step"><p>
+Convert all inputs to the final candidate type. Fail if there is not an
+implicit conversion from a given input type to the candidate type.
+</p></li></ol></div><p>
+Some examples follow.
+</p><div class="example" id="id-1.5.9.10.11"><p class="title"><strong>Example 10.10. Type Resolution with Underspecified Types in a Union</strong></p><div class="example-contents"><p>
+</p><pre class="screen">
+SELECT text 'a' AS "text" UNION SELECT 'b';
+
+ text
+------
+ a
+ b
+(2 rows)
+</pre><p>
+Here, the unknown-type literal <code class="literal">'b'</code> will be resolved to type <code class="type">text</code>.
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.10.12"><p class="title"><strong>Example 10.11. Type Resolution in a Simple Union</strong></p><div class="example-contents"><p>
+</p><pre class="screen">
+SELECT 1.2 AS "numeric" UNION SELECT 1;
+
+ numeric
+---------
+ 1
+ 1.2
+(2 rows)
+</pre><p>
+The literal <code class="literal">1.2</code> is of type <code class="type">numeric</code>,
+and the <code class="type">integer</code> value <code class="literal">1</code> can be cast implicitly to
+<code class="type">numeric</code>, so that type is used.
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.10.13"><p class="title"><strong>Example 10.12. Type Resolution in a Transposed Union</strong></p><div class="example-contents"><p>
+</p><pre class="screen">
+SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
+
+ real
+------
+ 1
+ 2.2
+(2 rows)
+</pre><p>
+Here, since type <code class="type">real</code> cannot be implicitly cast to <code class="type">integer</code>,
+but <code class="type">integer</code> can be implicitly cast to <code class="type">real</code>, the union
+result type is resolved as <code class="type">real</code>.
+</p></div></div><br class="example-break" /><div class="example" id="id-1.5.9.10.14"><p class="title"><strong>Example 10.13. Type Resolution in a Nested Union</strong></p><div class="example-contents"><p>
+</p><pre class="screen">
+SELECT NULL UNION SELECT NULL UNION SELECT 1;
+
+ERROR: UNION types text and integer cannot be matched
+</pre><p>
+This failure occurs because <span class="productname">PostgreSQL</span> treats
+multiple <code class="literal">UNION</code>s as a nest of pairwise operations;
+that is, this input is the same as
+</p><pre class="screen">
+(SELECT NULL UNION SELECT NULL) UNION SELECT 1;
+</pre><p>
+The inner <code class="literal">UNION</code> is resolved as emitting
+type <code class="type">text</code>, according to the rules given above. Then the
+outer <code class="literal">UNION</code> has inputs of types <code class="type">text</code>
+and <code class="type">integer</code>, leading to the observed error. The problem
+can be fixed by ensuring that the leftmost <code class="literal">UNION</code>
+has at least one input of the desired result type.
+</p><p>
+<code class="literal">INTERSECT</code> and <code class="literal">EXCEPT</code> operations are
+likewise resolved pairwise. However, the other constructs described in this
+section consider all of their inputs in one resolution step.
+</p></div></div><br class="example-break" /><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.5.9.10.9.3.1.1" class="footnote"><p><a href="#id-1.5.9.10.9.3.1.1" class="para"><sup class="para">[12] </sup></a>
+ Somewhat like the treatment of domain inputs for operators and
+ functions, this behavior allows a domain type to be preserved through
+ a <code class="literal">UNION</code> or similar construct, so long as the user is
+ careful to ensure that all inputs are implicitly or explicitly of that
+ exact type. Otherwise the domain's base type will be used.
+ </p></div><div id="ftn.id-1.5.9.10.9.6.1.1" class="footnote"><p><a href="#id-1.5.9.10.9.6.1.1" class="para"><sup class="para">[13] </sup></a>
+ For historical reasons, <code class="literal">CASE</code> treats
+ its <code class="literal">ELSE</code> clause (if any) as the <span class="quote">“<span class="quote">first</span>”</span>
+ input, with the <code class="literal">THEN</code> clauses(s) considered after
+ that. In all other cases, <span class="quote">“<span class="quote">left to right</span>”</span> means the order
+ in which the expressions appear in the query text.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="typeconv-query.html" title="10.4. Value Storage">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="typeconv.html" title="Chapter 10. Type Conversion">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-select.html" title="10.6. SELECT Output Columns">Next</a></td></tr><tr><td width="40%" align="left" valign="top">10.4. Value Storage </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.6. <code class="literal">SELECT</code> Output Columns</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/typeconv.html b/doc/src/sgml/html/typeconv.html
new file mode 100644
index 0000000..1e4c598
--- /dev/null
+++ b/doc/src/sgml/html/typeconv.html
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 10. Type Conversion</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="functions-statistics.html" title="9.30. Statistics Information Functions" /><link rel="next" href="typeconv-overview.html" title="10.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 10. Type Conversion</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="functions-statistics.html" title="9.30. Statistics Information Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><th width="60%" align="center">Part II. The SQL Language</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="typeconv-overview.html" title="10.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="TYPECONV"><div class="titlepage"><div><div><h2 class="title">Chapter 10. Type Conversion</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="typeconv-overview.html">10.1. Overview</a></span></dt><dt><span class="sect1"><a href="typeconv-oper.html">10.2. Operators</a></span></dt><dt><span class="sect1"><a href="typeconv-func.html">10.3. Functions</a></span></dt><dt><span class="sect1"><a href="typeconv-query.html">10.4. Value Storage</a></span></dt><dt><span class="sect1"><a href="typeconv-union-case.html">10.5. <code class="literal">UNION</code>, <code class="literal">CASE</code>, and Related Constructs</a></span></dt><dt><span class="sect1"><a href="typeconv-select.html">10.6. <code class="literal">SELECT</code> Output Columns</a></span></dt></dl></div><a id="id-1.5.9.2" class="indexterm"></a><p>
+<acronym class="acronym">SQL</acronym> statements can, intentionally or not, require
+the mixing of different data types in the same expression.
+<span class="productname">PostgreSQL</span> has extensive facilities for
+evaluating mixed-type expressions.
+</p><p>
+In many cases a user does not need
+to understand the details of the type conversion mechanism.
+However, implicit conversions done by <span class="productname">PostgreSQL</span>
+can affect the results of a query. When necessary, these results
+can be tailored by using <span class="emphasis"><em>explicit</em></span> type conversion.
+</p><p>
+This chapter introduces the <span class="productname">PostgreSQL</span>
+type conversion mechanisms and conventions.
+Refer to the relevant sections in <a class="xref" href="datatype.html" title="Chapter 8. Data Types">Chapter 8</a> and <a class="xref" href="functions.html" title="Chapter 9. Functions and Operators">Chapter 9</a>
+for more information on specific data types and allowed functions and
+operators.
+</p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="functions-statistics.html" title="9.30. Statistics Information Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql.html" title="Part II. The SQL Language">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="typeconv-overview.html" title="10.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">9.30. Statistics Information Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 10.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/unaccent.html b/doc/src/sgml/html/unaccent.html
new file mode 100644
index 0000000..72554f8
--- /dev/null
+++ b/doc/src/sgml/html/unaccent.html
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.48. unaccent</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="tsm-system-time.html" title="F.47. tsm_system_time" /><link rel="next" href="uuid-ossp.html" title="F.49. uuid-ossp" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.48. unaccent</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="tsm-system-time.html" title="F.47. tsm_system_time">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="uuid-ossp.html" title="F.49. uuid-ossp">Next</a></td></tr></table><hr /></div><div class="sect1" id="UNACCENT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.48. unaccent</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="unaccent.html#id-1.11.7.57.6">F.48.1. Configuration</a></span></dt><dt><span class="sect2"><a href="unaccent.html#id-1.11.7.57.7">F.48.2. Usage</a></span></dt><dt><span class="sect2"><a href="unaccent.html#id-1.11.7.57.8">F.48.3. Functions</a></span></dt></dl></div><a id="id-1.11.7.57.2" class="indexterm"></a><p>
+ <code class="filename">unaccent</code> is a text search dictionary that removes accents
+ (diacritic signs) from lexemes.
+ It's a filtering dictionary, which means its output is
+ always passed to the next dictionary (if any), unlike the normal
+ behavior of dictionaries. This allows accent-insensitive processing
+ for full text search.
+ </p><p>
+ The current implementation of <code class="filename">unaccent</code> cannot be used as a
+ normalizing dictionary for the <code class="filename">thesaurus</code> dictionary.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.57.6"><div class="titlepage"><div><div><h3 class="title">F.48.1. Configuration</h3></div></div></div><p>
+ An <code class="literal">unaccent</code> dictionary accepts the following options:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <code class="literal">RULES</code> is the base name of the file containing the list of
+ translation rules. This file must be stored in
+ <code class="filename">$SHAREDIR/tsearch_data/</code> (where <code class="literal">$SHAREDIR</code> means
+ the <span class="productname">PostgreSQL</span> installation's shared-data directory).
+ Its name must end in <code class="literal">.rules</code> (which is not to be included in
+ the <code class="literal">RULES</code> parameter).
+ </p></li></ul></div><p>
+ The rules file has the following format:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Each line represents one translation rule, consisting of a character with
+ accent followed by a character without accent. The first is translated
+ into the second. For example,
+</p><pre class="programlisting">
+À A
+Á A
+Â A
+Ã A
+Ä A
+Å A
+Æ AE
+</pre><p>
+ The two characters must be separated by whitespace, and any leading or
+ trailing whitespace on a line is ignored.
+ </p></li><li class="listitem"><p>
+ Alternatively, if only one character is given on a line, instances of
+ that character are deleted; this is useful in languages where accents
+ are represented by separate characters.
+ </p></li><li class="listitem"><p>
+ Actually, each <span class="quote">“<span class="quote">character</span>”</span> can be any string not containing
+ whitespace, so <code class="filename">unaccent</code> dictionaries could be used for
+ other sorts of substring substitutions besides diacritic removal.
+ </p></li><li class="listitem"><p>
+ As with other <span class="productname">PostgreSQL</span> text search configuration files,
+ the rules file must be stored in UTF-8 encoding. The data is
+ automatically translated into the current database's encoding when
+ loaded. Any lines containing untranslatable characters are silently
+ ignored, so that rules files can contain rules that are not applicable in
+ the current encoding.
+ </p></li></ul></div><p>
+ A more complete example, which is directly useful for most European
+ languages, can be found in <code class="filename">unaccent.rules</code>, which is installed
+ in <code class="filename">$SHAREDIR/tsearch_data/</code> when the <code class="filename">unaccent</code>
+ module is installed. This rules file translates characters with accents
+ to the same characters without accents, and it also expands ligatures
+ into the equivalent series of simple characters (for example, Æ to
+ AE).
+ </p></div><div class="sect2" id="id-1.11.7.57.7"><div class="titlepage"><div><div><h3 class="title">F.48.2. Usage</h3></div></div></div><p>
+ Installing the <code class="literal">unaccent</code> extension creates a text
+ search template <code class="literal">unaccent</code> and a dictionary <code class="literal">unaccent</code>
+ based on it. The <code class="literal">unaccent</code> dictionary has the default
+ parameter setting <code class="literal">RULES='unaccent'</code>, which makes it immediately
+ usable with the standard <code class="filename">unaccent.rules</code> file.
+ If you wish, you can alter the parameter, for example
+
+</p><pre class="programlisting">
+mydb=# ALTER TEXT SEARCH DICTIONARY unaccent (RULES='my_rules');
+</pre><p>
+
+ or create new dictionaries based on the template.
+ </p><p>
+ To test the dictionary, you can try:
+</p><pre class="programlisting">
+mydb=# select ts_lexize('unaccent','Hôtel');
+ ts_lexize
+-----------
+ {Hotel}
+(1 row)
+</pre><p>
+ </p><p>
+ Here is an example showing how to insert the
+ <code class="filename">unaccent</code> dictionary into a text search configuration:
+</p><pre class="programlisting">
+mydb=# CREATE TEXT SEARCH CONFIGURATION fr ( COPY = french );
+mydb=# ALTER TEXT SEARCH CONFIGURATION fr
+ ALTER MAPPING FOR hword, hword_part, word
+ WITH unaccent, french_stem;
+mydb=# select to_tsvector('fr','Hôtels de la Mer');
+ to_tsvector
+-------------------
+ 'hotel':1 'mer':4
+(1 row)
+
+mydb=# select to_tsvector('fr','Hôtel de la Mer') @@ to_tsquery('fr','Hotels');
+ ?column?
+----------
+ t
+(1 row)
+
+mydb=# select ts_headline('fr','Hôtel de la Mer',to_tsquery('fr','Hotels'));
+ ts_headline
+------------------------
+ &lt;b&gt;Hôtel&lt;/b&gt; de la Mer
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.11.7.57.8"><div class="titlepage"><div><div><h3 class="title">F.48.3. Functions</h3></div></div></div><p>
+ The <code class="function">unaccent()</code> function removes accents (diacritic signs) from
+ a given string. Basically, it's a wrapper around
+ <code class="filename">unaccent</code>-type dictionaries, but it can be used outside normal
+ text search contexts.
+ </p><a id="id-1.11.7.57.8.3" class="indexterm"></a><pre class="synopsis">
+unaccent([<span class="optional"><em class="replaceable"><code>dictionary</code></em> <code class="type">regdictionary</code>, </span>] <em class="replaceable"><code>string</code></em> <code class="type">text</code>) returns <code class="type">text</code>
+</pre><p>
+ If the <em class="replaceable"><code>dictionary</code></em> argument is
+ omitted, the text search dictionary named <code class="literal">unaccent</code> and
+ appearing in the same schema as the <code class="function">unaccent()</code>
+ function itself is used.
+ </p><p>
+ For example:
+</p><pre class="programlisting">
+SELECT unaccent('unaccent', 'Hôtel');
+SELECT unaccent('Hôtel');
+</pre><p>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tsm-system-time.html" title="F.47. tsm_system_time">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="uuid-ossp.html" title="F.49. uuid-ossp">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.47. tsm_system_time </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.49. uuid-ossp</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/unsupported-features-sql-standard.html b/doc/src/sgml/html/unsupported-features-sql-standard.html
new file mode 100644
index 0000000..6846504
--- /dev/null
+++ b/doc/src/sgml/html/unsupported-features-sql-standard.html
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>D.2. Unsupported Features</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="features-sql-standard.html" title="D.1. Supported Features" /><link rel="next" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">D.2. Unsupported Features</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="features-sql-standard.html" title="D.1. Supported Features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="features.html" title="Appendix D. SQL Conformance">Up</a></td><th width="60%" align="center">Appendix D. SQL Conformance</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML">Next</a></td></tr></table><hr /></div><div class="sect1" id="UNSUPPORTED-FEATURES-SQL-STANDARD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">D.2. Unsupported Features</h2></div></div></div><p>
+ The following features defined in <acronym class="acronym">SQL:2016</acronym> are not
+ implemented in this release of
+ <span class="productname">PostgreSQL</span>. In a few cases, equivalent
+ functionality is available.
+
+ </p><div class="informaltable"><table class="informaltable" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /><col class="col4" /></colgroup><thead><tr><th>Identifier</th><th>Core?</th><th>Description</th><th>Comment</th></tr></thead><tbody><tr><td>B011</td><td> </td><td>Embedded Ada</td><td> </td></tr><tr><td>B013</td><td> </td><td>Embedded COBOL</td><td> </td></tr><tr><td>B014</td><td> </td><td>Embedded Fortran</td><td> </td></tr><tr><td>B015</td><td> </td><td>Embedded MUMPS</td><td> </td></tr><tr><td>B016</td><td> </td><td>Embedded Pascal</td><td> </td></tr><tr><td>B017</td><td> </td><td>Embedded PL/I</td><td> </td></tr><tr><td>B031</td><td> </td><td>Basic dynamic SQL</td><td> </td></tr><tr><td>B032</td><td> </td><td>Extended dynamic SQL</td><td> </td></tr><tr><td>B032-01</td><td> </td><td>&lt;describe input statement&gt;</td><td> </td></tr><tr><td>B033</td><td> </td><td>Untyped SQL-invoked function arguments</td><td> </td></tr><tr><td>B034</td><td> </td><td>Dynamic specification of cursor attributes</td><td> </td></tr><tr><td>B035</td><td> </td><td>Non-extended descriptor names</td><td> </td></tr><tr><td>B041</td><td> </td><td>Extensions to embedded SQL exception declarations</td><td> </td></tr><tr><td>B051</td><td> </td><td>Enhanced execution rights</td><td> </td></tr><tr><td>B111</td><td> </td><td>Module language Ada</td><td> </td></tr><tr><td>B112</td><td> </td><td>Module language C</td><td> </td></tr><tr><td>B113</td><td> </td><td>Module language COBOL</td><td> </td></tr><tr><td>B114</td><td> </td><td>Module language Fortran</td><td> </td></tr><tr><td>B115</td><td> </td><td>Module language MUMPS</td><td> </td></tr><tr><td>B116</td><td> </td><td>Module language Pascal</td><td> </td></tr><tr><td>B117</td><td> </td><td>Module language PL/I</td><td> </td></tr><tr><td>B121</td><td> </td><td>Routine language Ada</td><td> </td></tr><tr><td>B122</td><td> </td><td>Routine language C</td><td> </td></tr><tr><td>B123</td><td> </td><td>Routine language COBOL</td><td> </td></tr><tr><td>B124</td><td> </td><td>Routine language Fortran</td><td> </td></tr><tr><td>B125</td><td> </td><td>Routine language MUMPS</td><td> </td></tr><tr><td>B126</td><td> </td><td>Routine language Pascal</td><td> </td></tr><tr><td>B127</td><td> </td><td>Routine language PL/I</td><td> </td></tr><tr><td>B200</td><td> </td><td>Polymorphic table functions</td><td> </td></tr><tr><td>B201</td><td> </td><td>More than one PTF generic table parameter</td><td> </td></tr><tr><td>B202</td><td> </td><td>PTF Copartitioning</td><td> </td></tr><tr><td>B203</td><td> </td><td>More than one copartition specification</td><td> </td></tr><tr><td>B204</td><td> </td><td>PRUNE WHEN EMPTY</td><td> </td></tr><tr><td>B205</td><td> </td><td>Pass-through columns</td><td> </td></tr><tr><td>B206</td><td> </td><td>PTF descriptor parameters</td><td> </td></tr><tr><td>B207</td><td> </td><td>Cross products of partitionings</td><td> </td></tr><tr><td>B208</td><td> </td><td>PTF component procedure interface</td><td> </td></tr><tr><td>B209</td><td> </td><td>PTF extended names</td><td> </td></tr><tr><td>B211</td><td> </td><td>Module language Ada: VARCHAR and NUMERIC support</td><td> </td></tr><tr><td>B221</td><td> </td><td>Routine language Ada: VARCHAR and NUMERIC support</td><td> </td></tr><tr><td>F054</td><td> </td><td>TIMESTAMP in DATE type precedence list</td><td> </td></tr><tr><td>F121</td><td> </td><td>Basic diagnostics management</td><td> </td></tr><tr><td>F121-01</td><td> </td><td>GET DIAGNOSTICS statement</td><td> </td></tr><tr><td>F121-02</td><td> </td><td>SET TRANSACTION statement: DIAGNOSTICS SIZE clause</td><td> </td></tr><tr><td>F122</td><td> </td><td>Enhanced diagnostics management</td><td> </td></tr><tr><td>F123</td><td> </td><td>All diagnostics</td><td> </td></tr><tr><td>F263</td><td> </td><td>Comma-separated predicates in simple CASE expression</td><td> </td></tr><tr><td>F291</td><td> </td><td>UNIQUE predicate</td><td> </td></tr><tr><td>F301</td><td> </td><td>CORRESPONDING in query expressions</td><td> </td></tr><tr><td>F403</td><td> </td><td>Partitioned joined tables</td><td> </td></tr><tr><td>F451</td><td> </td><td>Character set definition</td><td> </td></tr><tr><td>F461</td><td> </td><td>Named character sets</td><td> </td></tr><tr><td>F492</td><td> </td><td>Optional table constraint enforcement</td><td> </td></tr><tr><td>F521</td><td> </td><td>Assertions</td><td> </td></tr><tr><td>F671</td><td> </td><td>Subqueries in CHECK</td><td>intentionally omitted</td></tr><tr><td>F673</td><td> </td><td>Reads SQL-data routine invocations in CHECK constraints</td><td> </td></tr><tr><td>F693</td><td> </td><td>SQL-session and client module collations</td><td> </td></tr><tr><td>F695</td><td> </td><td>Translation support</td><td> </td></tr><tr><td>F696</td><td> </td><td>Additional translation documentation</td><td> </td></tr><tr><td>F721</td><td> </td><td>Deferrable constraints</td><td>foreign and unique keys only</td></tr><tr><td>F741</td><td> </td><td>Referential MATCH types</td><td>no partial match yet</td></tr><tr><td>F812</td><td>Core</td><td>Basic flagging</td><td> </td></tr><tr><td>F813</td><td> </td><td>Extended flagging</td><td> </td></tr><tr><td>F821</td><td> </td><td>Local table references</td><td> </td></tr><tr><td>F831</td><td> </td><td>Full cursor update</td><td> </td></tr><tr><td>F831-01</td><td> </td><td>Updatable scrollable cursors</td><td> </td></tr><tr><td>F831-02</td><td> </td><td>Updatable ordered cursors</td><td> </td></tr><tr><td>F841</td><td> </td><td>LIKE_REGEX predicate</td><td>consider regexp_like()</td></tr><tr><td>F842</td><td> </td><td>OCCURRENCES_REGEX function</td><td>consider regexp_matches()</td></tr><tr><td>F843</td><td> </td><td>POSITION_REGEX function</td><td>consider regexp_instr()</td></tr><tr><td>F844</td><td> </td><td>SUBSTRING_REGEX function</td><td>consider regexp_substr()</td></tr><tr><td>F845</td><td> </td><td>TRANSLATE_REGEX function</td><td>consider regexp_replace()</td></tr><tr><td>F846</td><td> </td><td>Octet support in regular expression operators</td><td> </td></tr><tr><td>F847</td><td> </td><td>Nonconstant regular expressions</td><td> </td></tr><tr><td>F866</td><td> </td><td>FETCH FIRST clause: PERCENT option</td><td> </td></tr><tr><td>R010</td><td> </td><td>Row pattern recognition: FROM clause</td><td> </td></tr><tr><td>R020</td><td> </td><td>Row pattern recognition: WINDOW clause</td><td> </td></tr><tr><td>R030</td><td> </td><td>Row pattern recognition: full aggregate support</td><td> </td></tr><tr><td>S011</td><td>Core</td><td>Distinct data types</td><td> </td></tr><tr><td>S011-01</td><td>Core</td><td>USER_DEFINED_TYPES view</td><td> </td></tr><tr><td>S023</td><td> </td><td>Basic structured types</td><td> </td></tr><tr><td>S024</td><td> </td><td>Enhanced structured types</td><td> </td></tr><tr><td>S025</td><td> </td><td>Final structured types</td><td> </td></tr><tr><td>S026</td><td> </td><td>Self-referencing structured types</td><td> </td></tr><tr><td>S027</td><td> </td><td>Create method by specific method name</td><td> </td></tr><tr><td>S028</td><td> </td><td>Permutable UDT options list</td><td> </td></tr><tr><td>S041</td><td> </td><td>Basic reference types</td><td> </td></tr><tr><td>S043</td><td> </td><td>Enhanced reference types</td><td> </td></tr><tr><td>S051</td><td> </td><td>Create table of type</td><td>partially supported</td></tr><tr><td>S081</td><td> </td><td>Subtables</td><td> </td></tr><tr><td>S091</td><td> </td><td>Basic array support</td><td>partially supported</td></tr><tr><td>S091-02</td><td> </td><td>Arrays of distinct types</td><td> </td></tr><tr><td>S094</td><td> </td><td>Arrays of reference types</td><td> </td></tr><tr><td>S097</td><td> </td><td>Array element assignment</td><td> </td></tr><tr><td>S151</td><td> </td><td>Type predicate</td><td>see pg_typeof()</td></tr><tr><td>S161</td><td> </td><td>Subtype treatment</td><td> </td></tr><tr><td>S162</td><td> </td><td>Subtype treatment for references</td><td> </td></tr><tr><td>S202</td><td> </td><td>SQL-invoked routines on multisets</td><td> </td></tr><tr><td>S231</td><td> </td><td>Structured type locators</td><td> </td></tr><tr><td>S232</td><td> </td><td>Array locators</td><td> </td></tr><tr><td>S233</td><td> </td><td>Multiset locators</td><td> </td></tr><tr><td>S241</td><td> </td><td>Transform functions</td><td> </td></tr><tr><td>S242</td><td> </td><td>Alter transform statement</td><td> </td></tr><tr><td>S251</td><td> </td><td>User-defined orderings</td><td> </td></tr><tr><td>S261</td><td> </td><td>Specific type method</td><td> </td></tr><tr><td>S271</td><td> </td><td>Basic multiset support</td><td> </td></tr><tr><td>S272</td><td> </td><td>Multisets of user-defined types</td><td> </td></tr><tr><td>S274</td><td> </td><td>Multisets of reference types</td><td> </td></tr><tr><td>S275</td><td> </td><td>Advanced multiset support</td><td> </td></tr><tr><td>S281</td><td> </td><td>Nested collection types</td><td> </td></tr><tr><td>S291</td><td> </td><td>Unique constraint on entire row</td><td> </td></tr><tr><td>S401</td><td> </td><td>Distinct types based on array types</td><td> </td></tr><tr><td>S402</td><td> </td><td>Distinct types based on distinct types</td><td> </td></tr><tr><td>S403</td><td> </td><td>ARRAY_MAX_CARDINALITY</td><td> </td></tr><tr><td>T011</td><td> </td><td>Timestamp in Information Schema</td><td> </td></tr><tr><td>T021</td><td> </td><td>BINARY and VARBINARY data types</td><td> </td></tr><tr><td>T022</td><td> </td><td>Advanced support for BINARY and VARBINARY data types</td><td> </td></tr><tr><td>T023</td><td> </td><td>Compound binary literal</td><td> </td></tr><tr><td>T024</td><td> </td><td>Spaces in binary literals</td><td> </td></tr><tr><td>T041</td><td> </td><td>Basic LOB data type support</td><td> </td></tr><tr><td>T041-01</td><td> </td><td>BLOB data type</td><td> </td></tr><tr><td>T041-02</td><td> </td><td>CLOB data type</td><td> </td></tr><tr><td>T041-03</td><td> </td><td>POSITION, LENGTH, LOWER, TRIM, UPPER, and SUBSTRING functions for LOB data types</td><td> </td></tr><tr><td>T041-04</td><td> </td><td>Concatenation of LOB data types</td><td> </td></tr><tr><td>T041-05</td><td> </td><td>LOB locator: non-holdable</td><td> </td></tr><tr><td>T042</td><td> </td><td>Extended LOB data type support</td><td> </td></tr><tr><td>T043</td><td> </td><td>Multiplier T</td><td> </td></tr><tr><td>T044</td><td> </td><td>Multiplier P</td><td> </td></tr><tr><td>T051</td><td> </td><td>Row types</td><td> </td></tr><tr><td>T053</td><td> </td><td>Explicit aliases for all-fields reference</td><td> </td></tr><tr><td>T061</td><td> </td><td>UCS support</td><td> </td></tr><tr><td>T076</td><td> </td><td>DECFLOAT data type</td><td> </td></tr><tr><td>T101</td><td> </td><td>Enhanced nullability determination</td><td> </td></tr><tr><td>T111</td><td> </td><td>Updatable joins, unions, and columns</td><td> </td></tr><tr><td>T175</td><td> </td><td>Generated columns</td><td>mostly supported</td></tr><tr><td>T176</td><td> </td><td>Sequence generator support</td><td>supported except for NEXT VALUE FOR</td></tr><tr><td>T180</td><td> </td><td>System-versioned tables</td><td> </td></tr><tr><td>T181</td><td> </td><td>Application-time period tables</td><td> </td></tr><tr><td>T211</td><td> </td><td>Basic trigger capability</td><td> </td></tr><tr><td>T211-06</td><td> </td><td>Support for run-time rules for the interaction of triggers and constraints</td><td> </td></tr><tr><td>T211-08</td><td> </td><td>Multiple triggers for the same event are executed in the order in which they were created in the catalog</td><td>intentionally omitted</td></tr><tr><td>T231</td><td> </td><td>Sensitive cursors</td><td> </td></tr><tr><td>T251</td><td> </td><td>SET TRANSACTION statement: LOCAL option</td><td> </td></tr><tr><td>T272</td><td> </td><td>Enhanced savepoint management</td><td> </td></tr><tr><td>T301</td><td> </td><td>Functional dependencies</td><td>partially supported</td></tr><tr><td>T321</td><td>Core</td><td>Basic SQL-invoked routines</td><td>partially supported</td></tr><tr><td>T322</td><td> </td><td>Declared data type attributes</td><td> </td></tr><tr><td>T324</td><td> </td><td>Explicit security for SQL routines</td><td> </td></tr><tr><td>T326</td><td> </td><td>Table functions</td><td> </td></tr><tr><td>T471</td><td> </td><td>Result sets return value</td><td> </td></tr><tr><td>T472</td><td> </td><td>DESCRIBE CURSOR</td><td> </td></tr><tr><td>T495</td><td> </td><td>Combined data change and retrieval</td><td>different syntax</td></tr><tr><td>T502</td><td> </td><td>Period predicates</td><td> </td></tr><tr><td>T511</td><td> </td><td>Transaction counts</td><td> </td></tr><tr><td>T522</td><td> </td><td>Default values for IN parameters of SQL-invoked procedures</td><td>supported except DEFAULT key word in invocation</td></tr><tr><td>T561</td><td> </td><td>Holdable locators</td><td> </td></tr><tr><td>T571</td><td> </td><td>Array-returning external SQL-invoked functions</td><td> </td></tr><tr><td>T572</td><td> </td><td>Multiset-returning external SQL-invoked functions</td><td> </td></tr><tr><td>T601</td><td> </td><td>Local cursor references</td><td> </td></tr><tr><td>T616</td><td> </td><td>Null treatment option for LEAD and LAG functions</td><td> </td></tr><tr><td>T618</td><td> </td><td>NTH_VALUE function</td><td>function exists, but some options missing</td></tr><tr><td>T619</td><td> </td><td>Nested window functions</td><td> </td></tr><tr><td>T625</td><td> </td><td>LISTAGG</td><td> </td></tr><tr><td>T641</td><td> </td><td>Multiple column assignment</td><td>only some syntax variants supported</td></tr><tr><td>T652</td><td> </td><td>SQL-dynamic statements in SQL routines</td><td> </td></tr><tr><td>T654</td><td> </td><td>SQL-dynamic statements in external routines</td><td> </td></tr><tr><td>T811</td><td> </td><td>Basic SQL/JSON constructor functions</td><td> </td></tr><tr><td>T812</td><td> </td><td>SQL/JSON: JSON_OBJECTAGG</td><td> </td></tr><tr><td>T813</td><td> </td><td>SQL/JSON: JSON_ARRAYAGG with ORDER BY</td><td> </td></tr><tr><td>T814</td><td> </td><td>Colon in JSON_OBJECT or JSON_OBJECTAGG</td><td> </td></tr><tr><td>T821</td><td> </td><td>Basic SQL/JSON query operators</td><td> </td></tr><tr><td>T822</td><td> </td><td>SQL/JSON: IS JSON WITH UNIQUE KEYS predicate</td><td> </td></tr><tr><td>T823</td><td> </td><td>SQL/JSON: PASSING clause</td><td> </td></tr><tr><td>T824</td><td> </td><td>JSON_TABLE: specific PLAN clause</td><td> </td></tr><tr><td>T825</td><td> </td><td>SQL/JSON: ON EMPTY and ON ERROR clauses</td><td> </td></tr><tr><td>T826</td><td> </td><td>General value expression in ON ERROR or ON EMPTY clauses</td><td> </td></tr><tr><td>T827</td><td> </td><td>JSON_TABLE: sibling NESTED COLUMNS clauses</td><td> </td></tr><tr><td>T828</td><td> </td><td>JSON_QUERY</td><td> </td></tr><tr><td>T829</td><td> </td><td>JSON_QUERY: array wrapper options</td><td> </td></tr><tr><td>T830</td><td> </td><td>Enforcing unique keys in SQL/JSON constructor functions</td><td> </td></tr><tr><td>T838</td><td> </td><td>JSON_TABLE: PLAN DEFAULT clause</td><td> </td></tr><tr><td>T839</td><td> </td><td>Formatted cast of datetimes to/from character strings</td><td> </td></tr><tr><td>M001</td><td> </td><td>Datalinks</td><td> </td></tr><tr><td>M002</td><td> </td><td>Datalinks via SQL/CLI</td><td> </td></tr><tr><td>M003</td><td> </td><td>Datalinks via Embedded SQL</td><td> </td></tr><tr><td>M004</td><td> </td><td>Foreign data support</td><td>partially supported</td></tr><tr><td>M005</td><td> </td><td>Foreign schema support</td><td> </td></tr><tr><td>M006</td><td> </td><td>GetSQLString routine</td><td> </td></tr><tr><td>M007</td><td> </td><td>TransmitRequest</td><td> </td></tr><tr><td>M009</td><td> </td><td>GetOpts and GetStatistics routines</td><td> </td></tr><tr><td>M010</td><td> </td><td>Foreign data wrapper support</td><td>different API</td></tr><tr><td>M011</td><td> </td><td>Datalinks via Ada</td><td> </td></tr><tr><td>M012</td><td> </td><td>Datalinks via C</td><td> </td></tr><tr><td>M013</td><td> </td><td>Datalinks via COBOL</td><td> </td></tr><tr><td>M014</td><td> </td><td>Datalinks via Fortran</td><td> </td></tr><tr><td>M015</td><td> </td><td>Datalinks via M</td><td> </td></tr><tr><td>M016</td><td> </td><td>Datalinks via Pascal</td><td> </td></tr><tr><td>M017</td><td> </td><td>Datalinks via PL/I</td><td> </td></tr><tr><td>M018</td><td> </td><td>Foreign data wrapper interface routines in Ada</td><td> </td></tr><tr><td>M019</td><td> </td><td>Foreign data wrapper interface routines in C</td><td>different API</td></tr><tr><td>M020</td><td> </td><td>Foreign data wrapper interface routines in COBOL</td><td> </td></tr><tr><td>M021</td><td> </td><td>Foreign data wrapper interface routines in Fortran</td><td> </td></tr><tr><td>M022</td><td> </td><td>Foreign data wrapper interface routines in MUMPS</td><td> </td></tr><tr><td>M023</td><td> </td><td>Foreign data wrapper interface routines in Pascal</td><td> </td></tr><tr><td>M024</td><td> </td><td>Foreign data wrapper interface routines in PL/I</td><td> </td></tr><tr><td>M030</td><td> </td><td>SQL-server foreign data support</td><td> </td></tr><tr><td>M031</td><td> </td><td>Foreign data wrapper general routines</td><td> </td></tr><tr><td>X012</td><td> </td><td>Multisets of XML type</td><td> </td></tr><tr><td>X013</td><td> </td><td>Distinct types of XML type</td><td> </td></tr><tr><td>X015</td><td> </td><td>Fields of XML type</td><td> </td></tr><tr><td>X025</td><td> </td><td>XMLCast</td><td> </td></tr><tr><td>X030</td><td> </td><td>XMLDocument</td><td> </td></tr><tr><td>X038</td><td> </td><td>XMLText</td><td> </td></tr><tr><td>X065</td><td> </td><td>XMLParse: BLOB input and CONTENT option</td><td> </td></tr><tr><td>X066</td><td> </td><td>XMLParse: BLOB input and DOCUMENT option</td><td> </td></tr><tr><td>X068</td><td> </td><td>XMLSerialize: BOM</td><td> </td></tr><tr><td>X069</td><td> </td><td>XMLSerialize: INDENT</td><td> </td></tr><tr><td>X073</td><td> </td><td>XMLSerialize: BLOB serialization and CONTENT option</td><td> </td></tr><tr><td>X074</td><td> </td><td>XMLSerialize: BLOB serialization and DOCUMENT option</td><td> </td></tr><tr><td>X075</td><td> </td><td>XMLSerialize: BLOB serialization</td><td> </td></tr><tr><td>X076</td><td> </td><td>XMLSerialize: VERSION</td><td> </td></tr><tr><td>X077</td><td> </td><td>XMLSerialize: explicit ENCODING option</td><td> </td></tr><tr><td>X078</td><td> </td><td>XMLSerialize: explicit XML declaration</td><td> </td></tr><tr><td>X080</td><td> </td><td>Namespaces in XML publishing</td><td> </td></tr><tr><td>X081</td><td> </td><td>Query-level XML namespace declarations</td><td> </td></tr><tr><td>X082</td><td> </td><td>XML namespace declarations in DML</td><td> </td></tr><tr><td>X083</td><td> </td><td>XML namespace declarations in DDL</td><td> </td></tr><tr><td>X084</td><td> </td><td>XML namespace declarations in compound statements</td><td> </td></tr><tr><td>X085</td><td> </td><td>Predefined namespace prefixes</td><td> </td></tr><tr><td>X086</td><td> </td><td>XML namespace declarations in XMLTable</td><td> </td></tr><tr><td>X091</td><td> </td><td>XML content predicate</td><td> </td></tr><tr><td>X096</td><td> </td><td>XMLExists</td><td>XPath 1.0 only</td></tr><tr><td>X100</td><td> </td><td>Host language support for XML: CONTENT option</td><td> </td></tr><tr><td>X101</td><td> </td><td>Host language support for XML: DOCUMENT option</td><td> </td></tr><tr><td>X110</td><td> </td><td>Host language support for XML: VARCHAR mapping</td><td> </td></tr><tr><td>X111</td><td> </td><td>Host language support for XML: CLOB mapping</td><td> </td></tr><tr><td>X112</td><td> </td><td>Host language support for XML: BLOB mapping</td><td> </td></tr><tr><td>X113</td><td> </td><td>Host language support for XML: STRIP WHITESPACE option</td><td> </td></tr><tr><td>X114</td><td> </td><td>Host language support for XML: PRESERVE WHITESPACE option</td><td> </td></tr><tr><td>X131</td><td> </td><td>Query-level XMLBINARY clause</td><td> </td></tr><tr><td>X132</td><td> </td><td>XMLBINARY clause in DML</td><td> </td></tr><tr><td>X133</td><td> </td><td>XMLBINARY clause in DDL</td><td> </td></tr><tr><td>X134</td><td> </td><td>XMLBINARY clause in compound statements</td><td> </td></tr><tr><td>X135</td><td> </td><td>XMLBINARY clause in subqueries</td><td> </td></tr><tr><td>X141</td><td> </td><td>IS VALID predicate: data-driven case</td><td> </td></tr><tr><td>X142</td><td> </td><td>IS VALID predicate: ACCORDING TO clause</td><td> </td></tr><tr><td>X143</td><td> </td><td>IS VALID predicate: ELEMENT clause</td><td> </td></tr><tr><td>X144</td><td> </td><td>IS VALID predicate: schema location</td><td> </td></tr><tr><td>X145</td><td> </td><td>IS VALID predicate outside check constraints</td><td> </td></tr><tr><td>X151</td><td> </td><td>IS VALID predicate with DOCUMENT option</td><td> </td></tr><tr><td>X152</td><td> </td><td>IS VALID predicate with CONTENT option</td><td> </td></tr><tr><td>X153</td><td> </td><td>IS VALID predicate with SEQUENCE option</td><td> </td></tr><tr><td>X155</td><td> </td><td>IS VALID predicate: NAMESPACE without ELEMENT clause</td><td> </td></tr><tr><td>X157</td><td> </td><td>IS VALID predicate: NO NAMESPACE with ELEMENT clause</td><td> </td></tr><tr><td>X160</td><td> </td><td>Basic Information Schema for registered XML Schemas</td><td> </td></tr><tr><td>X161</td><td> </td><td>Advanced Information Schema for registered XML Schemas</td><td> </td></tr><tr><td>X170</td><td> </td><td>XML null handling options</td><td> </td></tr><tr><td>X171</td><td> </td><td>NIL ON NO CONTENT option</td><td> </td></tr><tr><td>X181</td><td> </td><td>XML(DOCUMENT(UNTYPED)) type</td><td> </td></tr><tr><td>X182</td><td> </td><td>XML(DOCUMENT(ANY)) type</td><td> </td></tr><tr><td>X190</td><td> </td><td>XML(SEQUENCE) type</td><td> </td></tr><tr><td>X191</td><td> </td><td>XML(DOCUMENT(XMLSCHEMA)) type</td><td> </td></tr><tr><td>X192</td><td> </td><td>XML(CONTENT(XMLSCHEMA)) type</td><td> </td></tr><tr><td>X200</td><td> </td><td>XMLQuery</td><td> </td></tr><tr><td>X201</td><td> </td><td>XMLQuery: RETURNING CONTENT</td><td> </td></tr><tr><td>X202</td><td> </td><td>XMLQuery: RETURNING SEQUENCE</td><td> </td></tr><tr><td>X203</td><td> </td><td>XMLQuery: passing a context item</td><td> </td></tr><tr><td>X204</td><td> </td><td>XMLQuery: initializing an XQuery variable</td><td> </td></tr><tr><td>X205</td><td> </td><td>XMLQuery: EMPTY ON EMPTY option</td><td> </td></tr><tr><td>X206</td><td> </td><td>XMLQuery: NULL ON EMPTY option</td><td> </td></tr><tr><td>X211</td><td> </td><td>XML 1.1 support</td><td> </td></tr><tr><td>X222</td><td> </td><td>XML passing mechanism BY REF</td><td>parser accepts BY REF but ignores it; passing is always BY VALUE</td></tr><tr><td>X231</td><td> </td><td>XML(CONTENT(UNTYPED)) type</td><td> </td></tr><tr><td>X232</td><td> </td><td>XML(CONTENT(ANY)) type</td><td> </td></tr><tr><td>X241</td><td> </td><td>RETURNING CONTENT in XML publishing</td><td> </td></tr><tr><td>X242</td><td> </td><td>RETURNING SEQUENCE in XML publishing</td><td> </td></tr><tr><td>X251</td><td> </td><td>Persistent XML values of XML(DOCUMENT(UNTYPED)) type</td><td> </td></tr><tr><td>X252</td><td> </td><td>Persistent XML values of XML(DOCUMENT(ANY)) type</td><td> </td></tr><tr><td>X253</td><td> </td><td>Persistent XML values of XML(CONTENT(UNTYPED)) type</td><td> </td></tr><tr><td>X254</td><td> </td><td>Persistent XML values of XML(CONTENT(ANY)) type</td><td> </td></tr><tr><td>X255</td><td> </td><td>Persistent XML values of XML(SEQUENCE) type</td><td> </td></tr><tr><td>X256</td><td> </td><td>Persistent XML values of XML(DOCUMENT(XMLSCHEMA)) type</td><td> </td></tr><tr><td>X257</td><td> </td><td>Persistent XML values of XML(CONTENT(XMLSCHEMA)) type</td><td> </td></tr><tr><td>X260</td><td> </td><td>XML type: ELEMENT clause</td><td> </td></tr><tr><td>X261</td><td> </td><td>XML type: NAMESPACE without ELEMENT clause</td><td> </td></tr><tr><td>X263</td><td> </td><td>XML type: NO NAMESPACE with ELEMENT clause</td><td> </td></tr><tr><td>X264</td><td> </td><td>XML type: schema location</td><td> </td></tr><tr><td>X271</td><td> </td><td>XMLValidate: data-driven case</td><td> </td></tr><tr><td>X272</td><td> </td><td>XMLValidate: ACCORDING TO clause</td><td> </td></tr><tr><td>X273</td><td> </td><td>XMLValidate: ELEMENT clause</td><td> </td></tr><tr><td>X274</td><td> </td><td>XMLValidate: schema location</td><td> </td></tr><tr><td>X281</td><td> </td><td>XMLValidate with DOCUMENT option</td><td> </td></tr><tr><td>X282</td><td> </td><td>XMLValidate with CONTENT option</td><td> </td></tr><tr><td>X283</td><td> </td><td>XMLValidate with SEQUENCE option</td><td> </td></tr><tr><td>X284</td><td> </td><td>XMLValidate: NAMESPACE without ELEMENT clause</td><td> </td></tr><tr><td>X286</td><td> </td><td>XMLValidate: NO NAMESPACE with ELEMENT clause</td><td> </td></tr><tr><td>X300</td><td> </td><td>XMLTable</td><td>XPath 1.0 only</td></tr><tr><td>X305</td><td> </td><td>XMLTable: initializing an XQuery variable</td><td> </td></tr></tbody></table></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="features-sql-standard.html" title="D.1. Supported Features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="features.html" title="Appendix D. SQL Conformance">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xml-limits-conformance.html" title="D.3. XML Limits and Conformance to SQL/XML">Next</a></td></tr><tr><td width="40%" align="left" valign="top">D.1. Supported Features </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> D.3. XML Limits and Conformance to SQL/XML</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/upgrading.html b/doc/src/sgml/html/upgrading.html
new file mode 100644
index 0000000..01e29e7
--- /dev/null
+++ b/doc/src/sgml/html/upgrading.html
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>19.6. Upgrading a PostgreSQL Cluster</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="server-shutdown.html" title="19.5. Shutting Down the Server" /><link rel="next" href="preventing-server-spoofing.html" title="19.7. Preventing Server Spoofing" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">19.6. Upgrading a <span class="productname">PostgreSQL</span> Cluster</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="server-shutdown.html" title="19.5. Shutting Down the Server">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><th width="60%" align="center">Chapter 19. Server Setup and Operation</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="preventing-server-spoofing.html" title="19.7. Preventing Server Spoofing">Next</a></td></tr></table><hr /></div><div class="sect1" id="UPGRADING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">19.6. Upgrading a <span class="productname">PostgreSQL</span> Cluster</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="upgrading.html#UPGRADING-VIA-PGDUMPALL">19.6.1. Upgrading Data via <span class="application">pg_dumpall</span></a></span></dt><dt><span class="sect2"><a href="upgrading.html#UPGRADING-VIA-PG-UPGRADE">19.6.2. Upgrading Data via <span class="application">pg_upgrade</span></a></span></dt><dt><span class="sect2"><a href="upgrading.html#UPGRADING-VIA-REPLICATION">19.6.3. Upgrading Data via Replication</a></span></dt></dl></div><a id="id-1.6.6.9.2" class="indexterm"></a><a id="id-1.6.6.9.3" class="indexterm"></a><p>
+ This section discusses how to upgrade your database data from one
+ <span class="productname">PostgreSQL</span> release to a newer one.
+ </p><p>
+ Current <span class="productname">PostgreSQL</span> version numbers consist of a
+ major and a minor version number. For example, in the version number 10.1,
+ the 10 is the major version number and the 1 is the minor version number,
+ meaning this would be the first minor release of the major release 10. For
+ releases before <span class="productname">PostgreSQL</span> version 10.0, version
+ numbers consist of three numbers, for example, 9.5.3. In those cases, the
+ major version consists of the first two digit groups of the version number,
+ e.g., 9.5, and the minor version is the third number, e.g., 3, meaning this
+ would be the third minor release of the major release 9.5.
+ </p><p>
+ Minor releases never change the internal storage format and are always
+ compatible with earlier and later minor releases of the same major version
+ number. For example, version 10.1 is compatible with version 10.0 and
+ version 10.6. Similarly, for example, 9.5.3 is compatible with 9.5.0,
+ 9.5.1, and 9.5.6. To update between compatible versions, you simply
+ replace the executables while the server is down and restart the server.
+ The data directory remains unchanged — minor upgrades are that
+ simple.
+ </p><p>
+ For <span class="emphasis"><em>major</em></span> releases of <span class="productname">PostgreSQL</span>, the
+ internal data storage format is subject to change, thus complicating
+ upgrades. The traditional method for moving data to a new major version
+ is to dump and restore the database, though this can be slow. A
+ faster method is <a class="xref" href="pgupgrade.html" title="pg_upgrade"><span class="refentrytitle"><span class="application">pg_upgrade</span></span></a>. Replication methods are
+ also available, as discussed below.
+ (If you are using a pre-packaged version
+ of <span class="productname">PostgreSQL</span>, it may provide scripts to
+ assist with major version upgrades. Consult the package-level
+ documentation for details.)
+ </p><p>
+ New major versions also typically introduce some user-visible
+ incompatibilities, so application programming changes might be required.
+ All user-visible changes are listed in the release notes (<a class="xref" href="release.html" title="Appendix E. Release Notes">Appendix E</a>); pay particular attention to the section
+ labeled "Migration". Though you can upgrade from one major version
+ to another without upgrading to intervening versions, you should read
+ the major release notes of all intervening versions.
+ </p><p>
+ Cautious users will want to test their client applications on the new
+ version before switching over fully; therefore, it's often a good idea to
+ set up concurrent installations of old and new versions. When
+ testing a <span class="productname">PostgreSQL</span> major upgrade, consider the
+ following categories of possible changes:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">Administration</span></dt><dd><p>
+ The capabilities available for administrators to monitor and control
+ the server often change and improve in each major release.
+ </p></dd><dt><span class="term">SQL</span></dt><dd><p>
+ Typically this includes new SQL command capabilities and not changes
+ in behavior, unless specifically mentioned in the release notes.
+ </p></dd><dt><span class="term">Library API</span></dt><dd><p>
+ Typically libraries like <span class="application">libpq</span> only add new
+ functionality, again unless mentioned in the release notes.
+ </p></dd><dt><span class="term">System Catalogs</span></dt><dd><p>
+ System catalog changes usually only affect database management tools.
+ </p></dd><dt><span class="term">Server C-language API</span></dt><dd><p>
+ This involves changes in the backend function API, which is written
+ in the C programming language. Such changes affect code that
+ references backend functions deep inside the server.
+ </p></dd></dl></div><div class="sect2" id="UPGRADING-VIA-PGDUMPALL"><div class="titlepage"><div><div><h3 class="title">19.6.1. Upgrading Data via <span class="application">pg_dumpall</span></h3></div></div></div><p>
+ One upgrade method is to dump data from one major version of
+ <span class="productname">PostgreSQL</span> and restore it in another — to do
+ this, you must use a <span class="emphasis"><em>logical</em></span> backup tool like
+ <span class="application">pg_dumpall</span>; file system
+ level backup methods will not work. (There are checks in place that prevent
+ you from using a data directory with an incompatible version of
+ <span class="productname">PostgreSQL</span>, so no great harm can be done by
+ trying to start the wrong server version on a data directory.)
+ </p><p>
+ It is recommended that you use the <span class="application">pg_dump</span> and
+ <span class="application">pg_dumpall</span> programs from the <span class="emphasis"><em>newer</em></span>
+ version of
+ <span class="productname">PostgreSQL</span>, to take advantage of enhancements
+ that might have been made in these programs. Current releases of the
+ dump programs can read data from any server version back to 9.2.
+ </p><p>
+ These instructions assume that your existing installation is under the
+ <code class="filename">/usr/local/pgsql</code> directory, and that the data area is in
+ <code class="filename">/usr/local/pgsql/data</code>. Substitute your paths
+ appropriately.
+ </p><div class="procedure"><ol class="procedure" type="1"><li class="step"><p>
+ If making a backup, make sure that your database is not being updated.
+ This does not affect the integrity of the backup, but the changed
+ data would of course not be included. If necessary, edit the
+ permissions in the file <code class="filename">/usr/local/pgsql/data/pg_hba.conf</code>
+ (or equivalent) to disallow access from everyone except you.
+ See <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a> for additional information on
+ access control.
+ </p><p>
+ <a id="id-1.6.6.9.11.5.1.2.1" class="indexterm"></a>
+
+ To back up your database installation, type:
+</p><pre class="screen">
+<strong class="userinput"><code>pg_dumpall &gt; <em class="replaceable"><code>outputfile</code></em></code></strong>
+</pre><p>
+ </p><p>
+ To make the backup, you can use the <span class="application">pg_dumpall</span>
+ command from the version you are currently running; see <a class="xref" href="backup-dump.html#BACKUP-DUMP-ALL" title="26.1.2. Using pg_dumpall">Section 26.1.2</a> for more details. For best
+ results, however, try to use the <span class="application">pg_dumpall</span>
+ command from <span class="productname">PostgreSQL</span> 15.4,
+ since this version contains bug fixes and improvements over older
+ versions. While this advice might seem idiosyncratic since you
+ haven't installed the new version yet, it is advisable to follow
+ it if you plan to install the new version in parallel with the
+ old version. In that case you can complete the installation
+ normally and transfer the data later. This will also decrease
+ the downtime.
+ </p></li><li class="step"><p>
+ Shut down the old server:
+</p><pre class="screen">
+<strong class="userinput"><code>pg_ctl stop</code></strong>
+</pre><p>
+ On systems that have <span class="productname">PostgreSQL</span> started at boot time,
+ there is probably a start-up file that will accomplish the same thing. For
+ example, on a <span class="systemitem">Red Hat Linux</span> system one
+ might find that this works:
+</p><pre class="screen">
+<strong class="userinput"><code>/etc/rc.d/init.d/postgresql stop</code></strong>
+</pre><p>
+ See <a class="xref" href="runtime.html" title="Chapter 19. Server Setup and Operation">Chapter 19</a> for details about starting and
+ stopping the server.
+ </p></li><li class="step"><p>
+ If restoring from backup, rename or delete the old installation
+ directory if it is not version-specific. It is a good idea to
+ rename the directory, rather than
+ delete it, in case you have trouble and need to revert to it. Keep
+ in mind the directory might consume significant disk space. To rename
+ the directory, use a command like this:
+</p><pre class="screen">
+<strong class="userinput"><code>mv /usr/local/pgsql /usr/local/pgsql.old</code></strong>
+</pre><p>
+ (Be sure to move the directory as a single unit so relative paths
+ remain unchanged.)
+ </p></li><li class="step"><p>
+ Install the new version of <span class="productname">PostgreSQL</span> as
+ outlined in <a class="xref" href="install-procedure.html" title="17.4. Installation Procedure">Section 17.4</a>.
+ </p></li><li class="step"><p>
+ Create a new database cluster if needed. Remember that you must
+ execute these commands while logged in to the special database user
+ account (which you already have if you are upgrading).
+</p><pre class="programlisting">
+<strong class="userinput"><code>/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data</code></strong>
+</pre><p>
+ </p></li><li class="step"><p>
+ Restore your previous <code class="filename">pg_hba.conf</code> and any
+ <code class="filename">postgresql.conf</code> modifications.
+ </p></li><li class="step"><p>
+ Start the database server, again using the special database user
+ account:
+</p><pre class="programlisting">
+<strong class="userinput"><code>/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data</code></strong>
+</pre><p>
+ </p></li><li class="step"><p>
+ Finally, restore your data from backup with:
+</p><pre class="screen">
+<strong class="userinput"><code>/usr/local/pgsql/bin/psql -d postgres -f <em class="replaceable"><code>outputfile</code></em></code></strong>
+</pre><p>
+ using the <span class="emphasis"><em>new</em></span> <span class="application">psql</span>.
+ </p></li></ol></div><p>
+ The least downtime can be achieved by installing the new server in
+ a different directory and running both the old and the new servers
+ in parallel, on different ports. Then you can use something like:
+
+</p><pre class="programlisting">
+pg_dumpall -p 5432 | psql -d postgres -p 5433
+</pre><p>
+ to transfer your data.
+ </p></div><div class="sect2" id="UPGRADING-VIA-PG-UPGRADE"><div class="titlepage"><div><div><h3 class="title">19.6.2. Upgrading Data via <span class="application">pg_upgrade</span></h3></div></div></div><p>
+ The <a class="xref" href="pgupgrade.html" title="pg_upgrade"><span class="refentrytitle"><span class="application">pg_upgrade</span></span></a> module allows an installation to
+ be migrated in-place from one major <span class="productname">PostgreSQL</span>
+ version to another. Upgrades can be performed in minutes,
+ particularly with <code class="option">--link</code> mode. It requires steps similar to
+ <span class="application">pg_dumpall</span> above, e.g., starting/stopping the server,
+ running <span class="application">initdb</span>. The <span class="application">pg_upgrade</span> <a class="link" href="pgupgrade.html" title="pg_upgrade">documentation</a> outlines the necessary steps.
+ </p></div><div class="sect2" id="UPGRADING-VIA-REPLICATION"><div class="titlepage"><div><div><h3 class="title">19.6.3. Upgrading Data via Replication</h3></div></div></div><p>
+ It is also possible to use logical replication methods to create a standby
+ server with the updated version of <span class="productname">PostgreSQL</span>.
+ This is possible because logical replication supports
+ replication between different major versions of
+ <span class="productname">PostgreSQL</span>. The standby can be on the same computer or
+ a different computer. Once it has synced up with the primary server
+ (running the older version of <span class="productname">PostgreSQL</span>), you can
+ switch primaries and make the standby the primary and shut down the older
+ database instance. Such a switch-over results in only several seconds
+ of downtime for an upgrade.
+ </p><p>
+ This method of upgrading can be performed using the built-in logical
+ replication facilities as well as using external logical replication
+ systems such as <span class="productname">pglogical</span>,
+ <span class="productname">Slony</span>, <span class="productname">Londiste</span>, and
+ <span class="productname">Bucardo</span>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="server-shutdown.html" title="19.5. Shutting Down the Server">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="runtime.html" title="Chapter 19. Server Setup and Operation">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="preventing-server-spoofing.html" title="19.7. Preventing Server Spoofing">Next</a></td></tr><tr><td width="40%" align="left" valign="top">19.5. Shutting Down the Server </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 19.7. Preventing Server Spoofing</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/user-manag.html b/doc/src/sgml/html/user-manag.html
new file mode 100644
index 0000000..0a10b72
--- /dev/null
+++ b/doc/src/sgml/html/user-manag.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 22. Database Roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="client-authentication-problems.html" title="21.15. Authentication Problems" /><link rel="next" href="database-roles.html" title="22.1. Database Roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 22. Database Roles</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="client-authentication-problems.html" title="21.15. Authentication Problems">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="database-roles.html" title="22.1. Database Roles">Next</a></td></tr></table><hr /></div><div class="chapter" id="USER-MANAG"><div class="titlepage"><div><div><h2 class="title">Chapter 22. Database Roles</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="database-roles.html">22.1. Database Roles</a></span></dt><dt><span class="sect1"><a href="role-attributes.html">22.2. Role Attributes</a></span></dt><dt><span class="sect1"><a href="role-membership.html">22.3. Role Membership</a></span></dt><dt><span class="sect1"><a href="role-removal.html">22.4. Dropping Roles</a></span></dt><dt><span class="sect1"><a href="predefined-roles.html">22.5. Predefined Roles</a></span></dt><dt><span class="sect1"><a href="perm-functions.html">22.6. Function Security</a></span></dt></dl></div><p>
+ <span class="productname">PostgreSQL</span> manages database access permissions
+ using the concept of <em class="firstterm">roles</em>. A role can be thought of as
+ either a database user, or a group of database users, depending on how
+ the role is set up. Roles can own database objects (for example, tables
+ and functions) and can assign privileges on those objects to other roles to
+ control who has access to which objects. Furthermore, it is possible
+ to grant <em class="firstterm">membership</em> in a role to another role, thus
+ allowing the member role to use privileges assigned to another role.
+ </p><p>
+ The concept of roles subsumes the concepts of <span class="quote">“<span class="quote">users</span>”</span> and
+ <span class="quote">“<span class="quote">groups</span>”</span>. In <span class="productname">PostgreSQL</span> versions
+ before 8.1, users and groups were distinct kinds of entities, but now
+ there are only roles. Any role can act as a user, a group, or both.
+ </p><p>
+ This chapter describes how to create and manage roles.
+ More information about the effects of role privileges on various
+ database objects can be found in <a class="xref" href="ddl-priv.html" title="5.7. Privileges">Section 5.7</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="client-authentication-problems.html" title="21.15. Authentication Problems">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="database-roles.html" title="22.1. Database Roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">21.15. Authentication Problems </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 22.1. Database Roles</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/using-explain.html b/doc/src/sgml/html/using-explain.html
new file mode 100644
index 0000000..0eba28e
--- /dev/null
+++ b/doc/src/sgml/html/using-explain.html
@@ -0,0 +1,804 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>14.1. Using EXPLAIN</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="performance-tips.html" title="Chapter 14. Performance Tips" /><link rel="next" href="planner-stats.html" title="14.2. Statistics Used by the Planner" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">14.1. Using <code class="command">EXPLAIN</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="performance-tips.html" title="Chapter 14. Performance Tips">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><th width="60%" align="center">Chapter 14. Performance Tips</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Next</a></td></tr></table><hr /></div><div class="sect1" id="USING-EXPLAIN"><div class="titlepage"><div><div><h2 class="title" style="clear: both">14.1. Using <code class="command">EXPLAIN</code></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="using-explain.html#USING-EXPLAIN-BASICS">14.1.1. <code class="command">EXPLAIN</code> Basics</a></span></dt><dt><span class="sect2"><a href="using-explain.html#USING-EXPLAIN-ANALYZE">14.1.2. <code class="command">EXPLAIN ANALYZE</code></a></span></dt><dt><span class="sect2"><a href="using-explain.html#USING-EXPLAIN-CAVEATS">14.1.3. Caveats</a></span></dt></dl></div><a id="id-1.5.13.4.2" class="indexterm"></a><a id="id-1.5.13.4.3" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> devises a <em class="firstterm">query
+ plan</em> for each query it receives. Choosing the right
+ plan to match the query structure and the properties of the data
+ is absolutely critical for good performance, so the system includes
+ a complex <em class="firstterm">planner</em> that tries to choose good plans.
+ You can use the <a class="link" href="sql-explain.html" title="EXPLAIN"><code class="command">EXPLAIN</code></a> command
+ to see what query plan the planner creates for any query.
+ Plan-reading is an art that requires some experience to master,
+ but this section attempts to cover the basics.
+ </p><p>
+ Examples in this section are drawn from the regression test database
+ after doing a <code class="command">VACUUM ANALYZE</code>, using 9.3 development sources.
+ You should be able to get similar results if you try the examples
+ yourself, but your estimated costs and row counts might vary slightly
+ because <code class="command">ANALYZE</code>'s statistics are random samples rather
+ than exact, and because costs are inherently somewhat platform-dependent.
+ </p><p>
+ The examples use <code class="command">EXPLAIN</code>'s default <span class="quote">“<span class="quote">text</span>”</span> output
+ format, which is compact and convenient for humans to read.
+ If you want to feed <code class="command">EXPLAIN</code>'s output to a program for further
+ analysis, you should use one of its machine-readable output formats
+ (XML, JSON, or YAML) instead.
+ </p><div class="sect2" id="USING-EXPLAIN-BASICS"><div class="titlepage"><div><div><h3 class="title">14.1.1. <code class="command">EXPLAIN</code> Basics</h3></div></div></div><p>
+ The structure of a query plan is a tree of <em class="firstterm">plan nodes</em>.
+ Nodes at the bottom level of the tree are scan nodes: they return raw rows
+ from a table. There are different types of scan nodes for different
+ table access methods: sequential scans, index scans, and bitmap index
+ scans. There are also non-table row sources, such as <code class="literal">VALUES</code>
+ clauses and set-returning functions in <code class="literal">FROM</code>, which have their
+ own scan node types.
+ If the query requires joining, aggregation, sorting, or other
+ operations on the raw rows, then there will be additional nodes
+ above the scan nodes to perform these operations. Again,
+ there is usually more than one possible way to do these operations,
+ so different node types can appear here too. The output
+ of <code class="command">EXPLAIN</code> has one line for each node in the plan
+ tree, showing the basic node type plus the cost estimates that the planner
+ made for the execution of that plan node. Additional lines might appear,
+ indented from the node's summary line,
+ to show additional properties of the node.
+ The very first line (the summary line for the topmost
+ node) has the estimated total execution cost for the plan; it is this
+ number that the planner seeks to minimize.
+ </p><p>
+ Here is a trivial example, just to show what the output looks like:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1;
+
+ QUERY PLAN
+-------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
+</pre><p>
+ </p><p>
+ Since this query has no <code class="literal">WHERE</code> clause, it must scan all the
+ rows of the table, so the planner has chosen to use a simple sequential
+ scan plan. The numbers that are quoted in parentheses are (left
+ to right):
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Estimated start-up cost. This is the time expended before the output
+ phase can begin, e.g., time to do the sorting in a sort node.
+ </p></li><li class="listitem"><p>
+ Estimated total cost. This is stated on the assumption that the plan
+ node is run to completion, i.e., all available rows are retrieved.
+ In practice a node's parent node might stop short of reading all
+ available rows (see the <code class="literal">LIMIT</code> example below).
+ </p></li><li class="listitem"><p>
+ Estimated number of rows output by this plan node. Again, the node
+ is assumed to be run to completion.
+ </p></li><li class="listitem"><p>
+ Estimated average width of rows output by this plan node (in bytes).
+ </p></li></ul></div><p>
+ </p><p>
+ The costs are measured in arbitrary units determined by the planner's
+ cost parameters (see <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS" title="20.7.2. Planner Cost Constants">Section 20.7.2</a>).
+ Traditional practice is to measure the costs in units of disk page
+ fetches; that is, <a class="xref" href="runtime-config-query.html#GUC-SEQ-PAGE-COST">seq_page_cost</a> is conventionally
+ set to <code class="literal">1.0</code> and the other cost parameters are set relative
+ to that. The examples in this section are run with the default cost
+ parameters.
+ </p><p>
+ It's important to understand that the cost of an upper-level node includes
+ the cost of all its child nodes. It's also important to realize that
+ the cost only reflects things that the planner cares about.
+ In particular, the cost does not consider the time spent transmitting
+ result rows to the client, which could be an important
+ factor in the real elapsed time; but the planner ignores it because
+ it cannot change it by altering the plan. (Every correct plan will
+ output the same row set, we trust.)
+ </p><p>
+ The <code class="literal">rows</code> value is a little tricky because it is
+ not the number of rows processed or scanned by the
+ plan node, but rather the number emitted by the node. This is often
+ less than the number scanned, as a result of filtering by any
+ <code class="literal">WHERE</code>-clause conditions that are being applied at the node.
+ Ideally the top-level rows estimate will approximate the number of rows
+ actually returned, updated, or deleted by the query.
+ </p><p>
+ Returning to our example:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1;
+
+ QUERY PLAN
+-------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
+</pre><p>
+ </p><p>
+ These numbers are derived very straightforwardly. If you do:
+
+</p><pre class="programlisting">
+SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
+</pre><p>
+
+ you will find that <code class="classname">tenk1</code> has 358 disk
+ pages and 10000 rows. The estimated cost is computed as (disk pages read *
+ <a class="xref" href="runtime-config-query.html#GUC-SEQ-PAGE-COST">seq_page_cost</a>) + (rows scanned *
+ <a class="xref" href="runtime-config-query.html#GUC-CPU-TUPLE-COST">cpu_tuple_cost</a>). By default,
+ <code class="varname">seq_page_cost</code> is 1.0 and <code class="varname">cpu_tuple_cost</code> is 0.01,
+ so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458.
+ </p><p>
+ Now let's modify the query to add a <code class="literal">WHERE</code> condition:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000;
+
+ QUERY PLAN
+------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=7001 width=244)
+ Filter: (unique1 &lt; 7000)
+</pre><p>
+
+ Notice that the <code class="command">EXPLAIN</code> output shows the <code class="literal">WHERE</code>
+ clause being applied as a <span class="quote">“<span class="quote">filter</span>”</span> condition attached to the Seq
+ Scan plan node. This means that
+ the plan node checks the condition for each row it scans, and outputs
+ only the ones that pass the condition.
+ The estimate of output rows has been reduced because of the
+ <code class="literal">WHERE</code> clause.
+ However, the scan will still have to visit all 10000 rows, so the cost
+ hasn't decreased; in fact it has gone up a bit (by 10000 * <a class="xref" href="runtime-config-query.html#GUC-CPU-OPERATOR-COST">cpu_operator_cost</a>, to be exact) to reflect the extra CPU
+ time spent checking the <code class="literal">WHERE</code> condition.
+ </p><p>
+ The actual number of rows this query would select is 7000, but the <code class="literal">rows</code>
+ estimate is only approximate. If you try to duplicate this experiment,
+ you will probably get a slightly different estimate; moreover, it can
+ change after each <code class="command">ANALYZE</code> command, because the
+ statistics produced by <code class="command">ANALYZE</code> are taken from a
+ randomized sample of the table.
+ </p><p>
+ Now, let's make the condition more restrictive:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------
+ Bitmap Heap Scan on tenk1 (cost=5.07..229.20 rows=101 width=244)
+ Recheck Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+</pre><p>
+
+ Here the planner has decided to use a two-step plan: the child plan
+ node visits an index to find the locations of rows matching the index
+ condition, and then the upper plan node actually fetches those rows
+ from the table itself. Fetching rows separately is much more
+ expensive than reading them sequentially, but because not all the pages
+ of the table have to be visited, this is still cheaper than a sequential
+ scan. (The reason for using two plan levels is that the upper plan
+ node sorts the row locations identified by the index into physical order
+ before reading them, to minimize the cost of separate fetches.
+ The <span class="quote">“<span class="quote">bitmap</span>”</span> mentioned in the node names is the mechanism that
+ does the sorting.)
+ </p><p>
+ Now let's add another condition to the <code class="literal">WHERE</code> clause:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND stringu1 = 'xxx';
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------
+ Bitmap Heap Scan on tenk1 (cost=5.04..229.43 rows=1 width=244)
+ Recheck Cond: (unique1 &lt; 100)
+ Filter: (stringu1 = 'xxx'::name)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+</pre><p>
+
+ The added condition <code class="literal">stringu1 = 'xxx'</code> reduces the
+ output row count estimate, but not the cost because we still have to visit
+ the same set of rows. Notice that the <code class="literal">stringu1</code> clause
+ cannot be applied as an index condition, since this index is only on
+ the <code class="literal">unique1</code> column. Instead it is applied as a filter on
+ the rows retrieved by the index. Thus the cost has actually gone up
+ slightly to reflect this extra checking.
+ </p><p>
+ In some cases the planner will prefer a <span class="quote">“<span class="quote">simple</span>”</span> index scan plan:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42;
+
+ QUERY PLAN
+-------------------------------------------------------------------​----------
+ Index Scan using tenk1_unique1 on tenk1 (cost=0.29..8.30 rows=1 width=244)
+ Index Cond: (unique1 = 42)
+</pre><p>
+
+ In this type of plan the table rows are fetched in index order, which
+ makes them even more expensive to read, but there are so few that the
+ extra cost of sorting the row locations is not worth it. You'll most
+ often see this plan type for queries that fetch just a single row. It's
+ also often used for queries that have an <code class="literal">ORDER BY</code> condition
+ that matches the index order, because then no extra sorting step is needed
+ to satisfy the <code class="literal">ORDER BY</code>. In this example, adding
+ <code class="literal">ORDER BY unique1</code> would use the same plan because the
+ index already implicitly provides the requested ordering.
+ </p><p>
+ The planner may implement an <code class="literal">ORDER BY</code> clause in several
+ ways. The above example shows that such an ordering clause may be
+ implemented implicitly. The planner may also add an explicit
+ <code class="literal">sort</code> step:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 ORDER BY unique1;
+ QUERY PLAN
+-------------------------------------------------------------------
+ Sort (cost=1109.39..1134.39 rows=10000 width=244)
+ Sort Key: unique1
+ -&gt; Seq Scan on tenk1 (cost=0.00..445.00 rows=10000 width=244)
+</pre><p>
+
+ If a part of the plan guarantees an ordering on a prefix of the
+ required sort keys, then the planner may instead decide to use an
+ <code class="literal">incremental sort</code> step:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 ORDER BY four, ten LIMIT 100;
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------------------
+ Limit (cost=521.06..538.05 rows=100 width=244)
+ -&gt; Incremental Sort (cost=521.06..2220.95 rows=10000 width=244)
+ Sort Key: four, ten
+ Presorted Key: four
+ -&gt; Index Scan using index_tenk1_on_four on tenk1 (cost=0.29..1510.08 rows=10000 width=244)
+</pre><p>
+
+ Compared to regular sorts, sorting incrementally allows returning tuples
+ before the entire result set has been sorted, which particularly enables
+ optimizations with <code class="literal">LIMIT</code> queries. It may also reduce
+ memory usage and the likelihood of spilling sorts to disk, but it comes at
+ the cost of the increased overhead of splitting the result set into multiple
+ sorting batches.
+ </p><p>
+ If there are separate indexes on several of the columns referenced
+ in <code class="literal">WHERE</code>, the planner might choose to use an AND or OR
+ combination of the indexes:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
+
+ QUERY PLAN
+-------------------------------------------------------------------​------------------
+ Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244)
+ Recheck Cond: ((unique1 &lt; 100) AND (unique2 &gt; 9000))
+ -&gt; BitmapAnd (cost=25.08..25.08 rows=10 width=0)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0)
+ Index Cond: (unique2 &gt; 9000)
+</pre><p>
+
+ But this requires visiting both indexes, so it's not necessarily a win
+ compared to using just one index and treating the other condition as
+ a filter. If you vary the ranges involved you'll see the plan change
+ accordingly.
+ </p><p>
+ Here is an example showing the effects of <code class="literal">LIMIT</code>:
+
+</p><pre class="screen">
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​------------------
+ Limit (cost=0.29..14.48 rows=2 width=244)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 (cost=0.29..71.27 rows=10 width=244)
+ Index Cond: (unique2 &gt; 9000)
+ Filter: (unique1 &lt; 100)
+</pre><p>
+ </p><p>
+ This is the same query as above, but we added a <code class="literal">LIMIT</code> so that
+ not all the rows need be retrieved, and the planner changed its mind about
+ what to do. Notice that the total cost and row count of the Index Scan
+ node are shown as if it were run to completion. However, the Limit node
+ is expected to stop after retrieving only a fifth of those rows, so its
+ total cost is only a fifth as much, and that's the actual estimated cost
+ of the query. This plan is preferred over adding a Limit node to the
+ previous plan because the Limit could not avoid paying the startup cost
+ of the bitmap scan, so the total cost would be something over 25 units
+ with that approach.
+ </p><p>
+ Let's try joining two tables, using the columns we have been discussing:
+
+</p><pre class="screen">
+EXPLAIN SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------
+ Nested Loop (cost=4.65..118.62 rows=10 width=488)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244)
+ Recheck Cond: (unique1 &lt; 10)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0)
+ Index Cond: (unique1 &lt; 10)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244)
+ Index Cond: (unique2 = t1.unique2)
+</pre><p>
+ </p><p>
+ In this plan, we have a nested-loop join node with two table scans as
+ inputs, or children. The indentation of the node summary lines reflects
+ the plan tree structure. The join's first, or <span class="quote">“<span class="quote">outer</span>”</span>, child
+ is a bitmap scan similar to those we saw before. Its cost and row count
+ are the same as we'd get from <code class="literal">SELECT ... WHERE unique1 &lt; 10</code>
+ because we are
+ applying the <code class="literal">WHERE</code> clause <code class="literal">unique1 &lt; 10</code>
+ at that node.
+ The <code class="literal">t1.unique2 = t2.unique2</code> clause is not relevant yet,
+ so it doesn't affect the row count of the outer scan. The nested-loop
+ join node will run its second,
+ or <span class="quote">“<span class="quote">inner</span>”</span> child once for each row obtained from the outer child.
+ Column values from the current outer row can be plugged into the inner
+ scan; here, the <code class="literal">t1.unique2</code> value from the outer row is available,
+ so we get a plan and costs similar to what we saw above for a simple
+ <code class="literal">SELECT ... WHERE t2.unique2 = <em class="replaceable"><code>constant</code></em></code> case.
+ (The estimated cost is actually a bit lower than what was seen above,
+ as a result of caching that's expected to occur during the repeated
+ index scans on <code class="literal">t2</code>.) The
+ costs of the loop node are then set on the basis of the cost of the outer
+ scan, plus one repetition of the inner scan for each outer row (10 * 7.91,
+ here), plus a little CPU time for join processing.
+ </p><p>
+ In this example the join's output row count is the same as the product
+ of the two scans' row counts, but that's not true in all cases because
+ there can be additional <code class="literal">WHERE</code> clauses that mention both tables
+ and so can only be applied at the join point, not to either input scan.
+ Here's an example:
+
+</p><pre class="screen">
+EXPLAIN SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 10 AND t2.unique2 &lt; 10 AND t1.hundred &lt; t2.hundred;
+
+ QUERY PLAN
+-------------------------------------------------------------------​--------------------------
+ Nested Loop (cost=4.65..49.46 rows=33 width=488)
+ Join Filter: (t1.hundred &lt; t2.hundred)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244)
+ Recheck Cond: (unique1 &lt; 10)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0)
+ Index Cond: (unique1 &lt; 10)
+ -&gt; Materialize (cost=0.29..8.51 rows=10 width=244)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..8.46 rows=10 width=244)
+ Index Cond: (unique2 &lt; 10)
+</pre><p>
+
+ The condition <code class="literal">t1.hundred &lt; t2.hundred</code> can't be
+ tested in the <code class="literal">tenk2_unique2</code> index, so it's applied at the
+ join node. This reduces the estimated output row count of the join node,
+ but does not change either input scan.
+ </p><p>
+ Notice that here the planner has chosen to <span class="quote">“<span class="quote">materialize</span>”</span> the inner
+ relation of the join, by putting a Materialize plan node atop it. This
+ means that the <code class="literal">t2</code> index scan will be done just once, even
+ though the nested-loop join node needs to read that data ten times, once
+ for each row from the outer relation. The Materialize node saves the data
+ in memory as it's read, and then returns the data from memory on each
+ subsequent pass.
+ </p><p>
+ When dealing with outer joins, you might see join plan nodes with both
+ <span class="quote">“<span class="quote">Join Filter</span>”</span> and plain <span class="quote">“<span class="quote">Filter</span>”</span> conditions attached.
+ Join Filter conditions come from the outer join's <code class="literal">ON</code> clause,
+ so a row that fails the Join Filter condition could still get emitted as
+ a null-extended row. But a plain Filter condition is applied after the
+ outer-join rules and so acts to remove rows unconditionally. In an inner
+ join there is no semantic difference between these types of filters.
+ </p><p>
+ If we change the query's selectivity a bit, we might get a very different
+ join plan:
+
+</p><pre class="screen">
+EXPLAIN SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------
+ Hash Join (cost=230.47..713.98 rows=101 width=488)
+ Hash Cond: (t2.unique2 = t1.unique2)
+ -&gt; Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244)
+ -&gt; Hash (cost=229.20..229.20 rows=101 width=244)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244)
+ Recheck Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+</pre><p>
+ </p><p>
+ Here, the planner has chosen to use a hash join, in which rows of one
+ table are entered into an in-memory hash table, after which the other
+ table is scanned and the hash table is probed for matches to each row.
+ Again note how the indentation reflects the plan structure: the bitmap
+ scan on <code class="literal">tenk1</code> is the input to the Hash node, which constructs
+ the hash table. That's then returned to the Hash Join node, which reads
+ rows from its outer child plan and searches the hash table for each one.
+ </p><p>
+ Another possible type of join is a merge join, illustrated here:
+
+</p><pre class="screen">
+EXPLAIN SELECT *
+FROM tenk1 t1, onek t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------
+ Merge Join (cost=198.11..268.19 rows=10 width=488)
+ Merge Cond: (t1.unique2 = t2.unique2)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244)
+ Filter: (unique1 &lt; 100)
+ -&gt; Sort (cost=197.83..200.33 rows=1000 width=244)
+ Sort Key: t2.unique2
+ -&gt; Seq Scan on onek t2 (cost=0.00..148.00 rows=1000 width=244)
+</pre><p>
+ </p><p>
+ Merge join requires its input data to be sorted on the join keys. In this
+ plan the <code class="literal">tenk1</code> data is sorted by using an index scan to visit
+ the rows in the correct order, but a sequential scan and sort is preferred
+ for <code class="literal">onek</code>, because there are many more rows to be visited in
+ that table.
+ (Sequential-scan-and-sort frequently beats an index scan for sorting many rows,
+ because of the nonsequential disk access required by the index scan.)
+ </p><p>
+ One way to look at variant plans is to force the planner to disregard
+ whatever strategy it thought was the cheapest, using the enable/disable
+ flags described in <a class="xref" href="runtime-config-query.html#RUNTIME-CONFIG-QUERY-ENABLE" title="20.7.1. Planner Method Configuration">Section 20.7.1</a>.
+ (This is a crude tool, but useful. See
+ also <a class="xref" href="explicit-joins.html" title="14.3. Controlling the Planner with Explicit JOIN Clauses">Section 14.3</a>.)
+ For example, if we're unconvinced that sequential-scan-and-sort is the best way to
+ deal with table <code class="literal">onek</code> in the previous example, we could try
+
+</p><pre class="screen">
+SET enable_sort = off;
+
+EXPLAIN SELECT *
+FROM tenk1 t1, onek t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------
+ Merge Join (cost=0.56..292.65 rows=10 width=488)
+ Merge Cond: (t1.unique2 = t2.unique2)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244)
+ Filter: (unique1 &lt; 100)
+ -&gt; Index Scan using onek_unique2 on onek t2 (cost=0.28..224.79 rows=1000 width=244)
+</pre><p>
+
+ which shows that the planner thinks that sorting <code class="literal">onek</code> by
+ index-scanning is about 12% more expensive than sequential-scan-and-sort.
+ Of course, the next question is whether it's right about that.
+ We can investigate that using <code class="command">EXPLAIN ANALYZE</code>, as discussed
+ below.
+ </p></div><div class="sect2" id="USING-EXPLAIN-ANALYZE"><div class="titlepage"><div><div><h3 class="title">14.1.2. <code class="command">EXPLAIN ANALYZE</code></h3></div></div></div><p>
+ It is possible to check the accuracy of the planner's estimates
+ by using <code class="command">EXPLAIN</code>'s <code class="literal">ANALYZE</code> option. With this
+ option, <code class="command">EXPLAIN</code> actually executes the query, and then displays
+ the true row counts and true run time accumulated within each plan node,
+ along with the same estimates that a plain <code class="command">EXPLAIN</code>
+ shows. For example, we might get a result like this:
+
+</p><pre class="screen">
+EXPLAIN ANALYZE SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​--------------------------------------------------------------
+ Nested Loop (cost=4.65..118.62 rows=10 width=488) (actual time=0.128..0.377 rows=10 loops=1)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244) (actual time=0.057..0.121 rows=10 loops=1)
+ Recheck Cond: (unique1 &lt; 10)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) (actual time=0.024..0.024 rows=10 loops=1)
+ Index Cond: (unique1 &lt; 10)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244) (actual time=0.021..0.022 rows=1 loops=10)
+ Index Cond: (unique2 = t1.unique2)
+ Planning time: 0.181 ms
+ Execution time: 0.501 ms
+</pre><p>
+
+ Note that the <span class="quote">“<span class="quote">actual time</span>”</span> values are in milliseconds of
+ real time, whereas the <code class="literal">cost</code> estimates are expressed in
+ arbitrary units; so they are unlikely to match up.
+ The thing that's usually most important to look for is whether the
+ estimated row counts are reasonably close to reality. In this example
+ the estimates were all dead-on, but that's quite unusual in practice.
+ </p><p>
+ In some query plans, it is possible for a subplan node to be executed more
+ than once. For example, the inner index scan will be executed once per
+ outer row in the above nested-loop plan. In such cases, the
+ <code class="literal">loops</code> value reports the
+ total number of executions of the node, and the actual time and rows
+ values shown are averages per-execution. This is done to make the numbers
+ comparable with the way that the cost estimates are shown. Multiply by
+ the <code class="literal">loops</code> value to get the total time actually spent in
+ the node. In the above example, we spent a total of 0.220 milliseconds
+ executing the index scans on <code class="literal">tenk2</code>.
+ </p><p>
+ In some cases <code class="command">EXPLAIN ANALYZE</code> shows additional execution
+ statistics beyond the plan node execution times and row counts.
+ For example, Sort and Hash nodes provide extra information:
+
+</p><pre class="screen">
+EXPLAIN ANALYZE SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------------------------------------------------------​------
+ Sort (cost=717.34..717.59 rows=101 width=488) (actual time=7.761..7.774 rows=100 loops=1)
+ Sort Key: t1.fivethous
+ Sort Method: quicksort Memory: 77kB
+ -&gt; Hash Join (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1)
+ Hash Cond: (t2.unique2 = t1.unique2)
+ -&gt; Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1)
+ -&gt; Hash (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1)
+ Buckets: 1024 Batches: 1 Memory Usage: 28kB
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)
+ Recheck Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.049..0.049 rows=100 loops=1)
+ Index Cond: (unique1 &lt; 100)
+ Planning time: 0.194 ms
+ Execution time: 8.008 ms
+</pre><p>
+
+ The Sort node shows the sort method used (in particular, whether the sort
+ was in-memory or on-disk) and the amount of memory or disk space needed.
+ The Hash node shows the number of hash buckets and batches as well as the
+ peak amount of memory used for the hash table. (If the number of batches
+ exceeds one, there will also be disk space usage involved, but that is not
+ shown.)
+ </p><p>
+ Another type of extra information is the number of rows removed by a
+ filter condition:
+
+</p><pre class="screen">
+EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten &lt; 7;
+
+ QUERY PLAN
+-------------------------------------------------------------------​--------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=7000 width=244) (actual time=0.016..5.107 rows=7000 loops=1)
+ Filter: (ten &lt; 7)
+ Rows Removed by Filter: 3000
+ Planning time: 0.083 ms
+ Execution time: 5.905 ms
+</pre><p>
+
+ These counts can be particularly valuable for filter conditions applied at
+ join nodes. The <span class="quote">“<span class="quote">Rows Removed</span>”</span> line only appears when at least
+ one scanned row, or potential join pair in the case of a join node,
+ is rejected by the filter condition.
+ </p><p>
+ A case similar to filter conditions occurs with <span class="quote">“<span class="quote">lossy</span>”</span>
+ index scans. For example, consider this search for polygons containing a
+ specific point:
+
+</p><pre class="screen">
+EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; polygon '(0.5,2.0)';
+
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------------------
+ Seq Scan on polygon_tbl (cost=0.00..1.05 rows=1 width=32) (actual time=0.044..0.044 rows=0 loops=1)
+ Filter: (f1 @&gt; '((0.5,2))'::polygon)
+ Rows Removed by Filter: 4
+ Planning time: 0.040 ms
+ Execution time: 0.083 ms
+</pre><p>
+
+ The planner thinks (quite correctly) that this sample table is too small
+ to bother with an index scan, so we have a plain sequential scan in which
+ all the rows got rejected by the filter condition. But if we force an
+ index scan to be used, we see:
+
+</p><pre class="screen">
+SET enable_seqscan TO off;
+
+EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; polygon '(0.5,2.0)';
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------------------------------------------
+ Index Scan using gpolygonind on polygon_tbl (cost=0.13..8.15 rows=1 width=32) (actual time=0.062..0.062 rows=0 loops=1)
+ Index Cond: (f1 @&gt; '((0.5,2))'::polygon)
+ Rows Removed by Index Recheck: 1
+ Planning time: 0.034 ms
+ Execution time: 0.144 ms
+</pre><p>
+
+ Here we can see that the index returned one candidate row, which was
+ then rejected by a recheck of the index condition. This happens because a
+ GiST index is <span class="quote">“<span class="quote">lossy</span>”</span> for polygon containment tests: it actually
+ returns the rows with polygons that overlap the target, and then we have
+ to do the exact containment test on those rows.
+ </p><p>
+ <code class="command">EXPLAIN</code> has a <code class="literal">BUFFERS</code> option that can be used with
+ <code class="literal">ANALYZE</code> to get even more run time statistics:
+
+</p><pre class="screen">
+EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
+
+ QUERY PLAN
+-------------------------------------------------------------------​--------------------------------------------------------------
+ Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244) (actual time=0.323..0.342 rows=10 loops=1)
+ Recheck Cond: ((unique1 &lt; 100) AND (unique2 &gt; 9000))
+ Buffers: shared hit=15
+ -&gt; BitmapAnd (cost=25.08..25.08 rows=10 width=0) (actual time=0.309..0.309 rows=0 loops=1)
+ Buffers: shared hit=7
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.043..0.043 rows=100 loops=1)
+ Index Cond: (unique1 &lt; 100)
+ Buffers: shared hit=2
+ -&gt; Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) (actual time=0.227..0.227 rows=999 loops=1)
+ Index Cond: (unique2 &gt; 9000)
+ Buffers: shared hit=5
+ Planning time: 0.088 ms
+ Execution time: 0.423 ms
+</pre><p>
+
+ The numbers provided by <code class="literal">BUFFERS</code> help to identify which parts
+ of the query are the most I/O-intensive.
+ </p><p>
+ Keep in mind that because <code class="command">EXPLAIN ANALYZE</code> actually
+ runs the query, any side-effects will happen as usual, even though
+ whatever results the query might output are discarded in favor of
+ printing the <code class="command">EXPLAIN</code> data. If you want to analyze a
+ data-modifying query without changing your tables, you can
+ roll the command back afterwards, for example:
+
+</p><pre class="screen">
+BEGIN;
+
+EXPLAIN ANALYZE UPDATE tenk1 SET hundred = hundred + 1 WHERE unique1 &lt; 100;
+
+ QUERY PLAN
+-------------------------------------------------------------------​-------------------------------------------------------------
+ Update on tenk1 (cost=5.08..230.08 rows=0 width=0) (actual time=3.791..3.792 rows=0 loops=1)
+ -&gt; Bitmap Heap Scan on tenk1 (cost=5.08..230.08 rows=102 width=10) (actual time=0.069..0.513 rows=100 loops=1)
+ Recheck Cond: (unique1 &lt; 100)
+ Heap Blocks: exact=90
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.05 rows=102 width=0) (actual time=0.036..0.037 rows=300 loops=1)
+ Index Cond: (unique1 &lt; 100)
+ Planning Time: 0.113 ms
+ Execution Time: 3.850 ms
+
+ROLLBACK;
+</pre><p>
+ </p><p>
+ As seen in this example, when the query is an <code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or
+ <code class="command">MERGE</code> command, the actual work of
+ applying the table changes is done by a top-level Insert, Update,
+ Delete, or Merge plan node. The plan nodes underneath this node perform
+ the work of locating the old rows and/or computing the new data.
+ So above, we see the same sort of bitmap table scan we've seen already,
+ and its output is fed to an Update node that stores the updated rows.
+ It's worth noting that although the data-modifying node can take a
+ considerable amount of run time (here, it's consuming the lion's share
+ of the time), the planner does not currently add anything to the cost
+ estimates to account for that work. That's because the work to be done is
+ the same for every correct query plan, so it doesn't affect planning
+ decisions.
+ </p><p>
+ When an <code class="command">UPDATE</code>, <code class="command">DELETE</code>, or
+ <code class="command">MERGE</code> command affects an
+ inheritance hierarchy, the output might look like this:
+
+</p><pre class="screen">
+EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
+ QUERY PLAN
+-------------------------------------------------------------------​-----------------------------------
+ Update on parent (cost=0.00..24.59 rows=0 width=0)
+ Update on parent parent_1
+ Update on child1 parent_2
+ Update on child2 parent_3
+ Update on child3 parent_4
+ -&gt; Result (cost=0.00..24.59 rows=4 width=14)
+ -&gt; Append (cost=0.00..24.54 rows=4 width=14)
+ -&gt; Seq Scan on parent parent_1 (cost=0.00..0.00 rows=1 width=14)
+ Filter: (f1 = 101)
+ -&gt; Index Scan using child1_pkey on child1 parent_2 (cost=0.15..8.17 rows=1 width=14)
+ Index Cond: (f1 = 101)
+ -&gt; Index Scan using child2_pkey on child2 parent_3 (cost=0.15..8.17 rows=1 width=14)
+ Index Cond: (f1 = 101)
+ -&gt; Index Scan using child3_pkey on child3 parent_4 (cost=0.15..8.17 rows=1 width=14)
+ Index Cond: (f1 = 101)
+</pre><p>
+
+ In this example the Update node needs to consider three child tables as
+ well as the originally-mentioned parent table. So there are four input
+ scanning subplans, one per table. For clarity, the Update node is
+ annotated to show the specific target tables that will be updated, in the
+ same order as the corresponding subplans.
+ </p><p>
+ The <code class="literal">Planning time</code> shown by <code class="command">EXPLAIN
+ ANALYZE</code> is the time it took to generate the query plan from the
+ parsed query and optimize it. It does not include parsing or rewriting.
+ </p><p>
+ The <code class="literal">Execution time</code> shown by <code class="command">EXPLAIN
+ ANALYZE</code> includes executor start-up and shut-down time, as well
+ as the time to run any triggers that are fired, but it does not include
+ parsing, rewriting, or planning time.
+ Time spent executing <code class="literal">BEFORE</code> triggers, if any, is included in
+ the time for the related Insert, Update, or Delete node; but time
+ spent executing <code class="literal">AFTER</code> triggers is not counted there because
+ <code class="literal">AFTER</code> triggers are fired after completion of the whole plan.
+ The total time spent in each trigger
+ (either <code class="literal">BEFORE</code> or <code class="literal">AFTER</code>) is also shown separately.
+ Note that deferred constraint triggers will not be executed
+ until end of transaction and are thus not considered at all by
+ <code class="command">EXPLAIN ANALYZE</code>.
+ </p></div><div class="sect2" id="USING-EXPLAIN-CAVEATS"><div class="titlepage"><div><div><h3 class="title">14.1.3. Caveats</h3></div></div></div><p>
+ There are two significant ways in which run times measured by
+ <code class="command">EXPLAIN ANALYZE</code> can deviate from normal execution of
+ the same query. First, since no output rows are delivered to the client,
+ network transmission costs and I/O conversion costs are not included.
+ Second, the measurement overhead added by <code class="command">EXPLAIN
+ ANALYZE</code> can be significant, especially on machines with slow
+ <code class="function">gettimeofday()</code> operating-system calls. You can use the
+ <a class="xref" href="pgtesttiming.html" title="pg_test_timing"><span class="refentrytitle"><span class="application">pg_test_timing</span></span></a> tool to measure the overhead of timing
+ on your system.
+ </p><p>
+ <code class="command">EXPLAIN</code> results should not be extrapolated to situations
+ much different from the one you are actually testing; for example,
+ results on a toy-sized table cannot be assumed to apply to large tables.
+ The planner's cost estimates are not linear and so it might choose
+ a different plan for a larger or smaller table. An extreme example
+ is that on a table that only occupies one disk page, you'll nearly
+ always get a sequential scan plan whether indexes are available or not.
+ The planner realizes that it's going to take one disk page read to
+ process the table in any case, so there's no value in expending additional
+ page reads to look at an index. (We saw this happening in the
+ <code class="literal">polygon_tbl</code> example above.)
+ </p><p>
+ There are cases in which the actual and estimated values won't match up
+ well, but nothing is really wrong. One such case occurs when
+ plan node execution is stopped short by a <code class="literal">LIMIT</code> or similar
+ effect. For example, in the <code class="literal">LIMIT</code> query we used before,
+
+</p><pre class="screen">
+EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;
+
+ QUERY PLAN
+-------------------------------------------------------------------​------------------------------------------------------------
+ Limit (cost=0.29..14.71 rows=2 width=244) (actual time=0.177..0.249 rows=2 loops=1)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 (cost=0.29..72.42 rows=10 width=244) (actual time=0.174..0.244 rows=2 loops=1)
+ Index Cond: (unique2 &gt; 9000)
+ Filter: (unique1 &lt; 100)
+ Rows Removed by Filter: 287
+ Planning time: 0.096 ms
+ Execution time: 0.336 ms
+</pre><p>
+
+ the estimated cost and row count for the Index Scan node are shown as
+ though it were run to completion. But in reality the Limit node stopped
+ requesting rows after it got two, so the actual row count is only 2 and
+ the run time is less than the cost estimate would suggest. This is not
+ an estimation error, only a discrepancy in the way the estimates and true
+ values are displayed.
+ </p><p>
+ Merge joins also have measurement artifacts that can confuse the unwary.
+ A merge join will stop reading one input if it's exhausted the other input
+ and the next key value in the one input is greater than the last key value
+ of the other input; in such a case there can be no more matches and so no
+ need to scan the rest of the first input. This results in not reading all
+ of one child, with results like those mentioned for <code class="literal">LIMIT</code>.
+ Also, if the outer (first) child contains rows with duplicate key values,
+ the inner (second) child is backed up and rescanned for the portion of its
+ rows matching that key value. <code class="command">EXPLAIN ANALYZE</code> counts these
+ repeated emissions of the same inner rows as if they were real additional
+ rows. When there are many outer duplicates, the reported actual row count
+ for the inner child plan node can be significantly larger than the number
+ of rows that are actually in the inner relation.
+ </p><p>
+ BitmapAnd and BitmapOr nodes always report their actual row counts as zero,
+ due to implementation limitations.
+ </p><p>
+ Normally, <code class="command">EXPLAIN</code> will display every plan node
+ created by the planner. However, there are cases where the executor
+ can determine that certain nodes need not be executed because they
+ cannot produce any rows, based on parameter values that were not
+ available at planning time. (Currently this can only happen for child
+ nodes of an Append or MergeAppend node that is scanning a partitioned
+ table.) When this happens, those plan nodes are omitted from
+ the <code class="command">EXPLAIN</code> output and a <code class="literal">Subplans
+ Removed: <em class="replaceable"><code>N</code></em></code> annotation appears
+ instead.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="performance-tips.html" title="Chapter 14. Performance Tips">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="performance-tips.html" title="Chapter 14. Performance Tips">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="planner-stats.html" title="14.2. Statistics Used by the Planner">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 14. Performance Tips </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 14.2. Statistics Used by the Planner</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/uuid-ossp.html b/doc/src/sgml/html/uuid-ossp.html
new file mode 100644
index 0000000..2d6bfc3
--- /dev/null
+++ b/doc/src/sgml/html/uuid-ossp.html
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.49. uuid-ossp</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="unaccent.html" title="F.48. unaccent" /><link rel="next" href="xml2.html" title="F.50. xml2" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.49. uuid-ossp</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="unaccent.html" title="F.48. unaccent">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xml2.html" title="F.50. xml2">Next</a></td></tr></table><hr /></div><div class="sect1" id="UUID-OSSP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.49. uuid-ossp</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="uuid-ossp.html#id-1.11.7.58.5">F.49.1. <code class="literal">uuid-ossp</code> Functions</a></span></dt><dt><span class="sect2"><a href="uuid-ossp.html#id-1.11.7.58.6">F.49.2. Building <code class="filename">uuid-ossp</code></a></span></dt><dt><span class="sect2"><a href="uuid-ossp.html#id-1.11.7.58.7">F.49.3. Author</a></span></dt></dl></div><a id="id-1.11.7.58.2" class="indexterm"></a><p>
+ The <code class="filename">uuid-ossp</code> module provides functions to generate universally
+ unique identifiers (UUIDs) using one of several standard algorithms. There
+ are also functions to produce certain special UUID constants.
+ This module is only necessary for special requirements beyond what is
+ available in core <span class="productname">PostgreSQL</span>. See <a class="xref" href="functions-uuid.html" title="9.14. UUID Functions">Section 9.14</a> for built-in ways to generate UUIDs.
+ </p><p>
+ This module is considered <span class="quote">“<span class="quote">trusted</span>”</span>, that is, it can be
+ installed by non-superusers who have <code class="literal">CREATE</code> privilege
+ on the current database.
+ </p><div class="sect2" id="id-1.11.7.58.5"><div class="titlepage"><div><div><h3 class="title">F.49.1. <code class="literal">uuid-ossp</code> Functions</h3></div></div></div><p>
+ <a class="xref" href="uuid-ossp.html#UUID-OSSP-FUNCTIONS" title="Table F.32. Functions for UUID Generation">Table F.32</a> shows the functions available to
+ generate UUIDs.
+ The relevant standards ITU-T Rec. X.667, ISO/IEC 9834-8:2005, and
+ <a class="ulink" href="https://tools.ietf.org/html/rfc4122" target="_top">RFC 4122</a>
+ specify four algorithms for generating UUIDs, identified by the
+ version numbers 1, 3, 4, and 5. (There is no version 2 algorithm.)
+ Each of these algorithms could be suitable for a different set of
+ applications.
+ </p><div class="table" id="UUID-OSSP-FUNCTIONS"><p class="title"><strong>Table F.32. Functions for UUID Generation</strong></p><div class="table-contents"><table class="table" summary="Functions for UUID Generation" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.58.5.3.2.2.1.1.1.1" class="indexterm"></a>
+ <code class="function">uuid_generate_v1</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Generates a version 1 UUID. This involves the MAC
+ address of the computer and a time stamp. Note that UUIDs of this
+ kind reveal the identity of the computer that created the identifier
+ and the time at which it did so, which might make it unsuitable for
+ certain security-sensitive applications.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.58.5.3.2.2.2.1.1.1" class="indexterm"></a>
+ <code class="function">uuid_generate_v1mc</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Generates a version 1 UUID, but uses a random multicast
+ MAC address instead of the real MAC address of the computer.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <a id="id-1.11.7.58.5.3.2.2.3.1.1.1" class="indexterm"></a>
+ <code class="function">uuid_generate_v3</code> ( <em class="parameter"><code>namespace</code></em> <code class="type">uuid</code>, <em class="parameter"><code>name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Generates a version 3 UUID in the given namespace using
+ the specified input name. The namespace should be one of the special
+ constants produced by the <code class="function">uuid_ns_*()</code> functions
+ shown in <a class="xref" href="uuid-ossp.html#UUID-OSSP-CONSTANTS" title="Table F.33. Functions Returning UUID Constants">Table F.33</a>. (It could be any UUID
+ in theory.) The name is an identifier in the selected namespace.
+ </p>
+ <p>
+ For example:
+
+</p><pre class="programlisting">
+SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org');
+</pre><p>
+
+ The name parameter will be MD5-hashed, so the cleartext cannot be
+ derived from the generated UUID.
+ The generation of UUIDs by this method has no random or
+ environment-dependent element and is therefore reproducible.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_generate_v4</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Generates a version 4 UUID, which is derived entirely
+ from random numbers.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_generate_v5</code> ( <em class="parameter"><code>namespace</code></em> <code class="type">uuid</code>, <em class="parameter"><code>name</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Generates a version 5 UUID, which works like a version 3
+ UUID except that SHA-1 is used as a hashing method. Version 5 should
+ be preferred over version 3 because SHA-1 is thought to be more secure
+ than MD5.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><div class="table" id="UUID-OSSP-CONSTANTS"><p class="title"><strong>Table F.33. Functions Returning UUID Constants</strong></p><div class="table-contents"><table class="table" summary="Functions Returning UUID Constants" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_nil</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Returns a <span class="quote">“<span class="quote">nil</span>”</span> UUID constant, which does not occur as a
+ real UUID.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_ns_dns</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Returns a constant designating the DNS namespace for UUIDs.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_ns_url</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Returns a constant designating the URL namespace for UUIDs.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_ns_oid</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Returns a constant designating the ISO object identifier (OID) namespace for
+ UUIDs. (This pertains to ASN.1 OIDs, which are unrelated to the OIDs
+ used in <span class="productname">PostgreSQL</span>.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">uuid_ns_x500</code> ()
+ → <code class="returnvalue">uuid</code>
+ </p>
+ <p>
+ Returns a constant designating the X.500 distinguished name (DN)
+ namespace for UUIDs.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.58.6"><div class="titlepage"><div><div><h3 class="title">F.49.2. Building <code class="filename">uuid-ossp</code></h3></div></div></div><p>
+ Historically this module depended on the OSSP UUID library, which accounts
+ for the module's name. While the OSSP UUID library can still be found
+ at <a class="ulink" href="http://www.ossp.org/pkg/lib/uuid/" target="_top">http://www.ossp.org/pkg/lib/uuid/</a>, it is not well
+ maintained, and is becoming increasingly difficult to port to newer
+ platforms. <code class="filename">uuid-ossp</code> can now be built without the OSSP
+ library on some platforms. On FreeBSD and some other BSD-derived
+ platforms, suitable UUID creation functions are included in the
+ core <code class="filename">libc</code> library. On Linux, macOS, and some other
+ platforms, suitable functions are provided in the <code class="filename">libuuid</code>
+ library, which originally came from the <code class="literal">e2fsprogs</code> project
+ (though on modern Linux it is considered part
+ of <code class="literal">util-linux-ng</code>). When invoking <code class="filename">configure</code>,
+ specify <code class="option">--with-uuid=bsd</code> to use the BSD functions,
+ or <code class="option">--with-uuid=e2fs</code> to
+ use <code class="literal">e2fsprogs</code>' <code class="filename">libuuid</code>, or
+ <code class="option">--with-uuid=ossp</code> to use the OSSP UUID library.
+ More than one of these libraries might be available on a particular
+ machine, so <code class="filename">configure</code> does not automatically choose one.
+ </p></div><div class="sect2" id="id-1.11.7.58.7"><div class="titlepage"><div><div><h3 class="title">F.49.3. Author</h3></div></div></div><p>
+ Peter Eisentraut <code class="email">&lt;<a class="email" href="mailto:peter_e@gmx.net">peter_e@gmx.net</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="unaccent.html" title="F.48. unaccent">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xml2.html" title="F.50. xml2">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.48. unaccent </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> F.50. xml2</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/vacuumlo.html b/doc/src/sgml/html/vacuumlo.html
new file mode 100644
index 0000000..4c687e2
--- /dev/null
+++ b/doc/src/sgml/html/vacuumlo.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>vacuumlo</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="oid2name.html" title="oid2name" /><link rel="next" href="contrib-prog-server.html" title="G.2. Server Applications" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center"><span class="application">vacuumlo</span></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="oid2name.html" title="oid2name">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib-prog-client.html" title="G.1. Client Applications">Up</a></td><th width="60%" align="center">G.1. Client Applications</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-prog-server.html" title="G.2. Server Applications">Next</a></td></tr></table><hr /></div><div class="refentry" id="VACUUMLO"><div class="titlepage"></div><a id="id-1.11.8.4.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle"><span class="application">vacuumlo</span></span></h2><p>vacuumlo — remove orphaned large objects from a <span class="productname">PostgreSQL</span> database</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p id="id-1.11.8.4.4.4.1"><code class="command">vacuumlo</code> [<em class="replaceable"><code>option</code></em>...] <em class="replaceable"><code>dbname</code></em>... </p></div></div><div class="refsect1" id="id-1.11.8.4.4.5"><h2>Description</h2><p>
+ <span class="application">vacuumlo</span> is a simple utility program that will remove any
+ <span class="quote">“<span class="quote">orphaned</span>”</span> large objects from a
+ <span class="productname">PostgreSQL</span> database. An orphaned large object (LO) is
+ considered to be any LO whose OID does not appear in any <code class="type">oid</code> or
+ <code class="type">lo</code> data column of the database.
+ </p><p>
+ If you use this, you may also be interested in the <code class="function">lo_manage</code>
+ trigger in the <a class="xref" href="lo.html" title="F.22. lo">lo</a> module.
+ <code class="function">lo_manage</code> is useful to try
+ to avoid creating orphaned LOs in the first place.
+ </p><p>
+ All databases named on the command line are processed.
+ </p></div><div class="refsect1" id="id-1.11.8.4.4.6"><h2>Options</h2><p>
+ <span class="application">vacuumlo</span> accepts the following command-line arguments:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-l <em class="replaceable"><code>limit</code></em></code><br /></span><span class="term"><code class="option">--limit=<em class="replaceable"><code>limit</code></em></code></span></dt><dd><p>
+ Remove no more than <em class="replaceable"><code>limit</code></em> large objects per
+ transaction (default 1000). Since the server acquires a lock per LO
+ removed, removing too many LOs in one transaction risks exceeding
+ <a class="xref" href="runtime-config-locks.html#GUC-MAX-LOCKS-PER-TRANSACTION">max_locks_per_transaction</a>. Set the limit to
+ zero if you want all removals done in a single transaction.
+ </p></dd><dt><span class="term"><code class="option">-n</code><br /></span><span class="term"><code class="option">--dry-run</code></span></dt><dd><p>Don't remove anything, just show what would be done.</p></dd><dt><span class="term"><code class="option">-v</code><br /></span><span class="term"><code class="option">--verbose</code></span></dt><dd><p>Write a lot of progress messages.</p></dd><dt><span class="term"><code class="option">-V</code><br /></span><span class="term"><code class="option">--version</code></span></dt><dd><p>
+ Print the <span class="application">vacuumlo</span> version and exit.
+ </p></dd><dt><span class="term"><code class="option">-?</code><br /></span><span class="term"><code class="option">--help</code></span></dt><dd><p>
+ Show help about <span class="application">vacuumlo</span> command line
+ arguments, and exit.
+ </p></dd></dl></div><p>
+ </p><p>
+ <span class="application">vacuumlo</span> also accepts the following command-line
+ arguments for connection parameters:
+
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="option">-h <em class="replaceable"><code>host</code></em></code><br /></span><span class="term"><code class="option">--host=<em class="replaceable"><code>host</code></em></code></span></dt><dd><p>Database server's host.</p></dd><dt><span class="term"><code class="option">-p <em class="replaceable"><code>port</code></em></code><br /></span><span class="term"><code class="option">--port=<em class="replaceable"><code>port</code></em></code></span></dt><dd><p>Database server's port.</p></dd><dt><span class="term"><code class="option">-U <em class="replaceable"><code>username</code></em></code><br /></span><span class="term"><code class="option">--username=<em class="replaceable"><code>username</code></em></code></span></dt><dd><p>User name to connect as.</p></dd><dt><span class="term"><code class="option">-w</code><br /></span><span class="term"><code class="option">--no-password</code></span></dt><dd><p>
+ Never issue a password prompt. If the server requires password
+ authentication and a password is not available by other means
+ such as a <code class="filename">.pgpass</code> file, the connection
+ attempt will fail. This option can be useful in batch jobs and
+ scripts where no user is present to enter a password.
+ </p></dd><dt><span class="term"><code class="option">-W</code><br /></span><span class="term"><code class="option">--password</code></span></dt><dd><p>
+ Force <span class="application">vacuumlo</span> to prompt for a
+ password before connecting to a database.
+ </p><p>
+ This option is never essential, since
+ <span class="application">vacuumlo</span> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <span class="application">vacuumlo</span> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <code class="option">-W</code> to avoid the extra
+ connection attempt.
+ </p></dd></dl></div><p>
+ </p></div><div class="refsect1" id="id-1.11.8.4.4.7"><h2>Environment</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="envar">PGHOST</code><br /></span><span class="term"><code class="envar">PGPORT</code><br /></span><span class="term"><code class="envar">PGUSER</code></span></dt><dd><p>
+ Default connection parameters.
+ </p></dd></dl></div><p>
+ This utility, like most other <span class="productname">PostgreSQL</span> utilities,
+ also uses the environment variables supported by <span class="application">libpq</span>
+ (see <a class="xref" href="libpq-envars.html" title="34.15. Environment Variables">Section 34.15</a>).
+ </p><p>
+ The environment variable <code class="envar">PG_COLOR</code> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <code class="literal">always</code>, <code class="literal">auto</code> and
+ <code class="literal">never</code>.
+ </p></div><div class="refsect1" id="id-1.11.8.4.4.8"><h2>Notes</h2><p>
+ <span class="application">vacuumlo</span> works by the following method:
+ First, <span class="application">vacuumlo</span> builds a temporary table which contains all
+ of the OIDs of the large objects in the selected database. It then scans
+ through all columns in the database that are of type
+ <code class="type">oid</code> or <code class="type">lo</code>, and removes matching entries from the temporary
+ table. (Note: Only types with these names are considered; in particular,
+ domains over them are not considered.) The remaining entries in the
+ temporary table identify orphaned LOs. These are removed.
+ </p></div><div class="refsect1" id="id-1.11.8.4.4.9"><h2>Author</h2><p>
+ Peter Mount <code class="email">&lt;<a class="email" href="mailto:peter@retep.org.uk">peter@retep.org.uk</a>&gt;</code>
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="oid2name.html" title="oid2name">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib-prog-client.html" title="G.1. Client Applications">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-prog-server.html" title="G.2. Server Applications">Next</a></td></tr><tr><td width="40%" align="left" valign="top">oid2name </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> G.2. Server Applications</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-available-extension-versions.html b/doc/src/sgml/html/view-pg-available-extension-versions.html
new file mode 100644
index 0000000..62f2e58
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-available-extension-versions.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.3. pg_available_extension_versions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions" /><link rel="next" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.3. <code class="structname">pg_available_extension_versions</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-AVAILABLE-EXTENSION-VERSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.3. <code class="structname">pg_available_extension_versions</code></h2></div></div></div><a id="id-1.10.5.7.2" class="indexterm"></a><p>
+ The <code class="structname">pg_available_extension_versions</code> view lists the
+ specific extension versions that are available for installation.
+ See also the <a class="link" href="catalog-pg-extension.html" title="53.22. pg_extension"><code class="structname">pg_extension</code></a>
+ catalog, which shows the extensions currently installed.
+ </p><div class="table" id="id-1.10.5.7.4"><p class="title"><strong>Table 54.3. <code class="structname">pg_available_extension_versions</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_available_extension_versions Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">name</code>
+ </p>
+ <p>
+ Extension name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">version</code> <code class="type">text</code>
+ </p>
+ <p>
+ Version name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">installed</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this version of this extension is currently
+ installed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">superuser</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if only superusers are allowed to install this extension
+ (but see <code class="structfield">trusted</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">trusted</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the extension can be installed by non-superusers
+ with appropriate privileges
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relocatable</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if extension can be relocated to another schema
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schema</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the schema that the extension must be installed into,
+ or <code class="literal">NULL</code> if partially or fully relocatable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">requires</code> <code class="type">name[]</code>
+ </p>
+ <p>
+ Names of prerequisite extensions,
+ or <code class="literal">NULL</code> if none
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">comment</code> <code class="type">text</code>
+ </p>
+ <p>
+ Comment string from the extension's control file
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="structname">pg_available_extension_versions</code> view is
+ read-only.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.2. <code class="structname">pg_available_extensions</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.4. <code class="structname">pg_backend_memory_contexts</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-available-extensions.html b/doc/src/sgml/html/view-pg-available-extensions.html
new file mode 100644
index 0000000..7f690d3
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-available-extensions.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.2. pg_available_extensions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="views-overview.html" title="54.1. Overview" /><link rel="next" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.2. <code class="structname">pg_available_extensions</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="views-overview.html" title="54.1. Overview">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-AVAILABLE-EXTENSIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.2. <code class="structname">pg_available_extensions</code></h2></div></div></div><a id="id-1.10.5.6.2" class="indexterm"></a><p>
+ The <code class="structname">pg_available_extensions</code> view lists the
+ extensions that are available for installation.
+ See also the
+ <a class="link" href="catalog-pg-extension.html" title="53.22. pg_extension"><code class="structname">pg_extension</code></a>
+ catalog, which shows the extensions currently installed.
+ </p><div class="table" id="id-1.10.5.6.4"><p class="title"><strong>Table 54.2. <code class="structname">pg_available_extensions</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_available_extensions Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">name</code>
+ </p>
+ <p>
+ Extension name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">default_version</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of default version, or <code class="literal">NULL</code> if none is
+ specified
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">installed_version</code> <code class="type">text</code>
+ </p>
+ <p>
+ Currently installed version of the extension,
+ or <code class="literal">NULL</code> if not installed
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">comment</code> <code class="type">text</code>
+ </p>
+ <p>
+ Comment string from the extension's control file
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="structname">pg_available_extensions</code> view is read-only.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="views-overview.html" title="54.1. Overview">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.1. Overview </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.3. <code class="structname">pg_available_extension_versions</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-backend-memory-contexts.html b/doc/src/sgml/html/view-pg-backend-memory-contexts.html
new file mode 100644
index 0000000..3efa6ec
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-backend-memory-contexts.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.4. pg_backend_memory_contexts</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions" /><link rel="next" href="view-pg-config.html" title="54.5. pg_config" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.4. <code class="structname">pg_backend_memory_contexts</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-config.html" title="54.5. pg_config">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-BACKEND-MEMORY-CONTEXTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.4. <code class="structname">pg_backend_memory_contexts</code></h2></div></div></div><a id="id-1.10.5.8.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_backend_memory_contexts</code> displays all
+ the memory contexts of the server process attached to the current session.
+ </p><p>
+ <code class="structname">pg_backend_memory_contexts</code> contains one row
+ for each memory context.
+ </p><div class="table" id="id-1.10.5.8.5"><p class="title"><strong>Table 54.4. <code class="structname">pg_backend_memory_contexts</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_backend_memory_contexts Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the memory context
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ident</code> <code class="type">text</code>
+ </p>
+ <p>
+ Identification information of the memory context. This field is truncated at 1024 bytes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parent</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the parent of this memory context
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">level</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Distance from TopMemoryContext in context tree
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_bytes</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Total bytes allocated for this memory context
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">total_nblocks</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Total number of blocks allocated for this memory context
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">free_bytes</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Free space in bytes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">free_chunks</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Total number of free chunks
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">used_bytes</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Used space in bytes
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ By default, the <code class="structname">pg_backend_memory_contexts</code> view can be
+ read only by superusers or roles with the privileges of the
+ <code class="literal">pg_read_all_stats</code> role.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-config.html" title="54.5. pg_config">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.3. <code class="structname">pg_available_extension_versions</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.5. <code class="structname">pg_config</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-config.html b/doc/src/sgml/html/view-pg-config.html
new file mode 100644
index 0000000..2c93ffa
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-config.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.5. pg_config</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts" /><link rel="next" href="view-pg-cursors.html" title="54.6. pg_cursors" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.5. <code class="structname">pg_config</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-cursors.html" title="54.6. pg_cursors">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-CONFIG"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.5. <code class="structname">pg_config</code></h2></div></div></div><a id="id-1.10.5.9.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_config</code> describes the
+ compile-time configuration parameters of the currently installed
+ version of <span class="productname">PostgreSQL</span>. It is intended, for example, to
+ be used by software packages that want to interface to
+ <span class="productname">PostgreSQL</span> to facilitate finding the required header
+ files and libraries. It provides the same basic information as the
+ <a class="xref" href="app-pgconfig.html" title="pg_config"><span class="refentrytitle"><span class="application">pg_config</span></span></a> <span class="productname">PostgreSQL</span> client
+ application.
+ </p><p>
+ By default, the <code class="structname">pg_config</code> view can be read
+ only by superusers.
+ </p><div class="table" id="id-1.10.5.9.5"><p class="title"><strong>Table 54.5. <code class="structname">pg_config</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_config Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ The parameter name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">setting</code> <code class="type">text</code>
+ </p>
+ <p>
+ The parameter value
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-cursors.html" title="54.6. pg_cursors">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.4. <code class="structname">pg_backend_memory_contexts</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.6. <code class="structname">pg_cursors</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-cursors.html b/doc/src/sgml/html/view-pg-cursors.html
new file mode 100644
index 0000000..56e70b1
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-cursors.html
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.6. pg_cursors</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-config.html" title="54.5. pg_config" /><link rel="next" href="view-pg-file-settings.html" title="54.7. pg_file_settings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.6. <code class="structname">pg_cursors</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-config.html" title="54.5. pg_config">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-file-settings.html" title="54.7. pg_file_settings">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-CURSORS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.6. <code class="structname">pg_cursors</code></h2></div></div></div><a id="id-1.10.5.10.2" class="indexterm"></a><p>
+ The <code class="structname">pg_cursors</code> view lists the cursors that
+ are currently available. Cursors can be defined in several ways:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ via the <a class="link" href="sql-declare.html" title="DECLARE"><code class="command">DECLARE</code></a>
+ statement in SQL
+ </p></li><li class="listitem"><p>
+ via the Bind message in the frontend/backend protocol, as
+ described in <a class="xref" href="protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY" title="55.2.3. Extended Query">Section 55.2.3</a>
+ </p></li><li class="listitem"><p>
+ via the Server Programming Interface (SPI), as described in
+ <a class="xref" href="spi-interface.html" title="47.1. Interface Functions">Section 47.1</a>
+ </p></li></ul></div><p>
+
+ The <code class="structname">pg_cursors</code> view displays cursors
+ created by any of these means. Cursors only exist for the duration
+ of the transaction that defines them, unless they have been
+ declared <code class="literal">WITH HOLD</code>. Therefore non-holdable
+ cursors are only present in the view until the end of their
+ creating transaction.
+
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Cursors are used internally to implement some of the components
+ of <span class="productname">PostgreSQL</span>, such as procedural languages.
+ Therefore, the <code class="structname">pg_cursors</code> view might include cursors
+ that have not been explicitly created by the user.
+ </p></div><p>
+ </p><div class="table" id="id-1.10.5.10.4"><p class="title"><strong>Table 54.6. <code class="structname">pg_cursors</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_cursors Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ The name of the cursor
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statement</code> <code class="type">text</code>
+ </p>
+ <p>
+ The verbatim query string submitted to declare this cursor
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_holdable</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="literal">true</code> if the cursor is holdable (that is, it
+ can be accessed after the transaction that declared the cursor
+ has committed); <code class="literal">false</code> otherwise
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_binary</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="literal">true</code> if the cursor was declared
+ <code class="literal">BINARY</code>; <code class="literal">false</code>
+ otherwise
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_scrollable</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="literal">true</code> if the cursor is scrollable (that is, it
+ allows rows to be retrieved in a nonsequential manner);
+ <code class="literal">false</code> otherwise
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">creation_time</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ The time at which the cursor was declared
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="structname">pg_cursors</code> view is read-only.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-config.html" title="54.5. pg_config">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-file-settings.html" title="54.7. pg_file_settings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.5. <code class="structname">pg_config</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.7. <code class="structname">pg_file_settings</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-file-settings.html b/doc/src/sgml/html/view-pg-file-settings.html
new file mode 100644
index 0000000..017a9fb
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-file-settings.html
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.7. pg_file_settings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-cursors.html" title="54.6. pg_cursors" /><link rel="next" href="view-pg-group.html" title="54.8. pg_group" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.7. <code class="structname">pg_file_settings</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-cursors.html" title="54.6. pg_cursors">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-group.html" title="54.8. pg_group">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-FILE-SETTINGS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.7. <code class="structname">pg_file_settings</code></h2></div></div></div><a id="id-1.10.5.11.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_file_settings</code> provides a summary of
+ the contents of the server's configuration file(s). A row appears in
+ this view for each <span class="quote">“<span class="quote">name = value</span>”</span> entry appearing in the files,
+ with annotations indicating whether the value could be applied
+ successfully. Additional row(s) may appear for problems not linked to
+ a <span class="quote">“<span class="quote">name = value</span>”</span> entry, such as syntax errors in the files.
+ </p><p>
+ This view is helpful for checking whether planned changes in the
+ configuration files will work, or for diagnosing a previous failure.
+ Note that this view reports on the <span class="emphasis"><em>current</em></span> contents of the
+ files, not on what was last applied by the server. (The
+ <a class="link" href="view-pg-settings.html" title="54.24. pg_settings"><code class="structname">pg_settings</code></a>
+ view is usually sufficient to determine that.)
+ </p><p>
+ By default, the <code class="structname">pg_file_settings</code> view can be read
+ only by superusers.
+ </p><div class="table" id="id-1.10.5.11.6"><p class="title"><strong>Table 54.7. <code class="structname">pg_file_settings</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_file_settings Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sourcefile</code> <code class="type">text</code>
+ </p>
+ <p>
+ Full path name of the configuration file
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sourceline</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Line number within the configuration file where the entry appears
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">seqno</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Order in which the entries are processed (1..<em class="replaceable"><code>n</code></em>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Configuration parameter name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">setting</code> <code class="type">text</code>
+ </p>
+ <p>
+ Value to be assigned to the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">applied</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the value can be applied successfully
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">error</code> <code class="type">text</code>
+ </p>
+ <p>
+ If not null, an error message indicating why this entry could
+ not be applied
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ If the configuration file contains syntax errors or invalid parameter
+ names, the server will not attempt to apply any settings from it, and
+ therefore all the <code class="structfield">applied</code> fields will read as false.
+ In such a case there will be one or more rows with
+ non-null <code class="structfield">error</code> fields indicating the
+ problem(s). Otherwise, individual settings will be applied if possible.
+ If an individual setting cannot be applied (e.g., invalid value, or the
+ setting cannot be changed after server start) it will have an appropriate
+ message in the <code class="structfield">error</code> field. Another way that
+ an entry might have <code class="structfield">applied</code> = false is that it is
+ overridden by a later entry for the same parameter name; this case is not
+ considered an error so nothing appears in
+ the <code class="structfield">error</code> field.
+ </p><p>
+ See <a class="xref" href="config-setting.html" title="20.1. Setting Parameters">Section 20.1</a> for more information about the various
+ ways to change run-time parameters.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-cursors.html" title="54.6. pg_cursors">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-group.html" title="54.8. pg_group">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.6. <code class="structname">pg_cursors</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.8. <code class="structname">pg_group</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-group.html b/doc/src/sgml/html/view-pg-group.html
new file mode 100644
index 0000000..f3fc92e
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-group.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.8. pg_group</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-file-settings.html" title="54.7. pg_file_settings" /><link rel="next" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.8. <code class="structname">pg_group</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-file-settings.html" title="54.7. pg_file_settings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-GROUP"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.8. <code class="structname">pg_group</code></h2></div></div></div><a id="id-1.10.5.12.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_group</code> exists for backwards
+ compatibility: it emulates a catalog that existed in
+ <span class="productname">PostgreSQL</span> before version 8.1.
+ It shows the names and members of all roles that are marked as not
+ <code class="structfield">rolcanlogin</code>, which is an approximation to the set
+ of roles that are being used as groups.
+ </p><div class="table" id="id-1.10.5.12.4"><p class="title"><strong>Table 54.8. <code class="structname">pg_group</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_group Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">groname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Name of the group
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grosysid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ ID of this group
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">grolist</code> <code class="type">oid[]</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ An array containing the IDs of the roles in this group
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-file-settings.html" title="54.7. pg_file_settings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.7. <code class="structname">pg_file_settings</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.9. <code class="structname">pg_hba_file_rules</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-hba-file-rules.html b/doc/src/sgml/html/view-pg-hba-file-rules.html
new file mode 100644
index 0000000..80df1e4
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-hba-file-rules.html
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.9. pg_hba_file_rules</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-group.html" title="54.8. pg_group" /><link rel="next" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.9. <code class="structname">pg_hba_file_rules</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-group.html" title="54.8. pg_group">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-HBA-FILE-RULES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.9. <code class="structname">pg_hba_file_rules</code></h2></div></div></div><a id="id-1.10.5.13.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_hba_file_rules</code> provides a summary of
+ the contents of the client authentication configuration file,
+ <a class="link" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File"><code class="filename">pg_hba.conf</code></a>.
+ A row appears in this view for each
+ non-empty, non-comment line in the file, with annotations indicating
+ whether the rule could be applied successfully.
+ </p><p>
+ This view can be helpful for checking whether planned changes in the
+ authentication configuration file will work, or for diagnosing a previous
+ failure. Note that this view reports on the <span class="emphasis"><em>current</em></span> contents
+ of the file, not on what was last loaded by the server.
+ </p><p>
+ By default, the <code class="structname">pg_hba_file_rules</code> view can be read
+ only by superusers.
+ </p><div class="table" id="id-1.10.5.13.6"><p class="title"><strong>Table 54.9. <code class="structname">pg_hba_file_rules</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_hba_file_rules Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">line_number</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Line number of this rule in <code class="filename">pg_hba.conf</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">type</code> <code class="type">text</code>
+ </p>
+ <p>
+ Type of connection
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">database</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ List of database name(s) to which this rule applies
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">user_name</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ List of user and group name(s) to which this rule applies
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">address</code> <code class="type">text</code>
+ </p>
+ <p>
+ Host name or IP address, or one
+ of <code class="literal">all</code>, <code class="literal">samehost</code>,
+ or <code class="literal">samenet</code>, or null for local connections
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">netmask</code> <code class="type">text</code>
+ </p>
+ <p>
+ IP address mask, or null if not applicable
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">auth_method</code> <code class="type">text</code>
+ </p>
+ <p>
+ Authentication method
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">options</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Options specified for authentication method, if any
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">error</code> <code class="type">text</code>
+ </p>
+ <p>
+ If not null, an error message indicating why this
+ line could not be processed
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Usually, a row reflecting an incorrect entry will have values for only
+ the <code class="structfield">line_number</code> and <code class="structfield">error</code> fields.
+ </p><p>
+ See <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a> for more information about
+ client authentication configuration.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-group.html" title="54.8. pg_group">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.8. <code class="structname">pg_group</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.10. <code class="structname">pg_ident_file_mappings</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-ident-file-mappings.html b/doc/src/sgml/html/view-pg-ident-file-mappings.html
new file mode 100644
index 0000000..60674ae
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-ident-file-mappings.html
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.10. pg_ident_file_mappings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules" /><link rel="next" href="view-pg-indexes.html" title="54.11. pg_indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.10. <code class="structname">pg_ident_file_mappings</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-indexes.html" title="54.11. pg_indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-IDENT-FILE-MAPPINGS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.10. <code class="structname">pg_ident_file_mappings</code></h2></div></div></div><a id="id-1.10.5.14.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_ident_file_mappings</code> provides a summary
+ of the contents of the client user name mapping configuration file,
+ <a class="link" href="auth-username-maps.html" title="21.2. User Name Maps"><code class="filename">pg_ident.conf</code></a>.
+ A row appears in this view for each non-empty, non-comment line in the file,
+ with annotations indicating whether the map could be applied successfully.
+ </p><p>
+ This view can be helpful for checking whether planned changes in the
+ authentication configuration file will work, or for diagnosing a previous
+ failure. Note that this view reports on the <span class="emphasis"><em>current</em></span>
+ contents of the file, not on what was last loaded by the server.
+ </p><p>
+ By default, the <code class="structname">pg_ident_file_mappings</code> view can be
+ read only by superusers.
+ </p><div class="table" id="id-1.10.5.14.6"><p class="title"><strong>Table 54.10. <code class="structname">pg_ident_file_mappings</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_ident_file_mappings Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">line_number</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Line number of this map in <code class="filename">pg_ident.conf</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">map_name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the map
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sys_name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Detected user name of the client
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pg_username</code> <code class="type">text</code>
+ </p>
+ <p>
+ Requested PostgreSQL user name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">error</code> <code class="type">text</code>
+ </p>
+ <p>
+ If not <code class="literal">NULL</code>, an error message indicating why this
+ line could not be processed
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Usually, a row reflecting an incorrect entry will have values for only
+ the <code class="structfield">line_number</code> and <code class="structfield">error</code> fields.
+ </p><p>
+ See <a class="xref" href="client-authentication.html" title="Chapter 21. Client Authentication">Chapter 21</a> for more information about
+ client authentication configuration.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-indexes.html" title="54.11. pg_indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.9. <code class="structname">pg_hba_file_rules</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.11. <code class="structname">pg_indexes</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-indexes.html b/doc/src/sgml/html/view-pg-indexes.html
new file mode 100644
index 0000000..a93fca7
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-indexes.html
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.11. pg_indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings" /><link rel="next" href="view-pg-locks.html" title="54.12. pg_locks" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.11. <code class="structname">pg_indexes</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-locks.html" title="54.12. pg_locks">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-INDEXES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.11. <code class="structname">pg_indexes</code></h2></div></div></div><a id="id-1.10.5.15.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_indexes</code> provides access to
+ useful information about each index in the database.
+ </p><div class="table" id="id-1.10.5.15.4"><p class="title"><strong>Table 54.11. <code class="structname">pg_indexes</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_indexes Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table and index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table the index is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of index
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablespace</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a>.<code class="structfield">spcname</code>)
+ </p>
+ <p>
+ Name of tablespace containing index (null if default for database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">indexdef</code> <code class="type">text</code>
+ </p>
+ <p>
+ Index definition (a reconstructed <a class="xref" href="sql-createindex.html" title="CREATE INDEX"><span class="refentrytitle">CREATE INDEX</span></a>
+ command)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-locks.html" title="54.12. pg_locks">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.10. <code class="structname">pg_ident_file_mappings</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.12. <code class="structname">pg_locks</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-locks.html b/doc/src/sgml/html/view-pg-locks.html
new file mode 100644
index 0000000..8f5ff43
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-locks.html
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.12. pg_locks</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-indexes.html" title="54.11. pg_indexes" /><link rel="next" href="view-pg-matviews.html" title="54.13. pg_matviews" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.12. <code class="structname">pg_locks</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-indexes.html" title="54.11. pg_indexes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-matviews.html" title="54.13. pg_matviews">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-LOCKS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.12. <code class="structname">pg_locks</code></h2></div></div></div><a id="id-1.10.5.16.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_locks</code> provides access to
+ information about the locks held by active processes within the
+ database server. See <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a> for more discussion
+ of locking.
+ </p><p>
+ <code class="structname">pg_locks</code> contains one row per active lockable
+ object, requested lock mode, and relevant process. Thus, the same
+ lockable object might
+ appear many times, if multiple processes are holding or waiting
+ for locks on it. However, an object that currently has no locks on it
+ will not appear at all.
+ </p><p>
+ There are several distinct types of lockable objects:
+ whole relations (e.g., tables), individual pages of relations,
+ individual tuples of relations,
+ transaction IDs (both virtual and permanent IDs),
+ and general database objects (identified by class OID and object OID,
+ in the same way as in <a class="link" href="catalog-pg-description.html" title="53.19. pg_description"><code class="structname">pg_description</code></a> or
+ <a class="link" href="catalog-pg-depend.html" title="53.18. pg_depend"><code class="structname">pg_depend</code></a>). Also, the right to extend a
+ relation is represented as a separate lockable object, as is the right to
+ update <code class="structname">pg_database</code>.<code class="structfield">datfrozenxid</code>.
+ Also, <span class="quote">“<span class="quote">advisory</span>”</span> locks can be taken on numbers that have
+ user-defined meanings.
+ </p><div class="table" id="id-1.10.5.16.6"><p class="title"><strong>Table 54.12. <code class="structname">pg_locks</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_locks Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">locktype</code> <code class="type">text</code>
+ </p>
+ <p>
+ Type of the lockable object:
+ <code class="literal">relation</code>,
+ <code class="literal">extend</code>,
+ <code class="literal">frozenid</code>,
+ <code class="literal">page</code>,
+ <code class="literal">tuple</code>,
+ <code class="literal">transactionid</code>,
+ <code class="literal">virtualxid</code>,
+ <code class="literal">spectoken</code>,
+ <code class="literal">object</code>,
+ <code class="literal">userlock</code>, or
+ <code class="literal">advisory</code>.
+ (See also <a class="xref" href="monitoring-stats.html#WAIT-EVENT-LOCK-TABLE" title="Table 28.11. Wait Events of Type Lock">Table 28.11</a>.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">database</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the database in which the lock target exists, or
+ zero if the target is a shared object, or
+ null if the target is a transaction ID
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">relation</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the relation targeted by the lock, or null if the target is not
+ a relation or part of a relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">page</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Page number targeted by the lock within the relation,
+ or null if the target is not a relation page or tuple
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tuple</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Tuple number targeted by the lock within the page,
+ or null if the target is not a tuple
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">virtualxid</code> <code class="type">text</code>
+ </p>
+ <p>
+ Virtual ID of the transaction targeted by the lock,
+ or null if the target is not a virtual transaction ID
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">transactionid</code> <code class="type">xid</code>
+ </p>
+ <p>
+ ID of the transaction targeted by the lock,
+ or null if the target is not a transaction ID
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the system catalog containing the lock target, or null if the
+ target is not a general database object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ OID of the lock target within its system catalog, or null if the
+ target is not a general database object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int2</code>
+ </p>
+ <p>
+ Column number targeted by the lock (the
+ <code class="structfield">classid</code> and <code class="structfield">objid</code> refer to the
+ table itself),
+ or zero if the target is some other general database object,
+ or null if the target is not a general database object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">virtualtransaction</code> <code class="type">text</code>
+ </p>
+ <p>
+ Virtual ID of the transaction that is holding or awaiting this lock
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Process ID of the server process holding or awaiting this
+ lock, or null if the lock is held by a prepared transaction
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">mode</code> <code class="type">text</code>
+ </p>
+ <p>
+ Name of the lock mode held or desired by this process (see <a class="xref" href="explicit-locking.html#LOCKING-TABLES" title="13.3.1. Table-Level Locks">Section 13.3.1</a> and <a class="xref" href="transaction-iso.html#XACT-SERIALIZABLE" title="13.2.3. Serializable Isolation Level">Section 13.2.3</a>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">granted</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if lock is held, false if lock is awaited
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">fastpath</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if lock was taken via fast path, false if taken via main
+ lock table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">waitstart</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ Time when the server process started waiting for this lock,
+ or null if the lock is held.
+ Note that this can be null for a very short period of time after
+ the wait started even though <code class="structfield">granted</code>
+ is <code class="literal">false</code>.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ <code class="structfield">granted</code> is true in a row representing a lock
+ held by the indicated process. False indicates that this process is
+ currently waiting to acquire this lock, which implies that at least one
+ other process is holding or waiting for a conflicting lock mode on the same
+ lockable object. The waiting process will sleep until the other lock is
+ released (or a deadlock situation is detected). A single process can be
+ waiting to acquire at most one lock at a time.
+ </p><p>
+ Throughout running a transaction, a server process holds an exclusive lock
+ on the transaction's virtual transaction ID. If a permanent ID is assigned
+ to the transaction (which normally happens only if the transaction changes
+ the state of the database), it also holds an exclusive lock on the
+ transaction's permanent transaction ID until it ends. When a process finds
+ it necessary to wait specifically for another transaction to end, it does
+ so by attempting to acquire share lock on the other transaction's ID
+ (either virtual or permanent ID depending on the situation). That will
+ succeed only when the other transaction terminates and releases its locks.
+ </p><p>
+ Although tuples are a lockable type of object,
+ information about row-level locks is stored on disk, not in memory,
+ and therefore row-level locks normally do not appear in this view.
+ If a process is waiting for a
+ row-level lock, it will usually appear in the view as waiting for the
+ permanent transaction ID of the current holder of that row lock.
+ </p><p>
+ Advisory locks can be acquired on keys consisting of either a single
+ <code class="type">bigint</code> value or two integer values.
+ A <code class="type">bigint</code> key is displayed with its
+ high-order half in the <code class="structfield">classid</code> column, its low-order half
+ in the <code class="structfield">objid</code> column, and <code class="structfield">objsubid</code> equal
+ to 1. The original <code class="type">bigint</code> value can be reassembled with the
+ expression <code class="literal">(classid::bigint &lt;&lt; 32) |
+ objid::bigint</code>. Integer keys are displayed with the
+ first key in the
+ <code class="structfield">classid</code> column, the second key in the <code class="structfield">objid</code>
+ column, and <code class="structfield">objsubid</code> equal to 2. The actual meaning of
+ the keys is up to the user. Advisory locks are local to each database,
+ so the <code class="structfield">database</code> column is meaningful for an advisory lock.
+ </p><p>
+ <code class="structname">pg_locks</code> provides a global view of all locks
+ in the database cluster, not only those relevant to the current database.
+ Although its <code class="structfield">relation</code> column can be joined
+ against <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code> to identify locked
+ relations, this will only work correctly for relations in the current
+ database (those for which the <code class="structfield">database</code> column
+ is either the current database's OID or zero).
+ </p><p>
+ The <code class="structfield">pid</code> column can be joined to the
+ <code class="structfield">pid</code> column of the
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW" title="28.2.3. pg_stat_activity">
+ <code class="structname">pg_stat_activity</code></a>
+ view to get more
+ information on the session holding or awaiting each lock,
+ for example
+</p><pre class="programlisting">
+SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa
+ ON pl.pid = psa.pid;
+</pre><p>
+ Also, if you are using prepared transactions, the
+ <code class="structfield">virtualtransaction</code> column can be joined to the
+ <code class="structfield">transaction</code> column of the <a class="link" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts"><code class="structname">pg_prepared_xacts</code></a>
+ view to get more information on prepared transactions that hold locks.
+ (A prepared transaction can never be waiting for a lock,
+ but it continues to hold the locks it acquired while running.)
+ For example:
+</p><pre class="programlisting">
+SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
+ ON pl.virtualtransaction = '-1/' || ppx.transaction;
+</pre><p>
+ </p><p>
+ While it is possible to obtain information about which processes block
+ which other processes by joining <code class="structname">pg_locks</code> against
+ itself, this is very difficult to get right in detail. Such a query would
+ have to encode knowledge about which lock modes conflict with which
+ others. Worse, the <code class="structname">pg_locks</code> view does not expose
+ information about which processes are ahead of which others in lock wait
+ queues, nor information about which processes are parallel workers running
+ on behalf of which other client sessions. It is better to use
+ the <code class="function">pg_blocking_pids()</code> function
+ (see <a class="xref" href="functions-info.html#FUNCTIONS-INFO-SESSION-TABLE" title="Table 9.66. Session Information Functions">Table 9.66</a>) to identify which
+ process(es) a waiting process is blocked behind.
+ </p><p>
+ The <code class="structname">pg_locks</code> view displays data from both the
+ regular lock manager and the predicate lock manager, which are
+ separate systems; in addition, the regular lock manager subdivides its
+ locks into regular and <em class="firstterm">fast-path</em> locks.
+ This data is not guaranteed to be entirely consistent.
+ When the view is queried,
+ data on fast-path locks (with <code class="structfield">fastpath</code> = <code class="literal">true</code>)
+ is gathered from each backend one at a time, without freezing the state of
+ the entire lock manager, so it is possible for locks to be taken or
+ released while information is gathered. Note, however, that these locks are
+ known not to conflict with any other lock currently in place. After
+ all backends have been queried for fast-path locks, the remainder of the
+ regular lock manager is locked as a unit, and a consistent snapshot of all
+ remaining locks is collected as an atomic action. After unlocking the
+ regular lock manager, the predicate lock manager is similarly locked and all
+ predicate locks are collected as an atomic action. Thus, with the exception
+ of fast-path locks, each lock manager will deliver a consistent set of
+ results, but as we do not lock both lock managers simultaneously, it is
+ possible for locks to be taken or released after we interrogate the regular
+ lock manager and before we interrogate the predicate lock manager.
+ </p><p>
+ Locking the regular and/or predicate lock manager could have some
+ impact on database performance if this view is very frequently accessed.
+ The locks are held only for the minimum amount of time necessary to
+ obtain data from the lock managers, but this does not completely eliminate
+ the possibility of a performance impact.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-indexes.html" title="54.11. pg_indexes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-matviews.html" title="54.13. pg_matviews">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.11. <code class="structname">pg_indexes</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.13. <code class="structname">pg_matviews</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-matviews.html b/doc/src/sgml/html/view-pg-matviews.html
new file mode 100644
index 0000000..210f543
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-matviews.html
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.13. pg_matviews</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-locks.html" title="54.12. pg_locks" /><link rel="next" href="view-pg-policies.html" title="54.14. pg_policies" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.13. <code class="structname">pg_matviews</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-locks.html" title="54.12. pg_locks">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-policies.html" title="54.14. pg_policies">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-MATVIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.13. <code class="structname">pg_matviews</code></h2></div></div></div><a id="id-1.10.5.17.2" class="indexterm"></a><a id="id-1.10.5.17.3" class="indexterm"></a><p>
+ The view <code class="structname">pg_matviews</code> provides access to
+ useful information about each materialized view in the database.
+ </p><div class="table" id="id-1.10.5.17.5"><p class="title"><strong>Table 54.13. <code class="structname">pg_matviews</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_matviews Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing materialized view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">matviewname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of materialized view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">matviewowner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Name of materialized view's owner
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablespace</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a>.<code class="structfield">spcname</code>)
+ </p>
+ <p>
+ Name of tablespace containing materialized view (null if default for database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">hasindexes</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if materialized view has (or recently had) any indexes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">ispopulated</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if materialized view is currently populated
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">definition</code> <code class="type">text</code>
+ </p>
+ <p>
+ Materialized view definition (a reconstructed <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> query)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-locks.html" title="54.12. pg_locks">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-policies.html" title="54.14. pg_policies">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.12. <code class="structname">pg_locks</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.14. <code class="structname">pg_policies</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-policies.html b/doc/src/sgml/html/view-pg-policies.html
new file mode 100644
index 0000000..89c0d65
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-policies.html
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.14. pg_policies</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-matviews.html" title="54.13. pg_matviews" /><link rel="next" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.14. <code class="structname">pg_policies</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-matviews.html" title="54.13. pg_matviews">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-POLICIES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.14. <code class="structname">pg_policies</code></h2></div></div></div><a id="id-1.10.5.18.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_policies</code> provides access to
+ useful information about each row-level security policy in the database.
+ </p><div class="table" id="id-1.10.5.18.4"><p class="title"><strong>Table 54.14. <code class="structname">pg_policies</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_policies Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table policy is on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table policy is on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">policyname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-policy.html" title="53.38. pg_policy"><code class="structname">pg_policy</code></a>.<code class="structfield">polname</code>)
+ </p>
+ <p>
+ Name of policy
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">permissive</code> <code class="type">text</code>
+ </p>
+ <p>
+ Is the policy permissive or restrictive?
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">roles</code> <code class="type">name[]</code>
+ </p>
+ <p>
+ The roles to which this policy applies
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cmd</code> <code class="type">text</code>
+ </p>
+ <p>
+ The command type to which the policy is applied
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">qual</code> <code class="type">text</code>
+ </p>
+ <p>
+ The expression added to the security barrier qualifications for
+ queries that this policy applies to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">with_check</code> <code class="type">text</code>
+ </p>
+ <p>
+ The expression added to the WITH CHECK qualifications for
+ queries that attempt to add rows to this table
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-matviews.html" title="54.13. pg_matviews">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.13. <code class="structname">pg_matviews</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.15. <code class="structname">pg_prepared_statements</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-prepared-statements.html b/doc/src/sgml/html/view-pg-prepared-statements.html
new file mode 100644
index 0000000..3b384b9
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-prepared-statements.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.15. pg_prepared_statements</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-policies.html" title="54.14. pg_policies" /><link rel="next" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.15. <code class="structname">pg_prepared_statements</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-policies.html" title="54.14. pg_policies">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-PREPARED-STATEMENTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.15. <code class="structname">pg_prepared_statements</code></h2></div></div></div><a id="id-1.10.5.19.2" class="indexterm"></a><p>
+ The <code class="structname">pg_prepared_statements</code> view displays
+ all the prepared statements that are available in the current
+ session. See <a class="xref" href="sql-prepare.html" title="PREPARE"><span class="refentrytitle">PREPARE</span></a> for more information about prepared
+ statements.
+ </p><p>
+ <code class="structname">pg_prepared_statements</code> contains one row
+ for each prepared statement. Rows are added to the view when a new
+ prepared statement is created and removed when a prepared statement
+ is released (for example, via the <a class="link" href="sql-deallocate.html" title="DEALLOCATE"><code class="command">DEALLOCATE</code></a> command).
+ </p><div class="table" id="id-1.10.5.19.5"><p class="title"><strong>Table 54.15. <code class="structname">pg_prepared_statements</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_prepared_statements Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ The identifier of the prepared statement
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statement</code> <code class="type">text</code>
+ </p>
+ <p>
+ The query string submitted by the client to create this
+ prepared statement. For prepared statements created via SQL,
+ this is the <code class="command">PREPARE</code> statement submitted by
+ the client. For prepared statements created via the
+ frontend/backend protocol, this is the text of the prepared
+ statement itself.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prepare_time</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ The time at which the prepared statement was created
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">parameter_types</code> <code class="type">regtype[]</code>
+ </p>
+ <p>
+ The expected parameter types for the prepared statement in the
+ form of an array of <code class="type">regtype</code>. The OID corresponding
+ to an element of this array can be obtained by casting the
+ <code class="type">regtype</code> value to <code class="type">oid</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">from_sql</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="literal">true</code> if the prepared statement was created
+ via the <code class="command">PREPARE</code> SQL command;
+ <code class="literal">false</code> if the statement was prepared via the
+ frontend/backend protocol
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">generic_plans</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Number of times generic plan was chosen
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">custom_plans</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Number of times custom plan was chosen
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="structname">pg_prepared_statements</code> view is read-only.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-policies.html" title="54.14. pg_policies">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.14. <code class="structname">pg_policies</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.16. <code class="structname">pg_prepared_xacts</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-prepared-xacts.html b/doc/src/sgml/html/view-pg-prepared-xacts.html
new file mode 100644
index 0000000..17dc9e8
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-prepared-xacts.html
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.16. pg_prepared_xacts</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements" /><link rel="next" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.16. <code class="structname">pg_prepared_xacts</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-PREPARED-XACTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.16. <code class="structname">pg_prepared_xacts</code></h2></div></div></div><a id="id-1.10.5.20.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_prepared_xacts</code> displays
+ information about transactions that are currently prepared for two-phase
+ commit (see <a class="xref" href="sql-prepare-transaction.html" title="PREPARE TRANSACTION"><span class="refentrytitle">PREPARE TRANSACTION</span></a> for details).
+ </p><p>
+ <code class="structname">pg_prepared_xacts</code> contains one row per prepared
+ transaction. An entry is removed when the transaction is committed or
+ rolled back.
+ </p><div class="table" id="id-1.10.5.20.5"><p class="title"><strong>Table 54.16. <code class="structname">pg_prepared_xacts</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_prepared_xacts Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">transaction</code> <code class="type">xid</code>
+ </p>
+ <p>
+ Numeric transaction identifier of the prepared transaction
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">gid</code> <code class="type">text</code>
+ </p>
+ <p>
+ Global transaction identifier that was assigned to the transaction
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">prepared</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ Time at which the transaction was prepared for commit
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">owner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Name of the user that executed the transaction
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">database</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">datname</code>)
+ </p>
+ <p>
+ Name of the database in which the transaction was executed
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ When the <code class="structname">pg_prepared_xacts</code> view is accessed, the
+ internal transaction manager data structures are momentarily locked, and
+ a copy is made for the view to display. This ensures that the
+ view produces a consistent set of results, while not blocking
+ normal operations longer than necessary. Nonetheless
+ there could be some impact on database performance if this view is
+ frequently accessed.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.15. <code class="structname">pg_prepared_statements</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.17. <code class="structname">pg_publication_tables</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-publication-tables.html b/doc/src/sgml/html/view-pg-publication-tables.html
new file mode 100644
index 0000000..09c0439
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-publication-tables.html
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.17. pg_publication_tables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts" /><link rel="next" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.17. <code class="structname">pg_publication_tables</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-PUBLICATION-TABLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.17. <code class="structname">pg_publication_tables</code></h2></div></div></div><a id="id-1.10.5.21.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_publication_tables</code> provides
+ information about the mapping between publications and information of
+ tables they contain. Unlike the underlying catalog
+ <a class="link" href="catalog-pg-publication-rel.html" title="53.42. pg_publication_rel"><code class="structname">pg_publication_rel</code></a>,
+ this view expands publications defined as <code class="literal">FOR ALL TABLES</code>
+ and <code class="literal">FOR TABLES IN SCHEMA</code>, so for such publications
+ there will be a row for each eligible table.
+ </p><div class="table" id="id-1.10.5.21.4"><p class="title"><strong>Table 54.17. <code class="structname">pg_publication_tables</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_publication_tables Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pubname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-publication.html" title="53.40. pg_publication"><code class="structname">pg_publication</code></a>.<code class="structfield">pubname</code>)
+ </p>
+ <p>
+ Name of publication
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attnames</code> <code class="type">name[]</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attname</code>)
+ </p>
+ <p>
+ Names of table columns included in the publication. This contains all
+ the columns of the table when the user didn't specify the column list
+ for the table.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rowfilter</code> <code class="type">text</code>
+ </p>
+ <p>
+ Expression for the table's publication qualifying condition
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.16. <code class="structname">pg_prepared_xacts</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.18. <code class="structname">pg_replication_origin_status</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-replication-origin-status.html b/doc/src/sgml/html/view-pg-replication-origin-status.html
new file mode 100644
index 0000000..714036d
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-replication-origin-status.html
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.18. pg_replication_origin_status</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables" /><link rel="next" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.18. <code class="structname">pg_replication_origin_status</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-REPLICATION-ORIGIN-STATUS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.18. <code class="structname">pg_replication_origin_status</code></h2></div></div></div><a id="id-1.10.5.22.2" class="indexterm"></a><p>
+ The <code class="structname">pg_replication_origin_status</code> view
+ contains information about how far replay for a certain origin has
+ progressed. For more on replication origins
+ see <a class="xref" href="replication-origins.html" title="Chapter 50. Replication Progress Tracking">Chapter 50</a>.
+ </p><div class="table" id="id-1.10.5.22.4"><p class="title"><strong>Table 54.18. <code class="structname">pg_replication_origin_status</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_replication_origin_status Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">local_id</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin"><code class="structname">pg_replication_origin</code></a>.<code class="structfield">roident</code>)
+ </p>
+ <p>
+ internal node identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">external_id</code> <code class="type">text</code>
+ (references <a class="link" href="catalog-pg-replication-origin.html" title="53.44. pg_replication_origin"><code class="structname">pg_replication_origin</code></a>.<code class="structfield">roname</code>)
+ </p>
+ <p>
+ external node identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">remote_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ The origin node's LSN up to which data has been replicated.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">local_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ This node's LSN at which <code class="literal">remote_lsn</code> has
+ been replicated. Used to flush commit records before persisting
+ data to disk when using asynchronous commits.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.17. <code class="structname">pg_publication_tables</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.19. <code class="structname">pg_replication_slots</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-replication-slots.html b/doc/src/sgml/html/view-pg-replication-slots.html
new file mode 100644
index 0000000..633e697
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-replication-slots.html
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.19. pg_replication_slots</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status" /><link rel="next" href="view-pg-roles.html" title="54.20. pg_roles" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.19. <code class="structname">pg_replication_slots</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-roles.html" title="54.20. pg_roles">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-REPLICATION-SLOTS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.19. <code class="structname">pg_replication_slots</code></h2></div></div></div><a id="id-1.10.5.23.2" class="indexterm"></a><p>
+ The <code class="structname">pg_replication_slots</code> view provides a listing
+ of all replication slots that currently exist on the database cluster,
+ along with their current state.
+ </p><p>
+ For more on replication slots,
+ see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a> and <a class="xref" href="logicaldecoding.html" title="Chapter 49. Logical Decoding">Chapter 49</a>.
+ </p><div class="table" id="id-1.10.5.23.5"><p class="title"><strong>Table 54.19. <code class="structname">pg_replication_slots</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_replication_slots Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">slot_name</code> <code class="type">name</code>
+ </p>
+ <p>
+ A unique, cluster-wide identifier for the replication slot
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">plugin</code> <code class="type">name</code>
+ </p>
+ <p>
+ The base name of the shared object containing the output plugin this logical slot is using, or null for physical slots.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">slot_type</code> <code class="type">text</code>
+ </p>
+ <p>
+ The slot type: <code class="literal">physical</code> or <code class="literal">logical</code>
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">datoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the database this slot is associated with, or
+ null. Only logical slots have an associated database.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">database</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-database.html" title="53.15. pg_database"><code class="structname">pg_database</code></a>.<code class="structfield">datname</code>)
+ </p>
+ <p>
+ The name of the database this slot is associated with, or
+ null. Only logical slots have an associated database.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">temporary</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this is a temporary replication slot. Temporary slots are
+ not saved to disk and are automatically dropped on error or when
+ the session has finished.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">active</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this slot is currently actively being used
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">active_pid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ The process ID of the session using this slot if the slot
+ is currently actively being used. <code class="literal">NULL</code> if
+ inactive.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">xmin</code> <code class="type">xid</code>
+ </p>
+ <p>
+ The oldest transaction that this slot needs the database to
+ retain. <code class="literal">VACUUM</code> cannot remove tuples deleted
+ by any later transaction.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">catalog_xmin</code> <code class="type">xid</code>
+ </p>
+ <p>
+ The oldest transaction affecting the system catalogs that this
+ slot needs the database to retain. <code class="literal">VACUUM</code> cannot
+ remove catalog tuples deleted by any later transaction.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">restart_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ The address (<code class="literal">LSN</code>) of oldest WAL which still
+ might be required by the consumer of this slot and thus won't be
+ automatically removed during checkpoints unless this LSN
+ gets behind more than <a class="xref" href="runtime-config-replication.html#GUC-MAX-SLOT-WAL-KEEP-SIZE">max_slot_wal_keep_size</a>
+ from the current LSN. <code class="literal">NULL</code>
+ if the <code class="literal">LSN</code> of this slot has never been reserved.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">confirmed_flush_lsn</code> <code class="type">pg_lsn</code>
+ </p>
+ <p>
+ The address (<code class="literal">LSN</code>) up to which the logical
+ slot's consumer has confirmed receiving data. Data older than this is
+ not available anymore. <code class="literal">NULL</code> for physical slots.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">wal_status</code> <code class="type">text</code>
+ </p>
+ <p>
+ Availability of WAL files claimed by this slot.
+ Possible values are:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><code class="literal">reserved</code> means that the claimed files
+ are within <code class="varname">max_wal_size</code>.</p></li><li class="listitem"><p><code class="literal">extended</code> means
+ that <code class="varname">max_wal_size</code> is exceeded but the files are
+ still retained, either by the replication slot or
+ by <code class="varname">wal_keep_size</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">unreserved</code> means that the slot no longer
+ retains the required WAL files and some of them are to be removed at
+ the next checkpoint. This state can return
+ to <code class="literal">reserved</code> or <code class="literal">extended</code>.
+ </p></li><li class="listitem"><p>
+ <code class="literal">lost</code> means that some required WAL files have
+ been removed and this slot is no longer usable.
+ </p></li></ul></div><p>
+ The last two states are seen only when
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-SLOT-WAL-KEEP-SIZE">max_slot_wal_keep_size</a> is
+ non-negative. If <code class="structfield">restart_lsn</code> is NULL, this
+ field is null.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">safe_wal_size</code> <code class="type">int8</code>
+ </p>
+ <p>
+ The number of bytes that can be written to WAL such that this slot
+ is not in danger of getting in state "lost". It is NULL for lost
+ slots, as well as if <code class="varname">max_slot_wal_keep_size</code>
+ is <code class="literal">-1</code>.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">two_phase</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if the slot is enabled for decoding prepared transactions. Always
+ false for physical slots.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-roles.html" title="54.20. pg_roles">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.18. <code class="structname">pg_replication_origin_status</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.20. <code class="structname">pg_roles</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-roles.html b/doc/src/sgml/html/view-pg-roles.html
new file mode 100644
index 0000000..c466230
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-roles.html
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.20. pg_roles</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots" /><link rel="next" href="view-pg-rules.html" title="54.21. pg_rules" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.20. <code class="structname">pg_roles</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-rules.html" title="54.21. pg_rules">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-ROLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.20. <code class="structname">pg_roles</code></h2></div></div></div><a id="id-1.10.5.24.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_roles</code> provides access to
+ information about database roles. This is simply a publicly
+ readable view of
+ <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>
+ that blanks out the password field.
+ </p><div class="table" id="id-1.10.5.24.4"><p class="title"><strong>Table 54.20. <code class="structname">pg_roles</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_roles Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolname</code> <code class="type">name</code>
+ </p>
+ <p>
+ Role name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolsuper</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role has superuser privileges
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolinherit</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role automatically inherits privileges of roles it is a
+ member of
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolcreaterole</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role can create more roles
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolcreatedb</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role can create databases
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolcanlogin</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role can log in. That is, this role can be given as the initial
+ session authorization identifier
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolreplication</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role is a replication role. A replication role can initiate replication
+ connections and create and drop replication slots.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolconnlimit</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For roles that can log in, this sets maximum number of concurrent
+ connections this role can make. -1 means no limit.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolpassword</code> <code class="type">text</code>
+ </p>
+ <p>
+ Not the password (always reads as <code class="literal">********</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolvaliduntil</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ Password expiry time (only used for password authentication);
+ null if no expiration
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolbypassrls</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Role bypasses every row-level security policy, see
+ <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rolconfig</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Role-specific defaults for run-time configuration variables
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">oid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ ID of role
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-rules.html" title="54.21. pg_rules">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.19. <code class="structname">pg_replication_slots</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.21. <code class="structname">pg_rules</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-rules.html b/doc/src/sgml/html/view-pg-rules.html
new file mode 100644
index 0000000..f544cba
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-rules.html
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.21. pg_rules</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-roles.html" title="54.20. pg_roles" /><link rel="next" href="view-pg-seclabels.html" title="54.22. pg_seclabels" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.21. <code class="structname">pg_rules</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-roles.html" title="54.20. pg_roles">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-seclabels.html" title="54.22. pg_seclabels">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-RULES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.21. <code class="structname">pg_rules</code></h2></div></div></div><a id="id-1.10.5.25.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_rules</code> provides access to
+ useful information about query rewrite rules.
+ </p><div class="table" id="id-1.10.5.25.4"><p class="title"><strong>Table 54.21. <code class="structname">pg_rules</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_rules Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table the rule is for
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rulename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-rewrite.html" title="53.45. pg_rewrite"><code class="structname">pg_rewrite</code></a>.<code class="structfield">rulename</code>)
+ </p>
+ <p>
+ Name of rule
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">definition</code> <code class="type">text</code>
+ </p>
+ <p>
+ Rule definition (a reconstructed creation command)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The <code class="structname">pg_rules</code> view excludes the <code class="literal">ON SELECT</code> rules
+ of views and materialized views; those can be seen in
+ <a class="link" href="view-pg-views.html" title="54.35. pg_views"><code class="structname">pg_views</code></a> and <a class="link" href="view-pg-matviews.html" title="54.13. pg_matviews"><code class="structname">pg_matviews</code></a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-roles.html" title="54.20. pg_roles">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-seclabels.html" title="54.22. pg_seclabels">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.20. <code class="structname">pg_roles</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.22. <code class="structname">pg_seclabels</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-seclabels.html b/doc/src/sgml/html/view-pg-seclabels.html
new file mode 100644
index 0000000..e655937
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-seclabels.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.22. pg_seclabels</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-rules.html" title="54.21. pg_rules" /><link rel="next" href="view-pg-sequences.html" title="54.23. pg_sequences" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.22. <code class="structname">pg_seclabels</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-rules.html" title="54.21. pg_rules">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-sequences.html" title="54.23. pg_sequences">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-SECLABELS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.22. <code class="structname">pg_seclabels</code></h2></div></div></div><a id="id-1.10.5.26.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_seclabels</code> provides information about
+ security labels. It as an easier-to-query version of the
+ <a class="link" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel"><code class="structname">pg_seclabel</code></a> catalog.
+ </p><div class="table" id="id-1.10.5.26.4"><p class="title"><strong>Table 54.22. <code class="structname">pg_seclabels</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_seclabels Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objoid</code> <code class="type">oid</code>
+ (references any OID column)
+ </p>
+ <p>
+ The OID of the object this security label pertains to
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">classoid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the system catalog this object appears in
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objsubid</code> <code class="type">int4</code>
+ </p>
+ <p>
+ For a security label on a table column, this is the column number (the
+ <code class="structfield">objoid</code> and <code class="structfield">classoid</code> refer to
+ the table itself). For all other object types, this column is
+ zero.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objtype</code> <code class="type">text</code>
+ </p>
+ <p>
+ The type of object to which this label applies, as text.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objnamespace</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the namespace for this object, if applicable;
+ otherwise NULL.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">objname</code> <code class="type">text</code>
+ </p>
+ <p>
+ The name of the object to which this label applies, as text.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">provider</code> <code class="type">text</code>
+ (references <a class="link" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel"><code class="structname">pg_seclabel</code></a>.<code class="structfield">provider</code>)
+ </p>
+ <p>
+ The label provider associated with this label.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">label</code> <code class="type">text</code>
+ (references <a class="link" href="catalog-pg-seclabel.html" title="53.46. pg_seclabel"><code class="structname">pg_seclabel</code></a>.<code class="structfield">label</code>)
+ </p>
+ <p>
+ The security label applied to this object.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-rules.html" title="54.21. pg_rules">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-sequences.html" title="54.23. pg_sequences">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.21. <code class="structname">pg_rules</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.23. <code class="structname">pg_sequences</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-sequences.html b/doc/src/sgml/html/view-pg-sequences.html
new file mode 100644
index 0000000..07bba2a
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-sequences.html
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.23. pg_sequences</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-seclabels.html" title="54.22. pg_seclabels" /><link rel="next" href="view-pg-settings.html" title="54.24. pg_settings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.23. <code class="structname">pg_sequences</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-seclabels.html" title="54.22. pg_seclabels">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-settings.html" title="54.24. pg_settings">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-SEQUENCES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.23. <code class="structname">pg_sequences</code></h2></div></div></div><a id="id-1.10.5.27.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_sequences</code> provides access to
+ useful information about each sequence in the database.
+ </p><div class="table" id="id-1.10.5.27.4"><p class="title"><strong>Table 54.23. <code class="structname">pg_sequences</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_sequences Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequencename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sequenceowner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Name of sequence's owner
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">data_type</code> <code class="type">regtype</code>
+ (references <a class="link" href="catalog-pg-type.html" title="53.64. pg_type"><code class="structname">pg_type</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ Data type of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">start_value</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Start value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">min_value</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Minimum value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">max_value</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Maximum value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">increment_by</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Increment value of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cycle</code> <code class="type">bool</code>
+ </p>
+ <p>
+ Whether the sequence cycles
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">cache_size</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Cache size of the sequence
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">last_value</code> <code class="type">int8</code>
+ </p>
+ <p>
+ The last sequence value written to disk. If caching is used,
+ this value can be greater than the last value handed out from the
+ sequence. Null if the sequence has not been read from yet. Also, if
+ the current user does not have <code class="literal">USAGE</code>
+ or <code class="literal">SELECT</code> privilege on the sequence, the value is
+ null.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-seclabels.html" title="54.22. pg_seclabels">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-settings.html" title="54.24. pg_settings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.22. <code class="structname">pg_seclabels</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.24. <code class="structname">pg_settings</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-settings.html b/doc/src/sgml/html/view-pg-settings.html
new file mode 100644
index 0000000..2141b3b
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-settings.html
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.24. pg_settings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-sequences.html" title="54.23. pg_sequences" /><link rel="next" href="view-pg-shadow.html" title="54.25. pg_shadow" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.24. <code class="structname">pg_settings</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-sequences.html" title="54.23. pg_sequences">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-shadow.html" title="54.25. pg_shadow">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-SETTINGS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.24. <code class="structname">pg_settings</code></h2></div></div></div><a id="id-1.10.5.28.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_settings</code> provides access to
+ run-time parameters of the server. It is essentially an alternative
+ interface to the <a class="link" href="sql-show.html" title="SHOW"><code class="command">SHOW</code></a>
+ and <a class="link" href="sql-set.html" title="SET"><code class="command">SET</code></a> commands.
+ It also provides access to some facts about each parameter that are
+ not directly available from <a class="link" href="sql-show.html" title="SHOW"><code class="command">SHOW</code></a>, such as minimum and
+ maximum values.
+ </p><div class="table" id="id-1.10.5.28.4"><p class="title"><strong>Table 54.24. <code class="structname">pg_settings</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_settings Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Run-time configuration parameter name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">setting</code> <code class="type">text</code>
+ </p>
+ <p>
+ Current value of the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">unit</code> <code class="type">text</code>
+ </p>
+ <p>
+ Implicit unit of the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">category</code> <code class="type">text</code>
+ </p>
+ <p>
+ Logical group of the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">short_desc</code> <code class="type">text</code>
+ </p>
+ <p>
+ A brief description of the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">extra_desc</code> <code class="type">text</code>
+ </p>
+ <p>
+ Additional, more detailed, description of the parameter
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">context</code> <code class="type">text</code>
+ </p>
+ <p>
+ Context required to set the parameter's value (see below)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">vartype</code> <code class="type">text</code>
+ </p>
+ <p>
+ Parameter type (<code class="literal">bool</code>, <code class="literal">enum</code>,
+ <code class="literal">integer</code>, <code class="literal">real</code>, or <code class="literal">string</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">source</code> <code class="type">text</code>
+ </p>
+ <p>
+ Source of the current parameter value
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">min_val</code> <code class="type">text</code>
+ </p>
+ <p>
+ Minimum allowed value of the parameter (null for non-numeric
+ values)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">max_val</code> <code class="type">text</code>
+ </p>
+ <p>
+ Maximum allowed value of the parameter (null for non-numeric
+ values)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">enumvals</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Allowed values of an enum parameter (null for non-enum
+ values)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">boot_val</code> <code class="type">text</code>
+ </p>
+ <p>
+ Parameter value assumed at server startup if the parameter is
+ not otherwise set
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">reset_val</code> <code class="type">text</code>
+ </p>
+ <p>
+ Value that <a class="link" href="sql-reset.html" title="RESET"><code class="command">RESET</code></a> would reset the parameter to
+ in the current session
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sourcefile</code> <code class="type">text</code>
+ </p>
+ <p>
+ Configuration file the current value was set in (null for
+ values set from sources other than configuration files, or when
+ examined by a user who neither is a superuser nor has privileges of
+ <code class="literal">pg_read_all_settings</code>); helpful when using
+ <code class="literal">include</code> directives in configuration files
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">sourceline</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Line number within the configuration file the current value was
+ set at (null for values set from sources other than configuration files,
+ or when examined by a user who neither is a superuser nor has privileges of
+ <code class="literal">pg_read_all_settings</code>).
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">pending_restart</code> <code class="type">bool</code>
+ </p>
+ <p>
+ <code class="literal">true</code> if the value has been changed in the
+ configuration file but needs a restart; or <code class="literal">false</code>
+ otherwise.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ There are several possible values of <code class="structfield">context</code>.
+ In order of decreasing difficulty of changing the setting, they are:
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">internal</code></span></dt><dd><p>
+ These settings cannot be changed directly; they reflect internally
+ determined values. Some of them may be adjustable by rebuilding the
+ server with different configuration options, or by changing options
+ supplied to <span class="application">initdb</span>.
+ </p></dd><dt><span class="term"><code class="literal">postmaster</code></span></dt><dd><p>
+ These settings can only be applied when the server starts, so any change
+ requires restarting the server. Values for these settings are typically
+ stored in the <code class="filename">postgresql.conf</code> file, or passed on
+ the command line when starting the server. Of course, settings with any
+ of the lower <code class="structfield">context</code> types can also be
+ set at server start time.
+ </p></dd><dt><span class="term"><code class="literal">sighup</code></span></dt><dd><p>
+ Changes to these settings can be made in
+ <code class="filename">postgresql.conf</code> without restarting the server.
+ Send a <span class="systemitem">SIGHUP</span> signal to the postmaster to
+ cause it to re-read <code class="filename">postgresql.conf</code> and apply
+ the changes. The postmaster will also forward the
+ <span class="systemitem">SIGHUP</span> signal to its child processes so that
+ they all pick up the new value.
+ </p></dd><dt><span class="term"><code class="literal">superuser-backend</code></span></dt><dd><p>
+ Changes to these settings can be made in
+ <code class="filename">postgresql.conf</code> without restarting the server.
+ They can also be set for a particular session in the connection request
+ packet (for example, via <span class="application">libpq</span>'s <code class="literal">PGOPTIONS</code>
+ environment variable), but only if the connecting user is a superuser
+ or has been granted the appropriate <code class="literal">SET</code> privilege.
+ However, these settings never change in a session after it is started.
+ If you change them in <code class="filename">postgresql.conf</code>, send a
+ <span class="systemitem">SIGHUP</span> signal to the postmaster to cause it to
+ re-read <code class="filename">postgresql.conf</code>. The new values will only
+ affect subsequently-launched sessions.
+ </p></dd><dt><span class="term"><code class="literal">backend</code></span></dt><dd><p>
+ Changes to these settings can be made in
+ <code class="filename">postgresql.conf</code> without restarting the server.
+ They can also be set for a particular session in the connection request
+ packet (for example, via <span class="application">libpq</span>'s <code class="literal">PGOPTIONS</code>
+ environment variable); any user can make such a change for their session.
+ However, these settings never change in a session after it is started.
+ If you change them in <code class="filename">postgresql.conf</code>, send a
+ <span class="systemitem">SIGHUP</span> signal to the postmaster to cause it to
+ re-read <code class="filename">postgresql.conf</code>. The new values will only
+ affect subsequently-launched sessions.
+ </p></dd><dt><span class="term"><code class="literal">superuser</code></span></dt><dd><p>
+ These settings can be set from <code class="filename">postgresql.conf</code>,
+ or within a session via the <code class="command">SET</code> command; but only superusers
+ and users with the appropriate <code class="literal">SET</code> privilege
+ can change them via <code class="command">SET</code>. Changes in
+ <code class="filename">postgresql.conf</code> will affect existing sessions
+ only if no session-local value has been established with <code class="command">SET</code>.
+ </p></dd><dt><span class="term"><code class="literal">user</code></span></dt><dd><p>
+ These settings can be set from <code class="filename">postgresql.conf</code>,
+ or within a session via the <code class="command">SET</code> command. Any user is
+ allowed to change their session-local value. Changes in
+ <code class="filename">postgresql.conf</code> will affect existing sessions
+ only if no session-local value has been established with <code class="command">SET</code>.
+ </p></dd></dl></div><p>
+ See <a class="xref" href="config-setting.html" title="20.1. Setting Parameters">Section 20.1</a> for more information about the various
+ ways to change these parameters.
+ </p><p>
+ This view cannot be inserted into or deleted from, but it can be updated. An
+ <code class="command">UPDATE</code> applied to a row of <code class="structname">pg_settings</code>
+ is equivalent to executing the <code class="command">SET</code> command on that named
+ parameter. The change only affects the value used by the current
+ session. If an <code class="command">UPDATE</code> is issued within a transaction
+ that is later aborted, the effects of the <code class="command">UPDATE</code> command
+ disappear when the transaction is rolled back. Once the surrounding
+ transaction is committed, the effects will persist until the end of the
+ session, unless overridden by another <code class="command">UPDATE</code> or
+ <code class="command">SET</code>.
+ </p><p>
+ This view does not
+ display <a class="link" href="runtime-config-custom.html" title="20.16. Customized Options">customized options</a>
+ unless the extension module that defines them has been loaded by the
+ backend process executing the query (e.g., via a mention in
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a>,
+ a call to a C function in the extension, or the
+ <a class="link" href="sql-load.html" title="LOAD"><code class="command">LOAD</code></a> command).
+ For example, since <a class="link" href="archive-modules.html" title="Chapter 51. Archive Modules">archive modules</a>
+ are normally loaded only by the archiver process not regular sessions,
+ this view will not display any customized options defined by such modules
+ unless special action is taken to load them into the backend process
+ executing the query.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-sequences.html" title="54.23. pg_sequences">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-shadow.html" title="54.25. pg_shadow">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.23. <code class="structname">pg_sequences</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.25. <code class="structname">pg_shadow</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-shadow.html b/doc/src/sgml/html/view-pg-shadow.html
new file mode 100644
index 0000000..28fe479
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-shadow.html
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.25. pg_shadow</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-settings.html" title="54.24. pg_settings" /><link rel="next" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.25. <code class="structname">pg_shadow</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-settings.html" title="54.24. pg_settings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-SHADOW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.25. <code class="structname">pg_shadow</code></h2></div></div></div><a id="id-1.10.5.29.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_shadow</code> exists for backwards
+ compatibility: it emulates a catalog that existed in
+ <span class="productname">PostgreSQL</span> before version 8.1.
+ It shows properties of all roles that are marked as
+ <code class="structfield">rolcanlogin</code> in
+ <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.
+ </p><p>
+ The name stems from the fact that this table
+ should not be readable by the public since it contains passwords.
+ <a class="link" href="view-pg-user.html" title="54.33. pg_user"><code class="structname">pg_user</code></a>
+ is a publicly readable view on
+ <code class="structname">pg_shadow</code> that blanks out the password field.
+ </p><div class="table" id="id-1.10.5.29.5"><p class="title"><strong>Table 54.25. <code class="structname">pg_shadow</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_shadow Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ User name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usesysid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ ID of this user
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usecreatedb</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User can create databases
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usesuper</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User is a superuser
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">userepl</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User can initiate streaming replication and put the system in and
+ out of backup mode.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usebypassrls</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User bypasses every row-level security policy, see
+ <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">passwd</code> <code class="type">text</code>
+ </p>
+ <p>
+ Password (possibly encrypted); null if none. See
+ <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>
+ for details of how encrypted passwords are stored.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">valuntil</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ Password expiry time (only used for password authentication)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">useconfig</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Session defaults for run-time configuration variables
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-settings.html" title="54.24. pg_settings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.24. <code class="structname">pg_settings</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.26. <code class="structname">pg_shmem_allocations</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-shmem-allocations.html b/doc/src/sgml/html/view-pg-shmem-allocations.html
new file mode 100644
index 0000000..4e040e4
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-shmem-allocations.html
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.26. pg_shmem_allocations</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-shadow.html" title="54.25. pg_shadow" /><link rel="next" href="view-pg-stats.html" title="54.27. pg_stats" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.26. <code class="structname">pg_shmem_allocations</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-shadow.html" title="54.25. pg_shadow">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-stats.html" title="54.27. pg_stats">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-SHMEM-ALLOCATIONS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.26. <code class="structname">pg_shmem_allocations</code></h2></div></div></div><a id="id-1.10.5.30.2" class="indexterm"></a><p>
+ The <code class="structname">pg_shmem_allocations</code> view shows allocations
+ made from the server's main shared memory segment. This includes both
+ memory allocated by <span class="productname">PostgreSQL</span> itself and memory
+ allocated by extensions using the mechanisms detailed in
+ <a class="xref" href="xfunc-c.html#XFUNC-SHARED-ADDIN" title="38.10.10. Shared Memory and LWLocks">Section 38.10.10</a>.
+ </p><p>
+ Note that this view does not include memory allocated using the dynamic
+ shared memory infrastructure.
+ </p><div class="table" id="id-1.10.5.30.5"><p class="title"><strong>Table 54.26. <code class="structname">pg_shmem_allocations</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_shmem_allocations Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ The name of the shared memory allocation. NULL for unused memory
+ and <code class="literal">&lt;anonymous&gt;</code> for anonymous
+ allocations.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">off</code> <code class="type">int8</code>
+ </p>
+ <p>
+ The offset at which the allocation starts. NULL for anonymous
+ allocations, since details related to them are not known.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">size</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Size of the allocation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">allocated_size</code> <code class="type">int8</code>
+ </p>
+ <p>
+ Size of the allocation including padding. For anonymous
+ allocations, no information about padding is available, so the
+ <code class="literal">size</code> and <code class="literal">allocated_size</code> columns
+ will always be equal. Padding is not meaningful for free memory, so
+ the columns will be equal in that case also.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Anonymous allocations are allocations that have been made
+ with <code class="literal">ShmemAlloc()</code> directly, rather than via
+ <code class="literal">ShmemInitStruct()</code> or
+ <code class="literal">ShmemInitHash()</code>.
+ </p><p>
+ By default, the <code class="structname">pg_shmem_allocations</code> view can be
+ read only by superusers or roles with privileges of the
+ <code class="literal">pg_read_all_stats</code> role.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-shadow.html" title="54.25. pg_shadow">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-stats.html" title="54.27. pg_stats">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.25. <code class="structname">pg_shadow</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.27. <code class="structname">pg_stats</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-stats-ext-exprs.html b/doc/src/sgml/html/view-pg-stats-ext-exprs.html
new file mode 100644
index 0000000..1adf34a
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-stats-ext-exprs.html
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.29. pg_stats_ext_exprs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext" /><link rel="next" href="view-pg-tables.html" title="54.30. pg_tables" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.29. <code class="structname">pg_stats_ext_exprs</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-tables.html" title="54.30. pg_tables">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-STATS-EXT-EXPRS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.29. <code class="structname">pg_stats_ext_exprs</code></h2></div></div></div><a id="id-1.10.5.33.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_stats_ext_exprs</code> provides access to
+ information about all expressions included in extended statistics objects,
+ combining information stored in the <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>
+ and <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>
+ catalogs. This view allows access only to rows of
+ <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a> and <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>
+ that correspond to tables the user has permission to read, and therefore
+ it is safe to allow public read access to this view.
+ </p><p>
+ <code class="structname">pg_stats_ext_exprs</code> is also designed to present
+ the information in a more readable format than the underlying catalogs
+ — at the cost that its schema must be extended whenever the structure
+ of statistics in <code class="structname">pg_statistic_ext</code> changes.
+ </p><div class="table" id="id-1.10.5.33.5"><p class="title"><strong>Table 54.29. <code class="structname">pg_stats_ext_exprs</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_stats_ext_exprs Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table the statistics object is defined on
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statistics_schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statistics_name</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>.<code class="structfield">stxname</code>)
+ </p>
+ <p>
+ Name of extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statistics_owner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Owner of the extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">expr</code> <code class="type">text</code>
+ </p>
+ <p>
+ Expression included in the extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inherited</code> <code class="type">bool</code>
+ (references <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>.<code class="structfield">stxdinherit</code>)
+ </p>
+ <p>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">null_frac</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Fraction of expression entries that are null
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">avg_width</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Average width in bytes of expression's entries
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_distinct</code> <code class="type">float4</code>
+ </p>
+ <p>
+ If greater than zero, the estimated number of distinct values in the
+ expression. If less than zero, the negative of the number of distinct
+ values divided by the number of rows. (The negated form is used when
+ <code class="command">ANALYZE</code> believes that the number of distinct values is
+ likely to increase as the table grows; the positive form is used when
+ the expression seems to have a fixed number of possible values.) For
+ example, -1 indicates a unique expression in which the number of distinct
+ values is the same as the number of rows.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_vals</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ A list of the most common values in the expression. (Null if
+ no values seem to be more common than any others.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_freqs</code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ A list of the frequencies of the most common values,
+ i.e., number of occurrences of each divided by total number of rows.
+ (Null when <code class="structfield">most_common_vals</code> is.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">histogram_bounds</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ A list of values that divide the expression's values into groups of
+ approximately equal population. The values in
+ <code class="structfield">most_common_vals</code>, if present, are omitted from this
+ histogram calculation. (This expression is null if the expression data type
+ does not have a <code class="literal">&lt;</code> operator or if the
+ <code class="structfield">most_common_vals</code> list accounts for the entire
+ population.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">correlation</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Statistical correlation between physical row ordering and
+ logical ordering of the expression values. This ranges from -1 to +1.
+ When the value is near -1 or +1, an index scan on the expression will
+ be estimated to be cheaper than when it is near zero, due to reduction
+ of random access to the disk. (This expression is null if the expression's
+ data type does not have a <code class="literal">&lt;</code> operator.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_elems</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ A list of non-null element values most often appearing within values of
+ the expression. (Null for scalar types.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_elem_freqs</code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ A list of the frequencies of the most common element values, i.e., the
+ fraction of rows containing at least one instance of the given value.
+ Two or three additional values follow the per-element frequencies;
+ these are the minimum and maximum of the preceding per-element
+ frequencies, and optionally the frequency of null elements.
+ (Null when <code class="structfield">most_common_elems</code> is.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">elem_count_histogram</code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ A histogram of the counts of distinct non-null element values within the
+ values of the expression, followed by the average number of distinct
+ non-null elements. (Null for scalar types.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The maximum number of entries in the array fields can be controlled on a
+ column-by-column basis using the <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER
+ TABLE SET STATISTICS</code></a> command, or globally by setting the
+ <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> run-time parameter.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-tables.html" title="54.30. pg_tables">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.28. <code class="structname">pg_stats_ext</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.30. <code class="structname">pg_tables</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-stats-ext.html b/doc/src/sgml/html/view-pg-stats-ext.html
new file mode 100644
index 0000000..d5327f4
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-stats-ext.html
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.28. pg_stats_ext</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-stats.html" title="54.27. pg_stats" /><link rel="next" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.28. <code class="structname">pg_stats_ext</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-stats.html" title="54.27. pg_stats">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-STATS-EXT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.28. <code class="structname">pg_stats_ext</code></h2></div></div></div><a id="id-1.10.5.32.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_stats_ext</code> provides access to
+ information about each extended statistics object in the database,
+ combining information stored in the <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>
+ and <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>
+ catalogs. This view allows access only to rows of
+ <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a> and <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>
+ that correspond to tables the user has permission to read, and therefore
+ it is safe to allow public read access to this view.
+ </p><p>
+ <code class="structname">pg_stats_ext</code> is also designed to present the
+ information in a more readable format than the underlying catalogs
+ — at the cost that its schema must be extended whenever new types
+ of extended statistics are added to <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>.
+ </p><div class="table" id="id-1.10.5.32.5"><p class="title"><strong>Table 54.28. <code class="structname">pg_stats_ext</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_stats_ext Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statistics_schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statistics_name</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-statistic-ext.html" title="53.52. pg_statistic_ext"><code class="structname">pg_statistic_ext</code></a>.<code class="structfield">stxname</code>)
+ </p>
+ <p>
+ Name of extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">statistics_owner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Owner of the extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attnames</code> <code class="type">name[]</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attname</code>)
+ </p>
+ <p>
+ Names of the columns included in the extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">exprs</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Expressions included in the extended statistics object
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">kinds</code> <code class="type">char[]</code>
+ </p>
+ <p>
+ Types of extended statistics object enabled for this record
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inherited</code> <code class="type">bool</code>
+ (references <a class="link" href="catalog-pg-statistic-ext-data.html" title="53.53. pg_statistic_ext_data"><code class="structname">pg_statistic_ext_data</code></a>.<code class="structfield">stxdinherit</code>)
+ </p>
+ <p>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_distinct</code> <code class="type">pg_ndistinct</code>
+ </p>
+ <p>
+ N-distinct counts for combinations of column values. If greater
+ than zero, the estimated number of distinct values in the combination.
+ If less than zero, the negative of the number of distinct values divided
+ by the number of rows.
+ (The negated form is used when <code class="command">ANALYZE</code> believes that
+ the number of distinct values is likely to increase as the table grows;
+ the positive form is used when the column seems to have a fixed number
+ of possible values.) For example, -1 indicates a unique combination of
+ columns in which the number of distinct combinations is the same as the
+ number of rows.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">dependencies</code> <code class="type">pg_dependencies</code>
+ </p>
+ <p>
+ Functional dependency statistics
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_vals</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ A list of the most common combinations of values in the columns.
+ (Null if no combinations seem to be more common than any others.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_val_nulls</code> <code class="type">bool[]</code>
+ </p>
+ <p>
+ A list of NULL flags for the most common combinations of values.
+ (Null when <code class="structfield">most_common_vals</code> is.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_freqs</code> <code class="type">float8[]</code>
+ </p>
+ <p>
+ A list of the frequencies of the most common combinations,
+ i.e., number of occurrences of each divided by total number of rows.
+ (Null when <code class="structfield">most_common_vals</code> is.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_base_freqs</code> <code class="type">float8[]</code>
+ </p>
+ <p>
+ A list of the base frequencies of the most common combinations,
+ i.e., product of per-value frequencies.
+ (Null when <code class="structfield">most_common_vals</code> is.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The maximum number of entries in the array fields can be controlled on a
+ column-by-column basis using the <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER
+ TABLE SET STATISTICS</code></a> command, or globally by setting the
+ <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> run-time parameter.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-stats.html" title="54.27. pg_stats">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.27. <code class="structname">pg_stats</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.29. <code class="structname">pg_stats_ext_exprs</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-stats.html b/doc/src/sgml/html/view-pg-stats.html
new file mode 100644
index 0000000..3055f0f
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-stats.html
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.27. pg_stats</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations" /><link rel="next" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.27. <code class="structname">pg_stats</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-STATS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.27. <code class="structname">pg_stats</code></h2></div></div></div><a id="id-1.10.5.31.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_stats</code> provides access to
+ the information stored in the <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a>
+ catalog. This view allows access only to rows of
+ <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a> that correspond to tables the
+ user has permission to read, and therefore it is safe to allow public
+ read access to this view.
+ </p><p>
+ <code class="structname">pg_stats</code> is also designed to present the
+ information in a more readable format than the underlying catalog
+ — at the cost that its schema must be extended whenever new slot types
+ are defined for <a class="link" href="catalog-pg-statistic.html" title="53.51. pg_statistic"><code class="structname">pg_statistic</code></a>.
+ </p><div class="table" id="id-1.10.5.31.5"><p class="title"><strong>Table 54.27. <code class="structname">pg_stats</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_stats Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">attname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-attribute.html" title="53.7. pg_attribute"><code class="structname">pg_attribute</code></a>.<code class="structfield">attname</code>)
+ </p>
+ <p>
+ Name of column described by this row
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">inherited</code> <code class="type">bool</code>
+ </p>
+ <p>
+ If true, this row includes values from child tables, not just the
+ values in the specified table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">null_frac</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Fraction of column entries that are null
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">avg_width</code> <code class="type">int4</code>
+ </p>
+ <p>
+ Average width in bytes of column's entries
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">n_distinct</code> <code class="type">float4</code>
+ </p>
+ <p>
+ If greater than zero, the estimated number of distinct values in the
+ column. If less than zero, the negative of the number of distinct
+ values divided by the number of rows. (The negated form is used when
+ <code class="command">ANALYZE</code> believes that the number of distinct values is
+ likely to increase as the table grows; the positive form is used when
+ the column seems to have a fixed number of possible values.) For
+ example, -1 indicates a unique column in which the number of distinct
+ values is the same as the number of rows.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_vals</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ A list of the most common values in the column. (Null if
+ no values seem to be more common than any others.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_freqs</code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ A list of the frequencies of the most common values,
+ i.e., number of occurrences of each divided by total number of rows.
+ (Null when <code class="structfield">most_common_vals</code> is.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">histogram_bounds</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ A list of values that divide the column's values into groups of
+ approximately equal population. The values in
+ <code class="structfield">most_common_vals</code>, if present, are omitted from this
+ histogram calculation. (This column is null if the column data type
+ does not have a <code class="literal">&lt;</code> operator or if the
+ <code class="structfield">most_common_vals</code> list accounts for the entire
+ population.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">correlation</code> <code class="type">float4</code>
+ </p>
+ <p>
+ Statistical correlation between physical row ordering and
+ logical ordering of the column values. This ranges from -1 to +1.
+ When the value is near -1 or +1, an index scan on the column will
+ be estimated to be cheaper than when it is near zero, due to reduction
+ of random access to the disk. (This column is null if the column data
+ type does not have a <code class="literal">&lt;</code> operator.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_elems</code> <code class="type">anyarray</code>
+ </p>
+ <p>
+ A list of non-null element values most often appearing within values of
+ the column. (Null for scalar types.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">most_common_elem_freqs</code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ A list of the frequencies of the most common element values, i.e., the
+ fraction of rows containing at least one instance of the given value.
+ Two or three additional values follow the per-element frequencies;
+ these are the minimum and maximum of the preceding per-element
+ frequencies, and optionally the frequency of null elements.
+ (Null when <code class="structfield">most_common_elems</code> is.)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">elem_count_histogram</code> <code class="type">float4[]</code>
+ </p>
+ <p>
+ A histogram of the counts of distinct non-null element values within the
+ values of the column, followed by the average number of distinct
+ non-null elements. (Null for scalar types.)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ The maximum number of entries in the array fields can be controlled on a
+ column-by-column basis using the <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER
+ TABLE SET STATISTICS</code></a>
+ command, or globally by setting the
+ <a class="xref" href="runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET">default_statistics_target</a> run-time parameter.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.26. <code class="structname">pg_shmem_allocations</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.28. <code class="structname">pg_stats_ext</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-tables.html b/doc/src/sgml/html/view-pg-tables.html
new file mode 100644
index 0000000..dac66cf
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-tables.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.30. pg_tables</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs" /><link rel="next" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.30. <code class="structname">pg_tables</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-TABLES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.30. <code class="structname">pg_tables</code></h2></div></div></div><a id="id-1.10.5.34.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_tables</code> provides access to
+ useful information about each table in the database.
+ </p><div class="table" id="id-1.10.5.34.4"><p class="title"><strong>Table 54.30. <code class="structname">pg_tables</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_tables Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablename</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of table
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tableowner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Name of table's owner
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">tablespace</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-tablespace.html" title="53.56. pg_tablespace"><code class="structname">pg_tablespace</code></a>.<code class="structfield">spcname</code>)
+ </p>
+ <p>
+ Name of tablespace containing table (null if default for database)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">hasindexes</code> <code class="type">bool</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relhasindex</code>)
+ </p>
+ <p>
+ True if table has (or recently had) any indexes
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">hasrules</code> <code class="type">bool</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relhasrules</code>)
+ </p>
+ <p>
+ True if table has (or once had) rules
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">hastriggers</code> <code class="type">bool</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relhastriggers</code>)
+ </p>
+ <p>
+ True if table has (or once had) triggers
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">rowsecurity</code> <code class="type">bool</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relrowsecurity</code>)
+ </p>
+ <p>
+ True if row security is enabled on the table
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.29. <code class="structname">pg_stats_ext_exprs</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.31. <code class="structname">pg_timezone_abbrevs</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-timezone-abbrevs.html b/doc/src/sgml/html/view-pg-timezone-abbrevs.html
new file mode 100644
index 0000000..de7df8a
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-timezone-abbrevs.html
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.31. pg_timezone_abbrevs</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-tables.html" title="54.30. pg_tables" /><link rel="next" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.31. <code class="structname">pg_timezone_abbrevs</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-tables.html" title="54.30. pg_tables">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-TIMEZONE-ABBREVS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.31. <code class="structname">pg_timezone_abbrevs</code></h2></div></div></div><a id="id-1.10.5.35.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_timezone_abbrevs</code> provides a list
+ of time zone abbreviations that are currently recognized by the datetime
+ input routines. The contents of this view change when the
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE-ABBREVIATIONS">timezone_abbreviations</a> run-time parameter is modified.
+ </p><div class="table" id="id-1.10.5.35.4"><p class="title"><strong>Table 54.31. <code class="structname">pg_timezone_abbrevs</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_timezone_abbrevs Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">abbrev</code> <code class="type">text</code>
+ </p>
+ <p>
+ Time zone abbreviation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">utc_offset</code> <code class="type">interval</code>
+ </p>
+ <p>
+ Offset from UTC (positive means east of Greenwich)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_dst</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if this is a daylight-savings abbreviation
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ While most timezone abbreviations represent fixed offsets from UTC,
+ there are some that have historically varied in value
+ (see <a class="xref" href="datetime-config-files.html" title="B.4. Date/Time Configuration Files">Section B.4</a> for more information).
+ In such cases this view presents their current meaning.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-tables.html" title="54.30. pg_tables">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.30. <code class="structname">pg_tables</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.32. <code class="structname">pg_timezone_names</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-timezone-names.html b/doc/src/sgml/html/view-pg-timezone-names.html
new file mode 100644
index 0000000..0d22ba7
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-timezone-names.html
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.32. pg_timezone_names</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs" /><link rel="next" href="view-pg-user.html" title="54.33. pg_user" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.32. <code class="structname">pg_timezone_names</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-user.html" title="54.33. pg_user">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-TIMEZONE-NAMES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.32. <code class="structname">pg_timezone_names</code></h2></div></div></div><a id="id-1.10.5.36.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_timezone_names</code> provides a list
+ of time zone names that are recognized by <code class="command">SET TIMEZONE</code>,
+ along with their associated abbreviations, UTC offsets,
+ and daylight-savings status. (Technically,
+ <span class="productname">PostgreSQL</span> does not use UTC because leap
+ seconds are not handled.)
+ Unlike the abbreviations shown in <a class="link" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs"><code class="structname">pg_timezone_abbrevs</code></a>, many of these names imply a set of daylight-savings transition
+ date rules. Therefore, the associated information changes across local DST
+ boundaries. The displayed information is computed based on the current
+ value of <code class="function">CURRENT_TIMESTAMP</code>.
+ </p><div class="table" id="id-1.10.5.36.4"><p class="title"><strong>Table 54.32. <code class="structname">pg_timezone_names</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_timezone_names Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">name</code> <code class="type">text</code>
+ </p>
+ <p>
+ Time zone name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">abbrev</code> <code class="type">text</code>
+ </p>
+ <p>
+ Time zone abbreviation
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">utc_offset</code> <code class="type">interval</code>
+ </p>
+ <p>
+ Offset from UTC (positive means east of Greenwich)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">is_dst</code> <code class="type">bool</code>
+ </p>
+ <p>
+ True if currently observing daylight savings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-user.html" title="54.33. pg_user">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.31. <code class="structname">pg_timezone_abbrevs</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.33. <code class="structname">pg_user</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-user-mappings.html b/doc/src/sgml/html/view-pg-user-mappings.html
new file mode 100644
index 0000000..a3ea3a2
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-user-mappings.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.34. pg_user_mappings</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-user.html" title="54.33. pg_user" /><link rel="next" href="view-pg-views.html" title="54.35. pg_views" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.34. <code class="structname">pg_user_mappings</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-user.html" title="54.33. pg_user">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-views.html" title="54.35. pg_views">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-USER-MAPPINGS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.34. <code class="structname">pg_user_mappings</code></h2></div></div></div><a id="id-1.10.5.38.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_user_mappings</code> provides access
+ to information about user mappings. This is essentially a publicly
+ readable view of
+ <a class="link" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping"><code class="structname">pg_user_mapping</code></a>
+ that leaves out the options field if the user has no rights to use
+ it.
+ </p><div class="table" id="id-1.10.5.38.4"><p class="title"><strong>Table 54.34. <code class="structname">pg_user_mappings</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_user_mappings Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">umid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping"><code class="structname">pg_user_mapping</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the user mapping
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvid</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server"><code class="structname">pg_foreign_server</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ The OID of the foreign server that contains this mapping
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">srvname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-foreign-server.html" title="53.24. pg_foreign_server"><code class="structname">pg_foreign_server</code></a>.<code class="structfield">srvname</code>)
+ </p>
+ <p>
+ Name of the foreign server
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">umuser</code> <code class="type">oid</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">oid</code>)
+ </p>
+ <p>
+ OID of the local role being mapped, or zero if the user mapping is public
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usename</code> <code class="type">name</code>
+ </p>
+ <p>
+ Name of the local user to be mapped
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">umoptions</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ User mapping specific options, as <span class="quote">“<span class="quote">keyword=value</span>”</span> strings
+ </p></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ To protect password information stored as a user mapping option,
+ the <code class="structfield">umoptions</code> column will read as null
+ unless one of the following applies:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ current user is the user being mapped, and owns the server or
+ holds <code class="literal">USAGE</code> privilege on it
+ </p></li><li class="listitem"><p>
+ current user is the server owner and mapping is for <code class="literal">PUBLIC</code>
+ </p></li><li class="listitem"><p>
+ current user is a superuser
+ </p></li></ul></div><p>
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-user.html" title="54.33. pg_user">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-views.html" title="54.35. pg_views">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.33. <code class="structname">pg_user</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.35. <code class="structname">pg_views</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-user.html b/doc/src/sgml/html/view-pg-user.html
new file mode 100644
index 0000000..77a044c
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-user.html
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.33. pg_user</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names" /><link rel="next" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.33. <code class="structname">pg_user</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-USER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.33. <code class="structname">pg_user</code></h2></div></div></div><a id="id-1.10.5.37.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_user</code> provides access to
+ information about database users. This is simply a publicly
+ readable view of
+ <a class="link" href="view-pg-shadow.html" title="54.25. pg_shadow"><code class="structname">pg_shadow</code></a>
+ that blanks out the password field.
+ </p><div class="table" id="id-1.10.5.37.4"><p class="title"><strong>Table 54.33. <code class="structname">pg_user</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_user Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usename</code> <code class="type">name</code>
+ </p>
+ <p>
+ User name
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usesysid</code> <code class="type">oid</code>
+ </p>
+ <p>
+ ID of this user
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usecreatedb</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User can create databases
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usesuper</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User is a superuser
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">userepl</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User can initiate streaming replication and put the system in and
+ out of backup mode.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">usebypassrls</code> <code class="type">bool</code>
+ </p>
+ <p>
+ User bypasses every row-level security policy, see
+ <a class="xref" href="ddl-rowsecurity.html" title="5.8. Row Security Policies">Section 5.8</a> for more information.
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">passwd</code> <code class="type">text</code>
+ </p>
+ <p>
+ Not the password (always reads as <code class="literal">********</code>)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">valuntil</code> <code class="type">timestamptz</code>
+ </p>
+ <p>
+ Password expiry time (only used for password authentication)
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">useconfig</code> <code class="type">text[]</code>
+ </p>
+ <p>
+ Session defaults for run-time configuration variables
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.32. <code class="structname">pg_timezone_names</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.34. <code class="structname">pg_user_mappings</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/view-pg-views.html b/doc/src/sgml/html/view-pg-views.html
new file mode 100644
index 0000000..f4e07af
--- /dev/null
+++ b/doc/src/sgml/html/view-pg-views.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.35. pg_views</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings" /><link rel="next" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.35. <code class="structname">pg_views</code></th></tr><tr><td width="10%" align="left"><a accesskey="p" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEW-PG-VIEWS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.35. <code class="structname">pg_views</code></h2></div></div></div><a id="id-1.10.5.39.2" class="indexterm"></a><p>
+ The view <code class="structname">pg_views</code> provides access to
+ useful information about each view in the database.
+ </p><div class="table" id="id-1.10.5.39.4"><p class="title"><strong>Table 54.35. <code class="structname">pg_views</code> Columns</strong></p><div class="table-contents"><table class="table" summary="pg_views Columns" border="1"><colgroup><col /></colgroup><thead><tr><th class="catalog_table_entry"><p class="column_definition">
+ Column Type
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">schemaname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-namespace.html" title="53.32. pg_namespace"><code class="structname">pg_namespace</code></a>.<code class="structfield">nspname</code>)
+ </p>
+ <p>
+ Name of schema containing view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">viewname</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-class.html" title="53.11. pg_class"><code class="structname">pg_class</code></a>.<code class="structfield">relname</code>)
+ </p>
+ <p>
+ Name of view
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">viewowner</code> <code class="type">name</code>
+ (references <a class="link" href="catalog-pg-authid.html" title="53.8. pg_authid"><code class="structname">pg_authid</code></a>.<code class="structfield">rolname</code>)
+ </p>
+ <p>
+ Name of view's owner
+ </p></td></tr><tr><td class="catalog_table_entry"><p class="column_definition">
+ <code class="structfield">definition</code> <code class="type">text</code>
+ </p>
+ <p>
+ View definition (a reconstructed <a class="xref" href="sql-select.html" title="SELECT"><span class="refentrytitle">SELECT</span></a> query)
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="protocol.html" title="Chapter 55. Frontend/Backend Protocol">Next</a></td></tr><tr><td width="40%" align="left" valign="top">54.34. <code class="structname">pg_user_mappings</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 55. Frontend/Backend Protocol</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/views-overview.html b/doc/src/sgml/html/views-overview.html
new file mode 100644
index 0000000..e71e364
--- /dev/null
+++ b/doc/src/sgml/html/views-overview.html
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>54.1. Overview</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="views.html" title="Chapter 54. System Views" /><link rel="next" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">54.1. Overview</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="views.html" title="Chapter 54. System Views">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><th width="60%" align="center">Chapter 54. System Views</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions">Next</a></td></tr></table><hr /></div><div class="sect1" id="VIEWS-OVERVIEW"><div class="titlepage"><div><div><h2 class="title" style="clear: both">54.1. Overview</h2></div></div></div><p>
+ <a class="xref" href="views-overview.html#VIEW-TABLE" title="Table 54.1. System Views">Table 54.1</a> lists the system views.
+ More detailed documentation of each catalog follows below.
+ Except where noted, all the views described here are read-only.
+ </p><div class="table" id="VIEW-TABLE"><p class="title"><strong>Table 54.1. System Views</strong></p><div class="table-contents"><table class="table" summary="System Views" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>View Name</th><th>Purpose</th></tr></thead><tbody><tr><td><a class="link" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions"><code class="structname">pg_available_extensions</code></a></td><td>available extensions</td></tr><tr><td><a class="link" href="view-pg-available-extension-versions.html" title="54.3. pg_available_extension_versions"><code class="structname">pg_available_extension_versions</code></a></td><td>available versions of extensions</td></tr><tr><td><a class="link" href="view-pg-backend-memory-contexts.html" title="54.4. pg_backend_memory_contexts"><code class="structname">pg_backend_memory_contexts</code></a></td><td>backend memory contexts</td></tr><tr><td><a class="link" href="view-pg-config.html" title="54.5. pg_config"><code class="structname">pg_config</code></a></td><td>compile-time configuration parameters</td></tr><tr><td><a class="link" href="view-pg-cursors.html" title="54.6. pg_cursors"><code class="structname">pg_cursors</code></a></td><td>open cursors</td></tr><tr><td><a class="link" href="view-pg-file-settings.html" title="54.7. pg_file_settings"><code class="structname">pg_file_settings</code></a></td><td>summary of configuration file contents</td></tr><tr><td><a class="link" href="view-pg-group.html" title="54.8. pg_group"><code class="structname">pg_group</code></a></td><td>groups of database users</td></tr><tr><td><a class="link" href="view-pg-hba-file-rules.html" title="54.9. pg_hba_file_rules"><code class="structname">pg_hba_file_rules</code></a></td><td>summary of client authentication configuration file contents</td></tr><tr><td><a class="link" href="view-pg-ident-file-mappings.html" title="54.10. pg_ident_file_mappings"><code class="structname">pg_ident_file_mappings</code></a></td><td>summary of client user name mapping configuration file contents</td></tr><tr><td><a class="link" href="view-pg-indexes.html" title="54.11. pg_indexes"><code class="structname">pg_indexes</code></a></td><td>indexes</td></tr><tr><td><a class="link" href="view-pg-locks.html" title="54.12. pg_locks"><code class="structname">pg_locks</code></a></td><td>locks currently held or awaited</td></tr><tr><td><a class="link" href="view-pg-matviews.html" title="54.13. pg_matviews"><code class="structname">pg_matviews</code></a></td><td>materialized views</td></tr><tr><td><a class="link" href="view-pg-policies.html" title="54.14. pg_policies"><code class="structname">pg_policies</code></a></td><td>policies</td></tr><tr><td><a class="link" href="view-pg-prepared-statements.html" title="54.15. pg_prepared_statements"><code class="structname">pg_prepared_statements</code></a></td><td>prepared statements</td></tr><tr><td><a class="link" href="view-pg-prepared-xacts.html" title="54.16. pg_prepared_xacts"><code class="structname">pg_prepared_xacts</code></a></td><td>prepared transactions</td></tr><tr><td><a class="link" href="view-pg-publication-tables.html" title="54.17. pg_publication_tables"><code class="structname">pg_publication_tables</code></a></td><td>publications and information of their associated tables</td></tr><tr><td><a class="link" href="view-pg-replication-origin-status.html" title="54.18. pg_replication_origin_status"><code class="structname">pg_replication_origin_status</code></a></td><td>information about replication origins, including replication progress</td></tr><tr><td><a class="link" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots"><code class="structname">pg_replication_slots</code></a></td><td>replication slot information</td></tr><tr><td><a class="link" href="view-pg-roles.html" title="54.20. pg_roles"><code class="structname">pg_roles</code></a></td><td>database roles</td></tr><tr><td><a class="link" href="view-pg-rules.html" title="54.21. pg_rules"><code class="structname">pg_rules</code></a></td><td>rules</td></tr><tr><td><a class="link" href="view-pg-seclabels.html" title="54.22. pg_seclabels"><code class="structname">pg_seclabels</code></a></td><td>security labels</td></tr><tr><td><a class="link" href="view-pg-sequences.html" title="54.23. pg_sequences"><code class="structname">pg_sequences</code></a></td><td>sequences</td></tr><tr><td><a class="link" href="view-pg-settings.html" title="54.24. pg_settings"><code class="structname">pg_settings</code></a></td><td>parameter settings</td></tr><tr><td><a class="link" href="view-pg-shadow.html" title="54.25. pg_shadow"><code class="structname">pg_shadow</code></a></td><td>database users</td></tr><tr><td><a class="link" href="view-pg-shmem-allocations.html" title="54.26. pg_shmem_allocations"><code class="structname">pg_shmem_allocations</code></a></td><td>shared memory allocations</td></tr><tr><td><a class="link" href="view-pg-stats.html" title="54.27. pg_stats"><code class="structname">pg_stats</code></a></td><td>planner statistics</td></tr><tr><td><a class="link" href="view-pg-stats-ext.html" title="54.28. pg_stats_ext"><code class="structname">pg_stats_ext</code></a></td><td>extended planner statistics</td></tr><tr><td><a class="link" href="view-pg-stats-ext-exprs.html" title="54.29. pg_stats_ext_exprs"><code class="structname">pg_stats_ext_exprs</code></a></td><td>extended planner statistics for expressions</td></tr><tr><td><a class="link" href="view-pg-tables.html" title="54.30. pg_tables"><code class="structname">pg_tables</code></a></td><td>tables</td></tr><tr><td><a class="link" href="view-pg-timezone-abbrevs.html" title="54.31. pg_timezone_abbrevs"><code class="structname">pg_timezone_abbrevs</code></a></td><td>time zone abbreviations</td></tr><tr><td><a class="link" href="view-pg-timezone-names.html" title="54.32. pg_timezone_names"><code class="structname">pg_timezone_names</code></a></td><td>time zone names</td></tr><tr><td><a class="link" href="view-pg-user.html" title="54.33. pg_user"><code class="structname">pg_user</code></a></td><td>database users</td></tr><tr><td><a class="link" href="view-pg-user-mappings.html" title="54.34. pg_user_mappings"><code class="structname">pg_user_mappings</code></a></td><td>user mappings</td></tr><tr><td><a class="link" href="view-pg-views.html" title="54.35. pg_views"><code class="structname">pg_views</code></a></td><td>views</td></tr></tbody></table></div></div><br class="table-break" /></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="views.html" title="Chapter 54. System Views">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="views.html" title="Chapter 54. System Views">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="view-pg-available-extensions.html" title="54.2. pg_available_extensions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 54. System Views </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.2. <code class="structname">pg_available_extensions</code></td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/views.html b/doc/src/sgml/html/views.html
new file mode 100644
index 0000000..bc9b57c
--- /dev/null
+++ b/doc/src/sgml/html/views.html
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 54. System Views</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping" /><link rel="next" href="views-overview.html" title="54.1. Overview" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 54. System Views</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><th width="60%" align="center">Part VII. Internals</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="views-overview.html" title="54.1. Overview">Next</a></td></tr></table><hr /></div><div class="chapter" id="VIEWS"><div class="titlepage"><div><div><h2 class="title">Chapter 54. System Views</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="views-overview.html">54.1. Overview</a></span></dt><dt><span class="sect1"><a href="view-pg-available-extensions.html">54.2. <code class="structname">pg_available_extensions</code></a></span></dt><dt><span class="sect1"><a href="view-pg-available-extension-versions.html">54.3. <code class="structname">pg_available_extension_versions</code></a></span></dt><dt><span class="sect1"><a href="view-pg-backend-memory-contexts.html">54.4. <code class="structname">pg_backend_memory_contexts</code></a></span></dt><dt><span class="sect1"><a href="view-pg-config.html">54.5. <code class="structname">pg_config</code></a></span></dt><dt><span class="sect1"><a href="view-pg-cursors.html">54.6. <code class="structname">pg_cursors</code></a></span></dt><dt><span class="sect1"><a href="view-pg-file-settings.html">54.7. <code class="structname">pg_file_settings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-group.html">54.8. <code class="structname">pg_group</code></a></span></dt><dt><span class="sect1"><a href="view-pg-hba-file-rules.html">54.9. <code class="structname">pg_hba_file_rules</code></a></span></dt><dt><span class="sect1"><a href="view-pg-ident-file-mappings.html">54.10. <code class="structname">pg_ident_file_mappings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-indexes.html">54.11. <code class="structname">pg_indexes</code></a></span></dt><dt><span class="sect1"><a href="view-pg-locks.html">54.12. <code class="structname">pg_locks</code></a></span></dt><dt><span class="sect1"><a href="view-pg-matviews.html">54.13. <code class="structname">pg_matviews</code></a></span></dt><dt><span class="sect1"><a href="view-pg-policies.html">54.14. <code class="structname">pg_policies</code></a></span></dt><dt><span class="sect1"><a href="view-pg-prepared-statements.html">54.15. <code class="structname">pg_prepared_statements</code></a></span></dt><dt><span class="sect1"><a href="view-pg-prepared-xacts.html">54.16. <code class="structname">pg_prepared_xacts</code></a></span></dt><dt><span class="sect1"><a href="view-pg-publication-tables.html">54.17. <code class="structname">pg_publication_tables</code></a></span></dt><dt><span class="sect1"><a href="view-pg-replication-origin-status.html">54.18. <code class="structname">pg_replication_origin_status</code></a></span></dt><dt><span class="sect1"><a href="view-pg-replication-slots.html">54.19. <code class="structname">pg_replication_slots</code></a></span></dt><dt><span class="sect1"><a href="view-pg-roles.html">54.20. <code class="structname">pg_roles</code></a></span></dt><dt><span class="sect1"><a href="view-pg-rules.html">54.21. <code class="structname">pg_rules</code></a></span></dt><dt><span class="sect1"><a href="view-pg-seclabels.html">54.22. <code class="structname">pg_seclabels</code></a></span></dt><dt><span class="sect1"><a href="view-pg-sequences.html">54.23. <code class="structname">pg_sequences</code></a></span></dt><dt><span class="sect1"><a href="view-pg-settings.html">54.24. <code class="structname">pg_settings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-shadow.html">54.25. <code class="structname">pg_shadow</code></a></span></dt><dt><span class="sect1"><a href="view-pg-shmem-allocations.html">54.26. <code class="structname">pg_shmem_allocations</code></a></span></dt><dt><span class="sect1"><a href="view-pg-stats.html">54.27. <code class="structname">pg_stats</code></a></span></dt><dt><span class="sect1"><a href="view-pg-stats-ext.html">54.28. <code class="structname">pg_stats_ext</code></a></span></dt><dt><span class="sect1"><a href="view-pg-stats-ext-exprs.html">54.29. <code class="structname">pg_stats_ext_exprs</code></a></span></dt><dt><span class="sect1"><a href="view-pg-tables.html">54.30. <code class="structname">pg_tables</code></a></span></dt><dt><span class="sect1"><a href="view-pg-timezone-abbrevs.html">54.31. <code class="structname">pg_timezone_abbrevs</code></a></span></dt><dt><span class="sect1"><a href="view-pg-timezone-names.html">54.32. <code class="structname">pg_timezone_names</code></a></span></dt><dt><span class="sect1"><a href="view-pg-user.html">54.33. <code class="structname">pg_user</code></a></span></dt><dt><span class="sect1"><a href="view-pg-user-mappings.html">54.34. <code class="structname">pg_user_mappings</code></a></span></dt><dt><span class="sect1"><a href="view-pg-views.html">54.35. <code class="structname">pg_views</code></a></span></dt></dl></div><p>
+ In addition to the system catalogs, <span class="productname">PostgreSQL</span>
+ provides a number of built-in views. Some system views provide convenient
+ access to some commonly used queries on the system catalogs. Other views
+ provide access to internal server state.
+ </p><p>
+ The information schema (<a class="xref" href="information-schema.html" title="Chapter 37. The Information Schema">Chapter 37</a>) provides
+ an alternative set of views which overlap the functionality of the system
+ views. Since the information schema is SQL-standard whereas the views
+ described here are <span class="productname">PostgreSQL</span>-specific,
+ it's usually better to use the information schema if it provides all
+ the information you need.
+ </p><p>
+ <a class="xref" href="views-overview.html#VIEW-TABLE" title="Table 54.1. System Views">Table 54.1</a> lists the system views described here.
+ More detailed documentation of each view follows below.
+ There are some additional views that provide access to accumulated
+ statistics; they are described in
+ <a class="xref" href="monitoring-stats.html#MONITORING-STATS-VIEWS-TABLE" title="Table 28.2. Collected Statistics Views">Table 28.2</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="catalog-pg-user-mapping.html" title="53.65. pg_user_mapping">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="internals.html" title="Part VII. Internals">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="views-overview.html" title="54.1. Overview">Next</a></td></tr><tr><td width="40%" align="left" valign="top">53.65. <code class="structname">pg_user_mapping</code> </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 54.1. Overview</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/wal-async-commit.html b/doc/src/sgml/html/wal-async-commit.html
new file mode 100644
index 0000000..aed630c
--- /dev/null
+++ b/doc/src/sgml/html/wal-async-commit.html
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>30.4. Asynchronous Commit</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="wal-intro.html" title="30.3. Write-Ahead Logging (WAL)" /><link rel="next" href="wal-configuration.html" title="30.5. WAL Configuration" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">30.4. Asynchronous Commit</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="wal-intro.html" title="30.3. Write-Ahead Logging (WAL)">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><th width="60%" align="center">Chapter 30. Reliability and the Write-Ahead Log</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="wal-configuration.html" title="30.5. WAL Configuration">Next</a></td></tr></table><hr /></div><div class="sect1" id="WAL-ASYNC-COMMIT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">30.4. Asynchronous Commit</h2></div></div></div><a id="id-1.6.17.6.2" class="indexterm"></a><a id="id-1.6.17.6.3" class="indexterm"></a><p>
+ <em class="firstterm">Asynchronous commit</em> is an option that allows transactions
+ to complete more quickly, at the cost that the most recent transactions may
+ be lost if the database should crash. In many applications this is an
+ acceptable trade-off.
+ </p><p>
+ As described in the previous section, transaction commit is normally
+ <em class="firstterm">synchronous</em>: the server waits for the transaction's
+ <acronym class="acronym">WAL</acronym> records to be flushed to permanent storage
+ before returning a success indication to the client. The client is
+ therefore guaranteed that a transaction reported to be committed will
+ be preserved, even in the event of a server crash immediately after.
+ However, for short transactions this delay is a major component of the
+ total transaction time. Selecting asynchronous commit mode means that
+ the server returns success as soon as the transaction is logically
+ completed, before the <acronym class="acronym">WAL</acronym> records it generated have
+ actually made their way to disk. This can provide a significant boost
+ in throughput for small transactions.
+ </p><p>
+ Asynchronous commit introduces the risk of data loss. There is a short
+ time window between the report of transaction completion to the client
+ and the time that the transaction is truly committed (that is, it is
+ guaranteed not to be lost if the server crashes). Thus asynchronous
+ commit should not be used if the client will take external actions
+ relying on the assumption that the transaction will be remembered.
+ As an example, a bank would certainly not use asynchronous commit for
+ a transaction recording an ATM's dispensing of cash. But in many
+ scenarios, such as event logging, there is no need for a strong
+ guarantee of this kind.
+ </p><p>
+ The risk that is taken by using asynchronous commit is of data loss,
+ not data corruption. If the database should crash, it will recover
+ by replaying <acronym class="acronym">WAL</acronym> up to the last record that was
+ flushed. The database will therefore be restored to a self-consistent
+ state, but any transactions that were not yet flushed to disk will
+ not be reflected in that state. The net effect is therefore loss of
+ the last few transactions. Because the transactions are replayed in
+ commit order, no inconsistency can be introduced — for example,
+ if transaction B made changes relying on the effects of a previous
+ transaction A, it is not possible for A's effects to be lost while B's
+ effects are preserved.
+ </p><p>
+ The user can select the commit mode of each transaction, so that
+ it is possible to have both synchronous and asynchronous commit
+ transactions running concurrently. This allows flexible trade-offs
+ between performance and certainty of transaction durability.
+ The commit mode is controlled by the user-settable parameter
+ <a class="xref" href="runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT">synchronous_commit</a>, which can be changed in any of
+ the ways that a configuration parameter can be set. The mode used for
+ any one transaction depends on the value of
+ <code class="varname">synchronous_commit</code> when transaction commit begins.
+ </p><p>
+ Certain utility commands, for instance <code class="command">DROP TABLE</code>, are
+ forced to commit synchronously regardless of the setting of
+ <code class="varname">synchronous_commit</code>. This is to ensure consistency
+ between the server's file system and the logical state of the database.
+ The commands supporting two-phase commit, such as <code class="command">PREPARE
+ TRANSACTION</code>, are also always synchronous.
+ </p><p>
+ If the database crashes during the risk window between an
+ asynchronous commit and the writing of the transaction's
+ <acronym class="acronym">WAL</acronym> records,
+ then changes made during that transaction <span class="emphasis"><em>will</em></span> be lost.
+ The duration of the
+ risk window is limited because a background process (the <span class="quote">“<span class="quote">WAL
+ writer</span>”</span>) flushes unwritten <acronym class="acronym">WAL</acronym> records to disk
+ every <a class="xref" href="runtime-config-wal.html#GUC-WAL-WRITER-DELAY">wal_writer_delay</a> milliseconds.
+ The actual maximum duration of the risk window is three times
+ <code class="varname">wal_writer_delay</code> because the WAL writer is
+ designed to favor writing whole pages at a time during busy periods.
+ </p><div class="caution"><h3 class="title">Caution</h3><p>
+ An immediate-mode shutdown is equivalent to a server crash, and will
+ therefore cause loss of any unflushed asynchronous commits.
+ </p></div><p>
+ Asynchronous commit provides behavior different from setting
+ <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a> = off.
+ <code class="varname">fsync</code> is a server-wide
+ setting that will alter the behavior of all transactions. It disables
+ all logic within <span class="productname">PostgreSQL</span> that attempts to synchronize
+ writes to different portions of the database, and therefore a system
+ crash (that is, a hardware or operating system crash, not a failure of
+ <span class="productname">PostgreSQL</span> itself) could result in arbitrarily bad
+ corruption of the database state. In many scenarios, asynchronous
+ commit provides most of the performance improvement that could be
+ obtained by turning off <code class="varname">fsync</code>, but without the risk
+ of data corruption.
+ </p><p>
+ <a class="xref" href="runtime-config-wal.html#GUC-COMMIT-DELAY">commit_delay</a> also sounds very similar to
+ asynchronous commit, but it is actually a synchronous commit method
+ (in fact, <code class="varname">commit_delay</code> is ignored during an
+ asynchronous commit). <code class="varname">commit_delay</code> causes a delay
+ just before a transaction flushes <acronym class="acronym">WAL</acronym> to disk, in
+ the hope that a single flush executed by one such transaction can also
+ serve other transactions committing at about the same time. The
+ setting can be thought of as a way of increasing the time window in
+ which transactions can join a group about to participate in a single
+ flush, to amortize the cost of the flush among multiple transactions.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="wal-intro.html" title="30.3. Write-Ahead Logging (WAL)">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="wal-configuration.html" title="30.5. WAL Configuration">Next</a></td></tr><tr><td width="40%" align="left" valign="top">30.3. Write-Ahead Logging (<acronym class="acronym">WAL</acronym>) </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 30.5. <acronym class="acronym">WAL</acronym> Configuration</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/wal-configuration.html b/doc/src/sgml/html/wal-configuration.html
new file mode 100644
index 0000000..e683789
--- /dev/null
+++ b/doc/src/sgml/html/wal-configuration.html
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>30.5. WAL Configuration</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="wal-async-commit.html" title="30.4. Asynchronous Commit" /><link rel="next" href="wal-internals.html" title="30.6. WAL Internals" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">30.5. <acronym class="acronym">WAL</acronym> Configuration</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="wal-async-commit.html" title="30.4. Asynchronous Commit">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><th width="60%" align="center">Chapter 30. Reliability and the Write-Ahead Log</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="wal-internals.html" title="30.6. WAL Internals">Next</a></td></tr></table><hr /></div><div class="sect1" id="WAL-CONFIGURATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">30.5. <acronym class="acronym">WAL</acronym> Configuration</h2></div></div></div><p>
+ There are several <acronym class="acronym">WAL</acronym>-related configuration parameters that
+ affect database performance. This section explains their use.
+ Consult <a class="xref" href="runtime-config.html" title="Chapter 20. Server Configuration">Chapter 20</a> for general information about
+ setting server configuration parameters.
+ </p><p>
+ <em class="firstterm">Checkpoints</em><a id="id-1.6.17.7.3.2" class="indexterm"></a>
+ are points in the sequence of transactions at which it is guaranteed
+ that the heap and index data files have been updated with all
+ information written before that checkpoint. At checkpoint time, all
+ dirty data pages are flushed to disk and a special checkpoint record is
+ written to the log file. (The change records were previously flushed
+ to the <acronym class="acronym">WAL</acronym> files.)
+ In the event of a crash, the crash recovery procedure looks at the latest
+ checkpoint record to determine the point in the log (known as the redo
+ record) from which it should start the REDO operation. Any changes made to
+ data files before that point are guaranteed to be already on disk.
+ Hence, after a checkpoint, log segments preceding the one containing
+ the redo record are no longer needed and can be recycled or removed. (When
+ <acronym class="acronym">WAL</acronym> archiving is being done, the log segments must be
+ archived before being recycled or removed.)
+ </p><p>
+ The checkpoint requirement of flushing all dirty data pages to disk
+ can cause a significant I/O load. For this reason, checkpoint
+ activity is throttled so that I/O begins at checkpoint start and completes
+ before the next checkpoint is due to start; this minimizes performance
+ degradation during checkpoints.
+ </p><p>
+ The server's checkpointer process automatically performs
+ a checkpoint every so often. A checkpoint is begun every <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-TIMEOUT">checkpoint_timeout</a> seconds, or if
+ <a class="xref" href="runtime-config-wal.html#GUC-MAX-WAL-SIZE">max_wal_size</a> is about to be exceeded,
+ whichever comes first.
+ The default settings are 5 minutes and 1 GB, respectively.
+ If no WAL has been written since the previous checkpoint, new checkpoints
+ will be skipped even if <code class="varname">checkpoint_timeout</code> has passed.
+ (If WAL archiving is being used and you want to put a lower limit on how
+ often files are archived in order to bound potential data loss, you should
+ adjust the <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-TIMEOUT">archive_timeout</a> parameter rather than the
+ checkpoint parameters.)
+ It is also possible to force a checkpoint by using the SQL
+ command <code class="command">CHECKPOINT</code>.
+ </p><p>
+ Reducing <code class="varname">checkpoint_timeout</code> and/or
+ <code class="varname">max_wal_size</code> causes checkpoints to occur
+ more often. This allows faster after-crash recovery, since less work
+ will need to be redone. However, one must balance this against the
+ increased cost of flushing dirty data pages more often. If
+ <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a> is set (as is the default), there is
+ another factor to consider. To ensure data page consistency,
+ the first modification of a data page after each checkpoint results in
+ logging the entire page content. In that case,
+ a smaller checkpoint interval increases the volume of output to the WAL log,
+ partially negating the goal of using a smaller interval,
+ and in any case causing more disk I/O.
+ </p><p>
+ Checkpoints are fairly expensive, first because they require writing
+ out all currently dirty buffers, and second because they result in
+ extra subsequent WAL traffic as discussed above. It is therefore
+ wise to set the checkpointing parameters high enough so that checkpoints
+ don't happen too often. As a simple sanity check on your checkpointing
+ parameters, you can set the <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-WARNING">checkpoint_warning</a>
+ parameter. If checkpoints happen closer together than
+ <code class="varname">checkpoint_warning</code> seconds,
+ a message will be output to the server log recommending increasing
+ <code class="varname">max_wal_size</code>. Occasional appearance of such
+ a message is not cause for alarm, but if it appears often then the
+ checkpoint control parameters should be increased. Bulk operations such
+ as large <code class="command">COPY</code> transfers might cause a number of such warnings
+ to appear if you have not set <code class="varname">max_wal_size</code> high
+ enough.
+ </p><p>
+ To avoid flooding the I/O system with a burst of page writes,
+ writing dirty buffers during a checkpoint is spread over a period of time.
+ That period is controlled by
+ <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-COMPLETION-TARGET">checkpoint_completion_target</a>, which is
+ given as a fraction of the checkpoint interval (configured by using
+ <code class="varname">checkpoint_timeout</code>).
+ The I/O rate is adjusted so that the checkpoint finishes when the
+ given fraction of
+ <code class="varname">checkpoint_timeout</code> seconds have elapsed, or before
+ <code class="varname">max_wal_size</code> is exceeded, whichever is sooner.
+ With the default value of 0.9,
+ <span class="productname">PostgreSQL</span> can be expected to complete each checkpoint
+ a bit before the next scheduled checkpoint (at around 90% of the last checkpoint's
+ duration). This spreads out the I/O as much as possible so that the checkpoint
+ I/O load is consistent throughout the checkpoint interval. The disadvantage of
+ this is that prolonging checkpoints affects recovery time, because more WAL
+ segments will need to be kept around for possible use in recovery. A user
+ concerned about the amount of time required to recover might wish to reduce
+ <code class="varname">checkpoint_timeout</code> so that checkpoints occur more frequently
+ but still spread the I/O across the checkpoint interval. Alternatively,
+ <code class="varname">checkpoint_completion_target</code> could be reduced, but this would
+ result in times of more intense I/O (during the checkpoint) and times of less I/O
+ (after the checkpoint completed but before the next scheduled checkpoint) and
+ therefore is not recommended.
+ Although <code class="varname">checkpoint_completion_target</code> could be set as high as
+ 1.0, it is typically recommended to set it to no higher than 0.9 (the default)
+ since checkpoints include some other activities besides writing dirty buffers.
+ A setting of 1.0 is quite likely to result in checkpoints not being
+ completed on time, which would result in performance loss due to
+ unexpected variation in the number of WAL segments needed.
+ </p><p>
+ On Linux and POSIX platforms <a class="xref" href="runtime-config-wal.html#GUC-CHECKPOINT-FLUSH-AFTER">checkpoint_flush_after</a>
+ allows to force the OS that pages written by the checkpoint should be
+ flushed to disk after a configurable number of bytes. Otherwise, these
+ pages may be kept in the OS's page cache, inducing a stall when
+ <code class="literal">fsync</code> is issued at the end of a checkpoint. This setting will
+ often help to reduce transaction latency, but it also can have an adverse
+ effect on performance; particularly for workloads that are bigger than
+ <a class="xref" href="runtime-config-resource.html#GUC-SHARED-BUFFERS">shared_buffers</a>, but smaller than the OS's page cache.
+ </p><p>
+ The number of WAL segment files in <code class="filename">pg_wal</code> directory depends on
+ <code class="varname">min_wal_size</code>, <code class="varname">max_wal_size</code> and
+ the amount of WAL generated in previous checkpoint cycles. When old log
+ segment files are no longer needed, they are removed or recycled (that is,
+ renamed to become future segments in the numbered sequence). If, due to a
+ short-term peak of log output rate, <code class="varname">max_wal_size</code> is
+ exceeded, the unneeded segment files will be removed until the system
+ gets back under this limit. Below that limit, the system recycles enough
+ WAL files to cover the estimated need until the next checkpoint, and
+ removes the rest. The estimate is based on a moving average of the number
+ of WAL files used in previous checkpoint cycles. The moving average
+ is increased immediately if the actual usage exceeds the estimate, so it
+ accommodates peak usage rather than average usage to some extent.
+ <code class="varname">min_wal_size</code> puts a minimum on the amount of WAL files
+ recycled for future usage; that much WAL is always recycled for future use,
+ even if the system is idle and the WAL usage estimate suggests that little
+ WAL is needed.
+ </p><p>
+ Independently of <code class="varname">max_wal_size</code>,
+ the most recent <a class="xref" href="runtime-config-replication.html#GUC-WAL-KEEP-SIZE">wal_keep_size</a> megabytes of
+ WAL files plus one additional WAL file are
+ kept at all times. Also, if WAL archiving is used, old segments cannot be
+ removed or recycled until they are archived. If WAL archiving cannot keep up
+ with the pace that WAL is generated, or if <code class="varname">archive_command</code>
+ or <code class="varname">archive_library</code>
+ fails repeatedly, old WAL files will accumulate in <code class="filename">pg_wal</code>
+ until the situation is resolved. A slow or failed standby server that
+ uses a replication slot will have the same effect (see
+ <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-SLOTS" title="27.2.6. Replication Slots">Section 27.2.6</a>).
+ </p><p>
+ In archive recovery or standby mode, the server periodically performs
+ <em class="firstterm">restartpoints</em>,<a id="id-1.6.17.7.12.2" class="indexterm"></a>
+ which are similar to checkpoints in normal operation: the server forces
+ all its state to disk, updates the <code class="filename">pg_control</code> file to
+ indicate that the already-processed WAL data need not be scanned again,
+ and then recycles any old log segment files in the <code class="filename">pg_wal</code>
+ directory.
+ Restartpoints can't be performed more frequently than checkpoints on the
+ primary because restartpoints can only be performed at checkpoint records.
+ A restartpoint is triggered when a checkpoint record is reached if at
+ least <code class="varname">checkpoint_timeout</code> seconds have passed since the last
+ restartpoint, or if WAL size is about to exceed
+ <code class="varname">max_wal_size</code>. However, because of limitations on when a
+ restartpoint can be performed, <code class="varname">max_wal_size</code> is often exceeded
+ during recovery, by up to one checkpoint cycle's worth of WAL.
+ (<code class="varname">max_wal_size</code> is never a hard limit anyway, so you should
+ always leave plenty of headroom to avoid running out of disk space.)
+ </p><p>
+ There are two commonly used internal <acronym class="acronym">WAL</acronym> functions:
+ <code class="function">XLogInsertRecord</code> and <code class="function">XLogFlush</code>.
+ <code class="function">XLogInsertRecord</code> is used to place a new record into
+ the <acronym class="acronym">WAL</acronym> buffers in shared memory. If there is no
+ space for the new record, <code class="function">XLogInsertRecord</code> will have
+ to write (move to kernel cache) a few filled <acronym class="acronym">WAL</acronym>
+ buffers. This is undesirable because <code class="function">XLogInsertRecord</code>
+ is used on every database low level modification (for example, row
+ insertion) at a time when an exclusive lock is held on affected
+ data pages, so the operation needs to be as fast as possible. What
+ is worse, writing <acronym class="acronym">WAL</acronym> buffers might also force the
+ creation of a new log segment, which takes even more
+ time. Normally, <acronym class="acronym">WAL</acronym> buffers should be written
+ and flushed by an <code class="function">XLogFlush</code> request, which is
+ made, for the most part, at transaction commit time to ensure that
+ transaction records are flushed to permanent storage. On systems
+ with high log output, <code class="function">XLogFlush</code> requests might
+ not occur often enough to prevent <code class="function">XLogInsertRecord</code>
+ from having to do writes. On such systems
+ one should increase the number of <acronym class="acronym">WAL</acronym> buffers by
+ modifying the <a class="xref" href="runtime-config-wal.html#GUC-WAL-BUFFERS">wal_buffers</a> parameter. When
+ <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a> is set and the system is very busy,
+ setting <code class="varname">wal_buffers</code> higher will help smooth response times
+ during the period immediately following each checkpoint.
+ </p><p>
+ The <a class="xref" href="runtime-config-wal.html#GUC-COMMIT-DELAY">commit_delay</a> parameter defines for how many
+ microseconds a group commit leader process will sleep after acquiring a
+ lock within <code class="function">XLogFlush</code>, while group commit
+ followers queue up behind the leader. This delay allows other server
+ processes to add their commit records to the WAL buffers so that all of
+ them will be flushed by the leader's eventual sync operation. No sleep
+ will occur if <a class="xref" href="runtime-config-wal.html#GUC-FSYNC">fsync</a> is not enabled, or if fewer
+ than <a class="xref" href="runtime-config-wal.html#GUC-COMMIT-SIBLINGS">commit_siblings</a> other sessions are currently
+ in active transactions; this avoids sleeping when it's unlikely that
+ any other session will commit soon. Note that on some platforms, the
+ resolution of a sleep request is ten milliseconds, so that any nonzero
+ <code class="varname">commit_delay</code> setting between 1 and 10000
+ microseconds would have the same effect. Note also that on some
+ platforms, sleep operations may take slightly longer than requested by
+ the parameter.
+ </p><p>
+ Since the purpose of <code class="varname">commit_delay</code> is to allow the
+ cost of each flush operation to be amortized across concurrently
+ committing transactions (potentially at the expense of transaction
+ latency), it is necessary to quantify that cost before the setting can
+ be chosen intelligently. The higher that cost is, the more effective
+ <code class="varname">commit_delay</code> is expected to be in increasing
+ transaction throughput, up to a point. The <a class="xref" href="pgtestfsync.html" title="pg_test_fsync"><span class="refentrytitle"><span class="application">pg_test_fsync</span></span></a> program can be used to measure the average time
+ in microseconds that a single WAL flush operation takes. A value of
+ half of the average time the program reports it takes to flush after a
+ single 8kB write operation is often the most effective setting for
+ <code class="varname">commit_delay</code>, so this value is recommended as the
+ starting point to use when optimizing for a particular workload. While
+ tuning <code class="varname">commit_delay</code> is particularly useful when the
+ WAL log is stored on high-latency rotating disks, benefits can be
+ significant even on storage media with very fast sync times, such as
+ solid-state drives or RAID arrays with a battery-backed write cache;
+ but this should definitely be tested against a representative workload.
+ Higher values of <code class="varname">commit_siblings</code> should be used in
+ such cases, whereas smaller <code class="varname">commit_siblings</code> values
+ are often helpful on higher latency media. Note that it is quite
+ possible that a setting of <code class="varname">commit_delay</code> that is too
+ high can increase transaction latency by so much that total transaction
+ throughput suffers.
+ </p><p>
+ When <code class="varname">commit_delay</code> is set to zero (the default), it
+ is still possible for a form of group commit to occur, but each group
+ will consist only of sessions that reach the point where they need to
+ flush their commit records during the window in which the previous
+ flush operation (if any) is occurring. At higher client counts a
+ <span class="quote">“<span class="quote">gangway effect</span>”</span> tends to occur, so that the effects of group
+ commit become significant even when <code class="varname">commit_delay</code> is
+ zero, and thus explicitly setting <code class="varname">commit_delay</code> tends
+ to help less. Setting <code class="varname">commit_delay</code> can only help
+ when (1) there are some concurrently committing transactions, and (2)
+ throughput is limited to some degree by commit rate; but with high
+ rotational latency this setting can be effective in increasing
+ transaction throughput with as few as two clients (that is, a single
+ committing client with one sibling transaction).
+ </p><p>
+ The <a class="xref" href="runtime-config-wal.html#GUC-WAL-SYNC-METHOD">wal_sync_method</a> parameter determines how
+ <span class="productname">PostgreSQL</span> will ask the kernel to force
+ <acronym class="acronym">WAL</acronym> updates out to disk.
+ All the options should be the same in terms of reliability, with
+ the exception of <code class="literal">fsync_writethrough</code>, which can sometimes
+ force a flush of the disk cache even when other options do not do so.
+ However, it's quite platform-specific which one will be the fastest.
+ You can test the speeds of different options using the <a class="xref" href="pgtestfsync.html" title="pg_test_fsync"><span class="refentrytitle"><span class="application">pg_test_fsync</span></span></a> program.
+ Note that this parameter is irrelevant if <code class="varname">fsync</code>
+ has been turned off.
+ </p><p>
+ Enabling the <a class="xref" href="runtime-config-developer.html#GUC-WAL-DEBUG">wal_debug</a> configuration parameter
+ (provided that <span class="productname">PostgreSQL</span> has been
+ compiled with support for it) will result in each
+ <code class="function">XLogInsertRecord</code> and <code class="function">XLogFlush</code>
+ <acronym class="acronym">WAL</acronym> call being logged to the server log. This
+ option might be replaced by a more general mechanism in the future.
+ </p><p>
+ There are two internal functions to write WAL data to disk:
+ <code class="function">XLogWrite</code> and <code class="function">issue_xlog_fsync</code>.
+ When <a class="xref" href="runtime-config-statistics.html#GUC-TRACK-WAL-IO-TIMING">track_wal_io_timing</a> is enabled, the total
+ amounts of time <code class="function">XLogWrite</code> writes and
+ <code class="function">issue_xlog_fsync</code> syncs WAL data to disk are counted as
+ <code class="literal">wal_write_time</code> and <code class="literal">wal_sync_time</code> in
+ <a class="xref" href="monitoring-stats.html#PG-STAT-WAL-VIEW" title="Table 28.24. pg_stat_wal View">pg_stat_wal</a>, respectively.
+ <code class="function">XLogWrite</code> is normally called by
+ <code class="function">XLogInsertRecord</code> (when there is no space for the new
+ record in WAL buffers), <code class="function">XLogFlush</code> and the WAL writer,
+ to write WAL buffers to disk and call <code class="function">issue_xlog_fsync</code>.
+ <code class="function">issue_xlog_fsync</code> is normally called by
+ <code class="function">XLogWrite</code> to sync WAL files to disk.
+ If <code class="varname">wal_sync_method</code> is either
+ <code class="literal">open_datasync</code> or <code class="literal">open_sync</code>,
+ a write operation in <code class="function">XLogWrite</code> guarantees to sync written
+ WAL data to disk and <code class="function">issue_xlog_fsync</code> does nothing.
+ If <code class="varname">wal_sync_method</code> is either <code class="literal">fdatasync</code>,
+ <code class="literal">fsync</code>, or <code class="literal">fsync_writethrough</code>,
+ the write operation moves WAL buffers to kernel cache and
+ <code class="function">issue_xlog_fsync</code> syncs them to disk. Regardless
+ of the setting of <code class="varname">track_wal_io_timing</code>, the number
+ of times <code class="function">XLogWrite</code> writes and
+ <code class="function">issue_xlog_fsync</code> syncs WAL data to disk are also
+ counted as <code class="literal">wal_write</code> and <code class="literal">wal_sync</code>
+ in <code class="structname">pg_stat_wal</code>, respectively.
+ </p><p>
+ The <a class="xref" href="runtime-config-wal.html#GUC-RECOVERY-PREFETCH">recovery_prefetch</a> parameter can be used to reduce
+ I/O wait times during recovery by instructing the kernel to initiate reads
+ of disk blocks that will soon be needed but are not currently in
+ <span class="productname">PostgreSQL</span>'s buffer pool.
+ The <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-IO-CONCURRENCY">maintenance_io_concurrency</a> and
+ <a class="xref" href="runtime-config-wal.html#GUC-WAL-DECODE-BUFFER-SIZE">wal_decode_buffer_size</a> settings limit prefetching
+ concurrency and distance, respectively. By default, it is set to
+ <code class="literal">try</code>, which enables the feature on systems where
+ <code class="function">posix_fadvise</code> is available.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="wal-async-commit.html" title="30.4. Asynchronous Commit">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="wal-internals.html" title="30.6. WAL Internals">Next</a></td></tr><tr><td width="40%" align="left" valign="top">30.4. Asynchronous Commit </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 30.6. WAL Internals</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/wal-internals.html b/doc/src/sgml/html/wal-internals.html
new file mode 100644
index 0000000..10fb749
--- /dev/null
+++ b/doc/src/sgml/html/wal-internals.html
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>30.6. WAL Internals</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="wal-configuration.html" title="30.5. WAL Configuration" /><link rel="next" href="logical-replication.html" title="Chapter 31. Logical Replication" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">30.6. WAL Internals</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="wal-configuration.html" title="30.5. WAL Configuration">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><th width="60%" align="center">Chapter 30. Reliability and the Write-Ahead Log</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="logical-replication.html" title="Chapter 31. Logical Replication">Next</a></td></tr></table><hr /></div><div class="sect1" id="WAL-INTERNALS"><div class="titlepage"><div><div><h2 class="title" style="clear: both">30.6. WAL Internals</h2></div></div></div><a id="id-1.6.17.8.2" class="indexterm"></a><p>
+ <acronym class="acronym">WAL</acronym> is automatically enabled; no action is
+ required from the administrator except ensuring that the
+ disk-space requirements for the <acronym class="acronym">WAL</acronym> logs are met,
+ and that any necessary tuning is done (see <a class="xref" href="wal-configuration.html" title="30.5. WAL Configuration">Section 30.5</a>).
+ </p><p>
+ <acronym class="acronym">WAL</acronym> records are appended to the <acronym class="acronym">WAL</acronym>
+ logs as each new record is written. The insert position is described by
+ a Log Sequence Number (<acronym class="acronym">LSN</acronym>) that is a byte offset into
+ the logs, increasing monotonically with each new record.
+ <acronym class="acronym">LSN</acronym> values are returned as the datatype
+ <a class="link" href="datatype-pg-lsn.html" title="8.20. pg_lsn Type"><code class="type">pg_lsn</code></a>. Values can be
+ compared to calculate the volume of <acronym class="acronym">WAL</acronym> data that
+ separates them, so they are used to measure the progress of replication
+ and recovery.
+ </p><p>
+ <acronym class="acronym">WAL</acronym> logs are stored in the directory
+ <code class="filename">pg_wal</code> under the data directory, as a set of
+ segment files, normally each 16 MB in size (but the size can be changed
+ by altering the <code class="option">--wal-segsize</code> <span class="application">initdb</span> option). Each segment is
+ divided into pages, normally 8 kB each (this size can be changed via the
+ <code class="option">--with-wal-blocksize</code> configure option). The log record headers
+ are described in <code class="filename">access/xlogrecord.h</code>; the record
+ content is dependent on the type of event that is being logged. Segment
+ files are given ever-increasing numbers as names, starting at
+ <code class="filename">000000010000000000000001</code>. The numbers do not wrap,
+ but it will take a very, very long time to exhaust the
+ available stock of numbers.
+ </p><p>
+ It is advantageous if the log is located on a different disk from the
+ main database files. This can be achieved by moving the
+ <code class="filename">pg_wal</code> directory to another location (while the server
+ is shut down, of course) and creating a symbolic link from the
+ original location in the main data directory to the new location.
+ </p><p>
+ The aim of <acronym class="acronym">WAL</acronym> is to ensure that the log is
+ written before database records are altered, but this can be subverted by
+ disk drives<a id="id-1.6.17.8.7.2" class="indexterm"></a> that falsely report a
+ successful write to the kernel,
+ when in fact they have only cached the data and not yet stored it
+ on the disk. A power failure in such a situation might lead to
+ irrecoverable data corruption. Administrators should try to ensure
+ that disks holding <span class="productname">PostgreSQL</span>'s
+ <acronym class="acronym">WAL</acronym> log files do not make such false reports.
+ (See <a class="xref" href="wal-reliability.html" title="30.1. Reliability">Section 30.1</a>.)
+ </p><p>
+ After a checkpoint has been made and the log flushed, the
+ checkpoint's position is saved in the file
+ <code class="filename">pg_control</code>. Therefore, at the start of recovery,
+ the server first reads <code class="filename">pg_control</code> and
+ then the checkpoint record; then it performs the REDO operation by
+ scanning forward from the log location indicated in the checkpoint
+ record. Because the entire content of data pages is saved in the
+ log on the first page modification after a checkpoint (assuming
+ <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a> is not disabled), all pages
+ changed since the checkpoint will be restored to a consistent
+ state.
+ </p><p>
+ To deal with the case where <code class="filename">pg_control</code> is
+ corrupt, we should support the possibility of scanning existing log
+ segments in reverse order — newest to oldest — in order to find the
+ latest checkpoint. This has not been implemented yet.
+ <code class="filename">pg_control</code> is small enough (less than one disk page)
+ that it is not subject to partial-write problems, and as of this writing
+ there have been no reports of database failures due solely to the inability
+ to read <code class="filename">pg_control</code> itself. So while it is
+ theoretically a weak spot, <code class="filename">pg_control</code> does not
+ seem to be a problem in practice.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="wal-configuration.html" title="30.5. WAL Configuration">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="logical-replication.html" title="Chapter 31. Logical Replication">Next</a></td></tr><tr><td width="40%" align="left" valign="top">30.5. <acronym class="acronym">WAL</acronym> Configuration </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 31. Logical Replication</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/wal-intro.html b/doc/src/sgml/html/wal-intro.html
new file mode 100644
index 0000000..49d3319
--- /dev/null
+++ b/doc/src/sgml/html/wal-intro.html
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>30.3. Write-Ahead Logging (WAL)</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="checksums.html" title="30.2. Data Checksums" /><link rel="next" href="wal-async-commit.html" title="30.4. Asynchronous Commit" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">30.3. Write-Ahead Logging (<acronym class="acronym">WAL</acronym>)</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="checksums.html" title="30.2. Data Checksums">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><th width="60%" align="center">Chapter 30. Reliability and the Write-Ahead Log</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="wal-async-commit.html" title="30.4. Asynchronous Commit">Next</a></td></tr></table><hr /></div><div class="sect1" id="WAL-INTRO"><div class="titlepage"><div><div><h2 class="title" style="clear: both">30.3. Write-Ahead Logging (<acronym class="acronym">WAL</acronym>)</h2></div></div></div><a id="id-1.6.17.5.2" class="indexterm"></a><a id="id-1.6.17.5.3" class="indexterm"></a><p>
+ <em class="firstterm">Write-Ahead Logging</em> (<acronym class="acronym">WAL</acronym>)
+ is a standard method for ensuring data integrity. A detailed
+ description can be found in most (if not all) books about
+ transaction processing. Briefly, <acronym class="acronym">WAL</acronym>'s central
+ concept is that changes to data files (where tables and indexes
+ reside) must be written only after those changes have been logged,
+ that is, after log records describing the changes have been flushed
+ to permanent storage. If we follow this procedure, we do not need
+ to flush data pages to disk on every transaction commit, because we
+ know that in the event of a crash we will be able to recover the
+ database using the log: any changes that have not been applied to
+ the data pages can be redone from the log records. (This is
+ roll-forward recovery, also known as REDO.)
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ Because <acronym class="acronym">WAL</acronym> restores database file
+ contents after a crash, journaled file systems are not necessary for
+ reliable storage of the data files or WAL files. In fact, journaling
+ overhead can reduce performance, especially if journaling
+ causes file system <span class="emphasis"><em>data</em></span> to be flushed
+ to disk. Fortunately, data flushing during journaling can
+ often be disabled with a file system mount option, e.g.,
+ <code class="literal">data=writeback</code> on a Linux ext3 file system.
+ Journaled file systems do improve boot speed after a crash.
+ </p></div><p>
+ Using <acronym class="acronym">WAL</acronym> results in a
+ significantly reduced number of disk writes, because only the log
+ file needs to be flushed to disk to guarantee that a transaction is
+ committed, rather than every data file changed by the transaction.
+ The log file is written sequentially,
+ and so the cost of syncing the log is much less than the cost of
+ flushing the data pages. This is especially true for servers
+ handling many small transactions touching different parts of the data
+ store. Furthermore, when the server is processing many small concurrent
+ transactions, one <code class="function">fsync</code> of the log file may
+ suffice to commit many transactions.
+ </p><p>
+ <acronym class="acronym">WAL</acronym> also makes it possible to support on-line
+ backup and point-in-time recovery, as described in <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>. By archiving the WAL data we can support
+ reverting to any time instant covered by the available WAL data:
+ we simply install a prior physical backup of the database, and
+ replay the WAL log just as far as the desired time. What's more,
+ the physical backup doesn't have to be an instantaneous snapshot
+ of the database state — if it is made over some period of time,
+ then replaying the WAL log for that period will fix any internal
+ inconsistencies.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="checksums.html" title="30.2. Data Checksums">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="wal-async-commit.html" title="30.4. Asynchronous Commit">Next</a></td></tr><tr><td width="40%" align="left" valign="top">30.2. Data Checksums </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 30.4. Asynchronous Commit</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/wal-reliability.html b/doc/src/sgml/html/wal-reliability.html
new file mode 100644
index 0000000..8cac3cf
--- /dev/null
+++ b/doc/src/sgml/html/wal-reliability.html
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>30.1. Reliability</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log" /><link rel="next" href="checksums.html" title="30.2. Data Checksums" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">30.1. Reliability</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><th width="60%" align="center">Chapter 30. Reliability and the Write-Ahead Log</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="checksums.html" title="30.2. Data Checksums">Next</a></td></tr></table><hr /></div><div class="sect1" id="WAL-RELIABILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">30.1. Reliability</h2></div></div></div><p>
+ Reliability is an important property of any serious database
+ system, and <span class="productname">PostgreSQL</span> does everything possible to
+ guarantee reliable operation. One aspect of reliable operation is
+ that all data recorded by a committed transaction should be stored
+ in a nonvolatile area that is safe from power loss, operating
+ system failure, and hardware failure (except failure of the
+ nonvolatile area itself, of course). Successfully writing the data
+ to the computer's permanent storage (disk drive or equivalent)
+ ordinarily meets this requirement. In fact, even if a computer is
+ fatally damaged, if the disk drives survive they can be moved to
+ another computer with similar hardware and all committed
+ transactions will remain intact.
+ </p><p>
+ While forcing data to the disk platters periodically might seem like
+ a simple operation, it is not. Because disk drives are dramatically
+ slower than main memory and CPUs, several layers of caching exist
+ between the computer's main memory and the disk platters.
+ First, there is the operating system's buffer cache, which caches
+ frequently requested disk blocks and combines disk writes. Fortunately,
+ all operating systems give applications a way to force writes from
+ the buffer cache to disk, and <span class="productname">PostgreSQL</span> uses those
+ features. (See the <a class="xref" href="runtime-config-wal.html#GUC-WAL-SYNC-METHOD">wal_sync_method</a> parameter
+ to adjust how this is done.)
+ </p><p>
+ Next, there might be a cache in the disk drive controller; this is
+ particularly common on <acronym class="acronym">RAID</acronym> controller cards. Some of
+ these caches are <em class="firstterm">write-through</em>, meaning writes are sent
+ to the drive as soon as they arrive. Others are
+ <em class="firstterm">write-back</em>, meaning data is sent to the drive at
+ some later time. Such caches can be a reliability hazard because the
+ memory in the disk controller cache is volatile, and will lose its
+ contents in a power failure. Better controller cards have
+ <em class="firstterm">battery-backup units</em> (<acronym class="acronym">BBU</acronym>s), meaning
+ the card has a battery that
+ maintains power to the cache in case of system power loss. After power
+ is restored the data will be written to the disk drives.
+ </p><p>
+ And finally, most disk drives have caches. Some are write-through
+ while some are write-back, and the same concerns about data loss
+ exist for write-back drive caches as for disk controller
+ caches. Consumer-grade IDE and SATA drives are particularly likely
+ to have write-back caches that will not survive a power failure. Many
+ solid-state drives (SSD) also have volatile write-back caches.
+ </p><p>
+ These caches can typically be disabled; however, the method for doing
+ this varies by operating system and drive type:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ On <span class="productname">Linux</span>, IDE and SATA drives can be queried using
+ <code class="command">hdparm -I</code>; write caching is enabled if there is
+ a <code class="literal">*</code> next to <code class="literal">Write cache</code>. <code class="command">hdparm -W 0</code>
+ can be used to turn off write caching. SCSI drives can be queried
+ using <a class="ulink" href="http://sg.danny.cz/sg/sdparm.html" target="_top"><span class="application">sdparm</span></a>.
+ Use <code class="command">sdparm --get=WCE</code> to check
+ whether the write cache is enabled and <code class="command">sdparm --clear=WCE</code>
+ to disable it.
+ </p></li><li class="listitem"><p>
+ On <span class="productname">FreeBSD</span>, IDE drives can be queried using
+ <code class="command">atacontrol</code> and write caching turned off using
+ <code class="literal">hw.ata.wc=0</code> in <code class="filename">/boot/loader.conf</code>;
+ SCSI drives can be queried using <code class="command">camcontrol identify</code>,
+ and the write cache both queried and changed using
+ <code class="command">sdparm</code> when available.
+ </p></li><li class="listitem"><p>
+ On <span class="productname">Solaris</span>, the disk write cache is controlled by
+ <code class="command">format -e</code>.
+ (The Solaris <acronym class="acronym">ZFS</acronym> file system is safe with disk write-cache
+ enabled because it issues its own disk cache flush commands.)
+ </p></li><li class="listitem"><p>
+ On <span class="productname">Windows</span>, if <code class="varname">wal_sync_method</code> is
+ <code class="literal">open_datasync</code> (the default), write caching can be disabled
+ by unchecking <code class="literal">My Computer\Open\<em class="replaceable"><code>disk drive</code></em>\Properties\Hardware\Properties\Policies\Enable write caching on the disk</code>.
+ Alternatively, set <code class="varname">wal_sync_method</code> to
+ <code class="literal">fsync</code> or <code class="literal">fsync_writethrough</code>, which prevent
+ write caching.
+ </p></li><li class="listitem"><p>
+ On <span class="productname">macOS</span>, write caching can be prevented by
+ setting <code class="varname">wal_sync_method</code> to <code class="literal">fsync_writethrough</code>.
+ </p></li></ul></div><p>
+ Recent SATA drives (those following <acronym class="acronym">ATAPI-6</acronym> or later)
+ offer a drive cache flush command (<code class="command">FLUSH CACHE EXT</code>),
+ while SCSI drives have long supported a similar command
+ <code class="command">SYNCHRONIZE CACHE</code>. These commands are not directly
+ accessible to <span class="productname">PostgreSQL</span>, but some file systems
+ (e.g., <acronym class="acronym">ZFS</acronym>, <acronym class="acronym">ext4</acronym>) can use them to flush
+ data to the platters on write-back-enabled drives. Unfortunately, such
+ file systems behave suboptimally when combined with battery-backup unit
+ (<acronym class="acronym">BBU</acronym>) disk controllers. In such setups, the synchronize
+ command forces all data from the controller cache to the disks,
+ eliminating much of the benefit of the BBU. You can run the
+ <a class="xref" href="pgtestfsync.html" title="pg_test_fsync"><span class="refentrytitle"><span class="application">pg_test_fsync</span></span></a> program to see
+ if you are affected. If you are affected, the performance benefits
+ of the BBU can be regained by turning off write barriers in
+ the file system or reconfiguring the disk controller, if that is
+ an option. If write barriers are turned off, make sure the battery
+ remains functional; a faulty battery can potentially lead to data loss.
+ Hopefully file system and disk controller designers will eventually
+ address this suboptimal behavior.
+ </p><p>
+ When the operating system sends a write request to the storage hardware,
+ there is little it can do to make sure the data has arrived at a truly
+ non-volatile storage area. Rather, it is the
+ administrator's responsibility to make certain that all storage components
+ ensure integrity for both data and file-system metadata.
+ Avoid disk controllers that have non-battery-backed write caches.
+ At the drive level, disable write-back caching if the
+ drive cannot guarantee the data will be written before shutdown.
+ If you use SSDs, be aware that many of these do not honor cache flush
+ commands by default.
+ You can test for reliable I/O subsystem behavior using <a class="ulink" href="https://brad.livejournal.com/2116715.html" target="_top"><code class="filename">diskchecker.pl</code></a>.
+ </p><p>
+ Another risk of data loss is posed by the disk platter write
+ operations themselves. Disk platters are divided into sectors,
+ commonly 512 bytes each. Every physical read or write operation
+ processes a whole sector.
+ When a write request arrives at the drive, it might be for some multiple
+ of 512 bytes (<span class="productname">PostgreSQL</span> typically writes 8192 bytes, or
+ 16 sectors, at a time), and the process of writing could fail due
+ to power loss at any time, meaning some of the 512-byte sectors were
+ written while others were not. To guard against such failures,
+ <span class="productname">PostgreSQL</span> periodically writes full page images to
+ permanent WAL storage <span class="emphasis"><em>before</em></span> modifying the actual page on
+ disk. By doing this, during crash recovery <span class="productname">PostgreSQL</span> can
+ restore partially-written pages from WAL. If you have file-system software
+ that prevents partial page writes (e.g., ZFS), you can turn off
+ this page imaging by turning off the <a class="xref" href="runtime-config-wal.html#GUC-FULL-PAGE-WRITES">full_page_writes</a> parameter. Battery-Backed Unit
+ (BBU) disk controllers do not prevent partial page writes unless
+ they guarantee that data is written to the BBU as full (8kB) pages.
+ </p><p>
+ <span class="productname">PostgreSQL</span> also protects against some kinds of data corruption
+ on storage devices that may occur because of hardware errors or media failure over time,
+ such as reading/writing garbage data.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Each individual record in a WAL file is protected by a CRC-32 (32-bit) check
+ that allows us to tell if record contents are correct. The CRC value
+ is set when we write each WAL record and checked during crash recovery,
+ archive recovery and replication.
+ </p></li><li class="listitem"><p>
+ Data pages are not currently checksummed by default, though full page images
+ recorded in WAL records will be protected; see <a class="link" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS"><span class="application">initdb</span></a>
+ for details about enabling data checksums.
+ </p></li><li class="listitem"><p>
+ Internal data structures such as <code class="filename">pg_xact</code>, <code class="filename">pg_subtrans</code>, <code class="filename">pg_multixact</code>,
+ <code class="filename">pg_serial</code>, <code class="filename">pg_notify</code>, <code class="filename">pg_stat</code>, <code class="filename">pg_snapshots</code> are not directly
+ checksummed, nor are pages protected by full page writes. However, where
+ such data structures are persistent, WAL records are written that allow
+ recent changes to be accurately rebuilt at crash recovery and those
+ WAL records are protected as discussed above.
+ </p></li><li class="listitem"><p>
+ Individual state files in <code class="filename">pg_twophase</code> are protected by CRC-32.
+ </p></li><li class="listitem"><p>
+ Temporary data files used in larger SQL queries for sorts,
+ materializations and intermediate results are not currently checksummed,
+ nor will WAL records be written for changes to those files.
+ </p></li></ul></div><p>
+ </p><p>
+ <span class="productname">PostgreSQL</span> does not protect against correctable memory errors
+ and it is assumed you will operate using RAM that uses industry standard
+ Error Correcting Codes (ECC) or better protection.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="wal.html" title="Chapter 30. Reliability and the Write-Ahead Log">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="checksums.html" title="30.2. Data Checksums">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 30. Reliability and the Write-Ahead Log </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 30.2. Data Checksums</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/wal.html b/doc/src/sgml/html/wal.html
new file mode 100644
index 0000000..fd97a64
--- /dev/null
+++ b/doc/src/sgml/html/wal.html
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 30. Reliability and the Write-Ahead Log</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="disk-full.html" title="29.2. Disk Full Failure" /><link rel="next" href="wal-reliability.html" title="30.1. Reliability" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 30. Reliability and the Write-Ahead Log</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="disk-full.html" title="29.2. Disk Full Failure">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><th width="60%" align="center">Part III. Server Administration</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="wal-reliability.html" title="30.1. Reliability">Next</a></td></tr></table><hr /></div><div class="chapter" id="WAL"><div class="titlepage"><div><div><h2 class="title">Chapter 30. Reliability and the Write-Ahead Log</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="wal-reliability.html">30.1. Reliability</a></span></dt><dt><span class="sect1"><a href="checksums.html">30.2. Data Checksums</a></span></dt><dd><dl><dt><span class="sect2"><a href="checksums.html#CHECKSUMS-OFFLINE-ENABLE-DISABLE">30.2.1. Off-line Enabling of Checksums</a></span></dt></dl></dd><dt><span class="sect1"><a href="wal-intro.html">30.3. Write-Ahead Logging (<acronym class="acronym">WAL</acronym>)</a></span></dt><dt><span class="sect1"><a href="wal-async-commit.html">30.4. Asynchronous Commit</a></span></dt><dt><span class="sect1"><a href="wal-configuration.html">30.5. <acronym class="acronym">WAL</acronym> Configuration</a></span></dt><dt><span class="sect1"><a href="wal-internals.html">30.6. WAL Internals</a></span></dt></dl></div><p>
+ This chapter explains how the Write-Ahead Log is used to obtain
+ efficient, reliable operation.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="disk-full.html" title="29.2. Disk Full Failure">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="admin.html" title="Part III. Server Administration">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="wal-reliability.html" title="30.1. Reliability">Next</a></td></tr><tr><td width="40%" align="left" valign="top">29.2. Disk Full Failure </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 30.1. Reliability</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/warm-standby-failover.html b/doc/src/sgml/html/warm-standby-failover.html
new file mode 100644
index 0000000..dd769dd
--- /dev/null
+++ b/doc/src/sgml/html/warm-standby-failover.html
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>27.3. Failover</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers" /><link rel="next" href="hot-standby.html" title="27.4. Hot Standby" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">27.3. Failover</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><th width="60%" align="center">Chapter 27. High Availability, Load Balancing, and Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="hot-standby.html" title="27.4. Hot Standby">Next</a></td></tr></table><hr /></div><div class="sect1" id="WARM-STANDBY-FAILOVER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">27.3. Failover</h2></div></div></div><p>
+ If the primary server fails then the standby server should begin
+ failover procedures.
+ </p><p>
+ If the standby server fails then no failover need take place. If the
+ standby server can be restarted, even some time later, then the recovery
+ process can also be restarted immediately, taking advantage of
+ restartable recovery. If the standby server cannot be restarted, then a
+ full new standby server instance should be created.
+ </p><p>
+ If the primary server fails and the standby server becomes the
+ new primary, and then the old primary restarts, you must have
+ a mechanism for informing the old primary that it is no longer the primary. This is
+ sometimes known as <acronym class="acronym">STONITH</acronym> (Shoot The Other Node In The Head), which is
+ necessary to avoid situations where both systems think they are the
+ primary, which will lead to confusion and ultimately data loss.
+ </p><p>
+ Many failover systems use just two systems, the primary and the standby,
+ connected by some kind of heartbeat mechanism to continually verify the
+ connectivity between the two and the viability of the primary. It is
+ also possible to use a third system (called a witness server) to prevent
+ some cases of inappropriate failover, but the additional complexity
+ might not be worthwhile unless it is set up with sufficient care and
+ rigorous testing.
+ </p><p>
+ <span class="productname">PostgreSQL</span> does not provide the system
+ software required to identify a failure on the primary and notify
+ the standby database server. Many such tools exist and are well
+ integrated with the operating system facilities required for
+ successful failover, such as IP address migration.
+ </p><p>
+ Once failover to the standby occurs, there is only a
+ single server in operation. This is known as a degenerate state.
+ The former standby is now the primary, but the former primary is down
+ and might stay down. To return to normal operation, a standby server
+ must be recreated,
+ either on the former primary system when it comes up, or on a third,
+ possibly new, system. The <a class="xref" href="app-pgrewind.html" title="pg_rewind"><span class="refentrytitle"><span class="application">pg_rewind</span></span></a> utility can be
+ used to speed up this process on large clusters.
+ Once complete, the primary and standby can be
+ considered to have switched roles. Some people choose to use a third
+ server to provide backup for the new primary until the new standby
+ server is recreated,
+ though clearly this complicates the system configuration and
+ operational processes.
+ </p><p>
+ So, switching from primary to standby server can be fast but requires
+ some time to re-prepare the failover cluster. Regular switching from
+ primary to standby is useful, since it allows regular downtime on
+ each system for maintenance. This also serves as a test of the
+ failover mechanism to ensure that it will really work when you need it.
+ Written administration procedures are advised.
+ </p><p>
+ To trigger failover of a log-shipping standby server, run
+ <code class="command">pg_ctl promote</code>, call <code class="function">pg_promote()</code>,
+ or create a trigger file with the file name and path specified by the
+ <code class="varname">promote_trigger_file</code>. If you're planning to use
+ <code class="command">pg_ctl promote</code> or to call
+ <code class="function">pg_promote()</code> to fail over,
+ <code class="varname">promote_trigger_file</code> is not required. If you're
+ setting up the reporting servers that are only used to offload read-only
+ queries from the primary, not for high availability purposes, you don't
+ need to promote it.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="hot-standby.html" title="27.4. Hot Standby">Next</a></td></tr><tr><td width="40%" align="left" valign="top">27.2. Log-Shipping Standby Servers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 27.4. Hot Standby</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/warm-standby.html b/doc/src/sgml/html/warm-standby.html
new file mode 100644
index 0000000..ab6f94a
--- /dev/null
+++ b/doc/src/sgml/html/warm-standby.html
@@ -0,0 +1,657 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>27.2. Log-Shipping Standby Servers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="different-replication-solutions.html" title="27.1. Comparison of Different Solutions" /><link rel="next" href="warm-standby-failover.html" title="27.3. Failover" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">27.2. Log-Shipping Standby Servers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="different-replication-solutions.html" title="27.1. Comparison of Different Solutions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><th width="60%" align="center">Chapter 27. High Availability, Load Balancing, and Replication</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="warm-standby-failover.html" title="27.3. Failover">Next</a></td></tr></table><hr /></div><div class="sect1" id="WARM-STANDBY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">27.2. Log-Shipping Standby Servers</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="warm-standby.html#STANDBY-PLANNING">27.2.1. Planning</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STANDBY-SERVER-OPERATION">27.2.2. Standby Server Operation</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#PREPARING-PRIMARY-FOR-STANDBY">27.2.3. Preparing the Primary for Standby Servers</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STANDBY-SERVER-SETUP">27.2.4. Setting Up a Standby Server</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STREAMING-REPLICATION">27.2.5. Streaming Replication</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#STREAMING-REPLICATION-SLOTS">27.2.6. Replication Slots</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#CASCADING-REPLICATION">27.2.7. Cascading Replication</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#SYNCHRONOUS-REPLICATION">27.2.8. Synchronous Replication</a></span></dt><dt><span class="sect2"><a href="warm-standby.html#CONTINUOUS-ARCHIVING-IN-STANDBY">27.2.9. Continuous Archiving in Standby</a></span></dt></dl></div><p>
+ Continuous archiving can be used to create a <em class="firstterm">high
+ availability</em> (HA) cluster configuration with one or more
+ <em class="firstterm">standby servers</em> ready to take over operations if the
+ primary server fails. This capability is widely referred to as
+ <em class="firstterm">warm standby</em> or <em class="firstterm">log shipping</em>.
+ </p><p>
+ The primary and standby server work together to provide this capability,
+ though the servers are only loosely coupled. The primary server operates
+ in continuous archiving mode, while each standby server operates in
+ continuous recovery mode, reading the WAL files from the primary. No
+ changes to the database tables are required to enable this capability,
+ so it offers low administration overhead compared to some other
+ replication solutions. This configuration also has relatively low
+ performance impact on the primary server.
+ </p><p>
+ Directly moving WAL records from one database server to another
+ is typically described as log shipping. <span class="productname">PostgreSQL</span>
+ implements file-based log shipping by transferring WAL records
+ one file (WAL segment) at a time. WAL files (16MB) can be
+ shipped easily and cheaply over any distance, whether it be to an
+ adjacent system, another system at the same site, or another system on
+ the far side of the globe. The bandwidth required for this technique
+ varies according to the transaction rate of the primary server.
+ Record-based log shipping is more granular and streams WAL changes
+ incrementally over a network connection (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>).
+ </p><p>
+ It should be noted that log shipping is asynchronous, i.e., the WAL
+ records are shipped after transaction commit. As a result, there is a
+ window for data loss should the primary server suffer a catastrophic
+ failure; transactions not yet shipped will be lost. The size of the
+ data loss window in file-based log shipping can be limited by use of the
+ <code class="varname">archive_timeout</code> parameter, which can be set as low
+ as a few seconds. However such a low setting will
+ substantially increase the bandwidth required for file shipping.
+ Streaming replication (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION" title="27.2.5. Streaming Replication">Section 27.2.5</a>)
+ allows a much smaller window of data loss.
+ </p><p>
+ Recovery performance is sufficiently good that the standby will
+ typically be only moments away from full
+ availability once it has been activated. As a result, this is called
+ a warm standby configuration which offers high
+ availability. Restoring a server from an archived base backup and
+ rollforward will take considerably longer, so that technique only
+ offers a solution for disaster recovery, not high availability.
+ A standby server can also be used for read-only queries, in which case
+ it is called a <em class="firstterm">hot standby</em> server. See
+ <a class="xref" href="hot-standby.html" title="27.4. Hot Standby">Section 27.4</a> for more information.
+ </p><a id="id-1.6.14.16.7" class="indexterm"></a><a id="id-1.6.14.16.8" class="indexterm"></a><a id="id-1.6.14.16.9" class="indexterm"></a><a id="id-1.6.14.16.10" class="indexterm"></a><a id="id-1.6.14.16.11" class="indexterm"></a><a id="id-1.6.14.16.12" class="indexterm"></a><div class="sect2" id="STANDBY-PLANNING"><div class="titlepage"><div><div><h3 class="title">27.2.1. Planning</h3></div></div></div><p>
+ It is usually wise to create the primary and standby servers
+ so that they are as similar as possible, at least from the
+ perspective of the database server. In particular, the path names
+ associated with tablespaces will be passed across unmodified, so both
+ primary and standby servers must have the same mount paths for
+ tablespaces if that feature is used. Keep in mind that if
+ <a class="xref" href="sql-createtablespace.html" title="CREATE TABLESPACE"><span class="refentrytitle">CREATE TABLESPACE</span></a>
+ is executed on the primary, any new mount point needed for it must
+ be created on the primary and all standby servers before the command
+ is executed. Hardware need not be exactly the same, but experience shows
+ that maintaining two identical systems is easier than maintaining two
+ dissimilar ones over the lifetime of the application and system.
+ In any case the hardware architecture must be the same — shipping
+ from, say, a 32-bit to a 64-bit system will not work.
+ </p><p>
+ In general, log shipping between servers running different major
+ <span class="productname">PostgreSQL</span> release
+ levels is not possible. It is the policy of the PostgreSQL Global
+ Development Group not to make changes to disk formats during minor release
+ upgrades, so it is likely that running different minor release levels
+ on primary and standby servers will work successfully. However, no
+ formal support for that is offered and you are advised to keep primary
+ and standby servers at the same release level as much as possible.
+ When updating to a new minor release, the safest policy is to update
+ the standby servers first — a new minor release is more likely
+ to be able to read WAL files from a previous minor release than vice
+ versa.
+ </p></div><div class="sect2" id="STANDBY-SERVER-OPERATION"><div class="titlepage"><div><div><h3 class="title">27.2.2. Standby Server Operation</h3></div></div></div><p>
+ A server enters standby mode if a
+ <span id="FILE-STANDBY-SIGNAL"></span>
+ <code class="filename">standby.signal</code>
+ <a id="id-1.6.14.16.14.2.3" class="indexterm"></a>
+ file exists in the data directory when the server is started.
+ </p><p>
+ In standby mode, the server continuously applies WAL received from the
+ primary server. The standby server can read WAL from a WAL archive
+ (see <a class="xref" href="runtime-config-wal.html#GUC-RESTORE-COMMAND">restore_command</a>) or directly from the primary
+ over a TCP connection (streaming replication). The standby server will
+ also attempt to restore any WAL found in the standby cluster's
+ <code class="filename">pg_wal</code> directory. That typically happens after a server
+ restart, when the standby replays again WAL that was streamed from the
+ primary before the restart, but you can also manually copy files to
+ <code class="filename">pg_wal</code> at any time to have them replayed.
+ </p><p>
+ At startup, the standby begins by restoring all WAL available in the
+ archive location, calling <code class="varname">restore_command</code>. Once it
+ reaches the end of WAL available there and <code class="varname">restore_command</code>
+ fails, it tries to restore any WAL available in the <code class="filename">pg_wal</code> directory.
+ If that fails, and streaming replication has been configured, the
+ standby tries to connect to the primary server and start streaming WAL
+ from the last valid record found in archive or <code class="filename">pg_wal</code>. If that fails
+ or streaming replication is not configured, or if the connection is
+ later disconnected, the standby goes back to step 1 and tries to
+ restore the file from the archive again. This loop of retries from the
+ archive, <code class="filename">pg_wal</code>, and via streaming replication goes on until the server
+ is stopped or failover is triggered by a trigger file.
+ </p><p>
+ Standby mode is exited and the server switches to normal operation
+ when <code class="command">pg_ctl promote</code> is run,
+ <code class="function">pg_promote()</code> is called, or a trigger file is found
+ (<code class="varname">promote_trigger_file</code>). Before failover,
+ any WAL immediately available in the archive or in <code class="filename">pg_wal</code> will be
+ restored, but no attempt is made to connect to the primary.
+ </p></div><div class="sect2" id="PREPARING-PRIMARY-FOR-STANDBY"><div class="titlepage"><div><div><h3 class="title">27.2.3. Preparing the Primary for Standby Servers</h3></div></div></div><p>
+ Set up continuous archiving on the primary to an archive directory
+ accessible from the standby, as described
+ in <a class="xref" href="continuous-archiving.html" title="26.3. Continuous Archiving and Point-in-Time Recovery (PITR)">Section 26.3</a>. The archive location should be
+ accessible from the standby even when the primary is down, i.e., it should
+ reside on the standby server itself or another trusted server, not on
+ the primary server.
+ </p><p>
+ If you want to use streaming replication, set up authentication on the
+ primary server to allow replication connections from the standby
+ server(s); that is, create a role and provide a suitable entry or
+ entries in <code class="filename">pg_hba.conf</code> with the database field set to
+ <code class="literal">replication</code>. Also ensure <code class="varname">max_wal_senders</code> is set
+ to a sufficiently large value in the configuration file of the primary
+ server. If replication slots will be used,
+ ensure that <code class="varname">max_replication_slots</code> is set sufficiently
+ high as well.
+ </p><p>
+ Take a base backup as described in <a class="xref" href="continuous-archiving.html#BACKUP-BASE-BACKUP" title="26.3.2. Making a Base Backup">Section 26.3.2</a>
+ to bootstrap the standby server.
+ </p></div><div class="sect2" id="STANDBY-SERVER-SETUP"><div class="titlepage"><div><div><h3 class="title">27.2.4. Setting Up a Standby Server</h3></div></div></div><p>
+ To set up the standby server, restore the base backup taken from primary
+ server (see <a class="xref" href="continuous-archiving.html#BACKUP-PITR-RECOVERY" title="26.3.4. Recovering Using a Continuous Archive Backup">Section 26.3.4</a>). Create a file
+ <a class="link" href="warm-standby.html#FILE-STANDBY-SIGNAL"><code class="filename">standby.signal</code></a><a id="id-1.6.14.16.16.2.3" class="indexterm"></a>
+ in the standby's cluster data
+ directory. Set <a class="xref" href="runtime-config-wal.html#GUC-RESTORE-COMMAND">restore_command</a> to a simple command to copy files from
+ the WAL archive. If you plan to have multiple standby servers for high
+ availability purposes, make sure that <code class="varname">recovery_target_timeline</code> is set to
+ <code class="literal">latest</code> (the default), to make the standby server follow the timeline change
+ that occurs at failover to another standby.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <a class="xref" href="runtime-config-wal.html#GUC-RESTORE-COMMAND">restore_command</a> should return immediately
+ if the file does not exist; the server will retry the command again if
+ necessary.
+ </p></div><p>
+ If you want to use streaming replication, fill in
+ <a class="xref" href="runtime-config-replication.html#GUC-PRIMARY-CONNINFO">primary_conninfo</a> with a libpq connection string, including
+ the host name (or IP address) and any additional details needed to
+ connect to the primary server. If the primary needs a password for
+ authentication, the password needs to be specified in
+ <a class="xref" href="runtime-config-replication.html#GUC-PRIMARY-CONNINFO">primary_conninfo</a> as well.
+ </p><p>
+ If you're setting up the standby server for high availability purposes,
+ set up WAL archiving, connections and authentication like the primary
+ server, because the standby server will work as a primary server after
+ failover.
+ </p><p>
+ If you're using a WAL archive, its size can be minimized using the <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-CLEANUP-COMMAND">archive_cleanup_command</a> parameter to remove files that are no
+ longer required by the standby server.
+ The <span class="application">pg_archivecleanup</span> utility is designed specifically to
+ be used with <code class="varname">archive_cleanup_command</code> in typical single-standby
+ configurations, see <a class="xref" href="pgarchivecleanup.html" title="pg_archivecleanup"><span class="refentrytitle"><span class="application">pg_archivecleanup</span></span></a>.
+ Note however, that if you're using the archive for backup purposes, you
+ need to retain files needed to recover from at least the latest base
+ backup, even if they're no longer needed by the standby.
+ </p><p>
+ A simple example of configuration is:
+</p><pre class="programlisting">
+primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000'''
+restore_command = 'cp /path/to/archive/%f %p'
+archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'
+</pre><p>
+ </p><p>
+ You can have any number of standby servers, but if you use streaming
+ replication, make sure you set <code class="varname">max_wal_senders</code> high enough in
+ the primary to allow them to be connected simultaneously.
+ </p></div><div class="sect2" id="STREAMING-REPLICATION"><div class="titlepage"><div><div><h3 class="title">27.2.5. Streaming Replication</h3></div></div></div><a id="id-1.6.14.16.17.2" class="indexterm"></a><p>
+ Streaming replication allows a standby server to stay more up-to-date
+ than is possible with file-based log shipping. The standby connects
+ to the primary, which streams WAL records to the standby as they're
+ generated, without waiting for the WAL file to be filled.
+ </p><p>
+ Streaming replication is asynchronous by default
+ (see <a class="xref" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="27.2.8. Synchronous Replication">Section 27.2.8</a>), in which case there is
+ a small delay between committing a transaction in the primary and the
+ changes becoming visible in the standby. This delay is however much
+ smaller than with file-based log shipping, typically under one second
+ assuming the standby is powerful enough to keep up with the load. With
+ streaming replication, <code class="varname">archive_timeout</code> is not required to
+ reduce the data loss window.
+ </p><p>
+ If you use streaming replication without file-based continuous
+ archiving, the server might recycle old WAL segments before the standby
+ has received them. If this occurs, the standby will need to be
+ reinitialized from a new base backup. You can avoid this by setting
+ <code class="varname">wal_keep_size</code> to a value large enough to ensure that
+ WAL segments are not recycled too early, or by configuring a replication
+ slot for the standby. If you set up a WAL archive that's accessible from
+ the standby, these solutions are not required, since the standby can
+ always use the archive to catch up provided it retains enough segments.
+ </p><p>
+ To use streaming replication, set up a file-based log-shipping standby
+ server as described in <a class="xref" href="warm-standby.html" title="27.2. Log-Shipping Standby Servers">Section 27.2</a>. The step that
+ turns a file-based log-shipping standby into streaming replication
+ standby is setting the <code class="varname">primary_conninfo</code> setting
+ to point to the primary server. Set
+ <a class="xref" href="runtime-config-connection.html#GUC-LISTEN-ADDRESSES">listen_addresses</a> and authentication options
+ (see <code class="filename">pg_hba.conf</code>) on the primary so that the standby server
+ can connect to the <code class="literal">replication</code> pseudo-database on the primary
+ server (see <a class="xref" href="warm-standby.html#STREAMING-REPLICATION-AUTHENTICATION" title="27.2.5.1. Authentication">Section 27.2.5.1</a>).
+ </p><p>
+ On systems that support the keepalive socket option, setting
+ <a class="xref" href="runtime-config-connection.html#GUC-TCP-KEEPALIVES-IDLE">tcp_keepalives_idle</a>,
+ <a class="xref" href="runtime-config-connection.html#GUC-TCP-KEEPALIVES-INTERVAL">tcp_keepalives_interval</a> and
+ <a class="xref" href="runtime-config-connection.html#GUC-TCP-KEEPALIVES-COUNT">tcp_keepalives_count</a> helps the primary promptly
+ notice a broken connection.
+ </p><p>
+ Set the maximum number of concurrent connections from the standby servers
+ (see <a class="xref" href="runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</a> for details).
+ </p><p>
+ When the standby is started and <code class="varname">primary_conninfo</code> is set
+ correctly, the standby will connect to the primary after replaying all
+ WAL files available in the archive. If the connection is established
+ successfully, you will see a <code class="literal">walreceiver</code> in the standby, and
+ a corresponding <code class="literal">walsender</code> process in the primary.
+ </p><div class="sect3" id="STREAMING-REPLICATION-AUTHENTICATION"><div class="titlepage"><div><div><h4 class="title">27.2.5.1. Authentication</h4></div></div></div><p>
+ It is very important that the access privileges for replication be set up
+ so that only trusted users can read the WAL stream, because it is
+ easy to extract privileged information from it. Standby servers must
+ authenticate to the primary as an account that has the
+ <code class="literal">REPLICATION</code> privilege or a superuser. It is
+ recommended to create a dedicated user account with
+ <code class="literal">REPLICATION</code> and <code class="literal">LOGIN</code>
+ privileges for replication. While <code class="literal">REPLICATION</code>
+ privilege gives very high permissions, it does not allow the user to
+ modify any data on the primary system, which the
+ <code class="literal">SUPERUSER</code> privilege does.
+ </p><p>
+ Client authentication for replication is controlled by a
+ <code class="filename">pg_hba.conf</code> record specifying <code class="literal">replication</code> in the
+ <em class="replaceable"><code>database</code></em> field. For example, if the standby is running on
+ host IP <code class="literal">192.168.1.100</code> and the account name for replication
+ is <code class="literal">foo</code>, the administrator can add the following line to the
+ <code class="filename">pg_hba.conf</code> file on the primary:
+
+</p><pre class="programlisting">
+# Allow the user "foo" from host 192.168.1.100 to connect to the primary
+# as a replication standby if the user's password is correctly supplied.
+#
+# TYPE DATABASE USER ADDRESS METHOD
+host replication foo 192.168.1.100/32 md5
+</pre><p>
+ </p><p>
+ The host name and port number of the primary, connection user name,
+ and password are specified in the <a class="xref" href="runtime-config-replication.html#GUC-PRIMARY-CONNINFO">primary_conninfo</a>.
+ The password can also be set in the <code class="filename">~/.pgpass</code> file on the
+ standby (specify <code class="literal">replication</code> in the <em class="replaceable"><code>database</code></em>
+ field).
+ For example, if the primary is running on host IP <code class="literal">192.168.1.50</code>,
+ port <code class="literal">5432</code>, the account name for replication is
+ <code class="literal">foo</code>, and the password is <code class="literal">foopass</code>, the administrator
+ can add the following line to the <code class="filename">postgresql.conf</code> file on the
+ standby:
+
+</p><pre class="programlisting">
+# The standby connects to the primary that is running on host 192.168.1.50
+# and port 5432 as the user "foo" whose password is "foopass".
+primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
+</pre><p>
+ </p></div><div class="sect3" id="STREAMING-REPLICATION-MONITORING"><div class="titlepage"><div><div><h4 class="title">27.2.5.2. Monitoring</h4></div></div></div><p>
+ An important health indicator of streaming replication is the amount
+ of WAL records generated in the primary, but not yet applied in the
+ standby. You can calculate this lag by comparing the current WAL write
+ location on the primary with the last WAL location received by the
+ standby. These locations can be retrieved using
+ <code class="function">pg_current_wal_lsn</code> on the primary and
+ <code class="function">pg_last_wal_receive_lsn</code> on the standby,
+ respectively (see <a class="xref" href="functions-admin.html#FUNCTIONS-ADMIN-BACKUP-TABLE" title="Table 9.89. Backup Control Functions">Table 9.89</a> and
+ <a class="xref" href="functions-admin.html#FUNCTIONS-RECOVERY-INFO-TABLE" title="Table 9.90. Recovery Information Functions">Table 9.90</a> for details).
+ The last WAL receive location in the standby is also displayed in the
+ process status of the WAL receiver process, displayed using the
+ <code class="command">ps</code> command (see <a class="xref" href="monitoring-ps.html" title="28.1. Standard Unix Tools">Section 28.1</a> for details).
+ </p><p>
+ You can retrieve a list of WAL sender processes via the
+ <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-REPLICATION-VIEW" title="28.2.4. pg_stat_replication"><code class="structname">
+ pg_stat_replication</code></a> view. Large differences between
+ <code class="function">pg_current_wal_lsn</code> and the view's <code class="literal">sent_lsn</code> field
+ might indicate that the primary server is under heavy load, while
+ differences between <code class="literal">sent_lsn</code> and
+ <code class="function">pg_last_wal_receive_lsn</code> on the standby might indicate
+ network delay, or that the standby is under heavy load.
+ </p><p>
+ On a hot standby, the status of the WAL receiver process can be retrieved
+ via the <a class="link" href="monitoring-stats.html#MONITORING-PG-STAT-WAL-RECEIVER-VIEW" title="28.2.6. pg_stat_wal_receiver">
+ <code class="structname">pg_stat_wal_receiver</code></a> view. A large
+ difference between <code class="function">pg_last_wal_replay_lsn</code> and the
+ view's <code class="literal">flushed_lsn</code> indicates that WAL is being
+ received faster than it can be replayed.
+ </p></div></div><div class="sect2" id="STREAMING-REPLICATION-SLOTS"><div class="titlepage"><div><div><h3 class="title">27.2.6. Replication Slots</h3></div></div></div><a id="id-1.6.14.16.18.2" class="indexterm"></a><p>
+ Replication slots provide an automated way to ensure that the primary does
+ not remove WAL segments until they have been received by all standbys,
+ and that the primary does not remove rows which could cause a
+ <a class="link" href="hot-standby.html#HOT-STANDBY-CONFLICT" title="27.4.2. Handling Query Conflicts">recovery conflict</a> even when the
+ standby is disconnected.
+ </p><p>
+ In lieu of using replication slots, it is possible to prevent the removal
+ of old WAL segments using <a class="xref" href="runtime-config-replication.html#GUC-WAL-KEEP-SIZE">wal_keep_size</a>, or by
+ storing the segments in an archive using
+ <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-COMMAND">archive_command</a> or <a class="xref" href="runtime-config-wal.html#GUC-ARCHIVE-LIBRARY">archive_library</a>.
+ However, these methods often result in retaining more WAL segments than
+ required, whereas replication slots retain only the number of segments
+ known to be needed. On the other hand, replication slots can retain so
+ many WAL segments that they fill up the space allocated
+ for <code class="literal">pg_wal</code>;
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-SLOT-WAL-KEEP-SIZE">max_slot_wal_keep_size</a> limits the size of WAL files
+ retained by replication slots.
+ </p><p>
+ Similarly, <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY-FEEDBACK">hot_standby_feedback</a>
+ and <a class="xref" href="runtime-config-replication.html#GUC-VACUUM-DEFER-CLEANUP-AGE">vacuum_defer_cleanup_age</a> provide protection against
+ relevant rows being removed by vacuum, but the former provides no
+ protection during any time period when the standby is not connected,
+ and the latter often needs to be set to a high value to provide adequate
+ protection. Replication slots overcome these disadvantages.
+ </p><div class="sect3" id="STREAMING-REPLICATION-SLOTS-MANIPULATION"><div class="titlepage"><div><div><h4 class="title">27.2.6.1. Querying and Manipulating Replication Slots</h4></div></div></div><p>
+ Each replication slot has a name, which can contain lower-case letters,
+ numbers, and the underscore character.
+ </p><p>
+ Existing replication slots and their state can be seen in the
+ <a class="link" href="view-pg-replication-slots.html" title="54.19. pg_replication_slots"><code class="structname">pg_replication_slots</code></a>
+ view.
+ </p><p>
+ Slots can be created and dropped either via the streaming replication
+ protocol (see <a class="xref" href="protocol-replication.html" title="55.4. Streaming Replication Protocol">Section 55.4</a>) or via SQL
+ functions (see <a class="xref" href="functions-admin.html#FUNCTIONS-REPLICATION" title="9.27.6. Replication Management Functions">Section 9.27.6</a>).
+ </p></div><div class="sect3" id="STREAMING-REPLICATION-SLOTS-CONFIG"><div class="titlepage"><div><div><h4 class="title">27.2.6.2. Configuration Example</h4></div></div></div><p>
+ You can create a replication slot like this:
+</p><pre class="programlisting">
+postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
+ slot_name | lsn
+-------------+-----
+ node_a_slot |
+
+postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
+ slot_name | slot_type | active
+-------------+-----------+--------
+ node_a_slot | physical | f
+(1 row)
+</pre><p>
+ To configure the standby to use this slot, <code class="varname">primary_slot_name</code>
+ should be configured on the standby. Here is a simple example:
+</p><pre class="programlisting">
+primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
+primary_slot_name = 'node_a_slot'
+</pre><p>
+ </p></div></div><div class="sect2" id="CASCADING-REPLICATION"><div class="titlepage"><div><div><h3 class="title">27.2.7. Cascading Replication</h3></div></div></div><a id="id-1.6.14.16.19.2" class="indexterm"></a><p>
+ The cascading replication feature allows a standby server to accept replication
+ connections and stream WAL records to other standbys, acting as a relay.
+ This can be used to reduce the number of direct connections to the primary
+ and also to minimize inter-site bandwidth overheads.
+ </p><p>
+ A standby acting as both a receiver and a sender is known as a cascading
+ standby. Standbys that are more directly connected to the primary are known
+ as upstream servers, while those standby servers further away are downstream
+ servers. Cascading replication does not place limits on the number or
+ arrangement of downstream servers, though each standby connects to only
+ one upstream server which eventually links to a single primary server.
+ </p><p>
+ A cascading standby sends not only WAL records received from the
+ primary but also those restored from the archive. So even if the replication
+ connection in some upstream connection is terminated, streaming replication
+ continues downstream for as long as new WAL records are available.
+ </p><p>
+ Cascading replication is currently asynchronous. Synchronous replication
+ (see <a class="xref" href="warm-standby.html#SYNCHRONOUS-REPLICATION" title="27.2.8. Synchronous Replication">Section 27.2.8</a>) settings have no effect on
+ cascading replication at present.
+ </p><p>
+ Hot standby feedback propagates upstream, whatever the cascaded arrangement.
+ </p><p>
+ If an upstream standby server is promoted to become the new primary, downstream
+ servers will continue to stream from the new primary if
+ <code class="varname">recovery_target_timeline</code> is set to <code class="literal">'latest'</code> (the default).
+ </p><p>
+ To use cascading replication, set up the cascading standby so that it can
+ accept replication connections (that is, set
+ <a class="xref" href="runtime-config-replication.html#GUC-MAX-WAL-SENDERS">max_wal_senders</a> and <a class="xref" href="runtime-config-replication.html#GUC-HOT-STANDBY">hot_standby</a>,
+ and configure
+ <a class="link" href="auth-pg-hba-conf.html" title="21.1. The pg_hba.conf File">host-based authentication</a>).
+ You will also need to set <code class="varname">primary_conninfo</code> in the downstream
+ standby to point to the cascading standby.
+ </p></div><div class="sect2" id="SYNCHRONOUS-REPLICATION"><div class="titlepage"><div><div><h3 class="title">27.2.8. Synchronous Replication</h3></div></div></div><a id="id-1.6.14.16.20.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> streaming replication is asynchronous by
+ default. If the primary server
+ crashes then some transactions that were committed may not have been
+ replicated to the standby server, causing data loss. The amount
+ of data loss is proportional to the replication delay at the time of
+ failover.
+ </p><p>
+ Synchronous replication offers the ability to confirm that all changes
+ made by a transaction have been transferred to one or more synchronous
+ standby servers. This extends that standard level of durability
+ offered by a transaction commit. This level of protection is referred
+ to as 2-safe replication in computer science theory, and group-1-safe
+ (group-safe and 1-safe) when <code class="varname">synchronous_commit</code> is set to
+ <code class="literal">remote_write</code>.
+ </p><p>
+ When requesting synchronous replication, each commit of a
+ write transaction will wait until confirmation is
+ received that the commit has been written to the write-ahead log on disk
+ of both the primary and standby server. The only possibility that data
+ can be lost is if both the primary and the standby suffer crashes at the
+ same time. This can provide a much higher level of durability, though only
+ if the sysadmin is cautious about the placement and management of the two
+ servers. Waiting for confirmation increases the user's confidence that the
+ changes will not be lost in the event of server crashes but it also
+ necessarily increases the response time for the requesting transaction.
+ The minimum wait time is the round-trip time between primary and standby.
+ </p><p>
+ Read-only transactions and transaction rollbacks need not wait for
+ replies from standby servers. Subtransaction commits do not wait for
+ responses from standby servers, only top-level commits. Long
+ running actions such as data loading or index building do not wait
+ until the very final commit message. All two-phase commit actions
+ require commit waits, including both prepare and commit.
+ </p><p>
+ A synchronous standby can be a physical replication standby or a logical
+ replication subscriber. It can also be any other physical or logical WAL
+ replication stream consumer that knows how to send the appropriate
+ feedback messages. Besides the built-in physical and logical replication
+ systems, this includes special programs such
+ as <code class="command">pg_receivewal</code> and <code class="command">pg_recvlogical</code>
+ as well as some third-party replication systems and custom programs.
+ Check the respective documentation for details on synchronous replication
+ support.
+ </p><div class="sect3" id="SYNCHRONOUS-REPLICATION-CONFIG"><div class="titlepage"><div><div><h4 class="title">27.2.8.1. Basic Configuration</h4></div></div></div><p>
+ Once streaming replication has been configured, configuring synchronous
+ replication requires only one additional configuration step:
+ <a class="xref" href="runtime-config-replication.html#GUC-SYNCHRONOUS-STANDBY-NAMES">synchronous_standby_names</a> must be set to
+ a non-empty value. <code class="varname">synchronous_commit</code> must also be set to
+ <code class="literal">on</code>, but since this is the default value, typically no change is
+ required. (See <a class="xref" href="runtime-config-wal.html#RUNTIME-CONFIG-WAL-SETTINGS" title="20.5.1. Settings">Section 20.5.1</a> and
+ <a class="xref" href="runtime-config-replication.html#RUNTIME-CONFIG-REPLICATION-PRIMARY" title="20.6.2. Primary Server">Section 20.6.2</a>.)
+ This configuration will cause each commit to wait for
+ confirmation that the standby has written the commit record to durable
+ storage.
+ <code class="varname">synchronous_commit</code> can be set by individual
+ users, so it can be configured in the configuration file, for particular
+ users or databases, or dynamically by applications, in order to control
+ the durability guarantee on a per-transaction basis.
+ </p><p>
+ After a commit record has been written to disk on the primary, the
+ WAL record is then sent to the standby. The standby sends reply
+ messages each time a new batch of WAL data is written to disk, unless
+ <code class="varname">wal_receiver_status_interval</code> is set to zero on the standby.
+ In the case that <code class="varname">synchronous_commit</code> is set to
+ <code class="literal">remote_apply</code>, the standby sends reply messages when the commit
+ record is replayed, making the transaction visible.
+ If the standby is chosen as a synchronous standby, according to the setting
+ of <code class="varname">synchronous_standby_names</code> on the primary, the reply
+ messages from that standby will be considered along with those from other
+ synchronous standbys to decide when to release transactions waiting for
+ confirmation that the commit record has been received. These parameters
+ allow the administrator to specify which standby servers should be
+ synchronous standbys. Note that the configuration of synchronous
+ replication is mainly on the primary. Named standbys must be directly
+ connected to the primary; the primary knows nothing about downstream
+ standby servers using cascaded replication.
+ </p><p>
+ Setting <code class="varname">synchronous_commit</code> to <code class="literal">remote_write</code> will
+ cause each commit to wait for confirmation that the standby has received
+ the commit record and written it out to its own operating system, but not
+ for the data to be flushed to disk on the standby. This
+ setting provides a weaker guarantee of durability than <code class="literal">on</code>
+ does: the standby could lose the data in the event of an operating system
+ crash, though not a <span class="productname">PostgreSQL</span> crash.
+ However, it's a useful setting in practice
+ because it can decrease the response time for the transaction.
+ Data loss could only occur if both the primary and the standby crash and
+ the database of the primary gets corrupted at the same time.
+ </p><p>
+ Setting <code class="varname">synchronous_commit</code> to <code class="literal">remote_apply</code> will
+ cause each commit to wait until the current synchronous standbys report
+ that they have replayed the transaction, making it visible to user
+ queries. In simple cases, this allows for load balancing with causal
+ consistency.
+ </p><p>
+ Users will stop waiting if a fast shutdown is requested. However, as
+ when using asynchronous replication, the server will not fully
+ shutdown until all outstanding WAL records are transferred to the currently
+ connected standby servers.
+ </p></div><div class="sect3" id="SYNCHRONOUS-REPLICATION-MULTIPLE-STANDBYS"><div class="titlepage"><div><div><h4 class="title">27.2.8.2. Multiple Synchronous Standbys</h4></div></div></div><p>
+ Synchronous replication supports one or more synchronous standby servers;
+ transactions will wait until all the standby servers which are considered
+ as synchronous confirm receipt of their data. The number of synchronous
+ standbys that transactions must wait for replies from is specified in
+ <code class="varname">synchronous_standby_names</code>. This parameter also specifies
+ a list of standby names and the method (<code class="literal">FIRST</code> and
+ <code class="literal">ANY</code>) to choose synchronous standbys from the listed ones.
+ </p><p>
+ The method <code class="literal">FIRST</code> specifies a priority-based synchronous
+ replication and makes transaction commits wait until their WAL records are
+ replicated to the requested number of synchronous standbys chosen based on
+ their priorities. The standbys whose names appear earlier in the list are
+ given higher priority and will be considered as synchronous. Other standby
+ servers appearing later in this list represent potential synchronous
+ standbys. If any of the current synchronous standbys disconnects for
+ whatever reason, it will be replaced immediately with the
+ next-highest-priority standby.
+ </p><p>
+ An example of <code class="varname">synchronous_standby_names</code> for
+ a priority-based multiple synchronous standbys is:
+</p><pre class="programlisting">
+synchronous_standby_names = 'FIRST 2 (s1, s2, s3)'
+</pre><p>
+ In this example, if four standby servers <code class="literal">s1</code>, <code class="literal">s2</code>,
+ <code class="literal">s3</code> and <code class="literal">s4</code> are running, the two standbys
+ <code class="literal">s1</code> and <code class="literal">s2</code> will be chosen as synchronous standbys
+ because their names appear early in the list of standby names.
+ <code class="literal">s3</code> is a potential synchronous standby and will take over
+ the role of synchronous standby when either of <code class="literal">s1</code> or
+ <code class="literal">s2</code> fails. <code class="literal">s4</code> is an asynchronous standby since
+ its name is not in the list.
+ </p><p>
+ The method <code class="literal">ANY</code> specifies a quorum-based synchronous
+ replication and makes transaction commits wait until their WAL records
+ are replicated to <span class="emphasis"><em>at least</em></span> the requested number of
+ synchronous standbys in the list.
+ </p><p>
+ An example of <code class="varname">synchronous_standby_names</code> for
+ a quorum-based multiple synchronous standbys is:
+</p><pre class="programlisting">
+synchronous_standby_names = 'ANY 2 (s1, s2, s3)'
+</pre><p>
+ In this example, if four standby servers <code class="literal">s1</code>, <code class="literal">s2</code>,
+ <code class="literal">s3</code> and <code class="literal">s4</code> are running, transaction commits will
+ wait for replies from at least any two standbys of <code class="literal">s1</code>,
+ <code class="literal">s2</code> and <code class="literal">s3</code>. <code class="literal">s4</code> is an asynchronous
+ standby since its name is not in the list.
+ </p><p>
+ The synchronous states of standby servers can be viewed using
+ the <code class="structname">pg_stat_replication</code> view.
+ </p></div><div class="sect3" id="SYNCHRONOUS-REPLICATION-PERFORMANCE"><div class="titlepage"><div><div><h4 class="title">27.2.8.3. Planning for Performance</h4></div></div></div><p>
+ Synchronous replication usually requires carefully planned and placed
+ standby servers to ensure applications perform acceptably. Waiting
+ doesn't utilize system resources, but transaction locks continue to be
+ held until the transfer is confirmed. As a result, incautious use of
+ synchronous replication will reduce performance for database
+ applications because of increased response times and higher contention.
+ </p><p>
+ <span class="productname">PostgreSQL</span> allows the application developer
+ to specify the durability level required via replication. This can be
+ specified for the system overall, though it can also be specified for
+ specific users or connections, or even individual transactions.
+ </p><p>
+ For example, an application workload might consist of:
+ 10% of changes are important customer details, while
+ 90% of changes are less important data that the business can more
+ easily survive if it is lost, such as chat messages between users.
+ </p><p>
+ With synchronous replication options specified at the application level
+ (on the primary) we can offer synchronous replication for the most
+ important changes, without slowing down the bulk of the total workload.
+ Application level options are an important and practical tool for allowing
+ the benefits of synchronous replication for high performance applications.
+ </p><p>
+ You should consider that the network bandwidth must be higher than
+ the rate of generation of WAL data.
+ </p></div><div class="sect3" id="SYNCHRONOUS-REPLICATION-HA"><div class="titlepage"><div><div><h4 class="title">27.2.8.4. Planning for High Availability</h4></div></div></div><p>
+ <code class="varname">synchronous_standby_names</code> specifies the number and
+ names of synchronous standbys that transaction commits made when
+ <code class="varname">synchronous_commit</code> is set to <code class="literal">on</code>,
+ <code class="literal">remote_apply</code> or <code class="literal">remote_write</code> will wait for
+ responses from. Such transaction commits may never be completed
+ if any one of synchronous standbys should crash.
+ </p><p>
+ The best solution for high availability is to ensure you keep as many
+ synchronous standbys as requested. This can be achieved by naming multiple
+ potential synchronous standbys using <code class="varname">synchronous_standby_names</code>.
+ </p><p>
+ In a priority-based synchronous replication, the standbys whose names
+ appear earlier in the list will be used as synchronous standbys.
+ Standbys listed after these will take over the role of synchronous standby
+ if one of current ones should fail.
+ </p><p>
+ In a quorum-based synchronous replication, all the standbys appearing
+ in the list will be used as candidates for synchronous standbys.
+ Even if one of them should fail, the other standbys will keep performing
+ the role of candidates of synchronous standby.
+ </p><p>
+ When a standby first attaches to the primary, it will not yet be properly
+ synchronized. This is described as <code class="literal">catchup</code> mode. Once
+ the lag between standby and primary reaches zero for the first time
+ we move to real-time <code class="literal">streaming</code> state.
+ The catch-up duration may be long immediately after the standby has
+ been created. If the standby is shut down, then the catch-up period
+ will increase according to the length of time the standby has been down.
+ The standby is only able to become a synchronous standby
+ once it has reached <code class="literal">streaming</code> state.
+ This state can be viewed using
+ the <code class="structname">pg_stat_replication</code> view.
+ </p><p>
+ If primary restarts while commits are waiting for acknowledgment, those
+ waiting transactions will be marked fully committed once the primary
+ database recovers.
+ There is no way to be certain that all standbys have received all
+ outstanding WAL data at time of the crash of the primary. Some
+ transactions may not show as committed on the standby, even though
+ they show as committed on the primary. The guarantee we offer is that
+ the application will not receive explicit acknowledgment of the
+ successful commit of a transaction until the WAL data is known to be
+ safely received by all the synchronous standbys.
+ </p><p>
+ If you really cannot keep as many synchronous standbys as requested
+ then you should decrease the number of synchronous standbys that
+ transaction commits must wait for responses from
+ in <code class="varname">synchronous_standby_names</code> (or disable it) and
+ reload the configuration file on the primary server.
+ </p><p>
+ If the primary is isolated from remaining standby servers you should
+ fail over to the best candidate of those other remaining standby servers.
+ </p><p>
+ If you need to re-create a standby server while transactions are
+ waiting, make sure that the commands pg_backup_start() and
+ pg_backup_stop() are run in a session with
+ <code class="varname">synchronous_commit</code> = <code class="literal">off</code>, otherwise those
+ requests will wait forever for the standby to appear.
+ </p></div></div><div class="sect2" id="CONTINUOUS-ARCHIVING-IN-STANDBY"><div class="titlepage"><div><div><h3 class="title">27.2.9. Continuous Archiving in Standby</h3></div></div></div><a id="id-1.6.14.16.21.2" class="indexterm"></a><p>
+ When continuous WAL archiving is used in a standby, there are two
+ different scenarios: the WAL archive can be shared between the primary
+ and the standby, or the standby can have its own WAL archive. When
+ the standby has its own WAL archive, set <code class="varname">archive_mode</code>
+ to <code class="literal">always</code>, and the standby will call the archive
+ command for every WAL segment it receives, whether it's by restoring
+ from the archive or by streaming replication. The shared archive can
+ be handled similarly, but the <code class="varname">archive_command</code> or <code class="varname">archive_library</code> must
+ test if the file being archived exists already, and if the existing file
+ has identical contents. This requires more care in the
+ <code class="varname">archive_command</code> or <code class="varname">archive_library</code>, as it must
+ be careful to not overwrite an existing file with different contents,
+ but return success if the exactly same file is archived twice. And
+ all that must be done free of race conditions, if two servers attempt
+ to archive the same file at the same time.
+ </p><p>
+ If <code class="varname">archive_mode</code> is set to <code class="literal">on</code>, the
+ archiver is not enabled during recovery or standby mode. If the standby
+ server is promoted, it will start archiving after the promotion, but
+ will not archive any WAL or timeline history files that
+ it did not generate itself. To get a complete
+ series of WAL files in the archive, you must ensure that all WAL is
+ archived, before it reaches the standby. This is inherently true with
+ file-based log shipping, as the standby can only restore files that
+ are found in the archive, but not if streaming replication is enabled.
+ When a server is not in recovery mode, there is no difference between
+ <code class="literal">on</code> and <code class="literal">always</code> modes.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="different-replication-solutions.html" title="27.1. Comparison of Different Solutions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="high-availability.html" title="Chapter 27. High Availability, Load Balancing, and Replication">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="warm-standby-failover.html" title="27.3. Failover">Next</a></td></tr><tr><td width="40%" align="left" valign="top">27.1. Comparison of Different Solutions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 27.3. Failover</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/when-can-parallel-query-be-used.html b/doc/src/sgml/html/when-can-parallel-query-be-used.html
new file mode 100644
index 0000000..fddb08f
--- /dev/null
+++ b/doc/src/sgml/html/when-can-parallel-query-be-used.html
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>15.2. When Can Parallel Query Be Used?</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="how-parallel-query-works.html" title="15.1. How Parallel Query Works" /><link rel="next" href="parallel-plans.html" title="15.3. Parallel Plans" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">15.2. When Can Parallel Query Be Used?</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="how-parallel-query-works.html" title="15.1. How Parallel Query Works">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><th width="60%" align="center">Chapter 15. Parallel Query</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="parallel-plans.html" title="15.3. Parallel Plans">Next</a></td></tr></table><hr /></div><div class="sect1" id="WHEN-CAN-PARALLEL-QUERY-BE-USED"><div class="titlepage"><div><div><h2 class="title" style="clear: both">15.2. When Can Parallel Query Be Used?</h2></div></div></div><p>
+ There are several settings that can cause the query planner not to
+ generate a parallel query plan under any circumstances. In order for
+ any parallel query plans whatsoever to be generated, the following
+ settings must be configured as indicated.
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER">max_parallel_workers_per_gather</a> must be set to a
+ value that is greater than zero. This is a special case of the more
+ general principle that no more workers should be used than the number
+ configured via <code class="varname">max_parallel_workers_per_gather</code>.
+ </p></li></ul></div><p>
+ In addition, the system must not be running in single-user mode. Since
+ the entire database system is running as a single process in this situation,
+ no background workers will be available.
+ </p><p>
+ Even when it is in general possible for parallel query plans to be
+ generated, the planner will not generate them for a given query
+ if any of the following are true:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The query writes any data or locks any database rows. If a query
+ contains a data-modifying operation either at the top level or within
+ a CTE, no parallel plans for that query will be generated. As an
+ exception, the following commands, which create a new table and populate
+ it, can use a parallel plan for the underlying <code class="literal">SELECT</code>
+ part of the query:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p><code class="command">CREATE TABLE ... AS</code></p></li><li class="listitem"><p><code class="command">SELECT INTO</code></p></li><li class="listitem"><p><code class="command">CREATE MATERIALIZED VIEW</code></p></li><li class="listitem"><p><code class="command">REFRESH MATERIALIZED VIEW</code></p></li></ul></div><p>
+ </p></li><li class="listitem"><p>
+ The query might be suspended during execution. In any situation in
+ which the system thinks that partial or incremental execution might
+ occur, no parallel plan is generated. For example, a cursor created
+ using <a class="link" href="sql-declare.html" title="DECLARE">DECLARE CURSOR</a> will never use
+ a parallel plan. Similarly, a PL/pgSQL loop of the form
+ <code class="literal">FOR x IN query LOOP .. END LOOP</code> will never use a
+ parallel plan, because the parallel query system is unable to verify
+ that the code in the loop is safe to execute while parallel query is
+ active.
+ </p></li><li class="listitem"><p>
+ The query uses any function marked <code class="literal">PARALLEL UNSAFE</code>.
+ Most system-defined functions are <code class="literal">PARALLEL SAFE</code>,
+ but user-defined functions are marked <code class="literal">PARALLEL
+ UNSAFE</code> by default. See the discussion of
+ <a class="xref" href="parallel-safety.html" title="15.4. Parallel Safety">Section 15.4</a>.
+ </p></li><li class="listitem"><p>
+ The query is running inside of another query that is already parallel.
+ For example, if a function called by a parallel query issues an SQL
+ query itself, that query will never use a parallel plan. This is a
+ limitation of the current implementation, but it may not be desirable
+ to remove this limitation, since it could result in a single query
+ using a very large number of processes.
+ </p></li></ul></div><p>
+ Even when parallel query plan is generated for a particular query, there
+ are several circumstances under which it will be impossible to execute
+ that plan in parallel at execution time. If this occurs, the leader
+ will execute the portion of the plan below the <code class="literal">Gather</code>
+ node entirely by itself, almost as if the <code class="literal">Gather</code> node were
+ not present. This will happen if any of the following conditions are met:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ No background workers can be obtained because of the limitation that
+ the total number of background workers cannot exceed
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES">max_worker_processes</a>.
+ </p></li><li class="listitem"><p>
+ No background workers can be obtained because of the limitation that
+ the total number of background workers launched for purposes of
+ parallel query cannot exceed <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS">max_parallel_workers</a>.
+ </p></li><li class="listitem"><p>
+ The client sends an Execute message with a non-zero fetch count.
+ See the discussion of the
+ <a class="link" href="protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY" title="55.2.3. Extended Query">extended query protocol</a>.
+ Since <a class="link" href="libpq.html" title="Chapter 34. libpq — C Library">libpq</a> currently provides no way to
+ send such a message, this can only occur when using a client that
+ does not rely on libpq. If this is a frequent
+ occurrence, it may be a good idea to set
+ <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER">max_parallel_workers_per_gather</a> to zero in
+ sessions where it is likely, so as to avoid generating query plans
+ that may be suboptimal when run serially.
+ </p></li></ul></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="how-parallel-query-works.html" title="15.1. How Parallel Query Works">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="parallel-query.html" title="Chapter 15. Parallel Query">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="parallel-plans.html" title="15.3. Parallel Plans">Next</a></td></tr><tr><td width="40%" align="left" valign="top">15.1. How Parallel Query Works </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 15.3. Parallel Plans</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xaggr.html b/doc/src/sgml/html/xaggr.html
new file mode 100644
index 0000000..f0a4004
--- /dev/null
+++ b/doc/src/sgml/html/xaggr.html
@@ -0,0 +1,528 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.12. User-Defined Aggregates</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-optimization.html" title="38.11. Function Optimization Information" /><link rel="next" href="xtypes.html" title="38.13. User-Defined Types" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.12. User-Defined Aggregates</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xtypes.html" title="38.13. User-Defined Types">Next</a></td></tr></table><hr /></div><div class="sect1" id="XAGGR"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.12. User-Defined Aggregates</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xaggr.html#XAGGR-MOVING-AGGREGATES">38.12.1. Moving-Aggregate Mode</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-POLYMORPHIC-AGGREGATES">38.12.2. Polymorphic and Variadic Aggregates</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-ORDERED-SET-AGGREGATES">38.12.3. Ordered-Set Aggregates</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-PARTIAL-AGGREGATES">38.12.4. Partial Aggregation</a></span></dt><dt><span class="sect2"><a href="xaggr.html#XAGGR-SUPPORT-FUNCTIONS">38.12.5. Support Functions for Aggregates</a></span></dt></dl></div><a id="id-1.8.3.15.2" class="indexterm"></a><p>
+ Aggregate functions in <span class="productname">PostgreSQL</span>
+ are defined in terms of <em class="firstterm">state values</em>
+ and <em class="firstterm">state transition functions</em>.
+ That is, an aggregate operates using a state value that is updated
+ as each successive input row is processed.
+ To define a new aggregate
+ function, one selects a data type for the state value,
+ an initial value for the state, and a state transition
+ function. The state transition function takes the previous state
+ value and the aggregate's input value(s) for the current row, and
+ returns a new state value.
+ A <em class="firstterm">final function</em>
+ can also be specified, in case the desired result of the aggregate
+ is different from the data that needs to be kept in the running
+ state value. The final function takes the ending state value
+ and returns whatever is wanted as the aggregate result.
+ In principle, the transition and final functions are just ordinary
+ functions that could also be used outside the context of the
+ aggregate. (In practice, it's often helpful for performance reasons
+ to create specialized transition functions that can only work when
+ called as part of an aggregate.)
+ </p><p>
+ Thus, in addition to the argument and result data types seen by a user
+ of the aggregate, there is an internal state-value data type that
+ might be different from both the argument and result types.
+ </p><p>
+ If we define an aggregate that does not use a final function,
+ we have an aggregate that computes a running function of
+ the column values from each row. <code class="function">sum</code> is an
+ example of this kind of aggregate. <code class="function">sum</code> starts at
+ zero and always adds the current row's value to
+ its running total. For example, if we want to make a <code class="function">sum</code>
+ aggregate to work on a data type for complex numbers,
+ we only need the addition function for that data type.
+ The aggregate definition would be:
+
+</p><pre class="programlisting">
+CREATE AGGREGATE sum (complex)
+(
+ sfunc = complex_add,
+ stype = complex,
+ initcond = '(0,0)'
+);
+</pre><p>
+
+ which we might use like this:
+
+</p><pre class="programlisting">
+SELECT sum(a) FROM test_complex;
+
+ sum
+-----------
+ (34,53.9)
+</pre><p>
+
+ (Notice that we are relying on function overloading: there is more than
+ one aggregate named <code class="function">sum</code>, but
+ <span class="productname">PostgreSQL</span> can figure out which kind
+ of sum applies to a column of type <code class="type">complex</code>.)
+ </p><p>
+ The above definition of <code class="function">sum</code> will return zero
+ (the initial state value) if there are no nonnull input values.
+ Perhaps we want to return null in that case instead — the SQL standard
+ expects <code class="function">sum</code> to behave that way. We can do this simply by
+ omitting the <code class="literal">initcond</code> phrase, so that the initial state
+ value is null. Ordinarily this would mean that the <code class="literal">sfunc</code>
+ would need to check for a null state-value input. But for
+ <code class="function">sum</code> and some other simple aggregates like
+ <code class="function">max</code> and <code class="function">min</code>,
+ it is sufficient to insert the first nonnull input value into
+ the state variable and then start applying the transition function
+ at the second nonnull input value. <span class="productname">PostgreSQL</span>
+ will do that automatically if the initial state value is null and
+ the transition function is marked <span class="quote">“<span class="quote">strict</span>”</span> (i.e., not to be called
+ for null inputs).
+ </p><p>
+ Another bit of default behavior for a <span class="quote">“<span class="quote">strict</span>”</span> transition function
+ is that the previous state value is retained unchanged whenever a
+ null input value is encountered. Thus, null values are ignored. If you
+ need some other behavior for null inputs, do not declare your
+ transition function as strict; instead code it to test for null inputs and
+ do whatever is needed.
+ </p><p>
+ <code class="function">avg</code> (average) is a more complex example of an aggregate.
+ It requires
+ two pieces of running state: the sum of the inputs and the count
+ of the number of inputs. The final result is obtained by dividing
+ these quantities. Average is typically implemented by using an
+ array as the state value. For example,
+ the built-in implementation of <code class="function">avg(float8)</code>
+ looks like:
+
+</p><pre class="programlisting">
+CREATE AGGREGATE avg (float8)
+(
+ sfunc = float8_accum,
+ stype = float8[],
+ finalfunc = float8_avg,
+ initcond = '{0,0,0}'
+);
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <code class="function">float8_accum</code> requires a three-element array, not just
+ two elements, because it accumulates the sum of squares as well as
+ the sum and count of the inputs. This is so that it can be used for
+ some other aggregates as well as <code class="function">avg</code>.
+ </p></div><p>
+ Aggregate function calls in SQL allow <code class="literal">DISTINCT</code>
+ and <code class="literal">ORDER BY</code> options that control which rows are fed
+ to the aggregate's transition function and in what order. These
+ options are implemented behind the scenes and are not the concern
+ of the aggregate's support functions.
+ </p><p>
+ For further details see the
+ <a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a>
+ command.
+ </p><div class="sect2" id="XAGGR-MOVING-AGGREGATES"><div class="titlepage"><div><div><h3 class="title">38.12.1. Moving-Aggregate Mode</h3></div></div></div><a id="id-1.8.3.15.12.2" class="indexterm"></a><a id="id-1.8.3.15.12.3" class="indexterm"></a><p>
+ Aggregate functions can optionally support <em class="firstterm">moving-aggregate
+ mode</em>, which allows substantially faster execution of aggregate
+ functions within windows with moving frame starting points.
+ (See <a class="xref" href="tutorial-window.html" title="3.5. Window Functions">Section 3.5</a>
+ and <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a> for information about use of
+ aggregate functions as window functions.)
+ The basic idea is that in addition to a normal <span class="quote">“<span class="quote">forward</span>”</span>
+ transition function, the aggregate provides an <em class="firstterm">inverse
+ transition function</em>, which allows rows to be removed from the
+ aggregate's running state value when they exit the window frame.
+ For example a <code class="function">sum</code> aggregate, which uses addition as the
+ forward transition function, would use subtraction as the inverse
+ transition function. Without an inverse transition function, the window
+ function mechanism must recalculate the aggregate from scratch each time
+ the frame starting point moves, resulting in run time proportional to the
+ number of input rows times the average frame length. With an inverse
+ transition function, the run time is only proportional to the number of
+ input rows.
+ </p><p>
+ The inverse transition function is passed the current state value and the
+ aggregate input value(s) for the earliest row included in the current
+ state. It must reconstruct what the state value would have been if the
+ given input row had never been aggregated, but only the rows following
+ it. This sometimes requires that the forward transition function keep
+ more state than is needed for plain aggregation mode. Therefore, the
+ moving-aggregate mode uses a completely separate implementation from the
+ plain mode: it has its own state data type, its own forward transition
+ function, and its own final function if needed. These can be the same as
+ the plain mode's data type and functions, if there is no need for extra
+ state.
+ </p><p>
+ As an example, we could extend the <code class="function">sum</code> aggregate given above
+ to support moving-aggregate mode like this:
+
+</p><pre class="programlisting">
+CREATE AGGREGATE sum (complex)
+(
+ sfunc = complex_add,
+ stype = complex,
+ initcond = '(0,0)',
+ msfunc = complex_add,
+ minvfunc = complex_sub,
+ mstype = complex,
+ minitcond = '(0,0)'
+);
+</pre><p>
+
+ The parameters whose names begin with <code class="literal">m</code> define the
+ moving-aggregate implementation. Except for the inverse transition
+ function <code class="literal">minvfunc</code>, they correspond to the plain-aggregate
+ parameters without <code class="literal">m</code>.
+ </p><p>
+ The forward transition function for moving-aggregate mode is not allowed
+ to return null as the new state value. If the inverse transition
+ function returns null, this is taken as an indication that the inverse
+ function cannot reverse the state calculation for this particular input,
+ and so the aggregate calculation will be redone from scratch for the
+ current frame starting position. This convention allows moving-aggregate
+ mode to be used in situations where there are some infrequent cases that
+ are impractical to reverse out of the running state value. The inverse
+ transition function can <span class="quote">“<span class="quote">punt</span>”</span> on these cases, and yet still come
+ out ahead so long as it can work for most cases. As an example, an
+ aggregate working with floating-point numbers might choose to punt when
+ a <code class="literal">NaN</code> (not a number) input has to be removed from the running
+ state value.
+ </p><p>
+ When writing moving-aggregate support functions, it is important to be
+ sure that the inverse transition function can reconstruct the correct
+ state value exactly. Otherwise there might be user-visible differences
+ in results depending on whether the moving-aggregate mode is used.
+ An example of an aggregate for which adding an inverse transition
+ function seems easy at first, yet where this requirement cannot be met
+ is <code class="function">sum</code> over <code class="type">float4</code> or <code class="type">float8</code> inputs. A
+ naive declaration of <code class="function">sum(<code class="type">float8</code>)</code> could be
+
+</p><pre class="programlisting">
+CREATE AGGREGATE unsafe_sum (float8)
+(
+ stype = float8,
+ sfunc = float8pl,
+ mstype = float8,
+ msfunc = float8pl,
+ minvfunc = float8mi
+);
+</pre><p>
+
+ This aggregate, however, can give wildly different results than it would
+ have without the inverse transition function. For example, consider
+
+</p><pre class="programlisting">
+SELECT
+ unsafe_sum(x) OVER (ORDER BY n ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
+FROM (VALUES (1, 1.0e20::float8),
+ (2, 1.0::float8)) AS v (n,x);
+</pre><p>
+
+ This query returns <code class="literal">0</code> as its second result, rather than the
+ expected answer of <code class="literal">1</code>. The cause is the limited precision of
+ floating-point values: adding <code class="literal">1</code> to <code class="literal">1e20</code> results
+ in <code class="literal">1e20</code> again, and so subtracting <code class="literal">1e20</code> from that
+ yields <code class="literal">0</code>, not <code class="literal">1</code>. Note that this is a limitation
+ of floating-point arithmetic in general, not a limitation
+ of <span class="productname">PostgreSQL</span>.
+ </p></div><div class="sect2" id="XAGGR-POLYMORPHIC-AGGREGATES"><div class="titlepage"><div><div><h3 class="title">38.12.2. Polymorphic and Variadic Aggregates</h3></div></div></div><a id="id-1.8.3.15.13.2" class="indexterm"></a><a id="id-1.8.3.15.13.3" class="indexterm"></a><p>
+ Aggregate functions can use polymorphic
+ state transition functions or final functions, so that the same functions
+ can be used to implement multiple aggregates.
+ See <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>
+ for an explanation of polymorphic functions.
+ Going a step further, the aggregate function itself can be specified
+ with polymorphic input type(s) and state type, allowing a single
+ aggregate definition to serve for multiple input data types.
+ Here is an example of a polymorphic aggregate:
+
+</p><pre class="programlisting">
+CREATE AGGREGATE array_accum (anycompatible)
+(
+ sfunc = array_append,
+ stype = anycompatiblearray,
+ initcond = '{}'
+);
+</pre><p>
+
+ Here, the actual state type for any given aggregate call is the array type
+ having the actual input type as elements. The behavior of the aggregate
+ is to concatenate all the inputs into an array of that type.
+ (Note: the built-in aggregate <code class="function">array_agg</code> provides similar
+ functionality, with better performance than this definition would have.)
+ </p><p>
+ Here's the output using two different actual data types as arguments:
+
+</p><pre class="programlisting">
+SELECT attrelid::regclass, array_accum(attname)
+ FROM pg_attribute
+ WHERE attnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
+ GROUP BY attrelid;
+
+ attrelid | array_accum
+---------------+---------------------------------------
+ pg_tablespace | {spcname,spcowner,spcacl,spcoptions}
+(1 row)
+
+SELECT attrelid::regclass, array_accum(atttypid::regtype)
+ FROM pg_attribute
+ WHERE attnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
+ GROUP BY attrelid;
+
+ attrelid | array_accum
+---------------+---------------------------
+ pg_tablespace | {name,oid,aclitem[],text[]}
+(1 row)
+</pre><p>
+ </p><p>
+ Ordinarily, an aggregate function with a polymorphic result type has a
+ polymorphic state type, as in the above example. This is necessary
+ because otherwise the final function cannot be declared sensibly: it
+ would need to have a polymorphic result type but no polymorphic argument
+ type, which <code class="command">CREATE FUNCTION</code> will reject on the grounds that
+ the result type cannot be deduced from a call. But sometimes it is
+ inconvenient to use a polymorphic state type. The most common case is
+ where the aggregate support functions are to be written in C and the
+ state type should be declared as <code class="type">internal</code> because there is
+ no SQL-level equivalent for it. To address this case, it is possible to
+ declare the final function as taking extra <span class="quote">“<span class="quote">dummy</span>”</span> arguments
+ that match the input arguments of the aggregate. Such dummy arguments
+ are always passed as null values since no specific value is available when the
+ final function is called. Their only use is to allow a polymorphic
+ final function's result type to be connected to the aggregate's input
+ type(s). For example, the definition of the built-in
+ aggregate <code class="function">array_agg</code> is equivalent to
+
+</p><pre class="programlisting">
+CREATE FUNCTION array_agg_transfn(internal, anynonarray)
+ RETURNS internal ...;
+CREATE FUNCTION array_agg_finalfn(internal, anynonarray)
+ RETURNS anyarray ...;
+
+CREATE AGGREGATE array_agg (anynonarray)
+(
+ sfunc = array_agg_transfn,
+ stype = internal,
+ finalfunc = array_agg_finalfn,
+ finalfunc_extra
+);
+</pre><p>
+
+ Here, the <code class="literal">finalfunc_extra</code> option specifies that the final
+ function receives, in addition to the state value, extra dummy
+ argument(s) corresponding to the aggregate's input argument(s).
+ The extra <code class="type">anynonarray</code> argument allows the declaration
+ of <code class="function">array_agg_finalfn</code> to be valid.
+ </p><p>
+ An aggregate function can be made to accept a varying number of arguments
+ by declaring its last argument as a <code class="literal">VARIADIC</code> array, in much
+ the same fashion as for regular functions; see
+ <a class="xref" href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS" title="38.5.6. SQL Functions with Variable Numbers of Arguments">Section 38.5.6</a>. The aggregate's transition
+ function(s) must have the same array type as their last argument. The
+ transition function(s) typically would also be marked <code class="literal">VARIADIC</code>,
+ but this is not strictly required.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Variadic aggregates are easily misused in connection with
+ the <code class="literal">ORDER BY</code> option (see <a class="xref" href="sql-expressions.html#SYNTAX-AGGREGATES" title="4.2.7. Aggregate Expressions">Section 4.2.7</a>),
+ since the parser cannot tell whether the wrong number of actual arguments
+ have been given in such a combination. Keep in mind that everything to
+ the right of <code class="literal">ORDER BY</code> is a sort key, not an argument to the
+ aggregate. For example, in
+</p><pre class="programlisting">
+SELECT myaggregate(a ORDER BY a, b, c) FROM ...
+</pre><p>
+ the parser will see this as a single aggregate function argument and
+ three sort keys. However, the user might have intended
+</p><pre class="programlisting">
+SELECT myaggregate(a, b, c ORDER BY a) FROM ...
+</pre><p>
+ If <code class="literal">myaggregate</code> is variadic, both these calls could be
+ perfectly valid.
+ </p><p>
+ For the same reason, it's wise to think twice before creating aggregate
+ functions with the same names and different numbers of regular arguments.
+ </p></div></div><div class="sect2" id="XAGGR-ORDERED-SET-AGGREGATES"><div class="titlepage"><div><div><h3 class="title">38.12.3. Ordered-Set Aggregates</h3></div></div></div><a id="id-1.8.3.15.14.2" class="indexterm"></a><p>
+ The aggregates we have been describing so far are <span class="quote">“<span class="quote">normal</span>”</span>
+ aggregates. <span class="productname">PostgreSQL</span> also
+ supports <em class="firstterm">ordered-set aggregates</em>, which differ from
+ normal aggregates in two key ways. First, in addition to ordinary
+ aggregated arguments that are evaluated once per input row, an
+ ordered-set aggregate can have <span class="quote">“<span class="quote">direct</span>”</span> arguments that are
+ evaluated only once per aggregation operation. Second, the syntax
+ for the ordinary aggregated arguments specifies a sort ordering
+ for them explicitly. An ordered-set aggregate is usually
+ used to implement a computation that depends on a specific row
+ ordering, for instance rank or percentile, so that the sort ordering
+ is a required aspect of any call. For example, the built-in
+ definition of <code class="function">percentile_disc</code> is equivalent to:
+
+</p><pre class="programlisting">
+CREATE FUNCTION ordered_set_transition(internal, anyelement)
+ RETURNS internal ...;
+CREATE FUNCTION percentile_disc_final(internal, float8, anyelement)
+ RETURNS anyelement ...;
+
+CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement)
+(
+ sfunc = ordered_set_transition,
+ stype = internal,
+ finalfunc = percentile_disc_final,
+ finalfunc_extra
+);
+</pre><p>
+
+ This aggregate takes a <code class="type">float8</code> direct argument (the percentile
+ fraction) and an aggregated input that can be of any sortable data type.
+ It could be used to obtain a median household income like this:
+
+</p><pre class="programlisting">
+SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households;
+ percentile_disc
+-----------------
+ 50489
+</pre><p>
+
+ Here, <code class="literal">0.5</code> is a direct argument; it would make no sense
+ for the percentile fraction to be a value varying across rows.
+ </p><p>
+ Unlike the case for normal aggregates, the sorting of input rows for
+ an ordered-set aggregate is <span class="emphasis"><em>not</em></span> done behind the scenes,
+ but is the responsibility of the aggregate's support functions.
+ The typical implementation approach is to keep a reference to
+ a <span class="quote">“<span class="quote">tuplesort</span>”</span> object in the aggregate's state value, feed the
+ incoming rows into that object, and then complete the sorting and
+ read out the data in the final function. This design allows the
+ final function to perform special operations such as injecting
+ additional <span class="quote">“<span class="quote">hypothetical</span>”</span> rows into the data to be sorted.
+ While normal aggregates can often be implemented with support
+ functions written in <span class="application">PL/pgSQL</span> or another
+ PL language, ordered-set aggregates generally have to be written in
+ C, since their state values aren't definable as any SQL data type.
+ (In the above example, notice that the state value is declared as
+ type <code class="type">internal</code> — this is typical.)
+ Also, because the final function performs the sort, it is not possible
+ to continue adding input rows by executing the transition function again
+ later. This means the final function is not <code class="literal">READ_ONLY</code>;
+ it must be declared in <a class="link" href="sql-createaggregate.html" title="CREATE AGGREGATE"><code class="command">CREATE AGGREGATE</code></a>
+ as <code class="literal">READ_WRITE</code>, or as <code class="literal">SHAREABLE</code> if
+ it's possible for additional final-function calls to make use of the
+ already-sorted state.
+ </p><p>
+ The state transition function for an ordered-set aggregate receives
+ the current state value plus the aggregated input values for
+ each row, and returns the updated state value. This is the
+ same definition as for normal aggregates, but note that the direct
+ arguments (if any) are not provided. The final function receives
+ the last state value, the values of the direct arguments if any,
+ and (if <code class="literal">finalfunc_extra</code> is specified) null values
+ corresponding to the aggregated input(s). As with normal
+ aggregates, <code class="literal">finalfunc_extra</code> is only really useful if the
+ aggregate is polymorphic; then the extra dummy argument(s) are needed
+ to connect the final function's result type to the aggregate's input
+ type(s).
+ </p><p>
+ Currently, ordered-set aggregates cannot be used as window functions,
+ and therefore there is no need for them to support moving-aggregate mode.
+ </p></div><div class="sect2" id="XAGGR-PARTIAL-AGGREGATES"><div class="titlepage"><div><div><h3 class="title">38.12.4. Partial Aggregation</h3></div></div></div><a id="id-1.8.3.15.15.2" class="indexterm"></a><p>
+ Optionally, an aggregate function can support <em class="firstterm">partial
+ aggregation</em>. The idea of partial aggregation is to run the aggregate's
+ state transition function over different subsets of the input data
+ independently, and then to combine the state values resulting from those
+ subsets to produce the same state value that would have resulted from
+ scanning all the input in a single operation. This mode can be used for
+ parallel aggregation by having different worker processes scan different
+ portions of a table. Each worker produces a partial state value, and at
+ the end those state values are combined to produce a final state value.
+ (In the future this mode might also be used for purposes such as combining
+ aggregations over local and remote tables; but that is not implemented
+ yet.)
+ </p><p>
+ To support partial aggregation, the aggregate definition must provide
+ a <em class="firstterm">combine function</em>, which takes two values of the
+ aggregate's state type (representing the results of aggregating over two
+ subsets of the input rows) and produces a new value of the state type,
+ representing what the state would have been after aggregating over the
+ combination of those sets of rows. It is unspecified what the relative
+ order of the input rows from the two sets would have been. This means
+ that it's usually impossible to define a useful combine function for
+ aggregates that are sensitive to input row order.
+ </p><p>
+ As simple examples, <code class="literal">MAX</code> and <code class="literal">MIN</code> aggregates can be
+ made to support partial aggregation by specifying the combine function as
+ the same greater-of-two or lesser-of-two comparison function that is used
+ as their transition function. <code class="literal">SUM</code> aggregates just need an
+ addition function as combine function. (Again, this is the same as their
+ transition function, unless the state value is wider than the input data
+ type.)
+ </p><p>
+ The combine function is treated much like a transition function that
+ happens to take a value of the state type, not of the underlying input
+ type, as its second argument. In particular, the rules for dealing
+ with null values and strict functions are similar. Also, if the aggregate
+ definition specifies a non-null <code class="literal">initcond</code>, keep in mind that
+ that will be used not only as the initial state for each partial
+ aggregation run, but also as the initial state for the combine function,
+ which will be called to combine each partial result into that state.
+ </p><p>
+ If the aggregate's state type is declared as <code class="type">internal</code>, it is
+ the combine function's responsibility that its result is allocated in
+ the correct memory context for aggregate state values. This means in
+ particular that when the first input is <code class="literal">NULL</code> it's invalid
+ to simply return the second input, as that value will be in the wrong
+ context and will not have sufficient lifespan.
+ </p><p>
+ When the aggregate's state type is declared as <code class="type">internal</code>, it is
+ usually also appropriate for the aggregate definition to provide a
+ <em class="firstterm">serialization function</em> and a <em class="firstterm">deserialization
+ function</em>, which allow such a state value to be copied from one process
+ to another. Without these functions, parallel aggregation cannot be
+ performed, and future applications such as local/remote aggregation will
+ probably not work either.
+ </p><p>
+ A serialization function must take a single argument of
+ type <code class="type">internal</code> and return a result of type <code class="type">bytea</code>, which
+ represents the state value packaged up into a flat blob of bytes.
+ Conversely, a deserialization function reverses that conversion. It must
+ take two arguments of types <code class="type">bytea</code> and <code class="type">internal</code>, and
+ return a result of type <code class="type">internal</code>. (The second argument is unused
+ and is always zero, but it is required for type-safety reasons.) The
+ result of the deserialization function should simply be allocated in the
+ current memory context, as unlike the combine function's result, it is not
+ long-lived.
+ </p><p>
+ Worth noting also is that for an aggregate to be executed in parallel,
+ the aggregate itself must be marked <code class="literal">PARALLEL SAFE</code>. The
+ parallel-safety markings on its support functions are not consulted.
+ </p></div><div class="sect2" id="XAGGR-SUPPORT-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">38.12.5. Support Functions for Aggregates</h3></div></div></div><a id="id-1.8.3.15.16.2" class="indexterm"></a><p>
+ A function written in C can detect that it is being called as an
+ aggregate support function by calling
+ <code class="function">AggCheckCallContext</code>, for example:
+</p><pre class="programlisting">
+if (AggCheckCallContext(fcinfo, NULL))
+</pre><p>
+ One reason for checking this is that when it is true, the first input
+ must be a temporary state value and can therefore safely be modified
+ in-place rather than allocating a new copy.
+ See <code class="function">int8inc()</code> for an example.
+ (While aggregate transition functions are always allowed to modify
+ the transition value in-place, aggregate final functions are generally
+ discouraged from doing so; if they do so, the behavior must be declared
+ when creating the aggregate. See <a class="xref" href="sql-createaggregate.html" title="CREATE AGGREGATE"><span class="refentrytitle">CREATE AGGREGATE</span></a>
+ for more detail.)
+ </p><p>
+ The second argument of <code class="function">AggCheckCallContext</code> can be used to
+ retrieve the memory context in which aggregate state values are being kept.
+ This is useful for transition functions that wish to use <span class="quote">“<span class="quote">expanded</span>”</span>
+ objects (see <a class="xref" href="xtypes.html#XTYPES-TOAST" title="38.13.1. TOAST Considerations">Section 38.13.1</a>) as their state values.
+ On first call, the transition function should return an expanded object
+ whose memory context is a child of the aggregate state context, and then
+ keep returning the same expanded object on subsequent calls. See
+ <code class="function">array_append()</code> for an example. (<code class="function">array_append()</code>
+ is not the transition function of any built-in aggregate, but it is written
+ to behave efficiently when used as transition function of a custom
+ aggregate.)
+ </p><p>
+ Another support routine available to aggregate functions written in C
+ is <code class="function">AggGetAggref</code>, which returns the <code class="literal">Aggref</code>
+ parse node that defines the aggregate call. This is mainly useful
+ for ordered-set aggregates, which can inspect the substructure of
+ the <code class="literal">Aggref</code> node to find out what sort ordering they are
+ supposed to implement. Examples can be found
+ in <code class="filename">orderedsetaggs.c</code> in the <span class="productname">PostgreSQL</span>
+ source code.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xtypes.html" title="38.13. User-Defined Types">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.11. Function Optimization Information </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.13. User-Defined Types</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-c.html b/doc/src/sgml/html/xfunc-c.html
new file mode 100644
index 0000000..a36377a
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-c.html
@@ -0,0 +1,1387 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.10. C-Language Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-internal.html" title="38.9. Internal Functions" /><link rel="next" href="xfunc-optimization.html" title="38.11. Function Optimization Information" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.10. C-Language Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-internal.html" title="38.9. Internal Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-C"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.10. C-Language Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-C-DYNLOAD">38.10.1. Dynamic Loading</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-C-BASETYPE">38.10.2. Base Types in C-Language Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.7">38.10.3. Version 1 Calling Conventions</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.8">38.10.4. Writing Code</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#DFUNC">38.10.5. Compiling and Linking Dynamically-Loaded Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.10">38.10.6. Composite-Type Arguments</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.11">38.10.7. Returning Rows (Composite Types)</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-C-RETURN-SET">38.10.8. Returning Sets</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#id-1.8.3.13.13">38.10.9. Polymorphic Arguments and Return Types</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#XFUNC-SHARED-ADDIN">38.10.10. Shared Memory and LWLocks</a></span></dt><dt><span class="sect2"><a href="xfunc-c.html#EXTEND-CPP">38.10.11. Using C++ for Extensibility</a></span></dt></dl></div><a id="id-1.8.3.13.2" class="indexterm"></a><p>
+ User-defined functions can be written in C (or a language that can
+ be made compatible with C, such as C++). Such functions are
+ compiled into dynamically loadable objects (also called shared
+ libraries) and are loaded by the server on demand. The dynamic
+ loading feature is what distinguishes <span class="quote">“<span class="quote">C language</span>”</span> functions
+ from <span class="quote">“<span class="quote">internal</span>”</span> functions — the actual coding conventions
+ are essentially the same for both. (Hence, the standard internal
+ function library is a rich source of coding examples for user-defined
+ C functions.)
+ </p><p>
+ Currently only one calling convention is used for C functions
+ (<span class="quote">“<span class="quote">version 1</span>”</span>). Support for that calling convention is
+ indicated by writing a <code class="literal">PG_FUNCTION_INFO_V1()</code> macro
+ call for the function, as illustrated below.
+ </p><div class="sect2" id="XFUNC-C-DYNLOAD"><div class="titlepage"><div><div><h3 class="title">38.10.1. Dynamic Loading</h3></div></div></div><a id="id-1.8.3.13.5.2" class="indexterm"></a><p>
+ The first time a user-defined function in a particular
+ loadable object file is called in a session,
+ the dynamic loader loads that object file into memory so that the
+ function can be called. The <code class="command">CREATE FUNCTION</code>
+ for a user-defined C function must therefore specify two pieces of
+ information for the function: the name of the loadable
+ object file, and the C name (link symbol) of the specific function to call
+ within that object file. If the C name is not explicitly specified then
+ it is assumed to be the same as the SQL function name.
+ </p><p>
+ The following algorithm is used to locate the shared object file
+ based on the name given in the <code class="command">CREATE FUNCTION</code>
+ command:
+
+ </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>
+ If the name is an absolute path, the given file is loaded.
+ </p></li><li class="listitem"><p>
+ If the name starts with the string <code class="literal">$libdir</code>,
+ that part is replaced by the <span class="productname">PostgreSQL</span> package
+ library directory
+ name, which is determined at build time.<a id="id-1.8.3.13.5.4.2.2.1.3" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ If the name does not contain a directory part, the file is
+ searched for in the path specified by the configuration variable
+ <a class="xref" href="runtime-config-client.html#GUC-DYNAMIC-LIBRARY-PATH">dynamic_library_path</a>.<a id="id-1.8.3.13.5.4.2.3.1.2" class="indexterm"></a>
+ </p></li><li class="listitem"><p>
+ Otherwise (the file was not found in the path, or it contains a
+ non-absolute directory part), the dynamic loader will try to
+ take the name as given, which will most likely fail. (It is
+ unreliable to depend on the current working directory.)
+ </p></li></ol></div><p>
+
+ If this sequence does not work, the platform-specific shared
+ library file name extension (often <code class="filename">.so</code>) is
+ appended to the given name and this sequence is tried again. If
+ that fails as well, the load will fail.
+ </p><p>
+ It is recommended to locate shared libraries either relative to
+ <code class="literal">$libdir</code> or through the dynamic library path.
+ This simplifies version upgrades if the new installation is at a
+ different location. The actual directory that
+ <code class="literal">$libdir</code> stands for can be found out with the
+ command <code class="literal">pg_config --pkglibdir</code>.
+ </p><p>
+ The user ID the <span class="productname">PostgreSQL</span> server runs
+ as must be able to traverse the path to the file you intend to
+ load. Making the file or a higher-level directory not readable
+ and/or not executable by the <span class="systemitem">postgres</span>
+ user is a common mistake.
+ </p><p>
+ In any case, the file name that is given in the
+ <code class="command">CREATE FUNCTION</code> command is recorded literally
+ in the system catalogs, so if the file needs to be loaded again
+ the same procedure is applied.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> will not compile a C function
+ automatically. The object file must be compiled before it is referenced
+ in a <code class="command">CREATE
+ FUNCTION</code> command. See <a class="xref" href="xfunc-c.html#DFUNC" title="38.10.5. Compiling and Linking Dynamically-Loaded Functions">Section 38.10.5</a> for additional
+ information.
+ </p></div><a id="id-1.8.3.13.5.9" class="indexterm"></a><p>
+ To ensure that a dynamically loaded object file is not loaded into an
+ incompatible server, <span class="productname">PostgreSQL</span> checks that the
+ file contains a <span class="quote">“<span class="quote">magic block</span>”</span> with the appropriate contents.
+ This allows the server to detect obvious incompatibilities, such as code
+ compiled for a different major version of
+ <span class="productname">PostgreSQL</span>. To include a magic block,
+ write this in one (and only one) of the module source files, after having
+ included the header <code class="filename">fmgr.h</code>:
+
+</p><pre class="programlisting">
+PG_MODULE_MAGIC;
+</pre><p>
+ </p><p>
+ After it is used for the first time, a dynamically loaded object
+ file is retained in memory. Future calls in the same session to
+ the function(s) in that file will only incur the small overhead of
+ a symbol table lookup. If you need to force a reload of an object
+ file, for example after recompiling it, begin a fresh session.
+ </p><a id="id-1.8.3.13.5.12" class="indexterm"></a><a id="id-1.8.3.13.5.13" class="indexterm"></a><p>
+ Optionally, a dynamically loaded file can contain an initialization
+ function. If the file includes a function named
+ <code class="function">_PG_init</code>, that function will be called immediately after
+ loading the file. The function receives no parameters and should
+ return void. There is presently no way to unload a dynamically loaded file.
+ </p></div><div class="sect2" id="XFUNC-C-BASETYPE"><div class="titlepage"><div><div><h3 class="title">38.10.2. Base Types in C-Language Functions</h3></div></div></div><a id="id-1.8.3.13.6.2" class="indexterm"></a><p>
+ To know how to write C-language functions, you need to know how
+ <span class="productname">PostgreSQL</span> internally represents base
+ data types and how they can be passed to and from functions.
+ Internally, <span class="productname">PostgreSQL</span> regards a base
+ type as a <span class="quote">“<span class="quote">blob of memory</span>”</span>. The user-defined
+ functions that you define over a type in turn define the way that
+ <span class="productname">PostgreSQL</span> can operate on it. That
+ is, <span class="productname">PostgreSQL</span> will only store and
+ retrieve the data from disk and use your user-defined functions
+ to input, process, and output the data.
+ </p><p>
+ Base types can have one of three internal formats:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ pass by value, fixed-length
+ </p></li><li class="listitem"><p>
+ pass by reference, fixed-length
+ </p></li><li class="listitem"><p>
+ pass by reference, variable-length
+ </p></li></ul></div><p>
+ </p><p>
+ By-value types can only be 1, 2, or 4 bytes in length
+ (also 8 bytes, if <code class="literal">sizeof(Datum)</code> is 8 on your machine).
+ You should be careful to define your types such that they will be the
+ same size (in bytes) on all architectures. For example, the
+ <code class="literal">long</code> type is dangerous because it is 4 bytes on some
+ machines and 8 bytes on others, whereas <code class="type">int</code> type is 4 bytes
+ on most Unix machines. A reasonable implementation of the
+ <code class="type">int4</code> type on Unix machines might be:
+
+</p><pre class="programlisting">
+/* 4-byte integer, passed by value */
+typedef int int4;
+</pre><p>
+
+ (The actual PostgreSQL C code calls this type <code class="type">int32</code>, because
+ it is a convention in C that <code class="type">int<em class="replaceable"><code>XX</code></em></code>
+ means <em class="replaceable"><code>XX</code></em> <span class="emphasis"><em>bits</em></span>. Note
+ therefore also that the C type <code class="type">int8</code> is 1 byte in size. The
+ SQL type <code class="type">int8</code> is called <code class="type">int64</code> in C. See also
+ <a class="xref" href="xfunc-c.html#XFUNC-C-TYPE-TABLE" title="Table 38.2. Equivalent C Types for Built-in SQL Types">Table 38.2</a>.)
+ </p><p>
+ On the other hand, fixed-length types of any size can
+ be passed by-reference. For example, here is a sample
+ implementation of a <span class="productname">PostgreSQL</span> type:
+
+</p><pre class="programlisting">
+/* 16-byte structure, passed by reference */
+typedef struct
+{
+ double x, y;
+} Point;
+</pre><p>
+
+ Only pointers to such types can be used when passing
+ them in and out of <span class="productname">PostgreSQL</span> functions.
+ To return a value of such a type, allocate the right amount of
+ memory with <code class="literal">palloc</code>, fill in the allocated memory,
+ and return a pointer to it. (Also, if you just want to return the
+ same value as one of your input arguments that's of the same data type,
+ you can skip the extra <code class="literal">palloc</code> and just return the
+ pointer to the input value.)
+ </p><p>
+ Finally, all variable-length types must also be passed
+ by reference. All variable-length types must begin
+ with an opaque length field of exactly 4 bytes, which will be set
+ by <code class="symbol">SET_VARSIZE</code>; never set this field directly! All data to
+ be stored within that type must be located in the memory
+ immediately following that length field. The
+ length field contains the total length of the structure,
+ that is, it includes the size of the length field
+ itself.
+ </p><p>
+ Another important point is to avoid leaving any uninitialized bits
+ within data type values; for example, take care to zero out any
+ alignment padding bytes that might be present in structs. Without
+ this, logically-equivalent constants of your data type might be
+ seen as unequal by the planner, leading to inefficient (though not
+ incorrect) plans.
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ <span class="emphasis"><em>Never</em></span> modify the contents of a pass-by-reference input
+ value. If you do so you are likely to corrupt on-disk data, since
+ the pointer you are given might point directly into a disk buffer.
+ The sole exception to this rule is explained in
+ <a class="xref" href="xaggr.html" title="38.12. User-Defined Aggregates">Section 38.12</a>.
+ </p></div><p>
+ As an example, we can define the type <code class="type">text</code> as
+ follows:
+
+</p><pre class="programlisting">
+typedef struct {
+ int32 length;
+ char data[FLEXIBLE_ARRAY_MEMBER];
+} text;
+</pre><p>
+
+ The <code class="literal">[FLEXIBLE_ARRAY_MEMBER]</code> notation means that the actual
+ length of the data part is not specified by this declaration.
+ </p><p>
+ When manipulating
+ variable-length types, we must be careful to allocate
+ the correct amount of memory and set the length field correctly.
+ For example, if we wanted to store 40 bytes in a <code class="structname">text</code>
+ structure, we might use a code fragment like this:
+
+</p><pre class="programlisting">
+#include "postgres.h"
+...
+char buffer[40]; /* our source data */
+...
+text *destination = (text *) palloc(VARHDRSZ + 40);
+SET_VARSIZE(destination, VARHDRSZ + 40);
+memcpy(destination-&gt;data, buffer, 40);
+...
+
+</pre><p>
+
+ <code class="literal">VARHDRSZ</code> is the same as <code class="literal">sizeof(int32)</code>, but
+ it's considered good style to use the macro <code class="literal">VARHDRSZ</code>
+ to refer to the size of the overhead for a variable-length type.
+ Also, the length field <span class="emphasis"><em>must</em></span> be set using the
+ <code class="literal">SET_VARSIZE</code> macro, not by simple assignment.
+ </p><p>
+ <a class="xref" href="xfunc-c.html#XFUNC-C-TYPE-TABLE" title="Table 38.2. Equivalent C Types for Built-in SQL Types">Table 38.2</a> shows the C types
+ corresponding to many of the built-in SQL data types
+ of <span class="productname">PostgreSQL</span>.
+ The <span class="quote">“<span class="quote">Defined In</span>”</span> column gives the header file that
+ needs to be included to get the type definition. (The actual
+ definition might be in a different file that is included by the
+ listed file. It is recommended that users stick to the defined
+ interface.) Note that you should always include
+ <code class="filename">postgres.h</code> first in any source file of server
+ code, because it declares a number of things that you will need
+ anyway, and because including other headers first can cause
+ portability issues.
+ </p><div class="table" id="XFUNC-C-TYPE-TABLE"><p class="title"><strong>Table 38.2. Equivalent C Types for Built-in SQL Types</strong></p><div class="table-contents"><table class="table" summary="Equivalent C Types for Built-in SQL Types" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>
+ SQL Type
+ </th><th>
+ C Type
+ </th><th>
+ Defined In
+ </th></tr></thead><tbody><tr><td><code class="type">boolean</code></td><td><code class="type">bool</code></td><td><code class="filename">postgres.h</code> (maybe compiler built-in)</td></tr><tr><td><code class="type">box</code></td><td><code class="type">BOX*</code></td><td><code class="filename">utils/geo_decls.h</code></td></tr><tr><td><code class="type">bytea</code></td><td><code class="type">bytea*</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">"char"</code></td><td><code class="type">char</code></td><td>(compiler built-in)</td></tr><tr><td><code class="type">character</code></td><td><code class="type">BpChar*</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">cid</code></td><td><code class="type">CommandId</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">date</code></td><td><code class="type">DateADT</code></td><td><code class="filename">utils/date.h</code></td></tr><tr><td><code class="type">float4</code> (<code class="type">real</code>)</td><td><code class="type">float4</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">float8</code> (<code class="type">double precision</code>)</td><td><code class="type">float8</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">int2</code> (<code class="type">smallint</code>)</td><td><code class="type">int16</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">int4</code> (<code class="type">integer</code>)</td><td><code class="type">int32</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">int8</code> (<code class="type">bigint</code>)</td><td><code class="type">int64</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">interval</code></td><td><code class="type">Interval*</code></td><td><code class="filename">datatype/timestamp.h</code></td></tr><tr><td><code class="type">lseg</code></td><td><code class="type">LSEG*</code></td><td><code class="filename">utils/geo_decls.h</code></td></tr><tr><td><code class="type">name</code></td><td><code class="type">Name</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">numeric</code></td><td><code class="type">Numeric</code></td><td><code class="filename">utils/numeric.h</code></td></tr><tr><td><code class="type">oid</code></td><td><code class="type">Oid</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">oidvector</code></td><td><code class="type">oidvector*</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">path</code></td><td><code class="type">PATH*</code></td><td><code class="filename">utils/geo_decls.h</code></td></tr><tr><td><code class="type">point</code></td><td><code class="type">POINT*</code></td><td><code class="filename">utils/geo_decls.h</code></td></tr><tr><td><code class="type">regproc</code></td><td><code class="type">RegProcedure</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">text</code></td><td><code class="type">text*</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">tid</code></td><td><code class="type">ItemPointer</code></td><td><code class="filename">storage/itemptr.h</code></td></tr><tr><td><code class="type">time</code></td><td><code class="type">TimeADT</code></td><td><code class="filename">utils/date.h</code></td></tr><tr><td><code class="type">time with time zone</code></td><td><code class="type">TimeTzADT</code></td><td><code class="filename">utils/date.h</code></td></tr><tr><td><code class="type">timestamp</code></td><td><code class="type">Timestamp</code></td><td><code class="filename">datatype/timestamp.h</code></td></tr><tr><td><code class="type">timestamp with time zone</code></td><td><code class="type">TimestampTz</code></td><td><code class="filename">datatype/timestamp.h</code></td></tr><tr><td><code class="type">varchar</code></td><td><code class="type">VarChar*</code></td><td><code class="filename">postgres.h</code></td></tr><tr><td><code class="type">xid</code></td><td><code class="type">TransactionId</code></td><td><code class="filename">postgres.h</code></td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Now that we've gone over all of the possible structures
+ for base types, we can show some examples of real functions.
+ </p></div><div class="sect2" id="id-1.8.3.13.7"><div class="titlepage"><div><div><h3 class="title">38.10.3. Version 1 Calling Conventions</h3></div></div></div><p>
+ The version-1 calling convention relies on macros to suppress most
+ of the complexity of passing arguments and results. The C declaration
+ of a version-1 function is always:
+</p><pre class="programlisting">
+Datum funcname(PG_FUNCTION_ARGS)
+</pre><p>
+ In addition, the macro call:
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(funcname);
+</pre><p>
+ must appear in the same source file. (Conventionally, it's
+ written just before the function itself.) This macro call is not
+ needed for <code class="literal">internal</code>-language functions, since
+ <span class="productname">PostgreSQL</span> assumes that all internal functions
+ use the version-1 convention. It is, however, required for
+ dynamically-loaded functions.
+ </p><p>
+ In a version-1 function, each actual argument is fetched using a
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>()</code>
+ macro that corresponds to the argument's data type. (In non-strict
+ functions there needs to be a previous check about argument null-ness
+ using <code class="function">PG_ARGISNULL()</code>; see below.)
+ The result is returned using a
+ <code class="function">PG_RETURN_<em class="replaceable"><code>xxx</code></em>()</code>
+ macro for the return type.
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>()</code>
+ takes as its argument the number of the function argument to
+ fetch, where the count starts at 0.
+ <code class="function">PG_RETURN_<em class="replaceable"><code>xxx</code></em>()</code>
+ takes as its argument the actual value to return.
+ </p><p>
+ Here are some examples using the version-1 calling convention:
+ </p><pre class="programlisting">
+#include "postgres.h"
+#include &lt;string.h&gt;
+#include "fmgr.h"
+#include "utils/geo_decls.h"
+
+PG_MODULE_MAGIC;
+
+/* by value */
+
+PG_FUNCTION_INFO_V1(add_one);
+
+Datum
+add_one(PG_FUNCTION_ARGS)
+{
+ int32 arg = PG_GETARG_INT32(0);
+
+ PG_RETURN_INT32(arg + 1);
+}
+
+/* by reference, fixed length */
+
+PG_FUNCTION_INFO_V1(add_one_float8);
+
+Datum
+add_one_float8(PG_FUNCTION_ARGS)
+{
+ /* The macros for FLOAT8 hide its pass-by-reference nature. */
+ float8 arg = PG_GETARG_FLOAT8(0);
+
+ PG_RETURN_FLOAT8(arg + 1.0);
+}
+
+PG_FUNCTION_INFO_V1(makepoint);
+
+Datum
+makepoint(PG_FUNCTION_ARGS)
+{
+ /* Here, the pass-by-reference nature of Point is not hidden. */
+ Point *pointx = PG_GETARG_POINT_P(0);
+ Point *pointy = PG_GETARG_POINT_P(1);
+ Point *new_point = (Point *) palloc(sizeof(Point));
+
+ new_point-&gt;x = pointx-&gt;x;
+ new_point-&gt;y = pointy-&gt;y;
+
+ PG_RETURN_POINT_P(new_point);
+}
+
+/* by reference, variable length */
+
+PG_FUNCTION_INFO_V1(copytext);
+
+Datum
+copytext(PG_FUNCTION_ARGS)
+{
+ text *t = PG_GETARG_TEXT_PP(0);
+
+ /*
+ * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the
+ * VARHDRSZ or VARHDRSZ_SHORT of its header. Construct the copy with a
+ * full-length header.
+ */
+ text *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ);
+ SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ);
+
+ /*
+ * VARDATA is a pointer to the data region of the new struct. The source
+ * could be a short datum, so retrieve its data through VARDATA_ANY.
+ */
+ memcpy((void *) VARDATA(new_t), /* destination */
+ (void *) VARDATA_ANY(t), /* source */
+ VARSIZE_ANY_EXHDR(t)); /* how many bytes */
+ PG_RETURN_TEXT_P(new_t);
+}
+
+PG_FUNCTION_INFO_V1(concat_text);
+
+Datum
+concat_text(PG_FUNCTION_ARGS)
+{
+ text *arg1 = PG_GETARG_TEXT_PP(0);
+ text *arg2 = PG_GETARG_TEXT_PP(1);
+ int32 arg1_size = VARSIZE_ANY_EXHDR(arg1);
+ int32 arg2_size = VARSIZE_ANY_EXHDR(arg2);
+ int32 new_text_size = arg1_size + arg2_size + VARHDRSZ;
+ text *new_text = (text *) palloc(new_text_size);
+
+ SET_VARSIZE(new_text, new_text_size);
+ memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);
+ memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);
+ PG_RETURN_TEXT_P(new_text);
+}
+
+</pre><p>
+ Supposing that the above code has been prepared in file
+ <code class="filename">funcs.c</code> and compiled into a shared object,
+ we could define the functions to <span class="productname">PostgreSQL</span>
+ with commands like this:
+ </p><pre class="programlisting">
+CREATE FUNCTION add_one(integer) RETURNS integer
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'add_one'
+ LANGUAGE C STRICT;
+
+-- note overloading of SQL function name "add_one"
+CREATE FUNCTION add_one(double precision) RETURNS double precision
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'add_one_float8'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION makepoint(point, point) RETURNS point
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'makepoint'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION copytext(text) RETURNS text
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'copytext'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION concat_text(text, text) RETURNS text
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'concat_text'
+ LANGUAGE C STRICT;
+</pre><p>
+ Here, <em class="replaceable"><code>DIRECTORY</code></em> stands for the
+ directory of the shared library file (for instance the
+ <span class="productname">PostgreSQL</span> tutorial directory, which
+ contains the code for the examples used in this section).
+ (Better style would be to use just <code class="literal">'funcs'</code> in the
+ <code class="literal">AS</code> clause, after having added
+ <em class="replaceable"><code>DIRECTORY</code></em> to the search path. In any
+ case, we can omit the system-specific extension for a shared
+ library, commonly <code class="literal">.so</code>.)
+ </p><p>
+ Notice that we have specified the functions as <span class="quote">“<span class="quote">strict</span>”</span>,
+ meaning that
+ the system should automatically assume a null result if any input
+ value is null. By doing this, we avoid having to check for null inputs
+ in the function code. Without this, we'd have to check for null values
+ explicitly, using <code class="function">PG_ARGISNULL()</code>.
+ </p><p>
+ The macro <code class="function">PG_ARGISNULL(<em class="replaceable"><code>n</code></em>)</code>
+ allows a function to test whether each input is null. (Of course, doing
+ this is only necessary in functions not declared <span class="quote">“<span class="quote">strict</span>”</span>.)
+ As with the
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>()</code> macros,
+ the input arguments are counted beginning at zero. Note that one
+ should refrain from executing
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>()</code> until
+ one has verified that the argument isn't null.
+ To return a null result, execute <code class="function">PG_RETURN_NULL()</code>;
+ this works in both strict and nonstrict functions.
+ </p><p>
+ At first glance, the version-1 coding conventions might appear
+ to be just pointless obscurantism, compared to using
+ plain <code class="literal">C</code> calling conventions. They do however allow
+ us to deal with <code class="literal">NULL</code>able arguments/return values,
+ and <span class="quote">“<span class="quote">toasted</span>”</span> (compressed or out-of-line) values.
+ </p><p>
+ Other options provided by the version-1 interface are two
+ variants of the
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>()</code>
+ macros. The first of these,
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>_COPY()</code>,
+ guarantees to return a copy of the specified argument that is
+ safe for writing into. (The normal macros will sometimes return a
+ pointer to a value that is physically stored in a table, which
+ must not be written to. Using the
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>_COPY()</code>
+ macros guarantees a writable result.)
+ The second variant consists of the
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em>_SLICE()</code>
+ macros which take three arguments. The first is the number of the
+ function argument (as above). The second and third are the offset and
+ length of the segment to be returned. Offsets are counted from
+ zero, and a negative length requests that the remainder of the
+ value be returned. These macros provide more efficient access to
+ parts of large values in the case where they have storage type
+ <span class="quote">“<span class="quote">external</span>”</span>. (The storage type of a column can be specified using
+ <code class="literal">ALTER TABLE <em class="replaceable"><code>tablename</code></em> ALTER
+ COLUMN <em class="replaceable"><code>colname</code></em> SET STORAGE
+ <em class="replaceable"><code>storagetype</code></em></code>. <em class="replaceable"><code>storagetype</code></em> is one of
+ <code class="literal">plain</code>, <code class="literal">external</code>, <code class="literal">extended</code>,
+ or <code class="literal">main</code>.)
+ </p><p>
+ Finally, the version-1 function call conventions make it possible
+ to return set results (<a class="xref" href="xfunc-c.html#XFUNC-C-RETURN-SET" title="38.10.8. Returning Sets">Section 38.10.8</a>) and
+ implement trigger functions (<a class="xref" href="triggers.html" title="Chapter 39. Triggers">Chapter 39</a>) and
+ procedural-language call handlers (<a class="xref" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Chapter 58</a>). For more details
+ see <code class="filename">src/backend/utils/fmgr/README</code> in the
+ source distribution.
+ </p></div><div class="sect2" id="id-1.8.3.13.8"><div class="titlepage"><div><div><h3 class="title">38.10.4. Writing Code</h3></div></div></div><p>
+ Before we turn to the more advanced topics, we should discuss
+ some coding rules for <span class="productname">PostgreSQL</span>
+ C-language functions. While it might be possible to load functions
+ written in languages other than C into
+ <span class="productname">PostgreSQL</span>, this is usually difficult
+ (when it is possible at all) because other languages, such as
+ C++, FORTRAN, or Pascal often do not follow the same calling
+ convention as C. That is, other languages do not pass argument
+ and return values between functions in the same way. For this
+ reason, we will assume that your C-language functions are
+ actually written in C.
+ </p><p>
+ The basic rules for writing and building C functions are as follows:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Use <code class="literal">pg_config
+ --includedir-server</code><a id="id-1.8.3.13.8.3.1.1.1.2" class="indexterm"></a>
+ to find out where the <span class="productname">PostgreSQL</span> server header
+ files are installed on your system (or the system that your
+ users will be running on).
+ </p></li><li class="listitem"><p>
+ Compiling and linking your code so that it can be dynamically
+ loaded into <span class="productname">PostgreSQL</span> always
+ requires special flags. See <a class="xref" href="xfunc-c.html#DFUNC" title="38.10.5. Compiling and Linking Dynamically-Loaded Functions">Section 38.10.5</a> for a
+ detailed explanation of how to do it for your particular
+ operating system.
+ </p></li><li class="listitem"><p>
+ Remember to define a <span class="quote">“<span class="quote">magic block</span>”</span> for your shared library,
+ as described in <a class="xref" href="xfunc-c.html#XFUNC-C-DYNLOAD" title="38.10.1. Dynamic Loading">Section 38.10.1</a>.
+ </p></li><li class="listitem"><p>
+ When allocating memory, use the
+ <span class="productname">PostgreSQL</span> functions
+ <code class="function">palloc</code><a id="id-1.8.3.13.8.3.1.4.1.3" class="indexterm"></a> and <code class="function">pfree</code><a id="id-1.8.3.13.8.3.1.4.1.5" class="indexterm"></a>
+ instead of the corresponding C library functions
+ <code class="function">malloc</code> and <code class="function">free</code>.
+ The memory allocated by <code class="function">palloc</code> will be
+ freed automatically at the end of each transaction, preventing
+ memory leaks.
+ </p></li><li class="listitem"><p>
+ Always zero the bytes of your structures using <code class="function">memset</code>
+ (or allocate them with <code class="function">palloc0</code> in the first place).
+ Even if you assign to each field of your structure, there might be
+ alignment padding (holes in the structure) that contain
+ garbage values. Without this, it's difficult to
+ support hash indexes or hash joins, as you must pick out only
+ the significant bits of your data structure to compute a hash.
+ The planner also sometimes relies on comparing constants via
+ bitwise equality, so you can get undesirable planning results if
+ logically-equivalent values aren't bitwise equal.
+ </p></li><li class="listitem"><p>
+ Most of the internal <span class="productname">PostgreSQL</span>
+ types are declared in <code class="filename">postgres.h</code>, while
+ the function manager interfaces
+ (<code class="symbol">PG_FUNCTION_ARGS</code>, etc.) are in
+ <code class="filename">fmgr.h</code>, so you will need to include at
+ least these two files. For portability reasons it's best to
+ include <code class="filename">postgres.h</code> <span class="emphasis"><em>first</em></span>,
+ before any other system or user header files. Including
+ <code class="filename">postgres.h</code> will also include
+ <code class="filename">elog.h</code> and <code class="filename">palloc.h</code>
+ for you.
+ </p></li><li class="listitem"><p>
+ Symbol names defined within object files must not conflict
+ with each other or with symbols defined in the
+ <span class="productname">PostgreSQL</span> server executable. You
+ will have to rename your functions or variables if you get
+ error messages to this effect.
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="DFUNC"><div class="titlepage"><div><div><h3 class="title">38.10.5. Compiling and Linking Dynamically-Loaded Functions</h3></div></div></div><p>
+ Before you are able to use your
+ <span class="productname">PostgreSQL</span> extension functions written in
+ C, they must be compiled and linked in a special way to produce a
+ file that can be dynamically loaded by the server. To be precise, a
+ <em class="firstterm">shared library</em> needs to be
+ created.<a id="id-1.8.3.13.9.2.3" class="indexterm"></a>
+
+ </p><p>
+ For information beyond what is contained in this section
+ you should read the documentation of your
+ operating system, in particular the manual pages for the C compiler,
+ <code class="command">cc</code>, and the link editor, <code class="command">ld</code>.
+ In addition, the <span class="productname">PostgreSQL</span> source code
+ contains several working examples in the
+ <code class="filename">contrib</code> directory. If you rely on these
+ examples you will make your modules dependent on the availability
+ of the <span class="productname">PostgreSQL</span> source code, however.
+ </p><p>
+ Creating shared libraries is generally analogous to linking
+ executables: first the source files are compiled into object files,
+ then the object files are linked together. The object files need to
+ be created as <em class="firstterm">position-independent code</em>
+ (<acronym class="acronym">PIC</acronym>),<a id="id-1.8.3.13.9.4.3" class="indexterm"></a> which
+ conceptually means that they can be placed at an arbitrary location
+ in memory when they are loaded by the executable. (Object files
+ intended for executables are usually not compiled that way.) The
+ command to link a shared library contains special flags to
+ distinguish it from linking an executable (at least in theory
+ — on some systems the practice is much uglier).
+ </p><p>
+ In the following examples we assume that your source code is in a
+ file <code class="filename">foo.c</code> and we will create a shared library
+ <code class="filename">foo.so</code>. The intermediate object file will be
+ called <code class="filename">foo.o</code> unless otherwise noted. A shared
+ library can contain more than one object file, but we only use one
+ here.
+ </p><div class="variablelist"><dl class="variablelist"><dt><span class="term">
+ <span class="systemitem">FreeBSD</span>
+ <a id="id-1.8.3.13.9.6.1.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The compiler flag to create <acronym class="acronym">PIC</acronym> is
+ <code class="option">-fPIC</code>. To create shared libraries the compiler
+ flag is <code class="option">-shared</code>.
+</p><pre class="programlisting">
+gcc -fPIC -c foo.c
+gcc -shared -o foo.so foo.o
+</pre><p>
+ This is applicable as of version 3.0 of
+ <span class="systemitem">FreeBSD</span>.
+ </p></dd><dt><span class="term">
+ <span class="systemitem">HP-UX</span>
+ <a id="id-1.8.3.13.9.6.2.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The compiler flag of the system compiler to create
+ <acronym class="acronym">PIC</acronym> is <code class="option">+z</code>. When using
+ <span class="application">GCC</span> it's <code class="option">-fPIC</code>. The
+ linker flag for shared libraries is <code class="option">-b</code>. So:
+</p><pre class="programlisting">
+cc +z -c foo.c
+</pre><p>
+ or:
+</p><pre class="programlisting">
+gcc -fPIC -c foo.c
+</pre><p>
+ and then:
+</p><pre class="programlisting">
+ld -b -o foo.sl foo.o
+</pre><p>
+ <span class="systemitem">HP-UX</span> uses the extension
+ <code class="filename">.sl</code> for shared libraries, unlike most other
+ systems.
+ </p></dd><dt><span class="term">
+ <span class="systemitem">Linux</span>
+ <a id="id-1.8.3.13.9.6.3.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The compiler flag to create <acronym class="acronym">PIC</acronym> is
+ <code class="option">-fPIC</code>.
+ The compiler flag to create a shared library is
+ <code class="option">-shared</code>. A complete example looks like this:
+</p><pre class="programlisting">
+cc -fPIC -c foo.c
+cc -shared -o foo.so foo.o
+</pre><p>
+ </p></dd><dt><span class="term">
+ <span class="systemitem">macOS</span>
+ <a id="id-1.8.3.13.9.6.4.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ Here is an example. It assumes the developer tools are installed.
+</p><pre class="programlisting">
+cc -c foo.c
+cc -bundle -flat_namespace -undefined suppress -o foo.so foo.o
+</pre><p>
+ </p></dd><dt><span class="term">
+ <span class="systemitem">NetBSD</span>
+ <a id="id-1.8.3.13.9.6.5.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The compiler flag to create <acronym class="acronym">PIC</acronym> is
+ <code class="option">-fPIC</code>. For <acronym class="acronym">ELF</acronym> systems, the
+ compiler with the flag <code class="option">-shared</code> is used to link
+ shared libraries. On the older non-ELF systems, <code class="literal">ld
+ -Bshareable</code> is used.
+</p><pre class="programlisting">
+gcc -fPIC -c foo.c
+gcc -shared -o foo.so foo.o
+</pre><p>
+ </p></dd><dt><span class="term">
+ <span class="systemitem">OpenBSD</span>
+ <a id="id-1.8.3.13.9.6.6.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The compiler flag to create <acronym class="acronym">PIC</acronym> is
+ <code class="option">-fPIC</code>. <code class="literal">ld -Bshareable</code> is
+ used to link shared libraries.
+</p><pre class="programlisting">
+gcc -fPIC -c foo.c
+ld -Bshareable -o foo.so foo.o
+</pre><p>
+ </p></dd><dt><span class="term">
+ <span class="systemitem">Solaris</span>
+ <a id="id-1.8.3.13.9.6.7.1.2" class="indexterm"></a>
+ </span></dt><dd><p>
+ The compiler flag to create <acronym class="acronym">PIC</acronym> is
+ <code class="option">-KPIC</code> with the Sun compiler and
+ <code class="option">-fPIC</code> with <span class="application">GCC</span>. To
+ link shared libraries, the compiler option is
+ <code class="option">-G</code> with either compiler or alternatively
+ <code class="option">-shared</code> with <span class="application">GCC</span>.
+</p><pre class="programlisting">
+cc -KPIC -c foo.c
+cc -G -o foo.so foo.o
+</pre><p>
+ or
+</p><pre class="programlisting">
+gcc -fPIC -c foo.c
+gcc -G -o foo.so foo.o
+</pre><p>
+ </p></dd></dl></div><div class="tip"><h3 class="title">Tip</h3><p>
+ If this is too complicated for you, you should consider using
+ <a class="ulink" href="https://www.gnu.org/software/libtool/" target="_top">
+ <span class="productname">GNU Libtool</span></a>,
+ which hides the platform differences behind a uniform interface.
+ </p></div><p>
+ The resulting shared library file can then be loaded into
+ <span class="productname">PostgreSQL</span>. When specifying the file name
+ to the <code class="command">CREATE FUNCTION</code> command, one must give it
+ the name of the shared library file, not the intermediate object file.
+ Note that the system's standard shared-library extension (usually
+ <code class="literal">.so</code> or <code class="literal">.sl</code>) can be omitted from
+ the <code class="command">CREATE FUNCTION</code> command, and normally should
+ be omitted for best portability.
+ </p><p>
+ Refer back to <a class="xref" href="xfunc-c.html#XFUNC-C-DYNLOAD" title="38.10.1. Dynamic Loading">Section 38.10.1</a> about where the
+ server expects to find the shared library files.
+ </p></div><div class="sect2" id="id-1.8.3.13.10"><div class="titlepage"><div><div><h3 class="title">38.10.6. Composite-Type Arguments</h3></div></div></div><p>
+ Composite types do not have a fixed layout like C structures.
+ Instances of a composite type can contain null fields. In
+ addition, composite types that are part of an inheritance
+ hierarchy can have different fields than other members of the
+ same inheritance hierarchy. Therefore,
+ <span class="productname">PostgreSQL</span> provides a function
+ interface for accessing fields of composite types from C.
+ </p><p>
+ Suppose we want to write a function to answer the query:
+
+</p><pre class="programlisting">
+SELECT name, c_overpaid(emp, 1500) AS overpaid
+ FROM emp
+ WHERE name = 'Bill' OR name = 'Sam';
+</pre><p>
+
+ Using the version-1 calling conventions, we can define
+ <code class="function">c_overpaid</code> as:
+
+</p><pre class="programlisting">
+#include "postgres.h"
+#include "executor/executor.h" /* for GetAttributeByName() */
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(c_overpaid);
+
+Datum
+c_overpaid(PG_FUNCTION_ARGS)
+{
+ HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
+ int32 limit = PG_GETARG_INT32(1);
+ bool isnull;
+ Datum salary;
+
+ salary = GetAttributeByName(t, "salary", &amp;isnull);
+ if (isnull)
+ PG_RETURN_BOOL(false);
+ /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */
+
+ PG_RETURN_BOOL(DatumGetInt32(salary) &gt; limit);
+}
+
+</pre><p>
+ </p><p>
+ <code class="function">GetAttributeByName</code> is the
+ <span class="productname">PostgreSQL</span> system function that
+ returns attributes out of the specified row. It has
+ three arguments: the argument of type <code class="type">HeapTupleHeader</code> passed
+ into
+ the function, the name of the desired attribute, and a
+ return parameter that tells whether the attribute
+ is null. <code class="function">GetAttributeByName</code> returns a <code class="type">Datum</code>
+ value that you can convert to the proper data type by using the
+ appropriate <code class="function">DatumGet<em class="replaceable"><code>XXX</code></em>()</code>
+ macro. Note that the return value is meaningless if the null flag is
+ set; always check the null flag before trying to do anything with the
+ result.
+ </p><p>
+ There is also <code class="function">GetAttributeByNum</code>, which selects
+ the target attribute by column number instead of name.
+ </p><p>
+ The following command declares the function
+ <code class="function">c_overpaid</code> in SQL:
+
+</p><pre class="programlisting">
+CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'c_overpaid'
+ LANGUAGE C STRICT;
+</pre><p>
+
+ Notice we have used <code class="literal">STRICT</code> so that we did not have to
+ check whether the input arguments were NULL.
+ </p></div><div class="sect2" id="id-1.8.3.13.11"><div class="titlepage"><div><div><h3 class="title">38.10.7. Returning Rows (Composite Types)</h3></div></div></div><p>
+ To return a row or composite-type value from a C-language
+ function, you can use a special API that provides macros and
+ functions to hide most of the complexity of building composite
+ data types. To use this API, the source file must include:
+</p><pre class="programlisting">
+#include "funcapi.h"
+</pre><p>
+ </p><p>
+ There are two ways you can build a composite data value (henceforth
+ a <span class="quote">“<span class="quote">tuple</span>”</span>): you can build it from an array of Datum values,
+ or from an array of C strings that can be passed to the input
+ conversion functions of the tuple's column data types. In either
+ case, you first need to obtain or construct a <code class="structname">TupleDesc</code>
+ descriptor for the tuple structure. When working with Datums, you
+ pass the <code class="structname">TupleDesc</code> to <code class="function">BlessTupleDesc</code>,
+ and then call <code class="function">heap_form_tuple</code> for each row. When working
+ with C strings, you pass the <code class="structname">TupleDesc</code> to
+ <code class="function">TupleDescGetAttInMetadata</code>, and then call
+ <code class="function">BuildTupleFromCStrings</code> for each row. In the case of a
+ function returning a set of tuples, the setup steps can all be done
+ once during the first call of the function.
+ </p><p>
+ Several helper functions are available for setting up the needed
+ <code class="structname">TupleDesc</code>. The recommended way to do this in most
+ functions returning composite values is to call:
+</p><pre class="programlisting">
+TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
+ Oid *resultTypeId,
+ TupleDesc *resultTupleDesc)
+</pre><p>
+ passing the same <code class="literal">fcinfo</code> struct passed to the calling function
+ itself. (This of course requires that you use the version-1
+ calling conventions.) <code class="varname">resultTypeId</code> can be specified
+ as <code class="literal">NULL</code> or as the address of a local variable to receive the
+ function's result type OID. <code class="varname">resultTupleDesc</code> should be the
+ address of a local <code class="structname">TupleDesc</code> variable. Check that the
+ result is <code class="literal">TYPEFUNC_COMPOSITE</code>; if so,
+ <code class="varname">resultTupleDesc</code> has been filled with the needed
+ <code class="structname">TupleDesc</code>. (If it is not, you can report an error along
+ the lines of <span class="quote">“<span class="quote">function returning record called in context that
+ cannot accept type record</span>”</span>.)
+ </p><div class="tip"><h3 class="title">Tip</h3><p>
+ <code class="function">get_call_result_type</code> can resolve the actual type of a
+ polymorphic function result; so it is useful in functions that return
+ scalar polymorphic results, not only functions that return composites.
+ The <code class="varname">resultTypeId</code> output is primarily useful for functions
+ returning polymorphic scalars.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ <code class="function">get_call_result_type</code> has a sibling
+ <code class="function">get_expr_result_type</code>, which can be used to resolve the
+ expected output type for a function call represented by an expression
+ tree. This can be used when trying to determine the result type from
+ outside the function itself. There is also
+ <code class="function">get_func_result_type</code>, which can be used when only the
+ function's OID is available. However these functions are not able
+ to deal with functions declared to return <code class="structname">record</code>, and
+ <code class="function">get_func_result_type</code> cannot resolve polymorphic types,
+ so you should preferentially use <code class="function">get_call_result_type</code>.
+ </p></div><p>
+ Older, now-deprecated functions for obtaining
+ <code class="structname">TupleDesc</code>s are:
+</p><pre class="programlisting">
+TupleDesc RelationNameGetTupleDesc(const char *relname)
+</pre><p>
+ to get a <code class="structname">TupleDesc</code> for the row type of a named relation,
+ and:
+</p><pre class="programlisting">
+TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
+</pre><p>
+ to get a <code class="structname">TupleDesc</code> based on a type OID. This can
+ be used to get a <code class="structname">TupleDesc</code> for a base or
+ composite type. It will not work for a function that returns
+ <code class="structname">record</code>, however, and it cannot resolve polymorphic
+ types.
+ </p><p>
+ Once you have a <code class="structname">TupleDesc</code>, call:
+</p><pre class="programlisting">
+TupleDesc BlessTupleDesc(TupleDesc tupdesc)
+</pre><p>
+ if you plan to work with Datums, or:
+</p><pre class="programlisting">
+AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)
+</pre><p>
+ if you plan to work with C strings. If you are writing a function
+ returning set, you can save the results of these functions in the
+ <code class="structname">FuncCallContext</code> structure — use the
+ <code class="structfield">tuple_desc</code> or <code class="structfield">attinmeta</code> field
+ respectively.
+ </p><p>
+ When working with Datums, use:
+</p><pre class="programlisting">
+HeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)
+</pre><p>
+ to build a <code class="structname">HeapTuple</code> given user data in Datum form.
+ </p><p>
+ When working with C strings, use:
+</p><pre class="programlisting">
+HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
+</pre><p>
+ to build a <code class="structname">HeapTuple</code> given user data
+ in C string form. <em class="parameter"><code>values</code></em> is an array of C strings,
+ one for each attribute of the return row. Each C string should be in
+ the form expected by the input function of the attribute data
+ type. In order to return a null value for one of the attributes,
+ the corresponding pointer in the <em class="parameter"><code>values</code></em> array
+ should be set to <code class="symbol">NULL</code>. This function will need to
+ be called again for each row you return.
+ </p><p>
+ Once you have built a tuple to return from your function, it
+ must be converted into a <code class="type">Datum</code>. Use:
+</p><pre class="programlisting">
+HeapTupleGetDatum(HeapTuple tuple)
+</pre><p>
+ to convert a <code class="structname">HeapTuple</code> into a valid Datum. This
+ <code class="type">Datum</code> can be returned directly if you intend to return
+ just a single row, or it can be used as the current return value
+ in a set-returning function.
+ </p><p>
+ An example appears in the next section.
+ </p></div><div class="sect2" id="XFUNC-C-RETURN-SET"><div class="titlepage"><div><div><h3 class="title">38.10.8. Returning Sets</h3></div></div></div><p>
+ C-language functions have two options for returning sets (multiple
+ rows). In one method, called <em class="firstterm">ValuePerCall</em>
+ mode, a set-returning function is called repeatedly (passing the same
+ arguments each time) and it returns one new row on each call, until
+ it has no more rows to return and signals that by returning NULL.
+ The set-returning function (<acronym class="acronym">SRF</acronym>) must therefore
+ save enough state across calls to remember what it was doing and
+ return the correct next item on each call.
+ In the other method, called <em class="firstterm">Materialize</em> mode,
+ an SRF fills and returns a tuplestore object containing its
+ entire result; then only one call occurs for the whole result, and
+ no inter-call state is needed.
+ </p><p>
+ When using ValuePerCall mode, it is important to remember that the
+ query is not guaranteed to be run to completion; that is, due to
+ options such as <code class="literal">LIMIT</code>, the executor might stop
+ making calls to the set-returning function before all rows have been
+ fetched. This means it is not safe to perform cleanup activities in
+ the last call, because that might not ever happen. It's recommended
+ to use Materialize mode for functions that need access to external
+ resources, such as file descriptors.
+ </p><p>
+ The remainder of this section documents a set of helper macros that
+ are commonly used (though not required to be used) for SRFs using
+ ValuePerCall mode. Additional details about Materialize mode can be
+ found in <code class="filename">src/backend/utils/fmgr/README</code>. Also,
+ the <code class="filename">contrib</code> modules in
+ the <span class="productname">PostgreSQL</span> source distribution contain
+ many examples of SRFs using both ValuePerCall and Materialize mode.
+ </p><p>
+ To use the ValuePerCall support macros described here,
+ include <code class="filename">funcapi.h</code>. These macros work with a
+ structure <code class="structname">FuncCallContext</code> that contains the
+ state that needs to be saved across calls. Within the calling
+ SRF, <code class="literal">fcinfo-&gt;flinfo-&gt;fn_extra</code> is used to
+ hold a pointer to <code class="structname">FuncCallContext</code> across
+ calls. The macros automatically fill that field on first use,
+ and expect to find the same pointer there on subsequent uses.
+</p><pre class="programlisting">
+typedef struct FuncCallContext
+{
+ /*
+ * Number of times we've been called before
+ *
+ * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
+ * incremented for you every time SRF_RETURN_NEXT() is called.
+ */
+ uint64 call_cntr;
+
+ /*
+ * OPTIONAL maximum number of calls
+ *
+ * max_calls is here for convenience only and setting it is optional.
+ * If not set, you must provide alternative means to know when the
+ * function is done.
+ */
+ uint64 max_calls;
+
+ /*
+ * OPTIONAL pointer to miscellaneous user-provided context information
+ *
+ * user_fctx is for use as a pointer to your own data to retain
+ * arbitrary context information between calls of your function.
+ */
+ void *user_fctx;
+
+ /*
+ * OPTIONAL pointer to struct containing attribute type input metadata
+ *
+ * attinmeta is for use when returning tuples (i.e., composite data types)
+ * and is not used when returning base data types. It is only needed
+ * if you intend to use BuildTupleFromCStrings() to create the return
+ * tuple.
+ */
+ AttInMetadata *attinmeta;
+
+ /*
+ * memory context used for structures that must live for multiple calls
+ *
+ * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
+ * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
+ * context for any memory that is to be reused across multiple calls
+ * of the SRF.
+ */
+ MemoryContext multi_call_memory_ctx;
+
+ /*
+ * OPTIONAL pointer to struct containing tuple description
+ *
+ * tuple_desc is for use when returning tuples (i.e., composite data types)
+ * and is only needed if you are going to build the tuples with
+ * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that
+ * the TupleDesc pointer stored here should usually have been run through
+ * BlessTupleDesc() first.
+ */
+ TupleDesc tuple_desc;
+
+} FuncCallContext;
+</pre><p>
+ </p><p>
+ The macros to be used by an <acronym class="acronym">SRF</acronym> using this
+ infrastructure are:
+</p><pre class="programlisting">
+SRF_IS_FIRSTCALL()
+</pre><p>
+ Use this to determine if your function is being called for the first or a
+ subsequent time. On the first call (only), call:
+</p><pre class="programlisting">
+SRF_FIRSTCALL_INIT()
+</pre><p>
+ to initialize the <code class="structname">FuncCallContext</code>. On every function call,
+ including the first, call:
+</p><pre class="programlisting">
+SRF_PERCALL_SETUP()
+</pre><p>
+ to set up for using the <code class="structname">FuncCallContext</code>.
+ </p><p>
+ If your function has data to return in the current call, use:
+</p><pre class="programlisting">
+SRF_RETURN_NEXT(funcctx, result)
+</pre><p>
+ to return it to the caller. (<code class="literal">result</code> must be of type
+ <code class="type">Datum</code>, either a single value or a tuple prepared as
+ described above.) Finally, when your function is finished
+ returning data, use:
+</p><pre class="programlisting">
+SRF_RETURN_DONE(funcctx)
+</pre><p>
+ to clean up and end the <acronym class="acronym">SRF</acronym>.
+ </p><p>
+ The memory context that is current when the <acronym class="acronym">SRF</acronym> is called is
+ a transient context that will be cleared between calls. This means
+ that you do not need to call <code class="function">pfree</code> on everything
+ you allocated using <code class="function">palloc</code>; it will go away anyway. However, if you want to allocate
+ any data structures to live across calls, you need to put them somewhere
+ else. The memory context referenced by
+ <code class="structfield">multi_call_memory_ctx</code> is a suitable location for any
+ data that needs to survive until the <acronym class="acronym">SRF</acronym> is finished running. In most
+ cases, this means that you should switch into
+ <code class="structfield">multi_call_memory_ctx</code> while doing the
+ first-call setup.
+ Use <code class="literal">funcctx-&gt;user_fctx</code> to hold a pointer to
+ any such cross-call data structures.
+ (Data you allocate
+ in <code class="structfield">multi_call_memory_ctx</code> will go away
+ automatically when the query ends, so it is not necessary to free
+ that data manually, either.)
+ </p><div class="warning"><h3 class="title">Warning</h3><p>
+ While the actual arguments to the function remain unchanged between
+ calls, if you detoast the argument values (which is normally done
+ transparently by the
+ <code class="function">PG_GETARG_<em class="replaceable"><code>xxx</code></em></code> macro)
+ in the transient context then the detoasted copies will be freed on
+ each cycle. Accordingly, if you keep references to such values in
+ your <code class="structfield">user_fctx</code>, you must either copy them into the
+ <code class="structfield">multi_call_memory_ctx</code> after detoasting, or ensure
+ that you detoast the values only in that context.
+ </p></div><p>
+ A complete pseudo-code example looks like the following:
+</p><pre class="programlisting">
+Datum
+my_set_returning_function(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+ <em class="replaceable"><code>further declarations as needed</code></em>
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ MemoryContext oldcontext;
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ oldcontext = MemoryContextSwitchTo(funcctx-&gt;multi_call_memory_ctx);
+ /* One-time setup code appears here: */
+ <em class="replaceable"><code>user code</code></em>
+ <em class="replaceable"><code>if returning composite</code></em>
+ <em class="replaceable"><code>build TupleDesc, and perhaps AttInMetadata</code></em>
+ <em class="replaceable"><code>endif returning composite</code></em>
+ <em class="replaceable"><code>user code</code></em>
+ MemoryContextSwitchTo(oldcontext);
+ }
+
+ /* Each-time setup code appears here: */
+ <em class="replaceable"><code>user code</code></em>
+ funcctx = SRF_PERCALL_SETUP();
+ <em class="replaceable"><code>user code</code></em>
+
+ /* this is just one way we might test whether we are done: */
+ if (funcctx-&gt;call_cntr &lt; funcctx-&gt;max_calls)
+ {
+ /* Here we want to return another item: */
+ <em class="replaceable"><code>user code</code></em>
+ <em class="replaceable"><code>obtain result Datum</code></em>
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else
+ {
+ /* Here we are done returning items, so just report that fact. */
+ /* (Resist the temptation to put cleanup code here.) */
+ SRF_RETURN_DONE(funcctx);
+ }
+}
+</pre><p>
+ </p><p>
+ A complete example of a simple <acronym class="acronym">SRF</acronym> returning a composite type
+ looks like:
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(retcomposite);
+
+Datum
+retcomposite(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ int call_cntr;
+ int max_calls;
+ TupleDesc tupdesc;
+ AttInMetadata *attinmeta;
+
+ /* stuff done only on the first call of the function */
+ if (SRF_IS_FIRSTCALL())
+ {
+ MemoryContext oldcontext;
+
+ /* create a function context for cross-call persistence */
+ funcctx = SRF_FIRSTCALL_INIT();
+
+ /* switch to memory context appropriate for multiple function calls */
+ oldcontext = MemoryContextSwitchTo(funcctx-&gt;multi_call_memory_ctx);
+
+ /* total number of tuples to be returned */
+ funcctx-&gt;max_calls = PG_GETARG_INT32(0);
+
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &amp;tupdesc) != TYPEFUNC_COMPOSITE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("function returning record called in context "
+ "that cannot accept type record")));
+
+ /*
+ * generate attribute metadata needed later to produce tuples from raw
+ * C strings
+ */
+ attinmeta = TupleDescGetAttInMetadata(tupdesc);
+ funcctx-&gt;attinmeta = attinmeta;
+
+ MemoryContextSwitchTo(oldcontext);
+ }
+
+ /* stuff done on every call of the function */
+ funcctx = SRF_PERCALL_SETUP();
+
+ call_cntr = funcctx-&gt;call_cntr;
+ max_calls = funcctx-&gt;max_calls;
+ attinmeta = funcctx-&gt;attinmeta;
+
+ if (call_cntr &lt; max_calls) /* do when there is more left to send */
+ {
+ char **values;
+ HeapTuple tuple;
+ Datum result;
+
+ /*
+ * Prepare a values array for building the returned tuple.
+ * This should be an array of C strings which will
+ * be processed later by the type input functions.
+ */
+ values = (char **) palloc(3 * sizeof(char *));
+ values[0] = (char *) palloc(16 * sizeof(char));
+ values[1] = (char *) palloc(16 * sizeof(char));
+ values[2] = (char *) palloc(16 * sizeof(char));
+
+ snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1));
+ snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1));
+ snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1));
+
+ /* build a tuple */
+ tuple = BuildTupleFromCStrings(attinmeta, values);
+
+ /* make the tuple into a datum */
+ result = HeapTupleGetDatum(tuple);
+
+ /* clean up (this is not really necessary) */
+ pfree(values[0]);
+ pfree(values[1]);
+ pfree(values[2]);
+ pfree(values);
+
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else /* do when there is no more left */
+ {
+ SRF_RETURN_DONE(funcctx);
+ }
+}
+
+</pre><p>
+
+ One way to declare this function in SQL is:
+</p><pre class="programlisting">
+CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);
+
+CREATE OR REPLACE FUNCTION retcomposite(integer, integer)
+ RETURNS SETOF __retcomposite
+ AS '<em class="replaceable"><code>filename</code></em>', 'retcomposite'
+ LANGUAGE C IMMUTABLE STRICT;
+</pre><p>
+ A different way is to use OUT parameters:
+</p><pre class="programlisting">
+CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
+ OUT f1 integer, OUT f2 integer, OUT f3 integer)
+ RETURNS SETOF record
+ AS '<em class="replaceable"><code>filename</code></em>', 'retcomposite'
+ LANGUAGE C IMMUTABLE STRICT;
+</pre><p>
+ Notice that in this method the output type of the function is formally
+ an anonymous <code class="structname">record</code> type.
+ </p></div><div class="sect2" id="id-1.8.3.13.13"><div class="titlepage"><div><div><h3 class="title">38.10.9. Polymorphic Arguments and Return Types</h3></div></div></div><p>
+ C-language functions can be declared to accept and
+ return the polymorphic types described in <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>.
+ When a function's arguments or return types
+ are defined as polymorphic types, the function author cannot know
+ in advance what data type it will be called with, or
+ need to return. There are two routines provided in <code class="filename">fmgr.h</code>
+ to allow a version-1 C function to discover the actual data types
+ of its arguments and the type it is expected to return. The routines are
+ called <code class="literal">get_fn_expr_rettype(FmgrInfo *flinfo)</code> and
+ <code class="literal">get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)</code>.
+ They return the result or argument type OID, or <code class="symbol">InvalidOid</code> if the
+ information is not available.
+ The structure <code class="literal">flinfo</code> is normally accessed as
+ <code class="literal">fcinfo-&gt;flinfo</code>. The parameter <code class="literal">argnum</code>
+ is zero based. <code class="function">get_call_result_type</code> can also be used
+ as an alternative to <code class="function">get_fn_expr_rettype</code>.
+ There is also <code class="function">get_fn_expr_variadic</code>, which can be used to
+ find out whether variadic arguments have been merged into an array.
+ This is primarily useful for <code class="literal">VARIADIC "any"</code> functions,
+ since such merging will always have occurred for variadic functions
+ taking ordinary array types.
+ </p><p>
+ For example, suppose we want to write a function to accept a single
+ element of any type, and return a one-dimensional array of that type:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(make_array);
+Datum
+make_array(PG_FUNCTION_ARGS)
+{
+ ArrayType *result;
+ Oid element_type = get_fn_expr_argtype(fcinfo-&gt;flinfo, 0);
+ Datum element;
+ bool isnull;
+ int16 typlen;
+ bool typbyval;
+ char typalign;
+ int ndims;
+ int dims[MAXDIM];
+ int lbs[MAXDIM];
+
+ if (!OidIsValid(element_type))
+ elog(ERROR, "could not determine data type of input");
+
+ /* get the provided element, being careful in case it's NULL */
+ isnull = PG_ARGISNULL(0);
+ if (isnull)
+ element = (Datum) 0;
+ else
+ element = PG_GETARG_DATUM(0);
+
+ /* we have one dimension */
+ ndims = 1;
+ /* and one element */
+ dims[0] = 1;
+ /* and lower bound is 1 */
+ lbs[0] = 1;
+
+ /* get required info about the element type */
+ get_typlenbyvalalign(element_type, &amp;typlen, &amp;typbyval, &amp;typalign);
+
+ /* now build the array */
+ result = construct_md_array(&amp;element, &amp;isnull, ndims, dims, lbs,
+ element_type, typlen, typbyval, typalign);
+
+ PG_RETURN_ARRAYTYPE_P(result);
+}
+</pre><p>
+ </p><p>
+ The following command declares the function
+ <code class="function">make_array</code> in SQL:
+
+</p><pre class="programlisting">
+CREATE FUNCTION make_array(anyelement) RETURNS anyarray
+ AS '<em class="replaceable"><code>DIRECTORY</code></em>/funcs', 'make_array'
+ LANGUAGE C IMMUTABLE;
+</pre><p>
+ </p><p>
+ There is a variant of polymorphism that is only available to C-language
+ functions: they can be declared to take parameters of type
+ <code class="literal">"any"</code>. (Note that this type name must be double-quoted,
+ since it's also an SQL reserved word.) This works like
+ <code class="type">anyelement</code> except that it does not constrain different
+ <code class="literal">"any"</code> arguments to be the same type, nor do they help
+ determine the function's result type. A C-language function can also
+ declare its final parameter to be <code class="literal">VARIADIC "any"</code>. This will
+ match one or more actual arguments of any type (not necessarily the same
+ type). These arguments will <span class="emphasis"><em>not</em></span> be gathered into an array
+ as happens with normal variadic functions; they will just be passed to
+ the function separately. The <code class="function">PG_NARGS()</code> macro and the
+ methods described above must be used to determine the number of actual
+ arguments and their types when using this feature. Also, users of such
+ a function might wish to use the <code class="literal">VARIADIC</code> keyword in their
+ function call, with the expectation that the function would treat the
+ array elements as separate arguments. The function itself must implement
+ that behavior if wanted, after using <code class="function">get_fn_expr_variadic</code> to
+ detect that the actual argument was marked with <code class="literal">VARIADIC</code>.
+ </p></div><div class="sect2" id="XFUNC-SHARED-ADDIN"><div class="titlepage"><div><div><h3 class="title">38.10.10. Shared Memory and LWLocks</h3></div></div></div><p>
+ Add-ins can reserve LWLocks and an allocation of shared memory on server
+ startup. The add-in's shared library must be preloaded by specifying
+ it in
+ <a class="xref" href="runtime-config-client.html#GUC-SHARED-PRELOAD-LIBRARIES">shared_preload_libraries</a><a id="id-1.8.3.13.14.2.2" class="indexterm"></a>.
+ The shared library should register a <code class="literal">shmem_request_hook</code>
+ in its <code class="function">_PG_init</code> function. This
+ <code class="literal">shmem_request_hook</code> can reserve LWLocks or shared memory.
+ Shared memory is reserved by calling:
+</p><pre class="programlisting">
+void RequestAddinShmemSpace(int size)
+</pre><p>
+ from your <code class="literal">shmem_request_hook</code>.
+ </p><p>
+ LWLocks are reserved by calling:
+</p><pre class="programlisting">
+void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
+</pre><p>
+ from your <code class="literal">shmem_request_hook</code>. This will ensure that an array of
+ <code class="literal">num_lwlocks</code> LWLocks is available under the name
+ <code class="literal">tranche_name</code>. Use <code class="function">GetNamedLWLockTranche</code>
+ to get a pointer to this array.
+ </p><p>
+ An example of a <code class="literal">shmem_request_hook</code> can be found in
+ <code class="filename">contrib/pg_stat_statements/pg_stat_statements.c</code> in the
+ <span class="productname">PostgreSQL</span> source tree.
+ </p><p>
+ To avoid possible race-conditions, each backend should use the LWLock
+ <code class="function">AddinShmemInitLock</code> when connecting to and initializing
+ its allocation of shared memory, as shown here:
+</p><pre class="programlisting">
+static mystruct *ptr = NULL;
+
+if (!ptr)
+{
+ bool found;
+
+ LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
+ ptr = ShmemInitStruct("my struct name", size, &amp;found);
+ if (!found)
+ {
+ initialize contents of shmem area;
+ acquire any requested LWLocks using:
+ ptr-&gt;locks = GetNamedLWLockTranche("my tranche name");
+ }
+ LWLockRelease(AddinShmemInitLock);
+}
+</pre><p>
+ </p></div><div class="sect2" id="EXTEND-CPP"><div class="titlepage"><div><div><h3 class="title">38.10.11. Using C++ for Extensibility</h3></div></div></div><a id="id-1.8.3.13.15.2" class="indexterm"></a><p>
+ Although the <span class="productname">PostgreSQL</span> backend is written in
+ C, it is possible to write extensions in C++ if these guidelines are
+ followed:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ All functions accessed by the backend must present a C interface
+ to the backend; these C functions can then call C++ functions.
+ For example, <code class="literal">extern C</code> linkage is required for
+ backend-accessed functions. This is also necessary for any
+ functions that are passed as pointers between the backend and
+ C++ code.
+ </p></li><li class="listitem"><p>
+ Free memory using the appropriate deallocation method. For example,
+ most backend memory is allocated using <code class="function">palloc()</code>, so use
+ <code class="function">pfree()</code> to free it. Using C++
+ <code class="function">delete</code> in such cases will fail.
+ </p></li><li class="listitem"><p>
+ Prevent exceptions from propagating into the C code (use a catch-all
+ block at the top level of all <code class="literal">extern C</code> functions). This
+ is necessary even if the C++ code does not explicitly throw any
+ exceptions, because events like out-of-memory can still throw
+ exceptions. Any exceptions must be caught and appropriate errors
+ passed back to the C interface. If possible, compile C++ with
+ <code class="option">-fno-exceptions</code> to eliminate exceptions entirely; in such
+ cases, you must check for failures in your C++ code, e.g., check for
+ NULL returned by <code class="function">new()</code>.
+ </p></li><li class="listitem"><p>
+ If calling backend functions from C++ code, be sure that the
+ C++ call stack contains only plain old data structures
+ (<acronym class="acronym">POD</acronym>). This is necessary because backend errors
+ generate a distant <code class="function">longjmp()</code> that does not properly
+ unroll a C++ call stack with non-POD objects.
+ </p></li></ul></div><p>
+ </p><p>
+ In summary, it is best to place C++ code behind a wall of
+ <code class="literal">extern C</code> functions that interface to the backend,
+ and avoid exception, memory, and call stack leakage.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-internal.html" title="38.9. Internal Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.9. Internal Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.11. Function Optimization Information</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-internal.html b/doc/src/sgml/html/xfunc-internal.html
new file mode 100644
index 0000000..46adc7f
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-internal.html
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.9. Internal Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-pl.html" title="38.8. Procedural Language Functions" /><link rel="next" href="xfunc-c.html" title="38.10. C-Language Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.9. Internal Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-pl.html" title="38.8. Procedural Language Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-c.html" title="38.10. C-Language Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-INTERNAL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.9. Internal Functions</h2></div></div></div><a id="id-1.8.3.12.2" class="indexterm"></a><p>
+ Internal functions are functions written in C that have been statically
+ linked into the <span class="productname">PostgreSQL</span> server.
+ The <span class="quote">“<span class="quote">body</span>”</span> of the function definition
+ specifies the C-language name of the function, which need not be the
+ same as the name being declared for SQL use.
+ (For reasons of backward compatibility, an empty body
+ is accepted as meaning that the C-language function name is the
+ same as the SQL name.)
+ </p><p>
+ Normally, all internal functions present in the
+ server are declared during the initialization of the database cluster
+ (see <a class="xref" href="creating-cluster.html" title="19.2. Creating a Database Cluster">Section 19.2</a>),
+ but a user could use <code class="command">CREATE FUNCTION</code>
+ to create additional alias names for an internal function.
+ Internal functions are declared in <code class="command">CREATE FUNCTION</code>
+ with language name <code class="literal">internal</code>. For instance, to
+ create an alias for the <code class="function">sqrt</code> function:
+</p><pre class="programlisting">
+CREATE FUNCTION square_root(double precision) RETURNS double precision
+ AS 'dsqrt'
+ LANGUAGE internal
+ STRICT;
+</pre><p>
+ (Most internal functions expect to be declared <span class="quote">“<span class="quote">strict</span>”</span>.)
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Not all <span class="quote">“<span class="quote">predefined</span>”</span> functions are
+ <span class="quote">“<span class="quote">internal</span>”</span> in the above sense. Some predefined
+ functions are written in SQL.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-pl.html" title="38.8. Procedural Language Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-c.html" title="38.10. C-Language Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.8. Procedural Language Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.10. C-Language Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-optimization.html b/doc/src/sgml/html/xfunc-optimization.html
new file mode 100644
index 0000000..4470680
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-optimization.html
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.11. Function Optimization Information</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-c.html" title="38.10. C-Language Functions" /><link rel="next" href="xaggr.html" title="38.12. User-Defined Aggregates" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.11. Function Optimization Information</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-c.html" title="38.10. C-Language Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xaggr.html" title="38.12. User-Defined Aggregates">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-OPTIMIZATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.11. Function Optimization Information</h2></div></div></div><a id="id-1.8.3.14.2" class="indexterm"></a><p>
+ By default, a function is just a <span class="quote">“<span class="quote">black box</span>”</span> that the
+ database system knows very little about the behavior of. However,
+ that means that queries using the function may be executed much less
+ efficiently than they could be. It is possible to supply additional
+ knowledge that helps the planner optimize function calls.
+ </p><p>
+ Some basic facts can be supplied by declarative annotations provided in
+ the <a class="link" href="sql-createfunction.html" title="CREATE FUNCTION"><code class="command">CREATE FUNCTION</code></a> command. Most important of
+ these is the function's <a class="link" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">volatility
+ category</a> (<code class="literal">IMMUTABLE</code>, <code class="literal">STABLE</code>,
+ or <code class="literal">VOLATILE</code>); one should always be careful to
+ specify this correctly when defining a function.
+ The parallel safety property (<code class="literal">PARALLEL
+ UNSAFE</code>, <code class="literal">PARALLEL RESTRICTED</code>, or
+ <code class="literal">PARALLEL SAFE</code>) must also be specified if you hope
+ to use the function in parallelized queries.
+ It can also be useful to specify the function's estimated execution
+ cost, and/or the number of rows a set-returning function is estimated
+ to return. However, the declarative way of specifying those two
+ facts only allows specifying a constant value, which is often
+ inadequate.
+ </p><p>
+ It is also possible to attach a <em class="firstterm">planner support
+ function</em> to an SQL-callable function (called
+ its <em class="firstterm">target function</em>), and thereby provide
+ knowledge about the target function that is too complex to be
+ represented declaratively. Planner support functions have to be
+ written in C (although their target functions might not be), so this is
+ an advanced feature that relatively few people will use.
+ </p><p>
+ A planner support function must have the SQL signature
+</p><pre class="programlisting">
+supportfn(internal) returns internal
+</pre><p>
+ It is attached to its target function by specifying
+ the <code class="literal">SUPPORT</code> clause when creating the target function.
+ </p><p>
+ The details of the API for planner support functions can be found in
+ file <code class="filename">src/include/nodes/supportnodes.h</code> in the
+ <span class="productname">PostgreSQL</span> source code. Here we provide
+ just an overview of what planner support functions can do.
+ The set of possible requests to a support function is extensible,
+ so more things might be possible in future versions.
+ </p><p>
+ Some function calls can be simplified during planning based on
+ properties specific to the function. For example,
+ <code class="literal">int4mul(n, 1)</code> could be simplified to
+ just <code class="literal">n</code>. This type of transformation can be
+ performed by a planner support function, by having it implement
+ the <code class="literal">SupportRequestSimplify</code> request type.
+ The support function will be called for each instance of its target
+ function found in a query parse tree. If it finds that the particular
+ call can be simplified into some other form, it can build and return a
+ parse tree representing that expression. This will automatically work
+ for operators based on the function, too — in the example just
+ given, <code class="literal">n * 1</code> would also be simplified to
+ <code class="literal">n</code>.
+ (But note that this is just an example; this particular
+ optimization is not actually performed by
+ standard <span class="productname">PostgreSQL</span>.)
+ We make no guarantee that <span class="productname">PostgreSQL</span> will
+ never call the target function in cases that the support function could
+ simplify. Ensure rigorous equivalence between the simplified
+ expression and an actual execution of the target function.
+ </p><p>
+ For target functions that return <code class="type">boolean</code>, it is often useful to estimate
+ the fraction of rows that will be selected by a <code class="literal">WHERE</code> clause using that
+ function. This can be done by a support function that implements
+ the <code class="literal">SupportRequestSelectivity</code> request type.
+ </p><p>
+ If the target function's run time is highly dependent on its inputs,
+ it may be useful to provide a non-constant cost estimate for it.
+ This can be done by a support function that implements
+ the <code class="literal">SupportRequestCost</code> request type.
+ </p><p>
+ For target functions that return sets, it is often useful to provide
+ a non-constant estimate for the number of rows that will be returned.
+ This can be done by a support function that implements
+ the <code class="literal">SupportRequestRows</code> request type.
+ </p><p>
+ For target functions that return <code class="type">boolean</code>, it may be possible to
+ convert a function call appearing in <code class="literal">WHERE</code> into an indexable operator
+ clause or clauses. The converted clauses might be exactly equivalent
+ to the function's condition, or they could be somewhat weaker (that is,
+ they might accept some values that the function condition does not).
+ In the latter case the index condition is said to
+ be <em class="firstterm">lossy</em>; it can still be used to scan an index,
+ but the function call will have to be executed for each row returned by
+ the index to see if it really passes the <code class="literal">WHERE</code> condition or not.
+ To create such conditions, the support function must implement
+ the <code class="literal">SupportRequestIndexCondition</code> request type.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-c.html" title="38.10. C-Language Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xaggr.html" title="38.12. User-Defined Aggregates">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.10. C-Language Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.12. User-Defined Aggregates</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-overload.html b/doc/src/sgml/html/xfunc-overload.html
new file mode 100644
index 0000000..0e8cd31
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-overload.html
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.6. Function Overloading</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions" /><link rel="next" href="xfunc-volatility.html" title="38.7. Function Volatility Categories" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.6. Function Overloading</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-OVERLOAD"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.6. Function Overloading</h2></div></div></div><a id="id-1.8.3.9.2" class="indexterm"></a><p>
+ More than one function can be defined with the same SQL name, so long
+ as the arguments they take are different. In other words,
+ function names can be <em class="firstterm">overloaded</em>. Whether or not
+ you use it, this capability entails security precautions when calling
+ functions in databases where some users mistrust other users; see
+ <a class="xref" href="typeconv-func.html" title="10.3. Functions">Section 10.3</a>. When a query is executed, the server
+ will determine which function to call from the data types and the number
+ of the provided arguments. Overloading can also be used to simulate
+ functions with a variable number of arguments, up to a finite maximum
+ number.
+ </p><p>
+ When creating a family of overloaded functions, one should be
+ careful not to create ambiguities. For instance, given the
+ functions:
+</p><pre class="programlisting">
+CREATE FUNCTION test(int, real) RETURNS ...
+CREATE FUNCTION test(smallint, double precision) RETURNS ...
+</pre><p>
+ it is not immediately clear which function would be called with
+ some trivial input like <code class="literal">test(1, 1.5)</code>. The
+ currently implemented resolution rules are described in
+ <a class="xref" href="typeconv.html" title="Chapter 10. Type Conversion">Chapter 10</a>, but it is unwise to design a system that subtly
+ relies on this behavior.
+ </p><p>
+ A function that takes a single argument of a composite type should
+ generally not have the same name as any attribute (field) of that type.
+ Recall that <code class="literal"><em class="replaceable"><code>attribute</code></em>(<em class="replaceable"><code>table</code></em>)</code>
+ is considered equivalent
+ to <code class="literal"><em class="replaceable"><code>table</code></em>.<em class="replaceable"><code>attribute</code></em></code>.
+ In the case that there is an
+ ambiguity between a function on a composite type and an attribute of
+ the composite type, the attribute will always be used. It is possible
+ to override that choice by schema-qualifying the function name
+ (that is, <code class="literal"><em class="replaceable"><code>schema</code></em>.<em class="replaceable"><code>func</code></em>(<em class="replaceable"><code>table</code></em>)
+ </code>) but it's better to
+ avoid the problem by not choosing conflicting names.
+ </p><p>
+ Another possible conflict is between variadic and non-variadic functions.
+ For instance, it is possible to create both <code class="literal">foo(numeric)</code> and
+ <code class="literal">foo(VARIADIC numeric[])</code>. In this case it is unclear which one
+ should be matched to a call providing a single numeric argument, such as
+ <code class="literal">foo(10.1)</code>. The rule is that the function appearing
+ earlier in the search path is used, or if the two functions are in the
+ same schema, the non-variadic one is preferred.
+ </p><p>
+ When overloading C-language functions, there is an additional
+ constraint: The C name of each function in the family of
+ overloaded functions must be different from the C names of all
+ other functions, either internal or dynamically loaded. If this
+ rule is violated, the behavior is not portable. You might get a
+ run-time linker error, or one of the functions will get called
+ (usually the internal one). The alternative form of the
+ <code class="literal">AS</code> clause for the SQL <code class="command">CREATE
+ FUNCTION</code> command decouples the SQL function name from
+ the function name in the C source code. For instance:
+</p><pre class="programlisting">
+CREATE FUNCTION test(int) RETURNS int
+ AS '<em class="replaceable"><code>filename</code></em>', 'test_1arg'
+ LANGUAGE C;
+CREATE FUNCTION test(int, int) RETURNS int
+ AS '<em class="replaceable"><code>filename</code></em>', 'test_2arg'
+ LANGUAGE C;
+</pre><p>
+ The names of the C functions here reflect one of many possible conventions.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.5. Query Language (<acronym class="acronym">SQL</acronym>) Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.7. Function Volatility Categories</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-pl.html b/doc/src/sgml/html/xfunc-pl.html
new file mode 100644
index 0000000..01692a8
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-pl.html
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.8. Procedural Language Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-volatility.html" title="38.7. Function Volatility Categories" /><link rel="next" href="xfunc-internal.html" title="38.9. Internal Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.8. Procedural Language Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-internal.html" title="38.9. Internal Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-PL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.8. Procedural Language Functions</h2></div></div></div><p>
+ <span class="productname">PostgreSQL</span> allows user-defined functions
+ to be written in other languages besides SQL and C. These other
+ languages are generically called <em class="firstterm">procedural
+ languages</em> (<acronym class="acronym">PL</acronym>s).
+ Procedural languages aren't built into the
+ <span class="productname">PostgreSQL</span> server; they are offered
+ by loadable modules.
+ See <a class="xref" href="xplang.html" title="Chapter 42. Procedural Languages">Chapter 42</a> and following chapters for more
+ information.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-volatility.html" title="38.7. Function Volatility Categories">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-internal.html" title="38.9. Internal Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.7. Function Volatility Categories </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.9. Internal Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-sql.html b/doc/src/sgml/html/xfunc-sql.html
new file mode 100644
index 0000000..a15c71a
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-sql.html
@@ -0,0 +1,1123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.5. Query Language (SQL) Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xproc.html" title="38.4. User-Defined Procedures" /><link rel="next" href="xfunc-overload.html" title="38.6. Function Overloading" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.5. Query Language (<acronym class="acronym">SQL</acronym>) Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xproc.html" title="38.4. User-Defined Procedures">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-overload.html" title="38.6. Function Overloading">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-SQL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.5. Query Language (<acronym class="acronym">SQL</acronym>) Functions</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS">38.5.1. Arguments for <acronym class="acronym">SQL</acronym> Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-BASE-FUNCTIONS">38.5.2. <acronym class="acronym">SQL</acronym> Functions on Base Types</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-COMPOSITE-FUNCTIONS">38.5.3. <acronym class="acronym">SQL</acronym> Functions on Composite Types</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS">38.5.4. <acronym class="acronym">SQL</acronym> Functions with Output Parameters</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS-PROC">38.5.5. <acronym class="acronym">SQL</acronym> Procedures with Output Parameters</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-VARIADIC-FUNCTIONS">38.5.6. <acronym class="acronym">SQL</acronym> Functions with Variable Numbers of Arguments</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-PARAMETER-DEFAULTS">38.5.7. <acronym class="acronym">SQL</acronym> Functions with Default Values for Arguments</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-TABLE-FUNCTIONS">38.5.8. <acronym class="acronym">SQL</acronym> Functions as Table Sources</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-SET">38.5.9. <acronym class="acronym">SQL</acronym> Functions Returning Sets</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-FUNCTIONS-RETURNING-TABLE">38.5.10. <acronym class="acronym">SQL</acronym> Functions Returning <code class="literal">TABLE</code></a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#XFUNC-SQL-POLYMORPHIC-FUNCTIONS">38.5.11. Polymorphic <acronym class="acronym">SQL</acronym> Functions</a></span></dt><dt><span class="sect2"><a href="xfunc-sql.html#id-1.8.3.8.21">38.5.12. <acronym class="acronym">SQL</acronym> Functions with Collations</a></span></dt></dl></div><a id="id-1.8.3.8.2" class="indexterm"></a><p>
+ SQL functions execute an arbitrary list of SQL statements, returning
+ the result of the last query in the list.
+ In the simple (non-set)
+ case, the first row of the last query's result will be returned.
+ (Bear in mind that <span class="quote">“<span class="quote">the first row</span>”</span> of a multirow
+ result is not well-defined unless you use <code class="literal">ORDER BY</code>.)
+ If the last query happens
+ to return no rows at all, the null value will be returned.
+ </p><p>
+ Alternatively, an SQL function can be declared to return a set (that is,
+ multiple rows) by specifying the function's return type as <code class="literal">SETOF
+ <em class="replaceable"><code>sometype</code></em></code>, or equivalently by declaring it as
+ <code class="literal">RETURNS TABLE(<em class="replaceable"><code>columns</code></em>)</code>. In this case
+ all rows of the last query's result are returned. Further details appear
+ below.
+ </p><p>
+ The body of an SQL function must be a list of SQL
+ statements separated by semicolons. A semicolon after the last
+ statement is optional. Unless the function is declared to return
+ <code class="type">void</code>, the last statement must be a <code class="command">SELECT</code>,
+ or an <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or <code class="command">DELETE</code>
+ that has a <code class="literal">RETURNING</code> clause.
+ </p><p>
+ Any collection of commands in the <acronym class="acronym">SQL</acronym>
+ language can be packaged together and defined as a function.
+ Besides <code class="command">SELECT</code> queries, the commands can include data
+ modification queries (<code class="command">INSERT</code>,
+ <code class="command">UPDATE</code>, <code class="command">DELETE</code>, and
+ <code class="command">MERGE</code>), as well as
+ other SQL commands. (You cannot use transaction control commands, e.g.,
+ <code class="command">COMMIT</code>, <code class="command">SAVEPOINT</code>, and some utility
+ commands, e.g., <code class="literal">VACUUM</code>, in <acronym class="acronym">SQL</acronym> functions.)
+ However, the final command
+ must be a <code class="command">SELECT</code> or have a <code class="literal">RETURNING</code>
+ clause that returns whatever is
+ specified as the function's return type. Alternatively, if you
+ want to define an SQL function that performs actions but has no
+ useful value to return, you can define it as returning <code class="type">void</code>.
+ For example, this function removes rows with negative salaries from
+ the <code class="literal">emp</code> table:
+
+</p><pre class="screen">
+CREATE FUNCTION clean_emp() RETURNS void AS '
+ DELETE FROM emp
+ WHERE salary &lt; 0;
+' LANGUAGE SQL;
+
+SELECT clean_emp();
+
+ clean_emp
+-----------
+
+(1 row)
+</pre><p>
+ </p><p>
+ You can also write this as a procedure, thus avoiding the issue of the
+ return type. For example:
+</p><pre class="screen">
+CREATE PROCEDURE clean_emp() AS '
+ DELETE FROM emp
+ WHERE salary &lt; 0;
+' LANGUAGE SQL;
+
+CALL clean_emp();
+</pre><p>
+ In simple cases like this, the difference between a function returning
+ <code class="type">void</code> and a procedure is mostly stylistic. However,
+ procedures offer additional functionality such as transaction control
+ that is not available in functions. Also, procedures are SQL standard
+ whereas returning <code class="type">void</code> is a PostgreSQL extension.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The entire body of an SQL function is parsed before any of it is
+ executed. While an SQL function can contain commands that alter
+ the system catalogs (e.g., <code class="command">CREATE TABLE</code>), the effects
+ of such commands will not be visible during parse analysis of
+ later commands in the function. Thus, for example,
+ <code class="literal">CREATE TABLE foo (...); INSERT INTO foo VALUES(...);</code>
+ will not work as desired if packaged up into a single SQL function,
+ since <code class="structname">foo</code> won't exist yet when the <code class="command">INSERT</code>
+ command is parsed. It's recommended to use <span class="application">PL/pgSQL</span>
+ instead of an SQL function in this type of situation.
+ </p></div><p>
+ The syntax of the <code class="command">CREATE FUNCTION</code> command requires
+ the function body to be written as a string constant. It is usually
+ most convenient to use dollar quoting (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING" title="4.1.2.4. Dollar-Quoted String Constants">Section 4.1.2.4</a>) for the string constant.
+ If you choose to use regular single-quoted string constant syntax,
+ you must double single quote marks (<code class="literal">'</code>) and backslashes
+ (<code class="literal">\</code>) (assuming escape string syntax) in the body of
+ the function (see <a class="xref" href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS" title="4.1.2.1. String Constants">Section 4.1.2.1</a>).
+ </p><div class="sect2" id="XFUNC-SQL-FUNCTION-ARGUMENTS"><div class="titlepage"><div><div><h3 class="title">38.5.1. Arguments for <acronym class="acronym">SQL</acronym> Functions</h3></div></div></div><a id="id-1.8.3.8.10.2" class="indexterm"></a><p>
+ Arguments of an SQL function can be referenced in the function
+ body using either names or numbers. Examples of both methods appear
+ below.
+ </p><p>
+ To use a name, declare the function argument as having a name, and
+ then just write that name in the function body. If the argument name
+ is the same as any column name in the current SQL command within the
+ function, the column name will take precedence. To override this,
+ qualify the argument name with the name of the function itself, that is
+ <code class="literal"><em class="replaceable"><code>function_name</code></em>.<em class="replaceable"><code>argument_name</code></em></code>.
+ (If this would conflict with a qualified column name, again the column
+ name wins. You can avoid the ambiguity by choosing a different alias for
+ the table within the SQL command.)
+ </p><p>
+ In the older numeric approach, arguments are referenced using the syntax
+ <code class="literal">$<em class="replaceable"><code>n</code></em></code>: <code class="literal">$1</code> refers to the first input
+ argument, <code class="literal">$2</code> to the second, and so on. This will work
+ whether or not the particular argument was declared with a name.
+ </p><p>
+ If an argument is of a composite type, then the dot notation,
+ e.g., <code class="literal"><em class="replaceable"><code>argname</code></em>.<em class="replaceable"><code>fieldname</code></em></code> or
+ <code class="literal">$1.<em class="replaceable"><code>fieldname</code></em></code>, can be used to access attributes of the
+ argument. Again, you might need to qualify the argument's name with the
+ function name to make the form with an argument name unambiguous.
+ </p><p>
+ SQL function arguments can only be used as data values,
+ not as identifiers. Thus for example this is reasonable:
+</p><pre class="programlisting">
+INSERT INTO mytable VALUES ($1);
+</pre><p>
+but this will not work:
+</p><pre class="programlisting">
+INSERT INTO $1 VALUES (42);
+</pre><p>
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The ability to use names to reference SQL function arguments was added
+ in <span class="productname">PostgreSQL</span> 9.2. Functions to be used in
+ older servers must use the <code class="literal">$<em class="replaceable"><code>n</code></em></code> notation.
+ </p></div></div><div class="sect2" id="XFUNC-SQL-BASE-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">38.5.2. <acronym class="acronym">SQL</acronym> Functions on Base Types</h3></div></div></div><p>
+ The simplest possible <acronym class="acronym">SQL</acronym> function has no arguments and
+ simply returns a base type, such as <code class="type">integer</code>:
+
+</p><pre class="screen">
+CREATE FUNCTION one() RETURNS integer AS $$
+ SELECT 1 AS result;
+$$ LANGUAGE SQL;
+
+-- Alternative syntax for string literal:
+CREATE FUNCTION one() RETURNS integer AS '
+ SELECT 1 AS result;
+' LANGUAGE SQL;
+
+SELECT one();
+
+ one
+-----
+ 1
+</pre><p>
+ </p><p>
+ Notice that we defined a column alias within the function body for the result of the function
+ (with the name <code class="literal">result</code>), but this column alias is not visible
+ outside the function. Hence, the result is labeled <code class="literal">one</code>
+ instead of <code class="literal">result</code>.
+ </p><p>
+ It is almost as easy to define <acronym class="acronym">SQL</acronym> functions
+ that take base types as arguments:
+
+</p><pre class="screen">
+CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$
+ SELECT x + y;
+$$ LANGUAGE SQL;
+
+SELECT add_em(1, 2) AS answer;
+
+ answer
+--------
+ 3
+</pre><p>
+ </p><p>
+ Alternatively, we could dispense with names for the arguments and
+ use numbers:
+
+</p><pre class="screen">
+CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$
+ SELECT $1 + $2;
+$$ LANGUAGE SQL;
+
+SELECT add_em(1, 2) AS answer;
+
+ answer
+--------
+ 3
+</pre><p>
+ </p><p>
+ Here is a more useful function, which might be used to debit a
+ bank account:
+
+</p><pre class="programlisting">
+CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tf1.accountno;
+ SELECT 1;
+$$ LANGUAGE SQL;
+</pre><p>
+
+ A user could execute this function to debit account 17 by $100.00 as
+ follows:
+
+</p><pre class="programlisting">
+SELECT tf1(17, 100.0);
+</pre><p>
+ </p><p>
+ In this example, we chose the name <code class="literal">accountno</code> for the first
+ argument, but this is the same as the name of a column in the
+ <code class="literal">bank</code> table. Within the <code class="command">UPDATE</code> command,
+ <code class="literal">accountno</code> refers to the column <code class="literal">bank.accountno</code>,
+ so <code class="literal">tf1.accountno</code> must be used to refer to the argument.
+ We could of course avoid this by using a different name for the argument.
+ </p><p>
+ In practice one would probably like a more useful result from the
+ function than a constant 1, so a more likely definition
+ is:
+
+</p><pre class="programlisting">
+CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tf1.accountno;
+ SELECT balance FROM bank WHERE accountno = tf1.accountno;
+$$ LANGUAGE SQL;
+</pre><p>
+
+ which adjusts the balance and returns the new balance.
+ The same thing could be done in one command using <code class="literal">RETURNING</code>:
+
+</p><pre class="programlisting">
+CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tf1.accountno
+ RETURNING balance;
+$$ LANGUAGE SQL;
+</pre><p>
+ </p><p>
+ If the final <code class="literal">SELECT</code> or <code class="literal">RETURNING</code>
+ clause in an <acronym class="acronym">SQL</acronym> function does not return exactly
+ the function's declared result
+ type, <span class="productname">PostgreSQL</span> will automatically cast
+ the value to the required type, if that is possible with an implicit
+ or assignment cast. Otherwise, you must write an explicit cast.
+ For example, suppose we wanted the
+ previous <code class="function">add_em</code> function to return
+ type <code class="type">float8</code> instead. It's sufficient to write
+
+</p><pre class="programlisting">
+CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$
+ SELECT $1 + $2;
+$$ LANGUAGE SQL;
+</pre><p>
+
+ since the <code class="type">integer</code> sum can be implicitly cast
+ to <code class="type">float8</code>.
+ (See <a class="xref" href="typeconv.html" title="Chapter 10. Type Conversion">Chapter 10</a> or <a class="xref" href="sql-createcast.html" title="CREATE CAST"><span class="refentrytitle">CREATE CAST</span></a>
+ for more about casts.)
+ </p></div><div class="sect2" id="XFUNC-SQL-COMPOSITE-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">38.5.3. <acronym class="acronym">SQL</acronym> Functions on Composite Types</h3></div></div></div><p>
+ When writing functions with arguments of composite types, we must not
+ only specify which argument we want but also the desired attribute
+ (field) of that argument. For example, suppose that
+ <code class="type">emp</code> is a table containing employee data, and therefore
+ also the name of the composite type of each row of the table. Here
+ is a function <code class="function">double_salary</code> that computes what someone's
+ salary would be if it were doubled:
+
+</p><pre class="screen">
+CREATE TABLE emp (
+ name text,
+ salary numeric,
+ age integer,
+ cubicle point
+);
+
+INSERT INTO emp VALUES ('Bill', 4200, 45, '(2,1)');
+
+CREATE FUNCTION double_salary(emp) RETURNS numeric AS $$
+ SELECT $1.salary * 2 AS salary;
+$$ LANGUAGE SQL;
+
+SELECT name, double_salary(emp.*) AS dream
+ FROM emp
+ WHERE emp.cubicle ~= point '(2,1)';
+
+ name | dream
+------+-------
+ Bill | 8400
+</pre><p>
+ </p><p>
+ Notice the use of the syntax <code class="literal">$1.salary</code>
+ to select one field of the argument row value. Also notice
+ how the calling <code class="command">SELECT</code> command
+ uses <em class="replaceable"><code>table_name</code></em><code class="literal">.*</code> to select
+ the entire current row of a table as a composite value. The table
+ row can alternatively be referenced using just the table name,
+ like this:
+</p><pre class="screen">
+SELECT name, double_salary(emp) AS dream
+ FROM emp
+ WHERE emp.cubicle ~= point '(2,1)';
+</pre><p>
+ but this usage is deprecated since it's easy to get confused.
+ (See <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a> for details about these
+ two notations for the composite value of a table row.)
+ </p><p>
+ Sometimes it is handy to construct a composite argument value
+ on-the-fly. This can be done with the <code class="literal">ROW</code> construct.
+ For example, we could adjust the data being passed to the function:
+</p><pre class="screen">
+SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream
+ FROM emp;
+</pre><p>
+ </p><p>
+ It is also possible to build a function that returns a composite type.
+ This is an example of a function
+ that returns a single <code class="type">emp</code> row:
+
+</p><pre class="programlisting">
+CREATE FUNCTION new_emp() RETURNS emp AS $$
+ SELECT text 'None' AS name,
+ 1000.0 AS salary,
+ 25 AS age,
+ point '(2,2)' AS cubicle;
+$$ LANGUAGE SQL;
+</pre><p>
+
+ In this example we have specified each of the attributes
+ with a constant value, but any computation
+ could have been substituted for these constants.
+ </p><p>
+ Note two important things about defining the function:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The select list order in the query must be exactly the same as
+ that in which the columns appear in the composite type.
+ (Naming the columns, as we did above,
+ is irrelevant to the system.)
+ </p></li><li class="listitem"><p>
+ We must ensure each expression's type can be cast to that of
+ the corresponding column of the composite type.
+ Otherwise we'll get errors like this:
+</p><pre class="screen">
+<code class="computeroutput">
+ERROR: return type mismatch in function declared to return emp
+DETAIL: Final statement returns text instead of point at column 4.
+</code>
+</pre><p>
+ As with the base-type case, the system will not insert explicit
+ casts automatically, only implicit or assignment casts.
+ </p></li></ul></div><p>
+ </p><p>
+ A different way to define the same function is:
+
+</p><pre class="programlisting">
+CREATE FUNCTION new_emp() RETURNS emp AS $$
+ SELECT ROW('None', 1000.0, 25, '(2,2)')::emp;
+$$ LANGUAGE SQL;
+</pre><p>
+
+ Here we wrote a <code class="command">SELECT</code> that returns just a single
+ column of the correct composite type. This isn't really better
+ in this situation, but it is a handy alternative in some cases
+ — for example, if we need to compute the result by calling
+ another function that returns the desired composite value.
+ Another example is that if we are trying to write a function that
+ returns a domain over composite, rather than a plain composite type,
+ it is always necessary to write it as returning a single column,
+ since there is no way to cause a coercion of the whole row result.
+ </p><p>
+ We could call this function directly either by using it in
+ a value expression:
+
+</p><pre class="screen">
+SELECT new_emp();
+
+ new_emp
+--------------------------
+ (None,1000.0,25,"(2,2)")
+</pre><p>
+
+ or by calling it as a table function:
+
+</p><pre class="screen">
+SELECT * FROM new_emp();
+
+ name | salary | age | cubicle
+------+--------+-----+---------
+ None | 1000.0 | 25 | (2,2)
+</pre><p>
+
+ The second way is described more fully in <a class="xref" href="xfunc-sql.html#XFUNC-SQL-TABLE-FUNCTIONS" title="38.5.8. SQL Functions as Table Sources">Section 38.5.8</a>.
+ </p><p>
+ When you use a function that returns a composite type,
+ you might want only one field (attribute) from its result.
+ You can do that with syntax like this:
+
+</p><pre class="screen">
+SELECT (new_emp()).name;
+
+ name
+------
+ None
+</pre><p>
+
+ The extra parentheses are needed to keep the parser from getting
+ confused. If you try to do it without them, you get something like this:
+
+</p><pre class="screen">
+SELECT new_emp().name;
+ERROR: syntax error at or near "."
+LINE 1: SELECT new_emp().name;
+ ^
+</pre><p>
+ </p><p>
+ Another option is to use functional notation for extracting an attribute:
+
+</p><pre class="screen">
+SELECT name(new_emp());
+
+ name
+------
+ None
+</pre><p>
+
+ As explained in <a class="xref" href="rowtypes.html#ROWTYPES-USAGE" title="8.16.5. Using Composite Types in Queries">Section 8.16.5</a>, the field notation and
+ functional notation are equivalent.
+ </p><p>
+ Another way to use a function returning a composite type is to pass the
+ result to another function that accepts the correct row type as input:
+
+</p><pre class="screen">
+CREATE FUNCTION getname(emp) RETURNS text AS $$
+ SELECT $1.name;
+$$ LANGUAGE SQL;
+
+SELECT getname(new_emp());
+ getname
+---------
+ None
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="XFUNC-OUTPUT-PARAMETERS"><div class="titlepage"><div><div><h3 class="title">38.5.4. <acronym class="acronym">SQL</acronym> Functions with Output Parameters</h3></div></div></div><a id="id-1.8.3.8.13.2" class="indexterm"></a><p>
+ An alternative way of describing a function's results is to define it
+ with <em class="firstterm">output parameters</em>, as in this example:
+
+</p><pre class="screen">
+CREATE FUNCTION add_em (IN x int, IN y int, OUT sum int)
+AS 'SELECT x + y'
+LANGUAGE SQL;
+
+SELECT add_em(3,7);
+ add_em
+--------
+ 10
+(1 row)
+</pre><p>
+
+ This is not essentially different from the version of <code class="literal">add_em</code>
+ shown in <a class="xref" href="xfunc-sql.html#XFUNC-SQL-BASE-FUNCTIONS" title="38.5.2. SQL Functions on Base Types">Section 38.5.2</a>. The real value of
+ output parameters is that they provide a convenient way of defining
+ functions that return several columns. For example,
+
+</p><pre class="screen">
+CREATE FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int)
+AS 'SELECT x + y, x * y'
+LANGUAGE SQL;
+
+ SELECT * FROM sum_n_product(11,42);
+ sum | product
+-----+---------
+ 53 | 462
+(1 row)
+</pre><p>
+
+ What has essentially happened here is that we have created an anonymous
+ composite type for the result of the function. The above example has
+ the same end result as
+
+</p><pre class="screen">
+CREATE TYPE sum_prod AS (sum int, product int);
+
+CREATE FUNCTION sum_n_product (int, int) RETURNS sum_prod
+AS 'SELECT $1 + $2, $1 * $2'
+LANGUAGE SQL;
+</pre><p>
+
+ but not having to bother with the separate composite type definition
+ is often handy. Notice that the names attached to the output parameters
+ are not just decoration, but determine the column names of the anonymous
+ composite type. (If you omit a name for an output parameter, the
+ system will choose a name on its own.)
+ </p><p>
+ Notice that output parameters are not included in the calling argument
+ list when invoking such a function from SQL. This is because
+ <span class="productname">PostgreSQL</span> considers only the input
+ parameters to define the function's calling signature. That means
+ also that only the input parameters matter when referencing the function
+ for purposes such as dropping it. We could drop the above function
+ with either of
+
+</p><pre class="screen">
+DROP FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int);
+DROP FUNCTION sum_n_product (int, int);
+</pre><p>
+ </p><p>
+ Parameters can be marked as <code class="literal">IN</code> (the default),
+ <code class="literal">OUT</code>, <code class="literal">INOUT</code>, or <code class="literal">VARIADIC</code>.
+ An <code class="literal">INOUT</code>
+ parameter serves as both an input parameter (part of the calling
+ argument list) and an output parameter (part of the result record type).
+ <code class="literal">VARIADIC</code> parameters are input parameters, but are treated
+ specially as described below.
+ </p></div><div class="sect2" id="XFUNC-OUTPUT-PARAMETERS-PROC"><div class="titlepage"><div><div><h3 class="title">38.5.5. <acronym class="acronym">SQL</acronym> Procedures with Output Parameters</h3></div></div></div><a id="id-1.8.3.8.14.2" class="indexterm"></a><p>
+ Output parameters are also supported in procedures, but they work a bit
+ differently from functions. In <code class="command">CALL</code> commands,
+ output parameters must be included in the argument list.
+ For example, the bank account debiting routine from earlier could be
+ written like this:
+</p><pre class="programlisting">
+CREATE PROCEDURE tp1 (accountno integer, debit numeric, OUT new_balance numeric) AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tp1.accountno
+ RETURNING balance;
+$$ LANGUAGE SQL;
+</pre><p>
+ To call this procedure, an argument matching the <code class="literal">OUT</code>
+ parameter must be included. It's customary to write
+ <code class="literal">NULL</code>:
+</p><pre class="programlisting">
+CALL tp1(17, 100.0, NULL);
+</pre><p>
+ If you write something else, it must be an expression that is implicitly
+ coercible to the declared type of the parameter, just as for input
+ parameters. Note however that such an expression will not be evaluated.
+ </p><p>
+ When calling a procedure from <span class="application">PL/pgSQL</span>,
+ instead of writing <code class="literal">NULL</code> you must write a variable
+ that will receive the procedure's output. See <a class="xref" href="plpgsql-control-structures.html#PLPGSQL-STATEMENTS-CALLING-PROCEDURE" title="43.6.3. Calling a Procedure">Section 43.6.3</a> for details.
+ </p></div><div class="sect2" id="XFUNC-SQL-VARIADIC-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">38.5.6. <acronym class="acronym">SQL</acronym> Functions with Variable Numbers of Arguments</h3></div></div></div><a id="id-1.8.3.8.15.2" class="indexterm"></a><a id="id-1.8.3.8.15.3" class="indexterm"></a><p>
+ <acronym class="acronym">SQL</acronym> functions can be declared to accept
+ variable numbers of arguments, so long as all the <span class="quote">“<span class="quote">optional</span>”</span>
+ arguments are of the same data type. The optional arguments will be
+ passed to the function as an array. The function is declared by
+ marking the last parameter as <code class="literal">VARIADIC</code>; this parameter
+ must be declared as being of an array type. For example:
+
+</p><pre class="screen">
+CREATE FUNCTION mleast(VARIADIC arr numeric[]) RETURNS numeric AS $$
+ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
+$$ LANGUAGE SQL;
+
+SELECT mleast(10, -1, 5, 4.4);
+ mleast
+--------
+ -1
+(1 row)
+</pre><p>
+
+ Effectively, all the actual arguments at or beyond the
+ <code class="literal">VARIADIC</code> position are gathered up into a one-dimensional
+ array, as if you had written
+
+</p><pre class="screen">
+SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work
+</pre><p>
+
+ You can't actually write that, though — or at least, it will
+ not match this function definition. A parameter marked
+ <code class="literal">VARIADIC</code> matches one or more occurrences of its element
+ type, not of its own type.
+ </p><p>
+ Sometimes it is useful to be able to pass an already-constructed array
+ to a variadic function; this is particularly handy when one variadic
+ function wants to pass on its array parameter to another one. Also,
+ this is the only secure way to call a variadic function found in a schema
+ that permits untrusted users to create objects; see
+ <a class="xref" href="typeconv-func.html" title="10.3. Functions">Section 10.3</a>. You can do this by
+ specifying <code class="literal">VARIADIC</code> in the call:
+
+</p><pre class="screen">
+SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);
+</pre><p>
+
+ This prevents expansion of the function's variadic parameter into its
+ element type, thereby allowing the array argument value to match
+ normally. <code class="literal">VARIADIC</code> can only be attached to the last
+ actual argument of a function call.
+ </p><p>
+ Specifying <code class="literal">VARIADIC</code> in the call is also the only way to
+ pass an empty array to a variadic function, for example:
+
+</p><pre class="screen">
+SELECT mleast(VARIADIC ARRAY[]::numeric[]);
+</pre><p>
+
+ Simply writing <code class="literal">SELECT mleast()</code> does not work because a
+ variadic parameter must match at least one actual argument.
+ (You could define a second function also named <code class="literal">mleast</code>,
+ with no parameters, if you wanted to allow such calls.)
+ </p><p>
+ The array element parameters generated from a variadic parameter are
+ treated as not having any names of their own. This means it is not
+ possible to call a variadic function using named arguments (<a class="xref" href="sql-syntax-calling-funcs.html" title="4.3. Calling Functions">Section 4.3</a>), except when you specify
+ <code class="literal">VARIADIC</code>. For example, this will work:
+
+</p><pre class="screen">
+SELECT mleast(VARIADIC arr =&gt; ARRAY[10, -1, 5, 4.4]);
+</pre><p>
+
+ but not these:
+
+</p><pre class="screen">
+SELECT mleast(arr =&gt; 10);
+SELECT mleast(arr =&gt; ARRAY[10, -1, 5, 4.4]);
+</pre><p>
+ </p></div><div class="sect2" id="XFUNC-SQL-PARAMETER-DEFAULTS"><div class="titlepage"><div><div><h3 class="title">38.5.7. <acronym class="acronym">SQL</acronym> Functions with Default Values for Arguments</h3></div></div></div><a id="id-1.8.3.8.16.2" class="indexterm"></a><p>
+ Functions can be declared with default values for some or all input
+ arguments. The default values are inserted whenever the function is
+ called with insufficiently many actual arguments. Since arguments
+ can only be omitted from the end of the actual argument list, all
+ parameters after a parameter with a default value have to have
+ default values as well. (Although the use of named argument notation
+ could allow this restriction to be relaxed, it's still enforced so that
+ positional argument notation works sensibly.) Whether or not you use it,
+ this capability creates a need for precautions when calling functions in
+ databases where some users mistrust other users; see
+ <a class="xref" href="typeconv-func.html" title="10.3. Functions">Section 10.3</a>.
+ </p><p>
+ For example:
+</p><pre class="screen">
+CREATE FUNCTION foo(a int, b int DEFAULT 2, c int DEFAULT 3)
+RETURNS int
+LANGUAGE SQL
+AS $$
+ SELECT $1 + $2 + $3;
+$$;
+
+SELECT foo(10, 20, 30);
+ foo
+-----
+ 60
+(1 row)
+
+SELECT foo(10, 20);
+ foo
+-----
+ 33
+(1 row)
+
+SELECT foo(10);
+ foo
+-----
+ 15
+(1 row)
+
+SELECT foo(); -- fails since there is no default for the first argument
+ERROR: function foo() does not exist
+</pre><p>
+ The <code class="literal">=</code> sign can also be used in place of the
+ key word <code class="literal">DEFAULT</code>.
+ </p></div><div class="sect2" id="XFUNC-SQL-TABLE-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">38.5.8. <acronym class="acronym">SQL</acronym> Functions as Table Sources</h3></div></div></div><p>
+ All SQL functions can be used in the <code class="literal">FROM</code> clause of a query,
+ but it is particularly useful for functions returning composite types.
+ If the function is defined to return a base type, the table function
+ produces a one-column table. If the function is defined to return
+ a composite type, the table function produces a column for each attribute
+ of the composite type.
+ </p><p>
+ Here is an example:
+
+</p><pre class="screen">
+CREATE TABLE foo (fooid int, foosubid int, fooname text);
+INSERT INTO foo VALUES (1, 1, 'Joe');
+INSERT INTO foo VALUES (1, 2, 'Ed');
+INSERT INTO foo VALUES (2, 1, 'Mary');
+
+CREATE FUNCTION getfoo(int) RETURNS foo AS $$
+ SELECT * FROM foo WHERE fooid = $1;
+$$ LANGUAGE SQL;
+
+SELECT *, upper(fooname) FROM getfoo(1) AS t1;
+
+ fooid | foosubid | fooname | upper
+-------+----------+---------+-------
+ 1 | 1 | Joe | JOE
+(1 row)
+</pre><p>
+
+ As the example shows, we can work with the columns of the function's
+ result just the same as if they were columns of a regular table.
+ </p><p>
+ Note that we only got one row out of the function. This is because
+ we did not use <code class="literal">SETOF</code>. That is described in the next section.
+ </p></div><div class="sect2" id="XFUNC-SQL-FUNCTIONS-RETURNING-SET"><div class="titlepage"><div><div><h3 class="title">38.5.9. <acronym class="acronym">SQL</acronym> Functions Returning Sets</h3></div></div></div><a id="id-1.8.3.8.18.2" class="indexterm"></a><p>
+ When an SQL function is declared as returning <code class="literal">SETOF
+ <em class="replaceable"><code>sometype</code></em></code>, the function's final
+ query is executed to completion, and each row it
+ outputs is returned as an element of the result set.
+ </p><p>
+ This feature is normally used when calling the function in the <code class="literal">FROM</code>
+ clause. In this case each row returned by the function becomes
+ a row of the table seen by the query. For example, assume that
+ table <code class="literal">foo</code> has the same contents as above, and we say:
+
+</p><pre class="programlisting">
+CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
+ SELECT * FROM foo WHERE fooid = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM getfoo(1) AS t1;
+</pre><p>
+
+ Then we would get:
+</p><pre class="screen">
+ fooid | foosubid | fooname
+-------+----------+---------
+ 1 | 1 | Joe
+ 1 | 2 | Ed
+(2 rows)
+</pre><p>
+ </p><p>
+ It is also possible to return multiple rows with the columns defined by
+ output parameters, like this:
+
+</p><pre class="programlisting">
+CREATE TABLE tab (y int, z int);
+INSERT INTO tab VALUES (1, 2), (3, 4), (5, 6), (7, 8);
+
+CREATE FUNCTION sum_n_product_with_tab (x int, OUT sum int, OUT product int)
+RETURNS SETOF record
+AS $$
+ SELECT $1 + tab.y, $1 * tab.y FROM tab;
+$$ LANGUAGE SQL;
+
+SELECT * FROM sum_n_product_with_tab(10);
+ sum | product
+-----+---------
+ 11 | 10
+ 13 | 30
+ 15 | 50
+ 17 | 70
+(4 rows)
+</pre><p>
+
+ The key point here is that you must write <code class="literal">RETURNS SETOF record</code>
+ to indicate that the function returns multiple rows instead of just one.
+ If there is only one output parameter, write that parameter's type
+ instead of <code class="type">record</code>.
+ </p><p>
+ It is frequently useful to construct a query's result by invoking a
+ set-returning function multiple times, with the parameters for each
+ invocation coming from successive rows of a table or subquery. The
+ preferred way to do this is to use the <code class="literal">LATERAL</code> key word,
+ which is described in <a class="xref" href="queries-table-expressions.html#QUERIES-LATERAL" title="7.2.1.5. LATERAL Subqueries">Section 7.2.1.5</a>.
+ Here is an example using a set-returning function to enumerate
+ elements of a tree structure:
+
+</p><pre class="screen">
+SELECT * FROM nodes;
+ name | parent
+-----------+--------
+ Top |
+ Child1 | Top
+ Child2 | Top
+ Child3 | Top
+ SubChild1 | Child1
+ SubChild2 | Child1
+(6 rows)
+
+CREATE FUNCTION listchildren(text) RETURNS SETOF text AS $$
+ SELECT name FROM nodes WHERE parent = $1
+$$ LANGUAGE SQL STABLE;
+
+SELECT * FROM listchildren('Top');
+ listchildren
+--------------
+ Child1
+ Child2
+ Child3
+(3 rows)
+
+SELECT name, child FROM nodes, LATERAL listchildren(name) AS child;
+ name | child
+--------+-----------
+ Top | Child1
+ Top | Child2
+ Top | Child3
+ Child1 | SubChild1
+ Child1 | SubChild2
+(5 rows)
+</pre><p>
+
+ This example does not do anything that we couldn't have done with a
+ simple join, but in more complex calculations the option to put
+ some of the work into a function can be quite convenient.
+ </p><p>
+ Functions returning sets can also be called in the select list
+ of a query. For each row that the query
+ generates by itself, the set-returning function is invoked, and an output
+ row is generated for each element of the function's result set.
+ The previous example could also be done with queries like
+ these:
+
+</p><pre class="screen">
+SELECT listchildren('Top');
+ listchildren
+--------------
+ Child1
+ Child2
+ Child3
+(3 rows)
+
+SELECT name, listchildren(name) FROM nodes;
+ name | listchildren
+--------+--------------
+ Top | Child1
+ Top | Child2
+ Top | Child3
+ Child1 | SubChild1
+ Child1 | SubChild2
+(5 rows)
+</pre><p>
+
+ In the last <code class="command">SELECT</code>,
+ notice that no output row appears for <code class="literal">Child2</code>, <code class="literal">Child3</code>, etc.
+ This happens because <code class="function">listchildren</code> returns an empty set
+ for those arguments, so no result rows are generated. This is the same
+ behavior as we got from an inner join to the function result when using
+ the <code class="literal">LATERAL</code> syntax.
+ </p><p>
+ <span class="productname">PostgreSQL</span>'s behavior for a set-returning function in a
+ query's select list is almost exactly the same as if the set-returning
+ function had been written in a <code class="literal">LATERAL FROM</code>-clause item
+ instead. For example,
+</p><pre class="programlisting">
+SELECT x, generate_series(1,5) AS g FROM tab;
+</pre><p>
+ is almost equivalent to
+</p><pre class="programlisting">
+SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g;
+</pre><p>
+ It would be exactly the same, except that in this specific example,
+ the planner could choose to put <code class="structname">g</code> on the outside of the
+ nested-loop join, since <code class="structname">g</code> has no actual lateral dependency
+ on <code class="structname">tab</code>. That would result in a different output row
+ order. Set-returning functions in the select list are always evaluated
+ as though they are on the inside of a nested-loop join with the rest of
+ the <code class="literal">FROM</code> clause, so that the function(s) are run to
+ completion before the next row from the <code class="literal">FROM</code> clause is
+ considered.
+ </p><p>
+ If there is more than one set-returning function in the query's select
+ list, the behavior is similar to what you get from putting the functions
+ into a single <code class="literal">LATERAL ROWS FROM( ... )</code> <code class="literal">FROM</code>-clause
+ item. For each row from the underlying query, there is an output row
+ using the first result from each function, then an output row using the
+ second result, and so on. If some of the set-returning functions
+ produce fewer outputs than others, null values are substituted for the
+ missing data, so that the total number of rows emitted for one
+ underlying row is the same as for the set-returning function that
+ produced the most outputs. Thus the set-returning functions
+ run <span class="quote">“<span class="quote">in lockstep</span>”</span> until they are all exhausted, and then
+ execution continues with the next underlying row.
+ </p><p>
+ Set-returning functions can be nested in a select list, although that is
+ not allowed in <code class="literal">FROM</code>-clause items. In such cases, each level
+ of nesting is treated separately, as though it were
+ a separate <code class="literal">LATERAL ROWS FROM( ... )</code> item. For example, in
+</p><pre class="programlisting">
+SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab;
+</pre><p>
+ the set-returning functions <code class="function">srf2</code>, <code class="function">srf3</code>,
+ and <code class="function">srf5</code> would be run in lockstep for each row
+ of <code class="structname">tab</code>, and then <code class="function">srf1</code> and <code class="function">srf4</code>
+ would be applied in lockstep to each row produced by the lower
+ functions.
+ </p><p>
+ Set-returning functions cannot be used within conditional-evaluation
+ constructs, such as <code class="literal">CASE</code> or <code class="literal">COALESCE</code>. For
+ example, consider
+</p><pre class="programlisting">
+SELECT x, CASE WHEN x &gt; 0 THEN generate_series(1, 5) ELSE 0 END FROM tab;
+</pre><p>
+ It might seem that this should produce five repetitions of input rows
+ that have <code class="literal">x &gt; 0</code>, and a single repetition of those that do
+ not; but actually, because <code class="function">generate_series(1, 5)</code> would be
+ run in an implicit <code class="literal">LATERAL FROM</code> item before
+ the <code class="literal">CASE</code> expression is ever evaluated, it would produce five
+ repetitions of every input row. To reduce confusion, such cases produce
+ a parse-time error instead.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ If a function's last command is <code class="command">INSERT</code>, <code class="command">UPDATE</code>,
+ or <code class="command">DELETE</code> with <code class="literal">RETURNING</code>, that command will
+ always be executed to completion, even if the function is not declared
+ with <code class="literal">SETOF</code> or the calling query does not fetch all the
+ result rows. Any extra rows produced by the <code class="literal">RETURNING</code>
+ clause are silently dropped, but the commanded table modifications
+ still happen (and are all completed before returning from the function).
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ Before <span class="productname">PostgreSQL</span> 10, putting more than one
+ set-returning function in the same select list did not behave very
+ sensibly unless they always produced equal numbers of rows. Otherwise,
+ what you got was a number of output rows equal to the least common
+ multiple of the numbers of rows produced by the set-returning
+ functions. Also, nested set-returning functions did not work as
+ described above; instead, a set-returning function could have at most
+ one set-returning argument, and each nest of set-returning functions
+ was run independently. Also, conditional execution (set-returning
+ functions inside <code class="literal">CASE</code> etc.) was previously allowed,
+ complicating things even more.
+ Use of the <code class="literal">LATERAL</code> syntax is recommended when writing
+ queries that need to work in older <span class="productname">PostgreSQL</span> versions,
+ because that will give consistent results across different versions.
+ If you have a query that is relying on conditional execution of a
+ set-returning function, you may be able to fix it by moving the
+ conditional test into a custom set-returning function. For example,
+</p><pre class="programlisting">
+SELECT x, CASE WHEN y &gt; 0 THEN generate_series(1, z) ELSE 5 END FROM tab;
+</pre><p>
+ could become
+</p><pre class="programlisting">
+CREATE FUNCTION case_generate_series(cond bool, start int, fin int, els int)
+ RETURNS SETOF int AS $$
+BEGIN
+ IF cond THEN
+ RETURN QUERY SELECT generate_series(start, fin);
+ ELSE
+ RETURN QUERY SELECT els;
+ END IF;
+END$$ LANGUAGE plpgsql;
+
+SELECT x, case_generate_series(y &gt; 0, 1, z, 5) FROM tab;
+</pre><p>
+ This formulation will work the same in all versions
+ of <span class="productname">PostgreSQL</span>.
+ </p></div></div><div class="sect2" id="XFUNC-SQL-FUNCTIONS-RETURNING-TABLE"><div class="titlepage"><div><div><h3 class="title">38.5.10. <acronym class="acronym">SQL</acronym> Functions Returning <code class="literal">TABLE</code></h3></div></div></div><a id="id-1.8.3.8.19.2" class="indexterm"></a><p>
+ There is another way to declare a function as returning a set,
+ which is to use the syntax
+ <code class="literal">RETURNS TABLE(<em class="replaceable"><code>columns</code></em>)</code>.
+ This is equivalent to using one or more <code class="literal">OUT</code> parameters plus
+ marking the function as returning <code class="literal">SETOF record</code> (or
+ <code class="literal">SETOF</code> a single output parameter's type, as appropriate).
+ This notation is specified in recent versions of the SQL standard, and
+ thus may be more portable than using <code class="literal">SETOF</code>.
+ </p><p>
+ For example, the preceding sum-and-product example could also be
+ done this way:
+
+</p><pre class="programlisting">
+CREATE FUNCTION sum_n_product_with_tab (x int)
+RETURNS TABLE(sum int, product int) AS $$
+ SELECT $1 + tab.y, $1 * tab.y FROM tab;
+$$ LANGUAGE SQL;
+</pre><p>
+
+ It is not allowed to use explicit <code class="literal">OUT</code> or <code class="literal">INOUT</code>
+ parameters with the <code class="literal">RETURNS TABLE</code> notation — you must
+ put all the output columns in the <code class="literal">TABLE</code> list.
+ </p></div><div class="sect2" id="XFUNC-SQL-POLYMORPHIC-FUNCTIONS"><div class="titlepage"><div><div><h3 class="title">38.5.11. Polymorphic <acronym class="acronym">SQL</acronym> Functions</h3></div></div></div><p>
+ <acronym class="acronym">SQL</acronym> functions can be declared to accept and
+ return the polymorphic types described in <a class="xref" href="extend-type-system.html#EXTEND-TYPES-POLYMORPHIC" title="38.2.5. Polymorphic Types">Section 38.2.5</a>. Here is a polymorphic
+ function <code class="function">make_array</code> that builds up an array
+ from two arbitrary data type elements:
+</p><pre class="screen">
+CREATE FUNCTION make_array(anyelement, anyelement) RETURNS anyarray AS $$
+ SELECT ARRAY[$1, $2];
+$$ LANGUAGE SQL;
+
+SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray;
+ intarray | textarray
+----------+-----------
+ {1,2} | {a,b}
+(1 row)
+</pre><p>
+ </p><p>
+ Notice the use of the typecast <code class="literal">'a'::text</code>
+ to specify that the argument is of type <code class="type">text</code>. This is
+ required if the argument is just a string literal, since otherwise
+ it would be treated as type
+ <code class="type">unknown</code>, and array of <code class="type">unknown</code> is not a valid
+ type.
+ Without the typecast, you will get errors like this:
+</p><pre class="screen">
+ERROR: could not determine polymorphic type because input has type unknown
+</pre><p>
+ </p><p>
+ With <code class="function">make_array</code> declared as above, you must
+ provide two arguments that are of exactly the same data type; the
+ system will not attempt to resolve any type differences. Thus for
+ example this does not work:
+</p><pre class="screen">
+SELECT make_array(1, 2.5) AS numericarray;
+ERROR: function make_array(integer, numeric) does not exist
+</pre><p>
+ An alternative approach is to use the <span class="quote">“<span class="quote">common</span>”</span> family of
+ polymorphic types, which allows the system to try to identify a
+ suitable common type:
+</p><pre class="screen">
+CREATE FUNCTION make_array2(anycompatible, anycompatible)
+RETURNS anycompatiblearray AS $$
+ SELECT ARRAY[$1, $2];
+$$ LANGUAGE SQL;
+
+SELECT make_array2(1, 2.5) AS numericarray;
+ numericarray
+--------------
+ {1,2.5}
+(1 row)
+</pre><p>
+ Because the rules for common type resolution default to choosing
+ type <code class="type">text</code> when all inputs are of unknown types, this
+ also works:
+</p><pre class="screen">
+SELECT make_array2('a', 'b') AS textarray;
+ textarray
+-----------
+ {a,b}
+(1 row)
+</pre><p>
+ </p><p>
+ It is permitted to have polymorphic arguments with a fixed
+ return type, but the converse is not. For example:
+</p><pre class="screen">
+CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$
+ SELECT $1 &gt; $2;
+$$ LANGUAGE SQL;
+
+SELECT is_greater(1, 2);
+ is_greater
+------------
+ f
+(1 row)
+
+CREATE FUNCTION invalid_func() RETURNS anyelement AS $$
+ SELECT 1;
+$$ LANGUAGE SQL;
+ERROR: cannot determine result data type
+DETAIL: A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
+</pre><p>
+ </p><p>
+ Polymorphism can be used with functions that have output arguments.
+ For example:
+</p><pre class="screen">
+CREATE FUNCTION dup (f1 anyelement, OUT f2 anyelement, OUT f3 anyarray)
+AS 'select $1, array[$1,$1]' LANGUAGE SQL;
+
+SELECT * FROM dup(22);
+ f2 | f3
+----+---------
+ 22 | {22,22}
+(1 row)
+</pre><p>
+ </p><p>
+ Polymorphism can also be used with variadic functions.
+ For example:
+</p><pre class="screen">
+CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$
+ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
+$$ LANGUAGE SQL;
+
+SELECT anyleast(10, -1, 5, 4);
+ anyleast
+----------
+ -1
+(1 row)
+
+SELECT anyleast('abc'::text, 'def');
+ anyleast
+----------
+ abc
+(1 row)
+
+CREATE FUNCTION concat_values(text, VARIADIC anyarray) RETURNS text AS $$
+ SELECT array_to_string($2, $1);
+$$ LANGUAGE SQL;
+
+SELECT concat_values('|', 1, 4, 2);
+ concat_values
+---------------
+ 1|4|2
+(1 row)
+</pre><p>
+ </p></div><div class="sect2" id="id-1.8.3.8.21"><div class="titlepage"><div><div><h3 class="title">38.5.12. <acronym class="acronym">SQL</acronym> Functions with Collations</h3></div></div></div><a id="id-1.8.3.8.21.2" class="indexterm"></a><p>
+ When an SQL function has one or more parameters of collatable data types,
+ a collation is identified for each function call depending on the
+ collations assigned to the actual arguments, as described in <a class="xref" href="collation.html" title="24.2. Collation Support">Section 24.2</a>. If a collation is successfully identified
+ (i.e., there are no conflicts of implicit collations among the arguments)
+ then all the collatable parameters are treated as having that collation
+ implicitly. This will affect the behavior of collation-sensitive
+ operations within the function. For example, using the
+ <code class="function">anyleast</code> function described above, the result of
+</p><pre class="programlisting">
+SELECT anyleast('abc'::text, 'ABC');
+</pre><p>
+ will depend on the database's default collation. In <code class="literal">C</code> locale
+ the result will be <code class="literal">ABC</code>, but in many other locales it will
+ be <code class="literal">abc</code>. The collation to use can be forced by adding
+ a <code class="literal">COLLATE</code> clause to any of the arguments, for example
+</p><pre class="programlisting">
+SELECT anyleast('abc'::text, 'ABC' COLLATE "C");
+</pre><p>
+ Alternatively, if you wish a function to operate with a particular
+ collation regardless of what it is called with, insert
+ <code class="literal">COLLATE</code> clauses as needed in the function definition.
+ This version of <code class="function">anyleast</code> would always use <code class="literal">en_US</code>
+ locale to compare strings:
+</p><pre class="programlisting">
+CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$
+ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i);
+$$ LANGUAGE SQL;
+</pre><p>
+ But note that this will throw an error if applied to a non-collatable
+ data type.
+ </p><p>
+ If no common collation can be identified among the actual arguments,
+ then an SQL function treats its parameters as having their data types'
+ default collation (which is usually the database's default collation,
+ but could be different for parameters of domain types).
+ </p><p>
+ The behavior of collatable parameters can be thought of as a limited
+ form of polymorphism, applicable only to textual data types.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xproc.html" title="38.4. User-Defined Procedures">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-overload.html" title="38.6. Function Overloading">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.4. User-Defined Procedures </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.6. Function Overloading</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc-volatility.html b/doc/src/sgml/html/xfunc-volatility.html
new file mode 100644
index 0000000..b34ef2f
--- /dev/null
+++ b/doc/src/sgml/html/xfunc-volatility.html
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.7. Function Volatility Categories</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc-overload.html" title="38.6. Function Overloading" /><link rel="next" href="xfunc-pl.html" title="38.8. Procedural Language Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.7. Function Volatility Categories</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc-overload.html" title="38.6. Function Overloading">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-pl.html" title="38.8. Procedural Language Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC-VOLATILITY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.7. Function Volatility Categories</h2></div></div></div><a id="id-1.8.3.10.2" class="indexterm"></a><a id="id-1.8.3.10.3" class="indexterm"></a><a id="id-1.8.3.10.4" class="indexterm"></a><a id="id-1.8.3.10.5" class="indexterm"></a><p>
+ Every function has a <em class="firstterm">volatility</em> classification, with
+ the possibilities being <code class="literal">VOLATILE</code>, <code class="literal">STABLE</code>, or
+ <code class="literal">IMMUTABLE</code>. <code class="literal">VOLATILE</code> is the default if the
+ <a class="link" href="sql-createfunction.html" title="CREATE FUNCTION"><code class="command">CREATE FUNCTION</code></a>
+ command does not specify a category. The volatility category is a
+ promise to the optimizer about the behavior of the function:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ A <code class="literal">VOLATILE</code> function can do anything, including modifying
+ the database. It can return different results on successive calls with
+ the same arguments. The optimizer makes no assumptions about the
+ behavior of such functions. A query using a volatile function will
+ re-evaluate the function at every row where its value is needed.
+ </p></li><li class="listitem"><p>
+ A <code class="literal">STABLE</code> function cannot modify the database and is
+ guaranteed to return the same results given the same arguments
+ for all rows within a single statement. This category allows the
+ optimizer to optimize multiple calls of the function to a single
+ call. In particular, it is safe to use an expression containing
+ such a function in an index scan condition. (Since an index scan
+ will evaluate the comparison value only once, not once at each
+ row, it is not valid to use a <code class="literal">VOLATILE</code> function in an
+ index scan condition.)
+ </p></li><li class="listitem"><p>
+ An <code class="literal">IMMUTABLE</code> function cannot modify the database and is
+ guaranteed to return the same results given the same arguments forever.
+ This category allows the optimizer to pre-evaluate the function when
+ a query calls it with constant arguments. For example, a query like
+ <code class="literal">SELECT ... WHERE x = 2 + 2</code> can be simplified on sight to
+ <code class="literal">SELECT ... WHERE x = 4</code>, because the function underlying
+ the integer addition operator is marked <code class="literal">IMMUTABLE</code>.
+ </p></li></ul></div><p>
+ </p><p>
+ For best optimization results, you should label your functions with the
+ strictest volatility category that is valid for them.
+ </p><p>
+ Any function with side-effects <span class="emphasis"><em>must</em></span> be labeled
+ <code class="literal">VOLATILE</code>, so that calls to it cannot be optimized away.
+ Even a function with no side-effects needs to be labeled
+ <code class="literal">VOLATILE</code> if its value can change within a single query;
+ some examples are <code class="literal">random()</code>, <code class="literal">currval()</code>,
+ <code class="literal">timeofday()</code>.
+ </p><p>
+ Another important example is that the <code class="function">current_timestamp</code>
+ family of functions qualify as <code class="literal">STABLE</code>, since their values do
+ not change within a transaction.
+ </p><p>
+ There is relatively little difference between <code class="literal">STABLE</code> and
+ <code class="literal">IMMUTABLE</code> categories when considering simple interactive
+ queries that are planned and immediately executed: it doesn't matter
+ a lot whether a function is executed once during planning or once during
+ query execution startup. But there is a big difference if the plan is
+ saved and reused later. Labeling a function <code class="literal">IMMUTABLE</code> when
+ it really isn't might allow it to be prematurely folded to a constant during
+ planning, resulting in a stale value being re-used during subsequent uses
+ of the plan. This is a hazard when using prepared statements or when
+ using function languages that cache plans (such as
+ <span class="application">PL/pgSQL</span>).
+ </p><p>
+ For functions written in SQL or in any of the standard procedural
+ languages, there is a second important property determined by the
+ volatility category, namely the visibility of any data changes that have
+ been made by the SQL command that is calling the function. A
+ <code class="literal">VOLATILE</code> function will see such changes, a <code class="literal">STABLE</code>
+ or <code class="literal">IMMUTABLE</code> function will not. This behavior is implemented
+ using the snapshotting behavior of MVCC (see <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>):
+ <code class="literal">STABLE</code> and <code class="literal">IMMUTABLE</code> functions use a snapshot
+ established as of the start of the calling query, whereas
+ <code class="literal">VOLATILE</code> functions obtain a fresh snapshot at the start of
+ each query they execute.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Functions written in C can manage snapshots however they want, but it's
+ usually a good idea to make C functions work this way too.
+ </p></div><p>
+ Because of this snapshotting behavior,
+ a function containing only <code class="command">SELECT</code> commands can safely be
+ marked <code class="literal">STABLE</code>, even if it selects from tables that might be
+ undergoing modifications by concurrent queries.
+ <span class="productname">PostgreSQL</span> will execute all commands of a
+ <code class="literal">STABLE</code> function using the snapshot established for the
+ calling query, and so it will see a fixed view of the database throughout
+ that query.
+ </p><p>
+ The same snapshotting behavior is used for <code class="command">SELECT</code> commands
+ within <code class="literal">IMMUTABLE</code> functions. It is generally unwise to select
+ from database tables within an <code class="literal">IMMUTABLE</code> function at all,
+ since the immutability will be broken if the table contents ever change.
+ However, <span class="productname">PostgreSQL</span> does not enforce that you
+ do not do that.
+ </p><p>
+ A common error is to label a function <code class="literal">IMMUTABLE</code> when its
+ results depend on a configuration parameter. For example, a function
+ that manipulates timestamps might well have results that depend on the
+ <a class="xref" href="runtime-config-client.html#GUC-TIMEZONE">TimeZone</a> setting. For safety, such functions should
+ be labeled <code class="literal">STABLE</code> instead.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ <span class="productname">PostgreSQL</span> requires that <code class="literal">STABLE</code>
+ and <code class="literal">IMMUTABLE</code> functions contain no SQL commands other
+ than <code class="command">SELECT</code> to prevent data modification.
+ (This is not a completely bulletproof test, since such functions could
+ still call <code class="literal">VOLATILE</code> functions that modify the database.
+ If you do that, you will find that the <code class="literal">STABLE</code> or
+ <code class="literal">IMMUTABLE</code> function does not notice the database changes
+ applied by the called function, since they are hidden from its snapshot.)
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc-overload.html" title="38.6. Function Overloading">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-pl.html" title="38.8. Procedural Language Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.6. Function Overloading </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.8. Procedural Language Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xfunc.html b/doc/src/sgml/html/xfunc.html
new file mode 100644
index 0000000..4c94a24
--- /dev/null
+++ b/doc/src/sgml/html/xfunc.html
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.3. User-Defined Functions</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="extend-type-system.html" title="38.2. The PostgreSQL Type System" /><link rel="next" href="xproc.html" title="38.4. User-Defined Procedures" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.3. User-Defined Functions</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="extend-type-system.html" title="38.2. The PostgreSQL Type System">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xproc.html" title="38.4. User-Defined Procedures">Next</a></td></tr></table><hr /></div><div class="sect1" id="XFUNC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.3. User-Defined Functions</h2></div></div></div><a id="id-1.8.3.6.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> provides four kinds of
+ functions:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ query language functions (functions written in
+ <acronym class="acronym">SQL</acronym>) (<a class="xref" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions">Section 38.5</a>)
+ </p></li><li class="listitem"><p>
+ procedural language functions (functions written in, for
+ example, <span class="application">PL/pgSQL</span> or <span class="application">PL/Tcl</span>)
+ (<a class="xref" href="xfunc-pl.html" title="38.8. Procedural Language Functions">Section 38.8</a>)
+ </p></li><li class="listitem"><p>
+ internal functions (<a class="xref" href="xfunc-internal.html" title="38.9. Internal Functions">Section 38.9</a>)
+ </p></li><li class="listitem"><p>
+ C-language functions (<a class="xref" href="xfunc-c.html" title="38.10. C-Language Functions">Section 38.10</a>)
+ </p></li></ul></div><p>
+ </p><p>
+ Every kind
+ of function can take base types, composite types, or
+ combinations of these as arguments (parameters). In addition,
+ every kind of function can return a base type or
+ a composite type. Functions can also be defined to return
+ sets of base or composite values.
+ </p><p>
+ Many kinds of functions can take or return certain pseudo-types
+ (such as polymorphic types), but the available facilities vary.
+ Consult the description of each kind of function for more details.
+ </p><p>
+ It's easiest to define <acronym class="acronym">SQL</acronym>
+ functions, so we'll start by discussing those.
+ Most of the concepts presented for <acronym class="acronym">SQL</acronym> functions
+ will carry over to the other types of functions.
+ </p><p>
+ Throughout this chapter, it can be useful to look at the reference
+ page of the <a class="link" href="sql-createfunction.html" title="CREATE FUNCTION"><code class="command">CREATE
+ FUNCTION</code></a> command to
+ understand the examples better. Some examples from this chapter
+ can be found in <code class="filename">funcs.sql</code> and
+ <code class="filename">funcs.c</code> in the <code class="filename">src/tutorial</code>
+ directory in the <span class="productname">PostgreSQL</span> source
+ distribution.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="extend-type-system.html" title="38.2. The PostgreSQL Type System">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xproc.html" title="38.4. User-Defined Procedures">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.2. The <span class="productname">PostgreSQL</span> Type System </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.4. User-Defined Procedures</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xindex.html b/doc/src/sgml/html/xindex.html
new file mode 100644
index 0000000..9e87128
--- /dev/null
+++ b/doc/src/sgml/html/xindex.html
@@ -0,0 +1,772 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.16. Interfacing Extensions to Indexes</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xoper-optimization.html" title="38.15. Operator Optimization Information" /><link rel="next" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.16. Interfacing Extensions to Indexes</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xoper-optimization.html" title="38.15. Operator Optimization Information">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Next</a></td></tr></table><hr /></div><div class="sect1" id="XINDEX"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.16. Interfacing Extensions to Indexes</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xindex.html#XINDEX-OPCLASS">38.16.1. Index Methods and Operator Classes</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-STRATEGIES">38.16.2. Index Method Strategies</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-SUPPORT">38.16.3. Index Method Support Routines</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-EXAMPLE">38.16.4. An Example</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-OPFAMILY">38.16.5. Operator Classes and Operator Families</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-OPCLASS-DEPENDENCIES">38.16.6. System Dependencies on Operator Classes</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-ORDERING-OPS">38.16.7. Ordering Operators</a></span></dt><dt><span class="sect2"><a href="xindex.html#XINDEX-OPCLASS-FEATURES">38.16.8. Special Features of Operator Classes</a></span></dt></dl></div><a id="id-1.8.3.19.2" class="indexterm"></a><p>
+ The procedures described thus far let you define new types, new
+ functions, and new operators. However, we cannot yet define an
+ index on a column of a new data type. To do this, we must define an
+ <em class="firstterm">operator class</em> for the new data type. Later in this
+ section, we will illustrate this concept in an example: a new
+ operator class for the B-tree index method that stores and sorts
+ complex numbers in ascending absolute value order.
+ </p><p>
+ Operator classes can be grouped into <em class="firstterm">operator families</em>
+ to show the relationships between semantically compatible classes.
+ When only a single data type is involved, an operator class is sufficient,
+ so we'll focus on that case first and then return to operator families.
+ </p><div class="sect2" id="XINDEX-OPCLASS"><div class="titlepage"><div><div><h3 class="title">38.16.1. Index Methods and Operator Classes</h3></div></div></div><p>
+ The <code class="classname">pg_am</code> table contains one row for every
+ index method (internally known as access method). Support for
+ regular access to tables is built into
+ <span class="productname">PostgreSQL</span>, but all index methods are
+ described in <code class="classname">pg_am</code>. It is possible to add a
+ new index access method by writing the necessary code and
+ then creating an entry in <code class="classname">pg_am</code> — but that is
+ beyond the scope of this chapter (see <a class="xref" href="indexam.html" title="Chapter 64. Index Access Method Interface Definition">Chapter 64</a>).
+ </p><p>
+ The routines for an index method do not directly know anything
+ about the data types that the index method will operate on.
+ Instead, an <em class="firstterm">operator
+ class</em><a id="id-1.8.3.19.5.3.2" class="indexterm"></a>
+ identifies the set of operations that the index method needs to use
+ to work with a particular data type. Operator classes are so
+ called because one thing they specify is the set of
+ <code class="literal">WHERE</code>-clause operators that can be used with an index
+ (i.e., can be converted into an index-scan qualification). An
+ operator class can also specify some <em class="firstterm">support
+ function</em> that are needed by the internal operations of the
+ index method, but do not directly correspond to any
+ <code class="literal">WHERE</code>-clause operator that can be used with the index.
+ </p><p>
+ It is possible to define multiple operator classes for the same
+ data type and index method. By doing this, multiple
+ sets of indexing semantics can be defined for a single data type.
+ For example, a B-tree index requires a sort ordering to be defined
+ for each data type it works on.
+ It might be useful for a complex-number data type
+ to have one B-tree operator class that sorts the data by complex
+ absolute value, another that sorts by real part, and so on.
+ Typically, one of the operator classes will be deemed most commonly
+ useful and will be marked as the default operator class for that
+ data type and index method.
+ </p><p>
+ The same operator class name
+ can be used for several different index methods (for example, both B-tree
+ and hash index methods have operator classes named
+ <code class="literal">int4_ops</code>), but each such class is an independent
+ entity and must be defined separately.
+ </p></div><div class="sect2" id="XINDEX-STRATEGIES"><div class="titlepage"><div><div><h3 class="title">38.16.2. Index Method Strategies</h3></div></div></div><p>
+ The operators associated with an operator class are identified by
+ <span class="quote">“<span class="quote">strategy numbers</span>”</span>, which serve to identify the semantics of
+ each operator within the context of its operator class.
+ For example, B-trees impose a strict ordering on keys, lesser to greater,
+ and so operators like <span class="quote">“<span class="quote">less than</span>”</span> and <span class="quote">“<span class="quote">greater than or equal
+ to</span>”</span> are interesting with respect to a B-tree.
+ Because
+ <span class="productname">PostgreSQL</span> allows the user to define operators,
+ <span class="productname">PostgreSQL</span> cannot look at the name of an operator
+ (e.g., <code class="literal">&lt;</code> or <code class="literal">&gt;=</code>) and tell what kind of
+ comparison it is. Instead, the index method defines a set of
+ <span class="quote">“<span class="quote">strategies</span>”</span>, which can be thought of as generalized operators.
+ Each operator class specifies which actual operator corresponds to each
+ strategy for a particular data type and interpretation of the index
+ semantics.
+ </p><p>
+ The B-tree index method defines five strategies, shown in <a class="xref" href="xindex.html#XINDEX-BTREE-STRAT-TABLE" title="Table 38.3. B-Tree Strategies">Table 38.3</a>.
+ </p><div class="table" id="XINDEX-BTREE-STRAT-TABLE"><p class="title"><strong>Table 38.3. B-Tree Strategies</strong></p><div class="table-contents"><table class="table" summary="B-Tree Strategies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operation</th><th>Strategy Number</th></tr></thead><tbody><tr><td>less than</td><td>1</td></tr><tr><td>less than or equal</td><td>2</td></tr><tr><td>equal</td><td>3</td></tr><tr><td>greater than or equal</td><td>4</td></tr><tr><td>greater than</td><td>5</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Hash indexes support only equality comparisons, and so they use only one
+ strategy, shown in <a class="xref" href="xindex.html#XINDEX-HASH-STRAT-TABLE" title="Table 38.4. Hash Strategies">Table 38.4</a>.
+ </p><div class="table" id="XINDEX-HASH-STRAT-TABLE"><p class="title"><strong>Table 38.4. Hash Strategies</strong></p><div class="table-contents"><table class="table" summary="Hash Strategies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operation</th><th>Strategy Number</th></tr></thead><tbody><tr><td>equal</td><td>1</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ GiST indexes are more flexible: they do not have a fixed set of
+ strategies at all. Instead, the <span class="quote">“<span class="quote">consistency</span>”</span> support routine
+ of each particular GiST operator class interprets the strategy numbers
+ however it likes. As an example, several of the built-in GiST index
+ operator classes index two-dimensional geometric objects, providing
+ the <span class="quote">“<span class="quote">R-tree</span>”</span> strategies shown in
+ <a class="xref" href="xindex.html#XINDEX-RTREE-STRAT-TABLE" title="Table 38.5. GiST Two-Dimensional “R-tree” Strategies">Table 38.5</a>. Four of these are true
+ two-dimensional tests (overlaps, same, contains, contained by);
+ four of them consider only the X direction; and the other four
+ provide the same tests in the Y direction.
+ </p><div class="table" id="XINDEX-RTREE-STRAT-TABLE"><p class="title"><strong>Table 38.5. GiST Two-Dimensional <span class="quote">“<span class="quote">R-tree</span>”</span> Strategies</strong></p><div class="table-contents"><table class="table" summary="GiST Two-Dimensional R-tree Strategies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operation</th><th>Strategy Number</th></tr></thead><tbody><tr><td>strictly left of</td><td>1</td></tr><tr><td>does not extend to right of</td><td>2</td></tr><tr><td>overlaps</td><td>3</td></tr><tr><td>does not extend to left of</td><td>4</td></tr><tr><td>strictly right of</td><td>5</td></tr><tr><td>same</td><td>6</td></tr><tr><td>contains</td><td>7</td></tr><tr><td>contained by</td><td>8</td></tr><tr><td>does not extend above</td><td>9</td></tr><tr><td>strictly below</td><td>10</td></tr><tr><td>strictly above</td><td>11</td></tr><tr><td>does not extend below</td><td>12</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ SP-GiST indexes are similar to GiST indexes in flexibility: they don't have
+ a fixed set of strategies. Instead the support routines of each operator
+ class interpret the strategy numbers according to the operator class's
+ definition. As an example, the strategy numbers used by the built-in
+ operator classes for points are shown in <a class="xref" href="xindex.html#XINDEX-SPGIST-POINT-STRAT-TABLE" title="Table 38.6. SP-GiST Point Strategies">Table 38.6</a>.
+ </p><div class="table" id="XINDEX-SPGIST-POINT-STRAT-TABLE"><p class="title"><strong>Table 38.6. SP-GiST Point Strategies</strong></p><div class="table-contents"><table class="table" summary="SP-GiST Point Strategies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operation</th><th>Strategy Number</th></tr></thead><tbody><tr><td>strictly left of</td><td>1</td></tr><tr><td>strictly right of</td><td>5</td></tr><tr><td>same</td><td>6</td></tr><tr><td>contained by</td><td>8</td></tr><tr><td>strictly below</td><td>10</td></tr><tr><td>strictly above</td><td>11</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ GIN indexes are similar to GiST and SP-GiST indexes, in that they don't
+ have a fixed set of strategies either. Instead the support routines of
+ each operator class interpret the strategy numbers according to the
+ operator class's definition. As an example, the strategy numbers used by
+ the built-in operator class for arrays are shown in
+ <a class="xref" href="xindex.html#XINDEX-GIN-ARRAY-STRAT-TABLE" title="Table 38.7. GIN Array Strategies">Table 38.7</a>.
+ </p><div class="table" id="XINDEX-GIN-ARRAY-STRAT-TABLE"><p class="title"><strong>Table 38.7. GIN Array Strategies</strong></p><div class="table-contents"><table class="table" summary="GIN Array Strategies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operation</th><th>Strategy Number</th></tr></thead><tbody><tr><td>overlap</td><td>1</td></tr><tr><td>contains</td><td>2</td></tr><tr><td>is contained by</td><td>3</td></tr><tr><td>equal</td><td>4</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ BRIN indexes are similar to GiST, SP-GiST and GIN indexes in that they
+ don't have a fixed set of strategies either. Instead the support routines
+ of each operator class interpret the strategy numbers according to the
+ operator class's definition. As an example, the strategy numbers used by
+ the built-in <code class="literal">Minmax</code> operator classes are shown in
+ <a class="xref" href="xindex.html#XINDEX-BRIN-MINMAX-STRAT-TABLE" title="Table 38.8. BRIN Minmax Strategies">Table 38.8</a>.
+ </p><div class="table" id="XINDEX-BRIN-MINMAX-STRAT-TABLE"><p class="title"><strong>Table 38.8. BRIN Minmax Strategies</strong></p><div class="table-contents"><table class="table" summary="BRIN Minmax Strategies" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>Operation</th><th>Strategy Number</th></tr></thead><tbody><tr><td>less than</td><td>1</td></tr><tr><td>less than or equal</td><td>2</td></tr><tr><td>equal</td><td>3</td></tr><tr><td>greater than or equal</td><td>4</td></tr><tr><td>greater than</td><td>5</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Notice that all the operators listed above return Boolean values. In
+ practice, all operators defined as index method search operators must
+ return type <code class="type">boolean</code>, since they must appear at the top
+ level of a <code class="literal">WHERE</code> clause to be used with an index.
+ (Some index access methods also support <em class="firstterm">ordering operators</em>,
+ which typically don't return Boolean values; that feature is discussed
+ in <a class="xref" href="xindex.html#XINDEX-ORDERING-OPS" title="38.16.7. Ordering Operators">Section 38.16.7</a>.)
+ </p></div><div class="sect2" id="XINDEX-SUPPORT"><div class="titlepage"><div><div><h3 class="title">38.16.3. Index Method Support Routines</h3></div></div></div><p>
+ Strategies aren't usually enough information for the system to figure
+ out how to use an index. In practice, the index methods require
+ additional support routines in order to work. For example, the B-tree
+ index method must be able to compare two keys and determine whether one
+ is greater than, equal to, or less than the other. Similarly, the
+ hash index method must be able to compute hash codes for key values.
+ These operations do not correspond to operators used in qualifications in
+ SQL commands; they are administrative routines used by
+ the index methods, internally.
+ </p><p>
+ Just as with strategies, the operator class identifies which specific
+ functions should play each of these roles for a given data type and
+ semantic interpretation. The index method defines the set
+ of functions it needs, and the operator class identifies the correct
+ functions to use by assigning them to the <span class="quote">“<span class="quote">support function numbers</span>”</span>
+ specified by the index method.
+ </p><p>
+ Additionally, some opclasses allow users to specify parameters which
+ control their behavior. Each builtin index access method has an optional
+ <code class="function">options</code> support function, which defines a set of
+ opclass-specific parameters.
+ </p><p>
+ B-trees require a comparison support function,
+ and allow four additional support functions to be
+ supplied at the operator class author's option, as shown in <a class="xref" href="xindex.html#XINDEX-BTREE-SUPPORT-TABLE" title="Table 38.9. B-Tree Support Functions">Table 38.9</a>.
+ The requirements for these support functions are explained further in
+ <a class="xref" href="btree-support-funcs.html" title="67.3. B-Tree Support Functions">Section 67.3</a>.
+ </p><div class="table" id="XINDEX-BTREE-SUPPORT-TABLE"><p class="title"><strong>Table 38.9. B-Tree Support Functions</strong></p><div class="table-contents"><table class="table" summary="B-Tree Support Functions" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Function</th><th>Support Number</th></tr></thead><tbody><tr><td>
+ Compare two keys and return an integer less than zero, zero, or
+ greater than zero, indicating whether the first key is less than,
+ equal to, or greater than the second
+ </td><td>1</td></tr><tr><td>
+ Return the addresses of C-callable sort support function(s)
+ (optional)
+ </td><td>2</td></tr><tr><td>
+ Compare a test value to a base value plus/minus an offset, and return
+ true or false according to the comparison result (optional)
+ </td><td>3</td></tr><tr><td>
+ Determine if it is safe for indexes that use the operator
+ class to apply the btree deduplication optimization (optional)
+ </td><td>4</td></tr><tr><td>
+ Define options that are specific to this operator class
+ (optional)
+ </td><td>5</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Hash indexes require one support function, and allow two additional ones to
+ be supplied at the operator class author's option, as shown in <a class="xref" href="xindex.html#XINDEX-HASH-SUPPORT-TABLE" title="Table 38.10. Hash Support Functions">Table 38.10</a>.
+ </p><div class="table" id="XINDEX-HASH-SUPPORT-TABLE"><p class="title"><strong>Table 38.10. Hash Support Functions</strong></p><div class="table-contents"><table class="table" summary="Hash Support Functions" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Function</th><th>Support Number</th></tr></thead><tbody><tr><td>Compute the 32-bit hash value for a key</td><td>1</td></tr><tr><td>
+ Compute the 64-bit hash value for a key given a 64-bit salt; if
+ the salt is 0, the low 32 bits of the result must match the value
+ that would have been computed by function 1
+ (optional)
+ </td><td>2</td></tr><tr><td>
+ Define options that are specific to this operator class
+ (optional)
+ </td><td>3</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ GiST indexes have eleven support functions, six of which are optional,
+ as shown in <a class="xref" href="xindex.html#XINDEX-GIST-SUPPORT-TABLE" title="Table 38.11. GiST Support Functions">Table 38.11</a>.
+ (For more information see <a class="xref" href="gist.html" title="Chapter 68. GiST Indexes">Chapter 68</a>.)
+ </p><div class="table" id="XINDEX-GIST-SUPPORT-TABLE"><p class="title"><strong>Table 38.11. GiST Support Functions</strong></p><div class="table-contents"><table class="table" summary="GiST Support Functions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Function</th><th>Description</th><th>Support Number</th></tr></thead><tbody><tr><td><code class="function">consistent</code></td><td>determine whether key satisfies the
+ query qualifier</td><td>1</td></tr><tr><td><code class="function">union</code></td><td>compute union of a set of keys</td><td>2</td></tr><tr><td><code class="function">compress</code></td><td>compute a compressed representation of a key or value
+ to be indexed (optional)</td><td>3</td></tr><tr><td><code class="function">decompress</code></td><td>compute a decompressed representation of a
+ compressed key (optional)</td><td>4</td></tr><tr><td><code class="function">penalty</code></td><td>compute penalty for inserting new key into subtree
+ with given subtree's key</td><td>5</td></tr><tr><td><code class="function">picksplit</code></td><td>determine which entries of a page are to be moved
+ to the new page and compute the union keys for resulting pages</td><td>6</td></tr><tr><td><code class="function">same</code></td><td>compare two keys and return true if they are equal</td><td>7</td></tr><tr><td><code class="function">distance</code></td><td>determine distance from key to query value (optional)</td><td>8</td></tr><tr><td><code class="function">fetch</code></td><td>compute original representation of a compressed key for
+ index-only scans (optional)</td><td>9</td></tr><tr><td><code class="function">options</code></td><td>define options that are specific to this operator class
+ (optional)</td><td>10</td></tr><tr><td><code class="function">sortsupport</code></td><td>provide a sort comparator to be used in fast index builds
+ (optional)</td><td>11</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ SP-GiST indexes have six support functions, one of which is optional, as
+ shown in <a class="xref" href="xindex.html#XINDEX-SPGIST-SUPPORT-TABLE" title="Table 38.12. SP-GiST Support Functions">Table 38.12</a>.
+ (For more information see <a class="xref" href="spgist.html" title="Chapter 69. SP-GiST Indexes">Chapter 69</a>.)
+ </p><div class="table" id="XINDEX-SPGIST-SUPPORT-TABLE"><p class="title"><strong>Table 38.12. SP-GiST Support Functions</strong></p><div class="table-contents"><table class="table" summary="SP-GiST Support Functions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Function</th><th>Description</th><th>Support Number</th></tr></thead><tbody><tr><td><code class="function">config</code></td><td>provide basic information about the operator class</td><td>1</td></tr><tr><td><code class="function">choose</code></td><td>determine how to insert a new value into an inner tuple</td><td>2</td></tr><tr><td><code class="function">picksplit</code></td><td>determine how to partition a set of values</td><td>3</td></tr><tr><td><code class="function">inner_consistent</code></td><td>determine which sub-partitions need to be searched for a
+ query</td><td>4</td></tr><tr><td><code class="function">leaf_consistent</code></td><td>determine whether key satisfies the
+ query qualifier</td><td>5</td></tr><tr><td><code class="function">options</code></td><td>define options that are specific to this operator class
+ (optional)</td><td>6</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ GIN indexes have seven support functions, four of which are optional,
+ as shown in <a class="xref" href="xindex.html#XINDEX-GIN-SUPPORT-TABLE" title="Table 38.13. GIN Support Functions">Table 38.13</a>.
+ (For more information see <a class="xref" href="gin.html" title="Chapter 70. GIN Indexes">Chapter 70</a>.)
+ </p><div class="table" id="XINDEX-GIN-SUPPORT-TABLE"><p class="title"><strong>Table 38.13. GIN Support Functions</strong></p><div class="table-contents"><table class="table" summary="GIN Support Functions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Function</th><th>Description</th><th>Support Number</th></tr></thead><tbody><tr><td><code class="function">compare</code></td><td>
+ compare two keys and return an integer less than zero, zero,
+ or greater than zero, indicating whether the first key is less than,
+ equal to, or greater than the second
+ </td><td>1</td></tr><tr><td><code class="function">extractValue</code></td><td>extract keys from a value to be indexed</td><td>2</td></tr><tr><td><code class="function">extractQuery</code></td><td>extract keys from a query condition</td><td>3</td></tr><tr><td><code class="function">consistent</code></td><td>
+ determine whether value matches query condition (Boolean variant)
+ (optional if support function 6 is present)
+ </td><td>4</td></tr><tr><td><code class="function">comparePartial</code></td><td>
+ compare partial key from
+ query and key from index, and return an integer less than zero, zero,
+ or greater than zero, indicating whether GIN should ignore this index
+ entry, treat the entry as a match, or stop the index scan (optional)
+ </td><td>5</td></tr><tr><td><code class="function">triConsistent</code></td><td>
+ determine whether value matches query condition (ternary variant)
+ (optional if support function 4 is present)
+ </td><td>6</td></tr><tr><td><code class="function">options</code></td><td>
+ define options that are specific to this operator class
+ (optional)
+ </td><td>7</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ BRIN indexes have five basic support functions, one of which is optional,
+ as shown in <a class="xref" href="xindex.html#XINDEX-BRIN-SUPPORT-TABLE" title="Table 38.14. BRIN Support Functions">Table 38.14</a>. Some versions of
+ the basic functions require additional support functions to be provided.
+ (For more information see <a class="xref" href="brin-extensibility.html" title="71.3. Extensibility">Section 71.3</a>.)
+ </p><div class="table" id="XINDEX-BRIN-SUPPORT-TABLE"><p class="title"><strong>Table 38.14. BRIN Support Functions</strong></p><div class="table-contents"><table class="table" summary="BRIN Support Functions" border="1"><colgroup><col class="col1" /><col class="col2" /><col class="col3" /></colgroup><thead><tr><th>Function</th><th>Description</th><th>Support Number</th></tr></thead><tbody><tr><td><code class="function">opcInfo</code></td><td>
+ return internal information describing the indexed columns'
+ summary data
+ </td><td>1</td></tr><tr><td><code class="function">add_value</code></td><td>add a new value to an existing summary index tuple</td><td>2</td></tr><tr><td><code class="function">consistent</code></td><td>determine whether value matches query condition</td><td>3</td></tr><tr><td><code class="function">union</code></td><td>
+ compute union of two summary tuples
+ </td><td>4</td></tr><tr><td><code class="function">options</code></td><td>
+ define options that are specific to this operator class
+ (optional)
+ </td><td>5</td></tr></tbody></table></div></div><br class="table-break" /><p>
+ Unlike search operators, support functions return whichever data
+ type the particular index method expects; for example in the case
+ of the comparison function for B-trees, a signed integer. The number
+ and types of the arguments to each support function are likewise
+ dependent on the index method. For B-tree and hash the comparison and
+ hashing support functions take the same input data types as do the
+ operators included in the operator class, but this is not the case for
+ most GiST, SP-GiST, GIN, and BRIN support functions.
+ </p></div><div class="sect2" id="XINDEX-EXAMPLE"><div class="titlepage"><div><div><h3 class="title">38.16.4. An Example</h3></div></div></div><p>
+ Now that we have seen the ideas, here is the promised example of
+ creating a new operator class.
+ (You can find a working copy of this example in
+ <code class="filename">src/tutorial/complex.c</code> and
+ <code class="filename">src/tutorial/complex.sql</code> in the source
+ distribution.)
+ The operator class encapsulates
+ operators that sort complex numbers in absolute value order, so we
+ choose the name <code class="literal">complex_abs_ops</code>. First, we need
+ a set of operators. The procedure for defining operators was
+ discussed in <a class="xref" href="xoper.html" title="38.14. User-Defined Operators">Section 38.14</a>. For an operator class on
+ B-trees, the operators we require are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; "><li class="listitem">absolute-value less-than (strategy 1)</li><li class="listitem">absolute-value less-than-or-equal (strategy 2)</li><li class="listitem">absolute-value equal (strategy 3)</li><li class="listitem">absolute-value greater-than-or-equal (strategy 4)</li><li class="listitem">absolute-value greater-than (strategy 5)</li></ul></div><p>
+ </p><p>
+ The least error-prone way to define a related set of comparison operators
+ is to write the B-tree comparison support function first, and then write the
+ other functions as one-line wrappers around the support function. This
+ reduces the odds of getting inconsistent results for corner cases.
+ Following this approach, we first write:
+
+</p><pre class="programlisting">
+#define Mag(c) ((c)-&gt;x*(c)-&gt;x + (c)-&gt;y*(c)-&gt;y)
+
+static int
+complex_abs_cmp_internal(Complex *a, Complex *b)
+{
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ if (amag &lt; bmag)
+ return -1;
+ if (amag &gt; bmag)
+ return 1;
+ return 0;
+}
+
+</pre><p>
+
+ Now the less-than function looks like:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(complex_abs_lt);
+
+Datum
+complex_abs_lt(PG_FUNCTION_ARGS)
+{
+ Complex *a = (Complex *) PG_GETARG_POINTER(0);
+ Complex *b = (Complex *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) &lt; 0);
+}
+
+</pre><p>
+
+ The other four functions differ only in how they compare the internal
+ function's result to zero.
+ </p><p>
+ Next we declare the functions and the operators based on the functions
+ to SQL:
+
+</p><pre class="programlisting">
+CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool
+ AS '<em class="replaceable"><code>filename</code></em>', 'complex_abs_lt'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR &lt; (
+ leftarg = complex, rightarg = complex, procedure = complex_abs_lt,
+ commutator = &gt; , negator = &gt;= ,
+ restrict = scalarltsel, join = scalarltjoinsel
+);
+</pre><p>
+ It is important to specify the correct commutator and negator operators,
+ as well as suitable restriction and join selectivity
+ functions, otherwise the optimizer will be unable to make effective
+ use of the index.
+ </p><p>
+ Other things worth noting are happening here:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ There can only be one operator named, say, <code class="literal">=</code>
+ and taking type <code class="type">complex</code> for both operands. In this
+ case we don't have any other operator <code class="literal">=</code> for
+ <code class="type">complex</code>, but if we were building a practical data
+ type we'd probably want <code class="literal">=</code> to be the ordinary
+ equality operation for complex numbers (and not the equality of
+ the absolute values). In that case, we'd need to use some other
+ operator name for <code class="function">complex_abs_eq</code>.
+ </p></li><li class="listitem"><p>
+ Although <span class="productname">PostgreSQL</span> can cope with
+ functions having the same SQL name as long as they have different
+ argument data types, C can only cope with one global function
+ having a given name. So we shouldn't name the C function
+ something simple like <code class="filename">abs_eq</code>. Usually it's
+ a good practice to include the data type name in the C function
+ name, so as not to conflict with functions for other data types.
+ </p></li><li class="listitem"><p>
+ We could have made the SQL name
+ of the function <code class="filename">abs_eq</code>, relying on
+ <span class="productname">PostgreSQL</span> to distinguish it by
+ argument data types from any other SQL function of the same name.
+ To keep the example simple, we make the function have the same
+ names at the C level and SQL level.
+ </p></li></ul></div><p>
+ </p><p>
+ The next step is the registration of the support routine required
+ by B-trees. The example C code that implements this is in the same
+ file that contains the operator functions. This is how we declare
+ the function:
+
+</p><pre class="programlisting">
+CREATE FUNCTION complex_abs_cmp(complex, complex)
+ RETURNS integer
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C IMMUTABLE STRICT;
+</pre><p>
+ </p><p>
+ Now that we have the required operators and support routine,
+ we can finally create the operator class:
+
+</p><pre class="programlisting">
+CREATE OPERATOR CLASS complex_abs_ops
+ DEFAULT FOR TYPE complex USING btree AS
+ OPERATOR 1 &lt; ,
+ OPERATOR 2 &lt;= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 &gt;= ,
+ OPERATOR 5 &gt; ,
+ FUNCTION 1 complex_abs_cmp(complex, complex);
+
+</pre><p>
+ </p><p>
+ And we're done! It should now be possible to create
+ and use B-tree indexes on <code class="type">complex</code> columns.
+ </p><p>
+ We could have written the operator entries more verbosely, as in:
+</p><pre class="programlisting">
+ OPERATOR 1 &lt; (complex, complex) ,
+</pre><p>
+ but there is no need to do so when the operators take the same data type
+ we are defining the operator class for.
+ </p><p>
+ The above example assumes that you want to make this new operator class the
+ default B-tree operator class for the <code class="type">complex</code> data type.
+ If you don't, just leave out the word <code class="literal">DEFAULT</code>.
+ </p></div><div class="sect2" id="XINDEX-OPFAMILY"><div class="titlepage"><div><div><h3 class="title">38.16.5. Operator Classes and Operator Families</h3></div></div></div><p>
+ So far we have implicitly assumed that an operator class deals with
+ only one data type. While there certainly can be only one data type in
+ a particular index column, it is often useful to index operations that
+ compare an indexed column to a value of a different data type. Also,
+ if there is use for a cross-data-type operator in connection with an
+ operator class, it is often the case that the other data type has a
+ related operator class of its own. It is helpful to make the connections
+ between related classes explicit, because this can aid the planner in
+ optimizing SQL queries (particularly for B-tree operator classes, since
+ the planner contains a great deal of knowledge about how to work with them).
+ </p><p>
+ To handle these needs, <span class="productname">PostgreSQL</span>
+ uses the concept of an <em class="firstterm">operator
+ family</em><a id="id-1.8.3.19.9.3.3" class="indexterm"></a>.
+ An operator family contains one or more operator classes, and can also
+ contain indexable operators and corresponding support functions that
+ belong to the family as a whole but not to any single class within the
+ family. We say that such operators and functions are <span class="quote">“<span class="quote">loose</span>”</span>
+ within the family, as opposed to being bound into a specific class.
+ Typically each operator class contains single-data-type operators
+ while cross-data-type operators are loose in the family.
+ </p><p>
+ All the operators and functions in an operator family must have compatible
+ semantics, where the compatibility requirements are set by the index
+ method. You might therefore wonder why bother to single out particular
+ subsets of the family as operator classes; and indeed for many purposes
+ the class divisions are irrelevant and the family is the only interesting
+ grouping. The reason for defining operator classes is that they specify
+ how much of the family is needed to support any particular index.
+ If there is an index using an operator class, then that operator class
+ cannot be dropped without dropping the index — but other parts of
+ the operator family, namely other operator classes and loose operators,
+ could be dropped. Thus, an operator class should be specified to contain
+ the minimum set of operators and functions that are reasonably needed
+ to work with an index on a specific data type, and then related but
+ non-essential operators can be added as loose members of the operator
+ family.
+ </p><p>
+ As an example, <span class="productname">PostgreSQL</span> has a built-in
+ B-tree operator family <code class="literal">integer_ops</code>, which includes operator
+ classes <code class="literal">int8_ops</code>, <code class="literal">int4_ops</code>, and
+ <code class="literal">int2_ops</code> for indexes on <code class="type">bigint</code> (<code class="type">int8</code>),
+ <code class="type">integer</code> (<code class="type">int4</code>), and <code class="type">smallint</code> (<code class="type">int2</code>)
+ columns respectively. The family also contains cross-data-type comparison
+ operators allowing any two of these types to be compared, so that an index
+ on one of these types can be searched using a comparison value of another
+ type. The family could be duplicated by these definitions:
+
+</p><pre class="programlisting">
+CREATE OPERATOR FAMILY integer_ops USING btree;
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS
+ -- standard int8 comparisons
+ OPERATOR 1 &lt; ,
+ OPERATOR 2 &lt;= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 &gt;= ,
+ OPERATOR 5 &gt; ,
+ FUNCTION 1 btint8cmp(int8, int8) ,
+ FUNCTION 2 btint8sortsupport(internal) ,
+ FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) ,
+ FUNCTION 4 btequalimage(oid) ;
+
+CREATE OPERATOR CLASS int4_ops
+DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS
+ -- standard int4 comparisons
+ OPERATOR 1 &lt; ,
+ OPERATOR 2 &lt;= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 &gt;= ,
+ OPERATOR 5 &gt; ,
+ FUNCTION 1 btint4cmp(int4, int4) ,
+ FUNCTION 2 btint4sortsupport(internal) ,
+ FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) ,
+ FUNCTION 4 btequalimage(oid) ;
+
+CREATE OPERATOR CLASS int2_ops
+DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS
+ -- standard int2 comparisons
+ OPERATOR 1 &lt; ,
+ OPERATOR 2 &lt;= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 &gt;= ,
+ OPERATOR 5 &gt; ,
+ FUNCTION 1 btint2cmp(int2, int2) ,
+ FUNCTION 2 btint2sortsupport(internal) ,
+ FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) ,
+ FUNCTION 4 btequalimage(oid) ;
+
+ALTER OPERATOR FAMILY integer_ops USING btree ADD
+ -- cross-type comparisons int8 vs int2
+ OPERATOR 1 &lt; (int8, int2) ,
+ OPERATOR 2 &lt;= (int8, int2) ,
+ OPERATOR 3 = (int8, int2) ,
+ OPERATOR 4 &gt;= (int8, int2) ,
+ OPERATOR 5 &gt; (int8, int2) ,
+ FUNCTION 1 btint82cmp(int8, int2) ,
+
+ -- cross-type comparisons int8 vs int4
+ OPERATOR 1 &lt; (int8, int4) ,
+ OPERATOR 2 &lt;= (int8, int4) ,
+ OPERATOR 3 = (int8, int4) ,
+ OPERATOR 4 &gt;= (int8, int4) ,
+ OPERATOR 5 &gt; (int8, int4) ,
+ FUNCTION 1 btint84cmp(int8, int4) ,
+
+ -- cross-type comparisons int4 vs int2
+ OPERATOR 1 &lt; (int4, int2) ,
+ OPERATOR 2 &lt;= (int4, int2) ,
+ OPERATOR 3 = (int4, int2) ,
+ OPERATOR 4 &gt;= (int4, int2) ,
+ OPERATOR 5 &gt; (int4, int2) ,
+ FUNCTION 1 btint42cmp(int4, int2) ,
+
+ -- cross-type comparisons int4 vs int8
+ OPERATOR 1 &lt; (int4, int8) ,
+ OPERATOR 2 &lt;= (int4, int8) ,
+ OPERATOR 3 = (int4, int8) ,
+ OPERATOR 4 &gt;= (int4, int8) ,
+ OPERATOR 5 &gt; (int4, int8) ,
+ FUNCTION 1 btint48cmp(int4, int8) ,
+
+ -- cross-type comparisons int2 vs int8
+ OPERATOR 1 &lt; (int2, int8) ,
+ OPERATOR 2 &lt;= (int2, int8) ,
+ OPERATOR 3 = (int2, int8) ,
+ OPERATOR 4 &gt;= (int2, int8) ,
+ OPERATOR 5 &gt; (int2, int8) ,
+ FUNCTION 1 btint28cmp(int2, int8) ,
+
+ -- cross-type comparisons int2 vs int4
+ OPERATOR 1 &lt; (int2, int4) ,
+ OPERATOR 2 &lt;= (int2, int4) ,
+ OPERATOR 3 = (int2, int4) ,
+ OPERATOR 4 &gt;= (int2, int4) ,
+ OPERATOR 5 &gt; (int2, int4) ,
+ FUNCTION 1 btint24cmp(int2, int4) ,
+
+ -- cross-type in_range functions
+ FUNCTION 3 in_range(int4, int4, int8, boolean, boolean) ,
+ FUNCTION 3 in_range(int4, int4, int2, boolean, boolean) ,
+ FUNCTION 3 in_range(int2, int2, int8, boolean, boolean) ,
+ FUNCTION 3 in_range(int2, int2, int4, boolean, boolean) ;
+
+</pre><p>
+
+ Notice that this definition <span class="quote">“<span class="quote">overloads</span>”</span> the operator strategy and
+ support function numbers: each number occurs multiple times within the
+ family. This is allowed so long as each instance of a
+ particular number has distinct input data types. The instances that have
+ both input types equal to an operator class's input type are the
+ primary operators and support functions for that operator class,
+ and in most cases should be declared as part of the operator class rather
+ than as loose members of the family.
+ </p><p>
+ In a B-tree operator family, all the operators in the family must sort
+ compatibly, as is specified in detail in <a class="xref" href="btree-behavior.html" title="67.2. Behavior of B-Tree Operator Classes">Section 67.2</a>.
+ For each
+ operator in the family there must be a support function having the same
+ two input data types as the operator. It is recommended that a family be
+ complete, i.e., for each combination of data types, all operators are
+ included. Each operator class should include just the non-cross-type
+ operators and support function for its data type.
+ </p><p>
+ To build a multiple-data-type hash operator family, compatible hash
+ support functions must be created for each data type supported by the
+ family. Here compatibility means that the functions are guaranteed to
+ return the same hash code for any two values that are considered equal
+ by the family's equality operators, even when the values are of different
+ types. This is usually difficult to accomplish when the types have
+ different physical representations, but it can be done in some cases.
+ Furthermore, casting a value from one data type represented in the operator
+ family to another data type also represented in the operator family via
+ an implicit or binary coercion cast must not change the computed hash value.
+ Notice that there is only one support function per data type, not one
+ per equality operator. It is recommended that a family be complete, i.e.,
+ provide an equality operator for each combination of data types.
+ Each operator class should include just the non-cross-type equality
+ operator and the support function for its data type.
+ </p><p>
+ GiST, SP-GiST, and GIN indexes do not have any explicit notion of
+ cross-data-type operations. The set of operators supported is just
+ whatever the primary support functions for a given operator class can
+ handle.
+ </p><p>
+ In BRIN, the requirements depends on the framework that provides the
+ operator classes. For operator classes based on <code class="literal">minmax</code>,
+ the behavior required is the same as for B-tree operator families:
+ all the operators in the family must sort compatibly, and casts must
+ not change the associated sort ordering.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Prior to <span class="productname">PostgreSQL</span> 8.3, there was no concept
+ of operator families, and so any cross-data-type operators intended to be
+ used with an index had to be bound directly into the index's operator
+ class. While this approach still works, it is deprecated because it
+ makes an index's dependencies too broad, and because the planner can
+ handle cross-data-type comparisons more effectively when both data types
+ have operators in the same operator family.
+ </p></div></div><div class="sect2" id="XINDEX-OPCLASS-DEPENDENCIES"><div class="titlepage"><div><div><h3 class="title">38.16.6. System Dependencies on Operator Classes</h3></div></div></div><a id="id-1.8.3.19.10.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> uses operator classes to infer the
+ properties of operators in more ways than just whether they can be used
+ with indexes. Therefore, you might want to create operator classes
+ even if you have no intention of indexing any columns of your data type.
+ </p><p>
+ In particular, there are SQL features such as <code class="literal">ORDER BY</code> and
+ <code class="literal">DISTINCT</code> that require comparison and sorting of values.
+ To implement these features on a user-defined data type,
+ <span class="productname">PostgreSQL</span> looks for the default B-tree operator
+ class for the data type. The <span class="quote">“<span class="quote">equals</span>”</span> member of this operator
+ class defines the system's notion of equality of values for
+ <code class="literal">GROUP BY</code> and <code class="literal">DISTINCT</code>, and the sort ordering
+ imposed by the operator class defines the default <code class="literal">ORDER BY</code>
+ ordering.
+ </p><p>
+ If there is no default B-tree operator class for a data type, the system
+ will look for a default hash operator class. But since that kind of
+ operator class only provides equality, it is only able to support grouping
+ not sorting.
+ </p><p>
+ When there is no default operator class for a data type, you will get
+ errors like <span class="quote">“<span class="quote">could not identify an ordering operator</span>”</span> if you
+ try to use these SQL features with the data type.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ In <span class="productname">PostgreSQL</span> versions before 7.4,
+ sorting and grouping operations would implicitly use operators named
+ <code class="literal">=</code>, <code class="literal">&lt;</code>, and <code class="literal">&gt;</code>. The new
+ behavior of relying on default operator classes avoids having to make
+ any assumption about the behavior of operators with particular names.
+ </p></div><p>
+ Sorting by a non-default B-tree operator class is possible by specifying
+ the class's less-than operator in a <code class="literal">USING</code> option,
+ for example
+</p><pre class="programlisting">
+SELECT * FROM mytable ORDER BY somecol USING ~&lt;~;
+</pre><p>
+ Alternatively, specifying the class's greater-than operator
+ in <code class="literal">USING</code> selects a descending-order sort.
+ </p><p>
+ Comparison of arrays of a user-defined type also relies on the semantics
+ defined by the type's default B-tree operator class. If there is no
+ default B-tree operator class, but there is a default hash operator class,
+ then array equality is supported, but not ordering comparisons.
+ </p><p>
+ Another SQL feature that requires even more data-type-specific knowledge
+ is the <code class="literal">RANGE</code> <em class="replaceable"><code>offset</code></em>
+ <code class="literal">PRECEDING</code>/<code class="literal">FOLLOWING</code> framing option
+ for window functions (see <a class="xref" href="sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS" title="4.2.8. Window Function Calls">Section 4.2.8</a>).
+ For a query such as
+</p><pre class="programlisting">
+SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING)
+ FROM mytable;
+</pre><p>
+ it is not sufficient to know how to order by <code class="literal">x</code>;
+ the database must also understand how to <span class="quote">“<span class="quote">subtract 5</span>”</span> or
+ <span class="quote">“<span class="quote">add 10</span>”</span> to the current row's value of <code class="literal">x</code>
+ to identify the bounds of the current window frame. Comparing the
+ resulting bounds to other rows' values of <code class="literal">x</code> is
+ possible using the comparison operators provided by the B-tree operator
+ class that defines the <code class="literal">ORDER BY</code> ordering — but
+ addition and subtraction operators are not part of the operator class, so
+ which ones should be used? Hard-wiring that choice would be undesirable,
+ because different sort orders (different B-tree operator classes) might
+ need different behavior. Therefore, a B-tree operator class can specify
+ an <em class="firstterm">in_range</em> support function that encapsulates the
+ addition and subtraction behaviors that make sense for its sort order.
+ It can even provide more than one in_range support function, in case
+ there is more than one data type that makes sense to use as the offset
+ in <code class="literal">RANGE</code> clauses.
+ If the B-tree operator class associated with the window's <code class="literal">ORDER
+ BY</code> clause does not have a matching in_range support function,
+ the <code class="literal">RANGE</code> <em class="replaceable"><code>offset</code></em>
+ <code class="literal">PRECEDING</code>/<code class="literal">FOLLOWING</code>
+ option is not supported.
+ </p><p>
+ Another important point is that an equality operator that
+ appears in a hash operator family is a candidate for hash joins,
+ hash aggregation, and related optimizations. The hash operator family
+ is essential here since it identifies the hash function(s) to use.
+ </p></div><div class="sect2" id="XINDEX-ORDERING-OPS"><div class="titlepage"><div><div><h3 class="title">38.16.7. Ordering Operators</h3></div></div></div><p>
+ Some index access methods (currently, only GiST and SP-GiST) support the concept of
+ <em class="firstterm">ordering operators</em>. What we have been discussing so far
+ are <em class="firstterm">search operators</em>. A search operator is one for which
+ the index can be searched to find all rows satisfying
+ <code class="literal">WHERE</code>
+ <em class="replaceable"><code>indexed_column</code></em>
+ <em class="replaceable"><code>operator</code></em>
+ <em class="replaceable"><code>constant</code></em>.
+ Note that nothing is promised about the order in which the matching rows
+ will be returned. In contrast, an ordering operator does not restrict the
+ set of rows that can be returned, but instead determines their order.
+ An ordering operator is one for which the index can be scanned to return
+ rows in the order represented by
+ <code class="literal">ORDER BY</code>
+ <em class="replaceable"><code>indexed_column</code></em>
+ <em class="replaceable"><code>operator</code></em>
+ <em class="replaceable"><code>constant</code></em>.
+ The reason for defining ordering operators that way is that it supports
+ nearest-neighbor searches, if the operator is one that measures distance.
+ For example, a query like
+</p><pre class="programlisting">
+SELECT * FROM places ORDER BY location &lt;-&gt; point '(101,456)' LIMIT 10;
+
+</pre><p>
+ finds the ten places closest to a given target point. A GiST index
+ on the location column can do this efficiently because
+ <code class="literal">&lt;-&gt;</code> is an ordering operator.
+ </p><p>
+ While search operators have to return Boolean results, ordering operators
+ usually return some other type, such as float or numeric for distances.
+ This type is normally not the same as the data type being indexed.
+ To avoid hard-wiring assumptions about the behavior of different data
+ types, the definition of an ordering operator is required to name
+ a B-tree operator family that specifies the sort ordering of the result
+ data type. As was stated in the previous section, B-tree operator families
+ define <span class="productname">PostgreSQL</span>'s notion of ordering, so
+ this is a natural representation. Since the point <code class="literal">&lt;-&gt;</code>
+ operator returns <code class="type">float8</code>, it could be specified in an operator
+ class creation command like this:
+</p><pre class="programlisting">
+OPERATOR 15 &lt;-&gt; (point, point) FOR ORDER BY float_ops
+
+</pre><p>
+ where <code class="literal">float_ops</code> is the built-in operator family that includes
+ operations on <code class="type">float8</code>. This declaration states that the index
+ is able to return rows in order of increasing values of the
+ <code class="literal">&lt;-&gt;</code> operator.
+ </p></div><div class="sect2" id="XINDEX-OPCLASS-FEATURES"><div class="titlepage"><div><div><h3 class="title">38.16.8. Special Features of Operator Classes</h3></div></div></div><p>
+ There are two special features of operator classes that we have
+ not discussed yet, mainly because they are not useful
+ with the most commonly used index methods.
+ </p><p>
+ Normally, declaring an operator as a member of an operator class
+ (or family) means that the index method can retrieve exactly the set of rows
+ that satisfy a <code class="literal">WHERE</code> condition using the operator. For example:
+</p><pre class="programlisting">
+SELECT * FROM table WHERE integer_column &lt; 4;
+</pre><p>
+ can be satisfied exactly by a B-tree index on the integer column.
+ But there are cases where an index is useful as an inexact guide to
+ the matching rows. For example, if a GiST index stores only bounding boxes
+ for geometric objects, then it cannot exactly satisfy a <code class="literal">WHERE</code>
+ condition that tests overlap between nonrectangular objects such as
+ polygons. Yet we could use the index to find objects whose bounding
+ box overlaps the bounding box of the target object, and then do the
+ exact overlap test only on the objects found by the index. If this
+ scenario applies, the index is said to be <span class="quote">“<span class="quote">lossy</span>”</span> for the
+ operator. Lossy index searches are implemented by having the index
+ method return a <em class="firstterm">recheck</em> flag when a row might or might
+ not really satisfy the query condition. The core system will then
+ test the original query condition on the retrieved row to see whether
+ it should be returned as a valid match. This approach works if
+ the index is guaranteed to return all the required rows, plus perhaps
+ some additional rows, which can be eliminated by performing the original
+ operator invocation. The index methods that support lossy searches
+ (currently, GiST, SP-GiST and GIN) allow the support functions of individual
+ operator classes to set the recheck flag, and so this is essentially an
+ operator-class feature.
+ </p><p>
+ Consider again the situation where we are storing in the index only
+ the bounding box of a complex object such as a polygon. In this
+ case there's not much value in storing the whole polygon in the index
+ entry — we might as well store just a simpler object of type
+ <code class="type">box</code>. This situation is expressed by the <code class="literal">STORAGE</code>
+ option in <code class="command">CREATE OPERATOR CLASS</code>: we'd write something like:
+
+</p><pre class="programlisting">
+CREATE OPERATOR CLASS polygon_ops
+ DEFAULT FOR TYPE polygon USING gist AS
+ ...
+ STORAGE box;
+</pre><p>
+
+ At present, only the GiST, SP-GiST, GIN and BRIN index methods support a
+ <code class="literal">STORAGE</code> type that's different from the column data type.
+ The GiST <code class="function">compress</code> and <code class="function">decompress</code> support
+ routines must deal with data-type conversion when <code class="literal">STORAGE</code>
+ is used. SP-GiST likewise requires a <code class="function">compress</code>
+ support function to convert to the storage type, when that is different;
+ if an SP-GiST opclass also supports retrieving data, the reverse
+ conversion must be handled by the <code class="function">consistent</code> function.
+ In GIN, the <code class="literal">STORAGE</code> type identifies the type of
+ the <span class="quote">“<span class="quote">key</span>”</span> values, which normally is different from the type
+ of the indexed column — for example, an operator class for
+ integer-array columns might have keys that are just integers. The
+ GIN <code class="function">extractValue</code> and <code class="function">extractQuery</code> support
+ routines are responsible for extracting keys from indexed values.
+ BRIN is similar to GIN: the <code class="literal">STORAGE</code> type identifies the
+ type of the stored summary values, and operator classes' support
+ procedures are responsible for interpreting the summary values
+ correctly.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xoper-optimization.html" title="38.15. Operator Optimization Information">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="extend-extensions.html" title="38.17. Packaging Related Objects into an Extension">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.15. Operator Optimization Information </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.17. Packaging Related Objects into an Extension</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xml-limits-conformance.html b/doc/src/sgml/html/xml-limits-conformance.html
new file mode 100644
index 0000000..a2a8ba7
--- /dev/null
+++ b/doc/src/sgml/html/xml-limits-conformance.html
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>D.3. XML Limits and Conformance to SQL/XML</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="unsupported-features-sql-standard.html" title="D.2. Unsupported Features" /><link rel="next" href="release.html" title="Appendix E. Release Notes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">D.3. XML Limits and Conformance to SQL/XML</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="unsupported-features-sql-standard.html" title="D.2. Unsupported Features">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="features.html" title="Appendix D. SQL Conformance">Up</a></td><th width="60%" align="center">Appendix D. SQL Conformance</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="release.html" title="Appendix E. Release Notes">Next</a></td></tr></table><hr /></div><div class="sect1" id="XML-LIMITS-CONFORMANCE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">D.3. XML Limits and Conformance to SQL/XML</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-XPATH1">D.3.1. Queries Are Restricted to XPath 1.0</a></span></dt><dt><span class="sect2"><a href="xml-limits-conformance.html#FUNCTIONS-XML-LIMITS-POSTGRESQL">D.3.2. Incidental Limits of the Implementation</a></span></dt></dl></div><a id="id-1.11.5.13.2" class="indexterm"></a><p>
+ Significant revisions to the XML-related specifications in ISO/IEC 9075-14
+ (SQL/XML) were introduced with SQL:2006.
+ <span class="productname">PostgreSQL</span>'s implementation of the XML data
+ type and related functions largely follows the earlier 2003 edition,
+ with some borrowing from later editions. In particular:
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Where the current standard provides a family of XML data types
+ to hold <span class="quote">“<span class="quote">document</span>”</span> or <span class="quote">“<span class="quote">content</span>”</span> in
+ untyped or XML Schema-typed variants, and a type
+ <code class="type">XML(SEQUENCE)</code> to hold arbitrary pieces of XML content,
+ <span class="productname">PostgreSQL</span> provides the single
+ <code class="type">xml</code> type, which can hold <span class="quote">“<span class="quote">document</span>”</span> or
+ <span class="quote">“<span class="quote">content</span>”</span>. There is no equivalent of the
+ standard's <span class="quote">“<span class="quote">sequence</span>”</span> type.
+ </p></li><li class="listitem"><p>
+ <span class="productname">PostgreSQL</span> provides two functions
+ introduced in SQL:2006, but in variants that use the XPath 1.0
+ language, rather than XML Query as specified for them in the
+ standard.
+ </p></li></ul></div><p>
+ </p><p>
+ This section presents some of the resulting differences you may encounter.
+ </p><div class="sect2" id="FUNCTIONS-XML-LIMITS-XPATH1"><div class="titlepage"><div><div><h3 class="title">D.3.1. Queries Are Restricted to XPath 1.0</h3></div></div></div><p>
+ The <span class="productname">PostgreSQL</span>-specific functions
+ <code class="function">xpath()</code> and <code class="function">xpath_exists()</code>
+ query XML documents using the XPath language.
+ <span class="productname">PostgreSQL</span> also provides XPath-only variants
+ of the standard functions <code class="function">XMLEXISTS</code> and
+ <code class="function">XMLTABLE</code>, which officially use
+ the XQuery language. For all of these functions,
+ <span class="productname">PostgreSQL</span> relies on the
+ <span class="application">libxml2</span> library, which provides only XPath 1.0.
+ </p><p>
+ There is a strong connection between the XQuery language and XPath
+ versions 2.0 and later: any expression that is syntactically valid and
+ executes successfully in both produces the same result (with a minor
+ exception for expressions containing numeric character references or
+ predefined entity references, which XQuery replaces with the
+ corresponding character while XPath leaves them alone). But there is
+ no such connection between these languages and XPath 1.0; it was an
+ earlier language and differs in many respects.
+ </p><p>
+ There are two categories of limitation to keep in mind: the restriction
+ from XQuery to XPath for the functions specified in the SQL standard, and
+ the restriction of XPath to version 1.0 for both the standard and the
+ <span class="productname">PostgreSQL</span>-specific functions.
+ </p><div class="sect3" id="id-1.11.5.13.5.5"><div class="titlepage"><div><div><h4 class="title">D.3.1.1. Restriction of XQuery to XPath</h4></div></div></div><p>
+ Features of XQuery beyond those of XPath include:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ XQuery expressions can construct and return new XML nodes, in
+ addition to all possible XPath values. XPath can create and return
+ values of the atomic types (numbers, strings, and so on) but can
+ only return XML nodes that were already present in documents
+ supplied as input to the expression.
+ </p></li><li class="listitem"><p>
+ XQuery has control constructs for iteration, sorting, and grouping.
+ </p></li><li class="listitem"><p>
+ XQuery allows declaration and use of local functions.
+ </p></li></ul></div><p>
+ </p><p>
+ Recent XPath versions begin to offer capabilities overlapping with
+ these (such as functional-style <code class="function">for-each</code> and
+ <code class="function">sort</code>, anonymous functions, and
+ <code class="function">parse-xml</code> to create a node from a string),
+ but such features were not available before XPath 3.0.
+ </p></div><div class="sect3" id="XML-XPATH-1-SPECIFICS"><div class="titlepage"><div><div><h4 class="title">D.3.1.2. Restriction of XPath to 1.0</h4></div></div></div><p>
+ For developers familiar with XQuery and XPath 2.0 or later, XPath 1.0
+ presents a number of differences to contend with:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ The fundamental type of an XQuery/XPath expression, the
+ <code class="type">sequence</code>, which can contain XML nodes, atomic values,
+ or both, does not exist in XPath 1.0. A 1.0 expression can only
+ produce a node-set (containing zero or more XML nodes), or a single
+ atomic value.
+ </p></li><li class="listitem"><p>
+ Unlike an XQuery/XPath sequence, which can contain any desired
+ items in any desired order, an XPath 1.0 node-set has no
+ guaranteed order and, like any set, does not allow multiple
+ appearances of the same item.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The <span class="application">libxml2</span> library does seem to
+ always return node-sets to <span class="productname">PostgreSQL</span>
+ with their members in the same relative order they had in the
+ input document. Its documentation does not commit to this
+ behavior, and an XPath 1.0 expression cannot control it.
+ </p></div><p>
+ </p></li><li class="listitem"><p>
+ While XQuery/XPath provides all of the types defined in XML Schema
+ and many operators and functions over those types, XPath 1.0 has only
+ node-sets and the three atomic types <code class="type">boolean</code>,
+ <code class="type">double</code>, and <code class="type">string</code>.
+ </p></li><li class="listitem"><p>
+ XPath 1.0 has no conditional operator. An XQuery/XPath expression
+ such as <code class="literal">if ( hat ) then hat/@size else "no hat"</code>
+ has no XPath 1.0 equivalent.
+ </p></li><li class="listitem"><p>
+ XPath 1.0 has no ordering comparison operator for strings. Both
+ <code class="literal">"cat" &lt; "dog"</code> and
+ <code class="literal">"cat" &gt; "dog"</code> are false, because each is a
+ numeric comparison of two <code class="literal">NaN</code>s. In contrast,
+ <code class="literal">=</code> and <code class="literal">!=</code> do compare the strings
+ as strings.
+ </p></li><li class="listitem"><p>
+ XPath 1.0 blurs the distinction between
+ <em class="firstterm">value comparisons</em> and
+ <em class="firstterm">general comparisons</em> as XQuery/XPath define
+ them. Both <code class="literal">sale/@hatsize = 7</code> and
+ <code class="literal">sale/@customer = "alice"</code> are existentially
+ quantified comparisons, true if there is
+ any <code class="literal">sale</code> with the given value for the
+ attribute, but <code class="literal">sale/@taxable = false()</code> is a
+ value comparison to the
+ <em class="firstterm">effective boolean value</em> of a whole node-set.
+ It is true only if no <code class="literal">sale</code> has
+ a <code class="literal">taxable</code> attribute at all.
+ </p></li><li class="listitem"><p>
+ In the XQuery/XPath data model, a <em class="firstterm">document
+ node</em> can have either document form (i.e., exactly one
+ top-level element, with only comments and processing instructions
+ outside of it) or content form (with those constraints
+ relaxed). Its equivalent in XPath 1.0, the
+ <em class="firstterm">root node</em>, can only be in document form.
+ This is part of the reason an <code class="type">xml</code> value passed as the
+ context item to any <span class="productname">PostgreSQL</span>
+ XPath-based function must be in document form.
+ </p></li></ul></div><p>
+ </p><p>
+ The differences highlighted here are not all of them. In XQuery and
+ the 2.0 and later versions of XPath, there is an XPath 1.0 compatibility
+ mode, and the W3C lists of
+ <a class="ulink" href="https://www.w3.org/TR/2010/REC-xpath-functions-20101214/#xpath1-compatibility" target="_top">function library changes</a>
+ and
+ <a class="ulink" href="https://www.w3.org/TR/xpath20/#id-backwards-compatibility" target="_top">language changes</a>
+ applied in that mode offer a more complete (but still not exhaustive)
+ account of the differences. The compatibility mode cannot make the
+ later languages exactly equivalent to XPath 1.0.
+ </p></div><div class="sect3" id="FUNCTIONS-XML-LIMITS-CASTS"><div class="titlepage"><div><div><h4 class="title">D.3.1.3. Mappings between SQL and XML Data Types and Values</h4></div></div></div><p>
+ In SQL:2006 and later, both directions of conversion between standard SQL
+ data types and the XML Schema types are specified precisely. However, the
+ rules are expressed using the types and semantics of XQuery/XPath, and
+ have no direct application to the different data model of XPath 1.0.
+ </p><p>
+ When <span class="productname">PostgreSQL</span> maps SQL data values to XML
+ (as in <code class="function">xmlelement</code>), or XML to SQL (as in the output
+ columns of <code class="function">xmltable</code>), except for a few cases
+ treated specially, <span class="productname">PostgreSQL</span> simply assumes
+ that the XML data type's XPath 1.0 string form will be valid as the
+ text-input form of the SQL datatype, and conversely. This rule has the
+ virtue of simplicity while producing, for many data types, results similar
+ to the mappings specified in the standard.
+ </p><p>
+ Where interoperability with other systems is a concern, for some data
+ types, it may be necessary to use data type formatting functions (such
+ as those in <a class="xref" href="functions-formatting.html" title="9.8. Data Type Formatting Functions">Section 9.8</a>) explicitly to
+ produce the standard mappings.
+ </p></div></div><div class="sect2" id="FUNCTIONS-XML-LIMITS-POSTGRESQL"><div class="titlepage"><div><div><h3 class="title">D.3.2. Incidental Limits of the Implementation</h3></div></div></div><p>
+ This section concerns limits that are not inherent in the
+ <span class="application">libxml2</span> library, but apply to the current
+ implementation in <span class="productname">PostgreSQL</span>.
+ </p><div class="sect3" id="id-1.11.5.13.6.3"><div class="titlepage"><div><div><h4 class="title">D.3.2.1. Only <code class="literal">BY VALUE</code> Passing Mechanism Is Supported</h4></div></div></div><p>
+ The SQL standard defines two <em class="firstterm">passing mechanisms</em>
+ that apply when passing an XML argument from SQL to an XML function or
+ receiving a result: <code class="literal">BY REF</code>, in which a particular XML
+ value retains its node identity, and <code class="literal">BY VALUE</code>, in which
+ the content of the XML is passed but node identity is not preserved. A
+ mechanism can be specified before a list of parameters, as the default
+ mechanism for all of them, or after any parameter, to override the
+ default.
+ </p><p>
+ To illustrate the difference, if
+ <em class="replaceable"><code>x</code></em> is an XML value, these two queries in
+ an SQL:2006 environment would produce true and false, respectively:
+
+</p><pre class="programlisting">
+SELECT XMLQUERY('$a is $b' PASSING BY REF <em class="replaceable"><code>x</code></em> AS a, <em class="replaceable"><code>x</code></em> AS b NULL ON EMPTY);
+SELECT XMLQUERY('$a is $b' PASSING BY VALUE <em class="replaceable"><code>x</code></em> AS a, <em class="replaceable"><code>x</code></em> AS b NULL ON EMPTY);
+</pre><p>
+ </p><p>
+ <span class="productname">PostgreSQL</span> will accept
+ <code class="literal">BY VALUE</code> or <code class="literal">BY REF</code> in an
+ <code class="function">XMLEXISTS</code> or <code class="function">XMLTABLE</code>
+ construct, but it ignores them. The <code class="type">xml</code> data type holds
+ a character-string serialized representation, so there is no node
+ identity to preserve, and passing is always effectively <code class="literal">BY
+ VALUE</code>.
+ </p></div><div class="sect3" id="id-1.11.5.13.6.4"><div class="titlepage"><div><div><h4 class="title">D.3.2.2. Cannot Pass Named Parameters to Queries</h4></div></div></div><p>
+ The XPath-based functions support passing one parameter to serve as the
+ XPath expression's context item, but do not support passing additional
+ values to be available to the expression as named parameters.
+ </p></div><div class="sect3" id="id-1.11.5.13.6.5"><div class="titlepage"><div><div><h4 class="title">D.3.2.3. No <code class="type">XML(SEQUENCE)</code> Type</h4></div></div></div><p>
+ The <span class="productname">PostgreSQL</span> <code class="type">xml</code> data type
+ can only hold a value in <code class="literal">DOCUMENT</code>
+ or <code class="literal">CONTENT</code> form. An XQuery/XPath expression
+ context item must be a single XML node or atomic value, but XPath 1.0
+ further restricts it to be only an XML node, and has no node type
+ allowing <code class="literal">CONTENT</code>. The upshot is that a
+ well-formed <code class="literal">DOCUMENT</code> is the only form of XML value
+ that <span class="productname">PostgreSQL</span> can supply as an XPath
+ context item.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="unsupported-features-sql-standard.html" title="D.2. Unsupported Features">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="features.html" title="Appendix D. SQL Conformance">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="release.html" title="Appendix E. Release Notes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">D.2. Unsupported Features </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix E. Release Notes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xml2.html b/doc/src/sgml/html/xml2.html
new file mode 100644
index 0000000..d6ea359
--- /dev/null
+++ b/doc/src/sgml/html/xml2.html
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>F.50. xml2</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="uuid-ossp.html" title="F.49. uuid-ossp" /><link rel="next" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">F.50. xml2</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="uuid-ossp.html" title="F.49. uuid-ossp">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><th width="60%" align="center">Appendix F. Additional Supplied Modules</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Next</a></td></tr></table><hr /></div><div class="sect1" id="XML2"><div class="titlepage"><div><div><h2 class="title" style="clear: both">F.50. xml2</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.4">F.50.1. Deprecation Notice</a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.5">F.50.2. Description of Functions</a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.6">F.50.3. <code class="literal">xpath_table</code></a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.7">F.50.4. XSLT Functions</a></span></dt><dt><span class="sect2"><a href="xml2.html#id-1.11.7.59.8">F.50.5. Author</a></span></dt></dl></div><a id="id-1.11.7.59.2" class="indexterm"></a><p>
+ The <code class="filename">xml2</code> module provides XPath querying and
+ XSLT functionality.
+ </p><div class="sect2" id="id-1.11.7.59.4"><div class="titlepage"><div><div><h3 class="title">F.50.1. Deprecation Notice</h3></div></div></div><p>
+ From <span class="productname">PostgreSQL</span> 8.3 on, there is XML-related
+ functionality based on the SQL/XML standard in the core server.
+ That functionality covers XML syntax checking and XPath queries,
+ which is what this module does, and more, but the API is
+ not at all compatible. It is planned that this module will be
+ removed in a future version of PostgreSQL in favor of the newer standard API, so
+ you are encouraged to try converting your applications. If you
+ find that some of the functionality of this module is not
+ available in an adequate form with the newer API, please explain
+ your issue to <code class="email">&lt;<a class="email" href="mailto:pgsql-hackers@lists.postgresql.org">pgsql-hackers@lists.postgresql.org</a>&gt;</code> so that the deficiency
+ can be addressed.
+ </p></div><div class="sect2" id="id-1.11.7.59.5"><div class="titlepage"><div><div><h3 class="title">F.50.2. Description of Functions</h3></div></div></div><p>
+ <a class="xref" href="xml2.html#XML2-FUNCTIONS-TABLE" title="Table F.34. xml2 Functions">Table F.34</a> shows the functions provided by this module.
+ These functions provide straightforward XML parsing and XPath queries.
+ </p><div class="table" id="XML2-FUNCTIONS-TABLE"><p class="title"><strong>Table F.34. <code class="filename">xml2</code> Functions</strong></p><div class="table-contents"><table class="table" summary="xml2 Functions" border="1"><colgroup><col /></colgroup><thead><tr><th class="func_table_entry"><p class="func_signature">
+ Function
+ </p>
+ <p>
+ Description
+ </p></th></tr></thead><tbody><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xml_valid</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Parses the given document and returns true if the
+ document is well-formed XML. (Note: this is an alias for the standard
+ PostgreSQL function <code class="function">xml_is_well_formed()</code>. The
+ name <code class="function">xml_valid()</code> is technically incorrect since validity
+ and well-formedness have different meanings in XML.)
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_string</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Evaluates the XPath query on the supplied document, and
+ casts the result to <code class="type">text</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_number</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">real</code>
+ </p>
+ <p>
+ Evaluates the XPath query on the supplied document, and
+ casts the result to <code class="type">real</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_bool</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">boolean</code>
+ </p>
+ <p>
+ Evaluates the XPath query on the supplied document, and
+ casts the result to <code class="type">boolean</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_nodeset</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code>, <em class="parameter"><code>toptag</code></em> <code class="type">text</code>, <em class="parameter"><code>itemtag</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Evaluates the query on the document and wraps the result in XML
+ tags. If the result is multivalued, the output will look like:
+</p><pre class="synopsis">
+&lt;toptag&gt;
+&lt;itemtag&gt;Value 1 which could be an XML fragment&lt;/itemtag&gt;
+&lt;itemtag&gt;Value 2....&lt;/itemtag&gt;
+&lt;/toptag&gt;
+</pre><p>
+ If either <em class="parameter"><code>toptag</code></em>
+ or <em class="parameter"><code>itemtag</code></em> is an empty string, the relevant tag
+ is omitted.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_nodeset</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code>, <em class="parameter"><code>itemtag</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Like <code class="function">xpath_nodeset(document, query, toptag, itemtag)</code> but result omits <em class="parameter"><code>toptag</code></em>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_nodeset</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Like <code class="function">xpath_nodeset(document, query, toptag, itemtag)</code> but result omits both tags.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_list</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code>, <em class="parameter"><code>separator</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ Evaluates the query on the document and returns multiple values
+ separated by the specified separator, for example <code class="literal">Value
+ 1,Value 2,Value 3</code> if <em class="parameter"><code>separator</code></em>
+ is <code class="literal">,</code>.
+ </p></td></tr><tr><td class="func_table_entry"><p class="func_signature">
+ <code class="function">xpath_list</code> ( <em class="parameter"><code>document</code></em> <code class="type">text</code>, <em class="parameter"><code>query</code></em> <code class="type">text</code> )
+ → <code class="returnvalue">text</code>
+ </p>
+ <p>
+ This is a wrapper for the above function that uses <code class="literal">,</code>
+ as the separator.
+ </p></td></tr></tbody></table></div></div><br class="table-break" /></div><div class="sect2" id="id-1.11.7.59.6"><div class="titlepage"><div><div><h3 class="title">F.50.3. <code class="literal">xpath_table</code></h3></div></div></div><a id="id-1.11.7.59.6.2" class="indexterm"></a><pre class="synopsis">
+xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
+</pre><p>
+ <code class="function">xpath_table</code> is a table function that evaluates a set of XPath
+ queries on each of a set of documents and returns the results as a
+ table. The primary key field from the original document table is returned
+ as the first column of the result so that the result set
+ can readily be used in joins. The parameters are described in
+ <a class="xref" href="xml2.html#XML2-XPATH-TABLE-PARAMETERS" title="Table F.35. xpath_table Parameters">Table F.35</a>.
+ </p><div class="table" id="XML2-XPATH-TABLE-PARAMETERS"><p class="title"><strong>Table F.35. <code class="function">xpath_table</code> Parameters</strong></p><div class="table-contents"><table class="table" summary="xpath_table Parameters" border="1"><colgroup><col class="col1" /><col class="col2" /></colgroup><thead><tr><th>Parameter</th><th>Description</th></tr></thead><tbody><tr><td><em class="parameter"><code>key</code></em></td><td>
+ <p>
+ the name of the <span class="quote">“<span class="quote">key</span>”</span> field — this is just a field to be used as
+ the first column of the output table, i.e., it identifies the record from
+ which each output row came (see note below about multiple values)
+ </p>
+ </td></tr><tr><td><em class="parameter"><code>document</code></em></td><td>
+ <p>
+ the name of the field containing the XML document
+ </p>
+ </td></tr><tr><td><em class="parameter"><code>relation</code></em></td><td>
+ <p>
+ the name of the table or view containing the documents
+ </p>
+ </td></tr><tr><td><em class="parameter"><code>xpaths</code></em></td><td>
+ <p>
+ one or more XPath expressions, separated by <code class="literal">|</code>
+ </p>
+ </td></tr><tr><td><em class="parameter"><code>criteria</code></em></td><td>
+ <p>
+ the contents of the WHERE clause. This cannot be omitted, so use
+ <code class="literal">true</code> or <code class="literal">1=1</code> if you want to
+ process all the rows in the relation
+ </p>
+ </td></tr></tbody></table></div></div><br class="table-break" /><p>
+ These parameters (except the XPath strings) are just substituted
+ into a plain SQL SELECT statement, so you have some flexibility — the
+ statement is
+ </p><p>
+ <code class="literal">
+ SELECT &lt;key&gt;, &lt;document&gt; FROM &lt;relation&gt; WHERE &lt;criteria&gt;
+ </code>
+ </p><p>
+ so those parameters can be <span class="emphasis"><em>anything</em></span> valid in those particular
+ locations. The result from this SELECT needs to return exactly two
+ columns (which it will unless you try to list multiple fields for key
+ or document). Beware that this simplistic approach requires that you
+ validate any user-supplied values to avoid SQL injection attacks.
+ </p><p>
+ The function has to be used in a <code class="literal">FROM</code> expression, with an
+ <code class="literal">AS</code> clause to specify the output columns; for example
+</p><pre class="programlisting">
+SELECT * FROM
+xpath_table('article_id',
+ 'article_xml',
+ 'articles',
+ '/article/author|/article/pages|/article/title',
+ 'date_entered &gt; ''2003-01-01'' ')
+AS t(article_id integer, author text, page_count integer, title text);
+</pre><p>
+ The <code class="literal">AS</code> clause defines the names and types of the columns in the
+ output table. The first is the <span class="quote">“<span class="quote">key</span>”</span> field and the rest correspond
+ to the XPath queries.
+ If there are more XPath queries than result columns,
+ the extra queries will be ignored. If there are more result columns
+ than XPath queries, the extra columns will be NULL.
+ </p><p>
+ Notice that this example defines the <code class="structname">page_count</code> result
+ column as an integer. The function deals internally with string
+ representations, so when you say you want an integer in the output, it will
+ take the string representation of the XPath result and use PostgreSQL input
+ functions to transform it into an integer (or whatever type the <code class="type">AS</code>
+ clause requests). An error will result if it can't do this — for
+ example if the result is empty — so you may wish to just stick to
+ <code class="type">text</code> as the column type if you think your data has any problems.
+ </p><p>
+ The calling <code class="command">SELECT</code> statement doesn't necessarily have to be
+ just <code class="literal">SELECT *</code> — it can reference the output
+ columns by name or join them to other tables. The function produces a
+ virtual table with which you can perform any operation you wish (e.g.,
+ aggregation, joining, sorting etc.). So we could also have:
+</p><pre class="programlisting">
+SELECT t.title, p.fullname, p.email
+FROM xpath_table('article_id', 'article_xml', 'articles',
+ '/article/title|/article/author/@id',
+ 'xpath_string(article_xml,''/article/@date'') &gt; ''2003-03-20'' ')
+ AS t(article_id integer, title text, author_id integer),
+ tblPeopleInfo AS p
+WHERE t.author_id = p.person_id;
+</pre><p>
+ as a more complicated example. Of course, you could wrap all
+ of this in a view for convenience.
+ </p><div class="sect3" id="id-1.11.7.59.6.12"><div class="titlepage"><div><div><h4 class="title">F.50.3.1. Multivalued Results</h4></div></div></div><p>
+ The <code class="function">xpath_table</code> function assumes that the results of each XPath query
+ might be multivalued, so the number of rows returned by the function
+ may not be the same as the number of input documents. The first row
+ returned contains the first result from each query, the second row the
+ second result from each query. If one of the queries has fewer values
+ than the others, null values will be returned instead.
+ </p><p>
+ In some cases, a user will know that a given XPath query will return
+ only a single result (perhaps a unique document identifier) — if used
+ alongside an XPath query returning multiple results, the single-valued
+ result will appear only on the first row of the result. The solution
+ to this is to use the key field as part of a join against a simpler
+ XPath query. As an example:
+
+</p><pre class="programlisting">
+CREATE TABLE test (
+ id int PRIMARY KEY,
+ xml text
+);
+
+INSERT INTO test VALUES (1, '&lt;doc num="C1"&gt;
+&lt;line num="L1"&gt;&lt;a&gt;1&lt;/a&gt;&lt;b&gt;2&lt;/b&gt;&lt;c&gt;3&lt;/c&gt;&lt;/line&gt;
+&lt;line num="L2"&gt;&lt;a&gt;11&lt;/a&gt;&lt;b&gt;22&lt;/b&gt;&lt;c&gt;33&lt;/c&gt;&lt;/line&gt;
+&lt;/doc&gt;');
+
+INSERT INTO test VALUES (2, '&lt;doc num="C2"&gt;
+&lt;line num="L1"&gt;&lt;a&gt;111&lt;/a&gt;&lt;b&gt;222&lt;/b&gt;&lt;c&gt;333&lt;/c&gt;&lt;/line&gt;
+&lt;line num="L2"&gt;&lt;a&gt;111&lt;/a&gt;&lt;b&gt;222&lt;/b&gt;&lt;c&gt;333&lt;/c&gt;&lt;/line&gt;
+&lt;/doc&gt;');
+
+SELECT * FROM
+ xpath_table('id','xml','test',
+ '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
+ 'true')
+ AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
+WHERE id = 1 ORDER BY doc_num, line_num
+
+ id | doc_num | line_num | val1 | val2 | val3
+----+---------+----------+------+------+------
+ 1 | C1 | L1 | 1 | 2 | 3
+ 1 | | L2 | 11 | 22 | 33
+</pre><p>
+ </p><p>
+ To get <code class="literal">doc_num</code> on every line, the solution is to use two invocations
+ of <code class="function">xpath_table</code> and join the results:
+
+</p><pre class="programlisting">
+SELECT t.*,i.doc_num FROM
+ xpath_table('id', 'xml', 'test',
+ '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
+ 'true')
+ AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
+ xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
+ AS i(id int, doc_num varchar(10))
+WHERE i.id=t.id AND i.id=1
+ORDER BY doc_num, line_num;
+
+ id | line_num | val1 | val2 | val3 | doc_num
+----+----------+------+------+------+---------
+ 1 | L1 | 1 | 2 | 3 | C1
+ 1 | L2 | 11 | 22 | 33 | C1
+(2 rows)
+</pre><p>
+ </p></div></div><div class="sect2" id="id-1.11.7.59.7"><div class="titlepage"><div><div><h3 class="title">F.50.4. XSLT Functions</h3></div></div></div><p>
+ The following functions are available if libxslt is installed:
+ </p><div class="sect3" id="id-1.11.7.59.7.3"><div class="titlepage"><div><div><h4 class="title">F.50.4.1. <code class="literal">xslt_process</code></h4></div></div></div><a id="id-1.11.7.59.7.3.2" class="indexterm"></a><pre class="synopsis">
+xslt_process(text document, text stylesheet, text paramlist) returns text
+</pre><p>
+ This function applies the XSL stylesheet to the document and returns
+ the transformed result. The <code class="literal">paramlist</code> is a list of parameter
+ assignments to be used in the transformation, specified in the form
+ <code class="literal">a=1,b=2</code>. Note that the
+ parameter parsing is very simple-minded: parameter values cannot
+ contain commas!
+ </p><p>
+ There is also a two-parameter version of <code class="function">xslt_process</code> which
+ does not pass any parameters to the transformation.
+ </p></div></div><div class="sect2" id="id-1.11.7.59.8"><div class="titlepage"><div><div><h3 class="title">F.50.5. Author</h3></div></div></div><p>
+ John Gray <code class="email">&lt;<a class="email" href="mailto:jgray@azuli.co.uk">jgray@azuli.co.uk</a>&gt;</code>
+ </p><p>
+ Development of this module was sponsored by Torchbox Ltd. (www.torchbox.com).
+ It has the same BSD license as PostgreSQL.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="uuid-ossp.html" title="F.49. uuid-ossp">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="contrib.html" title="Appendix F. Additional Supplied Modules">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="contrib-prog.html" title="Appendix G. Additional Supplied Programs">Next</a></td></tr><tr><td width="40%" align="left" valign="top">F.49. uuid-ossp </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Appendix G. Additional Supplied Programs</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xoper-optimization.html b/doc/src/sgml/html/xoper-optimization.html
new file mode 100644
index 0000000..ae5f41c
--- /dev/null
+++ b/doc/src/sgml/html/xoper-optimization.html
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.15. Operator Optimization Information</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xoper.html" title="38.14. User-Defined Operators" /><link rel="next" href="xindex.html" title="38.16. Interfacing Extensions to Indexes" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.15. Operator Optimization Information</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xoper.html" title="38.14. User-Defined Operators">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Next</a></td></tr></table><hr /></div><div class="sect1" id="XOPER-OPTIMIZATION"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.15. Operator Optimization Information</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.6">38.15.1. <code class="literal">COMMUTATOR</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.7">38.15.2. <code class="literal">NEGATOR</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.8">38.15.3. <code class="literal">RESTRICT</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.9">38.15.4. <code class="literal">JOIN</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.10">38.15.5. <code class="literal">HASHES</code></a></span></dt><dt><span class="sect2"><a href="xoper-optimization.html#id-1.8.3.18.11">38.15.6. <code class="literal">MERGES</code></a></span></dt></dl></div><a id="id-1.8.3.18.2" class="indexterm"></a><p>
+ A <span class="productname">PostgreSQL</span> operator definition can include
+ several optional clauses that tell the system useful things about how
+ the operator behaves. These clauses should be provided whenever
+ appropriate, because they can make for considerable speedups in execution
+ of queries that use the operator. But if you provide them, you must be
+ sure that they are right! Incorrect use of an optimization clause can
+ result in slow queries, subtly wrong output, or other Bad Things.
+ You can always leave out an optimization clause if you are not sure
+ about it; the only consequence is that queries might run slower than
+ they need to.
+ </p><p>
+ Additional optimization clauses might be added in future versions of
+ <span class="productname">PostgreSQL</span>. The ones described here are all
+ the ones that release 15.4 understands.
+ </p><p>
+ It is also possible to attach a planner support function to the function
+ that underlies an operator, providing another way of telling the system
+ about the behavior of the operator.
+ See <a class="xref" href="xfunc-optimization.html" title="38.11. Function Optimization Information">Section 38.11</a> for more information.
+ </p><div class="sect2" id="id-1.8.3.18.6"><div class="titlepage"><div><div><h3 class="title">38.15.1. <code class="literal">COMMUTATOR</code></h3></div></div></div><p>
+ The <code class="literal">COMMUTATOR</code> clause, if provided, names an operator that is the
+ commutator of the operator being defined. We say that operator A is the
+ commutator of operator B if (x A y) equals (y B x) for all possible input
+ values x, y. Notice that B is also the commutator of A. For example,
+ operators <code class="literal">&lt;</code> and <code class="literal">&gt;</code> for a particular data type are usually each others'
+ commutators, and operator <code class="literal">+</code> is usually commutative with itself.
+ But operator <code class="literal">-</code> is usually not commutative with anything.
+ </p><p>
+ The left operand type of a commutable operator is the same as the
+ right operand type of its commutator, and vice versa. So the name of
+ the commutator operator is all that <span class="productname">PostgreSQL</span>
+ needs to be given to look up the commutator, and that's all that needs to
+ be provided in the <code class="literal">COMMUTATOR</code> clause.
+ </p><p>
+ It's critical to provide commutator information for operators that
+ will be used in indexes and join clauses, because this allows the
+ query optimizer to <span class="quote">“<span class="quote">flip around</span>”</span> such a clause to the forms
+ needed for different plan types. For example, consider a query with
+ a WHERE clause like <code class="literal">tab1.x = tab2.y</code>, where <code class="literal">tab1.x</code>
+ and <code class="literal">tab2.y</code> are of a user-defined type, and suppose that
+ <code class="literal">tab2.y</code> is indexed. The optimizer cannot generate an
+ index scan unless it can determine how to flip the clause around to
+ <code class="literal">tab2.y = tab1.x</code>, because the index-scan machinery expects
+ to see the indexed column on the left of the operator it is given.
+ <span class="productname">PostgreSQL</span> will <span class="emphasis"><em>not</em></span> simply
+ assume that this is a valid transformation — the creator of the
+ <code class="literal">=</code> operator must specify that it is valid, by marking the
+ operator with commutator information.
+ </p><p>
+ When you are defining a self-commutative operator, you just do it.
+ When you are defining a pair of commutative operators, things are
+ a little trickier: how can the first one to be defined refer to the
+ other one, which you haven't defined yet? There are two solutions
+ to this problem:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ One way is to omit the <code class="literal">COMMUTATOR</code> clause in the first operator that
+ you define, and then provide one in the second operator's definition.
+ Since <span class="productname">PostgreSQL</span> knows that commutative
+ operators come in pairs, when it sees the second definition it will
+ automatically go back and fill in the missing <code class="literal">COMMUTATOR</code> clause in
+ the first definition.
+ </p></li><li class="listitem"><p>
+ The other, more straightforward way is just to include <code class="literal">COMMUTATOR</code> clauses
+ in both definitions. When <span class="productname">PostgreSQL</span> processes
+ the first definition and realizes that <code class="literal">COMMUTATOR</code> refers to a nonexistent
+ operator, the system will make a dummy entry for that operator in the
+ system catalog. This dummy entry will have valid data only
+ for the operator name, left and right operand types, and result type,
+ since that's all that <span class="productname">PostgreSQL</span> can deduce
+ at this point. The first operator's catalog entry will link to this
+ dummy entry. Later, when you define the second operator, the system
+ updates the dummy entry with the additional information from the second
+ definition. If you try to use the dummy operator before it's been filled
+ in, you'll just get an error message.
+ </p></li></ul></div><p>
+ </p></div><div class="sect2" id="id-1.8.3.18.7"><div class="titlepage"><div><div><h3 class="title">38.15.2. <code class="literal">NEGATOR</code></h3></div></div></div><p>
+ The <code class="literal">NEGATOR</code> clause, if provided, names an operator that is the
+ negator of the operator being defined. We say that operator A
+ is the negator of operator B if both return Boolean results and
+ (x A y) equals NOT (x B y) for all possible inputs x, y.
+ Notice that B is also the negator of A.
+ For example, <code class="literal">&lt;</code> and <code class="literal">&gt;=</code> are a negator pair for most data types.
+ An operator can never validly be its own negator.
+ </p><p>
+ Unlike commutators, a pair of unary operators could validly be marked
+ as each other's negators; that would mean (A x) equals NOT (B x)
+ for all x.
+ </p><p>
+ An operator's negator must have the same left and/or right operand types
+ as the operator to be defined, so just as with <code class="literal">COMMUTATOR</code>, only the operator
+ name need be given in the <code class="literal">NEGATOR</code> clause.
+ </p><p>
+ Providing a negator is very helpful to the query optimizer since
+ it allows expressions like <code class="literal">NOT (x = y)</code> to be simplified into
+ <code class="literal">x &lt;&gt; y</code>. This comes up more often than you might think, because
+ <code class="literal">NOT</code> operations can be inserted as a consequence of other rearrangements.
+ </p><p>
+ Pairs of negator operators can be defined using the same methods
+ explained above for commutator pairs.
+ </p></div><div class="sect2" id="id-1.8.3.18.8"><div class="titlepage"><div><div><h3 class="title">38.15.3. <code class="literal">RESTRICT</code></h3></div></div></div><p>
+ The <code class="literal">RESTRICT</code> clause, if provided, names a restriction selectivity
+ estimation function for the operator. (Note that this is a function
+ name, not an operator name.) <code class="literal">RESTRICT</code> clauses only make sense for
+ binary operators that return <code class="type">boolean</code>. The idea behind a restriction
+ selectivity estimator is to guess what fraction of the rows in a
+ table will satisfy a <code class="literal">WHERE</code>-clause condition of the form:
+</p><pre class="programlisting">
+column OP constant
+</pre><p>
+ for the current operator and a particular constant value.
+ This assists the optimizer by
+ giving it some idea of how many rows will be eliminated by <code class="literal">WHERE</code>
+ clauses that have this form. (What happens if the constant is on
+ the left, you might be wondering? Well, that's one of the things that
+ <code class="literal">COMMUTATOR</code> is for...)
+ </p><p>
+ Writing new restriction selectivity estimation functions is far beyond
+ the scope of this chapter, but fortunately you can usually just use
+ one of the system's standard estimators for many of your own operators.
+ These are the standard restriction estimators:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="function">eqsel</code> for <code class="literal">=</code></td></tr><tr><td><code class="function">neqsel</code> for <code class="literal">&lt;&gt;</code></td></tr><tr><td><code class="function">scalarltsel</code> for <code class="literal">&lt;</code></td></tr><tr><td><code class="function">scalarlesel</code> for <code class="literal">&lt;=</code></td></tr><tr><td><code class="function">scalargtsel</code> for <code class="literal">&gt;</code></td></tr><tr><td><code class="function">scalargesel</code> for <code class="literal">&gt;=</code></td></tr></table><p>
+ </p><p>
+ You can frequently get away with using either <code class="function">eqsel</code> or <code class="function">neqsel</code> for
+ operators that have very high or very low selectivity, even if they
+ aren't really equality or inequality. For example, the
+ approximate-equality geometric operators use <code class="function">eqsel</code> on the assumption that
+ they'll usually only match a small fraction of the entries in a table.
+ </p><p>
+ You can use <code class="function">scalarltsel</code>, <code class="function">scalarlesel</code>,
+ <code class="function">scalargtsel</code> and <code class="function">scalargesel</code> for comparisons on
+ data types that have some sensible means of being converted into numeric
+ scalars for range comparisons. If possible, add the data type to those
+ understood by the function <code class="function">convert_to_scalar()</code> in
+ <code class="filename">src/backend/utils/adt/selfuncs.c</code>.
+ (Eventually, this function should be replaced by per-data-type functions
+ identified through a column of the <code class="classname">pg_type</code> system catalog; but that hasn't happened
+ yet.) If you do not do this, things will still work, but the optimizer's
+ estimates won't be as good as they could be.
+ </p><p>
+ Another useful built-in selectivity estimation function
+ is <code class="function">matchingsel</code>, which will work for almost any
+ binary operator, if standard MCV and/or histogram statistics are
+ collected for the input data type(s). Its default estimate is set to
+ twice the default estimate used in <code class="function">eqsel</code>, making
+ it most suitable for comparison operators that are somewhat less
+ strict than equality. (Or you could call the
+ underlying <code class="function">generic_restriction_selectivity</code>
+ function, providing a different default estimate.)
+ </p><p>
+ There are additional selectivity estimation functions designed for geometric
+ operators in <code class="filename">src/backend/utils/adt/geo_selfuncs.c</code>: <code class="function">areasel</code>, <code class="function">positionsel</code>,
+ and <code class="function">contsel</code>. At this writing these are just stubs, but you might want
+ to use them (or even better, improve them) anyway.
+ </p></div><div class="sect2" id="id-1.8.3.18.9"><div class="titlepage"><div><div><h3 class="title">38.15.4. <code class="literal">JOIN</code></h3></div></div></div><p>
+ The <code class="literal">JOIN</code> clause, if provided, names a join selectivity
+ estimation function for the operator. (Note that this is a function
+ name, not an operator name.) <code class="literal">JOIN</code> clauses only make sense for
+ binary operators that return <code class="type">boolean</code>. The idea behind a join
+ selectivity estimator is to guess what fraction of the rows in a
+ pair of tables will satisfy a <code class="literal">WHERE</code>-clause condition of the form:
+</p><pre class="programlisting">
+table1.column1 OP table2.column2
+</pre><p>
+ for the current operator. As with the <code class="literal">RESTRICT</code> clause, this helps
+ the optimizer very substantially by letting it figure out which
+ of several possible join sequences is likely to take the least work.
+ </p><p>
+ As before, this chapter will make no attempt to explain how to write
+ a join selectivity estimator function, but will just suggest that
+ you use one of the standard estimators if one is applicable:
+ </p><table border="0" summary="Simple list" class="simplelist"><tr><td><code class="function">eqjoinsel</code> for <code class="literal">=</code></td></tr><tr><td><code class="function">neqjoinsel</code> for <code class="literal">&lt;&gt;</code></td></tr><tr><td><code class="function">scalarltjoinsel</code> for <code class="literal">&lt;</code></td></tr><tr><td><code class="function">scalarlejoinsel</code> for <code class="literal">&lt;=</code></td></tr><tr><td><code class="function">scalargtjoinsel</code> for <code class="literal">&gt;</code></td></tr><tr><td><code class="function">scalargejoinsel</code> for <code class="literal">&gt;=</code></td></tr><tr><td><code class="function">matchingjoinsel</code> for generic matching operators</td></tr><tr><td><code class="function">areajoinsel</code> for 2D area-based comparisons</td></tr><tr><td><code class="function">positionjoinsel</code> for 2D position-based comparisons</td></tr><tr><td><code class="function">contjoinsel</code> for 2D containment-based comparisons</td></tr></table><p>
+ </p></div><div class="sect2" id="id-1.8.3.18.10"><div class="titlepage"><div><div><h3 class="title">38.15.5. <code class="literal">HASHES</code></h3></div></div></div><p>
+ The <code class="literal">HASHES</code> clause, if present, tells the system that
+ it is permissible to use the hash join method for a join based on this
+ operator. <code class="literal">HASHES</code> only makes sense for a binary operator that
+ returns <code class="literal">boolean</code>, and in practice the operator must represent
+ equality for some data type or pair of data types.
+ </p><p>
+ The assumption underlying hash join is that the join operator can
+ only return true for pairs of left and right values that hash to the
+ same hash code. If two values get put in different hash buckets, the
+ join will never compare them at all, implicitly assuming that the
+ result of the join operator must be false. So it never makes sense
+ to specify <code class="literal">HASHES</code> for operators that do not represent
+ some form of equality. In most cases it is only practical to support
+ hashing for operators that take the same data type on both sides.
+ However, sometimes it is possible to design compatible hash functions
+ for two or more data types; that is, functions that will generate the
+ same hash codes for <span class="quote">“<span class="quote">equal</span>”</span> values, even though the values
+ have different representations. For example, it's fairly simple
+ to arrange this property when hashing integers of different widths.
+ </p><p>
+ To be marked <code class="literal">HASHES</code>, the join operator must appear
+ in a hash index operator family. This is not enforced when you create
+ the operator, since of course the referencing operator family couldn't
+ exist yet. But attempts to use the operator in hash joins will fail
+ at run time if no such operator family exists. The system needs the
+ operator family to find the data-type-specific hash function(s) for the
+ operator's input data type(s). Of course, you must also create suitable
+ hash functions before you can create the operator family.
+ </p><p>
+ Care should be exercised when preparing a hash function, because there
+ are machine-dependent ways in which it might fail to do the right thing.
+ For example, if your data type is a structure in which there might be
+ uninteresting pad bits, you cannot simply pass the whole structure to
+ <code class="function">hash_any</code>. (Unless you write your other operators and
+ functions to ensure that the unused bits are always zero, which is the
+ recommended strategy.)
+ Another example is that on machines that meet the <acronym class="acronym">IEEE</acronym>
+ floating-point standard, negative zero and positive zero are different
+ values (different bit patterns) but they are defined to compare equal.
+ If a float value might contain negative zero then extra steps are needed
+ to ensure it generates the same hash value as positive zero.
+ </p><p>
+ A hash-joinable operator must have a commutator (itself if the two
+ operand data types are the same, or a related equality operator
+ if they are different) that appears in the same operator family.
+ If this is not the case, planner errors might occur when the operator
+ is used. Also, it is a good idea (but not strictly required) for
+ a hash operator family that supports multiple data types to provide
+ equality operators for every combination of the data types; this
+ allows better optimization.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The function underlying a hash-joinable operator must be marked
+ immutable or stable. If it is volatile, the system will never
+ attempt to use the operator for a hash join.
+ </p></div><div class="note"><h3 class="title">Note</h3><p>
+ If a hash-joinable operator has an underlying function that is marked
+ strict, the
+ function must also be complete: that is, it should return true or
+ false, never null, for any two nonnull inputs. If this rule is
+ not followed, hash-optimization of <code class="literal">IN</code> operations might
+ generate wrong results. (Specifically, <code class="literal">IN</code> might return
+ false where the correct answer according to the standard would be null;
+ or it might yield an error complaining that it wasn't prepared for a
+ null result.)
+ </p></div></div><div class="sect2" id="id-1.8.3.18.11"><div class="titlepage"><div><div><h3 class="title">38.15.6. <code class="literal">MERGES</code></h3></div></div></div><p>
+ The <code class="literal">MERGES</code> clause, if present, tells the system that
+ it is permissible to use the merge-join method for a join based on this
+ operator. <code class="literal">MERGES</code> only makes sense for a binary operator that
+ returns <code class="literal">boolean</code>, and in practice the operator must represent
+ equality for some data type or pair of data types.
+ </p><p>
+ Merge join is based on the idea of sorting the left- and right-hand tables
+ into order and then scanning them in parallel. So, both data types must
+ be capable of being fully ordered, and the join operator must be one
+ that can only succeed for pairs of values that fall at the
+ <span class="quote">“<span class="quote">same place</span>”</span>
+ in the sort order. In practice this means that the join operator must
+ behave like equality. But it is possible to merge-join two
+ distinct data types so long as they are logically compatible. For
+ example, the <code class="type">smallint</code>-versus-<code class="type">integer</code>
+ equality operator is merge-joinable.
+ We only need sorting operators that will bring both data types into a
+ logically compatible sequence.
+ </p><p>
+ To be marked <code class="literal">MERGES</code>, the join operator must appear
+ as an equality member of a <code class="literal">btree</code> index operator family.
+ This is not enforced when you create
+ the operator, since of course the referencing operator family couldn't
+ exist yet. But the operator will not actually be used for merge joins
+ unless a matching operator family can be found. The
+ <code class="literal">MERGES</code> flag thus acts as a hint to the planner that
+ it's worth looking for a matching operator family.
+ </p><p>
+ A merge-joinable operator must have a commutator (itself if the two
+ operand data types are the same, or a related equality operator
+ if they are different) that appears in the same operator family.
+ If this is not the case, planner errors might occur when the operator
+ is used. Also, it is a good idea (but not strictly required) for
+ a <code class="literal">btree</code> operator family that supports multiple data types to provide
+ equality operators for every combination of the data types; this
+ allows better optimization.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ The function underlying a merge-joinable operator must be marked
+ immutable or stable. If it is volatile, the system will never
+ attempt to use the operator for a merge join.
+ </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xoper.html" title="38.14. User-Defined Operators">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xindex.html" title="38.16. Interfacing Extensions to Indexes">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.14. User-Defined Operators </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.16. Interfacing Extensions to Indexes</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xoper.html b/doc/src/sgml/html/xoper.html
new file mode 100644
index 0000000..52663d8
--- /dev/null
+++ b/doc/src/sgml/html/xoper.html
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.14. User-Defined Operators</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xtypes.html" title="38.13. User-Defined Types" /><link rel="next" href="xoper-optimization.html" title="38.15. Operator Optimization Information" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.14. User-Defined Operators</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xtypes.html" title="38.13. User-Defined Types">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xoper-optimization.html" title="38.15. Operator Optimization Information">Next</a></td></tr></table><hr /></div><div class="sect1" id="XOPER"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.14. User-Defined Operators</h2></div></div></div><a id="id-1.8.3.17.2" class="indexterm"></a><p>
+ Every operator is <span class="quote">“<span class="quote">syntactic sugar</span>”</span> for a call to an
+ underlying function that does the real work; so you must
+ first create the underlying function before you can create
+ the operator. However, an operator is <span class="emphasis"><em>not merely</em></span>
+ syntactic sugar, because it carries additional information
+ that helps the query planner optimize queries that use the
+ operator. The next section will be devoted to explaining
+ that additional information.
+ </p><p>
+ <span class="productname">PostgreSQL</span> supports prefix
+ and infix operators. Operators can be
+ overloaded;<a id="id-1.8.3.17.4.2" class="indexterm"></a>
+ that is, the same operator name can be used for different operators
+ that have different numbers and types of operands. When a query is
+ executed, the system determines the operator to call from the
+ number and types of the provided operands.
+ </p><p>
+ Here is an example of creating an operator for adding two complex
+ numbers. We assume we've already created the definition of type
+ <code class="type">complex</code> (see <a class="xref" href="xtypes.html" title="38.13. User-Defined Types">Section 38.13</a>). First we need a
+ function that does the work, then we can define the operator:
+
+</p><pre class="programlisting">
+CREATE FUNCTION complex_add(complex, complex)
+ RETURNS complex
+ AS '<em class="replaceable"><code>filename</code></em>', 'complex_add'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR + (
+ leftarg = complex,
+ rightarg = complex,
+ function = complex_add,
+ commutator = +
+);
+</pre><p>
+ </p><p>
+ Now we could execute a query like this:
+
+</p><pre class="screen">
+SELECT (a + b) AS c FROM test_complex;
+
+ c
+-----------------
+ (5.2,6.05)
+ (133.42,144.95)
+</pre><p>
+ </p><p>
+ We've shown how to create a binary operator here. To create a prefix
+ operator, just omit the <code class="literal">leftarg</code>.
+ The <code class="literal">function</code>
+ clause and the argument clauses are the only required items in
+ <code class="command">CREATE OPERATOR</code>. The <code class="literal">commutator</code>
+ clause shown in the example is an optional hint to the query
+ optimizer. Further details about <code class="literal">commutator</code> and other
+ optimizer hints appear in the next section.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xtypes.html" title="38.13. User-Defined Types">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xoper-optimization.html" title="38.15. Operator Optimization Information">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.13. User-Defined Types </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.15. Operator Optimization Information</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xplang-install.html b/doc/src/sgml/html/xplang-install.html
new file mode 100644
index 0000000..a286182
--- /dev/null
+++ b/doc/src/sgml/html/xplang-install.html
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>42.1. Installing Procedural Languages</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xplang.html" title="Chapter 42. Procedural Languages" /><link rel="next" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">42.1. Installing Procedural Languages</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xplang.html" title="Chapter 42. Procedural Languages">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="xplang.html" title="Chapter 42. Procedural Languages">Up</a></td><th width="60%" align="center">Chapter 42. Procedural Languages</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Next</a></td></tr></table><hr /></div><div class="sect1" id="XPLANG-INSTALL"><div class="titlepage"><div><div><h2 class="title" style="clear: both">42.1. Installing Procedural Languages</h2></div></div></div><p>
+ A procedural language must be <span class="quote">“<span class="quote">installed</span>”</span> into each
+ database where it is to be used. But procedural languages installed in
+ the database <code class="literal">template1</code> are automatically available in all
+ subsequently created databases, since their entries in
+ <code class="literal">template1</code> will be copied by <code class="command">CREATE DATABASE</code>.
+ So the database administrator can
+ decide which languages are available in which databases and can make
+ some languages available by default if desired.
+ </p><p>
+ For the languages supplied with the standard distribution, it is
+ only necessary to execute <code class="command">CREATE EXTENSION</code>
+ <em class="replaceable"><code>language_name</code></em> to install the language into the
+ current database.
+ The manual procedure described below is only recommended for
+ installing languages that have not been packaged as extensions.
+ </p><div class="procedure" id="id-1.8.7.5.4"><p class="title"><strong>Manual Procedural Language Installation</strong></p><p>
+ A procedural language is installed in a database in five steps,
+ which must be carried out by a database superuser. In most cases
+ the required SQL commands should be packaged as the installation script
+ of an <span class="quote">“<span class="quote">extension</span>”</span>, so that <code class="command">CREATE EXTENSION</code> can be
+ used to execute them.
+ </p><ol class="procedure" type="1"><li class="step" id="XPLANG-INSTALL-CR1"><p>
+ The shared object for the language handler must be compiled and
+ installed into an appropriate library directory. This works in the same
+ way as building and installing modules with regular user-defined C
+ functions does; see <a class="xref" href="xfunc-c.html#DFUNC" title="38.10.5. Compiling and Linking Dynamically-Loaded Functions">Section 38.10.5</a>. Often, the language
+ handler will depend on an external library that provides the actual
+ programming language engine; if so, that must be installed as well.
+ </p></li><li class="step" id="XPLANG-INSTALL-CR2"><p>
+ The handler must be declared with the command
+</p><pre class="synopsis">
+CREATE FUNCTION <em class="replaceable"><code>handler_function_name</code></em>()
+ RETURNS language_handler
+ AS '<em class="replaceable"><code>path-to-shared-object</code></em>'
+ LANGUAGE C;
+</pre><p>
+ The special return type of <code class="type">language_handler</code> tells
+ the database system that this function does not return one of
+ the defined <acronym class="acronym">SQL</acronym> data types and is not directly usable
+ in <acronym class="acronym">SQL</acronym> statements.
+ </p></li><li class="step" id="XPLANG-INSTALL-CR3"><p>
+ Optionally, the language handler can provide an <span class="quote">“<span class="quote">inline</span>”</span>
+ handler function that executes anonymous code blocks
+ (<a class="link" href="sql-do.html" title="DO"><code class="command">DO</code></a> commands)
+ written in this language. If an inline handler function
+ is provided by the language, declare it with a command like
+</p><pre class="synopsis">
+CREATE FUNCTION <em class="replaceable"><code>inline_function_name</code></em>(internal)
+ RETURNS void
+ AS '<em class="replaceable"><code>path-to-shared-object</code></em>'
+ LANGUAGE C;
+</pre><p>
+ </p></li><li class="step" id="XPLANG-INSTALL-CR4"><p>
+ Optionally, the language handler can provide a <span class="quote">“<span class="quote">validator</span>”</span>
+ function that checks a function definition for correctness without
+ actually executing it. The validator function is called by
+ <code class="command">CREATE FUNCTION</code> if it exists. If a validator function
+ is provided by the language, declare it with a command like
+</p><pre class="synopsis">
+CREATE FUNCTION <em class="replaceable"><code>validator_function_name</code></em>(oid)
+ RETURNS void
+ AS '<em class="replaceable"><code>path-to-shared-object</code></em>'
+ LANGUAGE C STRICT;
+</pre><p>
+ </p></li><li class="step" id="XPLANG-INSTALL-CR5"><p>
+ Finally, the PL must be declared with the command
+</p><pre class="synopsis">
+CREATE [<span class="optional">TRUSTED</span>] LANGUAGE <em class="replaceable"><code>language_name</code></em>
+ HANDLER <em class="replaceable"><code>handler_function_name</code></em>
+ [<span class="optional">INLINE <em class="replaceable"><code>inline_function_name</code></em></span>]
+ [<span class="optional">VALIDATOR <em class="replaceable"><code>validator_function_name</code></em></span>] ;
+</pre><p>
+ The optional key word <code class="literal">TRUSTED</code> specifies that
+ the language does not grant access to data that the user would
+ not otherwise have. Trusted languages are designed for ordinary
+ database users (those without superuser privilege) and allows them
+ to safely create functions and
+ procedures. Since PL functions are executed inside the database
+ server, the <code class="literal">TRUSTED</code> flag should only be given
+ for languages that do not allow access to database server
+ internals or the file system. The languages
+ <span class="application">PL/pgSQL</span>,
+ <span class="application">PL/Tcl</span>, and
+ <span class="application">PL/Perl</span>
+ are considered trusted; the languages
+ <span class="application">PL/TclU</span>,
+ <span class="application">PL/PerlU</span>, and
+ <span class="application">PL/PythonU</span>
+ are designed to provide unlimited functionality and should
+ <span class="emphasis"><em>not</em></span> be marked trusted.
+ </p></li></ol></div><p>
+ <a class="xref" href="xplang-install.html#XPLANG-INSTALL-EXAMPLE" title="Example 42.1. Manual Installation of PL/Perl">Example 42.1</a> shows how the manual
+ installation procedure would work with the language
+ <span class="application">PL/Perl</span>.
+ </p><div class="example" id="XPLANG-INSTALL-EXAMPLE"><p class="title"><strong>Example 42.1. Manual Installation of <span class="application">PL/Perl</span></strong></p><div class="example-contents"><p>
+ The following command tells the database server where to find the
+ shared object for the <span class="application">PL/Perl</span> language's call
+ handler function:
+
+</p><pre class="programlisting">
+CREATE FUNCTION plperl_call_handler() RETURNS language_handler AS
+ '$libdir/plperl' LANGUAGE C;
+</pre><p>
+ </p><p>
+ <span class="application">PL/Perl</span> has an inline handler function
+ and a validator function, so we declare those too:
+
+</p><pre class="programlisting">
+CREATE FUNCTION plperl_inline_handler(internal) RETURNS void AS
+ '$libdir/plperl' LANGUAGE C STRICT;
+
+CREATE FUNCTION plperl_validator(oid) RETURNS void AS
+ '$libdir/plperl' LANGUAGE C STRICT;
+</pre><p>
+ </p><p>
+ The command:
+</p><pre class="programlisting">
+CREATE TRUSTED LANGUAGE plperl
+ HANDLER plperl_call_handler
+ INLINE plperl_inline_handler
+ VALIDATOR plperl_validator;
+</pre><p>
+ then defines that the previously declared functions
+ should be invoked for functions and procedures where the
+ language attribute is <code class="literal">plperl</code>.
+ </p></div></div><br class="example-break" /><p>
+ In a default <span class="productname">PostgreSQL</span> installation,
+ the handler for the <span class="application">PL/pgSQL</span> language
+ is built and installed into the <span class="quote">“<span class="quote">library</span>”</span>
+ directory; furthermore, the <span class="application">PL/pgSQL</span> language
+ itself is installed in all databases.
+ If <span class="application">Tcl</span> support is configured in, the handlers for
+ <span class="application">PL/Tcl</span> and <span class="application">PL/TclU</span> are built and installed
+ in the library directory, but the language itself is not installed in any
+ database by default.
+ Likewise, the <span class="application">PL/Perl</span> and <span class="application">PL/PerlU</span>
+ handlers are built and installed if Perl support is configured, and the
+ <span class="application">PL/PythonU</span> handler is installed if Python support is
+ configured, but these languages are not installed by default.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xplang.html" title="Chapter 42. Procedural Languages">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="xplang.html" title="Chapter 42. Procedural Languages">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 42. Procedural Languages </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> Chapter 43. <span class="application">PL/pgSQL</span> — <acronym class="acronym">SQL</acronym> Procedural Language</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xplang.html b/doc/src/sgml/html/xplang.html
new file mode 100644
index 0000000..331a8fd
--- /dev/null
+++ b/doc/src/sgml/html/xplang.html
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 42. Procedural Languages</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="rules-triggers.html" title="41.7. Rules Versus Triggers" /><link rel="next" href="xplang-install.html" title="42.1. Installing Procedural Languages" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">Chapter 42. Procedural Languages</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="rules-triggers.html" title="41.7. Rules Versus Triggers">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><th width="60%" align="center">Part V. Server Programming</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xplang-install.html" title="42.1. Installing Procedural Languages">Next</a></td></tr></table><hr /></div><div class="chapter" id="XPLANG"><div class="titlepage"><div><div><h2 class="title">Chapter 42. Procedural Languages</h2></div></div></div><div class="toc"><p><strong>Table of Contents</strong></p><dl class="toc"><dt><span class="sect1"><a href="xplang-install.html">42.1. Installing Procedural Languages</a></span></dt></dl></div><a id="id-1.8.7.2" class="indexterm"></a><p>
+ <span class="productname">PostgreSQL</span> allows user-defined functions
+ to be written in other languages besides SQL and C. These other
+ languages are generically called <em class="firstterm">procedural
+ languages</em> (<acronym class="acronym">PL</acronym>s). For a function
+ written in a procedural language, the database server has
+ no built-in knowledge about how to interpret the function's source
+ text. Instead, the task is passed to a special handler that knows
+ the details of the language. The handler could either do all the
+ work of parsing, syntax analysis, execution, etc. itself, or it
+ could serve as <span class="quote">“<span class="quote">glue</span>”</span> between
+ <span class="productname">PostgreSQL</span> and an existing implementation
+ of a programming language. The handler itself is a
+ C language function compiled into a shared object and
+ loaded on demand, just like any other C function.
+ </p><p>
+ There are currently four procedural languages available in the
+ standard <span class="productname">PostgreSQL</span> distribution:
+ <span class="application">PL/pgSQL</span> (<a class="xref" href="plpgsql.html" title="Chapter 43. PL/pgSQL — SQL Procedural Language">Chapter 43</a>),
+ <span class="application">PL/Tcl</span> (<a class="xref" href="pltcl.html" title="Chapter 44. PL/Tcl — Tcl Procedural Language">Chapter 44</a>),
+ <span class="application">PL/Perl</span> (<a class="xref" href="plperl.html" title="Chapter 45. PL/Perl — Perl Procedural Language">Chapter 45</a>), and
+ <span class="application">PL/Python</span> (<a class="xref" href="plpython.html" title="Chapter 46. PL/Python — Python Procedural Language">Chapter 46</a>).
+ There are additional procedural languages available that are not
+ included in the core distribution. <a class="xref" href="external-projects.html" title="Appendix H. External Projects">Appendix H</a>
+ has information about finding them. In addition other languages can
+ be defined by users; the basics of developing a new procedural
+ language are covered in <a class="xref" href="plhandler.html" title="Chapter 58. Writing a Procedural Language Handler">Chapter 58</a>.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="rules-triggers.html" title="41.7. Rules Versus Triggers">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="server-programming.html" title="Part V. Server Programming">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xplang-install.html" title="42.1. Installing Procedural Languages">Next</a></td></tr><tr><td width="40%" align="left" valign="top">41.7. Rules Versus Triggers </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 42.1. Installing Procedural Languages</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xproc.html b/doc/src/sgml/html/xproc.html
new file mode 100644
index 0000000..1c15497
--- /dev/null
+++ b/doc/src/sgml/html/xproc.html
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.4. User-Defined Procedures</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xfunc.html" title="38.3. User-Defined Functions" /><link rel="next" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.4. User-Defined Procedures</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xfunc.html" title="38.3. User-Defined Functions">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="XPROC"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.4. User-Defined Procedures</h2></div></div></div><a id="id-1.8.3.7.2" class="indexterm"></a><p>
+ A procedure is a database object similar to a function.
+ The key differences are:
+
+ </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
+ Procedures are defined with
+ the <a class="link" href="sql-createprocedure.html" title="CREATE PROCEDURE"><code class="command">CREATE
+ PROCEDURE</code></a> command, not <code class="command">CREATE
+ FUNCTION</code>.
+ </p></li><li class="listitem"><p>
+ Procedures do not return a function value; hence <code class="command">CREATE
+ PROCEDURE</code> lacks a <code class="literal">RETURNS</code> clause.
+ However, procedures can instead return data to their callers via
+ output parameters.
+ </p></li><li class="listitem"><p>
+ While a function is called as part of a query or DML command, a
+ procedure is called in isolation using
+ the <a class="link" href="sql-call.html" title="CALL"><code class="command">CALL</code></a> command.
+ </p></li><li class="listitem"><p>
+ A procedure can commit or roll back transactions during its
+ execution (then automatically beginning a new transaction), so long
+ as the invoking <code class="command">CALL</code> command is not part of an
+ explicit transaction block. A function cannot do that.
+ </p></li><li class="listitem"><p>
+ Certain function attributes, such as strictness, don't apply to
+ procedures. Those attributes control how the function is
+ used in a query, which isn't relevant to procedures.
+ </p></li></ul></div><p>
+ </p><p>
+ The explanations in the following sections about how to define
+ user-defined functions apply to procedures as well, except for the
+ points made above.
+ </p><p>
+ Collectively, functions and procedures are also known
+ as <em class="firstterm">routines</em><a id="id-1.8.3.7.5.2" class="indexterm"></a>.
+ There are commands such as <a class="link" href="sql-alterroutine.html" title="ALTER ROUTINE"><code class="command">ALTER ROUTINE</code></a>
+ and <a class="link" href="sql-droproutine.html" title="DROP ROUTINE"><code class="command">DROP ROUTINE</code></a> that can operate on functions and
+ procedures without having to know which kind it is. Note, however, that
+ there is no <code class="literal">CREATE ROUTINE</code> command.
+ </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xfunc.html" title="38.3. User-Defined Functions">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xfunc-sql.html" title="38.5. Query Language (SQL) Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.3. User-Defined Functions </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.5. Query Language (<acronym class="acronym">SQL</acronym>) Functions</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/html/xtypes.html b/doc/src/sgml/html/xtypes.html
new file mode 100644
index 0000000..88d1e8a
--- /dev/null
+++ b/doc/src/sgml/html/xtypes.html
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>38.13. User-Defined Types</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="xaggr.html" title="38.12. User-Defined Aggregates" /><link rel="next" href="xoper.html" title="38.14. User-Defined Operators" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">38.13. User-Defined Types</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="xaggr.html" title="38.12. User-Defined Aggregates">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><th width="60%" align="center">Chapter 38. Extending <acronym class="acronym">SQL</acronym></th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="xoper.html" title="38.14. User-Defined Operators">Next</a></td></tr></table><hr /></div><div class="sect1" id="XTYPES"><div class="titlepage"><div><div><h2 class="title" style="clear: both">38.13. User-Defined Types</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="xtypes.html#XTYPES-TOAST">38.13.1. TOAST Considerations</a></span></dt></dl></div><a id="id-1.8.3.16.2" class="indexterm"></a><p>
+ As described in <a class="xref" href="extend-type-system.html" title="38.2. The PostgreSQL Type System">Section 38.2</a>,
+ <span class="productname">PostgreSQL</span> can be extended to support new
+ data types. This section describes how to define new base types,
+ which are data types defined below the level of the <acronym class="acronym">SQL</acronym>
+ language. Creating a new base type requires implementing functions
+ to operate on the type in a low-level language, usually C.
+ </p><p>
+ The examples in this section can be found in
+ <code class="filename">complex.sql</code> and <code class="filename">complex.c</code>
+ in the <code class="filename">src/tutorial</code> directory of the source distribution.
+ See the <code class="filename">README</code> file in that directory for instructions
+ about running the examples.
+ </p><p>
+ <a id="id-1.8.3.16.5.1" class="indexterm"></a>
+ <a id="id-1.8.3.16.5.2" class="indexterm"></a>
+ A user-defined type must always have input and output functions.
+ These functions determine how the type appears in strings (for input
+ by the user and output to the user) and how the type is organized in
+ memory. The input function takes a null-terminated character string
+ as its argument and returns the internal (in memory) representation
+ of the type. The output function takes the internal representation
+ of the type as argument and returns a null-terminated character
+ string. If we want to do anything more with the type than merely
+ store it, we must provide additional functions to implement whatever
+ operations we'd like to have for the type.
+ </p><p>
+ Suppose we want to define a type <code class="type">complex</code> that represents
+ complex numbers. A natural way to represent a complex number in
+ memory would be the following C structure:
+
+</p><pre class="programlisting">
+typedef struct Complex {
+ double x;
+ double y;
+} Complex;
+</pre><p>
+
+ We will need to make this a pass-by-reference type, since it's too
+ large to fit into a single <code class="type">Datum</code> value.
+ </p><p>
+ As the external string representation of the type, we choose a
+ string of the form <code class="literal">(x,y)</code>.
+ </p><p>
+ The input and output functions are usually not hard to write,
+ especially the output function. But when defining the external
+ string representation of the type, remember that you must eventually
+ write a complete and robust parser for that representation as your
+ input function. For instance:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(complex_in);
+
+Datum
+complex_in(PG_FUNCTION_ARGS)
+{
+ char *str = PG_GETARG_CSTRING(0);
+ double x,
+ y;
+ Complex *result;
+
+ if (sscanf(str, " ( %lf , %lf )", &amp;x, &amp;y) != 2)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "complex", str)));
+
+ result = (Complex *) palloc(sizeof(Complex));
+ result-&gt;x = x;
+ result-&gt;y = y;
+ PG_RETURN_POINTER(result);
+}
+
+</pre><p>
+
+ The output function can simply be:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(complex_out);
+
+Datum
+complex_out(PG_FUNCTION_ARGS)
+{
+ Complex *complex = (Complex *) PG_GETARG_POINTER(0);
+ char *result;
+
+ result = psprintf("(%g,%g)", complex-&gt;x, complex-&gt;y);
+ PG_RETURN_CSTRING(result);
+}
+
+</pre><p>
+ </p><p>
+ You should be careful to make the input and output functions inverses of
+ each other. If you do not, you will have severe problems when you
+ need to dump your data into a file and then read it back in. This
+ is a particularly common problem when floating-point numbers are
+ involved.
+ </p><p>
+ Optionally, a user-defined type can provide binary input and output
+ routines. Binary I/O is normally faster but less portable than textual
+ I/O. As with textual I/O, it is up to you to define exactly what the
+ external binary representation is. Most of the built-in data types
+ try to provide a machine-independent binary representation. For
+ <code class="type">complex</code>, we will piggy-back on the binary I/O converters
+ for type <code class="type">float8</code>:
+
+</p><pre class="programlisting">
+PG_FUNCTION_INFO_V1(complex_recv);
+
+Datum
+complex_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ Complex *result;
+
+ result = (Complex *) palloc(sizeof(Complex));
+ result-&gt;x = pq_getmsgfloat8(buf);
+ result-&gt;y = pq_getmsgfloat8(buf);
+ PG_RETURN_POINTER(result);
+}
+
+PG_FUNCTION_INFO_V1(complex_send);
+
+Datum
+complex_send(PG_FUNCTION_ARGS)
+{
+ Complex *complex = (Complex *) PG_GETARG_POINTER(0);
+ StringInfoData buf;
+
+ pq_begintypsend(&amp;buf);
+ pq_sendfloat8(&amp;buf, complex-&gt;x);
+ pq_sendfloat8(&amp;buf, complex-&gt;y);
+ PG_RETURN_BYTEA_P(pq_endtypsend(&amp;buf));
+}
+
+</pre><p>
+ </p><p>
+ Once we have written the I/O functions and compiled them into a shared
+ library, we can define the <code class="type">complex</code> type in SQL.
+ First we declare it as a shell type:
+
+</p><pre class="programlisting">
+CREATE TYPE complex;
+</pre><p>
+
+ This serves as a placeholder that allows us to reference the type while
+ defining its I/O functions. Now we can define the I/O functions:
+
+</p><pre class="programlisting">
+CREATE FUNCTION complex_in(cstring)
+ RETURNS complex
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION complex_out(complex)
+ RETURNS cstring
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION complex_recv(internal)
+ RETURNS complex
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION complex_send(complex)
+ RETURNS bytea
+ AS '<em class="replaceable"><code>filename</code></em>'
+ LANGUAGE C IMMUTABLE STRICT;
+</pre><p>
+ </p><p>
+ Finally, we can provide the full definition of the data type:
+</p><pre class="programlisting">
+CREATE TYPE complex (
+ internallength = 16,
+ input = complex_in,
+ output = complex_out,
+ receive = complex_recv,
+ send = complex_send,
+ alignment = double
+);
+</pre><p>
+ </p><p>
+ <a id="id-1.8.3.16.13.1" class="indexterm"></a>
+ When you define a new base type,
+ <span class="productname">PostgreSQL</span> automatically provides support
+ for arrays of that type. The array type typically
+ has the same name as the base type with the underscore character
+ (<code class="literal">_</code>) prepended.
+ </p><p>
+ Once the data type exists, we can declare additional functions to
+ provide useful operations on the data type. Operators can then be
+ defined atop the functions, and if needed, operator classes can be
+ created to support indexing of the data type. These additional
+ layers are discussed in following sections.
+ </p><p>
+ If the internal representation of the data type is variable-length, the
+ internal representation must follow the standard layout for variable-length
+ data: the first four bytes must be a <code class="type">char[4]</code> field which is
+ never accessed directly (customarily named <code class="structfield">vl_len_</code>). You
+ must use the <code class="function">SET_VARSIZE()</code> macro to store the total
+ size of the datum (including the length field itself) in this field
+ and <code class="function">VARSIZE()</code> to retrieve it. (These macros exist
+ because the length field may be encoded depending on platform.)
+ </p><p>
+ For further details see the description of the
+ <a class="xref" href="sql-createtype.html" title="CREATE TYPE"><span class="refentrytitle">CREATE TYPE</span></a> command.
+ </p><div class="sect2" id="XTYPES-TOAST"><div class="titlepage"><div><div><h3 class="title">38.13.1. TOAST Considerations</h3></div></div></div><a id="id-1.8.3.16.17.2" class="indexterm"></a><p>
+ If the values of your data type vary in size (in internal form), it's
+ usually desirable to make the data type <acronym class="acronym">TOAST</acronym>-able (see <a class="xref" href="storage-toast.html" title="73.2. TOAST">Section 73.2</a>). You should do this even if the values are always
+ too small to be compressed or stored externally, because
+ <acronym class="acronym">TOAST</acronym> can save space on small data too, by reducing header
+ overhead.
+ </p><p>
+ To support <acronym class="acronym">TOAST</acronym> storage, the C functions operating on the data
+ type must always be careful to unpack any toasted values they are handed
+ by using <code class="function">PG_DETOAST_DATUM</code>. (This detail is customarily hidden
+ by defining type-specific <code class="function">GETARG_DATATYPE_P</code> macros.)
+ Then, when running the <code class="command">CREATE TYPE</code> command, specify the
+ internal length as <code class="literal">variable</code> and select some appropriate storage
+ option other than <code class="literal">plain</code>.
+ </p><p>
+ If data alignment is unimportant (either just for a specific function or
+ because the data type specifies byte alignment anyway) then it's possible
+ to avoid some of the overhead of <code class="function">PG_DETOAST_DATUM</code>. You can use
+ <code class="function">PG_DETOAST_DATUM_PACKED</code> instead (customarily hidden by
+ defining a <code class="function">GETARG_DATATYPE_PP</code> macro) and using the macros
+ <code class="function">VARSIZE_ANY_EXHDR</code> and <code class="function">VARDATA_ANY</code> to access
+ a potentially-packed datum.
+ Again, the data returned by these macros is not aligned even if the data
+ type definition specifies an alignment. If the alignment is important you
+ must go through the regular <code class="function">PG_DETOAST_DATUM</code> interface.
+ </p><div class="note"><h3 class="title">Note</h3><p>
+ Older code frequently declares <code class="structfield">vl_len_</code> as an
+ <code class="type">int32</code> field instead of <code class="type">char[4]</code>. This is OK as long as
+ the struct definition has other fields that have at least <code class="type">int32</code>
+ alignment. But it is dangerous to use such a struct definition when
+ working with a potentially unaligned datum; the compiler may take it as
+ license to assume the datum actually is aligned, leading to core dumps on
+ architectures that are strict about alignment.
+ </p></div><p>
+ Another feature that's enabled by <acronym class="acronym">TOAST</acronym> support is the
+ possibility of having an <em class="firstterm">expanded</em> in-memory data
+ representation that is more convenient to work with than the format that
+ is stored on disk. The regular or <span class="quote">“<span class="quote">flat</span>”</span> varlena storage format
+ is ultimately just a blob of bytes; it cannot for example contain
+ pointers, since it may get copied to other locations in memory.
+ For complex data types, the flat format may be quite expensive to work
+ with, so <span class="productname">PostgreSQL</span> provides a way to <span class="quote">“<span class="quote">expand</span>”</span>
+ the flat format into a representation that is more suited to computation,
+ and then pass that format in-memory between functions of the data type.
+ </p><p>
+ To use expanded storage, a data type must define an expanded format that
+ follows the rules given in <code class="filename">src/include/utils/expandeddatum.h</code>,
+ and provide functions to <span class="quote">“<span class="quote">expand</span>”</span> a flat varlena value into
+ expanded format and <span class="quote">“<span class="quote">flatten</span>”</span> the expanded format back to the
+ regular varlena representation. Then ensure that all C functions for
+ the data type can accept either representation, possibly by converting
+ one into the other immediately upon receipt. This does not require fixing
+ all existing functions for the data type at once, because the standard
+ <code class="function">PG_DETOAST_DATUM</code> macro is defined to convert expanded inputs
+ into regular flat format. Therefore, existing functions that work with
+ the flat varlena format will continue to work, though slightly
+ inefficiently, with expanded inputs; they need not be converted until and
+ unless better performance is important.
+ </p><p>
+ C functions that know how to work with an expanded representation
+ typically fall into two categories: those that can only handle expanded
+ format, and those that can handle either expanded or flat varlena inputs.
+ The former are easier to write but may be less efficient overall, because
+ converting a flat input to expanded form for use by a single function may
+ cost more than is saved by operating on the expanded format.
+ When only expanded format need be handled, conversion of flat inputs to
+ expanded form can be hidden inside an argument-fetching macro, so that
+ the function appears no more complex than one working with traditional
+ varlena input.
+ To handle both types of input, write an argument-fetching function that
+ will detoast external, short-header, and compressed varlena inputs, but
+ not expanded inputs. Such a function can be defined as returning a
+ pointer to a union of the flat varlena format and the expanded format.
+ Callers can use the <code class="function">VARATT_IS_EXPANDED_HEADER()</code> macro to
+ determine which format they received.
+ </p><p>
+ The <acronym class="acronym">TOAST</acronym> infrastructure not only allows regular varlena
+ values to be distinguished from expanded values, but also
+ distinguishes <span class="quote">“<span class="quote">read-write</span>”</span> and <span class="quote">“<span class="quote">read-only</span>”</span> pointers to
+ expanded values. C functions that only need to examine an expanded
+ value, or will only change it in safe and non-semantically-visible ways,
+ need not care which type of pointer they receive. C functions that
+ produce a modified version of an input value are allowed to modify an
+ expanded input value in-place if they receive a read-write pointer, but
+ must not modify the input if they receive a read-only pointer; in that
+ case they have to copy the value first, producing a new value to modify.
+ A C function that has constructed a new expanded value should always
+ return a read-write pointer to it. Also, a C function that is modifying
+ a read-write expanded value in-place should take care to leave the value
+ in a sane state if it fails partway through.
+ </p><p>
+ For examples of working with expanded values, see the standard array
+ infrastructure, particularly
+ <code class="filename">src/backend/utils/adt/array_expanded.c</code>.
+ </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="xaggr.html" title="38.12. User-Defined Aggregates">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="extend.html" title="Chapter 38. Extending SQL">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="xoper.html" title="38.14. User-Defined Operators">Next</a></td></tr><tr><td width="40%" align="left" valign="top">38.12. User-Defined Aggregates </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.4 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 38.14. User-Defined Operators</td></tr></table></div></body></html> \ No newline at end of file
diff --git a/doc/src/sgml/images/Makefile b/doc/src/sgml/images/Makefile
new file mode 100644
index 0000000..6455190
--- /dev/null
+++ b/doc/src/sgml/images/Makefile
@@ -0,0 +1,27 @@
+# doc/src/sgml/images/Makefile
+#
+# see README in this directory about image handling
+
+ALL_IMAGES = \
+ genetic-algorithm.svg \
+ gin.svg \
+ pagelayout.svg
+
+DITAA = ditaa
+DOT = dot
+XSLTPROC = xsltproc --nonet
+
+all: $(ALL_IMAGES)
+
+%.svg.tmp: %.gv
+ $(DOT) -T svg -o $@ $<
+
+%.svg.tmp: %.txt
+ $(DITAA) -E -S --svg $< $@
+
+# Post-processing for SVG files coming from other tools
+#
+# Use --novalid to avoid loading SVG DTD if a file specifies it, since
+# it might not be available locally, and we don't need it.
+%.svg: %.svg.tmp fixup-svg.xsl
+ $(XSLTPROC) --novalid -o $@ $(word 2,$^) $<
diff --git a/doc/src/sgml/images/README b/doc/src/sgml/images/README
new file mode 100644
index 0000000..07c4580
--- /dev/null
+++ b/doc/src/sgml/images/README
@@ -0,0 +1,65 @@
+Images
+======
+
+This directory contains images for use in the documentation.
+
+Creating an image
+-----------------
+
+A variety of tools can be used to create an image. The appropriate
+choice depends on the nature of the image. We prefer workflows that
+involve diffable source files.
+
+These tools are acceptable:
+
+- Graphviz (https://graphviz.org/)
+- Ditaa (http://ditaa.sourceforge.net/)
+
+We use SVG as the format for integrating the image into the ultimate
+output formats of the documentation, that is, HTML, PDF, and others.
+Therefore, any tool used needs to be able to produce SVG.
+
+This directory contains makefile rules to build SVG from common input
+formats, using some common styling.
+
+fixup-svg.xsl applies some postprocessing to the SVG files produced by
+those external tools to address assorted issues. See comments in
+there, and adjust and expand as necessary.
+
+Both the source and the SVG output file are committed in this
+directory. That way, we don't need all developers to have all the
+tools installed. While we accept that there could be some gratuitous
+diffs in the SVG output depending the specific tool, let's keep an eye
+on that and keep it to a minimum.
+
+Using an image in DocBook
+-------------------------
+
+Here is an example for using an image in DocBook:
+
+ <figure id="gin-internals-figure">
+ <title>GIN Internals</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/gin.svg" format="SVG" width="100%"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+Notes:
+
+- The real action is in the <mediaobject> element, but typically a
+ <figure> should be wrapped around it and an <xref> to the figure
+ should be put into the text somewhere. Don't just put an image into
+ the documentation without a link to it and an explanation of it.
+
+- Things are set up so that we only need one <imagedata> element, even
+ with different output formats.
+
+- The attribute format="SVG" is required. If you omit it, it will
+ still appear to work, but the stylesheets do a better job if the
+ image is declared as SVG explicitly.
+
+- The width should be set to something. This ensures that the image
+ is scaled to fit the page in PDF output. (Other widths than 100%
+ might be appropriate.)
diff --git a/doc/src/sgml/images/fixup-svg.xsl b/doc/src/sgml/images/fixup-svg.xsl
new file mode 100644
index 0000000..d6c46b3
--- /dev/null
+++ b/doc/src/sgml/images/fixup-svg.xsl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ version="1.0">
+
+<!--
+Transform the SVG produced by various tools, applying assorted fixups.
+-->
+
+<!--
+Add viewBox attribute to svg element if not already present. This allows the
+image to scale.
+-->
+<xsl:template match="svg:svg">
+ <xsl:copy>
+ <xsl:if test="not(@viewBox)">
+ <xsl:attribute name="viewBox">
+ <xsl:text>0 0 </xsl:text>
+ <xsl:value-of select="@width"/>
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@height"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates select="@* | node()"/>
+ </xsl:copy>
+</xsl:template>
+
+<!--
+Fix stroke="transparent" attribute, which is invalid SVG.
+-->
+<xsl:template match="@stroke[.='transparent']">
+ <xsl:attribute name="stroke">none</xsl:attribute>
+</xsl:template>
+
+<!--
+copy everything else
+-->
+<xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()"/>
+ </xsl:copy>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/images/genetic-algorithm.gv b/doc/src/sgml/images/genetic-algorithm.gv
new file mode 100644
index 0000000..80c354c
--- /dev/null
+++ b/doc/src/sgml/images/genetic-algorithm.gv
@@ -0,0 +1,48 @@
+digraph {
+ layout=dot;
+
+ // default values
+ node [shape=box, label="", fontname="sans-serif", style=filled, fillcolor=white, fontsize=8];
+ graph [fontname="sans-serif"]; // must be specified separately
+ edge [fontname="sans-serif"]; // must be specified separately
+
+ // an unobtrusive background color
+ pad="1.0, 0.5";
+ bgcolor=whitesmoke;
+
+ // layout of edges and nodes
+ splines=ortho;
+ nodesep=0.3;
+ ranksep=0.3;
+
+ // nodes
+ a1[label="INITIALIZE t := 0"];
+ a2[label="INITIALIZE P(t)"];
+ a3[label="evaluate FITNESS of P(t)"];
+ a4[shape="diamond", label="STOPPING CRITERION"; width=4];
+
+ // connect 'end' node with 'a9' node (bottom of figure)
+ {
+ rank=same;
+ a9[label="t := t + 1"];
+ // end-symbol similar to UML notation
+ end[shape=doublecircle, label="end", width=0.5];
+ }
+
+ a5[label="P'(t) := RECOMBINATION{P(t)}"];
+ a6[label="P''(t) := MUTATION{P'(t)}"];
+ a7[label="P(t+1) := SELECTION{P''(t) + P(t)}"];
+ a8[label="evaluate FITNESS of P''(t)"];
+
+ // edges
+ a1 -> a2 -> a3 -> a4;
+ a4 -> a5[xlabel="false ", fontsize=10];
+ a4 -> end[xlabel="true ", fontsize=10];
+ a5 -> a6 -> a7 -> a8 -> a9;
+ a4 -> a9 [dir=back];
+
+ // explain the notation
+ expl [shape=plaintext, fontsize=10, width=3.2, fillcolor=whitesmoke,
+ label="P(t): generation of ancestors at a time t\lP''(t): generation of descendants at a time t\l"];
+
+}
diff --git a/doc/src/sgml/images/genetic-algorithm.svg b/doc/src/sgml/images/genetic-algorithm.svg
new file mode 100644
index 0000000..fb9fdd1
--- /dev/null
+++ b/doc/src/sgml/images/genetic-algorithm.svg
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: %3 Pages: 1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="583pt" height="580pt" viewBox="0.00 0.00 583.00 580.30">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(72 544.3026)">
+<title>%3</title>
+<polygon fill="#f5f5f5" stroke="none" points="-72,36 -72,-544.3026 511,-544.3026 511,36 -72,36"/>
+<!-- a1 -->
+<g id="node1" class="node">
+<title>a1</title>
+<polygon fill="#ffffff" stroke="#000000" points="187,-508.3026 101,-508.3026 101,-472.3026 187,-472.3026 187,-508.3026"/>
+<text text-anchor="middle" x="144" y="-488.4026" font-family="sans-serif" font-size="8.00" fill="#000000">INITIALIZE t := 0</text>
+</g>
+<!-- a2 -->
+<g id="node2" class="node">
+<title>a2</title>
+<polygon fill="#ffffff" stroke="#000000" points="182,-450.3026 106,-450.3026 106,-414.3026 182,-414.3026 182,-450.3026"/>
+<text text-anchor="middle" x="144" y="-430.4026" font-family="sans-serif" font-size="8.00" fill="#000000">INITIALIZE P(t)</text>
+</g>
+<!-- a1&#45;&gt;a2 -->
+<g id="edge1" class="edge">
+<title>a1-&gt;a2</title>
+<path fill="none" stroke="#000000" d="M144,-472.269C144,-472.269 144,-460.5248 144,-460.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-460.5248 144,-450.5248 140.5001,-460.5249 147.5001,-460.5248"/>
+</g>
+<!-- a3 -->
+<g id="node3" class="node">
+<title>a3</title>
+<polygon fill="#ffffff" stroke="#000000" points="203.5,-392.3026 84.5,-392.3026 84.5,-356.3026 203.5,-356.3026 203.5,-392.3026"/>
+<text text-anchor="middle" x="144" y="-372.4026" font-family="sans-serif" font-size="8.00" fill="#000000">evaluate FITNESS of P(t)</text>
+</g>
+<!-- a2&#45;&gt;a3 -->
+<g id="edge2" class="edge">
+<title>a2-&gt;a3</title>
+<path fill="none" stroke="#000000" d="M144,-414.269C144,-414.269 144,-402.5248 144,-402.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-402.5248 144,-392.5248 140.5001,-402.5249 147.5001,-402.5248"/>
+</g>
+<!-- a4 -->
+<g id="node4" class="node">
+<title>a4</title>
+<polygon fill="#ffffff" stroke="#000000" points="144,-334.3026 0,-316.3026 144,-298.3026 288,-316.3026 144,-334.3026"/>
+<text text-anchor="middle" x="144" y="-314.4026" font-family="sans-serif" font-size="8.00" fill="#000000">STOPPING CRITERION</text>
+</g>
+<!-- a3&#45;&gt;a4 -->
+<g id="edge3" class="edge">
+<title>a3-&gt;a4</title>
+<path fill="none" stroke="#000000" d="M144,-356.269C144,-356.269 144,-344.5248 144,-344.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-344.5248 144,-334.5248 140.5001,-344.5249 147.5001,-344.5248"/>
+</g>
+<!-- a9 -->
+<g id="node5" class="node">
+<title>a9</title>
+<polygon fill="#ffffff" stroke="#000000" points="106,-40.1513 50,-40.1513 50,-4.1513 106,-4.1513 106,-40.1513"/>
+<text text-anchor="middle" x="78" y="-20.2513" font-family="sans-serif" font-size="8.00" fill="#000000">t := t + 1</text>
+</g>
+<!-- a4&#45;&gt;a9 -->
+<g id="edge10" class="edge">
+<title>a4-&gt;a9</title>
+<path fill="none" stroke="#000000" d="M56.75,-299.0314C56.75,-299.0314 56.75,-40.524 56.75,-40.524"/>
+<polygon fill="#000000" stroke="#000000" points="53.2501,-299.0314 56.75,-309.0314 60.2501,-299.0314 53.2501,-299.0314"/>
+</g>
+<!-- end -->
+<g id="node6" class="node">
+<title>end</title>
+<ellipse fill="#ffffff" stroke="#000000" cx="259" cy="-22.1513" rx="18.2761" ry="18.2761"/>
+<ellipse fill="none" stroke="#000000" cx="259" cy="-22.1513" rx="22.3036" ry="22.3036"/>
+<text text-anchor="middle" x="259" y="-20.2513" font-family="sans-serif" font-size="8.00" fill="#000000">end</text>
+</g>
+<!-- a4&#45;&gt;end -->
+<g id="edge5" class="edge">
+<title>a4-&gt;end</title>
+<path fill="none" stroke="#000000" d="M259,-312.5834C259,-312.5834 259,-54.659 259,-54.659"/>
+<polygon fill="#000000" stroke="#000000" points="262.5001,-54.659 259,-44.659 255.5001,-54.6591 262.5001,-54.659"/>
+<text text-anchor="middle" x="246" y="-186.6212" font-family="sans-serif" font-size="10.00" fill="#000000">true  </text>
+</g>
+<!-- a5 -->
+<g id="node7" class="node">
+<title>a5</title>
+<polygon fill="#ffffff" stroke="#000000" points="216,-276.3026 72,-276.3026 72,-240.3026 216,-240.3026 216,-276.3026"/>
+<text text-anchor="middle" x="144" y="-256.4026" font-family="sans-serif" font-size="8.00" fill="#000000">P'(t) := RECOMBINATION{P(t)}</text>
+</g>
+<!-- a4&#45;&gt;a5 -->
+<g id="edge4" class="edge">
+<title>a4-&gt;a5</title>
+<path fill="none" stroke="#000000" d="M144,-298.269C144,-298.269 144,-286.5248 144,-286.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-286.5248 144,-276.5248 140.5001,-286.5249 147.5001,-286.5248"/>
+<text text-anchor="middle" x="127" y="-284.3969" font-family="sans-serif" font-size="10.00" fill="#000000">false   </text>
+</g>
+<!-- a6 -->
+<g id="node8" class="node">
+<title>a6</title>
+<polygon fill="#ffffff" stroke="#000000" points="204.5,-218.3026 83.5,-218.3026 83.5,-182.3026 204.5,-182.3026 204.5,-218.3026"/>
+<text text-anchor="middle" x="144" y="-198.4026" font-family="sans-serif" font-size="8.00" fill="#000000">P''(t) := MUTATION{P'(t)}</text>
+</g>
+<!-- a5&#45;&gt;a6 -->
+<g id="edge6" class="edge">
+<title>a5-&gt;a6</title>
+<path fill="none" stroke="#000000" d="M144,-240.269C144,-240.269 144,-228.5248 144,-228.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-228.5248 144,-218.5248 140.5001,-228.5249 147.5001,-228.5248"/>
+</g>
+<!-- a7 -->
+<g id="node9" class="node">
+<title>a7</title>
+<polygon fill="#ffffff" stroke="#000000" points="224.5,-160.3026 63.5,-160.3026 63.5,-124.3026 224.5,-124.3026 224.5,-160.3026"/>
+<text text-anchor="middle" x="144" y="-140.4026" font-family="sans-serif" font-size="8.00" fill="#000000">P(t+1) := SELECTION{P''(t) + P(t)}</text>
+</g>
+<!-- a6&#45;&gt;a7 -->
+<g id="edge7" class="edge">
+<title>a6-&gt;a7</title>
+<path fill="none" stroke="#000000" d="M144,-182.269C144,-182.269 144,-170.5248 144,-170.5248"/>
+<polygon fill="#000000" stroke="#000000" points="147.5001,-170.5248 144,-160.5248 140.5001,-170.5249 147.5001,-170.5248"/>
+</g>
+<!-- a8 -->
+<g id="node10" class="node">
+<title>a8</title>
+<polygon fill="#ffffff" stroke="#000000" points="196.5,-102.3026 73.5,-102.3026 73.5,-66.3026 196.5,-66.3026 196.5,-102.3026"/>
+<text text-anchor="middle" x="135" y="-82.4026" font-family="sans-serif" font-size="8.00" fill="#000000">evaluate FITNESS of P''(t)</text>
+</g>
+<!-- a7&#45;&gt;a8 -->
+<g id="edge8" class="edge">
+<title>a7-&gt;a8</title>
+<path fill="none" stroke="#000000" d="M135,-124.269C135,-124.269 135,-112.5248 135,-112.5248"/>
+<polygon fill="#000000" stroke="#000000" points="138.5001,-112.5248 135,-102.5248 131.5001,-112.5249 138.5001,-112.5248"/>
+</g>
+<!-- a8&#45;&gt;a9 -->
+<g id="edge9" class="edge">
+<title>a8-&gt;a9</title>
+<path fill="none" stroke="#000000" d="M89.75,-65.9913C89.75,-65.9913 89.75,-50.5465 89.75,-50.5465"/>
+<polygon fill="#000000" stroke="#000000" points="93.2501,-50.5464 89.75,-40.5465 86.2501,-50.5465 93.2501,-50.5464"/>
+</g>
+<!-- expl -->
+<g id="node11" class="node">
+<title>expl</title>
+<polygon fill="#f5f5f5" stroke="none" points="439,-508.3026 209,-508.3026 209,-472.3026 439,-472.3026 439,-508.3026"/>
+<text text-anchor="start" x="217" y="-493.3026" font-family="sans-serif" font-size="10.00" fill="#000000">P(t): generation of ancestors at a time t</text>
+<text text-anchor="start" x="217" y="-482.3026" font-family="sans-serif" font-size="10.00" fill="#000000">P''(t): generation of descendants at a time t</text>
+</g>
+</g>
+</svg>
diff --git a/doc/src/sgml/images/gin.gv b/doc/src/sgml/images/gin.gv
new file mode 100644
index 0000000..097e910
--- /dev/null
+++ b/doc/src/sgml/images/gin.gv
@@ -0,0 +1,93 @@
+digraph "gin" {
+ layout=dot;
+ node [label="", shape=box, style=filled, fillcolor=gray, width=1.4];
+
+ m1 [label="meta page"];
+
+ subgraph cluster01 {
+ label="entry tree";
+ subgraph egroup1 {
+ rank=same;
+ e1;
+ }
+ subgraph egroup2 {
+ rank=same;
+ e2 -> e3 -> e4;
+ }
+ subgraph egroup3 {
+ rank=same;
+ e5 -> e6 -> e7 -> e8 -> e9;
+ }
+ e1 -> e4;
+ e1 -> e3;
+ e1 -> e2;
+ e2 -> e5;
+ e2 -> e6;
+ e3 -> e7;
+ e4 -> e8;
+ e4 -> e9;
+
+ e6 [fillcolor=green, label="posting list"];
+ e8 [fillcolor=green, label="posting list"];
+ e9 [fillcolor=green, label="posting list"];
+ }
+
+ subgraph cluster02 {
+ label="posting tree";
+ subgraph pgroup1 {
+ rank=same;
+ p1;
+ }
+ subgraph pgroup2 {
+ rank=same;
+ p2 -> p3;
+ }
+ p1 -> p2;
+ p1 -> p3;
+
+ p2 [fillcolor=green, label="heap ptr"];
+ p3 [fillcolor=green, label="heap ptr"];
+ }
+
+ subgraph cluster03 {
+ label="posting tree";
+ subgraph pgroup3 {
+ rank=same;
+ p4;
+ }
+
+ p4 [fillcolor=green, label="heap ptr"];
+ }
+
+ subgraph cluster04 {
+ label="posting tree";
+ subgraph pgroup4 {
+ rank=same;
+ p5;
+ }
+ subgraph pgroup5 {
+ rank=same;
+ p6 -> p7;
+ }
+ p5 -> p6;
+ p5 -> p7;
+
+ p6 [fillcolor=green, label="heap ptr"];
+ p7 [fillcolor=green, label="heap ptr"];
+ }
+
+ subgraph cluster05 {
+ label="pending list";
+ node [style=filled, fillcolor=red];
+ n1 -> n2 -> n3 -> n4;
+ }
+
+ m1 -> e1;
+ e5 -> p1;
+ e7 -> p4;
+ e7 -> p5;
+ m1 -> n1;
+
+ e5 [style=filled, fillcolor=green4];
+ e7 [style=filled, fillcolor=green4];
+}
diff --git a/doc/src/sgml/images/gin.svg b/doc/src/sgml/images/gin.svg
new file mode 100644
index 0000000..04fe85b
--- /dev/null
+++ b/doc/src/sgml/images/gin.svg
@@ -0,0 +1,317 @@
+<?xml version="1.0"?>
+<!-- Generated by graphviz version 2.40.1 (20161225.0304)
+ -->
+<!-- Title: gin Pages: 1 -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="836pt" height="432pt" viewBox="0.00 0.00 836.00 432.00">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 428)">
+<title>gin</title>
+<polygon fill="#ffffff" stroke="none" points="-4,4 -4,-428 832,-428 832,4 -4,4"/>
+<g id="clust1" class="cluster">
+<title>cluster01</title>
+<polygon fill="none" stroke="#000000" points="100,-162 100,-380 694,-380 694,-162 100,-162"/>
+<text text-anchor="middle" x="397" y="-364.8" font-family="Times,serif" font-size="14.00" fill="#000000">entry tree</text>
+</g>
+<g id="clust5" class="cluster">
+<title>cluster02</title>
+<polygon fill="none" stroke="#000000" points="8,-8 8,-154 245,-154 245,-8 8,-8"/>
+<text text-anchor="middle" x="126.5" y="-138.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting tree</text>
+</g>
+<g id="clust8" class="cluster">
+<title>cluster03</title>
+<polygon fill="none" stroke="#000000" points="279,-80 279,-154 397,-154 397,-80 279,-80"/>
+<text text-anchor="middle" x="338" y="-138.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting tree</text>
+</g>
+<g id="clust10" class="cluster">
+<title>cluster04</title>
+<polygon fill="none" stroke="#000000" points="405,-8 405,-154 642,-154 642,-8 405,-8"/>
+<text text-anchor="middle" x="523.5" y="-138.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting tree</text>
+</g>
+<g id="clust13" class="cluster">
+<title>cluster05</title>
+<polygon fill="none" stroke="#000000" points="702,-80 702,-380 820,-380 820,-80 702,-80"/>
+<text text-anchor="middle" x="761" y="-364.8" font-family="Times,serif" font-size="14.00" fill="#000000">pending list</text>
+</g>
+<!-- m1 -->
+<g id="node1" class="node">
+<title>m1</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="688.5,-424 587.5,-424 587.5,-388 688.5,-388 688.5,-424"/>
+<text text-anchor="middle" x="638" y="-401.8" font-family="Times,serif" font-size="14.00" fill="#000000">meta page</text>
+</g>
+<!-- e1 -->
+<g id="node2" class="node">
+<title>e1</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="506.5,-350 405.5,-350 405.5,-314 506.5,-314 506.5,-350"/>
+</g>
+<!-- m1&#45;&gt;e1 -->
+<g id="edge24" class="edge">
+<title>m1-&gt;e1</title>
+<path fill="none" stroke="#000000" d="M593.4778,-387.8976C568.2655,-377.6464 536.5468,-364.7498 509.931,-353.928"/>
+<polygon fill="#000000" stroke="#000000" points="510.9595,-350.568 500.3776,-350.0436 508.3229,-357.0525 510.9595,-350.568"/>
+</g>
+<!-- n1 -->
+<g id="node18" class="node">
+<title>n1</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-350 710.5,-350 710.5,-314 811.5,-314 811.5,-350"/>
+</g>
+<!-- m1&#45;&gt;n1 -->
+<g id="edge28" class="edge">
+<title>m1-&gt;n1</title>
+<path fill="none" stroke="#000000" d="M683.1514,-387.8551C688.2504,-385.3905 693.2983,-382.7547 698,-380 709.7018,-373.1438 721.7385,-364.4455 732.115,-356.3423"/>
+<polygon fill="#000000" stroke="#000000" points="734.4083,-358.9902 740.0427,-350.0178 730.0428,-353.5181 734.4083,-358.9902"/>
+</g>
+<!-- e2 -->
+<g id="node3" class="node">
+<title>e2</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="328.5,-278 227.5,-278 227.5,-242 328.5,-242 328.5,-278"/>
+</g>
+<!-- e1&#45;&gt;e2 -->
+<g id="edge9" class="edge">
+<title>e1-&gt;e2</title>
+<path fill="none" stroke="#000000" d="M411.0831,-313.8314C387.065,-304.1162 357.3166,-292.0831 332.0408,-281.8592"/>
+<polygon fill="#000000" stroke="#000000" points="333.1767,-278.5432 322.5939,-278.038 330.5518,-285.0325 333.1767,-278.5432"/>
+</g>
+<!-- e3 -->
+<g id="node4" class="node">
+<title>e3</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="447.5,-278 346.5,-278 346.5,-242 447.5,-242 447.5,-278"/>
+</g>
+<!-- e1&#45;&gt;e3 -->
+<g id="edge8" class="edge">
+<title>e1-&gt;e3</title>
+<path fill="none" stroke="#000000" d="M441.1118,-313.8314C434.247,-305.454 425.9699,-295.3531 418.4489,-286.1749"/>
+<polygon fill="#000000" stroke="#000000" points="421.1341,-283.9297 412.0886,-278.4133 415.7197,-288.3665 421.1341,-283.9297"/>
+</g>
+<!-- e4 -->
+<g id="node5" class="node">
+<title>e4</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="566.5,-278 465.5,-278 465.5,-242 566.5,-242 566.5,-278"/>
+</g>
+<!-- e1&#45;&gt;e4 -->
+<g id="edge7" class="edge">
+<title>e1-&gt;e4</title>
+<path fill="none" stroke="#000000" d="M471.1405,-313.8314C478.1217,-305.454 486.5391,-295.3531 494.1876,-286.1749"/>
+<polygon fill="#000000" stroke="#000000" points="496.9425,-288.3362 500.6556,-278.4133 491.5649,-283.8548 496.9425,-288.3362"/>
+</g>
+<!-- e2&#45;&gt;e3 -->
+<g id="edge1" class="edge">
+<title>e2-&gt;e3</title>
+<path fill="none" stroke="#000000" d="M328.668,-260C331.1453,-260 333.6227,-260 336.1001,-260"/>
+<polygon fill="#000000" stroke="#000000" points="336.2849,-263.5001 346.2848,-260 336.2848,-256.5001 336.2849,-263.5001"/>
+</g>
+<!-- e5 -->
+<g id="node6" class="node">
+<title>e5</title>
+<polygon fill="#008b00" stroke="#000000" points="209.5,-206 108.5,-206 108.5,-170 209.5,-170 209.5,-206"/>
+</g>
+<!-- e2&#45;&gt;e5 -->
+<g id="edge10" class="edge">
+<title>e2-&gt;e5</title>
+<path fill="none" stroke="#000000" d="M247.9713,-241.8314C232.7504,-232.6221 214.0872,-221.3301 197.7917,-211.4706"/>
+<polygon fill="#000000" stroke="#000000" points="199.3868,-208.345 189.0191,-206.1628 195.7631,-214.3341 199.3868,-208.345"/>
+</g>
+<!-- e6 -->
+<g id="node7" class="node">
+<title>e6</title>
+<polygon fill="#00ff00" stroke="#000000" points="328.5,-206 227.5,-206 227.5,-170 328.5,-170 328.5,-206"/>
+<text text-anchor="middle" x="278" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting list</text>
+</g>
+<!-- e2&#45;&gt;e6 -->
+<g id="edge11" class="edge">
+<title>e2-&gt;e6</title>
+<path fill="none" stroke="#000000" d="M278,-241.8314C278,-234.131 278,-224.9743 278,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="281.5001,-216.4132 278,-206.4133 274.5001,-216.4133 281.5001,-216.4132"/>
+</g>
+<!-- e3&#45;&gt;e4 -->
+<g id="edge2" class="edge">
+<title>e3-&gt;e4</title>
+<path fill="none" stroke="#000000" d="M447.668,-260C450.1453,-260 452.6227,-260 455.1001,-260"/>
+<polygon fill="#000000" stroke="#000000" points="455.2849,-263.5001 465.2848,-260 455.2848,-256.5001 455.2849,-263.5001"/>
+</g>
+<!-- e7 -->
+<g id="node8" class="node">
+<title>e7</title>
+<polygon fill="#008b00" stroke="#000000" points="447.5,-206 346.5,-206 346.5,-170 447.5,-170 447.5,-206"/>
+</g>
+<!-- e3&#45;&gt;e7 -->
+<g id="edge12" class="edge">
+<title>e3-&gt;e7</title>
+<path fill="none" stroke="#000000" d="M397,-241.8314C397,-234.131 397,-224.9743 397,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="400.5001,-216.4132 397,-206.4133 393.5001,-216.4133 400.5001,-216.4132"/>
+</g>
+<!-- e8 -->
+<g id="node9" class="node">
+<title>e8</title>
+<polygon fill="#00ff00" stroke="#000000" points="566.5,-206 465.5,-206 465.5,-170 566.5,-170 566.5,-206"/>
+<text text-anchor="middle" x="516" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting list</text>
+</g>
+<!-- e4&#45;&gt;e8 -->
+<g id="edge13" class="edge">
+<title>e4-&gt;e8</title>
+<path fill="none" stroke="#000000" d="M516,-241.8314C516,-234.131 516,-224.9743 516,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="519.5001,-216.4132 516,-206.4133 512.5001,-216.4133 519.5001,-216.4132"/>
+</g>
+<!-- e9 -->
+<g id="node10" class="node">
+<title>e9</title>
+<polygon fill="#00ff00" stroke="#000000" points="685.5,-206 584.5,-206 584.5,-170 685.5,-170 685.5,-206"/>
+<text text-anchor="middle" x="635" y="-183.8" font-family="Times,serif" font-size="14.00" fill="#000000">posting list</text>
+</g>
+<!-- e4&#45;&gt;e9 -->
+<g id="edge14" class="edge">
+<title>e4-&gt;e9</title>
+<path fill="none" stroke="#000000" d="M546.0287,-241.8314C561.2496,-232.6221 579.9128,-221.3301 596.2083,-211.4706"/>
+<polygon fill="#000000" stroke="#000000" points="598.2369,-214.3341 604.9809,-206.1628 594.6132,-208.345 598.2369,-214.3341"/>
+</g>
+<!-- e5&#45;&gt;e6 -->
+<g id="edge3" class="edge">
+<title>e5-&gt;e6</title>
+<path fill="none" stroke="#000000" d="M209.668,-188C212.1453,-188 214.6227,-188 217.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="217.2849,-191.5001 227.2848,-188 217.2848,-184.5001 217.2849,-191.5001"/>
+</g>
+<!-- p1 -->
+<g id="node11" class="node">
+<title>p1</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="209.5,-124 108.5,-124 108.5,-88 209.5,-88 209.5,-124"/>
+</g>
+<!-- e5&#45;&gt;p1 -->
+<g id="edge25" class="edge">
+<title>e5-&gt;p1</title>
+<path fill="none" stroke="#000000" d="M159,-169.8015C159,-159.3976 159,-146.1215 159,-134.3768"/>
+<polygon fill="#000000" stroke="#000000" points="162.5001,-134.1476 159,-124.1476 155.5001,-134.1476 162.5001,-134.1476"/>
+</g>
+<!-- e6&#45;&gt;e7 -->
+<g id="edge4" class="edge">
+<title>e6-&gt;e7</title>
+<path fill="none" stroke="#000000" d="M328.668,-188C331.1453,-188 333.6227,-188 336.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="336.2849,-191.5001 346.2848,-188 336.2848,-184.5001 336.2849,-191.5001"/>
+</g>
+<!-- e7&#45;&gt;e8 -->
+<g id="edge5" class="edge">
+<title>e7-&gt;e8</title>
+<path fill="none" stroke="#000000" d="M447.668,-188C450.1453,-188 452.6227,-188 455.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="455.2849,-191.5001 465.2848,-188 455.2848,-184.5001 455.2849,-191.5001"/>
+</g>
+<!-- p4 -->
+<g id="node14" class="node">
+<title>p4</title>
+<polygon fill="#00ff00" stroke="#000000" points="388.5,-124 287.5,-124 287.5,-88 388.5,-88 388.5,-124"/>
+<text text-anchor="middle" x="338" y="-101.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- e7&#45;&gt;p4 -->
+<g id="edge26" class="edge">
+<title>e7-&gt;p4</title>
+<path fill="none" stroke="#000000" d="M383.906,-169.8015C376.0383,-158.8668 365.8878,-144.7593 357.133,-132.5916"/>
+<polygon fill="#000000" stroke="#000000" points="359.7389,-130.2207 351.0574,-124.1476 354.0569,-134.309 359.7389,-130.2207"/>
+</g>
+<!-- p5 -->
+<g id="node15" class="node">
+<title>p5</title>
+<polygon fill="#c0c0c0" stroke="#000000" points="514.5,-124 413.5,-124 413.5,-88 514.5,-88 514.5,-124"/>
+</g>
+<!-- e7&#45;&gt;p5 -->
+<g id="edge27" class="edge">
+<title>e7-&gt;p5</title>
+<path fill="none" stroke="#000000" d="M411.8695,-169.8015C420.8907,-158.7606 432.5549,-144.4851 442.5618,-132.2378"/>
+<polygon fill="#000000" stroke="#000000" points="445.5552,-134.1059 449.1721,-124.1476 440.1345,-129.6768 445.5552,-134.1059"/>
+</g>
+<!-- e8&#45;&gt;e9 -->
+<g id="edge6" class="edge">
+<title>e8-&gt;e9</title>
+<path fill="none" stroke="#000000" d="M566.668,-188C569.1453,-188 571.6227,-188 574.1001,-188"/>
+<polygon fill="#000000" stroke="#000000" points="574.2849,-191.5001 584.2848,-188 574.2848,-184.5001 574.2849,-191.5001"/>
+</g>
+<!-- p2 -->
+<g id="node12" class="node">
+<title>p2</title>
+<polygon fill="#00ff00" stroke="#000000" points="117.5,-52 16.5,-52 16.5,-16 117.5,-16 117.5,-52"/>
+<text text-anchor="middle" x="67" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p1&#45;&gt;p2 -->
+<g id="edge16" class="edge">
+<title>p1-&gt;p2</title>
+<path fill="none" stroke="#000000" d="M135.7845,-87.8314C124.453,-78.9632 110.6536,-68.1637 98.3973,-58.5718"/>
+<polygon fill="#000000" stroke="#000000" points="100.2402,-55.5697 90.2081,-52.1628 95.926,-61.0822 100.2402,-55.5697"/>
+</g>
+<!-- p3 -->
+<g id="node13" class="node">
+<title>p3</title>
+<polygon fill="#00ff00" stroke="#000000" points="236.5,-52 135.5,-52 135.5,-16 236.5,-16 236.5,-52"/>
+<text text-anchor="middle" x="186" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p1&#45;&gt;p3 -->
+<g id="edge17" class="edge">
+<title>p1-&gt;p3</title>
+<path fill="none" stroke="#000000" d="M165.8132,-87.8314C168.7644,-79.9617 172.2858,-70.5712 175.555,-61.8533"/>
+<polygon fill="#000000" stroke="#000000" points="178.8609,-63.0055 179.095,-52.4133 172.3066,-60.5476 178.8609,-63.0055"/>
+</g>
+<!-- p2&#45;&gt;p3 -->
+<g id="edge15" class="edge">
+<title>p2-&gt;p3</title>
+<path fill="none" stroke="#000000" d="M117.668,-34C120.1453,-34 122.6227,-34 125.1001,-34"/>
+<polygon fill="#000000" stroke="#000000" points="125.2849,-37.5001 135.2848,-34 125.2848,-30.5001 125.2849,-37.5001"/>
+</g>
+<!-- p6 -->
+<g id="node16" class="node">
+<title>p6</title>
+<polygon fill="#00ff00" stroke="#000000" points="514.5,-52 413.5,-52 413.5,-16 514.5,-16 514.5,-52"/>
+<text text-anchor="middle" x="464" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p5&#45;&gt;p6 -->
+<g id="edge19" class="edge">
+<title>p5-&gt;p6</title>
+<path fill="none" stroke="#000000" d="M464,-87.8314C464,-80.131 464,-70.9743 464,-62.4166"/>
+<polygon fill="#000000" stroke="#000000" points="467.5001,-62.4132 464,-52.4133 460.5001,-62.4133 467.5001,-62.4132"/>
+</g>
+<!-- p7 -->
+<g id="node17" class="node">
+<title>p7</title>
+<polygon fill="#00ff00" stroke="#000000" points="633.5,-52 532.5,-52 532.5,-16 633.5,-16 633.5,-52"/>
+<text text-anchor="middle" x="583" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">heap ptr</text>
+</g>
+<!-- p5&#45;&gt;p7 -->
+<g id="edge20" class="edge">
+<title>p5-&gt;p7</title>
+<path fill="none" stroke="#000000" d="M494.0287,-87.8314C509.2496,-78.6221 527.9128,-67.3301 544.2083,-57.4706"/>
+<polygon fill="#000000" stroke="#000000" points="546.2369,-60.3341 552.9809,-52.1628 542.6132,-54.345 546.2369,-60.3341"/>
+</g>
+<!-- p6&#45;&gt;p7 -->
+<g id="edge18" class="edge">
+<title>p6-&gt;p7</title>
+<path fill="none" stroke="#000000" d="M514.668,-34C517.1453,-34 519.6227,-34 522.1001,-34"/>
+<polygon fill="#000000" stroke="#000000" points="522.2849,-37.5001 532.2848,-34 522.2848,-30.5001 522.2849,-37.5001"/>
+</g>
+<!-- n2 -->
+<g id="node19" class="node">
+<title>n2</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-278 710.5,-278 710.5,-242 811.5,-242 811.5,-278"/>
+</g>
+<!-- n1&#45;&gt;n2 -->
+<g id="edge21" class="edge">
+<title>n1-&gt;n2</title>
+<path fill="none" stroke="#000000" d="M761,-313.8314C761,-306.131 761,-296.9743 761,-288.4166"/>
+<polygon fill="#000000" stroke="#000000" points="764.5001,-288.4132 761,-278.4133 757.5001,-288.4133 764.5001,-288.4132"/>
+</g>
+<!-- n3 -->
+<g id="node20" class="node">
+<title>n3</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-206 710.5,-206 710.5,-170 811.5,-170 811.5,-206"/>
+</g>
+<!-- n2&#45;&gt;n3 -->
+<g id="edge22" class="edge">
+<title>n2-&gt;n3</title>
+<path fill="none" stroke="#000000" d="M761,-241.8314C761,-234.131 761,-224.9743 761,-216.4166"/>
+<polygon fill="#000000" stroke="#000000" points="764.5001,-216.4132 761,-206.4133 757.5001,-216.4133 764.5001,-216.4132"/>
+</g>
+<!-- n4 -->
+<g id="node21" class="node">
+<title>n4</title>
+<polygon fill="#ff0000" stroke="#000000" points="811.5,-124 710.5,-124 710.5,-88 811.5,-88 811.5,-124"/>
+</g>
+<!-- n3&#45;&gt;n4 -->
+<g id="edge23" class="edge">
+<title>n3-&gt;n4</title>
+<path fill="none" stroke="#000000" d="M761,-169.8015C761,-159.3976 761,-146.1215 761,-134.3768"/>
+<polygon fill="#000000" stroke="#000000" points="764.5001,-134.1476 761,-124.1476 757.5001,-134.1476 764.5001,-134.1476"/>
+</g>
+</g>
+</svg>
diff --git a/doc/src/sgml/images/pagelayout.svg b/doc/src/sgml/images/pagelayout.svg
new file mode 100644
index 0000000..5b2caaf
--- /dev/null
+++ b/doc/src/sgml/images/pagelayout.svg
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 610 210" width="610" height="210" shape-rendering="geometricPrecision" version="1.0">
+ <defs>
+ <filter id="f2" x="0" y="0" width="200%" height="200%">
+ <feOffset result="offOut" in="SourceGraphic" dx="5" dy="5"/>
+ <feGaussianBlur result="blurOut" in="offOut" stdDeviation="3"/>
+ <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
+ </filter>
+ </defs>
+ <g stroke-width="1" stroke-linecap="square" stroke-linejoin="round">
+ <rect x="0" y="0" width="610" height="210" style="fill: #ffffff"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M25.0 35.0 L25.0 175.0 L585.0 175.0 L585.0 35.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M305.0 175.0 L485.0 175.0 L485.0 147.0 L305.0 147.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M25.0 35.0 L25.0 63.0 L195.0 63.0 L195.0 35.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M305.0 147.0 L305.0 175.0 L195.0 175.0 L195.0 147.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M325.0 63.0 L325.0 91.0 L265.0 91.0 L265.0 105.0 L235.0 105.0 L235.0 63.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M585.0 147.0 L585.0 175.0 L485.0 175.0 L485.0 147.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M195.0 35.0 L285.0 35.0 L285.0 63.0 L195.0 63.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="white" d="M375.0 35.0 L375.0 63.0 L285.0 63.0 L285.0 35.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M335.0 133.0 L335.0 105.0 L265.0 105.0 "/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M470.0 42.0 L480.0 49.0 L470.0 56.0 z"/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M260.0 126.0 L265.0 140.0 L270.0 126.0 z"/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M330.0 126.0 L335.0 140.0 L340.0 126.0 z"/>
+ <path stroke="none" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="#000000" d="M140.0 154.0 L130.0 161.0 L140.0 168.0 z"/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-linecap="round" stroke-linejoin="round" fill="none" d="M265.0 105.0 L265.0 133.0 "/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-dasharray="5.000000,5.000000" stroke-miterlimit="0" stroke-linecap="butt" stroke-linejoin="round" fill="white" d="M375.0 49.0 L475.0 49.0 "/>
+ <path stroke="#000000" stroke-width="1.000000" stroke-dasharray="5.000000,5.000000" stroke-miterlimit="0" stroke-linecap="butt" stroke-linejoin="round" fill="white" d="M135.0 161.0 L195.0 161.0 "/>
+ <text x="48" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">PageHeaderData</text>
+ <text x="214" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">Item</text>
+ <text x="216" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">ItemId</text>
+ <text x="306" y="54" font-family="Courier" font-size="15" stroke="none" fill="#000000">ItemId</text>
+ <text x="324" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">Item</text>
+ <text x="509" y="166" font-family="Courier" font-size="15" stroke="none" fill="#000000">Special</text>
+ </g>
+</svg>
diff --git a/doc/src/sgml/images/pagelayout.txt b/doc/src/sgml/images/pagelayout.txt
new file mode 100644
index 0000000..40bee5d
--- /dev/null
+++ b/doc/src/sgml/images/pagelayout.txt
@@ -0,0 +1,11 @@
++----------------+--------+--------+--------------------+
+| PageHeaderData | ItemId | ItemId +=--------> |
++----------------+---+----+---+----+ |
+| | | |
+| | +-----+ |
+| +--+------+ |
+| | | |
+| v v |
+| +----------+-----------------+---------+
+| <----=+ Item | Item | Special |
++----------------+----------+-----------------+---------+
diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml
new file mode 100644
index 0000000..4f83970
--- /dev/null
+++ b/doc/src/sgml/indexam.sgml
@@ -0,0 +1,1486 @@
+<!-- doc/src/sgml/indexam.sgml -->
+
+<chapter id="indexam">
+ <title>Index Access Method Interface Definition</title>
+
+ <indexterm>
+ <primary>Index Access Method</primary>
+ </indexterm>
+ <indexterm>
+ <primary>indexam</primary>
+ <secondary>Index Access Method</secondary>
+ </indexterm>
+
+ <para>
+ This chapter defines the interface between the core
+ <productname>PostgreSQL</productname> system and <firstterm>index access
+ methods</firstterm>, which manage individual index types. The core system
+ knows nothing about indexes beyond what is specified here, so it is
+ possible to develop entirely new index types by writing add-on code.
+ </para>
+
+ <para>
+ All indexes in <productname>PostgreSQL</productname> are what are known
+ technically as <firstterm>secondary indexes</firstterm>; that is, the index is
+ physically separate from the table file that it describes. Each index
+ is stored as its own physical <firstterm>relation</firstterm> and so is described
+ by an entry in the <structname>pg_class</structname> catalog. The contents of an
+ index are entirely under the control of its index access method. In
+ practice, all index access methods divide indexes into standard-size
+ pages so that they can use the regular storage manager and buffer manager
+ to access the index contents. (All the existing index access methods
+ furthermore use the standard page layout described in <xref
+ linkend="storage-page-layout"/>, and most use the same format for index
+ tuple headers; but these decisions are not forced on an access method.)
+ </para>
+
+ <para>
+ An index is effectively a mapping from some data key values to
+ <firstterm>tuple identifiers</firstterm>, or <acronym>TIDs</acronym>, of row versions
+ (tuples) in the index's parent table. A TID consists of a
+ block number and an item number within that block (see <xref
+ linkend="storage-page-layout"/>). This is sufficient
+ information to fetch a particular row version from the table.
+ Indexes are not directly aware that under MVCC, there might be multiple
+ extant versions of the same logical row; to an index, each tuple is
+ an independent object that needs its own index entry. Thus, an
+ update of a row always creates all-new index entries for the row, even if
+ the key values did not change. (<link linkend="storage-hot">HOT
+ tuples</link> are an exception to this
+ statement; but indexes do not deal with those, either.) Index entries for
+ dead tuples are reclaimed (by vacuuming) when the dead tuples themselves
+ are reclaimed.
+ </para>
+
+ <sect1 id="index-api">
+ <title>Basic API Structure for Indexes</title>
+
+ <para>
+ Each index access method is described by a row in the
+ <link linkend="catalog-pg-am"><structname>pg_am</structname></link>
+ system catalog. The <structname>pg_am</structname> entry
+ specifies a name and a <firstterm>handler function</firstterm> for the index
+ access method. These entries can be created and deleted using the
+ <xref linkend="sql-create-access-method"/> and
+ <xref linkend="sql-drop-access-method"/> SQL commands.
+ </para>
+
+ <para>
+ An index access method handler function must be declared to accept a
+ single argument of type <type>internal</type> and to return the
+ pseudo-type <type>index_am_handler</type>. The argument is a dummy value that
+ simply serves to prevent handler functions from being called directly from
+ SQL commands. The result of the function must be a palloc'd struct of
+ type <structname>IndexAmRoutine</structname>, which contains everything
+ that the core code needs to know to make use of the index access method.
+ The <structname>IndexAmRoutine</structname> struct, also called the access
+ method's <firstterm>API struct</firstterm>, includes fields specifying assorted
+ fixed properties of the access method, such as whether it can support
+ multicolumn indexes. More importantly, it contains pointers to support
+ functions for the access method, which do all of the real work to access
+ indexes. These support functions are plain C functions and are not
+ visible or callable at the SQL level. The support functions are described
+ in <xref linkend="index-functions"/>.
+ </para>
+
+ <para>
+ The structure <structname>IndexAmRoutine</structname> is defined thus:
+<programlisting>
+typedef struct IndexAmRoutine
+{
+ NodeTag type;
+
+ /*
+ * Total number of strategies (operators) by which we can traverse/search
+ * this AM. Zero if AM does not have a fixed set of strategy assignments.
+ */
+ uint16 amstrategies;
+ /* total number of support functions that this AM uses */
+ uint16 amsupport;
+ /* opclass options support function number or 0 */
+ uint16 amoptsprocnum;
+ /* does AM support ORDER BY indexed column's value? */
+ bool amcanorder;
+ /* does AM support ORDER BY result of an operator on indexed column? */
+ bool amcanorderbyop;
+ /* does AM support backward scanning? */
+ bool amcanbackward;
+ /* does AM support UNIQUE indexes? */
+ bool amcanunique;
+ /* does AM support multi-column indexes? */
+ bool amcanmulticol;
+ /* does AM require scans to have a constraint on the first index column? */
+ bool amoptionalkey;
+ /* does AM handle ScalarArrayOpExpr quals? */
+ bool amsearcharray;
+ /* does AM handle IS NULL/IS NOT NULL quals? */
+ bool amsearchnulls;
+ /* can index storage data type differ from column data type? */
+ bool amstorage;
+ /* can an index of this type be clustered on? */
+ bool amclusterable;
+ /* does AM handle predicate locks? */
+ bool ampredlocks;
+ /* does AM support parallel scan? */
+ bool amcanparallel;
+ /* does AM support columns included with clause INCLUDE? */
+ bool amcaninclude;
+ /* does AM use maintenance_work_mem? */
+ bool amusemaintenanceworkmem;
+ /* OR of parallel vacuum flags */
+ uint8 amparallelvacuumoptions;
+ /* type of data stored in index, or InvalidOid if variable */
+ Oid amkeytype;
+
+ /* interface functions */
+ ambuild_function ambuild;
+ ambuildempty_function ambuildempty;
+ aminsert_function aminsert;
+ ambulkdelete_function ambulkdelete;
+ amvacuumcleanup_function amvacuumcleanup;
+ amcanreturn_function amcanreturn; /* can be NULL */
+ amcostestimate_function amcostestimate;
+ amoptions_function amoptions;
+ amproperty_function amproperty; /* can be NULL */
+ ambuildphasename_function ambuildphasename; /* can be NULL */
+ amvalidate_function amvalidate;
+ amadjustmembers_function amadjustmembers; /* can be NULL */
+ ambeginscan_function ambeginscan;
+ amrescan_function amrescan;
+ amgettuple_function amgettuple; /* can be NULL */
+ amgetbitmap_function amgetbitmap; /* can be NULL */
+ amendscan_function amendscan;
+ ammarkpos_function ammarkpos; /* can be NULL */
+ amrestrpos_function amrestrpos; /* can be NULL */
+
+ /* interface functions to support parallel index scans */
+ amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
+ aminitparallelscan_function aminitparallelscan; /* can be NULL */
+ amparallelrescan_function amparallelrescan; /* can be NULL */
+} IndexAmRoutine;
+</programlisting>
+ </para>
+
+ <para>
+ To be useful, an index access method must also have one or more
+ <firstterm>operator families</firstterm> and
+ <firstterm>operator classes</firstterm> defined in
+ <link linkend="catalog-pg-opfamily"><structname>pg_opfamily</structname></link>,
+ <link linkend="catalog-pg-opclass"><structname>pg_opclass</structname></link>,
+ <link linkend="catalog-pg-amop"><structname>pg_amop</structname></link>, and
+ <link linkend="catalog-pg-amproc"><structname>pg_amproc</structname></link>.
+ These entries allow the planner
+ to determine what kinds of query qualifications can be used with
+ indexes of this access method. Operator families and classes are described
+ in <xref linkend="xindex"/>, which is prerequisite material for reading
+ this chapter.
+ </para>
+
+ <para>
+ An individual index is defined by a
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>
+ entry that describes it as a physical relation, plus a
+ <link linkend="catalog-pg-index"><structname>pg_index</structname></link>
+ entry that shows the logical content of the index &mdash; that is, the set
+ of index columns it has and the semantics of those columns, as captured by
+ the associated operator classes. The index columns (key values) can be
+ either simple columns of the underlying table or expressions over the table
+ rows. The index access method normally has no interest in where the index
+ key values come from (it is always handed precomputed key values) but it
+ will be very interested in the operator class information in
+ <structname>pg_index</structname>. Both of these catalog entries can be
+ accessed as part of the <structname>Relation</structname> data structure that is
+ passed to all operations on the index.
+ </para>
+
+ <para>
+ Some of the flag fields of <structname>IndexAmRoutine</structname> have nonobvious
+ implications. The requirements of <structfield>amcanunique</structfield>
+ are discussed in <xref linkend="index-unique-checks"/>.
+ The <structfield>amcanmulticol</structfield> flag asserts that the
+ access method supports multi-key-column indexes, while
+ <structfield>amoptionalkey</structfield> asserts that it allows scans
+ where no indexable restriction clause is given for the first index column.
+ When <structfield>amcanmulticol</structfield> is false,
+ <structfield>amoptionalkey</structfield> essentially says whether the
+ access method supports full-index scans without any restriction clause.
+ Access methods that support multiple index columns <emphasis>must</emphasis>
+ support scans that omit restrictions on any or all of the columns after
+ the first; however they are permitted to require some restriction to
+ appear for the first index column, and this is signaled by setting
+ <structfield>amoptionalkey</structfield> false.
+ One reason that an index AM might set
+ <structfield>amoptionalkey</structfield> false is if it doesn't index
+ null values. Since most indexable operators are
+ strict and hence cannot return true for null inputs,
+ it is at first sight attractive to not store index entries for null values:
+ they could never be returned by an index scan anyway. However, this
+ argument fails when an index scan has no restriction clause for a given
+ index column. In practice this means that
+ indexes that have <structfield>amoptionalkey</structfield> true must
+ index nulls, since the planner might decide to use such an index
+ with no scan keys at all. A related restriction is that an index
+ access method that supports multiple index columns <emphasis>must</emphasis>
+ support indexing null values in columns after the first, because the planner
+ will assume the index can be used for queries that do not restrict
+ these columns. For example, consider an index on (a,b) and a query with
+ <literal>WHERE a = 4</literal>. The system will assume the index can be
+ used to scan for rows with <literal>a = 4</literal>, which is wrong if the
+ index omits rows where <literal>b</literal> is null.
+ It is, however, OK to omit rows where the first indexed column is null.
+ An index access method that does index nulls may also set
+ <structfield>amsearchnulls</structfield>, indicating that it supports
+ <literal>IS NULL</literal> and <literal>IS NOT NULL</literal> clauses as search
+ conditions.
+ </para>
+
+ <para>
+ The <structfield>amcaninclude</structfield> flag indicates whether the
+ access method supports <quote>included</quote> columns, that is it can
+ store (without processing) additional columns beyond the key column(s).
+ The requirements of the preceding paragraph apply only to the key
+ columns. In particular, the combination
+ of <structfield>amcanmulticol</structfield>=<literal>false</literal>
+ and <structfield>amcaninclude</structfield>=<literal>true</literal> is
+ sensible: it means that there can only be one key column, but there can
+ also be included column(s). Also, included columns must be allowed to be
+ null, independently of <structfield>amoptionalkey</structfield>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="index-functions">
+ <title>Index Access Method Functions</title>
+
+ <para>
+ The index construction and maintenance functions that an index access
+ method must provide in <structname>IndexAmRoutine</structname> are:
+ </para>
+
+ <para>
+<programlisting>
+IndexBuildResult *
+ambuild (Relation heapRelation,
+ Relation indexRelation,
+ IndexInfo *indexInfo);
+</programlisting>
+ Build a new index. The index relation has been physically created,
+ but is empty. It must be filled in with whatever fixed data the
+ access method requires, plus entries for all tuples already existing
+ in the table. Ordinarily the <function>ambuild</function> function will call
+ <function>table_index_build_scan()</function> to scan the table for existing tuples
+ and compute the keys that need to be inserted into the index.
+ The function must return a palloc'd struct containing statistics about
+ the new index.
+ </para>
+
+ <para>
+<programlisting>
+void
+ambuildempty (Relation indexRelation);
+</programlisting>
+ Build an empty index, and write it to the initialization fork (<symbol>INIT_FORKNUM</symbol>)
+ of the given relation. This method is called only for unlogged indexes; the
+ empty index written to the initialization fork will be copied over the main
+ relation fork on each server restart.
+ </para>
+
+ <para>
+<programlisting>
+bool
+aminsert (Relation indexRelation,
+ Datum *values,
+ bool *isnull,
+ ItemPointer heap_tid,
+ Relation heapRelation,
+ IndexUniqueCheck checkUnique,
+ bool indexUnchanged,
+ IndexInfo *indexInfo);
+</programlisting>
+ Insert a new tuple into an existing index. The <literal>values</literal> and
+ <literal>isnull</literal> arrays give the key values to be indexed, and
+ <literal>heap_tid</literal> is the TID to be indexed.
+ If the access method supports unique indexes (its
+ <structfield>amcanunique</structfield> flag is true) then
+ <literal>checkUnique</literal> indicates the type of uniqueness check to
+ perform. This varies depending on whether the unique constraint is
+ deferrable; see <xref linkend="index-unique-checks"/> for details.
+ Normally the access method only needs the <literal>heapRelation</literal>
+ parameter when performing uniqueness checking (since then it will have to
+ look into the heap to verify tuple liveness).
+ </para>
+
+ <para>
+ The <literal>indexUnchanged</literal> Boolean value gives a hint
+ about the nature of the tuple to be indexed. When it is true,
+ the tuple is a duplicate of some existing tuple in the index. The
+ new tuple is a logically unchanged successor MVCC tuple version. This
+ happens when an <command>UPDATE</command> takes place that does not
+ modify any columns covered by the index, but nevertheless requires a
+ new version in the index. The index AM may use this hint to decide
+ to apply bottom-up index deletion in parts of the index where many
+ versions of the same logical row accumulate. Note that updating a
+ non-key column does not affect the value of
+ <literal>indexUnchanged</literal>.
+ </para>
+
+ <para>
+ The function's Boolean result value is significant only when
+ <literal>checkUnique</literal> is <literal>UNIQUE_CHECK_PARTIAL</literal>.
+ In this case a true result means the new entry is known unique, whereas
+ false means it might be non-unique (and a deferred uniqueness check must
+ be scheduled). For other cases a constant false result is recommended.
+ </para>
+
+ <para>
+ Some indexes might not index all tuples. If the tuple is not to be
+ indexed, <function>aminsert</function> should just return without doing anything.
+ </para>
+
+ <para>
+ If the index AM wishes to cache data across successive index insertions
+ within an SQL statement, it can allocate space
+ in <literal>indexInfo-&gt;ii_Context</literal> and store a pointer to the
+ data in <literal>indexInfo-&gt;ii_AmCache</literal> (which will be NULL
+ initially).
+ </para>
+
+ <para>
+<programlisting>
+IndexBulkDeleteResult *
+ambulkdelete (IndexVacuumInfo *info,
+ IndexBulkDeleteResult *stats,
+ IndexBulkDeleteCallback callback,
+ void *callback_state);
+</programlisting>
+ Delete tuple(s) from the index. This is a <quote>bulk delete</quote> operation
+ that is intended to be implemented by scanning the whole index and checking
+ each entry to see if it should be deleted.
+ The passed-in <literal>callback</literal> function must be called, in the style
+ <literal>callback(<replaceable>TID</replaceable>, callback_state) returns bool</literal>,
+ to determine whether any particular index entry, as identified by its
+ referenced TID, is to be deleted. Must return either NULL or a palloc'd
+ struct containing statistics about the effects of the deletion operation.
+ It is OK to return NULL if no information needs to be passed on to
+ <function>amvacuumcleanup</function>.
+ </para>
+
+ <para>
+ Because of limited <varname>maintenance_work_mem</varname>,
+ <function>ambulkdelete</function> might need to be called more than once when many
+ tuples are to be deleted. The <literal>stats</literal> argument is the result
+ of the previous call for this index (it is NULL for the first call within a
+ <command>VACUUM</command> operation). This allows the AM to accumulate statistics
+ across the whole operation. Typically, <function>ambulkdelete</function> will
+ modify and return the same struct if the passed <literal>stats</literal> is not
+ null.
+ </para>
+
+ <para>
+<programlisting>
+IndexBulkDeleteResult *
+amvacuumcleanup (IndexVacuumInfo *info,
+ IndexBulkDeleteResult *stats);
+</programlisting>
+ Clean up after a <command>VACUUM</command> operation (zero or more
+ <function>ambulkdelete</function> calls). This does not have to do anything
+ beyond returning index statistics, but it might perform bulk cleanup
+ such as reclaiming empty index pages. <literal>stats</literal> is whatever the
+ last <function>ambulkdelete</function> call returned, or NULL if
+ <function>ambulkdelete</function> was not called because no tuples needed to be
+ deleted. If the result is not NULL it must be a palloc'd struct.
+ The statistics it contains will be used to update <structname>pg_class</structname>,
+ and will be reported by <command>VACUUM</command> if <literal>VERBOSE</literal> is given.
+ It is OK to return NULL if the index was not changed at all during the
+ <command>VACUUM</command> operation, but otherwise correct stats should
+ be returned.
+ </para>
+
+ <para>
+ <function>amvacuumcleanup</function> will also be called at completion of an
+ <command>ANALYZE</command> operation. In this case <literal>stats</literal> is always
+ NULL and any return value will be ignored. This case can be distinguished
+ by checking <literal>info-&gt;analyze_only</literal>. It is recommended
+ that the access method do nothing except post-insert cleanup in such a
+ call, and that only in an autovacuum worker process.
+ </para>
+
+ <para>
+<programlisting>
+bool
+amcanreturn (Relation indexRelation, int attno);
+</programlisting>
+ Check whether the index can support <link
+ linkend="indexes-index-only-scans"><firstterm>index-only scans</firstterm></link> on
+ the given column, by returning the column's original indexed value.
+ The attribute number is 1-based, i.e., the first column's attno is 1.
+ Returns true if supported, else false.
+ This function should always return true for included columns
+ (if those are supported), since there's little point in an included
+ column that can't be retrieved.
+ If the access method does not support index-only scans at all,
+ the <structfield>amcanreturn</structfield> field in its <structname>IndexAmRoutine</structname>
+ struct can be set to NULL.
+ </para>
+
+ <para>
+<programlisting>
+void
+amcostestimate (PlannerInfo *root,
+ IndexPath *path,
+ double loop_count,
+ Cost *indexStartupCost,
+ Cost *indexTotalCost,
+ Selectivity *indexSelectivity,
+ double *indexCorrelation,
+ double *indexPages);
+</programlisting>
+ Estimate the costs of an index scan. This function is described fully
+ in <xref linkend="index-cost-estimation"/>, below.
+ </para>
+
+ <para>
+<programlisting>
+bytea *
+amoptions (ArrayType *reloptions,
+ bool validate);
+</programlisting>
+ Parse and validate the reloptions array for an index. This is called only
+ when a non-null reloptions array exists for the index.
+ <parameter>reloptions</parameter> is a <type>text</type> array containing entries of the
+ form <replaceable>name</replaceable><literal>=</literal><replaceable>value</replaceable>.
+ The function should construct a <type>bytea</type> value, which will be copied
+ into the <structfield>rd_options</structfield> field of the index's relcache entry.
+ The data contents of the <type>bytea</type> value are open for the access
+ method to define; most of the standard access methods use struct
+ <structname>StdRdOptions</structname>.
+ When <parameter>validate</parameter> is true, the function should report a suitable
+ error message if any of the options are unrecognized or have invalid
+ values; when <parameter>validate</parameter> is false, invalid entries should be
+ silently ignored. (<parameter>validate</parameter> is false when loading options
+ already stored in <structname>pg_catalog</structname>; an invalid entry could only
+ be found if the access method has changed its rules for options, and in
+ that case ignoring obsolete entries is appropriate.)
+ It is OK to return NULL if default behavior is wanted.
+ </para>
+
+ <para>
+<programlisting>
+bool
+amproperty (Oid index_oid, int attno,
+ IndexAMProperty prop, const char *propname,
+ bool *res, bool *isnull);
+</programlisting>
+ The <function>amproperty</function> method allows index access methods to override
+ the default behavior of <function>pg_index_column_has_property</function>
+ and related functions.
+ If the access method does not have any special behavior for index property
+ inquiries, the <structfield>amproperty</structfield> field in
+ its <structname>IndexAmRoutine</structname> struct can be set to NULL.
+ Otherwise, the <function>amproperty</function> method will be called with
+ <parameter>index_oid</parameter> and <parameter>attno</parameter> both zero for
+ <function>pg_indexam_has_property</function> calls,
+ or with <parameter>index_oid</parameter> valid and <parameter>attno</parameter> zero for
+ <function>pg_index_has_property</function> calls,
+ or with <parameter>index_oid</parameter> valid and <parameter>attno</parameter> greater than
+ zero for <function>pg_index_column_has_property</function> calls.
+ <parameter>prop</parameter> is an enum value identifying the property being tested,
+ while <parameter>propname</parameter> is the original property name string.
+ If the core code does not recognize the property name
+ then <parameter>prop</parameter> is <literal>AMPROP_UNKNOWN</literal>.
+ Access methods can define custom property names by
+ checking <parameter>propname</parameter> for a match (use <function>pg_strcasecmp</function>
+ to match, for consistency with the core code); for names known to the core
+ code, it's better to inspect <parameter>prop</parameter>.
+ If the <structfield>amproperty</structfield> method returns <literal>true</literal> then
+ it has determined the property test result: it must set <literal>*res</literal>
+ to the Boolean value to return, or set <literal>*isnull</literal>
+ to <literal>true</literal> to return a NULL. (Both of the referenced variables
+ are initialized to <literal>false</literal> before the call.)
+ If the <structfield>amproperty</structfield> method returns <literal>false</literal> then
+ the core code will proceed with its normal logic for determining the
+ property test result.
+ </para>
+
+ <para>
+ Access methods that support ordering operators should
+ implement <literal>AMPROP_DISTANCE_ORDERABLE</literal> property testing, as the
+ core code does not know how to do that and will return NULL. It may
+ also be advantageous to implement <literal>AMPROP_RETURNABLE</literal> testing,
+ if that can be done more cheaply than by opening the index and calling
+ <function>amcanreturn</function>, which is the core code's default behavior.
+ The default behavior should be satisfactory for all other standard
+ properties.
+ </para>
+
+ <para>
+<programlisting>
+char *
+ambuildphasename (int64 phasenum);
+</programlisting>
+ Return the textual name of the given build phase number.
+ The phase numbers are those reported during an index build via the
+ <function>pgstat_progress_update_param</function> interface.
+ The phase names are then exposed in the
+ <structname>pg_stat_progress_create_index</structname> view.
+ </para>
+
+ <para>
+<programlisting>
+bool
+amvalidate (Oid opclassoid);
+</programlisting>
+ Validate the catalog entries for the specified operator class, so far as
+ the access method can reasonably do that. For example, this might include
+ testing that all required support functions are provided.
+ The <function>amvalidate</function> function must return false if the opclass is
+ invalid. Problems should be reported with <function>ereport</function>
+ messages, typically at <literal>INFO</literal> level.
+ </para>
+
+ <para>
+<programlisting>
+void
+amadjustmembers (Oid opfamilyoid,
+ Oid opclassoid,
+ List *operators,
+ List *functions);
+</programlisting>
+ Validate proposed new operator and function members of an operator family,
+ so far as the access method can reasonably do that, and set their
+ dependency types if the default is not satisfactory. This is called
+ during <command>CREATE OPERATOR CLASS</command> and during
+ <command>ALTER OPERATOR FAMILY ADD</command>; in the latter
+ case <parameter>opclassoid</parameter> is <literal>InvalidOid</literal>.
+ The <type>List</type> arguments are lists
+ of <structname>OpFamilyMember</structname> structs, as defined
+ in <filename>amapi.h</filename>.
+
+ Tests done by this function will typically be a subset of those
+ performed by <function>amvalidate</function>,
+ since <function>amadjustmembers</function> cannot assume that it is
+ seeing a complete set of members. For example, it would be reasonable
+ to check the signature of a support function, but not to check whether
+ all required support functions are provided. Any problems can be
+ reported by throwing an error.
+
+ The dependency-related fields of
+ the <structname>OpFamilyMember</structname> structs are initialized by
+ the core code to create hard dependencies on the opclass if this
+ is <command>CREATE OPERATOR CLASS</command>, or soft dependencies on the
+ opfamily if this is <command>ALTER OPERATOR FAMILY ADD</command>.
+ <function>amadjustmembers</function> can adjust these fields if some other
+ behavior is more appropriate. For example, GIN, GiST, and SP-GiST
+ always set operator members to have soft dependencies on the opfamily,
+ since the connection between an operator and an opclass is relatively
+ weak in these index types; so it is reasonable to allow operator members
+ to be added and removed freely. Optional support functions are typically
+ also given soft dependencies, so that they can be removed if necessary.
+ </para>
+
+
+ <para>
+ The purpose of an index, of course, is to support scans for tuples matching
+ an indexable <literal>WHERE</literal> condition, often called a
+ <firstterm>qualifier</firstterm> or <firstterm>scan key</firstterm>. The semantics of
+ index scanning are described more fully in <xref linkend="index-scanning"/>,
+ below. An index access method can support <quote>plain</quote> index scans,
+ <quote>bitmap</quote> index scans, or both. The scan-related functions that an
+ index access method must or may provide are:
+ </para>
+
+ <para>
+<programlisting>
+IndexScanDesc
+ambeginscan (Relation indexRelation,
+ int nkeys,
+ int norderbys);
+</programlisting>
+ Prepare for an index scan. The <literal>nkeys</literal> and <literal>norderbys</literal>
+ parameters indicate the number of quals and ordering operators that will be
+ used in the scan; these may be useful for space allocation purposes.
+ Note that the actual values of the scan keys aren't provided yet.
+ The result must be a palloc'd struct.
+ For implementation reasons the index access method
+ <emphasis>must</emphasis> create this struct by calling
+ <function>RelationGetIndexScan()</function>. In most cases
+ <function>ambeginscan</function> does little beyond making that call and perhaps
+ acquiring locks;
+ the interesting parts of index-scan startup are in <function>amrescan</function>.
+ </para>
+
+ <para>
+<programlisting>
+void
+amrescan (IndexScanDesc scan,
+ ScanKey keys,
+ int nkeys,
+ ScanKey orderbys,
+ int norderbys);
+</programlisting>
+ Start or restart an index scan, possibly with new scan keys. (To restart
+ using previously-passed keys, NULL is passed for <literal>keys</literal> and/or
+ <literal>orderbys</literal>.) Note that it is not allowed for
+ the number of keys or order-by operators to be larger than
+ what was passed to <function>ambeginscan</function>. In practice the restart
+ feature is used when a new outer tuple is selected by a nested-loop join
+ and so a new key comparison value is needed, but the scan key structure
+ remains the same.
+ </para>
+
+ <para>
+<programlisting>
+bool
+amgettuple (IndexScanDesc scan,
+ ScanDirection direction);
+</programlisting>
+ Fetch the next tuple in the given scan, moving in the given
+ direction (forward or backward in the index). Returns true if a tuple was
+ obtained, false if no matching tuples remain. In the true case the tuple
+ TID is stored into the <literal>scan</literal> structure. Note that
+ <quote>success</quote> means only that the index contains an entry that matches
+ the scan keys, not that the tuple necessarily still exists in the heap or
+ will pass the caller's snapshot test. On success, <function>amgettuple</function>
+ must also set <literal>scan-&gt;xs_recheck</literal> to true or false.
+ False means it is certain that the index entry matches the scan keys.
+ True means this is not certain, and the conditions represented by the
+ scan keys must be rechecked against the heap tuple after fetching it.
+ This provision supports <quote>lossy</quote> index operators.
+ Note that rechecking will extend only to the scan conditions; a partial
+ index predicate (if any) is never rechecked by <function>amgettuple</function>
+ callers.
+ </para>
+
+ <para>
+ If the index supports <link linkend="indexes-index-only-scans">index-only
+ scans</link> (i.e., <function>amcanreturn</function> returns true for any
+ of its columns),
+ then on success the AM must also check <literal>scan-&gt;xs_want_itup</literal>,
+ and if that is true it must return the originally indexed data for the
+ index entry. Columns for which <function>amcanreturn</function> returns
+ false can be returned as nulls.
+ The data can be returned in the form of an
+ <structname>IndexTuple</structname> pointer stored at <literal>scan-&gt;xs_itup</literal>,
+ with tuple descriptor <literal>scan-&gt;xs_itupdesc</literal>; or in the form of
+ a <structname>HeapTuple</structname> pointer stored at <literal>scan-&gt;xs_hitup</literal>,
+ with tuple descriptor <literal>scan-&gt;xs_hitupdesc</literal>. (The latter
+ format should be used when reconstructing data that might possibly not fit
+ into an <structname>IndexTuple</structname>.) In either case,
+ management of the data referenced by the pointer is the access method's
+ responsibility. The data must remain good at least until the next
+ <function>amgettuple</function>, <function>amrescan</function>, or <function>amendscan</function>
+ call for the scan.
+ </para>
+
+ <para>
+ The <function>amgettuple</function> function need only be provided if the access
+ method supports <quote>plain</quote> index scans. If it doesn't, the
+ <structfield>amgettuple</structfield> field in its <structname>IndexAmRoutine</structname>
+ struct must be set to NULL.
+ </para>
+
+ <para>
+<programlisting>
+int64
+amgetbitmap (IndexScanDesc scan,
+ TIDBitmap *tbm);
+</programlisting>
+ Fetch all tuples in the given scan and add them to the caller-supplied
+ <type>TIDBitmap</type> (that is, OR the set of tuple IDs into whatever set is already
+ in the bitmap). The number of tuples fetched is returned (this might be
+ just an approximate count, for instance some AMs do not detect duplicates).
+ While inserting tuple IDs into the bitmap, <function>amgetbitmap</function> can
+ indicate that rechecking of the scan conditions is required for specific
+ tuple IDs. This is analogous to the <literal>xs_recheck</literal> output parameter
+ of <function>amgettuple</function>. Note: in the current implementation, support
+ for this feature is conflated with support for lossy storage of the bitmap
+ itself, and therefore callers recheck both the scan conditions and the
+ partial index predicate (if any) for recheckable tuples. That might not
+ always be true, however.
+ <function>amgetbitmap</function> and
+ <function>amgettuple</function> cannot be used in the same index scan; there
+ are other restrictions too when using <function>amgetbitmap</function>, as explained
+ in <xref linkend="index-scanning"/>.
+ </para>
+
+ <para>
+ The <function>amgetbitmap</function> function need only be provided if the access
+ method supports <quote>bitmap</quote> index scans. If it doesn't, the
+ <structfield>amgetbitmap</structfield> field in its <structname>IndexAmRoutine</structname>
+ struct must be set to NULL.
+ </para>
+
+ <para>
+<programlisting>
+void
+amendscan (IndexScanDesc scan);
+</programlisting>
+ End a scan and release resources. The <literal>scan</literal> struct itself
+ should not be freed, but any locks or pins taken internally by the
+ access method must be released, as well as any other memory allocated
+ by <function>ambeginscan</function> and other scan-related functions.
+ </para>
+
+ <para>
+<programlisting>
+void
+ammarkpos (IndexScanDesc scan);
+</programlisting>
+ Mark current scan position. The access method need only support one
+ remembered scan position per scan.
+ </para>
+
+ <para>
+ The <function>ammarkpos</function> function need only be provided if the access
+ method supports ordered scans. If it doesn't,
+ the <structfield>ammarkpos</structfield> field in its <structname>IndexAmRoutine</structname>
+ struct may be set to NULL.
+ </para>
+
+ <para>
+<programlisting>
+void
+amrestrpos (IndexScanDesc scan);
+</programlisting>
+ Restore the scan to the most recently marked position.
+ </para>
+
+ <para>
+ The <function>amrestrpos</function> function need only be provided if the access
+ method supports ordered scans. If it doesn't,
+ the <structfield>amrestrpos</structfield> field in its <structname>IndexAmRoutine</structname>
+ struct may be set to NULL.
+ </para>
+
+ <para>
+ In addition to supporting ordinary index scans, some types of index
+ may wish to support <firstterm>parallel index scans</firstterm>, which allow
+ multiple backends to cooperate in performing an index scan. The
+ index access method should arrange things so that each cooperating
+ process returns a subset of the tuples that would be performed by
+ an ordinary, non-parallel index scan, but in such a way that the
+ union of those subsets is equal to the set of tuples that would be
+ returned by an ordinary, non-parallel index scan. Furthermore, while
+ there need not be any global ordering of tuples returned by a parallel
+ scan, the ordering of that subset of tuples returned within each
+ cooperating backend must match the requested ordering. The following
+ functions may be implemented to support parallel index scans:
+ </para>
+
+ <para>
+<programlisting>
+Size
+amestimateparallelscan (void);
+</programlisting>
+ Estimate and return the number of bytes of dynamic shared memory which
+ the access method will be needed to perform a parallel scan. (This number
+ is in addition to, not in lieu of, the amount of space needed for
+ AM-independent data in <structname>ParallelIndexScanDescData</structname>.)
+ </para>
+
+ <para>
+ It is not necessary to implement this function for access methods which
+ do not support parallel scans or for which the number of additional bytes
+ of storage required is zero.
+ </para>
+
+ <para>
+<programlisting>
+void
+aminitparallelscan (void *target);
+</programlisting>
+ This function will be called to initialize dynamic shared memory at the
+ beginning of a parallel scan. <parameter>target</parameter> will point to at least
+ the number of bytes previously returned by
+ <function>amestimateparallelscan</function>, and this function may use that
+ amount of space to store whatever data it wishes.
+ </para>
+
+ <para>
+ It is not necessary to implement this function for access methods which
+ do not support parallel scans or in cases where the shared memory space
+ required needs no initialization.
+ </para>
+
+ <para>
+<programlisting>
+void
+amparallelrescan (IndexScanDesc scan);
+</programlisting>
+ This function, if implemented, will be called when a parallel index scan
+ must be restarted. It should reset any shared state set up by
+ <function>aminitparallelscan</function> such that the scan will be restarted from
+ the beginning.
+ </para>
+
+ </sect1>
+
+ <sect1 id="index-scanning">
+ <title>Index Scanning</title>
+
+ <para>
+ In an index scan, the index access method is responsible for regurgitating
+ the TIDs of all the tuples it has been told about that match the
+ <firstterm>scan keys</firstterm>. The access method is <emphasis>not</emphasis> involved in
+ actually fetching those tuples from the index's parent table, nor in
+ determining whether they pass the scan's visibility test or other
+ conditions.
+ </para>
+
+ <para>
+ A scan key is the internal representation of a <literal>WHERE</literal> clause of
+ the form <replaceable>index_key</replaceable> <replaceable>operator</replaceable>
+ <replaceable>constant</replaceable>, where the index key is one of the columns of the
+ index and the operator is one of the members of the operator family
+ associated with that index column. An index scan has zero or more scan
+ keys, which are implicitly ANDed &mdash; the returned tuples are expected
+ to satisfy all the indicated conditions.
+ </para>
+
+ <para>
+ The access method can report that the index is <firstterm>lossy</firstterm>, or
+ requires rechecks, for a particular query. This implies that the index
+ scan will return all the entries that pass the scan key, plus possibly
+ additional entries that do not. The core system's index-scan machinery
+ will then apply the index conditions again to the heap tuple to verify
+ whether or not it really should be selected. If the recheck option is not
+ specified, the index scan must return exactly the set of matching entries.
+ </para>
+
+ <para>
+ Note that it is entirely up to the access method to ensure that it
+ correctly finds all and only the entries passing all the given scan keys.
+ Also, the core system will simply hand off all the <literal>WHERE</literal>
+ clauses that match the index keys and operator families, without any
+ semantic analysis to determine whether they are redundant or
+ contradictory. As an example, given
+ <literal>WHERE x &gt; 4 AND x &gt; 14</literal> where <literal>x</literal> is a b-tree
+ indexed column, it is left to the b-tree <function>amrescan</function> function
+ to realize that the first scan key is redundant and can be discarded.
+ The extent of preprocessing needed during <function>amrescan</function> will
+ depend on the extent to which the index access method needs to reduce
+ the scan keys to a <quote>normalized</quote> form.
+ </para>
+
+ <para>
+ Some access methods return index entries in a well-defined order, others
+ do not. There are actually two different ways that an access method can
+ support sorted output:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Access methods that always return entries in the natural ordering
+ of their data (such as btree) should set
+ <structfield>amcanorder</structfield> to true.
+ Currently, such access methods must use btree-compatible strategy
+ numbers for their equality and ordering operators.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Access methods that support ordering operators should set
+ <structfield>amcanorderbyop</structfield> to true.
+ This indicates that the index is capable of returning entries in
+ an order satisfying <literal>ORDER BY</literal> <replaceable>index_key</replaceable>
+ <replaceable>operator</replaceable> <replaceable>constant</replaceable>. Scan modifiers
+ of that form can be passed to <function>amrescan</function> as described
+ previously.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The <function>amgettuple</function> function has a <literal>direction</literal> argument,
+ which can be either <literal>ForwardScanDirection</literal> (the normal case)
+ or <literal>BackwardScanDirection</literal>. If the first call after
+ <function>amrescan</function> specifies <literal>BackwardScanDirection</literal>, then the
+ set of matching index entries is to be scanned back-to-front rather than in
+ the normal front-to-back direction, so <function>amgettuple</function> must return
+ the last matching tuple in the index, rather than the first one as it
+ normally would. (This will only occur for access
+ methods that set <structfield>amcanorder</structfield> to true.) After the
+ first call, <function>amgettuple</function> must be prepared to advance the scan in
+ either direction from the most recently returned entry. (But if
+ <structfield>amcanbackward</structfield> is false, all subsequent
+ calls will have the same direction as the first one.)
+ </para>
+
+ <para>
+ Access methods that support ordered scans must support <quote>marking</quote> a
+ position in a scan and later returning to the marked position. The same
+ position might be restored multiple times. However, only one position need
+ be remembered per scan; a new <function>ammarkpos</function> call overrides the
+ previously marked position. An access method that does not support ordered
+ scans need not provide <function>ammarkpos</function> and <function>amrestrpos</function>
+ functions in <structname>IndexAmRoutine</structname>; set those pointers to NULL
+ instead.
+ </para>
+
+ <para>
+ Both the scan position and the mark position (if any) must be maintained
+ consistently in the face of concurrent insertions or deletions in the
+ index. It is OK if a freshly-inserted entry is not returned by a scan that
+ would have found the entry if it had existed when the scan started, or for
+ the scan to return such an entry upon rescanning or backing
+ up even though it had not been returned the first time through. Similarly,
+ a concurrent delete might or might not be reflected in the results of a scan.
+ What is important is that insertions or deletions not cause the scan to
+ miss or multiply return entries that were not themselves being inserted or
+ deleted.
+ </para>
+
+ <para>
+ If the index stores the original indexed data values (and not some lossy
+ representation of them), it is useful to
+ support <link linkend="indexes-index-only-scans">index-only scans</link>, in
+ which the index returns the actual data not just the TID of the heap tuple.
+ This will only avoid I/O if the visibility map shows that the TID is on an
+ all-visible page; else the heap tuple must be visited anyway to check
+ MVCC visibility. But that is no concern of the access method's.
+ </para>
+
+ <para>
+ Instead of using <function>amgettuple</function>, an index scan can be done with
+ <function>amgetbitmap</function> to fetch all tuples in one call. This can be
+ noticeably more efficient than <function>amgettuple</function> because it allows
+ avoiding lock/unlock cycles within the access method. In principle
+ <function>amgetbitmap</function> should have the same effects as repeated
+ <function>amgettuple</function> calls, but we impose several restrictions to
+ simplify matters. First of all, <function>amgetbitmap</function> returns all
+ tuples at once and marking or restoring scan positions isn't
+ supported. Secondly, the tuples are returned in a bitmap which doesn't
+ have any specific ordering, which is why <function>amgetbitmap</function> doesn't
+ take a <literal>direction</literal> argument. (Ordering operators will never be
+ supplied for such a scan, either.)
+ Also, there is no provision for index-only scans with
+ <function>amgetbitmap</function>, since there is no way to return the contents of
+ index tuples.
+ Finally, <function>amgetbitmap</function>
+ does not guarantee any locking of the returned tuples, with implications
+ spelled out in <xref linkend="index-locking"/>.
+ </para>
+
+ <para>
+ Note that it is permitted for an access method to implement only
+ <function>amgetbitmap</function> and not <function>amgettuple</function>, or vice versa,
+ if its internal implementation is unsuited to one API or the other.
+ </para>
+
+ </sect1>
+
+ <sect1 id="index-locking">
+ <title>Index Locking Considerations</title>
+
+ <para>
+ Index access methods must handle concurrent updates
+ of the index by multiple processes.
+ The core <productname>PostgreSQL</productname> system obtains
+ <literal>AccessShareLock</literal> on the index during an index scan, and
+ <literal>RowExclusiveLock</literal> when updating the index (including plain
+ <command>VACUUM</command>). Since these lock types do not conflict, the access
+ method is responsible for handling any fine-grained locking it might need.
+ An <literal>ACCESS EXCLUSIVE</literal> lock on the index as a whole will be
+ taken only during index creation, destruction, or <command>REINDEX</command>
+ (<literal>SHARE UPDATE EXCLUSIVE</literal> is taken instead with
+ <literal>CONCURRENTLY</literal>).
+ </para>
+
+ <para>
+ Building an index type that supports concurrent updates usually requires
+ extensive and subtle analysis of the required behavior. For the b-tree
+ and hash index types, you can read about the design decisions involved in
+ <filename>src/backend/access/nbtree/README</filename> and
+ <filename>src/backend/access/hash/README</filename>.
+ </para>
+
+ <para>
+ Aside from the index's own internal consistency requirements, concurrent
+ updates create issues about consistency between the parent table (the
+ <firstterm>heap</firstterm>) and the index. Because
+ <productname>PostgreSQL</productname> separates accesses
+ and updates of the heap from those of the index, there are windows in
+ which the index might be inconsistent with the heap. We handle this problem
+ with the following rules:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A new heap entry is made before making its index entries. (Therefore
+ a concurrent index scan is likely to fail to see the heap entry.
+ This is okay because the index reader would be uninterested in an
+ uncommitted row anyway. But see <xref linkend="index-unique-checks"/>.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When a heap entry is to be deleted (by <command>VACUUM</command>), all its
+ index entries must be removed first.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An index scan must maintain a pin
+ on the index page holding the item last returned by
+ <function>amgettuple</function>, and <function>ambulkdelete</function> cannot delete
+ entries from pages that are pinned by other backends. The need
+ for this rule is explained below.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Without the third rule, it is possible for an index reader to
+ see an index entry just before it is removed by <command>VACUUM</command>, and
+ then to arrive at the corresponding heap entry after that was removed by
+ <command>VACUUM</command>.
+ This creates no serious problems if that item
+ number is still unused when the reader reaches it, since an empty
+ item slot will be ignored by <function>heap_fetch()</function>. But what if a
+ third backend has already re-used the item slot for something else?
+ When using an MVCC-compliant snapshot, there is no problem because
+ the new occupant of the slot is certain to be too new to pass the
+ snapshot test. However, with a non-MVCC-compliant snapshot (such as
+ <literal>SnapshotAny</literal>), it would be possible to accept and return
+ a row that does not in fact match the scan keys. We could defend
+ against this scenario by requiring the scan keys to be rechecked
+ against the heap row in all cases, but that is too expensive. Instead,
+ we use a pin on an index page as a proxy to indicate that the reader
+ might still be <quote>in flight</quote> from the index entry to the matching
+ heap entry. Making <function>ambulkdelete</function> block on such a pin ensures
+ that <command>VACUUM</command> cannot delete the heap entry before the reader
+ is done with it. This solution costs little in run time, and adds blocking
+ overhead only in the rare cases where there actually is a conflict.
+ </para>
+
+ <para>
+ This solution requires that index scans be <quote>synchronous</quote>: we have
+ to fetch each heap tuple immediately after scanning the corresponding index
+ entry. This is expensive for a number of reasons. An
+ <quote>asynchronous</quote> scan in which we collect many TIDs from the index,
+ and only visit the heap tuples sometime later, requires much less index
+ locking overhead and can allow a more efficient heap access pattern.
+ Per the above analysis, we must use the synchronous approach for
+ non-MVCC-compliant snapshots, but an asynchronous scan is workable
+ for a query using an MVCC snapshot.
+ </para>
+
+ <para>
+ In an <function>amgetbitmap</function> index scan, the access method does not
+ keep an index pin on any of the returned tuples. Therefore
+ it is only safe to use such scans with MVCC-compliant snapshots.
+ </para>
+
+ <para>
+ When the <structfield>ampredlocks</structfield> flag is not set, any scan using that
+ index access method within a serializable transaction will acquire a
+ nonblocking predicate lock on the full index. This will generate a
+ read-write conflict with the insert of any tuple into that index by a
+ concurrent serializable transaction. If certain patterns of read-write
+ conflicts are detected among a set of concurrent serializable
+ transactions, one of those transactions may be canceled to protect data
+ integrity. When the flag is set, it indicates that the index access
+ method implements finer-grained predicate locking, which will tend to
+ reduce the frequency of such transaction cancellations.
+ </para>
+
+ </sect1>
+
+ <sect1 id="index-unique-checks">
+ <title>Index Uniqueness Checks</title>
+
+ <para>
+ <productname>PostgreSQL</productname> enforces SQL uniqueness constraints
+ using <firstterm>unique indexes</firstterm>, which are indexes that disallow
+ multiple entries with identical keys. An access method that supports this
+ feature sets <structfield>amcanunique</structfield> true.
+ (At present, only b-tree supports it.) Columns listed in the
+ <literal>INCLUDE</literal> clause are not considered when enforcing
+ uniqueness.
+ </para>
+
+ <para>
+ Because of MVCC, it is always necessary to allow duplicate entries to
+ exist physically in an index: the entries might refer to successive
+ versions of a single logical row. The behavior we actually want to
+ enforce is that no MVCC snapshot could include two rows with equal
+ index keys. This breaks down into the following cases that must be
+ checked when inserting a new row into a unique index:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If a conflicting valid row has been deleted by the current transaction,
+ it's okay. (In particular, since an UPDATE always deletes the old row
+ version before inserting the new version, this will allow an UPDATE on
+ a row without changing the key.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a conflicting row has been inserted by an as-yet-uncommitted
+ transaction, the would-be inserter must wait to see if that transaction
+ commits. If it rolls back then there is no conflict. If it commits
+ without deleting the conflicting row again, there is a uniqueness
+ violation. (In practice we just wait for the other transaction to
+ end and then redo the visibility check in toto.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Similarly, if a conflicting valid row has been deleted by an
+ as-yet-uncommitted transaction, the would-be inserter must wait
+ for that transaction to commit or abort, and then repeat the test.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Furthermore, immediately before reporting a uniqueness violation
+ according to the above rules, the access method must recheck the
+ liveness of the row being inserted. If it is committed dead then
+ no violation should be reported. (This case cannot occur during the
+ ordinary scenario of inserting a row that's just been created by
+ the current transaction. It can happen during
+ <command>CREATE UNIQUE INDEX CONCURRENTLY</command>, however.)
+ </para>
+
+ <para>
+ We require the index access method to apply these tests itself, which
+ means that it must reach into the heap to check the commit status of
+ any row that is shown to have a duplicate key according to the index
+ contents. This is without a doubt ugly and non-modular, but it saves
+ redundant work: if we did a separate probe then the index lookup for
+ a conflicting row would be essentially repeated while finding the place to
+ insert the new row's index entry. What's more, there is no obvious way
+ to avoid race conditions unless the conflict check is an integral part
+ of insertion of the new index entry.
+ </para>
+
+ <para>
+ If the unique constraint is deferrable, there is additional complexity:
+ we need to be able to insert an index entry for a new row, but defer any
+ uniqueness-violation error until end of statement or even later. To
+ avoid unnecessary repeat searches of the index, the index access method
+ should do a preliminary uniqueness check during the initial insertion.
+ If this shows that there is definitely no conflicting live tuple, we
+ are done. Otherwise, we schedule a recheck to occur when it is time to
+ enforce the constraint. If, at the time of the recheck, both the inserted
+ tuple and some other tuple with the same key are live, then the error
+ must be reported. (Note that for this purpose, <quote>live</quote> actually
+ means <quote>any tuple in the index entry's HOT chain is live</quote>.)
+ To implement this, the <function>aminsert</function> function is passed a
+ <literal>checkUnique</literal> parameter having one of the following values:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>UNIQUE_CHECK_NO</literal> indicates that no uniqueness checking
+ should be done (this is not a unique index).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>UNIQUE_CHECK_YES</literal> indicates that this is a non-deferrable
+ unique index, and the uniqueness check must be done immediately, as
+ described above.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>UNIQUE_CHECK_PARTIAL</literal> indicates that the unique
+ constraint is deferrable. <productname>PostgreSQL</productname>
+ will use this mode to insert each row's index entry. The access
+ method must allow duplicate entries into the index, and report any
+ potential duplicates by returning false from <function>aminsert</function>.
+ For each row for which false is returned, a deferred recheck will
+ be scheduled.
+ </para>
+
+ <para>
+ The access method must identify any rows which might violate the
+ unique constraint, but it is not an error for it to report false
+ positives. This allows the check to be done without waiting for other
+ transactions to finish; conflicts reported here are not treated as
+ errors and will be rechecked later, by which time they may no longer
+ be conflicts.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>UNIQUE_CHECK_EXISTING</literal> indicates that this is a deferred
+ recheck of a row that was reported as a potential uniqueness violation.
+ Although this is implemented by calling <function>aminsert</function>, the
+ access method must <emphasis>not</emphasis> insert a new index entry in this
+ case. The index entry is already present. Rather, the access method
+ must check to see if there is another live index entry. If so, and
+ if the target row is also still live, report error.
+ </para>
+
+ <para>
+ It is recommended that in a <literal>UNIQUE_CHECK_EXISTING</literal> call,
+ the access method further verify that the target row actually does
+ have an existing entry in the index, and report error if not. This
+ is a good idea because the index tuple values passed to
+ <function>aminsert</function> will have been recomputed. If the index
+ definition involves functions that are not really immutable, we
+ might be checking the wrong area of the index. Checking that the
+ target row is found in the recheck verifies that we are scanning
+ for the same tuple values as were used in the original insertion.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect1>
+
+ <sect1 id="index-cost-estimation">
+ <title>Index Cost Estimation Functions</title>
+
+ <para>
+ The <function>amcostestimate</function> function is given information describing
+ a possible index scan, including lists of WHERE and ORDER BY clauses that
+ have been determined to be usable with the index. It must return estimates
+ of the cost of accessing the index and the selectivity of the WHERE
+ clauses (that is, the fraction of parent-table rows that will be
+ retrieved during the index scan). For simple cases, nearly all the
+ work of the cost estimator can be done by calling standard routines
+ in the optimizer; the point of having an <function>amcostestimate</function> function is
+ to allow index access methods to provide index-type-specific knowledge,
+ in case it is possible to improve on the standard estimates.
+ </para>
+
+ <para>
+ Each <function>amcostestimate</function> function must have the signature:
+
+<programlisting>
+void
+amcostestimate (PlannerInfo *root,
+ IndexPath *path,
+ double loop_count,
+ Cost *indexStartupCost,
+ Cost *indexTotalCost,
+ Selectivity *indexSelectivity,
+ double *indexCorrelation,
+ double *indexPages);
+</programlisting>
+
+ The first three parameters are inputs:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>root</parameter></term>
+ <listitem>
+ <para>
+ The planner's information about the query being processed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>path</parameter></term>
+ <listitem>
+ <para>
+ The index access path being considered. All fields except cost and
+ selectivity values are valid.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>loop_count</parameter></term>
+ <listitem>
+ <para>
+ The number of repetitions of the index scan that should be factored
+ into the cost estimates. This will typically be greater than one when
+ considering a parameterized scan for use in the inside of a nestloop
+ join. Note that the cost estimates should still be for just one scan;
+ a larger <parameter>loop_count</parameter> means that it may be appropriate
+ to allow for some caching effects across multiple scans.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The last five parameters are pass-by-reference outputs:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>*indexStartupCost</parameter></term>
+ <listitem>
+ <para>
+ Set to cost of index start-up processing
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>*indexTotalCost</parameter></term>
+ <listitem>
+ <para>
+ Set to total cost of index processing
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>*indexSelectivity</parameter></term>
+ <listitem>
+ <para>
+ Set to index selectivity
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>*indexCorrelation</parameter></term>
+ <listitem>
+ <para>
+ Set to correlation coefficient between index scan order and
+ underlying table's order
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>*indexPages</parameter></term>
+ <listitem>
+ <para>
+ Set to number of index leaf pages
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Note that cost estimate functions must be written in C, not in SQL or
+ any available procedural language, because they must access internal
+ data structures of the planner/optimizer.
+ </para>
+
+ <para>
+ The index access costs should be computed using the parameters used by
+ <filename>src/backend/optimizer/path/costsize.c</filename>: a sequential
+ disk block fetch has cost <varname>seq_page_cost</varname>, a nonsequential fetch
+ has cost <varname>random_page_cost</varname>, and the cost of processing one index
+ row should usually be taken as <varname>cpu_index_tuple_cost</varname>. In
+ addition, an appropriate multiple of <varname>cpu_operator_cost</varname> should
+ be charged for any comparison operators invoked during index processing
+ (especially evaluation of the indexquals themselves).
+ </para>
+
+ <para>
+ The access costs should include all disk and CPU costs associated with
+ scanning the index itself, but <emphasis>not</emphasis> the costs of retrieving or
+ processing the parent-table rows that are identified by the index.
+ </para>
+
+ <para>
+ The <quote>start-up cost</quote> is the part of the total scan cost that
+ must be expended before we can begin to fetch the first row. For most
+ indexes this can be taken as zero, but an index type with a high start-up
+ cost might want to set it nonzero.
+ </para>
+
+ <para>
+ The <parameter>indexSelectivity</parameter> should be set to the estimated fraction of the parent
+ table rows that will be retrieved during the index scan. In the case
+ of a lossy query, this will typically be higher than the fraction of
+ rows that actually pass the given qual conditions.
+ </para>
+
+ <para>
+ The <parameter>indexCorrelation</parameter> should be set to the correlation (ranging between
+ -1.0 and 1.0) between the index order and the table order. This is used
+ to adjust the estimate for the cost of fetching rows from the parent
+ table.
+ </para>
+
+ <para>
+ The <parameter>indexPages</parameter> should be set to the number of leaf pages.
+ This is used to estimate the number of workers for parallel index scan.
+ </para>
+
+ <para>
+ When <parameter>loop_count</parameter> is greater than one, the returned numbers
+ should be averages expected for any one scan of the index.
+ </para>
+
+ <procedure>
+ <title>Cost Estimation</title>
+ <para>
+ A typical cost estimator will proceed as follows:
+ </para>
+
+ <step>
+ <para>
+ Estimate and return the fraction of parent-table rows that will be visited
+ based on the given qual conditions. In the absence of any index-type-specific
+ knowledge, use the standard optimizer function <function>clauselist_selectivity()</function>:
+
+<programlisting>
+*indexSelectivity = clauselist_selectivity(root, path-&gt;indexquals,
+ path-&gt;indexinfo-&gt;rel-&gt;relid,
+ JOIN_INNER, NULL);
+</programlisting>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Estimate the number of index rows that will be visited during the
+ scan. For many index types this is the same as <parameter>indexSelectivity</parameter> times
+ the number of rows in the index, but it might be more. (Note that the
+ index's size in pages and rows is available from the
+ <literal>path-&gt;indexinfo</literal> struct.)
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Estimate the number of index pages that will be retrieved during the scan.
+ This might be just <parameter>indexSelectivity</parameter> times the index's size in pages.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Compute the index access cost. A generic estimator might do this:
+
+<programlisting>
+/*
+ * Our generic assumption is that the index pages will be read
+ * sequentially, so they cost seq_page_cost each, not random_page_cost.
+ * Also, we charge for evaluation of the indexquals at each index row.
+ * All the costs are assumed to be paid incrementally during the scan.
+ */
+cost_qual_eval(&amp;index_qual_cost, path-&gt;indexquals, root);
+*indexStartupCost = index_qual_cost.startup;
+*indexTotalCost = seq_page_cost * numIndexPages +
+ (cpu_index_tuple_cost + index_qual_cost.per_tuple) * numIndexTuples;
+</programlisting>
+
+ However, the above does not account for amortization of index reads
+ across repeated index scans.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Estimate the index correlation. For a simple ordered index on a single
+ field, this can be retrieved from pg_statistic. If the correlation
+ is not known, the conservative estimate is zero (no correlation).
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ Examples of cost estimator functions can be found in
+ <filename>src/backend/utils/adt/selfuncs.c</filename>.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml
new file mode 100644
index 0000000..5512212
--- /dev/null
+++ b/doc/src/sgml/indices.sgml
@@ -0,0 +1,1605 @@
+<!-- doc/src/sgml/indices.sgml -->
+
+<chapter id="indexes">
+ <title>Indexes</title>
+
+ <indexterm zone="indexes">
+ <primary>index</primary>
+ </indexterm>
+
+ <para>
+ Indexes are a common way to enhance database performance. An index
+ allows the database server to find and retrieve specific rows much
+ faster than it could do without an index. But indexes also add
+ overhead to the database system as a whole, so they should be used
+ sensibly.
+ </para>
+
+
+ <sect1 id="indexes-intro">
+ <title>Introduction</title>
+
+ <para>
+ Suppose we have a table similar to this:
+<programlisting>
+CREATE TABLE test1 (
+ id integer,
+ content varchar
+);
+</programlisting>
+ and the application issues many queries of the form:
+<programlisting>
+SELECT content FROM test1 WHERE id = <replaceable>constant</replaceable>;
+</programlisting>
+ With no advance preparation, the system would have to scan the entire
+ <structname>test1</structname> table, row by row, to find all
+ matching entries. If there are many rows in
+ <structname>test1</structname> and only a few rows (perhaps zero
+ or one) that would be returned by such a query, this is clearly an
+ inefficient method. But if the system has been instructed to maintain an
+ index on the <structfield>id</structfield> column, it can use a more
+ efficient method for locating matching rows. For instance, it
+ might only have to walk a few levels deep into a search tree.
+ </para>
+
+ <para>
+ A similar approach is used in most non-fiction books: terms and
+ concepts that are frequently looked up by readers are collected in
+ an alphabetic index at the end of the book. The interested reader
+ can scan the index relatively quickly and flip to the appropriate
+ page(s), rather than having to read the entire book to find the
+ material of interest. Just as it is the task of the author to
+ anticipate the items that readers are likely to look up,
+ it is the task of the database programmer to foresee which indexes
+ will be useful.
+ </para>
+
+ <para>
+ The following command can be used to create an index on the
+ <structfield>id</structfield> column, as discussed:
+<programlisting>
+CREATE INDEX test1_id_index ON test1 (id);
+</programlisting>
+ The name <structname>test1_id_index</structname> can be chosen
+ freely, but you should pick something that enables you to remember
+ later what the index was for.
+ </para>
+
+ <para>
+ To remove an index, use the <command>DROP INDEX</command> command.
+ Indexes can be added to and removed from tables at any time.
+ </para>
+
+ <para>
+ Once an index is created, no further intervention is required: the
+ system will update the index when the table is modified, and it will
+ use the index in queries when it thinks doing so would be more efficient
+ than a sequential table scan. But you might have to run the
+ <command>ANALYZE</command> command regularly to update
+ statistics to allow the query planner to make educated decisions.
+ See <xref linkend="performance-tips"/> for information about
+ how to find out whether an index is used and when and why the
+ planner might choose <emphasis>not</emphasis> to use an index.
+ </para>
+
+ <para>
+ Indexes can also benefit <command>UPDATE</command> and
+ <command>DELETE</command> commands with search conditions.
+ Indexes can moreover be used in join searches. Thus,
+ an index defined on a column that is part of a join condition can
+ also significantly speed up queries with joins.
+ </para>
+
+ <para>
+ Creating an index on a large table can take a long time. By default,
+ <productname>PostgreSQL</productname> allows reads (<command>SELECT</command> statements) to occur
+ on the table in parallel with index creation, but writes (<command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>) are blocked until the index build is finished.
+ In production environments this is often unacceptable.
+ It is possible to allow writes to occur in parallel with index
+ creation, but there are several caveats to be aware of &mdash;
+ for more information see <xref linkend="sql-createindex-concurrently"/>.
+ </para>
+
+ <para>
+ After an index is created, the system has to keep it synchronized with the
+ table. This adds overhead to data manipulation operations. Indexes can
+ also prevent the creation of <link linkend="storage-hot">heap-only
+ tuples</link>.
+ Therefore indexes that are seldom or never used in queries
+ should be removed.
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-types">
+ <title>Index Types</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides several index types:
+ B-tree, Hash, GiST, SP-GiST, GIN, BRIN, and the extension <link
+ linkend="bloom">bloom</link>.
+ Each index type uses a different
+ algorithm that is best suited to different types of queries.
+ By default, the <link linkend="sql-createindex"><command>CREATE
+ INDEX</command></link> command creates
+ B-tree indexes, which fit the most common situations.
+ The other index types are selected by writing the keyword
+ <literal>USING</literal> followed by the index type name.
+ For example, to create a Hash index:
+<programlisting>
+CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> USING HASH (<replaceable>column</replaceable>);
+</programlisting>
+ </para>
+
+ <sect2 id="indexes-types-btree">
+ <title>B-Tree</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>B-Tree</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>B-Tree</primary>
+ <see>index</see>
+ </indexterm>
+
+ <para>
+ B-trees can handle equality and range queries on data that can be sorted
+ into some ordering.
+ In particular, the <productname>PostgreSQL</productname> query planner
+ will consider using a B-tree index whenever an indexed column is
+ involved in a comparison using one of these operators:
+
+<synopsis>
+&lt; &nbsp; &lt;= &nbsp; = &nbsp; &gt;= &nbsp; &gt;
+</synopsis>
+
+ Constructs equivalent to combinations of these operators, such as
+ <literal>BETWEEN</literal> and <literal>IN</literal>, can also be implemented with
+ a B-tree index search. Also, an <literal>IS NULL</literal> or <literal>IS NOT
+ NULL</literal> condition on an index column can be used with a B-tree index.
+ </para>
+
+ <para>
+ The optimizer can also use a B-tree index for queries involving the
+ pattern matching operators <literal>LIKE</literal> and <literal>~</literal>
+ <emphasis>if</emphasis> the pattern is a constant and is anchored to
+ the beginning of the string &mdash; for example, <literal>col LIKE
+ 'foo%'</literal> or <literal>col ~ '^foo'</literal>, but not
+ <literal>col LIKE '%bar'</literal>. However, if your database does not
+ use the C locale you will need to create the index with a special
+ operator class to support indexing of pattern-matching queries; see
+ <xref linkend="indexes-opclass"/> below. It is also possible to use
+ B-tree indexes for <literal>ILIKE</literal> and
+ <literal>~*</literal>, but only if the pattern starts with
+ non-alphabetic characters, i.e., characters that are not affected by
+ upper/lower case conversion.
+ </para>
+
+ <para>
+ B-tree indexes can also be used to retrieve data in sorted order.
+ This is not always faster than a simple scan and sort, but it is
+ often helpful.
+ </para>
+ </sect2>
+
+ <sect2 id="indexes-types-hash">
+ <title>Hash</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>hash</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>hash</primary>
+ <see>index</see>
+ </indexterm>
+
+ <para>
+ Hash indexes store a 32-bit hash code derived from the
+ value of the indexed column. Hence,
+ such indexes can only handle simple equality comparisons.
+ The query planner will consider using a hash index whenever an
+ indexed column is involved in a comparison using the
+ equal operator:
+
+<synopsis>
+=
+</synopsis>
+ </para>
+ </sect2>
+
+ <sect2 id="indexes-type-gist">
+ <title>GiST</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>GiST</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>GiST</primary>
+ <see>index</see>
+ </indexterm>
+
+ <para>
+ GiST indexes are not a single kind of index, but rather an infrastructure
+ within which many different indexing strategies can be implemented.
+ Accordingly, the particular operators with which a GiST index can be
+ used vary depending on the indexing strategy (the <firstterm>operator
+ class</firstterm>). As an example, the standard distribution of
+ <productname>PostgreSQL</productname> includes GiST operator classes
+ for several two-dimensional geometric data types, which support indexed
+ queries using these operators:
+
+<synopsis>
+&lt;&lt; &nbsp; &amp;&lt; &nbsp; &amp;&gt; &nbsp; &gt;&gt; &nbsp; &lt;&lt;| &nbsp; &amp;&lt;| &nbsp; |&amp;&gt; &nbsp; |&gt;&gt; &nbsp; @&gt; &nbsp; &lt;@ &nbsp; ~= &nbsp; &amp;&amp;
+</synopsis>
+
+ (See <xref linkend="functions-geometry"/> for the meaning of
+ these operators.)
+ The GiST operator classes included in the standard distribution are
+ documented in <xref linkend="gist-builtin-opclasses-table"/>.
+ Many other GiST operator
+ classes are available in the <literal>contrib</literal> collection or as separate
+ projects. For more information see <xref linkend="gist"/>.
+ </para>
+
+ <para>
+ GiST indexes are also capable of optimizing <quote>nearest-neighbor</quote>
+ searches, such as
+<programlisting><![CDATA[
+SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
+]]>
+</programlisting>
+ which finds the ten places closest to a given target point. The ability
+ to do this is again dependent on the particular operator class being used.
+ In <xref linkend="gist-builtin-opclasses-table"/>, operators that can be
+ used in this way are listed in the column <quote>Ordering Operators</quote>.
+ </para>
+ </sect2>
+
+ <sect2 id="indexes-type-spgist">
+ <title>SP-GiST</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>SP-GiST</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>SP-GiST</primary>
+ <see>index</see>
+ </indexterm>
+
+ <para>
+ SP-GiST indexes, like GiST indexes, offer an infrastructure that supports
+ various kinds of searches. SP-GiST permits implementation of a wide range
+ of different non-balanced disk-based data structures, such as quadtrees,
+ k-d trees, and radix trees (tries). As an example, the standard distribution of
+ <productname>PostgreSQL</productname> includes SP-GiST operator classes
+ for two-dimensional points, which support indexed
+ queries using these operators:
+
+<synopsis>
+&lt;&lt; &nbsp; &gt;&gt; &nbsp; ~= &nbsp; &lt;@ &nbsp; &lt;&lt;| &nbsp; |&gt;&gt;
+</synopsis>
+
+ (See <xref linkend="functions-geometry"/> for the meaning of
+ these operators.)
+ The SP-GiST operator classes included in the standard distribution are
+ documented in <xref linkend="spgist-builtin-opclasses-table"/>.
+ For more information see <xref linkend="spgist"/>.
+ </para>
+
+ <para>
+ Like GiST, SP-GiST supports <quote>nearest-neighbor</quote> searches.
+ For SP-GiST operator classes that support distance ordering, the
+ corresponding operator is listed in the <quote>Ordering Operators</quote>
+ column in <xref linkend="spgist-builtin-opclasses-table"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="indexes-types-gin">
+ <title>GIN</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>GIN</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>GIN</primary>
+ <see>index</see>
+ </indexterm>
+
+ <para>
+ GIN indexes are <quote>inverted indexes</quote> which are appropriate for
+ data values that contain multiple component values, such as arrays. An
+ inverted index contains a separate entry for each component value, and
+ can efficiently handle queries that test for the presence of specific
+ component values.
+ </para>
+
+ <para>
+ Like GiST and SP-GiST, GIN can support
+ many different user-defined indexing strategies, and the particular
+ operators with which a GIN index can be used vary depending on the
+ indexing strategy.
+ As an example, the standard distribution of
+ <productname>PostgreSQL</productname> includes a GIN operator class
+ for arrays, which supports indexed queries using these operators:
+
+<synopsis>
+&lt;@ &nbsp; @&gt; &nbsp; = &nbsp; &amp;&amp;
+</synopsis>
+
+ (See <xref linkend="functions-array"/> for the meaning of
+ these operators.)
+ The GIN operator classes included in the standard distribution are
+ documented in <xref linkend="gin-builtin-opclasses-table"/>.
+ Many other GIN operator
+ classes are available in the <literal>contrib</literal> collection or as separate
+ projects. For more information see <xref linkend="gin"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="indexes-types-brin">
+ <title>BRIN</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>BRIN</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>BRIN</primary>
+ <see>index</see>
+ </indexterm>
+
+ <para>
+ BRIN indexes (a shorthand for Block Range INdexes) store summaries about
+ the values stored in consecutive physical block ranges of a table.
+ Thus, they are most effective for columns whose values are well-correlated
+ with the physical order of the table rows.
+ Like GiST, SP-GiST and GIN,
+ BRIN can support many different indexing strategies,
+ and the particular operators with which a BRIN index can be used
+ vary depending on the indexing strategy.
+ For data types that have a linear sort order, the indexed data
+ corresponds to the minimum and maximum values of the
+ values in the column for each block range. This supports indexed queries
+ using these operators:
+
+<synopsis>
+&lt; &nbsp; &lt;= &nbsp; = &nbsp; &gt;= &nbsp; &gt;
+</synopsis>
+
+ The BRIN operator classes included in the standard distribution are
+ documented in <xref linkend="brin-builtin-opclasses-table"/>.
+ For more information see <xref linkend="brin"/>.
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="indexes-multicolumn">
+ <title>Multicolumn Indexes</title>
+
+ <indexterm zone="indexes-multicolumn">
+ <primary>index</primary>
+ <secondary>multicolumn</secondary>
+ </indexterm>
+
+ <para>
+ An index can be defined on more than one column of a table. For example, if
+ you have a table of this form:
+<programlisting>
+CREATE TABLE test2 (
+ major int,
+ minor int,
+ name varchar
+);
+</programlisting>
+ (say, you keep your <filename class="directory">/dev</filename>
+ directory in a database...) and you frequently issue queries like:
+<programlisting>
+SELECT name FROM test2 WHERE major = <replaceable>constant</replaceable> AND minor = <replaceable>constant</replaceable>;
+</programlisting>
+ then it might be appropriate to define an index on the columns
+ <structfield>major</structfield> and
+ <structfield>minor</structfield> together, e.g.:
+<programlisting>
+CREATE INDEX test2_mm_idx ON test2 (major, minor);
+</programlisting>
+ </para>
+
+ <para>
+ Currently, only the B-tree, GiST, GIN, and BRIN index types support
+ multiple-key-column indexes. Whether there can be multiple key
+ columns is independent of whether <literal>INCLUDE</literal> columns
+ can be added to the index. Indexes can have up to 32 columns,
+ including <literal>INCLUDE</literal> columns. (This limit can be
+ altered when building <productname>PostgreSQL</productname>; see the
+ file <filename>pg_config_manual.h</filename>.)
+ </para>
+
+ <para>
+ A multicolumn B-tree index can be used with query conditions that
+ involve any subset of the index's columns, but the index is most
+ efficient when there are constraints on the leading (leftmost) columns.
+ The exact rule is that equality constraints on leading columns, plus
+ any inequality constraints on the first column that does not have an
+ equality constraint, will be used to limit the portion of the index
+ that is scanned. Constraints on columns to the right of these columns
+ are checked in the index, so they save visits to the table proper, but
+ they do not reduce the portion of the index that has to be scanned.
+ For example, given an index on <literal>(a, b, c)</literal> and a
+ query condition <literal>WHERE a = 5 AND b &gt;= 42 AND c &lt; 77</literal>,
+ the index would have to be scanned from the first entry with
+ <literal>a</literal> = 5 and <literal>b</literal> = 42 up through the last entry with
+ <literal>a</literal> = 5. Index entries with <literal>c</literal> &gt;= 77 would be
+ skipped, but they'd still have to be scanned through.
+ This index could in principle be used for queries that have constraints
+ on <literal>b</literal> and/or <literal>c</literal> with no constraint on <literal>a</literal>
+ &mdash; but the entire index would have to be scanned, so in most cases
+ the planner would prefer a sequential table scan over using the index.
+ </para>
+
+ <para>
+ A multicolumn GiST index can be used with query conditions that
+ involve any subset of the index's columns. Conditions on additional
+ columns restrict the entries returned by the index, but the condition on
+ the first column is the most important one for determining how much of
+ the index needs to be scanned. A GiST index will be relatively
+ ineffective if its first column has only a few distinct values, even if
+ there are many distinct values in additional columns.
+ </para>
+
+ <para>
+ A multicolumn GIN index can be used with query conditions that
+ involve any subset of the index's columns. Unlike B-tree or GiST,
+ index search effectiveness is the same regardless of which index column(s)
+ the query conditions use.
+ </para>
+
+ <para>
+ A multicolumn BRIN index can be used with query conditions that
+ involve any subset of the index's columns. Like GIN and unlike B-tree or
+ GiST, index search effectiveness is the same regardless of which index
+ column(s) the query conditions use. The only reason to have multiple BRIN
+ indexes instead of one multicolumn BRIN index on a single table is to have
+ a different <literal>pages_per_range</literal> storage parameter.
+ </para>
+
+ <para>
+ Of course, each column must be used with operators appropriate to the index
+ type; clauses that involve other operators will not be considered.
+ </para>
+
+ <para>
+ Multicolumn indexes should be used sparingly. In most situations,
+ an index on a single column is sufficient and saves space and time.
+ Indexes with more than three columns are unlikely to be helpful
+ unless the usage of the table is extremely stylized. See also
+ <xref linkend="indexes-bitmap-scans"/> and
+ <xref linkend="indexes-index-only-scans"/> for some discussion of the
+ merits of different index configurations.
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-ordering">
+ <title>Indexes and <literal>ORDER BY</literal></title>
+
+ <indexterm zone="indexes-ordering">
+ <primary>index</primary>
+ <secondary>and <literal>ORDER BY</literal></secondary>
+ </indexterm>
+
+ <para>
+ In addition to simply finding the rows to be returned by a query,
+ an index may be able to deliver them in a specific sorted order.
+ This allows a query's <literal>ORDER BY</literal> specification to be honored
+ without a separate sorting step. Of the index types currently
+ supported by <productname>PostgreSQL</productname>, only B-tree
+ can produce sorted output &mdash; the other index types return
+ matching rows in an unspecified, implementation-dependent order.
+ </para>
+
+ <para>
+ The planner will consider satisfying an <literal>ORDER BY</literal> specification
+ either by scanning an available index that matches the specification,
+ or by scanning the table in physical order and doing an explicit
+ sort. For a query that requires scanning a large fraction of the
+ table, an explicit sort is likely to be faster than using an index
+ because it requires
+ less disk I/O due to following a sequential access pattern. Indexes are
+ more useful when only a few rows need be fetched. An important
+ special case is <literal>ORDER BY</literal> in combination with
+ <literal>LIMIT</literal> <replaceable>n</replaceable>: an explicit sort will have to process
+ all the data to identify the first <replaceable>n</replaceable> rows, but if there is
+ an index matching the <literal>ORDER BY</literal>, the first <replaceable>n</replaceable>
+ rows can be retrieved directly, without scanning the remainder at all.
+ </para>
+
+ <para>
+ By default, B-tree indexes store their entries in ascending order
+ with nulls last (table TID is treated as a tiebreaker column among
+ otherwise equal entries). This means that a forward scan of an
+ index on column <literal>x</literal> produces output satisfying <literal>ORDER BY x</literal>
+ (or more verbosely, <literal>ORDER BY x ASC NULLS LAST</literal>). The
+ index can also be scanned backward, producing output satisfying
+ <literal>ORDER BY x DESC</literal>
+ (or more verbosely, <literal>ORDER BY x DESC NULLS FIRST</literal>, since
+ <literal>NULLS FIRST</literal> is the default for <literal>ORDER BY DESC</literal>).
+ </para>
+
+ <para>
+ You can adjust the ordering of a B-tree index by including the
+ options <literal>ASC</literal>, <literal>DESC</literal>, <literal>NULLS FIRST</literal>,
+ and/or <literal>NULLS LAST</literal> when creating the index; for example:
+<programlisting>
+CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
+CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
+</programlisting>
+ An index stored in ascending order with nulls first can satisfy
+ either <literal>ORDER BY x ASC NULLS FIRST</literal> or
+ <literal>ORDER BY x DESC NULLS LAST</literal> depending on which direction
+ it is scanned in.
+ </para>
+
+ <para>
+ You might wonder why bother providing all four options, when two
+ options together with the possibility of backward scan would cover
+ all the variants of <literal>ORDER BY</literal>. In single-column indexes
+ the options are indeed redundant, but in multicolumn indexes they can be
+ useful. Consider a two-column index on <literal>(x, y)</literal>: this can
+ satisfy <literal>ORDER BY x, y</literal> if we scan forward, or
+ <literal>ORDER BY x DESC, y DESC</literal> if we scan backward.
+ But it might be that the application frequently needs to use
+ <literal>ORDER BY x ASC, y DESC</literal>. There is no way to get that
+ ordering from a plain index, but it is possible if the index is defined
+ as <literal>(x ASC, y DESC)</literal> or <literal>(x DESC, y ASC)</literal>.
+ </para>
+
+ <para>
+ Obviously, indexes with non-default sort orderings are a fairly
+ specialized feature, but sometimes they can produce tremendous
+ speedups for certain queries. Whether it's worth maintaining such an
+ index depends on how often you use queries that require a special
+ sort ordering.
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-bitmap-scans">
+ <title>Combining Multiple Indexes</title>
+
+ <indexterm zone="indexes-bitmap-scans">
+ <primary>index</primary>
+ <secondary>combining multiple indexes</secondary>
+ </indexterm>
+
+ <indexterm zone="indexes-bitmap-scans">
+ <primary>bitmap scan</primary>
+ </indexterm>
+
+ <para>
+ A single index scan can only use query clauses that use the index's
+ columns with operators of its operator class and are joined with
+ <literal>AND</literal>. For example, given an index on <literal>(a, b)</literal>
+ a query condition like <literal>WHERE a = 5 AND b = 6</literal> could
+ use the index, but a query like <literal>WHERE a = 5 OR b = 6</literal> could not
+ directly use the index.
+ </para>
+
+ <para>
+ Fortunately,
+ <productname>PostgreSQL</productname> has the ability to combine multiple indexes
+ (including multiple uses of the same index) to handle cases that cannot
+ be implemented by single index scans. The system can form <literal>AND</literal>
+ and <literal>OR</literal> conditions across several index scans. For example,
+ a query like <literal>WHERE x = 42 OR x = 47 OR x = 53 OR x = 99</literal>
+ could be broken down into four separate scans of an index on <literal>x</literal>,
+ each scan using one of the query clauses. The results of these scans are
+ then ORed together to produce the result. Another example is that if we
+ have separate indexes on <literal>x</literal> and <literal>y</literal>, one possible
+ implementation of a query like <literal>WHERE x = 5 AND y = 6</literal> is to
+ use each index with the appropriate query clause and then AND together
+ the index results to identify the result rows.
+ </para>
+
+ <para>
+ To combine multiple indexes, the system scans each needed index and
+ prepares a <firstterm>bitmap</firstterm> in memory giving the locations of
+ table rows that are reported as matching that index's conditions.
+ The bitmaps are then ANDed and ORed together as needed by the query.
+ Finally, the actual table rows are visited and returned. The table rows
+ are visited in physical order, because that is how the bitmap is laid
+ out; this means that any ordering of the original indexes is lost, and
+ so a separate sort step will be needed if the query has an <literal>ORDER
+ BY</literal> clause. For this reason, and because each additional index scan
+ adds extra time, the planner will sometimes choose to use a simple index
+ scan even though additional indexes are available that could have been
+ used as well.
+ </para>
+
+ <para>
+ In all but the simplest applications, there are various combinations of
+ indexes that might be useful, and the database developer must make
+ trade-offs to decide which indexes to provide. Sometimes multicolumn
+ indexes are best, but sometimes it's better to create separate indexes
+ and rely on the index-combination feature. For example, if your
+ workload includes a mix of queries that sometimes involve only column
+ <literal>x</literal>, sometimes only column <literal>y</literal>, and sometimes both
+ columns, you might choose to create two separate indexes on
+ <literal>x</literal> and <literal>y</literal>, relying on index combination to
+ process the queries that use both columns. You could also create a
+ multicolumn index on <literal>(x, y)</literal>. This index would typically be
+ more efficient than index combination for queries involving both
+ columns, but as discussed in <xref linkend="indexes-multicolumn"/>, it
+ would be almost useless for queries involving only <literal>y</literal>, so it
+ should not be the only index. A combination of the multicolumn index
+ and a separate index on <literal>y</literal> would serve reasonably well. For
+ queries involving only <literal>x</literal>, the multicolumn index could be
+ used, though it would be larger and hence slower than an index on
+ <literal>x</literal> alone. The last alternative is to create all three
+ indexes, but this is probably only reasonable if the table is searched
+ much more often than it is updated and all three types of query are
+ common. If one of the types of query is much less common than the
+ others, you'd probably settle for creating just the two indexes that
+ best match the common types.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="indexes-unique">
+ <title>Unique Indexes</title>
+
+ <indexterm zone="indexes-unique">
+ <primary>index</primary>
+ <secondary>unique</secondary>
+ </indexterm>
+
+ <para>
+ Indexes can also be used to enforce uniqueness of a column's value,
+ or the uniqueness of the combined values of more than one column.
+<synopsis>
+CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <optional>, ...</optional>) <optional> NULLS <optional> NOT </optional> DISTINCT </optional>;
+</synopsis>
+ Currently, only B-tree indexes can be declared unique.
+ </para>
+
+ <para>
+ When an index is declared unique, multiple table rows with equal
+ indexed values are not allowed. By default, null values in a unique column
+ are not considered equal, allowing multiple nulls in the column. The
+ <literal>NULLS NOT DISTINCT</literal> option modifies this and causes the
+ index to treat nulls as equal. A multicolumn unique index will only reject
+ cases where all indexed columns are equal in multiple rows.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> automatically creates a unique
+ index when a unique constraint or primary key is defined for a table.
+ The index covers the columns that make up the primary key or unique
+ constraint (a multicolumn index, if appropriate), and is the mechanism
+ that enforces the constraint.
+ </para>
+
+ <note>
+ <para>
+ There's no need to manually
+ create indexes on unique columns; doing so would just duplicate
+ the automatically-created index.
+ </para>
+ </note>
+ </sect1>
+
+
+ <sect1 id="indexes-expressional">
+ <title>Indexes on Expressions</title>
+
+ <indexterm zone="indexes-expressional">
+ <primary>index</primary>
+ <secondary sortas="expressions">on expressions</secondary>
+ </indexterm>
+
+ <para>
+ An index column need not be just a column of the underlying table,
+ but can be a function or scalar expression computed from one or
+ more columns of the table. This feature is useful to obtain fast
+ access to tables based on the results of computations.
+ </para>
+
+ <para>
+ For example, a common way to do case-insensitive comparisons is to
+ use the <function>lower</function> function:
+<programlisting>
+SELECT * FROM test1 WHERE lower(col1) = 'value';
+</programlisting>
+ This query can use an index if one has been
+ defined on the result of the <literal>lower(col1)</literal>
+ function:
+<programlisting>
+CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
+</programlisting>
+ </para>
+
+ <para>
+ If we were to declare this index <literal>UNIQUE</literal>, it would prevent
+ creation of rows whose <literal>col1</literal> values differ only in case,
+ as well as rows whose <literal>col1</literal> values are actually identical.
+ Thus, indexes on expressions can be used to enforce constraints that
+ are not definable as simple unique constraints.
+ </para>
+
+ <para>
+ As another example, if one often does queries like:
+<programlisting>
+SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';
+</programlisting>
+ then it might be worth creating an index like this:
+<programlisting>
+CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
+</programlisting>
+ </para>
+
+ <para>
+ The syntax of the <command>CREATE INDEX</command> command normally requires
+ writing parentheses around index expressions, as shown in the second
+ example. The parentheses can be omitted when the expression is just
+ a function call, as in the first example.
+ </para>
+
+ <para>
+ Index expressions are relatively expensive to maintain, because the
+ derived expression(s) must be computed for each row insertion
+ and <link linkend="storage-hot">non-HOT update.</link> However, the index expressions are
+ <emphasis>not</emphasis> recomputed during an indexed search, since they are
+ already stored in the index. In both examples above, the system
+ sees the query as just <literal>WHERE indexedcolumn = 'constant'</literal>
+ and so the speed of the search is equivalent to any other simple index
+ query. Thus, indexes on expressions are useful when retrieval speed
+ is more important than insertion and update speed.
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-partial">
+ <title>Partial Indexes</title>
+
+ <indexterm zone="indexes-partial">
+ <primary>index</primary>
+ <secondary>partial</secondary>
+ </indexterm>
+
+ <para>
+ A <firstterm>partial index</firstterm> is an index built over a
+ subset of a table; the subset is defined by a conditional
+ expression (called the <firstterm>predicate</firstterm> of the
+ partial index). The index contains entries only for those table
+ rows that satisfy the predicate. Partial indexes are a specialized
+ feature, but there are several situations in which they are useful.
+ </para>
+
+ <para>
+ One major reason for using a partial index is to avoid indexing common
+ values. Since a query searching for a common value (one that
+ accounts for more than a few percent of all the table rows) will not
+ use the index anyway, there is no point in keeping those rows in the
+ index at all. This reduces the size of the index, which will speed
+ up those queries that do use the index. It will also speed up many table
+ update operations because the index does not need to be
+ updated in all cases. <xref linkend="indexes-partial-ex1"/> shows a
+ possible application of this idea.
+ </para>
+
+ <example id="indexes-partial-ex1">
+ <title>Setting up a Partial Index to Exclude Common Values</title>
+
+ <para>
+ Suppose you are storing web server access logs in a database.
+ Most accesses originate from the IP address range of your organization but
+ some are from elsewhere (say, employees on dial-up connections).
+ If your searches by IP are primarily for outside accesses,
+ you probably do not need to index the IP range that corresponds to your
+ organization's subnet.
+ </para>
+
+ <para>
+ Assume a table like this:
+<programlisting>
+CREATE TABLE access_log (
+ url varchar,
+ client_ip inet,
+ ...
+);
+</programlisting>
+ </para>
+
+ <para>
+ To create a partial index that suits our example, use a command
+ such as this:
+<programlisting>
+CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
+WHERE NOT (client_ip &gt; inet '192.168.100.0' AND
+ client_ip &lt; inet '192.168.100.255');
+</programlisting>
+ </para>
+
+ <para>
+ A typical query that can use this index would be:
+<programlisting>
+SELECT *
+FROM access_log
+WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';
+</programlisting>
+ Here the query's IP address is covered by the partial index. The
+ following query cannot use the partial index, as it uses an IP address
+ that is excluded from the index:
+<programlisting>
+SELECT *
+FROM access_log
+WHERE url = '/index.html' AND client_ip = inet '192.168.100.23';
+</programlisting>
+ </para>
+
+ <para>
+ Observe that this kind of partial index requires that the common
+ values be predetermined, so such partial indexes are best used for
+ data distributions that do not change. Such indexes can be recreated
+ occasionally to adjust for new data distributions, but this adds
+ maintenance effort.
+ </para>
+ </example>
+
+ <para>
+ Another possible use for a partial index is to exclude values from the
+ index that the
+ typical query workload is not interested in; this is shown in <xref
+ linkend="indexes-partial-ex2"/>. This results in the same
+ advantages as listed above, but it prevents the
+ <quote>uninteresting</quote> values from being accessed via that
+ index, even if an index scan might be profitable in that
+ case. Obviously, setting up partial indexes for this kind of
+ scenario will require a lot of care and experimentation.
+ </para>
+
+ <example id="indexes-partial-ex2">
+ <title>Setting up a Partial Index to Exclude Uninteresting Values</title>
+
+ <para>
+ If you have a table that contains both billed and unbilled orders,
+ where the unbilled orders take up a small fraction of the total
+ table and yet those are the most-accessed rows, you can improve
+ performance by creating an index on just the unbilled rows. The
+ command to create the index would look like this:
+<programlisting>
+CREATE INDEX orders_unbilled_index ON orders (order_nr)
+ WHERE billed is not true;
+</programlisting>
+ </para>
+
+ <para>
+ A possible query to use this index would be:
+<programlisting>
+SELECT * FROM orders WHERE billed is not true AND order_nr &lt; 10000;
+</programlisting>
+ However, the index can also be used in queries that do not involve
+ <structfield>order_nr</structfield> at all, e.g.:
+<programlisting>
+SELECT * FROM orders WHERE billed is not true AND amount &gt; 5000.00;
+</programlisting>
+ This is not as efficient as a partial index on the
+ <structfield>amount</structfield> column would be, since the system has to
+ scan the entire index. Yet, if there are relatively few unbilled
+ orders, using this partial index just to find the unbilled orders
+ could be a win.
+ </para>
+
+ <para>
+ Note that this query cannot use this index:
+<programlisting>
+SELECT * FROM orders WHERE order_nr = 3501;
+</programlisting>
+ The order 3501 might be among the billed or unbilled
+ orders.
+ </para>
+ </example>
+
+ <para>
+ <xref linkend="indexes-partial-ex2"/> also illustrates that the
+ indexed column and the column used in the predicate do not need to
+ match. <productname>PostgreSQL</productname> supports partial
+ indexes with arbitrary predicates, so long as only columns of the
+ table being indexed are involved. However, keep in mind that the
+ predicate must match the conditions used in the queries that
+ are supposed to benefit from the index. To be precise, a partial
+ index can be used in a query only if the system can recognize that
+ the <literal>WHERE</literal> condition of the query mathematically implies
+ the predicate of the index.
+ <productname>PostgreSQL</productname> does not have a sophisticated
+ theorem prover that can recognize mathematically equivalent
+ expressions that are written in different forms. (Not
+ only is such a general theorem prover extremely difficult to
+ create, it would probably be too slow to be of any real use.)
+ The system can recognize simple inequality implications, for example
+ <quote>x &lt; 1</quote> implies <quote>x &lt; 2</quote>; otherwise
+ the predicate condition must exactly match part of the query's
+ <literal>WHERE</literal> condition
+ or the index will not be recognized as usable. Matching takes
+ place at query planning time, not at run time. As a result,
+ parameterized query clauses do not work with a partial index. For
+ example a prepared query with a parameter might specify
+ <quote>x &lt; ?</quote> which will never imply
+ <quote>x &lt; 2</quote> for all possible values of the parameter.
+ </para>
+
+ <para>
+ A third possible use for partial indexes does not require the
+ index to be used in queries at all. The idea here is to create
+ a unique index over a subset of a table, as in <xref
+ linkend="indexes-partial-ex3"/>. This enforces uniqueness
+ among the rows that satisfy the index predicate, without constraining
+ those that do not.
+ </para>
+
+ <example id="indexes-partial-ex3">
+ <title>Setting up a Partial Unique Index</title>
+
+ <para>
+ Suppose that we have a table describing test outcomes. We wish
+ to ensure that there is only one <quote>successful</quote> entry for
+ a given subject and target combination, but there might be any number of
+ <quote>unsuccessful</quote> entries. Here is one way to do it:
+<programlisting>
+CREATE TABLE tests (
+ subject text,
+ target text,
+ success boolean,
+ ...
+);
+
+CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
+ WHERE success;
+</programlisting>
+ This is a particularly efficient approach when there are few
+ successful tests and many unsuccessful ones. It is also possible to
+ allow only one null in a column by creating a unique partial index
+ with an <literal>IS NULL</literal> restriction.
+ </para>
+
+ </example>
+
+ <para>
+ Finally, a partial index can also be used to override the system's
+ query plan choices. Also, data sets with peculiar
+ distributions might cause the system to use an index when it really
+ should not. In that case the index can be set up so that it is not
+ available for the offending query. Normally,
+ <productname>PostgreSQL</productname> makes reasonable choices about index
+ usage (e.g., it avoids them when retrieving common values, so the
+ earlier example really only saves index size, it is not required to
+ avoid index usage), and grossly incorrect plan choices are cause
+ for a bug report.
+ </para>
+
+ <para>
+ Keep in mind that setting up a partial index indicates that you
+ know at least as much as the query planner knows, in particular you
+ know when an index might be profitable. Forming this knowledge
+ requires experience and understanding of how indexes in
+ <productname>PostgreSQL</productname> work. In most cases, the
+ advantage of a partial index over a regular index will be minimal.
+ There are cases where they are quite counterproductive, as in <xref
+ linkend="indexes-partial-ex4"/>.
+ </para>
+
+ <example id="indexes-partial-ex4">
+ <title>Do Not Use Partial Indexes as a Substitute for Partitioning</title>
+
+ <para>
+ You might be tempted to create a large set of non-overlapping partial
+ indexes, for example
+
+<programlisting>
+CREATE INDEX mytable_cat_1 ON mytable (data) WHERE category = 1;
+CREATE INDEX mytable_cat_2 ON mytable (data) WHERE category = 2;
+CREATE INDEX mytable_cat_3 ON mytable (data) WHERE category = 3;
+...
+CREATE INDEX mytable_cat_<replaceable>N</replaceable> ON mytable (data) WHERE category = <replaceable>N</replaceable>;
+</programlisting>
+
+ This is a bad idea! Almost certainly, you'll be better off with a
+ single non-partial index, declared like
+
+<programlisting>
+CREATE INDEX mytable_cat_data ON mytable (category, data);
+</programlisting>
+
+ (Put the category column first, for the reasons described in
+ <xref linkend="indexes-multicolumn"/>.) While a search in this larger
+ index might have to descend through a couple more tree levels than a
+ search in a smaller index, that's almost certainly going to be cheaper
+ than the planner effort needed to select the appropriate one of the
+ partial indexes. The core of the problem is that the system does not
+ understand the relationship among the partial indexes, and will
+ laboriously test each one to see if it's applicable to the current
+ query.
+ </para>
+
+ <para>
+ If your table is large enough that a single index really is a bad idea,
+ you should look into using partitioning instead (see
+ <xref linkend="ddl-partitioning"/>). With that mechanism, the system
+ does understand that the tables and indexes are non-overlapping, so
+ far better performance is possible.
+ </para>
+ </example>
+
+ <para>
+ More information about partial indexes can be found in <xref
+ linkend="ston89b"/>, <xref linkend="olson93"/>, and <xref
+ linkend="seshadri95"/>.
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-index-only-scans">
+ <title>Index-Only Scans and Covering Indexes</title>
+
+ <indexterm zone="indexes-index-only-scans">
+ <primary>index</primary>
+ <secondary>index-only scans</secondary>
+ </indexterm>
+ <indexterm zone="indexes-index-only-scans">
+ <primary>index-only scan</primary>
+ </indexterm>
+ <indexterm zone="indexes-index-only-scans">
+ <primary>index</primary>
+ <secondary>covering</secondary>
+ </indexterm>
+ <indexterm zone="indexes-index-only-scans">
+ <primary>covering index</primary>
+ </indexterm>
+
+ <para>
+ All indexes in <productname>PostgreSQL</productname>
+ are <firstterm>secondary</firstterm> indexes, meaning that each index is
+ stored separately from the table's main data area (which is called the
+ table's <firstterm>heap</firstterm>
+ in <productname>PostgreSQL</productname> terminology). This means that
+ in an ordinary index scan, each row retrieval requires fetching data from
+ both the index and the heap. Furthermore, while the index entries that
+ match a given indexable <literal>WHERE</literal> condition are usually
+ close together in the index, the table rows they reference might be
+ anywhere in the heap. The heap-access portion of an index scan thus
+ involves a lot of random access into the heap, which can be slow,
+ particularly on traditional rotating media. (As described in
+ <xref linkend="indexes-bitmap-scans"/>, bitmap scans try to alleviate
+ this cost by doing the heap accesses in sorted order, but that only goes
+ so far.)
+ </para>
+
+ <para>
+ To solve this performance problem, <productname>PostgreSQL</productname>
+ supports <firstterm>index-only scans</firstterm>, which can answer
+ queries from an index alone without any heap access. The basic idea is
+ to return values directly out of each index entry instead of consulting
+ the associated heap entry. There are two fundamental restrictions on
+ when this method can be used:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ The index type must support index-only scans. B-tree indexes always
+ do. GiST and SP-GiST indexes support index-only scans for some
+ operator classes but not others. Other index types have no support.
+ The underlying requirement is that the index must physically store, or
+ else be able to reconstruct, the original data value for each index
+ entry. As a counterexample, GIN indexes cannot support index-only
+ scans because each index entry typically holds only part of the
+ original data value.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The query must reference only columns stored in the index. For
+ example, given an index on columns <literal>x</literal>
+ and <literal>y</literal> of a table that also has a
+ column <literal>z</literal>, these queries could use index-only scans:
+<programlisting>
+SELECT x, y FROM tab WHERE x = 'key';
+SELECT x FROM tab WHERE x = 'key' AND y &lt; 42;
+</programlisting>
+ but these queries could not:
+<programlisting>
+SELECT x, z FROM tab WHERE x = 'key';
+SELECT x FROM tab WHERE x = 'key' AND z &lt; 42;
+</programlisting>
+ (Expression indexes and partial indexes complicate this rule,
+ as discussed below.)
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ If these two fundamental requirements are met, then all the data values
+ required by the query are available from the index, so an index-only scan
+ is physically possible. But there is an additional requirement for any
+ table scan in <productname>PostgreSQL</productname>: it must verify that
+ each retrieved row be <quote>visible</quote> to the query's MVCC
+ snapshot, as discussed in <xref linkend="mvcc"/>. Visibility information
+ is not stored in index entries, only in heap entries; so at first glance
+ it would seem that every row retrieval would require a heap access
+ anyway. And this is indeed the case, if the table row has been modified
+ recently. However, for seldom-changing data there is a way around this
+ problem. <productname>PostgreSQL</productname> tracks, for each page in
+ a table's heap, whether all rows stored in that page are old enough to be
+ visible to all current and future transactions. This information is
+ stored in a bit in the table's <firstterm>visibility map</firstterm>. An
+ index-only scan, after finding a candidate index entry, checks the
+ visibility map bit for the corresponding heap page. If it's set, the row
+ is known visible and so the data can be returned with no further work.
+ If it's not set, the heap entry must be visited to find out whether it's
+ visible, so no performance advantage is gained over a standard index
+ scan. Even in the successful case, this approach trades visibility map
+ accesses for heap accesses; but since the visibility map is four orders
+ of magnitude smaller than the heap it describes, far less physical I/O is
+ needed to access it. In most situations the visibility map remains
+ cached in memory all the time.
+ </para>
+
+ <para>
+ In short, while an index-only scan is possible given the two fundamental
+ requirements, it will be a win only if a significant fraction of the
+ table's heap pages have their all-visible map bits set. But tables in
+ which a large fraction of the rows are unchanging are common enough to
+ make this type of scan very useful in practice.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary><literal>INCLUDE</literal></primary>
+ <secondary>in index definitions</secondary>
+ </indexterm>
+ To make effective use of the index-only scan feature, you might choose to
+ create a <firstterm>covering index</firstterm>, which is an index
+ specifically designed to include the columns needed by a particular
+ type of query that you run frequently. Since queries typically need to
+ retrieve more columns than just the ones they search
+ on, <productname>PostgreSQL</productname> allows you to create an index
+ in which some columns are just <quote>payload</quote> and are not part
+ of the search key. This is done by adding an <literal>INCLUDE</literal>
+ clause listing the extra columns. For example, if you commonly run
+ queries like
+<programlisting>
+SELECT y FROM tab WHERE x = 'key';
+</programlisting>
+ the traditional approach to speeding up such queries would be to create
+ an index on <literal>x</literal> only. However, an index defined as
+<programlisting>
+CREATE INDEX tab_x_y ON tab(x) INCLUDE (y);
+</programlisting>
+ could handle these queries as index-only scans,
+ because <literal>y</literal> can be obtained from the index without
+ visiting the heap.
+ </para>
+
+ <para>
+ Because column <literal>y</literal> is not part of the index's search
+ key, it does not have to be of a data type that the index can handle;
+ it's merely stored in the index and is not interpreted by the index
+ machinery. Also, if the index is a unique index, that is
+<programlisting>
+CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y);
+</programlisting>
+ the uniqueness condition applies to just column <literal>x</literal>,
+ not to the combination of <literal>x</literal> and <literal>y</literal>.
+ (An <literal>INCLUDE</literal> clause can also be written
+ in <literal>UNIQUE</literal> and <literal>PRIMARY KEY</literal>
+ constraints, providing alternative syntax for setting up an index like
+ this.)
+ </para>
+
+ <para>
+ It's wise to be conservative about adding non-key payload columns to an
+ index, especially wide columns. If an index tuple exceeds the
+ maximum size allowed for the index type, data insertion will fail.
+ In any case, non-key columns duplicate data from the index's table
+ and bloat the size of the index, thus potentially slowing searches.
+ And remember that there is little point in including payload columns in an
+ index unless the table changes slowly enough that an index-only scan is
+ likely to not need to access the heap. If the heap tuple must be visited
+ anyway, it costs nothing more to get the column's value from there.
+ Other restrictions are that expressions are not currently supported as
+ included columns, and that only B-tree, GiST and SP-GiST indexes currently
+ support included columns.
+ </para>
+
+ <para>
+ Before <productname>PostgreSQL</productname> had
+ the <literal>INCLUDE</literal> feature, people sometimes made covering
+ indexes by writing the payload columns as ordinary index columns,
+ that is writing
+<programlisting>
+CREATE INDEX tab_x_y ON tab(x, y);
+</programlisting>
+ even though they had no intention of ever using <literal>y</literal> as
+ part of a <literal>WHERE</literal> clause. This works fine as long as
+ the extra columns are trailing columns; making them be leading columns is
+ unwise for the reasons explained in <xref linkend="indexes-multicolumn"/>.
+ However, this method doesn't support the case where you want the index to
+ enforce uniqueness on the key column(s).
+ </para>
+
+ <para>
+ <firstterm>Suffix truncation</firstterm> always removes non-key
+ columns from upper B-Tree levels. As payload columns, they are
+ never used to guide index scans. The truncation process also
+ removes one or more trailing key column(s) when the remaining
+ prefix of key column(s) happens to be sufficient to describe tuples
+ on the lowest B-Tree level. In practice, covering indexes without
+ an <literal>INCLUDE</literal> clause often avoid storing columns
+ that are effectively payload in the upper levels. However,
+ explicitly defining payload columns as non-key columns
+ <emphasis>reliably</emphasis> keeps the tuples in upper levels
+ small.
+ </para>
+
+ <para>
+ In principle, index-only scans can be used with expression indexes.
+ For example, given an index on <literal>f(x)</literal>
+ where <literal>x</literal> is a table column, it should be possible to
+ execute
+<programlisting>
+SELECT f(x) FROM tab WHERE f(x) &lt; 1;
+</programlisting>
+ as an index-only scan; and this is very attractive
+ if <literal>f()</literal> is an expensive-to-compute function.
+ However, <productname>PostgreSQL</productname>'s planner is currently not
+ very smart about such cases. It considers a query to be potentially
+ executable by index-only scan only when all <emphasis>columns</emphasis>
+ needed by the query are available from the index. In this
+ example, <literal>x</literal> is not needed except in the
+ context <literal>f(x)</literal>, but the planner does not notice that and
+ concludes that an index-only scan is not possible. If an index-only scan
+ seems sufficiently worthwhile, this can be worked around by
+ adding <literal>x</literal> as an included column, for example
+<programlisting>
+CREATE INDEX tab_f_x ON tab (f(x)) INCLUDE (x);
+</programlisting>
+ An additional caveat, if the goal is to avoid
+ recalculating <literal>f(x)</literal>, is that the planner won't
+ necessarily match uses of <literal>f(x)</literal> that aren't in
+ indexable <literal>WHERE</literal> clauses to the index column. It will
+ usually get this right in simple queries such as shown above, but not in
+ queries that involve joins. These deficiencies may be remedied in future
+ versions of <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ Partial indexes also have interesting interactions with index-only scans.
+ Consider the partial index shown in <xref linkend="indexes-partial-ex3"/>:
+<programlisting>
+CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
+ WHERE success;
+</programlisting>
+ In principle, we could do an index-only scan on this index to satisfy a
+ query like
+<programlisting>
+SELECT target FROM tests WHERE subject = 'some-subject' AND success;
+</programlisting>
+ But there's a problem: the <literal>WHERE</literal> clause refers
+ to <literal>success</literal> which is not available as a result column
+ of the index. Nonetheless, an index-only scan is possible because the
+ plan does not need to recheck that part of the <literal>WHERE</literal>
+ clause at run time: all entries found in the index necessarily
+ have <literal>success = true</literal> so this need not be explicitly
+ checked in the plan. <productname>PostgreSQL</productname> versions 9.6
+ and later will recognize such cases and allow index-only scans to be
+ generated, but older versions will not.
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-opclass">
+ <title>Operator Classes and Operator Families</title>
+
+ <indexterm zone="indexes-opclass">
+ <primary>operator class</primary>
+ </indexterm>
+
+ <indexterm zone="indexes-opclass">
+ <primary>operator family</primary>
+ </indexterm>
+
+ <para>
+ An index definition can specify an <firstterm>operator
+ class</firstterm> for each column of an index.
+<synopsis>
+CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <replaceable>opclass</replaceable> [ ( <replaceable>opclass_options</replaceable> ) ] <optional><replaceable>sort options</replaceable></optional> <optional>, ...</optional>);
+</synopsis>
+ The operator class identifies the operators to be used by the index
+ for that column. For example, a B-tree index on the type <type>int4</type>
+ would use the <literal>int4_ops</literal> class; this operator
+ class includes comparison functions for values of type <type>int4</type>.
+ In practice the default operator class for the column's data type is
+ usually sufficient. The main reason for having operator classes is
+ that for some data types, there could be more than one meaningful
+ index behavior. For example, we might want to sort a complex-number data
+ type either by absolute value or by real part. We could do this by
+ defining two operator classes for the data type and then selecting
+ the proper class when making an index. The operator class determines
+ the basic sort ordering (which can then be modified by adding sort options
+ <literal>COLLATE</literal>,
+ <literal>ASC</literal>/<literal>DESC</literal> and/or
+ <literal>NULLS FIRST</literal>/<literal>NULLS LAST</literal>).
+ </para>
+
+ <para>
+ There are also some built-in operator classes besides the default ones:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The operator classes <literal>text_pattern_ops</literal>,
+ <literal>varchar_pattern_ops</literal>, and
+ <literal>bpchar_pattern_ops</literal> support B-tree indexes on
+ the types <type>text</type>, <type>varchar</type>, and
+ <type>char</type> respectively. The
+ difference from the default operator classes is that the values
+ are compared strictly character by character rather than
+ according to the locale-specific collation rules. This makes
+ these operator classes suitable for use by queries involving
+ pattern matching expressions (<literal>LIKE</literal> or POSIX
+ regular expressions) when the database does not use the standard
+ <quote>C</quote> locale. As an example, you might index a
+ <type>varchar</type> column like this:
+<programlisting>
+CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
+</programlisting>
+ Note that you should also create an index with the default operator
+ class if you want queries involving ordinary <literal>&lt;</literal>,
+ <literal>&lt;=</literal>, <literal>&gt;</literal>, or <literal>&gt;=</literal> comparisons
+ to use an index. Such queries cannot use the
+ <literal><replaceable>xxx</replaceable>_pattern_ops</literal>
+ operator classes. (Ordinary equality comparisons can use these
+ operator classes, however.) It is possible to create multiple
+ indexes on the same column with different operator classes.
+ If you do use the C locale, you do not need the
+ <literal><replaceable>xxx</replaceable>_pattern_ops</literal>
+ operator classes, because an index with the default operator class
+ is usable for pattern-matching queries in the C locale.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The following query shows all defined operator classes:
+
+<programlisting>
+SELECT am.amname AS index_method,
+ opc.opcname AS opclass_name,
+ opc.opcintype::regtype AS indexed_type,
+ opc.opcdefault AS is_default
+ FROM pg_am am, pg_opclass opc
+ WHERE opc.opcmethod = am.oid
+ ORDER BY index_method, opclass_name;
+</programlisting>
+ </para>
+
+ <para>
+ An operator class is actually just a subset of a larger structure called an
+ <firstterm>operator family</firstterm>. In cases where several data types have
+ similar behaviors, it is frequently useful to define cross-data-type
+ operators and allow these to work with indexes. To do this, the operator
+ classes for each of the types must be grouped into the same operator
+ family. The cross-type operators are members of the family, but are not
+ associated with any single class within the family.
+ </para>
+
+ <para>
+ This expanded version of the previous query shows the operator family
+ each operator class belongs to:
+<programlisting>
+SELECT am.amname AS index_method,
+ opc.opcname AS opclass_name,
+ opf.opfname AS opfamily_name,
+ opc.opcintype::regtype AS indexed_type,
+ opc.opcdefault AS is_default
+ FROM pg_am am, pg_opclass opc, pg_opfamily opf
+ WHERE opc.opcmethod = am.oid AND
+ opc.opcfamily = opf.oid
+ ORDER BY index_method, opclass_name;
+</programlisting>
+ </para>
+
+ <para>
+ This query shows all defined operator families and all
+ the operators included in each family:
+<programlisting>
+SELECT am.amname AS index_method,
+ opf.opfname AS opfamily_name,
+ amop.amopopr::regoperator AS opfamily_operator
+ FROM pg_am am, pg_opfamily opf, pg_amop amop
+ WHERE opf.opfmethod = am.oid AND
+ amop.amopfamily = opf.oid
+ ORDER BY index_method, opfamily_name, opfamily_operator;
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ <xref linkend="app-psql"/> has
+ commands <command>\dAc</command>, <command>\dAf</command>,
+ and <command>\dAo</command>, which provide slightly more sophisticated
+ versions of these queries.
+ </para>
+ </tip>
+ </sect1>
+
+
+ <sect1 id="indexes-collations">
+ <title>Indexes and Collations</title>
+
+ <para>
+ An index can support only one collation per index column.
+ If multiple collations are of interest, multiple indexes may be needed.
+ </para>
+
+ <para>
+ Consider these statements:
+<programlisting>
+CREATE TABLE test1c (
+ id integer,
+ content varchar COLLATE "x"
+);
+
+CREATE INDEX test1c_content_index ON test1c (content);
+</programlisting>
+ The index automatically uses the collation of the
+ underlying column. So a query of the form
+<programlisting>
+SELECT * FROM test1c WHERE content &gt; <replaceable>constant</replaceable>;
+</programlisting>
+ could use the index, because the comparison will by default use the
+ collation of the column. However, this index cannot accelerate queries
+ that involve some other collation. So if queries of the form, say,
+<programlisting>
+SELECT * FROM test1c WHERE content &gt; <replaceable>constant</replaceable> COLLATE "y";
+</programlisting>
+ are also of interest, an additional index could be created that supports
+ the <literal>"y"</literal> collation, like this:
+<programlisting>
+CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y");
+</programlisting>
+ </para>
+ </sect1>
+
+
+ <sect1 id="indexes-examine">
+ <title>Examining Index Usage</title>
+
+ <indexterm zone="indexes-examine">
+ <primary>index</primary>
+ <secondary>examining usage</secondary>
+ </indexterm>
+
+ <para>
+ Although indexes in <productname>PostgreSQL</productname> do not need
+ maintenance or tuning, it is still important to check
+ which indexes are actually used by the real-life query workload.
+ Examining index usage for an individual query is done with the
+ <xref linkend="sql-explain"/>
+ command; its application for this purpose is
+ illustrated in <xref linkend="using-explain"/>.
+ It is also possible to gather overall statistics about index usage
+ in a running server, as described in <xref linkend="monitoring-stats"/>.
+ </para>
+
+ <para>
+ It is difficult to formulate a general procedure for determining
+ which indexes to create. There are a number of typical cases that
+ have been shown in the examples throughout the previous sections.
+ A good deal of experimentation is often necessary.
+ The rest of this section gives some tips for that:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Always run <xref linkend="sql-analyze"/>
+ first. This command
+ collects statistics about the distribution of the values in the
+ table. This information is required to estimate the number of rows
+ returned by a query, which is needed by the planner to assign
+ realistic costs to each possible query plan. In absence of any
+ real statistics, some default values are assumed, which are
+ almost certain to be inaccurate. Examining an application's
+ index usage without having run <command>ANALYZE</command> is
+ therefore a lost cause.
+ See <xref linkend="vacuum-for-statistics"/>
+ and <xref linkend="autovacuum"/> for more information.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Use real data for experimentation. Using test data for setting
+ up indexes will tell you what indexes you need for the test data,
+ but that is all.
+ </para>
+
+ <para>
+ It is especially fatal to use very small test data sets.
+ While selecting 1000 out of 100000 rows could be a candidate for
+ an index, selecting 1 out of 100 rows will hardly be, because the
+ 100 rows probably fit within a single disk page, and there
+ is no plan that can beat sequentially fetching 1 disk page.
+ </para>
+
+ <para>
+ Also be careful when making up test data, which is often
+ unavoidable when the application is not yet in production.
+ Values that are very similar, completely random, or inserted in
+ sorted order will skew the statistics away from the distribution
+ that real data would have.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When indexes are not used, it can be useful for testing to force
+ their use. There are run-time parameters that can turn off
+ various plan types (see <xref linkend="runtime-config-query-enable"/>).
+ For instance, turning off sequential scans
+ (<varname>enable_seqscan</varname>) and nested-loop joins
+ (<varname>enable_nestloop</varname>), which are the most basic plans,
+ will force the system to use a different plan. If the system
+ still chooses a sequential scan or nested-loop join then there is
+ probably a more fundamental reason why the index is not being
+ used; for example, the query condition does not match the index.
+ (What kind of query can use what kind of index is explained in
+ the previous sections.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If forcing index usage does use the index, then there are two
+ possibilities: Either the system is right and using the index is
+ indeed not appropriate, or the cost estimates of the query plans
+ are not reflecting reality. So you should time your query with
+ and without indexes. The <command>EXPLAIN ANALYZE</command>
+ command can be useful here.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If it turns out that the cost estimates are wrong, there are,
+ again, two possibilities. The total cost is computed from the
+ per-row costs of each plan node times the selectivity estimate of
+ the plan node. The costs estimated for the plan nodes can be adjusted
+ via run-time parameters (described in <xref
+ linkend="runtime-config-query-constants"/>).
+ An inaccurate selectivity estimate is due to
+ insufficient statistics. It might be possible to improve this by
+ tuning the statistics-gathering parameters (see
+ <xref linkend="sql-altertable"/>).
+ </para>
+
+ <para>
+ If you do not succeed in adjusting the costs to be more
+ appropriate, then you might have to resort to forcing index usage
+ explicitly. You might also want to contact the
+ <productname>PostgreSQL</productname> developers to examine the issue.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/info.sgml b/doc/src/sgml/info.sgml
new file mode 100644
index 0000000..6b9f1b5
--- /dev/null
+++ b/doc/src/sgml/info.sgml
@@ -0,0 +1,69 @@
+<!-- doc/src/sgml/info.sgml -->
+
+<sect1 id="resources">
+ <title>Further Information</title>
+
+ <para>
+ Besides the documentation, that is, this book, there are other
+ resources about <productname>PostgreSQL</productname>:
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Wiki</term>
+ <listitem>
+ <para>
+ The <productname>PostgreSQL</productname> <ulink
+ url="https://wiki.postgresql.org">wiki</ulink> contains the project's <ulink
+ url="https://wiki.postgresql.org/wiki/Frequently_Asked_Questions">FAQ</ulink>
+ (Frequently Asked Questions) list, <ulink
+ url="https://wiki.postgresql.org/wiki/Todo">TODO</ulink> list, and
+ detailed information about many more topics.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Web Site</term>
+ <listitem>
+ <para>
+ The <productname>PostgreSQL</productname>
+ <ulink url="https://www.postgresql.org">web site</ulink>
+ carries details on the latest release and other
+ information to make your work or play with
+ <productname>PostgreSQL</productname> more productive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Mailing Lists</term>
+ <listitem>
+ <para>
+ The mailing lists are a good place to have your questions
+ answered, to share experiences with other users, and to contact
+ the developers. Consult the <productname>PostgreSQL</productname> web site
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Yourself!</term>
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> is an open-source project.
+ As such, it depends on the user community for ongoing support.
+ As you begin to use <productname>PostgreSQL</productname>, you
+ will rely on others for help, either through the documentation
+ or through the mailing lists. Consider contributing your
+ knowledge back. Read the mailing lists and answer questions. If
+ you learn something which is not in the documentation, write it
+ up and contribute it. If you add features to the code,
+ contribute them.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+</sect1>
diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml
new file mode 100644
index 0000000..350c75b
--- /dev/null
+++ b/doc/src/sgml/information_schema.sgml
@@ -0,0 +1,8680 @@
+<!-- doc/src/sgml/information_schema.sgml -->
+
+<chapter id="information-schema">
+ <title>The Information Schema</title>
+
+ <indexterm zone="information-schema">
+ <primary>information schema</primary>
+ </indexterm>
+
+ <para>
+ The information schema consists of a set of views that contain
+ information about the objects defined in the current database. The
+ information schema is defined in the SQL standard and can therefore
+ be expected to be portable and remain stable &mdash; unlike the system
+ catalogs, which are specific to
+ <productname>PostgreSQL</productname> and are modeled after
+ implementation concerns. The information schema views do not,
+ however, contain information about
+ <productname>PostgreSQL</productname>-specific features; to inquire
+ about those you need to query the system catalogs or other
+ <productname>PostgreSQL</productname>-specific views.
+ </para>
+
+ <note>
+ <para>
+ When querying the database for constraint information, it is possible
+ for a standard-compliant query that expects to return one row to
+ return several. This is because the SQL standard requires constraint
+ names to be unique within a schema, but
+ <productname>PostgreSQL</productname> does not enforce this
+ restriction. <productname>PostgreSQL</productname>
+ automatically-generated constraint names avoid duplicates in the
+ same schema, but users can specify such duplicate names.
+ </para>
+
+ <para>
+ This problem can appear when querying information schema views such
+ as <literal>check_constraint_routine_usage</literal>,
+ <literal>check_constraints</literal>, <literal>domain_constraints</literal>, and
+ <literal>referential_constraints</literal>. Some other views have similar
+ issues but contain the table name to help distinguish duplicate
+ rows, e.g., <literal>constraint_column_usage</literal>,
+ <literal>constraint_table_usage</literal>, <literal>table_constraints</literal>.
+ </para>
+ </note>
+
+
+ <sect1 id="infoschema-schema">
+ <title>The Schema</title>
+
+ <para>
+ The information schema itself is a schema named
+ <literal>information_schema</literal>. This schema automatically
+ exists in all databases. The owner of this schema is the initial
+ database user in the cluster, and that user naturally has all the
+ privileges on this schema, including the ability to drop it (but
+ the space savings achieved by that are minuscule).
+ </para>
+
+ <para>
+ By default, the information schema is not in the schema search
+ path, so you need to access all objects in it through qualified
+ names. Since the names of some of the objects in the information
+ schema are generic names that might occur in user applications, you
+ should be careful if you want to put the information schema in the
+ path.
+ </para>
+ </sect1>
+
+ <sect1 id="infoschema-datatypes">
+ <title>Data Types</title>
+
+ <para>
+ The columns of the information schema views use special data types
+ that are defined in the information schema. These are defined as
+ simple domains over ordinary built-in types. You should not use
+ these types for work outside the information schema, but your
+ applications must be prepared for them if they select from the
+ information schema.
+ </para>
+
+ <para>
+ These types are:
+
+ <variablelist>
+ <varlistentry>
+ <term><type>cardinal_number</type></term>
+ <listitem>
+ <para>
+ A nonnegative integer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><type>character_data</type></term>
+ <listitem>
+ <para>
+ A character string (without specific maximum length).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><type>sql_identifier</type></term>
+ <listitem>
+ <para>
+ A character string. This type is used for SQL identifiers, the
+ type <type>character_data</type> is used for any other kind of
+ text data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><type>time_stamp</type></term>
+ <listitem>
+ <para>
+ A domain over the type <type>timestamp with time zone</type>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><type>yes_or_no</type></term>
+ <listitem>
+ <para>
+ A character string domain that contains
+ either <literal>YES</literal> or <literal>NO</literal>. This
+ is used to represent Boolean (true/false) data in the
+ information schema. (The information schema was invented
+ before the type <type>boolean</type> was added to the SQL
+ standard, so this convention is necessary to keep the
+ information schema backward compatible.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Every column in the information schema has one of these five types.
+ </para>
+ </sect1>
+
+ <sect1 id="infoschema-information-schema-catalog-name">
+ <title><literal>information_schema_catalog_name</literal></title>
+
+ <para>
+ <literal>information_schema_catalog_name</literal> is a table that
+ always contains one row and one column containing the name of the
+ current database (current catalog, in SQL terminology).
+ </para>
+
+ <table>
+ <title><structname>information_schema_catalog_name</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>catalog_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains this information schema
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-administrable-role-authorizations">
+ <title><literal>administrable_role_&zwsp;authorizations</literal></title>
+
+ <para>
+ The view <literal>administrable_role_authorizations</literal>
+ identifies all roles that the current user has the admin option
+ for.
+ </para>
+
+ <table>
+ <title><structname>administrable_role_authorizations</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role to which this role membership was granted (can
+ be the current user, or a different role in case of nested role
+ memberships)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>role_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of a role
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Always <literal>YES</literal>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-applicable-roles">
+ <title><literal>applicable_roles</literal></title>
+
+ <para>
+ The view <literal>applicable_roles</literal> identifies all roles
+ whose privileges the current user can use. This means there is
+ some chain of role grants from the current user to the role in
+ question. The current user itself is also an applicable role. The
+ set of applicable roles is generally used for permission checking.
+ <indexterm><primary>applicable role</primary></indexterm>
+ <indexterm><primary>role</primary><secondary>applicable</secondary></indexterm>
+ </para>
+
+ <table>
+ <title><structname>applicable_roles</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role to which this role membership was granted (can
+ be the current user, or a different role in case of nested role
+ memberships)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>role_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of a role
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the grantee has the admin option on
+ the role, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-attributes">
+ <title><literal>attributes</literal></title>
+
+ <para>
+ The view <literal>attributes</literal> contains information about
+ the attributes of composite data types defined in the database.
+ (Note that the view does not give information about table columns,
+ which are sometimes called attributes in PostgreSQL contexts.)
+ Only those attributes are shown that the current user has access to (by way
+ of being the owner of or having some privilege on the type).
+ </para>
+
+ <table>
+ <title><structname>attributes</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the data type (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attribute_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the attribute
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordinal_position</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Ordinal position of the attribute within the data type (count starts at 1)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attribute_default</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Default expression of the attribute
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_nullable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the attribute is possibly nullable,
+ <literal>NO</literal> if it is known not nullable.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Data type of the attribute, if it is a built-in type, or
+ <literal>ARRAY</literal> if it is some array (in that case, see
+ the view <literal>element_types</literal>), else
+ <literal>USER-DEFINED</literal> (in that case, the type is
+ identified in <literal>attribute_udt_name</literal> and
+ associated columns).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a character or bit
+ string type, the declared maximum length; null for all other
+ data types or if no maximum length was declared.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a character type,
+ the maximum possible length in octets (bytes) of a datum; null
+ for all other data types. The maximum octet length depends on
+ the declared character maximum length (see above) and the
+ server encoding.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the collation of the attribute
+ (always the current database), null if default or the data type
+ of the attribute is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the collation of the attribute,
+ null if default or the data type of the attribute is not
+ collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the collation of the attribute, null if default or the
+ data type of the attribute is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a numeric type, this
+ column contains the (declared or implicit) precision of the
+ type for this attribute. The precision indicates the number of
+ significant digits. It can be expressed in decimal (base 10)
+ or binary (base 2) terms, as specified in the column
+ <literal>numeric_precision_radix</literal>. For all other data
+ types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a numeric type, this
+ column indicates in which base the values in the columns
+ <literal>numeric_precision</literal> and
+ <literal>numeric_scale</literal> are expressed. The value is
+ either 2 or 10. For all other data types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies an exact numeric
+ type, this column contains the (declared or implicit) scale of
+ the type for this attribute. The scale indicates the number of
+ significant digits to the right of the decimal point. It can
+ be expressed in decimal (base 10) or binary (base 2) terms, as
+ specified in the column
+ <literal>numeric_precision_radix</literal>. For all other data
+ types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a date, time,
+ timestamp, or interval type, this column contains the (declared
+ or implicit) fractional seconds precision of the type for this
+ attribute, that is, the number of decimal digits maintained
+ following the decimal point in the seconds value. For all
+ other data types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies an interval type,
+ this column contains the specification which fields the
+ intervals include for this attribute, e.g., <literal>YEAR TO
+ MONTH</literal>, <literal>DAY TO SECOND</literal>, etc. If no
+ field restrictions were specified (that is, the interval
+ accepts all fields), and for all other data types, this field
+ is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available
+ in <productname>PostgreSQL</productname>
+ (see <literal>datetime_precision</literal> for the fractional
+ seconds precision of interval type attributes)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attribute_udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the attribute data type is defined in
+ (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attribute_udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the attribute data type is defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attribute_udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the attribute data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ An identifier of the data type descriptor of the column, unique
+ among the data type descriptors pertaining to the table. This
+ is mainly useful for joining with other instances of such
+ identifiers. (The specific format of the identifier is not
+ defined and not guaranteed to remain the same in future
+ versions.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_derived_reference_attribute</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ See also under <xref linkend="infoschema-columns"/>, a similarly
+ structured view, for further information on some of the columns.
+ </para>
+ </sect1>
+
+ <sect1 id="infoschema-character-sets">
+ <title><literal>character_sets</literal></title>
+
+ <para>
+ The view <literal>character_sets</literal> identifies the character
+ sets available in the current database. Since PostgreSQL does not
+ support multiple character sets within one database, this view only
+ shows one, which is the database encoding.
+ </para>
+
+ <para>
+ Take note of how the following terms are used in the SQL standard:
+ <variablelist>
+ <varlistentry>
+ <term>character repertoire</term>
+ <listitem>
+ <para>
+ An abstract collection of characters, for
+ example <literal>UNICODE</literal>, <literal>UCS</literal>, or
+ <literal>LATIN1</literal>. Not exposed as an SQL object, but
+ visible in this view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>character encoding form</term>
+ <listitem>
+ <para>
+ An encoding of some character repertoire. Most older character
+ repertoires only use one encoding form, and so there are no
+ separate names for them (e.g., <literal>LATIN1</literal> is an
+ encoding form applicable to the <literal>LATIN1</literal>
+ repertoire). But for example Unicode has the encoding forms
+ <literal>UTF8</literal>, <literal>UTF16</literal>, etc. (not
+ all supported by PostgreSQL). Encoding forms are not exposed
+ as an SQL object, but are visible in this view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>character set</term>
+ <listitem>
+ <para>
+ A named SQL object that identifies a character repertoire, a
+ character encoding, and a default collation. A predefined
+ character set would typically have the same name as an encoding
+ form, but users could define other names. For example, the
+ character set <literal>UTF8</literal> would typically identify
+ the character repertoire <literal>UCS</literal>, encoding
+ form <literal>UTF8</literal>, and some default collation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ You can think of an <quote>encoding</quote> in PostgreSQL either as
+ a character set or a character encoding form. They will have the
+ same name, and there can only be one in one database.
+ </para>
+
+ <table>
+ <title><structname>character_sets</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Character sets are currently not implemented as schema objects, so this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Character sets are currently not implemented as schema objects, so this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the character set, currently implemented as showing the name of the database encoding
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_repertoire</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Character repertoire, showing <literal>UCS</literal> if the encoding is <literal>UTF8</literal>, else just the encoding name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>form_of_use</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Character encoding form, same as the database encoding
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_collate_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the default collation (always the current database, if any collation is identified)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_collate_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the default collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_collate_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the default collation. The default collation is
+ identified as the collation that matches
+ the <literal>COLLATE</literal> and <literal>CTYPE</literal>
+ settings of the current database. If there is no such
+ collation, then this column and the associated schema and
+ catalog columns are null.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-check-constraint-routine-usage">
+ <title><literal>check_constraint_routine_usage</literal></title>
+
+ <para>
+ The view <literal>check_constraint_routine_usage</literal>
+ identifies routines (functions and procedures) that are used by a
+ check constraint. Only those routines are shown that are owned by
+ a currently enabled role.
+ </para>
+
+ <table>
+ <title><structname>check_constraint_routine_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-check-constraints">
+ <title><literal>check_constraints</literal></title>
+
+ <para>
+ The view <literal>check_constraints</literal> contains all check
+ constraints, either defined on a table or on a domain, that are
+ owned by a currently enabled role. (The owner of the table or
+ domain is the owner of the constraint.)
+ </para>
+
+ <table>
+ <title><structname>check_constraints</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>check_clause</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The check expression of the check constraint
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-collations">
+ <title><literal>collations</literal></title>
+
+ <para>
+ The view <literal>collations</literal> contains the collations
+ available in the current database.
+ </para>
+
+ <table>
+ <title><structname>collations</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the collation (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the default collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pad_attribute</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>NO PAD</literal> (The alternative <literal>PAD
+ SPACE</literal> is not supported by PostgreSQL.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-collation-character-set-applicab"> <!-- max 44 characters -->
+ <title><literal>collation_character_set_&zwsp;applicability</literal></title>
+
+ <para>
+ The view <literal>collation_character_set_applicability</literal>
+ identifies which character set the available collations are
+ applicable to. In PostgreSQL, there is only one character set per
+ database (see explanation
+ in <xref linkend="infoschema-character-sets"/>), so this view does
+ not provide much useful information.
+ </para>
+
+ <table>
+ <title><structname>collation_character_set_applicability</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the collation (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the default collation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Character sets are currently not implemented as schema objects, so this column is null
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Character sets are currently not implemented as schema objects, so this column is null
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the character set
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-column-column-usage">
+ <title><literal>column_column_usage</literal></title>
+
+ <para>
+ The view <literal>column_column_usage</literal> identifies all generated
+ columns that depend on another base column in the same table. Only tables
+ owned by a currently enabled role are included.
+ </para>
+
+ <table>
+ <title><structname>column_column_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the base column that a generated column depends on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dependent_column</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the generated column
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-column-domain-usage">
+ <title><literal>column_domain_usage</literal></title>
+
+ <para>
+ The view <literal>column_domain_usage</literal> identifies all
+ columns (of a table or a view) that make use of some domain defined
+ in the current database and owned by a currently enabled role.
+ </para>
+
+ <table>
+ <title><structname>column_domain_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the domain (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-column-options">
+ <title><literal>column_options</literal></title>
+
+ <para>
+ The view <literal>column_options</literal> contains all the
+ options defined for foreign table columns in the current database. Only
+ those foreign table columns are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>column_options</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the foreign table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of an option
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Value of the option
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-column-privileges">
+ <title><literal>column_privileges</literal></title>
+
+ <para>
+ The view <literal>column_privileges</literal> identifies all
+ privileges granted on columns to a currently enabled role or by a
+ currently enabled role. There is one row for each combination of
+ column, grantor, and grantee.
+ </para>
+
+ <para>
+ If a privilege has been granted on an entire table, it will show up in
+ this view as a grant for each column, but only for the
+ privilege types where column granularity is possible:
+ <literal>SELECT</literal>, <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, <literal>REFERENCES</literal>.
+ </para>
+
+ <table>
+ <title><structname>column_privileges</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that contains the column (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that contains the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that contains the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Type of the privilege: <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>, or
+ <literal>REFERENCES</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-column-udt-usage">
+ <title><literal>column_udt_usage</literal></title>
+
+ <para>
+ The view <literal>column_udt_usage</literal> identifies all columns
+ that use data types owned by a currently enabled role. Note that in
+ <productname>PostgreSQL</productname>, built-in data types behave
+ like user-defined types, so they are included here as well. See
+ also <xref linkend="infoschema-columns"/> for details.
+ </para>
+
+ <table>
+ <title><structname>column_udt_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the column data type (the underlying
+ type of the domain, if applicable) is defined in (always the
+ current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the column data type (the underlying
+ type of the domain, if applicable) is defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column data type (the underlying type of the
+ domain, if applicable)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-columns">
+ <title><literal>columns</literal></title>
+
+ <para>
+ The view <literal>columns</literal> contains information about all
+ table columns (or view columns) in the database. System columns
+ (<literal>ctid</literal>, etc.) are not included. Only those columns are
+ shown that the current user has access to (by way of being the
+ owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>columns</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordinal_position</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Ordinal position of the column within the table (count starts at 1)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_default</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Default expression of the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_nullable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the column is possibly nullable,
+ <literal>NO</literal> if it is known not nullable. A not-null
+ constraint is one way a column can be known not nullable, but
+ there can be others.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Data type of the column, if it is a built-in type, or
+ <literal>ARRAY</literal> if it is some array (in that case, see
+ the view <literal>element_types</literal>), else
+ <literal>USER-DEFINED</literal> (in that case, the type is
+ identified in <literal>udt_name</literal> and associated
+ columns). If the column is based on a domain, this column
+ refers to the type underlying the domain (and the domain is
+ identified in <literal>domain_name</literal> and associated
+ columns).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a character or bit
+ string type, the declared maximum length; null for all other
+ data types or if no maximum length was declared.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a character type,
+ the maximum possible length in octets (bytes) of a datum; null
+ for all other data types. The maximum octet length depends on
+ the declared character maximum length (see above) and the
+ server encoding.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a numeric type, this
+ column contains the (declared or implicit) precision of the
+ type for this column. The precision indicates the number of
+ significant digits. It can be expressed in decimal (base 10)
+ or binary (base 2) terms, as specified in the column
+ <literal>numeric_precision_radix</literal>. For all other data
+ types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a numeric type, this
+ column indicates in which base the values in the columns
+ <literal>numeric_precision</literal> and
+ <literal>numeric_scale</literal> are expressed. The value is
+ either 2 or 10. For all other data types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies an exact numeric
+ type, this column contains the (declared or implicit) scale of
+ the type for this column. The scale indicates the number of
+ significant digits to the right of the decimal point. It can
+ be expressed in decimal (base 10) or binary (base 2) terms, as
+ specified in the column
+ <literal>numeric_precision_radix</literal>. For all other data
+ types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a date, time,
+ timestamp, or interval type, this column contains the (declared
+ or implicit) fractional seconds precision of the type for this
+ column, that is, the number of decimal digits maintained
+ following the decimal point in the seconds value. For all
+ other data types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies an interval type,
+ this column contains the specification which fields the
+ intervals include for this column, e.g., <literal>YEAR TO
+ MONTH</literal>, <literal>DAY TO SECOND</literal>, etc. If no
+ field restrictions were specified (that is, the interval
+ accepts all fields), and for all other data types, this field
+ is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available
+ in <productname>PostgreSQL</productname>
+ (see <literal>datetime_precision</literal> for the fractional
+ seconds precision of interval type columns)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the collation of the column
+ (always the current database), null if default or the data type
+ of the column is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the collation of the column, null
+ if default or the data type of the column is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the collation of the column, null if default or the
+ data type of the column is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ If the column has a domain type, the name of the database that
+ the domain is defined in (always the current database), else
+ null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ If the column has a domain type, the name of the schema that
+ the domain is defined in, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ If the column has a domain type, the name of the domain, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the column data type (the underlying
+ type of the domain, if applicable) is defined in (always the
+ current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the column data type (the underlying
+ type of the domain, if applicable) is defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column data type (the underlying type of the
+ domain, if applicable)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ An identifier of the data type descriptor of the column, unique
+ among the data type descriptors pertaining to the table. This
+ is mainly useful for joining with other instances of such
+ identifiers. (The specific format of the identifier is not
+ defined and not guaranteed to remain the same in future
+ versions.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_self_referencing</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_identity</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ If the column is an identity column, then <literal>YES</literal>,
+ else <literal>NO</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>identity_generation</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is an identity column, then <literal>ALWAYS</literal>
+ or <literal>BY DEFAULT</literal>, reflecting the definition of the
+ column.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>identity_start</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is an identity column, then the start value of the
+ internal sequence, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>identity_increment</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is an identity column, then the increment of the internal
+ sequence, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>identity_maximum</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is an identity column, then the maximum value of the
+ internal sequence, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>identity_minimum</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is an identity column, then the minimum value of the
+ internal sequence, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>identity_cycle</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ If the column is an identity column, then <literal>YES</literal> if the
+ internal sequence cycles or <literal>NO</literal> if it does not;
+ otherwise null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_generated</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is a generated column, then <literal>ALWAYS</literal>,
+ else <literal>NEVER</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>generation_expression</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the column is a generated column, then the generation expression,
+ else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_updatable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the column is updatable,
+ <literal>NO</literal> if not (Columns in base tables are always
+ updatable, columns in views not necessarily)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Since data types can be defined in a variety of ways in SQL, and
+ <productname>PostgreSQL</productname> contains additional ways to
+ define data types, their representation in the information schema
+ can be somewhat difficult. The column <literal>data_type</literal>
+ is supposed to identify the underlying built-in type of the column.
+ In <productname>PostgreSQL</productname>, this means that the type
+ is defined in the system catalog schema
+ <literal>pg_catalog</literal>. This column might be useful if the
+ application can handle the well-known built-in types specially (for
+ example, format the numeric types differently or use the data in
+ the precision columns). The columns <literal>udt_name</literal>,
+ <literal>udt_schema</literal>, and <literal>udt_catalog</literal>
+ always identify the underlying data type of the column, even if the
+ column is based on a domain. (Since
+ <productname>PostgreSQL</productname> treats built-in types like
+ user-defined types, built-in types appear here as well. This is an
+ extension of the SQL standard.) These columns should be used if an
+ application wants to process data differently according to the
+ type, because in that case it wouldn't matter if the column is
+ really based on a domain. If the column is based on a domain, the
+ identity of the domain is stored in the columns
+ <literal>domain_name</literal>, <literal>domain_schema</literal>,
+ and <literal>domain_catalog</literal>. If you want to pair up
+ columns with their associated data types and treat domains as
+ separate types, you could write <literal>coalesce(domain_name,
+ udt_name)</literal>, etc.
+ </para>
+ </sect1>
+
+ <sect1 id="infoschema-constraint-column-usage">
+ <title><literal>constraint_column_usage</literal></title>
+
+ <para>
+ The view <literal>constraint_column_usage</literal> identifies all
+ columns in the current database that are used by some constraint.
+ Only those columns are shown that are contained in a table owned by
+ a currently enabled role. For a check constraint, this view
+ identifies the columns that are used in the check expression. For
+ a foreign key constraint, this view identifies the columns that the
+ foreign key references. For a unique or primary key constraint,
+ this view identifies the constrained columns.
+ </para>
+
+ <table>
+ <title><structname>constraint_column_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that contains the
+ column that is used by some constraint (always the current
+ database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that contains the
+ column that is used by some constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that contains the column that is used by some
+ constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column that is used by some constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-constraint-table-usage">
+ <title><literal>constraint_table_usage</literal></title>
+
+ <para>
+ The view <literal>constraint_table_usage</literal> identifies all
+ tables in the current database that are used by some constraint and
+ are owned by a currently enabled role. (This is different from the
+ view <literal>table_constraints</literal>, which identifies all
+ table constraints along with the table they are defined on.) For a
+ foreign key constraint, this view identifies the table that the
+ foreign key references. For a unique or primary key constraint,
+ this view simply identifies the table the constraint belongs to.
+ Check constraints and not-null constraints are not included in this
+ view.
+ </para>
+
+ <table>
+ <title><structname>constraint_table_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that is used by
+ some constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that is used by some
+ constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that is used by some constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-data-type-privileges">
+ <title><literal>data_type_privileges</literal></title>
+
+ <para>
+ The view <literal>data_type_privileges</literal> identifies all
+ data type descriptors that the current user has access to, by way
+ of being the owner of the described object or having some privilege
+ for it. A data type descriptor is generated whenever a data type
+ is used in the definition of a table column, a domain, or a
+ function (as parameter or return type) and stores some information
+ about how the data type is used in that instance (for example, the
+ declared maximum length, if applicable). Each data type
+ descriptor is assigned an arbitrary identifier that is unique
+ among the data type descriptor identifiers assigned for one object
+ (table, domain, function). This view is probably not useful for
+ applications, but it is used to define some other views in the
+ information schema.
+ </para>
+
+ <table>
+ <title><structname>data_type_privileges</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the described object (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the described object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the described object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The type of the described object: one of
+ <literal>TABLE</literal> (the data type descriptor pertains to
+ a column of that table), <literal>DOMAIN</literal> (the data
+ type descriptors pertains to that domain),
+ <literal>ROUTINE</literal> (the data type descriptor pertains
+ to a parameter or the return data type of that function).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The identifier of the data type descriptor, which is unique
+ among the data type descriptors for that same object.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-domain-constraints">
+ <title><literal>domain_constraints</literal></title>
+
+ <para>
+ The view <literal>domain_constraints</literal> contains all constraints
+ belonging to domains defined in the current database. Only those domains
+ are shown that the current user has access to (by way of being the owner or
+ having some privilege).
+ </para>
+
+ <table>
+ <title><structname>domain_constraints</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the domain (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_deferrable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the constraint is deferrable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>initially_deferred</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the constraint is deferrable and initially deferred, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-domain-udt-usage">
+ <title><literal>domain_udt_usage</literal></title>
+
+ <para>
+ The view <literal>domain_udt_usage</literal> identifies all domains
+ that are based on data types owned by a currently enabled role.
+ Note that in <productname>PostgreSQL</productname>, built-in data
+ types behave like user-defined types, so they are included here as
+ well.
+ </para>
+
+ <table>
+ <title><structname>domain_udt_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the domain data type is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the domain data type is defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the domain data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the domain (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the domain
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-domains">
+ <title><literal>domains</literal></title>
+
+ <para>
+ The view <literal>domains</literal> contains all
+ <glossterm linkend="glossary-domain">domains</glossterm> defined in the
+ current database. Only those domains are shown that the current user has
+ access to (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>domains</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the domain (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Data type of the domain, if it is a built-in type, or
+ <literal>ARRAY</literal> if it is some array (in that case, see
+ the view <literal>element_types</literal>), else
+ <literal>USER-DEFINED</literal> (in that case, the type is
+ identified in <literal>udt_name</literal> and associated
+ columns).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If the domain has a character or bit string type, the declared
+ maximum length; null for all other data types or if no maximum
+ length was declared.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If the domain has a character type, the maximum possible length
+ in octets (bytes) of a datum; null for all other data types.
+ The maximum octet length depends on the declared character
+ maximum length (see above) and the server encoding.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the collation of the domain
+ (always the current database), null if default or the data type
+ of the domain is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the collation of the domain, null
+ if default or the data type of the domain is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the collation of the domain, null if default or the
+ data type of the domain is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If the domain has a numeric type, this column contains the
+ (declared or implicit) precision of the type for this domain.
+ The precision indicates the number of significant digits. It
+ can be expressed in decimal (base 10) or binary (base 2) terms,
+ as specified in the column
+ <literal>numeric_precision_radix</literal>. For all other data
+ types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If the domain has a numeric type, this column indicates in
+ which base the values in the columns
+ <literal>numeric_precision</literal> and
+ <literal>numeric_scale</literal> are expressed. The value is
+ either 2 or 10. For all other data types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If the domain has an exact numeric type, this column contains
+ the (declared or implicit) scale of the type for this domain.
+ The scale indicates the number of significant digits to the
+ right of the decimal point. It can be expressed in decimal
+ (base 10) or binary (base 2) terms, as specified in the column
+ <literal>numeric_precision_radix</literal>. For all other data
+ types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies a date, time,
+ timestamp, or interval type, this column contains the (declared
+ or implicit) fractional seconds precision of the type for this
+ domain, that is, the number of decimal digits maintained
+ following the decimal point in the seconds value. For all
+ other data types, this column is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If <literal>data_type</literal> identifies an interval type,
+ this column contains the specification which fields the
+ intervals include for this domain, e.g., <literal>YEAR TO
+ MONTH</literal>, <literal>DAY TO SECOND</literal>, etc. If no
+ field restrictions were specified (that is, the interval
+ accepts all fields), and for all other data types, this field
+ is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available
+ in <productname>PostgreSQL</productname>
+ (see <literal>datetime_precision</literal> for the fractional
+ seconds precision of interval type domains)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_default</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Default expression of the domain
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the domain data type is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the domain data type is defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the domain data type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ An identifier of the data type descriptor of the domain, unique
+ among the data type descriptors pertaining to the domain (which
+ is trivial, because a domain only contains one data type
+ descriptor). This is mainly useful for joining with other
+ instances of such identifiers. (The specific format of the
+ identifier is not defined and not guaranteed to remain the same
+ in future versions.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-element-types">
+ <title><literal>element_types</literal></title>
+
+ <para>
+ The view <literal>element_types</literal> contains the data type
+ descriptors of the elements of arrays. When a table column, composite-type attribute,
+ domain, function parameter, or function return value is defined to
+ be of an array type, the respective information schema view only
+ contains <literal>ARRAY</literal> in the column
+ <literal>data_type</literal>. To obtain information on the element
+ type of the array, you can join the respective view with this view.
+ For example, to show the columns of a table with data types and
+ array element types, if applicable, you could do:
+<programlisting>
+SELECT c.column_name, c.data_type, e.data_type AS element_type
+FROM information_schema.columns c LEFT JOIN information_schema.element_types e
+ ON ((c.table_catalog, c.table_schema, c.table_name, 'TABLE', c.dtd_identifier)
+ = (e.object_catalog, e.object_schema, e.object_name, e.object_type, e.collection_type_identifier))
+WHERE c.table_schema = '...' AND c.table_name = '...'
+ORDER BY c.ordinal_position;
+</programlisting>
+ This view only includes objects that the current user has access
+ to, by way of being the owner or having some privilege.
+ </para>
+
+ <table>
+ <title><structname>element_types</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the object that uses the
+ array being described (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the object that uses the array
+ being described
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the object that uses the array being described
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The type of the object that uses the array being described: one
+ of <literal>TABLE</literal> (the array is used by a column of
+ that table), <literal>USER-DEFINED TYPE</literal> (the array is
+ used by an attribute of that composite type),
+ <literal>DOMAIN</literal> (the array is used by that domain),
+ <literal>ROUTINE</literal> (the array is used by a parameter or
+ the return data type of that function).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collection_type_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The identifier of the data type descriptor of the array being
+ described. Use this to join with the
+ <literal>dtd_identifier</literal> columns of other information
+ schema views.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Data type of the array elements, if it is a built-in type, else
+ <literal>USER-DEFINED</literal> (in that case, the type is
+ identified in <literal>udt_name</literal> and associated
+ columns).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the collation of the element
+ type (always the current database), null if default or the data
+ type of the element is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the collation of the element
+ type, null if default or the data type of the element is not
+ collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the collation of the element type, null if default or
+ the data type of the element is not collatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to array element data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>domain_default</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Not yet implemented
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the data type of the elements is
+ defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the data type of the elements is
+ defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the data type of the elements
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ An identifier of the data type descriptor of the element. This
+ is currently not useful.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-enabled-roles">
+ <title><literal>enabled_roles</literal></title>
+
+ <para>
+ The view <literal>enabled_roles</literal> identifies the currently
+ <quote>enabled roles</quote>. The enabled roles are recursively
+ defined as the current user together with all roles that have been
+ granted to the enabled roles with automatic inheritance. In other
+ words, these are all roles that the current user has direct or
+ indirect, automatically inheriting membership in.
+ <indexterm><primary>enabled role</primary></indexterm>
+ <indexterm><primary>role</primary><secondary>enabled</secondary></indexterm>
+ </para>
+
+ <para>
+ For permission checking, the set of <quote>applicable roles</quote>
+ is applied, which can be broader than the set of enabled roles. So
+ generally, it is better to use the view
+ <literal>applicable_roles</literal> instead of this one; See
+ <xref linkend="infoschema-applicable-roles"/> for details on
+ <literal>applicable_roles</literal> view.
+ </para>
+
+ <table>
+ <title><structname>enabled_roles</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>role_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of a role
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-foreign-data-wrapper-options">
+ <title><literal>foreign_data_wrapper_options</literal></title>
+
+ <para>
+ The view <literal>foreign_data_wrapper_options</literal> contains
+ all the options defined for foreign-data wrappers in the current
+ database. Only those foreign-data wrappers are shown that the
+ current user has access to (by way of being the owner or having
+ some privilege).
+ </para>
+
+ <table>
+ <title><structname>foreign_data_wrapper_options</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign-data wrapper is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign-data wrapper
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of an option
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Value of the option
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-foreign-data-wrappers">
+ <title><literal>foreign_data_wrappers</literal></title>
+
+ <para>
+ The view <literal>foreign_data_wrappers</literal> contains all
+ foreign-data wrappers defined in the current database. Only those
+ foreign-data wrappers are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>foreign_data_wrappers</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the foreign-data
+ wrapper (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign-data wrapper
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>authorization_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the owner of the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>library_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ File name of the library that implementing this foreign-data wrapper
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_language</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Language used to implement this foreign-data wrapper
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-foreign-server-options">
+ <title><literal>foreign_server_options</literal></title>
+
+ <para>
+ The view <literal>foreign_server_options</literal> contains all the
+ options defined for foreign servers in the current database. Only
+ those foreign servers are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>foreign_server_options</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign server is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of an option
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Value of the option
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-foreign-servers">
+ <title><literal>foreign_servers</literal></title>
+
+ <para>
+ The view <literal>foreign_servers</literal> contains all foreign
+ servers defined in the current database. Only those foreign
+ servers are shown that the current user has access to (by way of
+ being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>foreign_servers</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign server is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the foreign-data
+ wrapper used by the foreign server (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_data_wrapper_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign-data wrapper used by the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Foreign server type information, if specified upon creation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_version</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Foreign server version information, if specified upon creation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>authorization_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the owner of the foreign server
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-foreign-table-options">
+ <title><literal>foreign_table_options</literal></title>
+
+ <para>
+ The view <literal>foreign_table_options</literal> contains all the
+ options defined for foreign tables in the current database. Only
+ those foreign tables are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>foreign_table_options</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the foreign table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of an option
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Value of the option
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-foreign-tables">
+ <title><literal>foreign_tables</literal></title>
+
+ <para>
+ The view <literal>foreign_tables</literal> contains all foreign
+ tables defined in the current database. Only those foreign
+ tables are shown that the current user has access to (by way of
+ being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>foreign_tables</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign table is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign server is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign server
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-key-column-usage">
+ <title><literal>key_column_usage</literal></title>
+
+ <para>
+ The view <literal>key_column_usage</literal> identifies all columns
+ in the current database that are restricted by some unique, primary
+ key, or foreign key constraint. Check constraints are not included
+ in this view. Only those columns are shown that the current user
+ has access to, by way of being the owner or having some privilege.
+ </para>
+
+ <table>
+ <title><structname>key_column_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that contains the
+ column that is restricted by this constraint (always the
+ current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that contains the
+ column that is restricted by this constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that contains the column that is restricted
+ by this constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column that is restricted by this constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordinal_position</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Ordinal position of the column within the constraint key (count
+ starts at 1)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>position_in_unique_constraint</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ For a foreign-key constraint, ordinal position of the referenced
+ column within its unique constraint (count starts at 1);
+ otherwise null
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-parameters">
+ <title><literal>parameters</literal></title>
+
+ <para>
+ The view <literal>parameters</literal> contains information about
+ the parameters (arguments) of all functions in the current database.
+ Only those functions are shown that the current user has access to
+ (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>parameters</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordinal_position</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Ordinal position of the parameter in the argument list of the
+ function (count starts at 1)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parameter_mode</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>IN</literal> for input parameter,
+ <literal>OUT</literal> for output parameter,
+ and <literal>INOUT</literal> for input/output parameter.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_result</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>as_locator</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parameter_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the parameter, or null if the parameter has no name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Data type of the parameter, if it is a built-in type, or
+ <literal>ARRAY</literal> if it is some array (in that case, see
+ the view <literal>element_types</literal>), else
+ <literal>USER-DEFINED</literal> (in that case, the type is
+ identified in <literal>udt_name</literal> and associated
+ columns).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to parameter data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the data type of the parameter is
+ defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the data type of the parameter is
+ defined in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the data type of the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ An identifier of the data type descriptor of the parameter,
+ unique among the data type descriptors pertaining to the
+ function. This is mainly useful for joining with other
+ instances of such identifiers. (The specific format of the
+ identifier is not defined and not guaranteed to remain the same
+ in future versions.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parameter_default</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The default expression of the parameter, or null if none or if the
+ function is not owned by a currently enabled role.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-referential-constraints">
+ <title><literal>referential_constraints</literal></title>
+
+ <para>
+ The view <literal>referential_constraints</literal> contains all
+ referential (foreign key) constraints in the current database.
+ Only those constraints are shown for which the current user has
+ write access to the referencing table (by way of being the
+ owner or having some privilege other than <literal>SELECT</literal>).
+ </para>
+
+ <table>
+ <title><structname>referential_constraints</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>unique_constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the unique or primary key
+ constraint that the foreign key constraint references (always
+ the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>unique_constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the unique or primary key
+ constraint that the foreign key constraint references
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>unique_constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the unique or primary key constraint that the foreign
+ key constraint references
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>match_option</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Match option of the foreign key constraint:
+ <literal>FULL</literal>, <literal>PARTIAL</literal>, or
+ <literal>NONE</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>update_rule</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Update rule of the foreign key constraint:
+ <literal>CASCADE</literal>, <literal>SET NULL</literal>,
+ <literal>SET DEFAULT</literal>, <literal>RESTRICT</literal>, or
+ <literal>NO ACTION</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>delete_rule</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Delete rule of the foreign key constraint:
+ <literal>CASCADE</literal>, <literal>SET NULL</literal>,
+ <literal>SET DEFAULT</literal>, <literal>RESTRICT</literal>, or
+ <literal>NO ACTION</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="infoschema-role-column-grants">
+ <title><literal>role_column_grants</literal></title>
+
+ <para>
+ The view <literal>role_column_grants</literal> identifies all
+ privileges granted on columns where the grantor or grantee is a
+ currently enabled role. Further information can be found under
+ <literal>column_privileges</literal>. The only effective
+ difference between this view
+ and <literal>column_privileges</literal> is that this view omits
+ columns that have been made accessible to the current user by way
+ of a grant to <literal>PUBLIC</literal>.
+ </para>
+
+ <table>
+ <title><structname>role_column_grants</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that contains the column (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that contains the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that contains the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Type of the privilege: <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>, or
+ <literal>REFERENCES</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-role-routine-grants">
+ <title><literal>role_routine_grants</literal></title>
+
+ <para>
+ The view <literal>role_routine_grants</literal> identifies all
+ privileges granted on functions where the grantor or grantee is a
+ currently enabled role. Further information can be found under
+ <literal>routine_privileges</literal>. The only effective
+ difference between this view
+ and <literal>routine_privileges</literal> is that this view omits
+ functions that have been made accessible to the current user by way
+ of a grant to <literal>PUBLIC</literal>.
+ </para>
+
+ <table>
+ <title><structname>role_routine_grants</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the function (might be duplicated in case of overloading)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>EXECUTE</literal> (the only privilege type for functions)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-role-table-grants">
+ <title><literal>role_table_grants</literal></title>
+
+ <para>
+ The view <literal>role_table_grants</literal> identifies all
+ privileges granted on tables or views where the grantor or grantee
+ is a currently enabled role. Further information can be found
+ under <literal>table_privileges</literal>. The only effective
+ difference between this view
+ and <literal>table_privileges</literal> is that this view omits
+ tables that have been made accessible to the current user by way of
+ a grant to <literal>PUBLIC</literal>.
+ </para>
+
+ <table>
+ <title><structname>role_table_grants</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Type of the privilege: <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, <literal>TRUNCATE</literal>,
+ <literal>REFERENCES</literal>, or <literal>TRIGGER</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>with_hierarchy</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ In the SQL standard, <literal>WITH HIERARCHY OPTION</literal>
+ is a separate (sub-)privilege allowing certain operations on
+ table inheritance hierarchies. In PostgreSQL, this is included
+ in the <literal>SELECT</literal> privilege, so this column
+ shows <literal>YES</literal> if the privilege
+ is <literal>SELECT</literal>, else <literal>NO</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-role-udt-grants">
+ <title><literal>role_udt_grants</literal></title>
+
+ <para>
+ The view <literal>role_udt_grants</literal> is intended to identify
+ <literal>USAGE</literal> privileges granted on user-defined types
+ where the grantor or grantee is a currently enabled role. Further
+ information can be found under
+ <literal>udt_privileges</literal>. The only effective difference
+ between this view and <literal>udt_privileges</literal> is that
+ this view omits objects that have been made accessible to the
+ current user by way of a grant to <literal>PUBLIC</literal>. Since
+ data types do not have real privileges in PostgreSQL, but only an
+ implicit grant to <literal>PUBLIC</literal>, this view is empty.
+ </para>
+
+ <table>
+ <title><structname>role_udt_grants</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the type (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>TYPE USAGE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-role-usage-grants">
+ <title><literal>role_usage_grants</literal></title>
+
+ <para>
+ The view <literal>role_usage_grants</literal> identifies
+ <literal>USAGE</literal> privileges granted on various kinds of
+ objects where the grantor or grantee is a currently enabled role.
+ Further information can be found under
+ <literal>usage_privileges</literal>. The only effective difference
+ between this view and <literal>usage_privileges</literal> is that
+ this view omits objects that have been made accessible to the
+ current user by way of a grant to <literal>PUBLIC</literal>.
+ </para>
+
+ <table>
+ <title><structname>role_usage_grants</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the object (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the object, if applicable,
+ else an empty string
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>COLLATION</literal> or <literal>DOMAIN</literal> or <literal>FOREIGN DATA WRAPPER</literal> or <literal>FOREIGN SERVER</literal> or <literal>SEQUENCE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>USAGE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-routine-column-usage">
+ <title><literal>routine_column_usage</literal></title>
+
+ <para>
+ The view <literal>routine_column_usage</literal> is meant to identify all
+ columns that are used by a function or procedure. This information is
+ currently not tracked by <productname>PostgreSQL</productname>.
+ </para>
+
+ <table>
+ <title><literal>routine_column_usage</literal> Columns</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the function (might be duplicated in case of overloading)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that is used by the
+ function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that is used by the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that is used by the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column that is used by the function
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-routine-privileges">
+ <title><literal>routine_privileges</literal></title>
+
+ <para>
+ The view <literal>routine_privileges</literal> identifies all
+ privileges granted on functions to a currently enabled role or by a
+ currently enabled role. There is one row for each combination of function,
+ grantor, and grantee.
+ </para>
+
+ <table>
+ <title><structname>routine_privileges</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the function (might be duplicated in case of overloading)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>EXECUTE</literal> (the only privilege type for functions)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-routine-routine-usage">
+ <title><literal>routine_routine_usage</literal></title>
+
+ <para>
+ The view <literal>routine_routine_usage</literal> is meant to identify all
+ functions or procedures that are used by another (or the same) function or
+ procedure, either in the body or in parameter default expressions.
+ Currently, only functions used in parameter default expressions are
+ tracked. An entry is included here only if the used function is owned by a
+ currently enabled role. (There is no such restriction on the using
+ function.)
+ </para>
+
+ <para>
+ Note that the entries for both functions in the view refer to the
+ <quote>specific</quote> name of the routine, even though the column names
+ are used in a way that is inconsistent with other information schema views
+ about routines. This is per SQL standard, although it is arguably a
+ misdesign. See <xref linkend="infoschema-routines"/> for more information
+ about specific names.
+ </para>
+
+ <table>
+ <title><literal>routine_routine_usage</literal> Columns</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the using function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the using function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the using function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the function that is used by the
+ first function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the function that is used by the first
+ function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function that is used by the
+ first function.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-routine-sequence-usage">
+ <title><literal>routine_sequence_usage</literal></title>
+
+ <para>
+ The view <literal>routine_sequence_usage</literal> is meant to identify all
+ sequences that are used by a function or procedure, either in the body or
+ in parameter default expressions. Currently, only sequences used in
+ parameter default expressions are tracked. A sequence is only included if
+ that sequence is owned by a currently enabled role.
+ </para>
+
+ <table>
+ <title><literal>routine_sequence_usage</literal> Columns</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the function (might be duplicated in case of overloading)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schema_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the sequence that is used by the
+ function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequence_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the sequence that is used by the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequence_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the sequence that is used by the function
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-routine-table-usage">
+ <title><literal>routine_table_usage</literal></title>
+
+ <para>
+ The view <literal>routine_table_usage</literal> is meant to identify all
+ tables that are used by a function or procedure. This information is
+ currently not tracked by <productname>PostgreSQL</productname>.
+ </para>
+
+ <table>
+ <title><literal>routine_table_usage</literal> Columns</title>
+
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the function (might be duplicated in case of overloading)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that is used by the
+ function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that is used by the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that is used by the function
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-routines">
+ <title><literal>routines</literal></title>
+
+ <para>
+ The view <literal>routines</literal> contains all functions and procedures in the
+ current database. Only those functions and procedures are shown that the current
+ user has access to (by way of being the owner or having some
+ privilege).
+ </para>
+
+ <table>
+ <title><structname>routines</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. This is a
+ name that uniquely identifies the function in the schema, even
+ if the real name of the function is overloaded. The format of
+ the specific name is not defined, it should only be used to
+ compare it to other instances of specific routine names.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the function (might be duplicated in case of overloading)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>FUNCTION</literal> for a
+ function, <literal>PROCEDURE</literal> for a procedure
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>module_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>module_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>module_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Return data type of the function, if it is a built-in type, or
+ <literal>ARRAY</literal> if it is some array (in that case, see
+ the view <literal>element_types</literal>), else
+ <literal>USER-DEFINED</literal> (in that case, the type is
+ identified in <literal>type_udt_name</literal> and associated
+ columns). Null for a procedure.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, since this information is not applied to return data types in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>type_udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the return data type of the function
+ is defined in (always the current database). Null for a procedure.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>type_udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that the return data type of the function is
+ defined in. Null for a procedure.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>type_udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the return data type of the function. Null for a procedure.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Always null, because arrays always have unlimited maximum cardinality in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ An identifier of the data type descriptor of the return data
+ type of this function, unique among the data type descriptors
+ pertaining to the function. This is mainly useful for joining
+ with other instances of such identifiers. (The specific format
+ of the identifier is not defined and not guaranteed to remain
+ the same in future versions.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_body</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the function is an SQL function, then
+ <literal>SQL</literal>, else <literal>EXTERNAL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>routine_definition</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The source text of the function (null if the function is not
+ owned by a currently enabled role). (According to the SQL
+ standard, this column is only applicable if
+ <literal>routine_body</literal> is <literal>SQL</literal>, but
+ in <productname>PostgreSQL</productname> it will contain
+ whatever source text was specified when the function was
+ created.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>external_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If this function is a C function, then the external name (link
+ symbol) of the function; else null. (This works out to be the
+ same value that is shown in
+ <literal>routine_definition</literal>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>external_language</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The language the function is written in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parameter_style</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>GENERAL</literal> (The SQL standard defines
+ other parameter styles, which are not available in <productname>PostgreSQL</productname>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_deterministic</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ If the function is declared immutable (called deterministic in
+ the SQL standard), then <literal>YES</literal>, else
+ <literal>NO</literal>. (You cannot query the other volatility
+ levels available in <productname>PostgreSQL</productname> through the information schema.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sql_data_access</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>MODIFIES</literal>, meaning that the function
+ possibly modifies SQL data. This information is not useful for
+ <productname>PostgreSQL</productname>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_null_call</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ If the function automatically returns null if any of its
+ arguments are null, then <literal>YES</literal>, else
+ <literal>NO</literal>. Null for a procedure.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sql_path</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schema_level_routine</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Always <literal>YES</literal> (The opposite would be a method
+ of a user-defined type, which is a feature not available in
+ <productname>PostgreSQL</productname>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>max_dynamic_result_sets</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_user_defined_cast</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_implicitly_invocable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>security_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ If the function runs with the privileges of the current user,
+ then <literal>INVOKER</literal>, if the function runs with the
+ privileges of the user who defined it, then
+ <literal>DEFINER</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>to_sql_specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>to_sql_specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>to_sql_specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>as_locator</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>created</structfield> <type>time_stamp</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_altered</structfield> <type>time_stamp</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>new_savepoint_level</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_udt_dependent</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Currently always <literal>NO</literal>. The alternative
+ <literal>YES</literal> applies to a feature not available in
+ <productname>PostgreSQL</productname>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_from_data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_as_locator</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_char_max_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_char_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_char_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_char_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_char_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_type_udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_type_udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_type_udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_scope_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_scope_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_scope_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_maximum_cardinality</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>result_cast_dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-schemata">
+ <title><literal>schemata</literal></title>
+
+ <para>
+ The view <literal>schemata</literal> contains all schemas in the current
+ database that the current user has access to (by way of being the owner or
+ having some privilege).
+ </para>
+
+ <table>
+ <title><structname>schemata</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>catalog_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the schema is contained in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schema_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schema_owner</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the owner of the schema
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sql_path</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-sequences">
+ <title><literal>sequences</literal></title>
+
+ <para>
+ The view <literal>sequences</literal> contains all sequences
+ defined in the current database. Only those sequences are shown
+ that the current user has access to (by way of being the owner or
+ having some privilege).
+ </para>
+
+ <table>
+ <title><structname>sequences</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequence_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the sequence (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequence_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequence_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The data type of the sequence.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ This column contains the (declared or implicit) precision of
+ the sequence data type (see above). The precision indicates
+ the number of significant digits. It can be expressed in
+ decimal (base 10) or binary (base 2) terms, as specified in the
+ column <literal>numeric_precision_radix</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ This column indicates in which base the values in the columns
+ <literal>numeric_precision</literal> and
+ <literal>numeric_scale</literal> are expressed. The value is
+ either 2 or 10.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ This column contains the (declared or implicit) scale of the
+ sequence data type (see above). The scale indicates the number
+ of significant digits to the right of the decimal point. It
+ can be expressed in decimal (base 10) or binary (base 2) terms,
+ as specified in the column
+ <literal>numeric_precision_radix</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>start_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The start value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>minimum_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The minimum value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maximum_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The maximum value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>increment</structfield> <type>character_data</type>
+ </para>
+ <para>
+ The increment of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cycle_option</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the sequence cycles, else <literal>NO</literal>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Note that in accordance with the SQL standard, the start, minimum,
+ maximum, and increment values are returned as character strings.
+ </para>
+ </sect1>
+
+ <sect1 id="infoschema-sql-features">
+ <title><literal>sql_features</literal></title>
+
+ <para>
+ The table <literal>sql_features</literal> contains information
+ about which formal features defined in the SQL standard are
+ supported by <productname>PostgreSQL</productname>. This is the
+ same information that is presented in <xref linkend="features"/>.
+ There you can also find some additional background information.
+ </para>
+
+ <table>
+ <title><structname>sql_features</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>feature_id</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Identifier string of the feature
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>feature_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Descriptive name of the feature
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sub_feature_id</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Identifier string of the subfeature, or a zero-length string if not a subfeature
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sub_feature_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Descriptive name of the subfeature, or a zero-length string if not a subfeature
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_supported</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the feature is fully supported by the
+ current version of <productname>PostgreSQL</productname>, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_verified_by</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always null, since the <productname>PostgreSQL</productname> development group does not
+ perform formal testing of feature conformance
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>comments</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Possibly a comment about the supported status of the feature
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-sql-implementation-info">
+ <title><literal>sql_implementation_info</literal></title>
+
+ <para>
+ The table <literal>sql_implementation_info</literal> contains
+ information about various aspects that are left
+ implementation-defined by the SQL standard. This information is
+ primarily intended for use in the context of the ODBC interface;
+ users of other interfaces will probably find this information to be
+ of little use. For this reason, the individual implementation
+ information items are not described here; you will find them in the
+ description of the ODBC interface.
+ </para>
+
+ <table>
+ <title><structname>sql_implementation_info</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>implementation_info_id</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Identifier string of the implementation information item
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>implementation_info_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Descriptive name of the implementation information item
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>integer_value</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Value of the implementation information item, or null if the
+ value is contained in the column
+ <literal>character_value</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Value of the implementation information item, or null if the
+ value is contained in the column
+ <literal>integer_value</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>comments</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Possibly a comment pertaining to the implementation information item
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-sql-parts">
+ <title><literal>sql_parts</literal></title>
+
+ <para>
+ The table <literal>sql_parts</literal> contains information about
+ which of the several parts of the SQL standard are supported by
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <table>
+ <title><structname>sql_parts</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>feature_id</structfield> <type>character_data</type>
+ </para>
+ <para>
+ An identifier string containing the number of the part
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>feature_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Descriptive name of the part
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_supported</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the part is fully supported by the
+ current version of <productname>PostgreSQL</productname>,
+ <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_verified_by</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always null, since the <productname>PostgreSQL</productname> development group does not
+ perform formal testing of feature conformance
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>comments</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Possibly a comment about the supported status of the part
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-sql-sizing">
+ <title><literal>sql_sizing</literal></title>
+
+ <para>
+ The table <literal>sql_sizing</literal> contains information about
+ various size limits and maximum values in
+ <productname>PostgreSQL</productname>. This information is
+ primarily intended for use in the context of the ODBC interface;
+ users of other interfaces will probably find this information to be
+ of little use. For this reason, the individual sizing items are
+ not described here; you will find them in the description of the
+ ODBC interface.
+ </para>
+
+ <table>
+ <title><structname>sql_sizing</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sizing_id</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Identifier of the sizing item
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sizing_name</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Descriptive name of the sizing item
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>supported_value</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Value of the sizing item, or 0 if the size is unlimited or
+ cannot be determined, or null if the features for which the
+ sizing item is applicable are not supported
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>comments</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Possibly a comment pertaining to the sizing item
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-table-constraints">
+ <title><literal>table_constraints</literal></title>
+
+ <para>
+ The view <literal>table_constraints</literal> contains all
+ constraints belonging to tables that the current user owns or has
+ some privilege other than <literal>SELECT</literal> on.
+ </para>
+
+ <table>
+ <title><structname>table_constraints</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the constraint (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the constraint
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>constraint_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Type of the constraint: <literal>CHECK</literal>,
+ <literal>FOREIGN KEY</literal>, <literal>PRIMARY KEY</literal>,
+ or <literal>UNIQUE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_deferrable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the constraint is deferrable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>initially_deferred</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the constraint is deferrable and initially deferred, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>enforced</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in
+ <productname>PostgreSQL</productname> (currently always
+ <literal>YES</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>nulls_distinct</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ If the constraint is a unique constraint, then <literal>YES</literal>
+ if the constraint treats nulls as distinct or <literal>NO</literal> if
+ it treats nulls as not distinct, otherwise null for other types of
+ constraints.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-table-privileges">
+ <title><literal>table_privileges</literal></title>
+
+ <para>
+ The view <literal>table_privileges</literal> identifies all
+ privileges granted on tables or views to a currently enabled role
+ or by a currently enabled role. There is one row for each
+ combination of table, grantor, and grantee.
+ </para>
+
+ <table>
+ <title><structname>table_privileges</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Type of the privilege: <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, <literal>TRUNCATE</literal>,
+ <literal>REFERENCES</literal>, or <literal>TRIGGER</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>with_hierarchy</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ In the SQL standard, <literal>WITH HIERARCHY OPTION</literal>
+ is a separate (sub-)privilege allowing certain operations on
+ table inheritance hierarchies. In PostgreSQL, this is included
+ in the <literal>SELECT</literal> privilege, so this column
+ shows <literal>YES</literal> if the privilege
+ is <literal>SELECT</literal>, else <literal>NO</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-tables">
+ <title><literal>tables</literal></title>
+
+ <para>
+ The view <literal>tables</literal> contains all tables and views
+ defined in the current database. Only those tables and views are
+ shown that the current user has access to (by way of being the
+ owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>tables</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Type of the table: <literal>BASE TABLE</literal> for a
+ persistent base table (the normal table type),
+ <literal>VIEW</literal> for a view, <literal>FOREIGN</literal>
+ for a foreign table, or
+ <literal>LOCAL TEMPORARY</literal> for a temporary table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>self_referencing_column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reference_generation</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ If the table is a typed table, the name of the database that
+ contains the underlying data type (always the current
+ database), else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ If the table is a typed table, the name of the schema that
+ contains the underlying data type, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ If the table is a typed table, the name of the underlying data
+ type, else null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_insertable_into</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the table is insertable into,
+ <literal>NO</literal> if not (Base tables are always insertable
+ into, views not necessarily.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_typed</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the table is a typed table, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>commit_action</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Not yet implemented
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-transforms">
+ <title><literal>transforms</literal></title>
+
+ <para>
+ The view <literal>transforms</literal> contains information about the
+ transforms defined in the current database. More precisely, it contains a
+ row for each function contained in a transform (the <quote>from SQL</quote>
+ or <quote>to SQL</quote> function).
+ </para>
+
+ <table>
+ <title><structname>transforms</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the type the transform is for (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the type the transform is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the type the transform is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>group_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The SQL standard allows defining transforms in <quote>groups</quote>,
+ and selecting a group at run time. PostgreSQL does not support this.
+ Instead, transforms are specific to a language. As a compromise, this
+ field contains the language the transform is for.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>transform_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>FROM SQL</literal> or <literal>TO SQL</literal>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-triggered-update-columns">
+ <title><literal>triggered_update_columns</literal></title>
+
+ <para>
+ For triggers in the current database that specify a column list
+ (like <literal>UPDATE OF column1, column2</literal>), the
+ view <literal>triggered_update_columns</literal> identifies these
+ columns. Triggers that do not specify a column list are not
+ included in this view. Only those columns are shown that the
+ current user owns or has some privilege other than
+ <literal>SELECT</literal> on.
+ </para>
+
+ <table>
+ <title><structname>triggered_update_columns</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trigger_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the trigger (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trigger_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the trigger
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trigger_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the trigger
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that the trigger
+ is defined on (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that the trigger is defined on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_table</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that the trigger is defined on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_column</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column that the trigger is defined on
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-triggers">
+ <title><literal>triggers</literal></title>
+
+ <para>
+ The view <literal>triggers</literal> contains all triggers defined
+ in the current database on tables and views that the current user owns
+ or has some privilege other than <literal>SELECT</literal> on.
+ </para>
+
+ <table>
+ <title><structname>triggers</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trigger_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the trigger (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trigger_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the trigger
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trigger_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the trigger
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_manipulation</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Event that fires the trigger (<literal>INSERT</literal>,
+ <literal>UPDATE</literal>, or <literal>DELETE</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that the trigger
+ is defined on (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that the trigger is defined on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>event_object_table</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that the trigger is defined on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_order</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Firing order among triggers on the same table having the same
+ <literal>event_manipulation</literal>,
+ <literal>action_timing</literal>, and
+ <literal>action_orientation</literal>. In
+ <productname>PostgreSQL</productname>, triggers are fired in name
+ order, so this column reflects that.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_condition</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>WHEN</literal> condition of the trigger, null if none
+ (also null if the table is not owned by a currently enabled
+ role)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_statement</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Statement that is executed by the trigger (currently always
+ <literal>EXECUTE FUNCTION
+ <replaceable>function</replaceable>(...)</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_orientation</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Identifies whether the trigger fires once for each processed
+ row or once for each statement (<literal>ROW</literal> or
+ <literal>STATEMENT</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_timing</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Time at which the trigger fires (<literal>BEFORE</literal>,
+ <literal>AFTER</literal>, or <literal>INSTEAD OF</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_reference_old_table</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the <quote>old</quote> transition table, or null if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_reference_new_table</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the <quote>new</quote> transition table, or null if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_reference_old_row</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>action_reference_new_row</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>created</structfield> <type>time_stamp</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Triggers in <productname>PostgreSQL</productname> have two
+ incompatibilities with the SQL standard that affect the
+ representation in the information schema. First, trigger names are
+ local to each table in <productname>PostgreSQL</productname>, rather
+ than being independent schema objects. Therefore there can be duplicate
+ trigger names defined in one schema, so long as they belong to
+ different tables. (<literal>trigger_catalog</literal> and
+ <literal>trigger_schema</literal> are really the values pertaining
+ to the table that the trigger is defined on.) Second, triggers can
+ be defined to fire on multiple events in
+ <productname>PostgreSQL</productname> (e.g., <literal>ON INSERT OR
+ UPDATE</literal>), whereas the SQL standard only allows one. If a
+ trigger is defined to fire on multiple events, it is represented as
+ multiple rows in the information schema, one for each type of
+ event. As a consequence of these two issues, the primary key of
+ the view <literal>triggers</literal> is really
+ <literal>(trigger_catalog, trigger_schema, event_object_table,
+ trigger_name, event_manipulation)</literal> instead of
+ <literal>(trigger_catalog, trigger_schema, trigger_name)</literal>,
+ which is what the SQL standard specifies. Nonetheless, if you
+ define your triggers in a manner that conforms with the SQL
+ standard (trigger names unique in the schema and only one event
+ type per trigger), this will not affect you.
+ </para>
+
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 9.1, this view's columns
+ <structfield>action_timing</structfield>,
+ <structfield>action_reference_old_table</structfield>,
+ <structfield>action_reference_new_table</structfield>,
+ <structfield>action_reference_old_row</structfield>, and
+ <structfield>action_reference_new_row</structfield>
+ were named
+ <structfield>condition_timing</structfield>,
+ <structfield>condition_reference_old_table</structfield>,
+ <structfield>condition_reference_new_table</structfield>,
+ <structfield>condition_reference_old_row</structfield>, and
+ <structfield>condition_reference_new_row</structfield>
+ respectively.
+ That was how they were named in the SQL:1999 standard.
+ The new naming conforms to SQL:2003 and later.
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="infoschema-udt-privileges">
+ <title><literal>udt_privileges</literal></title>
+
+ <para>
+ The view <literal>udt_privileges</literal> identifies
+ <literal>USAGE</literal> privileges granted on user-defined types to a
+ currently enabled role or by a currently enabled role. There is one row for
+ each combination of type, grantor, and grantee. This view shows only
+ composite types (see under <xref linkend="infoschema-user-defined-types"/>
+ for why); see
+ <xref linkend="infoschema-usage-privileges"/> for domain privileges.
+ </para>
+
+ <table>
+ <title><structname>udt_privileges</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the type (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>udt_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>TYPE USAGE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-usage-privileges">
+ <title><literal>usage_privileges</literal></title>
+
+ <para>
+ The view <literal>usage_privileges</literal> identifies
+ <literal>USAGE</literal> privileges granted on various kinds of
+ objects to a currently enabled role or by a currently enabled role.
+ In <productname>PostgreSQL</productname>, this currently applies to
+ collations, domains, foreign-data wrappers, foreign servers, and sequences. There is one
+ row for each combination of object, grantor, and grantee.
+ </para>
+
+ <para>
+ Since collations do not have real privileges
+ in <productname>PostgreSQL</productname>, this view shows implicit
+ non-grantable <literal>USAGE</literal> privileges granted by the
+ owner to <literal>PUBLIC</literal> for all collations. The other
+ object types, however, show real privileges.
+ </para>
+
+ <para>
+ In PostgreSQL, sequences also support <literal>SELECT</literal>
+ and <literal>UPDATE</literal> privileges in addition to
+ the <literal>USAGE</literal> privilege. These are nonstandard and therefore
+ not visible in the information schema.
+ </para>
+
+ <table>
+ <title><structname>usage_privileges</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantor</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that granted the privilege
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grantee</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the role that the privilege was granted to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the object (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the object, if applicable,
+ else an empty string
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>object_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>COLLATION</literal> or <literal>DOMAIN</literal> or <literal>FOREIGN DATA WRAPPER</literal> or <literal>FOREIGN SERVER</literal> or <literal>SEQUENCE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>privilege_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Always <literal>USAGE</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_grantable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the privilege is grantable, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-user-defined-types">
+ <title><literal>user_defined_types</literal></title>
+
+ <para>
+ The view <literal>user_defined_types</literal> currently contains
+ all composite types defined in the current database.
+ Only those types are shown that the current user has access to (by way
+ of being the owner or having some privilege).
+ </para>
+
+ <para>
+ SQL knows about two kinds of user-defined types: structured types
+ (also known as composite types
+ in <productname>PostgreSQL</productname>) and distinct types (not
+ implemented in <productname>PostgreSQL</productname>). To be
+ future-proof, use the
+ column <literal>user_defined_type_category</literal> to
+ differentiate between these. Other user-defined types such as base
+ types and enums, which are <productname>PostgreSQL</productname>
+ extensions, are not shown here. For domains,
+ see <xref linkend="infoschema-domains"/> instead.
+ </para>
+
+ <table>
+ <title><structname>user_defined_types</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the type (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the type
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_defined_type_category</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Currently always <literal>STRUCTURED</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_instantiable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_final</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordering_form</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordering_category</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordering_routine_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordering_routine_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ordering_routine_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reference_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_maximum_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_octet_length</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>character_set_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>collation_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_precision_radix</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numeric_scale</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datetime_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_type</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>interval_precision</structfield> <type>cardinal_number</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>source_dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ref_dtd_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Applies to a feature not available in <productname>PostgreSQL</productname>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-user-mapping-options">
+ <title><literal>user_mapping_options</literal></title>
+
+ <para>
+ The view <literal>user_mapping_options</literal> contains all the
+ options defined for user mappings in the current database. Only
+ those user mappings are shown where the current user has access to
+ the corresponding foreign server (by way of being the owner or
+ having some privilege).
+ </para>
+
+ <table>
+ <title><structname>user_mapping_options</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>authorization_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the user being mapped,
+ or <literal>PUBLIC</literal> if the mapping is public
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign server used by this
+ mapping is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign server used by this mapping
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of an option
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>option_value</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Value of the option. This column will show as null
+ unless the current user is the user being mapped, or the mapping
+ is for <literal>PUBLIC</literal> and the current user is the
+ server owner, or the current user is a superuser. The intent is
+ to protect password information stored as user mapping
+ option.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-user-mappings">
+ <title><literal>user_mappings</literal></title>
+
+ <para>
+ The view <literal>user_mappings</literal> contains all user
+ mappings defined in the current database. Only those user mappings
+ are shown where the current user has access to the corresponding
+ foreign server (by way of being the owner or having some
+ privilege).
+ </para>
+
+ <table>
+ <title><structname>user_mappings</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>authorization_identifier</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the user being mapped,
+ or <literal>PUBLIC</literal> if the mapping is public
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that the foreign server used by this
+ mapping is defined in (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>foreign_server_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the foreign server used by this mapping
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-view-column-usage">
+ <title><literal>view_column_usage</literal></title>
+
+ <para>
+ The view <literal>view_column_usage</literal> identifies all
+ columns that are used in the query expression of a view (the
+ <command>SELECT</command> statement that defines the view). A
+ column is only included if the table that contains the column is
+ owned by a currently enabled role.
+ </para>
+
+ <note>
+ <para>
+ Columns of system tables are not included. This should be fixed
+ sometime.
+ </para>
+ </note>
+
+ <table>
+ <title><structname>view_column_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the view (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that contains the
+ column that is used by the view (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that contains the
+ column that is used by the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that contains the column that is used by the
+ view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>column_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the column that is used by the view
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-view-routine-usage">
+ <title><literal>view_routine_usage</literal></title>
+
+ <para>
+ The view <literal>view_routine_usage</literal> identifies all
+ routines (functions and procedures) that are used in the query
+ expression of a view (the <command>SELECT</command> statement that
+ defines the view). A routine is only included if that routine is
+ owned by a currently enabled role.
+ </para>
+
+ <table>
+ <title><structname>view_routine_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the view (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database containing the function (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema containing the function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>specific_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ The <quote>specific name</quote> of the function. See <xref linkend="infoschema-routines"/> for more information.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-view-table-usage">
+ <title><literal>view_table_usage</literal></title>
+
+ <para>
+ The view <literal>view_table_usage</literal> identifies all tables
+ that are used in the query expression of a view (the
+ <command>SELECT</command> statement that defines the view). A
+ table is only included if that table is owned by a currently
+ enabled role.
+ </para>
+
+ <note>
+ <para>
+ System tables are not included. This should be fixed sometime.
+ </para>
+ </note>
+
+ <table>
+ <title><structname>view_table_usage</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the view (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the table that is
+ used by the view (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the table that is used by the
+ view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the table that is used by the view
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="infoschema-views">
+ <title><literal>views</literal></title>
+
+ <para>
+ The view <literal>views</literal> contains all views defined in the
+ current database. Only those views are shown that the current user
+ has access to (by way of being the owner or having some privilege).
+ </para>
+
+ <table>
+ <title><structname>views</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_catalog</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the database that contains the view (always the current database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_schema</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the schema that contains the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>table_name</structfield> <type>sql_identifier</type>
+ </para>
+ <para>
+ Name of the view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>view_definition</structfield> <type>character_data</type>
+ </para>
+ <para>
+ Query expression defining the view (null if the view is not
+ owned by a currently enabled role)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>check_option</structfield> <type>character_data</type>
+ </para>
+ <para>
+ <literal>CASCADED</literal> or <literal>LOCAL</literal> if the view
+ has a <literal>CHECK OPTION</literal> defined on it,
+ <literal>NONE</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_updatable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the view is updatable (allows
+ <command>UPDATE</command> and <command>DELETE</command>),
+ <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_insertable_into</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the view is insertable into (allows
+ <command>INSERT</command>), <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_trigger_updatable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the view has an <literal>INSTEAD OF</literal>
+ <command>UPDATE</command> trigger defined on it, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_trigger_deletable</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the view has an <literal>INSTEAD OF</literal>
+ <command>DELETE</command> trigger defined on it, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_trigger_insertable_into</structfield> <type>yes_or_no</type>
+ </para>
+ <para>
+ <literal>YES</literal> if the view has an <literal>INSTEAD OF</literal>
+ <command>INSERT</command> trigger defined on it, <literal>NO</literal> if not
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/install-binaries.sgml b/doc/src/sgml/install-binaries.sgml
new file mode 100644
index 0000000..001c3c7
--- /dev/null
+++ b/doc/src/sgml/install-binaries.sgml
@@ -0,0 +1,24 @@
+<!-- doc/src/sgml/install-binaries.sgml -->
+<chapter id="install-binaries">
+ <title>Installation from Binaries</title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>binaries</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> is available in the form of binary
+ packages for most common operating systems today. When available, this is
+ the recommended way to install PostgreSQL for users of the system. Building
+ from source (see <xref linkend="installation" />) is only recommended for
+ people developing <productname>PostgreSQL</productname> or extensions.
+ </para>
+
+ <para>
+ For an updated list of platforms providing binary packages, please visit
+ the download section on the <productname>PostgreSQL</productname> website at
+ <ulink url="https://www.postgresql.org/download/"></ulink> and follow the
+ instructions for the specific platform.
+ </para>
+</chapter>
diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml
new file mode 100644
index 0000000..0d7decc
--- /dev/null
+++ b/doc/src/sgml/install-windows.sgml
@@ -0,0 +1,573 @@
+<!-- doc/src/sgml/install-windows.sgml -->
+
+<chapter id="install-windows">
+ <title>Installation from Source Code on <productname>Windows</productname></title>
+
+ <indexterm>
+ <primary>installation</primary>
+ <secondary>on Windows</secondary>
+ </indexterm>
+
+ <para>
+ It is recommended that most users download the binary distribution for
+ Windows, available as a graphical installer package
+ from the <productname>PostgreSQL</productname> website at
+ <ulink url="https://www.postgresql.org/download/"></ulink>. Building from source
+ is only intended for people developing <productname>PostgreSQL</productname>
+ or extensions.
+ </para>
+
+ <para>
+ There are several different ways of building PostgreSQL on
+ <productname>Windows</productname>. The simplest way to build with
+ Microsoft tools is to install <productname>Visual Studio 2022</productname>
+ and use the included compiler. It is also possible to build with the full
+ <productname>Microsoft Visual C++ 2013 to 2022</productname>.
+ In some cases that requires the installation of the
+ <productname>Windows SDK</productname> in addition to the compiler.
+ </para>
+
+ <para>
+ It is also possible to build PostgreSQL using the GNU compiler tools
+ provided by <productname>MinGW</productname>, or using
+ <productname>Cygwin</productname> for older versions of
+ <productname>Windows</productname>.
+ </para>
+
+ <para>
+ Building using <productname>MinGW</productname> or
+ <productname>Cygwin</productname> uses the normal build system, see
+ <xref linkend="installation"/> and the specific notes in
+ <xref linkend="installation-notes-mingw"/> and <xref linkend="installation-notes-cygwin"/>.
+ To produce native 64 bit binaries in these environments, use the tools from
+ <productname>MinGW-w64</productname>. These tools can also be used to
+ cross-compile for 32 bit and 64 bit <productname>Windows</productname>
+ targets on other hosts, such as <productname>Linux</productname> and
+ <productname>macOS</productname>.
+ <productname>Cygwin</productname> is not recommended for running a
+ production server, and it should only be used for running on
+ older versions of <productname>Windows</productname> where
+ the native build does not work. The official
+ binaries are built using <productname>Visual Studio</productname>.
+ </para>
+
+ <para>
+ Native builds of <application>psql</application> don't support command
+ line editing. The <productname>Cygwin</productname> build does support
+ command line editing, so it should be used where psql is needed for
+ interactive use on <productname>Windows</productname>.
+ </para>
+
+ <sect1 id="install-windows-full">
+ <title>Building with <productname>Visual C++</productname> or the
+ <productname>Microsoft Windows SDK</productname></title>
+
+ <para>
+ PostgreSQL can be built using the Visual C++ compiler suite from Microsoft.
+ These compilers can be either from <productname>Visual Studio</productname>,
+ <productname>Visual Studio Express</productname> or some versions of the
+ <productname>Microsoft Windows SDK</productname>. If you do not already have a
+ <productname>Visual Studio</productname> environment set up, the easiest
+ ways are to use the compilers from
+ <productname>Visual Studio 2022</productname> or those in the
+ <productname>Windows SDK 10</productname>, which are both free downloads
+ from Microsoft.
+ </para>
+
+ <para>
+ Both 32-bit and 64-bit builds are possible with the Microsoft Compiler suite.
+ 32-bit PostgreSQL builds are possible with
+ <productname>Visual Studio 2013</productname> to
+ <productname>Visual Studio 2022</productname>,
+ as well as standalone Windows SDK releases 8.1a to 10.
+ 64-bit PostgreSQL builds are supported with
+ <productname>Microsoft Windows SDK</productname> version 8.1a to 10 or
+ <productname>Visual Studio 2013</productname> and above. Compilation
+ is supported down to <productname>Windows 7</productname> and
+ <productname>Windows Server 2008 R2 SP1</productname> when building with
+ <productname>Visual Studio 2013</productname> to
+ <productname>Visual Studio 2022</productname>.
+ <!--
+ For 2013 requirements:
+ https://docs.microsoft.com/en-us/visualstudio/productinfo/vs2013-sysrequirements-vs
+ For 2015 requirements:
+ https://docs.microsoft.com/en-us/visualstudio/productinfo/vs2015-sysrequirements-vs
+ For 2017 requirements:
+ https://docs.microsoft.com/en-us/visualstudio/productinfo/vs2017-system-requirements-vs
+ For 2019 requirements:
+ https://docs.microsoft.com/en-us/visualstudio/releases/2019/system-requirements
+ For 2022 requirements:
+ https://docs.microsoft.com/en-us/visualstudio/releases/2022/system-requirements
+ -->
+ </para>
+
+ <para>
+ The tools for building using <productname>Visual C++</productname> or
+ <productname>Platform SDK</productname> are in the
+ <filename>src\tools\msvc</filename> directory. When building, make sure
+ there are no tools from <productname>MinGW</productname> or
+ <productname>Cygwin</productname> present in your system PATH. Also, make
+ sure you have all the required Visual C++ tools available in the PATH. In
+ <productname>Visual Studio</productname>, start the
+ <application>Visual Studio Command Prompt</application>.
+ If you wish to build a 64-bit version, you must use the 64-bit version of
+ the command, and vice versa.
+ Starting with <productname>Visual Studio 2017</productname> this can be
+ done from the command line using <command>VsDevCmd.bat</command>, see
+ <command>-help</command> for the available options and their default values.
+ <command>vsvars32.bat</command> is available in
+ <productname>Visual Studio 2015</productname> and earlier versions for the
+ same purpose.
+ From the <application>Visual Studio Command Prompt</application>, you can
+ change the targeted CPU architecture, build type, and target OS by using the
+ <command>vcvarsall.bat</command> command, e.g.,
+ <command>vcvarsall.bat x64 10.0.10240.0</command> to target Windows 10
+ with a 64-bit release build. See <command>-help</command> for the other
+ options of <command>vcvarsall.bat</command>. All commands should be run from
+ the <filename>src\tools\msvc</filename> directory.
+ </para>
+
+ <para>
+ Before you build, you can create the file <filename>config.pl</filename>
+ to reflect any configuration options you want to change, or the paths to
+ any third party libraries to use. The complete configuration is determined
+ by first reading and parsing the file <filename>config_default.pl</filename>,
+ and then apply any changes from <filename>config.pl</filename>. For example,
+ to specify the location of your <productname>Python</productname> installation,
+ put the following in <filename>config.pl</filename>:
+<programlisting>
+$config->{python} = 'c:\python310';
+</programlisting>
+ You only need to specify those parameters that are different from what's in
+ <filename>config_default.pl</filename>.
+ </para>
+
+ <para>
+ If you need to set any other environment variables, create a file called
+ <filename>buildenv.pl</filename> and put the required commands there. For
+ example, to add the path for bison when it's not in the PATH, create a file
+ containing:
+<programlisting>
+$ENV{PATH}=$ENV{PATH} . ';c:\some\where\bison\bin';
+</programlisting>
+ </para>
+
+ <para>
+ To pass additional command line arguments to the Visual Studio build
+ command (msbuild or vcbuild):
+<programlisting>
+$ENV{MSBFLAGS}="/m";
+</programlisting>
+ </para>
+
+ <sect2>
+ <title>Requirements</title>
+ <para>
+ The following additional products are required to build
+ <productname>PostgreSQL</productname>. Use the
+ <filename>config.pl</filename> file to specify which directories the libraries
+ are available in.
+
+ <variablelist>
+ <varlistentry>
+ <term><productname>Microsoft Windows SDK</productname></term>
+ <listitem><para>
+ If your build environment doesn't ship with a supported version of the
+ <productname>Microsoft Windows SDK</productname> it
+ is recommended that you upgrade to the latest version (currently
+ version 10), available for download from
+ <ulink url="https://www.microsoft.com/download"></ulink>.
+ </para>
+ <para>
+ You must always include the
+ <application>Windows Headers and Libraries</application> part of the SDK.
+ If you install a <productname>Windows SDK</productname>
+ including the <application>Visual C++ Compilers</application>,
+ you don't need <productname>Visual Studio</productname> to build.
+ Note that as of Version 8.0a the Windows SDK no longer ships with a
+ complete command-line build environment.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>ActiveState Perl</productname></term>
+ <listitem><para>
+ ActiveState Perl is required to run the build generation scripts. MinGW
+ or Cygwin Perl will not work. It must also be present in the PATH.
+ Binaries can be downloaded from
+ <ulink url="https://www.activestate.com"></ulink>
+ (Note: version 5.8.3 or later is required,
+ the free Standard Distribution is sufficient).
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ <para>
+ The following additional products are not required to get started,
+ but are required to build the complete package. Use the
+ <filename>config.pl</filename> file to specify which directories the libraries
+ are available in.
+
+ <variablelist>
+ <varlistentry>
+ <term><productname>ActiveState TCL</productname></term>
+ <listitem><para>
+ Required for building <application>PL/Tcl</application> (Note: version
+ 8.4 is required, the free Standard Distribution is sufficient).
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>Bison</productname> and
+ <productname>Flex</productname></term>
+ <listitem>
+ <para>
+ <productname>Bison</productname> and <productname>Flex</productname> are
+ required to build from Git, but not required when building from a release
+ file. Only <productname>Bison</productname> 1.875 or versions 2.2 and later
+ will work. <productname>Flex</productname> must be version 2.5.31 or later.
+ </para>
+
+ <para>
+ Both <productname>Bison</productname> and <productname>Flex</productname>
+ are included in the <productname>msys</productname> tool suite, available
+ from <ulink url="http://www.mingw.org/wiki/MSYS"></ulink> as part of the
+ <productname>MinGW</productname> compiler suite.
+ </para>
+
+ <para>
+ You will need to add the directory containing
+ <filename>flex.exe</filename> and <filename>bison.exe</filename> to the
+ PATH environment variable in <filename>buildenv.pl</filename> unless
+ they are already in PATH. In the case of MinGW, the directory is the
+ <filename>\msys\1.0\bin</filename> subdirectory of your MinGW
+ installation directory.
+ </para>
+
+ <note>
+ <para>
+ The Bison distribution from GnuWin32 appears to have a bug that
+ causes Bison to malfunction when installed in a directory with
+ spaces in the name, such as the default location on English
+ installations <filename>C:\Program Files\GnuWin32</filename>.
+ Consider installing into <filename>C:\GnuWin32</filename> or use the
+ NTFS short name path to GnuWin32 in your PATH environment setting
+ (e.g., <filename>C:\PROGRA~1\GnuWin32</filename>).
+ </para>
+ </note>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>Diff</productname></term>
+ <listitem><para>
+ Diff is required to run the regression tests, and can be downloaded
+ from <ulink url="http://gnuwin32.sourceforge.net"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>Gettext</productname></term>
+ <listitem><para>
+ Gettext is required to build with NLS support, and can be downloaded
+ from <ulink url="http://gnuwin32.sourceforge.net"></ulink>. Note that binaries,
+ dependencies and developer files are all needed.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>MIT Kerberos</productname></term>
+ <listitem><para>
+ Required for GSSAPI authentication support. MIT Kerberos can be
+ downloaded from
+ <ulink url="https://web.mit.edu/Kerberos/dist/index.html"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>libxml2</productname> and
+ <productname>libxslt</productname></term>
+ <listitem><para>
+ Required for XML support. Binaries can be downloaded from
+ <ulink url="https://zlatkovic.com/pub/libxml"></ulink> or source from
+ <ulink url="http://xmlsoft.org"></ulink>. Note that libxml2 requires iconv,
+ which is available from the same download location.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>LZ4</productname></term>
+ <listitem><para>
+ Required for supporting <productname>LZ4</productname> compression.
+ Binaries and source can be downloaded from
+ <ulink url="https://github.com/lz4/lz4/releases"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>Zstandard</productname></term>
+ <listitem><para>
+ Required for supporting <productname>Zstandard</productname> compression.
+ Binaries and source can be downloaded from
+ <ulink url="https://github.com/facebook/zstd/releases"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>OpenSSL</productname></term>
+ <listitem><para>
+ Required for SSL support. Binaries can be downloaded from
+ <ulink url="https://slproweb.com/products/Win32OpenSSL.html"></ulink>
+ or source from <ulink url="https://www.openssl.org"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>ossp-uuid</productname></term>
+ <listitem><para>
+ Required for UUID-OSSP support (contrib only). Source can be
+ downloaded from
+ <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>Python</productname></term>
+ <listitem><para>
+ Required for building <application>PL/Python</application>. Binaries can
+ be downloaded from <ulink url="https://www.python.org"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><productname>zlib</productname></term>
+ <listitem><para>
+ Required for compression support in <application>pg_dump</application>
+ and <application>pg_restore</application>. Binaries can be downloaded
+ from <ulink url="https://www.zlib.net"></ulink>.
+ </para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Special Considerations for 64-Bit Windows</title>
+
+ <para>
+ PostgreSQL will only build for the x64 architecture on 64-bit Windows, there
+ is no support for Itanium processors.
+ </para>
+
+ <para>
+ Mixing 32- and 64-bit versions in the same build tree is not supported.
+ The build system will automatically detect if it's running in a 32- or
+ 64-bit environment, and build PostgreSQL accordingly. For this reason, it
+ is important to start the correct command prompt before building.
+ </para>
+
+ <para>
+ To use a server-side third party library such as <productname>Python</productname> or
+ <productname>OpenSSL</productname>, this library <emphasis>must</emphasis> also be
+ 64-bit. There is no support for loading a 32-bit library in a 64-bit
+ server. Several of the third party libraries that PostgreSQL supports may
+ only be available in 32-bit versions, in which case they cannot be used with
+ 64-bit PostgreSQL.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Building</title>
+
+ <para>
+ To build all of PostgreSQL in release configuration (the default), run the
+ command:
+<screen>
+<userinput>build</userinput>
+</screen>
+ To build all of PostgreSQL in debug configuration, run the command:
+<screen>
+<userinput>build DEBUG</userinput>
+</screen>
+ To build just a single project, for example psql, run the commands:
+<screen>
+<userinput>build psql</userinput>
+<userinput>build DEBUG psql</userinput>
+</screen>
+ To change the default build configuration to debug, put the following
+ in the <filename>buildenv.pl</filename> file:
+<programlisting>
+$ENV{CONFIG}="Debug";
+</programlisting>
+ </para>
+
+ <para>
+ It is also possible to build from inside the Visual Studio GUI. In this
+ case, you need to run:
+<screen>
+<userinput>perl mkvcbuild.pl</userinput>
+</screen>
+ from the command prompt, and then open the generated
+ <filename>pgsql.sln</filename> (in the root directory of the source tree)
+ in Visual Studio.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Cleaning and Installing</title>
+
+ <para>
+ Most of the time, the automatic dependency tracking in Visual Studio will
+ handle changed files. But if there have been large changes, you may need
+ to clean the installation. To do this, simply run the
+ <filename>clean.bat</filename> command, which will automatically clean out
+ all generated files. You can also run it with the
+ <parameter>dist</parameter> parameter, in which case it will behave like
+ <userinput>make distclean</userinput> and remove the flex/bison output files
+ as well.
+ </para>
+
+ <para>
+ By default, all files are written into a subdirectory of the
+ <filename>debug</filename> or <filename>release</filename> directories. To
+ install these files using the standard layout, and also generate the files
+ required to initialize and use the database, run the command:
+<screen>
+<userinput>install c:\destination\directory</userinput>
+</screen>
+ </para>
+
+ <para>
+ If you want to install only the client applications and
+ interface libraries, then you can use these commands:
+<screen>
+<userinput>install c:\destination\directory client</userinput>
+</screen>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Running the Regression Tests</title>
+
+ <para>
+ To run the regression tests, make sure you have completed the build of all
+ required parts first. Also, make sure that the DLLs required to load all
+ parts of the system (such as the Perl and Python DLLs for the procedural
+ languages) are present in the system path. If they are not, set it through
+ the <filename>buildenv.pl</filename> file. To run the tests, run one of
+ the following commands from the <filename>src\tools\msvc</filename>
+ directory:
+<screen>
+<userinput>vcregress check</userinput>
+<userinput>vcregress installcheck</userinput>
+<userinput>vcregress plcheck</userinput>
+<userinput>vcregress contribcheck</userinput>
+<userinput>vcregress modulescheck</userinput>
+<userinput>vcregress ecpgcheck</userinput>
+<userinput>vcregress isolationcheck</userinput>
+<userinput>vcregress bincheck</userinput>
+<userinput>vcregress recoverycheck</userinput>
+</screen>
+
+ To change the schedule used (default is parallel), append it to the
+ command line like:
+<screen>
+<userinput>vcregress check serial</userinput>
+</screen>
+
+ For more information about the regression tests, see
+ <xref linkend="regress"/>.
+ </para>
+
+ <para>
+ Running the regression tests on client programs, with
+ <command>vcregress bincheck</command>, or on recovery tests, with
+ <command>vcregress recoverycheck</command>, requires an additional Perl module
+ to be installed:
+ <variablelist>
+ <varlistentry>
+ <term><productname>IPC::Run</productname></term>
+ <listitem><para>
+ As of this writing, <literal>IPC::Run</literal> is not included in the
+ ActiveState Perl installation, nor in the ActiveState Perl Package
+ Manager (PPM) library. To install, download the
+ <filename>IPC-Run-&lt;version&gt;.tar.gz</filename> source archive from CPAN,
+ at <ulink url="https://metacpan.org/release/IPC-Run"></ulink>, and
+ uncompress. Edit the <filename>buildenv.pl</filename> file, and add a PERL5LIB
+ variable to point to the <filename>lib</filename> subdirectory from the
+ extracted archive. For example:
+<programlisting>
+$ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib';
+</programlisting>
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The TAP tests run with <command>vcregress</command> support the
+ environment variables <varname>PROVE_TESTS</varname>, that is expanded
+ automatically using the name patterns given, and
+ <varname>PROVE_FLAGS</varname>. These can be set on a Windows terminal,
+ before running <command>vcregress</command>:
+<programlisting>
+set PROVE_FLAGS=--timer --jobs 2
+set PROVE_TESTS=t/020*.pl t/010*.pl
+</programlisting>
+ It is also possible to set up those parameters in
+ <filename>buildenv.pl</filename>:
+<programlisting>
+$ENV{PROVE_FLAGS}='--timer --jobs 2'
+$ENV{PROVE_TESTS}='t/020*.pl t/010*.pl'
+</programlisting>
+ </para>
+
+ <para>
+ Some of the TAP tests depend on a set of external commands that would
+ optionally trigger tests related to them. Each one of those variables
+ can be set or unset in <filename>buildenv.pl</filename>:
+ <variablelist>
+ <varlistentry>
+ <term><varname>GZIP_PROGRAM</varname></term>
+ <listitem><para>
+ Path to a <application>gzip</application> command. The default is
+ <literal>gzip</literal>, which will search for a command by that
+ name in the configured <envar>PATH</envar>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>LZ4</varname></term>
+ <listitem><para>
+ Path to a <application>lz4</application> command. The default is
+ <literal>lz4</literal>, which will search for a command by that
+ name in the configured <envar>PATH</envar>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TAR</varname></term>
+ <listitem><para>
+ Path to a <application>tar</application> command. The default is
+ <literal>tar</literal>, which will search for a command by that
+ name in the configured <envar>PATH</envar>.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ZSTD</varname></term>
+ <listitem><para>
+ Path to a <application>zstd</application> command. The default is
+ <literal>zstd</literal>, which will search for a command by that
+ name in the configured <envar>PATH</envar>.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
new file mode 100644
index 0000000..04a2258
--- /dev/null
+++ b/doc/src/sgml/installation.sgml
@@ -0,0 +1,2637 @@
+<!-- doc/src/sgml/installation.sgml -->
+<!--
+
+The standalone version has some portions that are different from the version
+that is integrated into the full documentation set, in particular as regards
+links, so that INSTALL.html can be created without links to the main
+documentation. See standalone-profile.xsl for details.
+
+-->
+
+<chapter id="installation">
+ <title>Installation from Source Code</title>
+
+ <indexterm zone="installation">
+ <primary>installation</primary>
+ </indexterm>
+
+ <!-- See also the version of this text in standalone-install.xml -->
+ <para>
+ This chapter describes the installation of
+ <productname>PostgreSQL</productname> using the source code
+ distribution. If you are installing a pre-packaged distribution,
+ such as an RPM or Debian package, ignore this chapter
+ and see <xref linkend="install-binaries" /> instead.
+ </para>
+
+ <para>
+ If you are building <productname>PostgreSQL</productname> for Microsoft
+ Windows, read this chapter if you intend to build with MinGW or Cygwin;
+ but if you intend to build with Microsoft's <productname>Visual
+ C++</productname>, see <xref linkend="install-windows"/> instead.
+ </para>
+
+ <sect1 id="install-short">
+ <title>Short Version</title>
+
+ <para>
+<synopsis>
+./configure
+make
+su
+make install
+adduser postgres
+mkdir -p /usr/local/pgsql/data
+chown postgres /usr/local/pgsql/data
+su - postgres
+/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
+/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start
+/usr/local/pgsql/bin/createdb test
+/usr/local/pgsql/bin/psql test
+</synopsis>
+ The long version is the rest of this
+ <phrase>chapter</phrase>.
+ </para>
+ </sect1>
+
+
+ <sect1 id="install-requirements">
+ <title>Requirements</title>
+
+ <para>
+ In general, a modern Unix-compatible platform should be able to run
+ <productname>PostgreSQL</productname>.
+ The platforms that had received specific testing at the
+ time of release are described in <xref linkend="supported-platforms"/>
+ below.
+ </para>
+
+ <para>
+ The following software packages are required for building
+ <productname>PostgreSQL</productname>:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>make</primary>
+ </indexterm>
+
+ <acronym>GNU</acronym> <application>make</application> version 3.81 or newer is required; other
+ <application>make</application> programs or older <acronym>GNU</acronym> <application>make</application> versions will <emphasis>not</emphasis> work.
+ (<acronym>GNU</acronym> <application>make</application> is sometimes installed under
+ the name <filename>gmake</filename>.) To test for <acronym>GNU</acronym>
+ <application>make</application> enter:
+<screen>
+<userinput>make --version</userinput>
+</screen>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You need an <acronym>ISO</acronym>/<acronym>ANSI</acronym> C compiler (at least
+ C99-compliant). Recent
+ versions of <productname>GCC</productname> are recommended, but
+ <productname>PostgreSQL</productname> is known to build using a wide variety
+ of compilers from different vendors.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <application>tar</application> is required to unpack the source
+ distribution, in addition to either
+ <application>gzip</application> or <application>bzip2</application>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>readline</primary>
+ </indexterm>
+ <indexterm>
+ <primary>libedit</primary>
+ </indexterm>
+
+ The <acronym>GNU</acronym> <productname>Readline</productname> library is used by
+ default. It allows <application>psql</application> (the
+ PostgreSQL command line SQL interpreter) to remember each
+ command you type, and allows you to use arrow keys to recall and
+ edit previous commands. This is very helpful and is strongly
+ recommended. If you don't want to use it then you must specify
+ the <option>--without-readline</option> option to
+ <filename>configure</filename>. As an alternative, you can often use the
+ BSD-licensed <filename>libedit</filename> library, originally
+ developed on <productname>NetBSD</productname>. The
+ <filename>libedit</filename> library is
+ GNU <productname>Readline</productname>-compatible and is used if
+ <filename>libreadline</filename> is not found, or if
+ <option>--with-libedit-preferred</option> is used as an
+ option to <filename>configure</filename>. If you are using a package-based
+ Linux distribution, be aware that you need both the
+ <literal>readline</literal> and <literal>readline-devel</literal> packages, if
+ those are separate in your distribution.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>zlib</primary>
+ </indexterm>
+
+ The <productname>zlib</productname> compression library is
+ used by default. If you don't want to use it then you must
+ specify the <option>--without-zlib</option> option to
+ <filename>configure</filename>. Using this option disables
+ support for compressed archives in <application>pg_dump</application> and
+ <application>pg_restore</application>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The following packages are optional. They are not required in the
+ default configuration, but they are needed when certain build
+ options are enabled, as explained below:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ To build the server programming language
+ <application>PL/Perl</application> you need a full
+ <productname>Perl</productname> installation, including the
+ <filename>libperl</filename> library and the header files.
+ The minimum required version is <productname>Perl</productname> 5.8.3.
+ Since <application>PL/Perl</application> will be a shared
+ library, the <indexterm><primary>libperl</primary></indexterm>
+ <filename>libperl</filename> library must be a shared library
+ also on most platforms. This appears to be the default in
+ recent <productname>Perl</productname> versions, but it was not
+ in earlier versions, and in any case it is the choice of whomever
+ installed Perl at your site. <filename>configure</filename> will fail
+ if building <application>PL/Perl</application> is selected but it cannot
+ find a shared <filename>libperl</filename>. In that case, you will have
+ to rebuild and install <productname>Perl</productname> manually to be
+ able to build <application>PL/Perl</application>. During the
+ configuration process for <productname>Perl</productname>, request a
+ shared library.
+ </para>
+
+ <para>
+ If you intend to make more than incidental use of
+ <application>PL/Perl</application>, you should ensure that the
+ <productname>Perl</productname> installation was built with the
+ <literal>usemultiplicity</literal> option enabled (<literal>perl -V</literal>
+ will show whether this is the case).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ To build the <application>PL/Python</application> server programming
+ language, you need a <productname>Python</productname>
+ installation with the header files and
+ the <application>sysconfig</application> module. The minimum
+ required version is <productname>Python</productname> 3.2.
+ </para>
+
+ <para>
+ Since <application>PL/Python</application> will be a shared
+ library, the <indexterm><primary>libpython</primary></indexterm>
+ <filename>libpython</filename> library must be a shared library
+ also on most platforms. This is not the case in a default
+ <productname>Python</productname> installation built from source, but a
+ shared library is available in many operating system
+ distributions. <filename>configure</filename> will fail if
+ building <application>PL/Python</application> is selected but it cannot
+ find a shared <filename>libpython</filename>. That might mean that you
+ either have to install additional packages or rebuild (part of) your
+ <productname>Python</productname> installation to provide this shared
+ library. When building from source, run <productname>Python</productname>'s
+ configure with the <literal>--enable-shared</literal> flag.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ To build the <application>PL/Tcl</application>
+ procedural language, you of course need a <productname>Tcl</productname>
+ installation. The minimum required version is
+ <productname>Tcl</productname> 8.4.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ To enable Native Language Support (<acronym>NLS</acronym>), that
+ is, the ability to display a program's messages in a language
+ other than English, you need an implementation of the
+ <application>Gettext</application> <acronym>API</acronym>. Some operating
+ systems have this built-in (e.g., <systemitem
+ class="osname">Linux</systemitem>, <systemitem class="osname">NetBSD</systemitem>,
+ <systemitem class="osname">Solaris</systemitem>), for other systems you
+ can download an add-on package from <ulink
+ url="https://www.gnu.org/software/gettext/"></ulink>.
+ If you are using the <application>Gettext</application> implementation in
+ the <acronym>GNU</acronym> C library then you will additionally
+ need the <productname>GNU Gettext</productname> package for some
+ utility programs. For any of the other implementations you will
+ not need it.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You need <productname>OpenSSL</productname>, if you want to support
+ encrypted client connections. <productname>OpenSSL</productname> is
+ also required for random number generation on platforms that do not
+ have <filename>/dev/urandom</filename> (except Windows). The minimum
+ required version is 1.0.1.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You need <application>Kerberos</application>, <productname>OpenLDAP</productname>,
+ and/or <application>PAM</application>, if you want to support authentication
+ using those services.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You need <productname>LZ4</productname>, if you want to support
+ compression of data with that method; see
+ <xref linkend="guc-default-toast-compression"/> and
+ <xref linkend="guc-wal-compression"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You need <productname>Zstandard</productname>, if you want to support
+ compression of data with that method; see
+ <xref linkend="guc-wal-compression"/>.
+ The minimum required version is 1.4.0.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ To build the <productname>PostgreSQL</productname> documentation,
+ there is a separate set of requirements; see
+ <xref linkend="docguide-toolsets"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ If you are building from a <productname>Git</productname> tree instead of
+ using a released source package, or if you want to do server development,
+ you also need the following packages:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>flex</primary>
+ </indexterm>
+ <indexterm>
+ <primary>lex</primary>
+ </indexterm>
+ <indexterm>
+ <primary>bison</primary>
+ </indexterm>
+ <indexterm>
+ <primary>yacc</primary>
+ </indexterm>
+
+ <application>Flex</application> and <application>Bison</application>
+ are needed to build from a Git checkout, or if you changed the actual
+ scanner and parser definition files. If you need them, be sure
+ to get <application>Flex</application> 2.5.31 or later and
+ <application>Bison</application> 1.875 or later. Other <application>lex</application>
+ and <application>yacc</application> programs cannot be used.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>perl</primary>
+ </indexterm>
+
+ <application>Perl</application> 5.8.3 or later is needed to build from a Git checkout,
+ or if you changed the input files for any of the build steps that
+ use Perl scripts. If building on Windows you will need
+ <application>Perl</application> in any case. <application>Perl</application> is
+ also required to run some test suites.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ If you need to get a <acronym>GNU</acronym> package, you can find
+ it at your local <acronym>GNU</acronym> mirror site (see <ulink
+ url="https://www.gnu.org/prep/ftp"></ulink>
+ for a list) or at <ulink
+ url="ftp://ftp.gnu.org/gnu/"></ulink>.
+ </para>
+
+ <para>
+ Also check that you have sufficient disk space. You will need about
+ 350 MB for the source tree during compilation and about 60 MB for
+ the installation directory. An empty database cluster takes about
+ 40 MB; databases take about five times the amount of space that a
+ flat text file with the same data would take. If you are going to
+ run the regression tests you will temporarily need up to an extra
+ 300 MB. Use the <command>df</command> command to check free disk
+ space.
+ </para>
+ </sect1>
+
+ <sect1 id="install-getsource">
+ <title>Getting the Source</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> source code for released versions
+ can be obtained from the download section of our website:
+ <ulink url="https://www.postgresql.org/ftp/source/"></ulink>.
+ Download the
+ <filename>postgresql-<replaceable>version</replaceable>.tar.gz</filename>
+ or <filename>postgresql-<replaceable>version</replaceable>.tar.bz2</filename>
+ file you're interested in, then unpack it:
+<screen>
+<userinput>tar xf postgresql-<replaceable>version</replaceable>.tar.bz2</userinput>
+</screen>
+ This will create a directory
+ <filename>postgresql-<replaceable>version</replaceable></filename> under
+ the current directory with the <productname>PostgreSQL</productname> sources.
+ Change into that directory for the rest of the installation procedure.
+ </para>
+
+ <para>
+ Alternatively, you can use the Git version control system; see
+ <xref linkend="git"/> for more information.
+ </para>
+ </sect1>
+
+ <sect1 id="install-procedure">
+ <title>Installation Procedure</title>
+
+ <procedure>
+
+ <step id="configure">
+ <title>Configuration</title>
+
+ <indexterm zone="configure">
+ <primary>configure</primary>
+ </indexterm>
+
+ <para>
+ The first step of the installation procedure is to configure the
+ source tree for your system and choose the options you would like.
+ This is done by running the <filename>configure</filename> script. For a
+ default installation simply enter:
+<screen>
+<userinput>./configure</userinput>
+</screen>
+ This script will run a number of tests to determine values for various
+ system dependent variables and detect any quirks of your
+ operating system, and finally will create several files in the
+ build tree to record what it found.
+ </para>
+
+ <para>
+ You can also run <filename>configure</filename> in a directory outside
+ the source tree, and then build there, if you want to keep the build
+ directory separate from the original source files. This procedure is
+ called a
+ <indexterm><primary>VPATH</primary></indexterm><firstterm>VPATH</firstterm>
+ build. Here's how:
+<screen>
+<userinput>mkdir build_dir</userinput>
+<userinput>cd build_dir</userinput>
+<userinput>/path/to/source/tree/configure [options go here]</userinput>
+<userinput>make</userinput>
+</screen>
+ </para>
+
+ <para>
+ The default configuration will build the server and utilities, as
+ well as all client applications and interfaces that require only a
+ C compiler. All files will be installed under
+ <filename>/usr/local/pgsql</filename> by default.
+ </para>
+
+ <para>
+ You can customize the build and installation process by supplying one
+ or more command line options to <filename>configure</filename>.
+ Typically you would customize the install location, or the set of
+ optional features that are built. <filename>configure</filename>
+ has a large number of options, which are described in
+ <xref linkend="configure-options"/>.
+ </para>
+
+ <para>
+ Also, <filename>configure</filename> responds to certain environment
+ variables, as described in <xref linkend="configure-envvars"/>.
+ These provide additional ways to customize the configuration.
+ </para>
+ </step>
+
+ <step id="build">
+ <title>Build</title>
+
+ <para>
+ To start the build, type either of:
+<screen>
+<userinput>make</userinput>
+<userinput>make all</userinput>
+</screen>
+ (Remember to use <acronym>GNU</acronym> <application>make</application>.)
+ The build will take a few minutes depending on your
+ hardware.
+ </para>
+
+ <para>
+ If you want to build everything that can be built, including the
+ documentation (HTML and man pages), and the additional modules
+ (<filename>contrib</filename>), type instead:
+<screen>
+<userinput>make world</userinput>
+</screen>
+ </para>
+
+ <para>
+ If you want to build everything that can be built, including the
+ additional modules (<filename>contrib</filename>), but without
+ the documentation, type instead:
+<screen>
+<userinput>make world-bin</userinput>
+</screen>
+ </para>
+
+ <para>
+ If you want to invoke the build from another makefile rather than
+ manually, you must unset <varname>MAKELEVEL</varname> or set it to zero,
+ for instance like this:
+<programlisting>
+build-postgresql:
+ $(MAKE) -C postgresql MAKELEVEL=0 all
+</programlisting>
+ Failure to do that can lead to strange error messages, typically about
+ missing header files.
+ </para>
+ </step>
+
+ <step>
+ <title>Regression Tests</title>
+
+ <indexterm>
+ <primary>regression test</primary>
+ </indexterm>
+
+ <para>
+ If you want to test the newly built server before you install it,
+ you can run the regression tests at this point. The regression
+ tests are a test suite to verify that <productname>PostgreSQL</productname>
+ runs on your machine in the way the developers expected it
+ to. Type:
+<screen>
+<userinput>make check</userinput>
+</screen>
+ (This won't work as root; do it as an unprivileged user.)
+ See <xref linkend="regress"/> for
+ detailed information about interpreting the test results. You can
+ repeat this test at any later time by issuing the same command.
+ </para>
+ </step>
+
+ <step id="install">
+ <title>Installing the Files</title>
+
+ <note>
+ <para>
+ If you are upgrading an existing system be sure to read
+ <xref linkend="upgrading"/>,
+ which has instructions about upgrading a
+ cluster.
+ </para>
+ </note>
+
+ <para>
+ To install <productname>PostgreSQL</productname> enter:
+<screen>
+<userinput>make install</userinput>
+</screen>
+ This will install files into the directories that were specified
+ in <xref linkend="configure"/>. Make sure that you have appropriate
+ permissions to write into that area. Normally you need to do this
+ step as root. Alternatively, you can create the target
+ directories in advance and arrange for appropriate permissions to
+ be granted.
+ </para>
+
+ <para>
+ To install the documentation (HTML and man pages), enter:
+<screen>
+<userinput>make install-docs</userinput>
+</screen>
+ </para>
+
+ <para>
+ If you built the world above, type instead:
+<screen>
+<userinput>make install-world</userinput>
+</screen>
+ This also installs the documentation.
+ </para>
+
+ <para>
+ If you built the world without the documentation above, type instead:
+<screen>
+<userinput>make install-world-bin</userinput>
+</screen>
+ </para>
+
+ <para>
+ You can use <literal>make install-strip</literal> instead of
+ <literal>make install</literal> to strip the executable files and
+ libraries as they are installed. This will save some space. If
+ you built with debugging support, stripping will effectively
+ remove the debugging support, so it should only be done if
+ debugging is no longer needed. <literal>install-strip</literal>
+ tries to do a reasonable job saving space, but it does not have
+ perfect knowledge of how to strip every unneeded byte from an
+ executable file, so if you want to save all the disk space you
+ possibly can, you will have to do manual work.
+ </para>
+
+ <para>
+ The standard installation provides all the header files needed for client
+ application development as well as for server-side program
+ development, such as custom functions or data types written in C.
+ </para>
+
+ <formalpara>
+ <title>Client-only installation:</title>
+ <para>
+ If you want to install only the client applications and
+ interface libraries, then you can use these commands:
+<screen>
+<userinput>make -C src/bin install</userinput>
+<userinput>make -C src/include install</userinput>
+<userinput>make -C src/interfaces install</userinput>
+<userinput>make -C doc install</userinput>
+</screen>
+ <filename>src/bin</filename> has a few binaries for server-only use,
+ but they are small.
+ </para>
+ </formalpara>
+ </step>
+ </procedure>
+
+ <formalpara>
+ <title>Uninstallation:</title>
+ <para>
+ To undo the installation use the command <command>make
+ uninstall</command>. However, this will not remove any created directories.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Cleaning:</title>
+
+ <para>
+ After the installation you can free disk space by removing the built
+ files from the source tree with the command <command>make
+ clean</command>. This will preserve the files made by the <command>configure</command>
+ program, so that you can rebuild everything with <command>make</command>
+ later on. To reset the source tree to the state in which it was
+ distributed, use <command>make distclean</command>. If you are going to
+ build for several platforms within the same source tree you must do
+ this and re-configure for each platform. (Alternatively, use
+ a separate build tree for each platform, so that the source tree
+ remains unmodified.)
+ </para>
+ </formalpara>
+
+ <para>
+ If you perform a build and then discover that your <command>configure</command>
+ options were wrong, or if you change anything that <command>configure</command>
+ investigates (for example, software upgrades), then it's a good
+ idea to do <command>make distclean</command> before reconfiguring and
+ rebuilding. Without this, your changes in configuration choices
+ might not propagate everywhere they need to.
+ </para>
+
+ <sect2 id="configure-options">
+ <title><filename>configure</filename> Options</title>
+
+ <indexterm zone="configure-options">
+ <primary>configure options</primary>
+ </indexterm>
+
+ <para>
+ <command>configure</command>'s command line options are explained below.
+ This list is not exhaustive (use <literal>./configure --help</literal>
+ to get one that is). The options not covered here are meant for
+ advanced use-cases such as cross-compilation, and are documented in
+ the standard Autoconf documentation.
+ </para>
+
+ <sect3 id="configure-options-locations">
+ <title>Installation Locations</title>
+
+ <para>
+ These options control where <literal>make install</literal> will put
+ the files. The <option>--prefix</option> option is sufficient for
+ most cases. If you have special needs, you can customize the
+ installation subdirectories with the other options described in this
+ section. Beware however that changing the relative locations of the
+ different subdirectories may render the installation non-relocatable,
+ meaning you won't be able to move it after installation.
+ (The <literal>man</literal> and <literal>doc</literal> locations are
+ not affected by this restriction.) For relocatable installs, you
+ might want to use the <literal>--disable-rpath</literal> option
+ described later.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--prefix=<replaceable>PREFIX</replaceable></option></term>
+ <listitem>
+ <para>
+ Install all files under the directory <replaceable>PREFIX</replaceable>
+ instead of <filename>/usr/local/pgsql</filename>. The actual
+ files will be installed into various subdirectories; no files
+ will ever be installed directly into the
+ <replaceable>PREFIX</replaceable> directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--exec-prefix=<replaceable>EXEC-PREFIX</replaceable></option></term>
+ <listitem>
+ <para>
+ You can install architecture-dependent files under a
+ different prefix, <replaceable>EXEC-PREFIX</replaceable>, than what
+ <replaceable>PREFIX</replaceable> was set to. This can be useful to
+ share architecture-independent files between hosts. If you
+ omit this, then <replaceable>EXEC-PREFIX</replaceable> is set equal to
+ <replaceable>PREFIX</replaceable> and both architecture-dependent and
+ independent files will be installed under the same tree,
+ which is probably what you want.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--bindir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the directory for executable programs. The default
+ is <filename><replaceable>EXEC-PREFIX</replaceable>/bin</filename>, which
+ normally means <filename>/usr/local/pgsql/bin</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--sysconfdir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the directory for various configuration files,
+ <filename><replaceable>PREFIX</replaceable>/etc</filename> by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--libdir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the location to install libraries and dynamically loadable
+ modules. The default is
+ <filename><replaceable>EXEC-PREFIX</replaceable>/lib</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--includedir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the directory for installing C and C++ header files. The
+ default is <filename><replaceable>PREFIX</replaceable>/include</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--datarootdir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the root directory for various types of read-only data
+ files. This only sets the default for some of the following
+ options. The default is
+ <filename><replaceable>PREFIX</replaceable>/share</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--datadir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the directory for read-only data files used by the
+ installed programs. The default is
+ <filename><replaceable>DATAROOTDIR</replaceable></filename>. Note that this has
+ nothing to do with where your database files will be placed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--localedir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the directory for installing locale data, in particular
+ message translation catalog files. The default is
+ <filename><replaceable>DATAROOTDIR</replaceable>/locale</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--mandir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ The man pages that come with <productname>PostgreSQL</productname> will be installed under
+ this directory, in their respective
+ <filename>man<replaceable>x</replaceable></filename> subdirectories.
+ The default is <filename><replaceable>DATAROOTDIR</replaceable>/man</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--docdir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the root directory for installing documentation files,
+ except <quote>man</quote> pages. This only sets the default for
+ the following options. The default value for this option is
+ <filename><replaceable>DATAROOTDIR</replaceable>/doc/postgresql</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--htmldir=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ The HTML-formatted documentation for
+ <productname>PostgreSQL</productname> will be installed under
+ this directory. The default is
+ <filename><replaceable>DATAROOTDIR</replaceable></filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <note>
+ <para>
+ Care has been taken to make it possible to install
+ <productname>PostgreSQL</productname> into shared installation locations
+ (such as <filename>/usr/local/include</filename>) without
+ interfering with the namespace of the rest of the system. First,
+ the string <quote><literal>/postgresql</literal></quote> is
+ automatically appended to <varname>datadir</varname>,
+ <varname>sysconfdir</varname>, and <varname>docdir</varname>,
+ unless the fully expanded directory name already contains the
+ string <quote><literal>postgres</literal></quote> or
+ <quote><literal>pgsql</literal></quote>. For example, if you choose
+ <filename>/usr/local</filename> as prefix, the documentation will
+ be installed in <filename>/usr/local/doc/postgresql</filename>,
+ but if the prefix is <filename>/opt/postgres</filename>, then it
+ will be in <filename>/opt/postgres/doc</filename>. The public C
+ header files of the client interfaces are installed into
+ <varname>includedir</varname> and are namespace-clean. The
+ internal header files and the server header files are installed
+ into private directories under <varname>includedir</varname>. See
+ the documentation of each interface for information about how to
+ access its header files. Finally, a private subdirectory will
+ also be created, if appropriate, under <varname>libdir</varname>
+ for dynamically loadable modules.
+ </para>
+ </note>
+
+ </sect3>
+
+ <sect3 id="configure-options-features">
+ <title><productname>PostgreSQL</productname> Features</title>
+
+ <para>
+ The options described in this section enable building of
+ various <productname>PostgreSQL</productname> features that are not
+ built by default. Most of these are non-default only because they
+ require additional software, as described in
+ <xref linkend="install-requirements"/>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--enable-nls<optional>=<replaceable>LANGUAGES</replaceable></optional></option></term>
+ <listitem>
+ <para>
+ Enables Native Language Support (<acronym>NLS</acronym>),
+ that is, the ability to display a program's messages in a
+ language other than English.
+ <replaceable>LANGUAGES</replaceable> is an optional space-separated
+ list of codes of the languages that you want supported, for
+ example <literal>--enable-nls='de fr'</literal>. (The intersection
+ between your list and the set of actually provided
+ translations will be computed automatically.) If you do not
+ specify a list, then all available translations are
+ installed.
+ </para>
+
+ <para>
+ To use this option, you will need an implementation of the
+ <application>Gettext</application> API.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-perl</option></term>
+ <listitem>
+ <para>
+ Build the <application>PL/Perl</application> server-side language.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-python</option></term>
+ <listitem>
+ <para>
+ Build the <application>PL/Python</application> server-side language.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-tcl</option></term>
+ <listitem>
+ <para>
+ Build the <application>PL/Tcl</application> server-side language.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-tclconfig=<replaceable>DIRECTORY</replaceable></option></term>
+ <listitem>
+ <para>
+ Tcl installs the file <filename>tclConfig.sh</filename>, which
+ contains configuration information needed to build modules
+ interfacing to Tcl. This file is normally found automatically
+ at a well-known location, but if you want to use a different
+ version of Tcl you can specify the directory in which to look
+ for <filename>tclConfig.sh</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-icu</option></term>
+ <listitem>
+ <para>
+ Build with support for
+ the <productname>ICU</productname><indexterm><primary>ICU</primary></indexterm>
+ library, enabling use of ICU collation
+ features<phrase condition="standalone-ignore"> (see
+ <xref linkend="collation"/>)</phrase>.
+ This requires the <productname>ICU4C</productname> package
+ to be installed. The minimum required version
+ of <productname>ICU4C</productname> is currently 4.2.
+ </para>
+
+ <para>
+ By default,
+ <productname>pkg-config</productname><indexterm><primary>pkg-config</primary></indexterm>
+ will be used to find the required compilation options. This is
+ supported for <productname>ICU4C</productname> version 4.6 and later.
+ For older versions, or if <productname>pkg-config</productname> is
+ not available, the variables <envar>ICU_CFLAGS</envar>
+ and <envar>ICU_LIBS</envar> can be specified
+ to <filename>configure</filename>, like in this example:
+<programlisting>
+./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata'
+</programlisting>
+ (If <productname>ICU4C</productname> is in the default search path
+ for the compiler, then you still need to specify nonempty strings in
+ order to avoid use of <productname>pkg-config</productname>, for
+ example, <literal>ICU_CFLAGS=' '</literal>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="configure-with-llvm">
+ <term><option>--with-llvm</option></term>
+ <listitem>
+ <para>
+ Build with support for <productname>LLVM</productname> based
+ <acronym>JIT</acronym> compilation<phrase
+ condition="standalone-ignore"> (see <xref
+ linkend="jit"/>)</phrase>. This
+ requires the <productname>LLVM</productname> library to be installed.
+ The minimum required version of <productname>LLVM</productname> is
+ currently 3.9.
+ </para>
+ <para>
+ <command>llvm-config</command><indexterm><primary>llvm-config</primary></indexterm>
+ will be used to find the required compilation options.
+ <command>llvm-config</command>, and then
+ <command>llvm-config-$major-$minor</command> for all supported
+ versions, will be searched for in your <envar>PATH</envar>. If
+ that would not yield the desired program,
+ use <envar>LLVM_CONFIG</envar> to specify a path to the
+ correct <command>llvm-config</command>. For example
+<programlisting>
+./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config'
+</programlisting>
+ </para>
+
+ <para>
+ <productname>LLVM</productname> support requires a compatible
+ <command>clang</command> compiler (specified, if necessary, using the
+ <envar>CLANG</envar> environment variable), and a working C++
+ compiler (specified, if necessary, using the <envar>CXX</envar>
+ environment variable).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-lz4</option></term>
+ <listitem>
+ <para>
+ Build with <productname>LZ4</productname> compression support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-zstd</option></term>
+ <listitem>
+ <para>
+ Build with <productname>Zstandard</productname> compression support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-ssl=<replaceable>LIBRARY</replaceable></option>
+ <indexterm>
+ <primary>OpenSSL</primary>
+ <seealso>SSL</seealso>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Build with support for <acronym>SSL</acronym> (encrypted)
+ connections. The only <replaceable>LIBRARY</replaceable>
+ supported is <option>openssl</option>. This requires the
+ <productname>OpenSSL</productname> package to be installed.
+ <filename>configure</filename> will check for the required
+ header files and libraries to make sure that your
+ <productname>OpenSSL</productname> installation is sufficient
+ before proceeding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-openssl</option></term>
+ <listitem>
+ <para>
+ Obsolete equivalent of <literal>--with-ssl=openssl</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-gssapi</option></term>
+ <listitem>
+ <para>
+ Build with support for GSSAPI authentication. On many systems, the
+ GSSAPI system (usually a part of the Kerberos installation) is not
+ installed in a location
+ that is searched by default (e.g., <filename>/usr/include</filename>,
+ <filename>/usr/lib</filename>), so you must use the options
+ <option>--with-includes</option> and <option>--with-libraries</option> in
+ addition to this option. <filename>configure</filename> will check
+ for the required header files and libraries to make sure that
+ your GSSAPI installation is sufficient before proceeding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-ldap</option></term>
+ <listitem>
+ <para>
+ Build with <acronym>LDAP</acronym><indexterm><primary>LDAP</primary></indexterm>
+ support for authentication and connection parameter lookup (see
+ <phrase id="install-ldap-links"><xref linkend="libpq-ldap"/> and
+ <xref linkend="auth-ldap"/></phrase> for more information). On Unix,
+ this requires the <productname>OpenLDAP</productname> package to be
+ installed. On Windows, the default <productname>WinLDAP</productname>
+ library is used. <filename>configure</filename> will check for the required
+ header files and libraries to make sure that your
+ <productname>OpenLDAP</productname> installation is sufficient before
+ proceeding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-pam</option></term>
+ <listitem>
+ <para>
+ Build with <acronym>PAM</acronym><indexterm><primary>PAM</primary></indexterm>
+ (Pluggable Authentication Modules) support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-bsd-auth</option></term>
+ <listitem>
+ <para>
+ Build with BSD Authentication support.
+ (The BSD Authentication framework is
+ currently only available on OpenBSD.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-systemd</option></term>
+ <listitem>
+ <para>
+ Build with support
+ for <application>systemd</application><indexterm><primary>systemd</primary></indexterm>
+ service notifications. This improves integration if the server
+ is started under <application>systemd</application> but has no impact
+ otherwise<phrase condition="standalone-ignore">; see <xref linkend="server-start"/> for more
+ information</phrase>. <application>libsystemd</application> and the
+ associated header files need to be installed to use this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-bonjour</option></term>
+ <listitem>
+ <para>
+ Build with support for Bonjour automatic service discovery.
+ This requires Bonjour support in your operating system.
+ Recommended on macOS.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-uuid=<replaceable>LIBRARY</replaceable></option></term>
+ <listitem>
+ <para>
+ Build the <xref linkend="uuid-ossp"/> module
+ (which provides functions to generate UUIDs), using the specified
+ UUID library.<indexterm><primary>UUID</primary></indexterm>
+ <replaceable>LIBRARY</replaceable> must be one of:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <option>bsd</option> to use the UUID functions found in FreeBSD
+ and some other BSD-derived systems
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <option>e2fs</option> to use the UUID library created by
+ the <literal>e2fsprogs</literal> project; this library is present in most
+ Linux systems and in macOS, and can be obtained for other
+ platforms as well
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <option>ossp</option> to use the <ulink
+ url="http://www.ossp.org/pkg/lib/uuid/">OSSP UUID library</ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-ossp-uuid</option></term>
+ <listitem>
+ <para>
+ Obsolete equivalent of <literal>--with-uuid=ossp</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-libxml</option></term>
+ <listitem>
+ <para>
+ Build with libxml2, enabling SQL/XML support. Libxml2 version 2.6.23 or
+ later is required for this feature.
+ </para>
+
+ <para>
+ To detect the required compiler and linker options, PostgreSQL will
+ query <command>pkg-config</command>, if that is installed and knows
+ about libxml2. Otherwise the program <command>xml2-config</command>,
+ which is installed by libxml2, will be used if it is found. Use
+ of <command>pkg-config</command> is preferred, because it can deal
+ with multi-architecture installations better.
+ </para>
+
+ <para>
+ To use a libxml2 installation that is in an unusual location, you
+ can set <command>pkg-config</command>-related environment
+ variables (see its documentation), or set the environment variable
+ <envar>XML2_CONFIG</envar> to point to
+ the <command>xml2-config</command> program belonging to the libxml2
+ installation, or set the variables <envar>XML2_CFLAGS</envar>
+ and <envar>XML2_LIBS</envar>. (If <command>pkg-config</command> is
+ installed, then to override its idea of where libxml2 is you must
+ either set <envar>XML2_CONFIG</envar> or set
+ both <envar>XML2_CFLAGS</envar> and <envar>XML2_LIBS</envar> to
+ nonempty strings.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-libxslt</option></term>
+ <listitem>
+ <para>
+ Build with libxslt, enabling the
+ <xref linkend="xml2"/>
+ module to perform XSL transformations of XML.
+ <option>--with-libxml</option> must be specified as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id="configure-options-anti-features">
+ <title>Anti-Features</title>
+
+ <para>
+ The options described in this section allow disabling
+ certain <productname>PostgreSQL</productname> features that are built
+ by default, but which might need to be turned off if the required
+ software or system features are not available. Using these options is
+ not recommended unless really necessary.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--without-readline</option></term>
+ <listitem>
+ <para>
+ Prevents use of the <application>Readline</application> library
+ (and <application>libedit</application> as well). This option disables
+ command-line editing and history in
+ <application>psql</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-libedit-preferred</option></term>
+ <listitem>
+ <para>
+ Favors the use of the BSD-licensed <application>libedit</application> library
+ rather than GPL-licensed <application>Readline</application>. This option
+ is significant only if you have both libraries installed; the
+ default in that case is to use <application>Readline</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--without-zlib</option></term>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>zlib</primary>
+ </indexterm>
+ Prevents use of the <application>Zlib</application> library.
+ This disables
+ support for compressed archives in <application>pg_dump</application>
+ and <application>pg_restore</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-spinlocks</option></term>
+ <listitem>
+ <para>
+ Allow the build to succeed even if <productname>PostgreSQL</productname>
+ has no CPU spinlock support for the platform. The lack of
+ spinlock support will result in very poor performance; therefore,
+ this option should only be used if the build aborts and
+ informs you that the platform lacks spinlock support. If this
+ option is required to build <productname>PostgreSQL</productname> on
+ your platform, please report the problem to the
+ <productname>PostgreSQL</productname> developers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-atomics</option></term>
+ <listitem>
+ <para>
+ Disable use of CPU atomic operations. This option does nothing on
+ platforms that lack such operations. On platforms that do have
+ them, this will result in poor performance. This option is only
+ useful for debugging or making performance comparisons.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-thread-safety</option></term>
+ <listitem>
+ <para>
+ Disable the thread-safety of client libraries. This prevents
+ concurrent threads in <application>libpq</application> and
+ <application>ECPG</application> programs from safely controlling
+ their private connection handles. Use this only on platforms
+ with deficient threading support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id="configure-options-build-process">
+ <title>Build Process Details</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--with-includes=<replaceable>DIRECTORIES</replaceable></option></term>
+ <listitem>
+ <para>
+ <replaceable>DIRECTORIES</replaceable> is a colon-separated list of
+ directories that will be added to the list the compiler
+ searches for header files. If you have optional packages
+ (such as GNU <application>Readline</application>) installed in a non-standard
+ location,
+ you have to use this option and probably also the corresponding
+ <option>--with-libraries</option> option.
+ </para>
+ <para>
+ Example: <literal>--with-includes=/opt/gnu/include:/usr/sup/include</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-libraries=<replaceable>DIRECTORIES</replaceable></option></term>
+ <listitem>
+ <para>
+ <replaceable>DIRECTORIES</replaceable> is a colon-separated list of
+ directories to search for libraries. You will probably have
+ to use this option (and the corresponding
+ <option>--with-includes</option> option) if you have packages
+ installed in non-standard locations.
+ </para>
+ <para>
+ Example: <literal>--with-libraries=/opt/gnu/lib:/usr/sup/lib</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-system-tzdata=<replaceable>DIRECTORY</replaceable></option>
+ <indexterm>
+ <primary>time zone data</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> includes its own time zone database,
+ which it requires for date and time operations. This time zone
+ database is in fact compatible with the IANA time zone
+ database provided by many operating systems such as FreeBSD,
+ Linux, and Solaris, so it would be redundant to install it again.
+ When this option is used, the system-supplied time zone database
+ in <replaceable>DIRECTORY</replaceable> is used instead of the one
+ included in the PostgreSQL source distribution.
+ <replaceable>DIRECTORY</replaceable> must be specified as an
+ absolute path. <filename>/usr/share/zoneinfo</filename> is a
+ likely directory on some operating systems. Note that the
+ installation routine will not detect mismatching or erroneous time
+ zone data. If you use this option, you are advised to run the
+ regression tests to verify that the time zone data you have
+ pointed to works correctly with <productname>PostgreSQL</productname>.
+ </para>
+
+ <indexterm><primary>cross compilation</primary></indexterm>
+
+ <para>
+ This option is mainly aimed at binary package distributors
+ who know their target operating system well. The main
+ advantage of using this option is that the PostgreSQL package
+ won't need to be upgraded whenever any of the many local
+ daylight-saving time rules change. Another advantage is that
+ PostgreSQL can be cross-compiled more straightforwardly if the
+ time zone database files do not need to be built during the
+ installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-extra-version=<replaceable>STRING</replaceable></option></term>
+ <listitem>
+ <para>
+ Append <replaceable>STRING</replaceable> to the PostgreSQL version number. You
+ can use this, for example, to mark binaries built from unreleased Git
+ snapshots or containing custom patches with an extra version string,
+ such as a <command>git describe</command> identifier or a
+ distribution package release number.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-rpath</option></term>
+ <listitem>
+ <para>
+ Do not mark <productname>PostgreSQL</productname>'s executables
+ to indicate that they should search for shared libraries in the
+ installation's library directory (see <option>--libdir</option>).
+ On most platforms, this marking uses an absolute path to the
+ library directory, so that it will be unhelpful if you relocate
+ the installation later. However, you will then need to provide
+ some other way for the executables to find the shared libraries.
+ Typically this requires configuring the operating system's
+ dynamic linker to search the library directory; see
+ <xref linkend="install-post-shlibs"/> for more detail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id="configure-options-misc">
+ <title>Miscellaneous</title>
+
+ <para>
+ It's fairly common, particularly for test builds, to adjust the
+ default port number with <option>--with-pgport</option>.
+ The other options in this section are recommended only for advanced
+ users.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--with-pgport=<replaceable>NUMBER</replaceable></option></term>
+ <listitem>
+ <para>
+ Set <replaceable>NUMBER</replaceable> as the default port number for
+ server and clients. The default is 5432. The port can always
+ be changed later on, but if you specify it here then both
+ server and clients will have the same default compiled in,
+ which can be very convenient. Usually the only good reason
+ to select a non-default value is if you intend to run multiple
+ <productname>PostgreSQL</productname> servers on the same machine.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-krb-srvnam=<replaceable>NAME</replaceable></option></term>
+ <listitem>
+ <para>
+ The default name of the Kerberos service principal used
+ by GSSAPI.
+ <literal>postgres</literal> is the default. There's usually no
+ reason to change this unless you are building for a Windows
+ environment, in which case it must be set to upper case
+ <literal>POSTGRES</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-segsize=<replaceable>SEGSIZE</replaceable></option></term>
+ <listitem>
+ <para>
+ Set the <firstterm>segment size</firstterm>, in gigabytes. Large tables are
+ divided into multiple operating-system files, each of size equal
+ to the segment size. This avoids problems with file size limits
+ that exist on many platforms. The default segment size, 1 gigabyte,
+ is safe on all supported platforms. If your operating system has
+ <quote>largefile</quote> support (which most do, nowadays), you can use
+ a larger segment size. This can be helpful to reduce the number of
+ file descriptors consumed when working with very large tables.
+ But be careful not to select a value larger than is supported
+ by your platform and the file systems you intend to use. Other
+ tools you might wish to use, such as <application>tar</application>, could
+ also set limits on the usable file size.
+ It is recommended, though not absolutely required, that this value
+ be a power of 2.
+ Note that changing this value breaks on-disk database compatibility,
+ meaning you cannot use <command>pg_upgrade</command> to upgrade to
+ a build with a different segment size.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-blocksize=<replaceable>BLOCKSIZE</replaceable></option></term>
+ <listitem>
+ <para>
+ Set the <firstterm>block size</firstterm>, in kilobytes. This is the unit
+ of storage and I/O within tables. The default, 8 kilobytes,
+ is suitable for most situations; but other values may be useful
+ in special cases.
+ The value must be a power of 2 between 1 and 32 (kilobytes).
+ Note that changing this value breaks on-disk database compatibility,
+ meaning you cannot use <command>pg_upgrade</command> to upgrade to
+ a build with a different block size.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--with-wal-blocksize=<replaceable>BLOCKSIZE</replaceable></option></term>
+ <listitem>
+ <para>
+ Set the <firstterm>WAL block size</firstterm>, in kilobytes. This is the unit
+ of storage and I/O within the WAL log. The default, 8 kilobytes,
+ is suitable for most situations; but other values may be useful
+ in special cases.
+ The value must be a power of 2 between 1 and 64 (kilobytes).
+ Note that changing this value breaks on-disk database compatibility,
+ meaning you cannot use <command>pg_upgrade</command> to upgrade to
+ a build with a different WAL block size.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id="configure-options-devel">
+ <title>Developer Options</title>
+
+ <para>
+ Most of the options in this section are only of interest for
+ developing or debugging <productname>PostgreSQL</productname>.
+ They are not recommended for production builds, except
+ for <option>--enable-debug</option>, which can be useful to enable
+ detailed bug reports in the unlucky event that you encounter a bug.
+ On platforms supporting DTrace, <option>--enable-dtrace</option>
+ may also be reasonable to use in production.
+ </para>
+
+ <para>
+ When building an installation that will be used to develop code inside
+ the server, it is recommended to use at least the
+ options <option>--enable-debug</option>
+ and <option>--enable-cassert</option>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--enable-debug</option></term>
+ <listitem>
+ <para>
+ Compiles all programs and libraries with debugging symbols.
+ This means that you can run the programs in a debugger
+ to analyze problems. This enlarges the size of the installed
+ executables considerably, and on non-GCC compilers it usually
+ also disables compiler optimization, causing slowdowns. However,
+ having the symbols available is extremely helpful for dealing
+ with any problems that might arise. Currently, this option is
+ recommended for production installations only if you use GCC.
+ But you should always have it on if you are doing development work
+ or running a beta version.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-cassert</option></term>
+ <listitem>
+ <para>
+ Enables <firstterm>assertion</firstterm> checks in the server, which test for
+ many <quote>cannot happen</quote> conditions. This is invaluable for
+ code development purposes, but the tests can slow down the
+ server significantly.
+ Also, having the tests turned on won't necessarily enhance the
+ stability of your server! The assertion checks are not categorized
+ for severity, and so what might be a relatively harmless bug will
+ still lead to server restarts if it triggers an assertion
+ failure. This option is not recommended for production use, but
+ you should have it on for development work or when running a beta
+ version.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-tap-tests</option></term>
+ <listitem>
+ <para>
+ Enable tests using the Perl TAP tools. This requires a Perl
+ installation and the Perl module <literal>IPC::Run</literal>.
+ <phrase condition="standalone-ignore">See <xref linkend="regress-tap"/> for more information.</phrase>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-depend</option></term>
+ <listitem>
+ <para>
+ Enables automatic dependency tracking. With this option, the
+ makefiles are set up so that all affected object files will
+ be rebuilt when any header file is changed. This is useful
+ if you are doing development work, but is just wasted overhead
+ if you intend only to compile once and install. At present,
+ this option only works with GCC.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-coverage</option></term>
+ <listitem>
+ <para>
+ If using GCC, all programs and libraries are compiled with
+ code coverage testing instrumentation. When run, they
+ generate files in the build directory with code coverage
+ metrics.
+ <phrase condition="standalone-ignore">See <xref linkend="regress-coverage"/>
+ for more information.</phrase> This option is for use only with GCC
+ and when doing development work.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-profiling</option></term>
+ <listitem>
+ <para>
+ If using GCC, all programs and libraries are compiled so they
+ can be profiled. On backend exit, a subdirectory will be created
+ that contains the <filename>gmon.out</filename> file containing
+ profile data.
+ This option is for use only with GCC and when doing development work.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-dtrace</option></term>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary>DTrace</primary>
+ </indexterm>
+ Compiles <productname>PostgreSQL</productname> with support for the
+ dynamic tracing tool DTrace.
+ <phrase condition="standalone-ignore">See <xref linkend="dynamic-trace"/>
+ for more information.</phrase>
+ </para>
+
+ <para>
+ To point to the <command>dtrace</command> program, the
+ environment variable <envar>DTRACE</envar> can be set. This
+ will often be necessary because <command>dtrace</command> is
+ typically installed under <filename>/usr/sbin</filename>,
+ which might not be in your <envar>PATH</envar>.
+ </para>
+
+ <para>
+ Extra command-line options for the <command>dtrace</command> program
+ can be specified in the environment variable
+ <envar>DTRACEFLAGS</envar>. On Solaris,
+ to include DTrace support in a 64-bit binary, you must specify
+ <literal>DTRACEFLAGS="-64"</literal>. For example,
+ using the GCC compiler:
+<screen>
+./configure CC='gcc -m64' --enable-dtrace DTRACEFLAGS='-64' ...
+</screen>
+ Using Sun's compiler:
+<screen>
+./configure CC='/opt/SUNWspro/bin/cc -xtarget=native64' --enable-dtrace DTRACEFLAGS='-64' ...
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="configure-envvars">
+ <title><filename>configure</filename> Environment Variables</title>
+
+ <indexterm zone="configure-envvars">
+ <primary>configure environment variables</primary>
+ </indexterm>
+
+ <para>
+ In addition to the ordinary command-line options described above,
+ <filename>configure</filename> responds to a number of environment
+ variables.
+ You can specify environment variables on the
+ <filename>configure</filename> command line, for example:
+<screen>
+<userinput>./configure CC=/opt/bin/gcc CFLAGS='-O2 -pipe'</userinput>
+</screen>
+ In this usage an environment variable is little different from a
+ command-line option.
+ You can also set such variables beforehand:
+<screen>
+<userinput>export CC=/opt/bin/gcc</userinput>
+<userinput>export CFLAGS='-O2 -pipe'</userinput>
+<userinput>./configure</userinput>
+</screen>
+ This usage can be convenient because many programs' configuration
+ scripts respond to these variables in similar ways.
+ </para>
+
+ <para>
+ The most commonly used of these environment variables are
+ <envar>CC</envar> and <envar>CFLAGS</envar>.
+ If you prefer a C compiler different from the one
+ <filename>configure</filename> picks, you can set the
+ variable <envar>CC</envar> to the program of your choice.
+ By default, <filename>configure</filename> will pick
+ <filename>gcc</filename> if available, else the platform's
+ default (usually <filename>cc</filename>). Similarly, you can override the
+ default compiler flags if needed with the <envar>CFLAGS</envar> variable.
+ </para>
+
+ <para>
+ Here is a list of the significant variables that can be set in
+ this manner:
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>BISON</envar></term>
+ <listitem>
+ <para>
+ Bison program
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CC</envar></term>
+ <listitem>
+ <para>
+ C compiler
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CFLAGS</envar></term>
+ <listitem>
+ <para>
+ options to pass to the C compiler
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CLANG</envar></term>
+ <listitem>
+ <para>
+ path to <command>clang</command> program used to process source code
+ for inlining when compiling with <literal>--with-llvm</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CPP</envar></term>
+ <listitem>
+ <para>
+ C preprocessor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CPPFLAGS</envar></term>
+ <listitem>
+ <para>
+ options to pass to the C preprocessor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CXX</envar></term>
+ <listitem>
+ <para>
+ C++ compiler
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>CXXFLAGS</envar></term>
+ <listitem>
+ <para>
+ options to pass to the C++ compiler
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>DTRACE</envar></term>
+ <listitem>
+ <para>
+ location of the <command>dtrace</command> program
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>DTRACEFLAGS</envar></term>
+ <listitem>
+ <para>
+ options to pass to the <command>dtrace</command> program
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>FLEX</envar></term>
+ <listitem>
+ <para>
+ Flex program
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>LDFLAGS</envar></term>
+ <listitem>
+ <para>
+ options to use when linking either executables or shared libraries
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>LDFLAGS_EX</envar></term>
+ <listitem>
+ <para>
+ additional options for linking executables only
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>LDFLAGS_SL</envar></term>
+ <listitem>
+ <para>
+ additional options for linking shared libraries only
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>LLVM_CONFIG</envar></term>
+ <listitem>
+ <para>
+ <command>llvm-config</command> program used to locate the
+ <productname>LLVM</productname> installation
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>MSGFMT</envar></term>
+ <listitem>
+ <para>
+ <command>msgfmt</command> program for native language support
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PERL</envar></term>
+ <listitem>
+ <para>
+ Perl interpreter program. This will be used to determine the
+ dependencies for building PL/Perl. The default is
+ <command>perl</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PYTHON</envar></term>
+ <listitem>
+ <para>
+ Python interpreter program. This will be used to determine the
+ dependencies for building PL/Python. If this is not set, the
+ following are probed in this order:
+ <literal>python3 python</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>TCLSH</envar></term>
+ <listitem>
+ <para>
+ Tcl interpreter program. This will be used to
+ determine the dependencies for building PL/Tcl.
+ If this is not set, the following are probed in this
+ order: <literal>tclsh tcl tclsh8.6 tclsh86 tclsh8.5 tclsh85
+ tclsh8.4 tclsh84</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>XML2_CONFIG</envar></term>
+ <listitem>
+ <para>
+ <command>xml2-config</command> program used to locate the
+ libxml2 installation
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Sometimes it is useful to add compiler flags after-the-fact to the set
+ that were chosen by <filename>configure</filename>. An important example is
+ that <application>gcc</application>'s <option>-Werror</option> option cannot be included
+ in the <envar>CFLAGS</envar> passed to <filename>configure</filename>, because
+ it will break many of <filename>configure</filename>'s built-in tests. To add
+ such flags, include them in the <envar>COPT</envar> environment variable
+ while running <filename>make</filename>. The contents of <envar>COPT</envar>
+ are added to both the <envar>CFLAGS</envar> and <envar>LDFLAGS</envar>
+ options set up by <filename>configure</filename>. For example, you could do
+<screen>
+<userinput>make COPT='-Werror'</userinput>
+</screen>
+ or
+<screen>
+<userinput>export COPT='-Werror'</userinput>
+<userinput>make</userinput>
+</screen>
+ </para>
+
+ <note>
+ <para>
+ If using GCC, it is best to build with an optimization level of
+ at least <option>-O1</option>, because using no optimization
+ (<option>-O0</option>) disables some important compiler warnings (such
+ as the use of uninitialized variables). However, non-zero
+ optimization levels can complicate debugging because stepping
+ through compiled code will usually not match up one-to-one with
+ source code lines. If you get confused while trying to debug
+ optimized code, recompile the specific files of interest with
+ <option>-O0</option>. An easy way to do this is by passing an option
+ to <application>make</application>: <command>make PROFILE=-O0 file.o</command>.
+ </para>
+
+ <para>
+ The <envar>COPT</envar> and <envar>PROFILE</envar> environment variables are
+ actually handled identically by the <productname>PostgreSQL</productname>
+ makefiles. Which to use is a matter of preference, but a common habit
+ among developers is to use <envar>PROFILE</envar> for one-time flag
+ adjustments, while <envar>COPT</envar> might be kept set all the time.
+ </para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 id="install-post">
+ <title>Post-Installation Setup</title>
+
+ <sect2 id="install-post-shlibs">
+ <title>Shared Libraries</title>
+
+ <indexterm>
+ <primary>shared library</primary>
+ </indexterm>
+
+ <para>
+ On some systems with shared libraries
+ you need to tell the system how to find the newly installed
+ shared libraries. The systems on which this is
+ <emphasis>not</emphasis> necessary include
+ <systemitem class="osname">FreeBSD</systemitem>,
+ <systemitem class="osname">HP-UX</systemitem>,
+ <systemitem class="osname">Linux</systemitem>,
+ <systemitem class="osname">NetBSD</systemitem>, <systemitem
+ class="osname">OpenBSD</systemitem>, and
+ <systemitem class="osname">Solaris</systemitem>.
+ </para>
+
+ <para>
+ The method to set the shared library search path varies between
+ platforms, but the most widely-used method is to set the
+ environment variable <envar>LD_LIBRARY_PATH</envar> like so: In Bourne
+ shells (<command>sh</command>, <command>ksh</command>, <command>bash</command>, <command>zsh</command>):
+<programlisting>
+LD_LIBRARY_PATH=/usr/local/pgsql/lib
+export LD_LIBRARY_PATH
+</programlisting>
+ or in <command>csh</command> or <command>tcsh</command>:
+<programlisting>
+setenv LD_LIBRARY_PATH /usr/local/pgsql/lib
+</programlisting>
+ Replace <literal>/usr/local/pgsql/lib</literal> with whatever you set
+ <option><literal>--libdir</literal></option> to in <xref linkend="configure"/>.
+ You should put these commands into a shell start-up file such as
+ <filename>/etc/profile</filename> or <filename>~/.bash_profile</filename>. Some
+ good information about the caveats associated with this method can
+ be found at <ulink
+ url="http://xahlee.info/UnixResource_dir/_/ldpath.html"></ulink>.
+ </para>
+
+ <para>
+ On some systems it might be preferable to set the environment
+ variable <envar>LD_RUN_PATH</envar> <emphasis>before</emphasis>
+ building.
+ </para>
+
+ <para>
+ On <systemitem class="osname">Cygwin</systemitem>, put the library
+ directory in the <envar>PATH</envar> or move the
+ <filename>.dll</filename> files into the <filename>bin</filename>
+ directory.
+ </para>
+
+ <para>
+ If in doubt, refer to the manual pages of your system (perhaps
+ <command>ld.so</command> or <command>rld</command>). If you later
+ get a message like:
+<screen>
+psql: error in loading shared libraries
+libpq.so.2.1: cannot open shared object file: No such file or directory
+</screen>
+ then this step was necessary. Simply take care of it then.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>ldconfig</primary>
+ </indexterm>
+ If you are on <systemitem class="osname">Linux</systemitem> and you have root
+ access, you can run:
+<programlisting>
+/sbin/ldconfig /usr/local/pgsql/lib
+</programlisting>
+ (or equivalent directory) after installation to enable the
+ run-time linker to find the shared libraries faster. Refer to the
+ manual page of <command>ldconfig</command> for more information. On
+ <systemitem class="osname">FreeBSD</systemitem>, <systemitem
+ class="osname">NetBSD</systemitem>, and <systemitem
+ class="osname">OpenBSD</systemitem> the command is:
+<programlisting>
+/sbin/ldconfig -m /usr/local/pgsql/lib
+</programlisting>
+ instead. Other systems are not known to have an equivalent
+ command.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Environment Variables</title>
+
+ <indexterm>
+ <primary><envar>PATH</envar></primary>
+ </indexterm>
+
+ <para>
+ If you installed into <filename>/usr/local/pgsql</filename> or some other
+ location that is not searched for programs by default, you should
+ add <filename>/usr/local/pgsql/bin</filename> (or whatever you set
+ <option><literal>--bindir</literal></option> to in <xref linkend="configure"/>)
+ into your <envar>PATH</envar>. Strictly speaking, this is not
+ necessary, but it will make the use of <productname>PostgreSQL</productname>
+ much more convenient.
+ </para>
+
+ <para>
+ To do this, add the following to your shell start-up file, such as
+ <filename>~/.bash_profile</filename> (or <filename>/etc/profile</filename>, if you
+ want it to affect all users):
+<programlisting>
+PATH=/usr/local/pgsql/bin:$PATH
+export PATH
+</programlisting>
+ If you are using <command>csh</command> or <command>tcsh</command>, then use this command:
+<programlisting>
+set path = ( /usr/local/pgsql/bin $path )
+</programlisting>
+ </para>
+
+ <para>
+ <indexterm>
+ <primary><envar>MANPATH</envar></primary>
+ </indexterm>
+ To enable your system to find the <application>man</application>
+ documentation, you need to add lines like the following to a
+ shell start-up file unless you installed into a location that is
+ searched by default:
+<programlisting>
+MANPATH=/usr/local/pgsql/share/man:$MANPATH
+export MANPATH
+</programlisting>
+ </para>
+
+ <para>
+ The environment variables <envar>PGHOST</envar> and <envar>PGPORT</envar>
+ specify to client applications the host and port of the database
+ server, overriding the compiled-in defaults. If you are going to
+ run client applications remotely then it is convenient if every
+ user that plans to use the database sets <envar>PGHOST</envar>. This
+ is not required, however; the settings can be communicated via command
+ line options to most client programs.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="supported-platforms">
+ <title>Supported Platforms</title>
+
+ <para>
+ A platform (that is, a CPU architecture and operating system combination)
+ is considered supported by the <productname>PostgreSQL</productname> development
+ community if the code contains provisions to work on that platform and
+ it has recently been verified to build and pass its regression tests
+ on that platform. Currently, most testing of platform compatibility
+ is done automatically by test machines in the
+ <ulink url="https://buildfarm.postgresql.org/">PostgreSQL Build Farm</ulink>.
+ If you are interested in using <productname>PostgreSQL</productname> on a platform
+ that is not represented in the build farm, but on which the code works
+ or can be made to work, you are strongly encouraged to set up a build
+ farm member machine so that continued compatibility can be assured.
+ </para>
+
+ <para>
+ In general, <productname>PostgreSQL</productname> can be expected to work on
+ these CPU architectures: x86, x86_64, IA64, PowerPC,
+ PowerPC 64, S/390, S/390x, Sparc, Sparc 64, ARM, MIPS, MIPSEL,
+ and PA-RISC. Code support exists for M68K, M32R, and VAX, but these
+ architectures are not known to have been tested recently. It is often
+ possible to build on an unsupported CPU type by configuring with
+ <option>--disable-spinlocks</option>, but performance will be poor.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> can be expected to work on these operating
+ systems: Linux (all recent distributions), Windows (XP and later),
+ FreeBSD, OpenBSD, NetBSD, macOS, AIX, HP/UX, and Solaris.
+ Other Unix-like systems may also work but are not currently
+ being tested. In most cases, all CPU architectures supported by
+ a given operating system will work. Look in
+ <xref linkend="installation-platform-notes"/> below to see if
+ there is information
+ specific to your operating system, particularly if using an older system.
+ </para>
+
+ <para>
+ If you have installation problems on a platform that is known
+ to be supported according to recent build farm results, please report
+ it to <email>pgsql-bugs@lists.postgresql.org</email>. If you are interested
+ in porting <productname>PostgreSQL</productname> to a new platform,
+ <email>pgsql-hackers@lists.postgresql.org</email> is the appropriate place
+ to discuss that.
+ </para>
+ </sect1>
+
+ <sect1 id="installation-platform-notes">
+ <title>Platform-Specific Notes</title>
+
+ <para>
+ This section documents additional platform-specific issues
+ regarding the installation and setup of PostgreSQL. Be sure to
+ read the installation instructions, and in
+ particular <xref linkend="install-requirements"/> as well. Also,
+ check <xref linkend="regress"/> regarding the
+ interpretation of regression test results.
+ </para>
+
+ <para>
+ Platforms that are not covered here have no known platform-specific
+ installation issues.
+ </para>
+
+ <sect2 id="installation-notes-aix">
+ <title>AIX</title>
+
+ <indexterm zone="installation-notes-aix">
+ <primary>AIX</primary>
+ <secondary>installation on</secondary>
+ </indexterm>
+
+ <para>
+ You can use GCC or the native IBM compiler <command>xlc</command>
+ to build <productname>PostgreSQL</productname>
+ on <productname>AIX</productname>.
+ </para>
+
+ <para>
+ <productname>AIX</productname> versions before 7.1 are no longer
+ tested nor supported by the <productname>PostgreSQL</productname>
+ community.
+ </para>
+
+ <sect3>
+ <title>Memory Management</title>
+ <!-- https://archives.postgresql.org/message-id/603bgqmpl9.fsf@dba2.int.libertyrms.com -->
+
+ <para>
+ AIX can be somewhat peculiar with regards to the way it does
+ memory management. You can have a server with many multiples of
+ gigabytes of RAM free, but still get out of memory or address
+ space errors when running applications. One example
+ is loading of extensions failing with unusual errors.
+ For example, running as the owner of the PostgreSQL installation:
+<screen>
+=# CREATE EXTENSION plperl;
+ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process.
+</screen>
+ Running as a non-owner in the group possessing the PostgreSQL
+ installation:
+<screen>
+=# CREATE EXTENSION plperl;
+ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address
+</screen>
+ Another example is out of memory errors in the PostgreSQL server
+ logs, with every memory allocation near or greater than 256 MB
+ failing.
+ </para>
+
+ <para>
+ The overall cause of all these problems is the default bittedness
+ and memory model used by the server process. By default, all
+ binaries built on AIX are 32-bit. This does not depend upon
+ hardware type or kernel in use. These 32-bit processes are
+ limited to 4 GB of memory laid out in 256 MB segments using one
+ of a few models. The default allows for less than 256 MB in the
+ heap as it shares a single segment with the stack.
+ </para>
+
+ <para>
+ In the case of the <literal>plperl</literal> example, above,
+ check your umask and the permissions of the binaries in your
+ PostgreSQL installation. The binaries involved in that example
+ were 32-bit and installed as mode 750 instead of 755. Due to the
+ permissions being set in this fashion, only the owner or a member
+ of the possessing group can load the library. Since it isn't
+ world-readable, the loader places the object into the process'
+ heap instead of the shared library segments where it would
+ otherwise be placed.
+ </para>
+
+ <para>
+ The <quote>ideal</quote> solution for this is to use a 64-bit
+ build of PostgreSQL, but that is not always practical, because
+ systems with 32-bit processors can build, but not run, 64-bit
+ binaries.
+ </para>
+
+ <para>
+ If a 32-bit binary is desired, set <symbol>LDR_CNTRL</symbol> to
+ <literal>MAXDATA=0x<replaceable>n</replaceable>0000000</literal>,
+ where 1 &lt;= n &lt;= 8, before starting the PostgreSQL server,
+ and try different values and <filename>postgresql.conf</filename>
+ settings to find a configuration that works satisfactorily. This
+ use of <symbol>LDR_CNTRL</symbol> tells AIX that you want the
+ server to have <symbol>MAXDATA</symbol> bytes set aside for the
+ heap, allocated in 256 MB segments. When you find a workable
+ configuration,
+ <command>ldedit</command> can be used to modify the binaries so
+ that they default to using the desired heap size. PostgreSQL can
+ also be rebuilt, passing <literal>configure
+ LDFLAGS="-Wl,-bmaxdata:0x<replaceable>n</replaceable>0000000"</literal>
+ to achieve the same effect.
+ </para>
+
+ <para>
+ For a 64-bit build, set <envar>OBJECT_MODE</envar> to 64 and
+ pass <literal>CC="gcc -maix64"</literal>
+ and <literal>LDFLAGS="-Wl,-bbigtoc"</literal>
+ to <command>configure</command>. (Options for
+ <command>xlc</command> might differ.) If you omit the export of
+ <envar>OBJECT_MODE</envar>, your build may fail with linker errors. When
+ <envar>OBJECT_MODE</envar> is set, it tells AIX's build utilities
+ such as <command>ar</command>, <command>as</command>, and <command>ld</command> what
+ type of objects to default to handling.
+ </para>
+
+ <para>
+ By default, overcommit of paging space can happen. While we have
+ not seen this occur, AIX will kill processes when it runs out of
+ memory and the overcommit is accessed. The closest to this that
+ we have seen is fork failing because the system decided that
+ there was not enough memory for another process. Like many other
+ parts of AIX, the paging space allocation method and
+ out-of-memory kill is configurable on a system- or process-wide
+ basis if this becomes a problem.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="installation-notes-cygwin">
+ <title>Cygwin</title>
+
+ <indexterm zone="installation-notes-cygwin">
+ <primary>Cygwin</primary>
+ <secondary>installation on</secondary>
+ </indexterm>
+
+ <para>
+ PostgreSQL can be built using Cygwin, a Linux-like environment for
+ Windows, but that method is inferior to the native Windows build
+ <phrase condition="standalone-ignore">(see <xref linkend="install-windows"/>)</phrase> and
+ running a server under Cygwin is no longer recommended.
+ </para>
+
+ <para>
+ When building from source, proceed according to the Unix-style
+ installation procedure (i.e., <literal>./configure;
+ make</literal>; etc.), noting the following Cygwin-specific
+ differences:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Set your path to use the Cygwin bin directory before the
+ Windows utilities. This will help prevent problems with
+ compilation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <command>adduser</command> command is not supported; use
+ the appropriate user management application on Windows NT,
+ 2000, or XP. Otherwise, skip this step.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <command>su</command> command is not supported; use ssh to
+ simulate su on Windows NT, 2000, or XP. Otherwise, skip this
+ step.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <productname>OpenSSL</productname> is not supported.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Start <command>cygserver</command> for shared memory support.
+ To do this, enter the command <literal>/usr/sbin/cygserver
+ &amp;</literal>. This program needs to be running anytime you
+ start the PostgreSQL server or initialize a database cluster
+ (<command>initdb</command>). The
+ default <command>cygserver</command> configuration may need to
+ be changed (e.g., increase <symbol>SEMMNS</symbol>) to prevent
+ PostgreSQL from failing due to a lack of system resources.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Building might fail on some systems where a locale other than
+ C is in use. To fix this, set the locale to C by doing
+ <command>export LANG=C.utf8</command> before building, and then
+ setting it back to the previous setting after you have installed
+ PostgreSQL.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The parallel regression tests (<literal>make check</literal>)
+ can generate spurious regression test failures due to
+ overflowing the <function>listen()</function> backlog queue
+ which causes connection refused errors or hangs. You can limit
+ the number of connections using the make
+ variable <varname>MAX_CONNECTIONS</varname> thus:
+<programlisting>
+make MAX_CONNECTIONS=5 check
+</programlisting>
+ (On some systems you can have up to about 10 simultaneous
+ connections.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ It is possible to install <command>cygserver</command> and the
+ PostgreSQL server as Windows NT services. For information on how
+ to do this, please refer to the <filename>README</filename>
+ document included with the PostgreSQL binary package on Cygwin.
+ It is installed in the
+ directory <filename>/usr/share/doc/Cygwin</filename>.
+ </para>
+ </sect2>
+
+ <sect2 id="installation-notes-macos">
+ <title>macOS</title>
+
+ <indexterm zone="installation-notes-macos">
+ <primary>macOS</primary>
+ <secondary>installation on</secondary>
+ </indexterm>
+
+ <para>
+ To build <productname>PostgreSQL</productname> from source
+ on <productname>macOS</productname>, you will need to install Apple's
+ command line developer tools, which can be done by issuing
+<programlisting>
+xcode-select --install
+</programlisting>
+ (note that this will pop up a GUI dialog window for confirmation).
+ You may or may not wish to also install Xcode.
+ </para>
+
+ <para>
+ On recent <productname>macOS</productname> releases, it's necessary to
+ embed the <quote>sysroot</quote> path in the include switches used to
+ find some system header files. This results in the outputs of
+ the <application>configure</application> script varying depending on
+ which SDK version was used during <application>configure</application>.
+ That shouldn't pose any problem in simple scenarios, but if you are
+ trying to do something like building an extension on a different machine
+ than the server code was built on, you may need to force use of a
+ different sysroot path. To do that, set <varname>PG_SYSROOT</varname>,
+ for example
+<programlisting>
+make PG_SYSROOT=<replaceable>/desired/path</replaceable> all
+</programlisting>
+ To find out the appropriate path on your machine, run
+<programlisting>
+xcrun --show-sdk-path
+</programlisting>
+ Note that building an extension using a different sysroot version than
+ was used to build the core server is not really recommended; in the
+ worst case it could result in hard-to-debug ABI inconsistencies.
+ </para>
+
+ <para>
+ You can also select a non-default sysroot path when configuring, by
+ specifying <varname>PG_SYSROOT</varname>
+ to <application>configure</application>:
+<programlisting>
+./configure ... PG_SYSROOT=<replaceable>/desired/path</replaceable>
+</programlisting>
+ This would primarily be useful to cross-compile for some other
+ macOS version. There is no guarantee that the resulting executables
+ will run on the current host.
+ </para>
+
+ <para>
+ To suppress the <option>-isysroot</option> options altogether, use
+<programlisting>
+./configure ... PG_SYSROOT=none
+</programlisting>
+ (any nonexistent pathname will work). This might be useful if you wish
+ to build with a non-Apple compiler, but beware that that case is not
+ tested or supported by the PostgreSQL developers.
+ </para>
+
+ <para>
+ <productname>macOS</productname>'s <quote>System Integrity
+ Protection</quote> (SIP) feature breaks <literal>make check</literal>,
+ because it prevents passing the needed setting
+ of <literal>DYLD_LIBRARY_PATH</literal> down to the executables being
+ tested. You can work around that by doing <literal>make
+ install</literal> before <literal>make check</literal>.
+ Most PostgreSQL developers just turn off SIP, though.
+ </para>
+ </sect2>
+
+ <sect2 id="installation-notes-mingw">
+ <title>MinGW/Native Windows</title>
+
+ <indexterm zone="installation-notes-mingw">
+ <primary>MinGW</primary>
+ <secondary>installation on</secondary>
+ </indexterm>
+
+ <para>
+ PostgreSQL for Windows can be built using MinGW, a Unix-like build
+ environment for Microsoft operating systems, or using
+ Microsoft's <productname>Visual C++</productname> compiler suite.
+ The MinGW build procedure uses the normal build system described in
+ this chapter; the Visual C++ build works completely differently
+ and is described in <xref linkend="install-windows"/>.
+ </para>
+
+ <para>
+ The native Windows port requires a 32 or 64-bit version of Windows
+ 2000 or later. Earlier operating systems do
+ not have sufficient infrastructure (but Cygwin may be used on
+ those). MinGW, the Unix-like build tools, and MSYS, a collection
+ of Unix tools required to run shell scripts
+ like <command>configure</command>, can be downloaded
+ from <ulink url="http://www.mingw.org/"></ulink>. Neither is
+ required to run the resulting binaries; they are needed only for
+ creating the binaries.
+ </para>
+
+ <para>
+ To build 64 bit binaries using MinGW, install the 64 bit tool set
+ from <ulink url="https://mingw-w64.org/"></ulink>, put its bin
+ directory in the <envar>PATH</envar>, and run
+ <command>configure</command> with the
+ <command>--host=x86_64-w64-mingw32</command> option.
+ </para>
+
+ <para>
+ After you have everything installed, it is suggested that you
+ run <application>psql</application>
+ under <command>CMD.EXE</command>, as the MSYS console has
+ buffering issues.
+ </para>
+
+ <sect3 id="windows-crash-dumps">
+ <title>Collecting Crash Dumps on Windows</title>
+
+ <para>
+ If PostgreSQL on Windows crashes, it has the ability to generate
+ <productname>minidumps</productname> that can be used to track down the cause
+ for the crash, similar to core dumps on Unix. These dumps can be
+ read using the <productname>Windows Debugger Tools</productname> or using
+ <productname>Visual Studio</productname>. To enable the generation of dumps
+ on Windows, create a subdirectory named <filename>crashdumps</filename>
+ inside the cluster data directory. The dumps will then be written
+ into this directory with a unique name based on the identifier of
+ the crashing process and the current time of the crash.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="installation-notes-solaris">
+ <title>Solaris</title>
+
+ <indexterm zone="installation-notes-solaris">
+ <primary>Solaris</primary>
+ <secondary>installation on</secondary>
+ </indexterm>
+
+ <para>
+ PostgreSQL is well-supported on Solaris. The more up to date your
+ operating system, the fewer issues you will experience.
+ </para>
+
+ <sect3>
+ <title>Required Tools</title>
+
+ <para>
+ You can build with either GCC or Sun's compiler suite. For
+ better code optimization, Sun's compiler is strongly recommended
+ on the SPARC architecture. If
+ you are using Sun's compiler, be careful not to select
+ <filename>/usr/ucb/cc</filename>;
+ use <filename>/opt/SUNWspro/bin/cc</filename>.
+ </para>
+
+ <para>
+ You can download Sun Studio
+ from <ulink url="https://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/"></ulink>.
+ Many GNU tools are integrated into Solaris 10, or they are
+ present on the Solaris companion CD. If you need packages for
+ older versions of Solaris, you can find these tools
+ at <ulink url="http://www.sunfreeware.com"></ulink>.
+ If you prefer
+ sources, look
+ at <ulink url="https://www.gnu.org/prep/ftp"></ulink>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>configure Complains About a Failed Test Program</title>
+
+ <para>
+ If <command>configure</command> complains about a failed test
+ program, this is probably a case of the run-time linker being
+ unable to find some library, probably libz, libreadline or some
+ other non-standard library such as libssl. To point it to the
+ right location, set the <envar>LDFLAGS</envar> environment
+ variable on the <command>configure</command> command line, e.g.,
+<programlisting>
+configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib"
+</programlisting>
+ See
+ the <citerefentry><refentrytitle>ld</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ man page for more information.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Compiling for Optimal Performance</title>
+
+ <para>
+ On the SPARC architecture, Sun Studio is strongly recommended for
+ compilation. Try using the <option>-xO5</option> optimization
+ flag to generate significantly faster binaries. Do not use any
+ flags that modify behavior of floating-point operations
+ and <varname>errno</varname> processing (e.g.,
+ <option>-fast</option>).
+ </para>
+
+ <para>
+ If you do not have a reason to use 64-bit binaries on SPARC,
+ prefer the 32-bit version. The 64-bit operations are slower and
+ 64-bit binaries are slower than the 32-bit variants. On the
+ other hand, 32-bit code on the AMD64 CPU family is not native,
+ so 32-bit code is significantly slower on that CPU family.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Using DTrace for Tracing PostgreSQL</title>
+
+ <para>
+ Yes, using DTrace is possible. See <xref linkend="dynamic-trace"/> for
+ further information.
+ </para>
+
+ <para>
+ If you see the linking of the <command>postgres</command> executable abort with an
+ error message like:
+<screen>
+Undefined first referenced
+ symbol in file
+AbortTransaction utils/probes.o
+CommitTransaction utils/probes.o
+ld: fatal: Symbol referencing errors. No output written to postgres
+collect2: ld returned 1 exit status
+make: *** [postgres] Error 1
+</screen>
+ your DTrace installation is too old to handle probes in static
+ functions. You need Solaris 10u4 or newer to use DTrace.
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/intagg.sgml b/doc/src/sgml/intagg.sgml
new file mode 100644
index 0000000..c410f64
--- /dev/null
+++ b/doc/src/sgml/intagg.sgml
@@ -0,0 +1,131 @@
+<!-- doc/src/sgml/intagg.sgml -->
+
+<sect1 id="intagg" xreflabel="intagg">
+ <title>intagg</title>
+
+ <indexterm zone="intagg">
+ <primary>intagg</primary>
+ </indexterm>
+
+ <para>
+ The <filename>intagg</filename> module provides an integer aggregator and an
+ enumerator. <filename>intagg</filename> is now obsolete, because there
+ are built-in functions that provide a superset of its capabilities.
+ However, the module is still provided as a compatibility wrapper around
+ the built-in functions.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <indexterm>
+ <primary>int_array_aggregate</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>array_agg</primary>
+ </indexterm>
+
+ <para>
+ The aggregator is an aggregate function
+ <function>int_array_aggregate(integer)</function>
+ that produces an integer array
+ containing exactly the integers it is fed.
+ This is a wrapper around <function>array_agg</function>,
+ which does the same thing for any array type.
+ </para>
+
+ <indexterm>
+ <primary>int_array_enum</primary>
+ </indexterm>
+
+ <para>
+ The enumerator is a function
+ <function>int_array_enum(integer[])</function>
+ that returns <type>setof integer</type>. It is essentially the reverse
+ operation of the aggregator: given an array of integers, expand it
+ into a set of rows. This is a wrapper around <function>unnest</function>,
+ which does the same thing for any array type.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Sample Uses</title>
+
+ <para>
+ Many database systems have the notion of a one to many table. Such a table
+ usually sits between two indexed tables, for example:
+
+<programlisting>
+CREATE TABLE left (id INT PRIMARY KEY, ...);
+CREATE TABLE right (id INT PRIMARY KEY, ...);
+CREATE TABLE one_to_many(left INT REFERENCES left, right INT REFERENCES right);
+</programlisting>
+
+ It is typically used like this:
+
+<programlisting>
+SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
+ WHERE one_to_many.left = <replaceable>item</replaceable>;
+</programlisting>
+
+ This will return all the items in the right hand table for an entry
+ in the left hand table. This is a very common construct in SQL.
+ </para>
+
+ <para>
+ Now, this methodology can be cumbersome with a very large number of
+ entries in the <structname>one_to_many</structname> table. Often,
+ a join like this would result in an index scan
+ and a fetch for each right hand entry in the table for a particular
+ left hand entry. If you have a very dynamic system, there is not much you
+ can do. However, if you have some data which is fairly static, you can
+ create a summary table with the aggregator.
+
+<programlisting>
+CREATE TABLE summary AS
+ SELECT left, int_array_aggregate(right) AS right
+ FROM one_to_many
+ GROUP BY left;
+</programlisting>
+
+ This will create a table with one row per left item, and an array
+ of right items. Now this is pretty useless without some way of using
+ the array; that's why there is an array enumerator. You can do
+
+<programlisting>
+SELECT left, int_array_enum(right) FROM summary WHERE left = <replaceable>item</replaceable>;
+</programlisting>
+
+ The above query using <function>int_array_enum</function> produces the same results
+ as
+
+<programlisting>
+SELECT left, right FROM one_to_many WHERE left = <replaceable>item</replaceable>;
+</programlisting>
+
+ The difference is that the query against the summary table has to get
+ only one row from the table, whereas the direct query against
+ <structname>one_to_many</structname> must index scan and fetch a row for each entry.
+ </para>
+
+ <para>
+ On one system, an <command>EXPLAIN</command> showed a query with a cost of 8488 was
+ reduced to a cost of 329. The original query was a join involving the
+ <structname>one_to_many</structname> table, which was replaced by:
+
+<programlisting>
+SELECT right, count(right) FROM
+ ( SELECT left, int_array_enum(right) AS right
+ FROM summary JOIN (SELECT left FROM left_table WHERE left = <replaceable>item</replaceable>) AS lefts
+ ON (summary.left = lefts.left)
+ ) AS list
+ GROUP BY right
+ ORDER BY count DESC;
+</programlisting>
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/intarray.sgml b/doc/src/sgml/intarray.sgml
new file mode 100644
index 0000000..18c6f8c
--- /dev/null
+++ b/doc/src/sgml/intarray.sgml
@@ -0,0 +1,503 @@
+<!-- doc/src/sgml/intarray.sgml -->
+
+<sect1 id="intarray" xreflabel="intarray">
+ <title>intarray</title>
+
+ <indexterm zone="intarray">
+ <primary>intarray</primary>
+ </indexterm>
+
+ <para>
+ The <filename>intarray</filename> module provides a number of useful functions
+ and operators for manipulating null-free arrays of integers.
+ There is also support for indexed searches using some of the operators.
+ </para>
+
+ <para>
+ All of these operations will throw an error if a supplied array contains any
+ NULL elements.
+ </para>
+
+ <para>
+ Many of these operations are only sensible for one-dimensional arrays.
+ Although they will accept input arrays of more dimensions, the data is
+ treated as though it were a linear array in storage order.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title><filename>intarray</filename> Functions and Operators</title>
+
+ <para>
+ The functions provided by the <filename>intarray</filename> module
+ are shown in <xref linkend="intarray-func-table"/>, the operators
+ in <xref linkend="intarray-op-table"/>.
+ </para>
+
+ <table id="intarray-func-table">
+ <title><filename>intarray</filename> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>icount</primary></indexterm>
+ <function>icount</function> ( <type>integer[]</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of elements in the array.
+ </para>
+ <para>
+ <literal>icount('{1,2,3}'::integer[])</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>sort</primary></indexterm>
+ <function>sort</function> ( <type>integer[]</type>, <parameter>dir</parameter> <type>text</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Sorts the array in either ascending or descending order.
+ <parameter>dir</parameter> must be <literal>asc</literal>
+ or <literal>desc</literal>.
+ </para>
+ <para>
+ <literal>sort('{1,3,2}'::integer[], 'desc')</literal>
+ <returnvalue>{3,2,1}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sort</function> ( <type>integer[]</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para role="func_signature">
+ <indexterm><primary>sort_asc</primary></indexterm>
+ <function>sort_asc</function> ( <type>integer[]</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Sorts in ascending order.
+ </para>
+ <para>
+ <literal>sort(array[11,77,44])</literal>
+ <returnvalue>{11,44,77}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>sort_desc</primary></indexterm>
+ <function>sort_desc</function> ( <type>integer[]</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Sorts in descending order.
+ </para>
+ <para>
+ <literal>sort_desc(array[11,77,44])</literal>
+ <returnvalue>{77,44,11}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>uniq</primary></indexterm>
+ <function>uniq</function> ( <type>integer[]</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Removes adjacent duplicates.
+ Often used with <function>sort</function> to remove all duplicates.
+ </para>
+ <para>
+ <literal>uniq('{1,2,2,3,1,1}'::integer[])</literal>
+ <returnvalue>{1,2,3,1}</returnvalue>
+ </para>
+ <para>
+ <literal>uniq(sort('{1,2,3,2,1}'::integer[]))</literal>
+ <returnvalue>{1,2,3}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>idx</primary></indexterm>
+ <function>idx</function> ( <type>integer[]</type>, <parameter>item</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns index of the first array element
+ matching <parameter>item</parameter>, or 0 if no match.
+ </para>
+ <para>
+ <literal>idx(array[11,22,33,22,11], 22)</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>subarray</primary></indexterm>
+ <function>subarray</function> ( <type>integer[]</type>, <parameter>start</parameter> <type>integer</type>, <parameter>len</parameter> <type>integer</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Extracts the portion of the array starting at
+ position <parameter>start</parameter>, with <parameter>len</parameter>
+ elements.
+ </para>
+ <para>
+ <literal>subarray('{1,2,3,2,1}'::integer[], 2, 3)</literal>
+ <returnvalue>{2,3,2}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>subarray</function> ( <type>integer[]</type>, <parameter>start</parameter> <type>integer</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Extracts the portion of the array starting at
+ position <parameter>start</parameter>.
+ </para>
+ <para>
+ <literal>subarray('{1,2,3,2,1}'::integer[], 2)</literal>
+ <returnvalue>{2,3,2,1}</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>intset</primary></indexterm>
+ <function>intset</function> ( <type>integer</type> )
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Makes a single-element array.
+ </para>
+ <para>
+ <literal>intset(42)</literal>
+ <returnvalue>{42}</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="intarray-op-table">
+ <title><filename>intarray</filename> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>&amp;&amp;</literal> <type>integer[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do arrays overlap (have at least one element in common)?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>@&gt;</literal> <type>integer[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does left array contain right array?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>&lt;@</literal> <type>integer[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is left array contained in right array?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type></type> <literal>#</literal> <type>integer[]</type>
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the number of elements in the array.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>#</literal> <type>integer</type>
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns index of the first array element
+ matching the right argument, or 0 if no match.
+ (Same as <function>idx</function> function.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>+</literal> <type>integer</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Adds element to end of array.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>+</literal> <type>integer[]</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Concatenates the arrays.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>-</literal> <type>integer</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Removes entries matching the right argument from the array.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>-</literal> <type>integer[]</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Removes elements of the right array from the left array.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>|</literal> <type>integer</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Computes the union of the arguments.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>|</literal> <type>integer[]</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Computes the union of the arguments.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>&amp;</literal> <type>integer[]</type>
+ <returnvalue>integer[]</returnvalue>
+ </para>
+ <para>
+ Computes the intersection of the arguments.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>integer[]</type> <literal>@@</literal> <type>query_int</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array satisfy query? (see below)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>query_int</type> <literal>~~</literal> <type>integer[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array satisfy query? (commutator of <literal>@@</literal>)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The operators <literal>&amp;&amp;</literal>, <literal>@&gt;</literal> and
+ <literal>&lt;@</literal> are equivalent to <productname>PostgreSQL</productname>'s built-in
+ operators of the same names, except that they work only on integer arrays
+ that do not contain nulls, while the built-in operators work for any array
+ type. This restriction makes them faster than the built-in operators
+ in many cases.
+ </para>
+
+ <para>
+ The <literal>@@</literal> and <literal>~~</literal> operators test whether an array
+ satisfies a <firstterm>query</firstterm>, which is expressed as a value of a
+ specialized data type <type>query_int</type>. A <firstterm>query</firstterm>
+ consists of integer values that are checked against the elements of
+ the array, possibly combined using the operators <literal>&amp;</literal>
+ (AND), <literal>|</literal> (OR), and <literal>!</literal> (NOT). Parentheses
+ can be used as needed. For example,
+ the query <literal>1&amp;(2|3)</literal> matches arrays that contain 1
+ and also contain either 2 or 3.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Index Support</title>
+
+ <para>
+ <filename>intarray</filename> provides index support for the
+ <literal>&amp;&amp;</literal>, <literal>@&gt;</literal>,
+ and <literal>@@</literal> operators, as well as regular array equality.
+ </para>
+
+ <para>
+ Two parameterized GiST index operator classes are provided:
+ <literal>gist__int_ops</literal> (used by default) is suitable for
+ small- to medium-size data sets, while
+ <literal>gist__intbig_ops</literal> uses a larger signature and is more
+ suitable for indexing large data sets (i.e., columns containing
+ a large number of distinct array values).
+ The implementation uses an RD-tree data structure with
+ built-in lossy compression.
+ </para>
+
+ <para>
+ <literal>gist__int_ops</literal> approximates an integer set as an array of
+ integer ranges. Its optional integer parameter <literal>numranges</literal>
+ determines the maximum number of ranges in
+ one index key. The default value of <literal>numranges</literal> is 100.
+ Valid values are between 1 and 253. Using larger arrays as GiST index
+ keys leads to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </para>
+
+ <para>
+ <literal>gist__intbig_ops</literal> approximates an integer set as a bitmap
+ signature. Its optional integer parameter <literal>siglen</literal>
+ determines the signature length in bytes.
+ The default signature length is 16 bytes. Valid values of signature length
+ are between 1 and 2024 bytes. Longer signatures lead to a more precise
+ search (scanning a smaller fraction of the index and fewer heap pages), at
+ the cost of a larger index.
+ </para>
+
+ <para>
+ There is also a non-default GIN operator class
+ <literal>gin__int_ops</literal>, which supports these operators as well
+ as <literal>&lt;@</literal>.
+ </para>
+
+ <para>
+ The choice between GiST and GIN indexing depends on the relative
+ performance characteristics of GiST and GIN, which are discussed elsewhere.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Example</title>
+
+<programlisting>
+-- a message can be in one or more <quote>sections</quote>
+CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);
+
+-- create specialized index with signature length of 32 bytes
+CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32));
+
+-- select messages in section 1 OR 2 - OVERLAP operator
+SELECT message.mid FROM message WHERE message.sections &amp;&amp; '{1,2}';
+
+-- select messages in sections 1 AND 2 - CONTAINS operator
+SELECT message.mid FROM message WHERE message.sections @&gt; '{1,2}';
+
+-- the same, using QUERY operator
+SELECT message.mid FROM message WHERE message.sections @@ '1&amp;2'::query_int;
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Benchmark</title>
+
+ <para>
+ The source directory <filename>contrib/intarray/bench</filename> contains a
+ benchmark test suite, which can be run against an installed
+ <productname>PostgreSQL</productname> server. (It also requires <filename>DBD::Pg</filename>
+ to be installed.) To run:
+ </para>
+
+<programlisting>
+cd .../contrib/intarray/bench
+createdb TEST
+psql -c "CREATE EXTENSION intarray" TEST
+./create_test.pl | psql TEST
+./bench.pl
+</programlisting>
+
+ <para>
+ The <filename>bench.pl</filename> script has numerous options, which
+ are displayed when it is run without any arguments.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ All work was done by Teodor Sigaev (<email>teodor@sigaev.ru</email>) and
+ Oleg Bartunov (<email>oleg@sai.msu.su</email>). See
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/"></ulink> for
+ additional information. Andrey Oktyabrski did a great work on adding new
+ functions and operations.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/intro.sgml b/doc/src/sgml/intro.sgml
new file mode 100644
index 0000000..63eda05
--- /dev/null
+++ b/doc/src/sgml/intro.sgml
@@ -0,0 +1,161 @@
+<!-- doc/src/sgml/intro.sgml -->
+
+<preface id="preface">
+ <title>Preface</title>
+
+ <para>
+ This book is the official documentation of
+ <productname>PostgreSQL</productname>. It has been written by the
+ <productname>PostgreSQL</productname> developers and other
+ volunteers in parallel to the development of the
+ <productname>PostgreSQL</productname> software. It describes all
+ the functionality that the current version of
+ <productname>PostgreSQL</productname> officially supports.
+ </para>
+
+ <para>
+ To make the large amount of information about
+ <productname>PostgreSQL</productname> manageable, this book has been
+ organized in several parts. Each part is targeted at a different
+ class of users, or at users in different stages of their
+ <productname>PostgreSQL</productname> experience:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <xref linkend="tutorial"/> is an informal introduction for new users.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="sql"/> documents the <acronym>SQL</acronym> query
+ language environment, including data types and functions, as well
+ as user-level performance tuning. Every
+ <productname>PostgreSQL</productname> user should read this.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="admin"/> describes the installation and
+ administration of the server. Everyone who runs a
+ <productname>PostgreSQL</productname> server, be it for private
+ use or for others, should read this part.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="client-interfaces"/> describes the programming
+ interfaces for <productname>PostgreSQL</productname> client
+ programs.
+ </para>
+ </listitem>
+
+
+ <listitem>
+ <para>
+ <xref linkend="server-programming"/> contains information for
+ advanced users about the extensibility capabilities of the
+ server. Topics include user-defined data types and
+ functions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="reference"/> contains reference information about
+ SQL commands, client and server programs. This part supports
+ the other parts with structured information sorted by command or
+ program.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="internals"/> contains assorted information that might be of
+ use to <productname>PostgreSQL</productname> developers.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect1 id="intro-whatis">
+ <title> What Is <productname>PostgreSQL</productname>?</title>
+
+ <para>
+ <productname>PostgreSQL</productname> is an object-relational
+ database management system (<acronym>ORDBMS</acronym>) based on
+ <ulink url="https://dsf.berkeley.edu/postgres.html">
+ <productname>POSTGRES, Version 4.2</productname></ulink>,
+ developed at the University of California at Berkeley Computer Science
+ Department. POSTGRES pioneered many concepts that only became
+ available in some commercial database systems much later.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> is an open-source descendant
+ of this original Berkeley code. It supports a large part of the SQL
+ standard and offers many modern features:
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <simpara>complex queries</simpara>
+ </listitem>
+ <listitem>
+ <simpara>foreign keys</simpara>
+ </listitem>
+ <listitem>
+ <simpara>triggers</simpara>
+ </listitem>
+ <listitem>
+ <simpara>updatable views</simpara>
+ </listitem>
+ <listitem>
+ <simpara>transactional integrity</simpara>
+ </listitem>
+ <listitem>
+ <simpara>multiversion concurrency control</simpara>
+ </listitem>
+ </itemizedlist>
+
+ Also, <productname>PostgreSQL</productname> can be extended by the
+ user in many ways, for example by adding new
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <simpara>data types</simpara>
+ </listitem>
+ <listitem>
+ <simpara>functions</simpara>
+ </listitem>
+ <listitem>
+ <simpara>operators</simpara>
+ </listitem>
+ <listitem>
+ <simpara>aggregate functions</simpara>
+ </listitem>
+ <listitem>
+ <simpara>index methods</simpara>
+ </listitem>
+ <listitem>
+ <simpara>procedural languages</simpara>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ And because of the liberal license,
+ <productname>PostgreSQL</productname> can be used, modified, and
+ distributed by anyone free of charge for any purpose, be it
+ private, commercial, or academic.
+ </para>
+ </sect1>
+
+ &history;
+ &notation;
+ &info;
+ &problems;
+
+</preface>
diff --git a/doc/src/sgml/isn.sgml b/doc/src/sgml/isn.sgml
new file mode 100644
index 0000000..709bc83
--- /dev/null
+++ b/doc/src/sgml/isn.sgml
@@ -0,0 +1,424 @@
+<!-- doc/src/sgml/isn.sgml -->
+
+<sect1 id="isn" xreflabel="isn">
+ <title>isn</title>
+
+ <indexterm zone="isn">
+ <primary>isn</primary>
+ </indexterm>
+
+ <para>
+ The <filename>isn</filename> module provides data types for the following
+ international product numbering standards: EAN13, UPC, ISBN (books), ISMN
+ (music), and ISSN (serials). Numbers are validated on input according to a
+ hard-coded list of prefixes; this list of prefixes is also used to hyphenate
+ numbers on output. Since new prefixes are assigned from time to time, the
+ list of prefixes may be out of date. It is hoped that a future version of
+ this module will obtain the prefix list from one or more tables that
+ can be easily updated by users as needed; however, at present, the
+ list can only be updated by modifying the source code and recompiling.
+ Alternatively, prefix validation and hyphenation support may be
+ dropped from a future version of this module.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Data Types</title>
+
+ <para>
+ <xref linkend="isn-datatypes"/> shows the data types provided by
+ the <filename>isn</filename> module.
+ </para>
+
+ <table id="isn-datatypes">
+ <title><filename>isn</filename> Data Types</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Data Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><type>EAN13</type></entry>
+ <entry>
+ European Article Numbers, always displayed in the EAN13 display format
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>ISBN13</type></entry>
+ <entry>
+ International Standard Book Numbers to be displayed in
+ the new EAN13 display format
+ </entry>
+ </row>
+
+ <row>
+ <entry><type>ISMN13</type></entry>
+ <entry>
+ International Standard Music Numbers to be displayed in
+ the new EAN13 display format
+ </entry>
+ </row>
+ <row>
+ <entry><type>ISSN13</type></entry>
+ <entry>
+ International Standard Serial Numbers to be displayed in the new
+ EAN13 display format
+ </entry>
+ </row>
+ <row>
+ <entry><type>ISBN</type></entry>
+ <entry>
+ International Standard Book Numbers to be displayed in the old
+ short display format
+ </entry>
+ </row>
+ <row>
+ <entry><type>ISMN</type></entry>
+ <entry>
+ International Standard Music Numbers to be displayed in the
+ old short display format
+ </entry>
+ </row>
+ <row>
+ <entry><type>ISSN</type></entry>
+ <entry>
+ International Standard Serial Numbers to be displayed in the
+ old short display format
+ </entry>
+ </row>
+ <row>
+ <entry><type>UPC</type></entry>
+ <entry>
+ Universal Product Codes
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Some notes:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>ISBN13, ISMN13, ISSN13 numbers are all EAN13 numbers.</para>
+ </listitem>
+ <listitem>
+ <para>EAN13 numbers aren't always ISBN13, ISMN13 or ISSN13 (some
+ are).</para>
+ </listitem>
+ <listitem>
+ <para>Some ISBN13 numbers can be displayed as ISBN.</para>
+ </listitem>
+ <listitem>
+ <para>Some ISMN13 numbers can be displayed as ISMN.</para>
+ </listitem>
+ <listitem>
+ <para>Some ISSN13 numbers can be displayed as ISSN.</para>
+ </listitem>
+ <listitem>
+ <para>UPC numbers are a subset of the EAN13 numbers (they are basically
+ EAN13 without the first <literal>0</literal> digit).</para>
+ </listitem>
+ <listitem>
+ <para>All UPC, ISBN, ISMN and ISSN numbers can be represented as EAN13
+ numbers.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ Internally, all these types use the same representation (a 64-bit
+ integer), and all are interchangeable. Multiple types are provided
+ to control display formatting and to permit tighter validity checking
+ of input that is supposed to denote one particular type of number.
+ </para>
+
+ <para>
+ The <type>ISBN</type>, <type>ISMN</type>, and <type>ISSN</type> types will display the
+ short version of the number (ISxN 10) whenever it's possible, and will show
+ ISxN 13 format for numbers that do not fit in the short version.
+ The <type>EAN13</type>, <type>ISBN13</type>, <type>ISMN13</type> and
+ <type>ISSN13</type> types will always display the long version of the ISxN
+ (EAN13).
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Casts</title>
+
+ <para>
+ The <filename>isn</filename> module provides the following pairs of type casts:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ ISBN13 &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISMN13 &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISSN13 &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISBN &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISMN &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISSN &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ UPC &lt;=&gt; EAN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISBN &lt;=&gt; ISBN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISMN &lt;=&gt; ISMN13
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ ISSN &lt;=&gt; ISSN13
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ When casting from <type>EAN13</type> to another type, there is a run-time
+ check that the value is within the domain of the other type, and an error
+ is thrown if not. The other casts are simply relabelings that will
+ always succeed.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Functions and Operators</title>
+
+ <para>
+ The <filename>isn</filename> module provides the standard comparison operators,
+ plus B-tree and hash indexing support for all these data types. In
+ addition there are several specialized functions; shown in <xref linkend="isn-functions"/>.
+ In this table,
+ <type>isn</type> means any one of the module's data types.
+ </para>
+
+ <table id="isn-functions">
+ <title><filename>isn</filename> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>isn_weak</primary></indexterm>
+ <function>isn_weak</function> ( <type>boolean</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Sets the weak input mode, and returns new setting.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>isn_weak</function> ()
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns the current status of the weak mode.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>make_valid</primary></indexterm>
+ <function>make_valid</function> ( <type>isn</type> )
+ <returnvalue>isn</returnvalue>
+ </para>
+ <para>
+ Validates an invalid number (clears the invalid flag).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>is_valid</primary></indexterm>
+ <function>is_valid</function> ( <type>isn</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Checks for the presence of the invalid flag.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <firstterm>Weak</firstterm> mode is used to be able to insert invalid data
+ into a table. Invalid means the check digit is wrong, not that there are
+ missing numbers.
+ </para>
+
+ <para>
+ Why would you want to use the weak mode? Well, it could be that
+ you have a huge collection of ISBN numbers, and that there are so many of
+ them that for weird reasons some have the wrong check digit (perhaps the
+ numbers were scanned from a printed list and the OCR got the numbers wrong,
+ perhaps the numbers were manually captured... who knows). Anyway, the point
+ is you might want to clean the mess up, but you still want to be able to
+ have all the numbers in your database and maybe use an external tool to
+ locate the invalid numbers in the database so you can verify the
+ information and validate it more easily; so for example you'd want to
+ select all the invalid numbers in the table.
+ </para>
+
+ <para>
+ When you insert invalid numbers in a table using the weak mode, the number
+ will be inserted with the corrected check digit, but it will be displayed
+ with an exclamation mark (<literal>!</literal>) at the end, for example
+ <literal>0-11-000322-5!</literal>. This invalid marker can be checked with
+ the <function>is_valid</function> function and cleared with the
+ <function>make_valid</function> function.
+ </para>
+
+ <para>
+ You can also force the insertion of invalid numbers even when not in the
+ weak mode, by appending the <literal>!</literal> character at the end of the
+ number.
+ </para>
+
+ <para>
+ Another special feature is that during input, you can write
+ <literal>?</literal> in place of the check digit, and the correct check digit
+ will be inserted automatically.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Examples</title>
+
+<programlisting>
+--Using the types directly:
+SELECT isbn('978-0-393-04002-9');
+SELECT isbn13('0901690546');
+SELECT issn('1436-4522');
+
+--Casting types:
+-- note that you can only cast from ean13 to another type when the
+-- number would be valid in the realm of the target type;
+-- thus, the following will NOT work: select isbn(ean13('0220356483481'));
+-- but these will:
+SELECT upc(ean13('0220356483481'));
+SELECT ean13(upc('220356483481'));
+
+--Create a table with a single column to hold ISBN numbers:
+CREATE TABLE test (id isbn);
+INSERT INTO test VALUES('9780393040029');
+
+--Automatically calculate check digits (observe the '?'):
+INSERT INTO test VALUES('220500896?');
+INSERT INTO test VALUES('978055215372?');
+
+SELECT issn('3251231?');
+SELECT ismn('979047213542?');
+
+--Using the weak mode:
+SELECT isn_weak(true);
+INSERT INTO test VALUES('978-0-11-000533-4');
+INSERT INTO test VALUES('9780141219307');
+INSERT INTO test VALUES('2-205-00876-X');
+SELECT isn_weak(false);
+
+SELECT id FROM test WHERE NOT is_valid(id);
+UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!';
+
+SELECT * FROM test;
+
+SELECT isbn13(id) FROM test;
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Bibliography</title>
+
+ <para>
+ The information to implement this module was collected from
+ several sites, including:
+ <itemizedlist>
+ <listitem><para><ulink url="https://www.isbn-international.org/"></ulink></para></listitem>
+ <listitem><para><ulink url="https://www.issn.org/"></ulink></para></listitem>
+ <listitem><para><ulink url="https://www.ismn-international.org/"></ulink></para></listitem>
+ <listitem><para><ulink url="https://www.wikipedia.org/"></ulink></para></listitem>
+ </itemizedlist>
+
+ The prefixes used for hyphenation were also compiled from:
+ <itemizedlist>
+ <listitem><para><ulink url="https://www.gs1.org/standards/id-keys"></ulink></para></listitem>
+ <listitem><para><ulink url="https://en.wikipedia.org/wiki/List_of_ISBN_identifier_groups"></ulink></para></listitem>
+ <listitem><para><ulink url="https://www.isbn-international.org/content/isbn-users-manual"></ulink></para></listitem>
+ <listitem><para><ulink url="https://en.wikipedia.org/wiki/International_Standard_Music_Number"></ulink></para></listitem>
+ <listitem><para><ulink url="https://www.ismn-international.org/ranges.html"></ulink></para></listitem>
+ </itemizedlist>
+
+ Care was taken during the creation of the algorithms and they
+ were meticulously verified against the suggested algorithms
+ in the official ISBN, ISMN, ISSN User Manuals.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+ <para>
+ Germ&aacute;n M&eacute;ndez Bravo (Kronuz), 2004&ndash;2006
+ </para>
+
+ <para>
+ This module was inspired by Garrett A. Wollman's
+ <filename>isbn_issn</filename> code.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/jit.sgml b/doc/src/sgml/jit.sgml
new file mode 100644
index 0000000..0c68389
--- /dev/null
+++ b/doc/src/sgml/jit.sgml
@@ -0,0 +1,285 @@
+<!-- doc/src/sgml/jit.sgml -->
+
+<chapter id="jit">
+ <title>Just-in-Time Compilation (<acronym>JIT</acronym>)</title>
+
+ <indexterm zone="jit">
+ <primary><acronym>JIT</acronym></primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>Just-In-Time compilation</primary>
+ <see><acronym>JIT</acronym></see>
+ </indexterm>
+
+ <para>
+ This chapter explains what just-in-time compilation is, and how it can be
+ configured in <productname>PostgreSQL</productname>.
+ </para>
+
+ <sect1 id="jit-reason">
+ <title>What Is <acronym>JIT</acronym> compilation?</title>
+
+ <para>
+ Just-in-Time (<acronym>JIT</acronym>) compilation is the process of turning
+ some form of interpreted program evaluation into a native program, and
+ doing so at run time.
+ For example, instead of using general-purpose code that can evaluate
+ arbitrary SQL expressions to evaluate a particular SQL predicate
+ like <literal>WHERE a.col = 3</literal>, it is possible to generate a
+ function that is specific to that expression and can be natively executed
+ by the CPU, yielding a speedup.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> has builtin support to perform
+ <acronym>JIT</acronym> compilation using <ulink
+ url="https://llvm.org/"><productname>LLVM</productname></ulink> when
+ <productname>PostgreSQL</productname> is built with
+ <link linkend="configure-with-llvm"><literal>--with-llvm</literal></link>.
+ </para>
+
+ <para>
+ See <filename>src/backend/jit/README</filename> for further details.
+ </para>
+
+ <sect2 id="jit-accelerated-operations">
+ <title><acronym>JIT</acronym> Accelerated Operations</title>
+ <para>
+ Currently <productname>PostgreSQL</productname>'s <acronym>JIT</acronym>
+ implementation has support for accelerating expression evaluation and
+ tuple deforming. Several other operations could be accelerated in the
+ future.
+ </para>
+ <para>
+ Expression evaluation is used to evaluate <literal>WHERE</literal>
+ clauses, target lists, aggregates and projections. It can be accelerated
+ by generating code specific to each case.
+ </para>
+ <para>
+ Tuple deforming is the process of transforming an on-disk tuple (see <xref
+ linkend="storage-tuple-layout"/>) into its in-memory representation.
+ It can be accelerated by creating a function specific to the table layout
+ and the number of columns to be extracted.
+ </para>
+ </sect2>
+
+ <sect2 id="jit-inlining">
+ <title>Inlining</title>
+ <para>
+ <productname>PostgreSQL</productname> is very extensible and allows new
+ data types, functions, operators and other database objects to be defined;
+ see <xref linkend="extend"/>. In fact the built-in objects are implemented
+ using nearly the same mechanisms. This extensibility implies some
+ overhead, for example due to function calls (see <xref linkend="xfunc"/>).
+ To reduce that overhead, <acronym>JIT</acronym> compilation can inline the
+ bodies of small functions into the expressions using them. That allows a
+ significant percentage of the overhead to be optimized away.
+ </para>
+ </sect2>
+
+ <sect2 id="jit-optimization">
+ <title>Optimization</title>
+ <para>
+ <productname>LLVM</productname> has support for optimizing generated
+ code. Some of the optimizations are cheap enough to be performed whenever
+ <acronym>JIT</acronym> is used, while others are only beneficial for
+ longer-running queries.
+ See <ulink url="https://llvm.org/docs/Passes.html#transform-passes"/> for
+ more details about optimizations.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="jit-decision">
+ <title>When to <acronym>JIT</acronym>?</title>
+
+ <para>
+ <acronym>JIT</acronym> compilation is beneficial primarily for long-running
+ CPU-bound queries. Frequently these will be analytical queries. For short
+ queries the added overhead of performing <acronym>JIT</acronym> compilation
+ will often be higher than the time it can save.
+ </para>
+
+ <para>
+ To determine whether <acronym>JIT</acronym> compilation should be used,
+ the total estimated cost of a query (see
+ <xref linkend="planner-stats-details"/> and
+ <xref linkend="runtime-config-query-constants"/>) is used.
+ The estimated cost of the query will be compared with the setting of <xref
+ linkend="guc-jit-above-cost"/>. If the cost is higher,
+ <acronym>JIT</acronym> compilation will be performed.
+ Two further decisions are then needed.
+ Firstly, if the estimated cost is more
+ than the setting of <xref linkend="guc-jit-inline-above-cost"/>, short
+ functions and operators used in the query will be inlined.
+ Secondly, if the estimated cost is more than the setting of <xref
+ linkend="guc-jit-optimize-above-cost"/>, expensive optimizations are
+ applied to improve the generated code.
+ Each of these options increases the <acronym>JIT</acronym> compilation
+ overhead, but can reduce query execution time considerably.
+ </para>
+
+ <para>
+ These cost-based decisions will be made at plan time, not execution
+ time. This means that when prepared statements are in use, and a generic
+ plan is used (see <xref linkend="sql-prepare"/>), the values of the
+ configuration parameters in effect at prepare time control the decisions,
+ not the settings at execution time.
+ </para>
+
+ <note>
+ <para>
+ If <xref linkend="guc-jit"/> is set to <literal>off</literal>, or if no
+ <acronym>JIT</acronym> implementation is available (for example because
+ the server was compiled without <literal>--with-llvm</literal>),
+ <acronym>JIT</acronym> will not be performed, even if it would be
+ beneficial based on the above criteria. Setting <xref linkend="guc-jit"/>
+ to <literal>off</literal> has effects at both plan and execution time.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="sql-explain"/> can be used to see whether
+ <acronym>JIT</acronym> is used or not. As an example, here is a query that
+ is not using <acronym>JIT</acronym>:
+<screen>
+=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------------------------------------
+ Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1)
+ -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1)
+ Planning Time: 0.116 ms
+ Execution Time: 0.365 ms
+(4 rows)
+</screen>
+ Given the cost of the plan, it is entirely reasonable that no
+ <acronym>JIT</acronym> was used; the cost of <acronym>JIT</acronym> would
+ have been bigger than the potential savings. Adjusting the cost limits
+ will lead to <acronym>JIT</acronym> use:
+<screen>
+=# SET jit_above_cost = 10;
+SET
+=# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------------------------------------
+ Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1)
+ -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1)
+ Planning Time: 0.133 ms
+ JIT:
+ Functions: 3
+ Options: Inlining false, Optimization false, Expressions true, Deforming true
+ Timing: Generation 1.259 ms, Inlining 0.000 ms, Optimization 0.797 ms, Emission 5.048 ms, Total 7.104 ms
+ Execution Time: 7.416 ms
+</screen>
+ As visible here, <acronym>JIT</acronym> was used, but inlining and
+ expensive optimization were not. If <xref
+ linkend="guc-jit-inline-above-cost"/> or <xref
+ linkend="guc-jit-optimize-above-cost"/> were also lowered,
+ that would change.
+ </para>
+ </sect1>
+
+ <sect1 id="jit-configuration" xreflabel="JIT Configuration">
+ <title>Configuration</title>
+
+ <para>
+ The configuration variable
+ <xref linkend="guc-jit"/> determines whether <acronym>JIT</acronym>
+ compilation is enabled or disabled.
+ If it is enabled, the configuration variables
+ <xref linkend="guc-jit-above-cost"/>, <xref
+ linkend="guc-jit-inline-above-cost"/>, and <xref
+ linkend="guc-jit-optimize-above-cost"/> determine
+ whether <acronym>JIT</acronym> compilation is performed for a query,
+ and how much effort is spent doing so.
+ </para>
+
+ <para>
+ <xref linkend="guc-jit-provider"/> determines which <acronym>JIT</acronym>
+ implementation is used. It is rarely required to be changed. See <xref
+ linkend="jit-pluggable"/>.
+ </para>
+
+ <para>
+ For development and debugging purposes a few additional configuration
+ parameters exist, as described in
+ <xref linkend="runtime-config-developer"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="jit-extensibility">
+ <title>Extensibility</title>
+
+ <sect2 id="jit-extensibility-bitcode">
+ <title>Inlining Support for Extensions</title>
+ <para>
+ <productname>PostgreSQL</productname>'s <acronym>JIT</acronym>
+ implementation can inline the bodies of functions
+ of types <literal>C</literal> and <literal>internal</literal>, as well as
+ operators based on such functions. To do so for functions in extensions,
+ the definitions of those functions need to be made available.
+ When using <link linkend="extend-pgxs">PGXS</link> to build an extension
+ against a server that has been compiled with LLVM JIT support, the
+ relevant files will be built and installed automatically.
+ </para>
+
+ <para>
+ The relevant files have to be installed into
+ <filename>$pkglibdir/bitcode/$extension/</filename> and a summary of them
+ into <filename>$pkglibdir/bitcode/$extension.index.bc</filename>, where
+ <literal>$pkglibdir</literal> is the directory returned by
+ <literal>pg_config --pkglibdir</literal> and <literal>$extension</literal>
+ is the base name of the extension's shared library.
+
+ <note>
+ <para>
+ For functions built into <productname>PostgreSQL</productname> itself,
+ the bitcode is installed into
+ <literal>$pkglibdir/bitcode/postgres</literal>.
+ </para>
+ </note>
+ </para>
+ </sect2>
+
+ <sect2 id="jit-pluggable">
+ <title>Pluggable <acronym>JIT</acronym> Providers</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a <acronym>JIT</acronym>
+ implementation based on <productname>LLVM</productname>. The interface to
+ the <acronym>JIT</acronym> provider is pluggable and the provider can be
+ changed without recompiling (although currently, the build process only
+ provides inlining support data for <productname>LLVM</productname>).
+ The active provider is chosen via the setting
+ <xref linkend="guc-jit-provider"/>.
+ </para>
+
+ <sect3>
+ <title><acronym>JIT</acronym> Provider Interface</title>
+ <para>
+ A <acronym>JIT</acronym> provider is loaded by dynamically loading the
+ named shared library. The normal library search path is used to locate
+ the library. To provide the required <acronym>JIT</acronym> provider
+ callbacks and to indicate that the library is actually a
+ <acronym>JIT</acronym> provider, it needs to provide a C function named
+ <function>_PG_jit_provider_init</function>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions:
+<programlisting>
+struct JitProviderCallbacks
+{
+ JitProviderResetAfterErrorCB reset_after_error;
+ JitProviderReleaseContextCB release_context;
+ JitProviderCompileExprCB compile_expr;
+};
+
+extern void _PG_jit_provider_init(JitProviderCallbacks *cb);
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml
new file mode 100644
index 0000000..4182d69
--- /dev/null
+++ b/doc/src/sgml/json.sgml
@@ -0,0 +1,1013 @@
+<!-- doc/src/sgml/json.sgml -->
+
+<sect1 id="datatype-json">
+ <title><acronym>JSON</acronym> Types</title>
+
+ <indexterm zone="datatype-json">
+ <primary>JSON</primary>
+ </indexterm>
+
+ <indexterm zone="datatype-json">
+ <primary>JSONB</primary>
+ </indexterm>
+
+ <para>
+ JSON data types are for storing JSON (JavaScript Object Notation)
+ data, as specified in <ulink url="https://tools.ietf.org/html/rfc7159">RFC
+ 7159</ulink>. Such data can also be stored as <type>text</type>, but
+ the JSON data types have the advantage of enforcing that each
+ stored value is valid according to the JSON rules. There are also
+ assorted JSON-specific functions and operators available for data stored
+ in these data types; see <xref linkend="functions-json"/>.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> offers two types for storing JSON
+ data: <type>json</type> and <type>jsonb</type>. To implement efficient query
+ mechanisms for these data types, <productname>PostgreSQL</productname>
+ also provides the <type>jsonpath</type> data type described in
+ <xref linkend="datatype-jsonpath"/>.
+ </para>
+
+ <para>
+ The <type>json</type> and <type>jsonb</type> data types
+ accept <emphasis>almost</emphasis> identical sets of values as
+ input. The major practical difference is one of efficiency. The
+ <type>json</type> data type stores an exact copy of the input text,
+ which processing functions must reparse on each execution; while
+ <type>jsonb</type> data is stored in a decomposed binary format that
+ makes it slightly slower to input due to added conversion
+ overhead, but significantly faster to process, since no reparsing
+ is needed. <type>jsonb</type> also supports indexing, which can be a
+ significant advantage.
+ </para>
+
+ <para>
+ Because the <type>json</type> type stores an exact copy of the input text, it
+ will preserve semantically-insignificant white space between tokens, as
+ well as the order of keys within JSON objects. Also, if a JSON object
+ within the value contains the same key more than once, all the key/value
+ pairs are kept. (The processing functions consider the last value as the
+ operative one.) By contrast, <type>jsonb</type> does not preserve white
+ space, does not preserve the order of object keys, and does not keep
+ duplicate object keys. If duplicate keys are specified in the input,
+ only the last value is kept.
+ </para>
+
+ <para>
+ In general, most applications should prefer to store JSON data as
+ <type>jsonb</type>, unless there are quite specialized needs, such as
+ legacy assumptions about ordering of object keys.
+ </para>
+
+ <para>
+ <acronym>RFC</acronym> 7159 specifies that JSON strings should be encoded in UTF8.
+ It is therefore not possible for the JSON
+ types to conform rigidly to the JSON specification unless the database
+ encoding is UTF8. Attempts to directly include characters that
+ cannot be represented in the database encoding will fail; conversely,
+ characters that can be represented in the database encoding but not
+ in UTF8 will be allowed.
+ </para>
+
+ <para>
+ <acronym>RFC</acronym> 7159 permits JSON strings to contain Unicode escape sequences
+ denoted by <literal>\u<replaceable>XXXX</replaceable></literal>. In the input
+ function for the <type>json</type> type, Unicode escapes are allowed
+ regardless of the database encoding, and are checked only for syntactic
+ correctness (that is, that four hex digits follow <literal>\u</literal>).
+ However, the input function for <type>jsonb</type> is stricter: it disallows
+ Unicode escapes for characters that cannot be represented in the database
+ encoding. The <type>jsonb</type> type also
+ rejects <literal>\u0000</literal> (because that cannot be represented in
+ <productname>PostgreSQL</productname>'s <type>text</type> type), and it insists
+ that any use of Unicode surrogate pairs to designate characters outside
+ the Unicode Basic Multilingual Plane be correct. Valid Unicode escapes
+ are converted to the equivalent single character for storage;
+ this includes folding surrogate pairs into a single character.
+ </para>
+
+ <note>
+ <para>
+ Many of the JSON processing functions described
+ in <xref linkend="functions-json"/> will convert Unicode escapes to
+ regular characters, and will therefore throw the same types of errors
+ just described even if their input is of type <type>json</type>
+ not <type>jsonb</type>. The fact that the <type>json</type> input function does
+ not make these checks may be considered a historical artifact, although
+ it does allow for simple storage (without processing) of JSON Unicode
+ escapes in a database encoding that does not support the represented
+ characters.
+ </para>
+ </note>
+
+ <para>
+ When converting textual JSON input into <type>jsonb</type>, the primitive
+ types described by <acronym>RFC</acronym> 7159 are effectively mapped onto
+ native <productname>PostgreSQL</productname> types, as shown
+ in <xref linkend="json-type-mapping-table"/>.
+ Therefore, there are some minor additional constraints on what
+ constitutes valid <type>jsonb</type> data that do not apply to
+ the <type>json</type> type, nor to JSON in the abstract, corresponding
+ to limits on what can be represented by the underlying data type.
+ Notably, <type>jsonb</type> will reject numbers that are outside the
+ range of the <productname>PostgreSQL</productname> <type>numeric</type> data
+ type, while <type>json</type> will not. Such implementation-defined
+ restrictions are permitted by <acronym>RFC</acronym> 7159. However, in
+ practice such problems are far more likely to occur in other
+ implementations, as it is common to represent JSON's <type>number</type>
+ primitive type as IEEE 754 double precision floating point
+ (which <acronym>RFC</acronym> 7159 explicitly anticipates and allows for).
+ When using JSON as an interchange format with such systems, the danger
+ of losing numeric precision compared to data originally stored
+ by <productname>PostgreSQL</productname> should be considered.
+ </para>
+
+ <para>
+ Conversely, as noted in the table there are some minor restrictions on
+ the input format of JSON primitive types that do not apply to
+ the corresponding <productname>PostgreSQL</productname> types.
+ </para>
+
+ <table id="json-type-mapping-table">
+ <title>JSON Primitive Types and Corresponding <productname>PostgreSQL</productname> Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>JSON primitive type</entry>
+ <entry><productname>PostgreSQL</productname> type</entry>
+ <entry>Notes</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>string</type></entry>
+ <entry><type>text</type></entry>
+ <entry><literal>\u0000</literal> is disallowed, as are Unicode escapes
+ representing characters not available in the database encoding</entry>
+ </row>
+ <row>
+ <entry><type>number</type></entry>
+ <entry><type>numeric</type></entry>
+ <entry><literal>NaN</literal> and <literal>infinity</literal> values are disallowed</entry>
+ </row>
+ <row>
+ <entry><type>boolean</type></entry>
+ <entry><type>boolean</type></entry>
+ <entry>Only lowercase <literal>true</literal> and <literal>false</literal> spellings are accepted</entry>
+ </row>
+ <row>
+ <entry><type>null</type></entry>
+ <entry>(none)</entry>
+ <entry>SQL <literal>NULL</literal> is a different concept</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="json-keys-elements">
+ <title>JSON Input and Output Syntax</title>
+ <para>
+ The input/output syntax for the JSON data types is as specified in
+ <acronym>RFC</acronym> 7159.
+ </para>
+ <para>
+ The following are all valid <type>json</type> (or <type>jsonb</type>) expressions:
+<programlisting>
+-- Simple scalar/primitive value
+-- Primitive values can be numbers, quoted strings, true, false, or null
+SELECT '5'::json;
+
+-- Array of zero or more elements (elements need not be of same type)
+SELECT '[1, 2, "foo", null]'::json;
+
+-- Object containing pairs of keys and values
+-- Note that object keys must always be quoted strings
+SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;
+
+-- Arrays and objects can be nested arbitrarily
+SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
+</programlisting>
+ </para>
+
+ <para>
+ As previously stated, when a JSON value is input and then printed without
+ any additional processing, <type>json</type> outputs the same text that was
+ input, while <type>jsonb</type> does not preserve semantically-insignificant
+ details such as whitespace. For example, note the differences here:
+<programlisting>
+SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::json;
+ json
+-------------------------------------------------
+ {"bar": "baz", "balance": 7.77, "active":false}
+(1 row)
+
+SELECT '{"bar": "baz", "balance": 7.77, "active":false}'::jsonb;
+ jsonb
+--------------------------------------------------
+ {"bar": "baz", "active": false, "balance": 7.77}
+(1 row)
+</programlisting>
+ One semantically-insignificant detail worth noting is that
+ in <type>jsonb</type>, numbers will be printed according to the behavior of the
+ underlying <type>numeric</type> type. In practice this means that numbers
+ entered with <literal>E</literal> notation will be printed without it, for
+ example:
+<programlisting>
+SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
+ json | jsonb
+-----------------------+-------------------------
+ {"reading": 1.230e-5} | {"reading": 0.00001230}
+(1 row)
+</programlisting>
+ However, <type>jsonb</type> will preserve trailing fractional zeroes, as seen
+ in this example, even though those are semantically insignificant for
+ purposes such as equality checks.
+ </para>
+
+ <para>
+ For the list of built-in functions and operators available for
+ constructing and processing JSON values, see <xref linkend="functions-json"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="json-doc-design">
+ <title>Designing JSON Documents</title>
+ <para>
+ Representing data as JSON can be considerably more flexible than
+ the traditional relational data model, which is compelling in
+ environments where requirements are fluid. It is quite possible
+ for both approaches to co-exist and complement each other within
+ the same application. However, even for applications where maximal
+ flexibility is desired, it is still recommended that JSON documents
+ have a somewhat fixed structure. The structure is typically
+ unenforced (though enforcing some business rules declaratively is
+ possible), but having a predictable structure makes it easier to write
+ queries that usefully summarize a set of <quote>documents</quote> (datums)
+ in a table.
+ </para>
+ <para>
+ JSON data is subject to the same concurrency-control
+ considerations as any other data type when stored in a table.
+ Although storing large documents is practicable, keep in mind that
+ any update acquires a row-level lock on the whole row.
+ Consider limiting JSON documents to a
+ manageable size in order to decrease lock contention among updating
+ transactions. Ideally, JSON documents should each
+ represent an atomic datum that business rules dictate cannot
+ reasonably be further subdivided into smaller datums that
+ could be modified independently.
+ </para>
+ </sect2>
+
+ <sect2 id="json-containment">
+ <title><type>jsonb</type> Containment and Existence</title>
+ <indexterm>
+ <primary>jsonb</primary>
+ <secondary>containment</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>jsonb</primary>
+ <secondary>existence</secondary>
+ </indexterm>
+ <para>
+ Testing <firstterm>containment</firstterm> is an important capability of
+ <type>jsonb</type>. There is no parallel set of facilities for the
+ <type>json</type> type. Containment tests whether
+ one <type>jsonb</type> document has contained within it another one.
+ These examples return true except as noted:
+ </para>
+<programlisting>
+-- Simple scalar/primitive values contain only the identical value:
+SELECT '"foo"'::jsonb @&gt; '"foo"'::jsonb;
+
+-- The array on the right side is contained within the one on the left:
+SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 3]'::jsonb;
+
+-- Order of array elements is not significant, so this is also true:
+SELECT '[1, 2, 3]'::jsonb @&gt; '[3, 1]'::jsonb;
+
+-- Duplicate array elements don't matter either:
+SELECT '[1, 2, 3]'::jsonb @&gt; '[1, 2, 2]'::jsonb;
+
+-- The object with a single pair on the right side is contained
+-- within the object on the left side:
+SELECT '{"product": "PostgreSQL", "version": 9.4, "jsonb": true}'::jsonb @&gt; '{"version": 9.4}'::jsonb;
+
+-- The array on the right side is <emphasis>not</emphasis> considered contained within the
+-- array on the left, even though a similar array is nested within it:
+SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[1, 3]'::jsonb; -- yields false
+
+-- But with a layer of nesting, it is contained:
+SELECT '[1, 2, [1, 3]]'::jsonb @&gt; '[[1, 3]]'::jsonb;
+
+-- Similarly, containment is not reported here:
+SELECT '{"foo": {"bar": "baz"}}'::jsonb @&gt; '{"bar": "baz"}'::jsonb; -- yields false
+
+-- A top-level key and an empty object is contained:
+SELECT '{"foo": {"bar": "baz"}}'::jsonb @&gt; '{"foo": {}}'::jsonb;
+</programlisting>
+
+ <para>
+ The general principle is that the contained object must match the
+ containing object as to structure and data contents, possibly after
+ discarding some non-matching array elements or object key/value pairs
+ from the containing object.
+ But remember that the order of array elements is not significant when
+ doing a containment match, and duplicate array elements are effectively
+ considered only once.
+ </para>
+
+ <para>
+ As a special exception to the general principle that the structures
+ must match, an array may contain a primitive value:
+ </para>
+<programlisting>
+-- This array contains the primitive string value:
+SELECT '["foo", "bar"]'::jsonb @&gt; '"bar"'::jsonb;
+
+-- This exception is not reciprocal -- non-containment is reported here:
+SELECT '"bar"'::jsonb @&gt; '["bar"]'::jsonb; -- yields false
+</programlisting>
+
+ <para>
+ <type>jsonb</type> also has an <firstterm>existence</firstterm> operator, which is
+ a variation on the theme of containment: it tests whether a string
+ (given as a <type>text</type> value) appears as an object key or array
+ element at the top level of the <type>jsonb</type> value.
+ These examples return true except as noted:
+ </para>
+<programlisting>
+-- String exists as array element:
+SELECT '["foo", "bar", "baz"]'::jsonb ? 'bar';
+
+-- String exists as object key:
+SELECT '{"foo": "bar"}'::jsonb ? 'foo';
+
+-- Object values are not considered:
+SELECT '{"foo": "bar"}'::jsonb ? 'bar'; -- yields false
+
+-- As with containment, existence must match at the top level:
+SELECT '{"foo": {"bar": "baz"}}'::jsonb ? 'bar'; -- yields false
+
+-- A string is considered to exist if it matches a primitive JSON string:
+SELECT '"foo"'::jsonb ? 'foo';
+</programlisting>
+
+ <para>
+ JSON objects are better suited than arrays for testing containment or
+ existence when there are many keys or elements involved, because
+ unlike arrays they are internally optimized for searching, and do not
+ need to be searched linearly.
+ </para>
+
+ <tip>
+ <para>
+ Because JSON containment is nested, an appropriate query can skip
+ explicit selection of sub-objects. As an example, suppose that we have
+ a <structfield>doc</structfield> column containing objects at the top level, with
+ most objects containing <literal>tags</literal> fields that contain arrays of
+ sub-objects. This query finds entries in which sub-objects containing
+ both <literal>"term":"paris"</literal> and <literal>"term":"food"</literal> appear,
+ while ignoring any such keys outside the <literal>tags</literal> array:
+<programlisting>
+SELECT doc-&gt;'site_name' FROM websites
+ WHERE doc @&gt; '{"tags":[{"term":"paris"}, {"term":"food"}]}';
+</programlisting>
+ One could accomplish the same thing with, say,
+<programlisting>
+SELECT doc-&gt;'site_name' FROM websites
+ WHERE doc-&gt;'tags' @&gt; '[{"term":"paris"}, {"term":"food"}]';
+</programlisting>
+ but that approach is less flexible, and often less efficient as well.
+ </para>
+
+ <para>
+ On the other hand, the JSON existence operator is not nested: it will
+ only look for the specified key or array element at top level of the
+ JSON value.
+ </para>
+ </tip>
+
+ <para>
+ The various containment and existence operators, along with all other
+ JSON operators and functions are documented
+ in <xref linkend="functions-json"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="json-indexing">
+ <title><type>jsonb</type> Indexing</title>
+ <indexterm>
+ <primary>jsonb</primary>
+ <secondary>indexes on</secondary>
+ </indexterm>
+
+ <para>
+ GIN indexes can be used to efficiently search for
+ keys or key/value pairs occurring within a large number of
+ <type>jsonb</type> documents (datums).
+ Two GIN <quote>operator classes</quote> are provided, offering different
+ performance and flexibility trade-offs.
+ </para>
+ <para>
+ The default GIN operator class for <type>jsonb</type> supports queries with
+ the key-exists operators <literal>?</literal>, <literal>?|</literal>
+ and <literal>?&amp;</literal>, the containment operator
+ <literal>@&gt;</literal>, and the <type>jsonpath</type> match
+ operators <literal>@?</literal> and <literal>@@</literal>.
+ (For details of the semantics that these operators
+ implement, see <xref linkend="functions-jsonb-op-table"/>.)
+ An example of creating an index with this operator class is:
+<programlisting>
+CREATE INDEX idxgin ON api USING GIN (jdoc);
+</programlisting>
+ The non-default GIN operator class <literal>jsonb_path_ops</literal>
+ does not support the key-exists operators, but it does support
+ <literal>@&gt;</literal>, <literal>@?</literal> and <literal>@@</literal>.
+ An example of creating an index with this operator class is:
+<programlisting>
+CREATE INDEX idxginp ON api USING GIN (jdoc jsonb_path_ops);
+</programlisting>
+ </para>
+
+ <para>
+ Consider the example of a table that stores JSON documents
+ retrieved from a third-party web service, with a documented schema
+ definition. A typical document is:
+<programlisting>
+{
+ "guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
+ "name": "Angela Barton",
+ "is_active": true,
+ "company": "Magnafone",
+ "address": "178 Howard Place, Gulf, Washington, 702",
+ "registered": "2009-11-07T08:53:22 +08:00",
+ "latitude": 19.793713,
+ "longitude": 86.513373,
+ "tags": [
+ "enim",
+ "aliquip",
+ "qui"
+ ]
+}
+</programlisting>
+ We store these documents in a table named <structname>api</structname>,
+ in a <type>jsonb</type> column named <structfield>jdoc</structfield>.
+ If a GIN index is created on this column,
+ queries like the following can make use of the index:
+<programlisting>
+-- Find documents in which the key "company" has value "Magnafone"
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"company": "Magnafone"}';
+</programlisting>
+ However, the index could not be used for queries like the
+ following, because though the operator <literal>?</literal> is indexable,
+ it is not applied directly to the indexed column <structfield>jdoc</structfield>:
+<programlisting>
+-- Find documents in which the key "tags" contains key or array element "qui"
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc -&gt; 'tags' ? 'qui';
+</programlisting>
+ Still, with appropriate use of expression indexes, the above
+ query can use an index. If querying for particular items within
+ the <literal>"tags"</literal> key is common, defining an index like this
+ may be worthwhile:
+<programlisting>
+CREATE INDEX idxgintags ON api USING GIN ((jdoc -&gt; 'tags'));
+</programlisting>
+ Now, the <literal>WHERE</literal> clause <literal>jdoc -&gt; 'tags' ? 'qui'</literal>
+ will be recognized as an application of the indexable
+ operator <literal>?</literal> to the indexed
+ expression <literal>jdoc -&gt; 'tags'</literal>.
+ (More information on expression indexes can be found in <xref
+ linkend="indexes-expressional"/>.)
+ </para>
+
+ <para>
+ Another approach to querying is to exploit containment, for example:
+<programlisting>
+-- Find documents in which the key "tags" contains array element "qui"
+SELECT jdoc-&gt;'guid', jdoc-&gt;'name' FROM api WHERE jdoc @&gt; '{"tags": ["qui"]}';
+</programlisting>
+ A simple GIN index on the <structfield>jdoc</structfield> column can support this
+ query. But note that such an index will store copies of every key and
+ value in the <structfield>jdoc</structfield> column, whereas the expression index
+ of the previous example stores only data found under
+ the <literal>tags</literal> key. While the simple-index approach is far more
+ flexible (since it supports queries about any key), targeted expression
+ indexes are likely to be smaller and faster to search than a simple
+ index.
+ </para>
+
+ <para>
+ GIN indexes also support the <literal>@?</literal>
+ and <literal>@@</literal> operators, which
+ perform <type>jsonpath</type> matching. Examples are
+<programlisting>
+SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @? '$.tags[*] ? (@ == "qui")';
+</programlisting>
+<programlisting>
+SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @@ '$.tags[*] == "qui"';
+</programlisting>
+ For these operators, a GIN index extracts clauses of the form
+ <literal><replaceable>accessors_chain</replaceable>
+ = <replaceable>constant</replaceable></literal> out of
+ the <type>jsonpath</type> pattern, and does the index search based on
+ the keys and values mentioned in these clauses. The accessors chain
+ may include <literal>.<replaceable>key</replaceable></literal>,
+ <literal>[*]</literal>,
+ and <literal>[<replaceable>index</replaceable>]</literal> accessors.
+ The <literal>jsonb_ops</literal> operator class also
+ supports <literal>.*</literal> and <literal>.**</literal> accessors,
+ but the <literal>jsonb_path_ops</literal> operator class does not.
+ </para>
+
+ <para>
+ Although the <literal>jsonb_path_ops</literal> operator class supports
+ only queries with the <literal>@&gt;</literal>, <literal>@?</literal>
+ and <literal>@@</literal> operators, it has notable
+ performance advantages over the default operator
+ class <literal>jsonb_ops</literal>. A <literal>jsonb_path_ops</literal>
+ index is usually much smaller than a <literal>jsonb_ops</literal>
+ index over the same data, and the specificity of searches is better,
+ particularly when queries contain keys that appear frequently in the
+ data. Therefore search operations typically perform better
+ than with the default operator class.
+ </para>
+
+ <para>
+ The technical difference between a <literal>jsonb_ops</literal>
+ and a <literal>jsonb_path_ops</literal> GIN index is that the former
+ creates independent index items for each key and value in the data,
+ while the latter creates index items only for each value in the
+ data.
+ <footnote>
+ <para>
+ For this purpose, the term <quote>value</quote> includes array elements,
+ though JSON terminology sometimes considers array elements distinct
+ from values within objects.
+ </para>
+ </footnote>
+ Basically, each <literal>jsonb_path_ops</literal> index item is
+ a hash of the value and the key(s) leading to it; for example to index
+ <literal>{"foo": {"bar": "baz"}}</literal>, a single index item would
+ be created incorporating all three of <literal>foo</literal>, <literal>bar</literal>,
+ and <literal>baz</literal> into the hash value. Thus a containment query
+ looking for this structure would result in an extremely specific index
+ search; but there is no way at all to find out whether <literal>foo</literal>
+ appears as a key. On the other hand, a <literal>jsonb_ops</literal>
+ index would create three index items representing <literal>foo</literal>,
+ <literal>bar</literal>, and <literal>baz</literal> separately; then to do the
+ containment query, it would look for rows containing all three of
+ these items. While GIN indexes can perform such an AND search fairly
+ efficiently, it will still be less specific and slower than the
+ equivalent <literal>jsonb_path_ops</literal> search, especially if
+ there are a very large number of rows containing any single one of the
+ three index items.
+ </para>
+
+ <para>
+ A disadvantage of the <literal>jsonb_path_ops</literal> approach is
+ that it produces no index entries for JSON structures not containing
+ any values, such as <literal>{"a": {}}</literal>. If a search for
+ documents containing such a structure is requested, it will require a
+ full-index scan, which is quite slow. <literal>jsonb_path_ops</literal> is
+ therefore ill-suited for applications that often perform such searches.
+ </para>
+
+ <para>
+ <type>jsonb</type> also supports <literal>btree</literal> and <literal>hash</literal>
+ indexes. These are usually useful only if it's important to check
+ equality of complete JSON documents.
+ The <literal>btree</literal> ordering for <type>jsonb</type> datums is seldom
+ of great interest, but for completeness it is:
+<synopsis>
+<replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
+
+<replaceable>Object with n pairs</replaceable> > <replaceable>object with n - 1 pairs</replaceable>
+
+<replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
+</synopsis>
+ Objects with equal numbers of pairs are compared in the order:
+<synopsis>
+<replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
+</synopsis>
+ Note that object keys are compared in their storage order;
+ in particular, since shorter keys are stored before longer keys, this
+ can lead to results that might be unintuitive, such as:
+<programlisting>
+{ "aa": 1, "c": 1} > {"b": 1, "d": 1}
+</programlisting>
+ Similarly, arrays with equal numbers of elements are compared in the
+ order:
+<synopsis>
+<replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
+</synopsis>
+ Primitive JSON values are compared using the same
+ comparison rules as for the underlying
+ <productname>PostgreSQL</productname> data type. Strings are
+ compared using the default database collation.
+ </para>
+ </sect2>
+
+ <sect2 id="jsonb-subscripting">
+ <title><type>jsonb</type> Subscripting</title>
+ <para>
+ The <type>jsonb</type> data type supports array-style subscripting expressions
+ to extract and modify elements. Nested values can be indicated by chaining
+ subscripting expressions, following the same rules as the <literal>path</literal>
+ argument in the <literal>jsonb_set</literal> function. If a <type>jsonb</type>
+ value is an array, numeric subscripts start at zero, and negative integers count
+ backwards from the last element of the array. Slice expressions are not supported.
+ The result of a subscripting expression is always of the jsonb data type.
+ </para>
+
+ <para>
+ <command>UPDATE</command> statements may use subscripting in the
+ <literal>SET</literal> clause to modify <type>jsonb</type> values. Subscript
+ paths must be traversable for all affected values insofar as they exist. For
+ instance, the path <literal>val['a']['b']['c']</literal> can be traversed all
+ the way to <literal>c</literal> if every <literal>val</literal>,
+ <literal>val['a']</literal>, and <literal>val['a']['b']</literal> is an
+ object. If any <literal>val['a']</literal> or <literal>val['a']['b']</literal>
+ is not defined, it will be created as an empty object and filled as
+ necessary. However, if any <literal>val</literal> itself or one of the
+ intermediary values is defined as a non-object such as a string, number, or
+ <literal>jsonb</literal> <literal>null</literal>, traversal cannot proceed so
+ an error is raised and the transaction aborted.
+ </para>
+
+ <para>
+ An example of subscripting syntax:
+
+<programlisting>
+
+-- Extract object value by key
+SELECT ('{"a": 1}'::jsonb)['a'];
+
+-- Extract nested object value by key path
+SELECT ('{"a": {"b": {"c": 1}}}'::jsonb)['a']['b']['c'];
+
+-- Extract array element by index
+SELECT ('[1, "2", null]'::jsonb)[1];
+
+-- Update object value by key. Note the quotes around '1': the assigned
+-- value must be of the jsonb type as well
+UPDATE table_name SET jsonb_field['key'] = '1';
+
+-- This will raise an error if any record's jsonb_field['a']['b'] is something
+-- other than an object. For example, the value {"a": 1} has a numeric value
+-- of the key 'a'.
+UPDATE table_name SET jsonb_field['a']['b']['c'] = '1';
+
+-- Filter records using a WHERE clause with subscripting. Since the result of
+-- subscripting is jsonb, the value we compare it against must also be jsonb.
+-- The double quotes make "value" also a valid jsonb string.
+SELECT * FROM table_name WHERE jsonb_field['key'] = '"value"';
+</programlisting>
+
+ <type>jsonb</type> assignment via subscripting handles a few edge cases
+ differently from <literal>jsonb_set</literal>. When a source <type>jsonb</type>
+ value is <literal>NULL</literal>, assignment via subscripting will proceed
+ as if it was an empty JSON value of the type (object or array) implied by the
+ subscript key:
+
+<programlisting>
+-- Where jsonb_field was NULL, it is now {"a": 1}
+UPDATE table_name SET jsonb_field['a'] = '1';
+
+-- Where jsonb_field was NULL, it is now [1]
+UPDATE table_name SET jsonb_field[0] = '1';
+</programlisting>
+
+ If an index is specified for an array containing too few elements,
+ <literal>NULL</literal> elements will be appended until the index is reachable
+ and the value can be set.
+
+<programlisting>
+-- Where jsonb_field was [], it is now [null, null, 2];
+-- where jsonb_field was [0], it is now [0, null, 2]
+UPDATE table_name SET jsonb_field[2] = '2';
+</programlisting>
+
+ A <type>jsonb</type> value will accept assignments to nonexistent subscript
+ paths as long as the last existing element to be traversed is an object or
+ array, as implied by the corresponding subscript (the element indicated by
+ the last subscript in the path is not traversed and may be anything). Nested
+ array and object structures will be created, and in the former case
+ <literal>null</literal>-padded, as specified by the subscript path until the
+ assigned value can be placed.
+
+<programlisting>
+-- Where jsonb_field was {}, it is now {"a": [{"b": 1}]}
+UPDATE table_name SET jsonb_field['a'][0]['b'] = '1';
+
+-- Where jsonb_field was [], it is now [null, {"a": 1}]
+UPDATE table_name SET jsonb_field[1]['a'] = '1';
+</programlisting>
+
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Transforms</title>
+
+ <para>
+ Additional extensions are available that implement transforms for the
+ <type>jsonb</type> type for different procedural languages.
+ </para>
+
+ <para>
+ The extensions for PL/Perl are called <literal>jsonb_plperl</literal> and
+ <literal>jsonb_plperlu</literal>. If you use them, <type>jsonb</type>
+ values are mapped to Perl arrays, hashes, and scalars, as appropriate.
+ </para>
+
+ <para>
+ The extension for PL/Python is called <literal>jsonb_plpython3u</literal>.
+ If you use it, <type>jsonb</type> values are mapped to Python
+ dictionaries, lists, and scalars, as appropriate.
+ </para>
+
+ <para>
+ Of these extensions, <literal>jsonb_plperl</literal> is
+ considered <quote>trusted</quote>, that is, it can be installed by
+ non-superusers who have <literal>CREATE</literal> privilege on the
+ current database. The rest require superuser privilege to install.
+ </para>
+ </sect2>
+
+ <sect2 id="datatype-jsonpath">
+ <title>jsonpath Type</title>
+
+ <indexterm zone="datatype-jsonpath">
+ <primary>jsonpath</primary>
+ </indexterm>
+
+ <para>
+ The <type>jsonpath</type> type implements support for the SQL/JSON path language
+ in <productname>PostgreSQL</productname> to efficiently query JSON data.
+ It provides a binary representation of the parsed SQL/JSON path
+ expression that specifies the items to be retrieved by the path
+ engine from the JSON data for further processing with the
+ SQL/JSON query functions.
+ </para>
+
+ <para>
+ The semantics of SQL/JSON path predicates and operators generally follow SQL.
+ At the same time, to provide a natural way of working with JSON data,
+ SQL/JSON path syntax uses some JavaScript conventions:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Dot (<literal>.</literal>) is used for member access.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Square brackets (<literal>[]</literal>) are used for array access.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ SQL/JSON arrays are 0-relative, unlike regular SQL arrays that start from 1.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ An SQL/JSON path expression is typically written in an SQL query as an
+ SQL character string literal, so it must be enclosed in single quotes,
+ and any single quotes desired within the value must be doubled
+ (see <xref linkend="sql-syntax-strings"/>).
+ Some forms of path expressions require string literals within them.
+ These embedded string literals follow JavaScript/ECMAScript conventions:
+ they must be surrounded by double quotes, and backslash escapes may be
+ used within them to represent otherwise-hard-to-type characters.
+ In particular, the way to write a double quote within an embedded string
+ literal is <literal>\"</literal>, and to write a backslash itself, you
+ must write <literal>\\</literal>. Other special backslash sequences
+ include those recognized in JSON strings:
+ <literal>\b</literal>,
+ <literal>\f</literal>,
+ <literal>\n</literal>,
+ <literal>\r</literal>,
+ <literal>\t</literal>,
+ <literal>\v</literal>
+ for various ASCII control characters, and
+ <literal>\u<replaceable>NNNN</replaceable></literal> for a Unicode
+ character identified by its 4-hex-digit code point. The backslash
+ syntax also includes two cases not allowed by JSON:
+ <literal>\x<replaceable>NN</replaceable></literal> for a character code
+ written with only two hex digits, and
+ <literal>\u{<replaceable>N...</replaceable>}</literal> for a character
+ code written with 1 to 6 hex digits.
+ </para>
+
+ <para>
+ A path expression consists of a sequence of path elements,
+ which can be any of the following:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Path literals of JSON primitive types:
+ Unicode text, numeric, true, false, or null.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Path variables listed in <xref linkend="type-jsonpath-variables"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Accessor operators listed in <xref linkend="type-jsonpath-accessors"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <type>jsonpath</type> operators and methods listed
+ in <xref linkend="functions-sqljson-path-operators"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Parentheses, which can be used to provide filter expressions
+ or define the order of path evaluation.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ For details on using <type>jsonpath</type> expressions with SQL/JSON
+ query functions, see <xref linkend="functions-sqljson-path"/>.
+ </para>
+
+ <table id="type-jsonpath-variables">
+ <title><type>jsonpath</type> Variables</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>$</literal></entry>
+ <entry>A variable representing the JSON value being queried
+ (the <firstterm>context item</firstterm>).
+ </entry>
+ </row>
+ <row>
+ <entry><literal>$varname</literal></entry>
+ <entry>
+ A named variable. Its value can be set by the parameter
+ <parameter>vars</parameter> of several JSON processing functions;
+ see <xref linkend="functions-json-processing-table"/> for details.
+ <!-- TODO: describe PASSING clause once implemented !-->
+ </entry>
+ </row>
+ <row>
+ <entry><literal>@</literal></entry>
+ <entry>A variable representing the result of path evaluation
+ in filter expressions.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="type-jsonpath-accessors">
+ <title><type>jsonpath</type> Accessors</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Accessor Operator</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <literal>.<replaceable>key</replaceable></literal>
+ </para>
+ <para>
+ <literal>."$<replaceable>varname</replaceable>"</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Member accessor that returns an object member with
+ the specified key. If the key name matches some named variable
+ starting with <literal>$</literal> or does not meet the
+ JavaScript rules for an identifier, it must be enclosed in
+ double quotes to make it a string literal.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>.*</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Wildcard member accessor that returns the values of all
+ members located at the top level of the current object.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>.**</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Recursive wildcard member accessor that processes all levels
+ of the JSON hierarchy of the current object and returns all
+ the member values, regardless of their nesting level. This
+ is a <productname>PostgreSQL</productname> extension of
+ the SQL/JSON standard.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>.**{<replaceable>level</replaceable>}</literal>
+ </para>
+ <para>
+ <literal>.**{<replaceable>start_level</replaceable> to
+ <replaceable>end_level</replaceable>}</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Like <literal>.**</literal>, but selects only the specified
+ levels of the JSON hierarchy. Nesting levels are specified as integers.
+ Level zero corresponds to the current object. To access the lowest
+ nesting level, you can use the <literal>last</literal> keyword.
+ This is a <productname>PostgreSQL</productname> extension of
+ the SQL/JSON standard.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>[<replaceable>subscript</replaceable>, ...]</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Array element accessor.
+ <literal><replaceable>subscript</replaceable></literal> can be
+ given in two forms: <literal><replaceable>index</replaceable></literal>
+ or <literal><replaceable>start_index</replaceable> to <replaceable>end_index</replaceable></literal>.
+ The first form returns a single array element by its index. The second
+ form returns an array slice by the range of indexes, including the
+ elements that correspond to the provided
+ <replaceable>start_index</replaceable> and <replaceable>end_index</replaceable>.
+ </para>
+ <para>
+ The specified <replaceable>index</replaceable> can be an integer, as
+ well as an expression returning a single numeric value, which is
+ automatically cast to integer. Index zero corresponds to the first
+ array element. You can also use the <literal>last</literal> keyword
+ to denote the last array element, which is useful for handling arrays
+ of unknown length.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <literal>[*]</literal>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ Wildcard array element accessor that returns all array elements.
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+</sect1>
diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml
new file mode 100644
index 0000000..a7bf30c
--- /dev/null
+++ b/doc/src/sgml/keywords.sgml
@@ -0,0 +1,90 @@
+<!-- doc/src/sgml/keywords.sgml -->
+
+<appendix id="sql-keywords-appendix">
+ <title><acronym>SQL</acronym> Key Words</title>
+
+ <indexterm zone="sql-keywords-appendix">
+ <primary>key word</primary>
+ <secondary>list of</secondary>
+ </indexterm>
+
+ <para>
+ <xref linkend="keywords-table"/> lists all tokens that are key words
+ in the SQL standard and in <productname>PostgreSQL</productname>
+ &version;. Background information can be found in <xref
+ linkend="sql-syntax-identifiers"/>.
+ (For space reasons, only the latest two versions of the SQL standard, and
+ SQL-92 for historical comparison, are included. The differences between
+ those and the other intermediate standard versions are small.)
+ </para>
+
+ <para>
+ SQL distinguishes between <firstterm>reserved</firstterm> and
+ <firstterm>non-reserved</firstterm> key words. According to the standard,
+ reserved key words
+ are the only real key words; they are never allowed as identifiers.
+ Non-reserved key words only have a special meaning in particular
+ contexts and can be used as identifiers in other contexts. Most
+ non-reserved key words are actually the names of built-in tables
+ and functions specified by SQL. The concept of non-reserved key
+ words essentially only exists to declare that some predefined meaning
+ is attached to a word in some contexts.
+ </para>
+
+ <para>
+ In the <productname>PostgreSQL</productname> parser, life is a bit
+ more complicated. There are several different classes of tokens
+ ranging from those that can never be used as an identifier to those
+ that have absolutely no special status in the parser, but are considered
+ ordinary identifiers. (The latter is usually the case for
+ functions specified by SQL.) Even reserved key words are not
+ completely reserved in <productname>PostgreSQL</productname>, but
+ can be used as column labels (for example, <literal>SELECT 55 AS
+ CHECK</literal>, even though <token>CHECK</token> is a reserved key
+ word).
+ </para>
+
+ <para>
+ In <xref linkend="keywords-table"/> in the column for
+ <productname>PostgreSQL</productname> we classify as
+ <quote>non-reserved</quote> those key words that are explicitly
+ known to the parser but are allowed as column or table names.
+ Some key words that are otherwise
+ non-reserved cannot be used as function or data type names and are
+ marked accordingly. (Most of these words represent built-in
+ functions or data types with special syntax. The function or type
+ is still available but it cannot be redefined by the user.) Labeled
+ <quote>reserved</quote> are those tokens that are not allowed as
+ column or table names. Some reserved key words are
+ allowable as names for functions or data types; this is also shown in the
+ table. If not so marked, a reserved key word is only allowed as a
+ column label.
+ A blank entry in this column means that the word is treated as an
+ ordinary identifier by <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ Furthermore, while most key words can be used as <quote>bare</quote>
+ column labels without writing <literal>AS</literal> before them (as
+ described in <xref linkend="queries-column-labels"/>), there are a few
+ that require a leading <literal>AS</literal> to avoid ambiguity. These
+ are marked in the table as <quote>requires <literal>AS</literal></quote>.
+ </para>
+
+ <para>
+ As a general rule, if you get spurious parser errors for commands
+ that use any of the listed key words as an identifier, you should
+ try quoting the identifier to see if the problem goes away.
+ </para>
+
+ <para>
+ It is important to understand before studying <xref
+ linkend="keywords-table"/> that the fact that a key word is not
+ reserved in <productname>PostgreSQL</productname> does not mean that
+ the feature related to the word is not implemented. Conversely, the
+ presence of a key word does not indicate the existence of a feature.
+ </para>
+
+ &keywords-table;
+
+</appendix>
diff --git a/doc/src/sgml/keywords/sql1992-nonreserved.txt b/doc/src/sgml/keywords/sql1992-nonreserved.txt
new file mode 100644
index 0000000..00abeda
--- /dev/null
+++ b/doc/src/sgml/keywords/sql1992-nonreserved.txt
@@ -0,0 +1,50 @@
+ADA
+C
+CATALOG_NAME
+CHARACTER_SET_CATALOG
+CHARACTER_SET_NAME
+CHARACTER_SET_SCHEMA
+CLASS_ORIGIN
+COBOL
+COLLATION_CATALOG
+COLLATION_NAME
+COLLATION_SCHEMA
+COLUMN_NAME
+COMMAND_FUNCTION
+COMMITTED
+CONDITION_NUMBER
+CONNECTION_NAME
+CONSTRAINT_CATALOG
+CONSTRAINT_NAME
+CONSTRAINT_SCHEMA
+CURSOR_NAME
+DATA
+DATETIME_INTERVAL_CODE
+DATETIME_INTERVAL_PRECISION
+DYNAMIC_FUNCTION
+FORTRAN
+LENGTH
+MESSAGE_LENGTH
+MESSAGE_OCTET_LENGTH
+MESSAGE_TEXT
+MORE
+MUMPS
+NAME
+NULLABLE
+NUMBER
+PASCAL
+PLI
+REPEATABLE
+RETURNED_LENGTH
+RETURNED_OCTET_LENGTH
+RETURNED_SQLSTATE
+ROW_COUNT
+SCALE
+SCHEMA_NAME
+SERIALIZABLE
+SERVER_NAME
+SUBCLASS_ORIGIN
+TABLE_NAME
+TYPE
+UNCOMMITTED
+UNNAMED
diff --git a/doc/src/sgml/keywords/sql1992-reserved.txt b/doc/src/sgml/keywords/sql1992-reserved.txt
new file mode 100644
index 0000000..5bda213
--- /dev/null
+++ b/doc/src/sgml/keywords/sql1992-reserved.txt
@@ -0,0 +1,227 @@
+ABSOLUTE
+ACTION
+ADD
+ALL
+ALLOCATE
+ALTER
+AND
+ANY
+ARE
+AS
+ASC
+ASSERTION
+AT
+AUTHORIZATION
+AVG
+BEGIN
+BETWEEN
+BIT
+BIT_LENGTH
+BOTH
+BY
+CASCADE
+CASCADED
+CASE
+CAST
+CATALOG
+CHAR
+CHARACTER
+CHAR_LENGTH
+CHARACTER_LENGTH
+CHECK
+CLOSE
+COALESCE
+COLLATE
+COLLATION
+COLUMN
+COMMIT
+CONNECT
+CONNECTION
+CONSTRAINT
+CONSTRAINTS
+CONTINUE
+CONVERT
+CORRESPONDING
+COUNT
+CREATE
+CROSS
+CURRENT
+CURRENT_DATE
+CURRENT_TIME
+CURRENT_TIMESTAMP
+CURRENT_USER
+CURSOR
+DATE
+DAY
+DEALLOCATE
+DEC
+DECIMAL
+DECLARE
+DEFAULT
+DEFERRABLE
+DEFERRED
+DELETE
+DESC
+DESCRIBE
+DESCRIPTOR
+DIAGNOSTICS
+DISCONNECT
+DISTINCT
+DOMAIN
+DOUBLE
+DROP
+ELSE
+END
+END-EXEC
+ESCAPE
+EXCEPT
+EXCEPTION
+EXEC
+EXECUTE
+EXISTS
+EXTERNAL
+EXTRACT
+FALSE
+FETCH
+FIRST
+FLOAT
+FOR
+FOREIGN
+FOUND
+FROM
+FULL
+GET
+GLOBAL
+GO
+GOTO
+GRANT
+GROUP
+HAVING
+HOUR
+IDENTITY
+IMMEDIATE
+IN
+INDICATOR
+INITIALLY
+INNER
+INPUT
+INSENSITIVE
+INSERT
+INT
+INTEGER
+INTERSECT
+INTERVAL
+INTO
+IS
+ISOLATION
+JOIN
+KEY
+LANGUAGE
+LAST
+LEADING
+LEFT
+LEVEL
+LIKE
+LOCAL
+LOWER
+MATCH
+MAX
+MIN
+MINUTE
+MODULE
+MONTH
+NAMES
+NATIONAL
+NATURAL
+NCHAR
+NEXT
+NO
+NOT
+NULL
+NULLIF
+NUMERIC
+OCTET_LENGTH
+OF
+ON
+ONLY
+OPEN
+OPTION
+OR
+ORDER
+OUTER
+OUTPUT
+OVERLAPS
+PAD
+PARTIAL
+POSITION
+PRECISION
+PREPARE
+PRESERVE
+PRIMARY
+PRIOR
+PRIVILEGES
+PROCEDURE
+PUBLIC
+READ
+REAL
+REFERENCES
+RELATIVE
+RESTRICT
+REVOKE
+RIGHT
+ROLLBACK
+ROWS
+SCHEMA
+SCROLL
+SECOND
+SECTION
+SELECT
+SESSION
+SESSION_USER
+SET
+SIZE
+SMALLINT
+SOME
+SPACE
+SQL
+SQLCODE
+SQLERROR
+SQLSTATE
+SUBSTRING
+SUM
+SYSTEM_USER
+TABLE
+TEMPORARY
+THEN
+TIME
+TIMESTAMP
+TIMEZONE_HOUR
+TIMEZONE_MINUTE
+TO
+TRAILING
+TRANSACTION
+TRANSLATE
+TRANSLATION
+TRIM
+TRUE
+UNION
+UNIQUE
+UNKNOWN
+UPDATE
+UPPER
+USAGE
+USER
+USING
+VALUE
+VALUES
+VARCHAR
+VARYING
+VIEW
+WHEN
+WHENEVER
+WHERE
+WITH
+WORK
+WRITE
+YEAR
+ZONE
diff --git a/doc/src/sgml/keywords/sql2011-02-nonreserved.txt b/doc/src/sgml/keywords/sql2011-02-nonreserved.txt
new file mode 100644
index 0000000..b28a180
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2011-02-nonreserved.txt
@@ -0,0 +1,219 @@
+A
+ABSOLUTE
+ACTION
+ADA
+ADD
+ADMIN
+AFTER
+ALWAYS
+ASC
+ASSERTION
+ASSIGNMENT
+ATTRIBUTE
+ATTRIBUTES
+BEFORE
+BERNOULLI
+BREADTH
+C
+CASCADE
+CATALOG
+CATALOG_NAME
+CHAIN
+CHARACTER_SET_CATALOG
+CHARACTER_SET_NAME
+CHARACTER_SET_SCHEMA
+CHARACTERISTICS
+CHARACTERS
+CLASS_ORIGIN
+COBOL
+COLLATION
+COLLATION_CATALOG
+COLLATION_NAME
+COLLATION_SCHEMA
+COLUMN_NAME
+COMMAND_FUNCTION
+COMMAND_FUNCTION_CODE
+COMMITTED
+CONDITION_NUMBER
+CONNECTION
+CONNECTION_NAME
+CONSTRAINT_CATALOG
+CONSTRAINT_NAME
+CONSTRAINT_SCHEMA
+CONSTRAINTS
+CONSTRUCTOR
+CONTINUE
+CURSOR_NAME
+DATA
+DATETIME_INTERVAL_CODE
+DATETIME_INTERVAL_PRECISION
+DEFAULTS
+DEFERRABLE
+DEFERRED
+DEFINED
+DEFINER
+DEGREE
+DEPTH
+DERIVED
+DESC
+DESCRIPTOR
+DIAGNOSTICS
+DISPATCH
+DOMAIN
+DYNAMIC_FUNCTION
+DYNAMIC_FUNCTION_CODE
+ENFORCED
+EXCLUDE
+EXCLUDING
+EXPRESSION
+FINAL
+FIRST
+FLAG
+FOLLOWING
+FORTRAN
+FOUND
+G
+GENERAL
+GENERATED
+GO
+GOTO
+GRANTED
+HIERARCHY
+IGNORE
+IMMEDIATE
+IMMEDIATELY
+IMPLEMENTATION
+INCLUDING
+INCREMENT
+INITIALLY
+INPUT
+INSTANCE
+INSTANTIABLE
+INSTEAD
+INVOKER
+ISOLATION
+K
+KEY
+KEY_MEMBER
+KEY_TYPE
+LAST
+LENGTH
+LEVEL
+LOCATOR
+M
+MAP
+MATCHED
+MAXVALUE
+MESSAGE_LENGTH
+MESSAGE_OCTET_LENGTH
+MESSAGE_TEXT
+MINVALUE
+MORE
+MUMPS
+NAME
+NAMES
+NESTING
+NEXT
+NFC
+NFD
+NFKC
+NFKD
+NORMALIZED
+NULLABLE
+NULLS
+NUMBER
+OBJECT
+OCTETS
+OPTION
+OPTIONS
+ORDERING
+ORDINALITY
+OTHERS
+OUTPUT
+OVERRIDING
+P
+PAD
+PARAMETER_MODE
+PARAMETER_NAME
+PARAMETER_ORDINAL_POSITION
+PARAMETER_SPECIFIC_CATALOG
+PARAMETER_SPECIFIC_NAME
+PARAMETER_SPECIFIC_SCHEMA
+PARTIAL
+PASCAL
+PATH
+PLACING
+PLI
+PRECEDING
+PRESERVE
+PRIOR
+PRIVILEGES
+PUBLIC
+READ
+RELATIVE
+REPEATABLE
+RESPECT
+RESTART
+RESTRICT
+RETURNED_CARDINALITY
+RETURNED_LENGTH
+RETURNED_OCTET_LENGTH
+RETURNED_SQLSTATE
+ROLE
+ROUTINE
+ROUTINE_CATALOG
+ROUTINE_NAME
+ROUTINE_SCHEMA
+ROW_COUNT
+SCALE
+SCHEMA
+SCHEMA_NAME
+SCOPE_CATALOG
+SCOPE_NAME
+SCOPE_SCHEMA
+SECTION
+SECURITY
+SELF
+SEQUENCE
+SERIALIZABLE
+SERVER_NAME
+SESSION
+SETS
+SIMPLE
+SIZE
+SOURCE
+SPACE
+SPECIFIC_NAME
+STATE
+STATEMENT
+STRUCTURE
+STYLE
+SUBCLASS_ORIGIN
+T
+TABLE_NAME
+TEMPORARY
+TIES
+TOP_LEVEL_COUNT
+TRANSACTION
+TRANSACTION_ACTIVE
+TRANSACTIONS_COMMITTED
+TRANSACTIONS_ROLLED_BACK
+TRANSFORM
+TRANSFORMS
+TRIGGER_CATALOG
+TRIGGER_NAME
+TRIGGER_SCHEMA
+TYPE
+UNBOUNDED
+UNCOMMITTED
+UNDER
+UNNAMED
+USAGE
+USER_DEFINED_TYPE_CATALOG
+USER_DEFINED_TYPE_CODE
+USER_DEFINED_TYPE_NAME
+USER_DEFINED_TYPE_SCHEMA
+VIEW
+WORK
+WRITE
+ZONE
diff --git a/doc/src/sgml/keywords/sql2011-02-reserved.txt b/doc/src/sgml/keywords/sql2011-02-reserved.txt
new file mode 100644
index 0000000..95f99e7
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2011-02-reserved.txt
@@ -0,0 +1,324 @@
+ABS
+ALL
+ALLOCATE
+ALTER
+AND
+ANY
+ARE
+ARRAY
+ARRAY_AGG
+ARRAY_MAX_CARDINALITY
+AS
+ASENSITIVE
+ASYMMETRIC
+AT
+ATOMIC
+AUTHORIZATION
+AVG
+BEGIN
+BEGIN_FRAME
+BEGIN_PARTITION
+BETWEEN
+BIGINT
+BINARY
+BLOB
+BOOLEAN
+BOTH
+BY
+CALL
+CALLED
+CARDINALITY
+CASCADED
+CASE
+CAST
+CEIL
+CEILING
+CHAR
+CHAR_LENGTH
+CHARACTER
+CHARACTER_LENGTH
+CHECK
+CLOB
+CLOSE
+COALESCE
+COLLATE
+COLLECT
+COLUMN
+COMMIT
+CONDITION
+CONNECT
+CONSTRAINT
+CONTAINS
+CONVERT
+CORR
+CORRESPONDING
+COUNT
+COVAR_POP
+COVAR_SAMP
+CREATE
+CROSS
+CUBE
+CUME_DIST
+CURRENT
+CURRENT_CATALOG
+CURRENT_DATE
+CURRENT_DEFAULT_TRANSFORM_GROUP
+CURRENT_PATH
+CURRENT_ROLE
+CURRENT_ROW
+CURRENT_SCHEMA
+CURRENT_TIME
+CURRENT_TIMESTAMP
+CURRENT_TRANSFORM_GROUP_FOR_TYPE
+CURRENT_USER
+CURSOR
+CYCLE
+DATE
+DAY
+DEALLOCATE
+DEC
+DECIMAL
+DECLARE
+DEFAULT
+DELETE
+DENSE_RANK
+DEREF
+DESCRIBE
+DETERMINISTIC
+DISCONNECT
+DISTINCT
+DOUBLE
+DROP
+DYNAMIC
+EACH
+ELEMENT
+ELSE
+END
+END_FRAME
+END_PARTITION
+END-EXEC
+EQUALS
+ESCAPE
+EVERY
+EXCEPT
+EXEC
+EXECUTE
+EXISTS
+EXP
+EXTERNAL
+EXTRACT
+FALSE
+FETCH
+FILTER
+FIRST_VALUE
+FLOAT
+FLOOR
+FOR
+FOREIGN
+FRAME_ROW
+FREE
+FROM
+FULL
+FUNCTION
+FUSION
+GET
+GLOBAL
+GRANT
+GROUP
+GROUPING
+GROUPS
+HAVING
+HOLD
+HOUR
+IDENTITY
+IN
+INDICATOR
+INNER
+INOUT
+INSENSITIVE
+INSERT
+INT
+INTEGER
+INTERSECT
+INTERSECTION
+INTERVAL
+INTO
+IS
+JOIN
+LAG
+LANGUAGE
+LARGE
+LAST_VALUE
+LATERAL
+LEAD
+LEADING
+LEFT
+LIKE
+LIKE_REGEX
+LN
+LOCAL
+LOCALTIME
+LOCALTIMESTAMP
+LOWER
+MATCH
+MAX
+MEMBER
+MERGE
+METHOD
+MIN
+MINUTE
+MOD
+MODIFIES
+MODULE
+MONTH
+MULTISET
+NATIONAL
+NATURAL
+NCHAR
+NCLOB
+NEW
+NO
+NONE
+NORMALIZE
+NOT
+NTH_VALUE
+NTILE
+NULL
+NULLIF
+NUMERIC
+OCTET_LENGTH
+OCCURRENCES_REGEX
+OF
+OFFSET
+OLD
+ON
+ONLY
+OPEN
+OR
+ORDER
+OUT
+OUTER
+OVER
+OVERLAPS
+OVERLAY
+PARAMETER
+PARTITION
+PERCENT
+PERCENT_RANK
+PERCENTILE_CONT
+PERCENTILE_DISC
+PERIOD
+PORTION
+POSITION
+POSITION_REGEX
+POWER
+PRECEDES
+PRECISION
+PREPARE
+PRIMARY
+PROCEDURE
+RANGE
+RANK
+READS
+REAL
+RECURSIVE
+REF
+REFERENCES
+REFERENCING
+REGR_AVGX
+REGR_AVGY
+REGR_COUNT
+REGR_INTERCEPT
+REGR_R2
+REGR_SLOPE
+REGR_SXX
+REGR_SXY
+REGR_SYY
+RELEASE
+RESULT
+RETURN
+RETURNS
+REVOKE
+RIGHT
+ROLLBACK
+ROLLUP
+ROW
+ROW_NUMBER
+ROWS
+SAVEPOINT
+SCOPE
+SCROLL
+SEARCH
+SECOND
+SELECT
+SENSITIVE
+SESSION_USER
+SET
+SIMILAR
+SMALLINT
+SOME
+SPECIFIC
+SPECIFICTYPE
+SQL
+SQLEXCEPTION
+SQLSTATE
+SQLWARNING
+SQRT
+START
+STATIC
+STDDEV_POP
+STDDEV_SAMP
+SUBMULTISET
+SUBSTRING
+SUBSTRING_REGEX
+SUCCEEDS
+SUM
+SYMMETRIC
+SYSTEM
+SYSTEM_TIME
+SYSTEM_USER
+TABLE
+TABLESAMPLE
+THEN
+TIME
+TIMESTAMP
+TIMEZONE_HOUR
+TIMEZONE_MINUTE
+TO
+TRAILING
+TRANSLATE
+TRANSLATE_REGEX
+TRANSLATION
+TREAT
+TRIGGER
+TRUNCATE
+TRIM
+TRIM_ARRAY
+TRUE
+UESCAPE
+UNION
+UNIQUE
+UNKNOWN
+UNNEST
+UPDATE
+UPPER
+USER
+USING
+VALUE
+VALUES
+VALUE_OF
+VAR_POP
+VAR_SAMP
+VARBINARY
+VARCHAR
+VARYING
+VERSIONING
+WHEN
+WHENEVER
+WHERE
+WIDTH_BUCKET
+WINDOW
+WITH
+WITHIN
+WITHOUT
+YEAR
diff --git a/doc/src/sgml/keywords/sql2011-09-nonreserved.txt b/doc/src/sgml/keywords/sql2011-09-nonreserved.txt
new file mode 100644
index 0000000..b360f0c
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2011-09-nonreserved.txt
@@ -0,0 +1,23 @@
+BLOCKED
+CONTROL
+DB
+FILE
+FS
+INTEGRITY
+LIBRARY
+LIMIT
+LINK
+MAPPING
+OFF
+PASSTHROUGH
+PERMISSION
+RECOVERY
+REQUIRING
+RESTORE
+SELECTIVE
+SERVER
+TOKEN
+UNLINK
+VERSION
+WRAPPER
+YES
diff --git a/doc/src/sgml/keywords/sql2011-09-reserved.txt b/doc/src/sgml/keywords/sql2011-09-reserved.txt
new file mode 100644
index 0000000..0205485
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2011-09-reserved.txt
@@ -0,0 +1,13 @@
+DATALINK
+DLNEWCOPY
+DLPREVIOUSCOPY
+DLURLCOMPLETE
+DLURLCOMPLETEWRITE
+DLURLCOMPLETEONLY
+DLURLPATH
+DLURLPATHWRITE
+DLURLPATHONLY
+DLURLSCHEME
+DLURLSERVER
+DLVALUE
+IMPORT
diff --git a/doc/src/sgml/keywords/sql2011-14-nonreserved.txt b/doc/src/sgml/keywords/sql2011-14-nonreserved.txt
new file mode 100644
index 0000000..317f651
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2011-14-nonreserved.txt
@@ -0,0 +1,29 @@
+ABSENT
+ACCORDING
+BASE64
+BOM
+COLUMNS
+CONTENT
+DOCUMENT
+EMPTY
+ENCODING
+HEX
+ID
+INDENT
+LOCATION
+NAMESPACE
+NIL
+PASSING
+PATH
+PRESERVE
+RETURNING
+SEQUENCE
+STANDALONE
+STRIP
+UNTYPED
+URI
+VALID
+VERSION
+WHITESPACE
+XMLSCHEMA
+XMLDECLARATION
diff --git a/doc/src/sgml/keywords/sql2011-14-reserved.txt b/doc/src/sgml/keywords/sql2011-14-reserved.txt
new file mode 100644
index 0000000..cf80529
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2011-14-reserved.txt
@@ -0,0 +1,20 @@
+XML
+XMLAGG
+XMLATTRIBUTES
+XMLBINARY
+XMLCAST
+XMLCOMMENT
+XMLCONCAT
+XMLDOCUMENT
+XMLELEMENT
+XMLEXISTS
+XMLFOREST
+XMLITERATE
+XMLNAMESPACES
+XMLPARSE
+XMLPI
+XMLQUERY
+XMLSERIALIZE
+XMLTABLE
+XMLTEXT
+XMLVALIDATE
diff --git a/doc/src/sgml/keywords/sql2016-02-nonreserved.txt b/doc/src/sgml/keywords/sql2016-02-nonreserved.txt
new file mode 100644
index 0000000..9edcbce
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2016-02-nonreserved.txt
@@ -0,0 +1,256 @@
+A
+ABSOLUTE
+ACTION
+ADA
+ADD
+ADMIN
+AFTER
+ALWAYS
+ASC
+ASSERTION
+ASSIGNMENT
+ATTRIBUTE
+ATTRIBUTES
+BEFORE
+BERNOULLI
+BREADTH
+C
+CASCADE
+CATALOG
+CATALOG_NAME
+CHAIN
+CHAINING
+CHARACTER_SET_CATALOG
+CHARACTER_SET_NAME
+CHARACTER_SET_SCHEMA
+CHARACTERISTICS
+CHARACTERS
+CLASS_ORIGIN
+COBOL
+COLLATION
+COLLATION_CATALOG
+COLLATION_NAME
+COLLATION_SCHEMA
+COLUMNS
+COLUMN_NAME
+COMMAND_FUNCTION
+COMMAND_FUNCTION_CODE
+COMMITTED
+CONDITIONAL
+CONDITION_NUMBER
+CONNECTION
+CONNECTION_NAME
+CONSTRAINT_CATALOG
+CONSTRAINT_NAME
+CONSTRAINT_SCHEMA
+CONSTRAINTS
+CONSTRUCTOR
+CONTINUE
+CURSOR_NAME
+DATA
+DATETIME_INTERVAL_CODE
+DATETIME_INTERVAL_PRECISION
+DEFAULTS
+DEFERRABLE
+DEFERRED
+DEFINED
+DEFINER
+DEGREE
+DEPTH
+DERIVED
+DESC
+DESCRIPTOR
+DIAGNOSTICS
+DISPATCH
+DOMAIN
+DYNAMIC_FUNCTION
+DYNAMIC_FUNCTION_CODE
+ENCODING
+ENFORCED
+ERROR
+EXCLUDE
+EXCLUDING
+EXPRESSION
+FINAL
+FINISH
+FIRST
+FLAG
+FOLLOWING
+FORMAT
+FORTRAN
+FOUND
+FULFILL
+G
+GENERAL
+GENERATED
+GO
+GOTO
+GRANTED
+HIERARCHY
+IGNORE
+IMMEDIATE
+IMMEDIATELY
+IMPLEMENTATION
+INCLUDING
+INCREMENT
+INITIALLY
+INPUT
+INSTANCE
+INSTANTIABLE
+INSTEAD
+INVOKER
+ISOLATION
+K
+KEEP
+KEY
+KEYS
+KEY_MEMBER
+KEY_TYPE
+LAST
+LENGTH
+LEVEL
+LOCATOR
+M
+MAP
+MATCHED
+MAXVALUE
+MEASURES
+MESSAGE_LENGTH
+MESSAGE_OCTET_LENGTH
+MESSAGE_TEXT
+MINVALUE
+MORE
+MUMPS
+NAME
+NAMES
+NESTED
+NESTING
+NEXT
+NFC
+NFD
+NFKC
+NFKD
+NORMALIZED
+NULL_ORDERING
+NULLABLE
+NULLS
+NUMBER
+OBJECT
+OCCURRENCE
+OCTETS
+OPTION
+OPTIONS
+ORDERING
+ORDINALITY
+OTHERS
+OUTPUT
+OVERFLOW
+OVERRIDING
+P
+PAD
+PARAMETER_MODE
+PARAMETER_NAME
+PARAMETER_ORDINAL_POSITION
+PARAMETER_SPECIFIC_CATALOG
+PARAMETER_SPECIFIC_NAME
+PARAMETER_SPECIFIC_SCHEMA
+PARTIAL
+PASCAL
+PASS
+PASSING
+PAST
+PATH
+PERMUTE
+PIPE
+PLACING
+PLAN
+PLI
+PRECEDING
+PRESERVE
+PREV
+PRIOR
+PRIVATE
+PRIVILEGES
+PRUNE
+PUBLIC
+QUOTES
+READ
+RELATIVE
+REPEATABLE
+RESPECT
+RESTART
+RESTRICT
+RETURNED_CARDINALITY
+RETURNED_LENGTH
+RETURNED_OCTET_LENGTH
+RETURNED_SQLSTATE
+RETURNING
+ROLE
+ROUTINE
+ROUTINE_CATALOG
+ROUTINE_NAME
+ROUTINE_SCHEMA
+ROW_COUNT
+SCALAR
+SCALE
+SCHEMA
+SCHEMA_NAME
+SCOPE_CATALOG
+SCOPE_NAME
+SCOPE_SCHEMA
+SECTION
+SECURITY
+SELF
+SEMANTICS
+SEQUENCE
+SERIALIZABLE
+SERVER_NAME
+SESSION
+SETS
+SIMPLE
+SIZE
+SORT_DIRECTION
+SOURCE
+SPACE
+SPECIFIC_NAME
+STATE
+STATEMENT
+STRING
+STRUCTURE
+STYLE
+SUBCLASS_ORIGIN
+T
+TABLE_NAME
+TEMPORARY
+THROUGH
+TIES
+TOP_LEVEL_COUNT
+TRANSACTION
+TRANSACTION_ACTIVE
+TRANSACTIONS_COMMITTED
+TRANSACTIONS_ROLLED_BACK
+TRANSFORM
+TRANSFORMS
+TRIGGER_CATALOG
+TRIGGER_NAME
+TRIGGER_SCHEMA
+TYPE
+UNBOUNDED
+UNCOMMITTED
+UNCONDITIONAL
+UNDER
+UNMATCHED
+UNNAMED
+USAGE
+USER_DEFINED_TYPE_CATALOG
+USER_DEFINED_TYPE_CODE
+USER_DEFINED_TYPE_NAME
+USER_DEFINED_TYPE_SCHEMA
+UTF16
+UTF32
+UTF8
+VIEW
+WORK
+WRAPPER
+WRITE
+ZONE
diff --git a/doc/src/sgml/keywords/sql2016-02-reserved.txt b/doc/src/sgml/keywords/sql2016-02-reserved.txt
new file mode 100644
index 0000000..b1bb077
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2016-02-reserved.txt
@@ -0,0 +1,368 @@
+ABS
+ABSENT
+ACOS
+ALL
+ALLOCATE
+ALTER
+AND
+ANY
+ARE
+ARRAY
+ARRAY_AGG
+ARRAY_MAX_CARDINALITY
+AS
+ASENSITIVE
+ASIN
+ASYMMETRIC
+AT
+ATAN
+ATOMIC
+AUTHORIZATION
+AVG
+BEGIN
+BEGIN_FRAME
+BEGIN_PARTITION
+BETWEEN
+BIGINT
+BINARY
+BLOB
+BOOLEAN
+BOTH
+BY
+CALL
+CALLED
+CARDINALITY
+CASCADED
+CASE
+CAST
+CEIL
+CEILING
+CHAR
+CHAR_LENGTH
+CHARACTER
+CHARACTER_LENGTH
+CHECK
+CLASSIFIER
+CLOB
+CLOSE
+COALESCE
+COLLATE
+COLLECT
+COLUMN
+COMMIT
+CONDITION
+CONNECT
+CONSTRAINT
+CONTAINS
+CONVERT
+COPY
+CORR
+CORRESPONDING
+COS
+COSH
+COUNT
+COVAR_POP
+COVAR_SAMP
+CREATE
+CROSS
+CUBE
+CUME_DIST
+CURRENT
+CURRENT_CATALOG
+CURRENT_DATE
+CURRENT_DEFAULT_TRANSFORM_GROUP
+CURRENT_PATH
+CURRENT_ROLE
+CURRENT_ROW
+CURRENT_SCHEMA
+CURRENT_TIME
+CURRENT_TIMESTAMP
+CURRENT_TRANSFORM_GROUP_FOR_TYPE
+CURRENT_USER
+CURSOR
+CYCLE
+DATE
+DAY
+DEALLOCATE
+DEC
+DECIMAL
+DECFLOAT
+DECLARE
+DEFAULT
+DEFINE
+DELETE
+DENSE_RANK
+DEREF
+DESCRIBE
+DETERMINISTIC
+DISCONNECT
+DISTINCT
+DOUBLE
+DROP
+DYNAMIC
+EACH
+ELEMENT
+ELSE
+EMPTY
+END
+END_FRAME
+END_PARTITION
+END-EXEC
+EQUALS
+ESCAPE
+EVERY
+EXCEPT
+EXEC
+EXECUTE
+EXISTS
+EXP
+EXTERNAL
+EXTRACT
+FALSE
+FETCH
+FILTER
+FIRST_VALUE
+FLOAT
+FLOOR
+FOR
+FOREIGN
+FRAME_ROW
+FREE
+FROM
+FULL
+FUNCTION
+FUSION
+GET
+GLOBAL
+GRANT
+GROUP
+GROUPING
+GROUPS
+HAVING
+HOLD
+HOUR
+IDENTITY
+IN
+INDICATOR
+INITIAL
+INNER
+INOUT
+INSENSITIVE
+INSERT
+INT
+INTEGER
+INTERSECT
+INTERSECTION
+INTERVAL
+INTO
+IS
+JOIN
+JSON_ARRAY
+JSON_ARRAYAGG
+JSON_EXISTS
+JSON_OBJECT
+JSON_OBJECTAGG
+JSON_QUERY
+JSON_TABLE
+JSON_TABLE_PRIMITIVE
+JSON_VALUE
+LAG
+LANGUAGE
+LARGE
+LAST_VALUE
+LATERAL
+LEAD
+LEADING
+LEFT
+LIKE
+LIKE_REGEX
+LISTAGG
+LN
+LOCAL
+LOCALTIME
+LOCALTIMESTAMP
+LOG
+LOG10
+LOWER
+MATCH
+MATCH_NUMBER
+MATCH_RECOGNIZE
+MATCHES
+MAX
+MEASURES
+MEMBER
+MERGE
+METHOD
+MIN
+MINUTE
+MOD
+MODIFIES
+MODULE
+MONTH
+MULTISET
+NATIONAL
+NATURAL
+NCHAR
+NCLOB
+NEW
+NO
+NONE
+NORMALIZE
+NOT
+NTH_VALUE
+NTILE
+NULL
+NULLIF
+NUMERIC
+OCTET_LENGTH
+OCCURRENCES_REGEX
+OF
+OFFSET
+OLD
+OMIT
+ON
+ONE
+ONLY
+OPEN
+OR
+ORDER
+OUT
+OUTER
+OVER
+OVERLAPS
+OVERLAY
+PARAMETER
+PARTITION
+PATTERN
+PER
+PERCENT
+PERCENT_RANK
+PERCENTILE_CONT
+PERCENTILE_DISC
+PERIOD
+PERMUTE
+PORTION
+POSITION
+POSITION_REGEX
+POWER
+PRECEDES
+PRECISION
+PREPARE
+PRIMARY
+PROCEDURE
+PTF
+RANGE
+RANK
+READS
+REAL
+RECURSIVE
+REF
+REFERENCES
+REFERENCING
+REGR_AVGX
+REGR_AVGY
+REGR_COUNT
+REGR_INTERCEPT
+REGR_R2
+REGR_SLOPE
+REGR_SXX
+REGR_SXY
+REGR_SYY
+RELEASE
+RESULT
+RETURN
+RETURNS
+REVOKE
+RIGHT
+ROLLBACK
+ROLLUP
+ROW
+ROW_NUMBER
+ROWS
+RUNNING
+SAVEPOINT
+SCOPE
+SCROLL
+SEARCH
+SECOND
+SEEK
+SELECT
+SENSITIVE
+SESSION_USER
+SET
+SHOW
+SIMILAR
+SIN
+SINH
+SKIP
+SMALLINT
+SOME
+SPECIFIC
+SPECIFICTYPE
+SQL
+SQLEXCEPTION
+SQLSTATE
+SQLWARNING
+SQRT
+START
+STATIC
+STDDEV_POP
+STDDEV_SAMP
+SUBMULTISET
+SUBSET
+SUBSTRING
+SUBSTRING_REGEX
+SUCCEEDS
+SUM
+SYMMETRIC
+SYSTEM
+SYSTEM_TIME
+SYSTEM_USER
+TABLE
+TABLESAMPLE
+TAN
+TANH
+THEN
+TIME
+TIMESTAMP
+TIMEZONE_HOUR
+TIMEZONE_MINUTE
+TO
+TRAILING
+TRANSLATE
+TRANSLATE_REGEX
+TRANSLATION
+TREAT
+TRIGGER
+TRIM
+TRIM_ARRAY
+TRUE
+TRUNCATE
+UESCAPE
+UNION
+UNIQUE
+UNKNOWN
+UNMATCHED
+UNNEST
+UPDATE
+UPPER
+USER
+USING
+VALUE
+VALUES
+VALUE_OF
+VAR_POP
+VAR_SAMP
+VARBINARY
+VARCHAR
+VARYING
+VERSIONING
+WHEN
+WHENEVER
+WHERE
+WIDTH_BUCKET
+WINDOW
+WITH
+WITHIN
+WITHOUT
+YEAR
diff --git a/doc/src/sgml/keywords/sql2016-09-nonreserved.txt b/doc/src/sgml/keywords/sql2016-09-nonreserved.txt
new file mode 100644
index 0000000..b360f0c
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2016-09-nonreserved.txt
@@ -0,0 +1,23 @@
+BLOCKED
+CONTROL
+DB
+FILE
+FS
+INTEGRITY
+LIBRARY
+LIMIT
+LINK
+MAPPING
+OFF
+PASSTHROUGH
+PERMISSION
+RECOVERY
+REQUIRING
+RESTORE
+SELECTIVE
+SERVER
+TOKEN
+UNLINK
+VERSION
+WRAPPER
+YES
diff --git a/doc/src/sgml/keywords/sql2016-09-reserved.txt b/doc/src/sgml/keywords/sql2016-09-reserved.txt
new file mode 100644
index 0000000..0205485
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2016-09-reserved.txt
@@ -0,0 +1,13 @@
+DATALINK
+DLNEWCOPY
+DLPREVIOUSCOPY
+DLURLCOMPLETE
+DLURLCOMPLETEWRITE
+DLURLCOMPLETEONLY
+DLURLPATH
+DLURLPATHWRITE
+DLURLPATHONLY
+DLURLSCHEME
+DLURLSERVER
+DLVALUE
+IMPORT
diff --git a/doc/src/sgml/keywords/sql2016-14-nonreserved.txt b/doc/src/sgml/keywords/sql2016-14-nonreserved.txt
new file mode 100644
index 0000000..00c88ff
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2016-14-nonreserved.txt
@@ -0,0 +1,27 @@
+ABSENT
+ACCORDING
+BASE64
+BOM
+COLUMNS
+CONTENT
+DOCUMENT
+ENCODING
+HEX
+ID
+INDENT
+LOCATION
+NAMESPACE
+NIL
+PATH
+PRESERVE
+RETURNING
+SEQUENCE
+STANDALONE
+STRIP
+UNTYPED
+URI
+VALID
+VERSION
+WHITESPACE
+XMLSCHEMA
+XMLDECLARATION
diff --git a/doc/src/sgml/keywords/sql2016-14-reserved.txt b/doc/src/sgml/keywords/sql2016-14-reserved.txt
new file mode 100644
index 0000000..cf80529
--- /dev/null
+++ b/doc/src/sgml/keywords/sql2016-14-reserved.txt
@@ -0,0 +1,20 @@
+XML
+XMLAGG
+XMLATTRIBUTES
+XMLBINARY
+XMLCAST
+XMLCOMMENT
+XMLCONCAT
+XMLDOCUMENT
+XMLELEMENT
+XMLEXISTS
+XMLFOREST
+XMLITERATE
+XMLNAMESPACES
+XMLPARSE
+XMLPI
+XMLQUERY
+XMLSERIALIZE
+XMLTABLE
+XMLTEXT
+XMLVALIDATE
diff --git a/doc/src/sgml/legal.sgml b/doc/src/sgml/legal.sgml
new file mode 100644
index 0000000..b4773b6
--- /dev/null
+++ b/doc/src/sgml/legal.sgml
@@ -0,0 +1,48 @@
+<!-- doc/src/sgml/legal.sgml -->
+
+<date>2023</date>
+
+<copyright>
+ <year>1996&ndash;2023</year>
+ <holder>The PostgreSQL Global Development Group</holder>
+</copyright>
+
+<legalnotice id="legalnotice">
+ <title>Legal Notice</title>
+
+ <para>
+ <productname>PostgreSQL</productname> is Copyright &copy; 1996&ndash;2023
+ by the PostgreSQL Global Development Group.
+ </para>
+
+ <para>
+ <productname>Postgres95</productname> is Copyright &copy; 1994&ndash;5
+ by the Regents of the University of California.
+ </para>
+
+ <para>
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose, without fee, and without a
+ written agreement is hereby granted, provided that the above
+ copyright notice and this paragraph and the following two paragraphs
+ appear in all copies.
+ </para>
+
+ <para>
+ IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY
+ PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS
+ SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
+ HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ </para>
+
+ <para>
+ THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+ PROVIDED HEREUNDER IS ON AN <quote>AS-IS</quote> BASIS, AND THE UNIVERSITY OF
+ CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
+ UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ </para>
+
+</legalnotice>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
new file mode 100644
index 0000000..76afcff
--- /dev/null
+++ b/doc/src/sgml/libpq.sgml
@@ -0,0 +1,9573 @@
+<!-- doc/src/sgml/libpq.sgml -->
+
+<chapter id="libpq">
+ <title><application>libpq</application> &mdash; C Library</title>
+
+ <indexterm zone="libpq">
+ <primary>libpq</primary>
+ </indexterm>
+
+ <indexterm zone="libpq">
+ <primary>C</primary>
+ </indexterm>
+
+ <para>
+ <application>libpq</application> is the <acronym>C</acronym>
+ application programmer's interface to <productname>PostgreSQL</productname>.
+ <application>libpq</application> is a set of library functions that allow
+ client programs to pass queries to the <productname>PostgreSQL</productname>
+ backend server and to receive the results of these queries.
+ </para>
+
+ <para>
+ <application>libpq</application> is also the underlying engine for several
+ other <productname>PostgreSQL</productname> application interfaces, including
+ those written for C++, Perl, Python, Tcl and <application>ECPG</application>.
+ So some aspects of <application>libpq</application>'s behavior will be
+ important to you if you use one of those packages. In particular,
+ <xref linkend="libpq-envars"/>,
+ <xref linkend="libpq-pgpass"/> and
+ <xref linkend="libpq-ssl"/>
+ describe behavior that is visible to the user of any application
+ that uses <application>libpq</application>.
+ </para>
+
+ <para>
+ Some short programs are included at the end of this chapter (<xref linkend="libpq-example"/>) to show how
+ to write programs that use <application>libpq</application>. There are also several
+ complete examples of <application>libpq</application> applications in the
+ directory <filename>src/test/examples</filename> in the source code distribution.
+ </para>
+
+ <para>
+ Client programs that use <application>libpq</application> must
+ include the header file
+ <filename>libpq-fe.h</filename><indexterm><primary>libpq-fe.h</primary></indexterm>
+ and must link with the <application>libpq</application> library.
+ </para>
+
+ <sect1 id="libpq-connect">
+ <title>Database Connection Control Functions</title>
+
+ <para>
+ The following functions deal with making a connection to a
+ <productname>PostgreSQL</productname> backend server. An
+ application program can have several backend connections open at
+ one time. (One reason to do that is to access more than one
+ database.) Each connection is represented by a
+ <structname>PGconn</structname><indexterm><primary>PGconn</primary></indexterm> object, which
+ is obtained from the function <xref linkend="libpq-PQconnectdb"/>,
+ <xref linkend="libpq-PQconnectdbParams"/>, or
+ <xref linkend="libpq-PQsetdbLogin"/>. Note that these functions will always
+ return a non-null object pointer, unless perhaps there is too
+ little memory even to allocate the <structname>PGconn</structname> object.
+ The <xref linkend="libpq-PQstatus"/> function should be called to check
+ the return value for a successful connection before queries are sent
+ via the connection object.
+
+ <warning>
+ <para>
+ If untrusted users have access to a database that has not adopted a
+ <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
+ begin each session by removing publicly-writable schemas from
+ <varname>search_path</varname>. One can set parameter key
+ word <literal>options</literal> to
+ value <literal>-csearch_path=</literal>. Alternately, one can
+ issue <literal>PQexec(<replaceable>conn</replaceable>, "SELECT
+ pg_catalog.set_config('search_path', '', false)")</literal> after
+ connecting. This consideration is not specific
+ to <application>libpq</application>; it applies to every interface for
+ executing arbitrary SQL commands.
+ </para>
+ </warning>
+
+ <warning>
+ <para>
+ On Unix, forking a process with open libpq connections can lead to
+ unpredictable results because the parent and child processes share
+ the same sockets and operating system resources. For this reason,
+ such usage is not recommended, though doing an <function>exec</function> from
+ the child process to load a new executable is safe.
+ </para>
+ </warning>
+
+ <variablelist>
+ <varlistentry id="libpq-PQconnectdbParams">
+ <term><function>PQconnectdbParams</function><indexterm><primary>PQconnectdbParams</primary></indexterm></term>
+ <listitem>
+ <para>
+ Makes a new connection to the database server.
+
+<synopsis>
+PGconn *PQconnectdbParams(const char * const *keywords,
+ const char * const *values,
+ int expand_dbname);
+</synopsis>
+ </para>
+
+ <para>
+ This function opens a new database connection using the parameters taken
+ from two <symbol>NULL</symbol>-terminated arrays. The first,
+ <literal>keywords</literal>, is defined as an array of strings, each one
+ being a key word. The second, <literal>values</literal>, gives the value
+ for each key word. Unlike <xref linkend="libpq-PQsetdbLogin"/> below, the parameter
+ set can be extended without changing the function signature, so use of
+ this function (or its nonblocking analogs <xref linkend="libpq-PQconnectStartParams"/>
+ and <function>PQconnectPoll</function>) is preferred for new application
+ programming.
+ </para>
+
+ <para>
+ The currently recognized parameter key words are listed in
+ <xref linkend="libpq-paramkeywords"/>.
+ </para>
+
+ <para>
+ The passed arrays can be empty to use all default parameters, or can
+ contain one or more parameter settings. They must be matched in length.
+ Processing will stop at the first <symbol>NULL</symbol> entry
+ in the <literal>keywords</literal> array.
+ Also, if the <literal>values</literal> entry associated with a
+ non-<symbol>NULL</symbol> <literal>keywords</literal> entry is
+ <symbol>NULL</symbol> or an empty string, that entry is ignored and
+ processing continues with the next pair of array entries.
+ </para>
+
+ <para>
+ When <literal>expand_dbname</literal> is non-zero, the value for
+ the first <parameter>dbname</parameter> key word is checked to see
+ if it is a <firstterm>connection string</firstterm>. If so, it
+ is <quote>expanded</quote> into the individual connection
+ parameters extracted from the string. The value is considered to
+ be a connection string, rather than just a database name, if it
+ contains an equal sign (<literal>=</literal>) or it begins with a
+ URI scheme designator. (More details on connection string formats
+ appear in <xref linkend="libpq-connstring"/>.) Only the first
+ occurrence of <parameter>dbname</parameter> is treated in this way;
+ any subsequent <parameter>dbname</parameter> parameter is processed
+ as a plain database name.
+ </para>
+
+ <para>
+ In general the parameter arrays are processed from start to end.
+ If any key word is repeated, the last value (that is
+ not <symbol>NULL</symbol> or empty) is used. This rule applies in
+ particular when a key word found in a connection string conflicts
+ with one appearing in the <literal>keywords</literal> array. Thus,
+ the programmer may determine whether array entries can override or
+ be overridden by values taken from a connection string. Array
+ entries appearing before an expanded <parameter>dbname</parameter>
+ entry can be overridden by fields of the connection string, and in
+ turn those fields are overridden by array entries appearing
+ after <parameter>dbname</parameter> (but, again, only if those
+ entries supply non-empty values).
+ </para>
+
+ <para>
+ After processing all the array entries and any expanded connection
+ string, any connection parameters that remain unset are filled with
+ default values. If an unset parameter's corresponding environment
+ variable (see <xref linkend="libpq-envars"/>) is set, its value is
+ used. If the environment variable is not set either, then the
+ parameter's built-in default value is used.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconnectdb">
+ <term><function>PQconnectdb</function><indexterm><primary>PQconnectdb</primary></indexterm></term>
+ <listitem>
+ <para>
+ Makes a new connection to the database server.
+
+<synopsis>
+PGconn *PQconnectdb(const char *conninfo);
+</synopsis>
+ </para>
+
+ <para>
+ This function opens a new database connection using the parameters taken
+ from the string <literal>conninfo</literal>.
+ </para>
+
+ <para>
+ The passed string can be empty to use all default parameters, or it can
+ contain one or more parameter settings separated by whitespace,
+ or it can contain a <acronym>URI</acronym>.
+ See <xref linkend="libpq-connstring"/> for details.
+ </para>
+
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetdbLogin">
+ <term><function>PQsetdbLogin</function><indexterm><primary>PQsetdbLogin</primary></indexterm></term>
+ <listitem>
+ <para>
+ Makes a new connection to the database server.
+<synopsis>
+PGconn *PQsetdbLogin(const char *pghost,
+ const char *pgport,
+ const char *pgoptions,
+ const char *pgtty,
+ const char *dbName,
+ const char *login,
+ const char *pwd);
+</synopsis>
+ </para>
+
+ <para>
+ This is the predecessor of <xref linkend="libpq-PQconnectdb"/> with a fixed
+ set of parameters. It has the same functionality except that the
+ missing parameters will always take on default values. Write <symbol>NULL</symbol> or an
+ empty string for any one of the fixed parameters that is to be defaulted.
+ </para>
+
+ <para>
+ If the <parameter>dbName</parameter> contains
+ an <symbol>=</symbol> sign or has a valid connection <acronym>URI</acronym> prefix, it
+ is taken as a <parameter>conninfo</parameter> string in exactly the same way as
+ if it had been passed to <xref linkend="libpq-PQconnectdb"/>, and the remaining
+ parameters are then applied as specified for <xref linkend="libpq-PQconnectdbParams"/>.
+ </para>
+
+ <para>
+ <literal>pgtty</literal> is no longer used and any value passed will
+ be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetdb">
+ <term><function>PQsetdb</function><indexterm><primary>PQsetdb</primary></indexterm></term>
+ <listitem>
+ <para>
+ Makes a new connection to the database server.
+<synopsis>
+PGconn *PQsetdb(char *pghost,
+ char *pgport,
+ char *pgoptions,
+ char *pgtty,
+ char *dbName);
+</synopsis>
+ </para>
+
+ <para>
+ This is a macro that calls <xref linkend="libpq-PQsetdbLogin"/> with null pointers
+ for the <parameter>login</parameter> and <parameter>pwd</parameter> parameters. It is provided
+ for backward compatibility with very old programs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconnectStartParams">
+ <term><function>PQconnectStartParams</function><indexterm><primary>PQconnectStartParams</primary></indexterm></term>
+ <term><function>PQconnectStart</function><indexterm><primary>PQconnectStart</primary></indexterm></term>
+ <term><function>PQconnectPoll</function><indexterm><primary>PQconnectPoll</primary></indexterm></term>
+ <listitem>
+ <para>
+ <indexterm><primary>nonblocking connection</primary></indexterm>
+ Make a connection to the database server in a nonblocking manner.
+
+<synopsis>
+PGconn *PQconnectStartParams(const char * const *keywords,
+ const char * const *values,
+ int expand_dbname);
+
+PGconn *PQconnectStart(const char *conninfo);
+
+PostgresPollingStatusType PQconnectPoll(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ These three functions are used to open a connection to a database server such
+ that your application's thread of execution is not blocked on remote I/O
+ whilst doing so. The point of this approach is that the waits for I/O to
+ complete can occur in the application's main loop, rather than down inside
+ <xref linkend="libpq-PQconnectdbParams"/> or <xref linkend="libpq-PQconnectdb"/>, and so the
+ application can manage this operation in parallel with other activities.
+ </para>
+
+ <para>
+ With <xref linkend="libpq-PQconnectStartParams"/>, the database connection is made
+ using the parameters taken from the <literal>keywords</literal> and
+ <literal>values</literal> arrays, and controlled by <literal>expand_dbname</literal>,
+ as described above for <xref linkend="libpq-PQconnectdbParams"/>.
+ </para>
+
+ <para>
+ With <function>PQconnectStart</function>, the database connection is made
+ using the parameters taken from the string <literal>conninfo</literal> as
+ described above for <xref linkend="libpq-PQconnectdb"/>.
+ </para>
+
+ <para>
+ Neither <xref linkend="libpq-PQconnectStartParams"/> nor <function>PQconnectStart</function>
+ nor <function>PQconnectPoll</function> will block, so long as a number of
+ restrictions are met:
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <literal>hostaddr</literal> parameter must be used appropriately
+ to prevent DNS queries from being made. See the documentation of
+ this parameter in <xref linkend="libpq-paramkeywords"/> for details.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you call <xref linkend="libpq-PQtrace"/>, ensure that the stream object
+ into which you trace will not block.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You must ensure that the socket is in the appropriate state
+ before calling <function>PQconnectPoll</function>, as described below.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ To begin a nonblocking connection request,
+ call <function>PQconnectStart</function>
+ or <xref linkend="libpq-PQconnectStartParams"/>. If the result is null,
+ then <application>libpq</application> has been unable to allocate a
+ new <structname>PGconn</structname> structure. Otherwise, a
+ valid <structname>PGconn</structname> pointer is returned (though not
+ yet representing a valid connection to the database). Next
+ call <literal>PQstatus(conn)</literal>. If the result
+ is <symbol>CONNECTION_BAD</symbol>, the connection attempt has already
+ failed, typically because of invalid connection parameters.
+ </para>
+
+ <para>
+ If <function>PQconnectStart</function>
+ or <xref linkend="libpq-PQconnectStartParams"/> succeeds, the next stage
+ is to poll <application>libpq</application> so that it can proceed with
+ the connection sequence.
+ Use <function>PQsocket(conn)</function> to obtain the descriptor of the
+ socket underlying the database connection.
+ (Caution: do not assume that the socket remains the same
+ across <function>PQconnectPoll</function> calls.)
+ Loop thus: If <function>PQconnectPoll(conn)</function> last returned
+ <symbol>PGRES_POLLING_READING</symbol>, wait until the socket is ready to
+ read (as indicated by <function>select()</function>, <function>poll()</function>, or
+ similar system function).
+ Then call <function>PQconnectPoll(conn)</function> again.
+ Conversely, if <function>PQconnectPoll(conn)</function> last returned
+ <symbol>PGRES_POLLING_WRITING</symbol>, wait until the socket is ready
+ to write, then call <function>PQconnectPoll(conn)</function> again.
+ On the first iteration, i.e., if you have yet to call
+ <function>PQconnectPoll</function>, behave as if it last returned
+ <symbol>PGRES_POLLING_WRITING</symbol>. Continue this loop until
+ <function>PQconnectPoll(conn)</function> returns
+ <symbol>PGRES_POLLING_FAILED</symbol>, indicating the connection procedure
+ has failed, or <symbol>PGRES_POLLING_OK</symbol>, indicating the connection
+ has been successfully made.
+ </para>
+
+ <para>
+ At any time during connection, the status of the connection can be
+ checked by calling <xref linkend="libpq-PQstatus"/>. If this call returns <symbol>CONNECTION_BAD</symbol>, then the
+ connection procedure has failed; if the call returns <function>CONNECTION_OK</function>, then the
+ connection is ready. Both of these states are equally detectable
+ from the return value of <function>PQconnectPoll</function>, described above. Other states might also occur
+ during (and only during) an asynchronous connection procedure. These
+ indicate the current stage of the connection procedure and might be useful
+ to provide feedback to the user for example. These statuses are:
+
+ <variablelist>
+ <varlistentry id="libpq-connection-started">
+ <term><symbol>CONNECTION_STARTED</symbol></term>
+ <listitem>
+ <para>
+ Waiting for connection to be made.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-made">
+ <term><symbol>CONNECTION_MADE</symbol></term>
+ <listitem>
+ <para>
+ Connection OK; waiting to send.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-awaiting-response">
+ <term><symbol>CONNECTION_AWAITING_RESPONSE</symbol></term>
+ <listitem>
+ <para>
+ Waiting for a response from the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-auth-ok">
+ <term><symbol>CONNECTION_AUTH_OK</symbol></term>
+ <listitem>
+ <para>
+ Received authentication; waiting for backend start-up to finish.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-ssl-startup">
+ <term><symbol>CONNECTION_SSL_STARTUP</symbol></term>
+ <listitem>
+ <para>
+ Negotiating SSL encryption.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-setenv">
+ <term><symbol>CONNECTION_SETENV</symbol></term>
+ <listitem>
+ <para>
+ Negotiating environment-driven parameter settings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-check-writable">
+ <term><symbol>CONNECTION_CHECK_WRITABLE</symbol></term>
+ <listitem>
+ <para>
+ Checking if connection is able to handle write transactions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connection-consume">
+ <term><symbol>CONNECTION_CONSUME</symbol></term>
+ <listitem>
+ <para>
+ Consuming any remaining response messages on connection.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Note that, although these constants will remain (in order to maintain
+ compatibility), an application should never rely upon these occurring in a
+ particular order, or at all, or on the status always being one of these
+ documented values. An application might do something like this:
+<programlisting>
+switch(PQstatus(conn))
+{
+ case CONNECTION_STARTED:
+ feedback = "Connecting...";
+ break;
+
+ case CONNECTION_MADE:
+ feedback = "Connected to server...";
+ break;
+.
+.
+.
+ default:
+ feedback = "Connecting...";
+}
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>connect_timeout</literal> connection parameter is ignored
+ when using <function>PQconnectPoll</function>; it is the application's
+ responsibility to decide whether an excessive amount of time has elapsed.
+ Otherwise, <function>PQconnectStart</function> followed by a
+ <function>PQconnectPoll</function> loop is equivalent to
+ <xref linkend="libpq-PQconnectdb"/>.
+ </para>
+
+ <para>
+ Note that when <function>PQconnectStart</function>
+ or <xref linkend="libpq-PQconnectStartParams"/> returns a non-null
+ pointer, you must call <xref linkend="libpq-PQfinish"/> when you are
+ finished with it, in order to dispose of the structure and any
+ associated memory blocks. This must be done even if the connection
+ attempt fails or is abandoned.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconndefaults">
+ <term><function>PQconndefaults</function><indexterm><primary>PQconndefaults</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns the default connection options.
+<synopsis>
+PQconninfoOption *PQconndefaults(void);
+
+typedef struct
+{
+ char *keyword; /* The keyword of the option */
+ char *envvar; /* Fallback environment variable name */
+ char *compiled; /* Fallback compiled in default value */
+ char *val; /* Option's current value, or NULL */
+ char *label; /* Label for field in connect dialog */
+ char *dispchar; /* Indicates how to display this field
+ in a connect dialog. Values are:
+ "" Display entered value as is
+ "*" Password field - hide value
+ "D" Debug option - don't show by default */
+ int dispsize; /* Field size in characters for dialog */
+} PQconninfoOption;
+</synopsis>
+ </para>
+
+ <para>
+ Returns a connection options array. This can be used to determine
+ all possible <xref linkend="libpq-PQconnectdb"/> options and their
+ current default values. The return value points to an array of
+ <structname>PQconninfoOption</structname> structures, which ends
+ with an entry having a null <structfield>keyword</structfield> pointer. The
+ null pointer is returned if memory could not be allocated. Note that
+ the current default values (<structfield>val</structfield> fields)
+ will depend on environment variables and other context. A
+ missing or invalid service file will be silently ignored. Callers
+ must treat the connection options data as read-only.
+ </para>
+
+ <para>
+ After processing the options array, free it by passing it to
+ <xref linkend="libpq-PQconninfoFree"/>. If this is not done, a small amount of memory
+ is leaked for each call to <xref linkend="libpq-PQconndefaults"/>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconninfo">
+ <term><function>PQconninfo</function><indexterm><primary>PQconninfo</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns the connection options used by a live connection.
+<synopsis>
+PQconninfoOption *PQconninfo(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ Returns a connection options array. This can be used to determine
+ all possible <xref linkend="libpq-PQconnectdb"/> options and the
+ values that were used to connect to the server. The return
+ value points to an array of <structname>PQconninfoOption</structname>
+ structures, which ends with an entry having a null <structfield>keyword</structfield>
+ pointer. All notes above for <xref linkend="libpq-PQconndefaults"/> also
+ apply to the result of <xref linkend="libpq-PQconninfo"/>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="libpq-PQconninfoParse">
+ <term><function>PQconninfoParse</function><indexterm><primary>PQconninfoParse</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns parsed connection options from the provided connection string.
+
+<synopsis>
+PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg);
+</synopsis>
+ </para>
+
+ <para>
+ Parses a connection string and returns the resulting options as an
+ array; or returns <symbol>NULL</symbol> if there is a problem with the connection
+ string. This function can be used to extract
+ the <xref linkend="libpq-PQconnectdb"/> options in the provided
+ connection string. The return value points to an array of
+ <structname>PQconninfoOption</structname> structures, which ends
+ with an entry having a null <structfield>keyword</structfield> pointer.
+ </para>
+
+ <para>
+ All legal options will be present in the result array, but the
+ <literal>PQconninfoOption</literal> for any option not present
+ in the connection string will have <literal>val</literal> set to
+ <literal>NULL</literal>; default values are not inserted.
+ </para>
+
+ <para>
+ If <literal>errmsg</literal> is not <symbol>NULL</symbol>, then <literal>*errmsg</literal> is set
+ to <symbol>NULL</symbol> on success, else to a <function>malloc</function>'d error string explaining
+ the problem. (It is also possible for <literal>*errmsg</literal> to be
+ set to <symbol>NULL</symbol> and the function to return <symbol>NULL</symbol>;
+ this indicates an out-of-memory condition.)
+ </para>
+
+ <para>
+ After processing the options array, free it by passing it to
+ <xref linkend="libpq-PQconninfoFree"/>. If this is not done, some memory
+ is leaked for each call to <xref linkend="libpq-PQconninfoParse"/>.
+ Conversely, if an error occurs and <literal>errmsg</literal> is not <symbol>NULL</symbol>,
+ be sure to free the error string using <xref linkend="libpq-PQfreemem"/>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfinish">
+ <term><function>PQfinish</function><indexterm><primary>PQfinish</primary></indexterm></term>
+ <listitem>
+ <para>
+ Closes the connection to the server. Also frees
+ memory used by the <structname>PGconn</structname> object.
+<synopsis>
+void PQfinish(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ Note that even if the server connection attempt fails (as
+ indicated by <xref linkend="libpq-PQstatus"/>), the application should call <xref linkend="libpq-PQfinish"/>
+ to free the memory used by the <structname>PGconn</structname> object.
+ The <structname>PGconn</structname> pointer must not be used again after
+ <xref linkend="libpq-PQfinish"/> has been called.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQreset">
+ <term><function>PQreset</function><indexterm><primary>PQreset</primary></indexterm></term>
+ <listitem>
+ <para>
+ Resets the communication channel to the server.
+<synopsis>
+void PQreset(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ This function will close the connection
+ to the server and attempt to establish a new
+ connection, using all the same
+ parameters previously used. This might be useful for
+ error recovery if a working connection is lost.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresetStart">
+ <term><function>PQresetStart</function><indexterm><primary>PQresetStart</primary></indexterm></term>
+ <term><function>PQresetPoll</function><indexterm><primary>PQresetPoll</primary></indexterm></term>
+ <listitem>
+ <para>
+ Reset the communication channel to the server, in a nonblocking manner.
+
+<synopsis>
+int PQresetStart(PGconn *conn);
+
+PostgresPollingStatusType PQresetPoll(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ These functions will close the connection to the server and attempt to
+ establish a new connection, using all the same
+ parameters previously used. This can be useful for error recovery if a
+ working connection is lost. They differ from <xref linkend="libpq-PQreset"/> (above) in that they
+ act in a nonblocking manner. These functions suffer from the same
+ restrictions as <xref linkend="libpq-PQconnectStartParams"/>, <function>PQconnectStart</function>
+ and <function>PQconnectPoll</function>.
+ </para>
+
+ <para>
+ To initiate a connection reset, call
+ <xref linkend="libpq-PQresetStart"/>. If it returns 0, the reset has
+ failed. If it returns 1, poll the reset using
+ <function>PQresetPoll</function> in exactly the same way as you
+ would create the connection using <function>PQconnectPoll</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQpingParams">
+ <term><function>PQpingParams</function><indexterm><primary>PQpingParams</primary></indexterm></term>
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQpingParams"/> reports the status of the
+ server. It accepts connection parameters identical to those of
+ <xref linkend="libpq-PQconnectdbParams"/>, described above. It is not
+ necessary to supply correct user name, password, or database name
+ values to obtain the server status; however, if incorrect values
+ are provided, the server will log a failed connection attempt.
+
+<synopsis>
+PGPing PQpingParams(const char * const *keywords,
+ const char * const *values,
+ int expand_dbname);
+</synopsis>
+
+ The function returns one of the following values:
+
+ <variablelist>
+ <varlistentry id="libpq-PQpingParams-PQPING_OK">
+ <term><literal>PQPING_OK</literal></term>
+ <listitem>
+ <para>
+ The server is running and appears to be accepting connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQpingParams-PQPING_REJECT">
+ <term><literal>PQPING_REJECT</literal></term>
+ <listitem>
+ <para>
+ The server is running but is in a state that disallows connections
+ (startup, shutdown, or crash recovery).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQpingParams-PQPING_NO_RESPONSE">
+ <term><literal>PQPING_NO_RESPONSE</literal></term>
+ <listitem>
+ <para>
+ The server could not be contacted. This might indicate that the
+ server is not running, or that there is something wrong with the
+ given connection parameters (for example, wrong port number), or
+ that there is a network connectivity problem (for example, a
+ firewall blocking the connection request).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQpingParams-PQPING_NO_ATTEMPT">
+ <term><literal>PQPING_NO_ATTEMPT</literal></term>
+ <listitem>
+ <para>
+ No attempt was made to contact the server, because the supplied
+ parameters were obviously incorrect or there was some client-side
+ problem (for example, out of memory).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQping">
+ <term><function>PQping</function><indexterm><primary>PQping</primary></indexterm></term>
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQping"/> reports the status of the
+ server. It accepts connection parameters identical to those of
+ <xref linkend="libpq-PQconnectdb"/>, described above. It is not
+ necessary to supply correct user name, password, or database name
+ values to obtain the server status; however, if incorrect values
+ are provided, the server will log a failed connection attempt.
+
+<synopsis>
+PGPing PQping(const char *conninfo);
+</synopsis>
+ </para>
+
+ <para>
+ The return values are the same as for <xref linkend="libpq-PQpingParams"/>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pqsetsslkeypasshook-openssl">
+ <term><function>PQsetSSLKeyPassHook_OpenSSL</function><indexterm><primary>PQsetSSLKeyPassHook_OpenSSL</primary></indexterm></term>
+ <listitem>
+ <para>
+ <function>PQsetSSLKeyPassHook_OpenSSL</function> lets an application override
+ <application>libpq</application>'s <link linkend="libpq-ssl-clientcert">default
+ handling of encrypted client certificate key files</link> using
+ <xref linkend="libpq-connect-sslpassword"/> or interactive prompting.
+
+<synopsis>
+void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook);
+</synopsis>
+
+ The application passes a pointer to a callback function with signature:
+<programlisting>
+int callback_fn(char *buf, int size, PGconn *conn);
+</programlisting>
+ which <application>libpq</application> will then call
+ <emphasis>instead of</emphasis> its default
+ <function>PQdefaultSSLKeyPassHook_OpenSSL</function> handler. The
+ callback should determine the password for the key and copy it to
+ result-buffer <parameter>buf</parameter> of size
+ <parameter>size</parameter>. The string in <parameter>buf</parameter>
+ must be null-terminated. The callback must return the length of the
+ password stored in <parameter>buf</parameter> excluding the null
+ terminator. On failure, the callback should set
+ <literal>buf[0] = '\0'</literal> and return 0. See
+ <function>PQdefaultSSLKeyPassHook_OpenSSL</function> in
+ <application>libpq</application>'s source code for an example.
+ </para>
+
+ <para>
+ If the user specified an explicit key location,
+ its path will be in <literal>conn->sslkey</literal> when the callback
+ is invoked. This will be empty if the default key path is being used.
+ For keys that are engine specifiers, it is up to engine implementations
+ whether they use the <productname>OpenSSL</productname> password
+ callback or define their own handling.
+ </para>
+
+ <para>
+ The app callback may choose to delegate unhandled cases to
+ <function>PQdefaultSSLKeyPassHook_OpenSSL</function>,
+ or call it first and try something else if it returns 0, or completely override it.
+ </para>
+
+ <para>
+ The callback <emphasis>must not</emphasis> escape normal flow control with exceptions,
+ <function>longjmp(...)</function>, etc. It must return normally.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pqgetsslkeypasshook-openssl">
+ <term><function>PQgetSSLKeyPassHook_OpenSSL</function><indexterm><primary>PQgetSSLKeyPassHook_OpenSSL</primary></indexterm></term>
+ <listitem>
+ <para>
+ <function>PQgetSSLKeyPassHook_OpenSSL</function> returns the current
+ client certificate key password hook, or <literal>NULL</literal>
+ if none has been set.
+
+<synopsis>
+PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void);
+</synopsis>
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <sect2 id="libpq-connstring">
+ <title>Connection Strings</title>
+
+ <indexterm zone="libpq-connstring">
+ <primary><literal>conninfo</literal></primary>
+ </indexterm>
+
+ <indexterm zone="libpq-connstring">
+ <primary><literal>URI</literal></primary>
+ </indexterm>
+
+ <para>
+ Several <application>libpq</application> functions parse a user-specified string to obtain
+ connection parameters. There are two accepted formats for these strings:
+ plain keyword/value strings
+ and URIs. URIs generally follow
+ <ulink url="https://tools.ietf.org/html/rfc3986">RFC
+ 3986</ulink>, except that multi-host connection strings are allowed
+ as further described below.
+ </para>
+
+ <sect3>
+ <title>Keyword/Value Connection Strings</title>
+
+ <para>
+ In the keyword/value format, each parameter setting is in the form
+ <replaceable>keyword</replaceable> <literal>=</literal>
+ <replaceable>value</replaceable>, with space(s) between settings.
+ Spaces around a setting's equal sign are
+ optional. To write an empty value, or a value containing spaces, surround it
+ with single quotes, for example <literal>keyword = 'a value'</literal>.
+ Single quotes and backslashes within
+ a value must be escaped with a backslash, i.e., <literal>\'</literal> and
+ <literal>\\</literal>.
+ </para>
+
+ <para>
+ Example:
+<programlisting>
+host=localhost port=5432 dbname=mydb connect_timeout=10
+</programlisting>
+ </para>
+
+ <para>
+ The recognized parameter key words are listed in <xref
+ linkend="libpq-paramkeywords"/>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Connection URIs</title>
+
+ <para>
+ The general form for a connection <acronym>URI</acronym> is:
+<synopsis>
+postgresql://<optional><replaceable>userspec</replaceable>@</optional><optional><replaceable>hostspec</replaceable></optional><optional>/<replaceable>dbname</replaceable></optional><optional>?<replaceable>paramspec</replaceable></optional>
+
+<phrase>where <replaceable>userspec</replaceable> is:</phrase>
+
+<replaceable>user</replaceable><optional>:<replaceable>password</replaceable></optional>
+
+<phrase>and <replaceable>hostspec</replaceable> is:</phrase>
+
+<optional><replaceable>host</replaceable></optional><optional>:<replaceable>port</replaceable></optional><optional>,...</optional>
+
+<phrase>and <replaceable>paramspec</replaceable> is:</phrase>
+
+<replaceable>name</replaceable>=<replaceable>value</replaceable><optional>&amp;...</optional>
+</synopsis>
+ </para>
+
+ <para>
+ The <acronym>URI</acronym> scheme designator can be either
+ <literal>postgresql://</literal> or <literal>postgres://</literal>. Each
+ of the remaining <acronym>URI</acronym> parts is optional. The
+ following examples illustrate valid <acronym>URI</acronym> syntax:
+<programlisting>
+postgresql://
+postgresql://localhost
+postgresql://localhost:5433
+postgresql://localhost/mydb
+postgresql://user@localhost
+postgresql://user:secret@localhost
+postgresql://other@localhost/otherdb?connect_timeout=10&amp;application_name=myapp
+postgresql://host1:123,host2:456/somedb?target_session_attrs=any&amp;application_name=myapp
+</programlisting>
+ Values that would normally appear in the hierarchical part of
+ the <acronym>URI</acronym> can alternatively be given as named
+ parameters. For example:
+<programlisting>
+postgresql:///mydb?host=localhost&amp;port=5433
+</programlisting>
+ All named parameters must match key words listed in
+ <xref linkend="libpq-paramkeywords"/>, except that for compatibility
+ with JDBC connection <acronym>URI</acronym>s, instances
+ of <literal>ssl=true</literal> are translated into
+ <literal>sslmode=require</literal>.
+ </para>
+
+ <para>
+ The connection <acronym>URI</acronym> needs to be encoded with <ulink
+ url="https://tools.ietf.org/html/rfc3986#section-2.1">percent-encoding</ulink>
+ if it includes symbols with special meaning in any of its parts. Here is
+ an example where the equal sign (<literal>=</literal>) is replaced with
+ <literal>%3D</literal> and the space character with
+ <literal>%20</literal>:
+<programlisting>
+postgresql://user@localhost:5433/mydb?options=-c%20synchronous_commit%3Doff
+</programlisting>
+ </para>
+
+ <para>
+ The host part may be either a host name or an IP address. To specify an
+ IPv6 address, enclose it in square brackets:
+<synopsis>
+postgresql://[2001:db8::1234]/database
+</synopsis>
+ </para>
+
+ <para>
+ The host part is interpreted as described for the parameter <xref
+ linkend="libpq-connect-host"/>. In particular, a Unix-domain socket
+ connection is chosen if the host part is either empty or looks like an
+ absolute path name,
+ otherwise a TCP/IP connection is initiated. Note, however, that the
+ slash is a reserved character in the hierarchical part of the URI. So, to
+ specify a non-standard Unix-domain socket directory, either omit the host
+ part of the URI and specify the host as a named parameter, or
+ percent-encode the path in the host part of the URI:
+<programlisting>
+postgresql:///dbname?host=/var/lib/postgresql
+postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
+</programlisting>
+ </para>
+
+ <para>
+ It is possible to specify multiple host components, each with an optional
+ port component, in a single URI. A URI of the form
+ <literal>postgresql://host1:port1,host2:port2,host3:port3/</literal>
+ is equivalent to a connection string of the form
+ <literal>host=host1,host2,host3 port=port1,port2,port3</literal>.
+ As further described below, each
+ host will be tried in turn until a connection is successfully established.
+ </para>
+ </sect3>
+
+ <sect3 id="libpq-multiple-hosts">
+ <title>Specifying Multiple Hosts</title>
+
+ <para>
+ It is possible to specify multiple hosts to connect to, so that they are
+ tried in the given order. In the Keyword/Value format, the <literal>host</literal>,
+ <literal>hostaddr</literal>, and <literal>port</literal> options accept comma-separated
+ lists of values. The same number of elements must be given in each
+ option that is specified, such
+ that e.g., the first <literal>hostaddr</literal> corresponds to the first host name,
+ the second <literal>hostaddr</literal> corresponds to the second host name, and so
+ forth. As an exception, if only one <literal>port</literal> is specified, it
+ applies to all the hosts.
+ </para>
+
+ <para>
+ In the connection URI format, you can list multiple <literal>host:port</literal> pairs
+ separated by commas in the <literal>host</literal> component of the URI.
+ </para>
+
+ <para>
+ In either format, a single host name can translate to multiple network
+ addresses. A common example of this is a host that has both an IPv4 and
+ an IPv6 address.
+ </para>
+
+ <para>
+ When multiple hosts are specified, or when a single host name is
+ translated to multiple addresses, all the hosts and addresses will be
+ tried in order, until one succeeds. If none of the hosts can be reached,
+ the connection fails. If a connection is established successfully, but
+ authentication fails, the remaining hosts in the list are not tried.
+ </para>
+
+ <para>
+ If a password file is used, you can have different passwords for
+ different hosts. All the other connection options are the same for every
+ host in the list; it is not possible to e.g., specify different
+ usernames for different hosts.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="libpq-paramkeywords">
+ <title>Parameter Key Words</title>
+
+ <para>
+ The currently recognized parameter key words are:
+
+ <variablelist>
+ <varlistentry id="libpq-connect-host" xreflabel="host">
+ <term><literal>host</literal></term>
+ <listitem>
+ <para>
+ Name of host to connect to.<indexterm><primary>host
+ name</primary></indexterm> If a host name looks like an absolute path
+ name, it specifies Unix-domain communication rather than TCP/IP
+ communication; the value is the name of the directory in which the
+ socket file is stored. (On Unix, an absolute path name begins with a
+ slash. On Windows, paths starting with drive letters are also
+ recognized.) If the host name starts with <literal>@</literal>, it is
+ taken as a Unix-domain socket in the abstract namespace (currently
+ supported on Linux and Windows).
+ The default behavior when <literal>host</literal> is not
+ specified, or is empty, is to connect to a Unix-domain
+ socket<indexterm><primary>Unix domain socket</primary></indexterm> in
+ <filename>/tmp</filename> (or whatever socket directory was specified
+ when <productname>PostgreSQL</productname> was built). On Windows and
+ on machines without Unix-domain sockets, the default is to connect to
+ <literal>localhost</literal>.
+ </para>
+ <para>
+ A comma-separated list of host names is also accepted, in which case
+ each host name in the list is tried in order; an empty item in the
+ list selects the default behavior as explained above. See
+ <xref linkend="libpq-multiple-hosts"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-hostaddr" xreflabel="hostaddr">
+ <term><literal>hostaddr</literal></term>
+ <listitem>
+ <para>
+ Numeric IP address of host to connect to. This should be in the
+ standard IPv4 address format, e.g., <literal>172.28.40.9</literal>. If
+ your machine supports IPv6, you can also use those addresses.
+ TCP/IP communication is
+ always used when a nonempty string is specified for this parameter.
+ If this parameter is not specified, the value of <literal>host</literal>
+ will be looked up to find the corresponding IP address &mdash; or, if
+ <literal>host</literal> specifies an IP address, that value will be
+ used directly.
+ </para>
+
+ <para>
+ Using <literal>hostaddr</literal> allows the
+ application to avoid a host name look-up, which might be important
+ in applications with time constraints. However, a host name is
+ required for GSSAPI or SSPI authentication
+ methods, as well as for <literal>verify-full</literal> SSL
+ certificate verification. The following rules are used:
+ <itemizedlist>
+ <listitem>
+ <para>
+ If <literal>host</literal> is specified
+ without <literal>hostaddr</literal>, a host name lookup occurs.
+ (When using <function>PQconnectPoll</function>, the lookup occurs
+ when <function>PQconnectPoll</function> first considers this host
+ name, and it may cause <function>PQconnectPoll</function> to block
+ for a significant amount of time.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If <literal>hostaddr</literal> is specified without <literal>host</literal>,
+ the value for <literal>hostaddr</literal> gives the server network address.
+ The connection attempt will fail if the authentication
+ method requires a host name.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If both <literal>host</literal> and <literal>hostaddr</literal> are specified,
+ the value for <literal>hostaddr</literal> gives the server network address.
+ The value for <literal>host</literal> is ignored unless the
+ authentication method requires it, in which case it will be
+ used as the host name.
+ </para>
+ </listitem>
+ </itemizedlist>
+ Note that authentication is likely to fail if <literal>host</literal>
+ is not the name of the server at network address <literal>hostaddr</literal>.
+ Also, when both <literal>host</literal> and <literal>hostaddr</literal>
+ are specified, <literal>host</literal>
+ is used to identify the connection in a password file (see
+ <xref linkend="libpq-pgpass"/>).
+ </para>
+
+ <para>
+ A comma-separated list of <literal>hostaddr</literal> values is also
+ accepted, in which case each host in the list is tried in order.
+ An empty item in the list causes the corresponding host name to be
+ used, or the default host name if that is empty as well. See
+ <xref linkend="libpq-multiple-hosts"/> for details.
+ </para>
+ <para>
+ Without either a host name or host address,
+ <application>libpq</application> will connect using a local
+ Unix-domain socket; or on Windows and on machines without Unix-domain
+ sockets, it will attempt to connect to <literal>localhost</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-port" xreflabel="port">
+ <term><literal>port</literal></term>
+ <listitem>
+ <para>
+ Port number to connect to at the server host, or socket file
+ name extension for Unix-domain
+ connections.<indexterm><primary>port</primary></indexterm>
+ If multiple hosts were given in the <literal>host</literal> or
+ <literal>hostaddr</literal> parameters, this parameter may specify a
+ comma-separated list of ports of the same length as the host list, or
+ it may specify a single port number to be used for all hosts.
+ An empty string, or an empty item in a comma-separated list,
+ specifies the default port number established
+ when <productname>PostgreSQL</productname> was built.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-dbname" xreflabel="dbname">
+ <term><literal>dbname</literal></term>
+ <listitem>
+ <para>
+ The database name. Defaults to be the same as the user name.
+ In certain contexts, the value is checked for extended
+ formats; see <xref linkend="libpq-connstring"/> for more details on
+ those.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-user" xreflabel="user">
+ <term><literal>user</literal></term>
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> user name to connect as.
+ Defaults to be the same as the operating system name of the user
+ running the application.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-password" xreflabel="password">
+ <term><literal>password</literal></term>
+ <listitem>
+ <para>
+ Password to be used if the server demands password authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-passfile" xreflabel="passfile">
+ <term><literal>passfile</literal></term>
+ <listitem>
+ <para>
+ Specifies the name of the file used to store passwords
+ (see <xref linkend="libpq-pgpass"/>).
+ Defaults to <filename>~/.pgpass</filename>, or
+ <filename>%APPDATA%\postgresql\pgpass.conf</filename> on Microsoft Windows.
+ (No error is reported if this file does not exist.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-channel-binding" xreflabel="channel_binding">
+ <term><literal>channel_binding</literal></term>
+ <listitem>
+ <para>
+ This option controls the client's use of channel binding. A setting
+ of <literal>require</literal> means that the connection must employ
+ channel binding, <literal>prefer</literal> means that the client will
+ choose channel binding if available, and <literal>disable</literal>
+ prevents the use of channel binding. The default
+ is <literal>prefer</literal> if
+ <productname>PostgreSQL</productname> is compiled with SSL support;
+ otherwise the default is <literal>disable</literal>.
+ </para>
+ <para>
+ Channel binding is a method for the server to authenticate itself to
+ the client. It is only supported over SSL connections
+ with <productname>PostgreSQL</productname> 11 or later servers using
+ the <literal>SCRAM</literal> authentication method.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-connect-timeout" xreflabel="connect_timeout">
+ <term><literal>connect_timeout</literal></term>
+ <listitem>
+ <para>
+ Maximum time to wait while connecting, in seconds (write as a decimal integer,
+ e.g., <literal>10</literal>). Zero, negative, or not specified means
+ wait indefinitely. The minimum allowed timeout is 2 seconds, therefore
+ a value of <literal>1</literal> is interpreted as <literal>2</literal>.
+ This timeout applies separately to each host name or IP address.
+ For example, if you specify two hosts and <literal>connect_timeout</literal>
+ is 5, each host will time out if no connection is made within 5
+ seconds, so the total time spent waiting for a connection might be
+ up to 10 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-client-encoding" xreflabel="client_encoding">
+ <term><literal>client_encoding</literal></term>
+ <listitem>
+ <para>
+ This sets the <varname>client_encoding</varname>
+ configuration parameter for this connection. In addition to
+ the values accepted by the corresponding server option, you
+ can use <literal>auto</literal> to determine the right
+ encoding from the current locale in the client
+ (<envar>LC_CTYPE</envar> environment variable on Unix
+ systems).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-options" xreflabel="options">
+ <term><literal>options</literal></term>
+ <listitem>
+ <para>
+ Specifies command-line options to send to the server at connection
+ start. For example, setting this to <literal>-c geqo=off</literal> sets the
+ session's value of the <varname>geqo</varname> parameter to
+ <literal>off</literal>. Spaces within this string are considered to
+ separate command-line arguments, unless escaped with a backslash
+ (<literal>\</literal>); write <literal>\\</literal> to represent a literal
+ backslash. For a detailed discussion of the available
+ options, consult <xref linkend="runtime-config"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-application-name" xreflabel="application_name">
+ <term><literal>application_name</literal></term>
+ <listitem>
+ <para>
+ Specifies a value for the <xref linkend="guc-application-name"/>
+ configuration parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-fallback-application-name" xreflabel="fallback_application_name">
+ <term><literal>fallback_application_name</literal></term>
+ <listitem>
+ <para>
+ Specifies a fallback value for the <xref
+ linkend="guc-application-name"/> configuration parameter.
+ This value will be used if no value has been given for
+ <literal>application_name</literal> via a connection parameter or the
+ <envar>PGAPPNAME</envar> environment variable. Specifying
+ a fallback name is useful in generic utility programs that
+ wish to set a default application name but allow it to be
+ overridden by the user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-keepalives" xreflabel="keepalives">
+ <term><literal>keepalives</literal></term>
+ <listitem>
+ <para>
+ Controls whether client-side TCP keepalives are used. The default
+ value is 1, meaning on, but you can change this to 0, meaning off,
+ if keepalives are not wanted. This parameter is ignored for
+ connections made via a Unix-domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-keepalives-idle" xreflabel="keepalives_idle">
+ <term><literal>keepalives_idle</literal></term>
+ <listitem>
+ <para>
+ Controls the number of seconds of inactivity after which TCP should
+ send a keepalive message to the server. A value of zero uses the
+ system default. This parameter is ignored for connections made via a
+ Unix-domain socket, or if keepalives are disabled.
+ It is only supported on systems where <symbol>TCP_KEEPIDLE</symbol> or
+ an equivalent socket option is available, and on Windows; on other
+ systems, it has no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-keepalives-interval" xreflabel="keepalives_interval">
+ <term><literal>keepalives_interval</literal></term>
+ <listitem>
+ <para>
+ Controls the number of seconds after which a TCP keepalive message
+ that is not acknowledged by the server should be retransmitted. A
+ value of zero uses the system default. This parameter is ignored for
+ connections made via a Unix-domain socket, or if keepalives are disabled.
+ It is only supported on systems where <symbol>TCP_KEEPINTVL</symbol> or
+ an equivalent socket option is available, and on Windows; on other
+ systems, it has no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-keepalives-count" xreflabel="keepalives_count">
+ <term><literal>keepalives_count</literal></term>
+ <listitem>
+ <para>
+ Controls the number of TCP keepalives that can be lost before the
+ client's connection to the server is considered dead. A value of
+ zero uses the system default. This parameter is ignored for
+ connections made via a Unix-domain socket, or if keepalives are disabled.
+ It is only supported on systems where <symbol>TCP_KEEPCNT</symbol> or
+ an equivalent socket option is available; on other systems, it has no
+ effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-tcp-user-timeout" xreflabel="tcp_user_timeout">
+ <term><literal>tcp_user_timeout</literal></term>
+ <listitem>
+ <para>
+ Controls the number of milliseconds that transmitted data may
+ remain unacknowledged before a connection is forcibly closed.
+ A value of zero uses the system default. This parameter is
+ ignored for connections made via a Unix-domain socket.
+ It is only supported on systems where <symbol>TCP_USER_TIMEOUT</symbol>
+ is available; on other systems, it has no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-replication" xreflabel="replication">
+ <term><literal>replication</literal></term>
+ <listitem>
+ <para>
+ This option determines whether the connection should use the
+ replication protocol instead of the normal protocol. This is what
+ PostgreSQL replication connections as well as tools such as
+ <application>pg_basebackup</application> use internally, but it can
+ also be used by third-party applications. For a description of the
+ replication protocol, consult <xref linkend="protocol-replication"/>.
+ </para>
+
+ <para>
+ The following values, which are case-insensitive, are supported:
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>true</literal>, <literal>on</literal>,
+ <literal>yes</literal>, <literal>1</literal>
+ </term>
+ <listitem>
+ <para>
+ The connection goes into physical replication mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>database</literal></term>
+ <listitem>
+ <para>
+ The connection goes into logical replication mode, connecting to
+ the database specified in the <literal>dbname</literal> parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>false</literal>, <literal>off</literal>,
+ <literal>no</literal>, <literal>0</literal>
+ </term>
+ <listitem>
+ <para>
+ The connection is a regular one, which is the default behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ In physical or logical replication mode, only the simple query protocol
+ can be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-gssencmode" xreflabel="gssencmode">
+ <term><literal>gssencmode</literal></term>
+ <listitem>
+ <para>
+ This option determines whether or with what priority a secure
+ <acronym>GSS</acronym> TCP/IP connection will be negotiated with the
+ server. There are three modes:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>disable</literal></term>
+ <listitem>
+ <para>
+ only try a non-<acronym>GSSAPI</acronym>-encrypted connection
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>prefer</literal> (default)</term>
+ <listitem>
+ <para>
+ if there are <acronym>GSSAPI</acronym> credentials present (i.e.,
+ in a credentials cache), first try
+ a <acronym>GSSAPI</acronym>-encrypted connection; if that fails or
+ there are no credentials, try a
+ non-<acronym>GSSAPI</acronym>-encrypted connection. This is the
+ default when <productname>PostgreSQL</productname> has been
+ compiled with <acronym>GSSAPI</acronym> support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>require</literal></term>
+ <listitem>
+ <para>
+ only try a <acronym>GSSAPI</acronym>-encrypted connection
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <literal>gssencmode</literal> is ignored for Unix domain socket
+ communication. If <productname>PostgreSQL</productname> is compiled
+ without GSSAPI support, using the <literal>require</literal> option
+ will cause an error, while <literal>prefer</literal> will be accepted
+ but <application>libpq</application> will not actually attempt
+ a <acronym>GSSAPI</acronym>-encrypted
+ connection.<indexterm><primary>GSSAPI</primary><secondary sortas="libpq">with
+ libpq</secondary></indexterm>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslmode" xreflabel="sslmode">
+ <term><literal>sslmode</literal></term>
+ <listitem>
+ <para>
+ This option determines whether or with what priority a secure
+ <acronym>SSL</acronym> TCP/IP connection will be negotiated with the
+ server. There are six modes:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>disable</literal></term>
+ <listitem>
+ <para>
+ only try a non-<acronym>SSL</acronym> connection
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>allow</literal></term>
+ <listitem>
+ <para>
+ first try a non-<acronym>SSL</acronym> connection; if that
+ fails, try an <acronym>SSL</acronym> connection
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>prefer</literal> (default)</term>
+ <listitem>
+ <para>
+ first try an <acronym>SSL</acronym> connection; if that fails,
+ try a non-<acronym>SSL</acronym> connection
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>require</literal></term>
+ <listitem>
+ <para>
+ only try an <acronym>SSL</acronym> connection. If a root CA
+ file is present, verify the certificate in the same way as
+ if <literal>verify-ca</literal> was specified
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>verify-ca</literal></term>
+ <listitem>
+ <para>
+ only try an <acronym>SSL</acronym> connection, and verify that
+ the server certificate is issued by a trusted
+ certificate authority (<acronym>CA</acronym>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>verify-full</literal></term>
+ <listitem>
+ <para>
+ only try an <acronym>SSL</acronym> connection, verify that the
+ server certificate is issued by a
+ trusted <acronym>CA</acronym> and that the requested server host name
+ matches that in the certificate
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ See <xref linkend="libpq-ssl"/> for a detailed description of how
+ these options work.
+ </para>
+
+ <para>
+ <literal>sslmode</literal> is ignored for Unix domain socket
+ communication.
+ If <productname>PostgreSQL</productname> is compiled without SSL support,
+ using options <literal>require</literal>, <literal>verify-ca</literal>, or
+ <literal>verify-full</literal> will cause an error, while
+ options <literal>allow</literal> and <literal>prefer</literal> will be
+ accepted but <application>libpq</application> will not actually attempt
+ an <acronym>SSL</acronym>
+ connection.<indexterm><primary>SSL</primary><secondary
+ sortas="libpq">with libpq</secondary></indexterm>
+ </para>
+
+ <para>
+ Note that if <acronym>GSSAPI</acronym> encryption is possible,
+ that will be used in preference to <acronym>SSL</acronym>
+ encryption, regardless of the value of <literal>sslmode</literal>.
+ To force use of <acronym>SSL</acronym> encryption in an
+ environment that has working <acronym>GSSAPI</acronym>
+ infrastructure (such as a Kerberos server), also
+ set <literal>gssencmode</literal> to <literal>disable</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-requiressl" xreflabel="requiressl">
+ <term><literal>requiressl</literal></term>
+ <listitem>
+ <para>
+ This option is deprecated in favor of the <literal>sslmode</literal>
+ setting.
+ </para>
+
+ <para>
+ If set to 1, an <acronym>SSL</acronym> connection to the server
+ is required (this is equivalent to <literal>sslmode</literal>
+ <literal>require</literal>). <application>libpq</application> will then refuse
+ to connect if the server does not accept an
+ <acronym>SSL</acronym> connection. If set to 0 (default),
+ <application>libpq</application> will negotiate the connection type with
+ the server (equivalent to <literal>sslmode</literal>
+ <literal>prefer</literal>). This option is only available if
+ <productname>PostgreSQL</productname> is compiled with SSL support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslcompression" xreflabel="sslcompression">
+ <term><literal>sslcompression</literal></term>
+ <listitem>
+ <para>
+ If set to 1, data sent over SSL connections will be compressed. If
+ set to 0, compression will be disabled. The default is 0. This
+ parameter is ignored if a connection without SSL is made.
+ </para>
+
+ <para>
+ SSL compression is nowadays considered insecure and its use is no
+ longer recommended. <productname>OpenSSL</productname> 1.1.0 disables
+ compression by default, and many operating system distributions
+ disable it in prior versions as well, so setting this parameter to on
+ will not have any effect if the server does not accept compression.
+ <productname>PostgreSQL</productname> 14 disables compression
+ completely in the backend.
+ </para>
+
+ <para>
+ If security is not a primary concern, compression can improve
+ throughput if the network is the bottleneck. Disabling compression
+ can improve response time and throughput if CPU performance is the
+ limiting factor.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslcert" xreflabel="sslcert">
+ <term><literal>sslcert</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the file name of the client SSL
+ certificate, replacing the default
+ <filename>~/.postgresql/postgresql.crt</filename>.
+ This parameter is ignored if an SSL connection is not made.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslkey" xreflabel="sslkey">
+ <term><literal>sslkey</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the location for the secret key used for
+ the client certificate. It can either specify a file name that will
+ be used instead of the default
+ <filename>~/.postgresql/postgresql.key</filename>, or it can specify a key
+ obtained from an external <quote>engine</quote> (engines are
+ <productname>OpenSSL</productname> loadable modules). An external engine
+ specification should consist of a colon-separated engine name and
+ an engine-specific key identifier. This parameter is ignored if an
+ SSL connection is not made.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslpassword" xreflabel="sslpassword">
+ <term><literal>sslpassword</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the password for the secret key specified in
+ <literal>sslkey</literal>, allowing client certificate private keys
+ to be stored in encrypted form on disk even when interactive passphrase
+ input is not practical.
+ </para>
+ <para>
+ Specifying this parameter with any non-empty value suppresses the
+ <literal>Enter PEM pass phrase:</literal>
+ prompt that <productname>OpenSSL</productname> will emit by default
+ when an encrypted client certificate key is provided to
+ <literal>libpq</literal>.
+ </para>
+ <para>
+ If the key is not encrypted this parameter is ignored. The parameter
+ has no effect on keys specified by <productname>OpenSSL</productname>
+ engines unless the engine uses the <productname>OpenSSL</productname>
+ password callback mechanism for prompts.
+ </para>
+ <para>
+ There is no environment variable equivalent to this option, and no
+ facility for looking it up in <filename>.pgpass</filename>. It can be
+ used in a service file connection definition. Users with
+ more sophisticated uses should consider using <productname>OpenSSL</productname> engines and
+ tools like PKCS#11 or USB crypto offload devices.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslrootcert" xreflabel="sslrootcert">
+ <term><literal>sslrootcert</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the name of a file containing SSL
+ certificate authority (<acronym>CA</acronym>) certificate(s).
+ If the file exists, the server's certificate will be verified
+ to be signed by one of these authorities. The default is
+ <filename>~/.postgresql/root.crt</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslcrl" xreflabel="sslcrl">
+ <term><literal>sslcrl</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the file name of the SSL server certificate
+ revocation list (CRL). Certificates listed in this file, if it
+ exists, will be rejected while attempting to authenticate the
+ server's certificate. If neither
+ <xref linkend='libpq-connect-sslcrl'/> nor
+ <xref linkend='libpq-connect-sslcrldir'/> is set, this setting is
+ taken as
+ <filename>~/.postgresql/root.crl</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslcrldir" xreflabel="sslcrldir">
+ <term><literal>sslcrldir</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the directory name of the SSL server certificate
+ revocation list (CRL). Certificates listed in the files in this
+ directory, if it exists, will be rejected while attempting to
+ authenticate the server's certificate.
+ </para>
+
+ <para>
+ The directory needs to be prepared with the
+ <productname>OpenSSL</productname> command
+ <literal>openssl rehash</literal> or <literal>c_rehash</literal>. See
+ its documentation for details.
+ </para>
+
+ <para>
+ Both <literal>sslcrl</literal> and <literal>sslcrldir</literal> can be
+ specified together.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-sslsni" xreflabel="sslsni">
+ <term><literal>sslsni</literal><indexterm><primary>Server Name Indication</primary></indexterm></term>
+ <listitem>
+ <para>
+ If set to 1 (default), libpq sets the TLS extension <quote>Server Name
+ Indication</quote> (<acronym>SNI</acronym>) on SSL-enabled connections.
+ By setting this parameter to 0, this is turned off.
+ </para>
+
+ <para>
+ The Server Name Indication can be used by SSL-aware proxies to route
+ connections without having to decrypt the SSL stream. (Note that this
+ requires a proxy that is aware of the PostgreSQL protocol handshake,
+ not just any SSL proxy.) However, <acronym>SNI</acronym> makes the
+ destination host name appear in cleartext in the network traffic, so
+ it might be undesirable in some cases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-requirepeer" xreflabel="requirepeer">
+ <term><literal>requirepeer</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the operating-system user name of the
+ server, for example <literal>requirepeer=postgres</literal>.
+ When making a Unix-domain socket connection, if this
+ parameter is set, the client checks at the beginning of the
+ connection that the server process is running under the specified
+ user name; if it is not, the connection is aborted with an error.
+ This parameter can be used to provide server authentication similar
+ to that available with SSL certificates on TCP/IP connections.
+ (Note that if the Unix-domain socket is in
+ <filename>/tmp</filename> or another publicly writable location,
+ any user could start a server listening there. Use this parameter
+ to ensure that you are connected to a server run by a trusted user.)
+ This option is only supported on platforms for which the
+ <literal>peer</literal> authentication method is implemented; see
+ <xref linkend="auth-peer"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-ssl-min-protocol-version" xreflabel="ssl_min_protocol_version">
+ <term><literal>ssl_min_protocol_version</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the minimum SSL/TLS protocol version to allow
+ for the connection. Valid values are <literal>TLSv1</literal>,
+ <literal>TLSv1.1</literal>, <literal>TLSv1.2</literal> and
+ <literal>TLSv1.3</literal>. The supported protocols depend on the
+ version of <productname>OpenSSL</productname> used, older versions
+ not supporting the most modern protocol versions. If not specified,
+ the default is <literal>TLSv1.2</literal>, which satisfies industry
+ best practices as of this writing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-ssl-max-protocol-version" xreflabel="ssl_max_protocol_version">
+ <term><literal>ssl_max_protocol_version</literal></term>
+ <listitem>
+ <para>
+ This parameter specifies the maximum SSL/TLS protocol version to allow
+ for the connection. Valid values are <literal>TLSv1</literal>,
+ <literal>TLSv1.1</literal>, <literal>TLSv1.2</literal> and
+ <literal>TLSv1.3</literal>. The supported protocols depend on the
+ version of <productname>OpenSSL</productname> used, older versions
+ not supporting the most modern protocol versions. If not set, this
+ parameter is ignored and the connection will use the maximum bound
+ defined by the backend, if set. Setting the maximum protocol version
+ is mainly useful for testing or if some component has issues working
+ with a newer protocol.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-krbsrvname" xreflabel="krbsrvname">
+ <term><literal>krbsrvname</literal></term>
+ <listitem>
+ <para>
+ Kerberos service name to use when authenticating with GSSAPI.
+ This must match the service name specified in the server
+ configuration for Kerberos authentication to succeed. (See also
+ <xref linkend="gssapi-auth"/>.)
+ The default value is normally <literal>postgres</literal>,
+ but that can be changed when
+ building <productname>PostgreSQL</productname> via
+ the <option>--with-krb-srvnam</option> option
+ of <application>configure</application>.
+ In most environments, this parameter never needs to be changed.
+ Some Kerberos implementations might require a different service name,
+ such as Microsoft Active Directory which requires the service name
+ to be in upper case (<literal>POSTGRES</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-gsslib" xreflabel="gsslib">
+ <term><literal>gsslib</literal></term>
+ <listitem>
+ <para>
+ GSS library to use for GSSAPI authentication.
+ Currently this is disregarded except on Windows builds that include
+ both GSSAPI and SSPI support. In that case, set
+ this to <literal>gssapi</literal> to cause libpq to use the GSSAPI
+ library for authentication instead of the default SSPI.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-service" xreflabel="service">
+ <term><literal>service</literal></term>
+ <listitem>
+ <para>
+ Service name to use for additional parameters. It specifies a service
+ name in <filename>pg_service.conf</filename> that holds additional connection parameters.
+ This allows applications to specify only a service name so connection parameters
+ can be centrally maintained. See <xref linkend="libpq-pgservice"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-connect-target-session-attrs" xreflabel="target_session_attrs">
+ <term><literal>target_session_attrs</literal></term>
+ <listitem>
+ <para>
+ This option determines whether the session must have certain
+ properties to be acceptable. It's typically used in combination
+ with multiple host names to select the first acceptable alternative
+ among several hosts. There are six modes:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>any</literal> (default)</term>
+ <listitem>
+ <para>
+ any successful connection is acceptable
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>read-write</literal></term>
+ <listitem>
+ <para>
+ session must accept read-write transactions by default (that
+ is, the server must not be in hot standby mode and
+ the <varname>default_transaction_read_only</varname> parameter
+ must be <literal>off</literal>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>read-only</literal></term>
+ <listitem>
+ <para>
+ session must not accept read-write transactions by default (the
+ converse)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>primary</literal></term>
+ <listitem>
+ <para>
+ server must not be in hot standby mode
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>standby</literal></term>
+ <listitem>
+ <para>
+ server must be in hot standby mode
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>prefer-standby</literal></term>
+ <listitem>
+ <para>
+ first try to find a standby server, but if none of the listed
+ hosts is a standby server, try again in <literal>any</literal>
+ mode
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="libpq-status">
+ <title>Connection Status Functions</title>
+
+ <para>
+ These functions can be used to interrogate the status
+ of an existing database connection object.
+ </para>
+
+ <tip>
+ <para>
+ <indexterm><primary>libpq-fe.h</primary></indexterm>
+ <indexterm><primary>libpq-int.h</primary></indexterm>
+ <application>libpq</application> application programmers should be careful to
+ maintain the <structname>PGconn</structname> abstraction. Use the accessor
+ functions described below to get at the contents of <structname>PGconn</structname>.
+ Reference to internal <structname>PGconn</structname> fields using
+ <filename>libpq-int.h</filename> is not recommended because they are subject to change
+ in the future.
+ </para>
+ </tip>
+
+ <para>
+ The following functions return parameter values established at connection.
+ These values are fixed for the life of the connection. If a multi-host
+ connection string is used, the values of <xref linkend="libpq-PQhost"/>,
+ <xref linkend="libpq-PQport"/>, and <xref linkend="libpq-PQpass"/> can change if a new connection
+ is established using the same <structname>PGconn</structname> object. Other values
+ are fixed for the lifetime of the <structname>PGconn</structname> object.
+
+ <variablelist>
+ <varlistentry id="libpq-PQdb">
+ <term><function>PQdb</function><indexterm><primary>PQdb</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the database name of the connection.
+<synopsis>
+char *PQdb(const PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQuser">
+ <term><function>PQuser</function><indexterm><primary>PQuser</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the user name of the connection.
+<synopsis>
+char *PQuser(const PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQpass">
+ <term><function>PQpass</function><indexterm><primary>PQpass</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the password of the connection.
+<synopsis>
+char *PQpass(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQpass"/> will return either the password specified
+ in the connection parameters, or if there was none and the password
+ was obtained from the <link linkend="libpq-pgpass">password
+ file</link>, it will return that. In the latter case,
+ if multiple hosts were specified in the connection parameters, it is
+ not possible to rely on the result of <xref linkend="libpq-PQpass"/> until
+ the connection is established. The status of the connection can be
+ checked using the function <xref linkend="libpq-PQstatus"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQhost">
+ <term><function>PQhost</function><indexterm><primary>PQhost</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the server host name of the active connection.
+ This can be a host name, an IP address, or a directory path if the
+ connection is via Unix socket. (The path case can be distinguished
+ because it will always be an absolute path, beginning
+ with <literal>/</literal>.)
+<synopsis>
+char *PQhost(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ If the connection parameters specified both <literal>host</literal> and
+ <literal>hostaddr</literal>, then <xref linkend="libpq-PQhost"/> will
+ return the <literal>host</literal> information. If only
+ <literal>hostaddr</literal> was specified, then that is returned.
+ If multiple hosts were specified in the connection parameters,
+ <xref linkend="libpq-PQhost"/> returns the host actually connected to.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQhost"/> returns <symbol>NULL</symbol> if the
+ <parameter>conn</parameter> argument is <symbol>NULL</symbol>.
+ Otherwise, if there is an error producing the host information (perhaps
+ if the connection has not been fully established or there was an
+ error), it returns an empty string.
+ </para>
+
+ <para>
+ If multiple hosts were specified in the connection parameters, it is
+ not possible to rely on the result of <xref linkend="libpq-PQhost"/> until
+ the connection is established. The status of the connection can be
+ checked using the function <xref linkend="libpq-PQstatus"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="libpq-PQhostaddr">
+ <term><function>PQhostaddr</function><indexterm><primary>PQhostaddr</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the server IP address of the active connection.
+ This can be the address that a host name resolved to,
+ or an IP address provided through the <literal>hostaddr</literal>
+ parameter.
+<synopsis>
+char *PQhostaddr(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQhostaddr"/> returns <symbol>NULL</symbol> if the
+ <parameter>conn</parameter> argument is <symbol>NULL</symbol>.
+ Otherwise, if there is an error producing the host information
+ (perhaps if the connection has not been fully established or
+ there was an error), it returns an empty string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQport">
+ <term><function>PQport</function><indexterm><primary>PQport</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the port of the active connection.
+
+<synopsis>
+char *PQport(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ If multiple ports were specified in the connection parameters,
+ <xref linkend="libpq-PQport"/> returns the port actually connected to.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQport"/> returns <symbol>NULL</symbol> if the
+ <parameter>conn</parameter> argument is <symbol>NULL</symbol>.
+ Otherwise, if there is an error producing the port information (perhaps
+ if the connection has not been fully established or there was an
+ error), it returns an empty string.
+ </para>
+
+ <para>
+ If multiple ports were specified in the connection parameters, it is
+ not possible to rely on the result of <xref linkend="libpq-PQport"/> until
+ the connection is established. The status of the connection can be
+ checked using the function <xref linkend="libpq-PQstatus"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQtty">
+ <term><function>PQtty</function><indexterm><primary>PQtty</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ This function no longer does anything, but it remains for backwards
+ compatibility. The function always return an empty string, or
+ <symbol>NULL</symbol> if the <parameter>conn</parameter> argument is
+ <symbol>NULL</symbol>.
+
+<synopsis>
+char *PQtty(const PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQoptions">
+ <term><function>PQoptions</function><indexterm><primary>PQoptions</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the command-line options passed in the connection request.
+<synopsis>
+char *PQoptions(const PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following functions return status data that can change as operations
+ are executed on the <structname>PGconn</structname> object.
+
+ <variablelist>
+ <varlistentry id="libpq-PQstatus">
+ <term><function>PQstatus</function><indexterm><primary>PQstatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the status of the connection.
+<synopsis>
+ConnStatusType PQstatus(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ The status can be one of a number of values. However, only two of
+ these are seen outside of an asynchronous connection procedure:
+ <literal>CONNECTION_OK</literal> and
+ <literal>CONNECTION_BAD</literal>. A good connection to the database
+ has the status <literal>CONNECTION_OK</literal>. A failed
+ connection attempt is signaled by status
+ <literal>CONNECTION_BAD</literal>. Ordinarily, an OK status will
+ remain so until <xref linkend="libpq-PQfinish"/>, but a communications
+ failure might result in the status changing to
+ <literal>CONNECTION_BAD</literal> prematurely. In that case the
+ application could try to recover by calling
+ <xref linkend="libpq-PQreset"/>.
+ </para>
+
+ <para>
+ See the entry for <xref linkend="libpq-PQconnectStartParams"/>, <function>PQconnectStart</function>
+ and <function>PQconnectPoll</function> with regards to other status codes that
+ might be returned.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQtransactionStatus">
+ <term><function>PQtransactionStatus</function><indexterm><primary>PQtransactionStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the current in-transaction status of the server.
+
+<synopsis>
+PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
+</synopsis>
+
+ The status can be <literal>PQTRANS_IDLE</literal> (currently idle),
+ <literal>PQTRANS_ACTIVE</literal> (a command is in progress),
+ <literal>PQTRANS_INTRANS</literal> (idle, in a valid transaction block),
+ or <literal>PQTRANS_INERROR</literal> (idle, in a failed transaction block).
+ <literal>PQTRANS_UNKNOWN</literal> is reported if the connection is bad.
+ <literal>PQTRANS_ACTIVE</literal> is reported only when a query
+ has been sent to the server and not yet completed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQparameterStatus">
+ <term><function>PQparameterStatus</function><indexterm><primary>PQparameterStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Looks up a current parameter setting of the server.
+
+<synopsis>
+const char *PQparameterStatus(const PGconn *conn, const char *paramName);
+</synopsis>
+
+ Certain parameter values are reported by the server automatically at
+ connection startup or whenever their values change.
+ <xref linkend="libpq-PQparameterStatus"/> can be used to interrogate these settings.
+ It returns the current value of a parameter if known, or <symbol>NULL</symbol>
+ if the parameter is not known.
+ </para>
+
+ <para>
+ Parameters reported as of the current release include
+ <varname>server_version</varname>,
+ <varname>server_encoding</varname>,
+ <varname>client_encoding</varname>,
+ <varname>application_name</varname>,
+ <varname>default_transaction_read_only</varname>,
+ <varname>in_hot_standby</varname>,
+ <varname>is_superuser</varname>,
+ <varname>session_authorization</varname>,
+ <varname>DateStyle</varname>,
+ <varname>IntervalStyle</varname>,
+ <varname>TimeZone</varname>,
+ <varname>integer_datetimes</varname>, and
+ <varname>standard_conforming_strings</varname>.
+ (<varname>server_encoding</varname>, <varname>TimeZone</varname>, and
+ <varname>integer_datetimes</varname> were not reported by releases before 8.0;
+ <varname>standard_conforming_strings</varname> was not reported by releases
+ before 8.1;
+ <varname>IntervalStyle</varname> was not reported by releases before 8.4;
+ <varname>application_name</varname> was not reported by releases before
+ 9.0;
+ <varname>default_transaction_read_only</varname> and
+ <varname>in_hot_standby</varname> were not reported by releases before
+ 14.)
+ Note that
+ <varname>server_version</varname>,
+ <varname>server_encoding</varname> and
+ <varname>integer_datetimes</varname>
+ cannot change after startup.
+ </para>
+
+ <para>
+ If no value for <varname>standard_conforming_strings</varname> is reported,
+ applications can assume it is <literal>off</literal>, that is, backslashes
+ are treated as escapes in string literals. Also, the presence of
+ this parameter can be taken as an indication that the escape string
+ syntax (<literal>E'...'</literal>) is accepted.
+ </para>
+
+ <para>
+ Although the returned pointer is declared <literal>const</literal>, it in fact
+ points to mutable storage associated with the <literal>PGconn</literal> structure.
+ It is unwise to assume the pointer will remain valid across queries.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQprotocolVersion">
+ <term><function>PQprotocolVersion</function><indexterm><primary>PQprotocolVersion</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Interrogates the frontend/backend protocol being used.
+<synopsis>
+int PQprotocolVersion(const PGconn *conn);
+</synopsis>
+ Applications might wish to use this function to determine whether certain
+ features are supported. Currently, the possible values are 3
+ (3.0 protocol), or zero (connection bad). The protocol version will
+ not change after connection startup is complete, but it could
+ theoretically change during a connection reset. The 3.0 protocol is
+ supported by <productname>PostgreSQL</productname> server versions 7.4
+ and above.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQserverVersion">
+ <term><function>PQserverVersion</function><indexterm><primary>PQserverVersion</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns an integer representing the server version.
+<synopsis>
+int PQserverVersion(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ Applications might use this function to determine the version of the
+ database server they are connected to. The result is formed by
+ multiplying the server's major version number by 10000 and adding
+ the minor version number. For example, version 10.1 will be
+ returned as 100001, and version 11.0 will be returned as 110000.
+ Zero is returned if the connection is bad.
+ </para>
+
+ <para>
+ Prior to major version 10, <productname>PostgreSQL</productname> used
+ three-part version numbers in which the first two parts together
+ represented the major version. For those
+ versions, <xref linkend="libpq-PQserverVersion"/> uses two digits for each
+ part; for example version 9.1.5 will be returned as 90105, and
+ version 9.2.0 will be returned as 90200.
+ </para>
+
+ <para>
+ Therefore, for purposes of determining feature compatibility,
+ applications should divide the result of <xref linkend="libpq-PQserverVersion"/>
+ by 100 not 10000 to determine a logical major version number.
+ In all release series, only the last two digits differ between
+ minor releases (bug-fix releases).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQerrorMessage">
+ <term><function>PQerrorMessage</function><indexterm><primary>PQerrorMessage</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ <indexterm><primary>error message</primary></indexterm> Returns the error message
+ most recently generated by an operation on the connection.
+
+<synopsis>
+char *PQerrorMessage(const PGconn *conn);
+</synopsis>
+
+ </para>
+
+ <para>
+ Nearly all <application>libpq</application> functions will set a message for
+ <xref linkend="libpq-PQerrorMessage"/> if they fail. Note that by
+ <application>libpq</application> convention, a nonempty
+ <xref linkend="libpq-PQerrorMessage"/> result can consist of multiple lines,
+ and will include a trailing newline. The caller should not free
+ the result directly. It will be freed when the associated
+ <structname>PGconn</structname> handle is passed to
+ <xref linkend="libpq-PQfinish"/>. The result string should not be
+ expected to remain the same across operations on the
+ <literal>PGconn</literal> structure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsocket">
+ <term><function>PQsocket</function><indexterm><primary>PQsocket</primary></indexterm></term>
+ <listitem>
+ <para>
+ Obtains the file descriptor number of the connection socket to
+ the server. A valid descriptor will be greater than or equal
+ to 0; a result of -1 indicates that no server connection is
+ currently open. (This will not change during normal operation,
+ but could change during connection setup or reset.)
+
+<synopsis>
+int PQsocket(const PGconn *conn);
+</synopsis>
+
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQbackendPID">
+ <term><function>PQbackendPID</function><indexterm><primary>PQbackendPID</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns the process <acronym>ID</acronym> (PID)<indexterm>
+ <primary>PID</primary>
+ <secondary>determining PID of server process</secondary>
+ <tertiary>in libpq</tertiary>
+ </indexterm>
+ of the backend process handling this connection.
+
+<synopsis>
+int PQbackendPID(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ The backend <acronym>PID</acronym> is useful for debugging
+ purposes and for comparison to <command>NOTIFY</command>
+ messages (which include the <acronym>PID</acronym> of the
+ notifying backend process). Note that the
+ <acronym>PID</acronym> belongs to a process executing on the
+ database server host, not the local host!
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconnectionNeedsPassword">
+ <term><function>PQconnectionNeedsPassword</function><indexterm><primary>PQconnectionNeedsPassword</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns true (1) if the connection authentication method
+ required a password, but none was available.
+ Returns false (0) if not.
+
+<synopsis>
+int PQconnectionNeedsPassword(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ This function can be applied after a failed connection attempt
+ to decide whether to prompt the user for a password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconnectionUsedPassword">
+ <term><function>PQconnectionUsedPassword</function><indexterm><primary>PQconnectionUsedPassword</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns true (1) if the connection authentication method
+ used a password. Returns false (0) if not.
+
+<synopsis>
+int PQconnectionUsedPassword(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ This function can be applied after either a failed or successful
+ connection attempt to detect whether the server demanded a password.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following functions return information related to SSL. This information
+ usually doesn't change after a connection is established.
+
+ <variablelist>
+ <varlistentry id="libpq-PQsslInUse">
+ <term><function>PQsslInUse</function><indexterm><primary>PQsslInUse</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns true (1) if the connection uses SSL, false (0) if not.
+
+<synopsis>
+int PQsslInUse(const PGconn *conn);
+</synopsis>
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsslAttribute">
+ <term><function>PQsslAttribute</function><indexterm><primary>PQsslAttribute</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns SSL-related information about the connection.
+
+<synopsis>
+const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
+</synopsis>
+ </para>
+
+ <para>
+ The list of available attributes varies depending on the SSL library
+ being used and the type of connection. Returns NULL if the connection
+ does not use SSL or the specified attribute name is not defined for the
+ library in use.
+ </para>
+
+ <para>
+ The following attributes are commonly available:
+ <variablelist>
+ <varlistentry>
+ <term><literal>library</literal></term>
+ <listitem>
+ <para>
+ Name of the SSL implementation in use. (Currently, only
+ <literal>"OpenSSL"</literal> is implemented)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>protocol</literal></term>
+ <listitem>
+ <para>
+ SSL/TLS version in use. Common values
+ are <literal>"TLSv1"</literal>, <literal>"TLSv1.1"</literal>
+ and <literal>"TLSv1.2"</literal>, but an implementation may
+ return other strings if some other protocol is used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>key_bits</literal></term>
+ <listitem>
+ <para>
+ Number of key bits used by the encryption algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>cipher</literal></term>
+ <listitem>
+ <para>
+ A short name of the ciphersuite used, e.g.,
+ <literal>"DHE-RSA-DES-CBC3-SHA"</literal>. The names are specific
+ to each SSL implementation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>compression</literal></term>
+ <listitem>
+ <para>
+ Returns "on" if SSL compression is in use, else it returns "off".
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ As a special case, the <literal>library</literal> attribute may be
+ queried without a connection by passing NULL as
+ the <literal>conn</literal> argument. The result will be the default
+ SSL library name, or NULL if <application>libpq</application> was
+ compiled without any SSL support. (Prior
+ to <productname>PostgreSQL</productname> version 15, passing NULL as
+ the <literal>conn</literal> argument always resulted in NULL.
+ Client programs needing to differentiate between the newer and older
+ implementations of this case may check the
+ <literal>LIBPQ_HAS_SSL_LIBRARY_DETECTION</literal> feature macro.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsslAttributeNames">
+ <term><function>PQsslAttributeNames</function><indexterm><primary>PQsslAttributeNames</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns an array of SSL attribute names available.
+ The array is terminated by a NULL pointer.
+<synopsis>
+const char * const * PQsslAttributeNames(const PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsslStruct">
+ <term><function>PQsslStruct</function><indexterm><primary>PQsslStruct</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns a pointer to an SSL-implementation-specific object describing
+ the connection. Returns NULL if the connection is not encrypted
+ or the requested type of object is not available from the connection's
+ SSL implementation.
+<synopsis>
+void *PQsslStruct(const PGconn *conn, const char *struct_name);
+</synopsis>
+ </para>
+ <para>
+ The struct(s) available depend on the SSL implementation in use.
+ For <productname>OpenSSL</productname>, there is one struct,
+ available under the name <literal>OpenSSL</literal>,
+ and it returns a pointer to
+ <productname>OpenSSL</productname>'s <literal>SSL</literal> struct.
+ To use this function, code along the following lines could be used:
+<programlisting><![CDATA[
+#include <libpq-fe.h>
+#include <openssl/ssl.h>
+
+...
+
+ SSL *ssl;
+
+ dbconn = PQconnectdb(...);
+ ...
+
+ ssl = PQsslStruct(dbconn, "OpenSSL");
+ if (ssl)
+ {
+ /* use OpenSSL functions to access ssl */
+ }
+]]></programlisting>
+ </para>
+ <para>
+ This structure can be used to verify encryption levels, check server
+ certificates, and more. Refer to the <productname>OpenSSL</productname>
+ documentation for information about this structure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQgetssl">
+ <term><function>PQgetssl</function><indexterm><primary>PQgetssl</primary></indexterm></term>
+ <listitem>
+ <para>
+ <indexterm><primary>SSL</primary><secondary sortas="libpq">in libpq</secondary></indexterm>
+ Returns the SSL structure used in the connection, or NULL
+ if SSL is not in use.
+
+<synopsis>
+void *PQgetssl(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ This function is equivalent to <literal>PQsslStruct(conn, "OpenSSL")</literal>. It should
+ not be used in new applications, because the returned struct is
+ specific to <productname>OpenSSL</productname> and will not be
+ available if another <acronym>SSL</acronym> implementation is used.
+ To check if a connection uses SSL, call
+ <xref linkend="libpq-PQsslInUse"/> instead, and for more details about the
+ connection, use <xref linkend="libpq-PQsslAttribute"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </sect1>
+
+ <sect1 id="libpq-exec">
+ <title>Command Execution Functions</title>
+
+ <para>
+ Once a connection to a database server has been successfully
+ established, the functions described here are used to perform
+ SQL queries and commands.
+ </para>
+
+ <sect2 id="libpq-exec-main">
+ <title>Main Functions</title>
+
+ <para>
+ <variablelist>
+ <varlistentry id="libpq-PQexec">
+ <term><function>PQexec</function><indexterm><primary>PQexec</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a command to the server and waits for the result.
+
+<synopsis>
+PGresult *PQexec(PGconn *conn, const char *command);
+</synopsis>
+ </para>
+
+ <para>
+ Returns a <structname>PGresult</structname> pointer or possibly a null
+ pointer. A non-null pointer will generally be returned except in
+ out-of-memory conditions or serious errors such as inability to send
+ the command to the server. The <xref linkend="libpq-PQresultStatus"/> function
+ should be called to check the return value for any errors (including
+ the value of a null pointer, in which case it will return
+ <symbol>PGRES_FATAL_ERROR</symbol>). Use
+ <xref linkend="libpq-PQerrorMessage"/> to get more information about such
+ errors.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The command string can include multiple SQL commands
+ (separated by semicolons). Multiple queries sent in a single
+ <xref linkend="libpq-PQexec"/> call are processed in a single transaction, unless
+ there are explicit <command>BEGIN</command>/<command>COMMIT</command>
+ commands included in the query string to divide it into multiple
+ transactions. (See <xref linkend="protocol-flow-multi-statement"/>
+ for more details about how the server handles multi-query strings.)
+ Note however that the returned
+ <structname>PGresult</structname> structure describes only the result
+ of the last command executed from the string. Should one of the
+ commands fail, processing of the string stops with it and the returned
+ <structname>PGresult</structname> describes the error condition.
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry id="libpq-PQexecParams">
+ <term><function>PQexecParams</function><indexterm><primary>PQexecParams</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a command to the server and waits for the result,
+ with the ability to pass parameters separately from the SQL
+ command text.
+
+<synopsis>
+PGresult *PQexecParams(PGconn *conn,
+ const char *command,
+ int nParams,
+ const Oid *paramTypes,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQexecParams"/> is like <xref linkend="libpq-PQexec"/>, but offers additional
+ functionality: parameter values can be specified separately from the command
+ string proper, and query results can be requested in either text or binary
+ format.
+ </para>
+
+ <para>
+ The function arguments are:
+
+ <variablelist>
+ <varlistentry>
+ <term><parameter>conn</parameter></term>
+
+ <listitem>
+ <para>
+ The connection object to send the command through.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>command</parameter></term>
+ <listitem>
+ <para>
+ The SQL command string to be executed. If parameters are used,
+ they are referred to in the command string as <literal>$1</literal>,
+ <literal>$2</literal>, etc.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>nParams</parameter></term>
+ <listitem>
+ <para>
+ The number of parameters supplied; it is the length of the arrays
+ <parameter>paramTypes[]</parameter>, <parameter>paramValues[]</parameter>,
+ <parameter>paramLengths[]</parameter>, and <parameter>paramFormats[]</parameter>. (The
+ array pointers can be <symbol>NULL</symbol> when <parameter>nParams</parameter>
+ is zero.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>paramTypes[]</parameter></term>
+ <listitem>
+ <para>
+ Specifies, by OID, the data types to be assigned to the
+ parameter symbols. If <parameter>paramTypes</parameter> is
+ <symbol>NULL</symbol>, or any particular element in the array
+ is zero, the server infers a data type for the parameter symbol
+ in the same way it would do for an untyped literal string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>paramValues[]</parameter></term>
+ <listitem>
+ <para>
+ Specifies the actual values of the parameters. A null pointer
+ in this array means the corresponding parameter is null;
+ otherwise the pointer points to a zero-terminated text string
+ (for text format) or binary data in the format expected by the
+ server (for binary format).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>paramLengths[]</parameter></term>
+ <listitem>
+ <para>
+ Specifies the actual data lengths of binary-format parameters.
+ It is ignored for null parameters and text-format parameters.
+ The array pointer can be null when there are no binary parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>paramFormats[]</parameter></term>
+ <listitem>
+ <para>
+ Specifies whether parameters are text (put a zero in the
+ array entry for the corresponding parameter) or binary (put
+ a one in the array entry for the corresponding parameter).
+ If the array pointer is null then all parameters are presumed
+ to be text strings.
+ </para>
+ <para>
+ Values passed in binary format require knowledge of
+ the internal representation expected by the backend.
+ For example, integers must be passed in network byte
+ order. Passing <type>numeric</type> values requires
+ knowledge of the server storage format, as implemented
+ in
+ <filename>src/backend/utils/adt/numeric.c::numeric_send()</filename> and
+ <filename>src/backend/utils/adt/numeric.c::numeric_recv()</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>resultFormat</parameter></term>
+ <listitem>
+ <para>
+ Specify zero to obtain results in text format, or one to obtain
+ results in binary format. (There is not currently a provision
+ to obtain different result columns in different formats,
+ although that is possible in the underlying protocol.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The primary advantage of <xref linkend="libpq-PQexecParams"/> over
+ <xref linkend="libpq-PQexec"/> is that parameter values can be separated from the
+ command string, thus avoiding the need for tedious and error-prone
+ quoting and escaping.
+ </para>
+
+ <para>
+ Unlike <xref linkend="libpq-PQexec"/>, <xref linkend="libpq-PQexecParams"/> allows at most
+ one SQL command in the given string. (There can be semicolons in it,
+ but not more than one nonempty command.) This is a limitation of the
+ underlying protocol, but has some usefulness as an extra defense against
+ SQL-injection attacks.
+ </para>
+
+ <tip>
+ <para>
+ Specifying parameter types via OIDs is tedious, particularly if you prefer
+ not to hard-wire particular OID values into your program. However, you can
+ avoid doing so even in cases where the server by itself cannot determine the
+ type of the parameter, or chooses a different type than you want. In the
+ SQL command text, attach an explicit cast to the parameter symbol to show what
+ data type you will send. For example:
+<programlisting>
+SELECT * FROM mytable WHERE x = $1::bigint;
+</programlisting>
+ This forces parameter <literal>$1</literal> to be treated as <type>bigint</type>, whereas
+ by default it would be assigned the same type as <literal>x</literal>. Forcing the
+ parameter type decision, either this way or by specifying a numeric type OID,
+ is strongly recommended when sending parameter values in binary format, because
+ binary format has less redundancy than text format and so there is less chance
+ that the server will detect a type mismatch mistake for you.
+ </para>
+ </tip>
+
+ <para>
+ <variablelist>
+ <varlistentry id="libpq-PQprepare">
+ <term><function>PQprepare</function><indexterm><primary>PQprepare</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a request to create a prepared statement with the
+ given parameters, and waits for completion.
+<synopsis>
+PGresult *PQprepare(PGconn *conn,
+ const char *stmtName,
+ const char *query,
+ int nParams,
+ const Oid *paramTypes);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQprepare"/> creates a prepared statement for later
+ execution with <xref linkend="libpq-PQexecPrepared"/>. This feature allows
+ commands to be executed repeatedly without being parsed and
+ planned each time; see <xref linkend="sql-prepare"/> for details.
+ </para>
+
+ <para>
+ The function creates a prepared statement named
+ <parameter>stmtName</parameter> from the <parameter>query</parameter> string, which
+ must contain a single SQL command. <parameter>stmtName</parameter> can be
+ <literal>""</literal> to create an unnamed statement, in which case any
+ pre-existing unnamed statement is automatically replaced; otherwise
+ it is an error if the statement name is already defined in the
+ current session. If any parameters are used, they are referred
+ to in the query as <literal>$1</literal>, <literal>$2</literal>, etc.
+ <parameter>nParams</parameter> is the number of parameters for which types
+ are pre-specified in the array <parameter>paramTypes[]</parameter>. (The
+ array pointer can be <symbol>NULL</symbol> when
+ <parameter>nParams</parameter> is zero.) <parameter>paramTypes[]</parameter>
+ specifies, by OID, the data types to be assigned to the parameter
+ symbols. If <parameter>paramTypes</parameter> is <symbol>NULL</symbol>,
+ or any particular element in the array is zero, the server assigns
+ a data type to the parameter symbol in the same way it would do
+ for an untyped literal string. Also, the query can use parameter
+ symbols with numbers higher than <parameter>nParams</parameter>; data types
+ will be inferred for these symbols as well. (See
+ <xref linkend="libpq-PQdescribePrepared"/> for a means to find out
+ what data types were inferred.)
+ </para>
+
+ <para>
+ As with <xref linkend="libpq-PQexec"/>, the result is normally a
+ <structname>PGresult</structname> object whose contents indicate
+ server-side success or failure. A null result indicates
+ out-of-memory or inability to send the command at all. Use
+ <xref linkend="libpq-PQerrorMessage"/> to get more information about
+ such errors.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Prepared statements for use with <xref linkend="libpq-PQexecPrepared"/> can also
+ be created by executing SQL <xref linkend="sql-prepare"/>
+ statements. Also, although there is no <application>libpq</application>
+ function for deleting a prepared statement, the SQL <xref
+ linkend="sql-deallocate"/> statement
+ can be used for that purpose.
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry id="libpq-PQexecPrepared">
+ <term><function>PQexecPrepared</function><indexterm><primary>PQexecPrepared</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends a request to execute a prepared statement with given
+ parameters, and waits for the result.
+<synopsis>
+PGresult *PQexecPrepared(PGconn *conn,
+ const char *stmtName,
+ int nParams,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQexecPrepared"/> is like <xref linkend="libpq-PQexecParams"/>,
+ but the command to be executed is specified by naming a
+ previously-prepared statement, instead of giving a query string.
+ This feature allows commands that will be used repeatedly to be
+ parsed and planned just once, rather than each time they are
+ executed. The statement must have been prepared previously in
+ the current session.
+ </para>
+
+ <para>
+ The parameters are identical to <xref linkend="libpq-PQexecParams"/>, except that the
+ name of a prepared statement is given instead of a query string, and the
+ <parameter>paramTypes[]</parameter> parameter is not present (it is not needed since
+ the prepared statement's parameter types were determined when it was created).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQdescribePrepared">
+ <term><function>PQdescribePrepared</function><indexterm><primary>PQdescribePrepared</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a request to obtain information about the specified
+ prepared statement, and waits for completion.
+<synopsis>
+PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQdescribePrepared"/> allows an application to obtain
+ information about a previously prepared statement.
+ </para>
+
+ <para>
+ <parameter>stmtName</parameter> can be <literal>""</literal> or <symbol>NULL</symbol> to reference
+ the unnamed statement, otherwise it must be the name of an existing
+ prepared statement. On success, a <structname>PGresult</structname> with
+ status <literal>PGRES_COMMAND_OK</literal> is returned. The
+ functions <xref linkend="libpq-PQnparams"/> and
+ <xref linkend="libpq-PQparamtype"/> can be applied to this
+ <structname>PGresult</structname> to obtain information about the parameters
+ of the prepared statement, and the functions
+ <xref linkend="libpq-PQnfields"/>, <xref linkend="libpq-PQfname"/>,
+ <xref linkend="libpq-PQftype"/>, etc. provide information about the
+ result columns (if any) of the statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQdescribePortal">
+ <term><function>PQdescribePortal</function><indexterm><primary>PQdescribePortal</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a request to obtain information about the specified
+ portal, and waits for completion.
+<synopsis>
+PGresult *PQdescribePortal(PGconn *conn, const char *portalName);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQdescribePortal"/> allows an application to obtain
+ information about a previously created portal.
+ (<application>libpq</application> does not provide any direct access to
+ portals, but you can use this function to inspect the properties
+ of a cursor created with a <command>DECLARE CURSOR</command> SQL command.)
+ </para>
+
+ <para>
+ <parameter>portalName</parameter> can be <literal>""</literal> or <symbol>NULL</symbol> to reference
+ the unnamed portal, otherwise it must be the name of an existing
+ portal. On success, a <structname>PGresult</structname> with status
+ <literal>PGRES_COMMAND_OK</literal> is returned. The functions
+ <xref linkend="libpq-PQnfields"/>, <xref linkend="libpq-PQfname"/>,
+ <xref linkend="libpq-PQftype"/>, etc. can be applied to the
+ <structname>PGresult</structname> to obtain information about the result
+ columns (if any) of the portal.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <structname>PGresult</structname><indexterm><primary>PGresult</primary></indexterm>
+ structure encapsulates the result returned by the server.
+ <application>libpq</application> application programmers should be
+ careful to maintain the <structname>PGresult</structname> abstraction.
+ Use the accessor functions below to get at the contents of
+ <structname>PGresult</structname>. Avoid directly referencing the
+ fields of the <structname>PGresult</structname> structure because they
+ are subject to change in the future.
+
+ <variablelist>
+ <varlistentry id="libpq-PQresultStatus">
+ <term><function>PQresultStatus</function><indexterm><primary>PQresultStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the result status of the command.
+<synopsis>
+ExecStatusType PQresultStatus(const PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQresultStatus"/> can return one of the following values:
+
+ <variablelist>
+ <varlistentry id="libpq-pgres-empty-query">
+ <term><literal>PGRES_EMPTY_QUERY</literal></term>
+ <listitem>
+ <para>
+ The string sent to the server was empty.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-command-ok">
+ <term><literal>PGRES_COMMAND_OK</literal></term>
+ <listitem>
+ <para>
+ Successful completion of a command returning no data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-tuples-ok">
+ <term><literal>PGRES_TUPLES_OK</literal></term>
+ <listitem>
+ <para>
+ Successful completion of a command returning data (such as
+ a <command>SELECT</command> or <command>SHOW</command>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-copy-out">
+ <term><literal>PGRES_COPY_OUT</literal></term>
+ <listitem>
+ <para>
+ Copy Out (from server) data transfer started.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-copy-in">
+ <term><literal>PGRES_COPY_IN</literal></term>
+ <listitem>
+ <para>
+ Copy In (to server) data transfer started.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-bad-response">
+ <term><literal>PGRES_BAD_RESPONSE</literal></term>
+ <listitem>
+ <para>
+ The server's response was not understood.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-nonfatal-error">
+ <term><literal>PGRES_NONFATAL_ERROR</literal></term>
+ <listitem>
+ <para>
+ A nonfatal error (a notice or warning) occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-fatal-error">
+ <term><literal>PGRES_FATAL_ERROR</literal></term>
+ <listitem>
+ <para>
+ A fatal error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-copy-both">
+ <term><literal>PGRES_COPY_BOTH</literal></term>
+ <listitem>
+ <para>
+ Copy In/Out (to and from server) data transfer started. This
+ feature is currently used only for streaming replication,
+ so this status should not occur in ordinary applications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-single-tuple">
+ <term><literal>PGRES_SINGLE_TUPLE</literal></term>
+ <listitem>
+ <para>
+ The <structname>PGresult</structname> contains a single result tuple
+ from the current command. This status occurs only when
+ single-row mode has been selected for the query
+ (see <xref linkend="libpq-single-row-mode"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-pipeline-sync">
+ <term><literal>PGRES_PIPELINE_SYNC</literal></term>
+ <listitem>
+ <para>
+ The <structname>PGresult</structname> represents a
+ synchronization point in pipeline mode, requested by
+ <xref linkend="libpq-PQpipelineSync"/>.
+ This status occurs only when pipeline mode has been selected.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgres-pipeline-aborted">
+ <term><literal>PGRES_PIPELINE_ABORTED</literal></term>
+ <listitem>
+ <para>
+ The <structname>PGresult</structname> represents a pipeline that has
+ received an error from the server. <function>PQgetResult</function>
+ must be called repeatedly, and each time it will return this status code
+ until the end of the current pipeline, at which point it will return
+ <literal>PGRES_PIPELINE_SYNC</literal> and normal processing can
+ resume.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ If the result status is <literal>PGRES_TUPLES_OK</literal> or
+ <literal>PGRES_SINGLE_TUPLE</literal>, then
+ the functions described below can be used to retrieve the rows
+ returned by the query. Note that a <command>SELECT</command>
+ command that happens to retrieve zero rows still shows
+ <literal>PGRES_TUPLES_OK</literal>.
+ <literal>PGRES_COMMAND_OK</literal> is for commands that can never
+ return rows (<command>INSERT</command> or <command>UPDATE</command>
+ without a <literal>RETURNING</literal> clause,
+ etc.). A response of <literal>PGRES_EMPTY_QUERY</literal> might
+ indicate a bug in the client software.
+ </para>
+
+ <para>
+ A result of status <symbol>PGRES_NONFATAL_ERROR</symbol> will
+ never be returned directly by <xref linkend="libpq-PQexec"/> or other
+ query execution functions; results of this kind are instead passed
+ to the notice processor (see <xref
+ linkend="libpq-notice-processing"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresStatus">
+ <term><function>PQresStatus</function><indexterm><primary>PQresStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Converts the enumerated type returned by
+ <xref linkend="libpq-PQresultStatus"/> into a string constant describing the
+ status code. The caller should not free the result.
+
+<synopsis>
+char *PQresStatus(ExecStatusType status);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultErrorMessage">
+ <term><function>PQresultErrorMessage</function><indexterm><primary>PQresultErrorMessage</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the error message associated with the command, or an empty string
+ if there was no error.
+<synopsis>
+char *PQresultErrorMessage(const PGresult *res);
+</synopsis>
+ If there was an error, the returned string will include a trailing
+ newline. The caller should not free the result directly. It will
+ be freed when the associated <structname>PGresult</structname> handle is
+ passed to <xref linkend="libpq-PQclear"/>.
+ </para>
+
+ <para>
+ Immediately following a <xref linkend="libpq-PQexec"/> or
+ <xref linkend="libpq-PQgetResult"/> call,
+ <xref linkend="libpq-PQerrorMessage"/> (on the connection) will return
+ the same string as <xref linkend="libpq-PQresultErrorMessage"/> (on
+ the result). However, a <structname>PGresult</structname> will
+ retain its error message until destroyed, whereas the connection's
+ error message will change when subsequent operations are done.
+ Use <xref linkend="libpq-PQresultErrorMessage"/> when you want to
+ know the status associated with a particular
+ <structname>PGresult</structname>; use
+ <xref linkend="libpq-PQerrorMessage"/> when you want to know the
+ status from the latest operation on the connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultVerboseErrorMessage">
+ <term><function>PQresultVerboseErrorMessage</function><indexterm><primary>PQresultVerboseErrorMessage</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns a reformatted version of the error message associated with
+ a <structname>PGresult</structname> object.
+<synopsis>
+char *PQresultVerboseErrorMessage(const PGresult *res,
+ PGVerbosity verbosity,
+ PGContextVisibility show_context);
+</synopsis>
+ In some situations a client might wish to obtain a more detailed
+ version of a previously-reported error.
+ <xref linkend="libpq-PQresultVerboseErrorMessage"/> addresses this need
+ by computing the message that would have been produced
+ by <xref linkend="libpq-PQresultErrorMessage"/> if the specified
+ verbosity settings had been in effect for the connection when the
+ given <structname>PGresult</structname> was generated. If
+ the <structname>PGresult</structname> is not an error result,
+ <quote>PGresult is not an error result</quote> is reported instead.
+ The returned string includes a trailing newline.
+ </para>
+
+ <para>
+ Unlike most other functions for extracting data from
+ a <structname>PGresult</structname>, the result of this function is a freshly
+ allocated string. The caller must free it
+ using <function>PQfreemem()</function> when the string is no longer needed.
+ </para>
+
+ <para>
+ A NULL return is possible if there is insufficient memory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultErrorField">
+ <term><function>PQresultErrorField</function><indexterm><primary>PQresultErrorField</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns an individual field of an error report.
+<synopsis>
+char *PQresultErrorField(const PGresult *res, int fieldcode);
+</synopsis>
+ <parameter>fieldcode</parameter> is an error field identifier; see the symbols
+ listed below. <symbol>NULL</symbol> is returned if the
+ <structname>PGresult</structname> is not an error or warning result,
+ or does not include the specified field. Field values will normally
+ not include a trailing newline. The caller should not free the
+ result directly. It will be freed when the
+ associated <structname>PGresult</structname> handle is passed to
+ <xref linkend="libpq-PQclear"/>.
+ </para>
+
+ <para>
+ The following field codes are available:
+ <variablelist>
+ <varlistentry id="libpq-pg-diag-severity">
+ <term><symbol>PG_DIAG_SEVERITY</symbol></term>
+ <listitem>
+ <para>
+ The severity; the field contents are <literal>ERROR</literal>,
+ <literal>FATAL</literal>, or <literal>PANIC</literal> (in an error message),
+ or <literal>WARNING</literal>, <literal>NOTICE</literal>, <literal>DEBUG</literal>,
+ <literal>INFO</literal>, or <literal>LOG</literal> (in a notice message), or
+ a localized translation of one of these. Always present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PG-diag-severity-nonlocalized">
+ <term><symbol>PG_DIAG_SEVERITY_NONLOCALIZED</symbol></term>
+ <listitem>
+ <para>
+ The severity; the field contents are <literal>ERROR</literal>,
+ <literal>FATAL</literal>, or <literal>PANIC</literal> (in an error message),
+ or <literal>WARNING</literal>, <literal>NOTICE</literal>, <literal>DEBUG</literal>,
+ <literal>INFO</literal>, or <literal>LOG</literal> (in a notice message).
+ This is identical to the <symbol>PG_DIAG_SEVERITY</symbol> field except
+ that the contents are never localized. This is present only in
+ reports generated by <productname>PostgreSQL</productname> versions 9.6
+ and later.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-sqlstate">
+ <term><symbol>PG_DIAG_SQLSTATE</symbol><indexterm
+ ><primary>error codes</primary><secondary>libpq</secondary></indexterm></term>
+ <listitem>
+ <para>
+ The SQLSTATE code for the error. The SQLSTATE code identifies
+ the type of error that has occurred; it can be used by
+ front-end applications to perform specific operations (such
+ as error handling) in response to a particular database error.
+ For a list of the possible SQLSTATE codes, see <xref
+ linkend="errcodes-appendix"/>. This field is not localizable,
+ and is always present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-message-primary">
+ <term><symbol>PG_DIAG_MESSAGE_PRIMARY</symbol></term>
+ <listitem>
+ <para>
+ The primary human-readable error message (typically one line).
+ Always present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-message-detail">
+ <term><symbol>PG_DIAG_MESSAGE_DETAIL</symbol></term>
+ <listitem>
+ <para>
+ Detail: an optional secondary error message carrying more
+ detail about the problem. Might run to multiple lines.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-message-hint">
+ <term><symbol>PG_DIAG_MESSAGE_HINT</symbol></term>
+ <listitem>
+ <para>
+ Hint: an optional suggestion what to do about the problem.
+ This is intended to differ from detail in that it offers advice
+ (potentially inappropriate) rather than hard facts. Might
+ run to multiple lines.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-statement-position">
+ <term><symbol>PG_DIAG_STATEMENT_POSITION</symbol></term>
+ <listitem>
+ <para>
+ A string containing a decimal integer indicating an error cursor
+ position as an index into the original statement string. The
+ first character has index 1, and positions are measured in
+ characters not bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-internal-position">
+ <term><symbol>PG_DIAG_INTERNAL_POSITION</symbol></term>
+ <listitem>
+ <para>
+ This is defined the same as the
+ <symbol>PG_DIAG_STATEMENT_POSITION</symbol> field, but it is used
+ when the cursor position refers to an internally generated
+ command rather than the one submitted by the client. The
+ <symbol>PG_DIAG_INTERNAL_QUERY</symbol> field will always appear when
+ this field appears.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-internal-query">
+ <term><symbol>PG_DIAG_INTERNAL_QUERY</symbol></term>
+ <listitem>
+ <para>
+ The text of a failed internally-generated command. This could
+ be, for example, an SQL query issued by a PL/pgSQL function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-context">
+ <term><symbol>PG_DIAG_CONTEXT</symbol></term>
+ <listitem>
+ <para>
+ An indication of the context in which the error occurred.
+ Presently this includes a call stack traceback of active
+ procedural language functions and internally-generated queries.
+ The trace is one entry per line, most recent first.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-schema-name">
+ <term><symbol>PG_DIAG_SCHEMA_NAME</symbol></term>
+ <listitem>
+ <para>
+ If the error was associated with a specific database object,
+ the name of the schema containing that object, if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-table-name">
+ <term><symbol>PG_DIAG_TABLE_NAME</symbol></term>
+ <listitem>
+ <para>
+ If the error was associated with a specific table, the name of the
+ table. (Refer to the schema name field for the name of the
+ table's schema.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-column-name">
+ <term><symbol>PG_DIAG_COLUMN_NAME</symbol></term>
+ <listitem>
+ <para>
+ If the error was associated with a specific table column, the name
+ of the column. (Refer to the schema and table name fields to
+ identify the table.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-datatype-name">
+ <term><symbol>PG_DIAG_DATATYPE_NAME</symbol></term>
+ <listitem>
+ <para>
+ If the error was associated with a specific data type, the name of
+ the data type. (Refer to the schema name field for the name of
+ the data type's schema.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-constraint-name">
+ <term><symbol>PG_DIAG_CONSTRAINT_NAME</symbol></term>
+ <listitem>
+ <para>
+ If the error was associated with a specific constraint, the name
+ of the constraint. Refer to fields listed above for the
+ associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with
+ constraint syntax.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-source-file">
+ <term><symbol>PG_DIAG_SOURCE_FILE</symbol></term>
+ <listitem>
+ <para>
+ The file name of the source-code location where the error was
+ reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-source-line">
+ <term><symbol>PG_DIAG_SOURCE_LINE</symbol></term>
+ <listitem>
+ <para>
+ The line number of the source-code location where the error
+ was reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pg-diag-source-function">
+ <term><symbol>PG_DIAG_SOURCE_FUNCTION</symbol></term>
+ <listitem>
+ <para>
+ The name of the source-code function reporting the error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <note>
+ <para>
+ The fields for schema name, table name, column name, data type name,
+ and constraint name are supplied only for a limited number of error
+ types; see <xref linkend="errcodes-appendix"/>. Do not assume that
+ the presence of any of these fields guarantees the presence of
+ another field. Core error sources observe the interrelationships
+ noted above, but user-defined functions may use these fields in other
+ ways. In the same vein, do not assume that these fields denote
+ contemporary objects in the current database.
+ </para>
+ </note>
+
+ <para>
+ The client is responsible for formatting displayed information to meet
+ its needs; in particular it should break long lines as needed.
+ Newline characters appearing in the error message fields should be
+ treated as paragraph breaks, not line breaks.
+ </para>
+
+ <para>
+ Errors generated internally by <application>libpq</application> will
+ have severity and primary message, but typically no other fields.
+ </para>
+
+ <para>
+ Note that error fields are only available from
+ <structname>PGresult</structname> objects, not
+ <structname>PGconn</structname> objects; there is no
+ <function>PQerrorField</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQclear">
+ <term><function>PQclear</function><indexterm><primary>PQclear</primary></indexterm></term>
+ <listitem>
+ <para>
+ Frees the storage associated with a
+ <structname>PGresult</structname>. Every command result should be
+ freed via <xref linkend="libpq-PQclear"/> when it is no longer
+ needed.
+
+<synopsis>
+void PQclear(PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ You can keep a <structname>PGresult</structname> object around for
+ as long as you need it; it does not go away when you issue a new
+ command, nor even if you close the connection. To get rid of it,
+ you must call <xref linkend="libpq-PQclear"/>. Failure to do this
+ will result in memory leaks in your application.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="libpq-exec-select-info">
+ <title>Retrieving Query Result Information</title>
+
+ <para>
+ These functions are used to extract information from a
+ <structname>PGresult</structname> object that represents a successful
+ query result (that is, one that has status
+ <literal>PGRES_TUPLES_OK</literal> or <literal>PGRES_SINGLE_TUPLE</literal>).
+ They can also be used to extract
+ information from a successful Describe operation: a Describe's result
+ has all the same column information that actual execution of the query
+ would provide, but it has zero rows. For objects with other status values,
+ these functions will act as though the result has zero rows and zero columns.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQntuples">
+ <term><function>PQntuples</function><indexterm><primary>PQntuples</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the number of rows (tuples) in the query result.
+ (Note that <structname>PGresult</structname> objects are limited to no more
+ than <literal>INT_MAX</literal> rows, so an <type>int</type> result is
+ sufficient.)
+
+<synopsis>
+int PQntuples(const PGresult *res);
+</synopsis>
+
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQnfields">
+ <term><function>PQnfields</function><indexterm><primary>PQnfields</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the number of columns (fields) in each row of the query
+ result.
+
+<synopsis>
+int PQnfields(const PGresult *res);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfname">
+ <term><function>PQfname</function><indexterm><primary>PQfname</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the column name associated with the given column number.
+ Column numbers start at 0. The caller should not free the result
+ directly. It will be freed when the associated
+ <structname>PGresult</structname> handle is passed to
+ <xref linkend="libpq-PQclear"/>.
+<synopsis>
+char *PQfname(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ <symbol>NULL</symbol> is returned if the column number is out of range.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfnumber">
+ <term><function>PQfnumber</function><indexterm><primary>PQfnumber</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the column number associated with the given column name.
+<synopsis>
+int PQfnumber(const PGresult *res,
+ const char *column_name);
+</synopsis>
+ </para>
+
+ <para>
+ -1 is returned if the given name does not match any column.
+ </para>
+
+ <para>
+ The given name is treated like an identifier in an SQL command,
+ that is, it is downcased unless double-quoted. For example, given
+ a query result generated from the SQL command:
+<programlisting>
+SELECT 1 AS FOO, 2 AS "BAR";
+</programlisting>
+ we would have the results:
+<programlisting>
+PQfname(res, 0) <lineannotation>foo</lineannotation>
+PQfname(res, 1) <lineannotation>BAR</lineannotation>
+PQfnumber(res, "FOO") <lineannotation>0</lineannotation>
+PQfnumber(res, "foo") <lineannotation>0</lineannotation>
+PQfnumber(res, "BAR") <lineannotation>-1</lineannotation>
+PQfnumber(res, "\"BAR\"") <lineannotation>1</lineannotation>
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQftable">
+ <term><function>PQftable</function><indexterm><primary>PQftable</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the OID of the table from which the given column was
+ fetched. Column numbers start at 0.
+<synopsis>
+Oid PQftable(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ <literal>InvalidOid</literal> is returned if the column number is out of range,
+ or if the specified column is not a simple reference to a table column.
+ You can query the system table <literal>pg_class</literal> to determine
+ exactly which table is referenced.
+ </para>
+
+ <para>
+ The type <type>Oid</type> and the constant
+ <literal>InvalidOid</literal> will be defined when you include
+ the <application>libpq</application> header file. They will both
+ be some integer type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQftablecol">
+ <term><function>PQftablecol</function><indexterm><primary>PQftablecol</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the column number (within its table) of the column making
+ up the specified query result column. Query-result column numbers
+ start at 0, but table columns have nonzero numbers.
+<synopsis>
+int PQftablecol(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ Zero is returned if the column number is out of range, or if the
+ specified column is not a simple reference to a table column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfformat">
+ <term><function>PQfformat</function><indexterm><primary>PQfformat</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the format code indicating the format of the given
+ column. Column numbers start at 0.
+<synopsis>
+int PQfformat(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ Format code zero indicates textual data representation, while format
+ code one indicates binary representation. (Other codes are reserved
+ for future definition.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQftype">
+ <term><function>PQftype</function><indexterm><primary>PQftype</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the data type associated with the given column number.
+ The integer returned is the internal OID number of the type.
+ Column numbers start at 0.
+<synopsis>
+Oid PQftype(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ You can query the system table <literal>pg_type</literal> to
+ obtain the names and properties of the various data types. The
+ <acronym>OID</acronym>s of the built-in data types are defined
+ in the file <filename>catalog/pg_type_d.h</filename>
+ in the <productname>PostgreSQL</productname>
+ installation's <filename>include</filename> directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfmod">
+ <term><function>PQfmod</function><indexterm><primary>PQfmod</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the type modifier of the column associated with the
+ given column number. Column numbers start at 0.
+<synopsis>
+int PQfmod(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ The interpretation of modifier values is type-specific; they
+ typically indicate precision or size limits. The value -1 is
+ used to indicate <quote>no information available</quote>. Most data
+ types do not use modifiers, in which case the value is always
+ -1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfsize">
+ <term><function>PQfsize</function><indexterm><primary>PQfsize</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the size in bytes of the column associated with the
+ given column number. Column numbers start at 0.
+<synopsis>
+int PQfsize(const PGresult *res,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQfsize"/> returns the space allocated for this column
+ in a database row, in other words the size of the server's
+ internal representation of the data type. (Accordingly, it is
+ not really very useful to clients.) A negative value indicates
+ the data type is variable-length.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQbinaryTuples">
+ <term><function>PQbinaryTuples</function><indexterm><primary>PQbinaryTuples</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns 1 if the <structname>PGresult</structname> contains binary data
+ and 0 if it contains text data.
+<synopsis>
+int PQbinaryTuples(const PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ This function is deprecated (except for its use in connection with
+ <command>COPY</command>), because it is possible for a single
+ <structname>PGresult</structname> to contain text data in some columns and
+ binary data in others. <xref linkend="libpq-PQfformat"/> is preferred.
+ <xref linkend="libpq-PQbinaryTuples"/> returns 1 only if all columns of the
+ result are binary (format 1).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQgetvalue">
+ <term><function>PQgetvalue</function><indexterm><primary>PQgetvalue</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns a single field value of one row of a
+ <structname>PGresult</structname>. Row and column numbers start
+ at 0. The caller should not free the result directly. It will
+ be freed when the associated <structname>PGresult</structname> handle is
+ passed to <xref linkend="libpq-PQclear"/>.
+<synopsis>
+char *PQgetvalue(const PGresult *res,
+ int row_number,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ For data in text format, the value returned by
+ <xref linkend="libpq-PQgetvalue"/> is a null-terminated character
+ string representation of the field value. For data in binary
+ format, the value is in the binary representation determined by
+ the data type's <function>typsend</function> and <function>typreceive</function>
+ functions. (The value is actually followed by a zero byte in
+ this case too, but that is not ordinarily useful, since the
+ value is likely to contain embedded nulls.)
+ </para>
+
+ <para>
+ An empty string is returned if the field value is null. See
+ <xref linkend="libpq-PQgetisnull"/> to distinguish null values from
+ empty-string values.
+ </para>
+
+ <para>
+ The pointer returned by <xref linkend="libpq-PQgetvalue"/> points
+ to storage that is part of the <structname>PGresult</structname>
+ structure. One should not modify the data it points to, and one
+ must explicitly copy the data into other storage if it is to be
+ used past the lifetime of the <structname>PGresult</structname>
+ structure itself.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQgetisnull">
+ <term><function>PQgetisnull</function><indexterm
+ ><primary>PQgetisnull</primary></indexterm><indexterm
+ ><primary>null value</primary><secondary sortas="libpq">in libpq</secondary></indexterm></term>
+
+ <listitem>
+ <para>
+ Tests a field for a null value. Row and column numbers start
+ at 0.
+<synopsis>
+int PQgetisnull(const PGresult *res,
+ int row_number,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ This function returns 1 if the field is null and 0 if it
+ contains a non-null value. (Note that
+ <xref linkend="libpq-PQgetvalue"/> will return an empty string,
+ not a null pointer, for a null field.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQgetlength">
+ <term><function>PQgetlength</function><indexterm><primary>PQgetlength</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the actual length of a field value in bytes. Row and
+ column numbers start at 0.
+<synopsis>
+int PQgetlength(const PGresult *res,
+ int row_number,
+ int column_number);
+</synopsis>
+ </para>
+
+ <para>
+ This is the actual data length for the particular data value,
+ that is, the size of the object pointed to by
+ <xref linkend="libpq-PQgetvalue"/>. For text data format this is
+ the same as <function>strlen()</function>. For binary format this is
+ essential information. Note that one should <emphasis>not</emphasis>
+ rely on <xref linkend="libpq-PQfsize"/> to obtain the actual data
+ length.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQnparams">
+ <term><function>PQnparams</function><indexterm><primary>PQnparams</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the number of parameters of a prepared statement.
+<synopsis>
+int PQnparams(const PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ This function is only useful when inspecting the result of
+ <xref linkend="libpq-PQdescribePrepared"/>. For other types of queries it
+ will return zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQparamtype">
+ <term><function>PQparamtype</function><indexterm><primary>PQparamtype</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the data type of the indicated statement parameter.
+ Parameter numbers start at 0.
+<synopsis>
+Oid PQparamtype(const PGresult *res, int param_number);
+</synopsis>
+ </para>
+
+ <para>
+ This function is only useful when inspecting the result of
+ <xref linkend="libpq-PQdescribePrepared"/>. For other types of queries it
+ will return zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQprint">
+ <term><function>PQprint</function><indexterm><primary>PQprint</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Prints out all the rows and, optionally, the column names to
+ the specified output stream.
+<synopsis>
+void PQprint(FILE *fout, /* output stream */
+ const PGresult *res,
+ const PQprintOpt *po);
+typedef struct
+{
+ pqbool header; /* print output field headings and row count */
+ pqbool align; /* fill align the fields */
+ pqbool standard; /* old brain dead format */
+ pqbool html3; /* output HTML tables */
+ pqbool expanded; /* expand tables */
+ pqbool pager; /* use pager for output if needed */
+ char *fieldSep; /* field separator */
+ char *tableOpt; /* attributes for HTML table element */
+ char *caption; /* HTML table caption */
+ char **fieldName; /* null-terminated array of replacement field names */
+} PQprintOpt;
+</synopsis>
+ </para>
+
+ <para>
+ This function was formerly used by <application>psql</application>
+ to print query results, but this is no longer the case. Note
+ that it assumes all the data is in text format.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="libpq-exec-nonselect">
+ <title>Retrieving Other Result Information</title>
+
+ <para>
+ These functions are used to extract other information from
+ <structname>PGresult</structname> objects.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQcmdStatus">
+ <term><function>PQcmdStatus</function><indexterm><primary>PQcmdStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the command status tag from the SQL command that generated
+ the <structname>PGresult</structname>.
+<synopsis>
+char *PQcmdStatus(PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ Commonly this is just the name of the command, but it might include
+ additional data such as the number of rows processed. The caller
+ should not free the result directly. It will be freed when the
+ associated <structname>PGresult</structname> handle is passed to
+ <xref linkend="libpq-PQclear"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQcmdTuples">
+ <term><function>PQcmdTuples</function><indexterm><primary>PQcmdTuples</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the number of rows affected by the SQL command.
+<synopsis>
+char *PQcmdTuples(PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ This function returns a string containing the number of rows
+ affected by the <acronym>SQL</acronym> statement that generated the
+ <structname>PGresult</structname>. This function can only be used following
+ the execution of a <command>SELECT</command>, <command>CREATE TABLE AS</command>,
+ <command>INSERT</command>, <command>UPDATE</command>, <command>DELETE</command>,
+ <command>MERGE</command>, <command>MOVE</command>, <command>FETCH</command>,
+ or <command>COPY</command> statement, or an <command>EXECUTE</command> of a
+ prepared query that contains an <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>,
+ or <command>MERGE</command> statement.
+ If the command that generated the <structname>PGresult</structname> was anything
+ else, <xref linkend="libpq-PQcmdTuples"/> returns an empty string. The caller
+ should not free the return value directly. It will be freed when
+ the associated <structname>PGresult</structname> handle is passed to
+ <xref linkend="libpq-PQclear"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQoidValue">
+ <term><function>PQoidValue</function><indexterm><primary>PQoidValue</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the OID<indexterm><primary>OID</primary><secondary>in libpq</secondary></indexterm>
+ of the inserted row, if the <acronym>SQL</acronym> command was an
+ <command>INSERT</command> that inserted exactly one row into a table that
+ has OIDs, or a <command>EXECUTE</command> of a prepared query containing
+ a suitable <command>INSERT</command> statement. Otherwise, this function
+ returns <literal>InvalidOid</literal>. This function will also
+ return <literal>InvalidOid</literal> if the table affected by the
+ <command>INSERT</command> statement does not contain OIDs.
+<synopsis>
+Oid PQoidValue(const PGresult *res);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQoidStatus">
+ <term><function>PQoidStatus</function><indexterm><primary>PQoidStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ This function is deprecated in favor of
+ <xref linkend="libpq-PQoidValue"/> and is not thread-safe.
+ It returns a string with the OID of the inserted row, while
+ <xref linkend="libpq-PQoidValue"/> returns the OID value.
+<synopsis>
+char *PQoidStatus(const PGresult *res);
+</synopsis>
+ </para>
+
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="libpq-exec-escape-string">
+ <title>Escaping Strings for Inclusion in SQL Commands</title>
+
+ <indexterm zone="libpq-exec-escape-string">
+ <primary>escaping strings</primary>
+ <secondary>in libpq</secondary>
+ </indexterm>
+
+ <variablelist>
+ <varlistentry id="libpq-PQescapeLiteral">
+ <term><function>PQescapeLiteral</function><indexterm><primary>PQescapeLiteral</primary></indexterm></term>
+
+ <listitem>
+ <para>
+<synopsis>
+char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeLiteral"/> escapes a string for
+ use within an SQL command. This is useful when inserting data
+ values as literal constants in SQL commands. Certain characters
+ (such as quotes and backslashes) must be escaped to prevent them
+ from being interpreted specially by the SQL parser.
+ <xref linkend="libpq-PQescapeLiteral"/> performs this operation.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeLiteral"/> returns an escaped version of the
+ <parameter>str</parameter> parameter in memory allocated with
+ <function>malloc()</function>. This memory should be freed using
+ <function>PQfreemem()</function> when the result is no longer needed.
+ A terminating zero byte is not required, and should not be
+ counted in <parameter>length</parameter>. (If a terminating zero byte is found
+ before <parameter>length</parameter> bytes are processed,
+ <xref linkend="libpq-PQescapeLiteral"/> stops at the zero; the behavior is
+ thus rather like <function>strncpy</function>.) The
+ return string has all special characters replaced so that they can
+ be properly processed by the <productname>PostgreSQL</productname>
+ string literal parser. A terminating zero byte is also added. The
+ single quotes that must surround <productname>PostgreSQL</productname>
+ string literals are included in the result string.
+ </para>
+
+ <para>
+ On error, <xref linkend="libpq-PQescapeLiteral"/> returns <symbol>NULL</symbol> and a suitable
+ message is stored in the <parameter>conn</parameter> object.
+ </para>
+
+ <tip>
+ <para>
+ It is especially important to do proper escaping when handling
+ strings that were received from an untrustworthy source.
+ Otherwise there is a security risk: you are vulnerable to
+ <quote>SQL injection</quote> attacks wherein unwanted SQL commands are
+ fed to your database.
+ </para>
+ </tip>
+
+ <para>
+ Note that it is neither necessary nor correct to do escaping when a data
+ value is passed as a separate parameter in <xref linkend="libpq-PQexecParams"/> or
+ its sibling routines.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQescapeIdentifier">
+ <term><function>PQescapeIdentifier</function><indexterm><primary>PQescapeIdentifier</primary></indexterm></term>
+
+ <listitem>
+ <para>
+<synopsis>
+char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeIdentifier"/> escapes a string for
+ use as an SQL identifier, such as a table, column, or function name.
+ This is useful when a user-supplied identifier might contain
+ special characters that would otherwise not be interpreted as part
+ of the identifier by the SQL parser, or when the identifier might
+ contain upper case characters whose case should be preserved.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeIdentifier"/> returns a version of the
+ <parameter>str</parameter> parameter escaped as an SQL identifier
+ in memory allocated with <function>malloc()</function>. This memory must be
+ freed using <function>PQfreemem()</function> when the result is no longer
+ needed. A terminating zero byte is not required, and should not be
+ counted in <parameter>length</parameter>. (If a terminating zero byte is found
+ before <parameter>length</parameter> bytes are processed,
+ <xref linkend="libpq-PQescapeIdentifier"/> stops at the zero; the behavior is
+ thus rather like <function>strncpy</function>.) The
+ return string has all special characters replaced so that it
+ will be properly processed as an SQL identifier. A terminating zero byte
+ is also added. The return string will also be surrounded by double
+ quotes.
+ </para>
+
+ <para>
+ On error, <xref linkend="libpq-PQescapeIdentifier"/> returns <symbol>NULL</symbol> and a suitable
+ message is stored in the <parameter>conn</parameter> object.
+ </para>
+
+ <tip>
+ <para>
+ As with string literals, to prevent SQL injection attacks,
+ SQL identifiers must be escaped when they are received from an
+ untrustworthy source.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQescapeStringConn">
+ <term><function>PQescapeStringConn</function><indexterm><primary>PQescapeStringConn</primary></indexterm></term>
+
+ <listitem>
+ <para>
+<synopsis>
+size_t PQescapeStringConn(PGconn *conn,
+ char *to, const char *from, size_t length,
+ int *error);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeStringConn"/> escapes string literals, much like
+ <xref linkend="libpq-PQescapeLiteral"/>. Unlike <xref linkend="libpq-PQescapeLiteral"/>,
+ the caller is responsible for providing an appropriately sized buffer.
+ Furthermore, <xref linkend="libpq-PQescapeStringConn"/> does not generate the
+ single quotes that must surround <productname>PostgreSQL</productname> string
+ literals; they should be provided in the SQL command that the
+ result is inserted into. The parameter <parameter>from</parameter> points to
+ the first character of the string that is to be escaped, and the
+ <parameter>length</parameter> parameter gives the number of bytes in this
+ string. A terminating zero byte is not required, and should not be
+ counted in <parameter>length</parameter>. (If a terminating zero byte is found
+ before <parameter>length</parameter> bytes are processed,
+ <xref linkend="libpq-PQescapeStringConn"/> stops at the zero; the behavior is
+ thus rather like <function>strncpy</function>.) <parameter>to</parameter> shall point
+ to a buffer that is able to hold at least one more byte than twice
+ the value of <parameter>length</parameter>, otherwise the behavior is undefined.
+ Behavior is likewise undefined if the <parameter>to</parameter> and
+ <parameter>from</parameter> strings overlap.
+ </para>
+
+ <para>
+ If the <parameter>error</parameter> parameter is not <symbol>NULL</symbol>, then
+ <literal>*error</literal> is set to zero on success, nonzero on error.
+ Presently the only possible error conditions involve invalid multibyte
+ encoding in the source string. The output string is still generated
+ on error, but it can be expected that the server will reject it as
+ malformed. On error, a suitable message is stored in the
+ <parameter>conn</parameter> object, whether or not <parameter>error</parameter> is <symbol>NULL</symbol>.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeStringConn"/> returns the number of bytes written
+ to <parameter>to</parameter>, not including the terminating zero byte.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQescapeString">
+ <term><function>PQescapeString</function><indexterm><primary>PQescapeString</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQescapeString"/> is an older, deprecated version of
+ <xref linkend="libpq-PQescapeStringConn"/>.
+<synopsis>
+size_t PQescapeString (char *to, const char *from, size_t length);
+</synopsis>
+ </para>
+
+ <para>
+ The only difference from <xref linkend="libpq-PQescapeStringConn"/> is that
+ <xref linkend="libpq-PQescapeString"/> does not take <structname>PGconn</structname>
+ or <parameter>error</parameter> parameters.
+ Because of this, it cannot adjust its behavior depending on the
+ connection properties (such as character encoding) and therefore
+ <emphasis>it might give the wrong results</emphasis>. Also, it has no way
+ to report error conditions.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeString"/> can be used safely in
+ client programs that work with only one <productname>PostgreSQL</productname>
+ connection at a time (in this case it can find out what it needs to
+ know <quote>behind the scenes</quote>). In other contexts it is a security
+ hazard and should be avoided in favor of
+ <xref linkend="libpq-PQescapeStringConn"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQescapeByteaConn">
+ <term><function>PQescapeByteaConn</function><indexterm><primary>PQescapeByteaConn</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Escapes binary data for use within an SQL command with the type
+ <type>bytea</type>. As with <xref linkend="libpq-PQescapeStringConn"/>,
+ this is only used when inserting data directly into an SQL command string.
+<synopsis>
+unsigned char *PQescapeByteaConn(PGconn *conn,
+ const unsigned char *from,
+ size_t from_length,
+ size_t *to_length);
+</synopsis>
+ </para>
+
+ <para>
+ Certain byte values must be escaped when used as part of a
+ <type>bytea</type> literal in an <acronym>SQL</acronym> statement.
+ <xref linkend="libpq-PQescapeByteaConn"/> escapes bytes using
+ either hex encoding or backslash escaping. See <xref
+ linkend="datatype-binary"/> for more information.
+ </para>
+
+ <para>
+ The <parameter>from</parameter> parameter points to the first
+ byte of the string that is to be escaped, and the
+ <parameter>from_length</parameter> parameter gives the number of
+ bytes in this binary string. (A terminating zero byte is
+ neither necessary nor counted.) The <parameter>to_length</parameter>
+ parameter points to a variable that will hold the resultant
+ escaped string length. This result string length includes the terminating
+ zero byte of the result.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQescapeByteaConn"/> returns an escaped version of the
+ <parameter>from</parameter> parameter binary string in memory
+ allocated with <function>malloc()</function>. This memory should be freed using
+ <function>PQfreemem()</function> when the result is no longer needed. The
+ return string has all special characters replaced so that they can
+ be properly processed by the <productname>PostgreSQL</productname>
+ string literal parser, and the <type>bytea</type> input function. A
+ terminating zero byte is also added. The single quotes that must
+ surround <productname>PostgreSQL</productname> string literals are
+ not part of the result string.
+ </para>
+
+ <para>
+ On error, a null pointer is returned, and a suitable error message
+ is stored in the <parameter>conn</parameter> object. Currently, the only
+ possible error is insufficient memory for the result string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQescapeBytea">
+ <term><function>PQescapeBytea</function><indexterm><primary>PQescapeBytea</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQescapeBytea"/> is an older, deprecated version of
+ <xref linkend="libpq-PQescapeByteaConn"/>.
+<synopsis>
+unsigned char *PQescapeBytea(const unsigned char *from,
+ size_t from_length,
+ size_t *to_length);
+</synopsis>
+ </para>
+
+ <para>
+ The only difference from <xref linkend="libpq-PQescapeByteaConn"/> is that
+ <xref linkend="libpq-PQescapeBytea"/> does not take a <structname>PGconn</structname>
+ parameter. Because of this, <xref linkend="libpq-PQescapeBytea"/> can
+ only be used safely in client programs that use a single
+ <productname>PostgreSQL</productname> connection at a time (in this case
+ it can find out what it needs to know <quote>behind the
+ scenes</quote>). It <emphasis>might give the wrong results</emphasis> if
+ used in programs that use multiple database connections (use
+ <xref linkend="libpq-PQescapeByteaConn"/> in such cases).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQunescapeBytea">
+ <term><function>PQunescapeBytea</function><indexterm><primary>PQunescapeBytea</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Converts a string representation of binary data into binary data
+ &mdash; the reverse of <xref linkend="libpq-PQescapeBytea"/>. This
+ is needed when retrieving <type>bytea</type> data in text format,
+ but not when retrieving it in binary format.
+
+<synopsis>
+unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
+</synopsis>
+ </para>
+
+ <para>
+ The <parameter>from</parameter> parameter points to a string
+ such as might be returned by <xref linkend="libpq-PQgetvalue"/> when applied
+ to a <type>bytea</type> column. <xref linkend="libpq-PQunescapeBytea"/>
+ converts this string representation into its binary representation.
+ It returns a pointer to a buffer allocated with
+ <function>malloc()</function>, or <symbol>NULL</symbol> on error, and puts the size of
+ the buffer in <parameter>to_length</parameter>. The result must be
+ freed using <xref linkend="libpq-PQfreemem"/> when it is no longer needed.
+ </para>
+
+ <para>
+ This conversion is not exactly the inverse of
+ <xref linkend="libpq-PQescapeBytea"/>, because the string is not expected
+ to be <quote>escaped</quote> when received from <xref linkend="libpq-PQgetvalue"/>.
+ In particular this means there is no need for string quoting considerations,
+ and so no need for a <structname>PGconn</structname> parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="libpq-async">
+ <title>Asynchronous Command Processing</title>
+
+ <indexterm zone="libpq-async">
+ <primary>nonblocking connection</primary>
+ </indexterm>
+
+ <para>
+ The <xref linkend="libpq-PQexec"/> function is adequate for submitting
+ commands in normal, synchronous applications. It has a few
+ deficiencies, however, that can be of importance to some users:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQexec"/> waits for the command to be completed.
+ The application might have other work to do (such as maintaining a
+ user interface), in which case it won't want to block waiting for
+ the response.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Since the execution of the client application is suspended while it
+ waits for the result, it is hard for the application to decide that
+ it would like to try to cancel the ongoing command. (It can be done
+ from a signal handler, but not otherwise.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQexec"/> can return only one
+ <structname>PGresult</structname> structure. If the submitted command
+ string contains multiple <acronym>SQL</acronym> commands, all but
+ the last <structname>PGresult</structname> are discarded by
+ <xref linkend="libpq-PQexec"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQexec"/> always collects the command's entire result,
+ buffering it in a single <structname>PGresult</structname>. While
+ this simplifies error-handling logic for the application, it can be
+ impractical for results containing many rows.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Applications that do not like these limitations can instead use the
+ underlying functions that <xref linkend="libpq-PQexec"/> is built from:
+ <xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/>.
+ There are also
+ <xref linkend="libpq-PQsendQueryParams"/>,
+ <xref linkend="libpq-PQsendPrepare"/>,
+ <xref linkend="libpq-PQsendQueryPrepared"/>,
+ <xref linkend="libpq-PQsendDescribePrepared"/>, and
+ <xref linkend="libpq-PQsendDescribePortal"/>,
+ which can be used with <xref linkend="libpq-PQgetResult"/> to duplicate
+ the functionality of
+ <xref linkend="libpq-PQexecParams"/>,
+ <xref linkend="libpq-PQprepare"/>,
+ <xref linkend="libpq-PQexecPrepared"/>,
+ <xref linkend="libpq-PQdescribePrepared"/>, and
+ <xref linkend="libpq-PQdescribePortal"/>
+ respectively.
+
+ <variablelist>
+ <varlistentry id="libpq-PQsendQuery">
+ <term><function>PQsendQuery</function><indexterm><primary>PQsendQuery</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a command to the server without waiting for the result(s).
+ 1 is returned if the command was successfully dispatched and 0 if
+ not (in which case, use <xref linkend="libpq-PQerrorMessage"/> to get more
+ information about the failure).
+<synopsis>
+int PQsendQuery(PGconn *conn, const char *command);
+</synopsis>
+
+ After successfully calling <xref linkend="libpq-PQsendQuery"/>, call
+ <xref linkend="libpq-PQgetResult"/> one or more times to obtain the
+ results. <xref linkend="libpq-PQsendQuery"/> cannot be called again
+ (on the same connection) until <xref linkend="libpq-PQgetResult"/>
+ has returned a null pointer, indicating that the command is done.
+ </para>
+
+ <para>
+ In pipeline mode, this function is disallowed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsendQueryParams">
+ <term><function>PQsendQueryParams</function><indexterm><primary>PQsendQueryParams</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a command and separate parameters to the server without
+ waiting for the result(s).
+<synopsis>
+int PQsendQueryParams(PGconn *conn,
+ const char *command,
+ int nParams,
+ const Oid *paramTypes,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</synopsis>
+
+ This is equivalent to <xref linkend="libpq-PQsendQuery"/> except that
+ query parameters can be specified separately from the query string.
+ The function's parameters are handled identically to
+ <xref linkend="libpq-PQexecParams"/>. Like
+ <xref linkend="libpq-PQexecParams"/>, it allows only one command in the
+ query string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsendPrepare">
+ <term><function>PQsendPrepare</function><indexterm><primary>PQsendPrepare</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends a request to create a prepared statement with the given
+ parameters, without waiting for completion.
+<synopsis>
+int PQsendPrepare(PGconn *conn,
+ const char *stmtName,
+ const char *query,
+ int nParams,
+ const Oid *paramTypes);
+</synopsis>
+
+ This is an asynchronous version of <xref linkend="libpq-PQprepare"/>: it
+ returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <xref linkend="libpq-PQgetResult"/> to
+ determine whether the server successfully created the prepared
+ statement. The function's parameters are handled identically to
+ <xref linkend="libpq-PQprepare"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsendQueryPrepared">
+ <term><function>PQsendQueryPrepared</function><indexterm><primary>PQsendQueryPrepared</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends a request to execute a prepared statement with given
+ parameters, without waiting for the result(s).
+<synopsis>
+int PQsendQueryPrepared(PGconn *conn,
+ const char *stmtName,
+ int nParams,
+ const char * const *paramValues,
+ const int *paramLengths,
+ const int *paramFormats,
+ int resultFormat);
+</synopsis>
+
+ This is similar to <xref linkend="libpq-PQsendQueryParams"/>, but
+ the command to be executed is specified by naming a
+ previously-prepared statement, instead of giving a query string.
+ The function's parameters are handled identically to
+ <xref linkend="libpq-PQexecPrepared"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsendDescribePrepared">
+ <term><function>PQsendDescribePrepared</function><indexterm><primary>PQsendDescribePrepared</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a request to obtain information about the specified
+ prepared statement, without waiting for completion.
+<synopsis>
+int PQsendDescribePrepared(PGconn *conn, const char *stmtName);
+</synopsis>
+
+ This is an asynchronous version of <xref linkend="libpq-PQdescribePrepared"/>:
+ it returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <xref linkend="libpq-PQgetResult"/> to
+ obtain the results. The function's parameters are handled
+ identically to <xref linkend="libpq-PQdescribePrepared"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsendDescribePortal">
+ <term><function>PQsendDescribePortal</function><indexterm><primary>PQsendDescribePortal</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Submits a request to obtain information about the specified
+ portal, without waiting for completion.
+<synopsis>
+int PQsendDescribePortal(PGconn *conn, const char *portalName);
+</synopsis>
+
+ This is an asynchronous version of <xref linkend="libpq-PQdescribePortal"/>:
+ it returns 1 if it was able to dispatch the request, and 0 if not.
+ After a successful call, call <xref linkend="libpq-PQgetResult"/> to
+ obtain the results. The function's parameters are handled
+ identically to <xref linkend="libpq-PQdescribePortal"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQgetResult">
+ <term><function>PQgetResult</function><indexterm><primary>PQgetResult</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Waits for the next result from a prior
+ <xref linkend="libpq-PQsendQuery"/>,
+ <xref linkend="libpq-PQsendQueryParams"/>,
+ <xref linkend="libpq-PQsendPrepare"/>,
+ <xref linkend="libpq-PQsendQueryPrepared"/>,
+ <xref linkend="libpq-PQsendDescribePrepared"/>,
+ <xref linkend="libpq-PQsendDescribePortal"/>, or
+ <xref linkend="libpq-PQpipelineSync"/>
+ call, and returns it.
+ A null pointer is returned when the command is complete and there
+ will be no more results.
+<synopsis>
+PGresult *PQgetResult(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQgetResult"/> must be called repeatedly until
+ it returns a null pointer, indicating that the command is done.
+ (If called when no command is active,
+ <xref linkend="libpq-PQgetResult"/> will just return a null pointer
+ at once.) Each non-null result from
+ <xref linkend="libpq-PQgetResult"/> should be processed using the
+ same <structname>PGresult</structname> accessor functions previously
+ described. Don't forget to free each result object with
+ <xref linkend="libpq-PQclear"/> when done with it. Note that
+ <xref linkend="libpq-PQgetResult"/> will block only if a command is
+ active and the necessary response data has not yet been read by
+ <xref linkend="libpq-PQconsumeInput"/>.
+ </para>
+
+ <para>
+ In pipeline mode, <function>PQgetResult</function> will return normally
+ unless an error occurs; for any subsequent query sent after the one
+ that caused the error until (and excluding) the next synchronization point,
+ a special result of type <literal>PGRES_PIPELINE_ABORTED</literal> will
+ be returned, and a null pointer will be returned after it.
+ When the pipeline synchronization point is reached, a result of type
+ <literal>PGRES_PIPELINE_SYNC</literal> will be returned.
+ The result of the next query after the synchronization point follows
+ immediately (that is, no null pointer is returned after
+ the synchronization point.)
+ </para>
+
+ <note>
+ <para>
+ Even when <xref linkend="libpq-PQresultStatus"/> indicates a fatal
+ error, <xref linkend="libpq-PQgetResult"/> should be called until it
+ returns a null pointer, to allow <application>libpq</application> to
+ process the error information completely.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Using <xref linkend="libpq-PQsendQuery"/> and
+ <xref linkend="libpq-PQgetResult"/> solves one of
+ <xref linkend="libpq-PQexec"/>'s problems: If a command string contains
+ multiple <acronym>SQL</acronym> commands, the results of those commands
+ can be obtained individually. (This allows a simple form of overlapped
+ processing, by the way: the client can be handling the results of one
+ command while the server is still working on later queries in the same
+ command string.)
+ </para>
+
+ <para>
+ Another frequently-desired feature that can be obtained with
+ <xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/>
+ is retrieving large query results a row at a time. This is discussed
+ in <xref linkend="libpq-single-row-mode"/>.
+ </para>
+
+ <para>
+ By itself, calling <xref linkend="libpq-PQgetResult"/>
+ will still cause the client to block until the server completes the
+ next <acronym>SQL</acronym> command. This can be avoided by proper
+ use of two more functions:
+
+ <variablelist>
+ <varlistentry id="libpq-PQconsumeInput">
+ <term><function>PQconsumeInput</function><indexterm><primary>PQconsumeInput</primary></indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ If input is available from the server, consume it.
+<synopsis>
+int PQconsumeInput(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQconsumeInput"/> normally returns 1 indicating
+ <quote>no error</quote>, but returns 0 if there was some kind of
+ trouble (in which case <xref linkend="libpq-PQerrorMessage"/> can be
+ consulted). Note that the result does not say whether any input
+ data was actually collected. After calling
+ <xref linkend="libpq-PQconsumeInput"/>, the application can check
+ <xref linkend="libpq-PQisBusy"/> and/or
+ <function>PQnotifies</function> to see if their state has changed.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQconsumeInput"/> can be called even if the
+ application is not prepared to deal with a result or notification
+ just yet. The function will read available data and save it in
+ a buffer, thereby causing a <function>select()</function>
+ read-ready indication to go away. The application can thus use
+ <xref linkend="libpq-PQconsumeInput"/> to clear the
+ <function>select()</function> condition immediately, and then
+ examine the results at leisure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQisBusy">
+ <term><function>PQisBusy</function><indexterm><primary>PQisBusy</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns 1 if a command is busy, that is,
+ <xref linkend="libpq-PQgetResult"/> would block waiting for input.
+ A 0 return indicates that <xref linkend="libpq-PQgetResult"/> can be
+ called with assurance of not blocking.
+<synopsis>
+int PQisBusy(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQisBusy"/> will not itself attempt to read data
+ from the server; therefore <xref linkend="libpq-PQconsumeInput"/>
+ must be invoked first, or the busy state will never end.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ A typical application using these functions will have a main loop that
+ uses <function>select()</function> or <function>poll()</function> to wait for
+ all the conditions that it must respond to. One of the conditions
+ will be input available from the server, which in terms of
+ <function>select()</function> means readable data on the file
+ descriptor identified by <xref linkend="libpq-PQsocket"/>. When the main
+ loop detects input ready, it should call
+ <xref linkend="libpq-PQconsumeInput"/> to read the input. It can then
+ call <xref linkend="libpq-PQisBusy"/>, followed by
+ <xref linkend="libpq-PQgetResult"/> if <xref linkend="libpq-PQisBusy"/>
+ returns false (0). It can also call <function>PQnotifies</function>
+ to detect <command>NOTIFY</command> messages (see <xref
+ linkend="libpq-notify"/>).
+ </para>
+
+ <para>
+ A client that uses
+ <xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/>
+ can also attempt to cancel a command that is still being processed
+ by the server; see <xref linkend="libpq-cancel"/>. But regardless of
+ the return value of <xref linkend="libpq-PQcancel"/>, the application
+ must continue with the normal result-reading sequence using
+ <xref linkend="libpq-PQgetResult"/>. A successful cancellation will
+ simply cause the command to terminate sooner than it would have
+ otherwise.
+ </para>
+
+ <para>
+ By using the functions described above, it is possible to avoid
+ blocking while waiting for input from the database server. However,
+ it is still possible that the application will block waiting to send
+ output to the server. This is relatively uncommon but can happen if
+ very long SQL commands or data values are sent. (It is much more
+ probable if the application sends data via <command>COPY IN</command>,
+ however.) To prevent this possibility and achieve completely
+ nonblocking database operation, the following additional functions
+ can be used.
+
+ <variablelist>
+ <varlistentry id="libpq-PQsetnonblocking">
+ <term><function>PQsetnonblocking</function><indexterm><primary>PQsetnonblocking</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sets the nonblocking status of the connection.
+<synopsis>
+int PQsetnonblocking(PGconn *conn, int arg);
+</synopsis>
+ </para>
+
+ <para>
+ Sets the state of the connection to nonblocking if
+ <parameter>arg</parameter> is 1, or blocking if
+ <parameter>arg</parameter> is 0. Returns 0 if OK, -1 if error.
+ </para>
+
+ <para>
+ In the nonblocking state, calls to
+ <xref linkend="libpq-PQsendQuery"/>, <xref linkend="libpq-PQputline"/>,
+ <xref linkend="libpq-PQputnbytes"/>, <xref linkend="libpq-PQputCopyData"/>,
+ and <xref linkend="libpq-PQendcopy"/> will not block but instead return
+ an error if they need to be called again.
+ </para>
+
+ <para>
+ Note that <xref linkend="libpq-PQexec"/> does not honor nonblocking
+ mode; if it is called, it will act in blocking fashion anyway.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQisnonblocking">
+ <term><function>PQisnonblocking</function><indexterm><primary>PQisnonblocking</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the blocking status of the database connection.
+<synopsis>
+int PQisnonblocking(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ Returns 1 if the connection is set to nonblocking mode and 0 if
+ blocking.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQflush">
+ <term><function>PQflush</function><indexterm><primary>PQflush</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Attempts to flush any queued output data to the server. Returns
+ 0 if successful (or if the send queue is empty), -1 if it failed
+ for some reason, or 1 if it was unable to send all the data in
+ the send queue yet (this case can only occur if the connection
+ is nonblocking).
+<synopsis>
+int PQflush(PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ After sending any command or data on a nonblocking connection, call
+ <xref linkend="libpq-PQflush"/>. If it returns 1, wait for the socket
+ to become read- or write-ready. If it becomes write-ready, call
+ <xref linkend="libpq-PQflush"/> again. If it becomes read-ready, call
+ <xref linkend="libpq-PQconsumeInput"/>, then call
+ <xref linkend="libpq-PQflush"/> again. Repeat until
+ <xref linkend="libpq-PQflush"/> returns 0. (It is necessary to check for
+ read-ready and drain the input with <xref linkend="libpq-PQconsumeInput"/>,
+ because the server can block trying to send us data, e.g., NOTICE
+ messages, and won't read our data until we read its.) Once
+ <xref linkend="libpq-PQflush"/> returns 0, wait for the socket to be
+ read-ready and then read the response as described above.
+ </para>
+
+ </sect1>
+
+ <sect1 id="libpq-pipeline-mode">
+ <title>Pipeline Mode</title>
+
+ <indexterm zone="libpq-pipeline-mode">
+ <primary>libpq</primary>
+ <secondary>pipeline mode</secondary>
+ </indexterm>
+
+ <indexterm zone="libpq-pipeline-mode">
+ <primary>pipelining</primary>
+ <secondary>in libpq</secondary>
+ </indexterm>
+
+ <indexterm zone="libpq-pipeline-mode">
+ <primary>batch mode</primary>
+ <secondary>in libpq</secondary>
+ </indexterm>
+
+ <para>
+ <application>libpq</application> pipeline mode allows applications to
+ send a query without having to read the result of the previously
+ sent query. Taking advantage of the pipeline mode, a client will wait
+ less for the server, since multiple queries/results can be
+ sent/received in a single network transaction.
+ </para>
+
+ <para>
+ While pipeline mode provides a significant performance boost, writing
+ clients using the pipeline mode is more complex because it involves
+ managing a queue of pending queries and finding which result
+ corresponds to which query in the queue.
+ </para>
+
+ <para>
+ Pipeline mode also generally consumes more memory on both the client and server,
+ though careful and aggressive management of the send/receive queue can mitigate
+ this. This applies whether or not the connection is in blocking or non-blocking
+ mode.
+ </para>
+
+ <para>
+ While <application>libpq</application>'s pipeline API was introduced in
+ <productname>PostgreSQL</productname> 14, it is a client-side feature
+ which doesn't require special server support and works on any server
+ that supports the v3 extended query protocol. For more information see
+ <xref linkend="protocol-flow-pipelining"/>.
+ </para>
+
+ <sect2 id="libpq-pipeline-using">
+ <title>Using Pipeline Mode</title>
+
+ <para>
+ To issue pipelines, the application must switch the connection
+ into pipeline mode,
+ which is done with <xref linkend="libpq-PQenterPipelineMode"/>.
+ <xref linkend="libpq-PQpipelineStatus"/> can be used
+ to test whether pipeline mode is active.
+ In pipeline mode, only <link linkend="libpq-async">asynchronous operations</link>
+ that utilize the extended query protocol
+ are permitted, command strings containing multiple SQL commands are
+ disallowed, and so is <literal>COPY</literal>.
+ Using synchronous command execution functions
+ such as <function>PQfn</function>,
+ <function>PQexec</function>,
+ <function>PQexecParams</function>,
+ <function>PQprepare</function>,
+ <function>PQexecPrepared</function>,
+ <function>PQdescribePrepared</function>,
+ <function>PQdescribePortal</function>,
+ is an error condition.
+ <function>PQsendQuery</function> is
+ also disallowed, because it uses the simple query protocol.
+ Once all dispatched commands have had their results processed, and
+ the end pipeline result has been consumed, the application may return
+ to non-pipelined mode with <xref linkend="libpq-PQexitPipelineMode"/>.
+ </para>
+
+ <note>
+ <para>
+ It is best to use pipeline mode with <application>libpq</application> in
+ <link linkend="libpq-PQsetnonblocking">non-blocking mode</link>. If used
+ in blocking mode it is possible for a client/server deadlock to occur.
+ <footnote>
+ <para>
+ The client will block trying to send queries to the server, but the
+ server will block trying to send results to the client from queries
+ it has already processed. This only occurs when the client sends
+ enough queries to fill both its output buffer and the server's receive
+ buffer before it switches to processing input from the server,
+ but it's hard to predict exactly when that will happen.
+ </para>
+ </footnote>
+ </para>
+ </note>
+
+ <sect3 id="libpq-pipeline-sending">
+ <title>Issuing Queries</title>
+
+ <para>
+ After entering pipeline mode, the application dispatches requests using
+ <xref linkend="libpq-PQsendQueryParams"/>
+ or its prepared-query sibling
+ <xref linkend="libpq-PQsendQueryPrepared"/>.
+ These requests are queued on the client-side until flushed to the server;
+ this occurs when <xref linkend="libpq-PQpipelineSync"/> is used to
+ establish a synchronization point in the pipeline,
+ or when <xref linkend="libpq-PQflush"/> is called.
+ The functions <xref linkend="libpq-PQsendPrepare"/>,
+ <xref linkend="libpq-PQsendDescribePrepared"/>, and
+ <xref linkend="libpq-PQsendDescribePortal"/> also work in pipeline mode.
+ Result processing is described below.
+ </para>
+
+ <para>
+ The server executes statements, and returns results, in the order the
+ client sends them. The server will begin executing the commands in the
+ pipeline immediately, not waiting for the end of the pipeline.
+ Note that results are buffered on the server side; the server flushes
+ that buffer when a synchronization point is established with
+ <function>PQpipelineSync</function>, or when
+ <function>PQsendFlushRequest</function> is called.
+ If any statement encounters an error, the server aborts the current
+ transaction and does not execute any subsequent command in the queue
+ until the next synchronization point;
+ a <literal>PGRES_PIPELINE_ABORTED</literal> result is produced for
+ each such command.
+ (This remains true even if the commands in the pipeline would rollback
+ the transaction.)
+ Query processing resumes after the synchronization point.
+ </para>
+
+ <para>
+ It's fine for one operation to depend on the results of a
+ prior one; for example, one query may define a table that the next
+ query in the same pipeline uses. Similarly, an application may
+ create a named prepared statement and execute it with later
+ statements in the same pipeline.
+ </para>
+ </sect3>
+
+ <sect3 id="libpq-pipeline-results">
+ <title>Processing Results</title>
+
+ <para>
+ To process the result of one query in a pipeline, the application calls
+ <function>PQgetResult</function> repeatedly and handles each result
+ until <function>PQgetResult</function> returns null.
+ The result from the next query in the pipeline may then be retrieved using
+ <function>PQgetResult</function> again and the cycle repeated.
+ The application handles individual statement results as normal.
+ When the results of all the queries in the pipeline have been
+ returned, <function>PQgetResult</function> returns a result
+ containing the status value <literal>PGRES_PIPELINE_SYNC</literal>
+ </para>
+
+ <para>
+ The client may choose to defer result processing until the complete
+ pipeline has been sent, or interleave that with sending further
+ queries in the pipeline; see <xref linkend="libpq-pipeline-interleave"/>.
+ </para>
+
+ <para>
+ To enter single-row mode, call <function>PQsetSingleRowMode</function>
+ before retrieving results with <function>PQgetResult</function>.
+ This mode selection is effective only for the query currently
+ being processed. For more information on the use of
+ <function>PQsetSingleRowMode</function>,
+ refer to <xref linkend="libpq-single-row-mode"/>.
+ </para>
+
+ <para>
+ <function>PQgetResult</function> behaves the same as for normal
+ asynchronous processing except that it may contain the new
+ <type>PGresult</type> types <literal>PGRES_PIPELINE_SYNC</literal>
+ and <literal>PGRES_PIPELINE_ABORTED</literal>.
+ <literal>PGRES_PIPELINE_SYNC</literal> is reported exactly once for each
+ <function>PQpipelineSync</function> at the corresponding point
+ in the pipeline.
+ <literal>PGRES_PIPELINE_ABORTED</literal> is emitted in place of a normal
+ query result for the first error and all subsequent results
+ until the next <literal>PGRES_PIPELINE_SYNC</literal>;
+ see <xref linkend="libpq-pipeline-errors"/>.
+ </para>
+
+ <para>
+ <function>PQisBusy</function>, <function>PQconsumeInput</function>, etc
+ operate as normal when processing pipeline results. In particular,
+ a call to <function>PQisBusy</function> in the middle of a pipeline
+ returns 0 if the results for all the queries issued so far have been
+ consumed.
+ </para>
+
+ <para>
+ <application>libpq</application> does not provide any information to the
+ application about the query currently being processed (except that
+ <function>PQgetResult</function> returns null to indicate that we start
+ returning the results of next query). The application must keep track
+ of the order in which it sent queries, to associate them with their
+ corresponding results.
+ Applications will typically use a state machine or a FIFO queue for this.
+ </para>
+
+ </sect3>
+
+ <sect3 id="libpq-pipeline-errors">
+ <title>Error Handling</title>
+
+ <para>
+ From the client's perspective, after <function>PQresultStatus</function>
+ returns <literal>PGRES_FATAL_ERROR</literal>,
+ the pipeline is flagged as aborted.
+ <function>PQresultStatus</function> will report a
+ <literal>PGRES_PIPELINE_ABORTED</literal> result for each remaining queued
+ operation in an aborted pipeline. The result for
+ <function>PQpipelineSync</function> is reported as
+ <literal>PGRES_PIPELINE_SYNC</literal> to signal the end of the aborted pipeline
+ and resumption of normal result processing.
+ </para>
+
+ <para>
+ The client <emphasis>must</emphasis> process results with
+ <function>PQgetResult</function> during error recovery.
+ </para>
+
+ <para>
+ If the pipeline used an implicit transaction, then operations that have
+ already executed are rolled back and operations that were queued to follow
+ the failed operation are skipped entirely. The same behavior holds if the
+ pipeline starts and commits a single explicit transaction (i.e. the first
+ statement is <literal>BEGIN</literal> and the last is
+ <literal>COMMIT</literal>) except that the session remains in an aborted
+ transaction state at the end of the pipeline. If a pipeline contains
+ <emphasis>multiple explicit transactions</emphasis>, all transactions that
+ committed prior to the error remain committed, the currently in-progress
+ transaction is aborted, and all subsequent operations are skipped completely,
+ including subsequent transactions. If a pipeline synchronization point
+ occurs with an explicit transaction block in aborted state, the next pipeline
+ will become aborted immediately unless the next command puts the transaction
+ in normal mode with <command>ROLLBACK</command>.
+ </para>
+
+ <note>
+ <para>
+ The client must not assume that work is committed when it
+ <emphasis>sends</emphasis> a <literal>COMMIT</literal> &mdash; only when the
+ corresponding result is received to confirm the commit is complete.
+ Because errors arrive asynchronously, the application needs to be able to
+ restart from the last <emphasis>received</emphasis> committed change and
+ resend work done after that point if something goes wrong.
+ </para>
+ </note>
+ </sect3>
+
+ <sect3 id="libpq-pipeline-interleave">
+ <title>Interleaving Result Processing and Query Dispatch</title>
+
+ <para>
+ To avoid deadlocks on large pipelines the client should be structured
+ around a non-blocking event loop using operating system facilities
+ such as <function>select</function>, <function>poll</function>,
+ <function>WaitForMultipleObjectEx</function>, etc.
+ </para>
+
+ <para>
+ The client application should generally maintain a queue of work
+ remaining to be dispatched and a queue of work that has been dispatched
+ but not yet had its results processed. When the socket is writable
+ it should dispatch more work. When the socket is readable it should
+ read results and process them, matching them up to the next entry in
+ its corresponding results queue. Based on available memory, results from the
+ socket should be read frequently: there's no need to wait until the
+ pipeline end to read the results. Pipelines should be scoped to logical
+ units of work, usually (but not necessarily) one transaction per pipeline.
+ There's no need to exit pipeline mode and re-enter it between pipelines,
+ or to wait for one pipeline to finish before sending the next.
+ </para>
+
+ <para>
+ An example using <function>select()</function> and a simple state
+ machine to track sent and received work is in
+ <filename>src/test/modules/libpq_pipeline/libpq_pipeline.c</filename>
+ in the PostgreSQL source distribution.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="libpq-pipeline-functions">
+ <title>Functions Associated with Pipeline Mode</title>
+
+ <variablelist>
+
+ <varlistentry id="libpq-PQpipelineStatus">
+ <term><function>PQpipelineStatus</function><indexterm><primary>PQpipelineStatus</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the current pipeline mode status of the
+ <application>libpq</application> connection.
+<synopsis>
+PGpipelineStatus PQpipelineStatus(const PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <function>PQpipelineStatus</function> can return one of the following values:
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal>PQ_PIPELINE_ON</literal>
+ </term>
+ <listitem>
+ <para>
+ The <application>libpq</application> connection is in
+ pipeline mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>PQ_PIPELINE_OFF</literal>
+ </term>
+ <listitem>
+ <para>
+ The <application>libpq</application> connection is
+ <emphasis>not</emphasis> in pipeline mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>PQ_PIPELINE_ABORTED</literal>
+ </term>
+ <listitem>
+ <para>
+ The <application>libpq</application> connection is in pipeline
+ mode and an error occurred while processing the current pipeline.
+ The aborted flag is cleared when <function>PQgetResult</function>
+ returns a result of type <literal>PGRES_PIPELINE_SYNC</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQenterPipelineMode">
+ <term><function>PQenterPipelineMode</function><indexterm><primary>PQenterPipelineMode</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Causes a connection to enter pipeline mode if it is currently idle or
+ already in pipeline mode.
+
+<synopsis>
+int PQenterPipelineMode(PGconn *conn);
+</synopsis>
+
+ </para>
+ <para>
+ Returns 1 for success.
+ Returns 0 and has no effect if the connection is not currently
+ idle, i.e., it has a result ready, or it is waiting for more
+ input from the server, etc.
+ This function does not actually send anything to the server,
+ it just changes the <application>libpq</application> connection
+ state.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQexitPipelineMode">
+ <term><function>PQexitPipelineMode</function><indexterm><primary>PQexitPipelineMode</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Causes a connection to exit pipeline mode if it is currently in pipeline mode
+ with an empty queue and no pending results.
+<synopsis>
+int PQexitPipelineMode(PGconn *conn);
+</synopsis>
+ </para>
+ <para>
+ Returns 1 for success. Returns 1 and takes no action if not in
+ pipeline mode. If the current statement isn't finished processing,
+ or <function>PQgetResult</function> has not been called to collect
+ results from all previously sent query, returns 0 (in which case,
+ use <xref linkend="libpq-PQerrorMessage"/> to get more information
+ about the failure).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQpipelineSync">
+ <term><function>PQpipelineSync</function><indexterm><primary>PQpipelineSync</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Marks a synchronization point in a pipeline by sending a
+ <link linkend="protocol-flow-ext-query">sync message</link>
+ and flushing the send buffer. This serves as
+ the delimiter of an implicit transaction and an error recovery
+ point; see <xref linkend="libpq-pipeline-errors"/>.
+
+<synopsis>
+int PQpipelineSync(PGconn *conn);
+</synopsis>
+ </para>
+ <para>
+ Returns 1 for success. Returns 0 if the connection is not in
+ pipeline mode or sending a
+ <link linkend="protocol-flow-ext-query">sync message</link>
+ failed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsendFlushRequest">
+ <term><function>PQsendFlushRequest</function><indexterm><primary>PQsendFlushRequest</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends a request for the server to flush its output buffer.
+<synopsis>
+int PQsendFlushRequest(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ Returns 1 for success. Returns 0 on any failure.
+ </para>
+ <para>
+ The server flushes its output buffer automatically as a result of
+ <function>PQpipelineSync</function> being called, or
+ on any request when not in pipeline mode; this function is useful
+ to cause the server to flush its output buffer in pipeline mode
+ without establishing a synchronization point.
+ Note that the request is not itself flushed to the server automatically;
+ use <function>PQflush</function> if necessary.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="libpq-pipeline-tips">
+ <title>When to Use Pipeline Mode</title>
+
+ <para>
+ Much like asynchronous query mode, there is no meaningful performance
+ overhead when using pipeline mode. It increases client application complexity,
+ and extra caution is required to prevent client/server deadlocks, but
+ pipeline mode can offer considerable performance improvements, in exchange for
+ increased memory usage from leaving state around longer.
+ </para>
+
+ <para>
+ Pipeline mode is most useful when the server is distant, i.e., network latency
+ (<quote>ping time</quote>) is high, and also when many small operations
+ are being performed in rapid succession. There is usually less benefit
+ in using pipelined commands when each query takes many multiples of the client/server
+ round-trip time to execute. A 100-statement operation run on a server
+ 300 ms round-trip-time away would take 30 seconds in network latency alone
+ without pipelining; with pipelining it may spend as little as 0.3 s waiting for
+ results from the server.
+ </para>
+
+ <para>
+ Use pipelined commands when your application does lots of small
+ <literal>INSERT</literal>, <literal>UPDATE</literal> and
+ <literal>DELETE</literal> operations that can't easily be transformed
+ into operations on sets, or into a <literal>COPY</literal> operation.
+ </para>
+
+ <para>
+ Pipeline mode is not useful when information from one operation is required by
+ the client to produce the next operation. In such cases, the client
+ would have to introduce a synchronization point and wait for a full client/server
+ round-trip to get the results it needs. However, it's often possible to
+ adjust the client design to exchange the required information server-side.
+ Read-modify-write cycles are especially good candidates; for example:
+<programlisting>
+BEGIN;
+SELECT x FROM mytable WHERE id = 42 FOR UPDATE;
+-- result: x=2
+-- client adds 1 to x:
+UPDATE mytable SET x = 3 WHERE id = 42;
+COMMIT;
+</programlisting>
+ could be much more efficiently done with:
+<programlisting>
+UPDATE mytable SET x = x + 1 WHERE id = 42;
+</programlisting>
+ </para>
+
+ <para>
+ Pipelining is less useful, and more complex, when a single pipeline contains
+ multiple transactions (see <xref linkend="libpq-pipeline-errors"/>).
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="libpq-single-row-mode">
+ <title>Retrieving Query Results Row-by-Row</title>
+
+ <indexterm zone="libpq-single-row-mode">
+ <primary>libpq</primary>
+ <secondary>single-row mode</secondary>
+ </indexterm>
+
+ <para>
+ Ordinarily, <application>libpq</application> collects an SQL command's
+ entire result and returns it to the application as a single
+ <structname>PGresult</structname>. This can be unworkable for commands
+ that return a large number of rows. For such cases, applications can use
+ <xref linkend="libpq-PQsendQuery"/> and <xref linkend="libpq-PQgetResult"/> in
+ <firstterm>single-row mode</firstterm>. In this mode, the result row(s) are
+ returned to the application one at a time, as they are received from the
+ server.
+ </para>
+
+ <para>
+ To enter single-row mode, call <xref linkend="libpq-PQsetSingleRowMode"/>
+ immediately after a successful call of <xref linkend="libpq-PQsendQuery"/>
+ (or a sibling function). This mode selection is effective only for the
+ currently executing query. Then call <xref linkend="libpq-PQgetResult"/>
+ repeatedly, until it returns null, as documented in <xref
+ linkend="libpq-async"/>. If the query returns any rows, they are returned
+ as individual <structname>PGresult</structname> objects, which look like
+ normal query results except for having status code
+ <literal>PGRES_SINGLE_TUPLE</literal> instead of
+ <literal>PGRES_TUPLES_OK</literal>. After the last row, or immediately if
+ the query returns zero rows, a zero-row object with status
+ <literal>PGRES_TUPLES_OK</literal> is returned; this is the signal that no
+ more rows will arrive. (But note that it is still necessary to continue
+ calling <xref linkend="libpq-PQgetResult"/> until it returns null.) All of
+ these <structname>PGresult</structname> objects will contain the same row
+ description data (column names, types, etc.) that an ordinary
+ <structname>PGresult</structname> object for the query would have.
+ Each object should be freed with <xref linkend="libpq-PQclear"/> as usual.
+ </para>
+
+ <para>
+ When using pipeline mode, single-row mode needs to be activated for each
+ query in the pipeline before retrieving results for that query
+ with <function>PQgetResult</function>.
+ See <xref linkend="libpq-pipeline-mode"/> for more information.
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry id="libpq-PQsetSingleRowMode">
+ <term><function>PQsetSingleRowMode</function><indexterm><primary>PQsetSingleRowMode</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Select single-row mode for the currently-executing query.
+
+<synopsis>
+int PQsetSingleRowMode(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ This function can only be called immediately after
+ <xref linkend="libpq-PQsendQuery"/> or one of its sibling functions,
+ before any other operation on the connection such as
+ <xref linkend="libpq-PQconsumeInput"/> or
+ <xref linkend="libpq-PQgetResult"/>. If called at the correct time,
+ the function activates single-row mode for the current query and
+ returns 1. Otherwise the mode stays unchanged and the function
+ returns 0. In any case, the mode reverts to normal after
+ completion of the current query.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <caution>
+ <para>
+ While processing a query, the server may return some rows and then
+ encounter an error, causing the query to be aborted. Ordinarily,
+ <application>libpq</application> discards any such rows and reports only the
+ error. But in single-row mode, those rows will have already been
+ returned to the application. Hence, the application will see some
+ <literal>PGRES_SINGLE_TUPLE</literal> <structname>PGresult</structname>
+ objects followed by a <literal>PGRES_FATAL_ERROR</literal> object. For
+ proper transactional behavior, the application must be designed to
+ discard or undo whatever has been done with the previously-processed
+ rows, if the query ultimately fails.
+ </para>
+ </caution>
+
+ </sect1>
+
+ <sect1 id="libpq-cancel">
+ <title>Canceling Queries in Progress</title>
+
+ <indexterm zone="libpq-cancel">
+ <primary>canceling</primary>
+ <secondary>SQL command</secondary>
+ </indexterm>
+
+ <para>
+ A client application can request cancellation of a command that is
+ still being processed by the server, using the functions described in
+ this section.
+
+ <variablelist>
+ <varlistentry id="libpq-PQgetCancel">
+ <term><function>PQgetCancel</function><indexterm><primary>PQgetCancel</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Creates a data structure containing the information needed to cancel
+ a command issued through a particular database connection.
+<synopsis>
+PGcancel *PQgetCancel(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQgetCancel"/> creates a
+ <structname>PGcancel</structname><indexterm><primary>PGcancel</primary></indexterm> object
+ given a <structname>PGconn</structname> connection object. It will return
+ <symbol>NULL</symbol> if the given <parameter>conn</parameter> is <symbol>NULL</symbol> or an invalid
+ connection. The <structname>PGcancel</structname> object is an opaque
+ structure that is not meant to be accessed directly by the
+ application; it can only be passed to <xref linkend="libpq-PQcancel"/>
+ or <xref linkend="libpq-PQfreeCancel"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfreeCancel">
+ <term><function>PQfreeCancel</function><indexterm><primary>PQfreeCancel</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Frees a data structure created by <xref linkend="libpq-PQgetCancel"/>.
+<synopsis>
+void PQfreeCancel(PGcancel *cancel);
+</synopsis>
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQfreeCancel"/> frees a data object previously created
+ by <xref linkend="libpq-PQgetCancel"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQcancel">
+ <term><function>PQcancel</function><indexterm><primary>PQcancel</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Requests that the server abandon processing of the current command.
+<synopsis>
+int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize);
+</synopsis>
+ </para>
+
+ <para>
+ The return value is 1 if the cancel request was successfully
+ dispatched and 0 if not. If not, <parameter>errbuf</parameter> is filled
+ with an explanatory error message. <parameter>errbuf</parameter>
+ must be a char array of size <parameter>errbufsize</parameter> (the
+ recommended size is 256 bytes).
+ </para>
+
+ <para>
+ Successful dispatch is no guarantee that the request will have
+ any effect, however. If the cancellation is effective, the current
+ command will terminate early and return an error result. If the
+ cancellation fails (say, because the server was already done
+ processing the command), then there will be no visible result at
+ all.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQcancel"/> can safely be invoked from a signal
+ handler, if the <parameter>errbuf</parameter> is a local variable in the
+ signal handler. The <structname>PGcancel</structname> object is read-only
+ as far as <xref linkend="libpq-PQcancel"/> is concerned, so it can
+ also be invoked from a thread that is separate from the one
+ manipulating the <structname>PGconn</structname> object.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <varlistentry id="libpq-PQrequestCancel">
+ <term><function>PQrequestCancel</function><indexterm><primary>PQrequestCancel</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ <xref linkend="libpq-PQrequestCancel"/> is a deprecated variant of
+ <xref linkend="libpq-PQcancel"/>.
+<synopsis>
+int PQrequestCancel(PGconn *conn);
+</synopsis>
+ </para>
+
+ <para>
+ Requests that the server abandon processing of the current
+ command. It operates directly on the
+ <structname>PGconn</structname> object, and in case of failure stores the
+ error message in the <structname>PGconn</structname> object (whence it can
+ be retrieved by <xref linkend="libpq-PQerrorMessage"/>). Although
+ the functionality is the same, this approach is not safe within
+ multiple-thread programs or signal handlers, since it is possible
+ that overwriting the <structname>PGconn</structname>'s error message will
+ mess up the operation currently in progress on the connection.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ </sect1>
+
+ <sect1 id="libpq-fastpath">
+ <title>The Fast-Path Interface</title>
+
+ <indexterm zone="libpq-fastpath">
+ <primary>fast path</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a fast-path interface
+ to send simple function calls to the server.
+ </para>
+
+ <tip>
+ <para>
+ This interface is somewhat obsolete, as one can achieve similar
+ performance and greater functionality by setting up a prepared
+ statement to define the function call. Then, executing the statement
+ with binary transmission of parameters and results substitutes for a
+ fast-path function call.
+ </para>
+ </tip>
+
+ <para>
+ The function <function id="libpq-PQfn">PQfn</function><indexterm><primary>PQfn</primary></indexterm>
+ requests execution of a server function via the fast-path interface:
+<synopsis>
+PGresult *PQfn(PGconn *conn,
+ int fnid,
+ int *result_buf,
+ int *result_len,
+ int result_is_int,
+ const PQArgBlock *args,
+ int nargs);
+
+typedef struct
+{
+ int len;
+ int isint;
+ union
+ {
+ int *ptr;
+ int integer;
+ } u;
+} PQArgBlock;
+</synopsis>
+ </para>
+
+ <para>
+ The <parameter>fnid</parameter> argument is the OID of the function to be
+ executed. <parameter>args</parameter> and <parameter>nargs</parameter> define the
+ parameters to be passed to the function; they must match the declared
+ function argument list. When the <parameter>isint</parameter> field of a
+ parameter structure is true, the <parameter>u.integer</parameter> value is sent
+ to the server as an integer of the indicated length (this must be
+ 2 or 4 bytes); proper byte-swapping occurs. When <parameter>isint</parameter>
+ is false, the indicated number of bytes at <parameter>*u.ptr</parameter> are
+ sent with no processing; the data must be in the format expected by
+ the server for binary transmission of the function's argument data
+ type. (The declaration of <parameter>u.ptr</parameter> as being of
+ type <type>int *</type> is historical; it would be better to consider
+ it <type>void *</type>.)
+ <parameter>result_buf</parameter> points to the buffer in which to place
+ the function's return value. The caller must have allocated sufficient
+ space to store the return value. (There is no check!) The actual result
+ length in bytes will be returned in the integer pointed to by
+ <parameter>result_len</parameter>. If a 2- or 4-byte integer result
+ is expected, set <parameter>result_is_int</parameter> to 1, otherwise
+ set it to 0. Setting <parameter>result_is_int</parameter> to 1 causes
+ <application>libpq</application> to byte-swap the value if necessary, so that it
+ is delivered as a proper <type>int</type> value for the client machine;
+ note that a 4-byte integer is delivered into <parameter>*result_buf</parameter>
+ for either allowed result size.
+ When <parameter>result_is_int</parameter> is 0, the binary-format byte string
+ sent by the server is returned unmodified. (In this case it's better
+ to consider <parameter>result_buf</parameter> as being of
+ type <type>void *</type>.)
+ </para>
+
+ <para>
+ <function>PQfn</function> always returns a valid
+ <structname>PGresult</structname> pointer, with
+ status <literal>PGRES_COMMAND_OK</literal> for success
+ or <literal>PGRES_FATAL_ERROR</literal> if some problem was encountered.
+ The result status should be
+ checked before the result is used. The caller is responsible for
+ freeing the <structname>PGresult</structname> with
+ <xref linkend="libpq-PQclear"/> when it is no longer needed.
+ </para>
+
+ <para>
+ To pass a NULL argument to the function, set
+ the <parameter>len</parameter> field of that parameter structure
+ to <literal>-1</literal>; the <parameter>isint</parameter>
+ and <parameter>u</parameter> fields are then irrelevant.
+ </para>
+
+ <para>
+ If the function returns NULL, <parameter>*result_len</parameter> is set
+ to <literal>-1</literal>, and <parameter>*result_buf</parameter> is not
+ modified.
+ </para>
+
+ <para>
+ Note that it is not possible to handle set-valued results when using
+ this interface. Also, the function must be a plain function, not an
+ aggregate, window function, or procedure.
+ </para>
+
+ </sect1>
+
+ <sect1 id="libpq-notify">
+ <title>Asynchronous Notification</title>
+
+ <indexterm zone="libpq-notify">
+ <primary>NOTIFY</primary>
+ <secondary>in libpq</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> offers asynchronous notification
+ via the <command>LISTEN</command> and <command>NOTIFY</command>
+ commands. A client session registers its interest in a particular
+ notification channel with the <command>LISTEN</command> command (and
+ can stop listening with the <command>UNLISTEN</command> command). All
+ sessions listening on a particular channel will be notified
+ asynchronously when a <command>NOTIFY</command> command with that
+ channel name is executed by any session. A <quote>payload</quote> string can
+ be passed to communicate additional data to the listeners.
+ </para>
+
+ <para>
+ <application>libpq</application> applications submit
+ <command>LISTEN</command>, <command>UNLISTEN</command>,
+ and <command>NOTIFY</command> commands as
+ ordinary SQL commands. The arrival of <command>NOTIFY</command>
+ messages can subsequently be detected by calling
+ <function id="libpq-PQnotifies">PQnotifies</function>.<indexterm><primary>PQnotifies</primary></indexterm>
+ </para>
+
+ <para>
+ The function <function>PQnotifies</function> returns the next notification
+ from a list of unhandled notification messages received from the server.
+ It returns a null pointer if there are no pending notifications. Once a
+ notification is returned from <function>PQnotifies</function>, it is considered
+ handled and will be removed from the list of notifications.
+
+<synopsis>
+PGnotify *PQnotifies(PGconn *conn);
+
+typedef struct pgNotify
+{
+ char *relname; /* notification channel name */
+ int be_pid; /* process ID of notifying server process */
+ char *extra; /* notification payload string */
+} PGnotify;
+</synopsis>
+
+ After processing a <structname>PGnotify</structname> object returned
+ by <function>PQnotifies</function>, be sure to free it with
+ <xref linkend="libpq-PQfreemem"/>. It is sufficient to free the
+ <structname>PGnotify</structname> pointer; the
+ <structfield>relname</structfield> and <structfield>extra</structfield>
+ fields do not represent separate allocations. (The names of these fields
+ are historical; in particular, channel names need not have anything to
+ do with relation names.)
+ </para>
+
+ <para>
+ <xref linkend="libpq-example-2"/> gives a sample program that illustrates
+ the use of asynchronous notification.
+ </para>
+
+ <para>
+ <function>PQnotifies</function> does not actually read data from the
+ server; it just returns messages previously absorbed by another
+ <application>libpq</application> function. In ancient releases of
+ <application>libpq</application>, the only way to ensure timely receipt
+ of <command>NOTIFY</command> messages was to constantly submit commands, even
+ empty ones, and then check <function>PQnotifies</function> after each
+ <xref linkend="libpq-PQexec"/>. While this still works, it is deprecated
+ as a waste of processing power.
+ </para>
+
+ <para>
+ A better way to check for <command>NOTIFY</command> messages when you have no
+ useful commands to execute is to call
+ <xref linkend="libpq-PQconsumeInput"/>, then check
+ <function>PQnotifies</function>. You can use
+ <function>select()</function> to wait for data to arrive from the
+ server, thereby using no <acronym>CPU</acronym> power unless there is
+ something to do. (See <xref linkend="libpq-PQsocket"/> to obtain the file
+ descriptor number to use with <function>select()</function>.) Note that
+ this will work OK whether you submit commands with
+ <xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/> or
+ simply use <xref linkend="libpq-PQexec"/>. You should, however, remember
+ to check <function>PQnotifies</function> after each
+ <xref linkend="libpq-PQgetResult"/> or <xref linkend="libpq-PQexec"/>, to
+ see if any notifications came in during the processing of the command.
+ </para>
+
+ </sect1>
+
+ <sect1 id="libpq-copy">
+ <title>Functions Associated with the <command>COPY</command> Command</title>
+
+ <indexterm zone="libpq-copy">
+ <primary>COPY</primary>
+ <secondary>with libpq</secondary>
+ </indexterm>
+
+ <para>
+ The <command>COPY</command> command in
+ <productname>PostgreSQL</productname> has options to read from or write
+ to the network connection used by <application>libpq</application>.
+ The functions described in this section allow applications to take
+ advantage of this capability by supplying or consuming copied data.
+ </para>
+
+ <para>
+ The overall process is that the application first issues the SQL
+ <command>COPY</command> command via <xref linkend="libpq-PQexec"/> or one
+ of the equivalent functions. The response to this (if there is no
+ error in the command) will be a <structname>PGresult</structname> object bearing
+ a status code of <literal>PGRES_COPY_OUT</literal> or
+ <literal>PGRES_COPY_IN</literal> (depending on the specified copy
+ direction). The application should then use the functions of this
+ section to receive or transmit data rows. When the data transfer is
+ complete, another <structname>PGresult</structname> object is returned to indicate
+ success or failure of the transfer. Its status will be
+ <literal>PGRES_COMMAND_OK</literal> for success or
+ <literal>PGRES_FATAL_ERROR</literal> if some problem was encountered.
+ At this point further SQL commands can be issued via
+ <xref linkend="libpq-PQexec"/>. (It is not possible to execute other SQL
+ commands using the same connection while the <command>COPY</command>
+ operation is in progress.)
+ </para>
+
+ <para>
+ If a <command>COPY</command> command is issued via
+ <xref linkend="libpq-PQexec"/> in a string that could contain additional
+ commands, the application must continue fetching results via
+ <xref linkend="libpq-PQgetResult"/> after completing the <command>COPY</command>
+ sequence. Only when <xref linkend="libpq-PQgetResult"/> returns
+ <symbol>NULL</symbol> is it certain that the <xref linkend="libpq-PQexec"/>
+ command string is done and it is safe to issue more commands.
+ </para>
+
+ <para>
+ The functions of this section should be executed only after obtaining
+ a result status of <literal>PGRES_COPY_OUT</literal> or
+ <literal>PGRES_COPY_IN</literal> from <xref linkend="libpq-PQexec"/> or
+ <xref linkend="libpq-PQgetResult"/>.
+ </para>
+
+ <para>
+ A <structname>PGresult</structname> object bearing one of these status values
+ carries some additional data about the <command>COPY</command> operation
+ that is starting. This additional data is available using functions
+ that are also used in connection with query results:
+
+ <variablelist>
+ <varlistentry id="libpq-PQnfields-1">
+ <term><function>PQnfields</function><indexterm
+ ><primary>PQnfields</primary><secondary>with COPY</secondary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the number of columns (fields) to be copied.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQbinaryTuples-1">
+ <term><function>PQbinaryTuples</function><indexterm
+ ><primary>PQbinaryTuples</primary><secondary>with COPY</secondary></indexterm></term>
+
+ <listitem>
+ <para>
+ 0 indicates the overall copy format is textual (rows separated by
+ newlines, columns separated by separator characters, etc.). 1
+ indicates the overall copy format is binary. See <xref
+ linkend="sql-copy"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfformat-1">
+ <term><function>PQfformat</function><indexterm
+ ><primary>PQfformat</primary><secondary>with COPY</secondary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the format code (0 for text, 1 for binary) associated with
+ each column of the copy operation. The per-column format codes
+ will always be zero when the overall copy format is textual, but
+ the binary format can support both text and binary columns.
+ (However, as of the current implementation of <command>COPY</command>,
+ only binary columns appear in a binary copy; so the per-column
+ formats always match the overall format at present.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <sect2 id="libpq-copy-send">
+ <title>Functions for Sending <command>COPY</command> Data</title>
+
+ <para>
+ These functions are used to send data during <literal>COPY FROM
+ STDIN</literal>. They will fail if called when the connection is not in
+ <literal>COPY_IN</literal> state.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQputCopyData">
+ <term><function>PQputCopyData</function><indexterm><primary>PQputCopyData</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends data to the server during <literal>COPY_IN</literal> state.
+<synopsis>
+int PQputCopyData(PGconn *conn,
+ const char *buffer,
+ int nbytes);
+</synopsis>
+ </para>
+
+ <para>
+ Transmits the <command>COPY</command> data in the specified
+ <parameter>buffer</parameter>, of length <parameter>nbytes</parameter>, to the server.
+ The result is 1 if the data was queued, zero if it was not queued
+ because of full buffers (this will only happen in nonblocking mode),
+ or -1 if an error occurred.
+ (Use <xref linkend="libpq-PQerrorMessage"/> to retrieve details if
+ the return value is -1. If the value is zero, wait for write-ready
+ and try again.)
+ </para>
+
+ <para>
+ The application can divide the <command>COPY</command> data stream
+ into buffer loads of any convenient size. Buffer-load boundaries
+ have no semantic significance when sending. The contents of the
+ data stream must match the data format expected by the
+ <command>COPY</command> command; see <xref linkend="sql-copy"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQputCopyEnd">
+ <term><function>PQputCopyEnd</function><indexterm><primary>PQputCopyEnd</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends end-of-data indication to the server during <literal>COPY_IN</literal> state.
+<synopsis>
+int PQputCopyEnd(PGconn *conn,
+ const char *errormsg);
+</synopsis>
+ </para>
+
+ <para>
+ Ends the <literal>COPY_IN</literal> operation successfully if
+ <parameter>errormsg</parameter> is <symbol>NULL</symbol>. If
+ <parameter>errormsg</parameter> is not <symbol>NULL</symbol> then the
+ <command>COPY</command> is forced to fail, with the string pointed to by
+ <parameter>errormsg</parameter> used as the error message. (One should not
+ assume that this exact error message will come back from the server,
+ however, as the server might have already failed the
+ <command>COPY</command> for its own reasons.)
+ </para>
+
+ <para>
+ The result is 1 if the termination message was sent; or in
+ nonblocking mode, this may only indicate that the termination
+ message was successfully queued. (In nonblocking mode, to be
+ certain that the data has been sent, you should next wait for
+ write-ready and call <xref linkend="libpq-PQflush"/>, repeating until it
+ returns zero.) Zero indicates that the function could not queue
+ the termination message because of full buffers; this will only
+ happen in nonblocking mode. (In this case, wait for
+ write-ready and try the <xref linkend="libpq-PQputCopyEnd"/> call
+ again.) If a hard error occurs, -1 is returned; you can use
+ <xref linkend="libpq-PQerrorMessage"/> to retrieve details.
+ </para>
+
+ <para>
+ After successfully calling <xref linkend="libpq-PQputCopyEnd"/>, call
+ <xref linkend="libpq-PQgetResult"/> to obtain the final result status of the
+ <command>COPY</command> command. One can wait for this result to be
+ available in the usual way. Then return to normal operation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="libpq-copy-receive">
+ <title>Functions for Receiving <command>COPY</command> Data</title>
+
+ <para>
+ These functions are used to receive data during <literal>COPY TO
+ STDOUT</literal>. They will fail if called when the connection is not in
+ <literal>COPY_OUT</literal> state.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQgetCopyData">
+ <term><function>PQgetCopyData</function><indexterm><primary>PQgetCopyData</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Receives data from the server during <literal>COPY_OUT</literal> state.
+<synopsis>
+int PQgetCopyData(PGconn *conn,
+ char **buffer,
+ int async);
+</synopsis>
+ </para>
+
+ <para>
+ Attempts to obtain another row of data from the server during a
+ <command>COPY</command>. Data is always returned one data row at
+ a time; if only a partial row is available, it is not returned.
+ Successful return of a data row involves allocating a chunk of
+ memory to hold the data. The <parameter>buffer</parameter> parameter must
+ be non-<symbol>NULL</symbol>. <parameter>*buffer</parameter> is set to
+ point to the allocated memory, or to <symbol>NULL</symbol> in cases
+ where no buffer is returned. A non-<symbol>NULL</symbol> result
+ buffer should be freed using <xref linkend="libpq-PQfreemem"/> when no longer
+ needed.
+ </para>
+
+ <para>
+ When a row is successfully returned, the return value is the number
+ of data bytes in the row (this will always be greater than zero).
+ The returned string is always null-terminated, though this is
+ probably only useful for textual <command>COPY</command>. A result
+ of zero indicates that the <command>COPY</command> is still in
+ progress, but no row is yet available (this is only possible when
+ <parameter>async</parameter> is true). A result of -1 indicates that the
+ <command>COPY</command> is done. A result of -2 indicates that an
+ error occurred (consult <xref linkend="libpq-PQerrorMessage"/> for the reason).
+ </para>
+
+ <para>
+ When <parameter>async</parameter> is true (not zero),
+ <xref linkend="libpq-PQgetCopyData"/> will not block waiting for input; it
+ will return zero if the <command>COPY</command> is still in progress
+ but no complete row is available. (In this case wait for read-ready
+ and then call <xref linkend="libpq-PQconsumeInput"/> before calling
+ <xref linkend="libpq-PQgetCopyData"/> again.) When <parameter>async</parameter> is
+ false (zero), <xref linkend="libpq-PQgetCopyData"/> will block until data is
+ available or the operation completes.
+ </para>
+
+ <para>
+ After <xref linkend="libpq-PQgetCopyData"/> returns -1, call
+ <xref linkend="libpq-PQgetResult"/> to obtain the final result status of the
+ <command>COPY</command> command. One can wait for this result to be
+ available in the usual way. Then return to normal operation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="libpq-copy-deprecated">
+ <title>Obsolete Functions for <command>COPY</command></title>
+
+ <para>
+ These functions represent older methods of handling <command>COPY</command>.
+ Although they still work, they are deprecated due to poor error handling,
+ inconvenient methods of detecting end-of-data, and lack of support for binary
+ or nonblocking transfers.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQgetline">
+ <term><function>PQgetline</function><indexterm><primary>PQgetline</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Reads a newline-terminated line of characters (transmitted
+ by the server) into a buffer string of size <parameter>length</parameter>.
+<synopsis>
+int PQgetline(PGconn *conn,
+ char *buffer,
+ int length);
+</synopsis>
+ </para>
+
+ <para>
+ This function copies up to <parameter>length</parameter>-1 characters into
+ the buffer and converts the terminating newline into a zero byte.
+ <xref linkend="libpq-PQgetline"/> returns <symbol>EOF</symbol> at the
+ end of input, 0 if the entire line has been read, and 1 if the
+ buffer is full but the terminating newline has not yet been read.
+ </para>
+ <para>
+ Note that the application must check to see if a new line consists
+ of the two characters <literal>\.</literal>, which indicates
+ that the server has finished sending the results of the
+ <command>COPY</command> command. If the application might receive
+ lines that are more than <parameter>length</parameter>-1 characters long,
+ care is needed to be sure it recognizes the <literal>\.</literal>
+ line correctly (and does not, for example, mistake the end of a
+ long data line for a terminator line).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQgetlineAsync">
+ <term><function>PQgetlineAsync</function><indexterm><primary>PQgetlineAsync</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Reads a row of <command>COPY</command> data (transmitted by the
+ server) into a buffer without blocking.
+<synopsis>
+int PQgetlineAsync(PGconn *conn,
+ char *buffer,
+ int bufsize);
+</synopsis>
+ </para>
+
+ <para>
+ This function is similar to <xref linkend="libpq-PQgetline"/>, but it can be used
+ by applications
+ that must read <command>COPY</command> data asynchronously, that is, without blocking.
+ Having issued the <command>COPY</command> command and gotten a <literal>PGRES_COPY_OUT</literal>
+ response, the
+ application should call <xref linkend="libpq-PQconsumeInput"/> and
+ <xref linkend="libpq-PQgetlineAsync"/> until the
+ end-of-data signal is detected.
+ </para>
+ <para>
+ Unlike <xref linkend="libpq-PQgetline"/>, this function takes
+ responsibility for detecting end-of-data.
+ </para>
+
+ <para>
+ On each call, <xref linkend="libpq-PQgetlineAsync"/> will return data if a
+ complete data row is available in <application>libpq</application>'s input buffer.
+ Otherwise, no data is returned until the rest of the row arrives.
+ The function returns -1 if the end-of-copy-data marker has been recognized,
+ or 0 if no data is available, or a positive number giving the number of
+ bytes of data returned. If -1 is returned, the caller must next call
+ <xref linkend="libpq-PQendcopy"/>, and then return to normal processing.
+ </para>
+
+ <para>
+ The data returned will not extend beyond a data-row boundary. If possible
+ a whole row will be returned at one time. But if the buffer offered by
+ the caller is too small to hold a row sent by the server, then a partial
+ data row will be returned. With textual data this can be detected by testing
+ whether the last returned byte is <literal>\n</literal> or not. (In a binary
+ <command>COPY</command>, actual parsing of the <command>COPY</command> data format will be needed to make the
+ equivalent determination.)
+ The returned string is not null-terminated. (If you want to add a
+ terminating null, be sure to pass a <parameter>bufsize</parameter> one smaller
+ than the room actually available.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQputline">
+ <term><function>PQputline</function><indexterm><primary>PQputline</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends a null-terminated string to the server. Returns 0 if
+ OK and <symbol>EOF</symbol> if unable to send the string.
+<synopsis>
+int PQputline(PGconn *conn,
+ const char *string);
+</synopsis>
+ </para>
+
+ <para>
+ The <command>COPY</command> data stream sent by a series of calls
+ to <xref linkend="libpq-PQputline"/> has the same format as that
+ returned by <xref linkend="libpq-PQgetlineAsync"/>, except that
+ applications are not obliged to send exactly one data row per
+ <xref linkend="libpq-PQputline"/> call; it is okay to send a partial
+ line or multiple lines per call.
+ </para>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> protocol 3.0, it was necessary
+ for the application to explicitly send the two characters
+ <literal>\.</literal> as a final line to indicate to the server that it had
+ finished sending <command>COPY</command> data. While this still works, it is deprecated and the
+ special meaning of <literal>\.</literal> can be expected to be removed in a
+ future release. It is sufficient to call <xref linkend="libpq-PQendcopy"/> after
+ having sent the actual data.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQputnbytes">
+ <term><function>PQputnbytes</function><indexterm><primary>PQputnbytes</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sends a non-null-terminated string to the server. Returns
+ 0 if OK and <symbol>EOF</symbol> if unable to send the string.
+<synopsis>
+int PQputnbytes(PGconn *conn,
+ const char *buffer,
+ int nbytes);
+</synopsis>
+ </para>
+
+ <para>
+ This is exactly like <xref linkend="libpq-PQputline"/>, except that the data
+ buffer need not be null-terminated since the number of bytes to send is
+ specified directly. Use this procedure when sending binary data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQendcopy">
+ <term><function>PQendcopy</function><indexterm><primary>PQendcopy</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Synchronizes with the server.
+<synopsis>
+int PQendcopy(PGconn *conn);
+</synopsis>
+ This function waits until the server has finished the copying.
+ It should either be issued when the last string has been sent
+ to the server using <xref linkend="libpq-PQputline"/> or when the
+ last string has been received from the server using
+ <function>PQgetline</function>. It must be issued or the server
+ will get <quote>out of sync</quote> with the client. Upon return
+ from this function, the server is ready to receive the next SQL
+ command. The return value is 0 on successful completion,
+ nonzero otherwise. (Use <xref linkend="libpq-PQerrorMessage"/> to
+ retrieve details if the return value is nonzero.)
+ </para>
+
+ <para>
+ When using <xref linkend="libpq-PQgetResult"/>, the application should
+ respond to a <literal>PGRES_COPY_OUT</literal> result by executing
+ <xref linkend="libpq-PQgetline"/> repeatedly, followed by
+ <xref linkend="libpq-PQendcopy"/> after the terminator line is seen.
+ It should then return to the <xref linkend="libpq-PQgetResult"/> loop
+ until <xref linkend="libpq-PQgetResult"/> returns a null pointer.
+ Similarly a <literal>PGRES_COPY_IN</literal> result is processed
+ by a series of <xref linkend="libpq-PQputline"/> calls followed by
+ <xref linkend="libpq-PQendcopy"/>, then return to the
+ <xref linkend="libpq-PQgetResult"/> loop. This arrangement will
+ ensure that a <command>COPY</command> command embedded in a series
+ of <acronym>SQL</acronym> commands will be executed correctly.
+ </para>
+
+ <para>
+ Older applications are likely to submit a <command>COPY</command>
+ via <xref linkend="libpq-PQexec"/> and assume that the transaction
+ is done after <xref linkend="libpq-PQendcopy"/>. This will work
+ correctly only if the <command>COPY</command> is the only
+ <acronym>SQL</acronym> command in the command string.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="libpq-control">
+ <title>Control Functions</title>
+
+ <para>
+ These functions control miscellaneous details of <application>libpq</application>'s
+ behavior.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQclientEncoding">
+ <term><function>PQclientEncoding</function><indexterm><primary>PQclientEncoding</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the client encoding.
+<synopsis>
+int PQclientEncoding(const PGconn *<replaceable>conn</replaceable>);
+</synopsis>
+
+ Note that it returns the encoding ID, not a symbolic string
+ such as <literal>EUC_JP</literal>. If unsuccessful, it returns -1.
+ To convert an encoding ID to an encoding name, you
+ can use:
+
+<synopsis>
+char *pg_encoding_to_char(int <replaceable>encoding_id</replaceable>);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetClientEncoding">
+ <term><function>PQsetClientEncoding</function><indexterm><primary>PQsetClientEncoding</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sets the client encoding.
+<synopsis>
+int PQsetClientEncoding(PGconn *<replaceable>conn</replaceable>, const char *<replaceable>encoding</replaceable>);
+</synopsis>
+
+ <replaceable>conn</replaceable> is a connection to the server,
+ and <replaceable>encoding</replaceable> is the encoding you want to
+ use. If the function successfully sets the encoding, it returns 0,
+ otherwise -1. The current encoding for this connection can be
+ determined by using <xref linkend="libpq-PQclientEncoding"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetErrorVerbosity">
+ <term><function>PQsetErrorVerbosity</function><indexterm><primary>PQsetErrorVerbosity</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Determines the verbosity of messages returned by
+ <xref linkend="libpq-PQerrorMessage"/> and <xref linkend="libpq-PQresultErrorMessage"/>.
+<synopsis>
+typedef enum
+{
+ PQERRORS_TERSE,
+ PQERRORS_DEFAULT,
+ PQERRORS_VERBOSE,
+ PQERRORS_SQLSTATE
+} PGVerbosity;
+
+PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
+</synopsis>
+
+ <xref linkend="libpq-PQsetErrorVerbosity"/> sets the verbosity mode,
+ returning the connection's previous setting.
+ In <firstterm>TERSE</firstterm> mode, returned messages include
+ severity, primary text, and position only; this will normally fit on a
+ single line. The <firstterm>DEFAULT</firstterm> mode produces messages
+ that include the above plus any detail, hint, or context fields (these
+ might span multiple lines). The <firstterm>VERBOSE</firstterm> mode
+ includes all available fields. The <firstterm>SQLSTATE</firstterm>
+ mode includes only the error severity and the <symbol>SQLSTATE</symbol>
+ error code, if one is available (if not, the output is like
+ <firstterm>TERSE</firstterm> mode).
+ </para>
+
+ <para>
+ Changing the verbosity setting does not affect the messages available
+ from already-existing <structname>PGresult</structname> objects, only
+ subsequently-created ones.
+ (But see <xref linkend="libpq-PQresultVerboseErrorMessage"/> if you
+ want to print a previous error with a different verbosity.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetErrorContextVisibility">
+ <term><function>PQsetErrorContextVisibility</function><indexterm><primary>PQsetErrorContextVisibility</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Determines the handling of <literal>CONTEXT</literal> fields in messages
+ returned by <xref linkend="libpq-PQerrorMessage"/>
+ and <xref linkend="libpq-PQresultErrorMessage"/>.
+<synopsis>
+typedef enum
+{
+ PQSHOW_CONTEXT_NEVER,
+ PQSHOW_CONTEXT_ERRORS,
+ PQSHOW_CONTEXT_ALWAYS
+} PGContextVisibility;
+
+PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context);
+</synopsis>
+
+ <xref linkend="libpq-PQsetErrorContextVisibility"/> sets the context display mode,
+ returning the connection's previous setting. This mode controls
+ whether the <literal>CONTEXT</literal> field is included in messages.
+ The <firstterm>NEVER</firstterm> mode
+ never includes <literal>CONTEXT</literal>, while <firstterm>ALWAYS</firstterm> always
+ includes it if available. In <firstterm>ERRORS</firstterm> mode (the
+ default), <literal>CONTEXT</literal> fields are included only in error
+ messages, not in notices and warnings.
+ (However, if the verbosity setting is <firstterm>TERSE</firstterm>
+ or <firstterm>SQLSTATE</firstterm>, <literal>CONTEXT</literal> fields
+ are omitted regardless of the context display mode.)
+ </para>
+
+ <para>
+ Changing this mode does not
+ affect the messages available from
+ already-existing <structname>PGresult</structname> objects, only
+ subsequently-created ones.
+ (But see <xref linkend="libpq-PQresultVerboseErrorMessage"/> if you
+ want to print a previous error with a different display mode.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQtrace">
+ <term><function>PQtrace</function><indexterm><primary>PQtrace</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Enables tracing of the client/server communication to a debugging file
+ stream.
+<synopsis>
+void PQtrace(PGconn *conn, FILE *stream);
+</synopsis>
+ </para>
+
+ <para>
+ Each line consists of: an optional timestamp, a direction indicator
+ (<literal>F</literal> for messages from client to server
+ or <literal>B</literal> for messages from server to client),
+ message length, message type, and message contents.
+ Non-message contents fields (timestamp, direction, length and message type)
+ are separated by a tab. Message contents are separated by a space.
+ Protocol strings are enclosed in double quotes, while strings used as data
+ values are enclosed in single quotes. Non-printable chars are printed as
+ hexadecimal escapes.
+ Further message-type-specific detail can be found in
+ <xref linkend="protocol-message-formats"/>.
+ </para>
+
+ <note>
+ <para>
+ On Windows, if the <application>libpq</application> library and an application are
+ compiled with different flags, this function call will crash the
+ application because the internal representation of the <literal>FILE</literal>
+ pointers differ. Specifically, multithreaded/single-threaded,
+ release/debug, and static/dynamic flags should be the same for the
+ library and all applications using that library.
+ </para>
+ </note>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetTraceFlags">
+ <term><function>PQsetTraceFlags</function><indexterm><primary>PQsetTraceFlags</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Controls the tracing behavior of client/server communication.
+<synopsis>
+void PQsetTraceFlags(PGconn *conn, int flags);
+</synopsis>
+ </para>
+
+ <para>
+ <literal>flags</literal> contains flag bits describing the operating mode
+ of tracing.
+ If <literal>flags</literal> contains <literal>PQTRACE_SUPPRESS_TIMESTAMPS</literal>,
+ then the timestamp is not included when printing each message.
+ If <literal>flags</literal> contains <literal>PQTRACE_REGRESS_MODE</literal>,
+ then some fields are redacted when printing each message, such as object
+ OIDs, to make the output more convenient to use in testing frameworks.
+ This function must be called after calling <function>PQtrace</function>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQuntrace">
+ <term><function>PQuntrace</function><indexterm><primary>PQuntrace</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Disables tracing started by <xref linkend="libpq-PQtrace"/>.
+<synopsis>
+void PQuntrace(PGconn *conn);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="libpq-misc">
+ <title>Miscellaneous Functions</title>
+
+ <para>
+ As always, there are some functions that just don't fit anywhere.
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQfreemem">
+ <term><function>PQfreemem</function><indexterm><primary>PQfreemem</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Frees memory allocated by <application>libpq</application>.
+<synopsis>
+void PQfreemem(void *ptr);
+</synopsis>
+ </para>
+
+ <para>
+ Frees memory allocated by <application>libpq</application>, particularly
+ <xref linkend="libpq-PQescapeByteaConn"/>,
+ <xref linkend="libpq-PQescapeBytea"/>,
+ <xref linkend="libpq-PQunescapeBytea"/>,
+ and <function>PQnotifies</function>.
+ It is particularly important that this function, rather than
+ <function>free()</function>, be used on Microsoft Windows. This is because
+ allocating memory in a DLL and releasing it in the application works
+ only if multithreaded/single-threaded, release/debug, and static/dynamic
+ flags are the same for the DLL and the application. On non-Microsoft
+ Windows platforms, this function is the same as the standard library
+ function <function>free()</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQconninfoFree">
+ <term><function>PQconninfoFree</function><indexterm><primary>PQconninfoFree</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Frees the data structures allocated by
+ <xref linkend="libpq-PQconndefaults"/> or <xref linkend="libpq-PQconninfoParse"/>.
+<synopsis>
+void PQconninfoFree(PQconninfoOption *connOptions);
+</synopsis>
+ </para>
+
+ <para>
+ A simple <xref linkend="libpq-PQfreemem"/> will not do for this, since
+ the array contains references to subsidiary strings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQencryptPasswordConn">
+ <term><function>PQencryptPasswordConn</function><indexterm><primary>PQencryptPasswordConn</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Prepares the encrypted form of a <productname>PostgreSQL</productname> password.
+<synopsis>
+char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm);
+</synopsis>
+ This function is intended to be used by client applications that
+ wish to send commands like <literal>ALTER USER joe PASSWORD
+ 'pwd'</literal>. It is good practice not to send the original cleartext
+ password in such a command, because it might be exposed in command
+ logs, activity displays, and so on. Instead, use this function to
+ convert the password to encrypted form before it is sent.
+ </para>
+
+ <para>
+ The <parameter>passwd</parameter> and <parameter>user</parameter> arguments
+ are the cleartext password, and the SQL name of the user it is for.
+ <parameter>algorithm</parameter> specifies the encryption algorithm
+ to use to encrypt the password. Currently supported algorithms are
+ <literal>md5</literal> and <literal>scram-sha-256</literal> (<literal>on</literal> and
+ <literal>off</literal> are also accepted as aliases for <literal>md5</literal>, for
+ compatibility with older server versions). Note that support for
+ <literal>scram-sha-256</literal> was introduced in <productname>PostgreSQL</productname>
+ version 10, and will not work correctly with older server versions. If
+ <parameter>algorithm</parameter> is <symbol>NULL</symbol>, this function will query
+ the server for the current value of the
+ <xref linkend="guc-password-encryption"/> setting. That can block, and
+ will fail if the current transaction is aborted, or if the connection
+ is busy executing another query. If you wish to use the default
+ algorithm for the server but want to avoid blocking, query
+ <varname>password_encryption</varname> yourself before calling
+ <xref linkend="libpq-PQencryptPasswordConn"/>, and pass that value as the
+ <parameter>algorithm</parameter>.
+ </para>
+
+ <para>
+ The return value is a string allocated by <function>malloc</function>.
+ The caller can assume the string doesn't contain any special characters
+ that would require escaping. Use <xref linkend="libpq-PQfreemem"/> to free the
+ result when done with it. On error, returns <symbol>NULL</symbol>, and
+ a suitable message is stored in the connection object.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQencryptPassword">
+ <term><function>PQencryptPassword</function><indexterm><primary>PQencryptPassword</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Prepares the md5-encrypted form of a <productname>PostgreSQL</productname> password.
+<synopsis>
+char *PQencryptPassword(const char *passwd, const char *user);
+</synopsis>
+ <xref linkend="libpq-PQencryptPassword"/> is an older, deprecated version of
+ <xref linkend="libpq-PQencryptPasswordConn"/>. The difference is that
+ <xref linkend="libpq-PQencryptPassword"/> does not
+ require a connection object, and <literal>md5</literal> is always used as the
+ encryption algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQmakeEmptyPGresult">
+ <term><function>PQmakeEmptyPGresult</function><indexterm><primary>PQmakeEmptyPGresult</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Constructs an empty <structname>PGresult</structname> object with the given status.
+<synopsis>
+PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
+</synopsis>
+ </para>
+
+ <para>
+ This is <application>libpq</application>'s internal function to allocate and
+ initialize an empty <structname>PGresult</structname> object. This
+ function returns <symbol>NULL</symbol> if memory could not be allocated. It is
+ exported because some applications find it useful to generate result
+ objects (particularly objects with error status) themselves. If
+ <parameter>conn</parameter> is not null and <parameter>status</parameter>
+ indicates an error, the current error message of the specified
+ connection is copied into the <structname>PGresult</structname>.
+ Also, if <parameter>conn</parameter> is not null, any event procedures
+ registered in the connection are copied into the
+ <structname>PGresult</structname>. (They do not get
+ <literal>PGEVT_RESULTCREATE</literal> calls, but see
+ <xref linkend="libpq-PQfireResultCreateEvents"/>.)
+ Note that <xref linkend="libpq-PQclear"/> should eventually be called
+ on the object, just as with a <structname>PGresult</structname>
+ returned by <application>libpq</application> itself.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQfireResultCreateEvents">
+ <term><function>PQfireResultCreateEvents</function><indexterm><primary>PQfireResultCreateEvents</primary></indexterm></term>
+ <listitem>
+ <para>
+ Fires a <literal>PGEVT_RESULTCREATE</literal> event (see <xref
+ linkend="libpq-events"/>) for each event procedure registered in the
+ <structname>PGresult</structname> object. Returns non-zero for success,
+ zero if any event procedure fails.
+
+<synopsis>
+int PQfireResultCreateEvents(PGconn *conn, PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ The <literal>conn</literal> argument is passed through to event procedures
+ but not used directly. It can be <symbol>NULL</symbol> if the event
+ procedures won't use it.
+ </para>
+
+ <para>
+ Event procedures that have already received a
+ <literal>PGEVT_RESULTCREATE</literal> or <literal>PGEVT_RESULTCOPY</literal> event
+ for this object are not fired again.
+ </para>
+
+ <para>
+ The main reason that this function is separate from
+ <xref linkend="libpq-PQmakeEmptyPGresult"/> is that it is often appropriate
+ to create a <structname>PGresult</structname> and fill it with data
+ before invoking the event procedures.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQcopyResult">
+ <term><function>PQcopyResult</function><indexterm><primary>PQcopyResult</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Makes a copy of a <structname>PGresult</structname> object. The copy is
+ not linked to the source result in any way and
+ <xref linkend="libpq-PQclear"/> must be called when the copy is no longer
+ needed. If the function fails, <symbol>NULL</symbol> is returned.
+
+<synopsis>
+PGresult *PQcopyResult(const PGresult *src, int flags);
+</synopsis>
+ </para>
+
+ <para>
+ This is not intended to make an exact copy. The returned result is
+ always put into <literal>PGRES_TUPLES_OK</literal> status, and does not
+ copy any error message in the source. (It does copy the command status
+ string, however.) The <parameter>flags</parameter> argument determines
+ what else is copied. It is a bitwise OR of several flags.
+ <literal>PG_COPYRES_ATTRS</literal> specifies copying the source
+ result's attributes (column definitions).
+ <literal>PG_COPYRES_TUPLES</literal> specifies copying the source
+ result's tuples. (This implies copying the attributes, too.)
+ <literal>PG_COPYRES_NOTICEHOOKS</literal> specifies
+ copying the source result's notify hooks.
+ <literal>PG_COPYRES_EVENTS</literal> specifies copying the source
+ result's events. (But any instance data associated with the source
+ is not copied.)
+ The event procedures receive <literal>PGEVT_RESULTCOPY</literal> events.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetResultAttrs">
+ <term><function>PQsetResultAttrs</function><indexterm><primary>PQsetResultAttrs</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sets the attributes of a <structname>PGresult</structname> object.
+<synopsis>
+int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs);
+</synopsis>
+ </para>
+
+ <para>
+ The provided <parameter>attDescs</parameter> are copied into the result.
+ If the <parameter>attDescs</parameter> pointer is <symbol>NULL</symbol> or
+ <parameter>numAttributes</parameter> is less than one, the request is
+ ignored and the function succeeds. If <parameter>res</parameter>
+ already contains attributes, the function will fail. If the function
+ fails, the return value is zero. If the function succeeds, the return
+ value is non-zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetvalue">
+ <term><function>PQsetvalue</function><indexterm><primary>PQsetvalue</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Sets a tuple field value of a <structname>PGresult</structname> object.
+<synopsis>
+int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len);
+</synopsis>
+ </para>
+
+ <para>
+ The function will automatically grow the result's internal tuples array
+ as needed. However, the <parameter>tup_num</parameter> argument must be
+ less than or equal to <xref linkend="libpq-PQntuples"/>, meaning this
+ function can only grow the tuples array one tuple at a time. But any
+ field of any existing tuple can be modified in any order. If a value at
+ <parameter>field_num</parameter> already exists, it will be overwritten.
+ If <parameter>len</parameter> is -1 or
+ <parameter>value</parameter> is <symbol>NULL</symbol>, the field value
+ will be set to an SQL null value. The
+ <parameter>value</parameter> is copied into the result's private storage,
+ thus is no longer needed after the function
+ returns. If the function fails, the return value is zero. If the
+ function succeeds, the return value is non-zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultAlloc">
+ <term><function>PQresultAlloc</function><indexterm><primary>PQresultAlloc</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Allocate subsidiary storage for a <structname>PGresult</structname> object.
+<synopsis>
+void *PQresultAlloc(PGresult *res, size_t nBytes);
+</synopsis>
+ </para>
+
+ <para>
+ Any memory allocated with this function will be freed when
+ <parameter>res</parameter> is cleared. If the function fails,
+ the return value is <symbol>NULL</symbol>. The result is
+ guaranteed to be adequately aligned for any type of data,
+ just as for <function>malloc</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultMemorySize">
+ <term><function>PQresultMemorySize</function><indexterm><primary>PQresultMemorySize</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Retrieves the number of bytes allocated for
+ a <structname>PGresult</structname> object.
+<synopsis>
+size_t PQresultMemorySize(const PGresult *res);
+</synopsis>
+ </para>
+
+ <para>
+ This value is the sum of all <function>malloc</function> requests
+ associated with the <structname>PGresult</structname> object, that is,
+ all the space that will be freed by <xref linkend="libpq-PQclear"/>.
+ This information can be useful for managing memory consumption.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQlibVersion">
+ <term><function>PQlibVersion</function><indexterm
+ ><primary>PQlibVersion</primary><seealso>PQserverVersion</seealso></indexterm></term>
+
+ <listitem>
+ <para>
+ Return the version of <productname>libpq</productname> that is being used.
+<synopsis>
+int PQlibVersion(void);
+</synopsis>
+ </para>
+
+ <para>
+ The result of this function can be used to determine, at
+ run time, whether specific functionality is available in the currently
+ loaded version of libpq. The function can be used, for example,
+ to determine which connection options are available in
+ <xref linkend="libpq-PQconnectdb"/>.
+ </para>
+
+ <para>
+ The result is formed by multiplying the library's major version
+ number by 10000 and adding the minor version number. For example,
+ version 10.1 will be returned as 100001, and version 11.0 will be
+ returned as 110000.
+ </para>
+
+ <para>
+ Prior to major version 10, <productname>PostgreSQL</productname> used
+ three-part version numbers in which the first two parts together
+ represented the major version. For those
+ versions, <xref linkend="libpq-PQlibVersion"/> uses two digits for each
+ part; for example version 9.1.5 will be returned as 90105, and
+ version 9.2.0 will be returned as 90200.
+ </para>
+
+ <para>
+ Therefore, for purposes of determining feature compatibility,
+ applications should divide the result of <xref linkend="libpq-PQlibVersion"/>
+ by 100 not 10000 to determine a logical major version number.
+ In all release series, only the last two digits differ between
+ minor releases (bug-fix releases).
+ </para>
+
+ <note>
+ <para>
+ This function appeared in <productname>PostgreSQL</productname> version 9.1, so
+ it cannot be used to detect required functionality in earlier
+ versions, since calling it will create a link dependency
+ on version 9.1 or later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="libpq-notice-processing">
+ <title>Notice Processing</title>
+
+ <indexterm zone="libpq-notice-processing">
+ <primary>notice processing</primary>
+ <secondary>in libpq</secondary>
+ </indexterm>
+
+ <para>
+ Notice and warning messages generated by the server are not returned
+ by the query execution functions, since they do not imply failure of
+ the query. Instead they are passed to a notice handling function, and
+ execution continues normally after the handler returns. The default
+ notice handling function prints the message on
+ <filename>stderr</filename>, but the application can override this
+ behavior by supplying its own handling function.
+ </para>
+
+ <para>
+ For historical reasons, there are two levels of notice handling, called
+ the notice receiver and notice processor. The default behavior is for
+ the notice receiver to format the notice and pass a string to the notice
+ processor for printing. However, an application that chooses to provide
+ its own notice receiver will typically ignore the notice processor
+ layer and just do all the work in the notice receiver.
+ </para>
+
+ <para>
+ The function <function id="libpq-PQsetNoticeReceiver">PQsetNoticeReceiver</function>
+ <indexterm><primary>notice receiver</primary></indexterm>
+ <indexterm><primary>PQsetNoticeReceiver</primary></indexterm> sets or
+ examines the current notice receiver for a connection object.
+ Similarly, <function id="libpq-PQsetNoticeProcessor">PQsetNoticeProcessor</function>
+ <indexterm><primary>notice processor</primary></indexterm>
+ <indexterm><primary>PQsetNoticeProcessor</primary></indexterm> sets or
+ examines the current notice processor.
+
+<synopsis>
+typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res);
+
+PQnoticeReceiver
+PQsetNoticeReceiver(PGconn *conn,
+ PQnoticeReceiver proc,
+ void *arg);
+
+typedef void (*PQnoticeProcessor) (void *arg, const char *message);
+
+PQnoticeProcessor
+PQsetNoticeProcessor(PGconn *conn,
+ PQnoticeProcessor proc,
+ void *arg);
+</synopsis>
+
+ Each of these functions returns the previous notice receiver or
+ processor function pointer, and sets the new value. If you supply a
+ null function pointer, no action is taken, but the current pointer is
+ returned.
+ </para>
+
+ <para>
+ When a notice or warning message is received from the server, or
+ generated internally by <application>libpq</application>, the notice
+ receiver function is called. It is passed the message in the form of
+ a <symbol>PGRES_NONFATAL_ERROR</symbol>
+ <structname>PGresult</structname>. (This allows the receiver to extract
+ individual fields using <xref linkend="libpq-PQresultErrorField"/>, or obtain a
+ complete preformatted message using <xref linkend="libpq-PQresultErrorMessage"/>
+ or <xref linkend="libpq-PQresultVerboseErrorMessage"/>.) The same
+ void pointer passed to <function>PQsetNoticeReceiver</function> is also
+ passed. (This pointer can be used to access application-specific state
+ if needed.)
+ </para>
+
+ <para>
+ The default notice receiver simply extracts the message (using
+ <xref linkend="libpq-PQresultErrorMessage"/>) and passes it to the notice
+ processor.
+ </para>
+
+ <para>
+ The notice processor is responsible for handling a notice or warning
+ message given in text form. It is passed the string text of the message
+ (including a trailing newline), plus a void pointer that is the same
+ one passed to <function>PQsetNoticeProcessor</function>. (This pointer
+ can be used to access application-specific state if needed.)
+ </para>
+
+ <para>
+ The default notice processor is simply:
+<programlisting>
+static void
+defaultNoticeProcessor(void *arg, const char *message)
+{
+ fprintf(stderr, "%s", message);
+}
+</programlisting>
+ </para>
+
+ <para>
+ Once you have set a notice receiver or processor, you should expect
+ that that function could be called as long as either the
+ <structname>PGconn</structname> object or <structname>PGresult</structname> objects made
+ from it exist. At creation of a <structname>PGresult</structname>, the
+ <structname>PGconn</structname>'s current notice handling pointers are copied
+ into the <structname>PGresult</structname> for possible use by functions like
+ <xref linkend="libpq-PQgetvalue"/>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="libpq-events">
+ <title>Event System</title>
+
+ <para>
+ <application>libpq</application>'s event system is designed to notify
+ registered event handlers about interesting
+ <application>libpq</application> events, such as the creation or
+ destruction of <structname>PGconn</structname> and
+ <structname>PGresult</structname> objects. A principal use case is that
+ this allows applications to associate their own data with a
+ <structname>PGconn</structname> or <structname>PGresult</structname>
+ and ensure that that data is freed at an appropriate time.
+ </para>
+
+ <para>
+ Each registered event handler is associated with two pieces of data,
+ known to <application>libpq</application> only as opaque <literal>void *</literal>
+ pointers. There is a <firstterm>pass-through</firstterm> pointer that is provided
+ by the application when the event handler is registered with a
+ <structname>PGconn</structname>. The pass-through pointer never changes for the
+ life of the <structname>PGconn</structname> and all <structname>PGresult</structname>s
+ generated from it; so if used, it must point to long-lived data.
+ In addition there is an <firstterm>instance data</firstterm> pointer, which starts
+ out <symbol>NULL</symbol> in every <structname>PGconn</structname> and <structname>PGresult</structname>.
+ This pointer can be manipulated using the
+ <xref linkend="libpq-PQinstanceData"/>,
+ <xref linkend="libpq-PQsetInstanceData"/>,
+ <xref linkend="libpq-PQresultInstanceData"/> and
+ <xref linkend="libpq-PQresultSetInstanceData"/> functions. Note that
+ unlike the pass-through pointer, instance data of a <structname>PGconn</structname>
+ is not automatically inherited by <structname>PGresult</structname>s created from
+ it. <application>libpq</application> does not know what pass-through
+ and instance data pointers point to (if anything) and will never attempt
+ to free them &mdash; that is the responsibility of the event handler.
+ </para>
+
+ <sect2 id="libpq-events-types">
+ <title>Event Types</title>
+
+ <para>
+ The enum <literal>PGEventId</literal> names the types of events handled by
+ the event system. All its values have names beginning with
+ <literal>PGEVT</literal>. For each event type, there is a corresponding
+ event info structure that carries the parameters passed to the event
+ handlers. The event types are:
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-pgevt-register">
+ <term><literal>PGEVT_REGISTER</literal></term>
+ <listitem>
+ <para>
+ The register event occurs when <xref linkend="libpq-PQregisterEventProc"/>
+ is called. It is the ideal time to initialize any
+ <literal>instanceData</literal> an event procedure may need. Only one
+ register event will be fired per event handler per connection. If the
+ event procedure fails (returns zero), the registration is cancelled.
+
+<synopsis>
+typedef struct
+{
+ PGconn *conn;
+} PGEventRegister;
+</synopsis>
+
+ When a <literal>PGEVT_REGISTER</literal> event is received, the
+ <parameter>evtInfo</parameter> pointer should be cast to a
+ <structname>PGEventRegister *</structname>. This structure contains a
+ <structname>PGconn</structname> that should be in the
+ <literal>CONNECTION_OK</literal> status; guaranteed if one calls
+ <xref linkend="libpq-PQregisterEventProc"/> right after obtaining a good
+ <structname>PGconn</structname>. When returning a failure code, all
+ cleanup must be performed as no <literal>PGEVT_CONNDESTROY</literal>
+ event will be sent.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgevt-connreset">
+ <term><literal>PGEVT_CONNRESET</literal></term>
+ <listitem>
+ <para>
+ The connection reset event is fired on completion of
+ <xref linkend="libpq-PQreset"/> or <function>PQresetPoll</function>. In
+ both cases, the event is only fired if the reset was successful.
+ The return value of the event procedure is ignored
+ in <productname>PostgreSQL</productname> v15 and later.
+ With earlier versions, however, it's important to return success
+ (nonzero) or the connection will be aborted.
+
+<synopsis>
+typedef struct
+{
+ PGconn *conn;
+} PGEventConnReset;
+</synopsis>
+
+ When a <literal>PGEVT_CONNRESET</literal> event is received, the
+ <parameter>evtInfo</parameter> pointer should be cast to a
+ <structname>PGEventConnReset *</structname>. Although the contained
+ <structname>PGconn</structname> was just reset, all event data remains
+ unchanged. This event should be used to reset/reload/requery any
+ associated <literal>instanceData</literal>. Note that even if the
+ event procedure fails to process <literal>PGEVT_CONNRESET</literal>, it will
+ still receive a <literal>PGEVT_CONNDESTROY</literal> event when the connection
+ is closed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgevt-conndestroy">
+ <term><literal>PGEVT_CONNDESTROY</literal></term>
+ <listitem>
+ <para>
+ The connection destroy event is fired in response to
+ <xref linkend="libpq-PQfinish"/>. It is the event procedure's
+ responsibility to properly clean up its event data as libpq has no
+ ability to manage this memory. Failure to clean up will lead
+ to memory leaks.
+
+<synopsis>
+typedef struct
+{
+ PGconn *conn;
+} PGEventConnDestroy;
+</synopsis>
+
+ When a <literal>PGEVT_CONNDESTROY</literal> event is received, the
+ <parameter>evtInfo</parameter> pointer should be cast to a
+ <structname>PGEventConnDestroy *</structname>. This event is fired
+ prior to <xref linkend="libpq-PQfinish"/> performing any other cleanup.
+ The return value of the event procedure is ignored since there is no
+ way of indicating a failure from <xref linkend="libpq-PQfinish"/>. Also,
+ an event procedure failure should not abort the process of cleaning up
+ unwanted memory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgevt-resultcreate">
+ <term><literal>PGEVT_RESULTCREATE</literal></term>
+ <listitem>
+ <para>
+ The result creation event is fired in response to any query execution
+ function that generates a result, including
+ <xref linkend="libpq-PQgetResult"/>. This event will only be fired after
+ the result has been created successfully.
+
+<synopsis>
+typedef struct
+{
+ PGconn *conn;
+ PGresult *result;
+} PGEventResultCreate;
+</synopsis>
+
+ When a <literal>PGEVT_RESULTCREATE</literal> event is received, the
+ <parameter>evtInfo</parameter> pointer should be cast to a
+ <structname>PGEventResultCreate *</structname>. The
+ <parameter>conn</parameter> is the connection used to generate the
+ result. This is the ideal place to initialize any
+ <literal>instanceData</literal> that needs to be associated with the
+ result. If an event procedure fails (returns zero), that event
+ procedure will be ignored for the remaining lifetime of the result;
+ that is, it will not receive <literal>PGEVT_RESULTCOPY</literal>
+ or <literal>PGEVT_RESULTDESTROY</literal> events for this result or
+ results copied from it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgevt-resultcopy">
+ <term><literal>PGEVT_RESULTCOPY</literal></term>
+ <listitem>
+ <para>
+ The result copy event is fired in response to
+ <xref linkend="libpq-PQcopyResult"/>. This event will only be fired after
+ the copy is complete. Only event procedures that have
+ successfully handled the <literal>PGEVT_RESULTCREATE</literal>
+ or <literal>PGEVT_RESULTCOPY</literal> event for the source result
+ will receive <literal>PGEVT_RESULTCOPY</literal> events.
+
+<synopsis>
+typedef struct
+{
+ const PGresult *src;
+ PGresult *dest;
+} PGEventResultCopy;
+</synopsis>
+
+ When a <literal>PGEVT_RESULTCOPY</literal> event is received, the
+ <parameter>evtInfo</parameter> pointer should be cast to a
+ <structname>PGEventResultCopy *</structname>. The
+ <parameter>src</parameter> result is what was copied while the
+ <parameter>dest</parameter> result is the copy destination. This event
+ can be used to provide a deep copy of <literal>instanceData</literal>,
+ since <literal>PQcopyResult</literal> cannot do that. If an event
+ procedure fails (returns zero), that event procedure will be
+ ignored for the remaining lifetime of the new result; that is, it
+ will not receive <literal>PGEVT_RESULTCOPY</literal>
+ or <literal>PGEVT_RESULTDESTROY</literal> events for that result or
+ results copied from it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-pgevt-resultdestroy">
+ <term><literal>PGEVT_RESULTDESTROY</literal></term>
+ <listitem>
+ <para>
+ The result destroy event is fired in response to a
+ <xref linkend="libpq-PQclear"/>. It is the event procedure's
+ responsibility to properly clean up its event data as libpq has no
+ ability to manage this memory. Failure to clean up will lead
+ to memory leaks.
+
+<synopsis>
+typedef struct
+{
+ PGresult *result;
+} PGEventResultDestroy;
+</synopsis>
+
+ When a <literal>PGEVT_RESULTDESTROY</literal> event is received, the
+ <parameter>evtInfo</parameter> pointer should be cast to a
+ <structname>PGEventResultDestroy *</structname>. This event is fired
+ prior to <xref linkend="libpq-PQclear"/> performing any other cleanup.
+ The return value of the event procedure is ignored since there is no
+ way of indicating a failure from <xref linkend="libpq-PQclear"/>. Also,
+ an event procedure failure should not abort the process of cleaning up
+ unwanted memory.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="libpq-events-proc">
+ <title>Event Callback Procedure</title>
+
+ <variablelist>
+ <varlistentry id="libpq-PGEventProc">
+ <term><literal>PGEventProc</literal><indexterm><primary>PGEventProc</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ <literal>PGEventProc</literal> is a typedef for a pointer to an
+ event procedure, that is, the user callback function that receives
+ events from libpq. The signature of an event procedure must be
+
+<synopsis>
+int eventproc(PGEventId evtId, void *evtInfo, void *passThrough)
+</synopsis>
+
+ The <parameter>evtId</parameter> parameter indicates which
+ <literal>PGEVT</literal> event occurred. The
+ <parameter>evtInfo</parameter> pointer must be cast to the appropriate
+ structure type to obtain further information about the event.
+ The <parameter>passThrough</parameter> parameter is the pointer
+ provided to <xref linkend="libpq-PQregisterEventProc"/> when the event
+ procedure was registered. The function should return a non-zero value
+ if it succeeds and zero if it fails.
+ </para>
+
+ <para>
+ A particular event procedure can be registered only once in any
+ <structname>PGconn</structname>. This is because the address of the procedure
+ is used as a lookup key to identify the associated instance data.
+ </para>
+
+ <caution>
+ <para>
+ On Windows, functions can have two different addresses: one visible
+ from outside a DLL and another visible from inside the DLL. One
+ should be careful that only one of these addresses is used with
+ <application>libpq</application>'s event-procedure functions, else confusion will
+ result. The simplest rule for writing code that will work is to
+ ensure that event procedures are declared <literal>static</literal>. If the
+ procedure's address must be available outside its own source file,
+ expose a separate function to return the address.
+ </para>
+ </caution>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="libpq-events-funcs">
+ <title>Event Support Functions</title>
+
+ <variablelist>
+ <varlistentry id="libpq-PQregisterEventProc">
+ <term><function>PQregisterEventProc</function><indexterm><primary>PQregisterEventProc</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Registers an event callback procedure with libpq.
+
+<synopsis>
+int PQregisterEventProc(PGconn *conn, PGEventProc proc,
+ const char *name, void *passThrough);
+</synopsis>
+ </para>
+
+ <para>
+ An event procedure must be registered once on each
+ <structname>PGconn</structname> you want to receive events about. There is no
+ limit, other than memory, on the number of event procedures that
+ can be registered with a connection. The function returns a non-zero
+ value if it succeeds and zero if it fails.
+ </para>
+
+ <para>
+ The <parameter>proc</parameter> argument will be called when a libpq
+ event is fired. Its memory address is also used to lookup
+ <literal>instanceData</literal>. The <parameter>name</parameter>
+ argument is used to refer to the event procedure in error messages.
+ This value cannot be <symbol>NULL</symbol> or a zero-length string. The name string is
+ copied into the <structname>PGconn</structname>, so what is passed need not be
+ long-lived. The <parameter>passThrough</parameter> pointer is passed
+ to the <parameter>proc</parameter> whenever an event occurs. This
+ argument can be <symbol>NULL</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQsetInstanceData">
+ <term><function>PQsetInstanceData</function><indexterm><primary>PQsetInstanceData</primary></indexterm></term>
+ <listitem>
+ <para>
+ Sets the connection <parameter>conn</parameter>'s <literal>instanceData</literal>
+ for procedure <parameter>proc</parameter> to <parameter>data</parameter>. This
+ returns non-zero for success and zero for failure. (Failure is
+ only possible if <parameter>proc</parameter> has not been properly
+ registered in <parameter>conn</parameter>.)
+
+<synopsis>
+int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQinstanceData">
+ <term><function>PQinstanceData</function><indexterm><primary>PQinstanceData</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns the
+ connection <parameter>conn</parameter>'s <literal>instanceData</literal>
+ associated with procedure <parameter>proc</parameter>,
+ or <symbol>NULL</symbol> if there is none.
+
+<synopsis>
+void *PQinstanceData(const PGconn *conn, PGEventProc proc);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultSetInstanceData">
+ <term><function>PQresultSetInstanceData</function><indexterm><primary>PQresultSetInstanceData</primary></indexterm></term>
+ <listitem>
+ <para>
+ Sets the result's <literal>instanceData</literal>
+ for <parameter>proc</parameter> to <parameter>data</parameter>. This returns
+ non-zero for success and zero for failure. (Failure is only
+ possible if <parameter>proc</parameter> has not been properly registered
+ in the result.)
+
+<synopsis>
+int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);
+</synopsis>
+ </para>
+
+ <para>
+ Beware that any storage represented by <parameter>data</parameter>
+ will not be accounted for by <xref linkend="libpq-PQresultMemorySize"/>,
+ unless it is allocated using <xref linkend="libpq-PQresultAlloc"/>.
+ (Doing so is recommendable because it eliminates the need to free
+ such storage explicitly when the result is destroyed.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQresultInstanceData">
+ <term><function>PQresultInstanceData</function><indexterm><primary>PQresultInstanceData</primary></indexterm></term>
+ <listitem>
+ <para>
+ Returns the result's <literal>instanceData</literal> associated with <parameter>proc</parameter>, or <symbol>NULL</symbol>
+ if there is none.
+
+<synopsis>
+void *PQresultInstanceData(const PGresult *res, PGEventProc proc);
+</synopsis>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="libpq-events-example">
+ <title>Event Example</title>
+
+ <para>
+ Here is a skeleton example of managing private data associated with
+ libpq connections and results.
+ </para>
+
+<programlisting>
+<![CDATA[
+/* required header for libpq events (note: includes libpq-fe.h) */
+#include <libpq-events.h>
+
+/* The instanceData */
+typedef struct
+{
+ int n;
+ char *str;
+} mydata;
+
+/* PGEventProc */
+static int myEventProc(PGEventId evtId, void *evtInfo, void *passThrough);
+
+int
+main(void)
+{
+ mydata *data;
+ PGresult *res;
+ PGconn *conn =
+ PQconnectdb("dbname=postgres options=-csearch_path=");
+
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ /* PQerrorMessage's result includes a trailing newline */
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ PQfinish(conn);
+ return 1;
+ }
+
+ /* called once on any connection that should receive events.
+ * Sends a PGEVT_REGISTER to myEventProc.
+ */
+ if (!PQregisterEventProc(conn, myEventProc, "mydata_proc", NULL))
+ {
+ fprintf(stderr, "Cannot register PGEventProc\n");
+ PQfinish(conn);
+ return 1;
+ }
+
+ /* conn instanceData is available */
+ data = PQinstanceData(conn, myEventProc);
+
+ /* Sends a PGEVT_RESULTCREATE to myEventProc */
+ res = PQexec(conn, "SELECT 1 + 1");
+
+ /* result instanceData is available */
+ data = PQresultInstanceData(res, myEventProc);
+
+ /* If PG_COPYRES_EVENTS is used, sends a PGEVT_RESULTCOPY to myEventProc */
+ res_copy = PQcopyResult(res, PG_COPYRES_TUPLES | PG_COPYRES_EVENTS);
+
+ /* result instanceData is available if PG_COPYRES_EVENTS was
+ * used during the PQcopyResult call.
+ */
+ data = PQresultInstanceData(res_copy, myEventProc);
+
+ /* Both clears send a PGEVT_RESULTDESTROY to myEventProc */
+ PQclear(res);
+ PQclear(res_copy);
+
+ /* Sends a PGEVT_CONNDESTROY to myEventProc */
+ PQfinish(conn);
+
+ return 0;
+}
+
+static int
+myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
+{
+ switch (evtId)
+ {
+ case PGEVT_REGISTER:
+ {
+ PGEventRegister *e = (PGEventRegister *)evtInfo;
+ mydata *data = get_mydata(e->conn);
+
+ /* associate app specific data with connection */
+ PQsetInstanceData(e->conn, myEventProc, data);
+ break;
+ }
+
+ case PGEVT_CONNRESET:
+ {
+ PGEventConnReset *e = (PGEventConnReset *)evtInfo;
+ mydata *data = PQinstanceData(e->conn, myEventProc);
+
+ if (data)
+ memset(data, 0, sizeof(mydata));
+ break;
+ }
+
+ case PGEVT_CONNDESTROY:
+ {
+ PGEventConnDestroy *e = (PGEventConnDestroy *)evtInfo;
+ mydata *data = PQinstanceData(e->conn, myEventProc);
+
+ /* free instance data because the conn is being destroyed */
+ if (data)
+ free_mydata(data);
+ break;
+ }
+
+ case PGEVT_RESULTCREATE:
+ {
+ PGEventResultCreate *e = (PGEventResultCreate *)evtInfo;
+ mydata *conn_data = PQinstanceData(e->conn, myEventProc);
+ mydata *res_data = dup_mydata(conn_data);
+
+ /* associate app specific data with result (copy it from conn) */
+ PQresultSetInstanceData(e->result, myEventProc, res_data);
+ break;
+ }
+
+ case PGEVT_RESULTCOPY:
+ {
+ PGEventResultCopy *e = (PGEventResultCopy *)evtInfo;
+ mydata *src_data = PQresultInstanceData(e->src, myEventProc);
+ mydata *dest_data = dup_mydata(src_data);
+
+ /* associate app specific data with result (copy it from a result) */
+ PQresultSetInstanceData(e->dest, myEventProc, dest_data);
+ break;
+ }
+
+ case PGEVT_RESULTDESTROY:
+ {
+ PGEventResultDestroy *e = (PGEventResultDestroy *)evtInfo;
+ mydata *data = PQresultInstanceData(e->result, myEventProc);
+
+ /* free instance data because the result is being destroyed */
+ if (data)
+ free_mydata(data);
+ break;
+ }
+
+ /* unknown event ID, just return true. */
+ default:
+ break;
+ }
+
+ return true; /* event processing succeeded */
+}
+]]>
+</programlisting>
+ </sect2>
+ </sect1>
+
+ <sect1 id="libpq-envars">
+ <title>Environment Variables</title>
+
+ <indexterm zone="libpq-envars">
+ <primary>environment variable</primary>
+ </indexterm>
+
+ <para>
+ The following environment variables can be used to select default
+ connection parameter values, which will be used by
+ <xref linkend="libpq-PQconnectdb"/>, <xref linkend="libpq-PQsetdbLogin"/> and
+ <xref linkend="libpq-PQsetdb"/> if no value is directly specified by the calling
+ code. These are useful to avoid hard-coding database connection
+ information into simple client applications, for example.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGHOST</envar></primary>
+ </indexterm>
+ <envar>PGHOST</envar> behaves the same as the <xref
+ linkend="libpq-connect-host"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGHOSTADDR</envar></primary>
+ </indexterm>
+ <envar>PGHOSTADDR</envar> behaves the same as the <xref
+ linkend="libpq-connect-hostaddr"/> connection parameter.
+ This can be set instead of or in addition to <envar>PGHOST</envar>
+ to avoid DNS lookup overhead.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGPORT</envar></primary>
+ </indexterm>
+ <envar>PGPORT</envar> behaves the same as the <xref
+ linkend="libpq-connect-port"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGDATABASE</envar></primary>
+ </indexterm>
+ <envar>PGDATABASE</envar> behaves the same as the <xref
+ linkend="libpq-connect-dbname"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGUSER</envar></primary>
+ </indexterm>
+ <envar>PGUSER</envar> behaves the same as the <xref
+ linkend="libpq-connect-user"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGPASSWORD</envar></primary>
+ </indexterm>
+ <envar>PGPASSWORD</envar> behaves the same as the <xref
+ linkend="libpq-connect-password"/> connection parameter.
+ Use of this environment variable
+ is not recommended for security reasons, as some operating systems
+ allow non-root users to see process environment variables via
+ <application>ps</application>; instead consider using a password file
+ (see <xref linkend="libpq-pgpass"/>).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGPASSFILE</envar></primary>
+ </indexterm>
+ <envar>PGPASSFILE</envar> behaves the same as the <xref
+ linkend="libpq-connect-passfile"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGCHANNELBINDING</envar></primary>
+ </indexterm>
+ <envar>PGCHANNELBINDING</envar> behaves the same as the <xref
+ linkend="libpq-connect-channel-binding"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSERVICE</envar></primary>
+ </indexterm>
+ <envar>PGSERVICE</envar> behaves the same as the <xref
+ linkend="libpq-connect-service"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSERVICEFILE</envar></primary>
+ </indexterm>
+ <envar>PGSERVICEFILE</envar> specifies the name of the per-user
+ connection service file
+ (see <xref linkend="libpq-pgservice"/>).
+ Defaults to <filename>~/.pg_service.conf</filename>, or
+ <filename>%APPDATA%\postgresql\.pg_service.conf</filename> on
+ Microsoft Windows.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGOPTIONS</envar></primary>
+ </indexterm>
+ <envar>PGOPTIONS</envar> behaves the same as the <xref
+ linkend="libpq-connect-options"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGAPPNAME</envar></primary>
+ </indexterm>
+ <envar>PGAPPNAME</envar> behaves the same as the <xref
+ linkend="libpq-connect-application-name"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLMODE</envar></primary>
+ </indexterm>
+ <envar>PGSSLMODE</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslmode"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGREQUIRESSL</envar></primary>
+ </indexterm>
+ <envar>PGREQUIRESSL</envar> behaves the same as the <xref
+ linkend="libpq-connect-requiressl"/> connection parameter.
+ This environment variable is deprecated in favor of the
+ <envar>PGSSLMODE</envar> variable; setting both variables suppresses the
+ effect of this one.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLCOMPRESSION</envar></primary>
+ </indexterm>
+ <envar>PGSSLCOMPRESSION</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslcompression"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLCERT</envar></primary>
+ </indexterm>
+ <envar>PGSSLCERT</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslcert"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLKEY</envar></primary>
+ </indexterm>
+ <envar>PGSSLKEY</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslkey"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLROOTCERT</envar></primary>
+ </indexterm>
+ <envar>PGSSLROOTCERT</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslrootcert"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLCRL</envar></primary>
+ </indexterm>
+ <envar>PGSSLCRL</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslcrl"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLCRLDIR</envar></primary>
+ </indexterm>
+ <envar>PGSSLCRLDIR</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslcrldir"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLSNI</envar></primary>
+ </indexterm>
+ <envar>PGSSLSNI</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslsni"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGREQUIREPEER</envar></primary>
+ </indexterm>
+ <envar>PGREQUIREPEER</envar> behaves the same as the <xref
+ linkend="libpq-connect-requirepeer"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLMINPROTOCOLVERSION</envar></primary>
+ </indexterm>
+ <envar>PGSSLMINPROTOCOLVERSION</envar> behaves the same as the <xref
+ linkend="libpq-connect-ssl-min-protocol-version"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLMAXPROTOCOLVERSION</envar></primary>
+ </indexterm>
+ <envar>PGSSLMAXPROTOCOLVERSION</envar> behaves the same as the <xref
+ linkend="libpq-connect-ssl-max-protocol-version"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGGSSENCMODE</envar></primary>
+ </indexterm>
+ <envar>PGGSSENCMODE</envar> behaves the same as the <xref
+ linkend="libpq-connect-gssencmode"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGKRBSRVNAME</envar></primary>
+ </indexterm>
+ <envar>PGKRBSRVNAME</envar> behaves the same as the <xref
+ linkend="libpq-connect-krbsrvname"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGGSSLIB</envar></primary>
+ </indexterm>
+ <envar>PGGSSLIB</envar> behaves the same as the <xref
+ linkend="libpq-connect-gsslib"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGCONNECT_TIMEOUT</envar></primary>
+ </indexterm>
+ <envar>PGCONNECT_TIMEOUT</envar> behaves the same as the <xref
+ linkend="libpq-connect-connect-timeout"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGCLIENTENCODING</envar></primary>
+ </indexterm>
+ <envar>PGCLIENTENCODING</envar> behaves the same as the <xref
+ linkend="libpq-connect-client-encoding"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGTARGETSESSIONATTRS</envar></primary>
+ </indexterm>
+ <envar>PGTARGETSESSIONATTRS</envar> behaves the same as the <xref
+ linkend="libpq-connect-target-session-attrs"/> connection parameter.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The following environment variables can be used to specify default
+ behavior for each <productname>PostgreSQL</productname> session. (See
+ also the <xref linkend="sql-alterrole"/>
+ and <xref linkend="sql-alterdatabase"/>
+ commands for ways to set default behavior on a per-user or per-database
+ basis.)
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGDATESTYLE</envar></primary>
+ </indexterm>
+ <envar>PGDATESTYLE</envar> sets the default style of date/time
+ representation. (Equivalent to <literal>SET datestyle TO
+ ...</literal>.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGTZ</envar></primary>
+ </indexterm>
+ <envar>PGTZ</envar> sets the default time zone. (Equivalent to
+ <literal>SET timezone TO ...</literal>.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGGEQO</envar></primary>
+ </indexterm>
+ <envar>PGGEQO</envar> sets the default mode for the genetic query
+ optimizer. (Equivalent to <literal>SET geqo TO ...</literal>.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Refer to the <acronym>SQL</acronym> command <xref linkend="sql-set"/>
+ for information on correct values for these
+ environment variables.
+ </para>
+
+ <para>
+ The following environment variables determine internal behavior of
+ <application>libpq</application>; they override compiled-in defaults.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSYSCONFDIR</envar></primary>
+ </indexterm>
+ <envar>PGSYSCONFDIR</envar> sets the directory containing the
+ <filename>pg_service.conf</filename> file and in a future version
+ possibly other system-wide configuration files.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGLOCALEDIR</envar></primary>
+ </indexterm>
+ <envar>PGLOCALEDIR</envar> sets the directory containing the
+ <literal>locale</literal> files for message localization.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="libpq-pgpass">
+ <title>The Password File</title>
+
+ <indexterm zone="libpq-pgpass">
+ <primary>password file</primary>
+ </indexterm>
+ <indexterm zone="libpq-pgpass">
+ <primary>.pgpass</primary>
+ </indexterm>
+
+ <para>
+ The file <filename>.pgpass</filename> in a user's home directory can
+ contain passwords to
+ be used if the connection requires a password (and no password has been
+ specified otherwise). On Microsoft Windows the file is named
+ <filename>%APPDATA%\postgresql\pgpass.conf</filename> (where
+ <filename>%APPDATA%</filename> refers to the Application Data subdirectory in
+ the user's profile).
+ Alternatively, the password file to use can be specified
+ using the connection parameter <xref linkend="libpq-connect-passfile"/>
+ or the environment variable <envar>PGPASSFILE</envar>.
+ </para>
+
+ <para>
+ This file should contain lines of the following format:
+<synopsis>
+<replaceable>hostname</replaceable>:<replaceable>port</replaceable>:<replaceable>database</replaceable>:<replaceable>username</replaceable>:<replaceable>password</replaceable>
+</synopsis>
+ (You can add a reminder comment to the file by copying the line above and
+ preceding it with <literal>#</literal>.)
+ Each of the first four fields can be a literal value, or
+ <literal>*</literal>, which matches anything. The password field from
+ the first line that matches the current connection parameters will be
+ used. (Therefore, put more-specific entries first when you are using
+ wildcards.) If an entry needs to contain <literal>:</literal> or
+ <literal>\</literal>, escape this character with <literal>\</literal>.
+ The host name field is matched to the <literal>host</literal> connection
+ parameter if that is specified, otherwise to
+ the <literal>hostaddr</literal> parameter if that is specified; if neither
+ are given then the host name <literal>localhost</literal> is searched for.
+ The host name <literal>localhost</literal> is also searched for when
+ the connection is a Unix-domain socket connection and
+ the <literal>host</literal> parameter
+ matches <application>libpq</application>'s default socket directory path.
+ In a standby server, a database field of <literal>replication</literal>
+ matches streaming replication connections made to the primary server.
+ The database field is of limited usefulness otherwise, because users have
+ the same password for all databases in the same cluster.
+ </para>
+
+ <para>
+ On Unix systems, the permissions on a password file must
+ disallow any access to world or group; achieve this by a command such as
+ <command>chmod 0600 ~/.pgpass</command>. If the permissions are less
+ strict than this, the file will be ignored. On Microsoft Windows, it
+ is assumed that the file is stored in a directory that is secure, so
+ no special permissions check is made.
+ </para>
+ </sect1>
+
+
+ <sect1 id="libpq-pgservice">
+ <title>The Connection Service File</title>
+
+ <indexterm zone="libpq-pgservice">
+ <primary>connection service file</primary>
+ </indexterm>
+ <indexterm zone="libpq-pgservice">
+ <primary>pg_service.conf</primary>
+ </indexterm>
+ <indexterm zone="libpq-pgservice">
+ <primary>.pg_service.conf</primary>
+ </indexterm>
+
+ <para>
+ The connection service file allows libpq connection parameters to be
+ associated with a single service name. That service name can then be
+ specified in a libpq connection string, and the associated settings will be
+ used. This allows connection parameters to be modified without requiring
+ a recompile of the libpq-using application. The service name can also be
+ specified using the <envar>PGSERVICE</envar> environment variable.
+ </para>
+
+ <para>
+ Service names can be defined in either a per-user service file or a
+ system-wide file. If the same service name exists in both the user
+ and the system file, the user file takes precedence.
+ By default, the per-user service file is named
+ <filename>~/.pg_service.conf</filename>.
+ On Microsoft Windows, it is named
+ <filename>%APPDATA%\postgresql\.pg_service.conf</filename> (where
+ <filename>%APPDATA%</filename> refers to the Application Data subdirectory
+ in the user's profile). A different file name can be specified by
+ setting the environment variable <envar>PGSERVICEFILE</envar>.
+ The system-wide file is named <filename>pg_service.conf</filename>.
+ By default it is sought in the <filename>etc</filename> directory
+ of the <productname>PostgreSQL</productname> installation
+ (use <literal>pg_config --sysconfdir</literal> to identify this
+ directory precisely). Another directory, but not a different file
+ name, can be specified by setting the environment variable
+ <envar>PGSYSCONFDIR</envar>.
+ </para>
+
+ <para>
+ Either service file uses an <quote>INI file</quote> format where the section
+ name is the service name and the parameters are connection
+ parameters; see <xref linkend="libpq-paramkeywords"/> for a list. For
+ example:
+<programlisting>
+# comment
+[mydb]
+host=somehost
+port=5433
+user=admin
+</programlisting>
+ An example file is provided in
+ the <productname>PostgreSQL</productname> installation at
+ <filename>share/pg_service.conf.sample</filename>.
+ </para>
+
+ <para>
+ Connection parameters obtained from a service file are combined with
+ parameters obtained from other sources. A service file setting
+ overrides the corresponding environment variable, and in turn can be
+ overridden by a value given directly in the connection string.
+ For example, using the above service file, a connection string
+ <literal>service=mydb port=5434</literal> will use
+ host <literal>somehost</literal>, port <literal>5434</literal>,
+ user <literal>admin</literal>, and other parameters as set by
+ environment variables or built-in defaults.
+ </para>
+ </sect1>
+
+
+ <sect1 id="libpq-ldap">
+ <title>LDAP Lookup of Connection Parameters</title>
+
+ <indexterm zone="libpq-ldap">
+ <primary>LDAP connection parameter lookup</primary>
+ </indexterm>
+
+ <para>
+ If <application>libpq</application> has been compiled with LDAP support (option
+ <literal><option>--with-ldap</option></literal> for <command>configure</command>)
+ it is possible to retrieve connection options like <literal>host</literal>
+ or <literal>dbname</literal> via LDAP from a central server.
+ The advantage is that if the connection parameters for a database change,
+ the connection information doesn't have to be updated on all client machines.
+ </para>
+
+ <para>
+ LDAP connection parameter lookup uses the connection service file
+ <filename>pg_service.conf</filename> (see <xref
+ linkend="libpq-pgservice"/>). A line in a
+ <filename>pg_service.conf</filename> stanza that starts with
+ <literal>ldap://</literal> will be recognized as an LDAP URL and an
+ LDAP query will be performed. The result must be a list of
+ <literal>keyword = value</literal> pairs which will be used to set
+ connection options. The URL must conform to
+ <ulink url="https://tools.ietf.org/html/rfc1959">RFC 1959</ulink>
+ and be of the form
+<synopsis>
+ldap://[<replaceable>hostname</replaceable>[:<replaceable>port</replaceable>]]/<replaceable>search_base</replaceable>?<replaceable>attribute</replaceable>?<replaceable>search_scope</replaceable>?<replaceable>filter</replaceable>
+</synopsis>
+ where <replaceable>hostname</replaceable> defaults to
+ <literal>localhost</literal> and <replaceable>port</replaceable>
+ defaults to 389.
+ </para>
+
+ <para>
+ Processing of <filename>pg_service.conf</filename> is terminated after
+ a successful LDAP lookup, but is continued if the LDAP server cannot
+ be contacted. This is to provide a fallback with further LDAP URL
+ lines that point to different LDAP servers, classical <literal>keyword
+ = value</literal> pairs, or default connection options. If you would
+ rather get an error message in this case, add a syntactically incorrect
+ line after the LDAP URL.
+ </para>
+
+ <para>
+ A sample LDAP entry that has been created with the LDIF file
+<programlisting>
+version:1
+dn:cn=mydatabase,dc=mycompany,dc=com
+changetype:add
+objectclass:top
+objectclass:device
+cn:mydatabase
+description:host=dbserver.mycompany.com
+description:port=5439
+description:dbname=mydb
+description:user=mydb_user
+description:sslmode=require
+</programlisting>
+ might be queried with the following LDAP URL:
+<programlisting>
+ldap://ldap.mycompany.com/dc=mycompany,dc=com?description?one?(cn=mydatabase)
+</programlisting>
+ </para>
+
+ <para>
+ You can also mix regular service file entries with LDAP lookups.
+ A complete example for a stanza in <filename>pg_service.conf</filename>
+ would be:
+<programlisting>
+# only host and port are stored in LDAP, specify dbname and user explicitly
+[customerdb]
+dbname=customer
+user=appuser
+ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
+</programlisting>
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="libpq-ssl">
+ <title>SSL Support</title>
+
+ <indexterm zone="libpq-ssl">
+ <primary>SSL</primary>
+ <secondary>TLS</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> has native support for using <acronym>SSL</acronym>
+ connections to encrypt client/server communications using
+ <acronym>TLS</acronym> protocols for increased security.
+ See <xref linkend="ssl-tcp"/> for details about the server-side
+ <acronym>SSL</acronym> functionality.
+ </para>
+
+ <para>
+ <application>libpq</application> reads the system-wide
+ <productname>OpenSSL</productname> configuration file. By default, this
+ file is named <filename>openssl.cnf</filename> and is located in the
+ directory reported by <literal>openssl version -d</literal>. This default
+ can be overridden by setting environment variable
+ <envar>OPENSSL_CONF</envar> to the name of the desired configuration
+ file.
+ </para>
+
+ <sect2 id="libq-ssl-certificates">
+ <title>Client Verification of Server Certificates</title>
+
+ <para>
+ By default, <productname>PostgreSQL</productname> will not perform any verification of
+ the server certificate. This means that it is possible to spoof the server
+ identity (for example by modifying a DNS record or by taking over the server
+ IP address) without the client knowing. In order to prevent spoofing,
+ the client must be able to verify the server's identity via a chain of
+ trust. A chain of trust is established by placing a root (self-signed)
+ certificate authority (<acronym>CA</acronym>) certificate on one
+ computer and a leaf certificate <emphasis>signed</emphasis> by the
+ root certificate on another computer. It is also possible to use an
+ <quote>intermediate</quote> certificate which is signed by the root
+ certificate and signs leaf certificates.
+ </para>
+
+ <para>
+ To allow the client to verify the identity of the server, place a root
+ certificate on the client and a leaf certificate signed by the root
+ certificate on the server. To allow the server to verify the identity
+ of the client, place a root certificate on the server and a leaf
+ certificate signed by the root certificate on the client. One or more
+ intermediate certificates (usually stored with the leaf certificate)
+ can also be used to link the leaf certificate to the root certificate.
+ </para>
+
+ <para>
+ Once a chain of trust has been established, there are two ways for
+ the client to validate the leaf certificate sent by the server.
+ If the parameter <literal>sslmode</literal> is set to <literal>verify-ca</literal>,
+ libpq will verify that the server is trustworthy by checking the
+ certificate chain up to the root certificate stored on the client.
+ If <literal>sslmode</literal> is set to <literal>verify-full</literal>,
+ libpq will <emphasis>also</emphasis> verify that the server host
+ name matches the name stored in the server certificate. The
+ SSL connection will fail if the server certificate cannot be
+ verified. <literal>verify-full</literal> is recommended in most
+ security-sensitive environments.
+ </para>
+
+ <para>
+ In <literal>verify-full</literal> mode, the host name is matched against the
+ certificate's Subject Alternative Name attribute(s) (SAN), or against the
+ Common Name attribute if no SAN of type <literal>dNSName</literal> is
+ present. If the certificate's name attribute starts with an asterisk
+ (<literal>*</literal>), the asterisk will be treated as
+ a wildcard, which will match all characters <emphasis>except</emphasis> a dot
+ (<literal>.</literal>). This means the certificate will not match subdomains.
+ If the connection is made using an IP address instead of a host name, the
+ IP address will be matched (without doing any DNS lookups) against SANs of
+ type <literal>iPAddress</literal> or <literal>dNSName</literal>. If no
+ <literal>iPAddress</literal> SAN is present and no
+ matching <literal>dNSName</literal> SAN is present, the host IP address is
+ matched against the Common Name attribute.
+ </para>
+
+ <note>
+ <para>
+ For backward compatibility with earlier versions of PostgreSQL, the host
+ IP address is verified in a manner different
+ from <ulink url="https://tools.ietf.org/html/rfc6125">RFC 6125</ulink>.
+ The host IP address is always matched against <literal>dNSName</literal>
+ SANs as well as <literal>iPAddress</literal> SANs, and can be matched
+ against the Common Name attribute if no relevant SANs exist.
+ </para>
+ </note>
+
+ <para>
+ To allow server certificate verification, one or more root certificates
+ must be placed in the file <filename>~/.postgresql/root.crt</filename>
+ in the user's home directory. (On Microsoft Windows the file is named
+ <filename>%APPDATA%\postgresql\root.crt</filename>.) Intermediate
+ certificates should also be added to the file if they are needed to link
+ the certificate chain sent by the server to the root certificates
+ stored on the client.
+ </para>
+
+ <para>
+ Certificate Revocation List (CRL) entries are also checked
+ if the file <filename>~/.postgresql/root.crl</filename> exists
+ (<filename>%APPDATA%\postgresql\root.crl</filename> on Microsoft
+ Windows).
+ </para>
+
+ <para>
+ The location of the root certificate file and the CRL can be changed by
+ setting
+ the connection parameters <literal>sslrootcert</literal> and <literal>sslcrl</literal>
+ or the environment variables <envar>PGSSLROOTCERT</envar> and <envar>PGSSLCRL</envar>.
+ <literal>sslcrldir</literal> or the environment variable <envar>PGSSLCRLDIR</envar>
+ can also be used to specify a directory containing CRL files.
+ </para>
+
+ <note>
+ <para>
+ For backwards compatibility with earlier versions of PostgreSQL, if a
+ root CA file exists, the behavior of
+ <literal>sslmode</literal>=<literal>require</literal> will be the same
+ as that of <literal>verify-ca</literal>, meaning the server certificate
+ is validated against the CA. Relying on this behavior is discouraged,
+ and applications that need certificate validation should always use
+ <literal>verify-ca</literal> or <literal>verify-full</literal>.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="libpq-ssl-clientcert">
+ <title>Client Certificates</title>
+
+ <para>
+ If the server attempts to verify the identity of the
+ client by requesting the client's leaf certificate,
+ <application>libpq</application> will send the certificate(s) stored in
+ file <filename>~/.postgresql/postgresql.crt</filename> in the user's home
+ directory. The certificates must chain to the root certificate trusted
+ by the server. A matching
+ private key file <filename>~/.postgresql/postgresql.key</filename> must also
+ be present.
+ On Microsoft Windows these files are named
+ <filename>%APPDATA%\postgresql\postgresql.crt</filename> and
+ <filename>%APPDATA%\postgresql\postgresql.key</filename>.
+ The location of the certificate and key files can be overridden by the
+ connection parameters <literal>sslcert</literal>
+ and <literal>sslkey</literal>, or by the
+ environment variables <envar>PGSSLCERT</envar> and <envar>PGSSLKEY</envar>.
+ </para>
+
+ <para>
+ On Unix systems, the permissions on the private key file must disallow
+ any access to world or group; achieve this by a command such as
+ <command>chmod 0600 ~/.postgresql/postgresql.key</command>.
+ Alternatively, the file can be owned by root and have group read access
+ (that is, <literal>0640</literal> permissions). That setup is intended
+ for installations where certificate and key files are managed by the
+ operating system. The user of <application>libpq</application> should
+ then be made a member of the group that has access to those certificate
+ and key files. (On Microsoft Windows, there is no file permissions
+ check, since the <filename>%APPDATA%\postgresql</filename> directory is
+ presumed secure.)
+ </para>
+
+ <para>
+ The first certificate in <filename>postgresql.crt</filename> must be the
+ client's certificate because it must match the client's private key.
+ <quote>Intermediate</quote> certificates can be optionally appended
+ to the file &mdash; doing so avoids requiring storage of intermediate
+ certificates on the server (<xref linkend="guc-ssl-ca-file"/>).
+ </para>
+
+ <para>
+ The certificate and key may be in PEM or ASN.1 DER format.
+ </para>
+
+ <para>
+ The key may be
+ stored in cleartext or encrypted with a passphrase using any algorithm
+ supported by <productname>OpenSSL</productname>, like AES-128. If the key
+ is stored encrypted, then the passphrase may be provided in the
+ <xref linkend="libpq-connect-sslpassword"/> connection option. If an
+ encrypted key is supplied and the <literal>sslpassword</literal> option
+ is absent or blank, a password will be prompted for interactively by
+ <productname>OpenSSL</productname> with a
+ <literal>Enter PEM pass phrase:</literal> prompt if a TTY is available.
+ Applications can override the client certificate prompt and the handling
+ of the <literal>sslpassword</literal> parameter by supplying their own
+ key password callback; see
+ <xref linkend="libpq-pqsetsslkeypasshook-openssl"/>.
+ </para>
+
+ <para>
+ For instructions on creating certificates, see <xref
+ linkend="ssl-certificate-creation"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="libpq-ssl-protection">
+ <title>Protection Provided in Different Modes</title>
+
+ <para>
+ The different values for the <literal>sslmode</literal> parameter provide different
+ levels of protection. SSL can provide
+ protection against three types of attacks:
+
+ <variablelist>
+ <varlistentry>
+ <term>Eavesdropping</term>
+ <listitem>
+ <para>If a third party can examine the network traffic between the
+ client and the server, it can read both connection information (including
+ the user name and password) and the data that is passed. <acronym>SSL</acronym>
+ uses encryption to prevent this.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Man-in-the-middle (<acronym>MITM</acronym>)</term>
+ <listitem>
+ <para>If a third party can modify the data while passing between the
+ client and server, it can pretend to be the server and therefore see and
+ modify data <emphasis>even if it is encrypted</emphasis>. The third party can then
+ forward the connection information and data to the original server,
+ making it impossible to detect this attack. Common vectors to do this
+ include DNS poisoning and address hijacking, whereby the client is directed
+ to a different server than intended. There are also several other
+ attack methods that can accomplish this. <acronym>SSL</acronym> uses certificate
+ verification to prevent this, by authenticating the server to the client.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Impersonation</term>
+ <listitem>
+ <para>If a third party can pretend to be an authorized client, it can
+ simply access data it should not have access to. Typically this can
+ happen through insecure password management. <acronym>SSL</acronym> uses
+ client certificates to prevent this, by making sure that only holders
+ of valid certificates can access the server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ For a connection to be known SSL-secured, SSL usage must be configured
+ on <emphasis>both the client and the server</emphasis> before the connection
+ is made. If it is only configured on the server, the client may end up
+ sending sensitive information (e.g., passwords) before
+ it knows that the server requires high security. In libpq, secure
+ connections can be ensured
+ by setting the <literal>sslmode</literal> parameter to <literal>verify-full</literal> or
+ <literal>verify-ca</literal>, and providing the system with a root certificate to
+ verify against. This is analogous to using an <literal>https</literal>
+ <acronym>URL</acronym> for encrypted web browsing.
+ </para>
+
+ <para>
+ Once the server has been authenticated, the client can pass sensitive data.
+ This means that up until this point, the client does not need to know if
+ certificates will be used for authentication, making it safe to specify that
+ only in the server configuration.
+ </para>
+
+ <para>
+ All <acronym>SSL</acronym> options carry overhead in the form of encryption and
+ key-exchange, so there is a trade-off that has to be made between performance
+ and security. <xref linkend="libpq-ssl-sslmode-statements"/>
+ illustrates the risks the different <literal>sslmode</literal> values
+ protect against, and what statement they make about security and overhead.
+ </para>
+
+ <table id="libpq-ssl-sslmode-statements">
+ <title>SSL Mode Descriptions</title>
+ <tgroup cols="4">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry><literal>sslmode</literal></entry>
+ <entry>Eavesdropping protection</entry>
+ <entry><acronym>MITM</acronym> protection</entry>
+ <entry>Statement</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>disable</literal></entry>
+ <entry>No</entry>
+ <entry>No</entry>
+ <entry>I don't care about security, and I don't want to pay the overhead
+ of encryption.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>allow</literal></entry>
+ <entry>Maybe</entry>
+ <entry>No</entry>
+ <entry>I don't care about security, but I will pay the overhead of
+ encryption if the server insists on it.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>prefer</literal></entry>
+ <entry>Maybe</entry>
+ <entry>No</entry>
+ <entry>I don't care about encryption, but I wish to pay the overhead of
+ encryption if the server supports it.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>require</literal></entry>
+ <entry>Yes</entry>
+ <entry>No</entry>
+ <entry>I want my data to be encrypted, and I accept the overhead. I trust
+ that the network will make sure I always connect to the server I want.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>verify-ca</literal></entry>
+ <entry>Yes</entry>
+ <entry>Depends on CA policy</entry>
+ <entry>I want my data encrypted, and I accept the overhead. I want to be
+ sure that I connect to a server that I trust.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>verify-full</literal></entry>
+ <entry>Yes</entry>
+ <entry>Yes</entry>
+ <entry>I want my data encrypted, and I accept the overhead. I want to be
+ sure that I connect to a server I trust, and that it's the one I
+ specify.
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The difference between <literal>verify-ca</literal> and <literal>verify-full</literal>
+ depends on the policy of the root <acronym>CA</acronym>. If a public
+ <acronym>CA</acronym> is used, <literal>verify-ca</literal> allows connections to a server
+ that <emphasis>somebody else</emphasis> may have registered with the <acronym>CA</acronym>.
+ In this case, <literal>verify-full</literal> should always be used. If
+ a local <acronym>CA</acronym> is used, or even a self-signed certificate, using
+ <literal>verify-ca</literal> often provides enough protection.
+ </para>
+
+ <para>
+ The default value for <literal>sslmode</literal> is <literal>prefer</literal>. As is shown
+ in the table, this makes no sense from a security point of view, and it only
+ promises performance overhead if possible. It is only provided as the default
+ for backward compatibility, and is not recommended in secure deployments.
+ </para>
+
+ </sect2>
+
+ <sect2 id="libpq-ssl-fileusage">
+ <title>SSL Client File Usage</title>
+
+ <para>
+ <xref linkend="libpq-ssl-file-usage"/> summarizes the files that are
+ relevant to the SSL setup on the client.
+ </para>
+
+ <table id="libpq-ssl-file-usage">
+ <title>Libpq/Client SSL File Usage</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>File</entry>
+ <entry>Contents</entry>
+ <entry>Effect</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><filename>~/.postgresql/postgresql.crt</filename></entry>
+ <entry>client certificate</entry>
+ <entry>sent to server</entry>
+ </row>
+
+ <row>
+ <entry><filename>~/.postgresql/postgresql.key</filename></entry>
+ <entry>client private key</entry>
+ <entry>proves client certificate sent by owner; does not indicate
+ certificate owner is trustworthy</entry>
+ </row>
+
+ <row>
+ <entry><filename>~/.postgresql/root.crt</filename></entry>
+ <entry>trusted certificate authorities</entry>
+ <entry>checks that server certificate is signed by a trusted certificate
+ authority</entry>
+ </row>
+
+ <row>
+ <entry><filename>~/.postgresql/root.crl</filename></entry>
+ <entry>certificates revoked by certificate authorities</entry>
+ <entry>server certificate must not be on this list</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="libpq-ssl-initialize">
+ <title>SSL Library Initialization</title>
+
+ <para>
+ If your application initializes <literal>libssl</literal> and/or
+ <literal>libcrypto</literal> libraries and <application>libpq</application>
+ is built with <acronym>SSL</acronym> support, you should call
+ <xref linkend="libpq-PQinitOpenSSL"/> to tell <application>libpq</application>
+ that the <literal>libssl</literal> and/or <literal>libcrypto</literal> libraries
+ have been initialized by your application, so that
+ <application>libpq</application> will not also initialize those libraries.
+ However, this is unnecessary when using <productname>OpenSSL</productname>
+ version 1.1.0 or later, as duplicate initializations are no longer problematic.
+ </para>
+
+ <para>
+ <variablelist>
+ <varlistentry id="libpq-PQinitOpenSSL">
+ <term><function>PQinitOpenSSL</function><indexterm><primary>PQinitOpenSSL</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Allows applications to select which security libraries to initialize.
+<synopsis>
+void PQinitOpenSSL(int do_ssl, int do_crypto);
+</synopsis>
+ </para>
+
+ <para>
+ When <parameter>do_ssl</parameter> is non-zero, <application>libpq</application>
+ will initialize the <productname>OpenSSL</productname> library before first
+ opening a database connection. When <parameter>do_crypto</parameter> is
+ non-zero, the <literal>libcrypto</literal> library will be initialized. By
+ default (if <xref linkend="libpq-PQinitOpenSSL"/> is not called), both libraries
+ are initialized. When SSL support is not compiled in, this function is
+ present but does nothing.
+ </para>
+
+ <para>
+ If your application uses and initializes either <productname>OpenSSL</productname>
+ or its underlying <literal>libcrypto</literal> library, you <emphasis>must</emphasis>
+ call this function with zeroes for the appropriate parameter(s)
+ before first opening a database connection. Also be sure that you
+ have done that initialization before opening a database connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="libpq-PQinitSSL">
+ <term><function>PQinitSSL</function><indexterm><primary>PQinitSSL</primary></indexterm></term><listitem>
+ <para>
+ Allows applications to select which security libraries to initialize.
+<synopsis>
+void PQinitSSL(int do_ssl);
+</synopsis>
+ </para>
+
+ <para>
+ This function is equivalent to
+ <literal>PQinitOpenSSL(do_ssl, do_ssl)</literal>.
+ It is sufficient for applications that initialize both or neither
+ of <productname>OpenSSL</productname> and <literal>libcrypto</literal>.
+ </para>
+
+ <para>
+ <xref linkend="libpq-PQinitSSL"/> has been present since
+ <productname>PostgreSQL</productname> 8.0, while <xref linkend="libpq-PQinitOpenSSL"/>
+ was added in <productname>PostgreSQL</productname> 8.4, so <xref linkend="libpq-PQinitSSL"/>
+ might be preferable for applications that need to work with older
+ versions of <application>libpq</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="libpq-threading">
+ <title>Behavior in Threaded Programs</title>
+
+ <indexterm zone="libpq-threading">
+ <primary>threads</primary>
+ <secondary>with libpq</secondary>
+ </indexterm>
+
+ <para>
+ <application>libpq</application> is reentrant and thread-safe by default.
+ You might need to use special compiler command-line
+ options when you compile your application code. Refer to your
+ system's documentation for information about how to build
+ thread-enabled applications, or look in
+ <filename>src/Makefile.global</filename> for <literal>PTHREAD_CFLAGS</literal>
+ and <literal>PTHREAD_LIBS</literal>. This function allows the querying of
+ <application>libpq</application>'s thread-safe status:
+ </para>
+
+ <variablelist>
+ <varlistentry id="libpq-PQisthreadsafe">
+ <term><function>PQisthreadsafe</function><indexterm><primary>PQisthreadsafe</primary></indexterm></term>
+
+ <listitem>
+ <para>
+ Returns the thread safety status of the
+ <application>libpq</application> library.
+<synopsis>
+int PQisthreadsafe();
+</synopsis>
+ </para>
+
+ <para>
+ Returns 1 if the <application>libpq</application> is thread-safe
+ and 0 if it is not.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ One thread restriction is that no two threads attempt to manipulate
+ the same <structname>PGconn</structname> object at the same time. In particular,
+ you cannot issue concurrent commands from different threads through
+ the same connection object. (If you need to run concurrent commands,
+ use multiple connections.)
+ </para>
+
+ <para>
+ <structname>PGresult</structname> objects are normally read-only after creation,
+ and so can be passed around freely between threads. However, if you use
+ any of the <structname>PGresult</structname>-modifying functions described in
+ <xref linkend="libpq-misc"/> or <xref linkend="libpq-events"/>, it's up
+ to you to avoid concurrent operations on the same <structname>PGresult</structname>,
+ too.
+ </para>
+
+ <para>
+ The deprecated functions <xref linkend="libpq-PQrequestCancel"/> and
+ <xref linkend="libpq-PQoidStatus"/> are not thread-safe and should not be
+ used in multithread programs. <xref linkend="libpq-PQrequestCancel"/>
+ can be replaced by <xref linkend="libpq-PQcancel"/>.
+ <xref linkend="libpq-PQoidStatus"/> can be replaced by
+ <xref linkend="libpq-PQoidValue"/>.
+ </para>
+
+ <para>
+ If you are using Kerberos inside your application (in addition to inside
+ <application>libpq</application>), you will need to do locking around
+ Kerberos calls because Kerberos functions are not thread-safe. See
+ function <function>PQregisterThreadLock</function> in the
+ <application>libpq</application> source code for a way to do cooperative
+ locking between <application>libpq</application> and your application.
+ </para>
+ </sect1>
+
+
+ <sect1 id="libpq-build">
+ <title>Building <application>libpq</application> Programs</title>
+
+ <indexterm zone="libpq-build">
+ <primary>compiling</primary>
+ <secondary>libpq applications</secondary>
+ </indexterm>
+
+ <para>
+ To build (i.e., compile and link) a program using
+ <application>libpq</application> you need to do all of the following
+ things:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Include the <filename>libpq-fe.h</filename> header file:
+<programlisting>
+#include &lt;libpq-fe.h&gt;
+</programlisting>
+ If you failed to do that then you will normally get error messages
+ from your compiler similar to:
+<screen>
+foo.c: In function `main':
+foo.c:34: `PGconn' undeclared (first use in this function)
+foo.c:35: `PGresult' undeclared (first use in this function)
+foo.c:54: `CONNECTION_BAD' undeclared (first use in this function)
+foo.c:68: `PGRES_COMMAND_OK' undeclared (first use in this function)
+foo.c:95: `PGRES_TUPLES_OK' undeclared (first use in this function)
+</screen>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Point your compiler to the directory where the <productname>PostgreSQL</productname> header
+ files were installed, by supplying the
+ <literal>-I<replaceable>directory</replaceable></literal> option
+ to your compiler. (In some cases the compiler will look into
+ the directory in question by default, so you can omit this
+ option.) For instance, your compile command line could look
+ like:
+<programlisting>
+cc -c -I/usr/local/pgsql/include testprog.c
+</programlisting>
+ If you are using makefiles then add the option to the
+ <varname>CPPFLAGS</varname> variable:
+<programlisting>
+CPPFLAGS += -I/usr/local/pgsql/include
+</programlisting>
+ </para>
+
+ <para>
+ If there is any chance that your program might be compiled by
+ other users then you should not hardcode the directory location
+ like that. Instead, you can run the utility
+ <command>pg_config</command><indexterm><primary>pg_config</primary><secondary
+ sortas="libpq">with libpq</secondary></indexterm> to find out where the header
+ files are on the local system:
+<screen>
+<prompt>$</prompt> pg_config --includedir
+<computeroutput>/usr/local/include</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ If you
+ have <command>pkg-config</command><indexterm><primary>pkg-config</primary><secondary sortas="libpq">with
+ libpq</secondary></indexterm> installed, you can run instead:
+<screen>
+<prompt>$</prompt> pkg-config --cflags libpq
+<computeroutput>-I/usr/local/include</computeroutput>
+</screen>
+ Note that this will already include the <option>-I</option> in front of
+ the path.
+ </para>
+
+ <para>
+ Failure to specify the correct option to the compiler will
+ result in an error message such as:
+<screen>
+testlibpq.c:8:22: libpq-fe.h: No such file or directory
+</screen>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When linking the final program, specify the option
+ <literal>-lpq</literal> so that the <application>libpq</application>
+ library gets pulled in, as well as the option
+ <literal>-L<replaceable>directory</replaceable></literal> to point
+ the compiler to the directory where the
+ <application>libpq</application> library resides. (Again, the
+ compiler will search some directories by default.) For maximum
+ portability, put the <option>-L</option> option before the
+ <option>-lpq</option> option. For example:
+<programlisting>
+cc -o testprog testprog1.o testprog2.o -L/usr/local/pgsql/lib -lpq
+</programlisting>
+ </para>
+
+ <para>
+ You can find out the library directory using
+ <command>pg_config</command> as well:
+<screen>
+<prompt>$</prompt> pg_config --libdir
+<computeroutput>/usr/local/pgsql/lib</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ Or again use <command>pkg-config</command>:
+<screen>
+<prompt>$</prompt> pkg-config --libs libpq
+<computeroutput>-L/usr/local/pgsql/lib -lpq</computeroutput>
+</screen>
+ Note again that this prints the full options, not only the path.
+ </para>
+
+ <para>
+ Error messages that point to problems in this area could look like
+ the following:
+<screen>
+testlibpq.o: In function `main':
+testlibpq.o(.text+0x60): undefined reference to `PQsetdbLogin'
+testlibpq.o(.text+0x71): undefined reference to `PQstatus'
+testlibpq.o(.text+0xa4): undefined reference to `PQerrorMessage'
+</screen>
+ This means you forgot <option>-lpq</option>.
+<screen>
+/usr/bin/ld: cannot find -lpq
+</screen>
+ This means you forgot the <option>-L</option> option or did not
+ specify the right directory.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="libpq-example">
+ <title>Example Programs</title>
+
+ <para>
+ These examples and others can be found in the
+ directory <filename>src/test/examples</filename> in the source code
+ distribution.
+ </para>
+
+ <example id="libpq-example-1">
+ <title><application>libpq</application> Example Program 1</title>
+
+<programlisting>
+<![CDATA[
+/*
+ * src/test/examples/testlibpq.c
+ *
+ *
+ * testlibpq.c
+ *
+ * Test the C version of libpq, the PostgreSQL frontend library.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "libpq-fe.h"
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *conninfo;
+ PGconn *conn;
+ PGresult *res;
+ int nFields;
+ int i,
+ j;
+
+ /*
+ * If the user supplies a parameter on the command line, use it as the
+ * conninfo string; otherwise default to setting dbname=postgres and using
+ * environment variables or defaults for all other connection parameters.
+ */
+ if (argc > 1)
+ conninfo = argv[1];
+ else
+ conninfo = "dbname = postgres";
+
+ /* Make a connection to the database */
+ conn = PQconnectdb(conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn,
+ "SELECT pg_catalog.set_config('search_path', '', false)");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * Should PQclear PGresult whenever it is no longer needed to avoid memory
+ * leaks
+ */
+ PQclear(res);
+
+ /*
+ * Our test case here involves using a cursor, for which we must be inside
+ * a transaction block. We could do the whole thing with a single
+ * PQexec() of "select * from pg_database", but that's too trivial to make
+ * a good example.
+ */
+
+ /* Start a transaction block */
+ res = PQexec(conn, "BEGIN");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ /*
+ * Fetch rows from pg_database, the system catalog of databases
+ */
+ res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ res = PQexec(conn, "FETCH ALL in myportal");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /* first, print out the attribute names */
+ nFields = PQnfields(res);
+ for (i = 0; i < nFields; i++)
+ printf("%-15s", PQfname(res, i));
+ printf("\n\n");
+
+ /* next, print out the rows */
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ for (j = 0; j < nFields; j++)
+ printf("%-15s", PQgetvalue(res, i, j));
+ printf("\n");
+ }
+
+ PQclear(res);
+
+ /* close the portal ... we don't bother to check for errors ... */
+ res = PQexec(conn, "CLOSE myportal");
+ PQclear(res);
+
+ /* end the transaction */
+ res = PQexec(conn, "END");
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+ return 0;
+}
+]]>
+</programlisting>
+ </example>
+
+ <example id="libpq-example-2">
+ <title><application>libpq</application> Example Program 2</title>
+
+<programlisting>
+<![CDATA[
+/*
+ * src/test/examples/testlibpq2.c
+ *
+ *
+ * testlibpq2.c
+ * Test of the asynchronous notification interface
+ *
+ * Start this program, then from psql in another window do
+ * NOTIFY TBL2;
+ * Repeat four times to get this program to exit.
+ *
+ * Or, if you want to get fancy, try this:
+ * populate a database with the following commands
+ * (provided in src/test/examples/testlibpq2.sql):
+ *
+ * CREATE SCHEMA TESTLIBPQ2;
+ * SET search_path = TESTLIBPQ2;
+ * CREATE TABLE TBL1 (i int4);
+ * CREATE TABLE TBL2 (i int4);
+ * CREATE RULE r1 AS ON INSERT TO TBL1 DO
+ * (INSERT INTO TBL2 VALUES (new.i); NOTIFY TBL2);
+ *
+ * Start this program, then from psql do this four times:
+ *
+ * INSERT INTO TESTLIBPQ2.TBL1 VALUES (10);
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "libpq-fe.h"
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *conninfo;
+ PGconn *conn;
+ PGresult *res;
+ PGnotify *notify;
+ int nnotifies;
+
+ /*
+ * If the user supplies a parameter on the command line, use it as the
+ * conninfo string; otherwise default to setting dbname=postgres and using
+ * environment variables or defaults for all other connection parameters.
+ */
+ if (argc > 1)
+ conninfo = argv[1];
+ else
+ conninfo = "dbname = postgres";
+
+ /* Make a connection to the database */
+ conn = PQconnectdb(conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn,
+ "SELECT pg_catalog.set_config('search_path', '', false)");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ /*
+ * Should PQclear PGresult whenever it is no longer needed to avoid memory
+ * leaks
+ */
+ PQclear(res);
+
+ /*
+ * Issue LISTEN command to enable notifications from the rule's NOTIFY.
+ */
+ res = PQexec(conn, "LISTEN TBL2");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "LISTEN command failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ /* Quit after four notifies are received. */
+ nnotifies = 0;
+ while (nnotifies < 4)
+ {
+ /*
+ * Sleep until something happens on the connection. We use select(2)
+ * to wait for input, but you could also use poll() or similar
+ * facilities.
+ */
+ int sock;
+ fd_set input_mask;
+
+ sock = PQsocket(conn);
+
+ if (sock < 0)
+ break; /* shouldn't happen */
+
+ FD_ZERO(&input_mask);
+ FD_SET(sock, &input_mask);
+
+ if (select(sock + 1, &input_mask, NULL, NULL, NULL) < 0)
+ {
+ fprintf(stderr, "select() failed: %s\n", strerror(errno));
+ exit_nicely(conn);
+ }
+
+ /* Now check for input */
+ PQconsumeInput(conn);
+ while ((notify = PQnotifies(conn)) != NULL)
+ {
+ fprintf(stderr,
+ "ASYNC NOTIFY of '%s' received from backend PID %d\n",
+ notify->relname, notify->be_pid);
+ PQfreemem(notify);
+ nnotifies++;
+ PQconsumeInput(conn);
+ }
+ }
+
+ fprintf(stderr, "Done.\n");
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+ return 0;
+}
+]]>
+</programlisting>
+ </example>
+
+ <example id="libpq-example-3">
+ <title><application>libpq</application> Example Program 3</title>
+
+<programlisting>
+<![CDATA[
+/*
+ * src/test/examples/testlibpq3.c
+ *
+ *
+ * testlibpq3.c
+ * Test out-of-line parameters and binary I/O.
+ *
+ * Before running this, populate a database with the following commands
+ * (provided in src/test/examples/testlibpq3.sql):
+ *
+ * CREATE SCHEMA testlibpq3;
+ * SET search_path = testlibpq3;
+ * SET standard_conforming_strings = ON;
+ * CREATE TABLE test1 (i int4, t text, b bytea);
+ * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004');
+ * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000');
+ *
+ * The expected output is:
+ *
+ * tuple 0: got
+ * i = (4 bytes) 1
+ * t = (11 bytes) 'joe's place'
+ * b = (5 bytes) \000\001\002\003\004
+ *
+ * tuple 0: got
+ * i = (4 bytes) 2
+ * t = (8 bytes) 'ho there'
+ * b = (5 bytes) \004\003\002\001\000
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include "libpq-fe.h"
+
+/* for ntohl/htonl */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+/*
+ * This function prints a query result that is a binary-format fetch from
+ * a table defined as in the comment above. We split it out because the
+ * main() function uses it twice.
+ */
+static void
+show_binary_results(PGresult *res)
+{
+ int i,
+ j;
+ int i_fnum,
+ t_fnum,
+ b_fnum;
+
+ /* Use PQfnumber to avoid assumptions about field order in result */
+ i_fnum = PQfnumber(res, "i");
+ t_fnum = PQfnumber(res, "t");
+ b_fnum = PQfnumber(res, "b");
+
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ char *iptr;
+ char *tptr;
+ char *bptr;
+ int blen;
+ int ival;
+
+ /* Get the field values (we ignore possibility they are null!) */
+ iptr = PQgetvalue(res, i, i_fnum);
+ tptr = PQgetvalue(res, i, t_fnum);
+ bptr = PQgetvalue(res, i, b_fnum);
+
+ /*
+ * The binary representation of INT4 is in network byte order, which
+ * we'd better coerce to the local byte order.
+ */
+ ival = ntohl(*((uint32_t *) iptr));
+
+ /*
+ * The binary representation of TEXT is, well, text, and since libpq
+ * was nice enough to append a zero byte to it, it'll work just fine
+ * as a C string.
+ *
+ * The binary representation of BYTEA is a bunch of bytes, which could
+ * include embedded nulls so we have to pay attention to field length.
+ */
+ blen = PQgetlength(res, i, b_fnum);
+
+ printf("tuple %d: got\n", i);
+ printf(" i = (%d bytes) %d\n",
+ PQgetlength(res, i, i_fnum), ival);
+ printf(" t = (%d bytes) '%s'\n",
+ PQgetlength(res, i, t_fnum), tptr);
+ printf(" b = (%d bytes) ", blen);
+ for (j = 0; j < blen; j++)
+ printf("\\%03o", bptr[j]);
+ printf("\n\n");
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *conninfo;
+ PGconn *conn;
+ PGresult *res;
+ const char *paramValues[1];
+ int paramLengths[1];
+ int paramFormats[1];
+ uint32_t binaryIntVal;
+
+ /*
+ * If the user supplies a parameter on the command line, use it as the
+ * conninfo string; otherwise default to setting dbname=postgres and using
+ * environment variables or defaults for all other connection parameters.
+ */
+ if (argc > 1)
+ conninfo = argv[1];
+ else
+ conninfo = "dbname = postgres";
+
+ /* Make a connection to the database */
+ conn = PQconnectdb(conninfo);
+
+ /* Check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn, "SET search_path = testlibpq3");
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ /*
+ * The point of this program is to illustrate use of PQexecParams() with
+ * out-of-line parameters, as well as binary transmission of data.
+ *
+ * This first example transmits the parameters as text, but receives the
+ * results in binary format. By using out-of-line parameters we can avoid
+ * a lot of tedious mucking about with quoting and escaping, even though
+ * the data is text. Notice how we don't have to do anything special with
+ * the quote mark in the parameter value.
+ */
+
+ /* Here is our out-of-line parameter value */
+ paramValues[0] = "joe's place";
+
+ res = PQexecParams(conn,
+ "SELECT * FROM test1 WHERE t = $1",
+ 1, /* one param */
+ NULL, /* let the backend deduce param type */
+ paramValues,
+ NULL, /* don't need param lengths since text */
+ NULL, /* default to all text params */
+ 1); /* ask for binary results */
+
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ show_binary_results(res);
+
+ PQclear(res);
+
+ /*
+ * In this second example we transmit an integer parameter in binary form,
+ * and again retrieve the results in binary form.
+ *
+ * Although we tell PQexecParams we are letting the backend deduce
+ * parameter type, we really force the decision by casting the parameter
+ * symbol in the query text. This is a good safety measure when sending
+ * binary parameters.
+ */
+
+ /* Convert integer value "2" to network byte order */
+ binaryIntVal = htonl((uint32_t) 2);
+
+ /* Set up parameter arrays for PQexecParams */
+ paramValues[0] = (char *) &binaryIntVal;
+ paramLengths[0] = sizeof(binaryIntVal);
+ paramFormats[0] = 1; /* binary */
+
+ res = PQexecParams(conn,
+ "SELECT * FROM test1 WHERE i = $1::int4",
+ 1, /* one param */
+ NULL, /* let the backend deduce param type */
+ paramValues,
+ paramLengths,
+ paramFormats,
+ 1); /* ask for binary results */
+
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SELECT failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+
+ show_binary_results(res);
+
+ PQclear(res);
+
+ /* close the connection to the database and cleanup */
+ PQfinish(conn);
+
+ return 0;
+}
+]]>
+</programlisting>
+ </example>
+
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/limits.sgml b/doc/src/sgml/limits.sgml
new file mode 100644
index 0000000..d5b2b62
--- /dev/null
+++ b/doc/src/sgml/limits.sgml
@@ -0,0 +1,126 @@
+<!-- doc/src/sgml/limits.sgml -->
+
+<appendix id="limits">
+ <title><productname>PostgreSQL</productname> Limits</title>
+
+ <para>
+ <xref linkend="limits-table"/> describes various hard limits of
+ <productname>PostgreSQL</productname>. However, practical limits, such as
+ performance limitations or available disk space may apply before absolute
+ hard limits are reached.
+ </para>
+
+ <table id="limits-table">
+ <title><productname>PostgreSQL</productname> Limitations</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Item</entry>
+ <entry>Upper Limit</entry>
+ <entry>Comment</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>database size</entry>
+ <entry>unlimited</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>number of databases</entry>
+ <!-- 2^32 - FirstNormalObjectId - 1 -->
+ <entry>4,294,950,911</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>relations per database</entry>
+ <!-- (2^32 - FirstNormalObjectId - 1) / 3 (3 because of the table and the
+ two types that are created to go with it) -->
+ <entry>1,431,650,303</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>relation size</entry>
+ <entry>32 TB</entry>
+ <entry>with the default <symbol>BLCKSZ</symbol> of 8192 bytes</entry>
+ </row>
+
+ <row>
+ <entry>rows per table</entry>
+ <entry>limited by the number of tuples that can fit onto 4,294,967,295 pages</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>columns per table</entry>
+ <entry>1600</entry>
+ <entry>further limited by tuple size fitting on a single page; see note
+ below</entry>
+ </row>
+
+ <row>
+ <entry>columns in a result set</entry>
+ <entry>1664</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>field size</entry>
+ <entry>1 GB</entry>
+ <entry></entry>
+ </row>
+
+ <row>
+ <entry>identifier length</entry>
+ <entry>63 bytes</entry>
+ <entry>can be increased by recompiling <productname>PostgreSQL</productname></entry>
+ </row>
+
+ <row>
+ <entry>indexes per table</entry>
+ <entry>unlimited</entry>
+ <entry>constrained by maximum relations per database</entry>
+ </row>
+
+ <row>
+ <entry>columns per index</entry>
+ <entry>32</entry>
+ <entry>can be increased by recompiling <productname>PostgreSQL</productname></entry>
+ </row>
+
+ <row>
+ <entry>partition keys</entry>
+ <entry>32</entry>
+ <entry>can be increased by recompiling <productname>PostgreSQL</productname></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The maximum number of columns for a table is further reduced as the tuple
+ being stored must fit in a single 8192-byte heap page. For example,
+ excluding the tuple header, a tuple made up of 1600 <type>int</type> columns
+ would consume 6400 bytes and could be stored in a heap page, but a tuple of
+ 1600 <type>bigint</type> columns would consume 12800 bytes and would
+ therefore not fit inside a heap page.
+ Variable-length fields of
+ types such as <type>text</type>, <type>varchar</type>, and <type>char</type>
+ can have their values stored out of line in the table's TOAST table when the
+ values are large enough to require it. Only an 18-byte pointer must remain
+ inside the tuple in the table's heap. For shorter length variable-length
+ fields, either a 4-byte or 1-byte field header is used and the value is
+ stored inside the heap tuple.
+ </para>
+
+ <para>
+ Columns that have been dropped from the table also contribute to the maximum
+ column limit. Moreover, although the dropped column values for newly
+ created tuples are internally marked as null in the tuple's null bitmap, the
+ null bitmap also occupies space.
+ </para>
+</appendix>
diff --git a/doc/src/sgml/lo.sgml b/doc/src/sgml/lo.sgml
new file mode 100644
index 0000000..f46cd39
--- /dev/null
+++ b/doc/src/sgml/lo.sgml
@@ -0,0 +1,136 @@
+<!-- doc/src/sgml/lo.sgml -->
+
+<sect1 id="lo" xreflabel="lo">
+ <title>lo</title>
+
+ <indexterm zone="lo">
+ <primary>lo</primary>
+ </indexterm>
+
+ <para>
+ The <filename>lo</filename> module provides support for managing Large Objects
+ (also called LOs or BLOBs). This includes a data type <type>lo</type>
+ and a trigger <function>lo_manage</function>.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Rationale</title>
+
+ <para>
+ One of the problems with the JDBC driver (and this affects the ODBC driver
+ also), is that the specification assumes that references to BLOBs (Binary
+ Large OBjects) are stored within a table, and if that entry is changed, the
+ associated BLOB is deleted from the database.
+ </para>
+
+ <para>
+ As <productname>PostgreSQL</productname> stands, this doesn't occur. Large objects
+ are treated as objects in their own right; a table entry can reference a
+ large object by OID, but there can be multiple table entries referencing
+ the same large object OID, so the system doesn't delete the large object
+ just because you change or remove one such entry.
+ </para>
+
+ <para>
+ Now this is fine for <productname>PostgreSQL</productname>-specific applications, but
+ standard code using JDBC or ODBC won't delete the objects, resulting in
+ orphan objects &mdash; objects that are not referenced by anything, and
+ simply occupy disk space.
+ </para>
+
+ <para>
+ The <filename>lo</filename> module allows fixing this by attaching a trigger
+ to tables that contain LO reference columns. The trigger essentially just
+ does a <function>lo_unlink</function> whenever you delete or modify a value
+ referencing a large object. When you use this trigger, you are assuming
+ that there is only one database reference to any large object that is
+ referenced in a trigger-controlled column!
+ </para>
+
+ <para>
+ The module also provides a data type <type>lo</type>, which is really just
+ a <glossterm linkend="glossary-domain">domain</glossterm> over
+ the <type>oid</type> type. This is useful for differentiating
+ database columns that hold large object references from those that are
+ OIDs of other things. You don't have to use the <type>lo</type> type to
+ use the trigger, but it may be convenient to use it to keep track of which
+ columns in your database represent large objects that you are managing with
+ the trigger. It is also rumored that the ODBC driver gets confused if you
+ don't use <type>lo</type> for BLOB columns.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>How to Use It</title>
+
+ <para>
+ Here's a simple example of usage:
+ </para>
+
+<programlisting>
+CREATE TABLE image (title text, raster lo);
+
+CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image
+ FOR EACH ROW EXECUTE FUNCTION lo_manage(raster);
+</programlisting>
+
+ <para>
+ For each column that will contain unique references to large objects,
+ create a <literal>BEFORE UPDATE OR DELETE</literal> trigger, and give the column
+ name as the sole trigger argument. You can also restrict the trigger
+ to only execute on updates to the column by using <literal>BEFORE UPDATE
+ OF</literal> <replaceable class="parameter">column_name</replaceable>.
+ If you need multiple <type>lo</type>
+ columns in the same table, create a separate trigger for each one,
+ remembering to give a different name to each trigger on the same table.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Limitations</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Dropping a table will still orphan any objects it contains, as the trigger
+ is not executed. You can avoid this by preceding the <command>DROP
+ TABLE</command> with <command>DELETE FROM <replaceable>table</replaceable></command>.
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> has the same hazard.
+ </para>
+
+ <para>
+ If you already have, or suspect you have, orphaned large objects, see the
+ <xref linkend="vacuumlo"/> module to help
+ you clean them up. It's a good idea to run <application>vacuumlo</application>
+ occasionally as a back-stop to the <function>lo_manage</function> trigger.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Some frontends may create their own tables, and will not create the
+ associated trigger(s). Also, users may not remember (or know) to create
+ the triggers.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Peter Mount <email>peter@retep.org.uk</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/lobj.sgml b/doc/src/sgml/lobj.sgml
new file mode 100644
index 0000000..b767ba1
--- /dev/null
+++ b/doc/src/sgml/lobj.sgml
@@ -0,0 +1,996 @@
+<!-- doc/src/sgml/lobj.sgml -->
+
+ <chapter id="largeobjects">
+ <title>Large Objects</title>
+
+ <indexterm zone="largeobjects"><primary>large object</primary></indexterm>
+ <indexterm><primary>BLOB</primary><see>large object</see></indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> has a <firstterm>large object</firstterm>
+ facility, which provides stream-style access to user data that is stored
+ in a special large-object structure. Streaming access is useful
+ when working with data values that are too large to manipulate
+ conveniently as a whole.
+ </para>
+
+ <para>
+ This chapter describes the implementation and the programming and
+ query language interfaces to <productname>PostgreSQL</productname>
+ large object data. We use the <application>libpq</application> C
+ library for the examples in this chapter, but most programming
+ interfaces native to <productname>PostgreSQL</productname> support
+ equivalent functionality. Other interfaces might use the large
+ object interface internally to provide generic support for large
+ values. This is not described here.
+ </para>
+
+ <sect1 id="lo-intro">
+ <title>Introduction</title>
+
+ <indexterm>
+ <primary>TOAST</primary>
+ <secondary>versus large objects</secondary>
+ </indexterm>
+
+ <para>
+ All large objects are stored in a single system table named <link
+ linkend="catalog-pg-largeobject"><structname>pg_largeobject</structname></link>.
+ Each large object also has an entry in the system table <link
+ linkend="catalog-pg-largeobject-metadata"><structname>pg_largeobject_metadata</structname></link>.
+ Large objects can be created, modified, and deleted using a read/write API
+ that is similar to standard operations on files.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> also supports a storage system called
+ <link
+ linkend="storage-toast"><quote><acronym>TOAST</acronym></quote></link>,
+ which automatically stores values
+ larger than a single database page into a secondary storage area per table.
+ This makes the large object facility partially obsolete. One
+ remaining advantage of the large object facility is that it allows values
+ up to 4 TB in size, whereas <acronym>TOAST</acronym>ed fields can be at
+ most 1 GB. Also, reading and updating portions of a large object can be
+ done efficiently, while most operations on a <acronym>TOAST</acronym>ed
+ field will read or write the whole value as a unit.
+ </para>
+
+ </sect1>
+
+ <sect1 id="lo-implementation">
+ <title>Implementation Features</title>
+
+ <para>
+ The large object implementation breaks large
+ objects up into <quote>chunks</quote> and stores the chunks in
+ rows in the database. A B-tree index guarantees fast
+ searches for the correct chunk number when doing random
+ access reads and writes.
+ </para>
+
+ <para>
+ The chunks stored for a large object do not have to be contiguous.
+ For example, if an application opens a new large object, seeks to offset
+ 1000000, and writes a few bytes there, this does not result in allocation
+ of 1000000 bytes worth of storage; only of chunks covering the range of
+ data bytes actually written. A read operation will, however, read out
+ zeroes for any unallocated locations preceding the last existing chunk.
+ This corresponds to the common behavior of <quote>sparsely allocated</quote>
+ files in <acronym>Unix</acronym> file systems.
+ </para>
+
+ <para>
+ As of <productname>PostgreSQL</productname> 9.0, large objects have an owner
+ and a set of access permissions, which can be managed using
+ <xref linkend="sql-grant"/> and
+ <xref linkend="sql-revoke"/>.
+ <literal>SELECT</literal> privileges are required to read a large
+ object, and
+ <literal>UPDATE</literal> privileges are required to write or
+ truncate it.
+ Only the large object's owner (or a database superuser) can delete,
+ comment on, or change the owner of a large object.
+ To adjust this behavior for compatibility with prior releases, see the
+ <xref linkend="guc-lo-compat-privileges"/> run-time parameter.
+ </para>
+ </sect1>
+
+ <sect1 id="lo-interfaces">
+ <title>Client Interfaces</title>
+
+ <para>
+ This section describes the facilities that
+ <productname>PostgreSQL</productname>'s <application>libpq</application>
+ client interface library provides for accessing large objects.
+ The <productname>PostgreSQL</productname> large object interface is
+ modeled after the <acronym>Unix</acronym> file-system interface, with
+ analogues of <function>open</function>, <function>read</function>,
+ <function>write</function>,
+ <function>lseek</function>, etc.
+ </para>
+
+ <para>
+ All large object manipulation using these functions
+ <emphasis>must</emphasis> take place within an SQL transaction block,
+ since large object file descriptors are only valid for the duration of
+ a transaction.
+ </para>
+
+ <para>
+ If an error occurs while executing any one of these functions, the
+ function will return an otherwise-impossible value, typically 0 or -1.
+ A message describing the error is stored in the connection object and
+ can be retrieved with <xref linkend="libpq-PQerrorMessage"/>.
+ </para>
+
+ <para>
+ Client applications that use these functions should include the header file
+ <filename>libpq/libpq-fs.h</filename> and link with the
+ <application>libpq</application> library.
+ </para>
+
+ <para>
+ Client applications cannot use these functions while a libpq connection is in pipeline mode.
+ </para>
+
+ <sect2 id="lo-create">
+ <title>Creating a Large Object</title>
+
+ <para>
+ <indexterm><primary>lo_create</primary></indexterm>
+ The function
+<synopsis>
+Oid lo_create(PGconn *conn, Oid lobjId);
+</synopsis>
+ creates a new large object. The OID to be assigned can be
+ specified by <replaceable class="parameter">lobjId</replaceable>;
+ if so, failure occurs if that OID is already in use for some large
+ object. If <replaceable class="parameter">lobjId</replaceable>
+ is <symbol>InvalidOid</symbol> (zero) then <function>lo_create</function>
+ assigns an unused OID.
+ The return value is the OID that was assigned to the new large object,
+ or <symbol>InvalidOid</symbol> (zero) on failure.
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+inv_oid = lo_create(conn, desired_oid);
+</programlisting>
+ </para>
+
+ <para>
+ <indexterm><primary>lo_creat</primary></indexterm>
+ The older function
+<synopsis>
+Oid lo_creat(PGconn *conn, int mode);
+</synopsis>
+ also creates a new large object, always assigning an unused OID.
+ The return value is the OID that was assigned to the new large object,
+ or <symbol>InvalidOid</symbol> (zero) on failure.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname> releases 8.1 and later,
+ the <replaceable class="parameter">mode</replaceable> is ignored,
+ so that <function>lo_creat</function> is exactly equivalent to
+ <function>lo_create</function> with a zero second argument.
+ However, there is little reason to use <function>lo_creat</function>
+ unless you need to work with servers older than 8.1.
+ To work with such an old server, you must
+ use <function>lo_creat</function> not <function>lo_create</function>,
+ and you must set <replaceable class="parameter">mode</replaceable> to
+ one of <symbol>INV_READ</symbol>, <symbol>INV_WRITE</symbol>,
+ or <symbol>INV_READ</symbol> <literal>|</literal> <symbol>INV_WRITE</symbol>.
+ (These symbolic constants are defined
+ in the header file <filename>libpq/libpq-fs.h</filename>.)
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+inv_oid = lo_creat(conn, INV_READ|INV_WRITE);
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="lo-import">
+ <title>Importing a Large Object</title>
+
+ <para>
+ <indexterm><primary>lo_import</primary></indexterm>
+ To import an operating system file as a large object, call
+<synopsis>
+Oid lo_import(PGconn *conn, const char *filename);
+</synopsis>
+ <replaceable class="parameter">filename</replaceable>
+ specifies the operating system name of
+ the file to be imported as a large object.
+ The return value is the OID that was assigned to the new large object,
+ or <symbol>InvalidOid</symbol> (zero) on failure.
+ Note that the file is read by the client interface library, not by
+ the server; so it must exist in the client file system and be readable
+ by the client application.
+ </para>
+
+ <para>
+ <indexterm><primary>lo_import_with_oid</primary></indexterm>
+ The function
+<synopsis>
+Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId);
+</synopsis>
+ also imports a new large object. The OID to be assigned can be
+ specified by <replaceable class="parameter">lobjId</replaceable>;
+ if so, failure occurs if that OID is already in use for some large
+ object. If <replaceable class="parameter">lobjId</replaceable>
+ is <symbol>InvalidOid</symbol> (zero) then <function>lo_import_with_oid</function> assigns an unused
+ OID (this is the same behavior as <function>lo_import</function>).
+ The return value is the OID that was assigned to the new large object,
+ or <symbol>InvalidOid</symbol> (zero) on failure.
+ </para>
+
+ <para>
+ <function>lo_import_with_oid</function> is new as of <productname>PostgreSQL</productname>
+ 8.4 and uses <function>lo_create</function> internally which is new in 8.1; if this function is run against 8.0 or before, it will
+ fail and return <symbol>InvalidOid</symbol>.
+ </para>
+ </sect2>
+
+ <sect2 id="lo-export">
+ <title>Exporting a Large Object</title>
+
+ <para>
+ <indexterm><primary>lo_export</primary></indexterm>
+ To export a large object
+ into an operating system file, call
+<synopsis>
+int lo_export(PGconn *conn, Oid lobjId, const char *filename);
+</synopsis>
+ The <parameter>lobjId</parameter> argument specifies the OID of the large
+ object to export and the <parameter>filename</parameter> argument
+ specifies the operating system name of the file. Note that the file is
+ written by the client interface library, not by the server. Returns 1
+ on success, -1 on failure.
+ </para>
+ </sect2>
+
+ <sect2 id="lo-open">
+ <title>Opening an Existing Large Object</title>
+
+ <para>
+ <indexterm><primary>lo_open</primary></indexterm>
+ To open an existing large object for reading or writing, call
+<synopsis>
+int lo_open(PGconn *conn, Oid lobjId, int mode);
+</synopsis>
+ The <parameter>lobjId</parameter> argument specifies the OID of the large
+ object to open. The <parameter>mode</parameter> bits control whether the
+ object is opened for reading (<symbol>INV_READ</symbol>), writing
+ (<symbol>INV_WRITE</symbol>), or both.
+ (These symbolic constants are defined
+ in the header file <filename>libpq/libpq-fs.h</filename>.)
+ <function>lo_open</function> returns a (non-negative) large object
+ descriptor for later use in <function>lo_read</function>,
+ <function>lo_write</function>, <function>lo_lseek</function>,
+ <function>lo_lseek64</function>, <function>lo_tell</function>,
+ <function>lo_tell64</function>, <function>lo_truncate</function>,
+ <function>lo_truncate64</function>, and <function>lo_close</function>.
+ The descriptor is only valid for
+ the duration of the current transaction.
+ On failure, -1 is returned.
+ </para>
+
+ <para>
+ The server currently does not distinguish between modes
+ <symbol>INV_WRITE</symbol> and <symbol>INV_READ</symbol> <literal>|</literal>
+ <symbol>INV_WRITE</symbol>: you are allowed to read from the descriptor
+ in either case. However there is a significant difference between
+ these modes and <symbol>INV_READ</symbol> alone: with <symbol>INV_READ</symbol>
+ you cannot write on the descriptor, and the data read from it will
+ reflect the contents of the large object at the time of the transaction
+ snapshot that was active when <function>lo_open</function> was executed,
+ regardless of later writes by this or other transactions. Reading
+ from a descriptor opened with <symbol>INV_WRITE</symbol> returns
+ data that reflects all writes of other committed transactions as well
+ as writes of the current transaction. This is similar to the behavior
+ of <literal>REPEATABLE READ</literal> versus <literal>READ COMMITTED</literal> transaction
+ modes for ordinary SQL <command>SELECT</command> commands.
+ </para>
+
+ <para>
+ <function>lo_open</function> will fail if <literal>SELECT</literal>
+ privilege is not available for the large object, or
+ if <symbol>INV_WRITE</symbol> is specified and <literal>UPDATE</literal>
+ privilege is not available.
+ (Prior to <productname>PostgreSQL</productname> 11, these privilege
+ checks were instead performed at the first actual read or write call
+ using the descriptor.)
+ These privilege checks can be disabled with the
+ <xref linkend="guc-lo-compat-privileges"/> run-time parameter.
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+inv_fd = lo_open(conn, inv_oid, INV_READ|INV_WRITE);
+</programlisting>
+ </para>
+</sect2>
+
+<sect2 id="lo-write">
+<title>Writing Data to a Large Object</title>
+
+<para>
+ <indexterm><primary>lo_write</primary></indexterm>
+ The function
+<synopsis>
+int lo_write(PGconn *conn, int fd, const char *buf, size_t len);
+</synopsis>
+ writes <parameter>len</parameter> bytes from <parameter>buf</parameter>
+ (which must be of size <parameter>len</parameter>) to large object
+ descriptor <parameter>fd</parameter>. The <parameter>fd</parameter> argument must
+ have been returned by a previous <function>lo_open</function>. The
+ number of bytes actually written is returned (in the current
+ implementation, this will always equal <parameter>len</parameter> unless
+ there is an error). In the event of an error, the return value is -1.
+</para>
+
+<para>
+ Although the <parameter>len</parameter> parameter is declared as
+ <type>size_t</type>, this function will reject length values larger than
+ <literal>INT_MAX</literal>. In practice, it's best to transfer data in chunks
+ of at most a few megabytes anyway.
+</para>
+</sect2>
+
+<sect2 id="lo-read">
+<title>Reading Data from a Large Object</title>
+
+<para>
+ <indexterm><primary>lo_read</primary></indexterm>
+ The function
+<synopsis>
+int lo_read(PGconn *conn, int fd, char *buf, size_t len);
+</synopsis>
+ reads up to <parameter>len</parameter> bytes from large object descriptor
+ <parameter>fd</parameter> into <parameter>buf</parameter> (which must be
+ of size <parameter>len</parameter>). The <parameter>fd</parameter>
+ argument must have been returned by a previous
+ <function>lo_open</function>. The number of bytes actually read is
+ returned; this will be less than <parameter>len</parameter> if the end of
+ the large object is reached first. In the event of an error, the return
+ value is -1.
+</para>
+
+<para>
+ Although the <parameter>len</parameter> parameter is declared as
+ <type>size_t</type>, this function will reject length values larger than
+ <literal>INT_MAX</literal>. In practice, it's best to transfer data in chunks
+ of at most a few megabytes anyway.
+</para>
+</sect2>
+
+<sect2 id="lo-seek">
+<title>Seeking in a Large Object</title>
+
+<para>
+ <indexterm><primary>lo_lseek</primary></indexterm>
+ To change the current read or write location associated with a
+ large object descriptor, call
+<synopsis>
+int lo_lseek(PGconn *conn, int fd, int offset, int whence);
+</synopsis>
+ This function moves the
+ current location pointer for the large object descriptor identified by
+ <parameter>fd</parameter> to the new location specified by
+ <parameter>offset</parameter>. The valid values for <parameter>whence</parameter>
+ are <symbol>SEEK_SET</symbol> (seek from object start),
+ <symbol>SEEK_CUR</symbol> (seek from current position), and
+ <symbol>SEEK_END</symbol> (seek from object end). The return value is
+ the new location pointer, or -1 on error.
+</para>
+
+<para>
+ <indexterm><primary>lo_lseek64</primary></indexterm>
+ When dealing with large objects that might exceed 2GB in size,
+ instead use
+<synopsis>
+pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence);
+</synopsis>
+ This function has the same behavior
+ as <function>lo_lseek</function>, but it can accept an
+ <parameter>offset</parameter> larger than 2GB and/or deliver a result larger
+ than 2GB.
+ Note that <function>lo_lseek</function> will fail if the new location
+ pointer would be greater than 2GB.
+</para>
+
+<para>
+ <function>lo_lseek64</function> is new as of <productname>PostgreSQL</productname>
+ 9.3. If this function is run against an older server version, it will
+ fail and return -1.
+</para>
+
+</sect2>
+
+<sect2 id="lo-tell">
+<title>Obtaining the Seek Position of a Large Object</title>
+
+<para>
+ <indexterm><primary>lo_tell</primary></indexterm>
+ To obtain the current read or write location of a large object descriptor,
+ call
+<synopsis>
+int lo_tell(PGconn *conn, int fd);
+</synopsis>
+ If there is an error, the return value is -1.
+</para>
+
+<para>
+ <indexterm><primary>lo_tell64</primary></indexterm>
+ When dealing with large objects that might exceed 2GB in size,
+ instead use
+<synopsis>
+pg_int64 lo_tell64(PGconn *conn, int fd);
+</synopsis>
+ This function has the same behavior
+ as <function>lo_tell</function>, but it can deliver a result larger
+ than 2GB.
+ Note that <function>lo_tell</function> will fail if the current
+ read/write location is greater than 2GB.
+</para>
+
+<para>
+ <function>lo_tell64</function> is new as of <productname>PostgreSQL</productname>
+ 9.3. If this function is run against an older server version, it will
+ fail and return -1.
+</para>
+</sect2>
+
+<sect2 id="lo-truncate">
+<title>Truncating a Large Object</title>
+
+<para>
+ <indexterm><primary>lo_truncate</primary></indexterm>
+ To truncate a large object to a given length, call
+<synopsis>
+int lo_truncate(PGconn *conn, int fd, size_t len);
+</synopsis>
+ This function truncates the large object
+ descriptor <parameter>fd</parameter> to length <parameter>len</parameter>. The
+ <parameter>fd</parameter> argument must have been returned by a
+ previous <function>lo_open</function>. If <parameter>len</parameter> is
+ greater than the large object's current length, the large object
+ is extended to the specified length with null bytes ('\0').
+ On success, <function>lo_truncate</function> returns
+ zero. On error, the return value is -1.
+</para>
+
+<para>
+ The read/write location associated with the descriptor
+ <parameter>fd</parameter> is not changed.
+</para>
+
+<para>
+ Although the <parameter>len</parameter> parameter is declared as
+ <type>size_t</type>, <function>lo_truncate</function> will reject length
+ values larger than <literal>INT_MAX</literal>.
+</para>
+
+<para>
+ <indexterm><primary>lo_truncate64</primary></indexterm>
+ When dealing with large objects that might exceed 2GB in size,
+ instead use
+<synopsis>
+int lo_truncate64(PGconn *conn, int fd, pg_int64 len);
+</synopsis>
+ This function has the same
+ behavior as <function>lo_truncate</function>, but it can accept a
+ <parameter>len</parameter> value exceeding 2GB.
+</para>
+
+<para>
+ <function>lo_truncate</function> is new as of <productname>PostgreSQL</productname>
+ 8.3; if this function is run against an older server version, it will
+ fail and return -1.
+</para>
+
+<para>
+ <function>lo_truncate64</function> is new as of <productname>PostgreSQL</productname>
+ 9.3; if this function is run against an older server version, it will
+ fail and return -1.
+</para>
+</sect2>
+
+<sect2 id="lo-close">
+<title>Closing a Large Object Descriptor</title>
+
+<para>
+ <indexterm><primary>lo_close</primary></indexterm>
+ A large object descriptor can be closed by calling
+<synopsis>
+int lo_close(PGconn *conn, int fd);
+</synopsis>
+ where <parameter>fd</parameter> is a
+ large object descriptor returned by <function>lo_open</function>.
+ On success, <function>lo_close</function> returns zero. On
+ error, the return value is -1.
+</para>
+
+<para>
+ Any large object descriptors that remain open at the end of a
+ transaction will be closed automatically.
+</para>
+</sect2>
+
+ <sect2 id="lo-unlink">
+ <title>Removing a Large Object</title>
+
+ <para>
+ <indexterm><primary>lo_unlink</primary></indexterm>
+ To remove a large object from the database, call
+<synopsis>
+int lo_unlink(PGconn *conn, Oid lobjId);
+</synopsis>
+ The <parameter>lobjId</parameter> argument specifies the OID of the
+ large object to remove. Returns 1 if successful, -1 on failure.
+ </para>
+ </sect2>
+
+</sect1>
+
+<sect1 id="lo-funcs">
+<title>Server-Side Functions</title>
+
+ <para>
+ Server-side functions tailored for manipulating large objects from SQL are
+ listed in <xref linkend="lo-funcs-table"/>.
+ </para>
+
+ <table id="lo-funcs-table">
+ <title>SQL-Oriented Large Object Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lo_from_bytea</primary>
+ </indexterm>
+ <function>lo_from_bytea</function> ( <parameter>loid</parameter> <type>oid</type>, <parameter>data</parameter> <type>bytea</type> )
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Creates a large object and stores <parameter>data</parameter> in it.
+ If <parameter>loid</parameter> is zero then the system will choose a
+ free OID, otherwise that OID is used (with an error if some large
+ object already has that OID). On success, the large object's OID is
+ returned.
+ </para>
+ <para>
+ <literal>lo_from_bytea(0, '\xffffff00')</literal>
+ <returnvalue>24528</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lo_put</primary>
+ </indexterm>
+ <function>lo_put</function> ( <parameter>loid</parameter> <type>oid</type>, <parameter>offset</parameter> <type>bigint</type>, <parameter>data</parameter> <type>bytea</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Writes <parameter>data</parameter> starting at the given offset within
+ the large object; the large object is enlarged if necessary.
+ </para>
+ <para>
+ <literal>lo_put(24528, 1, '\xaa')</literal>
+ <returnvalue></returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>lo_get</primary>
+ </indexterm>
+ <function>lo_get</function> ( <parameter>loid</parameter> <type>oid</type> <optional>, <parameter>offset</parameter> <type>bigint</type>, <parameter>length</parameter> <type>integer</type> </optional> )
+ <returnvalue>bytea</returnvalue>
+ </para>
+ <para>
+ Extracts the large object's contents, or a substring thereof.
+ </para>
+ <para>
+ <literal>lo_get(24528, 0, 3)</literal>
+ <returnvalue>\xffaaff</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ There are additional server-side functions corresponding to each of the
+ client-side functions described earlier; indeed, for the most part the
+ client-side functions are simply interfaces to the equivalent server-side
+ functions. The ones just as convenient to call via SQL commands are
+ <function>lo_creat</function><indexterm><primary>lo_creat</primary></indexterm>,
+ <function>lo_create</function>,
+ <function>lo_unlink</function><indexterm><primary>lo_unlink</primary></indexterm>,
+ <function>lo_import</function><indexterm><primary>lo_import</primary></indexterm>, and
+ <function>lo_export</function><indexterm><primary>lo_export</primary></indexterm>.
+ Here are examples of their use:
+
+<programlisting>
+CREATE TABLE image (
+ name text,
+ raster oid
+);
+
+SELECT lo_creat(-1); -- returns OID of new, empty large object
+
+SELECT lo_create(43213); -- attempts to create large object with OID 43213
+
+SELECT lo_unlink(173454); -- deletes large object with OID 173454
+
+INSERT INTO image (name, raster)
+ VALUES ('beautiful image', lo_import('/etc/motd'));
+
+INSERT INTO image (name, raster) -- same as above, but specify OID to use
+ VALUES ('beautiful image', lo_import('/etc/motd', 68583));
+
+SELECT lo_export(image.raster, '/tmp/motd') FROM image
+ WHERE name = 'beautiful image';
+</programlisting>
+ </para>
+
+ <para>
+ The server-side <function>lo_import</function> and
+ <function>lo_export</function> functions behave considerably differently
+ from their client-side analogs. These two functions read and write files
+ in the server's file system, using the permissions of the database's
+ owning user. Therefore, by default their use is restricted to superusers.
+ In contrast, the client-side import and export functions read and write
+ files in the client's file system, using the permissions of the client
+ program. The client-side functions do not require any database
+ privileges, except the privilege to read or write the large object in
+ question.
+ </para>
+
+ <caution>
+ <para>
+ It is possible to <xref linkend="sql-grant"/> use of the
+ server-side <function>lo_import</function>
+ and <function>lo_export</function> functions to non-superusers, but
+ careful consideration of the security implications is required. A
+ malicious user of such privileges could easily parlay them into becoming
+ superuser (for example by rewriting server configuration files), or could
+ attack the rest of the server's file system without bothering to obtain
+ database superuser privileges as such. <emphasis>Access to roles having
+ such privilege must therefore be guarded just as carefully as access to
+ superuser roles.</emphasis> Nonetheless, if use of
+ server-side <function>lo_import</function>
+ or <function>lo_export</function> is needed for some routine task, it's
+ safer to use a role with such privileges than one with full superuser
+ privileges, as that helps to reduce the risk of damage from accidental
+ errors.
+ </para>
+ </caution>
+
+ <para>
+ The functionality of <function>lo_read</function> and
+ <function>lo_write</function> is also available via server-side calls,
+ but the names of the server-side functions differ from the client side
+ interfaces in that they do not contain underscores. You must call
+ these functions as <function>loread</function> and <function>lowrite</function>.
+ </para>
+
+</sect1>
+
+<sect1 id="lo-examplesect">
+<title>Example Program</title>
+
+<para>
+ <xref linkend="lo-example"/> is a sample program which shows how the large object
+ interface
+ in <application>libpq</application> can be used. Parts of the program are
+ commented out but are left in the source for the reader's
+ benefit. This program can also be found in
+ <filename>src/test/examples/testlo.c</filename> in the source distribution.
+</para>
+
+ <example id="lo-example">
+ <title>Large Objects with <application>libpq</application> Example Program</title>
+<programlisting><![CDATA[
+/*-----------------------------------------------------------------
+ *
+ * testlo.c
+ * test using large objects with libpq
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/test/examples/testlo.c
+ *
+ *-----------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "libpq-fe.h"
+#include "libpq/libpq-fs.h"
+
+#define BUFSIZE 1024
+
+/*
+ * importFile -
+ * import file "in_filename" into database as large object "lobjOid"
+ *
+ */
+static Oid
+importFile(PGconn *conn, char *filename)
+{
+ Oid lobjId;
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * open the file to be read in
+ */
+ fd = open(filename, O_RDONLY, 0666);
+ if (fd < 0)
+ { /* error */
+ fprintf(stderr, "cannot open unix file\"%s\"\n", filename);
+ }
+
+ /*
+ * create the large object
+ */
+ lobjId = lo_creat(conn, INV_READ | INV_WRITE);
+ if (lobjId == 0)
+ fprintf(stderr, "cannot create large object");
+
+ lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+
+ /*
+ * read in from the Unix file and write to the inversion file
+ */
+ while ((nbytes = read(fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = lo_write(conn, lobj_fd, buf, nbytes);
+ if (tmp < nbytes)
+ fprintf(stderr, "error while reading \"%s\"", filename);
+ }
+
+ close(fd);
+ lo_close(conn, lobj_fd);
+
+ return lobjId;
+}
+
+static void
+pickout(PGconn *conn, Oid lobjId, int start, int len)
+{
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nread;
+
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ fprintf(stderr, "cannot open large object %u", lobjId);
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ nread = 0;
+ while (len - nread > 0)
+ {
+ nbytes = lo_read(conn, lobj_fd, buf, len - nread);
+ buf[nbytes] = '\0';
+ fprintf(stderr, ">>> %s", buf);
+ nread += nbytes;
+ if (nbytes <= 0)
+ break; /* no more data? */
+ }
+ free(buf);
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
+}
+
+static void
+overwrite(PGconn *conn, Oid lobjId, int start, int len)
+{
+ int lobj_fd;
+ char *buf;
+ int nbytes;
+ int nwritten;
+ int i;
+
+ lobj_fd = lo_open(conn, lobjId, INV_WRITE);
+ if (lobj_fd < 0)
+ fprintf(stderr, "cannot open large object %u", lobjId);
+
+ lo_lseek(conn, lobj_fd, start, SEEK_SET);
+ buf = malloc(len + 1);
+
+ for (i = 0; i < len; i++)
+ buf[i] = 'X';
+ buf[i] = '\0';
+
+ nwritten = 0;
+ while (len - nwritten > 0)
+ {
+ nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
+ nwritten += nbytes;
+ if (nbytes <= 0)
+ {
+ fprintf(stderr, "\nWRITE FAILED!\n");
+ break;
+ }
+ }
+ free(buf);
+ fprintf(stderr, "\n");
+ lo_close(conn, lobj_fd);
+}
+
+
+/*
+ * exportFile -
+ * export large object "lobjOid" to file "out_filename"
+ *
+ */
+static void
+exportFile(PGconn *conn, Oid lobjId, char *filename)
+{
+ int lobj_fd;
+ char buf[BUFSIZE];
+ int nbytes,
+ tmp;
+ int fd;
+
+ /*
+ * open the large object
+ */
+ lobj_fd = lo_open(conn, lobjId, INV_READ);
+ if (lobj_fd < 0)
+ fprintf(stderr, "cannot open large object %u", lobjId);
+
+ /*
+ * open the file to be written to
+ */
+ fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+ if (fd < 0)
+ { /* error */
+ fprintf(stderr, "cannot open unix file\"%s\"",
+ filename);
+ }
+
+ /*
+ * read in from the inversion file and write to the Unix file
+ */
+ while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0)
+ {
+ tmp = write(fd, buf, nbytes);
+ if (tmp < nbytes)
+ {
+ fprintf(stderr, "error while writing \"%s\"",
+ filename);
+ }
+ }
+
+ lo_close(conn, lobj_fd);
+ close(fd);
+}
+
+static void
+exit_nicely(PGconn *conn)
+{
+ PQfinish(conn);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *in_filename,
+ *out_filename;
+ char *database;
+ Oid lobjOid;
+ PGconn *conn;
+ PGresult *res;
+
+ if (argc != 4)
+ {
+ fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
+ argv[0]);
+ exit(1);
+ }
+
+ database = argv[1];
+ in_filename = argv[2];
+ out_filename = argv[3];
+
+ /*
+ * set up the connection
+ */
+ conn = PQsetdb(NULL, NULL, NULL, NULL, database);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) != CONNECTION_OK)
+ {
+ fprintf(stderr, "%s", PQerrorMessage(conn));
+ exit_nicely(conn);
+ }
+
+ /* Set always-secure search path, so malicious users can't take control. */
+ res = PQexec(conn,
+ "SELECT pg_catalog.set_config('search_path', '', false)");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "SET failed: %s", PQerrorMessage(conn));
+ PQclear(res);
+ exit_nicely(conn);
+ }
+ PQclear(res);
+
+ res = PQexec(conn, "begin");
+ PQclear(res);
+ printf("importing file \"%s\" ...\n", in_filename);
+/* lobjOid = importFile(conn, in_filename); */
+ lobjOid = lo_import(conn, in_filename);
+ if (lobjOid == 0)
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ else
+ {
+ printf("\tas large object %u.\n", lobjOid);
+
+ printf("picking out bytes 1000-2000 of the large object\n");
+ pickout(conn, lobjOid, 1000, 1000);
+
+ printf("overwriting bytes 1000-2000 of the large object with X's\n");
+ overwrite(conn, lobjOid, 1000, 1000);
+
+ printf("exporting large object to file \"%s\" ...\n", out_filename);
+/* exportFile(conn, lobjOid, out_filename); */
+ if (lo_export(conn, lobjOid, out_filename) < 0)
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ }
+
+ res = PQexec(conn, "end");
+ PQclear(res);
+ PQfinish(conn);
+ return 0;
+}
+]]>
+</programlisting>
+</example>
+
+</sect1>
+</chapter>
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
new file mode 100644
index 0000000..bc3f5ec
--- /dev/null
+++ b/doc/src/sgml/logical-replication.sgml
@@ -0,0 +1,1677 @@
+<!-- doc/src/sgml/logical-replication.sgml -->
+
+<chapter id="logical-replication">
+ <title>Logical Replication</title>
+
+ <para>
+ Logical replication is a method of replicating data objects and their
+ changes, based upon their replication identity (usually a primary key). We
+ use the term logical in contrast to physical replication, which uses exact
+ block addresses and byte-by-byte replication. PostgreSQL supports both
+ mechanisms concurrently, see <xref linkend="high-availability"/>. Logical
+ replication allows fine-grained control over both data replication and
+ security.
+ </para>
+
+ <para>
+ Logical replication uses a <firstterm>publish</firstterm>
+ and <firstterm>subscribe</firstterm> model with one or
+ more <firstterm>subscribers</firstterm> subscribing to one or more
+ <firstterm>publications</firstterm> on a <firstterm>publisher</firstterm>
+ node. Subscribers pull data from the publications they subscribe to and may
+ subsequently re-publish data to allow cascading replication or more complex
+ configurations.
+ </para>
+
+ <para>
+ Logical replication of a table typically starts with taking a snapshot
+ of the data on the publisher database and copying that to the subscriber.
+ Once that is done, the changes on the publisher are sent to the subscriber
+ as they occur in real-time. The subscriber applies the data in the same
+ order as the publisher so that transactional consistency is guaranteed for
+ publications within a single subscription. This method of data replication
+ is sometimes referred to as transactional replication.
+ </para>
+
+ <para>
+ The typical use-cases for logical replication are:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Sending incremental changes in a single database or a subset of a
+ database to subscribers as they occur.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Firing triggers for individual changes as they arrive on the
+ subscriber.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Consolidating multiple databases into a single one (for example for
+ analytical purposes).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Replicating between different major versions of PostgreSQL.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Replicating between PostgreSQL instances on different platforms (for
+ example Linux to Windows)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Giving access to replicated data to different groups of users.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Sharing a subset of the database between multiple databases.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The subscriber database behaves in the same way as any other PostgreSQL
+ instance and can be used as a publisher for other databases by defining its
+ own publications. When the subscriber is treated as read-only by
+ application, there will be no conflicts from a single subscription. On the
+ other hand, if there are other writes done either by an application or by other
+ subscribers to the same set of tables, conflicts can arise.
+ </para>
+
+ <sect1 id="logical-replication-publication">
+ <title>Publication</title>
+
+ <para>
+ A <firstterm>publication</firstterm> can be defined on any physical
+ replication primary. The node where a publication is defined is referred to
+ as <firstterm>publisher</firstterm>. A publication is a set of changes
+ generated from a table or a group of tables, and might also be described as
+ a change set or replication set. Each publication exists in only one database.
+ </para>
+
+ <para>
+ Publications are different from schemas and do not affect how the table is
+ accessed. Each table can be added to multiple publications if needed.
+ Publications may currently only contain tables and all tables in schema.
+ Objects must be added explicitly, except when a publication is created for
+ <literal>ALL TABLES</literal>.
+ </para>
+
+ <para>
+ Publications can choose to limit the changes they produce to
+ any combination of <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, and <command>TRUNCATE</command>, similar to how triggers are fired by
+ particular event types. By default, all operation types are replicated.
+ These publication specifications apply only for DML operations; they do not affect the initial
+ data synchronization copy. (Row filters have no effect for
+ <command>TRUNCATE</command>. See <xref linkend="logical-replication-row-filter"/>).
+ </para>
+
+ <para>
+ A published table must have a <quote>replica identity</quote> configured in
+ order to be able to replicate <command>UPDATE</command>
+ and <command>DELETE</command> operations, so that appropriate rows to
+ update or delete can be identified on the subscriber side. By default,
+ this is the primary key, if there is one. Another unique index (with
+ certain additional requirements) can also be set to be the replica
+ identity. If the table does not have any suitable key, then it can be set
+ to replica identity <quote>full</quote>, which means the entire row becomes
+ the key. This, however, is very inefficient and should only be used as a
+ fallback if no other solution is possible. If a replica identity other
+ than <quote>full</quote> is set on the publisher side, a replica identity
+ comprising the same or fewer columns must also be set on the subscriber
+ side. See <xref linkend="sql-altertable-replica-identity"/> for details on
+ how to set the replica identity. If a table without a replica identity is
+ added to a publication that replicates <command>UPDATE</command>
+ or <command>DELETE</command> operations then
+ subsequent <command>UPDATE</command> or <command>DELETE</command>
+ operations will cause an error on the publisher. <command>INSERT</command>
+ operations can proceed regardless of any replica identity.
+ </para>
+
+ <para>
+ Every publication can have multiple subscribers.
+ </para>
+
+ <para>
+ A publication is created using the <link linkend="sql-createpublication"><command>CREATE PUBLICATION</command></link>
+ command and may later be altered or dropped using corresponding commands.
+ </para>
+
+ <para>
+ The individual tables can be added and removed dynamically using
+ <link linkend="sql-alterpublication"><command>ALTER PUBLICATION</command></link>. Both the <literal>ADD
+ TABLE</literal> and <literal>DROP TABLE</literal> operations are
+ transactional; so the table will start or stop replicating at the correct
+ snapshot once the transaction has committed.
+ </para>
+ </sect1>
+
+ <sect1 id="logical-replication-subscription">
+ <title>Subscription</title>
+
+ <para>
+ A <firstterm>subscription</firstterm> is the downstream side of logical
+ replication. The node where a subscription is defined is referred to as
+ the <firstterm>subscriber</firstterm>. A subscription defines the connection
+ to another database and set of publications (one or more) to which it wants
+ to subscribe.
+ </para>
+
+ <para>
+ The subscriber database behaves in the same way as any other PostgreSQL
+ instance and can be used as a publisher for other databases by defining its
+ own publications.
+ </para>
+
+ <para>
+ A subscriber node may have multiple subscriptions if desired. It is
+ possible to define multiple subscriptions between a single
+ publisher-subscriber pair, in which case care must be taken to ensure
+ that the subscribed publication objects don't overlap.
+ </para>
+
+ <para>
+ Each subscription will receive changes via one replication slot (see
+ <xref linkend="streaming-replication-slots"/>). Additional replication
+ slots may be required for the initial data synchronization of
+ pre-existing table data and those will be dropped at the end of data
+ synchronization.
+ </para>
+
+ <para>
+ A logical replication subscription can be a standby for synchronous
+ replication (see <xref linkend="synchronous-replication"/>). The standby
+ name is by default the subscription name. An alternative name can be
+ specified as <literal>application_name</literal> in the connection
+ information of the subscription.
+ </para>
+
+ <para>
+ Subscriptions are dumped by <command>pg_dump</command> if the current user
+ is a superuser. Otherwise a warning is written and subscriptions are
+ skipped, because non-superusers cannot read all subscription information
+ from the <structname>pg_subscription</structname> catalog.
+ </para>
+
+ <para>
+ The subscription is added using <link linkend="sql-createsubscription"><command>CREATE SUBSCRIPTION</command></link> and
+ can be stopped/resumed at any time using the
+ <link linkend="sql-altersubscription"><command>ALTER SUBSCRIPTION</command></link> command and removed using
+ <link linkend="sql-dropsubscription"><command>DROP SUBSCRIPTION</command></link>.
+ </para>
+
+ <para>
+ When a subscription is dropped and recreated, the synchronization
+ information is lost. This means that the data has to be resynchronized
+ afterwards.
+ </para>
+
+ <para>
+ The schema definitions are not replicated, and the published tables must
+ exist on the subscriber. Only regular tables may be
+ the target of replication. For example, you can't replicate to a view.
+ </para>
+
+ <para>
+ The tables are matched between the publisher and the subscriber using the
+ fully qualified table name. Replication to differently-named tables on the
+ subscriber is not supported.
+ </para>
+
+ <para>
+ Columns of a table are also matched by name. The order of columns in the
+ subscriber table does not need to match that of the publisher. The data
+ types of the columns do not need to match, as long as the text
+ representation of the data can be converted to the target type. For
+ example, you can replicate from a column of type <type>integer</type> to a
+ column of type <type>bigint</type>. The target table can also have
+ additional columns not provided by the published table. Any such columns
+ will be filled with the default value as specified in the definition of the
+ target table.
+ </para>
+
+ <sect2 id="logical-replication-subscription-slot">
+ <title>Replication Slot Management</title>
+
+ <para>
+ As mentioned earlier, each (active) subscription receives changes from a
+ replication slot on the remote (publishing) side.
+ </para>
+ <para>
+ Additional table synchronization slots are normally transient, created
+ internally to perform initial table synchronization and dropped
+ automatically when they are no longer needed. These table synchronization
+ slots have generated names: <quote><literal>pg_%u_sync_%u_%llu</literal></quote>
+ (parameters: Subscription <parameter>oid</parameter>,
+ Table <parameter>relid</parameter>, system identifier <parameter>sysid</parameter>)
+ </para>
+ <para>
+ Normally, the remote replication slot is created automatically when the
+ subscription is created using <command>CREATE SUBSCRIPTION</command> and it
+ is dropped automatically when the subscription is dropped using
+ <command>DROP SUBSCRIPTION</command>. In some situations, however, it can
+ be useful or necessary to manipulate the subscription and the underlying
+ replication slot separately. Here are some scenarios:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ When creating a subscription, the replication slot already exists. In
+ that case, the subscription can be created using
+ the <literal>create_slot = false</literal> option to associate with the
+ existing slot.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When creating a subscription, the remote host is not reachable or in an
+ unclear state. In that case, the subscription can be created using
+ the <literal>connect = false</literal> option. The remote host will then not
+ be contacted at all. This is what <application>pg_dump</application>
+ uses. The remote replication slot will then have to be created
+ manually before the subscription can be activated.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When dropping a subscription, the replication slot should be kept.
+ This could be useful when the subscriber database is being moved to a
+ different host and will be activated from there. In that case,
+ disassociate the slot from the subscription using <command>ALTER
+ SUBSCRIPTION</command> before attempting to drop the subscription.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When dropping a subscription, the remote host is not reachable. In
+ that case, disassociate the slot from the subscription
+ using <command>ALTER SUBSCRIPTION</command> before attempting to drop
+ the subscription. If the remote database instance no longer exists, no
+ further action is then necessary. If, however, the remote database
+ instance is just unreachable, the replication slot (and any still
+ remaining table synchronization slots) should then be
+ dropped manually; otherwise it/they would continue to reserve WAL and might
+ eventually cause the disk to fill up. Such cases should be carefully
+ investigated.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2 id="logical-replication-subscription-examples">
+ <title>Examples</title>
+
+ <para>
+ Create some test tables on the publisher.
+<programlisting>
+test_pub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
+CREATE TABLE
+test_pub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
+CREATE TABLE
+test_pub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
+CREATE TABLE
+</programlisting></para>
+
+ <para>
+ Create the same tables on the subscriber.
+<programlisting>
+test_sub=# CREATE TABLE t1(a int, b text, PRIMARY KEY(a));
+CREATE TABLE
+test_sub=# CREATE TABLE t2(c int, d text, PRIMARY KEY(c));
+CREATE TABLE
+test_sub=# CREATE TABLE t3(e int, f text, PRIMARY KEY(e));
+CREATE TABLE
+</programlisting></para>
+
+ <para>
+ Insert data to the tables at the publisher side.
+<programlisting>
+test_pub=# INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');
+INSERT 0 3
+test_pub=# INSERT INTO t2 VALUES (1, 'A'), (2, 'B'), (3, 'C');
+INSERT 0 3
+test_pub=# INSERT INTO t3 VALUES (1, 'i'), (2, 'ii'), (3, 'iii');
+INSERT 0 3
+</programlisting></para>
+
+ <para>
+ Create publications for the tables. The publications <literal>pub2</literal>
+ and <literal>pub3a</literal> disallow some <literal>publish</literal>
+ operations. The publication <literal>pub3b</literal> has a row filter (see
+ <xref linkend="logical-replication-row-filter"/>).
+<programlisting>
+test_pub=# CREATE PUBLICATION pub1 FOR TABLE t1;
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION pub2 FOR TABLE t2 WITH (publish = 'truncate');
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION pub3a FOR TABLE t3 WITH (publish = 'truncate');
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION pub3b FOR TABLE t3 WHERE (e > 5);
+CREATE PUBLICATION
+</programlisting></para>
+
+ <para>
+ Create subscriptions for the publications. The subscription
+ <literal>sub3</literal> subscribes to both <literal>pub3a</literal> and
+ <literal>pub3b</literal>. All subscriptions will copy initial data by default.
+<programlisting>
+test_sub=# CREATE SUBSCRIPTION sub1
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub1'
+test_sub-# PUBLICATION pub1;
+CREATE SUBSCRIPTION
+test_sub=# CREATE SUBSCRIPTION sub2
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub2'
+test_sub-# PUBLICATION pub2;
+CREATE SUBSCRIPTION
+test_sub=# CREATE SUBSCRIPTION sub3
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=sub3'
+test_sub-# PUBLICATION pub3a, pub3b;
+CREATE SUBSCRIPTION
+</programlisting></para>
+
+ <para>
+ Observe that initial table data is copied, regardless of the
+ <literal>publish</literal> operation of the publication.
+<programlisting>
+test_sub=# SELECT * FROM t1;
+ a | b
+---+-------
+ 1 | one
+ 2 | two
+ 3 | three
+(3 rows)
+
+test_sub=# SELECT * FROM t2;
+ c | d
+---+---
+ 1 | A
+ 2 | B
+ 3 | C
+(3 rows)
+</programlisting></para>
+
+ <para>
+ Furthermore, because the initial data copy ignores the <literal>publish</literal>
+ operation, and because publication <literal>pub3a</literal> has no row filter,
+ it means the copied table <literal>t3</literal> contains all rows even when
+ they do not match the row filter of publication <literal>pub3b</literal>.
+<programlisting>
+test_sub=# SELECT * FROM t3;
+ e | f
+---+-----
+ 1 | i
+ 2 | ii
+ 3 | iii
+(3 rows)
+</programlisting></para>
+
+ <para>
+ Insert more data to the tables at the publisher side.
+<programlisting>
+test_pub=# INSERT INTO t1 VALUES (4, 'four'), (5, 'five'), (6, 'six');
+INSERT 0 3
+test_pub=# INSERT INTO t2 VALUES (4, 'D'), (5, 'E'), (6, 'F');
+INSERT 0 3
+test_pub=# INSERT INTO t3 VALUES (4, 'iv'), (5, 'v'), (6, 'vi');
+INSERT 0 3
+</programlisting></para>
+
+ <para>
+ Now the publisher side data looks like:
+<programlisting>
+test_pub=# SELECT * FROM t1;
+ a | b
+---+-------
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+ 5 | five
+ 6 | six
+(6 rows)
+
+test_pub=# SELECT * FROM t2;
+ c | d
+---+---
+ 1 | A
+ 2 | B
+ 3 | C
+ 4 | D
+ 5 | E
+ 6 | F
+(6 rows)
+
+test_pub=# SELECT * FROM t3;
+ e | f
+---+-----
+ 1 | i
+ 2 | ii
+ 3 | iii
+ 4 | iv
+ 5 | v
+ 6 | vi
+(6 rows)
+</programlisting></para>
+
+ <para>
+ Observe that during normal replication the appropriate
+ <literal>publish</literal> operations are used. This means publications
+ <literal>pub2</literal> and <literal>pub3a</literal> will not replicate the
+ <literal>INSERT</literal>. Also, publication <literal>pub3b</literal> will
+ only replicate data that matches the row filter of <literal>pub3b</literal>.
+ Now the subscriber side data looks like:
+<programlisting>
+test_sub=# SELECT * FROM t1;
+ a | b
+---+-------
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+ 5 | five
+ 6 | six
+(6 rows)
+
+test_sub=# SELECT * FROM t2;
+ c | d
+---+---
+ 1 | A
+ 2 | B
+ 3 | C
+(3 rows)
+
+test_sub=# SELECT * FROM t3;
+ e | f
+---+-----
+ 1 | i
+ 2 | ii
+ 3 | iii
+ 6 | vi
+(4 rows)
+</programlisting></para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="logical-replication-row-filter">
+ <title>Row Filters</title>
+
+ <para>
+ By default, all data from all published tables will be replicated to the
+ appropriate subscribers. The replicated data can be reduced by using a
+ <firstterm>row filter</firstterm>. A user might choose to use row filters
+ for behavioral, security or performance reasons. If a published table sets a
+ row filter, a row is replicated only if its data satisfies the row filter
+ expression. This allows a set of tables to be partially replicated. The row
+ filter is defined per table. Use a <literal>WHERE</literal> clause after the
+ table name for each published table that requires data to be filtered out.
+ The <literal>WHERE</literal> clause must be enclosed by parentheses. See
+ <xref linkend="sql-createpublication"/> for details.
+ </para>
+
+ <sect2 id="logical-replication-row-filter-rules">
+ <title>Row Filter Rules</title>
+
+ <para>
+ Row filters are applied <emphasis>before</emphasis> publishing the changes.
+ If the row filter evaluates to <literal>false</literal> or <literal>NULL</literal>
+ then the row is not replicated. The <literal>WHERE</literal> clause expression
+ is evaluated with the same role used for the replication connection (i.e.
+ the role specified in the <literal>CONNECTION</literal> clause of the
+ <xref linkend="sql-createsubscription"/>). Row filters have no effect for
+ <command>TRUNCATE</command> command.
+ </para>
+
+ </sect2>
+
+ <sect2 id="logical-replication-row-filter-restrictions">
+ <title>Expression Restrictions</title>
+
+ <para>
+ The <literal>WHERE</literal> clause allows only simple expressions. It
+ cannot contain user-defined functions, operators, types, and collations,
+ system column references or non-immutable built-in functions.
+ </para>
+
+ <para>
+ If a publication publishes <command>UPDATE</command> or
+ <command>DELETE</command> operations, the row filter <literal>WHERE</literal>
+ clause must contain only columns that are covered by the replica identity
+ (see <xref linkend="sql-altertable-replica-identity"/>). If a publication
+ publishes only <command>INSERT</command> operations, the row filter
+ <literal>WHERE</literal> clause can use any column.
+ </para>
+
+ </sect2>
+
+ <sect2 id="logical-replication-row-filter-transformations">
+ <title>UPDATE Transformations</title>
+
+ <para>
+ Whenever an <command>UPDATE</command> is processed, the row filter
+ expression is evaluated for both the old and new row (i.e. using the data
+ before and after the update). If both evaluations are <literal>true</literal>,
+ it replicates the <command>UPDATE</command> change. If both evaluations are
+ <literal>false</literal>, it doesn't replicate the change. If only one of
+ the old/new rows matches the row filter expression, the <command>UPDATE</command>
+ is transformed to <command>INSERT</command> or <command>DELETE</command>, to
+ avoid any data inconsistency. The row on the subscriber should reflect what
+ is defined by the row filter expression on the publisher.
+ </para>
+
+ <para>
+ If the old row satisfies the row filter expression (it was sent to the
+ subscriber) but the new row doesn't, then, from a data consistency
+ perspective the old row should be removed from the subscriber.
+ So the <command>UPDATE</command> is transformed into a <command>DELETE</command>.
+ </para>
+
+ <para>
+ If the old row doesn't satisfy the row filter expression (it wasn't sent
+ to the subscriber) but the new row does, then, from a data consistency
+ perspective the new row should be added to the subscriber.
+ So the <command>UPDATE</command> is transformed into an <command>INSERT</command>.
+ </para>
+
+ <para>
+ <xref linkend="logical-replication-row-filter-transformations-summary"/>
+ summarizes the applied transformations.
+ </para>
+
+ <table id="logical-replication-row-filter-transformations-summary">
+ <title><command>UPDATE</command> Transformation Summary</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Old row</entry><entry>New row</entry><entry>Transformation</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>no match</entry><entry>no match</entry><entry>don't replicate</entry>
+ </row>
+ <row>
+ <entry>no match</entry><entry>match</entry><entry><literal>INSERT</literal></entry>
+ </row>
+ <row>
+ <entry>match</entry><entry>no match</entry><entry><literal>DELETE</literal></entry>
+ </row>
+ <row>
+ <entry>match</entry><entry>match</entry><entry><literal>UPDATE</literal></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="logical-replication-row-filter-partitioned-table">
+ <title>Partitioned Tables</title>
+
+ <para>
+ If the publication contains a partitioned table, the publication parameter
+ <literal>publish_via_partition_root</literal> determines which row filter
+ is used. If <literal>publish_via_partition_root</literal> is <literal>true</literal>,
+ the <emphasis>root partitioned table's</emphasis> row filter is used. Otherwise,
+ if <literal>publish_via_partition_root</literal> is <literal>false</literal>
+ (default), each <emphasis>partition's</emphasis> row filter is used.
+ </para>
+
+ </sect2>
+
+ <sect2 id="logical-replication-row-filter-initial-data-sync">
+ <title>Initial Data Synchronization</title>
+
+ <para>
+ If the subscription requires copying pre-existing table data
+ and a publication contains <literal>WHERE</literal> clauses, only data that
+ satisfies the row filter expressions is copied to the subscriber.
+ </para>
+
+ <para>
+ If the subscription has several publications in which a table has been
+ published with different <literal>WHERE</literal> clauses, rows that satisfy
+ <emphasis>any</emphasis> of the expressions will be copied. See
+ <xref linkend="logical-replication-row-filter-combining"/> for details.
+ </para>
+
+ <warning>
+ <para>
+ Because initial data synchronization does not take into account the
+ <literal>publish</literal> parameter when copying existing table data,
+ some rows may be copied that would not be replicated using DML. Refer to
+ <xref linkend="logical-replication-snapshot"/>, and see
+ <xref linkend="logical-replication-subscription-examples"/> for examples.
+ </para>
+ </warning>
+
+ <note>
+ <para>
+ If the subscriber is in a release prior to 15, copy pre-existing data
+ doesn't use row filters even if they are defined in the publication.
+ This is because old releases can only copy the entire table data.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="logical-replication-row-filter-combining">
+ <title>Combining Multiple Row Filters</title>
+
+ <para>
+ If the subscription has several publications in which the same table has
+ been published with different row filters (for the same <literal>publish</literal>
+ operation), those expressions get ORed together, so that rows satisfying
+ <emphasis>any</emphasis> of the expressions will be replicated. This means all
+ the other row filters for the same table become redundant if:
+ <itemizedlist>
+ <listitem>
+ <para>
+ One of the publications has no row filter.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ One of the publications was created using <literal>FOR ALL TABLES</literal>.
+ This clause does not allow row filters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ One of the publications was created using
+ <literal>FOR TABLES IN SCHEMA</literal> and the table belongs to
+ the referred schema. This clause does not allow row filters.
+ </para>
+ </listitem>
+ </itemizedlist></para>
+
+ </sect2>
+
+ <sect2 id="logical-replication-row-filter-examples">
+ <title>Examples</title>
+
+ <para>
+ Create some tables to be used in the following examples.
+<programlisting>
+test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
+CREATE TABLE
+test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d));
+CREATE TABLE
+test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g));
+CREATE TABLE
+</programlisting></para>
+
+ <para>
+ Create some publications. Publication <literal>p1</literal> has one table
+ (<literal>t1</literal>) and that table has a row filter. Publication
+ <literal>p2</literal> has two tables. Table <literal>t1</literal> has no row
+ filter, and table <literal>t2</literal> has a row filter. Publication
+ <literal>p3</literal> has two tables, and both of them have a row filter.
+<programlisting>
+test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'NSW');
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99);
+CREATE PUBLICATION
+test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10);
+CREATE PUBLICATION
+</programlisting></para>
+
+ <para>
+ <command>psql</command> can be used to show the row filter expressions (if
+ defined) for each publication.
+<programlisting>
+test_pub=# \dRp+
+ Publication p1
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text))
+
+ Publication p2
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t1"
+ "public.t2" WHERE (e = 99)
+
+ Publication p3
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t2" WHERE (d = 10)
+ "public.t3" WHERE (g = 10)
+</programlisting></para>
+
+ <para>
+ <command>psql</command> can be used to show the row filter expressions (if
+ defined) for each table. See that table <literal>t1</literal> is a member
+ of two publications, but has a row filter only in <literal>p1</literal>.
+ See that table <literal>t2</literal> is a member of two publications, and
+ has a different row filter in each of them.
+<programlisting>
+test_pub=# \d t1
+ Table "public.t1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ a | integer | | not null |
+ b | integer | | |
+ c | text | | not null |
+Indexes:
+ "t1_pkey" PRIMARY KEY, btree (a, c)
+Publications:
+ "p1" WHERE ((a > 5) AND (c = 'NSW'::text))
+ "p2"
+
+test_pub=# \d t2
+ Table "public.t2"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ d | integer | | not null |
+ e | integer | | |
+ f | integer | | |
+Indexes:
+ "t2_pkey" PRIMARY KEY, btree (d)
+Publications:
+ "p2" WHERE (e = 99)
+ "p3" WHERE (d = 10)
+
+test_pub=# \d t3
+ Table "public.t3"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ g | integer | | not null |
+ h | integer | | |
+ i | integer | | |
+Indexes:
+ "t3_pkey" PRIMARY KEY, btree (g)
+Publications:
+ "p3" WHERE (g = 10)
+</programlisting></para>
+
+ <para>
+ On the subscriber node, create a table <literal>t1</literal> with the same
+ definition as the one on the publisher, and also create the subscription
+ <literal>s1</literal> that subscribes to the publication <literal>p1</literal>.
+<programlisting>
+test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c));
+CREATE TABLE
+test_sub=# CREATE SUBSCRIPTION s1
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
+test_sub-# PUBLICATION p1;
+CREATE SUBSCRIPTION
+</programlisting></para>
+
+ <para>
+ Insert some rows. Only the rows satisfying the <literal>t1 WHERE</literal>
+ clause of publication <literal>p1</literal> are replicated.
+<programlisting>
+test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW');
+INSERT 0 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 2 | 102 | NSW
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 6 | 106 | NSW
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 9 | 109 | NSW
+(8 rows)
+</programlisting>
+<programlisting>
+test_sub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 6 | 106 | NSW
+ 9 | 109 | NSW
+(2 rows)
+</programlisting></para>
+
+ <para>
+ Update some data, where the old and new row values both
+ satisfy the <literal>t1 WHERE</literal> clause of publication
+ <literal>p1</literal>. The <command>UPDATE</command> replicates
+ the change as normal.
+<programlisting>
+test_pub=# UPDATE t1 SET b = 999 WHERE a = 6;
+UPDATE 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 2 | 102 | NSW
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+(8 rows)
+</programlisting>
+<programlisting>
+test_sub=# SELECT * FROM t1;
+ a | b | c
+---+-----+-----
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+(2 rows)
+</programlisting></para>
+
+ <para>
+ Update some data, where the old row values did not satisfy
+ the <literal>t1 WHERE</literal> clause of publication <literal>p1</literal>,
+ but the new row values do satisfy it. The <command>UPDATE</command> is
+ transformed into an <command>INSERT</command> and the change is replicated.
+ See the new row on the subscriber.
+<programlisting>
+test_pub=# UPDATE t1 SET a = 555 WHERE a = 2;
+UPDATE 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+(8 rows)
+</programlisting>
+<programlisting>
+test_sub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 9 | 109 | NSW
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+(3 rows)
+</programlisting></para>
+
+ <para>
+ Update some data, where the old row values satisfied
+ the <literal>t1 WHERE</literal> clause of publication <literal>p1</literal>,
+ but the new row values do not satisfy it. The <command>UPDATE</command> is
+ transformed into a <command>DELETE</command> and the change is replicated.
+ See that the row is removed from the subscriber.
+<programlisting>
+test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9;
+UPDATE 1
+
+test_pub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 3 | 103 | QLD
+ 4 | 104 | VIC
+ 5 | 105 | ACT
+ 7 | 107 | NT
+ 8 | 108 | QLD
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+ 9 | 109 | VIC
+(8 rows)
+</programlisting>
+<programlisting>
+test_sub=# SELECT * FROM t1;
+ a | b | c
+-----+-----+-----
+ 6 | 999 | NSW
+ 555 | 102 | NSW
+(2 rows)
+</programlisting></para>
+
+ <para>
+ The following examples show how the publication parameter
+ <literal>publish_via_partition_root</literal> determines whether the row
+ filter of the parent or child table will be used in the case of partitioned
+ tables.
+ </para>
+
+ <para>
+ Create a partitioned table on the publisher.
+<programlisting>
+test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
+CREATE TABLE
+test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT;
+CREATE TABLE
+</programlisting>
+ Create the same tables on the subscriber.
+<programlisting>
+test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a);
+CREATE TABLE
+test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT;
+CREATE TABLE
+</programlisting></para>
+
+ <para>
+ Create a publication <literal>p4</literal>, and then subscribe to it. The
+ publication parameter <literal>publish_via_partition_root</literal> is set
+ as true. There are row filters defined on both the partitioned table
+ (<literal>parent</literal>), and on the partition (<literal>child</literal>).
+<programlisting>
+test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a &lt; 5), child WHERE (a >= 5)
+test_pub-# WITH (publish_via_partition_root=true);
+CREATE PUBLICATION
+</programlisting>
+<programlisting>
+test_sub=# CREATE SUBSCRIPTION s4
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4'
+test_sub-# PUBLICATION p4;
+CREATE SUBSCRIPTION
+</programlisting></para>
+
+ <para>
+ Insert some values directly into the <literal>parent</literal> and
+ <literal>child</literal> tables. They replicate using the row filter of
+ <literal>parent</literal> (because <literal>publish_via_partition_root</literal>
+ is true).
+<programlisting>
+test_pub=# INSERT INTO parent VALUES (2), (4), (6);
+INSERT 0 3
+test_pub=# INSERT INTO child VALUES (3), (5), (7);
+INSERT 0 3
+
+test_pub=# SELECT * FROM parent ORDER BY a;
+ a
+---
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+(6 rows)
+</programlisting>
+<programlisting>
+test_sub=# SELECT * FROM parent ORDER BY a;
+ a
+---
+ 2
+ 3
+ 4
+(3 rows)
+</programlisting></para>
+
+ <para>
+ Repeat the same test, but with a different value for <literal>publish_via_partition_root</literal>.
+ The publication parameter <literal>publish_via_partition_root</literal> is
+ set as false. A row filter is defined on the partition (<literal>child</literal>).
+<programlisting>
+test_pub=# DROP PUBLICATION p4;
+DROP PUBLICATION
+test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5)
+test_pub-# WITH (publish_via_partition_root=false);
+CREATE PUBLICATION
+</programlisting>
+<programlisting>
+test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION;
+ALTER SUBSCRIPTION
+</programlisting></para>
+
+ <para>
+ Do the inserts on the publisher same as before. They replicate using the
+ row filter of <literal>child</literal> (because
+ <literal>publish_via_partition_root</literal> is false).
+<programlisting>
+test_pub=# TRUNCATE parent;
+TRUNCATE TABLE
+test_pub=# INSERT INTO parent VALUES (2), (4), (6);
+INSERT 0 3
+test_pub=# INSERT INTO child VALUES (3), (5), (7);
+INSERT 0 3
+
+test_pub=# SELECT * FROM parent ORDER BY a;
+ a
+---
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+(6 rows)
+</programlisting>
+<programlisting>
+test_sub=# SELECT * FROM child ORDER BY a;
+ a
+---
+ 5
+ 6
+ 7
+(3 rows)
+</programlisting></para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="logical-replication-col-lists">
+ <title>Column Lists</title>
+
+ <para>
+ Each publication can optionally specify which columns of each table are
+ replicated to subscribers. The table on the subscriber side must have at
+ least all the columns that are published. If no column list is specified,
+ then all columns on the publisher are replicated.
+ See <xref linkend="sql-createpublication"/> for details on the syntax.
+ </para>
+
+ <para>
+ The choice of columns can be based on behavioral or performance reasons.
+ However, do not rely on this feature for security: a malicious subscriber
+ is able to obtain data from columns that are not specifically
+ published. If security is a consideration, protections can be applied
+ at the publisher side.
+ </para>
+
+ <para>
+ If no column list is specified, any columns added later are automatically
+ replicated. This means that having a column list which names all columns
+ is not the same as having no column list at all.
+ </para>
+
+ <para>
+ A column list can contain only simple column references. The order
+ of columns in the list is not preserved.
+ </para>
+
+ <para>
+ Specifying a column list when the publication also publishes
+ <literal>FOR TABLES IN SCHEMA</literal> is not supported.
+ </para>
+
+ <para>
+ For partitioned tables, the publication parameter
+ <literal>publish_via_partition_root</literal> determines which column list
+ is used. If <literal>publish_via_partition_root</literal> is
+ <literal>true</literal>, the root partitioned table's column list is used.
+ Otherwise, if <literal>publish_via_partition_root</literal> is
+ <literal>false</literal> (the default), each partition's column list is used.
+ </para>
+
+ <para>
+ If a publication publishes <command>UPDATE</command> or
+ <command>DELETE</command> operations, any column list must include the
+ table's replica identity columns (see
+ <xref linkend="sql-altertable-replica-identity"/>).
+ If a publication publishes only <command>INSERT</command> operations, then
+ the column list may omit replica identity columns.
+ </para>
+
+ <para>
+ Column lists have no effect for the <literal>TRUNCATE</literal> command.
+ </para>
+
+ <para>
+ During initial data synchronization, only the published columns are
+ copied. However, if the subscriber is from a release prior to 15, then
+ all the columns in the table are copied during initial data synchronization,
+ ignoring any column lists.
+ </para>
+
+ <warning id="logical-replication-col-list-combining">
+ <title>Warning: Combining Column Lists from Multiple Publications</title>
+ <para>
+ There's currently no support for subscriptions comprising several
+ publications where the same table has been published with different
+ column lists. <xref linkend="sql-createsubscription"/> disallows
+ creating such subscriptions, but it is still possible to get into
+ that situation by adding or altering column lists on the publication
+ side after a subscription has been created.
+ </para>
+ <para>
+ This means changing the column lists of tables on publications that are
+ already subscribed could lead to errors being thrown on the subscriber
+ side.
+ </para>
+ <para>
+ If a subscription is affected by this problem, the only way to resume
+ replication is to adjust one of the column lists on the publication
+ side so that they all match; and then either recreate the subscription,
+ or use <literal>ALTER SUBSCRIPTION ... DROP PUBLICATION</literal> to
+ remove one of the offending publications and add it again.
+ </para>
+ </warning>
+
+ <sect2 id="logical-replication-col-list-examples">
+ <title>Examples</title>
+
+ <para>
+ Create a table <literal>t1</literal> to be used in the following example.
+<programlisting>
+test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id));
+CREATE TABLE
+</programlisting></para>
+
+ <para>
+ Create a publication <literal>p1</literal>. A column list is defined for
+ table <literal>t1</literal> to reduce the number of columns that will be
+ replicated. Notice that the order of column names in the column list does
+ not matter.
+<programlisting>
+test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d);
+CREATE PUBLICATION
+</programlisting></para>
+
+ <para>
+ <literal>psql</literal> can be used to show the column lists (if defined)
+ for each publication.
+<programlisting>
+test_pub=# \dRp+
+ Publication p1
+ Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root
+----------+------------+---------+---------+---------+-----------+----------
+ postgres | f | t | t | t | t | f
+Tables:
+ "public.t1" (id, a, b, d)
+</programlisting></para>
+
+ <para>
+ <literal>psql</literal> can be used to show the column lists (if defined)
+ for each table.
+<programlisting>
+test_pub=# \d t1
+ Table "public.t1"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ id | integer | | not null |
+ a | text | | |
+ b | text | | |
+ c | text | | |
+ d | text | | |
+ e | text | | |
+Indexes:
+ "t1_pkey" PRIMARY KEY, btree (id)
+Publications:
+ "p1" (id, a, b, d)
+</programlisting></para>
+
+ <para>
+ On the subscriber node, create a table <literal>t1</literal> which now
+ only needs a subset of the columns that were on the publisher table
+ <literal>t1</literal>, and also create the subscription
+ <literal>s1</literal> that subscribes to the publication
+ <literal>p1</literal>.
+<programlisting>
+test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id));
+CREATE TABLE
+test_sub=# CREATE SUBSCRIPTION s1
+test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1'
+test_sub-# PUBLICATION p1;
+CREATE SUBSCRIPTION
+</programlisting></para>
+
+ <para>
+ On the publisher node, insert some rows to table <literal>t1</literal>.
+<programlisting>
+test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2');
+INSERT 0 1
+test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3');
+INSERT 0 1
+test_pub=# SELECT * FROM t1 ORDER BY id;
+ id | a | b | c | d | e
+----+-----+-----+-----+-----+-----
+ 1 | a-1 | b-1 | c-1 | d-1 | e-1
+ 2 | a-2 | b-2 | c-2 | d-2 | e-2
+ 3 | a-3 | b-3 | c-3 | d-3 | e-3
+(3 rows)
+</programlisting></para>
+
+ <para>
+ Only data from the column list of publication <literal>p1</literal> is
+ replicated.
+<programlisting>
+test_sub=# SELECT * FROM t1 ORDER BY id;
+ id | b | a | d
+----+-----+-----+-----
+ 1 | b-1 | a-1 | d-1
+ 2 | b-2 | a-2 | d-2
+ 3 | b-3 | a-3 | d-3
+(3 rows)
+</programlisting></para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="logical-replication-conflicts">
+ <title>Conflicts</title>
+
+ <para>
+ Logical replication behaves similarly to normal DML operations in that
+ the data will be updated even if it was changed locally on the subscriber
+ node. If incoming data violates any constraints the replication will
+ stop. This is referred to as a <firstterm>conflict</firstterm>. When
+ replicating <command>UPDATE</command> or <command>DELETE</command>
+ operations, missing data will not produce a conflict and such operations
+ will simply be skipped.
+ </para>
+
+ <para>
+ Logical replication operations are performed with the privileges of the role
+ which owns the subscription. Permissions failures on target tables will
+ cause replication conflicts, as will enabled
+ <link linkend="ddl-rowsecurity">row-level security</link> on target tables
+ that the subscription owner is subject to, without regard to whether any
+ policy would ordinarily reject the <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command> or
+ <command>TRUNCATE</command> which is being replicated. This restriction on
+ row-level security may be lifted in a future version of
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ A conflict will produce an error and will stop the replication; it must be
+ resolved manually by the user. Details about the conflict can be found in
+ the subscriber's server log.
+ </para>
+
+ <para>
+ The resolution can be done either by changing data or permissions on the subscriber so
+ that it does not conflict with the incoming change or by skipping the
+ transaction that conflicts with the existing data. When a conflict produces
+ an error, the replication won't proceed, and the logical replication worker will
+ emit the following kind of message to the subscriber's server log:
+<screen>
+ERROR: duplicate key value violates unique constraint "test_pkey"
+DETAIL: Key (c)=(1) already exists.
+CONTEXT: processing remote data for replication origin "pg_16395" during "INSERT" for replication target relation "public.test" in transaction 725 finished at 0/14C0378
+</screen>
+ The LSN of the transaction that contains the change violating the constraint and
+ the replication origin name can be found from the server log (LSN 0/14C0378 and
+ replication origin <literal>pg_16395</literal> in the above case). The
+ transaction that produced the conflict can be skipped by using
+ <command>ALTER SUBSCRIPTION ... SKIP</command> with the finish LSN
+ (i.e., LSN 0/14C0378). The finish LSN could be an LSN at which the transaction
+ is committed or prepared on the publisher. Alternatively, the transaction can
+ also be skipped by calling the <link linkend="pg-replication-origin-advance">
+ <function>pg_replication_origin_advance()</function></link> function.
+ Before using this function, the subscription needs to be disabled temporarily
+ either by <command>ALTER SUBSCRIPTION ... DISABLE</command> or, the
+ subscription can be used with the <literal>disable_on_error</literal> option.
+ Then, you can use <function>pg_replication_origin_advance()</function> function
+ with the <parameter>node_name</parameter> (i.e., <literal>pg_16395</literal>)
+ and the next LSN of the finish LSN (i.e., 0/14C0379). The current position of
+ origins can be seen in the <link linkend="view-pg-replication-origin-status">
+ <structname>pg_replication_origin_status</structname></link> system view.
+ Please note that skipping the whole transaction includes skipping changes that
+ might not violate any constraint. This can easily make the subscriber
+ inconsistent.
+ </para>
+ </sect1>
+
+ <sect1 id="logical-replication-restrictions">
+ <title>Restrictions</title>
+
+ <para>
+ Logical replication currently has the following restrictions or missing
+ functionality. These might be addressed in future releases.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The database schema and DDL commands are not replicated. The initial
+ schema can be copied by hand using <literal>pg_dump
+ --schema-only</literal>. Subsequent schema changes would need to be kept
+ in sync manually. (Note, however, that there is no need for the schemas
+ to be absolutely the same on both sides.) Logical replication is robust
+ when schema definitions change in a live database: When the schema is
+ changed on the publisher and replicated data starts arriving at the
+ subscriber but does not fit into the table schema, replication will error
+ until the schema is updated. In many cases, intermittent errors can be
+ avoided by applying additive schema changes to the subscriber first.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Sequence data is not replicated. The data in serial or identity columns
+ backed by sequences will of course be replicated as part of the table,
+ but the sequence itself would still show the start value on the
+ subscriber. If the subscriber is used as a read-only database, then this
+ should typically not be a problem. If, however, some kind of switchover
+ or failover to the subscriber database is intended, then the sequences
+ would need to be updated to the latest values, either by copying the
+ current data from the publisher (perhaps
+ using <command>pg_dump</command>) or by determining a sufficiently high
+ value from the tables themselves.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Replication of <command>TRUNCATE</command> commands is supported, but
+ some care must be taken when truncating groups of tables connected by
+ foreign keys. When replicating a truncate action, the subscriber will
+ truncate the same group of tables that was truncated on the publisher,
+ either explicitly specified or implicitly collected via
+ <literal>CASCADE</literal>, minus tables that are not part of the
+ subscription. This will work correctly if all affected tables are part
+ of the same subscription. But if some tables to be truncated on the
+ subscriber have foreign-key links to tables that are not part of the same
+ (or any) subscription, then the application of the truncate action on the
+ subscriber will fail.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Large objects (see <xref linkend="largeobjects"/>) are not replicated.
+ There is no workaround for that, other than storing data in normal
+ tables.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Replication is only supported by tables, including partitioned tables.
+ Attempts to replicate other types of relations, such as views, materialized
+ views, or foreign tables, will result in an error.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When replicating between partitioned tables, the actual replication
+ originates, by default, from the leaf partitions on the publisher, so
+ partitions on the publisher must also exist on the subscriber as valid
+ target tables. (They could either be leaf partitions themselves, or they
+ could be further subpartitioned, or they could even be independent
+ tables.) Publications can also specify that changes are to be replicated
+ using the identity and schema of the partitioned root table instead of
+ that of the individual leaf partitions in which the changes actually
+ originate (see <link linkend="sql-createpublication"><command>CREATE PUBLICATION</command></link>).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 id="logical-replication-architecture">
+ <title>Architecture</title>
+
+ <para>
+ Logical replication starts by copying a snapshot of the data on the
+ publisher database. Once that is done, changes on the publisher are sent
+ to the subscriber as they occur in real time. The subscriber applies data
+ in the order in which commits were made on the publisher so that
+ transactional consistency is guaranteed for the publications within any
+ single subscription.
+ </para>
+
+ <para>
+ Logical replication is built with an architecture similar to physical
+ streaming replication (see <xref linkend="streaming-replication"/>). It is
+ implemented by <quote>walsender</quote> and <quote>apply</quote>
+ processes. The walsender process starts logical decoding (described
+ in <xref linkend="logicaldecoding"/>) of the WAL and loads the standard
+ logical decoding plugin (pgoutput). The plugin transforms the changes read
+ from WAL to the logical replication protocol
+ (see <xref linkend="protocol-logical-replication"/>) and filters the data
+ according to the publication specification. The data is then continuously
+ transferred using the streaming replication protocol to the apply worker,
+ which maps the data to local tables and applies the individual changes as
+ they are received, in correct transactional order.
+ </para>
+
+ <para>
+ The apply process on the subscriber database always runs with
+ <link linkend="guc-session-replication-role"><varname>session_replication_role</varname></link>
+ set to <literal>replica</literal>. This means that, by default,
+ triggers and rules will not fire on a subscriber. Users can optionally choose to
+ enable triggers and rules on a table using the
+ <link linkend="sql-altertable"><command>ALTER TABLE</command></link> command
+ and the <literal>ENABLE TRIGGER</literal> and <literal>ENABLE RULE</literal>
+ clauses.
+ </para>
+
+ <para>
+ The logical replication apply process currently only fires row triggers,
+ not statement triggers. The initial table synchronization, however, is
+ implemented like a <command>COPY</command> command and thus fires both row
+ and statement triggers for <command>INSERT</command>.
+ </para>
+
+ <sect2 id="logical-replication-snapshot">
+ <title>Initial Snapshot</title>
+ <para>
+ The initial data in existing subscribed tables are snapshotted and
+ copied in a parallel instance of a special kind of apply process.
+ This process will create its own replication slot and copy the existing
+ data. As soon as the copy is finished the table contents will become
+ visible to other backends. Once existing data is copied, the worker
+ enters synchronization mode, which ensures that the table is brought
+ up to a synchronized state with the main apply process by streaming
+ any changes that happened during the initial data copy using standard
+ logical replication. During this synchronization phase, the changes
+ are applied and committed in the same order as they happened on the
+ publisher. Once synchronization is done, control of the
+ replication of the table is given back to the main apply process where
+ replication continues as normal.
+ </para>
+ <note>
+ <para>
+ The publication <literal>publish</literal> parameter only affects what
+ DML operations will be replicated. The initial data synchronization does
+ not take this parameter into account when copying the existing table data.
+ </para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 id="logical-replication-monitoring">
+ <title>Monitoring</title>
+
+ <para>
+ Because logical replication is based on a similar architecture as
+ <link linkend="streaming-replication">physical streaming replication</link>,
+ the monitoring on a publication node is similar to monitoring of a
+ physical replication primary
+ (see <xref linkend="streaming-replication-monitoring"/>).
+ </para>
+
+ <para>
+ The monitoring information about subscription is visible in
+ <link linkend="monitoring-pg-stat-subscription">
+ <structname>pg_stat_subscription</structname></link>.
+ This view contains one row for every subscription worker. A subscription
+ can have zero or more active subscription workers depending on its state.
+ </para>
+
+ <para>
+ Normally, there is a single apply process running for an enabled
+ subscription. A disabled subscription or a crashed subscription will have
+ zero rows in this view. If the initial data synchronization of any
+ table is in progress, there will be additional workers for the tables
+ being synchronized.
+ </para>
+ </sect1>
+
+ <sect1 id="logical-replication-security">
+ <title>Security</title>
+
+ <para>
+ A user able to modify the schema of subscriber-side tables can execute
+ arbitrary code as the role which owns any subscription which modifies those tables. Limit ownership
+ and <literal>TRIGGER</literal> privilege on such tables to trusted roles.
+ Moreover, if untrusted users can create tables, use only
+ publications that list tables explicitly. That is to say, create a
+ subscription <literal>FOR ALL TABLES</literal> or
+ <literal>FOR TABLES IN SCHEMA</literal> only when superusers trust
+ every user permitted to create a non-temp table on the publisher or the
+ subscriber.
+ </para>
+
+ <para>
+ The role used for the replication connection must have
+ the <literal>REPLICATION</literal> attribute (or be a superuser). If the
+ role lacks <literal>SUPERUSER</literal> and <literal>BYPASSRLS</literal>,
+ publisher row security policies can execute. If the role does not trust
+ all table owners, include <literal>options=-crow_security=off</literal> in
+ the connection string; if a table owner then adds a row security policy,
+ that setting will cause replication to halt rather than execute the policy.
+ Access for the role must be configured in <filename>pg_hba.conf</filename>
+ and it must have the <literal>LOGIN</literal> attribute.
+ </para>
+
+ <para>
+ In order to be able to copy the initial table data, the role used for the
+ replication connection must have the <literal>SELECT</literal> privilege on
+ a published table (or be a superuser).
+ </para>
+
+ <para>
+ To create a publication, the user must have the <literal>CREATE</literal>
+ privilege in the database.
+ </para>
+
+ <para>
+ To add tables to a publication, the user must have ownership rights on the
+ table. To add all tables in schema to a publication, the user must be a
+ superuser. To create a publication that publishes all tables or all tables in
+ schema automatically, the user must be a superuser.
+ </para>
+
+ <para>
+ To create a subscription, the user must be a superuser.
+ </para>
+
+ <para>
+ The subscription apply process will run in the local database with the
+ privileges of the subscription owner.
+ </para>
+
+ <para>
+ On the publisher, privileges are only checked once at the start of a
+ replication connection and are not re-checked as each change record is read.
+ </para>
+
+ <para>
+ On the subscriber, the subscription owner's privileges are re-checked for
+ each transaction when applied. If a worker is in the process of applying a
+ transaction when the ownership of the subscription is changed by a
+ concurrent transaction, the application of the current transaction will
+ continue under the old owner's privileges.
+ </para>
+ </sect1>
+
+ <sect1 id="logical-replication-config">
+ <title>Configuration Settings</title>
+
+ <para>
+ Logical replication requires several configuration options to be set.
+ </para>
+
+ <para>
+ On the publisher side, <varname>wal_level</varname> must be set to
+ <literal>logical</literal>, and <varname>max_replication_slots</varname>
+ must be set to at least the number of subscriptions expected to connect,
+ plus some reserve for table synchronization. And
+ <varname>max_wal_senders</varname> should be set to at least the same as
+ <varname>max_replication_slots</varname> plus the number of physical
+ replicas that are connected at the same time.
+ </para>
+
+ <para>
+ <varname>max_replication_slots</varname> must also be set on the subscriber.
+ It should be set to at least the number of subscriptions that will be added
+ to the subscriber, plus some reserve for table synchronization.
+ <varname>max_logical_replication_workers</varname> must be set to at least
+ the number of subscriptions, again plus some reserve for the table
+ synchronization. Additionally the <varname>max_worker_processes</varname>
+ may need to be adjusted to accommodate for replication workers, at least
+ (<varname>max_logical_replication_workers</varname>
+ + <literal>1</literal>). Note that some extensions and parallel queries
+ also take worker slots from <varname>max_worker_processes</varname>.
+ </para>
+ </sect1>
+
+ <sect1 id="logical-replication-quick-setup">
+ <title>Quick Setup</title>
+
+ <para>
+ First set the configuration options in <filename>postgresql.conf</filename>:
+<programlisting>
+wal_level = logical
+</programlisting>
+ The other required settings have default values that are sufficient for a
+ basic setup.
+ </para>
+
+ <para>
+ <filename>pg_hba.conf</filename> needs to be adjusted to allow replication
+ (the values here depend on your actual network configuration and user you
+ want to use for connecting):
+<programlisting>
+host all repuser 0.0.0.0/0 md5
+</programlisting>
+ </para>
+
+ <para>
+ Then on the publisher database:
+<programlisting>
+CREATE PUBLICATION mypub FOR TABLE users, departments;
+</programlisting>
+ </para>
+
+ <para>
+ And on the subscriber database:
+<programlisting>
+CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=bar user=repuser' PUBLICATION mypub;
+</programlisting>
+ </para>
+
+ <para>
+ The above will start the replication process, which synchronizes the
+ initial table contents of the tables <literal>users</literal> and
+ <literal>departments</literal> and then starts replicating
+ incremental changes to those tables.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/logicaldecoding.sgml b/doc/src/sgml/logicaldecoding.sgml
new file mode 100644
index 0000000..38ee69d
--- /dev/null
+++ b/doc/src/sgml/logicaldecoding.sgml
@@ -0,0 +1,1355 @@
+<!-- doc/src/sgml/logicaldecoding.sgml -->
+ <chapter id="logicaldecoding">
+ <title>Logical Decoding</title>
+ <indexterm zone="logicaldecoding">
+ <primary>Logical Decoding</primary>
+ </indexterm>
+ <para>
+ PostgreSQL provides infrastructure to stream the modifications performed
+ via SQL to external consumers. This functionality can be used for a
+ variety of purposes, including replication solutions and auditing.
+ </para>
+
+ <para>
+ Changes are sent out in streams identified by logical replication slots.
+ </para>
+
+ <para>
+ The format in which those changes are streamed is determined by the output
+ plugin used. An example plugin is provided in the PostgreSQL distribution.
+ Additional plugins can be
+ written to extend the choice of available formats without modifying any
+ core code.
+ Every output plugin has access to each individual new row produced
+ by <command>INSERT</command> and the new row version created
+ by <command>UPDATE</command>. Availability of old row versions for
+ <command>UPDATE</command> and <command>DELETE</command> depends on
+ the configured replica identity (see <xref linkend="sql-altertable-replica-identity"/>).
+ </para>
+
+ <para>
+ Changes can be consumed either using the streaming replication protocol
+ (see <xref linkend="protocol-replication"/> and
+ <xref linkend="logicaldecoding-walsender"/>), or by calling functions
+ via SQL (see <xref linkend="logicaldecoding-sql"/>). It is also possible
+ to write additional methods of consuming the output of a replication slot
+ without modifying core code
+ (see <xref linkend="logicaldecoding-writer"/>).
+ </para>
+
+ <sect1 id="logicaldecoding-example">
+ <title>Logical Decoding Examples</title>
+
+ <para>
+ The following example demonstrates controlling logical decoding using the
+ SQL interface.
+ </para>
+
+ <para>
+ Before you can use logical decoding, you must set
+ <xref linkend="guc-wal-level"/> to <literal>logical</literal> and
+ <xref linkend="guc-max-replication-slots"/> to at least 1. Then, you
+ should connect to the target database (in the example
+ below, <literal>postgres</literal>) as a superuser.
+ </para>
+
+<programlisting>
+postgres=# -- Create a slot named 'regression_slot' using the output plugin 'test_decoding'
+postgres=# SELECT * FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);
+ slot_name | lsn
+-----------------+-----------
+ regression_slot | 0/16B1970
+(1 row)
+
+postgres=# SELECT slot_name, plugin, slot_type, database, active, restart_lsn, confirmed_flush_lsn FROM pg_replication_slots;
+ slot_name | plugin | slot_type | database | active | restart_lsn | confirmed_flush_lsn
+-----------------+---------------+-----------+----------+--------+-------------+-----------------
+ regression_slot | test_decoding | logical | postgres | f | 0/16A4408 | 0/16A4440
+(1 row)
+
+postgres=# -- There are no changes to see yet
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----+-----+------
+(0 rows)
+
+postgres=# CREATE TABLE data(id serial primary key, data text);
+CREATE TABLE
+
+postgres=# -- DDL isn't replicated, so all you'll see is the transaction
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+--------------
+ 0/BA2DA58 | 10297 | BEGIN 10297
+ 0/BA5A5A0 | 10297 | COMMIT 10297
+(2 rows)
+
+postgres=# -- Once changes are read, they're consumed and not emitted
+postgres=# -- in a subsequent call:
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----+-----+------
+(0 rows)
+
+postgres=# BEGIN;
+postgres=*# INSERT INTO data(data) VALUES('1');
+postgres=*# INSERT INTO data(data) VALUES('2');
+postgres=*# COMMIT;
+
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A688 | 10298 | BEGIN 10298
+ 0/BA5A6F0 | 10298 | table public.data: INSERT: id[integer]:1 data[text]:'1'
+ 0/BA5A7F8 | 10298 | table public.data: INSERT: id[integer]:2 data[text]:'2'
+ 0/BA5A8A8 | 10298 | COMMIT 10298
+(4 rows)
+
+postgres=# INSERT INTO data(data) VALUES('3');
+
+postgres=# -- You can also peek ahead in the change stream without consuming changes
+postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A8E0 | 10299 | BEGIN 10299
+ 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3'
+ 0/BA5A990 | 10299 | COMMIT 10299
+(3 rows)
+
+postgres=# -- The next call to pg_logical_slot_peek_changes() returns the same changes again
+postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A8E0 | 10299 | BEGIN 10299
+ 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3'
+ 0/BA5A990 | 10299 | COMMIT 10299
+(3 rows)
+
+postgres=# -- options can be passed to output plugin, to influence the formatting
+postgres=# SELECT * FROM pg_logical_slot_peek_changes('regression_slot', NULL, NULL, 'include-timestamp', 'on');
+ lsn | xid | data
+-----------+-------+---------------------------------------------------------
+ 0/BA5A8E0 | 10299 | BEGIN 10299
+ 0/BA5A8E0 | 10299 | table public.data: INSERT: id[integer]:3 data[text]:'3'
+ 0/BA5A990 | 10299 | COMMIT 10299 (at 2017-05-10 12:07:21.272494-04)
+(3 rows)
+
+postgres=# -- Remember to destroy a slot you no longer need to stop it consuming
+postgres=# -- server resources:
+postgres=# SELECT pg_drop_replication_slot('regression_slot');
+ pg_drop_replication_slot
+-----------------------
+
+(1 row)
+</programlisting>
+
+ <para>
+ The following examples shows how logical decoding is controlled over the
+ streaming replication protocol, using the
+ program <xref linkend="app-pgrecvlogical"/> included in the PostgreSQL
+ distribution. This requires that client authentication is set up to allow
+ replication connections
+ (see <xref linkend="streaming-replication-authentication"/>) and
+ that <varname>max_wal_senders</varname> is set sufficiently high to allow
+ an additional connection. The second example shows how to stream two-phase
+ transactions. Before you use two-phase commands, you must set
+ <xref linkend="guc-max-prepared-transactions"/> to at least 1.
+ </para>
+<programlisting>
+Example 1:
+$ pg_recvlogical -d postgres --slot=test --create-slot
+$ pg_recvlogical -d postgres --slot=test --start -f -
+<keycombo action="simul"><keycap>Control</keycap><keycap>Z</keycap></keycombo>
+$ psql -d postgres -c "INSERT INTO data(data) VALUES('4');"
+$ fg
+BEGIN 693
+table public.data: INSERT: id[integer]:4 data[text]:'4'
+COMMIT 693
+<keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>
+$ pg_recvlogical -d postgres --slot=test --drop-slot
+
+Example 2:
+$ pg_recvlogical -d postgres --slot=test --create-slot --two-phase
+$ pg_recvlogical -d postgres --slot=test --start -f -
+<keycombo action="simul"><keycap>Control</keycap><keycap>Z</keycap></keycombo>
+$ psql -d postgres -c "BEGIN;INSERT INTO data(data) VALUES('5');PREPARE TRANSACTION 'test';"
+$ fg
+BEGIN 694
+table public.data: INSERT: id[integer]:5 data[text]:'5'
+PREPARE TRANSACTION 'test', txid 694
+<keycombo action="simul"><keycap>Control</keycap><keycap>Z</keycap></keycombo>
+$ psql -d postgres -c "COMMIT PREPARED 'test';"
+$ fg
+COMMIT PREPARED 'test', txid 694
+<keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>
+$ pg_recvlogical -d postgres --slot=test --drop-slot
+</programlisting>
+
+ <para>
+ The following example shows SQL interface that can be used to decode prepared
+ transactions. Before you use two-phase commit commands, you must set
+ <varname>max_prepared_transactions</varname> to at least 1. You must also have
+ set the two-phase parameter as 'true' while creating the slot using
+ <function>pg_create_logical_replication_slot</function>
+ Note that we will stream the entire transaction after the commit if it
+ is not already decoded.
+ </para>
+<programlisting>
+postgres=# BEGIN;
+postgres=*# INSERT INTO data(data) VALUES('5');
+postgres=*# PREPARE TRANSACTION 'test_prepared1';
+
+postgres=# SELECT * FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+---------------------------------------------------------
+ 0/1689DC0 | 529 | BEGIN 529
+ 0/1689DC0 | 529 | table public.data: INSERT: id[integer]:3 data[text]:'5'
+ 0/1689FC0 | 529 | PREPARE TRANSACTION 'test_prepared1', txid 529
+(3 rows)
+
+postgres=# COMMIT PREPARED 'test_prepared1';
+postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+--------------------------------------------
+ 0/168A060 | 529 | COMMIT PREPARED 'test_prepared1', txid 529
+(4 row)
+
+postgres=#-- you can also rollback a prepared transaction
+postgres=# BEGIN;
+postgres=*# INSERT INTO data(data) VALUES('6');
+postgres=*# PREPARE TRANSACTION 'test_prepared2';
+postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+---------------------------------------------------------
+ 0/168A180 | 530 | BEGIN 530
+ 0/168A1E8 | 530 | table public.data: INSERT: id[integer]:4 data[text]:'6'
+ 0/168A430 | 530 | PREPARE TRANSACTION 'test_prepared2', txid 530
+(3 rows)
+
+postgres=# ROLLBACK PREPARED 'test_prepared2';
+postgres=# select * from pg_logical_slot_get_changes('regression_slot', NULL, NULL);
+ lsn | xid | data
+-----------+-----+----------------------------------------------
+ 0/168A4B8 | 530 | ROLLBACK PREPARED 'test_prepared2', txid 530
+(1 row)
+</programlisting>
+</sect1>
+
+ <sect1 id="logicaldecoding-explanation">
+ <title>Logical Decoding Concepts</title>
+ <sect2>
+ <title>Logical Decoding</title>
+
+ <indexterm>
+ <primary>Logical Decoding</primary>
+ </indexterm>
+
+ <para>
+ Logical decoding is the process of extracting all persistent changes
+ to a database's tables into a coherent, easy to understand format which
+ can be interpreted without detailed knowledge of the database's internal
+ state.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname>, logical decoding is implemented
+ by decoding the contents of the <link linkend="wal">write-ahead
+ log</link>, which describe changes on a storage level, into an
+ application-specific form such as a stream of tuples or SQL statements.
+ </para>
+ </sect2>
+
+ <sect2 id="logicaldecoding-replication-slots">
+ <title>Replication Slots</title>
+
+ <indexterm>
+ <primary>replication slot</primary>
+ <secondary>logical replication</secondary>
+ </indexterm>
+
+ <para>
+ In the context of logical replication, a slot represents a stream of
+ changes that can be replayed to a client in the order they were made on
+ the origin server. Each slot streams a sequence of changes from a single
+ database.
+ </para>
+
+ <note>
+ <para><productname>PostgreSQL</productname> also has streaming replication slots
+ (see <xref linkend="streaming-replication"/>), but they are used somewhat
+ differently there.
+ </para>
+ </note>
+
+ <para>
+ A replication slot has an identifier that is unique across all databases
+ in a <productname>PostgreSQL</productname> cluster. Slots persist
+ independently of the connection using them and are crash-safe.
+ </para>
+
+ <para>
+ A logical slot will emit each change just once in normal operation.
+ The current position of each slot is persisted only at checkpoint, so in
+ the case of a crash the slot may return to an earlier LSN, which will
+ then cause recent changes to be sent again when the server restarts.
+ Logical decoding clients are responsible for avoiding ill effects from
+ handling the same message more than once. Clients may wish to record
+ the last LSN they saw when decoding and skip over any repeated data or
+ (when using the replication protocol) request that decoding start from
+ that LSN rather than letting the server determine the start point.
+ The Replication Progress Tracking feature is designed for this purpose,
+ refer to <link linkend="replication-origins">replication origins</link>.
+ </para>
+
+ <para>
+ Multiple independent slots may exist for a single database. Each slot has
+ its own state, allowing different consumers to receive changes from
+ different points in the database change stream. For most applications, a
+ separate slot will be required for each consumer.
+ </para>
+
+ <para>
+ A logical replication slot knows nothing about the state of the
+ receiver(s). It's even possible to have multiple different receivers using
+ the same slot at different times; they'll just get the changes following
+ on from when the last receiver stopped consuming them. Only one receiver
+ may consume changes from a slot at any given time.
+ </para>
+
+ <caution>
+ <para>
+ Replication slots persist across crashes and know nothing about the state
+ of their consumer(s). They will prevent removal of required resources
+ even when there is no connection using them. This consumes storage
+ because neither required WAL nor required rows from the system catalogs
+ can be removed by <command>VACUUM</command> as long as they are required by a replication
+ slot. In extreme cases this could cause the database to shut down to prevent
+ transaction ID wraparound (see <xref linkend="vacuum-for-wraparound"/>).
+ So if a slot is no longer required it should be dropped.
+ </para>
+ </caution>
+ </sect2>
+
+ <sect2>
+ <title>Output Plugins</title>
+ <para>
+ Output plugins transform the data from the write-ahead log's internal
+ representation into the format the consumer of a replication slot desires.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Exported Snapshots</title>
+ <para>
+ When a new replication slot is created using the streaming replication
+ interface (see <xref linkend="protocol-replication-create-replication-slot"/>), a
+ snapshot is exported
+ (see <xref linkend="functions-snapshot-synchronization"/>), which will show
+ exactly the state of the database after which all changes will be
+ included in the change stream. This can be used to create a new replica by
+ using <link linkend="sql-set-transaction"><literal>SET TRANSACTION
+ SNAPSHOT</literal></link> to read the state of the database at the moment
+ the slot was created. This transaction can then be used to dump the
+ database's state at that point in time, which afterwards can be updated
+ using the slot's contents without losing any changes.
+ </para>
+ <para>
+ Creation of a snapshot is not always possible. In particular, it will
+ fail when connected to a hot standby. Applications that do not require
+ snapshot export may suppress it with the <literal>NOEXPORT_SNAPSHOT</literal>
+ option.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="logicaldecoding-walsender">
+ <title>Streaming Replication Protocol Interface</title>
+
+ <para>
+ The commands
+ <itemizedlist>
+ <listitem>
+ <para><literal>CREATE_REPLICATION_SLOT <replaceable>slot_name</replaceable> LOGICAL <replaceable>output_plugin</replaceable></literal></para>
+ </listitem>
+
+ <listitem>
+ <para><literal>DROP_REPLICATION_SLOT <replaceable>slot_name</replaceable></literal> <optional> <literal>WAIT</literal> </optional></para>
+ </listitem>
+
+ <listitem>
+ <para><literal>START_REPLICATION SLOT <replaceable>slot_name</replaceable> LOGICAL ...</literal></para>
+ </listitem>
+ </itemizedlist>
+ are used to create, drop, and stream changes from a replication
+ slot, respectively. These commands are only available over a replication
+ connection; they cannot be used via SQL.
+ See <xref linkend="protocol-replication"/> for details on these commands.
+ </para>
+
+ <para>
+ The command <xref linkend="app-pgrecvlogical"/> can be used to control
+ logical decoding over a streaming replication connection. (It uses
+ these commands internally.)
+ </para>
+ </sect1>
+
+ <sect1 id="logicaldecoding-sql">
+ <title>Logical Decoding <acronym>SQL</acronym> Interface</title>
+
+ <para>
+ See <xref linkend="functions-replication"/> for detailed documentation on
+ the SQL-level API for interacting with logical decoding.
+ </para>
+
+ <para>
+ Synchronous replication (see <xref linkend="synchronous-replication"/>) is
+ only supported on replication slots used over the streaming replication interface. The
+ function interface and additional, non-core interfaces do not support
+ synchronous replication.
+ </para>
+ </sect1>
+
+ <sect1 id="logicaldecoding-catalogs">
+ <title>System Catalogs Related to Logical Decoding</title>
+
+ <para>
+ The <link linkend="view-pg-replication-slots"><structname>pg_replication_slots</structname></link>
+ view and the
+ <link linkend="monitoring-pg-stat-replication-view">
+ <structname>pg_stat_replication</structname></link>
+ view provide information about the current state of replication slots and
+ streaming replication connections respectively. These views apply to both physical and
+ logical replication. The
+ <link linkend="monitoring-pg-stat-replication-slots-view">
+ <structname>pg_stat_replication_slots</structname></link>
+ view provides statistics information about the logical replication slots.
+ </para>
+ </sect1>
+
+ <sect1 id="logicaldecoding-output-plugin">
+ <title>Logical Decoding Output Plugins</title>
+ <para>
+ An example output plugin can be found in the
+ <link linkend="test-decoding">
+ <filename>contrib/test_decoding</filename>
+ </link>
+ subdirectory of the PostgreSQL source tree.
+ </para>
+ <sect2 id="logicaldecoding-output-init">
+ <title>Initialization Function</title>
+ <indexterm zone="logicaldecoding-output-init">
+ <primary>_PG_output_plugin_init</primary>
+ </indexterm>
+ <para>
+ An output plugin is loaded by dynamically loading a shared library with
+ the output plugin's name as the library base name. The normal library
+ search path is used to locate the library. To provide the required output
+ plugin callbacks and to indicate that the library is actually an output
+ plugin it needs to provide a function named
+ <function>_PG_output_plugin_init</function>. This function is passed a
+ struct that needs to be filled with the callback function pointers for
+ individual actions.
+<programlisting>
+typedef struct OutputPluginCallbacks
+{
+ LogicalDecodeStartupCB startup_cb;
+ LogicalDecodeBeginCB begin_cb;
+ LogicalDecodeChangeCB change_cb;
+ LogicalDecodeTruncateCB truncate_cb;
+ LogicalDecodeCommitCB commit_cb;
+ LogicalDecodeMessageCB message_cb;
+ LogicalDecodeFilterByOriginCB filter_by_origin_cb;
+ LogicalDecodeShutdownCB shutdown_cb;
+ LogicalDecodeFilterPrepareCB filter_prepare_cb;
+ LogicalDecodeBeginPrepareCB begin_prepare_cb;
+ LogicalDecodePrepareCB prepare_cb;
+ LogicalDecodeCommitPreparedCB commit_prepared_cb;
+ LogicalDecodeRollbackPreparedCB rollback_prepared_cb;
+ LogicalDecodeStreamStartCB stream_start_cb;
+ LogicalDecodeStreamStopCB stream_stop_cb;
+ LogicalDecodeStreamAbortCB stream_abort_cb;
+ LogicalDecodeStreamPrepareCB stream_prepare_cb;
+ LogicalDecodeStreamCommitCB stream_commit_cb;
+ LogicalDecodeStreamChangeCB stream_change_cb;
+ LogicalDecodeStreamMessageCB stream_message_cb;
+ LogicalDecodeStreamTruncateCB stream_truncate_cb;
+} OutputPluginCallbacks;
+
+typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb);
+</programlisting>
+ The <function>begin_cb</function>, <function>change_cb</function>
+ and <function>commit_cb</function> callbacks are required,
+ while <function>startup_cb</function>,
+ <function>filter_by_origin_cb</function>, <function>truncate_cb</function>,
+ and <function>shutdown_cb</function> are optional.
+ If <function>truncate_cb</function> is not set but a
+ <command>TRUNCATE</command> is to be decoded, the action will be ignored.
+ </para>
+
+ <para>
+ An output plugin may also define functions to support streaming of large,
+ in-progress transactions. The <function>stream_start_cb</function>,
+ <function>stream_stop_cb</function>, <function>stream_abort_cb</function>,
+ <function>stream_commit_cb</function>, <function>stream_change_cb</function>,
+ and <function>stream_prepare_cb</function>
+ are required, while <function>stream_message_cb</function> and
+ <function>stream_truncate_cb</function> are optional.
+ </para>
+
+ <para>
+ An output plugin may also define functions to support two-phase commits,
+ which allows actions to be decoded on the <command>PREPARE TRANSACTION</command>.
+ The <function>begin_prepare_cb</function>, <function>prepare_cb</function>,
+ <function>stream_prepare_cb</function>,
+ <function>commit_prepared_cb</function> and <function>rollback_prepared_cb</function>
+ callbacks are required, while <function>filter_prepare_cb</function> is optional.
+ </para>
+ </sect2>
+
+ <sect2 id="logicaldecoding-capabilities">
+ <title>Capabilities</title>
+
+ <para>
+ To decode, format and output changes, output plugins can use most of the
+ backend's normal infrastructure, including calling output functions. Read
+ only access to relations is permitted as long as only relations are
+ accessed that either have been created by <command>initdb</command> in
+ the <literal>pg_catalog</literal> schema, or have been marked as user
+ provided catalog tables using
+<programlisting>
+ALTER TABLE user_catalog_table SET (user_catalog_table = true);
+CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
+</programlisting>
+ Note that access to user catalog tables or regular system catalog tables
+ in the output plugins has to be done via the <literal>systable_*</literal>
+ scan APIs only. Access via the <literal>heap_*</literal> scan APIs will
+ error out. Additionally, any actions leading to transaction ID assignment
+ are prohibited. That, among others, includes writing to tables, performing
+ DDL changes, and calling <literal>pg_current_xact_id()</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="logicaldecoding-output-mode">
+ <title>Output Modes</title>
+
+ <para>
+ Output plugin callbacks can pass data to the consumer in nearly arbitrary
+ formats. For some use cases, like viewing the changes via SQL, returning
+ data in a data type that can contain arbitrary data (e.g., <type>bytea</type>) is
+ cumbersome. If the output plugin only outputs textual data in the
+ server's encoding, it can declare that by
+ setting <literal>OutputPluginOptions.output_type</literal>
+ to <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal> instead
+ of <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal> in
+ the <link linkend="logicaldecoding-output-plugin-startup">startup
+ callback</link>. In that case, all the data has to be in the server's encoding
+ so that a <type>text</type> datum can contain it. This is checked in assertion-enabled
+ builds.
+ </para>
+ </sect2>
+
+ <sect2 id="logicaldecoding-output-plugin-callbacks">
+ <title>Output Plugin Callbacks</title>
+
+ <para>
+ An output plugin gets notified about changes that are happening via
+ various callbacks it needs to provide.
+ </para>
+
+ <para>
+ Concurrent transactions are decoded in commit order, and only changes
+ belonging to a specific transaction are decoded between
+ the <literal>begin</literal> and <literal>commit</literal>
+ callbacks. Transactions that were rolled back explicitly or implicitly
+ never get
+ decoded. Successful savepoints are
+ folded into the transaction containing them in the order they were
+ executed within that transaction. A transaction that is prepared for
+ a two-phase commit using <command>PREPARE TRANSACTION</command> will
+ also be decoded if the output plugin callbacks needed for decoding
+ them are provided. It is possible that the current prepared transaction
+ which is being decoded is aborted concurrently via a
+ <command>ROLLBACK PREPARED</command> command. In that case, the logical
+ decoding of this transaction will be aborted too. All the changes of such
+ a transaction are skipped once the abort is detected and the
+ <function>prepare_cb</function> callback is invoked. Thus even in case of
+ a concurrent abort, enough information is provided to the output plugin
+ for it to properly deal with <command>ROLLBACK PREPARED</command> once
+ that is decoded.
+ </para>
+
+ <note>
+ <para>
+ Only transactions that have already safely been flushed to disk will be
+ decoded. That can lead to a <command>COMMIT</command> not immediately being decoded in a
+ directly following <literal>pg_logical_slot_get_changes()</literal>
+ when <varname>synchronous_commit</varname> is set
+ to <literal>off</literal>.
+ </para>
+ </note>
+
+ <sect3 id="logicaldecoding-output-plugin-startup">
+ <title>Startup Callback</title>
+ <para>
+ The optional <function>startup_cb</function> callback is called whenever
+ a replication slot is created or asked to stream changes, independent
+ of the number of changes that are ready to be put out.
+<programlisting>
+typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx,
+ OutputPluginOptions *options,
+ bool is_init);
+</programlisting>
+ The <literal>is_init</literal> parameter will be true when the
+ replication slot is being created and false
+ otherwise. <parameter>options</parameter> points to a struct of options
+ that output plugins can set:
+<programlisting>
+typedef struct OutputPluginOptions
+{
+ OutputPluginOutputType output_type;
+ bool receive_rewrites;
+} OutputPluginOptions;
+</programlisting>
+ <literal>output_type</literal> has to either be set to
+ <literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal>
+ or <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal>. See also
+ <xref linkend="logicaldecoding-output-mode"/>.
+ If <literal>receive_rewrites</literal> is true, the output plugin will
+ also be called for changes made by heap rewrites during certain DDL
+ operations. These are of interest to plugins that handle DDL
+ replication, but they require special handling.
+ </para>
+
+ <para>
+ The startup callback should validate the options present in
+ <literal>ctx-&gt;output_plugin_options</literal>. If the output plugin
+ needs to have a state, it can
+ use <literal>ctx-&gt;output_plugin_private</literal> to store it.
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-shutdown">
+ <title>Shutdown Callback</title>
+
+ <para>
+ The optional <function>shutdown_cb</function> callback is called
+ whenever a formerly active replication slot is not used anymore and can
+ be used to deallocate resources private to the output plugin. The slot
+ isn't necessarily being dropped, streaming is just being stopped.
+<programlisting>
+typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-begin">
+ <title>Transaction Begin Callback</title>
+
+ <para>
+ The required <function>begin_cb</function> callback is called whenever a
+ start of a committed transaction has been decoded. Aborted transactions
+ and their contents never get decoded.
+<programlisting>
+typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</programlisting>
+ The <parameter>txn</parameter> parameter contains meta information about
+ the transaction, like the time stamp at which it has been committed and
+ its XID.
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-commit">
+ <title>Transaction End Callback</title>
+
+ <para>
+ The required <function>commit_cb</function> callback is called whenever
+ a transaction commit has been
+ decoded. The <function>change_cb</function> callbacks for all modified
+ rows will have been called before this, if there have been any modified
+ rows.
+<programlisting>
+typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-change">
+ <title>Change Callback</title>
+
+ <para>
+ The required <function>change_cb</function> callback is called for every
+ individual row modification inside a transaction, may it be
+ an <command>INSERT</command>, <command>UPDATE</command>,
+ or <command>DELETE</command>. Even if the original command modified
+ several rows at once the callback will be called individually for each
+ row. The <function>change_cb</function> callback may access system or
+ user catalog tables to aid in the process of outputting the row
+ modification details. In case of decoding a prepared (but yet
+ uncommitted) transaction or decoding of an uncommitted transaction, this
+ change callback might also error out due to simultaneous rollback of
+ this very same transaction. In that case, the logical decoding of this
+ aborted transaction is stopped gracefully.
+<programlisting>
+typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ Relation relation,
+ ReorderBufferChange *change);
+</programlisting>
+ The <parameter>ctx</parameter> and <parameter>txn</parameter> parameters
+ have the same contents as for the <function>begin_cb</function>
+ and <function>commit_cb</function> callbacks, but additionally the
+ relation descriptor <parameter>relation</parameter> points to the
+ relation the row belongs to and a struct
+ <parameter>change</parameter> describing the row modification are passed
+ in.
+ </para>
+
+ <note>
+ <para>
+ Only changes in user defined tables that are not unlogged
+ (see <xref linkend="sql-createtable-unlogged"/>) and not temporary
+ (see <xref linkend="sql-createtable-temporary"/>) can be extracted using
+ logical decoding.
+ </para>
+ </note>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-truncate">
+ <title>Truncate Callback</title>
+
+ <para>
+ The <function>truncate_cb</function> callback is called for a
+ <command>TRUNCATE</command> command.
+<programlisting>
+typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ int nrelations,
+ Relation relations[],
+ ReorderBufferChange *change);
+</programlisting>
+ The parameters are analogous to the <function>change_cb</function>
+ callback. However, because <command>TRUNCATE</command> actions on
+ tables connected by foreign keys need to be executed together, this
+ callback receives an array of relations instead of just a single one.
+ See the description of the <xref linkend="sql-truncate"/> statement for
+ details.
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-filter-origin">
+ <title>Origin Filter Callback</title>
+
+ <para>
+ The optional <function>filter_by_origin_cb</function> callback
+ is called to determine whether data that has been replayed
+ from <parameter>origin_id</parameter> is of interest to the
+ output plugin.
+<programlisting>
+typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx,
+ RepOriginId origin_id);
+</programlisting>
+ The <parameter>ctx</parameter> parameter has the same contents
+ as for the other callbacks. No information but the origin is
+ available. To signal that changes originating on the passed in
+ node are irrelevant, return true, causing them to be filtered
+ away; false otherwise. The other callbacks will not be called
+ for transactions and changes that have been filtered away.
+ </para>
+ <para>
+ This is useful when implementing cascading or multidirectional
+ replication solutions. Filtering by the origin allows to
+ prevent replicating the same changes back and forth in such
+ setups. While transactions and changes also carry information
+ about the origin, filtering via this callback is noticeably
+ more efficient.
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-message">
+ <title>Generic Message Callback</title>
+
+ <para>
+ The optional <function>message_cb</function> callback is called whenever
+ a logical decoding message has been decoded.
+<programlisting>
+typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr message_lsn,
+ bool transactional,
+ const char *prefix,
+ Size message_size,
+ const char *message);
+</programlisting>
+ The <parameter>txn</parameter> parameter contains meta information about
+ the transaction, like the time stamp at which it has been committed and
+ its XID. Note however that it can be NULL when the message is
+ non-transactional and the XID was not assigned yet in the transaction
+ which logged the message. The <parameter>lsn</parameter> has WAL
+ location of the message. The <parameter>transactional</parameter> says
+ if the message was sent as transactional or not. Similar to the change
+ callback, in case of decoding a prepared (but yet uncommitted)
+ transaction or decoding of an uncommitted transaction, this message
+ callback might also error out due to simultaneous rollback of
+ this very same transaction. In that case, the logical decoding of this
+ aborted transaction is stopped gracefully.
+
+ The <parameter>prefix</parameter> is arbitrary null-terminated prefix
+ which can be used for identifying interesting messages for the current
+ plugin. And finally the <parameter>message</parameter> parameter holds
+ the actual message of <parameter>message_size</parameter> size.
+ </para>
+ <para>
+ Extra care should be taken to ensure that the prefix the output plugin
+ considers interesting is unique. Using name of the extension or the
+ output plugin itself is often a good choice.
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-filter-prepare">
+ <title>Prepare Filter Callback</title>
+
+ <para>
+ The optional <function>filter_prepare_cb</function> callback
+ is called to determine whether data that is part of the current
+ two-phase commit transaction should be considered for decoding
+ at this prepare stage or later as a regular one-phase transaction at
+ <command>COMMIT PREPARED</command> time. To signal that
+ decoding should be skipped, return <literal>true</literal>;
+ <literal>false</literal> otherwise. When the callback is not
+ defined, <literal>false</literal> is assumed (i.e. no filtering, all
+ transactions using two-phase commit are decoded in two phases as well).
+<programlisting>
+typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx,
+ TransactionId xid,
+ const char *gid);
+</programlisting>
+ The <parameter>ctx</parameter> parameter has the same contents as for
+ the other callbacks. The parameters <parameter>xid</parameter>
+ and <parameter>gid</parameter> provide two different ways to identify
+ the transaction. The later <command>COMMIT PREPARED</command> or
+ <command>ROLLBACK PREPARED</command> carries both identifiers,
+ providing an output plugin the choice of what to use.
+ </para>
+ <para>
+ The callback may be invoked multiple times per transaction to decode
+ and must provide the same static answer for a given pair of
+ <parameter>xid</parameter> and <parameter>gid</parameter> every time
+ it is called.
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-begin-prepare">
+ <title>Transaction Begin Prepare Callback</title>
+
+ <para>
+ The required <function>begin_prepare_cb</function> callback is called
+ whenever the start of a prepared transaction has been decoded. The
+ <parameter>gid</parameter> field, which is part of the
+ <parameter>txn</parameter> parameter, can be used in this callback to
+ check if the plugin has already received this <command>PREPARE</command>
+ in which case it can either error out or skip the remaining changes of
+ the transaction.
+<programlisting>
+typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-prepare">
+ <title>Transaction Prepare Callback</title>
+
+ <para>
+ The required <function>prepare_cb</function> callback is called whenever
+ a transaction which is prepared for two-phase commit has been
+ decoded. The <function>change_cb</function> callback for all modified
+ rows will have been called before this, if there have been any modified
+ rows. The <parameter>gid</parameter> field, which is part of the
+ <parameter>txn</parameter> parameter, can be used in this callback.
+<programlisting>
+typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_lsn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-commit-prepared">
+ <title>Transaction Commit Prepared Callback</title>
+
+ <para>
+ The required <function>commit_prepared_cb</function> callback is called
+ whenever a transaction <command>COMMIT PREPARED</command> has been decoded.
+ The <parameter>gid</parameter> field, which is part of the
+ <parameter>txn</parameter> parameter, can be used in this callback.
+<programlisting>
+typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-rollback-prepared">
+ <title>Transaction Rollback Prepared Callback</title>
+
+ <para>
+ The required <function>rollback_prepared_cb</function> callback is called
+ whenever a transaction <command>ROLLBACK PREPARED</command> has been
+ decoded. The <parameter>gid</parameter> field, which is part of the
+ <parameter>txn</parameter> parameter, can be used in this callback. The
+ parameters <parameter>prepare_end_lsn</parameter> and
+ <parameter>prepare_time</parameter> can be used to check if the plugin
+ has received this <command>PREPARE TRANSACTION</command> in which case
+ it can apply the rollback, otherwise, it can skip the rollback operation. The
+ <parameter>gid</parameter> alone is not sufficient because the downstream
+ node can have a prepared transaction with same identifier.
+<programlisting>
+typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_end_lsn,
+ TimestampTz prepare_time);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-start">
+ <title>Stream Start Callback</title>
+ <para>
+ The <function>stream_start_cb</function> callback is called when opening
+ a block of streamed changes from an in-progress transaction.
+<programlisting>
+typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-stop">
+ <title>Stream Stop Callback</title>
+ <para>
+ The <function>stream_stop_cb</function> callback is called when closing
+ a block of streamed changes from an in-progress transaction.
+<programlisting>
+typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-abort">
+ <title>Stream Abort Callback</title>
+ <para>
+ The <function>stream_abort_cb</function> callback is called to abort
+ a previously streamed transaction.
+<programlisting>
+typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr abort_lsn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-prepare">
+ <title>Stream Prepare Callback</title>
+ <para>
+ The <function>stream_prepare_cb</function> callback is called to prepare
+ a previously streamed transaction as part of a two-phase commit.
+<programlisting>
+typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr prepare_lsn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-commit">
+ <title>Stream Commit Callback</title>
+ <para>
+ The <function>stream_commit_cb</function> callback is called to commit
+ a previously streamed transaction.
+<programlisting>
+typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr commit_lsn);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-change">
+ <title>Stream Change Callback</title>
+ <para>
+ The <function>stream_change_cb</function> callback is called when sending
+ a change in a block of streamed changes (demarcated by
+ <function>stream_start_cb</function> and <function>stream_stop_cb</function> calls).
+ The actual changes are not displayed as the transaction can abort at a later
+ point in time and we don't decode changes for aborted transactions.
+<programlisting>
+typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ Relation relation,
+ ReorderBufferChange *change);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-message">
+ <title>Stream Message Callback</title>
+ <para>
+ The <function>stream_message_cb</function> callback is called when sending
+ a generic message in a block of streamed changes (demarcated by
+ <function>stream_start_cb</function> and <function>stream_stop_cb</function> calls).
+ The message contents for transactional messages are not displayed as the transaction
+ can abort at a later point in time and we don't decode changes for aborted
+ transactions.
+<programlisting>
+typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ XLogRecPtr message_lsn,
+ bool transactional,
+ const char *prefix,
+ Size message_size,
+ const char *message);
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="logicaldecoding-output-plugin-stream-truncate">
+ <title>Stream Truncate Callback</title>
+ <para>
+ The <function>stream_truncate_cb</function> callback is called for a
+ <command>TRUNCATE</command> command in a block of streamed changes
+ (demarcated by <function>stream_start_cb</function> and
+ <function>stream_stop_cb</function> calls).
+<programlisting>
+typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx,
+ ReorderBufferTXN *txn,
+ int nrelations,
+ Relation relations[],
+ ReorderBufferChange *change);
+</programlisting>
+ The parameters are analogous to the <function>stream_change_cb</function>
+ callback. However, because <command>TRUNCATE</command> actions on
+ tables connected by foreign keys need to be executed together, this
+ callback receives an array of relations instead of just a single one.
+ See the description of the <xref linkend="sql-truncate"/> statement for
+ details.
+ </para>
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="logicaldecoding-output-plugin-output">
+ <title>Functions for Producing Output</title>
+
+ <para>
+ To actually produce output, output plugins can write data to
+ the <literal>StringInfo</literal> output buffer
+ in <literal>ctx-&gt;out</literal> when inside
+ the <function>begin_cb</function>, <function>commit_cb</function>,
+ or <function>change_cb</function> callbacks. Before writing to the output
+ buffer, <function>OutputPluginPrepareWrite(ctx, last_write)</function> has
+ to be called, and after finishing writing to the
+ buffer, <function>OutputPluginWrite(ctx, last_write)</function> has to be
+ called to perform the write. The <parameter>last_write</parameter>
+ indicates whether a particular write was the callback's last write.
+ </para>
+
+ <para>
+ The following example shows how to output data to the consumer of an
+ output plugin:
+<programlisting>
+OutputPluginPrepareWrite(ctx, true);
+appendStringInfo(ctx->out, "BEGIN %u", txn->xid);
+OutputPluginWrite(ctx, true);
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="logicaldecoding-writer">
+ <title>Logical Decoding Output Writers</title>
+
+ <para>
+ It is possible to add more output methods for logical decoding.
+ For details, see
+ <filename>src/backend/replication/logical/logicalfuncs.c</filename>.
+ Essentially, three functions need to be provided: one to read WAL, one to
+ prepare writing output, and one to write the output
+ (see <xref linkend="logicaldecoding-output-plugin-output"/>).
+ </para>
+ </sect1>
+
+ <sect1 id="logicaldecoding-synchronous">
+ <title>Synchronous Replication Support for Logical Decoding</title>
+ <sect2>
+ <title>Overview</title>
+
+ <para>
+ Logical decoding can be used to build
+ <link linkend="synchronous-replication">synchronous
+ replication</link> solutions with the same user interface as synchronous
+ replication for <link linkend="streaming-replication">streaming
+ replication</link>. To do this, the streaming replication interface
+ (see <xref linkend="logicaldecoding-walsender"/>) must be used to stream out
+ data. Clients have to send <literal>Standby status update (F)</literal>
+ (see <xref linkend="protocol-replication"/>) messages, just like streaming
+ replication clients do.
+ </para>
+
+ <note>
+ <para>
+ A synchronous replica receiving changes via logical decoding will work in
+ the scope of a single database. Since, in contrast to
+ that, <parameter>synchronous_standby_names</parameter> currently is
+ server wide, this means this technique will not work properly if more
+ than one database is actively used.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="logicaldecoding-synchronous-caveats">
+ <title>Caveats</title>
+
+ <para>
+ In synchronous replication setup, a deadlock can happen, if the transaction
+ has locked [user] catalog tables exclusively. See
+ <xref linkend="logicaldecoding-capabilities"/> for information on user
+ catalog tables. This is because logical decoding of transactions can lock
+ catalog tables to access them. To avoid this users must refrain from taking
+ an exclusive lock on [user] catalog tables. This can happen in the following
+ ways:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Issuing an explicit <command>LOCK</command> on <structname>pg_class</structname>
+ in a transaction.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Perform <command>CLUSTER</command> on <structname>pg_class</structname> in
+ a transaction.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <command>PREPARE TRANSACTION</command> after <command>LOCK</command> command
+ on <structname>pg_class</structname> and allow logical decoding of two-phase
+ transactions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <command>PREPARE TRANSACTION</command> after <command>CLUSTER</command>
+ command on <structname>pg_trigger</structname> and allow logical decoding of
+ two-phase transactions. This will lead to deadlock only when published table
+ have a trigger.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Executing <command>TRUNCATE</command> on [user] catalog table in a
+ transaction.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Note that these commands that can cause deadlock apply to not only explicitly
+ indicated system catalog tables above but also to any other [user] catalog
+ table.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="logicaldecoding-streaming">
+ <title>Streaming of Large Transactions for Logical Decoding</title>
+
+ <para>
+ The basic output plugin callbacks (e.g., <function>begin_cb</function>,
+ <function>change_cb</function>, <function>commit_cb</function> and
+ <function>message_cb</function>) are only invoked when the transaction
+ actually commits. The changes are still decoded from the transaction
+ log, but are only passed to the output plugin at commit (and discarded
+ if the transaction aborts).
+ </para>
+
+ <para>
+ This means that while the decoding happens incrementally, and may spill
+ to disk to keep memory usage under control, all the decoded changes have
+ to be transmitted when the transaction finally commits (or more precisely,
+ when the commit is decoded from the transaction log). Depending on the
+ size of the transaction and network bandwidth, the transfer time may
+ significantly increase the apply lag.
+ </para>
+
+ <para>
+ To reduce the apply lag caused by large transactions, an output plugin
+ may provide additional callback to support incremental streaming of
+ in-progress transactions. There are multiple required streaming callbacks
+ (<function>stream_start_cb</function>, <function>stream_stop_cb</function>,
+ <function>stream_abort_cb</function>, <function>stream_commit_cb</function>
+ and <function>stream_change_cb</function>) and two optional callbacks
+ (<function>stream_message_cb</function> and <function>stream_truncate_cb</function>).
+ Also, if streaming of two-phase commands is to be supported, then additional
+ callbacks must be provided. (See <xref linkend="logicaldecoding-two-phase-commits"/>
+ for details).
+ </para>
+
+ <para>
+ When streaming an in-progress transaction, the changes (and messages) are
+ streamed in blocks demarcated by <function>stream_start_cb</function>
+ and <function>stream_stop_cb</function> callbacks. Once all the decoded
+ changes are transmitted, the transaction can be committed using the
+ <function>stream_commit_cb</function> callback
+ (or possibly aborted using the <function>stream_abort_cb</function> callback).
+ If two-phase commits are supported, the transaction can be prepared using the
+ <function>stream_prepare_cb</function> callback,
+ <command>COMMIT PREPARED</command> using the
+ <function>commit_prepared_cb</function> callback or aborted using the
+ <function>rollback_prepared_cb</function>.
+ </para>
+
+ <para>
+ One example sequence of streaming callback calls for one transaction may
+ look like this:
+<programlisting>
+stream_start_cb(...); &lt;-- start of first block of changes
+ stream_change_cb(...);
+ stream_change_cb(...);
+ stream_message_cb(...);
+ stream_change_cb(...);
+ ...
+ stream_change_cb(...);
+stream_stop_cb(...); &lt;-- end of first block of changes
+
+stream_start_cb(...); &lt;-- start of second block of changes
+ stream_change_cb(...);
+ stream_change_cb(...);
+ stream_change_cb(...);
+ ...
+ stream_message_cb(...);
+ stream_change_cb(...);
+stream_stop_cb(...); &lt;-- end of second block of changes
+
+
+[a. when using normal commit]
+stream_commit_cb(...); &lt;-- commit of the streamed transaction
+
+[b. when using two-phase commit]
+stream_prepare_cb(...); &lt;-- prepare the streamed transaction
+commit_prepared_cb(...); &lt;-- commit of the prepared transaction
+</programlisting>
+ </para>
+
+ <para>
+ The actual sequence of callback calls may be more complicated, of course.
+ There may be blocks for multiple streamed transactions, some of the
+ transactions may get aborted, etc.
+ </para>
+
+ <para>
+ Similar to spill-to-disk behavior, streaming is triggered when the total
+ amount of changes decoded from the WAL (for all in-progress transactions)
+ exceeds the limit defined by <varname>logical_decoding_work_mem</varname> setting.
+ At that point, the largest top-level transaction (measured by the amount of memory
+ currently used for decoded changes) is selected and streamed. However, in
+ some cases we still have to spill to disk even if streaming is enabled
+ because we exceed the memory threshold but still have not decoded the
+ complete tuple e.g., only decoded toast table insert but not the main table
+ insert.
+ </para>
+
+ <para>
+ Even when streaming large transactions, the changes are still applied in
+ commit order, preserving the same guarantees as the non-streaming mode.
+ </para>
+
+ </sect1>
+
+ <sect1 id="logicaldecoding-two-phase-commits">
+ <title>Two-phase Commit Support for Logical Decoding</title>
+
+ <para>
+ With the basic output plugin callbacks (eg., <function>begin_cb</function>,
+ <function>change_cb</function>, <function>commit_cb</function> and
+ <function>message_cb</function>) two-phase commit commands like
+ <command>PREPARE TRANSACTION</command>, <command>COMMIT PREPARED</command>
+ and <command>ROLLBACK PREPARED</command> are not decoded. While the
+ <command>PREPARE TRANSACTION</command> is ignored,
+ <command>COMMIT PREPARED</command> is decoded as a <command>COMMIT</command>
+ and <command>ROLLBACK PREPARED</command> is decoded as a
+ <command>ROLLBACK</command>.
+ </para>
+
+ <para>
+ To support the streaming of two-phase commands, an output plugin needs to
+ provide additional callbacks. There are multiple two-phase commit callbacks
+ that are required, (<function>begin_prepare_cb</function>,
+ <function>prepare_cb</function>, <function>commit_prepared_cb</function>,
+ <function>rollback_prepared_cb</function> and
+ <function>stream_prepare_cb</function>) and an optional callback
+ (<function>filter_prepare_cb</function>).
+ </para>
+
+ <para>
+ If the output plugin callbacks for decoding two-phase commit commands are
+ provided, then on <command>PREPARE TRANSACTION</command>, the changes of
+ that transaction are decoded, passed to the output plugin, and the
+ <function>prepare_cb</function> callback is invoked. This differs from the
+ basic decoding setup where changes are only passed to the output plugin
+ when a transaction is committed. The start of a prepared transaction is
+ indicated by the <function>begin_prepare_cb</function> callback.
+ </para>
+
+ <para>
+ When a prepared transaction is rolled back using the
+ <command>ROLLBACK PREPARED</command>, then the
+ <function>rollback_prepared_cb</function> callback is invoked and when the
+ prepared transaction is committed using <command>COMMIT PREPARED</command>,
+ then the <function>commit_prepared_cb</function> callback is invoked.
+ </para>
+
+ <para>
+ Optionally the output plugin can define filtering rules via
+ <function>filter_prepare_cb</function> to decode only specific transaction
+ in two phases. This can be achieved by pattern matching on the
+ <parameter>gid</parameter> or via lookups using the
+ <parameter>xid</parameter>.
+ </para>
+
+ <para>
+ The users that want to decode prepared transactions need to be careful about
+ below mentioned points:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If the prepared transaction has locked [user] catalog tables exclusively
+ then decoding prepare can block till the main transaction is committed.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The logical replication solution that builds distributed two phase commit
+ using this feature can deadlock if the prepared transaction has locked
+ [user] catalog tables exclusively. To avoid this users must refrain from
+ having locks on catalog tables (e.g. explicit <command>LOCK</command> command)
+ in such transactions.
+ See <xref linkend="logicaldecoding-synchronous-caveats"/> for the details.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml
new file mode 100644
index 0000000..1543432
--- /dev/null
+++ b/doc/src/sgml/ltree.sgml
@@ -0,0 +1,858 @@
+<!-- doc/src/sgml/ltree.sgml -->
+
+<sect1 id="ltree" xreflabel="ltree">
+ <title>ltree</title>
+
+ <indexterm zone="ltree">
+ <primary>ltree</primary>
+ </indexterm>
+
+ <para>
+ This module implements a data type <type>ltree</type> for representing
+ labels of data stored in a hierarchical tree-like structure.
+ Extensive facilities for searching through label trees are provided.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Definitions</title>
+
+ <para>
+ A <firstterm>label</firstterm> is a sequence of alphanumeric characters
+ and underscores (for example, in C locale the characters
+ <literal>A-Za-z0-9_</literal> are allowed).
+ Labels must be less than 256 characters long.
+ </para>
+
+ <para>
+ Examples: <literal>42</literal>, <literal>Personal_Services</literal>
+ </para>
+
+ <para>
+ A <firstterm>label path</firstterm> is a sequence of zero or more
+ labels separated by dots, for example <literal>L1.L2.L3</literal>, representing
+ a path from the root of a hierarchical tree to a particular node. The
+ length of a label path cannot exceed 65535 labels.
+ </para>
+
+ <para>
+ Example: <literal>Top.Countries.Europe.Russia</literal>
+ </para>
+
+ <para>
+ The <filename>ltree</filename> module provides several data types:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <type>ltree</type> stores a label path.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <type>lquery</type> represents a regular-expression-like pattern
+ for matching <type>ltree</type> values. A simple word matches that
+ label within a path. A star symbol (<literal>*</literal>) matches zero
+ or more labels. These can be joined with dots to form a pattern that
+ must match the whole label path. For example:
+<synopsis>
+foo <lineannotation>Match the exact label path <literal>foo</literal></lineannotation>
+*.foo.* <lineannotation>Match any label path containing the label <literal>foo</literal></lineannotation>
+*.foo <lineannotation>Match any label path whose last label is <literal>foo</literal></lineannotation>
+</synopsis>
+ </para>
+
+ <para>
+ Both star symbols and simple words can be quantified to restrict how many
+ labels they can match:
+<synopsis>
+*{<replaceable>n</replaceable>} <lineannotation>Match exactly <replaceable>n</replaceable> labels</lineannotation>
+*{<replaceable>n</replaceable>,} <lineannotation>Match at least <replaceable>n</replaceable> labels</lineannotation>
+*{<replaceable>n</replaceable>,<replaceable>m</replaceable>} <lineannotation>Match at least <replaceable>n</replaceable> but not more than <replaceable>m</replaceable> labels</lineannotation>
+*{,<replaceable>m</replaceable>} <lineannotation>Match at most <replaceable>m</replaceable> labels &mdash; same as </lineannotation>*{0,<replaceable>m</replaceable>}
+foo{<replaceable>n</replaceable>,<replaceable>m</replaceable>} <lineannotation>Match at least <replaceable>n</replaceable> but not more than <replaceable>m</replaceable> occurrences of <literal>foo</literal></lineannotation>
+foo{,} <lineannotation>Match any number of occurrences of <literal>foo</literal>, including zero</lineannotation>
+</synopsis>
+ In the absence of any explicit quantifier, the default for a star symbol
+ is to match any number of labels (that is, <literal>{,}</literal>) while
+ the default for a non-star item is to match exactly once (that
+ is, <literal>{1}</literal>).
+ </para>
+
+ <para>
+ There are several modifiers that can be put at the end of a non-star
+ <type>lquery</type> item to make it match more than just the exact match:
+<synopsis>
+@ <lineannotation>Match case-insensitively, for example <literal>a@</literal> matches <literal>A</literal></lineannotation>
+* <lineannotation>Match any label with this prefix, for example <literal>foo*</literal> matches <literal>foobar</literal></lineannotation>
+% <lineannotation>Match initial underscore-separated words</lineannotation>
+</synopsis>
+ The behavior of <literal>%</literal> is a bit complicated. It tries to match
+ words rather than the entire label. For example
+ <literal>foo_bar%</literal> matches <literal>foo_bar_baz</literal> but not
+ <literal>foo_barbaz</literal>. If combined with <literal>*</literal>, prefix
+ matching applies to each word separately, for example
+ <literal>foo_bar%*</literal> matches <literal>foo1_bar2_baz</literal> but
+ not <literal>foo1_br2_baz</literal>.
+ </para>
+
+ <para>
+ Also, you can write several possibly-modified non-star items separated with
+ <literal>|</literal> (OR) to match any of those items, and you can put
+ <literal>!</literal> (NOT) at the start of a non-star group to match any
+ label that doesn't match any of the alternatives. A quantifier, if any,
+ goes at the end of the group; it means some number of matches for the
+ group as a whole (that is, some number of labels matching or not matching
+ any of the alternatives).
+ </para>
+
+ <para>
+ Here's an annotated example of <type>lquery</type>:
+<programlisting>
+Top.*{0,2}.sport*@.!football|tennis{1,}.Russ*|Spain
+a. b. c. d. e.
+</programlisting>
+ This query will match any label path that:
+ </para>
+ <orderedlist numeration="loweralpha">
+ <listitem>
+ <para>
+ begins with the label <literal>Top</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ and next has zero to two labels before
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a label beginning with the case-insensitive prefix <literal>sport</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ then has one or more labels, none of which
+ match <literal>football</literal> nor <literal>tennis</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ and then ends with a label beginning with <literal>Russ</literal> or
+ exactly matching <literal>Spain</literal>.
+ </para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+
+ <listitem>
+ <para><type>ltxtquery</type> represents a full-text-search-like
+ pattern for matching <type>ltree</type> values. An
+ <type>ltxtquery</type> value contains words, possibly with the
+ modifiers <literal>@</literal>, <literal>*</literal>, <literal>%</literal> at the end;
+ the modifiers have the same meanings as in <type>lquery</type>.
+ Words can be combined with <literal>&amp;</literal> (AND),
+ <literal>|</literal> (OR), <literal>!</literal> (NOT), and parentheses.
+ The key difference from
+ <type>lquery</type> is that <type>ltxtquery</type> matches words without
+ regard to their position in the label path.
+ </para>
+
+ <para>
+ Here's an example <type>ltxtquery</type>:
+<programlisting>
+Europe &amp; Russia*@ &amp; !Transportation
+</programlisting>
+ This will match paths that contain the label <literal>Europe</literal> and
+ any label beginning with <literal>Russia</literal> (case-insensitive),
+ but not paths containing the label <literal>Transportation</literal>.
+ The location of these words within the path is not important.
+ Also, when <literal>%</literal> is used, the word can be matched to any
+ underscore-separated word within a label, regardless of position.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Note: <type>ltxtquery</type> allows whitespace between symbols, but
+ <type>ltree</type> and <type>lquery</type> do not.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Operators and Functions</title>
+
+ <para>
+ Type <type>ltree</type> has the usual comparison operators
+ <literal>=</literal>, <literal>&lt;&gt;</literal>,
+ <literal>&lt;</literal>, <literal>&gt;</literal>, <literal>&lt;=</literal>, <literal>&gt;=</literal>.
+ Comparison sorts in the order of a tree traversal, with the children
+ of a node sorted by label text. In addition, the specialized
+ operators shown in <xref linkend="ltree-op-table"/> are available.
+ </para>
+
+ <table id="ltree-op-table">
+ <title><type>ltree</type> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>@&gt;</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is left argument an ancestor of right (or equal)?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>&lt;@</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is left argument a descendant of right (or equal)?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>~</literal> <type>lquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>lquery</type> <literal>~</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>ltree</type> match <type>lquery</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>?</literal> <type>lquery[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>lquery[]</type> <literal>?</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>ltree</type> match any <type>lquery</type> in array?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>@</literal> <type>ltxtquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>ltxtquery</type> <literal>@</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>ltree</type> match <type>ltxtquery</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>||</literal> <type>ltree</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Concatenates <type>ltree</type> paths.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree</type> <literal>||</literal> <type>text</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>text</type> <literal>||</literal> <type>ltree</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Converts text to <type>ltree</type> and concatenates.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>@&gt;</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>ltree</type> <literal>&lt;@</literal> <type>ltree[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array contain an ancestor of <type>ltree</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>&lt;@</literal> <type>ltree</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>ltree</type> <literal>@&gt;</literal> <type>ltree[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array contain a descendant of <type>ltree</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>~</literal> <type>lquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>lquery</type> <literal>~</literal> <type>ltree[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array contain any path matching <type>lquery</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>?</literal> <type>lquery[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>lquery[]</type> <literal>?</literal> <type>ltree[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does <type>ltree</type> array contain any path matching
+ any <type>lquery</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>@</literal> <type>ltxtquery</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para role="func_signature">
+ <type>ltxtquery</type> <literal>@</literal> <type>ltree[]</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does array contain any path matching <type>ltxtquery</type>?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>?@&gt;</literal> <type>ltree</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns first array entry that is an ancestor of <type>ltree</type>,
+ or <literal>NULL</literal> if none.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>?&lt;@</literal> <type>ltree</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns first array entry that is a descendant of <type>ltree</type>,
+ or <literal>NULL</literal> if none.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>?~</literal> <type>lquery</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns first array entry that matches <type>lquery</type>,
+ or <literal>NULL</literal> if none.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>ltree[]</type> <literal>?@</literal> <type>ltxtquery</type>
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns first array entry that matches <type>ltxtquery</type>,
+ or <literal>NULL</literal> if none.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The operators <literal>&lt;@</literal>, <literal>@&gt;</literal>,
+ <literal>@</literal> and <literal>~</literal> have analogues
+ <literal>^&lt;@</literal>, <literal>^@&gt;</literal>, <literal>^@</literal>,
+ <literal>^~</literal>, which are the same except they do not use
+ indexes. These are useful only for testing purposes.
+ </para>
+
+ <para>
+ The available functions are shown in <xref linkend="ltree-func-table"/>.
+ </para>
+
+ <table id="ltree-func-table">
+ <title><type>ltree</type> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>subltree</primary></indexterm>
+ <function>subltree</function> ( <type>ltree</type>, <parameter>start</parameter> <type>integer</type>, <parameter>end</parameter> <type>integer</type> )
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns subpath of <type>ltree</type> from
+ position <parameter>start</parameter> to
+ position <parameter>end</parameter>-1 (counting from 0).
+ </para>
+ <para>
+ <literal>subltree('Top.Child1.Child2', 1, 2)</literal>
+ <returnvalue>Child1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>subpath</primary></indexterm>
+ <function>subpath</function> ( <type>ltree</type>, <parameter>offset</parameter> <type>integer</type>, <parameter>len</parameter> <type>integer</type> )
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns subpath of <type>ltree</type> starting at
+ position <parameter>offset</parameter>, with
+ length <parameter>len</parameter>. If <parameter>offset</parameter>
+ is negative, subpath starts that far from the end of the path.
+ If <parameter>len</parameter> is negative, leaves that many labels off
+ the end of the path.
+ </para>
+ <para>
+ <literal>subpath('Top.Child1.Child2', 0, 2)</literal>
+ <returnvalue>Top.Child1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>subpath</function> ( <type>ltree</type>, <parameter>offset</parameter> <type>integer</type> )
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Returns subpath of <type>ltree</type> starting at
+ position <parameter>offset</parameter>, extending to end of path.
+ If <parameter>offset</parameter> is negative, subpath starts that far
+ from the end of the path.
+ </para>
+ <para>
+ <literal>subpath('Top.Child1.Child2', 1)</literal>
+ <returnvalue>Child1.Child2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>nlevel</primary></indexterm>
+ <function>nlevel</function> ( <type>ltree</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns number of labels in path.
+ </para>
+ <para>
+ <literal>nlevel('Top.Child1.Child2')</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>index</primary></indexterm>
+ <function>index</function> ( <parameter>a</parameter> <type>ltree</type>, <parameter>b</parameter> <type>ltree</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns position of first occurrence of <parameter>b</parameter> in
+ <parameter>a</parameter>, or -1 if not found.
+ </para>
+ <para>
+ <literal>index('0.1.2.3.5.4.5.6.8.5.6.8', '5.6')</literal>
+ <returnvalue>6</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>index</function> ( <parameter>a</parameter> <type>ltree</type>, <parameter>b</parameter> <type>ltree</type>, <parameter>offset</parameter> <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns position of first occurrence of <parameter>b</parameter>
+ in <parameter>a</parameter>, or -1 if not found. The search starts at
+ position <parameter>offset</parameter>;
+ negative <parameter>offset</parameter> means
+ start <parameter>-offset</parameter> labels from the end of the path.
+ </para>
+ <para>
+ <literal>index('0.1.2.3.5.4.5.6.8.5.6.8', '5.6', -4)</literal>
+ <returnvalue>9</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>text2ltree</primary></indexterm>
+ <function>text2ltree</function> ( <type>text</type> )
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Casts <type>text</type> to <type>ltree</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>ltree2text</primary></indexterm>
+ <function>ltree2text</function> ( <type>ltree</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Casts <type>ltree</type> to <type>text</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>lca</primary></indexterm>
+ <function>lca</function> ( <type>ltree</type> <optional>, <type>ltree</type> <optional>, ... </optional></optional> )
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Computes longest common ancestor of paths
+ (up to 8 arguments are supported).
+ </para>
+ <para>
+ <literal>lca('1.2.3', '1.2.3.4.5.6')</literal>
+ <returnvalue>1.2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>lca</function> ( <type>ltree[]</type> )
+ <returnvalue>ltree</returnvalue>
+ </para>
+ <para>
+ Computes longest common ancestor of paths in array.
+ </para>
+ <para>
+ <literal>lca(array['1.2.3'::ltree,'1.2.3.4'])</literal>
+ <returnvalue>1.2</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Indexes</title>
+ <para>
+ <filename>ltree</filename> supports several types of indexes that can speed
+ up the indicated operators:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ B-tree index over <type>ltree</type>:
+ <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
+ <literal>&gt;=</literal>, <literal>&gt;</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ GiST index over <type>ltree</type> (<literal>gist_ltree_ops</literal>
+ opclass):
+ <literal>&lt;</literal>, <literal>&lt;=</literal>, <literal>=</literal>,
+ <literal>&gt;=</literal>, <literal>&gt;</literal>,
+ <literal>@&gt;</literal>, <literal>&lt;@</literal>,
+ <literal>@</literal>, <literal>~</literal>, <literal>?</literal>
+ </para>
+ <para>
+ <literal>gist_ltree_ops</literal> GiST opclass approximates a set of
+ path labels as a bitmap signature. Its optional integer parameter
+ <literal>siglen</literal> determines the
+ signature length in bytes. The default signature length is 8 bytes.
+ The length must be a positive multiple of <type>int</type> alignment
+ (4 bytes on most machines)) up to 2024. Longer
+ signatures lead to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </para>
+ <para>
+ Example of creating such an index with the default signature length of 8 bytes:
+ </para>
+<programlisting>
+CREATE INDEX path_gist_idx ON test USING GIST (path);
+</programlisting>
+ <para>
+ Example of creating such an index with a signature length of 100 bytes:
+ </para>
+<programlisting>
+CREATE INDEX path_gist_idx ON test USING GIST (path gist_ltree_ops(siglen=100));
+</programlisting>
+ </listitem>
+ <listitem>
+ <para>
+ GiST index over <type>ltree[]</type> (<literal>gist__ltree_ops</literal>
+ opclass):
+ <literal>ltree[] &lt;@ ltree</literal>, <literal>ltree @&gt; ltree[]</literal>,
+ <literal>@</literal>, <literal>~</literal>, <literal>?</literal>
+ </para>
+ <para>
+ <literal>gist__ltree_ops</literal> GiST opclass works similarly to
+ <literal>gist_ltree_ops</literal> and also takes signature length as
+ a parameter. The default value of <literal>siglen</literal> in
+ <literal>gist__ltree_ops</literal> is 28 bytes.
+ </para>
+ <para>
+ Example of creating such an index with the default signature length of 28 bytes:
+ </para>
+<programlisting>
+CREATE INDEX path_gist_idx ON test USING GIST (array_path);
+</programlisting>
+ <para>
+ Example of creating such an index with a signature length of 100 bytes:
+ </para>
+<programlisting>
+CREATE INDEX path_gist_idx ON test USING GIST (array_path gist__ltree_ops(siglen=100));
+</programlisting>
+ <para>
+ Note: This index type is lossy.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>Example</title>
+
+ <para>
+ This example uses the following data (also available in file
+ <filename>contrib/ltree/ltreetest.sql</filename> in the source distribution):
+ </para>
+
+<programlisting>
+CREATE TABLE test (path ltree);
+INSERT INTO test VALUES ('Top');
+INSERT INTO test VALUES ('Top.Science');
+INSERT INTO test VALUES ('Top.Science.Astronomy');
+INSERT INTO test VALUES ('Top.Science.Astronomy.Astrophysics');
+INSERT INTO test VALUES ('Top.Science.Astronomy.Cosmology');
+INSERT INTO test VALUES ('Top.Hobbies');
+INSERT INTO test VALUES ('Top.Hobbies.Amateurs_Astronomy');
+INSERT INTO test VALUES ('Top.Collections');
+INSERT INTO test VALUES ('Top.Collections.Pictures');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Stars');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Galaxies');
+INSERT INTO test VALUES ('Top.Collections.Pictures.Astronomy.Astronauts');
+CREATE INDEX path_gist_idx ON test USING GIST (path);
+CREATE INDEX path_idx ON test USING BTREE (path);
+</programlisting>
+
+ <para>
+ Now, we have a table <structname>test</structname> populated with data describing
+ the hierarchy shown below:
+ </para>
+
+<literallayout class="monospaced">
+ Top
+ / | \
+ Science Hobbies Collections
+ / | \
+ Astronomy Amateurs_Astronomy Pictures
+ / \ |
+Astrophysics Cosmology Astronomy
+ / | \
+ Galaxies Stars Astronauts
+</literallayout>
+
+ <para>
+ We can do inheritance:
+<screen>
+ltreetest=&gt; SELECT path FROM test WHERE path &lt;@ 'Top.Science';
+ path
+------------------------------------
+ Top.Science
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+(4 rows)
+</screen>
+ </para>
+
+ <para>
+ Here are some examples of path matching:
+<screen>
+ltreetest=&gt; SELECT path FROM test WHERE path ~ '*.Astronomy.*';
+ path
+-----------------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+ Top.Collections.Pictures.Astronomy
+ Top.Collections.Pictures.Astronomy.Stars
+ Top.Collections.Pictures.Astronomy.Galaxies
+ Top.Collections.Pictures.Astronomy.Astronauts
+(7 rows)
+
+ltreetest=&gt; SELECT path FROM test WHERE path ~ '*.!pictures@.Astronomy.*';
+ path
+------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+(3 rows)
+</screen>
+ </para>
+
+ <para>
+ Here are some examples of full text search:
+<screen>
+ltreetest=&gt; SELECT path FROM test WHERE path @ 'Astro*% &amp; !pictures@';
+ path
+------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+ Top.Hobbies.Amateurs_Astronomy
+(4 rows)
+
+ltreetest=&gt; SELECT path FROM test WHERE path @ 'Astro* &amp; !pictures@';
+ path
+------------------------------------
+ Top.Science.Astronomy
+ Top.Science.Astronomy.Astrophysics
+ Top.Science.Astronomy.Cosmology
+(3 rows)
+</screen>
+ </para>
+
+ <para>
+ Path construction using functions:
+<screen>
+ltreetest=&gt; SELECT subpath(path,0,2)||'Space'||subpath(path,2) FROM test WHERE path &lt;@ 'Top.Science.Astronomy';
+ ?column?
+------------------------------------------
+ Top.Science.Space.Astronomy
+ Top.Science.Space.Astronomy.Astrophysics
+ Top.Science.Space.Astronomy.Cosmology
+(3 rows)
+</screen>
+ </para>
+
+ <para>
+ We could simplify this by creating an SQL function that inserts a label
+ at a specified position in a path:
+<screen>
+CREATE FUNCTION ins_label(ltree, int, text) RETURNS ltree
+ AS 'select subpath($1,0,$2) || $3 || subpath($1,$2);'
+ LANGUAGE SQL IMMUTABLE;
+
+ltreetest=&gt; SELECT ins_label(path,2,'Space') FROM test WHERE path &lt;@ 'Top.Science.Astronomy';
+ ins_label
+------------------------------------------
+ Top.Science.Space.Astronomy
+ Top.Science.Space.Astronomy.Astrophysics
+ Top.Science.Space.Astronomy.Cosmology
+(3 rows)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Transforms</title>
+
+ <para>
+ The <literal>ltree_plpython3u</literal> extension implements transforms for
+ the <type>ltree</type> type for PL/Python. If installed and specified when
+ creating a function, <type>ltree</type> values are mapped to Python lists.
+ (The reverse is currently not supported, however.)
+ </para>
+
+ <caution>
+ <para>
+ It is strongly recommended that the transform extension be installed in
+ the same schema as <filename>ltree</filename>. Otherwise there are
+ installation-time security hazards if a transform extension's schema
+ contains objects defined by a hostile user.
+ </para>
+ </caution>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ All work was done by Teodor Sigaev (<email>teodor@stack.net</email>) and
+ Oleg Bartunov (<email>oleg@sai.msu.su</email>). See
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/"></ulink> for
+ additional information. Authors would like to thank Eugeny Rodichev for
+ helpful discussions. Comments and bug reports are welcome.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
new file mode 100644
index 0000000..759ea5a
--- /dev/null
+++ b/doc/src/sgml/maintenance.sgml
@@ -0,0 +1,1116 @@
+<!-- doc/src/sgml/maintenance.sgml -->
+
+<chapter id="maintenance">
+ <title>Routine Database Maintenance Tasks</title>
+
+ <indexterm zone="maintenance">
+ <primary>maintenance</primary>
+ </indexterm>
+
+ <indexterm zone="maintenance">
+ <primary>routine maintenance</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname>, like any database software, requires that certain tasks
+ be performed regularly to achieve optimum performance. The tasks
+ discussed here are <emphasis>required</emphasis>, but they
+ are repetitive in nature and can easily be automated using standard
+ tools such as <application>cron</application> scripts or
+ Windows' <application>Task Scheduler</application>. It is the database
+ administrator's responsibility to set up appropriate scripts, and to
+ check that they execute successfully.
+ </para>
+
+ <para>
+ One obvious maintenance task is the creation of backup copies of the data on a
+ regular schedule. Without a recent backup, you have no chance of recovery
+ after a catastrophe (disk failure, fire, mistakenly dropping a critical
+ table, etc.). The backup and recovery mechanisms available in
+ <productname>PostgreSQL</productname> are discussed at length in
+ <xref linkend="backup"/>.
+ </para>
+
+ <para>
+ The other main category of maintenance task is periodic <quote>vacuuming</quote>
+ of the database. This activity is discussed in
+ <xref linkend="routine-vacuuming"/>. Closely related to this is updating
+ the statistics that will be used by the query planner, as discussed in
+ <xref linkend="vacuum-for-statistics"/>.
+ </para>
+
+ <para>
+ Another task that might need periodic attention is log file management.
+ This is discussed in <xref linkend="logfile-maintenance"/>.
+ </para>
+
+ <para>
+ <ulink
+ url="https://bucardo.org/check_postgres/"><application>check_postgres</application></ulink>
+ is available for monitoring database health and reporting unusual
+ conditions. <application>check_postgres</application> integrates with
+ Nagios and MRTG, but can be run standalone too.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> is low-maintenance compared
+ to some other database management systems. Nonetheless,
+ appropriate attention to these tasks will go far towards ensuring a
+ pleasant and productive experience with the system.
+ </para>
+
+ <sect1 id="routine-vacuuming">
+ <title>Routine Vacuuming</title>
+
+ <indexterm zone="routine-vacuuming">
+ <primary>vacuum</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> databases require periodic
+ maintenance known as <firstterm>vacuuming</firstterm>. For many installations, it
+ is sufficient to let vacuuming be performed by the <firstterm>autovacuum
+ daemon</firstterm>, which is described in <xref linkend="autovacuum"/>. You might
+ need to adjust the autovacuuming parameters described there to obtain best
+ results for your situation. Some database administrators will want to
+ supplement or replace the daemon's activities with manually-managed
+ <command>VACUUM</command> commands, which typically are executed according to a
+ schedule by <application>cron</application> or <application>Task
+ Scheduler</application> scripts. To set up manually-managed vacuuming properly,
+ it is essential to understand the issues discussed in the next few
+ subsections. Administrators who rely on autovacuuming may still wish
+ to skim this material to help them understand and adjust autovacuuming.
+ </para>
+
+ <sect2 id="vacuum-basics">
+ <title>Vacuuming Basics</title>
+
+ <para>
+ <productname>PostgreSQL</productname>'s
+ <link linkend="sql-vacuum"><command>VACUUM</command></link> command has to
+ process each table on a regular basis for several reasons:
+
+ <orderedlist>
+ <listitem>
+ <simpara>To recover or reuse disk space occupied by updated or deleted
+ rows.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>To update data statistics used by the
+ <productname>PostgreSQL</productname> query planner.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>To update the visibility map, which speeds
+ up <link linkend="indexes-index-only-scans">index-only
+ scans</link>.</simpara>
+ </listitem>
+
+ <listitem>
+ <simpara>To protect against loss of very old data due to
+ <firstterm>transaction ID wraparound</firstterm> or
+ <firstterm>multixact ID wraparound</firstterm>.</simpara>
+ </listitem>
+ </orderedlist>
+
+ Each of these reasons dictates performing <command>VACUUM</command> operations
+ of varying frequency and scope, as explained in the following subsections.
+ </para>
+
+ <para>
+ There are two variants of <command>VACUUM</command>: standard <command>VACUUM</command>
+ and <command>VACUUM FULL</command>. <command>VACUUM FULL</command> can reclaim more
+ disk space but runs much more slowly. Also,
+ the standard form of <command>VACUUM</command> can run in parallel with production
+ database operations. (Commands such as <command>SELECT</command>,
+ <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> will continue to function normally, though you
+ will not be able to modify the definition of a table with commands such as
+ <command>ALTER TABLE</command> while it is being vacuumed.)
+ <command>VACUUM FULL</command> requires an
+ <literal>ACCESS EXCLUSIVE</literal> lock on the table it is
+ working on, and therefore cannot be done in parallel with other use
+ of the table. Generally, therefore,
+ administrators should strive to use standard <command>VACUUM</command> and
+ avoid <command>VACUUM FULL</command>.
+ </para>
+
+ <para>
+ <command>VACUUM</command> creates a substantial amount of I/O
+ traffic, which can cause poor performance for other active sessions.
+ There are configuration parameters that can be adjusted to reduce the
+ performance impact of background vacuuming &mdash; see
+ <xref linkend="runtime-config-resource-vacuum-cost"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="vacuum-for-space-recovery">
+ <title>Recovering Disk Space</title>
+
+ <indexterm zone="vacuum-for-space-recovery">
+ <primary>disk space</primary>
+ </indexterm>
+
+ <para>
+ In <productname>PostgreSQL</productname>, an
+ <command>UPDATE</command> or <command>DELETE</command> of a row does not
+ immediately remove the old version of the row.
+ This approach is necessary to gain the benefits of multiversion
+ concurrency control (<acronym>MVCC</acronym>, see <xref linkend="mvcc"/>): the row version
+ must not be deleted while it is still potentially visible to other
+ transactions. But eventually, an outdated or deleted row version is no
+ longer of interest to any transaction. The space it occupies must then be
+ reclaimed for reuse by new rows, to avoid unbounded growth of disk
+ space requirements. This is done by running <command>VACUUM</command>.
+ </para>
+
+ <para>
+ The standard form of <command>VACUUM</command> removes dead row
+ versions in tables and indexes and marks the space available for
+ future reuse. However, it will not return the space to the operating
+ system, except in the special case where one or more pages at the
+ end of a table become entirely free and an exclusive table lock can be
+ easily obtained. In contrast, <command>VACUUM FULL</command> actively compacts
+ tables by writing a complete new version of the table file with no dead
+ space. This minimizes the size of the table, but can take a long time.
+ It also requires extra disk space for the new copy of the table, until
+ the operation completes.
+ </para>
+
+ <para>
+ The usual goal of routine vacuuming is to do standard <command>VACUUM</command>s
+ often enough to avoid needing <command>VACUUM FULL</command>. The
+ autovacuum daemon attempts to work this way, and in fact will
+ never issue <command>VACUUM FULL</command>. In this approach, the idea
+ is not to keep tables at their minimum size, but to maintain steady-state
+ usage of disk space: each table occupies space equivalent to its
+ minimum size plus however much space gets used up between vacuum runs.
+ Although <command>VACUUM FULL</command> can be used to shrink a table back
+ to its minimum size and return the disk space to the operating system,
+ there is not much point in this if the table will just grow again in the
+ future. Thus, moderately-frequent standard <command>VACUUM</command> runs are a
+ better approach than infrequent <command>VACUUM FULL</command> runs for
+ maintaining heavily-updated tables.
+ </para>
+
+ <para>
+ Some administrators prefer to schedule vacuuming themselves, for example
+ doing all the work at night when load is low.
+ The difficulty with doing vacuuming according to a fixed schedule
+ is that if a table has an unexpected spike in update activity, it may
+ get bloated to the point that <command>VACUUM FULL</command> is really necessary
+ to reclaim space. Using the autovacuum daemon alleviates this problem,
+ since the daemon schedules vacuuming dynamically in response to update
+ activity. It is unwise to disable the daemon completely unless you
+ have an extremely predictable workload. One possible compromise is
+ to set the daemon's parameters so that it will only react to unusually
+ heavy update activity, thus keeping things from getting out of hand,
+ while scheduled <command>VACUUM</command>s are expected to do the bulk of the
+ work when the load is typical.
+ </para>
+
+ <para>
+ For those not using autovacuum, a typical approach is to schedule a
+ database-wide <command>VACUUM</command> once a day during a low-usage period,
+ supplemented by more frequent vacuuming of heavily-updated tables as
+ necessary. (Some installations with extremely high update rates vacuum
+ their busiest tables as often as once every few minutes.) If you have
+ multiple databases in a cluster, don't forget to
+ <command>VACUUM</command> each one; the program <xref
+ linkend="app-vacuumdb"/> might be helpful.
+ </para>
+
+ <tip>
+ <para>
+ Plain <command>VACUUM</command> may not be satisfactory when
+ a table contains large numbers of dead row versions as a result of
+ massive update or delete activity. If you have such a table and
+ you need to reclaim the excess disk space it occupies, you will need
+ to use <command>VACUUM FULL</command>, or alternatively
+ <link linkend="sql-cluster"><command>CLUSTER</command></link>
+ or one of the table-rewriting variants of
+ <link linkend="sql-altertable"><command>ALTER TABLE</command></link>.
+ These commands rewrite an entire new copy of the table and build
+ new indexes for it. All these options require an
+ <literal>ACCESS EXCLUSIVE</literal> lock. Note that
+ they also temporarily use extra disk space approximately equal to the size
+ of the table, since the old copies of the table and indexes can't be
+ released until the new ones are complete.
+ </para>
+ </tip>
+
+ <tip>
+ <para>
+ If you have a table whose entire contents are deleted on a periodic
+ basis, consider doing it with
+ <link linkend="sql-truncate"><command>TRUNCATE</command></link> rather
+ than using <command>DELETE</command> followed by
+ <command>VACUUM</command>. <command>TRUNCATE</command> removes the
+ entire content of the table immediately, without requiring a
+ subsequent <command>VACUUM</command> or <command>VACUUM
+ FULL</command> to reclaim the now-unused disk space.
+ The disadvantage is that strict MVCC semantics are violated.
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2 id="vacuum-for-statistics">
+ <title>Updating Planner Statistics</title>
+
+ <indexterm zone="vacuum-for-statistics">
+ <primary>statistics</primary>
+ <secondary>of the planner</secondary>
+ </indexterm>
+
+ <indexterm zone="vacuum-for-statistics">
+ <primary>ANALYZE</primary>
+ </indexterm>
+
+ <para>
+ The <productname>PostgreSQL</productname> query planner relies on
+ statistical information about the contents of tables in order to
+ generate good plans for queries. These statistics are gathered by
+ the <link linkend="sql-analyze"><command>ANALYZE</command></link> command,
+ which can be invoked by itself or
+ as an optional step in <command>VACUUM</command>. It is important to have
+ reasonably accurate statistics, otherwise poor choices of plans might
+ degrade database performance.
+ </para>
+
+ <para>
+ The autovacuum daemon, if enabled, will automatically issue
+ <command>ANALYZE</command> commands whenever the content of a table has
+ changed sufficiently. However, administrators might prefer to rely
+ on manually-scheduled <command>ANALYZE</command> operations, particularly
+ if it is known that update activity on a table will not affect the
+ statistics of <quote>interesting</quote> columns. The daemon schedules
+ <command>ANALYZE</command> strictly as a function of the number of rows
+ inserted or updated; it has no knowledge of whether that will lead
+ to meaningful statistical changes.
+ </para>
+
+ <para>
+ Tuples changed in partitions and inheritance children do not trigger
+ analyze on the parent table. If the parent table is empty or rarely
+ changed, it may never be processed by autovacuum, and the statistics for
+ the inheritance tree as a whole won't be collected. It is necessary to
+ run <command>ANALYZE</command> on the parent table manually in order to
+ keep the statistics up to date.
+ </para>
+
+ <para>
+ As with vacuuming for space recovery, frequent updates of statistics
+ are more useful for heavily-updated tables than for seldom-updated
+ ones. But even for a heavily-updated table, there might be no need for
+ statistics updates if the statistical distribution of the data is
+ not changing much. A simple rule of thumb is to think about how much
+ the minimum and maximum values of the columns in the table change.
+ For example, a <type>timestamp</type> column that contains the time
+ of row update will have a constantly-increasing maximum value as
+ rows are added and updated; such a column will probably need more
+ frequent statistics updates than, say, a column containing URLs for
+ pages accessed on a website. The URL column might receive changes just
+ as often, but the statistical distribution of its values probably
+ changes relatively slowly.
+ </para>
+
+ <para>
+ It is possible to run <command>ANALYZE</command> on specific tables and even
+ just specific columns of a table, so the flexibility exists to update some
+ statistics more frequently than others if your application requires it.
+ In practice, however, it is usually best to just analyze the entire
+ database, because it is a fast operation. <command>ANALYZE</command> uses a
+ statistically random sampling of the rows of a table rather than reading
+ every single row.
+ </para>
+
+ <tip>
+ <para>
+ Although per-column tweaking of <command>ANALYZE</command> frequency might not be
+ very productive, you might find it worthwhile to do per-column
+ adjustment of the level of detail of the statistics collected by
+ <command>ANALYZE</command>. Columns that are heavily used in <literal>WHERE</literal>
+ clauses and have highly irregular data distributions might require a
+ finer-grain data histogram than other columns. See <command>ALTER TABLE
+ SET STATISTICS</command>, or change the database-wide default using the <xref
+ linkend="guc-default-statistics-target"/> configuration parameter.
+ </para>
+
+ <para>
+ Also, by default there is limited information available about
+ the selectivity of functions. However, if you create a statistics
+ object or an expression
+ index that uses a function call, useful statistics will be
+ gathered about the function, which can greatly improve query
+ plans that use the expression index.
+ </para>
+ </tip>
+
+ <tip>
+ <para>
+ The autovacuum daemon does not issue <command>ANALYZE</command> commands for
+ foreign tables, since it has no means of determining how often that
+ might be useful. If your queries require statistics on foreign tables
+ for proper planning, it's a good idea to run manually-managed
+ <command>ANALYZE</command> commands on those tables on a suitable schedule.
+ </para>
+ </tip>
+
+ <tip>
+ <para>
+ The autovacuum daemon does not issue <command>ANALYZE</command> commands
+ for partitioned tables. Inheritance parents will only be analyzed if the
+ parent itself is changed - changes to child tables do not trigger
+ autoanalyze on the parent table. If your queries require statistics on
+ parent tables for proper planning, it is necessary to periodically run
+ a manual <command>ANALYZE</command> on those tables to keep the statistics
+ up to date.
+ </para>
+ </tip>
+
+ </sect2>
+
+ <sect2 id="vacuum-for-visibility-map">
+ <title>Updating the Visibility Map</title>
+
+ <para>
+ Vacuum maintains a <link linkend="storage-vm">visibility map</link> for each
+ table to keep track of which pages contain only tuples that are known to be
+ visible to all active transactions (and all future transactions, until the
+ page is again modified). This has two purposes. First, vacuum
+ itself can skip such pages on the next run, since there is nothing to
+ clean up.
+ </para>
+
+ <para>
+ Second, it allows <productname>PostgreSQL</productname> to answer some
+ queries using only the index, without reference to the underlying table.
+ Since <productname>PostgreSQL</productname> indexes don't contain tuple
+ visibility information, a normal index scan fetches the heap tuple for each
+ matching index entry, to check whether it should be seen by the current
+ transaction.
+ An <link linkend="indexes-index-only-scans"><firstterm>index-only
+ scan</firstterm></link>, on the other hand, checks the visibility map first.
+ If it's known that all tuples on the page are
+ visible, the heap fetch can be skipped. This is most useful on
+ large data sets where the visibility map can prevent disk accesses.
+ The visibility map is vastly smaller than the heap, so it can easily be
+ cached even when the heap is very large.
+ </para>
+ </sect2>
+
+ <sect2 id="vacuum-for-wraparound">
+ <title>Preventing Transaction ID Wraparound Failures</title>
+
+ <indexterm zone="vacuum-for-wraparound">
+ <primary>transaction ID</primary>
+ <secondary>wraparound</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>wraparound</primary>
+ <secondary>of transaction IDs</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname>'s
+ <link linkend="mvcc-intro">MVCC</link> transaction semantics
+ depend on being able to compare transaction ID (<acronym>XID</acronym>)
+ numbers: a row version with an insertion XID greater than the current
+ transaction's XID is <quote>in the future</quote> and should not be visible
+ to the current transaction. But since transaction IDs have limited size
+ (32 bits) a cluster that runs for a long time (more
+ than 4 billion transactions) would suffer <firstterm>transaction ID
+ wraparound</firstterm>: the XID counter wraps around to zero, and all of a sudden
+ transactions that were in the past appear to be in the future &mdash; which
+ means their output become invisible. In short, catastrophic data loss.
+ (Actually the data is still there, but that's cold comfort if you cannot
+ get at it.) To avoid this, it is necessary to vacuum every table
+ in every database at least once every two billion transactions.
+ </para>
+
+ <para>
+ The reason that periodic vacuuming solves the problem is that
+ <command>VACUUM</command> will mark rows as <emphasis>frozen</emphasis>, indicating that
+ they were inserted by a transaction that committed sufficiently far in
+ the past that the effects of the inserting transaction are certain to be
+ visible to all current and future transactions.
+ Normal XIDs are
+ compared using modulo-2<superscript>32</superscript> arithmetic. This means
+ that for every normal XID, there are two billion XIDs that are
+ <quote>older</quote> and two billion that are <quote>newer</quote>; another
+ way to say it is that the normal XID space is circular with no
+ endpoint. Therefore, once a row version has been created with a particular
+ normal XID, the row version will appear to be <quote>in the past</quote> for
+ the next two billion transactions, no matter which normal XID we are
+ talking about. If the row version still exists after more than two billion
+ transactions, it will suddenly appear to be in the future. To
+ prevent this, <productname>PostgreSQL</productname> reserves a special XID,
+ <literal>FrozenTransactionId</literal>, which does not follow the normal XID
+ comparison rules and is always considered older
+ than every normal XID.
+ Frozen row versions are treated as if the inserting XID were
+ <literal>FrozenTransactionId</literal>, so that they will appear to be
+ <quote>in the past</quote> to all normal transactions regardless of wraparound
+ issues, and so such row versions will be valid until deleted, no matter
+ how long that is.
+ </para>
+
+ <note>
+ <para>
+ In <productname>PostgreSQL</productname> versions before 9.4, freezing was
+ implemented by actually replacing a row's insertion XID
+ with <literal>FrozenTransactionId</literal>, which was visible in the
+ row's <structname>xmin</structname> system column. Newer versions just set a flag
+ bit, preserving the row's original <structname>xmin</structname> for possible
+ forensic use. However, rows with <structname>xmin</structname> equal
+ to <literal>FrozenTransactionId</literal> (2) may still be found
+ in databases <application>pg_upgrade</application>'d from pre-9.4 versions.
+ </para>
+ <para>
+ Also, system catalogs may contain rows with <structname>xmin</structname> equal
+ to <literal>BootstrapTransactionId</literal> (1), indicating that they were
+ inserted during the first phase of <application>initdb</application>.
+ Like <literal>FrozenTransactionId</literal>, this special XID is treated as
+ older than every normal XID.
+ </para>
+ </note>
+
+ <para>
+ <xref linkend="guc-vacuum-freeze-min-age"/>
+ controls how old an XID value has to be before rows bearing that XID will be
+ frozen. Increasing this setting may avoid unnecessary work if the
+ rows that would otherwise be frozen will soon be modified again,
+ but decreasing this setting increases
+ the number of transactions that can elapse before the table must be
+ vacuumed again.
+ </para>
+
+ <para>
+ <command>VACUUM</command> uses the <link linkend="storage-vm">visibility map</link>
+ to determine which pages of a table must be scanned. Normally, it
+ will skip pages that don't have any dead row versions even if those pages
+ might still have row versions with old XID values. Therefore, normal
+ <command>VACUUM</command>s won't always freeze every old row version in the table.
+ When that happens, <command>VACUUM</command> will eventually need to perform an
+ <firstterm>aggressive vacuum</firstterm>, which will freeze all eligible unfrozen
+ XID and MXID values, including those from all-visible but not all-frozen pages.
+ In practice most tables require periodic aggressive vacuuming.
+ <xref linkend="guc-vacuum-freeze-table-age"/>
+ controls when <command>VACUUM</command> does that: all-visible but not all-frozen
+ pages are scanned if the number of transactions that have passed since the
+ last such scan is greater than <varname>vacuum_freeze_table_age</varname> minus
+ <varname>vacuum_freeze_min_age</varname>. Setting
+ <varname>vacuum_freeze_table_age</varname> to 0 forces <command>VACUUM</command> to
+ always use its aggressive strategy.
+ </para>
+
+ <para>
+ The maximum time that a table can go unvacuumed is two billion
+ transactions minus the <varname>vacuum_freeze_min_age</varname> value at
+ the time of the last aggressive vacuum. If it were to go
+ unvacuumed for longer than
+ that, data loss could result. To ensure that this does not happen,
+ autovacuum is invoked on any table that might contain unfrozen rows with
+ XIDs older than the age specified by the configuration parameter <xref
+ linkend="guc-autovacuum-freeze-max-age"/>. (This will happen even if
+ autovacuum is disabled.)
+ </para>
+
+ <para>
+ This implies that if a table is not otherwise vacuumed,
+ autovacuum will be invoked on it approximately once every
+ <varname>autovacuum_freeze_max_age</varname> minus
+ <varname>vacuum_freeze_min_age</varname> transactions.
+ For tables that are regularly vacuumed for space reclamation purposes,
+ this is of little importance. However, for static tables
+ (including tables that receive inserts, but no updates or deletes),
+ there is no need to vacuum for space reclamation, so it can
+ be useful to try to maximize the interval between forced autovacuums
+ on very large static tables. Obviously one can do this either by
+ increasing <varname>autovacuum_freeze_max_age</varname> or decreasing
+ <varname>vacuum_freeze_min_age</varname>.
+ </para>
+
+ <para>
+ The effective maximum for <varname>vacuum_freeze_table_age</varname> is 0.95 *
+ <varname>autovacuum_freeze_max_age</varname>; a setting higher than that will be
+ capped to the maximum. A value higher than
+ <varname>autovacuum_freeze_max_age</varname> wouldn't make sense because an
+ anti-wraparound autovacuum would be triggered at that point anyway, and
+ the 0.95 multiplier leaves some breathing room to run a manual
+ <command>VACUUM</command> before that happens. As a rule of thumb,
+ <command>vacuum_freeze_table_age</command> should be set to a value somewhat
+ below <varname>autovacuum_freeze_max_age</varname>, leaving enough gap so that
+ a regularly scheduled <command>VACUUM</command> or an autovacuum triggered by
+ normal delete and update activity is run in that window. Setting it too
+ close could lead to anti-wraparound autovacuums, even though the table
+ was recently vacuumed to reclaim space, whereas lower values lead to more
+ frequent aggressive vacuuming.
+ </para>
+
+ <para>
+ The sole disadvantage of increasing <varname>autovacuum_freeze_max_age</varname>
+ (and <varname>vacuum_freeze_table_age</varname> along with it) is that
+ the <filename>pg_xact</filename> and <filename>pg_commit_ts</filename>
+ subdirectories of the database cluster will take more space, because it
+ must store the commit status and (if <varname>track_commit_timestamp</varname> is
+ enabled) timestamp of all transactions back to
+ the <varname>autovacuum_freeze_max_age</varname> horizon. The commit status uses
+ two bits per transaction, so if
+ <varname>autovacuum_freeze_max_age</varname> is set to its maximum allowed value
+ of two billion, <filename>pg_xact</filename> can be expected to grow to about half
+ a gigabyte and <filename>pg_commit_ts</filename> to about 20GB. If this
+ is trivial compared to your total database size,
+ setting <varname>autovacuum_freeze_max_age</varname> to its maximum allowed value
+ is recommended. Otherwise, set it depending on what you are willing to
+ allow for <filename>pg_xact</filename> and <filename>pg_commit_ts</filename> storage.
+ (The default, 200 million transactions, translates to about 50MB
+ of <filename>pg_xact</filename> storage and about 2GB of <filename>pg_commit_ts</filename>
+ storage.)
+ </para>
+
+ <para>
+ One disadvantage of decreasing <varname>vacuum_freeze_min_age</varname> is that
+ it might cause <command>VACUUM</command> to do useless work: freezing a row
+ version is a waste of time if the row is modified
+ soon thereafter (causing it to acquire a new XID). So the setting should
+ be large enough that rows are not frozen until they are unlikely to change
+ any more.
+ </para>
+
+ <para>
+ To track the age of the oldest unfrozen XIDs in a database,
+ <command>VACUUM</command> stores XID
+ statistics in the system tables <structname>pg_class</structname> and
+ <structname>pg_database</structname>. In particular,
+ the <structfield>relfrozenxid</structfield> column of a table's
+ <structname>pg_class</structname> row contains the oldest remaining unfrozen
+ XID at the end of the most recent <command>VACUUM</command> that successfully
+ advanced <structfield>relfrozenxid</structfield> (typically the most recent
+ aggressive VACUUM). Similarly, the
+ <structfield>datfrozenxid</structfield> column of a database's
+ <structname>pg_database</structname> row is a lower bound on the unfrozen XIDs
+ appearing in that database &mdash; it is just the minimum of the
+ per-table <structfield>relfrozenxid</structfield> values within the database.
+ A convenient way to
+ examine this information is to execute queries such as:
+
+<programlisting>
+SELECT c.oid::regclass as table_name,
+ greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age
+FROM pg_class c
+LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
+WHERE c.relkind IN ('r', 'm');
+
+SELECT datname, age(datfrozenxid) FROM pg_database;
+</programlisting>
+
+ The <literal>age</literal> column measures the number of transactions from the
+ cutoff XID to the current transaction's XID.
+ </para>
+
+ <tip>
+ <para>
+ When the <command>VACUUM</command> command's <literal>VERBOSE</literal>
+ parameter is specified, <command>VACUUM</command> prints various
+ statistics about the table. This includes information about how
+ <structfield>relfrozenxid</structfield> and
+ <structfield>relminmxid</structfield> advanced. The same details appear
+ in the server log when autovacuum logging (controlled by <xref
+ linkend="guc-log-autovacuum-min-duration"/>) reports on a
+ <command>VACUUM</command> operation executed by autovacuum.
+ </para>
+ </tip>
+
+ <para>
+ <command>VACUUM</command> normally only scans pages that have been modified
+ since the last vacuum, but <structfield>relfrozenxid</structfield> can only be
+ advanced when every page of the table
+ that might contain unfrozen XIDs is scanned. This happens when
+ <structfield>relfrozenxid</structfield> is more than
+ <varname>vacuum_freeze_table_age</varname> transactions old, when
+ <command>VACUUM</command>'s <literal>FREEZE</literal> option is used, or when all
+ pages that are not already all-frozen happen to
+ require vacuuming to remove dead row versions. When <command>VACUUM</command>
+ scans every page in the table that is not already all-frozen, it should
+ set <literal>age(relfrozenxid)</literal> to a value just a little more than the
+ <varname>vacuum_freeze_min_age</varname> setting
+ that was used (more by the number of transactions started since the
+ <command>VACUUM</command> started). <command>VACUUM</command>
+ will set <structfield>relfrozenxid</structfield> to the oldest XID
+ that remains in the table, so it's possible that the final value
+ will be much more recent than strictly required.
+ If no <structfield>relfrozenxid</structfield>-advancing
+ <command>VACUUM</command> is issued on the table until
+ <varname>autovacuum_freeze_max_age</varname> is reached, an autovacuum will soon
+ be forced for the table.
+ </para>
+
+ <para>
+ If for some reason autovacuum fails to clear old XIDs from a table, the
+ system will begin to emit warning messages like this when the database's
+ oldest XIDs reach forty million transactions from the wraparound point:
+
+<programlisting>
+WARNING: database "mydb" must be vacuumed within 39985967 transactions
+HINT: To avoid a database shutdown, execute a database-wide VACUUM in that database.
+</programlisting>
+
+ (A manual <command>VACUUM</command> should fix the problem, as suggested by the
+ hint; but note that the <command>VACUUM</command> must be performed by a
+ superuser, else it will fail to process system catalogs and thus not
+ be able to advance the database's <structfield>datfrozenxid</structfield>.)
+ If these warnings are
+ ignored, the system will shut down and refuse to start any new
+ transactions once there are fewer than three million transactions left
+ until wraparound:
+
+<programlisting>
+ERROR: database is not accepting commands to avoid wraparound data loss in database "mydb"
+HINT: Stop the postmaster and vacuum that database in single-user mode.
+</programlisting>
+
+ The three-million-transaction safety margin exists to let the
+ administrator recover without data loss, by manually executing the
+ required <command>VACUUM</command> commands. However, since the system will not
+ execute commands once it has gone into the safety shutdown mode,
+ the only way to do this is to stop the server and start the server in single-user
+ mode to execute <command>VACUUM</command>. The shutdown mode is not enforced
+ in single-user mode. See the <xref linkend="app-postgres"/> reference
+ page for details about using single-user mode.
+ </para>
+
+ <sect3 id="vacuum-for-multixact-wraparound">
+ <title>Multixacts and Wraparound</title>
+
+ <indexterm>
+ <primary>MultiXactId</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>wraparound</primary>
+ <secondary>of multixact IDs</secondary>
+ </indexterm>
+
+ <para>
+ <firstterm>Multixact IDs</firstterm> are used to support row locking by
+ multiple transactions. Since there is only limited space in a tuple
+ header to store lock information, that information is encoded as
+ a <quote>multiple transaction ID</quote>, or multixact ID for short,
+ whenever there is more than one transaction concurrently locking a
+ row. Information about which transaction IDs are included in any
+ particular multixact ID is stored separately in
+ the <filename>pg_multixact</filename> subdirectory, and only the multixact ID
+ appears in the <structfield>xmax</structfield> field in the tuple header.
+ Like transaction IDs, multixact IDs are implemented as a
+ 32-bit counter and corresponding storage, all of which requires
+ careful aging management, storage cleanup, and wraparound handling.
+ There is a separate storage area which holds the list of members in
+ each multixact, which also uses a 32-bit counter and which must also
+ be managed.
+ </para>
+
+ <para>
+ Whenever <command>VACUUM</command> scans any part of a table, it will replace
+ any multixact ID it encounters which is older than
+ <xref linkend="guc-vacuum-multixact-freeze-min-age"/>
+ by a different value, which can be the zero value, a single
+ transaction ID, or a newer multixact ID. For each table,
+ <structname>pg_class</structname>.<structfield>relminmxid</structfield> stores the oldest
+ possible multixact ID still appearing in any tuple of that table.
+ If this value is older than
+ <xref linkend="guc-vacuum-multixact-freeze-table-age"/>, an aggressive
+ vacuum is forced. As discussed in the previous section, an aggressive
+ vacuum means that only those pages which are known to be all-frozen will
+ be skipped. <function>mxid_age()</function> can be used on
+ <structname>pg_class</structname>.<structfield>relminmxid</structfield> to find its age.
+ </para>
+
+ <para>
+ Aggressive <command>VACUUM</command>s, regardless of what causes
+ them, are <emphasis>guaranteed</emphasis> to be able to advance
+ the table's <structfield>relminmxid</structfield>.
+ Eventually, as all tables in all databases are scanned and their
+ oldest multixact values are advanced, on-disk storage for older
+ multixacts can be removed.
+ </para>
+
+ <para>
+ As a safety device, an aggressive vacuum scan will
+ occur for any table whose multixact-age is greater than <xref
+ linkend="guc-autovacuum-multixact-freeze-max-age"/>. Also, if the
+ storage occupied by multixacts members exceeds 2GB, aggressive vacuum
+ scans will occur more often for all tables, starting with those that
+ have the oldest multixact-age. Both of these kinds of aggressive
+ scans will occur even if autovacuum is nominally disabled.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="autovacuum">
+ <title>The Autovacuum Daemon</title>
+
+ <indexterm>
+ <primary>autovacuum</primary>
+ <secondary>general information</secondary>
+ </indexterm>
+ <para>
+ <productname>PostgreSQL</productname> has an optional but highly
+ recommended feature called <firstterm>autovacuum</firstterm>,
+ whose purpose is to automate the execution of
+ <command>VACUUM</command> and <command>ANALYZE</command> commands.
+ When enabled, autovacuum checks for
+ tables that have had a large number of inserted, updated or deleted
+ tuples. These checks use the statistics collection facility;
+ therefore, autovacuum cannot be used unless <xref
+ linkend="guc-track-counts"/> is set to <literal>true</literal>.
+ In the default configuration, autovacuuming is enabled and the related
+ configuration parameters are appropriately set.
+ </para>
+
+ <para>
+ The <quote>autovacuum daemon</quote> actually consists of multiple processes.
+ There is a persistent daemon process, called the
+ <firstterm>autovacuum launcher</firstterm>, which is in charge of starting
+ <firstterm>autovacuum worker</firstterm> processes for all databases. The
+ launcher will distribute the work across time, attempting to start one
+ worker within each database every <xref linkend="guc-autovacuum-naptime"/>
+ seconds. (Therefore, if the installation has <replaceable>N</replaceable> databases,
+ a new worker will be launched every
+ <varname>autovacuum_naptime</varname>/<replaceable>N</replaceable> seconds.)
+ A maximum of <xref linkend="guc-autovacuum-max-workers"/> worker processes
+ are allowed to run at the same time. If there are more than
+ <varname>autovacuum_max_workers</varname> databases to be processed,
+ the next database will be processed as soon as the first worker finishes.
+ Each worker process will check each table within its database and
+ execute <command>VACUUM</command> and/or <command>ANALYZE</command> as needed.
+ <xref linkend="guc-log-autovacuum-min-duration"/> can be set to monitor
+ autovacuum workers' activity.
+ </para>
+
+ <para>
+ If several large tables all become eligible for vacuuming in a short
+ amount of time, all autovacuum workers might become occupied with
+ vacuuming those tables for a long period. This would result
+ in other tables and databases not being vacuumed until a worker becomes
+ available. There is no limit on how many workers might be in a
+ single database, but workers do try to avoid repeating work that has
+ already been done by other workers. Note that the number of running
+ workers does not count towards <xref linkend="guc-max-connections"/> or
+ <xref linkend="guc-superuser-reserved-connections"/> limits.
+ </para>
+
+ <para>
+ Tables whose <structfield>relfrozenxid</structfield> value is more than
+ <xref linkend="guc-autovacuum-freeze-max-age"/> transactions old are always
+ vacuumed (this also applies to those tables whose freeze max age has
+ been modified via storage parameters; see below). Otherwise, if the
+ number of tuples obsoleted since the last
+ <command>VACUUM</command> exceeds the <quote>vacuum threshold</quote>, the
+ table is vacuumed. The vacuum threshold is defined as:
+<programlisting>
+vacuum threshold = vacuum base threshold + vacuum scale factor * number of tuples
+</programlisting>
+ where the vacuum base threshold is
+ <xref linkend="guc-autovacuum-vacuum-threshold"/>,
+ the vacuum scale factor is
+ <xref linkend="guc-autovacuum-vacuum-scale-factor"/>,
+ and the number of tuples is
+ <structname>pg_class</structname>.<structfield>reltuples</structfield>.
+ </para>
+
+ <para>
+ The table is also vacuumed if the number of tuples inserted since the last
+ vacuum has exceeded the defined insert threshold, which is defined as:
+<programlisting>
+vacuum insert threshold = vacuum base insert threshold + vacuum insert scale factor * number of tuples
+</programlisting>
+ where the vacuum insert base threshold is
+ <xref linkend="guc-autovacuum-vacuum-insert-threshold"/>,
+ and vacuum insert scale factor is
+ <xref linkend="guc-autovacuum-vacuum-insert-scale-factor"/>.
+ Such vacuums may allow portions of the table to be marked as
+ <firstterm>all visible</firstterm> and also allow tuples to be frozen, which
+ can reduce the work required in subsequent vacuums.
+ For tables which receive <command>INSERT</command> operations but no or
+ almost no <command>UPDATE</command>/<command>DELETE</command> operations,
+ it may be beneficial to lower the table's
+ <xref linkend="reloption-autovacuum-freeze-min-age"/> as this may allow
+ tuples to be frozen by earlier vacuums. The number of obsolete tuples and
+ the number of inserted tuples are obtained from the cumulative statistics system;
+ it is a semi-accurate count updated by each <command>UPDATE</command>,
+ <command>DELETE</command> and <command>INSERT</command> operation. (It is
+ only semi-accurate because some information might be lost under heavy
+ load.) If the <structfield>relfrozenxid</structfield> value of the table
+ is more than <varname>vacuum_freeze_table_age</varname> transactions old,
+ an aggressive vacuum is performed to freeze old tuples and advance
+ <structfield>relfrozenxid</structfield>; otherwise, only pages that have been modified
+ since the last vacuum are scanned.
+ </para>
+
+ <para>
+ For analyze, a similar condition is used: the threshold, defined as:
+<programlisting>
+analyze threshold = analyze base threshold + analyze scale factor * number of tuples
+</programlisting>
+ is compared to the total number of tuples inserted, updated, or deleted
+ since the last <command>ANALYZE</command>.
+ </para>
+
+ <para>
+ Partitioned tables are not processed by autovacuum. Statistics
+ should be collected by running a manual <command>ANALYZE</command> when it is
+ first populated, and again whenever the distribution of data in its
+ partitions changes significantly.
+ </para>
+
+ <para>
+ Temporary tables cannot be accessed by autovacuum. Therefore,
+ appropriate vacuum and analyze operations should be performed via
+ session SQL commands.
+ </para>
+
+ <para>
+ The default thresholds and scale factors are taken from
+ <filename>postgresql.conf</filename>, but it is possible to override them
+ (and many other autovacuum control parameters) on a per-table basis; see
+ <xref linkend="sql-createtable-storage-parameters"/> for more information.
+ If a setting has been changed via a table's storage parameters, that value
+ is used when processing that table; otherwise the global settings are
+ used. See <xref linkend="runtime-config-autovacuum"/> for more details on
+ the global settings.
+ </para>
+
+ <para>
+ When multiple workers are running, the autovacuum cost delay parameters
+ (see <xref linkend="runtime-config-resource-vacuum-cost"/>) are
+ <quote>balanced</quote> among all the running workers, so that the
+ total I/O impact on the system is the same regardless of the number
+ of workers actually running. However, any workers processing tables whose
+ per-table <literal>autovacuum_vacuum_cost_delay</literal> or
+ <literal>autovacuum_vacuum_cost_limit</literal> storage parameters have been set
+ are not considered in the balancing algorithm.
+ </para>
+
+ <para>
+ Autovacuum workers generally don't block other commands. If a process
+ attempts to acquire a lock that conflicts with the
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock held by autovacuum, lock
+ acquisition will interrupt the autovacuum. For conflicting lock modes,
+ see <xref linkend="table-lock-compatibility"/>. However, if the autovacuum
+ is running to prevent transaction ID wraparound (i.e., the autovacuum query
+ name in the <structname>pg_stat_activity</structname> view ends with
+ <literal>(to prevent wraparound)</literal>), the autovacuum is not
+ automatically interrupted.
+ </para>
+
+ <warning>
+ <para>
+ Regularly running commands that acquire locks conflicting with a
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock (e.g., ANALYZE) can
+ effectively prevent autovacuums from ever completing.
+ </para>
+ </warning>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="routine-reindex">
+ <title>Routine Reindexing</title>
+
+ <indexterm zone="routine-reindex">
+ <primary>reindex</primary>
+ </indexterm>
+
+ <para>
+ In some situations it is worthwhile to rebuild indexes periodically
+ with the <xref linkend="sql-reindex"/> command or a series of individual
+ rebuilding steps.
+
+ </para>
+
+ <para>
+ B-tree index pages that have become completely empty are reclaimed for
+ re-use. However, there is still a possibility
+ of inefficient use of space: if all but a few index keys on a page have
+ been deleted, the page remains allocated. Therefore, a usage
+ pattern in which most, but not all, keys in each range are eventually
+ deleted will see poor use of space. For such usage patterns,
+ periodic reindexing is recommended.
+ </para>
+
+ <para>
+ The potential for bloat in non-B-tree indexes has not been well
+ researched. It is a good idea to periodically monitor the index's physical
+ size when using any non-B-tree index type.
+ </para>
+
+ <para>
+ Also, for B-tree indexes, a freshly-constructed index is slightly faster to
+ access than one that has been updated many times because logically
+ adjacent pages are usually also physically adjacent in a newly built index.
+ (This consideration does not apply to non-B-tree indexes.) It
+ might be worthwhile to reindex periodically just to improve access speed.
+ </para>
+
+ <para>
+ <xref linkend="sql-reindex"/> can be used safely and easily in all cases.
+ This command requires an <literal>ACCESS EXCLUSIVE</literal> lock by
+ default, hence it is often preferable to execute it with its
+ <literal>CONCURRENTLY</literal> option, which requires only a
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
+ </para>
+ </sect1>
+
+
+ <sect1 id="logfile-maintenance">
+ <title>Log File Maintenance</title>
+
+ <indexterm zone="logfile-maintenance">
+ <primary>server log</primary>
+ <secondary>log file maintenance</secondary>
+ </indexterm>
+
+ <para>
+ It is a good idea to save the database server's log output
+ somewhere, rather than just discarding it via <filename>/dev/null</filename>.
+ The log output is invaluable when diagnosing
+ problems.
+ </para>
+
+ <note>
+ <para>
+ The server log can contain sensitive information and needs to be protected,
+ no matter how or where it is stored, or the destination to which it is routed.
+ For example, some DDL statements might contain plaintext passwords or other
+ authentication details. Logged statements at the <literal>ERROR</literal>
+ level might show the SQL source code for applications
+ and might also contain some parts of data rows. Recording data, events and
+ related information is the intended function of this facility, so this is
+ not a leakage or a bug. Please ensure the server logs are visible only to
+ appropriately authorized people.
+ </para>
+ </note>
+
+ <para>
+ Log output tends to be voluminous
+ (especially at higher debug levels) so you won't want to save it
+ indefinitely. You need to <emphasis>rotate</emphasis> the log files so that
+ new log files are started and old ones removed after a reasonable
+ period of time.
+ </para>
+
+ <para>
+ If you simply direct the <systemitem>stderr</systemitem> of
+ <command>postgres</command> into a
+ file, you will have log output, but
+ the only way to truncate the log file is to stop and restart
+ the server. This might be acceptable if you are using
+ <productname>PostgreSQL</productname> in a development environment,
+ but few production servers would find this behavior acceptable.
+ </para>
+
+ <para>
+ A better approach is to send the server's
+ <systemitem>stderr</systemitem> output to some type of log rotation program.
+ There is a built-in log rotation facility, which you can use by
+ setting the configuration parameter <varname>logging_collector</varname> to
+ <literal>true</literal> in <filename>postgresql.conf</filename>. The control
+ parameters for this program are described in <xref
+ linkend="runtime-config-logging-where"/>. You can also use this approach
+ to capture the log data in machine readable <acronym>CSV</acronym>
+ (comma-separated values) format.
+ </para>
+
+ <para>
+ Alternatively, you might prefer to use an external log rotation
+ program if you have one that you are already using with other
+ server software. For example, the <application>rotatelogs</application>
+ tool included in the <productname>Apache</productname> distribution
+ can be used with <productname>PostgreSQL</productname>. One way to
+ do this is to pipe the server's
+ <systemitem>stderr</systemitem> output to the desired program.
+ If you start the server with
+ <command>pg_ctl</command>, then <systemitem>stderr</systemitem>
+ is already redirected to <systemitem>stdout</systemitem>, so you just need a
+ pipe command, for example:
+
+<programlisting>
+pg_ctl start | rotatelogs /var/log/pgsql_log 86400
+</programlisting>
+ </para>
+
+ <para>
+ You can combine these approaches by setting up <application>logrotate</application>
+ to collect log files produced by <productname>PostgreSQL</productname> built-in
+ logging collector. In this case, the logging collector defines the names and
+ location of the log files, while <application>logrotate</application>
+ periodically archives these files. When initiating log rotation,
+ <application>logrotate</application> must ensure that the application
+ sends further output to the new file. This is commonly done with a
+ <literal>postrotate</literal> script that sends a <literal>SIGHUP</literal>
+ signal to the application, which then reopens the log file.
+ In <productname>PostgreSQL</productname>, you can run <command>pg_ctl</command>
+ with the <literal>logrotate</literal> option instead. When the server receives
+ this command, the server either switches to a new log file or reopens the
+ existing file, depending on the logging configuration
+ (see <xref linkend="runtime-config-logging-where"/>).
+ </para>
+
+ <note>
+ <para>
+ When using static log file names, the server might fail to reopen the log
+ file if the max open file limit is reached or a file table overflow occurs.
+ In this case, log messages are sent to the old log file until a
+ successful log rotation. If <application>logrotate</application> is
+ configured to compress the log file and delete it, the server may lose
+ the messages logged in this time frame. To avoid this issue, you can
+ configure the logging collector to dynamically assign log file names
+ and use a <literal>prerotate</literal> script to ignore open log files.
+ </para>
+ </note>
+
+ <para>
+ Another production-grade approach to managing log output is to
+ send it to <application>syslog</application> and let
+ <application>syslog</application> deal with file rotation. To do this, set the
+ configuration parameter <varname>log_destination</varname> to <literal>syslog</literal>
+ (to log to <application>syslog</application> only) in
+ <filename>postgresql.conf</filename>. Then you can send a <literal>SIGHUP</literal>
+ signal to the <application>syslog</application> daemon whenever you want to force it
+ to start writing a new log file. If you want to automate log
+ rotation, the <application>logrotate</application> program can be
+ configured to work with log files from
+ <application>syslog</application>.
+ </para>
+
+ <para>
+ On many systems, however, <application>syslog</application> is not very reliable,
+ particularly with large log messages; it might truncate or drop messages
+ just when you need them the most. Also, on <productname>Linux</productname>,
+ <application>syslog</application> will flush each message to disk, yielding poor
+ performance. (You can use a <quote><literal>-</literal></quote> at the start of the file name
+ in the <application>syslog</application> configuration file to disable syncing.)
+ </para>
+
+ <para>
+ Note that all the solutions described above take care of starting new
+ log files at configurable intervals, but they do not handle deletion
+ of old, no-longer-useful log files. You will probably want to set
+ up a batch job to periodically delete old log files. Another possibility
+ is to configure the rotation program so that old log files are overwritten
+ cyclically.
+ </para>
+
+ <para>
+ <ulink url="https://pgbadger.darold.net/"><productname>pgBadger</productname></ulink>
+ is an external project that does sophisticated log file analysis.
+ <ulink
+ url="https://bucardo.org/check_postgres/"><productname>check_postgres</productname></ulink>
+ provides Nagios alerts when important messages appear in the log
+ files, as well as detection of many other extraordinary conditions.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/man-stamp b/doc/src/sgml/man-stamp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/src/sgml/man-stamp
diff --git a/doc/src/sgml/man1/clusterdb.1 b/doc/src/sgml/man1/clusterdb.1
new file mode 100644
index 0000000..4e12348
--- /dev/null
+++ b/doc/src/sgml/man1/clusterdb.1
@@ -0,0 +1,252 @@
+'\" t
+.\" Title: clusterdb
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CLUSTERDB" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+clusterdb \- cluster a PostgreSQL database
+.SH "SYNOPSIS"
+.HP \w'\fBclusterdb\fR\ 'u
+\fBclusterdb\fR [\fIconnection\-option\fR...] [\fB\-\-verbose\fR | \fB\-v\fR] [\ \fB\-\-table\fR\ |\ \fB\-t\fR\ \fItable\fR\ ]... [\fIdbname\fR]
+.HP \w'\fBclusterdb\fR\ 'u
+\fBclusterdb\fR [\fIconnection\-option\fR...] [\fB\-\-verbose\fR | \fB\-v\fR] \fB\-\-all\fR | \fB\-a\fR
+.SH "DESCRIPTION"
+.PP
+clusterdb
+is a utility for reclustering tables in a
+PostgreSQL
+database\&. It finds tables that have previously been clustered, and clusters them again on the same index that was last used\&. Tables that have never been clustered are not affected\&.
+.PP
+clusterdb
+is a wrapper around the SQL command
+\fBCLUSTER\fR(7)\&. There is no effective difference between clustering databases via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+clusterdb
+accepts the following command\-line arguments:
+.PP
+\fB\-a\fR
+.br
+\fB\-\-all\fR
+.RS 4
+Cluster all databases\&.
+.RE
+.PP
+\fB[\-d]\fR\fB \fR\fB\fIdbname\fR\fR
+.br
+\fB[\-\-dbname=]\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to be clustered, when
+\fB\-a\fR/\fB\-\-all\fR
+is not used\&. If this is not specified, the database name is read from the environment variable
+\fBPGDATABASE\fR\&. If that is not set, the user name specified for the connection is used\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+clusterdb
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Do not display progress messages\&.
+.RE
+.PP
+\fB\-t \fR\fB\fItable\fR\fR
+.br
+\fB\-\-table=\fR\fB\fItable\fR\fR
+.RS 4
+Cluster
+\fItable\fR
+only\&. Multiple tables can be clustered by writing multiple
+\fB\-t\fR
+switches\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Print detailed information during processing\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+clusterdb
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+clusterdb
+command line arguments, and exit\&.
+.RE
+.PP
+clusterdb
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+clusterdb
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+clusterdb
+will automatically prompt for a password if the server demands password authentication\&. However,
+clusterdb
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-maintenance\-db=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to to discover which databases should be clustered, when
+\fB\-a\fR/\fB\-\-all\fR
+is used\&. If not specified, the
+postgres
+database will be used, or if that does not exist,
+template1
+will be used\&. This can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&. Also, connection string parameters other than the database name itself will be re\-used when connecting to other databases\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATABASE\fR
+.br
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+\fBCLUSTER\fR(7)
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "EXAMPLES"
+.PP
+To cluster the database
+test:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBclusterdb test\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To cluster a single table
+foo
+in a database named
+xyzzy:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBclusterdb \-\-table=foo xyzzy\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBCLUSTER\fR(7)
diff --git a/doc/src/sgml/man1/createdb.1 b/doc/src/sgml/man1/createdb.1
new file mode 100644
index 0000000..c99a8b6
--- /dev/null
+++ b/doc/src/sgml/man1/createdb.1
@@ -0,0 +1,310 @@
+'\" t
+.\" Title: createdb
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATEDB" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+createdb \- create a new PostgreSQL database
+.SH "SYNOPSIS"
+.HP \w'\fBcreatedb\fR\ 'u
+\fBcreatedb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\fIdbname\fR\ [\fIdescription\fR]]
+.SH "DESCRIPTION"
+.PP
+createdb
+creates a new
+PostgreSQL
+database\&.
+.PP
+Normally, the database user who executes this command becomes the owner of the new database\&. However, a different owner can be specified via the
+\fB\-O\fR
+option, if the executing user has appropriate privileges\&.
+.PP
+createdb
+is a wrapper around the
+SQL
+command
+\fBCREATE DATABASE\fR\&. There is no effective difference between creating databases via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+createdb
+accepts the following command\-line arguments:
+.PP
+\fIdbname\fR
+.RS 4
+Specifies the name of the database to be created\&. The name must be unique among all
+PostgreSQL
+databases in this cluster\&. The default is to create a database with the same name as the current system user\&.
+.RE
+.PP
+\fIdescription\fR
+.RS 4
+Specifies a comment to be associated with the newly created database\&.
+.RE
+.PP
+\fB\-D \fR\fB\fItablespace\fR\fR
+.br
+\fB\-\-tablespace=\fR\fB\fItablespace\fR\fR
+.RS 4
+Specifies the default tablespace for the database\&. (This name is processed as a double\-quoted identifier\&.)
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+createdb
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-E \fR\fB\fIencoding\fR\fR
+.br
+\fB\-\-encoding=\fR\fB\fIencoding\fR\fR
+.RS 4
+Specifies the character encoding scheme to be used in this database\&. The character sets supported by the
+PostgreSQL
+server are described in
+Section\ \&24.3.1\&.
+.RE
+.PP
+\fB\-l \fR\fB\fIlocale\fR\fR
+.br
+\fB\-\-locale=\fR\fB\fIlocale\fR\fR
+.RS 4
+Specifies the locale to be used in this database\&. This is equivalent to specifying both
+\fB\-\-lc\-collate\fR
+and
+\fB\-\-lc\-ctype\fR\&.
+.RE
+.PP
+\fB\-\-lc\-collate=\fR\fB\fIlocale\fR\fR
+.RS 4
+Specifies the LC_COLLATE setting to be used in this database\&.
+.RE
+.PP
+\fB\-\-lc\-ctype=\fR\fB\fIlocale\fR\fR
+.RS 4
+Specifies the LC_CTYPE setting to be used in this database\&.
+.RE
+.PP
+\fB\-\-icu\-locale=\fR\fB\fIlocale\fR\fR
+.RS 4
+Specifies the ICU locale ID to be used in this database, if the ICU locale provider is selected\&.
+.RE
+.PP
+\fB\-\-locale\-provider={\fR\fBlibc\fR\fB|\fR\fBicu\fR\fB}\fR
+.RS 4
+Specifies the locale provider for the database\*(Aqs default collation\&.
+.RE
+.PP
+\fB\-O \fR\fB\fIowner\fR\fR
+.br
+\fB\-\-owner=\fR\fB\fIowner\fR\fR
+.RS 4
+Specifies the database user who will own the new database\&. (This name is processed as a double\-quoted identifier\&.)
+.RE
+.PP
+\fB\-S \fR\fB\fItemplate\fR\fR
+.br
+\fB\-\-strategy=\fR\fB\fIstrategy\fR\fR
+.RS 4
+Specifies the database creation strategy\&. See
+CREATE DATABASE STRATEGY
+for more details\&.
+.RE
+.PP
+\fB\-T \fR\fB\fItemplate\fR\fR
+.br
+\fB\-\-template=\fR\fB\fItemplate\fR\fR
+.RS 4
+Specifies the template database from which to build this database\&. (This name is processed as a double\-quoted identifier\&.)
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+createdb
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+createdb
+command line arguments, and exit\&.
+.RE
+.PP
+The options
+\fB\-D\fR,
+\fB\-l\fR,
+\fB\-E\fR,
+\fB\-O\fR, and
+\fB\-T\fR
+correspond to options of the underlying SQL command
+\fBCREATE DATABASE\fR; see there for more information about them\&.
+.PP
+createdb
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or the local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+createdb
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+createdb
+will automatically prompt for a password if the server demands password authentication\&. However,
+createdb
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-maintenance\-db=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to when creating the new database\&. If not specified, the
+postgres
+database will be used; if that does not exist (or if it is the name of the new database being created),
+template1
+will be used\&. This can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATABASE\fR
+.RS 4
+If set, the name of the database to create, unless overridden on the command line\&.
+.RE
+.PP
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters\&.
+\fBPGUSER\fR
+also determines the name of the database to create, if it is not specified on the command line or by
+\fBPGDATABASE\fR\&.
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+CREATE DATABASE (\fBCREATE_DATABASE\fR(7))
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "EXAMPLES"
+.PP
+To create the database
+demo
+using the default database server:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreatedb demo\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create the database
+demo
+using the server on host
+eden, port 5000, using the
+template0
+template database, here is the command\-line command and the underlying SQL command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreatedb \-p 5000 \-h eden \-T template0 \-e demo\fR
+CREATE DATABASE demo TEMPLATE template0;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBdropdb\fR(1), CREATE DATABASE (\fBCREATE_DATABASE\fR(7))
diff --git a/doc/src/sgml/man1/createuser.1 b/doc/src/sgml/man1/createuser.1
new file mode 100644
index 0000000..3e1db12
--- /dev/null
+++ b/doc/src/sgml/man1/createuser.1
@@ -0,0 +1,388 @@
+'\" t
+.\" Title: createuser
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATEUSER" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+createuser \- define a new PostgreSQL user account
+.SH "SYNOPSIS"
+.HP \w'\fBcreateuser\fR\ 'u
+\fBcreateuser\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\fIusername\fR]
+.SH "DESCRIPTION"
+.PP
+createuser
+creates a new
+PostgreSQL
+user (or more precisely, a role)\&. Only superusers and users with
+CREATEROLE
+privilege can create new users, so
+createuser
+must be invoked by someone who can connect as a superuser or a user with
+CREATEROLE
+privilege\&.
+.PP
+If you wish to create a role with the
+SUPERUSER,
+REPLICATION, or
+BYPASSRLS
+privilege, you must connect as a superuser, not merely with
+CREATEROLE
+privilege\&. Being a superuser implies the ability to bypass all access permission checks within the database, so superuser access should not be granted lightly\&.
+CREATEROLE
+also conveys
+very extensive privileges\&.
+.PP
+createuser
+is a wrapper around the
+SQL
+command
+\fBCREATE ROLE\fR\&. There is no effective difference between creating users via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+createuser
+accepts the following command\-line arguments:
+.PP
+\fIusername\fR
+.RS 4
+Specifies the name of the
+PostgreSQL
+user to be created\&. This name must be different from all existing roles in this
+PostgreSQL
+installation\&.
+.RE
+.PP
+\fB\-c \fR\fB\fInumber\fR\fR
+.br
+\fB\-\-connection\-limit=\fR\fB\fInumber\fR\fR
+.RS 4
+Set a maximum number of connections for the new user\&. The default is to set no limit\&.
+.RE
+.PP
+\fB\-d\fR
+.br
+\fB\-\-createdb\fR
+.RS 4
+The new user will be allowed to create databases\&.
+.RE
+.PP
+\fB\-D\fR
+.br
+\fB\-\-no\-createdb\fR
+.RS 4
+The new user will not be allowed to create databases\&. This is the default\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+createuser
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-E\fR
+.br
+\fB\-\-encrypted\fR
+.RS 4
+This option is obsolete but still accepted for backward compatibility\&.
+.RE
+.PP
+\fB\-g \fR\fB\fIrole\fR\fR
+.br
+\fB\-\-role=\fR\fB\fIrole\fR\fR
+.RS 4
+Indicates role to which this role will be added immediately as a new member\&. Multiple roles to which this role will be added as a member can be specified by writing multiple
+\fB\-g\fR
+switches\&.
+.RE
+.PP
+\fB\-i\fR
+.br
+\fB\-\-inherit\fR
+.RS 4
+The new role will automatically inherit privileges of roles it is a member of\&. This is the default\&.
+.RE
+.PP
+\fB\-I\fR
+.br
+\fB\-\-no\-inherit\fR
+.RS 4
+The new role will not automatically inherit privileges of roles it is a member of\&.
+.RE
+.PP
+\fB\-\-interactive\fR
+.RS 4
+Prompt for the user name if none is specified on the command line, and also prompt for whichever of the options
+\fB\-d\fR/\fB\-D\fR,
+\fB\-r\fR/\fB\-R\fR,
+\fB\-s\fR/\fB\-S\fR
+is not specified on the command line\&. (This was the default behavior up to PostgreSQL 9\&.1\&.)
+.RE
+.PP
+\fB\-l\fR
+.br
+\fB\-\-login\fR
+.RS 4
+The new user will be allowed to log in (that is, the user name can be used as the initial session user identifier)\&. This is the default\&.
+.RE
+.PP
+\fB\-L\fR
+.br
+\fB\-\-no\-login\fR
+.RS 4
+The new user will not be allowed to log in\&. (A role without login privilege is still useful as a means of managing database permissions\&.)
+.RE
+.PP
+\fB\-P\fR
+.br
+\fB\-\-pwprompt\fR
+.RS 4
+If given,
+createuser
+will issue a prompt for the password of the new user\&. This is not necessary if you do not plan on using password authentication\&.
+.RE
+.PP
+\fB\-r\fR
+.br
+\fB\-\-createrole\fR
+.RS 4
+The new user will be allowed to create, alter, drop, comment on, change the security label for, and grant or revoke membership in other roles; that is, this user will have
+CREATEROLE
+privilege\&. See
+role creation
+for more details about what capabilities are conferred by this privilege\&.
+.RE
+.PP
+\fB\-R\fR
+.br
+\fB\-\-no\-createrole\fR
+.RS 4
+The new user will not be allowed to create new roles\&. This is the default\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-superuser\fR
+.RS 4
+The new user will be a superuser\&.
+.RE
+.PP
+\fB\-S\fR
+.br
+\fB\-\-no\-superuser\fR
+.RS 4
+The new user will not be a superuser\&. This is the default\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+createuser
+version and exit\&.
+.RE
+.PP
+\fB\-\-replication\fR
+.RS 4
+The new user will have the
+REPLICATION
+privilege, which is described more fully in the documentation for
+CREATE ROLE (\fBCREATE_ROLE\fR(7))\&.
+.RE
+.PP
+\fB\-\-no\-replication\fR
+.RS 4
+The new user will not have the
+REPLICATION
+privilege, which is described more fully in the documentation for
+CREATE ROLE (\fBCREATE_ROLE\fR(7))\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+createuser
+command line arguments, and exit\&.
+.RE
+.PP
+createuser
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as (not the user name to create)\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+createuser
+to prompt for a password (for connecting to the server, not for the password of the new user)\&.
+.sp
+This option is never essential, since
+createuser
+will automatically prompt for a password if the server demands password authentication\&. However,
+createuser
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+CREATE ROLE (\fBCREATE_ROLE\fR(7))
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "EXAMPLES"
+.PP
+To create a user
+joe
+on the default database server:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreateuser joe\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a user
+joe
+on the default database server with prompting for some additional attributes:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreateuser \-\-interactive joe\fR
+Shall the new role be a superuser? (y/n) \fBn\fR
+Shall the new role be allowed to create databases? (y/n) \fBn\fR
+Shall the new role be allowed to create more new roles? (y/n) \fBn\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create the same user
+joe
+using the server on host
+eden, port 5000, with attributes explicitly specified, taking a look at the underlying command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreateuser \-h eden \-p 5000 \-S \-D \-R \-e joe\fR
+CREATE ROLE joe NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create the user
+joe
+as a superuser, and assign a password immediately:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreateuser \-P \-s \-e joe\fR
+Enter password for new role: \fBxyzzy\fR
+Enter it again: \fBxyzzy\fR
+CREATE ROLE joe PASSWORD \*(Aqmd5b5f5ba1a423792b526f799ae4eb3d59e\*(Aq SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In the above example, the new password isn\*(Aqt actually echoed when typed, but we show what was typed for clarity\&. As you see, the password is encrypted before it is sent to the client\&.
+.SH "SEE ALSO"
+\fBdropuser\fR(1), CREATE ROLE (\fBCREATE_ROLE\fR(7))
diff --git a/doc/src/sgml/man1/dropdb.1 b/doc/src/sgml/man1/dropdb.1
new file mode 100644
index 0000000..6be3631
--- /dev/null
+++ b/doc/src/sgml/man1/dropdb.1
@@ -0,0 +1,233 @@
+'\" t
+.\" Title: dropdb
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROPDB" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dropdb \- remove a PostgreSQL database
+.SH "SYNOPSIS"
+.HP \w'\fBdropdb\fR\ 'u
+\fBdropdb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] \fIdbname\fR
+.SH "DESCRIPTION"
+.PP
+dropdb
+destroys an existing
+PostgreSQL
+database\&. The user who executes this command must be a database superuser or the owner of the database\&.
+.PP
+dropdb
+is a wrapper around the
+SQL
+command
+\fBDROP DATABASE\fR\&. There is no effective difference between dropping databases via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+dropdb
+accepts the following command\-line arguments:
+.PP
+\fIdbname\fR
+.RS 4
+Specifies the name of the database to be removed\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+dropdb
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-f\fR
+.br
+\fB\-\-force\fR
+.RS 4
+Attempt to terminate all existing connections to the target database before dropping it\&. See
+DROP DATABASE (\fBDROP_DATABASE\fR(7))
+for more information on this option\&.
+.RE
+.PP
+\fB\-i\fR
+.br
+\fB\-\-interactive\fR
+.RS 4
+Issues a verification prompt before doing anything destructive\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+dropdb
+version and exit\&.
+.RE
+.PP
+\fB\-\-if\-exists\fR
+.RS 4
+Do not throw an error if the database does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+dropdb
+command line arguments, and exit\&.
+.RE
+.PP
+dropdb
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+dropdb
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+dropdb
+will automatically prompt for a password if the server demands password authentication\&. However,
+dropdb
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-maintenance\-db=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to in order to drop the target database\&. If not specified, the
+postgres
+database will be used; if that does not exist (or is the database being dropped),
+template1
+will be used\&. This can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+DROP DATABASE (\fBDROP_DATABASE\fR(7))
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "EXAMPLES"
+.PP
+To destroy the database
+demo
+on the default database server:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBdropdb demo\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To destroy the database
+demo
+using the server on host
+eden, port 5000, with verification and a peek at the underlying command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBdropdb \-p 5000 \-h eden \-i \-e demo\fR
+Database "demo" will be permanently deleted\&.
+Are you sure? (y/n) \fBy\fR
+DROP DATABASE demo;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBcreatedb\fR(1), DROP DATABASE (\fBDROP_DATABASE\fR(7))
diff --git a/doc/src/sgml/man1/dropuser.1 b/doc/src/sgml/man1/dropuser.1
new file mode 100644
index 0000000..d94d4fa
--- /dev/null
+++ b/doc/src/sgml/man1/dropuser.1
@@ -0,0 +1,222 @@
+'\" t
+.\" Title: dropuser
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROPUSER" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dropuser \- remove a PostgreSQL user account
+.SH "SYNOPSIS"
+.HP \w'\fBdropuser\fR\ 'u
+\fBdropuser\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\fIusername\fR]
+.SH "DESCRIPTION"
+.PP
+dropuser
+removes an existing
+PostgreSQL
+user\&. Only superusers and users with the
+CREATEROLE
+privilege can remove
+PostgreSQL
+users\&. (To remove a superuser, you must yourself be a superuser\&.)
+.PP
+dropuser
+is a wrapper around the
+SQL
+command
+\fBDROP ROLE\fR\&. There is no effective difference between dropping users via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+dropuser
+accepts the following command\-line arguments:
+.PP
+\fIusername\fR
+.RS 4
+Specifies the name of the
+PostgreSQL
+user to be removed\&. You will be prompted for a name if none is specified on the command line and the
+\fB\-i\fR/\fB\-\-interactive\fR
+option is used\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+dropuser
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-i\fR
+.br
+\fB\-\-interactive\fR
+.RS 4
+Prompt for confirmation before actually removing the user, and prompt for the user name if none is specified on the command line\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+dropuser
+version and exit\&.
+.RE
+.PP
+\fB\-\-if\-exists\fR
+.RS 4
+Do not throw an error if the user does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+dropuser
+command line arguments, and exit\&.
+.RE
+.PP
+dropuser
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as (not the user name to drop)\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+dropuser
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+dropuser
+will automatically prompt for a password if the server demands password authentication\&. However,
+dropuser
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+DROP ROLE (\fBDROP_ROLE\fR(7))
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "EXAMPLES"
+.PP
+To remove user
+joe
+from the default database server:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBdropuser joe\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To remove user
+joe
+using the server on host
+eden, port 5000, with verification and a peek at the underlying command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBdropuser \-p 5000 \-h eden \-i \-e joe\fR
+Role "joe" will be permanently removed\&.
+Are you sure? (y/n) \fBy\fR
+DROP ROLE joe;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBcreateuser\fR(1), DROP ROLE (\fBDROP_ROLE\fR(7))
diff --git a/doc/src/sgml/man1/ecpg.1 b/doc/src/sgml/man1/ecpg.1
new file mode 100644
index 0000000..6cad06e
--- /dev/null
+++ b/doc/src/sgml/man1/ecpg.1
@@ -0,0 +1,208 @@
+'\" t
+.\" Title: ecpg
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ECPG" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ecpg \- embedded SQL C preprocessor
+.SH "SYNOPSIS"
+.HP \w'\fBecpg\fR\ 'u
+\fBecpg\fR [\fIoption\fR...] \fIfile\fR...
+.SH "DESCRIPTION"
+.PP
+\fBecpg\fR
+is the embedded SQL preprocessor for C programs\&. It converts C programs with embedded SQL statements to normal C code by replacing the SQL invocations with special function calls\&. The output files can then be processed with any C compiler tool chain\&.
+.PP
+\fBecpg\fR
+will convert each input file given on the command line to the corresponding C output file\&. If an input file name does not have any extension,
+\&.pgc
+is assumed\&. The file\*(Aqs extension will be replaced by
+\&.c
+to construct the output file name\&. But the output file name can be overridden using the
+\fB\-o\fR
+option\&.
+.PP
+If an input file name is just
+\-,
+\fBecpg\fR
+reads the program from standard input (and writes to standard output, unless that is overridden with
+\fB\-o\fR)\&.
+.PP
+This reference page does not describe the embedded SQL language\&. See
+Chapter\ \&36
+for more information on that topic\&.
+.SH "OPTIONS"
+.PP
+\fBecpg\fR
+accepts the following command\-line arguments:
+.PP
+\fB\-c\fR
+.RS 4
+Automatically generate certain C code from SQL code\&. Currently, this works for
+EXEC SQL TYPE\&.
+.RE
+.PP
+\fB\-C \fR\fB\fImode\fR\fR
+.RS 4
+Set a compatibility mode\&.
+\fImode\fR
+can be
+INFORMIX,
+INFORMIX_SE, or
+ORACLE\&.
+.RE
+.PP
+\fB\-D \fR\fB\fIsymbol\fR\fR
+.RS 4
+Define a C preprocessor symbol\&.
+.RE
+.PP
+\fB\-h\fR
+.RS 4
+Process header files\&. When this option is specified, the output file extension becomes
+\&.h
+not
+\&.c, and the default input file extension is
+\&.pgh
+not
+\&.pgc\&. Also, the
+\fB\-c\fR
+option is forced on\&.
+.RE
+.PP
+\fB\-i\fR
+.RS 4
+Parse system include files as well\&.
+.RE
+.PP
+\fB\-I \fR\fB\fIdirectory\fR\fR
+.RS 4
+Specify an additional include path, used to find files included via
+EXEC SQL INCLUDE\&. Defaults are
+\&.
+(current directory),
+/usr/local/include, the
+PostgreSQL
+include directory which is defined at compile time (default:
+/usr/local/pgsql/include), and
+/usr/include, in that order\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIfilename\fR\fR
+.RS 4
+Specifies that
+\fBecpg\fR
+should write all its output to the given
+\fIfilename\fR\&. Write
+\-o \-
+to send all output to standard output\&.
+.RE
+.PP
+\fB\-r \fR\fB\fIoption\fR\fR
+.RS 4
+Selects run\-time behavior\&.
+\fIOption\fR
+can be one of the following:
+.PP
+\fBno_indicator\fR
+.RS 4
+Do not use indicators but instead use special values to represent null values\&. Historically there have been databases using this approach\&.
+.RE
+.PP
+\fBprepare\fR
+.RS 4
+Prepare all statements before using them\&. Libecpg will keep a cache of prepared statements and reuse a statement if it gets executed again\&. If the cache runs full, libecpg will free the least used statement\&.
+.RE
+.PP
+\fBquestionmarks\fR
+.RS 4
+Allow question mark as placeholder for compatibility reasons\&. This used to be the default long ago\&.
+.RE
+.RE
+.PP
+\fB\-t\fR
+.RS 4
+Turn on autocommit of transactions\&. In this mode, each SQL command is automatically committed unless it is inside an explicit transaction block\&. In the default mode, commands are committed only when
+\fBEXEC SQL COMMIT\fR
+is issued\&.
+.RE
+.PP
+\fB\-v\fR
+.RS 4
+Print additional information including the version and the "include" path\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Print the
+ecpg
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+ecpg
+command line arguments, and exit\&.
+.RE
+.SH "NOTES"
+.PP
+When compiling the preprocessed C code files, the compiler needs to be able to find the
+ECPG
+header files in the
+PostgreSQL
+include directory\&. Therefore, you might have to use the
+\fB\-I\fR
+option when invoking the compiler (e\&.g\&.,
+\-I/usr/local/pgsql/include)\&.
+.PP
+Programs using C code with embedded SQL have to be linked against the
+libecpg
+library, for example using the linker options
+\-L/usr/local/pgsql/lib \-lecpg\&.
+.PP
+The value of either of these directories that is appropriate for the installation can be found out using
+\fBpg_config\fR(1)\&.
+.SH "EXAMPLES"
+.PP
+If you have an embedded SQL C source file named
+prog1\&.pgc, you can create an executable program using the following sequence of commands:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ecpg prog1\&.pgc
+cc \-I/usr/local/pgsql/include \-c prog1\&.c
+cc \-o prog1 prog1\&.o \-L/usr/local/pgsql/lib \-lecpg
+.fi
+.if n \{\
+.RE
+.\}
+
diff --git a/doc/src/sgml/man1/initdb.1 b/doc/src/sgml/man1/initdb.1
new file mode 100644
index 0000000..3cb0fce
--- /dev/null
+++ b/doc/src/sgml/man1/initdb.1
@@ -0,0 +1,415 @@
+'\" t
+.\" Title: initdb
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "INITDB" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+initdb \- create a new PostgreSQL database cluster
+.SH "SYNOPSIS"
+.HP \w'\fBinitdb\fR\ 'u
+\fBinitdb\fR [\fIoption\fR...] [\fB\-\-pgdata\fR | \fB\-D\fR]\fI directory\fR
+.SH "DESCRIPTION"
+.PP
+\fBinitdb\fR
+creates a new
+PostgreSQL
+database cluster\&. A database cluster is a collection of databases that are managed by a single server instance\&.
+.PP
+Creating a database cluster consists of creating the directories in which the database data will live, generating the shared catalog tables (tables that belong to the whole cluster rather than to any particular database), and creating the
+postgres,
+template1, and
+template0
+databases\&. The
+postgres
+database is a default database meant for use by users, utilities and third party applications\&.
+template1
+and
+template0
+are meant as source databases to be copied by later
+\fBCREATE DATABASE\fR
+commands\&.
+template0
+should never be modified, but you can add objects to
+template1, which by default will be copied into databases created later\&. See
+Section\ \&23.3
+for more details\&.
+.PP
+Although
+\fBinitdb\fR
+will attempt to create the specified data directory, it might not have permission if the parent directory of the desired data directory is root\-owned\&. To initialize in such a setup, create an empty data directory as root, then use
+\fBchown\fR
+to assign ownership of that directory to the database user account, then
+\fBsu\fR
+to become the database user to run
+\fBinitdb\fR\&.
+.PP
+\fBinitdb\fR
+must be run as the user that will own the server process, because the server needs to have access to the files and directories that
+\fBinitdb\fR
+creates\&. Since the server cannot be run as root, you must not run
+\fBinitdb\fR
+as root either\&. (It will in fact refuse to do so\&.)
+.PP
+For security reasons the new cluster created by
+\fBinitdb\fR
+will only be accessible by the cluster owner by default\&. The
+\fB\-\-allow\-group\-access\fR
+option allows any user in the same group as the cluster owner to read files in the cluster\&. This is useful for performing backups as a non\-privileged user\&.
+.PP
+\fBinitdb\fR
+initializes the database cluster\*(Aqs default locale and character set encoding\&. These can also be set separately for each database when it is created\&.
+\fBinitdb\fR
+determines those settings for the template databases, which will serve as the default for all other databases\&. By default,
+\fBinitdb\fR
+uses the locale provider
+libc, takes the locale settings from the environment, and determines the encoding from the locale settings\&. This is almost always sufficient, unless there are special requirements\&.
+.PP
+To choose a different locale for the cluster, use the option
+\fB\-\-locale\fR\&. There are also individual options
+\fB\-\-lc\-*\fR
+(see below) to set values for the individual locale categories\&. Note that inconsistent settings for different locale categories can give nonsensical results, so this should be used with care\&.
+.PP
+Alternatively, the ICU library can be used to provide locale services\&. (Again, this only sets the default for subsequently created databases\&.) To select this option, specify
+\-\-locale\-provider=icu\&. To choose the specific ICU locale ID to apply, use the option
+\fB\-\-icu\-locale\fR\&. Note that for implementation reasons and to support legacy code,
+\fBinitdb\fR
+will still select and initialize libc locale settings when the ICU locale provider is used\&.
+.PP
+When
+\fBinitdb\fR
+runs, it will print out the locale settings it has chosen\&. If you have complex requirements or specified multiple options, it is advisable to check that the result matches what was intended\&.
+.PP
+More details about locale settings can be found in
+Section\ \&24.1\&.
+.PP
+To alter the default encoding, use the
+\fB\-\-encoding\fR\&. More details can be found in
+Section\ \&24.3\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fB\-A \fR\fB\fIauthmethod\fR\fR
+.br
+\fB\-\-auth=\fR\fB\fIauthmethod\fR\fR
+.RS 4
+This option specifies the default authentication method for local users used in
+pg_hba\&.conf
+(host
+and
+local
+lines)\&. See
+Section\ \&21.1
+for an overview of valid values\&.
+.sp
+\fBinitdb\fR
+will prepopulate
+pg_hba\&.conf
+entries using the specified authentication method for non\-replication as well as replication connections\&.
+.sp
+Do not use
+trust
+unless you trust all local users on your system\&.
+trust
+is the default for ease of installation\&.
+.RE
+.PP
+\fB\-\-auth\-host=\fR\fB\fIauthmethod\fR\fR
+.RS 4
+This option specifies the authentication method for local users via TCP/IP connections used in
+pg_hba\&.conf
+(host
+lines)\&.
+.RE
+.PP
+\fB\-\-auth\-local=\fR\fB\fIauthmethod\fR\fR
+.RS 4
+This option specifies the authentication method for local users via Unix\-domain socket connections used in
+pg_hba\&.conf
+(local
+lines)\&.
+.RE
+.PP
+\fB\-D \fR\fB\fIdirectory\fR\fR
+.br
+\fB\-\-pgdata=\fR\fB\fIdirectory\fR\fR
+.RS 4
+This option specifies the directory where the database cluster should be stored\&. This is the only information required by
+\fBinitdb\fR, but you can avoid writing it by setting the
+\fBPGDATA\fR
+environment variable, which can be convenient since the database server (\fBpostgres\fR) can find the database directory later by the same variable\&.
+.RE
+.PP
+\fB\-E \fR\fB\fIencoding\fR\fR
+.br
+\fB\-\-encoding=\fR\fB\fIencoding\fR\fR
+.RS 4
+Selects the encoding of the template databases\&. This will also be the default encoding of any database you create later, unless you override it then\&. The default is derived from the locale, if the libc locale provider is used, or
+UTF8
+if the ICU locale provider is used\&. The character sets supported by the
+PostgreSQL
+server are described in
+Section\ \&24.3.1\&.
+.RE
+.PP
+\fB\-g\fR
+.br
+\fB\-\-allow\-group\-access\fR
+.RS 4
+Allows users in the same group as the cluster owner to read all cluster files created by
+\fBinitdb\fR\&. This option is ignored on
+Windows
+as it does not support
+POSIX\-style group permissions\&.
+.RE
+.PP
+\fB\-\-icu\-locale=\fR\fB\fIlocale\fR\fR
+.RS 4
+Specifies the ICU locale ID, if the ICU locale provider is used\&.
+.RE
+.PP
+\fB\-k\fR
+.br
+\fB\-\-data\-checksums\fR
+.RS 4
+Use checksums on data pages to help detect corruption by the I/O system that would otherwise be silent\&. Enabling checksums may incur a noticeable performance penalty\&. If set, checksums are calculated for all objects, in all databases\&. All checksum failures will be reported in the
+pg_stat_database
+view\&. See
+Section\ \&30.2
+for details\&.
+.RE
+.PP
+\fB\-\-locale=\fR\fB\fIlocale\fR\fR
+.RS 4
+Sets the default locale for the database cluster\&. If this option is not specified, the locale is inherited from the environment that
+\fBinitdb\fR
+runs in\&. Locale support is described in
+Section\ \&24.1\&.
+.RE
+.PP
+\fB\-\-lc\-collate=\fR\fB\fIlocale\fR\fR
+.br
+\fB\-\-lc\-ctype=\fR\fB\fIlocale\fR\fR
+.br
+\fB\-\-lc\-messages=\fR\fB\fIlocale\fR\fR
+.br
+\fB\-\-lc\-monetary=\fR\fB\fIlocale\fR\fR
+.br
+\fB\-\-lc\-numeric=\fR\fB\fIlocale\fR\fR
+.br
+\fB\-\-lc\-time=\fR\fB\fIlocale\fR\fR
+.RS 4
+Like
+\fB\-\-locale\fR, but only sets the locale in the specified category\&.
+.RE
+.PP
+\fB\-\-no\-locale\fR
+.RS 4
+Equivalent to
+\fB\-\-locale=C\fR\&.
+.RE
+.PP
+\fB\-\-locale\-provider={\fR\fBlibc\fR\fB|\fR\fBicu\fR\fB}\fR
+.RS 4
+This option sets the locale provider for databases created in the new cluster\&. It can be overridden in the
+\fBCREATE DATABASE\fR
+command when new databases are subsequently created\&. The default is
+libc\&.
+.RE
+.PP
+\fB\-N\fR
+.br
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBinitdb\fR
+will wait for all files to be written safely to disk\&. This option causes
+\fBinitdb\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the data directory corrupt\&. Generally, this option is useful for testing, but should not be used when creating a production installation\&.
+.RE
+.PP
+\fB\-\-no\-instructions\fR
+.RS 4
+By default,
+\fBinitdb\fR
+will write instructions for how to start the cluster at the end of its output\&. This option causes those instructions to be left out\&. This is primarily intended for use by tools that wrap
+\fBinitdb\fR
+in platform\-specific behavior, where those instructions are likely to be incorrect\&.
+.RE
+.PP
+\fB\-\-pwfile=\fR\fB\fIfilename\fR\fR
+.RS 4
+Makes
+\fBinitdb\fR
+read the database superuser\*(Aqs password from a file\&. The first line of the file is taken as the password\&.
+.RE
+.PP
+\fB\-S\fR
+.br
+\fB\-\-sync\-only\fR
+.RS 4
+Safely write all database files to disk and exit\&. This does not perform any of the normal
+initdb
+operations\&. Generally, this option is useful for ensuring reliable recovery after changing
+fsync
+from
+off
+to
+on\&.
+.RE
+.PP
+\fB\-T \fR\fB\fIconfig\fR\fR
+.br
+\fB\-\-text\-search\-config=\fR\fB\fIconfig\fR\fR
+.RS 4
+Sets the default text search configuration\&. See
+default_text_search_config
+for further information\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+Selects the user name of the database superuser\&. This defaults to the name of the effective user running
+\fBinitdb\fR\&. It is really not important what the superuser\*(Aqs name is, but one might choose to keep the customary name
+postgres, even if the operating system user\*(Aqs name is different\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-pwprompt\fR
+.RS 4
+Makes
+\fBinitdb\fR
+prompt for a password to give the database superuser\&. If you don\*(Aqt plan on using password authentication, this is not important\&. Otherwise you won\*(Aqt be able to use password authentication until you have a password set up\&.
+.RE
+.PP
+\fB\-X \fR\fB\fIdirectory\fR\fR
+.br
+\fB\-\-waldir=\fR\fB\fIdirectory\fR\fR
+.RS 4
+This option specifies the directory where the write\-ahead log should be stored\&.
+.RE
+.PP
+\fB\-\-wal\-segsize=\fR\fB\fIsize\fR\fR
+.RS 4
+Set the
+WAL segment size, in megabytes\&. This is the size of each individual file in the WAL log\&. The default size is 16 megabytes\&. The value must be a power of 2 between 1 and 1024 (megabytes)\&. This option can only be set during initialization, and cannot be changed later\&.
+.sp
+It may be useful to adjust this size to control the granularity of WAL log shipping or archiving\&. Also, in databases with a high volume of WAL, the sheer number of WAL files per directory can become a performance and management problem\&. Increasing the WAL file size will reduce the number of WAL files\&.
+.RE
+.PP
+Other, less commonly used, options are also available:
+.PP
+\fB\-d\fR
+.br
+\fB\-\-debug\fR
+.RS 4
+Print debugging output from the bootstrap backend and a few other messages of lesser interest for the general public\&. The bootstrap backend is the program
+\fBinitdb\fR
+uses to create the catalog tables\&. This option generates a tremendous amount of extremely boring output\&.
+.RE
+.PP
+\fB\-\-discard\-caches\fR
+.RS 4
+Run the bootstrap backend with the
+debug_discard_caches=1
+option\&. This takes a very long time and is only of use for deep debugging\&.
+.RE
+.PP
+\fB\-L \fR\fB\fIdirectory\fR\fR
+.RS 4
+Specifies where
+\fBinitdb\fR
+should find its input files to initialize the database cluster\&. This is normally not necessary\&. You will be told if you need to specify their location explicitly\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-clean\fR
+.RS 4
+By default, when
+\fBinitdb\fR
+determines that an error prevented it from completely creating the database cluster, it removes any files it might have created before discovering that it cannot finish the job\&. This option inhibits tidying\-up and is thus useful for debugging\&.
+.RE
+.PP
+Other options:
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+initdb
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+initdb
+command line arguments, and exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATA\fR
+.RS 4
+Specifies the directory where the database cluster is to be stored; can be overridden using the
+\fB\-D\fR
+option\&.
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+\fBTZ\fR
+.RS 4
+Specifies the default time zone of the created database cluster\&. The value should be a full time zone name (see
+Section\ \&8.5.3)\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "NOTES"
+.PP
+\fBinitdb\fR
+can also be invoked via
+\fBpg_ctl initdb\fR\&.
+.SH "SEE ALSO"
+\fBpg_ctl\fR(1), \fBpostgres\fR(1), Section\ \&21.1
diff --git a/doc/src/sgml/man1/oid2name.1 b/doc/src/sgml/man1/oid2name.1
new file mode 100644
index 0000000..2c9763b
--- /dev/null
+++ b/doc/src/sgml/man1/oid2name.1
@@ -0,0 +1,379 @@
+'\" t
+.\" Title: oid2name
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "OID2NAME" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+oid2name \- resolve OIDs and file nodes in a PostgreSQL data directory
+.SH "SYNOPSIS"
+.HP \w'\fBoid2name\fR\ 'u
+\fBoid2name\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+oid2name
+is a utility program that helps administrators to examine the file structure used by PostgreSQL\&. To make use of it, you need to be familiar with the database file structure, which is described in
+Chapter\ \&73\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+The name
+\(lqoid2name\(rq
+is historical, and is actually rather misleading, since most of the time when you use it, you will really be concerned with tables\*(Aq filenode numbers (which are the file names visible in the database directories)\&. Be sure you understand the difference between table OIDs and table filenodes!
+.sp .5v
+.RE
+.PP
+oid2name
+connects to a target database and extracts OID, filenode, and/or table name information\&. You can also have it show database OIDs or tablespace OIDs\&.
+.SH "OPTIONS"
+.PP
+oid2name
+accepts the following command\-line arguments:
+.PP
+\fB\-f \fR\fB\fIfilenode\fR\fR
+.br
+\fB\-\-filenode=\fR\fB\fIfilenode\fR\fR
+.RS 4
+show info for table with filenode
+\fIfilenode\fR\&.
+.RE
+.PP
+\fB\-i\fR
+.br
+\fB\-\-indexes\fR
+.RS 4
+include indexes and sequences in the listing\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIoid\fR\fR
+.br
+\fB\-\-oid=\fR\fB\fIoid\fR\fR
+.RS 4
+show info for table with OID
+\fIoid\fR\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+omit headers (useful for scripting)\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-tablespaces\fR
+.RS 4
+show tablespace OIDs\&.
+.RE
+.PP
+\fB\-S\fR
+.br
+\fB\-\-system\-objects\fR
+.RS 4
+include system objects (those in
+\fBinformation_schema\fR,
+\fBpg_toast\fR
+and
+\fBpg_catalog\fR
+schemas)\&.
+.RE
+.PP
+\fB\-t \fR\fB\fItablename_pattern\fR\fR
+.br
+\fB\-\-table=\fR\fB\fItablename_pattern\fR\fR
+.RS 4
+show info for table(s) matching
+\fItablename_pattern\fR\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+oid2name
+version and exit\&.
+.RE
+.PP
+\fB\-x\fR
+.br
+\fB\-\-extended\fR
+.RS 4
+display more information about each object shown: tablespace name, schema name, and OID\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+oid2name
+command line arguments, and exit\&.
+.RE
+.PP
+oid2name
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-d \fR\fB\fIdatabase\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIdatabase\fR\fR
+.RS 4
+database to connect to\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+database server\*(Aqs host\&.
+.RE
+.PP
+\fB\-H \fR\fB\fIhost\fR\fR
+.RS 4
+database server\*(Aqs host\&. Use of this parameter is
+\fIdeprecated\fR
+as of
+PostgreSQL
+12\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+database server\*(Aqs port\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+user name to connect as\&.
+.RE
+.PP
+To display specific tables, select which tables to show by using
+\fB\-o\fR,
+\fB\-f\fR
+and/or
+\fB\-t\fR\&.
+\fB\-o\fR
+takes an OID,
+\fB\-f\fR
+takes a filenode, and
+\fB\-t\fR
+takes a table name (actually, it\*(Aqs a
+LIKE
+pattern, so you can use things like
+foo%)\&. You can use as many of these options as you like, and the listing will include all objects matched by any of the options\&. But note that these options can only show objects in the database given by
+\fB\-d\fR\&.
+.PP
+If you don\*(Aqt give any of
+\fB\-o\fR,
+\fB\-f\fR
+or
+\fB\-t\fR, but do give
+\fB\-d\fR, it will list all tables in the database named by
+\fB\-d\fR\&. In this mode, the
+\fB\-S\fR
+and
+\fB\-i\fR
+options control what gets listed\&.
+.PP
+If you don\*(Aqt give
+\fB\-d\fR
+either, it will show a listing of database OIDs\&. Alternatively you can give
+\fB\-s\fR
+to get a tablespace listing\&.
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+oid2name
+requires a running database server with non\-corrupt system catalogs\&. It is therefore of only limited use for recovering from catastrophic database corruption situations\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ # what\*(Aqs in this database server, anyway?
+$ oid2name
+All databases:
+ Oid Database Name Tablespace
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 17228 alvherre pg_default
+ 17255 regression pg_default
+ 17227 template0 pg_default
+ 1 template1 pg_default
+
+$ oid2name \-s
+All tablespaces:
+ Oid Tablespace Name
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 1663 pg_default
+ 1664 pg_global
+ 155151 fastdisk
+ 155152 bigdisk
+
+$ # OK, let\*(Aqs look into database alvherre
+$ cd $PGDATA/base/17228
+
+$ # get top 10 db objects in the default tablespace, ordered by size
+$ ls \-lS * | head \-10
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 136536064 sep 14 09:51 155173
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 17965056 sep 14 09:51 1155291
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 1204224 sep 14 09:51 16717
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 581632 sep 6 17:51 1255
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 237568 sep 14 09:50 16674
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 212992 sep 14 09:51 1249
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 204800 sep 14 09:51 16684
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 196608 sep 14 09:50 16700
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 163840 sep 14 09:50 16699
+\-rw\-\-\-\-\-\-\- 1 alvherre alvherre 122880 sep 6 17:51 16751
+
+$ # I wonder what file 155173 is \&.\&.\&.
+$ oid2name \-d alvherre \-f 155173
+From database "alvherre":
+ Filenode Table Name
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 155173 accounts
+
+$ # you can ask for more than one object
+$ oid2name \-d alvherre \-f 155173 \-f 1155291
+From database "alvherre":
+ Filenode Table Name
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 155173 accounts
+ 1155291 accounts_pkey
+
+$ # you can mix the options, and get more details with \-x
+$ oid2name \-d alvherre \-t accounts \-f 1155291 \-x
+From database "alvherre":
+ Filenode Table Name Oid Schema Tablespace
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 155173 accounts 155173 public pg_default
+ 1155291 accounts_pkey 1155291 public pg_default
+
+$ # show disk space for every db object
+$ du [0\-9]* |
+> while read SIZE FILENODE
+> do
+> echo "$SIZE `oid2name \-q \-d alvherre \-i \-f $FILENODE`"
+> done
+16 1155287 branches_pkey
+16 1155289 tellers_pkey
+17561 1155291 accounts_pkey
+\&.\&.\&.
+
+$ # same, but sort by size
+$ du [0\-9]* | sort \-rn | while read SIZE FN
+> do
+> echo "$SIZE `oid2name \-q \-d alvherre \-f $FN`"
+> done
+133466 155173 accounts
+17561 1155291 accounts_pkey
+1177 16717 pg_proc_proname_args_nsp_index
+\&.\&.\&.
+
+$ # If you want to see what\*(Aqs in tablespaces, use the pg_tblspc directory
+$ cd $PGDATA/pg_tblspc
+$ oid2name \-s
+All tablespaces:
+ Oid Tablespace Name
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 1663 pg_default
+ 1664 pg_global
+ 155151 fastdisk
+ 155152 bigdisk
+
+$ # what databases have objects in tablespace "fastdisk"?
+$ ls \-d 155151/*
+155151/17228/ 155151/PG_VERSION
+
+$ # Oh, what was database 17228 again?
+$ oid2name
+All databases:
+ Oid Database Name Tablespace
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 17228 alvherre pg_default
+ 17255 regression pg_default
+ 17227 template0 pg_default
+ 1 template1 pg_default
+
+$ # Let\*(Aqs see what objects does this database have in the tablespace\&.
+$ cd 155151/17228
+$ ls \-l
+total 0
+\-rw\-\-\-\-\-\-\- 1 postgres postgres 0 sep 13 23:20 155156
+
+$ # OK, this is a pretty small table \&.\&.\&. but which one is it?
+$ oid2name \-d alvherre \-f 155156
+From database "alvherre":
+ Filenode Table Name
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 155156 foo
+.fi
+.if n \{\
+.RE
+.\}
+.SH "AUTHOR"
+.PP
+B\&. Palmer
+<bpalmer@crimelabs\&.net>
diff --git a/doc/src/sgml/man1/pg_amcheck.1 b/doc/src/sgml/man1/pg_amcheck.1
new file mode 100644
index 0000000..5c559da
--- /dev/null
+++ b/doc/src/sgml/man1/pg_amcheck.1
@@ -0,0 +1,462 @@
+'\" t
+.\" Title: pg_amcheck
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_AMCHECK" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_amcheck \- checks for corruption in one or more PostgreSQL databases
+.SH "SYNOPSIS"
+.HP \w'\fBpg_amcheck\fR\ 'u
+\fBpg_amcheck\fR [\fIoption\fR...] [\fIdbname\fR]
+.SH "DESCRIPTION"
+.PP
+pg_amcheck
+supports running
+amcheck\*(Aqs corruption checking functions against one or more databases, with options to select which schemas, tables and indexes to check, which kinds of checking to perform, and whether to perform the checks in parallel, and if so, the number of parallel connections to establish and use\&.
+.PP
+Only ordinary and toast table relations, materialized views, sequences, and btree indexes are currently supported\&. Other relation types are silently skipped\&.
+.PP
+If
+dbname
+is specified, it should be the name of a single database to check, and no other database selection options should be present\&. Otherwise, if any database selection options are present, all matching databases will be checked\&. If no such options are present, the default database will be checked\&. Database selection options include
+\fB\-\-all\fR,
+\fB\-\-database\fR
+and
+\fB\-\-exclude\-database\fR\&. They also include
+\fB\-\-relation\fR,
+\fB\-\-exclude\-relation\fR,
+\fB\-\-table\fR,
+\fB\-\-exclude\-table\fR,
+\fB\-\-index\fR, and
+\fB\-\-exclude\-index\fR, but only when such options are used with a three\-part pattern (e\&.g\&.
+\fBmydb*\&.myschema*\&.myrel*\fR)\&. Finally, they include
+\fB\-\-schema\fR
+and
+\fB\-\-exclude\-schema\fR
+when such options are used with a two\-part pattern (e\&.g\&.
+\fBmydb*\&.myschema*\fR)\&.
+.PP
+\fIdbname\fR
+can also be a
+connection string\&.
+.SH "OPTIONS"
+.PP
+The following command\-line options control what is checked:
+.PP
+\fB\-a\fR
+.br
+\fB\-\-all\fR
+.RS 4
+Check all databases, except for any excluded via
+\fB\-\-exclude\-database\fR\&.
+.RE
+.PP
+\fB\-d \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-database=\fR\fB\fIpattern\fR\fR
+.RS 4
+Check databases matching the specified
+\fIpattern\fR, except for any excluded by
+\fB\-\-exclude\-database\fR\&. This option can be specified more than once\&.
+.RE
+.PP
+\fB\-D \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-database=\fR\fB\fIpattern\fR\fR
+.RS 4
+Exclude databases matching the given
+\fIpattern\fR\&. This option can be specified more than once\&.
+.RE
+.PP
+\fB\-i \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-index=\fR\fB\fIpattern\fR\fR
+.RS 4
+Check indexes matching the specified
+\fIpattern\fR, unless they are otherwise excluded\&. This option can be specified more than once\&.
+.sp
+This is similar to the
+\fB\-\-relation\fR
+option, except that it applies only to indexes, not to other relation types\&.
+.RE
+.PP
+\fB\-I \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-index=\fR\fB\fIpattern\fR\fR
+.RS 4
+Exclude indexes matching the specified
+\fIpattern\fR\&. This option can be specified more than once\&.
+.sp
+This is similar to the
+\fB\-\-exclude\-relation\fR
+option, except that it applies only to indexes, not other relation types\&.
+.RE
+.PP
+\fB\-r \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-relation=\fR\fB\fIpattern\fR\fR
+.RS 4
+Check relations matching the specified
+\fIpattern\fR, unless they are otherwise excluded\&. This option can be specified more than once\&.
+.sp
+Patterns may be unqualified, e\&.g\&.
+myrel*, or they may be schema\-qualified, e\&.g\&.
+myschema*\&.myrel*
+or database\-qualified and schema\-qualified, e\&.g\&.
+mydb*\&.myschema*\&.myrel*\&. A database\-qualified pattern will add matching databases to the list of databases to be checked\&.
+.RE
+.PP
+\fB\-R \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-relation=\fR\fB\fIpattern\fR\fR
+.RS 4
+Exclude relations matching the specified
+\fIpattern\fR\&. This option can be specified more than once\&.
+.sp
+As with
+\fB\-\-relation\fR, the
+\fIpattern\fR
+may be unqualified, schema\-qualified, or database\- and schema\-qualified\&.
+.RE
+.PP
+\fB\-s \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-schema=\fR\fB\fIpattern\fR\fR
+.RS 4
+Check tables and indexes in schemas matching the specified
+\fIpattern\fR, unless they are otherwise excluded\&. This option can be specified more than once\&.
+.sp
+To select only tables in schemas matching a particular pattern, consider using something like
+\-\-table=SCHEMAPAT\&.* \-\-no\-dependent\-indexes\&. To select only indexes, consider using something like
+\-\-index=SCHEMAPAT\&.*\&.
+.sp
+A schema pattern may be database\-qualified\&. For example, you may write
+\-\-schema=mydb*\&.myschema*
+to select schemas matching
+myschema*
+in databases matching
+mydb*\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-schema=\fR\fB\fIpattern\fR\fR
+.RS 4
+Exclude tables and indexes in schemas matching the specified
+\fIpattern\fR\&. This option can be specified more than once\&.
+.sp
+As with
+\fB\-\-schema\fR, the pattern may be database\-qualified\&.
+.RE
+.PP
+\fB\-t \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-table=\fR\fB\fIpattern\fR\fR
+.RS 4
+Check tables matching the specified
+\fIpattern\fR, unless they are otherwise excluded\&. This option can be specified more than once\&.
+.sp
+This is similar to the
+\fB\-\-relation\fR
+option, except that it applies only to tables, materialized views, and sequences, not to indexes\&.
+.RE
+.PP
+\fB\-T \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-table=\fR\fB\fIpattern\fR\fR
+.RS 4
+Exclude tables matching the specified
+\fIpattern\fR\&. This option can be specified more than once\&.
+.sp
+This is similar to the
+\fB\-\-exclude\-relation\fR
+option, except that it applies only to tables, materialized views, and sequences, not to indexes\&.
+.RE
+.PP
+\fB\-\-no\-dependent\-indexes\fR
+.RS 4
+By default, if a table is checked, any btree indexes of that table will also be checked, even if they are not explicitly selected by an option such as
+\-\-index
+or
+\-\-relation\&. This option suppresses that behavior\&.
+.RE
+.PP
+\fB\-\-no\-dependent\-toast\fR
+.RS 4
+By default, if a table is checked, its toast table, if any, will also be checked, even if it is not explicitly selected by an option such as
+\-\-table
+or
+\-\-relation\&. This option suppresses that behavior\&.
+.RE
+.PP
+\fB\-\-no\-strict\-names\fR
+.RS 4
+By default, if an argument to
+\-\-database,
+\-\-table,
+\-\-index, or
+\-\-relation
+matches no objects, it is a fatal error\&. This option downgrades that error to a warning\&.
+.RE
+.PP
+The following command\-line options control checking of tables:
+.PP
+\fB\-\-exclude\-toast\-pointers\fR
+.RS 4
+By default, whenever a toast pointer is encountered in a table, a lookup is performed to ensure that it references apparently\-valid entries in the toast table\&. These checks can be quite slow, and this option can be used to skip them\&.
+.RE
+.PP
+\fB\-\-on\-error\-stop\fR
+.RS 4
+After reporting all corruptions on the first page of a table where corruption is found, stop processing that table relation and move on to the next table or index\&.
+.sp
+Note that index checking always stops after the first corrupt page\&. This option only has meaning relative to table relations\&.
+.RE
+.PP
+\fB\-\-skip=\fR\fB\fIoption\fR\fR
+.RS 4
+If
+all\-frozen
+is given, table corruption checks will skip over pages in all tables that are marked as all frozen\&.
+.sp
+If
+all\-visible
+is given, table corruption checks will skip over pages in all tables that are marked as all visible\&.
+.sp
+By default, no pages are skipped\&. This can be specified as
+none, but since this is the default, it need not be mentioned\&.
+.RE
+.PP
+\fB\-\-startblock=\fR\fB\fIblock\fR\fR
+.RS 4
+Start checking at the specified block number\&. An error will occur if the table relation being checked has fewer than this number of blocks\&. This option does not apply to indexes, and is probably only useful when checking a single table relation\&. See
+\-\-endblock
+for further caveats\&.
+.RE
+.PP
+\fB\-\-endblock=\fR\fB\fIblock\fR\fR
+.RS 4
+End checking at the specified block number\&. An error will occur if the table relation being checked has fewer than this number of blocks\&. This option does not apply to indexes, and is probably only useful when checking a single table relation\&. If both a regular table and a toast table are checked, this option will apply to both, but higher\-numbered toast blocks may still be accessed while validating toast pointers, unless that is suppressed using
+\fB\-\-exclude\-toast\-pointers\fR\&.
+.RE
+.PP
+The following command\-line options control checking of B\-tree indexes:
+.PP
+\fB\-\-heapallindexed\fR
+.RS 4
+For each index checked, verify the presence of all heap tuples as index tuples in the index using
+amcheck\*(Aqs
+\fBheapallindexed\fR
+option\&.
+.RE
+.PP
+\fB\-\-parent\-check\fR
+.RS 4
+For each btree index checked, use
+amcheck\*(Aqs
+\fBbt_index_parent_check\fR
+function, which performs additional checks of parent/child relationships during index checking\&.
+.sp
+The default is to use
+amcheck\*(Aqs
+\fBbt_index_check\fR
+function, but note that use of the
+\fB\-\-rootdescend\fR
+option implicitly selects
+\fBbt_index_parent_check\fR\&.
+.RE
+.PP
+\fB\-\-rootdescend\fR
+.RS 4
+For each index checked, re\-find tuples on the leaf level by performing a new search from the root page for each tuple using
+amcheck\*(Aqs
+\fBrootdescend\fR
+option\&.
+.sp
+Use of this option implicitly also selects the
+\fB\-\-parent\-check\fR
+option\&.
+.sp
+This form of verification was originally written to help in the development of btree index features\&. It may be of limited use or even of no use in helping detect the kinds of corruption that occur in practice\&. It may also cause corruption checking to take considerably longer and consume considerably more resources on the server\&.
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBWarning\fR
+.ps -1
+.br
+.PP
+The extra checks performed against B\-tree indexes when the
+\fB\-\-parent\-check\fR
+option or the
+\fB\-\-rootdescend\fR
+option is specified require relatively strong relation\-level locks\&. These checks are the only checks that will block concurrent data modification from
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR
+commands\&.
+.sp .5v
+.RE
+.PP
+The following command\-line options control the connection to the server:
+.PP
+\fB\-h \fR\fB\fIhostname\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhostname\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+pg_amcheck
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+pg_amcheck
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_amcheck
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-maintenance\-db=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies a database or
+connection string
+to be used to discover the list of databases to be checked\&. If neither
+\fB\-\-all\fR
+nor any option including a database pattern is used, no such connection is required and this option does nothing\&. Otherwise, any connection string parameters other than the database name which are included in the value for this option will also be used when connecting to the databases being checked\&. If this option is omitted, the default is
+postgres
+or, if that fails,
+template1\&.
+.RE
+.PP
+Other options are also available:
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo to stdout all SQL sent to the server\&.
+.RE
+.PP
+\fB\-j \fR\fB\fInum\fR\fR
+.br
+\fB\-\-jobs=\fR\fB\fInum\fR\fR
+.RS 4
+Use
+\fInum\fR
+concurrent connections to the server, or one per object to be checked, whichever is less\&.
+.sp
+The default is to use a single connection\&.
+.RE
+.PP
+\fB\-P\fR
+.br
+\fB\-\-progress\fR
+.RS 4
+Show progress information\&. Progress information includes the number of relations for which checking has been completed, and the total size of those relations\&. It also includes the total number of relations that will eventually be checked, and the estimated size of those relations\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Print more messages\&. In particular, this will print a message for each relation being checked, and will increase the level of detail shown for server errors\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_amcheck
+version and exit\&.
+.RE
+.PP
+\fB\-\-install\-missing\fR
+.br
+\fB\-\-install\-missing=\fR\fB\fIschema\fR\fR
+.RS 4
+Install any missing extensions that are required to check the database(s)\&. If not yet installed, each extension\*(Aqs objects will be installed into the given
+\fIschema\fR, or if not specified into schema
+pg_catalog\&.
+.sp
+At present, the only required extension is
+amcheck\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_amcheck
+command line arguments, and exit\&.
+.RE
+.SH "NOTES"
+.PP
+pg_amcheck
+is designed to work with
+PostgreSQL
+14\&.0 and later\&.
+.SH "SEE ALSO"
+amcheck
diff --git a/doc/src/sgml/man1/pg_archivecleanup.1 b/doc/src/sgml/man1/pg_archivecleanup.1
new file mode 100644
index 0000000..ce693f7
--- /dev/null
+++ b/doc/src/sgml/man1/pg_archivecleanup.1
@@ -0,0 +1,207 @@
+'\" t
+.\" Title: pg_archivecleanup
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_ARCHIVECLEANUP" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_archivecleanup \- clean up PostgreSQL WAL archive files
+.SH "SYNOPSIS"
+.HP \w'\fBpg_archivecleanup\fR\ 'u
+\fBpg_archivecleanup\fR [\fIoption\fR...] \fIarchivelocation\fR \fIoldestkeptwalfile\fR
+.SH "DESCRIPTION"
+.PP
+pg_archivecleanup
+is designed to be used as an
+archive_cleanup_command
+to clean up WAL file archives when running as a standby server (see
+Section\ \&27.2)\&.
+pg_archivecleanup
+can also be used as a standalone program to clean WAL file archives\&.
+.PP
+To configure a standby server to use
+pg_archivecleanup, put this into its
+postgresql\&.conf
+configuration file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+archive_cleanup_command = \*(Aqpg_archivecleanup \fIarchivelocation\fR %r\*(Aq
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIarchivelocation\fR
+is the directory from which WAL segment files should be removed\&.
+.PP
+When used within
+archive_cleanup_command, all WAL files logically preceding the value of the
+%r
+argument will be removed from
+\fIarchivelocation\fR\&. This minimizes the number of files that need to be retained, while preserving crash\-restart capability\&. Use of this parameter is appropriate if the
+\fIarchivelocation\fR
+is a transient staging area for this particular standby server, but
+\fInot\fR
+when the
+\fIarchivelocation\fR
+is intended as a long\-term WAL archive area, or when multiple standby servers are recovering from the same archive location\&.
+.PP
+When used as a standalone program all WAL files logically preceding the
+\fIoldestkeptwalfile\fR
+will be removed from
+\fIarchivelocation\fR\&. In this mode, if you specify a
+\&.partial
+or
+\&.backup
+file name, then only the file prefix will be used as the
+\fIoldestkeptwalfile\fR\&. This treatment of
+\&.backup
+file name allows you to remove all WAL files archived prior to a specific base backup without error\&. For example, the following example will remove all files older than WAL file name
+000000010000003700000010:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+pg_archivecleanup \-d archive 000000010000003700000010\&.00000020\&.backup
+
+pg_archivecleanup: keep WAL file "archive/000000010000003700000010" and later
+pg_archivecleanup: removing file "archive/00000001000000370000000F"
+pg_archivecleanup: removing file "archive/00000001000000370000000E"
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+pg_archivecleanup
+assumes that
+\fIarchivelocation\fR
+is a directory readable and writable by the server\-owning user\&.
+.SH "OPTIONS"
+.PP
+pg_archivecleanup
+accepts the following command\-line arguments:
+.PP
+\fB\-d\fR
+.RS 4
+Print lots of debug logging output on
+stderr\&.
+.RE
+.PP
+\fB\-n\fR
+.RS 4
+Print the names of the files that would have been removed on
+stdout
+(performs a dry run)\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_archivecleanup
+version and exit\&.
+.RE
+.PP
+\fB\-x\fR \fIextension\fR
+.RS 4
+Provide an extension that will be stripped from all file names before deciding if they should be deleted\&. This is typically useful for cleaning up archives that have been compressed during storage, and therefore have had an extension added by the compression program\&. For example:
+\-x \&.gz\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_archivecleanup
+command line arguments, and exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+pg_archivecleanup
+is designed to work with
+PostgreSQL
+8\&.0 and later when used as a standalone utility, or with
+PostgreSQL
+9\&.0 and later when used as an archive cleanup command\&.
+.PP
+pg_archivecleanup
+is written in C and has an easy\-to\-modify source code, with specifically designated sections to modify for your own needs
+.SH "EXAMPLES"
+.PP
+On Linux or Unix systems, you might use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+archive_cleanup_command = \*(Aqpg_archivecleanup \-d /mnt/standby/archive %r 2>>cleanup\&.log\*(Aq
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where the archive directory is physically located on the standby server, so that the
+\fIarchive_command\fR
+is accessing it across NFS, but the files are local to the standby\&. This will:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+produce debugging output in
+cleanup\&.log
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+remove no\-longer\-needed files from the archive directory
+.RE
diff --git a/doc/src/sgml/man1/pg_basebackup.1 b/doc/src/sgml/man1/pg_basebackup.1
new file mode 100644
index 0000000..28603f9
--- /dev/null
+++ b/doc/src/sgml/man1/pg_basebackup.1
@@ -0,0 +1,756 @@
+'\" t
+.\" Title: pg_basebackup
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_BASEBACKUP" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_basebackup \- take a base backup of a PostgreSQL cluster
+.SH "SYNOPSIS"
+.HP \w'\fBpg_basebackup\fR\ 'u
+\fBpg_basebackup\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_basebackup
+is used to take a base backup of a running
+PostgreSQL
+database cluster\&. The backup is taken without affecting other clients of the database, and can be used both for point\-in\-time recovery (see
+Section\ \&26.3) and as the starting point for a log\-shipping or streaming\-replication standby server (see
+Section\ \&27.2)\&.
+.PP
+pg_basebackup
+makes an exact copy of the database cluster\*(Aqs files, while making sure the server is put into and out of backup mode automatically\&. Backups are always taken of the entire database cluster; it is not possible to back up individual databases or database objects\&. For selective backups, another tool such as
+\fBpg_dump\fR(1)
+must be used\&.
+.PP
+The backup is made over a regular
+PostgreSQL
+connection that uses the replication protocol\&. The connection must be made with a user ID that has
+REPLICATION
+permissions (see
+Section\ \&22.2) or is a superuser, and
+pg_hba\&.conf
+must permit the replication connection\&. The server must also be configured with
+max_wal_senders
+set high enough to provide at least one walsender for the backup plus one for WAL streaming (if used)\&.
+.PP
+There can be multiple
+\fBpg_basebackup\fRs running at the same time, but it is usually better from a performance point of view to take only one backup, and copy the result\&.
+.PP
+pg_basebackup
+can make a base backup from not only a primary server but also a standby\&. To take a backup from a standby, set up the standby so that it can accept replication connections (that is, set
+\fImax_wal_senders\fR
+and
+hot_standby, and configure its
+pg_hba\&.conf
+appropriately)\&. You will also need to enable
+full_page_writes
+on the primary\&.
+.PP
+Note that there are some limitations in taking a backup from a standby:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The backup history file is not created in the database cluster backed up\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+pg_basebackup
+cannot force the standby to switch to a new WAL file at the end of backup\&. When you are using
+\-X none, if write activity on the primary is low,
+pg_basebackup
+may need to wait a long time for the last WAL file required for the backup to be switched and archived\&. In this case, it may be useful to run
+\fBpg_switch_wal\fR
+on the primary in order to trigger an immediate WAL file switch\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If the standby is promoted to be primary during backup, the backup fails\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+All WAL records required for the backup must contain sufficient full\-page writes, which requires you to enable
+\fIfull_page_writes\fR
+on the primary\&.
+.RE
+.PP
+Whenever
+pg_basebackup
+is taking a base backup, the server\*(Aqs
+pg_stat_progress_basebackup
+view will report the progress of the backup\&. See
+Section\ \&28.4.5
+for details\&.
+.SH "OPTIONS"
+.PP
+The following command\-line options control the location and format of the output:
+.PP
+\fB\-D \fR\fB\fIdirectory\fR\fR
+.br
+\fB\-\-pgdata=\fR\fB\fIdirectory\fR\fR
+.RS 4
+Sets the target directory to write the output to\&.
+pg_basebackup
+will create this directory (and any missing parent directories) if it does not exist\&. If it already exists, it must be empty\&.
+.sp
+When the backup is in tar format, the target directory may be specified as
+\-
+(dash), causing the tar file to be written to
+stdout\&.
+.sp
+This option is required\&.
+.RE
+.PP
+\fB\-F \fR\fB\fIformat\fR\fR
+.br
+\fB\-\-format=\fR\fB\fIformat\fR\fR
+.RS 4
+Selects the format for the output\&.
+\fIformat\fR
+can be one of the following:
+.PP
+p
+.br
+plain
+.RS 4
+Write the output as plain files, with the same layout as the source server\*(Aqs data directory and tablespaces\&. When the cluster has no additional tablespaces, the whole database will be placed in the target directory\&. If the cluster contains additional tablespaces, the main data directory will be placed in the target directory, but all other tablespaces will be placed in the same absolute path as they have on the source server\&. (See
+\fB\-\-tablespace\-mapping\fR
+to change that\&.)
+.sp
+This is the default format\&.
+.RE
+.PP
+t
+.br
+tar
+.RS 4
+Write the output as tar files in the target directory\&. The main data directory\*(Aqs contents will be written to a file named
+base\&.tar, and each other tablespace will be written to a separate tar file named after that tablespace\*(Aqs OID\&.
+.sp
+If the target directory is specified as
+\-
+(dash), the tar contents will be written to standard output, suitable for piping to (for example)
+gzip\&. This is only allowed if the cluster has no additional tablespaces and WAL streaming is not used\&.
+.RE
+.RE
+.PP
+\fB\-R\fR
+.br
+\fB\-\-write\-recovery\-conf\fR
+.RS 4
+Creates a
+standby\&.signal
+
+file and appends connection settings to the
+postgresql\&.auto\&.conf
+file in the target directory (or within the base archive file when using tar format)\&. This eases setting up a standby server using the results of the backup\&.
+.sp
+The
+postgresql\&.auto\&.conf
+file will record the connection settings and, if specified, the replication slot that
+pg_basebackup
+is using, so that streaming replication will use the same settings later on\&.
+.RE
+.PP
+\fB\-t \fR\fB\fItarget\fR\fR
+.br
+\fB\-\-target=\fR\fB\fItarget\fR\fR
+.RS 4
+Instructs the server where to place the base backup\&. The default target is
+client, which specifies that the backup should be sent to the machine where
+pg_basebackup
+is running\&. If the target is instead set to
+server:/some/path, the backup will be stored on the machine where the server is running in the
+/some/path
+directory\&. Storing a backup on the server requires superuser privileges or having privileges of the
+pg_write_server_files
+role\&. If the target is set to
+blackhole, the contents are discarded and not stored anywhere\&. This should only be used for testing purposes, as you will not end up with an actual backup\&.
+.sp
+Since WAL streaming is implemented by
+pg_basebackup
+rather than by the server, this option cannot be used together with
+\-Xstream\&. Since that is the default, when this option is specified, you must also specify either
+\-Xfetch
+or
+\-Xnone\&.
+.RE
+.PP
+\fB\-T \fR\fB\fIolddir\fR\fR\fB=\fR\fB\fInewdir\fR\fR
+.br
+\fB\-\-tablespace\-mapping=\fR\fB\fIolddir\fR\fR\fB=\fR\fB\fInewdir\fR\fR
+.RS 4
+Relocates the tablespace in directory
+\fIolddir\fR
+to
+\fInewdir\fR
+during the backup\&. To be effective,
+\fIolddir\fR
+must exactly match the path specification of the tablespace as it is defined on the source server\&. (But it is not an error if there is no tablespace in
+\fIolddir\fR
+on the source server\&.) Meanwhile
+\fInewdir\fR
+is a directory in the receiving host\*(Aqs filesystem\&. As with the main target directory,
+\fInewdir\fR
+need not exist already, but if it does exist it must be empty\&. Both
+\fIolddir\fR
+and
+\fInewdir\fR
+must be absolute paths\&. If either path needs to contain an equal sign (=), precede that with a backslash\&. This option can be specified multiple times for multiple tablespaces\&.
+.sp
+If a tablespace is relocated in this way, the symbolic links inside the main data directory are updated to point to the new location\&. So the new data directory is ready to be used for a new server instance with all tablespaces in the updated locations\&.
+.sp
+Currently, this option only works with plain output format; it is ignored if tar format is selected\&.
+.RE
+.PP
+\fB\-\-waldir=\fR\fB\fIwaldir\fR\fR
+.RS 4
+Sets the directory to write WAL (write\-ahead log) files to\&. By default WAL files will be placed in the
+pg_wal
+subdirectory of the target directory, but this option can be used to place them elsewhere\&.
+\fIwaldir\fR
+must be an absolute path\&. As with the main target directory,
+\fIwaldir\fR
+need not exist already, but if it does exist it must be empty\&. This option can only be specified when the backup is in plain format\&.
+.RE
+.PP
+\fB\-X \fR\fB\fImethod\fR\fR
+.br
+\fB\-\-wal\-method=\fR\fB\fImethod\fR\fR
+.RS 4
+Includes the required WAL (write\-ahead log) files in the backup\&. This will include all write\-ahead logs generated during the backup\&. Unless the method
+none
+is specified, it is possible to start a postmaster in the target directory without the need to consult the log archive, thus making the output a completely standalone backup\&.
+.sp
+The following
+\fImethod\fRs for collecting the write\-ahead logs are supported:
+.PP
+n
+.br
+none
+.RS 4
+Don\*(Aqt include write\-ahead logs in the backup\&.
+.RE
+.PP
+f
+.br
+fetch
+.RS 4
+The write\-ahead log files are collected at the end of the backup\&. Therefore, it is necessary for the source server\*(Aqs
+wal_keep_size
+parameter to be set high enough that the required log data is not removed before the end of the backup\&. If the required log data has been recycled before it\*(Aqs time to transfer it, the backup will fail and be unusable\&.
+.sp
+When tar format is used, the write\-ahead log files will be included in the
+base\&.tar
+file\&.
+.RE
+.PP
+s
+.br
+stream
+.RS 4
+Stream write\-ahead log data while the backup is being taken\&. This method will open a second connection to the server and start streaming the write\-ahead log in parallel while running the backup\&. Therefore, it will require two replication connections not just one\&. As long as the client can keep up with the write\-ahead log data, using this method requires no extra write\-ahead logs to be saved on the source server\&.
+.sp
+When tar format is used, the write\-ahead log files will be written to a separate file named
+pg_wal\&.tar
+(if the server is a version earlier than 10, the file will be named
+pg_xlog\&.tar)\&.
+.sp
+This value is the default\&.
+.RE
+.RE
+.PP
+\fB\-z\fR
+.br
+\fB\-\-gzip\fR
+.RS 4
+Enables gzip compression of tar file output, with the default compression level\&. Compression is only available when using the tar format, and the suffix
+\&.gz
+will automatically be added to all tar filenames\&.
+.RE
+.PP
+\fB\-Z \fR\fB\fIlevel\fR\fR
+.br
+\fB\-Z [{client|server}\-]\fR\fB\fImethod\fR\fR\fB[:\fR\fB\fIdetail\fR\fR\fB]\fR
+.br
+\fB\-\-compress=\fR\fB\fIlevel\fR\fR
+.br
+\fB\-\-compress=[{client|server}\-]\fR\fB\fImethod\fR\fR\fB[:\fR\fB\fIdetail\fR\fR\fB]\fR
+.RS 4
+Requests compression of the backup\&. If
+client
+or
+server
+is included, it specifies where the compression is to be performed\&. Compressing on the server will reduce transfer bandwidth but will increase server CPU consumption\&. The default is
+client
+except when
+\-\-target
+is used\&. In that case, the backup is not being sent to the client, so only server compression is sensible\&. When
+\-Xstream, which is the default, is used, server\-side compression will not be applied to the WAL\&. To compress the WAL, use client\-side compression, or specify
+\-Xfetch\&.
+.sp
+The compression method can be set to
+gzip,
+lz4,
+zstd, or
+none
+for no compression\&. A compression detail string can optionally be specified\&. If the detail string is an integer, it specifies the compression level\&. Otherwise, it should be a comma\-separated list of items, each of the form
+keyword
+or
+keyword=value\&. Currently, the supported keywords are
+level
+and
+workers\&.
+.sp
+If no compression level is specified, the default compression level will be used\&. If only a level is specified without mentioning an algorithm,
+gzip
+compression will be used if the level is greater than 0, and no compression will be used if the level is 0\&.
+.sp
+When the tar format is used with
+gzip,
+lz4, or
+zstd, the suffix
+\&.gz,
+\&.lz4, or
+\&.zst, respectively, will be automatically added to all tar filenames\&. When the plain format is used, client\-side compression may not be specified, but it is still possible to request server\-side compression\&. If this is done, the server will compress the backup for transmission, and the client will decompress and extract it\&.
+.sp
+When this option is used in combination with
+\-Xstream,
+pg_wal\&.tar
+will be compressed using
+gzip
+if client\-side gzip compression is selected, but will not be compressed if any other compression algorithm is selected, or if server\-side compression is selected\&.
+.RE
+.PP
+The following command\-line options control the generation of the backup and the invocation of the program:
+.PP
+\fB\-c {fast|spread}\fR
+.br
+\fB\-\-checkpoint={fast|spread}\fR
+.RS 4
+Sets checkpoint mode to fast (immediate) or spread (the default) (see
+Section\ \&26.3.3)\&.
+.RE
+.PP
+\fB\-C\fR
+.br
+\fB\-\-create\-slot\fR
+.RS 4
+Specifies that the replication slot named by the
+\-\-slot
+option should be created before starting the backup\&. An error is raised if the slot already exists\&.
+.RE
+.PP
+\fB\-l \fR\fB\fIlabel\fR\fR
+.br
+\fB\-\-label=\fR\fB\fIlabel\fR\fR
+.RS 4
+Sets the label for the backup\&. If none is specified, a default value of
+\(lqpg_basebackup base backup\(rq
+will be used\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-clean\fR
+.RS 4
+By default, when
+\fBpg_basebackup\fR
+aborts with an error, it removes any directories it might have created before discovering that it cannot finish the job (for example, the target directory and write\-ahead log directory)\&. This option inhibits tidying\-up and is thus useful for debugging\&.
+.sp
+Note that tablespace directories are not cleaned up either way\&.
+.RE
+.PP
+\fB\-N\fR
+.br
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBpg_basebackup\fR
+will wait for all files to be written safely to disk\&. This option causes
+\fBpg_basebackup\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the base backup corrupt\&. Generally, this option is useful for testing but should not be used when creating a production installation\&.
+.RE
+.PP
+\fB\-P\fR
+.br
+\fB\-\-progress\fR
+.RS 4
+Enables progress reporting\&. Turning this on will deliver an approximate progress report during the backup\&. Since the database may change during the backup, this is only an approximation and may not end at exactly
+100%\&. In particular, when WAL log is included in the backup, the total amount of data cannot be estimated in advance, and in this case the estimated target size will increase once it passes the total estimate without WAL\&.
+.RE
+.PP
+\fB\-r \fR\fB\fIrate\fR\fR
+.br
+\fB\-\-max\-rate=\fR\fB\fIrate\fR\fR
+.RS 4
+Sets the maximum transfer rate at which data is collected from the source server\&. This can be useful to limit the impact of
+pg_basebackup
+on the server\&. Values are in kilobytes per second\&. Use a suffix of
+M
+to indicate megabytes per second\&. A suffix of
+k
+is also accepted, and has no effect\&. Valid values are between 32 kilobytes per second and 1024 megabytes per second\&.
+.sp
+This option always affects transfer of the data directory\&. Transfer of WAL files is only affected if the collection method is
+fetch\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIslotname\fR\fR
+.br
+\fB\-\-slot=\fR\fB\fIslotname\fR\fR
+.RS 4
+This option can only be used together with
+\-X stream\&. It causes WAL streaming to use the specified replication slot\&. If the base backup is intended to be used as a streaming\-replication standby using a replication slot, the standby should then use the same replication slot name as
+primary_slot_name\&. This ensures that the primary server does not remove any necessary WAL data in the time between the end of the base backup and the start of streaming replication on the new standby\&.
+.sp
+The specified replication slot has to exist unless the option
+\fB\-C\fR
+is also used\&.
+.sp
+If this option is not specified and the server supports temporary replication slots (version 10 and later), then a temporary replication slot is automatically used for WAL streaming\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Enables verbose mode\&. Will output some extra steps during startup and shutdown, as well as show the exact file name that is currently being processed if progress reporting is also enabled\&.
+.RE
+.PP
+\fB\-\-manifest\-checksums=\fR\fB\fIalgorithm\fR\fR
+.RS 4
+Specifies the checksum algorithm that should be applied to each file included in the backup manifest\&. Currently, the available algorithms are
+NONE,
+CRC32C,
+SHA224,
+SHA256,
+SHA384, and
+SHA512\&. The default is
+CRC32C\&.
+.sp
+If
+NONE
+is selected, the backup manifest will not contain any checksums\&. Otherwise, it will contain a checksum of each file in the backup using the specified algorithm\&. In addition, the manifest will always contain a
+SHA256
+checksum of its own contents\&. The
+SHA
+algorithms are significantly more CPU\-intensive than
+CRC32C, so selecting one of them may increase the time required to complete the backup\&.
+.sp
+Using a SHA hash function provides a cryptographically secure digest of each file for users who wish to verify that the backup has not been tampered with, while the CRC32C algorithm provides a checksum that is much faster to calculate; it is good at catching errors due to accidental changes but is not resistant to malicious modifications\&. Note that, to be useful against an adversary who has access to the backup, the backup manifest would need to be stored securely elsewhere or otherwise verified not to have been modified since the backup was taken\&.
+.sp
+\fBpg_verifybackup\fR(1)
+can be used to check the integrity of a backup against the backup manifest\&.
+.RE
+.PP
+\fB\-\-manifest\-force\-encode\fR
+.RS 4
+Forces all filenames in the backup manifest to be hex\-encoded\&. If this option is not specified, only non\-UTF8 filenames are hex\-encoded\&. This option is mostly intended to test that tools which read a backup manifest file properly handle this case\&.
+.RE
+.PP
+\fB\-\-no\-estimate\-size\fR
+.RS 4
+Prevents the server from estimating the total amount of backup data that will be streamed, resulting in the
+backup_total
+column in the
+pg_stat_progress_basebackup
+view always being
+NULL\&.
+.sp
+Without this option, the backup will start by enumerating the size of the entire database, and then go back and send the actual contents\&. This may make the backup take slightly longer, and in particular it will take longer before the first data is sent\&. This option is useful to avoid such estimation time if it\*(Aqs too long\&.
+.sp
+This option is not allowed when using
+\fB\-\-progress\fR\&.
+.RE
+.PP
+\fB\-\-no\-manifest\fR
+.RS 4
+Disables generation of a backup manifest\&. If this option is not specified, the server will generate and send a backup manifest which can be verified using
+\fBpg_verifybackup\fR(1)\&. The manifest is a list of every file present in the backup with the exception of any WAL files that may be included\&. It also stores the size, last modification time, and an optional checksum for each file\&.
+.RE
+.PP
+\fB\-\-no\-slot\fR
+.RS 4
+Prevents the creation of a temporary replication slot for the backup\&.
+.sp
+By default, if log streaming is selected but no slot name is given with the
+\fB\-S\fR
+option, then a temporary replication slot is created (if supported by the source server)\&.
+.sp
+The main purpose of this option is to allow taking a base backup when the server has no free replication slots\&. Using a replication slot is almost always preferred, because it prevents needed WAL from being removed by the server during the backup\&.
+.RE
+.PP
+\fB\-\-no\-verify\-checksums\fR
+.RS 4
+Disables verification of checksums, if they are enabled on the server the base backup is taken from\&.
+.sp
+By default, checksums are verified and checksum failures will result in a non\-zero exit status\&. However, the base backup will not be removed in such a case, as if the
+\fB\-\-no\-clean\fR
+option had been used\&. Checksum verification failures will also be reported in the
+pg_stat_database
+view\&.
+.RE
+.PP
+The following command\-line options control the connection to the source server:
+.PP
+\fB\-d \fR\fB\fIconnstr\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIconnstr\fR\fR
+.RS 4
+Specifies parameters used to connect to the server, as a
+connection string; these will override any conflicting command line options\&.
+.sp
+The option is called
+\-\-dbname
+for consistency with other client applications, but because
+pg_basebackup
+doesn\*(Aqt connect to any particular database in the cluster, any database name in the connection string will be ignored\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for a Unix domain socket\&. The default is taken from the
+\fBPGHOST\fR
+environment variable, if set, else a Unix domain socket connection is attempted\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&. Defaults to the
+\fBPGPORT\fR
+environment variable, if set, or a compiled\-in default\&.
+.RE
+.PP
+\fB\-s \fR\fB\fIinterval\fR\fR
+.br
+\fB\-\-status\-interval=\fR\fB\fIinterval\fR\fR
+.RS 4
+Specifies the number of seconds between status packets sent back to the source server\&. Smaller values allow more accurate monitoring of backup progress from the server\&. A value of zero disables periodic status updates completely, although an update will still be sent when requested by the server, to avoid timeout\-based disconnects\&. The default value is 10 seconds\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+Specifies the user name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Prevents issuing a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Forces
+pg_basebackup
+to prompt for a password before connecting to the source server\&.
+.sp
+This option is never essential, since
+pg_basebackup
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_basebackup
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+Other options are also available:
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Prints the
+pg_basebackup
+version and exits\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Shows help about
+pg_basebackup
+command line arguments, and exits\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+This utility, like most other
+PostgreSQL
+utilities, uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+At the beginning of the backup, a checkpoint needs to be performed on the source server\&. This can take some time (especially if the option
+\-\-checkpoint=fast
+is not used), during which
+pg_basebackup
+will appear to be idle\&.
+.PP
+The backup will include all files in the data directory and tablespaces, including the configuration files and any additional files placed in the directory by third parties, except certain temporary files managed by PostgreSQL\&. But only regular files and directories are copied, except that symbolic links used for tablespaces are preserved\&. Symbolic links pointing to certain directories known to PostgreSQL are copied as empty directories\&. Other symbolic links and special device files are skipped\&. See
+Section\ \&55.4
+for the precise details\&.
+.PP
+In plain format, tablespaces will be backed up to the same path they have on the source server, unless the option
+\-\-tablespace\-mapping
+is used\&. Without this option, running a plain format base backup on the same host as the server will not work if tablespaces are in use, because the backup would have to be written to the same directory locations as the original tablespaces\&.
+.PP
+When tar format is used, it is the user\*(Aqs responsibility to unpack each tar file before starting a PostgreSQL server that uses the data\&. If there are additional tablespaces, the tar files for them need to be unpacked in the correct locations\&. In this case the symbolic links for those tablespaces will be created by the server according to the contents of the
+tablespace_map
+file that is included in the
+base\&.tar
+file\&.
+.PP
+pg_basebackup
+works with servers of the same or an older major version, down to 9\&.1\&. However, WAL streaming mode (\-X stream) only works with server version 9\&.3 and later, and tar format (\-\-format=tar) only works with server version 9\&.5 and later\&.
+.PP
+pg_basebackup
+will preserve group permissions for data files if group permissions are enabled on the source cluster\&.
+.SH "EXAMPLES"
+.PP
+To create a base backup of the server at
+mydbserver
+and store it in the local directory
+/usr/local/pgsql/data:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-h mydbserver \-D /usr/local/pgsql/data\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a backup of the local server with one compressed tar file for each tablespace, and store it in the directory
+backup, showing a progress report while running:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-D backup \-Ft \-z \-P\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a backup of a single\-tablespace local database and compress this with
+bzip2:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-D \- \-Ft \-X fetch | bzip2 > backup\&.tar\&.bz2\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(This command will fail if there are multiple tablespaces in the database\&.)
+.PP
+To create a backup of a local database where the tablespace in
+/opt/ts
+is relocated to
+\&./backup/ts:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-D backup/data \-T /opt/ts=$(pwd)/backup/ts\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a backup of a local server with one tar file for each tablespace compressed with
+gzip
+at level 9, stored in the directory
+backup:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-D backup \-Ft \-\-compress=gzip:9\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBpg_dump\fR(1), Section\ \&28.4.5
diff --git a/doc/src/sgml/man1/pg_checksums.1 b/doc/src/sgml/man1/pg_checksums.1
new file mode 100644
index 0000000..f107c1a
--- /dev/null
+++ b/doc/src/sgml/man1/pg_checksums.1
@@ -0,0 +1,156 @@
+'\" t
+.\" Title: pg_checksums
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_CHECKSUMS" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_checksums \- enable, disable or check data checksums in a PostgreSQL database cluster
+.SH "SYNOPSIS"
+.HP \w'\fBpg_checksums\fR\ 'u
+\fBpg_checksums\fR [\fIoption\fR...] [[\fB\-D\fR | \fB\-\-pgdata\fR]\fIdatadir\fR]
+.SH "DESCRIPTION"
+.PP
+pg_checksums
+checks, enables or disables data checksums in a
+PostgreSQL
+cluster\&. The server must be shut down cleanly before running
+pg_checksums\&. When verifying checksums, the exit status is zero if there are no checksum errors, and nonzero if at least one checksum failure is detected\&. When enabling or disabling checksums, the exit status is nonzero if the operation failed\&.
+.PP
+When verifying checksums, every file in the cluster is scanned\&. When enabling checksums, each relation file block with a changed checksum is rewritten in\-place\&. Disabling checksums only updates the file
+pg_control\&.
+.SH "OPTIONS"
+.PP
+The following command\-line options are available:
+.PP
+\fB\-D \fR\fB\fIdirectory\fR\fR
+.br
+\fB\-\-pgdata=\fR\fB\fIdirectory\fR\fR
+.RS 4
+Specifies the directory where the database cluster is stored\&.
+.RE
+.PP
+\fB\-c\fR
+.br
+\fB\-\-check\fR
+.RS 4
+Checks checksums\&. This is the default mode if nothing else is specified\&.
+.RE
+.PP
+\fB\-d\fR
+.br
+\fB\-\-disable\fR
+.RS 4
+Disables checksums\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-enable\fR
+.RS 4
+Enables checksums\&.
+.RE
+.PP
+\fB\-f \fR\fB\fIfilenode\fR\fR
+.br
+\fB\-\-filenode=\fR\fB\fIfilenode\fR\fR
+.RS 4
+Only validate checksums in the relation with filenode
+\fIfilenode\fR\&.
+.RE
+.PP
+\fB\-N\fR
+.br
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBpg_checksums\fR
+will wait for all files to be written safely to disk\&. This option causes
+\fBpg_checksums\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the updated data directory corrupt\&. Generally, this option is useful for testing but should not be used on a production installation\&. This option has no effect when using
+\-\-check\&.
+.RE
+.PP
+\fB\-P\fR
+.br
+\fB\-\-progress\fR
+.RS 4
+Enable progress reporting\&. Turning this on will deliver a progress report while checking or enabling checksums\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Enable verbose output\&. Lists all checked files\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_checksums
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_checksums
+command line arguments, and exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATA\fR
+.RS 4
+Specifies the directory where the database cluster is stored; can be overridden using the
+\fB\-D\fR
+option\&.
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.SH "NOTES"
+.PP
+Enabling checksums in a large cluster can potentially take a long time\&. During this operation, the cluster or other programs that write to the data directory must not be started or else data loss may occur\&.
+.PP
+When using a replication setup with tools which perform direct copies of relation file blocks (for example
+\fBpg_rewind\fR(1)), enabling or disabling checksums can lead to page corruptions in the shape of incorrect checksums if the operation is not done consistently across all nodes\&. When enabling or disabling checksums in a replication setup, it is thus recommended to stop all the clusters before switching them all consistently\&. Destroying all standbys, performing the operation on the primary and finally recreating the standbys from scratch is also safe\&.
+.PP
+If
+pg_checksums
+is aborted or killed while enabling or disabling checksums, the cluster\*(Aqs data checksum configuration remains unchanged, and
+pg_checksums
+can be re\-run to perform the same operation\&.
diff --git a/doc/src/sgml/man1/pg_config.1 b/doc/src/sgml/man1/pg_config.1
new file mode 100644
index 0000000..160ce45
--- /dev/null
+++ b/doc/src/sgml/man1/pg_config.1
@@ -0,0 +1,257 @@
+'\" t
+.\" Title: pg_config
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_CONFIG" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_config \- retrieve information about the installed version of PostgreSQL
+.SH "SYNOPSIS"
+.HP \w'\fBpg_config\fR\ 'u
+\fBpg_config\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+The
+pg_config
+utility prints configuration parameters of the currently installed version of
+PostgreSQL\&. It is intended, for example, to be used by software packages that want to interface to
+PostgreSQL
+to facilitate finding the required header files and libraries\&.
+.SH "OPTIONS"
+.PP
+To use
+pg_config, supply one or more of the following options:
+.PP
+\fB\-\-bindir\fR
+.RS 4
+Print the location of user executables\&. Use this, for example, to find the
+\fBpsql\fR
+program\&. This is normally also the location where the
+pg_config
+program resides\&.
+.RE
+.PP
+\fB\-\-docdir\fR
+.RS 4
+Print the location of documentation files\&.
+.RE
+.PP
+\fB\-\-htmldir\fR
+.RS 4
+Print the location of HTML documentation files\&.
+.RE
+.PP
+\fB\-\-includedir\fR
+.RS 4
+Print the location of C header files of the client interfaces\&.
+.RE
+.PP
+\fB\-\-pkgincludedir\fR
+.RS 4
+Print the location of other C header files\&.
+.RE
+.PP
+\fB\-\-includedir\-server\fR
+.RS 4
+Print the location of C header files for server programming\&.
+.RE
+.PP
+\fB\-\-libdir\fR
+.RS 4
+Print the location of object code libraries\&.
+.RE
+.PP
+\fB\-\-pkglibdir\fR
+.RS 4
+Print the location of dynamically loadable modules, or where the server would search for them\&. (Other architecture\-dependent data files might also be installed in this directory\&.)
+.RE
+.PP
+\fB\-\-localedir\fR
+.RS 4
+Print the location of locale support files\&. (This will be an empty string if locale support was not configured when
+PostgreSQL
+was built\&.)
+.RE
+.PP
+\fB\-\-mandir\fR
+.RS 4
+Print the location of manual pages\&.
+.RE
+.PP
+\fB\-\-sharedir\fR
+.RS 4
+Print the location of architecture\-independent support files\&.
+.RE
+.PP
+\fB\-\-sysconfdir\fR
+.RS 4
+Print the location of system\-wide configuration files\&.
+.RE
+.PP
+\fB\-\-pgxs\fR
+.RS 4
+Print the location of extension makefiles\&.
+.RE
+.PP
+\fB\-\-configure\fR
+.RS 4
+Print the options that were given to the
+configure
+script when
+PostgreSQL
+was configured for building\&. This can be used to reproduce the identical configuration, or to find out with what options a binary package was built\&. (Note however that binary packages often contain vendor\-specific custom patches\&.) See also the examples below\&.
+.RE
+.PP
+\fB\-\-cc\fR
+.RS 4
+Print the value of the
+\fICC\fR
+variable that was used for building
+PostgreSQL\&. This shows the C compiler used\&.
+.RE
+.PP
+\fB\-\-cppflags\fR
+.RS 4
+Print the value of the
+\fICPPFLAGS\fR
+variable that was used for building
+PostgreSQL\&. This shows C compiler switches needed at preprocessing time (typically,
+\-I
+switches)\&.
+.RE
+.PP
+\fB\-\-cflags\fR
+.RS 4
+Print the value of the
+\fICFLAGS\fR
+variable that was used for building
+PostgreSQL\&. This shows C compiler switches\&.
+.RE
+.PP
+\fB\-\-cflags_sl\fR
+.RS 4
+Print the value of the
+\fICFLAGS_SL\fR
+variable that was used for building
+PostgreSQL\&. This shows extra C compiler switches used for building shared libraries\&.
+.RE
+.PP
+\fB\-\-ldflags\fR
+.RS 4
+Print the value of the
+\fILDFLAGS\fR
+variable that was used for building
+PostgreSQL\&. This shows linker switches\&.
+.RE
+.PP
+\fB\-\-ldflags_ex\fR
+.RS 4
+Print the value of the
+\fILDFLAGS_EX\fR
+variable that was used for building
+PostgreSQL\&. This shows linker switches used for building executables only\&.
+.RE
+.PP
+\fB\-\-ldflags_sl\fR
+.RS 4
+Print the value of the
+\fILDFLAGS_SL\fR
+variable that was used for building
+PostgreSQL\&. This shows linker switches used for building shared libraries only\&.
+.RE
+.PP
+\fB\-\-libs\fR
+.RS 4
+Print the value of the
+\fILIBS\fR
+variable that was used for building
+PostgreSQL\&. This normally contains
+\-l
+switches for external libraries linked into
+PostgreSQL\&.
+.RE
+.PP
+\fB\-\-version\fR
+.RS 4
+Print the version of
+PostgreSQL\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_config
+command line arguments, and exit\&.
+.RE
+If more than one option is given, the information is printed in that order, one item per line\&. If no options are given, all available information is printed, with labels\&.
+.SH "NOTES"
+.PP
+The options
+\fB\-\-docdir\fR,
+\fB\-\-pkgincludedir\fR,
+\fB\-\-localedir\fR,
+\fB\-\-mandir\fR,
+\fB\-\-sharedir\fR,
+\fB\-\-sysconfdir\fR,
+\fB\-\-cc\fR,
+\fB\-\-cppflags\fR,
+\fB\-\-cflags\fR,
+\fB\-\-cflags_sl\fR,
+\fB\-\-ldflags\fR,
+\fB\-\-ldflags_sl\fR, and
+\fB\-\-libs\fR
+were added in
+PostgreSQL
+8\&.1\&. The option
+\fB\-\-htmldir\fR
+was added in
+PostgreSQL
+8\&.4\&. The option
+\fB\-\-ldflags_ex\fR
+was added in
+PostgreSQL
+9\&.0\&.
+.SH "EXAMPLE"
+.PP
+To reproduce the build configuration of the current PostgreSQL installation, run the following command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+eval \&./configure `pg_config \-\-configure`
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The output of
+pg_config \-\-configure
+contains shell quotation marks so arguments with spaces are represented correctly\&. Therefore, using
+eval
+is required for proper results\&.
diff --git a/doc/src/sgml/man1/pg_controldata.1 b/doc/src/sgml/man1/pg_controldata.1
new file mode 100644
index 0000000..6bbe553
--- /dev/null
+++ b/doc/src/sgml/man1/pg_controldata.1
@@ -0,0 +1,65 @@
+'\" t
+.\" Title: pg_controldata
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_CONTROLDATA" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_controldata \- display control information of a PostgreSQL database cluster
+.SH "SYNOPSIS"
+.HP \w'\fBpg_controldata\fR\ 'u
+\fBpg_controldata\fR [\fIoption\fR] [[\fB\-D\fR | \fB\-\-pgdata\fR]\fIdatadir\fR]
+.SH "DESCRIPTION"
+.PP
+\fBpg_controldata\fR
+prints information initialized during
+\fBinitdb\fR, such as the catalog version\&. It also shows information about write\-ahead logging and checkpoint processing\&. This information is cluster\-wide, and not specific to any one database\&.
+.PP
+This utility can only be run by the user who initialized the cluster because it requires read access to the data directory\&. You can specify the data directory on the command line, or use the environment variable
+\fBPGDATA\fR\&. This utility supports the options
+\fB\-V\fR
+and
+\fB\-\-version\fR, which print the
+pg_controldata
+version and exit\&. It also supports options
+\fB\-?\fR
+and
+\fB\-\-help\fR, which output the supported arguments\&.
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATA\fR
+.RS 4
+Default data directory location
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
diff --git a/doc/src/sgml/man1/pg_ctl.1 b/doc/src/sgml/man1/pg_ctl.1
new file mode 100644
index 0000000..24a7c13
--- /dev/null
+++ b/doc/src/sgml/man1/pg_ctl.1
@@ -0,0 +1,537 @@
+'\" t
+.\" Title: pg_ctl
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_CTL" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_ctl \- initialize, start, stop, or control a PostgreSQL server
+.SH "SYNOPSIS"
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBinit[db]\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-s\fR] [\fB\-o\fR\ \fIinitdb\-options\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBstart\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-l\fR\ \fIfilename\fR] [\fB\-W\fR] [\fB\-t\fR\ \fIseconds\fR] [\fB\-s\fR] [\fB\-o\fR\ \fIoptions\fR] [\fB\-p\fR\ \fIpath\fR] [\fB\-c\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBstop\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-m\fR\ \fBs[mart]\fR\ |\ \fBf[ast]\fR\ |\ \fBi[mmediate]\fR] [\fB\-W\fR] [\fB\-t\fR\ \fIseconds\fR] [\fB\-s\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBrestart\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-m\fR\ \fBs[mart]\fR\ |\ \fBf[ast]\fR\ |\ \fBi[mmediate]\fR] [\fB\-W\fR] [\fB\-t\fR\ \fIseconds\fR] [\fB\-s\fR] [\fB\-o\fR\ \fIoptions\fR] [\fB\-c\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBreload\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-s\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBstatus\fR [\fB\-D\fR\ \fIdatadir\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBpromote\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-W\fR] [\fB\-t\fR\ \fIseconds\fR] [\fB\-s\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBlogrotate\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-s\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBkill\fR \fIsignal_name\fR \fIprocess_id\fR
+.PP
+On Microsoft Windows, also:
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBregister\fR [\fB\-D\fR\ \fIdatadir\fR] [\fB\-N\fR\ \fIservicename\fR] [\fB\-U\fR\ \fIusername\fR] [\fB\-P\fR\ \fIpassword\fR] [\fB\-S\fR\ \fBa[uto]\fR\ |\ \fBd[emand]\fR] [\fB\-e\fR\ \fIsource\fR] [\fB\-W\fR] [\fB\-t\fR\ \fIseconds\fR] [\fB\-s\fR] [\fB\-o\fR\ \fIoptions\fR]
+.HP \w'\fBpg_ctl\fR\ 'u
+\fBpg_ctl\fR \fBunregister\fR [\fB\-N\fR\ \fIservicename\fR]
+.SH "DESCRIPTION"
+.PP
+pg_ctl
+is a utility for initializing a
+PostgreSQL
+database cluster, starting, stopping, or restarting the
+PostgreSQL
+database server (\fBpostgres\fR(1)), or displaying the status of a running server\&. Although the server can be started manually,
+pg_ctl
+encapsulates tasks such as redirecting log output and properly detaching from the terminal and process group\&. It also provides convenient options for controlled shutdown\&.
+.PP
+The
+\fBinit\fR
+or
+\fBinitdb\fR
+mode creates a new
+PostgreSQL
+database cluster, that is, a collection of databases that will be managed by a single server instance\&. This mode invokes the
+\fBinitdb\fR
+command\&. See
+\fBinitdb\fR(1)
+for details\&.
+.PP
+\fBstart\fR
+mode launches a new server\&. The server is started in the background, and its standard input is attached to
+/dev/null
+(or
+nul
+on Windows)\&. On Unix\-like systems, by default, the server\*(Aqs standard output and standard error are sent to
+pg_ctl\*(Aqs standard output (not standard error)\&. The standard output of
+pg_ctl
+should then be redirected to a file or piped to another process such as a log rotating program like
+rotatelogs; otherwise
+\fBpostgres\fR
+will write its output to the controlling terminal (from the background) and will not leave the shell\*(Aqs process group\&. On Windows, by default the server\*(Aqs standard output and standard error are sent to the terminal\&. These default behaviors can be changed by using
+\fB\-l\fR
+to append the server\*(Aqs output to a log file\&. Use of either
+\fB\-l\fR
+or output redirection is recommended\&.
+.PP
+\fBstop\fR
+mode shuts down the server that is running in the specified data directory\&. Three different shutdown methods can be selected with the
+\fB\-m\fR
+option\&.
+\(lqSmart\(rq
+mode disallows new connections, then waits for all existing clients to disconnect\&. If the server is in hot standby, recovery and streaming replication will be terminated once all clients have disconnected\&.
+\(lqFast\(rq
+mode (the default) does not wait for clients to disconnect\&. All active transactions are rolled back and clients are forcibly disconnected, then the server is shut down\&.
+\(lqImmediate\(rq
+mode will abort all server processes immediately, without a clean shutdown\&. This choice will lead to a crash\-recovery cycle during the next server start\&.
+.PP
+\fBrestart\fR
+mode effectively executes a stop followed by a start\&. This allows changing the
+\fBpostgres\fR
+command\-line options, or changing configuration\-file options that cannot be changed without restarting the server\&. If relative paths were used on the command line during server start,
+\fBrestart\fR
+might fail unless
+pg_ctl
+is executed in the same current directory as it was during server start\&.
+.PP
+\fBreload\fR
+mode simply sends the
+\fBpostgres\fR
+server process a
+SIGHUP
+signal, causing it to reread its configuration files (postgresql\&.conf,
+pg_hba\&.conf, etc\&.)\&. This allows changing configuration\-file options that do not require a full server restart to take effect\&.
+.PP
+\fBstatus\fR
+mode checks whether a server is running in the specified data directory\&. If it is, the server\*(Aqs
+PID
+and the command line options that were used to invoke it are displayed\&. If the server is not running,
+pg_ctl
+returns an exit status of 3\&. If an accessible data directory is not specified,
+pg_ctl
+returns an exit status of 4\&.
+.PP
+\fBpromote\fR
+mode commands the standby server that is running in the specified data directory to end standby mode and begin read\-write operations\&.
+.PP
+\fBlogrotate\fR
+mode rotates the server log file\&. For details on how to use this mode with external log rotation tools, see
+Section\ \&25.3\&.
+.PP
+\fBkill\fR
+mode sends a signal to a specified process\&. This is primarily valuable on
+Microsoft Windows
+which does not have a built\-in
+kill
+command\&. Use
+\-\-help
+to see a list of supported signal names\&.
+.PP
+\fBregister\fR
+mode registers the
+PostgreSQL
+server as a system service on
+Microsoft Windows\&. The
+\fB\-S\fR
+option allows selection of service start type, either
+\(lqauto\(rq
+(start service automatically on system startup) or
+\(lqdemand\(rq
+(start service on demand)\&.
+.PP
+\fBunregister\fR
+mode unregisters a system service on
+Microsoft Windows\&. This undoes the effects of the
+\fBregister\fR
+command\&.
+.SH "OPTIONS"
+.PP
+\fB\-c\fR
+.br
+\fB\-\-core\-files\fR
+.RS 4
+Attempt to allow server crashes to produce core files, on platforms where this is possible, by lifting any soft resource limit placed on core files\&. This is useful in debugging or diagnosing problems by allowing a stack trace to be obtained from a failed server process\&.
+.RE
+.PP
+\fB\-D \fR\fB\fIdatadir\fR\fR
+.br
+\fB\-\-pgdata=\fR\fB\fIdatadir\fR\fR
+.RS 4
+Specifies the file system location of the database configuration files\&. If this option is omitted, the environment variable
+\fBPGDATA\fR
+is used\&.
+.RE
+.PP
+\fB\-l \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-log=\fR\fB\fIfilename\fR\fR
+.RS 4
+Append the server log output to
+\fIfilename\fR\&. If the file does not exist, it is created\&. The
+umask
+is set to 077, so access to the log file is disallowed to other users by default\&.
+.RE
+.PP
+\fB\-m \fR\fB\fImode\fR\fR
+.br
+\fB\-\-mode=\fR\fB\fImode\fR\fR
+.RS 4
+Specifies the shutdown mode\&.
+\fImode\fR
+can be
+smart,
+fast, or
+immediate, or the first letter of one of these three\&. If this option is omitted,
+fast
+is the default\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIoptions\fR\fR
+.br
+\fB\-\-options=\fR\fB\fIoptions\fR\fR
+.RS 4
+Specifies options to be passed directly to the
+\fBpostgres\fR
+command\&.
+\fB\-o\fR
+can be specified multiple times, with all the given options being passed through\&.
+.sp
+The
+\fIoptions\fR
+should usually be surrounded by single or double quotes to ensure that they are passed through as a group\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIinitdb\-options\fR\fR
+.br
+\fB\-\-options=\fR\fB\fIinitdb\-options\fR\fR
+.RS 4
+Specifies options to be passed directly to the
+\fBinitdb\fR
+command\&.
+\fB\-o\fR
+can be specified multiple times, with all the given options being passed through\&.
+.sp
+The
+\fIinitdb\-options\fR
+should usually be surrounded by single or double quotes to ensure that they are passed through as a group\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIpath\fR\fR
+.RS 4
+Specifies the location of the
+postgres
+executable\&. By default the
+postgres
+executable is taken from the same directory as
+\fBpg_ctl\fR, or failing that, the hard\-wired installation directory\&. It is not necessary to use this option unless you are doing something unusual and get errors that the
+postgres
+executable was not found\&.
+.sp
+In
+init
+mode, this option analogously specifies the location of the
+initdb
+executable\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-silent\fR
+.RS 4
+Print only errors, no informational messages\&.
+.RE
+.PP
+\fB\-t \fR\fB\fIseconds\fR\fR
+.br
+\fB\-\-timeout=\fR\fB\fIseconds\fR\fR
+.RS 4
+Specifies the maximum number of seconds to wait when waiting for an operation to complete (see option
+\fB\-w\fR)\&. Defaults to the value of the
+\fBPGCTLTIMEOUT\fR
+environment variable or, if not set, to 60 seconds\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_ctl
+version and exit\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-wait\fR
+.RS 4
+Wait for the operation to complete\&. This is supported for the modes
+start,
+stop,
+restart,
+promote, and
+register, and is the default for those modes\&.
+.sp
+When waiting,
+\fBpg_ctl\fR
+repeatedly checks the server\*(Aqs
+PID
+file, sleeping for a short amount of time between checks\&. Startup is considered complete when the
+PID
+file indicates that the server is ready to accept connections\&. Shutdown is considered complete when the server removes the
+PID
+file\&.
+\fBpg_ctl\fR
+returns an exit code based on the success of the startup or shutdown\&.
+.sp
+If the operation does not complete within the timeout (see option
+\fB\-t\fR), then
+\fBpg_ctl\fR
+exits with a nonzero exit status\&. But note that the operation might continue in the background and eventually succeed\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-no\-wait\fR
+.RS 4
+Do not wait for the operation to complete\&. This is the opposite of the option
+\fB\-w\fR\&.
+.sp
+If waiting is disabled, the requested action is triggered, but there is no feedback about its success\&. In that case, the server log file or an external monitoring system would have to be used to check the progress and success of the operation\&.
+.sp
+In prior releases of PostgreSQL, this was the default except for the
+stop
+mode\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_ctl
+command line arguments, and exit\&.
+.RE
+.PP
+If an option is specified that is valid, but not relevant to the selected operating mode,
+pg_ctl
+ignores it\&.
+.SS "Options for Windows"
+.PP
+\fB\-e \fR\fB\fIsource\fR\fR
+.RS 4
+Name of the event source for
+pg_ctl
+to use for logging to the event log when running as a Windows service\&. The default is
+PostgreSQL\&. Note that this only controls messages sent from
+pg_ctl
+itself; once started, the server will use the event source specified by its
+event_source
+parameter\&. Should the server fail very early in startup, before that parameter has been set, it might also log using the default event source name
+PostgreSQL\&.
+.RE
+.PP
+\fB\-N \fR\fB\fIservicename\fR\fR
+.RS 4
+Name of the system service to register\&. This name will be used as both the service name and the display name\&. The default is
+PostgreSQL\&.
+.RE
+.PP
+\fB\-P \fR\fB\fIpassword\fR\fR
+.RS 4
+Password for the user to run the service as\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIstart\-type\fR\fR
+.RS 4
+Start type of the system service\&.
+\fIstart\-type\fR
+can be
+auto, or
+demand, or the first letter of one of these two\&. If this option is omitted,
+auto
+is the default\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.RS 4
+User name for the user to run the service as\&. For domain users, use the format
+DOMAIN\eusername\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGCTLTIMEOUT\fR
+.RS 4
+Default limit on the number of seconds to wait when waiting for startup or shutdown to complete\&. If not set, the default is 60 seconds\&.
+.RE
+.PP
+\fBPGDATA\fR
+.RS 4
+Default data directory location\&.
+.RE
+.PP
+Most
+\fBpg_ctl\fR
+modes require knowing the data directory location; therefore, the
+\fB\-D\fR
+option is required unless
+\fBPGDATA\fR
+is set\&.
+.PP
+\fBpg_ctl\fR, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+For additional variables that affect the server, see
+\fBpostgres\fR(1)\&.
+.SH "FILES"
+.PP
+postmaster\&.pid
+.RS 4
+pg_ctl
+examines this file in the data directory to determine whether the server is currently running\&.
+.RE
+.PP
+postmaster\&.opts
+.RS 4
+If this file exists in the data directory,
+pg_ctl
+(in
+\fBrestart\fR
+mode) will pass the contents of the file as options to
+postgres, unless overridden by the
+\fB\-o\fR
+option\&. The contents of this file are also displayed in
+\fBstatus\fR
+mode\&.
+.RE
+.SH "EXAMPLES"
+.SS "Starting the Server"
+.PP
+To start the server, waiting until the server is accepting connections:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl start\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To start the server using port 5433, and running without
+\fBfsync\fR, use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl \-o "\-F \-p 5433" start\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SS "Stopping the Server"
+.PP
+To stop the server, use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl stop\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fB\-m\fR
+option allows control over
+\fIhow\fR
+the server shuts down:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl stop \-m smart\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SS "Restarting the Server"
+.PP
+Restarting the server is almost equivalent to stopping the server and starting it again, except that by default,
+\fBpg_ctl\fR
+saves and reuses the command line options that were passed to the previously\-running instance\&. To restart the server using the same options as before, use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl restart\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+But if
+\fB\-o\fR
+is specified, that replaces any previous options\&. To restart using port 5433, disabling
+\fBfsync\fR
+upon restart:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl \-o "\-F \-p 5433" restart\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SS "Showing the Server Status"
+.PP
+Here is sample status output from
+pg_ctl:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_ctl status\fR
+
+pg_ctl: server is running (PID: 13718)
+/usr/local/pgsql/bin/postgres "\-D" "/usr/local/pgsql/data" "\-p" "5433" "\-B" "128"
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The second line is the command that would be invoked in restart mode\&.
+.SH "SEE ALSO"
+\fBinitdb\fR(1), \fBpostgres\fR(1)
diff --git a/doc/src/sgml/man1/pg_dump.1 b/doc/src/sgml/man1/pg_dump.1
new file mode 100644
index 0000000..6603d11
--- /dev/null
+++ b/doc/src/sgml/man1/pg_dump.1
@@ -0,0 +1,1239 @@
+'\" t
+.\" Title: pg_dump
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_DUMP" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_dump \- extract a PostgreSQL database into a script file or other archive file
+.SH "SYNOPSIS"
+.HP \w'\fBpg_dump\fR\ 'u
+\fBpg_dump\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\fIdbname\fR]
+.SH "DESCRIPTION"
+.PP
+pg_dump
+is a utility for backing up a
+PostgreSQL
+database\&. It makes consistent backups even if the database is being used concurrently\&.
+pg_dump
+does not block other users accessing the database (readers or writers)\&.
+.PP
+pg_dump
+only dumps a single database\&. To back up an entire cluster, or to back up global objects that are common to all databases in a cluster (such as roles and tablespaces), use
+\fBpg_dumpall\fR(1)\&.
+.PP
+Dumps can be output in script or archive file formats\&. Script dumps are plain\-text files containing the SQL commands required to reconstruct the database to the state it was in at the time it was saved\&. To restore from such a script, feed it to
+\fBpsql\fR(1)\&. Script files can be used to reconstruct the database even on other machines and other architectures; with some modifications, even on other SQL database products\&.
+.PP
+The alternative archive file formats must be used with
+\fBpg_restore\fR(1)
+to rebuild the database\&. They allow
+pg_restore
+to be selective about what is restored, or even to reorder the items prior to being restored\&. The archive file formats are designed to be portable across architectures\&.
+.PP
+When used with one of the archive file formats and combined with
+pg_restore,
+pg_dump
+provides a flexible archival and transfer mechanism\&.
+pg_dump
+can be used to backup an entire database, then
+pg_restore
+can be used to examine the archive and/or select which parts of the database are to be restored\&. The most flexible output file formats are the
+\(lqcustom\(rq
+format (\fB\-Fc\fR) and the
+\(lqdirectory\(rq
+format (\fB\-Fd\fR)\&. They allow for selection and reordering of all archived items, support parallel restoration, and are compressed by default\&. The
+\(lqdirectory\(rq
+format is the only format that supports parallel dumps\&.
+.PP
+While running
+pg_dump, one should examine the output for any warnings (printed on standard error), especially in light of the limitations listed below\&.
+.SH "OPTIONS"
+.PP
+The following command\-line options control the content and format of the output\&.
+.PP
+\fIdbname\fR
+.RS 4
+Specifies the name of the database to be dumped\&. If this is not specified, the environment variable
+\fBPGDATABASE\fR
+is used\&. If that is not set, the user name specified for the connection is used\&.
+.RE
+.PP
+\fB\-a\fR
+.br
+\fB\-\-data\-only\fR
+.RS 4
+Dump only the data, not the schema (data definitions)\&. Table data, large objects, and sequence values are dumped\&.
+.sp
+This option is similar to, but for historical reasons not identical to, specifying
+\fB\-\-section=data\fR\&.
+.RE
+.PP
+\fB\-b\fR
+.br
+\fB\-\-blobs\fR
+.RS 4
+Include large objects in the dump\&. This is the default behavior except when
+\fB\-\-schema\fR,
+\fB\-\-table\fR, or
+\fB\-\-schema\-only\fR
+is specified\&. The
+\fB\-b\fR
+switch is therefore only useful to add large objects to dumps where a specific schema or table has been requested\&. Note that blobs are considered data and therefore will be included when
+\fB\-\-data\-only\fR
+is used, but not when
+\fB\-\-schema\-only\fR
+is\&.
+.RE
+.PP
+\fB\-B\fR
+.br
+\fB\-\-no\-blobs\fR
+.RS 4
+Exclude large objects in the dump\&.
+.sp
+When both
+\fB\-b\fR
+and
+\fB\-B\fR
+are given, the behavior is to output large objects, when data is being dumped, see the
+\fB\-b\fR
+documentation\&.
+.RE
+.PP
+\fB\-c\fR
+.br
+\fB\-\-clean\fR
+.RS 4
+Output commands to clean (drop) database objects prior to outputting the commands for creating them\&. (Unless
+\fB\-\-if\-exists\fR
+is also specified, restore might generate some harmless error messages, if any objects were not present in the destination database\&.)
+.sp
+This option is ignored when emitting an archive (non\-text) output file\&. For the archive formats, you can specify the option when you call
+\fBpg_restore\fR\&.
+.RE
+.PP
+\fB\-C\fR
+.br
+\fB\-\-create\fR
+.RS 4
+Begin the output with a command to create the database itself and reconnect to the created database\&. (With a script of this form, it doesn\*(Aqt matter which database in the destination installation you connect to before running the script\&.) If
+\fB\-\-clean\fR
+is also specified, the script drops and recreates the target database before reconnecting to it\&.
+.sp
+With
+\fB\-\-create\fR, the output also includes the database\*(Aqs comment if any, and any configuration variable settings that are specific to this database, that is, any
+\fBALTER DATABASE \&.\&.\&. SET \&.\&.\&.\fR
+and
+\fBALTER ROLE \&.\&.\&. IN DATABASE \&.\&.\&. SET \&.\&.\&.\fR
+commands that mention this database\&. Access privileges for the database itself are also dumped, unless
+\fB\-\-no\-acl\fR
+is specified\&.
+.sp
+This option is ignored when emitting an archive (non\-text) output file\&. For the archive formats, you can specify the option when you call
+\fBpg_restore\fR\&.
+.RE
+.PP
+\fB\-e \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-extension=\fR\fB\fIpattern\fR\fR
+.RS 4
+Dump only extensions matching
+\fIpattern\fR\&. When this option is not specified, all non\-system extensions in the target database will be dumped\&. Multiple extensions can be selected by writing multiple
+\fB\-e\fR
+switches\&. The
+\fIpattern\fR
+parameter is interpreted as a pattern according to the same rules used by
+psql\*(Aqs
+\ed
+commands (see
+Patterns), so multiple extensions can also be selected by writing wildcard characters in the pattern\&. When using wildcards, be careful to quote the pattern if needed to prevent the shell from expanding the wildcards\&.
+.sp
+Any configuration relation registered by
+\fBpg_extension_config_dump\fR
+is included in the dump if its extension is specified by
+\fB\-\-extension\fR\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+When
+\fB\-e\fR
+is specified,
+pg_dump
+makes no attempt to dump any other database objects that the selected extension(s) might depend upon\&. Therefore, there is no guarantee that the results of a specific\-extension dump can be successfully restored by themselves into a clean database\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-E \fR\fB\fIencoding\fR\fR
+.br
+\fB\-\-encoding=\fR\fB\fIencoding\fR\fR
+.RS 4
+Create the dump in the specified character set encoding\&. By default, the dump is created in the database encoding\&. (Another way to get the same result is to set the
+\fBPGCLIENTENCODING\fR
+environment variable to the desired dump encoding\&.) The supported encodings are described in
+Section\ \&24.3.1\&.
+.RE
+.PP
+\fB\-f \fR\fB\fIfile\fR\fR
+.br
+\fB\-\-file=\fR\fB\fIfile\fR\fR
+.RS 4
+Send output to the specified file\&. This parameter can be omitted for file based output formats, in which case the standard output is used\&. It must be given for the directory output format however, where it specifies the target directory instead of a file\&. In this case the directory is created by
+\fBpg_dump\fR
+and must not exist before\&.
+.RE
+.PP
+\fB\-F \fR\fB\fIformat\fR\fR
+.br
+\fB\-\-format=\fR\fB\fIformat\fR\fR
+.RS 4
+Selects the format of the output\&.
+\fIformat\fR
+can be one of the following:
+.PP
+p
+.br
+plain
+.RS 4
+Output a plain\-text
+SQL
+script file (the default)\&.
+.RE
+.PP
+c
+.br
+custom
+.RS 4
+Output a custom\-format archive suitable for input into
+pg_restore\&. Together with the directory output format, this is the most flexible output format in that it allows manual selection and reordering of archived items during restore\&. This format is also compressed by default\&.
+.RE
+.PP
+d
+.br
+directory
+.RS 4
+Output a directory\-format archive suitable for input into
+pg_restore\&. This will create a directory with one file for each table and blob being dumped, plus a so\-called Table of Contents file describing the dumped objects in a machine\-readable format that
+pg_restore
+can read\&. A directory format archive can be manipulated with standard Unix tools; for example, files in an uncompressed archive can be compressed with the
+gzip
+tool\&. This format is compressed by default and also supports parallel dumps\&.
+.RE
+.PP
+t
+.br
+tar
+.RS 4
+Output a
+\fBtar\fR\-format archive suitable for input into
+pg_restore\&. The tar format is compatible with the directory format: extracting a tar\-format archive produces a valid directory\-format archive\&. However, the tar format does not support compression\&. Also, when using tar format the relative order of table data items cannot be changed during restore\&.
+.RE
+.RE
+.PP
+\fB\-j \fR\fB\fInjobs\fR\fR
+.br
+\fB\-\-jobs=\fR\fB\fInjobs\fR\fR
+.RS 4
+Run the dump in parallel by dumping
+\fInjobs\fR
+tables simultaneously\&. This option may reduce the time needed to perform the dump but it also increases the load on the database server\&. You can only use this option with the directory output format because this is the only output format where multiple processes can write their data at the same time\&.
+.sp
+pg_dump
+will open
+\fInjobs\fR
++ 1 connections to the database, so make sure your
+max_connections
+setting is high enough to accommodate all connections\&.
+.sp
+Requesting exclusive locks on database objects while running a parallel dump could cause the dump to fail\&. The reason is that the
+pg_dump
+leader process requests shared locks (ACCESS SHARE) on the objects that the worker processes are going to dump later in order to make sure that nobody deletes them and makes them go away while the dump is running\&. If another client then requests an exclusive lock on a table, that lock will not be granted but will be queued waiting for the shared lock of the leader process to be released\&. Consequently any other access to the table will not be granted either and will queue after the exclusive lock request\&. This includes the worker process trying to dump the table\&. Without any precautions this would be a classic deadlock situation\&. To detect this conflict, the
+pg_dump
+worker process requests another shared lock using the
+NOWAIT
+option\&. If the worker process is not granted this shared lock, somebody else must have requested an exclusive lock in the meantime and there is no way to continue with the dump, so
+pg_dump
+has no choice but to abort the dump\&.
+.sp
+To perform a parallel dump, the database server needs to support synchronized snapshots, a feature that was introduced in
+PostgreSQL
+9\&.2 for primary servers and 10 for standbys\&. With this feature, database clients can ensure they see the same data set even though they use different connections\&.
+\fBpg_dump \-j\fR
+uses multiple database connections; it connects to the database once with the leader process and once again for each worker job\&. Without the synchronized snapshot feature, the different worker jobs wouldn\*(Aqt be guaranteed to see the same data in each connection, which could lead to an inconsistent backup\&.
+.RE
+.PP
+\fB\-n \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-schema=\fR\fB\fIpattern\fR\fR
+.RS 4
+Dump only schemas matching
+\fIpattern\fR; this selects both the schema itself, and all its contained objects\&. When this option is not specified, all non\-system schemas in the target database will be dumped\&. Multiple schemas can be selected by writing multiple
+\fB\-n\fR
+switches\&. The
+\fIpattern\fR
+parameter is interpreted as a pattern according to the same rules used by
+psql\*(Aqs
+\ed
+commands (see
+Patterns
+below), so multiple schemas can also be selected by writing wildcard characters in the pattern\&. When using wildcards, be careful to quote the pattern if needed to prevent the shell from expanding the wildcards; see
+Examples
+below\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+When
+\fB\-n\fR
+is specified,
+pg_dump
+makes no attempt to dump any other database objects that the selected schema(s) might depend upon\&. Therefore, there is no guarantee that the results of a specific\-schema dump can be successfully restored by themselves into a clean database\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+Non\-schema objects such as blobs are not dumped when
+\fB\-n\fR
+is specified\&. You can add blobs back to the dump with the
+\fB\-\-blobs\fR
+switch\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-N \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-schema=\fR\fB\fIpattern\fR\fR
+.RS 4
+Do not dump any schemas matching
+\fIpattern\fR\&. The pattern is interpreted according to the same rules as for
+\fB\-n\fR\&.
+\fB\-N\fR
+can be given more than once to exclude schemas matching any of several patterns\&.
+.sp
+When both
+\fB\-n\fR
+and
+\fB\-N\fR
+are given, the behavior is to dump just the schemas that match at least one
+\fB\-n\fR
+switch but no
+\fB\-N\fR
+switches\&. If
+\fB\-N\fR
+appears without
+\fB\-n\fR, then schemas matching
+\fB\-N\fR
+are excluded from what is otherwise a normal dump\&.
+.RE
+.PP
+\fB\-O\fR
+.br
+\fB\-\-no\-owner\fR
+.RS 4
+Do not output commands to set ownership of objects to match the original database\&. By default,
+pg_dump
+issues
+\fBALTER OWNER\fR
+or
+\fBSET SESSION AUTHORIZATION\fR
+statements to set ownership of created database objects\&. These statements will fail when the script is run unless it is started by a superuser (or the same user that owns all of the objects in the script)\&. To make a script that can be restored by any user, but will give that user ownership of all the objects, specify
+\fB\-O\fR\&.
+.sp
+This option is ignored when emitting an archive (non\-text) output file\&. For the archive formats, you can specify the option when you call
+\fBpg_restore\fR\&.
+.RE
+.PP
+\fB\-R\fR
+.br
+\fB\-\-no\-reconnect\fR
+.RS 4
+This option is obsolete but still accepted for backwards compatibility\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-schema\-only\fR
+.RS 4
+Dump only the object definitions (schema), not data\&.
+.sp
+This option is the inverse of
+\fB\-\-data\-only\fR\&. It is similar to, but for historical reasons not identical to, specifying
+\fB\-\-section=pre\-data \-\-section=post\-data\fR\&.
+.sp
+(Do not confuse this with the
+\fB\-\-schema\fR
+option, which uses the word
+\(lqschema\(rq
+in a different meaning\&.)
+.sp
+To exclude table data for only a subset of tables in the database, see
+\fB\-\-exclude\-table\-data\fR\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-superuser=\fR\fB\fIusername\fR\fR
+.RS 4
+Specify the superuser user name to use when disabling triggers\&. This is relevant only if
+\fB\-\-disable\-triggers\fR
+is used\&. (Usually, it\*(Aqs better to leave this out, and instead start the resulting script as superuser\&.)
+.RE
+.PP
+\fB\-t \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-table=\fR\fB\fIpattern\fR\fR
+.RS 4
+Dump only tables with names matching
+\fIpattern\fR\&. Multiple tables can be selected by writing multiple
+\fB\-t\fR
+switches\&. The
+\fIpattern\fR
+parameter is interpreted as a pattern according to the same rules used by
+psql\*(Aqs
+\ed
+commands (see
+Patterns
+below), so multiple tables can also be selected by writing wildcard characters in the pattern\&. When using wildcards, be careful to quote the pattern if needed to prevent the shell from expanding the wildcards; see
+Examples
+below\&.
+.sp
+As well as tables, this option can be used to dump the definition of matching views, materialized views, foreign tables, and sequences\&. It will not dump the contents of views or materialized views, and the contents of foreign tables will only be dumped if the corresponding foreign server is specified with
+\fB\-\-include\-foreign\-data\fR\&.
+.sp
+The
+\fB\-n\fR
+and
+\fB\-N\fR
+switches have no effect when
+\fB\-t\fR
+is used, because tables selected by
+\fB\-t\fR
+will be dumped regardless of those switches, and non\-table objects will not be dumped\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+When
+\fB\-t\fR
+is specified,
+pg_dump
+makes no attempt to dump any other database objects that the selected table(s) might depend upon\&. Therefore, there is no guarantee that the results of a specific\-table dump can be successfully restored by themselves into a clean database\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-T \fR\fB\fIpattern\fR\fR
+.br
+\fB\-\-exclude\-table=\fR\fB\fIpattern\fR\fR
+.RS 4
+Do not dump any tables matching
+\fIpattern\fR\&. The pattern is interpreted according to the same rules as for
+\fB\-t\fR\&.
+\fB\-T\fR
+can be given more than once to exclude tables matching any of several patterns\&.
+.sp
+When both
+\fB\-t\fR
+and
+\fB\-T\fR
+are given, the behavior is to dump just the tables that match at least one
+\fB\-t\fR
+switch but no
+\fB\-T\fR
+switches\&. If
+\fB\-T\fR
+appears without
+\fB\-t\fR, then tables matching
+\fB\-T\fR
+are excluded from what is otherwise a normal dump\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Specifies verbose mode\&. This will cause
+pg_dump
+to output detailed object comments and start/stop times to the dump file, and progress messages to standard error\&. Repeating the option causes additional debug\-level messages to appear on standard error\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_dump
+version and exit\&.
+.RE
+.PP
+\fB\-x\fR
+.br
+\fB\-\-no\-privileges\fR
+.br
+\fB\-\-no\-acl\fR
+.RS 4
+Prevent dumping of access privileges (grant/revoke commands)\&.
+.RE
+.PP
+\fB\-Z \fR\fB\fI0\&.\&.9\fR\fR
+.br
+\fB\-\-compress=\fR\fB\fI0\&.\&.9\fR\fR
+.RS 4
+Specify the compression level to use\&. Zero means no compression\&. For the custom and directory archive formats, this specifies compression of individual table\-data segments, and the default is to compress at a moderate level\&. For plain text output, setting a nonzero compression level causes the entire output file to be compressed, as though it had been fed through
+gzip; but the default is not to compress\&. The tar archive format currently does not support compression at all\&.
+.RE
+.PP
+\fB\-\-binary\-upgrade\fR
+.RS 4
+This option is for use by in\-place upgrade utilities\&. Its use for other purposes is not recommended or supported\&. The behavior of the option may change in future releases without notice\&.
+.RE
+.PP
+\fB\-\-column\-inserts\fR
+.br
+\fB\-\-attribute\-inserts\fR
+.RS 4
+Dump data as
+\fBINSERT\fR
+commands with explicit column names (INSERT INTO \fItable\fR (\fIcolumn\fR, \&.\&.\&.) VALUES \&.\&.\&.)\&. This will make restoration very slow; it is mainly useful for making dumps that can be loaded into non\-PostgreSQL
+databases\&. Any error during restoring will cause only rows that are part of the problematic
+\fBINSERT\fR
+to be lost, rather than the entire table contents\&.
+.RE
+.PP
+\fB\-\-disable\-dollar\-quoting\fR
+.RS 4
+This option disables the use of dollar quoting for function bodies, and forces them to be quoted using SQL standard string syntax\&.
+.RE
+.PP
+\fB\-\-disable\-triggers\fR
+.RS 4
+This option is relevant only when creating a data\-only dump\&. It instructs
+pg_dump
+to include commands to temporarily disable triggers on the target tables while the data is restored\&. Use this if you have referential integrity checks or other triggers on the tables that you do not want to invoke during data restore\&.
+.sp
+Presently, the commands emitted for
+\fB\-\-disable\-triggers\fR
+must be done as superuser\&. So, you should also specify a superuser name with
+\fB\-S\fR, or preferably be careful to start the resulting script as a superuser\&.
+.sp
+This option is ignored when emitting an archive (non\-text) output file\&. For the archive formats, you can specify the option when you call
+\fBpg_restore\fR\&.
+.RE
+.PP
+\fB\-\-enable\-row\-security\fR
+.RS 4
+This option is relevant only when dumping the contents of a table which has row security\&. By default,
+pg_dump
+will set
+row_security
+to off, to ensure that all data is dumped from the table\&. If the user does not have sufficient privileges to bypass row security, then an error is thrown\&. This parameter instructs
+pg_dump
+to set
+row_security
+to on instead, allowing the user to dump the parts of the contents of the table that they have access to\&.
+.sp
+Note that if you use this option currently, you probably also want the dump be in
+\fBINSERT\fR
+format, as the
+\fBCOPY FROM\fR
+during restore does not support row security\&.
+.RE
+.PP
+\fB\-\-exclude\-table\-data=\fR\fB\fIpattern\fR\fR
+.RS 4
+Do not dump data for any tables matching
+\fIpattern\fR\&. The pattern is interpreted according to the same rules as for
+\fB\-t\fR\&.
+\fB\-\-exclude\-table\-data\fR
+can be given more than once to exclude tables matching any of several patterns\&. This option is useful when you need the definition of a particular table even though you do not need the data in it\&.
+.sp
+To exclude data for all tables in the database, see
+\fB\-\-schema\-only\fR\&.
+.RE
+.PP
+\fB\-\-extra\-float\-digits=\fR\fB\fIndigits\fR\fR
+.RS 4
+Use the specified value of
+\fBextra_float_digits\fR
+when dumping floating\-point data, instead of the maximum available precision\&. Routine dumps made for backup purposes should not use this option\&.
+.RE
+.PP
+\fB\-\-if\-exists\fR
+.RS 4
+Use conditional commands (i\&.e\&., add an
+IF EXISTS
+clause) when cleaning database objects\&. This option is not valid unless
+\fB\-\-clean\fR
+is also specified\&.
+.RE
+.PP
+\fB\-\-include\-foreign\-data=\fR\fB\fIforeignserver\fR\fR
+.RS 4
+Dump the data for any foreign table with a foreign server matching
+\fIforeignserver\fR
+pattern\&. Multiple foreign servers can be selected by writing multiple
+\fB\-\-include\-foreign\-data\fR
+switches\&. Also, the
+\fIforeignserver\fR
+parameter is interpreted as a pattern according to the same rules used by
+psql\*(Aqs
+\ed
+commands (see
+Patterns
+below), so multiple foreign servers can also be selected by writing wildcard characters in the pattern\&. When using wildcards, be careful to quote the pattern if needed to prevent the shell from expanding the wildcards; see
+Examples
+below\&. The only exception is that an empty pattern is disallowed\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+When
+\fB\-\-include\-foreign\-data\fR
+is specified,
+pg_dump
+does not check that the foreign table is writable\&. Therefore, there is no guarantee that the results of a foreign table dump can be successfully restored\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-\-inserts\fR
+.RS 4
+Dump data as
+\fBINSERT\fR
+commands (rather than
+\fBCOPY\fR)\&. This will make restoration very slow; it is mainly useful for making dumps that can be loaded into non\-PostgreSQL
+databases\&. Any error during restoring will cause only rows that are part of the problematic
+\fBINSERT\fR
+to be lost, rather than the entire table contents\&. Note that the restore might fail altogether if you have rearranged column order\&. The
+\fB\-\-column\-inserts\fR
+option is safe against column order changes, though even slower\&.
+.RE
+.PP
+\fB\-\-load\-via\-partition\-root\fR
+.RS 4
+When dumping data for a table partition, make the
+\fBCOPY\fR
+or
+\fBINSERT\fR
+statements target the root of the partitioning hierarchy that contains it, rather than the partition itself\&. This causes the appropriate partition to be re\-determined for each row when the data is loaded\&. This may be useful when restoring data on a server where rows do not always fall into the same partitions as they did on the original server\&. That could happen, for example, if the partitioning column is of type text and the two systems have different definitions of the collation used to sort the partitioning column\&.
+.RE
+.PP
+\fB\-\-lock\-wait\-timeout=\fR\fB\fItimeout\fR\fR
+.RS 4
+Do not wait forever to acquire shared table locks at the beginning of the dump\&. Instead fail if unable to lock a table within the specified
+\fItimeout\fR\&. The timeout may be specified in any of the formats accepted by
+\fBSET statement_timeout\fR\&. (Allowed formats vary depending on the server version you are dumping from, but an integer number of milliseconds is accepted by all versions\&.)
+.RE
+.PP
+\fB\-\-no\-comments\fR
+.RS 4
+Do not dump comments\&.
+.RE
+.PP
+\fB\-\-no\-publications\fR
+.RS 4
+Do not dump publications\&.
+.RE
+.PP
+\fB\-\-no\-security\-labels\fR
+.RS 4
+Do not dump security labels\&.
+.RE
+.PP
+\fB\-\-no\-subscriptions\fR
+.RS 4
+Do not dump subscriptions\&.
+.RE
+.PP
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBpg_dump\fR
+will wait for all files to be written safely to disk\&. This option causes
+\fBpg_dump\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the dump corrupt\&. Generally, this option is useful for testing but should not be used when dumping data from production installation\&.
+.RE
+.PP
+\fB\-\-no\-table\-access\-method\fR
+.RS 4
+Do not output commands to select table access methods\&. With this option, all objects will be created with whichever table access method is the default during restore\&.
+.sp
+This option is ignored when emitting an archive (non\-text) output file\&. For the archive formats, you can specify the option when you call
+\fBpg_restore\fR\&.
+.RE
+.PP
+\fB\-\-no\-tablespaces\fR
+.RS 4
+Do not output commands to select tablespaces\&. With this option, all objects will be created in whichever tablespace is the default during restore\&.
+.sp
+This option is ignored when emitting an archive (non\-text) output file\&. For the archive formats, you can specify the option when you call
+\fBpg_restore\fR\&.
+.RE
+.PP
+\fB\-\-no\-toast\-compression\fR
+.RS 4
+Do not output commands to set
+TOAST
+compression methods\&. With this option, all columns will be restored with the default compression setting\&.
+.RE
+.PP
+\fB\-\-no\-unlogged\-table\-data\fR
+.RS 4
+Do not dump the contents of unlogged tables and sequences\&. This option has no effect on whether or not the table and sequence definitions (schema) are dumped; it only suppresses dumping the table and sequence data\&. Data in unlogged tables and sequences is always excluded when dumping from a standby server\&.
+.RE
+.PP
+\fB\-\-on\-conflict\-do\-nothing\fR
+.RS 4
+Add
+ON CONFLICT DO NOTHING
+to
+\fBINSERT\fR
+commands\&. This option is not valid unless
+\fB\-\-inserts\fR,
+\fB\-\-column\-inserts\fR
+or
+\fB\-\-rows\-per\-insert\fR
+is also specified\&.
+.RE
+.PP
+\fB\-\-quote\-all\-identifiers\fR
+.RS 4
+Force quoting of all identifiers\&. This option is recommended when dumping a database from a server whose
+PostgreSQL
+major version is different from
+pg_dump\*(Aqs, or when the output is intended to be loaded into a server of a different major version\&. By default,
+pg_dump
+quotes only identifiers that are reserved words in its own major version\&. This sometimes results in compatibility issues when dealing with servers of other versions that may have slightly different sets of reserved words\&. Using
+\fB\-\-quote\-all\-identifiers\fR
+prevents such issues, at the price of a harder\-to\-read dump script\&.
+.RE
+.PP
+\fB\-\-rows\-per\-insert=\fR\fB\fInrows\fR\fR
+.RS 4
+Dump data as
+\fBINSERT\fR
+commands (rather than
+\fBCOPY\fR)\&. Controls the maximum number of rows per
+\fBINSERT\fR
+command\&. The value specified must be a number greater than zero\&. Any error during restoring will cause only rows that are part of the problematic
+\fBINSERT\fR
+to be lost, rather than the entire table contents\&.
+.RE
+.PP
+\fB\-\-section=\fR\fB\fIsectionname\fR\fR
+.RS 4
+Only dump the named section\&. The section name can be
+\fBpre\-data\fR,
+\fBdata\fR, or
+\fBpost\-data\fR\&. This option can be specified more than once to select multiple sections\&. The default is to dump all sections\&.
+.sp
+The data section contains actual table data, large\-object contents, and sequence values\&. Post\-data items include definitions of indexes, triggers, rules, and constraints other than validated check constraints\&. Pre\-data items include all other data definition items\&.
+.RE
+.PP
+\fB\-\-serializable\-deferrable\fR
+.RS 4
+Use a
+serializable
+transaction for the dump, to ensure that the snapshot used is consistent with later database states; but do this by waiting for a point in the transaction stream at which no anomalies can be present, so that there isn\*(Aqt a risk of the dump failing or causing other transactions to roll back with a
+serialization_failure\&. See
+Chapter\ \&13
+for more information about transaction isolation and concurrency control\&.
+.sp
+This option is not beneficial for a dump which is intended only for disaster recovery\&. It could be useful for a dump used to load a copy of the database for reporting or other read\-only load sharing while the original database continues to be updated\&. Without it the dump may reflect a state which is not consistent with any serial execution of the transactions eventually committed\&. For example, if batch processing techniques are used, a batch may show as closed in the dump without all of the items which are in the batch appearing\&.
+.sp
+This option will make no difference if there are no read\-write transactions active when pg_dump is started\&. If read\-write transactions are active, the start of the dump may be delayed for an indeterminate length of time\&. Once running, performance with or without the switch is the same\&.
+.RE
+.PP
+\fB\-\-snapshot=\fR\fB\fIsnapshotname\fR\fR
+.RS 4
+Use the specified synchronized snapshot when making a dump of the database (see
+Table\ \&9.92
+for more details)\&.
+.sp
+This option is useful when needing to synchronize the dump with a logical replication slot (see
+Chapter\ \&49) or with a concurrent session\&.
+.sp
+In the case of a parallel dump, the snapshot name defined by this option is used rather than taking a new snapshot\&.
+.RE
+.PP
+\fB\-\-strict\-names\fR
+.RS 4
+Require that each extension (\fB\-e\fR/\fB\-\-extension\fR), schema (\fB\-n\fR/\fB\-\-schema\fR) and table (\fB\-t\fR/\fB\-\-table\fR) qualifier match at least one extension/schema/table in the database to be dumped\&. Note that if none of the extension/schema/table qualifiers find matches,
+pg_dump
+will generate an error even without
+\fB\-\-strict\-names\fR\&.
+.sp
+This option has no effect on
+\fB\-N\fR/\fB\-\-exclude\-schema\fR,
+\fB\-T\fR/\fB\-\-exclude\-table\fR, or
+\fB\-\-exclude\-table\-data\fR\&. An exclude pattern failing to match any objects is not considered an error\&.
+.RE
+.PP
+\fB\-\-use\-set\-session\-authorization\fR
+.RS 4
+Output SQL\-standard
+\fBSET SESSION AUTHORIZATION\fR
+commands instead of
+\fBALTER OWNER\fR
+commands to determine object ownership\&. This makes the dump more standards\-compatible, but depending on the history of the objects in the dump, might not restore properly\&. Also, a dump using
+\fBSET SESSION AUTHORIZATION\fR
+will certainly require superuser privileges to restore correctly, whereas
+\fBALTER OWNER\fR
+requires lesser privileges\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_dump
+command line arguments, and exit\&.
+.RE
+.PP
+The following command\-line options control the database connection parameters\&.
+.PP
+\fB\-d \fR\fB\fIdbname\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to\&. This is equivalent to specifying
+\fIdbname\fR
+as the first non\-option argument on the command line\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&. The default is taken from the
+\fBPGHOST\fR
+environment variable, if set, else a Unix domain socket connection is attempted\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&. Defaults to the
+\fBPGPORT\fR
+environment variable, if set, or a compiled\-in default\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+pg_dump
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+pg_dump
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_dump
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-role=\fR\fB\fIrolename\fR\fR
+.RS 4
+Specifies a role name to be used to create the dump\&. This option causes
+pg_dump
+to issue a
+\fBSET ROLE\fR
+\fIrolename\fR
+command after connecting to the database\&. It is useful when the authenticated user (specified by
+\fB\-U\fR) lacks privileges needed by
+pg_dump, but can switch to a role with the required rights\&. Some installations have a policy against logging in directly as a superuser, and use of this option allows dumps to be made without violating the policy\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATABASE\fR
+.br
+\fBPGHOST\fR
+.br
+\fBPGOPTIONS\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters\&.
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+pg_dump
+internally executes
+\fBSELECT\fR
+statements\&. If you have problems running
+pg_dump, make sure you are able to select information from the database using, for example,
+\fBpsql\fR(1)\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.PP
+The database activity of
+pg_dump
+is normally collected by the cumulative statistics system\&. If this is undesirable, you can set parameter
+\fItrack_counts\fR
+to false via
+\fBPGOPTIONS\fR
+or the
+ALTER USER
+command\&.
+.SH "NOTES"
+.PP
+If your database cluster has any local additions to the
+template1
+database, be careful to restore the output of
+pg_dump
+into a truly empty database; otherwise you are likely to get errors due to duplicate definitions of the added objects\&. To make an empty database without any local additions, copy from
+template0
+not
+template1, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DATABASE foo WITH TEMPLATE template0;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+When a data\-only dump is chosen and the option
+\fB\-\-disable\-triggers\fR
+is used,
+pg_dump
+emits commands to disable triggers on user tables before inserting the data, and then commands to re\-enable them after the data has been inserted\&. If the restore is stopped in the middle, the system catalogs might be left in the wrong state\&.
+.PP
+The dump file produced by
+pg_dump
+does not contain the statistics used by the optimizer to make query planning decisions\&. Therefore, it is wise to run
+\fBANALYZE\fR
+after restoring from a dump file to ensure optimal performance; see
+Section\ \&25.1.3
+and
+Section\ \&25.1.6
+for more information\&.
+.PP
+Because
+pg_dump
+is used to transfer data to newer versions of
+PostgreSQL, the output of
+pg_dump
+can be expected to load into
+PostgreSQL
+server versions newer than
+pg_dump\*(Aqs version\&.
+pg_dump
+can also dump from
+PostgreSQL
+servers older than its own version\&. (Currently, servers back to version 9\&.2 are supported\&.) However,
+pg_dump
+cannot dump from
+PostgreSQL
+servers newer than its own major version; it will refuse to even try, rather than risk making an invalid dump\&. Also, it is not guaranteed that
+pg_dump\*(Aqs output can be loaded into a server of an older major version \(em not even if the dump was taken from a server of that version\&. Loading a dump file into an older server may require manual editing of the dump file to remove syntax not understood by the older server\&. Use of the
+\fB\-\-quote\-all\-identifiers\fR
+option is recommended in cross\-version cases, as it can prevent problems arising from varying reserved\-word lists in different
+PostgreSQL
+versions\&.
+.PP
+When dumping logical replication subscriptions,
+pg_dump
+will generate
+\fBCREATE SUBSCRIPTION\fR
+commands that use the
+connect = false
+option, so that restoring the subscription does not make remote connections for creating a replication slot or for initial table copy\&. That way, the dump can be restored without requiring network access to the remote servers\&. It is then up to the user to reactivate the subscriptions in a suitable way\&. If the involved hosts have changed, the connection information might have to be changed\&. It might also be appropriate to truncate the target tables before initiating a new full table copy\&. If users intend to copy initial data during refresh they must create the slot with
+two_phase = false\&. After the initial sync, the
+two_phase
+option will be automatically enabled by the subscriber if the subscription had been originally created with
+two_phase = true
+option\&.
+.SH "EXAMPLES"
+.PP
+To dump a database called
+mydb
+into an SQL\-script file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump mydb > db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To reload such a script into a (freshly created) database named
+newdb:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpsql \-d newdb \-f db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump a database into a custom\-format archive file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-Fc mydb > db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump a database into a directory\-format archive:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-Fd mydb \-f dumpdir\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump a database into a directory\-format archive in parallel with 5 worker jobs:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-Fd mydb \-j 5 \-f dumpdir\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To reload an archive file into a (freshly created) database named
+newdb:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_restore \-d newdb db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To reload an archive file into the same database it was dumped from, discarding the current contents of that database:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_restore \-d postgres \-\-clean \-\-create db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump a single table named
+mytab:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-t mytab mydb > db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump all tables whose names start with
+emp
+in the
+detroit
+schema, except for the table named
+employee_log:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-t \*(Aqdetroit\&.emp*\*(Aq \-T detroit\&.employee_log mydb > db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump all schemas whose names start with
+east
+or
+west
+and end in
+gsm, excluding any schemas whose names contain the word
+test:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-n \*(Aqeast*gsm\*(Aq \-n \*(Aqwest*gsm\*(Aq \-N \*(Aq*test*\*(Aq mydb > db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The same, using regular expression notation to consolidate the switches:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-n \*(Aq(east|west)*gsm\*(Aq \-N \*(Aq*test*\*(Aq mydb > db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To dump all database objects except for tables whose names begin with
+ts_:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-T \*(Aqts_*\*(Aq mydb > db\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To specify an upper\-case or mixed\-case name in
+\fB\-t\fR
+and related switches, you need to double\-quote the name; else it will be folded to lower case (see
+Patterns
+below)\&. But double quotes are special to the shell, so in turn they must be quoted\&. Thus, to dump a single table with a mixed\-case name, you need something like
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-t "\e"MixedCaseName\e"" mydb > mytab\&.sql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBpg_dumpall\fR(1), \fBpg_restore\fR(1), \fBpsql\fR(1)
diff --git a/doc/src/sgml/man1/pg_dumpall.1 b/doc/src/sgml/man1/pg_dumpall.1
new file mode 100644
index 0000000..ecd216f
--- /dev/null
+++ b/doc/src/sgml/man1/pg_dumpall.1
@@ -0,0 +1,581 @@
+'\" t
+.\" Title: pg_dumpall
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_DUMPALL" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_dumpall \- extract a PostgreSQL database cluster into a script file
+.SH "SYNOPSIS"
+.HP \w'\fBpg_dumpall\fR\ 'u
+\fBpg_dumpall\fR [\fIconnection\-option\fR...] [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_dumpall
+is a utility for writing out (\(lqdumping\(rq) all
+PostgreSQL
+databases of a cluster into one script file\&. The script file contains
+SQL
+commands that can be used as input to
+\fBpsql\fR(1)
+to restore the databases\&. It does this by calling
+\fBpg_dump\fR(1)
+for each database in the cluster\&.
+pg_dumpall
+also dumps global objects that are common to all databases, namely database roles, tablespaces, and privilege grants for configuration parameters\&. (pg_dump
+does not save these objects\&.)
+.PP
+Since
+pg_dumpall
+reads tables from all databases you will most likely have to connect as a database superuser in order to produce a complete dump\&. Also you will need superuser privileges to execute the saved script in order to be allowed to add roles and create databases\&.
+.PP
+The SQL script will be written to the standard output\&. Use the
+\fB\-f\fR/\fB\-\-file\fR
+option or shell operators to redirect it into a file\&.
+.PP
+pg_dumpall
+needs to connect several times to the
+PostgreSQL
+server (once per database)\&. If you use password authentication it will ask for a password each time\&. It is convenient to have a
+~/\&.pgpass
+file in such cases\&. See
+Section\ \&34.16
+for more information\&.
+.SH "OPTIONS"
+.PP
+The following command\-line options control the content and format of the output\&.
+.PP
+\fB\-a\fR
+.br
+\fB\-\-data\-only\fR
+.RS 4
+Dump only the data, not the schema (data definitions)\&.
+.RE
+.PP
+\fB\-c\fR
+.br
+\fB\-\-clean\fR
+.RS 4
+Include SQL commands to clean (drop) databases before recreating them\&.
+\fBDROP\fR
+commands for roles and tablespaces are added as well\&.
+.RE
+.PP
+\fB\-E \fR\fB\fIencoding\fR\fR
+.br
+\fB\-\-encoding=\fR\fB\fIencoding\fR\fR
+.RS 4
+Create the dump in the specified character set encoding\&. By default, the dump is created in the database encoding\&. (Another way to get the same result is to set the
+\fBPGCLIENTENCODING\fR
+environment variable to the desired dump encoding\&.)
+.RE
+.PP
+\fB\-f \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-file=\fR\fB\fIfilename\fR\fR
+.RS 4
+Send output to the specified file\&. If this is omitted, the standard output is used\&.
+.RE
+.PP
+\fB\-g\fR
+.br
+\fB\-\-globals\-only\fR
+.RS 4
+Dump only global objects (roles and tablespaces), no databases\&.
+.RE
+.PP
+\fB\-O\fR
+.br
+\fB\-\-no\-owner\fR
+.RS 4
+Do not output commands to set ownership of objects to match the original database\&. By default,
+pg_dumpall
+issues
+\fBALTER OWNER\fR
+or
+\fBSET SESSION AUTHORIZATION\fR
+statements to set ownership of created schema elements\&. These statements will fail when the script is run unless it is started by a superuser (or the same user that owns all of the objects in the script)\&. To make a script that can be restored by any user, but will give that user ownership of all the objects, specify
+\fB\-O\fR\&.
+.RE
+.PP
+\fB\-r\fR
+.br
+\fB\-\-roles\-only\fR
+.RS 4
+Dump only roles, no databases or tablespaces\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-schema\-only\fR
+.RS 4
+Dump only the object definitions (schema), not data\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-superuser=\fR\fB\fIusername\fR\fR
+.RS 4
+Specify the superuser user name to use when disabling triggers\&. This is relevant only if
+\fB\-\-disable\-triggers\fR
+is used\&. (Usually, it\*(Aqs better to leave this out, and instead start the resulting script as superuser\&.)
+.RE
+.PP
+\fB\-t\fR
+.br
+\fB\-\-tablespaces\-only\fR
+.RS 4
+Dump only tablespaces, no databases or roles\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Specifies verbose mode\&. This will cause
+pg_dumpall
+to output start/stop times to the dump file, and progress messages to standard error\&. Repeating the option causes additional debug\-level messages to appear on standard error\&. The option is also passed down to
+pg_dump\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_dumpall
+version and exit\&.
+.RE
+.PP
+\fB\-x\fR
+.br
+\fB\-\-no\-privileges\fR
+.br
+\fB\-\-no\-acl\fR
+.RS 4
+Prevent dumping of access privileges (grant/revoke commands)\&.
+.RE
+.PP
+\fB\-\-binary\-upgrade\fR
+.RS 4
+This option is for use by in\-place upgrade utilities\&. Its use for other purposes is not recommended or supported\&. The behavior of the option may change in future releases without notice\&.
+.RE
+.PP
+\fB\-\-column\-inserts\fR
+.br
+\fB\-\-attribute\-inserts\fR
+.RS 4
+Dump data as
+\fBINSERT\fR
+commands with explicit column names (INSERT INTO \fItable\fR (\fIcolumn\fR, \&.\&.\&.) VALUES \&.\&.\&.)\&. This will make restoration very slow; it is mainly useful for making dumps that can be loaded into non\-PostgreSQL
+databases\&.
+.RE
+.PP
+\fB\-\-disable\-dollar\-quoting\fR
+.RS 4
+This option disables the use of dollar quoting for function bodies, and forces them to be quoted using SQL standard string syntax\&.
+.RE
+.PP
+\fB\-\-disable\-triggers\fR
+.RS 4
+This option is relevant only when creating a data\-only dump\&. It instructs
+pg_dumpall
+to include commands to temporarily disable triggers on the target tables while the data is restored\&. Use this if you have referential integrity checks or other triggers on the tables that you do not want to invoke during data restore\&.
+.sp
+Presently, the commands emitted for
+\fB\-\-disable\-triggers\fR
+must be done as superuser\&. So, you should also specify a superuser name with
+\fB\-S\fR, or preferably be careful to start the resulting script as a superuser\&.
+.RE
+.PP
+\fB\-\-exclude\-database=\fR\fB\fIpattern\fR\fR
+.RS 4
+Do not dump databases whose name matches
+\fIpattern\fR\&. Multiple patterns can be excluded by writing multiple
+\fB\-\-exclude\-database\fR
+switches\&. The
+\fIpattern\fR
+parameter is interpreted as a pattern according to the same rules used by
+psql\*(Aqs
+\ed
+commands (see
+Patterns
+below), so multiple databases can also be excluded by writing wildcard characters in the pattern\&. When using wildcards, be careful to quote the pattern if needed to prevent shell wildcard expansion\&.
+.RE
+.PP
+\fB\-\-extra\-float\-digits=\fR\fB\fIndigits\fR\fR
+.RS 4
+Use the specified value of extra_float_digits when dumping floating\-point data, instead of the maximum available precision\&. Routine dumps made for backup purposes should not use this option\&.
+.RE
+.PP
+\fB\-\-if\-exists\fR
+.RS 4
+Use conditional commands (i\&.e\&., add an
+IF EXISTS
+clause) to drop databases and other objects\&. This option is not valid unless
+\fB\-\-clean\fR
+is also specified\&.
+.RE
+.PP
+\fB\-\-inserts\fR
+.RS 4
+Dump data as
+\fBINSERT\fR
+commands (rather than
+\fBCOPY\fR)\&. This will make restoration very slow; it is mainly useful for making dumps that can be loaded into non\-PostgreSQL
+databases\&. Note that the restore might fail altogether if you have rearranged column order\&. The
+\fB\-\-column\-inserts\fR
+option is safer, though even slower\&.
+.RE
+.PP
+\fB\-\-load\-via\-partition\-root\fR
+.RS 4
+When dumping data for a table partition, make the
+\fBCOPY\fR
+or
+\fBINSERT\fR
+statements target the root of the partitioning hierarchy that contains it, rather than the partition itself\&. This causes the appropriate partition to be re\-determined for each row when the data is loaded\&. This may be useful when restoring data on a server where rows do not always fall into the same partitions as they did on the original server\&. That could happen, for example, if the partitioning column is of type text and the two systems have different definitions of the collation used to sort the partitioning column\&.
+.RE
+.PP
+\fB\-\-lock\-wait\-timeout=\fR\fB\fItimeout\fR\fR
+.RS 4
+Do not wait forever to acquire shared table locks at the beginning of the dump\&. Instead, fail if unable to lock a table within the specified
+\fItimeout\fR\&. The timeout may be specified in any of the formats accepted by
+\fBSET statement_timeout\fR\&.
+.RE
+.PP
+\fB\-\-no\-comments\fR
+.RS 4
+Do not dump comments\&.
+.RE
+.PP
+\fB\-\-no\-publications\fR
+.RS 4
+Do not dump publications\&.
+.RE
+.PP
+\fB\-\-no\-role\-passwords\fR
+.RS 4
+Do not dump passwords for roles\&. When restored, roles will have a null password, and password authentication will always fail until the password is set\&. Since password values aren\*(Aqt needed when this option is specified, the role information is read from the catalog view
+pg_roles
+instead of
+pg_authid\&. Therefore, this option also helps if access to
+pg_authid
+is restricted by some security policy\&.
+.RE
+.PP
+\fB\-\-no\-security\-labels\fR
+.RS 4
+Do not dump security labels\&.
+.RE
+.PP
+\fB\-\-no\-subscriptions\fR
+.RS 4
+Do not dump subscriptions\&.
+.RE
+.PP
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBpg_dumpall\fR
+will wait for all files to be written safely to disk\&. This option causes
+\fBpg_dumpall\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the dump corrupt\&. Generally, this option is useful for testing but should not be used when dumping data from production installation\&.
+.RE
+.PP
+\fB\-\-no\-table\-access\-method\fR
+.RS 4
+Do not output commands to select table access methods\&. With this option, all objects will be created with whichever table access method is the default during restore\&.
+.RE
+.PP
+\fB\-\-no\-tablespaces\fR
+.RS 4
+Do not output commands to create tablespaces nor select tablespaces for objects\&. With this option, all objects will be created in whichever tablespace is the default during restore\&.
+.RE
+.PP
+\fB\-\-no\-toast\-compression\fR
+.RS 4
+Do not output commands to set
+TOAST
+compression methods\&. With this option, all columns will be restored with the default compression setting\&.
+.RE
+.PP
+\fB\-\-no\-unlogged\-table\-data\fR
+.RS 4
+Do not dump the contents of unlogged tables\&. This option has no effect on whether or not the table definitions (schema) are dumped; it only suppresses dumping the table data\&.
+.RE
+.PP
+\fB\-\-on\-conflict\-do\-nothing\fR
+.RS 4
+Add
+ON CONFLICT DO NOTHING
+to
+\fBINSERT\fR
+commands\&. This option is not valid unless
+\fB\-\-inserts\fR
+or
+\fB\-\-column\-inserts\fR
+is also specified\&.
+.RE
+.PP
+\fB\-\-quote\-all\-identifiers\fR
+.RS 4
+Force quoting of all identifiers\&. This option is recommended when dumping a database from a server whose
+PostgreSQL
+major version is different from
+pg_dumpall\*(Aqs, or when the output is intended to be loaded into a server of a different major version\&. By default,
+pg_dumpall
+quotes only identifiers that are reserved words in its own major version\&. This sometimes results in compatibility issues when dealing with servers of other versions that may have slightly different sets of reserved words\&. Using
+\fB\-\-quote\-all\-identifiers\fR
+prevents such issues, at the price of a harder\-to\-read dump script\&.
+.RE
+.PP
+\fB\-\-rows\-per\-insert=\fR\fB\fInrows\fR\fR
+.RS 4
+Dump data as
+\fBINSERT\fR
+commands (rather than
+\fBCOPY\fR)\&. Controls the maximum number of rows per
+\fBINSERT\fR
+command\&. The value specified must be a number greater than zero\&. Any error during restoring will cause only rows that are part of the problematic
+\fBINSERT\fR
+to be lost, rather than the entire table contents\&.
+.RE
+.PP
+\fB\-\-use\-set\-session\-authorization\fR
+.RS 4
+Output SQL\-standard
+\fBSET SESSION AUTHORIZATION\fR
+commands instead of
+\fBALTER OWNER\fR
+commands to determine object ownership\&. This makes the dump more standards compatible, but depending on the history of the objects in the dump, might not restore properly\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_dumpall
+command line arguments, and exit\&.
+.RE
+.PP
+The following command\-line options control the database connection parameters\&.
+.PP
+\fB\-d \fR\fB\fIconnstr\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIconnstr\fR\fR
+.RS 4
+Specifies parameters used to connect to the server, as a
+connection string; these will override any conflicting command line options\&.
+.sp
+The option is called
+\-\-dbname
+for consistency with other client applications, but because
+pg_dumpall
+needs to connect to many databases, the database name in the connection string will be ignored\&. Use the
+\-l
+option to specify the name of the database used for the initial connection, which will dump global objects and discover what other databases should be dumped\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the database server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&. The default is taken from the
+\fBPGHOST\fR
+environment variable, if set, else a Unix domain socket connection is attempted\&.
+.RE
+.PP
+\fB\-l \fR\fB\fIdbname\fR\fR
+.br
+\fB\-\-database=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to for dumping global objects and discovering what other databases should be dumped\&. If not specified, the
+postgres
+database will be used, and if that does not exist,
+template1
+will be used\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&. Defaults to the
+\fBPGPORT\fR
+environment variable, if set, or a compiled\-in default\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+pg_dumpall
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+pg_dumpall
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_dumpall
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.sp
+Note that the password prompt will occur again for each database to be dumped\&. Usually, it\*(Aqs better to set up a
+~/\&.pgpass
+file than to rely on manual password entry\&.
+.RE
+.PP
+\fB\-\-role=\fR\fB\fIrolename\fR\fR
+.RS 4
+Specifies a role name to be used to create the dump\&. This option causes
+pg_dumpall
+to issue a
+\fBSET ROLE\fR
+\fIrolename\fR
+command after connecting to the database\&. It is useful when the authenticated user (specified by
+\fB\-U\fR) lacks privileges needed by
+pg_dumpall, but can switch to a role with the required rights\&. Some installations have a policy against logging in directly as a superuser, and use of this option allows dumps to be made without violating the policy\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGOPTIONS\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "NOTES"
+.PP
+Since
+pg_dumpall
+calls
+pg_dump
+internally, some diagnostic messages will refer to
+pg_dump\&.
+.PP
+The
+\fB\-\-clean\fR
+option can be useful even when your intention is to restore the dump script into a fresh cluster\&. Use of
+\fB\-\-clean\fR
+authorizes the script to drop and re\-create the built\-in
+postgres
+and
+template1
+databases, ensuring that those databases will retain the same properties (for instance, locale and encoding) that they had in the source cluster\&. Without the option, those databases will retain their existing database\-level properties, as well as any pre\-existing contents\&.
+.PP
+Once restored, it is wise to run
+\fBANALYZE\fR
+on each database so the optimizer has useful statistics\&. You can also run
+\fBvacuumdb \-a \-z\fR
+to analyze all databases\&.
+.PP
+The dump script should not be expected to run completely without errors\&. In particular, because the script will issue
+\fBCREATE ROLE\fR
+for every role existing in the source cluster, it is certain to get a
+\(lqrole already exists\(rq
+error for the bootstrap superuser, unless the destination cluster was initialized with a different bootstrap superuser name\&. This error is harmless and should be ignored\&. Use of the
+\fB\-\-clean\fR
+option is likely to produce additional harmless error messages about non\-existent objects, although you can minimize those by adding
+\fB\-\-if\-exists\fR\&.
+.PP
+pg_dumpall
+requires all needed tablespace directories to exist before the restore; otherwise, database creation will fail for databases in non\-default locations\&.
+.SH "EXAMPLES"
+.PP
+To dump all databases:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dumpall > db\&.out\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To restore database(s) from this file, you can use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpsql \-f db\&.out postgres\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+It is not important to which database you connect here since the script file created by
+pg_dumpall
+will contain the appropriate commands to create and connect to the saved databases\&. An exception is that if you specified
+\fB\-\-clean\fR, you must connect to the
+postgres
+database initially; the script will attempt to drop other databases immediately, and that will fail for the database you are connected to\&.
+.SH "SEE ALSO"
+.PP
+Check
+\fBpg_dump\fR(1)
+for details on possible error conditions\&.
diff --git a/doc/src/sgml/man1/pg_isready.1 b/doc/src/sgml/man1/pg_isready.1
new file mode 100644
index 0000000..89502e5
--- /dev/null
+++ b/doc/src/sgml/man1/pg_isready.1
@@ -0,0 +1,191 @@
+'\" t
+.\" Title: pg_isready
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_ISREADY" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_isready \- check the connection status of a PostgreSQL server
+.SH "SYNOPSIS"
+.HP \w'\fBpg_isready\fR\ 'u
+\fBpg_isready\fR [\fIconnection\-option\fR...] [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_isready
+is a utility for checking the connection status of a
+PostgreSQL
+database server\&. The exit status specifies the result of the connection check\&.
+.SH "OPTIONS"
+.PP
+\fB\-d \fR\fB\fIdbname\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhostname\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhostname\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix\-domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or the local Unix\-domain socket file extension on which the server is listening for connections\&. Defaults to the value of the
+\fBPGPORT\fR
+environment variable or, if not set, to the port specified at compile time, usually 5432\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Do not display status message\&. This is useful when scripting\&.
+.RE
+.PP
+\fB\-t \fR\fB\fIseconds\fR\fR
+.br
+\fB\-\-timeout=\fR\fB\fIseconds\fR\fR
+.RS 4
+The maximum number of seconds to wait when attempting connection before returning that the server is not responding\&. Setting to 0 disables\&. The default is 3 seconds\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+Connect to the database as the user
+\fIusername\fR
+instead of the default\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_isready
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_isready
+command line arguments, and exit\&.
+.RE
+.SH "EXIT STATUS"
+.PP
+pg_isready
+returns
+0
+to the shell if the server is accepting connections normally,
+1
+if the server is rejecting connections (for example during startup),
+2
+if there was no response to the connection attempt, and
+3
+if no attempt was made (for example due to invalid parameters)\&.
+.SH "ENVIRONMENT"
+.PP
+\fBpg_isready\fR, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+It is not necessary to supply correct user name, password, or database name values to obtain the server status; however, if incorrect values are provided, the server will log a failed connection attempt\&.
+.SH "EXAMPLES"
+.PP
+Standard Usage:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_isready\fR
+/tmp:5432 \- accepting connections
+$ \fBecho $?\fR
+0
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Running with connection parameters to a
+PostgreSQL
+cluster in startup:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_isready \-h localhost \-p 5433\fR
+localhost:5433 \- rejecting connections
+$ \fBecho $?\fR
+1
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Running with connection parameters to a non\-responsive
+PostgreSQL
+cluster:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_isready \-h someremotehost\fR
+someremotehost:5432 \- no response
+$ \fBecho $?\fR
+2
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+
diff --git a/doc/src/sgml/man1/pg_receivewal.1 b/doc/src/sgml/man1/pg_receivewal.1
new file mode 100644
index 0000000..8ddf2e3
--- /dev/null
+++ b/doc/src/sgml/man1/pg_receivewal.1
@@ -0,0 +1,419 @@
+'\" t
+.\" Title: pg_receivewal
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_RECEIVEWAL" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_receivewal \- stream write\-ahead logs from a PostgreSQL server
+.SH "SYNOPSIS"
+.HP \w'\fBpg_receivewal\fR\ 'u
+\fBpg_receivewal\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_receivewal
+is used to stream the write\-ahead log from a running
+PostgreSQL
+cluster\&. The write\-ahead log is streamed using the streaming replication protocol, and is written to a local directory of files\&. This directory can be used as the archive location for doing a restore using point\-in\-time recovery (see
+Section\ \&26.3)\&.
+.PP
+pg_receivewal
+streams the write\-ahead log in real time as it\*(Aqs being generated on the server, and does not wait for segments to complete like
+archive_command
+and
+archive_library
+do\&. For this reason, it is not necessary to set
+archive_timeout
+when using
+pg_receivewal\&.
+.PP
+Unlike the WAL receiver of a PostgreSQL standby server,
+pg_receivewal
+by default flushes WAL data only when a WAL file is closed\&. The option
+\fB\-\-synchronous\fR
+must be specified to flush WAL data in real time\&. Since
+pg_receivewal
+does not apply WAL, you should not allow it to become a synchronous standby when
+synchronous_commit
+equals
+remote_apply\&. If it does, it will appear to be a standby that never catches up, and will cause transaction commits to block\&. To avoid this, you should either configure an appropriate value for
+synchronous_standby_names, or specify
+\fIapplication_name\fR
+for
+pg_receivewal
+that does not match it, or change the value of
+\fIsynchronous_commit\fR
+to something other than
+remote_apply\&.
+.PP
+The write\-ahead log is streamed over a regular
+PostgreSQL
+connection and uses the replication protocol\&. The connection must be made with a user having
+REPLICATION
+permissions (see
+Section\ \&22.2) or a superuser, and
+pg_hba\&.conf
+must permit the replication connection\&. The server must also be configured with
+max_wal_senders
+set high enough to leave at least one session available for the stream\&.
+.PP
+The starting point of the write\-ahead log streaming is calculated when
+pg_receivewal
+starts:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+First, scan the directory where the WAL segment files are written and find the newest completed segment file, using as the starting point the beginning of the next WAL segment file\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+If a starting point cannot be calculated with the previous method, and if a replication slot is used, an extra
+\fBREAD_REPLICATION_SLOT\fR
+command is issued to retrieve the slot\*(Aqs
+restart_lsn
+to use as the starting point\&. This option is only available when streaming write\-ahead logs from
+PostgreSQL
+15 and up\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+If a starting point cannot be calculated with the previous method, the latest WAL flush location is used as reported by the server from an
+IDENTIFY_SYSTEM
+command\&.
+.RE
+.PP
+If the connection is lost, or if it cannot be initially established, with a non\-fatal error,
+pg_receivewal
+will retry the connection indefinitely, and reestablish streaming as soon as possible\&. To avoid this behavior, use the
+\-n
+parameter\&.
+.PP
+In the absence of fatal errors,
+pg_receivewal
+will run until terminated by the
+SIGINT
+signal (Control+C)\&.
+.SH "OPTIONS"
+.PP
+\fB\-D \fR\fB\fIdirectory\fR\fR
+.br
+\fB\-\-directory=\fR\fB\fIdirectory\fR\fR
+.RS 4
+Directory to write the output to\&.
+.sp
+This parameter is required\&.
+.RE
+.PP
+\fB\-E \fR\fB\fIlsn\fR\fR
+.br
+\fB\-\-endpos=\fR\fB\fIlsn\fR\fR
+.RS 4
+Automatically stop replication and exit with normal exit status 0 when receiving reaches the specified LSN\&.
+.sp
+If there is a record with LSN exactly equal to
+\fIlsn\fR, the record will be processed\&.
+.RE
+.PP
+\fB\-\-if\-not\-exists\fR
+.RS 4
+Do not error out when
+\fB\-\-create\-slot\fR
+is specified and a slot with the specified name already exists\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-loop\fR
+.RS 4
+Don\*(Aqt loop on connection errors\&. Instead, exit right away with an error\&.
+.RE
+.PP
+\fB\-\-no\-sync\fR
+.RS 4
+This option causes
+\fBpg_receivewal\fR
+to not force WAL data to be flushed to disk\&. This is faster, but means that a subsequent operating system crash can leave the WAL segments corrupt\&. Generally, this option is useful for testing but should not be used when doing WAL archiving on a production deployment\&.
+.sp
+This option is incompatible with
+\-\-synchronous\&.
+.RE
+.PP
+\fB\-s \fR\fB\fIinterval\fR\fR
+.br
+\fB\-\-status\-interval=\fR\fB\fIinterval\fR\fR
+.RS 4
+Specifies the number of seconds between status packets sent back to the server\&. This allows for easier monitoring of the progress from server\&. A value of zero disables the periodic status updates completely, although an update will still be sent when requested by the server, to avoid timeout disconnect\&. The default value is 10 seconds\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIslotname\fR\fR
+.br
+\fB\-\-slot=\fR\fB\fIslotname\fR\fR
+.RS 4
+Require
+pg_receivewal
+to use an existing replication slot (see
+Section\ \&27.2.6)\&. When this option is used,
+pg_receivewal
+will report a flush position to the server, indicating when each segment has been synchronized to disk so that the server can remove that segment if it is not otherwise needed\&.
+.sp
+When the replication client of
+pg_receivewal
+is configured on the server as a synchronous standby, then using a replication slot will report the flush position to the server, but only when a WAL file is closed\&. Therefore, that configuration will cause transactions on the primary to wait for a long time and effectively not work satisfactorily\&. The option
+\-\-synchronous
+(see below) must be specified in addition to make this work correctly\&.
+.RE
+.PP
+\fB\-\-synchronous\fR
+.RS 4
+Flush the WAL data to disk immediately after it has been received\&. Also send a status packet back to the server immediately after flushing, regardless of
+\-\-status\-interval\&.
+.sp
+This option should be specified if the replication client of
+pg_receivewal
+is configured on the server as a synchronous standby, to ensure that timely feedback is sent to the server\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Enables verbose mode\&.
+.RE
+.PP
+\fB\-Z \fR\fB\fIlevel\fR\fR
+.br
+\fB\-Z \fR\fB\fImethod\fR\fR\fB[:\fR\fB\fIdetail\fR\fR\fB]\fR
+.br
+\fB\-\-compress=\fR\fB\fIlevel\fR\fR
+.br
+\fB\-\-compress=\fR\fB\fImethod\fR\fR\fB[:\fR\fB\fIdetail\fR\fR\fB]\fR
+.RS 4
+Enables compression of write\-ahead logs\&.
+.sp
+The compression method can be set to
+gzip,
+lz4
+(if
+PostgreSQL
+was compiled with
+\fB\-\-with\-lz4\fR) or
+none
+for no compression\&. A compression detail string can optionally be specified\&. If the detail string is an integer, it specifies the compression level\&. Otherwise, it should be a comma\-separated list of items, each of the form
+keyword
+or
+keyword=value\&. Currently, the only supported keyword is
+level\&.
+.sp
+If no compression level is specified, the default compression level will be used\&. If only a level is specified without mentioning an algorithm,
+gzip
+compression will be used if the level is greater than 0, and no compression will be used if the level is 0\&.
+.sp
+The suffix
+\&.gz
+will automatically be added to all filenames when using
+gzip, and the suffix
+\&.lz4
+is added when using
+lz4\&.
+.RE
+.PP
+The following command\-line options control the database connection parameters\&.
+.PP
+\fB\-d \fR\fB\fIconnstr\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIconnstr\fR\fR
+.RS 4
+Specifies parameters used to connect to the server, as a
+connection string; these will override any conflicting command line options\&.
+.sp
+The option is called
+\-\-dbname
+for consistency with other client applications, but because
+pg_receivewal
+doesn\*(Aqt connect to any particular database in the cluster, database name in the connection string will be ignored\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&. The default is taken from the
+\fBPGHOST\fR
+environment variable, if set, else a Unix domain socket connection is attempted\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&. Defaults to the
+\fBPGPORT\fR
+environment variable, if set, or a compiled\-in default\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+pg_receivewal
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+pg_receivewal
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_receivewal
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+pg_receivewal
+can perform one of the two following actions in order to control physical replication slots:
+.PP
+\fB\-\-create\-slot\fR
+.RS 4
+Create a new physical replication slot with the name specified in
+\fB\-\-slot\fR, then exit\&.
+.RE
+.PP
+\fB\-\-drop\-slot\fR
+.RS 4
+Drop the replication slot with the name specified in
+\fB\-\-slot\fR, then exit\&.
+.RE
+.PP
+Other options are also available:
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_receivewal
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_receivewal
+command line arguments, and exit\&.
+.RE
+.SH "EXIT STATUS"
+.PP
+pg_receivewal
+will exit with status 0 when terminated by the
+SIGINT
+signal\&. (That is the normal way to end it\&. Hence it is not an error\&.) For fatal errors or other signals, the exit status will be nonzero\&.
+.SH "ENVIRONMENT"
+.PP
+This utility, like most other
+PostgreSQL
+utilities, uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+When using
+pg_receivewal
+instead of
+archive_command
+or
+archive_library
+as the main WAL backup method, it is strongly recommended to use replication slots\&. Otherwise, the server is free to recycle or remove write\-ahead log files before they are backed up, because it does not have any information, either from
+archive_command
+or
+archive_library
+or the replication slots, about how far the WAL stream has been archived\&. Note, however, that a replication slot will fill up the server\*(Aqs disk space if the receiver does not keep up with fetching the WAL data\&.
+.PP
+pg_receivewal
+will preserve group permissions on the received WAL files if group permissions are enabled on the source cluster\&.
+.SH "EXAMPLES"
+.PP
+To stream the write\-ahead log from the server at
+mydbserver
+and store it in the local directory
+/usr/local/pgsql/archive:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_receivewal \-h mydbserver \-D /usr/local/pgsql/archive\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBpg_basebackup\fR(1)
diff --git a/doc/src/sgml/man1/pg_recvlogical.1 b/doc/src/sgml/man1/pg_recvlogical.1
new file mode 100644
index 0000000..2d65dbe
--- /dev/null
+++ b/doc/src/sgml/man1/pg_recvlogical.1
@@ -0,0 +1,328 @@
+'\" t
+.\" Title: pg_recvlogical
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_RECVLOGICAL" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_recvlogical \- control PostgreSQL logical decoding streams
+.SH "SYNOPSIS"
+.HP \w'\fBpg_recvlogical\fR\ 'u
+\fBpg_recvlogical\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+\fBpg_recvlogical\fR
+controls logical decoding replication slots and streams data from such replication slots\&.
+.PP
+It creates a replication\-mode connection, so it is subject to the same constraints as
+\fBpg_receivewal\fR(1), plus those for logical replication (see
+Chapter\ \&49)\&.
+.PP
+\fBpg_recvlogical\fR
+has no equivalent to the logical decoding SQL interface\*(Aqs peek and get modes\&. It sends replay confirmations for data lazily as it receives it and on clean exit\&. To examine pending data on a slot without consuming it, use
+\fBpg_logical_slot_peek_changes\fR\&.
+.SH "OPTIONS"
+.PP
+At least one of the following options must be specified to select an action:
+.PP
+\fB\-\-create\-slot\fR
+.RS 4
+Create a new logical replication slot with the name specified by
+\fB\-\-slot\fR, using the output plugin specified by
+\fB\-\-plugin\fR, for the database specified by
+\fB\-\-dbname\fR\&.
+.sp
+The
+\fB\-\-two\-phase\fR
+can be specified with
+\fB\-\-create\-slot\fR
+to enable decoding of prepared transactions\&.
+.RE
+.PP
+\fB\-\-drop\-slot\fR
+.RS 4
+Drop the replication slot with the name specified by
+\fB\-\-slot\fR, then exit\&.
+.RE
+.PP
+\fB\-\-start\fR
+.RS 4
+Begin streaming changes from the logical replication slot specified by
+\fB\-\-slot\fR, continuing until terminated by a signal\&. If the server side change stream ends with a server shutdown or disconnect, retry in a loop unless
+\fB\-\-no\-loop\fR
+is specified\&.
+.sp
+The stream format is determined by the output plugin specified when the slot was created\&.
+.sp
+The connection must be to the same database used to create the slot\&.
+.RE
+.PP
+\fB\-\-create\-slot\fR
+and
+\fB\-\-start\fR
+can be specified together\&.
+\fB\-\-drop\-slot\fR
+cannot be combined with another action\&.
+.PP
+The following command\-line options control the location and format of the output and other replication behavior:
+.PP
+\fB\-E \fR\fB\fIlsn\fR\fR
+.br
+\fB\-\-endpos=\fR\fB\fIlsn\fR\fR
+.RS 4
+In
+\fB\-\-start\fR
+mode, automatically stop replication and exit with normal exit status 0 when receiving reaches the specified LSN\&. If specified when not in
+\fB\-\-start\fR
+mode, an error is raised\&.
+.sp
+If there\*(Aqs a record with LSN exactly equal to
+\fIlsn\fR, the record will be output\&.
+.sp
+The
+\fB\-\-endpos\fR
+option is not aware of transaction boundaries and may truncate output partway through a transaction\&. Any partially output transaction will not be consumed and will be replayed again when the slot is next read from\&. Individual messages are never truncated\&.
+.RE
+.PP
+\fB\-f \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-file=\fR\fB\fIfilename\fR\fR
+.RS 4
+Write received and decoded transaction data into this file\&. Use
+\-
+for
+stdout\&.
+.RE
+.PP
+\fB\-F \fR\fB\fIinterval_seconds\fR\fR
+.br
+\fB\-\-fsync\-interval=\fR\fB\fIinterval_seconds\fR\fR
+.RS 4
+Specifies how often
+pg_recvlogical
+should issue
+\fBfsync()\fR
+calls to ensure the output file is safely flushed to disk\&.
+.sp
+The server will occasionally request the client to perform a flush and report the flush position to the server\&. This setting is in addition to that, to perform flushes more frequently\&.
+.sp
+Specifying an interval of
+0
+disables issuing
+\fBfsync()\fR
+calls altogether, while still reporting progress to the server\&. In this case, data could be lost in the event of a crash\&.
+.RE
+.PP
+\fB\-I \fR\fB\fIlsn\fR\fR
+.br
+\fB\-\-startpos=\fR\fB\fIlsn\fR\fR
+.RS 4
+In
+\fB\-\-start\fR
+mode, start replication from the given LSN\&. For details on the effect of this, see the documentation in
+Chapter\ \&49
+and
+Section\ \&55.4\&. Ignored in other modes\&.
+.RE
+.PP
+\fB\-\-if\-not\-exists\fR
+.RS 4
+Do not error out when
+\fB\-\-create\-slot\fR
+is specified and a slot with the specified name already exists\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-loop\fR
+.RS 4
+When the connection to the server is lost, do not retry in a loop, just exit\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIname\fR\fR\fB[=\fR\fB\fIvalue\fR\fR\fB]\fR
+.br
+\fB\-\-option=\fR\fB\fIname\fR\fR\fB[=\fR\fB\fIvalue\fR\fR\fB]\fR
+.RS 4
+Pass the option
+\fIname\fR
+to the output plugin with, if specified, the option value
+\fIvalue\fR\&. Which options exist and their effects depends on the used output plugin\&.
+.RE
+.PP
+\fB\-P \fR\fB\fIplugin\fR\fR
+.br
+\fB\-\-plugin=\fR\fB\fIplugin\fR\fR
+.RS 4
+When creating a slot, use the specified logical decoding output plugin\&. See
+Chapter\ \&49\&. This option has no effect if the slot already exists\&.
+.RE
+.PP
+\fB\-s \fR\fB\fIinterval_seconds\fR\fR
+.br
+\fB\-\-status\-interval=\fR\fB\fIinterval_seconds\fR\fR
+.RS 4
+This option has the same effect as the option of the same name in
+\fBpg_receivewal\fR(1)\&. See the description there\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIslot_name\fR\fR
+.br
+\fB\-\-slot=\fR\fB\fIslot_name\fR\fR
+.RS 4
+In
+\fB\-\-start\fR
+mode, use the existing logical replication slot named
+\fIslot_name\fR\&. In
+\fB\-\-create\-slot\fR
+mode, create the slot with this name\&. In
+\fB\-\-drop\-slot\fR
+mode, delete the slot with this name\&.
+.RE
+.PP
+\fB\-t\fR
+.br
+\fB\-\-two\-phase\fR
+.RS 4
+Enables decoding of prepared transactions\&. This option may only be specified with
+\fB\-\-create\-slot\fR
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Enables verbose mode\&.
+.RE
+.PP
+The following command\-line options control the database connection parameters\&.
+.PP
+\fB\-d \fR\fB\fIdbname\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIdbname\fR\fR
+.RS 4
+The database to connect to\&. See the description of the actions for what this means in detail\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&. Defaults to the user name\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhostname\-or\-ip\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhostname\-or\-ip\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&. The default is taken from the
+\fBPGHOST\fR
+environment variable, if set, else a Unix domain socket connection is attempted\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&. Defaults to the
+\fBPGPORT\fR
+environment variable, if set, or a compiled\-in default\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIuser\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIuser\fR\fR
+.RS 4
+User name to connect as\&. Defaults to current operating system user name\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+pg_recvlogical
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+pg_recvlogical
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_recvlogical
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+The following additional options are available:
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_recvlogical
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_recvlogical
+command line arguments, and exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+This utility, like most other
+PostgreSQL
+utilities, uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+pg_recvlogical
+will preserve group permissions on the received WAL files if group permissions are enabled on the source cluster\&.
+.SH "EXAMPLES"
+.PP
+See
+Section\ \&49.1
+for an example\&.
+.SH "SEE ALSO"
+\fBpg_receivewal\fR(1)
diff --git a/doc/src/sgml/man1/pg_resetwal.1 b/doc/src/sgml/man1/pg_resetwal.1
new file mode 100644
index 0000000..8d15d16
--- /dev/null
+++ b/doc/src/sgml/man1/pg_resetwal.1
@@ -0,0 +1,287 @@
+'\" t
+.\" Title: pg_resetwal
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_RESETWAL" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_resetwal \- reset the write\-ahead log and other control information of a PostgreSQL database cluster
+.SH "SYNOPSIS"
+.HP \w'\fBpg_resetwal\fR\ 'u
+\fBpg_resetwal\fR [\fB\-f\fR | \fB\-\-force\fR] [\fB\-n\fR | \fB\-\-dry\-run\fR] [\fIoption\fR...] [\fB\-D\fR | \fB\-\-pgdata\fR]\fIdatadir\fR
+.SH "DESCRIPTION"
+.PP
+\fBpg_resetwal\fR
+clears the write\-ahead log (WAL) and optionally resets some other control information stored in the
+pg_control
+file\&. This function is sometimes needed if these files have become corrupted\&. It should be used only as a last resort, when the server will not start due to such corruption\&.
+.PP
+After running this command, it should be possible to start the server, but bear in mind that the database might contain inconsistent data due to partially\-committed transactions\&. You should immediately dump your data, run
+\fBinitdb\fR, and restore\&. After restore, check for inconsistencies and repair as needed\&.
+.PP
+This utility can only be run by the user who installed the server, because it requires read/write access to the data directory\&. For safety reasons, you must specify the data directory on the command line\&.
+\fBpg_resetwal\fR
+does not use the environment variable
+\fBPGDATA\fR\&.
+.PP
+If
+\fBpg_resetwal\fR
+complains that it cannot determine valid data for
+pg_control, you can force it to proceed anyway by specifying the
+\fB\-f\fR
+(force) option\&. In this case plausible values will be substituted for the missing data\&. Most of the fields can be expected to match, but manual assistance might be needed for the next OID, next transaction ID and epoch, next multitransaction ID and offset, and WAL starting location fields\&. These fields can be set using the options discussed below\&. If you are not able to determine correct values for all these fields,
+\fB\-f\fR
+can still be used, but the recovered database must be treated with even more suspicion than usual: an immediate dump and restore is imperative\&.
+\fIDo not\fR
+execute any data\-modifying operations in the database before you dump, as any such action is likely to make the corruption worse\&.
+.SH "OPTIONS"
+.PP
+\fB\-f\fR
+.br
+\fB\-\-force\fR
+.RS 4
+Force
+\fBpg_resetwal\fR
+to proceed even if it cannot determine valid data for
+pg_control, as explained above\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-dry\-run\fR
+.RS 4
+The
+\fB\-n\fR/\fB\-\-dry\-run\fR
+option instructs
+\fBpg_resetwal\fR
+to print the values reconstructed from
+pg_control
+and values about to be changed, and then exit without modifying anything\&. This is mainly a debugging tool, but can be useful as a sanity check before allowing
+\fBpg_resetwal\fR
+to proceed for real\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Display version information, then exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help, then exit\&.
+.RE
+.PP
+The following options are only needed when
+\fBpg_resetwal\fR
+is unable to determine appropriate values by reading
+pg_control\&. Safe values can be determined as described below\&. For values that take numeric arguments, hexadecimal values can be specified by using the prefix
+0x\&.
+.PP
+\fB\-c \fR\fB\fIxid\fR\fR\fB,\fR\fB\fIxid\fR\fR
+.br
+\fB\-\-commit\-timestamp\-ids=\fR\fB\fIxid\fR\fR\fB,\fR\fB\fIxid\fR\fR
+.RS 4
+Manually set the oldest and newest transaction IDs for which the commit time can be retrieved\&.
+.sp
+A safe value for the oldest transaction ID for which the commit time can be retrieved (first part) can be determined by looking for the numerically smallest file name in the directory
+pg_commit_ts
+under the data directory\&. Conversely, a safe value for the newest transaction ID for which the commit time can be retrieved (second part) can be determined by looking for the numerically greatest file name in the same directory\&. The file names are in hexadecimal\&.
+.RE
+.PP
+\fB\-e \fR\fB\fIxid_epoch\fR\fR
+.br
+\fB\-\-epoch=\fR\fB\fIxid_epoch\fR\fR
+.RS 4
+Manually set the next transaction ID\*(Aqs epoch\&.
+.sp
+The transaction ID epoch is not actually stored anywhere in the database except in the field that is set by
+\fBpg_resetwal\fR, so any value will work so far as the database itself is concerned\&. You might need to adjust this value to ensure that replication systems such as
+Slony\-I
+and
+Skytools
+work correctly \(em if so, an appropriate value should be obtainable from the state of the downstream replicated database\&.
+.RE
+.PP
+\fB\-l \fR\fB\fIwalfile\fR\fR
+.br
+\fB\-\-next\-wal\-file=\fR\fB\fIwalfile\fR\fR
+.RS 4
+Manually set the WAL starting location by specifying the name of the next WAL segment file\&.
+.sp
+The name of next WAL segment file should be larger than any WAL segment file name currently existing in the directory
+pg_wal
+under the data directory\&. These names are also in hexadecimal and have three parts\&. The first part is the
+\(lqtimeline ID\(rq
+and should usually be kept the same\&. For example, if
+00000001000000320000004A
+is the largest entry in
+pg_wal, use
+\-l 00000001000000320000004B
+or higher\&.
+.sp
+Note that when using nondefault WAL segment sizes, the numbers in the WAL file names are different from the LSNs that are reported by system functions and system views\&. This option takes a WAL file name, not an LSN\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+\fBpg_resetwal\fR
+itself looks at the files in
+pg_wal
+and chooses a default
+\fB\-l\fR
+setting beyond the last existing file name\&. Therefore, manual adjustment of
+\fB\-l\fR
+should only be needed if you are aware of WAL segment files that are not currently present in
+pg_wal, such as entries in an offline archive; or if the contents of
+pg_wal
+have been lost entirely\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-m \fR\fB\fImxid\fR\fR\fB,\fR\fB\fImxid\fR\fR
+.br
+\fB\-\-multixact\-ids=\fR\fB\fImxid\fR\fR\fB,\fR\fB\fImxid\fR\fR
+.RS 4
+Manually set the next and oldest multitransaction ID\&.
+.sp
+A safe value for the next multitransaction ID (first part) can be determined by looking for the numerically largest file name in the directory
+pg_multixact/offsets
+under the data directory, adding one, and then multiplying by 65536 (0x10000)\&. Conversely, a safe value for the oldest multitransaction ID (second part of
+\fB\-m\fR) can be determined by looking for the numerically smallest file name in the same directory and multiplying by 65536\&. The file names are in hexadecimal, so the easiest way to do this is to specify the option value in hexadecimal and append four zeroes\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIoid\fR\fR
+.br
+\fB\-\-next\-oid=\fR\fB\fIoid\fR\fR
+.RS 4
+Manually set the next OID\&.
+.sp
+There is no comparably easy way to determine a next OID that\*(Aqs beyond the largest one in the database, but fortunately it is not critical to get the next\-OID setting right\&.
+.RE
+.PP
+\fB\-O \fR\fB\fImxoff\fR\fR
+.br
+\fB\-\-multixact\-offset=\fR\fB\fImxoff\fR\fR
+.RS 4
+Manually set the next multitransaction offset\&.
+.sp
+A safe value can be determined by looking for the numerically largest file name in the directory
+pg_multixact/members
+under the data directory, adding one, and then multiplying by 52352 (0xCC80)\&. The file names are in hexadecimal\&. There is no simple recipe such as the ones for other options of appending zeroes\&.
+.RE
+.PP
+\fB\-\-wal\-segsize=\fR\fB\fIwal_segment_size\fR\fR
+.RS 4
+Set the new WAL segment size, in megabytes\&. The value must be set to a power of 2 between 1 and 1024 (megabytes)\&. See the same option of
+\fBinitdb\fR(1)
+for more information\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+While
+\fBpg_resetwal\fR
+will set the WAL starting address beyond the latest existing WAL segment file, some segment size changes can cause previous WAL file names to be reused\&. It is recommended to use
+\fB\-l\fR
+together with this option to manually set the WAL starting address if WAL file name overlap will cause problems with your archiving strategy\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-u \fR\fB\fIxid\fR\fR
+.br
+\fB\-\-oldest\-transaction\-id=\fR\fB\fIxid\fR\fR
+.RS 4
+Manually set the oldest unfrozen transaction ID\&.
+.sp
+A safe value can be determined by looking for the numerically smallest file name in the directory
+pg_xact
+under the data directory and then multiplying by 1048576 (0x100000)\&. Note that the file names are in hexadecimal\&. It is usually easiest to specify the option value in hexadecimal too\&. For example, if
+0007
+is the smallest entry in
+pg_xact,
+\-u 0x700000
+will work (five trailing zeroes provide the proper multiplier)\&.
+.RE
+.PP
+\fB\-x \fR\fB\fIxid\fR\fR
+.br
+\fB\-\-next\-transaction\-id=\fR\fB\fIxid\fR\fR
+.RS 4
+Manually set the next transaction ID\&.
+.sp
+A safe value can be determined by looking for the numerically largest file name in the directory
+pg_xact
+under the data directory, adding one, and then multiplying by 1048576 (0x100000)\&. Note that the file names are in hexadecimal\&. It is usually easiest to specify the option value in hexadecimal too\&. For example, if
+0011
+is the largest entry in
+pg_xact,
+\-x 0x1200000
+will work (five trailing zeroes provide the proper multiplier)\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.SH "NOTES"
+.PP
+This command must not be used when the server is running\&.
+\fBpg_resetwal\fR
+will refuse to start up if it finds a server lock file in the data directory\&. If the server crashed then a lock file might have been left behind; in that case you can remove the lock file to allow
+\fBpg_resetwal\fR
+to run\&. But before you do so, make doubly certain that there is no server process still alive\&.
+.PP
+\fBpg_resetwal\fR
+works only with servers of the same major version\&.
+.SH "SEE ALSO"
+\fBpg_controldata\fR(1)
diff --git a/doc/src/sgml/man1/pg_restore.1 b/doc/src/sgml/man1/pg_restore.1
new file mode 100644
index 0000000..560a9f5
--- /dev/null
+++ b/doc/src/sgml/man1/pg_restore.1
@@ -0,0 +1,873 @@
+'\" t
+.\" Title: pg_restore
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_RESTORE" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_restore \- restore a PostgreSQL database from an archive file created by pg_dump
+.SH "SYNOPSIS"
+.HP \w'\fBpg_restore\fR\ 'u
+\fBpg_restore\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\fIfilename\fR]
+.SH "DESCRIPTION"
+.PP
+pg_restore
+is a utility for restoring a
+PostgreSQL
+database from an archive created by
+\fBpg_dump\fR(1)
+in one of the non\-plain\-text formats\&. It will issue the commands necessary to reconstruct the database to the state it was in at the time it was saved\&. The archive files also allow
+pg_restore
+to be selective about what is restored, or even to reorder the items prior to being restored\&. The archive files are designed to be portable across architectures\&.
+.PP
+pg_restore
+can operate in two modes\&. If a database name is specified,
+pg_restore
+connects to that database and restores archive contents directly into the database\&. Otherwise, a script containing the SQL commands necessary to rebuild the database is created and written to a file or standard output\&. This script output is equivalent to the plain text output format of
+pg_dump\&. Some of the options controlling the output are therefore analogous to
+pg_dump
+options\&.
+.PP
+Obviously,
+pg_restore
+cannot restore information that is not present in the archive file\&. For instance, if the archive was made using the
+\(lqdump data as \fBINSERT\fR commands\(rq
+option,
+pg_restore
+will not be able to load the data using
+\fBCOPY\fR
+statements\&.
+.SH "OPTIONS"
+.PP
+pg_restore
+accepts the following command line arguments\&.
+.PP
+\fIfilename\fR
+.RS 4
+Specifies the location of the archive file (or directory, for a directory\-format archive) to be restored\&. If not specified, the standard input is used\&.
+.RE
+.PP
+\fB\-a\fR
+.br
+\fB\-\-data\-only\fR
+.RS 4
+Restore only the data, not the schema (data definitions)\&. Table data, large objects, and sequence values are restored, if present in the archive\&.
+.sp
+This option is similar to, but for historical reasons not identical to, specifying
+\fB\-\-section=data\fR\&.
+.RE
+.PP
+\fB\-c\fR
+.br
+\fB\-\-clean\fR
+.RS 4
+Clean (drop) database objects before recreating them\&. (Unless
+\fB\-\-if\-exists\fR
+is used, this might generate some harmless error messages, if any objects were not present in the destination database\&.)
+.RE
+.PP
+\fB\-C\fR
+.br
+\fB\-\-create\fR
+.RS 4
+Create the database before restoring into it\&. If
+\fB\-\-clean\fR
+is also specified, drop and recreate the target database before connecting to it\&.
+.sp
+With
+\fB\-\-create\fR,
+pg_restore
+also restores the database\*(Aqs comment if any, and any configuration variable settings that are specific to this database, that is, any
+\fBALTER DATABASE \&.\&.\&. SET \&.\&.\&.\fR
+and
+\fBALTER ROLE \&.\&.\&. IN DATABASE \&.\&.\&. SET \&.\&.\&.\fR
+commands that mention this database\&. Access privileges for the database itself are also restored, unless
+\fB\-\-no\-acl\fR
+is specified\&.
+.sp
+When this option is used, the database named with
+\fB\-d\fR
+is used only to issue the initial
+\fBDROP DATABASE\fR
+and
+\fBCREATE DATABASE\fR
+commands\&. All data is restored into the database name that appears in the archive\&.
+.RE
+.PP
+\fB\-d \fR\fB\fIdbname\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIdbname\fR\fR
+.RS 4
+Connect to database
+\fIdbname\fR
+and restore directly into the database\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-exit\-on\-error\fR
+.RS 4
+Exit if an error is encountered while sending SQL commands to the database\&. The default is to continue and to display a count of errors at the end of the restoration\&.
+.RE
+.PP
+\fB\-f \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-file=\fR\fB\fIfilename\fR\fR
+.RS 4
+Specify output file for generated script, or for the listing when used with
+\fB\-l\fR\&. Use
+\-
+for
+stdout\&.
+.RE
+.PP
+\fB\-F \fR\fB\fIformat\fR\fR
+.br
+\fB\-\-format=\fR\fB\fIformat\fR\fR
+.RS 4
+Specify format of the archive\&. It is not necessary to specify the format, since
+pg_restore
+will determine the format automatically\&. If specified, it can be one of the following:
+.PP
+c
+.br
+custom
+.RS 4
+The archive is in the custom format of
+pg_dump\&.
+.RE
+.PP
+d
+.br
+directory
+.RS 4
+The archive is a directory archive\&.
+.RE
+.PP
+t
+.br
+tar
+.RS 4
+The archive is a
+\fBtar\fR
+archive\&.
+.RE
+.RE
+.PP
+\fB\-I \fR\fB\fIindex\fR\fR
+.br
+\fB\-\-index=\fR\fB\fIindex\fR\fR
+.RS 4
+Restore definition of named index only\&. Multiple indexes may be specified with multiple
+\fB\-I\fR
+switches\&.
+.RE
+.PP
+\fB\-j \fR\fB\fInumber\-of\-jobs\fR\fR
+.br
+\fB\-\-jobs=\fR\fB\fInumber\-of\-jobs\fR\fR
+.RS 4
+Run the most time\-consuming steps of
+pg_restore
+\(em those that load data, create indexes, or create constraints \(em concurrently, using up to
+\fInumber\-of\-jobs\fR
+concurrent sessions\&. This option can dramatically reduce the time to restore a large database to a server running on a multiprocessor machine\&. This option is ignored when emitting a script rather than connecting directly to a database server\&.
+.sp
+Each job is one process or one thread, depending on the operating system, and uses a separate connection to the server\&.
+.sp
+The optimal value for this option depends on the hardware setup of the server, of the client, and of the network\&. Factors include the number of CPU cores and the disk setup\&. A good place to start is the number of CPU cores on the server, but values larger than that can also lead to faster restore times in many cases\&. Of course, values that are too high will lead to decreased performance because of thrashing\&.
+.sp
+Only the custom and directory archive formats are supported with this option\&. The input must be a regular file or directory (not, for example, a pipe or standard input)\&. Also, multiple jobs cannot be used together with the option
+\fB\-\-single\-transaction\fR\&.
+.RE
+.PP
+\fB\-l\fR
+.br
+\fB\-\-list\fR
+.RS 4
+List the table of contents of the archive\&. The output of this operation can be used as input to the
+\fB\-L\fR
+option\&. Note that if filtering switches such as
+\fB\-n\fR
+or
+\fB\-t\fR
+are used with
+\fB\-l\fR, they will restrict the items listed\&.
+.RE
+.PP
+\fB\-L \fR\fB\fIlist\-file\fR\fR
+.br
+\fB\-\-use\-list=\fR\fB\fIlist\-file\fR\fR
+.RS 4
+Restore only those archive elements that are listed in
+\fIlist\-file\fR, and restore them in the order they appear in the file\&. Note that if filtering switches such as
+\fB\-n\fR
+or
+\fB\-t\fR
+are used with
+\fB\-L\fR, they will further restrict the items restored\&.
+.sp
+\fIlist\-file\fR
+is normally created by editing the output of a previous
+\fB\-l\fR
+operation\&. Lines can be moved or removed, and can also be commented out by placing a semicolon (;) at the start of the line\&. See below for examples\&.
+.RE
+.PP
+\fB\-n \fR\fB\fIschema\fR\fR
+.br
+\fB\-\-schema=\fR\fB\fIschema\fR\fR
+.RS 4
+Restore only objects that are in the named schema\&. Multiple schemas may be specified with multiple
+\fB\-n\fR
+switches\&. This can be combined with the
+\fB\-t\fR
+option to restore just a specific table\&.
+.RE
+.PP
+\fB\-N \fR\fB\fIschema\fR\fR
+.br
+\fB\-\-exclude\-schema=\fR\fB\fIschema\fR\fR
+.RS 4
+Do not restore objects that are in the named schema\&. Multiple schemas to be excluded may be specified with multiple
+\fB\-N\fR
+switches\&.
+.sp
+When both
+\fB\-n\fR
+and
+\fB\-N\fR
+are given for the same schema name, the
+\fB\-N\fR
+switch wins and the schema is excluded\&.
+.RE
+.PP
+\fB\-O\fR
+.br
+\fB\-\-no\-owner\fR
+.RS 4
+Do not output commands to set ownership of objects to match the original database\&. By default,
+pg_restore
+issues
+\fBALTER OWNER\fR
+or
+\fBSET SESSION AUTHORIZATION\fR
+statements to set ownership of created schema elements\&. These statements will fail unless the initial connection to the database is made by a superuser (or the same user that owns all of the objects in the script)\&. With
+\fB\-O\fR, any user name can be used for the initial connection, and this user will own all the created objects\&.
+.RE
+.PP
+\fB\-P \fR\fB\fIfunction\-name(argtype [, \&.\&.\&.])\fR\fR
+.br
+\fB\-\-function=\fR\fB\fIfunction\-name(argtype [, \&.\&.\&.])\fR\fR
+.RS 4
+Restore the named function only\&. Be careful to spell the function name and arguments exactly as they appear in the dump file\*(Aqs table of contents\&. Multiple functions may be specified with multiple
+\fB\-P\fR
+switches\&.
+.RE
+.PP
+\fB\-R\fR
+.br
+\fB\-\-no\-reconnect\fR
+.RS 4
+This option is obsolete but still accepted for backwards compatibility\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-schema\-only\fR
+.RS 4
+Restore only the schema (data definitions), not data, to the extent that schema entries are present in the archive\&.
+.sp
+This option is the inverse of
+\fB\-\-data\-only\fR\&. It is similar to, but for historical reasons not identical to, specifying
+\fB\-\-section=pre\-data \-\-section=post\-data\fR\&.
+.sp
+(Do not confuse this with the
+\fB\-\-schema\fR
+option, which uses the word
+\(lqschema\(rq
+in a different meaning\&.)
+.RE
+.PP
+\fB\-S \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-superuser=\fR\fB\fIusername\fR\fR
+.RS 4
+Specify the superuser user name to use when disabling triggers\&. This is relevant only if
+\fB\-\-disable\-triggers\fR
+is used\&.
+.RE
+.PP
+\fB\-t \fR\fB\fItable\fR\fR
+.br
+\fB\-\-table=\fR\fB\fItable\fR\fR
+.RS 4
+Restore definition and/or data of only the named table\&. For this purpose,
+\(lqtable\(rq
+includes views, materialized views, sequences, and foreign tables\&. Multiple tables can be selected by writing multiple
+\fB\-t\fR
+switches\&. This option can be combined with the
+\fB\-n\fR
+option to specify table(s) in a particular schema\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+When
+\fB\-t\fR
+is specified,
+pg_restore
+makes no attempt to restore any other database objects that the selected table(s) might depend upon\&. Therefore, there is no guarantee that a specific\-table restore into a clean database will succeed\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This flag does not behave identically to the
+\fB\-t\fR
+flag of
+pg_dump\&. There is not currently any provision for wild\-card matching in
+pg_restore, nor can you include a schema name within its
+\fB\-t\fR\&. And, while
+pg_dump\*(Aqs
+\fB\-t\fR
+flag will also dump subsidiary objects (such as indexes) of the selected table(s),
+pg_restore\*(Aqs
+\fB\-t\fR
+flag does not include such subsidiary objects\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+In versions prior to
+PostgreSQL
+9\&.6, this flag matched only tables, not any other type of relation\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-T \fR\fB\fItrigger\fR\fR
+.br
+\fB\-\-trigger=\fR\fB\fItrigger\fR\fR
+.RS 4
+Restore named trigger only\&. Multiple triggers may be specified with multiple
+\fB\-T\fR
+switches\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Specifies verbose mode\&. This will cause
+pg_restore
+to output detailed object comments and start/stop times to the output file, and progress messages to standard error\&. Repeating the option causes additional debug\-level messages to appear on standard error\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_restore
+version and exit\&.
+.RE
+.PP
+\fB\-x\fR
+.br
+\fB\-\-no\-privileges\fR
+.br
+\fB\-\-no\-acl\fR
+.RS 4
+Prevent restoration of access privileges (grant/revoke commands)\&.
+.RE
+.PP
+\fB\-1\fR
+.br
+\fB\-\-single\-transaction\fR
+.RS 4
+Execute the restore as a single transaction (that is, wrap the emitted commands in
+\fBBEGIN\fR/\fBCOMMIT\fR)\&. This ensures that either all the commands complete successfully, or no changes are applied\&. This option implies
+\fB\-\-exit\-on\-error\fR\&.
+.RE
+.PP
+\fB\-\-disable\-triggers\fR
+.RS 4
+This option is relevant only when performing a data\-only restore\&. It instructs
+pg_restore
+to execute commands to temporarily disable triggers on the target tables while the data is restored\&. Use this if you have referential integrity checks or other triggers on the tables that you do not want to invoke during data restore\&.
+.sp
+Presently, the commands emitted for
+\fB\-\-disable\-triggers\fR
+must be done as superuser\&. So you should also specify a superuser name with
+\fB\-S\fR
+or, preferably, run
+pg_restore
+as a
+PostgreSQL
+superuser\&.
+.RE
+.PP
+\fB\-\-enable\-row\-security\fR
+.RS 4
+This option is relevant only when restoring the contents of a table which has row security\&. By default,
+pg_restore
+will set
+row_security
+to off, to ensure that all data is restored in to the table\&. If the user does not have sufficient privileges to bypass row security, then an error is thrown\&. This parameter instructs
+pg_restore
+to set
+row_security
+to on instead, allowing the user to attempt to restore the contents of the table with row security enabled\&. This might still fail if the user does not have the right to insert the rows from the dump into the table\&.
+.sp
+Note that this option currently also requires the dump be in
+\fBINSERT\fR
+format, as
+\fBCOPY FROM\fR
+does not support row security\&.
+.RE
+.PP
+\fB\-\-if\-exists\fR
+.RS 4
+Use conditional commands (i\&.e\&., add an
+IF EXISTS
+clause) to drop database objects\&. This option is not valid unless
+\fB\-\-clean\fR
+is also specified\&.
+.RE
+.PP
+\fB\-\-no\-comments\fR
+.RS 4
+Do not output commands to restore comments, even if the archive contains them\&.
+.RE
+.PP
+\fB\-\-no\-data\-for\-failed\-tables\fR
+.RS 4
+By default, table data is restored even if the creation command for the table failed (e\&.g\&., because it already exists)\&. With this option, data for such a table is skipped\&. This behavior is useful if the target database already contains the desired table contents\&. For example, auxiliary tables for
+PostgreSQL
+extensions such as
+PostGIS
+might already be loaded in the target database; specifying this option prevents duplicate or obsolete data from being loaded into them\&.
+.sp
+This option is effective only when restoring directly into a database, not when producing SQL script output\&.
+.RE
+.PP
+\fB\-\-no\-publications\fR
+.RS 4
+Do not output commands to restore publications, even if the archive contains them\&.
+.RE
+.PP
+\fB\-\-no\-security\-labels\fR
+.RS 4
+Do not output commands to restore security labels, even if the archive contains them\&.
+.RE
+.PP
+\fB\-\-no\-subscriptions\fR
+.RS 4
+Do not output commands to restore subscriptions, even if the archive contains them\&.
+.RE
+.PP
+\fB\-\-no\-table\-access\-method\fR
+.RS 4
+Do not output commands to select table access methods\&. With this option, all objects will be created with whichever access method is the default during restore\&.
+.RE
+.PP
+\fB\-\-no\-tablespaces\fR
+.RS 4
+Do not output commands to select tablespaces\&. With this option, all objects will be created in whichever tablespace is the default during restore\&.
+.RE
+.PP
+\fB\-\-section=\fR\fB\fIsectionname\fR\fR
+.RS 4
+Only restore the named section\&. The section name can be
+\fBpre\-data\fR,
+\fBdata\fR, or
+\fBpost\-data\fR\&. This option can be specified more than once to select multiple sections\&. The default is to restore all sections\&.
+.sp
+The data section contains actual table data as well as large\-object definitions\&. Post\-data items consist of definitions of indexes, triggers, rules and constraints other than validated check constraints\&. Pre\-data items consist of all other data definition items\&.
+.RE
+.PP
+\fB\-\-strict\-names\fR
+.RS 4
+Require that each schema (\fB\-n\fR/\fB\-\-schema\fR) and table (\fB\-t\fR/\fB\-\-table\fR) qualifier match at least one schema/table in the backup file\&.
+.RE
+.PP
+\fB\-\-use\-set\-session\-authorization\fR
+.RS 4
+Output SQL\-standard
+\fBSET SESSION AUTHORIZATION\fR
+commands instead of
+\fBALTER OWNER\fR
+commands to determine object ownership\&. This makes the dump more standards\-compatible, but depending on the history of the objects in the dump, might not restore properly\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_restore
+command line arguments, and exit\&.
+.RE
+.PP
+pg_restore
+also accepts the following command line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&. The default is taken from the
+\fBPGHOST\fR
+environment variable, if set, else a Unix domain socket connection is attempted\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&. Defaults to the
+\fBPGPORT\fR
+environment variable, if set, or a compiled\-in default\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+pg_restore
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+pg_restore
+will automatically prompt for a password if the server demands password authentication\&. However,
+pg_restore
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-role=\fR\fB\fIrolename\fR\fR
+.RS 4
+Specifies a role name to be used to perform the restore\&. This option causes
+pg_restore
+to issue a
+\fBSET ROLE\fR
+\fIrolename\fR
+command after connecting to the database\&. It is useful when the authenticated user (specified by
+\fB\-U\fR) lacks privileges needed by
+pg_restore, but can switch to a role with the required rights\&. Some installations have a policy against logging in directly as a superuser, and use of this option allows restores to be performed without violating the policy\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGOPTIONS\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&. However, it does not read
+\fBPGDATABASE\fR
+when a database name is not supplied\&.
+.SH "DIAGNOSTICS"
+.PP
+When a direct database connection is specified using the
+\fB\-d\fR
+option,
+pg_restore
+internally executes
+SQL
+statements\&. If you have problems running
+pg_restore, make sure you are able to select information from the database using, for example,
+\fBpsql\fR(1)\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "NOTES"
+.PP
+If your installation has any local additions to the
+template1
+database, be careful to load the output of
+pg_restore
+into a truly empty database; otherwise you are likely to get errors due to duplicate definitions of the added objects\&. To make an empty database without any local additions, copy from
+template0
+not
+template1, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DATABASE foo WITH TEMPLATE template0;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The limitations of
+pg_restore
+are detailed below\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+When restoring data to a pre\-existing table and the option
+\fB\-\-disable\-triggers\fR
+is used,
+pg_restore
+emits commands to disable triggers on user tables before inserting the data, then emits commands to re\-enable them after the data has been inserted\&. If the restore is stopped in the middle, the system catalogs might be left in the wrong state\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+pg_restore
+cannot restore large objects selectively; for instance, only those for a specific table\&. If an archive contains large objects, then all large objects will be restored, or none of them if they are excluded via
+\fB\-L\fR,
+\fB\-t\fR, or other options\&.
+.RE
+.PP
+See also the
+\fBpg_dump\fR(1)
+documentation for details on limitations of
+pg_dump\&.
+.PP
+Once restored, it is wise to run
+\fBANALYZE\fR
+on each restored table so the optimizer has useful statistics; see
+Section\ \&25.1.3
+and
+Section\ \&25.1.6
+for more information\&.
+.SH "EXAMPLES"
+.PP
+Assume we have dumped a database called
+mydb
+into a custom\-format dump file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_dump \-Fc mydb > db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To drop the database and recreate it from the dump:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBdropdb mydb\fR
+$ \fBpg_restore \-C \-d postgres db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The database named in the
+\fB\-d\fR
+switch can be any database existing in the cluster;
+pg_restore
+only uses it to issue the
+\fBCREATE DATABASE\fR
+command for
+mydb\&. With
+\fB\-C\fR, data is always restored into the database name that appears in the dump file\&.
+.PP
+To restore the dump into a new database called
+newdb:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBcreatedb \-T template0 newdb\fR
+$ \fBpg_restore \-d newdb db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Notice we don\*(Aqt use
+\fB\-C\fR, and instead connect directly to the database to be restored into\&. Also note that we clone the new database from
+template0
+not
+template1, to ensure it is initially empty\&.
+.PP
+To reorder database items, it is first necessary to dump the table of contents of the archive:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_restore \-l db\&.dump > db\&.list\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The listing file consists of a header and one line for each item, e\&.g\&.:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+;
+; Archive created at Mon Sep 14 13:55:39 2009
+; dbname: DBDEMOS
+; TOC Entries: 81
+; Compression: 9
+; Dump Version: 1\&.10\-0
+; Format: CUSTOM
+; Integer: 4 bytes
+; Offset: 8 bytes
+; Dumped from database version: 8\&.3\&.5
+; Dumped by pg_dump version: 8\&.3\&.8
+;
+;
+; Selected TOC Entries:
+;
+3; 2615 2200 SCHEMA \- public pasha
+1861; 0 0 COMMENT \- SCHEMA public pasha
+1862; 0 0 ACL \- public pasha
+317; 1247 17715 TYPE public composite pasha
+319; 1247 25899 DOMAIN public domain0 pasha
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Semicolons start a comment, and the numbers at the start of lines refer to the internal archive ID assigned to each item\&.
+.PP
+Lines in the file can be commented out, deleted, and reordered\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+10; 145433 TABLE map_resolutions postgres
+;2; 145344 TABLE species postgres
+;4; 145359 TABLE nt_header postgres
+6; 145402 TABLE species_records postgres
+;8; 145416 TABLE ss_old postgres
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+could be used as input to
+pg_restore
+and would only restore items 10 and 6, in that order:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_restore \-L db\&.list db\&.dump\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBpg_dump\fR(1), \fBpg_dumpall\fR(1), \fBpsql\fR(1)
diff --git a/doc/src/sgml/man1/pg_rewind.1 b/doc/src/sgml/man1/pg_rewind.1
new file mode 100644
index 0000000..e3a0064
--- /dev/null
+++ b/doc/src/sgml/man1/pg_rewind.1
@@ -0,0 +1,357 @@
+'\" t
+.\" Title: pg_rewind
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_REWIND" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_rewind \- synchronize a PostgreSQL data directory with another data directory that was forked from it
+.SH "SYNOPSIS"
+.HP \w'\fBpg_rewind\fR\ 'u
+\fBpg_rewind\fR [\fIoption\fR...] {\fB\-D\fR | \fB\-\-target\-pgdata\fR}\fI directory\fR {\fB\-\-source\-pgdata=\fR\fB\fIdirectory\fR\fR | \fB\-\-source\-server=\fR\fB\fIconnstr\fR\fR}
+.SH "DESCRIPTION"
+.PP
+pg_rewind
+is a tool for synchronizing a PostgreSQL cluster with another copy of the same cluster, after the clusters\*(Aq timelines have diverged\&. A typical scenario is to bring an old primary server back online after failover as a standby that follows the new primary\&.
+.PP
+After a successful rewind, the state of the target data directory is analogous to a base backup of the source data directory\&. Unlike taking a new base backup or using a tool like
+rsync,
+pg_rewind
+does not require comparing or copying unchanged relation blocks in the cluster\&. Only changed blocks from existing relation files are copied; all other files, including new relation files, configuration files, and WAL segments, are copied in full\&. As such the rewind operation is significantly faster than other approaches when the database is large and only a small fraction of blocks differ between the clusters\&.
+.PP
+pg_rewind
+examines the timeline histories of the source and target clusters to determine the point where they diverged, and expects to find WAL in the target cluster\*(Aqs
+pg_wal
+directory reaching all the way back to the point of divergence\&. The point of divergence can be found either on the target timeline, the source timeline, or their common ancestor\&. In the typical failover scenario where the target cluster was shut down soon after the divergence, this is not a problem, but if the target cluster ran for a long time after the divergence, its old WAL files might no longer be present\&. In this case, you can manually copy them from the WAL archive to the
+pg_wal
+directory, or run
+pg_rewind
+with the
+\-c
+option to automatically retrieve them from the WAL archive\&. The use of
+pg_rewind
+is not limited to failover, e\&.g\&., a standby server can be promoted, run some write transactions, and then rewound to become a standby again\&.
+.PP
+After running
+pg_rewind, WAL replay needs to complete for the data directory to be in a consistent state\&. When the target server is started again it will enter archive recovery and replay all WAL generated in the source server from the last checkpoint before the point of divergence\&. If some of the WAL was no longer available in the source server when
+pg_rewind
+was run, and therefore could not be copied by the
+pg_rewind
+session, it must be made available when the target server is started\&. This can be done by creating a
+recovery\&.signal
+file in the target data directory and by configuring a suitable
+restore_command
+in
+postgresql\&.conf\&.
+.PP
+pg_rewind
+requires that the target server either has the
+wal_log_hints
+option enabled in
+postgresql\&.conf
+or data checksums enabled when the cluster was initialized with
+initdb\&. Neither of these are currently on by default\&.
+full_page_writes
+must also be set to
+on, but is enabled by default\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBWarning\fR
+.ps -1
+.br
+.PP
+If
+pg_rewind
+fails while processing, then the data folder of the target is likely not in a state that can be recovered\&. In such a case, taking a new fresh backup is recommended\&.
+.PP
+As
+pg_rewind
+copies configuration files entirely from the source, it may be required to correct the configuration used for recovery before restarting the target server, especially if the target is reintroduced as a standby of the source\&. If you restart the server after the rewind operation has finished but without configuring recovery, the target may again diverge from the primary\&.
+.PP
+pg_rewind
+will fail immediately if it finds files it cannot write directly to\&. This can happen for example when the source and the target server use the same file mapping for read\-only SSL keys and certificates\&. If such files are present on the target server it is recommended to remove them before running
+pg_rewind\&. After doing the rewind, some of those files may have been copied from the source, in which case it may be necessary to remove the data copied and restore back the set of links used before the rewind\&.
+.sp .5v
+.RE
+.SH "OPTIONS"
+.PP
+pg_rewind
+accepts the following command\-line arguments:
+.PP
+\fB\-D \fR\fB\fIdirectory\fR\fR
+.br
+\fB\-\-target\-pgdata=\fR\fB\fIdirectory\fR\fR
+.RS 4
+This option specifies the target data directory that is synchronized with the source\&. The target server must be shut down cleanly before running
+pg_rewind
+.RE
+.PP
+\fB\-\-source\-pgdata=\fR\fB\fIdirectory\fR\fR
+.RS 4
+Specifies the file system path to the data directory of the source server to synchronize the target with\&. This option requires the source server to be cleanly shut down\&.
+.RE
+.PP
+\fB\-\-source\-server=\fR\fB\fIconnstr\fR\fR
+.RS 4
+Specifies a libpq connection string to connect to the source
+PostgreSQL
+server to synchronize the target with\&. The connection must be a normal (non\-replication) connection with a role having sufficient permissions to execute the functions used by
+pg_rewind
+on the source server (see Notes section for details) or a superuser role\&. This option requires the source server to be running and accepting connections\&.
+.RE
+.PP
+\fB\-R\fR
+.br
+\fB\-\-write\-recovery\-conf\fR
+.RS 4
+Create
+standby\&.signal
+and append connection settings to
+postgresql\&.auto\&.conf
+in the output directory\&.
+\-\-source\-server
+is mandatory with this option\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-dry\-run\fR
+.RS 4
+Do everything except actually modifying the target directory\&.
+.RE
+.PP
+\fB\-N\fR
+.br
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBpg_rewind\fR
+will wait for all files to be written safely to disk\&. This option causes
+\fBpg_rewind\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the data directory corrupt\&. Generally, this option is useful for testing but should not be used on a production installation\&.
+.RE
+.PP
+\fB\-P\fR
+.br
+\fB\-\-progress\fR
+.RS 4
+Enables progress reporting\&. Turning this on will deliver an approximate progress report while copying data from the source cluster\&.
+.RE
+.PP
+\fB\-c\fR
+.br
+\fB\-\-restore\-target\-wal\fR
+.RS 4
+Use
+\fIrestore_command\fR
+defined in the target cluster configuration to retrieve WAL files from the WAL archive if these files are no longer available in the
+pg_wal
+directory\&.
+.RE
+.PP
+\fB\-\-config\-file=\fR\fB\fIfilename\fR\fR
+.RS 4
+Use the specified main server configuration file for the target cluster\&. This affects
+pg_rewind
+when it uses internally the
+postgres
+command for the rewind operation on this cluster (when retrieving
+\fIrestore_command\fR
+with the option
+\fB\-c/\-\-restore\-target\-wal\fR
+and when forcing a completion of crash recovery)\&.
+.RE
+.PP
+\fB\-\-debug\fR
+.RS 4
+Print verbose debugging output that is mostly useful for developers debugging
+pg_rewind\&.
+.RE
+.PP
+\fB\-\-no\-ensure\-shutdown\fR
+.RS 4
+pg_rewind
+requires that the target server is cleanly shut down before rewinding\&. By default, if the target server is not shut down cleanly,
+pg_rewind
+starts the target server in single\-user mode to complete crash recovery first, and stops it\&. By passing this option,
+pg_rewind
+skips this and errors out immediately if the server is not cleanly shut down\&. Users are expected to handle the situation themselves in that case\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Display version information, then exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help, then exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+When
+\fB\-\-source\-server\fR
+option is used,
+pg_rewind
+also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+When executing
+pg_rewind
+using an online cluster as source, a role having sufficient permissions to execute the functions used by
+pg_rewind
+on the source cluster can be used instead of a superuser\&. Here is how to create such a role, named
+rewind_user
+here:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE USER rewind_user LOGIN;
+GRANT EXECUTE ON function pg_catalog\&.pg_ls_dir(text, boolean, boolean) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog\&.pg_stat_file(text, boolean) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog\&.pg_read_binary_file(text) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog\&.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+When executing
+pg_rewind
+using an online cluster as source which has been recently promoted, it is necessary to execute a
+\fBCHECKPOINT\fR
+after promotion such that its control file reflects up\-to\-date timeline information, which is used by
+pg_rewind
+to check if the target cluster can be rewound using the designated source cluster\&.
+.SS "How It Works"
+.PP
+The basic idea is to copy all file system\-level changes from the source cluster to the target cluster:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Scan the WAL log of the target cluster, starting from the last checkpoint before the point where the source cluster\*(Aqs timeline history forked off from the target cluster\&. For each WAL record, record each data block that was touched\&. This yields a list of all the data blocks that were changed in the target cluster, after the source cluster forked off\&. If some of the WAL files are no longer available, try re\-running
+pg_rewind
+with the
+\fB\-c\fR
+option to search for the missing files in the WAL archive\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+Copy all those changed blocks from the source cluster to the target cluster, either using direct file system access (\fB\-\-source\-pgdata\fR) or SQL (\fB\-\-source\-server\fR)\&. Relation files are now in a state equivalent to the moment of the last completed checkpoint prior to the point at which the WAL timelines of the source and target diverged plus the current state on the source of any blocks changed on the target after that divergence\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Copy all other files, including new relation files, WAL segments,
+pg_xact, and configuration files from the source cluster to the target cluster\&. Similarly to base backups, the contents of the directories
+pg_dynshmem/,
+pg_notify/,
+pg_replslot/,
+pg_serial/,
+pg_snapshots/,
+pg_stat_tmp/, and
+pg_subtrans/
+are omitted from the data copied from the source cluster\&. The files
+backup_label,
+tablespace_map,
+pg_internal\&.init,
+postmaster\&.opts, and
+postmaster\&.pid, as well as any file or directory beginning with
+pgsql_tmp, are omitted\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 4.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 4." 4.2
+.\}
+Create a
+backup_label
+file to begin WAL replay at the checkpoint created at failover and configure the
+pg_control
+file with a minimum consistency LSN defined as the result of
+pg_current_wal_insert_lsn()
+when rewinding from a live source or the last checkpoint LSN when rewinding from a stopped source\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 5.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 5." 4.2
+.\}
+When starting the target,
+PostgreSQL
+replays all the required WAL, resulting in a data directory in a consistent state\&.
+.RE
diff --git a/doc/src/sgml/man1/pg_test_fsync.1 b/doc/src/sgml/man1/pg_test_fsync.1
new file mode 100644
index 0000000..f7984bb
--- /dev/null
+++ b/doc/src/sgml/man1/pg_test_fsync.1
@@ -0,0 +1,100 @@
+'\" t
+.\" Title: pg_test_fsync
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_TEST_FSYNC" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_test_fsync \- determine fastest \fIwal_sync_method\fR for PostgreSQL
+.SH "SYNOPSIS"
+.HP \w'\fBpg_test_fsync\fR\ 'u
+\fBpg_test_fsync\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_test_fsync
+is intended to give you a reasonable idea of what the fastest
+wal_sync_method
+is on your specific system, as well as supplying diagnostic information in the event of an identified I/O problem\&. However, differences shown by
+pg_test_fsync
+might not make any significant difference in real database throughput, especially since many database servers are not speed\-limited by their write\-ahead logs\&.
+pg_test_fsync
+reports average file sync operation time in microseconds for each
+wal_sync_method, which can also be used to inform efforts to optimize the value of
+commit_delay\&.
+.SH "OPTIONS"
+.PP
+pg_test_fsync
+accepts the following command\-line options:
+.PP
+\fB\-f\fR
+.br
+\fB\-\-filename\fR
+.RS 4
+Specifies the file name to write test data in\&. This file should be in the same file system that the
+pg_wal
+directory is or will be placed in\&. (pg_wal
+contains the
+WAL
+files\&.) The default is
+pg_test_fsync\&.out
+in the current directory\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-secs\-per\-test\fR
+.RS 4
+Specifies the number of seconds for each test\&. The more time per test, the greater the test\*(Aqs accuracy, but the longer it takes to run\&. The default is 5 seconds, which allows the program to complete in under 2 minutes\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_test_fsync
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_test_fsync
+command line arguments, and exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "SEE ALSO"
+\fBpostgres\fR(1)
diff --git a/doc/src/sgml/man1/pg_test_timing.1 b/doc/src/sgml/man1/pg_test_timing.1
new file mode 100644
index 0000000..40c3bd9
--- /dev/null
+++ b/doc/src/sgml/man1/pg_test_timing.1
@@ -0,0 +1,208 @@
+'\" t
+.\" Title: pg_test_timing
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_TEST_TIMING" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_test_timing \- measure timing overhead
+.SH "SYNOPSIS"
+.HP \w'\fBpg_test_timing\fR\ 'u
+\fBpg_test_timing\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_test_timing
+is a tool to measure the timing overhead on your system and confirm that the system time never moves backwards\&. Systems that are slow to collect timing data can give less accurate
+\fBEXPLAIN ANALYZE\fR
+results\&.
+.SH "OPTIONS"
+.PP
+pg_test_timing
+accepts the following command\-line options:
+.PP
+\fB\-d \fR\fB\fIduration\fR\fR
+.br
+\fB\-\-duration=\fR\fB\fIduration\fR\fR
+.RS 4
+Specifies the test duration, in seconds\&. Longer durations give slightly better accuracy, and are more likely to discover problems with the system clock moving backwards\&. The default test duration is 3 seconds\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_test_timing
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_test_timing
+command line arguments, and exit\&.
+.RE
+.SH "USAGE"
+.SS "Interpreting Results"
+.PP
+Good results will show most (>90%) individual timing calls take less than one microsecond\&. Average per loop overhead will be even lower, below 100 nanoseconds\&. This example from an Intel i7\-860 system using a TSC clock source shows excellent performance:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+Testing timing overhead for 3 seconds\&.
+Per loop time including overhead: 35\&.96 ns
+Histogram of timing durations:
+ < us % of total count
+ 1 96\&.40465 80435604
+ 2 3\&.59518 2999652
+ 4 0\&.00015 126
+ 8 0\&.00002 13
+ 16 0\&.00000 2
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Note that different units are used for the per loop time than the histogram\&. The loop can have resolution within a few nanoseconds (ns), while the individual timing calls can only resolve down to one microsecond (us)\&.
+.SS "Measuring Executor Timing Overhead"
+.PP
+When the query executor is running a statement using
+\fBEXPLAIN ANALYZE\fR, individual operations are timed as well as showing a summary\&. The overhead of your system can be checked by counting rows with the
+psql
+program:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE t AS SELECT * FROM generate_series(1,100000);
+\etiming
+SELECT COUNT(*) FROM t;
+EXPLAIN ANALYZE SELECT COUNT(*) FROM t;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The i7\-860 system measured runs the count query in 9\&.8 ms while the
+\fBEXPLAIN ANALYZE\fR
+version takes 16\&.6 ms, each processing just over 100,000 rows\&. That 6\&.8 ms difference means the timing overhead per row is 68 ns, about twice what pg_test_timing estimated it would be\&. Even that relatively small amount of overhead is making the fully timed count statement take almost 70% longer\&. On more substantial queries, the timing overhead would be less problematic\&.
+.SS "Changing Time Sources"
+.PP
+On some newer Linux systems, it\*(Aqs possible to change the clock source used to collect timing data at any time\&. A second example shows the slowdown possible from switching to the slower acpi_pm time source, on the same system used for the fast results above:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
+tsc hpet acpi_pm
+# echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
+# pg_test_timing
+Per loop time including overhead: 722\&.92 ns
+Histogram of timing durations:
+ < us % of total count
+ 1 27\&.84870 1155682
+ 2 72\&.05956 2990371
+ 4 0\&.07810 3241
+ 8 0\&.01357 563
+ 16 0\&.00007 3
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+In this configuration, the sample
+\fBEXPLAIN ANALYZE\fR
+above takes 115\&.9 ms\&. That\*(Aqs 1061 ns of timing overhead, again a small multiple of what\*(Aqs measured directly by this utility\&. That much timing overhead means the actual query itself is only taking a tiny fraction of the accounted for time, most of it is being consumed in overhead instead\&. In this configuration, any
+\fBEXPLAIN ANALYZE\fR
+totals involving many timed operations would be inflated significantly by timing overhead\&.
+.PP
+FreeBSD also allows changing the time source on the fly, and it logs information about the timer selected during boot:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# dmesg | grep "Timecounter"
+Timecounter "ACPI\-fast" frequency 3579545 Hz quality 900
+Timecounter "i8254" frequency 1193182 Hz quality 0
+Timecounters tick every 10\&.000 msec
+Timecounter "TSC" frequency 2531787134 Hz quality 800
+# sysctl kern\&.timecounter\&.hardware=TSC
+kern\&.timecounter\&.hardware: ACPI\-fast \-> TSC
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Other systems may only allow setting the time source on boot\&. On older Linux systems the "clock" kernel setting is the only way to make this sort of change\&. And even on some more recent ones, the only option you\*(Aqll see for a clock source is "jiffies"\&. Jiffies are the older Linux software clock implementation, which can have good resolution when it\*(Aqs backed by fast enough timing hardware, as in this example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
+jiffies
+$ dmesg | grep time\&.c
+time\&.c: Using 3\&.579545 MHz WALL PM GTOD PIT/TSC timer\&.
+time\&.c: Detected 2400\&.153 MHz processor\&.
+$ pg_test_timing
+Testing timing overhead for 3 seconds\&.
+Per timing duration including loop overhead: 97\&.75 ns
+Histogram of timing durations:
+ < us % of total count
+ 1 90\&.23734 27694571
+ 2 9\&.75277 2993204
+ 4 0\&.00981 3010
+ 8 0\&.00007 22
+ 16 0\&.00000 1
+ 32 0\&.00000 1
+.fi
+.if n \{\
+.RE
+.\}
+.SS "Clock Hardware and Timing Accuracy"
+.PP
+Collecting accurate timing information is normally done on computers using hardware clocks with various levels of accuracy\&. With some hardware the operating systems can pass the system clock time almost directly to programs\&. A system clock can also be derived from a chip that simply provides timing interrupts, periodic ticks at some known time interval\&. In either case, operating system kernels provide a clock source that hides these details\&. But the accuracy of that clock source and how quickly it can return results varies based on the underlying hardware\&.
+.PP
+Inaccurate time keeping can result in system instability\&. Test any change to the clock source very carefully\&. Operating system defaults are sometimes made to favor reliability over best accuracy\&. And if you are using a virtual machine, look into the recommended time sources compatible with it\&. Virtual hardware faces additional difficulties when emulating timers, and there are often per operating system settings suggested by vendors\&.
+.PP
+The Time Stamp Counter (TSC) clock source is the most accurate one available on current generation CPUs\&. It\*(Aqs the preferred way to track the system time when it\*(Aqs supported by the operating system and the TSC clock is reliable\&. There are several ways that TSC can fail to provide an accurate timing source, making it unreliable\&. Older systems can have a TSC clock that varies based on the CPU temperature, making it unusable for timing\&. Trying to use TSC on some older multicore CPUs can give a reported time that\*(Aqs inconsistent among multiple cores\&. This can result in the time going backwards, a problem this program checks for\&. And even the newest systems can fail to provide accurate TSC timing with very aggressive power saving configurations\&.
+.PP
+Newer operating systems may check for the known TSC problems and switch to a slower, more stable clock source when they are seen\&. If your system supports TSC time but doesn\*(Aqt default to that, it may be disabled for a good reason\&. And some operating systems may not detect all the possible problems correctly, or will allow using TSC even in situations where it\*(Aqs known to be inaccurate\&.
+.PP
+The High Precision Event Timer (HPET) is the preferred timer on systems where it\*(Aqs available and TSC is not accurate\&. The timer chip itself is programmable to allow up to 100 nanosecond resolution, but you may not see that much accuracy in your system clock\&.
+.PP
+Advanced Configuration and Power Interface (ACPI) provides a Power Management (PM) Timer, which Linux refers to as the acpi_pm\&. The clock derived from acpi_pm will at best provide 300 nanosecond resolution\&.
+.PP
+Timers used on older PC hardware include the 8254 Programmable Interval Timer (PIT), the real\-time clock (RTC), the Advanced Programmable Interrupt Controller (APIC) timer, and the Cyclone timer\&. These timers aim for millisecond resolution\&.
+.SH "SEE ALSO"
+\fBEXPLAIN\fR(7)
diff --git a/doc/src/sgml/man1/pg_upgrade.1 b/doc/src/sgml/man1/pg_upgrade.1
new file mode 100644
index 0000000..1e80231
--- /dev/null
+++ b/doc/src/sgml/man1/pg_upgrade.1
@@ -0,0 +1,944 @@
+'\" t
+.\" Title: pg_upgrade
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_UPGRADE" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_upgrade \- upgrade a PostgreSQL server instance
+.SH "SYNOPSIS"
+.HP \w'\fBpg_upgrade\fR\ 'u
+\fBpg_upgrade\fR \fB\-b\fR \fIoldbindir\fR [\fB\-B\fR\ \fInewbindir\fR] \fB\-d\fR \fIoldconfigdir\fR \fB\-D\fR \fInewconfigdir\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_upgrade
+(formerly called
+pg_migrator) allows data stored in
+PostgreSQL
+data files to be upgraded to a later
+PostgreSQL
+major version without the data dump/restore typically required for major version upgrades, e\&.g\&., from 9\&.5\&.8 to 9\&.6\&.4 or from 10\&.7 to 11\&.2\&. It is not required for minor version upgrades, e\&.g\&., from 9\&.6\&.2 to 9\&.6\&.3 or from 10\&.1 to 10\&.2\&.
+.PP
+Major PostgreSQL releases regularly add new features that often change the layout of the system tables, but the internal data storage format rarely changes\&.
+pg_upgrade
+uses this fact to perform rapid upgrades by creating new system tables and simply reusing the old user data files\&. If a future major release ever changes the data storage format in a way that makes the old data format unreadable,
+pg_upgrade
+will not be usable for such upgrades\&. (The community will attempt to avoid such situations\&.)
+.PP
+pg_upgrade
+does its best to make sure the old and new clusters are binary\-compatible, e\&.g\&., by checking for compatible compile\-time settings, including 32/64\-bit binaries\&. It is important that any external modules are also binary compatible, though this cannot be checked by
+pg_upgrade\&.
+.PP
+pg_upgrade supports upgrades from 9\&.2\&.X and later to the current major release of
+PostgreSQL, including snapshot and beta releases\&.
+.SH "OPTIONS"
+.PP
+pg_upgrade
+accepts the following command\-line arguments:
+.PP
+\fB\-b\fR \fIbindir\fR
+.br
+\fB\-\-old\-bindir=\fR\fIbindir\fR
+.RS 4
+the old PostgreSQL executable directory; environment variable
+\fBPGBINOLD\fR
+.RE
+.PP
+\fB\-B\fR \fIbindir\fR
+.br
+\fB\-\-new\-bindir=\fR\fIbindir\fR
+.RS 4
+the new PostgreSQL executable directory; default is the directory where
+pg_upgrade
+resides; environment variable
+\fBPGBINNEW\fR
+.RE
+.PP
+\fB\-c\fR
+.br
+\fB\-\-check\fR
+.RS 4
+check clusters only, don\*(Aqt change any data
+.RE
+.PP
+\fB\-d\fR \fIconfigdir\fR
+.br
+\fB\-\-old\-datadir=\fR\fIconfigdir\fR
+.RS 4
+the old database cluster configuration directory; environment variable
+\fBPGDATAOLD\fR
+.RE
+.PP
+\fB\-D\fR \fIconfigdir\fR
+.br
+\fB\-\-new\-datadir=\fR\fIconfigdir\fR
+.RS 4
+the new database cluster configuration directory; environment variable
+\fBPGDATANEW\fR
+.RE
+.PP
+\fB\-j \fR\fB\fInjobs\fR\fR
+.br
+\fB\-\-jobs=\fR\fB\fInjobs\fR\fR
+.RS 4
+number of simultaneous processes or threads to use
+.RE
+.PP
+\fB\-k\fR
+.br
+\fB\-\-link\fR
+.RS 4
+use hard links instead of copying files to the new cluster
+.RE
+.PP
+\fB\-N\fR
+.br
+\fB\-\-no\-sync\fR
+.RS 4
+By default,
+\fBpg_upgrade\fR
+will wait for all files of the upgraded cluster to be written safely to disk\&. This option causes
+\fBpg_upgrade\fR
+to return without waiting, which is faster, but means that a subsequent operating system crash can leave the data directory corrupt\&. Generally, this option is useful for testing but should not be used on a production installation\&.
+.RE
+.PP
+\fB\-o\fR \fIoptions\fR
+.br
+\fB\-\-old\-options\fR \fIoptions\fR
+.RS 4
+options to be passed directly to the old
+\fBpostgres\fR
+command; multiple option invocations are appended
+.RE
+.PP
+\fB\-O\fR \fIoptions\fR
+.br
+\fB\-\-new\-options\fR \fIoptions\fR
+.RS 4
+options to be passed directly to the new
+\fBpostgres\fR
+command; multiple option invocations are appended
+.RE
+.PP
+\fB\-p\fR \fIport\fR
+.br
+\fB\-\-old\-port=\fR\fIport\fR
+.RS 4
+the old cluster port number; environment variable
+\fBPGPORTOLD\fR
+.RE
+.PP
+\fB\-P\fR \fIport\fR
+.br
+\fB\-\-new\-port=\fR\fIport\fR
+.RS 4
+the new cluster port number; environment variable
+\fBPGPORTNEW\fR
+.RE
+.PP
+\fB\-r\fR
+.br
+\fB\-\-retain\fR
+.RS 4
+retain SQL and log files even after successful completion
+.RE
+.PP
+\fB\-s\fR \fIdir\fR
+.br
+\fB\-\-socketdir=\fR\fIdir\fR
+.RS 4
+directory to use for postmaster sockets during upgrade; default is current working directory; environment variable
+\fBPGSOCKETDIR\fR
+.RE
+.PP
+\fB\-U\fR \fIusername\fR
+.br
+\fB\-\-username=\fR\fIusername\fR
+.RS 4
+cluster\*(Aqs install user name; environment variable
+\fBPGUSER\fR
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+enable verbose internal logging
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+display version information, then exit
+.RE
+.PP
+\fB\-\-clone\fR
+.RS 4
+Use efficient file cloning (also known as
+\(lqreflinks\(rq
+on some systems) instead of copying files to the new cluster\&. This can result in near\-instantaneous copying of the data files, giving the speed advantages of
+\fB\-k\fR/\fB\-\-link\fR
+while leaving the old cluster untouched\&.
+.sp
+File cloning is only supported on some operating systems and file systems\&. If it is selected but not supported, the
+pg_upgrade
+run will error\&. At present, it is supported on Linux (kernel 4\&.5 or later) with Btrfs and XFS (on file systems created with reflink support), and on macOS with APFS\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+show help, then exit
+.RE
+.SH "USAGE"
+.PP
+These are the steps to perform an upgrade with
+pg_upgrade:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Optionally move the old cluster: If you are using a version\-specific installation directory, e\&.g\&.,
+/opt/PostgreSQL/15, you do not need to move the old cluster\&. The graphical installers all use version\-specific installation directories\&.
+.sp
+If your installation directory is not version\-specific, e\&.g\&.,
+/usr/local/pgsql, it is necessary to move the current PostgreSQL install directory so it does not interfere with the new
+PostgreSQL
+installation\&. Once the current
+PostgreSQL
+server is shut down, it is safe to rename the PostgreSQL installation directory; assuming the old directory is
+/usr/local/pgsql, you can do:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+mv /usr/local/pgsql /usr/local/pgsql\&.old
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+to rename the directory\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+For source installs, build the new version: Build the new PostgreSQL source with
+\fBconfigure\fR
+flags that are compatible with the old cluster\&.
+pg_upgrade
+will check
+\fBpg_controldata\fR
+to make sure all settings are compatible before starting the upgrade\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Install the new PostgreSQL binaries: Install the new server\*(Aqs binaries and support files\&.
+pg_upgrade
+is included in a default installation\&.
+.sp
+For source installs, if you wish to install the new server in a custom location, use the
+prefix
+variable:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+make prefix=/usr/local/pgsql\&.new install
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 4.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 4." 4.2
+.\}
+Initialize the new PostgreSQL cluster: Initialize the new cluster using
+\fBinitdb\fR\&. Again, use compatible
+\fBinitdb\fR
+flags that match the old cluster\&. Many prebuilt installers do this step automatically\&. There is no need to start the new cluster\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 5.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 5." 4.2
+.\}
+Install extension shared object files: Many extensions and custom modules, whether from
+contrib
+or another source, use shared object files (or DLLs), e\&.g\&.,
+pgcrypto\&.so\&. If the old cluster used these, shared object files matching the new server binary must be installed in the new cluster, usually via operating system commands\&. Do not load the schema definitions, e\&.g\&.,
+\fBCREATE EXTENSION pgcrypto\fR, because these will be duplicated from the old cluster\&. If extension updates are available,
+pg_upgrade
+will report this and create a script that can be run later to update them\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 6.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 6." 4.2
+.\}
+Copy custom full\-text search files: Copy any custom full text search files (dictionary, synonym, thesaurus, stop words) from the old to the new cluster\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 7.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 7." 4.2
+.\}
+Adjust authentication: \fBpg_upgrade\fR
+will connect to the old and new servers several times, so you might want to set authentication to
+peer
+in
+pg_hba\&.conf
+or use a
+~/\&.pgpass
+file (see
+Section\ \&34.16)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 8.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 8." 4.2
+.\}
+Stop both servers: Make sure both database servers are stopped using, on Unix, e\&.g\&.:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+pg_ctl \-D /opt/PostgreSQL/9\&.6 stop
+pg_ctl \-D /opt/PostgreSQL/15 stop
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+or on Windows, using the proper service names:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+NET STOP postgresql\-9\&.6
+NET STOP postgresql\-15
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Streaming replication and log\-shipping standby servers can remain running until a later step\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 9.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 9." 4.2
+.\}
+Prepare for standby server upgrades: If you are upgrading standby servers using methods outlined in section
+Step 11, verify that the old standby servers are caught up by running
+pg_controldata
+against the old primary and standby clusters\&. Verify that the
+\(lqLatest checkpoint location\(rq
+values match in all clusters\&. (There will be a mismatch if old standby servers were shut down before the old primary or if the old standby servers are still running\&.) Also, make sure
+\fIwal_level\fR
+is not set to
+minimal
+in the
+postgresql\&.conf
+file on the new primary cluster\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 10.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 10." 4.2
+.\}
+Run pg_upgrade: Always run the
+pg_upgrade
+binary of the new server, not the old one\&.
+pg_upgrade
+requires the specification of the old and new cluster\*(Aqs data and executable (bin) directories\&. You can also specify user and port values, and whether you want the data files linked or cloned instead of the default copy behavior\&.
+.sp
+If you use link mode, the upgrade will be much faster (no file copying) and use less disk space, but you will not be able to access your old cluster once you start the new cluster after the upgrade\&. Link mode also requires that the old and new cluster data directories be in the same file system\&. (Tablespaces and
+pg_wal
+can be on different file systems\&.) Clone mode provides the same speed and disk space advantages but does not cause the old cluster to be unusable once the new cluster is started\&. Clone mode also requires that the old and new data directories be in the same file system\&. This mode is only available on certain operating systems and file systems\&.
+.sp
+The
+\fB\-\-jobs\fR
+option allows multiple CPU cores to be used for copying/linking of files and to dump and restore database schemas in parallel; a good place to start is the maximum of the number of CPU cores and tablespaces\&. This option can dramatically reduce the time to upgrade a multi\-database server running on a multiprocessor machine\&.
+.sp
+For Windows users, you must be logged into an administrative account, and then start a shell as the
+postgres
+user and set the proper path:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+RUNAS /USER:postgres "CMD\&.EXE"
+SET PATH=%PATH%;C:\eProgram Files\ePostgreSQL\e15\ebin;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+and then run
+pg_upgrade
+with quoted directories, e\&.g\&.:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+pg_upgrade\&.exe
+ \-\-old\-datadir "C:/Program Files/PostgreSQL/9\&.6/data"
+ \-\-new\-datadir "C:/Program Files/PostgreSQL/15/data"
+ \-\-old\-bindir "C:/Program Files/PostgreSQL/9\&.6/bin"
+ \-\-new\-bindir "C:/Program Files/PostgreSQL/15/bin"
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Once started,
+\fBpg_upgrade\fR
+will verify the two clusters are compatible and then do the upgrade\&. You can use
+\fBpg_upgrade \-\-check\fR
+to perform only the checks, even if the old server is still running\&.
+\fBpg_upgrade \-\-check\fR
+will also outline any manual adjustments you will need to make after the upgrade\&. If you are going to be using link or clone mode, you should use the option
+\fB\-\-link\fR
+or
+\fB\-\-clone\fR
+with
+\fB\-\-check\fR
+to enable mode\-specific checks\&.
+\fBpg_upgrade\fR
+requires write permission in the current directory\&.
+.sp
+Obviously, no one should be accessing the clusters during the upgrade\&.
+pg_upgrade
+defaults to running servers on port 50432 to avoid unintended client connections\&. You can use the same port number for both clusters when doing an upgrade because the old and new clusters will not be running at the same time\&. However, when checking an old running server, the old and new port numbers must be different\&.
+.sp
+If an error occurs while restoring the database schema,
+\fBpg_upgrade\fR
+will exit and you will have to revert to the old cluster as outlined in
+Step 17
+below\&. To try
+\fBpg_upgrade\fR
+again, you will need to modify the old cluster so the pg_upgrade schema restore succeeds\&. If the problem is a
+contrib
+module, you might need to uninstall the
+contrib
+module from the old cluster and install it in the new cluster after the upgrade, assuming the module is not being used to store user data\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 11.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 11." 4.2
+.\}
+Upgrade streaming replication and log\-shipping standby servers: If you used link mode and have Streaming Replication (see
+Section\ \&27.2.5) or Log\-Shipping (see
+Section\ \&27.2) standby servers, you can follow these steps to quickly upgrade them\&. You will not be running
+pg_upgrade
+on the standby servers, but rather
+rsync
+on the primary\&. Do not start any servers yet\&.
+.sp
+If you did
+\fInot\fR
+use link mode, do not have or do not want to use
+rsync, or want an easier solution, skip the instructions in this section and simply recreate the standby servers once
+pg_upgrade
+completes and the new primary is running\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Install the new PostgreSQL binaries on standby servers: Make sure the new binaries and support files are installed on all standby servers\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+Make sure the new standby data directories do \fInot\fR exist: Make sure the new standby data directories do
+\fInot\fR
+exist or are empty\&. If
+initdb
+was run, delete the standby servers\*(Aq new data directories\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Install extension shared object files: Install the same extension shared object files on the new standbys that you installed in the new primary cluster\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 4.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 4." 4.2
+.\}
+Stop standby servers: If the standby servers are still running, stop them now using the above instructions\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 5.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 5." 4.2
+.\}
+Save configuration files: Save any configuration files from the old standbys\*(Aq configuration directories you need to keep, e\&.g\&.,
+postgresql\&.conf
+(and any files included by it),
+postgresql\&.auto\&.conf,
+pg_hba\&.conf, because these will be overwritten or removed in the next step\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 6.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 6." 4.2
+.\}
+Run rsync: When using link mode, standby servers can be quickly upgraded using
+rsync\&. To accomplish this, from a directory on the primary server that is above the old and new database cluster directories, run this on the
+\fIprimary\fR
+for each standby server:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+rsync \-\-archive \-\-delete \-\-hard\-links \-\-size\-only \-\-no\-inc\-recursive old_cluster new_cluster remote_dir
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fBold_cluster\fR
+and
+\fBnew_cluster\fR
+are relative to the current directory on the primary, and
+\fBremote_dir\fR
+is
+\fIabove\fR
+the old and new cluster directories on the standby\&. The directory structure under the specified directories on the primary and standbys must match\&. Consult the
+rsync
+manual page for details on specifying the remote directory, e\&.g\&.,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+rsync \-\-archive \-\-delete \-\-hard\-links \-\-size\-only \-\-no\-inc\-recursive /opt/PostgreSQL/9\&.5 \e
+ /opt/PostgreSQL/9\&.6 standby\&.example\&.com:/opt/PostgreSQL
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+You can verify what the command will do using
+rsync\*(Aqs
+\fB\-\-dry\-run\fR
+option\&. While
+rsync
+must be run on the primary for at least one standby, it is possible to run
+rsync
+on an upgraded standby to upgrade other standbys, as long as the upgraded standby has not been started\&.
+.sp
+What this does is to record the links created by
+pg_upgrade\*(Aqs link mode that connect files in the old and new clusters on the primary server\&. It then finds matching files in the standby\*(Aqs old cluster and creates links for them in the standby\*(Aqs new cluster\&. Files that were not linked on the primary are copied from the primary to the standby\&. (They are usually small\&.) This provides rapid standby upgrades\&. Unfortunately,
+rsync
+needlessly copies files associated with temporary and unlogged tables because these files don\*(Aqt normally exist on standby servers\&.
+.sp
+If you have tablespaces, you will need to run a similar
+rsync
+command for each tablespace directory, e\&.g\&.:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+rsync \-\-archive \-\-delete \-\-hard\-links \-\-size\-only \-\-no\-inc\-recursive /vol1/pg_tblsp/PG_9\&.5_201510051 \e
+ /vol1/pg_tblsp/PG_9\&.6_201608131 standby\&.example\&.com:/vol1/pg_tblsp
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If you have relocated
+pg_wal
+outside the data directories,
+rsync
+must be run on those directories too\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 7.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 7." 4.2
+.\}
+Configure streaming replication and log\-shipping standby servers: Configure the servers for log shipping\&. (You do not need to run
+\fBpg_backup_start()\fR
+and
+\fBpg_backup_stop()\fR
+or take a file system backup as the standbys are still synchronized with the primary\&.) Replication slots are not copied and must be recreated\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 12.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 12." 4.2
+.\}
+Restore pg_hba\&.conf: If you modified
+pg_hba\&.conf, restore its original settings\&. It might also be necessary to adjust other configuration files in the new cluster to match the old cluster, e\&.g\&.,
+postgresql\&.conf
+(and any files included by it),
+postgresql\&.auto\&.conf\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 13.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 13." 4.2
+.\}
+Start the new server: The new server can now be safely started, and then any
+rsync\*(Aqed standby servers\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 14.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 14." 4.2
+.\}
+Post\-upgrade processing: If any post\-upgrade processing is required, pg_upgrade will issue warnings as it completes\&. It will also generate script files that must be run by the administrator\&. The script files will connect to each database that needs post\-upgrade processing\&. Each script should be run using:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+psql \-\-username=postgres \-\-file=script\&.sql postgres
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The scripts can be run in any order and can be deleted once they have been run\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+In general it is unsafe to access tables referenced in rebuild scripts until the rebuild scripts have run to completion; doing so could yield incorrect results or poor performance\&. Tables not referenced in rebuild scripts can be accessed immediately\&.
+.sp .5v
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 15.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 15." 4.2
+.\}
+Statistics: Because optimizer statistics are not transferred by
+\fBpg_upgrade\fR, you will be instructed to run a command to regenerate that information at the end of the upgrade\&. You might need to set connection parameters to match your new cluster\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 16.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 16." 4.2
+.\}
+Delete old cluster: Once you are satisfied with the upgrade, you can delete the old cluster\*(Aqs data directories by running the script mentioned when
+\fBpg_upgrade\fR
+completes\&. (Automatic deletion is not possible if you have user\-defined tablespaces inside the old data directory\&.) You can also delete the old installation directories (e\&.g\&.,
+bin,
+share)\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 17.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 17." 4.2
+.\}
+Reverting to old cluster: If, after running
+\fBpg_upgrade\fR, you wish to revert to the old cluster, there are several options:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If the
+\fB\-\-check\fR
+option was used, the old cluster was unmodified; it can be restarted\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If the
+\fB\-\-link\fR
+option was
+\fInot\fR
+used, the old cluster was unmodified; it can be restarted\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If the
+\fB\-\-link\fR
+option was used, the data files might be shared between the old and new cluster:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If
+\fBpg_upgrade\fR
+aborted before linking started, the old cluster was unmodified; it can be restarted\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If you did
+\fInot\fR
+start the new cluster, the old cluster was unmodified except that, when linking started, a
+\&.old
+suffix was appended to
+$PGDATA/global/pg_control\&. To reuse the old cluster, remove the
+\&.old
+suffix from
+$PGDATA/global/pg_control; you can then restart the old cluster\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If you did start the new cluster, it has written to shared files and it is unsafe to use the old cluster\&. The old cluster will need to be restored from backup in this case\&.
+.RE
+.RE
+.RE
+.SH "NOTES"
+.PP
+pg_upgrade
+creates various working files, such as schema dumps, stored within
+pg_upgrade_output\&.d
+in the directory of the new cluster\&. Each run creates a new subdirectory named with a timestamp formatted as per ISO 8601 (%Y%m%dT%H%M%S), where all its generated files are stored\&.
+pg_upgrade_output\&.d
+and its contained files will be removed automatically if
+pg_upgrade
+completes successfully; but in the event of trouble, the files there may provide useful debugging information\&.
+.PP
+pg_upgrade
+launches short\-lived postmasters in the old and new data directories\&. Temporary Unix socket files for communication with these postmasters are, by default, made in the current working directory\&. In some situations the path name for the current directory might be too long to be a valid socket name\&. In that case you can use the
+\fB\-s\fR
+option to put the socket files in some directory with a shorter path name\&. For security, be sure that that directory is not readable or writable by any other users\&. (This is not supported on Windows\&.)
+.PP
+All failure, rebuild, and reindex cases will be reported by
+pg_upgrade
+if they affect your installation; post\-upgrade scripts to rebuild tables and indexes will be generated automatically\&. If you are trying to automate the upgrade of many clusters, you should find that clusters with identical database schemas require the same post\-upgrade steps for all cluster upgrades; this is because the post\-upgrade steps are based on the database schemas, and not user data\&.
+.PP
+For deployment testing, create a schema\-only copy of the old cluster, insert dummy data, and upgrade that\&.
+.PP
+pg_upgrade
+does not support upgrading of databases containing table columns using these
+reg*
+OID\-referencing system data types:
+.RS 4
+regcollation
+.RE
+.RS 4
+regconfig
+.RE
+.RS 4
+regdictionary
+.RE
+.RS 4
+regnamespace
+.RE
+.RS 4
+regoper
+.RE
+.RS 4
+regoperator
+.RE
+.RS 4
+regproc
+.RE
+.RS 4
+regprocedure
+.RE
+(regclass,
+regrole, and
+regtype
+can be upgraded\&.)
+.PP
+If you want to use link mode and you do not want your old cluster to be modified when the new cluster is started, consider using the clone mode\&. If that is not available, make a copy of the old cluster and upgrade that in link mode\&. To make a valid copy of the old cluster, use
+\fBrsync\fR
+to create a dirty copy of the old cluster while the server is running, then shut down the old server and run
+\fBrsync \-\-checksum\fR
+again to update the copy with any changes to make it consistent\&. (\fB\-\-checksum\fR
+is necessary because
+\fBrsync\fR
+only has file modification\-time granularity of one second\&.) You might want to exclude some files, e\&.g\&.,
+postmaster\&.pid, as documented in
+Section\ \&26.3.3\&. If your file system supports file system snapshots or copy\-on\-write file copies, you can use that to make a backup of the old cluster and tablespaces, though the snapshot and copies must be created simultaneously or while the database server is down\&.
+.SH "SEE ALSO"
+\fBinitdb\fR(1), \fBpg_ctl\fR(1), \fBpg_dump\fR(1), \fBpostgres\fR(1)
diff --git a/doc/src/sgml/man1/pg_verifybackup.1 b/doc/src/sgml/man1/pg_verifybackup.1
new file mode 100644
index 0000000..e9eeb44
--- /dev/null
+++ b/doc/src/sgml/man1/pg_verifybackup.1
@@ -0,0 +1,217 @@
+'\" t
+.\" Title: pg_verifybackup
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_VERIFYBACKUP" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_verifybackup \- verify the integrity of a base backup of a PostgreSQL cluster
+.SH "SYNOPSIS"
+.HP \w'\fBpg_verifybackup\fR\ 'u
+\fBpg_verifybackup\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+pg_verifybackup
+is used to check the integrity of a database cluster backup taken using
+\fBpg_basebackup\fR
+against a
+backup_manifest
+generated by the server at the time of the backup\&. The backup must be stored in the "plain" format; a "tar" format backup can be checked after extracting it\&.
+.PP
+It is important to note that the validation which is performed by
+pg_verifybackup
+does not and cannot include every check which will be performed by a running server when attempting to make use of the backup\&. Even if you use this tool, you should still perform test restores and verify that the resulting databases work as expected and that they appear to contain the correct data\&. However,
+pg_verifybackup
+can detect many problems that commonly occur due to storage problems or user error\&.
+.PP
+Backup verification proceeds in four stages\&. First,
+pg_verifybackup
+reads the
+backup_manifest
+file\&. If that file does not exist, cannot be read, is malformed, or fails verification against its own internal checksum,
+pg_verifybackup
+will terminate with a fatal error\&.
+.PP
+Second,
+pg_verifybackup
+will attempt to verify that the data files currently stored on disk are exactly the same as the data files which the server intended to send, with some exceptions that are described below\&. Extra and missing files will be detected, with a few exceptions\&. This step will ignore the presence or absence of, or any modifications to,
+postgresql\&.auto\&.conf,
+standby\&.signal, and
+recovery\&.signal, because it is expected that these files may have been created or modified as part of the process of taking the backup\&. It also won\*(Aqt complain about a
+backup_manifest
+file in the target directory or about anything inside
+pg_wal, even though these files won\*(Aqt be listed in the backup manifest\&. Only files are checked; the presence or absence of directories is not verified, except indirectly: if a directory is missing, any files it should have contained will necessarily also be missing\&.
+.PP
+Next,
+pg_verifybackup
+will checksum all the files, compare the checksums against the values in the manifest, and emit errors for any files for which the computed checksum does not match the checksum stored in the manifest\&. This step is not performed for any files which produced errors in the previous step, since they are already known to have problems\&. Files which were ignored in the previous step are also ignored in this step\&.
+.PP
+Finally,
+pg_verifybackup
+will use the manifest to verify that the write\-ahead log records which will be needed to recover the backup are present and that they can be read and parsed\&. The
+backup_manifest
+contains information about which write\-ahead log records will be needed, and
+pg_verifybackup
+will use that information to invoke
+pg_waldump
+to parse those write\-ahead log records\&. The
+\-\-quiet
+flag will be used, so that
+pg_waldump
+will only report errors, without producing any other output\&. While this level of verification is sufficient to detect obvious problems such as a missing file or one whose internal checksums do not match, they aren\*(Aqt extensive enough to detect every possible problem that might occur when attempting to recover\&. For instance, a server bug that produces write\-ahead log records that have the correct checksums but specify nonsensical actions can\*(Aqt be detected by this method\&.
+.PP
+Note that if extra WAL files which are not required to recover the backup are present, they will not be checked by this tool, although a separate invocation of
+pg_waldump
+could be used for that purpose\&. Also note that WAL verification is version\-specific: you must use the version of
+pg_verifybackup, and thus of
+pg_waldump, which pertains to the backup being checked\&. In contrast, the data file integrity checks should work with any version of the server that generates a
+backup_manifest
+file\&.
+.SH "OPTIONS"
+.PP
+pg_verifybackup
+accepts the following command\-line arguments:
+.PP
+\fB\-e\fR
+.br
+\fB\-\-exit\-on\-error\fR
+.RS 4
+Exit as soon as a problem with the backup is detected\&. If this option is not specified,
+pg_verifybackup
+will continue checking the backup even after a problem has been detected, and will report all problems detected as errors\&.
+.RE
+.PP
+\fB\-i \fR\fB\fIpath\fR\fR
+.br
+\fB\-\-ignore=\fR\fB\fIpath\fR\fR
+.RS 4
+Ignore the specified file or directory, which should be expressed as a relative path name, when comparing the list of data files actually present in the backup to those listed in the
+backup_manifest
+file\&. If a directory is specified, this option affects the entire subtree rooted at that location\&. Complaints about extra files, missing files, file size differences, or checksum mismatches will be suppressed if the relative path name matches the specified path name\&. This option can be specified multiple times\&.
+.RE
+.PP
+\fB\-m \fR\fB\fIpath\fR\fR
+.br
+\fB\-\-manifest\-path=\fR\fB\fIpath\fR\fR
+.RS 4
+Use the manifest file at the specified path, rather than one located in the root of the backup directory\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-parse\-wal\fR
+.RS 4
+Don\*(Aqt attempt to parse write\-ahead log data that will be needed to recover from this backup\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Don\*(Aqt print anything when a backup is successfully verified\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-skip\-checksums\fR
+.RS 4
+Do not verify data file checksums\&. The presence or absence of files and the sizes of those files will still be checked\&. This is much faster, because the files themselves do not need to be read\&.
+.RE
+.PP
+\fB\-w \fR\fB\fIpath\fR\fR
+.br
+\fB\-\-wal\-directory=\fR\fB\fIpath\fR\fR
+.RS 4
+Try to parse WAL files stored in the specified directory, rather than in
+pg_wal\&. This may be useful if the backup is stored in a separate location from the WAL archive\&.
+.RE
+.PP
+Other options are also available:
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_verifybackup
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_verifybackup
+command line arguments, and exit\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To create a base backup of the server at
+mydbserver
+and verify the integrity of the backup:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-h mydbserver \-D /usr/local/pgsql/data\fR
+$ \fBpg_verifybackup /usr/local/pgsql/data\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a base backup of the server at
+mydbserver, move the manifest somewhere outside the backup directory, and verify the backup:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-h mydbserver \-D /usr/local/pgsql/backup1234\fR
+$ \fBmv /usr/local/pgsql/backup1234/backup_manifest /my/secure/location/backup_manifest\&.1234\fR
+$ \fBpg_verifybackup \-m /my/secure/location/backup_manifest\&.1234 /usr/local/pgsql/backup1234\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To verify a backup while ignoring a file that was added manually to the backup directory, and also skipping checksum verification:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpg_basebackup \-h mydbserver \-D /usr/local/pgsql/data\fR
+$ \fBedit /usr/local/pgsql/data/note\&.to\&.self\fR
+$ \fBpg_verifybackup \-\-ignore=note\&.to\&.self \-\-skip\-checksums /usr/local/pgsql/data\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBpg_basebackup\fR(1)
diff --git a/doc/src/sgml/man1/pg_waldump.1 b/doc/src/sgml/man1/pg_waldump.1
new file mode 100644
index 0000000..816b9e4
--- /dev/null
+++ b/doc/src/sgml/man1/pg_waldump.1
@@ -0,0 +1,239 @@
+'\" t
+.\" Title: pg_waldump
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PG_WALDUMP" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pg_waldump \- display a human\-readable rendering of the write\-ahead log of a PostgreSQL database cluster
+.SH "SYNOPSIS"
+.HP \w'\fBpg_waldump\fR\ 'u
+\fBpg_waldump\fR [\fBoption\fR...] [\fBstartseg\fR\ [\fBendseg\fR]]
+.SH "DESCRIPTION"
+.PP
+\fBpg_waldump\fR
+displays the write\-ahead log (WAL) and is mainly useful for debugging or educational purposes\&.
+.PP
+This utility can only be run by the user who installed the server, because it requires read\-only access to the data directory\&.
+.SH "OPTIONS"
+.PP
+The following command\-line options control the location and format of the output:
+.PP
+\fIstartseg\fR
+.RS 4
+Start reading at the specified log segment file\&. This implicitly determines the path in which files will be searched for, and the timeline to use\&.
+.RE
+.PP
+\fIendseg\fR
+.RS 4
+Stop after reading the specified log segment file\&.
+.RE
+.PP
+\fB\-b\fR
+.br
+\fB\-\-bkp\-details\fR
+.RS 4
+Output detailed information about backup blocks\&.
+.RE
+.PP
+\fB\-B \fR\fB\fIblock\fR\fR
+.br
+\fB\-\-block=\fR\fB\fIblock\fR\fR
+.RS 4
+Only display records that modify the given block\&. The relation must also be provided with
+\fB\-\-relation\fR
+or
+\fB\-R\fR\&.
+.RE
+.PP
+\fB\-e \fR\fB\fIend\fR\fR
+.br
+\fB\-\-end=\fR\fB\fIend\fR\fR
+.RS 4
+Stop reading at the specified WAL location, instead of reading to the end of the log stream\&.
+.RE
+.PP
+\fB\-f\fR
+.br
+\fB\-\-follow\fR
+.RS 4
+After reaching the end of valid WAL, keep polling once per second for new WAL to appear\&.
+.RE
+.PP
+\fB\-F \fR\fB\fIfork\fR\fR
+.br
+\fB\-\-fork=\fR\fB\fIfork\fR\fR
+.RS 4
+If provided, only display records that modify blocks in the given fork\&. The valid values are
+main
+for the main fork,
+fsm
+for the free space map,
+vm
+for the visibility map, and
+init
+for the init fork\&.
+.RE
+.PP
+\fB\-n \fR\fB\fIlimit\fR\fR
+.br
+\fB\-\-limit=\fR\fB\fIlimit\fR\fR
+.RS 4
+Display the specified number of records, then stop\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIpath\fR\fR
+.br
+\fB\-\-path=\fR\fB\fIpath\fR\fR
+.RS 4
+Specifies a directory to search for log segment files or a directory with a
+pg_wal
+subdirectory that contains such files\&. The default is to search in the current directory, the
+pg_wal
+subdirectory of the current directory, and the
+pg_wal
+subdirectory of
+\fBPGDATA\fR\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Do not print any output, except for errors\&. This option can be useful when you want to know whether a range of WAL records can be successfully parsed but don\*(Aqt care about the record contents\&.
+.RE
+.PP
+\fB\-r \fR\fB\fIrmgr\fR\fR
+.br
+\fB\-\-rmgr=\fR\fB\fIrmgr\fR\fR
+.RS 4
+Only display records generated by the specified resource manager\&. You can specify the option multiple times to select multiple resource managers\&. If
+list
+is passed as name, print a list of valid resource manager names, and exit\&.
+.sp
+Extensions may define custom resource managers, but pg_waldump does not load the extension module and therefore does not recognize custom resource managers by name\&. Instead, you can specify the custom resource managers as
+custom###
+where "###" is the three\-digit resource manager ID\&. Names of this form will always be considered valid\&.
+.RE
+.PP
+\fB\-R \fR\fB\fItblspc\fR\fR\fB/\fR\fB\fIdb\fR\fR\fB/\fR\fB\fIrel\fR\fR
+.br
+\fB\-\-relation=\fR\fB\fItblspc\fR\fR\fB/\fR\fB\fIdb\fR\fR\fB/\fR\fB\fIrel\fR\fR
+.RS 4
+Only display records that modify blocks in the given relation\&. The relation is specified with tablespace OID, database OID, and relfilenode separated by slashes, for example
+1234/12345/12345\&. This is the same format used for relations in the program\*(Aqs output\&.
+.RE
+.PP
+\fB\-s \fR\fB\fIstart\fR\fR
+.br
+\fB\-\-start=\fR\fB\fIstart\fR\fR
+.RS 4
+WAL location at which to start reading\&. The default is to start reading the first valid log record found in the earliest file found\&.
+.RE
+.PP
+\fB\-t \fR\fB\fItimeline\fR\fR
+.br
+\fB\-\-timeline=\fR\fB\fItimeline\fR\fR
+.RS 4
+Timeline from which to read log records\&. The default is to use the value in
+\fIstartseg\fR, if that is specified; otherwise, the default is 1\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pg_waldump
+version and exit\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-fullpage\fR
+.RS 4
+Only display records that include full page images\&.
+.RE
+.PP
+\fB\-x \fR\fB\fIxid\fR\fR
+.br
+\fB\-\-xid=\fR\fB\fIxid\fR\fR
+.RS 4
+Only display records marked with the given transaction ID\&.
+.RE
+.PP
+\fB\-z\fR
+.br
+\fB\-\-stats[=record]\fR
+.RS 4
+Display summary statistics (number and size of records and full\-page images) instead of individual records\&. Optionally generate statistics per\-record instead of per\-rmgr\&.
+.sp
+If
+pg_waldump
+is terminated by signal
+SIGINT
+(Control+C), the summary of the statistics computed is displayed up to the termination point\&. This operation is not supported on
+Windows\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pg_waldump
+command line arguments, and exit\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATA\fR
+.RS 4
+Data directory; see also the
+\fB\-p\fR
+option\&.
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.SH "NOTES"
+.PP
+Can give wrong results when the server is running\&.
+.PP
+Only the specified timeline is displayed (or the default, if none is specified)\&. Records in other timelines are ignored\&.
+.PP
+pg_waldump
+cannot read WAL files with suffix
+\&.partial\&. If those files need to be read,
+\&.partial
+suffix needs to be removed from the file name\&.
+.SH "SEE ALSO"
+Section\ \&30.6
diff --git a/doc/src/sgml/man1/pgbench.1 b/doc/src/sgml/man1/pgbench.1
new file mode 100644
index 0000000..a0bdc16
--- /dev/null
+++ b/doc/src/sgml/man1/pgbench.1
@@ -0,0 +1,2897 @@
+'\" t
+.\" Title: pgbench
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PGBENCH" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pgbench \- run a benchmark test on PostgreSQL
+.SH "SYNOPSIS"
+.HP \w'\fBpgbench\fR\ 'u
+\fBpgbench\fR \fB\-i\fR [\fIoption\fR...] [\fIdbname\fR]
+.HP \w'\fBpgbench\fR\ 'u
+\fBpgbench\fR [\fIoption\fR...] [\fIdbname\fR]
+.SH "DESCRIPTION"
+.PP
+pgbench
+is a simple program for running benchmark tests on
+PostgreSQL\&. It runs the same sequence of SQL commands over and over, possibly in multiple concurrent database sessions, and then calculates the average transaction rate (transactions per second)\&. By default,
+pgbench
+tests a scenario that is loosely based on TPC\-B, involving five
+\fBSELECT\fR,
+\fBUPDATE\fR, and
+\fBINSERT\fR
+commands per transaction\&. However, it is easy to test other cases by writing your own transaction script files\&.
+.PP
+Typical output from
+pgbench
+looks like:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+transaction type: <builtin: TPC\-B (sort of)>
+scaling factor: 10
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+number of failed transactions: 0 (0\&.000%)
+latency average = 11\&.013 ms
+latency stddev = 7\&.351 ms
+initial connection time = 45\&.758 ms
+tps = 896\&.967014 (without initial connection time)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The first seven lines report some of the most important parameter settings\&. The sixth line reports the maximum number of tries for transactions with serialization or deadlock errors (see
+Failures and Serialization/Deadlock Retries
+for more information)\&. The eighth line reports the number of transactions completed and intended (the latter being just the product of number of clients and number of transactions per client); these will be equal unless the run failed before completion or some SQL command(s) failed\&. (In
+\fB\-T\fR
+mode, only the actual number of transactions is printed\&.) The next line reports the number of failed transactions due to serialization or deadlock errors (see
+Failures and Serialization/Deadlock Retries
+for more information)\&. The last line reports the number of transactions per second\&.
+.PP
+The default TPC\-B\-like transaction test requires specific tables to be set up beforehand\&.
+pgbench
+should be invoked with the
+\fB\-i\fR
+(initialize) option to create and populate these tables\&. (When you are testing a custom script, you don\*(Aqt need this step, but will instead need to do whatever setup your test needs\&.) Initialization looks like:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+pgbench \-i [ \fIother\-options\fR ] \fIdbname\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIdbname\fR
+is the name of the already\-created database to test in\&. (You may also need
+\fB\-h\fR,
+\fB\-p\fR, and/or
+\fB\-U\fR
+options to specify how to connect to the database server\&.)
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+pgbench \-i
+creates four tables
+pgbench_accounts,
+pgbench_branches,
+pgbench_history, and
+pgbench_tellers, destroying any existing tables of these names\&. Be very careful to use another database if you have tables having these names!
+.sp .5v
+.RE
+.PP
+At the default
+\(lqscale factor\(rq
+of 1, the tables initially contain this many rows:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+table # of rows
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+pgbench_branches 1
+pgbench_tellers 10
+pgbench_accounts 100000
+pgbench_history 0
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+You can (and, for most purposes, probably should) increase the number of rows by using the
+\fB\-s\fR
+(scale factor) option\&. The
+\fB\-F\fR
+(fillfactor) option might also be used at this point\&.
+.PP
+Once you have done the necessary setup, you can run your benchmark with a command that doesn\*(Aqt include
+\fB\-i\fR, that is
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+pgbench [ \fIoptions\fR ] \fIdbname\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In nearly all cases, you\*(Aqll need some options to make a useful test\&. The most important options are
+\fB\-c\fR
+(number of clients),
+\fB\-t\fR
+(number of transactions),
+\fB\-T\fR
+(time limit), and
+\fB\-f\fR
+(specify a custom script file)\&. See below for a full list\&.
+.SH "OPTIONS"
+.PP
+The following is divided into three subsections\&. Different options are used during database initialization and while running benchmarks, but some options are useful in both cases\&.
+.SS "Initialization Options"
+.PP
+pgbench
+accepts the following command\-line initialization arguments:
+.PP
+\fIdbname\fR
+.RS 4
+Specifies the name of the database to test in\&. If this is not specified, the environment variable
+\fBPGDATABASE\fR
+is used\&. If that is not set, the user name specified for the connection is used\&.
+.RE
+.PP
+\fB\-i\fR
+.br
+\fB\-\-initialize\fR
+.RS 4
+Required to invoke initialization mode\&.
+.RE
+.PP
+\fB\-I \fR\fB\fIinit_steps\fR\fR
+.br
+\fB\-\-init\-steps=\fR\fB\fIinit_steps\fR\fR
+.RS 4
+Perform just a selected set of the normal initialization steps\&.
+\fIinit_steps\fR
+specifies the initialization steps to be performed, using one character per step\&. Each step is invoked in the specified order\&. The default is
+dtgvp\&. The available steps are:
+.PP
+d (Drop)
+.RS 4
+Drop any existing
+pgbench
+tables\&.
+.RE
+.PP
+t (create Tables)
+.RS 4
+Create the tables used by the standard
+pgbench
+scenario, namely
+pgbench_accounts,
+pgbench_branches,
+pgbench_history, and
+pgbench_tellers\&.
+.RE
+.PP
+g or G (Generate data, client\-side or server\-side)
+.RS 4
+Generate data and load it into the standard tables, replacing any data already present\&.
+.sp
+With
+g
+(client\-side data generation), data is generated in
+\fBpgbench\fR
+client and then sent to the server\&. This uses the client/server bandwidth extensively through a
+\fBCOPY\fR\&.
+\fBpgbench\fR
+uses the FREEZE option with version 14 or later of
+PostgreSQL
+to speed up subsequent
+\fBVACUUM\fR, unless partitions are enabled\&. Using
+g
+causes logging to print one message every 100,000 rows while generating data for the
+pgbench_accounts
+table\&.
+.sp
+With
+G
+(server\-side data generation), only small queries are sent from the
+\fBpgbench\fR
+client and then data is actually generated in the server\&. No significant bandwidth is required for this variant, but the server will do more work\&. Using
+G
+causes logging not to print any progress message while generating data\&.
+.sp
+The default initialization behavior uses client\-side data generation (equivalent to
+g)\&.
+.RE
+.PP
+v (Vacuum)
+.RS 4
+Invoke
+\fBVACUUM\fR
+on the standard tables\&.
+.RE
+.PP
+p (create Primary keys)
+.RS 4
+Create primary key indexes on the standard tables\&.
+.RE
+.PP
+f (create Foreign keys)
+.RS 4
+Create foreign key constraints between the standard tables\&. (Note that this step is not performed by default\&.)
+.RE
+.RE
+.PP
+\fB\-F\fR \fIfillfactor\fR
+.br
+\fB\-\-fillfactor=\fR\fIfillfactor\fR
+.RS 4
+Create the
+pgbench_accounts,
+pgbench_tellers
+and
+pgbench_branches
+tables with the given fillfactor\&. Default is 100\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-vacuum\fR
+.RS 4
+Perform no vacuuming during initialization\&. (This option suppresses the
+v
+initialization step, even if it was specified in
+\fB\-I\fR\&.)
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Switch logging to quiet mode, producing only one progress message per 5 seconds\&. The default logging prints one message each 100,000 rows, which often outputs many lines per second (especially on good hardware)\&.
+.sp
+This setting has no effect if
+G
+is specified in
+\fB\-I\fR\&.
+.RE
+.PP
+\fB\-s\fR \fIscale_factor\fR
+.br
+\fB\-\-scale=\fR\fIscale_factor\fR
+.RS 4
+Multiply the number of rows generated by the scale factor\&. For example,
+\-s 100
+will create 10,000,000 rows in the
+pgbench_accounts
+table\&. Default is 1\&. When the scale is 20,000 or larger, the columns used to hold account identifiers (aid
+columns) will switch to using larger integers (bigint), in order to be big enough to hold the range of account identifiers\&.
+.RE
+.PP
+\fB\-\-foreign\-keys\fR
+.RS 4
+Create foreign key constraints between the standard tables\&. (This option adds the
+f
+step to the initialization step sequence, if it is not already present\&.)
+.RE
+.PP
+\fB\-\-index\-tablespace=\fR\fB\fIindex_tablespace\fR\fR
+.RS 4
+Create indexes in the specified tablespace, rather than the default tablespace\&.
+.RE
+.PP
+\fB\-\-partition\-method=\fR\fB\fINAME\fR\fR
+.RS 4
+Create a partitioned
+pgbench_accounts
+table with
+\fINAME\fR
+method\&. Expected values are
+range
+or
+hash\&. This option requires that
+\fB\-\-partitions\fR
+is set to non\-zero\&. If unspecified, default is
+range\&.
+.RE
+.PP
+\fB\-\-partitions=\fR\fB\fINUM\fR\fR
+.RS 4
+Create a partitioned
+pgbench_accounts
+table with
+\fINUM\fR
+partitions of nearly equal size for the scaled number of accounts\&. Default is
+0, meaning no partitioning\&.
+.RE
+.PP
+\fB\-\-tablespace=\fR\fB\fItablespace\fR\fR
+.RS 4
+Create tables in the specified tablespace, rather than the default tablespace\&.
+.RE
+.PP
+\fB\-\-unlogged\-tables\fR
+.RS 4
+Create all tables as unlogged tables, rather than permanent tables\&.
+.RE
+.SS "Benchmarking Options"
+.PP
+pgbench
+accepts the following command\-line benchmarking arguments:
+.PP
+\fB\-b\fR \fIscriptname[@weight]\fR
+.br
+\fB\-\-builtin\fR=\fIscriptname[@weight]\fR
+.RS 4
+Add the specified built\-in script to the list of scripts to be executed\&. Available built\-in scripts are:
+tpcb\-like,
+simple\-update
+and
+select\-only\&. Unambiguous prefixes of built\-in names are accepted\&. With the special name
+list, show the list of built\-in scripts and exit immediately\&.
+.sp
+Optionally, write an integer weight after
+@
+to adjust the probability of selecting this script versus other ones\&. The default weight is 1\&. See below for details\&.
+.RE
+.PP
+\fB\-c\fR \fIclients\fR
+.br
+\fB\-\-client=\fR\fIclients\fR
+.RS 4
+Number of clients simulated, that is, number of concurrent database sessions\&. Default is 1\&.
+.RE
+.PP
+\fB\-C\fR
+.br
+\fB\-\-connect\fR
+.RS 4
+Establish a new connection for each transaction, rather than doing it just once per client session\&. This is useful to measure the connection overhead\&.
+.RE
+.PP
+\fB\-d\fR
+.br
+\fB\-\-debug\fR
+.RS 4
+Print debugging output\&.
+.RE
+.PP
+\fB\-D\fR \fIvarname\fR=\fIvalue\fR
+.br
+\fB\-\-define=\fR\fIvarname\fR=\fIvalue\fR
+.RS 4
+Define a variable for use by a custom script (see below)\&. Multiple
+\fB\-D\fR
+options are allowed\&.
+.RE
+.PP
+\fB\-f\fR \fIfilename[@weight]\fR
+.br
+\fB\-\-file=\fR\fIfilename[@weight]\fR
+.RS 4
+Add a transaction script read from
+\fIfilename\fR
+to the list of scripts to be executed\&.
+.sp
+Optionally, write an integer weight after
+@
+to adjust the probability of selecting this script versus other ones\&. The default weight is 1\&. (To use a script file name that includes an
+@
+character, append a weight so that there is no ambiguity, for example
+filen@me@1\&.) See below for details\&.
+.RE
+.PP
+\fB\-j\fR \fIthreads\fR
+.br
+\fB\-\-jobs=\fR\fIthreads\fR
+.RS 4
+Number of worker threads within
+pgbench\&. Using more than one thread can be helpful on multi\-CPU machines\&. Clients are distributed as evenly as possible among available threads\&. Default is 1\&.
+.RE
+.PP
+\fB\-l\fR
+.br
+\fB\-\-log\fR
+.RS 4
+Write information about each transaction to a log file\&. See below for details\&.
+.RE
+.PP
+\fB\-L\fR \fIlimit\fR
+.br
+\fB\-\-latency\-limit=\fR\fIlimit\fR
+.RS 4
+Transactions that last more than
+\fIlimit\fR
+milliseconds are counted and reported separately, as
+late\&.
+.sp
+When throttling is used (\fB\-\-rate=\&.\&.\&.\fR), transactions that lag behind schedule by more than
+\fIlimit\fR
+ms, and thus have no hope of meeting the latency limit, are not sent to the server at all\&. They are counted and reported separately as
+skipped\&.
+.sp
+When the
+\fB\-\-max\-tries\fR
+option is used, a transaction which fails due to a serialization anomaly or from a deadlock will not be retried if the total time of all its tries is greater than
+\fIlimit\fR
+ms\&. To limit only the time of tries and not their number, use
+\-\-max\-tries=0\&. By default, the option
+\fB\-\-max\-tries\fR
+is set to 1 and transactions with serialization/deadlock errors are not retried\&. See
+Failures and Serialization/Deadlock Retries
+for more information about retrying such transactions\&.
+.RE
+.PP
+\fB\-M\fR \fIquerymode\fR
+.br
+\fB\-\-protocol=\fR\fIquerymode\fR
+.RS 4
+Protocol to use for submitting queries to the server:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+simple: use simple query protocol\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+extended: use extended query protocol\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+prepared: use extended query protocol with prepared statements\&.
+.RE
+.sp
+In the
+prepared
+mode,
+pgbench
+reuses the parse analysis result starting from the second query iteration, so
+pgbench
+runs faster than in other modes\&.
+.sp
+The default is simple query protocol\&. (See
+Chapter\ \&55
+for more information\&.)
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-vacuum\fR
+.RS 4
+Perform no vacuuming before running the test\&. This option is
+\fInecessary\fR
+if you are running a custom test scenario that does not include the standard tables
+pgbench_accounts,
+pgbench_branches,
+pgbench_history, and
+pgbench_tellers\&.
+.RE
+.PP
+\fB\-N\fR
+.br
+\fB\-\-skip\-some\-updates\fR
+.RS 4
+Run built\-in simple\-update script\&. Shorthand for
+\fB\-b simple\-update\fR\&.
+.RE
+.PP
+\fB\-P\fR \fIsec\fR
+.br
+\fB\-\-progress=\fR\fIsec\fR
+.RS 4
+Show progress report every
+\fIsec\fR
+seconds\&. The report includes the time since the beginning of the run, the TPS since the last report, and the transaction latency average, standard deviation, and the number of failed transactions since the last report\&. Under throttling (\fB\-R\fR), the latency is computed with respect to the transaction scheduled start time, not the actual transaction beginning time, thus it also includes the average schedule lag time\&. When
+\fB\-\-max\-tries\fR
+is used to enable transaction retries after serialization/deadlock errors, the report includes the number of retried transactions and the sum of all retries\&.
+.RE
+.PP
+\fB\-r\fR
+.br
+\fB\-\-report\-per\-command\fR
+.RS 4
+Report the following statistics for each command after the benchmark finishes: the average per\-statement latency (execution time from the perspective of the client), the number of failures, and the number of retries after serialization or deadlock errors in this command\&. The report displays retry statistics only if the
+\fB\-\-max\-tries\fR
+option is not equal to 1\&.
+.RE
+.PP
+\fB\-R\fR \fIrate\fR
+.br
+\fB\-\-rate=\fR\fIrate\fR
+.RS 4
+Execute transactions targeting the specified rate instead of running as fast as possible (the default)\&. The rate is given in transactions per second\&. If the targeted rate is above the maximum possible rate, the rate limit won\*(Aqt impact the results\&.
+.sp
+The rate is targeted by starting transactions along a Poisson\-distributed schedule time line\&. The expected start time schedule moves forward based on when the client first started, not when the previous transaction ended\&. That approach means that when transactions go past their original scheduled end time, it is possible for later ones to catch up again\&.
+.sp
+When throttling is active, the transaction latency reported at the end of the run is calculated from the scheduled start times, so it includes the time each transaction had to wait for the previous transaction to finish\&. The wait time is called the schedule lag time, and its average and maximum are also reported separately\&. The transaction latency with respect to the actual transaction start time, i\&.e\&., the time spent executing the transaction in the database, can be computed by subtracting the schedule lag time from the reported latency\&.
+.sp
+If
+\fB\-\-latency\-limit\fR
+is used together with
+\fB\-\-rate\fR, a transaction can lag behind so much that it is already over the latency limit when the previous transaction ends, because the latency is calculated from the scheduled start time\&. Such transactions are not sent to the server, but are skipped altogether and counted separately\&.
+.sp
+A high schedule lag time is an indication that the system cannot process transactions at the specified rate, with the chosen number of clients and threads\&. When the average transaction execution time is longer than the scheduled interval between each transaction, each successive transaction will fall further behind, and the schedule lag time will keep increasing the longer the test run is\&. When that happens, you will have to reduce the specified transaction rate\&.
+.RE
+.PP
+\fB\-s\fR \fIscale_factor\fR
+.br
+\fB\-\-scale=\fR\fIscale_factor\fR
+.RS 4
+Report the specified scale factor in
+pgbench\*(Aqs output\&. With the built\-in tests, this is not necessary; the correct scale factor will be detected by counting the number of rows in the
+pgbench_branches
+table\&. However, when testing only custom benchmarks (\fB\-f\fR
+option), the scale factor will be reported as 1 unless this option is used\&.
+.RE
+.PP
+\fB\-S\fR
+.br
+\fB\-\-select\-only\fR
+.RS 4
+Run built\-in select\-only script\&. Shorthand for
+\fB\-b select\-only\fR\&.
+.RE
+.PP
+\fB\-t\fR \fItransactions\fR
+.br
+\fB\-\-transactions=\fR\fItransactions\fR
+.RS 4
+Number of transactions each client runs\&. Default is 10\&.
+.RE
+.PP
+\fB\-T\fR \fIseconds\fR
+.br
+\fB\-\-time=\fR\fIseconds\fR
+.RS 4
+Run the test for this many seconds, rather than a fixed number of transactions per client\&.
+\fB\-t\fR
+and
+\fB\-T\fR
+are mutually exclusive\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-vacuum\-all\fR
+.RS 4
+Vacuum all four standard tables before running the test\&. With neither
+\fB\-n\fR
+nor
+\fB\-v\fR,
+pgbench
+will vacuum the
+pgbench_tellers
+and
+pgbench_branches
+tables, and will truncate
+pgbench_history\&.
+.RE
+.PP
+\fB\-\-aggregate\-interval=\fR\fB\fIseconds\fR\fR
+.RS 4
+Length of aggregation interval (in seconds)\&. May be used only with
+\fB\-l\fR
+option\&. With this option, the log contains per\-interval summary data, as described below\&.
+.RE
+.PP
+\fB\-\-failures\-detailed\fR
+.RS 4
+Report failures in per\-transaction and aggregation logs, as well as in the main and per\-script reports, grouped by the following types:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+serialization failures;
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+deadlock failures;
+.RE
+.sp
+See
+Failures and Serialization/Deadlock Retries
+for more information\&.
+.RE
+.PP
+\fB\-\-log\-prefix=\fR\fB\fIprefix\fR\fR
+.RS 4
+Set the filename prefix for the log files created by
+\fB\-\-log\fR\&. The default is
+pgbench_log\&.
+.RE
+.PP
+\fB\-\-max\-tries=\fR\fB\fInumber_of_tries\fR\fR
+.RS 4
+Enable retries for transactions with serialization/deadlock errors and set the maximum number of these tries\&. This option can be combined with the
+\fB\-\-latency\-limit\fR
+option which limits the total time of all transaction tries; moreover, you cannot use an unlimited number of tries (\-\-max\-tries=0) without
+\fB\-\-latency\-limit\fR
+or
+\fB\-\-time\fR\&. The default value is 1 and transactions with serialization/deadlock errors are not retried\&. See
+Failures and Serialization/Deadlock Retries
+for more information about retrying such transactions\&.
+.RE
+.PP
+\fB\-\-progress\-timestamp\fR
+.RS 4
+When showing progress (option
+\fB\-P\fR), use a timestamp (Unix epoch) instead of the number of seconds since the beginning of the run\&. The unit is in seconds, with millisecond precision after the dot\&. This helps compare logs generated by various tools\&.
+.RE
+.PP
+\fB\-\-random\-seed=\fR\fIseed\fR
+.RS 4
+Set random generator seed\&. Seeds the system random number generator, which then produces a sequence of initial generator states, one for each thread\&. Values for
+\fIseed\fR
+may be:
+time
+(the default, the seed is based on the current time),
+rand
+(use a strong random source, failing if none is available), or an unsigned decimal integer value\&. The random generator is invoked explicitly from a pgbench script (random\&.\&.\&.
+functions) or implicitly (for instance option
+\fB\-\-rate\fR
+uses it to schedule transactions)\&. When explicitly set, the value used for seeding is shown on the terminal\&. Any value allowed for
+\fIseed\fR
+may also be provided through the environment variable
+PGBENCH_RANDOM_SEED\&. To ensure that the provided seed impacts all possible uses, put this option first or use the environment variable\&.
+.sp
+Setting the seed explicitly allows to reproduce a
+\fBpgbench\fR
+run exactly, as far as random numbers are concerned\&. As the random state is managed per thread, this means the exact same
+\fBpgbench\fR
+run for an identical invocation if there is one client per thread and there are no external or data dependencies\&. From a statistical viewpoint reproducing runs exactly is a bad idea because it can hide the performance variability or improve performance unduly, e\&.g\&., by hitting the same pages as a previous run\&. However, it may also be of great help for debugging, for instance re\-running a tricky case which leads to an error\&. Use wisely\&.
+.RE
+.PP
+\fB\-\-sampling\-rate=\fR\fB\fIrate\fR\fR
+.RS 4
+Sampling rate, used when writing data into the log, to reduce the amount of log generated\&. If this option is given, only the specified fraction of transactions are logged\&. 1\&.0 means all transactions will be logged, 0\&.05 means only 5% of the transactions will be logged\&.
+.sp
+Remember to take the sampling rate into account when processing the log file\&. For example, when computing TPS values, you need to multiply the numbers accordingly (e\&.g\&., with 0\&.01 sample rate, you\*(Aqll only get 1/100 of the actual TPS)\&.
+.RE
+.PP
+\fB\-\-show\-script=\fR\fIscriptname\fR
+.RS 4
+Show the actual code of builtin script
+\fIscriptname\fR
+on stderr, and exit immediately\&.
+.RE
+.PP
+\fB\-\-verbose\-errors\fR
+.RS 4
+Print messages about all errors and failures (errors without retrying) including which limit for retries was exceeded and how far it was exceeded for the serialization/deadlock failures\&. (Note that in this case the output can be significantly increased\&.)\&. See
+Failures and Serialization/Deadlock Retries
+for more information\&.
+.RE
+.SS "Common Options"
+.PP
+pgbench
+also accepts the following common command\-line arguments for connection parameters:
+.PP
+\fB\-h\fR \fIhostname\fR
+.br
+\fB\-\-host=\fR\fIhostname\fR
+.RS 4
+The database server\*(Aqs host name
+.RE
+.PP
+\fB\-p\fR \fIport\fR
+.br
+\fB\-\-port=\fR\fIport\fR
+.RS 4
+The database server\*(Aqs port number
+.RE
+.PP
+\fB\-U\fR \fIlogin\fR
+.br
+\fB\-\-username=\fR\fIlogin\fR
+.RS 4
+The user name to connect as
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+pgbench
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+pgbench
+command line arguments, and exit\&.
+.RE
+.SH "EXIT STATUS"
+.PP
+A successful run will exit with status 0\&. Exit status 1 indicates static problems such as invalid command\-line options or internal errors which are supposed to never occur\&. Early errors that occur when starting benchmark such as initial connection failures also exit with status 1\&. Errors during the run such as database errors or problems in the script will result in exit status 2\&. In the latter case,
+pgbench
+will print partial results\&.
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATABASE\fR
+.br
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.SS "What Is the \(lqTransaction\(rq Actually Performed in pgbench?"
+.PP
+pgbench
+executes test scripts chosen randomly from a specified list\&. The scripts may include built\-in scripts specified with
+\fB\-b\fR
+and user\-provided scripts specified with
+\fB\-f\fR\&. Each script may be given a relative weight specified after an
+@
+so as to change its selection probability\&. The default weight is
+1\&. Scripts with a weight of
+0
+are ignored\&.
+.PP
+The default built\-in transaction script (also invoked with
+\fB\-b tpcb\-like\fR) issues seven commands per transaction over randomly chosen
+aid,
+tid,
+bid
+and
+delta\&. The scenario is inspired by the TPC\-B benchmark, but is not actually TPC\-B, hence the name\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+BEGIN;
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 4.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 4." 4.2
+.\}
+UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 5.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 5." 4.2
+.\}
+UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 6.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 6." 4.2
+.\}
+INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 7.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 7." 4.2
+.\}
+END;
+.RE
+.PP
+If you select the
+simple\-update
+built\-in (also
+\fB\-N\fR), steps 4 and 5 aren\*(Aqt included in the transaction\&. This will avoid update contention on these tables, but it makes the test case even less like TPC\-B\&.
+.PP
+If you select the
+select\-only
+built\-in (also
+\fB\-S\fR), only the
+\fBSELECT\fR
+is issued\&.
+.SS "Custom Scripts"
+.PP
+pgbench
+has support for running custom benchmark scenarios by replacing the default transaction script (described above) with a transaction script read from a file (\fB\-f\fR
+option)\&. In this case a
+\(lqtransaction\(rq
+counts as one execution of a script file\&.
+.PP
+A script file contains one or more SQL commands terminated by semicolons\&. Empty lines and lines beginning with
+\-\-
+are ignored\&. Script files can also contain
+\(lqmeta commands\(rq, which are interpreted by
+pgbench
+itself, as described below\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+Before
+PostgreSQL
+9\&.6, SQL commands in script files were terminated by newlines, and so they could not be continued across lines\&. Now a semicolon is
+\fIrequired\fR
+to separate consecutive SQL commands (though an SQL command does not need one if it is followed by a meta command)\&. If you need to create a script file that works with both old and new versions of
+pgbench, be sure to write each SQL command on a single line ending with a semicolon\&.
+.PP
+It is assumed that pgbench scripts do not contain incomplete blocks of SQL transactions\&. If at runtime the client reaches the end of the script without completing the last transaction block, it will be aborted\&.
+.sp .5v
+.RE
+.PP
+There is a simple variable\-substitution facility for script files\&. Variable names must consist of letters (including non\-Latin letters), digits, and underscores, with the first character not being a digit\&. Variables can be set by the command\-line
+\fB\-D\fR
+option, explained above, or by the meta commands explained below\&. In addition to any variables preset by
+\fB\-D\fR
+command\-line options, there are a few variables that are preset automatically, listed in
+Table\ \&288\&. A value specified for these variables using
+\fB\-D\fR
+takes precedence over the automatic presets\&. Once set, a variable\*(Aqs value can be inserted into an SQL command by writing
+:\fIvariablename\fR\&. When running more than one client session, each session has its own set of variables\&.
+pgbench
+supports up to 255 variable uses in one statement\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.B Table\ \&288.\ \&pgbench Automatic Variables
+.TS
+allbox tab(:);
+lB lB.
+T{
+Variable
+T}:T{
+Description
+T}
+.T&
+l l
+l l
+l l
+l l.
+T{
+client_id
+T}:T{
+unique number identifying the client session (starts from zero)
+T}
+T{
+default_seed
+T}:T{
+seed used in hash and pseudorandom permutation functions by default
+T}
+T{
+random_seed
+T}:T{
+random generator seed (unless overwritten with \fB\-D\fR)
+T}
+T{
+scale
+T}:T{
+current scale factor
+T}
+.TE
+.sp 1
+.PP
+Script file meta commands begin with a backslash (\e) and normally extend to the end of the line, although they can be continued to additional lines by writing backslash\-return\&. Arguments to a meta command are separated by white space\&. These meta commands are supported:
+.PP
+\egset [\fIprefix\fR] \easet [\fIprefix\fR]
+.RS 4
+These commands may be used to end SQL queries, taking the place of the terminating semicolon (;)\&.
+.sp
+When the
+\egset
+command is used, the preceding SQL query is expected to return one row, the columns of which are stored into variables named after column names, and prefixed with
+\fIprefix\fR
+if provided\&.
+.sp
+When the
+\easet
+command is used, all combined SQL queries (separated by
+\e;) have their columns stored into variables named after column names, and prefixed with
+\fIprefix\fR
+if provided\&. If a query returns no row, no assignment is made and the variable can be tested for existence to detect this\&. If a query returns more than one row, the last value is kept\&.
+.sp
+\egset
+and
+\easet
+cannot be used in pipeline mode, since the query results are not yet available by the time the commands would need them\&.
+.sp
+The following example puts the final account balance from the first query into variable
+\fIabalance\fR, and fills variables
+\fIp_two\fR
+and
+\fIp_three\fR
+with integers from the third query\&. The result of the second query is discarded\&. The result of the two last combined queries are stored in variables
+\fIfour\fR
+and
+\fIfive\fR\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE pgbench_accounts
+ SET abalance = abalance + :delta
+ WHERE aid = :aid
+ RETURNING abalance \egset
+\-\- compound of two queries
+SELECT 1 \e;
+SELECT 2 AS two, 3 AS three \egset p_
+SELECT 4 AS four \e; SELECT 5 AS five \easet
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\eif \fIexpression\fR
+.br
+\eelif \fIexpression\fR
+.br
+\eelse
+.br
+\eendif
+.RS 4
+This group of commands implements nestable conditional blocks, similarly to
+psql\*(Aqs
+\eif \fIexpression\fR\&. Conditional expressions are identical to those with
+\eset, with non\-zero values interpreted as true\&.
+.RE
+.PP
+\eset \fIvarname\fR \fIexpression\fR
+.RS 4
+Sets variable
+\fIvarname\fR
+to a value calculated from
+\fIexpression\fR\&. The expression may contain the
+NULL
+constant, Boolean constants
+TRUE
+and
+FALSE, integer constants such as
+5432, double constants such as
+3\&.14159, references to variables
+:\fIvariablename\fR,
+operators
+with their usual SQL precedence and associativity,
+function calls, SQL
+CASE generic conditional expressions
+and parentheses\&.
+.sp
+Functions and most operators return
+NULL
+on
+NULL
+input\&.
+.sp
+For conditional purposes, non zero numerical values are
+TRUE, zero numerical values and
+NULL
+are
+FALSE\&.
+.sp
+Too large or small integer and double constants, as well as integer arithmetic operators (+,
+\-,
+*
+and
+/) raise errors on overflows\&.
+.sp
+When no final
+ELSE
+clause is provided to a
+CASE, the default value is
+NULL\&.
+.sp
+Examples:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eset ntellers 10 * :scale
+\eset aid (1021 * random(1, 100000 * :scale)) % \e
+ (100000 * :scale) + 1
+\eset divx CASE WHEN :x <> 0 THEN :y/:x ELSE NULL END
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\esleep \fInumber\fR [ us | ms | s ]
+.RS 4
+Causes script execution to sleep for the specified duration in microseconds (us), milliseconds (ms) or seconds (s)\&. If the unit is omitted then seconds are the default\&.
+\fInumber\fR
+can be either an integer constant or a
+:\fIvariablename\fR
+reference to a variable having an integer value\&.
+.sp
+Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\esleep 10 ms
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\esetshell \fIvarname\fR \fIcommand\fR [ \fIargument\fR \&.\&.\&. ]
+.RS 4
+Sets variable
+\fIvarname\fR
+to the result of the shell command
+\fIcommand\fR
+with the given
+\fIargument\fR(s)\&. The command must return an integer value through its standard output\&.
+.sp
+\fIcommand\fR
+and each
+\fIargument\fR
+can be either a text constant or a
+:\fIvariablename\fR
+reference to a variable\&. If you want to use an
+\fIargument\fR
+starting with a colon, write an additional colon at the beginning of
+\fIargument\fR\&.
+.sp
+Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\esetshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\eshell \fIcommand\fR [ \fIargument\fR \&.\&.\&. ]
+.RS 4
+Same as
+\esetshell, but the result of the command is discarded\&.
+.sp
+Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eshell command literal_argument :variable ::literal_starting_with_colon
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\estartpipeline
+.br
+\eendpipeline
+.RS 4
+These commands delimit the start and end of a pipeline of SQL statements\&. In pipeline mode, statements are sent to the server without waiting for the results of previous statements\&. See
+Section\ \&34.5
+for more details\&. Pipeline mode requires the use of extended query protocol\&.
+.RE
+.SS "Built\-in Operators"
+.PP
+The arithmetic, bitwise, comparison and logical operators listed in
+Table\ \&289
+are built into
+pgbench
+and may be used in expressions appearing in
+\eset\&. The operators are listed in increasing precedence order\&. Except as noted, operators taking two numeric inputs will produce a double value if either input is double, otherwise they produce an integer result\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.B Table\ \&289.\ \&pgbench Operators
+.TS
+allbox tab(:);
+lB.
+T{
+.PP
+Operator
+
+ .PP
+Description
+
+ .PP
+Example(s)
+T}
+.T&
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l.
+T{
+.PP
+\fIboolean\fR
+OR
+\fIboolean\fR
+→ \fIboolean\fR
+
+ .PP
+Logical OR
+
+ .PP
+5 or 0
+→ TRUE
+T}
+T{
+.PP
+\fIboolean\fR
+AND
+\fIboolean\fR
+→ \fIboolean\fR
+
+ .PP
+Logical AND
+
+ .PP
+3 and 0
+→ FALSE
+T}
+T{
+.PP
+NOT
+\fIboolean\fR
+→ \fIboolean\fR
+
+ .PP
+Logical NOT
+
+ .PP
+not false
+→ TRUE
+T}
+T{
+.PP
+\fIboolean\fR
+IS [NOT] (NULL|TRUE|FALSE)
+→ \fIboolean\fR
+
+ .PP
+Boolean value tests
+
+ .PP
+1 is null
+→ FALSE
+T}
+T{
+.PP
+\fIvalue\fR
+ISNULL|NOTNULL
+→ \fIboolean\fR
+
+ .PP
+Nullness tests
+
+ .PP
+1 notnull
+→ TRUE
+T}
+T{
+.PP
+\fInumber\fR
+=
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Equal
+
+ .PP
+5 = 4
+→ FALSE
+T}
+T{
+.PP
+\fInumber\fR
+<>
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Not equal
+
+ .PP
+5 <> 4
+→ TRUE
+T}
+T{
+.PP
+\fInumber\fR
+!=
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Not equal
+
+ .PP
+5 != 5
+→ FALSE
+T}
+T{
+.PP
+\fInumber\fR
+<
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Less than
+
+ .PP
+5 < 4
+→ FALSE
+T}
+T{
+.PP
+\fInumber\fR
+<=
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Less than or equal to
+
+ .PP
+5 <= 4
+→ FALSE
+T}
+T{
+.PP
+\fInumber\fR
+>
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Greater than
+
+ .PP
+5 > 4
+→ TRUE
+T}
+T{
+.PP
+\fInumber\fR
+>=
+\fInumber\fR
+→ \fIboolean\fR
+
+ .PP
+Greater than or equal to
+
+ .PP
+5 >= 4
+→ TRUE
+T}
+T{
+.PP
+\fIinteger\fR
+|
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Bitwise OR
+
+ .PP
+1 | 2
+→ 3
+T}
+T{
+.PP
+\fIinteger\fR
+#
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Bitwise XOR
+
+ .PP
+1 # 3
+→ 2
+T}
+T{
+.PP
+\fIinteger\fR
+&
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Bitwise AND
+
+ .PP
+1 & 3
+→ 1
+T}
+T{
+.PP
+~
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Bitwise NOT
+
+ .PP
+~ 1
+→ \-2
+T}
+T{
+.PP
+\fIinteger\fR
+<<
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Bitwise shift left
+
+ .PP
+1 << 2
+→ 4
+T}
+T{
+.PP
+\fIinteger\fR
+>>
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Bitwise shift right
+
+ .PP
+8 >> 2
+→ 2
+T}
+T{
+.PP
+\fInumber\fR
++
+\fInumber\fR
+→ \fInumber\fR
+
+ .PP
+Addition
+
+ .PP
+5 + 4
+→ 9
+T}
+T{
+.PP
+\fInumber\fR
+\-
+\fInumber\fR
+→ \fInumber\fR
+
+ .PP
+Subtraction
+
+ .PP
+3 \- 2\&.0
+→ 1\&.0
+T}
+T{
+.PP
+\fInumber\fR
+*
+\fInumber\fR
+→ \fInumber\fR
+
+ .PP
+Multiplication
+
+ .PP
+5 * 4
+→ 20
+T}
+T{
+.PP
+\fInumber\fR
+/
+\fInumber\fR
+→ \fInumber\fR
+
+ .PP
+Division (truncates the result towards zero if both inputs are integers)
+
+ .PP
+5 / 3
+→ 1
+T}
+T{
+.PP
+\fIinteger\fR
+%
+\fIinteger\fR
+→ \fIinteger\fR
+
+ .PP
+Modulo (remainder)
+
+ .PP
+3 % 2
+→ 1
+T}
+T{
+.PP
+\-
+\fInumber\fR
+→ \fInumber\fR
+
+ .PP
+Negation
+
+ .PP
+\- 2\&.0
+→ \-2\&.0
+T}
+.TE
+.sp 1
+.SS "Built\-In Functions"
+.PP
+The functions listed in
+Table\ \&290
+are built into
+pgbench
+and may be used in expressions appearing in
+\eset\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.B Table\ \&290.\ \&pgbench Functions
+.TS
+allbox tab(:);
+lB.
+T{
+.PP
+Function
+
+ .PP
+Description
+
+ .PP
+Example(s)
+T}
+.T&
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l
+l.
+T{
+.PP
+\fBabs\fR
+(
+\fInumber\fR
+)
+→
+same type as input
+
+ .PP
+Absolute value
+
+ .PP
+abs(\-17)
+→ 17
+T}
+T{
+.PP
+\fBdebug\fR
+(
+\fInumber\fR
+)
+→
+same type as input
+
+ .PP
+Prints the argument to
+stderr, and returns the argument\&.
+
+ .PP
+debug(5432\&.1)
+→ 5432\&.1
+T}
+T{
+.PP
+\fBdouble\fR
+(
+\fInumber\fR
+)
+→ double
+
+ .PP
+Casts to double\&.
+
+ .PP
+double(5432)
+→ 5432\&.0
+T}
+T{
+.PP
+\fBexp\fR
+(
+\fInumber\fR
+)
+→ double
+
+ .PP
+Exponential (e
+raised to the given power)
+
+ .PP
+exp(1\&.0)
+→ 2\&.718281828459045
+T}
+T{
+.PP
+\fBgreatest\fR
+(
+\fInumber\fR
+[, \&.\&.\&. ]
+)
+→
+double
+if any argument is double, else
+integer
+
+ .PP
+Selects the largest value among the arguments\&.
+
+ .PP
+greatest(5, 4, 3, 2)
+→ 5
+T}
+T{
+.PP
+\fBhash\fR
+(
+\fIvalue\fR
+[, \fIseed\fR ]
+)
+→ integer
+
+ .PP
+This is an alias for
+\fBhash_murmur2\fR\&.
+
+ .PP
+hash(10, 5432)
+→ \-5817877081768721676
+T}
+T{
+.PP
+\fBhash_fnv1a\fR
+(
+\fIvalue\fR
+[, \fIseed\fR ]
+)
+→ integer
+
+ .PP
+Computes
+\m[blue]\fBFNV\-1a hash\fR\m[]\&.
+
+ .PP
+hash_fnv1a(10, 5432)
+→ \-7793829335365542153
+T}
+T{
+.PP
+\fBhash_murmur2\fR
+(
+\fIvalue\fR
+[, \fIseed\fR ]
+)
+→ integer
+
+ .PP
+Computes
+\m[blue]\fBMurmurHash2 hash\fR\m[]\&.
+
+ .PP
+hash_murmur2(10, 5432)
+→ \-5817877081768721676
+T}
+T{
+.PP
+\fBint\fR
+(
+\fInumber\fR
+)
+→ integer
+
+ .PP
+Casts to integer\&.
+
+ .PP
+int(5\&.4 + 3\&.8)
+→ 9
+T}
+T{
+.PP
+\fBleast\fR
+(
+\fInumber\fR
+[, \&.\&.\&. ]
+)
+→
+double
+if any argument is double, else
+integer
+
+ .PP
+Selects the smallest value among the arguments\&.
+
+ .PP
+least(5, 4, 3, 2\&.1)
+→ 2\&.1
+T}
+T{
+.PP
+\fBln\fR
+(
+\fInumber\fR
+)
+→ double
+
+ .PP
+Natural logarithm
+
+ .PP
+ln(2\&.718281828459045)
+→ 1\&.0
+T}
+T{
+.PP
+\fBmod\fR
+(
+\fIinteger\fR,
+\fIinteger\fR
+)
+→ integer
+
+ .PP
+Modulo (remainder)
+
+ .PP
+mod(54, 32)
+→ 22
+T}
+T{
+.PP
+\fBpermute\fR
+(
+\fIi\fR,
+\fIsize\fR
+[,
+\fIseed\fR
+] )
+→ integer
+
+ .PP
+Permuted value of
+\fIi\fR, in the range
+[0, size)\&. This is the new position of
+\fIi\fR
+(modulo
+\fIsize\fR) in a pseudorandom permutation of the integers
+0\&.\&.\&.size\-1, parameterized by
+\fIseed\fR, see below\&.
+
+ .PP
+permute(0, 4)
+→ an integer between 0 and 3
+T}
+T{
+.PP
+\fBpi\fR
+()
+→ double
+
+ .PP
+Approximate value of
+
+ .PP
+pi()
+→ 3\&.14159265358979323846
+T}
+T{
+.PP
+\fBpow\fR
+(
+\fIx\fR,
+\fIy\fR
+)
+→ double
+
+ .PP
+\fBpower\fR
+(
+\fIx\fR,
+\fIy\fR
+)
+→ double
+
+ .PP
+\fIx\fR
+raised to the power of
+\fIy\fR
+
+ .PP
+pow(2\&.0, 10)
+→ 1024\&.0
+T}
+T{
+.PP
+\fBrandom\fR
+(
+\fIlb\fR,
+\fIub\fR
+)
+→ integer
+
+ .PP
+Computes a uniformly\-distributed random integer in
+[lb, ub]\&.
+
+ .PP
+random(1, 10)
+→ an integer between 1 and 10
+T}
+T{
+.PP
+\fBrandom_exponential\fR
+(
+\fIlb\fR,
+\fIub\fR,
+\fIparameter\fR
+)
+→ integer
+
+ .PP
+Computes an exponentially\-distributed random integer in
+[lb, ub], see below\&.
+
+ .PP
+random_exponential(1, 10, 3\&.0)
+→ an integer between 1 and 10
+T}
+T{
+.PP
+\fBrandom_gaussian\fR
+(
+\fIlb\fR,
+\fIub\fR,
+\fIparameter\fR
+)
+→ integer
+
+ .PP
+Computes a Gaussian\-distributed random integer in
+[lb, ub], see below\&.
+
+ .PP
+random_gaussian(1, 10, 2\&.5)
+→ an integer between 1 and 10
+T}
+T{
+.PP
+\fBrandom_zipfian\fR
+(
+\fIlb\fR,
+\fIub\fR,
+\fIparameter\fR
+)
+→ integer
+
+ .PP
+Computes a Zipfian\-distributed random integer in
+[lb, ub], see below\&.
+
+ .PP
+random_zipfian(1, 10, 1\&.5)
+→ an integer between 1 and 10
+T}
+T{
+.PP
+\fBsqrt\fR
+(
+\fInumber\fR
+)
+→ double
+
+ .PP
+Square root
+
+ .PP
+sqrt(2\&.0)
+→ 1\&.414213562
+T}
+.TE
+.sp 1
+.PP
+The
+random
+function generates values using a uniform distribution, that is all the values are drawn within the specified range with equal probability\&. The
+random_exponential,
+random_gaussian
+and
+random_zipfian
+functions require an additional double parameter which determines the precise shape of the distribution\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+For an exponential distribution,
+\fIparameter\fR
+controls the distribution by truncating a quickly\-decreasing exponential distribution at
+\fIparameter\fR, and then projecting onto integers between the bounds\&. To be precise, with
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+f(x) = exp(\-parameter * (x \- min) / (max \- min + 1)) / (1 \- exp(\-parameter))
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Then value
+\fIi\fR
+between
+\fImin\fR
+and
+\fImax\fR
+inclusive is drawn with probability:
+f(i) \- f(i + 1)\&.
+.sp
+Intuitively, the larger the
+\fIparameter\fR, the more frequently values close to
+\fImin\fR
+are accessed, and the less frequently values close to
+\fImax\fR
+are accessed\&. The closer to 0
+\fIparameter\fR
+is, the flatter (more uniform) the access distribution\&. A crude approximation of the distribution is that the most frequent 1% values in the range, close to
+\fImin\fR, are drawn
+\fIparameter\fR% of the time\&. The
+\fIparameter\fR
+value must be strictly positive\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+For a Gaussian distribution, the interval is mapped onto a standard normal distribution (the classical bell\-shaped Gaussian curve) truncated at
+\-parameter
+on the left and
++parameter
+on the right\&. Values in the middle of the interval are more likely to be drawn\&. To be precise, if
+PHI(x)
+is the cumulative distribution function of the standard normal distribution, with mean
+mu
+defined as
+(max + min) / 2\&.0, with
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+f(x) = PHI(2\&.0 * parameter * (x \- mu) / (max \- min + 1)) /
+ (2\&.0 * PHI(parameter) \- 1)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+then value
+\fIi\fR
+between
+\fImin\fR
+and
+\fImax\fR
+inclusive is drawn with probability:
+f(i + 0\&.5) \- f(i \- 0\&.5)\&. Intuitively, the larger the
+\fIparameter\fR, the more frequently values close to the middle of the interval are drawn, and the less frequently values close to the
+\fImin\fR
+and
+\fImax\fR
+bounds\&. About 67% of values are drawn from the middle
+1\&.0 / parameter, that is a relative
+0\&.5 / parameter
+around the mean, and 95% in the middle
+2\&.0 / parameter, that is a relative
+1\&.0 / parameter
+around the mean; for instance, if
+\fIparameter\fR
+is 4\&.0, 67% of values are drawn from the middle quarter (1\&.0 / 4\&.0) of the interval (i\&.e\&., from
+3\&.0 / 8\&.0
+to
+5\&.0 / 8\&.0) and 95% from the middle half (2\&.0 / 4\&.0) of the interval (second and third quartiles)\&. The minimum allowed
+\fIparameter\fR
+value is 2\&.0\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+random_zipfian
+generates a bounded Zipfian distribution\&.
+\fIparameter\fR
+defines how skewed the distribution is\&. The larger the
+\fIparameter\fR, the more frequently values closer to the beginning of the interval are drawn\&. The distribution is such that, assuming the range starts from 1, the ratio of the probability of drawing
+\fIk\fR
+versus drawing
+\fIk+1\fR
+is
+((\fIk\fR+1)/\fIk\fR)**\fIparameter\fR\&. For example,
+random_zipfian(1, \&.\&.\&., 2\&.5)
+produces the value
+1
+about
+(2/1)**2\&.5 = 5\&.66
+times more frequently than
+2, which itself is produced
+(3/2)**2\&.5 = 2\&.76
+times more frequently than
+3, and so on\&.
+.sp
+pgbench\*(Aqs implementation is based on "Non\-Uniform Random Variate Generation", Luc Devroye, p\&. 550\-551, Springer 1986\&. Due to limitations of that algorithm, the
+\fIparameter\fR
+value is restricted to the range [1\&.001, 1000]\&.
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+When designing a benchmark which selects rows non\-uniformly, be aware that the rows chosen may be correlated with other data such as IDs from a sequence or the physical row ordering, which may skew performance measurements\&.
+.PP
+To avoid this, you may wish to use the
+\fBpermute\fR
+function, or some other additional step with similar effect, to shuffle the selected rows and remove such correlations\&.
+.sp .5v
+.RE
+.PP
+Hash functions
+hash,
+hash_murmur2
+and
+hash_fnv1a
+accept an input value and an optional seed parameter\&. In case the seed isn\*(Aqt provided the value of
+:default_seed
+is used, which is initialized randomly unless set by the command\-line
+\-D
+option\&.
+.PP
+permute
+accepts an input value, a size, and an optional seed parameter\&. It generates a pseudorandom permutation of integers in the range
+[0, size), and returns the index of the input value in the permuted values\&. The permutation chosen is parameterized by the seed, which defaults to
+:default_seed, if not specified\&. Unlike the hash functions,
+permute
+ensures that there are no collisions or holes in the output values\&. Input values outside the interval are interpreted modulo the size\&. The function raises an error if the size is not positive\&.
+\fBpermute\fR
+can be used to scatter the distribution of non\-uniform random functions such as
+random_zipfian
+or
+random_exponential
+so that values drawn more often are not trivially correlated\&. For instance, the following
+pgbench
+script simulates a possible real world workload typical for social media and blogging platforms where a few accounts generate excessive load:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eset size 1000000
+\eset r random_zipfian(1, :size, 1\&.07)
+\eset k 1 + permute(:r, :size)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In some cases several distinct distributions are needed which don\*(Aqt correlate with each other and this is when the optional seed parameter comes in handy:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eset k1 1 + permute(:r, :size, :default_seed + 123)
+\eset k2 1 + permute(:r, :size, :default_seed + 321)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A similar behavior can also be approximated with
+\fBhash\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eset size 1000000
+\eset r random_zipfian(1, 100 * :size, 1\&.07)
+\eset k 1 + abs(hash(:r)) % :size
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+However, since
+\fBhash\fR
+generates collisions, some values will not be reachable and others will be more frequent than expected from the original distribution\&.
+.PP
+As an example, the full definition of the built\-in TPC\-B\-like transaction is:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eset aid random(1, 100000 * :scale)
+\eset bid random(1, 1 * :scale)
+\eset tid random(1, 10 * :scale)
+\eset delta random(\-5000, 5000)
+BEGIN;
+UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+END;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This script allows each iteration of the transaction to reference different, randomly\-chosen rows\&. (This example also shows why it\*(Aqs important for each client session to have its own variables \(em otherwise they\*(Aqd not be independently touching different rows\&.)
+.SS "Per\-Transaction Logging"
+.PP
+With the
+\fB\-l\fR
+option (but without the
+\fB\-\-aggregate\-interval\fR
+option),
+pgbench
+writes information about each transaction to a log file\&. The log file will be named
+\fIprefix\fR\&.\fInnn\fR, where
+\fIprefix\fR
+defaults to
+pgbench_log, and
+\fInnn\fR
+is the PID of the
+pgbench
+process\&. The prefix can be changed by using the
+\fB\-\-log\-prefix\fR
+option\&. If the
+\fB\-j\fR
+option is 2 or higher, so that there are multiple worker threads, each will have its own log file\&. The first worker will use the same name for its log file as in the standard single worker case\&. The additional log files for the other workers will be named
+\fIprefix\fR\&.\fInnn\fR\&.\fImmm\fR, where
+\fImmm\fR
+is a sequential number for each worker starting with 1\&.
+.PP
+Each line in a log file describes one transaction\&. It contains the following space\-separated fields:
+.PP
+\fIclient_id\fR
+.RS 4
+identifies the client session that ran the transaction
+.RE
+.PP
+\fItransaction_no\fR
+.RS 4
+counts how many transactions have been run by that session
+.RE
+.PP
+\fItime\fR
+.RS 4
+transaction\*(Aqs elapsed time, in microseconds
+.RE
+.PP
+\fIscript_no\fR
+.RS 4
+identifies the script file that was used for the transaction (useful when multiple scripts are specified with
+\fB\-f\fR
+or
+\fB\-b\fR)
+.RE
+.PP
+\fItime_epoch\fR
+.RS 4
+transaction\*(Aqs completion time, as a Unix\-epoch time stamp
+.RE
+.PP
+\fItime_us\fR
+.RS 4
+fractional\-second part of transaction\*(Aqs completion time, in microseconds
+.RE
+.PP
+\fIschedule_lag\fR
+.RS 4
+transaction start delay, that is the difference between the transaction\*(Aqs scheduled start time and the time it actually started, in microseconds (present only if
+\fB\-\-rate\fR
+is specified)
+.RE
+.PP
+\fIretries\fR
+.RS 4
+count of retries after serialization or deadlock errors during the transaction (present only if
+\fB\-\-max\-tries\fR
+is not equal to one)
+.RE
+.PP
+When both
+\fB\-\-rate\fR
+and
+\fB\-\-latency\-limit\fR
+are used, the
+\fItime\fR
+for a skipped transaction will be reported as
+skipped\&. If the transaction ends with a failure, its
+\fItime\fR
+will be reported as
+failed\&. If you use the
+\fB\-\-failures\-detailed\fR
+option, the
+\fItime\fR
+of the failed transaction will be reported as
+serialization
+or
+deadlock
+depending on the type of failure (see
+Failures and Serialization/Deadlock Retries
+for more information)\&.
+.PP
+Here is a snippet of a log file generated in a single\-client run:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+0 199 2241 0 1175850568 995598
+0 200 2465 0 1175850568 998079
+0 201 2513 0 1175850569 608
+0 202 2038 0 1175850569 2663
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Another example with
+\-\-rate=100
+and
+\-\-latency\-limit=5
+(note the additional
+\fIschedule_lag\fR
+column):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+0 81 4621 0 1412881037 912698 3005
+0 82 6173 0 1412881037 914578 4304
+0 83 skipped 0 1412881037 914578 5217
+0 83 skipped 0 1412881037 914578 5099
+0 83 4722 0 1412881037 916203 3108
+0 84 4142 0 1412881037 918023 2333
+0 85 2465 0 1412881037 919759 740
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In this example, transaction 82 was late, because its latency (6\&.173 ms) was over the 5 ms limit\&. The next two transactions were skipped, because they were already late before they were even started\&.
+.PP
+The following example shows a snippet of a log file with failures and retries, with the maximum number of tries set to 10 (note the additional
+\fIretries\fR
+column):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+3 0 47423 0 1499414498 34501 3
+3 1 8333 0 1499414498 42848 0
+3 2 8358 0 1499414498 51219 0
+4 0 72345 0 1499414498 59433 6
+1 3 41718 0 1499414498 67879 4
+1 4 8416 0 1499414498 76311 0
+3 3 33235 0 1499414498 84469 3
+0 0 failed 0 1499414498 84905 9
+2 0 failed 0 1499414498 86248 9
+3 4 8307 0 1499414498 92788 0
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+If the
+\fB\-\-failures\-detailed\fR
+option is used, the type of failure is reported in the
+\fItime\fR
+like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+3 0 47423 0 1499414498 34501 3
+3 1 8333 0 1499414498 42848 0
+3 2 8358 0 1499414498 51219 0
+4 0 72345 0 1499414498 59433 6
+1 3 41718 0 1499414498 67879 4
+1 4 8416 0 1499414498 76311 0
+3 3 33235 0 1499414498 84469 3
+0 0 serialization 0 1499414498 84905 9
+2 0 serialization 0 1499414498 86248 9
+3 4 8307 0 1499414498 92788 0
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+When running a long test on hardware that can handle a lot of transactions, the log files can become very large\&. The
+\fB\-\-sampling\-rate\fR
+option can be used to log only a random sample of transactions\&.
+.SS "Aggregated Logging"
+.PP
+With the
+\fB\-\-aggregate\-interval\fR
+option, a different format is used for the log files\&. Each log line describes one aggregation interval\&. It contains the following space\-separated fields:
+.PP
+\fIinterval_start\fR
+.RS 4
+start time of the interval, as a Unix\-epoch time stamp
+.RE
+.PP
+\fInum_transactions\fR
+.RS 4
+number of transactions within the interval
+.RE
+.PP
+\fIsum_latency\fR
+.RS 4
+sum of transaction latencies
+.RE
+.PP
+\fIsum_latency_2\fR
+.RS 4
+sum of squares of transaction latencies
+.RE
+.PP
+\fImin_latency\fR
+.RS 4
+minimum transaction latency
+.RE
+.PP
+\fImax_latency\fR
+.RS 4
+maximum transaction latency
+.RE
+.PP
+\fIsum_lag\fR
+.RS 4
+sum of transaction start delays (zero unless
+\fB\-\-rate\fR
+is specified)
+.RE
+.PP
+\fIsum_lag_2\fR
+.RS 4
+sum of squares of transaction start delays (zero unless
+\fB\-\-rate\fR
+is specified)
+.RE
+.PP
+\fImin_lag\fR
+.RS 4
+minimum transaction start delay (zero unless
+\fB\-\-rate\fR
+is specified)
+.RE
+.PP
+\fImax_lag\fR
+.RS 4
+maximum transaction start delay (zero unless
+\fB\-\-rate\fR
+is specified)
+.RE
+.PP
+\fIskipped\fR
+.RS 4
+number of transactions skipped because they would have started too late (zero unless
+\fB\-\-rate\fR
+and
+\fB\-\-latency\-limit\fR
+are specified)
+.RE
+.PP
+\fIretried\fR
+.RS 4
+number of retried transactions (zero unless
+\fB\-\-max\-tries\fR
+is not equal to one)
+.RE
+.PP
+\fIretries\fR
+.RS 4
+number of retries after serialization or deadlock errors (zero unless
+\fB\-\-max\-tries\fR
+is not equal to one)
+.RE
+.PP
+\fIserialization_failures\fR
+.RS 4
+number of transactions that got a serialization error and were not retried afterwards (zero unless
+\fB\-\-failures\-detailed\fR
+is specified)
+.RE
+.PP
+\fIdeadlock_failures\fR
+.RS 4
+number of transactions that got a deadlock error and were not retried afterwards (zero unless
+\fB\-\-failures\-detailed\fR
+is specified)
+.RE
+.PP
+Here is some example output generated with these options:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBpgbench \-\-aggregate\-interval=10 \-\-time=20 \-\-client=10 \-\-log \-\-rate=1000 \-\-latency\-limit=10 \-\-failures\-detailed \-\-max\-tries=10 test\fR
+
+1650260552 5178 26171317 177284491527 1136 44462 2647617 7321113867 0 9866 64 7564 28340 4148 0
+1650260562 4808 25573984 220121792172 1171 62083 3037380 9666800914 0 9998 598 7392 26621 4527 0
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Notice that while the plain (unaggregated) log format shows which script was used for each transaction, the aggregated format does not\&. Therefore if you need per\-script data, you need to aggregate the data on your own\&.
+.SS "Per\-Statement Report"
+.PP
+With the
+\fB\-r\fR
+option,
+pgbench
+collects the following statistics for each statement:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+latency
+\(em elapsed transaction time for each statement\&.
+pgbench
+reports an average value of all successful runs of the statement\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The number of failures in this statement\&. See
+Failures and Serialization/Deadlock Retries
+for more information\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The number of retries after a serialization or a deadlock error in this statement\&. See
+Failures and Serialization/Deadlock Retries
+for more information\&.
+.RE
+.PP
+The report displays retry statistics only if the
+\fB\-\-max\-tries\fR
+option is not equal to 1\&.
+.PP
+All values are computed for each statement executed by every client and are reported after the benchmark has finished\&.
+.PP
+For the default script, the output will look similar to this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+starting vacuum\&.\&.\&.end\&.
+transaction type: <builtin: TPC\-B (sort of)>
+scaling factor: 1
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+number of failed transactions: 0 (0\&.000%)
+number of transactions above the 50\&.0 ms latency limit: 1311/10000 (13\&.110 %)
+latency average = 28\&.488 ms
+latency stddev = 21\&.009 ms
+initial connection time = 69\&.068 ms
+tps = 346\&.224794 (without initial connection time)
+statement latencies in milliseconds and failures:
+ 0\&.012 0 \eset aid random(1, 100000 * :scale)
+ 0\&.002 0 \eset bid random(1, 1 * :scale)
+ 0\&.002 0 \eset tid random(1, 10 * :scale)
+ 0\&.002 0 \eset delta random(\-5000, 5000)
+ 0\&.319 0 BEGIN;
+ 0\&.834 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+ 0\&.641 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+ 11\&.126 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+ 12\&.961 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+ 0\&.634 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+ 1\&.957 0 END;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Another example of output for the default script using serializable default transaction isolation level (\fBPGOPTIONS=\*(Aq\-c default_transaction_isolation=serializable\*(Aq pgbench \&.\&.\&.\fR):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+starting vacuum\&.\&.\&.end\&.
+transaction type: <builtin: TPC\-B (sort of)>
+scaling factor: 1
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 10
+number of transactions per client: 1000
+number of transactions actually processed: 6317/10000
+number of failed transactions: 3683 (36\&.830%)
+number of transactions retried: 7667 (76\&.670%)
+total number of retries: 45339
+number of transactions above the 50\&.0 ms latency limit: 106/6317 (1\&.678 %)
+latency average = 17\&.016 ms
+latency stddev = 13\&.283 ms
+initial connection time = 45\&.017 ms
+tps = 186\&.792667 (without initial connection time)
+statement latencies in milliseconds, failures and retries:
+ 0\&.006 0 0 \eset aid random(1, 100000 * :scale)
+ 0\&.001 0 0 \eset bid random(1, 1 * :scale)
+ 0\&.001 0 0 \eset tid random(1, 10 * :scale)
+ 0\&.001 0 0 \eset delta random(\-5000, 5000)
+ 0\&.385 0 0 BEGIN;
+ 0\&.773 0 1 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+ 0\&.624 0 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+ 1\&.098 320 3762 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+ 0\&.582 3363 41576 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+ 0\&.465 0 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+ 1\&.933 0 0 END;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+If multiple script files are specified, all statistics are reported separately for each script file\&.
+.PP
+Note that collecting the additional timing information needed for per\-statement latency computation adds some overhead\&. This will slow average execution speed and lower the computed TPS\&. The amount of slowdown varies significantly depending on platform and hardware\&. Comparing average TPS values with and without latency reporting enabled is a good way to measure if the timing overhead is significant\&.
+.SS "Failures and Serialization/Deadlock Retries"
+.PP
+When executing
+pgbench, there are three main types of errors:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Errors of the main program\&. They are the most serious and always result in an immediate exit from
+pgbench
+with the corresponding error message\&. They include:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+errors at the beginning of
+pgbench
+(e\&.g\&. an invalid option value);
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+errors in the initialization mode (e\&.g\&. the query to create tables for built\-in scripts fails);
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+errors before starting threads (e\&.g\&. could not connect to the database server, syntax error in the meta command, thread creation failure);
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+internal
+pgbench
+errors (which are supposed to never occur\&.\&.\&.)\&.
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Errors when the thread manages its clients (e\&.g\&. the client could not start a connection to the database server / the socket for connecting the client to the database server has become invalid)\&. In such cases all clients of this thread stop while other threads continue to work\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Direct client errors\&. They lead to immediate exit from
+pgbench
+with the corresponding error message only in the case of an internal
+pgbench
+error (which are supposed to never occur\&.\&.\&.)\&. Otherwise in the worst case they only lead to the abortion of the failed client while other clients continue their run (but some client errors are handled without an abortion of the client and reported separately, see below)\&. Later in this section it is assumed that the discussed errors are only the direct client errors and they are not internal
+pgbench
+errors\&.
+.RE
+.PP
+A client\*(Aqs run is aborted in case of a serious error; for example, the connection with the database server was lost or the end of script was reached without completing the last transaction\&. In addition, if execution of an SQL or meta command fails for reasons other than serialization or deadlock errors, the client is aborted\&. Otherwise, if an SQL command fails with serialization or deadlock errors, the client is not aborted\&. In such cases, the current transaction is rolled back, which also includes setting the client variables as they were before the run of this transaction (it is assumed that one transaction script contains only one transaction; see
+What Is the "Transaction" Actually Performed in pgbench?
+for more information)\&. Transactions with serialization or deadlock errors are repeated after rollbacks until they complete successfully or reach the maximum number of tries (specified by the
+\fB\-\-max\-tries\fR
+option) / the maximum time of retries (specified by the
+\fB\-\-latency\-limit\fR
+option) / the end of benchmark (specified by the
+\fB\-\-time\fR
+option)\&. If the last trial run fails, this transaction will be reported as failed but the client is not aborted and continues to work\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+Without specifying the
+\fB\-\-max\-tries\fR
+option, a transaction will never be retried after a serialization or deadlock error because its default value is 1\&. Use an unlimited number of tries (\-\-max\-tries=0) and the
+\fB\-\-latency\-limit\fR
+option to limit only the maximum time of tries\&. You can also use the
+\fB\-\-time\fR
+option to limit the benchmark duration under an unlimited number of tries\&.
+.PP
+Be careful when repeating scripts that contain multiple transactions: the script is always retried completely, so successful transactions can be performed several times\&.
+.PP
+Be careful when repeating transactions with shell commands\&. Unlike the results of SQL commands, the results of shell commands are not rolled back, except for the variable value of the
+\fB\esetshell\fR
+command\&.
+.sp .5v
+.RE
+.PP
+The latency of a successful transaction includes the entire time of transaction execution with rollbacks and retries\&. The latency is measured only for successful transactions and commands but not for failed transactions or commands\&.
+.PP
+The main report contains the number of failed transactions\&. If the
+\fB\-\-max\-tries\fR
+option is not equal to 1, the main report also contains statistics related to retries: the total number of retried transactions and total number of retries\&. The per\-script report inherits all these fields from the main report\&. The per\-statement report displays retry statistics only if the
+\fB\-\-max\-tries\fR
+option is not equal to 1\&.
+.PP
+If you want to group failures by basic types in per\-transaction and aggregation logs, as well as in the main and per\-script reports, use the
+\fB\-\-failures\-detailed\fR
+option\&. If you also want to distinguish all errors and failures (errors without retrying) by type including which limit for retries was exceeded and how much it was exceeded by for the serialization/deadlock failures, use the
+\fB\-\-verbose\-errors\fR
+option\&.
+.SS "Good Practices"
+.PP
+It is very easy to use
+pgbench
+to produce completely meaningless numbers\&. Here are some guidelines to help you get useful results\&.
+.PP
+In the first place,
+\fInever\fR
+believe any test that runs for only a few seconds\&. Use the
+\fB\-t\fR
+or
+\fB\-T\fR
+option to make the run last at least a few minutes, so as to average out noise\&. In some cases you could need hours to get numbers that are reproducible\&. It\*(Aqs a good idea to try the test run a few times, to find out if your numbers are reproducible or not\&.
+.PP
+For the default TPC\-B\-like test scenario, the initialization scale factor (\fB\-s\fR) should be at least as large as the largest number of clients you intend to test (\fB\-c\fR); else you\*(Aqll mostly be measuring update contention\&. There are only
+\fB\-s\fR
+rows in the
+pgbench_branches
+table, and every transaction wants to update one of them, so
+\fB\-c\fR
+values in excess of
+\fB\-s\fR
+will undoubtedly result in lots of transactions blocked waiting for other transactions\&.
+.PP
+The default test scenario is also quite sensitive to how long it\*(Aqs been since the tables were initialized: accumulation of dead rows and dead space in the tables changes the results\&. To understand the results you must keep track of the total number of updates and when vacuuming happens\&. If autovacuum is enabled it can result in unpredictable changes in measured performance\&.
+.PP
+A limitation of
+pgbench
+is that it can itself become the bottleneck when trying to test a large number of client sessions\&. This can be alleviated by running
+pgbench
+on a different machine from the database server, although low network latency will be essential\&. It might even be useful to run several
+pgbench
+instances concurrently, on several client machines, against the same database server\&.
+.SS "Security"
+.PP
+If untrusted users have access to a database that has not adopted a
+secure schema usage pattern, do not run
+pgbench
+in that database\&.
+pgbench
+uses unqualified names and does not manipulate the search path\&.
diff --git a/doc/src/sgml/man1/postgres.1 b/doc/src/sgml/man1/postgres.1
new file mode 100644
index 0000000..b4e783a
--- /dev/null
+++ b/doc/src/sgml/man1/postgres.1
@@ -0,0 +1,631 @@
+'\" t
+.\" Title: postgres
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "POSTGRES" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+postgres \- PostgreSQL database server
+.SH "SYNOPSIS"
+.HP \w'\fBpostgres\fR\ 'u
+\fBpostgres\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+\fBpostgres\fR
+is the
+PostgreSQL
+database server\&. In order for a client application to access a database it connects (over a network or locally) to a running
+\fBpostgres\fR
+instance\&. The
+\fBpostgres\fR
+instance then starts a separate server process to handle the connection\&.
+.PP
+One
+\fBpostgres\fR
+instance always manages the data of exactly one database cluster\&. A database cluster is a collection of databases that is stored at a common file system location (the
+\(lqdata area\(rq)\&. More than one
+\fBpostgres\fR
+instance can run on a system at one time, so long as they use different data areas and different communication ports (see below)\&. When
+\fBpostgres\fR
+starts it needs to know the location of the data area\&. The location must be specified by the
+\fB\-D\fR
+option or the
+\fBPGDATA\fR
+environment variable; there is no default\&. Typically,
+\fB\-D\fR
+or
+\fBPGDATA\fR
+points directly to the data area directory created by
+\fBinitdb\fR(1)\&. Other possible file layouts are discussed in
+Section\ \&20.2\&.
+.PP
+By default
+\fBpostgres\fR
+starts in the foreground and prints log messages to the standard error stream\&. In practical applications
+\fBpostgres\fR
+should be started as a background process, perhaps at boot time\&.
+.PP
+The
+\fBpostgres\fR
+command can also be called in single\-user mode\&. The primary use for this mode is during bootstrapping by
+\fBinitdb\fR(1)\&. Sometimes it is used for debugging or disaster recovery; note that running a single\-user server is not truly suitable for debugging the server, since no realistic interprocess communication and locking will happen\&. When invoked in single\-user mode from the shell, the user can enter queries and the results will be printed to the screen, but in a form that is more useful for developers than end users\&. In the single\-user mode, the session user will be set to the user with ID 1, and implicit superuser powers are granted to this user\&. This user does not actually have to exist, so the single\-user mode can be used to manually recover from certain kinds of accidental damage to the system catalogs\&.
+.SH "OPTIONS"
+.PP
+\fBpostgres\fR
+accepts the following command\-line arguments\&. For a detailed discussion of the options consult
+Chapter\ \&20\&. You can save typing most of these options by setting up a configuration file\&. Some (safe) options can also be set from the connecting client in an application\-dependent way to apply only for that session\&. For example, if the environment variable
+\fBPGOPTIONS\fR
+is set, then
+libpq\-based clients will pass that string to the server, which will interpret it as
+\fBpostgres\fR
+command\-line options\&.
+.SS "General Purpose"
+.PP
+\fB\-B \fR\fB\fInbuffers\fR\fR
+.RS 4
+Sets the number of shared buffers for use by the server processes\&. The default value of this parameter is chosen automatically by
+initdb\&. Specifying this option is equivalent to setting the
+shared_buffers
+configuration parameter\&.
+.RE
+.PP
+\fB\-c \fR\fB\fIname\fR\fR\fB=\fR\fB\fIvalue\fR\fR
+.RS 4
+Sets a named run\-time parameter\&. The configuration parameters supported by
+PostgreSQL
+are described in
+Chapter\ \&20\&. Most of the other command line options are in fact short forms of such a parameter assignment\&.
+\fB\-c\fR
+can appear multiple times to set multiple parameters\&.
+.RE
+.PP
+\fB\-C \fR\fB\fIname\fR\fR
+.RS 4
+Prints the value of the named run\-time parameter, and exits\&. (See the
+\fB\-c\fR
+option above for details\&.) This returns values from
+postgresql\&.conf, modified by any parameters supplied in this invocation\&. It does not reflect parameters supplied when the cluster was started\&.
+.sp
+This can be used on a running server for most parameters\&. However, the server must be shut down for some runtime\-computed parameters (e\&.g\&.,
+shared_memory_size,
+shared_memory_size_in_huge_pages, and
+wal_segment_size)\&.
+.sp
+This option is meant for other programs that interact with a server instance, such as
+\fBpg_ctl\fR(1), to query configuration parameter values\&. User\-facing applications should instead use
+\fBSHOW\fR
+or the
+pg_settings
+view\&.
+.RE
+.PP
+\fB\-d \fR\fB\fIdebug\-level\fR\fR
+.RS 4
+Sets the debug level\&. The higher this value is set, the more debugging output is written to the server log\&. Values are from 1 to 5\&. It is also possible to pass
+\-d 0
+for a specific session, which will prevent the server log level of the parent
+\fBpostgres\fR
+process from being propagated to this session\&.
+.RE
+.PP
+\fB\-D \fR\fB\fIdatadir\fR\fR
+.RS 4
+Specifies the file system location of the database configuration files\&. See
+Section\ \&20.2
+for details\&.
+.RE
+.PP
+\fB\-e\fR
+.RS 4
+Sets the default date style to
+\(lqEuropean\(rq, that is
+DMY
+ordering of input date fields\&. This also causes the day to be printed before the month in certain date output formats\&. See
+Section\ \&8.5
+for more information\&.
+.RE
+.PP
+\fB\-F\fR
+.RS 4
+Disables
+\fBfsync\fR
+calls for improved performance, at the risk of data corruption in the event of a system crash\&. Specifying this option is equivalent to disabling the
+fsync
+configuration parameter\&. Read the detailed documentation before using this!
+.RE
+.PP
+\fB\-h \fR\fB\fIhostname\fR\fR
+.RS 4
+Specifies the IP host name or address on which
+\fBpostgres\fR
+is to listen for TCP/IP connections from client applications\&. The value can also be a comma\-separated list of addresses, or
+*
+to specify listening on all available interfaces\&. An empty value specifies not listening on any IP addresses, in which case only Unix\-domain sockets can be used to connect to the server\&. Defaults to listening only on
+localhost\&. Specifying this option is equivalent to setting the
+listen_addresses
+configuration parameter\&.
+.RE
+.PP
+\fB\-i\fR
+.RS 4
+Allows remote clients to connect via TCP/IP (Internet domain) connections\&. Without this option, only local connections are accepted\&. This option is equivalent to setting
+\fIlisten_addresses\fR
+to
+*
+in
+postgresql\&.conf
+or via
+\fB\-h\fR\&.
+.sp
+This option is deprecated since it does not allow access to the full functionality of
+listen_addresses\&. It\*(Aqs usually better to set
+\fIlisten_addresses\fR
+directly\&.
+.RE
+.PP
+\fB\-k \fR\fB\fIdirectory\fR\fR
+.RS 4
+Specifies the directory of the Unix\-domain socket on which
+\fBpostgres\fR
+is to listen for connections from client applications\&. The value can also be a comma\-separated list of directories\&. An empty value specifies not listening on any Unix\-domain sockets, in which case only TCP/IP sockets can be used to connect to the server\&. The default value is normally
+/tmp, but that can be changed at build time\&. Specifying this option is equivalent to setting the
+unix_socket_directories
+configuration parameter\&.
+.RE
+.PP
+\fB\-l\fR
+.RS 4
+Enables secure connections using
+SSL\&.
+PostgreSQL
+must have been compiled with support for
+SSL
+for this option to be available\&. For more information on using
+SSL, refer to
+Section\ \&19.9\&.
+.RE
+.PP
+\fB\-N \fR\fB\fImax\-connections\fR\fR
+.RS 4
+Sets the maximum number of client connections that this server will accept\&. The default value of this parameter is chosen automatically by
+initdb\&. Specifying this option is equivalent to setting the
+max_connections
+configuration parameter\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP/IP port or local Unix domain socket file extension on which
+\fBpostgres\fR
+is to listen for connections from client applications\&. Defaults to the value of the
+\fBPGPORT\fR
+environment variable, or if
+\fBPGPORT\fR
+is not set, then defaults to the value established during compilation (normally 5432)\&. If you specify a port other than the default port, then all client applications must specify the same port using either command\-line options or
+\fBPGPORT\fR\&.
+.RE
+.PP
+\fB\-s\fR
+.RS 4
+Print time information and other statistics at the end of each command\&. This is useful for benchmarking or for use in tuning the number of buffers\&.
+.RE
+.PP
+\fB\-S\fR \fIwork\-mem\fR
+.RS 4
+Specifies the base amount of memory to be used by sorts and hash tables before resorting to temporary disk files\&. See the description of the
+\fIwork_mem\fR
+configuration parameter in
+Section\ \&20.4.1\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+postgres
+version and exit\&.
+.RE
+.PP
+\fB\-\-\fR\fB\fIname\fR\fR\fB=\fR\fB\fIvalue\fR\fR
+.RS 4
+Sets a named run\-time parameter; a shorter form of
+\fB\-c\fR\&.
+.RE
+.PP
+\fB\-\-describe\-config\fR
+.RS 4
+This option dumps out the server\*(Aqs internal configuration variables, descriptions, and defaults in tab\-delimited
+\fBCOPY\fR
+format\&. It is designed primarily for use by administration tools\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+postgres
+command line arguments, and exit\&.
+.RE
+.SS "Semi\-Internal Options"
+.PP
+The options described here are used mainly for debugging purposes, and in some cases to assist with recovery of severely damaged databases\&. There should be no reason to use them in a production database setup\&. They are listed here only for use by
+PostgreSQL
+system developers\&. Furthermore, these options might change or be removed in a future release without notice\&.
+.PP
+\fB\-f\fR { s | i | o | b | t | n | m | h }
+.RS 4
+Forbids the use of particular scan and join methods:
+s
+and
+i
+disable sequential and index scans respectively,
+o,
+b
+and
+t
+disable index\-only scans, bitmap index scans, and TID scans respectively, while
+n,
+m, and
+h
+disable nested\-loop, merge and hash joins respectively\&.
+.sp
+Neither sequential scans nor nested\-loop joins can be disabled completely; the
+\-fs
+and
+\-fn
+options simply discourage the optimizer from using those plan types if it has any other alternative\&.
+.RE
+.PP
+\fB\-n\fR
+.RS 4
+This option is for debugging problems that cause a server process to die abnormally\&. The ordinary strategy in this situation is to notify all other server processes that they must terminate and then reinitialize the shared memory and semaphores\&. This is because an errant server process could have corrupted some shared state before terminating\&. This option specifies that
+\fBpostgres\fR
+will not reinitialize shared data structures\&. A knowledgeable system programmer can then use a debugger to examine shared memory and semaphore state\&.
+.RE
+.PP
+\fB\-O\fR
+.RS 4
+Allows the structure of system tables to be modified\&. This is used by
+\fBinitdb\fR\&.
+.RE
+.PP
+\fB\-P\fR
+.RS 4
+Ignore system indexes when reading system tables, but still update the indexes when modifying the tables\&. This is useful when recovering from damaged system indexes\&.
+.RE
+.PP
+\fB\-t\fR pa[rser] | pl[anner] | e[xecutor]
+.RS 4
+Print timing statistics for each query relating to each of the major system modules\&. This option cannot be used together with the
+\fB\-s\fR
+option\&.
+.RE
+.PP
+\fB\-T\fR
+.RS 4
+This option is for debugging problems that cause a server process to die abnormally\&. The ordinary strategy in this situation is to notify all other server processes that they must terminate and then reinitialize the shared memory and semaphores\&. This is because an errant server process could have corrupted some shared state before terminating\&. This option specifies that
+\fBpostgres\fR
+will stop all other server processes by sending the signal
+SIGSTOP, but will not cause them to terminate\&. This permits system programmers to collect core dumps from all server processes by hand\&.
+.RE
+.PP
+\fB\-v\fR \fIprotocol\fR
+.RS 4
+Specifies the version number of the frontend/backend protocol to be used for a particular session\&. This option is for internal use only\&.
+.RE
+.PP
+\fB\-W\fR \fIseconds\fR
+.RS 4
+A delay of this many seconds occurs when a new server process is started, after it conducts the authentication procedure\&. This is intended to give an opportunity to attach to the server process with a debugger\&.
+.RE
+.SS "Options for Single\-User Mode"
+.PP
+The following options only apply to the single\-user mode (see
+Single-User Mode
+below)\&.
+.PP
+\fB\-\-single\fR
+.RS 4
+Selects the single\-user mode\&. This must be the first argument on the command line\&.
+.RE
+.PP
+\fIdatabase\fR
+.RS 4
+Specifies the name of the database to be accessed\&. This must be the last argument on the command line\&. If it is omitted it defaults to the user name\&.
+.RE
+.PP
+\fB\-E\fR
+.RS 4
+Echo all commands to standard output before executing them\&.
+.RE
+.PP
+\fB\-j\fR
+.RS 4
+Use semicolon followed by two newlines, rather than just newline, as the command entry terminator\&.
+.RE
+.PP
+\fB\-r\fR \fIfilename\fR
+.RS 4
+Send all server log output to
+\fIfilename\fR\&. This option is only honored when supplied as a command\-line option\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGCLIENTENCODING\fR
+.RS 4
+Default character encoding used by clients\&. (The clients can override this individually\&.) This value can also be set in the configuration file\&.
+.RE
+.PP
+\fBPGDATA\fR
+.RS 4
+Default data directory location
+.RE
+.PP
+\fBPGDATESTYLE\fR
+.RS 4
+Default value of the
+DateStyle
+run\-time parameter\&. (The use of this environment variable is deprecated\&.)
+.RE
+.PP
+\fBPGPORT\fR
+.RS 4
+Default port number (preferably set in the configuration file)
+.RE
+.SH "DIAGNOSTICS"
+.PP
+A failure message mentioning
+semget
+or
+shmget
+probably indicates you need to configure your kernel to provide adequate shared memory and semaphores\&. For more discussion see
+Section\ \&19.4\&. You might be able to postpone reconfiguring your kernel by decreasing
+shared_buffers
+to reduce the shared memory consumption of
+PostgreSQL, and/or by reducing
+max_connections
+to reduce the semaphore consumption\&.
+.PP
+A failure message suggesting that another server is already running should be checked carefully, for example by using the command
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBps ax | grep postgres\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+or
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBps \-ef | grep postgres\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+depending on your system\&. If you are certain that no conflicting server is running, you can remove the lock file mentioned in the message and try again\&.
+.PP
+A failure message indicating inability to bind to a port might indicate that that port is already in use by some non\-PostgreSQL
+process\&. You might also get this error if you terminate
+\fBpostgres\fR
+and immediately restart it using the same port; in this case, you must simply wait a few seconds until the operating system closes the port before trying again\&. Finally, you might get this error if you specify a port number that your operating system considers to be reserved\&. For example, many versions of Unix consider port numbers under 1024 to be
+\(lqtrusted\(rq
+and only permit the Unix superuser to access them\&.
+.SH "NOTES"
+.PP
+The utility command
+\fBpg_ctl\fR(1)
+can be used to start and shut down the
+\fBpostgres\fR
+server safely and comfortably\&.
+.PP
+If at all possible,
+\fIdo not\fR
+use
+SIGKILL
+to kill the main
+\fBpostgres\fR
+server\&. Doing so will prevent
+\fBpostgres\fR
+from freeing the system resources (e\&.g\&., shared memory and semaphores) that it holds before terminating\&. This might cause problems for starting a fresh
+\fBpostgres\fR
+run\&.
+.PP
+To terminate the
+\fBpostgres\fR
+server normally, the signals
+SIGTERM,
+SIGINT, or
+SIGQUIT
+can be used\&. The first will wait for all clients to terminate before quitting, the second will forcefully disconnect all clients, and the third will quit immediately without proper shutdown, resulting in a recovery run during restart\&.
+.PP
+The
+SIGHUP
+signal will reload the server configuration files\&. It is also possible to send
+SIGHUP
+to an individual server process, but that is usually not sensible\&.
+.PP
+To cancel a running query, send the
+SIGINT
+signal to the process running that command\&. To terminate a backend process cleanly, send
+SIGTERM
+to that process\&. See also
+\fBpg_cancel_backend\fR
+and
+\fBpg_terminate_backend\fR
+in
+Section\ \&9.27.2
+for the SQL\-callable equivalents of these two actions\&.
+.PP
+The
+\fBpostgres\fR
+server uses
+SIGQUIT
+to tell subordinate server processes to terminate without normal cleanup\&. This signal
+\fIshould not\fR
+be used by users\&. It is also unwise to send
+SIGKILL
+to a server process \(em the main
+\fBpostgres\fR
+process will interpret this as a crash and will force all the sibling processes to quit as part of its standard crash\-recovery procedure\&.
+.SH "BUGS"
+.PP
+The
+\fB\-\-\fR
+options will not work on
+FreeBSD
+or
+OpenBSD\&. Use
+\fB\-c\fR
+instead\&. This is a bug in the affected operating systems; a future release of
+PostgreSQL
+will provide a workaround if this is not fixed\&.
+.SH "SINGLE\-USER MODE"
+.PP
+To start a single\-user mode server, use a command like
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fBpostgres \-\-single \-D /usr/local/pgsql/data \fR\fB\fIother\-options\fR\fR\fB my_database\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Provide the correct path to the database directory with
+\fB\-D\fR, or make sure that the environment variable
+\fBPGDATA\fR
+is set\&. Also specify the name of the particular database you want to work in\&.
+.PP
+Normally, the single\-user mode server treats newline as the command entry terminator; there is no intelligence about semicolons, as there is in
+psql\&. To continue a command across multiple lines, you must type backslash just before each newline except the last one\&. The backslash and adjacent newline are both dropped from the input command\&. Note that this will happen even when within a string literal or comment\&.
+.PP
+But if you use the
+\fB\-j\fR
+command line switch, a single newline does not terminate command entry; instead, the sequence semicolon\-newline\-newline does\&. That is, type a semicolon immediately followed by a completely empty line\&. Backslash\-newline is not treated specially in this mode\&. Again, there is no intelligence about such a sequence appearing within a string literal or comment\&.
+.PP
+In either input mode, if you type a semicolon that is not just before or part of a command entry terminator, it is considered a command separator\&. When you do type a command entry terminator, the multiple statements you\*(Aqve entered will be executed as a single transaction\&.
+.PP
+To quit the session, type
+EOF
+(Control+D, usually)\&. If you\*(Aqve entered any text since the last command entry terminator, then
+EOF
+will be taken as a command entry terminator, and another
+EOF
+will be needed to exit\&.
+.PP
+Note that the single\-user mode server does not provide sophisticated line\-editing features (no command history, for example)\&. Single\-user mode also does not do any background processing, such as automatic checkpoints or replication\&.
+.SH "EXAMPLES"
+.PP
+To start
+\fBpostgres\fR
+in the background using default values, type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBnohup postgres >logfile 2>&1 </dev/null &\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To start
+\fBpostgres\fR
+with a specific port, e\&.g\&., 1234:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpostgres \-p 1234\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+To connect to this server using
+psql, specify this port with the \-p option:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpsql \-p 1234\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+or set the environment variable
+\fBPGPORT\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBexport PGPORT=1234\fR
+$ \fBpsql\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Named run\-time parameters can be set in either of these styles:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpostgres \-c work_mem=1234\fR
+$ \fBpostgres \-\-work\-mem=1234\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Either form overrides whatever setting might exist for
+\fIwork_mem\fR
+in
+postgresql\&.conf\&. Notice that underscores in parameter names can be written as either underscore or dash on the command line\&. Except for short\-term experiments, it\*(Aqs probably better practice to edit the setting in
+postgresql\&.conf
+than to rely on a command\-line switch to set a parameter\&.
+.SH "SEE ALSO"
+.PP
+\fBinitdb\fR(1),
+\fBpg_ctl\fR(1)
diff --git a/doc/src/sgml/man1/postmaster.1 b/doc/src/sgml/man1/postmaster.1
new file mode 100644
index 0000000..1d8ad0d
--- /dev/null
+++ b/doc/src/sgml/man1/postmaster.1
@@ -0,0 +1,42 @@
+'\" t
+.\" Title: postmaster
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "POSTMASTER" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+postmaster \- PostgreSQL database server
+.SH "SYNOPSIS"
+.HP \w'\fBpostmaster\fR\ 'u
+\fBpostmaster\fR [\fIoption\fR...]
+.SH "DESCRIPTION"
+.PP
+\fBpostmaster\fR
+is a deprecated alias of
+\fBpostgres\fR\&.
+.SH "SEE ALSO"
+.PP
+\fBpostgres\fR(1)
diff --git a/doc/src/sgml/man1/psql.1 b/doc/src/sgml/man1/psql.1
new file mode 100644
index 0000000..2b9c0ce
--- /dev/null
+++ b/doc/src/sgml/man1/psql.1
@@ -0,0 +1,4515 @@
+'\" t
+.\" Title: psql
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PSQL" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+psql \- PostgreSQL interactive terminal
+.SH "SYNOPSIS"
+.HP \w'\fBpsql\fR\ 'u
+\fBpsql\fR [\fIoption\fR...] [\fIdbname\fR\ [\fIusername\fR]]
+.SH "DESCRIPTION"
+.PP
+psql
+is a terminal\-based front\-end to
+PostgreSQL\&. It enables you to type in queries interactively, issue them to
+PostgreSQL, and see the query results\&. Alternatively, input can be from a file or from command line arguments\&. In addition,
+psql
+provides a number of meta\-commands and various shell\-like features to facilitate writing scripts and automating a wide variety of tasks\&.
+.SH "OPTIONS"
+.PP
+\fB\-a\fR
+.br
+\fB\-\-echo\-all\fR
+.RS 4
+Print all nonempty input lines to standard output as they are read\&. (This does not apply to lines read interactively\&.) This is equivalent to setting the variable
+\fIECHO\fR
+to
+all\&.
+.RE
+.PP
+\fB\-A\fR
+.br
+\fB\-\-no\-align\fR
+.RS 4
+Switches to unaligned output mode\&. (The default output mode is
+aligned\&.) This is equivalent to
+\fB\epset format unaligned\fR\&.
+.RE
+.PP
+\fB\-b\fR
+.br
+\fB\-\-echo\-errors\fR
+.RS 4
+Print failed SQL commands to standard error output\&. This is equivalent to setting the variable
+\fIECHO\fR
+to
+errors\&.
+.RE
+.PP
+\fB\-c \fR\fB\fIcommand\fR\fR
+.br
+\fB\-\-command=\fR\fB\fIcommand\fR\fR
+.RS 4
+Specifies that
+psql
+is to execute the given command string,
+\fIcommand\fR\&. This option can be repeated and combined in any order with the
+\fB\-f\fR
+option\&. When either
+\fB\-c\fR
+or
+\fB\-f\fR
+is specified,
+psql
+does not read commands from standard input; instead it terminates after processing all the
+\fB\-c\fR
+and
+\fB\-f\fR
+options in sequence\&.
+.sp
+\fIcommand\fR
+must be either a command string that is completely parsable by the server (i\&.e\&., it contains no
+psql\-specific features), or a single backslash command\&. Thus you cannot mix
+SQL
+and
+psql
+meta\-commands within a
+\fB\-c\fR
+option\&. To achieve that, you could use repeated
+\fB\-c\fR
+options or pipe the string into
+psql, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+psql \-c \*(Aq\ex\*(Aq \-c \*(AqSELECT * FROM foo;\*(Aq
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+or
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+echo \*(Aq\ex \e\e SELECT * FROM foo;\*(Aq | psql
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(\e\e
+is the separator meta\-command\&.)
+.sp
+Each
+SQL
+command string passed to
+\fB\-c\fR
+is sent to the server as a single request\&. Because of this, the server executes it as a single transaction even if the string contains multiple
+SQL
+commands, unless there are explicit
+\fBBEGIN\fR/\fBCOMMIT\fR
+commands included in the string to divide it into multiple transactions\&. (See
+Section\ \&55.2.2.1
+for more details about how the server handles multi\-query strings\&.)
+.sp
+If having several commands executed in one transaction is not desired, use repeated
+\fB\-c\fR
+commands or feed multiple commands to
+psql\*(Aqs standard input, either using
+echo
+as illustrated above, or via a shell here\-document, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+psql <<EOF
+\ex
+SELECT * FROM foo;
+EOF
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\fB\-\-csv\fR
+.RS 4
+Switches to
+CSV
+(Comma\-Separated Values) output mode\&. This is equivalent to
+\fB\epset format csv\fR\&.
+.RE
+.PP
+\fB\-d \fR\fB\fIdbname\fR\fR
+.br
+\fB\-\-dbname=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to\&. This is equivalent to specifying
+\fIdbname\fR
+as the first non\-option argument on the command line\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\-queries\fR
+.RS 4
+Copy all SQL commands sent to the server to standard output as well\&. This is equivalent to setting the variable
+\fIECHO\fR
+to
+queries\&.
+.RE
+.PP
+\fB\-E\fR
+.br
+\fB\-\-echo\-hidden\fR
+.RS 4
+Echo the actual queries generated by
+\fB\ed\fR
+and other backslash commands\&. You can use this to study
+psql\*(Aqs internal operations\&. This is equivalent to setting the variable
+\fIECHO_HIDDEN\fR
+to
+on\&.
+.RE
+.PP
+\fB\-f \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-file=\fR\fB\fIfilename\fR\fR
+.RS 4
+Read commands from the file
+\fIfilename\fR, rather than standard input\&. This option can be repeated and combined in any order with the
+\fB\-c\fR
+option\&. When either
+\fB\-c\fR
+or
+\fB\-f\fR
+is specified,
+psql
+does not read commands from standard input; instead it terminates after processing all the
+\fB\-c\fR
+and
+\fB\-f\fR
+options in sequence\&. Except for that, this option is largely equivalent to the meta\-command
+\fB\ei\fR\&.
+.sp
+If
+\fIfilename\fR
+is
+\-
+(hyphen), then standard input is read until an EOF indication or
+\fB\eq\fR
+meta\-command\&. This can be used to intersperse interactive input with input from files\&. Note however that Readline is not used in this case (much as if
+\fB\-n\fR
+had been specified)\&.
+.sp
+Using this option is subtly different from writing
+psql < \fIfilename\fR\&. In general, both will do what you expect, but using
+\-f
+enables some nice features such as error messages with line numbers\&. There is also a slight chance that using this option will reduce the start\-up overhead\&. On the other hand, the variant using the shell\*(Aqs input redirection is (in theory) guaranteed to yield exactly the same output you would have received had you entered everything by hand\&.
+.RE
+.PP
+\fB\-F \fR\fB\fIseparator\fR\fR
+.br
+\fB\-\-field\-separator=\fR\fB\fIseparator\fR\fR
+.RS 4
+Use
+\fIseparator\fR
+as the field separator for unaligned output\&. This is equivalent to
+\fB\epset fieldsep\fR
+or
+\fB\ef\fR\&.
+.RE
+.PP
+\fB\-h \fR\fB\fIhostname\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhostname\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix\-domain socket\&.
+.RE
+.PP
+\fB\-H\fR
+.br
+\fB\-\-html\fR
+.RS 4
+Switches to
+HTML
+output mode\&. This is equivalent to
+\fB\epset format html\fR
+or the
+\fB\eH\fR
+command\&.
+.RE
+.PP
+\fB\-l\fR
+.br
+\fB\-\-list\fR
+.RS 4
+List all available databases, then exit\&. Other non\-connection options are ignored\&. This is similar to the meta\-command
+\fB\elist\fR\&.
+.sp
+When this option is used,
+psql
+will connect to the database
+postgres, unless a different database is named on the command line (option
+\fB\-d\fR
+or non\-option argument, possibly via a service entry, but not via an environment variable)\&.
+.RE
+.PP
+\fB\-L \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-log\-file=\fR\fB\fIfilename\fR\fR
+.RS 4
+Write all query output into file
+\fIfilename\fR, in addition to the normal output destination\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-no\-readline\fR
+.RS 4
+Do not use
+Readline
+for line editing and do not use the command history (see
+the section called \(lqCommand\-Line Editing\(rq
+below)\&.
+.RE
+.PP
+\fB\-o \fR\fB\fIfilename\fR\fR
+.br
+\fB\-\-output=\fR\fB\fIfilename\fR\fR
+.RS 4
+Put all query output into file
+\fIfilename\fR\&. This is equivalent to the command
+\fB\eo\fR\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or the local Unix\-domain socket file extension on which the server is listening for connections\&. Defaults to the value of the
+\fBPGPORT\fR
+environment variable or, if not set, to the port specified at compile time, usually 5432\&.
+.RE
+.PP
+\fB\-P \fR\fB\fIassignment\fR\fR
+.br
+\fB\-\-pset=\fR\fB\fIassignment\fR\fR
+.RS 4
+Specifies printing options, in the style of
+\fB\epset\fR\&. Note that here you have to separate name and value with an equal sign instead of a space\&. For example, to set the output format to
+LaTeX, you could write
+\-P format=latex\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Specifies that
+psql
+should do its work quietly\&. By default, it prints welcome messages and various informational output\&. If this option is used, none of this happens\&. This is useful with the
+\fB\-c\fR
+option\&. This is equivalent to setting the variable
+\fIQUIET\fR
+to
+on\&.
+.RE
+.PP
+\fB\-R \fR\fB\fIseparator\fR\fR
+.br
+\fB\-\-record\-separator=\fR\fB\fIseparator\fR\fR
+.RS 4
+Use
+\fIseparator\fR
+as the record separator for unaligned output\&. This is equivalent to
+\fB\epset recordsep\fR\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-single\-step\fR
+.RS 4
+Run in single\-step mode\&. That means the user is prompted before each command is sent to the server, with the option to cancel execution as well\&. Use this to debug scripts\&.
+.RE
+.PP
+\fB\-S\fR
+.br
+\fB\-\-single\-line\fR
+.RS 4
+Runs in single\-line mode where a newline terminates an SQL command, as a semicolon does\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This mode is provided for those who insist on it, but you are not necessarily encouraged to use it\&. In particular, if you mix
+SQL
+and meta\-commands on a line the order of execution might not always be clear to the inexperienced user\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-t\fR
+.br
+\fB\-\-tuples\-only\fR
+.RS 4
+Turn off printing of column names and result row count footers, etc\&. This is equivalent to
+\fB\et\fR
+or
+\fB\epset tuples_only\fR\&.
+.RE
+.PP
+\fB\-T \fR\fB\fItable_options\fR\fR
+.br
+\fB\-\-table\-attr=\fR\fB\fItable_options\fR\fR
+.RS 4
+Specifies options to be placed within the
+HTML
+table
+tag\&. See
+\fB\epset tableattr\fR
+for details\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+Connect to the database as the user
+\fIusername\fR
+instead of the default\&. (You must have permission to do so, of course\&.)
+.RE
+.PP
+\fB\-v \fR\fB\fIassignment\fR\fR
+.br
+\fB\-\-set=\fR\fB\fIassignment\fR\fR
+.br
+\fB\-\-variable=\fR\fB\fIassignment\fR\fR
+.RS 4
+Perform a variable assignment, like the
+\fB\eset\fR
+meta\-command\&. Note that you must separate name and value, if any, by an equal sign on the command line\&. To unset a variable, leave off the equal sign\&. To set a variable with an empty value, use the equal sign but leave off the value\&. These assignments are done during command line processing, so variables that reflect connection state will get overwritten later\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+psql
+version and exit\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available from other sources such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.sp
+Note that this option will remain set for the entire session, and so it affects uses of the meta\-command
+\fB\econnect\fR
+as well as the initial connection attempt\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+psql
+to prompt for a password before connecting to a database, even if the password will not be used\&.
+.sp
+If the server requires password authentication and a password is not available from other sources such as a
+\&.pgpass
+file,
+psql
+will prompt for a password in any case\&. However,
+psql
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.sp
+Note that this option will remain set for the entire session, and so it affects uses of the meta\-command
+\fB\econnect\fR
+as well as the initial connection attempt\&.
+.RE
+.PP
+\fB\-x\fR
+.br
+\fB\-\-expanded\fR
+.RS 4
+Turn on the expanded table formatting mode\&. This is equivalent to
+\fB\ex\fR
+or
+\fB\epset expanded\fR\&.
+.RE
+.PP
+\fB\-X,\fR
+.br
+\fB\-\-no\-psqlrc\fR
+.RS 4
+Do not read the start\-up file (neither the system\-wide
+psqlrc
+file nor the user\*(Aqs
+~/\&.psqlrc
+file)\&.
+.RE
+.PP
+\fB\-z\fR
+.br
+\fB\-\-field\-separator\-zero\fR
+.RS 4
+Set the field separator for unaligned output to a zero byte\&. This is equivalent to
+\fB\epset fieldsep_zero\fR\&.
+.RE
+.PP
+\fB\-0\fR
+.br
+\fB\-\-record\-separator\-zero\fR
+.RS 4
+Set the record separator for unaligned output to a zero byte\&. This is useful for interfacing, for example, with
+xargs \-0\&. This is equivalent to
+\fB\epset recordsep_zero\fR\&.
+.RE
+.PP
+\fB\-1\fR
+.br
+\fB\-\-single\-transaction\fR
+.RS 4
+This option can only be used in combination with one or more
+\fB\-c\fR
+and/or
+\fB\-f\fR
+options\&. It causes
+psql
+to issue a
+\fBBEGIN\fR
+command before the first such option and a
+\fBCOMMIT\fR
+command after the last one, thereby wrapping all the commands into a single transaction\&. If any of the commands fails and the variable
+\fION_ERROR_STOP\fR
+was set, a
+\fBROLLBACK\fR
+command is sent instead\&. This ensures that either all the commands complete successfully, or no changes are applied\&.
+.sp
+If the commands themselves contain
+\fBBEGIN\fR,
+\fBCOMMIT\fR, or
+\fBROLLBACK\fR, this option will not have the desired effects\&. Also, if an individual command cannot be executed inside a transaction block, specifying this option will cause the whole transaction to fail\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help[=\fR\fB\fItopic\fR\fR\fB]\fR
+.RS 4
+Show help about
+psql
+and exit\&. The optional
+\fItopic\fR
+parameter (defaulting to
+options) selects which part of
+psql
+is explained:
+commands
+describes
+psql\*(Aqs backslash commands;
+options
+describes the command\-line options that can be passed to
+psql; and
+variables
+shows help about
+psql
+configuration variables\&.
+.RE
+.SH "EXIT STATUS"
+.PP
+psql
+returns 0 to the shell if it finished normally, 1 if a fatal error of its own occurs (e\&.g\&., out of memory, file not found), 2 if the connection to the server went bad and the session was not interactive, and 3 if an error occurred in a script and the variable
+\fION_ERROR_STOP\fR
+was set\&.
+.SH "USAGE"
+.SS "Connecting to a Database"
+.PP
+psql
+is a regular
+PostgreSQL
+client application\&. In order to connect to a database you need to know the name of your target database, the host name and port number of the server, and what user name you want to connect as\&.
+psql
+can be told about those parameters via command line options, namely
+\fB\-d\fR,
+\fB\-h\fR,
+\fB\-p\fR, and
+\fB\-U\fR
+respectively\&. If an argument is found that does not belong to any option it will be interpreted as the database name (or the user name, if the database name is already given)\&. Not all of these options are required; there are useful defaults\&. If you omit the host name,
+psql
+will connect via a Unix\-domain socket to a server on the local host, or via TCP/IP to
+localhost
+on machines that don\*(Aqt have Unix\-domain sockets\&. The default port number is determined at compile time\&. Since the database server uses the same default, you will not have to specify the port in most cases\&. The default user name is your operating\-system user name, as is the default database name\&. Note that you cannot just connect to any database under any user name\&. Your database administrator should have informed you about your access rights\&.
+.PP
+When the defaults aren\*(Aqt quite right, you can save yourself some typing by setting the environment variables
+\fBPGDATABASE\fR,
+\fBPGHOST\fR,
+\fBPGPORT\fR
+and/or
+\fBPGUSER\fR
+to appropriate values\&. (For additional environment variables, see
+Section\ \&34.15\&.) It is also convenient to have a
+~/\&.pgpass
+file to avoid regularly having to type in passwords\&. See
+Section\ \&34.16
+for more information\&.
+.PP
+An alternative way to specify connection parameters is in a
+\fIconninfo\fR
+string or a
+URI, which is used instead of a database name\&. This mechanism give you very wide control over the connection\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpsql "service=myservice sslmode=require"\fR
+$ \fBpsql postgresql://dbmaster:5433/mydb?sslmode=require\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This way you can also use
+LDAP
+for connection parameter lookup as described in
+Section\ \&34.18\&. See
+Section\ \&34.1.2
+for more information on all the available connection options\&.
+.PP
+If the connection could not be made for any reason (e\&.g\&., insufficient privileges, server is not running on the targeted host, etc\&.),
+psql
+will return an error and terminate\&.
+.PP
+If both standard input and standard output are a terminal, then
+psql
+sets the client encoding to
+\(lqauto\(rq, which will detect the appropriate client encoding from the locale settings (\fBLC_CTYPE\fR
+environment variable on Unix systems)\&. If this doesn\*(Aqt work out as expected, the client encoding can be overridden using the environment variable
+\fBPGCLIENTENCODING\fR\&.
+.SS "Entering SQL Commands"
+.PP
+In normal operation,
+psql
+provides a prompt with the name of the database to which
+psql
+is currently connected, followed by the string
+=>\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBpsql testdb\fR
+psql (15\&.4)
+Type "help" for help\&.
+
+testdb=>
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+At the prompt, the user can type in
+SQL
+commands\&. Ordinarily, input lines are sent to the server when a command\-terminating semicolon is reached\&. An end of line does not terminate a command\&. Thus commands can be spread over several lines for clarity\&. If the command was sent and executed without error, the results of the command are displayed on the screen\&.
+.PP
+If untrusted users have access to a database that has not adopted a
+secure schema usage pattern, begin your session by removing publicly\-writable schemas from
+\fIsearch_path\fR\&. One can add
+options=\-csearch_path=
+to the connection string or issue
+SELECT pg_catalog\&.set_config(\*(Aqsearch_path\*(Aq, \*(Aq\*(Aq, false)
+before other SQL commands\&. This consideration is not specific to
+psql; it applies to every interface for executing arbitrary SQL commands\&.
+.PP
+Whenever a command is executed,
+psql
+also polls for asynchronous notification events generated by
+\fBLISTEN\fR
+and
+\fBNOTIFY\fR\&.
+.PP
+While C\-style block comments are passed to the server for processing and removal, SQL\-standard comments are removed by
+psql\&.
+.SS "Meta\-Commands"
+.PP
+Anything you enter in
+psql
+that begins with an unquoted backslash is a
+psql
+meta\-command that is processed by
+psql
+itself\&. These commands make
+psql
+more useful for administration or scripting\&. Meta\-commands are often called slash or backslash commands\&.
+.PP
+The format of a
+psql
+command is the backslash, followed immediately by a command verb, then any arguments\&. The arguments are separated from the command verb and each other by any number of whitespace characters\&.
+.PP
+To include whitespace in an argument you can quote it with single quotes\&. To include a single quote in an argument, write two single quotes within single\-quoted text\&. Anything contained in single quotes is furthermore subject to C\-like substitutions for
+\en
+(new line),
+\et
+(tab),
+\eb
+(backspace),
+\er
+(carriage return),
+\ef
+(form feed),
+\e\fIdigits\fR
+(octal), and
+\ex\fIdigits\fR
+(hexadecimal)\&. A backslash preceding any other character within single\-quoted text quotes that single character, whatever it is\&.
+.PP
+If an unquoted colon (:) followed by a
+psql
+variable name appears within an argument, it is replaced by the variable\*(Aqs value, as described in
+SQL Interpolation
+below\&. The forms
+:\*(Aq\fIvariable_name\fR\*(Aq
+and
+:"\fIvariable_name\fR"
+described there work as well\&. The
+:{?\fIvariable_name\fR}
+syntax allows testing whether a variable is defined\&. It is substituted by TRUE or FALSE\&. Escaping the colon with a backslash protects it from substitution\&.
+.PP
+Within an argument, text that is enclosed in backquotes (`) is taken as a command line that is passed to the shell\&. The output of the command (with any trailing newline removed) replaces the backquoted text\&. Within the text enclosed in backquotes, no special quoting or other processing occurs, except that appearances of
+:\fIvariable_name\fR
+where
+\fIvariable_name\fR
+is a
+psql
+variable name are replaced by the variable\*(Aqs value\&. Also, appearances of
+:\*(Aq\fIvariable_name\fR\*(Aq
+are replaced by the variable\*(Aqs value suitably quoted to become a single shell command argument\&. (The latter form is almost always preferable, unless you are very sure of what is in the variable\&.) Because carriage return and line feed characters cannot be safely quoted on all platforms, the
+:\*(Aq\fIvariable_name\fR\*(Aq
+form prints an error message and does not substitute the variable value when such characters appear in the value\&.
+.PP
+Some commands take an
+SQL
+identifier (such as a table name) as argument\&. These arguments follow the syntax rules of
+SQL: Unquoted letters are forced to lowercase, while double quotes (") protect letters from case conversion and allow incorporation of whitespace into the identifier\&. Within double quotes, paired double quotes reduce to a single double quote in the resulting name\&. For example,
+FOO"BAR"BAZ
+is interpreted as
+fooBARbaz, and
+"A weird"" name"
+becomes
+A weird" name\&.
+.PP
+Parsing for arguments stops at the end of the line, or when another unquoted backslash is found\&. An unquoted backslash is taken as the beginning of a new meta\-command\&. The special sequence
+\e\e
+(two backslashes) marks the end of arguments and continues parsing
+SQL
+commands, if any\&. That way
+SQL
+and
+psql
+commands can be freely mixed on a line\&. But in any case, the arguments of a meta\-command cannot continue beyond the end of the line\&.
+.PP
+Many of the meta\-commands act on the
+current query buffer\&. This is simply a buffer holding whatever SQL command text has been typed but not yet sent to the server for execution\&. This will include previous input lines as well as any text appearing before the meta\-command on the same line\&.
+.PP
+The following meta\-commands are defined:
+.PP
+\ea
+.RS 4
+If the current table output format is unaligned, it is switched to aligned\&. If it is not unaligned, it is set to unaligned\&. This command is kept for backwards compatibility\&. See
+\fB\epset\fR
+for a more general solution\&.
+.RE
+.PP
+\ec or \econnect [ \-reuse\-previous=\fIon|off\fR ] [ \fIdbname\fR [ \fIusername\fR ] [ \fIhost\fR ] [ \fIport\fR ] | \fIconninfo\fR ]
+.RS 4
+Establishes a new connection to a
+PostgreSQL
+server\&. The connection parameters to use can be specified either using a positional syntax (one or more of database name, user, host, and port), or using a
+\fIconninfo\fR
+connection string as detailed in
+Section\ \&34.1.1\&. If no arguments are given, a new connection is made using the same parameters as before\&.
+.sp
+Specifying any of
+\fIdbname\fR,
+\fIusername\fR,
+\fIhost\fR
+or
+\fIport\fR
+as
+\-
+is equivalent to omitting that parameter\&.
+.sp
+The new connection can re\-use connection parameters from the previous connection; not only database name, user, host, and port, but other settings such as
+\fIsslmode\fR\&. By default, parameters are re\-used in the positional syntax, but not when a
+\fIconninfo\fR
+string is given\&. Passing a first argument of
+\-reuse\-previous=on
+or
+\-reuse\-previous=off
+overrides that default\&. If parameters are re\-used, then any parameter not explicitly specified as a positional parameter or in the
+\fIconninfo\fR
+string is taken from the existing connection\*(Aqs parameters\&. An exception is that if the
+\fIhost\fR
+setting is changed from its previous value using the positional syntax, any
+\fIhostaddr\fR
+setting present in the existing connection\*(Aqs parameters is dropped\&. Also, any password used for the existing connection will be re\-used only if the user, host, and port settings are not changed\&. When the command neither specifies nor reuses a particular parameter, the
+libpq
+default is used\&.
+.sp
+If the new connection is successfully made, the previous connection is closed\&. If the connection attempt fails (wrong user name, access denied, etc\&.), the previous connection will be kept if
+psql
+is in interactive mode\&. But when executing a non\-interactive script, the old connection is closed and an error is reported\&. That may or may not terminate the script; if it does not, all database\-accessing commands will fail until another
+\econnect
+command is successfully executed\&. This distinction was chosen as a user convenience against typos on the one hand, and a safety mechanism that scripts are not accidentally acting on the wrong database on the other hand\&. Note that whenever a
+\econnect
+command attempts to re\-use parameters, the values re\-used are those of the last successful connection, not of any failed attempts made subsequently\&. However, in the case of a non\-interactive
+\econnect
+failure, no parameters are allowed to be re\-used later, since the script would likely be expecting the values from the failed
+\econnect
+to be re\-used\&.
+.sp
+Examples:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+=> \ec mydb myuser host\&.dom 6432
+=> \ec service=foo
+=> \ec "host=localhost port=5432 dbname=mydb connect_timeout=10 sslmode=disable"
+=> \ec \-reuse\-previous=on sslmode=require \-\- changes only sslmode
+=> \ec postgresql://tom@localhost/mydb?application_name=myapp
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\eC [ \fItitle\fR ]
+.RS 4
+Sets the title of any tables being printed as the result of a query or unset any such title\&. This command is equivalent to
+\epset title \fItitle\fR\&. (The name of this command derives from
+\(lqcaption\(rq, as it was previously only used to set the caption in an
+HTML
+table\&.)
+.RE
+.PP
+\ecd [ \fIdirectory\fR ]
+.RS 4
+Changes the current working directory to
+\fIdirectory\fR\&. Without argument, changes to the current user\*(Aqs home directory\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+To print your current working directory, use
+\e! pwd\&.
+.sp .5v
+.RE
+.RE
+.PP
+\econninfo
+.RS 4
+Outputs information about the current database connection\&.
+.RE
+.PP
+\ecopy { \fItable\fR [ ( \fIcolumn_list\fR ) ] } from { \fI\*(Aqfilename\*(Aq\fR | program \fI\*(Aqcommand\*(Aq\fR | stdin | pstdin } [ [ with ] ( \fIoption\fR [, \&.\&.\&.] ) ] [ where \fIcondition\fR ]
+.br
+\ecopy { \fItable\fR [ ( \fIcolumn_list\fR ) ] | ( \fIquery\fR ) } to { \fI\*(Aqfilename\*(Aq\fR | program \fI\*(Aqcommand\*(Aq\fR | stdout | pstdout } [ [ with ] ( \fIoption\fR [, \&.\&.\&.] ) ]
+.RS 4
+Performs a frontend (client) copy\&. This is an operation that runs an
+SQL
+\fBCOPY\fR
+command, but instead of the server reading or writing the specified file,
+psql
+reads or writes the file and routes the data between the server and the local file system\&. This means that file accessibility and privileges are those of the local user, not the server, and no SQL superuser privileges are required\&.
+.sp
+When
+program
+is specified,
+\fIcommand\fR
+is executed by
+psql
+and the data passed from or to
+\fIcommand\fR
+is routed between the server and the client\&. Again, the execution privileges are those of the local user, not the server, and no SQL superuser privileges are required\&.
+.sp
+For
+\ecopy \&.\&.\&. from stdin, data rows are read from the same source that issued the command, continuing until
+\e\&.
+is read or the stream reaches
+EOF\&. This option is useful for populating tables in\-line within an SQL script file\&. For
+\ecopy \&.\&.\&. to stdout, output is sent to the same place as
+psql
+command output, and the
+COPY \fIcount\fR
+command status is not printed (since it might be confused with a data row)\&. To read/write
+psql\*(Aqs standard input or output regardless of the current command source or
+\eo
+option, write
+from pstdin
+or
+to pstdout\&.
+.sp
+The syntax of this command is similar to that of the
+SQL
+\fBCOPY\fR
+command\&. All options other than the data source/destination are as specified for
+\fBCOPY\fR\&. Because of this, special parsing rules apply to the
+\fB\ecopy\fR
+meta\-command\&. Unlike most other meta\-commands, the entire remainder of the line is always taken to be the arguments of
+\fB\ecopy\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+Another way to obtain the same result as
+\ecopy \&.\&.\&. to
+is to use the
+SQL
+COPY \&.\&.\&. TO STDOUT
+command and terminate it with
+\eg \fIfilename\fR
+or
+\eg |\fIprogram\fR\&. Unlike
+\ecopy, this method allows the command to span multiple lines; also, variable interpolation and backquote expansion can be used\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+These operations are not as efficient as the
+SQL
+\fBCOPY\fR
+command with a file or program data source or destination, because all data must pass through the client/server connection\&. For large amounts of data the
+SQL
+command might be preferable\&.
+.sp .5v
+.RE
+.RE
+.PP
+\ecopyright
+.RS 4
+Shows the copyright and distribution terms of
+PostgreSQL\&.
+.RE
+.PP
+\ecrosstabview [ \fIcolV\fR [ \fIcolH\fR [ \fIcolD\fR [ \fIsortcolH\fR ] ] ] ]
+.RS 4
+Executes the current query buffer (like
+\eg) and shows the results in a crosstab grid\&. The query must return at least three columns\&. The output column identified by
+\fIcolV\fR
+becomes a vertical header and the output column identified by
+\fIcolH\fR
+becomes a horizontal header\&.
+\fIcolD\fR
+identifies the output column to display within the grid\&.
+\fIsortcolH\fR
+identifies an optional sort column for the horizontal header\&.
+.sp
+Each column specification can be a column number (starting at 1) or a column name\&. The usual SQL case folding and quoting rules apply to column names\&. If omitted,
+\fIcolV\fR
+is taken as column 1 and
+\fIcolH\fR
+as column 2\&.
+\fIcolH\fR
+must differ from
+\fIcolV\fR\&. If
+\fIcolD\fR
+is not specified, then there must be exactly three columns in the query result, and the column that is neither
+\fIcolV\fR
+nor
+\fIcolH\fR
+is taken to be
+\fIcolD\fR\&.
+.sp
+The vertical header, displayed as the leftmost column, contains the values found in column
+\fIcolV\fR, in the same order as in the query results, but with duplicates removed\&.
+.sp
+The horizontal header, displayed as the first row, contains the values found in column
+\fIcolH\fR, with duplicates removed\&. By default, these appear in the same order as in the query results\&. But if the optional
+\fIsortcolH\fR
+argument is given, it identifies a column whose values must be integer numbers, and the values from
+\fIcolH\fR
+will appear in the horizontal header sorted according to the corresponding
+\fIsortcolH\fR
+values\&.
+.sp
+Inside the crosstab grid, for each distinct value
+x
+of
+\fIcolH\fR
+and each distinct value
+y
+of
+\fIcolV\fR, the cell located at the intersection
+(x,y)
+contains the value of the
+colD
+column in the query result row for which the value of
+\fIcolH\fR
+is
+x
+and the value of
+\fIcolV\fR
+is
+y\&. If there is no such row, the cell is empty\&. If there are multiple such rows, an error is reported\&.
+.RE
+.PP
+\ed[S+] [ \fIpattern\fR ]
+.RS 4
+For each relation (table, view, materialized view, index, sequence, or foreign table) or composite type matching the
+\fIpattern\fR, show all columns, their types, the tablespace (if not the default) and any special attributes such as
+NOT NULL
+or defaults\&. Associated indexes, constraints, rules, and triggers are also shown\&. For foreign tables, the associated foreign server is shown as well\&. (\(lqMatching the pattern\(rq
+is defined in
+Patterns
+below\&.)
+.sp
+For some types of relation,
+\ed
+shows additional information for each column: column values for sequences, indexed expressions for indexes, and foreign data wrapper options for foreign tables\&.
+.sp
+The command form
+\ed+
+is identical, except that more information is displayed: any comments associated with the columns of the table are shown, as is the presence of OIDs in the table, the view definition if the relation is a view, a non\-default
+replica identity
+setting and the
+access method
+name if the relation has an access method\&.
+.sp
+By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+If
+\fB\ed\fR
+is used without a
+\fIpattern\fR
+argument, it is equivalent to
+\fB\edtvmsE\fR
+which will show a list of all visible tables, views, materialized views, sequences and foreign tables\&. This is purely a convenience measure\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eda[S] [ \fIpattern\fR ]
+.RS 4
+Lists aggregate functions, together with their return type and the data types they operate on\&. If
+\fIpattern\fR
+is specified, only aggregates whose names match the pattern are shown\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&.
+.RE
+.PP
+\edA[+] [ \fIpattern\fR ]
+.RS 4
+Lists access methods\&. If
+\fIpattern\fR
+is specified, only access methods whose names match the pattern are shown\&. If
++
+is appended to the command name, each access method is listed with its associated handler function and description\&.
+.RE
+.PP
+\edAc[+] [\fIaccess\-method\-pattern\fR [\fIinput\-type\-pattern\fR]]
+.RS 4
+Lists operator classes (see
+Section\ \&38.16.1)\&. If
+\fIaccess\-method\-pattern\fR
+is specified, only operator classes associated with access methods whose names match that pattern are listed\&. If
+\fIinput\-type\-pattern\fR
+is specified, only operator classes associated with input types whose names match that pattern are listed\&. If
++
+is appended to the command name, each operator class is listed with its associated operator family and owner\&.
+.RE
+.PP
+\edAf[+] [\fIaccess\-method\-pattern\fR [\fIinput\-type\-pattern\fR]]
+.RS 4
+Lists operator families (see
+Section\ \&38.16.5)\&. If
+\fIaccess\-method\-pattern\fR
+is specified, only operator families associated with access methods whose names match that pattern are listed\&. If
+\fIinput\-type\-pattern\fR
+is specified, only operator families associated with input types whose names match that pattern are listed\&. If
++
+is appended to the command name, each operator family is listed with its owner\&.
+.RE
+.PP
+\edAo[+] [\fIaccess\-method\-pattern\fR [\fIoperator\-family\-pattern\fR]]
+.RS 4
+Lists operators associated with operator families (see
+Section\ \&38.16.2)\&. If
+\fIaccess\-method\-pattern\fR
+is specified, only members of operator families associated with access methods whose names match that pattern are listed\&. If
+\fIoperator\-family\-pattern\fR
+is specified, only members of operator families whose names match that pattern are listed\&. If
++
+is appended to the command name, each operator is listed with its sort operator family (if it is an ordering operator)\&.
+.RE
+.PP
+\edAp[+] [\fIaccess\-method\-pattern\fR [\fIoperator\-family\-pattern\fR]]
+.RS 4
+Lists support functions associated with operator families (see
+Section\ \&38.16.3)\&. If
+\fIaccess\-method\-pattern\fR
+is specified, only functions of operator families associated with access methods whose names match that pattern are listed\&. If
+\fIoperator\-family\-pattern\fR
+is specified, only functions of operator families whose names match that pattern are listed\&. If
++
+is appended to the command name, functions are displayed verbosely, with their actual parameter lists\&.
+.RE
+.PP
+\edb[+] [ \fIpattern\fR ]
+.RS 4
+Lists tablespaces\&. If
+\fIpattern\fR
+is specified, only tablespaces whose names match the pattern are shown\&. If
++
+is appended to the command name, each tablespace is listed with its associated options, on\-disk size, permissions and description\&.
+.RE
+.PP
+\edc[S+] [ \fIpattern\fR ]
+.RS 4
+Lists conversions between character\-set encodings\&. If
+\fIpattern\fR
+is specified, only conversions whose names match the pattern are listed\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&. If
++
+is appended to the command name, each object is listed with its associated description\&.
+.RE
+.PP
+\edconfig[+] [ \fIpattern\fR ]
+.RS 4
+Lists server configuration parameters and their values\&. If
+\fIpattern\fR
+is specified, only parameters whose names match the pattern are listed\&. Without a
+\fIpattern\fR, only parameters that are set to non\-default values are listed\&. (Use
+\edconfig *
+to see all parameters\&.) If
++
+is appended to the command name, each parameter is listed with its data type, context in which the parameter can be set, and access privileges (if non\-default access privileges have been granted)\&.
+.RE
+.PP
+\edC[+] [ \fIpattern\fR ]
+.RS 4
+Lists type casts\&. If
+\fIpattern\fR
+is specified, only casts whose source or target types match the pattern are listed\&. If
++
+is appended to the command name, each object is listed with its associated description\&.
+.RE
+.PP
+\edd[S] [ \fIpattern\fR ]
+.RS 4
+Shows the descriptions of objects of type
+constraint,
+operator class,
+operator family,
+rule, and
+trigger\&. All other comments may be viewed by the respective backslash commands for those object types\&.
+.sp
+\edd
+displays descriptions for objects matching the
+\fIpattern\fR, or of visible objects of the appropriate type if no argument is given\&. But in either case, only objects that have a description are listed\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&.
+.sp
+Descriptions for objects can be created with the
+\fBCOMMENT\fR
+SQL
+command\&.
+.RE
+.PP
+\edD[S+] [ \fIpattern\fR ]
+.RS 4
+Lists domains\&. If
+\fIpattern\fR
+is specified, only domains whose names match the pattern are shown\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&. If
++
+is appended to the command name, each object is listed with its associated permissions and description\&.
+.RE
+.PP
+\eddp [ \fIpattern\fR ]
+.RS 4
+Lists default access privilege settings\&. An entry is shown for each role (and schema, if applicable) for which the default privilege settings have been changed from the built\-in defaults\&. If
+\fIpattern\fR
+is specified, only entries whose role name or schema name matches the pattern are listed\&.
+.sp
+The
+\fBALTER DEFAULT PRIVILEGES\fR
+command is used to set default access privileges\&. The meaning of the privilege display is explained in
+Section\ \&5.7\&.
+.RE
+.PP
+\edE[S+] [ \fIpattern\fR ]
+.br
+\edi[S+] [ \fIpattern\fR ]
+.br
+\edm[S+] [ \fIpattern\fR ]
+.br
+\eds[S+] [ \fIpattern\fR ]
+.br
+\edt[S+] [ \fIpattern\fR ]
+.br
+\edv[S+] [ \fIpattern\fR ]
+.RS 4
+In this group of commands, the letters
+E,
+i,
+m,
+s,
+t, and
+v
+stand for foreign table, index, materialized view, sequence, table, and view, respectively\&. You can specify any or all of these letters, in any order, to obtain a listing of objects of these types\&. For example,
+\edti
+lists tables and indexes\&. If
++
+is appended to the command name, each object is listed with its persistence status (permanent, temporary, or unlogged), physical size on disk, and associated description if any\&. If
+\fIpattern\fR
+is specified, only objects whose names match the pattern are listed\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&.
+.RE
+.PP
+\edes[+] [ \fIpattern\fR ]
+.RS 4
+Lists foreign servers (mnemonic:
+\(lqexternal servers\(rq)\&. If
+\fIpattern\fR
+is specified, only those servers whose name matches the pattern are listed\&. If the form
+\edes+
+is used, a full description of each server is shown, including the server\*(Aqs access privileges, type, version, options, and description\&.
+.RE
+.PP
+\edet[+] [ \fIpattern\fR ]
+.RS 4
+Lists foreign tables (mnemonic:
+\(lqexternal tables\(rq)\&. If
+\fIpattern\fR
+is specified, only entries whose table name or schema name matches the pattern are listed\&. If the form
+\edet+
+is used, generic options and the foreign table description are also displayed\&.
+.RE
+.PP
+\edeu[+] [ \fIpattern\fR ]
+.RS 4
+Lists user mappings (mnemonic:
+\(lqexternal users\(rq)\&. If
+\fIpattern\fR
+is specified, only those mappings whose user names match the pattern are listed\&. If the form
+\edeu+
+is used, additional information about each mapping is shown\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+\edeu+
+might also display the user name and password of the remote user, so care should be taken not to disclose them\&.
+.sp .5v
+.RE
+.RE
+.PP
+\edew[+] [ \fIpattern\fR ]
+.RS 4
+Lists foreign\-data wrappers (mnemonic:
+\(lqexternal wrappers\(rq)\&. If
+\fIpattern\fR
+is specified, only those foreign\-data wrappers whose name matches the pattern are listed\&. If the form
+\edew+
+is used, the access privileges, options, and description of the foreign\-data wrapper are also shown\&.
+.RE
+.PP
+\edf[anptwS+] [ \fIpattern\fR [ \fIarg_pattern\fR \&.\&.\&. ] ]
+.RS 4
+Lists functions, together with their result data types, argument data types, and function types, which are classified as
+\(lqagg\(rq
+(aggregate),
+\(lqnormal\(rq,
+\(lqprocedure\(rq,
+\(lqtrigger\(rq, or
+\(lqwindow\(rq\&. To display only functions of specific type(s), add the corresponding letters
+a,
+n,
+p,
+t, or
+w
+to the command\&. If
+\fIpattern\fR
+is specified, only functions whose names match the pattern are shown\&. Any additional arguments are type\-name patterns, which are matched to the type names of the first, second, and so on arguments of the function\&. (Matching functions can have more arguments than what you specify\&. To prevent that, write a dash
+\-
+as the last
+\fIarg_pattern\fR\&.) By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&. If the form
+\edf+
+is used, additional information about each function is shown, including volatility, parallel safety, owner, security classification, access privileges, language, source code and description\&.
+.RE
+.PP
+\edF[+] [ \fIpattern\fR ]
+.RS 4
+Lists text search configurations\&. If
+\fIpattern\fR
+is specified, only configurations whose names match the pattern are shown\&. If the form
+\edF+
+is used, a full description of each configuration is shown, including the underlying text search parser and the dictionary list for each parser token type\&.
+.RE
+.PP
+\edFd[+] [ \fIpattern\fR ]
+.RS 4
+Lists text search dictionaries\&. If
+\fIpattern\fR
+is specified, only dictionaries whose names match the pattern are shown\&. If the form
+\edFd+
+is used, additional information is shown about each selected dictionary, including the underlying text search template and the option values\&.
+.RE
+.PP
+\edFp[+] [ \fIpattern\fR ]
+.RS 4
+Lists text search parsers\&. If
+\fIpattern\fR
+is specified, only parsers whose names match the pattern are shown\&. If the form
+\edFp+
+is used, a full description of each parser is shown, including the underlying functions and the list of recognized token types\&.
+.RE
+.PP
+\edFt[+] [ \fIpattern\fR ]
+.RS 4
+Lists text search templates\&. If
+\fIpattern\fR
+is specified, only templates whose names match the pattern are shown\&. If the form
+\edFt+
+is used, additional information is shown about each template, including the underlying function names\&.
+.RE
+.PP
+\edg[S+] [ \fIpattern\fR ]
+.RS 4
+Lists database roles\&. (Since the concepts of
+\(lqusers\(rq
+and
+\(lqgroups\(rq
+have been unified into
+\(lqroles\(rq, this command is now equivalent to
+\edu\&.) By default, only user\-created roles are shown; supply the
+S
+modifier to include system roles\&. If
+\fIpattern\fR
+is specified, only those roles whose names match the pattern are listed\&. If the form
+\edg+
+is used, additional information is shown about each role; currently this adds the comment for each role\&.
+.RE
+.PP
+\edl[+]
+.RS 4
+This is an alias for
+\fB\elo_list\fR, which shows a list of large objects\&. If
++
+is appended to the command name, each large object is listed with its associated permissions, if any\&.
+.RE
+.PP
+\edL[S+] [ \fIpattern\fR ]
+.RS 4
+Lists procedural languages\&. If
+\fIpattern\fR
+is specified, only languages whose names match the pattern are listed\&. By default, only user\-created languages are shown; supply the
+S
+modifier to include system objects\&. If
++
+is appended to the command name, each language is listed with its call handler, validator, access privileges, and whether it is a system object\&.
+.RE
+.PP
+\edn[S+] [ \fIpattern\fR ]
+.RS 4
+Lists schemas (namespaces)\&. If
+\fIpattern\fR
+is specified, only schemas whose names match the pattern are listed\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&. If
++
+is appended to the command name, each object is listed with its associated permissions and description, if any\&.
+.RE
+.PP
+\edo[S+] [ \fIpattern\fR [ \fIarg_pattern\fR [ \fIarg_pattern\fR ] ] ]
+.RS 4
+Lists operators with their operand and result types\&. If
+\fIpattern\fR
+is specified, only operators whose names match the pattern are listed\&. If one
+\fIarg_pattern\fR
+is specified, only prefix operators whose right argument\*(Aqs type name matches that pattern are listed\&. If two
+\fIarg_pattern\fRs are specified, only binary operators whose argument type names match those patterns are listed\&. (Alternatively, write
+\-
+for the unused argument of a unary operator\&.) By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&. If
++
+is appended to the command name, additional information about each operator is shown, currently just the name of the underlying function\&.
+.RE
+.PP
+\edO[S+] [ \fIpattern\fR ]
+.RS 4
+Lists collations\&. If
+\fIpattern\fR
+is specified, only collations whose names match the pattern are listed\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&. If
++
+is appended to the command name, each collation is listed with its associated description, if any\&. Note that only collations usable with the current database\*(Aqs encoding are shown, so the results may vary in different databases of the same installation\&.
+.RE
+.PP
+\edp [ \fIpattern\fR ]
+.RS 4
+Lists tables, views and sequences with their associated access privileges\&. If
+\fIpattern\fR
+is specified, only tables, views and sequences whose names match the pattern are listed\&.
+.sp
+The
+\fBGRANT\fR
+and
+\fBREVOKE\fR
+commands are used to set access privileges\&. The meaning of the privilege display is explained in
+Section\ \&5.7\&.
+.RE
+.PP
+\edP[itn+] [ \fIpattern\fR ]
+.RS 4
+Lists partitioned relations\&. If
+\fIpattern\fR
+is specified, only entries whose name matches the pattern are listed\&. The modifiers
+t
+(tables) and
+i
+(indexes) can be appended to the command, filtering the kind of relations to list\&. By default, partitioned tables and indexes are listed\&.
+.sp
+If the modifier
+n
+(\(lqnested\(rq) is used, or a pattern is specified, then non\-root partitioned relations are included, and a column is shown displaying the parent of each partitioned relation\&.
+.sp
+If
++
+is appended to the command name, the sum of the sizes of each relation\*(Aqs partitions is also displayed, along with the relation\*(Aqs description\&. If
+n
+is combined with
++, two sizes are shown: one including the total size of directly\-attached leaf partitions, and another showing the total size of all partitions, including indirectly attached sub\-partitions\&.
+.RE
+.PP
+\edrds [ \fIrole\-pattern\fR [ \fIdatabase\-pattern\fR ] ]
+.RS 4
+Lists defined configuration settings\&. These settings can be role\-specific, database\-specific, or both\&.
+\fIrole\-pattern\fR
+and
+\fIdatabase\-pattern\fR
+are used to select specific roles and databases to list, respectively\&. If omitted, or if
+*
+is specified, all settings are listed, including those not role\-specific or database\-specific, respectively\&.
+.sp
+The
+\fBALTER ROLE\fR
+and
+\fBALTER DATABASE\fR
+commands are used to define per\-role and per\-database configuration settings\&.
+.RE
+.PP
+\edRp[+] [ \fIpattern\fR ]
+.RS 4
+Lists replication publications\&. If
+\fIpattern\fR
+is specified, only those publications whose names match the pattern are listed\&. If
++
+is appended to the command name, the tables and schemas associated with each publication are shown as well\&.
+.RE
+.PP
+\edRs[+] [ \fIpattern\fR ]
+.RS 4
+Lists replication subscriptions\&. If
+\fIpattern\fR
+is specified, only those subscriptions whose names match the pattern are listed\&. If
++
+is appended to the command name, additional properties of the subscriptions are shown\&.
+.RE
+.PP
+\edT[S+] [ \fIpattern\fR ]
+.RS 4
+Lists data types\&. If
+\fIpattern\fR
+is specified, only types whose names match the pattern are listed\&. If
++
+is appended to the command name, each type is listed with its internal name and size, its allowed values if it is an
+enum
+type, and its associated permissions\&. By default, only user\-created objects are shown; supply a pattern or the
+S
+modifier to include system objects\&.
+.RE
+.PP
+\edu[S+] [ \fIpattern\fR ]
+.RS 4
+Lists database roles\&. (Since the concepts of
+\(lqusers\(rq
+and
+\(lqgroups\(rq
+have been unified into
+\(lqroles\(rq, this command is now equivalent to
+\edg\&.) By default, only user\-created roles are shown; supply the
+S
+modifier to include system roles\&. If
+\fIpattern\fR
+is specified, only those roles whose names match the pattern are listed\&. If the form
+\edu+
+is used, additional information is shown about each role; currently this adds the comment for each role\&.
+.RE
+.PP
+\edx[+] [ \fIpattern\fR ]
+.RS 4
+Lists installed extensions\&. If
+\fIpattern\fR
+is specified, only those extensions whose names match the pattern are listed\&. If the form
+\edx+
+is used, all the objects belonging to each matching extension are listed\&.
+.RE
+.PP
+\edX [ \fIpattern\fR ]
+.RS 4
+Lists extended statistics\&. If
+\fIpattern\fR
+is specified, only those extended statistics whose names match the pattern are listed\&.
+.sp
+The status of each kind of extended statistics is shown in a column named after its statistic kind (e\&.g\&. Ndistinct)\&.
+defined
+means that it was requested when creating the statistics, and NULL means it wasn\*(Aqt requested\&. You can use
+pg_stats_ext
+if you\*(Aqd like to know whether
+\fBANALYZE\fR
+was run and statistics are available to the planner\&.
+.RE
+.PP
+\edy[+] [ \fIpattern\fR ]
+.RS 4
+Lists event triggers\&. If
+\fIpattern\fR
+is specified, only those event triggers whose names match the pattern are listed\&. If
++
+is appended to the command name, each object is listed with its associated description\&.
+.RE
+.PP
+\ee or \eedit [ \fIfilename\fR ] [ \fIline_number\fR ]
+.RS 4
+If
+\fIfilename\fR
+is specified, the file is edited; after the editor exits, the file\*(Aqs content is copied into the current query buffer\&. If no
+\fIfilename\fR
+is given, the current query buffer is copied to a temporary file which is then edited in the same fashion\&. Or, if the current query buffer is empty, the most recently executed query is copied to a temporary file and edited in the same fashion\&.
+.sp
+If you edit a file or the previous query, and you quit the editor without modifying the file, the query buffer is cleared\&. Otherwise, the new contents of the query buffer are re\-parsed according to the normal rules of
+psql, treating the whole buffer as a single line\&. Any complete queries are immediately executed; that is, if the query buffer contains or ends with a semicolon, everything up to that point is executed and removed from the query buffer\&. Whatever remains in the query buffer is redisplayed\&. Type semicolon or
+\eg
+to send it, or
+\er
+to cancel it by clearing the query buffer\&.
+.sp
+Treating the buffer as a single line primarily affects meta\-commands: whatever is in the buffer after a meta\-command will be taken as argument(s) to the meta\-command, even if it spans multiple lines\&. (Thus you cannot make meta\-command\-using scripts this way\&. Use
+\fB\ei\fR
+for that\&.)
+.sp
+If a line number is specified,
+psql
+will position the cursor on the specified line of the file or query buffer\&. Note that if a single all\-digits argument is given,
+psql
+assumes it is a line number, not a file name\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+See
+Environment, below, for how to configure and customize your editor\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eecho \fItext\fR [ \&.\&.\&. ]
+.RS 4
+Prints the evaluated arguments to standard output, separated by spaces and followed by a newline\&. This can be useful to intersperse information in the output of scripts\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+=> \fB\eecho `date`\fR
+Tue Oct 26 21:40:57 CEST 1999
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If the first argument is an unquoted
+\-n
+the trailing newline is not written (nor is the first argument)\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+If you use the
+\fB\eo\fR
+command to redirect your query output you might wish to use
+\fB\eqecho\fR
+instead of this command\&. See also
+\fB\ewarn\fR\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eef [ \fIfunction_description\fR [ \fIline_number\fR ] ]
+.RS 4
+This command fetches and edits the definition of the named function or procedure, in the form of a
+\fBCREATE OR REPLACE FUNCTION\fR
+or
+\fBCREATE OR REPLACE PROCEDURE\fR
+command\&. Editing is done in the same way as for
+\eedit\&. If you quit the editor without saving, the statement is discarded\&. If you save and exit the editor, the updated command is executed immediately if you added a semicolon to it\&. Otherwise it is redisplayed; type semicolon or
+\eg
+to send it, or
+\er
+to cancel\&.
+.sp
+The target function can be specified by name alone, or by name and arguments, for example
+foo(integer, text)\&. The argument types must be given if there is more than one function of the same name\&.
+.sp
+If no function is specified, a blank
+\fBCREATE FUNCTION\fR
+template is presented for editing\&.
+.sp
+If a line number is specified,
+psql
+will position the cursor on the specified line of the function body\&. (Note that the function body typically does not begin on the first line of the file\&.)
+.sp
+Unlike most other meta\-commands, the entire remainder of the line is always taken to be the argument(s) of
+\fB\eef\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+See
+Environment, below, for how to configure and customize your editor\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eencoding [ \fIencoding\fR ]
+.RS 4
+Sets the client character set encoding\&. Without an argument, this command shows the current encoding\&.
+.RE
+.PP
+\eerrverbose
+.RS 4
+Repeats the most recent server error message at maximum verbosity, as though
+\fIVERBOSITY\fR
+were set to
+verbose
+and
+\fISHOW_CONTEXT\fR
+were set to
+always\&.
+.RE
+.PP
+\eev [ \fIview_name\fR [ \fIline_number\fR ] ]
+.RS 4
+This command fetches and edits the definition of the named view, in the form of a
+\fBCREATE OR REPLACE VIEW\fR
+command\&. Editing is done in the same way as for
+\eedit\&. If you quit the editor without saving, the statement is discarded\&. If you save and exit the editor, the updated command is executed immediately if you added a semicolon to it\&. Otherwise it is redisplayed; type semicolon or
+\eg
+to send it, or
+\er
+to cancel\&.
+.sp
+If no view is specified, a blank
+\fBCREATE VIEW\fR
+template is presented for editing\&.
+.sp
+If a line number is specified,
+psql
+will position the cursor on the specified line of the view definition\&.
+.sp
+Unlike most other meta\-commands, the entire remainder of the line is always taken to be the argument(s) of
+\fB\eev\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&.
+.RE
+.PP
+\ef [ \fIstring\fR ]
+.RS 4
+Sets the field separator for unaligned query output\&. The default is the vertical bar (|)\&. It is equivalent to
+\fB\epset fieldsep\fR\&.
+.RE
+.PP
+\eg [ (\fIoption\fR=\fIvalue\fR [\&.\&.\&.]) ] [ \fIfilename\fR ]
+.br
+\eg [ (\fIoption\fR=\fIvalue\fR [\&.\&.\&.]) ] [ |\fIcommand\fR ]
+.RS 4
+Sends the current query buffer to the server for execution\&.
+.sp
+If parentheses appear after
+\eg, they surround a space\-separated list of
+\fIoption\fR=\fIvalue\fR
+formatting\-option clauses, which are interpreted in the same way as
+\epset
+\fIoption\fR
+\fIvalue\fR
+commands, but take effect only for the duration of this query\&. In this list, spaces are not allowed around
+=
+signs, but are required between option clauses\&. If
+=\fIvalue\fR
+is omitted, the named
+\fIoption\fR
+is changed in the same way as for
+\epset
+\fIoption\fR
+with no explicit
+\fIvalue\fR\&.
+.sp
+If a
+\fIfilename\fR
+or
+|\fIcommand\fR
+argument is given, the query\*(Aqs output is written to the named file or piped to the given shell command, instead of displaying it as usual\&. The file or command is written to only if the query successfully returns zero or more tuples, not if the query fails or is a non\-data\-returning SQL command\&.
+.sp
+If the current query buffer is empty, the most recently sent query is re\-executed instead\&. Except for that behavior,
+\eg
+without any arguments is essentially equivalent to a semicolon\&. With arguments,
+\eg
+provides a
+\(lqone\-shot\(rq
+alternative to the
+\fB\eo\fR
+command, and additionally allows one\-shot adjustments of the output formatting options normally set by
+\epset\&.
+.sp
+When the last argument begins with
+|, the entire remainder of the line is taken to be the
+\fIcommand\fR
+to execute, and neither variable interpolation nor backquote expansion are performed in it\&. The rest of the line is simply passed literally to the shell\&.
+.RE
+.PP
+\egdesc
+.RS 4
+Shows the description (that is, the column names and data types) of the result of the current query buffer\&. The query is not actually executed; however, if it contains some type of syntax error, that error will be reported in the normal way\&.
+.sp
+If the current query buffer is empty, the most recently sent query is described instead\&.
+.RE
+.PP
+\egetenv \fIpsql_var\fR \fIenv_var\fR
+.RS 4
+Gets the value of the environment variable
+\fIenv_var\fR
+and assigns it to the
+psql
+variable
+\fIpsql_var\fR\&. If
+\fIenv_var\fR
+is not defined in the
+psql
+process\*(Aqs environment,
+\fIpsql_var\fR
+is not changed\&. Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+=> \fB\egetenv home HOME\fR
+=> \fB\eecho :home\fR
+/home/postgres
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\egexec
+.RS 4
+Sends the current query buffer to the server, then treats each column of each row of the query\*(Aqs output (if any) as an SQL statement to be executed\&. For example, to create an index on each column of
+my_table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+=> \fBSELECT format(\*(Aqcreate index on my_table(%I)\*(Aq, attname)\fR
+\-> \fBFROM pg_attribute\fR
+\-> \fBWHERE attrelid = \*(Aqmy_table\*(Aq::regclass AND attnum > 0\fR
+\-> \fBORDER BY attnum\fR
+\-> \fB\egexec\fR
+CREATE INDEX
+CREATE INDEX
+CREATE INDEX
+CREATE INDEX
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The generated queries are executed in the order in which the rows are returned, and left\-to\-right within each row if there is more than one column\&. NULL fields are ignored\&. The generated queries are sent literally to the server for processing, so they cannot be
+psql
+meta\-commands nor contain
+psql
+variable references\&. If any individual query fails, execution of the remaining queries continues unless
+\fION_ERROR_STOP\fR
+is set\&. Execution of each query is subject to
+\fIECHO\fR
+processing\&. (Setting
+\fIECHO\fR
+to
+all
+or
+queries
+is often advisable when using
+\fB\egexec\fR\&.) Query logging, single\-step mode, timing, and other query execution features apply to each generated query as well\&.
+.sp
+If the current query buffer is empty, the most recently sent query is re\-executed instead\&.
+.RE
+.PP
+\egset [ \fIprefix\fR ]
+.RS 4
+Sends the current query buffer to the server and stores the query\*(Aqs output into
+psql
+variables (see
+Variables
+below)\&. The query to be executed must return exactly one row\&. Each column of the row is stored into a separate variable, named the same as the column\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+=> \fBSELECT \*(Aqhello\*(Aq AS var1, 10 AS var2\fR
+\-> \fB\egset\fR
+=> \fB\eecho :var1 :var2\fR
+hello 10
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If you specify a
+\fIprefix\fR, that string is prepended to the query\*(Aqs column names to create the variable names to use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+=> \fBSELECT \*(Aqhello\*(Aq AS var1, 10 AS var2\fR
+\-> \fB\egset result_\fR
+=> \fB\eecho :result_var1 :result_var2\fR
+hello 10
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If a column result is NULL, the corresponding variable is unset rather than being set\&.
+.sp
+If the query fails or does not return one row, no variables are changed\&.
+.sp
+If the current query buffer is empty, the most recently sent query is re\-executed instead\&.
+.RE
+.PP
+\egx [ (\fIoption\fR=\fIvalue\fR [\&.\&.\&.]) ] [ \fIfilename\fR ]
+.br
+\egx [ (\fIoption\fR=\fIvalue\fR [\&.\&.\&.]) ] [ |\fIcommand\fR ]
+.RS 4
+\egx
+is equivalent to
+\eg, except that it forces expanded output mode for this query, as if
+expanded=on
+were included in the list of
+\epset
+options\&. See also
+\ex\&.
+.RE
+.PP
+\eh or \ehelp [ \fIcommand\fR ]
+.RS 4
+Gives syntax help on the specified
+SQL
+command\&. If
+\fIcommand\fR
+is not specified, then
+psql
+will list all the commands for which syntax help is available\&. If
+\fIcommand\fR
+is an asterisk (*), then syntax help on all
+SQL
+commands is shown\&.
+.sp
+Unlike most other meta\-commands, the entire remainder of the line is always taken to be the argument(s) of
+\fB\ehelp\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+To simplify typing, commands that consists of several words do not have to be quoted\&. Thus it is fine to type
+\fB\ehelp alter table\fR\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eH or \ehtml
+.RS 4
+Turns on
+HTML
+query output format\&. If the
+HTML
+format is already on, it is switched back to the default aligned text format\&. This command is for compatibility and convenience, but see
+\fB\epset\fR
+about setting other output options\&.
+.RE
+.PP
+\ei or \einclude \fIfilename\fR
+.RS 4
+Reads input from the file
+\fIfilename\fR
+and executes it as though it had been typed on the keyboard\&.
+.sp
+If
+\fIfilename\fR
+is
+\-
+(hyphen), then standard input is read until an EOF indication or
+\fB\eq\fR
+meta\-command\&. This can be used to intersperse interactive input with input from files\&. Note that Readline behavior will be used only if it is active at the outermost level\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+If you want to see the lines on the screen as they are read you must set the variable
+\fIECHO\fR
+to
+all\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eif \fIexpression\fR
+.br
+\eelif \fIexpression\fR
+.br
+\eelse
+.br
+\eendif
+.RS 4
+This group of commands implements nestable conditional blocks\&. A conditional block must begin with an
+\fB\eif\fR
+and end with an
+\fB\eendif\fR\&. In between there may be any number of
+\fB\eelif\fR
+clauses, which may optionally be followed by a single
+\fB\eelse\fR
+clause\&. Ordinary queries and other types of backslash commands may (and usually do) appear between the commands forming a conditional block\&.
+.sp
+The
+\fB\eif\fR
+and
+\fB\eelif\fR
+commands read their argument(s) and evaluate them as a Boolean expression\&. If the expression yields
+true
+then processing continues normally; otherwise, lines are skipped until a matching
+\fB\eelif\fR,
+\fB\eelse\fR, or
+\fB\eendif\fR
+is reached\&. Once an
+\fB\eif\fR
+or
+\fB\eelif\fR
+test has succeeded, the arguments of later
+\fB\eelif\fR
+commands in the same block are not evaluated but are treated as false\&. Lines following an
+\fB\eelse\fR
+are processed only if no earlier matching
+\fB\eif\fR
+or
+\fB\eelif\fR
+succeeded\&.
+.sp
+The
+\fIexpression\fR
+argument of an
+\fB\eif\fR
+or
+\fB\eelif\fR
+command is subject to variable interpolation and backquote expansion, just like any other backslash command argument\&. After that it is evaluated like the value of an on/off option variable\&. So a valid value is any unambiguous case\-insensitive match for one of:
+true,
+false,
+1,
+0,
+on,
+off,
+yes,
+no\&. For example,
+t,
+T, and
+tR
+will all be considered to be
+true\&.
+.sp
+Expressions that do not properly evaluate to true or false will generate a warning and be treated as false\&.
+.sp
+Lines being skipped are parsed normally to identify queries and backslash commands, but queries are not sent to the server, and backslash commands other than conditionals (\fB\eif\fR,
+\fB\eelif\fR,
+\fB\eelse\fR,
+\fB\eendif\fR) are ignored\&. Conditional commands are checked only for valid nesting\&. Variable references in skipped lines are not expanded, and backquote expansion is not performed either\&.
+.sp
+All the backslash commands of a given conditional block must appear in the same source file\&. If EOF is reached on the main input file or an
+\fB\einclude\fR\-ed file before all local
+\fB\eif\fR\-blocks have been closed, then
+psql
+will raise an error\&.
+.sp
+Here is an example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\-\- check for the existence of two separate records in the database and store
+\-\- the results in separate psql variables
+SELECT
+ EXISTS(SELECT 1 FROM customer WHERE customer_id = 123) as is_customer,
+ EXISTS(SELECT 1 FROM employee WHERE employee_id = 456) as is_employee
+\egset
+\eif :is_customer
+ SELECT * FROM customer WHERE customer_id = 123;
+\eelif :is_employee
+ \eecho \*(Aqis not a customer but is an employee\*(Aq
+ SELECT * FROM employee WHERE employee_id = 456;
+\eelse
+ \eif yes
+ \eecho \*(Aqnot a customer or employee\*(Aq
+ \eelse
+ \eecho \*(Aqthis will never print\*(Aq
+ \eendif
+\eendif
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\eir or \einclude_relative \fIfilename\fR
+.RS 4
+The
+\eir
+command is similar to
+\ei, but resolves relative file names differently\&. When executing in interactive mode, the two commands behave identically\&. However, when invoked from a script,
+\eir
+interprets file names relative to the directory in which the script is located, rather than the current working directory\&.
+.RE
+.PP
+\el[+] or \elist[+] [ \fIpattern\fR ]
+.RS 4
+List the databases in the server and show their names, owners, character set encodings, and access privileges\&. If
+\fIpattern\fR
+is specified, only databases whose names match the pattern are listed\&. If
++
+is appended to the command name, database sizes, default tablespaces, and descriptions are also displayed\&. (Size information is only available for databases that the current user can connect to\&.)
+.RE
+.PP
+\elo_export \fIloid\fR \fIfilename\fR
+.RS 4
+Reads the large object with
+OID
+\fIloid\fR
+from the database and writes it to
+\fIfilename\fR\&. Note that this is subtly different from the server function
+\fBlo_export\fR, which acts with the permissions of the user that the database server runs as and on the server\*(Aqs file system\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+Use
+\fB\elo_list\fR
+to find out the large object\*(Aqs
+OID\&.
+.sp .5v
+.RE
+.RE
+.PP
+\elo_import \fIfilename\fR [ \fIcomment\fR ]
+.RS 4
+Stores the file into a
+PostgreSQL
+large object\&. Optionally, it associates the given comment with the object\&. Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+foo=> \fB\elo_import \*(Aq/home/peter/pictures/photo\&.xcf\*(Aq \*(Aqa picture of me\*(Aq\fR
+lo_import 152801
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The response indicates that the large object received object ID 152801, which can be used to access the newly\-created large object in the future\&. For the sake of readability, it is recommended to always associate a human\-readable comment with every object\&. Both OIDs and comments can be viewed with the
+\fB\elo_list\fR
+command\&.
+.sp
+Note that this command is subtly different from the server\-side
+\fBlo_import\fR
+because it acts as the local user on the local file system, rather than the server\*(Aqs user and file system\&.
+.RE
+.PP
+\elo_list[+]
+.RS 4
+Shows a list of all
+PostgreSQL
+large objects currently stored in the database, along with any comments provided for them\&. If
++
+is appended to the command name, each large object is listed with its associated permissions, if any\&.
+.RE
+.PP
+\elo_unlink \fIloid\fR
+.RS 4
+Deletes the large object with
+OID
+\fIloid\fR
+from the database\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+Use
+\fB\elo_list\fR
+to find out the large object\*(Aqs
+OID\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eo or \eout [ \fIfilename\fR ]
+.br
+\eo or \eout [ |\fIcommand\fR ]
+.RS 4
+Arranges to save future query results to the file
+\fIfilename\fR
+or pipe future results to the shell command
+\fIcommand\fR\&. If no argument is specified, the query output is reset to the standard output\&.
+.sp
+If the argument begins with
+|, then the entire remainder of the line is taken to be the
+\fIcommand\fR
+to execute, and neither variable interpolation nor backquote expansion are performed in it\&. The rest of the line is simply passed literally to the shell\&.
+.sp
+\(lqQuery results\(rq
+includes all tables, command responses, and notices obtained from the database server, as well as output of various backslash commands that query the database (such as
+\fB\ed\fR); but not error messages\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+To intersperse text output in between query results, use
+\fB\eqecho\fR\&.
+.sp .5v
+.RE
+.RE
+.PP
+\ep or \eprint
+.RS 4
+Print the current query buffer to the standard output\&. If the current query buffer is empty, the most recently executed query is printed instead\&.
+.RE
+.PP
+\epassword [ \fIusername\fR ]
+.RS 4
+Changes the password of the specified user (by default, the current user)\&. This command prompts for the new password, encrypts it, and sends it to the server as an
+\fBALTER ROLE\fR
+command\&. This makes sure that the new password does not appear in cleartext in the command history, the server log, or elsewhere\&.
+.RE
+.PP
+\eprompt [ \fItext\fR ] \fIname\fR
+.RS 4
+Prompts the user to supply text, which is assigned to the variable
+\fIname\fR\&. An optional prompt string,
+\fItext\fR, can be specified\&. (For multiword prompts, surround the text with single quotes\&.)
+.sp
+By default,
+\eprompt
+uses the terminal for input and output\&. However, if the
+\fB\-f\fR
+command line switch was used,
+\eprompt
+uses standard input and standard output\&.
+.RE
+.PP
+\epset [ \fIoption\fR [ \fIvalue\fR ] ]
+.RS 4
+This command sets options affecting the output of query result tables\&.
+\fIoption\fR
+indicates which option is to be set\&. The semantics of
+\fIvalue\fR
+vary depending on the selected option\&. For some options, omitting
+\fIvalue\fR
+causes the option to be toggled or unset, as described under the particular option\&. If no such behavior is mentioned, then omitting
+\fIvalue\fR
+just results in the current setting being displayed\&.
+.sp
+\fB\epset\fR
+without any arguments displays the current status of all printing options\&.
+.sp
+Adjustable printing options are:
+.PP
+border
+.RS 4
+The
+\fIvalue\fR
+must be a number\&. In general, the higher the number the more borders and lines the tables will have, but details depend on the particular format\&. In
+HTML
+format, this will translate directly into the
+border=\&.\&.\&.
+attribute\&. In most other formats only values 0 (no border), 1 (internal dividing lines), and 2 (table frame) make sense, and values above 2 will be treated the same as
+border = 2\&. The
+latex
+and
+latex\-longtable
+formats additionally allow a value of 3 to add dividing lines between data rows\&.
+.RE
+.PP
+columns
+.RS 4
+Sets the target width for the
+wrapped
+format, and also the width limit for determining whether output is wide enough to require the pager or switch to the vertical display in expanded auto mode\&. Zero (the default) causes the target width to be controlled by the environment variable
+\fBCOLUMNS\fR, or the detected screen width if
+\fBCOLUMNS\fR
+is not set\&. In addition, if
+columns
+is zero then the
+wrapped
+format only affects screen output\&. If
+columns
+is nonzero then file and pipe output is wrapped to that width as well\&.
+.RE
+.PP
+csv_fieldsep
+.RS 4
+Specifies the field separator to be used in
+CSV
+output format\&. If the separator character appears in a field\*(Aqs value, that field is output within double quotes, following standard
+CSV
+rules\&. The default is a comma\&.
+.RE
+.PP
+expanded (or x)
+.RS 4
+If
+\fIvalue\fR
+is specified it must be either
+on
+or
+off, which will enable or disable expanded mode, or
+auto\&. If
+\fIvalue\fR
+is omitted the command toggles between the on and off settings\&. When expanded mode is enabled, query results are displayed in two columns, with the column name on the left and the data on the right\&. This mode is useful if the data wouldn\*(Aqt fit on the screen in the normal
+\(lqhorizontal\(rq
+mode\&. In the auto setting, the expanded mode is used whenever the query output has more than one column and is wider than the screen; otherwise, the regular mode is used\&. The auto setting is only effective in the aligned and wrapped formats\&. In other formats, it always behaves as if the expanded mode is off\&.
+.RE
+.PP
+fieldsep
+.RS 4
+Specifies the field separator to be used in unaligned output format\&. That way one can create, for example, tab\-separated output, which other programs might prefer\&. To set a tab as field separator, type
+\epset fieldsep \*(Aq\et\*(Aq\&. The default field separator is
+\*(Aq|\*(Aq
+(a vertical bar)\&.
+.RE
+.PP
+fieldsep_zero
+.RS 4
+Sets the field separator to use in unaligned output format to a zero byte\&.
+.RE
+.PP
+footer
+.RS 4
+If
+\fIvalue\fR
+is specified it must be either
+on
+or
+off
+which will enable or disable display of the table footer (the
+(\fIn\fR rows)
+count)\&. If
+\fIvalue\fR
+is omitted the command toggles footer display on or off\&.
+.RE
+.PP
+format
+.RS 4
+Sets the output format to one of
+aligned,
+asciidoc,
+csv,
+html,
+latex,
+latex\-longtable,
+troff\-ms,
+unaligned, or
+wrapped\&. Unique abbreviations are allowed\&.
+.sp
+aligned
+format is the standard, human\-readable, nicely formatted text output; this is the default\&.
+.sp
+unaligned
+format writes all columns of a row on one line, separated by the currently active field separator\&. This is useful for creating output that might be intended to be read in by other programs, for example, tab\-separated or comma\-separated format\&. However, the field separator character is not treated specially if it appears in a column\*(Aqs value; so
+CSV
+format may be better suited for such purposes\&.
+.sp
+csv
+format
+
+writes column values separated by commas, applying the quoting rules described in
+\m[blue]\fBRFC 4180\fR\m[]\&. This output is compatible with the CSV format of the server\*(Aqs
+\fBCOPY\fR
+command\&. A header line with column names is generated unless the
+tuples_only
+parameter is
+on\&. Titles and footers are not printed\&. Each row is terminated by the system\-dependent end\-of\-line character, which is typically a single newline (\en) for Unix\-like systems or a carriage return and newline sequence (\er\en) for Microsoft Windows\&. Field separator characters other than comma can be selected with
+\fB\epset csv_fieldsep\fR\&.
+.sp
+wrapped
+format is like
+aligned
+but wraps wide data values across lines to make the output fit in the target column width\&. The target width is determined as described under the
+columns
+option\&. Note that
+psql
+will not attempt to wrap column header titles; therefore,
+wrapped
+format behaves the same as
+aligned
+if the total width needed for column headers exceeds the target\&.
+.sp
+The
+asciidoc,
+html,
+latex,
+latex\-longtable, and
+troff\-ms
+formats put out tables that are intended to be included in documents using the respective mark\-up language\&. They are not complete documents! This might not be necessary in
+HTML, but in
+LaTeX
+you must have a complete document wrapper\&. The
+latex
+format uses
+LaTeX\*(Aqs
+tabular
+environment\&. The
+latex\-longtable
+format requires the
+LaTeX
+longtable
+and
+booktabs
+packages\&.
+.RE
+.PP
+linestyle
+.RS 4
+Sets the border line drawing style to one of
+ascii,
+old\-ascii, or
+unicode\&. Unique abbreviations are allowed\&. (That would mean one letter is enough\&.) The default setting is
+ascii\&. This option only affects the
+aligned
+and
+wrapped
+output formats\&.
+.sp
+ascii
+style uses plain
+ASCII
+characters\&. Newlines in data are shown using a
++
+symbol in the right\-hand margin\&. When the
+wrapped
+format wraps data from one line to the next without a newline character, a dot (\&.) is shown in the right\-hand margin of the first line, and again in the left\-hand margin of the following line\&.
+.sp
+old\-ascii
+style uses plain
+ASCII
+characters, using the formatting style used in
+PostgreSQL
+8\&.4 and earlier\&. Newlines in data are shown using a
+:
+symbol in place of the left\-hand column separator\&. When the data is wrapped from one line to the next without a newline character, a
+;
+symbol is used in place of the left\-hand column separator\&.
+.sp
+unicode
+style uses Unicode box\-drawing characters\&. Newlines in data are shown using a carriage return symbol in the right\-hand margin\&. When the data is wrapped from one line to the next without a newline character, an ellipsis symbol is shown in the right\-hand margin of the first line, and again in the left\-hand margin of the following line\&.
+.sp
+When the
+border
+setting is greater than zero, the
+linestyle
+option also determines the characters with which the border lines are drawn\&. Plain
+ASCII
+characters work everywhere, but Unicode characters look nicer on displays that recognize them\&.
+.RE
+.PP
+null
+.RS 4
+Sets the string to be printed in place of a null value\&. The default is to print nothing, which can easily be mistaken for an empty string\&. For example, one might prefer
+\epset null \*(Aq(null)\*(Aq\&.
+.RE
+.PP
+numericlocale
+.RS 4
+If
+\fIvalue\fR
+is specified it must be either
+on
+or
+off
+which will enable or disable display of a locale\-specific character to separate groups of digits to the left of the decimal marker\&. If
+\fIvalue\fR
+is omitted the command toggles between regular and locale\-specific numeric output\&.
+.RE
+.PP
+pager
+.RS 4
+Controls use of a pager program for query and
+psql
+help output\&. When the
+pager
+option is
+off, the pager program is not used\&. When the
+pager
+option is
+on, the pager is used when appropriate, i\&.e\&., when the output is to a terminal and will not fit on the screen\&. The
+pager
+option can also be set to
+always, which causes the pager to be used for all terminal output regardless of whether it fits on the screen\&.
+\epset pager
+without a
+\fIvalue\fR
+toggles pager use on and off\&.
+.sp
+If the environment variable
+\fBPSQL_PAGER\fR
+or
+\fBPAGER\fR
+is set, output to be paged is piped to the specified program\&. Otherwise a platform\-dependent default program (such as
+more) is used\&.
+.sp
+When using the
+\ewatch
+command to execute a query repeatedly, the environment variable
+\fBPSQL_WATCH_PAGER\fR
+is used to find the pager program instead, on Unix systems\&. This is configured separately because it may confuse traditional pagers, but can be used to send output to tools that understand
+psql\*(Aqs output format (such as
+pspg \-\-stream)\&.
+.RE
+.PP
+pager_min_lines
+.RS 4
+If
+pager_min_lines
+is set to a number greater than the page height, the pager program will not be called unless there are at least this many lines of output to show\&. The default setting is 0\&.
+.RE
+.PP
+recordsep
+.RS 4
+Specifies the record (line) separator to use in unaligned output format\&. The default is a newline character\&.
+.RE
+.PP
+recordsep_zero
+.RS 4
+Sets the record separator to use in unaligned output format to a zero byte\&.
+.RE
+.PP
+tableattr (or T)
+.RS 4
+In
+HTML
+format, this specifies attributes to be placed inside the
+table
+tag\&. This could for example be
+cellpadding
+or
+bgcolor\&. Note that you probably don\*(Aqt want to specify
+border
+here, as that is already taken care of by
+\epset border\&. If no
+\fIvalue\fR
+is given, the table attributes are unset\&.
+.sp
+In
+latex\-longtable
+format, this controls the proportional width of each column containing a left\-aligned data type\&. It is specified as a whitespace\-separated list of values, e\&.g\&.,
+\*(Aq0\&.2 0\&.2 0\&.6\*(Aq\&. Unspecified output columns use the last specified value\&.
+.RE
+.PP
+title (or C)
+.RS 4
+Sets the table title for any subsequently printed tables\&. This can be used to give your output descriptive tags\&. If no
+\fIvalue\fR
+is given, the title is unset\&.
+.RE
+.PP
+tuples_only (or t)
+.RS 4
+If
+\fIvalue\fR
+is specified it must be either
+on
+or
+off
+which will enable or disable tuples\-only mode\&. If
+\fIvalue\fR
+is omitted the command toggles between regular and tuples\-only output\&. Regular output includes extra information such as column headers, titles, and various footers\&. In tuples\-only mode, only actual table data is shown\&.
+.RE
+.PP
+unicode_border_linestyle
+.RS 4
+Sets the border drawing style for the
+unicode
+line style to one of
+single
+or
+double\&.
+.RE
+.PP
+unicode_column_linestyle
+.RS 4
+Sets the column drawing style for the
+unicode
+line style to one of
+single
+or
+double\&.
+.RE
+.PP
+unicode_header_linestyle
+.RS 4
+Sets the header drawing style for the
+unicode
+line style to one of
+single
+or
+double\&.
+.RE
+.sp
+Illustrations of how these different formats look can be seen in
+Examples, below\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+There are various shortcut commands for
+\fB\epset\fR\&. See
+\fB\ea\fR,
+\fB\eC\fR,
+\fB\ef\fR,
+\fB\eH\fR,
+\fB\et\fR,
+\fB\eT\fR, and
+\fB\ex\fR\&.
+.sp .5v
+.RE
+.RE
+.PP
+\eq or \equit
+.RS 4
+Quits the
+psql
+program\&. In a script file, only execution of that script is terminated\&.
+.RE
+.PP
+\eqecho \fItext\fR [ \&.\&.\&. ]
+.RS 4
+This command is identical to
+\fB\eecho\fR
+except that the output will be written to the query output channel, as set by
+\fB\eo\fR\&.
+.RE
+.PP
+\er or \ereset
+.RS 4
+Resets (clears) the query buffer\&.
+.RE
+.PP
+\es [ \fIfilename\fR ]
+.RS 4
+Print
+psql\*(Aqs command line history to
+\fIfilename\fR\&. If
+\fIfilename\fR
+is omitted, the history is written to the standard output (using the pager if appropriate)\&. This command is not available if
+psql
+was built without
+Readline
+support\&.
+.RE
+.PP
+\eset [ \fIname\fR [ \fIvalue\fR [ \&.\&.\&. ] ] ]
+.RS 4
+Sets the
+psql
+variable
+\fIname\fR
+to
+\fIvalue\fR, or if more than one value is given, to the concatenation of all of them\&. If only one argument is given, the variable is set to an empty\-string value\&. To unset a variable, use the
+\fB\eunset\fR
+command\&.
+.sp
+\fB\eset\fR
+without any arguments displays the names and values of all currently\-set
+psql
+variables\&.
+.sp
+Valid variable names can contain letters, digits, and underscores\&. See
+Variables
+below for details\&. Variable names are case\-sensitive\&.
+.sp
+Certain variables are special, in that they control
+psql\*(Aqs behavior or are automatically set to reflect connection state\&. These variables are documented in
+Variables, below\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This command is unrelated to the
+SQL
+command
+\fBSET\fR\&.
+.sp .5v
+.RE
+.RE
+.PP
+\esetenv \fIname\fR [ \fIvalue\fR ]
+.RS 4
+Sets the environment variable
+\fIname\fR
+to
+\fIvalue\fR, or if the
+\fIvalue\fR
+is not supplied, unsets the environment variable\&. Example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\esetenv PAGER less\fR
+testdb=> \fB\esetenv LESS \-imx4F\fR
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\esf[+] \fIfunction_description\fR
+.RS 4
+This command fetches and shows the definition of the named function or procedure, in the form of a
+\fBCREATE OR REPLACE FUNCTION\fR
+or
+\fBCREATE OR REPLACE PROCEDURE\fR
+command\&. The definition is printed to the current query output channel, as set by
+\fB\eo\fR\&.
+.sp
+The target function can be specified by name alone, or by name and arguments, for example
+foo(integer, text)\&. The argument types must be given if there is more than one function of the same name\&.
+.sp
+If
++
+is appended to the command name, then the output lines are numbered, with the first line of the function body being line 1\&.
+.sp
+Unlike most other meta\-commands, the entire remainder of the line is always taken to be the argument(s) of
+\fB\esf\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&.
+.RE
+.PP
+\esv[+] \fIview_name\fR
+.RS 4
+This command fetches and shows the definition of the named view, in the form of a
+\fBCREATE OR REPLACE VIEW\fR
+command\&. The definition is printed to the current query output channel, as set by
+\fB\eo\fR\&.
+.sp
+If
++
+is appended to the command name, then the output lines are numbered from 1\&.
+.sp
+Unlike most other meta\-commands, the entire remainder of the line is always taken to be the argument(s) of
+\fB\esv\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&.
+.RE
+.PP
+\et
+.RS 4
+Toggles the display of output column name headings and row count footer\&. This command is equivalent to
+\epset tuples_only
+and is provided for convenience\&.
+.RE
+.PP
+\eT \fItable_options\fR
+.RS 4
+Specifies attributes to be placed within the
+table
+tag in
+HTML
+output format\&. This command is equivalent to
+\epset tableattr \fItable_options\fR\&.
+.RE
+.PP
+\etiming [ \fIon\fR | \fIoff\fR ]
+.RS 4
+With a parameter, turns displaying of how long each SQL statement takes on or off\&. Without a parameter, toggles the display between on and off\&. The display is in milliseconds; intervals longer than 1 second are also shown in minutes:seconds format, with hours and days fields added if needed\&.
+.RE
+.PP
+\eunset \fIname\fR
+.RS 4
+Unsets (deletes) the
+psql
+variable
+\fIname\fR\&.
+.sp
+Most variables that control
+psql\*(Aqs behavior cannot be unset; instead, an
+\eunset
+command is interpreted as setting them to their default values\&. See
+Variables
+below\&.
+.RE
+.PP
+\ew or \ewrite \fIfilename\fR
+.br
+\ew or \ewrite |\fIcommand\fR
+.RS 4
+Writes the current query buffer to the file
+\fIfilename\fR
+or pipes it to the shell command
+\fIcommand\fR\&. If the current query buffer is empty, the most recently executed query is written instead\&.
+.sp
+If the argument begins with
+|, then the entire remainder of the line is taken to be the
+\fIcommand\fR
+to execute, and neither variable interpolation nor backquote expansion are performed in it\&. The rest of the line is simply passed literally to the shell\&.
+.RE
+.PP
+\ewarn \fItext\fR [ \&.\&.\&. ]
+.RS 4
+This command is identical to
+\fB\eecho\fR
+except that the output will be written to
+psql\*(Aqs standard error channel, rather than standard output\&.
+.RE
+.PP
+\ewatch [ \fIseconds\fR ]
+.RS 4
+Repeatedly execute the current query buffer (as
+\eg
+does) until interrupted or the query fails\&. Wait the specified number of seconds (default 2) between executions\&. Each query result is displayed with a header that includes the
+\epset title
+string (if any), the time as of query start, and the delay interval\&.
+.sp
+If the current query buffer is empty, the most recently sent query is re\-executed instead\&.
+.RE
+.PP
+\ex [ \fIon\fR | \fIoff\fR | \fIauto\fR ]
+.RS 4
+Sets or toggles expanded table formatting mode\&. As such it is equivalent to
+\epset expanded\&.
+.RE
+.PP
+\ez [ \fIpattern\fR ]
+.RS 4
+Lists tables, views and sequences with their associated access privileges\&. If a
+\fIpattern\fR
+is specified, only tables, views and sequences whose names match the pattern are listed\&.
+.sp
+This is an alias for
+\fB\edp\fR
+(\(lqdisplay privileges\(rq)\&.
+.RE
+.PP
+\e! [ \fIcommand\fR ]
+.RS 4
+With no argument, escapes to a sub\-shell;
+psql
+resumes when the sub\-shell exits\&. With an argument, executes the shell command
+\fIcommand\fR\&.
+.sp
+Unlike most other meta\-commands, the entire remainder of the line is always taken to be the argument(s) of
+\fB\e!\fR, and neither variable interpolation nor backquote expansion are performed in the arguments\&. The rest of the line is simply passed literally to the shell\&.
+.RE
+.PP
+\e? [ \fItopic\fR ]
+.RS 4
+Shows help information\&. The optional
+\fItopic\fR
+parameter (defaulting to
+commands) selects which part of
+psql
+is explained:
+commands
+describes
+psql\*(Aqs backslash commands;
+options
+describes the command\-line options that can be passed to
+psql; and
+variables
+shows help about
+psql
+configuration variables\&.
+.RE
+.PP
+\e;
+.RS 4
+Backslash\-semicolon is not a meta\-command in the same way as the preceding commands; rather, it simply causes a semicolon to be added to the query buffer without any further processing\&.
+.sp
+Normally,
+psql
+will dispatch an SQL command to the server as soon as it reaches the command\-ending semicolon, even if more input remains on the current line\&. Thus for example entering
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+select 1; select 2; select 3;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+will result in the three SQL commands being individually sent to the server, with each one\*(Aqs results being displayed before continuing to the next command\&. However, a semicolon entered as
+\e;
+will not trigger command processing, so that the command before it and the one after are effectively combined and sent to the server in one request\&. So for example
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+select 1\e; select 2\e; select 3;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+results in sending the three SQL commands to the server in a single request, when the non\-backslashed semicolon is reached\&. The server executes such a request as a single transaction, unless there are explicit
+\fBBEGIN\fR/\fBCOMMIT\fR
+commands included in the string to divide it into multiple transactions\&. (See
+Section\ \&55.2.2.1
+for more details about how the server handles multi\-query strings\&.)
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBPatterns\fR
+.RS 4
+.PP
+The various
+\ed
+commands accept a
+\fIpattern\fR
+parameter to specify the object name(s) to be displayed\&. In the simplest case, a pattern is just the exact name of the object\&. The characters within a pattern are normally folded to lower case, just as in SQL names; for example,
+\edt FOO
+will display the table named
+foo\&. As in SQL names, placing double quotes around a pattern stops folding to lower case\&. Should you need to include an actual double quote character in a pattern, write it as a pair of double quotes within a double\-quote sequence; again this is in accord with the rules for SQL quoted identifiers\&. For example,
+\edt "FOO""BAR"
+will display the table named
+FOO"BAR
+(not
+foo"bar)\&. Unlike the normal rules for SQL names, you can put double quotes around just part of a pattern, for instance
+\edt FOO"FOO"BAR
+will display the table named
+fooFOObar\&.
+.PP
+Whenever the
+\fIpattern\fR
+parameter is omitted completely, the
+\ed
+commands display all objects that are visible in the current schema search path \(em this is equivalent to using
+*
+as the pattern\&. (An object is said to be
+visible
+if its containing schema is in the search path and no object of the same kind and name appears earlier in the search path\&. This is equivalent to the statement that the object can be referenced by name without explicit schema qualification\&.) To see all objects in the database regardless of visibility, use
+*\&.*
+as the pattern\&.
+.PP
+Within a pattern,
+*
+matches any sequence of characters (including no characters) and
+?
+matches any single character\&. (This notation is comparable to Unix shell file name patterns\&.) For example,
+\edt int*
+displays tables whose names begin with
+int\&. But within double quotes,
+*
+and
+?
+lose these special meanings and are just matched literally\&.
+.PP
+A relation pattern that contains a dot (\&.) is interpreted as a schema name pattern followed by an object name pattern\&. For example,
+\edt foo*\&.*bar*
+displays all tables whose table name includes
+bar
+that are in schemas whose schema name starts with
+foo\&. When no dot appears, then the pattern matches only objects that are visible in the current schema search path\&. Again, a dot within double quotes loses its special meaning and is matched literally\&. A relation pattern that contains two dots (\&.) is interpreted as a database name followed by a schema name pattern followed by an object name pattern\&. The database name portion will not be treated as a pattern and must match the name of the currently connected database, else an error will be raised\&.
+.PP
+A schema pattern that contains a dot (\&.) is interpreted as a database name followed by a schema name pattern\&. For example,
+\edn mydb\&.*foo*
+displays all schemas whose schema name includes
+foo\&. The database name portion will not be treated as a pattern and must match the name of the currently connected database, else an error will be raised\&.
+.PP
+Advanced users can use regular\-expression notations such as character classes, for example
+[0\-9]
+to match any digit\&. All regular expression special characters work as specified in
+Section\ \&9.7.3, except for
+\&.
+which is taken as a separator as mentioned above,
+*
+which is translated to the regular\-expression notation
+\&.*,
+?
+which is translated to
+\&., and
+$
+which is matched literally\&. You can emulate these pattern characters at need by writing
+?
+for
+\&.,
+(\fIR\fR+|)
+for
+\fIR\fR*, or
+(\fIR\fR|)
+for
+\fIR\fR?\&.
+$
+is not needed as a regular\-expression character since the pattern must match the whole name, unlike the usual interpretation of regular expressions (in other words,
+$
+is automatically appended to your pattern)\&. Write
+*
+at the beginning and/or end if you don\*(Aqt wish the pattern to be anchored\&. Note that within double quotes, all regular expression special characters lose their special meanings and are matched literally\&. Also, the regular expression special characters are matched literally in operator name patterns (i\&.e\&., the argument of
+\edo)\&.
+.RE
+.SS "Advanced Features"
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBVariables\fR
+.RS 4
+.PP
+psql
+provides variable substitution features similar to common Unix command shells\&. Variables are simply name/value pairs, where the value can be any string of any length\&. The name must consist of letters (including non\-Latin letters), digits, and underscores\&.
+.PP
+To set a variable, use the
+psql
+meta\-command
+\fB\eset\fR\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\eset foo bar\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+sets the variable
+foo
+to the value
+bar\&. To retrieve the content of the variable, precede the name with a colon, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\eecho :foo\fR
+bar
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This works in both regular SQL commands and meta\-commands; there is more detail in
+SQL Interpolation, below\&.
+.PP
+If you call
+\fB\eset\fR
+without a second argument, the variable is set to an empty\-string value\&. To unset (i\&.e\&., delete) a variable, use the command
+\fB\eunset\fR\&. To show the values of all variables, call
+\fB\eset\fR
+without any argument\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+The arguments of
+\fB\eset\fR
+are subject to the same substitution rules as with other commands\&. Thus you can construct interesting references such as
+\eset :foo \*(Aqsomething\*(Aq
+and get
+\(lqsoft links\(rq
+or
+\(lqvariable variables\(rq
+of
+Perl
+or
+PHP
+fame, respectively\&. Unfortunately (or fortunately?), there is no way to do anything useful with these constructs\&. On the other hand,
+\eset bar :foo
+is a perfectly valid way to copy a variable\&.
+.sp .5v
+.RE
+.PP
+A number of these variables are treated specially by
+psql\&. They represent certain option settings that can be changed at run time by altering the value of the variable, or in some cases represent changeable state of
+psql\&. By convention, all specially treated variables\*(Aq names consist of all upper\-case ASCII letters (and possibly digits and underscores)\&. To ensure maximum compatibility in the future, avoid using such variable names for your own purposes\&.
+.PP
+Variables that control
+psql\*(Aqs behavior generally cannot be unset or set to invalid values\&. An
+\eunset
+command is allowed but is interpreted as setting the variable to its default value\&. A
+\eset
+command without a second argument is interpreted as setting the variable to
+on, for control variables that accept that value, and is rejected for others\&. Also, control variables that accept the values
+on
+and
+off
+will also accept other common spellings of Boolean values, such as
+true
+and
+false\&.
+.PP
+The specially treated variables are:
+.PP
+\fIAUTOCOMMIT\fR
+.RS 4
+When
+on
+(the default), each SQL command is automatically committed upon successful completion\&. To postpone commit in this mode, you must enter a
+\fBBEGIN\fR
+or
+\fBSTART TRANSACTION\fR
+SQL command\&. When
+off
+or unset, SQL commands are not committed until you explicitly issue
+\fBCOMMIT\fR
+or
+\fBEND\fR\&. The autocommit\-off mode works by issuing an implicit
+\fBBEGIN\fR
+for you, just before any command that is not already in a transaction block and is not itself a
+\fBBEGIN\fR
+or other transaction\-control command, nor a command that cannot be executed inside a transaction block (such as
+\fBVACUUM\fR)\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+In autocommit\-off mode, you must explicitly abandon any failed transaction by entering
+\fBABORT\fR
+or
+\fBROLLBACK\fR\&. Also keep in mind that if you exit the session without committing, your work will be lost\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+The autocommit\-on mode is
+PostgreSQL\*(Aqs traditional behavior, but autocommit\-off is closer to the SQL spec\&. If you prefer autocommit\-off, you might wish to set it in the system\-wide
+psqlrc
+file or your
+~/\&.psqlrc
+file\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fICOMP_KEYWORD_CASE\fR
+.RS 4
+Determines which letter case to use when completing an SQL key word\&. If set to
+lower
+or
+upper, the completed word will be in lower or upper case, respectively\&. If set to
+preserve\-lower
+or
+preserve\-upper
+(the default), the completed word will be in the case of the word already entered, but words being completed without anything entered will be in lower or upper case, respectively\&.
+.RE
+.PP
+\fIDBNAME\fR
+.RS 4
+The name of the database you are currently connected to\&. This is set every time you connect to a database (including program start\-up), but can be changed or unset\&.
+.RE
+.PP
+\fIECHO\fR
+.RS 4
+If set to
+all, all nonempty input lines are printed to standard output as they are read\&. (This does not apply to lines read interactively\&.) To select this behavior on program start\-up, use the switch
+\fB\-a\fR\&. If set to
+queries,
+psql
+prints each query to standard output as it is sent to the server\&. The switch to select this behavior is
+\fB\-e\fR\&. If set to
+errors, then only failed queries are displayed on standard error output\&. The switch for this behavior is
+\fB\-b\fR\&. If set to
+none
+(the default), then no queries are displayed\&.
+.RE
+.PP
+\fIECHO_HIDDEN\fR
+.RS 4
+When this variable is set to
+on
+and a backslash command queries the database, the query is first shown\&. This feature helps you to study
+PostgreSQL
+internals and provide similar functionality in your own programs\&. (To select this behavior on program start\-up, use the switch
+\fB\-E\fR\&.) If you set this variable to the value
+noexec, the queries are just shown but are not actually sent to the server and executed\&. The default value is
+off\&.
+.RE
+.PP
+\fIENCODING\fR
+.RS 4
+The current client character set encoding\&. This is set every time you connect to a database (including program start\-up), and when you change the encoding with
+\eencoding, but it can be changed or unset\&.
+.RE
+.PP
+\fIERROR\fR
+.RS 4
+true
+if the last SQL query failed,
+false
+if it succeeded\&. See also
+\fISQLSTATE\fR\&.
+.RE
+.PP
+\fIFETCH_COUNT\fR
+.RS 4
+If this variable is set to an integer value greater than zero, the results of
+\fBSELECT\fR
+queries are fetched and displayed in groups of that many rows, rather than the default behavior of collecting the entire result set before display\&. Therefore only a limited amount of memory is used, regardless of the size of the result set\&. Settings of 100 to 1000 are commonly used when enabling this feature\&. Keep in mind that when using this feature, a query might fail after having already displayed some rows\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+Although you can use any output format with this feature, the default
+aligned
+format tends to look bad because each group of
+\fIFETCH_COUNT\fR
+rows will be formatted separately, leading to varying column widths across the row groups\&. The other output formats work better\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fIHIDE_TABLEAM\fR
+.RS 4
+If this variable is set to
+true, a table\*(Aqs access method details are not displayed\&. This is mainly useful for regression tests\&.
+.RE
+.PP
+\fIHIDE_TOAST_COMPRESSION\fR
+.RS 4
+If this variable is set to
+true, column compression method details are not displayed\&. This is mainly useful for regression tests\&.
+.RE
+.PP
+\fIHISTCONTROL\fR
+.RS 4
+If this variable is set to
+ignorespace, lines which begin with a space are not entered into the history list\&. If set to a value of
+ignoredups, lines matching the previous history line are not entered\&. A value of
+ignoreboth
+combines the two options\&. If set to
+none
+(the default), all lines read in interactive mode are saved on the history list\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This feature was shamelessly plagiarized from
+Bash\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fIHISTFILE\fR
+.RS 4
+The file name that will be used to store the history list\&. If unset, the file name is taken from the
+\fBPSQL_HISTORY\fR
+environment variable\&. If that is not set either, the default is
+~/\&.psql_history, or
+%APPDATA%\epostgresql\epsql_history
+on Windows\&. For example, putting:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\eset HISTFILE ~/\&.psql_history\-:DBNAME
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+in
+~/\&.psqlrc
+will cause
+psql
+to maintain a separate history for each database\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This feature was shamelessly plagiarized from
+Bash\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fIHISTSIZE\fR
+.RS 4
+The maximum number of commands to store in the command history (default 500)\&. If set to a negative value, no limit is applied\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This feature was shamelessly plagiarized from
+Bash\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fIHOST\fR
+.RS 4
+The database server host you are currently connected to\&. This is set every time you connect to a database (including program start\-up), but can be changed or unset\&.
+.RE
+.PP
+\fIIGNOREEOF\fR
+.RS 4
+If set to 1 or less, sending an
+EOF
+character (usually
+Control+D) to an interactive session of
+psql
+will terminate the application\&. If set to a larger numeric value, that many consecutive
+EOF
+characters must be typed to make an interactive session terminate\&. If the variable is set to a non\-numeric value, it is interpreted as 10\&. The default is 0\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This feature was shamelessly plagiarized from
+Bash\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fILASTOID\fR
+.RS 4
+The value of the last affected OID, as returned from an
+\fBINSERT\fR
+or
+\fB\elo_import\fR
+command\&. This variable is only guaranteed to be valid until after the result of the next
+SQL
+command has been displayed\&.
+PostgreSQL
+servers since version 12 do not support OID system columns anymore, thus LASTOID will always be 0 following
+\fBINSERT\fR
+when targeting such servers\&.
+.RE
+.PP
+\fILAST_ERROR_MESSAGE\fR
+.br
+\fILAST_ERROR_SQLSTATE\fR
+.RS 4
+The primary error message and associated SQLSTATE code for the most recent failed query in the current
+psql
+session, or an empty string and
+00000
+if no error has occurred in the current session\&.
+.RE
+.PP
+\fION_ERROR_ROLLBACK\fR
+.RS 4
+When set to
+on, if a statement in a transaction block generates an error, the error is ignored and the transaction continues\&. When set to
+interactive, such errors are only ignored in interactive sessions, and not when reading script files\&. When set to
+off
+(the default), a statement in a transaction block that generates an error aborts the entire transaction\&. The error rollback mode works by issuing an implicit
+\fBSAVEPOINT\fR
+for you, just before each command that is in a transaction block, and then rolling back to the savepoint if the command fails\&.
+.RE
+.PP
+\fION_ERROR_STOP\fR
+.RS 4
+By default, command processing continues after an error\&. When this variable is set to
+on, processing will instead stop immediately\&. In interactive mode,
+psql
+will return to the command prompt; otherwise,
+psql
+will exit, returning error code 3 to distinguish this case from fatal error conditions, which are reported using error code 1\&. In either case, any currently running scripts (the top\-level script, if any, and any other scripts which it may have in invoked) will be terminated immediately\&. If the top\-level command string contained multiple SQL commands, processing will stop with the current command\&.
+.RE
+.PP
+\fIPORT\fR
+.RS 4
+The database server port to which you are currently connected\&. This is set every time you connect to a database (including program start\-up), but can be changed or unset\&.
+.RE
+.PP
+\fIPROMPT1\fR
+.br
+\fIPROMPT2\fR
+.br
+\fIPROMPT3\fR
+.RS 4
+These specify what the prompts
+psql
+issues should look like\&. See
+Prompting
+below\&.
+.RE
+.PP
+\fIQUIET\fR
+.RS 4
+Setting this variable to
+on
+is equivalent to the command line option
+\fB\-q\fR\&. It is probably not too useful in interactive mode\&.
+.RE
+.PP
+\fIROW_COUNT\fR
+.RS 4
+The number of rows returned or affected by the last SQL query, or 0 if the query failed or did not report a row count\&.
+.RE
+.PP
+\fISERVER_VERSION_NAME\fR
+.br
+\fISERVER_VERSION_NUM\fR
+.RS 4
+The server\*(Aqs version number as a string, for example
+9\&.6\&.2,
+10\&.1
+or
+11beta1, and in numeric form, for example
+90602
+or
+100001\&. These are set every time you connect to a database (including program start\-up), but can be changed or unset\&.
+.RE
+.PP
+\fISHOW_ALL_RESULTS\fR
+.RS 4
+When this variable is set to
+off, only the last result of a combined query (\e;) is shown instead of all of them\&. The default is
+on\&. The off behavior is for compatibility with older versions of psql\&.
+.RE
+.PP
+\fISHOW_CONTEXT\fR
+.RS 4
+This variable can be set to the values
+never,
+errors, or
+always
+to control whether
+CONTEXT
+fields are displayed in messages from the server\&. The default is
+errors
+(meaning that context will be shown in error messages, but not in notice or warning messages)\&. This setting has no effect when
+\fIVERBOSITY\fR
+is set to
+terse
+or
+sqlstate\&. (See also
+\fB\eerrverbose\fR, for use when you want a verbose version of the error you just got\&.)
+.RE
+.PP
+\fISINGLELINE\fR
+.RS 4
+Setting this variable to
+on
+is equivalent to the command line option
+\fB\-S\fR\&.
+.RE
+.PP
+\fISINGLESTEP\fR
+.RS 4
+Setting this variable to
+on
+is equivalent to the command line option
+\fB\-s\fR\&.
+.RE
+.PP
+\fISQLSTATE\fR
+.RS 4
+The error code (see
+Appendix\ \&A) associated with the last SQL query\*(Aqs failure, or
+00000
+if it succeeded\&.
+.RE
+.PP
+\fIUSER\fR
+.RS 4
+The database user you are currently connected as\&. This is set every time you connect to a database (including program start\-up), but can be changed or unset\&.
+.RE
+.PP
+\fIVERBOSITY\fR
+.RS 4
+This variable can be set to the values
+default,
+verbose,
+terse, or
+sqlstate
+to control the verbosity of error reports\&. (See also
+\fB\eerrverbose\fR, for use when you want a verbose version of the error you just got\&.)
+.RE
+.PP
+\fIVERSION\fR
+.br
+\fIVERSION_NAME\fR
+.br
+\fIVERSION_NUM\fR
+.RS 4
+These variables are set at program start\-up to reflect
+psql\*(Aqs version, respectively as a verbose string, a short string (e\&.g\&.,
+9\&.6\&.2,
+10\&.1, or
+11beta1), and a number (e\&.g\&.,
+90602
+or
+100001)\&. They can be changed or unset\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBSQL Interpolation\fR
+.RS 4
+.PP
+A key feature of
+psql
+variables is that you can substitute (\(lqinterpolate\(rq) them into regular
+SQL
+statements, as well as the arguments of meta\-commands\&. Furthermore,
+psql
+provides facilities for ensuring that variable values used as SQL literals and identifiers are properly quoted\&. The syntax for interpolating a value without any quoting is to prepend the variable name with a colon (:)\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\eset foo \*(Aqmy_table\*(Aq\fR
+testdb=> \fBSELECT * FROM :foo;\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+would query the table
+my_table\&. Note that this may be unsafe: the value of the variable is copied literally, so it can contain unbalanced quotes, or even backslash commands\&. You must make sure that it makes sense where you put it\&.
+.PP
+When a value is to be used as an SQL literal or identifier, it is safest to arrange for it to be quoted\&. To quote the value of a variable as an SQL literal, write a colon followed by the variable name in single quotes\&. To quote the value as an SQL identifier, write a colon followed by the variable name in double quotes\&. These constructs deal correctly with quotes and other special characters embedded within the variable value\&. The previous example would be more safely written this way:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\eset foo \*(Aqmy_table\*(Aq\fR
+testdb=> \fBSELECT * FROM :"foo";\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Variable interpolation will not be performed within quoted
+SQL
+literals and identifiers\&. Therefore, a construction such as
+\*(Aq:foo\*(Aq
+doesn\*(Aqt work to produce a quoted literal from a variable\*(Aqs value (and it would be unsafe if it did work, since it wouldn\*(Aqt correctly handle quotes embedded in the value)\&.
+.PP
+One example use of this mechanism is to copy the contents of a file into a table column\&. First load the file into a variable and then interpolate the variable\*(Aqs value as a quoted string:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\eset content `cat my_file\&.txt`\fR
+testdb=> \fBINSERT INTO my_table VALUES (:\*(Aqcontent\*(Aq);\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(Note that this still won\*(Aqt work if
+my_file\&.txt
+contains NUL bytes\&.
+psql
+does not support embedded NUL bytes in variable values\&.)
+.PP
+Since colons can legally appear in SQL commands, an apparent attempt at interpolation (that is,
+:name,
+:\*(Aqname\*(Aq, or
+:"name") is not replaced unless the named variable is currently set\&. In any case, you can escape a colon with a backslash to protect it from substitution\&.
+.PP
+The
+:{?\fIname\fR}
+special syntax returns TRUE or FALSE depending on whether the variable exists or not, and is thus always substituted, unless the colon is backslash\-escaped\&.
+.PP
+The colon syntax for variables is standard
+SQL
+for embedded query languages, such as
+ECPG\&. The colon syntaxes for array slices and type casts are
+PostgreSQL
+extensions, which can sometimes conflict with the standard usage\&. The colon\-quote syntax for escaping a variable\*(Aqs value as an SQL literal or identifier is a
+psql
+extension\&.
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBPrompting\fR
+.RS 4
+.PP
+The prompts
+psql
+issues can be customized to your preference\&. The three variables
+\fIPROMPT1\fR,
+\fIPROMPT2\fR, and
+\fIPROMPT3\fR
+contain strings and special escape sequences that describe the appearance of the prompt\&. Prompt 1 is the normal prompt that is issued when
+psql
+requests a new command\&. Prompt 2 is issued when more input is expected during command entry, for example because the command was not terminated with a semicolon or a quote was not closed\&. Prompt 3 is issued when you are running an
+SQL
+\fBCOPY FROM STDIN\fR
+command and you need to type in a row value on the terminal\&.
+.PP
+The value of the selected prompt variable is printed literally, except where a percent sign (%) is encountered\&. Depending on the next character, certain other text is substituted instead\&. Defined substitutions are:
+.PP
+%M
+.RS 4
+The full host name (with domain name) of the database server, or
+[local]
+if the connection is over a Unix domain socket, or
+[local:\fI/dir/name\fR], if the Unix domain socket is not at the compiled in default location\&.
+.RE
+.PP
+%m
+.RS 4
+The host name of the database server, truncated at the first dot, or
+[local]
+if the connection is over a Unix domain socket\&.
+.RE
+.PP
+%>
+.RS 4
+The port number at which the database server is listening\&.
+.RE
+.PP
+%n
+.RS 4
+The database session user name\&. (The expansion of this value might change during a database session as the result of the command
+\fBSET SESSION AUTHORIZATION\fR\&.)
+.RE
+.PP
+%/
+.RS 4
+The name of the current database\&.
+.RE
+.PP
+%~
+.RS 4
+Like
+%/, but the output is
+~
+(tilde) if the database is your default database\&.
+.RE
+.PP
+%#
+.RS 4
+If the session user is a database superuser, then a
+#, otherwise a
+>\&. (The expansion of this value might change during a database session as the result of the command
+\fBSET SESSION AUTHORIZATION\fR\&.)
+.RE
+.PP
+%p
+.RS 4
+The process ID of the backend currently connected to\&.
+.RE
+.PP
+%R
+.RS 4
+In prompt 1 normally
+=, but
+@
+if the session is in an inactive branch of a conditional block, or
+^
+if in single\-line mode, or
+!
+if the session is disconnected from the database (which can happen if
+\fB\econnect\fR
+fails)\&. In prompt 2
+%R
+is replaced by a character that depends on why
+psql
+expects more input:
+\-
+if the command simply wasn\*(Aqt terminated yet, but
+*
+if there is an unfinished
+/* \&.\&.\&. */
+comment, a single quote if there is an unfinished quoted string, a double quote if there is an unfinished quoted identifier, a dollar sign if there is an unfinished dollar\-quoted string, or
+(
+if there is an unmatched left parenthesis\&. In prompt 3
+%R
+doesn\*(Aqt produce anything\&.
+.RE
+.PP
+%x
+.RS 4
+Transaction status: an empty string when not in a transaction block, or
+*
+when in a transaction block, or
+!
+when in a failed transaction block, or
+?
+when the transaction state is indeterminate (for example, because there is no connection)\&.
+.RE
+.PP
+%l
+.RS 4
+The line number inside the current statement, starting from
+1\&.
+.RE
+.PP
+%\fIdigits\fR
+.RS 4
+The character with the indicated octal code is substituted\&.
+.RE
+.PP
+%:\fIname\fR:
+.RS 4
+The value of the
+psql
+variable
+\fIname\fR\&. See
+Variables, above, for details\&.
+.RE
+.PP
+%`\fIcommand\fR`
+.RS 4
+The output of
+\fIcommand\fR, similar to ordinary
+\(lqback\-tick\(rq
+substitution\&.
+.RE
+.PP
+%[ \&.\&.\&. %]
+.RS 4
+Prompts can contain terminal control characters which, for example, change the color, background, or style of the prompt text, or change the title of the terminal window\&. In order for the line editing features of
+Readline
+to work properly, these non\-printing control characters must be designated as invisible by surrounding them with
+%[
+and
+%]\&. Multiple pairs of these can occur within the prompt\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \eset PROMPT1 \*(Aq%[%033[1;33;40m%]%n@%/%R%[%033[0m%]%# \*(Aq
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+results in a boldfaced (1;) yellow\-on\-black (33;40) prompt on VT100\-compatible, color\-capable terminals\&.
+.RE
+.PP
+%w
+.RS 4
+Whitespace of the same width as the most recent output of
+\fIPROMPT1\fR\&. This can be used as a
+\fIPROMPT2\fR
+setting, so that multi\-line statements are aligned with the first line, but there is no visible secondary prompt\&.
+.RE
+To insert a percent sign into your prompt, write
+%%\&. The default prompts are
+\*(Aq%/%R%x%# \*(Aq
+for prompts 1 and 2, and
+\*(Aq>> \*(Aq
+for prompt 3\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+This feature was shamelessly plagiarized from
+tcsh\&.
+.sp .5v
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCommand-Line Editing\fR
+.RS 4
+.PP
+psql
+uses the
+Readline
+or
+libedit
+library, if available, for convenient line editing and retrieval\&. The command history is automatically saved when
+psql
+exits and is reloaded when
+psql
+starts up\&. Type up\-arrow or control\-P to retrieve previous lines\&.
+.PP
+You can also use tab completion to fill in partially\-typed keywords and SQL object names in many (by no means all) contexts\&. For example, at the start of a command, typing
+ins
+and pressing TAB will fill in
+insert into\&. Then, typing a few characters of a table or schema name and pressing
+TAB
+will fill in the unfinished name, or offer a menu of possible completions when there\*(Aqs more than one\&. (Depending on the library in use, you may need to press
+TAB
+more than once to get a menu\&.)
+.PP
+Tab completion for SQL object names requires sending queries to the server to find possible matches\&. In some contexts this can interfere with other operations\&. For example, after
+\fBBEGIN\fR
+it will be too late to issue
+\fBSET TRANSACTION ISOLATION LEVEL\fR
+if a tab\-completion query is issued in between\&. If you do not want tab completion at all, you can turn it off permanently by putting this in a file named
+\&.inputrc
+in your home directory:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$if psql
+set disable\-completion on
+$endif
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(This is not a
+psql
+but a
+Readline
+feature\&. Read its documentation for further details\&.)
+.PP
+The
+\fB\-n\fR
+(\fB\-\-no\-readline\fR) command line option can also be useful to disable use of
+Readline
+for a single run of
+psql\&. This prevents tab completion, use or recording of command line history, and editing of multi\-line commands\&. It is particularly useful when you need to copy\-and\-paste text that contains
+TAB
+characters\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBCOLUMNS\fR
+.RS 4
+If
+\epset columns
+is zero, controls the width for the
+wrapped
+format and width for determining if wide output requires the pager or should be switched to the vertical format in expanded auto mode\&.
+.RE
+.PP
+\fBPGDATABASE\fR
+.br
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters (see
+Section\ \&34.15)\&.
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+\fBPSQL_EDITOR\fR
+.br
+\fBEDITOR\fR
+.br
+\fBVISUAL\fR
+.RS 4
+Editor used by the
+\fB\ee\fR,
+\fB\eef\fR, and
+\fB\eev\fR
+commands\&. These variables are examined in the order listed; the first that is set is used\&. If none of them is set, the default is to use
+vi
+on Unix systems or
+notepad\&.exe
+on Windows systems\&.
+.RE
+.PP
+\fBPSQL_EDITOR_LINENUMBER_ARG\fR
+.RS 4
+When
+\fB\ee\fR,
+\fB\eef\fR, or
+\fB\eev\fR
+is used with a line number argument, this variable specifies the command\-line argument used to pass the starting line number to the user\*(Aqs editor\&. For editors such as
+Emacs
+or
+vi, this is a plus sign\&. Include a trailing space in the value of the variable if there needs to be space between the option name and the line number\&. Examples:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+PSQL_EDITOR_LINENUMBER_ARG=\*(Aq+\*(Aq
+PSQL_EDITOR_LINENUMBER_ARG=\*(Aq\-\-line \*(Aq
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The default is
++
+on Unix systems (corresponding to the default editor
+vi, and useful for many other common editors); but there is no default on Windows systems\&.
+.RE
+.PP
+\fBPSQL_HISTORY\fR
+.RS 4
+Alternative location for the command history file\&. Tilde (~) expansion is performed\&.
+.RE
+.PP
+\fBPSQL_PAGER\fR
+.br
+\fBPAGER\fR
+.RS 4
+If a query\*(Aqs results do not fit on the screen, they are piped through this command\&. Typical values are
+more
+or
+less\&. Use of the pager can be disabled by setting
+\fBPSQL_PAGER\fR
+or
+\fBPAGER\fR
+to an empty string, or by adjusting the pager\-related options of the
+\fB\epset\fR
+command\&. These variables are examined in the order listed; the first that is set is used\&. If neither of them is set, the default is to use
+more
+on most platforms, but
+less
+on Cygwin\&.
+.RE
+.PP
+\fBPSQL_WATCH_PAGER\fR
+.RS 4
+When a query is executed repeatedly with the
+\fB\ewatch\fR
+command, a pager is not used by default\&. This behavior can be changed by setting
+\fBPSQL_WATCH_PAGER\fR
+to a pager command, on Unix systems\&. The
+pspg
+pager (not part of
+PostgreSQL
+but available in many open source software distributions) can display the output of
+\fB\ewatch\fR
+if started with the option
+\-\-stream\&.
+.RE
+.PP
+\fBPSQLRC\fR
+.RS 4
+Alternative location of the user\*(Aqs
+\&.psqlrc
+file\&. Tilde (~) expansion is performed\&.
+.RE
+.PP
+\fBSHELL\fR
+.RS 4
+Command executed by the
+\fB\e!\fR
+command\&.
+.RE
+.PP
+\fBTMPDIR\fR
+.RS 4
+Directory for storing temporary files\&. The default is
+/tmp\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "FILES"
+.PP
+psqlrc and ~/\&.psqlrc
+.RS 4
+Unless it is passed an
+\fB\-X\fR
+option,
+psql
+attempts to read and execute commands from the system\-wide startup file (psqlrc) and then the user\*(Aqs personal startup file (~/\&.psqlrc), after connecting to the database but before accepting normal commands\&. These files can be used to set up the client and/or the server to taste, typically with
+\fB\eset\fR
+and
+\fBSET\fR
+commands\&.
+.sp
+The system\-wide startup file is named
+psqlrc\&. By default it is sought in the installation\*(Aqs
+\(lqsystem configuration\(rq
+directory, which is most reliably identified by running
+pg_config \-\-sysconfdir\&. Typically this directory will be
+\&.\&./etc/
+relative to the directory containing the
+PostgreSQL
+executables\&. The directory to look in can be set explicitly via the
+\fBPGSYSCONFDIR\fR
+environment variable\&.
+.sp
+The user\*(Aqs personal startup file is named
+\&.psqlrc
+and is sought in the invoking user\*(Aqs home directory\&. On Windows the personal startup file is instead named
+%APPDATA%\epostgresql\epsqlrc\&.conf\&. In either case, this default file path can be overridden by setting the
+\fBPSQLRC\fR
+environment variable\&.
+.sp
+Both the system\-wide startup file and the user\*(Aqs personal startup file can be made
+psql\-version\-specific by appending a dash and the
+PostgreSQL
+major or minor release identifier to the file name, for example
+~/\&.psqlrc\-15
+or
+~/\&.psqlrc\-15\&.4\&. The most specific version\-matching file will be read in preference to a non\-version\-specific file\&. These version suffixes are added after determining the file path as explained above\&.
+.RE
+.PP
+\&.psql_history
+.RS 4
+The command\-line history is stored in the file
+~/\&.psql_history, or
+%APPDATA%\epostgresql\epsql_history
+on Windows\&.
+.sp
+The location of the history file can be set explicitly via the
+\fIHISTFILE\fR
+psql
+variable or the
+\fBPSQL_HISTORY\fR
+environment variable\&.
+.RE
+.SH "NOTES"
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+psql
+works best with servers of the same or an older major version\&. Backslash commands are particularly likely to fail if the server is of a newer version than
+psql
+itself\&. However, backslash commands of the
+\ed
+family should work with servers of versions back to 9\&.2, though not necessarily with servers newer than
+psql
+itself\&. The general functionality of running SQL commands and displaying query results should also work with servers of a newer major version, but this cannot be guaranteed in all cases\&.
+.sp
+If you want to use
+psql
+to connect to several servers of different major versions, it is recommended that you use the newest version of
+psql\&. Alternatively, you can keep around a copy of
+psql
+from each major version and be sure to use the version that matches the respective server\&. But in practice, this additional complication should not be necessary\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Before
+PostgreSQL
+9\&.6, the
+\fB\-c\fR
+option implied
+\fB\-X\fR
+(\fB\-\-no\-psqlrc\fR); this is no longer the case\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Before
+PostgreSQL
+8\&.4,
+psql
+allowed the first argument of a single\-letter backslash command to start directly after the command, without intervening whitespace\&. Now, some whitespace is required\&.
+.RE
+.SH "NOTES FOR WINDOWS USERS"
+.PP
+psql
+is built as a
+\(lqconsole application\(rq\&. Since the Windows console windows use a different encoding than the rest of the system, you must take special care when using 8\-bit characters within
+psql\&. If
+psql
+detects a problematic console code page, it will warn you at startup\&. To change the console code page, two things are necessary:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Set the code page by entering
+\fBcmd\&.exe /c chcp 1252\fR\&. (1252 is a code page that is appropriate for German; replace it with your value\&.) If you are using Cygwin, you can put this command in
+/etc/profile\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Set the console font to
+Lucida Console, because the raster font does not work with the ANSI code page\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The first example shows how to spread a command over several lines of input\&. Notice the changing prompt:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fBCREATE TABLE my_table (\fR
+testdb(> \fB first integer not null default 0,\fR
+testdb(> \fB second text)\fR
+testdb\-> \fB;\fR
+CREATE TABLE
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Now look at the table definition again:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\ed my_table\fR
+ Table "public\&.my_table"
+ Column | Type | Collation | Nullable | Default
+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-
+ first | integer | | not null | 0
+ second | text | | |
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Now we change the prompt to something more interesting:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\eset PROMPT1 \*(Aq%n@%m %~%R%# \*(Aq\fR
+peter@localhost testdb=>
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Let\*(Aqs assume you have filled the table with data and want to take a look at it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+peter@localhost testdb=> SELECT * FROM my_table;
+ first | second
+\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+(4 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+You can display tables in different ways by using the
+\fB\epset\fR
+command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+peter@localhost testdb=> \fB\epset border 2\fR
+Border style is 2\&.
+peter@localhost testdb=> \fBSELECT * FROM my_table;\fR
++\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+
+| first | second |
++\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+
+| 1 | one |
+| 2 | two |
+| 3 | three |
+| 4 | four |
++\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+
+(4 rows)
+
+peter@localhost testdb=> \fB\epset border 0\fR
+Border style is 0\&.
+peter@localhost testdb=> \fBSELECT * FROM my_table;\fR
+first second
+\-\-\-\-\- \-\-\-\-\-\-
+ 1 one
+ 2 two
+ 3 three
+ 4 four
+(4 rows)
+
+peter@localhost testdb=> \fB\epset border 1\fR
+Border style is 1\&.
+peter@localhost testdb=> \fB\epset format csv\fR
+Output format is csv\&.
+peter@localhost testdb=> \fB\epset tuples_only\fR
+Tuples only is on\&.
+peter@localhost testdb=> \fBSELECT second, first FROM my_table;\fR
+one,1
+two,2
+three,3
+four,4
+peter@localhost testdb=> \fB\epset format unaligned\fR
+Output format is unaligned\&.
+peter@localhost testdb=> \fB\epset fieldsep \*(Aq\et\*(Aq\fR
+Field separator is " "\&.
+peter@localhost testdb=> \fBSELECT second, first FROM my_table;\fR
+one 1
+two 2
+three 3
+four 4
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Alternatively, use the short commands:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+peter@localhost testdb=> \fB\ea \et \ex\fR
+Output format is aligned\&.
+Tuples only is off\&.
+Expanded display is on\&.
+peter@localhost testdb=> \fBSELECT * FROM my_table;\fR
+\-[ RECORD 1 ]\-
+first | 1
+second | one
+\-[ RECORD 2 ]\-
+first | 2
+second | two
+\-[ RECORD 3 ]\-
+first | 3
+second | three
+\-[ RECORD 4 ]\-
+first | 4
+second | four
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Also, these output format options can be set for just one query by using
+\eg:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+peter@localhost testdb=> \fBSELECT * FROM my_table\fR
+peter@localhost testdb\-> \fB\eg (format=aligned tuples_only=off expanded=on)\fR
+\-[ RECORD 1 ]\-
+first | 1
+second | one
+\-[ RECORD 2 ]\-
+first | 2
+second | two
+\-[ RECORD 3 ]\-
+first | 3
+second | three
+\-[ RECORD 4 ]\-
+first | 4
+second | four
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is an example of using the
+\fB\edf\fR
+command to find only functions with names matching
+int*pl
+and whose second argument is of type
+bigint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fB\edf int*pl * bigint\fR
+ List of functions
+ Schema | Name | Result data type | Argument data types | Type
+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-
+ pg_catalog | int28pl | bigint | smallint, bigint | func
+ pg_catalog | int48pl | bigint | integer, bigint | func
+ pg_catalog | int8pl | bigint | bigint, bigint | func
+(3 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+When suitable, query results can be shown in a crosstab representation with the
+\fB\ecrosstabview\fR
+command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fBSELECT first, second, first > 2 AS gt2 FROM my_table;\fR
+ first | second | gt2
+\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-
+ 1 | one | f
+ 2 | two | f
+ 3 | three | t
+ 4 | four | t
+(4 rows)
+
+testdb=> \fB\ecrosstabview first second\fR
+ first | one | two | three | four
+\-\-\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-\-\-+\-\-\-\-\-\-
+ 1 | f | | |
+ 2 | | f | |
+ 3 | | | t |
+ 4 | | | | t
+(4 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This second example shows a multiplication table with rows sorted in reverse numerical order and columns with an independent, ascending numerical order\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+testdb=> \fBSELECT t1\&.first as "A", t2\&.first+100 AS "B", t1\&.first*(t2\&.first+100) as "AxB",\fR
+testdb(> \fBrow_number() over(order by t2\&.first) AS ord\fR
+testdb(> \fBFROM my_table t1 CROSS JOIN my_table t2 ORDER BY 1 DESC\fR
+testdb(> \fB\ecrosstabview "A" "B" "AxB" ord\fR
+ A | 101 | 102 | 103 | 104
+\-\-\-+\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-
+ 4 | 404 | 408 | 412 | 416
+ 3 | 303 | 306 | 309 | 312
+ 2 | 202 | 204 | 206 | 208
+ 1 | 101 | 102 | 103 | 104
+(4 rows)
+.fi
+.if n \{\
+.RE
+.\}
+
diff --git a/doc/src/sgml/man1/reindexdb.1 b/doc/src/sgml/man1/reindexdb.1
new file mode 100644
index 0000000..8d677a2
--- /dev/null
+++ b/doc/src/sgml/man1/reindexdb.1
@@ -0,0 +1,330 @@
+'\" t
+.\" Title: reindexdb
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "REINDEXDB" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+reindexdb \- reindex a PostgreSQL database
+.SH "SYNOPSIS"
+.HP \w'\fBreindexdb\fR\ 'u
+\fBreindexdb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\ \fB\-S\fR\ |\ \fB\-\-schema\fR\ \fIschema\fR\ ]... [\ \fB\-t\fR\ |\ \fB\-\-table\fR\ \fItable\fR\ ]... [\ \fB\-i\fR\ |\ \fB\-\-index\fR\ \fIindex\fR\ ]... [\fIdbname\fR]
+.HP \w'\fBreindexdb\fR\ 'u
+\fBreindexdb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] \fB\-a\fR | \fB\-\-all\fR
+.HP \w'\fBreindexdb\fR\ 'u
+\fBreindexdb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] \fB\-s\fR | \fB\-\-system\fR [\fIdbname\fR]
+.SH "DESCRIPTION"
+.PP
+reindexdb
+is a utility for rebuilding indexes in a
+PostgreSQL
+database\&.
+.PP
+reindexdb
+is a wrapper around the SQL command
+\fBREINDEX\fR\&. There is no effective difference between reindexing databases via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+reindexdb
+accepts the following command\-line arguments:
+.PP
+\fB\-a\fR
+.br
+\fB\-\-all\fR
+.RS 4
+Reindex all databases\&.
+.RE
+.PP
+\fB\-\-concurrently\fR
+.RS 4
+Use the
+CONCURRENTLY
+option\&. See
+\fBREINDEX\fR(7), where all the caveats of this option are explained in detail\&.
+.RE
+.PP
+\fB[\-d]\fR\fB \fR\fB\fIdbname\fR\fR
+.br
+\fB[\-\-dbname=]\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to be reindexed, when
+\fB\-a\fR/\fB\-\-all\fR
+is not used\&. If this is not specified, the database name is read from the environment variable
+\fBPGDATABASE\fR\&. If that is not set, the user name specified for the connection is used\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+reindexdb
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-i \fR\fB\fIindex\fR\fR
+.br
+\fB\-\-index=\fR\fB\fIindex\fR\fR
+.RS 4
+Recreate
+\fIindex\fR
+only\&. Multiple indexes can be recreated by writing multiple
+\fB\-i\fR
+switches\&.
+.RE
+.PP
+\fB\-j \fR\fB\fInjobs\fR\fR
+.br
+\fB\-\-jobs=\fR\fB\fInjobs\fR\fR
+.RS 4
+Execute the reindex commands in parallel by running
+\fInjobs\fR
+commands simultaneously\&. This option may reduce the processing time but it also increases the load on the database server\&.
+.sp
+reindexdb
+will open
+\fInjobs\fR
+connections to the database, so make sure your
+max_connections
+setting is high enough to accommodate all connections\&.
+.sp
+Note that this option is incompatible with the
+\fB\-\-index\fR
+and
+\fB\-\-system\fR
+options\&.
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Do not display progress messages\&.
+.RE
+.PP
+\fB\-s\fR
+.br
+\fB\-\-system\fR
+.RS 4
+Reindex database\*(Aqs system catalogs only\&.
+.RE
+.PP
+\fB\-S \fR\fB\fIschema\fR\fR
+.br
+\fB\-\-schema=\fR\fB\fIschema\fR\fR
+.RS 4
+Reindex
+\fIschema\fR
+only\&. Multiple schemas can be reindexed by writing multiple
+\fB\-S\fR
+switches\&.
+.RE
+.PP
+\fB\-t \fR\fB\fItable\fR\fR
+.br
+\fB\-\-table=\fR\fB\fItable\fR\fR
+.RS 4
+Reindex
+\fItable\fR
+only\&. Multiple tables can be reindexed by writing multiple
+\fB\-t\fR
+switches\&.
+.RE
+.PP
+\fB\-\-tablespace=\fR\fB\fItablespace\fR\fR
+.RS 4
+Specifies the tablespace where indexes are rebuilt\&. (This name is processed as a double\-quoted identifier\&.)
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Print detailed information during processing\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+reindexdb
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+reindexdb
+command line arguments, and exit\&.
+.RE
+.PP
+reindexdb
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+reindexdb
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+reindexdb
+will automatically prompt for a password if the server demands password authentication\&. However,
+reindexdb
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-maintenance\-db=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to to discover which databases should be reindexed, when
+\fB\-a\fR/\fB\-\-all\fR
+is used\&. If not specified, the
+postgres
+database will be used, or if that does not exist,
+template1
+will be used\&. This can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&. Also, connection string parameters other than the database name itself will be re\-used when connecting to other databases\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATABASE\fR
+.br
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+\fBREINDEX\fR(7)
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "NOTES"
+.PP
+reindexdb
+might need to connect several times to the
+PostgreSQL
+server, asking for a password each time\&. It is convenient to have a
+~/\&.pgpass
+file in such cases\&. See
+Section\ \&34.16
+for more information\&.
+.SH "EXAMPLES"
+.PP
+To reindex the database
+test:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBreindexdb test\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To reindex the table
+foo
+and the index
+bar
+in a database named
+abcd:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBreindexdb \-\-table=foo \-\-index=bar abcd\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBREINDEX\fR(7)
diff --git a/doc/src/sgml/man1/vacuumdb.1 b/doc/src/sgml/man1/vacuumdb.1
new file mode 100644
index 0000000..bcbe5e9
--- /dev/null
+++ b/doc/src/sgml/man1/vacuumdb.1
@@ -0,0 +1,584 @@
+'\" t
+.\" Title: vacuumdb
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "VACUUMDB" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+vacuumdb \- garbage\-collect and analyze a PostgreSQL database
+.SH "SYNOPSIS"
+.HP \w'\fBvacuumdb\fR\ 'u
+\fBvacuumdb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] [\ \fB\-t\fR\ |\ \fB\-\-table\fR\ \fItable\fR\ [(\ \fIcolumn\fR\ [,\&.\&.\&.]\ )]\ ]... [\fIdbname\fR]
+.HP \w'\fBvacuumdb\fR\ 'u
+\fBvacuumdb\fR [\fIconnection\-option\fR...] [\fIoption\fR...] \fB\-a\fR | \fB\-\-all\fR
+.SH "DESCRIPTION"
+.PP
+vacuumdb
+is a utility for cleaning a
+PostgreSQL
+database\&.
+vacuumdb
+will also generate internal statistics used by the
+PostgreSQL
+query optimizer\&.
+.PP
+vacuumdb
+is a wrapper around the SQL command
+\fBVACUUM\fR\&. There is no effective difference between vacuuming and analyzing databases via this utility and via other methods for accessing the server\&.
+.SH "OPTIONS"
+.PP
+vacuumdb
+accepts the following command\-line arguments:
+.PP
+\fB\-a\fR
+.br
+\fB\-\-all\fR
+.RS 4
+Vacuum all databases\&.
+.RE
+.PP
+\fB[\-d]\fR\fB \fR\fB\fIdbname\fR\fR
+.br
+\fB[\-\-dbname=]\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to be cleaned or analyzed, when
+\fB\-a\fR/\fB\-\-all\fR
+is not used\&. If this is not specified, the database name is read from the environment variable
+\fBPGDATABASE\fR\&. If that is not set, the user name specified for the connection is used\&. The
+\fIdbname\fR
+can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&.
+.RE
+.PP
+\fB\-\-disable\-page\-skipping\fR
+.RS 4
+Disable skipping pages based on the contents of the visibility map\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+9\&.6 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-e\fR
+.br
+\fB\-\-echo\fR
+.RS 4
+Echo the commands that
+vacuumdb
+generates and sends to the server\&.
+.RE
+.PP
+\fB\-f\fR
+.br
+\fB\-\-full\fR
+.RS 4
+Perform
+\(lqfull\(rq
+vacuuming\&.
+.RE
+.PP
+\fB\-F\fR
+.br
+\fB\-\-freeze\fR
+.RS 4
+Aggressively
+\(lqfreeze\(rq
+tuples\&.
+.RE
+.PP
+\fB\-\-force\-index\-cleanup\fR
+.RS 4
+Always remove index entries pointing to dead tuples\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+12 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-j \fR\fB\fInjobs\fR\fR
+.br
+\fB\-\-jobs=\fR\fB\fInjobs\fR\fR
+.RS 4
+Execute the vacuum or analyze commands in parallel by running
+\fInjobs\fR
+commands simultaneously\&. This option may reduce the processing time but it also increases the load on the database server\&.
+.sp
+vacuumdb
+will open
+\fInjobs\fR
+connections to the database, so make sure your
+max_connections
+setting is high enough to accommodate all connections\&.
+.sp
+Note that using this mode together with the
+\fB\-f\fR
+(FULL) option might cause deadlock failures if certain system catalogs are processed in parallel\&.
+.RE
+.PP
+\fB\-\-min\-mxid\-age \fR\fB\fImxid_age\fR\fR
+.RS 4
+Only execute the vacuum or analyze commands on tables with a multixact ID age of at least
+\fImxid_age\fR\&. This setting is useful for prioritizing tables to process to prevent multixact ID wraparound (see
+Section\ \&25.1.5.1)\&.
+.sp
+For the purposes of this option, the multixact ID age of a relation is the greatest of the ages of the main relation and its associated
+TOAST
+table, if one exists\&. Since the commands issued by
+vacuumdb
+will also process the
+TOAST
+table for the relation if necessary, it does not need to be considered separately\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+9\&.6 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-\-min\-xid\-age \fR\fB\fIxid_age\fR\fR
+.RS 4
+Only execute the vacuum or analyze commands on tables with a transaction ID age of at least
+\fIxid_age\fR\&. This setting is useful for prioritizing tables to process to prevent transaction ID wraparound (see
+Section\ \&25.1.5)\&.
+.sp
+For the purposes of this option, the transaction ID age of a relation is the greatest of the ages of the main relation and its associated
+TOAST
+table, if one exists\&. Since the commands issued by
+vacuumdb
+will also process the
+TOAST
+table for the relation if necessary, it does not need to be considered separately\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+9\&.6 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-\-no\-index\-cleanup\fR
+.RS 4
+Do not remove index entries pointing to dead tuples\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+12 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-\-no\-process\-toast\fR
+.RS 4
+Skip the TOAST table associated with the table to vacuum, if any\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+14 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-\-no\-truncate\fR
+.RS 4
+Do not truncate empty pages at the end of the table\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+12 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-P \fR\fB\fIparallel_workers\fR\fR
+.br
+\fB\-\-parallel=\fR\fB\fIparallel_workers\fR\fR
+.RS 4
+Specify the number of parallel workers for
+parallel vacuum\&. This allows the vacuum to leverage multiple CPUs to process indexes\&. See
+\fBVACUUM\fR(7)\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+13 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-q\fR
+.br
+\fB\-\-quiet\fR
+.RS 4
+Do not display progress messages\&.
+.RE
+.PP
+\fB\-\-skip\-locked\fR
+.RS 4
+Skip relations that cannot be immediately locked for processing\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+This option is only available for servers running
+PostgreSQL
+12 and later\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-t \fR\fB\fItable\fR\fR\fB [ (\fR\fB\fIcolumn\fR\fR\fB [,\&.\&.\&.]) ]\fR
+.br
+\fB\-\-table=\fR\fB\fItable\fR\fR\fB [ (\fR\fB\fIcolumn\fR\fR\fB [,\&.\&.\&.]) ]\fR
+.RS 4
+Clean or analyze
+\fItable\fR
+only\&. Column names can be specified only in conjunction with the
+\fB\-\-analyze\fR
+or
+\fB\-\-analyze\-only\fR
+options\&. Multiple tables can be vacuumed by writing multiple
+\fB\-t\fR
+switches\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+If you specify columns, you probably have to escape the parentheses from the shell\&. (See examples below\&.)
+.sp .5v
+.RE
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Print detailed information during processing\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+vacuumdb
+version and exit\&.
+.RE
+.PP
+\fB\-z\fR
+.br
+\fB\-\-analyze\fR
+.RS 4
+Also calculate statistics for use by the optimizer\&.
+.RE
+.PP
+\fB\-Z\fR
+.br
+\fB\-\-analyze\-only\fR
+.RS 4
+Only calculate statistics for use by the optimizer (no vacuum)\&.
+.RE
+.PP
+\fB\-\-analyze\-in\-stages\fR
+.RS 4
+Only calculate statistics for use by the optimizer (no vacuum), like
+\fB\-\-analyze\-only\fR\&. Run three stages of analyze; the first stage uses the lowest possible statistics target (see
+default_statistics_target) to produce usable statistics faster, and subsequent stages build the full statistics\&.
+.sp
+This option is only useful to analyze a database that currently has no statistics or has wholly incorrect ones, such as if it is newly populated from a restored dump or by
+\fBpg_upgrade\fR\&. Be aware that running with this option in a database with existing statistics may cause the query optimizer choices to become transiently worse due to the low statistics targets of the early stages\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+vacuumdb
+command line arguments, and exit\&.
+.RE
+.PP
+vacuumdb
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Specifies the host name of the machine on which the server is running\&. If the value begins with a slash, it is used as the directory for the Unix domain socket\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+vacuumdb
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+vacuumdb
+will automatically prompt for a password if the server demands password authentication\&. However,
+vacuumdb
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.PP
+\fB\-\-maintenance\-db=\fR\fB\fIdbname\fR\fR
+.RS 4
+Specifies the name of the database to connect to to discover which databases should be vacuumed, when
+\fB\-a\fR/\fB\-\-all\fR
+is used\&. If not specified, the
+postgres
+database will be used, or if that does not exist,
+template1
+will be used\&. This can be a
+connection string\&. If so, connection string parameters will override any conflicting command line options\&. Also, connection string parameters other than the database name itself will be re\-used when connecting to other databases\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGDATABASE\fR
+.br
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters
+.RE
+.PP
+\fBPG_COLOR\fR
+.RS 4
+Specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.SH "DIAGNOSTICS"
+.PP
+In case of difficulty, see
+\fBVACUUM\fR(7)
+and
+\fBpsql\fR(1)
+for discussions of potential problems and error messages\&. The database server must be running at the targeted host\&. Also, any default connection settings and environment variables used by the
+libpq
+front\-end library will apply\&.
+.SH "NOTES"
+.PP
+vacuumdb
+might need to connect several times to the
+PostgreSQL
+server, asking for a password each time\&. It is convenient to have a
+~/\&.pgpass
+file in such cases\&. See
+Section\ \&34.16
+for more information\&.
+.SH "EXAMPLES"
+.PP
+To clean the database
+test:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBvacuumdb test\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To clean and analyze for the optimizer a database named
+bigdb:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBvacuumdb \-\-analyze bigdb\fR
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To clean a single table
+foo
+in a database named
+xyzzy, and analyze a single column
+bar
+of the table for the optimizer:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBvacuumdb \-\-analyze \-\-verbose \-\-table=\*(Aqfoo(bar)\*(Aq xyzzy\fR
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+\fBVACUUM\fR(7)
diff --git a/doc/src/sgml/man1/vacuumlo.1 b/doc/src/sgml/man1/vacuumlo.1
new file mode 100644
index 0000000..81b8fdd
--- /dev/null
+++ b/doc/src/sgml/man1/vacuumlo.1
@@ -0,0 +1,190 @@
+'\" t
+.\" Title: vacuumlo
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "VACUUMLO" "1" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+vacuumlo \- remove orphaned large objects from a PostgreSQL database
+.SH "SYNOPSIS"
+.HP \w'\fBvacuumlo\fR\ 'u
+\fBvacuumlo\fR [\fIoption\fR...] \fIdbname\fR...
+.SH "DESCRIPTION"
+.PP
+vacuumlo
+is a simple utility program that will remove any
+\(lqorphaned\(rq
+large objects from a
+PostgreSQL
+database\&. An orphaned large object (LO) is considered to be any LO whose OID does not appear in any
+oid
+or
+lo
+data column of the database\&.
+.PP
+If you use this, you may also be interested in the
+\fBlo_manage\fR
+trigger in the
+lo
+module\&.
+\fBlo_manage\fR
+is useful to try to avoid creating orphaned LOs in the first place\&.
+.PP
+All databases named on the command line are processed\&.
+.SH "OPTIONS"
+.PP
+vacuumlo
+accepts the following command\-line arguments:
+.PP
+\fB\-l \fR\fB\fIlimit\fR\fR
+.br
+\fB\-\-limit=\fR\fB\fIlimit\fR\fR
+.RS 4
+Remove no more than
+\fIlimit\fR
+large objects per transaction (default 1000)\&. Since the server acquires a lock per LO removed, removing too many LOs in one transaction risks exceeding
+max_locks_per_transaction\&. Set the limit to zero if you want all removals done in a single transaction\&.
+.RE
+.PP
+\fB\-n\fR
+.br
+\fB\-\-dry\-run\fR
+.RS 4
+Don\*(Aqt remove anything, just show what would be done\&.
+.RE
+.PP
+\fB\-v\fR
+.br
+\fB\-\-verbose\fR
+.RS 4
+Write a lot of progress messages\&.
+.RE
+.PP
+\fB\-V\fR
+.br
+\fB\-\-version\fR
+.RS 4
+Print the
+vacuumlo
+version and exit\&.
+.RE
+.PP
+\fB\-?\fR
+.br
+\fB\-\-help\fR
+.RS 4
+Show help about
+vacuumlo
+command line arguments, and exit\&.
+.RE
+.PP
+vacuumlo
+also accepts the following command\-line arguments for connection parameters:
+.PP
+\fB\-h \fR\fB\fIhost\fR\fR
+.br
+\fB\-\-host=\fR\fB\fIhost\fR\fR
+.RS 4
+Database server\*(Aqs host\&.
+.RE
+.PP
+\fB\-p \fR\fB\fIport\fR\fR
+.br
+\fB\-\-port=\fR\fB\fIport\fR\fR
+.RS 4
+Database server\*(Aqs port\&.
+.RE
+.PP
+\fB\-U \fR\fB\fIusername\fR\fR
+.br
+\fB\-\-username=\fR\fB\fIusername\fR\fR
+.RS 4
+User name to connect as\&.
+.RE
+.PP
+\fB\-w\fR
+.br
+\fB\-\-no\-password\fR
+.RS 4
+Never issue a password prompt\&. If the server requires password authentication and a password is not available by other means such as a
+\&.pgpass
+file, the connection attempt will fail\&. This option can be useful in batch jobs and scripts where no user is present to enter a password\&.
+.RE
+.PP
+\fB\-W\fR
+.br
+\fB\-\-password\fR
+.RS 4
+Force
+vacuumlo
+to prompt for a password before connecting to a database\&.
+.sp
+This option is never essential, since
+vacuumlo
+will automatically prompt for a password if the server demands password authentication\&. However,
+vacuumlo
+will waste a connection attempt finding out that the server wants a password\&. In some cases it is worth typing
+\fB\-W\fR
+to avoid the extra connection attempt\&.
+.RE
+.SH "ENVIRONMENT"
+.PP
+\fBPGHOST\fR
+.br
+\fBPGPORT\fR
+.br
+\fBPGUSER\fR
+.RS 4
+Default connection parameters\&.
+.RE
+.PP
+This utility, like most other
+PostgreSQL
+utilities, also uses the environment variables supported by
+libpq
+(see
+Section\ \&34.15)\&.
+.PP
+The environment variable
+\fBPG_COLOR\fR
+specifies whether to use color in diagnostic messages\&. Possible values are
+always,
+auto
+and
+never\&.
+.SH "NOTES"
+.PP
+vacuumlo
+works by the following method: First,
+vacuumlo
+builds a temporary table which contains all of the OIDs of the large objects in the selected database\&. It then scans through all columns in the database that are of type
+oid
+or
+lo, and removes matching entries from the temporary table\&. (Note: Only types with these names are considered; in particular, domains over them are not considered\&.) The remaining entries in the temporary table identify orphaned LOs\&. These are removed\&.
+.SH "AUTHOR"
+.PP
+Peter Mount
+<peter@retep\&.org\&.uk>
diff --git a/doc/src/sgml/man3/SPI_commit.3 b/doc/src/sgml/man3/SPI_commit.3
new file mode 100644
index 0000000..2864a2b
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_commit.3
@@ -0,0 +1,52 @@
+'\" t
+.\" Title: SPI_commit
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_COMMIT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_commit, SPI_commit_and_chain \- commit the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_commit(void)
+.fi
+.sp
+.nf
+void SPI_commit_and_chain(void)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_commit\fR
+commits the current transaction\&. It is approximately equivalent to running the SQL command
+\fBCOMMIT\fR\&. After the transaction is committed, a new transaction is automatically started using default transaction characteristics, so that the caller can continue using SPI facilities\&. If there is a failure during commit, the current transaction is instead rolled back and a new transaction is started, after which the error is thrown in the usual way\&.
+.PP
+\fBSPI_commit_and_chain\fR
+is the same, but the new transaction is started with the same transaction characteristics as the just finished one, like with the SQL command
+\fBCOMMIT AND CHAIN\fR\&.
+.PP
+These functions can only be executed if the SPI connection has been set as nonatomic in the call to
+\fBSPI_connect_ext\fR\&.
diff --git a/doc/src/sgml/man3/SPI_commit_and_chain.3 b/doc/src/sgml/man3/SPI_commit_and_chain.3
new file mode 100644
index 0000000..c127b9c
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_commit_and_chain.3
@@ -0,0 +1 @@
+.so man3/SPI_commit.3
diff --git a/doc/src/sgml/man3/SPI_connect.3 b/doc/src/sgml/man3/SPI_connect.3
new file mode 100644
index 0000000..6db577f
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_connect.3
@@ -0,0 +1,69 @@
+'\" t
+.\" Title: SPI_connect
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CONNECT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_connect, SPI_connect_ext \- connect a C function to the SPI manager
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_connect(void)
+.fi
+.sp
+.nf
+int SPI_connect_ext(int \fIoptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_connect\fR
+opens a connection from a C function invocation to the SPI manager\&. You must call this function if you want to execute commands through SPI\&. Some utility SPI functions can be called from unconnected C functions\&.
+.PP
+\fBSPI_connect_ext\fR
+does the same but has an argument that allows passing option flags\&. Currently, the following option values are available:
+.PP
+SPI_OPT_NONATOMIC
+.RS 4
+Sets the SPI connection to be
+nonatomic, which means that transaction control calls (\fBSPI_commit\fR,
+\fBSPI_rollback\fR) are allowed\&. Otherwise, calling those functions will result in an immediate error\&.
+.RE
+.PP
+SPI_connect()
+is equivalent to
+SPI_connect_ext(0)\&.
+.SH "RETURN VALUE"
+.PP
+SPI_OK_CONNECT
+.RS 4
+on success
+.RE
+.PP
+SPI_ERROR_CONNECT
+.RS 4
+on error
+.RE
diff --git a/doc/src/sgml/man3/SPI_connect_ext.3 b/doc/src/sgml/man3/SPI_connect_ext.3
new file mode 100644
index 0000000..51f12f5
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_connect_ext.3
@@ -0,0 +1 @@
+.so man3/SPI_connect.3
diff --git a/doc/src/sgml/man3/SPI_copytuple.3 b/doc/src/sgml/man3/SPI_copytuple.3
new file mode 100644
index 0000000..9359947
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_copytuple.3
@@ -0,0 +1,60 @@
+'\" t
+.\" Title: SPI_copytuple
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_COPYTUPLE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_copytuple \- make a copy of a row in the upper executor context
+.SH "SYNOPSIS"
+.sp
+.nf
+HeapTuple SPI_copytuple(HeapTuple \fIrow\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_copytuple\fR
+makes a copy of a row in the upper executor context\&. This is normally used to return a modified row from a trigger\&. In a function declared to return a composite type, use
+\fBSPI_returntuple\fR
+instead\&.
+.PP
+This function can only be used while connected to SPI\&. Otherwise, it returns NULL and sets
+\fISPI_result\fR
+to
+SPI_ERROR_UNCONNECTED\&.
+.SH "ARGUMENTS"
+.PP
+HeapTuple \fIrow\fR
+.RS 4
+row to be copied
+.RE
+.SH "RETURN VALUE"
+.PP
+the copied row, or
+NULL
+on error (see
+\fISPI_result\fR
+for an error indication)
diff --git a/doc/src/sgml/man3/SPI_cursor_close.3 b/doc/src/sgml/man3/SPI_cursor_close.3
new file mode 100644
index 0000000..2a41364
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_close.3
@@ -0,0 +1,50 @@
+'\" t
+.\" Title: SPI_cursor_close
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_CLOSE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_close \- close a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_cursor_close(Portal \fIportal\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_close\fR
+closes a previously created cursor and releases its portal storage\&.
+.PP
+All open cursors are closed automatically at the end of a transaction\&.
+\fBSPI_cursor_close\fR
+need only be invoked if it is desirable to release resources sooner\&.
+.SH "ARGUMENTS"
+.PP
+Portal \fIportal\fR
+.RS 4
+portal containing the cursor
+.RE
diff --git a/doc/src/sgml/man3/SPI_cursor_fetch.3 b/doc/src/sgml/man3/SPI_cursor_fetch.3
new file mode 100644
index 0000000..496f1b3
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_fetch.3
@@ -0,0 +1,73 @@
+'\" t
+.\" Title: SPI_cursor_fetch
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_FETCH" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_fetch \- fetch some rows from a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_cursor_fetch(Portal \fIportal\fR, bool \fIforward\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_fetch\fR
+fetches some rows from a cursor\&. This is equivalent to a subset of the SQL command
+\fBFETCH\fR
+(see
+\fBSPI_scroll_cursor_fetch\fR
+for more functionality)\&.
+.SH "ARGUMENTS"
+.PP
+Portal \fIportal\fR
+.RS 4
+portal containing the cursor
+.RE
+.PP
+bool \fIforward\fR
+.RS 4
+true for fetch forward, false for fetch backward
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to fetch
+.RE
+.SH "RETURN VALUE"
+.PP
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute\fR
+if successful\&.
+.SH "NOTES"
+.PP
+Fetching backward may fail if the cursor\*(Aqs plan was not created with the
+CURSOR_OPT_SCROLL
+option\&.
diff --git a/doc/src/sgml/man3/SPI_cursor_find.3 b/doc/src/sgml/man3/SPI_cursor_find.3
new file mode 100644
index 0000000..a1a6f06
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_find.3
@@ -0,0 +1,51 @@
+'\" t
+.\" Title: SPI_cursor_find
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_FIND" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_find \- find an existing cursor by name
+.SH "SYNOPSIS"
+.sp
+.nf
+Portal SPI_cursor_find(const char * \fIname\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_find\fR
+finds an existing portal by name\&. This is primarily useful to resolve a cursor name returned as text by some other function\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIname\fR
+.RS 4
+name of the portal
+.RE
+.SH "RETURN VALUE"
+.PP
+pointer to the portal with the specified name, or
+NULL
+if none was found
diff --git a/doc/src/sgml/man3/SPI_cursor_move.3 b/doc/src/sgml/man3/SPI_cursor_move.3
new file mode 100644
index 0000000..b334feb
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_move.3
@@ -0,0 +1,65 @@
+'\" t
+.\" Title: SPI_cursor_move
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_MOVE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_move \- move a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_cursor_move(Portal \fIportal\fR, bool \fIforward\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_move\fR
+skips over some number of rows in a cursor\&. This is equivalent to a subset of the SQL command
+\fBMOVE\fR
+(see
+\fBSPI_scroll_cursor_move\fR
+for more functionality)\&.
+.SH "ARGUMENTS"
+.PP
+Portal \fIportal\fR
+.RS 4
+portal containing the cursor
+.RE
+.PP
+bool \fIforward\fR
+.RS 4
+true for move forward, false for move backward
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to move
+.RE
+.SH "NOTES"
+.PP
+Moving backward may fail if the cursor\*(Aqs plan was not created with the
+CURSOR_OPT_SCROLL
+option\&.
diff --git a/doc/src/sgml/man3/SPI_cursor_open.3 b/doc/src/sgml/man3/SPI_cursor_open.3
new file mode 100644
index 0000000..d801fde
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_open.3
@@ -0,0 +1,102 @@
+'\" t
+.\" Title: SPI_cursor_open
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_OPEN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_open \- set up a cursor using a statement created with \fBSPI_prepare\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+Portal SPI_cursor_open(const char * \fIname\fR, SPIPlanPtr \fIplan\fR,
+ Datum * \fIvalues\fR, const char * \fInulls\fR,
+ bool \fIread_only\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_open\fR
+sets up a cursor (internally, a portal) that will execute a statement prepared by
+\fBSPI_prepare\fR\&. The parameters have the same meanings as the corresponding parameters to
+\fBSPI_execute_plan\fR\&.
+.PP
+Using a cursor instead of executing the statement directly has two benefits\&. First, the result rows can be retrieved a few at a time, avoiding memory overrun for queries that return many rows\&. Second, a portal can outlive the current C function (it can, in fact, live to the end of the current transaction)\&. Returning the portal name to the C function\*(Aqs caller provides a way of returning a row set as result\&.
+.PP
+The passed\-in parameter data will be copied into the cursor\*(Aqs portal, so it can be freed while the cursor still exists\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIname\fR
+.RS 4
+name for portal, or
+NULL
+to let the system select a name
+.RE
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+Datum * \fIvalues\fR
+.RS 4
+An array of actual parameter values\&. Must have same length as the statement\*(Aqs number of arguments\&.
+.RE
+.PP
+const char * \fInulls\fR
+.RS 4
+An array describing which parameters are null\&. Must have same length as the statement\*(Aqs number of arguments\&.
+.sp
+If
+\fInulls\fR
+is
+NULL
+then
+\fBSPI_cursor_open\fR
+assumes that no parameters are null\&. Otherwise, each entry of the
+\fInulls\fR
+array should be
+\*(Aq\ \&\*(Aq
+if the corresponding parameter value is non\-null, or
+\*(Aqn\*(Aq
+if the corresponding parameter value is null\&. (In the latter case, the actual value in the corresponding
+\fIvalues\fR
+entry doesn\*(Aqt matter\&.) Note that
+\fInulls\fR
+is not a text string, just an array: it does not need a
+\*(Aq\e0\*(Aq
+terminator\&.
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.SH "RETURN VALUE"
+.PP
+Pointer to portal containing the cursor\&. Note there is no error return convention; any error will be reported via
+\fBelog\fR\&.
diff --git a/doc/src/sgml/man3/SPI_cursor_open_with_args.3 b/doc/src/sgml/man3/SPI_cursor_open_with_args.3
new file mode 100644
index 0000000..091faf7
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_open_with_args.3
@@ -0,0 +1,130 @@
+'\" t
+.\" Title: SPI_cursor_open_with_args
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_OPEN_WITH_ARGS" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_open_with_args \- set up a cursor using a query and parameters
+.SH "SYNOPSIS"
+.sp
+.nf
+Portal SPI_cursor_open_with_args(const char *\fIname\fR,
+ const char *\fIcommand\fR,
+ int \fInargs\fR, Oid *\fIargtypes\fR,
+ Datum *\fIvalues\fR, const char *\fInulls\fR,
+ bool \fIread_only\fR, int \fIcursorOptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_open_with_args\fR
+sets up a cursor (internally, a portal) that will execute the specified query\&. Most of the parameters have the same meanings as the corresponding parameters to
+\fBSPI_prepare_cursor\fR
+and
+\fBSPI_cursor_open\fR\&.
+.PP
+For one\-time query execution, this function should be preferred over
+\fBSPI_prepare_cursor\fR
+followed by
+\fBSPI_cursor_open\fR\&. If the same command is to be executed with many different parameters, either method might be faster, depending on the cost of re\-planning versus the benefit of custom plans\&.
+.PP
+The passed\-in parameter data will be copied into the cursor\*(Aqs portal, so it can be freed while the cursor still exists\&.
+.PP
+This function is now deprecated in favor of
+\fBSPI_cursor_parse_open\fR, which provides equivalent functionality using a more modern API for handling query parameters\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIname\fR
+.RS 4
+name for portal, or
+NULL
+to let the system select a name
+.RE
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+int \fInargs\fR
+.RS 4
+number of input parameters ($1,
+$2, etc\&.)
+.RE
+.PP
+Oid * \fIargtypes\fR
+.RS 4
+an array of length
+\fInargs\fR, containing the
+OIDs of the data types of the parameters
+.RE
+.PP
+Datum * \fIvalues\fR
+.RS 4
+an array of length
+\fInargs\fR, containing the actual parameter values
+.RE
+.PP
+const char * \fInulls\fR
+.RS 4
+an array of length
+\fInargs\fR, describing which parameters are null
+.sp
+If
+\fInulls\fR
+is
+NULL
+then
+\fBSPI_cursor_open_with_args\fR
+assumes that no parameters are null\&. Otherwise, each entry of the
+\fInulls\fR
+array should be
+\*(Aq\ \&\*(Aq
+if the corresponding parameter value is non\-null, or
+\*(Aqn\*(Aq
+if the corresponding parameter value is null\&. (In the latter case, the actual value in the corresponding
+\fIvalues\fR
+entry doesn\*(Aqt matter\&.) Note that
+\fInulls\fR
+is not a text string, just an array: it does not need a
+\*(Aq\e0\*(Aq
+terminator\&.
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+int \fIcursorOptions\fR
+.RS 4
+integer bit mask of cursor options; zero produces default behavior
+.RE
+.SH "RETURN VALUE"
+.PP
+Pointer to portal containing the cursor\&. Note there is no error return convention; any error will be reported via
+\fBelog\fR\&.
diff --git a/doc/src/sgml/man3/SPI_cursor_open_with_paramlist.3 b/doc/src/sgml/man3/SPI_cursor_open_with_paramlist.3
new file mode 100644
index 0000000..3885a1f
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_open_with_paramlist.3
@@ -0,0 +1,80 @@
+'\" t
+.\" Title: SPI_cursor_open_with_paramlist
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_OPEN_WITH_PARAMLIST" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_open_with_paramlist \- set up a cursor using parameters
+.SH "SYNOPSIS"
+.sp
+.nf
+Portal SPI_cursor_open_with_paramlist(const char *\fIname\fR,
+ SPIPlanPtr \fIplan\fR,
+ ParamListInfo \fIparams\fR,
+ bool \fIread_only\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_open_with_paramlist\fR
+sets up a cursor (internally, a portal) that will execute a statement prepared by
+\fBSPI_prepare\fR\&. This function is equivalent to
+\fBSPI_cursor_open\fR
+except that information about the parameter values to be passed to the query is presented differently\&. The
+ParamListInfo
+representation can be convenient for passing down values that are already available in that format\&. It also supports use of dynamic parameter sets via hook functions specified in
+ParamListInfo\&.
+.PP
+The passed\-in parameter data will be copied into the cursor\*(Aqs portal, so it can be freed while the cursor still exists\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIname\fR
+.RS 4
+name for portal, or
+NULL
+to let the system select a name
+.RE
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+ParamListInfo \fIparams\fR
+.RS 4
+data structure containing parameter types and values; NULL if none
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.SH "RETURN VALUE"
+.PP
+Pointer to portal containing the cursor\&. Note there is no error return convention; any error will be reported via
+\fBelog\fR\&.
diff --git a/doc/src/sgml/man3/SPI_cursor_parse_open.3 b/doc/src/sgml/man3/SPI_cursor_parse_open.3
new file mode 100644
index 0000000..e30f074
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_cursor_parse_open.3
@@ -0,0 +1,104 @@
+'\" t
+.\" Title: SPI_cursor_parse_open
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_CURSOR_PARSE_OPEN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_cursor_parse_open \- set up a cursor using a query string and parameters
+.SH "SYNOPSIS"
+.sp
+.nf
+Portal SPI_cursor_parse_open(const char *\fIname\fR,
+ const char *\fIcommand\fR,
+ const SPIParseOpenOptions * \fIoptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_cursor_parse_open\fR
+sets up a cursor (internally, a portal) that will execute the specified query string\&. This is comparable to
+\fBSPI_prepare_cursor\fR
+followed by
+\fBSPI_cursor_open_with_paramlist\fR, except that parameter references within the query string are handled entirely by supplying a
+ParamListInfo
+object\&.
+.PP
+For one\-time query execution, this function should be preferred over
+\fBSPI_prepare_cursor\fR
+followed by
+\fBSPI_cursor_open_with_paramlist\fR\&. If the same command is to be executed with many different parameters, either method might be faster, depending on the cost of re\-planning versus the benefit of custom plans\&.
+.PP
+The
+\fIoptions\->params\fR
+object should normally mark each parameter with the
+PARAM_FLAG_CONST
+flag, since a one\-shot plan is always used for the query\&.
+.PP
+The passed\-in parameter data will be copied into the cursor\*(Aqs portal, so it can be freed while the cursor still exists\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIname\fR
+.RS 4
+name for portal, or
+NULL
+to let the system select a name
+.RE
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+const SPIParseOpenOptions * \fIoptions\fR
+.RS 4
+struct containing optional arguments
+.RE
+.PP
+Callers should always zero out the entire
+\fIoptions\fR
+struct, then fill whichever fields they want to set\&. This ensures forward compatibility of code, since any fields that are added to the struct in future will be defined to behave backwards\-compatibly if they are zero\&. The currently available
+\fIoptions\fR
+fields are:
+.PP
+ParamListInfo \fIparams\fR
+.RS 4
+data structure containing query parameter types and values; NULL if none
+.RE
+.PP
+int \fIcursorOptions\fR
+.RS 4
+integer bit mask of cursor options; zero produces default behavior
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.SH "RETURN VALUE"
+.PP
+Pointer to portal containing the cursor\&. Note there is no error return convention; any error will be reported via
+\fBelog\fR\&.
diff --git a/doc/src/sgml/man3/SPI_exec.3 b/doc/src/sgml/man3/SPI_exec.3
new file mode 100644
index 0000000..2d35750
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_exec.3
@@ -0,0 +1,61 @@
+'\" t
+.\" Title: SPI_exec
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXEC" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_exec \- execute a read/write command
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_exec(const char * \fIcommand\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_exec\fR
+is the same as
+\fBSPI_execute\fR, with the latter\*(Aqs
+\fIread_only\fR
+parameter always taken as
+false\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+string containing command to execute
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.SH "RETURN VALUE"
+.PP
+See
+\fBSPI_execute\fR\&.
diff --git a/doc/src/sgml/man3/SPI_execp.3 b/doc/src/sgml/man3/SPI_execp.3
new file mode 100644
index 0000000..0fb7634
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execp.3
@@ -0,0 +1,99 @@
+'\" t
+.\" Title: SPI_execp
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECP" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execp \- execute a statement in read/write mode
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execp(SPIPlanPtr \fIplan\fR, Datum * \fIvalues\fR, const char * \fInulls\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execp\fR
+is the same as
+\fBSPI_execute_plan\fR, with the latter\*(Aqs
+\fIread_only\fR
+parameter always taken as
+false\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+Datum * \fIvalues\fR
+.RS 4
+An array of actual parameter values\&. Must have same length as the statement\*(Aqs number of arguments\&.
+.RE
+.PP
+const char * \fInulls\fR
+.RS 4
+An array describing which parameters are null\&. Must have same length as the statement\*(Aqs number of arguments\&.
+.sp
+If
+\fInulls\fR
+is
+NULL
+then
+\fBSPI_execp\fR
+assumes that no parameters are null\&. Otherwise, each entry of the
+\fInulls\fR
+array should be
+\*(Aq\ \&\*(Aq
+if the corresponding parameter value is non\-null, or
+\*(Aqn\*(Aq
+if the corresponding parameter value is null\&. (In the latter case, the actual value in the corresponding
+\fIvalues\fR
+entry doesn\*(Aqt matter\&.) Note that
+\fInulls\fR
+is not a text string, just an array: it does not need a
+\*(Aq\e0\*(Aq
+terminator\&.
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.SH "RETURN VALUE"
+.PP
+See
+\fBSPI_execute_plan\fR\&.
+.PP
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute\fR
+if successful\&.
diff --git a/doc/src/sgml/man3/SPI_execute.3 b/doc/src/sgml/man3/SPI_execute.3
new file mode 100644
index 0000000..c1ba030
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execute.3
@@ -0,0 +1,344 @@
+'\" t
+.\" Title: SPI_execute
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECUTE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execute \- execute a command
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execute(const char * \fIcommand\fR, bool \fIread_only\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execute\fR
+executes the specified SQL command for
+\fIcount\fR
+rows\&. If
+\fIread_only\fR
+is
+true, the command must be read\-only, and execution overhead is somewhat reduced\&.
+.PP
+This function can only be called from a connected C function\&.
+.PP
+If
+\fIcount\fR
+is zero then the command is executed for all rows that it applies to\&. If
+\fIcount\fR
+is greater than zero, then no more than
+\fIcount\fR
+rows will be retrieved; execution stops when the count is reached, much like adding a
+LIMIT
+clause to the query\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SPI_execute("SELECT * FROM foo", true, 5);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+will retrieve at most 5 rows from the table\&. Note that such a limit is only effective when the command actually returns rows\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+inserts all rows from
+bar, ignoring the
+\fIcount\fR
+parameter\&. However, with
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+at most 5 rows would be inserted, since execution would stop after the fifth
+RETURNING
+result row is retrieved\&.
+.PP
+You can pass multiple commands in one string;
+\fBSPI_execute\fR
+returns the result for the command executed last\&. The
+\fIcount\fR
+limit applies to each command separately (even though only the last result will actually be returned)\&. The limit is not applied to any hidden commands generated by rules\&.
+.PP
+When
+\fIread_only\fR
+is
+false,
+\fBSPI_execute\fR
+increments the command counter and computes a new
+snapshot
+before executing each command in the string\&. The snapshot does not actually change if the current transaction isolation level is
+SERIALIZABLE
+or
+REPEATABLE READ, but in
+READ COMMITTED
+mode the snapshot update allows each command to see the results of newly committed transactions from other sessions\&. This is essential for consistent behavior when the commands are modifying the database\&.
+.PP
+When
+\fIread_only\fR
+is
+true,
+\fBSPI_execute\fR
+does not update either the snapshot or the command counter, and it allows only plain
+\fBSELECT\fR
+commands to appear in the command string\&. The commands are executed using the snapshot previously established for the surrounding query\&. This execution mode is somewhat faster than the read/write mode due to eliminating per\-command overhead\&. It also allows genuinely
+stable
+functions to be built: since successive executions will all use the same snapshot, there will be no change in the results\&.
+.PP
+It is generally unwise to mix read\-only and read\-write commands within a single function using SPI; that could result in very confusing behavior, since the read\-only queries would not see the results of any database updates done by the read\-write queries\&.
+.PP
+The actual number of rows for which the (last) command was executed is returned in the global variable
+\fISPI_processed\fR\&. If the return value of the function is
+SPI_OK_SELECT,
+SPI_OK_INSERT_RETURNING,
+SPI_OK_DELETE_RETURNING, or
+SPI_OK_UPDATE_RETURNING, then you can use the global pointer
+SPITupleTable *SPI_tuptable
+to access the result rows\&. Some utility commands (such as
+\fBEXPLAIN\fR) also return row sets, and
+SPI_tuptable
+will contain the result in these cases too\&. Some utility commands (\fBCOPY\fR,
+\fBCREATE TABLE AS\fR) don\*(Aqt return a row set, so
+SPI_tuptable
+is NULL, but they still return the number of rows processed in
+\fISPI_processed\fR\&.
+.PP
+The structure
+SPITupleTable
+is defined thus:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+typedef struct SPITupleTable
+{
+ /* Public members */
+ TupleDesc tupdesc; /* tuple descriptor */
+ HeapTuple *vals; /* array of tuples */
+ uint64 numvals; /* number of valid tuples */
+
+ /* Private members, not intended for external callers */
+ uint64 alloced; /* allocated length of vals array */
+ MemoryContext tuptabcxt; /* memory context of result table */
+ slist_node next; /* link for internal bookkeeping */
+ SubTransactionId subid; /* subxact in which tuptable was created */
+} SPITupleTable;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The fields
+tupdesc,
+vals, and
+numvals
+can be used by SPI callers; the remaining fields are internal\&.
+vals
+is an array of pointers to rows\&. The number of rows is given by
+numvals
+(for somewhat historical reasons, this count is also returned in
+\fISPI_processed\fR)\&.
+tupdesc
+is a row descriptor which you can pass to SPI functions dealing with rows\&.
+.PP
+\fBSPI_finish\fR
+frees all
+SPITupleTables allocated during the current C function\&. You can free a particular result table earlier, if you are done with it, by calling
+\fBSPI_freetuptable\fR\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+string containing command to execute
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.SH "RETURN VALUE"
+.PP
+If the execution of the command was successful then one of the following (nonnegative) values will be returned:
+.PP
+SPI_OK_SELECT
+.RS 4
+if a
+\fBSELECT\fR
+(but not
+\fBSELECT INTO\fR) was executed
+.RE
+.PP
+SPI_OK_SELINTO
+.RS 4
+if a
+\fBSELECT INTO\fR
+was executed
+.RE
+.PP
+SPI_OK_INSERT
+.RS 4
+if an
+\fBINSERT\fR
+was executed
+.RE
+.PP
+SPI_OK_DELETE
+.RS 4
+if a
+\fBDELETE\fR
+was executed
+.RE
+.PP
+SPI_OK_UPDATE
+.RS 4
+if an
+\fBUPDATE\fR
+was executed
+.RE
+.PP
+SPI_OK_MERGE
+.RS 4
+if a
+\fBMERGE\fR
+was executed
+.RE
+.PP
+SPI_OK_INSERT_RETURNING
+.RS 4
+if an
+\fBINSERT RETURNING\fR
+was executed
+.RE
+.PP
+SPI_OK_DELETE_RETURNING
+.RS 4
+if a
+\fBDELETE RETURNING\fR
+was executed
+.RE
+.PP
+SPI_OK_UPDATE_RETURNING
+.RS 4
+if an
+\fBUPDATE RETURNING\fR
+was executed
+.RE
+.PP
+SPI_OK_UTILITY
+.RS 4
+if a utility command (e\&.g\&.,
+\fBCREATE TABLE\fR) was executed
+.RE
+.PP
+SPI_OK_REWRITTEN
+.RS 4
+if the command was rewritten into another kind of command (e\&.g\&.,
+\fBUPDATE\fR
+became an
+\fBINSERT\fR) by a
+rule\&.
+.RE
+.PP
+On error, one of the following negative values is returned:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fIcommand\fR
+is
+NULL
+or
+\fIcount\fR
+is less than 0
+.RE
+.PP
+SPI_ERROR_COPY
+.RS 4
+if
+\fBCOPY TO stdout\fR
+or
+\fBCOPY FROM stdin\fR
+was attempted
+.RE
+.PP
+SPI_ERROR_TRANSACTION
+.RS 4
+if a transaction manipulation command was attempted (\fBBEGIN\fR,
+\fBCOMMIT\fR,
+\fBROLLBACK\fR,
+\fBSAVEPOINT\fR,
+\fBPREPARE TRANSACTION\fR,
+\fBCOMMIT PREPARED\fR,
+\fBROLLBACK PREPARED\fR, or any variant thereof)
+.RE
+.PP
+SPI_ERROR_OPUNKNOWN
+.RS 4
+if the command type is unknown (shouldn\*(Aqt happen)
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if called from an unconnected C function
+.RE
+.SH "NOTES"
+.PP
+All SPI query\-execution functions set both
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+(just the pointer, not the contents of the structure)\&. Save these two global variables into local C function variables if you need to access the result table of
+\fBSPI_execute\fR
+or another query\-execution function across later calls\&.
diff --git a/doc/src/sgml/man3/SPI_execute_extended.3 b/doc/src/sgml/man3/SPI_execute_extended.3
new file mode 100644
index 0000000..4911e94
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execute_extended.3
@@ -0,0 +1,144 @@
+'\" t
+.\" Title: SPI_execute_extended
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECUTE_EXTENDED" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execute_extended \- execute a command with out\-of\-line parameters
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execute_extended(const char *\fIcommand\fR,
+ const SPIExecuteOptions * \fIoptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execute_extended\fR
+executes a command that might include references to externally supplied parameters\&. The command text refers to a parameter as
+$\fIn\fR, and the
+\fIoptions\->params\fR
+object (if supplied) provides values and type information for each such symbol\&. Various execution options can be specified in the
+\fIoptions\fR
+struct, too\&.
+.PP
+The
+\fIoptions\->params\fR
+object should normally mark each parameter with the
+PARAM_FLAG_CONST
+flag, since a one\-shot plan is always used for the query\&.
+.PP
+If
+\fIoptions\->dest\fR
+is not NULL, then result tuples are passed to that object as they are generated by the executor, instead of being accumulated in
+\fISPI_tuptable\fR\&. Using a caller\-supplied
+DestReceiver
+object is particularly helpful for queries that might generate many tuples, since the data can be processed on\-the\-fly instead of being accumulated in memory\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+const SPIExecuteOptions * \fIoptions\fR
+.RS 4
+struct containing optional arguments
+.RE
+.PP
+Callers should always zero out the entire
+\fIoptions\fR
+struct, then fill whichever fields they want to set\&. This ensures forward compatibility of code, since any fields that are added to the struct in future will be defined to behave backwards\-compatibly if they are zero\&. The currently available
+\fIoptions\fR
+fields are:
+.PP
+ParamListInfo \fIparams\fR
+.RS 4
+data structure containing query parameter types and values; NULL if none
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+bool \fIallow_nonatomic\fR
+.RS 4
+true
+allows non\-atomic execution of CALL and DO statements
+.RE
+.PP
+bool \fImust_return_tuples\fR
+.RS 4
+if
+true, raise error if the query is not of a kind that returns tuples (this does not forbid the case where it happens to return zero tuples)
+.RE
+.PP
+uint64 \fItcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.PP
+DestReceiver * \fIdest\fR
+.RS 4
+DestReceiver
+object that will receive any tuples emitted by the query; if NULL, result tuples are accumulated into a
+\fISPI_tuptable\fR
+structure, as in
+\fBSPI_execute\fR
+.RE
+.PP
+ResourceOwner \fIowner\fR
+.RS 4
+This field is present for consistency with
+\fBSPI_execute_plan_extended\fR, but it is ignored, since the plan used by
+\fBSPI_execute_extended\fR
+is never saved\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+The return value is the same as for
+\fBSPI_execute\fR\&.
+.PP
+When
+\fIoptions\->dest\fR
+is NULL,
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute\fR\&. When
+\fIoptions\->dest\fR
+is not NULL,
+\fISPI_processed\fR
+is set to zero and
+\fISPI_tuptable\fR
+is set to NULL\&. If a tuple count is required, the caller\*(Aqs
+DestReceiver
+object must calculate it\&.
diff --git a/doc/src/sgml/man3/SPI_execute_plan.3 b/doc/src/sgml/man3/SPI_execute_plan.3
new file mode 100644
index 0000000..54b413d
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execute_plan.3
@@ -0,0 +1,131 @@
+'\" t
+.\" Title: SPI_execute_plan
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECUTE_PLAN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execute_plan \- execute a statement prepared by \fBSPI_prepare\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execute_plan(SPIPlanPtr \fIplan\fR, Datum * \fIvalues\fR, const char * \fInulls\fR,
+ bool \fIread_only\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execute_plan\fR
+executes a statement prepared by
+\fBSPI_prepare\fR
+or one of its siblings\&.
+\fIread_only\fR
+and
+\fIcount\fR
+have the same interpretation as in
+\fBSPI_execute\fR\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+Datum * \fIvalues\fR
+.RS 4
+An array of actual parameter values\&. Must have same length as the statement\*(Aqs number of arguments\&.
+.RE
+.PP
+const char * \fInulls\fR
+.RS 4
+An array describing which parameters are null\&. Must have same length as the statement\*(Aqs number of arguments\&.
+.sp
+If
+\fInulls\fR
+is
+NULL
+then
+\fBSPI_execute_plan\fR
+assumes that no parameters are null\&. Otherwise, each entry of the
+\fInulls\fR
+array should be
+\*(Aq\ \&\*(Aq
+if the corresponding parameter value is non\-null, or
+\*(Aqn\*(Aq
+if the corresponding parameter value is null\&. (In the latter case, the actual value in the corresponding
+\fIvalues\fR
+entry doesn\*(Aqt matter\&.) Note that
+\fInulls\fR
+is not a text string, just an array: it does not need a
+\*(Aq\e0\*(Aq
+terminator\&.
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.SH "RETURN VALUE"
+.PP
+The return value is the same as for
+\fBSPI_execute\fR, with the following additional possible error (negative) results:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fIplan\fR
+is
+NULL
+or invalid, or
+\fIcount\fR
+is less than 0
+.RE
+.PP
+SPI_ERROR_PARAM
+.RS 4
+if
+\fIvalues\fR
+is
+NULL
+and
+\fIplan\fR
+was prepared with some parameters
+.RE
+.PP
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute\fR
+if successful\&.
diff --git a/doc/src/sgml/man3/SPI_execute_plan_extended.3 b/doc/src/sgml/man3/SPI_execute_plan_extended.3
new file mode 100644
index 0000000..5726392
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execute_plan_extended.3
@@ -0,0 +1,138 @@
+'\" t
+.\" Title: SPI_execute_plan_extended
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECUTE_PLAN_EXTENDED" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execute_plan_extended \- execute a statement prepared by \fBSPI_prepare\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execute_plan_extended(SPIPlanPtr \fIplan\fR,
+ const SPIExecuteOptions * \fIoptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execute_plan_extended\fR
+executes a statement prepared by
+\fBSPI_prepare\fR
+or one of its siblings\&. This function is equivalent to
+\fBSPI_execute_plan\fR, except that information about the parameter values to be passed to the query is presented differently, and additional execution\-controlling options can be passed\&.
+.PP
+Query parameter values are represented by a
+ParamListInfo
+struct, which is convenient for passing down values that are already available in that format\&. Dynamic parameter sets can also be used, via hook functions specified in
+ParamListInfo\&.
+.PP
+Also, instead of always accumulating the result tuples into a
+\fISPI_tuptable\fR
+structure, tuples can be passed to a caller\-supplied
+DestReceiver
+object as they are generated by the executor\&. This is particularly helpful for queries that might generate many tuples, since the data can be processed on\-the\-fly instead of being accumulated in memory\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+const SPIExecuteOptions * \fIoptions\fR
+.RS 4
+struct containing optional arguments
+.RE
+.PP
+Callers should always zero out the entire
+\fIoptions\fR
+struct, then fill whichever fields they want to set\&. This ensures forward compatibility of code, since any fields that are added to the struct in future will be defined to behave backwards\-compatibly if they are zero\&. The currently available
+\fIoptions\fR
+fields are:
+.PP
+ParamListInfo \fIparams\fR
+.RS 4
+data structure containing query parameter types and values; NULL if none
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+bool \fIallow_nonatomic\fR
+.RS 4
+true
+allows non\-atomic execution of CALL and DO statements
+.RE
+.PP
+bool \fImust_return_tuples\fR
+.RS 4
+if
+true, raise error if the query is not of a kind that returns tuples (this does not forbid the case where it happens to return zero tuples)
+.RE
+.PP
+uint64 \fItcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.PP
+DestReceiver * \fIdest\fR
+.RS 4
+DestReceiver
+object that will receive any tuples emitted by the query; if NULL, result tuples are accumulated into a
+\fISPI_tuptable\fR
+structure, as in
+\fBSPI_execute_plan\fR
+.RE
+.PP
+ResourceOwner \fIowner\fR
+.RS 4
+The resource owner that will hold a reference count on the plan while it is executed\&. If NULL, CurrentResourceOwner is used\&. Ignored for non\-saved plans, as SPI does not acquire reference counts on those\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+The return value is the same as for
+\fBSPI_execute_plan\fR\&.
+.PP
+When
+\fIoptions\->dest\fR
+is NULL,
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute_plan\fR\&. When
+\fIoptions\->dest\fR
+is not NULL,
+\fISPI_processed\fR
+is set to zero and
+\fISPI_tuptable\fR
+is set to NULL\&. If a tuple count is required, the caller\*(Aqs
+DestReceiver
+object must calculate it\&.
diff --git a/doc/src/sgml/man3/SPI_execute_plan_with_paramlist.3 b/doc/src/sgml/man3/SPI_execute_plan_with_paramlist.3
new file mode 100644
index 0000000..cfbf86e
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execute_plan_with_paramlist.3
@@ -0,0 +1,88 @@
+'\" t
+.\" Title: SPI_execute_plan_with_paramlist
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECUTE_PLAN_WITH_PARAMLIST" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execute_plan_with_paramlist \- execute a statement prepared by \fBSPI_prepare\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execute_plan_with_paramlist(SPIPlanPtr \fIplan\fR,
+ ParamListInfo \fIparams\fR,
+ bool \fIread_only\fR,
+ long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execute_plan_with_paramlist\fR
+executes a statement prepared by
+\fBSPI_prepare\fR\&. This function is equivalent to
+\fBSPI_execute_plan\fR
+except that information about the parameter values to be passed to the query is presented differently\&. The
+ParamListInfo
+representation can be convenient for passing down values that are already available in that format\&. It also supports use of dynamic parameter sets via hook functions specified in
+ParamListInfo\&.
+.PP
+This function is now deprecated in favor of
+\fBSPI_execute_plan_extended\fR\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+ParamListInfo \fIparams\fR
+.RS 4
+data structure containing parameter types and values; NULL if none
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.SH "RETURN VALUE"
+.PP
+The return value is the same as for
+\fBSPI_execute_plan\fR\&.
+.PP
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute_plan\fR
+if successful\&.
diff --git a/doc/src/sgml/man3/SPI_execute_with_args.3 b/doc/src/sgml/man3/SPI_execute_with_args.3
new file mode 100644
index 0000000..23800e3
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_execute_with_args.3
@@ -0,0 +1,133 @@
+'\" t
+.\" Title: SPI_execute_with_args
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_EXECUTE_WITH_ARGS" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_execute_with_args \- execute a command with out\-of\-line parameters
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_execute_with_args(const char *\fIcommand\fR,
+ int \fInargs\fR, Oid *\fIargtypes\fR,
+ Datum *\fIvalues\fR, const char *\fInulls\fR,
+ bool \fIread_only\fR, long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_execute_with_args\fR
+executes a command that might include references to externally supplied parameters\&. The command text refers to a parameter as
+$\fIn\fR, and the call specifies data types and values for each such symbol\&.
+\fIread_only\fR
+and
+\fIcount\fR
+have the same interpretation as in
+\fBSPI_execute\fR\&.
+.PP
+The main advantage of this routine compared to
+\fBSPI_execute\fR
+is that data values can be inserted into the command without tedious quoting/escaping, and thus with much less risk of SQL\-injection attacks\&.
+.PP
+Similar results can be achieved with
+\fBSPI_prepare\fR
+followed by
+\fBSPI_execute_plan\fR; however, when using this function the query plan is always customized to the specific parameter values provided\&. For one\-time query execution, this function should be preferred\&. If the same command is to be executed with many different parameters, either method might be faster, depending on the cost of re\-planning versus the benefit of custom plans\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+int \fInargs\fR
+.RS 4
+number of input parameters ($1,
+$2, etc\&.)
+.RE
+.PP
+Oid * \fIargtypes\fR
+.RS 4
+an array of length
+\fInargs\fR, containing the
+OIDs of the data types of the parameters
+.RE
+.PP
+Datum * \fIvalues\fR
+.RS 4
+an array of length
+\fInargs\fR, containing the actual parameter values
+.RE
+.PP
+const char * \fInulls\fR
+.RS 4
+an array of length
+\fInargs\fR, describing which parameters are null
+.sp
+If
+\fInulls\fR
+is
+NULL
+then
+\fBSPI_execute_with_args\fR
+assumes that no parameters are null\&. Otherwise, each entry of the
+\fInulls\fR
+array should be
+\*(Aq\ \&\*(Aq
+if the corresponding parameter value is non\-null, or
+\*(Aqn\*(Aq
+if the corresponding parameter value is null\&. (In the latter case, the actual value in the corresponding
+\fIvalues\fR
+entry doesn\*(Aqt matter\&.) Note that
+\fInulls\fR
+is not a text string, just an array: it does not need a
+\*(Aq\e0\*(Aq
+terminator\&.
+.RE
+.PP
+bool \fIread_only\fR
+.RS 4
+true
+for read\-only execution
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+maximum number of rows to return, or
+0
+for no limit
+.RE
+.SH "RETURN VALUE"
+.PP
+The return value is the same as for
+\fBSPI_execute\fR\&.
+.PP
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute\fR
+if successful\&.
diff --git a/doc/src/sgml/man3/SPI_finish.3 b/doc/src/sgml/man3/SPI_finish.3
new file mode 100644
index 0000000..5549565
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_finish.3
@@ -0,0 +1,52 @@
+'\" t
+.\" Title: SPI_finish
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_FINISH" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_finish \- disconnect a C function from the SPI manager
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_finish(void)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_finish\fR
+closes an existing connection to the SPI manager\&. You must call this function after completing the SPI operations needed during your C function\*(Aqs current invocation\&. You do not need to worry about making this happen, however, if you abort the transaction via
+elog(ERROR)\&. In that case SPI will clean itself up automatically\&.
+.SH "RETURN VALUE"
+.PP
+SPI_OK_FINISH
+.RS 4
+if properly disconnected
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if called from an unconnected C function
+.RE
diff --git a/doc/src/sgml/man3/SPI_fname.3 b/doc/src/sgml/man3/SPI_fname.3
new file mode 100644
index 0000000..94c5c74
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_fname.3
@@ -0,0 +1,64 @@
+'\" t
+.\" Title: SPI_fname
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_FNAME" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_fname \- determine the column name for the specified column number
+.SH "SYNOPSIS"
+.sp
+.nf
+char * SPI_fname(TupleDesc \fIrowdesc\fR, int \fIcolnumber\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_fname\fR
+returns a copy of the column name of the specified column\&. (You can use
+\fBpfree\fR
+to release the copy of the name when you don\*(Aqt need it anymore\&.)
+.SH "ARGUMENTS"
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+input row description
+.RE
+.PP
+int \fIcolnumber\fR
+.RS 4
+column number (count starts at 1)
+.RE
+.SH "RETURN VALUE"
+.PP
+The column name;
+NULL
+if
+\fIcolnumber\fR
+is out of range\&.
+\fISPI_result\fR
+set to
+SPI_ERROR_NOATTRIBUTE
+on error\&.
diff --git a/doc/src/sgml/man3/SPI_fnumber.3 b/doc/src/sgml/man3/SPI_fnumber.3
new file mode 100644
index 0000000..abde037
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_fnumber.3
@@ -0,0 +1,63 @@
+'\" t
+.\" Title: SPI_fnumber
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_FNUMBER" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_fnumber \- determine the column number for the specified column name
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_fnumber(TupleDesc \fIrowdesc\fR, const char * \fIcolname\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_fnumber\fR
+returns the column number for the column with the specified name\&.
+.PP
+If
+\fIcolname\fR
+refers to a system column (e\&.g\&.,
+ctid) then the appropriate negative column number will be returned\&. The caller should be careful to test the return value for exact equality to
+SPI_ERROR_NOATTRIBUTE
+to detect an error; testing the result for less than or equal to 0 is not correct unless system columns should be rejected\&.
+.SH "ARGUMENTS"
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+input row description
+.RE
+.PP
+const char * \fIcolname\fR
+.RS 4
+column name
+.RE
+.SH "RETURN VALUE"
+.PP
+Column number (count starts at 1 for user\-defined columns), or
+SPI_ERROR_NOATTRIBUTE
+if the named column was not found\&.
diff --git a/doc/src/sgml/man3/SPI_freeplan.3 b/doc/src/sgml/man3/SPI_freeplan.3
new file mode 100644
index 0000000..e6ecd52
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_freeplan.3
@@ -0,0 +1,60 @@
+'\" t
+.\" Title: SPI_freeplan
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_FREEPLAN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_freeplan \- free a previously saved prepared statement
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_freeplan(SPIPlanPtr \fIplan\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_freeplan\fR
+releases a prepared statement previously returned by
+\fBSPI_prepare\fR
+or saved by
+\fBSPI_keepplan\fR
+or
+\fBSPI_saveplan\fR\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+pointer to statement to free
+.RE
+.SH "RETURN VALUE"
+.PP
+0 on success;
+SPI_ERROR_ARGUMENT
+if
+\fIplan\fR
+is
+NULL
+or invalid
diff --git a/doc/src/sgml/man3/SPI_freetuple.3 b/doc/src/sgml/man3/SPI_freetuple.3
new file mode 100644
index 0000000..8b5a5cd
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_freetuple.3
@@ -0,0 +1,49 @@
+'\" t
+.\" Title: SPI_freetuple
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_FREETUPLE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_freetuple \- free a row allocated in the upper executor context
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_freetuple(HeapTuple \fIrow\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_freetuple\fR
+frees a row previously allocated in the upper executor context\&.
+.PP
+This function is no longer different from plain
+\fBheap_freetuple\fR\&. It\*(Aqs kept just for backward compatibility of existing code\&.
+.SH "ARGUMENTS"
+.PP
+HeapTuple \fIrow\fR
+.RS 4
+row to free
+.RE
diff --git a/doc/src/sgml/man3/SPI_freetuptable.3 b/doc/src/sgml/man3/SPI_freetuptable.3
new file mode 100644
index 0000000..a0a7eeb
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_freetuptable.3
@@ -0,0 +1,58 @@
+'\" t
+.\" Title: SPI_freetuptable
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_FREETUPTABLE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_freetuptable \- free a row set created by \fBSPI_execute\fR or a similar function
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_freetuptable(SPITupleTable * \fItuptable\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_freetuptable\fR
+frees a row set created by a prior SPI command execution function, such as
+\fBSPI_execute\fR\&. Therefore, this function is often called with the global variable
+\fISPI_tuptable\fR
+as argument\&.
+.PP
+This function is useful if an SPI\-using C function needs to execute multiple commands and does not want to keep the results of earlier commands around until it ends\&. Note that any unfreed row sets will be freed anyway at
+\fBSPI_finish\fR\&. Also, if a subtransaction is started and then aborted within execution of an SPI\-using C function, SPI automatically frees any row sets created while the subtransaction was running\&.
+.PP
+Beginning in
+PostgreSQL
+9\&.3,
+\fBSPI_freetuptable\fR
+contains guard logic to protect against duplicate deletion requests for the same row set\&. In previous releases, duplicate deletions would lead to crashes\&.
+.SH "ARGUMENTS"
+.PP
+SPITupleTable * \fItuptable\fR
+.RS 4
+pointer to row set to free, or NULL to do nothing
+.RE
diff --git a/doc/src/sgml/man3/SPI_getargcount.3 b/doc/src/sgml/man3/SPI_getargcount.3
new file mode 100644
index 0000000..a0ca6bf
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_getargcount.3
@@ -0,0 +1,60 @@
+'\" t
+.\" Title: SPI_getargcount
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETARGCOUNT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_getargcount \- return the number of arguments needed by a statement prepared by \fBSPI_prepare\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_getargcount(SPIPlanPtr \fIplan\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_getargcount\fR
+returns the number of arguments needed to execute a statement prepared by
+\fBSPI_prepare\fR\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.SH "RETURN VALUE"
+.PP
+The count of expected arguments for the
+\fIplan\fR\&. If the
+\fIplan\fR
+is
+NULL
+or invalid,
+\fISPI_result\fR
+is set to
+SPI_ERROR_ARGUMENT
+and \-1 is returned\&.
diff --git a/doc/src/sgml/man3/SPI_getargtypeid.3 b/doc/src/sgml/man3/SPI_getargtypeid.3
new file mode 100644
index 0000000..a2b238d
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_getargtypeid.3
@@ -0,0 +1,70 @@
+'\" t
+.\" Title: SPI_getargtypeid
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETARGTYPEID" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_getargtypeid \- return the data type OID for an argument of a statement prepared by \fBSPI_prepare\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+Oid SPI_getargtypeid(SPIPlanPtr \fIplan\fR, int \fIargIndex\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_getargtypeid\fR
+returns the OID representing the type for the
+\fIargIndex\fR\*(Aqth argument of a statement prepared by
+\fBSPI_prepare\fR\&. First argument is at index zero\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.PP
+int \fIargIndex\fR
+.RS 4
+zero based index of the argument
+.RE
+.SH "RETURN VALUE"
+.PP
+The type OID of the argument at the given index\&. If the
+\fIplan\fR
+is
+NULL
+or invalid, or
+\fIargIndex\fR
+is less than 0 or not less than the number of arguments declared for the
+\fIplan\fR,
+\fISPI_result\fR
+is set to
+SPI_ERROR_ARGUMENT
+and
+InvalidOid
+is returned\&.
diff --git a/doc/src/sgml/man3/SPI_getbinval.3 b/doc/src/sgml/man3/SPI_getbinval.3
new file mode 100644
index 0000000..986b691
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_getbinval.3
@@ -0,0 +1,75 @@
+'\" t
+.\" Title: SPI_getbinval
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETBINVAL" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_getbinval \- return the binary value of the specified column
+.SH "SYNOPSIS"
+.sp
+.nf
+Datum SPI_getbinval(HeapTuple \fIrow\fR, TupleDesc \fIrowdesc\fR, int \fIcolnumber\fR,
+ bool * \fIisnull\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_getbinval\fR
+returns the value of the specified column in the internal form (as type
+Datum)\&.
+.PP
+This function does not allocate new space for the datum\&. In the case of a pass\-by\-reference data type, the return value will be a pointer into the passed row\&.
+.SH "ARGUMENTS"
+.PP
+HeapTuple \fIrow\fR
+.RS 4
+input row to be examined
+.RE
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+input row description
+.RE
+.PP
+int \fIcolnumber\fR
+.RS 4
+column number (count starts at 1)
+.RE
+.PP
+bool * \fIisnull\fR
+.RS 4
+flag for a null value in the column
+.RE
+.SH "RETURN VALUE"
+.PP
+The binary value of the column is returned\&. The variable pointed to by
+\fIisnull\fR
+is set to true if the column is null, else to false\&.
+.PP
+\fISPI_result\fR
+is set to
+SPI_ERROR_NOATTRIBUTE
+on error\&.
diff --git a/doc/src/sgml/man3/SPI_getnspname.3 b/doc/src/sgml/man3/SPI_getnspname.3
new file mode 100644
index 0000000..940093a
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_getnspname.3
@@ -0,0 +1,53 @@
+'\" t
+.\" Title: SPI_getnspname
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETNSPNAME" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_getnspname \- return the namespace of the specified relation
+.SH "SYNOPSIS"
+.sp
+.nf
+char * SPI_getnspname(Relation \fIrel\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_getnspname\fR
+returns a copy of the name of the namespace that the specified
+Relation
+belongs to\&. This is equivalent to the relation\*(Aqs schema\&. You should
+\fBpfree\fR
+the return value of this function when you are finished with it\&.
+.SH "ARGUMENTS"
+.PP
+Relation \fIrel\fR
+.RS 4
+input relation
+.RE
+.SH "RETURN VALUE"
+.PP
+The name of the specified relation\*(Aqs namespace\&.
diff --git a/doc/src/sgml/man3/SPI_getrelname.3 b/doc/src/sgml/man3/SPI_getrelname.3
new file mode 100644
index 0000000..71f7c9e
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_getrelname.3
@@ -0,0 +1,51 @@
+'\" t
+.\" Title: SPI_getrelname
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETRELNAME" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_getrelname \- return the name of the specified relation
+.SH "SYNOPSIS"
+.sp
+.nf
+char * SPI_getrelname(Relation \fIrel\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_getrelname\fR
+returns a copy of the name of the specified relation\&. (You can use
+\fBpfree\fR
+to release the copy of the name when you don\*(Aqt need it anymore\&.)
+.SH "ARGUMENTS"
+.PP
+Relation \fIrel\fR
+.RS 4
+input relation
+.RE
+.SH "RETURN VALUE"
+.PP
+The name of the specified relation\&.
diff --git a/doc/src/sgml/man3/SPI_gettype.3 b/doc/src/sgml/man3/SPI_gettype.3
new file mode 100644
index 0000000..ceccae8
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_gettype.3
@@ -0,0 +1,62 @@
+'\" t
+.\" Title: SPI_gettype
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETTYPE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_gettype \- return the data type name of the specified column
+.SH "SYNOPSIS"
+.sp
+.nf
+char * SPI_gettype(TupleDesc \fIrowdesc\fR, int \fIcolnumber\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_gettype\fR
+returns a copy of the data type name of the specified column\&. (You can use
+\fBpfree\fR
+to release the copy of the name when you don\*(Aqt need it anymore\&.)
+.SH "ARGUMENTS"
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+input row description
+.RE
+.PP
+int \fIcolnumber\fR
+.RS 4
+column number (count starts at 1)
+.RE
+.SH "RETURN VALUE"
+.PP
+The data type name of the specified column, or
+NULL
+on error\&.
+\fISPI_result\fR
+is set to
+SPI_ERROR_NOATTRIBUTE
+on error\&.
diff --git a/doc/src/sgml/man3/SPI_gettypeid.3 b/doc/src/sgml/man3/SPI_gettypeid.3
new file mode 100644
index 0000000..d93edf3
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_gettypeid.3
@@ -0,0 +1,63 @@
+'\" t
+.\" Title: SPI_gettypeid
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETTYPEID" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_gettypeid \- return the data type OID of the specified column
+.SH "SYNOPSIS"
+.sp
+.nf
+Oid SPI_gettypeid(TupleDesc \fIrowdesc\fR, int \fIcolnumber\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_gettypeid\fR
+returns the
+OID
+of the data type of the specified column\&.
+.SH "ARGUMENTS"
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+input row description
+.RE
+.PP
+int \fIcolnumber\fR
+.RS 4
+column number (count starts at 1)
+.RE
+.SH "RETURN VALUE"
+.PP
+The
+OID
+of the data type of the specified column or
+InvalidOid
+on error\&. On error,
+\fISPI_result\fR
+is set to
+SPI_ERROR_NOATTRIBUTE\&.
diff --git a/doc/src/sgml/man3/SPI_getvalue.3 b/doc/src/sgml/man3/SPI_getvalue.3
new file mode 100644
index 0000000..ed5532f
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_getvalue.3
@@ -0,0 +1,72 @@
+'\" t
+.\" Title: SPI_getvalue
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_GETVALUE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_getvalue \- return the string value of the specified column
+.SH "SYNOPSIS"
+.sp
+.nf
+char * SPI_getvalue(HeapTuple \fIrow\fR, TupleDesc \fIrowdesc\fR, int \fIcolnumber\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_getvalue\fR
+returns the string representation of the value of the specified column\&.
+.PP
+The result is returned in memory allocated using
+\fBpalloc\fR\&. (You can use
+\fBpfree\fR
+to release the memory when you don\*(Aqt need it anymore\&.)
+.SH "ARGUMENTS"
+.PP
+HeapTuple \fIrow\fR
+.RS 4
+input row to be examined
+.RE
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+input row description
+.RE
+.PP
+int \fIcolnumber\fR
+.RS 4
+column number (count starts at 1)
+.RE
+.SH "RETURN VALUE"
+.PP
+Column value, or
+NULL
+if the column is null,
+\fIcolnumber\fR
+is out of range (\fISPI_result\fR
+is set to
+SPI_ERROR_NOATTRIBUTE), or no output function is available (\fISPI_result\fR
+is set to
+SPI_ERROR_NOOUTFUNC)\&.
diff --git a/doc/src/sgml/man3/SPI_is_cursor_plan.3 b/doc/src/sgml/man3/SPI_is_cursor_plan.3
new file mode 100644
index 0000000..25c9f2c
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_is_cursor_plan.3
@@ -0,0 +1,82 @@
+'\" t
+.\" Title: SPI_is_cursor_plan
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_IS_CURSOR_PLAN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_is_cursor_plan \- return true if a statement prepared by \fBSPI_prepare\fR can be used with \fBSPI_cursor_open\fR
+.SH "SYNOPSIS"
+.sp
+.nf
+bool SPI_is_cursor_plan(SPIPlanPtr \fIplan\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_is_cursor_plan\fR
+returns
+true
+if a statement prepared by
+\fBSPI_prepare\fR
+can be passed as an argument to
+\fBSPI_cursor_open\fR, or
+false
+if that is not the case\&. The criteria are that the
+\fIplan\fR
+represents one single command and that this command returns tuples to the caller; for example,
+\fBSELECT\fR
+is allowed unless it contains an
+INTO
+clause, and
+\fBUPDATE\fR
+is allowed only if it contains a
+RETURNING
+clause\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+prepared statement (returned by
+\fBSPI_prepare\fR)
+.RE
+.SH "RETURN VALUE"
+.PP
+true
+or
+false
+to indicate if the
+\fIplan\fR
+can produce a cursor or not, with
+\fISPI_result\fR
+set to zero\&. If it is not possible to determine the answer (for example, if the
+\fIplan\fR
+is
+NULL
+or invalid, or if called when not connected to SPI), then
+\fISPI_result\fR
+is set to a suitable error code and
+false
+is returned\&.
diff --git a/doc/src/sgml/man3/SPI_keepplan.3 b/doc/src/sgml/man3/SPI_keepplan.3
new file mode 100644
index 0000000..abc1918
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_keepplan.3
@@ -0,0 +1,63 @@
+'\" t
+.\" Title: SPI_keepplan
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_KEEPPLAN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_keepplan \- save a prepared statement
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_keepplan(SPIPlanPtr \fIplan\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_keepplan\fR
+saves a passed statement (prepared by
+\fBSPI_prepare\fR) so that it will not be freed by
+\fBSPI_finish\fR
+nor by the transaction manager\&. This gives you the ability to reuse prepared statements in the subsequent invocations of your C function in the current session\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+the prepared statement to be saved
+.RE
+.SH "RETURN VALUE"
+.PP
+0 on success;
+SPI_ERROR_ARGUMENT
+if
+\fIplan\fR
+is
+NULL
+or invalid
+.SH "NOTES"
+.PP
+The passed\-in statement is relocated to permanent storage by means of pointer adjustment (no data copying is required)\&. If you later wish to delete it, use
+\fBSPI_freeplan\fR
+on it\&.
diff --git a/doc/src/sgml/man3/SPI_modifytuple.3 b/doc/src/sgml/man3/SPI_modifytuple.3
new file mode 100644
index 0000000..f131bed
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_modifytuple.3
@@ -0,0 +1,143 @@
+'\" t
+.\" Title: SPI_modifytuple
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_MODIFYTUPLE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_modifytuple \- create a row by replacing selected fields of a given row
+.SH "SYNOPSIS"
+.sp
+.nf
+HeapTuple SPI_modifytuple(Relation \fIrel\fR, HeapTuple \fIrow\fR, int \fIncols\fR,
+ int * \fIcolnum\fR, Datum * \fIvalues\fR, const char * \fInulls\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_modifytuple\fR
+creates a new row by substituting new values for selected columns, copying the original row\*(Aqs columns at other positions\&. The input row is not modified\&. The new row is returned in the upper executor context\&.
+.PP
+This function can only be used while connected to SPI\&. Otherwise, it returns NULL and sets
+\fISPI_result\fR
+to
+SPI_ERROR_UNCONNECTED\&.
+.SH "ARGUMENTS"
+.PP
+Relation \fIrel\fR
+.RS 4
+Used only as the source of the row descriptor for the row\&. (Passing a relation rather than a row descriptor is a misfeature\&.)
+.RE
+.PP
+HeapTuple \fIrow\fR
+.RS 4
+row to be modified
+.RE
+.PP
+int \fIncols\fR
+.RS 4
+number of columns to be changed
+.RE
+.PP
+int * \fIcolnum\fR
+.RS 4
+an array of length
+\fIncols\fR, containing the numbers of the columns that are to be changed (column numbers start at 1)
+.RE
+.PP
+Datum * \fIvalues\fR
+.RS 4
+an array of length
+\fIncols\fR, containing the new values for the specified columns
+.RE
+.PP
+const char * \fInulls\fR
+.RS 4
+an array of length
+\fIncols\fR, describing which new values are null
+.sp
+If
+\fInulls\fR
+is
+NULL
+then
+\fBSPI_modifytuple\fR
+assumes that no new values are null\&. Otherwise, each entry of the
+\fInulls\fR
+array should be
+\*(Aq\ \&\*(Aq
+if the corresponding new value is non\-null, or
+\*(Aqn\*(Aq
+if the corresponding new value is null\&. (In the latter case, the actual value in the corresponding
+\fIvalues\fR
+entry doesn\*(Aqt matter\&.) Note that
+\fInulls\fR
+is not a text string, just an array: it does not need a
+\*(Aq\e0\*(Aq
+terminator\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+new row with modifications, allocated in the upper executor context, or
+NULL
+on error (see
+\fISPI_result\fR
+for an error indication)
+.PP
+On error,
+\fISPI_result\fR
+is set as follows:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fIrel\fR
+is
+NULL, or if
+\fIrow\fR
+is
+NULL, or if
+\fIncols\fR
+is less than or equal to 0, or if
+\fIcolnum\fR
+is
+NULL, or if
+\fIvalues\fR
+is
+NULL\&.
+.RE
+.PP
+SPI_ERROR_NOATTRIBUTE
+.RS 4
+if
+\fIcolnum\fR
+contains an invalid column number (less than or equal to 0 or greater than the number of columns in
+\fIrow\fR)
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if SPI is not active
+.RE
diff --git a/doc/src/sgml/man3/SPI_palloc.3 b/doc/src/sgml/man3/SPI_palloc.3
new file mode 100644
index 0000000..bf4e2f7
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_palloc.3
@@ -0,0 +1,51 @@
+'\" t
+.\" Title: SPI_palloc
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_PALLOC" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_palloc \- allocate memory in the upper executor context
+.SH "SYNOPSIS"
+.sp
+.nf
+void * SPI_palloc(Size \fIsize\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_palloc\fR
+allocates memory in the upper executor context\&.
+.PP
+This function can only be used while connected to SPI\&. Otherwise, it throws an error\&.
+.SH "ARGUMENTS"
+.PP
+Size \fIsize\fR
+.RS 4
+size in bytes of storage to allocate
+.RE
+.SH "RETURN VALUE"
+.PP
+pointer to new storage space of the specified size
diff --git a/doc/src/sgml/man3/SPI_pfree.3 b/doc/src/sgml/man3/SPI_pfree.3
new file mode 100644
index 0000000..8c7d24a
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_pfree.3
@@ -0,0 +1,52 @@
+'\" t
+.\" Title: SPI_pfree
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_PFREE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_pfree \- free memory in the upper executor context
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_pfree(void * \fIpointer\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_pfree\fR
+frees memory previously allocated using
+\fBSPI_palloc\fR
+or
+\fBSPI_repalloc\fR\&.
+.PP
+This function is no longer different from plain
+\fBpfree\fR\&. It\*(Aqs kept just for backward compatibility of existing code\&.
+.SH "ARGUMENTS"
+.PP
+void * \fIpointer\fR
+.RS 4
+pointer to existing storage to free
+.RE
diff --git a/doc/src/sgml/man3/SPI_prepare.3 b/doc/src/sgml/man3/SPI_prepare.3
new file mode 100644
index 0000000..5b1f917
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_prepare.3
@@ -0,0 +1,134 @@
+'\" t
+.\" Title: SPI_prepare
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_PREPARE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_prepare \- prepare a statement, without executing it yet
+.SH "SYNOPSIS"
+.sp
+.nf
+SPIPlanPtr SPI_prepare(const char * \fIcommand\fR, int \fInargs\fR, Oid * \fIargtypes\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_prepare\fR
+creates and returns a prepared statement for the specified command, but doesn\*(Aqt execute the command\&. The prepared statement can later be executed repeatedly using
+\fBSPI_execute_plan\fR\&.
+.PP
+When the same or a similar command is to be executed repeatedly, it is generally advantageous to perform parse analysis only once, and might furthermore be advantageous to re\-use an execution plan for the command\&.
+\fBSPI_prepare\fR
+converts a command string into a prepared statement that encapsulates the results of parse analysis\&. The prepared statement also provides a place for caching an execution plan if it is found that generating a custom plan for each execution is not helpful\&.
+.PP
+A prepared command can be generalized by writing parameters ($1,
+$2, etc\&.) in place of what would be constants in a normal command\&. The actual values of the parameters are then specified when
+\fBSPI_execute_plan\fR
+is called\&. This allows the prepared command to be used over a wider range of situations than would be possible without parameters\&.
+.PP
+The statement returned by
+\fBSPI_prepare\fR
+can be used only in the current invocation of the C function, since
+\fBSPI_finish\fR
+frees memory allocated for such a statement\&. But the statement can be saved for longer using the functions
+\fBSPI_keepplan\fR
+or
+\fBSPI_saveplan\fR\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+int \fInargs\fR
+.RS 4
+number of input parameters ($1,
+$2, etc\&.)
+.RE
+.PP
+Oid * \fIargtypes\fR
+.RS 4
+pointer to an array containing the
+OIDs of the data types of the parameters
+.RE
+.SH "RETURN VALUE"
+.PP
+\fBSPI_prepare\fR
+returns a non\-null pointer to an
+SPIPlan, which is an opaque struct representing a prepared statement\&. On error,
+NULL
+will be returned, and
+\fISPI_result\fR
+will be set to one of the same error codes used by
+\fBSPI_execute\fR, except that it is set to
+SPI_ERROR_ARGUMENT
+if
+\fIcommand\fR
+is
+NULL, or if
+\fInargs\fR
+is less than 0, or if
+\fInargs\fR
+is greater than 0 and
+\fIargtypes\fR
+is
+NULL\&.
+.SH "NOTES"
+.PP
+If no parameters are defined, a generic plan will be created at the first use of
+\fBSPI_execute_plan\fR, and used for all subsequent executions as well\&. If there are parameters, the first few uses of
+\fBSPI_execute_plan\fR
+will generate custom plans that are specific to the supplied parameter values\&. After enough uses of the same prepared statement,
+\fBSPI_execute_plan\fR
+will build a generic plan, and if that is not too much more expensive than the custom plans, it will start using the generic plan instead of re\-planning each time\&. If this default behavior is unsuitable, you can alter it by passing the
+CURSOR_OPT_GENERIC_PLAN
+or
+CURSOR_OPT_CUSTOM_PLAN
+flag to
+\fBSPI_prepare_cursor\fR, to force use of generic or custom plans respectively\&.
+.PP
+Although the main point of a prepared statement is to avoid repeated parse analysis and planning of the statement,
+PostgreSQL
+will force re\-analysis and re\-planning of the statement before using it whenever database objects used in the statement have undergone definitional (DDL) changes since the previous use of the prepared statement\&. Also, if the value of
+search_path
+changes from one use to the next, the statement will be re\-parsed using the new
+\fIsearch_path\fR\&. (This latter behavior is new as of
+PostgreSQL
+9\&.3\&.) See
+\fBPREPARE\fR(7)
+for more information about the behavior of prepared statements\&.
+.PP
+This function should only be called from a connected C function\&.
+.PP
+SPIPlanPtr
+is declared as a pointer to an opaque struct type in
+spi\&.h\&. It is unwise to try to access its contents directly, as that makes your code much more likely to break in future revisions of
+PostgreSQL\&.
+.PP
+The name
+SPIPlanPtr
+is somewhat historical, since the data structure no longer necessarily contains an execution plan\&.
diff --git a/doc/src/sgml/man3/SPI_prepare_cursor.3 b/doc/src/sgml/man3/SPI_prepare_cursor.3
new file mode 100644
index 0000000..8424f67
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_prepare_cursor.3
@@ -0,0 +1,94 @@
+'\" t
+.\" Title: SPI_prepare_cursor
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_PREPARE_CURSOR" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_prepare_cursor \- prepare a statement, without executing it yet
+.SH "SYNOPSIS"
+.sp
+.nf
+SPIPlanPtr SPI_prepare_cursor(const char * \fIcommand\fR, int \fInargs\fR,
+ Oid * \fIargtypes\fR, int \fIcursorOptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_prepare_cursor\fR
+is identical to
+\fBSPI_prepare\fR, except that it also allows specification of the planner\*(Aqs
+\(lqcursor options\(rq
+parameter\&. This is a bit mask having the values shown in
+nodes/parsenodes\&.h
+for the
+options
+field of
+DeclareCursorStmt\&.
+\fBSPI_prepare\fR
+always takes the cursor options as zero\&.
+.PP
+This function is now deprecated in favor of
+\fBSPI_prepare_extended\fR\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+int \fInargs\fR
+.RS 4
+number of input parameters ($1,
+$2, etc\&.)
+.RE
+.PP
+Oid * \fIargtypes\fR
+.RS 4
+pointer to an array containing the
+OIDs of the data types of the parameters
+.RE
+.PP
+int \fIcursorOptions\fR
+.RS 4
+integer bit mask of cursor options; zero produces default behavior
+.RE
+.SH "RETURN VALUE"
+.PP
+\fBSPI_prepare_cursor\fR
+has the same return conventions as
+\fBSPI_prepare\fR\&.
+.SH "NOTES"
+.PP
+Useful bits to set in
+\fIcursorOptions\fR
+include
+CURSOR_OPT_SCROLL,
+CURSOR_OPT_NO_SCROLL,
+CURSOR_OPT_FAST_PLAN,
+CURSOR_OPT_GENERIC_PLAN, and
+CURSOR_OPT_CUSTOM_PLAN\&. Note in particular that
+CURSOR_OPT_HOLD
+is ignored\&.
diff --git a/doc/src/sgml/man3/SPI_prepare_extended.3 b/doc/src/sgml/man3/SPI_prepare_extended.3
new file mode 100644
index 0000000..7cd15c5
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_prepare_extended.3
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: SPI_prepare_extended
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_PREPARE_EXTENDED" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_prepare_extended \- prepare a statement, without executing it yet
+.SH "SYNOPSIS"
+.sp
+.nf
+SPIPlanPtr SPI_prepare_extended(const char * \fIcommand\fR,
+ const SPIPrepareOptions * \fIoptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_prepare_extended\fR
+creates and returns a prepared statement for the specified command, but doesn\*(Aqt execute the command\&. This function is equivalent to
+\fBSPI_prepare\fR, with the addition that the caller can specify options to control the parsing of external parameter references, as well as other facets of query parsing and planning\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+const SPIPrepareOptions * \fIoptions\fR
+.RS 4
+struct containing optional arguments
+.RE
+.PP
+Callers should always zero out the entire
+\fIoptions\fR
+struct, then fill whichever fields they want to set\&. This ensures forward compatibility of code, since any fields that are added to the struct in future will be defined to behave backwards\-compatibly if they are zero\&. The currently available
+\fIoptions\fR
+fields are:
+.PP
+ParserSetupHook \fIparserSetup\fR
+.RS 4
+Parser hook setup function
+.RE
+.PP
+void * \fIparserSetupArg\fR
+.RS 4
+pass\-through argument for
+\fIparserSetup\fR
+.RE
+.PP
+RawParseMode \fIparseMode\fR
+.RS 4
+mode for raw parsing;
+RAW_PARSE_DEFAULT
+(zero) produces default behavior
+.RE
+.PP
+int \fIcursorOptions\fR
+.RS 4
+integer bit mask of cursor options; zero produces default behavior
+.RE
+.SH "RETURN VALUE"
+.PP
+\fBSPI_prepare_extended\fR
+has the same return conventions as
+\fBSPI_prepare\fR\&.
diff --git a/doc/src/sgml/man3/SPI_prepare_params.3 b/doc/src/sgml/man3/SPI_prepare_params.3
new file mode 100644
index 0000000..7ca8c9b
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_prepare_params.3
@@ -0,0 +1,74 @@
+'\" t
+.\" Title: SPI_prepare_params
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_PREPARE_PARAMS" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_prepare_params \- prepare a statement, without executing it yet
+.SH "SYNOPSIS"
+.sp
+.nf
+SPIPlanPtr SPI_prepare_params(const char * \fIcommand\fR,
+ ParserSetupHook \fIparserSetup\fR,
+ void * \fIparserSetupArg\fR,
+ int \fIcursorOptions\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_prepare_params\fR
+creates and returns a prepared statement for the specified command, but doesn\*(Aqt execute the command\&. This function is equivalent to
+\fBSPI_prepare_cursor\fR, with the addition that the caller can specify parser hook functions to control the parsing of external parameter references\&.
+.PP
+This function is now deprecated in favor of
+\fBSPI_prepare_extended\fR\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIcommand\fR
+.RS 4
+command string
+.RE
+.PP
+ParserSetupHook \fIparserSetup\fR
+.RS 4
+Parser hook setup function
+.RE
+.PP
+void * \fIparserSetupArg\fR
+.RS 4
+pass\-through argument for
+\fIparserSetup\fR
+.RE
+.PP
+int \fIcursorOptions\fR
+.RS 4
+integer bit mask of cursor options; zero produces default behavior
+.RE
+.SH "RETURN VALUE"
+.PP
+\fBSPI_prepare_params\fR
+has the same return conventions as
+\fBSPI_prepare\fR\&.
diff --git a/doc/src/sgml/man3/SPI_register_relation.3 b/doc/src/sgml/man3/SPI_register_relation.3
new file mode 100644
index 0000000..c9a0f19
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_register_relation.3
@@ -0,0 +1,82 @@
+'\" t
+.\" Title: SPI_register_relation
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_REGISTER_RELATION" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_register_relation \- make an ephemeral named relation available by name in SPI queries
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_register_relation(EphemeralNamedRelation \fIenr\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_register_relation\fR
+makes an ephemeral named relation, with associated information, available to queries planned and executed through the current SPI connection\&.
+.SH "ARGUMENTS"
+.PP
+EphemeralNamedRelation \fIenr\fR
+.RS 4
+the ephemeral named relation registry entry
+.RE
+.SH "RETURN VALUE"
+.PP
+If the execution of the command was successful then the following (nonnegative) value will be returned:
+.PP
+SPI_OK_REL_REGISTER
+.RS 4
+if the relation has been successfully registered by name
+.RE
+.PP
+On error, one of the following negative values is returned:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fIenr\fR
+is
+NULL
+or its
+\fIname\fR
+field is
+NULL
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if called from an unconnected C function
+.RE
+.PP
+SPI_ERROR_REL_DUPLICATE
+.RS 4
+if the name specified in the
+\fIname\fR
+field of
+\fIenr\fR
+is already registered for this connection
+.RE
diff --git a/doc/src/sgml/man3/SPI_register_trigger_data.3 b/doc/src/sgml/man3/SPI_register_trigger_data.3
new file mode 100644
index 0000000..44d3f17
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_register_trigger_data.3
@@ -0,0 +1,81 @@
+'\" t
+.\" Title: SPI_register_trigger_data
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_REGISTER_TRIGGER_DATA" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_register_trigger_data \- make ephemeral trigger data available in SPI queries
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_register_trigger_data(TriggerData *\fItdata\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_register_trigger_data\fR
+makes any ephemeral relations captured by a trigger available to queries planned and executed through the current SPI connection\&. Currently, this means the transition tables captured by an
+AFTER
+trigger defined with a
+REFERENCING OLD/NEW TABLE AS
+\&.\&.\&. clause\&. This function should be called by a PL trigger handler function after connecting\&.
+.SH "ARGUMENTS"
+.PP
+TriggerData *\fItdata\fR
+.RS 4
+the
+TriggerData
+object passed to a trigger handler function as
+fcinfo\->context
+.RE
+.SH "RETURN VALUE"
+.PP
+If the execution of the command was successful then the following (nonnegative) value will be returned:
+.PP
+SPI_OK_TD_REGISTER
+.RS 4
+if the captured trigger data (if any) has been successfully registered
+.RE
+.PP
+On error, one of the following negative values is returned:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fItdata\fR
+is
+NULL
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if called from an unconnected C function
+.RE
+.PP
+SPI_ERROR_REL_DUPLICATE
+.RS 4
+if the name of any trigger data transient relation is already registered for this connection
+.RE
diff --git a/doc/src/sgml/man3/SPI_repalloc.3 b/doc/src/sgml/man3/SPI_repalloc.3
new file mode 100644
index 0000000..e921c99
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_repalloc.3
@@ -0,0 +1,58 @@
+'\" t
+.\" Title: SPI_repalloc
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_REPALLOC" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_repalloc \- reallocate memory in the upper executor context
+.SH "SYNOPSIS"
+.sp
+.nf
+void * SPI_repalloc(void * \fIpointer\fR, Size \fIsize\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_repalloc\fR
+changes the size of a memory segment previously allocated using
+\fBSPI_palloc\fR\&.
+.PP
+This function is no longer different from plain
+\fBrepalloc\fR\&. It\*(Aqs kept just for backward compatibility of existing code\&.
+.SH "ARGUMENTS"
+.PP
+void * \fIpointer\fR
+.RS 4
+pointer to existing storage to change
+.RE
+.PP
+Size \fIsize\fR
+.RS 4
+size in bytes of storage to allocate
+.RE
+.SH "RETURN VALUE"
+.PP
+pointer to new storage space of specified size with the contents copied from the existing area
diff --git a/doc/src/sgml/man3/SPI_result_code_string.3 b/doc/src/sgml/man3/SPI_result_code_string.3
new file mode 100644
index 0000000..3c579fe
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_result_code_string.3
@@ -0,0 +1,50 @@
+'\" t
+.\" Title: SPI_result_code_string
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_RESULT_CODE_STRING" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_result_code_string \- return error code as string
+.SH "SYNOPSIS"
+.sp
+.nf
+const char * SPI_result_code_string(int \fIcode\fR);
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_result_code_string\fR
+returns a string representation of the result code returned by various SPI functions or stored in
+\fISPI_result\fR\&.
+.SH "ARGUMENTS"
+.PP
+int \fIcode\fR
+.RS 4
+result code
+.RE
+.SH "RETURN VALUE"
+.PP
+A string representation of the result code\&.
diff --git a/doc/src/sgml/man3/SPI_returntuple.3 b/doc/src/sgml/man3/SPI_returntuple.3
new file mode 100644
index 0000000..b720564
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_returntuple.3
@@ -0,0 +1,73 @@
+'\" t
+.\" Title: SPI_returntuple
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_RETURNTUPLE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_returntuple \- prepare to return a tuple as a Datum
+.SH "SYNOPSIS"
+.sp
+.nf
+HeapTupleHeader SPI_returntuple(HeapTuple \fIrow\fR, TupleDesc \fIrowdesc\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_returntuple\fR
+makes a copy of a row in the upper executor context, returning it in the form of a row type
+Datum\&. The returned pointer need only be converted to
+Datum
+via
+\fBPointerGetDatum\fR
+before returning\&.
+.PP
+This function can only be used while connected to SPI\&. Otherwise, it returns NULL and sets
+\fISPI_result\fR
+to
+SPI_ERROR_UNCONNECTED\&.
+.PP
+Note that this should be used for functions that are declared to return composite types\&. It is not used for triggers; use
+\fBSPI_copytuple\fR
+for returning a modified row in a trigger\&.
+.SH "ARGUMENTS"
+.PP
+HeapTuple \fIrow\fR
+.RS 4
+row to be copied
+.RE
+.PP
+TupleDesc \fIrowdesc\fR
+.RS 4
+descriptor for row (pass the same descriptor each time for most effective caching)
+.RE
+.SH "RETURN VALUE"
+.PP
+HeapTupleHeader
+pointing to copied row, or
+NULL
+on error (see
+\fISPI_result\fR
+for an error indication)
diff --git a/doc/src/sgml/man3/SPI_rollback.3 b/doc/src/sgml/man3/SPI_rollback.3
new file mode 100644
index 0000000..a895038
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_rollback.3
@@ -0,0 +1,52 @@
+'\" t
+.\" Title: SPI_rollback
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_ROLLBACK" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_rollback, SPI_rollback_and_chain \- abort the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_rollback(void)
+.fi
+.sp
+.nf
+void SPI_rollback_and_chain(void)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_rollback\fR
+rolls back the current transaction\&. It is approximately equivalent to running the SQL command
+\fBROLLBACK\fR\&. After the transaction is rolled back, a new transaction is automatically started using default transaction characteristics, so that the caller can continue using SPI facilities\&.
+.PP
+\fBSPI_rollback_and_chain\fR
+is the same, but the new transaction is started with the same transaction characteristics as the just finished one, like with the SQL command
+\fBROLLBACK AND CHAIN\fR\&.
+.PP
+These functions can only be executed if the SPI connection has been set as nonatomic in the call to
+\fBSPI_connect_ext\fR\&.
diff --git a/doc/src/sgml/man3/SPI_rollback_and_chain.3 b/doc/src/sgml/man3/SPI_rollback_and_chain.3
new file mode 100644
index 0000000..25edc95
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_rollback_and_chain.3
@@ -0,0 +1 @@
+.so man3/SPI_rollback.3
diff --git a/doc/src/sgml/man3/SPI_saveplan.3 b/doc/src/sgml/man3/SPI_saveplan.3
new file mode 100644
index 0000000..f514ced
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_saveplan.3
@@ -0,0 +1,80 @@
+'\" t
+.\" Title: SPI_saveplan
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_SAVEPLAN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_saveplan \- save a prepared statement
+.SH "SYNOPSIS"
+.sp
+.nf
+SPIPlanPtr SPI_saveplan(SPIPlanPtr \fIplan\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_saveplan\fR
+copies a passed statement (prepared by
+\fBSPI_prepare\fR) into memory that will not be freed by
+\fBSPI_finish\fR
+nor by the transaction manager, and returns a pointer to the copied statement\&. This gives you the ability to reuse prepared statements in the subsequent invocations of your C function in the current session\&.
+.SH "ARGUMENTS"
+.PP
+SPIPlanPtr \fIplan\fR
+.RS 4
+the prepared statement to be saved
+.RE
+.SH "RETURN VALUE"
+.PP
+Pointer to the copied statement; or
+NULL
+if unsuccessful\&. On error,
+\fISPI_result\fR
+is set thus:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fIplan\fR
+is
+NULL
+or invalid
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if called from an unconnected C function
+.RE
+.SH "NOTES"
+.PP
+The originally passed\-in statement is not freed, so you might wish to do
+\fBSPI_freeplan\fR
+on it to avoid leaking memory until
+\fBSPI_finish\fR\&.
+.PP
+In most cases,
+\fBSPI_keepplan\fR
+is preferred to this function, since it accomplishes largely the same result without needing to physically copy the prepared statement\*(Aqs data structures\&.
diff --git a/doc/src/sgml/man3/SPI_scroll_cursor_fetch.3 b/doc/src/sgml/man3/SPI_scroll_cursor_fetch.3
new file mode 100644
index 0000000..545c94e
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_scroll_cursor_fetch.3
@@ -0,0 +1,91 @@
+'\" t
+.\" Title: SPI_scroll_cursor_fetch
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_SCROLL_CURSOR_FETCH" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_scroll_cursor_fetch \- fetch some rows from a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_scroll_cursor_fetch(Portal \fIportal\fR, FetchDirection \fIdirection\fR,
+ long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_scroll_cursor_fetch\fR
+fetches some rows from a cursor\&. This is equivalent to the SQL command
+\fBFETCH\fR\&.
+.SH "ARGUMENTS"
+.PP
+Portal \fIportal\fR
+.RS 4
+portal containing the cursor
+.RE
+.PP
+FetchDirection \fIdirection\fR
+.RS 4
+one of
+FETCH_FORWARD,
+FETCH_BACKWARD,
+FETCH_ABSOLUTE
+or
+FETCH_RELATIVE
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+number of rows to fetch for
+FETCH_FORWARD
+or
+FETCH_BACKWARD; absolute row number to fetch for
+FETCH_ABSOLUTE; or relative row number to fetch for
+FETCH_RELATIVE
+.RE
+.SH "RETURN VALUE"
+.PP
+\fISPI_processed\fR
+and
+\fISPI_tuptable\fR
+are set as in
+\fBSPI_execute\fR
+if successful\&.
+.SH "NOTES"
+.PP
+See the SQL
+\fBFETCH\fR(7)
+command for details of the interpretation of the
+\fIdirection\fR
+and
+\fIcount\fR
+parameters\&.
+.PP
+Direction values other than
+FETCH_FORWARD
+may fail if the cursor\*(Aqs plan was not created with the
+CURSOR_OPT_SCROLL
+option\&.
diff --git a/doc/src/sgml/man3/SPI_scroll_cursor_move.3 b/doc/src/sgml/man3/SPI_scroll_cursor_move.3
new file mode 100644
index 0000000..eaa793f
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_scroll_cursor_move.3
@@ -0,0 +1,92 @@
+'\" t
+.\" Title: SPI_scroll_cursor_move
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_SCROLL_CURSOR_MOVE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_scroll_cursor_move \- move a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_scroll_cursor_move(Portal \fIportal\fR, FetchDirection \fIdirection\fR,
+ long \fIcount\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_scroll_cursor_move\fR
+skips over some number of rows in a cursor\&. This is equivalent to the SQL command
+\fBMOVE\fR\&.
+.SH "ARGUMENTS"
+.PP
+Portal \fIportal\fR
+.RS 4
+portal containing the cursor
+.RE
+.PP
+FetchDirection \fIdirection\fR
+.RS 4
+one of
+FETCH_FORWARD,
+FETCH_BACKWARD,
+FETCH_ABSOLUTE
+or
+FETCH_RELATIVE
+.RE
+.PP
+long \fIcount\fR
+.RS 4
+number of rows to move for
+FETCH_FORWARD
+or
+FETCH_BACKWARD; absolute row number to move to for
+FETCH_ABSOLUTE; or relative row number to move to for
+FETCH_RELATIVE
+.RE
+.SH "RETURN VALUE"
+.PP
+\fISPI_processed\fR
+is set as in
+\fBSPI_execute\fR
+if successful\&.
+\fISPI_tuptable\fR
+is set to
+NULL, since no rows are returned by this function\&.
+.SH "NOTES"
+.PP
+See the SQL
+\fBFETCH\fR(7)
+command for details of the interpretation of the
+\fIdirection\fR
+and
+\fIcount\fR
+parameters\&.
+.PP
+Direction values other than
+FETCH_FORWARD
+may fail if the cursor\*(Aqs plan was not created with the
+CURSOR_OPT_SCROLL
+option\&.
diff --git a/doc/src/sgml/man3/SPI_start_transaction.3 b/doc/src/sgml/man3/SPI_start_transaction.3
new file mode 100644
index 0000000..363316b
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_start_transaction.3
@@ -0,0 +1,45 @@
+'\" t
+.\" Title: SPI_start_transaction
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_START_TRANSACTION" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_start_transaction \- obsolete function
+.SH "SYNOPSIS"
+.sp
+.nf
+void SPI_start_transaction(void)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_start_transaction\fR
+does nothing, and exists only for code compatibility with earlier
+PostgreSQL
+releases\&. It used to be required after calling
+\fBSPI_commit\fR
+or
+\fBSPI_rollback\fR, but now those functions start a new transaction automatically\&.
diff --git a/doc/src/sgml/man3/SPI_unregister_relation.3 b/doc/src/sgml/man3/SPI_unregister_relation.3
new file mode 100644
index 0000000..892043c
--- /dev/null
+++ b/doc/src/sgml/man3/SPI_unregister_relation.3
@@ -0,0 +1,76 @@
+'\" t
+.\" Title: SPI_unregister_relation
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SPI_UNREGISTER_RELATION" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SPI_unregister_relation \- remove an ephemeral named relation from the registry
+.SH "SYNOPSIS"
+.sp
+.nf
+int SPI_unregister_relation(const char * \fIname\fR)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSPI_unregister_relation\fR
+removes an ephemeral named relation from the registry for the current connection\&.
+.SH "ARGUMENTS"
+.PP
+const char * \fIname\fR
+.RS 4
+the relation registry entry name
+.RE
+.SH "RETURN VALUE"
+.PP
+If the execution of the command was successful then the following (nonnegative) value will be returned:
+.PP
+SPI_OK_REL_UNREGISTER
+.RS 4
+if the tuplestore has been successfully removed from the registry
+.RE
+.PP
+On error, one of the following negative values is returned:
+.PP
+SPI_ERROR_ARGUMENT
+.RS 4
+if
+\fIname\fR
+is
+NULL
+.RE
+.PP
+SPI_ERROR_UNCONNECTED
+.RS 4
+if called from an unconnected C function
+.RE
+.PP
+SPI_ERROR_REL_NOT_FOUND
+.RS 4
+if
+\fIname\fR
+is not found in the registry for the current connection
+.RE
diff --git a/doc/src/sgml/man3/dblink.3 b/doc/src/sgml/man3/dblink.3
new file mode 100644
index 0000000..76d5e9c
--- /dev/null
+++ b/doc/src/sgml/man3/dblink.3
@@ -0,0 +1,212 @@
+'\" t
+.\" Title: dblink
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink \- executes a query in a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink(text connname, text sql [, bool fail_on_error]) returns setof record
+dblink(text connstr, text sql [, bool fail_on_error]) returns setof record
+dblink(text sql [, bool fail_on_error]) returns setof record
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink\fR
+executes a query (usually a
+\fBSELECT\fR, but it can be any SQL statement that returns rows) in a remote database\&.
+.PP
+When two
+text
+arguments are given, the first one is first looked up as a persistent connection\*(Aqs name; if found, the command is executed on that connection\&. If not found, the first argument is treated as a connection info string as for
+\fBdblink_connect\fR, and the indicated connection is made just for the duration of this command\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use; omit this parameter to use the unnamed connection\&.
+.RE
+.PP
+\fIconnstr\fR
+.RS 4
+A connection info string, as previously described for
+\fBdblink_connect\fR\&.
+.RE
+.PP
+\fIsql\fR
+.RS 4
+The SQL query that you wish to execute in the remote database, for example
+select * from foo\&.
+.RE
+.PP
+\fIfail_on_error\fR
+.RS 4
+If true (the default when omitted) then an error thrown on the remote side of the connection causes an error to also be thrown locally\&. If false, the remote error is locally reported as a NOTICE, and the function returns no rows\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+The function returns the row(s) produced by the query\&. Since
+\fBdblink\fR
+can be used with any query, it is declared to return
+record, rather than specifying any particular set of columns\&. This means that you must specify the expected set of columns in the calling query \(em otherwise
+PostgreSQL
+would not know what to expect\&. Here is an example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT *
+ FROM dblink(\*(Aqdbname=mydb options=\-csearch_path=\*(Aq,
+ \*(Aqselect proname, prosrc from pg_proc\*(Aq)
+ AS t1(proname name, prosrc text)
+ WHERE proname LIKE \*(Aqbytea%\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\(lqalias\(rq
+part of the
+FROM
+clause must specify the column names and types that the function will return\&. (Specifying column names in an alias is actually standard SQL syntax, but specifying column types is a
+PostgreSQL
+extension\&.) This allows the system to understand what
+*
+should expand to, and what
+proname
+in the
+WHERE
+clause refers to, in advance of trying to execute the function\&. At run time, an error will be thrown if the actual query result from the remote database does not have the same number of columns shown in the
+FROM
+clause\&. The column names need not match, however, and
+\fBdblink\fR
+does not insist on exact type matches either\&. It will succeed so long as the returned data strings are valid input for the column type declared in the
+FROM
+clause\&.
+.SH "NOTES"
+.PP
+A convenient way to use
+\fBdblink\fR
+with predetermined queries is to create a view\&. This allows the column type information to be buried in the view, instead of having to spell it out in every query\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW myremote_pg_proc AS
+ SELECT *
+ FROM dblink(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq,
+ \*(Aqselect proname, prosrc from pg_proc\*(Aq)
+ AS t1(proname name, prosrc text);
+
+SELECT * FROM myremote_pg_proc WHERE proname LIKE \*(Aqbytea%\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM dblink(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq,
+ \*(Aqselect proname, prosrc from pg_proc\*(Aq)
+ AS t1(proname name, prosrc text) WHERE proname LIKE \*(Aqbytea%\*(Aq;
+ proname | prosrc
+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteain | byteain
+ byteaout | byteaout
+(12 rows)
+
+SELECT dblink_connect(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT * FROM dblink(\*(Aqselect proname, prosrc from pg_proc\*(Aq)
+ AS t1(proname name, prosrc text) WHERE proname LIKE \*(Aqbytea%\*(Aq;
+ proname | prosrc
+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteain | byteain
+ byteaout | byteaout
+(12 rows)
+
+SELECT dblink_connect(\*(Aqmyconn\*(Aq, \*(Aqdbname=regression options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT * FROM dblink(\*(Aqmyconn\*(Aq, \*(Aqselect proname, prosrc from pg_proc\*(Aq)
+ AS t1(proname name, prosrc text) WHERE proname LIKE \*(Aqbytea%\*(Aq;
+ proname | prosrc
+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+ bytearecv | bytearecv
+ byteasend | byteasend
+ byteale | byteale
+ byteagt | byteagt
+ byteage | byteage
+ byteane | byteane
+ byteacmp | byteacmp
+ bytealike | bytealike
+ byteanlike | byteanlike
+ byteacat | byteacat
+ byteaeq | byteaeq
+ bytealt | bytealt
+ byteain | byteain
+ byteaout | byteaout
+(14 rows)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_build_sql_delete.3 b/doc/src/sgml/man3/dblink_build_sql_delete.3
new file mode 100644
index 0000000..06e77df
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_build_sql_delete.3
@@ -0,0 +1,99 @@
+'\" t
+.\" Title: dblink_build_sql_delete
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_BUILD_SQL_DELETE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_build_sql_delete \- builds a DELETE statement using supplied values for primary key field values
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_build_sql_delete(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] tgt_pk_att_vals_array) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_build_sql_delete\fR
+can be useful in doing selective replication of a local table to a remote database\&. It builds an SQL
+\fBDELETE\fR
+command that will delete the row with the given primary key values\&.
+.SH "ARGUMENTS"
+.PP
+\fIrelname\fR
+.RS 4
+Name of a local relation, for example
+foo
+or
+myschema\&.mytab\&. Include double quotes if the name is mixed\-case or contains special characters, for example
+"FooBar"; without quotes, the string will be folded to lower case\&.
+.RE
+.PP
+\fIprimary_key_attnums\fR
+.RS 4
+Attribute numbers (1\-based) of the primary key fields, for example
+1 2\&.
+.RE
+.PP
+\fInum_primary_key_atts\fR
+.RS 4
+The number of primary key fields\&.
+.RE
+.PP
+\fItgt_pk_att_vals_array\fR
+.RS 4
+Values of the primary key fields to be used in the resulting
+\fBDELETE\fR
+command\&. Each field is represented in text form\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns the requested SQL statement as text\&.
+.SH "NOTES"
+.PP
+As of
+PostgreSQL
+9\&.0, the attribute numbers in
+\fIprimary_key_attnums\fR
+are interpreted as logical column numbers, corresponding to the column\*(Aqs position in
+SELECT * FROM relname\&. Previous versions interpreted the numbers as physical column positions\&. There is a difference if any column(s) to the left of the indicated column have been dropped during the lifetime of the table\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_build_sql_delete(\*(Aq"MyFoo"\*(Aq, \*(Aq1 2\*(Aq, 2, \*(Aq{"1", "b"}\*(Aq);
+ dblink_build_sql_delete
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ DELETE FROM "MyFoo" WHERE f1=\*(Aq1\*(Aq AND f2=\*(Aqb\*(Aq
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_build_sql_insert.3 b/doc/src/sgml/man3/dblink_build_sql_insert.3
new file mode 100644
index 0000000..a80c779
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_build_sql_insert.3
@@ -0,0 +1,105 @@
+'\" t
+.\" Title: dblink_build_sql_insert
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_BUILD_SQL_INSERT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_build_sql_insert \- builds an INSERT statement using a local tuple, replacing the primary key field values with alternative supplied values
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_build_sql_insert(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] src_pk_att_vals_array,
+ text[] tgt_pk_att_vals_array) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_build_sql_insert\fR
+can be useful in doing selective replication of a local table to a remote database\&. It selects a row from the local table based on primary key, and then builds an SQL
+\fBINSERT\fR
+command that will duplicate that row, but with the primary key values replaced by the values in the last argument\&. (To make an exact copy of the row, just specify the same values for the last two arguments\&.)
+.SH "ARGUMENTS"
+.PP
+\fIrelname\fR
+.RS 4
+Name of a local relation, for example
+foo
+or
+myschema\&.mytab\&. Include double quotes if the name is mixed\-case or contains special characters, for example
+"FooBar"; without quotes, the string will be folded to lower case\&.
+.RE
+.PP
+\fIprimary_key_attnums\fR
+.RS 4
+Attribute numbers (1\-based) of the primary key fields, for example
+1 2\&.
+.RE
+.PP
+\fInum_primary_key_atts\fR
+.RS 4
+The number of primary key fields\&.
+.RE
+.PP
+\fIsrc_pk_att_vals_array\fR
+.RS 4
+Values of the primary key fields to be used to look up the local tuple\&. Each field is represented in text form\&. An error is thrown if there is no local row with these primary key values\&.
+.RE
+.PP
+\fItgt_pk_att_vals_array\fR
+.RS 4
+Values of the primary key fields to be placed in the resulting
+\fBINSERT\fR
+command\&. Each field is represented in text form\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns the requested SQL statement as text\&.
+.SH "NOTES"
+.PP
+As of
+PostgreSQL
+9\&.0, the attribute numbers in
+\fIprimary_key_attnums\fR
+are interpreted as logical column numbers, corresponding to the column\*(Aqs position in
+SELECT * FROM relname\&. Previous versions interpreted the numbers as physical column positions\&. There is a difference if any column(s) to the left of the indicated column have been dropped during the lifetime of the table\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_build_sql_insert(\*(Aqfoo\*(Aq, \*(Aq1 2\*(Aq, 2, \*(Aq{"1", "a"}\*(Aq, \*(Aq{"1", "b\*(Aq\*(Aqa"}\*(Aq);
+ dblink_build_sql_insert
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ INSERT INTO foo(f1,f2,f3) VALUES(\*(Aq1\*(Aq,\*(Aqb\*(Aq\*(Aqa\*(Aq,\*(Aq1\*(Aq)
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_build_sql_update.3 b/doc/src/sgml/man3/dblink_build_sql_update.3
new file mode 100644
index 0000000..63f09a7
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_build_sql_update.3
@@ -0,0 +1,109 @@
+'\" t
+.\" Title: dblink_build_sql_update
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_BUILD_SQL_UPDATE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_build_sql_update \- builds an UPDATE statement using a local tuple, replacing the primary key field values with alternative supplied values
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_build_sql_update(text relname,
+ int2vector primary_key_attnums,
+ integer num_primary_key_atts,
+ text[] src_pk_att_vals_array,
+ text[] tgt_pk_att_vals_array) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_build_sql_update\fR
+can be useful in doing selective replication of a local table to a remote database\&. It selects a row from the local table based on primary key, and then builds an SQL
+\fBUPDATE\fR
+command that will duplicate that row, but with the primary key values replaced by the values in the last argument\&. (To make an exact copy of the row, just specify the same values for the last two arguments\&.) The
+\fBUPDATE\fR
+command always assigns all fields of the row \(em the main difference between this and
+\fBdblink_build_sql_insert\fR
+is that it\*(Aqs assumed that the target row already exists in the remote table\&.
+.SH "ARGUMENTS"
+.PP
+\fIrelname\fR
+.RS 4
+Name of a local relation, for example
+foo
+or
+myschema\&.mytab\&. Include double quotes if the name is mixed\-case or contains special characters, for example
+"FooBar"; without quotes, the string will be folded to lower case\&.
+.RE
+.PP
+\fIprimary_key_attnums\fR
+.RS 4
+Attribute numbers (1\-based) of the primary key fields, for example
+1 2\&.
+.RE
+.PP
+\fInum_primary_key_atts\fR
+.RS 4
+The number of primary key fields\&.
+.RE
+.PP
+\fIsrc_pk_att_vals_array\fR
+.RS 4
+Values of the primary key fields to be used to look up the local tuple\&. Each field is represented in text form\&. An error is thrown if there is no local row with these primary key values\&.
+.RE
+.PP
+\fItgt_pk_att_vals_array\fR
+.RS 4
+Values of the primary key fields to be placed in the resulting
+\fBUPDATE\fR
+command\&. Each field is represented in text form\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns the requested SQL statement as text\&.
+.SH "NOTES"
+.PP
+As of
+PostgreSQL
+9\&.0, the attribute numbers in
+\fIprimary_key_attnums\fR
+are interpreted as logical column numbers, corresponding to the column\*(Aqs position in
+SELECT * FROM relname\&. Previous versions interpreted the numbers as physical column positions\&. There is a difference if any column(s) to the left of the indicated column have been dropped during the lifetime of the table\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_build_sql_update(\*(Aqfoo\*(Aq, \*(Aq1 2\*(Aq, 2, \*(Aq{"1", "a"}\*(Aq, \*(Aq{"1", "b"}\*(Aq);
+ dblink_build_sql_update
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ UPDATE foo SET f1=\*(Aq1\*(Aq,f2=\*(Aqb\*(Aq,f3=\*(Aq1\*(Aq WHERE f1=\*(Aq1\*(Aq AND f2=\*(Aqb\*(Aq
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_cancel_query.3 b/doc/src/sgml/man3/dblink_cancel_query.3
new file mode 100644
index 0000000..f3ccb1a
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_cancel_query.3
@@ -0,0 +1,63 @@
+'\" t
+.\" Title: dblink_cancel_query
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_CANCEL_QUERY" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_cancel_query \- cancels any active query on the named connection
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_cancel_query(text connname) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_cancel_query\fR
+attempts to cancel any query that is in progress on the named connection\&. Note that this is not certain to succeed (since, for example, the remote query might already have finished)\&. A cancel request simply improves the odds that the query will fail soon\&. You must still complete the normal query protocol, for example by calling
+\fBdblink_get_result\fR\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns
+OK
+if the cancel request has been sent, or the text of an error message on failure\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_cancel_query(\*(Aqdtest1\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_close.3 b/doc/src/sgml/man3/dblink_close.3
new file mode 100644
index 0000000..2e9510c
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_close.3
@@ -0,0 +1,100 @@
+'\" t
+.\" Title: dblink_close
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_CLOSE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_close \- closes a cursor in a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_close(text cursorname [, bool fail_on_error]) returns text
+dblink_close(text connname, text cursorname [, bool fail_on_error]) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_close\fR
+closes a cursor previously opened with
+\fBdblink_open\fR\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use; omit this parameter to use the unnamed connection\&.
+.RE
+.PP
+\fIcursorname\fR
+.RS 4
+The name of the cursor to close\&.
+.RE
+.PP
+\fIfail_on_error\fR
+.RS 4
+If true (the default when omitted) then an error thrown on the remote side of the connection causes an error to also be thrown locally\&. If false, the remote error is locally reported as a NOTICE, and the function\*(Aqs return value is set to
+ERROR\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns status, either
+OK
+or
+ERROR\&.
+.SH "NOTES"
+.PP
+If
+\fBdblink_open\fR
+started an explicit transaction block, and this is the last remaining open cursor in this connection,
+\fBdblink_close\fR
+will issue the matching
+\fBCOMMIT\fR\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_connect(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_open(\*(Aqfoo\*(Aq, \*(Aqselect proname, prosrc from pg_proc\*(Aq);
+ dblink_open
+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_close(\*(Aqfoo\*(Aq);
+ dblink_close
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_connect.3 b/doc/src/sgml/man3/dblink_connect.3
new file mode 100644
index 0000000..c1afe37
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_connect.3
@@ -0,0 +1,155 @@
+'\" t
+.\" Title: dblink_connect
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_CONNECT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_connect \- opens a persistent connection to a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_connect(text connstr) returns text
+dblink_connect(text connname, text connstr) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_connect()\fR
+establishes a connection to a remote
+PostgreSQL
+database\&. The server and database to be contacted are identified through a standard
+libpq
+connection string\&. Optionally, a name can be assigned to the connection\&. Multiple named connections can be open at once, but only one unnamed connection is permitted at a time\&. The connection will persist until closed or until the database session is ended\&.
+.PP
+The connection string may also be the name of an existing foreign server\&. It is recommended to use the foreign\-data wrapper
+dblink_fdw
+when defining the foreign server\&. See the example below, as well as
+CREATE SERVER (\fBCREATE_SERVER\fR(7))
+and
+CREATE USER MAPPING (\fBCREATE_USER_MAPPING\fR(7))\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+The name to use for this connection; if omitted, an unnamed connection is opened, replacing any existing unnamed connection\&.
+.RE
+.PP
+\fIconnstr\fR
+.RS 4
+libpq\-style connection info string, for example
+hostaddr=127\&.0\&.0\&.1 port=5432 dbname=mydb user=postgres password=mypasswd options=\-csearch_path=\&. For details see
+Section\ \&34.1.1\&. Alternatively, the name of a foreign server\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns status, which is always
+OK
+(since any error causes the function to throw an error instead of returning)\&.
+.SH "NOTES"
+.PP
+If untrusted users have access to a database that has not adopted a
+secure schema usage pattern, begin each session by removing publicly\-writable schemas from
+\fIsearch_path\fR\&. One could, for example, add
+options=\-csearch_path=
+to
+\fIconnstr\fR\&. This consideration is not specific to
+dblink; it applies to every interface for executing arbitrary SQL commands\&.
+.PP
+Only superusers may use
+\fBdblink_connect\fR
+to create non\-password\-authenticated connections\&. If non\-superusers need this capability, use
+\fBdblink_connect_u\fR
+instead\&.
+.PP
+It is unwise to choose connection names that contain equal signs, as this opens a risk of confusion with connection info strings in other
+dblink
+functions\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_connect(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_connect(\*(Aqmyconn\*(Aq, \*(Aqdbname=postgres options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+\-\- FOREIGN DATA WRAPPER functionality
+\-\- Note: local connection must require password authentication for this to work properly
+\-\- Otherwise, you will receive the following error from dblink_connect():
+\-\- ERROR: password is required
+\-\- DETAIL: Non\-superuser cannot connect if the server does not request a password\&.
+\-\- HINT: Target server\*(Aqs authentication method must be changed\&.
+
+CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw OPTIONS (hostaddr \*(Aq127\&.0\&.0\&.1\*(Aq, dbname \*(Aqcontrib_regression\*(Aq);
+
+CREATE USER regress_dblink_user WITH PASSWORD \*(Aqsecret\*(Aq;
+CREATE USER MAPPING FOR regress_dblink_user SERVER fdtest OPTIONS (user \*(Aqregress_dblink_user\*(Aq, password \*(Aqsecret\*(Aq);
+GRANT USAGE ON FOREIGN SERVER fdtest TO regress_dblink_user;
+GRANT SELECT ON TABLE foo TO regress_dblink_user;
+
+\eset ORIGINAL_USER :USER
+\ec \- regress_dblink_user
+SELECT dblink_connect(\*(Aqmyconn\*(Aq, \*(Aqfdtest\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT * FROM dblink(\*(Aqmyconn\*(Aq, \*(AqSELECT * FROM foo\*(Aq) AS t(a int, b text, c text[]);
+ a | b | c
+\-\-\-\-+\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+ 3 | d | {a3,b3,c3}
+ 4 | e | {a4,b4,c4}
+ 5 | f | {a5,b5,c5}
+ 6 | g | {a6,b6,c6}
+ 7 | h | {a7,b7,c7}
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ 10 | k | {a10,b10,c10}
+(11 rows)
+
+\ec \- :ORIGINAL_USER
+REVOKE USAGE ON FOREIGN SERVER fdtest FROM regress_dblink_user;
+REVOKE SELECT ON TABLE foo FROM regress_dblink_user;
+DROP USER MAPPING FOR regress_dblink_user SERVER fdtest;
+DROP USER regress_dblink_user;
+DROP SERVER fdtest;
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_connect_u.3 b/doc/src/sgml/man3/dblink_connect_u.3
new file mode 100644
index 0000000..4d99a7c
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_connect_u.3
@@ -0,0 +1,62 @@
+'\" t
+.\" Title: dblink_connect_u
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_CONNECT_U" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_connect_u \- opens a persistent connection to a remote database, insecurely
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_connect_u(text connstr) returns text
+dblink_connect_u(text connname, text connstr) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_connect_u()\fR
+is identical to
+\fBdblink_connect()\fR, except that it will allow non\-superusers to connect using any authentication method\&.
+.PP
+If the remote server selects an authentication method that does not involve a password, then impersonation and subsequent escalation of privileges can occur, because the session will appear to have originated from the user as which the local
+PostgreSQL
+server runs\&. Also, even if the remote server does demand a password, it is possible for the password to be supplied from the server environment, such as a
+~/\&.pgpass
+file belonging to the server\*(Aqs user\&. This opens not only a risk of impersonation, but the possibility of exposing a password to an untrustworthy remote server\&. Therefore,
+\fBdblink_connect_u()\fR
+is initially installed with all privileges revoked from
+PUBLIC, making it un\-callable except by superusers\&. In some situations it may be appropriate to grant
+EXECUTE
+permission for
+\fBdblink_connect_u()\fR
+to specific users who are considered trustworthy, but this should be done with care\&. It is also recommended that any
+~/\&.pgpass
+file belonging to the server\*(Aqs user
+\fInot\fR
+contain any records specifying a wildcard host name\&.
+.PP
+For further details see
+\fBdblink_connect()\fR\&.
diff --git a/doc/src/sgml/man3/dblink_disconnect.3 b/doc/src/sgml/man3/dblink_disconnect.3
new file mode 100644
index 0000000..3044f6f
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_disconnect.3
@@ -0,0 +1,74 @@
+'\" t
+.\" Title: dblink_disconnect
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_DISCONNECT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_disconnect \- closes a persistent connection to a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_disconnect() returns text
+dblink_disconnect(text connname) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_disconnect()\fR
+closes a connection previously opened by
+\fBdblink_connect()\fR\&. The form with no arguments closes an unnamed connection\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+The name of a named connection to be closed\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns status, which is always
+OK
+(since any error causes the function to throw an error instead of returning)\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_disconnect();
+ dblink_disconnect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_disconnect(\*(Aqmyconn\*(Aq);
+ dblink_disconnect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_error_message.3 b/doc/src/sgml/man3/dblink_error_message.3
new file mode 100644
index 0000000..e676154
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_error_message.3
@@ -0,0 +1,71 @@
+'\" t
+.\" Title: dblink_error_message
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_ERROR_MESSAGE" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_error_message \- gets last error message on the named connection
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_error_message(text connname) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_error_message\fR
+fetches the most recent remote error message for a given connection\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns last error message, or
+OK
+if there has been no error in this connection\&.
+.SH "NOTES"
+.PP
+When asynchronous queries are initiated by
+\fBdblink_send_query\fR, the error message associated with the connection might not get updated until the server\*(Aqs response message is consumed\&. This typically means that
+\fBdblink_is_busy\fR
+or
+\fBdblink_get_result\fR
+should be called prior to
+\fBdblink_error_message\fR, so that any error generated by the asynchronous query will be visible\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_error_message(\*(Aqdtest1\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_exec.3 b/doc/src/sgml/man3/dblink_exec.3
new file mode 100644
index 0000000..e0bc337
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_exec.3
@@ -0,0 +1,117 @@
+'\" t
+.\" Title: dblink_exec
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_EXEC" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_exec \- executes a command in a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_exec(text connname, text sql [, bool fail_on_error]) returns text
+dblink_exec(text connstr, text sql [, bool fail_on_error]) returns text
+dblink_exec(text sql [, bool fail_on_error]) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_exec\fR
+executes a command (that is, any SQL statement that doesn\*(Aqt return rows) in a remote database\&.
+.PP
+When two
+text
+arguments are given, the first one is first looked up as a persistent connection\*(Aqs name; if found, the command is executed on that connection\&. If not found, the first argument is treated as a connection info string as for
+\fBdblink_connect\fR, and the indicated connection is made just for the duration of this command\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use; omit this parameter to use the unnamed connection\&.
+.RE
+.PP
+\fIconnstr\fR
+.RS 4
+A connection info string, as previously described for
+\fBdblink_connect\fR\&.
+.RE
+.PP
+\fIsql\fR
+.RS 4
+The SQL command that you wish to execute in the remote database, for example
+insert into foo values(0, \*(Aqa\*(Aq, \*(Aq{"a0","b0","c0"}\*(Aq)\&.
+.RE
+.PP
+\fIfail_on_error\fR
+.RS 4
+If true (the default when omitted) then an error thrown on the remote side of the connection causes an error to also be thrown locally\&. If false, the remote error is locally reported as a NOTICE, and the function\*(Aqs return value is set to
+ERROR\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns status, either the command\*(Aqs status string or
+ERROR\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_connect(\*(Aqdbname=dblink_test_standby\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_exec(\*(Aqinsert into foo values(21, \*(Aq\*(Aqz\*(Aq\*(Aq, \*(Aq\*(Aq{"a0","b0","c0"}\*(Aq\*(Aq);\*(Aq);
+ dblink_exec
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ INSERT 943366 1
+(1 row)
+
+SELECT dblink_connect(\*(Aqmyconn\*(Aq, \*(Aqdbname=regression\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_exec(\*(Aqmyconn\*(Aq, \*(Aqinsert into foo values(21, \*(Aq\*(Aqz\*(Aq\*(Aq, \*(Aq\*(Aq{"a0","b0","c0"}\*(Aq\*(Aq);\*(Aq);
+ dblink_exec
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ INSERT 6432584 1
+(1 row)
+
+SELECT dblink_exec(\*(Aqmyconn\*(Aq, \*(Aqinsert into pg_class values (\*(Aq\*(Aqfoo\*(Aq\*(Aq)\*(Aq,false);
+NOTICE: sql error
+DETAIL: ERROR: null value in column "relnamespace" violates not\-null constraint
+
+ dblink_exec
+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ ERROR
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_fetch.3 b/doc/src/sgml/man3/dblink_fetch.3
new file mode 100644
index 0000000..133ebfc
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_fetch.3
@@ -0,0 +1,129 @@
+'\" t
+.\" Title: dblink_fetch
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_FETCH" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_fetch \- returns rows from an open cursor in a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_fetch(text cursorname, int howmany [, bool fail_on_error]) returns setof record
+dblink_fetch(text connname, text cursorname, int howmany [, bool fail_on_error]) returns setof record
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_fetch\fR
+fetches rows from a cursor previously established by
+\fBdblink_open\fR\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use; omit this parameter to use the unnamed connection\&.
+.RE
+.PP
+\fIcursorname\fR
+.RS 4
+The name of the cursor to fetch from\&.
+.RE
+.PP
+\fIhowmany\fR
+.RS 4
+The maximum number of rows to retrieve\&. The next
+\fIhowmany\fR
+rows are fetched, starting at the current cursor position, moving forward\&. Once the cursor has reached its end, no more rows are produced\&.
+.RE
+.PP
+\fIfail_on_error\fR
+.RS 4
+If true (the default when omitted) then an error thrown on the remote side of the connection causes an error to also be thrown locally\&. If false, the remote error is locally reported as a NOTICE, and the function returns no rows\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+The function returns the row(s) fetched from the cursor\&. To use this function, you will need to specify the expected set of columns, as previously discussed for
+\fBdblink\fR\&.
+.SH "NOTES"
+.PP
+On a mismatch between the number of return columns specified in the
+FROM
+clause, and the actual number of columns returned by the remote cursor, an error will be thrown\&. In this event, the remote cursor is still advanced by as many rows as it would have been if the error had not occurred\&. The same is true for any other error occurring in the local query after the remote
+\fBFETCH\fR
+has been done\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_connect(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_open(\*(Aqfoo\*(Aq, \*(Aqselect proname, prosrc from pg_proc where proname like \*(Aq\*(Aqbytea%\*(Aq\*(Aq\*(Aq);
+ dblink_open
+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT * FROM dblink_fetch(\*(Aqfoo\*(Aq, 5) AS (funcname name, source text);
+ funcname | source
+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-
+ byteacat | byteacat
+ byteacmp | byteacmp
+ byteaeq | byteaeq
+ byteage | byteage
+ byteagt | byteagt
+(5 rows)
+
+SELECT * FROM dblink_fetch(\*(Aqfoo\*(Aq, 5) AS (funcname name, source text);
+ funcname | source
+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-
+ byteain | byteain
+ byteale | byteale
+ bytealike | bytealike
+ bytealt | bytealt
+ byteane | byteane
+(5 rows)
+
+SELECT * FROM dblink_fetch(\*(Aqfoo\*(Aq, 5) AS (funcname name, source text);
+ funcname | source
+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+ byteanlike | byteanlike
+ byteaout | byteaout
+(2 rows)
+
+SELECT * FROM dblink_fetch(\*(Aqfoo\*(Aq, 5) AS (funcname name, source text);
+ funcname | source
+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-
+(0 rows)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_get_connections.3 b/doc/src/sgml/man3/dblink_get_connections.3
new file mode 100644
index 0000000..5e0544e
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_get_connections.3
@@ -0,0 +1,56 @@
+'\" t
+.\" Title: dblink_get_connections
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_GET_CONNECTIONS" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_get_connections \- returns the names of all open named dblink connections
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_get_connections() returns text[]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_get_connections\fR
+returns an array of the names of all open named
+dblink
+connections\&.
+.SH "RETURN VALUE"
+.PP
+Returns a text array of connection names, or NULL if none\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_get_connections();
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_get_notify.3 b/doc/src/sgml/man3/dblink_get_notify.3
new file mode 100644
index 0000000..9be6325
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_get_notify.3
@@ -0,0 +1,86 @@
+'\" t
+.\" Title: dblink_get_notify
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_GET_NOTIFY" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_get_notify \- retrieve async notifications on a connection
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_get_notify() returns setof (notify_name text, be_pid int, extra text)
+dblink_get_notify(text connname) returns setof (notify_name text, be_pid int, extra text)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_get_notify\fR
+retrieves notifications on either the unnamed connection, or on a named connection if specified\&. To receive notifications via dblink,
+\fBLISTEN\fR
+must first be issued, using
+\fBdblink_exec\fR\&. For details see
+\fBLISTEN\fR(7)
+and
+\fBNOTIFY\fR(7)\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+The name of a named connection to get notifications on\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns
+setof (notify_name text, be_pid int, extra text), or an empty set if none\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_exec(\*(AqLISTEN virtual\*(Aq);
+ dblink_exec
+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ LISTEN
+(1 row)
+
+SELECT * FROM dblink_get_notify();
+ notify_name | be_pid | extra
+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+(0 rows)
+
+NOTIFY virtual;
+NOTIFY
+
+SELECT * FROM dblink_get_notify();
+ notify_name | be_pid | extra
+\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+ virtual | 1229 |
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_get_pkey.3 b/doc/src/sgml/man3/dblink_get_pkey.3
new file mode 100644
index 0000000..b0c62fb
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_get_pkey.3
@@ -0,0 +1,93 @@
+'\" t
+.\" Title: dblink_get_pkey
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_GET_PKEY" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_get_pkey \- returns the positions and field names of a relation\*(Aqs primary key fields
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_get_pkey(text relname) returns setof dblink_pkey_results
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_get_pkey\fR
+provides information about the primary key of a relation in the local database\&. This is sometimes useful in generating queries to be sent to remote databases\&.
+.SH "ARGUMENTS"
+.PP
+\fIrelname\fR
+.RS 4
+Name of a local relation, for example
+foo
+or
+myschema\&.mytab\&. Include double quotes if the name is mixed\-case or contains special characters, for example
+"FooBar"; without quotes, the string will be folded to lower case\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns one row for each primary key field, or no rows if the relation has no primary key\&. The result row type is defined as
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE dblink_pkey_results AS (position int, colname text);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+position
+column simply runs from 1 to
+\fIN\fR; it is the number of the field within the primary key, not the number within the table\*(Aqs columns\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE foobar (
+ f1 int,
+ f2 int,
+ f3 int,
+ PRIMARY KEY (f1, f2, f3)
+);
+CREATE TABLE
+
+SELECT * FROM dblink_get_pkey(\*(Aqfoobar\*(Aq);
+ position | colname
+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-
+ 1 | f1
+ 2 | f2
+ 3 | f3
+(3 rows)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_get_result.3 b/doc/src/sgml/man3/dblink_get_result.3
new file mode 100644
index 0000000..e3014a0
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_get_result.3
@@ -0,0 +1,143 @@
+'\" t
+.\" Title: dblink_get_result
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_GET_RESULT" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_get_result \- gets an async query result
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_get_result(text connname [, bool fail_on_error]) returns setof record
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_get_result\fR
+collects the results of an asynchronous query previously sent with
+\fBdblink_send_query\fR\&. If the query is not already completed,
+\fBdblink_get_result\fR
+will wait until it is\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use\&.
+.RE
+.PP
+\fIfail_on_error\fR
+.RS 4
+If true (the default when omitted) then an error thrown on the remote side of the connection causes an error to also be thrown locally\&. If false, the remote error is locally reported as a NOTICE, and the function returns no rows\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+For an async query (that is, an SQL statement returning rows), the function returns the row(s) produced by the query\&. To use this function, you will need to specify the expected set of columns, as previously discussed for
+\fBdblink\fR\&.
+.PP
+For an async command (that is, an SQL statement not returning rows), the function returns a single row with a single text column containing the command\*(Aqs status string\&. It is still necessary to specify that the result will have a single text column in the calling
+FROM
+clause\&.
+.SH "NOTES"
+.PP
+This function
+\fImust\fR
+be called if
+\fBdblink_send_query\fR
+returned 1\&. It must be called once for each query sent, and one additional time to obtain an empty set result, before the connection can be used again\&.
+.PP
+When using
+\fBdblink_send_query\fR
+and
+\fBdblink_get_result\fR,
+dblink
+fetches the entire remote query result before returning any of it to the local query processor\&. If the query returns a large number of rows, this can result in transient memory bloat in the local session\&. It may be better to open such a query as a cursor with
+\fBdblink_open\fR
+and then fetch a manageable number of rows at a time\&. Alternatively, use plain
+\fBdblink()\fR, which avoids memory bloat by spooling large result sets to disk\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+contrib_regression=# SELECT dblink_connect(\*(Aqdtest1\*(Aq, \*(Aqdbname=contrib_regression\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+contrib_regression=# SELECT * FROM
+contrib_regression\-# dblink_send_query(\*(Aqdtest1\*(Aq, \*(Aqselect * from foo where f1 < 3\*(Aq) AS t1;
+ t1
+\-\-\-\-
+ 1
+(1 row)
+
+contrib_regression=# SELECT * FROM dblink_get_result(\*(Aqdtest1\*(Aq) AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+\-\-\-\-+\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+(3 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result(\*(Aqdtest1\*(Aq) AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+\-\-\-\-+\-\-\-\-+\-\-\-\-
+(0 rows)
+
+contrib_regression=# SELECT * FROM
+contrib_regression\-# dblink_send_query(\*(Aqdtest1\*(Aq, \*(Aqselect * from foo where f1 < 3; select * from foo where f1 > 6\*(Aq) AS t1;
+ t1
+\-\-\-\-
+ 1
+(1 row)
+
+contrib_regression=# SELECT * FROM dblink_get_result(\*(Aqdtest1\*(Aq) AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+\-\-\-\-+\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-
+ 0 | a | {a0,b0,c0}
+ 1 | b | {a1,b1,c1}
+ 2 | c | {a2,b2,c2}
+(3 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result(\*(Aqdtest1\*(Aq) AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+\-\-\-\-+\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 7 | h | {a7,b7,c7}
+ 8 | i | {a8,b8,c8}
+ 9 | j | {a9,b9,c9}
+ 10 | k | {a10,b10,c10}
+(4 rows)
+
+contrib_regression=# SELECT * FROM dblink_get_result(\*(Aqdtest1\*(Aq) AS t1(f1 int, f2 text, f3 text[]);
+ f1 | f2 | f3
+\-\-\-\-+\-\-\-\-+\-\-\-\-
+(0 rows)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_is_busy.3 b/doc/src/sgml/man3/dblink_is_busy.3
new file mode 100644
index 0000000..61fc093
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_is_busy.3
@@ -0,0 +1,62 @@
+'\" t
+.\" Title: dblink_is_busy
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_IS_BUSY" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_is_busy \- checks if connection is busy with an async query
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_is_busy(text connname) returns int
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_is_busy\fR
+tests whether an async query is in progress\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to check\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns 1 if connection is busy, 0 if it is not busy\&. If this function returns 0, it is guaranteed that
+\fBdblink_get_result\fR
+will not block\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_is_busy(\*(Aqdtest1\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_open.3 b/doc/src/sgml/man3/dblink_open.3
new file mode 100644
index 0000000..bdaceb0
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_open.3
@@ -0,0 +1,113 @@
+'\" t
+.\" Title: dblink_open
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_OPEN" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_open \- opens a cursor in a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_open(text cursorname, text sql [, bool fail_on_error]) returns text
+dblink_open(text connname, text cursorname, text sql [, bool fail_on_error]) returns text
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_open()\fR
+opens a cursor in a remote database\&. The cursor can subsequently be manipulated with
+\fBdblink_fetch()\fR
+and
+\fBdblink_close()\fR\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use; omit this parameter to use the unnamed connection\&.
+.RE
+.PP
+\fIcursorname\fR
+.RS 4
+The name to assign to this cursor\&.
+.RE
+.PP
+\fIsql\fR
+.RS 4
+The
+\fBSELECT\fR
+statement that you wish to execute in the remote database, for example
+select * from pg_class\&.
+.RE
+.PP
+\fIfail_on_error\fR
+.RS 4
+If true (the default when omitted) then an error thrown on the remote side of the connection causes an error to also be thrown locally\&. If false, the remote error is locally reported as a NOTICE, and the function\*(Aqs return value is set to
+ERROR\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns status, either
+OK
+or
+ERROR\&.
+.SH "NOTES"
+.PP
+Since a cursor can only persist within a transaction,
+\fBdblink_open\fR
+starts an explicit transaction block (\fBBEGIN\fR) on the remote side, if the remote side was not already within a transaction\&. This transaction will be closed again when the matching
+\fBdblink_close\fR
+is executed\&. Note that if you use
+\fBdblink_exec\fR
+to change data between
+\fBdblink_open\fR
+and
+\fBdblink_close\fR, and then an error occurs or you use
+\fBdblink_disconnect\fR
+before
+\fBdblink_close\fR, your change
+\fIwill be lost\fR
+because the transaction will be aborted\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_connect(\*(Aqdbname=postgres options=\-csearch_path=\*(Aq);
+ dblink_connect
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+
+SELECT dblink_open(\*(Aqfoo\*(Aq, \*(Aqselect proname, prosrc from pg_proc\*(Aq);
+ dblink_open
+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ OK
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man3/dblink_send_query.3 b/doc/src/sgml/man3/dblink_send_query.3
new file mode 100644
index 0000000..9232ea3
--- /dev/null
+++ b/doc/src/sgml/man3/dblink_send_query.3
@@ -0,0 +1,71 @@
+'\" t
+.\" Title: dblink_send_query
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DBLINK_SEND_QUERY" "3" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+dblink_send_query \- sends an async query to a remote database
+.SH "SYNOPSIS"
+.sp
+.nf
+dblink_send_query(text connname, text sql) returns int
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBdblink_send_query\fR
+sends a query to be executed asynchronously, that is, without immediately waiting for the result\&. There must not be an async query already in progress on the connection\&.
+.PP
+After successfully dispatching an async query, completion status can be checked with
+\fBdblink_is_busy\fR, and the results are ultimately collected with
+\fBdblink_get_result\fR\&. It is also possible to attempt to cancel an active async query using
+\fBdblink_cancel_query\fR\&.
+.SH "ARGUMENTS"
+.PP
+\fIconnname\fR
+.RS 4
+Name of the connection to use\&.
+.RE
+.PP
+\fIsql\fR
+.RS 4
+The SQL statement that you wish to execute in the remote database, for example
+select * from pg_class\&.
+.RE
+.SH "RETURN VALUE"
+.PP
+Returns 1 if the query was successfully dispatched, 0 otherwise\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT dblink_send_query(\*(Aqdtest1\*(Aq, \*(AqSELECT * FROM foo WHERE f1 < 3\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
diff --git a/doc/src/sgml/man7/ABORT.7 b/doc/src/sgml/man7/ABORT.7
new file mode 100644
index 0000000..1aae154
--- /dev/null
+++ b/doc/src/sgml/man7/ABORT.7
@@ -0,0 +1,90 @@
+'\" t
+.\" Title: ABORT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ABORT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ABORT \- abort the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBABORT\fR
+rolls back the current transaction and causes all the updates made by the transaction to be discarded\&. This command is identical in behavior to the standard
+SQL
+command
+\fBROLLBACK\fR, and is present only for historical reasons\&.
+.SH "PARAMETERS"
+.PP
+WORK
+.br
+TRANSACTION
+.RS 4
+Optional key words\&. They have no effect\&.
+.RE
+.PP
+AND CHAIN
+.RS 4
+If
+AND CHAIN
+is specified, a new transaction is immediately started with the same transaction characteristics (see
+\fBSET TRANSACTION\fR) as the just finished one\&. Otherwise, no new transaction is started\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBCOMMIT\fR
+to successfully terminate a transaction\&.
+.PP
+Issuing
+\fBABORT\fR
+outside of a transaction block emits a warning and otherwise has no effect\&.
+.SH "EXAMPLES"
+.PP
+To abort all changes:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ABORT;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command is a
+PostgreSQL
+extension present for historical reasons\&.
+\fBROLLBACK\fR
+is the equivalent standard SQL command\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), \fBROLLBACK\fR(7)
diff --git a/doc/src/sgml/man7/ALTER_AGGREGATE.7 b/doc/src/sgml/man7/ALTER_AGGREGATE.7
new file mode 100644
index 0000000..ca00272
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_AGGREGATE.7
@@ -0,0 +1,187 @@
+'\" t
+.\" Title: ALTER AGGREGATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER AGGREGATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_AGGREGATE \- change the definition of an aggregate function
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER AGGREGATE \fIname\fR ( \fIaggregate_signature\fR ) RENAME TO \fInew_name\fR
+ALTER AGGREGATE \fIname\fR ( \fIaggregate_signature\fR )
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER AGGREGATE \fIname\fR ( \fIaggregate_signature\fR ) SET SCHEMA \fInew_schema\fR
+
+where \fIaggregate_signature\fR is:
+
+* |
+[ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] |
+[ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] ] ORDER BY [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER AGGREGATE\fR
+changes the definition of an aggregate function\&.
+.PP
+You must own the aggregate function to use
+\fBALTER AGGREGATE\fR\&. To change the schema of an aggregate function, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the aggregate function\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the aggregate function\&. However, a superuser can alter ownership of any aggregate function anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing aggregate function\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN
+or
+VARIADIC\&. If omitted, the default is
+IN\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Note that
+\fBALTER AGGREGATE\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the aggregate function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+An input data type on which the aggregate function operates\&. To reference a zero\-argument aggregate function, write
+*
+in place of the list of argument specifications\&. To reference an ordered\-set aggregate function, write
+ORDER BY
+between the direct and aggregated argument specifications\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the aggregate function\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the aggregate function\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the aggregate function\&.
+.RE
+.SH "NOTES"
+.PP
+The recommended syntax for referencing an ordered\-set aggregate is to write
+ORDER BY
+between the direct and aggregated argument specifications, in the same style as in
+\fBCREATE AGGREGATE\fR\&. However, it will also work to omit
+ORDER BY
+and just run the direct and aggregated argument specifications into a single list\&. In this abbreviated form, if
+VARIADIC "any"
+was used in both the direct and aggregated argument lists, write
+VARIADIC "any"
+only once\&.
+.SH "EXAMPLES"
+.PP
+To rename the aggregate function
+myavg
+for type
+integer
+to
+my_average:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER AGGREGATE myavg(integer) RENAME TO my_average;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the owner of the aggregate function
+myavg
+for type
+integer
+to
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER AGGREGATE myavg(integer) OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To move the ordered\-set aggregate
+mypercentile
+with direct argument of type
+float8
+and aggregated argument of type
+integer
+into schema
+myschema:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER AGGREGATE mypercentile(float8 ORDER BY integer) SET SCHEMA myschema;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This will work too:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER AGGREGATE mypercentile(float8, integer) SET SCHEMA myschema;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER AGGREGATE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE AGGREGATE (\fBCREATE_AGGREGATE\fR(7)), DROP AGGREGATE (\fBDROP_AGGREGATE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_COLLATION.7 b/doc/src/sgml/man7/ALTER_COLLATION.7
new file mode 100644
index 0000000..9abf672
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_COLLATION.7
@@ -0,0 +1,178 @@
+'\" t
+.\" Title: ALTER COLLATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER COLLATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_COLLATION \- change the definition of a collation
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER COLLATION \fIname\fR REFRESH VERSION
+
+ALTER COLLATION \fIname\fR RENAME TO \fInew_name\fR
+ALTER COLLATION \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER COLLATION \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER COLLATION\fR
+changes the definition of a collation\&.
+.PP
+You must own the collation to use
+\fBALTER COLLATION\fR\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the collation\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the collation\&. However, a superuser can alter ownership of any collation anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing collation\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the collation\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the collation\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the collation\&.
+.RE
+.PP
+REFRESH VERSION
+.RS 4
+Update the collation\*(Aqs version\&. See
+Notes
+below\&.
+.RE
+.SH "NOTES"
+.PP
+When a collation object is created, the provider\-specific version of the collation is recorded in the system catalog\&. When the collation is used, the current version is checked against the recorded version, and a warning is issued when there is a mismatch, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WARNING: collation "xx\-x\-icu" has version mismatch
+DETAIL: The collation in the database was created using version 1\&.2\&.3\&.4, but the operating system provides version 2\&.3\&.4\&.5\&.
+HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg_catalog\&."xx\-x\-icu" REFRESH VERSION, or build PostgreSQL with the right library version\&.
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A change in collation definitions can lead to corrupt indexes and other problems because the database system relies on stored objects having a certain sort order\&. Generally, this should be avoided, but it can happen in legitimate circumstances, such as when upgrading the operating system to a new major version or when using
+\fBpg_upgrade\fR
+to upgrade to server binaries linked with a newer version of ICU\&. When this happens, all objects depending on the collation should be rebuilt, for example, using
+\fBREINDEX\fR\&. When that is done, the collation version can be refreshed using the command
+ALTER COLLATION \&.\&.\&. REFRESH VERSION\&. This will update the system catalog to record the current collation version and will make the warning go away\&. Note that this does not actually check whether all affected objects have been rebuilt correctly\&.
+.PP
+When using collations provided by
+libc, version information is recorded on systems using the GNU C library (most Linux systems), FreeBSD and Windows\&. When using collations provided by ICU, the version information is provided by the ICU library and is available on all platforms\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+When using the GNU C library for collations, the C library\*(Aqs version is used as a proxy for the collation version\&. Many Linux distributions change collation definitions only when upgrading the C library, but this approach is imperfect as maintainers are free to back\-port newer collation definitions to older C library releases\&.
+.PP
+When using Windows for collations, version information is only available for collations defined with BCP 47 language tags such as
+en\-US\&.
+.sp .5v
+.RE
+.PP
+For the database default collation, there is an analogous command
+ALTER DATABASE \&.\&.\&. REFRESH COLLATION VERSION\&.
+.PP
+The following query can be used to identify all collations in the current database that need to be refreshed and the objects that depend on them:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT pg_describe_object(refclassid, refobjid, refobjsubid) AS "Collation",
+ pg_describe_object(classid, objid, objsubid) AS "Object"
+ FROM pg_depend d JOIN pg_collation c
+ ON refclassid = \*(Aqpg_collation\*(Aq::regclass AND refobjid = c\&.oid
+ WHERE c\&.collversion <> pg_collation_actual_version(c\&.oid)
+ ORDER BY 1, 2;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "EXAMPLES"
+.PP
+To rename the collation
+de_DE
+to
+german:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER COLLATION "de_DE" RENAME TO german;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the owner of the collation
+en_US
+to
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER COLLATION "en_US" OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER COLLATION\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE COLLATION (\fBCREATE_COLLATION\fR(7)), DROP COLLATION (\fBDROP_COLLATION\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_CONVERSION.7 b/doc/src/sgml/man7/ALTER_CONVERSION.7
new file mode 100644
index 0000000..f456699
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_CONVERSION.7
@@ -0,0 +1,106 @@
+'\" t
+.\" Title: ALTER CONVERSION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER CONVERSION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_CONVERSION \- change the definition of a conversion
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER CONVERSION \fIname\fR RENAME TO \fInew_name\fR
+ALTER CONVERSION \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER CONVERSION \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER CONVERSION\fR
+changes the definition of a conversion\&.
+.PP
+You must own the conversion to use
+\fBALTER CONVERSION\fR\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the conversion\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the conversion\&. However, a superuser can alter ownership of any conversion anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing conversion\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the conversion\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the conversion\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the conversion\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To rename the conversion
+iso_8859_1_to_utf8
+to
+latin1_to_unicode:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER CONVERSION iso_8859_1_to_utf8 RENAME TO latin1_to_unicode;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the owner of the conversion
+iso_8859_1_to_utf8
+to
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER CONVERSION iso_8859_1_to_utf8 OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER CONVERSION\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE CONVERSION (\fBCREATE_CONVERSION\fR(7)), DROP CONVERSION (\fBDROP_CONVERSION\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_DATABASE.7 b/doc/src/sgml/man7/ALTER_DATABASE.7
new file mode 100644
index 0000000..40537a0
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_DATABASE.7
@@ -0,0 +1,176 @@
+'\" t
+.\" Title: ALTER DATABASE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER DATABASE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_DATABASE \- change a database
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER DATABASE \fIname\fR [ [ WITH ] \fIoption\fR [ \&.\&.\&. ] ]
+
+where \fIoption\fR can be:
+
+ ALLOW_CONNECTIONS \fIallowconn\fR
+ CONNECTION LIMIT \fIconnlimit\fR
+ IS_TEMPLATE \fIistemplate\fR
+
+ALTER DATABASE \fIname\fR RENAME TO \fInew_name\fR
+
+ALTER DATABASE \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER DATABASE \fIname\fR SET TABLESPACE \fInew_tablespace\fR
+
+ALTER DATABASE \fIname\fR REFRESH COLLATION VERSION
+
+ALTER DATABASE \fIname\fR SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | DEFAULT }
+ALTER DATABASE \fIname\fR SET \fIconfiguration_parameter\fR FROM CURRENT
+ALTER DATABASE \fIname\fR RESET \fIconfiguration_parameter\fR
+ALTER DATABASE \fIname\fR RESET ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER DATABASE\fR
+changes the attributes of a database\&.
+.PP
+The first form changes certain per\-database settings\&. (See below for details\&.) Only the database owner or a superuser can change these settings\&.
+.PP
+The second form changes the name of the database\&. Only the database owner or a superuser can rename a database; non\-superuser owners must also have the
+CREATEDB
+privilege\&. The current database cannot be renamed\&. (Connect to a different database if you need to do that\&.)
+.PP
+The third form changes the owner of the database\&. To alter the owner, you must own the database and also be a direct or indirect member of the new owning role, and you must have the
+CREATEDB
+privilege\&. (Note that superusers have all these privileges automatically\&.)
+.PP
+The fourth form changes the default tablespace of the database\&. Only the database owner or a superuser can do this; you must also have create privilege for the new tablespace\&. This command physically moves any tables or indexes in the database\*(Aqs old default tablespace to the new tablespace\&. The new default tablespace must be empty for this database, and no one can be connected to the database\&. Tables and indexes in non\-default tablespaces are unaffected\&.
+.PP
+The remaining forms change the session default for a run\-time configuration variable for a
+PostgreSQL
+database\&. Whenever a new session is subsequently started in that database, the specified value becomes the session default value\&. The database\-specific default overrides whatever setting is present in
+postgresql\&.conf
+or has been received from the
+\fBpostgres\fR
+command line\&. Only the database owner or a superuser can change the session defaults for a database\&. Certain variables cannot be set this way, or can only be set by a superuser\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the database whose attributes are to be altered\&.
+.RE
+.PP
+\fIallowconn\fR
+.RS 4
+If false then no one can connect to this database\&.
+.RE
+.PP
+\fIconnlimit\fR
+.RS 4
+How many concurrent connections can be made to this database\&. \-1 means no limit\&.
+.RE
+.PP
+\fIistemplate\fR
+.RS 4
+If true, then this database can be cloned by any user with
+CREATEDB
+privileges; if false, then only superusers or the owner of the database can clone it\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the database\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the database\&.
+.RE
+.PP
+\fInew_tablespace\fR
+.RS 4
+The new default tablespace of the database\&.
+.sp
+This form of the command cannot be executed inside a transaction block\&.
+.RE
+.PP
+REFRESH COLLATION VERSION
+.RS 4
+Update the database collation version\&. See
+Notes
+for background\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.br
+\fIvalue\fR
+.RS 4
+Set this database\*(Aqs session default for the specified configuration parameter to the given value\&. If
+\fIvalue\fR
+is
+DEFAULT
+or, equivalently,
+RESET
+is used, the database\-specific setting is removed, so the system\-wide default setting will be inherited in new sessions\&. Use
+RESET ALL
+to clear all database\-specific settings\&.
+SET FROM CURRENT
+saves the session\*(Aqs current value of the parameter as the database\-specific value\&.
+.sp
+See
+\fBSET\fR(7)
+and
+Chapter\ \&20
+for more information about allowed parameter names and values\&.
+.RE
+.SH "NOTES"
+.PP
+It is also possible to tie a session default to a specific role rather than to a database; see
+ALTER ROLE (\fBALTER_ROLE\fR(7))\&. Role\-specific settings override database\-specific ones if there is a conflict\&.
+.SH "EXAMPLES"
+.PP
+To disable index scans by default in the database
+test:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DATABASE test SET enable_indexscan TO off;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBALTER DATABASE\fR
+statement is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE DATABASE (\fBCREATE_DATABASE\fR(7)), DROP DATABASE (\fBDROP_DATABASE\fR(7)), \fBSET\fR(7), CREATE TABLESPACE (\fBCREATE_TABLESPACE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_DEFAULT_PRIVILEGES.7 b/doc/src/sgml/man7/ALTER_DEFAULT_PRIVILEGES.7
new file mode 100644
index 0000000..a33f4a7
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_DEFAULT_PRIVILEGES.7
@@ -0,0 +1,227 @@
+'\" t
+.\" Title: ALTER DEFAULT PRIVILEGES
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER DEFAULT PRIVILEGES" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_DEFAULT_PRIVILEGES \- define default access privileges
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER DEFAULT PRIVILEGES
+ [ FOR { ROLE | USER } \fItarget_role\fR [, \&.\&.\&.] ]
+ [ IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] ]
+ \fIabbreviated_grant_or_revoke\fR
+
+where \fIabbreviated_grant_or_revoke\fR is one of:
+
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON TABLES
+ TO { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.] [ WITH GRANT OPTION ]
+
+GRANT { { USAGE | SELECT | UPDATE }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON SEQUENCES
+ TO { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.] [ WITH GRANT OPTION ]
+
+GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { FUNCTIONS | ROUTINES }
+ TO { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.] [ WITH GRANT OPTION ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPES
+ TO { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.] [ WITH GRANT OPTION ]
+
+GRANT { USAGE | CREATE | ALL [ PRIVILEGES ] }
+ ON SCHEMAS
+ TO { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.] [ WITH GRANT OPTION ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON TABLES
+ FROM { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { USAGE | SELECT | UPDATE }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON SEQUENCES
+ FROM { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { FUNCTIONS | ROUTINES }
+ FROM { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPES
+ FROM { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | CREATE | ALL [ PRIVILEGES ] }
+ ON SCHEMAS
+ FROM { [ GROUP ] \fIrole_name\fR | PUBLIC } [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER DEFAULT PRIVILEGES\fR
+allows you to set the privileges that will be applied to objects created in the future\&. (It does not affect privileges assigned to already\-existing objects\&.) Currently, only the privileges for schemas, tables (including views and foreign tables), sequences, functions, and types (including domains) can be altered\&. For this command, functions include aggregates and procedures\&. The words
+FUNCTIONS
+and
+ROUTINES
+are equivalent in this command\&. (ROUTINES
+is preferred going forward as the standard term for functions and procedures taken together\&. In earlier PostgreSQL releases, only the word
+FUNCTIONS
+was allowed\&. It is not possible to set default privileges for functions and procedures separately\&.)
+.PP
+You can change default privileges only for objects that will be created by yourself or by roles that you are a member of\&. The privileges can be set globally (i\&.e\&., for all objects created in the current database), or just for objects created in specified schemas\&.
+.PP
+As explained in
+Section\ \&5.7, the default privileges for any object type normally grant all grantable permissions to the object owner, and may grant some privileges to
+PUBLIC
+as well\&. However, this behavior can be changed by altering the global default privileges with
+\fBALTER DEFAULT PRIVILEGES\fR\&.
+.PP
+Default privileges that are specified per\-schema are added to whatever the global default privileges are for the particular object type\&. This means you cannot revoke privileges per\-schema if they are granted globally (either by default, or according to a previous
+\fBALTER DEFAULT PRIVILEGES\fR
+command that did not specify a schema)\&. Per\-schema
+REVOKE
+is only useful to reverse the effects of a previous per\-schema
+GRANT\&.
+.SS "Parameters"
+.PP
+\fItarget_role\fR
+.RS 4
+The name of an existing role of which the current role is a member\&. If
+FOR ROLE
+is omitted, the current role is assumed\&.
+.RE
+.PP
+\fIschema_name\fR
+.RS 4
+The name of an existing schema\&. If specified, the default privileges are altered for objects later created in that schema\&. If
+IN SCHEMA
+is omitted, the global default privileges are altered\&.
+IN SCHEMA
+is not allowed when setting privileges for schemas, since schemas can\*(Aqt be nested\&.
+.RE
+.PP
+\fIrole_name\fR
+.RS 4
+The name of an existing role to grant or revoke privileges for\&. This parameter, and all the other parameters in
+\fIabbreviated_grant_or_revoke\fR, act as described under
+\fBGRANT\fR(7)
+or
+\fBREVOKE\fR(7), except that one is setting permissions for a whole class of objects rather than specific named objects\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBpsql\fR(1)\*(Aqs
+\fB\eddp\fR
+command to obtain information about existing assignments of default privileges\&. The meaning of the privilege display is the same as explained for
+\fB\edp\fR
+in
+Section\ \&5.7\&.
+.PP
+If you wish to drop a role for which the default privileges have been altered, it is necessary to reverse the changes in its default privileges or use
+\fBDROP OWNED BY\fR
+to get rid of the default privileges entry for the role\&.
+.SH "EXAMPLES"
+.PP
+Grant SELECT privilege to everyone for all tables (and views) you subsequently create in schema
+myschema, and allow role
+webuser
+to INSERT into them too:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO PUBLIC;
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT INSERT ON TABLES TO webuser;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Undo the above, so that subsequently\-created tables won\*(Aqt have any more permissions than normal:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE SELECT ON TABLES FROM PUBLIC;
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE INSERT ON TABLES FROM webuser;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Remove the public EXECUTE permission that is normally granted on functions, for all functions subsequently created by role
+admin:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DEFAULT PRIVILEGES FOR ROLE admin REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note however that you
+\fIcannot\fR
+accomplish that effect with a command limited to a single schema\&. This command has no effect, unless it is undoing a matching
+GRANT:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+That\*(Aqs because per\-schema default privileges can only add privileges to the global setting, not remove privileges granted by it\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER DEFAULT PRIVILEGES\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBGRANT\fR(7), \fBREVOKE\fR(7)
diff --git a/doc/src/sgml/man7/ALTER_DOMAIN.7 b/doc/src/sgml/man7/ALTER_DOMAIN.7
new file mode 100644
index 0000000..6d74e57
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_DOMAIN.7
@@ -0,0 +1,293 @@
+'\" t
+.\" Title: ALTER DOMAIN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER DOMAIN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_DOMAIN \- change the definition of a domain
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER DOMAIN \fIname\fR
+ { SET DEFAULT \fIexpression\fR | DROP DEFAULT }
+ALTER DOMAIN \fIname\fR
+ { SET | DROP } NOT NULL
+ALTER DOMAIN \fIname\fR
+ ADD \fIdomain_constraint\fR [ NOT VALID ]
+ALTER DOMAIN \fIname\fR
+ DROP CONSTRAINT [ IF EXISTS ] \fIconstraint_name\fR [ RESTRICT | CASCADE ]
+ALTER DOMAIN \fIname\fR
+ RENAME CONSTRAINT \fIconstraint_name\fR TO \fInew_constraint_name\fR
+ALTER DOMAIN \fIname\fR
+ VALIDATE CONSTRAINT \fIconstraint_name\fR
+ALTER DOMAIN \fIname\fR
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER DOMAIN \fIname\fR
+ RENAME TO \fInew_name\fR
+ALTER DOMAIN \fIname\fR
+ SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER DOMAIN\fR
+changes the definition of an existing domain\&. There are several sub\-forms:
+.PP
+SET/DROP DEFAULT
+.RS 4
+These forms set or remove the default value for a domain\&. Note that defaults only apply to subsequent
+\fBINSERT\fR
+commands; they do not affect rows already in a table using the domain\&.
+.RE
+.PP
+SET/DROP NOT NULL
+.RS 4
+These forms change whether a domain is marked to allow NULL values or to reject NULL values\&. You can only
+SET NOT NULL
+when the columns using the domain contain no null values\&.
+.RE
+.PP
+ADD \fIdomain_constraint\fR [ NOT VALID ]
+.RS 4
+This form adds a new constraint to a domain using the same syntax as
+\fBCREATE DOMAIN\fR\&. When a new constraint is added to a domain, all columns using that domain will be checked against the newly added constraint\&. These checks can be suppressed by adding the new constraint using the
+NOT VALID
+option; the constraint can later be made valid using
+\fBALTER DOMAIN \&.\&.\&. VALIDATE CONSTRAINT\fR\&. Newly inserted or updated rows are always checked against all constraints, even those marked
+NOT VALID\&.
+NOT VALID
+is only accepted for
+CHECK
+constraints\&.
+.RE
+.PP
+DROP CONSTRAINT [ IF EXISTS ]
+.RS 4
+This form drops constraints on a domain\&. If
+IF EXISTS
+is specified and the constraint does not exist, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+RENAME CONSTRAINT
+.RS 4
+This form changes the name of a constraint on a domain\&.
+.RE
+.PP
+VALIDATE CONSTRAINT
+.RS 4
+This form validates a constraint previously added as
+NOT VALID, that is, it verifies that all values in table columns of the domain type satisfy the specified constraint\&.
+.RE
+.PP
+OWNER
+.RS 4
+This form changes the owner of the domain to the specified user\&.
+.RE
+.PP
+RENAME
+.RS 4
+This form changes the name of the domain\&.
+.RE
+.PP
+SET SCHEMA
+.RS 4
+This form changes the schema of the domain\&. Any constraints associated with the domain are moved into the new schema as well\&.
+.RE
+.PP
+You must own the domain to use
+\fBALTER DOMAIN\fR\&. To change the schema of a domain, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the domain\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the domain\&. However, a superuser can alter ownership of any domain anyway\&.)
+.SH "PARAMETERS"
+.PP
+.PP
+\fIname\fR
+.RS 4
+The name (possibly schema\-qualified) of an existing domain to alter\&.
+.RE
+.PP
+\fIdomain_constraint\fR
+.RS 4
+New domain constraint for the domain\&.
+.RE
+.PP
+\fIconstraint_name\fR
+.RS 4
+Name of an existing constraint to drop or rename\&.
+.RE
+.PP
+NOT VALID
+.RS 4
+Do not verify existing stored data for constraint validity\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the constraint, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the constraint if there are any dependent objects\&. This is the default behavior\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the domain\&.
+.RE
+.PP
+\fInew_constraint_name\fR
+.RS 4
+The new name for the constraint\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the domain\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the domain\&.
+.RE
+.SH "NOTES"
+.PP
+Although
+\fBALTER DOMAIN ADD CONSTRAINT\fR
+attempts to verify that existing stored data satisfies the new constraint, this check is not bulletproof, because the command cannot
+\(lqsee\(rq
+table rows that are newly inserted or updated and not yet committed\&. If there is a hazard that concurrent operations might insert bad data, the way to proceed is to add the constraint using the
+NOT VALID
+option, commit that command, wait until all transactions started before that commit have finished, and then issue
+\fBALTER DOMAIN VALIDATE CONSTRAINT\fR
+to search for data violating the constraint\&. This method is reliable because once the constraint is committed, all new transactions are guaranteed to enforce it against new values of the domain type\&.
+.PP
+Currently,
+\fBALTER DOMAIN ADD CONSTRAINT\fR,
+\fBALTER DOMAIN VALIDATE CONSTRAINT\fR, and
+\fBALTER DOMAIN SET NOT NULL\fR
+will fail if the named domain or any derived domain is used within a container\-type column (a composite, array, or range column) in any table in the database\&. They should eventually be improved to be able to verify the new constraint for such nested values\&.
+.SH "EXAMPLES"
+.PP
+To add a
+NOT NULL
+constraint to a domain:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DOMAIN zipcode SET NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+To remove a
+NOT NULL
+constraint from a domain:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DOMAIN zipcode DROP NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a check constraint to a domain:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DOMAIN zipcode ADD CONSTRAINT zipchk CHECK (char_length(VALUE) = 5);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To remove a check constraint from a domain:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To rename a check constraint on a domain:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DOMAIN zipcode RENAME CONSTRAINT zipchk TO zip_check;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To move the domain into a different schema:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER DOMAIN zipcode SET SCHEMA customers;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER DOMAIN\fR
+conforms to the
+SQL
+standard, except for the
+OWNER,
+RENAME,
+SET SCHEMA, and
+VALIDATE CONSTRAINT
+variants, which are
+PostgreSQL
+extensions\&. The
+NOT VALID
+clause of the
+ADD CONSTRAINT
+variant is also a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE DOMAIN (\fBCREATE_DOMAIN\fR(7)), DROP DOMAIN (\fBDROP_DOMAIN\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_EVENT_TRIGGER.7 b/doc/src/sgml/man7/ALTER_EVENT_TRIGGER.7
new file mode 100644
index 0000000..b71e7f0
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_EVENT_TRIGGER.7
@@ -0,0 +1,74 @@
+'\" t
+.\" Title: ALTER EVENT TRIGGER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER EVENT TRIGGER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_EVENT_TRIGGER \- change the definition of an event trigger
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER EVENT TRIGGER \fIname\fR DISABLE
+ALTER EVENT TRIGGER \fIname\fR ENABLE [ REPLICA | ALWAYS ]
+ALTER EVENT TRIGGER \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER EVENT TRIGGER \fIname\fR RENAME TO \fInew_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER EVENT TRIGGER\fR
+changes properties of an existing event trigger\&.
+.PP
+You must be superuser to alter an event trigger\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing trigger to alter\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the event trigger\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the event trigger\&.
+.RE
+.PP
+DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
+.RS 4
+These forms configure the firing of event triggers\&. A disabled trigger is still known to the system, but is not executed when its triggering event occurs\&. See also
+session_replication_role\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER EVENT TRIGGER\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE EVENT TRIGGER (\fBCREATE_EVENT_TRIGGER\fR(7)), DROP EVENT TRIGGER (\fBDROP_EVENT_TRIGGER\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_EXTENSION.7 b/doc/src/sgml/man7/ALTER_EXTENSION.7
new file mode 100644
index 0000000..717966b
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_EXTENSION.7
@@ -0,0 +1,260 @@
+'\" t
+.\" Title: ALTER EXTENSION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER EXTENSION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_EXTENSION \- change the definition of an extension
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER EXTENSION \fIname\fR UPDATE [ TO \fInew_version\fR ]
+ALTER EXTENSION \fIname\fR SET SCHEMA \fInew_schema\fR
+ALTER EXTENSION \fIname\fR ADD \fImember_object\fR
+ALTER EXTENSION \fIname\fR DROP \fImember_object\fR
+
+where \fImember_object\fR is:
+
+ ACCESS METHOD \fIobject_name\fR |
+ AGGREGATE \fIaggregate_name\fR ( \fIaggregate_signature\fR ) |
+ CAST (\fIsource_type\fR AS \fItarget_type\fR) |
+ COLLATION \fIobject_name\fR |
+ CONVERSION \fIobject_name\fR |
+ DOMAIN \fIobject_name\fR |
+ EVENT TRIGGER \fIobject_name\fR |
+ FOREIGN DATA WRAPPER \fIobject_name\fR |
+ FOREIGN TABLE \fIobject_name\fR |
+ FUNCTION \fIfunction_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ MATERIALIZED VIEW \fIobject_name\fR |
+ OPERATOR \fIoperator_name\fR (\fIleft_type\fR, \fIright_type\fR) |
+ OPERATOR CLASS \fIobject_name\fR USING \fIindex_method\fR |
+ OPERATOR FAMILY \fIobject_name\fR USING \fIindex_method\fR |
+ [ PROCEDURAL ] LANGUAGE \fIobject_name\fR |
+ PROCEDURE \fIprocedure_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ ROUTINE \fIroutine_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ SCHEMA \fIobject_name\fR |
+ SEQUENCE \fIobject_name\fR |
+ SERVER \fIobject_name\fR |
+ TABLE \fIobject_name\fR |
+ TEXT SEARCH CONFIGURATION \fIobject_name\fR |
+ TEXT SEARCH DICTIONARY \fIobject_name\fR |
+ TEXT SEARCH PARSER \fIobject_name\fR |
+ TEXT SEARCH TEMPLATE \fIobject_name\fR |
+ TRANSFORM FOR \fItype_name\fR LANGUAGE \fIlang_name\fR |
+ TYPE \fIobject_name\fR |
+ VIEW \fIobject_name\fR
+
+and \fIaggregate_signature\fR is:
+
+* |
+[ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] |
+[ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] ] ORDER BY [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER EXTENSION\fR
+changes the definition of an installed extension\&. There are several subforms:
+.PP
+UPDATE
+.RS 4
+This form updates the extension to a newer version\&. The extension must supply a suitable update script (or series of scripts) that can modify the currently\-installed version into the requested version\&.
+.RE
+.PP
+SET SCHEMA
+.RS 4
+This form moves the extension\*(Aqs objects into another schema\&. The extension has to be
+relocatable
+for this command to succeed\&.
+.RE
+.PP
+ADD \fImember_object\fR
+.RS 4
+This form adds an existing object to the extension\&. This is mainly useful in extension update scripts\&. The object will subsequently be treated as a member of the extension; notably, it can only be dropped by dropping the extension\&.
+.RE
+.PP
+DROP \fImember_object\fR
+.RS 4
+This form removes a member object from the extension\&. This is mainly useful in extension update scripts\&. The object is not dropped, only disassociated from the extension\&.
+.RE
+See
+Section\ \&38.17
+for more information about these operations\&.
+.PP
+You must own the extension to use
+\fBALTER EXTENSION\fR\&. The
+ADD/DROP
+forms require ownership of the added/dropped object as well\&.
+.SH "PARAMETERS"
+.PP
+.PP
+\fIname\fR
+.RS 4
+The name of an installed extension\&.
+.RE
+.PP
+\fInew_version\fR
+.RS 4
+The desired new version of the extension\&. This can be written as either an identifier or a string literal\&. If not specified,
+\fBALTER EXTENSION UPDATE\fR
+attempts to update to whatever is shown as the default version in the extension\*(Aqs control file\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the extension\&.
+.RE
+.PP
+\fIobject_name\fR
+.br
+\fIaggregate_name\fR
+.br
+\fIfunction_name\fR
+.br
+\fIoperator_name\fR
+.br
+\fIprocedure_name\fR
+.br
+\fIroutine_name\fR
+.RS 4
+The name of an object to be added to or removed from the extension\&. Names of tables, aggregates, domains, foreign tables, functions, operators, operator classes, operator families, procedures, routines, sequences, text search objects, types, and views can be schema\-qualified\&.
+.RE
+.PP
+\fIsource_type\fR
+.RS 4
+The name of the source data type of the cast\&.
+.RE
+.PP
+\fItarget_type\fR
+.RS 4
+The name of the target data type of the cast\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of a function, procedure, or aggregate argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&. Note that
+\fBALTER EXTENSION\fR
+does not actually pay any attention to
+OUT
+arguments, since only the input arguments are needed to determine the function\*(Aqs identity\&. So it is sufficient to list the
+IN,
+INOUT, and
+VARIADIC
+arguments\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of a function, procedure, or aggregate argument\&. Note that
+\fBALTER EXTENSION\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type of a function, procedure, or aggregate argument\&.
+.RE
+.PP
+\fIleft_type\fR
+.br
+\fIright_type\fR
+.RS 4
+The data type(s) of the operator\*(Aqs arguments (optionally schema\-qualified)\&. Write
+NONE
+for the missing argument of a prefix operator\&.
+.RE
+.PP
+PROCEDURAL
+.RS 4
+This is a noise word\&.
+.RE
+.PP
+\fItype_name\fR
+.RS 4
+The name of the data type of the transform\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the language of the transform\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To update the
+hstore
+extension to version 2\&.0:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER EXTENSION hstore UPDATE TO \*(Aq2\&.0\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the schema of the
+hstore
+extension to
+utils:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER EXTENSION hstore SET SCHEMA utils;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add an existing function to the
+hstore
+extension:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER EXTENSION hstore ADD FUNCTION populate_record(anyelement, hstore);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER EXTENSION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE EXTENSION (\fBCREATE_EXTENSION\fR(7)), DROP EXTENSION (\fBDROP_EXTENSION\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_FOREIGN_DATA_WRAPPER.7 b/doc/src/sgml/man7/ALTER_FOREIGN_DATA_WRAPPER.7
new file mode 100644
index 0000000..d256232
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_FOREIGN_DATA_WRAPPER.7
@@ -0,0 +1,144 @@
+'\" t
+.\" Title: ALTER FOREIGN DATA WRAPPER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER FOREIGN DATA WRAPPER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_FOREIGN_DATA_WRAPPER \- change the definition of a foreign\-data wrapper
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER FOREIGN DATA WRAPPER \fIname\fR
+ [ HANDLER \fIhandler_function\fR | NO HANDLER ]
+ [ VALIDATOR \fIvalidator_function\fR | NO VALIDATOR ]
+ [ OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ]) ]
+ALTER FOREIGN DATA WRAPPER \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER FOREIGN DATA WRAPPER \fIname\fR RENAME TO \fInew_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER FOREIGN DATA WRAPPER\fR
+changes the definition of a foreign\-data wrapper\&. The first form of the command changes the support functions or the generic options of the foreign\-data wrapper (at least one clause is required)\&. The second form changes the owner of the foreign\-data wrapper\&.
+.PP
+Only superusers can alter foreign\-data wrappers\&. Additionally, only superusers can own foreign\-data wrappers\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing foreign\-data wrapper\&.
+.RE
+.PP
+HANDLER \fIhandler_function\fR
+.RS 4
+Specifies a new handler function for the foreign\-data wrapper\&.
+.RE
+.PP
+NO HANDLER
+.RS 4
+This is used to specify that the foreign\-data wrapper should no longer have a handler function\&.
+.sp
+Note that foreign tables that use a foreign\-data wrapper with no handler cannot be accessed\&.
+.RE
+.PP
+VALIDATOR \fIvalidator_function\fR
+.RS 4
+Specifies a new validator function for the foreign\-data wrapper\&.
+.sp
+Note that it is possible that pre\-existing options of the foreign\-data wrapper, or of dependent servers, user mappings, or foreign tables, are invalid according to the new validator\&.
+PostgreSQL
+does not check for this\&. It is up to the user to make sure that these options are correct before using the modified foreign\-data wrapper\&. However, any options specified in this
+\fBALTER FOREIGN DATA WRAPPER\fR
+command will be checked using the new validator\&.
+.RE
+.PP
+NO VALIDATOR
+.RS 4
+This is used to specify that the foreign\-data wrapper should no longer have a validator function\&.
+.RE
+.PP
+OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ] )
+.RS 4
+Change options for the foreign\-data wrapper\&.
+ADD,
+SET, and
+DROP
+specify the action to be performed\&.
+ADD
+is assumed if no operation is explicitly specified\&. Option names must be unique; names and values are also validated using the foreign data wrapper\*(Aqs validator function, if any\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the foreign\-data wrapper\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the foreign\-data wrapper\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Change a foreign\-data wrapper
+dbi, add option
+foo, drop
+bar:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo \*(Aq1\*(Aq, DROP \*(Aqbar\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Change the foreign\-data wrapper
+dbi
+validator to
+bob\&.myvalidator:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FOREIGN DATA WRAPPER dbi VALIDATOR bob\&.myvalidator;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER FOREIGN DATA WRAPPER\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED), except that the
+HANDLER,
+VALIDATOR,
+OWNER TO, and
+RENAME
+clauses are extensions\&.
+.SH "SEE ALSO"
+CREATE FOREIGN DATA WRAPPER (\fBCREATE_FOREIGN_DATA_WRAPPER\fR(7)), DROP FOREIGN DATA WRAPPER (\fBDROP_FOREIGN_DATA_WRAPPER\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_FOREIGN_TABLE.7 b/doc/src/sgml/man7/ALTER_FOREIGN_TABLE.7
new file mode 100644
index 0000000..3dd98ec
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_FOREIGN_TABLE.7
@@ -0,0 +1,377 @@
+'\" t
+.\" Title: ALTER FOREIGN TABLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER FOREIGN TABLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_FOREIGN_TABLE \- change the definition of a foreign table
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] \fIname\fR [ * ]
+ \fIaction\fR [, \&.\&.\&. ]
+ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] \fIname\fR [ * ]
+ RENAME [ COLUMN ] \fIcolumn_name\fR TO \fInew_column_name\fR
+ALTER FOREIGN TABLE [ IF EXISTS ] \fIname\fR
+ RENAME TO \fInew_name\fR
+ALTER FOREIGN TABLE [ IF EXISTS ] \fIname\fR
+ SET SCHEMA \fInew_schema\fR
+
+where \fIaction\fR is one of:
+
+ ADD [ COLUMN ] \fIcolumn_name\fR \fIdata_type\fR [ COLLATE \fIcollation\fR ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ DROP [ COLUMN ] [ IF EXISTS ] \fIcolumn_name\fR [ RESTRICT | CASCADE ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR [ SET DATA ] TYPE \fIdata_type\fR [ COLLATE \fIcollation\fR ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET DEFAULT \fIexpression\fR
+ ALTER [ COLUMN ] \fIcolumn_name\fR DROP DEFAULT
+ ALTER [ COLUMN ] \fIcolumn_name\fR { SET | DROP } NOT NULL
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET STATISTICS \fIinteger\fR
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET ( \fIattribute_option\fR = \fIvalue\fR [, \&.\&.\&. ] )
+ ALTER [ COLUMN ] \fIcolumn_name\fR RESET ( \fIattribute_option\fR [, \&.\&.\&. ] )
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] \fIcolumn_name\fR OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ])
+ ADD \fItable_constraint\fR [ NOT VALID ]
+ VALIDATE CONSTRAINT \fIconstraint_name\fR
+ DROP CONSTRAINT [ IF EXISTS ] \fIconstraint_name\fR [ RESTRICT | CASCADE ]
+ DISABLE TRIGGER [ \fItrigger_name\fR | ALL | USER ]
+ ENABLE TRIGGER [ \fItrigger_name\fR | ALL | USER ]
+ ENABLE REPLICA TRIGGER \fItrigger_name\fR
+ ENABLE ALWAYS TRIGGER \fItrigger_name\fR
+ SET WITHOUT OIDS
+ INHERIT \fIparent_table\fR
+ NO INHERIT \fIparent_table\fR
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ])
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER FOREIGN TABLE\fR
+changes the definition of an existing foreign table\&. There are several subforms:
+.PP
+ADD COLUMN
+.RS 4
+This form adds a new column to the foreign table, using the same syntax as
+\fBCREATE FOREIGN TABLE\fR\&. Unlike the case when adding a column to a regular table, nothing happens to the underlying storage: this action simply declares that some new column is now accessible through the foreign table\&.
+.RE
+.PP
+DROP COLUMN [ IF EXISTS ]
+.RS 4
+This form drops a column from a foreign table\&. You will need to say
+CASCADE
+if anything outside the table depends on the column; for example, views\&. If
+IF EXISTS
+is specified and the column does not exist, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+SET DATA TYPE
+.RS 4
+This form changes the type of a column of a foreign table\&. Again, this has no effect on any underlying storage: this action simply changes the type that
+PostgreSQL
+believes the column to have\&.
+.RE
+.PP
+SET/DROP DEFAULT
+.RS 4
+These forms set or remove the default value for a column\&. Default values only apply in subsequent
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+commands; they do not cause rows already in the table to change\&.
+.RE
+.PP
+SET/DROP NOT NULL
+.RS 4
+Mark a column as allowing, or not allowing, null values\&.
+.RE
+.PP
+SET STATISTICS
+.RS 4
+This form sets the per\-column statistics\-gathering target for subsequent
+\fBANALYZE\fR
+operations\&. See the similar form of
+\fBALTER TABLE\fR
+for more details\&.
+.RE
+.PP
+SET ( \fIattribute_option\fR = \fIvalue\fR [, \&.\&.\&. ] )
+.br
+RESET ( \fIattribute_option\fR [, \&.\&.\&. ] )
+.RS 4
+This form sets or resets per\-attribute options\&. See the similar form of
+\fBALTER TABLE\fR
+for more details\&.
+.RE
+.PP
+SET STORAGE
+.RS 4
+This form sets the storage mode for a column\&. See the similar form of
+\fBALTER TABLE\fR
+for more details\&. Note that the storage mode has no effect unless the table\*(Aqs foreign\-data wrapper chooses to pay attention to it\&.
+.RE
+.PP
+ADD \fItable_constraint\fR [ NOT VALID ]
+.RS 4
+This form adds a new constraint to a foreign table, using the same syntax as
+\fBCREATE FOREIGN TABLE\fR\&. Currently only
+CHECK
+constraints are supported\&.
+.sp
+Unlike the case when adding a constraint to a regular table, nothing is done to verify the constraint is correct; rather, this action simply declares that some new condition should be assumed to hold for all rows in the foreign table\&. (See the discussion in
+\fBCREATE FOREIGN TABLE\fR\&.) If the constraint is marked
+NOT VALID, then it isn\*(Aqt assumed to hold, but is only recorded for possible future use\&.
+.RE
+.PP
+VALIDATE CONSTRAINT
+.RS 4
+This form marks as valid a constraint that was previously marked as
+NOT VALID\&. No action is taken to verify the constraint, but future queries will assume that it holds\&.
+.RE
+.PP
+DROP CONSTRAINT [ IF EXISTS ]
+.RS 4
+This form drops the specified constraint on a foreign table\&. If
+IF EXISTS
+is specified and the constraint does not exist, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
+.RS 4
+These forms configure the firing of trigger(s) belonging to the foreign table\&. See the similar form of
+\fBALTER TABLE\fR
+for more details\&.
+.RE
+.PP
+SET WITHOUT OIDS
+.RS 4
+Backward compatibility syntax for removing the
+oid
+system column\&. As
+oid
+system columns cannot be added anymore, this never has an effect\&.
+.RE
+.PP
+INHERIT \fIparent_table\fR
+.RS 4
+This form adds the target foreign table as a new child of the specified parent table\&. See the similar form of
+\fBALTER TABLE\fR
+for more details\&.
+.RE
+.PP
+NO INHERIT \fIparent_table\fR
+.RS 4
+This form removes the target foreign table from the list of children of the specified parent table\&.
+.RE
+.PP
+OWNER
+.RS 4
+This form changes the owner of the foreign table to the specified user\&.
+.RE
+.PP
+OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ] )
+.RS 4
+Change options for the foreign table or one of its columns\&.
+ADD,
+SET, and
+DROP
+specify the action to be performed\&.
+ADD
+is assumed if no operation is explicitly specified\&. Duplicate option names are not allowed (although it\*(Aqs OK for a table option and a column option to have the same name)\&. Option names and values are also validated using the foreign data wrapper library\&.
+.RE
+.PP
+RENAME
+.RS 4
+The
+RENAME
+forms change the name of a foreign table or the name of an individual column in a foreign table\&.
+.RE
+.PP
+SET SCHEMA
+.RS 4
+This form moves the foreign table into another schema\&.
+.RE
+.PP
+All the actions except
+RENAME
+and
+SET SCHEMA
+can be combined into a list of multiple alterations to apply in parallel\&. For example, it is possible to add several columns and/or alter the type of several columns in a single command\&.
+.PP
+If the command is written as
+ALTER FOREIGN TABLE IF EXISTS \&.\&.\&.
+and the foreign table does not exist, no error is thrown\&. A notice is issued in this case\&.
+.PP
+You must own the table to use
+\fBALTER FOREIGN TABLE\fR\&. To change the schema of a foreign table, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the table\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the table\&. However, a superuser can alter ownership of any table anyway\&.) To add a column or alter a column type, you must also have
+USAGE
+privilege on the data type\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (possibly schema\-qualified) of an existing foreign table to alter\&. If
+ONLY
+is specified before the table name, only that table is altered\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are altered\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+Name of a new or existing column\&.
+.RE
+.PP
+\fInew_column_name\fR
+.RS 4
+New name for an existing column\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+New name for the table\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+Data type of the new column, or new data type for an existing column\&.
+.RE
+.PP
+\fItable_constraint\fR
+.RS 4
+New table constraint for the foreign table\&.
+.RE
+.PP
+\fIconstraint_name\fR
+.RS 4
+Name of an existing constraint to drop\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the dropped column or constraint (for example, views referencing the column), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the column or constraint if there are any dependent objects\&. This is the default behavior\&.
+.RE
+.PP
+\fItrigger_name\fR
+.RS 4
+Name of a single trigger to disable or enable\&.
+.RE
+.PP
+ALL
+.RS 4
+Disable or enable all triggers belonging to the foreign table\&. (This requires superuser privilege if any of the triggers are internally generated triggers\&. The core system does not add such triggers to foreign tables, but add\-on code could do so\&.)
+.RE
+.PP
+USER
+.RS 4
+Disable or enable all triggers belonging to the foreign table except for internally generated triggers\&.
+.RE
+.PP
+\fIparent_table\fR
+.RS 4
+A parent table to associate or de\-associate with this foreign table\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the table\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The name of the schema to which the table will be moved\&.
+.RE
+.SH "NOTES"
+.PP
+The key word
+COLUMN
+is noise and can be omitted\&.
+.PP
+Consistency with the foreign server is not checked when a column is added or removed with
+ADD COLUMN
+or
+DROP COLUMN, a
+NOT NULL
+or
+CHECK
+constraint is added, or a column type is changed with
+SET DATA TYPE\&. It is the user\*(Aqs responsibility to ensure that the table definition matches the remote side\&.
+.PP
+Refer to
+\fBCREATE FOREIGN TABLE\fR
+for a further description of valid parameters\&.
+.SH "EXAMPLES"
+.PP
+To mark a column as not\-null:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FOREIGN TABLE distributors ALTER COLUMN street SET NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change options of a foreign table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FOREIGN TABLE myschema\&.distributors OPTIONS (ADD opt1 \*(Aqvalue\*(Aq, SET opt2 \*(Aqvalue2\*(Aq, DROP opt3);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The forms
+ADD,
+DROP, and
+SET DATA TYPE
+conform with the SQL standard\&. The other forms are
+PostgreSQL
+extensions of the SQL standard\&. Also, the ability to specify more than one manipulation in a single
+\fBALTER FOREIGN TABLE\fR
+command is an extension\&.
+.PP
+\fBALTER FOREIGN TABLE DROP COLUMN\fR
+can be used to drop the only column of a foreign table, leaving a zero\-column table\&. This is an extension of SQL, which disallows zero\-column foreign tables\&.
+.SH "SEE ALSO"
+CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7)), DROP FOREIGN TABLE (\fBDROP_FOREIGN_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_FUNCTION.7 b/doc/src/sgml/man7/ALTER_FUNCTION.7
new file mode 100644
index 0000000..7c6a458
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_FUNCTION.7
@@ -0,0 +1,348 @@
+'\" t
+.\" Title: ALTER FUNCTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER FUNCTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_FUNCTION \- change the definition of a function
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER FUNCTION \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ \fIaction\fR [ \&.\&.\&. ] [ RESTRICT ]
+ALTER FUNCTION \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ RENAME TO \fInew_name\fR
+ALTER FUNCTION \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER FUNCTION \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ SET SCHEMA \fInew_schema\fR
+ALTER FUNCTION \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION \fIextension_name\fR
+
+where \fIaction\fR is one of:
+
+ CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
+ IMMUTABLE | STABLE | VOLATILE
+ [ NOT ] LEAKPROOF
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ COST \fIexecution_cost\fR
+ ROWS \fIresult_rows\fR
+ SUPPORT \fIsupport_function\fR
+ SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | DEFAULT }
+ SET \fIconfiguration_parameter\fR FROM CURRENT
+ RESET \fIconfiguration_parameter\fR
+ RESET ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER FUNCTION\fR
+changes the definition of a function\&.
+.PP
+You must own the function to use
+\fBALTER FUNCTION\fR\&. To change a function\*(Aqs schema, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the function\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the function\&. However, a superuser can alter ownership of any function anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing function\&. If no argument list is specified, the name must be unique in its schema\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&. Note that
+\fBALTER FUNCTION\fR
+does not actually pay any attention to
+OUT
+arguments, since only the input arguments are needed to determine the function\*(Aqs identity\&. So it is sufficient to list the
+IN,
+INOUT, and
+VARIADIC
+arguments\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Note that
+\fBALTER FUNCTION\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type(s) of the function\*(Aqs arguments (optionally schema\-qualified), if any\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the function\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the function\&. Note that if the function is marked
+SECURITY DEFINER, it will subsequently execute as the new owner\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the function\&.
+.RE
+.PP
+DEPENDS ON EXTENSION \fIextension_name\fR
+.br
+NO DEPENDS ON EXTENSION \fIextension_name\fR
+.RS 4
+This form marks the function as dependent on the extension, or no longer dependent on that extension if
+NO
+is specified\&. A function that\*(Aqs marked as dependent on an extension is dropped when the extension is dropped, even if
+CASCADE
+is not specified\&. A function can depend upon multiple extensions, and will be dropped when any one of those extensions is dropped\&.
+.RE
+.PP
+CALLED ON NULL INPUT
+.br
+RETURNS NULL ON NULL INPUT
+.br
+STRICT
+.RS 4
+CALLED ON NULL INPUT
+changes the function so that it will be invoked when some or all of its arguments are null\&.
+RETURNS NULL ON NULL INPUT
+or
+STRICT
+changes the function so that it is not invoked if any of its arguments are null; instead, a null result is assumed automatically\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for more information\&.
+.RE
+.PP
+IMMUTABLE
+.br
+STABLE
+.br
+VOLATILE
+.RS 4
+Change the volatility of the function to the specified setting\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for details\&.
+.RE
+.PP
+[ EXTERNAL ] SECURITY INVOKER
+.br
+[ EXTERNAL ] SECURITY DEFINER
+.RS 4
+Change whether the function is a security definer or not\&. The key word
+EXTERNAL
+is ignored for SQL conformance\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for more information about this capability\&.
+.RE
+.PP
+PARALLEL
+.RS 4
+Change whether the function is deemed safe for parallelism\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for details\&.
+.RE
+.PP
+LEAKPROOF
+.RS 4
+Change whether the function is considered leakproof or not\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for more information about this capability\&.
+.RE
+.PP
+COST \fIexecution_cost\fR
+.RS 4
+Change the estimated execution cost of the function\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for more information\&.
+.RE
+.PP
+ROWS \fIresult_rows\fR
+.RS 4
+Change the estimated number of rows returned by a set\-returning function\&. See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for more information\&.
+.RE
+.PP
+SUPPORT \fIsupport_function\fR
+.RS 4
+Set or change the planner support function to use for this function\&. See
+Section\ \&38.11
+for details\&. You must be superuser to use this option\&.
+.sp
+This option cannot be used to remove the support function altogether, since it must name a new support function\&. Use
+\fBCREATE OR REPLACE FUNCTION\fR
+if you need to do that\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.br
+\fIvalue\fR
+.RS 4
+Add or change the assignment to be made to a configuration parameter when the function is called\&. If
+\fIvalue\fR
+is
+DEFAULT
+or, equivalently,
+RESET
+is used, the function\-local setting is removed, so that the function executes with the value present in its environment\&. Use
+RESET ALL
+to clear all function\-local settings\&.
+SET FROM CURRENT
+saves the value of the parameter that is current when
+\fBALTER FUNCTION\fR
+is executed as the value to be applied when the function is entered\&.
+.sp
+See
+\fBSET\fR(7)
+and
+Chapter\ \&20
+for more information about allowed parameter names and values\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Ignored for conformance with the SQL standard\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To rename the function
+sqrt
+for type
+integer
+to
+square_root:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FUNCTION sqrt(integer) RENAME TO square_root;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the owner of the function
+sqrt
+for type
+integer
+to
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FUNCTION sqrt(integer) OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the schema of the function
+sqrt
+for type
+integer
+to
+maths:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FUNCTION sqrt(integer) SET SCHEMA maths;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To mark the function
+sqrt
+for type
+integer
+as being dependent on the extension
+mathlib:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FUNCTION sqrt(integer) DEPENDS ON EXTENSION mathlib;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To adjust the search path that is automatically set for a function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FUNCTION check_password(text) SET search_path = admin, pg_temp;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To disable automatic setting of
+\fIsearch_path\fR
+for a function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER FUNCTION check_password(text) RESET search_path;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The function will now execute with whatever search path is used by its caller\&.
+.SH "COMPATIBILITY"
+.PP
+This statement is partially compatible with the
+\fBALTER FUNCTION\fR
+statement in the SQL standard\&. The standard allows more properties of a function to be modified, but does not provide the ability to rename a function, make a function a security definer, attach configuration parameter values to a function, or change the owner, schema, or volatility of a function\&. The standard also requires the
+RESTRICT
+key word, which is optional in
+PostgreSQL\&.
+.SH "SEE ALSO"
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)), DROP FUNCTION (\fBDROP_FUNCTION\fR(7)), ALTER PROCEDURE (\fBALTER_PROCEDURE\fR(7)), ALTER ROUTINE (\fBALTER_ROUTINE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_GROUP.7 b/doc/src/sgml/man7/ALTER_GROUP.7
new file mode 100644
index 0000000..6281c5d
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_GROUP.7
@@ -0,0 +1,113 @@
+'\" t
+.\" Title: ALTER GROUP
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER GROUP" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_GROUP \- change role name or membership
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER GROUP \fIrole_specification\fR ADD USER \fIuser_name\fR [, \&.\&.\&. ]
+ALTER GROUP \fIrole_specification\fR DROP USER \fIuser_name\fR [, \&.\&.\&. ]
+
+where \fIrole_specification\fR can be:
+
+ \fIrole_name\fR
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+
+ALTER GROUP \fIgroup_name\fR RENAME TO \fInew_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER GROUP\fR
+changes the attributes of a user group\&. This is an obsolete command, though still accepted for backwards compatibility, because groups (and users too) have been superseded by the more general concept of roles\&.
+.PP
+The first two variants add users to a group or remove them from a group\&. (Any role can play the part of either a
+\(lquser\(rq
+or a
+\(lqgroup\(rq
+for this purpose\&.) These variants are effectively equivalent to granting or revoking membership in the role named as the
+\(lqgroup\(rq; so the preferred way to do this is to use
+\fBGRANT\fR
+or
+\fBREVOKE\fR\&.
+.PP
+The third variant changes the name of the group\&. This is exactly equivalent to renaming the role with
+\fBALTER ROLE\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIgroup_name\fR
+.RS 4
+The name of the group (role) to modify\&.
+.RE
+.PP
+\fIuser_name\fR
+.RS 4
+Users (roles) that are to be added to or removed from the group\&. The users must already exist;
+\fBALTER GROUP\fR
+does not create or drop users\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the group\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add users to a group:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER GROUP staff ADD USER karl, john;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Remove a user from a group:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER GROUP workers DROP USER beth;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER GROUP\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBGRANT\fR(7), \fBREVOKE\fR(7), ALTER ROLE (\fBALTER_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_INDEX.7 b/doc/src/sgml/man7/ALTER_INDEX.7
new file mode 100644
index 0000000..8ccab98
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_INDEX.7
@@ -0,0 +1,237 @@
+'\" t
+.\" Title: ALTER INDEX
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER INDEX" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_INDEX \- change the definition of an index
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER INDEX [ IF EXISTS ] \fIname\fR RENAME TO \fInew_name\fR
+ALTER INDEX [ IF EXISTS ] \fIname\fR SET TABLESPACE \fItablespace_name\fR
+ALTER INDEX \fIname\fR ATTACH PARTITION \fIindex_name\fR
+ALTER INDEX \fIname\fR [ NO ] DEPENDS ON EXTENSION \fIextension_name\fR
+ALTER INDEX [ IF EXISTS ] \fIname\fR SET ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+ALTER INDEX [ IF EXISTS ] \fIname\fR RESET ( \fIstorage_parameter\fR [, \&.\&.\&. ] )
+ALTER INDEX [ IF EXISTS ] \fIname\fR ALTER [ COLUMN ] \fIcolumn_number\fR
+ SET STATISTICS \fIinteger\fR
+ALTER INDEX ALL IN TABLESPACE \fIname\fR [ OWNED BY \fIrole_name\fR [, \&.\&.\&. ] ]
+ SET TABLESPACE \fInew_tablespace\fR [ NOWAIT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER INDEX\fR
+changes the definition of an existing index\&. There are several subforms described below\&. Note that the lock level required may differ for each subform\&. An
+ACCESS EXCLUSIVE
+lock is held unless explicitly noted\&. When multiple subcommands are listed, the lock held will be the strictest one required from any subcommand\&.
+.PP
+RENAME
+.RS 4
+The
+RENAME
+form changes the name of the index\&. If the index is associated with a table constraint (either
+UNIQUE,
+PRIMARY KEY, or
+EXCLUDE), the constraint is renamed as well\&. There is no effect on the stored data\&.
+.sp
+Renaming an index acquires a
+SHARE UPDATE EXCLUSIVE
+lock\&.
+.RE
+.PP
+SET TABLESPACE
+.RS 4
+This form changes the index\*(Aqs tablespace to the specified tablespace and moves the data file(s) associated with the index to the new tablespace\&. To change the tablespace of an index, you must own the index and have
+CREATE
+privilege on the new tablespace\&. All indexes in the current database in a tablespace can be moved by using the
+ALL IN TABLESPACE
+form, which will lock all indexes to be moved and then move each one\&. This form also supports
+OWNED BY, which will only move indexes owned by the roles specified\&. If the
+NOWAIT
+option is specified then the command will fail if it is unable to acquire all of the locks required immediately\&. Note that system catalogs will not be moved by this command, use
+\fBALTER DATABASE\fR
+or explicit
+\fBALTER INDEX\fR
+invocations instead if desired\&. See also
+\fBCREATE TABLESPACE\fR\&.
+.RE
+.PP
+ATTACH PARTITION
+.RS 4
+Causes the named index to become attached to the altered index\&. The named index must be on a partition of the table containing the index being altered, and have an equivalent definition\&. An attached index cannot be dropped by itself, and will automatically be dropped if its parent index is dropped\&.
+.RE
+.PP
+DEPENDS ON EXTENSION \fIextension_name\fR
+.br
+NO DEPENDS ON EXTENSION \fIextension_name\fR
+.RS 4
+This form marks the index as dependent on the extension, or no longer dependent on that extension if
+NO
+is specified\&. An index that\*(Aqs marked as dependent on an extension is automatically dropped when the extension is dropped\&.
+.RE
+.PP
+SET ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This form changes one or more index\-method\-specific storage parameters for the index\&. See
+\fBCREATE INDEX\fR
+for details on the available parameters\&. Note that the index contents will not be modified immediately by this command; depending on the parameter you might need to rebuild the index with
+\fBREINDEX\fR
+to get the desired effects\&.
+.RE
+.PP
+RESET ( \fIstorage_parameter\fR [, \&.\&.\&. ] )
+.RS 4
+This form resets one or more index\-method\-specific storage parameters to their defaults\&. As with
+SET, a
+REINDEX
+might be needed to update the index entirely\&.
+.RE
+.PP
+ALTER [ COLUMN ] \fIcolumn_number\fR SET STATISTICS \fIinteger\fR
+.RS 4
+This form sets the per\-column statistics\-gathering target for subsequent
+\fBANALYZE\fR
+operations, though can be used only on index columns that are defined as an expression\&. Since expressions lack a unique name, we refer to them using the ordinal number of the index column\&. The target can be set in the range 0 to 10000; alternatively, set it to \-1 to revert to using the system default statistics target (default_statistics_target)\&. For more information on the use of statistics by the
+PostgreSQL
+query planner, refer to
+Section\ \&14.2\&.
+.RE
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the index does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIcolumn_number\fR
+.RS 4
+The ordinal number refers to the ordinal (left\-to\-right) position of the index column\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (possibly schema\-qualified) of an existing index to alter\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the index\&.
+.RE
+.PP
+\fItablespace_name\fR
+.RS 4
+The tablespace to which the index will be moved\&.
+.RE
+.PP
+\fIextension_name\fR
+.RS 4
+The name of the extension that the index is to depend on\&.
+.RE
+.PP
+\fIstorage_parameter\fR
+.RS 4
+The name of an index\-method\-specific storage parameter\&.
+.RE
+.PP
+\fIvalue\fR
+.RS 4
+The new value for an index\-method\-specific storage parameter\&. This might be a number or a word depending on the parameter\&.
+.RE
+.SH "NOTES"
+.PP
+These operations are also possible using
+\fBALTER TABLE\fR\&.
+\fBALTER INDEX\fR
+is in fact just an alias for the forms of
+\fBALTER TABLE\fR
+that apply to indexes\&.
+.PP
+There was formerly an
+\fBALTER INDEX OWNER\fR
+variant, but this is now ignored (with a warning)\&. An index cannot have an owner different from its table\*(Aqs owner\&. Changing the table\*(Aqs owner automatically changes the index as well\&.
+.PP
+Changing any part of a system catalog index is not permitted\&.
+.SH "EXAMPLES"
+.PP
+To rename an existing index:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER INDEX distributors RENAME TO suppliers;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To move an index to a different tablespace:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER INDEX distributors SET TABLESPACE fasttablespace;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change an index\*(Aqs fill factor (assuming that the index method supports it):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER INDEX distributors SET (fillfactor = 75);
+REINDEX INDEX distributors;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Set the statistics\-gathering target for an expression index:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX coord_idx ON measured (x, y, (z + t));
+ALTER INDEX coord_idx ALTER COLUMN 3 SET STATISTICS 1000;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER INDEX\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE INDEX (\fBCREATE_INDEX\fR(7)), \fBREINDEX\fR(7)
diff --git a/doc/src/sgml/man7/ALTER_LANGUAGE.7 b/doc/src/sgml/man7/ALTER_LANGUAGE.7
new file mode 100644
index 0000000..96431b4
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_LANGUAGE.7
@@ -0,0 +1,65 @@
+'\" t
+.\" Title: ALTER LANGUAGE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER LANGUAGE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_LANGUAGE \- change the definition of a procedural language
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER [ PROCEDURAL ] LANGUAGE \fIname\fR RENAME TO \fInew_name\fR
+ALTER [ PROCEDURAL ] LANGUAGE \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER LANGUAGE\fR
+changes the definition of a procedural language\&. The only functionality is to rename the language or assign a new owner\&. You must be superuser or owner of the language to use
+\fBALTER LANGUAGE\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+Name of a language
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the language
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the language
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER LANGUAGE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE LANGUAGE (\fBCREATE_LANGUAGE\fR(7)), DROP LANGUAGE (\fBDROP_LANGUAGE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_LARGE_OBJECT.7 b/doc/src/sgml/man7/ALTER_LARGE_OBJECT.7
new file mode 100644
index 0000000..06df1a1
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_LARGE_OBJECT.7
@@ -0,0 +1,61 @@
+'\" t
+.\" Title: ALTER LARGE OBJECT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER LARGE OBJECT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_LARGE_OBJECT \- change the definition of a large object
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER LARGE OBJECT \fIlarge_object_oid\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER LARGE OBJECT\fR
+changes the definition of a large object\&.
+.PP
+You must own the large object to use
+\fBALTER LARGE OBJECT\fR\&. To alter the owner, you must also be a direct or indirect member of the new owning role\&. (However, a superuser can alter any large object anyway\&.) Currently, the only functionality is to assign a new owner, so both restrictions always apply\&.
+.SH "PARAMETERS"
+.PP
+\fIlarge_object_oid\fR
+.RS 4
+OID of the large object to be altered
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the large object
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER LARGE OBJECT\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+Chapter\ \&35
diff --git a/doc/src/sgml/man7/ALTER_MATERIALIZED_VIEW.7 b/doc/src/sgml/man7/ALTER_MATERIALIZED_VIEW.7
new file mode 100644
index 0000000..9c59216
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_MATERIALIZED_VIEW.7
@@ -0,0 +1,142 @@
+'\" t
+.\" Title: ALTER MATERIALIZED VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER MATERIALIZED VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_MATERIALIZED_VIEW \- change the definition of a materialized view
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER MATERIALIZED VIEW [ IF EXISTS ] \fIname\fR
+ \fIaction\fR [, \&.\&.\&. ]
+ALTER MATERIALIZED VIEW \fIname\fR
+ [ NO ] DEPENDS ON EXTENSION \fIextension_name\fR
+ALTER MATERIALIZED VIEW [ IF EXISTS ] \fIname\fR
+ RENAME [ COLUMN ] \fIcolumn_name\fR TO \fInew_column_name\fR
+ALTER MATERIALIZED VIEW [ IF EXISTS ] \fIname\fR
+ RENAME TO \fInew_name\fR
+ALTER MATERIALIZED VIEW [ IF EXISTS ] \fIname\fR
+ SET SCHEMA \fInew_schema\fR
+ALTER MATERIALIZED VIEW ALL IN TABLESPACE \fIname\fR [ OWNED BY \fIrole_name\fR [, \&.\&.\&. ] ]
+ SET TABLESPACE \fInew_tablespace\fR [ NOWAIT ]
+
+where \fIaction\fR is one of:
+
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET STATISTICS \fIinteger\fR
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET ( \fIattribute_option\fR = \fIvalue\fR [, \&.\&.\&. ] )
+ ALTER [ COLUMN ] \fIcolumn_name\fR RESET ( \fIattribute_option\fR [, \&.\&.\&. ] )
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET COMPRESSION \fIcompression_method\fR
+ CLUSTER ON \fIindex_name\fR
+ SET WITHOUT CLUSTER
+ SET ACCESS METHOD \fInew_access_method\fR
+ SET TABLESPACE \fInew_tablespace\fR
+ SET ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+ RESET ( \fIstorage_parameter\fR [, \&.\&.\&. ] )
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER MATERIALIZED VIEW\fR
+changes various auxiliary properties of an existing materialized view\&.
+.PP
+You must own the materialized view to use
+\fBALTER MATERIALIZED VIEW\fR\&. To change a materialized view\*(Aqs schema, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the materialized view\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the materialized view\&. However, a superuser can alter ownership of any view anyway\&.)
+.PP
+The statement subforms and actions available for
+\fBALTER MATERIALIZED VIEW\fR
+are a subset of those available for
+\fBALTER TABLE\fR, and have the same meaning when used for materialized views\&. See the descriptions for
+\fBALTER TABLE\fR
+for details\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing materialized view\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+Name of a new or existing column\&.
+.RE
+.PP
+\fIextension_name\fR
+.RS 4
+The name of the extension that the materialized view is to depend on (or no longer dependent on, if
+NO
+is specified)\&. A materialized view that\*(Aqs marked as dependent on an extension is automatically dropped when the extension is dropped\&.
+.RE
+.PP
+\fInew_column_name\fR
+.RS 4
+New name for an existing column\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the materialized view\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the materialized view\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the materialized view\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To rename the materialized view
+foo
+to
+bar:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER MATERIALIZED VIEW foo RENAME TO bar;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER MATERIALIZED VIEW\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE MATERIALIZED VIEW (\fBCREATE_MATERIALIZED_VIEW\fR(7)), DROP MATERIALIZED VIEW (\fBDROP_MATERIALIZED_VIEW\fR(7)), REFRESH MATERIALIZED VIEW (\fBREFRESH_MATERIALIZED_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_OPERATOR.7 b/doc/src/sgml/man7/ALTER_OPERATOR.7
new file mode 100644
index 0000000..1593a80
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_OPERATOR.7
@@ -0,0 +1,130 @@
+'\" t
+.\" Title: ALTER OPERATOR
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER OPERATOR" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_OPERATOR \- change the definition of an operator
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER OPERATOR \fIname\fR ( { \fIleft_type\fR | NONE } , \fIright_type\fR )
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR \fIname\fR ( { \fIleft_type\fR | NONE } , \fIright_type\fR )
+ SET SCHEMA \fInew_schema\fR
+
+ALTER OPERATOR \fIname\fR ( { \fIleft_type\fR | NONE } , \fIright_type\fR )
+ SET ( { RESTRICT = { \fIres_proc\fR | NONE }
+ | JOIN = { \fIjoin_proc\fR | NONE }
+ } [, \&.\&.\&. ] )
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER OPERATOR\fR
+changes the definition of an operator\&.
+.PP
+You must own the operator to use
+\fBALTER OPERATOR\fR\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the operator\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the operator\&. However, a superuser can alter ownership of any operator anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing operator\&.
+.RE
+.PP
+\fIleft_type\fR
+.RS 4
+The data type of the operator\*(Aqs left operand; write
+NONE
+if the operator has no left operand\&.
+.RE
+.PP
+\fIright_type\fR
+.RS 4
+The data type of the operator\*(Aqs right operand\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the operator\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the operator\&.
+.RE
+.PP
+\fIres_proc\fR
+.RS 4
+The restriction selectivity estimator function for this operator; write NONE to remove existing selectivity estimator\&.
+.RE
+.PP
+\fIjoin_proc\fR
+.RS 4
+The join selectivity estimator function for this operator; write NONE to remove existing selectivity estimator\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Change the owner of a custom operator
+a @@ b
+for type
+text:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER OPERATOR @@ (text, text) OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Change the restriction and join selectivity estimator functions of a custom operator
+a && b
+for type
+int[]:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER OPERATOR && (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER OPERATOR\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE OPERATOR (\fBCREATE_OPERATOR\fR(7)), DROP OPERATOR (\fBDROP_OPERATOR\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_OPERATOR_CLASS.7 b/doc/src/sgml/man7/ALTER_OPERATOR_CLASS.7
new file mode 100644
index 0000000..b313318
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_OPERATOR_CLASS.7
@@ -0,0 +1,85 @@
+'\" t
+.\" Title: ALTER OPERATOR CLASS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER OPERATOR CLASS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_OPERATOR_CLASS \- change the definition of an operator class
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER OPERATOR CLASS \fIname\fR USING \fIindex_method\fR
+ RENAME TO \fInew_name\fR
+
+ALTER OPERATOR CLASS \fIname\fR USING \fIindex_method\fR
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR CLASS \fIname\fR USING \fIindex_method\fR
+ SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER OPERATOR CLASS\fR
+changes the definition of an operator class\&.
+.PP
+You must own the operator class to use
+\fBALTER OPERATOR CLASS\fR\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the operator class\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the operator class\&. However, a superuser can alter ownership of any operator class anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing operator class\&.
+.RE
+.PP
+\fIindex_method\fR
+.RS 4
+The name of the index method this operator class is for\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the operator class\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the operator class\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the operator class\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER OPERATOR CLASS\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), DROP OPERATOR CLASS (\fBDROP_OPERATOR_CLASS\fR(7)), ALTER OPERATOR FAMILY (\fBALTER_OPERATOR_FAMILY\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_OPERATOR_FAMILY.7 b/doc/src/sgml/man7/ALTER_OPERATOR_FAMILY.7
new file mode 100644
index 0000000..0ec77e1
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_OPERATOR_FAMILY.7
@@ -0,0 +1,259 @@
+'\" t
+.\" Title: ALTER OPERATOR FAMILY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER OPERATOR FAMILY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_OPERATOR_FAMILY \- change the definition of an operator family
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER OPERATOR FAMILY \fIname\fR USING \fIindex_method\fR ADD
+ { OPERATOR \fIstrategy_number\fR \fIoperator_name\fR ( \fIop_type\fR, \fIop_type\fR )
+ [ FOR SEARCH | FOR ORDER BY \fIsort_family_name\fR ]
+ | FUNCTION \fIsupport_number\fR [ ( \fIop_type\fR [ , \fIop_type\fR ] ) ]
+ \fIfunction_name\fR [ ( \fIargument_type\fR [, \&.\&.\&.] ) ]
+ } [, \&.\&.\&. ]
+
+ALTER OPERATOR FAMILY \fIname\fR USING \fIindex_method\fR DROP
+ { OPERATOR \fIstrategy_number\fR ( \fIop_type\fR [ , \fIop_type\fR ] )
+ | FUNCTION \fIsupport_number\fR ( \fIop_type\fR [ , \fIop_type\fR ] )
+ } [, \&.\&.\&. ]
+
+ALTER OPERATOR FAMILY \fIname\fR USING \fIindex_method\fR
+ RENAME TO \fInew_name\fR
+
+ALTER OPERATOR FAMILY \fIname\fR USING \fIindex_method\fR
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR FAMILY \fIname\fR USING \fIindex_method\fR
+ SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER OPERATOR FAMILY\fR
+changes the definition of an operator family\&. You can add operators and support functions to the family, remove them from the family, or change the family\*(Aqs name or owner\&.
+.PP
+When operators and support functions are added to a family with
+\fBALTER OPERATOR FAMILY\fR, they are not part of any specific operator class within the family, but are just
+\(lqloose\(rq
+within the family\&. This indicates that these operators and functions are compatible with the family\*(Aqs semantics, but are not required for correct functioning of any specific index\&. (Operators and functions that are so required should be declared as part of an operator class, instead; see
+CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7))\&.)
+PostgreSQL
+will allow loose members of a family to be dropped from the family at any time, but members of an operator class cannot be dropped without dropping the whole class and any indexes that depend on it\&. Typically, single\-data\-type operators and functions are part of operator classes because they are needed to support an index on that specific data type, while cross\-data\-type operators and functions are made loose members of the family\&.
+.PP
+You must be a superuser to use
+\fBALTER OPERATOR FAMILY\fR\&. (This restriction is made because an erroneous operator family definition could confuse or even crash the server\&.)
+.PP
+\fBALTER OPERATOR FAMILY\fR
+does not presently check whether the operator family definition includes all the operators and functions required by the index method, nor whether the operators and functions form a self\-consistent set\&. It is the user\*(Aqs responsibility to define a valid operator family\&.
+.PP
+Refer to
+Section\ \&38.16
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing operator family\&.
+.RE
+.PP
+\fIindex_method\fR
+.RS 4
+The name of the index method this operator family is for\&.
+.RE
+.PP
+\fIstrategy_number\fR
+.RS 4
+The index method\*(Aqs strategy number for an operator associated with the operator family\&.
+.RE
+.PP
+\fIoperator_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an operator associated with the operator family\&.
+.RE
+.PP
+\fIop_type\fR
+.RS 4
+In an
+OPERATOR
+clause, the operand data type(s) of the operator, or
+NONE
+to signify a prefix operator\&. Unlike the comparable syntax in
+\fBCREATE OPERATOR CLASS\fR, the operand data types must always be specified\&.
+.sp
+In an
+ADD FUNCTION
+clause, the operand data type(s) the function is intended to support, if different from the input data type(s) of the function\&. For B\-tree comparison functions and hash functions it is not necessary to specify
+\fIop_type\fR
+since the function\*(Aqs input data type(s) are always the correct ones to use\&. For B\-tree sort support functions, B\-Tree equal image functions, and all functions in GiST, SP\-GiST and GIN operator classes, it is necessary to specify the operand data type(s) the function is to be used with\&.
+.sp
+In a
+DROP FUNCTION
+clause, the operand data type(s) the function is intended to support must be specified\&.
+.RE
+.PP
+\fIsort_family_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing
+btree
+operator family that describes the sort ordering associated with an ordering operator\&.
+.sp
+If neither
+FOR SEARCH
+nor
+FOR ORDER BY
+is specified,
+FOR SEARCH
+is the default\&.
+.RE
+.PP
+\fIsupport_number\fR
+.RS 4
+The index method\*(Aqs support function number for a function associated with the operator family\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+The name (optionally schema\-qualified) of a function that is an index method support function for the operator family\&. If no argument list is specified, the name must be unique in its schema\&.
+.RE
+.PP
+\fIargument_type\fR
+.RS 4
+The parameter data type(s) of the function\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the operator family\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the operator family\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the operator family\&.
+.RE
+.PP
+The
+OPERATOR
+and
+FUNCTION
+clauses can appear in any order\&.
+.SH "NOTES"
+.PP
+Notice that the
+DROP
+syntax only specifies the
+\(lqslot\(rq
+in the operator family, by strategy or support number and input data type(s)\&. The name of the operator or function occupying the slot is not mentioned\&. Also, for
+DROP FUNCTION
+the type(s) to specify are the input data type(s) the function is intended to support; for GiST, SP\-GiST and GIN indexes this might have nothing to do with the actual input argument types of the function\&.
+.PP
+Because the index machinery does not check access permissions on functions before using them, including a function or operator in an operator family is tantamount to granting public execute permission on it\&. This is usually not an issue for the sorts of functions that are useful in an operator family\&.
+.PP
+The operators should not be defined by SQL functions\&. An SQL function is likely to be inlined into the calling query, which will prevent the optimizer from recognizing that the query matches an index\&.
+.PP
+Before
+PostgreSQL
+8\&.4, the
+OPERATOR
+clause could include a
+RECHECK
+option\&. This is no longer supported because whether an index operator is
+\(lqlossy\(rq
+is now determined on\-the\-fly at run time\&. This allows efficient handling of cases where an operator might or might not be lossy\&.
+.SH "EXAMPLES"
+.PP
+The following example command adds cross\-data\-type operators and support functions to an operator family that already contains B\-tree operator classes for data types
+int4
+and
+int2\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER OPERATOR FAMILY integer_ops USING btree ADD
+
+ \-\- int4 vs int2
+ OPERATOR 1 < (int4, int2) ,
+ OPERATOR 2 <= (int4, int2) ,
+ OPERATOR 3 = (int4, int2) ,
+ OPERATOR 4 >= (int4, int2) ,
+ OPERATOR 5 > (int4, int2) ,
+ FUNCTION 1 btint42cmp(int4, int2) ,
+
+ \-\- int2 vs int4
+ OPERATOR 1 < (int2, int4) ,
+ OPERATOR 2 <= (int2, int4) ,
+ OPERATOR 3 = (int2, int4) ,
+ OPERATOR 4 >= (int2, int4) ,
+ OPERATOR 5 > (int2, int4) ,
+ FUNCTION 1 btint24cmp(int2, int4) ;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To remove these entries again:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER OPERATOR FAMILY integer_ops USING btree DROP
+
+ \-\- int4 vs int2
+ OPERATOR 1 (int4, int2) ,
+ OPERATOR 2 (int4, int2) ,
+ OPERATOR 3 (int4, int2) ,
+ OPERATOR 4 (int4, int2) ,
+ OPERATOR 5 (int4, int2) ,
+ FUNCTION 1 (int4, int2) ,
+
+ \-\- int2 vs int4
+ OPERATOR 1 (int2, int4) ,
+ OPERATOR 2 (int2, int4) ,
+ OPERATOR 3 (int2, int4) ,
+ OPERATOR 4 (int2, int4) ,
+ OPERATOR 5 (int2, int4) ,
+ FUNCTION 1 (int2, int4) ;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER OPERATOR FAMILY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE OPERATOR FAMILY (\fBCREATE_OPERATOR_FAMILY\fR(7)), DROP OPERATOR FAMILY (\fBDROP_OPERATOR_FAMILY\fR(7)), CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), ALTER OPERATOR CLASS (\fBALTER_OPERATOR_CLASS\fR(7)), DROP OPERATOR CLASS (\fBDROP_OPERATOR_CLASS\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_POLICY.7 b/doc/src/sgml/man7/ALTER_POLICY.7
new file mode 100644
index 0000000..250435b
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_POLICY.7
@@ -0,0 +1,108 @@
+'\" t
+.\" Title: ALTER POLICY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER POLICY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_POLICY \- change the definition of a row\-level security policy
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER POLICY \fIname\fR ON \fItable_name\fR RENAME TO \fInew_name\fR
+
+ALTER POLICY \fIname\fR ON \fItable_name\fR
+ [ TO { \fIrole_name\fR | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, \&.\&.\&.] ]
+ [ USING ( \fIusing_expression\fR ) ]
+ [ WITH CHECK ( \fIcheck_expression\fR ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER POLICY\fR
+changes the definition of an existing row\-level security policy\&. Note that
+\fBALTER POLICY\fR
+only allows the set of roles to which the policy applies and the
+USING
+and
+WITH CHECK
+expressions to be modified\&. To change other properties of a policy, such as the command to which it applies or whether it is permissive or restrictive, the policy must be dropped and recreated\&.
+.PP
+To use
+\fBALTER POLICY\fR, you must own the table that the policy applies to\&.
+.PP
+In the second form of
+\fBALTER POLICY\fR, the role list,
+\fIusing_expression\fR, and
+\fIcheck_expression\fR
+are replaced independently if specified\&. When one of those clauses is omitted, the corresponding part of the policy is unchanged\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing policy to alter\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table that the policy is on\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the policy\&.
+.RE
+.PP
+\fIrole_name\fR
+.RS 4
+The role(s) to which the policy applies\&. Multiple roles can be specified at one time\&. To apply the policy to all roles, use
+PUBLIC\&.
+.RE
+.PP
+\fIusing_expression\fR
+.RS 4
+The
+USING
+expression for the policy\&. See
+CREATE POLICY (\fBCREATE_POLICY\fR(7))
+for details\&.
+.RE
+.PP
+\fIcheck_expression\fR
+.RS 4
+The
+WITH CHECK
+expression for the policy\&. See
+CREATE POLICY (\fBCREATE_POLICY\fR(7))
+for details\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+\fBALTER POLICY\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE POLICY (\fBCREATE_POLICY\fR(7)), DROP POLICY (\fBDROP_POLICY\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_PROCEDURE.7 b/doc/src/sgml/man7/ALTER_PROCEDURE.7
new file mode 100644
index 0000000..0ea7ffa
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_PROCEDURE.7
@@ -0,0 +1,263 @@
+'\" t
+.\" Title: ALTER PROCEDURE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER PROCEDURE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_PROCEDURE \- change the definition of a procedure
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER PROCEDURE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ \fIaction\fR [ \&.\&.\&. ] [ RESTRICT ]
+ALTER PROCEDURE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ RENAME TO \fInew_name\fR
+ALTER PROCEDURE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER PROCEDURE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ SET SCHEMA \fInew_schema\fR
+ALTER PROCEDURE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION \fIextension_name\fR
+
+where \fIaction\fR is one of:
+
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | DEFAULT }
+ SET \fIconfiguration_parameter\fR FROM CURRENT
+ RESET \fIconfiguration_parameter\fR
+ RESET ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER PROCEDURE\fR
+changes the definition of a procedure\&.
+.PP
+You must own the procedure to use
+\fBALTER PROCEDURE\fR\&. To change a procedure\*(Aqs schema, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the procedure\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the procedure\&. However, a superuser can alter ownership of any procedure anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing procedure\&. If no argument list is specified, the name must be unique in its schema\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Note that
+\fBALTER PROCEDURE\fR
+does not actually pay any attention to argument names, since only the argument data types are used to determine the procedure\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type(s) of the procedure\*(Aqs arguments (optionally schema\-qualified), if any\&. See
+DROP PROCEDURE (\fBDROP_PROCEDURE\fR(7))
+for the details of how the procedure is looked up using the argument data type(s)\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the procedure\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the procedure\&. Note that if the procedure is marked
+SECURITY DEFINER, it will subsequently execute as the new owner\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the procedure\&.
+.RE
+.PP
+\fIextension_name\fR
+.RS 4
+This form marks the procedure as dependent on the extension, or no longer dependent on the extension if
+NO
+is specified\&. A procedure that\*(Aqs marked as dependent on an extension is dropped when the extension is dropped, even if cascade is not specified\&. A procedure can depend upon multiple extensions, and will be dropped when any one of those extensions is dropped\&.
+.RE
+.PP
+[ EXTERNAL ] SECURITY INVOKER
+.br
+[ EXTERNAL ] SECURITY DEFINER
+.RS 4
+Change whether the procedure is a security definer or not\&. The key word
+EXTERNAL
+is ignored for SQL conformance\&. See
+CREATE PROCEDURE (\fBCREATE_PROCEDURE\fR(7))
+for more information about this capability\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.br
+\fIvalue\fR
+.RS 4
+Add or change the assignment to be made to a configuration parameter when the procedure is called\&. If
+\fIvalue\fR
+is
+DEFAULT
+or, equivalently,
+RESET
+is used, the procedure\-local setting is removed, so that the procedure executes with the value present in its environment\&. Use
+RESET ALL
+to clear all procedure\-local settings\&.
+SET FROM CURRENT
+saves the value of the parameter that is current when
+\fBALTER PROCEDURE\fR
+is executed as the value to be applied when the procedure is entered\&.
+.sp
+See
+\fBSET\fR(7)
+and
+Chapter\ \&20
+for more information about allowed parameter names and values\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Ignored for conformance with the SQL standard\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To rename the procedure
+insert_data
+with two arguments of type
+integer
+to
+insert_record:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PROCEDURE insert_data(integer, integer) RENAME TO insert_record;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the owner of the procedure
+insert_data
+with two arguments of type
+integer
+to
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PROCEDURE insert_data(integer, integer) OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the schema of the procedure
+insert_data
+with two arguments of type
+integer
+to
+accounting:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PROCEDURE insert_data(integer, integer) SET SCHEMA accounting;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To mark the procedure
+insert_data(integer, integer)
+as being dependent on the extension
+myext:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PROCEDURE insert_data(integer, integer) DEPENDS ON EXTENSION myext;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To adjust the search path that is automatically set for a procedure:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PROCEDURE check_password(text) SET search_path = admin, pg_temp;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To disable automatic setting of
+\fIsearch_path\fR
+for a procedure:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PROCEDURE check_password(text) RESET search_path;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The procedure will now execute with whatever search path is used by its caller\&.
+.SH "COMPATIBILITY"
+.PP
+This statement is partially compatible with the
+\fBALTER PROCEDURE\fR
+statement in the SQL standard\&. The standard allows more properties of a procedure to be modified, but does not provide the ability to rename a procedure, make a procedure a security definer, attach configuration parameter values to a procedure, or change the owner, schema, or volatility of a procedure\&. The standard also requires the
+RESTRICT
+key word, which is optional in
+PostgreSQL\&.
+.SH "SEE ALSO"
+CREATE PROCEDURE (\fBCREATE_PROCEDURE\fR(7)), DROP PROCEDURE (\fBDROP_PROCEDURE\fR(7)), ALTER FUNCTION (\fBALTER_FUNCTION\fR(7)), ALTER ROUTINE (\fBALTER_ROUTINE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_PUBLICATION.7 b/doc/src/sgml/man7/ALTER_PUBLICATION.7
new file mode 100644
index 0000000..6086964
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_PUBLICATION.7
@@ -0,0 +1,221 @@
+'\" t
+.\" Title: ALTER PUBLICATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER PUBLICATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_PUBLICATION \- change the definition of a publication
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER PUBLICATION \fIname\fR ADD \fIpublication_object\fR [, \&.\&.\&.]
+ALTER PUBLICATION \fIname\fR SET \fIpublication_object\fR [, \&.\&.\&.]
+ALTER PUBLICATION \fIname\fR DROP \fIpublication_object\fR [, \&.\&.\&.]
+ALTER PUBLICATION \fIname\fR SET ( \fIpublication_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+ALTER PUBLICATION \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER PUBLICATION \fIname\fR RENAME TO \fInew_name\fR
+
+where \fIpublication_object\fR is one of:
+
+ TABLE [ ONLY ] \fItable_name\fR [ * ] [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ] [ WHERE ( \fIexpression\fR ) ] [, \&.\&.\&. ]
+ TABLES IN SCHEMA { \fIschema_name\fR | CURRENT_SCHEMA } [, \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+The command
+\fBALTER PUBLICATION\fR
+can change the attributes of a publication\&.
+.PP
+The first three variants change which tables/schemas are part of the publication\&. The
+SET
+clause will replace the list of tables/schemas in the publication with the specified list; the existing tables/schemas that were present in the publication will be removed\&. The
+ADD
+and
+DROP
+clauses will add and remove one or more tables/schemas from the publication\&. Note that adding tables/schemas to a publication that is already subscribed to will require an
+ALTER SUBSCRIPTION \&.\&.\&. REFRESH PUBLICATION
+action on the subscribing side in order to become effective\&. Note also that
+DROP TABLES IN SCHEMA
+will not drop any schema tables that were specified using
+FOR TABLE/
+ADD TABLE, and the combination of
+DROP
+with a
+WHERE
+clause is not allowed\&.
+.PP
+The fourth variant of this command listed in the synopsis can change all of the publication properties specified in
+CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7))\&. Properties not mentioned in the command retain their previous settings\&.
+.PP
+The remaining variants change the owner and the name of the publication\&.
+.PP
+You must own the publication to use
+\fBALTER PUBLICATION\fR\&. Adding a table to a publication additionally requires owning that table\&. The
+ADD TABLES IN SCHEMA
+and
+SET TABLES IN SCHEMA
+to a publication requires the invoking user to be a superuser\&. To alter the owner, you must also be a direct or indirect member of the new owning role\&. The new owner must have
+CREATE
+privilege on the database\&. Also, the new owner of a
+FOR ALL TABLES
+or
+FOR TABLES IN SCHEMA
+publication must be a superuser\&. However, a superuser can change the ownership of a publication regardless of these restrictions\&.
+.PP
+Adding/Setting any schema when the publication also publishes a table with a column list, and vice versa is not supported\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing publication whose definition is to be altered\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+Name of an existing table\&. If
+ONLY
+is specified before the table name, only that table is affected\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are affected\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.sp
+Optionally, a column list can be specified\&. See
+CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7))
+for details\&. Note that a subscription having several publications in which the same table has been published with different column lists is not supported\&. See
+Warning: Combining Column Lists from Multiple Publications
+for details of potential problems when altering column lists\&.
+.sp
+If the optional
+WHERE
+clause is specified, rows for which the
+\fIexpression\fR
+evaluates to false or null will not be published\&. Note that parentheses are required around the expression\&. The
+\fIexpression\fR
+is evaluated with the role used for the replication connection\&.
+.RE
+.PP
+\fIschema_name\fR
+.RS 4
+Name of an existing schema\&.
+.RE
+.PP
+SET ( \fIpublication_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause alters publication parameters originally set by
+CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7))\&. See there for more information\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the publication\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the publication\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Change the publication to publish only deletes and updates:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PUBLICATION noinsert SET (publish = \*(Aqupdate, delete\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Add some tables to the publication:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PUBLICATION mypublication ADD TABLE users (user_id, firstname), departments;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Change the set of columns published for a table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PUBLICATION mypublication SET TABLE users (user_id, firstname, lastname), TABLE departments;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Add schemas
+marketing
+and
+sales
+to the publication
+sales_publication:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PUBLICATION sales_publication ADD TABLES IN SCHEMA marketing, sales;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Add tables
+users,
+departments
+and schema
+production
+to the publication
+production_publication:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER PUBLICATION production_publication ADD TABLE users, departments, TABLES IN SCHEMA production;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER PUBLICATION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7)), DROP PUBLICATION (\fBDROP_PUBLICATION\fR(7)), CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7)), ALTER SUBSCRIPTION (\fBALTER_SUBSCRIPTION\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_ROLE.7 b/doc/src/sgml/man7/ALTER_ROLE.7
new file mode 100644
index 0000000..e6ded18
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_ROLE.7
@@ -0,0 +1,335 @@
+'\" t
+.\" Title: ALTER ROLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER ROLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_ROLE \- change a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER ROLE \fIrole_specification\fR [ WITH ] \fIoption\fR [ \&.\&.\&. ]
+
+where \fIoption\fR can be:
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT \fIconnlimit\fR
+ | [ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq | PASSWORD NULL
+ | VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+
+ALTER ROLE \fIname\fR RENAME TO \fInew_name\fR
+
+ALTER ROLE { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | DEFAULT }
+ALTER ROLE { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] SET \fIconfiguration_parameter\fR FROM CURRENT
+ALTER ROLE { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] RESET \fIconfiguration_parameter\fR
+ALTER ROLE { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] RESET ALL
+
+where \fIrole_specification\fR can be:
+
+ \fIrole_name\fR
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER ROLE\fR
+changes the attributes of a
+PostgreSQL
+role\&.
+.PP
+The first variant of this command listed in the synopsis can change many of the role attributes that can be specified in
+\fBCREATE ROLE\fR\&. (All the possible attributes are covered, except that there are no options for adding or removing memberships; use
+\fBGRANT\fR
+and
+\fBREVOKE\fR
+for that\&.) Attributes not mentioned in the command retain their previous settings\&. Database superusers can change any of these settings for any role\&. Roles having
+CREATEROLE
+privilege can change any of these settings except
+SUPERUSER,
+REPLICATION, and
+BYPASSRLS; but only for non\-superuser and non\-replication roles\&. Ordinary roles can only change their own password\&.
+.PP
+The second variant changes the name of the role\&. Database superusers can rename any role\&. Roles having
+CREATEROLE
+privilege can rename non\-superuser roles\&. The current session user cannot be renamed\&. (Connect as a different user if you need to do that\&.) Because
+MD5\-encrypted passwords use the role name as cryptographic salt, renaming a role clears its password if the password is
+MD5\-encrypted\&.
+.PP
+The remaining variants change a role\*(Aqs session default for a configuration variable, either for all databases or, when the
+IN DATABASE
+clause is specified, only for sessions in the named database\&. If
+ALL
+is specified instead of a role name, this changes the setting for all roles\&. Using
+ALL
+with
+IN DATABASE
+is effectively the same as using the command
+ALTER DATABASE \&.\&.\&. SET \&.\&.\&.\&.
+.PP
+Whenever the role subsequently starts a new session, the specified value becomes the session default, overriding whatever setting is present in
+postgresql\&.conf
+or has been received from the
+\fBpostgres\fR
+command line\&. This only happens at login time; executing
+\fBSET ROLE\fR
+or
+\fBSET SESSION AUTHORIZATION\fR
+does not cause new configuration values to be set\&. Settings set for all databases are overridden by database\-specific settings attached to a role\&. Settings for specific databases or specific roles override settings for all roles\&.
+.PP
+Superusers can change anyone\*(Aqs session defaults\&. Roles having
+CREATEROLE
+privilege can change defaults for non\-superuser roles\&. Ordinary roles can only set defaults for themselves\&. Certain configuration variables cannot be set this way, or can only be set if a superuser issues the command\&. Only superusers can change a setting for all roles in all databases\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the role whose attributes are to be altered\&.
+.RE
+.PP
+CURRENT_ROLE
+.br
+CURRENT_USER
+.RS 4
+Alter the current user instead of an explicitly identified role\&.
+.RE
+.PP
+SESSION_USER
+.RS 4
+Alter the current session user instead of an explicitly identified role\&.
+.RE
+.PP
+SUPERUSER
+.br
+NOSUPERUSER
+.br
+CREATEDB
+.br
+NOCREATEDB
+.br
+CREATEROLE
+.br
+NOCREATEROLE
+.br
+INHERIT
+.br
+NOINHERIT
+.br
+LOGIN
+.br
+NOLOGIN
+.br
+REPLICATION
+.br
+NOREPLICATION
+.br
+BYPASSRLS
+.br
+NOBYPASSRLS
+.br
+CONNECTION LIMIT \fIconnlimit\fR
+.br
+[ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq
+.br
+PASSWORD NULL
+.br
+VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+.RS 4
+These clauses alter attributes originally set by
+\fBCREATE ROLE\fR\&. For more information, see the
+\fBCREATE ROLE\fR
+reference page\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the role\&.
+.RE
+.PP
+\fIdatabase_name\fR
+.RS 4
+The name of the database the configuration variable should be set in\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.br
+\fIvalue\fR
+.RS 4
+Set this role\*(Aqs session default for the specified configuration parameter to the given value\&. If
+\fIvalue\fR
+is
+DEFAULT
+or, equivalently,
+RESET
+is used, the role\-specific variable setting is removed, so the role will inherit the system\-wide default setting in new sessions\&. Use
+RESET ALL
+to clear all role\-specific settings\&.
+SET FROM CURRENT
+saves the session\*(Aqs current value of the parameter as the role\-specific value\&. If
+IN DATABASE
+is specified, the configuration parameter is set or removed for the given role and database only\&.
+.sp
+Role\-specific variable settings take effect only at login;
+\fBSET ROLE\fR
+and
+\fBSET SESSION AUTHORIZATION\fR
+do not process role\-specific variable settings\&.
+.sp
+See
+\fBSET\fR(7)
+and
+Chapter\ \&20
+for more information about allowed parameter names and values\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBCREATE ROLE\fR
+to add new roles, and
+\fBDROP ROLE\fR
+to remove a role\&.
+.PP
+\fBALTER ROLE\fR
+cannot change a role\*(Aqs memberships\&. Use
+\fBGRANT\fR
+and
+\fBREVOKE\fR
+to do that\&.
+.PP
+Caution must be exercised when specifying an unencrypted password with this command\&. The password will be transmitted to the server in cleartext, and it might also be logged in the client\*(Aqs command history or the server log\&.
+\fBpsql\fR(1)
+contains a command
+\fB\epassword\fR
+that can be used to change a role\*(Aqs password without exposing the cleartext password\&.
+.PP
+It is also possible to tie a session default to a specific database rather than to a role; see
+ALTER DATABASE (\fBALTER_DATABASE\fR(7))\&. If there is a conflict, database\-role\-specific settings override role\-specific ones, which in turn override database\-specific ones\&.
+.SH "EXAMPLES"
+.PP
+Change a role\*(Aqs password:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE davide WITH PASSWORD \*(Aqhu8jmn3\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Remove a role\*(Aqs password:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE davide WITH PASSWORD NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Change a password expiration date, specifying that the password should expire at midday on 4th May 2015 using the time zone which is one hour ahead of
+UTC:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE chris VALID UNTIL \*(AqMay 4 12:00:00 2015 +1\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Make a password valid forever:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE fred VALID UNTIL \*(Aqinfinity\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Give a role the ability to manage other roles and create new databases:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE miriam CREATEROLE CREATEDB;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Give a role a non\-default setting of the
+maintenance_work_mem
+parameter:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE worker_bee SET maintenance_work_mem = 100000;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Give a role a non\-default, database\-specific setting of the
+client_min_messages
+parameter:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROLE fred IN DATABASE devel SET client_min_messages = DEBUG;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBALTER ROLE\fR
+statement is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE ROLE (\fBCREATE_ROLE\fR(7)), DROP ROLE (\fBDROP_ROLE\fR(7)), ALTER DATABASE (\fBALTER_DATABASE\fR(7)), \fBSET\fR(7)
diff --git a/doc/src/sgml/man7/ALTER_ROUTINE.7 b/doc/src/sgml/man7/ALTER_ROUTINE.7
new file mode 100644
index 0000000..d00422c
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_ROUTINE.7
@@ -0,0 +1,105 @@
+'\" t
+.\" Title: ALTER ROUTINE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER ROUTINE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_ROUTINE \- change the definition of a routine
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER ROUTINE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ \fIaction\fR [ \&.\&.\&. ] [ RESTRICT ]
+ALTER ROUTINE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ RENAME TO \fInew_name\fR
+ALTER ROUTINE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER ROUTINE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ SET SCHEMA \fInew_schema\fR
+ALTER ROUTINE \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION \fIextension_name\fR
+
+where \fIaction\fR is one of:
+
+ IMMUTABLE | STABLE | VOLATILE
+ [ NOT ] LEAKPROOF
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ COST \fIexecution_cost\fR
+ ROWS \fIresult_rows\fR
+ SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | DEFAULT }
+ SET \fIconfiguration_parameter\fR FROM CURRENT
+ RESET \fIconfiguration_parameter\fR
+ RESET ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER ROUTINE\fR
+changes the definition of a routine, which can be an aggregate function, a normal function, or a procedure\&. See under
+ALTER AGGREGATE (\fBALTER_AGGREGATE\fR(7)),
+ALTER FUNCTION (\fBALTER_FUNCTION\fR(7)), and
+ALTER PROCEDURE (\fBALTER_PROCEDURE\fR(7))
+for the description of the parameters, more examples, and further details\&.
+.SH "EXAMPLES"
+.PP
+To rename the routine
+foo
+for type
+integer
+to
+foobar:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER ROUTINE foo(integer) RENAME TO foobar;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will work independent of whether
+foo
+is an aggregate, function, or procedure\&.
+.SH "COMPATIBILITY"
+.PP
+This statement is partially compatible with the
+\fBALTER ROUTINE\fR
+statement in the SQL standard\&. See under
+ALTER FUNCTION (\fBALTER_FUNCTION\fR(7))
+and
+ALTER PROCEDURE (\fBALTER_PROCEDURE\fR(7))
+for more details\&. Allowing routine names to refer to aggregate functions is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER AGGREGATE (\fBALTER_AGGREGATE\fR(7)), ALTER FUNCTION (\fBALTER_FUNCTION\fR(7)), ALTER PROCEDURE (\fBALTER_PROCEDURE\fR(7)), DROP ROUTINE (\fBDROP_ROUTINE\fR(7))
+.PP
+Note that there is no
+CREATE ROUTINE
+command\&.
diff --git a/doc/src/sgml/man7/ALTER_RULE.7 b/doc/src/sgml/man7/ALTER_RULE.7
new file mode 100644
index 0000000..0d9cd80
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_RULE.7
@@ -0,0 +1,80 @@
+'\" t
+.\" Title: ALTER RULE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER RULE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_RULE \- change the definition of a rule
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER RULE \fIname\fR ON \fItable_name\fR RENAME TO \fInew_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER RULE\fR
+changes properties of an existing rule\&. Currently, the only available action is to change the rule\*(Aqs name\&.
+.PP
+To use
+\fBALTER RULE\fR, you must own the table or view that the rule applies to\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing rule to alter\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table or view that the rule applies to\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the rule\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To rename an existing rule:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER RULE notify_all ON emp RENAME TO notify_me;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER RULE\fR
+is a
+PostgreSQL
+language extension, as is the entire query rewrite system\&.
+.SH "SEE ALSO"
+CREATE RULE (\fBCREATE_RULE\fR(7)), DROP RULE (\fBDROP_RULE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_SCHEMA.7 b/doc/src/sgml/man7/ALTER_SCHEMA.7
new file mode 100644
index 0000000..82ac9d2
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_SCHEMA.7
@@ -0,0 +1,72 @@
+'\" t
+.\" Title: ALTER SCHEMA
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER SCHEMA" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_SCHEMA \- change the definition of a schema
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER SCHEMA \fIname\fR RENAME TO \fInew_name\fR
+ALTER SCHEMA \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER SCHEMA\fR
+changes the definition of a schema\&.
+.PP
+You must own the schema to use
+\fBALTER SCHEMA\fR\&. To rename a schema you must also have the
+CREATE
+privilege for the database\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and you must have the
+CREATE
+privilege for the database\&. (Note that superusers have all these privileges automatically\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing schema\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the schema\&. The new name cannot begin with
+pg_, as such names are reserved for system schemas\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the schema\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER SCHEMA\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE SCHEMA (\fBCREATE_SCHEMA\fR(7)), DROP SCHEMA (\fBDROP_SCHEMA\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_SEQUENCE.7 b/doc/src/sgml/man7/ALTER_SEQUENCE.7
new file mode 100644
index 0000000..8301ca2
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_SEQUENCE.7
@@ -0,0 +1,282 @@
+'\" t
+.\" Title: ALTER SEQUENCE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER SEQUENCE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_SEQUENCE \- change the definition of a sequence generator
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER SEQUENCE [ IF EXISTS ] \fIname\fR
+ [ AS \fIdata_type\fR ]
+ [ INCREMENT [ BY ] \fIincrement\fR ]
+ [ MINVALUE \fIminvalue\fR | NO MINVALUE ] [ MAXVALUE \fImaxvalue\fR | NO MAXVALUE ]
+ [ START [ WITH ] \fIstart\fR ]
+ [ RESTART [ [ WITH ] \fIrestart\fR ] ]
+ [ CACHE \fIcache\fR ] [ [ NO ] CYCLE ]
+ [ OWNED BY { \fItable_name\fR\&.\fIcolumn_name\fR | NONE } ]
+ALTER SEQUENCE [ IF EXISTS ] \fIname\fR SET { LOGGED | UNLOGGED }
+ALTER SEQUENCE [ IF EXISTS ] \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SEQUENCE [ IF EXISTS ] \fIname\fR RENAME TO \fInew_name\fR
+ALTER SEQUENCE [ IF EXISTS ] \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER SEQUENCE\fR
+changes the parameters of an existing sequence generator\&. Any parameters not specifically set in the
+\fBALTER SEQUENCE\fR
+command retain their prior settings\&.
+.PP
+You must own the sequence to use
+\fBALTER SEQUENCE\fR\&. To change a sequence\*(Aqs schema, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the sequence\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the sequence\&. However, a superuser can alter ownership of any sequence anyway\&.)
+.SH "PARAMETERS"
+.PP
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of a sequence to be altered\&.
+.RE
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the sequence does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The optional clause
+AS \fIdata_type\fR
+changes the data type of the sequence\&. Valid types are
+smallint,
+integer, and
+bigint\&.
+.sp
+Changing the data type automatically changes the minimum and maximum values of the sequence if and only if the previous minimum and maximum values were the minimum or maximum value of the old data type (in other words, if the sequence had been created using
+NO MINVALUE
+or
+NO MAXVALUE, implicitly or explicitly)\&. Otherwise, the minimum and maximum values are preserved, unless new values are given as part of the same command\&. If the minimum and maximum values do not fit into the new data type, an error will be generated\&.
+.RE
+.PP
+\fIincrement\fR
+.RS 4
+The clause
+INCREMENT BY \fIincrement\fR
+is optional\&. A positive value will make an ascending sequence, a negative one a descending sequence\&. If unspecified, the old increment value will be maintained\&.
+.RE
+.PP
+\fIminvalue\fR
+.br
+NO MINVALUE
+.RS 4
+The optional clause
+MINVALUE \fIminvalue\fR
+determines the minimum value a sequence can generate\&. If
+NO MINVALUE
+is specified, the defaults of 1 and the minimum value of the data type for ascending and descending sequences, respectively, will be used\&. If neither option is specified, the current minimum value will be maintained\&.
+.RE
+.PP
+\fImaxvalue\fR
+.br
+NO MAXVALUE
+.RS 4
+The optional clause
+MAXVALUE \fImaxvalue\fR
+determines the maximum value for the sequence\&. If
+NO MAXVALUE
+is specified, the defaults of the maximum value of the data type and \-1 for ascending and descending sequences, respectively, will be used\&. If neither option is specified, the current maximum value will be maintained\&.
+.RE
+.PP
+\fIstart\fR
+.RS 4
+The optional clause
+START WITH \fIstart\fR
+changes the recorded start value of the sequence\&. This has no effect on the
+\fIcurrent\fR
+sequence value; it simply sets the value that future
+\fBALTER SEQUENCE RESTART\fR
+commands will use\&.
+.RE
+.PP
+\fIrestart\fR
+.RS 4
+The optional clause
+RESTART [ WITH \fIrestart\fR ]
+changes the current value of the sequence\&. This is similar to calling the
+\fBsetval\fR
+function with
+is_called
+=
+false: the specified value will be returned by the
+\fInext\fR
+call of
+\fBnextval\fR\&. Writing
+RESTART
+with no
+\fIrestart\fR
+value is equivalent to supplying the start value that was recorded by
+\fBCREATE SEQUENCE\fR
+or last set by
+\fBALTER SEQUENCE START WITH\fR\&.
+.sp
+In contrast to a
+\fBsetval\fR
+call, a
+RESTART
+operation on a sequence is transactional and blocks concurrent transactions from obtaining numbers from the same sequence\&. If that\*(Aqs not the desired mode of operation,
+\fBsetval\fR
+should be used\&.
+.RE
+.PP
+\fIcache\fR
+.RS 4
+The clause
+CACHE \fIcache\fR
+enables sequence numbers to be preallocated and stored in memory for faster access\&. The minimum value is 1 (only one value can be generated at a time, i\&.e\&., no cache)\&. If unspecified, the old cache value will be maintained\&.
+.RE
+.PP
+CYCLE
+.RS 4
+The optional
+CYCLE
+key word can be used to enable the sequence to wrap around when the
+\fImaxvalue\fR
+or
+\fIminvalue\fR
+has been reached by an ascending or descending sequence respectively\&. If the limit is reached, the next number generated will be the
+\fIminvalue\fR
+or
+\fImaxvalue\fR, respectively\&.
+.RE
+.PP
+NO CYCLE
+.RS 4
+If the optional
+NO CYCLE
+key word is specified, any calls to
+\fBnextval\fR
+after the sequence has reached its maximum value will return an error\&. If neither
+CYCLE
+or
+NO CYCLE
+are specified, the old cycle behavior will be maintained\&.
+.RE
+.PP
+SET { LOGGED | UNLOGGED }
+.RS 4
+This form changes the sequence from unlogged to logged or vice\-versa (see
+CREATE SEQUENCE (\fBCREATE_SEQUENCE\fR(7)))\&. It cannot be applied to a temporary sequence\&.
+.RE
+.PP
+OWNED BY \fItable_name\fR\&.\fIcolumn_name\fR
+.br
+OWNED BY NONE
+.RS 4
+The
+OWNED BY
+option causes the sequence to be associated with a specific table column, such that if that column (or its whole table) is dropped, the sequence will be automatically dropped as well\&. If specified, this association replaces any previously specified association for the sequence\&. The specified table must have the same owner and be in the same schema as the sequence\&. Specifying
+OWNED BY NONE
+removes any existing association, making the sequence
+\(lqfree\-standing\(rq\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the sequence\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the sequence\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the sequence\&.
+.RE
+.SH "NOTES"
+.PP
+\fBALTER SEQUENCE\fR
+will not immediately affect
+\fBnextval\fR
+results in backends, other than the current one, that have preallocated (cached) sequence values\&. They will use up all cached values prior to noticing the changed sequence generation parameters\&. The current backend will be affected immediately\&.
+.PP
+\fBALTER SEQUENCE\fR
+does not affect the
+\fBcurrval\fR
+status for the sequence\&. (Before
+PostgreSQL
+8\&.3, it sometimes did\&.)
+.PP
+\fBALTER SEQUENCE\fR
+blocks concurrent
+\fBnextval\fR,
+\fBcurrval\fR,
+\fBlastval\fR, and
+\fBsetval\fR
+calls\&.
+.PP
+For historical reasons,
+\fBALTER TABLE\fR
+can be used with sequences too; but the only variants of
+\fBALTER TABLE\fR
+that are allowed with sequences are equivalent to the forms shown above\&.
+.SH "EXAMPLES"
+.PP
+Restart a sequence called
+serial, at 105:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SEQUENCE serial RESTART WITH 105;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER SEQUENCE\fR
+conforms to the
+SQL
+standard, except for the
+AS,
+START WITH,
+OWNED BY,
+OWNER TO,
+RENAME TO, and
+SET SCHEMA
+clauses, which are
+PostgreSQL
+extensions\&.
+.SH "SEE ALSO"
+CREATE SEQUENCE (\fBCREATE_SEQUENCE\fR(7)), DROP SEQUENCE (\fBDROP_SEQUENCE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_SERVER.7 b/doc/src/sgml/man7/ALTER_SERVER.7
new file mode 100644
index 0000000..4b1343c
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_SERVER.7
@@ -0,0 +1,118 @@
+'\" t
+.\" Title: ALTER SERVER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER SERVER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_SERVER \- change the definition of a foreign server
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER SERVER \fIname\fR [ VERSION \*(Aq\fInew_version\fR\*(Aq ]
+ [ OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ] ) ]
+ALTER SERVER \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SERVER \fIname\fR RENAME TO \fInew_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER SERVER\fR
+changes the definition of a foreign server\&. The first form changes the server version string or the generic options of the server (at least one clause is required)\&. The second form changes the owner of the server\&.
+.PP
+To alter the server you must be the owner of the server\&. Additionally to alter the owner, you must own the server and also be a direct or indirect member of the new owning role, and you must have
+USAGE
+privilege on the server\*(Aqs foreign\-data wrapper\&. (Note that superusers satisfy all these criteria automatically\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing server\&.
+.RE
+.PP
+\fInew_version\fR
+.RS 4
+New server version\&.
+.RE
+.PP
+OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ] )
+.RS 4
+Change options for the server\&.
+ADD,
+SET, and
+DROP
+specify the action to be performed\&.
+ADD
+is assumed if no operation is explicitly specified\&. Option names must be unique; names and values are also validated using the server\*(Aqs foreign\-data wrapper library\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the foreign server\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the foreign server\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Alter server
+foo, add connection options:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SERVER foo OPTIONS (host \*(Aqfoo\*(Aq, dbname \*(Aqfoodb\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Alter server
+foo, change version, change
+host
+option:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SERVER foo VERSION \*(Aq8\&.4\*(Aq OPTIONS (SET host \*(Aqbaz\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER SERVER\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&. The
+OWNER TO
+and
+RENAME
+forms are PostgreSQL extensions\&.
+.SH "SEE ALSO"
+CREATE SERVER (\fBCREATE_SERVER\fR(7)), DROP SERVER (\fBDROP_SERVER\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_STATISTICS.7 b/doc/src/sgml/man7/ALTER_STATISTICS.7
new file mode 100644
index 0000000..142caa1
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_STATISTICS.7
@@ -0,0 +1,91 @@
+'\" t
+.\" Title: ALTER STATISTICS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER STATISTICS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_STATISTICS \- change the definition of an extended statistics object
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER STATISTICS \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER STATISTICS \fIname\fR RENAME TO \fInew_name\fR
+ALTER STATISTICS \fIname\fR SET SCHEMA \fInew_schema\fR
+ALTER STATISTICS \fIname\fR SET STATISTICS \fInew_target\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER STATISTICS\fR
+changes the parameters of an existing extended statistics object\&. Any parameters not specifically set in the
+\fBALTER STATISTICS\fR
+command retain their prior settings\&.
+.PP
+You must own the statistics object to use
+\fBALTER STATISTICS\fR\&. To change a statistics object\*(Aqs schema, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the statistics object\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the statistics object\&. However, a superuser can alter ownership of any statistics object anyway\&.)
+.SH "PARAMETERS"
+.PP
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the statistics object to be altered\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the statistics object\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the statistics object\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the statistics object\&.
+.RE
+.PP
+\fInew_target\fR
+.RS 4
+The statistic\-gathering target for this statistics object for subsequent
+\fBANALYZE\fR
+operations\&. The target can be set in the range 0 to 10000; alternatively, set it to \-1 to revert to using the maximum of the statistics target of the referenced columns, if set, or the system default statistics target (default_statistics_target)\&. For more information on the use of statistics by the
+PostgreSQL
+query planner, refer to
+Section\ \&14.2\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER STATISTICS\fR
+command in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE STATISTICS (\fBCREATE_STATISTICS\fR(7)), DROP STATISTICS (\fBDROP_STATISTICS\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_SUBSCRIPTION.7 b/doc/src/sgml/man7/ALTER_SUBSCRIPTION.7
new file mode 100644
index 0000000..2900517
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_SUBSCRIPTION.7
@@ -0,0 +1,235 @@
+'\" t
+.\" Title: ALTER SUBSCRIPTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER SUBSCRIPTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_SUBSCRIPTION \- change the definition of a subscription
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER SUBSCRIPTION \fIname\fR CONNECTION \*(Aq\fIconninfo\fR\*(Aq
+ALTER SUBSCRIPTION \fIname\fR SET PUBLICATION \fIpublication_name\fR [, \&.\&.\&.] [ WITH ( \fIpublication_option\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+ALTER SUBSCRIPTION \fIname\fR ADD PUBLICATION \fIpublication_name\fR [, \&.\&.\&.] [ WITH ( \fIpublication_option\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+ALTER SUBSCRIPTION \fIname\fR DROP PUBLICATION \fIpublication_name\fR [, \&.\&.\&.] [ WITH ( \fIpublication_option\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+ALTER SUBSCRIPTION \fIname\fR REFRESH PUBLICATION [ WITH ( \fIrefresh_option\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+ALTER SUBSCRIPTION \fIname\fR ENABLE
+ALTER SUBSCRIPTION \fIname\fR DISABLE
+ALTER SUBSCRIPTION \fIname\fR SET ( \fIsubscription_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+ALTER SUBSCRIPTION \fIname\fR SKIP ( \fIskip_option\fR = \fIvalue\fR )
+ALTER SUBSCRIPTION \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SUBSCRIPTION \fIname\fR RENAME TO \fInew_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER SUBSCRIPTION\fR
+can change most of the subscription properties that can be specified in
+CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7))\&.
+.PP
+You must own the subscription to use
+\fBALTER SUBSCRIPTION\fR\&. To alter the owner, you must also be a direct or indirect member of the new owning role\&. The new owner has to be a superuser\&. (Currently, all subscription owners must be superusers, so the owner checks will be bypassed in practice\&. But this might change in the future\&.)
+.PP
+When refreshing a publication we remove the relations that are no longer part of the publication and we also remove the table synchronization slots if there are any\&. It is necessary to remove these slots so that the resources allocated for the subscription on the remote host are released\&. If due to network breakdown or some other error,
+PostgreSQL
+is unable to remove the slots, an error will be reported\&. To proceed in this situation, the user either needs to retry the operation or disassociate the slot from the subscription and drop the subscription as explained in
+DROP SUBSCRIPTION (\fBDROP_SUBSCRIPTION\fR(7))\&.
+.PP
+Commands
+\fBALTER SUBSCRIPTION \&.\&.\&. REFRESH PUBLICATION\fR
+and
+\fBALTER SUBSCRIPTION \&.\&.\&. {SET|ADD|DROP} PUBLICATION \&.\&.\&.\fR
+with
+refresh
+option as
+true
+cannot be executed inside a transaction block\&. These commands also cannot be executed when the subscription has
+two_phase
+commit enabled, unless
+copy_data
+is
+false\&. See column
+subtwophasestate
+of
+pg_subscription
+to know the actual two\-phase state\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of a subscription whose properties are to be altered\&.
+.RE
+.PP
+CONNECTION \*(Aq\fIconninfo\fR\*(Aq
+.RS 4
+This clause replaces the connection string originally set by
+CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7))\&. See there for more information\&.
+.RE
+.PP
+SET PUBLICATION \fIpublication_name\fR
+.br
+ADD PUBLICATION \fIpublication_name\fR
+.br
+DROP PUBLICATION \fIpublication_name\fR
+.RS 4
+These forms change the list of subscribed publications\&.
+SET
+replaces the entire list of publications with a new list,
+ADD
+adds additional publications to the list of publications, and
+DROP
+removes the publications from the list of publications\&. We allow non\-existent publications to be specified in
+ADD
+and
+SET
+variants so that users can add those later\&. See
+CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7))
+for more information\&. By default, this command will also act like
+REFRESH PUBLICATION\&.
+.sp
+\fIpublication_option\fR
+specifies additional options for this operation\&. The supported options are:
+.PP
+refresh (boolean)
+.RS 4
+When false, the command will not try to refresh table information\&.
+REFRESH PUBLICATION
+should then be executed separately\&. The default is
+true\&.
+.RE
+.sp
+Additionally, the options described under
+REFRESH PUBLICATION
+may be specified, to control the implicit refresh operation\&.
+.RE
+.PP
+REFRESH PUBLICATION
+.RS 4
+Fetch missing table information from publisher\&. This will start replication of tables that were added to the subscribed\-to publications since
+\fBCREATE SUBSCRIPTION\fR
+or the last invocation of
+\fBREFRESH PUBLICATION\fR\&.
+.sp
+\fIrefresh_option\fR
+specifies additional options for the refresh operation\&. The supported options are:
+.PP
+copy_data (boolean)
+.RS 4
+Specifies whether to copy pre\-existing data in the publications that are being subscribed to when the replication starts\&. The default is
+true\&.
+.sp
+Previously subscribed tables are not copied, even if a table\*(Aqs row filter
+WHERE
+clause has since been modified\&.
+.RE
+.RE
+.PP
+ENABLE
+.RS 4
+Enables a previously disabled subscription, starting the logical replication worker at the end of the transaction\&.
+.RE
+.PP
+DISABLE
+.RS 4
+Disables a running subscription, stopping the logical replication worker at the end of the transaction\&.
+.RE
+.PP
+SET ( \fIsubscription_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause alters parameters originally set by
+CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7))\&. See there for more information\&. The parameters that can be altered are
+slot_name,
+synchronous_commit,
+binary,
+streaming, and
+disable_on_error\&.
+.RE
+.PP
+SKIP ( \fIskip_option\fR = \fIvalue\fR )
+.RS 4
+Skips applying all changes of the remote transaction\&. If incoming data violates any constraints, logical replication will stop until it is resolved\&. By using the
+\fBALTER SUBSCRIPTION \&.\&.\&. SKIP\fR
+command, the logical replication worker skips all data modification changes within the transaction\&. This option has no effect on the transactions that are already prepared by enabling
+two_phase
+on subscriber\&. After the logical replication worker successfully skips the transaction or finishes a transaction, the LSN (stored in
+pg_subscription\&.subskiplsn) is cleared\&. See
+Section\ \&31.5
+for the details of logical replication conflicts\&. Using this command requires superuser privilege\&.
+.sp
+\fIskip_option\fR
+specifies options for this operation\&. The supported option is:
+.PP
+lsn (pg_lsn)
+.RS 4
+Specifies the finish LSN of the remote transaction whose changes are to be skipped by the logical replication worker\&. The finish LSN is the LSN at which the transaction is either committed or prepared\&. Skipping individual subtransactions is not supported\&. Setting
+NONE
+resets the LSN\&.
+.RE
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the subscription\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the subscription\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Change the publication subscribed by a subscription to
+insert_only:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Disable (stop) the subscription:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SUBSCRIPTION mysub DISABLE;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER SUBSCRIPTION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7)), DROP SUBSCRIPTION (\fBDROP_SUBSCRIPTION\fR(7)), CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7)), ALTER PUBLICATION (\fBALTER_PUBLICATION\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_SYSTEM.7 b/doc/src/sgml/man7/ALTER_SYSTEM.7
new file mode 100644
index 0000000..0e7c77b
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_SYSTEM.7
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: ALTER SYSTEM
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER SYSTEM" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_SYSTEM \- change a server configuration parameter
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER SYSTEM SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | \*(Aq\fIvalue\fR\*(Aq | DEFAULT }
+
+ALTER SYSTEM RESET \fIconfiguration_parameter\fR
+ALTER SYSTEM RESET ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER SYSTEM\fR
+is used for changing server configuration parameters across the entire database cluster\&. It can be more convenient than the traditional method of manually editing the
+postgresql\&.conf
+file\&.
+\fBALTER SYSTEM\fR
+writes the given parameter setting to the
+postgresql\&.auto\&.conf
+file, which is read in addition to
+postgresql\&.conf\&. Setting a parameter to
+DEFAULT, or using the
+\fBRESET\fR
+variant, removes that configuration entry from the
+postgresql\&.auto\&.conf
+file\&. Use
+RESET ALL
+to remove all such configuration entries\&.
+.PP
+Values set with
+\fBALTER SYSTEM\fR
+will be effective after the next server configuration reload, or after the next server restart in the case of parameters that can only be changed at server start\&. A server configuration reload can be commanded by calling the SQL function
+\fBpg_reload_conf()\fR, running
+pg_ctl reload, or sending a
+SIGHUP
+signal to the main server process\&.
+.PP
+Only superusers and users granted
+ALTER SYSTEM
+privilege on a parameter can change it using
+\fBALTER SYSTEM\fR\&. Also, since this command acts directly on the file system and cannot be rolled back, it is not allowed inside a transaction block or function\&.
+.SH "PARAMETERS"
+.PP
+\fIconfiguration_parameter\fR
+.RS 4
+Name of a settable configuration parameter\&. Available parameters are documented in
+Chapter\ \&20\&.
+.RE
+.PP
+\fIvalue\fR
+.RS 4
+New value of the parameter\&. Values can be specified as string constants, identifiers, numbers, or comma\-separated lists of these, as appropriate for the particular parameter\&.
+DEFAULT
+can be written to specify removing the parameter and its value from
+postgresql\&.auto\&.conf\&.
+.RE
+.SH "NOTES"
+.PP
+This command can\*(Aqt be used to set
+data_directory, nor parameters that are not allowed in
+postgresql\&.conf
+(e\&.g\&.,
+preset options)\&.
+.PP
+See
+Section\ \&20.1
+for other ways to set the parameters\&.
+.SH "EXAMPLES"
+.PP
+Set the
+wal_level:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SYSTEM SET wal_level = replica;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Undo that, restoring whatever setting was effective in
+postgresql\&.conf:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER SYSTEM RESET wal_level;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBALTER SYSTEM\fR
+statement is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+\fBSET\fR(7), \fBSHOW\fR(7)
diff --git a/doc/src/sgml/man7/ALTER_TABLE.7 b/doc/src/sgml/man7/ALTER_TABLE.7
new file mode 100644
index 0000000..bc4aa3b
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TABLE.7
@@ -0,0 +1,1467 @@
+'\" t
+.\" Title: ALTER TABLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TABLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TABLE \- change the definition of a table
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TABLE [ IF EXISTS ] [ ONLY ] \fIname\fR [ * ]
+ \fIaction\fR [, \&.\&.\&. ]
+ALTER TABLE [ IF EXISTS ] [ ONLY ] \fIname\fR [ * ]
+ RENAME [ COLUMN ] \fIcolumn_name\fR TO \fInew_column_name\fR
+ALTER TABLE [ IF EXISTS ] [ ONLY ] \fIname\fR [ * ]
+ RENAME CONSTRAINT \fIconstraint_name\fR TO \fInew_constraint_name\fR
+ALTER TABLE [ IF EXISTS ] \fIname\fR
+ RENAME TO \fInew_name\fR
+ALTER TABLE [ IF EXISTS ] \fIname\fR
+ SET SCHEMA \fInew_schema\fR
+ALTER TABLE ALL IN TABLESPACE \fIname\fR [ OWNED BY \fIrole_name\fR [, \&.\&.\&. ] ]
+ SET TABLESPACE \fInew_tablespace\fR [ NOWAIT ]
+ALTER TABLE [ IF EXISTS ] \fIname\fR
+ ATTACH PARTITION \fIpartition_name\fR { FOR VALUES \fIpartition_bound_spec\fR | DEFAULT }
+ALTER TABLE [ IF EXISTS ] \fIname\fR
+ DETACH PARTITION \fIpartition_name\fR [ CONCURRENTLY | FINALIZE ]
+
+where \fIaction\fR is one of:
+
+ ADD [ COLUMN ] [ IF NOT EXISTS ] \fIcolumn_name\fR \fIdata_type\fR [ COLLATE \fIcollation\fR ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ DROP [ COLUMN ] [ IF EXISTS ] \fIcolumn_name\fR [ RESTRICT | CASCADE ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR [ SET DATA ] TYPE \fIdata_type\fR [ COLLATE \fIcollation\fR ] [ USING \fIexpression\fR ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET DEFAULT \fIexpression\fR
+ ALTER [ COLUMN ] \fIcolumn_name\fR DROP DEFAULT
+ ALTER [ COLUMN ] \fIcolumn_name\fR { SET | DROP } NOT NULL
+ ALTER [ COLUMN ] \fIcolumn_name\fR DROP EXPRESSION [ IF EXISTS ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( \fIsequence_options\fR ) ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR { SET GENERATED { ALWAYS | BY DEFAULT } | SET \fIsequence_option\fR | RESTART [ [ WITH ] \fIrestart\fR ] } [\&.\&.\&.]
+ ALTER [ COLUMN ] \fIcolumn_name\fR DROP IDENTITY [ IF EXISTS ]
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET STATISTICS \fIinteger\fR
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET ( \fIattribute_option\fR = \fIvalue\fR [, \&.\&.\&. ] )
+ ALTER [ COLUMN ] \fIcolumn_name\fR RESET ( \fIattribute_option\fR [, \&.\&.\&. ] )
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] \fIcolumn_name\fR SET COMPRESSION \fIcompression_method\fR
+ ADD \fItable_constraint\fR [ NOT VALID ]
+ ADD \fItable_constraint_using_index\fR
+ ALTER CONSTRAINT \fIconstraint_name\fR [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+ VALIDATE CONSTRAINT \fIconstraint_name\fR
+ DROP CONSTRAINT [ IF EXISTS ] \fIconstraint_name\fR [ RESTRICT | CASCADE ]
+ DISABLE TRIGGER [ \fItrigger_name\fR | ALL | USER ]
+ ENABLE TRIGGER [ \fItrigger_name\fR | ALL | USER ]
+ ENABLE REPLICA TRIGGER \fItrigger_name\fR
+ ENABLE ALWAYS TRIGGER \fItrigger_name\fR
+ DISABLE RULE \fIrewrite_rule_name\fR
+ ENABLE RULE \fIrewrite_rule_name\fR
+ ENABLE REPLICA RULE \fIrewrite_rule_name\fR
+ ENABLE ALWAYS RULE \fIrewrite_rule_name\fR
+ DISABLE ROW LEVEL SECURITY
+ ENABLE ROW LEVEL SECURITY
+ FORCE ROW LEVEL SECURITY
+ NO FORCE ROW LEVEL SECURITY
+ CLUSTER ON \fIindex_name\fR
+ SET WITHOUT CLUSTER
+ SET WITHOUT OIDS
+ SET ACCESS METHOD \fInew_access_method\fR
+ SET TABLESPACE \fInew_tablespace\fR
+ SET { LOGGED | UNLOGGED }
+ SET ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+ RESET ( \fIstorage_parameter\fR [, \&.\&.\&. ] )
+ INHERIT \fIparent_table\fR
+ NO INHERIT \fIparent_table\fR
+ OF \fItype_name\fR
+ NOT OF
+ OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ REPLICA IDENTITY { DEFAULT | USING INDEX \fIindex_name\fR | FULL | NOTHING }
+
+and \fIpartition_bound_spec\fR is:
+
+IN ( \fIpartition_bound_expr\fR [, \&.\&.\&.] ) |
+FROM ( { \fIpartition_bound_expr\fR | MINVALUE | MAXVALUE } [, \&.\&.\&.] )
+ TO ( { \fIpartition_bound_expr\fR | MINVALUE | MAXVALUE } [, \&.\&.\&.] ) |
+WITH ( MODULUS \fInumeric_literal\fR, REMAINDER \fInumeric_literal\fR )
+
+and \fIcolumn_constraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+{ NOT NULL |
+ NULL |
+ CHECK ( \fIexpression\fR ) [ NO INHERIT ] |
+ DEFAULT \fIdefault_expr\fR |
+ GENERATED ALWAYS AS ( \fIgeneration_expr\fR ) STORED |
+ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( \fIsequence_options\fR ) ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] \fIindex_parameters\fR |
+ PRIMARY KEY \fIindex_parameters\fR |
+ REFERENCES \fIreftable\fR [ ( \fIrefcolumn\fR ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+ [ ON DELETE \fIreferential_action\fR ] [ ON UPDATE \fIreferential_action\fR ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+and \fItable_constraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+{ CHECK ( \fIexpression\fR ) [ NO INHERIT ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] ( \fIcolumn_name\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR |
+ PRIMARY KEY ( \fIcolumn_name\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR |
+ EXCLUDE [ USING \fIindex_method\fR ] ( \fIexclude_element\fR WITH \fIoperator\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR [ WHERE ( \fIpredicate\fR ) ] |
+ FOREIGN KEY ( \fIcolumn_name\fR [, \&.\&.\&. ] ) REFERENCES \fIreftable\fR [ ( \fIrefcolumn\fR [, \&.\&.\&. ] ) ]
+ [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE \fIreferential_action\fR ] [ ON UPDATE \fIreferential_action\fR ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+and \fItable_constraint_using_index\fR is:
+
+ [ CONSTRAINT \fIconstraint_name\fR ]
+ { UNIQUE | PRIMARY KEY } USING INDEX \fIindex_name\fR
+ [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+\fIindex_parameters\fR in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:
+
+[ INCLUDE ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ]
+[ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+[ USING INDEX TABLESPACE \fItablespace_name\fR ]
+
+\fIexclude_element\fR in an EXCLUDE constraint is:
+
+{ \fIcolumn_name\fR | ( \fIexpression\fR ) } [ \fIopclass\fR ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
+
+\fIreferential_action\fR in a FOREIGN KEY/REFERENCES constraint is:
+
+{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ] | SET DEFAULT [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ] }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TABLE\fR
+changes the definition of an existing table\&. There are several subforms described below\&. Note that the lock level required may differ for each subform\&. An
+ACCESS EXCLUSIVE
+lock is acquired unless explicitly noted\&. When multiple subcommands are given, the lock acquired will be the strictest one required by any subcommand\&.
+.PP
+ADD COLUMN [ IF NOT EXISTS ]
+.RS 4
+This form adds a new column to the table, using the same syntax as
+\fBCREATE TABLE\fR\&. If
+IF NOT EXISTS
+is specified and a column already exists with this name, no error is thrown\&.
+.RE
+.PP
+DROP COLUMN [ IF EXISTS ]
+.RS 4
+This form drops a column from a table\&. Indexes and table constraints involving the column will be automatically dropped as well\&. Multivariate statistics referencing the dropped column will also be removed if the removal of the column would cause the statistics to contain data for only a single column\&. You will need to say
+CASCADE
+if anything outside the table depends on the column, for example, foreign key references or views\&. If
+IF EXISTS
+is specified and the column does not exist, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+SET DATA TYPE
+.RS 4
+This form changes the type of a column of a table\&. Indexes and simple table constraints involving the column will be automatically converted to use the new column type by reparsing the originally supplied expression\&. The optional
+COLLATE
+clause specifies a collation for the new column; if omitted, the collation is the default for the new column type\&. The optional
+USING
+clause specifies how to compute the new column value from the old; if omitted, the default conversion is the same as an assignment cast from old data type to new\&. A
+USING
+clause must be provided if there is no implicit or assignment cast from old to new type\&.
+.sp
+When this form is used, the column\*(Aqs statistics are removed, so running
+\fBANALYZE\fR
+on the table afterwards is recommended\&.
+.RE
+.PP
+SET/DROP DEFAULT
+.RS 4
+These forms set or remove the default value for a column (where removal is equivalent to setting the default value to NULL)\&. The new default value will only apply in subsequent
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+commands; it does not cause rows already in the table to change\&.
+.RE
+.PP
+SET/DROP NOT NULL
+.RS 4
+These forms change whether a column is marked to allow null values or to reject null values\&.
+.sp
+SET NOT NULL
+may only be applied to a column provided none of the records in the table contain a
+NULL
+value for the column\&. Ordinarily this is checked during the
+ALTER TABLE
+by scanning the entire table; however, if a valid
+CHECK
+constraint is found which proves no
+NULL
+can exist, then the table scan is skipped\&.
+.sp
+If this table is a partition, one cannot perform
+DROP NOT NULL
+on a column if it is marked
+NOT NULL
+in the parent table\&. To drop the
+NOT NULL
+constraint from all the partitions, perform
+DROP NOT NULL
+on the parent table\&. Even if there is no
+NOT NULL
+constraint on the parent, such a constraint can still be added to individual partitions, if desired; that is, the children can disallow nulls even if the parent allows them, but not the other way around\&.
+.RE
+.PP
+DROP EXPRESSION [ IF EXISTS ]
+.RS 4
+This form turns a stored generated column into a normal base column\&. Existing data in the columns is retained, but future changes will no longer apply the generation expression\&.
+.sp
+If
+DROP EXPRESSION IF EXISTS
+is specified and the column is not a stored generated column, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
+.br
+SET GENERATED { ALWAYS | BY DEFAULT }
+.br
+DROP IDENTITY [ IF EXISTS ]
+.RS 4
+These forms change whether a column is an identity column or change the generation attribute of an existing identity column\&. See
+\fBCREATE TABLE\fR
+for details\&. Like
+SET DEFAULT, these forms only affect the behavior of subsequent
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+commands; they do not cause rows already in the table to change\&.
+.sp
+If
+DROP IDENTITY IF EXISTS
+is specified and the column is not an identity column, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+SET \fIsequence_option\fR
+.br
+RESTART
+.RS 4
+These forms alter the sequence that underlies an existing identity column\&.
+\fIsequence_option\fR
+is an option supported by
+\fBALTER SEQUENCE\fR
+such as
+INCREMENT BY\&.
+.RE
+.PP
+SET STATISTICS
+.RS 4
+This form sets the per\-column statistics\-gathering target for subsequent
+\fBANALYZE\fR
+operations\&. The target can be set in the range 0 to 10000; alternatively, set it to \-1 to revert to using the system default statistics target (default_statistics_target)\&. For more information on the use of statistics by the
+PostgreSQL
+query planner, refer to
+Section\ \&14.2\&.
+.sp
+SET STATISTICS
+acquires a
+SHARE UPDATE EXCLUSIVE
+lock\&.
+.RE
+.PP
+SET ( \fIattribute_option\fR = \fIvalue\fR [, \&.\&.\&. ] )
+.br
+RESET ( \fIattribute_option\fR [, \&.\&.\&. ] )
+.RS 4
+This form sets or resets per\-attribute options\&. Currently, the only defined per\-attribute options are
+n_distinct
+and
+n_distinct_inherited, which override the number\-of\-distinct\-values estimates made by subsequent
+\fBANALYZE\fR
+operations\&.
+n_distinct
+affects the statistics for the table itself, while
+n_distinct_inherited
+affects the statistics gathered for the table plus its inheritance children\&. When set to a positive value,
+\fBANALYZE\fR
+will assume that the column contains exactly the specified number of distinct nonnull values\&. When set to a negative value, which must be greater than or equal to \-1,
+\fBANALYZE\fR
+will assume that the number of distinct nonnull values in the column is linear in the size of the table; the exact count is to be computed by multiplying the estimated table size by the absolute value of the given number\&. For example, a value of \-1 implies that all values in the column are distinct, while a value of \-0\&.5 implies that each value appears twice on the average\&. This can be useful when the size of the table changes over time, since the multiplication by the number of rows in the table is not performed until query planning time\&. Specify a value of 0 to revert to estimating the number of distinct values normally\&. For more information on the use of statistics by the
+PostgreSQL
+query planner, refer to
+Section\ \&14.2\&.
+.sp
+Changing per\-attribute options acquires a
+SHARE UPDATE EXCLUSIVE
+lock\&.
+.RE
+.PP
+SET STORAGE
+.RS 4
+This form sets the storage mode for a column\&. This controls whether this column is held inline or in a secondary
+TOAST
+table, and whether the data should be compressed or not\&.
+PLAIN
+must be used for fixed\-length values such as
+integer
+and is inline, uncompressed\&.
+MAIN
+is for inline, compressible data\&.
+EXTERNAL
+is for external, uncompressed data, and
+EXTENDED
+is for external, compressed data\&.
+EXTENDED
+is the default for most data types that support non\-PLAIN
+storage\&. Use of
+EXTERNAL
+will make substring operations on very large
+text
+and
+bytea
+values run faster, at the penalty of increased storage space\&. Note that
+SET STORAGE
+doesn\*(Aqt itself change anything in the table, it just sets the strategy to be pursued during future table updates\&. See
+Section\ \&73.2
+for more information\&.
+.RE
+.PP
+SET COMPRESSION \fIcompression_method\fR
+.RS 4
+This form sets the compression method for a column, determining how values inserted in future will be compressed (if the storage mode permits compression at all)\&. This does not cause the table to be rewritten, so existing data may still be compressed with other compression methods\&. If the table is restored with
+pg_restore, then all values are rewritten with the configured compression method\&. However, when data is inserted from another relation (for example, by
+\fBINSERT \&.\&.\&. SELECT\fR), values from the source table are not necessarily detoasted, so any previously compressed data may retain its existing compression method, rather than being recompressed with the compression method of the target column\&. The supported compression methods are
+pglz
+and
+lz4\&. (lz4
+is available only if
+\fB\-\-with\-lz4\fR
+was used when building
+PostgreSQL\&.) In addition,
+\fIcompression_method\fR
+can be
+default, which selects the default behavior of consulting the
+default_toast_compression
+setting at the time of data insertion to determine the method to use\&.
+.RE
+.PP
+ADD \fItable_constraint\fR [ NOT VALID ]
+.RS 4
+This form adds a new constraint to a table using the same constraint syntax as
+\fBCREATE TABLE\fR, plus the option
+NOT VALID, which is currently only allowed for foreign key and CHECK constraints\&.
+.sp
+Normally, this form will cause a scan of the table to verify that all existing rows in the table satisfy the new constraint\&. But if the
+NOT VALID
+option is used, this potentially\-lengthy scan is skipped\&. The constraint will still be enforced against subsequent inserts or updates (that is, they\*(Aqll fail unless there is a matching row in the referenced table, in the case of foreign keys, or they\*(Aqll fail unless the new row matches the specified check condition)\&. But the database will not assume that the constraint holds for all rows in the table, until it is validated by using the
+VALIDATE CONSTRAINT
+option\&. See
+Notes
+below for more information about using the
+NOT VALID
+option\&.
+.sp
+Although most forms of
+ADD \fItable_constraint\fR
+require an
+ACCESS EXCLUSIVE
+lock,
+ADD FOREIGN KEY
+requires only a
+SHARE ROW EXCLUSIVE
+lock\&. Note that
+ADD FOREIGN KEY
+also acquires a
+SHARE ROW EXCLUSIVE
+lock on the referenced table, in addition to the lock on the table on which the constraint is declared\&.
+.sp
+Additional restrictions apply when unique or primary key constraints are added to partitioned tables; see
+\fBCREATE TABLE\fR\&. Also, foreign key constraints on partitioned tables may not be declared
+NOT VALID
+at present\&.
+.RE
+.PP
+ADD \fItable_constraint_using_index\fR
+.RS 4
+This form adds a new
+PRIMARY KEY
+or
+UNIQUE
+constraint to a table based on an existing unique index\&. All the columns of the index will be included in the constraint\&.
+.sp
+The index cannot have expression columns nor be a partial index\&. Also, it must be a b\-tree index with default sort ordering\&. These restrictions ensure that the index is equivalent to one that would be built by a regular
+ADD PRIMARY KEY
+or
+ADD UNIQUE
+command\&.
+.sp
+If
+PRIMARY KEY
+is specified, and the index\*(Aqs columns are not already marked
+NOT NULL, then this command will attempt to do
+ALTER COLUMN SET NOT NULL
+against each such column\&. That requires a full table scan to verify the column(s) contain no nulls\&. In all other cases, this is a fast operation\&.
+.sp
+If a constraint name is provided then the index will be renamed to match the constraint name\&. Otherwise the constraint will be named the same as the index\&.
+.sp
+After this command is executed, the index is
+\(lqowned\(rq
+by the constraint, in the same way as if the index had been built by a regular
+ADD PRIMARY KEY
+or
+ADD UNIQUE
+command\&. In particular, dropping the constraint will make the index disappear too\&.
+.sp
+This form is not currently supported on partitioned tables\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+Adding a constraint using an existing index can be helpful in situations where a new constraint needs to be added without blocking table updates for a long time\&. To do that, create the index using
+\fBCREATE INDEX CONCURRENTLY\fR, and then install it as an official constraint using this syntax\&. See the example below\&.
+.sp .5v
+.RE
+.RE
+.PP
+ALTER CONSTRAINT
+.RS 4
+This form alters the attributes of a constraint that was previously created\&. Currently only foreign key constraints may be altered\&.
+.RE
+.PP
+VALIDATE CONSTRAINT
+.RS 4
+This form validates a foreign key or check constraint that was previously created as
+NOT VALID, by scanning the table to ensure there are no rows for which the constraint is not satisfied\&. Nothing happens if the constraint is already marked valid\&. (See
+Notes
+below for an explanation of the usefulness of this command\&.)
+.sp
+This command acquires a
+SHARE UPDATE EXCLUSIVE
+lock\&.
+.RE
+.PP
+DROP CONSTRAINT [ IF EXISTS ]
+.RS 4
+This form drops the specified constraint on a table, along with any index underlying the constraint\&. If
+IF EXISTS
+is specified and the constraint does not exist, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER
+.RS 4
+These forms configure the firing of trigger(s) belonging to the table\&. A disabled trigger is still known to the system, but is not executed when its triggering event occurs\&. (For a deferred trigger, the enable status is checked when the event occurs, not when the trigger function is actually executed\&.) One can disable or enable a single trigger specified by name, or all triggers on the table, or only user triggers (this option excludes internally generated constraint triggers, such as those that are used to implement foreign key constraints or deferrable uniqueness and exclusion constraints)\&. Disabling or enabling internally generated constraint triggers requires superuser privileges; it should be done with caution since of course the integrity of the constraint cannot be guaranteed if the triggers are not executed\&.
+.sp
+The trigger firing mechanism is also affected by the configuration variable
+session_replication_role\&. Simply enabled triggers (the default) will fire when the replication role is
+\(lqorigin\(rq
+(the default) or
+\(lqlocal\(rq\&. Triggers configured as
+ENABLE REPLICA
+will only fire if the session is in
+\(lqreplica\(rq
+mode, and triggers configured as
+ENABLE ALWAYS
+will fire regardless of the current replication role\&.
+.sp
+The effect of this mechanism is that in the default configuration, triggers do not fire on replicas\&. This is useful because if a trigger is used on the origin to propagate data between tables, then the replication system will also replicate the propagated data; so the trigger should not fire a second time on the replica, because that would lead to duplication\&. However, if a trigger is used for another purpose such as creating external alerts, then it might be appropriate to set it to
+ENABLE ALWAYS
+so that it is also fired on replicas\&.
+.sp
+When this command is applied to a partitioned table, the states of corresponding clone triggers in the partitions are updated too, unless
+ONLY
+is specified\&.
+.sp
+This command acquires a
+SHARE ROW EXCLUSIVE
+lock\&.
+.RE
+.PP
+DISABLE/ENABLE [ REPLICA | ALWAYS ] RULE
+.RS 4
+These forms configure the firing of rewrite rules belonging to the table\&. A disabled rule is still known to the system, but is not applied during query rewriting\&. The semantics are as for disabled/enabled triggers\&. This configuration is ignored for
+ON SELECT
+rules, which are always applied in order to keep views working even if the current session is in a non\-default replication role\&.
+.sp
+The rule firing mechanism is also affected by the configuration variable
+session_replication_role, analogous to triggers as described above\&.
+.RE
+.PP
+DISABLE/ENABLE ROW LEVEL SECURITY
+.RS 4
+These forms control the application of row security policies belonging to the table\&. If enabled and no policies exist for the table, then a default\-deny policy is applied\&. Note that policies can exist for a table even if row\-level security is disabled\&. In this case, the policies will
+\fInot\fR
+be applied and the policies will be ignored\&. See also
+\fBCREATE POLICY\fR\&.
+.RE
+.PP
+NO FORCE/FORCE ROW LEVEL SECURITY
+.RS 4
+These forms control the application of row security policies belonging to the table when the user is the table owner\&. If enabled, row\-level security policies will be applied when the user is the table owner\&. If disabled (the default) then row\-level security will not be applied when the user is the table owner\&. See also
+\fBCREATE POLICY\fR\&.
+.RE
+.PP
+CLUSTER ON
+.RS 4
+This form selects the default index for future
+\fBCLUSTER\fR
+operations\&. It does not actually re\-cluster the table\&.
+.sp
+Changing cluster options acquires a
+SHARE UPDATE EXCLUSIVE
+lock\&.
+.RE
+.PP
+SET WITHOUT CLUSTER
+.RS 4
+This form removes the most recently used
+\fBCLUSTER\fR
+index specification from the table\&. This affects future cluster operations that don\*(Aqt specify an index\&.
+.sp
+Changing cluster options acquires a
+SHARE UPDATE EXCLUSIVE
+lock\&.
+.RE
+.PP
+SET WITHOUT OIDS
+.RS 4
+Backward\-compatible syntax for removing the
+oid
+system column\&. As
+oid
+system columns cannot be added anymore, this never has an effect\&.
+.RE
+.PP
+SET ACCESS METHOD
+.RS 4
+This form changes the access method of the table by rewriting it\&. See
+Chapter\ \&63
+for more information\&.
+.RE
+.PP
+SET TABLESPACE
+.RS 4
+This form changes the table\*(Aqs tablespace to the specified tablespace and moves the data file(s) associated with the table to the new tablespace\&. Indexes on the table, if any, are not moved; but they can be moved separately with additional
+SET TABLESPACE
+commands\&. When applied to a partitioned table, nothing is moved, but any partitions created afterwards with
+\fBCREATE TABLE PARTITION OF\fR
+will use that tablespace, unless overridden by a
+TABLESPACE
+clause\&.
+.sp
+All tables in the current database in a tablespace can be moved by using the
+ALL IN TABLESPACE
+form, which will lock all tables to be moved first and then move each one\&. This form also supports
+OWNED BY, which will only move tables owned by the roles specified\&. If the
+NOWAIT
+option is specified then the command will fail if it is unable to acquire all of the locks required immediately\&. Note that system catalogs are not moved by this command; use
+\fBALTER DATABASE\fR
+or explicit
+\fBALTER TABLE\fR
+invocations instead if desired\&. The
+information_schema
+relations are not considered part of the system catalogs and will be moved\&. See also
+\fBCREATE TABLESPACE\fR\&.
+.RE
+.PP
+SET { LOGGED | UNLOGGED }
+.RS 4
+This form changes the table from unlogged to logged or vice\-versa (see
+UNLOGGED)\&. It cannot be applied to a temporary table\&.
+.sp
+This also changes the persistence of any sequences linked to the table (for identity or serial columns)\&. However, it is also possible to change the persistence of such sequences separately\&.
+.RE
+.PP
+SET ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This form changes one or more storage parameters for the table\&. See
+Storage Parameters
+in the
+\fBCREATE TABLE\fR
+documentation for details on the available parameters\&. Note that the table contents will not be modified immediately by this command; depending on the parameter you might need to rewrite the table to get the desired effects\&. That can be done with
+\fBVACUUM FULL\fR,
+\fBCLUSTER\fR
+or one of the forms of
+\fBALTER TABLE\fR
+that forces a table rewrite\&. For planner related parameters, changes will take effect from the next time the table is locked so currently executing queries will not be affected\&.
+.sp
+SHARE UPDATE EXCLUSIVE
+lock will be taken for fillfactor, toast and autovacuum storage parameters, as well as the planner parameter
+\fIparallel_workers\fR\&.
+.RE
+.PP
+RESET ( \fIstorage_parameter\fR [, \&.\&.\&. ] )
+.RS 4
+This form resets one or more storage parameters to their defaults\&. As with
+SET, a table rewrite might be needed to update the table entirely\&.
+.RE
+.PP
+INHERIT \fIparent_table\fR
+.RS 4
+This form adds the target table as a new child of the specified parent table\&. Subsequently, queries against the parent will include records of the target table\&. To be added as a child, the target table must already contain all the same columns as the parent (it could have additional columns, too)\&. The columns must have matching data types, and if they have
+NOT NULL
+constraints in the parent then they must also have
+NOT NULL
+constraints in the child\&.
+.sp
+There must also be matching child\-table constraints for all
+CHECK
+constraints of the parent, except those marked non\-inheritable (that is, created with
+ALTER TABLE \&.\&.\&. ADD CONSTRAINT \&.\&.\&. NO INHERIT) in the parent, which are ignored; all child\-table constraints matched must not be marked non\-inheritable\&. Currently
+UNIQUE,
+PRIMARY KEY, and
+FOREIGN KEY
+constraints are not considered, but this might change in the future\&.
+.RE
+.PP
+NO INHERIT \fIparent_table\fR
+.RS 4
+This form removes the target table from the list of children of the specified parent table\&. Queries against the parent table will no longer include records drawn from the target table\&.
+.RE
+.PP
+OF \fItype_name\fR
+.RS 4
+This form links the table to a composite type as though
+\fBCREATE TABLE OF\fR
+had formed it\&. The table\*(Aqs list of column names and types must precisely match that of the composite type\&. The table must not inherit from any other table\&. These restrictions ensure that
+\fBCREATE TABLE OF\fR
+would permit an equivalent table definition\&.
+.RE
+.PP
+NOT OF
+.RS 4
+This form dissociates a typed table from its type\&.
+.RE
+.PP
+OWNER TO
+.RS 4
+This form changes the owner of the table, sequence, view, materialized view, or foreign table to the specified user\&.
+.RE
+.PP
+REPLICA IDENTITY
+.RS 4
+This form changes the information which is written to the write\-ahead log to identify rows which are updated or deleted\&. In most cases, the old value of each column is only logged if it differs from the new value; however, if the old value is stored externally, it is always logged regardless of whether it changed\&. This option has no effect except when logical replication is in use\&.
+.PP
+DEFAULT
+.RS 4
+Records the old values of the columns of the primary key, if any\&. This is the default for non\-system tables\&.
+.RE
+.PP
+USING INDEX \fIindex_name\fR
+.RS 4
+Records the old values of the columns covered by the named index, that must be unique, not partial, not deferrable, and include only columns marked
+NOT NULL\&. If this index is dropped, the behavior is the same as
+NOTHING\&.
+.RE
+.PP
+FULL
+.RS 4
+Records the old values of all columns in the row\&.
+.RE
+.PP
+NOTHING
+.RS 4
+Records no information about the old row\&. This is the default for system tables\&.
+.RE
+.RE
+.PP
+RENAME
+.RS 4
+The
+RENAME
+forms change the name of a table (or an index, sequence, view, materialized view, or foreign table), the name of an individual column in a table, or the name of a constraint of the table\&. When renaming a constraint that has an underlying index, the index is renamed as well\&. There is no effect on the stored data\&.
+.RE
+.PP
+SET SCHEMA
+.RS 4
+This form moves the table into another schema\&. Associated indexes, constraints, and sequences owned by table columns are moved as well\&.
+.RE
+.PP
+ATTACH PARTITION \fIpartition_name\fR { FOR VALUES \fIpartition_bound_spec\fR | DEFAULT }
+.RS 4
+This form attaches an existing table (which might itself be partitioned) as a partition of the target table\&. The table can be attached as a partition for specific values using
+FOR VALUES
+or as a default partition by using
+DEFAULT\&. For each index in the target table, a corresponding one will be created in the attached table; or, if an equivalent index already exists, it will be attached to the target table\*(Aqs index, as if
+\fBALTER INDEX ATTACH PARTITION\fR
+had been executed\&. Note that if the existing table is a foreign table, it is currently not allowed to attach the table as a partition of the target table if there are
+UNIQUE
+indexes on the target table\&. (See also
+CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7))\&.) For each user\-defined row\-level trigger that exists in the target table, a corresponding one is created in the attached table\&.
+.sp
+A partition using
+FOR VALUES
+uses same syntax for
+\fIpartition_bound_spec\fR
+as
+\fBCREATE TABLE\fR\&. The partition bound specification must correspond to the partitioning strategy and partition key of the target table\&. The table to be attached must have all the same columns as the target table and no more; moreover, the column types must also match\&. Also, it must have all the
+NOT NULL
+and
+CHECK
+constraints of the target table\&. Currently
+FOREIGN KEY
+constraints are not considered\&.
+UNIQUE
+and
+PRIMARY KEY
+constraints from the parent table will be created in the partition, if they don\*(Aqt already exist\&. If any of the
+CHECK
+constraints of the table being attached are marked
+NO INHERIT, the command will fail; such constraints must be recreated without the
+NO INHERIT
+clause\&.
+.sp
+If the new partition is a regular table, a full table scan is performed to check that existing rows in the table do not violate the partition constraint\&. It is possible to avoid this scan by adding a valid
+CHECK
+constraint to the table that allows only rows satisfying the desired partition constraint before running this command\&. The
+CHECK
+constraint will be used to determine that the table need not be scanned to validate the partition constraint\&. This does not work, however, if any of the partition keys is an expression and the partition does not accept
+NULL
+values\&. If attaching a list partition that will not accept
+NULL
+values, also add a
+NOT NULL
+constraint to the partition key column, unless it\*(Aqs an expression\&.
+.sp
+If the new partition is a foreign table, nothing is done to verify that all the rows in the foreign table obey the partition constraint\&. (See the discussion in
+CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7))
+about constraints on the foreign table\&.)
+.sp
+When a table has a default partition, defining a new partition changes the partition constraint for the default partition\&. The default partition can\*(Aqt contain any rows that would need to be moved to the new partition, and will be scanned to verify that none are present\&. This scan, like the scan of the new partition, can be avoided if an appropriate
+CHECK
+constraint is present\&. Also like the scan of the new partition, it is always skipped when the default partition is a foreign table\&.
+.sp
+Attaching a partition acquires a
+SHARE UPDATE EXCLUSIVE
+lock on the parent table, in addition to the
+ACCESS EXCLUSIVE
+locks on the table being attached and on the default partition (if any)\&.
+.sp
+Further locks must also be held on all sub\-partitions if the table being attached is itself a partitioned table\&. Likewise if the default partition is itself a partitioned table\&. The locking of the sub\-partitions can be avoided by adding a
+CHECK
+constraint as described in
+Section\ \&5.11.2.2\&.
+.RE
+.PP
+DETACH PARTITION \fIpartition_name\fR [ CONCURRENTLY | FINALIZE ]
+.RS 4
+This form detaches the specified partition of the target table\&. The detached partition continues to exist as a standalone table, but no longer has any ties to the table from which it was detached\&. Any indexes that were attached to the target table\*(Aqs indexes are detached\&. Any triggers that were created as clones of those in the target table are removed\&.
+SHARE
+lock is obtained on any tables that reference this partitioned table in foreign key constraints\&.
+.sp
+If
+CONCURRENTLY
+is specified, it runs using a reduced lock level to avoid blocking other sessions that might be accessing the partitioned table\&. In this mode, two transactions are used internally\&. During the first transaction, a
+SHARE UPDATE EXCLUSIVE
+lock is taken on both parent table and partition, and the partition is marked as undergoing detach; at that point, the transaction is committed and all other transactions using the partitioned table are waited for\&. Once all those transactions have completed, the second transaction acquires
+SHARE UPDATE EXCLUSIVE
+on the partitioned table and
+ACCESS EXCLUSIVE
+on the partition, and the detach process completes\&. A
+CHECK
+constraint that duplicates the partition constraint is added to the partition\&.
+CONCURRENTLY
+cannot be run in a transaction block and is not allowed if the partitioned table contains a default partition\&.
+.sp
+If
+FINALIZE
+is specified, a previous
+DETACH CONCURRENTLY
+invocation that was canceled or interrupted is completed\&. At most one partition in a partitioned table can be pending detach at a time\&.
+.RE
+.PP
+All the forms of ALTER TABLE that act on a single table, except
+RENAME,
+SET SCHEMA,
+ATTACH PARTITION, and
+DETACH PARTITION
+can be combined into a list of multiple alterations to be applied together\&. For example, it is possible to add several columns and/or alter the type of several columns in a single command\&. This is particularly useful with large tables, since only one pass over the table need be made\&.
+.PP
+You must own the table to use
+\fBALTER TABLE\fR\&. To change the schema or tablespace of a table, you must also have
+CREATE
+privilege on the new schema or tablespace\&. To add the table as a new child of a parent table, you must own the parent table as well\&. Also, to attach a table as a new partition of the table, you must own the table being attached\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the table\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the table\&. However, a superuser can alter ownership of any table anyway\&.) To add a column or alter a column type or use the
+OF
+clause, you must also have
+USAGE
+privilege on the data type\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the table does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing table to alter\&. If
+ONLY
+is specified before the table name, only that table is altered\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are altered\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+Name of a new or existing column\&.
+.RE
+.PP
+\fInew_column_name\fR
+.RS 4
+New name for an existing column\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+New name for the table\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+Data type of the new column, or new data type for an existing column\&.
+.RE
+.PP
+\fItable_constraint\fR
+.RS 4
+New table constraint for the table\&.
+.RE
+.PP
+\fIconstraint_name\fR
+.RS 4
+Name of a new or existing constraint\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the dropped column or constraint (for example, views referencing the column), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the column or constraint if there are any dependent objects\&. This is the default behavior\&.
+.RE
+.PP
+\fItrigger_name\fR
+.RS 4
+Name of a single trigger to disable or enable\&.
+.RE
+.PP
+ALL
+.RS 4
+Disable or enable all triggers belonging to the table\&. (This requires superuser privilege if any of the triggers are internally generated constraint triggers, such as those that are used to implement foreign key constraints or deferrable uniqueness and exclusion constraints\&.)
+.RE
+.PP
+USER
+.RS 4
+Disable or enable all triggers belonging to the table except for internally generated constraint triggers, such as those that are used to implement foreign key constraints or deferrable uniqueness and exclusion constraints\&.
+.RE
+.PP
+\fIindex_name\fR
+.RS 4
+The name of an existing index\&.
+.RE
+.PP
+\fIstorage_parameter\fR
+.RS 4
+The name of a table storage parameter\&.
+.RE
+.PP
+\fIvalue\fR
+.RS 4
+The new value for a table storage parameter\&. This might be a number or a word depending on the parameter\&.
+.RE
+.PP
+\fIparent_table\fR
+.RS 4
+A parent table to associate or de\-associate with this table\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the table\&.
+.RE
+.PP
+\fInew_access_method\fR
+.RS 4
+The name of the access method to which the table will be converted\&.
+.RE
+.PP
+\fInew_tablespace\fR
+.RS 4
+The name of the tablespace to which the table will be moved\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The name of the schema to which the table will be moved\&.
+.RE
+.PP
+\fIpartition_name\fR
+.RS 4
+The name of the table to attach as a new partition or to detach from this table\&.
+.RE
+.PP
+\fIpartition_bound_spec\fR
+.RS 4
+The partition bound specification for a new partition\&. Refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for more details on the syntax of the same\&.
+.RE
+.SH "NOTES"
+.PP
+The key word
+COLUMN
+is noise and can be omitted\&.
+.PP
+When a column is added with
+ADD COLUMN
+and a non\-volatile
+DEFAULT
+is specified, the default is evaluated at the time of the statement and the result stored in the table\*(Aqs metadata\&. That value will be used for the column for all existing rows\&. If no
+DEFAULT
+is specified, NULL is used\&. In neither case is a rewrite of the table required\&.
+.PP
+Adding a column with a volatile
+DEFAULT
+or changing the type of an existing column will require the entire table and its indexes to be rewritten\&. As an exception, when changing the type of an existing column, if the
+USING
+clause does not change the column contents and the old type is either binary coercible to the new type or an unconstrained domain over the new type, a table rewrite is not needed\&. However, indexes must always be rebuilt unless the system can verify that the new index would be logically equivalent to the existing one\&. For example, if the collation for a column has been changed, an index rebuild is always required because the new sort order might be different\&. However, in the absence of a collation change, a column can be changed from
+text
+to
+varchar
+(or vice versa) without rebuilding the indexes because these data types sort identically\&. Table and/or index rebuilds may take a significant amount of time for a large table; and will temporarily require as much as double the disk space\&.
+.PP
+Adding a
+CHECK
+or
+NOT NULL
+constraint requires scanning the table to verify that existing rows meet the constraint, but does not require a table rewrite\&.
+.PP
+Similarly, when attaching a new partition it may be scanned to verify that existing rows meet the partition constraint\&.
+.PP
+The main reason for providing the option to specify multiple changes in a single
+\fBALTER TABLE\fR
+is that multiple table scans or rewrites can thereby be combined into a single pass over the table\&.
+.PP
+Scanning a large table to verify a new foreign key or check constraint can take a long time, and other updates to the table are locked out until the
+\fBALTER TABLE ADD CONSTRAINT\fR
+command is committed\&. The main purpose of the
+NOT VALID
+constraint option is to reduce the impact of adding a constraint on concurrent updates\&. With
+NOT VALID, the
+\fBADD CONSTRAINT\fR
+command does not scan the table and can be committed immediately\&. After that, a
+VALIDATE CONSTRAINT
+command can be issued to verify that existing rows satisfy the constraint\&. The validation step does not need to lock out concurrent updates, since it knows that other transactions will be enforcing the constraint for rows that they insert or update; only pre\-existing rows need to be checked\&. Hence, validation acquires only a
+SHARE UPDATE EXCLUSIVE
+lock on the table being altered\&. (If the constraint is a foreign key then a
+ROW SHARE
+lock is also required on the table referenced by the constraint\&.) In addition to improving concurrency, it can be useful to use
+NOT VALID
+and
+VALIDATE CONSTRAINT
+in cases where the table is known to contain pre\-existing violations\&. Once the constraint is in place, no new violations can be inserted, and the existing problems can be corrected at leisure until
+VALIDATE CONSTRAINT
+finally succeeds\&.
+.PP
+The
+DROP COLUMN
+form does not physically remove the column, but simply makes it invisible to SQL operations\&. Subsequent insert and update operations in the table will store a null value for the column\&. Thus, dropping a column is quick but it will not immediately reduce the on\-disk size of your table, as the space occupied by the dropped column is not reclaimed\&. The space will be reclaimed over time as existing rows are updated\&.
+.PP
+To force immediate reclamation of space occupied by a dropped column, you can execute one of the forms of
+\fBALTER TABLE\fR
+that performs a rewrite of the whole table\&. This results in reconstructing each row with the dropped column replaced by a null value\&.
+.PP
+The rewriting forms of
+\fBALTER TABLE\fR
+are not MVCC\-safe\&. After a table rewrite, the table will appear empty to concurrent transactions, if they are using a snapshot taken before the rewrite occurred\&. See
+Section\ \&13.6
+for more details\&.
+.PP
+The
+USING
+option of
+SET DATA TYPE
+can actually specify any expression involving the old values of the row; that is, it can refer to other columns as well as the one being converted\&. This allows very general conversions to be done with the
+SET DATA TYPE
+syntax\&. Because of this flexibility, the
+USING
+expression is not applied to the column\*(Aqs default value (if any); the result might not be a constant expression as required for a default\&. This means that when there is no implicit or assignment cast from old to new type,
+SET DATA TYPE
+might fail to convert the default even though a
+USING
+clause is supplied\&. In such cases, drop the default with
+DROP DEFAULT, perform the
+ALTER TYPE, and then use
+SET DEFAULT
+to add a suitable new default\&. Similar considerations apply to indexes and constraints involving the column\&.
+.PP
+If a table has any descendant tables, it is not permitted to add, rename, or change the type of a column in the parent table without doing the same to the descendants\&. This ensures that the descendants always have columns matching the parent\&. Similarly, a
+CHECK
+constraint cannot be renamed in the parent without also renaming it in all descendants, so that
+CHECK
+constraints also match between the parent and its descendants\&. (That restriction does not apply to index\-based constraints, however\&.) Also, because selecting from the parent also selects from its descendants, a constraint on the parent cannot be marked valid unless it is also marked valid for those descendants\&. In all of these cases,
+\fBALTER TABLE ONLY\fR
+will be rejected\&.
+.PP
+A recursive
+DROP COLUMN
+operation will remove a descendant table\*(Aqs column only if the descendant does not inherit that column from any other parents and never had an independent definition of the column\&. A nonrecursive
+DROP COLUMN
+(i\&.e\&.,
+\fBALTER TABLE ONLY \&.\&.\&. DROP COLUMN\fR) never removes any descendant columns, but instead marks them as independently defined rather than inherited\&. A nonrecursive
+DROP COLUMN
+command will fail for a partitioned table, because all partitions of a table must have the same columns as the partitioning root\&.
+.PP
+The actions for identity columns (ADD GENERATED,
+SET
+etc\&.,
+DROP IDENTITY), as well as the actions
+CLUSTER,
+OWNER, and
+TABLESPACE
+never recurse to descendant tables; that is, they always act as though
+ONLY
+were specified\&. Actions affecting trigger states recurse to partitions of partitioned tables (unless
+ONLY
+is specified), but never to traditional\-inheritance descendants\&. Adding a constraint recurses only for
+CHECK
+constraints that are not marked
+NO INHERIT\&.
+.PP
+Changing any part of a system catalog table is not permitted\&.
+.PP
+Refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for a further description of valid parameters\&.
+Chapter\ \&5
+has further information on inheritance\&.
+.SH "EXAMPLES"
+.PP
+To add a column of type
+varchar
+to a table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD COLUMN address varchar(30);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+That will cause all existing rows in the table to be filled with null values for the new column\&.
+.PP
+To add a column with a non\-null default:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE measurements
+ ADD COLUMN mtime timestamp with time zone DEFAULT now();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Existing rows will be filled with the current time as the value of the new column, and then new rows will receive the time of their insertion\&.
+.PP
+To add a column and fill it with a value different from the default to be used later:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE transactions
+ ADD COLUMN status varchar(30) DEFAULT \*(Aqold\*(Aq,
+ ALTER COLUMN status SET default \*(Aqcurrent\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Existing rows will be filled with
+old, but then the default for subsequent commands will be
+current\&. The effects are the same as if the two sub\-commands had been issued in separate
+\fBALTER TABLE\fR
+commands\&.
+.PP
+To drop a column from a table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors DROP COLUMN address RESTRICT;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the types of two existing columns in one operation:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors
+ ALTER COLUMN address TYPE varchar(80),
+ ALTER COLUMN name TYPE varchar(100);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change an integer column containing Unix timestamps to
+timestamp with time zone
+via a
+USING
+clause:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE foo
+ ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
+ USING
+ timestamp with time zone \*(Aqepoch\*(Aq + foo_timestamp * interval \*(Aq1 second\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The same, when the column has a default expression that won\*(Aqt automatically cast to the new data type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE foo
+ ALTER COLUMN foo_timestamp DROP DEFAULT,
+ ALTER COLUMN foo_timestamp TYPE timestamp with time zone
+ USING
+ timestamp with time zone \*(Aqepoch\*(Aq + foo_timestamp * interval \*(Aq1 second\*(Aq,
+ ALTER COLUMN foo_timestamp SET DEFAULT now();
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To rename an existing column:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors RENAME COLUMN address TO city;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To rename an existing table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors RENAME TO suppliers;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To rename an existing constraint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a not\-null constraint to a column:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+To remove a not\-null constraint from a column:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a check constraint to a table and all its children:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a check constraint only to a table and not to its children:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(The check constraint will not be inherited by future children, either\&.)
+.PP
+To remove a check constraint from a table and all its children:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors DROP CONSTRAINT zipchk;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To remove a check constraint from one table only:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(The check constraint remains in place for any child tables\&.)
+.PP
+To add a foreign key constraint to a table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a foreign key constraint to a table with the least impact on other work:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) NOT VALID;
+ALTER TABLE distributors VALIDATE CONSTRAINT distfk;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a (multicolumn) unique constraint to a table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add an automatically named primary key constraint to a table, noting that a table can only ever have one primary key:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To move a table to a different tablespace:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE distributors SET TABLESPACE fasttablespace;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To move a table to a different schema:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE myschema\&.distributors SET SCHEMA yourschema;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To recreate a primary key constraint, without blocking updates while the index is rebuilt:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
+ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
+ ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To attach a partition to a range\-partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE measurement
+ ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM (\*(Aq2016\-07\-01\*(Aq) TO (\*(Aq2016\-08\-01\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To attach a partition to a list\-partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE cities
+ ATTACH PARTITION cities_ab FOR VALUES IN (\*(Aqa\*(Aq, \*(Aqb\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To attach a partition to a hash\-partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE orders
+ ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To attach a default partition to a partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE cities
+ ATTACH PARTITION cities_partdef DEFAULT;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To detach a partition from a partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLE measurement
+ DETACH PARTITION measurement_y2015m12;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The forms
+ADD
+(without
+USING INDEX),
+DROP [COLUMN],
+DROP IDENTITY,
+RESTART,
+SET DEFAULT,
+SET DATA TYPE
+(without
+USING),
+SET GENERATED, and
+SET \fIsequence_option\fR
+conform with the SQL standard\&. The other forms are
+PostgreSQL
+extensions of the SQL standard\&. Also, the ability to specify more than one manipulation in a single
+\fBALTER TABLE\fR
+command is an extension\&.
+.PP
+\fBALTER TABLE DROP COLUMN\fR
+can be used to drop the only column of a table, leaving a zero\-column table\&. This is an extension of SQL, which disallows zero\-column tables\&.
+.SH "SEE ALSO"
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TABLESPACE.7 b/doc/src/sgml/man7/ALTER_TABLESPACE.7
new file mode 100644
index 0000000..49a0499
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TABLESPACE.7
@@ -0,0 +1,112 @@
+'\" t
+.\" Title: ALTER TABLESPACE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TABLESPACE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TABLESPACE \- change the definition of a tablespace
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TABLESPACE \fIname\fR RENAME TO \fInew_name\fR
+ALTER TABLESPACE \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TABLESPACE \fIname\fR SET ( \fItablespace_option\fR = \fIvalue\fR [, \&.\&.\&. ] )
+ALTER TABLESPACE \fIname\fR RESET ( \fItablespace_option\fR [, \&.\&.\&. ] )
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TABLESPACE\fR
+can be used to change the definition of a tablespace\&.
+.PP
+You must own the tablespace to change the definition of a tablespace\&. To alter the owner, you must also be a direct or indirect member of the new owning role\&. (Note that superusers have these privileges automatically\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing tablespace\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the tablespace\&. The new name cannot begin with
+pg_, as such names are reserved for system tablespaces\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the tablespace\&.
+.RE
+.PP
+\fItablespace_option\fR
+.RS 4
+A tablespace parameter to be set or reset\&. Currently, the only available parameters are
+\fIseq_page_cost\fR,
+\fIrandom_page_cost\fR,
+\fIeffective_io_concurrency\fR
+and
+\fImaintenance_io_concurrency\fR\&. Setting these values for a particular tablespace will override the planner\*(Aqs usual estimate of the cost of reading pages from tables in that tablespace, and the executor\*(Aqs prefetching behavior, as established by the configuration parameters of the same name (see
+seq_page_cost,
+random_page_cost,
+effective_io_concurrency,
+maintenance_io_concurrency)\&. This may be useful if one tablespace is located on a disk which is faster or slower than the remainder of the I/O subsystem\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Rename tablespace
+index_space
+to
+fast_raid:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLESPACE index_space RENAME TO fast_raid;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Change the owner of tablespace
+index_space:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TABLESPACE index_space OWNER TO mary;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER TABLESPACE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE TABLESPACE (\fBCREATE_TABLESPACE\fR(7)), DROP TABLESPACE (\fBDROP_TABLESPACE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TEXT_SEARCH_CONFIGURATION.7 b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_CONFIGURATION.7
new file mode 100644
index 0000000..29b53c4
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_CONFIGURATION.7
@@ -0,0 +1,143 @@
+'\" t
+.\" Title: ALTER TEXT SEARCH CONFIGURATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TEXT SEARCH CONFIGURATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TEXT_SEARCH_CONFIGURATION \- change the definition of a text search configuration
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR
+ ADD MAPPING FOR \fItoken_type\fR [, \&.\&.\&. ] WITH \fIdictionary_name\fR [, \&.\&.\&. ]
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR
+ ALTER MAPPING FOR \fItoken_type\fR [, \&.\&.\&. ] WITH \fIdictionary_name\fR [, \&.\&.\&. ]
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR
+ ALTER MAPPING REPLACE \fIold_dictionary\fR WITH \fInew_dictionary\fR
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR
+ ALTER MAPPING FOR \fItoken_type\fR [, \&.\&.\&. ] REPLACE \fIold_dictionary\fR WITH \fInew_dictionary\fR
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR
+ DROP MAPPING [ IF EXISTS ] FOR \fItoken_type\fR [, \&.\&.\&. ]
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR RENAME TO \fInew_name\fR
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TEXT SEARCH CONFIGURATION \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TEXT SEARCH CONFIGURATION\fR
+changes the definition of a text search configuration\&. You can modify its mappings from token types to dictionaries, or change the configuration\*(Aqs name or owner\&.
+.PP
+You must be the owner of the configuration to use
+\fBALTER TEXT SEARCH CONFIGURATION\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search configuration\&.
+.RE
+.PP
+\fItoken_type\fR
+.RS 4
+The name of a token type that is emitted by the configuration\*(Aqs parser\&.
+.RE
+.PP
+\fIdictionary_name\fR
+.RS 4
+The name of a text search dictionary to be consulted for the specified token type(s)\&. If multiple dictionaries are listed, they are consulted in the specified order\&.
+.RE
+.PP
+\fIold_dictionary\fR
+.RS 4
+The name of a text search dictionary to be replaced in the mapping\&.
+.RE
+.PP
+\fInew_dictionary\fR
+.RS 4
+The name of a text search dictionary to be substituted for
+\fIold_dictionary\fR\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the text search configuration\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the text search configuration\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the text search configuration\&.
+.RE
+.PP
+The
+ADD MAPPING FOR
+form installs a list of dictionaries to be consulted for the specified token type(s); it is an error if there is already a mapping for any of the token types\&. The
+ALTER MAPPING FOR
+form does the same, but first removing any existing mapping for those token types\&. The
+ALTER MAPPING REPLACE
+forms substitute
+\fInew_dictionary\fR
+for
+\fIold_dictionary\fR
+anywhere the latter appears\&. This is done for only the specified token types when
+FOR
+appears, or for all mappings of the configuration when it doesn\*(Aqt\&. The
+DROP MAPPING
+form removes all dictionaries for the specified token type(s), causing tokens of those types to be ignored by the text search configuration\&. It is an error if there is no mapping for the token types, unless
+IF EXISTS
+appears\&.
+.SH "EXAMPLES"
+.PP
+The following example replaces the
+english
+dictionary with the
+swedish
+dictionary anywhere that
+english
+is used within
+my_config\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TEXT SEARCH CONFIGURATION my_config
+ ALTER MAPPING REPLACE english WITH swedish;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER TEXT SEARCH CONFIGURATION\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE TEXT SEARCH CONFIGURATION (\fBCREATE_TEXT_SEARCH_CONFIGURATION\fR(7)), DROP TEXT SEARCH CONFIGURATION (\fBDROP_TEXT_SEARCH_CONFIGURATION\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TEXT_SEARCH_DICTIONARY.7 b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_DICTIONARY.7
new file mode 100644
index 0000000..3a25dea
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_DICTIONARY.7
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: ALTER TEXT SEARCH DICTIONARY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TEXT SEARCH DICTIONARY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TEXT_SEARCH_DICTIONARY \- change the definition of a text search dictionary
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TEXT SEARCH DICTIONARY \fIname\fR (
+ \fIoption\fR [ = \fIvalue\fR ] [, \&.\&.\&. ]
+)
+ALTER TEXT SEARCH DICTIONARY \fIname\fR RENAME TO \fInew_name\fR
+ALTER TEXT SEARCH DICTIONARY \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TEXT SEARCH DICTIONARY \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TEXT SEARCH DICTIONARY\fR
+changes the definition of a text search dictionary\&. You can change the dictionary\*(Aqs template\-specific options, or change the dictionary\*(Aqs name or owner\&.
+.PP
+You must be the owner of the dictionary to use
+\fBALTER TEXT SEARCH DICTIONARY\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search dictionary\&.
+.RE
+.PP
+\fIoption\fR
+.RS 4
+The name of a template\-specific option to be set for this dictionary\&.
+.RE
+.PP
+\fIvalue\fR
+.RS 4
+The new value to use for a template\-specific option\&. If the equal sign and value are omitted, then any previous setting for the option is removed from the dictionary, allowing the default to be used\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the text search dictionary\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The new owner of the text search dictionary\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the text search dictionary\&.
+.RE
+.PP
+Template\-specific options can appear in any order\&.
+.SH "EXAMPLES"
+.PP
+The following example command changes the stopword list for a Snowball\-based dictionary\&. Other parameters remain unchanged\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TEXT SEARCH DICTIONARY my_dict ( StopWords = newrussian );
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The following example command changes the language option to
+dutch, and removes the stopword option entirely\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TEXT SEARCH DICTIONARY my_dict ( language = dutch, StopWords );
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The following example command
+\(lqupdates\(rq
+the dictionary\*(Aqs definition without actually changing anything\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TEXT SEARCH DICTIONARY my_dict ( dummy );
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(The reason this works is that the option removal code doesn\*(Aqt complain if there is no such option\&.) This trick is useful when changing configuration files for the dictionary: the
+\fBALTER\fR
+will force existing database sessions to re\-read the configuration files, which otherwise they would never do if they had read them earlier\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER TEXT SEARCH DICTIONARY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE TEXT SEARCH DICTIONARY (\fBCREATE_TEXT_SEARCH_DICTIONARY\fR(7)), DROP TEXT SEARCH DICTIONARY (\fBDROP_TEXT_SEARCH_DICTIONARY\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TEXT_SEARCH_PARSER.7 b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_PARSER.7
new file mode 100644
index 0000000..fdd1d20
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_PARSER.7
@@ -0,0 +1,67 @@
+'\" t
+.\" Title: ALTER TEXT SEARCH PARSER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TEXT SEARCH PARSER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TEXT_SEARCH_PARSER \- change the definition of a text search parser
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TEXT SEARCH PARSER \fIname\fR RENAME TO \fInew_name\fR
+ALTER TEXT SEARCH PARSER \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TEXT SEARCH PARSER\fR
+changes the definition of a text search parser\&. Currently, the only supported functionality is to change the parser\*(Aqs name\&.
+.PP
+You must be a superuser to use
+\fBALTER TEXT SEARCH PARSER\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search parser\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the text search parser\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the text search parser\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER TEXT SEARCH PARSER\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE TEXT SEARCH PARSER (\fBCREATE_TEXT_SEARCH_PARSER\fR(7)), DROP TEXT SEARCH PARSER (\fBDROP_TEXT_SEARCH_PARSER\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TEXT_SEARCH_TEMPLATE.7 b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_TEMPLATE.7
new file mode 100644
index 0000000..ce63a75
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TEXT_SEARCH_TEMPLATE.7
@@ -0,0 +1,67 @@
+'\" t
+.\" Title: ALTER TEXT SEARCH TEMPLATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TEXT SEARCH TEMPLATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TEXT_SEARCH_TEMPLATE \- change the definition of a text search template
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TEXT SEARCH TEMPLATE \fIname\fR RENAME TO \fInew_name\fR
+ALTER TEXT SEARCH TEMPLATE \fIname\fR SET SCHEMA \fInew_schema\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TEXT SEARCH TEMPLATE\fR
+changes the definition of a text search template\&. Currently, the only supported functionality is to change the template\*(Aqs name\&.
+.PP
+You must be a superuser to use
+\fBALTER TEXT SEARCH TEMPLATE\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search template\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name of the text search template\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the text search template\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBALTER TEXT SEARCH TEMPLATE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE TEXT SEARCH TEMPLATE (\fBCREATE_TEXT_SEARCH_TEMPLATE\fR(7)), DROP TEXT SEARCH TEMPLATE (\fBDROP_TEXT_SEARCH_TEMPLATE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TRIGGER.7 b/doc/src/sgml/man7/ALTER_TRIGGER.7
new file mode 100644
index 0000000..84650d7
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TRIGGER.7
@@ -0,0 +1,114 @@
+'\" t
+.\" Title: ALTER TRIGGER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TRIGGER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TRIGGER \- change the definition of a trigger
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TRIGGER \fIname\fR ON \fItable_name\fR RENAME TO \fInew_name\fR
+ALTER TRIGGER \fIname\fR ON \fItable_name\fR [ NO ] DEPENDS ON EXTENSION \fIextension_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TRIGGER\fR
+changes properties of an existing trigger\&.
+.PP
+The
+RENAME
+clause changes the name of the given trigger without otherwise changing the trigger definition\&. If the table that the trigger is on is a partitioned table, then corresponding clone triggers in the partitions are renamed too\&.
+.PP
+The
+DEPENDS ON EXTENSION
+clause marks the trigger as dependent on an extension, such that if the extension is dropped, the trigger will automatically be dropped as well\&.
+.PP
+You must own the table on which the trigger acts to be allowed to change its properties\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an existing trigger to alter\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name of the table on which this trigger acts\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the trigger\&.
+.RE
+.PP
+\fIextension_name\fR
+.RS 4
+The name of the extension that the trigger is to depend on (or no longer dependent on, if
+NO
+is specified)\&. A trigger that\*(Aqs marked as dependent on an extension is automatically dropped when the extension is dropped\&.
+.RE
+.SH "NOTES"
+.PP
+The ability to temporarily enable or disable a trigger is provided by
+\fBALTER TABLE\fR, not by
+\fBALTER TRIGGER\fR, because
+\fBALTER TRIGGER\fR
+has no convenient way to express the option of enabling or disabling all of a table\*(Aqs triggers at once\&.
+.SH "EXAMPLES"
+.PP
+To rename an existing trigger:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TRIGGER emp_stamp ON emp RENAME TO emp_track_chgs;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To mark a trigger as being dependent on an extension:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER TRIGGER\fR
+is a
+PostgreSQL
+extension of the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TABLE (\fBALTER_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_TYPE.7 b/doc/src/sgml/man7/ALTER_TYPE.7
new file mode 100644
index 0000000..18775e4
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_TYPE.7
@@ -0,0 +1,424 @@
+'\" t
+.\" Title: ALTER TYPE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER TYPE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_TYPE \- change the definition of a type
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER TYPE \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TYPE \fIname\fR RENAME TO \fInew_name\fR
+ALTER TYPE \fIname\fR SET SCHEMA \fInew_schema\fR
+ALTER TYPE \fIname\fR RENAME ATTRIBUTE \fIattribute_name\fR TO \fInew_attribute_name\fR [ CASCADE | RESTRICT ]
+ALTER TYPE \fIname\fR \fIaction\fR [, \&.\&.\&. ]
+ALTER TYPE \fIname\fR ADD VALUE [ IF NOT EXISTS ] \fInew_enum_value\fR [ { BEFORE | AFTER } \fIneighbor_enum_value\fR ]
+ALTER TYPE \fIname\fR RENAME VALUE \fIexisting_enum_value\fR TO \fInew_enum_value\fR
+ALTER TYPE \fIname\fR SET ( \fIproperty\fR = \fIvalue\fR [, \&.\&.\&. ] )
+
+where \fIaction\fR is one of:
+
+ ADD ATTRIBUTE \fIattribute_name\fR \fIdata_type\fR [ COLLATE \fIcollation\fR ] [ CASCADE | RESTRICT ]
+ DROP ATTRIBUTE [ IF EXISTS ] \fIattribute_name\fR [ CASCADE | RESTRICT ]
+ ALTER ATTRIBUTE \fIattribute_name\fR [ SET DATA ] TYPE \fIdata_type\fR [ COLLATE \fIcollation\fR ] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER TYPE\fR
+changes the definition of an existing type\&. There are several subforms:
+.PP
+OWNER
+.RS 4
+This form changes the owner of the type\&.
+.RE
+.PP
+RENAME
+.RS 4
+This form changes the name of the type\&.
+.RE
+.PP
+SET SCHEMA
+.RS 4
+This form moves the type into another schema\&.
+.RE
+.PP
+RENAME ATTRIBUTE
+.RS 4
+This form is only usable with composite types\&. It changes the name of an individual attribute of the type\&.
+.RE
+.PP
+ADD ATTRIBUTE
+.RS 4
+This form adds a new attribute to a composite type, using the same syntax as
+\fBCREATE TYPE\fR\&.
+.RE
+.PP
+DROP ATTRIBUTE [ IF EXISTS ]
+.RS 4
+This form drops an attribute from a composite type\&. If
+IF EXISTS
+is specified and the attribute does not exist, no error is thrown\&. In this case a notice is issued instead\&.
+.RE
+.PP
+ALTER ATTRIBUTE \&.\&.\&. SET DATA TYPE
+.RS 4
+This form changes the type of an attribute of a composite type\&.
+.RE
+.PP
+ADD VALUE [ IF NOT EXISTS ] [ BEFORE | AFTER ]
+.RS 4
+This form adds a new value to an enum type\&. The new value\*(Aqs place in the enum\*(Aqs ordering can be specified as being
+BEFORE
+or
+AFTER
+one of the existing values\&. Otherwise, the new item is added at the end of the list of values\&.
+.sp
+If
+IF NOT EXISTS
+is specified, it is not an error if the type already contains the new value: a notice is issued but no other action is taken\&. Otherwise, an error will occur if the new value is already present\&.
+.RE
+.PP
+RENAME VALUE
+.RS 4
+This form renames a value of an enum type\&. The value\*(Aqs place in the enum\*(Aqs ordering is not affected\&. An error will occur if the specified value is not present or the new name is already present\&.
+.RE
+.PP
+SET ( \fIproperty\fR = \fIvalue\fR [, \&.\&.\&. ] )
+.RS 4
+This form is only applicable to base types\&. It allows adjustment of a subset of the base\-type properties that can be set in
+\fBCREATE TYPE\fR\&. Specifically, these properties can be changed:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+RECEIVE
+can be set to the name of a binary input function, or
+NONE
+to remove the type\*(Aqs binary input function\&. Using this option requires superuser privilege\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+SEND
+can be set to the name of a binary output function, or
+NONE
+to remove the type\*(Aqs binary output function\&. Using this option requires superuser privilege\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+TYPMOD_IN
+can be set to the name of a type modifier input function, or
+NONE
+to remove the type\*(Aqs type modifier input function\&. Using this option requires superuser privilege\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+TYPMOD_OUT
+can be set to the name of a type modifier output function, or
+NONE
+to remove the type\*(Aqs type modifier output function\&. Using this option requires superuser privilege\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+ANALYZE
+can be set to the name of a type\-specific statistics collection function, or
+NONE
+to remove the type\*(Aqs statistics collection function\&. Using this option requires superuser privilege\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+SUBSCRIPT
+can be set to the name of a type\-specific subscripting handler function, or
+NONE
+to remove the type\*(Aqs subscripting handler function\&. Using this option requires superuser privilege\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+STORAGE
+can be set to
+plain,
+extended,
+external, or
+main
+(see
+Section\ \&73.2
+for more information about what these mean)\&. However, changing from
+plain
+to another setting requires superuser privilege (because it requires that the type\*(Aqs C functions all be TOAST\-ready), and changing to
+plain
+from another setting is not allowed at all (since the type may already have TOASTed values present in the database)\&. Note that changing this option doesn\*(Aqt by itself change any stored data, it just sets the default TOAST strategy to be used for table columns created in the future\&. See
+ALTER TABLE (\fBALTER_TABLE\fR(7))
+to change the TOAST strategy for existing table columns\&.
+.RE
+.sp
+See
+CREATE TYPE (\fBCREATE_TYPE\fR(7))
+for more details about these type properties\&. Note that where appropriate, a change in these properties for a base type will be propagated automatically to domains based on that type\&.
+.RE
+.PP
+The
+ADD ATTRIBUTE,
+DROP ATTRIBUTE, and
+ALTER ATTRIBUTE
+actions can be combined into a list of multiple alterations to apply in parallel\&. For example, it is possible to add several attributes and/or alter the type of several attributes in a single command\&.
+.PP
+You must own the type to use
+\fBALTER TYPE\fR\&. To change the schema of a type, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the type\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the type\&. However, a superuser can alter ownership of any type anyway\&.) To add an attribute or alter an attribute type, you must also have
+USAGE
+privilege on the attribute\*(Aqs data type\&.
+.SH "PARAMETERS"
+.PP
+.PP
+\fIname\fR
+.RS 4
+The name (possibly schema\-qualified) of an existing type to alter\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the type\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the type\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the type\&.
+.RE
+.PP
+\fIattribute_name\fR
+.RS 4
+The name of the attribute to add, alter, or drop\&.
+.RE
+.PP
+\fInew_attribute_name\fR
+.RS 4
+The new name of the attribute to be renamed\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The data type of the attribute to add, or the new type of the attribute to alter\&.
+.RE
+.PP
+\fInew_enum_value\fR
+.RS 4
+The new value to be added to an enum type\*(Aqs list of values, or the new name to be given to an existing value\&. Like all enum literals, it needs to be quoted\&.
+.RE
+.PP
+\fIneighbor_enum_value\fR
+.RS 4
+The existing enum value that the new value should be added immediately before or after in the enum type\*(Aqs sort ordering\&. Like all enum literals, it needs to be quoted\&.
+.RE
+.PP
+\fIexisting_enum_value\fR
+.RS 4
+The existing enum value that should be renamed\&. Like all enum literals, it needs to be quoted\&.
+.RE
+.PP
+\fIproperty\fR
+.RS 4
+The name of a base\-type property to be modified; see above for possible values\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically propagate the operation to typed tables of the type being altered, and their descendants\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse the operation if the type being altered is the type of a typed table\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+If
+\fBALTER TYPE \&.\&.\&. ADD VALUE\fR
+(the form that adds a new value to an enum type) is executed inside a transaction block, the new value cannot be used until after the transaction has been committed\&.
+.PP
+Comparisons involving an added enum value will sometimes be slower than comparisons involving only original members of the enum type\&. This will usually only occur if
+BEFORE
+or
+AFTER
+is used to set the new value\*(Aqs sort position somewhere other than at the end of the list\&. However, sometimes it will happen even though the new value is added at the end (this occurs if the OID counter
+\(lqwrapped around\(rq
+since the original creation of the enum type)\&. The slowdown is usually insignificant; but if it matters, optimal performance can be regained by dropping and recreating the enum type, or by dumping and restoring the database\&.
+.SH "EXAMPLES"
+.PP
+To rename a data type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TYPE electronic_mail RENAME TO email;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the owner of the type
+email
+to
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TYPE email OWNER TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To change the schema of the type
+email
+to
+customers:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TYPE email SET SCHEMA customers;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a new attribute to a composite type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TYPE compfoo ADD ATTRIBUTE f3 int;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To add a new value to an enum type in a particular sort position:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TYPE colors ADD VALUE \*(Aqorange\*(Aq AFTER \*(Aqred\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To rename an enum value:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER TYPE colors RENAME VALUE \*(Aqpurple\*(Aq TO \*(Aqmauve\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create binary I/O functions for an existing base type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION mytypesend(mytype) RETURNS bytea \&.\&.\&.;
+CREATE FUNCTION mytyperecv(internal, oid, integer) RETURNS mytype \&.\&.\&.;
+ALTER TYPE mytype SET (
+ SEND = mytypesend,
+ RECEIVE = mytyperecv
+);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The variants to add and drop attributes are part of the SQL standard; the other variants are PostgreSQL extensions\&.
+.SH "SEE ALSO"
+CREATE TYPE (\fBCREATE_TYPE\fR(7)), DROP TYPE (\fBDROP_TYPE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_USER.7 b/doc/src/sgml/man7/ALTER_USER.7
new file mode 100644
index 0000000..513823c
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_USER.7
@@ -0,0 +1,77 @@
+'\" t
+.\" Title: ALTER USER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER USER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_USER \- change a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER USER \fIrole_specification\fR [ WITH ] \fIoption\fR [ \&.\&.\&. ]
+
+where \fIoption\fR can be:
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT \fIconnlimit\fR
+ | [ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq | PASSWORD NULL
+ | VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+
+ALTER USER \fIname\fR RENAME TO \fInew_name\fR
+
+ALTER USER { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] SET \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | DEFAULT }
+ALTER USER { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] SET \fIconfiguration_parameter\fR FROM CURRENT
+ALTER USER { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] RESET \fIconfiguration_parameter\fR
+ALTER USER { \fIrole_specification\fR | ALL } [ IN DATABASE \fIdatabase_name\fR ] RESET ALL
+
+where \fIrole_specification\fR can be:
+
+ \fIrole_name\fR
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER USER\fR
+is now an alias for
+\fBALTER ROLE\fR\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBALTER USER\fR
+statement is a
+PostgreSQL
+extension\&. The SQL standard leaves the definition of users to the implementation\&.
+.SH "SEE ALSO"
+ALTER ROLE (\fBALTER_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_USER_MAPPING.7 b/doc/src/sgml/man7/ALTER_USER_MAPPING.7
new file mode 100644
index 0000000..7fe38e1
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_USER_MAPPING.7
@@ -0,0 +1,104 @@
+'\" t
+.\" Title: ALTER USER MAPPING
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER USER MAPPING" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_USER_MAPPING \- change the definition of a user mapping
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER USER MAPPING FOR { \fIuser_name\fR | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC }
+ SERVER \fIserver_name\fR
+ OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ] )
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER USER MAPPING\fR
+changes the definition of a user mapping\&.
+.PP
+The owner of a foreign server can alter user mappings for that server for any user\&. Also, a user can alter a user mapping for their own user name if
+USAGE
+privilege on the server has been granted to the user\&.
+.SH "PARAMETERS"
+.PP
+\fIuser_name\fR
+.RS 4
+User name of the mapping\&.
+CURRENT_ROLE,
+CURRENT_USER, and
+USER
+match the name of the current user\&.
+PUBLIC
+is used to match all present and future user names in the system\&.
+.RE
+.PP
+\fIserver_name\fR
+.RS 4
+Server name of the user mapping\&.
+.RE
+.PP
+OPTIONS ( [ ADD | SET | DROP ] \fIoption\fR [\*(Aq\fIvalue\fR\*(Aq] [, \&.\&.\&. ] )
+.RS 4
+Change options for the user mapping\&. The new options override any previously specified options\&.
+ADD,
+SET, and
+DROP
+specify the action to be performed\&.
+ADD
+is assumed if no operation is explicitly specified\&. Option names must be unique; options are also validated by the server\*(Aqs foreign\-data wrapper\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Change the password for user mapping
+bob, server
+foo:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER USER MAPPING FOR bob SERVER foo OPTIONS (SET password \*(Aqpublic\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER USER MAPPING\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&. There is a subtle syntax issue: The standard omits the
+FOR
+key word\&. Since both
+CREATE USER MAPPING
+and
+DROP USER MAPPING
+use
+FOR
+in analogous positions, and IBM DB2 (being the other major SQL/MED implementation) also requires it for
+ALTER USER MAPPING, PostgreSQL diverges from the standard here in the interest of consistency and interoperability\&.
+.SH "SEE ALSO"
+CREATE USER MAPPING (\fBCREATE_USER_MAPPING\fR(7)), DROP USER MAPPING (\fBDROP_USER_MAPPING\fR(7))
diff --git a/doc/src/sgml/man7/ALTER_VIEW.7 b/doc/src/sgml/man7/ALTER_VIEW.7
new file mode 100644
index 0000000..dd3cdbe
--- /dev/null
+++ b/doc/src/sgml/man7/ALTER_VIEW.7
@@ -0,0 +1,178 @@
+'\" t
+.\" Title: ALTER VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ALTER VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ALTER_VIEW \- change the definition of a view
+.SH "SYNOPSIS"
+.sp
+.nf
+ALTER VIEW [ IF EXISTS ] \fIname\fR ALTER [ COLUMN ] \fIcolumn_name\fR SET DEFAULT \fIexpression\fR
+ALTER VIEW [ IF EXISTS ] \fIname\fR ALTER [ COLUMN ] \fIcolumn_name\fR DROP DEFAULT
+ALTER VIEW [ IF EXISTS ] \fIname\fR OWNER TO { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER VIEW [ IF EXISTS ] \fIname\fR RENAME [ COLUMN ] \fIcolumn_name\fR TO \fInew_column_name\fR
+ALTER VIEW [ IF EXISTS ] \fIname\fR RENAME TO \fInew_name\fR
+ALTER VIEW [ IF EXISTS ] \fIname\fR SET SCHEMA \fInew_schema\fR
+ALTER VIEW [ IF EXISTS ] \fIname\fR SET ( \fIview_option_name\fR [= \fIview_option_value\fR] [, \&.\&.\&. ] )
+ALTER VIEW [ IF EXISTS ] \fIname\fR RESET ( \fIview_option_name\fR [, \&.\&.\&. ] )
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBALTER VIEW\fR
+changes various auxiliary properties of a view\&. (If you want to modify the view\*(Aqs defining query, use
+\fBCREATE OR REPLACE VIEW\fR\&.)
+.PP
+You must own the view to use
+\fBALTER VIEW\fR\&. To change a view\*(Aqs schema, you must also have
+CREATE
+privilege on the new schema\&. To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have
+CREATE
+privilege on the view\*(Aqs schema\&. (These restrictions enforce that altering the owner doesn\*(Aqt do anything you couldn\*(Aqt do by dropping and recreating the view\&. However, a superuser can alter ownership of any view anyway\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing view\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+Name of an existing column\&.
+.RE
+.PP
+\fInew_column_name\fR
+.RS 4
+New name for an existing column\&.
+.RE
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the view does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+SET/DROP DEFAULT
+.RS 4
+These forms set or remove the default value for a column\&. A view column\*(Aqs default value is substituted into any
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+command whose target is the view, before applying any rules or triggers for the view\&. The view\*(Aqs default will therefore take precedence over any default values from underlying relations\&.
+.RE
+.PP
+\fInew_owner\fR
+.RS 4
+The user name of the new owner of the view\&.
+.RE
+.PP
+\fInew_name\fR
+.RS 4
+The new name for the view\&.
+.RE
+.PP
+\fInew_schema\fR
+.RS 4
+The new schema for the view\&.
+.RE
+.PP
+SET ( \fIview_option_name\fR [= \fIview_option_value\fR] [, \&.\&.\&. ] )
+.br
+RESET ( \fIview_option_name\fR [, \&.\&.\&. ] )
+.RS 4
+Sets or resets a view option\&. Currently supported options are:
+.PP
+check_option (enum)
+.RS 4
+Changes the check option of the view\&. The value must be
+local
+or
+cascaded\&.
+.RE
+.PP
+security_barrier (boolean)
+.RS 4
+Changes the security\-barrier property of the view\&. The value must be a Boolean value, such as
+true
+or
+false\&.
+.RE
+.PP
+security_invoker (boolean)
+.RS 4
+Changes the security\-invoker property of the view\&. The value must be a Boolean value, such as
+true
+or
+false\&.
+.RE
+.RE
+.SH "NOTES"
+.PP
+For historical reasons,
+\fBALTER TABLE\fR
+can be used with views too; but the only variants of
+\fBALTER TABLE\fR
+that are allowed with views are equivalent to the ones shown above\&.
+.SH "EXAMPLES"
+.PP
+To rename the view
+foo
+to
+bar:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ALTER VIEW foo RENAME TO bar;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To attach a default column value to an updatable view:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE base_table (id int, ts timestamptz);
+CREATE VIEW a_view AS SELECT * FROM base_table;
+ALTER VIEW a_view ALTER COLUMN ts SET DEFAULT now();
+INSERT INTO base_table(id) VALUES(1); \-\- ts will receive a NULL
+INSERT INTO a_view(id) VALUES(2); \-\- ts will receive the current time
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBALTER VIEW\fR
+is a
+PostgreSQL
+extension of the SQL standard\&.
+.SH "SEE ALSO"
+CREATE VIEW (\fBCREATE_VIEW\fR(7)), DROP VIEW (\fBDROP_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/ANALYZE.7 b/doc/src/sgml/man7/ANALYZE.7
new file mode 100644
index 0000000..3da57cb
--- /dev/null
+++ b/doc/src/sgml/man7/ANALYZE.7
@@ -0,0 +1,215 @@
+'\" t
+.\" Title: ANALYZE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ANALYZE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ANALYZE \- collect statistics about a database
+.SH "SYNOPSIS"
+.sp
+.nf
+ANALYZE [ ( \fIoption\fR [, \&.\&.\&.] ) ] [ \fItable_and_columns\fR [, \&.\&.\&.] ]
+ANALYZE [ VERBOSE ] [ \fItable_and_columns\fR [, \&.\&.\&.] ]
+
+where \fIoption\fR can be one of:
+
+ VERBOSE [ \fIboolean\fR ]
+ SKIP_LOCKED [ \fIboolean\fR ]
+
+and \fItable_and_columns\fR is:
+
+ \fItable_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBANALYZE\fR
+collects statistics about the contents of tables in the database, and stores the results in the
+pg_statistic
+system catalog\&. Subsequently, the query planner uses these statistics to help determine the most efficient execution plans for queries\&.
+.PP
+Without a
+\fItable_and_columns\fR
+list,
+\fBANALYZE\fR
+processes every table and materialized view in the current database that the current user has permission to analyze\&. With a list,
+\fBANALYZE\fR
+processes only those table(s)\&. It is further possible to give a list of column names for a table, in which case only the statistics for those columns are collected\&.
+.PP
+When the option list is surrounded by parentheses, the options can be written in any order\&. The parenthesized syntax was added in
+PostgreSQL
+11; the unparenthesized syntax is deprecated\&.
+.SH "PARAMETERS"
+.PP
+VERBOSE
+.RS 4
+Enables display of progress messages\&.
+.RE
+.PP
+SKIP_LOCKED
+.RS 4
+Specifies that
+\fBANALYZE\fR
+should not wait for any conflicting locks to be released when beginning work on a relation: if a relation cannot be locked immediately without waiting, the relation is skipped\&. Note that even with this option,
+\fBANALYZE\fR
+may still block when opening the relation\*(Aqs indexes or when acquiring sample rows from partitions, table inheritance children, and some types of foreign tables\&. Also, while
+\fBANALYZE\fR
+ordinarily processes all partitions of specified partitioned tables, this option will cause
+\fBANALYZE\fR
+to skip all partitions if there is a conflicting lock on the partitioned table\&.
+.RE
+.PP
+\fIboolean\fR
+.RS 4
+Specifies whether the selected option should be turned on or off\&. You can write
+TRUE,
+ON, or
+1
+to enable the option, and
+FALSE,
+OFF, or
+0
+to disable it\&. The
+\fIboolean\fR
+value can also be omitted, in which case
+TRUE
+is assumed\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (possibly schema\-qualified) of a specific table to analyze\&. If omitted, all regular tables, partitioned tables, and materialized views in the current database are analyzed (but not foreign tables)\&. If the specified table is a partitioned table, both the inheritance statistics of the partitioned table as a whole and statistics of the individual partitions are updated\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a specific column to analyze\&. Defaults to all columns\&.
+.RE
+.SH "OUTPUTS"
+.PP
+When
+VERBOSE
+is specified,
+\fBANALYZE\fR
+emits progress messages to indicate which table is currently being processed\&. Various statistics about the tables are printed as well\&.
+.SH "NOTES"
+.PP
+To analyze a table, one must ordinarily be the table\*(Aqs owner or a superuser\&. However, database owners are allowed to analyze all tables in their databases, except shared catalogs\&. (The restriction for shared catalogs means that a true database\-wide
+\fBANALYZE\fR
+can only be performed by a superuser\&.)
+\fBANALYZE\fR
+will skip over any tables that the calling user does not have permission to analyze\&.
+.PP
+Foreign tables are analyzed only when explicitly selected\&. Not all foreign data wrappers support
+\fBANALYZE\fR\&. If the table\*(Aqs wrapper does not support
+\fBANALYZE\fR, the command prints a warning and does nothing\&.
+.PP
+In the default
+PostgreSQL
+configuration, the autovacuum daemon (see
+Section\ \&25.1.6) takes care of automatic analyzing of tables when they are first loaded with data, and as they change throughout regular operation\&. When autovacuum is disabled, it is a good idea to run
+\fBANALYZE\fR
+periodically, or just after making major changes in the contents of a table\&. Accurate statistics will help the planner to choose the most appropriate query plan, and thereby improve the speed of query processing\&. A common strategy for read\-mostly databases is to run
+\fBVACUUM\fR
+and
+\fBANALYZE\fR
+once a day during a low\-usage time of day\&. (This will not be sufficient if there is heavy update activity\&.)
+.PP
+\fBANALYZE\fR
+requires only a read lock on the target table, so it can run in parallel with other activity on the table\&.
+.PP
+The statistics collected by
+\fBANALYZE\fR
+usually include a list of some of the most common values in each column and a histogram showing the approximate data distribution in each column\&. One or both of these can be omitted if
+\fBANALYZE\fR
+deems them uninteresting (for example, in a unique\-key column, there are no common values) or if the column data type does not support the appropriate operators\&. There is more information about the statistics in
+Chapter\ \&25\&.
+.PP
+For large tables,
+\fBANALYZE\fR
+takes a random sample of the table contents, rather than examining every row\&. This allows even very large tables to be analyzed in a small amount of time\&. Note, however, that the statistics are only approximate, and will change slightly each time
+\fBANALYZE\fR
+is run, even if the actual table contents did not change\&. This might result in small changes in the planner\*(Aqs estimated costs shown by
+\fBEXPLAIN\fR\&. In rare situations, this non\-determinism will cause the planner\*(Aqs choices of query plans to change after
+\fBANALYZE\fR
+is run\&. To avoid this, raise the amount of statistics collected by
+\fBANALYZE\fR, as described below\&.
+.PP
+The extent of analysis can be controlled by adjusting the
+default_statistics_target
+configuration variable, or on a column\-by\-column basis by setting the per\-column statistics target with
+\fBALTER TABLE \&.\&.\&. ALTER COLUMN \&.\&.\&. SET STATISTICS\fR\&. The target value sets the maximum number of entries in the most\-common\-value list and the maximum number of bins in the histogram\&. The default target value is 100, but this can be adjusted up or down to trade off accuracy of planner estimates against the time taken for
+\fBANALYZE\fR
+and the amount of space occupied in
+pg_statistic\&. In particular, setting the statistics target to zero disables collection of statistics for that column\&. It might be useful to do that for columns that are never used as part of the
+WHERE,
+GROUP BY, or
+ORDER BY
+clauses of queries, since the planner will have no use for statistics on such columns\&.
+.PP
+The largest statistics target among the columns being analyzed determines the number of table rows sampled to prepare the statistics\&. Increasing the target causes a proportional increase in the time and space needed to do
+\fBANALYZE\fR\&.
+.PP
+One of the values estimated by
+\fBANALYZE\fR
+is the number of distinct values that appear in each column\&. Because only a subset of the rows are examined, this estimate can sometimes be quite inaccurate, even with the largest possible statistics target\&. If this inaccuracy leads to bad query plans, a more accurate value can be determined manually and then installed with
+\fBALTER TABLE \&.\&.\&. ALTER COLUMN \&.\&.\&. SET (n_distinct = \&.\&.\&.)\fR\&.
+.PP
+If the table being analyzed has inheritance children,
+\fBANALYZE\fR
+gathers two sets of statistics: one on the rows of the parent table only, and a second including rows of both the parent table and all of its children\&. This second set of statistics is needed when planning queries that process the inheritance tree as a whole\&. The child tables themselves are not individually analyzed in this case\&. The autovacuum daemon, however, will only consider inserts or updates on the parent table itself when deciding whether to trigger an automatic analyze for that table\&. If that table is rarely inserted into or updated, the inheritance statistics will not be up to date unless you run
+\fBANALYZE\fR
+manually\&.
+.PP
+For partitioned tables,
+\fBANALYZE\fR
+gathers statistics by sampling rows from all partitions; in addition, it will recurse into each partition and update its statistics\&. Each leaf partition is analyzed only once, even with multi\-level partitioning\&. No statistics are collected for only the parent table (without data from its partitions), because with partitioning it\*(Aqs guaranteed to be empty\&.
+.PP
+The autovacuum daemon does not process partitioned tables, nor does it process inheritance parents if only the children are ever modified\&. It is usually necessary to periodically run a manual
+\fBANALYZE\fR
+to keep the statistics of the table hierarchy up to date\&.
+.PP
+If any child tables or partitions are foreign tables whose foreign data wrappers do not support
+\fBANALYZE\fR, those tables are ignored while gathering inheritance statistics\&.
+.PP
+If the table being analyzed is completely empty,
+\fBANALYZE\fR
+will not record new statistics for that table\&. Any existing statistics will be retained\&.
+.PP
+Each backend running
+\fBANALYZE\fR
+will report its progress in the
+pg_stat_progress_analyze
+view\&. See
+Section\ \&28.4.1
+for details\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBANALYZE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBVACUUM\fR(7), \fBvacuumdb\fR(1), Section\ \&20.4.4, Section\ \&25.1.6, Section\ \&28.4.1
diff --git a/doc/src/sgml/man7/BEGIN.7 b/doc/src/sgml/man7/BEGIN.7
new file mode 100644
index 0000000..36dfffc
--- /dev/null
+++ b/doc/src/sgml/man7/BEGIN.7
@@ -0,0 +1,128 @@
+'\" t
+.\" Title: BEGIN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "BEGIN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+BEGIN \- start a transaction block
+.SH "SYNOPSIS"
+.sp
+.nf
+BEGIN [ WORK | TRANSACTION ] [ \fItransaction_mode\fR [, \&.\&.\&.] ]
+
+where \fItransaction_mode\fR is one of:
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBBEGIN\fR
+initiates a transaction block, that is, all statements after a
+\fBBEGIN\fR
+command will be executed in a single transaction until an explicit
+\fBCOMMIT\fR
+or
+\fBROLLBACK\fR
+is given\&. By default (without
+\fBBEGIN\fR),
+PostgreSQL
+executes transactions in
+\(lqautocommit\(rq
+mode, that is, each statement is executed in its own transaction and a commit is implicitly performed at the end of the statement (if execution was successful, otherwise a rollback is done)\&.
+.PP
+Statements are executed more quickly in a transaction block, because transaction start/commit requires significant CPU and disk activity\&. Execution of multiple statements inside a transaction is also useful to ensure consistency when making several related changes: other sessions will be unable to see the intermediate states wherein not all the related updates have been done\&.
+.PP
+If the isolation level, read/write mode, or deferrable mode is specified, the new transaction has those characteristics, as if
+\fBSET TRANSACTION\fR
+was executed\&.
+.SH "PARAMETERS"
+.PP
+WORK
+.br
+TRANSACTION
+.RS 4
+Optional key words\&. They have no effect\&.
+.RE
+.PP
+Refer to
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))
+for information on the meaning of the other parameters to this statement\&.
+.SH "NOTES"
+.PP
+\fBSTART TRANSACTION\fR
+has the same functionality as
+\fBBEGIN\fR\&.
+.PP
+Use
+\fBCOMMIT\fR
+or
+\fBROLLBACK\fR
+to terminate a transaction block\&.
+.PP
+Issuing
+\fBBEGIN\fR
+when already inside a transaction block will provoke a warning message\&. The state of the transaction is not affected\&. To nest transactions within a transaction block, use savepoints (see
+\fBSAVEPOINT\fR(7))\&.
+.PP
+For reasons of backwards compatibility, the commas between successive
+\fItransaction_modes\fR
+can be omitted\&.
+.SH "EXAMPLES"
+.PP
+To begin a transaction block:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBBEGIN\fR
+is a
+PostgreSQL
+language extension\&. It is equivalent to the SQL\-standard command
+\fBSTART TRANSACTION\fR, whose reference page contains additional compatibility information\&.
+.PP
+The
+DEFERRABLE
+\fItransaction_mode\fR
+is a
+PostgreSQL
+language extension\&.
+.PP
+Incidentally, the
+BEGIN
+key word is used for a different purpose in embedded SQL\&. You are advised to be careful about the transaction semantics when porting database applications\&.
+.SH "SEE ALSO"
+\fBCOMMIT\fR(7), \fBROLLBACK\fR(7), START TRANSACTION (\fBSTART_TRANSACTION\fR(7)), \fBSAVEPOINT\fR(7)
diff --git a/doc/src/sgml/man7/CALL.7 b/doc/src/sgml/man7/CALL.7
new file mode 100644
index 0000000..221d7a8
--- /dev/null
+++ b/doc/src/sgml/man7/CALL.7
@@ -0,0 +1,108 @@
+'\" t
+.\" Title: CALL
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CALL" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CALL \- invoke a procedure
+.SH "SYNOPSIS"
+.sp
+.nf
+CALL \fIname\fR ( [ \fIargument\fR ] [, \&.\&.\&.] )
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCALL\fR
+executes a procedure\&.
+.PP
+If the procedure has any output parameters, then a result row will be returned, containing the values of those parameters\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the procedure\&.
+.RE
+.PP
+\fIargument\fR
+.RS 4
+An argument expression for the procedure call\&.
+.sp
+Arguments can include parameter names, using the syntax
+\fIname\fR => \fIvalue\fR\&. This works the same as in ordinary function calls; see
+Section\ \&4.3
+for details\&.
+.sp
+Arguments must be supplied for all procedure parameters that lack defaults, including
+OUT
+parameters\&. However, arguments matching
+OUT
+parameters are not evaluated, so it\*(Aqs customary to just write
+NULL
+for them\&. (Writing something else for an
+OUT
+parameter might cause compatibility problems with future
+PostgreSQL
+versions\&.)
+.RE
+.SH "NOTES"
+.PP
+The user must have
+EXECUTE
+privilege on the procedure in order to be allowed to invoke it\&.
+.PP
+To call a function (not a procedure), use
+\fBSELECT\fR
+instead\&.
+.PP
+If
+\fBCALL\fR
+is executed in a transaction block, then the called procedure cannot execute transaction control statements\&. Transaction control statements are only allowed if
+\fBCALL\fR
+is executed in its own transaction\&.
+.PP
+PL/pgSQL
+handles output parameters in
+\fBCALL\fR
+commands differently; see
+Section\ \&43.6.3\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CALL do_db_maintenance();
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCALL\fR
+conforms to the SQL standard, except for the handling of output parameters\&. The standard says that users should write variables to receive the values of output parameters\&.
+.SH "SEE ALSO"
+CREATE PROCEDURE (\fBCREATE_PROCEDURE\fR(7))
diff --git a/doc/src/sgml/man7/CHECKPOINT.7 b/doc/src/sgml/man7/CHECKPOINT.7
new file mode 100644
index 0000000..d90ff23
--- /dev/null
+++ b/doc/src/sgml/man7/CHECKPOINT.7
@@ -0,0 +1,65 @@
+'\" t
+.\" Title: CHECKPOINT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CHECKPOINT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CHECKPOINT \- force a write\-ahead log checkpoint
+.SH "SYNOPSIS"
+.sp
+.nf
+CHECKPOINT
+.fi
+.SH "DESCRIPTION"
+.PP
+A checkpoint is a point in the write\-ahead log sequence at which all data files have been updated to reflect the information in the log\&. All data files will be flushed to disk\&. Refer to
+Section\ \&30.5
+for more details about what happens during a checkpoint\&.
+.PP
+The
+\fBCHECKPOINT\fR
+command forces an immediate checkpoint when the command is issued, without waiting for a regular checkpoint scheduled by the system (controlled by the settings in
+Section\ \&20.5.2)\&.
+\fBCHECKPOINT\fR
+is not intended for use during normal operation\&.
+.PP
+If executed during recovery, the
+\fBCHECKPOINT\fR
+command will force a restartpoint (see
+Section\ \&30.5) rather than writing a new checkpoint\&.
+.PP
+Only superusers or users with the privileges of the
+pg_checkpoint
+role can call
+\fBCHECKPOINT\fR\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCHECKPOINT\fR
+command is a
+PostgreSQL
+language extension\&.
diff --git a/doc/src/sgml/man7/CLOSE.7 b/doc/src/sgml/man7/CLOSE.7
new file mode 100644
index 0000000..e43991e
--- /dev/null
+++ b/doc/src/sgml/man7/CLOSE.7
@@ -0,0 +1,99 @@
+'\" t
+.\" Title: CLOSE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CLOSE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CLOSE \- close a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+CLOSE { \fIname\fR | ALL }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCLOSE\fR
+frees the resources associated with an open cursor\&. After the cursor is closed, no subsequent operations are allowed on it\&. A cursor should be closed when it is no longer needed\&.
+.PP
+Every non\-holdable open cursor is implicitly closed when a transaction is terminated by
+\fBCOMMIT\fR
+or
+\fBROLLBACK\fR\&. A holdable cursor is implicitly closed if the transaction that created it aborts via
+\fBROLLBACK\fR\&. If the creating transaction successfully commits, the holdable cursor remains open until an explicit
+\fBCLOSE\fR
+is executed, or the client disconnects\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of an open cursor to close\&.
+.RE
+.PP
+ALL
+.RS 4
+Close all open cursors\&.
+.RE
+.SH "NOTES"
+.PP
+PostgreSQL
+does not have an explicit
+\fBOPEN\fR
+cursor statement; a cursor is considered open when it is declared\&. Use the
+\fBDECLARE\fR
+statement to declare a cursor\&.
+.PP
+You can see all available cursors by querying the
+pg_cursors
+system view\&.
+.PP
+If a cursor is closed after a savepoint which is later rolled back, the
+\fBCLOSE\fR
+is not rolled back; that is, the cursor remains closed\&.
+.SH "EXAMPLES"
+.PP
+Close the cursor
+liahona:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CLOSE liahona;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCLOSE\fR
+is fully conforming with the SQL standard\&.
+\fBCLOSE ALL\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+\fBDECLARE\fR(7), \fBFETCH\fR(7), \fBMOVE\fR(7)
diff --git a/doc/src/sgml/man7/CLUSTER.7 b/doc/src/sgml/man7/CLUSTER.7
new file mode 100644
index 0000000..9d2567b
--- /dev/null
+++ b/doc/src/sgml/man7/CLUSTER.7
@@ -0,0 +1,219 @@
+'\" t
+.\" Title: CLUSTER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CLUSTER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CLUSTER \- cluster a table according to an index
+.SH "SYNOPSIS"
+.sp
+.nf
+CLUSTER [VERBOSE] \fItable_name\fR [ USING \fIindex_name\fR ]
+CLUSTER ( \fIoption\fR [, \&.\&.\&.] ) \fItable_name\fR [ USING \fIindex_name\fR ]
+CLUSTER [VERBOSE]
+
+where \fIoption\fR can be one of:
+
+ VERBOSE [ \fIboolean\fR ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCLUSTER\fR
+instructs
+PostgreSQL
+to cluster the table specified by
+\fItable_name\fR
+based on the index specified by
+\fIindex_name\fR\&. The index must already have been defined on
+\fItable_name\fR\&.
+.PP
+When a table is clustered, it is physically reordered based on the index information\&. Clustering is a one\-time operation: when the table is subsequently updated, the changes are not clustered\&. That is, no attempt is made to store new or updated rows according to their index order\&. (If one wishes, one can periodically recluster by issuing the command again\&. Also, setting the table\*(Aqs
+fillfactor
+storage parameter to less than 100% can aid in preserving cluster ordering during updates, since updated rows are kept on the same page if enough space is available there\&.)
+.PP
+When a table is clustered,
+PostgreSQL
+remembers which index it was clustered by\&. The form
+\fBCLUSTER \fR\fB\fItable_name\fR\fR
+reclusters the table using the same index as before\&. You can also use the
+CLUSTER
+or
+SET WITHOUT CLUSTER
+forms of
+\fBALTER TABLE\fR
+to set the index to be used for future cluster operations, or to clear any previous setting\&.
+.PP
+\fBCLUSTER\fR
+without any parameter reclusters all the previously\-clustered tables in the current database that the calling user owns, or all such tables if called by a superuser\&. This form of
+\fBCLUSTER\fR
+cannot be executed inside a transaction block\&.
+.PP
+When a table is being clustered, an
+ACCESS EXCLUSIVE
+lock is acquired on it\&. This prevents any other database operations (both reads and writes) from operating on the table until the
+\fBCLUSTER\fR
+is finished\&.
+.SH "PARAMETERS"
+.PP
+\fItable_name\fR
+.RS 4
+The name (possibly schema\-qualified) of a table\&.
+.RE
+.PP
+\fIindex_name\fR
+.RS 4
+The name of an index\&.
+.RE
+.PP
+VERBOSE
+.RS 4
+Prints a progress report as each table is clustered\&.
+.RE
+.PP
+\fIboolean\fR
+.RS 4
+Specifies whether the selected option should be turned on or off\&. You can write
+TRUE,
+ON, or
+1
+to enable the option, and
+FALSE,
+OFF, or
+0
+to disable it\&. The
+\fIboolean\fR
+value can also be omitted, in which case
+TRUE
+is assumed\&.
+.RE
+.SH "NOTES"
+.PP
+In cases where you are accessing single rows randomly within a table, the actual order of the data in the table is unimportant\&. However, if you tend to access some data more than others, and there is an index that groups them together, you will benefit from using
+\fBCLUSTER\fR\&. If you are requesting a range of indexed values from a table, or a single indexed value that has multiple rows that match,
+\fBCLUSTER\fR
+will help because once the index identifies the table page for the first row that matches, all other rows that match are probably already on the same table page, and so you save disk accesses and speed up the query\&.
+.PP
+\fBCLUSTER\fR
+can re\-sort the table using either an index scan on the specified index, or (if the index is a b\-tree) a sequential scan followed by sorting\&. It will attempt to choose the method that will be faster, based on planner cost parameters and available statistical information\&.
+.PP
+When an index scan is used, a temporary copy of the table is created that contains the table data in the index order\&. Temporary copies of each index on the table are created as well\&. Therefore, you need free space on disk at least equal to the sum of the table size and the index sizes\&.
+.PP
+When a sequential scan and sort is used, a temporary sort file is also created, so that the peak temporary space requirement is as much as double the table size, plus the index sizes\&. This method is often faster than the index scan method, but if the disk space requirement is intolerable, you can disable this choice by temporarily setting
+enable_sort
+to
+off\&.
+.PP
+It is advisable to set
+maintenance_work_mem
+to a reasonably large value (but not more than the amount of RAM you can dedicate to the
+\fBCLUSTER\fR
+operation) before clustering\&.
+.PP
+Because the planner records statistics about the ordering of tables, it is advisable to run
+\fBANALYZE\fR
+on the newly clustered table\&. Otherwise, the planner might make poor choices of query plans\&.
+.PP
+Because
+\fBCLUSTER\fR
+remembers which indexes are clustered, one can cluster the tables one wants clustered manually the first time, then set up a periodic maintenance script that executes
+\fBCLUSTER\fR
+without any parameters, so that the desired tables are periodically reclustered\&.
+.PP
+Each backend running
+\fBCLUSTER\fR
+will report its progress in the
+pg_stat_progress_cluster
+view\&. See
+Section\ \&28.4.4
+for details\&.
+.PP
+Clustering a partitioned table clusters each of its partitions using the partition of the specified partitioned index\&. When clustering a partitioned table, the index may not be omitted\&.
+.SH "EXAMPLES"
+.PP
+Cluster the table
+employees
+on the basis of its index
+employees_ind:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CLUSTER employees USING employees_ind;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Cluster the
+employees
+table using the same index that was used before:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CLUSTER employees;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Cluster all tables in the database that have previously been clustered:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CLUSTER;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCLUSTER\fR
+statement in the SQL standard\&.
+.PP
+The syntax
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CLUSTER \fIindex_name\fR ON \fItable_name\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+is also supported for compatibility with pre\-8\&.3
+PostgreSQL
+versions\&.
+.SH "SEE ALSO"
+\fBclusterdb\fR(1), Section\ \&28.4.4
diff --git a/doc/src/sgml/man7/COMMENT.7 b/doc/src/sgml/man7/COMMENT.7
new file mode 100644
index 0000000..2847f07
--- /dev/null
+++ b/doc/src/sgml/man7/COMMENT.7
@@ -0,0 +1,324 @@
+'\" t
+.\" Title: COMMENT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "COMMENT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+COMMENT \- define or change the comment of an object
+.SH "SYNOPSIS"
+.sp
+.nf
+COMMENT ON
+{
+ ACCESS METHOD \fIobject_name\fR |
+ AGGREGATE \fIaggregate_name\fR ( \fIaggregate_signature\fR ) |
+ CAST (\fIsource_type\fR AS \fItarget_type\fR) |
+ COLLATION \fIobject_name\fR |
+ COLUMN \fIrelation_name\fR\&.\fIcolumn_name\fR |
+ CONSTRAINT \fIconstraint_name\fR ON \fItable_name\fR |
+ CONSTRAINT \fIconstraint_name\fR ON DOMAIN \fIdomain_name\fR |
+ CONVERSION \fIobject_name\fR |
+ DATABASE \fIobject_name\fR |
+ DOMAIN \fIobject_name\fR |
+ EXTENSION \fIobject_name\fR |
+ EVENT TRIGGER \fIobject_name\fR |
+ FOREIGN DATA WRAPPER \fIobject_name\fR |
+ FOREIGN TABLE \fIobject_name\fR |
+ FUNCTION \fIfunction_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ INDEX \fIobject_name\fR |
+ LARGE OBJECT \fIlarge_object_oid\fR |
+ MATERIALIZED VIEW \fIobject_name\fR |
+ OPERATOR \fIoperator_name\fR (\fIleft_type\fR, \fIright_type\fR) |
+ OPERATOR CLASS \fIobject_name\fR USING \fIindex_method\fR |
+ OPERATOR FAMILY \fIobject_name\fR USING \fIindex_method\fR |
+ POLICY \fIpolicy_name\fR ON \fItable_name\fR |
+ [ PROCEDURAL ] LANGUAGE \fIobject_name\fR |
+ PROCEDURE \fIprocedure_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ PUBLICATION \fIobject_name\fR |
+ ROLE \fIobject_name\fR |
+ ROUTINE \fIroutine_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ RULE \fIrule_name\fR ON \fItable_name\fR |
+ SCHEMA \fIobject_name\fR |
+ SEQUENCE \fIobject_name\fR |
+ SERVER \fIobject_name\fR |
+ STATISTICS \fIobject_name\fR |
+ SUBSCRIPTION \fIobject_name\fR |
+ TABLE \fIobject_name\fR |
+ TABLESPACE \fIobject_name\fR |
+ TEXT SEARCH CONFIGURATION \fIobject_name\fR |
+ TEXT SEARCH DICTIONARY \fIobject_name\fR |
+ TEXT SEARCH PARSER \fIobject_name\fR |
+ TEXT SEARCH TEMPLATE \fIobject_name\fR |
+ TRANSFORM FOR \fItype_name\fR LANGUAGE \fIlang_name\fR |
+ TRIGGER \fItrigger_name\fR ON \fItable_name\fR |
+ TYPE \fIobject_name\fR |
+ VIEW \fIobject_name\fR
+} IS { \fIstring_literal\fR | NULL }
+
+where \fIaggregate_signature\fR is:
+
+* |
+[ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] |
+[ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] ] ORDER BY [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCOMMENT\fR
+stores a comment about a database object\&.
+.PP
+Only one comment string is stored for each object, so to modify a comment, issue a new
+\fBCOMMENT\fR
+command for the same object\&. To remove a comment, write
+NULL
+in place of the text string\&. Comments are automatically dropped when their object is dropped\&.
+.PP
+A
+SHARE UPDATE EXCLUSIVE
+lock is acquired on the object to be commented\&.
+.PP
+For most kinds of object, only the object\*(Aqs owner can set the comment\&. Roles don\*(Aqt have owners, so the rule for
+COMMENT ON ROLE
+is that you must be superuser to comment on a superuser role, or have the
+CREATEROLE
+privilege to comment on non\-superuser roles\&. Likewise, access methods don\*(Aqt have owners either; you must be superuser to comment on an access method\&. Of course, a superuser can comment on anything\&.
+.PP
+Comments can be viewed using
+psql\*(Aqs
+\fB\ed\fR
+family of commands\&. Other user interfaces to retrieve comments can be built atop the same built\-in functions that
+psql
+uses, namely
+\fBobj_description\fR,
+\fBcol_description\fR, and
+\fBshobj_description\fR
+(see
+Table\ \&9.77)\&.
+.SH "PARAMETERS"
+.PP
+\fIobject_name\fR
+.br
+\fIrelation_name\fR\&.\fIcolumn_name\fR
+.br
+\fIaggregate_name\fR
+.br
+\fIconstraint_name\fR
+.br
+\fIfunction_name\fR
+.br
+\fIoperator_name\fR
+.br
+\fIpolicy_name\fR
+.br
+\fIprocedure_name\fR
+.br
+\fIroutine_name\fR
+.br
+\fIrule_name\fR
+.br
+\fItrigger_name\fR
+.RS 4
+The name of the object to be commented\&. Names of objects that reside in schemas (tables, functions, etc\&.) can be schema\-qualified\&. When commenting on a column,
+\fIrelation_name\fR
+must refer to a table, view, composite type, or foreign table\&.
+.RE
+.PP
+\fItable_name\fR
+.br
+\fIdomain_name\fR
+.RS 4
+When creating a comment on a constraint, a trigger, a rule or a policy these parameters specify the name of the table or domain on which that object is defined\&.
+.RE
+.PP
+\fIsource_type\fR
+.RS 4
+The name of the source data type of the cast\&.
+.RE
+.PP
+\fItarget_type\fR
+.RS 4
+The name of the target data type of the cast\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of a function, procedure, or aggregate argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&. Note that
+\fBCOMMENT\fR
+does not actually pay any attention to
+OUT
+arguments, since only the input arguments are needed to determine the function\*(Aqs identity\&. So it is sufficient to list the
+IN,
+INOUT, and
+VARIADIC
+arguments\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of a function, procedure, or aggregate argument\&. Note that
+\fBCOMMENT\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type of a function, procedure, or aggregate argument\&.
+.RE
+.PP
+\fIlarge_object_oid\fR
+.RS 4
+The OID of the large object\&.
+.RE
+.PP
+\fIleft_type\fR
+.br
+\fIright_type\fR
+.RS 4
+The data type(s) of the operator\*(Aqs arguments (optionally schema\-qualified)\&. Write
+NONE
+for the missing argument of a prefix operator\&.
+.RE
+.PP
+PROCEDURAL
+.RS 4
+This is a noise word\&.
+.RE
+.PP
+\fItype_name\fR
+.RS 4
+The name of the data type of the transform\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the language of the transform\&.
+.RE
+.PP
+\fIstring_literal\fR
+.RS 4
+The new comment contents, written as a string literal\&.
+.RE
+.PP
+NULL
+.RS 4
+Write
+NULL
+to drop the comment\&.
+.RE
+.SH "NOTES"
+.PP
+There is presently no security mechanism for viewing comments: any user connected to a database can see all the comments for objects in that database\&. For shared objects such as databases, roles, and tablespaces, comments are stored globally so any user connected to any database in the cluster can see all the comments for shared objects\&. Therefore, don\*(Aqt put security\-critical information in comments\&.
+.SH "EXAMPLES"
+.PP
+Attach a comment to the table
+mytable:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COMMENT ON TABLE mytable IS \*(AqThis is my table\&.\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Remove it again:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COMMENT ON TABLE mytable IS NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Some more examples:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COMMENT ON ACCESS METHOD gin IS \*(AqGIN index access method\*(Aq;
+COMMENT ON AGGREGATE my_aggregate (double precision) IS \*(AqComputes sample variance\*(Aq;
+COMMENT ON CAST (text AS int4) IS \*(AqAllow casts from text to int4\*(Aq;
+COMMENT ON COLLATION "fr_CA" IS \*(AqCanadian French\*(Aq;
+COMMENT ON COLUMN my_table\&.my_column IS \*(AqEmployee ID number\*(Aq;
+COMMENT ON CONVERSION my_conv IS \*(AqConversion to UTF8\*(Aq;
+COMMENT ON CONSTRAINT bar_col_cons ON bar IS \*(AqConstrains column col\*(Aq;
+COMMENT ON CONSTRAINT dom_col_constr ON DOMAIN dom IS \*(AqConstrains col of domain\*(Aq;
+COMMENT ON DATABASE my_database IS \*(AqDevelopment Database\*(Aq;
+COMMENT ON DOMAIN my_domain IS \*(AqEmail Address Domain\*(Aq;
+COMMENT ON EVENT TRIGGER abort_ddl IS \*(AqAborts all DDL commands\*(Aq;
+COMMENT ON EXTENSION hstore IS \*(Aqimplements the hstore data type\*(Aq;
+COMMENT ON FOREIGN DATA WRAPPER mywrapper IS \*(Aqmy foreign data wrapper\*(Aq;
+COMMENT ON FOREIGN TABLE my_foreign_table IS \*(AqEmployee Information in other database\*(Aq;
+COMMENT ON FUNCTION my_function (timestamp) IS \*(AqReturns Roman Numeral\*(Aq;
+COMMENT ON INDEX my_index IS \*(AqEnforces uniqueness on employee ID\*(Aq;
+COMMENT ON LANGUAGE plpython IS \*(AqPython support for stored procedures\*(Aq;
+COMMENT ON LARGE OBJECT 346344 IS \*(AqPlanning document\*(Aq;
+COMMENT ON MATERIALIZED VIEW my_matview IS \*(AqSummary of order history\*(Aq;
+COMMENT ON OPERATOR ^ (text, text) IS \*(AqPerforms intersection of two texts\*(Aq;
+COMMENT ON OPERATOR \- (NONE, integer) IS \*(AqUnary minus\*(Aq;
+COMMENT ON OPERATOR CLASS int4ops USING btree IS \*(Aq4 byte integer operators for btrees\*(Aq;
+COMMENT ON OPERATOR FAMILY integer_ops USING btree IS \*(Aqall integer operators for btrees\*(Aq;
+COMMENT ON POLICY my_policy ON mytable IS \*(AqFilter rows by users\*(Aq;
+COMMENT ON PROCEDURE my_proc (integer, integer) IS \*(AqRuns a report\*(Aq;
+COMMENT ON PUBLICATION alltables IS \*(AqPublishes all operations on all tables\*(Aq;
+COMMENT ON ROLE my_role IS \*(AqAdministration group for finance tables\*(Aq;
+COMMENT ON ROUTINE my_routine (integer, integer) IS \*(AqRuns a routine (which is a function or procedure)\*(Aq;
+COMMENT ON RULE my_rule ON my_table IS \*(AqLogs updates of employee records\*(Aq;
+COMMENT ON SCHEMA my_schema IS \*(AqDepartmental data\*(Aq;
+COMMENT ON SEQUENCE my_sequence IS \*(AqUsed to generate primary keys\*(Aq;
+COMMENT ON SERVER myserver IS \*(Aqmy foreign server\*(Aq;
+COMMENT ON STATISTICS my_statistics IS \*(AqImproves planner row estimations\*(Aq;
+COMMENT ON SUBSCRIPTION alltables IS \*(AqSubscription for all operations on all tables\*(Aq;
+COMMENT ON TABLE my_schema\&.my_table IS \*(AqEmployee Information\*(Aq;
+COMMENT ON TABLESPACE my_tablespace IS \*(AqTablespace for indexes\*(Aq;
+COMMENT ON TEXT SEARCH CONFIGURATION my_config IS \*(AqSpecial word filtering\*(Aq;
+COMMENT ON TEXT SEARCH DICTIONARY swedish IS \*(AqSnowball stemmer for Swedish language\*(Aq;
+COMMENT ON TEXT SEARCH PARSER my_parser IS \*(AqSplits text into words\*(Aq;
+COMMENT ON TEXT SEARCH TEMPLATE snowball IS \*(AqSnowball stemmer\*(Aq;
+COMMENT ON TRANSFORM FOR hstore LANGUAGE plpython3u IS \*(AqTransform between hstore and Python dict\*(Aq;
+COMMENT ON TRIGGER my_trigger ON my_table IS \*(AqUsed for RI\*(Aq;
+COMMENT ON TYPE complex IS \*(AqComplex number data type\*(Aq;
+COMMENT ON VIEW my_view IS \*(AqView of departmental costs\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCOMMENT\fR
+command in the SQL standard\&.
diff --git a/doc/src/sgml/man7/COMMIT.7 b/doc/src/sgml/man7/COMMIT.7
new file mode 100644
index 0000000..0316635
--- /dev/null
+++ b/doc/src/sgml/man7/COMMIT.7
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: COMMIT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "COMMIT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+COMMIT \- commit the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCOMMIT\fR
+commits the current transaction\&. All changes made by the transaction become visible to others and are guaranteed to be durable if a crash occurs\&.
+.SH "PARAMETERS"
+.PP
+WORK
+.br
+TRANSACTION
+.RS 4
+Optional key words\&. They have no effect\&.
+.RE
+.PP
+AND CHAIN
+.RS 4
+If
+AND CHAIN
+is specified, a new transaction is immediately started with the same transaction characteristics (see
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))) as the just finished one\&. Otherwise, no new transaction is started\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBROLLBACK\fR(7)
+to abort a transaction\&.
+.PP
+Issuing
+\fBCOMMIT\fR
+when not inside a transaction does no harm, but it will provoke a warning message\&.
+\fBCOMMIT AND CHAIN\fR
+when not inside a transaction is an error\&.
+.SH "EXAMPLES"
+.PP
+To commit the current transaction and make all changes permanent:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The command
+\fBCOMMIT\fR
+conforms to the SQL standard\&. The form
+COMMIT TRANSACTION
+is a PostgreSQL extension\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBROLLBACK\fR(7)
diff --git a/doc/src/sgml/man7/COMMIT_PREPARED.7 b/doc/src/sgml/man7/COMMIT_PREPARED.7
new file mode 100644
index 0000000..152f621
--- /dev/null
+++ b/doc/src/sgml/man7/COMMIT_PREPARED.7
@@ -0,0 +1,77 @@
+'\" t
+.\" Title: COMMIT PREPARED
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "COMMIT PREPARED" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+COMMIT_PREPARED \- commit a transaction that was earlier prepared for two\-phase commit
+.SH "SYNOPSIS"
+.sp
+.nf
+COMMIT PREPARED \fItransaction_id\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCOMMIT PREPARED\fR
+commits a transaction that is in prepared state\&.
+.SH "PARAMETERS"
+.PP
+\fItransaction_id\fR
+.RS 4
+The transaction identifier of the transaction that is to be committed\&.
+.RE
+.SH "NOTES"
+.PP
+To commit a prepared transaction, you must be either the same user that executed the transaction originally, or a superuser\&. But you do not have to be in the same session that executed the transaction\&.
+.PP
+This command cannot be executed inside a transaction block\&. The prepared transaction is committed immediately\&.
+.PP
+All currently available prepared transactions are listed in the
+pg_prepared_xacts
+system view\&.
+.SH "EXAMPLES"
+.PP
+Commit the transaction identified by the transaction identifier
+foobar:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COMMIT PREPARED \*(Aqfoobar\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCOMMIT PREPARED\fR
+is a
+PostgreSQL
+extension\&. It is intended for use by external transaction management systems, some of which are covered by standards (such as X/Open XA), but the SQL side of those systems is not standardized\&.
+.SH "SEE ALSO"
+PREPARE TRANSACTION (\fBPREPARE_TRANSACTION\fR(7)), ROLLBACK PREPARED (\fBROLLBACK_PREPARED\fR(7))
diff --git a/doc/src/sgml/man7/COPY.7 b/doc/src/sgml/man7/COPY.7
new file mode 100644
index 0000000..a29f0f3
--- /dev/null
+++ b/doc/src/sgml/man7/COPY.7
@@ -0,0 +1,1006 @@
+'\" t
+.\" Title: COPY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "COPY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+COPY \- copy data between a file and a table
+.SH "SYNOPSIS"
+.sp
+.nf
+COPY \fItable_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ FROM { \*(Aq\fIfilename\fR\*(Aq | PROGRAM \*(Aq\fIcommand\fR\*(Aq | STDIN }
+ [ [ WITH ] ( \fIoption\fR [, \&.\&.\&.] ) ]
+ [ WHERE \fIcondition\fR ]
+
+COPY { \fItable_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ] | ( \fIquery\fR ) }
+ TO { \*(Aq\fIfilename\fR\*(Aq | PROGRAM \*(Aq\fIcommand\fR\*(Aq | STDOUT }
+ [ [ WITH ] ( \fIoption\fR [, \&.\&.\&.] ) ]
+
+where \fIoption\fR can be one of:
+
+ FORMAT \fIformat_name\fR
+ FREEZE [ \fIboolean\fR ]
+ DELIMITER \*(Aq\fIdelimiter_character\fR\*(Aq
+ NULL \*(Aq\fInull_string\fR\*(Aq
+ HEADER [ \fIboolean\fR | MATCH ]
+ QUOTE \*(Aq\fIquote_character\fR\*(Aq
+ ESCAPE \*(Aq\fIescape_character\fR\*(Aq
+ FORCE_QUOTE { ( \fIcolumn_name\fR [, \&.\&.\&.] ) | * }
+ FORCE_NOT_NULL ( \fIcolumn_name\fR [, \&.\&.\&.] )
+ FORCE_NULL ( \fIcolumn_name\fR [, \&.\&.\&.] )
+ ENCODING \*(Aq\fIencoding_name\fR\*(Aq
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCOPY\fR
+moves data between
+PostgreSQL
+tables and standard file\-system files\&.
+\fBCOPY TO\fR
+copies the contents of a table
+\fIto\fR
+a file, while
+\fBCOPY FROM\fR
+copies data
+\fIfrom\fR
+a file to a table (appending the data to whatever is in the table already)\&.
+\fBCOPY TO\fR
+can also copy the results of a
+\fBSELECT\fR
+query\&.
+.PP
+If a column list is specified,
+\fBCOPY TO\fR
+copies only the data in the specified columns to the file\&. For
+\fBCOPY FROM\fR, each field in the file is inserted, in order, into the specified column\&. Table columns not specified in the
+\fBCOPY FROM\fR
+column list will receive their default values\&.
+.PP
+\fBCOPY\fR
+with a file name instructs the
+PostgreSQL
+server to directly read from or write to a file\&. The file must be accessible by the
+PostgreSQL
+user (the user ID the server runs as) and the name must be specified from the viewpoint of the server\&. When
+PROGRAM
+is specified, the server executes the given command and reads from the standard output of the program, or writes to the standard input of the program\&. The command must be specified from the viewpoint of the server, and be executable by the
+PostgreSQL
+user\&. When
+STDIN
+or
+STDOUT
+is specified, data is transmitted via the connection between the client and the server\&.
+.PP
+Each backend running
+\fBCOPY\fR
+will report its progress in the
+pg_stat_progress_copy
+view\&. See
+Section\ \&28.4.6
+for details\&.
+.SH "PARAMETERS"
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing table\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+An optional list of columns to be copied\&. If no column list is specified, all columns of the table except generated columns will be copied\&.
+.RE
+.PP
+\fIquery\fR
+.RS 4
+A
+\fBSELECT\fR,
+\fBVALUES\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR, or
+\fBDELETE\fR
+command whose results are to be copied\&. Note that parentheses are required around the query\&.
+.sp
+For
+\fBINSERT\fR,
+\fBUPDATE\fR
+and
+\fBDELETE\fR
+queries a RETURNING clause must be provided, and the target relation must not have a conditional rule, nor an
+ALSO
+rule, nor an
+INSTEAD
+rule that expands to multiple statements\&.
+.RE
+.PP
+\fIfilename\fR
+.RS 4
+The path name of the input or output file\&. An input file name can be an absolute or relative path, but an output file name must be an absolute path\&. Windows users might need to use an
+E\*(Aq\*(Aq
+string and double any backslashes used in the path name\&.
+.RE
+.PP
+PROGRAM
+.RS 4
+A command to execute\&. In
+\fBCOPY FROM\fR, the input is read from standard output of the command, and in
+\fBCOPY TO\fR, the output is written to the standard input of the command\&.
+.sp
+Note that the command is invoked by the shell, so if you need to pass any arguments to shell command that come from an untrusted source, you must be careful to strip or escape any special characters that might have a special meaning for the shell\&. For security reasons, it is best to use a fixed command string, or at least avoid passing any user input in it\&.
+.RE
+.PP
+STDIN
+.RS 4
+Specifies that input comes from the client application\&.
+.RE
+.PP
+STDOUT
+.RS 4
+Specifies that output goes to the client application\&.
+.RE
+.PP
+\fIboolean\fR
+.RS 4
+Specifies whether the selected option should be turned on or off\&. You can write
+TRUE,
+ON, or
+1
+to enable the option, and
+FALSE,
+OFF, or
+0
+to disable it\&. The
+\fIboolean\fR
+value can also be omitted, in which case
+TRUE
+is assumed\&.
+.RE
+.PP
+FORMAT
+.RS 4
+Selects the data format to be read or written:
+text,
+csv
+(Comma Separated Values), or
+binary\&. The default is
+text\&.
+.RE
+.PP
+FREEZE
+.RS 4
+Requests copying the data with rows already frozen, just as they would be after running the
+\fBVACUUM FREEZE\fR
+command\&. This is intended as a performance option for initial data loading\&. Rows will be frozen only if the table being loaded has been created or truncated in the current subtransaction, there are no cursors open and there are no older snapshots held by this transaction\&. It is currently not possible to perform a
+\fBCOPY FREEZE\fR
+on a partitioned table\&.
+.sp
+Note that all other sessions will immediately be able to see the data once it has been successfully loaded\&. This violates the normal rules of MVCC visibility and users specifying should be aware of the potential problems this might cause\&.
+.RE
+.PP
+DELIMITER
+.RS 4
+Specifies the character that separates columns within each row (line) of the file\&. The default is a tab character in text format, a comma in
+CSV
+format\&. This must be a single one\-byte character\&. This option is not allowed when using
+binary
+format\&.
+.RE
+.PP
+NULL
+.RS 4
+Specifies the string that represents a null value\&. The default is
+\eN
+(backslash\-N) in text format, and an unquoted empty string in
+CSV
+format\&. You might prefer an empty string even in text format for cases where you don\*(Aqt want to distinguish nulls from empty strings\&. This option is not allowed when using
+binary
+format\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+When using
+\fBCOPY FROM\fR, any data item that matches this string will be stored as a null value, so you should make sure that you use the same string as you used with
+\fBCOPY TO\fR\&.
+.sp .5v
+.RE
+.RE
+.PP
+HEADER
+.RS 4
+Specifies that the file contains a header line with the names of each column in the file\&. On output, the first line contains the column names from the table\&. On input, the first line is discarded when this option is set to
+true
+(or equivalent Boolean value)\&. If this option is set to
+MATCH, the number and names of the columns in the header line must match the actual column names of the table, in order; otherwise an error is raised\&. This option is not allowed when using
+binary
+format\&. The
+MATCH
+option is only valid for
+\fBCOPY FROM\fR
+commands\&.
+.RE
+.PP
+QUOTE
+.RS 4
+Specifies the quoting character to be used when a data value is quoted\&. The default is double\-quote\&. This must be a single one\-byte character\&. This option is allowed only when using
+CSV
+format\&.
+.RE
+.PP
+ESCAPE
+.RS 4
+Specifies the character that should appear before a data character that matches the
+QUOTE
+value\&. The default is the same as the
+QUOTE
+value (so that the quoting character is doubled if it appears in the data)\&. This must be a single one\-byte character\&. This option is allowed only when using
+CSV
+format\&.
+.RE
+.PP
+FORCE_QUOTE
+.RS 4
+Forces quoting to be used for all non\-NULL
+values in each specified column\&.
+NULL
+output is never quoted\&. If
+*
+is specified, non\-NULL
+values will be quoted in all columns\&. This option is allowed only in
+\fBCOPY TO\fR, and only when using
+CSV
+format\&.
+.RE
+.PP
+FORCE_NOT_NULL
+.RS 4
+Do not match the specified columns\*(Aq values against the null string\&. In the default case where the null string is empty, this means that empty values will be read as zero\-length strings rather than nulls, even when they are not quoted\&. This option is allowed only in
+\fBCOPY FROM\fR, and only when using
+CSV
+format\&.
+.RE
+.PP
+FORCE_NULL
+.RS 4
+Match the specified columns\*(Aq values against the null string, even if it has been quoted, and if a match is found set the value to
+NULL\&. In the default case where the null string is empty, this converts a quoted empty string into NULL\&. This option is allowed only in
+\fBCOPY FROM\fR, and only when using
+CSV
+format\&.
+.RE
+.PP
+ENCODING
+.RS 4
+Specifies that the file is encoded in the
+\fIencoding_name\fR\&. If this option is omitted, the current client encoding is used\&. See the Notes below for more details\&.
+.RE
+.PP
+WHERE
+.RS 4
+The optional
+WHERE
+clause has the general form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WHERE \fIcondition\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIcondition\fR
+is any expression that evaluates to a result of type
+boolean\&. Any row that does not satisfy this condition will not be inserted to the table\&. A row satisfies the condition if it returns true when the actual row values are substituted for any variable references\&.
+.sp
+Currently, subqueries are not allowed in
+WHERE
+expressions, and the evaluation does not see any changes made by the
+\fBCOPY\fR
+itself (this matters when the expression contains calls to
+VOLATILE
+functions)\&.
+.RE
+.SH "OUTPUTS"
+.PP
+On successful completion, a
+\fBCOPY\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY \fIcount\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fIcount\fR
+is the number of rows copied\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+psql
+will print this command tag only if the command was not
+COPY \&.\&.\&. TO STDOUT, or the equivalent
+psql
+meta\-command
+\ecopy \&.\&.\&. to stdout\&. This is to prevent confusing the command tag with the data that was just printed\&.
+.sp .5v
+.RE
+.SH "NOTES"
+.PP
+\fBCOPY TO\fR
+can be used only with plain tables, not views, and does not copy rows from child tables or child partitions\&. For example,
+COPY \fItable\fR TO
+copies the same rows as
+SELECT * FROM ONLY \fItable\fR\&. The syntax
+COPY (SELECT * FROM \fItable\fR) TO \&.\&.\&.
+can be used to dump all of the rows in an inheritance hierarchy, partitioned table, or view\&.
+.PP
+\fBCOPY FROM\fR
+can be used with plain, foreign, or partitioned tables or with views that have
+INSTEAD OF INSERT
+triggers\&.
+.PP
+You must have select privilege on the table whose values are read by
+\fBCOPY TO\fR, and insert privilege on the table into which values are inserted by
+\fBCOPY FROM\fR\&. It is sufficient to have column privileges on the column(s) listed in the command\&.
+.PP
+If row\-level security is enabled for the table, the relevant
+\fBSELECT\fR
+policies will apply to
+COPY \fItable\fR TO
+statements\&. Currently,
+\fBCOPY FROM\fR
+is not supported for tables with row\-level security\&. Use equivalent
+\fBINSERT\fR
+statements instead\&.
+.PP
+Files named in a
+\fBCOPY\fR
+command are read or written directly by the server, not by the client application\&. Therefore, they must reside on or be accessible to the database server machine, not the client\&. They must be accessible to and readable or writable by the
+PostgreSQL
+user (the user ID the server runs as), not the client\&. Similarly, the command specified with
+PROGRAM
+is executed directly by the server, not by the client application, must be executable by the
+PostgreSQL
+user\&.
+\fBCOPY\fR
+naming a file or command is only allowed to database superusers or users who are granted one of the roles
+pg_read_server_files,
+pg_write_server_files, or
+pg_execute_server_program, since it allows reading or writing any file or running a program that the server has privileges to access\&.
+.PP
+Do not confuse
+\fBCOPY\fR
+with the
+psql
+instruction
+\fB\ecopy\fR\&.
+\fB\ecopy\fR
+invokes
+\fBCOPY FROM STDIN\fR
+or
+\fBCOPY TO STDOUT\fR, and then fetches/stores the data in a file accessible to the
+psql
+client\&. Thus, file accessibility and access rights depend on the client rather than the server when
+\fB\ecopy\fR
+is used\&.
+.PP
+It is recommended that the file name used in
+\fBCOPY\fR
+always be specified as an absolute path\&. This is enforced by the server in the case of
+\fBCOPY TO\fR, but for
+\fBCOPY FROM\fR
+you do have the option of reading from a file specified by a relative path\&. The path will be interpreted relative to the working directory of the server process (normally the cluster\*(Aqs data directory), not the client\*(Aqs working directory\&.
+.PP
+Executing a command with
+PROGRAM
+might be restricted by the operating system\*(Aqs access control mechanisms, such as SELinux\&.
+.PP
+\fBCOPY FROM\fR
+will invoke any triggers and check constraints on the destination table\&. However, it will not invoke rules\&.
+.PP
+For identity columns, the
+\fBCOPY FROM\fR
+command will always write the column values provided in the input data, like the
+\fBINSERT\fR
+option
+OVERRIDING SYSTEM VALUE\&.
+.PP
+\fBCOPY\fR
+input and output is affected by
+\fIDateStyle\fR\&. To ensure portability to other
+PostgreSQL
+installations that might use non\-default
+\fIDateStyle\fR
+settings,
+\fIDateStyle\fR
+should be set to
+ISO
+before using
+\fBCOPY TO\fR\&. It is also a good idea to avoid dumping data with
+\fIIntervalStyle\fR
+set to
+sql_standard, because negative interval values might be misinterpreted by a server that has a different setting for
+\fIIntervalStyle\fR\&.
+.PP
+Input data is interpreted according to
+ENCODING
+option or the current client encoding, and output data is encoded in
+ENCODING
+or the current client encoding, even if the data does not pass through the client but is read from or written to a file directly by the server\&.
+.PP
+\fBCOPY\fR
+stops operation at the first error\&. This should not lead to problems in the event of a
+\fBCOPY TO\fR, but the target table will already have received earlier rows in a
+\fBCOPY FROM\fR\&. These rows will not be visible or accessible, but they still occupy disk space\&. This might amount to a considerable amount of wasted disk space if the failure happened well into a large copy operation\&. You might wish to invoke
+\fBVACUUM\fR
+to recover the wasted space\&.
+.PP
+FORCE_NULL
+and
+FORCE_NOT_NULL
+can be used simultaneously on the same column\&. This results in converting quoted null strings to null values and unquoted null strings to empty strings\&.
+.SH "FILE FORMATS"
+.SS "Text Format"
+.PP
+When the
+text
+format is used, the data read or written is a text file with one line per table row\&. Columns in a row are separated by the delimiter character\&. The column values themselves are strings generated by the output function, or acceptable to the input function, of each attribute\*(Aqs data type\&. The specified null string is used in place of columns that are null\&.
+\fBCOPY FROM\fR
+will raise an error if any line of the input file contains more or fewer columns than are expected\&.
+.PP
+End of data can be represented by a single line containing just backslash\-period (\e\&.)\&. An end\-of\-data marker is not necessary when reading from a file, since the end of file serves perfectly well; it is needed only when copying data to or from client applications using pre\-3\&.0 client protocol\&.
+.PP
+Backslash characters (\e) can be used in the
+\fBCOPY\fR
+data to quote data characters that might otherwise be taken as row or column delimiters\&. In particular, the following characters
+\fImust\fR
+be preceded by a backslash if they appear as part of a column value: backslash itself, newline, carriage return, and the current delimiter character\&.
+.PP
+The specified null string is sent by
+\fBCOPY TO\fR
+without adding any backslashes; conversely,
+\fBCOPY FROM\fR
+matches the input against the null string before removing backslashes\&. Therefore, a null string such as
+\eN
+cannot be confused with the actual data value
+\eN
+(which would be represented as
+\e\eN)\&.
+.PP
+The following special backslash sequences are recognized by
+\fBCOPY FROM\fR:
+.TS
+allbox tab(:);
+lB lB.
+T{
+Sequence
+T}:T{
+Represents
+T}
+.T&
+l l
+l l
+l l
+l l
+l l
+l l
+l l
+l l.
+T{
+\eb
+T}:T{
+Backspace (ASCII 8)
+T}
+T{
+\ef
+T}:T{
+Form feed (ASCII 12)
+T}
+T{
+\en
+T}:T{
+Newline (ASCII 10)
+T}
+T{
+\er
+T}:T{
+Carriage return (ASCII 13)
+T}
+T{
+\et
+T}:T{
+Tab (ASCII 9)
+T}
+T{
+\ev
+T}:T{
+Vertical tab (ASCII 11)
+T}
+T{
+\e\fIdigits\fR
+T}:T{
+Backslash followed by one to three octal digits specifies
+ the byte with that numeric code
+T}
+T{
+\ex\fIdigits\fR
+T}:T{
+Backslash x followed by one or two hex digits specifies
+ the byte with that numeric code
+T}
+.TE
+.sp 1
+Presently,
+\fBCOPY TO\fR
+will never emit an octal or hex\-digits backslash sequence, but it does use the other sequences listed above for those control characters\&.
+.PP
+Any other backslashed character that is not mentioned in the above table will be taken to represent itself\&. However, beware of adding backslashes unnecessarily, since that might accidentally produce a string matching the end\-of\-data marker (\e\&.) or the null string (\eN
+by default)\&. These strings will be recognized before any other backslash processing is done\&.
+.PP
+It is strongly recommended that applications generating
+\fBCOPY\fR
+data convert data newlines and carriage returns to the
+\en
+and
+\er
+sequences respectively\&. At present it is possible to represent a data carriage return by a backslash and carriage return, and to represent a data newline by a backslash and newline\&. However, these representations might not be accepted in future releases\&. They are also highly vulnerable to corruption if the
+\fBCOPY\fR
+file is transferred across different machines (for example, from Unix to Windows or vice versa)\&.
+.PP
+All backslash sequences are interpreted after encoding conversion\&. The bytes specified with the octal and hex\-digit backslash sequences must form valid characters in the database encoding\&.
+.PP
+\fBCOPY TO\fR
+will terminate each row with a Unix\-style newline (\(lq\en\(rq)\&. Servers running on Microsoft Windows instead output carriage return/newline (\(lq\er\en\(rq), but only for
+\fBCOPY\fR
+to a server file; for consistency across platforms,
+\fBCOPY TO STDOUT\fR
+always sends
+\(lq\en\(rq
+regardless of server platform\&.
+\fBCOPY FROM\fR
+can handle lines ending with newlines, carriage returns, or carriage return/newlines\&. To reduce the risk of error due to un\-backslashed newlines or carriage returns that were meant as data,
+\fBCOPY FROM\fR
+will complain if the line endings in the input are not all alike\&.
+.SS "CSV Format"
+.PP
+This format option is used for importing and exporting the Comma Separated Value (CSV) file format used by many other programs, such as spreadsheets\&. Instead of the escaping rules used by
+PostgreSQL\*(Aqs standard text format, it produces and recognizes the common CSV escaping mechanism\&.
+.PP
+The values in each record are separated by the
+DELIMITER
+character\&. If the value contains the delimiter character, the
+QUOTE
+character, the
+NULL
+string, a carriage return, or line feed character, then the whole value is prefixed and suffixed by the
+QUOTE
+character, and any occurrence within the value of a
+QUOTE
+character or the
+ESCAPE
+character is preceded by the escape character\&. You can also use
+FORCE_QUOTE
+to force quotes when outputting non\-NULL
+values in specific columns\&.
+.PP
+The
+CSV
+format has no standard way to distinguish a
+NULL
+value from an empty string\&.
+PostgreSQL\*(Aqs
+\fBCOPY\fR
+handles this by quoting\&. A
+NULL
+is output as the
+NULL
+parameter string and is not quoted, while a non\-NULL
+value matching the
+NULL
+parameter string is quoted\&. For example, with the default settings, a
+NULL
+is written as an unquoted empty string, while an empty string data value is written with double quotes ("")\&. Reading values follows similar rules\&. You can use
+FORCE_NOT_NULL
+to prevent
+NULL
+input comparisons for specific columns\&. You can also use
+FORCE_NULL
+to convert quoted null string data values to
+NULL\&.
+.PP
+Because backslash is not a special character in the
+CSV
+format,
+\e\&., the end\-of\-data marker, could also appear as a data value\&. To avoid any misinterpretation, a
+\e\&.
+data value appearing as a lone entry on a line is automatically quoted on output, and on input, if quoted, is not interpreted as the end\-of\-data marker\&. If you are loading a file created by another application that has a single unquoted column and might have a value of
+\e\&., you might need to quote that value in the input file\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+In
+CSV
+format, all characters are significant\&. A quoted value surrounded by white space, or any characters other than
+DELIMITER, will include those characters\&. This can cause errors if you import data from a system that pads
+CSV
+lines with white space out to some fixed width\&. If such a situation arises you might need to preprocess the
+CSV
+file to remove the trailing white space, before importing the data into
+PostgreSQL\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+CSV format will both recognize and produce CSV files with quoted values containing embedded carriage returns and line feeds\&. Thus the files are not strictly one line per table row like text\-format files\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+Many programs produce strange and occasionally perverse CSV files, so the file format is more a convention than a standard\&. Thus you might encounter some files that cannot be imported using this mechanism, and
+\fBCOPY\fR
+might produce files that other programs cannot process\&.
+.sp .5v
+.RE
+.SS "Binary Format"
+.PP
+The
+binary
+format option causes all data to be stored/read as binary format rather than as text\&. It is somewhat faster than the text and
+CSV
+formats, but a binary\-format file is less portable across machine architectures and
+PostgreSQL
+versions\&. Also, the binary format is very data type specific; for example it will not work to output binary data from a
+smallint
+column and read it into an
+integer
+column, even though that would work fine in text format\&.
+.PP
+The
+binary
+file format consists of a file header, zero or more tuples containing the row data, and a file trailer\&. Headers and data are in network byte order\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+PostgreSQL
+releases before 7\&.4 used a different binary file format\&.
+.sp .5v
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBFile Header\fR
+.RS 4
+.PP
+The file header consists of 15 bytes of fixed fields, followed by a variable\-length header extension area\&. The fixed fields are:
+.PP
+Signature
+.RS 4
+11\-byte sequence
+PGCOPY\en\e377\er\en\e0
+\(em note that the zero byte is a required part of the signature\&. (The signature is designed to allow easy identification of files that have been munged by a non\-8\-bit\-clean transfer\&. This signature will be changed by end\-of\-line\-translation filters, dropped zero bytes, dropped high bits, or parity changes\&.)
+.RE
+.PP
+Flags field
+.RS 4
+32\-bit integer bit mask to denote important aspects of the file format\&. Bits are numbered from 0 (LSB) to 31 (MSB)\&. Note that this field is stored in network byte order (most significant byte first), as are all the integer fields used in the file format\&. Bits 16\(en31 are reserved to denote critical file format issues; a reader should abort if it finds an unexpected bit set in this range\&. Bits 0\(en15 are reserved to signal backwards\-compatible format issues; a reader should simply ignore any unexpected bits set in this range\&. Currently only one flag bit is defined, and the rest must be zero:
+.PP
+Bit 16
+.RS 4
+If 1, OIDs are included in the data; if 0, not\&. Oid system columns are not supported in
+PostgreSQL
+anymore, but the format still contains the indicator\&.
+.RE
+.RE
+.PP
+Header extension area length
+.RS 4
+32\-bit integer, length in bytes of remainder of header, not including self\&. Currently, this is zero, and the first tuple follows immediately\&. Future changes to the format might allow additional data to be present in the header\&. A reader should silently skip over any header extension data it does not know what to do with\&.
+.RE
+.PP
+The header extension area is envisioned to contain a sequence of self\-identifying chunks\&. The flags field is not intended to tell readers what is in the extension area\&. Specific design of header extension contents is left for a later release\&.
+.PP
+This design allows for both backwards\-compatible header additions (add header extension chunks, or set low\-order flag bits) and non\-backwards\-compatible changes (set high\-order flag bits to signal such changes, and add supporting data to the extension area if needed)\&.
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTuples\fR
+.RS 4
+.PP
+Each tuple begins with a 16\-bit integer count of the number of fields in the tuple\&. (Presently, all tuples in a table will have the same count, but that might not always be true\&.) Then, repeated for each field in the tuple, there is a 32\-bit length word followed by that many bytes of field data\&. (The length word does not include itself, and can be zero\&.) As a special case, \-1 indicates a NULL field value\&. No value bytes follow in the NULL case\&.
+.PP
+There is no alignment padding or any other extra data between fields\&.
+.PP
+Presently, all data values in a binary\-format file are assumed to be in binary format (format code one)\&. It is anticipated that a future extension might add a header field that allows per\-column format codes to be specified\&.
+.PP
+To determine the appropriate binary format for the actual tuple data you should consult the
+PostgreSQL
+source, in particular the
+\fB*send\fR
+and
+\fB*recv\fR
+functions for each column\*(Aqs data type (typically these functions are found in the
+src/backend/utils/adt/
+directory of the source distribution)\&.
+.PP
+If OIDs are included in the file, the OID field immediately follows the field\-count word\&. It is a normal field except that it\*(Aqs not included in the field\-count\&. Note that oid system columns are not supported in current versions of
+PostgreSQL\&.
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBFile Trailer\fR
+.RS 4
+.PP
+The file trailer consists of a 16\-bit integer word containing \-1\&. This is easily distinguished from a tuple\*(Aqs field\-count word\&.
+.PP
+A reader should report an error if a field\-count word is neither \-1 nor the expected number of columns\&. This provides an extra check against somehow getting out of sync with the data\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The following example copies a table to the client using the vertical bar (|) as the field delimiter:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY country TO STDOUT (DELIMITER \*(Aq|\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To copy data from a file into the
+country
+table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY country FROM \*(Aq/usr1/proj/bray/sql/country_data\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To copy into a file just the countries whose names start with \*(AqA\*(Aq:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY (SELECT * FROM country WHERE country_name LIKE \*(AqA%\*(Aq) TO \*(Aq/usr1/proj/bray/sql/a_list_countries\&.copy\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To copy into a compressed file, you can pipe the output through an external compression program:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY country TO PROGRAM \*(Aqgzip > /usr1/proj/bray/sql/country_data\&.gz\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is a sample of data suitable for copying into a table from
+STDIN:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+AF AFGHANISTAN
+AL ALBANIA
+DZ ALGERIA
+ZM ZAMBIA
+ZW ZIMBABWE
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that the white space on each line is actually a tab character\&.
+.PP
+The following is the same data, output in binary format\&. The data is shown after filtering through the Unix utility
+\fBod \-c\fR\&. The table has three columns; the first has type
+char(2), the second has type
+text, and the third has type
+integer\&. All the rows have a null value in the third column\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+0000000 P G C O P Y \en 377 \er \en \e0 \e0 \e0 \e0 \e0 \e0
+0000020 \e0 \e0 \e0 \e0 003 \e0 \e0 \e0 002 A F \e0 \e0 \e0 013 A
+0000040 F G H A N I S T A N 377 377 377 377 \e0 003
+0000060 \e0 \e0 \e0 002 A L \e0 \e0 \e0 007 A L B A N I
+0000100 A 377 377 377 377 \e0 003 \e0 \e0 \e0 002 D Z \e0 \e0 \e0
+0000120 007 A L G E R I A 377 377 377 377 \e0 003 \e0 \e0
+0000140 \e0 002 Z M \e0 \e0 \e0 006 Z A M B I A 377 377
+0000160 377 377 \e0 003 \e0 \e0 \e0 002 Z W \e0 \e0 \e0 \eb Z I
+0000200 M B A B W E 377 377 377 377 377 377
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCOPY\fR
+statement in the SQL standard\&.
+.PP
+The following syntax was used before
+PostgreSQL
+version 9\&.0 and is still supported:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY \fItable_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ FROM { \*(Aq\fIfilename\fR\*(Aq | STDIN }
+ [ [ WITH ]
+ [ BINARY ]
+ [ DELIMITER [ AS ] \*(Aq\fIdelimiter_character\fR\*(Aq ]
+ [ NULL [ AS ] \*(Aq\fInull_string\fR\*(Aq ]
+ [ CSV [ HEADER ]
+ [ QUOTE [ AS ] \*(Aq\fIquote_character\fR\*(Aq ]
+ [ ESCAPE [ AS ] \*(Aq\fIescape_character\fR\*(Aq ]
+ [ FORCE NOT NULL \fIcolumn_name\fR [, \&.\&.\&.] ] ] ]
+
+COPY { \fItable_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ] | ( \fIquery\fR ) }
+ TO { \*(Aq\fIfilename\fR\*(Aq | STDOUT }
+ [ [ WITH ]
+ [ BINARY ]
+ [ DELIMITER [ AS ] \*(Aq\fIdelimiter_character\fR\*(Aq ]
+ [ NULL [ AS ] \*(Aq\fInull_string\fR\*(Aq ]
+ [ CSV [ HEADER ]
+ [ QUOTE [ AS ] \*(Aq\fIquote_character\fR\*(Aq ]
+ [ ESCAPE [ AS ] \*(Aq\fIescape_character\fR\*(Aq ]
+ [ FORCE QUOTE { \fIcolumn_name\fR [, \&.\&.\&.] | * } ] ] ]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that in this syntax,
+BINARY
+and
+CSV
+are treated as independent keywords, not as arguments of a
+FORMAT
+option\&.
+.PP
+The following syntax was used before
+PostgreSQL
+version 7\&.3 and is still supported:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COPY [ BINARY ] \fItable_name\fR
+ FROM { \*(Aq\fIfilename\fR\*(Aq | STDIN }
+ [ [USING] DELIMITERS \*(Aq\fIdelimiter_character\fR\*(Aq ]
+ [ WITH NULL AS \*(Aq\fInull_string\fR\*(Aq ]
+
+COPY [ BINARY ] \fItable_name\fR
+ TO { \*(Aq\fIfilename\fR\*(Aq | STDOUT }
+ [ [USING] DELIMITERS \*(Aq\fIdelimiter_character\fR\*(Aq ]
+ [ WITH NULL AS \*(Aq\fInull_string\fR\*(Aq ]
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+Section\ \&28.4.6
diff --git a/doc/src/sgml/man7/CREATE_ACCESS_METHOD.7 b/doc/src/sgml/man7/CREATE_ACCESS_METHOD.7
new file mode 100644
index 0000000..579d240
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_ACCESS_METHOD.7
@@ -0,0 +1,102 @@
+'\" t
+.\" Title: CREATE ACCESS METHOD
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE ACCESS METHOD" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_ACCESS_METHOD \- define a new access method
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE ACCESS METHOD \fIname\fR
+ TYPE \fIaccess_method_type\fR
+ HANDLER \fIhandler_function\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE ACCESS METHOD\fR
+creates a new access method\&.
+.PP
+The access method name must be unique within the database\&.
+.PP
+Only superusers can define new access methods\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the access method to be created\&.
+.RE
+.PP
+\fIaccess_method_type\fR
+.RS 4
+This clause specifies the type of access method to define\&. Only
+TABLE
+and
+INDEX
+are supported at present\&.
+.RE
+.PP
+\fIhandler_function\fR
+.RS 4
+\fIhandler_function\fR
+is the name (possibly schema\-qualified) of a previously registered function that represents the access method\&. The handler function must be declared to take a single argument of type
+internal, and its return type depends on the type of access method; for
+TABLE
+access methods, it must be
+table_am_handler
+and for
+INDEX
+access methods, it must be
+index_am_handler\&. The C\-level API that the handler function must implement varies depending on the type of access method\&. The table access method API is described in
+Chapter\ \&63
+and the index access method API is described in
+Chapter\ \&64\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Create an index access method
+heptree
+with handler function
+heptree_handler:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE ACCESS METHOD heptree TYPE INDEX HANDLER heptree_handler;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE ACCESS METHOD\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+DROP ACCESS METHOD (\fBDROP_ACCESS_METHOD\fR(7)), CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), CREATE OPERATOR FAMILY (\fBCREATE_OPERATOR_FAMILY\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_AGGREGATE.7 b/doc/src/sgml/man7/CREATE_AGGREGATE.7
new file mode 100644
index 0000000..42a52f3
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_AGGREGATE.7
@@ -0,0 +1,552 @@
+'\" t
+.\" Title: CREATE AGGREGATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE AGGREGATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_AGGREGATE \- define a new aggregate function
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] AGGREGATE \fIname\fR ( [ \fIargmode\fR ] [ \fIargname\fR ] \fIarg_data_type\fR [ , \&.\&.\&. ] ) (
+ SFUNC = \fIsfunc\fR,
+ STYPE = \fIstate_data_type\fR
+ [ , SSPACE = \fIstate_data_size\fR ]
+ [ , FINALFUNC = \fIffunc\fR ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , COMBINEFUNC = \fIcombinefunc\fR ]
+ [ , SERIALFUNC = \fIserialfunc\fR ]
+ [ , DESERIALFUNC = \fIdeserialfunc\fR ]
+ [ , INITCOND = \fIinitial_condition\fR ]
+ [ , MSFUNC = \fImsfunc\fR ]
+ [ , MINVFUNC = \fIminvfunc\fR ]
+ [ , MSTYPE = \fImstate_data_type\fR ]
+ [ , MSSPACE = \fImstate_data_size\fR ]
+ [ , MFINALFUNC = \fImffunc\fR ]
+ [ , MFINALFUNC_EXTRA ]
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , MINITCOND = \fIminitial_condition\fR ]
+ [ , SORTOP = \fIsort_operator\fR ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+)
+
+CREATE [ OR REPLACE ] AGGREGATE \fIname\fR ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIarg_data_type\fR [ , \&.\&.\&. ] ]
+ ORDER BY [ \fIargmode\fR ] [ \fIargname\fR ] \fIarg_data_type\fR [ , \&.\&.\&. ] ) (
+ SFUNC = \fIsfunc\fR,
+ STYPE = \fIstate_data_type\fR
+ [ , SSPACE = \fIstate_data_size\fR ]
+ [ , FINALFUNC = \fIffunc\fR ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , INITCOND = \fIinitial_condition\fR ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+ [ , HYPOTHETICAL ]
+)
+
+or the old syntax
+
+CREATE [ OR REPLACE ] AGGREGATE \fIname\fR (
+ BASETYPE = \fIbase_type\fR,
+ SFUNC = \fIsfunc\fR,
+ STYPE = \fIstate_data_type\fR
+ [ , SSPACE = \fIstate_data_size\fR ]
+ [ , FINALFUNC = \fIffunc\fR ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , COMBINEFUNC = \fIcombinefunc\fR ]
+ [ , SERIALFUNC = \fIserialfunc\fR ]
+ [ , DESERIALFUNC = \fIdeserialfunc\fR ]
+ [ , INITCOND = \fIinitial_condition\fR ]
+ [ , MSFUNC = \fImsfunc\fR ]
+ [ , MINVFUNC = \fIminvfunc\fR ]
+ [ , MSTYPE = \fImstate_data_type\fR ]
+ [ , MSSPACE = \fImstate_data_size\fR ]
+ [ , MFINALFUNC = \fImffunc\fR ]
+ [ , MFINALFUNC_EXTRA ]
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , MINITCOND = \fIminitial_condition\fR ]
+ [ , SORTOP = \fIsort_operator\fR ]
+)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE AGGREGATE\fR
+defines a new aggregate function\&.
+\fBCREATE OR REPLACE AGGREGATE\fR
+will either define a new aggregate function or replace an existing definition\&. Some basic and commonly\-used aggregate functions are included with the distribution; they are documented in
+Section\ \&9.21\&. If one defines new types or needs an aggregate function not already provided, then
+\fBCREATE AGGREGATE\fR
+can be used to provide the desired features\&.
+.PP
+When replacing an existing definition, the argument types, result type, and number of direct arguments may not be changed\&. Also, the new definition must be of the same kind (ordinary aggregate, ordered\-set aggregate, or hypothetical\-set aggregate) as the old one\&.
+.PP
+If a schema name is given (for example,
+CREATE AGGREGATE myschema\&.myagg \&.\&.\&.) then the aggregate function is created in the specified schema\&. Otherwise it is created in the current schema\&.
+.PP
+An aggregate function is identified by its name and input data type(s)\&. Two aggregates in the same schema can have the same name if they operate on different input types\&. The name and input data type(s) of an aggregate must also be distinct from the name and input data type(s) of every ordinary function in the same schema\&. This behavior is identical to overloading of ordinary function names (see
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)))\&.
+.PP
+A simple aggregate function is made from one or two ordinary functions: a state transition function
+\fIsfunc\fR, and an optional final calculation function
+\fIffunc\fR\&. These are used as follows:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIsfunc\fR( internal\-state, next\-data\-values ) \-\-\-> next\-internal\-state
+\fIffunc\fR( internal\-state ) \-\-\-> aggregate\-value
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+PostgreSQL
+creates a temporary variable of data type
+\fIstype\fR
+to hold the current internal state of the aggregate\&. At each input row, the aggregate argument value(s) are calculated and the state transition function is invoked with the current state value and the new argument value(s) to calculate a new internal state value\&. After all the rows have been processed, the final function is invoked once to calculate the aggregate\*(Aqs return value\&. If there is no final function then the ending state value is returned as\-is\&.
+.PP
+An aggregate function can provide an initial condition, that is, an initial value for the internal state value\&. This is specified and stored in the database as a value of type
+text, but it must be a valid external representation of a constant of the state value data type\&. If it is not supplied then the state value starts out null\&.
+.PP
+If the state transition function is declared
+\(lqstrict\(rq, then it cannot be called with null inputs\&. With such a transition function, aggregate execution behaves as follows\&. Rows with any null input values are ignored (the function is not called and the previous state value is retained)\&. If the initial state value is null, then at the first row with all\-nonnull input values, the first argument value replaces the state value, and the transition function is invoked at each subsequent row with all\-nonnull input values\&. This is handy for implementing aggregates like
+\fBmax\fR\&. Note that this behavior is only available when
+\fIstate_data_type\fR
+is the same as the first
+\fIarg_data_type\fR\&. When these types are different, you must supply a nonnull initial condition or use a nonstrict transition function\&.
+.PP
+If the state transition function is not strict, then it will be called unconditionally at each input row, and must deal with null inputs and null state values for itself\&. This allows the aggregate author to have full control over the aggregate\*(Aqs handling of null values\&.
+.PP
+If the final function is declared
+\(lqstrict\(rq, then it will not be called when the ending state value is null; instead a null result will be returned automatically\&. (Of course this is just the normal behavior of strict functions\&.) In any case the final function has the option of returning a null value\&. For example, the final function for
+\fBavg\fR
+returns null when it sees there were zero input rows\&.
+.PP
+Sometimes it is useful to declare the final function as taking not just the state value, but extra parameters corresponding to the aggregate\*(Aqs input values\&. The main reason for doing this is if the final function is polymorphic and the state value\*(Aqs data type would be inadequate to pin down the result type\&. These extra parameters are always passed as NULL (and so the final function must not be strict when the
+FINALFUNC_EXTRA
+option is used), but nonetheless they are valid parameters\&. The final function could for example make use of
+\fBget_fn_expr_argtype\fR
+to identify the actual argument type in the current call\&.
+.PP
+An aggregate can optionally support
+moving\-aggregate mode, as described in
+Section\ \&38.12.1\&. This requires specifying the
+MSFUNC,
+MINVFUNC, and
+MSTYPE
+parameters, and optionally the
+MSSPACE,
+MFINALFUNC,
+MFINALFUNC_EXTRA,
+MFINALFUNC_MODIFY, and
+MINITCOND
+parameters\&. Except for
+MINVFUNC, these parameters work like the corresponding simple\-aggregate parameters without
+M; they define a separate implementation of the aggregate that includes an inverse transition function\&.
+.PP
+The syntax with
+ORDER BY
+in the parameter list creates a special type of aggregate called an
+ordered\-set aggregate; or if
+HYPOTHETICAL
+is specified, then a
+hypothetical\-set aggregate
+is created\&. These aggregates operate over groups of sorted values in order\-dependent ways, so that specification of an input sort order is an essential part of a call\&. Also, they can have
+direct
+arguments, which are arguments that are evaluated only once per aggregation rather than once per input row\&. Hypothetical\-set aggregates are a subclass of ordered\-set aggregates in which some of the direct arguments are required to match, in number and data types, the aggregated argument columns\&. This allows the values of those direct arguments to be added to the collection of aggregate\-input rows as an additional
+\(lqhypothetical\(rq
+row\&.
+.PP
+An aggregate can optionally support
+partial aggregation, as described in
+Section\ \&38.12.4\&. This requires specifying the
+COMBINEFUNC
+parameter\&. If the
+\fIstate_data_type\fR
+is
+internal, it\*(Aqs usually also appropriate to provide the
+SERIALFUNC
+and
+DESERIALFUNC
+parameters so that parallel aggregation is possible\&. Note that the aggregate must also be marked
+PARALLEL SAFE
+to enable parallel aggregation\&.
+.PP
+Aggregates that behave like
+\fBMIN\fR
+or
+\fBMAX\fR
+can sometimes be optimized by looking into an index instead of scanning every input row\&. If this aggregate can be so optimized, indicate it by specifying a
+sort operator\&. The basic requirement is that the aggregate must yield the first element in the sort ordering induced by the operator; in other words:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT agg(col) FROM tab;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+must be equivalent to:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Further assumptions are that the aggregate ignores null inputs, and that it delivers a null result if and only if there were no non\-null inputs\&. Ordinarily, a data type\*(Aqs
+<
+operator is the proper sort operator for
+\fBMIN\fR, and
+>
+is the proper sort operator for
+\fBMAX\fR\&. Note that the optimization will never actually take effect unless the specified operator is the
+\(lqless than\(rq
+or
+\(lqgreater than\(rq
+strategy member of a B\-tree index operator class\&.
+.PP
+To be able to create an aggregate function, you must have
+USAGE
+privilege on the argument types, the state type(s), and the return type, as well as
+EXECUTE
+privilege on the supporting functions\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the aggregate function to create\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN
+or
+VARIADIC\&. (Aggregate functions do not support
+OUT
+arguments\&.) If omitted, the default is
+IN\&. Only the last argument can be marked
+VARIADIC\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. This is currently only useful for documentation purposes\&. If omitted, the argument has no name\&.
+.RE
+.PP
+\fIarg_data_type\fR
+.RS 4
+An input data type on which this aggregate function operates\&. To create a zero\-argument aggregate function, write
+*
+in place of the list of argument specifications\&. (An example of such an aggregate is
+\fBcount(*)\fR\&.)
+.RE
+.PP
+\fIbase_type\fR
+.RS 4
+In the old syntax for
+\fBCREATE AGGREGATE\fR, the input data type is specified by a
+basetype
+parameter rather than being written next to the aggregate name\&. Note that this syntax allows only one input parameter\&. To define a zero\-argument aggregate function with this syntax, specify the
+basetype
+as
+"ANY"
+(not
+*)\&. Ordered\-set aggregates cannot be defined with the old syntax\&.
+.RE
+.PP
+\fIsfunc\fR
+.RS 4
+The name of the state transition function to be called for each input row\&. For a normal
+\fIN\fR\-argument aggregate function, the
+\fIsfunc\fR
+must take
+\fIN\fR+1 arguments, the first being of type
+\fIstate_data_type\fR
+and the rest matching the declared input data type(s) of the aggregate\&. The function must return a value of type
+\fIstate_data_type\fR\&. This function takes the current state value and the current input data value(s), and returns the next state value\&.
+.sp
+For ordered\-set (including hypothetical\-set) aggregates, the state transition function receives only the current state value and the aggregated arguments, not the direct arguments\&. Otherwise it is the same\&.
+.RE
+.PP
+\fIstate_data_type\fR
+.RS 4
+The data type for the aggregate\*(Aqs state value\&.
+.RE
+.PP
+\fIstate_data_size\fR
+.RS 4
+The approximate average size (in bytes) of the aggregate\*(Aqs state value\&. If this parameter is omitted or is zero, a default estimate is used based on the
+\fIstate_data_type\fR\&. The planner uses this value to estimate the memory required for a grouped aggregate query\&.
+.RE
+.PP
+\fIffunc\fR
+.RS 4
+The name of the final function called to compute the aggregate\*(Aqs result after all input rows have been traversed\&. For a normal aggregate, this function must take a single argument of type
+\fIstate_data_type\fR\&. The return data type of the aggregate is defined as the return type of this function\&. If
+\fIffunc\fR
+is not specified, then the ending state value is used as the aggregate\*(Aqs result, and the return type is
+\fIstate_data_type\fR\&.
+.sp
+For ordered\-set (including hypothetical\-set) aggregates, the final function receives not only the final state value, but also the values of all the direct arguments\&.
+.sp
+If
+FINALFUNC_EXTRA
+is specified, then in addition to the final state value and any direct arguments, the final function receives extra NULL values corresponding to the aggregate\*(Aqs regular (aggregated) arguments\&. This is mainly useful to allow correct resolution of the aggregate result type when a polymorphic aggregate is being defined\&.
+.RE
+.PP
+FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE }
+.RS 4
+This option specifies whether the final function is a pure function that does not modify its arguments\&.
+READ_ONLY
+indicates it does not; the other two values indicate that it may change the transition state value\&. See
+Notes
+below for more detail\&. The default is
+READ_ONLY, except for ordered\-set aggregates, for which the default is
+READ_WRITE\&.
+.RE
+.PP
+\fIcombinefunc\fR
+.RS 4
+The
+\fIcombinefunc\fR
+function may optionally be specified to allow the aggregate function to support partial aggregation\&. If provided, the
+\fIcombinefunc\fR
+must combine two
+\fIstate_data_type\fR
+values, each containing the result of aggregation over some subset of the input values, to produce a new
+\fIstate_data_type\fR
+that represents the result of aggregating over both sets of inputs\&. This function can be thought of as an
+\fIsfunc\fR, where instead of acting upon an individual input row and adding it to the running aggregate state, it adds another aggregate state to the running state\&.
+.sp
+The
+\fIcombinefunc\fR
+must be declared as taking two arguments of the
+\fIstate_data_type\fR
+and returning a value of the
+\fIstate_data_type\fR\&. Optionally this function may be
+\(lqstrict\(rq\&. In this case the function will not be called when either of the input states are null; the other state will be taken as the correct result\&.
+.sp
+For aggregate functions whose
+\fIstate_data_type\fR
+is
+internal, the
+\fIcombinefunc\fR
+must not be strict\&. In this case the
+\fIcombinefunc\fR
+must ensure that null states are handled correctly and that the state being returned is properly stored in the aggregate memory context\&.
+.RE
+.PP
+\fIserialfunc\fR
+.RS 4
+An aggregate function whose
+\fIstate_data_type\fR
+is
+internal
+can participate in parallel aggregation only if it has a
+\fIserialfunc\fR
+function, which must serialize the aggregate state into a
+bytea
+value for transmission to another process\&. This function must take a single argument of type
+internal
+and return type
+bytea\&. A corresponding
+\fIdeserialfunc\fR
+is also required\&.
+.RE
+.PP
+\fIdeserialfunc\fR
+.RS 4
+Deserialize a previously serialized aggregate state back into
+\fIstate_data_type\fR\&. This function must take two arguments of types
+bytea
+and
+internal, and produce a result of type
+internal\&. (Note: the second,
+internal
+argument is unused, but is required for type safety reasons\&.)
+.RE
+.PP
+\fIinitial_condition\fR
+.RS 4
+The initial setting for the state value\&. This must be a string constant in the form accepted for the data type
+\fIstate_data_type\fR\&. If not specified, the state value starts out null\&.
+.RE
+.PP
+\fImsfunc\fR
+.RS 4
+The name of the forward state transition function to be called for each input row in moving\-aggregate mode\&. This is exactly like the regular transition function, except that its first argument and result are of type
+\fImstate_data_type\fR, which might be different from
+\fIstate_data_type\fR\&.
+.RE
+.PP
+\fIminvfunc\fR
+.RS 4
+The name of the inverse state transition function to be used in moving\-aggregate mode\&. This function has the same argument and result types as
+\fImsfunc\fR, but it is used to remove a value from the current aggregate state, rather than add a value to it\&. The inverse transition function must have the same strictness attribute as the forward state transition function\&.
+.RE
+.PP
+\fImstate_data_type\fR
+.RS 4
+The data type for the aggregate\*(Aqs state value, when using moving\-aggregate mode\&.
+.RE
+.PP
+\fImstate_data_size\fR
+.RS 4
+The approximate average size (in bytes) of the aggregate\*(Aqs state value, when using moving\-aggregate mode\&. This works the same as
+\fIstate_data_size\fR\&.
+.RE
+.PP
+\fImffunc\fR
+.RS 4
+The name of the final function called to compute the aggregate\*(Aqs result after all input rows have been traversed, when using moving\-aggregate mode\&. This works the same as
+\fIffunc\fR, except that its first argument\*(Aqs type is
+\fImstate_data_type\fR
+and extra dummy arguments are specified by writing
+MFINALFUNC_EXTRA\&. The aggregate result type determined by
+\fImffunc\fR
+or
+\fImstate_data_type\fR
+must match that determined by the aggregate\*(Aqs regular implementation\&.
+.RE
+.PP
+MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE }
+.RS 4
+This option is like
+FINALFUNC_MODIFY, but it describes the behavior of the moving\-aggregate final function\&.
+.RE
+.PP
+\fIminitial_condition\fR
+.RS 4
+The initial setting for the state value, when using moving\-aggregate mode\&. This works the same as
+\fIinitial_condition\fR\&.
+.RE
+.PP
+\fIsort_operator\fR
+.RS 4
+The associated sort operator for a
+\fBMIN\fR\- or
+\fBMAX\fR\-like aggregate\&. This is just an operator name (possibly schema\-qualified)\&. The operator is assumed to have the same input data types as the aggregate (which must be a single\-argument normal aggregate)\&.
+.RE
+.PP
+PARALLEL = { SAFE | RESTRICTED | UNSAFE }
+.RS 4
+The meanings of
+PARALLEL SAFE,
+PARALLEL RESTRICTED, and
+PARALLEL UNSAFE
+are the same as in
+\fBCREATE FUNCTION\fR\&. An aggregate will not be considered for parallelization if it is marked
+PARALLEL UNSAFE
+(which is the default!) or
+PARALLEL RESTRICTED\&. Note that the parallel\-safety markings of the aggregate\*(Aqs support functions are not consulted by the planner, only the marking of the aggregate itself\&.
+.RE
+.PP
+HYPOTHETICAL
+.RS 4
+For ordered\-set aggregates only, this flag specifies that the aggregate arguments are to be processed according to the requirements for hypothetical\-set aggregates: that is, the last few direct arguments must match the data types of the aggregated (WITHIN GROUP) arguments\&. The
+HYPOTHETICAL
+flag has no effect on run\-time behavior, only on parse\-time resolution of the data types and collations of the aggregate\*(Aqs arguments\&.
+.RE
+.PP
+The parameters of
+\fBCREATE AGGREGATE\fR
+can be written in any order, not just the order illustrated above\&.
+.SH "NOTES"
+.PP
+In parameters that specify support function names, you can write a schema name if needed, for example
+SFUNC = public\&.sum\&. Do not write argument types there, however \(em the argument types of the support functions are determined from other parameters\&.
+.PP
+Ordinarily, PostgreSQL functions are expected to be true functions that do not modify their input values\&. However, an aggregate transition function,
+\fIwhen used in the context of an aggregate\fR, is allowed to cheat and modify its transition\-state argument in place\&. This can provide substantial performance benefits compared to making a fresh copy of the transition state each time\&.
+.PP
+Likewise, while an aggregate final function is normally expected not to modify its input values, sometimes it is impractical to avoid modifying the transition\-state argument\&. Such behavior must be declared using the
+FINALFUNC_MODIFY
+parameter\&. The
+READ_WRITE
+value indicates that the final function modifies the transition state in unspecified ways\&. This value prevents use of the aggregate as a window function, and it also prevents merging of transition states for aggregate calls that share the same input values and transition functions\&. The
+SHAREABLE
+value indicates that the transition function cannot be applied after the final function, but multiple final\-function calls can be performed on the ending transition state value\&. This value prevents use of the aggregate as a window function, but it allows merging of transition states\&. (That is, the optimization of interest here is not applying the same final function repeatedly, but applying different final functions to the same ending transition state value\&. This is allowed as long as none of the final functions are marked
+READ_WRITE\&.)
+.PP
+If an aggregate supports moving\-aggregate mode, it will improve calculation efficiency when the aggregate is used as a window function for a window with moving frame start (that is, a frame start mode other than
+UNBOUNDED PRECEDING)\&. Conceptually, the forward transition function adds input values to the aggregate\*(Aqs state when they enter the window frame from the bottom, and the inverse transition function removes them again when they leave the frame at the top\&. So, when values are removed, they are always removed in the same order they were added\&. Whenever the inverse transition function is invoked, it will thus receive the earliest added but not yet removed argument value(s)\&. The inverse transition function can assume that at least one row will remain in the current state after it removes the oldest row\&. (When this would not be the case, the window function mechanism simply starts a fresh aggregation, rather than using the inverse transition function\&.)
+.PP
+The forward transition function for moving\-aggregate mode is not allowed to return NULL as the new state value\&. If the inverse transition function returns NULL, this is taken as an indication that the inverse function cannot reverse the state calculation for this particular input, and so the aggregate calculation will be redone from scratch for the current frame starting position\&. This convention allows moving\-aggregate mode to be used in situations where there are some infrequent cases that are impractical to reverse out of the running state value\&.
+.PP
+If no moving\-aggregate implementation is supplied, the aggregate can still be used with moving frames, but
+PostgreSQL
+will recompute the whole aggregation whenever the start of the frame moves\&. Note that whether or not the aggregate supports moving\-aggregate mode,
+PostgreSQL
+can handle a moving frame end without recalculation; this is done by continuing to add new values to the aggregate\*(Aqs state\&. This is why use of an aggregate as a window function requires that the final function be read\-only: it must not damage the aggregate\*(Aqs state value, so that the aggregation can be continued even after an aggregate result value has been obtained for one set of frame boundaries\&.
+.PP
+The syntax for ordered\-set aggregates allows
+VARIADIC
+to be specified for both the last direct parameter and the last aggregated (WITHIN GROUP) parameter\&. However, the current implementation restricts use of
+VARIADIC
+in two ways\&. First, ordered\-set aggregates can only use
+VARIADIC "any", not other variadic array types\&. Second, if the last direct parameter is
+VARIADIC "any", then there can be only one aggregated parameter and it must also be
+VARIADIC "any"\&. (In the representation used in the system catalogs, these two parameters are merged into a single
+VARIADIC "any"
+item, since
+pg_proc
+cannot represent functions with more than one
+VARIADIC
+parameter\&.) If the aggregate is a hypothetical\-set aggregate, the direct arguments that match the
+VARIADIC "any"
+parameter are the hypothetical ones; any preceding parameters represent additional direct arguments that are not constrained to match the aggregated arguments\&.
+.PP
+Currently, ordered\-set aggregates do not need to support moving\-aggregate mode, since they cannot be used as window functions\&.
+.PP
+Partial (including parallel) aggregation is currently not supported for ordered\-set aggregates\&. Also, it will never be used for aggregate calls that include
+DISTINCT
+or
+ORDER BY
+clauses, since those semantics cannot be supported during partial aggregation\&.
+.SH "EXAMPLES"
+.PP
+See
+Section\ \&38.12\&.
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE AGGREGATE\fR
+is a
+PostgreSQL
+language extension\&. The SQL standard does not provide for user\-defined aggregate functions\&.
+.SH "SEE ALSO"
+ALTER AGGREGATE (\fBALTER_AGGREGATE\fR(7)), DROP AGGREGATE (\fBDROP_AGGREGATE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_CAST.7 b/doc/src/sgml/man7/CREATE_CAST.7
new file mode 100644
index 0000000..b8278e6
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_CAST.7
@@ -0,0 +1,373 @@
+'\" t
+.\" Title: CREATE CAST
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE CAST" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_CAST \- define a new cast
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE CAST (\fIsource_type\fR AS \fItarget_type\fR)
+ WITH FUNCTION \fIfunction_name\fR [ (\fIargument_type\fR [, \&.\&.\&.]) ]
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (\fIsource_type\fR AS \fItarget_type\fR)
+ WITHOUT FUNCTION
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (\fIsource_type\fR AS \fItarget_type\fR)
+ WITH INOUT
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE CAST\fR
+defines a new cast\&. A cast specifies how to perform a conversion between two data types\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT CAST(42 AS float8);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+converts the integer constant 42 to type
+float8
+by invoking a previously specified function, in this case
+float8(int4)\&. (If no suitable cast has been defined, the conversion fails\&.)
+.PP
+Two types can be
+binary coercible, which means that the conversion can be performed
+\(lqfor free\(rq
+without invoking any function\&. This requires that corresponding values use the same internal representation\&. For instance, the types
+text
+and
+varchar
+are binary coercible both ways\&. Binary coercibility is not necessarily a symmetric relationship\&. For example, the cast from
+xml
+to
+text
+can be performed for free in the present implementation, but the reverse direction requires a function that performs at least a syntax check\&. (Two types that are binary coercible both ways are also referred to as binary compatible\&.)
+.PP
+You can define a cast as an
+I/O conversion cast
+by using the
+WITH INOUT
+syntax\&. An I/O conversion cast is performed by invoking the output function of the source data type, and passing the resulting string to the input function of the target data type\&. In many common cases, this feature avoids the need to write a separate cast function for conversion\&. An I/O conversion cast acts the same as a regular function\-based cast; only the implementation is different\&.
+.PP
+By default, a cast can be invoked only by an explicit cast request, that is an explicit
+CAST(\fIx\fR AS \fItypename\fR)
+or
+\fIx\fR::\fItypename\fR
+construct\&.
+.PP
+If the cast is marked
+AS ASSIGNMENT
+then it can be invoked implicitly when assigning a value to a column of the target data type\&. For example, supposing that
+foo\&.f1
+is a column of type
+text, then:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO foo (f1) VALUES (42);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+will be allowed if the cast from type
+integer
+to type
+text
+is marked
+AS ASSIGNMENT, otherwise not\&. (We generally use the term
+assignment cast
+to describe this kind of cast\&.)
+.PP
+If the cast is marked
+AS IMPLICIT
+then it can be invoked implicitly in any context, whether assignment or internally in an expression\&. (We generally use the term
+implicit cast
+to describe this kind of cast\&.) For example, consider this query:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT 2 + 4\&.0;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The parser initially marks the constants as being of type
+integer
+and
+numeric
+respectively\&. There is no
+integer
++
+numeric
+operator in the system catalogs, but there is a
+numeric
++
+numeric
+operator\&. The query will therefore succeed if a cast from
+integer
+to
+numeric
+is available and is marked
+AS IMPLICIT
+\(em which in fact it is\&. The parser will apply the implicit cast and resolve the query as if it had been written
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT CAST ( 2 AS numeric ) + 4\&.0;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Now, the catalogs also provide a cast from
+numeric
+to
+integer\&. If that cast were marked
+AS IMPLICIT
+\(em which it is not \(em then the parser would be faced with choosing between the above interpretation and the alternative of casting the
+numeric
+constant to
+integer
+and applying the
+integer
++
+integer
+operator\&. Lacking any knowledge of which choice to prefer, it would give up and declare the query ambiguous\&. The fact that only one of the two casts is implicit is the way in which we teach the parser to prefer resolution of a mixed
+numeric\-and\-integer
+expression as
+numeric; there is no built\-in knowledge about that\&.
+.PP
+It is wise to be conservative about marking casts as implicit\&. An overabundance of implicit casting paths can cause
+PostgreSQL
+to choose surprising interpretations of commands, or to be unable to resolve commands at all because there are multiple possible interpretations\&. A good rule of thumb is to make a cast implicitly invokable only for information\-preserving transformations between types in the same general type category\&. For example, the cast from
+int2
+to
+int4
+can reasonably be implicit, but the cast from
+float8
+to
+int4
+should probably be assignment\-only\&. Cross\-type\-category casts, such as
+text
+to
+int4, are best made explicit\-only\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+Sometimes it is necessary for usability or standards\-compliance reasons to provide multiple implicit casts among a set of types, resulting in ambiguity that cannot be avoided as above\&. The parser has a fallback heuristic based on
+type categories
+and
+preferred types
+that can help to provide desired behavior in such cases\&. See
+CREATE TYPE (\fBCREATE_TYPE\fR(7))
+for more information\&.
+.sp .5v
+.RE
+.PP
+To be able to create a cast, you must own the source or the target data type and have
+USAGE
+privilege on the other type\&. To create a binary\-coercible cast, you must be superuser\&. (This restriction is made because an erroneous binary\-coercible cast conversion can easily crash the server\&.)
+.SH "PARAMETERS"
+.PP
+\fIsource_type\fR
+.RS 4
+The name of the source data type of the cast\&.
+.RE
+.PP
+\fItarget_type\fR
+.RS 4
+The name of the target data type of the cast\&.
+.RE
+.PP
+\fIfunction_name\fR[(\fIargument_type\fR [, \&.\&.\&.])]
+.RS 4
+The function used to perform the cast\&. The function name can be schema\-qualified\&. If it is not, the function will be looked up in the schema search path\&. The function\*(Aqs result data type must match the target type of the cast\&. Its arguments are discussed below\&. If no argument list is specified, the function name must be unique in its schema\&.
+.RE
+.PP
+WITHOUT FUNCTION
+.RS 4
+Indicates that the source type is binary\-coercible to the target type, so no function is required to perform the cast\&.
+.RE
+.PP
+WITH INOUT
+.RS 4
+Indicates that the cast is an I/O conversion cast, performed by invoking the output function of the source data type, and passing the resulting string to the input function of the target data type\&.
+.RE
+.PP
+AS ASSIGNMENT
+.RS 4
+Indicates that the cast can be invoked implicitly in assignment contexts\&.
+.RE
+.PP
+AS IMPLICIT
+.RS 4
+Indicates that the cast can be invoked implicitly in any context\&.
+.RE
+.PP
+Cast implementation functions can have one to three arguments\&. The first argument type must be identical to or binary\-coercible from the cast\*(Aqs source type\&. The second argument, if present, must be type
+integer; it receives the type modifier associated with the destination type, or
+\-1
+if there is none\&. The third argument, if present, must be type
+boolean; it receives
+true
+if the cast is an explicit cast,
+false
+otherwise\&. (Bizarrely, the SQL standard demands different behaviors for explicit and implicit casts in some cases\&. This argument is supplied for functions that must implement such casts\&. It is not recommended that you design your own data types so that this matters\&.)
+.PP
+The return type of a cast function must be identical to or binary\-coercible to the cast\*(Aqs target type\&.
+.PP
+Ordinarily a cast must have different source and target data types\&. However, it is allowed to declare a cast with identical source and target types if it has a cast implementation function with more than one argument\&. This is used to represent type\-specific length coercion functions in the system catalogs\&. The named function is used to coerce a value of the type to the type modifier value given by its second argument\&.
+.PP
+When a cast has different source and target types and a function that takes more than one argument, it supports converting from one type to another and applying a length coercion in a single step\&. When no such entry is available, coercion to a type that uses a type modifier involves two cast steps, one to convert between data types and a second to apply the modifier\&.
+.PP
+A cast to or from a domain type currently has no effect\&. Casting to or from a domain uses the casts associated with its underlying type\&.
+.SH "NOTES"
+.PP
+Use
+\fBDROP CAST\fR
+to remove user\-defined casts\&.
+.PP
+Remember that if you want to be able to convert types both ways you need to declare casts both ways explicitly\&.
+.PP
+It is normally not necessary to create casts between user\-defined types and the standard string types (text,
+varchar, and
+char(\fIn\fR), as well as user\-defined types that are defined to be in the string category)\&.
+PostgreSQL
+provides automatic I/O conversion casts for that\&. The automatic casts to string types are treated as assignment casts, while the automatic casts from string types are explicit\-only\&. You can override this behavior by declaring your own cast to replace an automatic cast, but usually the only reason to do so is if you want the conversion to be more easily invokable than the standard assignment\-only or explicit\-only setting\&. Another possible reason is that you want the conversion to behave differently from the type\*(Aqs I/O function; but that is sufficiently surprising that you should think twice about whether it\*(Aqs a good idea\&. (A small number of the built\-in types do indeed have different behaviors for conversions, mostly because of requirements of the SQL standard\&.)
+.PP
+While not required, it is recommended that you continue to follow this old convention of naming cast implementation functions after the target data type\&. Many users are used to being able to cast data types using a function\-style notation, that is
+\fItypename\fR(\fIx\fR)\&. This notation is in fact nothing more nor less than a call of the cast implementation function; it is not specially treated as a cast\&. If your conversion functions are not named to support this convention then you will have surprised users\&. Since
+PostgreSQL
+allows overloading of the same function name with different argument types, there is no difficulty in having multiple conversion functions from different types that all use the target type\*(Aqs name\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+Actually the preceding paragraph is an oversimplification: there are two cases in which a function\-call construct will be treated as a cast request without having matched it to an actual function\&. If a function call
+\fIname\fR(\fIx\fR) does not exactly match any existing function, but
+\fIname\fR
+is the name of a data type and
+pg_cast
+provides a binary\-coercible cast to this type from the type of
+\fIx\fR, then the call will be construed as a binary\-coercible cast\&. This exception is made so that binary\-coercible casts can be invoked using functional syntax, even though they lack any function\&. Likewise, if there is no
+pg_cast
+entry but the cast would be to or from a string type, the call will be construed as an I/O conversion cast\&. This exception allows I/O conversion casts to be invoked using functional syntax\&.
+.sp .5v
+.RE
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+There is also an exception to the exception: I/O conversion casts from composite types to string types cannot be invoked using functional syntax, but must be written in explicit cast syntax (either
+CAST
+or
+::
+notation)\&. This exception was added because after the introduction of automatically\-provided I/O conversion casts, it was found too easy to accidentally invoke such a cast when a function or column reference was intended\&.
+.sp .5v
+.RE
+.SH "EXAMPLES"
+.PP
+To create an assignment cast from type
+bigint
+to type
+int4
+using the function
+int4(bigint):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(This cast is already predefined in the system\&.)
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCREATE CAST\fR
+command conforms to the
+SQL
+standard, except that SQL does not make provisions for binary\-coercible types or extra arguments to implementation functions\&.
+AS IMPLICIT
+is a
+PostgreSQL
+extension, too\&.
+.SH "SEE ALSO"
+.PP
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)),
+CREATE TYPE (\fBCREATE_TYPE\fR(7)),
+DROP CAST (\fBDROP_CAST\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_COLLATION.7 b/doc/src/sgml/man7/CREATE_COLLATION.7
new file mode 100644
index 0000000..0bfa226
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_COLLATION.7
@@ -0,0 +1,197 @@
+'\" t
+.\" Title: CREATE COLLATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE COLLATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_COLLATION \- define a new collation
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE COLLATION [ IF NOT EXISTS ] \fIname\fR (
+ [ LOCALE = \fIlocale\fR, ]
+ [ LC_COLLATE = \fIlc_collate\fR, ]
+ [ LC_CTYPE = \fIlc_ctype\fR, ]
+ [ PROVIDER = \fIprovider\fR, ]
+ [ DETERMINISTIC = \fIboolean\fR, ]
+ [ VERSION = \fIversion\fR ]
+)
+CREATE COLLATION [ IF NOT EXISTS ] \fIname\fR FROM \fIexisting_collation\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE COLLATION\fR
+defines a new collation using the specified operating system locale settings, or by copying an existing collation\&.
+.PP
+To be able to create a collation, you must have
+CREATE
+privilege on the destination schema\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a collation with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing collation is anything like the one that would have been created\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the collation\&. The collation name can be schema\-qualified\&. If it is not, the collation is defined in the current schema\&. The collation name must be unique within that schema\&. (The system catalogs can contain collations with the same name for other encodings, but these are ignored if the database encoding does not match\&.)
+.RE
+.PP
+\fIlocale\fR
+.RS 4
+This is a shortcut for setting
+LC_COLLATE
+and
+LC_CTYPE
+at once\&. If you specify this, you cannot specify either of those parameters\&.
+.RE
+.PP
+\fIlc_collate\fR
+.RS 4
+Use the specified operating system locale for the
+LC_COLLATE
+locale category\&.
+.RE
+.PP
+\fIlc_ctype\fR
+.RS 4
+Use the specified operating system locale for the
+LC_CTYPE
+locale category\&.
+.RE
+.PP
+\fIprovider\fR
+.RS 4
+Specifies the provider to use for locale services associated with this collation\&. Possible values are:
+icu,
+libc\&.
+libc
+is the default\&. The available choices depend on the operating system and build options\&.
+.RE
+.PP
+DETERMINISTIC
+.RS 4
+Specifies whether the collation should use deterministic comparisons\&. The default is true\&. A deterministic comparison considers strings that are not byte\-wise equal to be unequal even if they are considered logically equal by the comparison\&. PostgreSQL breaks ties using a byte\-wise comparison\&. Comparison that is not deterministic can make the collation be, say, case\- or accent\-insensitive\&. For that, you need to choose an appropriate
+LC_COLLATE
+setting
+\fIand\fR
+set the collation to not deterministic here\&.
+.sp
+Nondeterministic collations are only supported with the ICU provider\&.
+.RE
+.PP
+\fIversion\fR
+.RS 4
+Specifies the version string to store with the collation\&. Normally, this should be omitted, which will cause the version to be computed from the actual version of the collation as provided by the operating system\&. This option is intended to be used by
+\fBpg_upgrade\fR
+for copying the version from an existing installation\&.
+.sp
+See also
+ALTER COLLATION (\fBALTER_COLLATION\fR(7))
+for how to handle collation version mismatches\&.
+.RE
+.PP
+\fIexisting_collation\fR
+.RS 4
+The name of an existing collation to copy\&. The new collation will have the same properties as the existing one, but it will be an independent object\&.
+.RE
+.SH "NOTES"
+.PP
+\fBCREATE COLLATION\fR
+takes a
+SHARE ROW EXCLUSIVE
+lock, which is self\-conflicting, on the
+pg_collation
+system catalog, so only one
+\fBCREATE COLLATION\fR
+command can run at a time\&.
+.PP
+Use
+\fBDROP COLLATION\fR
+to remove user\-defined collations\&.
+.PP
+See
+Section\ \&24.2.2.3
+for more information on how to create collations\&.
+.PP
+When using the
+libc
+collation provider, the locale must be applicable to the current database encoding\&. See
+CREATE DATABASE (\fBCREATE_DATABASE\fR(7))
+for the precise rules\&.
+.SH "EXAMPLES"
+.PP
+To create a collation from the operating system locale
+fr_FR\&.utf8
+(assuming the current database encoding is
+UTF8):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE COLLATION french (locale = \*(Aqfr_FR\&.utf8\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a collation using the ICU provider using German phone book sort order:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE COLLATION german_phonebook (provider = icu, locale = \*(Aqde\-u\-co\-phonebk\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a collation from an existing collation:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE COLLATION german FROM "de_DE";
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This can be convenient to be able to use operating\-system\-independent collation names in applications\&.
+.SH "COMPATIBILITY"
+.PP
+There is a
+\fBCREATE COLLATION\fR
+statement in the SQL standard, but it is limited to copying an existing collation\&. The syntax to create a new collation is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER COLLATION (\fBALTER_COLLATION\fR(7)), DROP COLLATION (\fBDROP_COLLATION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_CONVERSION.7 b/doc/src/sgml/man7/CREATE_CONVERSION.7
new file mode 100644
index 0000000..3bbb34c
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_CONVERSION.7
@@ -0,0 +1,145 @@
+'\" t
+.\" Title: CREATE CONVERSION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE CONVERSION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_CONVERSION \- define a new encoding conversion
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ DEFAULT ] CONVERSION \fIname\fR
+ FOR \fIsource_encoding\fR TO \fIdest_encoding\fR FROM \fIfunction_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE CONVERSION\fR
+defines a new conversion between two character set encodings\&.
+.PP
+Conversions that are marked
+DEFAULT
+can be used for automatic encoding conversion between client and server\&. To support that usage, two conversions, from encoding A to B
+\fIand\fR
+from encoding B to A, must be defined\&.
+.PP
+To be able to create a conversion, you must have
+EXECUTE
+privilege on the function and
+CREATE
+privilege on the destination schema\&.
+.SH "PARAMETERS"
+.PP
+DEFAULT
+.RS 4
+The
+DEFAULT
+clause indicates that this conversion is the default for this particular source to destination encoding\&. There should be only one default encoding in a schema for the encoding pair\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the conversion\&. The conversion name can be schema\-qualified\&. If it is not, the conversion is defined in the current schema\&. The conversion name must be unique within a schema\&.
+.RE
+.PP
+\fIsource_encoding\fR
+.RS 4
+The source encoding name\&.
+.RE
+.PP
+\fIdest_encoding\fR
+.RS 4
+The destination encoding name\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+The function used to perform the conversion\&. The function name can be schema\-qualified\&. If it is not, the function will be looked up in the path\&.
+.sp
+The function must have the following signature:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+conv_proc(
+ integer, \-\- source encoding ID
+ integer, \-\- destination encoding ID
+ cstring, \-\- source string (null terminated C string)
+ internal, \-\- destination (fill with a null terminated C string)
+ integer, \-\- source string length
+ boolean \-\- if true, don\*(Aqt throw an error if conversion fails
+) RETURNS integer;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The return value is the number of source bytes that were successfully converted\&. If the last argument is false, the function must throw an error on invalid input, and the return value is always equal to the source string length\&.
+.RE
+.SH "NOTES"
+.PP
+Neither the source nor the destination encoding can be
+SQL_ASCII, as the server\*(Aqs behavior for cases involving the
+SQL_ASCII
+\(lqencoding\(rq
+is hard\-wired\&.
+.PP
+Use
+\fBDROP CONVERSION\fR
+to remove user\-defined conversions\&.
+.PP
+The privileges required to create a conversion might be changed in a future release\&.
+.SH "EXAMPLES"
+.PP
+To create a conversion from encoding
+UTF8
+to
+LATIN1
+using
+\fBmyfunc\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE CONVERSION myconv FOR \*(AqUTF8\*(Aq TO \*(AqLATIN1\*(Aq FROM myfunc;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE CONVERSION\fR
+is a
+PostgreSQL
+extension\&. There is no
+\fBCREATE CONVERSION\fR
+statement in the SQL standard, but a
+\fBCREATE TRANSLATION\fR
+statement that is very similar in purpose and syntax\&.
+.SH "SEE ALSO"
+ALTER CONVERSION (\fBALTER_CONVERSION\fR(7)), CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)), DROP CONVERSION (\fBDROP_CONVERSION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_DATABASE.7 b/doc/src/sgml/man7/CREATE_DATABASE.7
new file mode 100644
index 0000000..d58360a
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_DATABASE.7
@@ -0,0 +1,353 @@
+'\" t
+.\" Title: CREATE DATABASE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE DATABASE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_DATABASE \- create a new database
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE DATABASE \fIname\fR
+ [ WITH ] [ OWNER [=] \fIuser_name\fR ]
+ [ TEMPLATE [=] \fItemplate\fR ]
+ [ ENCODING [=] \fIencoding\fR ]
+ [ STRATEGY [=] \fIstrategy\fR ] ]
+ [ LOCALE [=] \fIlocale\fR ]
+ [ LC_COLLATE [=] \fIlc_collate\fR ]
+ [ LC_CTYPE [=] \fIlc_ctype\fR ]
+ [ ICU_LOCALE [=] \fIicu_locale\fR ]
+ [ LOCALE_PROVIDER [=] \fIlocale_provider\fR ]
+ [ COLLATION_VERSION = \fIcollation_version\fR ]
+ [ TABLESPACE [=] \fItablespace_name\fR ]
+ [ ALLOW_CONNECTIONS [=] \fIallowconn\fR ]
+ [ CONNECTION LIMIT [=] \fIconnlimit\fR ]
+ [ IS_TEMPLATE [=] \fIistemplate\fR ]
+ [ OID [=] \fIoid\fR ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE DATABASE\fR
+creates a new
+PostgreSQL
+database\&.
+.PP
+To create a database, you must be a superuser or have the special
+CREATEDB
+privilege\&. See
+CREATE ROLE (\fBCREATE_ROLE\fR(7))\&.
+.PP
+By default, the new database will be created by cloning the standard system database
+template1\&. A different template can be specified by writing
+TEMPLATE \fIname\fR\&. In particular, by writing
+TEMPLATE template0, you can create a pristine database (one where no user\-defined objects exist and where the system objects have not been altered) containing only the standard objects predefined by your version of
+PostgreSQL\&. This is useful if you wish to avoid copying any installation\-local objects that might have been added to
+template1\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of a database to create\&.
+.RE
+.PP
+\fIuser_name\fR
+.RS 4
+The role name of the user who will own the new database, or
+DEFAULT
+to use the default (namely, the user executing the command)\&. To create a database owned by another role, you must be a direct or indirect member of that role, or be a superuser\&.
+.RE
+.PP
+\fItemplate\fR
+.RS 4
+The name of the template from which to create the new database, or
+DEFAULT
+to use the default template (template1)\&.
+.RE
+.PP
+\fIencoding\fR
+.RS 4
+Character set encoding to use in the new database\&. Specify a string constant (e\&.g\&.,
+\*(AqSQL_ASCII\*(Aq), or an integer encoding number, or
+DEFAULT
+to use the default encoding (namely, the encoding of the template database)\&. The character sets supported by the
+PostgreSQL
+server are described in
+Section\ \&24.3.1\&. See below for additional restrictions\&.
+.RE
+.PP
+\fIstrategy\fR
+.RS 4
+Strategy to be used in creating the new database\&. If the
+WAL_LOG
+strategy is used, the database will be copied block by block and each block will be separately written to the write\-ahead log\&. This is the most efficient strategy in cases where the template database is small, and therefore it is the default\&. The older
+FILE_COPY
+strategy is also available\&. This strategy writes a small record to the write\-ahead log for each tablespace used by the target database\&. Each such record represents copying an entire directory to a new location at the filesystem level\&. While this does reduce the write\-ahead log volume substantially, especially if the template database is large, it also forces the system to perform a checkpoint both before and after the creation of the new database\&. In some situations, this may have a noticeable negative impact on overall system performance\&.
+.RE
+.PP
+\fIlocale\fR
+.RS 4
+This is a shortcut for setting
+LC_COLLATE
+and
+LC_CTYPE
+at once\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+The other locale settings
+lc_messages,
+lc_monetary,
+lc_numeric, and
+lc_time
+are not fixed per database and are not set by this command\&. If you want to make them the default for a specific database, you can use
+ALTER DATABASE \&.\&.\&. SET\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fIlc_collate\fR
+.RS 4
+Collation order (LC_COLLATE) to use in the new database\&. This affects the sort order applied to strings, e\&.g\&., in queries with ORDER BY, as well as the order used in indexes on text columns\&. The default is to use the collation order of the template database\&. See below for additional restrictions\&.
+.RE
+.PP
+\fIlc_ctype\fR
+.RS 4
+Character classification (LC_CTYPE) to use in the new database\&. This affects the categorization of characters, e\&.g\&., lower, upper and digit\&. The default is to use the character classification of the template database\&. See below for additional restrictions\&.
+.RE
+.PP
+\fIicu_locale\fR
+.RS 4
+Specifies the ICU locale ID if the ICU locale provider is used\&.
+.RE
+.PP
+\fIlocale_provider\fR
+.RS 4
+Specifies the provider to use for the default collation in this database\&. Possible values are:
+icu,
+libc\&.
+libc
+is the default\&. The available choices depend on the operating system and build options\&.
+.RE
+.PP
+\fIcollation_version\fR
+.RS 4
+Specifies the collation version string to store with the database\&. Normally, this should be omitted, which will cause the version to be computed from the actual version of the database collation as provided by the operating system\&. This option is intended to be used by
+\fBpg_upgrade\fR
+for copying the version from an existing installation\&.
+.sp
+See also
+ALTER DATABASE (\fBALTER_DATABASE\fR(7))
+for how to handle database collation version mismatches\&.
+.RE
+.PP
+\fItablespace_name\fR
+.RS 4
+The name of the tablespace that will be associated with the new database, or
+DEFAULT
+to use the template database\*(Aqs tablespace\&. This tablespace will be the default tablespace used for objects created in this database\&. See
+CREATE TABLESPACE (\fBCREATE_TABLESPACE\fR(7))
+for more information\&.
+.RE
+.PP
+\fIallowconn\fR
+.RS 4
+If false then no one can connect to this database\&. The default is true, allowing connections (except as restricted by other mechanisms, such as
+GRANT/REVOKE CONNECT)\&.
+.RE
+.PP
+\fIconnlimit\fR
+.RS 4
+How many concurrent connections can be made to this database\&. \-1 (the default) means no limit\&.
+.RE
+.PP
+\fIistemplate\fR
+.RS 4
+If true, then this database can be cloned by any user with
+CREATEDB
+privileges; if false (the default), then only superusers or the owner of the database can clone it\&.
+.RE
+.PP
+\fIoid\fR
+.RS 4
+The object identifier to be used for the new database\&. If this parameter is not specified,
+PostgreSQL
+will choose a suitable OID automatically\&. This parameter is primarily intended for internal use by
+pg_upgrade, and only
+pg_upgrade
+can specify a value less than 16384\&.
+.RE
+.PP
+Optional parameters can be written in any order, not only the order illustrated above\&.
+.SH "NOTES"
+.PP
+\fBCREATE DATABASE\fR
+cannot be executed inside a transaction block\&.
+.PP
+Errors along the line of
+\(lqcould not initialize database directory\(rq
+are most likely related to insufficient permissions on the data directory, a full disk, or other file system problems\&.
+.PP
+Use
+\fBDROP DATABASE\fR
+to remove a database\&.
+.PP
+The program
+\fBcreatedb\fR(1)
+is a wrapper program around this command, provided for convenience\&.
+.PP
+Database\-level configuration parameters (set via
+\fBALTER DATABASE\fR) and database\-level permissions (set via
+\fBGRANT\fR) are not copied from the template database\&.
+.PP
+Although it is possible to copy a database other than
+template1
+by specifying its name as the template, this is not (yet) intended as a general\-purpose
+\(lq\fBCOPY DATABASE\fR\(rq
+facility\&. The principal limitation is that no other sessions can be connected to the template database while it is being copied\&.
+\fBCREATE DATABASE\fR
+will fail if any other connection exists when it starts; otherwise, new connections to the template database are locked out until
+\fBCREATE DATABASE\fR
+completes\&. See
+Section\ \&23.3
+for more information\&.
+.PP
+The character set encoding specified for the new database must be compatible with the chosen locale settings (LC_COLLATE
+and
+LC_CTYPE)\&. If the locale is
+C
+(or equivalently
+POSIX), then all encodings are allowed, but for other locale settings there is only one encoding that will work properly\&. (On Windows, however, UTF\-8 encoding can be used with any locale\&.)
+\fBCREATE DATABASE\fR
+will allow superusers to specify
+SQL_ASCII
+encoding regardless of the locale settings, but this choice is deprecated and may result in misbehavior of character\-string functions if data that is not encoding\-compatible with the locale is stored in the database\&.
+.PP
+The encoding and locale settings must match those of the template database, except when
+template0
+is used as template\&. This is because other databases might contain data that does not match the specified encoding, or might contain indexes whose sort ordering is affected by
+LC_COLLATE
+and
+LC_CTYPE\&. Copying such data would result in a database that is corrupt according to the new settings\&.
+template0, however, is known to not contain any data or indexes that would be affected\&.
+.PP
+There is currently no option to use a database locale with nondeterministic comparisons (see
+\fBCREATE COLLATION\fR
+for an explanation)\&. If this is needed, then per\-column collations would need to be used\&.
+.PP
+The
+CONNECTION LIMIT
+option is only enforced approximately; if two new sessions start at about the same time when just one connection
+\(lqslot\(rq
+remains for the database, it is possible that both will fail\&. Also, the limit is not enforced against superusers or background worker processes\&.
+.SH "EXAMPLES"
+.PP
+To create a new database:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DATABASE lusiadas;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a database
+sales
+owned by user
+salesapp
+with a default tablespace of
+salesspace:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a database
+music
+with a different locale:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DATABASE music
+ LOCALE \*(Aqsv_SE\&.utf8\*(Aq
+ TEMPLATE template0;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In this example, the
+TEMPLATE template0
+clause is required if the specified locale is different from the one in
+template1\&. (If it is not, then specifying the locale explicitly is redundant\&.)
+.PP
+To create a database
+music2
+with a different locale and a different character set encoding:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DATABASE music2
+ LOCALE \*(Aqsv_SE\&.iso885915\*(Aq
+ ENCODING LATIN9
+ TEMPLATE template0;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The specified locale and encoding settings must match, or an error will be reported\&.
+.PP
+Note that locale names are specific to the operating system, so that the above commands might not work in the same way everywhere\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE DATABASE\fR
+statement in the SQL standard\&. Databases are equivalent to catalogs, whose creation is implementation\-defined\&.
+.SH "SEE ALSO"
+ALTER DATABASE (\fBALTER_DATABASE\fR(7)), DROP DATABASE (\fBDROP_DATABASE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_DOMAIN.7 b/doc/src/sgml/man7/CREATE_DOMAIN.7
new file mode 100644
index 0000000..5702b28
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_DOMAIN.7
@@ -0,0 +1,195 @@
+'\" t
+.\" Title: CREATE DOMAIN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE DOMAIN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_DOMAIN \- define a new domain
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE DOMAIN \fIname\fR [ AS ] \fIdata_type\fR
+ [ COLLATE \fIcollation\fR ]
+ [ DEFAULT \fIexpression\fR ]
+ [ \fIconstraint\fR [ \&.\&.\&. ] ]
+
+where \fIconstraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+{ NOT NULL | NULL | CHECK (\fIexpression\fR) }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE DOMAIN\fR
+creates a new domain\&. A domain is essentially a data type with optional constraints (restrictions on the allowed set of values)\&. The user who defines a domain becomes its owner\&.
+.PP
+If a schema name is given (for example,
+CREATE DOMAIN myschema\&.mydomain \&.\&.\&.) then the domain is created in the specified schema\&. Otherwise it is created in the current schema\&. The domain name must be unique among the types and domains existing in its schema\&.
+.PP
+Domains are useful for abstracting common constraints on fields into a single location for maintenance\&. For example, several tables might contain email address columns, all requiring the same CHECK constraint to verify the address syntax\&. Define a domain rather than setting up each table\*(Aqs constraint individually\&.
+.PP
+To be able to create a domain, you must have
+USAGE
+privilege on the underlying type\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of a domain to be created\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The underlying data type of the domain\&. This can include array specifiers\&.
+.RE
+.PP
+\fIcollation\fR
+.RS 4
+An optional collation for the domain\&. If no collation is specified, the domain has the same collation behavior as its underlying data type\&. The underlying type must be collatable if
+COLLATE
+is specified\&.
+.RE
+.PP
+DEFAULT \fIexpression\fR
+.RS 4
+The
+DEFAULT
+clause specifies a default value for columns of the domain data type\&. The value is any variable\-free expression (but subqueries are not allowed)\&. The data type of the default expression must match the data type of the domain\&. If no default value is specified, then the default value is the null value\&.
+.sp
+The default expression will be used in any insert operation that does not specify a value for the column\&. If a default value is defined for a particular column, it overrides any default associated with the domain\&. In turn, the domain default overrides any default value associated with the underlying data type\&.
+.RE
+.PP
+CONSTRAINT \fIconstraint_name\fR
+.RS 4
+An optional name for a constraint\&. If not specified, the system generates a name\&.
+.RE
+.PP
+NOT NULL
+.RS 4
+Values of this domain are prevented from being null (but see notes below)\&.
+.RE
+.PP
+NULL
+.RS 4
+Values of this domain are allowed to be null\&. This is the default\&.
+.sp
+This clause is only intended for compatibility with nonstandard SQL databases\&. Its use is discouraged in new applications\&.
+.RE
+.PP
+CHECK (\fIexpression\fR)
+.RS 4
+CHECK
+clauses specify integrity constraints or tests which values of the domain must satisfy\&. Each constraint must be an expression producing a Boolean result\&. It should use the key word
+VALUE
+to refer to the value being tested\&. Expressions evaluating to TRUE or UNKNOWN succeed\&. If the expression produces a FALSE result, an error is reported and the value is not allowed to be converted to the domain type\&.
+.sp
+Currently,
+CHECK
+expressions cannot contain subqueries nor refer to variables other than
+VALUE\&.
+.sp
+When a domain has multiple
+CHECK
+constraints, they will be tested in alphabetical order by name\&. (PostgreSQL
+versions before 9\&.5 did not honor any particular firing order for
+CHECK
+constraints\&.)
+.RE
+.SH "NOTES"
+.PP
+Domain constraints, particularly
+NOT NULL, are checked when converting a value to the domain type\&. It is possible for a column that is nominally of the domain type to read as null despite there being such a constraint\&. For example, this can happen in an outer\-join query, if the domain column is on the nullable side of the outer join\&. A more subtle example is
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The empty scalar sub\-SELECT will produce a null value that is considered to be of the domain type, so no further constraint checking is applied to it, and the insertion will succeed\&.
+.PP
+It is very difficult to avoid such problems, because of SQL\*(Aqs general assumption that a null value is a valid value of every data type\&. Best practice therefore is to design a domain\*(Aqs constraints so that a null value is allowed, and then to apply column
+NOT NULL
+constraints to columns of the domain type as needed, rather than directly to the domain type\&.
+.PP
+PostgreSQL
+assumes that
+CHECK
+constraints\*(Aq conditions are immutable, that is, they will always give the same result for the same input value\&. This assumption is what justifies examining
+CHECK
+constraints only when a value is first converted to be of a domain type, and not at other times\&. (This is essentially the same as the treatment of table
+CHECK
+constraints, as described in
+Section\ \&5.4.1\&.)
+.PP
+An example of a common way to break this assumption is to reference a user\-defined function in a
+CHECK
+expression, and then change the behavior of that function\&.
+PostgreSQL
+does not disallow that, but it will not notice if there are stored values of the domain type that now violate the
+CHECK
+constraint\&. That would cause a subsequent database dump and restore to fail\&. The recommended way to handle such a change is to drop the constraint (using
+\fBALTER DOMAIN\fR), adjust the function definition, and re\-add the constraint, thereby rechecking it against stored data\&.
+.SH "EXAMPLES"
+.PP
+This example creates the
+us_postal_code
+data type and then uses the type in a table definition\&. A regular expression test is used to verify that the value looks like a valid US postal code:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE DOMAIN us_postal_code AS TEXT
+CHECK(
+ VALUE ~ \*(Aq^\ed{5}$\*(Aq
+OR VALUE ~ \*(Aq^\ed{5}\-\ed{4}$\*(Aq
+);
+
+CREATE TABLE us_snail_addy (
+ address_id SERIAL PRIMARY KEY,
+ street1 TEXT NOT NULL,
+ street2 TEXT,
+ street3 TEXT,
+ city TEXT NOT NULL,
+ postal us_postal_code NOT NULL
+);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The command
+\fBCREATE DOMAIN\fR
+conforms to the SQL standard\&.
+.SH "SEE ALSO"
+ALTER DOMAIN (\fBALTER_DOMAIN\fR(7)), DROP DOMAIN (\fBDROP_DOMAIN\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_EVENT_TRIGGER.7 b/doc/src/sgml/man7/CREATE_EVENT_TRIGGER.7
new file mode 100644
index 0000000..e85d653
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_EVENT_TRIGGER.7
@@ -0,0 +1,129 @@
+'\" t
+.\" Title: CREATE EVENT TRIGGER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE EVENT TRIGGER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_EVENT_TRIGGER \- define a new event trigger
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE EVENT TRIGGER \fIname\fR
+ ON \fIevent\fR
+ [ WHEN \fIfilter_variable\fR IN (\fIfilter_value\fR [, \&.\&.\&. ]) [ AND \&.\&.\&. ] ]
+ EXECUTE { FUNCTION | PROCEDURE } \fIfunction_name\fR()
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE EVENT TRIGGER\fR
+creates a new event trigger\&. Whenever the designated event occurs and the
+WHEN
+condition associated with the trigger, if any, is satisfied, the trigger function will be executed\&. For a general introduction to event triggers, see
+Chapter\ \&40\&. The user who creates an event trigger becomes its owner\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name to give the new trigger\&. This name must be unique within the database\&.
+.RE
+.PP
+\fIevent\fR
+.RS 4
+The name of the event that triggers a call to the given function\&. See
+Section\ \&40.1
+for more information on event names\&.
+.RE
+.PP
+\fIfilter_variable\fR
+.RS 4
+The name of a variable used to filter events\&. This makes it possible to restrict the firing of the trigger to a subset of the cases in which it is supported\&. Currently the only supported
+\fIfilter_variable\fR
+is
+TAG\&.
+.RE
+.PP
+\fIfilter_value\fR
+.RS 4
+A list of values for the associated
+\fIfilter_variable\fR
+for which the trigger should fire\&. For
+TAG, this means a list of command tags (e\&.g\&.,
+\*(AqDROP FUNCTION\*(Aq)\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+A user\-supplied function that is declared as taking no argument and returning type
+event_trigger\&.
+.sp
+In the syntax of
+CREATE EVENT TRIGGER, the keywords
+FUNCTION
+and
+PROCEDURE
+are equivalent, but the referenced function must in any case be a function, not a procedure\&. The use of the keyword
+PROCEDURE
+here is historical and deprecated\&.
+.RE
+.SH "NOTES"
+.PP
+Only superusers can create event triggers\&.
+.PP
+Event triggers are disabled in single\-user mode (see
+\fBpostgres\fR(1))\&. If an erroneous event trigger disables the database so much that you can\*(Aqt even drop the trigger, restart in single\-user mode and you\*(Aqll be able to do that\&.
+.SH "EXAMPLES"
+.PP
+Forbid the execution of any
+DDL
+command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE OR REPLACE FUNCTION abort_any_command()
+ RETURNS event_trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+ RAISE EXCEPTION \*(Aqcommand % is disabled\*(Aq, tg_tag;
+END;
+$$;
+
+CREATE EVENT TRIGGER abort_ddl ON ddl_command_start
+ EXECUTE FUNCTION abort_any_command();
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE EVENT TRIGGER\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER EVENT TRIGGER (\fBALTER_EVENT_TRIGGER\fR(7)), DROP EVENT TRIGGER (\fBDROP_EVENT_TRIGGER\fR(7)), CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_EXTENSION.7 b/doc/src/sgml/man7/CREATE_EXTENSION.7
new file mode 100644
index 0000000..1a98842
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_EXTENSION.7
@@ -0,0 +1,188 @@
+'\" t
+.\" Title: CREATE EXTENSION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE EXTENSION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_EXTENSION \- install an extension
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE EXTENSION [ IF NOT EXISTS ] \fIextension_name\fR
+ [ WITH ] [ SCHEMA \fIschema_name\fR ]
+ [ VERSION \fIversion\fR ]
+ [ CASCADE ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE EXTENSION\fR
+loads a new extension into the current database\&. There must not be an extension of the same name already loaded\&.
+.PP
+Loading an extension essentially amounts to running the extension\*(Aqs script file\&. The script will typically create new
+SQL
+objects such as functions, data types, operators and index support methods\&.
+\fBCREATE EXTENSION\fR
+additionally records the identities of all the created objects, so that they can be dropped again if
+\fBDROP EXTENSION\fR
+is issued\&.
+.PP
+The user who runs
+\fBCREATE EXTENSION\fR
+becomes the owner of the extension for purposes of later privilege checks, and normally also becomes the owner of any objects created by the extension\*(Aqs script\&.
+.PP
+Loading an extension ordinarily requires the same privileges that would be required to create its component objects\&. For many extensions this means superuser privileges are needed\&. However, if the extension is marked
+trusted
+in its control file, then it can be installed by any user who has
+CREATE
+privilege on the current database\&. In this case the extension object itself will be owned by the calling user, but the contained objects will be owned by the bootstrap superuser (unless the extension\*(Aqs script explicitly assigns them to the calling user)\&. This configuration gives the calling user the right to drop the extension, but not to modify individual objects within it\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if an extension with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing extension is anything like the one that would have been created from the currently\-available script file\&.
+.RE
+.PP
+\fIextension_name\fR
+.RS 4
+The name of the extension to be installed\&.
+PostgreSQL
+will create the extension using details from the file
+SHAREDIR/extension/\fIextension_name\fR\&.control\&.
+.RE
+.PP
+\fIschema_name\fR
+.RS 4
+The name of the schema in which to install the extension\*(Aqs objects, given that the extension allows its contents to be relocated\&. The named schema must already exist\&. If not specified, and the extension\*(Aqs control file does not specify a schema either, the current default object creation schema is used\&.
+.sp
+If the extension specifies a
+schema
+parameter in its control file, then that schema cannot be overridden with a
+SCHEMA
+clause\&. Normally, an error will be raised if a
+SCHEMA
+clause is given and it conflicts with the extension\*(Aqs
+schema
+parameter\&. However, if the
+CASCADE
+clause is also given, then
+\fIschema_name\fR
+is ignored when it conflicts\&. The given
+\fIschema_name\fR
+will be used for installation of any needed extensions that do not specify
+schema
+in their control files\&.
+.sp
+Remember that the extension itself is not considered to be within any schema: extensions have unqualified names that must be unique database\-wide\&. But objects belonging to the extension can be within schemas\&.
+.RE
+.PP
+\fIversion\fR
+.RS 4
+The version of the extension to install\&. This can be written as either an identifier or a string literal\&. The default version is whatever is specified in the extension\*(Aqs control file\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically install any extensions that this extension depends on that are not already installed\&. Their dependencies are likewise automatically installed, recursively\&. The
+SCHEMA
+clause, if given, applies to all extensions that get installed this way\&. Other options of the statement are not applied to automatically\-installed extensions; in particular, their default versions are always selected\&.
+.RE
+.SH "NOTES"
+.PP
+Before you can use
+\fBCREATE EXTENSION\fR
+to load an extension into a database, the extension\*(Aqs supporting files must be installed\&. Information about installing the extensions supplied with
+PostgreSQL
+can be found in
+Additional Supplied Modules\&.
+.PP
+The extensions currently available for loading can be identified from the
+pg_available_extensions
+or
+pg_available_extension_versions
+system views\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+Installing an extension as superuser requires trusting that the extension\*(Aqs author wrote the extension installation script in a secure fashion\&. It is not terribly difficult for a malicious user to create trojan\-horse objects that will compromise later execution of a carelessly\-written extension script, allowing that user to acquire superuser privileges\&. However, trojan\-horse objects are only hazardous if they are in the
+\fIsearch_path\fR
+during script execution, meaning that they are in the extension\*(Aqs installation target schema or in the schema of some extension it depends on\&. Therefore, a good rule of thumb when dealing with extensions whose scripts have not been carefully vetted is to install them only into schemas for which CREATE privilege has not been and will not be granted to any untrusted users\&. Likewise for any extensions they depend on\&.
+.PP
+The extensions supplied with
+PostgreSQL
+are believed to be secure against installation\-time attacks of this sort, except for a few that depend on other extensions\&. As stated in the documentation for those extensions, they should be installed into secure schemas, or installed into the same schemas as the extensions they depend on, or both\&.
+.sp .5v
+.RE
+.PP
+For information about writing new extensions, see
+Section\ \&38.17\&.
+.SH "EXAMPLES"
+.PP
+Install the
+hstore
+extension into the current database, placing its objects in schema
+addons:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE EXTENSION hstore SCHEMA addons;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Another way to accomplish the same thing:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SET search_path = addons;
+CREATE EXTENSION hstore;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE EXTENSION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER EXTENSION (\fBALTER_EXTENSION\fR(7)), DROP EXTENSION (\fBDROP_EXTENSION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_FOREIGN_DATA_WRAPPER.7 b/doc/src/sgml/man7/CREATE_FOREIGN_DATA_WRAPPER.7
new file mode 100644
index 0000000..37763b3
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_FOREIGN_DATA_WRAPPER.7
@@ -0,0 +1,143 @@
+'\" t
+.\" Title: CREATE FOREIGN DATA WRAPPER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE FOREIGN DATA WRAPPER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_FOREIGN_DATA_WRAPPER \- define a new foreign\-data wrapper
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE FOREIGN DATA WRAPPER \fIname\fR
+ [ HANDLER \fIhandler_function\fR | NO HANDLER ]
+ [ VALIDATOR \fIvalidator_function\fR | NO VALIDATOR ]
+ [ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE FOREIGN DATA WRAPPER\fR
+creates a new foreign\-data wrapper\&. The user who defines a foreign\-data wrapper becomes its owner\&.
+.PP
+The foreign\-data wrapper name must be unique within the database\&.
+.PP
+Only superusers can create foreign\-data wrappers\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the foreign\-data wrapper to be created\&.
+.RE
+.PP
+HANDLER \fIhandler_function\fR
+.RS 4
+\fIhandler_function\fR
+is the name of a previously registered function that will be called to retrieve the execution functions for foreign tables\&. The handler function must take no arguments, and its return type must be
+fdw_handler\&.
+.sp
+It is possible to create a foreign\-data wrapper with no handler function, but foreign tables using such a wrapper can only be declared, not accessed\&.
+.RE
+.PP
+VALIDATOR \fIvalidator_function\fR
+.RS 4
+\fIvalidator_function\fR
+is the name of a previously registered function that will be called to check the generic options given to the foreign\-data wrapper, as well as options for foreign servers, user mappings and foreign tables using the foreign\-data wrapper\&. If no validator function or
+NO VALIDATOR
+is specified, then options will not be checked at creation time\&. (Foreign\-data wrappers will possibly ignore or reject invalid option specifications at run time, depending on the implementation\&.) The validator function must take two arguments: one of type
+text[], which will contain the array of options as stored in the system catalogs, and one of type
+oid, which will be the OID of the system catalog containing the options\&. The return type is ignored; the function should report invalid options using the
+\fBereport(ERROR)\fR
+function\&.
+.RE
+.PP
+OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] )
+.RS 4
+This clause specifies options for the new foreign\-data wrapper\&. The allowed option names and values are specific to each foreign data wrapper and are validated using the foreign\-data wrapper\*(Aqs validator function\&. Option names must be unique\&.
+.RE
+.SH "NOTES"
+.PP
+PostgreSQL\*(Aqs foreign\-data functionality is still under active development\&. Optimization of queries is primitive (and mostly left to the wrapper, too)\&. Thus, there is considerable room for future performance improvements\&.
+.SH "EXAMPLES"
+.PP
+Create a useless foreign\-data wrapper
+dummy:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FOREIGN DATA WRAPPER dummy;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a foreign\-data wrapper
+file
+with handler function
+file_fdw_handler:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FOREIGN DATA WRAPPER file HANDLER file_fdw_handler;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a foreign\-data wrapper
+mywrapper
+with some options:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FOREIGN DATA WRAPPER mywrapper
+ OPTIONS (debug \*(Aqtrue\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE FOREIGN DATA WRAPPER\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED), with the exception that the
+HANDLER
+and
+VALIDATOR
+clauses are extensions and the standard clauses
+LIBRARY
+and
+LANGUAGE
+are not implemented in
+PostgreSQL\&.
+.PP
+Note, however, that the SQL/MED functionality as a whole is not yet conforming\&.
+.SH "SEE ALSO"
+ALTER FOREIGN DATA WRAPPER (\fBALTER_FOREIGN_DATA_WRAPPER\fR(7)), DROP FOREIGN DATA WRAPPER (\fBDROP_FOREIGN_DATA_WRAPPER\fR(7)), CREATE SERVER (\fBCREATE_SERVER\fR(7)), CREATE USER MAPPING (\fBCREATE_USER_MAPPING\fR(7)), CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_FOREIGN_TABLE.7 b/doc/src/sgml/man7/CREATE_FOREIGN_TABLE.7
new file mode 100644
index 0000000..ac9f516
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_FOREIGN_TABLE.7
@@ -0,0 +1,309 @@
+'\" t
+.\" Title: CREATE FOREIGN TABLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE FOREIGN TABLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_FOREIGN_TABLE \- define a new foreign table
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE FOREIGN TABLE [ IF NOT EXISTS ] \fItable_name\fR ( [
+ { \fIcolumn_name\fR \fIdata_type\fR [ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] ) ] [ COLLATE \fIcollation\fR ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ | \fItable_constraint\fR }
+ [, \&.\&.\&. ]
+] )
+[ INHERITS ( \fIparent_table\fR [, \&.\&.\&. ] ) ]
+ SERVER \fIserver_name\fR
+[ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] ) ]
+
+CREATE FOREIGN TABLE [ IF NOT EXISTS ] \fItable_name\fR
+ PARTITION OF \fIparent_table\fR [ (
+ { \fIcolumn_name\fR [ WITH OPTIONS ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ | \fItable_constraint\fR }
+ [, \&.\&.\&. ]
+) ]
+{ FOR VALUES \fIpartition_bound_spec\fR | DEFAULT }
+ SERVER \fIserver_name\fR
+[ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] ) ]
+
+where \fIcolumn_constraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+{ NOT NULL |
+ NULL |
+ CHECK ( \fIexpression\fR ) [ NO INHERIT ] |
+ DEFAULT \fIdefault_expr\fR |
+ GENERATED ALWAYS AS ( \fIgeneration_expr\fR ) STORED }
+
+and \fItable_constraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+CHECK ( \fIexpression\fR ) [ NO INHERIT ]
+
+and \fIpartition_bound_spec\fR is:
+
+IN ( \fIpartition_bound_expr\fR [, \&.\&.\&.] ) |
+FROM ( { \fIpartition_bound_expr\fR | MINVALUE | MAXVALUE } [, \&.\&.\&.] )
+ TO ( { \fIpartition_bound_expr\fR | MINVALUE | MAXVALUE } [, \&.\&.\&.] ) |
+WITH ( MODULUS \fInumeric_literal\fR, REMAINDER \fInumeric_literal\fR )
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE FOREIGN TABLE\fR
+creates a new foreign table in the current database\&. The table will be owned by the user issuing the command\&.
+.PP
+If a schema name is given (for example,
+CREATE FOREIGN TABLE myschema\&.mytable \&.\&.\&.) then the table is created in the specified schema\&. Otherwise it is created in the current schema\&. The name of the foreign table must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in the same schema\&.
+.PP
+\fBCREATE FOREIGN TABLE\fR
+also automatically creates a data type that represents the composite type corresponding to one row of the foreign table\&. Therefore, foreign tables cannot have the same name as any existing data type in the same schema\&.
+.PP
+If
+PARTITION OF
+clause is specified then the table is created as a partition of
+parent_table
+with specified bounds\&.
+.PP
+To be able to create a foreign table, you must have
+USAGE
+privilege on the foreign server, as well as
+USAGE
+privilege on all column types used in the table\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a relation with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing relation is anything like the one that would have been created\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to be created\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column to be created in the new table\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The data type of the column\&. This can include array specifiers\&. For more information on the data types supported by
+PostgreSQL, refer to
+Chapter\ \&8\&.
+.RE
+.PP
+COLLATE \fIcollation\fR
+.RS 4
+The
+COLLATE
+clause assigns a collation to the column (which must be of a collatable data type)\&. If not specified, the column data type\*(Aqs default collation is used\&.
+.RE
+.PP
+INHERITS ( \fIparent_table\fR [, \&.\&.\&. ] )
+.RS 4
+The optional
+INHERITS
+clause specifies a list of tables from which the new foreign table automatically inherits all columns\&. Parent tables can be plain tables or foreign tables\&. See the similar form of
+\fBCREATE TABLE\fR
+for more details\&.
+.RE
+.PP
+PARTITION OF \fIparent_table\fR { FOR VALUES \fIpartition_bound_spec\fR | DEFAULT }
+.RS 4
+This form can be used to create the foreign table as partition of the given parent table with specified partition bound values\&. See the similar form of
+\fBCREATE TABLE\fR
+for more details\&. Note that it is currently not allowed to create the foreign table as a partition of the parent table if there are
+UNIQUE
+indexes on the parent table\&. (See also
+\fBALTER TABLE ATTACH PARTITION\fR\&.)
+.RE
+.PP
+CONSTRAINT \fIconstraint_name\fR
+.RS 4
+An optional name for a column or table constraint\&. If the constraint is violated, the constraint name is present in error messages, so constraint names like
+col must be positive
+can be used to communicate helpful constraint information to client applications\&. (Double\-quotes are needed to specify constraint names that contain spaces\&.) If a constraint name is not specified, the system generates a name\&.
+.RE
+.PP
+NOT NULL
+.RS 4
+The column is not allowed to contain null values\&.
+.RE
+.PP
+NULL
+.RS 4
+The column is allowed to contain null values\&. This is the default\&.
+.sp
+This clause is only provided for compatibility with non\-standard SQL databases\&. Its use is discouraged in new applications\&.
+.RE
+.PP
+CHECK ( \fIexpression\fR ) [ NO INHERIT ]
+.RS 4
+The
+CHECK
+clause specifies an expression producing a Boolean result which each row in the foreign table is expected to satisfy; that is, the expression should produce TRUE or UNKNOWN, never FALSE, for all rows in the foreign table\&. A check constraint specified as a column constraint should reference that column\*(Aqs value only, while an expression appearing in a table constraint can reference multiple columns\&.
+.sp
+Currently,
+CHECK
+expressions cannot contain subqueries nor refer to variables other than columns of the current row\&. The system column
+tableoid
+may be referenced, but not any other system column\&.
+.sp
+A constraint marked with
+NO INHERIT
+will not propagate to child tables\&.
+.RE
+.PP
+DEFAULT \fIdefault_expr\fR
+.RS 4
+The
+DEFAULT
+clause assigns a default data value for the column whose column definition it appears within\&. The value is any variable\-free expression (subqueries and cross\-references to other columns in the current table are not allowed)\&. The data type of the default expression must match the data type of the column\&.
+.sp
+The default expression will be used in any insert operation that does not specify a value for the column\&. If there is no default for a column, then the default is null\&.
+.RE
+.PP
+GENERATED ALWAYS AS ( \fIgeneration_expr\fR ) STORED
+.RS 4
+This clause creates the column as a
+generated column\&. The column cannot be written to, and when read the result of the specified expression will be returned\&.
+.sp
+The keyword
+STORED
+is required to signify that the column will be computed on write\&. (The computed value will be presented to the foreign\-data wrapper for storage and must be returned on reading\&.)
+.sp
+The generation expression can refer to other columns in the table, but not other generated columns\&. Any functions and operators used must be immutable\&. References to other tables are not allowed\&.
+.RE
+.PP
+\fIserver_name\fR
+.RS 4
+The name of an existing foreign server to use for the foreign table\&. For details on defining a server, see
+CREATE SERVER (\fBCREATE_SERVER\fR(7))\&.
+.RE
+.PP
+OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&.] )
+.RS 4
+Options to be associated with the new foreign table or one of its columns\&. The allowed option names and values are specific to each foreign data wrapper and are validated using the foreign\-data wrapper\*(Aqs validator function\&. Duplicate option names are not allowed (although it\*(Aqs OK for a table option and a column option to have the same name)\&.
+.RE
+.SH "NOTES"
+.PP
+Constraints on foreign tables (such as
+CHECK
+or
+NOT NULL
+clauses) are not enforced by the core
+PostgreSQL
+system, and most foreign data wrappers do not attempt to enforce them either; that is, the constraint is simply assumed to hold true\&. There would be little point in such enforcement since it would only apply to rows inserted or updated via the foreign table, and not to rows modified by other means, such as directly on the remote server\&. Instead, a constraint attached to a foreign table should represent a constraint that is being enforced by the remote server\&.
+.PP
+Some special\-purpose foreign data wrappers might be the only access mechanism for the data they access, and in that case it might be appropriate for the foreign data wrapper itself to perform constraint enforcement\&. But you should not assume that a wrapper does that unless its documentation says so\&.
+.PP
+Although
+PostgreSQL
+does not attempt to enforce constraints on foreign tables, it does assume that they are correct for purposes of query optimization\&. If there are rows visible in the foreign table that do not satisfy a declared constraint, queries on the table might produce errors or incorrect answers\&. It is the user\*(Aqs responsibility to ensure that the constraint definition matches reality\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+When a foreign table is used as a partition of a partitioned table, there is an implicit constraint that its contents must satisfy the partitioning rule\&. Again, it is the user\*(Aqs responsibility to ensure that that is true, which is best done by installing a matching constraint on the remote server\&.
+.sp .5v
+.RE
+.PP
+Within a partitioned table containing foreign\-table partitions, an
+\fBUPDATE\fR
+that changes the partition key value can cause a row to be moved from a local partition to a foreign\-table partition, provided the foreign data wrapper supports tuple routing\&. However it is not currently possible to move a row from a foreign\-table partition to another partition\&. An
+\fBUPDATE\fR
+that would require doing that will fail due to the partitioning constraint, assuming that that is properly enforced by the remote server\&.
+.PP
+Similar considerations apply to generated columns\&. Stored generated columns are computed on insert or update on the local
+PostgreSQL
+server and handed to the foreign\-data wrapper for writing out to the foreign data store, but it is not enforced that a query of the foreign table returns values for stored generated columns that are consistent with the generation expression\&. Again, this might result in incorrect query results\&.
+.SH "EXAMPLES"
+.PP
+Create foreign table
+films, which will be accessed through the server
+film_server:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FOREIGN TABLE films (
+ code char(5) NOT NULL,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+)
+SERVER film_server;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create foreign table
+measurement_y2016m07, which will be accessed through the server
+server_07, as a partition of the range partitioned table
+measurement:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FOREIGN TABLE measurement_y2016m07
+ PARTITION OF measurement FOR VALUES FROM (\*(Aq2016\-07\-01\*(Aq) TO (\*(Aq2016\-08\-01\*(Aq)
+ SERVER server_07;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCREATE FOREIGN TABLE\fR
+command largely conforms to the
+SQL
+standard; however, much as with
+\fBCREATE TABLE\fR,
+NULL
+constraints and zero\-column foreign tables are permitted\&. The ability to specify column default values is also a
+PostgreSQL
+extension\&. Table inheritance, in the form defined by
+PostgreSQL, is nonstandard\&.
+.SH "SEE ALSO"
+ALTER FOREIGN TABLE (\fBALTER_FOREIGN_TABLE\fR(7)), DROP FOREIGN TABLE (\fBDROP_FOREIGN_TABLE\fR(7)), CREATE TABLE (\fBCREATE_TABLE\fR(7)), CREATE SERVER (\fBCREATE_SERVER\fR(7)), IMPORT FOREIGN SCHEMA (\fBIMPORT_FOREIGN_SCHEMA\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_FUNCTION.7 b/doc/src/sgml/man7/CREATE_FUNCTION.7
new file mode 100644
index 0000000..c916f45
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_FUNCTION.7
@@ -0,0 +1,781 @@
+'\" t
+.\" Title: CREATE FUNCTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE FUNCTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_FUNCTION \- define a new function
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] FUNCTION
+ \fIname\fR ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ { DEFAULT | = } \fIdefault_expr\fR ] [, \&.\&.\&.] ] )
+ [ RETURNS \fIrettype\fR
+ | RETURNS TABLE ( \fIcolumn_name\fR \fIcolumn_type\fR [, \&.\&.\&.] ) ]
+ { LANGUAGE \fIlang_name\fR
+ | TRANSFORM { FOR TYPE \fItype_name\fR } [, \&.\&.\&. ]
+ | WINDOW
+ | { IMMUTABLE | STABLE | VOLATILE }
+ | [ NOT ] LEAKPROOF
+ | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
+ | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
+ | PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ | COST \fIexecution_cost\fR
+ | ROWS \fIresult_rows\fR
+ | SUPPORT \fIsupport_function\fR
+ | SET \fIconfiguration_parameter\fR { TO \fIvalue\fR | = \fIvalue\fR | FROM CURRENT }
+ | AS \*(Aq\fIdefinition\fR\*(Aq
+ | AS \*(Aq\fIobj_file\fR\*(Aq, \*(Aq\fIlink_symbol\fR\*(Aq
+ | \fIsql_body\fR
+ } \&.\&.\&.
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE FUNCTION\fR
+defines a new function\&.
+\fBCREATE OR REPLACE FUNCTION\fR
+will either create a new function, or replace an existing definition\&. To be able to define a function, the user must have the
+USAGE
+privilege on the language\&.
+.PP
+If a schema name is included, then the function is created in the specified schema\&. Otherwise it is created in the current schema\&. The name of the new function must not match any existing function or procedure with the same input argument types in the same schema\&. However, functions and procedures of different argument types can share a name (this is called
+overloading)\&.
+.PP
+To replace the current definition of an existing function, use
+\fBCREATE OR REPLACE FUNCTION\fR\&. It is not possible to change the name or argument types of a function this way (if you tried, you would actually be creating a new, distinct function)\&. Also,
+\fBCREATE OR REPLACE FUNCTION\fR
+will not let you change the return type of an existing function\&. To do that, you must drop and recreate the function\&. (When using
+OUT
+parameters, that means you cannot change the types of any
+OUT
+parameters except by dropping the function\&.)
+.PP
+When
+\fBCREATE OR REPLACE FUNCTION\fR
+is used to replace an existing function, the ownership and permissions of the function do not change\&. All other function properties are assigned the values specified or implied in the command\&. You must own the function to replace it (this includes being a member of the owning role)\&.
+.PP
+If you drop and then recreate a function, the new function is not the same entity as the old; you will have to drop existing rules, views, triggers, etc\&. that refer to the old function\&. Use
+\fBCREATE OR REPLACE FUNCTION\fR
+to change a function definition without breaking objects that refer to the function\&. Also,
+\fBALTER FUNCTION\fR
+can be used to change most of the auxiliary properties of an existing function\&.
+.PP
+The user that creates the function becomes the owner of the function\&.
+.PP
+To be able to create a function, you must have
+USAGE
+privilege on the argument types and the return type\&.
+.PP
+Refer to
+Section\ \&38.3
+for further information on writing functions\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the function to create\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&. Only
+OUT
+arguments can follow a
+VARIADIC
+one\&. Also,
+OUT
+and
+INOUT
+arguments cannot be used together with the
+RETURNS TABLE
+notation\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Some languages (including SQL and PL/pgSQL) let you use the name in the function body\&. For other languages the name of an input argument is just extra documentation, so far as the function itself is concerned; but you can use input argument names when calling a function to improve readability (see
+Section\ \&4.3)\&. In any case, the name of an output argument is significant, because it defines the column name in the result row type\&. (If you omit the name for an output argument, the system will choose a default column name\&.)
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type(s) of the function\*(Aqs arguments (optionally schema\-qualified), if any\&. The argument types can be base, composite, or domain types, or can reference the type of a table column\&.
+.sp
+Depending on the implementation language it might also be allowed to specify
+\(lqpseudo\-types\(rq
+such as
+cstring\&. Pseudo\-types indicate that the actual argument type is either incompletely specified, or outside the set of ordinary SQL data types\&.
+.sp
+The type of a column is referenced by writing
+\fItable_name\fR\&.\fIcolumn_name\fR%TYPE\&. Using this feature can sometimes help make a function independent of changes to the definition of a table\&.
+.RE
+.PP
+\fIdefault_expr\fR
+.RS 4
+An expression to be used as default value if the parameter is not specified\&. The expression has to be coercible to the argument type of the parameter\&. Only input (including
+INOUT) parameters can have a default value\&. All input parameters following a parameter with a default value must have default values as well\&.
+.RE
+.PP
+\fIrettype\fR
+.RS 4
+The return data type (optionally schema\-qualified)\&. The return type can be a base, composite, or domain type, or can reference the type of a table column\&. Depending on the implementation language it might also be allowed to specify
+\(lqpseudo\-types\(rq
+such as
+cstring\&. If the function is not supposed to return a value, specify
+void
+as the return type\&.
+.sp
+When there are
+OUT
+or
+INOUT
+parameters, the
+RETURNS
+clause can be omitted\&. If present, it must agree with the result type implied by the output parameters:
+RECORD
+if there are multiple output parameters, or the same type as the single output parameter\&.
+.sp
+The
+SETOF
+modifier indicates that the function will return a set of items, rather than a single item\&.
+.sp
+The type of a column is referenced by writing
+\fItable_name\fR\&.\fIcolumn_name\fR%TYPE\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of an output column in the
+RETURNS TABLE
+syntax\&. This is effectively another way of declaring a named
+OUT
+parameter, except that
+RETURNS TABLE
+also implies
+RETURNS SETOF\&.
+.RE
+.PP
+\fIcolumn_type\fR
+.RS 4
+The data type of an output column in the
+RETURNS TABLE
+syntax\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the language that the function is implemented in\&. It can be
+sql,
+c,
+internal, or the name of a user\-defined procedural language, e\&.g\&.,
+plpgsql\&. The default is
+sql
+if
+\fIsql_body\fR
+is specified\&. Enclosing the name in single quotes is deprecated and requires matching case\&.
+.RE
+.PP
+TRANSFORM { FOR TYPE \fItype_name\fR } [, \&.\&.\&. ] }
+.RS 4
+Lists which transforms a call to the function should apply\&. Transforms convert between SQL types and language\-specific data types; see
+CREATE TRANSFORM (\fBCREATE_TRANSFORM\fR(7))\&. Procedural language implementations usually have hardcoded knowledge of the built\-in types, so those don\*(Aqt need to be listed here\&. If a procedural language implementation does not know how to handle a type and no transform is supplied, it will fall back to a default behavior for converting data types, but this depends on the implementation\&.
+.RE
+.PP
+WINDOW
+.RS 4
+WINDOW
+indicates that the function is a
+window function
+rather than a plain function\&. This is currently only useful for functions written in C\&. The
+WINDOW
+attribute cannot be changed when replacing an existing function definition\&.
+.RE
+.PP
+IMMUTABLE
+.br
+STABLE
+.br
+VOLATILE
+.RS 4
+These attributes inform the query optimizer about the behavior of the function\&. At most one choice can be specified\&. If none of these appear,
+VOLATILE
+is the default assumption\&.
+.sp
+IMMUTABLE
+indicates that the function cannot modify the database and always returns the same result when given the same argument values; that is, it does not do database lookups or otherwise use information not directly present in its argument list\&. If this option is given, any call of the function with all\-constant arguments can be immediately replaced with the function value\&.
+.sp
+STABLE
+indicates that the function cannot modify the database, and that within a single table scan it will consistently return the same result for the same argument values, but that its result could change across SQL statements\&. This is the appropriate selection for functions whose results depend on database lookups, parameter variables (such as the current time zone), etc\&. (It is inappropriate for
+AFTER
+triggers that wish to query rows modified by the current command\&.) Also note that the
+\fBcurrent_timestamp\fR
+family of functions qualify as stable, since their values do not change within a transaction\&.
+.sp
+VOLATILE
+indicates that the function value can change even within a single table scan, so no optimizations can be made\&. Relatively few database functions are volatile in this sense; some examples are
+random(),
+currval(),
+timeofday()\&. But note that any function that has side\-effects must be classified volatile, even if its result is quite predictable, to prevent calls from being optimized away; an example is
+setval()\&.
+.sp
+For additional details see
+Section\ \&38.7\&.
+.RE
+.PP
+LEAKPROOF
+.RS 4
+LEAKPROOF
+indicates that the function has no side effects\&. It reveals no information about its arguments other than by its return value\&. For example, a function which throws an error message for some argument values but not others, or which includes the argument values in any error message, is not leakproof\&. This affects how the system executes queries against views created with the
+security_barrier
+option or tables with row level security enabled\&. The system will enforce conditions from security policies and security barrier views before any user\-supplied conditions from the query itself that contain non\-leakproof functions, in order to prevent the inadvertent exposure of data\&. Functions and operators marked as leakproof are assumed to be trustworthy, and may be executed before conditions from security policies and security barrier views\&. In addition, functions which do not take arguments or which are not passed any arguments from the security barrier view or table do not have to be marked as leakproof to be executed before security conditions\&. See
+CREATE VIEW (\fBCREATE_VIEW\fR(7))
+and
+Section\ \&41.5\&. This option can only be set by the superuser\&.
+.RE
+.PP
+CALLED ON NULL INPUT
+.br
+RETURNS NULL ON NULL INPUT
+.br
+STRICT
+.RS 4
+CALLED ON NULL INPUT
+(the default) indicates that the function will be called normally when some of its arguments are null\&. It is then the function author\*(Aqs responsibility to check for null values if necessary and respond appropriately\&.
+.sp
+RETURNS NULL ON NULL INPUT
+or
+STRICT
+indicates that the function always returns null whenever any of its arguments are null\&. If this parameter is specified, the function is not executed when there are null arguments; instead a null result is assumed automatically\&.
+.RE
+.PP
+[EXTERNAL] SECURITY INVOKER
+.br
+[EXTERNAL] SECURITY DEFINER
+.RS 4
+SECURITY INVOKER
+indicates that the function is to be executed with the privileges of the user that calls it\&. That is the default\&.
+SECURITY DEFINER
+specifies that the function is to be executed with the privileges of the user that owns it\&.
+.sp
+The key word
+EXTERNAL
+is allowed for SQL conformance, but it is optional since, unlike in SQL, this feature applies to all functions not only external ones\&.
+.RE
+.PP
+PARALLEL
+.RS 4
+PARALLEL UNSAFE
+indicates that the function can\*(Aqt be executed in parallel mode and the presence of such a function in an SQL statement forces a serial execution plan\&. This is the default\&.
+PARALLEL RESTRICTED
+indicates that the function can be executed in parallel mode, but the execution is restricted to parallel group leader\&.
+PARALLEL SAFE
+indicates that the function is safe to run in parallel mode without restriction\&.
+.sp
+Functions should be labeled parallel unsafe if they modify any database state, or if they make changes to the transaction such as using sub\-transactions, or if they access sequences or attempt to make persistent changes to settings (e\&.g\&.,
+setval)\&. They should be labeled as parallel restricted if they access temporary tables, client connection state, cursors, prepared statements, or miscellaneous backend\-local state which the system cannot synchronize in parallel mode (e\&.g\&.,
+setseed
+cannot be executed other than by the group leader because a change made by another process would not be reflected in the leader)\&. In general, if a function is labeled as being safe when it is restricted or unsafe, or if it is labeled as being restricted when it is in fact unsafe, it may throw errors or produce wrong answers when used in a parallel query\&. C\-language functions could in theory exhibit totally undefined behavior if mislabeled, since there is no way for the system to protect itself against arbitrary C code, but in most likely cases the result will be no worse than for any other function\&. If in doubt, functions should be labeled as
+UNSAFE, which is the default\&.
+.RE
+.PP
+COST \fIexecution_cost\fR
+.RS 4
+A positive number giving the estimated execution cost for the function, in units of
+cpu_operator_cost\&. If the function returns a set, this is the cost per returned row\&. If the cost is not specified, 1 unit is assumed for C\-language and internal functions, and 100 units for functions in all other languages\&. Larger values cause the planner to try to avoid evaluating the function more often than necessary\&.
+.RE
+.PP
+ROWS \fIresult_rows\fR
+.RS 4
+A positive number giving the estimated number of rows that the planner should expect the function to return\&. This is only allowed when the function is declared to return a set\&. The default assumption is 1000 rows\&.
+.RE
+.PP
+SUPPORT \fIsupport_function\fR
+.RS 4
+The name (optionally schema\-qualified) of a
+planner support function
+to use for this function\&. See
+Section\ \&38.11
+for details\&. You must be superuser to use this option\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.br
+\fIvalue\fR
+.RS 4
+The
+SET
+clause causes the specified configuration parameter to be set to the specified value when the function is entered, and then restored to its prior value when the function exits\&.
+SET FROM CURRENT
+saves the value of the parameter that is current when
+\fBCREATE FUNCTION\fR
+is executed as the value to be applied when the function is entered\&.
+.sp
+If a
+SET
+clause is attached to a function, then the effects of a
+\fBSET LOCAL\fR
+command executed inside the function for the same variable are restricted to the function: the configuration parameter\*(Aqs prior value is still restored at function exit\&. However, an ordinary
+\fBSET\fR
+command (without
+LOCAL) overrides the
+SET
+clause, much as it would do for a previous
+\fBSET LOCAL\fR
+command: the effects of such a command will persist after function exit, unless the current transaction is rolled back\&.
+.sp
+See
+\fBSET\fR(7)
+and
+Chapter\ \&20
+for more information about allowed parameter names and values\&.
+.RE
+.PP
+\fIdefinition\fR
+.RS 4
+A string constant defining the function; the meaning depends on the language\&. It can be an internal function name, the path to an object file, an SQL command, or text in a procedural language\&.
+.sp
+It is often helpful to use dollar quoting (see
+Section\ \&4.1.2.4) to write the function definition string, rather than the normal single quote syntax\&. Without dollar quoting, any single quotes or backslashes in the function definition must be escaped by doubling them\&.
+.RE
+.PP
+\fIobj_file\fR, \fIlink_symbol\fR
+.RS 4
+This form of the
+AS
+clause is used for dynamically loadable C language functions when the function name in the C language source code is not the same as the name of the SQL function\&. The string
+\fIobj_file\fR
+is the name of the shared library file containing the compiled C function, and is interpreted as for the
+\fBLOAD\fR
+command\&. The string
+\fIlink_symbol\fR
+is the function\*(Aqs link symbol, that is, the name of the function in the C language source code\&. If the link symbol is omitted, it is assumed to be the same as the name of the SQL function being defined\&. The C names of all functions must be different, so you must give overloaded C functions different C names (for example, use the argument types as part of the C names)\&.
+.sp
+When repeated
+\fBCREATE FUNCTION\fR
+calls refer to the same object file, the file is only loaded once per session\&. To unload and reload the file (perhaps during development), start a new session\&.
+.RE
+.PP
+\fIsql_body\fR
+.RS 4
+The body of a
+LANGUAGE SQL
+function\&. This can either be a single statement
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+RETURN \fIexpression\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+or a block
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN ATOMIC
+ \fIstatement\fR;
+ \fIstatement\fR;
+ \&.\&.\&.
+ \fIstatement\fR;
+END
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This is similar to writing the text of the function body as a string constant (see
+\fIdefinition\fR
+above), but there are some differences: This form only works for
+LANGUAGE SQL, the string constant form works for all languages\&. This form is parsed at function definition time, the string constant form is parsed at execution time; therefore this form cannot support polymorphic argument types and other constructs that are not resolvable at function definition time\&. This form tracks dependencies between the function and objects used in the function body, so
+DROP \&.\&.\&. CASCADE
+will work correctly, whereas the form using string literals may leave dangling functions\&. Finally, this form is more compatible with the SQL standard and other SQL implementations\&.
+.RE
+.SH "OVERLOADING"
+.PP
+PostgreSQL
+allows function
+overloading; that is, the same name can be used for several different functions so long as they have distinct input argument types\&. Whether or not you use it, this capability entails security precautions when calling functions in databases where some users mistrust other users; see
+Section\ \&10.3\&.
+.PP
+Two functions are considered the same if they have the same names and
+\fIinput\fR
+argument types, ignoring any
+OUT
+parameters\&. Thus for example these declarations conflict:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION foo(int) \&.\&.\&.
+CREATE FUNCTION foo(int, out text) \&.\&.\&.
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Functions that have different argument type lists will not be considered to conflict at creation time, but if defaults are provided they might conflict in use\&. For example, consider
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION foo(int) \&.\&.\&.
+CREATE FUNCTION foo(int, int default 42) \&.\&.\&.
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A call
+foo(10)
+will fail due to the ambiguity about which function should be called\&.
+.SH "NOTES"
+.PP
+The full
+SQL
+type syntax is allowed for declaring a function\*(Aqs arguments and return value\&. However, parenthesized type modifiers (e\&.g\&., the precision field for type
+numeric) are discarded by
+\fBCREATE FUNCTION\fR\&. Thus for example
+CREATE FUNCTION foo (varchar(10)) \&.\&.\&.
+is exactly the same as
+CREATE FUNCTION foo (varchar) \&.\&.\&.\&.
+.PP
+When replacing an existing function with
+\fBCREATE OR REPLACE FUNCTION\fR, there are restrictions on changing parameter names\&. You cannot change the name already assigned to any input parameter (although you can add names to parameters that had none before)\&. If there is more than one output parameter, you cannot change the names of the output parameters, because that would change the column names of the anonymous composite type that describes the function\*(Aqs result\&. These restrictions are made to ensure that existing calls of the function do not stop working when it is replaced\&.
+.PP
+If a function is declared
+STRICT
+with a
+VARIADIC
+argument, the strictness check tests that the variadic array
+\fIas a whole\fR
+is non\-null\&. The function will still be called if the array has null elements\&.
+.SH "EXAMPLES"
+.PP
+Add two integers using an SQL function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION add(integer, integer) RETURNS integer
+ AS \*(Aqselect $1 + $2;\*(Aq
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The same function written in a more SQL\-conforming style, using argument names and an unquoted body:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION add(a integer, b integer) RETURNS integer
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT
+ RETURN a + b;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Increment an integer, making use of an argument name, in
+PL/pgSQL:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
+ BEGIN
+ RETURN i + 1;
+ END;
+$$ LANGUAGE plpgsql;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Return a record containing multiple output parameters:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION dup(in int, out f1 int, out f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || \*(Aq is text\*(Aq $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+You can do the same thing more verbosely with an explicitly named composite type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE dup_result AS (f1 int, f2 text);
+
+CREATE FUNCTION dup(int) RETURNS dup_result
+ AS $$ SELECT $1, CAST($1 AS text) || \*(Aq is text\*(Aq $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Another way to return multiple columns is to use a
+TABLE
+function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || \*(Aq is text\*(Aq $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+However, a
+TABLE
+function is different from the preceding examples, because it actually returns a
+\fIset\fR
+of records, not just one record\&.
+.SH "WRITING SECURITY DEFINER FUNCTIONS SAFELY"
+.PP
+Because a
+SECURITY DEFINER
+function is executed with the privileges of the user that owns it, care is needed to ensure that the function cannot be misused\&. For security,
+search_path
+should be set to exclude any schemas writable by untrusted users\&. This prevents malicious users from creating objects (e\&.g\&., tables, functions, and operators) that mask objects intended to be used by the function\&. Particularly important in this regard is the temporary\-table schema, which is searched first by default, and is normally writable by anyone\&. A secure arrangement can be obtained by forcing the temporary schema to be searched last\&. To do this, write
+pg_temp
+as the last entry in
+\fIsearch_path\fR\&. This function illustrates safe usage:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION check_password(uname TEXT, pass TEXT)
+RETURNS BOOLEAN AS $$
+DECLARE passed BOOLEAN;
+BEGIN
+ SELECT (pwd = $2) INTO passed
+ FROM pwds
+ WHERE username = $1;
+
+ RETURN passed;
+END;
+$$ LANGUAGE plpgsql
+ SECURITY DEFINER
+ \-\- Set a secure search_path: trusted schema(s), then \*(Aqpg_temp\*(Aq\&.
+ SET search_path = admin, pg_temp;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This function\*(Aqs intention is to access a table
+admin\&.pwds\&. But without the
+SET
+clause, or with a
+SET
+clause mentioning only
+admin, the function could be subverted by creating a temporary table named
+pwds\&.
+.PP
+Before
+PostgreSQL
+version 8\&.3, the
+SET
+clause was not available, and so older functions may contain rather complicated logic to save, set, and restore
+\fIsearch_path\fR\&. The
+SET
+clause is far easier to use for this purpose\&.
+.PP
+Another point to keep in mind is that by default, execute privilege is granted to
+PUBLIC
+for newly created functions (see
+Section\ \&5.7
+for more information)\&. Frequently you will wish to restrict use of a security definer function to only some users\&. To do that, you must revoke the default
+PUBLIC
+privileges and then grant execute privilege selectively\&. To avoid having a window where the new function is accessible to all, create it and set the privileges within a single transaction\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+CREATE FUNCTION check_password(uname TEXT, pass TEXT) \&.\&.\&. SECURITY DEFINER;
+REVOKE ALL ON FUNCTION check_password(uname TEXT, pass TEXT) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION check_password(uname TEXT, pass TEXT) TO admins;
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+A
+\fBCREATE FUNCTION\fR
+command is defined in the SQL standard\&. The
+PostgreSQL
+implementation can be used in a compatible way but has many extensions\&. Conversely, the SQL standard specifies a number of optional features that are not implemented in
+PostgreSQL\&.
+.PP
+The following are important compatibility issues:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+OR REPLACE
+is a PostgreSQL extension\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+For compatibility with some other database systems,
+\fIargmode\fR
+can be written either before or after
+\fIargname\fR\&. But only the first way is standard\-compliant\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+For parameter defaults, the SQL standard specifies only the syntax with the
+DEFAULT
+key word\&. The syntax with
+=
+is used in T\-SQL and Firebird\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+SETOF
+modifier is a PostgreSQL extension\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Only
+SQL
+is standardized as a language\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+All other attributes except
+CALLED ON NULL INPUT
+and
+RETURNS NULL ON NULL INPUT
+are not standardized\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+For the body of
+LANGUAGE SQL
+functions, the SQL standard only specifies the
+\fIsql_body\fR
+form\&.
+.RE
+.PP
+Simple
+LANGUAGE SQL
+functions can be written in a way that is both standard\-conforming and portable to other implementations\&. More complex functions using advanced features, optimization attributes, or other languages will necessarily be specific to PostgreSQL in a significant way\&.
+.SH "SEE ALSO"
+ALTER FUNCTION (\fBALTER_FUNCTION\fR(7)), DROP FUNCTION (\fBDROP_FUNCTION\fR(7)), \fBGRANT\fR(7), \fBLOAD\fR(7), \fBREVOKE\fR(7)
diff --git a/doc/src/sgml/man7/CREATE_GROUP.7 b/doc/src/sgml/man7/CREATE_GROUP.7
new file mode 100644
index 0000000..a803ba5
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_GROUP.7
@@ -0,0 +1,67 @@
+'\" t
+.\" Title: CREATE GROUP
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE GROUP" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_GROUP \- define a new database role
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE GROUP \fIname\fR [ [ WITH ] \fIoption\fR [ \&.\&.\&. ] ]
+
+where \fIoption\fR can be:
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT \fIconnlimit\fR
+ | [ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq | PASSWORD NULL
+ | VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+ | IN ROLE \fIrole_name\fR [, \&.\&.\&.]
+ | IN GROUP \fIrole_name\fR [, \&.\&.\&.]
+ | ROLE \fIrole_name\fR [, \&.\&.\&.]
+ | ADMIN \fIrole_name\fR [, \&.\&.\&.]
+ | USER \fIrole_name\fR [, \&.\&.\&.]
+ | SYSID \fIuid\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE GROUP\fR
+is now an alias for
+CREATE ROLE (\fBCREATE_ROLE\fR(7))\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE GROUP\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE ROLE (\fBCREATE_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_INDEX.7 b/doc/src/sgml/man7/CREATE_INDEX.7
new file mode 100644
index 0000000..371a36d
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_INDEX.7
@@ -0,0 +1,766 @@
+'\" t
+.\" Title: CREATE INDEX
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE INDEX" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_INDEX \- define a new index
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] \fIname\fR ] ON [ ONLY ] \fItable_name\fR [ USING \fImethod\fR ]
+ ( { \fIcolumn_name\fR | ( \fIexpression\fR ) } [ COLLATE \fIcollation\fR ] [ \fIopclass\fR [ ( \fIopclass_parameter\fR = \fIvalue\fR [, \&.\&.\&. ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, \&.\&.\&.] )
+ [ INCLUDE ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ [ NULLS [ NOT ] DISTINCT ]
+ [ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+ [ TABLESPACE \fItablespace_name\fR ]
+ [ WHERE \fIpredicate\fR ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE INDEX\fR
+constructs an index on the specified column(s) of the specified relation, which can be a table or a materialized view\&. Indexes are primarily used to enhance database performance (though inappropriate use can result in slower performance)\&.
+.PP
+The key field(s) for the index are specified as column names, or alternatively as expressions written in parentheses\&. Multiple fields can be specified if the index method supports multicolumn indexes\&.
+.PP
+An index field can be an expression computed from the values of one or more columns of the table row\&. This feature can be used to obtain fast access to data based on some transformation of the basic data\&. For example, an index computed on
+upper(col)
+would allow the clause
+WHERE upper(col) = \*(AqJIM\*(Aq
+to use an index\&.
+.PP
+PostgreSQL
+provides the index methods B\-tree, hash, GiST, SP\-GiST, GIN, and BRIN\&. Users can also define their own index methods, but that is fairly complicated\&.
+.PP
+When the
+WHERE
+clause is present, a
+partial index
+is created\&. A partial index is an index that contains entries for only a portion of a table, usually a portion that is more useful for indexing than the rest of the table\&. For example, if you have a table that contains both billed and unbilled orders where the unbilled orders take up a small fraction of the total table and yet that is an often used section, you can improve performance by creating an index on just that portion\&. Another possible application is to use
+WHERE
+with
+UNIQUE
+to enforce uniqueness over a subset of a table\&. See
+Section\ \&11.8
+for more discussion\&.
+.PP
+The expression used in the
+WHERE
+clause can refer only to columns of the underlying table, but it can use all columns, not just the ones being indexed\&. Presently, subqueries and aggregate expressions are also forbidden in
+WHERE\&. The same restrictions apply to index fields that are expressions\&.
+.PP
+All functions and operators used in an index definition must be
+\(lqimmutable\(rq, that is, their results must depend only on their arguments and never on any outside influence (such as the contents of another table or the current time)\&. This restriction ensures that the behavior of the index is well\-defined\&. To use a user\-defined function in an index expression or
+WHERE
+clause, remember to mark the function immutable when you create it\&.
+.SH "PARAMETERS"
+.PP
+UNIQUE
+.RS 4
+Causes the system to check for duplicate values in the table when the index is created (if data already exist) and each time data is added\&. Attempts to insert or update data which would result in duplicate entries will generate an error\&.
+.sp
+Additional restrictions apply when unique indexes are applied to partitioned tables; see
+CREATE TABLE (\fBCREATE_TABLE\fR(7))\&.
+.RE
+.PP
+CONCURRENTLY
+.RS 4
+When this option is used,
+PostgreSQL
+will build the index without taking any locks that prevent concurrent inserts, updates, or deletes on the table; whereas a standard index build locks out writes (but not reads) on the table until it\*(Aqs done\&. There are several caveats to be aware of when using this option \(em see
+Building Indexes Concurrently
+below\&.
+.sp
+For temporary tables,
+\fBCREATE INDEX\fR
+is always non\-concurrent, as no other session can access them, and non\-concurrent index creation is cheaper\&.
+.RE
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a relation with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing index is anything like the one that would have been created\&. Index name is required when
+IF NOT EXISTS
+is specified\&.
+.RE
+.PP
+INCLUDE
+.RS 4
+The optional
+INCLUDE
+clause specifies a list of columns which will be included in the index as
+non\-key
+columns\&. A non\-key column cannot be used in an index scan search qualification, and it is disregarded for purposes of any uniqueness or exclusion constraint enforced by the index\&. However, an index\-only scan can return the contents of non\-key columns without having to visit the index\*(Aqs table, since they are available directly from the index entry\&. Thus, addition of non\-key columns allows index\-only scans to be used for queries that otherwise could not use them\&.
+.sp
+It\*(Aqs wise to be conservative about adding non\-key columns to an index, especially wide columns\&. If an index tuple exceeds the maximum size allowed for the index type, data insertion will fail\&. In any case, non\-key columns duplicate data from the index\*(Aqs table and bloat the size of the index, thus potentially slowing searches\&. Furthermore, B\-tree deduplication is never used with indexes that have a non\-key column\&.
+.sp
+Columns listed in the
+INCLUDE
+clause don\*(Aqt need appropriate operator classes; the clause can include columns whose data types don\*(Aqt have operator classes defined for a given access method\&.
+.sp
+Expressions are not supported as included columns since they cannot be used in index\-only scans\&.
+.sp
+Currently, the B\-tree, GiST and SP\-GiST index access methods support this feature\&. In these indexes, the values of columns listed in the
+INCLUDE
+clause are included in leaf tuples which correspond to heap tuples, but are not included in upper\-level index entries used for tree navigation\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the index to be created\&. No schema name can be included here; the index is always created in the same schema as its parent table\&. The name of the index must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in that schema\&. If the name is omitted,
+PostgreSQL
+chooses a suitable name based on the parent table\*(Aqs name and the indexed column name(s)\&.
+.RE
+.PP
+ONLY
+.RS 4
+Indicates not to recurse creating indexes on partitions, if the table is partitioned\&. The default is to recurse\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (possibly schema\-qualified) of the table to be indexed\&.
+.RE
+.PP
+\fImethod\fR
+.RS 4
+The name of the index method to be used\&. Choices are
+btree,
+hash,
+gist,
+spgist,
+gin,
+brin, or user\-installed access methods like
+bloom\&. The default method is
+btree\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column of the table\&.
+.RE
+.PP
+\fIexpression\fR
+.RS 4
+An expression based on one or more columns of the table\&. The expression usually must be written with surrounding parentheses, as shown in the syntax\&. However, the parentheses can be omitted if the expression has the form of a function call\&.
+.RE
+.PP
+\fIcollation\fR
+.RS 4
+The name of the collation to use for the index\&. By default, the index uses the collation declared for the column to be indexed or the result collation of the expression to be indexed\&. Indexes with non\-default collations can be useful for queries that involve expressions using non\-default collations\&.
+.RE
+.PP
+\fIopclass\fR
+.RS 4
+The name of an operator class\&. See below for details\&.
+.RE
+.PP
+\fIopclass_parameter\fR
+.RS 4
+The name of an operator class parameter\&. See below for details\&.
+.RE
+.PP
+ASC
+.RS 4
+Specifies ascending sort order (which is the default)\&.
+.RE
+.PP
+DESC
+.RS 4
+Specifies descending sort order\&.
+.RE
+.PP
+NULLS FIRST
+.RS 4
+Specifies that nulls sort before non\-nulls\&. This is the default when
+DESC
+is specified\&.
+.RE
+.PP
+NULLS LAST
+.RS 4
+Specifies that nulls sort after non\-nulls\&. This is the default when
+DESC
+is not specified\&.
+.RE
+.PP
+NULLS DISTINCT
+.br
+NULLS NOT DISTINCT
+.RS 4
+Specifies whether for a unique index, null values should be considered distinct (not equal)\&. The default is that they are distinct, so that a unique index could contain multiple null values in a column\&.
+.RE
+.PP
+\fIstorage_parameter\fR
+.RS 4
+The name of an index\-method\-specific storage parameter\&. See
+Index Storage Parameters
+below for details\&.
+.RE
+.PP
+\fItablespace_name\fR
+.RS 4
+The tablespace in which to create the index\&. If not specified,
+default_tablespace
+is consulted, or
+temp_tablespaces
+for indexes on temporary tables\&.
+.RE
+.PP
+\fIpredicate\fR
+.RS 4
+The constraint expression for a partial index\&.
+.RE
+.SS "Index Storage Parameters"
+.PP
+The optional
+WITH
+clause specifies
+storage parameters
+for the index\&. Each index method has its own set of allowed storage parameters\&. The B\-tree, hash, GiST and SP\-GiST index methods all accept this parameter:
+.PP
+fillfactor (integer)
+.RS 4
+The fillfactor for an index is a percentage that determines how full the index method will try to pack index pages\&. For B\-trees, leaf pages are filled to this percentage during initial index builds, and also when extending the index at the right (adding new largest key values)\&. If pages subsequently become completely full, they will be split, leading to fragmentation of the on\-disk index structure\&. B\-trees use a default fillfactor of 90, but any integer value from 10 to 100 can be selected\&.
+.sp
+B\-tree indexes on tables where many inserts and/or updates are anticipated can benefit from lower fillfactor settings at
+\fBCREATE INDEX\fR
+time (following bulk loading into the table)\&. Values in the range of 50 \- 90 can usefully
+\(lqsmooth out\(rq
+the
+\fIrate\fR
+of page splits during the early life of the B\-tree index (lowering fillfactor like this may even lower the absolute number of page splits, though this effect is highly workload dependent)\&. The B\-tree bottom\-up index deletion technique described in
+Section\ \&67.4.2
+is dependent on having some
+\(lqextra\(rq
+space on pages to store
+\(lqextra\(rq
+tuple versions, and so can be affected by fillfactor (though the effect is usually not significant)\&.
+.sp
+In other specific cases it might be useful to increase fillfactor to 100 at
+\fBCREATE INDEX\fR
+time as a way of maximizing space utilization\&. You should only consider this when you are completely sure that the table is static (i\&.e\&. that it will never be affected by either inserts or updates)\&. A fillfactor setting of 100 otherwise risks
+\fIharming\fR
+performance: even a few updates or inserts will cause a sudden flood of page splits\&.
+.sp
+The other index methods use fillfactor in different but roughly analogous ways; the default fillfactor varies between methods\&.
+.RE
+.PP
+B\-tree indexes additionally accept this parameter:
+.PP
+deduplicate_items (boolean)
+.RS 4
+Controls usage of the B\-tree deduplication technique described in
+Section\ \&67.4.3\&. Set to
+ON
+or
+OFF
+to enable or disable the optimization\&. (Alternative spellings of
+ON
+and
+OFF
+are allowed as described in
+Section\ \&20.1\&.) The default is
+ON\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+Turning
+deduplicate_items
+off via
+\fBALTER INDEX\fR
+prevents future insertions from triggering deduplication, but does not in itself make existing posting list tuples use the standard tuple representation\&.
+.sp .5v
+.RE
+.RE
+.PP
+GiST indexes additionally accept this parameter:
+.PP
+buffering (enum)
+.RS 4
+Determines whether the buffered build technique described in
+Section\ \&68.4.1
+is used to build the index\&. With
+OFF
+buffering is disabled, with
+ON
+it is enabled, and with
+AUTO
+it is initially disabled, but is turned on on\-the\-fly once the index size reaches
+effective_cache_size\&. The default is
+AUTO\&. Note that if sorted build is possible, it will be used instead of buffered build unless
+buffering=ON
+is specified\&.
+.RE
+.PP
+GIN indexes accept different parameters:
+.PP
+fastupdate (boolean)
+.RS 4
+This setting controls usage of the fast update technique described in
+Section\ \&70.4.1\&. It is a Boolean parameter:
+ON
+enables fast update,
+OFF
+disables it\&. The default is
+ON\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+Turning
+fastupdate
+off via
+\fBALTER INDEX\fR
+prevents future insertions from going into the list of pending index entries, but does not in itself flush previous entries\&. You might want to
+\fBVACUUM\fR
+the table or call
+\fBgin_clean_pending_list\fR
+function afterward to ensure the pending list is emptied\&.
+.sp .5v
+.RE
+.RE
+.PP
+gin_pending_list_limit (integer)
+.RS 4
+Custom
+gin_pending_list_limit
+parameter\&. This value is specified in kilobytes\&.
+.RE
+.PP
+BRIN
+indexes accept different parameters:
+.PP
+pages_per_range (integer)
+.RS 4
+Defines the number of table blocks that make up one block range for each entry of a
+BRIN
+index (see
+Section\ \&71.1
+for more details)\&. The default is
+128\&.
+.RE
+.PP
+autosummarize (boolean)
+.RS 4
+Defines whether a summarization run is queued for the previous page range whenever an insertion is detected on the next one\&. See
+Section\ \&71.1.1
+for more details\&. The default is
+off\&.
+.RE
+.SS "Building Indexes Concurrently"
+.PP
+Creating an index can interfere with regular operation of a database\&. Normally
+PostgreSQL
+locks the table to be indexed against writes and performs the entire index build with a single scan of the table\&. Other transactions can still read the table, but if they try to insert, update, or delete rows in the table they will block until the index build is finished\&. This could have a severe effect if the system is a live production database\&. Very large tables can take many hours to be indexed, and even for smaller tables, an index build can lock out writers for periods that are unacceptably long for a production system\&.
+.PP
+PostgreSQL
+supports building indexes without locking out writes\&. This method is invoked by specifying the
+CONCURRENTLY
+option of
+\fBCREATE INDEX\fR\&. When this option is used,
+PostgreSQL
+must perform two scans of the table, and in addition it must wait for all existing transactions that could potentially modify or use the index to terminate\&. Thus this method requires more total work than a standard index build and takes significantly longer to complete\&. However, since it allows normal operations to continue while the index is built, this method is useful for adding new indexes in a production environment\&. Of course, the extra CPU and I/O load imposed by the index creation might slow other operations\&.
+.PP
+In a concurrent index build, the index is actually entered as an
+\(lqinvalid\(rq
+index into the system catalogs in one transaction, then two table scans occur in two more transactions\&. Before each table scan, the index build must wait for existing transactions that have modified the table to terminate\&. After the second scan, the index build must wait for any transactions that have a snapshot (see
+Chapter\ \&13) predating the second scan to terminate, including transactions used by any phase of concurrent index builds on other tables, if the indexes involved are partial or have columns that are not simple column references\&. Then finally the index can be marked
+\(lqvalid\(rq
+and ready for use, and the
+\fBCREATE INDEX\fR
+command terminates\&. Even then, however, the index may not be immediately usable for queries: in the worst case, it cannot be used as long as transactions exist that predate the start of the index build\&.
+.PP
+If a problem arises while scanning the table, such as a deadlock or a uniqueness violation in a unique index, the
+\fBCREATE INDEX\fR
+command will fail but leave behind an
+\(lqinvalid\(rq
+index\&. This index will be ignored for querying purposes because it might be incomplete; however it will still consume update overhead\&. The
+psql
+\fB\ed\fR
+command will report such an index as
+INVALID:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+postgres=# \ed tab
+ Table "public\&.tab"
+ Column | Type | Collation | Nullable | Default
+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-
+ col | integer | | |
+Indexes:
+ "idx" btree (col) INVALID
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The recommended recovery method in such cases is to drop the index and try again to perform
+\fBCREATE INDEX CONCURRENTLY\fR\&. (Another possibility is to rebuild the index with
+\fBREINDEX INDEX CONCURRENTLY\fR)\&.
+.PP
+Another caveat when building a unique index concurrently is that the uniqueness constraint is already being enforced against other transactions when the second table scan begins\&. This means that constraint violations could be reported in other queries prior to the index becoming available for use, or even in cases where the index build eventually fails\&. Also, if a failure does occur in the second scan, the
+\(lqinvalid\(rq
+index continues to enforce its uniqueness constraint afterwards\&.
+.PP
+Concurrent builds of expression indexes and partial indexes are supported\&. Errors occurring in the evaluation of these expressions could cause behavior similar to that described above for unique constraint violations\&.
+.PP
+Regular index builds permit other regular index builds on the same table to occur simultaneously, but only one concurrent index build can occur on a table at a time\&. In either case, schema modification of the table is not allowed while the index is being built\&. Another difference is that a regular
+\fBCREATE INDEX\fR
+command can be performed within a transaction block, but
+\fBCREATE INDEX CONCURRENTLY\fR
+cannot\&.
+.PP
+Concurrent builds for indexes on partitioned tables are currently not supported\&. However, you may concurrently build the index on each partition individually and then finally create the partitioned index non\-concurrently in order to reduce the time where writes to the partitioned table will be locked out\&. In this case, building the partitioned index is a metadata only operation\&.
+.SH "NOTES"
+.PP
+See
+Chapter\ \&11
+for information about when indexes can be used, when they are not used, and in which particular situations they can be useful\&.
+.PP
+Currently, only the B\-tree, GiST, GIN, and BRIN index methods support multiple\-key\-column indexes\&. Whether there can be multiple key columns is independent of whether
+INCLUDE
+columns can be added to the index\&. Indexes can have up to 32 columns, including
+INCLUDE
+columns\&. (This limit can be altered when building
+PostgreSQL\&.) Only B\-tree currently supports unique indexes\&.
+.PP
+An
+operator class
+with optional parameters can be specified for each column of an index\&. The operator class identifies the operators to be used by the index for that column\&. For example, a B\-tree index on four\-byte integers would use the
+int4_ops
+class; this operator class includes comparison functions for four\-byte integers\&. In practice the default operator class for the column\*(Aqs data type is usually sufficient\&. The main point of having operator classes is that for some data types, there could be more than one meaningful ordering\&. For example, we might want to sort a complex\-number data type either by absolute value or by real part\&. We could do this by defining two operator classes for the data type and then selecting the proper class when creating an index\&. More information about operator classes is in
+Section\ \&11.10
+and in
+Section\ \&38.16\&.
+.PP
+When
+CREATE INDEX
+is invoked on a partitioned table, the default behavior is to recurse to all partitions to ensure they all have matching indexes\&. Each partition is first checked to determine whether an equivalent index already exists, and if so, that index will become attached as a partition index to the index being created, which will become its parent index\&. If no matching index exists, a new index will be created and automatically attached; the name of the new index in each partition will be determined as if no index name had been specified in the command\&. If the
+ONLY
+option is specified, no recursion is done, and the index is marked invalid\&. (\fBALTER INDEX \&.\&.\&. ATTACH PARTITION\fR
+marks the index valid, once all partitions acquire matching indexes\&.) Note, however, that any partition that is created in the future using
+\fBCREATE TABLE \&.\&.\&. PARTITION OF\fR
+will automatically have a matching index, regardless of whether
+ONLY
+is specified\&.
+.PP
+For index methods that support ordered scans (currently, only B\-tree), the optional clauses
+ASC,
+DESC,
+NULLS FIRST, and/or
+NULLS LAST
+can be specified to modify the sort ordering of the index\&. Since an ordered index can be scanned either forward or backward, it is not normally useful to create a single\-column
+DESC
+index \(em that sort ordering is already available with a regular index\&. The value of these options is that multicolumn indexes can be created that match the sort ordering requested by a mixed\-ordering query, such as
+SELECT \&.\&.\&. ORDER BY x ASC, y DESC\&. The
+NULLS
+options are useful if you need to support
+\(lqnulls sort low\(rq
+behavior, rather than the default
+\(lqnulls sort high\(rq, in queries that depend on indexes to avoid sorting steps\&.
+.PP
+The system regularly collects statistics on all of a table\*(Aqs columns\&. Newly\-created non\-expression indexes can immediately use these statistics to determine an index\*(Aqs usefulness\&. For new expression indexes, it is necessary to run
+\fBANALYZE\fR
+or wait for the
+autovacuum daemon
+to analyze the table to generate statistics for these indexes\&.
+.PP
+For most index methods, the speed of creating an index is dependent on the setting of
+maintenance_work_mem\&. Larger values will reduce the time needed for index creation, so long as you don\*(Aqt make it larger than the amount of memory really available, which would drive the machine into swapping\&.
+.PP
+PostgreSQL
+can build indexes while leveraging multiple CPUs in order to process the table rows faster\&. This feature is known as
+parallel index build\&. For index methods that support building indexes in parallel (currently, only B\-tree),
+\fImaintenance_work_mem\fR
+specifies the maximum amount of memory that can be used by each index build operation as a whole, regardless of how many worker processes were started\&. Generally, a cost model automatically determines how many worker processes should be requested, if any\&.
+.PP
+Parallel index builds may benefit from increasing
+\fImaintenance_work_mem\fR
+where an equivalent serial index build will see little or no benefit\&. Note that
+\fImaintenance_work_mem\fR
+may influence the number of worker processes requested, since parallel workers must have at least a
+32MB
+share of the total
+\fImaintenance_work_mem\fR
+budget\&. There must also be a remaining
+32MB
+share for the leader process\&. Increasing
+max_parallel_maintenance_workers
+may allow more workers to be used, which will reduce the time needed for index creation, so long as the index build is not already I/O bound\&. Of course, there should also be sufficient CPU capacity that would otherwise lie idle\&.
+.PP
+Setting a value for
+parallel_workers
+via
+\fBALTER TABLE\fR
+directly controls how many parallel worker processes will be requested by a
+\fBCREATE INDEX\fR
+against the table\&. This bypasses the cost model completely, and prevents
+\fImaintenance_work_mem\fR
+from affecting how many parallel workers are requested\&. Setting
+parallel_workers
+to 0 via
+\fBALTER TABLE\fR
+will disable parallel index builds on the table in all cases\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+.PP
+You might want to reset
+parallel_workers
+after setting it as part of tuning an index build\&. This avoids inadvertent changes to query plans, since
+parallel_workers
+affects
+\fIall\fR
+parallel table scans\&.
+.sp .5v
+.RE
+.PP
+While
+\fBCREATE INDEX\fR
+with the
+CONCURRENTLY
+option supports parallel builds without special restrictions, only the first table scan is actually performed in parallel\&.
+.PP
+Use
+\fBDROP INDEX\fR
+to remove an index\&.
+.PP
+Like any long\-running transaction,
+\fBCREATE INDEX\fR
+on a table can affect which tuples can be removed by concurrent
+\fBVACUUM\fR
+on any other table\&.
+.PP
+Prior releases of
+PostgreSQL
+also had an R\-tree index method\&. This method has been removed because it had no significant advantages over the GiST method\&. If
+USING rtree
+is specified,
+\fBCREATE INDEX\fR
+will interpret it as
+USING gist, to simplify conversion of old databases to GiST\&.
+.PP
+Each backend running
+\fBCREATE INDEX\fR
+will report its progress in the
+pg_stat_progress_create_index
+view\&. See
+Section\ \&28.4.2
+for details\&.
+.SH "EXAMPLES"
+.PP
+To create a unique B\-tree index on the column
+title
+in the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE UNIQUE INDEX title_idx ON films (title);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a unique B\-tree index on the column
+title
+with included columns
+director
+and
+rating
+in the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a B\-Tree index with deduplication disabled:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create an index on the expression
+lower(title), allowing efficient case\-insensitive searches:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX ON films ((lower(title)));
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(In this example we have chosen to omit the index name, so the system will choose a name, typically
+films_lower_idx\&.)
+.PP
+To create an index with non\-default collation:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX title_idx_german ON films (title COLLATE "de_DE");
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create an index with non\-default sort ordering of nulls:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create an index with non\-default fill factor:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a
+GIN
+index with fast updates disabled:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create an index on the column
+code
+in the table
+films
+and have the index reside in the tablespace
+indexspace:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX code_idx ON films (code) TABLESPACE indexspace;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a GiST index on a point attribute so that we can efficiently use box operators on the result of the conversion function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX pointloc
+ ON points USING gist (box(location,location));
+SELECT * FROM points
+ WHERE box(location,location) && \*(Aq(0,0),(1,1)\*(Aq::box;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create an index without locking out writes to the table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE INDEX\fR
+is a
+PostgreSQL
+language extension\&. There are no provisions for indexes in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER INDEX (\fBALTER_INDEX\fR(7)), DROP INDEX (\fBDROP_INDEX\fR(7)), \fBREINDEX\fR(7), Section\ \&28.4.2
diff --git a/doc/src/sgml/man7/CREATE_LANGUAGE.7 b/doc/src/sgml/man7/CREATE_LANGUAGE.7
new file mode 100644
index 0000000..9e2119a
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_LANGUAGE.7
@@ -0,0 +1,178 @@
+'\" t
+.\" Title: CREATE LANGUAGE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE LANGUAGE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_LANGUAGE \- define a new procedural language
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE \fIname\fR
+ HANDLER \fIcall_handler\fR [ INLINE \fIinline_handler\fR ] [ VALIDATOR \fIvalfunction\fR ]
+CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE \fIname\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE LANGUAGE\fR
+registers a new procedural language with a
+PostgreSQL
+database\&. Subsequently, functions and procedures can be defined in this new language\&.
+.PP
+\fBCREATE LANGUAGE\fR
+effectively associates the language name with handler function(s) that are responsible for executing functions written in the language\&. Refer to
+Chapter\ \&58
+for more information about language handlers\&.
+.PP
+\fBCREATE OR REPLACE LANGUAGE\fR
+will either create a new language, or replace an existing definition\&. If the language already exists, its parameters are updated according to the command, but the language\*(Aqs ownership and permissions settings do not change, and any existing functions written in the language are assumed to still be valid\&.
+.PP
+One must have the
+PostgreSQL
+superuser privilege to register a new language or change an existing language\*(Aqs parameters\&. However, once the language is created it is valid to assign ownership of it to a non\-superuser, who may then drop it, change its permissions, rename it, or assign it to a new owner\&. (Do not, however, assign ownership of the underlying C functions to a non\-superuser; that would create a privilege escalation path for that user\&.)
+.PP
+The form of
+\fBCREATE LANGUAGE\fR
+that does not supply any handler function is obsolete\&. For backwards compatibility with old dump files, it is interpreted as
+\fBCREATE EXTENSION\fR\&. That will work if the language has been packaged into an extension of the same name, which is the conventional way to set up procedural languages\&.
+.SH "PARAMETERS"
+.PP
+TRUSTED
+.RS 4
+TRUSTED
+specifies that the language does not grant access to data that the user would not otherwise have\&. If this key word is omitted when registering the language, only users with the
+PostgreSQL
+superuser privilege can use this language to create new functions\&.
+.RE
+.PP
+PROCEDURAL
+.RS 4
+This is a noise word\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the new procedural language\&. The name must be unique among the languages in the database\&.
+.RE
+.PP
+HANDLER \fIcall_handler\fR
+.RS 4
+\fIcall_handler\fR
+is the name of a previously registered function that will be called to execute the procedural language\*(Aqs functions\&. The call handler for a procedural language must be written in a compiled language such as C with version 1 call convention and registered with
+PostgreSQL
+as a function taking no arguments and returning the
+language_handler
+type, a placeholder type that is simply used to identify the function as a call handler\&.
+.RE
+.PP
+INLINE \fIinline_handler\fR
+.RS 4
+\fIinline_handler\fR
+is the name of a previously registered function that will be called to execute an anonymous code block (\fBDO\fR
+command) in this language\&. If no
+\fIinline_handler\fR
+function is specified, the language does not support anonymous code blocks\&. The handler function must take one argument of type
+internal, which will be the
+\fBDO\fR
+command\*(Aqs internal representation, and it will typically return
+void\&. The return value of the handler is ignored\&.
+.RE
+.PP
+VALIDATOR \fIvalfunction\fR
+.RS 4
+\fIvalfunction\fR
+is the name of a previously registered function that will be called when a new function in the language is created, to validate the new function\&. If no validator function is specified, then a new function will not be checked when it is created\&. The validator function must take one argument of type
+oid, which will be the OID of the to\-be\-created function, and will typically return
+void\&.
+.sp
+A validator function would typically inspect the function body for syntactical correctness, but it can also look at other properties of the function, for example if the language cannot handle certain argument types\&. To signal an error, the validator function should use the
+\fBereport()\fR
+function\&. The return value of the function is ignored\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBDROP LANGUAGE\fR
+to drop procedural languages\&.
+.PP
+The system catalog
+pg_language
+(see
+Section\ \&53.29) records information about the currently installed languages\&. Also, the
+psql
+command
+\fB\edL\fR
+lists the installed languages\&.
+.PP
+To create functions in a procedural language, a user must have the
+USAGE
+privilege for the language\&. By default,
+USAGE
+is granted to
+PUBLIC
+(i\&.e\&., everyone) for trusted languages\&. This can be revoked if desired\&.
+.PP
+Procedural languages are local to individual databases\&. However, a language can be installed into the
+template1
+database, which will cause it to be available automatically in all subsequently\-created databases\&.
+.SH "EXAMPLES"
+.PP
+A minimal sequence for creating a new procedural language is:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION plsample_call_handler() RETURNS language_handler
+ AS \*(Aq$libdir/plsample\*(Aq
+ LANGUAGE C;
+CREATE LANGUAGE plsample
+ HANDLER plsample_call_handler;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Typically that would be written in an extension\*(Aqs creation script, and users would do this to install the extension:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE EXTENSION plsample;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE LANGUAGE\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER LANGUAGE (\fBALTER_LANGUAGE\fR(7)), CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)), DROP LANGUAGE (\fBDROP_LANGUAGE\fR(7)), \fBGRANT\fR(7), \fBREVOKE\fR(7)
diff --git a/doc/src/sgml/man7/CREATE_MATERIALIZED_VIEW.7 b/doc/src/sgml/man7/CREATE_MATERIALIZED_VIEW.7
new file mode 100644
index 0000000..50c3910
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_MATERIALIZED_VIEW.7
@@ -0,0 +1,131 @@
+'\" t
+.\" Title: CREATE MATERIALIZED VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE MATERIALIZED VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_MATERIALIZED_VIEW \- define a new materialized view
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] \fItable_name\fR
+ [ (\fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ [ USING \fImethod\fR ]
+ [ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+ [ TABLESPACE \fItablespace_name\fR ]
+ AS \fIquery\fR
+ [ WITH [ NO ] DATA ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE MATERIALIZED VIEW\fR
+defines a materialized view of a query\&. The query is executed and used to populate the view at the time the command is issued (unless
+\fBWITH NO DATA\fR
+is used) and may be refreshed later using
+\fBREFRESH MATERIALIZED VIEW\fR\&.
+.PP
+\fBCREATE MATERIALIZED VIEW\fR
+is similar to
+\fBCREATE TABLE AS\fR, except that it also remembers the query used to initialize the view, so that it can be refreshed later upon demand\&. A materialized view has many of the same properties as a table, but there is no support for temporary materialized views\&.
+.PP
+\fBCREATE MATERIALIZED VIEW\fR
+requires
+CREATE
+privilege on the schema used for the materialized view\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a materialized view with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing materialized view is anything like the one that would have been created\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the materialized view to be created\&. The name must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in the same schema\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column in the new materialized view\&. If column names are not provided, they are taken from the output column names of the query\&.
+.RE
+.PP
+USING \fImethod\fR
+.RS 4
+This optional clause specifies the table access method to use to store the contents for the new materialized view; the method needs be an access method of type
+TABLE\&. See
+Chapter\ \&63
+for more information\&. If this option is not specified, the default table access method is chosen for the new materialized view\&. See
+default_table_access_method
+for more information\&.
+.RE
+.PP
+WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause specifies optional storage parameters for the new materialized view; see
+Storage Parameters
+in the
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+documentation for more information\&. All parameters supported for
+CREATE TABLE
+are also supported for
+CREATE MATERIALIZED VIEW\&. See
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for more information\&.
+.RE
+.PP
+TABLESPACE \fItablespace_name\fR
+.RS 4
+The
+\fItablespace_name\fR
+is the name of the tablespace in which the new materialized view is to be created\&. If not specified,
+default_tablespace
+is consulted\&.
+.RE
+.PP
+\fIquery\fR
+.RS 4
+A
+\fBSELECT\fR,
+\fBTABLE\fR, or
+\fBVALUES\fR
+command\&. This query will run within a security\-restricted operation; in particular, calls to functions that themselves create temporary tables will fail\&.
+.RE
+.PP
+WITH [ NO ] DATA
+.RS 4
+This clause specifies whether or not the materialized view should be populated at creation time\&. If not, the materialized view will be flagged as unscannable and cannot be queried until
+\fBREFRESH MATERIALIZED VIEW\fR
+is used\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE MATERIALIZED VIEW\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER MATERIALIZED VIEW (\fBALTER_MATERIALIZED_VIEW\fR(7)), CREATE TABLE AS (\fBCREATE_TABLE_AS\fR(7)), CREATE VIEW (\fBCREATE_VIEW\fR(7)), DROP MATERIALIZED VIEW (\fBDROP_MATERIALIZED_VIEW\fR(7)), REFRESH MATERIALIZED VIEW (\fBREFRESH_MATERIALIZED_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_OPERATOR.7 b/doc/src/sgml/man7/CREATE_OPERATOR.7
new file mode 100644
index 0000000..afc9d75
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_OPERATOR.7
@@ -0,0 +1,282 @@
+'\" t
+.\" Title: CREATE OPERATOR
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE OPERATOR" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_OPERATOR \- define a new operator
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE OPERATOR \fIname\fR (
+ {FUNCTION|PROCEDURE} = \fIfunction_name\fR
+ [, LEFTARG = \fIleft_type\fR ] [, RIGHTARG = \fIright_type\fR ]
+ [, COMMUTATOR = \fIcom_op\fR ] [, NEGATOR = \fIneg_op\fR ]
+ [, RESTRICT = \fIres_proc\fR ] [, JOIN = \fIjoin_proc\fR ]
+ [, HASHES ] [, MERGES ]
+)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE OPERATOR\fR
+defines a new operator,
+\fIname\fR\&. The user who defines an operator becomes its owner\&. If a schema name is given then the operator is created in the specified schema\&. Otherwise it is created in the current schema\&.
+.PP
+The operator name is a sequence of up to
+NAMEDATALEN\-1 (63 by default) characters from the following list:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
++ \- * / < > = ~ ! @ # % ^ & | ` ?
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+There are a few restrictions on your choice of name:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\-\-
+and
+/*
+cannot appear anywhere in an operator name, since they will be taken as the start of a comment\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A multicharacter operator name cannot end in
++
+or
+\-, unless the name also contains at least one of these characters:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+~ ! @ # % ^ & | ` ?
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+For example,
+@\-
+is an allowed operator name, but
+*\-
+is not\&. This restriction allows
+PostgreSQL
+to parse SQL\-compliant commands without requiring spaces between tokens\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The use of
+=>
+as an operator name is deprecated\&. It may be disallowed altogether in a future release\&.
+.RE
+.PP
+The operator
+!=
+is mapped to
+<>
+on input, so these two names are always equivalent\&.
+.PP
+For binary operators, both
+LEFTARG
+and
+RIGHTARG
+must be defined\&. For prefix operators only
+RIGHTARG
+should be defined\&. The
+\fIfunction_name\fR
+function must have been previously defined using
+\fBCREATE FUNCTION\fR
+and must be defined to accept the correct number of arguments (either one or two) of the indicated types\&.
+.PP
+In the syntax of
+CREATE OPERATOR, the keywords
+FUNCTION
+and
+PROCEDURE
+are equivalent, but the referenced function must in any case be a function, not a procedure\&. The use of the keyword
+PROCEDURE
+here is historical and deprecated\&.
+.PP
+The other clauses specify optional operator optimization clauses\&. Their meaning is detailed in
+Section\ \&38.15\&.
+.PP
+To be able to create an operator, you must have
+USAGE
+privilege on the argument types and the return type, as well as
+EXECUTE
+privilege on the underlying function\&. If a commutator or negator operator is specified, you must own these operators\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the operator to be defined\&. See above for allowable characters\&. The name can be schema\-qualified, for example
+CREATE OPERATOR myschema\&.+ (\&.\&.\&.)\&. If not, then the operator is created in the current schema\&. Two operators in the same schema can have the same name if they operate on different data types\&. This is called
+overloading\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+The function used to implement this operator\&.
+.RE
+.PP
+\fIleft_type\fR
+.RS 4
+The data type of the operator\*(Aqs left operand, if any\&. This option would be omitted for a prefix operator\&.
+.RE
+.PP
+\fIright_type\fR
+.RS 4
+The data type of the operator\*(Aqs right operand\&.
+.RE
+.PP
+\fIcom_op\fR
+.RS 4
+The commutator of this operator\&.
+.RE
+.PP
+\fIneg_op\fR
+.RS 4
+The negator of this operator\&.
+.RE
+.PP
+\fIres_proc\fR
+.RS 4
+The restriction selectivity estimator function for this operator\&.
+.RE
+.PP
+\fIjoin_proc\fR
+.RS 4
+The join selectivity estimator function for this operator\&.
+.RE
+.PP
+HASHES
+.RS 4
+Indicates this operator can support a hash join\&.
+.RE
+.PP
+MERGES
+.RS 4
+Indicates this operator can support a merge join\&.
+.RE
+.PP
+To give a schema\-qualified operator name in
+\fIcom_op\fR
+or the other optional arguments, use the
+OPERATOR()
+syntax, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+COMMUTATOR = OPERATOR(myschema\&.===) ,
+.fi
+.if n \{\
+.RE
+.\}
+.SH "NOTES"
+.PP
+Refer to
+Section\ \&38.14
+for further information\&.
+.PP
+It is not possible to specify an operator\*(Aqs lexical precedence in
+\fBCREATE OPERATOR\fR, because the parser\*(Aqs precedence behavior is hard\-wired\&. See
+Section\ \&4.1.6
+for precedence details\&.
+.PP
+The obsolete options
+SORT1,
+SORT2,
+LTCMP, and
+GTCMP
+were formerly used to specify the names of sort operators associated with a merge\-joinable operator\&. This is no longer necessary, since information about associated operators is found by looking at B\-tree operator families instead\&. If one of these options is given, it is ignored except for implicitly setting
+MERGES
+true\&.
+.PP
+Use
+\fBDROP OPERATOR\fR
+to delete user\-defined operators from a database\&. Use
+\fBALTER OPERATOR\fR
+to modify operators in a database\&.
+.SH "EXAMPLES"
+.PP
+The following command defines a new operator, area\-equality, for the data type
+box:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE OPERATOR === (
+ LEFTARG = box,
+ RIGHTARG = box,
+ FUNCTION = area_equal_function,
+ COMMUTATOR = ===,
+ NEGATOR = !==,
+ RESTRICT = area_restriction_function,
+ JOIN = area_join_function,
+ HASHES, MERGES
+);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE OPERATOR\fR
+is a
+PostgreSQL
+extension\&. There are no provisions for user\-defined operators in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER OPERATOR (\fBALTER_OPERATOR\fR(7)), CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), DROP OPERATOR (\fBDROP_OPERATOR\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_OPERATOR_CLASS.7 b/doc/src/sgml/man7/CREATE_OPERATOR_CLASS.7
new file mode 100644
index 0000000..37f382a
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_OPERATOR_CLASS.7
@@ -0,0 +1,223 @@
+'\" t
+.\" Title: CREATE OPERATOR CLASS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE OPERATOR CLASS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_OPERATOR_CLASS \- define a new operator class
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE OPERATOR CLASS \fIname\fR [ DEFAULT ] FOR TYPE \fIdata_type\fR
+ USING \fIindex_method\fR [ FAMILY \fIfamily_name\fR ] AS
+ { OPERATOR \fIstrategy_number\fR \fIoperator_name\fR [ ( \fIop_type\fR, \fIop_type\fR ) ] [ FOR SEARCH | FOR ORDER BY \fIsort_family_name\fR ]
+ | FUNCTION \fIsupport_number\fR [ ( \fIop_type\fR [ , \fIop_type\fR ] ) ] \fIfunction_name\fR ( \fIargument_type\fR [, \&.\&.\&.] )
+ | STORAGE \fIstorage_type\fR
+ } [, \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE OPERATOR CLASS\fR
+creates a new operator class\&. An operator class defines how a particular data type can be used with an index\&. The operator class specifies that certain operators will fill particular roles or
+\(lqstrategies\(rq
+for this data type and this index method\&. The operator class also specifies the support functions to be used by the index method when the operator class is selected for an index column\&. All the operators and functions used by an operator class must be defined before the operator class can be created\&.
+.PP
+If a schema name is given then the operator class is created in the specified schema\&. Otherwise it is created in the current schema\&. Two operator classes in the same schema can have the same name only if they are for different index methods\&.
+.PP
+The user who defines an operator class becomes its owner\&. Presently, the creating user must be a superuser\&. (This restriction is made because an erroneous operator class definition could confuse or even crash the server\&.)
+.PP
+\fBCREATE OPERATOR CLASS\fR
+does not presently check whether the operator class definition includes all the operators and functions required by the index method, nor whether the operators and functions form a self\-consistent set\&. It is the user\*(Aqs responsibility to define a valid operator class\&.
+.PP
+Related operator classes can be grouped into
+operator families\&. To add a new operator class to an existing family, specify the
+FAMILY
+option in
+\fBCREATE OPERATOR CLASS\fR\&. Without this option, the new class is placed into a family named the same as the new class (creating that family if it doesn\*(Aqt already exist)\&.
+.PP
+Refer to
+Section\ \&38.16
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the operator class to be created\&. The name can be schema\-qualified\&.
+.RE
+.PP
+DEFAULT
+.RS 4
+If present, the operator class will become the default operator class for its data type\&. At most one operator class can be the default for a specific data type and index method\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The column data type that this operator class is for\&.
+.RE
+.PP
+\fIindex_method\fR
+.RS 4
+The name of the index method this operator class is for\&.
+.RE
+.PP
+\fIfamily_name\fR
+.RS 4
+The name of the existing operator family to add this operator class to\&. If not specified, a family named the same as the operator class is used (creating it, if it doesn\*(Aqt already exist)\&.
+.RE
+.PP
+\fIstrategy_number\fR
+.RS 4
+The index method\*(Aqs strategy number for an operator associated with the operator class\&.
+.RE
+.PP
+\fIoperator_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an operator associated with the operator class\&.
+.RE
+.PP
+\fIop_type\fR
+.RS 4
+In an
+OPERATOR
+clause, the operand data type(s) of the operator, or
+NONE
+to signify a prefix operator\&. The operand data types can be omitted in the normal case where they are the same as the operator class\*(Aqs data type\&.
+.sp
+In a
+FUNCTION
+clause, the operand data type(s) the function is intended to support, if different from the input data type(s) of the function (for B\-tree comparison functions and hash functions) or the class\*(Aqs data type (for B\-tree sort support functions, B\-tree equal image functions, and all functions in GiST, SP\-GiST, GIN and BRIN operator classes)\&. These defaults are correct, and so
+\fIop_type\fR
+need not be specified in
+FUNCTION
+clauses, except for the case of a B\-tree sort support function that is meant to support cross\-data\-type comparisons\&.
+.RE
+.PP
+\fIsort_family_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing
+btree
+operator family that describes the sort ordering associated with an ordering operator\&.
+.sp
+If neither
+FOR SEARCH
+nor
+FOR ORDER BY
+is specified,
+FOR SEARCH
+is the default\&.
+.RE
+.PP
+\fIsupport_number\fR
+.RS 4
+The index method\*(Aqs support function number for a function associated with the operator class\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+The name (optionally schema\-qualified) of a function that is an index method support function for the operator class\&.
+.RE
+.PP
+\fIargument_type\fR
+.RS 4
+The parameter data type(s) of the function\&.
+.RE
+.PP
+\fIstorage_type\fR
+.RS 4
+The data type actually stored in the index\&. Normally this is the same as the column data type, but some index methods (currently GiST, GIN, SP\-GiST and BRIN) allow it to be different\&. The
+STORAGE
+clause must be omitted unless the index method allows a different type to be used\&. If the column
+\fIdata_type\fR
+is specified as
+anyarray, the
+\fIstorage_type\fR
+can be declared as
+anyelement
+to indicate that the index entries are members of the element type belonging to the actual array type that each particular index is created for\&.
+.RE
+.PP
+The
+OPERATOR,
+FUNCTION, and
+STORAGE
+clauses can appear in any order\&.
+.SH "NOTES"
+.PP
+Because the index machinery does not check access permissions on functions before using them, including a function or operator in an operator class is tantamount to granting public execute permission on it\&. This is usually not an issue for the sorts of functions that are useful in an operator class\&.
+.PP
+The operators should not be defined by SQL functions\&. An SQL function is likely to be inlined into the calling query, which will prevent the optimizer from recognizing that the query matches an index\&.
+.PP
+Before
+PostgreSQL
+8\&.4, the
+OPERATOR
+clause could include a
+RECHECK
+option\&. This is no longer supported because whether an index operator is
+\(lqlossy\(rq
+is now determined on\-the\-fly at run time\&. This allows efficient handling of cases where an operator might or might not be lossy\&.
+.SH "EXAMPLES"
+.PP
+The following example command defines a GiST index operator class for the data type
+_int4
+(array of
+int4)\&. See the
+intarray
+module for the complete example\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE OPERATOR CLASS gist__int_ops
+ DEFAULT FOR TYPE _int4 USING gist AS
+ OPERATOR 3 &&,
+ OPERATOR 6 = (anyarray, anyarray),
+ OPERATOR 7 @>,
+ OPERATOR 8 <@,
+ OPERATOR 20 @@ (_int4, query_int),
+ FUNCTION 1 g_int_consistent (internal, _int4, smallint, oid, internal),
+ FUNCTION 2 g_int_union (internal, internal),
+ FUNCTION 3 g_int_compress (internal),
+ FUNCTION 4 g_int_decompress (internal),
+ FUNCTION 5 g_int_penalty (internal, internal, internal),
+ FUNCTION 6 g_int_picksplit (internal, internal),
+ FUNCTION 7 g_int_same (_int4, _int4, internal);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE OPERATOR CLASS\fR
+is a
+PostgreSQL
+extension\&. There is no
+\fBCREATE OPERATOR CLASS\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER OPERATOR CLASS (\fBALTER_OPERATOR_CLASS\fR(7)), DROP OPERATOR CLASS (\fBDROP_OPERATOR_CLASS\fR(7)), CREATE OPERATOR FAMILY (\fBCREATE_OPERATOR_FAMILY\fR(7)), ALTER OPERATOR FAMILY (\fBALTER_OPERATOR_FAMILY\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_OPERATOR_FAMILY.7 b/doc/src/sgml/man7/CREATE_OPERATOR_FAMILY.7
new file mode 100644
index 0000000..2d32c15
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_OPERATOR_FAMILY.7
@@ -0,0 +1,79 @@
+'\" t
+.\" Title: CREATE OPERATOR FAMILY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE OPERATOR FAMILY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_OPERATOR_FAMILY \- define a new operator family
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE OPERATOR FAMILY \fIname\fR USING \fIindex_method\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE OPERATOR FAMILY\fR
+creates a new operator family\&. An operator family defines a collection of related operator classes, and perhaps some additional operators and support functions that are compatible with these operator classes but not essential for the functioning of any individual index\&. (Operators and functions that are essential to indexes should be grouped within the relevant operator class, rather than being
+\(lqloose\(rq
+in the operator family\&. Typically, single\-data\-type operators are bound to operator classes, while cross\-data\-type operators can be loose in an operator family containing operator classes for both data types\&.)
+.PP
+The new operator family is initially empty\&. It should be populated by issuing subsequent
+\fBCREATE OPERATOR CLASS\fR
+commands to add contained operator classes, and optionally
+\fBALTER OPERATOR FAMILY\fR
+commands to add
+\(lqloose\(rq
+operators and their corresponding support functions\&.
+.PP
+If a schema name is given then the operator family is created in the specified schema\&. Otherwise it is created in the current schema\&. Two operator families in the same schema can have the same name only if they are for different index methods\&.
+.PP
+The user who defines an operator family becomes its owner\&. Presently, the creating user must be a superuser\&. (This restriction is made because an erroneous operator family definition could confuse or even crash the server\&.)
+.PP
+Refer to
+Section\ \&38.16
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the operator family to be created\&. The name can be schema\-qualified\&.
+.RE
+.PP
+\fIindex_method\fR
+.RS 4
+The name of the index method this operator family is for\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE OPERATOR FAMILY\fR
+is a
+PostgreSQL
+extension\&. There is no
+\fBCREATE OPERATOR FAMILY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER OPERATOR FAMILY (\fBALTER_OPERATOR_FAMILY\fR(7)), DROP OPERATOR FAMILY (\fBDROP_OPERATOR_FAMILY\fR(7)), CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), ALTER OPERATOR CLASS (\fBALTER_OPERATOR_CLASS\fR(7)), DROP OPERATOR CLASS (\fBDROP_OPERATOR_CLASS\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_POLICY.7 b/doc/src/sgml/man7/CREATE_POLICY.7
new file mode 100644
index 0000000..735db02
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_POLICY.7
@@ -0,0 +1,655 @@
+'\" t
+.\" Title: CREATE POLICY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE POLICY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_POLICY \- define a new row\-level security policy for a table
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE POLICY \fIname\fR ON \fItable_name\fR
+ [ AS { PERMISSIVE | RESTRICTIVE } ]
+ [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+ [ TO { \fIrole_name\fR | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, \&.\&.\&.] ]
+ [ USING ( \fIusing_expression\fR ) ]
+ [ WITH CHECK ( \fIcheck_expression\fR ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBCREATE POLICY\fR
+command defines a new row\-level security policy for a table\&. Note that row\-level security must be enabled on the table (using
+\fBALTER TABLE \&.\&.\&. ENABLE ROW LEVEL SECURITY\fR) in order for created policies to be applied\&.
+.PP
+A policy grants the permission to select, insert, update, or delete rows that match the relevant policy expression\&. Existing table rows are checked against the expression specified in
+USING, while new rows that would be created via
+INSERT
+or
+UPDATE
+are checked against the expression specified in
+WITH CHECK\&. When a
+USING
+expression returns true for a given row then that row is visible to the user, while if false or null is returned then the row is not visible\&. When a
+WITH CHECK
+expression returns true for a row then that row is inserted or updated, while if false or null is returned then an error occurs\&.
+.PP
+For
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBMERGE\fR
+statements,
+WITH CHECK
+expressions are enforced after
+BEFORE
+triggers are fired, and before any actual data modifications are made\&. Thus a
+BEFORE ROW
+trigger may modify the data to be inserted, affecting the result of the security policy check\&.
+WITH CHECK
+expressions are enforced before any other constraints\&.
+.PP
+Policy names are per\-table\&. Therefore, one policy name can be used for many different tables and have a definition for each table which is appropriate to that table\&.
+.PP
+Policies can be applied for specific commands or for specific roles\&. The default for newly created policies is that they apply for all commands and roles, unless otherwise specified\&. Multiple policies may apply to a single command; see below for more details\&.
+Table\ \&287
+summarizes how the different types of policy apply to specific commands\&.
+.PP
+For policies that can have both
+USING
+and
+WITH CHECK
+expressions (ALL
+and
+UPDATE), if no
+WITH CHECK
+expression is defined, then the
+USING
+expression will be used both to determine which rows are visible (normal
+USING
+case) and which new rows will be allowed to be added (WITH CHECK
+case)\&.
+.PP
+If row\-level security is enabled for a table, but no applicable policies exist, a
+\(lqdefault deny\(rq
+policy is assumed, so that no rows will be visible or updatable\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the policy to be created\&. This must be distinct from the name of any other policy for the table\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table the policy applies to\&.
+.RE
+.PP
+PERMISSIVE
+.RS 4
+Specify that the policy is to be created as a permissive policy\&. All permissive policies which are applicable to a given query will be combined together using the Boolean
+\(lqOR\(rq
+operator\&. By creating permissive policies, administrators can add to the set of records which can be accessed\&. Policies are permissive by default\&.
+.RE
+.PP
+RESTRICTIVE
+.RS 4
+Specify that the policy is to be created as a restrictive policy\&. All restrictive policies which are applicable to a given query will be combined together using the Boolean
+\(lqAND\(rq
+operator\&. By creating restrictive policies, administrators can reduce the set of records which can be accessed as all restrictive policies must be passed for each record\&.
+.sp
+Note that there needs to be at least one permissive policy to grant access to records before restrictive policies can be usefully used to reduce that access\&. If only restrictive policies exist, then no records will be accessible\&. When a mix of permissive and restrictive policies are present, a record is only accessible if at least one of the permissive policies passes, in addition to all the restrictive policies\&.
+.RE
+.PP
+\fIcommand\fR
+.RS 4
+The command to which the policy applies\&. Valid options are
+\fBALL\fR,
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR\&.
+\fBALL\fR
+is the default\&. See below for specifics regarding how these are applied\&.
+.RE
+.PP
+\fIrole_name\fR
+.RS 4
+The role(s) to which the policy is to be applied\&. The default is
+PUBLIC, which will apply the policy to all roles\&.
+.RE
+.PP
+\fIusing_expression\fR
+.RS 4
+Any
+SQL
+conditional expression (returning
+boolean)\&. The conditional expression cannot contain any aggregate or window functions\&. This expression will be added to queries that refer to the table if row\-level security is enabled\&. Rows for which the expression returns true will be visible\&. Any rows for which the expression returns false or null will not be visible to the user (in a
+\fBSELECT\fR), and will not be available for modification (in an
+\fBUPDATE\fR
+or
+\fBDELETE\fR)\&. Such rows are silently suppressed; no error is reported\&.
+.RE
+.PP
+\fIcheck_expression\fR
+.RS 4
+Any
+SQL
+conditional expression (returning
+boolean)\&. The conditional expression cannot contain any aggregate or window functions\&. This expression will be used in
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+queries against the table if row\-level security is enabled\&. Only rows for which the expression evaluates to true will be allowed\&. An error will be thrown if the expression evaluates to false or null for any of the records inserted or any of the records that result from the update\&. Note that the
+\fIcheck_expression\fR
+is evaluated against the proposed new contents of the row, not the original contents\&.
+.RE
+.SS "Per\-Command Policies"
+.PP
+ALL
+.RS 4
+Using
+ALL
+for a policy means that it will apply to all commands, regardless of the type of command\&. If an
+ALL
+policy exists and more specific policies exist, then both the
+ALL
+policy and the more specific policy (or policies) will be applied\&. Additionally,
+ALL
+policies will be applied to both the selection side of a query and the modification side, using the
+USING
+expression for both cases if only a
+USING
+expression has been defined\&.
+.sp
+As an example, if an
+UPDATE
+is issued, then the
+ALL
+policy will be applicable both to what the
+UPDATE
+will be able to select as rows to be updated (applying the
+USING
+expression), and to the resulting updated rows, to check if they are permitted to be added to the table (applying the
+WITH CHECK
+expression, if defined, and the
+USING
+expression otherwise)\&. If an
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+command attempts to add rows to the table that do not pass the
+ALL
+policy\*(Aqs
+WITH CHECK
+expression, the entire command will be aborted\&.
+.RE
+.PP
+SELECT
+.RS 4
+Using
+SELECT
+for a policy means that it will apply to
+SELECT
+queries and whenever
+SELECT
+permissions are required on the relation the policy is defined for\&. The result is that only those records from the relation that pass the
+SELECT
+policy will be returned during a
+SELECT
+query, and that queries that require
+SELECT
+permissions, such as
+UPDATE, will also only see those records that are allowed by the
+SELECT
+policy\&. A
+SELECT
+policy cannot have a
+WITH CHECK
+expression, as it only applies in cases where records are being retrieved from the relation\&.
+.RE
+.PP
+INSERT
+.RS 4
+Using
+INSERT
+for a policy means that it will apply to
+INSERT
+commands and
+MERGE
+commands that contain
+INSERT
+actions\&. Rows being inserted that do not pass this policy will result in a policy violation error, and the entire
+INSERT
+command will be aborted\&. An
+INSERT
+policy cannot have a
+USING
+expression, as it only applies in cases where records are being added to the relation\&.
+.sp
+Note that
+INSERT
+with
+ON CONFLICT DO UPDATE
+checks
+INSERT
+policies\*(Aq
+WITH CHECK
+expressions only for rows appended to the relation by the
+INSERT
+path\&.
+.RE
+.PP
+UPDATE
+.RS 4
+Using
+UPDATE
+for a policy means that it will apply to
+UPDATE,
+SELECT FOR UPDATE
+and
+SELECT FOR SHARE
+commands, as well as auxiliary
+ON CONFLICT DO UPDATE
+clauses of
+INSERT
+commands\&.
+MERGE
+commands containing
+UPDATE
+actions are affected as well\&. Since
+UPDATE
+involves pulling an existing record and replacing it with a new modified record,
+UPDATE
+policies accept both a
+USING
+expression and a
+WITH CHECK
+expression\&. The
+USING
+expression determines which records the
+UPDATE
+command will see to operate against, while the
+WITH CHECK
+expression defines which modified rows are allowed to be stored back into the relation\&.
+.sp
+Any rows whose updated values do not pass the
+WITH CHECK
+expression will cause an error, and the entire command will be aborted\&. If only a
+USING
+clause is specified, then that clause will be used for both
+USING
+and
+WITH CHECK
+cases\&.
+.sp
+Typically an
+UPDATE
+command also needs to read data from columns in the relation being updated (e\&.g\&., in a
+WHERE
+clause or a
+RETURNING
+clause, or in an expression on the right hand side of the
+SET
+clause)\&. In this case,
+SELECT
+rights are also required on the relation being updated, and the appropriate
+SELECT
+or
+ALL
+policies will be applied in addition to the
+UPDATE
+policies\&. Thus the user must have access to the row(s) being updated through a
+SELECT
+or
+ALL
+policy in addition to being granted permission to update the row(s) via an
+UPDATE
+or
+ALL
+policy\&.
+.sp
+When an
+INSERT
+command has an auxiliary
+ON CONFLICT DO UPDATE
+clause, if the
+UPDATE
+path is taken, the row to be updated is first checked against the
+USING
+expressions of any
+UPDATE
+policies, and then the new updated row is checked against the
+WITH CHECK
+expressions\&. Note, however, that unlike a standalone
+UPDATE
+command, if the existing row does not pass the
+USING
+expressions, an error will be thrown (the
+UPDATE
+path will
+\fInever\fR
+be silently avoided)\&.
+.RE
+.PP
+DELETE
+.RS 4
+Using
+DELETE
+for a policy means that it will apply to
+DELETE
+commands\&. Only rows that pass this policy will be seen by a
+DELETE
+command\&. There can be rows that are visible through a
+SELECT
+that are not available for deletion, if they do not pass the
+USING
+expression for the
+DELETE
+policy\&.
+.sp
+In most cases a
+DELETE
+command also needs to read data from columns in the relation that it is deleting from (e\&.g\&., in a
+WHERE
+clause or a
+RETURNING
+clause)\&. In this case,
+SELECT
+rights are also required on the relation, and the appropriate
+SELECT
+or
+ALL
+policies will be applied in addition to the
+DELETE
+policies\&. Thus the user must have access to the row(s) being deleted through a
+SELECT
+or
+ALL
+policy in addition to being granted permission to delete the row(s) via a
+DELETE
+or
+ALL
+policy\&.
+.sp
+A
+DELETE
+policy cannot have a
+WITH CHECK
+expression, as it only applies in cases where records are being deleted from the relation, so that there is no new row to check\&.
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.B Table\ \&287.\ \&Policies Applied by Command Type
+.TS
+allbox tab(:);
+lB lB lB lB s lB
+^ lB lB lB lB lB.
+T{
+Command
+T}:T{
+SELECT/ALL policy
+T}:T{
+INSERT/ALL policy
+T}:T{
+UPDATE/ALL policy
+T}:T{
+DELETE/ALL policy
+T}
+:T{
+USING expression
+T}:T{
+WITH CHECK expression
+T}:T{
+USING expression
+T}:T{
+WITH CHECK expression
+T}:T{
+USING expression
+T}
+.T&
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l l l l l l
+l s s s s s.
+T{
+\fBSELECT\fR
+T}:T{
+Existing row
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBSELECT FOR UPDATE/SHARE\fR
+T}:T{
+Existing row
+T}:T{
+\(em
+T}:T{
+Existing row
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBINSERT\fR / \fBMERGE \&.\&.\&. THEN INSERT\fR
+T}:T{
+\(em
+T}:T{
+New row
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBINSERT \&.\&.\&. RETURNING\fR
+T}:T{
+New row [a]
+T}:T{
+New row
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+T{
+\fBUPDATE\fR / \fBMERGE \&.\&.\&. THEN UPDATE\fR
+T}:T{
+Existing & new rows [a]
+T}:T{
+\(em
+T}:T{
+Existing row
+T}:T{
+New row
+T}:T{
+\(em
+T}
+T{
+\fBDELETE\fR
+T}:T{
+Existing row [a]
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+\(em
+T}:T{
+Existing row
+T}
+T{
+\fBON CONFLICT DO UPDATE\fR
+T}:T{
+Existing & new rows
+T}:T{
+\(em
+T}:T{
+Existing row
+T}:T{
+New row
+T}:T{
+\(em
+T}
+T{
+----
+.br
+[a]
+If read access is required to the existing or new row (for example, a
+WHERE
+or
+RETURNING
+clause that refers to columns from the relation)\&.
+T}
+.TE
+.sp 1
+.SS "Application of Multiple Policies"
+.PP
+When multiple policies of different command types apply to the same command (for example,
+SELECT
+and
+UPDATE
+policies applied to an
+UPDATE
+command), then the user must have both types of permissions (for example, permission to select rows from the relation as well as permission to update them)\&. Thus the expressions for one type of policy are combined with the expressions for the other type of policy using the
+AND
+operator\&.
+.PP
+When multiple policies of the same command type apply to the same command, then there must be at least one
+PERMISSIVE
+policy granting access to the relation, and all of the
+RESTRICTIVE
+policies must pass\&. Thus all the
+PERMISSIVE
+policy expressions are combined using
+OR, all the
+RESTRICTIVE
+policy expressions are combined using
+AND, and the results are combined using
+AND\&. If there are no
+PERMISSIVE
+policies, then access is denied\&.
+.PP
+Note that, for the purposes of combining multiple policies,
+ALL
+policies are treated as having the same type as whichever other type of policy is being applied\&.
+.PP
+For example, in an
+UPDATE
+command requiring both
+SELECT
+and
+UPDATE
+permissions, if there are multiple applicable policies of each type, they will be combined as follows:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIexpression\fR from RESTRICTIVE SELECT/ALL policy 1
+AND
+\fIexpression\fR from RESTRICTIVE SELECT/ALL policy 2
+AND
+\&.\&.\&.
+AND
+(
+ \fIexpression\fR from PERMISSIVE SELECT/ALL policy 1
+ OR
+ \fIexpression\fR from PERMISSIVE SELECT/ALL policy 2
+ OR
+ \&.\&.\&.
+)
+AND
+\fIexpression\fR from RESTRICTIVE UPDATE/ALL policy 1
+AND
+\fIexpression\fR from RESTRICTIVE UPDATE/ALL policy 2
+AND
+\&.\&.\&.
+AND
+(
+ \fIexpression\fR from PERMISSIVE UPDATE/ALL policy 1
+ OR
+ \fIexpression\fR from PERMISSIVE UPDATE/ALL policy 2
+ OR
+ \&.\&.\&.
+)
+.fi
+.if n \{\
+.RE
+.\}
+.SH "NOTES"
+.PP
+You must be the owner of a table to create or change policies for it\&.
+.PP
+While policies will be applied for explicit queries against tables in the database, they are not applied when the system is performing internal referential integrity checks or validating constraints\&. This means there are indirect ways to determine that a given value exists\&. An example of this is attempting to insert a duplicate value into a column that is a primary key or has a unique constraint\&. If the insert fails then the user can infer that the value already exists\&. (This example assumes that the user is permitted by policy to insert records which they are not allowed to see\&.) Another example is where a user is allowed to insert into a table which references another, otherwise hidden table\&. Existence can be determined by the user inserting values into the referencing table, where success would indicate that the value exists in the referenced table\&. These issues can be addressed by carefully crafting policies to prevent users from being able to insert, delete, or update records at all which might possibly indicate a value they are not otherwise able to see, or by using generated values (e\&.g\&., surrogate keys) instead of keys with external meanings\&.
+.PP
+Generally, the system will enforce filter conditions imposed using security policies prior to qualifications that appear in user queries, in order to prevent inadvertent exposure of the protected data to user\-defined functions which might not be trustworthy\&. However, functions and operators marked by the system (or the system administrator) as
+LEAKPROOF
+may be evaluated before policy expressions, as they are assumed to be trustworthy\&.
+.PP
+Since policy expressions are added to the user\*(Aqs query directly, they will be run with the rights of the user running the overall query\&. Therefore, users who are using a given policy must be able to access any tables or functions referenced in the expression or they will simply receive a permission denied error when attempting to query the table that has row\-level security enabled\&. This does not change how views work, however\&. As with normal queries and views, permission checks and policies for the tables which are referenced by a view will use the view owner\*(Aqs rights and any policies which apply to the view owner, except if the view is defined using the
+security_invoker
+option (see
+\fBCREATE VIEW\fR)\&.
+.PP
+No separate policy exists for
+\fBMERGE\fR\&. Instead, the policies defined for
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR
+are applied while executing
+\fBMERGE\fR, depending on the actions that are performed\&.
+.PP
+Additional discussion and practical examples can be found in
+Section\ \&5.8\&.
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE POLICY\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER POLICY (\fBALTER_POLICY\fR(7)), DROP POLICY (\fBDROP_POLICY\fR(7)), ALTER TABLE (\fBALTER_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_PROCEDURE.7 b/doc/src/sgml/man7/CREATE_PROCEDURE.7
new file mode 100644
index 0000000..764acce
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_PROCEDURE.7
@@ -0,0 +1,309 @@
+'\" t
+.\" Title: CREATE PROCEDURE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE PROCEDURE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_PROCEDURE \- define a new procedure
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] PROCEDURE
+ \fIname\fR ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ { DEFAULT | = } \fIdefault_expr\fR ] [, \&.\&.\&.] ] )
+ { LANGUAGE \fIlang_name\fR
+ | TRANSFORM { FOR TYPE \fItype_name\fR } [, \&.\&.\&. ]
+ | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ | SET \fIconfiguration_parameter\fR { TO \fIvalue\fR | = \fIvalue\fR | FROM CURRENT }
+ | AS \*(Aq\fIdefinition\fR\*(Aq
+ | AS \*(Aq\fIobj_file\fR\*(Aq, \*(Aq\fIlink_symbol\fR\*(Aq
+ | \fIsql_body\fR
+ } \&.\&.\&.
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE PROCEDURE\fR
+defines a new procedure\&.
+\fBCREATE OR REPLACE PROCEDURE\fR
+will either create a new procedure, or replace an existing definition\&. To be able to define a procedure, the user must have the
+USAGE
+privilege on the language\&.
+.PP
+If a schema name is included, then the procedure is created in the specified schema\&. Otherwise it is created in the current schema\&. The name of the new procedure must not match any existing procedure or function with the same input argument types in the same schema\&. However, procedures and functions of different argument types can share a name (this is called
+overloading)\&.
+.PP
+To replace the current definition of an existing procedure, use
+\fBCREATE OR REPLACE PROCEDURE\fR\&. It is not possible to change the name or argument types of a procedure this way (if you tried, you would actually be creating a new, distinct procedure)\&.
+.PP
+When
+\fBCREATE OR REPLACE PROCEDURE\fR
+is used to replace an existing procedure, the ownership and permissions of the procedure do not change\&. All other procedure properties are assigned the values specified or implied in the command\&. You must own the procedure to replace it (this includes being a member of the owning role)\&.
+.PP
+The user that creates the procedure becomes the owner of the procedure\&.
+.PP
+To be able to create a procedure, you must have
+USAGE
+privilege on the argument types\&.
+.PP
+Refer to
+Section\ \&38.4
+for further information on writing procedures\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the procedure to create\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type(s) of the procedure\*(Aqs arguments (optionally schema\-qualified), if any\&. The argument types can be base, composite, or domain types, or can reference the type of a table column\&.
+.sp
+Depending on the implementation language it might also be allowed to specify
+\(lqpseudo\-types\(rq
+such as
+cstring\&. Pseudo\-types indicate that the actual argument type is either incompletely specified, or outside the set of ordinary SQL data types\&.
+.sp
+The type of a column is referenced by writing
+\fItable_name\fR\&.\fIcolumn_name\fR%TYPE\&. Using this feature can sometimes help make a procedure independent of changes to the definition of a table\&.
+.RE
+.PP
+\fIdefault_expr\fR
+.RS 4
+An expression to be used as default value if the parameter is not specified\&. The expression has to be coercible to the argument type of the parameter\&. All input parameters following a parameter with a default value must have default values as well\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the language that the procedure is implemented in\&. It can be
+sql,
+c,
+internal, or the name of a user\-defined procedural language, e\&.g\&.,
+plpgsql\&. The default is
+sql
+if
+\fIsql_body\fR
+is specified\&. Enclosing the name in single quotes is deprecated and requires matching case\&.
+.RE
+.PP
+TRANSFORM { FOR TYPE \fItype_name\fR } [, \&.\&.\&. ] }
+.RS 4
+Lists which transforms a call to the procedure should apply\&. Transforms convert between SQL types and language\-specific data types; see
+CREATE TRANSFORM (\fBCREATE_TRANSFORM\fR(7))\&. Procedural language implementations usually have hardcoded knowledge of the built\-in types, so those don\*(Aqt need to be listed here\&. If a procedural language implementation does not know how to handle a type and no transform is supplied, it will fall back to a default behavior for converting data types, but this depends on the implementation\&.
+.RE
+.PP
+[EXTERNAL] SECURITY INVOKER
+.br
+[EXTERNAL] SECURITY DEFINER
+.RS 4
+SECURITY INVOKER
+indicates that the procedure is to be executed with the privileges of the user that calls it\&. That is the default\&.
+SECURITY DEFINER
+specifies that the procedure is to be executed with the privileges of the user that owns it\&.
+.sp
+The key word
+EXTERNAL
+is allowed for SQL conformance, but it is optional since, unlike in SQL, this feature applies to all procedures not only external ones\&.
+.sp
+A
+SECURITY DEFINER
+procedure cannot execute transaction control statements (for example,
+\fBCOMMIT\fR
+and
+\fBROLLBACK\fR, depending on the language)\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.br
+\fIvalue\fR
+.RS 4
+The
+SET
+clause causes the specified configuration parameter to be set to the specified value when the procedure is entered, and then restored to its prior value when the procedure exits\&.
+SET FROM CURRENT
+saves the value of the parameter that is current when
+\fBCREATE PROCEDURE\fR
+is executed as the value to be applied when the procedure is entered\&.
+.sp
+If a
+SET
+clause is attached to a procedure, then the effects of a
+\fBSET LOCAL\fR
+command executed inside the procedure for the same variable are restricted to the procedure: the configuration parameter\*(Aqs prior value is still restored at procedure exit\&. However, an ordinary
+\fBSET\fR
+command (without
+LOCAL) overrides the
+SET
+clause, much as it would do for a previous
+\fBSET LOCAL\fR
+command: the effects of such a command will persist after procedure exit, unless the current transaction is rolled back\&.
+.sp
+If a
+SET
+clause is attached to a procedure, then that procedure cannot execute transaction control statements (for example,
+\fBCOMMIT\fR
+and
+\fBROLLBACK\fR, depending on the language)\&.
+.sp
+See
+\fBSET\fR(7)
+and
+Chapter\ \&20
+for more information about allowed parameter names and values\&.
+.RE
+.PP
+\fIdefinition\fR
+.RS 4
+A string constant defining the procedure; the meaning depends on the language\&. It can be an internal procedure name, the path to an object file, an SQL command, or text in a procedural language\&.
+.sp
+It is often helpful to use dollar quoting (see
+Section\ \&4.1.2.4) to write the procedure definition string, rather than the normal single quote syntax\&. Without dollar quoting, any single quotes or backslashes in the procedure definition must be escaped by doubling them\&.
+.RE
+.PP
+\fIobj_file\fR, \fIlink_symbol\fR
+.RS 4
+This form of the
+AS
+clause is used for dynamically loadable C language procedures when the procedure name in the C language source code is not the same as the name of the SQL procedure\&. The string
+\fIobj_file\fR
+is the name of the shared library file containing the compiled C procedure, and is interpreted as for the
+\fBLOAD\fR
+command\&. The string
+\fIlink_symbol\fR
+is the procedure\*(Aqs link symbol, that is, the name of the procedure in the C language source code\&. If the link symbol is omitted, it is assumed to be the same as the name of the SQL procedure being defined\&.
+.sp
+When repeated
+\fBCREATE PROCEDURE\fR
+calls refer to the same object file, the file is only loaded once per session\&. To unload and reload the file (perhaps during development), start a new session\&.
+.RE
+.PP
+\fIsql_body\fR
+.RS 4
+The body of a
+LANGUAGE SQL
+procedure\&. This should be a block
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN ATOMIC
+ \fIstatement\fR;
+ \fIstatement\fR;
+ \&.\&.\&.
+ \fIstatement\fR;
+END
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This is similar to writing the text of the procedure body as a string constant (see
+\fIdefinition\fR
+above), but there are some differences: This form only works for
+LANGUAGE SQL, the string constant form works for all languages\&. This form is parsed at procedure definition time, the string constant form is parsed at execution time; therefore this form cannot support polymorphic argument types and other constructs that are not resolvable at procedure definition time\&. This form tracks dependencies between the procedure and objects used in the procedure body, so
+DROP \&.\&.\&. CASCADE
+will work correctly, whereas the form using string literals may leave dangling procedures\&. Finally, this form is more compatible with the SQL standard and other SQL implementations\&.
+.RE
+.SH "NOTES"
+.PP
+See
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
+for more details on function creation that also apply to procedures\&.
+.PP
+Use
+\fBCALL\fR(7)
+to execute a procedure\&.
+.SH "EXAMPLES"
+.PP
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PROCEDURE insert_data(a integer, b integer)
+LANGUAGE SQL
+AS $$
+INSERT INTO tbl VALUES (a);
+INSERT INTO tbl VALUES (b);
+$$;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+or
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PROCEDURE insert_data(a integer, b integer)
+LANGUAGE SQL
+BEGIN ATOMIC
+ INSERT INTO tbl VALUES (a);
+ INSERT INTO tbl VALUES (b);
+END;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+and call like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CALL insert_data(1, 2);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+A
+\fBCREATE PROCEDURE\fR
+command is defined in the SQL standard\&. The
+PostgreSQL
+implementation can be used in a compatible way but has many extensions\&. For details see also
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))\&.
+.SH "SEE ALSO"
+ALTER PROCEDURE (\fBALTER_PROCEDURE\fR(7)), DROP PROCEDURE (\fBDROP_PROCEDURE\fR(7)), \fBCALL\fR(7), CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_PUBLICATION.7 b/doc/src/sgml/man7/CREATE_PUBLICATION.7
new file mode 100644
index 0000000..c57ca34
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_PUBLICATION.7
@@ -0,0 +1,341 @@
+'\" t
+.\" Title: CREATE PUBLICATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE PUBLICATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_PUBLICATION \- define a new publication
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE PUBLICATION \fIname\fR
+ [ FOR ALL TABLES
+ | FOR \fIpublication_object\fR [, \&.\&.\&. ] ]
+ [ WITH ( \fIpublication_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+
+where \fIpublication_object\fR is one of:
+
+ TABLE [ ONLY ] \fItable_name\fR [ * ] [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ] [ WHERE ( \fIexpression\fR ) ] [, \&.\&.\&. ]
+ TABLES IN SCHEMA { \fIschema_name\fR | CURRENT_SCHEMA } [, \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE PUBLICATION\fR
+adds a new publication into the current database\&. The publication name must be distinct from the name of any existing publication in the current database\&.
+.PP
+A publication is essentially a group of tables whose data changes are intended to be replicated through logical replication\&. See
+Section\ \&31.1
+for details about how publications fit into the logical replication setup\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the new publication\&.
+.RE
+.PP
+FOR TABLE
+.RS 4
+Specifies a list of tables to add to the publication\&. If
+ONLY
+is specified before the table name, only that table is added to the publication\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are added\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&. This does not apply to a partitioned table, however\&. The partitions of a partitioned table are always implicitly considered part of the publication, so they are never explicitly added to the publication\&.
+.sp
+If the optional
+WHERE
+clause is specified, it defines a
+row filter
+expression\&. Rows for which the
+\fIexpression\fR
+evaluates to false or null will not be published\&. Note that parentheses are required around the expression\&. It has no effect on
+TRUNCATE
+commands\&.
+.sp
+When a column list is specified, only the named columns are replicated\&. If no column list is specified, all columns of the table are replicated through this publication, including any columns added later\&. It has no effect on
+TRUNCATE
+commands\&. See
+Section\ \&31.4
+for details about column lists\&.
+.sp
+Only persistent base tables and partitioned tables can be part of a publication\&. Temporary tables, unlogged tables, foreign tables, materialized views, and regular views cannot be part of a publication\&.
+.sp
+Specifying a column list when the publication also publishes
+FOR TABLES IN SCHEMA
+is not supported\&.
+.sp
+When a partitioned table is added to a publication, all of its existing and future partitions are implicitly considered to be part of the publication\&. So, even operations that are performed directly on a partition are also published via publications that its ancestors are part of\&.
+.RE
+.PP
+FOR ALL TABLES
+.RS 4
+Marks the publication as one that replicates changes for all tables in the database, including tables created in the future\&.
+.RE
+.PP
+FOR TABLES IN SCHEMA
+.RS 4
+Marks the publication as one that replicates changes for all tables in the specified list of schemas, including tables created in the future\&.
+.sp
+Specifying a schema when the publication also publishes a table with a column list is not supported\&.
+.sp
+Only persistent base tables and partitioned tables present in the schema will be included as part of the publication\&. Temporary tables, unlogged tables, foreign tables, materialized views, and regular views from the schema will not be part of the publication\&.
+.sp
+When a partitioned table is published via schema level publication, all of its existing and future partitions are implicitly considered to be part of the publication, regardless of whether they are from the publication schema or not\&. So, even operations that are performed directly on a partition are also published via publications that its ancestors are part of\&.
+.RE
+.PP
+WITH ( \fIpublication_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause specifies optional parameters for a publication\&. The following parameters are supported:
+.PP
+publish (string)
+.RS 4
+This parameter determines which DML operations will be published by the new publication to the subscribers\&. The value is comma\-separated list of operations\&. The allowed operations are
+insert,
+update,
+delete, and
+truncate\&. The default is to publish all actions, and so the default value for this option is
+\*(Aqinsert, update, delete, truncate\*(Aq\&.
+.sp
+This parameter only affects DML operations\&. In particular, the initial data synchronization (see
+Section\ \&31.7.1) for logical replication does not take this parameter into account when copying existing table data\&.
+.RE
+.PP
+publish_via_partition_root (boolean)
+.RS 4
+This parameter determines whether changes in a partitioned table (or on its partitions) contained in the publication will be published using the identity and schema of the partitioned table rather than that of the individual partitions that are actually changed; the latter is the default\&. Enabling this allows the changes to be replicated into a non\-partitioned table or a partitioned table consisting of a different set of partitions\&.
+.sp
+This parameter also affects how row filters and column lists are chosen for partitions; see below for details\&.
+.sp
+If this is enabled,
+TRUNCATE
+operations performed directly on partitions are not replicated\&.
+.RE
+.RE
+.SH "NOTES"
+.PP
+If
+FOR TABLE,
+FOR ALL TABLES
+or
+FOR TABLES IN SCHEMA
+are not specified, then the publication starts out with an empty set of tables\&. That is useful if tables or schemas are to be added later\&.
+.PP
+The creation of a publication does not start replication\&. It only defines a grouping and filtering logic for future subscribers\&.
+.PP
+To create a publication, the invoking user must have the
+CREATE
+privilege for the current database\&. (Of course, superusers bypass this check\&.)
+.PP
+To add a table to a publication, the invoking user must have ownership rights on the table\&. The
+\fBFOR ALL TABLES\fR
+and
+\fBFOR TABLES IN SCHEMA\fR
+clauses require the invoking user to be a superuser\&.
+.PP
+The tables added to a publication that publishes
+\fBUPDATE\fR
+and/or
+\fBDELETE\fR
+operations must have
+REPLICA IDENTITY
+defined\&. Otherwise those operations will be disallowed on those tables\&.
+.PP
+Any column list must include the
+REPLICA IDENTITY
+columns in order for
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+operations to be published\&. There are no column list restrictions if the publication publishes only
+\fBINSERT\fR
+operations\&.
+.PP
+A row filter expression (i\&.e\&., the
+WHERE
+clause) must contain only columns that are covered by the
+REPLICA IDENTITY, in order for
+\fBUPDATE\fR
+and
+\fBDELETE\fR
+operations to be published\&. For publication of
+\fBINSERT\fR
+operations, any column may be used in the
+WHERE
+expression\&. The row filter allows simple expressions that don\*(Aqt have user\-defined functions, user\-defined operators, user\-defined types, user\-defined collations, non\-immutable built\-in functions, or references to system columns\&.
+.PP
+The row filter on a table becomes redundant if
+FOR TABLES IN SCHEMA
+is specified and the table belongs to the referred schema\&.
+.PP
+For published partitioned tables, the row filter for each partition is taken from the published partitioned table if the publication parameter
+publish_via_partition_root
+is true, or from the partition itself if it is false (the default)\&. See
+Section\ \&31.3
+for details about row filters\&. Similarly, for published partitioned tables, the column list for each partition is taken from the published partitioned table if the publication parameter
+publish_via_partition_root
+is true, or from the partition itself if it is false\&.
+.PP
+For an
+\fBINSERT \&.\&.\&. ON CONFLICT\fR
+command, the publication will publish the operation that results from the command\&. Depending on the outcome, it may be published as either
+\fBINSERT\fR
+or
+\fBUPDATE\fR, or it may not be published at all\&.
+.PP
+For a
+\fBMERGE\fR
+command, the publication will publish an
+\fBINSERT\fR,
+\fBUPDATE\fR, or
+\fBDELETE\fR
+for each row inserted, updated, or deleted\&.
+.PP
+\fBATTACH\fRing a table into a partition tree whose root is published using a publication with
+publish_via_partition_root
+set to
+true
+does not result in the table\*(Aqs existing contents being replicated\&.
+.PP
+\fBCOPY \&.\&.\&. FROM\fR
+commands are published as
+\fBINSERT\fR
+operations\&.
+.PP
+DDL
+operations are not published\&.
+.PP
+The
+WHERE
+clause expression is executed with the role used for the replication connection\&.
+.SH "EXAMPLES"
+.PP
+Create a publication that publishes all changes in two tables:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION mypublication FOR TABLE users, departments;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a publication that publishes all changes from active departments:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a publication that publishes all changes in all tables:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION alltables FOR ALL TABLES;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a publication that only publishes
+\fBINSERT\fR
+operations in one table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION insert_only FOR TABLE mydata
+ WITH (publish = \*(Aqinsert\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a publication that publishes all changes for tables
+users,
+departments
+and all changes for all the tables present in the schema
+production:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a publication that publishes all changes for all the tables present in the schemas
+marketing
+and
+sales:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a publication that publishes all changes for table
+users, but replicates only columns
+user_id
+and
+firstname:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE PUBLICATION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER PUBLICATION (\fBALTER_PUBLICATION\fR(7)), DROP PUBLICATION (\fBDROP_PUBLICATION\fR(7)), CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7)), ALTER SUBSCRIPTION (\fBALTER_SUBSCRIPTION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_ROLE.7 b/doc/src/sgml/man7/CREATE_ROLE.7
new file mode 100644
index 0000000..e0df1d8
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_ROLE.7
@@ -0,0 +1,427 @@
+'\" t
+.\" Title: CREATE ROLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE ROLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_ROLE \- define a new database role
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE ROLE \fIname\fR [ [ WITH ] \fIoption\fR [ \&.\&.\&. ] ]
+
+where \fIoption\fR can be:
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT \fIconnlimit\fR
+ | [ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq | PASSWORD NULL
+ | VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+ | IN ROLE \fIrole_name\fR [, \&.\&.\&.]
+ | IN GROUP \fIrole_name\fR [, \&.\&.\&.]
+ | ROLE \fIrole_name\fR [, \&.\&.\&.]
+ | ADMIN \fIrole_name\fR [, \&.\&.\&.]
+ | USER \fIrole_name\fR [, \&.\&.\&.]
+ | SYSID \fIuid\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE ROLE\fR
+adds a new role to a
+PostgreSQL
+database cluster\&. A role is an entity that can own database objects and have database privileges; a role can be considered a
+\(lquser\(rq, a
+\(lqgroup\(rq, or both depending on how it is used\&. Refer to
+Chapter\ \&22
+and
+Chapter\ \&21
+for information about managing users and authentication\&. You must have
+CREATEROLE
+privilege or be a database superuser to use this command\&.
+.PP
+Note that roles are defined at the database cluster level, and so are valid in all databases in the cluster\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the new role\&.
+.RE
+.PP
+SUPERUSER
+.br
+NOSUPERUSER
+.RS 4
+These clauses determine whether the new role is a
+\(lqsuperuser\(rq, who can override all access restrictions within the database\&. Superuser status is dangerous and should be used only when really needed\&. You must yourself be a superuser to create a new superuser\&. If not specified,
+NOSUPERUSER
+is the default\&.
+.RE
+.PP
+CREATEDB
+.br
+NOCREATEDB
+.RS 4
+These clauses define a role\*(Aqs ability to create databases\&. If
+CREATEDB
+is specified, the role being defined will be allowed to create new databases\&. Specifying
+NOCREATEDB
+will deny a role the ability to create databases\&. If not specified,
+NOCREATEDB
+is the default\&.
+.RE
+.PP
+CREATEROLE
+.br
+NOCREATEROLE
+.RS 4
+These clauses determine whether a role will be permitted to create, alter, drop, comment on, change the security label for, and grant or revoke membership in other roles\&. See
+role creation
+for more details about what capabilities are conferred by this privilege\&. If not specified,
+NOCREATEROLE
+is the default\&.
+.RE
+.PP
+INHERIT
+.br
+NOINHERIT
+.RS 4
+These clauses determine whether a role
+\(lqinherits\(rq
+the privileges of roles it is a member of\&. A role with the
+INHERIT
+attribute can automatically use whatever database privileges have been granted to all roles it is directly or indirectly a member of\&. Without
+INHERIT, membership in another role only grants the ability to
+\fBSET ROLE\fR
+to that other role; the privileges of the other role are only available after having done so\&. If not specified,
+INHERIT
+is the default\&.
+.RE
+.PP
+LOGIN
+.br
+NOLOGIN
+.RS 4
+These clauses determine whether a role is allowed to log in; that is, whether the role can be given as the initial session authorization name during client connection\&. A role having the
+LOGIN
+attribute can be thought of as a user\&. Roles without this attribute are useful for managing database privileges, but are not users in the usual sense of the word\&. If not specified,
+NOLOGIN
+is the default, except when
+\fBCREATE ROLE\fR
+is invoked through its alternative spelling
+\fBCREATE USER\fR\&.
+.RE
+.PP
+REPLICATION
+.br
+NOREPLICATION
+.RS 4
+These clauses determine whether a role is a replication role\&. A role must have this attribute (or be a superuser) in order to be able to connect to the server in replication mode (physical or logical replication) and in order to be able to create or drop replication slots\&. A role having the
+REPLICATION
+attribute is a very highly privileged role, and should only be used on roles actually used for replication\&. If not specified,
+NOREPLICATION
+is the default\&. You must be a superuser to create a new role having the
+REPLICATION
+attribute\&.
+.RE
+.PP
+BYPASSRLS
+.br
+NOBYPASSRLS
+.RS 4
+These clauses determine whether a role bypasses every row\-level security (RLS) policy\&.
+NOBYPASSRLS
+is the default\&. You must be a superuser to create a new role having the
+BYPASSRLS
+attribute\&.
+.sp
+Note that pg_dump will set
+row_security
+to
+OFF
+by default, to ensure all contents of a table are dumped out\&. If the user running pg_dump does not have appropriate permissions, an error will be returned\&. However, superusers and the owner of the table being dumped always bypass RLS\&.
+.RE
+.PP
+CONNECTION LIMIT \fIconnlimit\fR
+.RS 4
+If role can log in, this specifies how many concurrent connections the role can make\&. \-1 (the default) means no limit\&. Note that only normal connections are counted towards this limit\&. Neither prepared transactions nor background worker connections are counted towards this limit\&.
+.RE
+.PP
+[ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq
+.br
+PASSWORD NULL
+.RS 4
+Sets the role\*(Aqs password\&. (A password is only of use for roles having the
+LOGIN
+attribute, but you can nonetheless define one for roles without it\&.) If you do not plan to use password authentication you can omit this option\&. If no password is specified, the password will be set to null and password authentication will always fail for that user\&. A null password can optionally be written explicitly as
+PASSWORD NULL\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+Specifying an empty string will also set the password to null, but that was not the case before
+PostgreSQL
+version 10\&. In earlier versions, an empty string could be used, or not, depending on the authentication method and the exact version, and libpq would refuse to use it in any case\&. To avoid the ambiguity, specifying an empty string should be avoided\&.
+.sp .5v
+.RE
+The password is always stored encrypted in the system catalogs\&. The
+ENCRYPTED
+keyword has no effect, but is accepted for backwards compatibility\&. The method of encryption is determined by the configuration parameter
+password_encryption\&. If the presented password string is already in MD5\-encrypted or SCRAM\-encrypted format, then it is stored as\-is regardless of
+\fIpassword_encryption\fR
+(since the system cannot decrypt the specified encrypted password string, to encrypt it in a different format)\&. This allows reloading of encrypted passwords during dump/restore\&.
+.RE
+.PP
+VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+.RS 4
+The
+VALID UNTIL
+clause sets a date and time after which the role\*(Aqs password is no longer valid\&. If this clause is omitted the password will be valid for all time\&.
+.RE
+.PP
+IN ROLE \fIrole_name\fR
+.RS 4
+The
+IN ROLE
+clause lists one or more existing roles to which the new role will be immediately added as a new member\&. (Note that there is no option to add the new role as an administrator; use a separate
+\fBGRANT\fR
+command to do that\&.)
+.RE
+.PP
+IN GROUP \fIrole_name\fR
+.RS 4
+IN GROUP
+is an obsolete spelling of
+IN ROLE\&.
+.RE
+.PP
+ROLE \fIrole_name\fR
+.RS 4
+The
+ROLE
+clause lists one or more existing roles which are automatically added as members of the new role\&. (This in effect makes the new role a
+\(lqgroup\(rq\&.)
+.RE
+.PP
+ADMIN \fIrole_name\fR
+.RS 4
+The
+ADMIN
+clause is like
+ROLE, but the named roles are added to the new role
+WITH ADMIN OPTION, giving them the right to grant membership in this role to others\&.
+.RE
+.PP
+USER \fIrole_name\fR
+.RS 4
+The
+USER
+clause is an obsolete spelling of the
+ROLE
+clause\&.
+.RE
+.PP
+SYSID \fIuid\fR
+.RS 4
+The
+SYSID
+clause is ignored, but is accepted for backwards compatibility\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBALTER ROLE\fR
+to change the attributes of a role, and
+\fBDROP ROLE\fR
+to remove a role\&. All the attributes specified by
+\fBCREATE ROLE\fR
+can be modified by later
+\fBALTER ROLE\fR
+commands\&.
+.PP
+The preferred way to add and remove members of roles that are being used as groups is to use
+\fBGRANT\fR
+and
+\fBREVOKE\fR\&.
+.PP
+The
+VALID UNTIL
+clause defines an expiration time for a password only, not for the role per se\&. In particular, the expiration time is not enforced when logging in using a non\-password\-based authentication method\&.
+.PP
+The
+INHERIT
+attribute governs inheritance of grantable privileges (that is, access privileges for database objects and role memberships)\&. It does not apply to the special role attributes set by
+\fBCREATE ROLE\fR
+and
+\fBALTER ROLE\fR\&. For example, being a member of a role with
+CREATEDB
+privilege does not immediately grant the ability to create databases, even if
+INHERIT
+is set; it would be necessary to become that role via
+\fBSET ROLE\fR
+before creating a database\&.
+.PP
+The
+INHERIT
+attribute is the default for reasons of backwards compatibility: in prior releases of
+PostgreSQL, users always had access to all privileges of groups they were members of\&. However,
+NOINHERIT
+provides a closer match to the semantics specified in the SQL standard\&.
+.PP
+Be careful with the
+CREATEROLE
+privilege\&. There is no concept of inheritance for the privileges of a
+CREATEROLE\-role\&. That means that even if a role does not have a certain privilege but is allowed to create other roles, it can easily create another role with different privileges than its own (except for creating roles with superuser privileges)\&. For example, if the role
+\(lquser\(rq
+has the
+CREATEROLE
+privilege but not the
+CREATEDB
+privilege, nonetheless it can create a new role with the
+CREATEDB
+privilege\&. Therefore, regard roles that have the
+CREATEROLE
+privilege as almost\-superuser\-roles\&.
+.PP
+PostgreSQL
+includes a program
+\fBcreateuser\fR(1)
+that has the same functionality as
+\fBCREATE ROLE\fR
+(in fact, it calls this command) but can be run from the command shell\&.
+.PP
+The
+CONNECTION LIMIT
+option is only enforced approximately; if two new sessions start at about the same time when just one connection
+\(lqslot\(rq
+remains for the role, it is possible that both will fail\&. Also, the limit is never enforced for superusers\&.
+.PP
+Caution must be exercised when specifying an unencrypted password with this command\&. The password will be transmitted to the server in cleartext, and it might also be logged in the client\*(Aqs command history or the server log\&. The command
+\fBcreateuser\fR(1), however, transmits the password encrypted\&. Also,
+\fBpsql\fR(1)
+contains a command
+\fB\epassword\fR
+that can be used to safely change the password later\&.
+.SH "EXAMPLES"
+.PP
+Create a role that can log in, but don\*(Aqt give it a password:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE ROLE jonathan LOGIN;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a role with a password:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE USER davide WITH PASSWORD \*(Aqjw8s0F4\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+(\fBCREATE USER\fR
+is the same as
+\fBCREATE ROLE\fR
+except that it implies
+LOGIN\&.)
+.PP
+Create a role with a password that is valid until the end of 2004\&. After one second has ticked in 2005, the password is no longer valid\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE ROLE miriam WITH LOGIN PASSWORD \*(Aqjw8s0F4\*(Aq VALID UNTIL \*(Aq2005\-01\-01\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a role that can create databases and manage roles:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE ROLE admin WITH CREATEDB CREATEROLE;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCREATE ROLE\fR
+statement is in the SQL standard, but the standard only requires the syntax
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE ROLE \fIname\fR [ WITH ADMIN \fIrole_name\fR ]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Multiple initial administrators, and all the other options of
+\fBCREATE ROLE\fR, are
+PostgreSQL
+extensions\&.
+.PP
+The SQL standard defines the concepts of users and roles, but it regards them as distinct concepts and leaves all commands defining users to be specified by each database implementation\&. In
+PostgreSQL
+we have chosen to unify users and roles into a single kind of entity\&. Roles therefore have many more optional attributes than they do in the standard\&.
+.PP
+The behavior specified by the SQL standard is most closely approximated by giving users the
+NOINHERIT
+attribute, while roles are given the
+INHERIT
+attribute\&.
+.SH "SEE ALSO"
+SET ROLE (\fBSET_ROLE\fR(7)), ALTER ROLE (\fBALTER_ROLE\fR(7)), DROP ROLE (\fBDROP_ROLE\fR(7)), \fBGRANT\fR(7), \fBREVOKE\fR(7), \fBcreateuser\fR(1)
diff --git a/doc/src/sgml/man7/CREATE_RULE.7 b/doc/src/sgml/man7/CREATE_RULE.7
new file mode 100644
index 0000000..e9bc688
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_RULE.7
@@ -0,0 +1,300 @@
+'\" t
+.\" Title: CREATE RULE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE RULE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_RULE \- define a new rewrite rule
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] RULE \fIname\fR AS ON \fIevent\fR
+ TO \fItable_name\fR [ WHERE \fIcondition\fR ]
+ DO [ ALSO | INSTEAD ] { NOTHING | \fIcommand\fR | ( \fIcommand\fR ; \fIcommand\fR \&.\&.\&. ) }
+
+where \fIevent\fR can be one of:
+
+ SELECT | INSERT | UPDATE | DELETE
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE RULE\fR
+defines a new rule applying to a specified table or view\&.
+\fBCREATE OR REPLACE RULE\fR
+will either create a new rule, or replace an existing rule of the same name for the same table\&.
+.PP
+The
+PostgreSQL
+rule system allows one to define an alternative action to be performed on insertions, updates, or deletions in database tables\&. Roughly speaking, a rule causes additional commands to be executed when a given command on a given table is executed\&. Alternatively, an
+INSTEAD
+rule can replace a given command by another, or cause a command not to be executed at all\&. Rules are used to implement SQL views as well\&. It is important to realize that a rule is really a command transformation mechanism, or command macro\&. The transformation happens before the execution of the command starts\&. If you actually want an operation that fires independently for each physical row, you probably want to use a trigger, not a rule\&. More information about the rules system is in
+Chapter\ \&41\&.
+.PP
+Presently,
+ON SELECT
+rules must be unconditional
+INSTEAD
+rules and must have actions that consist of a single
+\fBSELECT\fR
+command\&. Thus, an
+ON SELECT
+rule effectively turns the table into a view, whose visible contents are the rows returned by the rule\*(Aqs
+\fBSELECT\fR
+command rather than whatever had been stored in the table (if anything)\&. It is considered better style to write a
+\fBCREATE VIEW\fR
+command than to create a real table and define an
+ON SELECT
+rule for it\&.
+.PP
+You can create the illusion of an updatable view by defining
+ON INSERT,
+ON UPDATE, and
+ON DELETE
+rules (or any subset of those that\*(Aqs sufficient for your purposes) to replace update actions on the view with appropriate updates on other tables\&. If you want to support
+\fBINSERT RETURNING\fR
+and so on, then be sure to put a suitable
+RETURNING
+clause into each of these rules\&.
+.PP
+There is a catch if you try to use conditional rules for complex view updates: there
+\fImust\fR
+be an unconditional
+INSTEAD
+rule for each action you wish to allow on the view\&. If the rule is conditional, or is not
+INSTEAD, then the system will still reject attempts to perform the update action, because it thinks it might end up trying to perform the action on the dummy table of the view in some cases\&. If you want to handle all the useful cases in conditional rules, add an unconditional
+DO INSTEAD NOTHING
+rule to ensure that the system understands it will never be called on to update the dummy table\&. Then make the conditional rules non\-INSTEAD; in the cases where they are applied, they add to the default
+INSTEAD NOTHING
+action\&. (This method does not currently work to support
+RETURNING
+queries, however\&.)
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+A view that is simple enough to be automatically updatable (see
+CREATE VIEW (\fBCREATE_VIEW\fR(7))) does not require a user\-created rule in order to be updatable\&. While you can create an explicit rule anyway, the automatic update transformation will generally outperform an explicit rule\&.
+.PP
+Another alternative worth considering is to use
+INSTEAD OF
+triggers (see
+CREATE TRIGGER (\fBCREATE_TRIGGER\fR(7))) in place of rules\&.
+.sp .5v
+.RE
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of a rule to create\&. This must be distinct from the name of any other rule for the same table\&. Multiple rules on the same table and same event type are applied in alphabetical name order\&.
+.RE
+.PP
+\fIevent\fR
+.RS 4
+The event is one of
+SELECT,
+INSERT,
+UPDATE, or
+DELETE\&. Note that an
+\fBINSERT\fR
+containing an
+ON CONFLICT
+clause cannot be used on tables that have either
+INSERT
+or
+UPDATE
+rules\&. Consider using an updatable view instead\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table or view the rule applies to\&.
+.RE
+.PP
+\fIcondition\fR
+.RS 4
+Any
+SQL
+conditional expression (returning
+boolean)\&. The condition expression cannot refer to any tables except
+NEW
+and
+OLD, and cannot contain aggregate functions\&.
+.RE
+.PP
+\fBINSTEAD\fR
+.RS 4
+INSTEAD
+indicates that the commands should be executed
+\fIinstead of\fR
+the original command\&.
+.RE
+.PP
+\fBALSO\fR
+.RS 4
+ALSO
+indicates that the commands should be executed
+\fIin addition to\fR
+the original command\&.
+.sp
+If neither
+ALSO
+nor
+INSTEAD
+is specified,
+ALSO
+is the default\&.
+.RE
+.PP
+\fIcommand\fR
+.RS 4
+The command or commands that make up the rule action\&. Valid commands are
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR,
+\fBDELETE\fR, or
+\fBNOTIFY\fR\&.
+.RE
+.PP
+Within
+\fIcondition\fR
+and
+\fIcommand\fR, the special table names
+NEW
+and
+OLD
+can be used to refer to values in the referenced table\&.
+NEW
+is valid in
+ON INSERT
+and
+ON UPDATE
+rules to refer to the new row being inserted or updated\&.
+OLD
+is valid in
+ON UPDATE
+and
+ON DELETE
+rules to refer to the existing row being updated or deleted\&.
+.SH "NOTES"
+.PP
+You must be the owner of a table to create or change rules for it\&.
+.PP
+In a rule for
+INSERT,
+UPDATE, or
+DELETE
+on a view, you can add a
+RETURNING
+clause that emits the view\*(Aqs columns\&. This clause will be used to compute the outputs if the rule is triggered by an
+\fBINSERT RETURNING\fR,
+\fBUPDATE RETURNING\fR, or
+\fBDELETE RETURNING\fR
+command respectively\&. When the rule is triggered by a command without
+RETURNING, the rule\*(Aqs
+RETURNING
+clause will be ignored\&. The current implementation allows only unconditional
+INSTEAD
+rules to contain
+RETURNING; furthermore there can be at most one
+RETURNING
+clause among all the rules for the same event\&. (This ensures that there is only one candidate
+RETURNING
+clause to be used to compute the results\&.)
+RETURNING
+queries on the view will be rejected if there is no
+RETURNING
+clause in any available rule\&.
+.PP
+It is very important to take care to avoid circular rules\&. For example, though each of the following two rule definitions are accepted by
+PostgreSQL, the
+\fBSELECT\fR
+command would cause
+PostgreSQL
+to report an error because of recursive expansion of a rule:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t1
+ DO INSTEAD
+ SELECT * FROM t2;
+
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t2
+ DO INSTEAD
+ SELECT * FROM t1;
+
+SELECT * FROM t1;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Presently, if a rule action contains a
+\fBNOTIFY\fR
+command, the
+\fBNOTIFY\fR
+command will be executed unconditionally, that is, the
+\fBNOTIFY\fR
+will be issued even if there are not any rows that the rule should apply to\&. For example, in:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;
+
+UPDATE mytable SET name = \*(Aqfoo\*(Aq WHERE id = 42;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+one
+\fBNOTIFY\fR
+event will be sent during the
+\fBUPDATE\fR, whether or not there are any rows that match the condition
+id = 42\&. This is an implementation restriction that might be fixed in future releases\&.
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE RULE\fR
+is a
+PostgreSQL
+language extension, as is the entire query rewrite system\&.
+.SH "SEE ALSO"
+ALTER RULE (\fBALTER_RULE\fR(7)), DROP RULE (\fBDROP_RULE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_SCHEMA.7 b/doc/src/sgml/man7/CREATE_SCHEMA.7
new file mode 100644
index 0000000..e003f82
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_SCHEMA.7
@@ -0,0 +1,207 @@
+'\" t
+.\" Title: CREATE SCHEMA
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE SCHEMA" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_SCHEMA \- define a new schema
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE SCHEMA \fIschema_name\fR [ AUTHORIZATION \fIrole_specification\fR ] [ \fIschema_element\fR [ \&.\&.\&. ] ]
+CREATE SCHEMA AUTHORIZATION \fIrole_specification\fR [ \fIschema_element\fR [ \&.\&.\&. ] ]
+CREATE SCHEMA IF NOT EXISTS \fIschema_name\fR [ AUTHORIZATION \fIrole_specification\fR ]
+CREATE SCHEMA IF NOT EXISTS AUTHORIZATION \fIrole_specification\fR
+
+where \fIrole_specification\fR can be:
+
+ \fIuser_name\fR
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE SCHEMA\fR
+enters a new schema into the current database\&. The schema name must be distinct from the name of any existing schema in the current database\&.
+.PP
+A schema is essentially a namespace: it contains named objects (tables, data types, functions, and operators) whose names can duplicate those of other objects existing in other schemas\&. Named objects are accessed either by
+\(lqqualifying\(rq
+their names with the schema name as a prefix, or by setting a search path that includes the desired schema(s)\&. A
+CREATE
+command specifying an unqualified object name creates the object in the current schema (the one at the front of the search path, which can be determined with the function
+\fBcurrent_schema\fR)\&.
+.PP
+Optionally,
+\fBCREATE SCHEMA\fR
+can include subcommands to create objects within the new schema\&. The subcommands are treated essentially the same as separate commands issued after creating the schema, except that if the
+AUTHORIZATION
+clause is used, all the created objects will be owned by that user\&.
+.SH "PARAMETERS"
+.PP
+\fIschema_name\fR
+.RS 4
+The name of a schema to be created\&. If this is omitted, the
+\fIuser_name\fR
+is used as the schema name\&. The name cannot begin with
+pg_, as such names are reserved for system schemas\&.
+.RE
+.PP
+\fIuser_name\fR
+.RS 4
+The role name of the user who will own the new schema\&. If omitted, defaults to the user executing the command\&. To create a schema owned by another role, you must be a direct or indirect member of that role, or be a superuser\&.
+.RE
+.PP
+\fIschema_element\fR
+.RS 4
+An SQL statement defining an object to be created within the schema\&. Currently, only
+\fBCREATE TABLE\fR,
+\fBCREATE VIEW\fR,
+\fBCREATE INDEX\fR,
+\fBCREATE SEQUENCE\fR,
+\fBCREATE TRIGGER\fR
+and
+\fBGRANT\fR
+are accepted as clauses within
+\fBCREATE SCHEMA\fR\&. Other kinds of objects may be created in separate commands after the schema is created\&.
+.RE
+.PP
+IF NOT EXISTS
+.RS 4
+Do nothing (except issuing a notice) if a schema with the same name already exists\&.
+\fIschema_element\fR
+subcommands cannot be included when this option is used\&.
+.RE
+.SH "NOTES"
+.PP
+To create a schema, the invoking user must have the
+CREATE
+privilege for the current database\&. (Of course, superusers bypass this check\&.)
+.SH "EXAMPLES"
+.PP
+Create a schema:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SCHEMA myschema;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a schema for user
+joe; the schema will also be named
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SCHEMA AUTHORIZATION joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a schema named
+test
+that will be owned by user
+joe, unless there already is a schema named
+test\&. (It does not matter whether
+joe
+owns the pre\-existing schema\&.)
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a schema and create a table and view within it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SCHEMA hollywood
+ CREATE TABLE films (title text, release date, awards text[])
+ CREATE VIEW winners AS
+ SELECT title, release FROM films WHERE awards IS NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Notice that the individual subcommands do not end with semicolons\&.
+.PP
+The following is an equivalent way of accomplishing the same result:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SCHEMA hollywood;
+CREATE TABLE hollywood\&.films (title text, release date, awards text[]);
+CREATE VIEW hollywood\&.winners AS
+ SELECT title, release FROM hollywood\&.films WHERE awards IS NOT NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The SQL standard allows a
+DEFAULT CHARACTER SET
+clause in
+\fBCREATE SCHEMA\fR, as well as more subcommand types than are presently accepted by
+PostgreSQL\&.
+.PP
+The SQL standard specifies that the subcommands in
+\fBCREATE SCHEMA\fR
+can appear in any order\&. The present
+PostgreSQL
+implementation does not handle all cases of forward references in subcommands; it might sometimes be necessary to reorder the subcommands in order to avoid forward references\&.
+.PP
+According to the SQL standard, the owner of a schema always owns all objects within it\&.
+PostgreSQL
+allows schemas to contain objects owned by users other than the schema owner\&. This can happen only if the schema owner grants the
+CREATE
+privilege on their schema to someone else, or a superuser chooses to create objects in it\&.
+.PP
+The
+IF NOT EXISTS
+option is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER SCHEMA (\fBALTER_SCHEMA\fR(7)), DROP SCHEMA (\fBDROP_SCHEMA\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_SEQUENCE.7 b/doc/src/sgml/man7/CREATE_SEQUENCE.7
new file mode 100644
index 0000000..ac9b9db
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_SEQUENCE.7
@@ -0,0 +1,357 @@
+'\" t
+.\" Title: CREATE SEQUENCE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE SEQUENCE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_SEQUENCE \- define a new sequence generator
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] \fIname\fR
+ [ AS \fIdata_type\fR ]
+ [ INCREMENT [ BY ] \fIincrement\fR ]
+ [ MINVALUE \fIminvalue\fR | NO MINVALUE ] [ MAXVALUE \fImaxvalue\fR | NO MAXVALUE ]
+ [ START [ WITH ] \fIstart\fR ] [ CACHE \fIcache\fR ] [ [ NO ] CYCLE ]
+ [ OWNED BY { \fItable_name\fR\&.\fIcolumn_name\fR | NONE } ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE SEQUENCE\fR
+creates a new sequence number generator\&. This involves creating and initializing a new special single\-row table with the name
+\fIname\fR\&. The generator will be owned by the user issuing the command\&.
+.PP
+If a schema name is given then the sequence is created in the specified schema\&. Otherwise it is created in the current schema\&. Temporary sequences exist in a special schema, so a schema name cannot be given when creating a temporary sequence\&. The sequence name must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in the same schema\&.
+.PP
+After a sequence is created, you use the functions
+\fBnextval\fR,
+\fBcurrval\fR, and
+\fBsetval\fR
+to operate on the sequence\&. These functions are documented in
+Section\ \&9.17\&.
+.PP
+Although you cannot update a sequence directly, you can use a query like:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM \fIname\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+to examine the parameters and current state of a sequence\&. In particular, the
+last_value
+field of the sequence shows the last value allocated by any session\&. (Of course, this value might be obsolete by the time it\*(Aqs printed, if other sessions are actively doing
+\fBnextval\fR
+calls\&.)
+.SH "PARAMETERS"
+.PP
+TEMPORARY or TEMP
+.RS 4
+If specified, the sequence object is created only for this session, and is automatically dropped on session exit\&. Existing permanent sequences with the same name are not visible (in this session) while the temporary sequence exists, unless they are referenced with schema\-qualified names\&.
+.RE
+.PP
+UNLOGGED
+.RS 4
+If specified, the sequence is created as an unlogged sequence\&. Changes to unlogged sequences are not written to the write\-ahead log\&. They are not crash\-safe: an unlogged sequence is automatically reset to its initial state after a crash or unclean shutdown\&. Unlogged sequences are also not replicated to standby servers\&.
+.sp
+Unlike unlogged tables, unlogged sequences do not offer a significant performance advantage\&. This option is mainly intended for sequences associated with unlogged tables via identity columns or serial columns\&. In those cases, it usually wouldn\*(Aqt make sense to have the sequence WAL\-logged and replicated but not its associated table\&.
+.RE
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a relation with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing relation is anything like the sequence that would have been created \(em it might not even be a sequence\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the sequence to be created\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The optional clause
+AS \fIdata_type\fR
+specifies the data type of the sequence\&. Valid types are
+smallint,
+integer, and
+bigint\&.
+bigint
+is the default\&. The data type determines the default minimum and maximum values of the sequence\&.
+.RE
+.PP
+\fIincrement\fR
+.RS 4
+The optional clause
+INCREMENT BY \fIincrement\fR
+specifies which value is added to the current sequence value to create a new value\&. A positive value will make an ascending sequence, a negative one a descending sequence\&. The default value is 1\&.
+.RE
+.PP
+\fIminvalue\fR
+.br
+NO MINVALUE
+.RS 4
+The optional clause
+MINVALUE \fIminvalue\fR
+determines the minimum value a sequence can generate\&. If this clause is not supplied or
+\fBNO MINVALUE\fR
+is specified, then defaults will be used\&. The default for an ascending sequence is 1\&. The default for a descending sequence is the minimum value of the data type\&.
+.RE
+.PP
+\fImaxvalue\fR
+.br
+NO MAXVALUE
+.RS 4
+The optional clause
+MAXVALUE \fImaxvalue\fR
+determines the maximum value for the sequence\&. If this clause is not supplied or
+\fBNO MAXVALUE\fR
+is specified, then default values will be used\&. The default for an ascending sequence is the maximum value of the data type\&. The default for a descending sequence is \-1\&.
+.RE
+.PP
+\fIstart\fR
+.RS 4
+The optional clause
+START WITH \fIstart\fR
+allows the sequence to begin anywhere\&. The default starting value is
+\fIminvalue\fR
+for ascending sequences and
+\fImaxvalue\fR
+for descending ones\&.
+.RE
+.PP
+\fIcache\fR
+.RS 4
+The optional clause
+CACHE \fIcache\fR
+specifies how many sequence numbers are to be preallocated and stored in memory for faster access\&. The minimum value is 1 (only one value can be generated at a time, i\&.e\&., no cache), and this is also the default\&.
+.RE
+.PP
+CYCLE
+.br
+NO CYCLE
+.RS 4
+The
+CYCLE
+option allows the sequence to wrap around when the
+\fImaxvalue\fR
+or
+\fIminvalue\fR
+has been reached by an ascending or descending sequence respectively\&. If the limit is reached, the next number generated will be the
+\fIminvalue\fR
+or
+\fImaxvalue\fR, respectively\&.
+.sp
+If
+NO CYCLE
+is specified, any calls to
+\fBnextval\fR
+after the sequence has reached its maximum value will return an error\&. If neither
+CYCLE
+or
+NO CYCLE
+are specified,
+NO CYCLE
+is the default\&.
+.RE
+.PP
+OWNED BY \fItable_name\fR\&.\fIcolumn_name\fR
+.br
+OWNED BY NONE
+.RS 4
+The
+OWNED BY
+option causes the sequence to be associated with a specific table column, such that if that column (or its whole table) is dropped, the sequence will be automatically dropped as well\&. The specified table must have the same owner and be in the same schema as the sequence\&.
+OWNED BY NONE, the default, specifies that there is no such association\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBDROP SEQUENCE\fR
+to remove a sequence\&.
+.PP
+Sequences are based on
+bigint
+arithmetic, so the range cannot exceed the range of an eight\-byte integer (\-9223372036854775808 to 9223372036854775807)\&.
+.PP
+Because
+\fBnextval\fR
+and
+\fBsetval\fR
+calls are never rolled back, sequence objects cannot be used if
+\(lqgapless\(rq
+assignment of sequence numbers is needed\&. It is possible to build gapless assignment by using exclusive locking of a table containing a counter; but this solution is much more expensive than sequence objects, especially if many transactions need sequence numbers concurrently\&.
+.PP
+Unexpected results might be obtained if a
+\fIcache\fR
+setting greater than one is used for a sequence object that will be used concurrently by multiple sessions\&. Each session will allocate and cache successive sequence values during one access to the sequence object and increase the sequence object\*(Aqs
+last_value
+accordingly\&. Then, the next
+\fIcache\fR\-1 uses of
+\fBnextval\fR
+within that session simply return the preallocated values without touching the sequence object\&. So, any numbers allocated but not used within a session will be lost when that session ends, resulting in
+\(lqholes\(rq
+in the sequence\&.
+.PP
+Furthermore, although multiple sessions are guaranteed to allocate distinct sequence values, the values might be generated out of sequence when all the sessions are considered\&. For example, with a
+\fIcache\fR
+setting of 10, session A might reserve values 1\&.\&.10 and return
+\fBnextval\fR=1, then session B might reserve values 11\&.\&.20 and return
+\fBnextval\fR=11 before session A has generated
+\fBnextval\fR=2\&. Thus, with a
+\fIcache\fR
+setting of one it is safe to assume that
+\fBnextval\fR
+values are generated sequentially; with a
+\fIcache\fR
+setting greater than one you should only assume that the
+\fBnextval\fR
+values are all distinct, not that they are generated purely sequentially\&. Also,
+last_value
+will reflect the latest value reserved by any session, whether or not it has yet been returned by
+\fBnextval\fR\&.
+.PP
+Another consideration is that a
+\fBsetval\fR
+executed on such a sequence will not be noticed by other sessions until they have used up any preallocated values they have cached\&.
+.SH "EXAMPLES"
+.PP
+Create an ascending sequence called
+serial, starting at 101:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SEQUENCE serial START 101;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Select the next number from this sequence:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT nextval(\*(Aqserial\*(Aq);
+
+ nextval
+\-\-\-\-\-\-\-\-\-
+ 101
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Select the next number from this sequence:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT nextval(\*(Aqserial\*(Aq);
+
+ nextval
+\-\-\-\-\-\-\-\-\-
+ 102
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Use this sequence in an
+\fBINSERT\fR
+command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO distributors VALUES (nextval(\*(Aqserial\*(Aq), \*(Aqnothing\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Update the sequence value after a
+\fBCOPY FROM\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+COPY distributors FROM \*(Aqinput_file\*(Aq;
+SELECT setval(\*(Aqserial\*(Aq, max(id)) FROM distributors;
+END;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE SEQUENCE\fR
+conforms to the
+SQL
+standard, with the following exceptions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Obtaining the next value is done using the
+\fBnextval()\fR
+function instead of the standard\*(Aqs
+\fBNEXT VALUE FOR\fR
+expression\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+OWNED BY
+clause is a
+PostgreSQL
+extension\&.
+.RE
+.SH "SEE ALSO"
+ALTER SEQUENCE (\fBALTER_SEQUENCE\fR(7)), DROP SEQUENCE (\fBDROP_SEQUENCE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_SERVER.7 b/doc/src/sgml/man7/CREATE_SERVER.7
new file mode 100644
index 0000000..d10e962
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_SERVER.7
@@ -0,0 +1,116 @@
+'\" t
+.\" Title: CREATE SERVER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE SERVER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_SERVER \- define a new foreign server
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE SERVER [ IF NOT EXISTS ] \fIserver_name\fR [ TYPE \*(Aq\fIserver_type\fR\*(Aq ] [ VERSION \*(Aq\fIserver_version\fR\*(Aq ]
+ FOREIGN DATA WRAPPER \fIfdw_name\fR
+ [ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE SERVER\fR
+defines a new foreign server\&. The user who defines the server becomes its owner\&.
+.PP
+A foreign server typically encapsulates connection information that a foreign\-data wrapper uses to access an external data resource\&. Additional user\-specific connection information may be specified by means of user mappings\&.
+.PP
+The server name must be unique within the database\&.
+.PP
+Creating a server requires
+USAGE
+privilege on the foreign\-data wrapper being used\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a server with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing server is anything like the one that would have been created\&.
+.RE
+.PP
+\fIserver_name\fR
+.RS 4
+The name of the foreign server to be created\&.
+.RE
+.PP
+\fIserver_type\fR
+.RS 4
+Optional server type, potentially useful to foreign\-data wrappers\&.
+.RE
+.PP
+\fIserver_version\fR
+.RS 4
+Optional server version, potentially useful to foreign\-data wrappers\&.
+.RE
+.PP
+\fIfdw_name\fR
+.RS 4
+The name of the foreign\-data wrapper that manages the server\&.
+.RE
+.PP
+OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] )
+.RS 4
+This clause specifies the options for the server\&. The options typically define the connection details of the server, but the actual names and values are dependent on the server\*(Aqs foreign\-data wrapper\&.
+.RE
+.SH "NOTES"
+.PP
+When using the
+dblink
+module, a foreign server\*(Aqs name can be used as an argument of the
+\fBdblink_connect\fR(3)
+function to indicate the connection parameters\&. It is necessary to have the
+USAGE
+privilege on the foreign server to be able to use it in this way\&.
+.SH "EXAMPLES"
+.PP
+Create a server
+myserver
+that uses the foreign\-data wrapper
+postgres_fdw:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host \*(Aqfoo\*(Aq, dbname \*(Aqfoodb\*(Aq, port \*(Aq5432\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+See
+postgres_fdw
+for more details\&.
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE SERVER\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&.
+.SH "SEE ALSO"
+ALTER SERVER (\fBALTER_SERVER\fR(7)), DROP SERVER (\fBDROP_SERVER\fR(7)), CREATE FOREIGN DATA WRAPPER (\fBCREATE_FOREIGN_DATA_WRAPPER\fR(7)), CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7)), CREATE USER MAPPING (\fBCREATE_USER_MAPPING\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_STATISTICS.7 b/doc/src/sgml/man7/CREATE_STATISTICS.7
new file mode 100644
index 0000000..bc14191
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_STATISTICS.7
@@ -0,0 +1,236 @@
+'\" t
+.\" Title: CREATE STATISTICS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE STATISTICS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_STATISTICS \- define extended statistics
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE STATISTICS [ IF NOT EXISTS ] \fIstatistics_name\fR
+ ON ( \fIexpression\fR )
+ FROM \fItable_name\fR
+
+CREATE STATISTICS [ IF NOT EXISTS ] \fIstatistics_name\fR
+ [ ( \fIstatistics_kind\fR [, \&.\&.\&. ] ) ]
+ ON { \fIcolumn_name\fR | ( \fIexpression\fR ) }, { \fIcolumn_name\fR | ( \fIexpression\fR ) } [, \&.\&.\&.]
+ FROM \fItable_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE STATISTICS\fR
+will create a new extended statistics object tracking data about the specified table, foreign table or materialized view\&. The statistics object will be created in the current database and will be owned by the user issuing the command\&.
+.PP
+The
+\fBCREATE STATISTICS\fR
+command has two basic forms\&. The first form allows univariate statistics for a single expression to be collected, providing benefits similar to an expression index without the overhead of index maintenance\&. This form does not allow the statistics kind to be specified, since the various statistics kinds refer only to multivariate statistics\&. The second form of the command allows multivariate statistics on multiple columns and/or expressions to be collected, optionally specifying which statistics kinds to include\&. This form will also automatically cause univariate statistics to be collected on any expressions included in the list\&.
+.PP
+If a schema name is given (for example,
+CREATE STATISTICS myschema\&.mystat \&.\&.\&.) then the statistics object is created in the specified schema\&. Otherwise it is created in the current schema\&. The name of the statistics object must be distinct from the name of any other statistics object in the same schema\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a statistics object with the same name already exists\&. A notice is issued in this case\&. Note that only the name of the statistics object is considered here, not the details of its definition\&.
+.RE
+.PP
+\fIstatistics_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the statistics object to be created\&.
+.RE
+.PP
+\fIstatistics_kind\fR
+.RS 4
+A multivariate statistics kind to be computed in this statistics object\&. Currently supported kinds are
+ndistinct, which enables n\-distinct statistics,
+dependencies, which enables functional dependency statistics, and
+mcv
+which enables most\-common values lists\&. If this clause is omitted, all supported statistics kinds are included in the statistics object\&. Univariate expression statistics are built automatically if the statistics definition includes any complex expressions rather than just simple column references\&. For more information, see
+Section\ \&14.2.2
+and
+Section\ \&75.2\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a table column to be covered by the computed statistics\&. This is only allowed when building multivariate statistics\&. At least two column names or expressions must be specified, and their order is not significant\&.
+.RE
+.PP
+\fIexpression\fR
+.RS 4
+An expression to be covered by the computed statistics\&. This may be used to build univariate statistics on a single expression, or as part of a list of multiple column names and/or expressions to build multivariate statistics\&. In the latter case, separate univariate statistics are built automatically for each expression in the list\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table containing the column(s) the statistics are computed on; see
+\fBANALYZE\fR(7)
+for an explanation of the handling of inheritance and partitions\&.
+.RE
+.SH "NOTES"
+.PP
+You must be the owner of a table to create a statistics object reading it\&. Once created, however, the ownership of the statistics object is independent of the underlying table(s)\&.
+.PP
+Expression statistics are per\-expression and are similar to creating an index on the expression, except that they avoid the overhead of index maintenance\&. Expression statistics are built automatically for each expression in the statistics object definition\&.
+.PP
+Extended statistics are not currently used by the planner for selectivity estimations made for table joins\&. This limitation will likely be removed in a future version of
+PostgreSQL\&.
+.SH "EXAMPLES"
+.PP
+Create table
+t1
+with two functionally dependent columns, i\&.e\&., knowledge of a value in the first column is sufficient for determining the value in the other column\&. Then functional dependency statistics are built on those columns:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE t1 (
+ a int,
+ b int
+);
+
+INSERT INTO t1 SELECT i/100, i/500
+ FROM generate_series(1,1000000) s(i);
+
+ANALYZE t1;
+
+\-\- the number of matching rows will be drastically underestimated:
+EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
+
+CREATE STATISTICS s1 (dependencies) ON a, b FROM t1;
+
+ANALYZE t1;
+
+\-\- now the row count estimate is more accurate:
+EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Without functional\-dependency statistics, the planner would assume that the two
+WHERE
+conditions are independent, and would multiply their selectivities together to arrive at a much\-too\-small row count estimate\&. With such statistics, the planner recognizes that the
+WHERE
+conditions are redundant and does not underestimate the row count\&.
+.PP
+Create table
+t2
+with two perfectly correlated columns (containing identical data), and an MCV list on those columns:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE t2 (
+ a int,
+ b int
+);
+
+INSERT INTO t2 SELECT mod(i,100), mod(i,100)
+ FROM generate_series(1,1000000) s(i);
+
+CREATE STATISTICS s2 (mcv) ON a, b FROM t2;
+
+ANALYZE t2;
+
+\-\- valid combination (found in MCV)
+EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1);
+
+\-\- invalid combination (not found in MCV)
+EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The MCV list gives the planner more detailed information about the specific values that commonly appear in the table, as well as an upper bound on the selectivities of combinations of values that do not appear in the table, allowing it to generate better estimates in both cases\&.
+.PP
+Create table
+t3
+with a single timestamp column, and run queries using expressions on that column\&. Without extended statistics, the planner has no information about the data distribution for the expressions, and uses default estimates\&. The planner also does not realize that the value of the date truncated to the month is fully determined by the value of the date truncated to the day\&. Then expression and ndistinct statistics are built on those two expressions:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE t3 (
+ a timestamp
+);
+
+INSERT INTO t3 SELECT i FROM generate_series(\*(Aq2020\-01\-01\*(Aq::timestamp,
+ \*(Aq2020\-12\-31\*(Aq::timestamp,
+ \*(Aq1 minute\*(Aq::interval) s(i);
+
+ANALYZE t3;
+
+\-\- the number of matching rows will be drastically underestimated:
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc(\*(Aqmonth\*(Aq, a) = \*(Aq2020\-01\-01\*(Aq::timestamp;
+
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc(\*(Aqday\*(Aq, a) BETWEEN \*(Aq2020\-01\-01\*(Aq::timestamp
+ AND \*(Aq2020\-06\-30\*(Aq::timestamp;
+
+EXPLAIN ANALYZE SELECT date_trunc(\*(Aqmonth\*(Aq, a), date_trunc(\*(Aqday\*(Aq, a)
+ FROM t3 GROUP BY 1, 2;
+
+\-\- build ndistinct statistics on the pair of expressions (per\-expression
+\-\- statistics are built automatically)
+CREATE STATISTICS s3 (ndistinct) ON date_trunc(\*(Aqmonth\*(Aq, a), date_trunc(\*(Aqday\*(Aq, a) FROM t3;
+
+ANALYZE t3;
+
+\-\- now the row count estimates are more accurate:
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc(\*(Aqmonth\*(Aq, a) = \*(Aq2020\-01\-01\*(Aq::timestamp;
+
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc(\*(Aqday\*(Aq, a) BETWEEN \*(Aq2020\-01\-01\*(Aq::timestamp
+ AND \*(Aq2020\-06\-30\*(Aq::timestamp;
+
+EXPLAIN ANALYZE SELECT date_trunc(\*(Aqmonth\*(Aq, a), date_trunc(\*(Aqday\*(Aq, a)
+ FROM t3 GROUP BY 1, 2;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Without expression and ndistinct statistics, the planner has no information about the number of distinct values for the expressions, and has to rely on default estimates\&. The equality and range conditions are assumed to have 0\&.5% selectivity, and the number of distinct values in the expression is assumed to be the same as for the column (i\&.e\&. unique)\&. This results in a significant underestimate of the row count in the first two queries\&. Moreover, the planner has no information about the relationship between the expressions, so it assumes the two
+WHERE
+and
+GROUP BY
+conditions are independent, and multiplies their selectivities together to arrive at a severe overestimate of the group count in the aggregate query\&. This is further exacerbated by the lack of accurate statistics for the expressions, forcing the planner to use a default ndistinct estimate for the expression derived from ndistinct for the column\&. With such statistics, the planner recognizes that the conditions are correlated, and arrives at much more accurate estimates\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE STATISTICS\fR
+command in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER STATISTICS (\fBALTER_STATISTICS\fR(7)), DROP STATISTICS (\fBDROP_STATISTICS\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_SUBSCRIPTION.7 b/doc/src/sgml/man7/CREATE_SUBSCRIPTION.7
new file mode 100644
index 0000000..66a4659
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_SUBSCRIPTION.7
@@ -0,0 +1,303 @@
+'\" t
+.\" Title: CREATE SUBSCRIPTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE SUBSCRIPTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_SUBSCRIPTION \- define a new subscription
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE SUBSCRIPTION \fIsubscription_name\fR
+ CONNECTION \*(Aq\fIconninfo\fR\*(Aq
+ PUBLICATION \fIpublication_name\fR [, \&.\&.\&.]
+ [ WITH ( \fIsubscription_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE SUBSCRIPTION\fR
+adds a new logical\-replication subscription\&. The subscription name must be distinct from the name of any existing subscription in the current database\&.
+.PP
+A subscription represents a replication connection to the publisher\&. Hence, in addition to adding definitions in the local catalogs, this command normally creates a replication slot on the publisher\&.
+.PP
+A logical replication worker will be started to replicate data for the new subscription at the commit of the transaction where this command is run, unless the subscription is initially disabled\&.
+.PP
+Additional information about subscriptions and logical replication as a whole is available at
+Section\ \&31.2
+and
+Chapter\ \&31\&.
+.SH "PARAMETERS"
+.PP
+\fIsubscription_name\fR
+.RS 4
+The name of the new subscription\&.
+.RE
+.PP
+CONNECTION \*(Aq\fIconninfo\fR\*(Aq
+.RS 4
+The
+libpq
+connection string defining how to connect to the publisher database\&. For details see
+Section\ \&34.1.1\&.
+.RE
+.PP
+PUBLICATION \fIpublication_name\fR [, \&.\&.\&.]
+.RS 4
+Names of the publications on the publisher to subscribe to\&.
+.RE
+.PP
+WITH ( \fIsubscription_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause specifies optional parameters for a subscription\&.
+.sp
+The following parameters control what happens during subscription creation:
+.PP
+connect (boolean)
+.RS 4
+Specifies whether the
+\fBCREATE SUBSCRIPTION\fR
+command should connect to the publisher at all\&. The default is
+true\&. Setting this to
+false
+will force the values of
+create_slot,
+enabled
+and
+copy_data
+to
+false\&. (You cannot combine setting
+connect
+to
+false
+with setting
+create_slot,
+enabled, or
+copy_data
+to
+true\&.)
+.sp
+Since no connection is made when this option is
+false, no tables are subscribed, and so after you enable the subscription nothing will be replicated\&. You will need to then run
+ALTER SUBSCRIPTION \&.\&.\&. REFRESH PUBLICATION
+for tables to be subscribed\&.
+.RE
+.PP
+create_slot (boolean)
+.RS 4
+Specifies whether the command should create the replication slot on the publisher\&. The default is
+true\&. If set to
+false, you are responsible for creating the publisher\*(Aqs slot in some other way\&.
+.RE
+.PP
+enabled (boolean)
+.RS 4
+Specifies whether the subscription should be actively replicating or whether it should just be set up but not started yet\&. The default is
+true\&.
+.RE
+.PP
+slot_name (string)
+.RS 4
+Name of the publisher\*(Aqs replication slot to use\&. The default is to use the name of the subscription for the slot name\&.
+.sp
+Setting
+slot_name
+to
+NONE
+means there will be no replication slot associated with the subscription\&. Use this when you will be creating the replication slot later manually\&. Such subscriptions must also have both
+enabled
+and
+create_slot
+set to
+false\&.
+.RE
+.sp
+The following parameters control the subscription\*(Aqs replication behavior after it has been created:
+.PP
+binary (boolean)
+.RS 4
+Specifies whether the subscription will request the publisher to send the data in binary format (as opposed to text)\&. The default is
+false\&. Even when this option is enabled, only data types having binary send and receive functions will be transferred in binary\&.
+.sp
+When doing cross\-version replication, it could be that the publisher has a binary send function for some data type, but the subscriber lacks a binary receive function for that type\&. In such a case, data transfer will fail, and the
+binary
+option cannot be used\&.
+.RE
+.PP
+copy_data (boolean)
+.RS 4
+Specifies whether to copy pre\-existing data in the publications that are being subscribed to when the replication starts\&. The default is
+true\&.
+.sp
+If the publications contain
+WHERE
+clauses, it will affect what data is copied\&. Refer to the
+Notes
+for details\&.
+.RE
+.PP
+streaming (boolean)
+.RS 4
+Specifies whether to enable streaming of in\-progress transactions for this subscription\&. By default, all transactions are fully decoded on the publisher and only then sent to the subscriber as a whole\&.
+.RE
+.PP
+synchronous_commit (enum)
+.RS 4
+The value of this parameter overrides the
+synchronous_commit
+setting within this subscription\*(Aqs apply worker processes\&. The default value is
+off\&.
+.sp
+It is safe to use
+off
+for logical replication: If the subscriber loses transactions because of missing synchronization, the data will be sent again from the publisher\&.
+.sp
+A different setting might be appropriate when doing synchronous logical replication\&. The logical replication workers report the positions of writes and flushes to the publisher, and when using synchronous replication, the publisher will wait for the actual flush\&. This means that setting
+synchronous_commit
+for the subscriber to
+off
+when the subscription is used for synchronous replication might increase the latency for
+\fBCOMMIT\fR
+on the publisher\&. In this scenario, it can be advantageous to set
+synchronous_commit
+to
+local
+or higher\&.
+.RE
+.PP
+two_phase (boolean)
+.RS 4
+Specifies whether two\-phase commit is enabled for this subscription\&. The default is
+false\&.
+.sp
+When two\-phase commit is enabled, prepared transactions are sent to the subscriber at the time of
+\fBPREPARE TRANSACTION\fR, and are processed as two\-phase transactions on the subscriber too\&. Otherwise, prepared transactions are sent to the subscriber only when committed, and are then processed immediately by the subscriber\&.
+.sp
+The implementation of two\-phase commit requires that replication has successfully finished the initial table synchronization phase\&. So even when
+two_phase
+is enabled for a subscription, the internal two\-phase state remains temporarily
+\(lqpending\(rq
+until the initialization phase completes\&. See column
+subtwophasestate
+of
+pg_subscription
+to know the actual two\-phase state\&.
+.RE
+.PP
+disable_on_error (boolean)
+.RS 4
+Specifies whether the subscription should be automatically disabled if any errors are detected by subscription workers during data replication from the publisher\&. The default is
+false\&.
+.RE
+.RE
+.SH "NOTES"
+.PP
+See
+Section\ \&31.9
+for details on how to configure access control between the subscription and the publication instance\&.
+.PP
+When creating a replication slot (the default behavior),
+\fBCREATE SUBSCRIPTION\fR
+cannot be executed inside a transaction block\&.
+.PP
+Creating a subscription that connects to the same database cluster (for example, to replicate between databases in the same cluster or to replicate within the same database) will only succeed if the replication slot is not created as part of the same command\&. Otherwise, the
+\fBCREATE SUBSCRIPTION\fR
+call will hang\&. To make this work, create the replication slot separately (using the function
+\fBpg_create_logical_replication_slot\fR
+with the plugin name
+pgoutput) and create the subscription using the parameter
+create_slot = false\&. This is an implementation restriction that might be lifted in a future release\&.
+.PP
+If any table in the publication has a
+WHERE
+clause, rows for which the
+\fIexpression\fR
+evaluates to false or null will not be published\&. If the subscription has several publications in which the same table has been published with different
+WHERE
+clauses, a row will be published if any of the expressions (referring to that publish operation) are satisfied\&. In the case of different
+WHERE
+clauses, if one of the publications has no
+WHERE
+clause (referring to that publish operation) or the publication is declared as
+FOR ALL TABLES
+or
+FOR TABLES IN SCHEMA, rows are always published regardless of the definition of the other expressions\&. If the subscriber is a
+PostgreSQL
+version before 15, then any row filtering is ignored during the initial data synchronization phase\&. For this case, the user might want to consider deleting any initially copied data that would be incompatible with subsequent filtering\&. Because initial data synchronization does not take into account the publication
+publish
+parameter when copying existing table data, some rows may be copied that would not be replicated using DML\&. See
+Section\ \&31.2.2
+for examples\&.
+.PP
+Subscriptions having several publications in which the same table has been published with different column lists are not supported\&.
+.PP
+We allow non\-existent publications to be specified so that users can add those later\&. This means
+pg_subscription
+can have non\-existent publications\&.
+.SH "EXAMPLES"
+.PP
+Create a subscription to a remote server that replicates tables in the publications
+mypublication
+and
+insert_only
+and starts replicating immediately on commit:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SUBSCRIPTION mysub
+ CONNECTION \*(Aqhost=192\&.168\&.1\&.50 port=5432 user=foo dbname=foodb\*(Aq
+ PUBLICATION mypublication, insert_only;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a subscription to a remote server that replicates tables in the
+insert_only
+publication and does not start replicating until enabled at a later time\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE SUBSCRIPTION mysub
+ CONNECTION \*(Aqhost=192\&.168\&.1\&.50 port=5432 user=foo dbname=foodb\*(Aq
+ PUBLICATION insert_only
+ WITH (enabled = false);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE SUBSCRIPTION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER SUBSCRIPTION (\fBALTER_SUBSCRIPTION\fR(7)), DROP SUBSCRIPTION (\fBDROP_SUBSCRIPTION\fR(7)), CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7)), ALTER PUBLICATION (\fBALTER_PUBLICATION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TABLE.7 b/doc/src/sgml/man7/CREATE_TABLE.7
new file mode 100644
index 0000000..efde8d4
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TABLE.7
@@ -0,0 +1,1779 @@
+'\" t
+.\" Title: CREATE TABLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TABLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TABLE \- define a new table
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] \fItable_name\fR ( [
+ { \fIcolumn_name\fR \fIdata_type\fR [ COMPRESSION \fIcompression_method\fR ] [ COLLATE \fIcollation\fR ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ | \fItable_constraint\fR
+ | LIKE \fIsource_table\fR [ \fIlike_option\fR \&.\&.\&. ] }
+ [, \&.\&.\&. ]
+] )
+[ INHERITS ( \fIparent_table\fR [, \&.\&.\&. ] ) ]
+[ PARTITION BY { RANGE | LIST | HASH } ( { \fIcolumn_name\fR | ( \fIexpression\fR ) } [ COLLATE \fIcollation\fR ] [ \fIopclass\fR ] [, \&.\&.\&. ] ) ]
+[ USING \fImethod\fR ]
+[ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE \fItablespace_name\fR ]
+
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] \fItable_name\fR
+ OF \fItype_name\fR [ (
+ { \fIcolumn_name\fR [ WITH OPTIONS ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ | \fItable_constraint\fR }
+ [, \&.\&.\&. ]
+) ]
+[ PARTITION BY { RANGE | LIST | HASH } ( { \fIcolumn_name\fR | ( \fIexpression\fR ) } [ COLLATE \fIcollation\fR ] [ \fIopclass\fR ] [, \&.\&.\&. ] ) ]
+[ USING \fImethod\fR ]
+[ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE \fItablespace_name\fR ]
+
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] \fItable_name\fR
+ PARTITION OF \fIparent_table\fR [ (
+ { \fIcolumn_name\fR [ WITH OPTIONS ] [ \fIcolumn_constraint\fR [ \&.\&.\&. ] ]
+ | \fItable_constraint\fR }
+ [, \&.\&.\&. ]
+) ] { FOR VALUES \fIpartition_bound_spec\fR | DEFAULT }
+[ PARTITION BY { RANGE | LIST | HASH } ( { \fIcolumn_name\fR | ( \fIexpression\fR ) } [ COLLATE \fIcollation\fR ] [ \fIopclass\fR ] [, \&.\&.\&. ] ) ]
+[ USING \fImethod\fR ]
+[ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE \fItablespace_name\fR ]
+
+where \fIcolumn_constraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+{ NOT NULL |
+ NULL |
+ CHECK ( \fIexpression\fR ) [ NO INHERIT ] |
+ DEFAULT \fIdefault_expr\fR |
+ GENERATED ALWAYS AS ( \fIgeneration_expr\fR ) STORED |
+ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( \fIsequence_options\fR ) ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] \fIindex_parameters\fR |
+ PRIMARY KEY \fIindex_parameters\fR |
+ REFERENCES \fIreftable\fR [ ( \fIrefcolumn\fR ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+ [ ON DELETE \fIreferential_action\fR ] [ ON UPDATE \fIreferential_action\fR ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+and \fItable_constraint\fR is:
+
+[ CONSTRAINT \fIconstraint_name\fR ]
+{ CHECK ( \fIexpression\fR ) [ NO INHERIT ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] ( \fIcolumn_name\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR |
+ PRIMARY KEY ( \fIcolumn_name\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR |
+ EXCLUDE [ USING \fIindex_method\fR ] ( \fIexclude_element\fR WITH \fIoperator\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR [ WHERE ( \fIpredicate\fR ) ] |
+ FOREIGN KEY ( \fIcolumn_name\fR [, \&.\&.\&. ] ) REFERENCES \fIreftable\fR [ ( \fIrefcolumn\fR [, \&.\&.\&. ] ) ]
+ [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE \fIreferential_action\fR ] [ ON UPDATE \fIreferential_action\fR ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+and \fIlike_option\fR is:
+
+{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+
+and \fIpartition_bound_spec\fR is:
+
+IN ( \fIpartition_bound_expr\fR [, \&.\&.\&.] ) |
+FROM ( { \fIpartition_bound_expr\fR | MINVALUE | MAXVALUE } [, \&.\&.\&.] )
+ TO ( { \fIpartition_bound_expr\fR | MINVALUE | MAXVALUE } [, \&.\&.\&.] ) |
+WITH ( MODULUS \fInumeric_literal\fR, REMAINDER \fInumeric_literal\fR )
+
+\fIindex_parameters\fR in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:
+
+[ INCLUDE ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ]
+[ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) ]
+[ USING INDEX TABLESPACE \fItablespace_name\fR ]
+
+\fIexclude_element\fR in an EXCLUDE constraint is:
+
+{ \fIcolumn_name\fR | ( \fIexpression\fR ) } [ \fIopclass\fR ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
+
+\fIreferential_action\fR in a FOREIGN KEY/REFERENCES constraint is:
+
+{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ] | SET DEFAULT [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ] }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TABLE\fR
+will create a new, initially empty table in the current database\&. The table will be owned by the user issuing the command\&.
+.PP
+If a schema name is given (for example,
+CREATE TABLE myschema\&.mytable \&.\&.\&.) then the table is created in the specified schema\&. Otherwise it is created in the current schema\&. Temporary tables exist in a special schema, so a schema name cannot be given when creating a temporary table\&. The name of the table must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in the same schema\&.
+.PP
+\fBCREATE TABLE\fR
+also automatically creates a data type that represents the composite type corresponding to one row of the table\&. Therefore, tables cannot have the same name as any existing data type in the same schema\&.
+.PP
+The optional constraint clauses specify constraints (tests) that new or updated rows must satisfy for an insert or update operation to succeed\&. A constraint is an SQL object that helps define the set of valid values in the table in various ways\&.
+.PP
+There are two ways to define constraints: table constraints and column constraints\&. A column constraint is defined as part of a column definition\&. A table constraint definition is not tied to a particular column, and it can encompass more than one column\&. Every column constraint can also be written as a table constraint; a column constraint is only a notational convenience for use when the constraint only affects one column\&.
+.PP
+To be able to create a table, you must have
+USAGE
+privilege on all column types or the type in the
+OF
+clause, respectively\&.
+.SH "PARAMETERS"
+.PP
+TEMPORARY or TEMP
+.RS 4
+If specified, the table is created as a temporary table\&. Temporary tables are automatically dropped at the end of a session, or optionally at the end of the current transaction (see
+ON COMMIT
+below)\&. The default search_path includes the temporary schema first and so identically named existing permanent tables are not chosen for new plans while the temporary table exists, unless they are referenced with schema\-qualified names\&. Any indexes created on a temporary table are automatically temporary as well\&.
+.sp
+The
+autovacuum daemon
+cannot access and therefore cannot vacuum or analyze temporary tables\&. For this reason, appropriate vacuum and analyze operations should be performed via session SQL commands\&. For example, if a temporary table is going to be used in complex queries, it is wise to run
+\fBANALYZE\fR
+on the temporary table after it is populated\&.
+.sp
+Optionally,
+GLOBAL
+or
+LOCAL
+can be written before
+TEMPORARY
+or
+TEMP\&. This presently makes no difference in
+PostgreSQL
+and is deprecated; see
+Compatibility
+below\&.
+.RE
+.PP
+UNLOGGED
+.RS 4
+If specified, the table is created as an unlogged table\&. Data written to unlogged tables is not written to the write\-ahead log (see
+Chapter\ \&30), which makes them considerably faster than ordinary tables\&. However, they are not crash\-safe: an unlogged table is automatically truncated after a crash or unclean shutdown\&. The contents of an unlogged table are also not replicated to standby servers\&. Any indexes created on an unlogged table are automatically unlogged as well\&.
+.sp
+If this is specified, any sequences created together with the unlogged table (for identity or serial columns) are also created as unlogged\&.
+.RE
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a relation with the same name already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing relation is anything like the one that would have been created\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to be created\&.
+.RE
+.PP
+OF \fItype_name\fR
+.RS 4
+Creates a
+typed table, which takes its structure from the specified composite type (name optionally schema\-qualified)\&. A typed table is tied to its type; for example the table will be dropped if the type is dropped (with
+DROP TYPE \&.\&.\&. CASCADE)\&.
+.sp
+When a typed table is created, then the data types of the columns are determined by the underlying composite type and are not specified by the
+CREATE TABLE
+command\&. But the
+CREATE TABLE
+command can add defaults and constraints to the table and can specify storage parameters\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column to be created in the new table\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The data type of the column\&. This can include array specifiers\&. For more information on the data types supported by
+PostgreSQL, refer to
+Chapter\ \&8\&.
+.RE
+.PP
+COLLATE \fIcollation\fR
+.RS 4
+The
+COLLATE
+clause assigns a collation to the column (which must be of a collatable data type)\&. If not specified, the column data type\*(Aqs default collation is used\&.
+.RE
+.PP
+COMPRESSION \fIcompression_method\fR
+.RS 4
+The
+COMPRESSION
+clause sets the compression method for the column\&. Compression is supported only for variable\-width data types, and is used only when the column\*(Aqs storage mode is
+main
+or
+extended\&. (See
+ALTER TABLE (\fBALTER_TABLE\fR(7))
+for information on column storage modes\&.) Setting this property for a partitioned table has no direct effect, because such tables have no storage of their own, but the configured value will be inherited by newly\-created partitions\&. The supported compression methods are
+pglz
+and
+lz4\&. (lz4
+is available only if
+\fB\-\-with\-lz4\fR
+was used when building
+PostgreSQL\&.) In addition,
+\fIcompression_method\fR
+can be
+default
+to explicitly specify the default behavior, which is to consult the
+default_toast_compression
+setting at the time of data insertion to determine the method to use\&.
+.RE
+.PP
+INHERITS ( \fIparent_table\fR [, \&.\&.\&. ] )
+.RS 4
+The optional
+INHERITS
+clause specifies a list of tables from which the new table automatically inherits all columns\&. Parent tables can be plain tables or foreign tables\&.
+.sp
+Use of
+INHERITS
+creates a persistent relationship between the new child table and its parent table(s)\&. Schema modifications to the parent(s) normally propagate to children as well, and by default the data of the child table is included in scans of the parent(s)\&.
+.sp
+If the same column name exists in more than one parent table, an error is reported unless the data types of the columns match in each of the parent tables\&. If there is no conflict, then the duplicate columns are merged to form a single column in the new table\&. If the column name list of the new table contains a column name that is also inherited, the data type must likewise match the inherited column(s), and the column definitions are merged into one\&. If the new table explicitly specifies a default value for the column, this default overrides any defaults from inherited declarations of the column\&. Otherwise, any parents that specify default values for the column must all specify the same default, or an error will be reported\&.
+.sp
+CHECK
+constraints are merged in essentially the same way as columns: if multiple parent tables and/or the new table definition contain identically\-named
+CHECK
+constraints, these constraints must all have the same check expression, or an error will be reported\&. Constraints having the same name and expression will be merged into one copy\&. A constraint marked
+NO INHERIT
+in a parent will not be considered\&. Notice that an unnamed
+CHECK
+constraint in the new table will never be merged, since a unique name will always be chosen for it\&.
+.sp
+Column
+STORAGE
+settings are also copied from parent tables\&.
+.sp
+If a column in the parent table is an identity column, that property is not inherited\&. A column in the child table can be declared identity column if desired\&.
+.RE
+.PP
+PARTITION BY { RANGE | LIST | HASH } ( { \fIcolumn_name\fR | ( \fIexpression\fR ) } [ \fIopclass\fR ] [, \&.\&.\&.] )
+.RS 4
+The optional
+PARTITION BY
+clause specifies a strategy of partitioning the table\&. The table thus created is called a
+partitioned
+table\&. The parenthesized list of columns or expressions forms the
+partition key
+for the table\&. When using range or hash partitioning, the partition key can include multiple columns or expressions (up to 32, but this limit can be altered when building
+PostgreSQL), but for list partitioning, the partition key must consist of a single column or expression\&.
+.sp
+Range and list partitioning require a btree operator class, while hash partitioning requires a hash operator class\&. If no operator class is specified explicitly, the default operator class of the appropriate type will be used; if no default operator class exists, an error will be raised\&. When hash partitioning is used, the operator class used must implement support function 2 (see
+Section\ \&38.16.3
+for details)\&.
+.sp
+A partitioned table is divided into sub\-tables (called partitions), which are created using separate
+CREATE TABLE
+commands\&. The partitioned table is itself empty\&. A data row inserted into the table is routed to a partition based on the value of columns or expressions in the partition key\&. If no existing partition matches the values in the new row, an error will be reported\&.
+.sp
+Partitioned tables do not support
+EXCLUDE
+constraints; however, you can define these constraints on individual partitions\&.
+.sp
+See
+Section\ \&5.11
+for more discussion on table partitioning\&.
+.RE
+.PP
+PARTITION OF \fIparent_table\fR { FOR VALUES \fIpartition_bound_spec\fR | DEFAULT }
+.RS 4
+Creates the table as a
+partition
+of the specified parent table\&. The table can be created either as a partition for specific values using
+FOR VALUES
+or as a default partition using
+DEFAULT\&. Any indexes, constraints and user\-defined row\-level triggers that exist in the parent table are cloned on the new partition\&.
+.sp
+The
+\fIpartition_bound_spec\fR
+must correspond to the partitioning method and partition key of the parent table, and must not overlap with any existing partition of that parent\&. The form with
+IN
+is used for list partitioning, the form with
+FROM
+and
+TO
+is used for range partitioning, and the form with
+WITH
+is used for hash partitioning\&.
+.sp
+\fIpartition_bound_expr\fR
+is any variable\-free expression (subqueries, window functions, aggregate functions, and set\-returning functions are not allowed)\&. Its data type must match the data type of the corresponding partition key column\&. The expression is evaluated once at table creation time, so it can even contain volatile expressions such as
+\fBCURRENT_TIMESTAMP\fR\&.
+.sp
+When creating a list partition,
+NULL
+can be specified to signify that the partition allows the partition key column to be null\&. However, there cannot be more than one such list partition for a given parent table\&.
+NULL
+cannot be specified for range partitions\&.
+.sp
+When creating a range partition, the lower bound specified with
+FROM
+is an inclusive bound, whereas the upper bound specified with
+TO
+is an exclusive bound\&. That is, the values specified in the
+FROM
+list are valid values of the corresponding partition key columns for this partition, whereas those in the
+TO
+list are not\&. Note that this statement must be understood according to the rules of row\-wise comparison (Section\ \&9.24.5)\&. For example, given
+PARTITION BY RANGE (x,y), a partition bound
+FROM (1, 2) TO (3, 4)
+allows
+x=1
+with any
+y>=2,
+x=2
+with any non\-null
+y, and
+x=3
+with any
+y<4\&.
+.sp
+The special values
+MINVALUE
+and
+MAXVALUE
+may be used when creating a range partition to indicate that there is no lower or upper bound on the column\*(Aqs value\&. For example, a partition defined using
+FROM (MINVALUE) TO (10)
+allows any values less than 10, and a partition defined using
+FROM (10) TO (MAXVALUE)
+allows any values greater than or equal to 10\&.
+.sp
+When creating a range partition involving more than one column, it can also make sense to use
+MAXVALUE
+as part of the lower bound, and
+MINVALUE
+as part of the upper bound\&. For example, a partition defined using
+FROM (0, MAXVALUE) TO (10, MAXVALUE)
+allows any rows where the first partition key column is greater than 0 and less than or equal to 10\&. Similarly, a partition defined using
+FROM (\*(Aqa\*(Aq, MINVALUE) TO (\*(Aqb\*(Aq, MINVALUE)
+allows any rows where the first partition key column starts with "a"\&.
+.sp
+Note that if
+MINVALUE
+or
+MAXVALUE
+is used for one column of a partitioning bound, the same value must be used for all subsequent columns\&. For example,
+(10, MINVALUE, 0)
+is not a valid bound; you should write
+(10, MINVALUE, MINVALUE)\&.
+.sp
+Also note that some element types, such as
+timestamp, have a notion of "infinity", which is just another value that can be stored\&. This is different from
+MINVALUE
+and
+MAXVALUE, which are not real values that can be stored, but rather they are ways of saying that the value is unbounded\&.
+MAXVALUE
+can be thought of as being greater than any other value, including "infinity" and
+MINVALUE
+as being less than any other value, including "minus infinity"\&. Thus the range
+FROM (\*(Aqinfinity\*(Aq) TO (MAXVALUE)
+is not an empty range; it allows precisely one value to be stored \(em "infinity"\&.
+.sp
+If
+DEFAULT
+is specified, the table will be created as the default partition of the parent table\&. This option is not available for hash\-partitioned tables\&. A partition key value not fitting into any other partition of the given parent will be routed to the default partition\&.
+.sp
+When a table has an existing
+DEFAULT
+partition and a new partition is added to it, the default partition must be scanned to verify that it does not contain any rows which properly belong in the new partition\&. If the default partition contains a large number of rows, this may be slow\&. The scan will be skipped if the default partition is a foreign table or if it has a constraint which proves that it cannot contain rows which should be placed in the new partition\&.
+.sp
+When creating a hash partition, a modulus and remainder must be specified\&. The modulus must be a positive integer, and the remainder must be a non\-negative integer less than the modulus\&. Typically, when initially setting up a hash\-partitioned table, you should choose a modulus equal to the number of partitions and assign every table the same modulus and a different remainder (see examples, below)\&. However, it is not required that every partition have the same modulus, only that every modulus which occurs among the partitions of a hash\-partitioned table is a factor of the next larger modulus\&. This allows the number of partitions to be increased incrementally without needing to move all the data at once\&. For example, suppose you have a hash\-partitioned table with 8 partitions, each of which has modulus 8, but find it necessary to increase the number of partitions to 16\&. You can detach one of the modulus\-8 partitions, create two new modulus\-16 partitions covering the same portion of the key space (one with a remainder equal to the remainder of the detached partition, and the other with a remainder equal to that value plus 8), and repopulate them with data\&. You can then repeat this \-\- perhaps at a later time \-\- for each modulus\-8 partition until none remain\&. While this may still involve a large amount of data movement at each step, it is still better than having to create a whole new table and move all the data at once\&.
+.sp
+A partition must have the same column names and types as the partitioned table to which it belongs\&. Modifications to the column names or types of a partitioned table will automatically propagate to all partitions\&.
+CHECK
+constraints will be inherited automatically by every partition, but an individual partition may specify additional
+CHECK
+constraints; additional constraints with the same name and condition as in the parent will be merged with the parent constraint\&. Defaults may be specified separately for each partition\&. But note that a partition\*(Aqs default value is not applied when inserting a tuple through a partitioned table\&.
+.sp
+Rows inserted into a partitioned table will be automatically routed to the correct partition\&. If no suitable partition exists, an error will occur\&.
+.sp
+Operations such as
+\fBTRUNCATE\fR
+which normally affect a table and all of its inheritance children will cascade to all partitions, but may also be performed on an individual partition\&.
+.sp
+Note that creating a partition using
+PARTITION OF
+requires taking an
+ACCESS EXCLUSIVE
+lock on the parent partitioned table\&. Likewise, dropping a partition with
+\fBDROP TABLE\fR
+requires taking an
+ACCESS EXCLUSIVE
+lock on the parent table\&. It is possible to use
+\fBALTER TABLE ATTACH/DETACH PARTITION\fR
+to perform these operations with a weaker lock, thus reducing interference with concurrent operations on the partitioned table\&.
+.RE
+.PP
+LIKE \fIsource_table\fR [ \fIlike_option\fR \&.\&.\&. ]
+.RS 4
+The
+LIKE
+clause specifies a table from which the new table automatically copies all column names, their data types, and their not\-null constraints\&.
+.sp
+Unlike
+INHERITS, the new table and original table are completely decoupled after creation is complete\&. Changes to the original table will not be applied to the new table, and it is not possible to include data of the new table in scans of the original table\&.
+.sp
+Also unlike
+INHERITS, columns and constraints copied by
+LIKE
+are not merged with similarly named columns and constraints\&. If the same name is specified explicitly or in another
+LIKE
+clause, an error is signaled\&.
+.sp
+The optional
+\fIlike_option\fR
+clauses specify which additional properties of the original table to copy\&. Specifying
+INCLUDING
+copies the property, specifying
+EXCLUDING
+omits the property\&.
+EXCLUDING
+is the default\&. If multiple specifications are made for the same kind of object, the last one is used\&. The available options are:
+.PP
+INCLUDING COMMENTS
+.RS 4
+Comments for the copied columns, constraints, and indexes will be copied\&. The default behavior is to exclude comments, resulting in the copied columns and constraints in the new table having no comments\&.
+.RE
+.PP
+INCLUDING COMPRESSION
+.RS 4
+Compression method of the columns will be copied\&. The default behavior is to exclude compression methods, resulting in columns having the default compression method\&.
+.RE
+.PP
+INCLUDING CONSTRAINTS
+.RS 4
+CHECK
+constraints will be copied\&. No distinction is made between column constraints and table constraints\&. Not\-null constraints are always copied to the new table\&.
+.RE
+.PP
+INCLUDING DEFAULTS
+.RS 4
+Default expressions for the copied column definitions will be copied\&. Otherwise, default expressions are not copied, resulting in the copied columns in the new table having null defaults\&. Note that copying defaults that call database\-modification functions, such as
+\fBnextval\fR, may create a functional linkage between the original and new tables\&.
+.RE
+.PP
+INCLUDING GENERATED
+.RS 4
+Any generation expressions of copied column definitions will be copied\&. By default, new columns will be regular base columns\&.
+.RE
+.PP
+INCLUDING IDENTITY
+.RS 4
+Any identity specifications of copied column definitions will be copied\&. A new sequence is created for each identity column of the new table, separate from the sequences associated with the old table\&.
+.RE
+.PP
+INCLUDING INDEXES
+.RS 4
+Indexes,
+PRIMARY KEY,
+UNIQUE, and
+EXCLUDE
+constraints on the original table will be created on the new table\&. Names for the new indexes and constraints are chosen according to the default rules, regardless of how the originals were named\&. (This behavior avoids possible duplicate\-name failures for the new indexes\&.)
+.RE
+.PP
+INCLUDING STATISTICS
+.RS 4
+Extended statistics are copied to the new table\&.
+.RE
+.PP
+INCLUDING STORAGE
+.RS 4
+STORAGE
+settings for the copied column definitions will be copied\&. The default behavior is to exclude
+STORAGE
+settings, resulting in the copied columns in the new table having type\-specific default settings\&. For more on
+STORAGE
+settings, see
+Section\ \&73.2\&.
+.RE
+.PP
+INCLUDING ALL
+.RS 4
+INCLUDING ALL
+is an abbreviated form selecting all the available individual options\&. (It could be useful to write individual
+EXCLUDING
+clauses after
+INCLUDING ALL
+to select all but some specific options\&.)
+.RE
+.sp
+The
+LIKE
+clause can also be used to copy column definitions from views, foreign tables, or composite types\&. Inapplicable options (e\&.g\&.,
+INCLUDING INDEXES
+from a view) are ignored\&.
+.RE
+.PP
+CONSTRAINT \fIconstraint_name\fR
+.RS 4
+An optional name for a column or table constraint\&. If the constraint is violated, the constraint name is present in error messages, so constraint names like
+col must be positive
+can be used to communicate helpful constraint information to client applications\&. (Double\-quotes are needed to specify constraint names that contain spaces\&.) If a constraint name is not specified, the system generates a name\&.
+.RE
+.PP
+NOT NULL
+.RS 4
+The column is not allowed to contain null values\&.
+.RE
+.PP
+NULL
+.RS 4
+The column is allowed to contain null values\&. This is the default\&.
+.sp
+This clause is only provided for compatibility with non\-standard SQL databases\&. Its use is discouraged in new applications\&.
+.RE
+.PP
+CHECK ( \fIexpression\fR ) [ NO INHERIT ]
+.RS 4
+The
+CHECK
+clause specifies an expression producing a Boolean result which new or updated rows must satisfy for an insert or update operation to succeed\&. Expressions evaluating to TRUE or UNKNOWN succeed\&. Should any row of an insert or update operation produce a FALSE result, an error exception is raised and the insert or update does not alter the database\&. A check constraint specified as a column constraint should reference that column\*(Aqs value only, while an expression appearing in a table constraint can reference multiple columns\&.
+.sp
+Currently,
+CHECK
+expressions cannot contain subqueries nor refer to variables other than columns of the current row (see
+Section\ \&5.4.1)\&. The system column
+tableoid
+may be referenced, but not any other system column\&.
+.sp
+A constraint marked with
+NO INHERIT
+will not propagate to child tables\&.
+.sp
+When a table has multiple
+CHECK
+constraints, they will be tested for each row in alphabetical order by name, after checking
+NOT NULL
+constraints\&. (PostgreSQL
+versions before 9\&.5 did not honor any particular firing order for
+CHECK
+constraints\&.)
+.RE
+.PP
+DEFAULT \fIdefault_expr\fR
+.RS 4
+The
+DEFAULT
+clause assigns a default data value for the column whose column definition it appears within\&. The value is any variable\-free expression (in particular, cross\-references to other columns in the current table are not allowed)\&. Subqueries are not allowed either\&. The data type of the default expression must match the data type of the column\&.
+.sp
+The default expression will be used in any insert operation that does not specify a value for the column\&. If there is no default for a column, then the default is null\&.
+.RE
+.PP
+GENERATED ALWAYS AS ( \fIgeneration_expr\fR ) STORED
+.RS 4
+This clause creates the column as a
+generated column\&. The column cannot be written to, and when read the result of the specified expression will be returned\&.
+.sp
+The keyword
+STORED
+is required to signify that the column will be computed on write and will be stored on disk\&.
+.sp
+The generation expression can refer to other columns in the table, but not other generated columns\&. Any functions and operators used must be immutable\&. References to other tables are not allowed\&.
+.RE
+.PP
+GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( \fIsequence_options\fR ) ]
+.RS 4
+This clause creates the column as an
+identity column\&. It will have an implicit sequence attached to it and the column in new rows will automatically have values from the sequence assigned to it\&. Such a column is implicitly
+NOT NULL\&.
+.sp
+The clauses
+ALWAYS
+and
+BY DEFAULT
+determine how explicitly user\-specified values are handled in
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+commands\&.
+.sp
+In an
+\fBINSERT\fR
+command, if
+ALWAYS
+is selected, a user\-specified value is only accepted if the
+\fBINSERT\fR
+statement specifies
+OVERRIDING SYSTEM VALUE\&. If
+BY DEFAULT
+is selected, then the user\-specified value takes precedence\&. See
+\fBINSERT\fR(7)
+for details\&. (In the
+\fBCOPY\fR
+command, user\-specified values are always used regardless of this setting\&.)
+.sp
+In an
+\fBUPDATE\fR
+command, if
+ALWAYS
+is selected, any update of the column to any value other than
+DEFAULT
+will be rejected\&. If
+BY DEFAULT
+is selected, the column can be updated normally\&. (There is no
+OVERRIDING
+clause for the
+\fBUPDATE\fR
+command\&.)
+.sp
+The optional
+\fIsequence_options\fR
+clause can be used to override the options of the sequence\&. See
+CREATE SEQUENCE (\fBCREATE_SEQUENCE\fR(7))
+for details\&.
+.RE
+.PP
+UNIQUE [ NULLS [ NOT ] DISTINCT ] (column constraint)
+.br
+UNIQUE [ NULLS [ NOT ] DISTINCT ] ( \fIcolumn_name\fR [, \&.\&.\&. ] ) [ INCLUDE ( \fIcolumn_name\fR [, \&.\&.\&.]) ] (table constraint)
+.RS 4
+The
+UNIQUE
+constraint specifies that a group of one or more columns of a table can contain only unique values\&. The behavior of a unique table constraint is the same as that of a unique column constraint, with the additional capability to span multiple columns\&. The constraint therefore enforces that any two rows must differ in at least one of these columns\&.
+.sp
+For the purpose of a unique constraint, null values are not considered equal, unless
+NULLS NOT DISTINCT
+is specified\&.
+.sp
+Each unique constraint should name a set of columns that is different from the set of columns named by any other unique or primary key constraint defined for the table\&. (Otherwise, redundant unique constraints will be discarded\&.)
+.sp
+When establishing a unique constraint for a multi\-level partition hierarchy, all the columns in the partition key of the target partitioned table, as well as those of all its descendant partitioned tables, must be included in the constraint definition\&.
+.sp
+Adding a unique constraint will automatically create a unique btree index on the column or group of columns used in the constraint\&.
+.sp
+The optional
+INCLUDE
+clause adds to that index one or more columns that are simply
+\(lqpayload\(rq: uniqueness is not enforced on them, and the index cannot be searched on the basis of those columns\&. However they can be retrieved by an index\-only scan\&. Note that although the constraint is not enforced on included columns, it still depends on them\&. Consequently, some operations on such columns (e\&.g\&.,
+DROP COLUMN) can cause cascaded constraint and index deletion\&.
+.RE
+.PP
+PRIMARY KEY (column constraint)
+.br
+PRIMARY KEY ( \fIcolumn_name\fR [, \&.\&.\&. ] ) [ INCLUDE ( \fIcolumn_name\fR [, \&.\&.\&.]) ] (table constraint)
+.RS 4
+The
+PRIMARY KEY
+constraint specifies that a column or columns of a table can contain only unique (non\-duplicate), nonnull values\&. Only one primary key can be specified for a table, whether as a column constraint or a table constraint\&.
+.sp
+The primary key constraint should name a set of columns that is different from the set of columns named by any unique constraint defined for the same table\&. (Otherwise, the unique constraint is redundant and will be discarded\&.)
+.sp
+PRIMARY KEY
+enforces the same data constraints as a combination of
+UNIQUE
+and
+NOT NULL\&. However, identifying a set of columns as the primary key also provides metadata about the design of the schema, since a primary key implies that other tables can rely on this set of columns as a unique identifier for rows\&.
+.sp
+When placed on a partitioned table,
+PRIMARY KEY
+constraints share the restrictions previously described for
+UNIQUE
+constraints\&.
+.sp
+Adding a
+PRIMARY KEY
+constraint will automatically create a unique btree index on the column or group of columns used in the constraint\&.
+.sp
+The optional
+INCLUDE
+clause adds to that index one or more columns that are simply
+\(lqpayload\(rq: uniqueness is not enforced on them, and the index cannot be searched on the basis of those columns\&. However they can be retrieved by an index\-only scan\&. Note that although the constraint is not enforced on included columns, it still depends on them\&. Consequently, some operations on such columns (e\&.g\&.,
+DROP COLUMN) can cause cascaded constraint and index deletion\&.
+.RE
+.PP
+EXCLUDE [ USING \fIindex_method\fR ] ( \fIexclude_element\fR WITH \fIoperator\fR [, \&.\&.\&. ] ) \fIindex_parameters\fR [ WHERE ( \fIpredicate\fR ) ]
+.RS 4
+The
+EXCLUDE
+clause defines an exclusion constraint, which guarantees that if any two rows are compared on the specified column(s) or expression(s) using the specified operator(s), not all of these comparisons will return
+TRUE\&. If all of the specified operators test for equality, this is equivalent to a
+UNIQUE
+constraint, although an ordinary unique constraint will be faster\&. However, exclusion constraints can specify constraints that are more general than simple equality\&. For example, you can specify a constraint that no two rows in the table contain overlapping circles (see
+Section\ \&8.8) by using the
+&&
+operator\&.
+.sp
+Exclusion constraints are implemented using an index, so each specified operator must be associated with an appropriate operator class (see
+Section\ \&11.10) for the index access method
+\fIindex_method\fR\&. The operators are required to be commutative\&. Each
+\fIexclude_element\fR
+can optionally specify an operator class and/or ordering options; these are described fully under
+CREATE INDEX (\fBCREATE_INDEX\fR(7))\&.
+.sp
+The access method must support
+amgettuple
+(see
+Chapter\ \&64); at present this means
+GIN
+cannot be used\&. Although it\*(Aqs allowed, there is little point in using B\-tree or hash indexes with an exclusion constraint, because this does nothing that an ordinary unique constraint doesn\*(Aqt do better\&. So in practice the access method will always be
+GiST
+or
+SP\-GiST\&.
+.sp
+The
+\fIpredicate\fR
+allows you to specify an exclusion constraint on a subset of the table; internally this creates a partial index\&. Note that parentheses are required around the predicate\&.
+.RE
+.PP
+REFERENCES \fIreftable\fR [ ( \fIrefcolumn\fR ) ] [ MATCH \fImatchtype\fR ] [ ON DELETE \fIreferential_action\fR ] [ ON UPDATE \fIreferential_action\fR ] (column constraint)
+.br
+FOREIGN KEY ( \fIcolumn_name\fR [, \&.\&.\&. ] ) REFERENCES \fIreftable\fR [ ( \fIrefcolumn\fR [, \&.\&.\&. ] ) ] [ MATCH \fImatchtype\fR ] [ ON DELETE \fIreferential_action\fR ] [ ON UPDATE \fIreferential_action\fR ] (table constraint)
+.RS 4
+These clauses specify a foreign key constraint, which requires that a group of one or more columns of the new table must only contain values that match values in the referenced column(s) of some row of the referenced table\&. If the
+\fIrefcolumn\fR
+list is omitted, the primary key of the
+\fIreftable\fR
+is used\&. The referenced columns must be the columns of a non\-deferrable unique or primary key constraint in the referenced table\&. The user must have
+REFERENCES
+permission on the referenced table (either the whole table, or the specific referenced columns)\&. The addition of a foreign key constraint requires a
+SHARE ROW EXCLUSIVE
+lock on the referenced table\&. Note that foreign key constraints cannot be defined between temporary tables and permanent tables\&.
+.sp
+A value inserted into the referencing column(s) is matched against the values of the referenced table and referenced columns using the given match type\&. There are three match types:
+MATCH FULL,
+MATCH PARTIAL, and
+MATCH SIMPLE
+(which is the default)\&.
+MATCH FULL
+will not allow one column of a multicolumn foreign key to be null unless all foreign key columns are null; if they are all null, the row is not required to have a match in the referenced table\&.
+MATCH SIMPLE
+allows any of the foreign key columns to be null; if any of them are null, the row is not required to have a match in the referenced table\&.
+MATCH PARTIAL
+is not yet implemented\&. (Of course,
+NOT NULL
+constraints can be applied to the referencing column(s) to prevent these cases from arising\&.)
+.sp
+In addition, when the data in the referenced columns is changed, certain actions are performed on the data in this table\*(Aqs columns\&. The
+ON DELETE
+clause specifies the action to perform when a referenced row in the referenced table is being deleted\&. Likewise, the
+ON UPDATE
+clause specifies the action to perform when a referenced column in the referenced table is being updated to a new value\&. If the row is updated, but the referenced column is not actually changed, no action is done\&. Referential actions other than the
+NO ACTION
+check cannot be deferred, even if the constraint is declared deferrable\&. There are the following possible actions for each clause:
+.PP
+NO ACTION
+.RS 4
+Produce an error indicating that the deletion or update would create a foreign key constraint violation\&. If the constraint is deferred, this error will be produced at constraint check time if there still exist any referencing rows\&. This is the default action\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Produce an error indicating that the deletion or update would create a foreign key constraint violation\&. This is the same as
+NO ACTION
+except that the check is not deferrable\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Delete any rows referencing the deleted row, or update the values of the referencing column(s) to the new values of the referenced columns, respectively\&.
+.RE
+.PP
+SET NULL [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ]
+.RS 4
+Set all of the referencing columns, or a specified subset of the referencing columns, to null\&. A subset of columns can only be specified for
+ON DELETE
+actions\&.
+.RE
+.PP
+SET DEFAULT [ ( \fIcolumn_name\fR [, \&.\&.\&. ] ) ]
+.RS 4
+Set all of the referencing columns, or a specified subset of the referencing columns, to their default values\&. A subset of columns can only be specified for
+ON DELETE
+actions\&. (There must be a row in the referenced table matching the default values, if they are not null, or the operation will fail\&.)
+.RE
+.sp
+If the referenced column(s) are changed frequently, it might be wise to add an index to the referencing column(s) so that referential actions associated with the foreign key constraint can be performed more efficiently\&.
+.RE
+.PP
+DEFERRABLE
+.br
+NOT DEFERRABLE
+.RS 4
+This controls whether the constraint can be deferred\&. A constraint that is not deferrable will be checked immediately after every command\&. Checking of constraints that are deferrable can be postponed until the end of the transaction (using the
+\fBSET CONSTRAINTS\fR
+command)\&.
+NOT DEFERRABLE
+is the default\&. Currently, only
+UNIQUE,
+PRIMARY KEY,
+EXCLUDE, and
+REFERENCES
+(foreign key) constraints accept this clause\&.
+NOT NULL
+and
+CHECK
+constraints are not deferrable\&. Note that deferrable constraints cannot be used as conflict arbitrators in an
+\fBINSERT\fR
+statement that includes an
+ON CONFLICT DO UPDATE
+clause\&.
+.RE
+.PP
+INITIALLY IMMEDIATE
+.br
+INITIALLY DEFERRED
+.RS 4
+If a constraint is deferrable, this clause specifies the default time to check the constraint\&. If the constraint is
+INITIALLY IMMEDIATE, it is checked after each statement\&. This is the default\&. If the constraint is
+INITIALLY DEFERRED, it is checked only at the end of the transaction\&. The constraint check time can be altered with the
+\fBSET CONSTRAINTS\fR
+command\&.
+.RE
+.PP
+USING \fImethod\fR
+.RS 4
+This optional clause specifies the table access method to use to store the contents for the new table; the method needs be an access method of type
+TABLE\&. See
+Chapter\ \&63
+for more information\&. If this option is not specified, the default table access method is chosen for the new table\&. See
+default_table_access_method
+for more information\&.
+.RE
+.PP
+WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause specifies optional storage parameters for a table or index; see
+Storage Parameters
+below for more information\&. For backward\-compatibility the
+WITH
+clause for a table can also include
+OIDS=FALSE
+to specify that rows of the new table should not contain OIDs (object identifiers),
+OIDS=TRUE
+is not supported anymore\&.
+.RE
+.PP
+WITHOUT OIDS
+.RS 4
+This is backward\-compatible syntax for declaring a table
+WITHOUT OIDS, creating a table
+WITH OIDS
+is not supported anymore\&.
+.RE
+.PP
+ON COMMIT
+.RS 4
+The behavior of temporary tables at the end of a transaction block can be controlled using
+ON COMMIT\&. The three options are:
+.PP
+PRESERVE ROWS
+.RS 4
+No special action is taken at the ends of transactions\&. This is the default behavior\&.
+.RE
+.PP
+DELETE ROWS
+.RS 4
+All rows in the temporary table will be deleted at the end of each transaction block\&. Essentially, an automatic
+\fBTRUNCATE\fR
+is done at each commit\&. When used on a partitioned table, this is not cascaded to its partitions\&.
+.RE
+.PP
+DROP
+.RS 4
+The temporary table will be dropped at the end of the current transaction block\&. When used on a partitioned table, this action drops its partitions and when used on tables with inheritance children, it drops the dependent children\&.
+.RE
+.RE
+.PP
+TABLESPACE \fItablespace_name\fR
+.RS 4
+The
+\fItablespace_name\fR
+is the name of the tablespace in which the new table is to be created\&. If not specified,
+default_tablespace
+is consulted, or
+temp_tablespaces
+if the table is temporary\&. For partitioned tables, since no storage is required for the table itself, the tablespace specified overrides
+default_tablespace
+as the default tablespace to use for any newly created partitions when no other tablespace is explicitly specified\&.
+.RE
+.PP
+USING INDEX TABLESPACE \fItablespace_name\fR
+.RS 4
+This clause allows selection of the tablespace in which the index associated with a
+UNIQUE,
+PRIMARY KEY, or
+EXCLUDE
+constraint will be created\&. If not specified,
+default_tablespace
+is consulted, or
+temp_tablespaces
+if the table is temporary\&.
+.RE
+.SS "Storage Parameters"
+.PP
+The
+WITH
+clause can specify
+storage parameters
+for tables, and for indexes associated with a
+UNIQUE,
+PRIMARY KEY, or
+EXCLUDE
+constraint\&. Storage parameters for indexes are documented in
+CREATE INDEX (\fBCREATE_INDEX\fR(7))\&. The storage parameters currently available for tables are listed below\&. For many of these parameters, as shown, there is an additional parameter with the same name prefixed with
+toast\&., which controls the behavior of the table\*(Aqs secondary
+TOAST
+table, if any (see
+Section\ \&73.2
+for more information about TOAST)\&. If a table parameter value is set and the equivalent
+toast\&.
+parameter is not, the TOAST table will use the table\*(Aqs parameter value\&. Specifying these parameters for partitioned tables is not supported, but you may specify them for individual leaf partitions\&.
+.PP
+\fIfillfactor\fR (integer)
+.RS 4
+The fillfactor for a table is a percentage between 10 and 100\&. 100 (complete packing) is the default\&. When a smaller fillfactor is specified,
+\fBINSERT\fR
+operations pack table pages only to the indicated percentage; the remaining space on each page is reserved for updating rows on that page\&. This gives
+\fBUPDATE\fR
+a chance to place the updated copy of a row on the same page as the original, which is more efficient than placing it on a different page, and makes
+heap\-only tuple updates
+more likely\&. For a table whose entries are never updated, complete packing is the best choice, but in heavily updated tables smaller fillfactors are appropriate\&. This parameter cannot be set for TOAST tables\&.
+.RE
+.PP
+toast_tuple_target (integer)
+.RS 4
+The toast_tuple_target specifies the minimum tuple length required before we try to compress and/or move long column values into TOAST tables, and is also the target length we try to reduce the length below once toasting begins\&. This affects columns marked as External (for move), Main (for compression), or Extended (for both) and applies only to new tuples\&. There is no effect on existing rows\&. By default this parameter is set to allow at least 4 tuples per block, which with the default block size will be 2040 bytes\&. Valid values are between 128 bytes and the (block size \- header), by default 8160 bytes\&. Changing this value may not be useful for very short or very long rows\&. Note that the default setting is often close to optimal, and it is possible that setting this parameter could have negative effects in some cases\&. This parameter cannot be set for TOAST tables\&.
+.RE
+.PP
+parallel_workers (integer)
+.RS 4
+This sets the number of workers that should be used to assist a parallel scan of this table\&. If not set, the system will determine a value based on the relation size\&. The actual number of workers chosen by the planner or by utility statements that use parallel scans may be less, for example due to the setting of
+max_worker_processes\&.
+.RE
+.PP
+autovacuum_enabled, toast\&.autovacuum_enabled (boolean)
+.RS 4
+Enables or disables the autovacuum daemon for a particular table\&. If true, the autovacuum daemon will perform automatic
+\fBVACUUM\fR
+and/or
+\fBANALYZE\fR
+operations on this table following the rules discussed in
+Section\ \&25.1.6\&. If false, this table will not be autovacuumed, except to prevent transaction ID wraparound\&. See
+Section\ \&25.1.5
+for more about wraparound prevention\&. Note that the autovacuum daemon does not run at all (except to prevent transaction ID wraparound) if the
+autovacuum
+parameter is false; setting individual tables\*(Aq storage parameters does not override that\&. Therefore there is seldom much point in explicitly setting this storage parameter to
+true, only to
+false\&.
+.RE
+.PP
+vacuum_index_cleanup, toast\&.vacuum_index_cleanup (enum)
+.RS 4
+Forces or disables index cleanup when
+\fBVACUUM\fR
+is run on this table\&. The default value is
+AUTO\&. With
+OFF, index cleanup is disabled, with
+ON
+it is enabled, and with
+AUTO
+a decision is made dynamically, each time
+\fBVACUUM\fR
+runs\&. The dynamic behavior allows
+\fBVACUUM\fR
+to avoid needlessly scanning indexes to remove very few dead tuples\&. Forcibly disabling all index cleanup can speed up
+\fBVACUUM\fR
+very significantly, but may also lead to severely bloated indexes if table modifications are frequent\&. The
+INDEX_CLEANUP
+parameter of
+\fBVACUUM\fR, if specified, overrides the value of this option\&.
+.RE
+.PP
+vacuum_truncate, toast\&.vacuum_truncate (boolean)
+.RS 4
+Enables or disables vacuum to try to truncate off any empty pages at the end of this table\&. The default value is
+true\&. If
+true,
+\fBVACUUM\fR
+and autovacuum do the truncation and the disk space for the truncated pages is returned to the operating system\&. Note that the truncation requires
+ACCESS EXCLUSIVE
+lock on the table\&. The
+TRUNCATE
+parameter of
+\fBVACUUM\fR, if specified, overrides the value of this option\&.
+.RE
+.PP
+autovacuum_vacuum_threshold, toast\&.autovacuum_vacuum_threshold (integer)
+.RS 4
+Per\-table value for
+autovacuum_vacuum_threshold
+parameter\&.
+.RE
+.PP
+autovacuum_vacuum_scale_factor, toast\&.autovacuum_vacuum_scale_factor (floating point)
+.RS 4
+Per\-table value for
+autovacuum_vacuum_scale_factor
+parameter\&.
+.RE
+.PP
+autovacuum_vacuum_insert_threshold, toast\&.autovacuum_vacuum_insert_threshold (integer)
+.RS 4
+Per\-table value for
+autovacuum_vacuum_insert_threshold
+parameter\&. The special value of \-1 may be used to disable insert vacuums on the table\&.
+.RE
+.PP
+autovacuum_vacuum_insert_scale_factor, toast\&.autovacuum_vacuum_insert_scale_factor (floating point)
+.RS 4
+Per\-table value for
+autovacuum_vacuum_insert_scale_factor
+parameter\&.
+.RE
+.PP
+autovacuum_analyze_threshold (integer)
+.RS 4
+Per\-table value for
+autovacuum_analyze_threshold
+parameter\&.
+.RE
+.PP
+autovacuum_analyze_scale_factor (floating point)
+.RS 4
+Per\-table value for
+autovacuum_analyze_scale_factor
+parameter\&.
+.RE
+.PP
+autovacuum_vacuum_cost_delay, toast\&.autovacuum_vacuum_cost_delay (floating point)
+.RS 4
+Per\-table value for
+autovacuum_vacuum_cost_delay
+parameter\&.
+.RE
+.PP
+autovacuum_vacuum_cost_limit, toast\&.autovacuum_vacuum_cost_limit (integer)
+.RS 4
+Per\-table value for
+autovacuum_vacuum_cost_limit
+parameter\&.
+.RE
+.PP
+autovacuum_freeze_min_age, toast\&.autovacuum_freeze_min_age (integer)
+.RS 4
+Per\-table value for
+vacuum_freeze_min_age
+parameter\&. Note that autovacuum will ignore per\-table
+autovacuum_freeze_min_age
+parameters that are larger than half the system\-wide
+autovacuum_freeze_max_age
+setting\&.
+.RE
+.PP
+autovacuum_freeze_max_age, toast\&.autovacuum_freeze_max_age (integer)
+.RS 4
+Per\-table value for
+autovacuum_freeze_max_age
+parameter\&. Note that autovacuum will ignore per\-table
+autovacuum_freeze_max_age
+parameters that are larger than the system\-wide setting (it can only be set smaller)\&.
+.RE
+.PP
+autovacuum_freeze_table_age, toast\&.autovacuum_freeze_table_age (integer)
+.RS 4
+Per\-table value for
+vacuum_freeze_table_age
+parameter\&.
+.RE
+.PP
+autovacuum_multixact_freeze_min_age, toast\&.autovacuum_multixact_freeze_min_age (integer)
+.RS 4
+Per\-table value for
+vacuum_multixact_freeze_min_age
+parameter\&. Note that autovacuum will ignore per\-table
+autovacuum_multixact_freeze_min_age
+parameters that are larger than half the system\-wide
+autovacuum_multixact_freeze_max_age
+setting\&.
+.RE
+.PP
+autovacuum_multixact_freeze_max_age, toast\&.autovacuum_multixact_freeze_max_age (integer)
+.RS 4
+Per\-table value for
+autovacuum_multixact_freeze_max_age
+parameter\&. Note that autovacuum will ignore per\-table
+autovacuum_multixact_freeze_max_age
+parameters that are larger than the system\-wide setting (it can only be set smaller)\&.
+.RE
+.PP
+autovacuum_multixact_freeze_table_age, toast\&.autovacuum_multixact_freeze_table_age (integer)
+.RS 4
+Per\-table value for
+vacuum_multixact_freeze_table_age
+parameter\&.
+.RE
+.PP
+log_autovacuum_min_duration, toast\&.log_autovacuum_min_duration (integer)
+.RS 4
+Per\-table value for
+log_autovacuum_min_duration
+parameter\&.
+.RE
+.PP
+user_catalog_table (boolean)
+.RS 4
+Declare the table as an additional catalog table for purposes of logical replication\&. See
+Section\ \&49.6.2
+for details\&. This parameter cannot be set for TOAST tables\&.
+.RE
+.SH "NOTES"
+.PP
+PostgreSQL
+automatically creates an index for each unique constraint and primary key constraint to enforce uniqueness\&. Thus, it is not necessary to create an index explicitly for primary key columns\&. (See
+CREATE INDEX (\fBCREATE_INDEX\fR(7))
+for more information\&.)
+.PP
+Unique constraints and primary keys are not inherited in the current implementation\&. This makes the combination of inheritance and unique constraints rather dysfunctional\&.
+.PP
+A table cannot have more than 1600 columns\&. (In practice, the effective limit is usually lower because of tuple\-length constraints\&.)
+.SH "EXAMPLES"
+.PP
+Create table
+films
+and table
+distributors:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE films (
+ code char(5) CONSTRAINT firstkey PRIMARY KEY,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
+ name varchar(40) NOT NULL CHECK (name <> \*(Aq\*(Aq)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a table with a 2\-dimensional array:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE array_int (
+ vector int[][]
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define a unique table constraint for the table
+films\&. Unique table constraints can be defined on one or more columns of the table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT production UNIQUE(date_prod)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define a check column constraint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer CHECK (did > 100),
+ name varchar(40)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define a check table constraint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ CONSTRAINT con1 CHECK (did > 100 AND name <> \*(Aq\*(Aq)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define a primary key table constraint for the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT code_title PRIMARY KEY(code,title)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define a primary key constraint for table
+distributors\&. The following two examples are equivalent, the first using the table constraint syntax, the second the column constraint syntax:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ PRIMARY KEY(did)
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY,
+ name varchar(40)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Assign a literal constant default value for the column
+name, arrange for the default value of column
+did
+to be generated by selecting the next value of a sequence object, and make the default value of
+modtime
+be the time at which the row is inserted:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ name varchar(40) DEFAULT \*(AqLuso Films\*(Aq,
+ did integer DEFAULT nextval(\*(Aqdistributors_serial\*(Aq),
+ modtime timestamp DEFAULT current_timestamp
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define two
+NOT NULL
+column constraints on the table
+distributors, one of which is explicitly given a name:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer CONSTRAINT no_null NOT NULL,
+ name varchar(40) NOT NULL
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Define a unique constraint for the
+name
+column:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40) UNIQUE
+);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The same, specified as a table constraint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create the same table, specifying 70% fill factor for both the table and its unique index:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name) WITH (fillfactor=70)
+)
+WITH (fillfactor=70);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create table
+circles
+with an exclusion constraint that prevents any two circles from overlapping:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE circles (
+ c circle,
+ EXCLUDE USING gist (c WITH &&)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create table
+cinemas
+in tablespace
+diskvol1:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE cinemas (
+ id serial,
+ name text,
+ location text
+) TABLESPACE diskvol1;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a composite type and a typed table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE employee_type AS (name text, salary numeric);
+
+CREATE TABLE employees OF employee_type (
+ PRIMARY KEY (name),
+ salary WITH OPTIONS DEFAULT 1000
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a range partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE measurement (
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (logdate);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a range partitioned table with multiple columns in the partition key:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE measurement_year_month (
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a list partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE cities (
+ city_id bigserial not null,
+ name text not null,
+ population bigint
+) PARTITION BY LIST (left(lower(name), 1));
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a hash partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE orders (
+ order_id bigint not null,
+ cust_id bigint not null,
+ status text
+) PARTITION BY HASH (order_id);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create partition of a range partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE measurement_y2016m07
+ PARTITION OF measurement (
+ unitsales DEFAULT 0
+) FOR VALUES FROM (\*(Aq2016\-07\-01\*(Aq) TO (\*(Aq2016\-08\-01\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a few partitions of a range partitioned table with multiple columns in the partition key:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE measurement_ym_older
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);
+
+CREATE TABLE measurement_ym_y2016m11
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2016, 11) TO (2016, 12);
+
+CREATE TABLE measurement_ym_y2016m12
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2016, 12) TO (2017, 01);
+
+CREATE TABLE measurement_ym_y2017m01
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2017, 01) TO (2017, 02);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create partition of a list partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE cities_ab
+ PARTITION OF cities (
+ CONSTRAINT city_id_nonzero CHECK (city_id != 0)
+) FOR VALUES IN (\*(Aqa\*(Aq, \*(Aqb\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create partition of a list partitioned table that is itself further partitioned and then add a partition to it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE cities_ab
+ PARTITION OF cities (
+ CONSTRAINT city_id_nonzero CHECK (city_id != 0)
+) FOR VALUES IN (\*(Aqa\*(Aq, \*(Aqb\*(Aq) PARTITION BY RANGE (population);
+
+CREATE TABLE cities_ab_10000_to_100000
+ PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create partitions of a hash partitioned table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE orders_p1 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 0);
+CREATE TABLE orders_p2 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 1);
+CREATE TABLE orders_p3 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 2);
+CREATE TABLE orders_p4 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 3);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a default partition:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE cities_partdef
+ PARTITION OF cities DEFAULT;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCREATE TABLE\fR
+command conforms to the
+SQL
+standard, with exceptions listed below\&.
+.SS "Temporary Tables"
+.PP
+Although the syntax of
+CREATE TEMPORARY TABLE
+resembles that of the SQL standard, the effect is not the same\&. In the standard, temporary tables are defined just once and automatically exist (starting with empty contents) in every session that needs them\&.
+PostgreSQL
+instead requires each session to issue its own
+CREATE TEMPORARY TABLE
+command for each temporary table to be used\&. This allows different sessions to use the same temporary table name for different purposes, whereas the standard\*(Aqs approach constrains all instances of a given temporary table name to have the same table structure\&.
+.PP
+The standard\*(Aqs definition of the behavior of temporary tables is widely ignored\&.
+PostgreSQL\*(Aqs behavior on this point is similar to that of several other SQL databases\&.
+.PP
+The SQL standard also distinguishes between global and local temporary tables, where a local temporary table has a separate set of contents for each SQL module within each session, though its definition is still shared across sessions\&. Since
+PostgreSQL
+does not support SQL modules, this distinction is not relevant in
+PostgreSQL\&.
+.PP
+For compatibility\*(Aqs sake,
+PostgreSQL
+will accept the
+GLOBAL
+and
+LOCAL
+keywords in a temporary table declaration, but they currently have no effect\&. Use of these keywords is discouraged, since future versions of
+PostgreSQL
+might adopt a more standard\-compliant interpretation of their meaning\&.
+.PP
+The
+ON COMMIT
+clause for temporary tables also resembles the SQL standard, but has some differences\&. If the
+ON COMMIT
+clause is omitted, SQL specifies that the default behavior is
+ON COMMIT DELETE ROWS\&. However, the default behavior in
+PostgreSQL
+is
+ON COMMIT PRESERVE ROWS\&. The
+ON COMMIT DROP
+option does not exist in SQL\&.
+.SS "Non\-Deferred Uniqueness Constraints"
+.PP
+When a
+UNIQUE
+or
+PRIMARY KEY
+constraint is not deferrable,
+PostgreSQL
+checks for uniqueness immediately whenever a row is inserted or modified\&. The SQL standard says that uniqueness should be enforced only at the end of the statement; this makes a difference when, for example, a single command updates multiple key values\&. To obtain standard\-compliant behavior, declare the constraint as
+DEFERRABLE
+but not deferred (i\&.e\&.,
+INITIALLY IMMEDIATE)\&. Be aware that this can be significantly slower than immediate uniqueness checking\&.
+.SS "Column Check Constraints"
+.PP
+The SQL standard says that
+CHECK
+column constraints can only refer to the column they apply to; only
+CHECK
+table constraints can refer to multiple columns\&.
+PostgreSQL
+does not enforce this restriction; it treats column and table check constraints alike\&.
+.SS "EXCLUDE Constraint"
+.PP
+The
+EXCLUDE
+constraint type is a
+PostgreSQL
+extension\&.
+.SS "Foreign\-Key Constraint Actions"
+.PP
+The ability to specify column lists in the foreign\-key actions
+SET DEFAULT
+and
+SET NULL
+is a
+PostgreSQL
+extension\&.
+.SS "NULL \(lqConstraint\(rq"
+.PP
+The
+NULL
+\(lqconstraint\(rq
+(actually a non\-constraint) is a
+PostgreSQL
+extension to the SQL standard that is included for compatibility with some other database systems (and for symmetry with the
+NOT NULL
+constraint)\&. Since it is the default for any column, its presence is simply noise\&.
+.SS "Constraint Naming"
+.PP
+The SQL standard says that table and domain constraints must have names that are unique across the schema containing the table or domain\&.
+PostgreSQL
+is laxer: it only requires constraint names to be unique across the constraints attached to a particular table or domain\&. However, this extra freedom does not exist for index\-based constraints (UNIQUE,
+PRIMARY KEY, and
+EXCLUDE
+constraints), because the associated index is named the same as the constraint, and index names must be unique across all relations within the same schema\&.
+.PP
+Currently,
+PostgreSQL
+does not record names for
+NOT NULL
+constraints at all, so they are not subject to the uniqueness restriction\&. This might change in a future release\&.
+.SS "Inheritance"
+.PP
+Multiple inheritance via the
+INHERITS
+clause is a
+PostgreSQL
+language extension\&. SQL:1999 and later define single inheritance using a different syntax and different semantics\&. SQL:1999\-style inheritance is not yet supported by
+PostgreSQL\&.
+.SS "Zero\-Column Tables"
+.PP
+PostgreSQL
+allows a table of no columns to be created (for example,
+CREATE TABLE foo();)\&. This is an extension from the SQL standard, which does not allow zero\-column tables\&. Zero\-column tables are not in themselves very useful, but disallowing them creates odd special cases for
+\fBALTER TABLE DROP COLUMN\fR, so it seems cleaner to ignore this spec restriction\&.
+.SS "Multiple Identity Columns"
+.PP
+PostgreSQL
+allows a table to have more than one identity column\&. The standard specifies that a table can have at most one identity column\&. This is relaxed mainly to give more flexibility for doing schema changes or migrations\&. Note that the
+\fBINSERT\fR
+command supports only one override clause that applies to the entire statement, so having multiple identity columns with different behaviors is not well supported\&.
+.SS "Generated Columns"
+.PP
+The option
+STORED
+is not standard but is also used by other SQL implementations\&. The SQL standard does not specify the storage of generated columns\&.
+.SS "LIKE Clause"
+.PP
+While a
+LIKE
+clause exists in the SQL standard, many of the options that
+PostgreSQL
+accepts for it are not in the standard, and some of the standard\*(Aqs options are not implemented by
+PostgreSQL\&.
+.SS "WITH Clause"
+.PP
+The
+WITH
+clause is a
+PostgreSQL
+extension; storage parameters are not in the standard\&.
+.SS "Tablespaces"
+.PP
+The
+PostgreSQL
+concept of tablespaces is not part of the standard\&. Hence, the clauses
+TABLESPACE
+and
+USING INDEX TABLESPACE
+are extensions\&.
+.SS "Typed Tables"
+.PP
+Typed tables implement a subset of the SQL standard\&. According to the standard, a typed table has columns corresponding to the underlying composite type as well as one other column that is the
+\(lqself\-referencing column\(rq\&.
+PostgreSQL
+does not support self\-referencing columns explicitly\&.
+.SS "PARTITION BY Clause"
+.PP
+The
+PARTITION BY
+clause is a
+PostgreSQL
+extension\&.
+.SS "PARTITION OF Clause"
+.PP
+The
+PARTITION OF
+clause is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER TABLE (\fBALTER_TABLE\fR(7)), DROP TABLE (\fBDROP_TABLE\fR(7)), CREATE TABLE AS (\fBCREATE_TABLE_AS\fR(7)), CREATE TABLESPACE (\fBCREATE_TABLESPACE\fR(7)), CREATE TYPE (\fBCREATE_TYPE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TABLESPACE.7 b/doc/src/sgml/man7/CREATE_TABLESPACE.7
new file mode 100644
index 0000000..8d283a7
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TABLESPACE.7
@@ -0,0 +1,162 @@
+'\" t
+.\" Title: CREATE TABLESPACE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TABLESPACE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TABLESPACE \- define a new tablespace
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE TABLESPACE \fItablespace_name\fR
+ [ OWNER { \fInew_owner\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ]
+ LOCATION \*(Aq\fIdirectory\fR\*(Aq
+ [ WITH ( \fItablespace_option\fR = \fIvalue\fR [, \&.\&.\&. ] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TABLESPACE\fR
+registers a new cluster\-wide tablespace\&. The tablespace name must be distinct from the name of any existing tablespace in the database cluster\&.
+.PP
+A tablespace allows superusers to define an alternative location on the file system where the data files containing database objects (such as tables and indexes) can reside\&.
+.PP
+A user with appropriate privileges can pass
+\fItablespace_name\fR
+to
+\fBCREATE DATABASE\fR,
+\fBCREATE TABLE\fR,
+\fBCREATE INDEX\fR
+or
+\fBADD CONSTRAINT\fR
+to have the data files for these objects stored within the specified tablespace\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBWarning\fR
+.ps -1
+.br
+.PP
+A tablespace cannot be used independently of the cluster in which it is defined; see
+Section\ \&23.6\&.
+.sp .5v
+.RE
+.SH "PARAMETERS"
+.PP
+\fItablespace_name\fR
+.RS 4
+The name of a tablespace to be created\&. The name cannot begin with
+pg_, as such names are reserved for system tablespaces\&.
+.RE
+.PP
+\fIuser_name\fR
+.RS 4
+The name of the user who will own the tablespace\&. If omitted, defaults to the user executing the command\&. Only superusers can create tablespaces, but they can assign ownership of tablespaces to non\-superusers\&.
+.RE
+.PP
+\fIdirectory\fR
+.RS 4
+The directory that will be used for the tablespace\&. The directory must exist (\fBCREATE TABLESPACE\fR
+will not create it), should be empty, and must be owned by the
+PostgreSQL
+system user\&. The directory must be specified by an absolute path name\&.
+.RE
+.PP
+\fItablespace_option\fR
+.RS 4
+A tablespace parameter to be set or reset\&. Currently, the only available parameters are
+\fIseq_page_cost\fR,
+\fIrandom_page_cost\fR,
+\fIeffective_io_concurrency\fR
+and
+\fImaintenance_io_concurrency\fR\&. Setting these values for a particular tablespace will override the planner\*(Aqs usual estimate of the cost of reading pages from tables in that tablespace, and the executor\*(Aqs prefetching behavior, as established by the configuration parameters of the same name (see
+seq_page_cost,
+random_page_cost,
+effective_io_concurrency,
+maintenance_io_concurrency)\&. This may be useful if one tablespace is located on a disk which is faster or slower than the remainder of the I/O subsystem\&.
+.RE
+.SH "NOTES"
+.PP
+Tablespaces are only supported on systems that support symbolic links\&.
+.PP
+\fBCREATE TABLESPACE\fR
+cannot be executed inside a transaction block\&.
+.SH "EXAMPLES"
+.PP
+To create a tablespace
+dbspace
+at file system location
+/data/dbs, first create the directory using operating system facilities and set the correct ownership:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+mkdir /data/dbs
+chown postgres:postgres /data/dbs
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Then issue the tablespace creation command inside
+PostgreSQL:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLESPACE dbspace LOCATION \*(Aq/data/dbs\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To create a tablespace owned by a different database user, use a command like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLESPACE indexspace OWNER genevieve LOCATION \*(Aq/data/indexes\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE TABLESPACE\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE DATABASE (\fBCREATE_DATABASE\fR(7)), CREATE TABLE (\fBCREATE_TABLE\fR(7)), CREATE INDEX (\fBCREATE_INDEX\fR(7)), DROP TABLESPACE (\fBDROP_TABLESPACE\fR(7)), ALTER TABLESPACE (\fBALTER_TABLESPACE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TABLE_AS.7 b/doc/src/sgml/man7/CREATE_TABLE_AS.7
new file mode 100644
index 0000000..a6d6025
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TABLE_AS.7
@@ -0,0 +1,320 @@
+'\" t
+.\" Title: CREATE TABLE AS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TABLE AS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TABLE_AS \- define a new table from the results of a query
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] \fItable_name\fR
+ [ (\fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ [ USING \fImethod\fR ]
+ [ WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] ) | WITHOUT OIDS ]
+ [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+ [ TABLESPACE \fItablespace_name\fR ]
+ AS \fIquery\fR
+ [ WITH [ NO ] DATA ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TABLE AS\fR
+creates a table and fills it with data computed by a
+\fBSELECT\fR
+command\&. The table columns have the names and data types associated with the output columns of the
+\fBSELECT\fR
+(except that you can override the column names by giving an explicit list of new column names)\&.
+.PP
+\fBCREATE TABLE AS\fR
+bears some resemblance to creating a view, but it is really quite different: it creates a new table and evaluates the query just once to fill the new table initially\&. The new table will not track subsequent changes to the source tables of the query\&. In contrast, a view re\-evaluates its defining
+\fBSELECT\fR
+statement whenever it is queried\&.
+.PP
+\fBCREATE TABLE AS\fR
+requires
+CREATE
+privilege on the schema used for the table\&.
+.SH "PARAMETERS"
+.PP
+GLOBAL or LOCAL
+.RS 4
+Ignored for compatibility\&. Use of these keywords is deprecated; refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for details\&.
+.RE
+.PP
+TEMPORARY or TEMP
+.RS 4
+If specified, the table is created as a temporary table\&. Refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for details\&.
+.RE
+.PP
+UNLOGGED
+.RS 4
+If specified, the table is created as an unlogged table\&. Refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for details\&.
+.RE
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a relation with the same name already exists; simply issue a notice and leave the table unmodified\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to be created\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column in the new table\&. If column names are not provided, they are taken from the output column names of the query\&.
+.RE
+.PP
+USING \fImethod\fR
+.RS 4
+This optional clause specifies the table access method to use to store the contents for the new table; the method needs be an access method of type
+TABLE\&. See
+Chapter\ \&63
+for more information\&. If this option is not specified, the default table access method is chosen for the new table\&. See
+default_table_access_method
+for more information\&.
+.RE
+.PP
+WITH ( \fIstorage_parameter\fR [= \fIvalue\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause specifies optional storage parameters for the new table; see
+Storage Parameters
+in the
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+documentation for more information\&. For backward\-compatibility the
+WITH
+clause for a table can also include
+OIDS=FALSE
+to specify that rows of the new table should contain no OIDs (object identifiers),
+OIDS=TRUE
+is not supported anymore\&.
+.RE
+.PP
+WITHOUT OIDS
+.RS 4
+This is backward\-compatible syntax for declaring a table
+WITHOUT OIDS, creating a table
+WITH OIDS
+is not supported anymore\&.
+.RE
+.PP
+ON COMMIT
+.RS 4
+The behavior of temporary tables at the end of a transaction block can be controlled using
+ON COMMIT\&. The three options are:
+.PP
+PRESERVE ROWS
+.RS 4
+No special action is taken at the ends of transactions\&. This is the default behavior\&.
+.RE
+.PP
+DELETE ROWS
+.RS 4
+All rows in the temporary table will be deleted at the end of each transaction block\&. Essentially, an automatic
+\fBTRUNCATE\fR
+is done at each commit\&.
+.RE
+.PP
+DROP
+.RS 4
+The temporary table will be dropped at the end of the current transaction block\&.
+.RE
+.RE
+.PP
+TABLESPACE \fItablespace_name\fR
+.RS 4
+The
+\fItablespace_name\fR
+is the name of the tablespace in which the new table is to be created\&. If not specified,
+default_tablespace
+is consulted, or
+temp_tablespaces
+if the table is temporary\&.
+.RE
+.PP
+\fIquery\fR
+.RS 4
+A
+\fBSELECT\fR,
+\fBTABLE\fR, or
+\fBVALUES\fR
+command, or an
+\fBEXECUTE\fR
+command that runs a prepared
+\fBSELECT\fR,
+\fBTABLE\fR, or
+\fBVALUES\fR
+query\&.
+.RE
+.PP
+WITH [ NO ] DATA
+.RS 4
+This clause specifies whether or not the data produced by the query should be copied into the new table\&. If not, only the table structure is copied\&. The default is to copy the data\&.
+.RE
+.SH "NOTES"
+.PP
+This command is functionally similar to
+SELECT INTO (\fBSELECT_INTO\fR(7)), but it is preferred since it is less likely to be confused with other uses of the
+\fBSELECT INTO\fR
+syntax\&. Furthermore,
+\fBCREATE TABLE AS\fR
+offers a superset of the functionality offered by
+\fBSELECT INTO\fR\&.
+.SH "EXAMPLES"
+.PP
+Create a new table
+films_recent
+consisting of only recent entries from the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE films_recent AS
+ SELECT * FROM films WHERE date_prod >= \*(Aq2002\-01\-01\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To copy a table completely, the short form using the
+TABLE
+command can also be used:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TABLE films2 AS
+ TABLE films;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a new temporary table
+films_recent, consisting of only recent entries from the table
+films, using a prepared statement\&. The new table will be dropped at commit:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+PREPARE recentfilms(date) AS
+ SELECT * FROM films WHERE date_prod > $1;
+CREATE TEMP TABLE films_recent ON COMMIT DROP AS
+ EXECUTE recentfilms(\*(Aq2002\-01\-01\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE TABLE AS\fR
+conforms to the
+SQL
+standard\&. The following are nonstandard extensions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The standard requires parentheses around the subquery clause; in
+PostgreSQL, these parentheses are optional\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+In the standard, the
+WITH [ NO ] DATA
+clause is required; in PostgreSQL it is optional\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+PostgreSQL
+handles temporary tables in a way rather different from the standard; see
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for details\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+WITH
+clause is a
+PostgreSQL
+extension; storage parameters are not in the standard\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+PostgreSQL
+concept of tablespaces is not part of the standard\&. Hence, the clause
+TABLESPACE
+is an extension\&.
+.RE
+.SH "SEE ALSO"
+CREATE MATERIALIZED VIEW (\fBCREATE_MATERIALIZED_VIEW\fR(7)), CREATE TABLE (\fBCREATE_TABLE\fR(7)), \fBEXECUTE\fR(7), \fBSELECT\fR(7), SELECT INTO (\fBSELECT_INTO\fR(7)), \fBVALUES\fR(7)
diff --git a/doc/src/sgml/man7/CREATE_TEXT_SEARCH_CONFIGURATION.7 b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_CONFIGURATION.7
new file mode 100644
index 0000000..a8a9ecd
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_CONFIGURATION.7
@@ -0,0 +1,85 @@
+'\" t
+.\" Title: CREATE TEXT SEARCH CONFIGURATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TEXT SEARCH CONFIGURATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TEXT_SEARCH_CONFIGURATION \- define a new text search configuration
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE TEXT SEARCH CONFIGURATION \fIname\fR (
+ PARSER = \fIparser_name\fR |
+ COPY = \fIsource_config\fR
+)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TEXT SEARCH CONFIGURATION\fR
+creates a new text search configuration\&. A text search configuration specifies a text search parser that can divide a string into tokens, plus dictionaries that can be used to determine which tokens are of interest for searching\&.
+.PP
+If only the parser is specified, then the new text search configuration initially has no mappings from token types to dictionaries, and therefore will ignore all words\&. Subsequent
+\fBALTER TEXT SEARCH CONFIGURATION\fR
+commands must be used to create mappings to make the configuration useful\&. Alternatively, an existing text search configuration can be copied\&.
+.PP
+If a schema name is given then the text search configuration is created in the specified schema\&. Otherwise it is created in the current schema\&.
+.PP
+The user who defines a text search configuration becomes its owner\&.
+.PP
+Refer to
+Chapter\ \&12
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the text search configuration to be created\&. The name can be schema\-qualified\&.
+.RE
+.PP
+\fIparser_name\fR
+.RS 4
+The name of the text search parser to use for this configuration\&.
+.RE
+.PP
+\fIsource_config\fR
+.RS 4
+The name of an existing text search configuration to copy\&.
+.RE
+.SH "NOTES"
+.PP
+The
+PARSER
+and
+COPY
+options are mutually exclusive, because when an existing configuration is copied, its parser selection is copied too\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE TEXT SEARCH CONFIGURATION\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH CONFIGURATION (\fBALTER_TEXT_SEARCH_CONFIGURATION\fR(7)), DROP TEXT SEARCH CONFIGURATION (\fBDROP_TEXT_SEARCH_CONFIGURATION\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TEXT_SEARCH_DICTIONARY.7 b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_DICTIONARY.7
new file mode 100644
index 0000000..8822d92
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_DICTIONARY.7
@@ -0,0 +1,98 @@
+'\" t
+.\" Title: CREATE TEXT SEARCH DICTIONARY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TEXT SEARCH DICTIONARY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TEXT_SEARCH_DICTIONARY \- define a new text search dictionary
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE TEXT SEARCH DICTIONARY \fIname\fR (
+ TEMPLATE = \fItemplate\fR
+ [, \fIoption\fR = \fIvalue\fR [, \&.\&.\&. ]]
+)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TEXT SEARCH DICTIONARY\fR
+creates a new text search dictionary\&. A text search dictionary specifies a way of recognizing interesting or uninteresting words for searching\&. A dictionary depends on a text search template, which specifies the functions that actually perform the work\&. Typically the dictionary provides some options that control the detailed behavior of the template\*(Aqs functions\&.
+.PP
+If a schema name is given then the text search dictionary is created in the specified schema\&. Otherwise it is created in the current schema\&.
+.PP
+The user who defines a text search dictionary becomes its owner\&.
+.PP
+Refer to
+Chapter\ \&12
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the text search dictionary to be created\&. The name can be schema\-qualified\&.
+.RE
+.PP
+\fItemplate\fR
+.RS 4
+The name of the text search template that will define the basic behavior of this dictionary\&.
+.RE
+.PP
+\fIoption\fR
+.RS 4
+The name of a template\-specific option to be set for this dictionary\&.
+.RE
+.PP
+\fIvalue\fR
+.RS 4
+The value to use for a template\-specific option\&. If the value is not a simple identifier or number, it must be quoted (but you can always quote it, if you wish)\&.
+.RE
+.PP
+The options can appear in any order\&.
+.SH "EXAMPLES"
+.PP
+The following example command creates a Snowball\-based dictionary with a nonstandard list of stop words\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TEXT SEARCH DICTIONARY my_russian (
+ template = snowball,
+ language = russian,
+ stopwords = myrussian
+);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE TEXT SEARCH DICTIONARY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH DICTIONARY (\fBALTER_TEXT_SEARCH_DICTIONARY\fR(7)), DROP TEXT SEARCH DICTIONARY (\fBDROP_TEXT_SEARCH_DICTIONARY\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TEXT_SEARCH_PARSER.7 b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_PARSER.7
new file mode 100644
index 0000000..fe1a7de
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_PARSER.7
@@ -0,0 +1,97 @@
+'\" t
+.\" Title: CREATE TEXT SEARCH PARSER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TEXT SEARCH PARSER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TEXT_SEARCH_PARSER \- define a new text search parser
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE TEXT SEARCH PARSER \fIname\fR (
+ START = \fIstart_function\fR ,
+ GETTOKEN = \fIgettoken_function\fR ,
+ END = \fIend_function\fR ,
+ LEXTYPES = \fIlextypes_function\fR
+ [, HEADLINE = \fIheadline_function\fR ]
+)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TEXT SEARCH PARSER\fR
+creates a new text search parser\&. A text search parser defines a method for splitting a text string into tokens and assigning types (categories) to the tokens\&. A parser is not particularly useful by itself, but must be bound into a text search configuration along with some text search dictionaries to be used for searching\&.
+.PP
+If a schema name is given then the text search parser is created in the specified schema\&. Otherwise it is created in the current schema\&.
+.PP
+You must be a superuser to use
+\fBCREATE TEXT SEARCH PARSER\fR\&. (This restriction is made because an erroneous text search parser definition could confuse or even crash the server\&.)
+.PP
+Refer to
+Chapter\ \&12
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the text search parser to be created\&. The name can be schema\-qualified\&.
+.RE
+.PP
+\fIstart_function\fR
+.RS 4
+The name of the start function for the parser\&.
+.RE
+.PP
+\fIgettoken_function\fR
+.RS 4
+The name of the get\-next\-token function for the parser\&.
+.RE
+.PP
+\fIend_function\fR
+.RS 4
+The name of the end function for the parser\&.
+.RE
+.PP
+\fIlextypes_function\fR
+.RS 4
+The name of the lextypes function for the parser (a function that returns information about the set of token types it produces)\&.
+.RE
+.PP
+\fIheadline_function\fR
+.RS 4
+The name of the headline function for the parser (a function that summarizes a set of tokens)\&.
+.RE
+.PP
+The function names can be schema\-qualified if necessary\&. Argument types are not given, since the argument list for each type of function is predetermined\&. All except the headline function are required\&.
+.PP
+The arguments can appear in any order, not only the one shown above\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE TEXT SEARCH PARSER\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH PARSER (\fBALTER_TEXT_SEARCH_PARSER\fR(7)), DROP TEXT SEARCH PARSER (\fBDROP_TEXT_SEARCH_PARSER\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TEXT_SEARCH_TEMPLATE.7 b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_TEMPLATE.7
new file mode 100644
index 0000000..8430685
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TEXT_SEARCH_TEMPLATE.7
@@ -0,0 +1,81 @@
+'\" t
+.\" Title: CREATE TEXT SEARCH TEMPLATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TEXT SEARCH TEMPLATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TEXT_SEARCH_TEMPLATE \- define a new text search template
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE TEXT SEARCH TEMPLATE \fIname\fR (
+ [ INIT = \fIinit_function\fR , ]
+ LEXIZE = \fIlexize_function\fR
+)
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TEXT SEARCH TEMPLATE\fR
+creates a new text search template\&. Text search templates define the functions that implement text search dictionaries\&. A template is not useful by itself, but must be instantiated as a dictionary to be used\&. The dictionary typically specifies parameters to be given to the template functions\&.
+.PP
+If a schema name is given then the text search template is created in the specified schema\&. Otherwise it is created in the current schema\&.
+.PP
+You must be a superuser to use
+\fBCREATE TEXT SEARCH TEMPLATE\fR\&. This restriction is made because an erroneous text search template definition could confuse or even crash the server\&. The reason for separating templates from dictionaries is that a template encapsulates the
+\(lqunsafe\(rq
+aspects of defining a dictionary\&. The parameters that can be set when defining a dictionary are safe for unprivileged users to set, and so creating a dictionary need not be a privileged operation\&.
+.PP
+Refer to
+Chapter\ \&12
+for further information\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the text search template to be created\&. The name can be schema\-qualified\&.
+.RE
+.PP
+\fIinit_function\fR
+.RS 4
+The name of the init function for the template\&.
+.RE
+.PP
+\fIlexize_function\fR
+.RS 4
+The name of the lexize function for the template\&.
+.RE
+.PP
+The function names can be schema\-qualified if necessary\&. Argument types are not given, since the argument list for each type of function is predetermined\&. The lexize function is required, but the init function is optional\&.
+.PP
+The arguments can appear in any order, not only the one shown above\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBCREATE TEXT SEARCH TEMPLATE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH TEMPLATE (\fBALTER_TEXT_SEARCH_TEMPLATE\fR(7)), DROP TEXT SEARCH TEMPLATE (\fBDROP_TEXT_SEARCH_TEMPLATE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TRANSFORM.7 b/doc/src/sgml/man7/CREATE_TRANSFORM.7
new file mode 100644
index 0000000..b8a70c3
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TRANSFORM.7
@@ -0,0 +1,198 @@
+'\" t
+.\" Title: CREATE TRANSFORM
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TRANSFORM" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TRANSFORM \- define a new transform
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] TRANSFORM FOR \fItype_name\fR LANGUAGE \fIlang_name\fR (
+ FROM SQL WITH FUNCTION \fIfrom_sql_function_name\fR [ (\fIargument_type\fR [, \&.\&.\&.]) ],
+ TO SQL WITH FUNCTION \fIto_sql_function_name\fR [ (\fIargument_type\fR [, \&.\&.\&.]) ]
+);
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TRANSFORM\fR
+defines a new transform\&.
+\fBCREATE OR REPLACE TRANSFORM\fR
+will either create a new transform, or replace an existing definition\&.
+.PP
+A transform specifies how to adapt a data type to a procedural language\&. For example, when writing a function in PL/Python using the
+hstore
+type, PL/Python has no prior knowledge how to present
+hstore
+values in the Python environment\&. Language implementations usually default to using the text representation, but that is inconvenient when, for example, an associative array or a list would be more appropriate\&.
+.PP
+A transform specifies two functions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A
+\(lqfrom SQL\(rq
+function that converts the type from the SQL environment to the language\&. This function will be invoked on the arguments of a function written in the language\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+A
+\(lqto SQL\(rq
+function that converts the type from the language to the SQL environment\&. This function will be invoked on the return value of a function written in the language\&.
+.RE
+.sp
+It is not necessary to provide both of these functions\&. If one is not specified, the language\-specific default behavior will be used if necessary\&. (To prevent a transformation in a certain direction from happening at all, you could also write a transform function that always errors out\&.)
+.PP
+To be able to create a transform, you must own and have
+USAGE
+privilege on the type, have
+USAGE
+privilege on the language, and own and have
+EXECUTE
+privilege on the from\-SQL and to\-SQL functions, if specified\&.
+.SH "PARAMETERS"
+.PP
+\fItype_name\fR
+.RS 4
+The name of the data type of the transform\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the language of the transform\&.
+.RE
+.PP
+\fIfrom_sql_function_name\fR[(\fIargument_type\fR [, \&.\&.\&.])]
+.RS 4
+The name of the function for converting the type from the SQL environment to the language\&. It must take one argument of type
+internal
+and return type
+internal\&. The actual argument will be of the type for the transform, and the function should be coded as if it were\&. (But it is not allowed to declare an SQL\-level function returning
+internal
+without at least one argument of type
+internal\&.) The actual return value will be something specific to the language implementation\&. If no argument list is specified, the function name must be unique in its schema\&.
+.RE
+.PP
+\fIto_sql_function_name\fR[(\fIargument_type\fR [, \&.\&.\&.])]
+.RS 4
+The name of the function for converting the type from the language to the SQL environment\&. It must take one argument of type
+internal
+and return the type that is the type for the transform\&. The actual argument value will be something specific to the language implementation\&. If no argument list is specified, the function name must be unique in its schema\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBDROP TRANSFORM\fR
+to remove transforms\&.
+.SH "EXAMPLES"
+.PP
+To create a transform for type
+hstore
+and language
+plpython3u, first set up the type and the language:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE hstore \&.\&.\&.;
+
+CREATE EXTENSION plpython3u;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Then create the necessary functions:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION hstore_to_plpython(val internal) RETURNS internal
+LANGUAGE C STRICT IMMUTABLE
+AS \&.\&.\&.;
+
+CREATE FUNCTION plpython_to_hstore(val internal) RETURNS hstore
+LANGUAGE C STRICT IMMUTABLE
+AS \&.\&.\&.;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+And finally create the transform to connect them all together:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRANSFORM FOR hstore LANGUAGE plpython3u (
+ FROM SQL WITH FUNCTION hstore_to_plpython(internal),
+ TO SQL WITH FUNCTION plpython_to_hstore(internal)
+);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In practice, these commands would be wrapped up in an extension\&.
+.PP
+The
+contrib
+section contains a number of extensions that provide transforms, which can serve as real\-world examples\&.
+.SH "COMPATIBILITY"
+.PP
+This form of
+\fBCREATE TRANSFORM\fR
+is a
+PostgreSQL
+extension\&. There is a
+\fBCREATE TRANSFORM\fR
+command in the
+SQL
+standard, but it is for adapting data types to client languages\&. That usage is not supported by
+PostgreSQL\&.
+.SH "SEE ALSO"
+.PP
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)),
+CREATE LANGUAGE (\fBCREATE_LANGUAGE\fR(7)),
+CREATE TYPE (\fBCREATE_TYPE\fR(7)),
+DROP TRANSFORM (\fBDROP_TRANSFORM\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TRIGGER.7 b/doc/src/sgml/man7/CREATE_TRIGGER.7
new file mode 100644
index 0000000..47330a6
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TRIGGER.7
@@ -0,0 +1,715 @@
+'\" t
+.\" Title: CREATE TRIGGER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TRIGGER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TRIGGER \- define a new trigger
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER \fIname\fR { BEFORE | AFTER | INSTEAD OF } { \fIevent\fR [ OR \&.\&.\&. ] }
+ ON \fItable_name\fR
+ [ FROM \fIreferenced_table_name\fR ]
+ [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
+ [ REFERENCING { { OLD | NEW } TABLE [ AS ] \fItransition_relation_name\fR } [ \&.\&.\&. ] ]
+ [ FOR [ EACH ] { ROW | STATEMENT } ]
+ [ WHEN ( \fIcondition\fR ) ]
+ EXECUTE { FUNCTION | PROCEDURE } \fIfunction_name\fR ( \fIarguments\fR )
+
+where \fIevent\fR can be one of:
+
+ INSERT
+ UPDATE [ OF \fIcolumn_name\fR [, \&.\&.\&. ] ]
+ DELETE
+ TRUNCATE
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TRIGGER\fR
+creates a new trigger\&.
+\fBCREATE OR REPLACE TRIGGER\fR
+will either create a new trigger, or replace an existing trigger\&. The trigger will be associated with the specified table, view, or foreign table and will execute the specified function
+\fIfunction_name\fR
+when certain operations are performed on that table\&.
+.PP
+To replace the current definition of an existing trigger, use
+\fBCREATE OR REPLACE TRIGGER\fR, specifying the existing trigger\*(Aqs name and parent table\&. All other properties are replaced\&.
+.PP
+The trigger can be specified to fire before the operation is attempted on a row (before constraints are checked and the
+\fBINSERT\fR,
+\fBUPDATE\fR, or
+\fBDELETE\fR
+is attempted); or after the operation has completed (after constraints are checked and the
+\fBINSERT\fR,
+\fBUPDATE\fR, or
+\fBDELETE\fR
+has completed); or instead of the operation (in the case of inserts, updates or deletes on a view)\&. If the trigger fires before or instead of the event, the trigger can skip the operation for the current row, or change the row being inserted (for
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+operations only)\&. If the trigger fires after the event, all changes, including the effects of other triggers, are
+\(lqvisible\(rq
+to the trigger\&.
+.PP
+A trigger that is marked
+FOR EACH ROW
+is called once for every row that the operation modifies\&. For example, a
+\fBDELETE\fR
+that affects 10 rows will cause any
+ON DELETE
+triggers on the target relation to be called 10 separate times, once for each deleted row\&. In contrast, a trigger that is marked
+FOR EACH STATEMENT
+only executes once for any given operation, regardless of how many rows it modifies (in particular, an operation that modifies zero rows will still result in the execution of any applicable
+FOR EACH STATEMENT
+triggers)\&.
+.PP
+Triggers that are specified to fire
+INSTEAD OF
+the trigger event must be marked
+FOR EACH ROW, and can only be defined on views\&.
+BEFORE
+and
+AFTER
+triggers on a view must be marked as
+FOR EACH STATEMENT\&.
+.PP
+In addition, triggers may be defined to fire for
+\fBTRUNCATE\fR, though only
+FOR EACH STATEMENT\&.
+.PP
+The following table summarizes which types of triggers may be used on tables, views, and foreign tables:
+.TS
+allbox tab(:);
+lB lB lB lB.
+T{
+When
+T}:T{
+Event
+T}:T{
+Row\-level
+T}:T{
+Statement\-level
+T}
+.T&
+c c c c
+^ c c c
+c c c c
+^ c c c
+c c c c
+^ c c c.
+T{
+BEFORE
+T}:T{
+\fBINSERT\fR/\fBUPDATE\fR/\fBDELETE\fR
+T}:T{
+Tables and foreign tables
+T}:T{
+Tables, views, and foreign tables
+T}
+:T{
+\fBTRUNCATE\fR
+T}:T{
+\(em
+T}:T{
+Tables
+T}
+T{
+AFTER
+T}:T{
+\fBINSERT\fR/\fBUPDATE\fR/\fBDELETE\fR
+T}:T{
+Tables and foreign tables
+T}:T{
+Tables, views, and foreign tables
+T}
+:T{
+\fBTRUNCATE\fR
+T}:T{
+\(em
+T}:T{
+Tables
+T}
+T{
+INSTEAD OF
+T}:T{
+\fBINSERT\fR/\fBUPDATE\fR/\fBDELETE\fR
+T}:T{
+Views
+T}:T{
+\(em
+T}
+:T{
+\fBTRUNCATE\fR
+T}:T{
+\(em
+T}:T{
+\(em
+T}
+.TE
+.sp 1
+.PP
+Also, a trigger definition can specify a Boolean
+WHEN
+condition, which will be tested to see whether the trigger should be fired\&. In row\-level triggers the
+WHEN
+condition can examine the old and/or new values of columns of the row\&. Statement\-level triggers can also have
+WHEN
+conditions, although the feature is not so useful for them since the condition cannot refer to any values in the table\&.
+.PP
+If multiple triggers of the same kind are defined for the same event, they will be fired in alphabetical order by name\&.
+.PP
+When the
+CONSTRAINT
+option is specified, this command creates a
+constraint trigger\&.
+This is the same as a regular trigger except that the timing of the trigger firing can be adjusted using
+\fBSET CONSTRAINTS\fR\&. Constraint triggers must be
+AFTER ROW
+triggers on plain tables (not foreign tables)\&. They can be fired either at the end of the statement causing the triggering event, or at the end of the containing transaction; in the latter case they are said to be
+deferred\&. A pending deferred\-trigger firing can also be forced to happen immediately by using
+\fBSET CONSTRAINTS\fR\&. Constraint triggers are expected to raise an exception when the constraints they implement are violated\&.
+.PP
+The
+REFERENCING
+option enables collection of
+transition relations, which are row sets that include all of the rows inserted, deleted, or modified by the current SQL statement\&. This feature lets the trigger see a global view of what the statement did, not just one row at a time\&. This option is only allowed for an
+AFTER
+trigger that is not a constraint trigger; also, if the trigger is an
+UPDATE
+trigger, it must not specify a
+\fIcolumn_name\fR
+list\&.
+OLD TABLE
+may only be specified once, and only for a trigger that can fire on
+UPDATE
+or
+DELETE; it creates a transition relation containing the
+before\-images
+of all rows updated or deleted by the statement\&. Similarly,
+NEW TABLE
+may only be specified once, and only for a trigger that can fire on
+UPDATE
+or
+INSERT; it creates a transition relation containing the
+after\-images
+of all rows updated or inserted by the statement\&.
+.PP
+\fBSELECT\fR
+does not modify any rows so you cannot create
+\fBSELECT\fR
+triggers\&. Rules and views may provide workable solutions to problems that seem to need
+\fBSELECT\fR
+triggers\&.
+.PP
+Refer to
+Chapter\ \&39
+for more information about triggers\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name to give the new trigger\&. This must be distinct from the name of any other trigger for the same table\&. The name cannot be schema\-qualified \(em the trigger inherits the schema of its table\&. For a constraint trigger, this is also the name to use when modifying the trigger\*(Aqs behavior using
+\fBSET CONSTRAINTS\fR\&.
+.RE
+.PP
+BEFORE
+.br
+AFTER
+.br
+INSTEAD OF
+.RS 4
+Determines whether the function is called before, after, or instead of the event\&. A constraint trigger can only be specified as
+AFTER\&.
+.RE
+.PP
+\fIevent\fR
+.RS 4
+One of
+INSERT,
+UPDATE,
+DELETE, or
+TRUNCATE; this specifies the event that will fire the trigger\&. Multiple events can be specified using
+OR, except when transition relations are requested\&.
+.sp
+For
+UPDATE
+events, it is possible to specify a list of columns using this syntax:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE OF \fIcolumn_name1\fR [, \fIcolumn_name2\fR \&.\&.\&. ]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The trigger will only fire if at least one of the listed columns is mentioned as a target of the
+\fBUPDATE\fR
+command or if one of the listed columns is a generated column that depends on a column that is the target of the
+\fBUPDATE\fR\&.
+.sp
+INSTEAD OF UPDATE
+events do not allow a list of columns\&. A column list cannot be specified when requesting transition relations, either\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table, view, or foreign table the trigger is for\&.
+.RE
+.PP
+\fIreferenced_table_name\fR
+.RS 4
+The (possibly schema\-qualified) name of another table referenced by the constraint\&. This option is used for foreign\-key constraints and is not recommended for general use\&. This can only be specified for constraint triggers\&.
+.RE
+.PP
+DEFERRABLE
+.br
+NOT DEFERRABLE
+.br
+INITIALLY IMMEDIATE
+.br
+INITIALLY DEFERRED
+.RS 4
+The default timing of the trigger\&. See the
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+documentation for details of these constraint options\&. This can only be specified for constraint triggers\&.
+.RE
+.PP
+REFERENCING
+.RS 4
+This keyword immediately precedes the declaration of one or two relation names that provide access to the transition relations of the triggering statement\&.
+.RE
+.PP
+OLD TABLE
+.br
+NEW TABLE
+.RS 4
+This clause indicates whether the following relation name is for the before\-image transition relation or the after\-image transition relation\&.
+.RE
+.PP
+\fItransition_relation_name\fR
+.RS 4
+The (unqualified) name to be used within the trigger for this transition relation\&.
+.RE
+.PP
+FOR EACH ROW
+.br
+FOR EACH STATEMENT
+.RS 4
+This specifies whether the trigger function should be fired once for every row affected by the trigger event, or just once per SQL statement\&. If neither is specified,
+FOR EACH STATEMENT
+is the default\&. Constraint triggers can only be specified
+FOR EACH ROW\&.
+.RE
+.PP
+\fIcondition\fR
+.RS 4
+A Boolean expression that determines whether the trigger function will actually be executed\&. If
+WHEN
+is specified, the function will only be called if the
+\fIcondition\fR
+returns
+true\&. In
+FOR EACH ROW
+triggers, the
+WHEN
+condition can refer to columns of the old and/or new row values by writing
+OLD\&.\fIcolumn_name\fR
+or
+NEW\&.\fIcolumn_name\fR
+respectively\&. Of course,
+INSERT
+triggers cannot refer to
+OLD
+and
+DELETE
+triggers cannot refer to
+NEW\&.
+.sp
+INSTEAD OF
+triggers do not support
+WHEN
+conditions\&.
+.sp
+Currently,
+WHEN
+expressions cannot contain subqueries\&.
+.sp
+Note that for constraint triggers, evaluation of the
+WHEN
+condition is not deferred, but occurs immediately after the row update operation is performed\&. If the condition does not evaluate to true then the trigger is not queued for deferred execution\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+A user\-supplied function that is declared as taking no arguments and returning type
+trigger, which is executed when the trigger fires\&.
+.sp
+In the syntax of
+CREATE TRIGGER, the keywords
+FUNCTION
+and
+PROCEDURE
+are equivalent, but the referenced function must in any case be a function, not a procedure\&. The use of the keyword
+PROCEDURE
+here is historical and deprecated\&.
+.RE
+.PP
+\fIarguments\fR
+.RS 4
+An optional comma\-separated list of arguments to be provided to the function when the trigger is executed\&. The arguments are literal string constants\&. Simple names and numeric constants can be written here, too, but they will all be converted to strings\&. Please check the description of the implementation language of the trigger function to find out how these arguments can be accessed within the function; it might be different from normal function arguments\&.
+.RE
+.SH "NOTES"
+.PP
+To create or replace a trigger on a table, the user must have the
+TRIGGER
+privilege on the table\&. The user must also have
+EXECUTE
+privilege on the trigger function\&.
+.PP
+Use
+\fBDROP TRIGGER\fR
+to remove a trigger\&.
+.PP
+Creating a row\-level trigger on a partitioned table will cause an identical
+\(lqclone\(rq
+trigger to be created on each of its existing partitions; and any partitions created or attached later will have an identical trigger, too\&. If there is a conflictingly\-named trigger on a child partition already, an error occurs unless
+\fBCREATE OR REPLACE TRIGGER\fR
+is used, in which case that trigger is replaced with a clone trigger\&. When a partition is detached from its parent, its clone triggers are removed\&.
+.PP
+A column\-specific trigger (one defined using the
+UPDATE OF \fIcolumn_name\fR
+syntax) will fire when any of its columns are listed as targets in the
+\fBUPDATE\fR
+command\*(Aqs
+SET
+list\&. It is possible for a column\*(Aqs value to change even when the trigger is not fired, because changes made to the row\*(Aqs contents by
+BEFORE UPDATE
+triggers are not considered\&. Conversely, a command such as
+UPDATE \&.\&.\&. SET x = x \&.\&.\&.
+will fire a trigger on column
+x, even though the column\*(Aqs value did not change\&.
+.PP
+In a
+BEFORE
+trigger, the
+WHEN
+condition is evaluated just before the function is or would be executed, so using
+WHEN
+is not materially different from testing the same condition at the beginning of the trigger function\&. Note in particular that the
+NEW
+row seen by the condition is the current value, as possibly modified by earlier triggers\&. Also, a
+BEFORE
+trigger\*(Aqs
+WHEN
+condition is not allowed to examine the system columns of the
+NEW
+row (such as
+ctid), because those won\*(Aqt have been set yet\&.
+.PP
+In an
+AFTER
+trigger, the
+WHEN
+condition is evaluated just after the row update occurs, and it determines whether an event is queued to fire the trigger at the end of statement\&. So when an
+AFTER
+trigger\*(Aqs
+WHEN
+condition does not return true, it is not necessary to queue an event nor to re\-fetch the row at end of statement\&. This can result in significant speedups in statements that modify many rows, if the trigger only needs to be fired for a few of the rows\&.
+.PP
+In some cases it is possible for a single SQL command to fire more than one kind of trigger\&. For instance an
+\fBINSERT\fR
+with an
+ON CONFLICT DO UPDATE
+clause may cause both insert and update operations, so it will fire both kinds of triggers as needed\&. The transition relations supplied to triggers are specific to their event type; thus an
+\fBINSERT\fR
+trigger will see only the inserted rows, while an
+\fBUPDATE\fR
+trigger will see only the updated rows\&.
+.PP
+Row updates or deletions caused by foreign\-key enforcement actions, such as
+ON UPDATE CASCADE
+or
+ON DELETE SET NULL, are treated as part of the SQL command that caused them (note that such actions are never deferred)\&. Relevant triggers on the affected table will be fired, so that this provides another way in which an SQL command might fire triggers not directly matching its type\&. In simple cases, triggers that request transition relations will see all changes caused in their table by a single original SQL command as a single transition relation\&. However, there are cases in which the presence of an
+AFTER ROW
+trigger that requests transition relations will cause the foreign\-key enforcement actions triggered by a single SQL command to be split into multiple steps, each with its own transition relation(s)\&. In such cases, any statement\-level triggers that are present will be fired once per creation of a transition relation set, ensuring that the triggers see each affected row in a transition relation once and only once\&.
+.PP
+Statement\-level triggers on a view are fired only if the action on the view is handled by a row\-level
+INSTEAD OF
+trigger\&. If the action is handled by an
+INSTEAD
+rule, then whatever statements are emitted by the rule are executed in place of the original statement naming the view, so that the triggers that will be fired are those on tables named in the replacement statements\&. Similarly, if the view is automatically updatable, then the action is handled by automatically rewriting the statement into an action on the view\*(Aqs base table, so that the base table\*(Aqs statement\-level triggers are the ones that are fired\&.
+.PP
+Modifying a partitioned table or a table with inheritance children fires statement\-level triggers attached to the explicitly named table, but not statement\-level triggers for its partitions or child tables\&. In contrast, row\-level triggers are fired on the rows in affected partitions or child tables, even if they are not explicitly named in the query\&. If a statement\-level trigger has been defined with transition relations named by a
+REFERENCING
+clause, then before and after images of rows are visible from all affected partitions or child tables\&. In the case of inheritance children, the row images include only columns that are present in the table that the trigger is attached to\&.
+.PP
+Currently, row\-level triggers with transition relations cannot be defined on partitions or inheritance child tables\&. Also, triggers on partitioned tables may not be
+INSTEAD OF\&.
+.PP
+Currently, the
+OR REPLACE
+option is not supported for constraint triggers\&.
+.PP
+Replacing an existing trigger within a transaction that has already performed updating actions on the trigger\*(Aqs table is not recommended\&. Trigger firing decisions, or portions of firing decisions, that have already been made will not be reconsidered, so the effects could be surprising\&.
+.PP
+There are a few built\-in trigger functions that can be used to solve common problems without having to write your own trigger code; see
+Section\ \&9.28\&.
+.SH "EXAMPLES"
+.PP
+Execute the function
+\fBcheck_account_update\fR
+whenever a row of the table
+accounts
+is about to be updated:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRIGGER check_update
+ BEFORE UPDATE ON accounts
+ FOR EACH ROW
+ EXECUTE FUNCTION check_account_update();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Modify that trigger definition to only execute the function if column
+balance
+is specified as a target in the
+\fBUPDATE\fR
+command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE OR REPLACE TRIGGER check_update
+ BEFORE UPDATE OF balance ON accounts
+ FOR EACH ROW
+ EXECUTE FUNCTION check_account_update();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This form only executes the function if column
+balance
+has in fact changed value:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRIGGER check_update
+ BEFORE UPDATE ON accounts
+ FOR EACH ROW
+ WHEN (OLD\&.balance IS DISTINCT FROM NEW\&.balance)
+ EXECUTE FUNCTION check_account_update();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Call a function to log updates of
+accounts, but only if something changed:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRIGGER log_update
+ AFTER UPDATE ON accounts
+ FOR EACH ROW
+ WHEN (OLD\&.* IS DISTINCT FROM NEW\&.*)
+ EXECUTE FUNCTION log_account_update();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Execute the function
+\fBview_insert_row\fR
+for each row to insert rows into the tables underlying a view:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRIGGER view_insert
+ INSTEAD OF INSERT ON my_view
+ FOR EACH ROW
+ EXECUTE FUNCTION view_insert_row();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Execute the function
+\fBcheck_transfer_balances_to_zero\fR
+for each statement to confirm that the
+transfer
+rows offset to a net of zero:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRIGGER transfer_insert
+ AFTER INSERT ON transfer
+ REFERENCING NEW TABLE AS inserted
+ FOR EACH STATEMENT
+ EXECUTE FUNCTION check_transfer_balances_to_zero();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Execute the function
+\fBcheck_matching_pairs\fR
+for each row to confirm that changes are made to matching pairs at the same time (by the same statement):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TRIGGER paired_items_update
+ AFTER UPDATE ON paired_items
+ REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab
+ FOR EACH ROW
+ EXECUTE FUNCTION check_matching_pairs();
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Section\ \&39.4
+contains a complete example of a trigger function written in C\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCREATE TRIGGER\fR
+statement in
+PostgreSQL
+implements a subset of the
+SQL
+standard\&. The following functionalities are currently missing:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+While transition table names for
+AFTER
+triggers are specified using the
+REFERENCING
+clause in the standard way, the row variables used in
+FOR EACH ROW
+triggers may not be specified in a
+REFERENCING
+clause\&. They are available in a manner that is dependent on the language in which the trigger function is written, but is fixed for any one language\&. Some languages effectively behave as though there is a
+REFERENCING
+clause containing
+OLD ROW AS OLD NEW ROW AS NEW\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The standard allows transition tables to be used with column\-specific
+UPDATE
+triggers, but then the set of rows that should be visible in the transition tables depends on the trigger\*(Aqs column list\&. This is not currently implemented by
+PostgreSQL\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+PostgreSQL
+only allows the execution of a user\-defined function for the triggered action\&. The standard allows the execution of a number of other SQL commands, such as
+\fBCREATE TABLE\fR, as the triggered action\&. This limitation is not hard to work around by creating a user\-defined function that executes the desired commands\&.
+.RE
+.PP
+SQL specifies that multiple triggers should be fired in time\-of\-creation order\&.
+PostgreSQL
+uses name order, which was judged to be more convenient\&.
+.PP
+SQL specifies that
+BEFORE DELETE
+triggers on cascaded deletes fire
+\fIafter\fR
+the cascaded
+DELETE
+completes\&. The
+PostgreSQL
+behavior is for
+BEFORE DELETE
+to always fire before the delete action, even a cascading one\&. This is considered more consistent\&. There is also nonstandard behavior if
+BEFORE
+triggers modify rows or prevent updates during an update that is caused by a referential action\&. This can lead to constraint violations or stored data that does not honor the referential constraint\&.
+.PP
+The ability to specify multiple actions for a single trigger using
+OR
+is a
+PostgreSQL
+extension of the SQL standard\&.
+.PP
+The ability to fire triggers for
+\fBTRUNCATE\fR
+is a
+PostgreSQL
+extension of the SQL standard, as is the ability to define statement\-level triggers on views\&.
+.PP
+\fBCREATE CONSTRAINT TRIGGER\fR
+is a
+PostgreSQL
+extension of the
+SQL
+standard\&. So is the
+OR REPLACE
+option\&.
+.SH "SEE ALSO"
+ALTER TRIGGER (\fBALTER_TRIGGER\fR(7)), DROP TRIGGER (\fBDROP_TRIGGER\fR(7)), CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)), SET CONSTRAINTS (\fBSET_CONSTRAINTS\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_TYPE.7 b/doc/src/sgml/man7/CREATE_TYPE.7
new file mode 100644
index 0000000..004cd44
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_TYPE.7
@@ -0,0 +1,733 @@
+'\" t
+.\" Title: CREATE TYPE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE TYPE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_TYPE \- define a new data type
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE TYPE \fIname\fR AS
+ ( [ \fIattribute_name\fR \fIdata_type\fR [ COLLATE \fIcollation\fR ] [, \&.\&.\&. ] ] )
+
+CREATE TYPE \fIname\fR AS ENUM
+ ( [ \*(Aq\fIlabel\fR\*(Aq [, \&.\&.\&. ] ] )
+
+CREATE TYPE \fIname\fR AS RANGE (
+ SUBTYPE = \fIsubtype\fR
+ [ , SUBTYPE_OPCLASS = \fIsubtype_operator_class\fR ]
+ [ , COLLATION = \fIcollation\fR ]
+ [ , CANONICAL = \fIcanonical_function\fR ]
+ [ , SUBTYPE_DIFF = \fIsubtype_diff_function\fR ]
+ [ , MULTIRANGE_TYPE_NAME = \fImultirange_type_name\fR ]
+)
+
+CREATE TYPE \fIname\fR (
+ INPUT = \fIinput_function\fR,
+ OUTPUT = \fIoutput_function\fR
+ [ , RECEIVE = \fIreceive_function\fR ]
+ [ , SEND = \fIsend_function\fR ]
+ [ , TYPMOD_IN = \fItype_modifier_input_function\fR ]
+ [ , TYPMOD_OUT = \fItype_modifier_output_function\fR ]
+ [ , ANALYZE = \fIanalyze_function\fR ]
+ [ , SUBSCRIPT = \fIsubscript_function\fR ]
+ [ , INTERNALLENGTH = { \fIinternallength\fR | VARIABLE } ]
+ [ , PASSEDBYVALUE ]
+ [ , ALIGNMENT = \fIalignment\fR ]
+ [ , STORAGE = \fIstorage\fR ]
+ [ , LIKE = \fIlike_type\fR ]
+ [ , CATEGORY = \fIcategory\fR ]
+ [ , PREFERRED = \fIpreferred\fR ]
+ [ , DEFAULT = \fIdefault\fR ]
+ [ , ELEMENT = \fIelement\fR ]
+ [ , DELIMITER = \fIdelimiter\fR ]
+ [ , COLLATABLE = \fIcollatable\fR ]
+)
+
+CREATE TYPE \fIname\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE TYPE\fR
+registers a new data type for use in the current database\&. The user who defines a type becomes its owner\&.
+.PP
+If a schema name is given then the type is created in the specified schema\&. Otherwise it is created in the current schema\&. The type name must be distinct from the name of any existing type or domain in the same schema\&. (Because tables have associated data types, the type name must also be distinct from the name of any existing table in the same schema\&.)
+.PP
+There are five forms of
+\fBCREATE TYPE\fR, as shown in the syntax synopsis above\&. They respectively create a
+composite type, an
+enum type, a
+range type, a
+base type, or a
+shell type\&. The first four of these are discussed in turn below\&. A shell type is simply a placeholder for a type to be defined later; it is created by issuing
+\fBCREATE TYPE\fR
+with no parameters except for the type name\&. Shell types are needed as forward references when creating range types and base types, as discussed in those sections\&.
+.SS "Composite Types"
+.PP
+The first form of
+\fBCREATE TYPE\fR
+creates a composite type\&. The composite type is specified by a list of attribute names and data types\&. An attribute\*(Aqs collation can be specified too, if its data type is collatable\&. A composite type is essentially the same as the row type of a table, but using
+\fBCREATE TYPE\fR
+avoids the need to create an actual table when all that is wanted is to define a type\&. A stand\-alone composite type is useful, for example, as the argument or return type of a function\&.
+.PP
+To be able to create a composite type, you must have
+USAGE
+privilege on all attribute types\&.
+.SS "Enumerated Types"
+.PP
+The second form of
+\fBCREATE TYPE\fR
+creates an enumerated (enum) type, as described in
+Section\ \&8.7\&. Enum types take a list of quoted labels, each of which must be less than
+NAMEDATALEN
+bytes long (64 bytes in a standard
+PostgreSQL
+build)\&. (It is possible to create an enumerated type with zero labels, but such a type cannot be used to hold values before at least one label is added using
+\fBALTER TYPE\fR\&.)
+.SS "Range Types"
+.PP
+The third form of
+\fBCREATE TYPE\fR
+creates a new range type, as described in
+Section\ \&8.17\&.
+.PP
+The range type\*(Aqs
+\fIsubtype\fR
+can be any type with an associated b\-tree operator class (to determine the ordering of values for the range type)\&. Normally the subtype\*(Aqs default b\-tree operator class is used to determine ordering; to use a non\-default operator class, specify its name with
+\fIsubtype_opclass\fR\&. If the subtype is collatable, and you want to use a non\-default collation in the range\*(Aqs ordering, specify the desired collation with the
+\fIcollation\fR
+option\&.
+.PP
+The optional
+\fIcanonical\fR
+function must take one argument of the range type being defined, and return a value of the same type\&. This is used to convert range values to a canonical form, when applicable\&. See
+Section\ \&8.17.8
+for more information\&. Creating a
+\fIcanonical\fR
+function is a bit tricky, since it must be defined before the range type can be declared\&. To do this, you must first create a shell type, which is a placeholder type that has no properties except a name and an owner\&. This is done by issuing the command
+CREATE TYPE \fIname\fR, with no additional parameters\&. Then the function can be declared using the shell type as argument and result, and finally the range type can be declared using the same name\&. This automatically replaces the shell type entry with a valid range type\&.
+.PP
+The optional
+\fIsubtype_diff\fR
+function must take two values of the
+\fIsubtype\fR
+type as argument, and return a
+double precision
+value representing the difference between the two given values\&. While this is optional, providing it allows much greater efficiency of GiST indexes on columns of the range type\&. See
+Section\ \&8.17.8
+for more information\&.
+.PP
+The optional
+\fImultirange_type_name\fR
+parameter specifies the name of the corresponding multirange type\&. If not specified, this name is chosen automatically as follows\&. If the range type name contains the substring
+range, then the multirange type name is formed by replacement of the
+range
+substring with
+multirange
+in the range type name\&. Otherwise, the multirange type name is formed by appending a
+_multirange
+suffix to the range type name\&.
+.SS "Base Types"
+.PP
+The fourth form of
+\fBCREATE TYPE\fR
+creates a new base type (scalar type)\&. To create a new base type, you must be a superuser\&. (This restriction is made because an erroneous type definition could confuse or even crash the server\&.)
+.PP
+The parameters can appear in any order, not only that illustrated above, and most are optional\&. You must register two or more functions (using
+\fBCREATE FUNCTION\fR) before defining the type\&. The support functions
+\fIinput_function\fR
+and
+\fIoutput_function\fR
+are required, while the functions
+\fIreceive_function\fR,
+\fIsend_function\fR,
+\fItype_modifier_input_function\fR,
+\fItype_modifier_output_function\fR,
+\fIanalyze_function\fR, and
+\fIsubscript_function\fR
+are optional\&. Generally these functions have to be coded in C or another low\-level language\&.
+.PP
+The
+\fIinput_function\fR
+converts the type\*(Aqs external textual representation to the internal representation used by the operators and functions defined for the type\&.
+\fIoutput_function\fR
+performs the reverse transformation\&. The input function can be declared as taking one argument of type
+cstring, or as taking three arguments of types
+cstring,
+oid,
+integer\&. The first argument is the input text as a C string, the second argument is the type\*(Aqs own OID (except for array types, which instead receive their element type\*(Aqs OID), and the third is the
+typmod
+of the destination column, if known (\-1 will be passed if not)\&. The input function must return a value of the data type itself\&. Usually, an input function should be declared STRICT; if it is not, it will be called with a NULL first parameter when reading a NULL input value\&. The function must still return NULL in this case, unless it raises an error\&. (This case is mainly meant to support domain input functions, which might need to reject NULL inputs\&.) The output function must be declared as taking one argument of the new data type\&. The output function must return type
+cstring\&. Output functions are not invoked for NULL values\&.
+.PP
+The optional
+\fIreceive_function\fR
+converts the type\*(Aqs external binary representation to the internal representation\&. If this function is not supplied, the type cannot participate in binary input\&. The binary representation should be chosen to be cheap to convert to internal form, while being reasonably portable\&. (For example, the standard integer data types use network byte order as the external binary representation, while the internal representation is in the machine\*(Aqs native byte order\&.) The receive function should perform adequate checking to ensure that the value is valid\&. The receive function can be declared as taking one argument of type
+internal, or as taking three arguments of types
+internal,
+oid,
+integer\&. The first argument is a pointer to a
+StringInfo
+buffer holding the received byte string; the optional arguments are the same as for the text input function\&. The receive function must return a value of the data type itself\&. Usually, a receive function should be declared STRICT; if it is not, it will be called with a NULL first parameter when reading a NULL input value\&. The function must still return NULL in this case, unless it raises an error\&. (This case is mainly meant to support domain receive functions, which might need to reject NULL inputs\&.) Similarly, the optional
+\fIsend_function\fR
+converts from the internal representation to the external binary representation\&. If this function is not supplied, the type cannot participate in binary output\&. The send function must be declared as taking one argument of the new data type\&. The send function must return type
+bytea\&. Send functions are not invoked for NULL values\&.
+.PP
+You should at this point be wondering how the input and output functions can be declared to have results or arguments of the new type, when they have to be created before the new type can be created\&. The answer is that the type should first be defined as a
+shell type, which is a placeholder type that has no properties except a name and an owner\&. This is done by issuing the command
+CREATE TYPE \fIname\fR, with no additional parameters\&. Then the C I/O functions can be defined referencing the shell type\&. Finally,
+\fBCREATE TYPE\fR
+with a full definition replaces the shell entry with a complete, valid type definition, after which the new type can be used normally\&.
+.PP
+The optional
+\fItype_modifier_input_function\fR
+and
+\fItype_modifier_output_function\fR
+are needed if the type supports modifiers, that is optional constraints attached to a type declaration, such as
+char(5)
+or
+numeric(30,2)\&.
+PostgreSQL
+allows user\-defined types to take one or more simple constants or identifiers as modifiers\&. However, this information must be capable of being packed into a single non\-negative integer value for storage in the system catalogs\&. The
+\fItype_modifier_input_function\fR
+is passed the declared modifier(s) in the form of a
+cstring
+array\&. It must check the values for validity (throwing an error if they are wrong), and if they are correct, return a single non\-negative
+integer
+value that will be stored as the column
+\(lqtypmod\(rq\&. Type modifiers will be rejected if the type does not have a
+\fItype_modifier_input_function\fR\&. The
+\fItype_modifier_output_function\fR
+converts the internal integer typmod value back to the correct form for user display\&. It must return a
+cstring
+value that is the exact string to append to the type name; for example
+numeric\*(Aqs function might return
+(30,2)\&. It is allowed to omit the
+\fItype_modifier_output_function\fR, in which case the default display format is just the stored typmod integer value enclosed in parentheses\&.
+.PP
+The optional
+\fIanalyze_function\fR
+performs type\-specific statistics collection for columns of the data type\&. By default,
+\fBANALYZE\fR
+will attempt to gather statistics using the type\*(Aqs
+\(lqequals\(rq
+and
+\(lqless\-than\(rq
+operators, if there is a default b\-tree operator class for the type\&. For non\-scalar types this behavior is likely to be unsuitable, so it can be overridden by specifying a custom analysis function\&. The analysis function must be declared to take a single argument of type
+internal, and return a
+boolean
+result\&. The detailed API for analysis functions appears in
+src/include/commands/vacuum\&.h\&.
+.PP
+The optional
+\fIsubscript_function\fR
+allows the data type to be subscripted in SQL commands\&. Specifying this function does not cause the type to be considered a
+\(lqtrue\(rq
+array type; for example, it will not be a candidate for the result type of
+ARRAY[]
+constructs\&. But if subscripting a value of the type is a natural notation for extracting data from it, then a
+\fIsubscript_function\fR
+can be written to define what that means\&. The subscript function must be declared to take a single argument of type
+internal, and return an
+internal
+result, which is a pointer to a struct of methods (functions) that implement subscripting\&. The detailed API for subscript functions appears in
+src/include/nodes/subscripting\&.h\&. It may also be useful to read the array implementation in
+src/backend/utils/adt/arraysubs\&.c, or the simpler code in
+contrib/hstore/hstore_subs\&.c\&. Additional information appears in
+Array Types
+below\&.
+.PP
+While the details of the new type\*(Aqs internal representation are only known to the I/O functions and other functions you create to work with the type, there are several properties of the internal representation that must be declared to
+PostgreSQL\&. Foremost of these is
+\fIinternallength\fR\&. Base data types can be fixed\-length, in which case
+\fIinternallength\fR
+is a positive integer, or variable\-length, indicated by setting
+\fIinternallength\fR
+to
+VARIABLE\&. (Internally, this is represented by setting
+typlen
+to \-1\&.) The internal representation of all variable\-length types must start with a 4\-byte integer giving the total length of this value of the type\&. (Note that the length field is often encoded, as described in
+Section\ \&73.2; it\*(Aqs unwise to access it directly\&.)
+.PP
+The optional flag
+PASSEDBYVALUE
+indicates that values of this data type are passed by value, rather than by reference\&. Types passed by value must be fixed\-length, and their internal representation cannot be larger than the size of the
+Datum
+type (4 bytes on some machines, 8 bytes on others)\&.
+.PP
+The
+\fIalignment\fR
+parameter specifies the storage alignment required for the data type\&. The allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries\&. Note that variable\-length types must have an alignment of at least 4, since they necessarily contain an
+int4
+as their first component\&.
+.PP
+The
+\fIstorage\fR
+parameter allows selection of storage strategies for variable\-length data types\&. (Only
+plain
+is allowed for fixed\-length types\&.)
+plain
+specifies that data of the type will always be stored in\-line and not compressed\&.
+extended
+specifies that the system will first try to compress a long data value, and will move the value out of the main table row if it\*(Aqs still too long\&.
+external
+allows the value to be moved out of the main table, but the system will not try to compress it\&.
+main
+allows compression, but discourages moving the value out of the main table\&. (Data items with this storage strategy might still be moved out of the main table if there is no other way to make a row fit, but they will be kept in the main table preferentially over
+extended
+and
+external
+items\&.)
+.PP
+All
+\fIstorage\fR
+values other than
+plain
+imply that the functions of the data type can handle values that have been
+toasted, as described in
+Section\ \&73.2
+and
+Section\ \&38.13.1\&. The specific other value given merely determines the default TOAST storage strategy for columns of a toastable data type; users can pick other strategies for individual columns using
+ALTER TABLE SET STORAGE\&.
+.PP
+The
+\fIlike_type\fR
+parameter provides an alternative method for specifying the basic representation properties of a data type: copy them from some existing type\&. The values of
+\fIinternallength\fR,
+\fIpassedbyvalue\fR,
+\fIalignment\fR, and
+\fIstorage\fR
+are copied from the named type\&. (It is possible, though usually undesirable, to override some of these values by specifying them along with the
+LIKE
+clause\&.) Specifying representation this way is especially useful when the low\-level implementation of the new type
+\(lqpiggybacks\(rq
+on an existing type in some fashion\&.
+.PP
+The
+\fIcategory\fR
+and
+\fIpreferred\fR
+parameters can be used to help control which implicit cast will be applied in ambiguous situations\&. Each data type belongs to a category named by a single ASCII character, and each type is either
+\(lqpreferred\(rq
+or not within its category\&. The parser will prefer casting to preferred types (but only from other types within the same category) when this rule is helpful in resolving overloaded functions or operators\&. For more details see
+Chapter\ \&10\&. For types that have no implicit casts to or from any other types, it is sufficient to leave these settings at the defaults\&. However, for a group of related types that have implicit casts, it is often helpful to mark them all as belonging to a category and select one or two of the
+\(lqmost general\(rq
+types as being preferred within the category\&. The
+\fIcategory\fR
+parameter is especially useful when adding a user\-defined type to an existing built\-in category, such as the numeric or string types\&. However, it is also possible to create new entirely\-user\-defined type categories\&. Select any ASCII character other than an upper\-case letter to name such a category\&.
+.PP
+A default value can be specified, in case a user wants columns of the data type to default to something other than the null value\&. Specify the default with the
+DEFAULT
+key word\&. (Such a default can be overridden by an explicit
+DEFAULT
+clause attached to a particular column\&.)
+.PP
+To indicate that a type is a fixed\-length array type, specify the type of the array elements using the
+ELEMENT
+key word\&. For example, to define an array of 4\-byte integers (int4), specify
+ELEMENT = int4\&. For more details, see
+Array Types
+below\&.
+.PP
+To indicate the delimiter to be used between values in the external representation of arrays of this type,
+\fIdelimiter\fR
+can be set to a specific character\&. The default delimiter is the comma (,)\&. Note that the delimiter is associated with the array element type, not the array type itself\&.
+.PP
+If the optional Boolean parameter
+\fIcollatable\fR
+is true, column definitions and expressions of the type may carry collation information through use of the
+COLLATE
+clause\&. It is up to the implementations of the functions operating on the type to actually make use of the collation information; this does not happen automatically merely by marking the type collatable\&.
+.SS "Array Types"
+.PP
+Whenever a user\-defined type is created,
+PostgreSQL
+automatically creates an associated array type, whose name consists of the element type\*(Aqs name prepended with an underscore, and truncated if necessary to keep it less than
+NAMEDATALEN
+bytes long\&. (If the name so generated collides with an existing type name, the process is repeated until a non\-colliding name is found\&.) This implicitly\-created array type is variable length and uses the built\-in input and output functions
+array_in
+and
+array_out\&. Furthermore, this type is what the system uses for constructs such as
+ARRAY[]
+over the user\-defined type\&. The array type tracks any changes in its element type\*(Aqs owner or schema, and is dropped if the element type is\&.
+.PP
+You might reasonably ask why there is an
+\fBELEMENT\fR
+option, if the system makes the correct array type automatically\&. The main case where it\*(Aqs useful to use
+\fBELEMENT\fR
+is when you are making a fixed\-length type that happens to be internally an array of a number of identical things, and you want to allow these things to be accessed directly by subscripting, in addition to whatever operations you plan to provide for the type as a whole\&. For example, type
+point
+is represented as just two floating\-point numbers, which can be accessed using
+point[0]
+and
+point[1]\&. Note that this facility only works for fixed\-length types whose internal form is exactly a sequence of identical fixed\-length fields\&. For historical reasons (i\&.e\&., this is clearly wrong but it\*(Aqs far too late to change it), subscripting of fixed\-length array types starts from zero, rather than from one as for variable\-length arrays\&.
+.PP
+Specifying the
+\fBSUBSCRIPT\fR
+option allows a data type to be subscripted, even though the system does not otherwise regard it as an array type\&. The behavior just described for fixed\-length arrays is actually implemented by the
+\fBSUBSCRIPT\fR
+handler function
+\fBraw_array_subscript_handler\fR, which is used automatically if you specify
+\fBELEMENT\fR
+for a fixed\-length type without also writing
+\fBSUBSCRIPT\fR\&.
+.PP
+When specifying a custom
+\fBSUBSCRIPT\fR
+function, it is not necessary to specify
+\fBELEMENT\fR
+unless the
+\fBSUBSCRIPT\fR
+handler function needs to consult
+typelem
+to find out what to return\&. Be aware that specifying
+\fBELEMENT\fR
+causes the system to assume that the new type contains, or is somehow physically dependent on, the element type; thus for example changing properties of the element type won\*(Aqt be allowed if there are any columns of the dependent type\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of a type to be created\&.
+.RE
+.PP
+\fIattribute_name\fR
+.RS 4
+The name of an attribute (column) for the composite type\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The name of an existing data type to become a column of the composite type\&.
+.RE
+.PP
+\fIcollation\fR
+.RS 4
+The name of an existing collation to be associated with a column of a composite type, or with a range type\&.
+.RE
+.PP
+\fIlabel\fR
+.RS 4
+A string literal representing the textual label associated with one value of an enum type\&.
+.RE
+.PP
+\fIsubtype\fR
+.RS 4
+The name of the element type that the range type will represent ranges of\&.
+.RE
+.PP
+\fIsubtype_operator_class\fR
+.RS 4
+The name of a b\-tree operator class for the subtype\&.
+.RE
+.PP
+\fIcanonical_function\fR
+.RS 4
+The name of the canonicalization function for the range type\&.
+.RE
+.PP
+\fIsubtype_diff_function\fR
+.RS 4
+The name of a difference function for the subtype\&.
+.RE
+.PP
+\fImultirange_type_name\fR
+.RS 4
+The name of the corresponding multirange type\&.
+.RE
+.PP
+\fIinput_function\fR
+.RS 4
+The name of a function that converts data from the type\*(Aqs external textual form to its internal form\&.
+.RE
+.PP
+\fIoutput_function\fR
+.RS 4
+The name of a function that converts data from the type\*(Aqs internal form to its external textual form\&.
+.RE
+.PP
+\fIreceive_function\fR
+.RS 4
+The name of a function that converts data from the type\*(Aqs external binary form to its internal form\&.
+.RE
+.PP
+\fIsend_function\fR
+.RS 4
+The name of a function that converts data from the type\*(Aqs internal form to its external binary form\&.
+.RE
+.PP
+\fItype_modifier_input_function\fR
+.RS 4
+The name of a function that converts an array of modifier(s) for the type into internal form\&.
+.RE
+.PP
+\fItype_modifier_output_function\fR
+.RS 4
+The name of a function that converts the internal form of the type\*(Aqs modifier(s) to external textual form\&.
+.RE
+.PP
+\fIanalyze_function\fR
+.RS 4
+The name of a function that performs statistical analysis for the data type\&.
+.RE
+.PP
+\fIsubscript_function\fR
+.RS 4
+The name of a function that defines what subscripting a value of the data type does\&.
+.RE
+.PP
+\fIinternallength\fR
+.RS 4
+A numeric constant that specifies the length in bytes of the new type\*(Aqs internal representation\&. The default assumption is that it is variable\-length\&.
+.RE
+.PP
+\fIalignment\fR
+.RS 4
+The storage alignment requirement of the data type\&. If specified, it must be
+char,
+int2,
+int4, or
+double; the default is
+int4\&.
+.RE
+.PP
+\fIstorage\fR
+.RS 4
+The storage strategy for the data type\&. If specified, must be
+plain,
+external,
+extended, or
+main; the default is
+plain\&.
+.RE
+.PP
+\fIlike_type\fR
+.RS 4
+The name of an existing data type that the new type will have the same representation as\&. The values of
+\fIinternallength\fR,
+\fIpassedbyvalue\fR,
+\fIalignment\fR, and
+\fIstorage\fR
+are copied from that type, unless overridden by explicit specification elsewhere in this
+\fBCREATE TYPE\fR
+command\&.
+.RE
+.PP
+\fIcategory\fR
+.RS 4
+The category code (a single ASCII character) for this type\&. The default is
+\*(AqU\*(Aq
+for
+\(lquser\-defined type\(rq\&. Other standard category codes can be found in
+Table\ \&53.65\&. You may also choose other ASCII characters in order to create custom categories\&.
+.RE
+.PP
+\fIpreferred\fR
+.RS 4
+True if this type is a preferred type within its type category, else false\&. The default is false\&. Be very careful about creating a new preferred type within an existing type category, as this could cause surprising changes in behavior\&.
+.RE
+.PP
+\fIdefault\fR
+.RS 4
+The default value for the data type\&. If this is omitted, the default is null\&.
+.RE
+.PP
+\fIelement\fR
+.RS 4
+The type being created is an array; this specifies the type of the array elements\&.
+.RE
+.PP
+\fIdelimiter\fR
+.RS 4
+The delimiter character to be used between values in arrays made of this type\&.
+.RE
+.PP
+\fIcollatable\fR
+.RS 4
+True if this type\*(Aqs operations can use collation information\&. The default is false\&.
+.RE
+.SH "NOTES"
+.PP
+Because there are no restrictions on use of a data type once it\*(Aqs been created, creating a base type or range type is tantamount to granting public execute permission on the functions mentioned in the type definition\&. This is usually not an issue for the sorts of functions that are useful in a type definition\&. But you might want to think twice before designing a type in a way that would require
+\(lqsecret\(rq
+information to be used while converting it to or from external form\&.
+.PP
+Before
+PostgreSQL
+version 8\&.3, the name of a generated array type was always exactly the element type\*(Aqs name with one underscore character (_) prepended\&. (Type names were therefore restricted in length to one fewer character than other names\&.) While this is still usually the case, the array type name may vary from this in case of maximum\-length names or collisions with user type names that begin with underscore\&. Writing code that depends on this convention is therefore deprecated\&. Instead, use
+pg_type\&.typarray
+to locate the array type associated with a given type\&.
+.PP
+It may be advisable to avoid using type and table names that begin with underscore\&. While the server will change generated array type names to avoid collisions with user\-given names, there is still risk of confusion, particularly with old client software that may assume that type names beginning with underscores always represent arrays\&.
+.PP
+Before
+PostgreSQL
+version 8\&.2, the shell\-type creation syntax
+CREATE TYPE \fIname\fR
+did not exist\&. The way to create a new base type was to create its input function first\&. In this approach,
+PostgreSQL
+will first see the name of the new data type as the return type of the input function\&. The shell type is implicitly created in this situation, and then it can be referenced in the definitions of the remaining I/O functions\&. This approach still works, but is deprecated and might be disallowed in some future release\&. Also, to avoid accidentally cluttering the catalogs with shell types as a result of simple typos in function definitions, a shell type will only be made this way when the input function is written in C\&.
+.SH "EXAMPLES"
+.PP
+This example creates a composite type and uses it in a function definition:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE compfoo AS (f1 int, f2 text);
+
+CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
+ SELECT fooid, fooname FROM foo
+$$ LANGUAGE SQL;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example creates an enumerated type and uses it in a table definition:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE bug_status AS ENUM (\*(Aqnew\*(Aq, \*(Aqopen\*(Aq, \*(Aqclosed\*(Aq);
+
+CREATE TABLE bug (
+ id serial,
+ description text,
+ status bug_status
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example creates a range type:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example creates the base data type
+box
+and then uses the type in a table definition:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE box;
+
+CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS \&.\&.\&. ;
+CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS \&.\&.\&. ;
+
+CREATE TYPE box (
+ INTERNALLENGTH = 16,
+ INPUT = my_box_in_function,
+ OUTPUT = my_box_out_function
+);
+
+CREATE TABLE myboxes (
+ id integer,
+ description box
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+If the internal structure of
+box
+were an array of four
+float4
+elements, we might instead use:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE box (
+ INTERNALLENGTH = 16,
+ INPUT = my_box_in_function,
+ OUTPUT = my_box_out_function,
+ ELEMENT = float4
+);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+which would allow a box value\*(Aqs component numbers to be accessed by subscripting\&. Otherwise the type behaves the same as before\&.
+.PP
+This example creates a large object type and uses it in a table definition:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE TYPE bigobj (
+ INPUT = lo_filein, OUTPUT = lo_fileout,
+ INTERNALLENGTH = VARIABLE
+);
+CREATE TABLE big_objs (
+ id integer,
+ obj bigobj
+);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+More examples, including suitable input and output functions, are in
+Section\ \&38.13\&.
+.SH "COMPATIBILITY"
+.PP
+The first form of the
+\fBCREATE TYPE\fR
+command, which creates a composite type, conforms to the
+SQL
+standard\&. The other forms are
+PostgreSQL
+extensions\&. The
+\fBCREATE TYPE\fR
+statement in the
+SQL
+standard also defines other forms that are not implemented in
+PostgreSQL\&.
+.PP
+The ability to create a composite type with zero attributes is a
+PostgreSQL\-specific deviation from the standard (analogous to the same case in
+\fBCREATE TABLE\fR)\&.
+.SH "SEE ALSO"
+ALTER TYPE (\fBALTER_TYPE\fR(7)), CREATE DOMAIN (\fBCREATE_DOMAIN\fR(7)), CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)), DROP TYPE (\fBDROP_TYPE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_USER.7 b/doc/src/sgml/man7/CREATE_USER.7
new file mode 100644
index 0000000..c826e2f
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_USER.7
@@ -0,0 +1,75 @@
+'\" t
+.\" Title: CREATE USER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE USER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_USER \- define a new database role
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE USER \fIname\fR [ [ WITH ] \fIoption\fR [ \&.\&.\&. ] ]
+
+where \fIoption\fR can be:
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT \fIconnlimit\fR
+ | [ ENCRYPTED ] PASSWORD \*(Aq\fIpassword\fR\*(Aq | PASSWORD NULL
+ | VALID UNTIL \*(Aq\fItimestamp\fR\*(Aq
+ | IN ROLE \fIrole_name\fR [, \&.\&.\&.]
+ | IN GROUP \fIrole_name\fR [, \&.\&.\&.]
+ | ROLE \fIrole_name\fR [, \&.\&.\&.]
+ | ADMIN \fIrole_name\fR [, \&.\&.\&.]
+ | USER \fIrole_name\fR [, \&.\&.\&.]
+ | SYSID \fIuid\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE USER\fR
+is now an alias for
+\fBCREATE ROLE\fR\&. The only difference is that when the command is spelled
+\fBCREATE USER\fR,
+LOGIN
+is assumed by default, whereas
+NOLOGIN
+is assumed when the command is spelled
+\fBCREATE ROLE\fR\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBCREATE USER\fR
+statement is a
+PostgreSQL
+extension\&. The SQL standard leaves the definition of users to the implementation\&.
+.SH "SEE ALSO"
+CREATE ROLE (\fBCREATE_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_USER_MAPPING.7 b/doc/src/sgml/man7/CREATE_USER_MAPPING.7
new file mode 100644
index 0000000..ec62977
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_USER_MAPPING.7
@@ -0,0 +1,94 @@
+'\" t
+.\" Title: CREATE USER MAPPING
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE USER MAPPING" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_USER_MAPPING \- define a new mapping of a user to a foreign server
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE USER MAPPING [ IF NOT EXISTS ] FOR { \fIuser_name\fR | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC }
+ SERVER \fIserver_name\fR
+ [ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [ , \&.\&.\&. ] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE USER MAPPING\fR
+defines a mapping of a user to a foreign server\&. A user mapping typically encapsulates connection information that a foreign\-data wrapper uses together with the information encapsulated by a foreign server to access an external data resource\&.
+.PP
+The owner of a foreign server can create user mappings for that server for any user\&. Also, a user can create a user mapping for their own user name if
+USAGE
+privilege on the server has been granted to the user\&.
+.SH "PARAMETERS"
+.PP
+IF NOT EXISTS
+.RS 4
+Do not throw an error if a mapping of the given user to the given foreign server already exists\&. A notice is issued in this case\&. Note that there is no guarantee that the existing user mapping is anything like the one that would have been created\&.
+.RE
+.PP
+\fIuser_name\fR
+.RS 4
+The name of an existing user that is mapped to foreign server\&.
+CURRENT_ROLE,
+CURRENT_USER, and
+USER
+match the name of the current user\&. When
+PUBLIC
+is specified, a so\-called public mapping is created that is used when no user\-specific mapping is applicable\&.
+.RE
+.PP
+\fIserver_name\fR
+.RS 4
+The name of an existing server for which the user mapping is to be created\&.
+.RE
+.PP
+OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] )
+.RS 4
+This clause specifies the options of the user mapping\&. The options typically define the actual user name and password of the mapping\&. Option names must be unique\&. The allowed option names and values are specific to the server\*(Aqs foreign\-data wrapper\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Create a user mapping for user
+bob, server
+foo:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE USER MAPPING FOR bob SERVER foo OPTIONS (user \*(Aqbob\*(Aq, password \*(Aqsecret\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE USER MAPPING\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&.
+.SH "SEE ALSO"
+ALTER USER MAPPING (\fBALTER_USER_MAPPING\fR(7)), DROP USER MAPPING (\fBDROP_USER_MAPPING\fR(7)), CREATE FOREIGN DATA WRAPPER (\fBCREATE_FOREIGN_DATA_WRAPPER\fR(7)), CREATE SERVER (\fBCREATE_SERVER\fR(7))
diff --git a/doc/src/sgml/man7/CREATE_VIEW.7 b/doc/src/sgml/man7/CREATE_VIEW.7
new file mode 100644
index 0000000..519a9be
--- /dev/null
+++ b/doc/src/sgml/man7/CREATE_VIEW.7
@@ -0,0 +1,545 @@
+'\" t
+.\" Title: CREATE VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "CREATE VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+CREATE_VIEW \- define a new view
+.SH "SYNOPSIS"
+.sp
+.nf
+CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW \fIname\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ [ WITH ( \fIview_option_name\fR [= \fIview_option_value\fR] [, \&.\&.\&. ] ) ]
+ AS \fIquery\fR
+ [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBCREATE VIEW\fR
+defines a view of a query\&. The view is not physically materialized\&. Instead, the query is run every time the view is referenced in a query\&.
+.PP
+\fBCREATE OR REPLACE VIEW\fR
+is similar, but if a view of the same name already exists, it is replaced\&. The new query must generate the same columns that were generated by the existing view query (that is, the same column names in the same order and with the same data types), but it may add additional columns to the end of the list\&. The calculations giving rise to the output columns may be completely different\&.
+.PP
+If a schema name is given (for example,
+CREATE VIEW myschema\&.myview \&.\&.\&.) then the view is created in the specified schema\&. Otherwise it is created in the current schema\&. Temporary views exist in a special schema, so a schema name cannot be given when creating a temporary view\&. The name of the view must be distinct from the name of any other relation (table, sequence, index, view, materialized view, or foreign table) in the same schema\&.
+.SH "PARAMETERS"
+.PP
+TEMPORARY or TEMP
+.RS 4
+If specified, the view is created as a temporary view\&. Temporary views are automatically dropped at the end of the current session\&. Existing permanent relations with the same name are not visible to the current session while the temporary view exists, unless they are referenced with schema\-qualified names\&.
+.sp
+If any of the tables referenced by the view are temporary, the view is created as a temporary view (whether
+TEMPORARY
+is specified or not)\&.
+.RE
+.PP
+RECURSIVE
+.RS 4
+Creates a recursive view\&. The syntax
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE RECURSIVE VIEW [ \fIschema\fR \&. ] \fIview_name\fR (\fIcolumn_names\fR) AS SELECT \fI\&.\&.\&.\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+is equivalent to
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW [ \fIschema\fR \&. ] \fIview_name\fR AS WITH RECURSIVE \fIview_name\fR (\fIcolumn_names\fR) AS (SELECT \fI\&.\&.\&.\fR) SELECT \fIcolumn_names\fR FROM \fIview_name\fR;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A view column name list must be specified for a recursive view\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of a view to be created\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+An optional list of names to be used for columns of the view\&. If not given, the column names are deduced from the query\&.
+.RE
+.PP
+WITH ( \fIview_option_name\fR [= \fIview_option_value\fR] [, \&.\&.\&. ] )
+.RS 4
+This clause specifies optional parameters for a view; the following parameters are supported:
+.PP
+check_option (enum)
+.RS 4
+This parameter may be either
+local
+or
+cascaded, and is equivalent to specifying
+WITH [ CASCADED | LOCAL ] CHECK OPTION
+(see below)\&.
+.RE
+.PP
+security_barrier (boolean)
+.RS 4
+This should be used if the view is intended to provide row\-level security\&. See
+Section\ \&41.5
+for full details\&.
+.RE
+.PP
+security_invoker (boolean)
+.RS 4
+This option causes the underlying base relations to be checked against the privileges of the user of the view rather than the view owner\&. See the notes below for full details\&.
+.RE
+.sp
+All of the above options can be changed on existing views using
+\fBALTER VIEW\fR\&.
+.RE
+.PP
+\fIquery\fR
+.RS 4
+A
+\fBSELECT\fR
+or
+\fBVALUES\fR
+command which will provide the columns and rows of the view\&.
+.RE
+.PP
+WITH [ CASCADED | LOCAL ] CHECK OPTION
+.RS 4
+This option controls the behavior of automatically updatable views\&. When this option is specified,
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+commands on the view will be checked to ensure that new rows satisfy the view\-defining condition (that is, the new rows are checked to ensure that they are visible through the view)\&. If they are not, the update will be rejected\&. If the
+CHECK OPTION
+is not specified,
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+commands on the view are allowed to create rows that are not visible through the view\&. The following check options are supported:
+.PP
+LOCAL
+.RS 4
+New rows are only checked against the conditions defined directly in the view itself\&. Any conditions defined on underlying base views are not checked (unless they also specify the
+CHECK OPTION)\&.
+.RE
+.PP
+CASCADED
+.RS 4
+New rows are checked against the conditions of the view and all underlying base views\&. If the
+CHECK OPTION
+is specified, and neither
+LOCAL
+nor
+CASCADED
+is specified, then
+CASCADED
+is assumed\&.
+.RE
+.sp
+The
+CHECK OPTION
+may not be used with
+RECURSIVE
+views\&.
+.sp
+Note that the
+CHECK OPTION
+is only supported on views that are automatically updatable, and do not have
+INSTEAD OF
+triggers or
+INSTEAD
+rules\&. If an automatically updatable view is defined on top of a base view that has
+INSTEAD OF
+triggers, then the
+LOCAL CHECK OPTION
+may be used to check the conditions on the automatically updatable view, but the conditions on the base view with
+INSTEAD OF
+triggers will not be checked (a cascaded check option will not cascade down to a trigger\-updatable view, and any check options defined directly on a trigger\-updatable view will be ignored)\&. If the view or any of its base relations has an
+INSTEAD
+rule that causes the
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+command to be rewritten, then all check options will be ignored in the rewritten query, including any checks from automatically updatable views defined on top of the relation with the
+INSTEAD
+rule\&.
+.RE
+.SH "NOTES"
+.PP
+Use the
+\fBDROP VIEW\fR
+statement to drop views\&.
+.PP
+Be careful that the names and types of the view\*(Aqs columns will be assigned the way you want\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW vista AS SELECT \*(AqHello World\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+is bad form because the column name defaults to
+?column?; also, the column data type defaults to
+text, which might not be what you wanted\&. Better style for a string literal in a view\*(Aqs result is something like:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW vista AS SELECT text \*(AqHello World\*(Aq AS hello;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+By default, access to the underlying base relations referenced in the view is determined by the permissions of the view owner\&. In some cases, this can be used to provide secure but restricted access to the underlying tables\&. However, not all views are secure against tampering; see
+Section\ \&41.5
+for details\&.
+.PP
+If the view has the
+security_invoker
+property set to
+true, access to the underlying base relations is determined by the permissions of the user executing the query, rather than the view owner\&. Thus, the user of a security invoker view must have the relevant permissions on the view and its underlying base relations\&.
+.PP
+If any of the underlying base relations is a security invoker view, it will be treated as if it had been accessed directly from the original query\&. Thus, a security invoker view will always check its underlying base relations using the permissions of the current user, even if it is accessed from a view without the
+security_invoker
+property\&.
+.PP
+If any of the underlying base relations has
+row\-level security
+enabled, then by default, the row\-level security policies of the view owner are applied, and access to any additional relations referred to by those policies is determined by the permissions of the view owner\&. However, if the view has
+security_invoker
+set to
+true, then the policies and permissions of the invoking user are used instead, as if the base relations had been referenced directly from the query using the view\&.
+.PP
+Functions called in the view are treated the same as if they had been called directly from the query using the view\&. Therefore, the user of a view must have permissions to call all functions used by the view\&. Functions in the view are executed with the privileges of the user executing the query or the function owner, depending on whether the functions are defined as
+SECURITY INVOKER
+or
+SECURITY DEFINER\&. Thus, for example, calling
+CURRENT_USER
+directly in a view will always return the invoking user, not the view owner\&. This is not affected by the view\*(Aqs
+security_invoker
+setting, and so a view with
+security_invoker
+set to
+false
+is
+\fInot\fR
+equivalent to a
+SECURITY DEFINER
+function and those concepts should not be confused\&.
+.PP
+The user creating or replacing a view must have
+USAGE
+privileges on any schemas referred to in the view query, in order to look up the referenced objects in those schemas\&. Note, however, that this lookup only happens when the view is created or replaced\&. Therefore, the user of the view only requires the
+USAGE
+privilege on the schema containing the view, not on the schemas referred to in the view query, even for a security invoker view\&.
+.PP
+When
+\fBCREATE OR REPLACE VIEW\fR
+is used on an existing view, only the view\*(Aqs defining SELECT rule, plus any
+WITH ( \&.\&.\&. )
+parameters and its
+CHECK OPTION
+are changed\&. Other view properties, including ownership, permissions, and non\-SELECT rules, remain unchanged\&. You must own the view to replace it (this includes being a member of the owning role)\&.
+.SS "Updatable Views"
+.PP
+Simple views are automatically updatable: the system will allow
+\fBINSERT\fR,
+\fBUPDATE\fR
+and
+\fBDELETE\fR
+statements to be used on the view in the same way as on a regular table\&. A view is automatically updatable if it satisfies all of the following conditions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The view must have exactly one entry in its
+FROM
+list, which must be a table or another updatable view\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The view definition must not contain
+WITH,
+DISTINCT,
+GROUP BY,
+HAVING,
+LIMIT, or
+OFFSET
+clauses at the top level\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The view definition must not contain set operations (UNION,
+INTERSECT
+or
+EXCEPT) at the top level\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The view\*(Aqs select list must not contain any aggregates, window functions or set\-returning functions\&.
+.RE
+.PP
+An automatically updatable view may contain a mix of updatable and non\-updatable columns\&. A column is updatable if it is a simple reference to an updatable column of the underlying base relation; otherwise the column is read\-only, and an error will be raised if an
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+statement attempts to assign a value to it\&.
+.PP
+If the view is automatically updatable the system will convert any
+\fBINSERT\fR,
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+statement on the view into the corresponding statement on the underlying base relation\&.
+\fBINSERT\fR
+statements that have an
+ON CONFLICT UPDATE
+clause are fully supported\&.
+.PP
+If an automatically updatable view contains a
+WHERE
+condition, the condition restricts which rows of the base relation are available to be modified by
+\fBUPDATE\fR
+and
+\fBDELETE\fR
+statements on the view\&. However, an
+\fBUPDATE\fR
+is allowed to change a row so that it no longer satisfies the
+WHERE
+condition, and thus is no longer visible through the view\&. Similarly, an
+\fBINSERT\fR
+command can potentially insert base\-relation rows that do not satisfy the
+WHERE
+condition and thus are not visible through the view (ON CONFLICT UPDATE
+may similarly affect an existing row not visible through the view)\&. The
+CHECK OPTION
+may be used to prevent
+\fBINSERT\fR
+and
+\fBUPDATE\fR
+commands from creating such rows that are not visible through the view\&.
+.PP
+If an automatically updatable view is marked with the
+security_barrier
+property then all the view\*(Aqs
+WHERE
+conditions (and any conditions using operators which are marked as
+LEAKPROOF) will always be evaluated before any conditions that a user of the view has added\&. See
+Section\ \&41.5
+for full details\&. Note that, due to this, rows which are not ultimately returned (because they do not pass the user\*(Aqs
+WHERE
+conditions) may still end up being locked\&.
+\fBEXPLAIN\fR
+can be used to see which conditions are applied at the relation level (and therefore do not lock rows) and which are not\&.
+.PP
+A more complex view that does not satisfy all these conditions is read\-only by default: the system will not allow an insert, update, or delete on the view\&. You can get the effect of an updatable view by creating
+INSTEAD OF
+triggers on the view, which must convert attempted inserts, etc\&. on the view into appropriate actions on other tables\&. For more information see
+CREATE TRIGGER (\fBCREATE_TRIGGER\fR(7))\&. Another possibility is to create rules (see
+CREATE RULE (\fBCREATE_RULE\fR(7))), but in practice triggers are easier to understand and use correctly\&.
+.PP
+Note that the user performing the insert, update or delete on the view must have the corresponding insert, update or delete privilege on the view\&. In addition, by default, the view\*(Aqs owner must have the relevant privileges on the underlying base relations, whereas the user performing the update does not need any permissions on the underlying base relations (see
+Section\ \&41.5)\&. However, if the view has
+security_invoker
+set to
+true, the user performing the update, rather than the view owner, must have the relevant privileges on the underlying base relations\&.
+.SH "EXAMPLES"
+.PP
+Create a view consisting of all comedy films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW comedies AS
+ SELECT *
+ FROM films
+ WHERE kind = \*(AqComedy\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This will create a view containing the columns that are in the
+film
+table at the time of view creation\&. Though
+*
+was used to create the view, columns added later to the table will not be part of the view\&.
+.PP
+Create a view with
+LOCAL CHECK OPTION:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW universal_comedies AS
+ SELECT *
+ FROM comedies
+ WHERE classification = \*(AqU\*(Aq
+ WITH LOCAL CHECK OPTION;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This will create a view based on the
+comedies
+view, showing only films with
+kind = \*(AqComedy\*(Aq
+and
+classification = \*(AqU\*(Aq\&. Any attempt to
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+a row in the view will be rejected if the new row doesn\*(Aqt have
+classification = \*(AqU\*(Aq, but the film
+kind
+will not be checked\&.
+.PP
+Create a view with
+CASCADED CHECK OPTION:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW pg_comedies AS
+ SELECT *
+ FROM comedies
+ WHERE classification = \*(AqPG\*(Aq
+ WITH CASCADED CHECK OPTION;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This will create a view that checks both the
+kind
+and
+classification
+of new rows\&.
+.PP
+Create a view with a mix of updatable and non\-updatable columns:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE VIEW comedies AS
+ SELECT f\&.*,
+ country_code_to_name(f\&.country_code) AS country,
+ (SELECT avg(r\&.rating)
+ FROM user_ratings r
+ WHERE r\&.film_id = f\&.id) AS avg_rating
+ FROM films f
+ WHERE f\&.kind = \*(AqComedy\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This view will support
+\fBINSERT\fR,
+\fBUPDATE\fR
+and
+\fBDELETE\fR\&. All the columns from the
+films
+table will be updatable, whereas the computed columns
+country
+and
+avg_rating
+will be read\-only\&.
+.PP
+Create a recursive view consisting of the numbers from 1 to 100:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE RECURSIVE VIEW public\&.nums_1_100 (n) AS
+ VALUES (1)
+UNION ALL
+ SELECT n+1 FROM nums_1_100 WHERE n < 100;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Notice that although the recursive view\*(Aqs name is schema\-qualified in this
+\fBCREATE\fR, its internal self\-reference is not schema\-qualified\&. This is because the implicitly\-created CTE\*(Aqs name cannot be schema\-qualified\&.
+.SH "COMPATIBILITY"
+.PP
+\fBCREATE OR REPLACE VIEW\fR
+is a
+PostgreSQL
+language extension\&. So is the concept of a temporary view\&. The
+WITH ( \&.\&.\&. )
+clause is an extension as well, as are security barrier views and security invoker views\&.
+.SH "SEE ALSO"
+ALTER VIEW (\fBALTER_VIEW\fR(7)), DROP VIEW (\fBDROP_VIEW\fR(7)), CREATE MATERIALIZED VIEW (\fBCREATE_MATERIALIZED_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/DEALLOCATE.7 b/doc/src/sgml/man7/DEALLOCATE.7
new file mode 100644
index 0000000..6871b07
--- /dev/null
+++ b/doc/src/sgml/man7/DEALLOCATE.7
@@ -0,0 +1,66 @@
+'\" t
+.\" Title: DEALLOCATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DEALLOCATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DEALLOCATE \- deallocate a prepared statement
+.SH "SYNOPSIS"
+.sp
+.nf
+DEALLOCATE [ PREPARE ] { \fIname\fR | ALL }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDEALLOCATE\fR
+is used to deallocate a previously prepared SQL statement\&. If you do not explicitly deallocate a prepared statement, it is deallocated when the session ends\&.
+.PP
+For more information on prepared statements, see
+\fBPREPARE\fR(7)\&.
+.SH "PARAMETERS"
+.PP
+PREPARE
+.RS 4
+This key word is ignored\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the prepared statement to deallocate\&.
+.RE
+.PP
+ALL
+.RS 4
+Deallocate all prepared statements\&.
+.RE
+.SH "COMPATIBILITY"
+.PP
+The SQL standard includes a
+\fBDEALLOCATE\fR
+statement, but it is only for use in embedded SQL\&.
+.SH "SEE ALSO"
+\fBEXECUTE\fR(7), \fBPREPARE\fR(7)
diff --git a/doc/src/sgml/man7/DECLARE.7 b/doc/src/sgml/man7/DECLARE.7
new file mode 100644
index 0000000..fc23047
--- /dev/null
+++ b/doc/src/sgml/man7/DECLARE.7
@@ -0,0 +1,345 @@
+'\" t
+.\" Title: DECLARE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DECLARE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DECLARE \- define a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+DECLARE \fIname\fR [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
+ CURSOR [ { WITH | WITHOUT } HOLD ] FOR \fIquery\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDECLARE\fR
+allows a user to create cursors, which can be used to retrieve a small number of rows at a time out of a larger query\&. After the cursor is created, rows are fetched from it using
+\fBFETCH\fR\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+This page describes usage of cursors at the SQL command level\&. If you are trying to use cursors inside a
+PL/pgSQL
+function, the rules are different \(em see
+Section\ \&43.7\&.
+.sp .5v
+.RE
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the cursor to be created\&.
+.RE
+.PP
+BINARY
+.RS 4
+Causes the cursor to return data in binary rather than in text format\&.
+.RE
+.PP
+ASENSITIVE
+.br
+INSENSITIVE
+.RS 4
+Cursor sensitivity determines whether changes to the data underlying the cursor, done in the same transaction, after the cursor has been declared, are visible in the cursor\&.
+INSENSITIVE
+means they are not visible,
+ASENSITIVE
+means the behavior is implementation\-dependent\&. A third behavior,
+SENSITIVE, meaning that such changes are visible in the cursor, is not available in
+PostgreSQL\&. In
+PostgreSQL, all cursors are insensitive; so these key words have no effect and are only accepted for compatibility with the SQL standard\&.
+.sp
+Specifying
+INSENSITIVE
+together with
+FOR UPDATE
+or
+FOR SHARE
+is an error\&.
+.RE
+.PP
+SCROLL
+.br
+NO SCROLL
+.RS 4
+SCROLL
+specifies that the cursor can be used to retrieve rows in a nonsequential fashion (e\&.g\&., backward)\&. Depending upon the complexity of the query\*(Aqs execution plan, specifying
+SCROLL
+might impose a performance penalty on the query\*(Aqs execution time\&.
+NO SCROLL
+specifies that the cursor cannot be used to retrieve rows in a nonsequential fashion\&. The default is to allow scrolling in some cases; this is not the same as specifying
+SCROLL\&. See
+Notes
+below for details\&.
+.RE
+.PP
+WITH HOLD
+.br
+WITHOUT HOLD
+.RS 4
+WITH HOLD
+specifies that the cursor can continue to be used after the transaction that created it successfully commits\&.
+WITHOUT HOLD
+specifies that the cursor cannot be used outside of the transaction that created it\&. If neither
+WITHOUT HOLD
+nor
+WITH HOLD
+is specified,
+WITHOUT HOLD
+is the default\&.
+.RE
+.PP
+\fIquery\fR
+.RS 4
+A
+\fBSELECT\fR
+or
+\fBVALUES\fR
+command which will provide the rows to be returned by the cursor\&.
+.RE
+.PP
+The key words
+ASENSITIVE,
+BINARY,
+INSENSITIVE, and
+SCROLL
+can appear in any order\&.
+.SH "NOTES"
+.PP
+Normal cursors return data in text format, the same as a
+\fBSELECT\fR
+would produce\&. The
+BINARY
+option specifies that the cursor should return data in binary format\&. This reduces conversion effort for both the server and client, at the cost of more programmer effort to deal with platform\-dependent binary data formats\&. As an example, if a query returns a value of one from an integer column, you would get a string of
+1
+with a default cursor, whereas with a binary cursor you would get a 4\-byte field containing the internal representation of the value (in big\-endian byte order)\&.
+.PP
+Binary cursors should be used carefully\&. Many applications, including
+psql, are not prepared to handle binary cursors and expect data to come back in the text format\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+When the client application uses the
+\(lqextended query\(rq
+protocol to issue a
+\fBFETCH\fR
+command, the Bind protocol message specifies whether data is to be retrieved in text or binary format\&. This choice overrides the way that the cursor is defined\&. The concept of a binary cursor as such is thus obsolete when using extended query protocol \(em any cursor can be treated as either text or binary\&.
+.sp .5v
+.RE
+.PP
+Unless
+WITH HOLD
+is specified, the cursor created by this command can only be used within the current transaction\&. Thus,
+\fBDECLARE\fR
+without
+WITH HOLD
+is useless outside a transaction block: the cursor would survive only to the completion of the statement\&. Therefore
+PostgreSQL
+reports an error if such a command is used outside a transaction block\&. Use
+\fBBEGIN\fR
+and
+\fBCOMMIT\fR
+(or
+\fBROLLBACK\fR) to define a transaction block\&.
+.PP
+If
+WITH HOLD
+is specified and the transaction that created the cursor successfully commits, the cursor can continue to be accessed by subsequent transactions in the same session\&. (But if the creating transaction is aborted, the cursor is removed\&.) A cursor created with
+WITH HOLD
+is closed when an explicit
+\fBCLOSE\fR
+command is issued on it, or the session ends\&. In the current implementation, the rows represented by a held cursor are copied into a temporary file or memory area so that they remain available for subsequent transactions\&.
+.PP
+WITH HOLD
+may not be specified when the query includes
+FOR UPDATE
+or
+FOR SHARE\&.
+.PP
+The
+SCROLL
+option should be specified when defining a cursor that will be used to fetch backwards\&. This is required by the SQL standard\&. However, for compatibility with earlier versions,
+PostgreSQL
+will allow backward fetches without
+SCROLL, if the cursor\*(Aqs query plan is simple enough that no extra overhead is needed to support it\&. However, application developers are advised not to rely on using backward fetches from a cursor that has not been created with
+SCROLL\&. If
+NO SCROLL
+is specified, then backward fetches are disallowed in any case\&.
+.PP
+Backward fetches are also disallowed when the query includes
+FOR UPDATE
+or
+FOR SHARE; therefore
+SCROLL
+may not be specified in this case\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+Scrollable cursors may give unexpected results if they invoke any volatile functions (see
+Section\ \&38.7)\&. When a previously fetched row is re\-fetched, the functions might be re\-executed, perhaps leading to results different from the first time\&. It\*(Aqs best to specify
+NO SCROLL
+for a query involving volatile functions\&. If that is not practical, one workaround is to declare the cursor
+SCROLL WITH HOLD
+and commit the transaction before reading any rows from it\&. This will force the entire output of the cursor to be materialized in temporary storage, so that volatile functions are executed exactly once for each row\&.
+.sp .5v
+.RE
+.PP
+If the cursor\*(Aqs query includes
+FOR UPDATE
+or
+FOR SHARE, then returned rows are locked at the time they are first fetched, in the same way as for a regular
+\fBSELECT\fR
+command with these options\&. In addition, the returned rows will be the most up\-to\-date versions\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+It is generally recommended to use
+FOR UPDATE
+if the cursor is intended to be used with
+\fBUPDATE \&.\&.\&. WHERE CURRENT OF\fR
+or
+\fBDELETE \&.\&.\&. WHERE CURRENT OF\fR\&. Using
+FOR UPDATE
+prevents other sessions from changing the rows between the time they are fetched and the time they are updated\&. Without
+FOR UPDATE, a subsequent
+WHERE CURRENT OF
+command will have no effect if the row was changed since the cursor was created\&.
+.PP
+Another reason to use
+FOR UPDATE
+is that without it, a subsequent
+WHERE CURRENT OF
+might fail if the cursor query does not meet the SQL standard\*(Aqs rules for being
+\(lqsimply updatable\(rq
+(in particular, the cursor must reference just one table and not use grouping or
+ORDER BY)\&. Cursors that are not simply updatable might work, or might not, depending on plan choice details; so in the worst case, an application might work in testing and then fail in production\&. If
+FOR UPDATE
+is specified, the cursor is guaranteed to be updatable\&.
+.PP
+The main reason not to use
+FOR UPDATE
+with
+WHERE CURRENT OF
+is if you need the cursor to be scrollable, or to be isolated from concurrent updates (that is, continue to show the old data)\&. If this is a requirement, pay close heed to the caveats shown above\&.
+.sp .5v
+.RE
+.PP
+The SQL standard only makes provisions for cursors in embedded
+SQL\&. The
+PostgreSQL
+server does not implement an
+\fBOPEN\fR
+statement for cursors; a cursor is considered to be open when it is declared\&. However,
+ECPG, the embedded SQL preprocessor for
+PostgreSQL, supports the standard SQL cursor conventions, including those involving
+\fBDECLARE\fR
+and
+\fBOPEN\fR
+statements\&.
+.PP
+You can see all available cursors by querying the
+pg_cursors
+system view\&.
+.SH "EXAMPLES"
+.PP
+To declare a cursor:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DECLARE liahona CURSOR FOR SELECT * FROM films;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+See
+\fBFETCH\fR(7)
+for more examples of cursor usage\&.
+.SH "COMPATIBILITY"
+.PP
+The SQL standard allows cursors only in embedded
+SQL
+and in modules\&.
+PostgreSQL
+permits cursors to be used interactively\&.
+.PP
+According to the SQL standard, changes made to insensitive cursors by
+UPDATE \&.\&.\&. WHERE CURRENT OF
+and
+DELETE \&.\&.\&. WHERE CURRENT OF
+statements are visible in that same cursor\&.
+PostgreSQL
+treats these statements like all other data changing statements in that they are not visible in insensitive cursors\&.
+.PP
+Binary cursors are a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+\fBCLOSE\fR(7), \fBFETCH\fR(7), \fBMOVE\fR(7)
diff --git a/doc/src/sgml/man7/DELETE.7 b/doc/src/sgml/man7/DELETE.7
new file mode 100644
index 0000000..953b1a1
--- /dev/null
+++ b/doc/src/sgml/man7/DELETE.7
@@ -0,0 +1,320 @@
+'\" t
+.\" Title: DELETE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DELETE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DELETE \- delete rows of a table
+.SH "SYNOPSIS"
+.sp
+.nf
+[ WITH [ RECURSIVE ] \fIwith_query\fR [, \&.\&.\&.] ]
+DELETE FROM [ ONLY ] \fItable_name\fR [ * ] [ [ AS ] \fIalias\fR ]
+ [ USING \fIfrom_item\fR [, \&.\&.\&.] ]
+ [ WHERE \fIcondition\fR | WHERE CURRENT OF \fIcursor_name\fR ]
+ [ RETURNING * | \fIoutput_expression\fR [ [ AS ] \fIoutput_name\fR ] [, \&.\&.\&.] ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDELETE\fR
+deletes rows that satisfy the
+WHERE
+clause from the specified table\&. If the
+WHERE
+clause is absent, the effect is to delete all rows in the table\&. The result is a valid, but empty table\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+.PP
+\fBTRUNCATE\fR
+provides a faster mechanism to remove all rows from a table\&.
+.sp .5v
+.RE
+.PP
+There are two ways to delete rows in a table using information contained in other tables in the database: using sub\-selects, or specifying additional tables in the
+USING
+clause\&. Which technique is more appropriate depends on the specific circumstances\&.
+.PP
+The optional
+RETURNING
+clause causes
+\fBDELETE\fR
+to compute and return value(s) based on each row actually deleted\&. Any expression using the table\*(Aqs columns, and/or columns of other tables mentioned in
+USING, can be computed\&. The syntax of the
+RETURNING
+list is identical to that of the output list of
+\fBSELECT\fR\&.
+.PP
+You must have the
+DELETE
+privilege on the table to delete from it, as well as the
+SELECT
+privilege for any table in the
+USING
+clause or whose values are read in the
+\fIcondition\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIwith_query\fR
+.RS 4
+The
+WITH
+clause allows you to specify one or more subqueries that can be referenced by name in the
+\fBDELETE\fR
+query\&. See
+Section\ \&7.8
+and
+\fBSELECT\fR(7)
+for details\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to delete rows from\&. If
+ONLY
+is specified before the table name, matching rows are deleted from the named table only\&. If
+ONLY
+is not specified, matching rows are also deleted from any tables inheriting from the named table\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+\fIalias\fR
+.RS 4
+A substitute name for the target table\&. When an alias is provided, it completely hides the actual name of the table\&. For example, given
+DELETE FROM foo AS f, the remainder of the
+\fBDELETE\fR
+statement must refer to this table as
+f
+not
+foo\&.
+.RE
+.PP
+\fIfrom_item\fR
+.RS 4
+A table expression allowing columns from other tables to appear in the
+WHERE
+condition\&. This uses the same syntax as the
+FROM
+clause of a
+\fBSELECT\fR
+statement; for example, an alias for the table name can be specified\&. Do not repeat the target table as a
+\fIfrom_item\fR
+unless you wish to set up a self\-join (in which case it must appear with an alias in the
+\fIfrom_item\fR)\&.
+.RE
+.PP
+\fIcondition\fR
+.RS 4
+An expression that returns a value of type
+boolean\&. Only rows for which this expression returns
+true
+will be deleted\&.
+.RE
+.PP
+\fIcursor_name\fR
+.RS 4
+The name of the cursor to use in a
+WHERE CURRENT OF
+condition\&. The row to be deleted is the one most recently fetched from this cursor\&. The cursor must be a non\-grouping query on the
+\fBDELETE\fR\*(Aqs target table\&. Note that
+WHERE CURRENT OF
+cannot be specified together with a Boolean condition\&. See
+\fBDECLARE\fR(7)
+for more information about using cursors with
+WHERE CURRENT OF\&.
+.RE
+.PP
+\fIoutput_expression\fR
+.RS 4
+An expression to be computed and returned by the
+\fBDELETE\fR
+command after each row is deleted\&. The expression can use any column names of the table named by
+\fItable_name\fR
+or table(s) listed in
+USING\&. Write
+*
+to return all columns\&.
+.RE
+.PP
+\fIoutput_name\fR
+.RS 4
+A name to use for a returned column\&.
+.RE
+.SH "OUTPUTS"
+.PP
+On successful completion, a
+\fBDELETE\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE \fIcount\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fIcount\fR
+is the number of rows deleted\&. Note that the number may be less than the number of rows that matched the
+\fIcondition\fR
+when deletes were suppressed by a
+BEFORE DELETE
+trigger\&. If
+\fIcount\fR
+is 0, no rows were deleted by the query (this is not considered an error)\&.
+.PP
+If the
+\fBDELETE\fR
+command contains a
+RETURNING
+clause, the result will be similar to that of a
+\fBSELECT\fR
+statement containing the columns and values defined in the
+RETURNING
+list, computed over the row(s) deleted by the command\&.
+.SH "NOTES"
+.PP
+PostgreSQL
+lets you reference columns of other tables in the
+WHERE
+condition by specifying the other tables in the
+USING
+clause\&. For example, to delete all films produced by a given producer, one can do:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE FROM films USING producers
+ WHERE producer_id = producers\&.id AND producers\&.name = \*(Aqfoo\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+What is essentially happening here is a join between
+films
+and
+producers, with all successfully joined
+films
+rows being marked for deletion\&. This syntax is not standard\&. A more standard way to do it is:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE FROM films
+ WHERE producer_id IN (SELECT id FROM producers WHERE name = \*(Aqfoo\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In some cases the join style is easier to write or faster to execute than the sub\-select style\&.
+.SH "EXAMPLES"
+.PP
+Delete all films but musicals:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE FROM films WHERE kind <> \*(AqMusical\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Clear the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE FROM films;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Delete completed tasks, returning full details of the deleted rows:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE FROM tasks WHERE status = \*(AqDONE\*(Aq RETURNING *;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Delete the row of
+tasks
+on which the cursor
+c_tasks
+is currently positioned:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DELETE FROM tasks WHERE CURRENT OF c_tasks;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the
+SQL
+standard, except that the
+USING
+and
+RETURNING
+clauses are
+PostgreSQL
+extensions, as is the ability to use
+WITH
+with
+\fBDELETE\fR\&.
+.SH "SEE ALSO"
+\fBTRUNCATE\fR(7)
diff --git a/doc/src/sgml/man7/DISCARD.7 b/doc/src/sgml/man7/DISCARD.7
new file mode 100644
index 0000000..c6b5c6b
--- /dev/null
+++ b/doc/src/sgml/man7/DISCARD.7
@@ -0,0 +1,96 @@
+'\" t
+.\" Title: DISCARD
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DISCARD" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DISCARD \- discard session state
+.SH "SYNOPSIS"
+.sp
+.nf
+DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDISCARD\fR
+releases internal resources associated with a database session\&. This command is useful for partially or fully resetting the session\*(Aqs state\&. There are several subcommands to release different types of resources; the
+\fBDISCARD ALL\fR
+variant subsumes all the others, and also resets additional state\&.
+.SH "PARAMETERS"
+.PP
+PLANS
+.RS 4
+Releases all cached query plans, forcing re\-planning to occur the next time the associated prepared statement is used\&.
+.RE
+.PP
+SEQUENCES
+.RS 4
+Discards all cached sequence\-related state, including
+\fBcurrval()\fR/\fBlastval()\fR
+information and any preallocated sequence values that have not yet been returned by
+\fBnextval()\fR\&. (See
+CREATE SEQUENCE (\fBCREATE_SEQUENCE\fR(7))
+for a description of preallocated sequence values\&.)
+.RE
+.PP
+TEMPORARY or TEMP
+.RS 4
+Drops all temporary tables created in the current session\&.
+.RE
+.PP
+ALL
+.RS 4
+Releases all temporary resources associated with the current session and resets the session to its initial state\&. Currently, this has the same effect as executing the following sequence of statements:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CLOSE ALL;
+SET SESSION AUTHORIZATION DEFAULT;
+RESET ALL;
+DEALLOCATE ALL;
+UNLISTEN *;
+SELECT pg_advisory_unlock_all();
+DISCARD PLANS;
+DISCARD TEMP;
+DISCARD SEQUENCES;
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SH "NOTES"
+.PP
+\fBDISCARD ALL\fR
+cannot be executed inside a transaction block\&.
+.SH "COMPATIBILITY"
+.PP
+\fBDISCARD\fR
+is a
+PostgreSQL
+extension\&.
diff --git a/doc/src/sgml/man7/DO.7 b/doc/src/sgml/man7/DO.7
new file mode 100644
index 0000000..5904a47
--- /dev/null
+++ b/doc/src/sgml/man7/DO.7
@@ -0,0 +1,106 @@
+'\" t
+.\" Title: DO
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DO" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DO \- execute an anonymous code block
+.SH "SYNOPSIS"
+.sp
+.nf
+DO [ LANGUAGE \fIlang_name\fR ] \fIcode\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDO\fR
+executes an anonymous code block, or in other words a transient anonymous function in a procedural language\&.
+.PP
+The code block is treated as though it were the body of a function with no parameters, returning
+void\&. It is parsed and executed a single time\&.
+.PP
+The optional
+LANGUAGE
+clause can be written either before or after the code block\&.
+.SH "PARAMETERS"
+.PP
+\fIcode\fR
+.RS 4
+The procedural language code to be executed\&. This must be specified as a string literal, just as in
+\fBCREATE FUNCTION\fR\&. Use of a dollar\-quoted literal is recommended\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the procedural language the code is written in\&. If omitted, the default is
+plpgsql\&.
+.RE
+.SH "NOTES"
+.PP
+The procedural language to be used must already have been installed into the current database by means of
+\fBCREATE EXTENSION\fR\&.
+plpgsql
+is installed by default, but other languages are not\&.
+.PP
+The user must have
+USAGE
+privilege for the procedural language, or must be a superuser if the language is untrusted\&. This is the same privilege requirement as for creating a function in the language\&.
+.PP
+If
+\fBDO\fR
+is executed in a transaction block, then the procedure code cannot execute transaction control statements\&. Transaction control statements are only allowed if
+\fBDO\fR
+is executed in its own transaction\&.
+.SH "EXAMPLES"
+.PP
+Grant all privileges on all views in schema
+public
+to role
+webuser:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DO $$DECLARE r record;
+BEGIN
+ FOR r IN SELECT table_schema, table_name FROM information_schema\&.tables
+ WHERE table_type = \*(AqVIEW\*(Aq AND table_schema = \*(Aqpublic\*(Aq
+ LOOP
+ EXECUTE \*(AqGRANT ALL ON \*(Aq || quote_ident(r\&.table_schema) || \*(Aq\&.\*(Aq || quote_ident(r\&.table_name) || \*(Aq TO webuser\*(Aq;
+ END LOOP;
+END$$;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDO\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE LANGUAGE (\fBCREATE_LANGUAGE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_ACCESS_METHOD.7 b/doc/src/sgml/man7/DROP_ACCESS_METHOD.7
new file mode 100644
index 0000000..875e63d
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_ACCESS_METHOD.7
@@ -0,0 +1,84 @@
+'\" t
+.\" Title: DROP ACCESS METHOD
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP ACCESS METHOD" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_ACCESS_METHOD \- remove an access method
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP ACCESS METHOD [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP ACCESS METHOD\fR
+removes an existing access method\&. Only superusers can drop access methods\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the access method does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of an existing access method\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the access method (such as operator classes, operator families, and indexes), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the access method if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Drop the access method
+heptree:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP ACCESS METHOD heptree;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP ACCESS METHOD\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE ACCESS METHOD (\fBCREATE_ACCESS_METHOD\fR(7))
diff --git a/doc/src/sgml/man7/DROP_AGGREGATE.7 b/doc/src/sgml/man7/DROP_AGGREGATE.7
new file mode 100644
index 0000000..1096966
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_AGGREGATE.7
@@ -0,0 +1,145 @@
+'\" t
+.\" Title: DROP AGGREGATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP AGGREGATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_AGGREGATE \- remove an aggregate function
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP AGGREGATE [ IF EXISTS ] \fIname\fR ( \fIaggregate_signature\fR ) [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+
+where \fIaggregate_signature\fR is:
+
+* |
+[ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] |
+[ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] ] ORDER BY [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP AGGREGATE\fR
+removes an existing aggregate function\&. To execute this command the current user must be the owner of the aggregate function\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the aggregate does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing aggregate function\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN
+or
+VARIADIC\&. If omitted, the default is
+IN\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Note that
+\fBDROP AGGREGATE\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the aggregate function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+An input data type on which the aggregate function operates\&. To reference a zero\-argument aggregate function, write
+*
+in place of the list of argument specifications\&. To reference an ordered\-set aggregate function, write
+ORDER BY
+between the direct and aggregated argument specifications\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the aggregate function (such as views using it), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the aggregate function if any objects depend on it\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+Alternative syntaxes for referencing ordered\-set aggregates are described under
+ALTER AGGREGATE (\fBALTER_AGGREGATE\fR(7))\&.
+.SH "EXAMPLES"
+.PP
+To remove the aggregate function
+myavg
+for type
+integer:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP AGGREGATE myavg(integer);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To remove the hypothetical\-set aggregate function
+myrank, which takes an arbitrary list of ordering columns and a matching list of direct arguments:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP AGGREGATE myrank(VARIADIC "any" ORDER BY VARIADIC "any");
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To remove multiple aggregate functions in one command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP AGGREGATE myavg(integer), myavg(bigint);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP AGGREGATE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER AGGREGATE (\fBALTER_AGGREGATE\fR(7)), CREATE AGGREGATE (\fBCREATE_AGGREGATE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_CAST.7 b/doc/src/sgml/man7/DROP_CAST.7
new file mode 100644
index 0000000..ae8540e
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_CAST.7
@@ -0,0 +1,88 @@
+'\" t
+.\" Title: DROP CAST
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP CAST" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_CAST \- remove a cast
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP CAST [ IF EXISTS ] (\fIsource_type\fR AS \fItarget_type\fR) [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP CAST\fR
+removes a previously defined cast\&.
+.PP
+To be able to drop a cast, you must own the source or the target data type\&. These are the same privileges that are required to create a cast\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the cast does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIsource_type\fR
+.RS 4
+The name of the source data type of the cast\&.
+.RE
+.PP
+\fItarget_type\fR
+.RS 4
+The name of the target data type of the cast\&.
+.RE
+.PP
+CASCADE
+.br
+RESTRICT
+.RS 4
+These key words do not have any effect, since there are no dependencies on casts\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To drop the cast from type
+text
+to type
+int:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP CAST (text AS int);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBDROP CAST\fR
+command conforms to the SQL standard\&.
+.SH "SEE ALSO"
+CREATE CAST (\fBCREATE_CAST\fR(7))
diff --git a/doc/src/sgml/man7/DROP_COLLATION.7 b/doc/src/sgml/man7/DROP_COLLATION.7
new file mode 100644
index 0000000..2716a4d
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_COLLATION.7
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: DROP COLLATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP COLLATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_COLLATION \- remove a collation
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP COLLATION [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP COLLATION\fR
+removes a previously defined collation\&. To be able to drop a collation, you must own the collation\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the collation does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the collation\&. The collation name can be schema\-qualified\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the collation, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the collation if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To drop the collation named
+german:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP COLLATION german;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBDROP COLLATION\fR
+command conforms to the
+SQL
+standard, apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER COLLATION (\fBALTER_COLLATION\fR(7)), CREATE COLLATION (\fBCREATE_COLLATION\fR(7))
diff --git a/doc/src/sgml/man7/DROP_CONVERSION.7 b/doc/src/sgml/man7/DROP_CONVERSION.7
new file mode 100644
index 0000000..3aa429f
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_CONVERSION.7
@@ -0,0 +1,85 @@
+'\" t
+.\" Title: DROP CONVERSION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP CONVERSION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_CONVERSION \- remove a conversion
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP CONVERSION [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP CONVERSION\fR
+removes a previously defined conversion\&. To be able to drop a conversion, you must own the conversion\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the conversion does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the conversion\&. The conversion name can be schema\-qualified\&.
+.RE
+.PP
+CASCADE
+.br
+RESTRICT
+.RS 4
+These key words do not have any effect, since there are no dependencies on conversions\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To drop the conversion named
+myname:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP CONVERSION myname;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP CONVERSION\fR
+statement in the SQL standard, but a
+\fBDROP TRANSLATION\fR
+statement that goes along with the
+\fBCREATE TRANSLATION\fR
+statement that is similar to the
+\fBCREATE CONVERSION\fR
+statement in PostgreSQL\&.
+.SH "SEE ALSO"
+ALTER CONVERSION (\fBALTER_CONVERSION\fR(7)), CREATE CONVERSION (\fBCREATE_CONVERSION\fR(7))
diff --git a/doc/src/sgml/man7/DROP_DATABASE.7 b/doc/src/sgml/man7/DROP_DATABASE.7
new file mode 100644
index 0000000..f36cda4
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_DATABASE.7
@@ -0,0 +1,86 @@
+'\" t
+.\" Title: DROP DATABASE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP DATABASE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_DATABASE \- remove a database
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP DATABASE [ IF EXISTS ] \fIname\fR [ [ WITH ] ( \fIoption\fR [, \&.\&.\&.] ) ]
+
+where \fIoption\fR can be:
+
+ FORCE
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP DATABASE\fR
+drops a database\&. It removes the catalog entries for the database and deletes the directory containing the data\&. It can only be executed by the database owner\&. It cannot be executed while you are connected to the target database\&. (Connect to
+postgres
+or any other database to issue this command\&.) Also, if anyone else is connected to the target database, this command will fail unless you use the
+FORCE
+option described below\&.
+.PP
+\fBDROP DATABASE\fR
+cannot be undone\&. Use it with care!
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the database does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the database to remove\&.
+.RE
+.PP
+FORCE
+.RS 4
+Attempt to terminate all existing connections to the target database\&. It doesn\*(Aqt terminate if prepared transactions, active logical replication slots or subscriptions are present in the target database\&.
+.sp
+This will fail if the current user has no permissions to terminate other connections\&. Required permissions are the same as with
+pg_terminate_backend, described in
+Section\ \&9.27.2\&. This will also fail if we are not able to terminate connections\&.
+.RE
+.SH "NOTES"
+.PP
+\fBDROP DATABASE\fR
+cannot be executed inside a transaction block\&.
+.PP
+This command cannot be executed while connected to the target database\&. Thus, it might be more convenient to use the program
+\fBdropdb\fR(1)
+instead, which is a wrapper around this command\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP DATABASE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE DATABASE (\fBCREATE_DATABASE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_DOMAIN.7 b/doc/src/sgml/man7/DROP_DOMAIN.7
new file mode 100644
index 0000000..dd91da6
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_DOMAIN.7
@@ -0,0 +1,85 @@
+'\" t
+.\" Title: DROP DOMAIN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP DOMAIN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_DOMAIN \- remove a domain
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP DOMAIN [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP DOMAIN\fR
+removes a domain\&. Only the owner of a domain can remove it\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the domain does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing domain\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the domain (such as table columns), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the domain if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To remove the domain
+box:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP DOMAIN box;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the SQL standard, except for the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE DOMAIN (\fBCREATE_DOMAIN\fR(7)), ALTER DOMAIN (\fBALTER_DOMAIN\fR(7))
diff --git a/doc/src/sgml/man7/DROP_EVENT_TRIGGER.7 b/doc/src/sgml/man7/DROP_EVENT_TRIGGER.7
new file mode 100644
index 0000000..46402b1
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_EVENT_TRIGGER.7
@@ -0,0 +1,83 @@
+'\" t
+.\" Title: DROP EVENT TRIGGER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP EVENT TRIGGER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_EVENT_TRIGGER \- remove an event trigger
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP EVENT TRIGGER [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP EVENT TRIGGER\fR
+removes an existing event trigger\&. To execute this command, the current user must be the owner of the event trigger\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the event trigger does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the event trigger to remove\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the trigger, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the trigger if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Destroy the trigger
+snitch:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP EVENT TRIGGER snitch;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP EVENT TRIGGER\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE EVENT TRIGGER (\fBCREATE_EVENT_TRIGGER\fR(7)), ALTER EVENT TRIGGER (\fBALTER_EVENT_TRIGGER\fR(7))
diff --git a/doc/src/sgml/man7/DROP_EXTENSION.7 b/doc/src/sgml/man7/DROP_EXTENSION.7
new file mode 100644
index 0000000..d089e42
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_EXTENSION.7
@@ -0,0 +1,98 @@
+'\" t
+.\" Title: DROP EXTENSION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP EXTENSION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_EXTENSION \- remove an extension
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP EXTENSION [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP EXTENSION\fR
+removes extensions from the database\&. Dropping an extension causes its member objects, and other explicitly dependent routines (see
+ALTER ROUTINE (\fBALTER_ROUTINE\fR(7)), the
+DEPENDS ON EXTENSION \fIextension_name\fR
+action), to be dropped as well\&.
+.PP
+You must own the extension to use
+\fBDROP EXTENSION\fR\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the extension does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of an installed extension\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the extension, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+This option prevents the specified extensions from being dropped if other objects, besides these extensions, their members, and their explicitly dependent routines, depend on them\&.\ \& This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To remove the extension
+hstore
+from the current database:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP EXTENSION hstore;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will fail if any of
+hstore\*(Aqs objects are in use in the database, for example if any tables have columns of the
+hstore
+type\&. Add the
+CASCADE
+option to forcibly remove those dependent objects as well\&.
+.SH "COMPATIBILITY"
+.PP
+\fBDROP EXTENSION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE EXTENSION (\fBCREATE_EXTENSION\fR(7)), ALTER EXTENSION (\fBALTER_EXTENSION\fR(7))
diff --git a/doc/src/sgml/man7/DROP_FOREIGN_DATA_WRAPPER.7 b/doc/src/sgml/man7/DROP_FOREIGN_DATA_WRAPPER.7
new file mode 100644
index 0000000..ca0ee48
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_FOREIGN_DATA_WRAPPER.7
@@ -0,0 +1,86 @@
+'\" t
+.\" Title: DROP FOREIGN DATA WRAPPER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP FOREIGN DATA WRAPPER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_FOREIGN_DATA_WRAPPER \- remove a foreign\-data wrapper
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP FOREIGN DATA WRAPPER [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP FOREIGN DATA WRAPPER\fR
+removes an existing foreign\-data wrapper\&. To execute this command, the current user must be the owner of the foreign\-data wrapper\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the foreign\-data wrapper does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of an existing foreign\-data wrapper\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the foreign\-data wrapper (such as foreign tables and servers), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the foreign\-data wrapper if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Drop the foreign\-data wrapper
+dbi:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP FOREIGN DATA WRAPPER dbi;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP FOREIGN DATA WRAPPER\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&. The
+IF EXISTS
+clause is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE FOREIGN DATA WRAPPER (\fBCREATE_FOREIGN_DATA_WRAPPER\fR(7)), ALTER FOREIGN DATA WRAPPER (\fBALTER_FOREIGN_DATA_WRAPPER\fR(7))
diff --git a/doc/src/sgml/man7/DROP_FOREIGN_TABLE.7 b/doc/src/sgml/man7/DROP_FOREIGN_TABLE.7
new file mode 100644
index 0000000..36ffc9a
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_FOREIGN_TABLE.7
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: DROP FOREIGN TABLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP FOREIGN TABLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_FOREIGN_TABLE \- remove a foreign table
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP FOREIGN TABLE [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP FOREIGN TABLE\fR
+removes a foreign table\&. Only the owner of a foreign table can remove it\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the foreign table does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the foreign table to drop\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the foreign table (such as views), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the foreign table if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To destroy two foreign tables,
+films
+and
+distributors:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP FOREIGN TABLE films, distributors;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to ISO/IEC 9075\-9 (SQL/MED), except that the standard only allows one foreign table to be dropped per command, and apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER FOREIGN TABLE (\fBALTER_FOREIGN_TABLE\fR(7)), CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_FUNCTION.7 b/doc/src/sgml/man7/DROP_FUNCTION.7
new file mode 100644
index 0000000..8b7eb29
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_FUNCTION.7
@@ -0,0 +1,186 @@
+'\" t
+.\" Title: DROP FUNCTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP FUNCTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_FUNCTION \- remove a function
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP FUNCTION [ IF EXISTS ] \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP FUNCTION\fR
+removes the definition of an existing function\&. To execute this command the user must be the owner of the function\&. The argument types to the function must be specified, since several different functions can exist with the same name and different argument lists\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the function does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing function\&. If no argument list is specified, the name must be unique in its schema\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&. Note that
+\fBDROP FUNCTION\fR
+does not actually pay any attention to
+OUT
+arguments, since only the input arguments are needed to determine the function\*(Aqs identity\&. So it is sufficient to list the
+IN,
+INOUT, and
+VARIADIC
+arguments\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Note that
+\fBDROP FUNCTION\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type(s) of the function\*(Aqs arguments (optionally schema\-qualified), if any\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the function (such as operators or triggers), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the function if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+This command removes the square root function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP FUNCTION sqrt(integer);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Drop multiple functions in one command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP FUNCTION sqrt(integer), sqrt(bigint);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+If the function name is unique in its schema, it can be referred to without an argument list:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP FUNCTION update_employee_salaries;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that this is different from
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP FUNCTION update_employee_salaries();
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+which refers to a function with zero arguments, whereas the first variant can refer to a function with any number of arguments, including zero, as long as the name is unique\&.
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the SQL standard, with these
+PostgreSQL
+extensions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The standard only allows one function to be dropped per command\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+IF EXISTS
+option
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The ability to specify argument modes and names
+.RE
+.SH "SEE ALSO"
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7)), ALTER FUNCTION (\fBALTER_FUNCTION\fR(7)), DROP PROCEDURE (\fBDROP_PROCEDURE\fR(7)), DROP ROUTINE (\fBDROP_ROUTINE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_GROUP.7 b/doc/src/sgml/man7/DROP_GROUP.7
new file mode 100644
index 0000000..45ef57d
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_GROUP.7
@@ -0,0 +1,48 @@
+'\" t
+.\" Title: DROP GROUP
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP GROUP" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_GROUP \- remove a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP GROUP [ IF EXISTS ] \fIname\fR [, \&.\&.\&.]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP GROUP\fR
+is now an alias for
+\fBDROP ROLE\fR\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP GROUP\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+DROP ROLE (\fBDROP_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_INDEX.7 b/doc/src/sgml/man7/DROP_INDEX.7
new file mode 100644
index 0000000..2b50568
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_INDEX.7
@@ -0,0 +1,109 @@
+'\" t
+.\" Title: DROP INDEX
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP INDEX" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_INDEX \- remove an index
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP INDEX\fR
+drops an existing index from the database system\&. To execute this command you must be the owner of the index\&.
+.SH "PARAMETERS"
+.PP
+CONCURRENTLY
+.RS 4
+Drop the index without locking out concurrent selects, inserts, updates, and deletes on the index\*(Aqs table\&. A normal
+\fBDROP INDEX\fR
+acquires an
+ACCESS EXCLUSIVE
+lock on the table, blocking other accesses until the index drop can be completed\&. With this option, the command instead waits until conflicting transactions have completed\&.
+.sp
+There are several caveats to be aware of when using this option\&. Only one index name can be specified, and the
+CASCADE
+option is not supported\&. (Thus, an index that supports a
+UNIQUE
+or
+PRIMARY KEY
+constraint cannot be dropped this way\&.) Also, regular
+\fBDROP INDEX\fR
+commands can be performed within a transaction block, but
+\fBDROP INDEX CONCURRENTLY\fR
+cannot\&. Lastly, indexes on partitioned tables cannot be dropped using this option\&.
+.sp
+For temporary tables,
+\fBDROP INDEX\fR
+is always non\-concurrent, as no other session can access them, and non\-concurrent index drop is cheaper\&.
+.RE
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the index does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an index to remove\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the index, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the index if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+This command will remove the index
+title_idx:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP INDEX title_idx;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP INDEX\fR
+is a
+PostgreSQL
+language extension\&. There are no provisions for indexes in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE INDEX (\fBCREATE_INDEX\fR(7))
diff --git a/doc/src/sgml/man7/DROP_LANGUAGE.7 b/doc/src/sgml/man7/DROP_LANGUAGE.7
new file mode 100644
index 0000000..1f3b386
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_LANGUAGE.7
@@ -0,0 +1,106 @@
+'\" t
+.\" Title: DROP LANGUAGE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP LANGUAGE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_LANGUAGE \- remove a procedural language
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP LANGUAGE\fR
+removes the definition of a previously registered procedural language\&. You must be a superuser or the owner of the language to use
+\fBDROP LANGUAGE\fR\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+As of
+PostgreSQL
+9\&.1, most procedural languages have been made into
+\(lqextensions\(rq, and should therefore be removed with
+\fBDROP EXTENSION\fR
+not
+\fBDROP LANGUAGE\fR\&.
+.sp .5v
+.RE
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the language does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of an existing procedural language\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the language (such as functions in the language), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the language if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+This command removes the procedural language
+plsample:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP LANGUAGE plsample;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP LANGUAGE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER LANGUAGE (\fBALTER_LANGUAGE\fR(7)), CREATE LANGUAGE (\fBCREATE_LANGUAGE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_MATERIALIZED_VIEW.7 b/doc/src/sgml/man7/DROP_MATERIALIZED_VIEW.7
new file mode 100644
index 0000000..779ce70
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_MATERIALIZED_VIEW.7
@@ -0,0 +1,84 @@
+'\" t
+.\" Title: DROP MATERIALIZED VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP MATERIALIZED VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_MATERIALIZED_VIEW \- remove a materialized view
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP MATERIALIZED VIEW [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP MATERIALIZED VIEW\fR
+drops an existing materialized view\&. To execute this command you must be the owner of the materialized view\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the materialized view does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the materialized view to remove\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the materialized view (such as other materialized views, or regular views), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the materialized view if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+This command will remove the materialized view called
+order_summary:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP MATERIALIZED VIEW order_summary;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP MATERIALIZED VIEW\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE MATERIALIZED VIEW (\fBCREATE_MATERIALIZED_VIEW\fR(7)), ALTER MATERIALIZED VIEW (\fBALTER_MATERIALIZED_VIEW\fR(7)), REFRESH MATERIALIZED VIEW (\fBREFRESH_MATERIALIZED_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/DROP_OPERATOR.7 b/doc/src/sgml/man7/DROP_OPERATOR.7
new file mode 100644
index 0000000..e60e6dd
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_OPERATOR.7
@@ -0,0 +1,124 @@
+'\" t
+.\" Title: DROP OPERATOR
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP OPERATOR" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_OPERATOR \- remove an operator
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP OPERATOR [ IF EXISTS ] \fIname\fR ( { \fIleft_type\fR | NONE } , \fIright_type\fR ) [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP OPERATOR\fR
+drops an existing operator from the database system\&. To execute this command you must be the owner of the operator\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the operator does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing operator\&.
+.RE
+.PP
+\fIleft_type\fR
+.RS 4
+The data type of the operator\*(Aqs left operand; write
+NONE
+if the operator has no left operand\&.
+.RE
+.PP
+\fIright_type\fR
+.RS 4
+The data type of the operator\*(Aqs right operand\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the operator (such as views using it), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the operator if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Remove the power operator
+a^b
+for type
+integer:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP OPERATOR ^ (integer, integer);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Remove the bitwise\-complement prefix operator
+~b
+for type
+bit:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP OPERATOR ~ (none, bit);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Remove multiple operators in one command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP OPERATOR ~ (none, bit), ^ (integer, integer);
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP OPERATOR\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE OPERATOR (\fBCREATE_OPERATOR\fR(7)), ALTER OPERATOR (\fBALTER_OPERATOR\fR(7))
diff --git a/doc/src/sgml/man7/DROP_OPERATOR_CLASS.7 b/doc/src/sgml/man7/DROP_OPERATOR_CLASS.7
new file mode 100644
index 0000000..7a1eb63
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_OPERATOR_CLASS.7
@@ -0,0 +1,105 @@
+'\" t
+.\" Title: DROP OPERATOR CLASS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP OPERATOR CLASS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_OPERATOR_CLASS \- remove an operator class
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP OPERATOR CLASS [ IF EXISTS ] \fIname\fR USING \fIindex_method\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP OPERATOR CLASS\fR
+drops an existing operator class\&. To execute this command you must be the owner of the operator class\&.
+.PP
+\fBDROP OPERATOR CLASS\fR
+does not drop any of the operators or functions referenced by the class\&. If there are any indexes depending on the operator class, you will need to specify
+CASCADE
+for the drop to complete\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the operator class does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing operator class\&.
+.RE
+.PP
+\fIindex_method\fR
+.RS 4
+The name of the index access method the operator class is for\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the operator class (such as indexes), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the operator class if any objects depend on it\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+\fBDROP OPERATOR CLASS\fR
+will not drop the operator family containing the class, even if there is nothing else left in the family (in particular, in the case where the family was implicitly created by
+\fBCREATE OPERATOR CLASS\fR)\&. An empty operator family is harmless, but for the sake of tidiness you might wish to remove the family with
+\fBDROP OPERATOR FAMILY\fR; or perhaps better, use
+\fBDROP OPERATOR FAMILY\fR
+in the first place\&.
+.SH "EXAMPLES"
+.PP
+Remove the B\-tree operator class
+widget_ops:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP OPERATOR CLASS widget_ops USING btree;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will not succeed if there are any existing indexes that use the operator class\&. Add
+CASCADE
+to drop such indexes along with the operator class\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP OPERATOR CLASS\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER OPERATOR CLASS (\fBALTER_OPERATOR_CLASS\fR(7)), CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), DROP OPERATOR FAMILY (\fBDROP_OPERATOR_FAMILY\fR(7))
diff --git a/doc/src/sgml/man7/DROP_OPERATOR_FAMILY.7 b/doc/src/sgml/man7/DROP_OPERATOR_FAMILY.7
new file mode 100644
index 0000000..d54650c
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_OPERATOR_FAMILY.7
@@ -0,0 +1,97 @@
+'\" t
+.\" Title: DROP OPERATOR FAMILY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP OPERATOR FAMILY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_OPERATOR_FAMILY \- remove an operator family
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP OPERATOR FAMILY [ IF EXISTS ] \fIname\fR USING \fIindex_method\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP OPERATOR FAMILY\fR
+drops an existing operator family\&. To execute this command you must be the owner of the operator family\&.
+.PP
+\fBDROP OPERATOR FAMILY\fR
+includes dropping any operator classes contained in the family, but it does not drop any of the operators or functions referenced by the family\&. If there are any indexes depending on operator classes within the family, you will need to specify
+CASCADE
+for the drop to complete\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the operator family does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing operator family\&.
+.RE
+.PP
+\fIindex_method\fR
+.RS 4
+The name of the index access method the operator family is for\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the operator family, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the operator family if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Remove the B\-tree operator family
+float_ops:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP OPERATOR FAMILY float_ops USING btree;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will not succeed if there are any existing indexes that use operator classes within the family\&. Add
+CASCADE
+to drop such indexes along with the operator family\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP OPERATOR FAMILY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER OPERATOR FAMILY (\fBALTER_OPERATOR_FAMILY\fR(7)), CREATE OPERATOR FAMILY (\fBCREATE_OPERATOR_FAMILY\fR(7)), ALTER OPERATOR CLASS (\fBALTER_OPERATOR_CLASS\fR(7)), CREATE OPERATOR CLASS (\fBCREATE_OPERATOR_CLASS\fR(7)), DROP OPERATOR CLASS (\fBDROP_OPERATOR_CLASS\fR(7))
diff --git a/doc/src/sgml/man7/DROP_OWNED.7 b/doc/src/sgml/man7/DROP_OWNED.7
new file mode 100644
index 0000000..1b65490
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_OWNED.7
@@ -0,0 +1,88 @@
+'\" t
+.\" Title: DROP OWNED
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP OWNED" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_OWNED \- remove database objects owned by a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP OWNED BY { \fIname\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP OWNED\fR
+drops all the objects within the current database that are owned by one of the specified roles\&. Any privileges granted to the given roles on objects in the current database or on shared objects (databases, tablespaces, configuration parameters) will also be revoked\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of a role whose objects will be dropped, and whose privileges will be revoked\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the affected objects, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the objects owned by a role if any other database objects depend on one of the affected objects\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+\fBDROP OWNED\fR
+is often used to prepare for the removal of one or more roles\&. Because
+\fBDROP OWNED\fR
+only affects the objects in the current database, it is usually necessary to execute this command in each database that contains objects owned by a role that is to be removed\&.
+.PP
+Using the
+CASCADE
+option might make the command recurse to objects owned by other users\&.
+.PP
+The
+\fBREASSIGN OWNED\fR
+command is an alternative that reassigns the ownership of all the database objects owned by one or more roles\&. However,
+\fBREASSIGN OWNED\fR
+does not deal with privileges for other objects\&.
+.PP
+Databases and tablespaces owned by the role(s) will not be removed\&.
+.PP
+See
+Section\ \&22.4
+for more discussion\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBDROP OWNED\fR
+command is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+REASSIGN OWNED (\fBREASSIGN_OWNED\fR(7)), DROP ROLE (\fBDROP_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_POLICY.7 b/doc/src/sgml/man7/DROP_POLICY.7
new file mode 100644
index 0000000..da8a4e2
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_POLICY.7
@@ -0,0 +1,90 @@
+'\" t
+.\" Title: DROP POLICY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP POLICY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_POLICY \- remove a row\-level security policy from a table
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP POLICY [ IF EXISTS ] \fIname\fR ON \fItable_name\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP POLICY\fR
+removes the specified policy from the table\&. Note that if the last policy is removed for a table and the table still has row\-level security enabled via
+\fBALTER TABLE\fR, then the default\-deny policy will be used\&.
+ALTER TABLE \&.\&.\&. DISABLE ROW LEVEL SECURITY
+can be used to disable row\-level security for a table, whether policies for the table exist or not\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the policy does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the policy to drop\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table that the policy is on\&.
+.RE
+.PP
+CASCADE
+.br
+RESTRICT
+.RS 4
+These key words do not have any effect, since there are no dependencies on policies\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To drop the policy called
+p1
+on the table named
+my_table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP POLICY p1 ON my_table;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP POLICY\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE POLICY (\fBCREATE_POLICY\fR(7)), ALTER POLICY (\fBALTER_POLICY\fR(7))
diff --git a/doc/src/sgml/man7/DROP_PROCEDURE.7 b/doc/src/sgml/man7/DROP_PROCEDURE.7
new file mode 100644
index 0000000..807dd8e
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_PROCEDURE.7
@@ -0,0 +1,220 @@
+'\" t
+.\" Title: DROP PROCEDURE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP PROCEDURE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_PROCEDURE \- remove a procedure
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP PROCEDURE [ IF EXISTS ] \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP PROCEDURE\fR
+removes the definition of one or more existing procedures\&. To execute this command the user must be the owner of the procedure(s)\&. The argument types to the procedure(s) usually must be specified, since several different procedures can exist with the same name and different argument lists\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the procedure does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing procedure\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of an argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN
+(but see below)\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of an argument\&. Note that
+\fBDROP PROCEDURE\fR
+does not actually pay any attention to argument names, since only the argument data types are used to determine the procedure\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type(s) of the procedure\*(Aqs arguments (optionally schema\-qualified), if any\&. See below for details\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the procedure, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the procedure if any objects depend on it\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+If there is only one procedure of the given name, the argument list can be omitted\&. Omit the parentheses too in this case\&.
+.PP
+In
+PostgreSQL, it\*(Aqs sufficient to list the input (including
+INOUT) arguments, because no two routines of the same name are allowed to share the same input\-argument list\&. Moreover, the
+\fBDROP\fR
+command will not actually check that you wrote the types of
+OUT
+arguments correctly; so any arguments that are explicitly marked
+OUT
+are just noise\&. But writing them is recommendable for consistency with the corresponding
+\fBCREATE\fR
+command\&.
+.PP
+For compatibility with the SQL standard, it is also allowed to write all the argument data types (including those of
+OUT
+arguments) without any
+\fIargmode\fR
+markers\&. When this is done, the types of the procedure\*(Aqs
+OUT
+argument(s)
+\fIwill\fR
+be verified against the command\&. This provision creates an ambiguity, in that when the argument list contains no
+\fIargmode\fR
+markers, it\*(Aqs unclear which rule is intended\&. The
+\fBDROP\fR
+command will attempt the lookup both ways, and will throw an error if two different procedures are found\&. To avoid the risk of such ambiguity, it\*(Aqs recommendable to write
+IN
+markers explicitly rather than letting them be defaulted, thus forcing the traditional
+PostgreSQL
+interpretation to be used\&.
+.PP
+The lookup rules just explained are also used by other commands that act on existing procedures, such as
+\fBALTER PROCEDURE\fR
+and
+\fBCOMMENT ON PROCEDURE\fR\&.
+.SH "EXAMPLES"
+.PP
+If there is only one procedure
+do_db_maintenance, this command is sufficient to drop it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP PROCEDURE do_db_maintenance;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Given this procedure definition:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PROCEDURE do_db_maintenance(IN target_schema text, OUT results text) \&.\&.\&.
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+any one of these commands would work to drop it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP PROCEDURE do_db_maintenance(IN target_schema text, OUT results text);
+DROP PROCEDURE do_db_maintenance(IN text, OUT text);
+DROP PROCEDURE do_db_maintenance(IN text);
+DROP PROCEDURE do_db_maintenance(text);
+DROP PROCEDURE do_db_maintenance(text, text); \-\- potentially ambiguous
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+However, the last example would be ambiguous if there is also, say,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE PROCEDURE do_db_maintenance(IN target_schema text, IN options text) \&.\&.\&.
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the SQL standard, with these
+PostgreSQL
+extensions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The standard only allows one procedure to be dropped per command\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+IF EXISTS
+option is an extension\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The ability to specify argument modes and names is an extension, and the lookup rules differ when modes are given\&.
+.RE
+.SH "SEE ALSO"
+CREATE PROCEDURE (\fBCREATE_PROCEDURE\fR(7)), ALTER PROCEDURE (\fBALTER_PROCEDURE\fR(7)), DROP FUNCTION (\fBDROP_FUNCTION\fR(7)), DROP ROUTINE (\fBDROP_ROUTINE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_PUBLICATION.7 b/doc/src/sgml/man7/DROP_PUBLICATION.7
new file mode 100644
index 0000000..1a526b8
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_PUBLICATION.7
@@ -0,0 +1,81 @@
+'\" t
+.\" Title: DROP PUBLICATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP PUBLICATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_PUBLICATION \- remove a publication
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP PUBLICATION [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP PUBLICATION\fR
+removes an existing publication from the database\&.
+.PP
+A publication can only be dropped by its owner or a superuser\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the publication does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of an existing publication\&.
+.RE
+.PP
+CASCADE
+.br
+RESTRICT
+.RS 4
+These key words do not have any effect, since there are no dependencies on publications\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Drop a publication:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP PUBLICATION mypublication;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP PUBLICATION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE PUBLICATION (\fBCREATE_PUBLICATION\fR(7)), ALTER PUBLICATION (\fBALTER_PUBLICATION\fR(7))
diff --git a/doc/src/sgml/man7/DROP_ROLE.7 b/doc/src/sgml/man7/DROP_ROLE.7
new file mode 100644
index 0000000..558f599
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_ROLE.7
@@ -0,0 +1,92 @@
+'\" t
+.\" Title: DROP ROLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP ROLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_ROLE \- remove a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP ROLE [ IF EXISTS ] \fIname\fR [, \&.\&.\&.]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP ROLE\fR
+removes the specified role(s)\&. To drop a superuser role, you must be a superuser yourself; to drop non\-superuser roles, you must have
+CREATEROLE
+privilege\&.
+.PP
+A role cannot be removed if it is still referenced in any database of the cluster; an error will be raised if so\&. Before dropping the role, you must drop all the objects it owns (or reassign their ownership) and revoke any privileges the role has been granted on other objects\&. The
+\fBREASSIGN OWNED\fR
+and
+\fBDROP OWNED\fR
+commands can be useful for this purpose; see
+Section\ \&22.4
+for more discussion\&.
+.PP
+However, it is not necessary to remove role memberships involving the role;
+\fBDROP ROLE\fR
+automatically revokes any memberships of the target role in other roles, and of other roles in the target role\&. The other roles are not dropped nor otherwise affected\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the role does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the role to remove\&.
+.RE
+.SH "NOTES"
+.PP
+PostgreSQL
+includes a program
+\fBdropuser\fR(1)
+that has the same functionality as this command (in fact, it calls this command) but can be run from the command shell\&.
+.SH "EXAMPLES"
+.PP
+To drop a role:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP ROLE jonathan;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The SQL standard defines
+\fBDROP ROLE\fR, but it allows only one role to be dropped at a time, and it specifies different privilege requirements than
+PostgreSQL
+uses\&.
+.SH "SEE ALSO"
+CREATE ROLE (\fBCREATE_ROLE\fR(7)), ALTER ROLE (\fBALTER_ROLE\fR(7)), SET ROLE (\fBSET_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_ROUTINE.7 b/doc/src/sgml/man7/DROP_ROUTINE.7
new file mode 100644
index 0000000..42690d9
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_ROUTINE.7
@@ -0,0 +1,148 @@
+'\" t
+.\" Title: DROP ROUTINE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP ROUTINE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_ROUTINE \- remove a routine
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP ROUTINE [ IF EXISTS ] \fIname\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] [, \&.\&.\&.]
+ [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP ROUTINE\fR
+removes the definition of one or more existing routines\&. The term
+\(lqroutine\(rq
+includes aggregate functions, normal functions, and procedures\&. See under
+DROP AGGREGATE (\fBDROP_AGGREGATE\fR(7)),
+DROP FUNCTION (\fBDROP_FUNCTION\fR(7)), and
+DROP PROCEDURE (\fBDROP_PROCEDURE\fR(7))
+for the description of the parameters, more examples, and further details\&.
+.SH "NOTES"
+.PP
+The lookup rules used by
+\fBDROP ROUTINE\fR
+are fundamentally the same as for
+\fBDROP PROCEDURE\fR; in particular,
+\fBDROP ROUTINE\fR
+shares that command\*(Aqs behavior of considering an argument list that has no
+\fIargmode\fR
+markers to be possibly using the SQL standard\*(Aqs definition that
+OUT
+arguments are included in the list\&. (\fBDROP AGGREGATE\fR
+and
+\fBDROP FUNCTION\fR
+do not do that\&.)
+.PP
+In some cases where the same name is shared by routines of different kinds, it is possible for
+\fBDROP ROUTINE\fR
+to fail with an ambiguity error when a more specific command (\fBDROP FUNCTION\fR, etc\&.) would work\&. Specifying the argument type list more carefully will also resolve such problems\&.
+.PP
+These lookup rules are also used by other commands that act on existing routines, such as
+\fBALTER ROUTINE\fR
+and
+\fBCOMMENT ON ROUTINE\fR\&.
+.SH "EXAMPLES"
+.PP
+To drop the routine
+foo
+for type
+integer:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP ROUTINE foo(integer);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will work independent of whether
+foo
+is an aggregate, function, or procedure\&.
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the SQL standard, with these
+PostgreSQL
+extensions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The standard only allows one routine to be dropped per command\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The
+IF EXISTS
+option is an extension\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+The ability to specify argument modes and names is an extension, and the lookup rules differ when modes are given\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+User\-definable aggregate functions are an extension\&.
+.RE
+.SH "SEE ALSO"
+DROP AGGREGATE (\fBDROP_AGGREGATE\fR(7)), DROP FUNCTION (\fBDROP_FUNCTION\fR(7)), DROP PROCEDURE (\fBDROP_PROCEDURE\fR(7)), ALTER ROUTINE (\fBALTER_ROUTINE\fR(7))
+.PP
+Note that there is no
+CREATE ROUTINE
+command\&.
diff --git a/doc/src/sgml/man7/DROP_RULE.7 b/doc/src/sgml/man7/DROP_RULE.7
new file mode 100644
index 0000000..637b35c
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_RULE.7
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: DROP RULE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP RULE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_RULE \- remove a rewrite rule
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP RULE [ IF EXISTS ] \fIname\fR ON \fItable_name\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP RULE\fR
+drops a rewrite rule\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the rule does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the rule to drop\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table or view that the rule applies to\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the rule, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the rule if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To drop the rewrite rule
+newrule:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP RULE newrule ON mytable;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP RULE\fR
+is a
+PostgreSQL
+language extension, as is the entire query rewrite system\&.
+.SH "SEE ALSO"
+CREATE RULE (\fBCREATE_RULE\fR(7)), ALTER RULE (\fBALTER_RULE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_SCHEMA.7 b/doc/src/sgml/man7/DROP_SCHEMA.7
new file mode 100644
index 0000000..1a211e6
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_SCHEMA.7
@@ -0,0 +1,94 @@
+'\" t
+.\" Title: DROP SCHEMA
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP SCHEMA" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_SCHEMA \- remove a schema
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP SCHEMA [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP SCHEMA\fR
+removes schemas from the database\&.
+.PP
+A schema can only be dropped by its owner or a superuser\&. Note that the owner can drop the schema (and thereby all contained objects) even if they do not own some of the objects within the schema\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the schema does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of a schema\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects (tables, functions, etc\&.) that are contained in the schema, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the schema if it contains any objects\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+Using the
+CASCADE
+option might make the command remove objects in other schemas besides the one(s) named\&.
+.SH "EXAMPLES"
+.PP
+To remove schema
+mystuff
+from the database, along with everything it contains:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP SCHEMA mystuff CASCADE;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP SCHEMA\fR
+is fully conforming with the SQL standard, except that the standard only allows one schema to be dropped per command, and apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER SCHEMA (\fBALTER_SCHEMA\fR(7)), CREATE SCHEMA (\fBCREATE_SCHEMA\fR(7))
diff --git a/doc/src/sgml/man7/DROP_SEQUENCE.7 b/doc/src/sgml/man7/DROP_SEQUENCE.7
new file mode 100644
index 0000000..d94dca7
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_SEQUENCE.7
@@ -0,0 +1,88 @@
+'\" t
+.\" Title: DROP SEQUENCE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP SEQUENCE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_SEQUENCE \- remove a sequence
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP SEQUENCE [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP SEQUENCE\fR
+removes sequence number generators\&. A sequence can only be dropped by its owner or a superuser\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the sequence does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of a sequence\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the sequence, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the sequence if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To remove the sequence
+serial:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP SEQUENCE serial;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP SEQUENCE\fR
+conforms to the
+SQL
+standard, except that the standard only allows one sequence to be dropped per command, and apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE SEQUENCE (\fBCREATE_SEQUENCE\fR(7)), ALTER SEQUENCE (\fBALTER_SEQUENCE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_SERVER.7 b/doc/src/sgml/man7/DROP_SERVER.7
new file mode 100644
index 0000000..4381063
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_SERVER.7
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: DROP SERVER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP SERVER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_SERVER \- remove a foreign server descriptor
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP SERVER [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP SERVER\fR
+removes an existing foreign server descriptor\&. To execute this command, the current user must be the owner of the server\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the server does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of an existing server\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the server (such as user mappings), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the server if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Drop a server
+foo
+if it exists:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP SERVER IF EXISTS foo;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP SERVER\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&. The
+IF EXISTS
+clause is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE SERVER (\fBCREATE_SERVER\fR(7)), ALTER SERVER (\fBALTER_SERVER\fR(7))
diff --git a/doc/src/sgml/man7/DROP_STATISTICS.7 b/doc/src/sgml/man7/DROP_STATISTICS.7
new file mode 100644
index 0000000..b9fd44e
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_STATISTICS.7
@@ -0,0 +1,80 @@
+'\" t
+.\" Title: DROP STATISTICS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP STATISTICS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_STATISTICS \- remove extended statistics
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP STATISTICS [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP STATISTICS\fR
+removes statistics object(s) from the database\&. Only the statistics object\*(Aqs owner, the schema owner, or a superuser can drop a statistics object\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the statistics object does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the statistics object to drop\&.
+.RE
+.PP
+CASCADE
+.br
+RESTRICT
+.RS 4
+These key words do not have any effect, since there are no dependencies on statistics\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To destroy two statistics objects in different schemas, without failing if they don\*(Aqt exist:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP STATISTICS IF EXISTS
+ accounting\&.users_uid_creation,
+ public\&.grants_user_role;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP STATISTICS\fR
+command in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER STATISTICS (\fBALTER_STATISTICS\fR(7)), CREATE STATISTICS (\fBCREATE_STATISTICS\fR(7))
diff --git a/doc/src/sgml/man7/DROP_SUBSCRIPTION.7 b/doc/src/sgml/man7/DROP_SUBSCRIPTION.7
new file mode 100644
index 0000000..fe1116b
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_SUBSCRIPTION.7
@@ -0,0 +1,97 @@
+'\" t
+.\" Title: DROP SUBSCRIPTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP SUBSCRIPTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_SUBSCRIPTION \- remove a subscription
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP SUBSCRIPTION [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP SUBSCRIPTION\fR
+removes a subscription from the database cluster\&.
+.PP
+A subscription can only be dropped by a superuser\&.
+.PP
+\fBDROP SUBSCRIPTION\fR
+cannot be executed inside a transaction block if the subscription is associated with a replication slot\&. (You can use
+\fBALTER SUBSCRIPTION\fR
+to unset the slot\&.)
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of a subscription to be dropped\&.
+.RE
+.PP
+CASCADE
+.br
+RESTRICT
+.RS 4
+These key words do not have any effect, since there are no dependencies on subscriptions\&.
+.RE
+.SH "NOTES"
+.PP
+When dropping a subscription that is associated with a replication slot on the remote host (the normal state),
+\fBDROP SUBSCRIPTION\fR
+will connect to the remote host and try to drop the replication slot (and any remaining table synchronization slots) as part of its operation\&. This is necessary so that the resources allocated for the subscription on the remote host are released\&. If this fails, either because the remote host is not reachable or because the remote replication slot cannot be dropped or does not exist or never existed, the
+\fBDROP SUBSCRIPTION\fR
+command will fail\&. To proceed in this situation, first disable the subscription by executing
+ALTER SUBSCRIPTION \&.\&.\&. DISABLE, and then disassociate it from the replication slot by executing
+ALTER SUBSCRIPTION \&.\&.\&. SET (slot_name = NONE)\&. After that,
+\fBDROP SUBSCRIPTION\fR
+will no longer attempt any actions on a remote host\&. Note that if the remote replication slot still exists, it (and any related table synchronization slots) should then be dropped manually; otherwise it/they will continue to reserve WAL and might eventually cause the disk to fill up\&. See also
+Section\ \&31.2.1\&.
+.PP
+If a subscription is associated with a replication slot, then
+\fBDROP SUBSCRIPTION\fR
+cannot be executed inside a transaction block\&.
+.SH "EXAMPLES"
+.PP
+Drop a subscription:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP SUBSCRIPTION mysub;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP SUBSCRIPTION\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE SUBSCRIPTION (\fBCREATE_SUBSCRIPTION\fR(7)), ALTER SUBSCRIPTION (\fBALTER_SUBSCRIPTION\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TABLE.7 b/doc/src/sgml/man7/DROP_TABLE.7
new file mode 100644
index 0000000..d93a4f9
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TABLE.7
@@ -0,0 +1,96 @@
+'\" t
+.\" Title: DROP TABLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TABLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TABLE \- remove a table
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TABLE [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TABLE\fR
+removes tables from the database\&. Only the table owner, the schema owner, and superuser can drop a table\&. To empty a table of rows without destroying the table, use
+\fBDELETE\fR
+or
+\fBTRUNCATE\fR\&.
+.PP
+\fBDROP TABLE\fR
+always removes any indexes, rules, triggers, and constraints that exist for the target table\&. However, to drop a table that is referenced by a view or a foreign\-key constraint of another table,
+CASCADE
+must be specified\&. (CASCADE
+will remove a dependent view entirely, but in the foreign\-key case it will only remove the foreign\-key constraint, not the other table entirely\&.)
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the table does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to drop\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the table (such as views), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the table if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To destroy two tables,
+films
+and
+distributors:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TABLE films, distributors;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the SQL standard, except that the standard only allows one table to be dropped per command, and apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER TABLE (\fBALTER_TABLE\fR(7)), CREATE TABLE (\fBCREATE_TABLE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TABLESPACE.7 b/doc/src/sgml/man7/DROP_TABLESPACE.7
new file mode 100644
index 0000000..d6e122e
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TABLESPACE.7
@@ -0,0 +1,84 @@
+'\" t
+.\" Title: DROP TABLESPACE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TABLESPACE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TABLESPACE \- remove a tablespace
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TABLESPACE [ IF EXISTS ] \fIname\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TABLESPACE\fR
+removes a tablespace from the system\&.
+.PP
+A tablespace can only be dropped by its owner or a superuser\&. The tablespace must be empty of all database objects before it can be dropped\&. It is possible that objects in other databases might still reside in the tablespace even if no objects in the current database are using the tablespace\&. Also, if the tablespace is listed in the
+temp_tablespaces
+setting of any active session, the
+\fBDROP\fR
+might fail due to temporary files residing in the tablespace\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the tablespace does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of a tablespace\&.
+.RE
+.SH "NOTES"
+.PP
+\fBDROP TABLESPACE\fR
+cannot be executed inside a transaction block\&.
+.SH "EXAMPLES"
+.PP
+To remove tablespace
+mystuff
+from the system:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TABLESPACE mystuff;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP TABLESPACE\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE TABLESPACE (\fBCREATE_TABLESPACE\fR(7)), ALTER TABLESPACE (\fBALTER_TABLESPACE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TEXT_SEARCH_CONFIGURATION.7 b/doc/src/sgml/man7/DROP_TEXT_SEARCH_CONFIGURATION.7
new file mode 100644
index 0000000..4b875ea
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TEXT_SEARCH_CONFIGURATION.7
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: DROP TEXT SEARCH CONFIGURATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TEXT SEARCH CONFIGURATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TEXT_SEARCH_CONFIGURATION \- remove a text search configuration
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TEXT SEARCH CONFIGURATION\fR
+drops an existing text search configuration\&. To execute this command you must be the owner of the configuration\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the text search configuration does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search configuration\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the text search configuration, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the text search configuration if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Remove the text search configuration
+my_english:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TEXT SEARCH CONFIGURATION my_english;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will not succeed if there are any existing indexes that reference the configuration in
+\fBto_tsvector\fR
+calls\&. Add
+CASCADE
+to drop such indexes along with the text search configuration\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP TEXT SEARCH CONFIGURATION\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH CONFIGURATION (\fBALTER_TEXT_SEARCH_CONFIGURATION\fR(7)), CREATE TEXT SEARCH CONFIGURATION (\fBCREATE_TEXT_SEARCH_CONFIGURATION\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TEXT_SEARCH_DICTIONARY.7 b/doc/src/sgml/man7/DROP_TEXT_SEARCH_DICTIONARY.7
new file mode 100644
index 0000000..02f4e71
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TEXT_SEARCH_DICTIONARY.7
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: DROP TEXT SEARCH DICTIONARY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TEXT SEARCH DICTIONARY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TEXT_SEARCH_DICTIONARY \- remove a text search dictionary
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TEXT SEARCH DICTIONARY\fR
+drops an existing text search dictionary\&. To execute this command you must be the owner of the dictionary\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the text search dictionary does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search dictionary\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the text search dictionary, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the text search dictionary if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Remove the text search dictionary
+english:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TEXT SEARCH DICTIONARY english;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will not succeed if there are any existing text search configurations that use the dictionary\&. Add
+CASCADE
+to drop such configurations along with the dictionary\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP TEXT SEARCH DICTIONARY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH DICTIONARY (\fBALTER_TEXT_SEARCH_DICTIONARY\fR(7)), CREATE TEXT SEARCH DICTIONARY (\fBCREATE_TEXT_SEARCH_DICTIONARY\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TEXT_SEARCH_PARSER.7 b/doc/src/sgml/man7/DROP_TEXT_SEARCH_PARSER.7
new file mode 100644
index 0000000..42fe0aa
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TEXT_SEARCH_PARSER.7
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: DROP TEXT SEARCH PARSER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TEXT SEARCH PARSER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TEXT_SEARCH_PARSER \- remove a text search parser
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TEXT SEARCH PARSER [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TEXT SEARCH PARSER\fR
+drops an existing text search parser\&. You must be a superuser to use this command\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the text search parser does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search parser\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the text search parser, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the text search parser if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Remove the text search parser
+my_parser:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TEXT SEARCH PARSER my_parser;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will not succeed if there are any existing text search configurations that use the parser\&. Add
+CASCADE
+to drop such configurations along with the parser\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP TEXT SEARCH PARSER\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH PARSER (\fBALTER_TEXT_SEARCH_PARSER\fR(7)), CREATE TEXT SEARCH PARSER (\fBCREATE_TEXT_SEARCH_PARSER\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TEXT_SEARCH_TEMPLATE.7 b/doc/src/sgml/man7/DROP_TEXT_SEARCH_TEMPLATE.7
new file mode 100644
index 0000000..1f24857
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TEXT_SEARCH_TEMPLATE.7
@@ -0,0 +1,87 @@
+'\" t
+.\" Title: DROP TEXT SEARCH TEMPLATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TEXT SEARCH TEMPLATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TEXT_SEARCH_TEMPLATE \- remove a text search template
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] \fIname\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TEXT SEARCH TEMPLATE\fR
+drops an existing text search template\&. You must be a superuser to use this command\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the text search template does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing text search template\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the text search template, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the text search template if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Remove the text search template
+thesaurus:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TEXT SEARCH TEMPLATE thesaurus;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This command will not succeed if there are any existing text search dictionaries that use the template\&. Add
+CASCADE
+to drop such dictionaries along with the template\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBDROP TEXT SEARCH TEMPLATE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TEXT SEARCH TEMPLATE (\fBALTER_TEXT_SEARCH_TEMPLATE\fR(7)), CREATE TEXT SEARCH TEMPLATE (\fBCREATE_TEXT_SEARCH_TEMPLATE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TRANSFORM.7 b/doc/src/sgml/man7/DROP_TRANSFORM.7
new file mode 100644
index 0000000..5e84a3b
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TRANSFORM.7
@@ -0,0 +1,96 @@
+'\" t
+.\" Title: DROP TRANSFORM
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TRANSFORM" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TRANSFORM \- remove a transform
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TRANSFORM [ IF EXISTS ] FOR \fItype_name\fR LANGUAGE \fIlang_name\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TRANSFORM\fR
+removes a previously defined transform\&.
+.PP
+To be able to drop a transform, you must own the type and the language\&. These are the same privileges that are required to create a transform\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the transform does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fItype_name\fR
+.RS 4
+The name of the data type of the transform\&.
+.RE
+.PP
+\fIlang_name\fR
+.RS 4
+The name of the language of the transform\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the transform, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the transform if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To drop the transform for type
+hstore
+and language
+plpython3u:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TRANSFORM FOR hstore LANGUAGE plpython3u;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This form of
+\fBDROP TRANSFORM\fR
+is a
+PostgreSQL
+extension\&. See
+CREATE TRANSFORM (\fBCREATE_TRANSFORM\fR(7))
+for details\&.
+.SH "SEE ALSO"
+CREATE TRANSFORM (\fBCREATE_TRANSFORM\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TRIGGER.7 b/doc/src/sgml/man7/DROP_TRIGGER.7
new file mode 100644
index 0000000..4d9e360
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TRIGGER.7
@@ -0,0 +1,93 @@
+'\" t
+.\" Title: DROP TRIGGER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TRIGGER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TRIGGER \- remove a trigger
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TRIGGER [ IF EXISTS ] \fIname\fR ON \fItable_name\fR [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TRIGGER\fR
+removes an existing trigger definition\&. To execute this command, the current user must be the owner of the table for which the trigger is defined\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the trigger does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the trigger to remove\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table for which the trigger is defined\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the trigger, and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the trigger if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Destroy the trigger
+if_dist_exists
+on the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TRIGGER if_dist_exists ON films;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBDROP TRIGGER\fR
+statement in
+PostgreSQL
+is incompatible with the SQL standard\&. In the SQL standard, trigger names are not local to tables, so the command is simply
+DROP TRIGGER \fIname\fR\&.
+.SH "SEE ALSO"
+CREATE TRIGGER (\fBCREATE_TRIGGER\fR(7))
diff --git a/doc/src/sgml/man7/DROP_TYPE.7 b/doc/src/sgml/man7/DROP_TYPE.7
new file mode 100644
index 0000000..e2abe04
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_TYPE.7
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: DROP TYPE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP TYPE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_TYPE \- remove a data type
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP TYPE [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP TYPE\fR
+removes a user\-defined data type\&. Only the owner of a type can remove it\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the type does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the data type to remove\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the type (such as table columns, functions, and operators), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the type if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To remove the data type
+box:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP TYPE box;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command is similar to the corresponding command in the SQL standard, apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&. But note that much of the
+\fBCREATE TYPE\fR
+command and the data type extension mechanisms in
+PostgreSQL
+differ from the SQL standard\&.
+.SH "SEE ALSO"
+ALTER TYPE (\fBALTER_TYPE\fR(7)), CREATE TYPE (\fBCREATE_TYPE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_USER.7 b/doc/src/sgml/man7/DROP_USER.7
new file mode 100644
index 0000000..0f6d11f
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_USER.7
@@ -0,0 +1,50 @@
+'\" t
+.\" Title: DROP USER
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP USER" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_USER \- remove a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP USER [ IF EXISTS ] \fIname\fR [, \&.\&.\&.]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP USER\fR
+is simply an alternate spelling of
+\fBDROP ROLE\fR\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBDROP USER\fR
+statement is a
+PostgreSQL
+extension\&. The SQL standard leaves the definition of users to the implementation\&.
+.SH "SEE ALSO"
+DROP ROLE (\fBDROP_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/DROP_USER_MAPPING.7 b/doc/src/sgml/man7/DROP_USER_MAPPING.7
new file mode 100644
index 0000000..f67295a
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_USER_MAPPING.7
@@ -0,0 +1,92 @@
+'\" t
+.\" Title: DROP USER MAPPING
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP USER MAPPING" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_USER_MAPPING \- remove a user mapping for a foreign server
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP USER MAPPING [ IF EXISTS ] FOR { \fIuser_name\fR | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER \fIserver_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP USER MAPPING\fR
+removes an existing user mapping from foreign server\&.
+.PP
+The owner of a foreign server can drop user mappings for that server for any user\&. Also, a user can drop a user mapping for their own user name if
+USAGE
+privilege on the server has been granted to the user\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the user mapping does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIuser_name\fR
+.RS 4
+User name of the mapping\&.
+CURRENT_ROLE,
+CURRENT_USER, and
+USER
+match the name of the current user\&.
+PUBLIC
+is used to match all present and future user names in the system\&.
+.RE
+.PP
+\fIserver_name\fR
+.RS 4
+Server name of the user mapping\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Drop a user mapping
+bob, server
+foo
+if it exists:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP USER MAPPING IF EXISTS FOR bob SERVER foo;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBDROP USER MAPPING\fR
+conforms to ISO/IEC 9075\-9 (SQL/MED)\&. The
+IF EXISTS
+clause is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE USER MAPPING (\fBCREATE_USER_MAPPING\fR(7)), ALTER USER MAPPING (\fBALTER_USER_MAPPING\fR(7))
diff --git a/doc/src/sgml/man7/DROP_VIEW.7 b/doc/src/sgml/man7/DROP_VIEW.7
new file mode 100644
index 0000000..120e672
--- /dev/null
+++ b/doc/src/sgml/man7/DROP_VIEW.7
@@ -0,0 +1,85 @@
+'\" t
+.\" Title: DROP VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "DROP VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+DROP_VIEW \- remove a view
+.SH "SYNOPSIS"
+.sp
+.nf
+DROP VIEW [ IF EXISTS ] \fIname\fR [, \&.\&.\&.] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBDROP VIEW\fR
+drops an existing view\&. To execute this command you must be the owner of the view\&.
+.SH "PARAMETERS"
+.PP
+IF EXISTS
+.RS 4
+Do not throw an error if the view does not exist\&. A notice is issued in this case\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the view to remove\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically drop objects that depend on the view (such as other views), and in turn all objects that depend on those objects (see
+Section\ \&5.14)\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to drop the view if any objects depend on it\&. This is the default\&.
+.RE
+.SH "EXAMPLES"
+.PP
+This command will remove the view called
+kinds:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+DROP VIEW kinds;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the SQL standard, except that the standard only allows one view to be dropped per command, and apart from the
+IF EXISTS
+option, which is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+ALTER VIEW (\fBALTER_VIEW\fR(7)), CREATE VIEW (\fBCREATE_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/END.7 b/doc/src/sgml/man7/END.7
new file mode 100644
index 0000000..f22f845
--- /dev/null
+++ b/doc/src/sgml/man7/END.7
@@ -0,0 +1,90 @@
+'\" t
+.\" Title: END
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "END" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+END \- commit the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBEND\fR
+commits the current transaction\&. All changes made by the transaction become visible to others and are guaranteed to be durable if a crash occurs\&. This command is a
+PostgreSQL
+extension that is equivalent to
+\fBCOMMIT\fR\&.
+.SH "PARAMETERS"
+.PP
+WORK
+.br
+TRANSACTION
+.RS 4
+Optional key words\&. They have no effect\&.
+.RE
+.PP
+AND CHAIN
+.RS 4
+If
+AND CHAIN
+is specified, a new transaction is immediately started with the same transaction characteristics (see
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))) as the just finished one\&. Otherwise, no new transaction is started\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBROLLBACK\fR
+to abort a transaction\&.
+.PP
+Issuing
+\fBEND\fR
+when not inside a transaction does no harm, but it will provoke a warning message\&.
+.SH "EXAMPLES"
+.PP
+To commit the current transaction and make all changes permanent:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+END;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBEND\fR
+is a
+PostgreSQL
+extension that provides functionality equivalent to
+\fBCOMMIT\fR, which is specified in the SQL standard\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), \fBROLLBACK\fR(7)
diff --git a/doc/src/sgml/man7/EXECUTE.7 b/doc/src/sgml/man7/EXECUTE.7
new file mode 100644
index 0000000..5d19c82
--- /dev/null
+++ b/doc/src/sgml/man7/EXECUTE.7
@@ -0,0 +1,84 @@
+'\" t
+.\" Title: EXECUTE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "EXECUTE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+EXECUTE \- execute a prepared statement
+.SH "SYNOPSIS"
+.sp
+.nf
+EXECUTE \fIname\fR [ ( \fIparameter\fR [, \&.\&.\&.] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBEXECUTE\fR
+is used to execute a previously prepared statement\&. Since prepared statements only exist for the duration of a session, the prepared statement must have been created by a
+\fBPREPARE\fR
+statement executed earlier in the current session\&.
+.PP
+If the
+\fBPREPARE\fR
+statement that created the statement specified some parameters, a compatible set of parameters must be passed to the
+\fBEXECUTE\fR
+statement, or else an error is raised\&. Note that (unlike functions) prepared statements are not overloaded based on the type or number of their parameters; the name of a prepared statement must be unique within a database session\&.
+.PP
+For more information on the creation and usage of prepared statements, see
+\fBPREPARE\fR(7)\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of the prepared statement to execute\&.
+.RE
+.PP
+\fIparameter\fR
+.RS 4
+The actual value of a parameter to the prepared statement\&. This must be an expression yielding a value that is compatible with the data type of this parameter, as was determined when the prepared statement was created\&.
+.RE
+.SH "OUTPUTS"
+.PP
+The command tag returned by
+\fBEXECUTE\fR
+is that of the prepared statement, and not
+EXECUTE\&.
+.SH "EXAMPLES"
+.PP
+Examples are given in
+Examples
+in the
+\fBPREPARE\fR(7)
+documentation\&.
+.SH "COMPATIBILITY"
+.PP
+The SQL standard includes an
+\fBEXECUTE\fR
+statement, but it is only for use in embedded SQL\&. This version of the
+\fBEXECUTE\fR
+statement also uses a somewhat different syntax\&.
+.SH "SEE ALSO"
+\fBDEALLOCATE\fR(7), \fBPREPARE\fR(7)
diff --git a/doc/src/sgml/man7/EXPLAIN.7 b/doc/src/sgml/man7/EXPLAIN.7
new file mode 100644
index 0000000..854e205
--- /dev/null
+++ b/doc/src/sgml/man7/EXPLAIN.7
@@ -0,0 +1,421 @@
+'\" t
+.\" Title: EXPLAIN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "EXPLAIN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+EXPLAIN \- show the execution plan of a statement
+.SH "SYNOPSIS"
+.sp
+.nf
+EXPLAIN [ ( \fIoption\fR [, \&.\&.\&.] ) ] \fIstatement\fR
+EXPLAIN [ ANALYZE ] [ VERBOSE ] \fIstatement\fR
+
+where \fIoption\fR can be one of:
+
+ ANALYZE [ \fIboolean\fR ]
+ VERBOSE [ \fIboolean\fR ]
+ COSTS [ \fIboolean\fR ]
+ SETTINGS [ \fIboolean\fR ]
+ BUFFERS [ \fIboolean\fR ]
+ WAL [ \fIboolean\fR ]
+ TIMING [ \fIboolean\fR ]
+ SUMMARY [ \fIboolean\fR ]
+ FORMAT { TEXT | XML | JSON | YAML }
+.fi
+.SH "DESCRIPTION"
+.PP
+This command displays the execution plan that the
+PostgreSQL
+planner generates for the supplied statement\&. The execution plan shows how the table(s) referenced by the statement will be scanned \(em by plain sequential scan, index scan, etc\&. \(em and if multiple tables are referenced, what join algorithms will be used to bring together the required rows from each input table\&.
+.PP
+The most critical part of the display is the estimated statement execution cost, which is the planner\*(Aqs guess at how long it will take to run the statement (measured in cost units that are arbitrary, but conventionally mean disk page fetches)\&. Actually two numbers are shown: the start\-up cost before the first row can be returned, and the total cost to return all the rows\&. For most queries the total cost is what matters, but in contexts such as a subquery in
+EXISTS, the planner will choose the smallest start\-up cost instead of the smallest total cost (since the executor will stop after getting one row, anyway)\&. Also, if you limit the number of rows to return with a
+LIMIT
+clause, the planner makes an appropriate interpolation between the endpoint costs to estimate which plan is really the cheapest\&.
+.PP
+The
+ANALYZE
+option causes the statement to be actually executed, not only planned\&. Then actual run time statistics are added to the display, including the total elapsed time expended within each plan node (in milliseconds) and the total number of rows it actually returned\&. This is useful for seeing whether the planner\*(Aqs estimates are close to reality\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBImportant\fR
+.ps -1
+.br
+.PP
+Keep in mind that the statement is actually executed when the
+ANALYZE
+option is used\&. Although
+\fBEXPLAIN\fR
+will discard any output that a
+\fBSELECT\fR
+would return, other side effects of the statement will happen as usual\&. If you wish to use
+\fBEXPLAIN ANALYZE\fR
+on an
+\fBINSERT\fR,
+\fBUPDATE\fR,
+\fBDELETE\fR,
+\fBMERGE\fR,
+\fBCREATE TABLE AS\fR, or
+\fBEXECUTE\fR
+statement without letting the command affect your data, use this approach:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+EXPLAIN ANALYZE \&.\&.\&.;
+ROLLBACK;
+.fi
+.if n \{\
+.RE
+.\}
+.sp .5v
+.RE
+.PP
+Only the
+ANALYZE
+and
+VERBOSE
+options can be specified, and only in that order, without surrounding the option list in parentheses\&. Prior to
+PostgreSQL
+9\&.0, the unparenthesized syntax was the only one supported\&. It is expected that all new options will be supported only in the parenthesized syntax\&.
+.SH "PARAMETERS"
+.PP
+ANALYZE
+.RS 4
+Carry out the command and show actual run times and other statistics\&. This parameter defaults to
+FALSE\&.
+.RE
+.PP
+VERBOSE
+.RS 4
+Display additional information regarding the plan\&. Specifically, include the output column list for each node in the plan tree, schema\-qualify table and function names, always label variables in expressions with their range table alias, and always print the name of each trigger for which statistics are displayed\&. The query identifier will also be displayed if one has been computed, see
+compute_query_id
+for more details\&. This parameter defaults to
+FALSE\&.
+.RE
+.PP
+COSTS
+.RS 4
+Include information on the estimated startup and total cost of each plan node, as well as the estimated number of rows and the estimated width of each row\&. This parameter defaults to
+TRUE\&.
+.RE
+.PP
+SETTINGS
+.RS 4
+Include information on configuration parameters\&. Specifically, include options affecting query planning with value different from the built\-in default value\&. This parameter defaults to
+FALSE\&.
+.RE
+.PP
+BUFFERS
+.RS 4
+Include information on buffer usage\&. Specifically, include the number of shared blocks hit, read, dirtied, and written, the number of local blocks hit, read, dirtied, and written, the number of temp blocks read and written, and the time spent reading and writing data file blocks and temporary file blocks (in milliseconds) if
+track_io_timing
+is enabled\&. A
+\fIhit\fR
+means that a read was avoided because the block was found already in cache when needed\&. Shared blocks contain data from regular tables and indexes; local blocks contain data from temporary tables and indexes; while temporary blocks contain short\-term working data used in sorts, hashes, Materialize plan nodes, and similar cases\&. The number of blocks
+\fIdirtied\fR
+indicates the number of previously unmodified blocks that were changed by this query; while the number of blocks
+\fIwritten\fR
+indicates the number of previously\-dirtied blocks evicted from cache by this backend during query processing\&. The number of blocks shown for an upper\-level node includes those used by all its child nodes\&. In text format, only non\-zero values are printed\&. It defaults to
+FALSE\&.
+.RE
+.PP
+WAL
+.RS 4
+Include information on WAL record generation\&. Specifically, include the number of records, number of full page images (fpi) and the amount of WAL generated in bytes\&. In text format, only non\-zero values are printed\&. This parameter may only be used when
+ANALYZE
+is also enabled\&. It defaults to
+FALSE\&.
+.RE
+.PP
+TIMING
+.RS 4
+Include actual startup time and time spent in each node in the output\&. The overhead of repeatedly reading the system clock can slow down the query significantly on some systems, so it may be useful to set this parameter to
+FALSE
+when only actual row counts, and not exact times, are needed\&. Run time of the entire statement is always measured, even when node\-level timing is turned off with this option\&. This parameter may only be used when
+ANALYZE
+is also enabled\&. It defaults to
+TRUE\&.
+.RE
+.PP
+SUMMARY
+.RS 4
+Include summary information (e\&.g\&., totaled timing information) after the query plan\&. Summary information is included by default when
+ANALYZE
+is used but otherwise is not included by default, but can be enabled using this option\&. Planning time in
+\fBEXPLAIN EXECUTE\fR
+includes the time required to fetch the plan from the cache and the time required for re\-planning, if necessary\&.
+.RE
+.PP
+FORMAT
+.RS 4
+Specify the output format, which can be TEXT, XML, JSON, or YAML\&. Non\-text output contains the same information as the text output format, but is easier for programs to parse\&. This parameter defaults to
+TEXT\&.
+.RE
+.PP
+\fIboolean\fR
+.RS 4
+Specifies whether the selected option should be turned on or off\&. You can write
+TRUE,
+ON, or
+1
+to enable the option, and
+FALSE,
+OFF, or
+0
+to disable it\&. The
+\fIboolean\fR
+value can also be omitted, in which case
+TRUE
+is assumed\&.
+.RE
+.PP
+\fIstatement\fR
+.RS 4
+Any
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR,
+\fBDELETE\fR,
+\fBMERGE\fR,
+\fBVALUES\fR,
+\fBEXECUTE\fR,
+\fBDECLARE\fR,
+\fBCREATE TABLE AS\fR, or
+\fBCREATE MATERIALIZED VIEW AS\fR
+statement, whose execution plan you wish to see\&.
+.RE
+.SH "OUTPUTS"
+.PP
+The command\*(Aqs result is a textual description of the plan selected for the
+\fIstatement\fR, optionally annotated with execution statistics\&.
+Section\ \&14.1
+describes the information provided\&.
+.SH "NOTES"
+.PP
+In order to allow the
+PostgreSQL
+query planner to make reasonably informed decisions when optimizing queries, the
+pg_statistic
+data should be up\-to\-date for all tables used in the query\&. Normally the
+autovacuum daemon
+will take care of that automatically\&. But if a table has recently had substantial changes in its contents, you might need to do a manual
+\fBANALYZE\fR
+rather than wait for autovacuum to catch up with the changes\&.
+.PP
+In order to measure the run\-time cost of each node in the execution plan, the current implementation of
+\fBEXPLAIN ANALYZE\fR
+adds profiling overhead to query execution\&. As a result, running
+\fBEXPLAIN ANALYZE\fR
+on a query can sometimes take significantly longer than executing the query normally\&. The amount of overhead depends on the nature of the query, as well as the platform being used\&. The worst case occurs for plan nodes that in themselves require very little time per execution, and on machines that have relatively slow operating system calls for obtaining the time of day\&.
+.SH "EXAMPLES"
+.PP
+To show the plan for a simple query on a table with a single
+integer
+column and 10000 rows:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN SELECT * FROM foo;
+
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ Seq Scan on foo (cost=0\&.00\&.\&.155\&.00 rows=10000 width=4)
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is the same query, with JSON output formatting:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN (FORMAT JSON) SELECT * FROM foo;
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ [ +
+ { +
+ "Plan": { +
+ "Node Type": "Seq Scan",+
+ "Relation Name": "foo", +
+ "Alias": "foo", +
+ "Startup Cost": 0\&.00, +
+ "Total Cost": 155\&.00, +
+ "Plan Rows": 10000, +
+ "Plan Width": 4 +
+ } +
+ } +
+ ]
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+If there is an index and we use a query with an indexable
+WHERE
+condition,
+\fBEXPLAIN\fR
+might show a different plan:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN SELECT * FROM foo WHERE i = 4;
+
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ Index Scan using fi on foo (cost=0\&.00\&.\&.5\&.98 rows=1 width=4)
+ Index Cond: (i = 4)
+(2 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is the same query, but in YAML format:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i=\*(Aq4\*(Aq;
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ \- Plan: +
+ Node Type: "Index Scan" +
+ Scan Direction: "Forward"+
+ Index Name: "fi" +
+ Relation Name: "foo" +
+ Alias: "foo" +
+ Startup Cost: 0\&.00 +
+ Total Cost: 5\&.98 +
+ Plan Rows: 1 +
+ Plan Width: 4 +
+ Index Cond: "(i = 4)"
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+XML format is left as an exercise for the reader\&.
+.PP
+Here is the same plan with cost estimates suppressed:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4;
+
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ Index Scan using fi on foo
+ Index Cond: (i = 4)
+(2 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is an example of a query plan for a query using an aggregate function:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN SELECT sum(i) FROM foo WHERE i < 10;
+
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\:\-\-
+ Aggregate (cost=23\&.93\&.\&.23\&.93 rows=1 width=4)
+ \-> Index Scan using fi on foo (cost=0\&.00\&.\&.23\&.92 rows=6 width=4)
+ Index Cond: (i < 10)
+(3 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is an example of using
+\fBEXPLAIN EXECUTE\fR
+to display the execution plan for a prepared query:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+PREPARE query(int, int) AS SELECT sum(bar) FROM test
+ WHERE id > $1 AND id < $2
+ GROUP BY foo;
+
+EXPLAIN ANALYZE EXECUTE query(100, 200);
+
+ QUERY PLAN
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\:\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ HashAggregate (cost=9\&.54\&.\&.9\&.54 rows=1 width=8) (actual time=0\&.156\&.\&.0\&.161 rows=11 loops=1)
+ Group Key: foo
+ \-> Index Scan using test_pkey on test (cost=0\&.29\&.\&.9\&.29 rows=50 width=8) (actual time=0\&.039\&.\&.0\&.091 rows=99 loops=1)
+ Index Cond: ((id > $1) AND (id < $2))
+ Planning time: 0\&.197 ms
+ Execution time: 0\&.225 ms
+(6 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Of course, the specific numbers shown here depend on the actual contents of the tables involved\&. Also note that the numbers, and even the selected query strategy, might vary between
+PostgreSQL
+releases due to planner improvements\&. In addition, the
+\fBANALYZE\fR
+command uses random sampling to estimate data statistics; therefore, it is possible for cost estimates to change after a fresh run of
+\fBANALYZE\fR, even if the actual distribution of data in the table has not changed\&.
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBEXPLAIN\fR
+statement defined in the SQL standard\&.
+.SH "SEE ALSO"
+\fBANALYZE\fR(7)
diff --git a/doc/src/sgml/man7/FETCH.7 b/doc/src/sgml/man7/FETCH.7
new file mode 100644
index 0000000..f35d3f7
--- /dev/null
+++ b/doc/src/sgml/man7/FETCH.7
@@ -0,0 +1,352 @@
+'\" t
+.\" Title: FETCH
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "FETCH" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+FETCH \- retrieve rows from a query using a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+FETCH [ \fIdirection\fR ] [ FROM | IN ] \fIcursor_name\fR
+
+where \fIdirection\fR can be one of:
+
+ NEXT
+ PRIOR
+ FIRST
+ LAST
+ ABSOLUTE \fIcount\fR
+ RELATIVE \fIcount\fR
+ \fIcount\fR
+ ALL
+ FORWARD
+ FORWARD \fIcount\fR
+ FORWARD ALL
+ BACKWARD
+ BACKWARD \fIcount\fR
+ BACKWARD ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBFETCH\fR
+retrieves rows using a previously\-created cursor\&.
+.PP
+A cursor has an associated position, which is used by
+\fBFETCH\fR\&. The cursor position can be before the first row of the query result, on any particular row of the result, or after the last row of the result\&. When created, a cursor is positioned before the first row\&. After fetching some rows, the cursor is positioned on the row most recently retrieved\&. If
+\fBFETCH\fR
+runs off the end of the available rows then the cursor is left positioned after the last row, or before the first row if fetching backward\&.
+\fBFETCH ALL\fR
+or
+\fBFETCH BACKWARD ALL\fR
+will always leave the cursor positioned after the last row or before the first row\&.
+.PP
+The forms
+NEXT,
+PRIOR,
+FIRST,
+LAST,
+ABSOLUTE,
+RELATIVE
+fetch a single row after moving the cursor appropriately\&. If there is no such row, an empty result is returned, and the cursor is left positioned before the first row or after the last row as appropriate\&.
+.PP
+The forms using
+FORWARD
+and
+BACKWARD
+retrieve the indicated number of rows moving in the forward or backward direction, leaving the cursor positioned on the last\-returned row (or after/before all rows, if the
+\fIcount\fR
+exceeds the number of rows available)\&.
+.PP
+RELATIVE 0,
+FORWARD 0, and
+BACKWARD 0
+all request fetching the current row without moving the cursor, that is, re\-fetching the most recently fetched row\&. This will succeed unless the cursor is positioned before the first row or after the last row; in which case, no row is returned\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+This page describes usage of cursors at the SQL command level\&. If you are trying to use cursors inside a
+PL/pgSQL
+function, the rules are different \(em see
+Section\ \&43.7.3\&.
+.sp .5v
+.RE
+.SH "PARAMETERS"
+.PP
+\fIdirection\fR
+.RS 4
+\fIdirection\fR
+defines the fetch direction and number of rows to fetch\&. It can be one of the following:
+.PP
+NEXT
+.RS 4
+Fetch the next row\&. This is the default if
+\fIdirection\fR
+is omitted\&.
+.RE
+.PP
+PRIOR
+.RS 4
+Fetch the prior row\&.
+.RE
+.PP
+FIRST
+.RS 4
+Fetch the first row of the query (same as
+ABSOLUTE 1)\&.
+.RE
+.PP
+LAST
+.RS 4
+Fetch the last row of the query (same as
+ABSOLUTE \-1)\&.
+.RE
+.PP
+ABSOLUTE \fIcount\fR
+.RS 4
+Fetch the
+\fIcount\fR\*(Aqth row of the query, or the
+abs(\fIcount\fR)\*(Aqth row from the end if
+\fIcount\fR
+is negative\&. Position before first row or after last row if
+\fIcount\fR
+is out of range; in particular,
+ABSOLUTE 0
+positions before the first row\&.
+.RE
+.PP
+RELATIVE \fIcount\fR
+.RS 4
+Fetch the
+\fIcount\fR\*(Aqth succeeding row, or the
+abs(\fIcount\fR)\*(Aqth prior row if
+\fIcount\fR
+is negative\&.
+RELATIVE 0
+re\-fetches the current row, if any\&.
+.RE
+.PP
+\fIcount\fR
+.RS 4
+Fetch the next
+\fIcount\fR
+rows (same as
+FORWARD \fIcount\fR)\&.
+.RE
+.PP
+ALL
+.RS 4
+Fetch all remaining rows (same as
+FORWARD ALL)\&.
+.RE
+.PP
+FORWARD
+.RS 4
+Fetch the next row (same as
+NEXT)\&.
+.RE
+.PP
+FORWARD \fIcount\fR
+.RS 4
+Fetch the next
+\fIcount\fR
+rows\&.
+FORWARD 0
+re\-fetches the current row\&.
+.RE
+.PP
+FORWARD ALL
+.RS 4
+Fetch all remaining rows\&.
+.RE
+.PP
+BACKWARD
+.RS 4
+Fetch the prior row (same as
+PRIOR)\&.
+.RE
+.PP
+BACKWARD \fIcount\fR
+.RS 4
+Fetch the prior
+\fIcount\fR
+rows (scanning backwards)\&.
+BACKWARD 0
+re\-fetches the current row\&.
+.RE
+.PP
+BACKWARD ALL
+.RS 4
+Fetch all prior rows (scanning backwards)\&.
+.RE
+.RE
+.PP
+\fIcount\fR
+.RS 4
+\fIcount\fR
+is a possibly\-signed integer constant, determining the location or number of rows to fetch\&. For
+FORWARD
+and
+BACKWARD
+cases, specifying a negative
+\fIcount\fR
+is equivalent to changing the sense of
+FORWARD
+and
+BACKWARD\&.
+.RE
+.PP
+\fIcursor_name\fR
+.RS 4
+An open cursor\*(Aqs name\&.
+.RE
+.SH "OUTPUTS"
+.PP
+On successful completion, a
+\fBFETCH\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+FETCH \fIcount\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fIcount\fR
+is the number of rows fetched (possibly zero)\&. Note that in
+psql, the command tag will not actually be displayed, since
+psql
+displays the fetched rows instead\&.
+.SH "NOTES"
+.PP
+The cursor should be declared with the
+SCROLL
+option if one intends to use any variants of
+\fBFETCH\fR
+other than
+\fBFETCH NEXT\fR
+or
+\fBFETCH FORWARD\fR
+with a positive count\&. For simple queries
+PostgreSQL
+will allow backwards fetch from cursors not declared with
+SCROLL, but this behavior is best not relied on\&. If the cursor is declared with
+NO SCROLL, no backward fetches are allowed\&.
+.PP
+ABSOLUTE
+fetches are not any faster than navigating to the desired row with a relative move: the underlying implementation must traverse all the intermediate rows anyway\&. Negative absolute fetches are even worse: the query must be read to the end to find the last row, and then traversed backward from there\&. However, rewinding to the start of the query (as with
+FETCH ABSOLUTE 0) is fast\&.
+.PP
+\fBDECLARE\fR
+is used to define a cursor\&. Use
+\fBMOVE\fR
+to change cursor position without retrieving data\&.
+.SH "EXAMPLES"
+.PP
+The following example traverses a table using a cursor:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN WORK;
+
+\-\- Set up a cursor:
+DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;
+
+\-\- Fetch the first 5 rows in the cursor liahona:
+FETCH FORWARD 5 FROM liahona;
+
+ code | title | did | date_prod | kind | len
+\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+ BL101 | The Third Man | 101 | 1949\-12\-23 | Drama | 01:44
+ BL102 | The African Queen | 101 | 1951\-08\-11 | Romantic | 01:43
+ JL201 | Une Femme est une Femme | 102 | 1961\-03\-12 | Romantic | 01:25
+ P_301 | Vertigo | 103 | 1958\-11\-14 | Action | 02:08
+ P_302 | Becket | 103 | 1964\-02\-03 | Drama | 02:28
+
+\-\- Fetch the previous row:
+FETCH PRIOR FROM liahona;
+
+ code | title | did | date_prod | kind | len
+\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+ P_301 | Vertigo | 103 | 1958\-11\-14 | Action | 02:08
+
+\-\- Close the cursor and end the transaction:
+CLOSE liahona;
+COMMIT WORK;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The SQL standard defines
+\fBFETCH\fR
+for use in embedded SQL only\&. The variant of
+\fBFETCH\fR
+described here returns the data as if it were a
+\fBSELECT\fR
+result rather than placing it in host variables\&. Other than this point,
+\fBFETCH\fR
+is fully upward\-compatible with the SQL standard\&.
+.PP
+The
+\fBFETCH\fR
+forms involving
+FORWARD
+and
+BACKWARD, as well as the forms
+FETCH \fIcount\fR
+and
+FETCH ALL, in which
+FORWARD
+is implicit, are
+PostgreSQL
+extensions\&.
+.PP
+The SQL standard allows only
+FROM
+preceding the cursor name; the option to use
+IN, or to leave them out altogether, is an extension\&.
+.SH "SEE ALSO"
+\fBCLOSE\fR(7), \fBDECLARE\fR(7), \fBMOVE\fR(7)
diff --git a/doc/src/sgml/man7/GRANT.7 b/doc/src/sgml/man7/GRANT.7
new file mode 100644
index 0000000..28a6ddb
--- /dev/null
+++ b/doc/src/sgml/man7/GRANT.7
@@ -0,0 +1,416 @@
+'\" t
+.\" Title: GRANT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "GRANT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+GRANT \- define access privileges
+.SH "SYNOPSIS"
+.sp
+.nf
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON { [ TABLE ] \fItable_name\fR [, \&.\&.\&.]
+ | ALL TABLES IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] }
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( \fIcolumn_name\fR [, \&.\&.\&.] )
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] ( \fIcolumn_name\fR [, \&.\&.\&.] ) }
+ ON [ TABLE ] \fItable_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { { USAGE | SELECT | UPDATE }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON { SEQUENCE \fIsequence_name\fR [, \&.\&.\&.]
+ | ALL SEQUENCES IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] }
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON DATABASE \fIdatabase_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON DOMAIN \fIdomain_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN DATA WRAPPER \fIfdw_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN SERVER \fIserver_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { { FUNCTION | PROCEDURE | ROUTINE } \fIroutine_name\fR [ ( [ [ \fIargmode\fR ] [ \fIarg_name\fR ] \fIarg_type\fR [, \&.\&.\&.] ] ) ] [, \&.\&.\&.]
+ | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] }
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON LANGUAGE \fIlang_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { { SELECT | UPDATE } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON LARGE OBJECT \fIloid\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { { SET | ALTER SYSTEM } [, \&.\&.\&. ] | ALL [ PRIVILEGES ] }
+ ON PARAMETER \fIconfiguration_parameter\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { { CREATE | USAGE } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON SCHEMA \fIschema_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { CREATE | ALL [ PRIVILEGES ] }
+ ON TABLESPACE \fItablespace_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPE \fItype_name\fR [, \&.\&.\&.]
+ TO \fIrole_specification\fR [, \&.\&.\&.] [ WITH GRANT OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+GRANT \fIrole_name\fR [, \&.\&.\&.] TO \fIrole_specification\fR [, \&.\&.\&.]
+ [ WITH ADMIN OPTION ]
+ [ GRANTED BY \fIrole_specification\fR ]
+
+where \fIrole_specification\fR can be:
+
+ [ GROUP ] \fIrole_name\fR
+ | PUBLIC
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBGRANT\fR
+command has two basic variants: one that grants privileges on a database object (table, column, view, foreign table, sequence, database, foreign\-data wrapper, foreign server, function, procedure, procedural language, large object, configuration parameter, schema, tablespace, or type), and one that grants membership in a role\&. These variants are similar in many ways, but they are different enough to be described separately\&.
+.SS "GRANT on Database Objects"
+.PP
+This variant of the
+\fBGRANT\fR
+command gives specific privileges on a database object to one or more roles\&. These privileges are added to those already granted, if any\&.
+.PP
+The key word
+PUBLIC
+indicates that the privileges are to be granted to all roles, including those that might be created later\&.
+PUBLIC
+can be thought of as an implicitly defined group that always includes all roles\&. Any particular role will have the sum of privileges granted directly to it, privileges granted to any role it is presently a member of, and privileges granted to
+PUBLIC\&.
+.PP
+If
+WITH GRANT OPTION
+is specified, the recipient of the privilege can in turn grant it to others\&. Without a grant option, the recipient cannot do that\&. Grant options cannot be granted to
+PUBLIC\&.
+.PP
+If
+GRANTED BY
+is specified, the specified grantor must be the current user\&. This clause is currently present in this form only for SQL compatibility\&.
+.PP
+There is no need to grant privileges to the owner of an object (usually the user that created it), as the owner has all privileges by default\&. (The owner could, however, choose to revoke some of their own privileges for safety\&.)
+.PP
+The right to drop an object, or to alter its definition in any way, is not treated as a grantable privilege; it is inherent in the owner, and cannot be granted or revoked\&. (However, a similar effect can be obtained by granting or revoking membership in the role that owns the object; see below\&.) The owner implicitly has all grant options for the object, too\&.
+.PP
+The possible privileges are:
+.PP
+SELECT
+.br
+INSERT
+.br
+UPDATE
+.br
+DELETE
+.br
+TRUNCATE
+.br
+REFERENCES
+.br
+TRIGGER
+.br
+CREATE
+.br
+CONNECT
+.br
+TEMPORARY
+.br
+EXECUTE
+.br
+USAGE
+.br
+SET
+.br
+ALTER SYSTEM
+.RS 4
+Specific types of privileges, as defined in
+Section\ \&5.7\&.
+.RE
+.PP
+TEMP
+.RS 4
+Alternative spelling for
+TEMPORARY\&.
+.RE
+.PP
+ALL PRIVILEGES
+.RS 4
+Grant all of the privileges available for the object\*(Aqs type\&. The
+PRIVILEGES
+key word is optional in
+PostgreSQL, though it is required by strict SQL\&.
+.RE
+.PP
+The
+FUNCTION
+syntax works for plain functions, aggregate functions, and window functions, but not for procedures; use
+PROCEDURE
+for those\&. Alternatively, use
+ROUTINE
+to refer to a function, aggregate function, window function, or procedure regardless of its precise type\&.
+.PP
+There is also an option to grant privileges on all objects of the same type within one or more schemas\&. This functionality is currently supported only for tables, sequences, functions, and procedures\&.
+ALL TABLES
+also affects views and foreign tables, just like the specific\-object
+\fBGRANT\fR
+command\&.
+ALL FUNCTIONS
+also affects aggregate and window functions, but not procedures, again just like the specific\-object
+\fBGRANT\fR
+command\&. Use
+ALL ROUTINES
+to include procedures\&.
+.SS "GRANT on Roles"
+.PP
+This variant of the
+\fBGRANT\fR
+command grants membership in a role to one or more other roles\&. Membership in a role is significant because it conveys the privileges granted to a role to each of its members\&.
+.PP
+If
+WITH ADMIN OPTION
+is specified, the member can in turn grant membership in the role to others, and revoke membership in the role as well\&. Without the admin option, ordinary users cannot do that\&. A role is not considered to hold
+WITH ADMIN OPTION
+on itself\&. Database superusers can grant or revoke membership in any role to anyone\&. Roles having
+CREATEROLE
+privilege can grant or revoke membership in any role that is not a superuser\&.
+.PP
+If
+GRANTED BY
+is specified, the grant is recorded as having been done by the specified role\&. Only database superusers may use this option, except when it names the same role executing the command\&.
+.PP
+Unlike the case with privileges, membership in a role cannot be granted to
+PUBLIC\&. Note also that this form of the command does not allow the noise word
+GROUP
+in
+\fIrole_specification\fR\&.
+.SH "NOTES"
+.PP
+The
+\fBREVOKE\fR
+command is used to revoke access privileges\&.
+.PP
+Since
+PostgreSQL
+8\&.1, the concepts of users and groups have been unified into a single kind of entity called a role\&. It is therefore no longer necessary to use the keyword
+GROUP
+to identify whether a grantee is a user or a group\&.
+GROUP
+is still allowed in the command, but it is a noise word\&.
+.PP
+A user may perform
+\fBSELECT\fR,
+\fBINSERT\fR, etc\&. on a column if they hold that privilege for either the specific column or its whole table\&. Granting the privilege at the table level and then revoking it for one column will not do what one might wish: the table\-level grant is unaffected by a column\-level operation\&.
+.PP
+When a non\-owner of an object attempts to
+\fBGRANT\fR
+privileges on the object, the command will fail outright if the user has no privileges whatsoever on the object\&. As long as some privilege is available, the command will proceed, but it will grant only those privileges for which the user has grant options\&. The
+\fBGRANT ALL PRIVILEGES\fR
+forms will issue a warning message if no grant options are held, while the other forms will issue a warning if grant options for any of the privileges specifically named in the command are not held\&. (In principle these statements apply to the object owner as well, but since the owner is always treated as holding all grant options, the cases can never occur\&.)
+.PP
+It should be noted that database superusers can access all objects regardless of object privilege settings\&. This is comparable to the rights of
+root
+in a Unix system\&. As with
+root, it\*(Aqs unwise to operate as a superuser except when absolutely necessary\&.
+.PP
+If a superuser chooses to issue a
+\fBGRANT\fR
+or
+\fBREVOKE\fR
+command, the command is performed as though it were issued by the owner of the affected object\&. In particular, privileges granted via such a command will appear to have been granted by the object owner\&. (For role membership, the membership appears to have been granted by the containing role itself\&.)
+.PP
+\fBGRANT\fR
+and
+\fBREVOKE\fR
+can also be done by a role that is not the owner of the affected object, but is a member of the role that owns the object, or is a member of a role that holds privileges
+WITH GRANT OPTION
+on the object\&. In this case the privileges will be recorded as having been granted by the role that actually owns the object or holds the privileges
+WITH GRANT OPTION\&. For example, if table
+t1
+is owned by role
+g1, of which role
+u1
+is a member, then
+u1
+can grant privileges on
+t1
+to
+u2, but those privileges will appear to have been granted directly by
+g1\&. Any other member of role
+g1
+could revoke them later\&.
+.PP
+If the role executing
+\fBGRANT\fR
+holds the required privileges indirectly via more than one role membership path, it is unspecified which containing role will be recorded as having done the grant\&. In such cases it is best practice to use
+\fBSET ROLE\fR
+to become the specific role you want to do the
+\fBGRANT\fR
+as\&.
+.PP
+Granting permission on a table does not automatically extend permissions to any sequences used by the table, including sequences tied to
+SERIAL
+columns\&. Permissions on sequences must be set separately\&.
+.PP
+See
+Section\ \&5.7
+for more information about specific privilege types, as well as how to inspect objects\*(Aq privileges\&.
+.SH "EXAMPLES"
+.PP
+Grant insert privilege to all users on table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+GRANT INSERT ON films TO PUBLIC;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Grant all available privileges to user
+manuel
+on view
+kinds:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+GRANT ALL PRIVILEGES ON kinds TO manuel;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that while the above will indeed grant all privileges if executed by a superuser or the owner of
+kinds, when executed by someone else it will only grant those permissions for which the someone else has grant options\&.
+.PP
+Grant membership in role
+admins
+to user
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+GRANT admins TO joe;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+According to the SQL standard, the
+PRIVILEGES
+key word in
+ALL PRIVILEGES
+is required\&. The SQL standard does not support setting the privileges on more than one object per command\&.
+.PP
+PostgreSQL
+allows an object owner to revoke their own ordinary privileges: for example, a table owner can make the table read\-only to themselves by revoking their own
+INSERT,
+UPDATE,
+DELETE, and
+TRUNCATE
+privileges\&. This is not possible according to the SQL standard\&. The reason is that
+PostgreSQL
+treats the owner\*(Aqs privileges as having been granted by the owner to themselves; therefore they can revoke them too\&. In the SQL standard, the owner\*(Aqs privileges are granted by an assumed entity
+\(lq_SYSTEM\(rq\&. Not being
+\(lq_SYSTEM\(rq, the owner cannot revoke these rights\&.
+.PP
+According to the SQL standard, grant options can be granted to
+PUBLIC; PostgreSQL only supports granting grant options to roles\&.
+.PP
+The SQL standard allows the
+GRANTED BY
+option to specify only
+CURRENT_USER
+or
+CURRENT_ROLE\&. The other variants are PostgreSQL extensions\&.
+.PP
+The SQL standard provides for a
+USAGE
+privilege on other kinds of objects: character sets, collations, translations\&.
+.PP
+In the SQL standard, sequences only have a
+USAGE
+privilege, which controls the use of the
+NEXT VALUE FOR
+expression, which is equivalent to the function
+\fBnextval\fR
+in PostgreSQL\&. The sequence privileges
+SELECT
+and
+UPDATE
+are PostgreSQL extensions\&. The application of the sequence
+USAGE
+privilege to the
+currval
+function is also a PostgreSQL extension (as is the function itself)\&.
+.PP
+Privileges on databases, tablespaces, schemas, languages, and configuration parameters are
+PostgreSQL
+extensions\&.
+.SH "SEE ALSO"
+\fBREVOKE\fR(7), ALTER DEFAULT PRIVILEGES (\fBALTER_DEFAULT_PRIVILEGES\fR(7))
diff --git a/doc/src/sgml/man7/IMPORT_FOREIGN_SCHEMA.7 b/doc/src/sgml/man7/IMPORT_FOREIGN_SCHEMA.7
new file mode 100644
index 0000000..a044bce
--- /dev/null
+++ b/doc/src/sgml/man7/IMPORT_FOREIGN_SCHEMA.7
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: IMPORT FOREIGN SCHEMA
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "IMPORT FOREIGN SCHEMA" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+IMPORT_FOREIGN_SCHEMA \- import table definitions from a foreign server
+.SH "SYNOPSIS"
+.sp
+.nf
+IMPORT FOREIGN SCHEMA \fIremote_schema\fR
+ [ { LIMIT TO | EXCEPT } ( \fItable_name\fR [, \&.\&.\&.] ) ]
+ FROM SERVER \fIserver_name\fR
+ INTO \fIlocal_schema\fR
+ [ OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&. ] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBIMPORT FOREIGN SCHEMA\fR
+creates foreign tables that represent tables existing on a foreign server\&. The new foreign tables will be owned by the user issuing the command and are created with the correct column definitions and options to match the remote tables\&.
+.PP
+By default, all tables and views existing in a particular schema on the foreign server are imported\&. Optionally, the list of tables can be limited to a specified subset, or specific tables can be excluded\&. The new foreign tables are all created in the target schema, which must already exist\&.
+.PP
+To use
+\fBIMPORT FOREIGN SCHEMA\fR, the user must have
+USAGE
+privilege on the foreign server, as well as
+CREATE
+privilege on the target schema\&.
+.SH "PARAMETERS"
+.PP
+\fIremote_schema\fR
+.RS 4
+The remote schema to import from\&. The specific meaning of a remote schema depends on the foreign data wrapper in use\&.
+.RE
+.PP
+LIMIT TO ( \fItable_name\fR [, \&.\&.\&.] )
+.RS 4
+Import only foreign tables matching one of the given table names\&. Other tables existing in the foreign schema will be ignored\&.
+.RE
+.PP
+EXCEPT ( \fItable_name\fR [, \&.\&.\&.] )
+.RS 4
+Exclude specified foreign tables from the import\&. All tables existing in the foreign schema will be imported except the ones listed here\&.
+.RE
+.PP
+\fIserver_name\fR
+.RS 4
+The foreign server to import from\&.
+.RE
+.PP
+\fIlocal_schema\fR
+.RS 4
+The schema in which the imported foreign tables will be created\&.
+.RE
+.PP
+OPTIONS ( \fIoption\fR \*(Aq\fIvalue\fR\*(Aq [, \&.\&.\&.] )
+.RS 4
+Options to be used during the import\&. The allowed option names and values are specific to each foreign data wrapper\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Import table definitions from a remote schema
+foreign_films
+on server
+film_server, creating the foreign tables in local schema
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+IMPORT FOREIGN SCHEMA foreign_films
+ FROM SERVER film_server INTO films;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+As above, but import only the two tables
+actors
+and
+directors
+(if they exist):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+IMPORT FOREIGN SCHEMA foreign_films LIMIT TO (actors, directors)
+ FROM SERVER film_server INTO films;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBIMPORT FOREIGN SCHEMA\fR
+command conforms to the
+SQL
+standard, except that the
+OPTIONS
+clause is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE FOREIGN TABLE (\fBCREATE_FOREIGN_TABLE\fR(7)), CREATE SERVER (\fBCREATE_SERVER\fR(7))
diff --git a/doc/src/sgml/man7/INSERT.7 b/doc/src/sgml/man7/INSERT.7
new file mode 100644
index 0000000..65e509b
--- /dev/null
+++ b/doc/src/sgml/man7/INSERT.7
@@ -0,0 +1,766 @@
+'\" t
+.\" Title: INSERT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "INSERT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+INSERT \- create new rows in a table
+.SH "SYNOPSIS"
+.sp
+.nf
+[ WITH [ RECURSIVE ] \fIwith_query\fR [, \&.\&.\&.] ]
+INSERT INTO \fItable_name\fR [ AS \fIalias\fR ] [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+ [ OVERRIDING { SYSTEM | USER } VALUE ]
+ { DEFAULT VALUES | VALUES ( { \fIexpression\fR | DEFAULT } [, \&.\&.\&.] ) [, \&.\&.\&.] | \fIquery\fR }
+ [ ON CONFLICT [ \fIconflict_target\fR ] \fIconflict_action\fR ]
+ [ RETURNING * | \fIoutput_expression\fR [ [ AS ] \fIoutput_name\fR ] [, \&.\&.\&.] ]
+
+where \fIconflict_target\fR can be one of:
+
+ ( { \fIindex_column_name\fR | ( \fIindex_expression\fR ) } [ COLLATE \fIcollation\fR ] [ \fIopclass\fR ] [, \&.\&.\&.] ) [ WHERE \fIindex_predicate\fR ]
+ ON CONSTRAINT \fIconstraint_name\fR
+
+and \fIconflict_action\fR is one of:
+
+ DO NOTHING
+ DO UPDATE SET { \fIcolumn_name\fR = { \fIexpression\fR | DEFAULT } |
+ ( \fIcolumn_name\fR [, \&.\&.\&.] ) = [ ROW ] ( { \fIexpression\fR | DEFAULT } [, \&.\&.\&.] ) |
+ ( \fIcolumn_name\fR [, \&.\&.\&.] ) = ( \fIsub\-SELECT\fR )
+ } [, \&.\&.\&.]
+ [ WHERE \fIcondition\fR ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBINSERT\fR
+inserts new rows into a table\&. One can insert one or more rows specified by value expressions, or zero or more rows resulting from a query\&.
+.PP
+The target column names can be listed in any order\&. If no list of column names is given at all, the default is all the columns of the table in their declared order; or the first
+\fIN\fR
+column names, if there are only
+\fIN\fR
+columns supplied by the
+VALUES
+clause or
+\fIquery\fR\&. The values supplied by the
+VALUES
+clause or
+\fIquery\fR
+are associated with the explicit or implicit column list left\-to\-right\&.
+.PP
+Each column not present in the explicit or implicit column list will be filled with a default value, either its declared default value or null if there is none\&.
+.PP
+If the expression for any column is not of the correct data type, automatic type conversion will be attempted\&.
+.PP
+\fBINSERT\fR
+into tables that lack unique indexes will not be blocked by concurrent activity\&. Tables with unique indexes might block if concurrent sessions perform actions that lock or modify rows matching the unique index values being inserted; the details are covered in
+Section\ \&64.5\&.
+ON CONFLICT
+can be used to specify an alternative action to raising a unique constraint or exclusion constraint violation error\&. (See
+ON CONFLICT Clause
+below\&.)
+.PP
+The optional
+RETURNING
+clause causes
+\fBINSERT\fR
+to compute and return value(s) based on each row actually inserted (or updated, if an
+ON CONFLICT DO UPDATE
+clause was used)\&. This is primarily useful for obtaining values that were supplied by defaults, such as a serial sequence number\&. However, any expression using the table\*(Aqs columns is allowed\&. The syntax of the
+RETURNING
+list is identical to that of the output list of
+\fBSELECT\fR\&. Only rows that were successfully inserted or updated will be returned\&. For example, if a row was locked but not updated because an
+ON CONFLICT DO UPDATE \&.\&.\&. WHERE
+clause
+\fIcondition\fR
+was not satisfied, the row will not be returned\&.
+.PP
+You must have
+INSERT
+privilege on a table in order to insert into it\&. If
+ON CONFLICT DO UPDATE
+is present,
+UPDATE
+privilege on the table is also required\&.
+.PP
+If a column list is specified, you only need
+INSERT
+privilege on the listed columns\&. Similarly, when
+ON CONFLICT DO UPDATE
+is specified, you only need
+UPDATE
+privilege on the column(s) that are listed to be updated\&. However,
+ON CONFLICT DO UPDATE
+also requires
+SELECT
+privilege on any column whose values are read in the
+ON CONFLICT DO UPDATE
+expressions or
+\fIcondition\fR\&.
+.PP
+Use of the
+RETURNING
+clause requires
+SELECT
+privilege on all columns mentioned in
+RETURNING\&. If you use the
+\fIquery\fR
+clause to insert rows from a query, you of course need to have
+SELECT
+privilege on any table or column used in the query\&.
+.SH "PARAMETERS"
+.SS "Inserting"
+.PP
+This section covers parameters that may be used when only inserting new rows\&. Parameters
+\fIexclusively\fR
+used with the
+ON CONFLICT
+clause are described separately\&.
+.PP
+\fIwith_query\fR
+.RS 4
+The
+WITH
+clause allows you to specify one or more subqueries that can be referenced by name in the
+\fBINSERT\fR
+query\&. See
+Section\ \&7.8
+and
+\fBSELECT\fR(7)
+for details\&.
+.sp
+It is possible for the
+\fIquery\fR
+(\fBSELECT\fR
+statement) to also contain a
+WITH
+clause\&. In such a case both sets of
+\fIwith_query\fR
+can be referenced within the
+\fIquery\fR, but the second one takes precedence since it is more closely nested\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing table\&.
+.RE
+.PP
+\fIalias\fR
+.RS 4
+A substitute name for
+\fItable_name\fR\&. When an alias is provided, it completely hides the actual name of the table\&. This is particularly useful when
+ON CONFLICT DO UPDATE
+targets a table named
+\fIexcluded\fR, since that will otherwise be taken as the name of the special table representing the row proposed for insertion\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column in the table named by
+\fItable_name\fR\&. The column name can be qualified with a subfield name or array subscript, if needed\&. (Inserting into only some fields of a composite column leaves the other fields null\&.) When referencing a column with
+ON CONFLICT DO UPDATE, do not include the table\*(Aqs name in the specification of a target column\&. For example,
+INSERT INTO table_name \&.\&.\&. ON CONFLICT DO UPDATE SET table_name\&.col = 1
+is invalid (this follows the general behavior for
+\fBUPDATE\fR)\&.
+.RE
+.PP
+OVERRIDING SYSTEM VALUE
+.RS 4
+If this clause is specified, then any values supplied for identity columns will override the default sequence\-generated values\&.
+.sp
+For an identity column defined as
+GENERATED ALWAYS, it is an error to insert an explicit value (other than
+DEFAULT) without specifying either
+OVERRIDING SYSTEM VALUE
+or
+OVERRIDING USER VALUE\&. (For an identity column defined as
+GENERATED BY DEFAULT,
+OVERRIDING SYSTEM VALUE
+is the normal behavior and specifying it does nothing, but
+PostgreSQL
+allows it as an extension\&.)
+.RE
+.PP
+OVERRIDING USER VALUE
+.RS 4
+If this clause is specified, then any values supplied for identity columns are ignored and the default sequence\-generated values are applied\&.
+.sp
+This clause is useful for example when copying values between tables\&. Writing
+INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM tbl1
+will copy from
+tbl1
+all columns that are not identity columns in
+tbl2
+while values for the identity columns in
+tbl2
+will be generated by the sequences associated with
+tbl2\&.
+.RE
+.PP
+DEFAULT VALUES
+.RS 4
+All columns will be filled with their default values, as if
+DEFAULT
+were explicitly specified for each column\&. (An
+OVERRIDING
+clause is not permitted in this form\&.)
+.RE
+.PP
+\fIexpression\fR
+.RS 4
+An expression or value to assign to the corresponding column\&.
+.RE
+.PP
+DEFAULT
+.RS 4
+The corresponding column will be filled with its default value\&. An identity column will be filled with a new value generated by the associated sequence\&. For a generated column, specifying this is permitted but merely specifies the normal behavior of computing the column from its generation expression\&.
+.RE
+.PP
+\fIquery\fR
+.RS 4
+A query (\fBSELECT\fR
+statement) that supplies the rows to be inserted\&. Refer to the
+\fBSELECT\fR(7)
+statement for a description of the syntax\&.
+.RE
+.PP
+\fIoutput_expression\fR
+.RS 4
+An expression to be computed and returned by the
+\fBINSERT\fR
+command after each row is inserted or updated\&. The expression can use any column names of the table named by
+\fItable_name\fR\&. Write
+*
+to return all columns of the inserted or updated row(s)\&.
+.RE
+.PP
+\fIoutput_name\fR
+.RS 4
+A name to use for a returned column\&.
+.RE
+.SS "ON CONFLICT Clause"
+.PP
+The optional
+ON CONFLICT
+clause specifies an alternative action to raising a unique violation or exclusion constraint violation error\&. For each individual row proposed for insertion, either the insertion proceeds, or, if an
+\fIarbiter\fR
+constraint or index specified by
+\fIconflict_target\fR
+is violated, the alternative
+\fIconflict_action\fR
+is taken\&.
+ON CONFLICT DO NOTHING
+simply avoids inserting a row as its alternative action\&.
+ON CONFLICT DO UPDATE
+updates the existing row that conflicts with the row proposed for insertion as its alternative action\&.
+.PP
+\fIconflict_target\fR
+can perform
+\fIunique index inference\fR\&. When performing inference, it consists of one or more
+\fIindex_column_name\fR
+columns and/or
+\fIindex_expression\fR
+expressions, and an optional
+\fIindex_predicate\fR\&. All
+\fItable_name\fR
+unique indexes that, without regard to order, contain exactly the
+\fIconflict_target\fR\-specified columns/expressions are inferred (chosen) as arbiter indexes\&. If an
+\fIindex_predicate\fR
+is specified, it must, as a further requirement for inference, satisfy arbiter indexes\&. Note that this means a non\-partial unique index (a unique index without a predicate) will be inferred (and thus used by
+ON CONFLICT) if such an index satisfying every other criteria is available\&. If an attempt at inference is unsuccessful, an error is raised\&.
+.PP
+ON CONFLICT DO UPDATE
+guarantees an atomic
+\fBINSERT\fR
+or
+\fBUPDATE\fR
+outcome; provided there is no independent error, one of those two outcomes is guaranteed, even under high concurrency\&. This is also known as
+UPSERT
+\(em
+\(lqUPDATE or INSERT\(rq\&.
+.PP
+\fIconflict_target\fR
+.RS 4
+Specifies which conflicts
+ON CONFLICT
+takes the alternative action on by choosing
+arbiter indexes\&. Either performs
+\fIunique index inference\fR, or names a constraint explicitly\&. For
+ON CONFLICT DO NOTHING, it is optional to specify a
+\fIconflict_target\fR; when omitted, conflicts with all usable constraints (and unique indexes) are handled\&. For
+ON CONFLICT DO UPDATE, a
+\fIconflict_target\fR
+\fImust\fR
+be provided\&.
+.RE
+.PP
+\fIconflict_action\fR
+.RS 4
+\fIconflict_action\fR
+specifies an alternative
+ON CONFLICT
+action\&. It can be either
+DO NOTHING, or a
+DO UPDATE
+clause specifying the exact details of the
+UPDATE
+action to be performed in case of a conflict\&. The
+SET
+and
+WHERE
+clauses in
+ON CONFLICT DO UPDATE
+have access to the existing row using the table\*(Aqs name (or an alias), and to the row proposed for insertion using the special
+\fIexcluded\fR
+table\&.
+SELECT
+privilege is required on any column in the target table where corresponding
+\fIexcluded\fR
+columns are read\&.
+.sp
+Note that the effects of all per\-row
+BEFORE INSERT
+triggers are reflected in
+\fIexcluded\fR
+values, since those effects may have contributed to the row being excluded from insertion\&.
+.RE
+.PP
+\fIindex_column_name\fR
+.RS 4
+The name of a
+\fItable_name\fR
+column\&. Used to infer arbiter indexes\&. Follows
+\fBCREATE INDEX\fR
+format\&.
+SELECT
+privilege on
+\fIindex_column_name\fR
+is required\&.
+.RE
+.PP
+\fIindex_expression\fR
+.RS 4
+Similar to
+\fIindex_column_name\fR, but used to infer expressions on
+\fItable_name\fR
+columns appearing within index definitions (not simple columns)\&. Follows
+\fBCREATE INDEX\fR
+format\&.
+SELECT
+privilege on any column appearing within
+\fIindex_expression\fR
+is required\&.
+.RE
+.PP
+\fIcollation\fR
+.RS 4
+When specified, mandates that corresponding
+\fIindex_column_name\fR
+or
+\fIindex_expression\fR
+use a particular collation in order to be matched during inference\&. Typically this is omitted, as collations usually do not affect whether or not a constraint violation occurs\&. Follows
+\fBCREATE INDEX\fR
+format\&.
+.RE
+.PP
+\fIopclass\fR
+.RS 4
+When specified, mandates that corresponding
+\fIindex_column_name\fR
+or
+\fIindex_expression\fR
+use particular operator class in order to be matched during inference\&. Typically this is omitted, as the
+\fIequality\fR
+semantics are often equivalent across a type\*(Aqs operator classes anyway, or because it\*(Aqs sufficient to trust that the defined unique indexes have the pertinent definition of equality\&. Follows
+\fBCREATE INDEX\fR
+format\&.
+.RE
+.PP
+\fIindex_predicate\fR
+.RS 4
+Used to allow inference of partial unique indexes\&. Any indexes that satisfy the predicate (which need not actually be partial indexes) can be inferred\&. Follows
+\fBCREATE INDEX\fR
+format\&.
+SELECT
+privilege on any column appearing within
+\fIindex_predicate\fR
+is required\&.
+.RE
+.PP
+\fIconstraint_name\fR
+.RS 4
+Explicitly specifies an arbiter
+\fIconstraint\fR
+by name, rather than inferring a constraint or index\&.
+.RE
+.PP
+\fIcondition\fR
+.RS 4
+An expression that returns a value of type
+boolean\&. Only rows for which this expression returns
+true
+will be updated, although all rows will be locked when the
+ON CONFLICT DO UPDATE
+action is taken\&. Note that
+\fIcondition\fR
+is evaluated last, after a conflict has been identified as a candidate to update\&.
+.RE
+.PP
+Note that exclusion constraints are not supported as arbiters with
+ON CONFLICT DO UPDATE\&. In all cases, only
+NOT DEFERRABLE
+constraints and unique indexes are supported as arbiters\&.
+.PP
+\fBINSERT\fR
+with an
+ON CONFLICT DO UPDATE
+clause is a
+\(lqdeterministic\(rq
+statement\&. This means that the command will not be allowed to affect any single existing row more than once; a cardinality violation error will be raised when this situation arises\&. Rows proposed for insertion should not duplicate each other in terms of attributes constrained by an arbiter index or constraint\&.
+.PP
+Note that it is currently not supported for the
+ON CONFLICT DO UPDATE
+clause of an
+\fBINSERT\fR
+applied to a partitioned table to update the partition key of a conflicting row such that it requires the row be moved to a new partition\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+.PP
+It is often preferable to use unique index inference rather than naming a constraint directly using
+ON CONFLICT ON CONSTRAINT
+\fI constraint_name\fR\&. Inference will continue to work correctly when the underlying index is replaced by another more or less equivalent index in an overlapping way, for example when using
+CREATE UNIQUE INDEX \&.\&.\&. CONCURRENTLY
+before dropping the index being replaced\&.
+.sp .5v
+.RE
+.SH "OUTPUTS"
+.PP
+On successful completion, an
+\fBINSERT\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT \fIoid\fR \fIcount\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fIcount\fR
+is the number of rows inserted or updated\&.
+\fIoid\fR
+is always 0 (it used to be the
+OID
+assigned to the inserted row if
+\fIcount\fR
+was exactly one and the target table was declared
+WITH OIDS
+and 0 otherwise, but creating a table
+WITH OIDS
+is not supported anymore)\&.
+.PP
+If the
+\fBINSERT\fR
+command contains a
+RETURNING
+clause, the result will be similar to that of a
+\fBSELECT\fR
+statement containing the columns and values defined in the
+RETURNING
+list, computed over the row(s) inserted or updated by the command\&.
+.SH "NOTES"
+.PP
+If the specified table is a partitioned table, each row is routed to the appropriate partition and inserted into it\&. If the specified table is a partition, an error will occur if one of the input rows violates the partition constraint\&.
+.PP
+You may also wish to consider using
+\fBMERGE\fR, since that allows mixing
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR
+within a single statement\&. See
+\fBMERGE\fR(7)\&.
+.SH "EXAMPLES"
+.PP
+Insert a single row into table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films VALUES
+ (\*(AqUA502\*(Aq, \*(AqBananas\*(Aq, 105, \*(Aq1971\-07\-13\*(Aq, \*(AqComedy\*(Aq, \*(Aq82 minutes\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+In this example, the
+len
+column is omitted and therefore it will have the default value:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES (\*(AqT_601\*(Aq, \*(AqYojimbo\*(Aq, 106, \*(Aq1961\-06\-16\*(Aq, \*(AqDrama\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example uses the
+DEFAULT
+clause for the date columns rather than specifying a value:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films VALUES
+ (\*(AqUA502\*(Aq, \*(AqBananas\*(Aq, 105, DEFAULT, \*(AqComedy\*(Aq, \*(Aq82 minutes\*(Aq);
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES (\*(AqT_601\*(Aq, \*(AqYojimbo\*(Aq, 106, DEFAULT, \*(AqDrama\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To insert a row consisting entirely of default values:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films DEFAULT VALUES;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To insert multiple rows using the multirow
+\fBVALUES\fR
+syntax:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films (code, title, did, date_prod, kind) VALUES
+ (\*(AqB6717\*(Aq, \*(AqTampopo\*(Aq, 110, \*(Aq1985\-02\-10\*(Aq, \*(AqComedy\*(Aq),
+ (\*(AqHG120\*(Aq, \*(AqThe Dinner Game\*(Aq, 140, DEFAULT, \*(AqComedy\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example inserts some rows into table
+films
+from a table
+tmp_films
+with the same column layout as
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < \*(Aq2004\-05\-07\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example inserts into array columns:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\-\- Create an empty 3x3 gameboard for noughts\-and\-crosses
+INSERT INTO tictactoe (game, board[1:3][1:3])
+ VALUES (1, \*(Aq{{" "," "," "},{" "," "," "},{" "," "," "}}\*(Aq);
+\-\- The subscripts in the above example aren\*(Aqt really needed
+INSERT INTO tictactoe (game, board)
+ VALUES (2, \*(Aq{{X," "," "},{" ",O," "},{" ",X," "}}\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Insert a single row into table
+distributors, returning the sequence number generated by the
+DEFAULT
+clause:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO distributors (did, dname) VALUES (DEFAULT, \*(AqXYZ Widgets\*(Aq)
+ RETURNING did;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Increment the sales count of the salesperson who manages the account for Acme Corporation, and record the whole updated row along with current time in a log table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WITH upd AS (
+ UPDATE employees SET sales_count = sales_count + 1 WHERE id =
+ (SELECT sales_person FROM accounts WHERE name = \*(AqAcme Corporation\*(Aq)
+ RETURNING *
+)
+INSERT INTO employees_log SELECT *, current_timestamp FROM upd;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Insert or update new distributors as appropriate\&. Assumes a unique index has been defined that constrains values appearing in the
+did
+column\&. Note that the special
+\fIexcluded\fR
+table is used to reference values originally proposed for insertion:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO distributors (did, dname)
+ VALUES (5, \*(AqGizmo Transglobal\*(Aq), (6, \*(AqAssociated Computing, Inc\*(Aq)
+ ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED\&.dname;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Insert a distributor, or do nothing for rows proposed for insertion when an existing, excluded row (a row with a matching constrained column or columns after before row insert triggers fire) exists\&. Example assumes a unique index has been defined that constrains values appearing in the
+did
+column:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO distributors (did, dname) VALUES (7, \*(AqRedline GmbH\*(Aq)
+ ON CONFLICT (did) DO NOTHING;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Insert or update new distributors as appropriate\&. Example assumes a unique index has been defined that constrains values appearing in the
+did
+column\&.
+WHERE
+clause is used to limit the rows actually updated (any existing row not updated will still be locked, though):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\-\- Don\*(Aqt update existing distributors based in a certain ZIP code
+INSERT INTO distributors AS d (did, dname) VALUES (8, \*(AqAnvil Distribution\*(Aq)
+ ON CONFLICT (did) DO UPDATE
+ SET dname = EXCLUDED\&.dname || \*(Aq (formerly \*(Aq || d\&.dname || \*(Aq)\*(Aq
+ WHERE d\&.zipcode <> \*(Aq21201\*(Aq;
+
+\-\- Name a constraint directly in the statement (uses associated
+\-\- index to arbitrate taking the DO NOTHING action)
+INSERT INTO distributors (did, dname) VALUES (9, \*(AqAntwerp Design\*(Aq)
+ ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Insert new distributor if possible; otherwise
+DO NOTHING\&. Example assumes a unique index has been defined that constrains values appearing in the
+did
+column on a subset of rows where the
+is_active
+Boolean column evaluates to
+true:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\-\- This statement could infer a partial unique index on "did"
+\-\- with a predicate of "WHERE is_active", but it could also
+\-\- just use a regular unique constraint on "did"
+INSERT INTO distributors (did, dname) VALUES (10, \*(AqConrad International\*(Aq)
+ ON CONFLICT (did) WHERE is_active DO NOTHING;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBINSERT\fR
+conforms to the SQL standard, except that the
+RETURNING
+clause is a
+PostgreSQL
+extension, as is the ability to use
+WITH
+with
+\fBINSERT\fR, and the ability to specify an alternative action with
+ON CONFLICT\&. Also, the case in which a column name list is omitted, but not all the columns are filled from the
+VALUES
+clause or
+\fIquery\fR, is disallowed by the standard\&. If you prefer a more SQL standard conforming statement than
+ON CONFLICT, see
+\fBMERGE\fR(7)\&.
+.PP
+The SQL standard specifies that
+OVERRIDING SYSTEM VALUE
+can only be specified if an identity column that is generated always exists\&. PostgreSQL allows the clause in any case and ignores it if it is not applicable\&.
+.PP
+Possible limitations of the
+\fIquery\fR
+clause are documented under
+\fBSELECT\fR(7)\&.
diff --git a/doc/src/sgml/man7/LISTEN.7 b/doc/src/sgml/man7/LISTEN.7
new file mode 100644
index 0000000..d574997
--- /dev/null
+++ b/doc/src/sgml/man7/LISTEN.7
@@ -0,0 +1,117 @@
+'\" t
+.\" Title: LISTEN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "LISTEN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+LISTEN \- listen for a notification
+.SH "SYNOPSIS"
+.sp
+.nf
+LISTEN \fIchannel\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBLISTEN\fR
+registers the current session as a listener on the notification channel named
+\fIchannel\fR\&. If the current session is already registered as a listener for this notification channel, nothing is done\&.
+.PP
+Whenever the command
+\fBNOTIFY \fR\fB\fIchannel\fR\fR
+is invoked, either by this session or another one connected to the same database, all the sessions currently listening on that notification channel are notified, and each will in turn notify its connected client application\&.
+.PP
+A session can be unregistered for a given notification channel with the
+\fBUNLISTEN\fR
+command\&. A session\*(Aqs listen registrations are automatically cleared when the session ends\&.
+.PP
+The method a client application must use to detect notification events depends on which
+PostgreSQL
+application programming interface it uses\&. With the
+libpq
+library, the application issues
+\fBLISTEN\fR
+as an ordinary SQL command, and then must periodically call the function
+\fBPQnotifies\fR
+to find out whether any notification events have been received\&. Other interfaces such as
+libpgtcl
+provide higher\-level methods for handling notify events; indeed, with
+libpgtcl
+the application programmer should not even issue
+\fBLISTEN\fR
+or
+\fBUNLISTEN\fR
+directly\&. See the documentation for the interface you are using for more details\&.
+.SH "PARAMETERS"
+.PP
+\fIchannel\fR
+.RS 4
+Name of a notification channel (any identifier)\&.
+.RE
+.SH "NOTES"
+.PP
+\fBLISTEN\fR
+takes effect at transaction commit\&. If
+\fBLISTEN\fR
+or
+\fBUNLISTEN\fR
+is executed within a transaction that later rolls back, the set of notification channels being listened to is unchanged\&.
+.PP
+A transaction that has executed
+\fBLISTEN\fR
+cannot be prepared for two\-phase commit\&.
+.PP
+There is a race condition when first setting up a listening session: if concurrently\-committing transactions are sending notify events, exactly which of those will the newly listening session receive? The answer is that the session will receive all events committed after an instant during the transaction\*(Aqs commit step\&. But that is slightly later than any database state that the transaction could have observed in queries\&. This leads to the following rule for using
+\fBLISTEN\fR: first execute (and commit!) that command, then in a new transaction inspect the database state as needed by the application logic, then rely on notifications to find out about subsequent changes to the database state\&. The first few received notifications might refer to updates already observed in the initial database inspection, but this is usually harmless\&.
+.PP
+\fBNOTIFY\fR(7)
+contains a more extensive discussion of the use of
+\fBLISTEN\fR
+and
+\fBNOTIFY\fR\&.
+.SH "EXAMPLES"
+.PP
+Configure and execute a listen/notify sequence from
+psql:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448\&.
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBLISTEN\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBNOTIFY\fR(7), \fBUNLISTEN\fR(7)
diff --git a/doc/src/sgml/man7/LOAD.7 b/doc/src/sgml/man7/LOAD.7
new file mode 100644
index 0000000..df49469
--- /dev/null
+++ b/doc/src/sgml/man7/LOAD.7
@@ -0,0 +1,69 @@
+'\" t
+.\" Title: LOAD
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "LOAD" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+LOAD \- load a shared library file
+.SH "SYNOPSIS"
+.sp
+.nf
+LOAD \*(Aq\fIfilename\fR\*(Aq
+.fi
+.SH "DESCRIPTION"
+.PP
+This command loads a shared library file into the
+PostgreSQL
+server\*(Aqs address space\&. If the file has been loaded already, the command does nothing\&. Shared library files that contain C functions are automatically loaded whenever one of their functions is called\&. Therefore, an explicit
+\fBLOAD\fR
+is usually only needed to load a library that modifies the server\*(Aqs behavior through
+\(lqhooks\(rq
+rather than providing a set of functions\&.
+.PP
+The library file name is typically given as just a bare file name, which is sought in the server\*(Aqs library search path (set by
+dynamic_library_path)\&. Alternatively it can be given as a full path name\&. In either case the platform\*(Aqs standard shared library file name extension may be omitted\&. See
+Section\ \&38.10.1
+for more information on this topic\&.
+.PP
+Non\-superusers can only apply
+\fBLOAD\fR
+to library files located in
+$libdir/plugins/
+\(em the specified
+\fIfilename\fR
+must begin with exactly that string\&. (It is the database administrator\*(Aqs responsibility to ensure that only
+\(lqsafe\(rq
+libraries are installed there\&.)
+.SH "COMPATIBILITY"
+.PP
+\fBLOAD\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+.PP
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))
diff --git a/doc/src/sgml/man7/LOCK.7 b/doc/src/sgml/man7/LOCK.7
new file mode 100644
index 0000000..4375e15
--- /dev/null
+++ b/doc/src/sgml/man7/LOCK.7
@@ -0,0 +1,259 @@
+'\" t
+.\" Title: LOCK
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "LOCK" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+LOCK \- lock a table
+.SH "SYNOPSIS"
+.sp
+.nf
+LOCK [ TABLE ] [ ONLY ] \fIname\fR [ * ] [, \&.\&.\&.] [ IN \fIlockmode\fR MODE ] [ NOWAIT ]
+
+where \fIlockmode\fR is one of:
+
+ ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
+ | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBLOCK TABLE\fR
+obtains a table\-level lock, waiting if necessary for any conflicting locks to be released\&. If
+NOWAIT
+is specified,
+\fBLOCK TABLE\fR
+does not wait to acquire the desired lock: if it cannot be acquired immediately, the command is aborted and an error is emitted\&. Once obtained, the lock is held for the remainder of the current transaction\&. (There is no
+\fBUNLOCK TABLE\fR
+command; locks are always released at transaction end\&.)
+.PP
+When a view is locked, all relations appearing in the view definition query are also locked recursively with the same lock mode\&.
+.PP
+When acquiring locks automatically for commands that reference tables,
+PostgreSQL
+always uses the least restrictive lock mode possible\&.
+\fBLOCK TABLE\fR
+provides for cases when you might need more restrictive locking\&. For example, suppose an application runs a transaction at the
+READ COMMITTED
+isolation level and needs to ensure that data in a table remains stable for the duration of the transaction\&. To achieve this you could obtain
+SHARE
+lock mode over the table before querying\&. This will prevent concurrent data changes and ensure subsequent reads of the table see a stable view of committed data, because
+SHARE
+lock mode conflicts with the
+ROW EXCLUSIVE
+lock acquired by writers, and your
+\fBLOCK TABLE \fR\fB\fIname\fR\fR\fB IN SHARE MODE\fR
+statement will wait until any concurrent holders of
+ROW EXCLUSIVE
+mode locks commit or roll back\&. Thus, once you obtain the lock, there are no uncommitted writes outstanding; furthermore none can begin until you release the lock\&.
+.PP
+To achieve a similar effect when running a transaction at the
+REPEATABLE READ
+or
+SERIALIZABLE
+isolation level, you have to execute the
+\fBLOCK TABLE\fR
+statement before executing any
+\fBSELECT\fR
+or data modification statement\&. A
+REPEATABLE READ
+or
+SERIALIZABLE
+transaction\*(Aqs view of data will be frozen when its first
+\fBSELECT\fR
+or data modification statement begins\&. A
+\fBLOCK TABLE\fR
+later in the transaction will still prevent concurrent writes \(em but it won\*(Aqt ensure that what the transaction reads corresponds to the latest committed values\&.
+.PP
+If a transaction of this sort is going to change the data in the table, then it should use
+SHARE ROW EXCLUSIVE
+lock mode instead of
+SHARE
+mode\&. This ensures that only one transaction of this type runs at a time\&. Without this, a deadlock is possible: two transactions might both acquire
+SHARE
+mode, and then be unable to also acquire
+ROW EXCLUSIVE
+mode to actually perform their updates\&. (Note that a transaction\*(Aqs own locks never conflict, so a transaction can acquire
+ROW EXCLUSIVE
+mode when it holds
+SHARE
+mode \(em but not if anyone else holds
+SHARE
+mode\&.) To avoid deadlocks, make sure all transactions acquire locks on the same objects in the same order, and if multiple lock modes are involved for a single object, then transactions should always acquire the most restrictive mode first\&.
+.PP
+More information about the lock modes and locking strategies can be found in
+Section\ \&13.3\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing table to lock\&. If
+ONLY
+is specified before the table name, only that table is locked\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are locked\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.sp
+The command
+LOCK TABLE a, b;
+is equivalent to
+LOCK TABLE a; LOCK TABLE b;\&. The tables are locked one\-by\-one in the order specified in the
+\fBLOCK TABLE\fR
+command\&.
+.RE
+.PP
+\fIlockmode\fR
+.RS 4
+The lock mode specifies which locks this lock conflicts with\&. Lock modes are described in
+Section\ \&13.3\&.
+.sp
+If no lock mode is specified, then
+ACCESS EXCLUSIVE, the most restrictive mode, is used\&.
+.RE
+.PP
+NOWAIT
+.RS 4
+Specifies that
+\fBLOCK TABLE\fR
+should not wait for any conflicting locks to be released: if the specified lock(s) cannot be acquired immediately without waiting, the transaction is aborted\&.
+.RE
+.SH "NOTES"
+.PP
+LOCK TABLE \&.\&.\&. IN ACCESS SHARE MODE
+requires
+SELECT
+privileges on the target table\&.
+LOCK TABLE \&.\&.\&. IN ROW EXCLUSIVE MODE
+requires
+INSERT,
+UPDATE,
+DELETE, or
+TRUNCATE
+privileges on the target table\&. All other forms of
+\fBLOCK\fR
+require table\-level
+UPDATE,
+DELETE, or
+TRUNCATE
+privileges\&.
+.PP
+The user performing the lock on the view must have the corresponding privilege on the view\&. In addition, by default, the view\*(Aqs owner must have the relevant privileges on the underlying base relations, whereas the user performing the lock does not need any permissions on the underlying base relations\&. However, if the view has
+security_invoker
+set to
+true
+(see
+\fBCREATE VIEW\fR), the user performing the lock, rather than the view owner, must have the relevant privileges on the underlying base relations\&.
+.PP
+\fBLOCK TABLE\fR
+is useless outside a transaction block: the lock would remain held only to the completion of the statement\&. Therefore
+PostgreSQL
+reports an error if
+\fBLOCK\fR
+is used outside a transaction block\&. Use
+\fBBEGIN\fR
+and
+\fBCOMMIT\fR
+(or
+\fBROLLBACK\fR) to define a transaction block\&.
+.PP
+\fBLOCK TABLE\fR
+only deals with table\-level locks, and so the mode names involving
+ROW
+are all misnomers\&. These mode names should generally be read as indicating the intention of the user to acquire row\-level locks within the locked table\&. Also,
+ROW EXCLUSIVE
+mode is a shareable table lock\&. Keep in mind that all the lock modes have identical semantics so far as
+\fBLOCK TABLE\fR
+is concerned, differing only in the rules about which modes conflict with which\&. For information on how to acquire an actual row\-level lock, see
+Section\ \&13.3.2
+and
+The Locking Clause
+in the
+\fBSELECT\fR(7)
+documentation\&.
+.SH "EXAMPLES"
+.PP
+Obtain a
+SHARE
+lock on a primary key table when going to perform inserts into a foreign key table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN WORK;
+LOCK TABLE films IN SHARE MODE;
+SELECT id FROM films
+ WHERE name = \*(AqStar Wars: Episode I \- The Phantom Menace\*(Aq;
+\-\- Do ROLLBACK if record was not returned
+INSERT INTO films_user_comments VALUES
+ (_id_, \*(AqGREAT! I was waiting for it for so long!\*(Aq);
+COMMIT WORK;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Take a
+SHARE ROW EXCLUSIVE
+lock on a primary key table when going to perform a delete operation:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN WORK;
+LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
+DELETE FROM films_user_comments WHERE id IN
+ (SELECT id FROM films WHERE rating < 5);
+DELETE FROM films WHERE rating < 5;
+COMMIT WORK;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBLOCK TABLE\fR
+in the SQL standard, which instead uses
+\fBSET TRANSACTION\fR
+to specify concurrency levels on transactions\&.
+PostgreSQL
+supports that too; see
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))
+for details\&.
+.PP
+Except for
+ACCESS SHARE,
+ACCESS EXCLUSIVE, and
+SHARE UPDATE EXCLUSIVE
+lock modes, the
+PostgreSQL
+lock modes and the
+\fBLOCK TABLE\fR
+syntax are compatible with those present in
+Oracle\&.
diff --git a/doc/src/sgml/man7/MERGE.7 b/doc/src/sgml/man7/MERGE.7
new file mode 100644
index 0000000..9ba3834
--- /dev/null
+++ b/doc/src/sgml/man7/MERGE.7
@@ -0,0 +1,674 @@
+'\" t
+.\" Title: MERGE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "MERGE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+MERGE \- conditionally insert, update, or delete rows of a table
+.SH "SYNOPSIS"
+.sp
+.nf
+[ WITH \fIwith_query\fR [, \&.\&.\&.] ]
+MERGE INTO [ ONLY ] \fItarget_table_name\fR [ * ] [ [ AS ] \fItarget_alias\fR ]
+USING \fIdata_source\fR ON \fIjoin_condition\fR
+\fIwhen_clause\fR [\&.\&.\&.]
+
+where \fIdata_source\fR is:
+
+{ [ ONLY ] \fIsource_table_name\fR [ * ] | ( \fIsource_query\fR ) } [ [ AS ] \fIsource_alias\fR ]
+
+and \fIwhen_clause\fR is:
+
+{ WHEN MATCHED [ AND \fIcondition\fR ] THEN { \fImerge_update\fR | \fImerge_delete\fR | DO NOTHING } |
+ WHEN NOT MATCHED [ AND \fIcondition\fR ] THEN { \fImerge_insert\fR | DO NOTHING } }
+
+and \fImerge_insert\fR is:
+
+INSERT [( \fIcolumn_name\fR [, \&.\&.\&.] )]
+[ OVERRIDING { SYSTEM | USER } VALUE ]
+{ VALUES ( { \fIexpression\fR | DEFAULT } [, \&.\&.\&.] ) | DEFAULT VALUES }
+
+and \fImerge_update\fR is:
+
+UPDATE SET { \fIcolumn_name\fR = { \fIexpression\fR | DEFAULT } |
+ ( \fIcolumn_name\fR [, \&.\&.\&.] ) = ( { \fIexpression\fR | DEFAULT } [, \&.\&.\&.] ) } [, \&.\&.\&.]
+
+and \fImerge_delete\fR is:
+
+DELETE
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBMERGE\fR
+performs actions that modify rows in the
+\fItarget_table_name\fR, using the
+\fIdata_source\fR\&.
+\fBMERGE\fR
+provides a single
+SQL
+statement that can conditionally
+\fBINSERT\fR,
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+rows, a task that would otherwise require multiple procedural language statements\&.
+.PP
+First, the
+\fBMERGE\fR
+command performs a join from
+\fIdata_source\fR
+to
+\fItarget_table_name\fR
+producing zero or more candidate change rows\&. For each candidate change row, the status of
+MATCHED
+or
+NOT MATCHED
+is set just once, after which
+WHEN
+clauses are evaluated in the order specified\&. For each candidate change row, the first clause to evaluate as true is executed\&. No more than one
+WHEN
+clause is executed for any candidate change row\&.
+.PP
+\fBMERGE\fR
+actions have the same effect as regular
+\fBUPDATE\fR,
+\fBINSERT\fR, or
+\fBDELETE\fR
+commands of the same names\&. The syntax of those commands is different, notably that there is no
+WHERE
+clause and no table name is specified\&. All actions refer to the
+\fItarget_table_name\fR, though modifications to other tables may be made using triggers\&.
+.PP
+When
+DO NOTHING
+is specified, the source row is skipped\&. Since actions are evaluated in their specified order,
+DO NOTHING
+can be handy to skip non\-interesting source rows before more fine\-grained handling\&.
+.PP
+There is no separate
+MERGE
+privilege\&. If you specify an update action, you must have the
+UPDATE
+privilege on the column(s) of the
+\fItarget_table_name\fR
+that are referred to in the
+SET
+clause\&. If you specify an insert action, you must have the
+INSERT
+privilege on the
+\fItarget_table_name\fR\&. If you specify an delete action, you must have the
+DELETE
+privilege on the
+\fItarget_table_name\fR\&. Privileges are tested once at statement start and are checked whether or not particular
+WHEN
+clauses are executed\&. You will require the
+SELECT
+privilege on the
+\fIdata_source\fR
+and any column(s) of the
+\fItarget_table_name\fR
+referred to in a
+condition\&.
+.PP
+\fBMERGE\fR
+is not supported if the
+\fItarget_table_name\fR
+is a materialized view, foreign table, or if it has any rules defined on it\&.
+.SH "PARAMETERS"
+.PP
+\fItarget_table_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the target table to merge into\&. If
+ONLY
+is specified before the table name, matching rows are updated or deleted in the named table only\&. If
+ONLY
+is not specified, matching rows are also updated or deleted in any tables inheriting from the named table\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&. The
+ONLY
+keyword and
+*
+option do not affect insert actions, which always insert into the named table only\&.
+.RE
+.PP
+\fItarget_alias\fR
+.RS 4
+A substitute name for the target table\&. When an alias is provided, it completely hides the actual name of the table\&. For example, given
+MERGE INTO foo AS f, the remainder of the
+\fBMERGE\fR
+statement must refer to this table as
+f
+not
+foo\&.
+.RE
+.PP
+\fIsource_table_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the source table, view, or transition table\&. If
+ONLY
+is specified before the table name, matching rows are included from the named table only\&. If
+ONLY
+is not specified, matching rows are also included from any tables inheriting from the named table\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+\fIsource_query\fR
+.RS 4
+A query (\fBSELECT\fR
+statement or
+\fBVALUES\fR
+statement) that supplies the rows to be merged into the
+\fItarget_table_name\fR\&. Refer to the
+\fBSELECT\fR(7)
+statement or
+\fBVALUES\fR(7)
+statement for a description of the syntax\&.
+.RE
+.PP
+\fIsource_alias\fR
+.RS 4
+A substitute name for the data source\&. When an alias is provided, it completely hides the actual name of the table or the fact that a query was issued\&.
+.RE
+.PP
+\fIjoin_condition\fR
+.RS 4
+\fIjoin_condition\fR
+is an expression resulting in a value of type
+boolean
+(similar to a
+WHERE
+clause) that specifies which rows in the
+\fIdata_source\fR
+match rows in the
+\fItarget_table_name\fR\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBWarning\fR
+.ps -1
+.br
+Only columns from
+\fItarget_table_name\fR
+that attempt to match
+\fIdata_source\fR
+rows should appear in
+\fIjoin_condition\fR\&.
+\fIjoin_condition\fR
+subexpressions that only reference
+\fItarget_table_name\fR
+columns can affect which action is taken, often in surprising ways\&.
+.sp .5v
+.RE
+.RE
+.PP
+\fIwhen_clause\fR
+.RS 4
+At least one
+WHEN
+clause is required\&.
+.sp
+If the
+WHEN
+clause specifies
+WHEN MATCHED
+and the candidate change row matches a row in the
+\fItarget_table_name\fR, the
+WHEN
+clause is executed if the
+\fIcondition\fR
+is absent or it evaluates to
+true\&.
+.sp
+Conversely, if the
+WHEN
+clause specifies
+WHEN NOT MATCHED
+and the candidate change row does not match a row in the
+\fItarget_table_name\fR, the
+WHEN
+clause is executed if the
+\fIcondition\fR
+is absent or it evaluates to
+true\&.
+.RE
+.PP
+\fIcondition\fR
+.RS 4
+An expression that returns a value of type
+boolean\&. If this expression for a
+WHEN
+clause returns
+true, then the action for that clause is executed for that row\&.
+.sp
+A condition on a
+WHEN MATCHED
+clause can refer to columns in both the source and the target relations\&. A condition on a
+WHEN NOT MATCHED
+clause can only refer to columns from the source relation, since by definition there is no matching target row\&. Only the system attributes from the target table are accessible\&.
+.RE
+.PP
+\fImerge_insert\fR
+.RS 4
+The specification of an
+INSERT
+action that inserts one row into the target table\&. The target column names can be listed in any order\&. If no list of column names is given at all, the default is all the columns of the table in their declared order\&.
+.sp
+Each column not present in the explicit or implicit column list will be filled with a default value, either its declared default value or null if there is none\&.
+.sp
+If
+\fItarget_table_name\fR
+is a partitioned table, each row is routed to the appropriate partition and inserted into it\&. If
+\fItarget_table_name\fR
+is a partition, an error will occur if any input row violates the partition constraint\&.
+.sp
+Column names may not be specified more than once\&.
+\fBINSERT\fR
+actions cannot contain sub\-selects\&.
+.sp
+Only one
+VALUES
+clause can be specified\&. The
+VALUES
+clause can only refer to columns from the source relation, since by definition there is no matching target row\&.
+.RE
+.PP
+\fImerge_update\fR
+.RS 4
+The specification of an
+UPDATE
+action that updates the current row of the
+\fItarget_table_name\fR\&. Column names may not be specified more than once\&.
+.sp
+Neither a table name nor a
+WHERE
+clause are allowed\&.
+.RE
+.PP
+\fImerge_delete\fR
+.RS 4
+Specifies a
+DELETE
+action that deletes the current row of the
+\fItarget_table_name\fR\&. Do not include the table name or any other clauses, as you would normally do with a
+\fBDELETE\fR(7)
+command\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column in the
+\fItarget_table_name\fR\&. The column name can be qualified with a subfield name or array subscript, if needed\&. (Inserting into only some fields of a composite column leaves the other fields null\&.) Do not include the table\*(Aqs name in the specification of a target column\&.
+.RE
+.PP
+OVERRIDING SYSTEM VALUE
+.RS 4
+Without this clause, it is an error to specify an explicit value (other than
+DEFAULT) for an identity column defined as
+GENERATED ALWAYS\&. This clause overrides that restriction\&.
+.RE
+.PP
+OVERRIDING USER VALUE
+.RS 4
+If this clause is specified, then any values supplied for identity columns defined as
+GENERATED BY DEFAULT
+are ignored and the default sequence\-generated values are applied\&.
+.RE
+.PP
+DEFAULT VALUES
+.RS 4
+All columns will be filled with their default values\&. (An
+OVERRIDING
+clause is not permitted in this form\&.)
+.RE
+.PP
+\fIexpression\fR
+.RS 4
+An expression to assign to the column\&. If used in a
+WHEN MATCHED
+clause, the expression can use values from the original row in the target table, and values from the
+data_source
+row\&. If used in a
+WHEN NOT MATCHED
+clause, the expression can use values from the
+data_source\&.
+.RE
+.PP
+DEFAULT
+.RS 4
+Set the column to its default value (which will be
+NULL
+if no specific default expression has been assigned to it)\&.
+.RE
+.PP
+\fIwith_query\fR
+.RS 4
+The
+WITH
+clause allows you to specify one or more subqueries that can be referenced by name in the
+\fBMERGE\fR
+query\&. See
+Section\ \&7.8
+and
+\fBSELECT\fR(7)
+for details\&.
+.RE
+.SH "OUTPUTS"
+.PP
+On successful completion, a
+\fBMERGE\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+MERGE \fItotal_count\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fItotal_count\fR
+is the total number of rows changed (whether inserted, updated, or deleted)\&. If
+\fItotal_count\fR
+is 0, no rows were changed in any way\&.
+.SH "NOTES"
+.PP
+The following steps take place during the execution of
+\fBMERGE\fR\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Perform any
+BEFORE STATEMENT
+triggers for all actions specified, whether or not their
+WHEN
+clauses match\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+Perform a join from source to target table\&. The resulting query will be optimized normally and will produce a set of candidate change rows\&. For each candidate change row,
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Evaluate whether each row is
+MATCHED
+or
+NOT MATCHED\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+Test each
+WHEN
+condition in the order specified until one returns true\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+When a condition returns true, perform the following actions:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+Perform any
+BEFORE ROW
+triggers that fire for the action\*(Aqs event type\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+Perform the specified action, invoking any check constraints on the target table\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Perform any
+AFTER ROW
+triggers that fire for the action\*(Aqs event type\&.
+.RE
+.RE
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Perform any
+AFTER STATEMENT
+triggers for actions specified, whether or not they actually occur\&. This is similar to the behavior of an
+\fBUPDATE\fR
+statement that modifies no rows\&.
+.RE
+.sp
+In summary, statement triggers for an event type (say,
+\fBINSERT\fR) will be fired whenever we
+\fIspecify\fR
+an action of that kind\&. In contrast, row\-level triggers will fire only for the specific event type being
+\fIexecuted\fR\&. So a
+\fBMERGE\fR
+command might fire statement triggers for both
+\fBUPDATE\fR
+and
+\fBINSERT\fR, even though only
+\fBUPDATE\fR
+row triggers were fired\&.
+.PP
+You should ensure that the join produces at most one candidate change row for each target row\&. In other words, a target row shouldn\*(Aqt join to more than one data source row\&. If it does, then only one of the candidate change rows will be used to modify the target row; later attempts to modify the row will cause an error\&. This can also occur if row triggers make changes to the target table and the rows so modified are then subsequently also modified by
+\fBMERGE\fR\&. If the repeated action is an
+\fBINSERT\fR, this will cause a uniqueness violation, while a repeated
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+will cause a cardinality violation; the latter behavior is required by the
+SQL
+standard\&. This differs from historical
+PostgreSQL
+behavior of joins in
+\fBUPDATE\fR
+and
+\fBDELETE\fR
+statements where second and subsequent attempts to modify the same row are simply ignored\&.
+.PP
+If a
+WHEN
+clause omits an
+AND
+sub\-clause, it becomes the final reachable clause of that kind (MATCHED
+or
+NOT MATCHED)\&. If a later
+WHEN
+clause of that kind is specified it would be provably unreachable and an error is raised\&. If no final reachable clause is specified of either kind, it is possible that no action will be taken for a candidate change row\&.
+.PP
+The order in which rows are generated from the data source is indeterminate by default\&. A
+\fIsource_query\fR
+can be used to specify a consistent ordering, if required, which might be needed to avoid deadlocks between concurrent transactions\&.
+.PP
+There is no
+RETURNING
+clause with
+\fBMERGE\fR\&. Actions of
+\fBINSERT\fR,
+\fBUPDATE\fR
+and
+\fBDELETE\fR
+cannot contain
+RETURNING
+or
+WITH
+clauses\&.
+.PP
+When
+\fBMERGE\fR
+is run concurrently with other commands that modify the target table, the usual transaction isolation rules apply; see
+Section\ \&13.2
+for an explanation on the behavior at each isolation level\&. You may also wish to consider using
+\fBINSERT \&.\&.\&. ON CONFLICT\fR
+as an alternative statement which offers the ability to run an
+\fBUPDATE\fR
+if a concurrent
+\fBINSERT\fR
+occurs\&. There are a variety of differences and restrictions between the two statement types and they are not interchangeable\&.
+.SH "EXAMPLES"
+.PP
+Perform maintenance on
+customer_accounts
+based upon new
+recent_transactions\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+MERGE INTO customer_account ca
+USING recent_transactions t
+ON t\&.customer_id = ca\&.customer_id
+WHEN MATCHED THEN
+ UPDATE SET balance = balance + transaction_value
+WHEN NOT MATCHED THEN
+ INSERT (customer_id, balance)
+ VALUES (t\&.customer_id, t\&.transaction_value);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Notice that this would be exactly equivalent to the following statement because the
+MATCHED
+result does not change during execution\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+MERGE INTO customer_account ca
+USING (SELECT customer_id, transaction_value FROM recent_transactions) AS t
+ON t\&.customer_id = ca\&.customer_id
+WHEN MATCHED THEN
+ UPDATE SET balance = balance + transaction_value
+WHEN NOT MATCHED THEN
+ INSERT (customer_id, balance)
+ VALUES (t\&.customer_id, t\&.transaction_value);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Attempt to insert a new stock item along with the quantity of stock\&. If the item already exists, instead update the stock count of the existing item\&. Don\*(Aqt allow entries that have zero stock\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+MERGE INTO wines w
+USING wine_stock_changes s
+ON s\&.winename = w\&.winename
+WHEN NOT MATCHED AND s\&.stock_delta > 0 THEN
+ INSERT VALUES(s\&.winename, s\&.stock_delta)
+WHEN MATCHED AND w\&.stock + s\&.stock_delta > 0 THEN
+ UPDATE SET stock = w\&.stock + s\&.stock_delta
+WHEN MATCHED THEN
+ DELETE;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+wine_stock_changes
+table might be, for example, a temporary table recently loaded into the database\&.
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the
+SQL
+standard\&.
+.PP
+The WITH clause and
+DO NOTHING
+action are extensions to the
+SQL
+standard\&.
diff --git a/doc/src/sgml/man7/MOVE.7 b/doc/src/sgml/man7/MOVE.7
new file mode 100644
index 0000000..33b58b1
--- /dev/null
+++ b/doc/src/sgml/man7/MOVE.7
@@ -0,0 +1,124 @@
+'\" t
+.\" Title: MOVE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "MOVE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+MOVE \- position a cursor
+.SH "SYNOPSIS"
+.sp
+.nf
+MOVE [ \fIdirection\fR ] [ FROM | IN ] \fIcursor_name\fR
+
+where \fIdirection\fR can be one of:
+
+ NEXT
+ PRIOR
+ FIRST
+ LAST
+ ABSOLUTE \fIcount\fR
+ RELATIVE \fIcount\fR
+ \fIcount\fR
+ ALL
+ FORWARD
+ FORWARD \fIcount\fR
+ FORWARD ALL
+ BACKWARD
+ BACKWARD \fIcount\fR
+ BACKWARD ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBMOVE\fR
+repositions a cursor without retrieving any data\&.
+\fBMOVE\fR
+works exactly like the
+\fBFETCH\fR
+command, except it only positions the cursor and does not return rows\&.
+.PP
+The parameters for the
+\fBMOVE\fR
+command are identical to those of the
+\fBFETCH\fR
+command; refer to
+\fBFETCH\fR(7)
+for details on syntax and usage\&.
+.SH "OUTPUTS"
+.PP
+On successful completion, a
+\fBMOVE\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+MOVE \fIcount\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fIcount\fR
+is the number of rows that a
+\fBFETCH\fR
+command with the same parameters would have returned (possibly zero)\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN WORK;
+DECLARE liahona CURSOR FOR SELECT * FROM films;
+
+\-\- Skip the first 5 rows:
+MOVE FORWARD 5 IN liahona;
+MOVE 5
+
+\-\- Fetch the 6th row from the cursor liahona:
+FETCH 1 FROM liahona;
+ code | title | did | date_prod | kind | len
+\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+ P_303 | 48 Hrs | 103 | 1982\-10\-22 | Action | 01:37
+(1 row)
+
+\-\- Close the cursor liahona and end the transaction:
+CLOSE liahona;
+COMMIT WORK;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBMOVE\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBCLOSE\fR(7), \fBDECLARE\fR(7), \fBFETCH\fR(7)
diff --git a/doc/src/sgml/man7/NOTIFY.7 b/doc/src/sgml/man7/NOTIFY.7
new file mode 100644
index 0000000..3cf4599
--- /dev/null
+++ b/doc/src/sgml/man7/NOTIFY.7
@@ -0,0 +1,154 @@
+'\" t
+.\" Title: NOTIFY
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "NOTIFY" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+NOTIFY \- generate a notification
+.SH "SYNOPSIS"
+.sp
+.nf
+NOTIFY \fIchannel\fR [ , \fIpayload\fR ]
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBNOTIFY\fR
+command sends a notification event together with an optional
+\(lqpayload\(rq
+string to each client application that has previously executed
+\fBLISTEN \fR\fB\fIchannel\fR\fR
+for the specified channel name in the current database\&. Notifications are visible to all users\&.
+.PP
+\fBNOTIFY\fR
+provides a simple interprocess communication mechanism for a collection of processes accessing the same
+PostgreSQL
+database\&. A payload string can be sent along with the notification, and higher\-level mechanisms for passing structured data can be built by using tables in the database to pass additional data from notifier to listener(s)\&.
+.PP
+The information passed to the client for a notification event includes the notification channel name, the notifying session\*(Aqs server process
+PID, and the payload string, which is an empty string if it has not been specified\&.
+.PP
+It is up to the database designer to define the channel names that will be used in a given database and what each one means\&. Commonly, the channel name is the same as the name of some table in the database, and the notify event essentially means,
+\(lqI changed this table, take a look at it to see what\*(Aqs new\(rq\&. But no such association is enforced by the
+\fBNOTIFY\fR
+and
+\fBLISTEN\fR
+commands\&. For example, a database designer could use several different channel names to signal different sorts of changes to a single table\&. Alternatively, the payload string could be used to differentiate various cases\&.
+.PP
+When
+\fBNOTIFY\fR
+is used to signal the occurrence of changes to a particular table, a useful programming technique is to put the
+\fBNOTIFY\fR
+in a statement trigger that is triggered by table updates\&. In this way, notification happens automatically when the table is changed, and the application programmer cannot accidentally forget to do it\&.
+.PP
+\fBNOTIFY\fR
+interacts with SQL transactions in some important ways\&. Firstly, if a
+\fBNOTIFY\fR
+is executed inside a transaction, the notify events are not delivered until and unless the transaction is committed\&. This is appropriate, since if the transaction is aborted, all the commands within it have had no effect, including
+\fBNOTIFY\fR\&. But it can be disconcerting if one is expecting the notification events to be delivered immediately\&. Secondly, if a listening session receives a notification signal while it is within a transaction, the notification event will not be delivered to its connected client until just after the transaction is completed (either committed or aborted)\&. Again, the reasoning is that if a notification were delivered within a transaction that was later aborted, one would want the notification to be undone somehow \(em but the server cannot
+\(lqtake back\(rq
+a notification once it has sent it to the client\&. So notification events are only delivered between transactions\&. The upshot of this is that applications using
+\fBNOTIFY\fR
+for real\-time signaling should try to keep their transactions short\&.
+.PP
+If the same channel name is signaled multiple times with identical payload strings within the same transaction, only one instance of the notification event is delivered to listeners\&. On the other hand, notifications with distinct payload strings will always be delivered as distinct notifications\&. Similarly, notifications from different transactions will never get folded into one notification\&. Except for dropping later instances of duplicate notifications,
+\fBNOTIFY\fR
+guarantees that notifications from the same transaction get delivered in the order they were sent\&. It is also guaranteed that messages from different transactions are delivered in the order in which the transactions committed\&.
+.PP
+It is common for a client that executes
+\fBNOTIFY\fR
+to be listening on the same notification channel itself\&. In that case it will get back a notification event, just like all the other listening sessions\&. Depending on the application logic, this could result in useless work, for example, reading a database table to find the same updates that that session just wrote out\&. It is possible to avoid such extra work by noticing whether the notifying session\*(Aqs server process
+PID
+(supplied in the notification event message) is the same as one\*(Aqs own session\*(Aqs
+PID
+(available from
+libpq)\&. When they are the same, the notification event is one\*(Aqs own work bouncing back, and can be ignored\&.
+.SH "PARAMETERS"
+.PP
+\fIchannel\fR
+.RS 4
+Name of the notification channel to be signaled (any identifier)\&.
+.RE
+.PP
+\fIpayload\fR
+.RS 4
+The
+\(lqpayload\(rq
+string to be communicated along with the notification\&. This must be specified as a simple string literal\&. In the default configuration it must be shorter than 8000 bytes\&. (If binary data or large amounts of information need to be communicated, it\*(Aqs best to put it in a database table and send the key of the record\&.)
+.RE
+.SH "NOTES"
+.PP
+There is a queue that holds notifications that have been sent but not yet processed by all listening sessions\&. If this queue becomes full, transactions calling
+\fBNOTIFY\fR
+will fail at commit\&. The queue is quite large (8GB in a standard installation) and should be sufficiently sized for almost every use case\&. However, no cleanup can take place if a session executes
+\fBLISTEN\fR
+and then enters a transaction for a very long time\&. Once the queue is half full you will see warnings in the log file pointing you to the session that is preventing cleanup\&. In this case you should make sure that this session ends its current transaction so that cleanup can proceed\&.
+.PP
+The function
+\fBpg_notification_queue_usage\fR
+returns the fraction of the queue that is currently occupied by pending notifications\&. See
+Section\ \&9.26
+for more information\&.
+.PP
+A transaction that has executed
+\fBNOTIFY\fR
+cannot be prepared for two\-phase commit\&.
+.SS "pg_notify"
+.PP
+To send a notification you can also use the function
+\fBpg_notify\fR(text, text)\&. The function takes the channel name as the first argument and the payload as the second\&. The function is much easier to use than the
+\fBNOTIFY\fR
+command if you need to work with non\-constant channel names and payloads\&.
+.SH "EXAMPLES"
+.PP
+Configure and execute a listen/notify sequence from
+psql:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448\&.
+NOTIFY virtual, \*(AqThis is the payload\*(Aq;
+Asynchronous notification "virtual" with payload "This is the payload" received from server process with PID 8448\&.
+
+LISTEN foo;
+SELECT pg_notify(\*(Aqfo\*(Aq || \*(Aqo\*(Aq, \*(Aqpay\*(Aq || \*(Aqload\*(Aq);
+Asynchronous notification "foo" with payload "payload" received from server process with PID 14728\&.
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBNOTIFY\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBLISTEN\fR(7), \fBUNLISTEN\fR(7)
diff --git a/doc/src/sgml/man7/PREPARE.7 b/doc/src/sgml/man7/PREPARE.7
new file mode 100644
index 0000000..b16a8f0
--- /dev/null
+++ b/doc/src/sgml/man7/PREPARE.7
@@ -0,0 +1,189 @@
+'\" t
+.\" Title: PREPARE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PREPARE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+PREPARE \- prepare a statement for execution
+.SH "SYNOPSIS"
+.sp
+.nf
+PREPARE \fIname\fR [ ( \fIdata_type\fR [, \&.\&.\&.] ) ] AS \fIstatement\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBPREPARE\fR
+creates a prepared statement\&. A prepared statement is a server\-side object that can be used to optimize performance\&. When the
+\fBPREPARE\fR
+statement is executed, the specified statement is parsed, analyzed, and rewritten\&. When an
+\fBEXECUTE\fR
+command is subsequently issued, the prepared statement is planned and executed\&. This division of labor avoids repetitive parse analysis work, while allowing the execution plan to depend on the specific parameter values supplied\&.
+.PP
+Prepared statements can take parameters: values that are substituted into the statement when it is executed\&. When creating the prepared statement, refer to parameters by position, using
+$1,
+$2, etc\&. A corresponding list of parameter data types can optionally be specified\&. When a parameter\*(Aqs data type is not specified or is declared as
+unknown, the type is inferred from the context in which the parameter is first referenced (if possible)\&. When executing the statement, specify the actual values for these parameters in the
+\fBEXECUTE\fR
+statement\&. Refer to
+\fBEXECUTE\fR(7)
+for more information about that\&.
+.PP
+Prepared statements only last for the duration of the current database session\&. When the session ends, the prepared statement is forgotten, so it must be recreated before being used again\&. This also means that a single prepared statement cannot be used by multiple simultaneous database clients; however, each client can create their own prepared statement to use\&. Prepared statements can be manually cleaned up using the
+\fBDEALLOCATE\fR
+command\&.
+.PP
+Prepared statements potentially have the largest performance advantage when a single session is being used to execute a large number of similar statements\&. The performance difference will be particularly significant if the statements are complex to plan or rewrite, e\&.g\&., if the query involves a join of many tables or requires the application of several rules\&. If the statement is relatively simple to plan and rewrite but relatively expensive to execute, the performance advantage of prepared statements will be less noticeable\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+An arbitrary name given to this particular prepared statement\&. It must be unique within a single session and is subsequently used to execute or deallocate a previously prepared statement\&.
+.RE
+.PP
+\fIdata_type\fR
+.RS 4
+The data type of a parameter to the prepared statement\&. If the data type of a particular parameter is unspecified or is specified as
+unknown, it will be inferred from the context in which the parameter is first referenced\&. To refer to the parameters in the prepared statement itself, use
+$1,
+$2, etc\&.
+.RE
+.PP
+\fIstatement\fR
+.RS 4
+Any
+\fBSELECT\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR,
+\fBDELETE\fR,
+\fBMERGE\fR, or
+\fBVALUES\fR
+statement\&.
+.RE
+.SH "NOTES"
+.PP
+A prepared statement can be executed with either a
+generic plan
+or a
+custom plan\&. A generic plan is the same across all executions, while a custom plan is generated for a specific execution using the parameter values given in that call\&. Use of a generic plan avoids planning overhead, but in some situations a custom plan will be much more efficient to execute because the planner can make use of knowledge of the parameter values\&. (Of course, if the prepared statement has no parameters, then this is moot and a generic plan is always used\&.)
+.PP
+By default (that is, when
+plan_cache_mode
+is set to
+auto), the server will automatically choose whether to use a generic or custom plan for a prepared statement that has parameters\&. The current rule for this is that the first five executions are done with custom plans and the average estimated cost of those plans is calculated\&. Then a generic plan is created and its estimated cost is compared to the average custom\-plan cost\&. Subsequent executions use the generic plan if its cost is not so much higher than the average custom\-plan cost as to make repeated replanning seem preferable\&.
+.PP
+This heuristic can be overridden, forcing the server to use either generic or custom plans, by setting
+\fIplan_cache_mode\fR
+to
+force_generic_plan
+or
+force_custom_plan
+respectively\&. This setting is primarily useful if the generic plan\*(Aqs cost estimate is badly off for some reason, allowing it to be chosen even though its actual cost is much more than that of a custom plan\&.
+.PP
+To examine the query plan
+PostgreSQL
+is using for a prepared statement, use
+\fBEXPLAIN\fR, for example
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXPLAIN EXECUTE \fIname\fR(\fIparameter_values\fR);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If a generic plan is in use, it will contain parameter symbols
+$\fIn\fR, while a custom plan will have the supplied parameter values substituted into it\&.
+.PP
+For more information on query planning and the statistics collected by
+PostgreSQL
+for that purpose, see the
+\fBANALYZE\fR(7)
+documentation\&.
+.PP
+Although the main point of a prepared statement is to avoid repeated parse analysis and planning of the statement,
+PostgreSQL
+will force re\-analysis and re\-planning of the statement before using it whenever database objects used in the statement have undergone definitional (DDL) changes or their planner statistics have been updated since the previous use of the prepared statement\&. Also, if the value of
+search_path
+changes from one use to the next, the statement will be re\-parsed using the new
+\fIsearch_path\fR\&. (This latter behavior is new as of
+PostgreSQL
+9\&.3\&.) These rules make use of a prepared statement semantically almost equivalent to re\-submitting the same query text over and over, but with a performance benefit if no object definitions are changed, especially if the best plan remains the same across uses\&. An example of a case where the semantic equivalence is not perfect is that if the statement refers to a table by an unqualified name, and then a new table of the same name is created in a schema appearing earlier in the
+\fIsearch_path\fR, no automatic re\-parse will occur since no object used in the statement changed\&. However, if some other change forces a re\-parse, the new table will be referenced in subsequent uses\&.
+.PP
+You can see all prepared statements available in the session by querying the
+pg_prepared_statements
+system view\&.
+.SH "EXAMPLES"
+.PP
+Create a prepared statement for an
+\fBINSERT\fR
+statement, and then execute it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+PREPARE fooplan (int, text, bool, numeric) AS
+ INSERT INTO foo VALUES($1, $2, $3, $4);
+EXECUTE fooplan(1, \*(AqHunter Valley\*(Aq, \*(Aqt\*(Aq, 200\&.00);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Create a prepared statement for a
+\fBSELECT\fR
+statement, and then execute it:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+PREPARE usrrptplan (int) AS
+ SELECT * FROM users u, logs l WHERE u\&.usrid=$1 AND u\&.usrid=l\&.usrid
+ AND l\&.date = $2;
+EXECUTE usrrptplan(1, current_date);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In this example, the data type of the second parameter is not specified, so it is inferred from the context in which
+$2
+is used\&.
+.SH "COMPATIBILITY"
+.PP
+The SQL standard includes a
+\fBPREPARE\fR
+statement, but it is only for use in embedded SQL\&. This version of the
+\fBPREPARE\fR
+statement also uses a somewhat different syntax\&.
+.SH "SEE ALSO"
+\fBDEALLOCATE\fR(7), \fBEXECUTE\fR(7)
diff --git a/doc/src/sgml/man7/PREPARE_TRANSACTION.7 b/doc/src/sgml/man7/PREPARE_TRANSACTION.7
new file mode 100644
index 0000000..e7d64d2
--- /dev/null
+++ b/doc/src/sgml/man7/PREPARE_TRANSACTION.7
@@ -0,0 +1,147 @@
+'\" t
+.\" Title: PREPARE TRANSACTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "PREPARE TRANSACTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+PREPARE_TRANSACTION \- prepare the current transaction for two\-phase commit
+.SH "SYNOPSIS"
+.sp
+.nf
+PREPARE TRANSACTION \fItransaction_id\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBPREPARE TRANSACTION\fR
+prepares the current transaction for two\-phase commit\&. After this command, the transaction is no longer associated with the current session; instead, its state is fully stored on disk, and there is a very high probability that it can be committed successfully, even if a database crash occurs before the commit is requested\&.
+.PP
+Once prepared, a transaction can later be committed or rolled back with
+\fBCOMMIT PREPARED\fR
+or
+\fBROLLBACK PREPARED\fR, respectively\&. Those commands can be issued from any session, not only the one that executed the original transaction\&.
+.PP
+From the point of view of the issuing session,
+\fBPREPARE TRANSACTION\fR
+is not unlike a
+\fBROLLBACK\fR
+command: after executing it, there is no active current transaction, and the effects of the prepared transaction are no longer visible\&. (The effects will become visible again if the transaction is committed\&.)
+.PP
+If the
+\fBPREPARE TRANSACTION\fR
+command fails for any reason, it becomes a
+\fBROLLBACK\fR: the current transaction is canceled\&.
+.SH "PARAMETERS"
+.PP
+\fItransaction_id\fR
+.RS 4
+An arbitrary identifier that later identifies this transaction for
+\fBCOMMIT PREPARED\fR
+or
+\fBROLLBACK PREPARED\fR\&. The identifier must be written as a string literal, and must be less than 200 bytes long\&. It must not be the same as the identifier used for any currently prepared transaction\&.
+.RE
+.SH "NOTES"
+.PP
+\fBPREPARE TRANSACTION\fR
+is not intended for use in applications or interactive sessions\&. Its purpose is to allow an external transaction manager to perform atomic global transactions across multiple databases or other transactional resources\&. Unless you\*(Aqre writing a transaction manager, you probably shouldn\*(Aqt be using
+\fBPREPARE TRANSACTION\fR\&.
+.PP
+This command must be used inside a transaction block\&. Use
+\fBBEGIN\fR
+to start one\&.
+.PP
+It is not currently allowed to
+\fBPREPARE\fR
+a transaction that has executed any operations involving temporary tables or the session\*(Aqs temporary namespace, created any cursors
+WITH HOLD, or executed
+\fBLISTEN\fR,
+\fBUNLISTEN\fR, or
+\fBNOTIFY\fR\&. Those features are too tightly tied to the current session to be useful in a transaction to be prepared\&.
+.PP
+If the transaction modified any run\-time parameters with
+\fBSET\fR
+(without the
+LOCAL
+option), those effects persist after
+\fBPREPARE TRANSACTION\fR, and will not be affected by any later
+\fBCOMMIT PREPARED\fR
+or
+\fBROLLBACK PREPARED\fR\&. Thus, in this one respect
+\fBPREPARE TRANSACTION\fR
+acts more like
+\fBCOMMIT\fR
+than
+\fBROLLBACK\fR\&.
+.PP
+All currently available prepared transactions are listed in the
+pg_prepared_xacts
+system view\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+It is unwise to leave transactions in the prepared state for a long time\&. This will interfere with the ability of
+\fBVACUUM\fR
+to reclaim storage, and in extreme cases could cause the database to shut down to prevent transaction ID wraparound (see
+Section\ \&25.1.5)\&. Keep in mind also that the transaction continues to hold whatever locks it held\&. The intended usage of the feature is that a prepared transaction will normally be committed or rolled back as soon as an external transaction manager has verified that other databases are also prepared to commit\&.
+.PP
+If you have not set up an external transaction manager to track prepared transactions and ensure they get closed out promptly, it is best to keep the prepared\-transaction feature disabled by setting
+max_prepared_transactions
+to zero\&. This will prevent accidental creation of prepared transactions that might then be forgotten and eventually cause problems\&.
+.sp .5v
+.RE
+.SH "EXAMPLES"
+.PP
+Prepare the current transaction for two\-phase commit, using
+foobar
+as the transaction identifier:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+PREPARE TRANSACTION \*(Aqfoobar\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBPREPARE TRANSACTION\fR
+is a
+PostgreSQL
+extension\&. It is intended for use by external transaction management systems, some of which are covered by standards (such as X/Open XA), but the SQL side of those systems is not standardized\&.
+.SH "SEE ALSO"
+COMMIT PREPARED (\fBCOMMIT_PREPARED\fR(7)), ROLLBACK PREPARED (\fBROLLBACK_PREPARED\fR(7))
diff --git a/doc/src/sgml/man7/REASSIGN_OWNED.7 b/doc/src/sgml/man7/REASSIGN_OWNED.7
new file mode 100644
index 0000000..bad205f
--- /dev/null
+++ b/doc/src/sgml/man7/REASSIGN_OWNED.7
@@ -0,0 +1,91 @@
+'\" t
+.\" Title: REASSIGN OWNED
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "REASSIGN OWNED" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+REASSIGN_OWNED \- change the ownership of database objects owned by a database role
+.SH "SYNOPSIS"
+.sp
+.nf
+REASSIGN OWNED BY { \fIold_role\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, \&.\&.\&.]
+ TO { \fInew_role\fR | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBREASSIGN OWNED\fR
+instructs the system to change the ownership of database objects owned by any of the
+\fIold_roles\fR
+to
+\fInew_role\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIold_role\fR
+.RS 4
+The name of a role\&. The ownership of all the objects within the current database, and of all shared objects (databases, tablespaces), owned by this role will be reassigned to
+\fInew_role\fR\&.
+.RE
+.PP
+\fInew_role\fR
+.RS 4
+The name of the role that will be made the new owner of the affected objects\&.
+.RE
+.SH "NOTES"
+.PP
+\fBREASSIGN OWNED\fR
+is often used to prepare for the removal of one or more roles\&. Because
+\fBREASSIGN OWNED\fR
+does not affect objects within other databases, it is usually necessary to execute this command in each database that contains objects owned by a role that is to be removed\&.
+.PP
+\fBREASSIGN OWNED\fR
+requires membership on both the source role(s) and the target role\&.
+.PP
+The
+\fBDROP OWNED\fR
+command is an alternative that simply drops all the database objects owned by one or more roles\&.
+.PP
+The
+\fBREASSIGN OWNED\fR
+command does not affect any privileges granted to the
+\fIold_roles\fR
+on objects that are not owned by them\&. Likewise, it does not affect default privileges created with
+\fBALTER DEFAULT PRIVILEGES\fR\&. Use
+\fBDROP OWNED\fR
+to revoke such privileges\&.
+.PP
+See
+Section\ \&22.4
+for more discussion\&.
+.SH "COMPATIBILITY"
+.PP
+The
+\fBREASSIGN OWNED\fR
+command is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+DROP OWNED (\fBDROP_OWNED\fR(7)), DROP ROLE (\fBDROP_ROLE\fR(7)), ALTER DATABASE (\fBALTER_DATABASE\fR(7))
diff --git a/doc/src/sgml/man7/REFRESH_MATERIALIZED_VIEW.7 b/doc/src/sgml/man7/REFRESH_MATERIALIZED_VIEW.7
new file mode 100644
index 0000000..c0616c0
--- /dev/null
+++ b/doc/src/sgml/man7/REFRESH_MATERIALIZED_VIEW.7
@@ -0,0 +1,117 @@
+'\" t
+.\" Title: REFRESH MATERIALIZED VIEW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "REFRESH MATERIALIZED VIEW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+REFRESH_MATERIALIZED_VIEW \- replace the contents of a materialized view
+.SH "SYNOPSIS"
+.sp
+.nf
+REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] \fIname\fR
+ [ WITH [ NO ] DATA ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBREFRESH MATERIALIZED VIEW\fR
+completely replaces the contents of a materialized view\&. To execute this command you must be the owner of the materialized view\&. The old contents are discarded\&. If
+WITH DATA
+is specified (or defaults) the backing query is executed to provide the new data, and the materialized view is left in a scannable state\&. If
+WITH NO DATA
+is specified no new data is generated and the materialized view is left in an unscannable state\&.
+.PP
+CONCURRENTLY
+and
+WITH NO DATA
+may not be specified together\&.
+.SH "PARAMETERS"
+.PP
+CONCURRENTLY
+.RS 4
+Refresh the materialized view without locking out concurrent selects on the materialized view\&. Without this option a refresh which affects a lot of rows will tend to use fewer resources and complete more quickly, but could block other connections which are trying to read from the materialized view\&. This option may be faster in cases where a small number of rows are affected\&.
+.sp
+This option is only allowed if there is at least one
+UNIQUE
+index on the materialized view which uses only column names and includes all rows; that is, it must not be an expression index or include a
+WHERE
+clause\&.
+.sp
+This option may not be used when the materialized view is not already populated\&.
+.sp
+Even with this option only one
+REFRESH
+at a time may run against any one materialized view\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of the materialized view to refresh\&.
+.RE
+.SH "NOTES"
+.PP
+If there is an
+ORDER BY
+clause in the materialized view\*(Aqs defining query, the original contents of the materialized view will be ordered that way; but
+\fBREFRESH MATERIALIZED VIEW\fR
+does not guarantee to preserve that ordering\&.
+.SH "EXAMPLES"
+.PP
+This command will replace the contents of the materialized view called
+order_summary
+using the query from the materialized view\*(Aqs definition, and leave it in a scannable state:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REFRESH MATERIALIZED VIEW order_summary;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This command will free storage associated with the materialized view
+annual_statistics_basis
+and leave it in an unscannable state:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REFRESH MATERIALIZED VIEW annual_statistics_basis WITH NO DATA;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBREFRESH MATERIALIZED VIEW\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+CREATE MATERIALIZED VIEW (\fBCREATE_MATERIALIZED_VIEW\fR(7)), ALTER MATERIALIZED VIEW (\fBALTER_MATERIALIZED_VIEW\fR(7)), DROP MATERIALIZED VIEW (\fBDROP_MATERIALIZED_VIEW\fR(7))
diff --git a/doc/src/sgml/man7/REINDEX.7 b/doc/src/sgml/man7/REINDEX.7
new file mode 100644
index 0000000..fba135c
--- /dev/null
+++ b/doc/src/sgml/man7/REINDEX.7
@@ -0,0 +1,510 @@
+'\" t
+.\" Title: REINDEX
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "REINDEX" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+REINDEX \- rebuild indexes
+.SH "SYNOPSIS"
+.sp
+.nf
+REINDEX [ ( \fIoption\fR [, \&.\&.\&.] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] \fIname\fR
+
+where \fIoption\fR can be one of:
+
+ CONCURRENTLY [ \fIboolean\fR ]
+ TABLESPACE \fInew_tablespace\fR
+ VERBOSE [ \fIboolean\fR ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBREINDEX\fR
+rebuilds an index using the data stored in the index\*(Aqs table, replacing the old copy of the index\&. There are several scenarios in which to use
+\fBREINDEX\fR:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+An index has become corrupted, and no longer contains valid data\&. Although in theory this should never happen, in practice indexes can become corrupted due to software bugs or hardware failures\&.
+\fBREINDEX\fR
+provides a recovery method\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+An index has become
+\(lqbloated\(rq, that is it contains many empty or nearly\-empty pages\&. This can occur with B\-tree indexes in
+PostgreSQL
+under certain uncommon access patterns\&.
+\fBREINDEX\fR
+provides a way to reduce the space consumption of the index by writing a new version of the index without the dead pages\&. See
+Section\ \&25.2
+for more information\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+You have altered a storage parameter (such as fillfactor) for an index, and wish to ensure that the change has taken full effect\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+If an index build fails with the
+CONCURRENTLY
+option, this index is left as
+\(lqinvalid\(rq\&. Such indexes are useless but it can be convenient to use
+\fBREINDEX\fR
+to rebuild them\&. Note that only
+\fBREINDEX INDEX\fR
+is able to perform a concurrent build on an invalid index\&.
+.RE
+.SH "PARAMETERS"
+.PP
+INDEX
+.RS 4
+Recreate the specified index\&. This form of
+\fBREINDEX\fR
+cannot be executed inside a transaction block when used with a partitioned index\&.
+.RE
+.PP
+TABLE
+.RS 4
+Recreate all indexes of the specified table\&. If the table has a secondary
+\(lqTOAST\(rq
+table, that is reindexed as well\&. This form of
+\fBREINDEX\fR
+cannot be executed inside a transaction block when used with a partitioned table\&.
+.RE
+.PP
+SCHEMA
+.RS 4
+Recreate all indexes of the specified schema\&. If a table of this schema has a secondary
+\(lqTOAST\(rq
+table, that is reindexed as well\&. Indexes on shared system catalogs are also processed\&. This form of
+\fBREINDEX\fR
+cannot be executed inside a transaction block\&.
+.RE
+.PP
+DATABASE
+.RS 4
+Recreate all indexes within the current database\&. Indexes on shared system catalogs are also processed\&. This form of
+\fBREINDEX\fR
+cannot be executed inside a transaction block\&.
+.RE
+.PP
+SYSTEM
+.RS 4
+Recreate all indexes on system catalogs within the current database\&. Indexes on shared system catalogs are included\&. Indexes on user tables are not processed\&. This form of
+\fBREINDEX\fR
+cannot be executed inside a transaction block\&.
+.RE
+.PP
+\fIname\fR
+.RS 4
+The name of the specific index, table, or database to be reindexed\&. Index and table names can be schema\-qualified\&. Presently,
+\fBREINDEX DATABASE\fR
+and
+\fBREINDEX SYSTEM\fR
+can only reindex the current database, so their parameter must match the current database\*(Aqs name\&.
+.RE
+.PP
+CONCURRENTLY
+.RS 4
+When this option is used,
+PostgreSQL
+will rebuild the index without taking any locks that prevent concurrent inserts, updates, or deletes on the table; whereas a standard index rebuild locks out writes (but not reads) on the table until it\*(Aqs done\&. There are several caveats to be aware of when using this option \(em see
+Rebuilding Indexes Concurrently
+below\&.
+.sp
+For temporary tables,
+\fBREINDEX\fR
+is always non\-concurrent, as no other session can access them, and non\-concurrent reindex is cheaper\&.
+.RE
+.PP
+TABLESPACE
+.RS 4
+Specifies that indexes will be rebuilt on a new tablespace\&.
+.RE
+.PP
+VERBOSE
+.RS 4
+Prints a progress report as each index is reindexed\&.
+.RE
+.PP
+\fIboolean\fR
+.RS 4
+Specifies whether the selected option should be turned on or off\&. You can write
+TRUE,
+ON, or
+1
+to enable the option, and
+FALSE,
+OFF, or
+0
+to disable it\&. The
+\fIboolean\fR
+value can also be omitted, in which case
+TRUE
+is assumed\&.
+.RE
+.PP
+\fInew_tablespace\fR
+.RS 4
+The tablespace where indexes will be rebuilt\&.
+.RE
+.SH "NOTES"
+.PP
+If you suspect corruption of an index on a user table, you can simply rebuild that index, or all indexes on the table, using
+\fBREINDEX INDEX\fR
+or
+\fBREINDEX TABLE\fR\&.
+.PP
+Things are more difficult if you need to recover from corruption of an index on a system table\&. In this case it\*(Aqs important for the system to not have used any of the suspect indexes itself\&. (Indeed, in this sort of scenario you might find that server processes are crashing immediately at start\-up, due to reliance on the corrupted indexes\&.) To recover safely, the server must be started with the
+\fB\-P\fR
+option, which prevents it from using indexes for system catalog lookups\&.
+.PP
+One way to do this is to shut down the server and start a single\-user
+PostgreSQL
+server with the
+\fB\-P\fR
+option included on its command line\&. Then,
+\fBREINDEX DATABASE\fR,
+\fBREINDEX SYSTEM\fR,
+\fBREINDEX TABLE\fR, or
+\fBREINDEX INDEX\fR
+can be issued, depending on how much you want to reconstruct\&. If in doubt, use
+\fBREINDEX SYSTEM\fR
+to select reconstruction of all system indexes in the database\&. Then quit the single\-user server session and restart the regular server\&. See the
+\fBpostgres\fR(1)
+reference page for more information about how to interact with the single\-user server interface\&.
+.PP
+Alternatively, a regular server session can be started with
+\fB\-P\fR
+included in its command line options\&. The method for doing this varies across clients, but in all
+libpq\-based clients, it is possible to set the
+\fBPGOPTIONS\fR
+environment variable to
+\-P
+before starting the client\&. Note that while this method does not require locking out other clients, it might still be wise to prevent other users from connecting to the damaged database until repairs have been completed\&.
+.PP
+\fBREINDEX\fR
+is similar to a drop and recreate of the index in that the index contents are rebuilt from scratch\&. However, the locking considerations are rather different\&.
+\fBREINDEX\fR
+locks out writes but not reads of the index\*(Aqs parent table\&. It also takes an
+ACCESS EXCLUSIVE
+lock on the specific index being processed, which will block reads that attempt to use that index\&. In particular, the query planner tries to take an
+ACCESS SHARE
+lock on every index of the table, regardless of the query, and so
+\fBREINDEX\fR
+blocks virtually any queries except for some prepared queries whose plan has been cached and which don\*(Aqt use this very index\&. In contrast,
+\fBDROP INDEX\fR
+momentarily takes an
+ACCESS EXCLUSIVE
+lock on the parent table, blocking both writes and reads\&. The subsequent
+\fBCREATE INDEX\fR
+locks out writes but not reads; since the index is not there, no read will attempt to use it, meaning that there will be no blocking but reads might be forced into expensive sequential scans\&.
+.PP
+Reindexing a single index or table requires being the owner of that index or table\&. Reindexing a schema or database requires being the owner of that schema or database\&. Note specifically that it\*(Aqs thus possible for non\-superusers to rebuild indexes of tables owned by other users\&. However, as a special exception, when
+\fBREINDEX DATABASE\fR,
+\fBREINDEX SCHEMA\fR
+or
+\fBREINDEX SYSTEM\fR
+is issued by a non\-superuser, indexes on shared catalogs will be skipped unless the user owns the catalog (which typically won\*(Aqt be the case)\&. Of course, superusers can always reindex anything\&.
+.PP
+Reindexing partitioned indexes or partitioned tables is supported with
+\fBREINDEX INDEX\fR
+or
+\fBREINDEX TABLE\fR, respectively\&. Each partition of the specified partitioned relation is reindexed in a separate transaction\&. Those commands cannot be used inside a transaction block when working on a partitioned table or index\&.
+.PP
+When using the
+TABLESPACE
+clause with
+\fBREINDEX\fR
+on a partitioned index or table, only the tablespace references of the leaf partitions are updated\&. As partitioned indexes are not updated, it is recommended to separately use
+\fBALTER TABLE ONLY\fR
+on them so as any new partitions attached inherit the new tablespace\&. On failure, it may not have moved all the indexes to the new tablespace\&. Re\-running the command will rebuild all the leaf partitions and move previously\-unprocessed indexes to the new tablespace\&.
+.PP
+If
+SCHEMA,
+DATABASE
+or
+SYSTEM
+is used with
+TABLESPACE, system relations are skipped and a single
+WARNING
+will be generated\&. Indexes on TOAST tables are rebuilt, but not moved to the new tablespace\&.
+.SS "Rebuilding Indexes Concurrently"
+.PP
+Rebuilding an index can interfere with regular operation of a database\&. Normally
+PostgreSQL
+locks the table whose index is rebuilt against writes and performs the entire index build with a single scan of the table\&. Other transactions can still read the table, but if they try to insert, update, or delete rows in the table they will block until the index rebuild is finished\&. This could have a severe effect if the system is a live production database\&. Very large tables can take many hours to be indexed, and even for smaller tables, an index rebuild can lock out writers for periods that are unacceptably long for a production system\&.
+.PP
+PostgreSQL
+supports rebuilding indexes with minimum locking of writes\&. This method is invoked by specifying the
+CONCURRENTLY
+option of
+\fBREINDEX\fR\&. When this option is used,
+PostgreSQL
+must perform two scans of the table for each index that needs to be rebuilt and wait for termination of all existing transactions that could potentially use the index\&. This method requires more total work than a standard index rebuild and takes significantly longer to complete as it needs to wait for unfinished transactions that might modify the index\&. However, since it allows normal operations to continue while the index is being rebuilt, this method is useful for rebuilding indexes in a production environment\&. Of course, the extra CPU, memory and I/O load imposed by the index rebuild may slow down other operations\&.
+.PP
+The following steps occur in a concurrent reindex\&. Each step is run in a separate transaction\&. If there are multiple indexes to be rebuilt, then each step loops through all the indexes before moving to the next step\&.
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+A new transient index definition is added to the catalog
+pg_index\&. This definition will be used to replace the old index\&. A
+SHARE UPDATE EXCLUSIVE
+lock at session level is taken on the indexes being reindexed as well as their associated tables to prevent any schema modification while processing\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+A first pass to build the index is done for each new index\&. Once the index is built, its flag
+pg_index\&.indisready
+is switched to
+\(lqtrue\(rq
+to make it ready for inserts, making it visible to other sessions once the transaction that performed the build is finished\&. This step is done in a separate transaction for each index\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+Then a second pass is performed to add tuples that were added while the first pass was running\&. This step is also done in a separate transaction for each index\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 4.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 4." 4.2
+.\}
+All the constraints that refer to the index are changed to refer to the new index definition, and the names of the indexes are changed\&. At this point,
+pg_index\&.indisvalid
+is switched to
+\(lqtrue\(rq
+for the new index and to
+\(lqfalse\(rq
+for the old, and a cache invalidation is done causing all sessions that referenced the old index to be invalidated\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 5.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 5." 4.2
+.\}
+The old indexes have
+pg_index\&.indisready
+switched to
+\(lqfalse\(rq
+to prevent any new tuple insertions, after waiting for running queries that might reference the old index to complete\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 6.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 6." 4.2
+.\}
+The old indexes are dropped\&. The
+SHARE UPDATE EXCLUSIVE
+session locks for the indexes and the table are released\&.
+.RE
+.PP
+If a problem arises while rebuilding the indexes, such as a uniqueness violation in a unique index, the
+\fBREINDEX\fR
+command will fail but leave behind an
+\(lqinvalid\(rq
+new index in addition to the pre\-existing one\&. This index will be ignored for querying purposes because it might be incomplete; however it will still consume update overhead\&. The
+psql
+\fB\ed\fR
+command will report such an index as
+INVALID:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+postgres=# \ed tab
+ Table "public\&.tab"
+ Column | Type | Modifiers
+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-
+ col | integer |
+Indexes:
+ "idx" btree (col)
+ "idx_ccnew" btree (col) INVALID
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If the index marked
+INVALID
+is suffixed
+ccnew, then it corresponds to the transient index created during the concurrent operation, and the recommended recovery method is to drop it using
+DROP INDEX, then attempt
+\fBREINDEX CONCURRENTLY\fR
+again\&. If the invalid index is instead suffixed
+ccold, it corresponds to the original index which could not be dropped; the recommended recovery method is to just drop said index, since the rebuild proper has been successful\&.
+.PP
+Regular index builds permit other regular index builds on the same table to occur simultaneously, but only one concurrent index build can occur on a table at a time\&. In both cases, no other types of schema modification on the table are allowed meanwhile\&. Another difference is that a regular
+\fBREINDEX TABLE\fR
+or
+\fBREINDEX INDEX\fR
+command can be performed within a transaction block, but
+\fBREINDEX CONCURRENTLY\fR
+cannot\&.
+.PP
+Like any long\-running transaction,
+\fBREINDEX\fR
+on a table can affect which tuples can be removed by concurrent
+\fBVACUUM\fR
+on any other table\&.
+.PP
+\fBREINDEX SYSTEM\fR
+does not support
+\fBCONCURRENTLY\fR
+since system catalogs cannot be reindexed concurrently\&.
+.PP
+Furthermore, indexes for exclusion constraints cannot be reindexed concurrently\&. If such an index is named directly in this command, an error is raised\&. If a table or database with exclusion constraint indexes is reindexed concurrently, those indexes will be skipped\&. (It is possible to reindex such indexes without the
+\fBCONCURRENTLY\fR
+option\&.)
+.PP
+Each backend running
+\fBREINDEX\fR
+will report its progress in the
+pg_stat_progress_create_index
+view\&. See
+Section\ \&28.4.2
+for details\&.
+.SH "EXAMPLES"
+.PP
+Rebuild a single index:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REINDEX INDEX my_index;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Rebuild all the indexes on the table
+my_table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REINDEX TABLE my_table;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Rebuild all indexes in a particular database, without trusting the system indexes to be valid already:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+$ \fBexport PGOPTIONS="\-P"\fR
+$ \fBpsql broken_db\fR
+\&.\&.\&.
+broken_db=> REINDEX DATABASE broken_db;
+broken_db=> \eq
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Rebuild indexes for a table, without blocking read and write operations on involved relations while reindexing is in progress:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REINDEX TABLE CONCURRENTLY my_broken_table;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBREINDEX\fR
+command in the SQL standard\&.
+.SH "SEE ALSO"
+CREATE INDEX (\fBCREATE_INDEX\fR(7)), DROP INDEX (\fBDROP_INDEX\fR(7)), \fBreindexdb\fR(1), Section\ \&28.4.2
diff --git a/doc/src/sgml/man7/RELEASE_SAVEPOINT.7 b/doc/src/sgml/man7/RELEASE_SAVEPOINT.7
new file mode 100644
index 0000000..88ae86f
--- /dev/null
+++ b/doc/src/sgml/man7/RELEASE_SAVEPOINT.7
@@ -0,0 +1,90 @@
+'\" t
+.\" Title: RELEASE SAVEPOINT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "RELEASE SAVEPOINT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+RELEASE_SAVEPOINT \- destroy a previously defined savepoint
+.SH "SYNOPSIS"
+.sp
+.nf
+RELEASE [ SAVEPOINT ] \fIsavepoint_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBRELEASE SAVEPOINT\fR
+destroys a savepoint previously defined in the current transaction\&.
+.PP
+Destroying a savepoint makes it unavailable as a rollback point, but it has no other user visible behavior\&. It does not undo the effects of commands executed after the savepoint was established\&. (To do that, see
+ROLLBACK TO SAVEPOINT (\fBROLLBACK_TO_SAVEPOINT\fR(7))\&.) Destroying a savepoint when it is no longer needed allows the system to reclaim some resources earlier than transaction end\&.
+.PP
+\fBRELEASE SAVEPOINT\fR
+also destroys all savepoints that were established after the named savepoint was established\&.
+.SH "PARAMETERS"
+.PP
+\fIsavepoint_name\fR
+.RS 4
+The name of the savepoint to destroy\&.
+.RE
+.SH "NOTES"
+.PP
+Specifying a savepoint name that was not previously defined is an error\&.
+.PP
+It is not possible to release a savepoint when the transaction is in an aborted state\&.
+.PP
+If multiple savepoints have the same name, only the most recently defined unreleased one is released\&. Repeated commands will release progressively older savepoints\&.
+.SH "EXAMPLES"
+.PP
+To establish and later destroy a savepoint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+ INSERT INTO table1 VALUES (3);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (4);
+ RELEASE SAVEPOINT my_savepoint;
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The above transaction will insert both 3 and 4\&.
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the
+SQL
+standard\&. The standard specifies that the key word
+SAVEPOINT
+is mandatory, but
+PostgreSQL
+allows it to be omitted\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), \fBROLLBACK\fR(7), ROLLBACK TO SAVEPOINT (\fBROLLBACK_TO_SAVEPOINT\fR(7)), \fBSAVEPOINT\fR(7)
diff --git a/doc/src/sgml/man7/RESET.7 b/doc/src/sgml/man7/RESET.7
new file mode 100644
index 0000000..e085c97
--- /dev/null
+++ b/doc/src/sgml/man7/RESET.7
@@ -0,0 +1,107 @@
+'\" t
+.\" Title: RESET
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "RESET" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+RESET \- restore the value of a run\-time parameter to the default value
+.SH "SYNOPSIS"
+.sp
+.nf
+RESET \fIconfiguration_parameter\fR
+RESET ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBRESET\fR
+restores run\-time parameters to their default values\&.
+\fBRESET\fR
+is an alternative spelling for
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SET \fIconfiguration_parameter\fR TO DEFAULT
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Refer to
+\fBSET\fR(7)
+for details\&.
+.PP
+The default value is defined as the value that the parameter would have had, if no
+\fBSET\fR
+had ever been issued for it in the current session\&. The actual source of this value might be a compiled\-in default, the configuration file, command\-line options, or per\-database or per\-user default settings\&. This is subtly different from defining it as
+\(lqthe value that the parameter had at session start\(rq, because if the value came from the configuration file, it will be reset to whatever is specified by the configuration file now\&. See
+Chapter\ \&20
+for details\&.
+.PP
+The transactional behavior of
+\fBRESET\fR
+is the same as
+\fBSET\fR: its effects will be undone by transaction rollback\&.
+.SH "PARAMETERS"
+.PP
+\fIconfiguration_parameter\fR
+.RS 4
+Name of a settable run\-time parameter\&. Available parameters are documented in
+Chapter\ \&20
+and on the
+\fBSET\fR(7)
+reference page\&.
+.RE
+.PP
+ALL
+.RS 4
+Resets all settable run\-time parameters to default values\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Set the
+\fItimezone\fR
+configuration variable to its default value:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+RESET timezone;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBRESET\fR
+is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+\fBSET\fR(7), \fBSHOW\fR(7)
diff --git a/doc/src/sgml/man7/REVOKE.7 b/doc/src/sgml/man7/REVOKE.7
new file mode 100644
index 0000000..1f3d508
--- /dev/null
+++ b/doc/src/sgml/man7/REVOKE.7
@@ -0,0 +1,314 @@
+'\" t
+.\" Title: REVOKE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "REVOKE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+REVOKE \- remove access privileges
+.SH "SYNOPSIS"
+.sp
+.nf
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON { [ TABLE ] \fItable_name\fR [, \&.\&.\&.]
+ | ALL TABLES IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] }
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | REFERENCES } ( \fIcolumn_name\fR [, \&.\&.\&.] )
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] ( \fIcolumn_name\fR [, \&.\&.\&.] ) }
+ ON [ TABLE ] \fItable_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { USAGE | SELECT | UPDATE }
+ [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON { SEQUENCE \fIsequence_name\fR [, \&.\&.\&.]
+ | ALL SEQUENCES IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] }
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { CREATE | CONNECT | TEMPORARY | TEMP } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON DATABASE \fIdatabase_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON DOMAIN \fIdomain_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN DATA WRAPPER \fIfdw_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN SERVER \fIserver_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { { FUNCTION | PROCEDURE | ROUTINE } \fIfunction_name\fR [ ( [ [ \fIargmode\fR ] [ \fIarg_name\fR ] \fIarg_type\fR [, \&.\&.\&.] ] ) ] [, \&.\&.\&.]
+ | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA \fIschema_name\fR [, \&.\&.\&.] }
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON LANGUAGE \fIlang_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | UPDATE } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON LARGE OBJECT \fIloid\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SET | ALTER SYSTEM } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON PARAMETER \fIconfiguration_parameter\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { CREATE | USAGE } [, \&.\&.\&.] | ALL [ PRIVILEGES ] }
+ ON SCHEMA \fIschema_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { CREATE | ALL [ PRIVILEGES ] }
+ ON TABLESPACE \fItablespace_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPE \fItype_name\fR [, \&.\&.\&.]
+ FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ ADMIN OPTION FOR ]
+ \fIrole_name\fR [, \&.\&.\&.] FROM \fIrole_specification\fR [, \&.\&.\&.]
+ [ GRANTED BY \fIrole_specification\fR ]
+ [ CASCADE | RESTRICT ]
+
+where \fIrole_specification\fR can be:
+
+ [ GROUP ] \fIrole_name\fR
+ | PUBLIC
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBREVOKE\fR
+command revokes previously granted privileges from one or more roles\&. The key word
+PUBLIC
+refers to the implicitly defined group of all roles\&.
+.PP
+See the description of the
+\fBGRANT\fR
+command for the meaning of the privilege types\&.
+.PP
+Note that any particular role will have the sum of privileges granted directly to it, privileges granted to any role it is presently a member of, and privileges granted to
+PUBLIC\&. Thus, for example, revoking
+SELECT
+privilege from
+PUBLIC
+does not necessarily mean that all roles have lost
+SELECT
+privilege on the object: those who have it granted directly or via another role will still have it\&. Similarly, revoking
+SELECT
+from a user might not prevent that user from using
+SELECT
+if
+PUBLIC
+or another membership role still has
+SELECT
+rights\&.
+.PP
+If
+GRANT OPTION FOR
+is specified, only the grant option for the privilege is revoked, not the privilege itself\&. Otherwise, both the privilege and the grant option are revoked\&.
+.PP
+If a user holds a privilege with grant option and has granted it to other users then the privileges held by those other users are called dependent privileges\&. If the privilege or the grant option held by the first user is being revoked and dependent privileges exist, those dependent privileges are also revoked if
+CASCADE
+is specified; if it is not, the revoke action will fail\&. This recursive revocation only affects privileges that were granted through a chain of users that is traceable to the user that is the subject of this
+REVOKE
+command\&. Thus, the affected users might effectively keep the privilege if it was also granted through other users\&.
+.PP
+When revoking privileges on a table, the corresponding column privileges (if any) are automatically revoked on each column of the table, as well\&. On the other hand, if a role has been granted privileges on a table, then revoking the same privileges from individual columns will have no effect\&.
+.PP
+When revoking membership in a role,
+GRANT OPTION
+is instead called
+ADMIN OPTION, but the behavior is similar\&. This form of the command also allows a
+GRANTED BY
+option, but that option is currently ignored (except for checking the existence of the named role)\&. Note also that this form of the command does not allow the noise word
+GROUP
+in
+\fIrole_specification\fR\&.
+.SH "NOTES"
+.PP
+A user can only revoke privileges that were granted directly by that user\&. If, for example, user A has granted a privilege with grant option to user B, and user B has in turn granted it to user C, then user A cannot revoke the privilege directly from C\&. Instead, user A could revoke the grant option from user B and use the
+CASCADE
+option so that the privilege is in turn revoked from user C\&. For another example, if both A and B have granted the same privilege to C, A can revoke their own grant but not B\*(Aqs grant, so C will still effectively have the privilege\&.
+.PP
+When a non\-owner of an object attempts to
+\fBREVOKE\fR
+privileges on the object, the command will fail outright if the user has no privileges whatsoever on the object\&. As long as some privilege is available, the command will proceed, but it will revoke only those privileges for which the user has grant options\&. The
+\fBREVOKE ALL PRIVILEGES\fR
+forms will issue a warning message if no grant options are held, while the other forms will issue a warning if grant options for any of the privileges specifically named in the command are not held\&. (In principle these statements apply to the object owner as well, but since the owner is always treated as holding all grant options, the cases can never occur\&.)
+.PP
+If a superuser chooses to issue a
+\fBGRANT\fR
+or
+\fBREVOKE\fR
+command, the command is performed as though it were issued by the owner of the affected object\&. Since all privileges ultimately come from the object owner (possibly indirectly via chains of grant options), it is possible for a superuser to revoke all privileges, but this might require use of
+CASCADE
+as stated above\&.
+.PP
+\fBREVOKE\fR
+can also be done by a role that is not the owner of the affected object, but is a member of the role that owns the object, or is a member of a role that holds privileges
+WITH GRANT OPTION
+on the object\&. In this case the command is performed as though it were issued by the containing role that actually owns the object or holds the privileges
+WITH GRANT OPTION\&. For example, if table
+t1
+is owned by role
+g1, of which role
+u1
+is a member, then
+u1
+can revoke privileges on
+t1
+that are recorded as being granted by
+g1\&. This would include grants made by
+u1
+as well as by other members of role
+g1\&.
+.PP
+If the role executing
+\fBREVOKE\fR
+holds privileges indirectly via more than one role membership path, it is unspecified which containing role will be used to perform the command\&. In such cases it is best practice to use
+\fBSET ROLE\fR
+to become the specific role you want to do the
+\fBREVOKE\fR
+as\&. Failure to do so might lead to revoking privileges other than the ones you intended, or not revoking anything at all\&.
+.PP
+See
+Section\ \&5.7
+for more information about specific privilege types, as well as how to inspect objects\*(Aq privileges\&.
+.SH "EXAMPLES"
+.PP
+Revoke insert privilege for the public on table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REVOKE INSERT ON films FROM PUBLIC;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Revoke all privileges from user
+manuel
+on view
+kinds:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REVOKE ALL PRIVILEGES ON kinds FROM manuel;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that this actually means
+\(lqrevoke all privileges that I granted\(rq\&.
+.PP
+Revoke membership in role
+admins
+from user
+joe:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+REVOKE admins FROM joe;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The compatibility notes of the
+\fBGRANT\fR
+command apply analogously to
+\fBREVOKE\fR\&. The keyword
+RESTRICT
+or
+CASCADE
+is required according to the standard, but
+PostgreSQL
+assumes
+RESTRICT
+by default\&.
+.SH "SEE ALSO"
+\fBGRANT\fR(7), ALTER DEFAULT PRIVILEGES (\fBALTER_DEFAULT_PRIVILEGES\fR(7))
diff --git a/doc/src/sgml/man7/ROLLBACK.7 b/doc/src/sgml/man7/ROLLBACK.7
new file mode 100644
index 0000000..f8c77a7
--- /dev/null
+++ b/doc/src/sgml/man7/ROLLBACK.7
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: ROLLBACK
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ROLLBACK" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ROLLBACK \- abort the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBROLLBACK\fR
+rolls back the current transaction and causes all the updates made by the transaction to be discarded\&.
+.SH "PARAMETERS"
+.PP
+WORK
+.br
+TRANSACTION
+.RS 4
+Optional key words\&. They have no effect\&.
+.RE
+.PP
+AND CHAIN
+.RS 4
+If
+AND CHAIN
+is specified, a new transaction is immediately started with the same transaction characteristics (see
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))) as the just finished one\&. Otherwise, no new transaction is started\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBCOMMIT\fR
+to successfully terminate a transaction\&.
+.PP
+Issuing
+\fBROLLBACK\fR
+outside of a transaction block emits a warning and otherwise has no effect\&.
+\fBROLLBACK AND CHAIN\fR
+outside of a transaction block is an error\&.
+.SH "EXAMPLES"
+.PP
+To abort all changes:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ROLLBACK;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The command
+\fBROLLBACK\fR
+conforms to the SQL standard\&. The form
+ROLLBACK TRANSACTION
+is a PostgreSQL extension\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), ROLLBACK TO SAVEPOINT (\fBROLLBACK_TO_SAVEPOINT\fR(7))
diff --git a/doc/src/sgml/man7/ROLLBACK_PREPARED.7 b/doc/src/sgml/man7/ROLLBACK_PREPARED.7
new file mode 100644
index 0000000..d5db6b3
--- /dev/null
+++ b/doc/src/sgml/man7/ROLLBACK_PREPARED.7
@@ -0,0 +1,77 @@
+'\" t
+.\" Title: ROLLBACK PREPARED
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ROLLBACK PREPARED" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ROLLBACK_PREPARED \- cancel a transaction that was earlier prepared for two\-phase commit
+.SH "SYNOPSIS"
+.sp
+.nf
+ROLLBACK PREPARED \fItransaction_id\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBROLLBACK PREPARED\fR
+rolls back a transaction that is in prepared state\&.
+.SH "PARAMETERS"
+.PP
+\fItransaction_id\fR
+.RS 4
+The transaction identifier of the transaction that is to be rolled back\&.
+.RE
+.SH "NOTES"
+.PP
+To roll back a prepared transaction, you must be either the same user that executed the transaction originally, or a superuser\&. But you do not have to be in the same session that executed the transaction\&.
+.PP
+This command cannot be executed inside a transaction block\&. The prepared transaction is rolled back immediately\&.
+.PP
+All currently available prepared transactions are listed in the
+pg_prepared_xacts
+system view\&.
+.SH "EXAMPLES"
+.PP
+Roll back the transaction identified by the transaction identifier
+foobar:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ROLLBACK PREPARED \*(Aqfoobar\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+\fBROLLBACK PREPARED\fR
+is a
+PostgreSQL
+extension\&. It is intended for use by external transaction management systems, some of which are covered by standards (such as X/Open XA), but the SQL side of those systems is not standardized\&.
+.SH "SEE ALSO"
+PREPARE TRANSACTION (\fBPREPARE_TRANSACTION\fR(7)), COMMIT PREPARED (\fBCOMMIT_PREPARED\fR(7))
diff --git a/doc/src/sgml/man7/ROLLBACK_TO_SAVEPOINT.7 b/doc/src/sgml/man7/ROLLBACK_TO_SAVEPOINT.7
new file mode 100644
index 0000000..787e119
--- /dev/null
+++ b/doc/src/sgml/man7/ROLLBACK_TO_SAVEPOINT.7
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: ROLLBACK TO SAVEPOINT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "ROLLBACK TO SAVEPOINT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+ROLLBACK_TO_SAVEPOINT \- roll back to a savepoint
+.SH "SYNOPSIS"
+.sp
+.nf
+ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] \fIsavepoint_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+Roll back all commands that were executed after the savepoint was established\&. The savepoint remains valid and can be rolled back to again later, if needed\&.
+.PP
+\fBROLLBACK TO SAVEPOINT\fR
+implicitly destroys all savepoints that were established after the named savepoint\&.
+.SH "PARAMETERS"
+.PP
+\fIsavepoint_name\fR
+.RS 4
+The savepoint to roll back to\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBRELEASE SAVEPOINT\fR
+to destroy a savepoint without discarding the effects of commands executed after it was established\&.
+.PP
+Specifying a savepoint name that has not been established is an error\&.
+.PP
+Cursors have somewhat non\-transactional behavior with respect to savepoints\&. Any cursor that is opened inside a savepoint will be closed when the savepoint is rolled back\&. If a previously opened cursor is affected by a
+\fBFETCH\fR
+or
+\fBMOVE\fR
+command inside a savepoint that is later rolled back, the cursor remains at the position that
+\fBFETCH\fR
+left it pointing to (that is, the cursor motion caused by
+\fBFETCH\fR
+is not rolled back)\&. Closing a cursor is not undone by rolling back, either\&. However, other side\-effects caused by the cursor\*(Aqs query (such as side\-effects of volatile functions called by the query)
+\fIare\fR
+rolled back if they occur during a savepoint that is later rolled back\&. A cursor whose execution causes a transaction to abort is put in a cannot\-execute state, so while the transaction can be restored using
+\fBROLLBACK TO SAVEPOINT\fR, the cursor can no longer be used\&.
+.SH "EXAMPLES"
+.PP
+To undo the effects of the commands executed after
+my_savepoint
+was established:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ROLLBACK TO SAVEPOINT my_savepoint;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Cursor positions are not affected by savepoint rollback:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+
+DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2;
+
+SAVEPOINT foo;
+
+FETCH 1 FROM foo;
+ ?column?
+\-\-\-\-\-\-\-\-\-\-
+ 1
+
+ROLLBACK TO SAVEPOINT foo;
+
+FETCH 1 FROM foo;
+ ?column?
+\-\-\-\-\-\-\-\-\-\-
+ 2
+
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+SQL
+standard specifies that the key word
+SAVEPOINT
+is mandatory, but
+PostgreSQL
+and
+Oracle
+allow it to be omitted\&. SQL allows only
+WORK, not
+TRANSACTION, as a noise word after
+ROLLBACK\&. Also, SQL has an optional clause
+AND [ NO ] CHAIN
+which is not currently supported by
+PostgreSQL\&. Otherwise, this command conforms to the SQL standard\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), RELEASE SAVEPOINT (\fBRELEASE_SAVEPOINT\fR(7)), \fBROLLBACK\fR(7), \fBSAVEPOINT\fR(7)
diff --git a/doc/src/sgml/man7/SAVEPOINT.7 b/doc/src/sgml/man7/SAVEPOINT.7
new file mode 100644
index 0000000..f81310e
--- /dev/null
+++ b/doc/src/sgml/man7/SAVEPOINT.7
@@ -0,0 +1,141 @@
+'\" t
+.\" Title: SAVEPOINT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SAVEPOINT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SAVEPOINT \- define a new savepoint within the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+SAVEPOINT \fIsavepoint_name\fR
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSAVEPOINT\fR
+establishes a new savepoint within the current transaction\&.
+.PP
+A savepoint is a special mark inside a transaction that allows all commands that are executed after it was established to be rolled back, restoring the transaction state to what it was at the time of the savepoint\&.
+.SH "PARAMETERS"
+.PP
+\fIsavepoint_name\fR
+.RS 4
+The name to give to the new savepoint\&. If savepoints with the same name already exist, they will be inaccessible until newer identically\-named savepoints are released\&.
+.RE
+.SH "NOTES"
+.PP
+Use
+\fBROLLBACK TO\fR
+to rollback to a savepoint\&. Use
+\fBRELEASE SAVEPOINT\fR
+to destroy a savepoint, keeping the effects of commands executed after it was established\&.
+.PP
+Savepoints can only be established when inside a transaction block\&. There can be multiple savepoints defined within a transaction\&.
+.SH "EXAMPLES"
+.PP
+To establish a savepoint and later undo the effects of all commands executed after it was established:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+ INSERT INTO table1 VALUES (1);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (2);
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (3);
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The above transaction will insert the values 1 and 3, but not 2\&.
+.PP
+To establish and later destroy a savepoint:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+ INSERT INTO table1 VALUES (3);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (4);
+ RELEASE SAVEPOINT my_savepoint;
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The above transaction will insert both 3 and 4\&.
+.PP
+To use a single savepoint name:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+ INSERT INTO table1 VALUES (1);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (2);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (3);
+
+ \-\- rollback to the second savepoint
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ SELECT * FROM table1; \-\- shows rows 1 and 2
+
+ \-\- release the second savepoint
+ RELEASE SAVEPOINT my_savepoint;
+
+ \-\- rollback to the first savepoint
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ SELECT * FROM table1; \-\- shows only row 1
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The above transaction shows row 3 being rolled back first, then row 2\&.
+.SH "COMPATIBILITY"
+.PP
+SQL requires a savepoint to be destroyed automatically when another savepoint with the same name is established\&. In
+PostgreSQL, the old savepoint is kept, though only the more recent one will be used when rolling back or releasing\&. (Releasing the newer savepoint with
+\fBRELEASE SAVEPOINT\fR
+will cause the older one to again become accessible to
+\fBROLLBACK TO SAVEPOINT\fR
+and
+\fBRELEASE SAVEPOINT\fR\&.) Otherwise,
+\fBSAVEPOINT\fR
+is fully SQL conforming\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), RELEASE SAVEPOINT (\fBRELEASE_SAVEPOINT\fR(7)), \fBROLLBACK\fR(7), ROLLBACK TO SAVEPOINT (\fBROLLBACK_TO_SAVEPOINT\fR(7))
diff --git a/doc/src/sgml/man7/SECURITY_LABEL.7 b/doc/src/sgml/man7/SECURITY_LABEL.7
new file mode 100644
index 0000000..7906f20
--- /dev/null
+++ b/doc/src/sgml/man7/SECURITY_LABEL.7
@@ -0,0 +1,198 @@
+'\" t
+.\" Title: SECURITY LABEL
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SECURITY LABEL" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SECURITY_LABEL \- define or change a security label applied to an object
+.SH "SYNOPSIS"
+.sp
+.nf
+SECURITY LABEL [ FOR \fIprovider\fR ] ON
+{
+ TABLE \fIobject_name\fR |
+ COLUMN \fItable_name\fR\&.\fIcolumn_name\fR |
+ AGGREGATE \fIaggregate_name\fR ( \fIaggregate_signature\fR ) |
+ DATABASE \fIobject_name\fR |
+ DOMAIN \fIobject_name\fR |
+ EVENT TRIGGER \fIobject_name\fR |
+ FOREIGN TABLE \fIobject_name\fR
+ FUNCTION \fIfunction_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ LARGE OBJECT \fIlarge_object_oid\fR |
+ MATERIALIZED VIEW \fIobject_name\fR |
+ [ PROCEDURAL ] LANGUAGE \fIobject_name\fR |
+ PROCEDURE \fIprocedure_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ PUBLICATION \fIobject_name\fR |
+ ROLE \fIobject_name\fR |
+ ROUTINE \fIroutine_name\fR [ ( [ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [, \&.\&.\&.] ] ) ] |
+ SCHEMA \fIobject_name\fR |
+ SEQUENCE \fIobject_name\fR |
+ SUBSCRIPTION \fIobject_name\fR |
+ TABLESPACE \fIobject_name\fR |
+ TYPE \fIobject_name\fR |
+ VIEW \fIobject_name\fR
+} IS { \fIstring_literal\fR | NULL }
+
+where \fIaggregate_signature\fR is:
+
+* |
+[ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] |
+[ [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ] ] ORDER BY [ \fIargmode\fR ] [ \fIargname\fR ] \fIargtype\fR [ , \&.\&.\&. ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSECURITY LABEL\fR
+applies a security label to a database object\&. An arbitrary number of security labels, one per label provider, can be associated with a given database object\&. Label providers are loadable modules which register themselves by using the function
+\fBregister_label_provider\fR\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+\fBregister_label_provider\fR
+is not an SQL function; it can only be called from C code loaded into the backend\&.
+.sp .5v
+.RE
+.PP
+The label provider determines whether a given label is valid and whether it is permissible to assign that label to a given object\&. The meaning of a given label is likewise at the discretion of the label provider\&.
+PostgreSQL
+places no restrictions on whether or how a label provider must interpret security labels; it merely provides a mechanism for storing them\&. In practice, this facility is intended to allow integration with label\-based mandatory access control (MAC) systems such as
+SELinux\&. Such systems make all access control decisions based on object labels, rather than traditional discretionary access control (DAC) concepts such as users and groups\&.
+.SH "PARAMETERS"
+.PP
+\fIobject_name\fR
+.br
+\fItable_name\&.column_name\fR
+.br
+\fIaggregate_name\fR
+.br
+\fIfunction_name\fR
+.br
+\fIprocedure_name\fR
+.br
+\fIroutine_name\fR
+.RS 4
+The name of the object to be labeled\&. Names of objects that reside in schemas (tables, functions, etc\&.) can be schema\-qualified\&.
+.RE
+.PP
+\fIprovider\fR
+.RS 4
+The name of the provider with which this label is to be associated\&. The named provider must be loaded and must consent to the proposed labeling operation\&. If exactly one provider is loaded, the provider name may be omitted for brevity\&.
+.RE
+.PP
+\fIargmode\fR
+.RS 4
+The mode of a function, procedure, or aggregate argument:
+IN,
+OUT,
+INOUT, or
+VARIADIC\&. If omitted, the default is
+IN\&. Note that
+\fBSECURITY LABEL\fR
+does not actually pay any attention to
+OUT
+arguments, since only the input arguments are needed to determine the function\*(Aqs identity\&. So it is sufficient to list the
+IN,
+INOUT, and
+VARIADIC
+arguments\&.
+.RE
+.PP
+\fIargname\fR
+.RS 4
+The name of a function, procedure, or aggregate argument\&. Note that
+\fBSECURITY LABEL\fR
+does not actually pay any attention to argument names, since only the argument data types are needed to determine the function\*(Aqs identity\&.
+.RE
+.PP
+\fIargtype\fR
+.RS 4
+The data type of a function, procedure, or aggregate argument\&.
+.RE
+.PP
+\fIlarge_object_oid\fR
+.RS 4
+The OID of the large object\&.
+.RE
+.PP
+PROCEDURAL
+.RS 4
+This is a noise word\&.
+.RE
+.PP
+\fIstring_literal\fR
+.RS 4
+The new setting of the security label, written as a string literal\&.
+.RE
+.PP
+NULL
+.RS 4
+Write
+NULL
+to drop the security label\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The following example shows how the security label of a table could be set or changed:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SECURITY LABEL FOR selinux ON TABLE mytable IS \*(Aqsystem_u:object_r:sepgsql_table_t:s0\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+To remove the label:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SECURITY LABEL FOR selinux ON TABLE mytable IS NULL;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBSECURITY LABEL\fR
+command in the SQL standard\&.
+.SH "SEE ALSO"
+sepgsql, src/test/modules/dummy_seclabel
diff --git a/doc/src/sgml/man7/SELECT.7 b/doc/src/sgml/man7/SELECT.7
new file mode 100644
index 0000000..768e1ca
--- /dev/null
+++ b/doc/src/sgml/man7/SELECT.7
@@ -0,0 +1,2524 @@
+'\" t
+.\" Title: SELECT
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SELECT" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SELECT, TABLE, WITH \- retrieve rows from a table or view
+.SH "SYNOPSIS"
+.sp
+.nf
+[ WITH [ RECURSIVE ] \fIwith_query\fR [, \&.\&.\&.] ]
+SELECT [ ALL | DISTINCT [ ON ( \fIexpression\fR [, \&.\&.\&.] ) ] ]
+ [ * | \fIexpression\fR [ [ AS ] \fIoutput_name\fR ] [, \&.\&.\&.] ]
+ [ FROM \fIfrom_item\fR [, \&.\&.\&.] ]
+ [ WHERE \fIcondition\fR ]
+ [ GROUP BY [ ALL | DISTINCT ] \fIgrouping_element\fR [, \&.\&.\&.] ]
+ [ HAVING \fIcondition\fR ]
+ [ WINDOW \fIwindow_name\fR AS ( \fIwindow_definition\fR ) [, \&.\&.\&.] ]
+ [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] \fIselect\fR ]
+ [ ORDER BY \fIexpression\fR [ ASC | DESC | USING \fIoperator\fR ] [ NULLS { FIRST | LAST } ] [, \&.\&.\&.] ]
+ [ LIMIT { \fIcount\fR | ALL } ]
+ [ OFFSET \fIstart\fR [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ \fIcount\fR ] { ROW | ROWS } { ONLY | WITH TIES } ]
+ [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF \fItable_name\fR [, \&.\&.\&.] ] [ NOWAIT | SKIP LOCKED ] [\&.\&.\&.] ]
+
+where \fIfrom_item\fR can be one of:
+
+ [ ONLY ] \fItable_name\fR [ * ] [ [ AS ] \fIalias\fR [ ( \fIcolumn_alias\fR [, \&.\&.\&.] ) ] ]
+ [ TABLESAMPLE \fIsampling_method\fR ( \fIargument\fR [, \&.\&.\&.] ) [ REPEATABLE ( \fIseed\fR ) ] ]
+ [ LATERAL ] ( \fIselect\fR ) [ AS ] \fIalias\fR [ ( \fIcolumn_alias\fR [, \&.\&.\&.] ) ]
+ \fIwith_query_name\fR [ [ AS ] \fIalias\fR [ ( \fIcolumn_alias\fR [, \&.\&.\&.] ) ] ]
+ [ LATERAL ] \fIfunction_name\fR ( [ \fIargument\fR [, \&.\&.\&.] ] )
+ [ WITH ORDINALITY ] [ [ AS ] \fIalias\fR [ ( \fIcolumn_alias\fR [, \&.\&.\&.] ) ] ]
+ [ LATERAL ] \fIfunction_name\fR ( [ \fIargument\fR [, \&.\&.\&.] ] ) [ AS ] \fIalias\fR ( \fIcolumn_definition\fR [, \&.\&.\&.] )
+ [ LATERAL ] \fIfunction_name\fR ( [ \fIargument\fR [, \&.\&.\&.] ] ) AS ( \fIcolumn_definition\fR [, \&.\&.\&.] )
+ [ LATERAL ] ROWS FROM( \fIfunction_name\fR ( [ \fIargument\fR [, \&.\&.\&.] ] ) [ AS ( \fIcolumn_definition\fR [, \&.\&.\&.] ) ] [, \&.\&.\&.] )
+ [ WITH ORDINALITY ] [ [ AS ] \fIalias\fR [ ( \fIcolumn_alias\fR [, \&.\&.\&.] ) ] ]
+ \fIfrom_item\fR \fIjoin_type\fR \fIfrom_item\fR { ON \fIjoin_condition\fR | USING ( \fIjoin_column\fR [, \&.\&.\&.] ) [ AS \fIjoin_using_alias\fR ] }
+ \fIfrom_item\fR NATURAL \fIjoin_type\fR \fIfrom_item\fR
+ \fIfrom_item\fR CROSS JOIN \fIfrom_item\fR
+
+and \fIgrouping_element\fR can be one of:
+
+ ( )
+ \fIexpression\fR
+ ( \fIexpression\fR [, \&.\&.\&.] )
+ ROLLUP ( { \fIexpression\fR | ( \fIexpression\fR [, \&.\&.\&.] ) } [, \&.\&.\&.] )
+ CUBE ( { \fIexpression\fR | ( \fIexpression\fR [, \&.\&.\&.] ) } [, \&.\&.\&.] )
+ GROUPING SETS ( \fIgrouping_element\fR [, \&.\&.\&.] )
+
+and \fIwith_query\fR is:
+
+ \fIwith_query_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ] AS [ [ NOT ] MATERIALIZED ] ( \fIselect\fR | \fIvalues\fR | \fIinsert\fR | \fIupdate\fR | \fIdelete\fR )
+ [ SEARCH { BREADTH | DEPTH } FIRST BY \fIcolumn_name\fR [, \&.\&.\&.] SET \fIsearch_seq_col_name\fR ]
+ [ CYCLE \fIcolumn_name\fR [, \&.\&.\&.] SET \fIcycle_mark_col_name\fR [ TO \fIcycle_mark_value\fR DEFAULT \fIcycle_mark_default\fR ] USING \fIcycle_path_col_name\fR ]
+
+TABLE [ ONLY ] \fItable_name\fR [ * ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSELECT\fR
+retrieves rows from zero or more tables\&. The general processing of
+\fBSELECT\fR
+is as follows:
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 1.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 1." 4.2
+.\}
+All queries in the
+WITH
+list are computed\&. These effectively serve as temporary tables that can be referenced in the
+FROM
+list\&. A
+WITH
+query that is referenced more than once in
+FROM
+is computed only once, unless specified otherwise with
+NOT MATERIALIZED\&. (See
+WITH Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 2.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 2." 4.2
+.\}
+All elements in the
+FROM
+list are computed\&. (Each element in the
+FROM
+list is a real or virtual table\&.) If more than one element is specified in the
+FROM
+list, they are cross\-joined together\&. (See
+FROM Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 3.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 3." 4.2
+.\}
+If the
+WHERE
+clause is specified, all rows that do not satisfy the condition are eliminated from the output\&. (See
+WHERE Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 4.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 4." 4.2
+.\}
+If the
+GROUP BY
+clause is specified, or if there are aggregate function calls, the output is combined into groups of rows that match on one or more values, and the results of aggregate functions are computed\&. If the
+HAVING
+clause is present, it eliminates groups that do not satisfy the given condition\&. (See
+GROUP BY Clause
+and
+HAVING Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 5.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 5." 4.2
+.\}
+The actual output rows are computed using the
+\fBSELECT\fR
+output expressions for each selected row or row group\&. (See
+SELECT List
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 6.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 6." 4.2
+.\}
+SELECT DISTINCT
+eliminates duplicate rows from the result\&.
+SELECT DISTINCT ON
+eliminates rows that match on all the specified expressions\&.
+SELECT ALL
+(the default) will return all candidate rows, including duplicates\&. (See
+DISTINCT Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 7.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 7." 4.2
+.\}
+Using the operators
+UNION,
+INTERSECT, and
+EXCEPT, the output of more than one
+\fBSELECT\fR
+statement can be combined to form a single result set\&. The
+UNION
+operator returns all rows that are in one or both of the result sets\&. The
+INTERSECT
+operator returns all rows that are strictly in both result sets\&. The
+EXCEPT
+operator returns the rows that are in the first result set but not in the second\&. In all three cases, duplicate rows are eliminated unless
+ALL
+is specified\&. The noise word
+DISTINCT
+can be added to explicitly specify eliminating duplicate rows\&. Notice that
+DISTINCT
+is the default behavior here, even though
+ALL
+is the default for
+\fBSELECT\fR
+itself\&. (See
+UNION Clause,
+INTERSECT Clause, and
+EXCEPT Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 8.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 8." 4.2
+.\}
+If the
+ORDER BY
+clause is specified, the returned rows are sorted in the specified order\&. If
+ORDER BY
+is not given, the rows are returned in whatever order the system finds fastest to produce\&. (See
+ORDER BY Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04' 9.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP " 9." 4.2
+.\}
+If the
+LIMIT
+(or
+FETCH FIRST) or
+OFFSET
+clause is specified, the
+\fBSELECT\fR
+statement only returns a subset of the result rows\&. (See
+LIMIT Clause
+below\&.)
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'10.\h'+01'\c
+.\}
+.el \{\
+.sp -1
+.IP "10." 4.2
+.\}
+If
+FOR UPDATE,
+FOR NO KEY UPDATE,
+FOR SHARE
+or
+FOR KEY SHARE
+is specified, the
+\fBSELECT\fR
+statement locks the selected rows against concurrent updates\&. (See
+The Locking Clause
+below\&.)
+.RE
+.PP
+You must have
+SELECT
+privilege on each column used in a
+\fBSELECT\fR
+command\&. The use of
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+or
+FOR KEY SHARE
+requires
+UPDATE
+privilege as well (for at least one column of each table so selected)\&.
+.SH "PARAMETERS"
+.SS "WITH Clause"
+.PP
+The
+WITH
+clause allows you to specify one or more subqueries that can be referenced by name in the primary query\&. The subqueries effectively act as temporary tables or views for the duration of the primary query\&. Each subquery can be a
+\fBSELECT\fR,
+\fBTABLE\fR,
+\fBVALUES\fR,
+\fBINSERT\fR,
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+statement\&. When writing a data\-modifying statement (\fBINSERT\fR,
+\fBUPDATE\fR
+or
+\fBDELETE\fR) in
+WITH, it is usual to include a
+RETURNING
+clause\&. It is the output of
+RETURNING,
+\fInot\fR
+the underlying table that the statement modifies, that forms the temporary table that is read by the primary query\&. If
+RETURNING
+is omitted, the statement is still executed, but it produces no output so it cannot be referenced as a table by the primary query\&.
+.PP
+A name (without schema qualification) must be specified for each
+WITH
+query\&. Optionally, a list of column names can be specified; if this is omitted, the column names are inferred from the subquery\&.
+.PP
+If
+RECURSIVE
+is specified, it allows a
+\fBSELECT\fR
+subquery to reference itself by name\&. Such a subquery must have the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fInon_recursive_term\fR UNION [ ALL | DISTINCT ] \fIrecursive_term\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where the recursive self\-reference must appear on the right\-hand side of the
+UNION\&. Only one recursive self\-reference is permitted per query\&. Recursive data\-modifying statements are not supported, but you can use the results of a recursive
+\fBSELECT\fR
+query in a data\-modifying statement\&. See
+Section\ \&7.8
+for an example\&.
+.PP
+Another effect of
+RECURSIVE
+is that
+WITH
+queries need not be ordered: a query can reference another one that is later in the list\&. (However, circular references, or mutual recursion, are not implemented\&.) Without
+RECURSIVE,
+WITH
+queries can only reference sibling
+WITH
+queries that are earlier in the
+WITH
+list\&.
+.PP
+When there are multiple queries in the
+WITH
+clause,
+RECURSIVE
+should be written only once, immediately after
+WITH\&. It applies to all queries in the
+WITH
+clause, though it has no effect on queries that do not use recursion or forward references\&.
+.PP
+The optional
+SEARCH
+clause computes a
+search sequence column
+that can be used for ordering the results of a recursive query in either breadth\-first or depth\-first order\&. The supplied column name list specifies the row key that is to be used for keeping track of visited rows\&. A column named
+\fIsearch_seq_col_name\fR
+will be added to the result column list of the
+WITH
+query\&. This column can be ordered by in the outer query to achieve the respective ordering\&. See
+Section\ \&7.8.2.1
+for examples\&.
+.PP
+The optional
+CYCLE
+clause is used to detect cycles in recursive queries\&. The supplied column name list specifies the row key that is to be used for keeping track of visited rows\&. A column named
+\fIcycle_mark_col_name\fR
+will be added to the result column list of the
+WITH
+query\&. This column will be set to
+\fIcycle_mark_value\fR
+when a cycle has been detected, else to
+\fIcycle_mark_default\fR\&. Furthermore, processing of the recursive union will stop when a cycle has been detected\&.
+\fIcycle_mark_value\fR
+and
+\fIcycle_mark_default\fR
+must be constants and they must be coercible to a common data type, and the data type must have an inequality operator\&. (The SQL standard requires that they be Boolean constants or character strings, but PostgreSQL does not require that\&.) By default,
+TRUE
+and
+FALSE
+(of type
+boolean) are used\&. Furthermore, a column named
+\fIcycle_path_col_name\fR
+will be added to the result column list of the
+WITH
+query\&. This column is used internally for tracking visited rows\&. See
+Section\ \&7.8.2.2
+for examples\&.
+.PP
+Both the
+SEARCH
+and the
+CYCLE
+clause are only valid for recursive
+WITH
+queries\&. The
+\fIwith_query\fR
+must be a
+UNION
+(or
+UNION ALL) of two
+SELECT
+(or equivalent) commands (no nested
+UNIONs)\&. If both clauses are used, the column added by the
+SEARCH
+clause appears before the columns added by the
+CYCLE
+clause\&.
+.PP
+The primary query and the
+WITH
+queries are all (notionally) executed at the same time\&. This implies that the effects of a data\-modifying statement in
+WITH
+cannot be seen from other parts of the query, other than by reading its
+RETURNING
+output\&. If two such data\-modifying statements attempt to modify the same row, the results are unspecified\&.
+.PP
+A key property of
+WITH
+queries is that they are normally evaluated only once per execution of the primary query, even if the primary query refers to them more than once\&. In particular, data\-modifying statements are guaranteed to be executed once and only once, regardless of whether the primary query reads all or any of their output\&.
+.PP
+However, a
+WITH
+query can be marked
+NOT MATERIALIZED
+to remove this guarantee\&. In that case, the
+WITH
+query can be folded into the primary query much as though it were a simple sub\-SELECT
+in the primary query\*(Aqs
+FROM
+clause\&. This results in duplicate computations if the primary query refers to that
+WITH
+query more than once; but if each such use requires only a few rows of the
+WITH
+query\*(Aqs total output,
+NOT MATERIALIZED
+can provide a net savings by allowing the queries to be optimized jointly\&.
+NOT MATERIALIZED
+is ignored if it is attached to a
+WITH
+query that is recursive or is not side\-effect\-free (i\&.e\&., is not a plain
+SELECT
+containing no volatile functions)\&.
+.PP
+By default, a side\-effect\-free
+WITH
+query is folded into the primary query if it is used exactly once in the primary query\*(Aqs
+FROM
+clause\&. This allows joint optimization of the two query levels in situations where that should be semantically invisible\&. However, such folding can be prevented by marking the
+WITH
+query as
+MATERIALIZED\&. That might be useful, for example, if the
+WITH
+query is being used as an optimization fence to prevent the planner from choosing a bad plan\&.
+PostgreSQL
+versions before v12 never did such folding, so queries written for older versions might rely on
+WITH
+to act as an optimization fence\&.
+.PP
+See
+Section\ \&7.8
+for additional information\&.
+.SS "FROM Clause"
+.PP
+The
+FROM
+clause specifies one or more source tables for the
+\fBSELECT\fR\&. If multiple sources are specified, the result is the Cartesian product (cross join) of all the sources\&. But usually qualification conditions are added (via
+WHERE) to restrict the returned rows to a small subset of the Cartesian product\&.
+.PP
+The
+FROM
+clause can contain the following elements:
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of an existing table or view\&. If
+ONLY
+is specified before the table name, only that table is scanned\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are scanned\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+\fIalias\fR
+.RS 4
+A substitute name for the
+FROM
+item containing the alias\&. An alias is used for brevity or to eliminate ambiguity for self\-joins (where the same table is scanned multiple times)\&. When an alias is provided, it completely hides the actual name of the table or function; for example given
+FROM foo AS f, the remainder of the
+\fBSELECT\fR
+must refer to this
+FROM
+item as
+f
+not
+foo\&. If an alias is written, a column alias list can also be written to provide substitute names for one or more columns of the table\&.
+.RE
+.PP
+TABLESAMPLE \fIsampling_method\fR ( \fIargument\fR [, \&.\&.\&.] ) [ REPEATABLE ( \fIseed\fR ) ]
+.RS 4
+A
+TABLESAMPLE
+clause after a
+\fItable_name\fR
+indicates that the specified
+\fIsampling_method\fR
+should be used to retrieve a subset of the rows in that table\&. This sampling precedes the application of any other filters such as
+WHERE
+clauses\&. The standard
+PostgreSQL
+distribution includes two sampling methods,
+BERNOULLI
+and
+SYSTEM, and other sampling methods can be installed in the database via extensions\&.
+.sp
+The
+BERNOULLI
+and
+SYSTEM
+sampling methods each accept a single
+\fIargument\fR
+which is the fraction of the table to sample, expressed as a percentage between 0 and 100\&. This argument can be any
+real\-valued expression\&. (Other sampling methods might accept more or different arguments\&.) These two methods each return a randomly\-chosen sample of the table that will contain approximately the specified percentage of the table\*(Aqs rows\&. The
+BERNOULLI
+method scans the whole table and selects or ignores individual rows independently with the specified probability\&. The
+SYSTEM
+method does block\-level sampling with each block having the specified chance of being selected; all rows in each selected block are returned\&. The
+SYSTEM
+method is significantly faster than the
+BERNOULLI
+method when small sampling percentages are specified, but it may return a less\-random sample of the table as a result of clustering effects\&.
+.sp
+The optional
+REPEATABLE
+clause specifies a
+\fIseed\fR
+number or expression to use for generating random numbers within the sampling method\&. The seed value can be any non\-null floating\-point value\&. Two queries that specify the same seed and
+\fIargument\fR
+values will select the same sample of the table, if the table has not been changed meanwhile\&. But different seed values will usually produce different samples\&. If
+REPEATABLE
+is not given then a new random sample is selected for each query, based upon a system\-generated seed\&. Note that some add\-on sampling methods do not accept
+REPEATABLE, and will always produce new samples on each use\&.
+.RE
+.PP
+\fIselect\fR
+.RS 4
+A sub\-\fBSELECT\fR
+can appear in the
+FROM
+clause\&. This acts as though its output were created as a temporary table for the duration of this single
+\fBSELECT\fR
+command\&. Note that the sub\-\fBSELECT\fR
+must be surrounded by parentheses, and an alias
+\fImust\fR
+be provided for it\&. A
+\fBVALUES\fR
+command can also be used here\&.
+.RE
+.PP
+\fIwith_query_name\fR
+.RS 4
+A
+WITH
+query is referenced by writing its name, just as though the query\*(Aqs name were a table name\&. (In fact, the
+WITH
+query hides any real table of the same name for the purposes of the primary query\&. If necessary, you can refer to a real table of the same name by schema\-qualifying the table\*(Aqs name\&.) An alias can be provided in the same way as for a table\&.
+.RE
+.PP
+\fIfunction_name\fR
+.RS 4
+Function calls can appear in the
+FROM
+clause\&. (This is especially useful for functions that return result sets, but any function can be used\&.) This acts as though the function\*(Aqs output were created as a temporary table for the duration of this single
+\fBSELECT\fR
+command\&. If the function\*(Aqs result type is composite (including the case of a function with multiple
+OUT
+parameters), each attribute becomes a separate column in the implicit table\&.
+.sp
+When the optional
+\fBWITH ORDINALITY\fR
+clause is added to the function call, an additional column of type
+bigint
+will be appended to the function\*(Aqs result column(s)\&. This column numbers the rows of the function\*(Aqs result set, starting from 1\&. By default, this column is named
+ordinality\&.
+.sp
+An alias can be provided in the same way as for a table\&. If an alias is written, a column alias list can also be written to provide substitute names for one or more attributes of the function\*(Aqs composite return type, including the ordinality column if present\&.
+.sp
+Multiple function calls can be combined into a single
+FROM\-clause item by surrounding them with
+ROWS FROM( \&.\&.\&. )\&. The output of such an item is the concatenation of the first row from each function, then the second row from each function, etc\&. If some of the functions produce fewer rows than others, null values are substituted for the missing data, so that the total number of rows returned is always the same as for the function that produced the most rows\&.
+.sp
+If the function has been defined as returning the
+record
+data type, then an alias or the key word
+AS
+must be present, followed by a column definition list in the form
+( \fIcolumn_name\fR \fIdata_type\fR [, \&.\&.\&. ])\&. The column definition list must match the actual number and types of columns returned by the function\&.
+.sp
+When using the
+ROWS FROM( \&.\&.\&. )
+syntax, if one of the functions requires a column definition list, it\*(Aqs preferred to put the column definition list after the function call inside
+ROWS FROM( \&.\&.\&. )\&. A column definition list can be placed after the
+ROWS FROM( \&.\&.\&. )
+construct only if there\*(Aqs just a single function and no
+WITH ORDINALITY
+clause\&.
+.sp
+To use
+ORDINALITY
+together with a column definition list, you must use the
+ROWS FROM( \&.\&.\&. )
+syntax and put the column definition list inside
+ROWS FROM( \&.\&.\&. )\&.
+.RE
+.PP
+\fIjoin_type\fR
+.RS 4
+One of
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+[ INNER ] JOIN
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+LEFT [ OUTER ] JOIN
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+RIGHT [ OUTER ] JOIN
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+FULL [ OUTER ] JOIN
+.RE
+.sp
+For the
+INNER
+and
+OUTER
+join types, a join condition must be specified, namely exactly one of
+ON \fIjoin_condition\fR,
+USING (\fIjoin_column\fR [, \&.\&.\&.]), or
+NATURAL\&. See below for the meaning\&.
+.sp
+A
+JOIN
+clause combines two
+FROM
+items, which for convenience we will refer to as
+\(lqtables\(rq, though in reality they can be any type of
+FROM
+item\&. Use parentheses if necessary to determine the order of nesting\&. In the absence of parentheses,
+JOINs nest left\-to\-right\&. In any case
+JOIN
+binds more tightly than the commas separating
+FROM\-list items\&. All the
+JOIN
+options are just a notational convenience, since they do nothing you couldn\*(Aqt do with plain
+FROM
+and
+WHERE\&.
+.sp
+LEFT OUTER JOIN
+returns all rows in the qualified Cartesian product (i\&.e\&., all combined rows that pass its join condition), plus one copy of each row in the left\-hand table for which there was no right\-hand row that passed the join condition\&. This left\-hand row is extended to the full width of the joined table by inserting null values for the right\-hand columns\&. Note that only the
+JOIN
+clause\*(Aqs own condition is considered while deciding which rows have matches\&. Outer conditions are applied afterwards\&.
+.sp
+Conversely,
+RIGHT OUTER JOIN
+returns all the joined rows, plus one row for each unmatched right\-hand row (extended with nulls on the left)\&. This is just a notational convenience, since you could convert it to a
+LEFT OUTER JOIN
+by switching the left and right tables\&.
+.sp
+FULL OUTER JOIN
+returns all the joined rows, plus one row for each unmatched left\-hand row (extended with nulls on the right), plus one row for each unmatched right\-hand row (extended with nulls on the left)\&.
+.RE
+.PP
+ON \fIjoin_condition\fR
+.RS 4
+\fIjoin_condition\fR
+is an expression resulting in a value of type
+boolean
+(similar to a
+WHERE
+clause) that specifies which rows in a join are considered to match\&.
+.RE
+.PP
+USING ( \fIjoin_column\fR [, \&.\&.\&.] ) [ AS \fIjoin_using_alias\fR ]
+.RS 4
+A clause of the form
+USING ( a, b, \&.\&.\&. )
+is shorthand for
+ON left_table\&.a = right_table\&.a AND left_table\&.b = right_table\&.b \&.\&.\&.\&. Also,
+USING
+implies that only one of each pair of equivalent columns will be included in the join output, not both\&.
+.sp
+If a
+\fIjoin_using_alias\fR
+name is specified, it provides a table alias for the join columns\&. Only the join columns listed in the
+USING
+clause are addressable by this name\&. Unlike a regular
+\fIalias\fR, this does not hide the names of the joined tables from the rest of the query\&. Also unlike a regular
+\fIalias\fR, you cannot write a column alias list \(em the output names of the join columns are the same as they appear in the
+USING
+list\&.
+.RE
+.PP
+NATURAL
+.RS 4
+NATURAL
+is shorthand for a
+USING
+list that mentions all columns in the two tables that have matching names\&. If there are no common column names,
+NATURAL
+is equivalent to
+ON TRUE\&.
+.RE
+.PP
+CROSS JOIN
+.RS 4
+CROSS JOIN
+is equivalent to
+INNER JOIN ON (TRUE), that is, no rows are removed by qualification\&. They produce a simple Cartesian product, the same result as you get from listing the two tables at the top level of
+FROM, but restricted by the join condition (if any)\&.
+.RE
+.PP
+LATERAL
+.RS 4
+The
+LATERAL
+key word can precede a sub\-\fBSELECT\fR
+FROM
+item\&. This allows the sub\-\fBSELECT\fR
+to refer to columns of
+FROM
+items that appear before it in the
+FROM
+list\&. (Without
+LATERAL, each sub\-\fBSELECT\fR
+is evaluated independently and so cannot cross\-reference any other
+FROM
+item\&.)
+.sp
+LATERAL
+can also precede a function\-call
+FROM
+item, but in this case it is a noise word, because the function expression can refer to earlier
+FROM
+items in any case\&.
+.sp
+A
+LATERAL
+item can appear at top level in the
+FROM
+list, or within a
+JOIN
+tree\&. In the latter case it can also refer to any items that are on the left\-hand side of a
+JOIN
+that it is on the right\-hand side of\&.
+.sp
+When a
+FROM
+item contains
+LATERAL
+cross\-references, evaluation proceeds as follows: for each row of the
+FROM
+item providing the cross\-referenced column(s), or set of rows of multiple
+FROM
+items providing the columns, the
+LATERAL
+item is evaluated using that row or row set\*(Aqs values of the columns\&. The resulting row(s) are joined as usual with the rows they were computed from\&. This is repeated for each row or set of rows from the column source table(s)\&.
+.sp
+The column source table(s) must be
+INNER
+or
+LEFT
+joined to the
+LATERAL
+item, else there would not be a well\-defined set of rows from which to compute each set of rows for the
+LATERAL
+item\&. Thus, although a construct such as
+\fIX\fR RIGHT JOIN LATERAL \fIY\fR
+is syntactically valid, it is not actually allowed for
+\fIY\fR
+to reference
+\fIX\fR\&.
+.RE
+.SS "WHERE Clause"
+.PP
+The optional
+WHERE
+clause has the general form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WHERE \fIcondition\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIcondition\fR
+is any expression that evaluates to a result of type
+boolean\&. Any row that does not satisfy this condition will be eliminated from the output\&. A row satisfies the condition if it returns true when the actual row values are substituted for any variable references\&.
+.SS "GROUP BY Clause"
+.PP
+The optional
+GROUP BY
+clause has the general form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+GROUP BY [ ALL | DISTINCT ] \fIgrouping_element\fR [, \&.\&.\&.]
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+GROUP BY
+will condense into a single row all selected rows that share the same values for the grouped expressions\&. An
+\fIexpression\fR
+used inside a
+\fIgrouping_element\fR
+can be an input column name, or the name or ordinal number of an output column (\fBSELECT\fR
+list item), or an arbitrary expression formed from input\-column values\&. In case of ambiguity, a
+GROUP BY
+name will be interpreted as an input\-column name rather than an output column name\&.
+.PP
+If any of
+GROUPING SETS,
+ROLLUP
+or
+CUBE
+are present as grouping elements, then the
+GROUP BY
+clause as a whole defines some number of independent
+\fIgrouping sets\fR\&. The effect of this is equivalent to constructing a
+UNION ALL
+between subqueries with the individual grouping sets as their
+GROUP BY
+clauses\&. The optional
+DISTINCT
+clause removes duplicate sets before processing; it does
+\fInot\fR
+transform the
+UNION ALL
+into a
+UNION DISTINCT\&. For further details on the handling of grouping sets see
+Section\ \&7.2.4\&.
+.PP
+Aggregate functions, if any are used, are computed across all rows making up each group, producing a separate value for each group\&. (If there are aggregate functions but no
+GROUP BY
+clause, the query is treated as having a single group comprising all the selected rows\&.) The set of rows fed to each aggregate function can be further filtered by attaching a
+FILTER
+clause to the aggregate function call; see
+Section\ \&4.2.7
+for more information\&. When a
+FILTER
+clause is present, only those rows matching it are included in the input to that aggregate function\&.
+.PP
+When
+GROUP BY
+is present, or any aggregate functions are present, it is not valid for the
+\fBSELECT\fR
+list expressions to refer to ungrouped columns except within aggregate functions or when the ungrouped column is functionally dependent on the grouped columns, since there would otherwise be more than one possible value to return for an ungrouped column\&. A functional dependency exists if the grouped columns (or a subset thereof) are the primary key of the table containing the ungrouped column\&.
+.PP
+Keep in mind that all aggregate functions are evaluated before evaluating any
+\(lqscalar\(rq
+expressions in the
+HAVING
+clause or
+SELECT
+list\&. This means that, for example, a
+CASE
+expression cannot be used to skip evaluation of an aggregate function; see
+Section\ \&4.2.14\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified with
+GROUP BY\&.
+.SS "HAVING Clause"
+.PP
+The optional
+HAVING
+clause has the general form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+HAVING \fIcondition\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIcondition\fR
+is the same as specified for the
+WHERE
+clause\&.
+.PP
+HAVING
+eliminates group rows that do not satisfy the condition\&.
+HAVING
+is different from
+WHERE:
+WHERE
+filters individual rows before the application of
+GROUP BY, while
+HAVING
+filters group rows created by
+GROUP BY\&. Each column referenced in
+\fIcondition\fR
+must unambiguously reference a grouping column, unless the reference appears within an aggregate function or the ungrouped column is functionally dependent on the grouping columns\&.
+.PP
+The presence of
+HAVING
+turns a query into a grouped query even if there is no
+GROUP BY
+clause\&. This is the same as what happens when the query contains aggregate functions but no
+GROUP BY
+clause\&. All the selected rows are considered to form a single group, and the
+\fBSELECT\fR
+list and
+HAVING
+clause can only reference table columns from within aggregate functions\&. Such a query will emit a single row if the
+HAVING
+condition is true, zero rows if it is not true\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified with
+HAVING\&.
+.SS "WINDOW Clause"
+.PP
+The optional
+WINDOW
+clause has the general form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WINDOW \fIwindow_name\fR AS ( \fIwindow_definition\fR ) [, \&.\&.\&.]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIwindow_name\fR
+is a name that can be referenced from
+OVER
+clauses or subsequent window definitions, and
+\fIwindow_definition\fR
+is
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+[ \fIexisting_window_name\fR ]
+[ PARTITION BY \fIexpression\fR [, \&.\&.\&.] ]
+[ ORDER BY \fIexpression\fR [ ASC | DESC | USING \fIoperator\fR ] [ NULLS { FIRST | LAST } ] [, \&.\&.\&.] ]
+[ \fIframe_clause\fR ]
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+If an
+\fIexisting_window_name\fR
+is specified it must refer to an earlier entry in the
+WINDOW
+list; the new window copies its partitioning clause from that entry, as well as its ordering clause if any\&. In this case the new window cannot specify its own
+PARTITION BY
+clause, and it can specify
+ORDER BY
+only if the copied window does not have one\&. The new window always uses its own frame clause; the copied window must not specify a frame clause\&.
+.PP
+The elements of the
+PARTITION BY
+list are interpreted in much the same fashion as elements of a
+GROUP BY
+clause, except that they are always simple expressions and never the name or number of an output column\&. Another difference is that these expressions can contain aggregate function calls, which are not allowed in a regular
+GROUP BY
+clause\&. They are allowed here because windowing occurs after grouping and aggregation\&.
+.PP
+Similarly, the elements of the
+ORDER BY
+list are interpreted in much the same fashion as elements of a statement\-level
+ORDER BY
+clause, except that the expressions are always taken as simple expressions and never the name or number of an output column\&.
+.PP
+The optional
+\fIframe_clause\fR
+defines the
+window frame
+for window functions that depend on the frame (not all do)\&. The window frame is a set of related rows for each row of the query (called the
+current row)\&. The
+\fIframe_clause\fR
+can be one of
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+{ RANGE | ROWS | GROUPS } \fIframe_start\fR [ \fIframe_exclusion\fR ]
+{ RANGE | ROWS | GROUPS } BETWEEN \fIframe_start\fR AND \fIframe_end\fR [ \fIframe_exclusion\fR ]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIframe_start\fR
+and
+\fIframe_end\fR
+can be one of
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UNBOUNDED PRECEDING
+\fIoffset\fR PRECEDING
+CURRENT ROW
+\fIoffset\fR FOLLOWING
+UNBOUNDED FOLLOWING
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+and
+\fIframe_exclusion\fR
+can be one of
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+EXCLUDE CURRENT ROW
+EXCLUDE GROUP
+EXCLUDE TIES
+EXCLUDE NO OTHERS
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+If
+\fIframe_end\fR
+is omitted it defaults to
+CURRENT ROW\&. Restrictions are that
+\fIframe_start\fR
+cannot be
+UNBOUNDED FOLLOWING,
+\fIframe_end\fR
+cannot be
+UNBOUNDED PRECEDING, and the
+\fIframe_end\fR
+choice cannot appear earlier in the above list of
+\fIframe_start\fR
+and
+\fIframe_end\fR
+options than the
+\fIframe_start\fR
+choice does \(em for example
+RANGE BETWEEN CURRENT ROW AND \fIoffset\fR PRECEDING
+is not allowed\&.
+.PP
+The default framing option is
+RANGE UNBOUNDED PRECEDING, which is the same as
+RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW; it sets the frame to be all rows from the partition start up through the current row\*(Aqs last
+peer
+(a row that the window\*(Aqs
+ORDER BY
+clause considers equivalent to the current row; all rows are peers if there is no
+ORDER BY)\&. In general,
+UNBOUNDED PRECEDING
+means that the frame starts with the first row of the partition, and similarly
+UNBOUNDED FOLLOWING
+means that the frame ends with the last row of the partition, regardless of
+RANGE,
+ROWS
+or
+GROUPS
+mode\&. In
+ROWS
+mode,
+CURRENT ROW
+means that the frame starts or ends with the current row; but in
+RANGE
+or
+GROUPS
+mode it means that the frame starts or ends with the current row\*(Aqs first or last peer in the
+ORDER BY
+ordering\&. The
+\fIoffset\fR
+PRECEDING
+and
+\fIoffset\fR
+FOLLOWING
+options vary in meaning depending on the frame mode\&. In
+ROWS
+mode, the
+\fIoffset\fR
+is an integer indicating that the frame starts or ends that many rows before or after the current row\&. In
+GROUPS
+mode, the
+\fIoffset\fR
+is an integer indicating that the frame starts or ends that many peer groups before or after the current row\*(Aqs peer group, where a
+peer group
+is a group of rows that are equivalent according to the window\*(Aqs
+ORDER BY
+clause\&. In
+RANGE
+mode, use of an
+\fIoffset\fR
+option requires that there be exactly one
+ORDER BY
+column in the window definition\&. Then the frame contains those rows whose ordering column value is no more than
+\fIoffset\fR
+less than (for
+PRECEDING) or more than (for
+FOLLOWING) the current row\*(Aqs ordering column value\&. In these cases the data type of the
+\fIoffset\fR
+expression depends on the data type of the ordering column\&. For numeric ordering columns it is typically of the same type as the ordering column, but for datetime ordering columns it is an
+interval\&. In all these cases, the value of the
+\fIoffset\fR
+must be non\-null and non\-negative\&. Also, while the
+\fIoffset\fR
+does not have to be a simple constant, it cannot contain variables, aggregate functions, or window functions\&.
+.PP
+The
+\fIframe_exclusion\fR
+option allows rows around the current row to be excluded from the frame, even if they would be included according to the frame start and frame end options\&.
+EXCLUDE CURRENT ROW
+excludes the current row from the frame\&.
+EXCLUDE GROUP
+excludes the current row and its ordering peers from the frame\&.
+EXCLUDE TIES
+excludes any peers of the current row from the frame, but not the current row itself\&.
+EXCLUDE NO OTHERS
+simply specifies explicitly the default behavior of not excluding the current row or its peers\&.
+.PP
+Beware that the
+ROWS
+mode can produce unpredictable results if the
+ORDER BY
+ordering does not order the rows uniquely\&. The
+RANGE
+and
+GROUPS
+modes are designed to ensure that rows that are peers in the
+ORDER BY
+ordering are treated alike: all rows of a given peer group will be in the frame or excluded from it\&.
+.PP
+The purpose of a
+WINDOW
+clause is to specify the behavior of
+window functions
+appearing in the query\*(Aqs
+\fBSELECT\fR list
+or
+ORDER BY
+clause\&. These functions can reference the
+WINDOW
+clause entries by name in their
+OVER
+clauses\&. A
+WINDOW
+clause entry does not have to be referenced anywhere, however; if it is not used in the query it is simply ignored\&. It is possible to use window functions without any
+WINDOW
+clause at all, since a window function call can specify its window definition directly in its
+OVER
+clause\&. However, the
+WINDOW
+clause saves typing when the same window definition is needed for more than one window function\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified with
+WINDOW\&.
+.PP
+Window functions are described in detail in
+Section\ \&3.5,
+Section\ \&4.2.8, and
+Section\ \&7.2.5\&.
+.SS "SELECT List"
+.PP
+The
+\fBSELECT\fR
+list (between the key words
+SELECT
+and
+FROM) specifies expressions that form the output rows of the
+\fBSELECT\fR
+statement\&. The expressions can (and usually do) refer to columns computed in the
+FROM
+clause\&.
+.PP
+Just as in a table, every output column of a
+\fBSELECT\fR
+has a name\&. In a simple
+\fBSELECT\fR
+this name is just used to label the column for display, but when the
+\fBSELECT\fR
+is a sub\-query of a larger query, the name is seen by the larger query as the column name of the virtual table produced by the sub\-query\&. To specify the name to use for an output column, write
+AS
+\fIoutput_name\fR
+after the column\*(Aqs expression\&. (You can omit
+AS, but only if the desired output name does not match any
+PostgreSQL
+keyword (see
+Appendix\ \&C)\&. For protection against possible future keyword additions, it is recommended that you always either write
+AS
+or double\-quote the output name\&.) If you do not specify a column name, a name is chosen automatically by
+PostgreSQL\&. If the column\*(Aqs expression is a simple column reference then the chosen name is the same as that column\*(Aqs name\&. In more complex cases a function or type name may be used, or the system may fall back on a generated name such as
+?column?\&.
+.PP
+An output column\*(Aqs name can be used to refer to the column\*(Aqs value in
+ORDER BY
+and
+GROUP BY
+clauses, but not in the
+WHERE
+or
+HAVING
+clauses; there you must write out the expression instead\&.
+.PP
+Instead of an expression,
+*
+can be written in the output list as a shorthand for all the columns of the selected rows\&. Also, you can write
+\fItable_name\fR\&.*
+as a shorthand for the columns coming from just that table\&. In these cases it is not possible to specify new names with
+AS; the output column names will be the same as the table columns\*(Aq names\&.
+.PP
+According to the SQL standard, the expressions in the output list should be computed before applying
+DISTINCT,
+ORDER BY, or
+LIMIT\&. This is obviously necessary when using
+DISTINCT, since otherwise it\*(Aqs not clear what values are being made distinct\&. However, in many cases it is convenient if output expressions are computed after
+ORDER BY
+and
+LIMIT; particularly if the output list contains any volatile or expensive functions\&. With that behavior, the order of function evaluations is more intuitive and there will not be evaluations corresponding to rows that never appear in the output\&.
+PostgreSQL
+will effectively evaluate output expressions after sorting and limiting, so long as those expressions are not referenced in
+DISTINCT,
+ORDER BY
+or
+GROUP BY\&. (As a counterexample,
+SELECT f(x) FROM tab ORDER BY 1
+clearly must evaluate
+\fBf(x)\fR
+before sorting\&.) Output expressions that contain set\-returning functions are effectively evaluated after sorting and before limiting, so that
+LIMIT
+will act to cut off the output from a set\-returning function\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+PostgreSQL
+versions before 9\&.6 did not provide any guarantees about the timing of evaluation of output expressions versus sorting and limiting; it depended on the form of the chosen query plan\&.
+.sp .5v
+.RE
+.SS "DISTINCT Clause"
+.PP
+If
+SELECT DISTINCT
+is specified, all duplicate rows are removed from the result set (one row is kept from each group of duplicates)\&.
+SELECT ALL
+specifies the opposite: all rows are kept; that is the default\&.
+.PP
+SELECT DISTINCT ON ( \fIexpression\fR [, \&.\&.\&.] )
+keeps only the first row of each set of rows where the given expressions evaluate to equal\&. The
+DISTINCT ON
+expressions are interpreted using the same rules as for
+ORDER BY
+(see above)\&. Note that the
+\(lqfirst row\(rq
+of each set is unpredictable unless
+ORDER BY
+is used to ensure that the desired row appears first\&. For example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT DISTINCT ON (location) location, time, report
+ FROM weather_reports
+ ORDER BY location, time DESC;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+retrieves the most recent weather report for each location\&. But if we had not used
+ORDER BY
+to force descending order of time values for each location, we\*(Aqd have gotten a report from an unpredictable time for each location\&.
+.PP
+The
+DISTINCT ON
+expression(s) must match the leftmost
+ORDER BY
+expression(s)\&. The
+ORDER BY
+clause will normally contain additional expression(s) that determine the desired precedence of rows within each
+DISTINCT ON
+group\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified with
+DISTINCT\&.
+.SS "UNION Clause"
+.PP
+The
+UNION
+clause has this general form:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIselect_statement\fR UNION [ ALL | DISTINCT ] \fIselect_statement\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+\fIselect_statement\fR
+is any
+\fBSELECT\fR
+statement without an
+ORDER BY,
+LIMIT,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE, or
+FOR KEY SHARE
+clause\&. (ORDER BY
+and
+LIMIT
+can be attached to a subexpression if it is enclosed in parentheses\&. Without parentheses, these clauses will be taken to apply to the result of the
+UNION, not to its right\-hand input expression\&.)
+.PP
+The
+UNION
+operator computes the set union of the rows returned by the involved
+\fBSELECT\fR
+statements\&. A row is in the set union of two result sets if it appears in at least one of the result sets\&. The two
+\fBSELECT\fR
+statements that represent the direct operands of the
+UNION
+must produce the same number of columns, and corresponding columns must be of compatible data types\&.
+.PP
+The result of
+UNION
+does not contain any duplicate rows unless the
+ALL
+option is specified\&.
+ALL
+prevents elimination of duplicates\&. (Therefore,
+UNION ALL
+is usually significantly quicker than
+UNION; use
+ALL
+when you can\&.)
+DISTINCT
+can be written to explicitly specify the default behavior of eliminating duplicate rows\&.
+.PP
+Multiple
+UNION
+operators in the same
+\fBSELECT\fR
+statement are evaluated left to right, unless otherwise indicated by parentheses\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified either for a
+UNION
+result or for any input of a
+UNION\&.
+.SS "INTERSECT Clause"
+.PP
+The
+INTERSECT
+clause has this general form:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIselect_statement\fR INTERSECT [ ALL | DISTINCT ] \fIselect_statement\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+\fIselect_statement\fR
+is any
+\fBSELECT\fR
+statement without an
+ORDER BY,
+LIMIT,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE, or
+FOR KEY SHARE
+clause\&.
+.PP
+The
+INTERSECT
+operator computes the set intersection of the rows returned by the involved
+\fBSELECT\fR
+statements\&. A row is in the intersection of two result sets if it appears in both result sets\&.
+.PP
+The result of
+INTERSECT
+does not contain any duplicate rows unless the
+ALL
+option is specified\&. With
+ALL, a row that has
+\fIm\fR
+duplicates in the left table and
+\fIn\fR
+duplicates in the right table will appear min(\fIm\fR,\fIn\fR) times in the result set\&.
+DISTINCT
+can be written to explicitly specify the default behavior of eliminating duplicate rows\&.
+.PP
+Multiple
+INTERSECT
+operators in the same
+\fBSELECT\fR
+statement are evaluated left to right, unless parentheses dictate otherwise\&.
+INTERSECT
+binds more tightly than
+UNION\&. That is,
+A UNION B INTERSECT C
+will be read as
+A UNION (B INTERSECT C)\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified either for an
+INTERSECT
+result or for any input of an
+INTERSECT\&.
+.SS "EXCEPT Clause"
+.PP
+The
+EXCEPT
+clause has this general form:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+\fIselect_statement\fR EXCEPT [ ALL | DISTINCT ] \fIselect_statement\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+\fIselect_statement\fR
+is any
+\fBSELECT\fR
+statement without an
+ORDER BY,
+LIMIT,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE, or
+FOR KEY SHARE
+clause\&.
+.PP
+The
+EXCEPT
+operator computes the set of rows that are in the result of the left
+\fBSELECT\fR
+statement but not in the result of the right one\&.
+.PP
+The result of
+EXCEPT
+does not contain any duplicate rows unless the
+ALL
+option is specified\&. With
+ALL, a row that has
+\fIm\fR
+duplicates in the left table and
+\fIn\fR
+duplicates in the right table will appear max(\fIm\fR\-\fIn\fR,0) times in the result set\&.
+DISTINCT
+can be written to explicitly specify the default behavior of eliminating duplicate rows\&.
+.PP
+Multiple
+EXCEPT
+operators in the same
+\fBSELECT\fR
+statement are evaluated left to right, unless parentheses dictate otherwise\&.
+EXCEPT
+binds at the same level as
+UNION\&.
+.PP
+Currently,
+FOR NO KEY UPDATE,
+FOR UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+cannot be specified either for an
+EXCEPT
+result or for any input of an
+EXCEPT\&.
+.SS "ORDER BY Clause"
+.PP
+The optional
+ORDER BY
+clause has this general form:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ORDER BY \fIexpression\fR [ ASC | DESC | USING \fIoperator\fR ] [ NULLS { FIRST | LAST } ] [, \&.\&.\&.]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+ORDER BY
+clause causes the result rows to be sorted according to the specified expression(s)\&. If two rows are equal according to the leftmost expression, they are compared according to the next expression and so on\&. If they are equal according to all specified expressions, they are returned in an implementation\-dependent order\&.
+.PP
+Each
+\fIexpression\fR
+can be the name or ordinal number of an output column (\fBSELECT\fR
+list item), or it can be an arbitrary expression formed from input\-column values\&.
+.PP
+The ordinal number refers to the ordinal (left\-to\-right) position of the output column\&. This feature makes it possible to define an ordering on the basis of a column that does not have a unique name\&. This is never absolutely necessary because it is always possible to assign a name to an output column using the
+AS
+clause\&.
+.PP
+It is also possible to use arbitrary expressions in the
+ORDER BY
+clause, including columns that do not appear in the
+\fBSELECT\fR
+output list\&. Thus the following statement is valid:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT name FROM distributors ORDER BY code;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A limitation of this feature is that an
+ORDER BY
+clause applying to the result of a
+UNION,
+INTERSECT, or
+EXCEPT
+clause can only specify an output column name or number, not an expression\&.
+.PP
+If an
+ORDER BY
+expression is a simple name that matches both an output column name and an input column name,
+ORDER BY
+will interpret it as the output column name\&. This is the opposite of the choice that
+GROUP BY
+will make in the same situation\&. This inconsistency is made to be compatible with the SQL standard\&.
+.PP
+Optionally one can add the key word
+ASC
+(ascending) or
+DESC
+(descending) after any expression in the
+ORDER BY
+clause\&. If not specified,
+ASC
+is assumed by default\&. Alternatively, a specific ordering operator name can be specified in the
+USING
+clause\&. An ordering operator must be a less\-than or greater\-than member of some B\-tree operator family\&.
+ASC
+is usually equivalent to
+USING <
+and
+DESC
+is usually equivalent to
+USING >\&. (But the creator of a user\-defined data type can define exactly what the default sort ordering is, and it might correspond to operators with other names\&.)
+.PP
+If
+NULLS LAST
+is specified, null values sort after all non\-null values; if
+NULLS FIRST
+is specified, null values sort before all non\-null values\&. If neither is specified, the default behavior is
+NULLS LAST
+when
+ASC
+is specified or implied, and
+NULLS FIRST
+when
+DESC
+is specified (thus, the default is to act as though nulls are larger than non\-nulls)\&. When
+USING
+is specified, the default nulls ordering depends on whether the operator is a less\-than or greater\-than operator\&.
+.PP
+Note that ordering options apply only to the expression they follow; for example
+ORDER BY x, y DESC
+does not mean the same thing as
+ORDER BY x DESC, y DESC\&.
+.PP
+Character\-string data is sorted according to the collation that applies to the column being sorted\&. That can be overridden at need by including a
+COLLATE
+clause in the
+\fIexpression\fR, for example
+ORDER BY mycolumn COLLATE "en_US"\&. For more information see
+Section\ \&4.2.10
+and
+Section\ \&24.2\&.
+.SS "LIMIT Clause"
+.PP
+The
+LIMIT
+clause consists of two independent sub\-clauses:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+LIMIT { \fIcount\fR | ALL }
+OFFSET \fIstart\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The parameter
+\fIcount\fR
+specifies the maximum number of rows to return, while
+\fIstart\fR
+specifies the number of rows to skip before starting to return rows\&. When both are specified,
+\fIstart\fR
+rows are skipped before starting to count the
+\fIcount\fR
+rows to be returned\&.
+.PP
+If the
+\fIcount\fR
+expression evaluates to NULL, it is treated as
+LIMIT ALL, i\&.e\&., no limit\&. If
+\fIstart\fR
+evaluates to NULL, it is treated the same as
+OFFSET 0\&.
+.PP
+SQL:2008 introduced a different syntax to achieve the same result, which
+PostgreSQL
+also supports\&. It is:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+OFFSET \fIstart\fR { ROW | ROWS }
+FETCH { FIRST | NEXT } [ \fIcount\fR ] { ROW | ROWS } { ONLY | WITH TIES }
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+In this syntax, the
+\fIstart\fR
+or
+\fIcount\fR
+value is required by the standard to be a literal constant, a parameter, or a variable name; as a
+PostgreSQL
+extension, other expressions are allowed, but will generally need to be enclosed in parentheses to avoid ambiguity\&. If
+\fIcount\fR
+is omitted in a
+FETCH
+clause, it defaults to 1\&. The
+WITH TIES
+option is used to return any additional rows that tie for the last place in the result set according to the
+ORDER BY
+clause;
+ORDER BY
+is mandatory in this case, and
+SKIP LOCKED
+is not allowed\&.
+ROW
+and
+ROWS
+as well as
+FIRST
+and
+NEXT
+are noise words that don\*(Aqt influence the effects of these clauses\&. According to the standard, the
+OFFSET
+clause must come before the
+FETCH
+clause if both are present; but
+PostgreSQL
+is laxer and allows either order\&.
+.PP
+When using
+LIMIT, it is a good idea to use an
+ORDER BY
+clause that constrains the result rows into a unique order\&. Otherwise you will get an unpredictable subset of the query\*(Aqs rows \(em you might be asking for the tenth through twentieth rows, but tenth through twentieth in what ordering? You don\*(Aqt know what ordering unless you specify
+ORDER BY\&.
+.PP
+The query planner takes
+LIMIT
+into account when generating a query plan, so you are very likely to get different plans (yielding different row orders) depending on what you use for
+LIMIT
+and
+OFFSET\&. Thus, using different
+LIMIT/OFFSET
+values to select different subsets of a query result
+\fIwill give inconsistent results\fR
+unless you enforce a predictable result ordering with
+ORDER BY\&. This is not a bug; it is an inherent consequence of the fact that SQL does not promise to deliver the results of a query in any particular order unless
+ORDER BY
+is used to constrain the order\&.
+.PP
+It is even possible for repeated executions of the same
+LIMIT
+query to return different subsets of the rows of a table, if there is not an
+ORDER BY
+to enforce selection of a deterministic subset\&. Again, this is not a bug; determinism of the results is simply not guaranteed in such a case\&.
+.SS "The Locking Clause"
+.PP
+FOR UPDATE,
+FOR NO KEY UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+are
+locking clauses; they affect how
+SELECT
+locks rows as they are obtained from the table\&.
+.PP
+The locking clause has the general form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+FOR \fIlock_strength\fR [ OF \fItable_name\fR [, \&.\&.\&.] ] [ NOWAIT | SKIP LOCKED ]
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+where
+\fIlock_strength\fR
+can be one of
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE
+NO KEY UPDATE
+SHARE
+KEY SHARE
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+For more information on each row\-level lock mode, refer to
+Section\ \&13.3.2\&.
+.PP
+To prevent the operation from waiting for other transactions to commit, use either the
+NOWAIT
+or
+SKIP LOCKED
+option\&. With
+NOWAIT, the statement reports an error, rather than waiting, if a selected row cannot be locked immediately\&. With
+SKIP LOCKED, any selected rows that cannot be immediately locked are skipped\&. Skipping locked rows provides an inconsistent view of the data, so this is not suitable for general purpose work, but can be used to avoid lock contention with multiple consumers accessing a queue\-like table\&. Note that
+NOWAIT
+and
+SKIP LOCKED
+apply only to the row\-level lock(s) \(em the required
+ROW SHARE
+table\-level lock is still taken in the ordinary way (see
+Chapter\ \&13)\&. You can use
+\fBLOCK\fR
+with the
+NOWAIT
+option first, if you need to acquire the table\-level lock without waiting\&.
+.PP
+If specific tables are named in a locking clause, then only rows coming from those tables are locked; any other tables used in the
+\fBSELECT\fR
+are simply read as usual\&. A locking clause without a table list affects all tables used in the statement\&. If a locking clause is applied to a view or sub\-query, it affects all tables used in the view or sub\-query\&. However, these clauses do not apply to
+WITH
+queries referenced by the primary query\&. If you want row locking to occur within a
+WITH
+query, specify a locking clause within the
+WITH
+query\&.
+.PP
+Multiple locking clauses can be written if it is necessary to specify different locking behavior for different tables\&. If the same table is mentioned (or implicitly affected) by more than one locking clause, then it is processed as if it was only specified by the strongest one\&. Similarly, a table is processed as
+NOWAIT
+if that is specified in any of the clauses affecting it\&. Otherwise, it is processed as
+SKIP LOCKED
+if that is specified in any of the clauses affecting it\&.
+.PP
+The locking clauses cannot be used in contexts where returned rows cannot be clearly identified with individual table rows; for example they cannot be used with aggregation\&.
+.PP
+When a locking clause appears at the top level of a
+\fBSELECT\fR
+query, the rows that are locked are exactly those that are returned by the query; in the case of a join query, the rows locked are those that contribute to returned join rows\&. In addition, rows that satisfied the query conditions as of the query snapshot will be locked, although they will not be returned if they were updated after the snapshot and no longer satisfy the query conditions\&. If a
+LIMIT
+is used, locking stops once enough rows have been returned to satisfy the limit (but note that rows skipped over by
+OFFSET
+will get locked)\&. Similarly, if a locking clause is used in a cursor\*(Aqs query, only rows actually fetched or stepped past by the cursor will be locked\&.
+.PP
+When a locking clause appears in a sub\-\fBSELECT\fR, the rows locked are those returned to the outer query by the sub\-query\&. This might involve fewer rows than inspection of the sub\-query alone would suggest, since conditions from the outer query might be used to optimize execution of the sub\-query\&. For example,
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+will lock only rows having
+col1 = 5, even though that condition is not textually within the sub\-query\&.
+.PP
+Previous releases failed to preserve a lock which is upgraded by a later savepoint\&. For example, this code:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+SELECT * FROM mytable WHERE key = 1 FOR UPDATE;
+SAVEPOINT s;
+UPDATE mytable SET \&.\&.\&. WHERE key = 1;
+ROLLBACK TO s;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+would fail to preserve the
+FOR UPDATE
+lock after the
+\fBROLLBACK TO\fR\&. This has been fixed in release 9\&.3\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBCaution\fR
+.ps -1
+.br
+.PP
+It is possible for a
+\fBSELECT\fR
+command running at the
+READ COMMITTED
+transaction isolation level and using
+ORDER BY
+and a locking clause to return rows out of order\&. This is because
+ORDER BY
+is applied first\&. The command sorts the result, but might then block trying to obtain a lock on one or more of the rows\&. Once the
+SELECT
+unblocks, some of the ordering column values might have been modified, leading to those rows appearing to be out of order (though they are in order in terms of the original column values)\&. This can be worked around at need by placing the
+FOR UPDATE/SHARE
+clause in a sub\-query, for example
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that this will result in locking all rows of
+mytable, whereas
+FOR UPDATE
+at the top level would lock only the actually returned rows\&. This can make for a significant performance difference, particularly if the
+ORDER BY
+is combined with
+LIMIT
+or other restrictions\&. So this technique is recommended only if concurrent updates of the ordering columns are expected and a strictly sorted result is required\&.
+.PP
+At the
+REPEATABLE READ
+or
+SERIALIZABLE
+transaction isolation level this would cause a serialization failure (with an
+SQLSTATE
+of
+\*(Aq40001\*(Aq), so there is no possibility of receiving rows out of order under these isolation levels\&.
+.sp .5v
+.RE
+.SS "TABLE Command"
+.PP
+The command
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+TABLE \fIname\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+is equivalent to
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM \fIname\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+It can be used as a top\-level command or as a space\-saving syntax variant in parts of complex queries\&. Only the
+WITH,
+UNION,
+INTERSECT,
+EXCEPT,
+ORDER BY,
+LIMIT,
+OFFSET,
+FETCH
+and
+FOR
+locking clauses can be used with
+\fBTABLE\fR; the
+WHERE
+clause and any form of aggregation cannot be used\&.
+.SH "EXAMPLES"
+.PP
+To join the table
+films
+with the table
+distributors:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT f\&.title, f\&.did, d\&.name, f\&.date_prod, f\&.kind
+ FROM distributors d JOIN films f USING (did);
+
+ title | did | name | date_prod | kind
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-
+ The Third Man | 101 | British Lion | 1949\-12\-23 | Drama
+ The African Queen | 101 | British Lion | 1951\-08\-11 | Romantic
+ \&.\&.\&.
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To sum the column
+len
+of all films and group the results by
+kind:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT kind, sum(len) AS total FROM films GROUP BY kind;
+
+ kind | total
+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+ Action | 07:34
+ Comedy | 02:58
+ Drama | 14:28
+ Musical | 06:42
+ Romantic | 04:38
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To sum the column
+len
+of all films, group the results by
+kind
+and show those group totals that are less than 5 hours:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT kind, sum(len) AS total
+ FROM films
+ GROUP BY kind
+ HAVING sum(len) < interval \*(Aq5 hours\*(Aq;
+
+ kind | total
+\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-
+ Comedy | 02:58
+ Romantic | 04:38
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The following two examples are identical ways of sorting the individual results according to the contents of the second column (name):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM distributors ORDER BY name;
+SELECT * FROM distributors ORDER BY 2;
+
+ did | name
+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 109 | 20th Century Fox
+ 110 | Bavaria Atelier
+ 101 | British Lion
+ 107 | Columbia
+ 102 | Jean Luc Godard
+ 113 | Luso films
+ 104 | Mosfilm
+ 103 | Paramount
+ 106 | Toho
+ 105 | United Artists
+ 111 | Walt Disney
+ 112 | Warner Bros\&.
+ 108 | Westward
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The next example shows how to obtain the union of the tables
+distributors
+and
+actors, restricting the results to those that begin with the letter W in each table\&. Only distinct rows are wanted, so the key word
+ALL
+is omitted\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+distributors: actors:
+ did | name id | name
+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 108 | Westward 1 | Woody Allen
+ 111 | Walt Disney 2 | Warren Beatty
+ 112 | Warner Bros\&. 3 | Walter Matthau
+ \&.\&.\&. \&.\&.\&.
+
+SELECT distributors\&.name
+ FROM distributors
+ WHERE distributors\&.name LIKE \*(AqW%\*(Aq
+UNION
+SELECT actors\&.name
+ FROM actors
+ WHERE actors\&.name LIKE \*(AqW%\*(Aq;
+
+ name
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ Walt Disney
+ Walter Matthau
+ Warner Bros\&.
+ Warren Beatty
+ Westward
+ Woody Allen
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example shows how to use a function in the
+FROM
+clause, both with and without a column definition list:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+CREATE FUNCTION distributors(int) RETURNS SETOF distributors AS $$
+ SELECT * FROM distributors WHERE did = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM distributors(111);
+ did | name
+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 111 | Walt Disney
+
+CREATE FUNCTION distributors_2(int) RETURNS SETOF record AS $$
+ SELECT * FROM distributors WHERE did = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM distributors_2(111) AS (f1 int, f2 text);
+ f1 | f2
+\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 111 | Walt Disney
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Here is an example of a function with an ordinality column added:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM unnest(ARRAY[\*(Aqa\*(Aq,\*(Aqb\*(Aq,\*(Aqc\*(Aq,\*(Aqd\*(Aq,\*(Aqe\*(Aq,\*(Aqf\*(Aq]) WITH ORDINALITY;
+ unnest | ordinality
+\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-
+ a | 1
+ b | 2
+ c | 3
+ d | 4
+ e | 5
+ f | 6
+(6 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This example shows how to use a simple
+WITH
+clause:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WITH t AS (
+ SELECT random() as x FROM generate_series(1, 3)
+ )
+SELECT * FROM t
+UNION ALL
+SELECT * FROM t
+
+ x
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 0\&.534150459803641
+ 0\&.520092216785997
+ 0\&.0735620250925422
+ 0\&.534150459803641
+ 0\&.520092216785997
+ 0\&.0735620250925422
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Notice that the
+WITH
+query was evaluated only once, so that we got two sets of the same three random values\&.
+.PP
+This example uses
+WITH RECURSIVE
+to find all subordinates (direct or indirect) of the employee Mary, and their level of indirectness, from a table that shows only direct subordinates:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (
+ SELECT 1, employee_name, manager_name
+ FROM employee
+ WHERE manager_name = \*(AqMary\*(Aq
+ UNION ALL
+ SELECT er\&.distance + 1, e\&.employee_name, e\&.manager_name
+ FROM employee_recursive er, employee e
+ WHERE er\&.employee_name = e\&.manager_name
+ )
+SELECT distance, employee_name FROM employee_recursive;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Notice the typical form of recursive queries: an initial condition, followed by
+UNION, followed by the recursive part of the query\&. Be sure that the recursive part of the query will eventually return no tuples, or else the query will loop indefinitely\&. (See
+Section\ \&7.8
+for more examples\&.)
+.PP
+This example uses
+LATERAL
+to apply a set\-returning function
+\fBget_product_names()\fR
+for each row of the
+manufacturers
+table:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT m\&.name AS mname, pname
+FROM manufacturers m, LATERAL get_product_names(m\&.id) pname;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Manufacturers not currently having any products would not appear in the result, since it is an inner join\&. If we wished to include the names of such manufacturers in the result, we could do:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT m\&.name AS mname, pname
+FROM manufacturers m LEFT JOIN LATERAL get_product_names(m\&.id) pname ON true;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+Of course, the
+\fBSELECT\fR
+statement is compatible with the SQL standard\&. But there are some extensions and some missing features\&.
+.SS "Omitted FROM Clauses"
+.PP
+PostgreSQL
+allows one to omit the
+FROM
+clause\&. It has a straightforward use to compute the results of simple expressions:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT 2+2;
+
+ ?column?
+\-\-\-\-\-\-\-\-\-\-
+ 4
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Some other
+SQL
+databases cannot do this except by introducing a dummy one\-row table from which to do the
+\fBSELECT\fR\&.
+.SS "Empty SELECT Lists"
+.PP
+The list of output expressions after
+SELECT
+can be empty, producing a zero\-column result table\&. This is not valid syntax according to the SQL standard\&.
+PostgreSQL
+allows it to be consistent with allowing zero\-column tables\&. However, an empty list is not allowed when
+DISTINCT
+is used\&.
+.SS "Omitting the AS Key Word"
+.PP
+In the SQL standard, the optional key word
+AS
+can be omitted before an output column name whenever the new column name is a valid column name (that is, not the same as any reserved keyword)\&.
+PostgreSQL
+is slightly more restrictive:
+AS
+is required if the new column name matches any keyword at all, reserved or not\&. Recommended practice is to use
+AS
+or double\-quote output column names, to prevent any possible conflict against future keyword additions\&.
+.PP
+In
+FROM
+items, both the standard and
+PostgreSQL
+allow
+AS
+to be omitted before an alias that is an unreserved keyword\&. But this is impractical for output column names, because of syntactic ambiguities\&.
+.SS "ONLY and Inheritance"
+.PP
+The SQL standard requires parentheses around the table name when writing
+ONLY, for example
+SELECT * FROM ONLY (tab1), ONLY (tab2) WHERE \&.\&.\&.\&.
+PostgreSQL
+considers these parentheses to be optional\&.
+.PP
+PostgreSQL
+allows a trailing
+*
+to be written to explicitly specify the non\-ONLY
+behavior of including child tables\&. The standard does not allow this\&.
+.PP
+(These points apply equally to all SQL commands supporting the
+ONLY
+option\&.)
+.SS "TABLESAMPLE Clause Restrictions"
+.PP
+The
+TABLESAMPLE
+clause is currently accepted only on regular tables and materialized views\&. According to the SQL standard it should be possible to apply it to any
+FROM
+item\&.
+.SS "Function Calls in FROM"
+.PP
+PostgreSQL
+allows a function call to be written directly as a member of the
+FROM
+list\&. In the SQL standard it would be necessary to wrap such a function call in a sub\-\fBSELECT\fR; that is, the syntax
+FROM \fIfunc\fR(\&.\&.\&.) \fIalias\fR
+is approximately equivalent to
+FROM LATERAL (SELECT \fIfunc\fR(\&.\&.\&.)) \fIalias\fR\&. Note that
+LATERAL
+is considered to be implicit; this is because the standard requires
+LATERAL
+semantics for an
+UNNEST()
+item in
+FROM\&.
+PostgreSQL
+treats
+UNNEST()
+the same as other set\-returning functions\&.
+.SS "Namespace Available to GROUP BY and ORDER BY"
+.PP
+In the SQL\-92 standard, an
+ORDER BY
+clause can only use output column names or numbers, while a
+GROUP BY
+clause can only use expressions based on input column names\&.
+PostgreSQL
+extends each of these clauses to allow the other choice as well (but it uses the standard\*(Aqs interpretation if there is ambiguity)\&.
+PostgreSQL
+also allows both clauses to specify arbitrary expressions\&. Note that names appearing in an expression will always be taken as input\-column names, not as output\-column names\&.
+.PP
+SQL:1999 and later use a slightly different definition which is not entirely upward compatible with SQL\-92\&. In most cases, however,
+PostgreSQL
+will interpret an
+ORDER BY
+or
+GROUP BY
+expression the same way SQL:1999 does\&.
+.SS "Functional Dependencies"
+.PP
+PostgreSQL
+recognizes functional dependency (allowing columns to be omitted from
+GROUP BY) only when a table\*(Aqs primary key is included in the
+GROUP BY
+list\&. The SQL standard specifies additional conditions that should be recognized\&.
+.SS "LIMIT and OFFSET"
+.PP
+The clauses
+LIMIT
+and
+OFFSET
+are
+PostgreSQL\-specific syntax, also used by
+MySQL\&. The SQL:2008 standard has introduced the clauses
+OFFSET \&.\&.\&. FETCH {FIRST|NEXT} \&.\&.\&.
+for the same functionality, as shown above in
+LIMIT Clause\&. This syntax is also used by
+IBM DB2\&. (Applications written for
+Oracle
+frequently use a workaround involving the automatically generated
+rownum
+column, which is not available in PostgreSQL, to implement the effects of these clauses\&.)
+.SS "FOR NO KEY UPDATE, FOR UPDATE, FOR SHARE, FOR KEY SHARE"
+.PP
+Although
+FOR UPDATE
+appears in the SQL standard, the standard allows it only as an option of
+\fBDECLARE CURSOR\fR\&.
+PostgreSQL
+allows it in any
+\fBSELECT\fR
+query as well as in sub\-\fBSELECT\fRs, but this is an extension\&. The
+FOR NO KEY UPDATE,
+FOR SHARE
+and
+FOR KEY SHARE
+variants, as well as the
+NOWAIT
+and
+SKIP LOCKED
+options, do not appear in the standard\&.
+.SS "Data\-Modifying Statements in WITH"
+.PP
+PostgreSQL
+allows
+\fBINSERT\fR,
+\fBUPDATE\fR, and
+\fBDELETE\fR
+to be used as
+WITH
+queries\&. This is not found in the SQL standard\&.
+.SS "Nonstandard Clauses"
+.PP
+DISTINCT ON ( \&.\&.\&. )
+is an extension of the SQL standard\&.
+.PP
+ROWS FROM( \&.\&.\&. )
+is an extension of the SQL standard\&.
+.PP
+The
+MATERIALIZED
+and
+NOT MATERIALIZED
+options of
+WITH
+are extensions of the SQL standard\&.
diff --git a/doc/src/sgml/man7/SELECT_INTO.7 b/doc/src/sgml/man7/SELECT_INTO.7
new file mode 100644
index 0000000..8261252
--- /dev/null
+++ b/doc/src/sgml/man7/SELECT_INTO.7
@@ -0,0 +1,147 @@
+'\" t
+.\" Title: SELECT INTO
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SELECT INTO" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SELECT_INTO \- define a new table from the results of a query
+.SH "SYNOPSIS"
+.sp
+.nf
+[ WITH [ RECURSIVE ] \fIwith_query\fR [, \&.\&.\&.] ]
+SELECT [ ALL | DISTINCT [ ON ( \fIexpression\fR [, \&.\&.\&.] ) ] ]
+ * | \fIexpression\fR [ [ AS ] \fIoutput_name\fR ] [, \&.\&.\&.]
+ INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] \fInew_table\fR
+ [ FROM \fIfrom_item\fR [, \&.\&.\&.] ]
+ [ WHERE \fIcondition\fR ]
+ [ GROUP BY \fIexpression\fR [, \&.\&.\&.] ]
+ [ HAVING \fIcondition\fR ]
+ [ WINDOW \fIwindow_name\fR AS ( \fIwindow_definition\fR ) [, \&.\&.\&.] ]
+ [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] \fIselect\fR ]
+ [ ORDER BY \fIexpression\fR [ ASC | DESC | USING \fIoperator\fR ] [ NULLS { FIRST | LAST } ] [, \&.\&.\&.] ]
+ [ LIMIT { \fIcount\fR | ALL } ]
+ [ OFFSET \fIstart\fR [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ \fIcount\fR ] { ROW | ROWS } ONLY ]
+ [ FOR { UPDATE | SHARE } [ OF \fItable_name\fR [, \&.\&.\&.] ] [ NOWAIT ] [\&.\&.\&.] ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSELECT INTO\fR
+creates a new table and fills it with data computed by a query\&. The data is not returned to the client, as it is with a normal
+\fBSELECT\fR\&. The new table\*(Aqs columns have the names and data types associated with the output columns of the
+\fBSELECT\fR\&.
+.SH "PARAMETERS"
+.PP
+TEMPORARY or TEMP
+.RS 4
+If specified, the table is created as a temporary table\&. Refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for details\&.
+.RE
+.PP
+UNLOGGED
+.RS 4
+If specified, the table is created as an unlogged table\&. Refer to
+CREATE TABLE (\fBCREATE_TABLE\fR(7))
+for details\&.
+.RE
+.PP
+\fInew_table\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to be created\&.
+.RE
+.PP
+All other parameters are described in detail under
+\fBSELECT\fR(7)\&.
+.SH "NOTES"
+.PP
+\fBCREATE TABLE AS\fR
+is functionally similar to
+\fBSELECT INTO\fR\&.
+\fBCREATE TABLE AS\fR
+is the recommended syntax, since this form of
+\fBSELECT INTO\fR
+is not available in
+ECPG
+or
+PL/pgSQL, because they interpret the
+INTO
+clause differently\&. Furthermore,
+\fBCREATE TABLE AS\fR
+offers a superset of the functionality provided by
+\fBSELECT INTO\fR\&.
+.PP
+In contrast to
+\fBCREATE TABLE AS\fR,
+\fBSELECT INTO\fR
+does not allow specifying properties like a table\*(Aqs access method with
+USING \fImethod\fR
+or the table\*(Aqs tablespace with
+TABLESPACE \fItablespace_name\fR\&. Use
+\fBCREATE TABLE AS\fR
+if necessary\&. Therefore, the default table access method is chosen for the new table\&. See
+default_table_access_method
+for more information\&.
+.SH "EXAMPLES"
+.PP
+Create a new table
+films_recent
+consisting of only recent entries from the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * INTO films_recent FROM films WHERE date_prod >= \*(Aq2002\-01\-01\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The SQL standard uses
+\fBSELECT INTO\fR
+to represent selecting values into scalar variables of a host program, rather than creating a new table\&. This indeed is the usage found in
+ECPG
+(see
+Chapter\ \&36) and
+PL/pgSQL
+(see
+Chapter\ \&43)\&. The
+PostgreSQL
+usage of
+\fBSELECT INTO\fR
+to represent table creation is historical\&. Some other SQL implementations also use
+\fBSELECT INTO\fR
+in this way (but most SQL implementations support
+\fBCREATE TABLE AS\fR
+instead)\&. Apart from such compatibility considerations, it is best to use
+\fBCREATE TABLE AS\fR
+for this purpose in new code\&.
+.SH "SEE ALSO"
+CREATE TABLE AS (\fBCREATE_TABLE_AS\fR(7))
diff --git a/doc/src/sgml/man7/SET.7 b/doc/src/sgml/man7/SET.7
new file mode 100644
index 0000000..5dbdefc
--- /dev/null
+++ b/doc/src/sgml/man7/SET.7
@@ -0,0 +1,308 @@
+'\" t
+.\" Title: SET
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SET" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SET \- change a run\-time parameter
+.SH "SYNOPSIS"
+.sp
+.nf
+SET [ SESSION | LOCAL ] \fIconfiguration_parameter\fR { TO | = } { \fIvalue\fR | \*(Aq\fIvalue\fR\*(Aq | DEFAULT }
+SET [ SESSION | LOCAL ] TIME ZONE { \fIvalue\fR | \*(Aq\fIvalue\fR\*(Aq | LOCAL | DEFAULT }
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBSET\fR
+command changes run\-time configuration parameters\&. Many of the run\-time parameters listed in
+Chapter\ \&20
+can be changed on\-the\-fly with
+\fBSET\fR\&. (Some parameters can only be changed by superusers and users who have been granted
+SET
+privilege on that parameter\&. There are also parameters that cannot be changed after server or session start\&.)
+\fBSET\fR
+only affects the value used by the current session\&.
+.PP
+If
+\fBSET\fR
+(or equivalently
+\fBSET SESSION\fR) is issued within a transaction that is later aborted, the effects of the
+\fBSET\fR
+command disappear when the transaction is rolled back\&. Once the surrounding transaction is committed, the effects will persist until the end of the session, unless overridden by another
+\fBSET\fR\&.
+.PP
+The effects of
+\fBSET LOCAL\fR
+last only till the end of the current transaction, whether committed or not\&. A special case is
+\fBSET\fR
+followed by
+\fBSET LOCAL\fR
+within a single transaction: the
+\fBSET LOCAL\fR
+value will be seen until the end of the transaction, but afterwards (if the transaction is committed) the
+\fBSET\fR
+value will take effect\&.
+.PP
+The effects of
+\fBSET\fR
+or
+\fBSET LOCAL\fR
+are also canceled by rolling back to a savepoint that is earlier than the command\&.
+.PP
+If
+\fBSET LOCAL\fR
+is used within a function that has a
+SET
+option for the same variable (see
+CREATE FUNCTION (\fBCREATE_FUNCTION\fR(7))), the effects of the
+\fBSET LOCAL\fR
+command disappear at function exit; that is, the value in effect when the function was called is restored anyway\&. This allows
+\fBSET LOCAL\fR
+to be used for dynamic or repeated changes of a parameter within a function, while still having the convenience of using the
+SET
+option to save and restore the caller\*(Aqs value\&. However, a regular
+\fBSET\fR
+command overrides any surrounding function\*(Aqs
+SET
+option; its effects will persist unless rolled back\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.PP
+In
+PostgreSQL
+versions 8\&.0 through 8\&.2, the effects of a
+\fBSET LOCAL\fR
+would be canceled by releasing an earlier savepoint, or by successful exit from a
+PL/pgSQL
+exception block\&. This behavior has been changed because it was deemed unintuitive\&.
+.sp .5v
+.RE
+.SH "PARAMETERS"
+.PP
+SESSION
+.RS 4
+Specifies that the command takes effect for the current session\&. (This is the default if neither
+SESSION
+nor
+LOCAL
+appears\&.)
+.RE
+.PP
+LOCAL
+.RS 4
+Specifies that the command takes effect for only the current transaction\&. After
+\fBCOMMIT\fR
+or
+\fBROLLBACK\fR, the session\-level setting takes effect again\&. Issuing this outside of a transaction block emits a warning and otherwise has no effect\&.
+.RE
+.PP
+\fIconfiguration_parameter\fR
+.RS 4
+Name of a settable run\-time parameter\&. Available parameters are documented in
+Chapter\ \&20
+and below\&.
+.RE
+.PP
+\fIvalue\fR
+.RS 4
+New value of parameter\&. Values can be specified as string constants, identifiers, numbers, or comma\-separated lists of these, as appropriate for the particular parameter\&.
+DEFAULT
+can be written to specify resetting the parameter to its default value (that is, whatever value it would have had if no
+\fBSET\fR
+had been executed in the current session)\&.
+.RE
+.PP
+Besides the configuration parameters documented in
+Chapter\ \&20, there are a few that can only be adjusted using the
+\fBSET\fR
+command or that have a special syntax:
+.PP
+SCHEMA
+.RS 4
+SET SCHEMA \*(Aq\fIvalue\fR\*(Aq
+is an alias for
+SET search_path TO \fIvalue\fR\&. Only one schema can be specified using this syntax\&.
+.RE
+.PP
+NAMES
+.RS 4
+SET NAMES \fIvalue\fR
+is an alias for
+SET client_encoding TO \fIvalue\fR\&.
+.RE
+.PP
+SEED
+.RS 4
+Sets the internal seed for the random number generator (the function
+\fBrandom\fR)\&. Allowed values are floating\-point numbers between \-1 and 1 inclusive\&.
+.sp
+The seed can also be set by invoking the function
+\fBsetseed\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT setseed(\fIvalue\fR);
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+TIME ZONE
+.RS 4
+SET TIME ZONE \*(Aq\fIvalue\fR\*(Aq
+is an alias for
+SET timezone TO \*(Aq\fIvalue\fR\*(Aq\&. The syntax
+SET TIME ZONE
+allows special syntax for the time zone specification\&. Here are examples of valid values:
+.PP
+\*(AqPST8PDT\*(Aq
+.RS 4
+The time zone for Berkeley, California\&.
+.RE
+.PP
+\*(AqEurope/Rome\*(Aq
+.RS 4
+The time zone for Italy\&.
+.RE
+.PP
+\-7
+.RS 4
+The time zone 7 hours west from UTC (equivalent to PDT)\&. Positive values are east from UTC\&.
+.RE
+.PP
+INTERVAL \*(Aq\-08:00\*(Aq HOUR TO MINUTE
+.RS 4
+The time zone 8 hours west from UTC (equivalent to PST)\&.
+.RE
+.PP
+LOCAL
+.br
+DEFAULT
+.RS 4
+Set the time zone to your local time zone (that is, the server\*(Aqs default value of
+\fItimezone\fR)\&.
+.RE
+.sp
+Timezone settings given as numbers or intervals are internally translated to POSIX timezone syntax\&. For example, after
+SET TIME ZONE \-7,
+\fBSHOW TIME ZONE\fR
+would report
+<\-07>+07\&.
+.sp
+Time zone abbreviations are not supported by
+\fBSET\fR; see
+Section\ \&8.5.3
+for more information about time zones\&.
+.RE
+.SH "NOTES"
+.PP
+The function
+\fBset_config\fR
+provides equivalent functionality; see
+Section\ \&9.27.1\&. Also, it is possible to UPDATE the
+pg_settings
+system view to perform the equivalent of
+\fBSET\fR\&.
+.SH "EXAMPLES"
+.PP
+Set the schema search path:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SET search_path TO my_schema, public;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Set the style of date to traditional
+POSTGRES
+with
+\(lqday before month\(rq
+input convention:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SET datestyle TO postgres, dmy;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Set the time zone for Berkeley, California:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SET TIME ZONE \*(AqPST8PDT\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Set the time zone for Italy:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SET TIME ZONE \*(AqEurope/Rome\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+SET TIME ZONE
+extends syntax defined in the SQL standard\&. The standard allows only numeric time zone offsets while
+PostgreSQL
+allows more flexible time\-zone specifications\&. All other
+SET
+features are
+PostgreSQL
+extensions\&.
+.SH "SEE ALSO"
+\fBRESET\fR(7), \fBSHOW\fR(7)
diff --git a/doc/src/sgml/man7/SET_CONSTRAINTS.7 b/doc/src/sgml/man7/SET_CONSTRAINTS.7
new file mode 100644
index 0000000..6fffa54
--- /dev/null
+++ b/doc/src/sgml/man7/SET_CONSTRAINTS.7
@@ -0,0 +1,114 @@
+'\" t
+.\" Title: SET CONSTRAINTS
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SET CONSTRAINTS" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SET_CONSTRAINTS \- set constraint check timing for the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+SET CONSTRAINTS { ALL | \fIname\fR [, \&.\&.\&.] } { DEFERRED | IMMEDIATE }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSET CONSTRAINTS\fR
+sets the behavior of constraint checking within the current transaction\&.
+IMMEDIATE
+constraints are checked at the end of each statement\&.
+DEFERRED
+constraints are not checked until transaction commit\&. Each constraint has its own
+IMMEDIATE
+or
+DEFERRED
+mode\&.
+.PP
+Upon creation, a constraint is given one of three characteristics:
+DEFERRABLE INITIALLY DEFERRED,
+DEFERRABLE INITIALLY IMMEDIATE, or
+NOT DEFERRABLE\&. The third class is always
+IMMEDIATE
+and is not affected by the
+\fBSET CONSTRAINTS\fR
+command\&. The first two classes start every transaction in the indicated mode, but their behavior can be changed within a transaction by
+\fBSET CONSTRAINTS\fR\&.
+.PP
+\fBSET CONSTRAINTS\fR
+with a list of constraint names changes the mode of just those constraints (which must all be deferrable)\&. Each constraint name can be schema\-qualified\&. The current schema search path is used to find the first matching name if no schema name is specified\&.
+\fBSET CONSTRAINTS ALL\fR
+changes the mode of all deferrable constraints\&.
+.PP
+When
+\fBSET CONSTRAINTS\fR
+changes the mode of a constraint from
+DEFERRED
+to
+IMMEDIATE, the new mode takes effect retroactively: any outstanding data modifications that would have been checked at the end of the transaction are instead checked during the execution of the
+\fBSET CONSTRAINTS\fR
+command\&. If any such constraint is violated, the
+\fBSET CONSTRAINTS\fR
+fails (and does not change the constraint mode)\&. Thus,
+\fBSET CONSTRAINTS\fR
+can be used to force checking of constraints to occur at a specific point in a transaction\&.
+.PP
+Currently, only
+UNIQUE,
+PRIMARY KEY,
+REFERENCES
+(foreign key), and
+EXCLUDE
+constraints are affected by this setting\&.
+NOT NULL
+and
+CHECK
+constraints are always checked immediately when a row is inserted or modified (\fInot\fR
+at the end of the statement)\&. Uniqueness and exclusion constraints that have not been declared
+DEFERRABLE
+are also checked immediately\&.
+.PP
+The firing of triggers that are declared as
+\(lqconstraint triggers\(rq
+is also controlled by this setting \(em they fire at the same time that the associated constraint should be checked\&.
+.SH "NOTES"
+.PP
+Because
+PostgreSQL
+does not require constraint names to be unique within a schema (but only per\-table), it is possible that there is more than one match for a specified constraint name\&. In this case
+\fBSET CONSTRAINTS\fR
+will act on all matches\&. For a non\-schema\-qualified name, once a match or matches have been found in some schema in the search path, schemas appearing later in the path are not searched\&.
+.PP
+This command only alters the behavior of constraints within the current transaction\&. Issuing this outside of a transaction block emits a warning and otherwise has no effect\&.
+.SH "COMPATIBILITY"
+.PP
+This command complies with the behavior defined in the SQL standard, except for the limitation that, in
+PostgreSQL, it does not apply to
+NOT NULL
+and
+CHECK
+constraints\&. Also,
+PostgreSQL
+checks non\-deferrable uniqueness constraints immediately, not at end of statement as the standard would suggest\&.
diff --git a/doc/src/sgml/man7/SET_ROLE.7 b/doc/src/sgml/man7/SET_ROLE.7
new file mode 100644
index 0000000..c9a2c2b
--- /dev/null
+++ b/doc/src/sgml/man7/SET_ROLE.7
@@ -0,0 +1,143 @@
+'\" t
+.\" Title: SET ROLE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SET ROLE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SET_ROLE \- set the current user identifier of the current session
+.SH "SYNOPSIS"
+.sp
+.nf
+SET [ SESSION | LOCAL ] ROLE \fIrole_name\fR
+SET [ SESSION | LOCAL ] ROLE NONE
+RESET ROLE
+.fi
+.SH "DESCRIPTION"
+.PP
+This command sets the current user identifier of the current SQL session to be
+\fIrole_name\fR\&. The role name can be written as either an identifier or a string literal\&. After
+\fBSET ROLE\fR, permissions checking for SQL commands is carried out as though the named role were the one that had logged in originally\&.
+.PP
+The specified
+\fIrole_name\fR
+must be a role that the current session user is a member of\&. (If the session user is a superuser, any role can be selected\&.)
+.PP
+The
+SESSION
+and
+LOCAL
+modifiers act the same as for the regular
+\fBSET\fR
+command\&.
+.PP
+SET ROLE NONE
+sets the current user identifier to the current session user identifier, as returned by
+\fBsession_user\fR\&.
+RESET ROLE
+sets the current user identifier to the connection\-time setting specified by the
+command\-line options,
+\fBALTER ROLE\fR, or
+\fBALTER DATABASE\fR, if any such settings exist\&. Otherwise,
+RESET ROLE
+sets the current user identifier to the current session user identifier\&. These forms can be executed by any user\&.
+.SH "NOTES"
+.PP
+Using this command, it is possible to either add privileges or restrict one\*(Aqs privileges\&. If the session user role has the
+INHERIT
+attribute, then it automatically has all the privileges of every role that it could
+\fBSET ROLE\fR
+to; in this case
+\fBSET ROLE\fR
+effectively drops all the privileges assigned directly to the session user and to the other roles it is a member of, leaving only the privileges available to the named role\&. On the other hand, if the session user role has the
+NOINHERIT
+attribute,
+\fBSET ROLE\fR
+drops the privileges assigned directly to the session user and instead acquires the privileges available to the named role\&.
+.PP
+In particular, when a superuser chooses to
+\fBSET ROLE\fR
+to a non\-superuser role, they lose their superuser privileges\&.
+.PP
+\fBSET ROLE\fR
+has effects comparable to
+\fBSET SESSION AUTHORIZATION\fR, but the privilege checks involved are quite different\&. Also,
+\fBSET SESSION AUTHORIZATION\fR
+determines which roles are allowable for later
+\fBSET ROLE\fR
+commands, whereas changing roles with
+\fBSET ROLE\fR
+does not change the set of roles allowed to a later
+\fBSET ROLE\fR\&.
+.PP
+\fBSET ROLE\fR
+does not process session variables as specified by the role\*(Aqs
+\fBALTER ROLE\fR
+settings; this only happens during login\&.
+.PP
+\fBSET ROLE\fR
+cannot be used within a
+SECURITY DEFINER
+function\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ peter | peter
+
+SET ROLE \*(Aqpaul\*(Aq;
+
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ peter | paul
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+PostgreSQL
+allows identifier syntax ("\fIrolename\fR"), while the SQL standard requires the role name to be written as a string literal\&. SQL does not allow this command during a transaction;
+PostgreSQL
+does not make this restriction because there is no reason to\&. The
+SESSION
+and
+LOCAL
+modifiers are a
+PostgreSQL
+extension, as is the
+RESET
+syntax\&.
+.SH "SEE ALSO"
+SET SESSION AUTHORIZATION (\fBSET_SESSION_AUTHORIZATION\fR(7))
diff --git a/doc/src/sgml/man7/SET_SESSION_AUTHORIZATION.7 b/doc/src/sgml/man7/SET_SESSION_AUTHORIZATION.7
new file mode 100644
index 0000000..860eaa0
--- /dev/null
+++ b/doc/src/sgml/man7/SET_SESSION_AUTHORIZATION.7
@@ -0,0 +1,113 @@
+'\" t
+.\" Title: SET SESSION AUTHORIZATION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SET SESSION AUTHORIZATION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SET_SESSION_AUTHORIZATION \- set the session user identifier and the current user identifier of the current session
+.SH "SYNOPSIS"
+.sp
+.nf
+SET [ SESSION | LOCAL ] SESSION AUTHORIZATION \fIuser_name\fR
+SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT
+RESET SESSION AUTHORIZATION
+.fi
+.SH "DESCRIPTION"
+.PP
+This command sets the session user identifier and the current user identifier of the current SQL session to be
+\fIuser_name\fR\&. The user name can be written as either an identifier or a string literal\&. Using this command, it is possible, for example, to temporarily become an unprivileged user and later switch back to being a superuser\&.
+.PP
+The session user identifier is initially set to be the (possibly authenticated) user name provided by the client\&. The current user identifier is normally equal to the session user identifier, but might change temporarily in the context of
+SECURITY DEFINER
+functions and similar mechanisms; it can also be changed by
+\fBSET ROLE\fR\&. The current user identifier is relevant for permission checking\&.
+.PP
+The session user identifier can be changed only if the initial session user (the
+authenticated user) had the superuser privilege\&. Otherwise, the command is accepted only if it specifies the authenticated user name\&.
+.PP
+The
+SESSION
+and
+LOCAL
+modifiers act the same as for the regular
+\fBSET\fR
+command\&.
+.PP
+The
+DEFAULT
+and
+RESET
+forms reset the session and current user identifiers to be the originally authenticated user name\&. These forms can be executed by any user\&.
+.SH "NOTES"
+.PP
+\fBSET SESSION AUTHORIZATION\fR
+cannot be used within a
+SECURITY DEFINER
+function\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ peter | peter
+
+SET SESSION AUTHORIZATION \*(Aqpaul\*(Aq;
+
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ paul | paul
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The SQL standard allows some other expressions to appear in place of the literal
+\fIuser_name\fR, but these options are not important in practice\&.
+PostgreSQL
+allows identifier syntax ("\fIusername\fR"), which SQL does not\&. SQL does not allow this command during a transaction;
+PostgreSQL
+does not make this restriction because there is no reason to\&. The
+SESSION
+and
+LOCAL
+modifiers are a
+PostgreSQL
+extension, as is the
+RESET
+syntax\&.
+.PP
+The privileges necessary to execute this command are left implementation\-defined by the standard\&.
+.SH "SEE ALSO"
+SET ROLE (\fBSET_ROLE\fR(7))
diff --git a/doc/src/sgml/man7/SET_TRANSACTION.7 b/doc/src/sgml/man7/SET_TRANSACTION.7
new file mode 100644
index 0000000..3fc4561
--- /dev/null
+++ b/doc/src/sgml/man7/SET_TRANSACTION.7
@@ -0,0 +1,242 @@
+'\" t
+.\" Title: SET TRANSACTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SET TRANSACTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SET_TRANSACTION \- set the characteristics of the current transaction
+.SH "SYNOPSIS"
+.sp
+.nf
+SET TRANSACTION \fItransaction_mode\fR [, \&.\&.\&.]
+SET TRANSACTION SNAPSHOT \fIsnapshot_id\fR
+SET SESSION CHARACTERISTICS AS TRANSACTION \fItransaction_mode\fR [, \&.\&.\&.]
+
+where \fItransaction_mode\fR is one of:
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+.fi
+.SH "DESCRIPTION"
+.PP
+The
+\fBSET TRANSACTION\fR
+command sets the characteristics of the current transaction\&. It has no effect on any subsequent transactions\&.
+\fBSET SESSION CHARACTERISTICS\fR
+sets the default transaction characteristics for subsequent transactions of a session\&. These defaults can be overridden by
+\fBSET TRANSACTION\fR
+for an individual transaction\&.
+.PP
+The available transaction characteristics are the transaction isolation level, the transaction access mode (read/write or read\-only), and the deferrable mode\&. In addition, a snapshot can be selected, though only for the current transaction, not as a session default\&.
+.PP
+The isolation level of a transaction determines what data the transaction can see when other transactions are running concurrently:
+.PP
+READ COMMITTED
+.RS 4
+A statement can only see rows committed before it began\&. This is the default\&.
+.RE
+.PP
+REPEATABLE READ
+.RS 4
+All statements of the current transaction can only see rows committed before the first query or data\-modification statement was executed in this transaction\&.
+.RE
+.PP
+SERIALIZABLE
+.RS 4
+All statements of the current transaction can only see rows committed before the first query or data\-modification statement was executed in this transaction\&. If a pattern of reads and writes among concurrent serializable transactions would create a situation which could not have occurred for any serial (one\-at\-a\-time) execution of those transactions, one of them will be rolled back with a
+serialization_failure
+error\&.
+.RE
+The SQL standard defines one additional level,
+READ UNCOMMITTED\&. In
+PostgreSQL
+READ UNCOMMITTED
+is treated as
+READ COMMITTED\&.
+.PP
+The transaction isolation level cannot be changed after the first query or data\-modification statement (\fBSELECT\fR,
+\fBINSERT\fR,
+\fBDELETE\fR,
+\fBUPDATE\fR,
+\fBMERGE\fR,
+\fBFETCH\fR, or
+\fBCOPY\fR) of a transaction has been executed\&. See
+Chapter\ \&13
+for more information about transaction isolation and concurrency control\&.
+.PP
+The transaction access mode determines whether the transaction is read/write or read\-only\&. Read/write is the default\&. When a transaction is read\-only, the following SQL commands are disallowed:
+\fBINSERT\fR,
+\fBUPDATE\fR,
+\fBDELETE\fR,
+\fBMERGE\fR, and
+\fBCOPY FROM\fR
+if the table they would write to is not a temporary table; all
+CREATE,
+ALTER, and
+DROP
+commands;
+COMMENT,
+GRANT,
+REVOKE,
+TRUNCATE; and
+EXPLAIN ANALYZE
+and
+EXECUTE
+if the command they would execute is among those listed\&. This is a high\-level notion of read\-only that does not prevent all writes to disk\&.
+.PP
+The
+DEFERRABLE
+transaction property has no effect unless the transaction is also
+SERIALIZABLE
+and
+READ ONLY\&. When all three of these properties are selected for a transaction, the transaction may block when first acquiring its snapshot, after which it is able to run without the normal overhead of a
+SERIALIZABLE
+transaction and without any risk of contributing to or being canceled by a serialization failure\&. This mode is well suited for long\-running reports or backups\&.
+.PP
+The
+SET TRANSACTION SNAPSHOT
+command allows a new transaction to run with the same
+snapshot
+as an existing transaction\&. The pre\-existing transaction must have exported its snapshot with the
+pg_export_snapshot
+function (see
+Section\ \&9.27.5)\&. That function returns a snapshot identifier, which must be given to
+SET TRANSACTION SNAPSHOT
+to specify which snapshot is to be imported\&. The identifier must be written as a string literal in this command, for example
+\*(Aq00000003\-0000001B\-1\*(Aq\&.
+SET TRANSACTION SNAPSHOT
+can only be executed at the start of a transaction, before the first query or data\-modification statement (\fBSELECT\fR,
+\fBINSERT\fR,
+\fBDELETE\fR,
+\fBUPDATE\fR,
+\fBMERGE\fR,
+\fBFETCH\fR, or
+\fBCOPY\fR) of the transaction\&. Furthermore, the transaction must already be set to
+SERIALIZABLE
+or
+REPEATABLE READ
+isolation level (otherwise, the snapshot would be discarded immediately, since
+READ COMMITTED
+mode takes a new snapshot for each command)\&. If the importing transaction uses
+SERIALIZABLE
+isolation level, then the transaction that exported the snapshot must also use that isolation level\&. Also, a non\-read\-only serializable transaction cannot import a snapshot from a read\-only transaction\&.
+.SH "NOTES"
+.PP
+If
+\fBSET TRANSACTION\fR
+is executed without a prior
+\fBSTART TRANSACTION\fR
+or
+\fBBEGIN\fR, it emits a warning and otherwise has no effect\&.
+.PP
+It is possible to dispense with
+\fBSET TRANSACTION\fR
+by instead specifying the desired
+\fItransaction_modes\fR
+in
+\fBBEGIN\fR
+or
+\fBSTART TRANSACTION\fR\&. But that option is not available for
+\fBSET TRANSACTION SNAPSHOT\fR\&.
+.PP
+The session default transaction modes can also be set or examined via the configuration parameters
+default_transaction_isolation,
+default_transaction_read_only, and
+default_transaction_deferrable\&. (In fact
+\fBSET SESSION CHARACTERISTICS\fR
+is just a verbose equivalent for setting these variables with
+\fBSET\fR\&.) This means the defaults can be set in the configuration file, via
+\fBALTER DATABASE\fR, etc\&. Consult
+Chapter\ \&20
+for more information\&.
+.PP
+The current transaction\*(Aqs modes can similarly be set or examined via the configuration parameters
+transaction_isolation,
+transaction_read_only, and
+transaction_deferrable\&. Setting one of these parameters acts the same as the corresponding
+\fBSET TRANSACTION\fR
+option, with the same restrictions on when it can be done\&. However, these parameters cannot be set in the configuration file, or from any source other than live SQL\&.
+.SH "EXAMPLES"
+.PP
+To begin a new transaction with the same snapshot as an already existing transaction, first export the snapshot from the existing transaction\&. That will return the snapshot identifier, for example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SELECT pg_export_snapshot();
+ pg_export_snapshot
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ 00000003\-0000001B\-1
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Then give the snapshot identifier in a
+\fBSET TRANSACTION SNAPSHOT\fR
+command at the beginning of the newly opened transaction:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SET TRANSACTION SNAPSHOT \*(Aq00000003\-0000001B\-1\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+These commands are defined in the
+SQL
+standard, except for the
+DEFERRABLE
+transaction mode and the
+\fBSET TRANSACTION SNAPSHOT\fR
+form, which are
+PostgreSQL
+extensions\&.
+.PP
+SERIALIZABLE
+is the default transaction isolation level in the standard\&. In
+PostgreSQL
+the default is ordinarily
+READ COMMITTED, but you can change it as mentioned above\&.
+.PP
+In the SQL standard, there is one other transaction characteristic that can be set with these commands: the size of the diagnostics area\&. This concept is specific to embedded SQL, and therefore is not implemented in the
+PostgreSQL
+server\&.
+.PP
+The SQL standard requires commas between successive
+\fItransaction_modes\fR, but for historical reasons
+PostgreSQL
+allows the commas to be omitted\&.
diff --git a/doc/src/sgml/man7/SHOW.7 b/doc/src/sgml/man7/SHOW.7
new file mode 100644
index 0000000..89865a6
--- /dev/null
+++ b/doc/src/sgml/man7/SHOW.7
@@ -0,0 +1,167 @@
+'\" t
+.\" Title: SHOW
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "SHOW" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+SHOW \- show the value of a run\-time parameter
+.SH "SYNOPSIS"
+.sp
+.nf
+SHOW \fIname\fR
+SHOW ALL
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBSHOW\fR
+will display the current setting of run\-time parameters\&. These variables can be set using the
+\fBSET\fR
+statement, by editing the
+postgresql\&.conf
+configuration file, through the
+\fBPGOPTIONS\fR
+environmental variable (when using
+libpq
+or a
+libpq\-based application), or through command\-line flags when starting the
+\fBpostgres\fR
+server\&. See
+Chapter\ \&20
+for details\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name of a run\-time parameter\&. Available parameters are documented in
+Chapter\ \&20
+and on the
+\fBSET\fR(7)
+reference page\&. In addition, there are a few parameters that can be shown but not set:
+.PP
+SERVER_VERSION
+.RS 4
+Shows the server\*(Aqs version number\&.
+.RE
+.PP
+SERVER_ENCODING
+.RS 4
+Shows the server\-side character set encoding\&. At present, this parameter can be shown but not set, because the encoding is determined at database creation time\&.
+.RE
+.PP
+LC_COLLATE
+.RS 4
+Shows the database\*(Aqs locale setting for collation (text ordering)\&. At present, this parameter can be shown but not set, because the setting is determined at database creation time\&.
+.RE
+.PP
+LC_CTYPE
+.RS 4
+Shows the database\*(Aqs locale setting for character classification\&. At present, this parameter can be shown but not set, because the setting is determined at database creation time\&.
+.RE
+.PP
+IS_SUPERUSER
+.RS 4
+True if the current role has superuser privileges\&.
+.RE
+.RE
+.PP
+ALL
+.RS 4
+Show the values of all configuration parameters, with descriptions\&.
+.RE
+.SH "NOTES"
+.PP
+The function
+\fBcurrent_setting\fR
+produces equivalent output; see
+Section\ \&9.27.1\&. Also, the
+pg_settings
+system view produces the same information\&.
+.SH "EXAMPLES"
+.PP
+Show the current setting of the parameter
+\fIDateStyle\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SHOW DateStyle;
+ DateStyle
+\-\-\-\-\-\-\-\-\-\-\-
+ ISO, MDY
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Show the current setting of the parameter
+\fIgeqo\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SHOW geqo;
+ geqo
+\-\-\-\-\-\-
+ on
+(1 row)
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Show all settings:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SHOW ALL;
+ name | setting | description
+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
+ allow_system_table_mods | off | Allows modifications of the structure of \&.\&.\&.
+ \&.
+ \&.
+ \&.
+ xmloption | content | Sets whether XML data in implicit parsing \&.\&.\&.
+ zero_damaged_pages | off | Continues processing past damaged page headers\&.
+(196 rows)
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The
+\fBSHOW\fR
+command is a
+PostgreSQL
+extension\&.
+.SH "SEE ALSO"
+\fBSET\fR(7), \fBRESET\fR(7)
diff --git a/doc/src/sgml/man7/START_TRANSACTION.7 b/doc/src/sgml/man7/START_TRANSACTION.7
new file mode 100644
index 0000000..d55855c
--- /dev/null
+++ b/doc/src/sgml/man7/START_TRANSACTION.7
@@ -0,0 +1,83 @@
+'\" t
+.\" Title: START TRANSACTION
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "START TRANSACTION" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+START_TRANSACTION \- start a transaction block
+.SH "SYNOPSIS"
+.sp
+.nf
+START TRANSACTION [ \fItransaction_mode\fR [, \&.\&.\&.] ]
+
+where \fItransaction_mode\fR is one of:
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+.fi
+.SH "DESCRIPTION"
+.PP
+This command begins a new transaction block\&. If the isolation level, read/write mode, or deferrable mode is specified, the new transaction has those characteristics, as if
+\fBSET TRANSACTION\fR
+was executed\&. This is the same as the
+\fBBEGIN\fR
+command\&.
+.SH "PARAMETERS"
+.PP
+Refer to
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))
+for information on the meaning of the parameters to this statement\&.
+.SH "COMPATIBILITY"
+.PP
+In the standard, it is not necessary to issue
+\fBSTART TRANSACTION\fR
+to start a transaction block: any SQL command implicitly begins a block\&.
+PostgreSQL\*(Aqs behavior can be seen as implicitly issuing a
+\fBCOMMIT\fR
+after each command that does not follow
+\fBSTART TRANSACTION\fR
+(or
+\fBBEGIN\fR), and it is therefore often called
+\(lqautocommit\(rq\&. Other relational database systems might offer an autocommit feature as a convenience\&.
+.PP
+The
+DEFERRABLE
+\fItransaction_mode\fR
+is a
+PostgreSQL
+language extension\&.
+.PP
+The SQL standard requires commas between successive
+\fItransaction_modes\fR, but for historical reasons
+PostgreSQL
+allows the commas to be omitted\&.
+.PP
+See also the compatibility section of
+SET TRANSACTION (\fBSET_TRANSACTION\fR(7))\&.
+.SH "SEE ALSO"
+\fBBEGIN\fR(7), \fBCOMMIT\fR(7), \fBROLLBACK\fR(7), \fBSAVEPOINT\fR(7), SET TRANSACTION (\fBSET_TRANSACTION\fR(7))
diff --git a/doc/src/sgml/man7/TABLE.7 b/doc/src/sgml/man7/TABLE.7
new file mode 100644
index 0000000..8e9105d
--- /dev/null
+++ b/doc/src/sgml/man7/TABLE.7
@@ -0,0 +1 @@
+.so man7/SELECT.7
diff --git a/doc/src/sgml/man7/TRUNCATE.7 b/doc/src/sgml/man7/TRUNCATE.7
new file mode 100644
index 0000000..0b2c853
--- /dev/null
+++ b/doc/src/sgml/man7/TRUNCATE.7
@@ -0,0 +1,186 @@
+'\" t
+.\" Title: TRUNCATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "TRUNCATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+TRUNCATE \- empty a table or set of tables
+.SH "SYNOPSIS"
+.sp
+.nf
+TRUNCATE [ TABLE ] [ ONLY ] \fIname\fR [ * ] [, \&.\&.\&. ]
+ [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBTRUNCATE\fR
+quickly removes all rows from a set of tables\&. It has the same effect as an unqualified
+\fBDELETE\fR
+on each table, but since it does not actually scan the tables it is faster\&. Furthermore, it reclaims disk space immediately, rather than requiring a subsequent
+\fBVACUUM\fR
+operation\&. This is most useful on large tables\&.
+.SH "PARAMETERS"
+.PP
+\fIname\fR
+.RS 4
+The name (optionally schema\-qualified) of a table to truncate\&. If
+ONLY
+is specified before the table name, only that table is truncated\&. If
+ONLY
+is not specified, the table and all its descendant tables (if any) are truncated\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+RESTART IDENTITY
+.RS 4
+Automatically restart sequences owned by columns of the truncated table(s)\&.
+.RE
+.PP
+CONTINUE IDENTITY
+.RS 4
+Do not change the values of sequences\&. This is the default\&.
+.RE
+.PP
+CASCADE
+.RS 4
+Automatically truncate all tables that have foreign\-key references to any of the named tables, or to any tables added to the group due to
+CASCADE\&.
+.RE
+.PP
+RESTRICT
+.RS 4
+Refuse to truncate if any of the tables have foreign\-key references from tables that are not listed in the command\&. This is the default\&.
+.RE
+.SH "NOTES"
+.PP
+You must have the
+TRUNCATE
+privilege on a table to truncate it\&.
+.PP
+\fBTRUNCATE\fR
+acquires an
+ACCESS EXCLUSIVE
+lock on each table it operates on, which blocks all other concurrent operations on the table\&. When
+RESTART IDENTITY
+is specified, any sequences that are to be restarted are likewise locked exclusively\&. If concurrent access to a table is required, then the
+\fBDELETE\fR
+command should be used instead\&.
+.PP
+\fBTRUNCATE\fR
+cannot be used on a table that has foreign\-key references from other tables, unless all such tables are also truncated in the same command\&. Checking validity in such cases would require table scans, and the whole point is not to do one\&. The
+CASCADE
+option can be used to automatically include all dependent tables \(em but be very careful when using this option, or else you might lose data you did not intend to! Note in particular that when the table to be truncated is a partition, siblings partitions are left untouched, but cascading occurs to all referencing tables and all their partitions with no distinction\&.
+.PP
+\fBTRUNCATE\fR
+will not fire any
+ON DELETE
+triggers that might exist for the tables\&. But it will fire
+ON TRUNCATE
+triggers\&. If
+ON TRUNCATE
+triggers are defined for any of the tables, then all
+BEFORE TRUNCATE
+triggers are fired before any truncation happens, and all
+AFTER TRUNCATE
+triggers are fired after the last truncation is performed and any sequences are reset\&. The triggers will fire in the order that the tables are to be processed (first those listed in the command, and then any that were added due to cascading)\&.
+.PP
+\fBTRUNCATE\fR
+is not MVCC\-safe\&. After truncation, the table will appear empty to concurrent transactions, if they are using a snapshot taken before the truncation occurred\&. See
+Section\ \&13.6
+for more details\&.
+.PP
+\fBTRUNCATE\fR
+is transaction\-safe with respect to the data in the tables: the truncation will be safely rolled back if the surrounding transaction does not commit\&.
+.PP
+When
+RESTART IDENTITY
+is specified, the implied
+\fBALTER SEQUENCE RESTART\fR
+operations are also done transactionally; that is, they will be rolled back if the surrounding transaction does not commit\&. Be aware that if any additional sequence operations are done on the restarted sequences before the transaction rolls back, the effects of these operations on the sequences will be rolled back, but not their effects on
+\fBcurrval()\fR; that is, after the transaction
+\fBcurrval()\fR
+will continue to reflect the last sequence value obtained inside the failed transaction, even though the sequence itself may no longer be consistent with that\&. This is similar to the usual behavior of
+\fBcurrval()\fR
+after a failed transaction\&.
+.PP
+\fBTRUNCATE\fR
+can be used for foreign tables if supported by the foreign data wrapper, for instance, see
+postgres_fdw\&.
+.SH "EXAMPLES"
+.PP
+Truncate the tables
+bigtable
+and
+fattable:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+TRUNCATE bigtable, fattable;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+The same, and also reset any associated sequence generators:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+TRUNCATE bigtable, fattable RESTART IDENTITY;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Truncate the table
+othertable, and cascade to any tables that reference
+othertable
+via foreign\-key constraints:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+TRUNCATE othertable CASCADE;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+The SQL:2008 standard includes a
+\fBTRUNCATE\fR
+command with the syntax
+TRUNCATE TABLE \fItablename\fR\&. The clauses
+CONTINUE IDENTITY/RESTART IDENTITY
+also appear in that standard, but have slightly different though related meanings\&. Some of the concurrency behavior of this command is left implementation\-defined by the standard, so the above notes should be considered and compared with other implementations if necessary\&.
+.SH "SEE ALSO"
+\fBDELETE\fR(7)
diff --git a/doc/src/sgml/man7/UNLISTEN.7 b/doc/src/sgml/man7/UNLISTEN.7
new file mode 100644
index 0000000..b883fd9
--- /dev/null
+++ b/doc/src/sgml/man7/UNLISTEN.7
@@ -0,0 +1,117 @@
+'\" t
+.\" Title: UNLISTEN
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "UNLISTEN" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+UNLISTEN \- stop listening for a notification
+.SH "SYNOPSIS"
+.sp
+.nf
+UNLISTEN { \fIchannel\fR | * }
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBUNLISTEN\fR
+is used to remove an existing registration for
+\fBNOTIFY\fR
+events\&.
+\fBUNLISTEN\fR
+cancels any existing registration of the current
+PostgreSQL
+session as a listener on the notification channel named
+\fIchannel\fR\&. The special wildcard
+*
+cancels all listener registrations for the current session\&.
+.PP
+\fBNOTIFY\fR(7)
+contains a more extensive discussion of the use of
+\fBLISTEN\fR
+and
+\fBNOTIFY\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIchannel\fR
+.RS 4
+Name of a notification channel (any identifier)\&.
+.RE
+.PP
+*
+.RS 4
+All current listen registrations for this session are cleared\&.
+.RE
+.SH "NOTES"
+.PP
+You can unlisten something you were not listening for; no warning or error will appear\&.
+.PP
+At the end of each session,
+\fBUNLISTEN *\fR
+is automatically executed\&.
+.PP
+A transaction that has executed
+\fBUNLISTEN\fR
+cannot be prepared for two\-phase commit\&.
+.SH "EXAMPLES"
+.PP
+To make a registration:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448\&.
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Once
+\fBUNLISTEN\fR
+has been executed, further
+\fBNOTIFY\fR
+messages will be ignored:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UNLISTEN virtual;
+NOTIFY virtual;
+\-\- no NOTIFY event is received
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBUNLISTEN\fR
+command in the SQL standard\&.
+.SH "SEE ALSO"
+\fBLISTEN\fR(7), \fBNOTIFY\fR(7)
diff --git a/doc/src/sgml/man7/UPDATE.7 b/doc/src/sgml/man7/UPDATE.7
new file mode 100644
index 0000000..9a6a140
--- /dev/null
+++ b/doc/src/sgml/man7/UPDATE.7
@@ -0,0 +1,473 @@
+'\" t
+.\" Title: UPDATE
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "UPDATE" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+UPDATE \- update rows of a table
+.SH "SYNOPSIS"
+.sp
+.nf
+[ WITH [ RECURSIVE ] \fIwith_query\fR [, \&.\&.\&.] ]
+UPDATE [ ONLY ] \fItable_name\fR [ * ] [ [ AS ] \fIalias\fR ]
+ SET { \fIcolumn_name\fR = { \fIexpression\fR | DEFAULT } |
+ ( \fIcolumn_name\fR [, \&.\&.\&.] ) = [ ROW ] ( { \fIexpression\fR | DEFAULT } [, \&.\&.\&.] ) |
+ ( \fIcolumn_name\fR [, \&.\&.\&.] ) = ( \fIsub\-SELECT\fR )
+ } [, \&.\&.\&.]
+ [ FROM \fIfrom_item\fR [, \&.\&.\&.] ]
+ [ WHERE \fIcondition\fR | WHERE CURRENT OF \fIcursor_name\fR ]
+ [ RETURNING * | \fIoutput_expression\fR [ [ AS ] \fIoutput_name\fR ] [, \&.\&.\&.] ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBUPDATE\fR
+changes the values of the specified columns in all rows that satisfy the condition\&. Only the columns to be modified need be mentioned in the
+SET
+clause; columns not explicitly modified retain their previous values\&.
+.PP
+There are two ways to modify a table using information contained in other tables in the database: using sub\-selects, or specifying additional tables in the
+FROM
+clause\&. Which technique is more appropriate depends on the specific circumstances\&.
+.PP
+The optional
+RETURNING
+clause causes
+\fBUPDATE\fR
+to compute and return value(s) based on each row actually updated\&. Any expression using the table\*(Aqs columns, and/or columns of other tables mentioned in
+FROM, can be computed\&. The new (post\-update) values of the table\*(Aqs columns are used\&. The syntax of the
+RETURNING
+list is identical to that of the output list of
+\fBSELECT\fR\&.
+.PP
+You must have the
+UPDATE
+privilege on the table, or at least on the column(s) that are listed to be updated\&. You must also have the
+SELECT
+privilege on any column whose values are read in the
+\fIexpressions\fR
+or
+\fIcondition\fR\&.
+.SH "PARAMETERS"
+.PP
+\fIwith_query\fR
+.RS 4
+The
+WITH
+clause allows you to specify one or more subqueries that can be referenced by name in the
+\fBUPDATE\fR
+query\&. See
+Section\ \&7.8
+and
+\fBSELECT\fR(7)
+for details\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of the table to update\&. If
+ONLY
+is specified before the table name, matching rows are updated in the named table only\&. If
+ONLY
+is not specified, matching rows are also updated in any tables inheriting from the named table\&. Optionally,
+*
+can be specified after the table name to explicitly indicate that descendant tables are included\&.
+.RE
+.PP
+\fIalias\fR
+.RS 4
+A substitute name for the target table\&. When an alias is provided, it completely hides the actual name of the table\&. For example, given
+UPDATE foo AS f, the remainder of the
+\fBUPDATE\fR
+statement must refer to this table as
+f
+not
+foo\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a column in the table named by
+\fItable_name\fR\&. The column name can be qualified with a subfield name or array subscript, if needed\&. Do not include the table\*(Aqs name in the specification of a target column \(em for example,
+UPDATE table_name SET table_name\&.col = 1
+is invalid\&.
+.RE
+.PP
+\fIexpression\fR
+.RS 4
+An expression to assign to the column\&. The expression can use the old values of this and other columns in the table\&.
+.RE
+.PP
+DEFAULT
+.RS 4
+Set the column to its default value (which will be NULL if no specific default expression has been assigned to it)\&. An identity column will be set to a new value generated by the associated sequence\&. For a generated column, specifying this is permitted but merely specifies the normal behavior of computing the column from its generation expression\&.
+.RE
+.PP
+\fIsub\-SELECT\fR
+.RS 4
+A
+SELECT
+sub\-query that produces as many output columns as are listed in the parenthesized column list preceding it\&. The sub\-query must yield no more than one row when executed\&. If it yields one row, its column values are assigned to the target columns; if it yields no rows, NULL values are assigned to the target columns\&. The sub\-query can refer to old values of the current row of the table being updated\&.
+.RE
+.PP
+\fIfrom_item\fR
+.RS 4
+A table expression allowing columns from other tables to appear in the
+WHERE
+condition and update expressions\&. This uses the same syntax as the
+FROM
+clause of a
+\fBSELECT\fR
+statement; for example, an alias for the table name can be specified\&. Do not repeat the target table as a
+\fIfrom_item\fR
+unless you intend a self\-join (in which case it must appear with an alias in the
+\fIfrom_item\fR)\&.
+.RE
+.PP
+\fIcondition\fR
+.RS 4
+An expression that returns a value of type
+boolean\&. Only rows for which this expression returns
+true
+will be updated\&.
+.RE
+.PP
+\fIcursor_name\fR
+.RS 4
+The name of the cursor to use in a
+WHERE CURRENT OF
+condition\&. The row to be updated is the one most recently fetched from this cursor\&. The cursor must be a non\-grouping query on the
+\fBUPDATE\fR\*(Aqs target table\&. Note that
+WHERE CURRENT OF
+cannot be specified together with a Boolean condition\&. See
+\fBDECLARE\fR(7)
+for more information about using cursors with
+WHERE CURRENT OF\&.
+.RE
+.PP
+\fIoutput_expression\fR
+.RS 4
+An expression to be computed and returned by the
+\fBUPDATE\fR
+command after each row is updated\&. The expression can use any column names of the table named by
+\fItable_name\fR
+or table(s) listed in
+FROM\&. Write
+*
+to return all columns\&.
+.RE
+.PP
+\fIoutput_name\fR
+.RS 4
+A name to use for a returned column\&.
+.RE
+.SH "OUTPUTS"
+.PP
+On successful completion, an
+\fBUPDATE\fR
+command returns a command tag of the form
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE \fIcount\fR
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+The
+\fIcount\fR
+is the number of rows updated, including matched rows whose values did not change\&. Note that the number may be less than the number of rows that matched the
+\fIcondition\fR
+when updates were suppressed by a
+BEFORE UPDATE
+trigger\&. If
+\fIcount\fR
+is 0, no rows were updated by the query (this is not considered an error)\&.
+.PP
+If the
+\fBUPDATE\fR
+command contains a
+RETURNING
+clause, the result will be similar to that of a
+\fBSELECT\fR
+statement containing the columns and values defined in the
+RETURNING
+list, computed over the row(s) updated by the command\&.
+.SH "NOTES"
+.PP
+When a
+FROM
+clause is present, what essentially happens is that the target table is joined to the tables mentioned in the
+\fIfrom_item\fR
+list, and each output row of the join represents an update operation for the target table\&. When using
+FROM
+you should ensure that the join produces at most one output row for each row to be modified\&. In other words, a target row shouldn\*(Aqt join to more than one row from the other table(s)\&. If it does, then only one of the join rows will be used to update the target row, but which one will be used is not readily predictable\&.
+.PP
+Because of this indeterminacy, referencing other tables only within sub\-selects is safer, though often harder to read and slower than using a join\&.
+.PP
+In the case of a partitioned table, updating a row might cause it to no longer satisfy the partition constraint of the containing partition\&. In that case, if there is some other partition in the partition tree for which this row satisfies its partition constraint, then the row is moved to that partition\&. If there is no such partition, an error will occur\&. Behind the scenes, the row movement is actually a
+\fBDELETE\fR
+and
+\fBINSERT\fR
+operation\&.
+.PP
+There is a possibility that a concurrent
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+on the row being moved will get a serialization failure error\&. Suppose session 1 is performing an
+\fBUPDATE\fR
+on a partition key, and meanwhile a concurrent session 2 for which this row is visible performs an
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+operation on this row\&. In such case, session 2\*(Aqs
+\fBUPDATE\fR
+or
+\fBDELETE\fR
+will detect the row movement and raise a serialization failure error (which always returns with an SQLSTATE code \*(Aq40001\*(Aq)\&. Applications may wish to retry the transaction if this occurs\&. In the usual case where the table is not partitioned, or where there is no row movement, session 2 would have identified the newly updated row and carried out the
+\fBUPDATE\fR/\fBDELETE\fR
+on this new row version\&.
+.PP
+Note that while rows can be moved from local partitions to a foreign\-table partition (provided the foreign data wrapper supports tuple routing), they cannot be moved from a foreign\-table partition to another partition\&.
+.PP
+An attempt of moving a row from one partition to another will fail if a foreign key is found to directly reference an ancestor of the source partition that is not the same as the ancestor that\*(Aqs mentioned in the
+\fBUPDATE\fR
+query\&.
+.SH "EXAMPLES"
+.PP
+Change the word
+Drama
+to
+Dramatic
+in the column
+kind
+of the table
+films:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE films SET kind = \*(AqDramatic\*(Aq WHERE kind = \*(AqDrama\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Adjust temperature entries and reset precipitation to its default value in one row of the table
+weather:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
+ WHERE city = \*(AqSan Francisco\*(Aq AND date = \*(Aq2003\-07\-03\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Perform the same operation and return the updated entries:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
+ WHERE city = \*(AqSan Francisco\*(Aq AND date = \*(Aq2003\-07\-03\*(Aq
+ RETURNING temp_lo, temp_hi, prcp;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Use the alternative column\-list syntax to do the same update:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
+ WHERE city = \*(AqSan Francisco\*(Aq AND date = \*(Aq2003\-07\-03\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Increment the sales count of the salesperson who manages the account for Acme Corporation, using the
+FROM
+clause syntax:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE employees SET sales_count = sales_count + 1 FROM accounts
+ WHERE accounts\&.name = \*(AqAcme Corporation\*(Aq
+ AND employees\&.id = accounts\&.sales_person;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Perform the same operation, using a sub\-select in the
+WHERE
+clause:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE employees SET sales_count = sales_count + 1 WHERE id =
+ (SELECT sales_person FROM accounts WHERE name = \*(AqAcme Corporation\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Update contact names in an accounts table to match the currently assigned salespeople:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE accounts SET (contact_first_name, contact_last_name) =
+ (SELECT first_name, last_name FROM employees
+ WHERE employees\&.id = accounts\&.sales_person);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+A similar result could be accomplished with a join:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE accounts SET contact_first_name = first_name,
+ contact_last_name = last_name
+ FROM employees WHERE employees\&.id = accounts\&.sales_person;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+However, the second query may give unexpected results if
+employees\&.id
+is not a unique key, whereas the first query is guaranteed to raise an error if there are multiple
+id
+matches\&. Also, if there is no match for a particular
+accounts\&.sales_person
+entry, the first query will set the corresponding name fields to NULL, whereas the second query will not update that row at all\&.
+.PP
+Update statistics in a summary table to match the current data:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE summary s SET (sum_x, sum_y, avg_x, avg_y) =
+ (SELECT sum(x), sum(y), avg(x), avg(y) FROM data d
+ WHERE d\&.group_id = s\&.group_id);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Attempt to insert a new stock item along with the quantity of stock\&. If the item already exists, instead update the stock count of the existing item\&. To do this without failing the entire transaction, use savepoints:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+BEGIN;
+\-\- other operations
+SAVEPOINT sp1;
+INSERT INTO wines VALUES(\*(AqChateau Lafite 2003\*(Aq, \*(Aq24\*(Aq);
+\-\- Assume the above fails because of a unique key violation,
+\-\- so now we issue these commands:
+ROLLBACK TO sp1;
+UPDATE wines SET stock = stock + 24 WHERE winename = \*(AqChateau Lafite 2003\*(Aq;
+\-\- continue with other operations, and eventually
+COMMIT;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Change the
+kind
+column of the table
+films
+in the row on which the cursor
+c_films
+is currently positioned:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+UPDATE films SET kind = \*(AqDramatic\*(Aq WHERE CURRENT OF c_films;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+This command conforms to the
+SQL
+standard, except that the
+FROM
+and
+RETURNING
+clauses are
+PostgreSQL
+extensions, as is the ability to use
+WITH
+with
+\fBUPDATE\fR\&.
+.PP
+Some other database systems offer a
+FROM
+option in which the target table is supposed to be listed again within
+FROM\&. That is not how
+PostgreSQL
+interprets
+FROM\&. Be careful when porting applications that use this extension\&.
+.PP
+According to the standard, the source value for a parenthesized sub\-list of target column names can be any row\-valued expression yielding the correct number of columns\&.
+PostgreSQL
+only allows the source value to be a
+row constructor
+or a sub\-SELECT\&. An individual column\*(Aqs updated value can be specified as
+DEFAULT
+in the row\-constructor case, but not inside a sub\-SELECT\&.
diff --git a/doc/src/sgml/man7/VACUUM.7 b/doc/src/sgml/man7/VACUUM.7
new file mode 100644
index 0000000..eaf11a9
--- /dev/null
+++ b/doc/src/sgml/man7/VACUUM.7
@@ -0,0 +1,364 @@
+'\" t
+.\" Title: VACUUM
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "VACUUM" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+VACUUM \- garbage\-collect and optionally analyze a database
+.SH "SYNOPSIS"
+.sp
+.nf
+VACUUM [ ( \fIoption\fR [, \&.\&.\&.] ) ] [ \fItable_and_columns\fR [, \&.\&.\&.] ]
+VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ \fItable_and_columns\fR [, \&.\&.\&.] ]
+
+where \fIoption\fR can be one of:
+
+ FULL [ \fIboolean\fR ]
+ FREEZE [ \fIboolean\fR ]
+ VERBOSE [ \fIboolean\fR ]
+ ANALYZE [ \fIboolean\fR ]
+ DISABLE_PAGE_SKIPPING [ \fIboolean\fR ]
+ SKIP_LOCKED [ \fIboolean\fR ]
+ INDEX_CLEANUP { AUTO | ON | OFF }
+ PROCESS_TOAST [ \fIboolean\fR ]
+ TRUNCATE [ \fIboolean\fR ]
+ PARALLEL \fIinteger\fR
+
+and \fItable_and_columns\fR is:
+
+ \fItable_name\fR [ ( \fIcolumn_name\fR [, \&.\&.\&.] ) ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBVACUUM\fR
+reclaims storage occupied by dead tuples\&. In normal
+PostgreSQL
+operation, tuples that are deleted or obsoleted by an update are not physically removed from their table; they remain present until a
+\fBVACUUM\fR
+is done\&. Therefore it\*(Aqs necessary to do
+\fBVACUUM\fR
+periodically, especially on frequently\-updated tables\&.
+.PP
+Without a
+\fItable_and_columns\fR
+list,
+\fBVACUUM\fR
+processes every table and materialized view in the current database that the current user has permission to vacuum\&. With a list,
+\fBVACUUM\fR
+processes only those table(s)\&.
+.PP
+\fBVACUUM ANALYZE\fR
+performs a
+\fBVACUUM\fR
+and then an
+\fBANALYZE\fR
+for each selected table\&. This is a handy combination form for routine maintenance scripts\&. See
+\fBANALYZE\fR(7)
+for more details about its processing\&.
+.PP
+Plain
+\fBVACUUM\fR
+(without
+FULL) simply reclaims space and makes it available for re\-use\&. This form of the command can operate in parallel with normal reading and writing of the table, as an exclusive lock is not obtained\&. However, extra space is not returned to the operating system (in most cases); it\*(Aqs just kept available for re\-use within the same table\&. It also allows us to leverage multiple CPUs in order to process indexes\&. This feature is known as
+parallel vacuum\&. To disable this feature, one can use
+PARALLEL
+option and specify parallel workers as zero\&.
+\fBVACUUM FULL\fR
+rewrites the entire contents of the table into a new disk file with no extra space, allowing unused space to be returned to the operating system\&. This form is much slower and requires an
+ACCESS EXCLUSIVE
+lock on each table while it is being processed\&.
+.PP
+When the option list is surrounded by parentheses, the options can be written in any order\&. Without parentheses, options must be specified in exactly the order shown above\&. The parenthesized syntax was added in
+PostgreSQL
+9\&.0; the unparenthesized syntax is deprecated\&.
+.SH "PARAMETERS"
+.PP
+FULL
+.RS 4
+Selects
+\(lqfull\(rq
+vacuum, which can reclaim more space, but takes much longer and exclusively locks the table\&. This method also requires extra disk space, since it writes a new copy of the table and doesn\*(Aqt release the old copy until the operation is complete\&. Usually this should only be used when a significant amount of space needs to be reclaimed from within the table\&.
+.RE
+.PP
+FREEZE
+.RS 4
+Selects aggressive
+\(lqfreezing\(rq
+of tuples\&. Specifying
+FREEZE
+is equivalent to performing
+\fBVACUUM\fR
+with the
+vacuum_freeze_min_age
+and
+vacuum_freeze_table_age
+parameters set to zero\&. Aggressive freezing is always performed when the table is rewritten, so this option is redundant when
+FULL
+is specified\&.
+.RE
+.PP
+VERBOSE
+.RS 4
+Prints a detailed vacuum activity report for each table\&.
+.RE
+.PP
+ANALYZE
+.RS 4
+Updates statistics used by the planner to determine the most efficient way to execute a query\&.
+.RE
+.PP
+DISABLE_PAGE_SKIPPING
+.RS 4
+Normally,
+\fBVACUUM\fR
+will skip pages based on the
+visibility map\&. Pages where all tuples are known to be frozen can always be skipped, and those where all tuples are known to be visible to all transactions may be skipped except when performing an aggressive vacuum\&. Furthermore, except when performing an aggressive vacuum, some pages may be skipped in order to avoid waiting for other sessions to finish using them\&. This option disables all page\-skipping behavior, and is intended to be used only when the contents of the visibility map are suspect, which should happen only if there is a hardware or software issue causing database corruption\&.
+.RE
+.PP
+SKIP_LOCKED
+.RS 4
+Specifies that
+\fBVACUUM\fR
+should not wait for any conflicting locks to be released when beginning work on a relation: if a relation cannot be locked immediately without waiting, the relation is skipped\&. Note that even with this option,
+\fBVACUUM\fR
+may still block when opening the relation\*(Aqs indexes\&. Additionally,
+\fBVACUUM ANALYZE\fR
+may still block when acquiring sample rows from partitions, table inheritance children, and some types of foreign tables\&. Also, while
+\fBVACUUM\fR
+ordinarily processes all partitions of specified partitioned tables, this option will cause
+\fBVACUUM\fR
+to skip all partitions if there is a conflicting lock on the partitioned table\&.
+.RE
+.PP
+INDEX_CLEANUP
+.RS 4
+Normally,
+\fBVACUUM\fR
+will skip index vacuuming when there are very few dead tuples in the table\&. The cost of processing all of the table\*(Aqs indexes is expected to greatly exceed the benefit of removing dead index tuples when this happens\&. This option can be used to force
+\fBVACUUM\fR
+to process indexes when there are more than zero dead tuples\&. The default is
+AUTO, which allows
+\fBVACUUM\fR
+to skip index vacuuming when appropriate\&. If
+INDEX_CLEANUP
+is set to
+ON,
+\fBVACUUM\fR
+will conservatively remove all dead tuples from indexes\&. This may be useful for backwards compatibility with earlier releases of
+PostgreSQL
+where this was the standard behavior\&.
+.sp
+INDEX_CLEANUP
+can also be set to
+OFF
+to force
+\fBVACUUM\fR
+to
+\fIalways\fR
+skip index vacuuming, even when there are many dead tuples in the table\&. This may be useful when it is necessary to make
+\fBVACUUM\fR
+run as quickly as possible to avoid imminent transaction ID wraparound (see
+Section\ \&25.1.5)\&. However, the wraparound failsafe mechanism controlled by
+vacuum_failsafe_age
+will generally trigger automatically to avoid transaction ID wraparound failure, and should be preferred\&. If index cleanup is not performed regularly, performance may suffer, because as the table is modified indexes will accumulate dead tuples and the table itself will accumulate dead line pointers that cannot be removed until index cleanup is completed\&.
+.sp
+This option has no effect for tables that have no index and is ignored if the
+FULL
+option is used\&. It also has no effect on the transaction ID wraparound failsafe mechanism\&. When triggered it will skip index vacuuming, even when
+INDEX_CLEANUP
+is set to
+ON\&.
+.RE
+.PP
+PROCESS_TOAST
+.RS 4
+Specifies that
+\fBVACUUM\fR
+should attempt to process the corresponding
+TOAST
+table for each relation, if one exists\&. This is usually the desired behavior and is the default\&. Setting this option to false may be useful when it is only necessary to vacuum the main relation\&. This option is required when the
+FULL
+option is used\&.
+.RE
+.PP
+TRUNCATE
+.RS 4
+Specifies that
+\fBVACUUM\fR
+should attempt to truncate off any empty pages at the end of the table and allow the disk space for the truncated pages to be returned to the operating system\&. This is normally the desired behavior and is the default unless the
+vacuum_truncate
+option has been set to false for the table to be vacuumed\&. Setting this option to false may be useful to avoid
+ACCESS EXCLUSIVE
+lock on the table that the truncation requires\&. This option is ignored if the
+FULL
+option is used\&.
+.RE
+.PP
+PARALLEL
+.RS 4
+Perform index vacuum and index cleanup phases of
+\fBVACUUM\fR
+in parallel using
+\fIinteger\fR
+background workers (for the details of each vacuum phase, please refer to
+Table\ \&28.41)\&. The number of workers used to perform the operation is equal to the number of indexes on the relation that support parallel vacuum which is limited by the number of workers specified with
+PARALLEL
+option if any which is further limited by
+max_parallel_maintenance_workers\&. An index can participate in parallel vacuum if and only if the size of the index is more than
+min_parallel_index_scan_size\&. Please note that it is not guaranteed that the number of parallel workers specified in
+\fIinteger\fR
+will be used during execution\&. It is possible for a vacuum to run with fewer workers than specified, or even with no workers at all\&. Only one worker can be used per index\&. So parallel workers are launched only when there are at least
+2
+indexes in the table\&. Workers for vacuum are launched before the start of each phase and exit at the end of the phase\&. These behaviors might change in a future release\&. This option can\*(Aqt be used with the
+FULL
+option\&.
+.RE
+.PP
+\fIboolean\fR
+.RS 4
+Specifies whether the selected option should be turned on or off\&. You can write
+TRUE,
+ON, or
+1
+to enable the option, and
+FALSE,
+OFF, or
+0
+to disable it\&. The
+\fIboolean\fR
+value can also be omitted, in which case
+TRUE
+is assumed\&.
+.RE
+.PP
+\fIinteger\fR
+.RS 4
+Specifies a non\-negative integer value passed to the selected option\&.
+.RE
+.PP
+\fItable_name\fR
+.RS 4
+The name (optionally schema\-qualified) of a specific table or materialized view to vacuum\&. If the specified table is a partitioned table, all of its leaf partitions are vacuumed\&.
+.RE
+.PP
+\fIcolumn_name\fR
+.RS 4
+The name of a specific column to analyze\&. Defaults to all columns\&. If a column list is specified,
+ANALYZE
+must also be specified\&.
+.RE
+.SH "OUTPUTS"
+.PP
+When
+VERBOSE
+is specified,
+\fBVACUUM\fR
+emits progress messages to indicate which table is currently being processed\&. Various statistics about the tables are printed as well\&.
+.SH "NOTES"
+.PP
+To vacuum a table, one must ordinarily be the table\*(Aqs owner or a superuser\&. However, database owners are allowed to vacuum all tables in their databases, except shared catalogs\&. (The restriction for shared catalogs means that a true database\-wide
+\fBVACUUM\fR
+can only be performed by a superuser\&.)
+\fBVACUUM\fR
+will skip over any tables that the calling user does not have permission to vacuum\&.
+.PP
+\fBVACUUM\fR
+cannot be executed inside a transaction block\&.
+.PP
+For tables with
+GIN
+indexes,
+\fBVACUUM\fR
+(in any form) also completes any pending index insertions, by moving pending index entries to the appropriate places in the main
+GIN
+index structure\&. See
+Section\ \&70.4.1
+for details\&.
+.PP
+We recommend that all databases be vacuumed regularly in order to remove dead rows\&.
+PostgreSQL
+includes an
+\(lqautovacuum\(rq
+facility which can automate routine vacuum maintenance\&. For more information about automatic and manual vacuuming, see
+Section\ \&25.1\&.
+.PP
+The
+\fBFULL\fR
+option is not recommended for routine use, but might be useful in special cases\&. An example is when you have deleted or updated most of the rows in a table and would like the table to physically shrink to occupy less disk space and allow faster table scans\&.
+\fBVACUUM FULL\fR
+will usually shrink the table more than a plain
+\fBVACUUM\fR
+would\&.
+.PP
+The
+\fBPARALLEL\fR
+option is used only for vacuum purposes\&. If this option is specified with the
+\fBANALYZE\fR
+option, it does not affect
+\fBANALYZE\fR\&.
+.PP
+\fBVACUUM\fR
+causes a substantial increase in I/O traffic, which might cause poor performance for other active sessions\&. Therefore, it is sometimes advisable to use the cost\-based vacuum delay feature\&. For parallel vacuum, each worker sleeps in proportion to the work done by that worker\&. See
+Section\ \&20.4.4
+for details\&.
+.PP
+Each backend running
+\fBVACUUM\fR
+without the
+FULL
+option will report its progress in the
+pg_stat_progress_vacuum
+view\&. Backends running
+\fBVACUUM FULL\fR
+will instead report their progress in the
+pg_stat_progress_cluster
+view\&. See
+Section\ \&28.4.3
+and
+Section\ \&28.4.4
+for details\&.
+.SH "EXAMPLES"
+.PP
+To clean a single table
+onek, analyze it for the optimizer and print a detailed vacuum activity report:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+VACUUM (VERBOSE, ANALYZE) onek;
+.fi
+.if n \{\
+.RE
+.\}
+.SH "COMPATIBILITY"
+.PP
+There is no
+\fBVACUUM\fR
+statement in the SQL standard\&.
+.SH "SEE ALSO"
+\fBvacuumdb\fR(1), Section\ \&20.4.4, Section\ \&25.1.6, Section\ \&28.4.3, Section\ \&28.4.4
diff --git a/doc/src/sgml/man7/VALUES.7 b/doc/src/sgml/man7/VALUES.7
new file mode 100644
index 0000000..de2a178
--- /dev/null
+++ b/doc/src/sgml/man7/VALUES.7
@@ -0,0 +1,292 @@
+'\" t
+.\" Title: VALUES
+.\" Author: The PostgreSQL Global Development Group
+.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
+.\" Date: 2023
+.\" Manual: PostgreSQL 15.4 Documentation
+.\" Source: PostgreSQL 15.4
+.\" Language: English
+.\"
+.TH "VALUES" "7" "2023" "PostgreSQL 15.4" "PostgreSQL 15.4 Documentation"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+VALUES \- compute a set of rows
+.SH "SYNOPSIS"
+.sp
+.nf
+VALUES ( \fIexpression\fR [, \&.\&.\&.] ) [, \&.\&.\&.]
+ [ ORDER BY \fIsort_expression\fR [ ASC | DESC | USING \fIoperator\fR ] [, \&.\&.\&.] ]
+ [ LIMIT { \fIcount\fR | ALL } ]
+ [ OFFSET \fIstart\fR [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ \fIcount\fR ] { ROW | ROWS } ONLY ]
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBVALUES\fR
+computes a row value or set of row values specified by value expressions\&. It is most commonly used to generate a
+\(lqconstant table\(rq
+within a larger command, but it can be used on its own\&.
+.PP
+When more than one row is specified, all the rows must have the same number of elements\&. The data types of the resulting table\*(Aqs columns are determined by combining the explicit or inferred types of the expressions appearing in that column, using the same rules as for
+UNION
+(see
+Section\ \&10.5)\&.
+.PP
+Within larger commands,
+\fBVALUES\fR
+is syntactically allowed anywhere that
+\fBSELECT\fR
+is\&. Because it is treated like a
+\fBSELECT\fR
+by the grammar, it is possible to use the
+ORDER BY,
+LIMIT
+(or equivalently
+FETCH FIRST), and
+OFFSET
+clauses with a
+\fBVALUES\fR
+command\&.
+.SH "PARAMETERS"
+.PP
+\fIexpression\fR
+.RS 4
+A constant or expression to compute and insert at the indicated place in the resulting table (set of rows)\&. In a
+\fBVALUES\fR
+list appearing at the top level of an
+\fBINSERT\fR, an
+\fIexpression\fR
+can be replaced by
+DEFAULT
+to indicate that the destination column\*(Aqs default value should be inserted\&.
+DEFAULT
+cannot be used when
+\fBVALUES\fR
+appears in other contexts\&.
+.RE
+.PP
+\fIsort_expression\fR
+.RS 4
+An expression or integer constant indicating how to sort the result rows\&. This expression can refer to the columns of the
+\fBVALUES\fR
+result as
+column1,
+column2, etc\&. For more details see
+ORDER BY Clause
+in the
+\fBSELECT\fR(7)
+documentation\&.
+.RE
+.PP
+\fIoperator\fR
+.RS 4
+A sorting operator\&. For details see
+ORDER BY Clause
+in the
+\fBSELECT\fR(7)
+documentation\&.
+.RE
+.PP
+\fIcount\fR
+.RS 4
+The maximum number of rows to return\&. For details see
+LIMIT Clause
+in the
+\fBSELECT\fR(7)
+documentation\&.
+.RE
+.PP
+\fIstart\fR
+.RS 4
+The number of rows to skip before starting to return rows\&. For details see
+LIMIT Clause
+in the
+\fBSELECT\fR(7)
+documentation\&.
+.RE
+.SH "NOTES"
+.PP
+\fBVALUES\fR
+lists with very large numbers of rows should be avoided, as you might encounter out\-of\-memory failures or poor performance\&.
+\fBVALUES\fR
+appearing within
+\fBINSERT\fR
+is a special case (because the desired column types are known from the
+\fBINSERT\fR\*(Aqs target table, and need not be inferred by scanning the
+\fBVALUES\fR
+list), so it can handle larger lists than are practical in other contexts\&.
+.SH "EXAMPLES"
+.PP
+A bare
+\fBVALUES\fR
+command:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+VALUES (1, \*(Aqone\*(Aq), (2, \*(Aqtwo\*(Aq), (3, \*(Aqthree\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This will return a table of two columns and three rows\&. It\*(Aqs effectively equivalent to:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT 1 AS column1, \*(Aqone\*(Aq AS column2
+UNION ALL
+SELECT 2, \*(Aqtwo\*(Aq
+UNION ALL
+SELECT 3, \*(Aqthree\*(Aq;
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+More usually,
+\fBVALUES\fR
+is used within a larger SQL command\&. The most common use is in
+\fBINSERT\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES (\*(AqT_601\*(Aq, \*(AqYojimbo\*(Aq, 106, \*(Aq1961\-06\-16\*(Aq, \*(AqDrama\*(Aq);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+In the context of
+\fBINSERT\fR, entries of a
+\fBVALUES\fR
+list can be
+DEFAULT
+to indicate that the column default should be used here instead of specifying a value:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+INSERT INTO films VALUES
+ (\*(AqUA502\*(Aq, \*(AqBananas\*(Aq, 105, DEFAULT, \*(AqComedy\*(Aq, \*(Aq82 minutes\*(Aq),
+ (\*(AqT_601\*(Aq, \*(AqYojimbo\*(Aq, 106, DEFAULT, \*(AqDrama\*(Aq, DEFAULT);
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+\fBVALUES\fR
+can also be used where a sub\-\fBSELECT\fR
+might be written, for example in a
+FROM
+clause:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT f\&.*
+ FROM films f, (VALUES(\*(AqMGM\*(Aq, \*(AqHorror\*(Aq), (\*(AqUA\*(Aq, \*(AqSci\-Fi\*(Aq)) AS t (studio, kind)
+ WHERE f\&.studio = t\&.studio AND f\&.kind = t\&.kind;
+
+UPDATE employees SET salary = salary * v\&.increase
+ FROM (VALUES(1, 200000, 1\&.2), (2, 400000, 1\&.4)) AS v (depno, target, increase)
+ WHERE employees\&.depno = v\&.depno AND employees\&.sales >= v\&.target;
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note that an
+AS
+clause is required when
+\fBVALUES\fR
+is used in a
+FROM
+clause, just as is true for
+\fBSELECT\fR\&. It is not required that the
+AS
+clause specify names for all the columns, but it\*(Aqs good practice to do so\&. (The default column names for
+\fBVALUES\fR
+are
+column1,
+column2, etc\&. in
+PostgreSQL, but these names might be different in other database systems\&.)
+.PP
+When
+\fBVALUES\fR
+is used in
+\fBINSERT\fR, the values are all automatically coerced to the data type of the corresponding destination column\&. When it\*(Aqs used in other contexts, it might be necessary to specify the correct data type\&. If the entries are all quoted literal constants, coercing the first is sufficient to determine the assumed type for all:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+SELECT * FROM machines
+WHERE ip_address IN (VALUES(\*(Aq192\&.168\&.0\&.1\*(Aq::inet), (\*(Aq192\&.168\&.0\&.10\*(Aq), (\*(Aq192\&.168\&.1\&.43\*(Aq));
+.fi
+.if n \{\
+.RE
+.\}
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBTip\fR
+.ps -1
+.br
+.PP
+For simple
+IN
+tests, it\*(Aqs better to rely on the
+list\-of\-scalars
+form of
+IN
+than to write a
+\fBVALUES\fR
+query as shown above\&. The list of scalars method requires less writing and is often more efficient\&.
+.sp .5v
+.RE
+.SH "COMPATIBILITY"
+.PP
+\fBVALUES\fR
+conforms to the SQL standard\&.
+LIMIT
+and
+OFFSET
+are
+PostgreSQL
+extensions; see also under
+\fBSELECT\fR(7)\&.
+.SH "SEE ALSO"
+\fBINSERT\fR(7), \fBSELECT\fR(7)
diff --git a/doc/src/sgml/man7/WITH.7 b/doc/src/sgml/man7/WITH.7
new file mode 100644
index 0000000..8e9105d
--- /dev/null
+++ b/doc/src/sgml/man7/WITH.7
@@ -0,0 +1 @@
+.so man7/SELECT.7
diff --git a/doc/src/sgml/manage-ag.sgml b/doc/src/sgml/manage-ag.sgml
new file mode 100644
index 0000000..8903ab2
--- /dev/null
+++ b/doc/src/sgml/manage-ag.sgml
@@ -0,0 +1,552 @@
+<!-- doc/src/sgml/manage-ag.sgml -->
+
+<chapter id="managing-databases">
+ <title>Managing Databases</title>
+
+ <indexterm zone="managing-databases"><primary>database</primary></indexterm>
+
+ <para>
+ Every instance of a running <productname>PostgreSQL</productname>
+ server manages one or more databases. Databases are therefore the
+ topmost hierarchical level for organizing <acronym>SQL</acronym>
+ objects (<quote>database objects</quote>). This chapter describes
+ the properties of databases, and how to create, manage, and destroy
+ them.
+ </para>
+
+ <sect1 id="manage-ag-overview">
+ <title>Overview</title>
+
+ <indexterm zone="manage-ag-overview">
+ <primary>schema</primary>
+ </indexterm>
+
+ <para>
+ A small number of objects, like role, database, and tablespace
+ names, are defined at the cluster level and stored in the
+ <literal>pg_global</literal> tablespace. Inside the cluster are
+ multiple databases, which are isolated from each other but can access
+ cluster-level objects. Inside each database are multiple schemas,
+ which contain objects like tables and functions. So the full hierarchy
+ is: cluster, database, schema, table (or some other kind of object,
+ such as a function).
+ </para>
+
+ <para>
+ When connecting to the database server, a client must specify the
+ database name in its connection request.
+ It is not possible to access more than one database per
+ connection. However, clients can open multiple connections to
+ the same database, or different databases.
+ Database-level security has two components: access control
+ (see <xref linkend="auth-pg-hba-conf"/>), managed at the
+ connection level, and authorization control
+ (see <xref linkend="ddl-priv"/>), managed via the grant system.
+ Foreign data wrappers (see <xref linkend="postgres-fdw"/>)
+ allow for objects within one database to act as proxies for objects in
+ other database or clusters.
+ The older dblink module (see <xref linkend="dblink"/>) provides a similar capability.
+ By default, all users can connect to all databases using all connection methods.
+ </para>
+
+ <para>
+ If one <productname>PostgreSQL</productname> server cluster is planned to contain
+ unrelated projects or users that should be, for the most part, unaware
+ of each other, it is recommended to put them into separate databases and
+ adjust authorizations and access controls accordingly.
+ If the projects or users are interrelated, and thus should be able to use
+ each other's resources, they should be put in the same database but probably
+ into separate schemas; this provides a modular structure with namespace
+ isolation and authorization control.
+ More information about managing schemas is in <xref linkend="ddl-schemas"/>.
+ </para>
+
+ <para>
+ While multiple databases can be created within a single cluster, it is advised
+ to consider carefully whether the benefits outweigh the risks and limitations.
+ In particular, the impact that having a shared WAL (see <xref linkend="wal"/>)
+ has on backup and recovery options. While individual databases in the cluster
+ are isolated when considered from the user's perspective, they are closely bound
+ from the database administrator's point-of-view.
+ </para>
+
+ <para>
+ Databases are created with the <command>CREATE DATABASE</command> command
+ (see <xref linkend="manage-ag-createdb"/>) and destroyed with the
+ <command>DROP DATABASE</command> command
+ (see <xref linkend="manage-ag-dropdb"/>).
+ To determine the set of existing databases, examine the
+ <structname>pg_database</structname> system catalog, for example
+<synopsis>
+SELECT datname FROM pg_database;
+</synopsis>
+ The <xref linkend="app-psql"/> program's <literal>\l</literal> meta-command
+ and <option>-l</option> command-line option are also useful for listing the
+ existing databases.
+ </para>
+
+ <note>
+ <para>
+ The <acronym>SQL</acronym> standard calls databases <quote>catalogs</quote>, but there
+ is no difference in practice.
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="manage-ag-createdb">
+ <title>Creating a Database</title>
+
+ <indexterm><primary>CREATE DATABASE</primary></indexterm>
+
+ <para>
+ In order to create a database, the <productname>PostgreSQL</productname>
+ server must be up and running (see <xref
+ linkend="server-start"/>).
+ </para>
+
+ <para>
+ Databases are created with the SQL command
+ <xref linkend="sql-createdatabase"/>:
+<synopsis>
+CREATE DATABASE <replaceable>name</replaceable>;
+</synopsis>
+ where <replaceable>name</replaceable> follows the usual rules for
+ <acronym>SQL</acronym> identifiers. The current role automatically
+ becomes the owner of the new database. It is the privilege of the
+ owner of a database to remove it later (which also removes all
+ the objects in it, even if they have a different owner).
+ </para>
+
+ <para>
+ The creation of databases is a restricted operation. See <xref
+ linkend="role-attributes"/> for how to grant permission.
+ </para>
+
+ <para>
+ Since you need to be connected to the database server in order to
+ execute the <command>CREATE DATABASE</command> command, the
+ question remains how the <emphasis>first</emphasis> database at any given
+ site can be created. The first database is always created by the
+ <command>initdb</command> command when the data storage area is
+ initialized. (See <xref linkend="creating-cluster"/>.) This
+ database is called
+ <literal>postgres</literal>.<indexterm><primary>postgres</primary></indexterm> So to
+ create the first <quote>ordinary</quote> database you can connect to
+ <literal>postgres</literal>.
+ </para>
+
+ <para>
+ Two additional databases,
+ <literal>template1</literal><indexterm><primary>template1</primary></indexterm>
+ and
+ <literal>template0</literal>,<indexterm><primary>template0</primary></indexterm>
+ are also created during database cluster initialization. Whenever a
+ new database is created within the
+ cluster, <literal>template1</literal> is essentially cloned.
+ This means that any changes you make in <literal>template1</literal> are
+ propagated to all subsequently created databases. Because of this,
+ avoid creating objects in <literal>template1</literal> unless you want them
+ propagated to every newly created database.
+ <literal>template0</literal> is meant as a pristine copy of the original
+ contents of <literal>template1</literal>. It can be cloned instead
+ of <literal>template1</literal> when it is important to make a database
+ without any such site-local additions. More details
+ appear in <xref linkend="manage-ag-templatedbs"/>.
+ </para>
+
+ <para>
+ As a convenience, there is a program you can
+ execute from the shell to create new databases,
+ <command>createdb</command>.<indexterm><primary>createdb</primary></indexterm>
+
+<synopsis>
+createdb <replaceable class="parameter">dbname</replaceable>
+</synopsis>
+
+ <command>createdb</command> does no magic. It connects to the <literal>postgres</literal>
+ database and issues the <command>CREATE DATABASE</command> command,
+ exactly as described above.
+ The <xref linkend="app-createdb"/> reference page contains the invocation
+ details. Note that <command>createdb</command> without any arguments will create
+ a database with the current user name.
+ </para>
+
+ <note>
+ <para>
+ <xref linkend="client-authentication"/> contains information about
+ how to restrict who can connect to a given database.
+ </para>
+ </note>
+
+ <para>
+ Sometimes you want to create a database for someone else, and have them
+ become the owner of the new database, so they can
+ configure and manage it themselves. To achieve that, use one of the
+ following commands:
+<programlisting>
+CREATE DATABASE <replaceable>dbname</replaceable> OWNER <replaceable>rolename</replaceable>;
+</programlisting>
+ from the SQL environment, or:
+<programlisting>
+createdb -O <replaceable>rolename</replaceable> <replaceable>dbname</replaceable>
+</programlisting>
+ from the shell.
+ Only the superuser is allowed to create a database for
+ someone else (that is, for a role you are not a member of).
+ </para>
+ </sect1>
+
+ <sect1 id="manage-ag-templatedbs">
+ <title>Template Databases</title>
+
+ <para>
+ <command>CREATE DATABASE</command> actually works by copying an existing
+ database. By default, it copies the standard system database named
+ <literal>template1</literal>.<indexterm><primary>template1</primary></indexterm> Thus that
+ database is the <quote>template</quote> from which new databases are
+ made. If you add objects to <literal>template1</literal>, these objects
+ will be copied into subsequently created user databases. This
+ behavior allows site-local modifications to the standard set of
+ objects in databases. For example, if you install the procedural
+ language <application>PL/Perl</application> in <literal>template1</literal>, it will
+ automatically be available in user databases without any extra
+ action being taken when those databases are created.
+ </para>
+
+ <para>
+ There is a second standard system database named
+ <literal>template0</literal>.<indexterm><primary>template0</primary></indexterm> This
+ database contains the same data as the initial contents of
+ <literal>template1</literal>, that is, only the standard objects
+ predefined by your version of
+ <productname>PostgreSQL</productname>. <literal>template0</literal>
+ should never be changed after the database cluster has been
+ initialized. By instructing
+ <command>CREATE DATABASE</command> to copy <literal>template0</literal> instead
+ of <literal>template1</literal>, you can create a <quote>pristine</quote> user
+ database (one where no user-defined objects exist and where the system
+ objects have not been altered) that contains none of the site-local additions in
+ <literal>template1</literal>. This is particularly handy when restoring a
+ <literal>pg_dump</literal> dump: the dump script should be restored in a
+ pristine database to ensure that one recreates the correct contents
+ of the dumped database, without conflicting with objects that
+ might have been added to <literal>template1</literal> later on.
+ </para>
+
+ <para>
+ Another common reason for copying <literal>template0</literal> instead
+ of <literal>template1</literal> is that new encoding and locale settings
+ can be specified when copying <literal>template0</literal>, whereas a copy
+ of <literal>template1</literal> must use the same settings it does.
+ This is because <literal>template1</literal> might contain encoding-specific
+ or locale-specific data, while <literal>template0</literal> is known not to.
+ </para>
+
+ <para>
+ To create a database by copying <literal>template0</literal>, use:
+<programlisting>
+CREATE DATABASE <replaceable>dbname</replaceable> TEMPLATE template0;
+</programlisting>
+ from the SQL environment, or:
+<programlisting>
+createdb -T template0 <replaceable>dbname</replaceable>
+</programlisting>
+ from the shell.
+ </para>
+
+ <para>
+ It is possible to create additional template databases, and indeed
+ one can copy any database in a cluster by specifying its name
+ as the template for <command>CREATE DATABASE</command>. It is important to
+ understand, however, that this is not (yet) intended as
+ a general-purpose <quote><command>COPY DATABASE</command></quote> facility.
+ The principal limitation is that no other sessions can be connected to
+ the source database while it is being copied. <command>CREATE
+ DATABASE</command> will fail if any other connection exists when it starts;
+ during the copy operation, new connections to the source database
+ are prevented.
+ </para>
+
+ <para>
+ Two useful flags exist in <literal>pg_database</literal><indexterm><primary>pg_database</primary></indexterm> for each
+ database: the columns <literal>datistemplate</literal> and
+ <literal>datallowconn</literal>. <literal>datistemplate</literal>
+ can be set to indicate that a database is intended as a template for
+ <command>CREATE DATABASE</command>. If this flag is set, the database can be
+ cloned by any user with <literal>CREATEDB</literal> privileges; if it is not set,
+ only superusers and the owner of the database can clone it.
+ If <literal>datallowconn</literal> is false, then no new connections
+ to that database will be allowed (but existing sessions are not terminated
+ simply by setting the flag false). The <literal>template0</literal>
+ database is normally marked <literal>datallowconn = false</literal> to prevent its modification.
+ Both <literal>template0</literal> and <literal>template1</literal>
+ should always be marked with <literal>datistemplate = true</literal>.
+ </para>
+
+ <note>
+ <para>
+ <literal>template1</literal> and <literal>template0</literal> do not have any special
+ status beyond the fact that the name <literal>template1</literal> is the default
+ source database name for <command>CREATE DATABASE</command>.
+ For example, one could drop <literal>template1</literal> and recreate it from
+ <literal>template0</literal> without any ill effects. This course of action
+ might be advisable if one has carelessly added a bunch of junk in
+ <literal>template1</literal>. (To delete <literal>template1</literal>,
+ it must have <literal>pg_database.datistemplate = false</literal>.)
+ </para>
+
+ <para>
+ The <literal>postgres</literal> database is also created when a database
+ cluster is initialized. This database is meant as a default database for
+ users and applications to connect to. It is simply a copy of
+ <literal>template1</literal> and can be dropped and recreated if necessary.
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="manage-ag-config">
+ <title>Database Configuration</title>
+
+ <para>
+ Recall from <xref linkend="runtime-config"/> that the
+ <productname>PostgreSQL</productname> server provides a large number of
+ run-time configuration variables. You can set database-specific
+ default values for many of these settings.
+ </para>
+
+ <para>
+ For example, if for some reason you want to disable the
+ <acronym>GEQO</acronym> optimizer for a given database, you'd
+ ordinarily have to either disable it for all databases or make sure
+ that every connecting client is careful to issue <literal>SET geqo
+ TO off</literal>. To make this setting the default within a particular
+ database, you can execute the command:
+<programlisting>
+ALTER DATABASE mydb SET geqo TO off;
+</programlisting>
+ This will save the setting (but not set it immediately). In
+ subsequent connections to this database it will appear as though
+ <literal>SET geqo TO off;</literal> had been executed just before the
+ session started.
+ Note that users can still alter this setting during their sessions; it
+ will only be the default. To undo any such setting, use
+ <literal>ALTER DATABASE <replaceable>dbname</replaceable> RESET
+ <replaceable>varname</replaceable></literal>.
+ </para>
+ </sect1>
+
+ <sect1 id="manage-ag-dropdb">
+ <title>Destroying a Database</title>
+
+ <para>
+ Databases are destroyed with the command
+ <xref linkend="sql-dropdatabase"/>:<indexterm><primary>DROP DATABASE</primary></indexterm>
+<synopsis>
+DROP DATABASE <replaceable>name</replaceable>;
+</synopsis>
+ Only the owner of the database, or
+ a superuser, can drop a database. Dropping a database removes all objects
+ that were
+ contained within the database. The destruction of a database cannot
+ be undone.
+ </para>
+
+ <para>
+ You cannot execute the <command>DROP DATABASE</command> command
+ while connected to the victim database. You can, however, be
+ connected to any other database, including the <literal>template1</literal>
+ database.
+ <literal>template1</literal> would be the only option for dropping the last user database of a
+ given cluster.
+ </para>
+
+ <para>
+ For convenience, there is also a shell program to drop
+ databases, <xref linkend="app-dropdb"/>:<indexterm><primary>dropdb</primary></indexterm>
+<synopsis>
+dropdb <replaceable class="parameter">dbname</replaceable>
+</synopsis>
+ (Unlike <command>createdb</command>, it is not the default action to drop
+ the database with the current user name.)
+ </para>
+ </sect1>
+
+ <sect1 id="manage-ag-tablespaces">
+ <title>Tablespaces</title>
+
+ <indexterm zone="manage-ag-tablespaces">
+ <primary>tablespace</primary>
+ </indexterm>
+
+ <para>
+ Tablespaces in <productname>PostgreSQL</productname> allow database administrators to
+ define locations in the file system where the files representing
+ database objects can be stored. Once created, a tablespace can be referred
+ to by name when creating database objects.
+ </para>
+
+ <para>
+ By using tablespaces, an administrator can control the disk layout
+ of a <productname>PostgreSQL</productname> installation. This is useful in at
+ least two ways. First, if the partition or volume on which the
+ cluster was initialized runs out of space and cannot be extended,
+ a tablespace can be created on a different partition and used
+ until the system can be reconfigured.
+ </para>
+
+ <para>
+ Second, tablespaces allow an administrator to use knowledge of the
+ usage pattern of database objects to optimize performance. For
+ example, an index which is very heavily used can be placed on a
+ very fast, highly available disk, such as an expensive solid state
+ device. At the same time a table storing archived data which is
+ rarely used or not performance critical could be stored on a less
+ expensive, slower disk system.
+ </para>
+
+ <warning>
+ <para>
+ Even though located outside the main PostgreSQL data directory,
+ tablespaces are an integral part of the database cluster and
+ <emphasis>cannot</emphasis> be treated as an autonomous collection
+ of data files. They are dependent on metadata contained in the main
+ data directory, and therefore cannot be attached to a different
+ database cluster or backed up individually. Similarly, if you lose
+ a tablespace (file deletion, disk failure, etc.), the database cluster
+ might become unreadable or unable to start. Placing a tablespace
+ on a temporary file system like a RAM disk risks the reliability of
+ the entire cluster.
+ </para>
+ </warning>
+
+ <para>
+ To define a tablespace, use the <xref
+ linkend="sql-createtablespace"/>
+ command, for example:<indexterm><primary>CREATE TABLESPACE</primary></indexterm>:
+<programlisting>
+CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';
+</programlisting>
+ The location must be an existing, empty directory that is owned by
+ the <productname>PostgreSQL</productname> operating system user. All objects subsequently
+ created within the tablespace will be stored in files underneath this
+ directory. The location must not be on removable or transient storage,
+ as the cluster might fail to function if the tablespace is missing
+ or lost.
+ </para>
+
+ <note>
+ <para>
+ There is usually not much point in making more than one
+ tablespace per logical file system, since you cannot control the location
+ of individual files within a logical file system. However,
+ <productname>PostgreSQL</productname> does not enforce any such limitation, and
+ indeed it is not directly aware of the file system boundaries on your
+ system. It just stores files in the directories you tell it to use.
+ </para>
+ </note>
+
+ <para>
+ Creation of the tablespace itself must be done as a database superuser,
+ but after that you can allow ordinary database users to use it.
+ To do that, grant them the <literal>CREATE</literal> privilege on it.
+ </para>
+
+ <para>
+ Tables, indexes, and entire databases can be assigned to
+ particular tablespaces. To do so, a user with the <literal>CREATE</literal>
+ privilege on a given tablespace must pass the tablespace name as a
+ parameter to the relevant command. For example, the following creates
+ a table in the tablespace <literal>space1</literal>:
+<programlisting>
+CREATE TABLE foo(i int) TABLESPACE space1;
+</programlisting>
+ </para>
+
+ <para>
+ Alternatively, use the <xref linkend="guc-default-tablespace"/> parameter:
+<programlisting>
+SET default_tablespace = space1;
+CREATE TABLE foo(i int);
+</programlisting>
+ When <varname>default_tablespace</varname> is set to anything but an empty
+ string, it supplies an implicit <literal>TABLESPACE</literal> clause for
+ <command>CREATE TABLE</command> and <command>CREATE INDEX</command> commands that
+ do not have an explicit one.
+ </para>
+
+ <para>
+ There is also a <xref linkend="guc-temp-tablespaces"/> parameter, which
+ determines the placement of temporary tables and indexes, as well as
+ temporary files that are used for purposes such as sorting large data
+ sets. This can be a list of tablespace names, rather than only one,
+ so that the load associated with temporary objects can be spread over
+ multiple tablespaces. A random member of the list is picked each time
+ a temporary object is to be created.
+ </para>
+
+ <para>
+ The tablespace associated with a database is used to store the system
+ catalogs of that database. Furthermore, it is the default tablespace
+ used for tables, indexes, and temporary files created within the database,
+ if no <literal>TABLESPACE</literal> clause is given and no other selection is
+ specified by <varname>default_tablespace</varname> or
+ <varname>temp_tablespaces</varname> (as appropriate).
+ If a database is created without specifying a tablespace for it,
+ it uses the same tablespace as the template database it is copied from.
+ </para>
+
+ <para>
+ Two tablespaces are automatically created when the database cluster
+ is initialized. The
+ <literal>pg_global</literal> tablespace is used for shared system catalogs. The
+ <literal>pg_default</literal> tablespace is the default tablespace of the
+ <literal>template1</literal> and <literal>template0</literal> databases (and, therefore,
+ will be the default tablespace for other databases as well, unless
+ overridden by a <literal>TABLESPACE</literal> clause in <command>CREATE
+ DATABASE</command>).
+ </para>
+
+ <para>
+ Once created, a tablespace can be used from any database, provided
+ the requesting user has sufficient privilege. This means that a tablespace
+ cannot be dropped until all objects in all databases using the tablespace
+ have been removed.
+ </para>
+
+ <para>
+ To remove an empty tablespace, use the <xref
+ linkend="sql-droptablespace"/>
+ command.
+ </para>
+
+ <para>
+ To determine the set of existing tablespaces, examine the
+ <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname>
+ </link> system catalog, for example
+<synopsis>
+SELECT spcname FROM pg_tablespace;
+</synopsis>
+ The <xref linkend="app-psql"/> program's <literal>\db</literal> meta-command
+ is also useful for listing the existing tablespaces.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> makes use of symbolic links
+ to simplify the implementation of tablespaces. This
+ means that tablespaces can be used <emphasis>only</emphasis> on systems
+ that support symbolic links.
+ </para>
+
+ <para>
+ The directory <filename>$PGDATA/pg_tblspc</filename> contains symbolic links that
+ point to each of the non-built-in tablespaces defined in the cluster.
+ Although not recommended, it is possible to adjust the tablespace
+ layout by hand by redefining these links. Under no circumstances perform
+ this operation while the server is running. Note that in PostgreSQL 9.1
+ and earlier you will also need to update the <structname>pg_tablespace</structname>
+ catalog with the new locations. (If you do not, <literal>pg_dump</literal> will
+ continue to output the old tablespace locations.)
+ </para>
+
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/mk_feature_tables.pl b/doc/src/sgml/mk_feature_tables.pl
new file mode 100644
index 0000000..5a16da0
--- /dev/null
+++ b/doc/src/sgml/mk_feature_tables.pl
@@ -0,0 +1,77 @@
+# /usr/bin/perl
+
+# doc/src/sgml/mk_feature_tables.pl
+
+use strict;
+use warnings;
+
+my $yesno = $ARGV[0];
+
+open my $pack, '<', $ARGV[1] or die;
+
+my %feature_packages;
+
+while (<$pack>)
+{
+ chomp;
+ my ($fid, $pname) = split /\t/;
+ if ($feature_packages{$fid})
+ {
+ $feature_packages{$fid} .= ", $pname";
+ }
+ else
+ {
+ $feature_packages{$fid} = $pname;
+ }
+}
+
+close $pack;
+
+open my $feat, '<', $ARGV[2] or die;
+
+print "<tbody>\n";
+
+while (<$feat>)
+{
+ chomp;
+ my ($feature_id, $feature_name, $subfeature_id,
+ $subfeature_name, $is_supported, $comments) = split /\t/;
+
+ $is_supported eq $yesno || next;
+
+ $feature_name =~ s/</&lt;/g;
+ $feature_name =~ s/>/&gt;/g;
+ $subfeature_name =~ s/</&lt;/g;
+ $subfeature_name =~ s/>/&gt;/g;
+
+ print " <row>\n";
+
+ if ($subfeature_id)
+ {
+ print " <entry>$feature_id-$subfeature_id</entry>\n";
+ }
+ else
+ {
+ print " <entry>$feature_id</entry>\n";
+ }
+ print " <entry>",
+ defined($feature_packages{$feature_id})
+ ? $feature_packages{$feature_id}
+ : "",
+ "</entry>\n";
+ if ($subfeature_id)
+ {
+ print " <entry>$subfeature_name</entry>\n";
+ }
+ else
+ {
+ print " <entry>$feature_name</entry>\n";
+ }
+ print " <entry>$comments</entry>\n";
+
+ print " </row>\n";
+}
+
+print "</tbody>\n";
+
+close $feat;
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
new file mode 100644
index 0000000..c72ad60
--- /dev/null
+++ b/doc/src/sgml/monitoring.sgml
@@ -0,0 +1,7821 @@
+<!-- doc/src/sgml/monitoring.sgml -->
+
+<chapter id="monitoring">
+ <title>Monitoring Database Activity</title>
+
+ <indexterm zone="monitoring">
+ <primary>monitoring</primary>
+ <secondary>database activity</secondary>
+ </indexterm>
+
+ <indexterm zone="monitoring">
+ <primary>database activity</primary>
+ <secondary>monitoring</secondary>
+ </indexterm>
+
+ <para>
+ A database administrator frequently wonders, <quote>What is the system
+ doing right now?</quote>
+ This chapter discusses how to find that out.
+ </para>
+
+ <para>
+ Several tools are available for monitoring database activity and
+ analyzing performance. Most of this chapter is devoted to describing
+ <productname>PostgreSQL</productname>'s cumulative statistics system,
+ but one should not neglect regular Unix monitoring programs such as
+ <command>ps</command>, <command>top</command>, <command>iostat</command>, and <command>vmstat</command>.
+ Also, once one has identified a
+ poorly-performing query, further investigation might be needed using
+ <productname>PostgreSQL</productname>'s <link linkend="sql-explain"><command>EXPLAIN</command></link> command.
+ <xref linkend="using-explain"/> discusses <command>EXPLAIN</command>
+ and other methods for understanding the behavior of an individual
+ query.
+ </para>
+
+ <sect1 id="monitoring-ps">
+ <title>Standard Unix Tools</title>
+
+ <indexterm zone="monitoring-ps">
+ <primary>ps</primary>
+ <secondary>to monitor activity</secondary>
+ </indexterm>
+
+ <para>
+ On most Unix platforms, <productname>PostgreSQL</productname> modifies its
+ command title as reported by <command>ps</command>, so that individual server
+ processes can readily be identified. A sample display is
+
+<screen>
+$ ps auxww | grep ^postgres
+postgres 15551 0.0 0.1 57536 7132 pts/0 S 18:02 0:00 postgres -i
+postgres 15554 0.0 0.0 57536 1184 ? Ss 18:02 0:00 postgres: background writer
+postgres 15555 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: checkpointer
+postgres 15556 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: walwriter
+postgres 15557 0.0 0.0 58504 2244 ? Ss 18:02 0:00 postgres: autovacuum launcher
+postgres 15582 0.0 0.0 58772 3080 ? Ss 18:04 0:00 postgres: joe runbug 127.0.0.1 idle
+postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl regression [local] SELECT waiting
+postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction
+</screen>
+
+ (The appropriate invocation of <command>ps</command> varies across different
+ platforms, as do the details of what is shown. This example is from a
+ recent Linux system.) The first process listed here is the
+ primary server process. The command arguments
+ shown for it are the same ones used when it was launched. The next four
+ processes are background worker processes automatically launched by the
+ primary process. (The <quote>autovacuum launcher</quote> process will not
+ be present if you have set the system not to run autovacuum.)
+ Each of the remaining
+ processes is a server process handling one client connection. Each such
+ process sets its command line display in the form
+
+<screen>
+postgres: <replaceable>user</replaceable> <replaceable>database</replaceable> <replaceable>host</replaceable> <replaceable>activity</replaceable>
+</screen>
+
+ The user, database, and (client) host items remain the same for
+ the life of the client connection, but the activity indicator changes.
+ The activity can be <literal>idle</literal> (i.e., waiting for a client command),
+ <literal>idle in transaction</literal> (waiting for client inside a <command>BEGIN</command> block),
+ or a command type name such as <literal>SELECT</literal>. Also,
+ <literal>waiting</literal> is appended if the server process is presently waiting
+ on a lock held by another session. In the above example we can infer
+ that process 15606 is waiting for process 15610 to complete its transaction
+ and thereby release some lock. (Process 15610 must be the blocker, because
+ there is no other active session. In more complicated cases it would be
+ necessary to look into the
+ <link linkend="view-pg-locks"><structname>pg_locks</structname></link>
+ system view to determine who is blocking whom.)
+ </para>
+
+ <para>
+ If <xref linkend="guc-cluster-name"/> has been configured the
+ cluster name will also be shown in <command>ps</command> output:
+<screen>
+$ psql -c 'SHOW cluster_name'
+ cluster_name
+--------------
+ server1
+(1 row)
+
+$ ps aux|grep server1
+postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: server1: background writer
+...
+</screen>
+ </para>
+
+ <para>
+ If you have turned off <xref linkend="guc-update-process-title"/> then the
+ activity indicator is not updated; the process title is set only once
+ when a new process is launched. On some platforms this saves a measurable
+ amount of per-command overhead; on others it's insignificant.
+ </para>
+
+ <tip>
+ <para>
+ <productname>Solaris</productname> requires special handling. You must
+ use <command>/usr/ucb/ps</command>, rather than
+ <command>/bin/ps</command>. You also must use two <option>w</option>
+ flags, not just one. In addition, your original invocation of the
+ <command>postgres</command> command must have a shorter
+ <command>ps</command> status display than that provided by each
+ server process. If you fail to do all three things, the <command>ps</command>
+ output for each server process will be the original <command>postgres</command>
+ command line.
+ </para>
+ </tip>
+ </sect1>
+
+ <sect1 id="monitoring-stats">
+ <title>The Cumulative Statistics System</title>
+
+ <indexterm zone="monitoring-stats">
+ <primary>statistics</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname>'s <firstterm>cumulative statistics
+ system</firstterm> supports collection and reporting of information about
+ server activity. Presently, accesses to tables and indexes in both
+ disk-block and individual-row terms are counted. The total number of rows
+ in each table, and information about vacuum and analyze actions for each
+ table are also counted. If enabled, calls to user-defined functions and
+ the total time spent in each one are counted as well.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> also supports reporting dynamic
+ information about exactly what is going on in the system right now, such as
+ the exact command currently being executed by other server processes, and
+ which other connections exist in the system. This facility is independent
+ of the cumulative statistics system.
+ </para>
+
+ <sect2 id="monitoring-stats-setup">
+ <title>Statistics Collection Configuration</title>
+
+ <para>
+ Since collection of statistics adds some overhead to query execution,
+ the system can be configured to collect or not collect information.
+ This is controlled by configuration parameters that are normally set in
+ <filename>postgresql.conf</filename>. (See <xref linkend="runtime-config"/> for
+ details about setting configuration parameters.)
+ </para>
+
+ <para>
+ The parameter <xref linkend="guc-track-activities"/> enables monitoring
+ of the current command being executed by any server process.
+ </para>
+
+ <para>
+ The parameter <xref linkend="guc-track-counts"/> controls whether
+ cumulative statistics are collected about table and index accesses.
+ </para>
+
+ <para>
+ The parameter <xref linkend="guc-track-functions"/> enables tracking of
+ usage of user-defined functions.
+ </para>
+
+ <para>
+ The parameter <xref linkend="guc-track-io-timing"/> enables monitoring
+ of block read and write times.
+ </para>
+
+ <para>
+ The parameter <xref linkend="guc-track-wal-io-timing"/> enables monitoring
+ of WAL write times.
+ </para>
+
+ <para>
+ Normally these parameters are set in <filename>postgresql.conf</filename> so
+ that they apply to all server processes, but it is possible to turn
+ them on or off in individual sessions using the <xref
+ linkend="sql-set"/> command. (To prevent
+ ordinary users from hiding their activity from the administrator,
+ only superusers are allowed to change these parameters with
+ <command>SET</command>.)
+ </para>
+
+ <para>
+ Cumulative statistics are collected in shared memory. Every
+ <productname>PostgreSQL</productname> process collects statistics locally,
+ then updates the shared data at appropriate intervals. When a server,
+ including a physical replica, shuts down cleanly, a permanent copy of the
+ statistics data is stored in the <filename>pg_stat</filename> subdirectory,
+ so that statistics can be retained across server restarts. In contrast,
+ when starting from an unclean shutdown (e.g., after an immediate shutdown,
+ a server crash, starting from a base backup, and point-in-time recovery),
+ all statistics counters are reset.
+ </para>
+
+ </sect2>
+
+ <sect2 id="monitoring-stats-views">
+ <title>Viewing Statistics</title>
+
+ <para>
+ Several predefined views, listed in <xref
+ linkend="monitoring-stats-dynamic-views-table"/>, are available to show
+ the current state of the system. There are also several other
+ views, listed in <xref
+ linkend="monitoring-stats-views-table"/>, available to show the accumulated
+ statistics. Alternatively, one can
+ build custom views using the underlying cumulative statistics functions, as
+ discussed in <xref linkend="monitoring-stats-functions"/>.
+ </para>
+
+ <para>
+ When using the cumulative statistics views and functions to monitor
+ collected data, it is important to realize that the information does not
+ update instantaneously. Each individual server process flushes out
+ accumulated statistics to shared memory just before going idle, but not
+ more frequently than once per <varname>PGSTAT_MIN_INTERVAL</varname>
+ milliseconds (1 second unless altered while building the server); so a
+ query or transaction still in progress does not affect the displayed totals
+ and the displayed information lags behind actual activity. However,
+ current-query information collected by <varname>track_activities</varname>
+ is always up-to-date.
+ </para>
+
+ <para>
+ Another important point is that when a server process is asked to display
+ any of the accumulated statistics, accessed values are cached until the end
+ of its current transaction in the default configuration. So the statistics
+ will show static information as long as you continue the current
+ transaction. Similarly, information about the current queries of all
+ sessions is collected when any such information is first requested within a
+ transaction, and the same information will be displayed throughout the
+ transaction. This is a feature, not a bug, because it allows you to perform
+ several queries on the statistics and correlate the results without
+ worrying that the numbers are changing underneath you.
+
+ When analyzing statistics interactively, or with expensive queries, the
+ time delta between accesses to individual statistics can lead to
+ significant skew in the cached statistics. To minimize skew,
+ <varname>stats_fetch_consistency</varname> can be set to
+ <literal>snapshot</literal>, at the price of increased memory usage for
+ caching not-needed statistics data. Conversely, if it's known that
+ statistics are only accessed once, caching accessed statistics is
+ unnecessary and can be avoided by setting
+ <varname>stats_fetch_consistency</varname> to <literal>none</literal>.
+
+ You can invoke <function>pg_stat_clear_snapshot</function>() to discard the
+ current transaction's statistics snapshot or cached values (if any). The
+ next use of statistical information will (when in snapshot mode) cause a
+ new snapshot to be built or (when in cache mode) accessed statistics to be
+ cached.
+ </para>
+
+ <para>
+ A transaction can also see its own statistics (not yet flushed out to the
+ shared memory statistics) in the views
+ <structname>pg_stat_xact_all_tables</structname>,
+ <structname>pg_stat_xact_sys_tables</structname>,
+ <structname>pg_stat_xact_user_tables</structname>, and
+ <structname>pg_stat_xact_user_functions</structname>. These numbers do not act as
+ stated above; instead they update continuously throughout the transaction.
+ </para>
+
+ <para>
+ Some of the information in the dynamic statistics views shown in <xref
+ linkend="monitoring-stats-dynamic-views-table"/> is security restricted.
+ Ordinary users can only see all the information about their own sessions
+ (sessions belonging to a role that they are a member of). In rows about
+ other sessions, many columns will be null. Note, however, that the
+ existence of a session and its general properties such as its sessions user
+ and database are visible to all users. Superusers and roles with privileges of
+ built-in role <literal>pg_read_all_stats</literal> (see also <xref
+ linkend="predefined-roles"/>) can see all the information about all sessions.
+ </para>
+
+ <table id="monitoring-stats-dynamic-views-table">
+ <title>Dynamic Statistics Views</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>View Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <structname>pg_stat_activity</structname>
+ <indexterm><primary>pg_stat_activity</primary></indexterm>
+ </entry>
+ <entry>
+ One row per server process, showing information related to
+ the current activity of that process, such as state and current query.
+ See <link linkend="monitoring-pg-stat-activity-view">
+ <structname>pg_stat_activity</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_replication</structname><indexterm><primary>pg_stat_replication</primary></indexterm></entry>
+ <entry>One row per WAL sender process, showing statistics about
+ replication to that sender's connected standby server.
+ See <link linkend="monitoring-pg-stat-replication-view">
+ <structname>pg_stat_replication</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_wal_receiver</structname><indexterm><primary>pg_stat_wal_receiver</primary></indexterm></entry>
+ <entry>Only one row, showing statistics about the WAL receiver from
+ that receiver's connected server.
+ See <link linkend="monitoring-pg-stat-wal-receiver-view">
+ <structname>pg_stat_wal_receiver</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_recovery_prefetch</structname><indexterm><primary>pg_stat_recovery_prefetch</primary></indexterm></entry>
+ <entry>Only one row, showing statistics about blocks prefetched during recovery.
+ See <link linkend="monitoring-pg-stat-recovery-prefetch">
+ <structname>pg_stat_recovery_prefetch</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_subscription</structname><indexterm><primary>pg_stat_subscription</primary></indexterm></entry>
+ <entry>At least one row per subscription, showing information about
+ the subscription workers.
+ See <link linkend="monitoring-pg-stat-subscription">
+ <structname>pg_stat_subscription</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_ssl</structname><indexterm><primary>pg_stat_ssl</primary></indexterm></entry>
+ <entry>One row per connection (regular and replication), showing information about
+ SSL used on this connection.
+ See <link linkend="monitoring-pg-stat-ssl-view">
+ <structname>pg_stat_ssl</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_gssapi</structname><indexterm><primary>pg_stat_gssapi</primary></indexterm></entry>
+ <entry>One row per connection (regular and replication), showing information about
+ GSSAPI authentication and encryption used on this connection.
+ See <link linkend="monitoring-pg-stat-gssapi-view">
+ <structname>pg_stat_gssapi</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_progress_analyze</structname><indexterm><primary>pg_stat_progress_analyze</primary></indexterm></entry>
+ <entry>One row for each backend (including autovacuum worker processes) running
+ <command>ANALYZE</command>, showing current progress.
+ See <xref linkend='analyze-progress-reporting'/>.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_progress_create_index</structname><indexterm><primary>pg_stat_progress_create_index</primary></indexterm></entry>
+ <entry>One row for each backend running <command>CREATE INDEX</command> or <command>REINDEX</command>, showing
+ current progress.
+ See <xref linkend='create-index-progress-reporting'/>.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_progress_vacuum</structname><indexterm><primary>pg_stat_progress_vacuum</primary></indexterm></entry>
+ <entry>One row for each backend (including autovacuum worker processes) running
+ <command>VACUUM</command>, showing current progress.
+ See <xref linkend='vacuum-progress-reporting'/>.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_progress_cluster</structname><indexterm><primary>pg_stat_progress_cluster</primary></indexterm></entry>
+ <entry>One row for each backend running
+ <command>CLUSTER</command> or <command>VACUUM FULL</command>, showing current progress.
+ See <xref linkend='cluster-progress-reporting'/>.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_progress_basebackup</structname><indexterm><primary>pg_stat_progress_basebackup</primary></indexterm></entry>
+ <entry>One row for each WAL sender process streaming a base backup,
+ showing current progress.
+ See <xref linkend='basebackup-progress-reporting'/>.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_progress_copy</structname><indexterm><primary>pg_stat_progress_copy</primary></indexterm></entry>
+ <entry>One row for each backend running <command>COPY</command>, showing current progress.
+ See <xref linkend='copy-progress-reporting'/>.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="monitoring-stats-views-table">
+ <title>Collected Statistics Views</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>View Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structname>pg_stat_archiver</structname><indexterm><primary>pg_stat_archiver</primary></indexterm></entry>
+ <entry>One row only, showing statistics about the
+ WAL archiver process's activity. See
+ <link linkend="monitoring-pg-stat-archiver-view">
+ <structname>pg_stat_archiver</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_bgwriter</structname><indexterm><primary>pg_stat_bgwriter</primary></indexterm></entry>
+ <entry>One row only, showing statistics about the
+ background writer process's activity. See
+ <link linkend="monitoring-pg-stat-bgwriter-view">
+ <structname>pg_stat_bgwriter</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_wal</structname><indexterm><primary>pg_stat_wal</primary></indexterm></entry>
+ <entry>One row only, showing statistics about WAL activity. See
+ <link linkend="monitoring-pg-stat-wal-view">
+ <structname>pg_stat_wal</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_database</structname><indexterm><primary>pg_stat_database</primary></indexterm></entry>
+ <entry>One row per database, showing database-wide statistics. See
+ <link linkend="monitoring-pg-stat-database-view">
+ <structname>pg_stat_database</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_database_conflicts</structname><indexterm><primary>pg_stat_database_conflicts</primary></indexterm></entry>
+ <entry>
+ One row per database, showing database-wide statistics about
+ query cancels due to conflict with recovery on standby servers.
+ See <link linkend="monitoring-pg-stat-database-conflicts-view">
+ <structname>pg_stat_database_conflicts</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_all_tables</structname><indexterm><primary>pg_stat_all_tables</primary></indexterm></entry>
+ <entry>
+ One row for each table in the current database, showing statistics
+ about accesses to that specific table.
+ See <link linkend="monitoring-pg-stat-all-tables-view">
+ <structname>pg_stat_all_tables</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_sys_tables</structname><indexterm><primary>pg_stat_sys_tables</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_all_tables</structname>, except that only
+ system tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_user_tables</structname><indexterm><primary>pg_stat_user_tables</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_all_tables</structname>, except that only user
+ tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_xact_all_tables</structname><indexterm><primary>pg_stat_xact_all_tables</primary></indexterm></entry>
+ <entry>Similar to <structname>pg_stat_all_tables</structname>, but counts actions
+ taken so far within the current transaction (which are <emphasis>not</emphasis>
+ yet included in <structname>pg_stat_all_tables</structname> and related views).
+ The columns for numbers of live and dead rows and vacuum and
+ analyze actions are not present in this view.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_xact_sys_tables</structname><indexterm><primary>pg_stat_xact_sys_tables</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_xact_all_tables</structname>, except that only
+ system tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_xact_user_tables</structname><indexterm><primary>pg_stat_xact_user_tables</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_xact_all_tables</structname>, except that only
+ user tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_all_indexes</structname><indexterm><primary>pg_stat_all_indexes</primary></indexterm></entry>
+ <entry>
+ One row for each index in the current database, showing statistics
+ about accesses to that specific index.
+ See <link linkend="monitoring-pg-stat-all-indexes-view">
+ <structname>pg_stat_all_indexes</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_sys_indexes</structname><indexterm><primary>pg_stat_sys_indexes</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_all_indexes</structname>, except that only
+ indexes on system tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_user_indexes</structname><indexterm><primary>pg_stat_user_indexes</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_all_indexes</structname>, except that only
+ indexes on user tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_all_tables</structname><indexterm><primary>pg_statio_all_tables</primary></indexterm></entry>
+ <entry>
+ One row for each table in the current database, showing statistics
+ about I/O on that specific table.
+ See <link linkend="monitoring-pg-statio-all-tables-view">
+ <structname>pg_statio_all_tables</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_sys_tables</structname><indexterm><primary>pg_statio_sys_tables</primary></indexterm></entry>
+ <entry>Same as <structname>pg_statio_all_tables</structname>, except that only
+ system tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_user_tables</structname><indexterm><primary>pg_statio_user_tables</primary></indexterm></entry>
+ <entry>Same as <structname>pg_statio_all_tables</structname>, except that only
+ user tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_all_indexes</structname><indexterm><primary>pg_statio_all_indexes</primary></indexterm></entry>
+ <entry>
+ One row for each index in the current database,
+ showing statistics about I/O on that specific index.
+ See <link linkend="monitoring-pg-statio-all-indexes-view">
+ <structname>pg_statio_all_indexes</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_sys_indexes</structname><indexterm><primary>pg_statio_sys_indexes</primary></indexterm></entry>
+ <entry>Same as <structname>pg_statio_all_indexes</structname>, except that only
+ indexes on system tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_user_indexes</structname><indexterm><primary>pg_statio_user_indexes</primary></indexterm></entry>
+ <entry>Same as <structname>pg_statio_all_indexes</structname>, except that only
+ indexes on user tables are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_all_sequences</structname><indexterm><primary>pg_statio_all_sequences</primary></indexterm></entry>
+ <entry>
+ One row for each sequence in the current database,
+ showing statistics about I/O on that specific sequence.
+ See <link linkend="monitoring-pg-statio-all-sequences-view">
+ <structname>pg_statio_all_sequences</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_sys_sequences</structname><indexterm><primary>pg_statio_sys_sequences</primary></indexterm></entry>
+ <entry>Same as <structname>pg_statio_all_sequences</structname>, except that only
+ system sequences are shown. (Presently, no system sequences are defined,
+ so this view is always empty.)</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_statio_user_sequences</structname><indexterm><primary>pg_statio_user_sequences</primary></indexterm></entry>
+ <entry>Same as <structname>pg_statio_all_sequences</structname>, except that only
+ user sequences are shown.</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_user_functions</structname><indexterm><primary>pg_stat_user_functions</primary></indexterm></entry>
+ <entry>
+ One row for each tracked function, showing statistics
+ about executions of that function. See
+ <link linkend="monitoring-pg-stat-user-functions-view">
+ <structname>pg_stat_user_functions</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_xact_user_functions</structname><indexterm><primary>pg_stat_xact_user_functions</primary></indexterm></entry>
+ <entry>Similar to <structname>pg_stat_user_functions</structname>, but counts only
+ calls during the current transaction (which are <emphasis>not</emphasis>
+ yet included in <structname>pg_stat_user_functions</structname>).</entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_slru</structname><indexterm><primary>pg_stat_slru</primary></indexterm></entry>
+ <entry>One row per SLRU, showing statistics of operations. See
+ <link linkend="monitoring-pg-stat-slru-view">
+ <structname>pg_stat_slru</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_replication_slots</structname><indexterm><primary>pg_stat_replication_slots</primary></indexterm></entry>
+ <entry>One row per replication slot, showing statistics about the
+ replication slot's usage. See
+ <link linkend="monitoring-pg-stat-replication-slots-view">
+ <structname>pg_stat_replication_slots</structname></link> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_subscription_stats</structname><indexterm><primary>pg_stat_subscription_stats</primary></indexterm></entry>
+ <entry>One row per subscription, showing statistics about errors.
+ See <link linkend="monitoring-pg-stat-subscription-stats">
+ <structname>pg_stat_subscription_stats</structname></link> for details.
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The per-index statistics are particularly useful to determine which
+ indexes are being used and how effective they are.
+ </para>
+
+ <para>
+ The <structname>pg_statio_</structname> views are primarily useful to
+ determine the effectiveness of the buffer cache. When the number
+ of actual disk reads is much smaller than the number of buffer
+ hits, then the cache is satisfying most read requests without
+ invoking a kernel call. However, these statistics do not give the
+ entire story: due to the way in which <productname>PostgreSQL</productname>
+ handles disk I/O, data that is not in the
+ <productname>PostgreSQL</productname> buffer cache might still reside in the
+ kernel's I/O cache, and might therefore still be fetched without
+ requiring a physical read. Users interested in obtaining more
+ detailed information on <productname>PostgreSQL</productname> I/O behavior are
+ advised to use the <productname>PostgreSQL</productname> statistics views
+ in combination with operating system utilities that allow insight
+ into the kernel's handling of I/O.
+ </para>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-activity-view">
+ <title><structname>pg_stat_activity</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_activity</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_activity</structname> view will have one row
+ per server process, showing information related to
+ the current activity of that process.
+ </para>
+
+ <table id="pg-stat-activity-view" xreflabel="pg_stat_activity">
+ <title><structname>pg_stat_activity</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the database this backend is connected to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the database this backend is connected to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of this backend
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>leader_pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of the parallel group leader, if this process is a
+ parallel query worker. <literal>NULL</literal> if this process is a
+ parallel group leader or does not participate in parallel query.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usesysid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the user logged into this backend
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usename</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the user logged into this backend
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>application_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the application that is connected
+ to this backend
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_addr</structfield> <type>inet</type>
+ </para>
+ <para>
+ IP address of the client connected to this backend.
+ If this field is null, it indicates either that the client is
+ connected via a Unix socket on the server machine or that this is an
+ internal process such as autovacuum.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_hostname</structfield> <type>text</type>
+ </para>
+ <para>
+ Host name of the connected client, as reported by a
+ reverse DNS lookup of <structfield>client_addr</structfield>. This field will
+ only be non-null for IP connections, and only when <xref linkend="guc-log-hostname"/> is enabled.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_port</structfield> <type>integer</type>
+ </para>
+ <para>
+ TCP port number that the client is using for communication
+ with this backend, or <literal>-1</literal> if a Unix socket is used.
+ If this field is null, it indicates that this is an internal server process.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backend_start</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time when this process was started. For client backends,
+ this is the time the client connected to the server.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>xact_start</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time when this process' current transaction was started, or null
+ if no transaction is active. If the current
+ query is the first of its transaction, this column is equal to the
+ <structfield>query_start</structfield> column.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>query_start</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time when the currently active query was started, or if
+ <structfield>state</structfield> is not <literal>active</literal>, when the last query
+ was started
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>state_change</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time when the <structfield>state</structfield> was last changed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wait_event_type</structfield> <type>text</type>
+ </para>
+ <para>
+ The type of event for which the backend is waiting, if any;
+ otherwise NULL. See <xref linkend="wait-event-table"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wait_event</structfield> <type>text</type>
+ </para>
+ <para>
+ Wait event name if backend is currently waiting, otherwise NULL.
+ See <xref linkend="wait-event-activity-table"/> through
+ <xref linkend="wait-event-timeout-table"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>state</structfield> <type>text</type>
+ </para>
+ <para>
+ Current overall state of this backend.
+ Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>active</literal>: The backend is executing a query.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>idle</literal>: The backend is waiting for a new client command.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>idle in transaction</literal>: The backend is in a transaction,
+ but is not currently executing a query.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>idle in transaction (aborted)</literal>: This state is similar to
+ <literal>idle in transaction</literal>, except one of the statements in
+ the transaction caused an error.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>fastpath function call</literal>: The backend is executing a
+ fast-path function.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>disabled</literal>: This state is reported if <xref linkend="guc-track-activities"/> is disabled in this backend.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backend_xid</structfield> <type>xid</type>
+ </para>
+ <para>
+ Top-level transaction identifier of this backend, if any.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backend_xmin</structfield> <type>xid</type>
+ </para>
+ <para>
+ The current backend's <literal>xmin</literal> horizon.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>query_id</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Identifier of this backend's most recent query. If
+ <structfield>state</structfield> is <literal>active</literal> this
+ field shows the identifier of the currently executing query. In
+ all other states, it shows the identifier of last query that was
+ executed. Query identifiers are not computed by default so this
+ field will be null unless <xref linkend="guc-compute-query-id"/>
+ parameter is enabled or a third-party module that computes query
+ identifiers is configured.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>query</structfield> <type>text</type>
+ </para>
+ <para>
+ Text of this backend's most recent query. If
+ <structfield>state</structfield> is <literal>active</literal> this field shows the
+ currently executing query. In all other states, it shows the last query
+ that was executed. By default the query text is truncated at 1024
+ bytes; this value can be changed via the parameter
+ <xref linkend="guc-track-activity-query-size"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backend_type</structfield> <type>text</type>
+ </para>
+ <para>
+ Type of current backend. Possible types are
+ <literal>autovacuum launcher</literal>, <literal>autovacuum worker</literal>,
+ <literal>logical replication launcher</literal>,
+ <literal>logical replication worker</literal>,
+ <literal>parallel worker</literal>, <literal>background writer</literal>,
+ <literal>client backend</literal>, <literal>checkpointer</literal>,
+ <literal>archiver</literal>,
+ <literal>startup</literal>, <literal>walreceiver</literal>,
+ <literal>walsender</literal> and <literal>walwriter</literal>.
+ In addition, background workers registered by extensions may have
+ additional types.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The <structfield>wait_event</structfield> and <structfield>state</structfield> columns are
+ independent. If a backend is in the <literal>active</literal> state,
+ it may or may not be <literal>waiting</literal> on some event. If the state
+ is <literal>active</literal> and <structfield>wait_event</structfield> is non-null, it
+ means that a query is being executed, but is being blocked somewhere
+ in the system.
+ </para>
+ </note>
+
+ <table id="wait-event-table">
+ <title>Wait Event Types</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Wait Event Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>Activity</literal></entry>
+ <entry>The server process is idle. This event type indicates a process
+ waiting for activity in its main processing loop.
+ <literal>wait_event</literal> will identify the specific wait point;
+ see <xref linkend="wait-event-activity-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>BufferPin</literal></entry>
+ <entry>The server process is waiting for exclusive access to
+ a data buffer. Buffer pin waits can be protracted if
+ another process holds an open cursor that last read data from the
+ buffer in question. See <xref linkend="wait-event-bufferpin-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>Client</literal></entry>
+ <entry>The server process is waiting for activity on a socket
+ connected to a user application. Thus, the server expects something
+ to happen that is independent of its internal processes.
+ <literal>wait_event</literal> will identify the specific wait point;
+ see <xref linkend="wait-event-client-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>Extension</literal></entry>
+ <entry>The server process is waiting for some condition defined by an
+ extension module.
+ See <xref linkend="wait-event-extension-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>IO</literal></entry>
+ <entry>The server process is waiting for an I/O operation to complete.
+ <literal>wait_event</literal> will identify the specific wait point;
+ see <xref linkend="wait-event-io-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>IPC</literal></entry>
+ <entry>The server process is waiting for some interaction with
+ another server process. <literal>wait_event</literal> will
+ identify the specific wait point;
+ see <xref linkend="wait-event-ipc-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>Lock</literal></entry>
+ <entry>The server process is waiting for a heavyweight lock.
+ Heavyweight locks, also known as lock manager locks or simply locks,
+ primarily protect SQL-visible objects such as tables. However,
+ they are also used to ensure mutual exclusion for certain internal
+ operations such as relation extension. <literal>wait_event</literal>
+ will identify the type of lock awaited;
+ see <xref linkend="wait-event-lock-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>LWLock</literal></entry>
+ <entry> The server process is waiting for a lightweight lock.
+ Most such locks protect a particular data structure in shared memory.
+ <literal>wait_event</literal> will contain a name identifying the purpose
+ of the lightweight lock. (Some locks have specific names; others
+ are part of a group of locks each with a similar purpose.)
+ See <xref linkend="wait-event-lwlock-table"/>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>Timeout</literal></entry>
+ <entry>The server process is waiting for a timeout
+ to expire. <literal>wait_event</literal> will identify the specific wait
+ point; see <xref linkend="wait-event-timeout-table"/>.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-activity-table">
+ <title>Wait Events of Type <literal>Activity</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>Activity</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>ArchiverMain</literal></entry>
+ <entry>Waiting in main loop of archiver process.</entry>
+ </row>
+ <row>
+ <entry><literal>AutoVacuumMain</literal></entry>
+ <entry>Waiting in main loop of autovacuum launcher process.</entry>
+ </row>
+ <row>
+ <entry><literal>BgWriterHibernate</literal></entry>
+ <entry>Waiting in background writer process, hibernating.</entry>
+ </row>
+ <row>
+ <entry><literal>BgWriterMain</literal></entry>
+ <entry>Waiting in main loop of background writer process.</entry>
+ </row>
+ <row>
+ <entry><literal>CheckpointerMain</literal></entry>
+ <entry>Waiting in main loop of checkpointer process.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalApplyMain</literal></entry>
+ <entry>Waiting in main loop of logical replication apply process.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalLauncherMain</literal></entry>
+ <entry>Waiting in main loop of logical replication launcher process.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryWalStream</literal></entry>
+ <entry>Waiting in main loop of startup process for WAL to arrive, during
+ streaming recovery.</entry>
+ </row>
+ <row>
+ <entry><literal>SysLoggerMain</literal></entry>
+ <entry>Waiting in main loop of syslogger process.</entry>
+ </row>
+ <row>
+ <entry><literal>WalReceiverMain</literal></entry>
+ <entry>Waiting in main loop of WAL receiver process.</entry>
+ </row>
+ <row>
+ <entry><literal>WalSenderMain</literal></entry>
+ <entry>Waiting in main loop of WAL sender process.</entry>
+ </row>
+ <row>
+ <entry><literal>WalWriterMain</literal></entry>
+ <entry>Waiting in main loop of WAL writer process.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-bufferpin-table">
+ <title>Wait Events of Type <literal>BufferPin</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>BufferPin</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>BufferPin</literal></entry>
+ <entry>Waiting to acquire an exclusive pin on a buffer.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-client-table">
+ <title>Wait Events of Type <literal>Client</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>Client</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>ClientRead</literal></entry>
+ <entry>Waiting to read data from the client.</entry>
+ </row>
+ <row>
+ <entry><literal>ClientWrite</literal></entry>
+ <entry>Waiting to write data to the client.</entry>
+ </row>
+ <row>
+ <entry><literal>GSSOpenServer</literal></entry>
+ <entry>Waiting to read data from the client while establishing a GSSAPI
+ session.</entry>
+ </row>
+ <row>
+ <entry><literal>LibPQWalReceiverConnect</literal></entry>
+ <entry>Waiting in WAL receiver to establish connection to remote
+ server.</entry>
+ </row>
+ <row>
+ <entry><literal>LibPQWalReceiverReceive</literal></entry>
+ <entry>Waiting in WAL receiver to receive data from remote server.</entry>
+ </row>
+ <row>
+ <entry><literal>SSLOpenServer</literal></entry>
+ <entry>Waiting for SSL while attempting connection.</entry>
+ </row>
+ <row>
+ <entry><literal>WalSenderWaitForWAL</literal></entry>
+ <entry>Waiting for WAL to be flushed in WAL sender process.</entry>
+ </row>
+ <row>
+ <entry><literal>WalSenderWriteData</literal></entry>
+ <entry>Waiting for any activity when processing replies from WAL
+ receiver in WAL sender process.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-extension-table">
+ <title>Wait Events of Type <literal>Extension</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>Extension</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>Extension</literal></entry>
+ <entry>Waiting in an extension.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-io-table">
+ <title>Wait Events of Type <literal>IO</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>IO</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>BaseBackupRead</literal></entry>
+ <entry>Waiting for base backup to read from a file.</entry>
+ </row>
+ <row>
+ <entry><literal>BaseBackupSync</literal></entry>
+ <entry>Waiting for data written by a base backup to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>BaseBackupWrite</literal></entry>
+ <entry>Waiting for base backup to write to a file.</entry>
+ </row>
+ <row>
+ <entry><literal>BufFileRead</literal></entry>
+ <entry>Waiting for a read from a buffered file.</entry>
+ </row>
+ <row>
+ <entry><literal>BufFileWrite</literal></entry>
+ <entry>Waiting for a write to a buffered file.</entry>
+ </row>
+ <row>
+ <entry><literal>BufFileTruncate</literal></entry>
+ <entry>Waiting for a buffered file to be truncated.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileRead</literal></entry>
+ <entry>Waiting for a read from the <filename>pg_control</filename>
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileSync</literal></entry>
+ <entry>Waiting for the <filename>pg_control</filename> file to reach
+ durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileSyncUpdate</literal></entry>
+ <entry>Waiting for an update to the <filename>pg_control</filename> file
+ to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileWrite</literal></entry>
+ <entry>Waiting for a write to the <filename>pg_control</filename>
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFileWriteUpdate</literal></entry>
+ <entry>Waiting for a write to update the <filename>pg_control</filename>
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>CopyFileRead</literal></entry>
+ <entry>Waiting for a read during a file copy operation.</entry>
+ </row>
+ <row>
+ <entry><literal>CopyFileWrite</literal></entry>
+ <entry>Waiting for a write during a file copy operation.</entry>
+ </row>
+ <row>
+ <entry><literal>DSMFillZeroWrite</literal></entry>
+ <entry>Waiting to fill a dynamic shared memory backing file with
+ zeroes.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileExtend</literal></entry>
+ <entry>Waiting for a relation data file to be extended.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileFlush</literal></entry>
+ <entry>Waiting for a relation data file to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileImmediateSync</literal></entry>
+ <entry>Waiting for an immediate synchronization of a relation data file to
+ durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFilePrefetch</literal></entry>
+ <entry>Waiting for an asynchronous prefetch from a relation data
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileRead</literal></entry>
+ <entry>Waiting for a read from a relation data file.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileSync</literal></entry>
+ <entry>Waiting for changes to a relation data file to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileTruncate</literal></entry>
+ <entry>Waiting for a relation data file to be truncated.</entry>
+ </row>
+ <row>
+ <entry><literal>DataFileWrite</literal></entry>
+ <entry>Waiting for a write to a relation data file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileAddToDataDirRead</literal></entry>
+ <entry>Waiting for a read while adding a line to the data directory lock
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileAddToDataDirSync</literal></entry>
+ <entry>Waiting for data to reach durable storage while adding a line to the
+ data directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileAddToDataDirWrite</literal></entry>
+ <entry>Waiting for a write while adding a line to the data directory
+ lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileCreateRead</literal></entry>
+ <entry>Waiting to read while creating the data directory lock
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileCreateSync</literal></entry>
+ <entry>Waiting for data to reach durable storage while creating the data
+ directory lock file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileCreateWrite</literal></entry>
+ <entry>Waiting for a write while creating the data directory lock
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFileReCheckDataDirRead</literal></entry>
+ <entry>Waiting for a read during recheck of the data directory lock
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteCheckpointSync</literal></entry>
+ <entry>Waiting for logical rewrite mappings to reach durable storage
+ during a checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteMappingSync</literal></entry>
+ <entry>Waiting for mapping data to reach durable storage during a logical
+ rewrite.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteMappingWrite</literal></entry>
+ <entry>Waiting for a write of mapping data during a logical
+ rewrite.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteSync</literal></entry>
+ <entry>Waiting for logical rewrite mappings to reach durable
+ storage.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteTruncate</literal></entry>
+ <entry>Waiting for truncate of mapping data during a logical
+ rewrite.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRewriteWrite</literal></entry>
+ <entry>Waiting for a write of logical rewrite mappings.</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapRead</literal></entry>
+ <entry>Waiting for a read of the relation map file.</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapSync</literal></entry>
+ <entry>Waiting for the relation map file to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapWrite</literal></entry>
+ <entry>Waiting for a write to the relation map file.</entry>
+ </row>
+ <row>
+ <entry><literal>ReorderBufferRead</literal></entry>
+ <entry>Waiting for a read during reorder buffer management.</entry>
+ </row>
+ <row>
+ <entry><literal>ReorderBufferWrite</literal></entry>
+ <entry>Waiting for a write during reorder buffer management.</entry>
+ </row>
+ <row>
+ <entry><literal>ReorderLogicalMappingRead</literal></entry>
+ <entry>Waiting for a read of a logical mapping during reorder buffer
+ management.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotRead</literal></entry>
+ <entry>Waiting for a read from a replication slot control file.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotRestoreSync</literal></entry>
+ <entry>Waiting for a replication slot control file to reach durable storage
+ while restoring it to memory.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotSync</literal></entry>
+ <entry>Waiting for a replication slot control file to reach durable
+ storage.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotWrite</literal></entry>
+ <entry>Waiting for a write to a replication slot control file.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRUFlushSync</literal></entry>
+ <entry>Waiting for SLRU data to reach durable storage during a checkpoint
+ or database shutdown.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRURead</literal></entry>
+ <entry>Waiting for a read of an SLRU page.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRUSync</literal></entry>
+ <entry>Waiting for SLRU data to reach durable storage following a page
+ write.</entry>
+ </row>
+ <row>
+ <entry><literal>SLRUWrite</literal></entry>
+ <entry>Waiting for a write of an SLRU page.</entry>
+ </row>
+ <row>
+ <entry><literal>SnapbuildRead</literal></entry>
+ <entry>Waiting for a read of a serialized historical catalog
+ snapshot.</entry>
+ </row>
+ <row>
+ <entry><literal>SnapbuildSync</literal></entry>
+ <entry>Waiting for a serialized historical catalog snapshot to reach
+ durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>SnapbuildWrite</literal></entry>
+ <entry>Waiting for a write of a serialized historical catalog
+ snapshot.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryFileSync</literal></entry>
+ <entry>Waiting for a timeline history file received via streaming
+ replication to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryFileWrite</literal></entry>
+ <entry>Waiting for a write of a timeline history file received via
+ streaming replication.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryRead</literal></entry>
+ <entry>Waiting for a read of a timeline history file.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistorySync</literal></entry>
+ <entry>Waiting for a newly created timeline history file to reach durable
+ storage.</entry>
+ </row>
+ <row>
+ <entry><literal>TimelineHistoryWrite</literal></entry>
+ <entry>Waiting for a write of a newly created timeline history
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>TwophaseFileRead</literal></entry>
+ <entry>Waiting for a read of a two phase state file.</entry>
+ </row>
+ <row>
+ <entry><literal>TwophaseFileSync</literal></entry>
+ <entry>Waiting for a two phase state file to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>TwophaseFileWrite</literal></entry>
+ <entry>Waiting for a write of a two phase state file.</entry>
+ </row>
+ <row>
+ <entry><literal>VersionFileWrite</literal></entry>
+ <entry>Waiting for the version file to be written while creating a database.</entry>
+ </row>
+ <row>
+ <entry><literal>WALBootstrapSync</literal></entry>
+ <entry>Waiting for WAL to reach durable storage during
+ bootstrapping.</entry>
+ </row>
+ <row>
+ <entry><literal>WALBootstrapWrite</literal></entry>
+ <entry>Waiting for a write of a WAL page during bootstrapping.</entry>
+ </row>
+ <row>
+ <entry><literal>WALCopyRead</literal></entry>
+ <entry>Waiting for a read when creating a new WAL segment by copying an
+ existing one.</entry>
+ </row>
+ <row>
+ <entry><literal>WALCopySync</literal></entry>
+ <entry>Waiting for a new WAL segment created by copying an existing one to
+ reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>WALCopyWrite</literal></entry>
+ <entry>Waiting for a write when creating a new WAL segment by copying an
+ existing one.</entry>
+ </row>
+ <row>
+ <entry><literal>WALInitSync</literal></entry>
+ <entry>Waiting for a newly initialized WAL file to reach durable
+ storage.</entry>
+ </row>
+ <row>
+ <entry><literal>WALInitWrite</literal></entry>
+ <entry>Waiting for a write while initializing a new WAL file.</entry>
+ </row>
+ <row>
+ <entry><literal>WALRead</literal></entry>
+ <entry>Waiting for a read from a WAL file.</entry>
+ </row>
+ <row>
+ <entry><literal>WALSenderTimelineHistoryRead</literal></entry>
+ <entry>Waiting for a read from a timeline history file during a walsender
+ timeline command.</entry>
+ </row>
+ <row>
+ <entry><literal>WALSync</literal></entry>
+ <entry>Waiting for a WAL file to reach durable storage.</entry>
+ </row>
+ <row>
+ <entry><literal>WALSyncMethodAssign</literal></entry>
+ <entry>Waiting for data to reach durable storage while assigning a new
+ WAL sync method.</entry>
+ </row>
+ <row>
+ <entry><literal>WALWrite</literal></entry>
+ <entry>Waiting for a write to a WAL file.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-ipc-table">
+ <title>Wait Events of Type <literal>IPC</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>IPC</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>AppendReady</literal></entry>
+ <entry>Waiting for subplan nodes of an <literal>Append</literal> plan
+ node to be ready.</entry>
+ </row>
+ <row>
+ <entry><literal>ArchiveCleanupCommand</literal></entry>
+ <entry>Waiting for <xref linkend="guc-archive-cleanup-command"/> to
+ complete.</entry>
+ </row>
+ <row>
+ <entry><literal>ArchiveCommand</literal></entry>
+ <entry>Waiting for <xref linkend="guc-archive-command"/> to
+ complete.</entry>
+ </row>
+ <row>
+ <entry><literal>BackendTermination</literal></entry>
+ <entry>Waiting for the termination of another backend.</entry>
+ </row>
+ <row>
+ <entry><literal>BackupWaitWalArchive</literal></entry>
+ <entry>Waiting for WAL files required for a backup to be successfully
+ archived.</entry>
+ </row>
+ <row>
+ <entry><literal>BgWorkerShutdown</literal></entry>
+ <entry>Waiting for background worker to shut down.</entry>
+ </row>
+ <row>
+ <entry><literal>BgWorkerStartup</literal></entry>
+ <entry>Waiting for background worker to start up.</entry>
+ </row>
+ <row>
+ <entry><literal>BtreePage</literal></entry>
+ <entry>Waiting for the page number needed to continue a parallel B-tree
+ scan to become available.</entry>
+ </row>
+ <row>
+ <entry><literal>BufferIO</literal></entry>
+ <entry>Waiting for buffer I/O to complete.</entry>
+ </row>
+ <row>
+ <entry><literal>CheckpointDone</literal></entry>
+ <entry>Waiting for a checkpoint to complete.</entry>
+ </row>
+ <row>
+ <entry><literal>CheckpointStart</literal></entry>
+ <entry>Waiting for a checkpoint to start.</entry>
+ </row>
+ <row>
+ <entry><literal>ExecuteGather</literal></entry>
+ <entry>Waiting for activity from a child process while
+ executing a <literal>Gather</literal> plan node.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBatchAllocate</literal></entry>
+ <entry>Waiting for an elected Parallel Hash participant to allocate a hash
+ table.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBatchElect</literal></entry>
+ <entry>Waiting to elect a Parallel Hash participant to allocate a hash
+ table.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBatchLoad</literal></entry>
+ <entry>Waiting for other Parallel Hash participants to finish loading a
+ hash table.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBuildAllocate</literal></entry>
+ <entry>Waiting for an elected Parallel Hash participant to allocate the
+ initial hash table.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBuildElect</literal></entry>
+ <entry>Waiting to elect a Parallel Hash participant to allocate the
+ initial hash table.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBuildHashInner</literal></entry>
+ <entry>Waiting for other Parallel Hash participants to finish hashing the
+ inner relation.</entry>
+ </row>
+ <row>
+ <entry><literal>HashBuildHashOuter</literal></entry>
+ <entry>Waiting for other Parallel Hash participants to finish partitioning
+ the outer relation.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBatchesAllocate</literal></entry>
+ <entry>Waiting for an elected Parallel Hash participant to allocate more
+ batches.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBatchesDecide</literal></entry>
+ <entry>Waiting to elect a Parallel Hash participant to decide on future
+ batch growth.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBatchesElect</literal></entry>
+ <entry>Waiting to elect a Parallel Hash participant to allocate more
+ batches.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBatchesFinish</literal></entry>
+ <entry>Waiting for an elected Parallel Hash participant to decide on
+ future batch growth.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBatchesRepartition</literal></entry>
+ <entry>Waiting for other Parallel Hash participants to finish
+ repartitioning.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBucketsAllocate</literal></entry>
+ <entry>Waiting for an elected Parallel Hash participant to finish
+ allocating more buckets.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBucketsElect</literal></entry>
+ <entry>Waiting to elect a Parallel Hash participant to allocate more
+ buckets.</entry>
+ </row>
+ <row>
+ <entry><literal>HashGrowBucketsReinsert</literal></entry>
+ <entry>Waiting for other Parallel Hash participants to finish inserting
+ tuples into new buckets.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalSyncData</literal></entry>
+ <entry>Waiting for a logical replication remote server to send data for
+ initial table synchronization.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalSyncStateChange</literal></entry>
+ <entry>Waiting for a logical replication remote server to change
+ state.</entry>
+ </row>
+ <row>
+ <entry><literal>MessageQueueInternal</literal></entry>
+ <entry>Waiting for another process to be attached to a shared message
+ queue.</entry>
+ </row>
+ <row>
+ <entry><literal>MessageQueuePutMessage</literal></entry>
+ <entry>Waiting to write a protocol message to a shared message queue.</entry>
+ </row>
+ <row>
+ <entry><literal>MessageQueueReceive</literal></entry>
+ <entry>Waiting to receive bytes from a shared message queue.</entry>
+ </row>
+ <row>
+ <entry><literal>MessageQueueSend</literal></entry>
+ <entry>Waiting to send bytes to a shared message queue.</entry>
+ </row>
+ <row>
+ <entry><literal>ParallelBitmapScan</literal></entry>
+ <entry>Waiting for parallel bitmap scan to become initialized.</entry>
+ </row>
+ <row>
+ <entry><literal>ParallelCreateIndexScan</literal></entry>
+ <entry>Waiting for parallel <command>CREATE INDEX</command> workers to
+ finish heap scan.</entry>
+ </row>
+ <row>
+ <entry><literal>ParallelFinish</literal></entry>
+ <entry>Waiting for parallel workers to finish computing.</entry>
+ </row>
+ <row>
+ <entry><literal>ProcArrayGroupUpdate</literal></entry>
+ <entry>Waiting for the group leader to clear the transaction ID at
+ end of a parallel operation.</entry>
+ </row>
+ <row>
+ <entry><literal>ProcSignalBarrier</literal></entry>
+ <entry>Waiting for a barrier event to be processed by all
+ backends.</entry>
+ </row>
+ <row>
+ <entry><literal>Promote</literal></entry>
+ <entry>Waiting for standby promotion.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryConflictSnapshot</literal></entry>
+ <entry>Waiting for recovery conflict resolution for a vacuum
+ cleanup.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryConflictTablespace</literal></entry>
+ <entry>Waiting for recovery conflict resolution for dropping a
+ tablespace.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryEndCommand</literal></entry>
+ <entry>Waiting for <xref linkend="guc-recovery-end-command"/> to
+ complete.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryPause</literal></entry>
+ <entry>Waiting for recovery to be resumed.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationOriginDrop</literal></entry>
+ <entry>Waiting for a replication origin to become inactive so it can be
+ dropped.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotDrop</literal></entry>
+ <entry>Waiting for a replication slot to become inactive so it can be
+ dropped.</entry>
+ </row>
+ <row>
+ <entry><literal>RestoreCommand</literal></entry>
+ <entry>Waiting for <xref linkend="guc-restore-command"/> to
+ complete.</entry>
+ </row>
+ <row>
+ <entry><literal>SafeSnapshot</literal></entry>
+ <entry>Waiting to obtain a valid snapshot for a <literal>READ ONLY
+ DEFERRABLE</literal> transaction.</entry>
+ </row>
+ <row>
+ <entry><literal>SyncRep</literal></entry>
+ <entry>Waiting for confirmation from a remote server during synchronous
+ replication.</entry>
+ </row>
+ <row>
+ <entry><literal>WalReceiverExit</literal></entry>
+ <entry>Waiting for the WAL receiver to exit.</entry>
+ </row>
+ <row>
+ <entry><literal>WalReceiverWaitStart</literal></entry>
+ <entry>Waiting for startup process to send initial data for streaming
+ replication.</entry>
+ </row>
+ <row>
+ <entry><literal>XactGroupUpdate</literal></entry>
+ <entry>Waiting for the group leader to update transaction status at
+ end of a parallel operation.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-lock-table">
+ <title>Wait Events of Type <literal>Lock</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>Lock</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>advisory</literal></entry>
+ <entry>Waiting to acquire an advisory user lock.</entry>
+ </row>
+ <row>
+ <entry><literal>extend</literal></entry>
+ <entry>Waiting to extend a relation.</entry>
+ </row>
+ <row>
+ <entry><literal>frozenid</literal></entry>
+ <entry>Waiting to
+ update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield>
+ and <structname>pg_database</structname>.<structfield>datminmxid</structfield>.</entry>
+ </row>
+ <row>
+ <entry><literal>object</literal></entry>
+ <entry>Waiting to acquire a lock on a non-relation database object.</entry>
+ </row>
+ <row>
+ <entry><literal>page</literal></entry>
+ <entry>Waiting to acquire a lock on a page of a relation.</entry>
+ </row>
+ <row>
+ <entry><literal>relation</literal></entry>
+ <entry>Waiting to acquire a lock on a relation.</entry>
+ </row>
+ <row>
+ <entry><literal>spectoken</literal></entry>
+ <entry>Waiting to acquire a speculative insertion lock.</entry>
+ </row>
+ <row>
+ <entry><literal>transactionid</literal></entry>
+ <entry>Waiting for a transaction to finish.</entry>
+ </row>
+ <row>
+ <entry><literal>tuple</literal></entry>
+ <entry>Waiting to acquire a lock on a tuple.</entry>
+ </row>
+ <row>
+ <entry><literal>userlock</literal></entry>
+ <entry>Waiting to acquire a user lock.</entry>
+ </row>
+ <row>
+ <entry><literal>virtualxid</literal></entry>
+ <entry>Waiting to acquire a virtual transaction ID lock.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="wait-event-lwlock-table">
+ <title>Wait Events of Type <literal>LWLock</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>LWLock</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>AddinShmemInit</literal></entry>
+ <entry>Waiting to manage an extension's space allocation in shared
+ memory.</entry>
+ </row>
+ <row>
+ <entry><literal>AutoFile</literal></entry>
+ <entry>Waiting to update the <filename>postgresql.auto.conf</filename>
+ file.</entry>
+ </row>
+ <row>
+ <entry><literal>Autovacuum</literal></entry>
+ <entry>Waiting to read or update the current state of autovacuum
+ workers.</entry>
+ </row>
+ <row>
+ <entry><literal>AutovacuumSchedule</literal></entry>
+ <entry>Waiting to ensure that a table selected for autovacuum
+ still needs vacuuming.</entry>
+ </row>
+ <row>
+ <entry><literal>BackgroundWorker</literal></entry>
+ <entry>Waiting to read or update background worker state.</entry>
+ </row>
+ <row>
+ <entry><literal>BtreeVacuum</literal></entry>
+ <entry>Waiting to read or update vacuum-related information for a
+ B-tree index.</entry>
+ </row>
+ <row>
+ <entry><literal>BufferContent</literal></entry>
+ <entry>Waiting to access a data page in memory.</entry>
+ </row>
+ <row>
+ <entry><literal>BufferMapping</literal></entry>
+ <entry>Waiting to associate a data block with a buffer in the buffer
+ pool.</entry>
+ </row>
+ <row>
+ <entry><literal>CheckpointerComm</literal></entry>
+ <entry>Waiting to manage fsync requests.</entry>
+ </row>
+ <row>
+ <entry><literal>CommitTs</literal></entry>
+ <entry>Waiting to read or update the last value set for a
+ transaction commit timestamp.</entry>
+ </row>
+ <row>
+ <entry><literal>CommitTsBuffer</literal></entry>
+ <entry>Waiting for I/O on a commit timestamp SLRU buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>CommitTsSLRU</literal></entry>
+ <entry>Waiting to access the commit timestamp SLRU cache.</entry>
+ </row>
+ <row>
+ <entry><literal>ControlFile</literal></entry>
+ <entry>Waiting to read or update the <filename>pg_control</filename>
+ file or create a new WAL file.</entry>
+ </row>
+ <row>
+ <entry><literal>DynamicSharedMemoryControl</literal></entry>
+ <entry>Waiting to read or update dynamic shared memory allocation
+ information.</entry>
+ </row>
+ <row>
+ <entry><literal>LockFastPath</literal></entry>
+ <entry>Waiting to read or update a process' fast-path lock
+ information.</entry>
+ </row>
+ <row>
+ <entry><literal>LockManager</literal></entry>
+ <entry>Waiting to read or update information
+ about <quote>heavyweight</quote> locks.</entry>
+ </row>
+ <row>
+ <entry><literal>LogicalRepWorker</literal></entry>
+ <entry>Waiting to read or update the state of logical replication
+ workers.</entry>
+ </row>
+ <row>
+ <entry><literal>MultiXactGen</literal></entry>
+ <entry>Waiting to read or update shared multixact state.</entry>
+ </row>
+ <row>
+ <entry><literal>MultiXactMemberBuffer</literal></entry>
+ <entry>Waiting for I/O on a multixact member SLRU buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>MultiXactMemberSLRU</literal></entry>
+ <entry>Waiting to access the multixact member SLRU cache.</entry>
+ </row>
+ <row>
+ <entry><literal>MultiXactOffsetBuffer</literal></entry>
+ <entry>Waiting for I/O on a multixact offset SLRU buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>MultiXactOffsetSLRU</literal></entry>
+ <entry>Waiting to access the multixact offset SLRU cache.</entry>
+ </row>
+ <row>
+ <entry><literal>MultiXactTruncation</literal></entry>
+ <entry>Waiting to read or truncate multixact information.</entry>
+ </row>
+ <row>
+ <entry><literal>NotifyBuffer</literal></entry>
+ <entry>Waiting for I/O on a <command>NOTIFY</command> message SLRU
+ buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>NotifyQueue</literal></entry>
+ <entry>Waiting to read or update <command>NOTIFY</command> messages.</entry>
+ </row>
+ <row>
+ <entry><literal>NotifyQueueTail</literal></entry>
+ <entry>Waiting to update limit on <command>NOTIFY</command> message
+ storage.</entry>
+ </row>
+ <row>
+ <entry><literal>NotifySLRU</literal></entry>
+ <entry>Waiting to access the <command>NOTIFY</command> message SLRU
+ cache.</entry>
+ </row>
+ <row>
+ <entry><literal>OidGen</literal></entry>
+ <entry>Waiting to allocate a new OID.</entry>
+ </row>
+ <row>
+ <entry><literal>OldSnapshotTimeMap</literal></entry>
+ <entry>Waiting to read or update old snapshot control information.</entry>
+ </row>
+ <row>
+ <entry><literal>ParallelAppend</literal></entry>
+ <entry>Waiting to choose the next subplan during Parallel Append plan
+ execution.</entry>
+ </row>
+ <row>
+ <entry><literal>ParallelHashJoin</literal></entry>
+ <entry>Waiting to synchronize workers during Parallel Hash Join plan
+ execution.</entry>
+ </row>
+ <row>
+ <entry><literal>ParallelQueryDSA</literal></entry>
+ <entry>Waiting for parallel query dynamic shared memory allocation.</entry>
+ </row>
+ <row>
+ <entry><literal>PerSessionDSA</literal></entry>
+ <entry>Waiting for parallel query dynamic shared memory allocation.</entry>
+ </row>
+ <row>
+ <entry><literal>PerSessionRecordType</literal></entry>
+ <entry>Waiting to access a parallel query's information about composite
+ types.</entry>
+ </row>
+ <row>
+ <entry><literal>PerSessionRecordTypmod</literal></entry>
+ <entry>Waiting to access a parallel query's information about type
+ modifiers that identify anonymous record types.</entry>
+ </row>
+ <row>
+ <entry><literal>PerXactPredicateList</literal></entry>
+ <entry>Waiting to access the list of predicate locks held by the current
+ serializable transaction during a parallel query.</entry>
+ </row>
+ <row>
+ <entry><literal>PredicateLockManager</literal></entry>
+ <entry>Waiting to access predicate lock information used by
+ serializable transactions.</entry>
+ </row>
+ <row>
+ <entry><literal>ProcArray</literal></entry>
+ <entry>Waiting to access the shared per-process data structures
+ (typically, to get a snapshot or report a session's transaction
+ ID).</entry>
+ </row>
+ <row>
+ <entry><literal>RelationMapping</literal></entry>
+ <entry>Waiting to read or update
+ a <filename>pg_filenode.map</filename> file (used to track the
+ filenode assignments of certain system catalogs).</entry>
+ </row>
+ <row>
+ <entry><literal>RelCacheInit</literal></entry>
+ <entry>Waiting to read or update a <filename>pg_internal.init</filename>
+ relation cache initialization file.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationOrigin</literal></entry>
+ <entry>Waiting to create, drop or use a replication origin.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationOriginState</literal></entry>
+ <entry>Waiting to read or update the progress of one replication
+ origin.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotAllocation</literal></entry>
+ <entry>Waiting to allocate or free a replication slot.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotControl</literal></entry>
+ <entry>Waiting to read or update replication slot state.</entry>
+ </row>
+ <row>
+ <entry><literal>ReplicationSlotIO</literal></entry>
+ <entry>Waiting for I/O on a replication slot.</entry>
+ </row>
+ <row>
+ <entry><literal>SerialBuffer</literal></entry>
+ <entry>Waiting for I/O on a serializable transaction conflict SLRU
+ buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>SerializableFinishedList</literal></entry>
+ <entry>Waiting to access the list of finished serializable
+ transactions.</entry>
+ </row>
+ <row>
+ <entry><literal>SerializablePredicateList</literal></entry>
+ <entry>Waiting to access the list of predicate locks held by
+ serializable transactions.</entry>
+ </row>
+ <row>
+ <entry><literal>PgStatsDSA</literal></entry>
+ <entry>Waiting for stats dynamic shared memory allocator access</entry>
+ </row>
+ <row>
+ <entry><literal>PgStatsHash</literal></entry>
+ <entry>Waiting for stats shared memory hash table access</entry>
+ </row>
+ <row>
+ <entry><literal>PgStatsData</literal></entry>
+ <entry>Waiting for shared memory stats data access</entry>
+ </row>
+ <row>
+ <entry><literal>SerializableXactHash</literal></entry>
+ <entry>Waiting to read or update information about serializable
+ transactions.</entry>
+ </row>
+ <row>
+ <entry><literal>SerialSLRU</literal></entry>
+ <entry>Waiting to access the serializable transaction conflict SLRU
+ cache.</entry>
+ </row>
+ <row>
+ <entry><literal>SharedTidBitmap</literal></entry>
+ <entry>Waiting to access a shared TID bitmap during a parallel bitmap
+ index scan.</entry>
+ </row>
+ <row>
+ <entry><literal>SharedTupleStore</literal></entry>
+ <entry>Waiting to access a shared tuple store during parallel
+ query.</entry>
+ </row>
+ <row>
+ <entry><literal>ShmemIndex</literal></entry>
+ <entry>Waiting to find or allocate space in shared memory.</entry>
+ </row>
+ <row>
+ <entry><literal>SInvalRead</literal></entry>
+ <entry>Waiting to retrieve messages from the shared catalog invalidation
+ queue.</entry>
+ </row>
+ <row>
+ <entry><literal>SInvalWrite</literal></entry>
+ <entry>Waiting to add a message to the shared catalog invalidation
+ queue.</entry>
+ </row>
+ <row>
+ <entry><literal>SubtransBuffer</literal></entry>
+ <entry>Waiting for I/O on a sub-transaction SLRU buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>SubtransSLRU</literal></entry>
+ <entry>Waiting to access the sub-transaction SLRU cache.</entry>
+ </row>
+ <row>
+ <entry><literal>SyncRep</literal></entry>
+ <entry>Waiting to read or update information about the state of
+ synchronous replication.</entry>
+ </row>
+ <row>
+ <entry><literal>SyncScan</literal></entry>
+ <entry>Waiting to select the starting location of a synchronized table
+ scan.</entry>
+ </row>
+ <row>
+ <entry><literal>TablespaceCreate</literal></entry>
+ <entry>Waiting to create or drop a tablespace.</entry>
+ </row>
+ <row>
+ <entry><literal>TwoPhaseState</literal></entry>
+ <entry>Waiting to read or update the state of prepared transactions.</entry>
+ </row>
+ <row>
+ <entry><literal>WALBufMapping</literal></entry>
+ <entry>Waiting to replace a page in WAL buffers.</entry>
+ </row>
+ <row>
+ <entry><literal>WALInsert</literal></entry>
+ <entry>Waiting to insert WAL data into a memory buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>WALWrite</literal></entry>
+ <entry>Waiting for WAL buffers to be written to disk.</entry>
+ </row>
+ <row>
+ <entry><literal>WrapLimitsVacuum</literal></entry>
+ <entry>Waiting to update limits on transaction id and multixact
+ consumption.</entry>
+ </row>
+ <row>
+ <entry><literal>XactBuffer</literal></entry>
+ <entry>Waiting for I/O on a transaction status SLRU buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>XactSLRU</literal></entry>
+ <entry>Waiting to access the transaction status SLRU cache.</entry>
+ </row>
+ <row>
+ <entry><literal>XactTruncation</literal></entry>
+ <entry>Waiting to execute <function>pg_xact_status</function> or update
+ the oldest transaction ID available to it.</entry>
+ </row>
+ <row>
+ <entry><literal>XidGen</literal></entry>
+ <entry>Waiting to allocate a new transaction ID.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ Extensions can add <literal>LWLock</literal> types to the list shown in
+ <xref linkend="wait-event-lwlock-table"/>. In some cases, the name
+ assigned by an extension will not be available in all server processes;
+ so an <literal>LWLock</literal> wait event might be reported as
+ just <quote><literal>extension</literal></quote> rather than the
+ extension-assigned name.
+ </para>
+ </note>
+
+ <table id="wait-event-timeout-table">
+ <title>Wait Events of Type <literal>Timeout</literal></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry><literal>Timeout</literal> Wait Event</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>BaseBackupThrottle</literal></entry>
+ <entry>Waiting during base backup when throttling activity.</entry>
+ </row>
+ <row>
+ <entry><literal>CheckpointWriteDelay</literal></entry>
+ <entry>Waiting between writes while performing a checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>PgSleep</literal></entry>
+ <entry>Waiting due to a call to <function>pg_sleep</function> or
+ a sibling function.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryApplyDelay</literal></entry>
+ <entry>Waiting to apply WAL during recovery because of a delay
+ setting.</entry>
+ </row>
+ <row>
+ <entry><literal>RecoveryRetrieveRetryInterval</literal></entry>
+ <entry>Waiting during recovery when WAL data is not available from any
+ source (<filename>pg_wal</filename>, archive or stream).</entry>
+ </row>
+ <row>
+ <entry><literal>RegisterSyncRequest</literal></entry>
+ <entry>Waiting while sending synchronization requests to the
+ checkpointer, because the request queue is full.</entry>
+ </row>
+ <row>
+ <entry><literal>VacuumDelay</literal></entry>
+ <entry>Waiting in a cost-based vacuum delay point.</entry>
+ </row>
+ <row>
+ <entry><literal>VacuumTruncate</literal></entry>
+ <entry>Waiting to acquire an exclusive lock to truncate off any
+ empty pages at the end of a table vacuumed.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Here is an example of how wait events can be viewed:
+
+<programlisting>
+SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event is NOT NULL;
+ pid | wait_event_type | wait_event
+------+-----------------+------------
+ 2540 | Lock | relation
+ 6644 | LWLock | ProcArray
+(2 rows)
+</programlisting>
+ </para>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-replication-view">
+ <title><structname>pg_stat_replication</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_replication</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_replication</structname> view will contain one row
+ per WAL sender process, showing statistics about replication to that
+ sender's connected standby server. Only directly connected standbys are
+ listed; no information is available about downstream standby servers.
+ </para>
+
+ <table id="pg-stat-replication-view" xreflabel="pg_stat_replication">
+ <title><structname>pg_stat_replication</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of a WAL sender process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usesysid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the user logged into this WAL sender process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usename</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the user logged into this WAL sender process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>application_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the application that is connected
+ to this WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_addr</structfield> <type>inet</type>
+ </para>
+ <para>
+ IP address of the client connected to this WAL sender.
+ If this field is null, it indicates that the client is
+ connected via a Unix socket on the server machine.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_hostname</structfield> <type>text</type>
+ </para>
+ <para>
+ Host name of the connected client, as reported by a
+ reverse DNS lookup of <structfield>client_addr</structfield>. This field will
+ only be non-null for IP connections, and only when <xref linkend="guc-log-hostname"/> is enabled.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_port</structfield> <type>integer</type>
+ </para>
+ <para>
+ TCP port number that the client is using for communication
+ with this WAL sender, or <literal>-1</literal> if a Unix socket is used
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backend_start</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time when this process was started, i.e., when the
+ client connected to this WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backend_xmin</structfield> <type>xid</type>
+ </para>
+ <para>
+ This standby's <literal>xmin</literal> horizon reported
+ by <xref linkend="guc-hot-standby-feedback"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>state</structfield> <type>text</type>
+ </para>
+ <para>
+ Current WAL sender state.
+ Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>startup</literal>: This WAL sender is starting up.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>catchup</literal>: This WAL sender's connected standby is
+ catching up with the primary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>streaming</literal>: This WAL sender is streaming changes
+ after its connected standby server has caught up with the primary.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>backup</literal>: This WAL sender is sending a backup.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>stopping</literal>: This WAL sender is stopping.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sent_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location sent on this connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>write_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location written to disk by this standby
+ server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>flush_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location flushed to disk by this standby
+ server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>replay_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location replayed into the database on this
+ standby server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>write_lag</structfield> <type>interval</type>
+ </para>
+ <para>
+ Time elapsed between flushing recent WAL locally and receiving
+ notification that this standby server has written it (but not yet
+ flushed it or applied it). This can be used to gauge the delay that
+ <literal>synchronous_commit</literal> level
+ <literal>remote_write</literal> incurred while committing if this
+ server was configured as a synchronous standby.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>flush_lag</structfield> <type>interval</type>
+ </para>
+ <para>
+ Time elapsed between flushing recent WAL locally and receiving
+ notification that this standby server has written and flushed it
+ (but not yet applied it). This can be used to gauge the delay that
+ <literal>synchronous_commit</literal> level
+ <literal>on</literal> incurred while committing if this
+ server was configured as a synchronous standby.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>replay_lag</structfield> <type>interval</type>
+ </para>
+ <para>
+ Time elapsed between flushing recent WAL locally and receiving
+ notification that this standby server has written, flushed and
+ applied it. This can be used to gauge the delay that
+ <literal>synchronous_commit</literal> level
+ <literal>remote_apply</literal> incurred while committing if this
+ server was configured as a synchronous standby.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sync_priority</structfield> <type>integer</type>
+ </para>
+ <para>
+ Priority of this standby server for being chosen as the
+ synchronous standby in a priority-based synchronous replication.
+ This has no effect in a quorum-based synchronous replication.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sync_state</structfield> <type>text</type>
+ </para>
+ <para>
+ Synchronous state of this standby server.
+ Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>async</literal>: This standby server is asynchronous.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>potential</literal>: This standby server is now asynchronous,
+ but can potentially become synchronous if one of current
+ synchronous ones fails.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>sync</literal>: This standby server is synchronous.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>quorum</literal>: This standby server is considered as a candidate
+ for quorum standbys.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reply_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Send time of last reply message received from standby server
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The lag times reported in the <structname>pg_stat_replication</structname>
+ view are measurements of the time taken for recent WAL to be written,
+ flushed and replayed and for the sender to know about it. These times
+ represent the commit delay that was (or would have been) introduced by each
+ synchronous commit level, if the remote server was configured as a
+ synchronous standby. For an asynchronous standby, the
+ <structfield>replay_lag</structfield> column approximates the delay
+ before recent transactions became visible to queries. If the standby
+ server has entirely caught up with the sending server and there is no more
+ WAL activity, the most recently measured lag times will continue to be
+ displayed for a short time and then show NULL.
+ </para>
+
+ <para>
+ Lag times work automatically for physical replication. Logical decoding
+ plugins may optionally emit tracking messages; if they do not, the tracking
+ mechanism will simply display NULL lag.
+ </para>
+
+ <note>
+ <para>
+ The reported lag times are not predictions of how long it will take for
+ the standby to catch up with the sending server assuming the current
+ rate of replay. Such a system would show similar times while new WAL is
+ being generated, but would differ when the sender becomes idle. In
+ particular, when the standby has caught up completely,
+ <structname>pg_stat_replication</structname> shows the time taken to
+ write, flush and replay the most recent reported WAL location rather than
+ zero as some users might expect. This is consistent with the goal of
+ measuring synchronous commit and transaction visibility delays for
+ recent write transactions.
+ To reduce confusion for users expecting a different model of lag, the
+ lag columns revert to NULL after a short time on a fully replayed idle
+ system. Monitoring systems should choose whether to represent this
+ as missing data, zero or continue to display the last known value.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-replication-slots-view">
+ <title><structname>pg_stat_replication_slots</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_replication_slots</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_replication_slots</structname> view will contain
+ one row per logical replication slot, showing statistics about its usage.
+ </para>
+
+ <table id="pg-stat-replication-slots-view" xreflabel="pg_stat_replication_slots">
+ <title><structname>pg_stat_replication_slots</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slot_name</structfield> <type>text</type>
+ </para>
+ <para>
+ A unique, cluster-wide identifier for the replication slot
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spill_txns</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of transactions spilled to disk once the memory used by
+ logical decoding to decode changes from WAL has exceeded
+ <literal>logical_decoding_work_mem</literal>. The counter gets
+ incremented for both top-level transactions and subtransactions.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spill_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times transactions were spilled to disk while decoding
+ changes from WAL for this slot. This counter is incremented each time
+ a transaction is spilled, and the same transaction may be spilled
+ multiple times.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>spill_bytes</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Amount of decoded transaction data spilled to disk while performing
+ decoding of changes from WAL for this slot. This and other spill
+ counters can be used to gauge the I/O which occurred during logical
+ decoding and allow tuning <literal>logical_decoding_work_mem</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stream_txns</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of in-progress transactions streamed to the decoding output
+ plugin after the memory used by logical decoding to decode changes
+ from WAL for this slot has exceeded
+ <literal>logical_decoding_work_mem</literal>. Streaming only
+ works with top-level transactions (subtransactions can't be streamed
+ independently), so the counter is not incremented for subtransactions.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stream_count</structfield><type>bigint</type>
+ </para>
+ <para>
+ Number of times in-progress transactions were streamed to the decoding
+ output plugin while decoding changes from WAL for this slot. This
+ counter is incremented each time a transaction is streamed, and the
+ same transaction may be streamed multiple times.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stream_bytes</structfield><type>bigint</type>
+ </para>
+ <para>
+ Amount of transaction data decoded for streaming in-progress
+ transactions to the decoding output plugin while decoding changes from
+ WAL for this slot. This and other streaming counters for this slot can
+ be used to tune <literal>logical_decoding_work_mem</literal>.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_txns</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of decoded transactions sent to the decoding output plugin for
+ this slot. This counts top-level transactions only, and is not incremented
+ for subtransactions. Note that this includes the transactions that are
+ streamed and/or spilled.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_bytes</structfield><type>bigint</type>
+ </para>
+ <para>
+ Amount of transaction data decoded for sending transactions to the
+ decoding output plugin while decoding changes from WAL for this slot.
+ Note that this includes data that is streamed and/or spilled.
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-wal-receiver-view">
+ <title><structname>pg_stat_wal_receiver</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_wal_receiver</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_wal_receiver</structname> view will contain only
+ one row, showing statistics about the WAL receiver from that receiver's
+ connected server.
+ </para>
+
+ <table id="pg-stat-wal-receiver-view" xreflabel="pg_stat_wal_receiver">
+ <title><structname>pg_stat_wal_receiver</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of the WAL receiver process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>status</structfield> <type>text</type>
+ </para>
+ <para>
+ Activity status of the WAL receiver process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>receive_start_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ First write-ahead log location used when WAL receiver is
+ started
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>receive_start_tli</structfield> <type>integer</type>
+ </para>
+ <para>
+ First timeline number used when WAL receiver is started
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>written_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location already received and written to disk,
+ but not flushed. This should not be used for data integrity checks.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>flushed_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location already received and flushed to
+ disk, the initial value of this field being the first log location used
+ when WAL receiver is started
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>received_tli</structfield> <type>integer</type>
+ </para>
+ <para>
+ Timeline number of last write-ahead log location received and
+ flushed to disk, the initial value of this field being the timeline
+ number of the first log location used when WAL receiver is started
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_msg_send_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Send time of last message received from origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_msg_receipt_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Receipt time of last message received from origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>latest_end_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location reported to origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>latest_end_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time of last write-ahead log location reported to origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slot_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Replication slot name used by this WAL receiver
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sender_host</structfield> <type>text</type>
+ </para>
+ <para>
+ Host of the <productname>PostgreSQL</productname> instance
+ this WAL receiver is connected to. This can be a host name,
+ an IP address, or a directory path if the connection is via
+ Unix socket. (The path case can be distinguished because it
+ will always be an absolute path, beginning with <literal>/</literal>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sender_port</structfield> <type>integer</type>
+ </para>
+ <para>
+ Port number of the <productname>PostgreSQL</productname> instance
+ this WAL receiver is connected to.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conninfo</structfield> <type>text</type>
+ </para>
+ <para>
+ Connection string used by this WAL receiver,
+ with security-sensitive fields obfuscated.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-recovery-prefetch">
+ <title><structname>pg_stat_recovery_prefetch</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_recovery_prefetch</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_recovery_prefetch</structname> view will contain
+ only one row. The columns <structfield>wal_distance</structfield>,
+ <structfield>block_distance</structfield> and
+ <structfield>io_depth</structfield> show current values, and the
+ other columns show cumulative counters that can be reset
+ with the <function>pg_stat_reset_shared</function> function.
+ </para>
+
+ <table id="pg-stat-recovery-prefetch-view" xreflabel="pg_stat_recovery_prefetch">
+ <title><structname>pg_stat_recovery_prefetch</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>prefetch</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks prefetched because they were not in the buffer pool
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks not prefetched because they were already in the buffer pool
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>skip_init</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks not prefetched because they would be zero-initialized
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>skip_new</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks not prefetched because they didn't exist yet
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>skip_fpw</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks not prefetched because a full page image was included in the WAL
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>skip_rep</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks not prefetched because they were already recently prefetched
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>wal_distance</structfield> <type>int</type>
+ </para>
+ <para>
+ How many bytes ahead the prefetcher is looking
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>block_distance</structfield> <type>int</type>
+ </para>
+ <para>
+ How many blocks ahead the prefetcher is looking
+ </para>
+ </entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry">
+ <para role="column_definition">
+ <structfield>io_depth</structfield> <type>int</type>
+ </para>
+ <para>
+ How many prefetches have been initiated but are not yet known to have completed
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-subscription">
+ <title><structname>pg_stat_subscription</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_subscription</primary>
+ </indexterm>
+
+ <table id="pg-stat-subscription" xreflabel="pg_stat_subscription">
+ <title><structname>pg_stat_subscription</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of the subscription worker process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the relation that the worker is synchronizing; null for the
+ main apply worker
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>received_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location received, the initial value of
+ this field being 0
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_msg_send_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Send time of last message received from origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_msg_receipt_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Receipt time of last message received from origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>latest_end_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ Last write-ahead log location reported to origin WAL sender
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>latest_end_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time of last write-ahead log location reported to origin WAL
+ sender
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-subscription-stats">
+ <title><structname>pg_stat_subscription_stats</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_subscription_stats</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_subscription_stats</structname> view will contain
+ one row per subscription.
+ </para>
+
+ <table id="pg-stat-subscription-stats" xreflabel="pg_stat_subscription_stats">
+ <title><structname>pg_stat_subscription_stats</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>subname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the subscription
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>apply_error_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times an error occurred while applying changes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sync_error_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times an error occurred during the initial table
+ synchronization
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-ssl-view">
+ <title><structname>pg_stat_ssl</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_ssl</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_ssl</structname> view will contain one row per
+ backend or WAL sender process, showing statistics about SSL usage on
+ this connection. It can be joined to <structname>pg_stat_activity</structname>
+ or <structname>pg_stat_replication</structname> on the
+ <structfield>pid</structfield> column to get more details about the
+ connection.
+ </para>
+
+ <table id="pg-stat-ssl-view" xreflabel="pg_stat_ssl">
+ <title><structname>pg_stat_ssl</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of a backend or WAL sender process
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ssl</structfield> <type>boolean</type>
+ </para>
+ <para>
+ True if SSL is used on this connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>version</structfield> <type>text</type>
+ </para>
+ <para>
+ Version of SSL in use, or NULL if SSL is not in use
+ on this connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cipher</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of SSL cipher in use, or NULL if SSL is not in use
+ on this connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>bits</structfield> <type>integer</type>
+ </para>
+ <para>
+ Number of bits in the encryption algorithm used, or NULL
+ if SSL is not used on this connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_dn</structfield> <type>text</type>
+ </para>
+ <para>
+ Distinguished Name (DN) field from the client certificate
+ used, or NULL if no client certificate was supplied or if SSL
+ is not in use on this connection. This field is truncated if the
+ DN field is longer than <symbol>NAMEDATALEN</symbol> (64 characters
+ in a standard build).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>client_serial</structfield> <type>numeric</type>
+ </para>
+ <para>
+ Serial number of the client certificate, or NULL if no client
+ certificate was supplied or if SSL is not in use on this connection. The
+ combination of certificate serial number and certificate issuer uniquely
+ identifies a certificate (unless the issuer erroneously reuses serial
+ numbers).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>issuer_dn</structfield> <type>text</type>
+ </para>
+ <para>
+ DN of the issuer of the client certificate, or NULL if no client
+ certificate was supplied or if SSL is not in use on this connection.
+ This field is truncated like <structfield>client_dn</structfield>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-gssapi-view">
+ <title><structname>pg_stat_gssapi</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_gssapi</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_gssapi</structname> view will contain one row per
+ backend, showing information about GSSAPI usage on this connection. It can
+ be joined to <structname>pg_stat_activity</structname> or
+ <structname>pg_stat_replication</structname> on the
+ <structfield>pid</structfield> column to get more details about the
+ connection.
+ </para>
+
+ <table id="pg-stat-gssapi-view" xreflabel="pg_stat_gssapi">
+ <title><structname>pg_stat_gssapi</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of a backend
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>gss_authenticated</structfield> <type>boolean</type>
+ </para>
+ <para>
+ True if GSSAPI authentication was used for this connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>principal</structfield> <type>text</type>
+ </para>
+ <para>
+ Principal used to authenticate this connection, or NULL
+ if GSSAPI was not used to authenticate this connection. This
+ field is truncated if the principal is longer than
+ <symbol>NAMEDATALEN</symbol> (64 characters in a standard build).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>encrypted</structfield> <type>boolean</type>
+ </para>
+ <para>
+ True if GSSAPI encryption is in use on this connection
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-archiver-view">
+ <title><structname>pg_stat_archiver</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_archiver</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_archiver</structname> view will always have a
+ single row, containing data about the archiver process of the cluster.
+ </para>
+
+ <table id="pg-stat-archiver-view" xreflabel="pg_stat_archiver">
+ <title><structname>pg_stat_archiver</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>archived_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of WAL files that have been successfully archived
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_archived_wal</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the WAL file most recently successfully archived
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_archived_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time of the most recent successful archive operation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>failed_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of failed attempts for archiving WAL files
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_failed_wal</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the WAL file of the most recent failed archival operation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_failed_time</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time of the most recent failed archival operation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Normally, WAL files are archived in order, oldest to newest, but that is
+ not guaranteed, and does not hold under special circumstances like when
+ promoting a standby or after crash recovery. Therefore it is not safe to
+ assume that all files older than
+ <structfield>last_archived_wal</structfield> have also been successfully
+ archived.
+ </para>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-bgwriter-view">
+ <title><structname>pg_stat_bgwriter</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_bgwriter</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_bgwriter</structname> view will always have a
+ single row, containing global data for the cluster.
+ </para>
+
+ <table id="pg-stat-bgwriter-view" xreflabel="pg_stat_bgwriter">
+ <title><structname>pg_stat_bgwriter</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>checkpoints_timed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of scheduled checkpoints that have been performed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>checkpoints_req</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of requested checkpoints that have been performed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>checkpoint_write_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total amount of time that has been spent in the portion of
+ checkpoint processing where files are written to disk, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>checkpoint_sync_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total amount of time that has been spent in the portion of
+ checkpoint processing where files are synchronized to disk, in
+ milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>buffers_checkpoint</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffers written during checkpoints
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>buffers_clean</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffers written by the background writer
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>maxwritten_clean</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times the background writer stopped a cleaning
+ scan because it had written too many buffers
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>buffers_backend</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffers written directly by a backend
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>buffers_backend_fsync</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times a backend had to execute its own
+ <function>fsync</function> call (normally the background writer handles those
+ even when the backend does its own write)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>buffers_alloc</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffers allocated
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-wal-view">
+ <title><structname>pg_stat_wal</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_wal</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_wal</structname> view will always have a
+ single row, containing data about WAL activity of the cluster.
+ </para>
+
+ <table id="pg-stat-wal-view" xreflabel="pg_stat_wal">
+ <title><structname>pg_stat_wal</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_records</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of WAL records generated
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_fpi</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of WAL full page images generated
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_bytes</structfield> <type>numeric</type>
+ </para>
+ <para>
+ Total amount of WAL generated in bytes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_buffers_full</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times WAL data was written to disk because WAL buffers became full
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_write</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times WAL buffers were written out to disk via
+ <function>XLogWrite</function> request.
+ See <xref linkend="wal-configuration"/> for more information about
+ the internal WAL function <function>XLogWrite</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_sync</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times WAL files were synced to disk via
+ <function>issue_xlog_fsync</function> request
+ (if <xref linkend="guc-fsync"/> is <literal>on</literal> and
+ <xref linkend="guc-wal-sync-method"/> is either
+ <literal>fdatasync</literal>, <literal>fsync</literal> or
+ <literal>fsync_writethrough</literal>, otherwise zero).
+ See <xref linkend="wal-configuration"/> for more information about
+ the internal WAL function <function>issue_xlog_fsync</function>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_write_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total amount of time spent writing WAL buffers to disk via
+ <function>XLogWrite</function> request, in milliseconds
+ (if <xref linkend="guc-track-wal-io-timing"/> is enabled,
+ otherwise zero). This includes the sync time when
+ <varname>wal_sync_method</varname> is either
+ <literal>open_datasync</literal> or <literal>open_sync</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_sync_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total amount of time spent syncing WAL files to disk via
+ <function>issue_xlog_fsync</function> request, in milliseconds
+ (if <varname>track_wal_io_timing</varname> is enabled,
+ <varname>fsync</varname> is <literal>on</literal>, and
+ <varname>wal_sync_method</varname> is either
+ <literal>fdatasync</literal>, <literal>fsync</literal> or
+ <literal>fsync_writethrough</literal>, otherwise zero).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+</sect2>
+
+ <sect2 id="monitoring-pg-stat-database-view">
+ <title><structname>pg_stat_database</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_database</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_database</structname> view will contain one row
+ for each database in the cluster, plus one for shared objects, showing
+ database-wide statistics.
+ </para>
+
+ <table id="pg-stat-database-view" xreflabel="pg_stat_database">
+ <title><structname>pg_stat_database</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of this database, or 0 for objects belonging to a shared
+ relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this database, or <literal>NULL</literal> for shared
+ objects.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>numbackends</structfield> <type>integer</type>
+ </para>
+ <para>
+ Number of backends currently connected to this database, or
+ <literal>NULL</literal> for shared objects. This is the only column
+ in this view that returns a value reflecting current state; all other
+ columns return the accumulated values since the last reset.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>xact_commit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of transactions in this database that have been
+ committed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>xact_rollback</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of transactions in this database that have been
+ rolled back
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times disk blocks were found already in the buffer
+ cache, so that a read was not necessary (this only includes hits in the
+ PostgreSQL buffer cache, not the operating system's file system cache)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tup_returned</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of live rows fetched by sequential scans and index entries returned by index scans in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tup_fetched</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of live rows fetched by index scans in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tup_inserted</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows inserted by queries in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tup_updated</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows updated by queries in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tup_deleted</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows deleted by queries in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>conflicts</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of queries canceled due to conflicts with recovery
+ in this database. (Conflicts occur only on standby servers; see
+ <link linkend="monitoring-pg-stat-database-conflicts-view">
+ <structname>pg_stat_database_conflicts</structname></link> for details.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temp_files</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of temporary files created by queries in this database.
+ All temporary files are counted, regardless of why the temporary file
+ was created (e.g., sorting or hashing), and regardless of the
+ <xref linkend="guc-log-temp-files"/> setting.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temp_bytes</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total amount of data written to temporary files by queries in
+ this database. All temporary files are counted, regardless of why
+ the temporary file was created, and
+ regardless of the <xref linkend="guc-log-temp-files"/> setting.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>deadlocks</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of deadlocks detected in this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>checksum_failures</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of data page checksum failures detected in this
+ database (or on a shared object), or NULL if data checksums are not
+ enabled.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>checksum_last_failure</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which the last data page checksum failure was detected in
+ this database (or on a shared object), or NULL if data checksums are not
+ enabled.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blk_read_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Time spent reading data file blocks by backends in this database,
+ in milliseconds (if <xref linkend="guc-track-io-timing"/> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blk_write_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Time spent writing data file blocks by backends in this database,
+ in milliseconds (if <xref linkend="guc-track-io-timing"/> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>session_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Time spent by database sessions in this database, in milliseconds
+ (note that statistics are only updated when the state of a session
+ changes, so if sessions have been idle for a long time, this idle time
+ won't be included)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>active_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Time spent executing SQL statements in this database, in milliseconds
+ (this corresponds to the states <literal>active</literal> and
+ <literal>fastpath function call</literal> in
+ <link linkend="monitoring-pg-stat-activity-view">
+ <structname>pg_stat_activity</structname></link>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idle_in_transaction_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Time spent idling while in a transaction in this database, in milliseconds
+ (this corresponds to the states <literal>idle in transaction</literal> and
+ <literal>idle in transaction (aborted)</literal> in
+ <link linkend="monitoring-pg-stat-activity-view">
+ <structname>pg_stat_activity</structname></link>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sessions</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of sessions established to this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sessions_abandoned</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of database sessions to this database that were terminated
+ because connection to the client was lost
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sessions_fatal</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of database sessions to this database that were terminated
+ by fatal errors
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sessions_killed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of database sessions to this database that were terminated
+ by operator intervention
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-database-conflicts-view">
+ <title><structname>pg_stat_database_conflicts</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_database_conflicts</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_database_conflicts</structname> view will contain
+ one row per database, showing database-wide statistics about
+ query cancels occurring due to conflicts with recovery on standby servers.
+ This view will only contain information on standby servers, since
+ conflicts do not occur on primary servers.
+ </para>
+
+ <table id="pg-stat-database-conflicts-view" xreflabel="pg_stat_database_conflicts">
+ <title><structname>pg_stat_database_conflicts</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of a database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this database
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confl_tablespace</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of queries in this database that have been canceled due to
+ dropped tablespaces
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confl_lock</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of queries in this database that have been canceled due to
+ lock timeouts
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confl_snapshot</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of queries in this database that have been canceled due to
+ old snapshots
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confl_bufferpin</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of queries in this database that have been canceled due to
+ pinned buffers
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confl_deadlock</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of queries in this database that have been canceled due to
+ deadlocks
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-all-tables-view">
+ <title><structname>pg_stat_all_tables</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_all_tables</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_all_tables</structname> view will contain
+ one row for each table in the current database (including TOAST
+ tables), showing statistics about accesses to that specific table. The
+ <structname>pg_stat_user_tables</structname> and
+ <structname>pg_stat_sys_tables</structname> views
+ contain the same information,
+ but filtered to only show user and system tables respectively.
+ </para>
+
+ <table id="pg-stat-all-tables-view" xreflabel="pg_stat_all_tables">
+ <title><structname>pg_stat_all_tables</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of a table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema that this table is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seq_scan</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of sequential scans initiated on this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seq_tup_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of live rows fetched by sequential scans
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_scan</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of index scans initiated on this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_tup_fetch</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of live rows fetched by index scans
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_tup_ins</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows inserted
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_tup_upd</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows updated (includes <link linkend="storage-hot">HOT updated rows</link>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_tup_del</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows deleted
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_tup_hot_upd</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of rows HOT updated (i.e., with no separate index
+ update required)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_live_tup</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Estimated number of live rows
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_dead_tup</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Estimated number of dead rows
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_mod_since_analyze</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Estimated number of rows modified since this table was last analyzed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_ins_since_vacuum</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Estimated number of rows inserted since this table was last vacuumed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_vacuum</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Last time at which this table was manually vacuumed
+ (not counting <command>VACUUM FULL</command>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_autovacuum</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Last time at which this table was vacuumed by the autovacuum
+ daemon
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_analyze</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Last time at which this table was manually analyzed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_autoanalyze</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Last time at which this table was analyzed by the autovacuum
+ daemon
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>vacuum_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times this table has been manually vacuumed
+ (not counting <command>VACUUM FULL</command>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>autovacuum_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times this table has been vacuumed by the autovacuum
+ daemon
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>analyze_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times this table has been manually analyzed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>autoanalyze_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times this table has been analyzed by the autovacuum
+ daemon
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-all-indexes-view">
+ <title><structname>pg_stat_all_indexes</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_all_indexes</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_all_indexes</structname> view will contain
+ one row for each index in the current database,
+ showing statistics about accesses to that specific index. The
+ <structname>pg_stat_user_indexes</structname> and
+ <structname>pg_stat_sys_indexes</structname> views
+ contain the same information,
+ but filtered to only show user and system indexes respectively.
+ </para>
+
+ <table id="pg-stat-all-indexes-view" xreflabel="pg_stat_all_indexes">
+ <title><structname>pg_stat_all_indexes</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table for this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexrelid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema this index is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the table for this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexrelname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_scan</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of index scans initiated on this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_tup_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of index entries returned by scans on this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_tup_fetch</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of live table rows fetched by simple index scans using this
+ index
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Indexes can be used by simple index scans, <quote>bitmap</quote> index scans,
+ and the optimizer. In a bitmap scan
+ the output of several indexes can be combined via AND or OR rules,
+ so it is difficult to associate individual heap row fetches
+ with specific indexes when a bitmap scan is used. Therefore, a bitmap
+ scan increments the
+ <structname>pg_stat_all_indexes</structname>.<structfield>idx_tup_read</structfield>
+ count(s) for the index(es) it uses, and it increments the
+ <structname>pg_stat_all_tables</structname>.<structfield>idx_tup_fetch</structfield>
+ count for the table, but it does not affect
+ <structname>pg_stat_all_indexes</structname>.<structfield>idx_tup_fetch</structfield>.
+ The optimizer also accesses indexes to check for supplied constants
+ whose values are outside the recorded range of the optimizer statistics
+ because the optimizer statistics might be stale.
+ </para>
+
+ <note>
+ <para>
+ The <structfield>idx_tup_read</structfield> and <structfield>idx_tup_fetch</structfield> counts
+ can be different even without any use of bitmap scans,
+ because <structfield>idx_tup_read</structfield> counts
+ index entries retrieved from the index while <structfield>idx_tup_fetch</structfield>
+ counts live rows fetched from the table. The latter will be less if any
+ dead or not-yet-committed rows are fetched using the index, or if any
+ heap fetches are avoided by means of an index-only scan.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-statio-all-tables-view">
+ <title><structname>pg_statio_all_tables</structname></title>
+
+ <indexterm>
+ <primary>pg_statio_all_tables</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_statio_all_tables</structname> view will contain
+ one row for each table in the current database (including TOAST
+ tables), showing statistics about I/O on that specific table. The
+ <structname>pg_statio_user_tables</structname> and
+ <structname>pg_statio_sys_tables</structname> views
+ contain the same information,
+ but filtered to only show user and system tables respectively.
+ </para>
+
+ <table id="pg-statio-all-tables-view" xreflabel="pg_statio_all_tables">
+ <title><structname>pg_statio_all_tables</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of a table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema that this table is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read from this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffer hits in this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read from all indexes on this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffer hits in all indexes on this table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>toast_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read from this table's TOAST table (if any)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>toast_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffer hits in this table's TOAST table (if any)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tidx_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read from this table's TOAST table indexes (if any)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tidx_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffer hits in this table's TOAST table indexes (if any)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-statio-all-indexes-view">
+ <title><structname>pg_statio_all_indexes</structname></title>
+
+ <indexterm>
+ <primary>pg_statio_all_indexes</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_statio_all_indexes</structname> view will contain
+ one row for each index in the current database,
+ showing statistics about I/O on that specific index. The
+ <structname>pg_statio_user_indexes</structname> and
+ <structname>pg_statio_sys_indexes</structname> views
+ contain the same information,
+ but filtered to only show user and system indexes respectively.
+ </para>
+
+ <table id="pg-statio-all-indexes-view" xreflabel="pg_statio_all_indexes">
+ <title><structname>pg_statio_all_indexes</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table for this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexrelid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema this index is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the table for this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexrelname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read from this index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>idx_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffer hits in this index
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-statio-all-sequences-view">
+ <title><structname>pg_statio_all_sequences</structname></title>
+
+ <indexterm>
+ <primary>pg_statio_all_sequences</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_statio_all_sequences</structname> view will contain
+ one row for each sequence in the current database,
+ showing statistics about I/O on that specific sequence.
+ </para>
+
+ <table id="pg-statio-all-sequences-view" xreflabel="pg_statio_all_sequences">
+ <title><structname>pg_statio_all_sequences</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of a sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema this sequence is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read from this sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of buffer hits in this sequence
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-user-functions-view">
+ <title><structname>pg_stat_user_functions</structname></title>
+
+ <indexterm>
+ <primary>pg_stat_user_functions</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_stat_user_functions</structname> view will contain
+ one row for each tracked function, showing statistics about executions of
+ that function. The <xref linkend="guc-track-functions"/> parameter
+ controls exactly which functions are tracked.
+ </para>
+
+ <table id="pg-stat-user-functions-view" xreflabel="pg_stat_user_functions">
+ <title><structname>pg_stat_user_functions</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>funcid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of a function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema this function is in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>funcname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of this function
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>calls</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times this function has been called
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent in this function and all other functions
+ called by it, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>self_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent in this function itself, not including
+ other functions called by it, in milliseconds
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-pg-stat-slru-view">
+ <title><structname>pg_stat_slru</structname></title>
+
+ <indexterm>
+ <primary>SLRU</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pg_stat_slru</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> accesses certain on-disk information
+ via <firstterm>SLRU</firstterm> (simple least-recently-used) caches.
+ The <structname>pg_stat_slru</structname> view will contain
+ one row for each tracked SLRU cache, showing statistics about access
+ to cached pages.
+ </para>
+
+ <table id="pg-stat-slru-view" xreflabel="pg_stat_slru">
+ <title><structname>pg_stat_slru</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the SLRU
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_zeroed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks zeroed during initializations
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times disk blocks were found already in the SLRU,
+ so that a read was not necessary (this only includes hits in the
+ SLRU, not the operating system's file system cache)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks read for this SLRU
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of disk blocks written for this SLRU
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blks_exists</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks checked for existence for this SLRU
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>flushes</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of flushes of dirty data for this SLRU
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>truncates</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of truncates for this SLRU
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which these statistics were last reset
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="monitoring-stats-functions">
+ <title>Statistics Functions</title>
+
+ <para>
+ Other ways of looking at the statistics can be set up by writing
+ queries that use the same underlying statistics access functions used by
+ the standard views shown above. For details such as the functions' names,
+ consult the definitions of the standard views. (For example, in
+ <application>psql</application> you could issue <literal>\d+ pg_stat_activity</literal>.)
+ The access functions for per-database statistics take a database OID as an
+ argument to identify which database to report on.
+ The per-table and per-index functions take a table or index OID.
+ The functions for per-function statistics take a function OID.
+ Note that only tables, indexes, and functions in the current database
+ can be seen with these functions.
+ </para>
+
+ <para>
+ Additional functions related to the cumulative statistics system are listed
+ in <xref linkend="monitoring-stats-funcs-table"/>.
+ </para>
+
+ <table id="monitoring-stats-funcs-table">
+ <title>Additional Statistics Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <!-- See also the entry for this in func.sgml -->
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pg_backend_pid</function> ()
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the process ID of the server process attached to the current
+ session.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_activity</primary>
+ </indexterm>
+ <function>pg_stat_get_activity</function> ( <type>integer</type> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Returns a record of information about the backend with the specified
+ process ID, or one record for each active backend in the system
+ if <literal>NULL</literal> is specified. The fields returned are a
+ subset of those in the <structname>pg_stat_activity</structname> view.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_snapshot_timestamp</primary>
+ </indexterm>
+ <function>pg_stat_get_snapshot_timestamp</function> ()
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the timestamp of the current statistics snapshot, or NULL if
+ no statistics snapshot has been taken. A snapshot is taken the first
+ time cumulative statistics are accessed in a transaction if
+ <varname>stats_fetch_consistency</varname> is set to
+ <literal>snapshot</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_xact_blocks_fetched</primary>
+ </indexterm>
+ <function>pg_stat_get_xact_blocks_fetched</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the number of block read requests for table or index, in the
+ current transaction. This number minus
+ <function>pg_stat_get_xact_blocks_hit</function> gives the number of
+ kernel <function>read()</function> calls; the number of actual
+ physical reads is usually lower due to kernel-level buffering.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_xact_blocks_hit</primary>
+ </indexterm>
+ <function>pg_stat_get_xact_blocks_hit</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Returns the number of block read requests for table or index, in the
+ current transaction, found in cache (not triggering kernel
+ <function>read()</function> calls).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_clear_snapshot</primary>
+ </indexterm>
+ <function>pg_stat_clear_snapshot</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Discards the current statistics snapshot or cached information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset</primary>
+ </indexterm>
+ <function>pg_stat_reset</function> ()
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets all statistics counters for the current database to zero.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset_shared</primary>
+ </indexterm>
+ <function>pg_stat_reset_shared</function> ( <type>text</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets some cluster-wide statistics counters to zero, depending on the
+ argument. The argument can be <literal>bgwriter</literal> to reset
+ all the counters shown in
+ the <structname>pg_stat_bgwriter</structname>
+ view, <literal>archiver</literal> to reset all the counters shown in
+ the <structname>pg_stat_archiver</structname> view,
+ <literal>wal</literal> to reset all the counters shown in the
+ <structname>pg_stat_wal</structname> view or
+ <literal>recovery_prefetch</literal> to reset all the counters shown
+ in the <structname>pg_stat_recovery_prefetch</structname> view.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset_single_table_counters</primary>
+ </indexterm>
+ <function>pg_stat_reset_single_table_counters</function> ( <type>oid</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets statistics for a single table or index in the current database
+ or shared across all databases in the cluster to zero.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset_single_function_counters</primary>
+ </indexterm>
+ <function>pg_stat_reset_single_function_counters</function> ( <type>oid</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets statistics for a single function in the current database to
+ zero.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset_slru</primary>
+ </indexterm>
+ <function>pg_stat_reset_slru</function> ( <type>text</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets statistics to zero for a single SLRU cache, or for all SLRUs in
+ the cluster. If the argument is NULL, all counters shown in
+ the <structname>pg_stat_slru</structname> view for all SLRU caches are
+ reset. The argument can be one of
+ <literal>CommitTs</literal>,
+ <literal>MultiXactMember</literal>,
+ <literal>MultiXactOffset</literal>,
+ <literal>Notify</literal>,
+ <literal>Serial</literal>,
+ <literal>Subtrans</literal>, or
+ <literal>Xact</literal>
+ to reset the counters for only that entry.
+ If the argument is <literal>other</literal> (or indeed, any
+ unrecognized name), then the counters for all other SLRU caches, such
+ as extension-defined caches, are reset.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset_replication_slot</primary>
+ </indexterm>
+ <function>pg_stat_reset_replication_slot</function> ( <type>text</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets statistics of the replication slot defined by the argument. If
+ the argument is <literal>NULL</literal>, resets statistics for all
+ the replication slots.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_reset_subscription_stats</primary>
+ </indexterm>
+ <function>pg_stat_reset_subscription_stats</function> ( <type>oid</type> )
+ <returnvalue>void</returnvalue>
+ </para>
+ <para>
+ Resets statistics for a single subscription shown in the
+ <structname>pg_stat_subscription_stats</structname> view to zero. If
+ the argument is <literal>NULL</literal>, reset statistics for all
+ subscriptions.
+ </para>
+ <para>
+ This function is restricted to superusers by default, but other users
+ can be granted EXECUTE to run the function.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <warning>
+ <para>
+ Using <function>pg_stat_reset()</function> also resets counters that
+ autovacuum uses to determine when to trigger a vacuum or an analyze.
+ Resetting these counters can cause autovacuum to not perform necessary
+ work, which can cause problems such as table bloat or out-dated
+ table statistics. A database-wide <command>ANALYZE</command> is
+ recommended after the statistics have been reset.
+ </para>
+ </warning>
+
+ <para>
+ <function>pg_stat_get_activity</function>, the underlying function of
+ the <structname>pg_stat_activity</structname> view, returns a set of records
+ containing all the available information about each backend process.
+ Sometimes it may be more convenient to obtain just a subset of this
+ information. In such cases, an older set of per-backend statistics
+ access functions can be used; these are shown in <xref
+ linkend="monitoring-stats-backend-funcs-table"/>.
+ These access functions use a backend ID number, which ranges from one
+ to the number of currently active backends.
+ The function <function>pg_stat_get_backend_idset</function> provides a
+ convenient way to generate one row for each active backend for
+ invoking these functions. For example, to show the <acronym>PID</acronym>s and
+ current queries of all backends:
+
+<programlisting>
+SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
+ pg_stat_get_backend_activity(s.backendid) AS query
+ FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;
+</programlisting>
+ </para>
+
+ <table id="monitoring-stats-backend-funcs-table">
+ <title>Per-Backend Statistics Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_idset</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_idset</function> ()
+ <returnvalue>setof integer</returnvalue>
+ </para>
+ <para>
+ Returns the set of currently active backend ID numbers (from 1 to the
+ number of active backends).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_activity</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_activity</function> ( <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the text of this backend's most recent query.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_activity_start</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_activity_start</function> ( <type>integer</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the time when the backend's most recent query was started.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_client_addr</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_client_addr</function> ( <type>integer</type> )
+ <returnvalue>inet</returnvalue>
+ </para>
+ <para>
+ Returns the IP address of the client connected to this backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_client_port</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_client_port</function> ( <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the TCP port number that the client is using for communication.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_dbid</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_dbid</function> ( <type>integer</type> )
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Returns the OID of the database this backend is connected to.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_pid</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_pid</function> ( <type>integer</type> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Returns the process ID of this backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_start</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_start</function> ( <type>integer</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the time when this process was started.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_userid</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_userid</function> ( <type>integer</type> )
+ <returnvalue>oid</returnvalue>
+ </para>
+ <para>
+ Returns the OID of the user logged into this backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_wait_event_type</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_wait_event_type</function> ( <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the wait event type name if this backend is currently waiting,
+ otherwise NULL. See <xref linkend="wait-event-table"/> for details.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_wait_event</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_wait_event</function> ( <type>integer</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the wait event name if this backend is currently waiting,
+ otherwise NULL. See <xref linkend="wait-event-activity-table"/> through
+ <xref linkend="wait-event-timeout-table"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_stat_get_backend_xact_start</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_xact_start</function> ( <type>integer</type> )
+ <returnvalue>timestamp with time zone</returnvalue>
+ </para>
+ <para>
+ Returns the time when the backend's current transaction was started.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="monitoring-locks">
+ <title>Viewing Locks</title>
+
+ <indexterm zone="monitoring-locks">
+ <primary>lock</primary>
+ <secondary>monitoring</secondary>
+ </indexterm>
+
+ <para>
+ Another useful tool for monitoring database activity is the
+ <structname>pg_locks</structname> system table. It allows the
+ database administrator to view information about the outstanding
+ locks in the lock manager. For example, this capability can be used
+ to:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ View all the locks currently outstanding, all the locks on
+ relations in a particular database, all the locks on a
+ particular relation, or all the locks held by a particular
+ <productname>PostgreSQL</productname> session.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Determine the relation in the current database with the most
+ ungranted locks (which might be a source of contention among
+ database clients).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Determine the effect of lock contention on overall database
+ performance, as well as the extent to which contention varies
+ with overall database traffic.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Details of the <structname>pg_locks</structname> view appear in
+ <xref linkend="view-pg-locks"/>.
+ For more information on locking and managing concurrency with
+ <productname>PostgreSQL</productname>, refer to <xref linkend="mvcc"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="progress-reporting">
+ <title>Progress Reporting</title>
+
+ <para>
+ <productname>PostgreSQL</productname> has the ability to report the progress of
+ certain commands during command execution. Currently, the only commands
+ which support progress reporting are <command>ANALYZE</command>,
+ <command>CLUSTER</command>,
+ <command>CREATE INDEX</command>, <command>VACUUM</command>,
+ <command>COPY</command>,
+ and <xref linkend="protocol-replication-base-backup"/> (i.e., replication
+ command that <xref linkend="app-pgbasebackup"/> issues to take
+ a base backup).
+ This may be expanded in the future.
+ </para>
+
+ <sect2 id="analyze-progress-reporting">
+ <title>ANALYZE Progress Reporting</title>
+
+ <indexterm>
+ <primary>pg_stat_progress_analyze</primary>
+ </indexterm>
+
+ <para>
+ Whenever <command>ANALYZE</command> is running, the
+ <structname>pg_stat_progress_analyze</structname> view will contain a
+ row for each backend that is currently running that command. The tables
+ below describe the information that will be reported and provide
+ information about how to interpret it.
+ </para>
+
+ <table id="pg-stat-progress-analyze-view" xreflabel="pg_stat_progress_analyze">
+ <title><structname>pg_stat_progress_analyze</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table being analyzed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>phase</structfield> <type>text</type>
+ </para>
+ <para>
+ Current processing phase. See <xref linkend="analyze-phases"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sample_blks_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of heap blocks that will be sampled.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sample_blks_scanned</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of heap blocks scanned.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ext_stats_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of extended statistics.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ext_stats_computed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of extended statistics computed. This counter only advances
+ when the phase is <literal>computing extended statistics</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>child_tables_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of child tables.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>child_tables_done</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of child tables scanned. This counter only advances when the
+ phase is <literal>acquiring inherited sample rows</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>current_child_table_relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the child table currently being scanned. This field is
+ only valid when the phase is
+ <literal>acquiring inherited sample rows</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="analyze-phases">
+ <title>ANALYZE Phases</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Phase</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>initializing</literal></entry>
+ <entry>
+ The command is preparing to begin scanning the heap. This phase is
+ expected to be very brief.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>acquiring sample rows</literal></entry>
+ <entry>
+ The command is currently scanning the table given by
+ <structfield>relid</structfield> to obtain sample rows.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>acquiring inherited sample rows</literal></entry>
+ <entry>
+ The command is currently scanning child tables to obtain sample rows.
+ Columns <structfield>child_tables_total</structfield>,
+ <structfield>child_tables_done</structfield>, and
+ <structfield>current_child_table_relid</structfield> contain the
+ progress information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>computing statistics</literal></entry>
+ <entry>
+ The command is computing statistics from the sample rows obtained
+ during the table scan.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>computing extended statistics</literal></entry>
+ <entry>
+ The command is computing extended statistics from the sample rows
+ obtained during the table scan.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>finalizing analyze</literal></entry>
+ <entry>
+ The command is updating <structname>pg_class</structname>. When this
+ phase is completed, <command>ANALYZE</command> will end.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ Note that when <command>ANALYZE</command> is run on a partitioned table,
+ all of its partitions are also recursively analyzed.
+ In that case, <command>ANALYZE</command>
+ progress is reported first for the parent table, whereby its inheritance
+ statistics are collected, followed by that for each partition.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="create-index-progress-reporting">
+ <title>CREATE INDEX Progress Reporting</title>
+
+ <indexterm>
+ <primary>pg_stat_progress_create_index</primary>
+ </indexterm>
+
+ <para>
+ Whenever <command>CREATE INDEX</command> or <command>REINDEX</command> is running, the
+ <structname>pg_stat_progress_create_index</structname> view will contain
+ one row for each backend that is currently creating indexes. The tables
+ below describe the information that will be reported and provide information
+ about how to interpret it.
+ </para>
+
+ <table id="pg-stat-progress-create-index-view" xreflabel="pg_stat_progress_create_index">
+ <title><structname>pg_stat_progress_create_index</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table on which the index is being created.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>index_relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the index being created or reindexed. During a
+ non-concurrent <command>CREATE INDEX</command>, this is 0.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>command</structfield> <type>text</type>
+ </para>
+ <para>
+ The command that is running: <literal>CREATE INDEX</literal>,
+ <literal>CREATE INDEX CONCURRENTLY</literal>,
+ <literal>REINDEX</literal>, or <literal>REINDEX CONCURRENTLY</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>phase</structfield> <type>text</type>
+ </para>
+ <para>
+ Current processing phase of index creation. See <xref linkend="create-index-phases"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lockers_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of lockers to wait for, when applicable.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>lockers_done</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of lockers already waited for.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>current_locker_pid</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Process ID of the locker currently being waited for.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blocks_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of blocks to be processed in the current phase.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blocks_done</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of blocks already processed in the current phase.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tuples_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of tuples to be processed in the current phase.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tuples_done</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of tuples already processed in the current phase.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partitions_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ When creating an index on a partitioned table, this column is set to
+ the total number of partitions on which the index is to be created.
+ This field is <literal>0</literal> during a <literal>REINDEX</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>partitions_done</structfield> <type>bigint</type>
+ </para>
+ <para>
+ When creating an index on a partitioned table, this column is set to
+ the number of partitions on which the index has been created.
+ This field is <literal>0</literal> during a <literal>REINDEX</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="create-index-phases">
+ <title>CREATE INDEX Phases</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Phase</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>initializing</literal></entry>
+ <entry>
+ <command>CREATE INDEX</command> or <command>REINDEX</command> is preparing to create the index. This
+ phase is expected to be very brief.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for writers before build</literal></entry>
+ <entry>
+ <command>CREATE INDEX CONCURRENTLY</command> or <command>REINDEX CONCURRENTLY</command> is waiting for transactions
+ with write locks that can potentially see the table to finish.
+ This phase is skipped when not in concurrent mode.
+ Columns <structname>lockers_total</structname>, <structname>lockers_done</structname>
+ and <structname>current_locker_pid</structname> contain the progress
+ information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>building index</literal></entry>
+ <entry>
+ The index is being built by the access method-specific code. In this phase,
+ access methods that support progress reporting fill in their own progress data,
+ and the subphase is indicated in this column. Typically,
+ <structname>blocks_total</structname> and <structname>blocks_done</structname>
+ will contain progress data, as well as potentially
+ <structname>tuples_total</structname> and <structname>tuples_done</structname>.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for writers before validation</literal></entry>
+ <entry>
+ <command>CREATE INDEX CONCURRENTLY</command> or <command>REINDEX CONCURRENTLY</command> is waiting for transactions
+ with write locks that can potentially write into the table to finish.
+ This phase is skipped when not in concurrent mode.
+ Columns <structname>lockers_total</structname>, <structname>lockers_done</structname>
+ and <structname>current_locker_pid</structname> contain the progress
+ information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>index validation: scanning index</literal></entry>
+ <entry>
+ <command>CREATE INDEX CONCURRENTLY</command> is scanning the index searching
+ for tuples that need to be validated.
+ This phase is skipped when not in concurrent mode.
+ Columns <structname>blocks_total</structname> (set to the total size of the index)
+ and <structname>blocks_done</structname> contain the progress information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>index validation: sorting tuples</literal></entry>
+ <entry>
+ <command>CREATE INDEX CONCURRENTLY</command> is sorting the output of the
+ index scanning phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>index validation: scanning table</literal></entry>
+ <entry>
+ <command>CREATE INDEX CONCURRENTLY</command> is scanning the table
+ to validate the index tuples collected in the previous two phases.
+ This phase is skipped when not in concurrent mode.
+ Columns <structname>blocks_total</structname> (set to the total size of the table)
+ and <structname>blocks_done</structname> contain the progress information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for old snapshots</literal></entry>
+ <entry>
+ <command>CREATE INDEX CONCURRENTLY</command> or <command>REINDEX CONCURRENTLY</command> is waiting for transactions
+ that can potentially see the table to release their snapshots. This
+ phase is skipped when not in concurrent mode.
+ Columns <structname>lockers_total</structname>, <structname>lockers_done</structname>
+ and <structname>current_locker_pid</structname> contain the progress
+ information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for readers before marking dead</literal></entry>
+ <entry>
+ <command>REINDEX CONCURRENTLY</command> is waiting for transactions
+ with read locks on the table to finish, before marking the old index dead.
+ This phase is skipped when not in concurrent mode.
+ Columns <structname>lockers_total</structname>, <structname>lockers_done</structname>
+ and <structname>current_locker_pid</structname> contain the progress
+ information for this phase.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for readers before dropping</literal></entry>
+ <entry>
+ <command>REINDEX CONCURRENTLY</command> is waiting for transactions
+ with read locks on the table to finish, before dropping the old index.
+ This phase is skipped when not in concurrent mode.
+ Columns <structname>lockers_total</structname>, <structname>lockers_done</structname>
+ and <structname>current_locker_pid</structname> contain the progress
+ information for this phase.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="vacuum-progress-reporting">
+ <title>VACUUM Progress Reporting</title>
+
+ <indexterm>
+ <primary>pg_stat_progress_vacuum</primary>
+ </indexterm>
+
+ <para>
+ Whenever <command>VACUUM</command> is running, the
+ <structname>pg_stat_progress_vacuum</structname> view will contain
+ one row for each backend (including autovacuum worker processes) that is
+ currently vacuuming. The tables below describe the information
+ that will be reported and provide information about how to interpret it.
+ Progress for <command>VACUUM FULL</command> commands is reported via
+ <structname>pg_stat_progress_cluster</structname>
+ because both <command>VACUUM FULL</command> and <command>CLUSTER</command>
+ rewrite the table, while regular <command>VACUUM</command> only modifies it
+ in place. See <xref linkend='cluster-progress-reporting'/>.
+ </para>
+
+ <table id="pg-stat-progress-vacuum-view" xreflabel="pg_stat_progress_vacuum">
+ <title><structname>pg_stat_progress_vacuum</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table being vacuumed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>phase</structfield> <type>text</type>
+ </para>
+ <para>
+ Current processing phase of vacuum. See <xref linkend="vacuum-phases"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of heap blocks in the table. This number is reported
+ as of the beginning of the scan; blocks added later will not be (and
+ need not be) visited by this <command>VACUUM</command>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_scanned</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of heap blocks scanned. Because the
+ <link linkend="storage-vm">visibility map</link> is used to optimize scans,
+ some blocks will be skipped without inspection; skipped blocks are
+ included in this total, so that this number will eventually become
+ equal to <structfield>heap_blks_total</structfield> when the vacuum is complete.
+ This counter only advances when the phase is <literal>scanning heap</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_vacuumed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of heap blocks vacuumed. Unless the table has no indexes, this
+ counter only advances when the phase is <literal>vacuuming heap</literal>.
+ Blocks that contain no dead tuples are skipped, so the counter may
+ sometimes skip forward in large increments.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>index_vacuum_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of completed index vacuum cycles.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>max_dead_tuples</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of dead tuples that we can store before needing to perform
+ an index vacuum cycle, based on
+ <xref linkend="guc-maintenance-work-mem"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>num_dead_tuples</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of dead tuples collected since the last index vacuum cycle.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="vacuum-phases">
+ <title>VACUUM Phases</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Phase</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>initializing</literal></entry>
+ <entry>
+ <command>VACUUM</command> is preparing to begin scanning the heap. This
+ phase is expected to be very brief.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>scanning heap</literal></entry>
+ <entry>
+ <command>VACUUM</command> is currently scanning the heap. It will prune and
+ defragment each page if required, and possibly perform freezing
+ activity. The <structfield>heap_blks_scanned</structfield> column can be used
+ to monitor the progress of the scan.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>vacuuming indexes</literal></entry>
+ <entry>
+ <command>VACUUM</command> is currently vacuuming the indexes. If a table has
+ any indexes, this will happen at least once per vacuum, after the heap
+ has been completely scanned. It may happen multiple times per vacuum
+ if <xref linkend="guc-maintenance-work-mem"/> (or, in the case of autovacuum,
+ <xref linkend="guc-autovacuum-work-mem"/> if set) is insufficient to store
+ the number of dead tuples found.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>vacuuming heap</literal></entry>
+ <entry>
+ <command>VACUUM</command> is currently vacuuming the heap. Vacuuming the heap
+ is distinct from scanning the heap, and occurs after each instance of
+ vacuuming indexes. If <structfield>heap_blks_scanned</structfield> is less than
+ <structfield>heap_blks_total</structfield>, the system will return to scanning
+ the heap after this phase is completed; otherwise, it will begin
+ cleaning up indexes after this phase is completed.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>cleaning up indexes</literal></entry>
+ <entry>
+ <command>VACUUM</command> is currently cleaning up indexes. This occurs after
+ the heap has been completely scanned and all vacuuming of the indexes
+ and the heap has been completed.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>truncating heap</literal></entry>
+ <entry>
+ <command>VACUUM</command> is currently truncating the heap so as to return
+ empty pages at the end of the relation to the operating system. This
+ occurs after cleaning up indexes.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>performing final cleanup</literal></entry>
+ <entry>
+ <command>VACUUM</command> is performing final cleanup. During this phase,
+ <command>VACUUM</command> will vacuum the free space map, update statistics
+ in <literal>pg_class</literal>, and report statistics to the cumulative
+ statistics system. When this phase is completed, <command>VACUUM</command> will end.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="cluster-progress-reporting">
+ <title>CLUSTER Progress Reporting</title>
+
+ <indexterm>
+ <primary>pg_stat_progress_cluster</primary>
+ </indexterm>
+
+ <para>
+ Whenever <command>CLUSTER</command> or <command>VACUUM FULL</command> is
+ running, the <structname>pg_stat_progress_cluster</structname> view will
+ contain a row for each backend that is currently running either command.
+ The tables below describe the information that will be reported and
+ provide information about how to interpret it.
+ </para>
+
+ <table id="pg-stat-progress-cluster-view" xreflabel="pg_stat_progress_cluster">
+ <title><structname>pg_stat_progress_cluster</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table being clustered.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>command</structfield> <type>text</type>
+ </para>
+ <para>
+ The command that is running. Either <literal>CLUSTER</literal> or <literal>VACUUM FULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>phase</structfield> <type>text</type>
+ </para>
+ <para>
+ Current processing phase. See <xref linkend="cluster-phases"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cluster_index_relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ If the table is being scanned using an index, this is the OID of the
+ index being used; otherwise, it is zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_tuples_scanned</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of heap tuples scanned.
+ This counter only advances when the phase is
+ <literal>seq scanning heap</literal>,
+ <literal>index scanning heap</literal>
+ or <literal>writing new heap</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_tuples_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of heap tuples written.
+ This counter only advances when the phase is
+ <literal>seq scanning heap</literal>,
+ <literal>index scanning heap</literal>
+ or <literal>writing new heap</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of heap blocks in the table. This number is reported
+ as of the beginning of <literal>seq scanning heap</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>heap_blks_scanned</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of heap blocks scanned. This counter only advances when the
+ phase is <literal>seq scanning heap</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>index_rebuild_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of indexes rebuilt. This counter only advances when the phase
+ is <literal>rebuilding index</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="cluster-phases">
+ <title>CLUSTER and VACUUM FULL Phases</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Phase</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>initializing</literal></entry>
+ <entry>
+ The command is preparing to begin scanning the heap. This phase is
+ expected to be very brief.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>seq scanning heap</literal></entry>
+ <entry>
+ The command is currently scanning the table using a sequential scan.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>index scanning heap</literal></entry>
+ <entry>
+ <command>CLUSTER</command> is currently scanning the table using an index scan.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>sorting tuples</literal></entry>
+ <entry>
+ <command>CLUSTER</command> is currently sorting tuples.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>writing new heap</literal></entry>
+ <entry>
+ <command>CLUSTER</command> is currently writing the new heap.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>swapping relation files</literal></entry>
+ <entry>
+ The command is currently swapping newly-built files into place.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>rebuilding index</literal></entry>
+ <entry>
+ The command is currently rebuilding an index.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>performing final cleanup</literal></entry>
+ <entry>
+ The command is performing final cleanup. When this phase is
+ completed, <command>CLUSTER</command>
+ or <command>VACUUM FULL</command> will end.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="basebackup-progress-reporting">
+ <title>Base Backup Progress Reporting</title>
+
+ <indexterm>
+ <primary>pg_stat_progress_basebackup</primary>
+ </indexterm>
+
+ <para>
+ Whenever an application like <application>pg_basebackup</application>
+ is taking a base backup, the
+ <structname>pg_stat_progress_basebackup</structname>
+ view will contain a row for each WAL sender process that is currently
+ running the <command>BASE_BACKUP</command> replication command
+ and streaming the backup. The tables below describe the information
+ that will be reported and provide information about how to interpret it.
+ </para>
+
+ <table id="pg-stat-progress-basebackup-view" xreflabel="pg_stat_progress_basebackup">
+ <title><structname>pg_stat_progress_basebackup</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of a WAL sender process.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>phase</structfield> <type>text</type>
+ </para>
+ <para>
+ Current processing phase. See <xref linkend="basebackup-phases"/>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backup_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total amount of data that will be streamed. This is estimated and
+ reported as of the beginning of
+ <literal>streaming database files</literal> phase. Note that
+ this is only an approximation since the database
+ may change during <literal>streaming database files</literal> phase
+ and WAL log may be included in the backup later. This is always
+ the same value as <structfield>backup_streamed</structfield>
+ once the amount of data streamed exceeds the estimated
+ total size. If the estimation is disabled in
+ <application>pg_basebackup</application>
+ (i.e., <literal>--no-estimate-size</literal> option is specified),
+ this is <literal>NULL</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>backup_streamed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Amount of data streamed. This counter only advances
+ when the phase is <literal>streaming database files</literal> or
+ <literal>transferring wal files</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablespaces_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of tablespaces that will be streamed.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablespaces_streamed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of tablespaces streamed. This counter only
+ advances when the phase is <literal>streaming database files</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="basebackup-phases">
+ <title>Base Backup Phases</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Phase</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>initializing</literal></entry>
+ <entry>
+ The WAL sender process is preparing to begin the backup.
+ This phase is expected to be very brief.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for checkpoint to finish</literal></entry>
+ <entry>
+ The WAL sender process is currently performing
+ <function>pg_backup_start</function> to prepare to
+ take a base backup, and waiting for the start-of-backup
+ checkpoint to finish.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>estimating backup size</literal></entry>
+ <entry>
+ The WAL sender process is currently estimating the total amount
+ of database files that will be streamed as a base backup.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>streaming database files</literal></entry>
+ <entry>
+ The WAL sender process is currently streaming database files
+ as a base backup.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>waiting for wal archiving to finish</literal></entry>
+ <entry>
+ The WAL sender process is currently performing
+ <function>pg_backup_stop</function> to finish the backup,
+ and waiting for all the WAL files required for the base backup
+ to be successfully archived.
+ If either <literal>--wal-method=none</literal> or
+ <literal>--wal-method=stream</literal> is specified in
+ <application>pg_basebackup</application>, the backup will end
+ when this phase is completed.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>transferring wal files</literal></entry>
+ <entry>
+ The WAL sender process is currently transferring all WAL logs
+ generated during the backup. This phase occurs after
+ <literal>waiting for wal archiving to finish</literal> phase if
+ <literal>--wal-method=fetch</literal> is specified in
+ <application>pg_basebackup</application>. The backup will end
+ when this phase is completed.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect2>
+
+ <sect2 id="copy-progress-reporting">
+ <title>COPY Progress Reporting</title>
+
+ <indexterm>
+ <primary>pg_stat_progress_copy</primary>
+ </indexterm>
+
+ <para>
+ Whenever <command>COPY</command> is running, the
+ <structname>pg_stat_progress_copy</structname> view will contain one row
+ for each backend that is currently running a <command>COPY</command> command.
+ The table below describes the information that will be reported and provides
+ information about how to interpret it.
+ </para>
+
+ <table id="pg-stat-progress-copy-view" xreflabel="pg_stat_progress_copy">
+ <title><structname>pg_stat_progress_copy</structname> View</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>integer</type>
+ </para>
+ <para>
+ Process ID of backend.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datname</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the database to which this backend is connected.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relid</structfield> <type>oid</type>
+ </para>
+ <para>
+ OID of the table on which the <command>COPY</command> command is
+ executed. It is set to <literal>0</literal> if copying from a
+ <command>SELECT</command> query.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>command</structfield> <type>text</type>
+ </para>
+ <para>
+ The command that is running: <literal>COPY FROM</literal>, or
+ <literal>COPY TO</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>type</structfield> <type>text</type>
+ </para>
+ <para>
+ The io type that the data is read from or written to:
+ <literal>FILE</literal>, <literal>PROGRAM</literal>,
+ <literal>PIPE</literal> (for <command>COPY FROM STDIN</command> and
+ <command>COPY TO STDOUT</command>), or <literal>CALLBACK</literal>
+ (used for example during the initial table synchronization in
+ logical replication).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>bytes_processed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of bytes already processed by <command>COPY</command> command.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>bytes_total</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Size of source file for <command>COPY FROM</command> command in bytes.
+ It is set to <literal>0</literal> if not available.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tuples_processed</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of tuples already processed by <command>COPY</command> command.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tuples_excluded</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of tuples not processed because they were excluded by the
+ <command>WHERE</command> clause of the <command>COPY</command> command.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="dynamic-trace">
+ <title>Dynamic Tracing</title>
+
+ <indexterm zone="dynamic-trace">
+ <primary>DTrace</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides facilities to support
+ dynamic tracing of the database server. This allows an external
+ utility to be called at specific points in the code and thereby trace
+ execution.
+ </para>
+
+ <para>
+ A number of probes or trace points are already inserted into the source
+ code. These probes are intended to be used by database developers and
+ administrators. By default the probes are not compiled into
+ <productname>PostgreSQL</productname>; the user needs to explicitly tell
+ the configure script to make the probes available.
+ </para>
+
+ <para>
+ Currently, the
+ <ulink url="https://en.wikipedia.org/wiki/DTrace">DTrace</ulink>
+ utility is supported, which, at the time of this writing, is available
+ on Solaris, macOS, FreeBSD, NetBSD, and Oracle Linux. The
+ <ulink url="https://sourceware.org/systemtap/">SystemTap</ulink> project
+ for Linux provides a DTrace equivalent and can also be used. Supporting other dynamic
+ tracing utilities is theoretically possible by changing the definitions for
+ the macros in <filename>src/include/utils/probes.h</filename>.
+ </para>
+
+ <sect2 id="compiling-for-trace">
+ <title>Compiling for Dynamic Tracing</title>
+
+ <para>
+ By default, probes are not available, so you will need to
+ explicitly tell the configure script to make the probes available
+ in <productname>PostgreSQL</productname>. To include DTrace support
+ specify <option>--enable-dtrace</option> to configure. See <xref
+ linkend="install-procedure"/> for further information.
+ </para>
+ </sect2>
+
+ <sect2 id="trace-points">
+ <title>Built-in Probes</title>
+
+ <para>
+ A number of standard probes are provided in the source code,
+ as shown in <xref linkend="dtrace-probe-point-table"/>;
+ <xref linkend="typedefs-table"/>
+ shows the types used in the probes. More probes can certainly be
+ added to enhance <productname>PostgreSQL</productname>'s observability.
+ </para>
+
+ <table id="dtrace-probe-point-table">
+ <title>Built-in DTrace Probes</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Parameters</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><literal>transaction-start</literal></entry>
+ <entry><literal>(LocalTransactionId)</literal></entry>
+ <entry>Probe that fires at the start of a new transaction.
+ arg0 is the transaction ID.</entry>
+ </row>
+ <row>
+ <entry><literal>transaction-commit</literal></entry>
+ <entry><literal>(LocalTransactionId)</literal></entry>
+ <entry>Probe that fires when a transaction completes successfully.
+ arg0 is the transaction ID.</entry>
+ </row>
+ <row>
+ <entry><literal>transaction-abort</literal></entry>
+ <entry><literal>(LocalTransactionId)</literal></entry>
+ <entry>Probe that fires when a transaction completes unsuccessfully.
+ arg0 is the transaction ID.</entry>
+ </row>
+ <row>
+ <entry><literal>query-start</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires when the processing of a query is started.
+ arg0 is the query string.</entry>
+ </row>
+ <row>
+ <entry><literal>query-done</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires when the processing of a query is complete.
+ arg0 is the query string.</entry>
+ </row>
+ <row>
+ <entry><literal>query-parse-start</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires when the parsing of a query is started.
+ arg0 is the query string.</entry>
+ </row>
+ <row>
+ <entry><literal>query-parse-done</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires when the parsing of a query is complete.
+ arg0 is the query string.</entry>
+ </row>
+ <row>
+ <entry><literal>query-rewrite-start</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires when the rewriting of a query is started.
+ arg0 is the query string.</entry>
+ </row>
+ <row>
+ <entry><literal>query-rewrite-done</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires when the rewriting of a query is complete.
+ arg0 is the query string.</entry>
+ </row>
+ <row>
+ <entry><literal>query-plan-start</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when the planning of a query is started.</entry>
+ </row>
+ <row>
+ <entry><literal>query-plan-done</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when the planning of a query is complete.</entry>
+ </row>
+ <row>
+ <entry><literal>query-execute-start</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when the execution of a query is started.</entry>
+ </row>
+ <row>
+ <entry><literal>query-execute-done</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when the execution of a query is complete.</entry>
+ </row>
+ <row>
+ <entry><literal>statement-status</literal></entry>
+ <entry><literal>(const char *)</literal></entry>
+ <entry>Probe that fires anytime the server process updates its
+ <structname>pg_stat_activity</structname>.<structfield>status</structfield>.
+ arg0 is the new status string.</entry>
+ </row>
+ <row>
+ <entry><literal>checkpoint-start</literal></entry>
+ <entry><literal>(int)</literal></entry>
+ <entry>Probe that fires when a checkpoint is started.
+ arg0 holds the bitwise flags used to distinguish different checkpoint
+ types, such as shutdown, immediate or force.</entry>
+ </row>
+ <row>
+ <entry><literal>checkpoint-done</literal></entry>
+ <entry><literal>(int, int, int, int, int)</literal></entry>
+ <entry>Probe that fires when a checkpoint is complete.
+ (The probes listed next fire in sequence during checkpoint processing.)
+ arg0 is the number of buffers written. arg1 is the total number of
+ buffers. arg2, arg3 and arg4 contain the number of WAL files added,
+ removed and recycled respectively.</entry>
+ </row>
+ <row>
+ <entry><literal>clog-checkpoint-start</literal></entry>
+ <entry><literal>(bool)</literal></entry>
+ <entry>Probe that fires when the CLOG portion of a checkpoint is started.
+ arg0 is true for normal checkpoint, false for shutdown
+ checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>clog-checkpoint-done</literal></entry>
+ <entry><literal>(bool)</literal></entry>
+ <entry>Probe that fires when the CLOG portion of a checkpoint is
+ complete. arg0 has the same meaning as for <literal>clog-checkpoint-start</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>subtrans-checkpoint-start</literal></entry>
+ <entry><literal>(bool)</literal></entry>
+ <entry>Probe that fires when the SUBTRANS portion of a checkpoint is
+ started.
+ arg0 is true for normal checkpoint, false for shutdown
+ checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>subtrans-checkpoint-done</literal></entry>
+ <entry><literal>(bool)</literal></entry>
+ <entry>Probe that fires when the SUBTRANS portion of a checkpoint is
+ complete. arg0 has the same meaning as for
+ <literal>subtrans-checkpoint-start</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>multixact-checkpoint-start</literal></entry>
+ <entry><literal>(bool)</literal></entry>
+ <entry>Probe that fires when the MultiXact portion of a checkpoint is
+ started.
+ arg0 is true for normal checkpoint, false for shutdown
+ checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>multixact-checkpoint-done</literal></entry>
+ <entry><literal>(bool)</literal></entry>
+ <entry>Probe that fires when the MultiXact portion of a checkpoint is
+ complete. arg0 has the same meaning as for
+ <literal>multixact-checkpoint-start</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-checkpoint-start</literal></entry>
+ <entry><literal>(int)</literal></entry>
+ <entry>Probe that fires when the buffer-writing portion of a checkpoint
+ is started.
+ arg0 holds the bitwise flags used to distinguish different checkpoint
+ types, such as shutdown, immediate or force.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-sync-start</literal></entry>
+ <entry><literal>(int, int)</literal></entry>
+ <entry>Probe that fires when we begin to write dirty buffers during
+ checkpoint (after identifying which buffers must be written).
+ arg0 is the total number of buffers.
+ arg1 is the number that are currently dirty and need to be written.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-sync-written</literal></entry>
+ <entry><literal>(int)</literal></entry>
+ <entry>Probe that fires after each buffer is written during checkpoint.
+ arg0 is the ID number of the buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-sync-done</literal></entry>
+ <entry><literal>(int, int, int)</literal></entry>
+ <entry>Probe that fires when all dirty buffers have been written.
+ arg0 is the total number of buffers.
+ arg1 is the number of buffers actually written by the checkpoint process.
+ arg2 is the number that were expected to be written (arg1 of
+ <literal>buffer-sync-start</literal>); any difference reflects other processes flushing
+ buffers during the checkpoint.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-checkpoint-sync-start</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires after dirty buffers have been written to the
+ kernel, and before starting to issue fsync requests.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-checkpoint-done</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when syncing of buffers to disk is
+ complete.</entry>
+ </row>
+ <row>
+ <entry><literal>twophase-checkpoint-start</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when the two-phase portion of a checkpoint is
+ started.</entry>
+ </row>
+ <row>
+ <entry><literal>twophase-checkpoint-done</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when the two-phase portion of a checkpoint is
+ complete.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-read-start</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool)</literal></entry>
+ <entry>Probe that fires when a buffer read is started.
+ arg0 and arg1 contain the fork and block numbers of the page (but
+ arg1 will be -1 if this is a relation extension request).
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ arg6 is true for a relation extension request, false for normal
+ read.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-read-done</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool)</literal></entry>
+ <entry>Probe that fires when a buffer read is complete.
+ arg0 and arg1 contain the fork and block numbers of the page (if this
+ is a relation extension request, arg1 now contains the block number
+ of the newly added block).
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ arg6 is true for a relation extension request, false for normal
+ read.
+ arg7 is true if the buffer was found in the pool, false if not.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-flush-start</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid)</literal></entry>
+ <entry>Probe that fires before issuing any write request for a shared
+ buffer.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-flush-done</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid)</literal></entry>
+ <entry>Probe that fires when a write request is complete. (Note
+ that this just reflects the time to pass the data to the kernel;
+ it's typically not actually been written to disk yet.)
+ The arguments are the same as for <literal>buffer-flush-start</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-write-dirty-start</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid)</literal></entry>
+ <entry>Probe that fires when a server process begins to write a dirty
+ buffer. (If this happens often, it implies that
+ <xref linkend="guc-shared-buffers"/> is too
+ small or the background writer control parameters need adjustment.)
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.</entry>
+ </row>
+ <row>
+ <entry><literal>buffer-write-dirty-done</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid)</literal></entry>
+ <entry>Probe that fires when a dirty-buffer write is complete.
+ The arguments are the same as for <literal>buffer-write-dirty-start</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>wal-buffer-write-dirty-start</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when a server process begins to write a
+ dirty WAL buffer because no more WAL buffer space is available.
+ (If this happens often, it implies that
+ <xref linkend="guc-wal-buffers"/> is too small.)</entry>
+ </row>
+ <row>
+ <entry><literal>wal-buffer-write-dirty-done</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when a dirty WAL buffer write is complete.</entry>
+ </row>
+ <row>
+ <entry><literal>wal-insert</literal></entry>
+ <entry><literal>(unsigned char, unsigned char)</literal></entry>
+ <entry>Probe that fires when a WAL record is inserted.
+ arg0 is the resource manager (rmid) for the record.
+ arg1 contains the info flags.</entry>
+ </row>
+ <row>
+ <entry><literal>wal-switch</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when a WAL segment switch is requested.</entry>
+ </row>
+ <row>
+ <entry><literal>smgr-md-read-start</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int)</literal></entry>
+ <entry>Probe that fires when beginning to read a block from a relation.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>smgr-md-read-done</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int)</literal></entry>
+ <entry>Probe that fires when a block read is complete.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ arg6 is the number of bytes actually read, while arg7 is the number
+ requested (if these are different it indicates trouble).</entry>
+ </row>
+ <row>
+ <entry><literal>smgr-md-write-start</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int)</literal></entry>
+ <entry>Probe that fires when beginning to write a block to a relation.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.</entry>
+ </row>
+ <row>
+ <entry><literal>smgr-md-write-done</literal></entry>
+ <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, int, int)</literal></entry>
+ <entry>Probe that fires when a block write is complete.
+ arg0 and arg1 contain the fork and block numbers of the page.
+ arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs
+ identifying the relation.
+ arg5 is the ID of the backend which created the temporary relation for a
+ local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer.
+ arg6 is the number of bytes actually written, while arg7 is the number
+ requested (if these are different it indicates trouble).</entry>
+ </row>
+ <row>
+ <entry><literal>sort-start</literal></entry>
+ <entry><literal>(int, bool, int, int, bool, int)</literal></entry>
+ <entry>Probe that fires when a sort operation is started.
+ arg0 indicates heap, index or datum sort.
+ arg1 is true for unique-value enforcement.
+ arg2 is the number of key columns.
+ arg3 is the number of kilobytes of work memory allowed.
+ arg4 is true if random access to the sort result is required.
+ arg5 indicates serial when <literal>0</literal>, parallel worker when
+ <literal>1</literal>, or parallel leader when <literal>2</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>sort-done</literal></entry>
+ <entry><literal>(bool, long)</literal></entry>
+ <entry>Probe that fires when a sort is complete.
+ arg0 is true for external sort, false for internal sort.
+ arg1 is the number of disk blocks used for an external sort,
+ or kilobytes of memory used for an internal sort.</entry>
+ </row>
+ <row>
+ <entry><literal>lwlock-acquire</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
+ <entry>Probe that fires when an LWLock has been acquired.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
+ </row>
+ <row>
+ <entry><literal>lwlock-release</literal></entry>
+ <entry><literal>(char *)</literal></entry>
+ <entry>Probe that fires when an LWLock has been released (but note
+ that any released waiters have not yet been awakened).
+ arg0 is the LWLock's tranche.</entry>
+ </row>
+ <row>
+ <entry><literal>lwlock-wait-start</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
+ <entry>Probe that fires when an LWLock was not immediately available and
+ a server process has begun to wait for the lock to become available.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
+ </row>
+ <row>
+ <entry><literal>lwlock-wait-done</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
+ <entry>Probe that fires when a server process has been released from its
+ wait for an LWLock (it does not actually have the lock yet).
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
+ </row>
+ <row>
+ <entry><literal>lwlock-condacquire</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
+ <entry>Probe that fires when an LWLock was successfully acquired when the
+ caller specified no waiting.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
+ </row>
+ <row>
+ <entry><literal>lwlock-condacquire-fail</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
+ <entry>Probe that fires when an LWLock was not successfully acquired when
+ the caller specified no waiting.
+ arg0 is the LWLock's tranche.
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
+ </row>
+ <row>
+ <entry><literal>lock-wait-start</literal></entry>
+ <entry><literal>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE)</literal></entry>
+ <entry>Probe that fires when a request for a heavyweight lock (lmgr lock)
+ has begun to wait because the lock is not available.
+ arg0 through arg3 are the tag fields identifying the object being
+ locked. arg4 indicates the type of object being locked.
+ arg5 indicates the lock type being requested.</entry>
+ </row>
+ <row>
+ <entry><literal>lock-wait-done</literal></entry>
+ <entry><literal>(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE)</literal></entry>
+ <entry>Probe that fires when a request for a heavyweight lock (lmgr lock)
+ has finished waiting (i.e., has acquired the lock).
+ The arguments are the same as for <literal>lock-wait-start</literal>.</entry>
+ </row>
+ <row>
+ <entry><literal>deadlock-found</literal></entry>
+ <entry><literal>()</literal></entry>
+ <entry>Probe that fires when a deadlock is found by the deadlock
+ detector.</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="typedefs-table">
+ <title>Defined Types Used in Probe Parameters</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Type</entry>
+ <entry>Definition</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><type>LocalTransactionId</type></entry>
+ <entry><type>unsigned int</type></entry>
+ </row>
+ <row>
+ <entry><type>LWLockMode</type></entry>
+ <entry><type>int</type></entry>
+ </row>
+ <row>
+ <entry><type>LOCKMODE</type></entry>
+ <entry><type>int</type></entry>
+ </row>
+ <row>
+ <entry><type>BlockNumber</type></entry>
+ <entry><type>unsigned int</type></entry>
+ </row>
+ <row>
+ <entry><type>Oid</type></entry>
+ <entry><type>unsigned int</type></entry>
+ </row>
+ <row>
+ <entry><type>ForkNumber</type></entry>
+ <entry><type>int</type></entry>
+ </row>
+ <row>
+ <entry><type>bool</type></entry>
+ <entry><type>unsigned char</type></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+
+ </sect2>
+
+ <sect2 id="using-trace-points">
+ <title>Using Probes</title>
+
+ <para>
+ The example below shows a DTrace script for analyzing transaction
+ counts in the system, as an alternative to snapshotting
+ <structname>pg_stat_database</structname> before and after a performance test:
+<programlisting>
+#!/usr/sbin/dtrace -qs
+
+postgresql$1:::transaction-start
+{
+ @start["Start"] = count();
+ self->ts = timestamp;
+}
+
+postgresql$1:::transaction-abort
+{
+ @abort["Abort"] = count();
+}
+
+postgresql$1:::transaction-commit
+/self->ts/
+{
+ @commit["Commit"] = count();
+ @time["Total time (ns)"] = sum(timestamp - self->ts);
+ self->ts=0;
+}
+</programlisting>
+ When executed, the example D script gives output such as:
+<screen>
+# ./txn_count.d `pgrep -n postgres` or ./txn_count.d &lt;PID&gt;
+^C
+
+Start 71
+Commit 70
+Total time (ns) 2312105013
+</screen>
+ </para>
+
+ <note>
+ <para>
+ SystemTap uses a different notation for trace scripts than DTrace does,
+ even though the underlying trace points are compatible. One point worth
+ noting is that at this writing, SystemTap scripts must reference probe
+ names using double underscores in place of hyphens. This is expected to
+ be fixed in future SystemTap releases.
+ </para>
+ </note>
+
+ <para>
+ You should remember that DTrace scripts need to be carefully written and
+ debugged, otherwise the trace information collected might
+ be meaningless. In most cases where problems are found it is the
+ instrumentation that is at fault, not the underlying system. When
+ discussing information found using dynamic tracing, be sure to enclose
+ the script used to allow that too to be checked and discussed.
+ </para>
+ </sect2>
+
+ <sect2 id="defining-trace-points">
+ <title>Defining New Probes</title>
+
+ <para>
+ New probes can be defined within the code wherever the developer
+ desires, though this will require a recompilation. Below are the steps
+ for inserting new probes:
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ Decide on probe names and data to be made available through the probes
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Add the probe definitions to <filename>src/backend/utils/probes.d</filename>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Include <filename>pg_trace.h</filename> if it is not already present in the
+ module(s) containing the probe points, and insert
+ <literal>TRACE_POSTGRESQL</literal> probe macros at the desired locations
+ in the source code
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Recompile and verify that the new probes are available
+ </para>
+ </step>
+ </procedure>
+
+ <formalpara>
+ <title>Example:</title>
+ <para>
+ Here is an example of how you would add a probe to trace all new
+ transactions by transaction ID.
+ </para>
+ </formalpara>
+
+ <procedure>
+ <step>
+ <para>
+ Decide that the probe will be named <literal>transaction-start</literal> and
+ requires a parameter of type <type>LocalTransactionId</type>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Add the probe definition to <filename>src/backend/utils/probes.d</filename>:
+<programlisting>
+probe transaction__start(LocalTransactionId);
+</programlisting>
+ Note the use of the double underline in the probe name. In a DTrace
+ script using the probe, the double underline needs to be replaced with a
+ hyphen, so <literal>transaction-start</literal> is the name to document for
+ users.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ At compile time, <literal>transaction__start</literal> is converted to a macro
+ called <literal>TRACE_POSTGRESQL_TRANSACTION_START</literal> (notice the
+ underscores are single here), which is available by including
+ <filename>pg_trace.h</filename>. Add the macro call to the appropriate location
+ in the source code. In this case, it looks like the following:
+
+<programlisting>
+TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
+</programlisting>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ After recompiling and running the new binary, check that your newly added
+ probe is available by executing the following DTrace command. You
+ should see similar output:
+<screen>
+# dtrace -ln transaction-start
+ ID PROVIDER MODULE FUNCTION NAME
+18705 postgresql49878 postgres StartTransactionCommand transaction-start
+18755 postgresql49877 postgres StartTransactionCommand transaction-start
+18805 postgresql49876 postgres StartTransactionCommand transaction-start
+18855 postgresql49875 postgres StartTransactionCommand transaction-start
+18986 postgresql49873 postgres StartTransactionCommand transaction-start
+</screen>
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ There are a few things to be careful about when adding trace macros
+ to the C code:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ You should take care that the data types specified for a probe's
+ parameters match the data types of the variables used in the macro.
+ Otherwise, you will get compilation errors.
+ </para>
+ </listitem>
+
+
+ <listitem>
+ <para>
+ On most platforms, if <productname>PostgreSQL</productname> is
+ built with <option>--enable-dtrace</option>, the arguments to a trace
+ macro will be evaluated whenever control passes through the
+ macro, <emphasis>even if no tracing is being done</emphasis>. This is
+ usually not worth worrying about if you are just reporting the
+ values of a few local variables. But beware of putting expensive
+ function calls into the arguments. If you need to do that,
+ consider protecting the macro with a check to see if the trace
+ is actually enabled:
+
+<programlisting>
+if (TRACE_POSTGRESQL_TRANSACTION_START_ENABLED())
+ TRACE_POSTGRESQL_TRANSACTION_START(some_function(...));
+</programlisting>
+
+ Each trace macro has a corresponding <literal>ENABLED</literal> macro.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml
new file mode 100644
index 0000000..512e8b7
--- /dev/null
+++ b/doc/src/sgml/mvcc.sgml
@@ -0,0 +1,1941 @@
+<!-- doc/src/sgml/mvcc.sgml -->
+
+ <chapter id="mvcc">
+ <title>Concurrency Control</title>
+
+ <indexterm>
+ <primary>concurrency</primary>
+ </indexterm>
+
+ <para>
+ This chapter describes the behavior of the
+ <productname>PostgreSQL</productname> database system when two or
+ more sessions try to access the same data at the same time. The
+ goals in that situation are to allow efficient access for all
+ sessions while maintaining strict data integrity. Every developer
+ of database applications should be familiar with the topics covered
+ in this chapter.
+ </para>
+
+ <sect1 id="mvcc-intro">
+ <title>Introduction</title>
+
+ <indexterm>
+ <primary>Multiversion Concurrency Control</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>MVCC</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>Serializable Snapshot Isolation</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>SSI</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a rich set of tools
+ for developers to manage concurrent access to data. Internally,
+ data consistency is maintained by using a multiversion
+ model (Multiversion Concurrency Control, <acronym>MVCC</acronym>).
+ This means that each SQL statement sees
+ a snapshot of data (a <firstterm>database version</firstterm>)
+ as it was some
+ time ago, regardless of the current state of the underlying data.
+ This prevents statements from viewing inconsistent data produced
+ by concurrent transactions performing updates on the same
+ data rows, providing <firstterm>transaction isolation</firstterm>
+ for each database session. <acronym>MVCC</acronym>, by eschewing
+ the locking methodologies of traditional database systems,
+ minimizes lock contention in order to allow for reasonable
+ performance in multiuser environments.
+ </para>
+
+ <para>
+ The main advantage of using the <acronym>MVCC</acronym> model of
+ concurrency control rather than locking is that in
+ <acronym>MVCC</acronym> locks acquired for querying (reading) data
+ do not conflict with locks acquired for writing data, and so
+ reading never blocks writing and writing never blocks reading.
+ <productname>PostgreSQL</productname> maintains this guarantee
+ even when providing the strictest level of transaction
+ isolation through the use of an innovative <firstterm>Serializable
+ Snapshot Isolation</firstterm> (<acronym>SSI</acronym>) level.
+ </para>
+
+ <para>
+ Table- and row-level locking facilities are also available in
+ <productname>PostgreSQL</productname> for applications which don't
+ generally need full transaction isolation and prefer to explicitly
+ manage particular points of conflict. However, proper
+ use of <acronym>MVCC</acronym> will generally provide better
+ performance than locks. In addition, application-defined advisory
+ locks provide a mechanism for acquiring locks that are not tied
+ to a single transaction.
+ </para>
+ </sect1>
+
+ <sect1 id="transaction-iso">
+ <title>Transaction Isolation</title>
+
+ <indexterm>
+ <primary>transaction isolation</primary>
+ </indexterm>
+
+ <para>
+ The <acronym>SQL</acronym> standard defines four levels of
+ transaction isolation. The most strict is Serializable,
+ which is defined by the standard in a paragraph which says that any
+ concurrent execution of a set of Serializable transactions is guaranteed
+ to produce the same effect as running them one at a time in some order.
+ The other three levels are defined in terms of phenomena, resulting from
+ interaction between concurrent transactions, which must not occur at
+ each level. The standard notes that due to the definition of
+ Serializable, none of these phenomena are possible at that level. (This
+ is hardly surprising -- if the effect of the transactions must be
+ consistent with having been run one at a time, how could you see any
+ phenomena caused by interactions?)
+ </para>
+
+ <para>
+ The phenomena which are prohibited at various levels are:
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ dirty read
+ <indexterm><primary>dirty read</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ A transaction reads data written by a concurrent uncommitted transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ nonrepeatable read
+ <indexterm><primary>nonrepeatable read</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ A transaction re-reads data it has previously read and finds that data
+ has been modified by another transaction (that committed since the
+ initial read).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ phantom read
+ <indexterm><primary>phantom read</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ A transaction re-executes a query returning a set of rows that satisfy a
+ search condition and finds that the set of rows satisfying the condition
+ has changed due to another recently-committed transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ serialization anomaly
+ <indexterm><primary>serialization anomaly</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The result of successfully committing a group of transactions
+ is inconsistent with all possible orderings of running those
+ transactions one at a time.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ </indexterm>
+ The SQL standard and PostgreSQL-implemented transaction isolation levels
+ are described in <xref linkend="mvcc-isolevel-table"/>.
+ </para>
+
+ <table tocentry="1" id="mvcc-isolevel-table">
+ <title>Transaction Isolation Levels</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>
+ Isolation Level
+ </entry>
+ <entry>
+ Dirty Read
+ </entry>
+ <entry>
+ Nonrepeatable Read
+ </entry>
+ <entry>
+ Phantom Read
+ </entry>
+ <entry>
+ Serialization Anomaly
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ Read uncommitted
+ </entry>
+ <entry>
+ Allowed, but not in PG
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ Read committed
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ Repeatable read
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ <entry>
+ Allowed, but not in PG
+ </entry>
+ <entry>
+ Possible
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ Serializable
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ <entry>
+ Not possible
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In <productname>PostgreSQL</productname>, you can request any of
+ the four standard transaction isolation levels, but internally only
+ three distinct isolation levels are implemented, i.e., PostgreSQL's
+ Read Uncommitted mode behaves like Read Committed. This is because
+ it is the only sensible way to map the standard isolation levels to
+ PostgreSQL's multiversion concurrency control architecture.
+ </para>
+
+ <para>
+ The table also shows that PostgreSQL's Repeatable Read implementation
+ does not allow phantom reads. This is acceptable under the SQL
+ standard because the standard specifies which anomalies must
+ <emphasis>not</emphasis> occur at certain isolation levels; higher
+ guarantees are acceptable.
+ The behavior of the available isolation levels is detailed in the
+ following subsections.
+ </para>
+
+ <para>
+ To set the transaction isolation level of a transaction, use the
+ command <xref linkend="sql-set-transaction"/>.
+ </para>
+
+ <important>
+ <para>
+ Some <productname>PostgreSQL</productname> data types and functions have
+ special rules regarding transactional behavior. In particular, changes
+ made to a sequence (and therefore the counter of a
+ column declared using <type>serial</type>) are immediately visible
+ to all other transactions and are not rolled back if the transaction
+ that made the changes aborts. See <xref linkend="functions-sequence"/>
+ and <xref linkend="datatype-serial"/>.
+ </para>
+ </important>
+
+ <sect2 id="xact-read-committed">
+ <title>Read Committed Isolation Level</title>
+
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ <secondary>read committed</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>read committed</primary>
+ </indexterm>
+
+ <para>
+ <firstterm>Read Committed</firstterm> is the default isolation
+ level in <productname>PostgreSQL</productname>. When a transaction
+ uses this isolation level, a <command>SELECT</command> query
+ (without a <literal>FOR UPDATE/SHARE</literal> clause) sees only data
+ committed before the query began; it never sees either uncommitted
+ data or changes committed during query execution by concurrent
+ transactions. In effect, a <command>SELECT</command> query sees
+ a snapshot of the database as of the instant the query begins to
+ run. However, <command>SELECT</command> does see the effects
+ of previous updates executed within its own transaction, even
+ though they are not yet committed. Also note that two successive
+ <command>SELECT</command> commands can see different data, even
+ though they are within a single transaction, if other transactions
+ commit changes after the first <command>SELECT</command> starts and
+ before the second <command>SELECT</command> starts.
+ </para>
+
+ <para>
+ <command>UPDATE</command>, <command>DELETE</command>, <command>SELECT
+ FOR UPDATE</command>, and <command>SELECT FOR SHARE</command> commands
+ behave the same as <command>SELECT</command>
+ in terms of searching for target rows: they will only find target rows
+ that were committed as of the command start time. However, such a target
+ row might have already been updated (or deleted or locked) by
+ another concurrent transaction by the time it is found. In this case, the
+ would-be updater will wait for the first updating transaction to commit or
+ roll back (if it is still in progress). If the first updater rolls back,
+ then its effects are negated and the second updater can proceed with
+ updating the originally found row. If the first updater commits, the
+ second updater will ignore the row if the first updater deleted it,
+ otherwise it will attempt to apply its operation to the updated version of
+ the row. The search condition of the command (the <literal>WHERE</literal> clause) is
+ re-evaluated to see if the updated version of the row still matches the
+ search condition. If so, the second updater proceeds with its operation
+ using the updated version of the row. In the case of
+ <command>SELECT FOR UPDATE</command> and <command>SELECT FOR
+ SHARE</command>, this means it is the updated version of the row that is
+ locked and returned to the client.
+ </para>
+
+ <para>
+ <command>INSERT</command> with an <literal>ON CONFLICT DO UPDATE</literal> clause
+ behaves similarly. In Read Committed mode, each row proposed for insertion
+ will either insert or update. Unless there are unrelated errors, one of
+ those two outcomes is guaranteed. If a conflict originates in another
+ transaction whose effects are not yet visible to the <command>INSERT</command>,
+ the <command>UPDATE</command> clause will affect that row,
+ even though possibly <emphasis>no</emphasis> version of that row is
+ conventionally visible to the command.
+ </para>
+
+ <para>
+ <command>INSERT</command> with an <literal>ON CONFLICT DO
+ NOTHING</literal> clause may have insertion not proceed for a row due to
+ the outcome of another transaction whose effects are not visible
+ to the <command>INSERT</command> snapshot. Again, this is only
+ the case in Read Committed mode.
+ </para>
+
+ <para>
+ <command>MERGE</command> allows the user to specify various
+ combinations of <command>INSERT</command>, <command>UPDATE</command>
+ and <command>DELETE</command> subcommands. A <command>MERGE</command>
+ command with both <command>INSERT</command> and <command>UPDATE</command>
+ subcommands looks similar to <command>INSERT</command> with an
+ <literal>ON CONFLICT DO UPDATE</literal> clause but does not
+ guarantee that either <command>INSERT</command> or
+ <command>UPDATE</command> will occur.
+ If <command>MERGE</command> attempts an <command>UPDATE</command> or
+ <command>DELETE</command> and the row is concurrently updated but
+ the join condition still passes for the current target and the
+ current source tuple, then <command>MERGE</command> will behave
+ the same as the <command>UPDATE</command> or
+ <command>DELETE</command> commands and perform its action on the
+ updated version of the row. However, because <command>MERGE</command>
+ can specify several actions and they can be conditional, the
+ conditions for each action are re-evaluated on the updated version of
+ the row, starting from the first action, even if the action that had
+ originally matched appears later in the list of actions.
+ On the other hand, if the row is concurrently updated or deleted so
+ that the join condition fails, then <command>MERGE</command> will
+ evaluate the condition's <literal>NOT MATCHED</literal> actions next,
+ and execute the first one that succeeds.
+ If <command>MERGE</command> attempts an <command>INSERT</command>
+ and a unique index is present and a duplicate row is concurrently
+ inserted, then a uniqueness violation error is raised;
+ <command>MERGE</command> does not attempt to avoid such
+ errors by restarting evaluation of <literal>MATCHED</literal>
+ conditions.
+ </para>
+
+ <para>
+ Because of the above rules, it is possible for an updating command to see
+ an inconsistent snapshot: it can see the effects of concurrent updating
+ commands on the same rows it is trying to update, but it
+ does not see effects of those commands on other rows in the database.
+ This behavior makes Read Committed mode unsuitable for commands that
+ involve complex search conditions; however, it is just right for simpler
+ cases. For example, consider updating bank balances with transactions
+ like:
+
+<screen>
+BEGIN;
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 12345;
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 7534;
+COMMIT;
+</screen>
+
+ If two such transactions concurrently try to change the balance of account
+ 12345, we clearly want the second transaction to start with the updated
+ version of the account's row. Because each command is affecting only a
+ predetermined row, letting it see the updated version of the row does
+ not create any troublesome inconsistency.
+ </para>
+
+ <para>
+ More complex usage can produce undesirable results in Read Committed
+ mode. For example, consider a <command>DELETE</command> command
+ operating on data that is being both added and removed from its
+ restriction criteria by another command, e.g., assume
+ <literal>website</literal> is a two-row table with
+ <literal>website.hits</literal> equaling <literal>9</literal> and
+ <literal>10</literal>:
+
+<screen>
+BEGIN;
+UPDATE website SET hits = hits + 1;
+-- run from another session: DELETE FROM website WHERE hits = 10;
+COMMIT;
+</screen>
+
+ The <command>DELETE</command> will have no effect even though
+ there is a <literal>website.hits = 10</literal> row before and
+ after the <command>UPDATE</command>. This occurs because the
+ pre-update row value <literal>9</literal> is skipped, and when the
+ <command>UPDATE</command> completes and <command>DELETE</command>
+ obtains a lock, the new row value is no longer <literal>10</literal> but
+ <literal>11</literal>, which no longer matches the criteria.
+ </para>
+
+ <para>
+ Because Read Committed mode starts each command with a new snapshot
+ that includes all transactions committed up to that instant,
+ subsequent commands in the same transaction will see the effects
+ of the committed concurrent transaction in any case. The point
+ at issue above is whether or not a <emphasis>single</emphasis> command
+ sees an absolutely consistent view of the database.
+ </para>
+
+ <para>
+ The partial transaction isolation provided by Read Committed mode
+ is adequate for many applications, and this mode is fast and simple
+ to use; however, it is not sufficient for all cases. Applications
+ that do complex queries and updates might require a more rigorously
+ consistent view of the database than Read Committed mode provides.
+ </para>
+ </sect2>
+
+ <sect2 id="xact-repeatable-read">
+ <title>Repeatable Read Isolation Level</title>
+
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ <secondary>repeatable read</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>repeatable read</primary>
+ </indexterm>
+
+ <para>
+ The <firstterm>Repeatable Read</firstterm> isolation level only sees
+ data committed before the transaction began; it never sees either
+ uncommitted data or changes committed during transaction execution
+ by concurrent transactions. (However, the query does see the
+ effects of previous updates executed within its own transaction,
+ even though they are not yet committed.) This is a stronger
+ guarantee than is required by the <acronym>SQL</acronym> standard
+ for this isolation level, and prevents all of the phenomena described
+ in <xref linkend="mvcc-isolevel-table"/> except for serialization
+ anomalies. As mentioned above, this is
+ specifically allowed by the standard, which only describes the
+ <emphasis>minimum</emphasis> protections each isolation level must
+ provide.
+ </para>
+
+ <para>
+ This level is different from Read Committed in that a query in a
+ repeatable read transaction sees a snapshot as of the start of the
+ first non-transaction-control statement in the
+ <emphasis>transaction</emphasis>, not as of the start
+ of the current statement within the transaction. Thus, successive
+ <command>SELECT</command> commands within a <emphasis>single</emphasis>
+ transaction see the same data, i.e., they do not see changes made by
+ other transactions that committed after their own transaction started.
+ </para>
+
+ <para>
+ Applications using this level must be prepared to retry transactions
+ due to serialization failures.
+ </para>
+
+ <para>
+ <command>UPDATE</command>, <command>DELETE</command>,
+ <command>MERGE</command>, <command>SELECT FOR UPDATE</command>,
+ and <command>SELECT FOR SHARE</command> commands
+ behave the same as <command>SELECT</command>
+ in terms of searching for target rows: they will only find target rows
+ that were committed as of the transaction start time. However, such a
+ target row might have already been updated (or deleted or locked) by
+ another concurrent transaction by the time it is found. In this case, the
+ repeatable read transaction will wait for the first updating transaction to commit or
+ roll back (if it is still in progress). If the first updater rolls back,
+ then its effects are negated and the repeatable read transaction can proceed
+ with updating the originally found row. But if the first updater commits
+ (and actually updated or deleted the row, not just locked it)
+ then the repeatable read transaction will be rolled back with the message
+
+<screen>
+ERROR: could not serialize access due to concurrent update
+</screen>
+
+ because a repeatable read transaction cannot modify or lock rows changed by
+ other transactions after the repeatable read transaction began.
+ </para>
+
+ <para>
+ When an application receives this error message, it should abort
+ the current transaction and retry the whole transaction from
+ the beginning. The second time through, the transaction will see the
+ previously-committed change as part of its initial view of the database,
+ so there is no logical conflict in using the new version of the row
+ as the starting point for the new transaction's update.
+ </para>
+
+ <para>
+ Note that only updating transactions might need to be retried; read-only
+ transactions will never have serialization conflicts.
+ </para>
+
+ <para>
+ The Repeatable Read mode provides a rigorous guarantee that each
+ transaction sees a completely stable view of the database. However,
+ this view will not necessarily always be consistent with some serial
+ (one at a time) execution of concurrent transactions of the same level.
+ For example, even a read-only transaction at this level may see a
+ control record updated to show that a batch has been completed but
+ <emphasis>not</emphasis> see one of the detail records which is logically
+ part of the batch because it read an earlier revision of the control
+ record. Attempts to enforce business rules by transactions running at
+ this isolation level are not likely to work correctly without careful use
+ of explicit locks to block conflicting transactions.
+ </para>
+
+ <para>
+ The Repeatable Read isolation level is implemented using a technique
+ known in academic database literature and in some other database products
+ as <firstterm>Snapshot Isolation</firstterm>. Differences in behavior
+ and performance may be observed when compared with systems that use a
+ traditional locking technique that reduces concurrency. Some other
+ systems may even offer Repeatable Read and Snapshot Isolation as distinct
+ isolation levels with different behavior. The permitted phenomena that
+ distinguish the two techniques were not formalized by database researchers
+ until after the SQL standard was developed, and are outside the scope of
+ this manual. For a full treatment, please see
+ <xref linkend="berenson95"/>.
+ </para>
+
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> version 9.1, a request
+ for the Serializable transaction isolation level provided exactly the
+ same behavior described here. To retain the legacy Serializable
+ behavior, Repeatable Read should now be requested.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="xact-serializable">
+ <title>Serializable Isolation Level</title>
+
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ <secondary>serializable</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>serializable</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>predicate locking</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>serialization anomaly</primary>
+ </indexterm>
+
+ <para>
+ The <firstterm>Serializable</firstterm> isolation level provides
+ the strictest transaction isolation. This level emulates serial
+ transaction execution for all committed transactions;
+ as if transactions had been executed one after another, serially,
+ rather than concurrently. However, like the Repeatable Read level,
+ applications using this level must
+ be prepared to retry transactions due to serialization failures.
+ In fact, this isolation level works exactly the same as Repeatable
+ Read except that it also monitors for conditions which could make
+ execution of a concurrent set of serializable transactions behave
+ in a manner inconsistent with all possible serial (one at a time)
+ executions of those transactions. This monitoring does not
+ introduce any blocking beyond that present in repeatable read, but
+ there is some overhead to the monitoring, and detection of the
+ conditions which could cause a
+ <firstterm>serialization anomaly</firstterm> will trigger a
+ <firstterm>serialization failure</firstterm>.
+ </para>
+
+ <para>
+ As an example,
+ consider a table <structname>mytab</structname>, initially containing:
+<screen>
+ class | value
+-------+-------
+ 1 | 10
+ 1 | 20
+ 2 | 100
+ 2 | 200
+</screen>
+ Suppose that serializable transaction A computes:
+<screen>
+SELECT SUM(value) FROM mytab WHERE class = 1;
+</screen>
+ and then inserts the result (30) as the <structfield>value</structfield> in a
+ new row with <structfield>class</structfield><literal> = 2</literal>. Concurrently, serializable
+ transaction B computes:
+<screen>
+SELECT SUM(value) FROM mytab WHERE class = 2;
+</screen>
+ and obtains the result 300, which it inserts in a new row with
+ <structfield>class</structfield><literal> = 1</literal>. Then both transactions try to commit.
+ If either transaction were running at the Repeatable Read isolation level,
+ both would be allowed to commit; but since there is no serial order of execution
+ consistent with the result, using Serializable transactions will allow one
+ transaction to commit and will roll the other back with this message:
+
+<screen>
+ERROR: could not serialize access due to read/write dependencies among transactions
+</screen>
+
+ This is because if A had
+ executed before B, B would have computed the sum 330, not 300, and
+ similarly the other order would have resulted in a different sum
+ computed by A.
+ </para>
+
+ <para>
+ When relying on Serializable transactions to prevent anomalies, it is
+ important that any data read from a permanent user table not be
+ considered valid until the transaction which read it has successfully
+ committed. This is true even for read-only transactions, except that
+ data read within a <firstterm>deferrable</firstterm> read-only
+ transaction is known to be valid as soon as it is read, because such a
+ transaction waits until it can acquire a snapshot guaranteed to be free
+ from such problems before starting to read any data. In all other cases
+ applications must not depend on results read during a transaction that
+ later aborted; instead, they should retry the transaction until it
+ succeeds.
+ </para>
+
+ <para>
+ To guarantee true serializability <productname>PostgreSQL</productname>
+ uses <firstterm>predicate locking</firstterm>, which means that it keeps locks
+ which allow it to determine when a write would have had an impact on
+ the result of a previous read from a concurrent transaction, had it run
+ first. In <productname>PostgreSQL</productname> these locks do not
+ cause any blocking and therefore can <emphasis>not</emphasis> play any part in
+ causing a deadlock. They are used to identify and flag dependencies
+ among concurrent Serializable transactions which in certain combinations
+ can lead to serialization anomalies. In contrast, a Read Committed or
+ Repeatable Read transaction which wants to ensure data consistency may
+ need to take out a lock on an entire table, which could block other
+ users attempting to use that table, or it may use <literal>SELECT FOR
+ UPDATE</literal> or <literal>SELECT FOR SHARE</literal> which not only
+ can block other transactions but cause disk access.
+ </para>
+
+ <para>
+ Predicate locks in <productname>PostgreSQL</productname>, like in most
+ other database systems, are based on data actually accessed by a
+ transaction. These will show up in the
+ <link linkend="view-pg-locks"><structname>pg_locks</structname></link>
+ system view with a <literal>mode</literal> of <literal>SIReadLock</literal>. The
+ particular locks
+ acquired during execution of a query will depend on the plan used by
+ the query, and multiple finer-grained locks (e.g., tuple locks) may be
+ combined into fewer coarser-grained locks (e.g., page locks) during the
+ course of the transaction to prevent exhaustion of the memory used to
+ track the locks. A <literal>READ ONLY</literal> transaction may be able to
+ release its SIRead locks before completion, if it detects that no
+ conflicts can still occur which could lead to a serialization anomaly.
+ In fact, <literal>READ ONLY</literal> transactions will often be able to
+ establish that fact at startup and avoid taking any predicate locks.
+ If you explicitly request a <literal>SERIALIZABLE READ ONLY DEFERRABLE</literal>
+ transaction, it will block until it can establish this fact. (This is
+ the <emphasis>only</emphasis> case where Serializable transactions block but
+ Repeatable Read transactions don't.) On the other hand, SIRead locks
+ often need to be kept past transaction commit, until overlapping read
+ write transactions complete.
+ </para>
+
+ <para>
+ Consistent use of Serializable transactions can simplify development.
+ The guarantee that any set of successfully committed concurrent
+ Serializable transactions will have the same effect as if they were run
+ one at a time means that if you can demonstrate that a single transaction,
+ as written, will do the right thing when run by itself, you can have
+ confidence that it will do the right thing in any mix of Serializable
+ transactions, even without any information about what those other
+ transactions might do, or it will not successfully commit. It is
+ important that an environment which uses this technique have a
+ generalized way of handling serialization failures (which always return
+ with an SQLSTATE value of '40001'), because it will be very hard to
+ predict exactly which transactions might contribute to the read/write
+ dependencies and need to be rolled back to prevent serialization
+ anomalies. The monitoring of read/write dependencies has a cost, as does
+ the restart of transactions which are terminated with a serialization
+ failure, but balanced against the cost and blocking involved in use of
+ explicit locks and <literal>SELECT FOR UPDATE</literal> or <literal>SELECT FOR
+ SHARE</literal>, Serializable transactions are the best performance choice
+ for some environments.
+ </para>
+
+ <para>
+ While <productname>PostgreSQL</productname>'s Serializable transaction isolation
+ level only allows concurrent transactions to commit if it can prove there
+ is a serial order of execution that would produce the same effect, it
+ doesn't always prevent errors from being raised that would not occur in
+ true serial execution. In particular, it is possible to see unique
+ constraint violations caused by conflicts with overlapping Serializable
+ transactions even after explicitly checking that the key isn't present
+ before attempting to insert it. This can be avoided by making sure
+ that <emphasis>all</emphasis> Serializable transactions that insert potentially
+ conflicting keys explicitly check if they can do so first. For example,
+ imagine an application that asks the user for a new key and then checks
+ that it doesn't exist already by trying to select it first, or generates
+ a new key by selecting the maximum existing key and adding one. If some
+ Serializable transactions insert new keys directly without following this
+ protocol, unique constraints violations might be reported even in cases
+ where they could not occur in a serial execution of the concurrent
+ transactions.
+ </para>
+
+ <para>
+ For optimal performance when relying on Serializable transactions for
+ concurrency control, these issues should be considered:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Declare transactions as <literal>READ ONLY</literal> when possible.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Control the number of active connections, using a connection pool if
+ needed. This is always an important performance consideration, but
+ it can be particularly important in a busy system using Serializable
+ transactions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Don't put more into a single transaction than needed for integrity
+ purposes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Don't leave connections dangling <quote>idle in transaction</quote>
+ longer than necessary. The configuration parameter
+ <xref linkend="guc-idle-in-transaction-session-timeout"/> may be used to
+ automatically disconnect lingering sessions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Eliminate explicit locks, <literal>SELECT FOR UPDATE</literal>, and
+ <literal>SELECT FOR SHARE</literal> where no longer needed due to the
+ protections automatically provided by Serializable transactions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When the system is forced to combine multiple page-level predicate
+ locks into a single relation-level predicate lock because the predicate
+ lock table is short of memory, an increase in the rate of serialization
+ failures may occur. You can avoid this by increasing
+ <xref linkend="guc-max-pred-locks-per-transaction"/>,
+ <xref linkend="guc-max-pred-locks-per-relation"/>, and/or
+ <xref linkend="guc-max-pred-locks-per-page"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A sequential scan will always necessitate a relation-level predicate
+ lock. This can result in an increased rate of serialization failures.
+ It may be helpful to encourage the use of index scans by reducing
+ <xref linkend="guc-random-page-cost"/> and/or increasing
+ <xref linkend="guc-cpu-tuple-cost"/>. Be sure to weigh any decrease
+ in transaction rollbacks and restarts against any overall change in
+ query execution time.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The Serializable isolation level is implemented using a technique known
+ in academic database literature as Serializable Snapshot Isolation, which
+ builds on Snapshot Isolation by adding checks for serialization anomalies.
+ Some differences in behavior and performance may be observed when compared
+ with other systems that use a traditional locking technique. Please see
+ <xref linkend="ports12"/> for detailed information.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="explicit-locking">
+ <title>Explicit Locking</title>
+
+ <indexterm>
+ <primary>lock</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides various lock modes
+ to control concurrent access to data in tables. These modes can
+ be used for application-controlled locking in situations where
+ <acronym>MVCC</acronym> does not give the desired behavior. Also,
+ most <productname>PostgreSQL</productname> commands automatically
+ acquire locks of appropriate modes to ensure that referenced
+ tables are not dropped or modified in incompatible ways while the
+ command executes. (For example, <command>TRUNCATE</command> cannot safely be
+ executed concurrently with other operations on the same table, so it
+ obtains an <literal>ACCESS EXCLUSIVE</literal> lock on the table to
+ enforce that.)
+ </para>
+
+ <para>
+ To examine a list of the currently outstanding locks in a database
+ server, use the
+ <link linkend="view-pg-locks"><structname>pg_locks</structname></link>
+ system view. For more information on monitoring the status of the lock
+ manager subsystem, refer to <xref linkend="monitoring"/>.
+ </para>
+
+ <sect2 id="locking-tables">
+ <title>Table-Level Locks</title>
+
+ <indexterm zone="locking-tables">
+ <primary>LOCK</primary>
+ </indexterm>
+
+ <para>
+ The list below shows the available lock modes and the contexts in
+ which they are used automatically by
+ <productname>PostgreSQL</productname>. You can also acquire any
+ of these locks explicitly with the command <xref
+ linkend="sql-lock"/>.
+ Remember that all of these lock modes are table-level locks,
+ even if the name contains the word
+ <quote>row</quote>; the names of the lock modes are historical.
+ To some extent the names reflect the typical usage of each lock
+ mode &mdash; but the semantics are all the same. The only real difference
+ between one lock mode and another is the set of lock modes with
+ which each conflicts (see <xref linkend="table-lock-compatibility"/>).
+ Two transactions cannot hold locks of conflicting
+ modes on the same table at the same time. (However, a transaction
+ never conflicts with itself. For example, it might acquire
+ <literal>ACCESS EXCLUSIVE</literal> lock and later acquire
+ <literal>ACCESS SHARE</literal> lock on the same table.) Non-conflicting
+ lock modes can be held concurrently by many transactions. Notice in
+ particular that some lock modes are self-conflicting (for example,
+ an <literal>ACCESS EXCLUSIVE</literal> lock cannot be held by more than one
+ transaction at a time) while others are not self-conflicting (for example,
+ an <literal>ACCESS SHARE</literal> lock can be held by multiple transactions).
+ </para>
+
+ <variablelist>
+ <title>Table-Level Lock Modes</title>
+ <varlistentry>
+ <term>
+ <literal>ACCESS SHARE</literal> (<literal>AccessShareLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>ACCESS EXCLUSIVE</literal> lock
+ mode only.
+ </para>
+
+ <para>
+ The <command>SELECT</command> command acquires a lock of this mode on
+ referenced tables. In general, any query that only <emphasis>reads</emphasis> a table
+ and does not modify it will acquire this lock mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>ROW SHARE</literal> (<literal>RowShareLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>EXCLUSIVE</literal> and
+ <literal>ACCESS EXCLUSIVE</literal> lock modes.
+ </para>
+
+ <para>
+ The <command>SELECT</command> command acquires a lock of this mode
+ on all tables on which one of the <option>FOR UPDATE</option>,
+ <option>FOR NO KEY UPDATE</option>,
+ <option>FOR SHARE</option>, or
+ <option>FOR KEY SHARE</option> options is specified
+ (in addition to <literal>ACCESS SHARE</literal> locks on any other
+ tables that are referenced without any explicit
+ <option>FOR ...</option> locking option).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>ROW EXCLUSIVE</literal> (<literal>RowExclusiveLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>SHARE</literal>, <literal>SHARE ROW
+ EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
+ <literal>ACCESS EXCLUSIVE</literal> lock modes.
+ </para>
+
+ <para>
+ The commands <command>UPDATE</command>,
+ <command>DELETE</command>, <command>INSERT</command>, and
+ <command>MERGE</command>
+ acquire this lock mode on the target table (in addition to
+ <literal>ACCESS SHARE</literal> locks on any other referenced
+ tables). In general, this lock mode will be acquired by any
+ command that <emphasis>modifies data</emphasis> in a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SHARE UPDATE EXCLUSIVE</literal> (<literal>ShareUpdateExclusiveLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>SHARE UPDATE EXCLUSIVE</literal>,
+ <literal>SHARE</literal>, <literal>SHARE ROW
+ EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
+ <literal>ACCESS EXCLUSIVE</literal> lock modes.
+ This mode protects a table against
+ concurrent schema changes and <command>VACUUM</command> runs.
+ </para>
+
+ <para>
+ Acquired by <command>VACUUM</command> (without <option>FULL</option>),
+ <command>ANALYZE</command>, <command>CREATE INDEX CONCURRENTLY</command>,
+ <command>CREATE STATISTICS</command>, <command>COMMENT ON</command>,
+ <command>REINDEX CONCURRENTLY</command>,
+ and certain <link linkend="sql-alterindex"><command>ALTER INDEX</command></link>
+ and <link linkend="sql-altertable"><command>ALTER TABLE</command></link> variants
+ (for full details see the documentation of these commands).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SHARE</literal> (<literal>ShareLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>ROW EXCLUSIVE</literal>,
+ <literal>SHARE UPDATE EXCLUSIVE</literal>, <literal>SHARE ROW
+ EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
+ <literal>ACCESS EXCLUSIVE</literal> lock modes.
+ This mode protects a table against concurrent data changes.
+ </para>
+
+ <para>
+ Acquired by <command>CREATE INDEX</command>
+ (without <option>CONCURRENTLY</option>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SHARE ROW EXCLUSIVE</literal> (<literal>ShareRowExclusiveLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>ROW EXCLUSIVE</literal>,
+ <literal>SHARE UPDATE EXCLUSIVE</literal>,
+ <literal>SHARE</literal>, <literal>SHARE ROW
+ EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
+ <literal>ACCESS EXCLUSIVE</literal> lock modes.
+ This mode protects a table against concurrent data changes, and
+ is self-exclusive so that only one session can hold it at a time.
+ </para>
+
+ <para>
+ Acquired by <command>CREATE TRIGGER</command> and some forms of
+ <link linkend="sql-altertable"><command>ALTER TABLE</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>EXCLUSIVE</literal> (<literal>ExclusiveLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with the <literal>ROW SHARE</literal>, <literal>ROW
+ EXCLUSIVE</literal>, <literal>SHARE UPDATE
+ EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
+ ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
+ <literal>ACCESS EXCLUSIVE</literal> lock modes.
+ This mode allows only concurrent <literal>ACCESS SHARE</literal> locks,
+ i.e., only reads from the table can proceed in parallel with a
+ transaction holding this lock mode.
+ </para>
+
+ <para>
+ Acquired by <command>REFRESH MATERIALIZED VIEW CONCURRENTLY</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>ACCESS EXCLUSIVE</literal> (<literal>AccessExclusiveLock</literal>)
+ </term>
+ <listitem>
+ <para>
+ Conflicts with locks of all modes (<literal>ACCESS
+ SHARE</literal>, <literal>ROW SHARE</literal>, <literal>ROW
+ EXCLUSIVE</literal>, <literal>SHARE UPDATE
+ EXCLUSIVE</literal>, <literal>SHARE</literal>, <literal>SHARE
+ ROW EXCLUSIVE</literal>, <literal>EXCLUSIVE</literal>, and
+ <literal>ACCESS EXCLUSIVE</literal>).
+ This mode guarantees that the
+ holder is the only transaction accessing the table in any way.
+ </para>
+
+ <para>
+ Acquired by the <command>DROP TABLE</command>,
+ <command>TRUNCATE</command>, <command>REINDEX</command>,
+ <command>CLUSTER</command>, <command>VACUUM FULL</command>,
+ and <command>REFRESH MATERIALIZED VIEW</command> (without
+ <option>CONCURRENTLY</option>)
+ commands. Many forms of <command>ALTER INDEX</command> and <command>ALTER TABLE</command> also acquire
+ a lock at this level. This is also the default lock mode for
+ <command>LOCK TABLE</command> statements that do not specify
+ a mode explicitly.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <tip>
+ <para>
+ Only an <literal>ACCESS EXCLUSIVE</literal> lock blocks a
+ <command>SELECT</command> (without <option>FOR UPDATE/SHARE</option>)
+ statement.
+ </para>
+ </tip>
+
+ <para>
+ Once acquired, a lock is normally held until the end of the transaction. But if a
+ lock is acquired after establishing a savepoint, the lock is released
+ immediately if the savepoint is rolled back to. This is consistent with
+ the principle that <command>ROLLBACK</command> cancels all effects of the
+ commands since the savepoint. The same holds for locks acquired within a
+ <application>PL/pgSQL</application> exception block: an error escape from the block
+ releases locks acquired within it.
+ </para>
+
+
+
+ <table tocentry="1" id="table-lock-compatibility">
+ <title>Conflicting Lock Modes</title>
+ <tgroup cols="9">
+ <colspec colnum="1" colwidth="1.25*"/>
+ <colspec colnum="2" colwidth="1*" colname="lockst"/>
+ <colspec colnum="3" colwidth="1*"/>
+ <colspec colnum="4" colwidth="1*"/>
+ <colspec colnum="5" colwidth="1*"/>
+ <colspec colnum="6" colwidth="1*"/>
+ <colspec colnum="7" colwidth="1*"/>
+ <colspec colnum="8" colwidth="1*"/>
+ <colspec colnum="9" colwidth="1*" colname="lockend"/>
+ <spanspec spanname="lockreq" namest="lockst" nameend="lockend" align="center"/>
+ <thead>
+ <row>
+ <entry morerows="1">Requested Lock Mode</entry>
+ <entry spanname="lockreq">Existing Lock Mode</entry>
+ </row>
+ <row>
+ <entry><literal>ACCESS SHARE</literal></entry>
+ <entry><literal>ROW SHARE</literal></entry>
+ <entry><literal>ROW EXCL.</literal></entry>
+ <entry><literal>SHARE UPDATE EXCL.</literal></entry>
+ <entry><literal>SHARE</literal></entry>
+ <entry><literal>SHARE ROW EXCL.</literal></entry>
+ <entry><literal>EXCL.</literal></entry>
+ <entry><literal>ACCESS EXCL.</literal></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>ACCESS SHARE</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>ROW SHARE</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>ROW EXCL.</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>SHARE UPDATE EXCL.</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>SHARE</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>SHARE ROW EXCL.</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>EXCL.</literal></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry><literal>ACCESS EXCL.</literal></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="locking-rows">
+ <title>Row-Level Locks</title>
+
+ <para>
+ In addition to table-level locks, there are row-level locks, which
+ are listed as below with the contexts in which they are used
+ automatically by <productname>PostgreSQL</productname>. See
+ <xref linkend="row-lock-compatibility"/> for a complete table of
+ row-level lock conflicts. Note that a transaction can hold
+ conflicting locks on the same row, even in different subtransactions;
+ but other than that, two transactions can never hold conflicting locks
+ on the same row. Row-level locks do not affect data querying; they
+ block only <emphasis>writers and lockers</emphasis> to the same
+ row. Row-level locks are released at transaction end or during
+ savepoint rollback, just like table-level locks.
+
+ </para>
+
+ <variablelist>
+ <title>Row-Level Lock Modes</title>
+ <varlistentry>
+ <term>
+ <literal>FOR UPDATE</literal>
+ </term>
+ <listitem>
+ <para>
+ <literal>FOR UPDATE</literal> causes the rows retrieved by the
+ <command>SELECT</command> statement to be locked as though for
+ update. This prevents them from being locked, modified or deleted by
+ other transactions until the current transaction ends. That is,
+ other transactions that attempt <command>UPDATE</command>,
+ <command>DELETE</command>,
+ <command>SELECT FOR UPDATE</command>,
+ <command>SELECT FOR NO KEY UPDATE</command>,
+ <command>SELECT FOR SHARE</command> or
+ <command>SELECT FOR KEY SHARE</command>
+ of these rows will be blocked until the current transaction ends;
+ conversely, <command>SELECT FOR UPDATE</command> will wait for a
+ concurrent transaction that has run any of those commands on the
+ same row,
+ and will then lock and return the updated row (or no row, if the
+ row was deleted). Within a <literal>REPEATABLE READ</literal> or
+ <literal>SERIALIZABLE</literal> transaction,
+ however, an error will be thrown if a row to be locked has changed
+ since the transaction started. For further discussion see
+ <xref linkend="applevel-consistency"/>.
+ </para>
+ <para>
+ The <literal>FOR UPDATE</literal> lock mode
+ is also acquired by any <command>DELETE</command> on a row, and also by an
+ <command>UPDATE</command> that modifies the values of certain columns. Currently,
+ the set of columns considered for the <command>UPDATE</command> case are those that
+ have a unique index on them that can be used in a foreign key (so partial
+ indexes and expressional indexes are not considered), but this may change
+ in the future.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>FOR NO KEY UPDATE</literal>
+ </term>
+ <listitem>
+ <para>
+ Behaves similarly to <literal>FOR UPDATE</literal>, except that the lock
+ acquired is weaker: this lock will not block
+ <literal>SELECT FOR KEY SHARE</literal> commands that attempt to acquire
+ a lock on the same rows. This lock mode is also acquired by any
+ <command>UPDATE</command> that does not acquire a <literal>FOR UPDATE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>FOR SHARE</literal>
+ </term>
+ <listitem>
+ <para>
+ Behaves similarly to <literal>FOR NO KEY UPDATE</literal>, except that it
+ acquires a shared lock rather than exclusive lock on each retrieved
+ row. A shared lock blocks other transactions from performing
+ <command>UPDATE</command>, <command>DELETE</command>,
+ <command>SELECT FOR UPDATE</command> or
+ <command>SELECT FOR NO KEY UPDATE</command> on these rows, but it does not
+ prevent them from performing <command>SELECT FOR SHARE</command> or
+ <command>SELECT FOR KEY SHARE</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>FOR KEY SHARE</literal>
+ </term>
+ <listitem>
+ <para>
+ Behaves similarly to <literal>FOR SHARE</literal>, except that the
+ lock is weaker: <literal>SELECT FOR UPDATE</literal> is blocked, but not
+ <literal>SELECT FOR NO KEY UPDATE</literal>. A key-shared lock blocks
+ other transactions from performing <command>DELETE</command> or
+ any <command>UPDATE</command> that changes the key values, but not
+ other <command>UPDATE</command>, and neither does it prevent
+ <command>SELECT FOR NO KEY UPDATE</command>, <command>SELECT FOR SHARE</command>,
+ or <command>SELECT FOR KEY SHARE</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ <productname>PostgreSQL</productname> doesn't remember any
+ information about modified rows in memory, so there is no limit on
+ the number of rows locked at one time. However, locking a row
+ might cause a disk write, e.g., <command>SELECT FOR
+ UPDATE</command> modifies selected rows to mark them locked, and so
+ will result in disk writes.
+ </para>
+
+ <table tocentry="1" id="row-lock-compatibility">
+ <title>Conflicting Row-Level Locks</title>
+ <tgroup cols="5">
+ <colspec colname="col1" colwidth="1.5*"/>
+ <colspec colname="lockst" colwidth="1*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <colspec colname="col4" colwidth="1*"/>
+ <colspec colname="lockend" colwidth="1*"/>
+ <spanspec namest="lockst" nameend="lockend" spanname="lockreq"/>
+ <thead>
+ <row>
+ <entry morerows="1">Requested Lock Mode</entry>
+ <entry spanname="lockreq">Current Lock Mode</entry>
+ </row>
+ <row>
+ <entry>FOR KEY SHARE</entry>
+ <entry>FOR SHARE</entry>
+ <entry>FOR NO KEY UPDATE</entry>
+ <entry>FOR UPDATE</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>FOR KEY SHARE</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry>FOR SHARE</entry>
+ <entry align="center"></entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry>FOR NO KEY UPDATE</entry>
+ <entry align="center"></entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ <row>
+ <entry>FOR UPDATE</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ <entry align="center">X</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="locking-pages">
+ <title>Page-Level Locks</title>
+
+ <para>
+ In addition to table and row locks, page-level share/exclusive locks are
+ used to control read/write access to table pages in the shared buffer
+ pool. These locks are released immediately after a row is fetched or
+ updated. Application developers normally need not be concerned with
+ page-level locks, but they are mentioned here for completeness.
+ </para>
+
+ </sect2>
+
+ <sect2 id="locking-deadlocks">
+ <title>Deadlocks</title>
+
+ <indexterm zone="locking-deadlocks">
+ <primary>deadlock</primary>
+ </indexterm>
+
+ <para>
+ The use of explicit locking can increase the likelihood of
+ <firstterm>deadlocks</firstterm>, wherein two (or more) transactions each
+ hold locks that the other wants. For example, if transaction 1
+ acquires an exclusive lock on table A and then tries to acquire
+ an exclusive lock on table B, while transaction 2 has already
+ exclusive-locked table B and now wants an exclusive lock on table
+ A, then neither one can proceed.
+ <productname>PostgreSQL</productname> automatically detects
+ deadlock situations and resolves them by aborting one of the
+ transactions involved, allowing the other(s) to complete.
+ (Exactly which transaction will be aborted is difficult to
+ predict and should not be relied upon.)
+ </para>
+
+ <para>
+ Note that deadlocks can also occur as the result of row-level
+ locks (and thus, they can occur even if explicit locking is not
+ used). Consider the case in which two concurrent
+ transactions modify a table. The first transaction executes:
+
+<screen>
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;
+</screen>
+
+ This acquires a row-level lock on the row with the specified
+ account number. Then, the second transaction executes:
+
+<screen>
+UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;
+</screen>
+
+ The first <command>UPDATE</command> statement successfully
+ acquires a row-level lock on the specified row, so it succeeds in
+ updating that row. However, the second <command>UPDATE</command>
+ statement finds that the row it is attempting to update has
+ already been locked, so it waits for the transaction that
+ acquired the lock to complete. Transaction two is now waiting on
+ transaction one to complete before it continues execution. Now,
+ transaction one executes:
+
+<screen>
+UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
+</screen>
+
+ Transaction one attempts to acquire a row-level lock on the
+ specified row, but it cannot: transaction two already holds such
+ a lock. So it waits for transaction two to complete. Thus,
+ transaction one is blocked on transaction two, and transaction
+ two is blocked on transaction one: a deadlock
+ condition. <productname>PostgreSQL</productname> will detect this
+ situation and abort one of the transactions.
+ </para>
+
+ <para>
+ The best defense against deadlocks is generally to avoid them by
+ being certain that all applications using a database acquire
+ locks on multiple objects in a consistent order. In the example
+ above, if both transactions
+ had updated the rows in the same order, no deadlock would have
+ occurred. One should also ensure that the first lock acquired on
+ an object in a transaction is the most restrictive mode that will be
+ needed for that object. If it is not feasible to verify this in
+ advance, then deadlocks can be handled on-the-fly by retrying
+ transactions that abort due to deadlocks.
+ </para>
+
+ <para>
+ So long as no deadlock situation is detected, a transaction seeking
+ either a table-level or row-level lock will wait indefinitely for
+ conflicting locks to be released. This means it is a bad idea for
+ applications to hold transactions open for long periods of time
+ (e.g., while waiting for user input).
+ </para>
+ </sect2>
+
+ <sect2 id="advisory-locks">
+ <title>Advisory Locks</title>
+
+ <indexterm zone="advisory-locks">
+ <primary>advisory lock</primary>
+ </indexterm>
+
+ <indexterm zone="advisory-locks">
+ <primary>lock</primary>
+ <secondary>advisory</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a means for
+ creating locks that have application-defined meanings. These are
+ called <firstterm>advisory locks</firstterm>, because the system does not
+ enforce their use &mdash; it is up to the application to use them
+ correctly. Advisory locks can be useful for locking strategies
+ that are an awkward fit for the MVCC model.
+ For example, a common use of advisory locks is to emulate pessimistic
+ locking strategies typical of so-called <quote>flat file</quote> data
+ management systems.
+ While a flag stored in a table could be used for the same purpose,
+ advisory locks are faster, avoid table bloat, and are automatically
+ cleaned up by the server at the end of the session.
+ </para>
+
+ <para>
+ There are two ways to acquire an advisory lock in
+ <productname>PostgreSQL</productname>: at session level or at
+ transaction level.
+ Once acquired at session level, an advisory lock is held until
+ explicitly released or the session ends. Unlike standard lock requests,
+ session-level advisory lock requests do not honor transaction semantics:
+ a lock acquired during a transaction that is later rolled back will still
+ be held following the rollback, and likewise an unlock is effective even
+ if the calling transaction fails later. A lock can be acquired multiple
+ times by its owning process; for each completed lock request there must
+ be a corresponding unlock request before the lock is actually released.
+ Transaction-level lock requests, on the other hand, behave more like
+ regular lock requests: they are automatically released at the end of the
+ transaction, and there is no explicit unlock operation. This behavior
+ is often more convenient than the session-level behavior for short-term
+ usage of an advisory lock.
+ Session-level and transaction-level lock requests for the same advisory
+ lock identifier will block each other in the expected way.
+ If a session already holds a given advisory lock, additional requests by
+ it will always succeed, even if other sessions are awaiting the lock; this
+ statement is true regardless of whether the existing lock hold and new
+ request are at session level or transaction level.
+ </para>
+
+ <para>
+ Like all locks in
+ <productname>PostgreSQL</productname>, a complete list of advisory locks
+ currently held by any session can be found in the <link
+ linkend="view-pg-locks"><structname>pg_locks</structname></link> system
+ view.
+ </para>
+
+ <para>
+ Both advisory locks and regular locks are stored in a shared memory
+ pool whose size is defined by the configuration variables
+ <xref linkend="guc-max-locks-per-transaction"/> and
+ <xref linkend="guc-max-connections"/>.
+ Care must be taken not to exhaust this
+ memory or the server will be unable to grant any locks at all.
+ This imposes an upper limit on the number of advisory locks
+ grantable by the server, typically in the tens to hundreds of thousands
+ depending on how the server is configured.
+ </para>
+
+ <para>
+ In certain cases using advisory locking methods, especially in queries
+ involving explicit ordering and <literal>LIMIT</literal> clauses, care must be
+ taken to control the locks acquired because of the order in which SQL
+ expressions are evaluated. For example:
+<screen>
+SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
+SELECT pg_advisory_lock(id) FROM foo WHERE id &gt; 12345 LIMIT 100; -- danger!
+SELECT pg_advisory_lock(q.id) FROM
+(
+ SELECT id FROM foo WHERE id &gt; 12345 LIMIT 100
+) q; -- ok
+</screen>
+ In the above queries, the second form is dangerous because the
+ <literal>LIMIT</literal> is not guaranteed to be applied before the locking
+ function is executed. This might cause some locks to be acquired
+ that the application was not expecting, and hence would fail to release
+ (until it ends the session).
+ From the point of view of the application, such locks
+ would be dangling, although still viewable in
+ <structname>pg_locks</structname>.
+ </para>
+
+ <para>
+ The functions provided to manipulate advisory locks are described in
+ <xref linkend="functions-advisory-locks"/>.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="applevel-consistency">
+ <title>Data Consistency Checks at the Application Level</title>
+
+ <para>
+ It is very difficult to enforce business rules regarding data integrity
+ using Read Committed transactions because the view of the data is
+ shifting with each statement, and even a single statement may not
+ restrict itself to the statement's snapshot if a write conflict occurs.
+ </para>
+
+ <para>
+ While a Repeatable Read transaction has a stable view of the data
+ throughout its execution, there is a subtle issue with using
+ <acronym>MVCC</acronym> snapshots for data consistency checks, involving
+ something known as <firstterm>read/write conflicts</firstterm>.
+ If one transaction writes data and a concurrent transaction attempts
+ to read the same data (whether before or after the write), it cannot
+ see the work of the other transaction. The reader then appears to have
+ executed first regardless of which started first or which committed
+ first. If that is as far as it goes, there is no problem, but
+ if the reader also writes data which is read by a concurrent transaction
+ there is now a transaction which appears to have run before either of
+ the previously mentioned transactions. If the transaction which appears
+ to have executed last actually commits first, it is very easy for a
+ cycle to appear in a graph of the order of execution of the transactions.
+ When such a cycle appears, integrity checks will not work correctly
+ without some help.
+ </para>
+
+ <para>
+ As mentioned in <xref linkend="xact-serializable"/>, Serializable
+ transactions are just Repeatable Read transactions which add
+ nonblocking monitoring for dangerous patterns of read/write conflicts.
+ When a pattern is detected which could cause a cycle in the apparent
+ order of execution, one of the transactions involved is rolled back to
+ break the cycle.
+ </para>
+
+ <sect2 id="serializable-consistency">
+ <title>Enforcing Consistency with Serializable Transactions</title>
+
+ <para>
+ If the Serializable transaction isolation level is used for all writes
+ and for all reads which need a consistent view of the data, no other
+ effort is required to ensure consistency. Software from other
+ environments which is written to use serializable transactions to
+ ensure consistency should <quote>just work</quote> in this regard in
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ When using this technique, it will avoid creating an unnecessary burden
+ for application programmers if the application software goes through a
+ framework which automatically retries transactions which are rolled
+ back with a serialization failure. It may be a good idea to set
+ <literal>default_transaction_isolation</literal> to <literal>serializable</literal>.
+ It would also be wise to take some action to ensure that no other
+ transaction isolation level is used, either inadvertently or to
+ subvert integrity checks, through checks of the transaction isolation
+ level in triggers.
+ </para>
+
+ <para>
+ See <xref linkend="xact-serializable"/> for performance suggestions.
+ </para>
+
+ <warning>
+ <para>
+ This level of integrity protection using Serializable transactions
+ does not yet extend to hot standby mode (<xref linkend="hot-standby"/>).
+ Because of that, those using hot standby may want to use Repeatable
+ Read and explicit locking on the primary.
+ </para>
+ </warning>
+ </sect2>
+
+ <sect2 id="non-serializable-consistency">
+ <title>Enforcing Consistency with Explicit Blocking Locks</title>
+
+ <para>
+ When non-serializable writes are possible,
+ to ensure the current validity of a row and protect it against
+ concurrent updates one must use <command>SELECT FOR UPDATE</command>,
+ <command>SELECT FOR SHARE</command>, or an appropriate <command>LOCK
+ TABLE</command> statement. (<command>SELECT FOR UPDATE</command>
+ and <command>SELECT FOR SHARE</command> lock just the
+ returned rows against concurrent updates, while <command>LOCK
+ TABLE</command> locks the whole table.) This should be taken into
+ account when porting applications to
+ <productname>PostgreSQL</productname> from other environments.
+ </para>
+
+ <para>
+ Also of note to those converting from other environments is the fact
+ that <command>SELECT FOR UPDATE</command> does not ensure that a
+ concurrent transaction will not update or delete a selected row.
+ To do that in <productname>PostgreSQL</productname> you must actually
+ update the row, even if no values need to be changed.
+ <command>SELECT FOR UPDATE</command> <emphasis>temporarily blocks</emphasis>
+ other transactions from acquiring the same lock or executing an
+ <command>UPDATE</command> or <command>DELETE</command> which would
+ affect the locked row, but once the transaction holding this lock
+ commits or rolls back, a blocked transaction will proceed with the
+ conflicting operation unless an actual <command>UPDATE</command> of
+ the row was performed while the lock was held.
+ </para>
+
+ <para>
+ Global validity checks require extra thought under
+ non-serializable <acronym>MVCC</acronym>.
+ For example, a banking application might wish to check that the sum of
+ all credits in one table equals the sum of debits in another table,
+ when both tables are being actively updated. Comparing the results of two
+ successive <literal>SELECT sum(...)</literal> commands will not work reliably in
+ Read Committed mode, since the second query will likely include the results
+ of transactions not counted by the first. Doing the two sums in a
+ single repeatable read transaction will give an accurate picture of only the
+ effects of transactions that committed before the repeatable read transaction
+ started &mdash; but one might legitimately wonder whether the answer is still
+ relevant by the time it is delivered. If the repeatable read transaction
+ itself applied some changes before trying to make the consistency check,
+ the usefulness of the check becomes even more debatable, since now it
+ includes some but not all post-transaction-start changes. In such cases
+ a careful person might wish to lock all tables needed for the check,
+ in order to get an indisputable picture of current reality. A
+ <literal>SHARE</literal> mode (or higher) lock guarantees that there are no
+ uncommitted changes in the locked table, other than those of the current
+ transaction.
+ </para>
+
+ <para>
+ Note also that if one is relying on explicit locking to prevent concurrent
+ changes, one should either use Read Committed mode, or in Repeatable Read
+ mode be careful to obtain
+ locks before performing queries. A lock obtained by a
+ repeatable read transaction guarantees that no other transactions modifying
+ the table are still running, but if the snapshot seen by the
+ transaction predates obtaining the lock, it might predate some now-committed
+ changes in the table. A repeatable read transaction's snapshot is actually
+ frozen at the start of its first query or data-modification command
+ (<literal>SELECT</literal>, <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, <literal>DELETE</literal>, or
+ <literal>MERGE</literal>), so it is possible to obtain locks explicitly
+ before the snapshot is frozen.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mvcc-serialization-failure-handling">
+ <title>Serialization Failure Handling</title>
+
+ <indexterm>
+ <primary>serialization failure</primary>
+ </indexterm>
+ <indexterm>
+ <primary>retryable error</primary>
+ </indexterm>
+
+ <para>
+ Both Repeatable Read and Serializable isolation levels can produce
+ errors that are designed to prevent serialization anomalies. As
+ previously stated, applications using these levels must be prepared to
+ retry transactions that fail due to serialization errors. Such an
+ error's message text will vary according to the precise circumstances,
+ but it will always have the SQLSTATE code <literal>40001</literal>
+ (<literal>serialization_failure</literal>).
+ </para>
+
+ <para>
+ It may also be advisable to retry deadlock failures.
+ These have the SQLSTATE code <literal>40P01</literal>
+ (<literal>deadlock_detected</literal>).
+ </para>
+
+ <para>
+ In some cases it is also appropriate to retry unique-key failures,
+ which have SQLSTATE code <literal>23505</literal>
+ (<literal>unique_violation</literal>), and exclusion constraint
+ failures, which have SQLSTATE code <literal>23P01</literal>
+ (<literal>exclusion_violation</literal>). For example, if the
+ application selects a new value for a primary key column after
+ inspecting the currently stored keys, it could get a unique-key
+ failure because another application instance selected the same new key
+ concurrently. This is effectively a serialization failure, but the
+ server will not detect it as such because it cannot <quote>see</quote>
+ the connection between the inserted value and the previous reads.
+ There are also some corner cases in which the server will issue a
+ unique-key or exclusion constraint error even though in principle it
+ has enough information to determine that a serialization problem
+ is the underlying cause. While it's recommendable to just
+ retry <literal>serialization_failure</literal> errors unconditionally,
+ more care is needed when retrying these other error codes, since they
+ might represent persistent error conditions rather than transient
+ failures.
+ </para>
+
+ <para>
+ It is important to retry the complete transaction, including all logic
+ that decides which SQL to issue and/or which values to use.
+ Therefore, <productname>PostgreSQL</productname> does not offer an
+ automatic retry facility, since it cannot do so with any guarantee of
+ correctness.
+ </para>
+
+ <para>
+ Transaction retry does not guarantee that the retried transaction will
+ complete; multiple retries may be needed. In cases with very high
+ contention, it is possible that completion of a transaction may take
+ many attempts. In cases involving a conflicting prepared transaction,
+ it may not be possible to make progress until the prepared transaction
+ commits or rolls back.
+ </para>
+ </sect1>
+
+ <sect1 id="mvcc-caveats">
+ <title>Caveats</title>
+
+ <para>
+ Some DDL commands, currently only <link linkend="sql-truncate"><command>TRUNCATE</command></link> and the
+ table-rewriting forms of <link linkend="sql-altertable"><command>ALTER TABLE</command></link>, are not
+ MVCC-safe. This means that after the truncation or rewrite commits, the
+ table will appear empty to concurrent transactions, if they are using a
+ snapshot taken before the DDL command committed. This will only be an
+ issue for a transaction that did not access the table in question
+ before the DDL command started &mdash; any transaction that has done so
+ would hold at least an <literal>ACCESS SHARE</literal> table lock,
+ which would block the DDL command until that transaction completes.
+ So these commands will not cause any apparent inconsistency in the
+ table contents for successive queries on the target table, but they
+ could cause visible inconsistency between the contents of the target
+ table and other tables in the database.
+ </para>
+
+ <para>
+ Support for the Serializable transaction isolation level has not yet
+ been added to hot standby replication targets (described in
+ <xref linkend="hot-standby"/>). The strictest isolation level currently
+ supported in hot standby mode is Repeatable Read. While performing all
+ permanent database writes within Serializable transactions on the
+ primary will ensure that all standbys will eventually reach a consistent
+ state, a Repeatable Read transaction run on the standby can sometimes
+ see a transient state that is inconsistent with any serial execution
+ of the transactions on the primary.
+ </para>
+
+ <para>
+ Internal access to the system catalogs is not done using the isolation
+ level of the current transaction. This means that newly created database
+ objects such as tables are visible to concurrent Repeatable Read and
+ Serializable transactions, even though the rows they contain are not. In
+ contrast, queries that explicitly examine the system catalogs don't see
+ rows representing concurrently created database objects, in the higher
+ isolation levels.
+ </para>
+ </sect1>
+
+ <sect1 id="locking-indexes">
+ <title>Locking and Indexes</title>
+
+ <indexterm zone="locking-indexes">
+ <primary>index</primary>
+ <secondary>locks</secondary>
+ </indexterm>
+
+ <para>
+ Though <productname>PostgreSQL</productname>
+ provides nonblocking read/write access to table
+ data, nonblocking read/write access is not currently offered for every
+ index access method implemented
+ in <productname>PostgreSQL</productname>.
+ The various index types are handled as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ B-tree, <acronym>GiST</acronym> and <acronym>SP-GiST</acronym> indexes
+ </term>
+ <listitem>
+ <para>
+ Short-term share/exclusive page-level locks are used for
+ read/write access. Locks are released immediately after each
+ index row is fetched or inserted. These index types provide
+ the highest concurrency without deadlock conditions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ Hash indexes
+ </term>
+ <listitem>
+ <para>
+ Share/exclusive hash-bucket-level locks are used for read/write
+ access. Locks are released after the whole bucket is processed.
+ Bucket-level locks provide better concurrency than index-level
+ ones, but deadlock is possible since the locks are held longer
+ than one index operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <acronym>GIN</acronym> indexes
+ </term>
+ <listitem>
+ <para>
+ Short-term share/exclusive page-level locks are used for
+ read/write access. Locks are released immediately after each
+ index row is fetched or inserted. But note that insertion of a
+ GIN-indexed value usually produces several index key insertions
+ per row, so GIN might do substantial work for a single value's
+ insertion.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Currently, B-tree indexes offer the best performance for concurrent
+ applications; since they also have more features than hash
+ indexes, they are the recommended index type for concurrent
+ applications that need to index scalar data. When dealing with
+ non-scalar data, B-trees are not useful, and GiST, SP-GiST or GIN
+ indexes should be used instead.
+ </para>
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/nls.sgml b/doc/src/sgml/nls.sgml
new file mode 100644
index 0000000..d49f44f
--- /dev/null
+++ b/doc/src/sgml/nls.sgml
@@ -0,0 +1,532 @@
+<!-- doc/src/sgml/nls.sgml -->
+
+<chapter id="nls">
+ <title>Native Language Support</title>
+
+ <sect1 id="nls-translator">
+ <title>For the Translator</title>
+
+ <para>
+ <productname>PostgreSQL</productname>
+ programs (server and client) can issue their messages in
+ your favorite language &mdash; if the messages have been translated.
+ Creating and maintaining translated message sets needs the help of
+ people who speak their own language well and want to contribute to
+ the <productname>PostgreSQL</productname> effort. You do not have to be a
+ programmer at all
+ to do this. This section explains how to help.
+ </para>
+
+ <sect2>
+ <title>Requirements</title>
+
+ <para>
+ We won't judge your language skills &mdash; this section is about
+ software tools. Theoretically, you only need a text editor. But
+ this is only in the unlikely event that you do not want to try out
+ your translated messages. When you configure your source tree, be
+ sure to use the <option>--enable-nls</option> option. This will
+ also check for the <application>libintl</application> library and the
+ <filename>msgfmt</filename> program, which all end users will need
+ anyway. To try out your work, follow the applicable portions of
+ the installation instructions.
+ </para>
+
+ <para>
+ If you want to start a new translation effort or want to do a
+ message catalog merge (described later), you will need the
+ programs <filename>xgettext</filename> and
+ <filename>msgmerge</filename>, respectively, in a GNU-compatible
+ implementation. Later, we will try to arrange it so that if you
+ use a packaged source distribution, you won't need
+ <filename>xgettext</filename>. (If working from Git, you will still need
+ it.) <application>GNU Gettext 0.10.36</application> or later is currently recommended.
+ </para>
+
+ <para>
+ Your local gettext implementation should come with its own
+ documentation. Some of that is probably duplicated in what
+ follows, but for additional details you should look there.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Concepts</title>
+
+ <para>
+ The pairs of original (English) messages and their (possibly)
+ translated equivalents are kept in <firstterm>message
+ catalogs</firstterm>, one for each program (although related
+ programs can share a message catalog) and for each target
+ language. There are two file formats for message catalogs: The
+ first is the <quote>PO</quote> file (for Portable Object), which
+ is a plain text file with special syntax that translators edit.
+ The second is the <quote>MO</quote> file (for Machine Object),
+ which is a binary file generated from the respective PO file and
+ is used while the internationalized program is run. Translators
+ do not deal with MO files; in fact hardly anyone does.
+ </para>
+
+ <para>
+ The extension of the message catalog file is to no surprise either
+ <filename>.po</filename> or <filename>.mo</filename>. The base
+ name is either the name of the program it accompanies, or the
+ language the file is for, depending on the situation. This is a
+ bit confusing. Examples are <filename>psql.po</filename> (PO file
+ for psql) or <filename>fr.mo</filename> (MO file in French).
+ </para>
+
+ <para>
+ The file format of the PO files is illustrated here:
+<programlisting>
+# comment
+
+msgid "original string"
+msgstr "translated string"
+
+msgid "more original"
+msgstr "another translated"
+"string can be broken up like this"
+
+...
+</programlisting>
+ The msgid lines are extracted from the program source. (They need not
+ be, but this is the most common way.) The msgstr lines are
+ initially empty and are filled in with useful strings by the
+ translator. The strings can contain C-style escape characters and
+ can be continued across lines as illustrated. (The next line must
+ start at the beginning of the line.)
+ </para>
+
+ <para>
+ The # character introduces a comment. If whitespace immediately
+ follows the # character, then this is a comment maintained by the
+ translator. There can also be automatic comments, which have a
+ non-whitespace character immediately following the #. These are
+ maintained by the various tools that operate on the PO files and
+ are intended to aid the translator.
+<programlisting>
+#. automatic comment
+#: filename.c:1023
+#, flags, flags
+</programlisting>
+ The #. style comments are extracted from the source file where the
+ message is used. Possibly the programmer has inserted information
+ for the translator, such as about expected alignment. The #:
+ comments indicate the exact locations where the message is used
+ in the source. The translator need not look at the program
+ source, but can if there is doubt about the correct
+ translation. The #, comments contain flags that describe the
+ message in some way. There are currently two flags:
+ <literal>fuzzy</literal> is set if the message has possibly been
+ outdated because of changes in the program source. The translator
+ can then verify this and possibly remove the fuzzy flag. Note
+ that fuzzy messages are not made available to the end user. The
+ other flag is <literal>c-format</literal>, which indicates that
+ the message is a <function>printf</function>-style format
+ template. This means that the translation should also be a format
+ string with the same number and type of placeholders. There are
+ tools that can verify this, which key off the c-format flag.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Creating and Maintaining Message Catalogs</title>
+
+ <para>
+ OK, so how does one create a <quote>blank</quote> message
+ catalog? First, go into the directory that contains the program
+ whose messages you want to translate. If there is a file
+ <filename>nls.mk</filename>, then this program has been prepared
+ for translation.
+ </para>
+
+ <para>
+ If there are already some <filename>.po</filename> files, then
+ someone has already done some translation work. The files are
+ named <filename><replaceable>language</replaceable>.po</filename>,
+ where <replaceable>language</replaceable> is the
+ <ulink url="https://www.loc.gov/standards/iso639-2/php/English_list.php">
+ ISO 639-1 two-letter language code (in lower case)</ulink>, e.g.,
+ <filename>fr.po</filename> for French. If there is really a need
+ for more than one translation effort per language then the files
+ can also be named
+ <filename><replaceable>language</replaceable>_<replaceable>region</replaceable>.po</filename>
+ where <replaceable>region</replaceable> is the
+ <ulink url="https://www.iso.org/iso-3166-country-codes.html">
+ ISO 3166-1 two-letter country code (in upper case)</ulink>,
+ e.g.,
+ <filename>pt_BR.po</filename> for Portuguese in Brazil. If you
+ find the language you wanted you can just start working on that
+ file.
+ </para>
+
+ <para>
+ If you need to start a new translation effort, then first run the
+ command:
+<programlisting>
+make init-po
+</programlisting>
+ This will create a file
+ <filename><replaceable>progname</replaceable>.pot</filename>.
+ (<filename>.pot</filename> to distinguish it from PO files that
+ are <quote>in production</quote>. The <literal>T</literal> stands for
+ <quote>template</quote>.)
+ Copy this file to
+ <filename><replaceable>language</replaceable>.po</filename> and
+ edit it. To make it known that the new language is available,
+ also edit the file <filename>nls.mk</filename> and add the
+ language (or language and country) code to the line that looks like:
+<programlisting>
+AVAIL_LANGUAGES := de fr
+</programlisting>
+ (Other languages can appear, of course.)
+ </para>
+
+ <para>
+ As the underlying program or library changes, messages might be
+ changed or added by the programmers. In this case you do not need
+ to start from scratch. Instead, run the command:
+<programlisting>
+make update-po
+</programlisting>
+ which will create a new blank message catalog file (the pot file
+ you started with) and will merge it with the existing PO files.
+ If the merge algorithm is not sure about a particular message it
+ marks it <quote>fuzzy</quote> as explained above. The new PO file
+ is saved with a <filename>.po.new</filename> extension.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Editing the PO Files</title>
+
+ <para>
+ The PO files can be edited with a regular text editor. The
+ translator should only change the area between the quotes after
+ the msgstr directive, add comments, and alter the fuzzy flag.
+ There is (unsurprisingly) a PO mode for Emacs, which I find quite
+ useful.
+ </para>
+
+ <para>
+ The PO files need not be completely filled in. The software will
+ automatically fall back to the original string if no translation
+ (or an empty translation) is available. It is no problem to
+ submit incomplete translations for inclusions in the source tree;
+ that gives room for other people to pick up your work. However,
+ you are encouraged to give priority to removing fuzzy entries
+ after doing a merge. Remember that fuzzy entries will not be
+ installed; they only serve as reference for what might be the right
+ translation.
+ </para>
+
+ <para>
+ Here are some things to keep in mind while editing the
+ translations:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Make sure that if the original ends with a newline, the
+ translation does, too. Similarly for tabs, etc.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the original is a <function>printf</function> format string, the translation
+ also needs to be. The translation also needs to have the same
+ format specifiers in the same order. Sometimes the natural
+ rules of the language make this impossible or at least awkward.
+ In that case you can modify the format specifiers like this:
+<programlisting>
+msgstr "Die Datei %2$s hat %1$u Zeichen."
+</programlisting>
+ Then the first placeholder will actually use the second
+ argument from the list. The
+ <literal><replaceable>digits</replaceable>$</literal> needs to
+ follow the % immediately, before any other format manipulators.
+ (This feature really exists in the <function>printf</function>
+ family of functions. You might not have heard of it before because
+ there is little use for it outside of message
+ internationalization.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the original string contains a linguistic mistake, report
+ that (or fix it yourself in the program source) and translate
+ normally. The corrected string can be merged in when the
+ program sources have been updated. If the original string
+ contains a factual mistake, report that (or fix it yourself)
+ and do not translate it. Instead, you can mark the string with
+ a comment in the PO file.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Maintain the style and tone of the original string.
+ Specifically, messages that are not sentences (<literal>cannot
+ open file %s</literal>) should probably not start with a
+ capital letter (if your language distinguishes letter case) or
+ end with a period (if your language uses punctuation marks).
+ It might help to read <xref linkend="error-style-guide"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you don't know what a message means, or if it is ambiguous,
+ ask on the developers' mailing list. Chances are that English
+ speaking end users might also not understand it or find it
+ ambiguous, so it's best to improve the message.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ </sect1>
+
+
+ <sect1 id="nls-programmer">
+ <title>For the Programmer</title>
+
+ <sect2 id="nls-mechanics">
+ <title>Mechanics</title>
+
+ <para>
+ This section describes how to implement native language support in a
+ program or library that is part of the
+ <productname>PostgreSQL</productname> distribution.
+ Currently, it only applies to C programs.
+ </para>
+
+ <procedure>
+ <title>Adding NLS Support to a Program</title>
+
+ <step>
+ <para>
+ Insert this code into the start-up sequence of the program:
+<programlisting>
+#ifdef ENABLE_NLS
+#include &lt;locale.h&gt;
+#endif
+
+...
+
+#ifdef ENABLE_NLS
+setlocale(LC_ALL, "");
+bindtextdomain("<replaceable>progname</replaceable>", LOCALEDIR);
+textdomain("<replaceable>progname</replaceable>");
+#endif
+</programlisting>
+ (The <replaceable>progname</replaceable> can actually be chosen
+ freely.)
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Wherever a message that is a candidate for translation is found,
+ a call to <function>gettext()</function> needs to be inserted. E.g.:
+<programlisting>
+fprintf(stderr, "panic level %d\n", lvl);
+</programlisting>
+ would be changed to:
+<programlisting>
+fprintf(stderr, gettext("panic level %d\n"), lvl);
+</programlisting>
+ (<symbol>gettext</symbol> is defined as a no-op if NLS support is
+ not configured.)
+ </para>
+
+ <para>
+ This tends to add a lot of clutter. One common shortcut is to use:
+<programlisting>
+#define _(x) gettext(x)
+</programlisting>
+ Another solution is feasible if the program does much of its
+ communication through one or a few functions, such as
+ <function>ereport()</function> in the backend. Then you make this
+ function call <function>gettext</function> internally on all
+ input strings.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Add a file <filename>nls.mk</filename> in the directory with the
+ program sources. This file will be read as a makefile. The
+ following variable assignments need to be made here:
+
+ <variablelist>
+ <varlistentry>
+ <term><varname>CATALOG_NAME</varname></term>
+
+ <listitem>
+ <para>
+ The program name, as provided in the
+ <function>textdomain()</function> call.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>AVAIL_LANGUAGES</varname></term>
+
+ <listitem>
+ <para>
+ List of provided translations &mdash; initially empty.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>GETTEXT_FILES</varname></term>
+
+ <listitem>
+ <para>
+ List of files that contain translatable strings, i.e., those
+ marked with <function>gettext</function> or an alternative
+ solution. Eventually, this will include nearly all source
+ files of the program. If this list gets too long you can
+ make the first <quote>file</quote> be a <literal>+</literal>
+ and the second word be a file that contains one file name per
+ line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>GETTEXT_TRIGGERS</varname></term>
+
+ <listitem>
+ <para>
+ The tools that generate message catalogs for the translators
+ to work on need to know what function calls contain
+ translatable strings. By default, only
+ <function>gettext()</function> calls are known. If you used
+ <function>_</function> or other identifiers you need to list
+ them here. If the translatable string is not the first
+ argument, the item needs to be of the form
+ <literal>func:2</literal> (for the second argument).
+ If you have a function that supports pluralized messages,
+ the item should look like <literal>func:1,2</literal>
+ (identifying the singular and plural message arguments).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </step>
+
+ </procedure>
+
+ <para>
+ The build system will automatically take care of building and
+ installing the message catalogs.
+ </para>
+ </sect2>
+
+ <sect2 id="nls-guidelines">
+ <title>Message-Writing Guidelines</title>
+
+ <para>
+ Here are some guidelines for writing messages that are easily
+ translatable.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Do not construct sentences at run-time, like:
+<programlisting>
+printf("Files were %s.\n", flag ? "copied" : "removed");
+</programlisting>
+ The word order within the sentence might be different in other
+ languages. Also, even if you remember to call <function>gettext()</function> on
+ each fragment, the fragments might not translate well separately. It's
+ better to duplicate a little code so that each message to be
+ translated is a coherent whole. Only numbers, file names, and
+ such-like run-time variables should be inserted at run time into
+ a message text.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For similar reasons, this won't work:
+<programlisting>
+printf("copied %d file%s", n, n!=1 ? "s" : "");
+</programlisting>
+ because it assumes how the plural is formed. If you figured you
+ could solve it like this:
+<programlisting>
+if (n==1)
+ printf("copied 1 file");
+else
+ printf("copied %d files", n):
+</programlisting>
+ then be disappointed. Some languages have more than two forms,
+ with some peculiar rules. It's often best to design the message
+ to avoid the issue altogether, for instance like this:
+<programlisting>
+printf("number of copied files: %d", n);
+</programlisting>
+ </para>
+
+ <para>
+ If you really want to construct a properly pluralized message,
+ there is support for this, but it's a bit awkward. When generating
+ a primary or detail error message in <function>ereport()</function>, you can
+ write something like this:
+<programlisting>
+errmsg_plural("copied %d file",
+ "copied %d files",
+ n,
+ n)
+</programlisting>
+ The first argument is the format string appropriate for English
+ singular form, the second is the format string appropriate for
+ English plural form, and the third is the integer control value
+ that determines which plural form to use. Subsequent arguments
+ are formatted per the format string as usual. (Normally, the
+ pluralization control value will also be one of the values to be
+ formatted, so it has to be written twice.) In English it only
+ matters whether <replaceable>n</replaceable> is 1 or not 1, but in other
+ languages there can be many different plural forms. The translator
+ sees the two English forms as a group and has the opportunity to
+ supply multiple substitute strings, with the appropriate one being
+ selected based on the run-time value of <replaceable>n</replaceable>.
+ </para>
+
+ <para>
+ If you need to pluralize a message that isn't going directly to an
+ <function>errmsg</function> or <function>errdetail</function> report, you have to use
+ the underlying function <function>ngettext</function>. See the gettext
+ documentation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you want to communicate something to the translator, such as
+ about how a message is intended to line up with other output,
+ precede the occurrence of the string with a comment that starts
+ with <literal>translator</literal>, e.g.:
+<programlisting>
+/* translator: This message is not what it seems to be. */
+</programlisting>
+ These comments are copied to the message catalog files so that
+ the translators can see them.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/notation.sgml b/doc/src/sgml/notation.sgml
new file mode 100644
index 0000000..c3798d5
--- /dev/null
+++ b/doc/src/sgml/notation.sgml
@@ -0,0 +1,31 @@
+<!-- doc/src/sgml/notation.sgml -->
+
+<sect1 id="notation">
+ <title>Conventions</title>
+
+ <para>
+ The following conventions are used in the synopsis of a command:
+ brackets (<literal>[</literal> and <literal>]</literal>) indicate
+ optional parts. Braces
+ (<literal>{</literal> and <literal>}</literal>) and vertical lines
+ (<literal>|</literal>) indicate that you must choose one
+ alternative. Dots (<literal>...</literal>) mean that the preceding element
+ can be repeated. All other symbols, including parentheses, should be
+ taken literally.
+ </para>
+
+ <para>
+ Where it enhances the clarity, SQL commands are preceded by the
+ prompt <literal>=&gt;</literal>, and shell commands are preceded by the
+ prompt <literal>$</literal>. Normally, prompts are not shown, though.
+ </para>
+
+ <para>
+ An <firstterm>administrator</firstterm> is generally a person who is
+ in charge of installing and running the server. A <firstterm>user</firstterm>
+ could be anyone who is using, or wants to use, any part of the
+ <productname>PostgreSQL</productname> system. These terms should not
+ be interpreted too narrowly; this book does not have fixed
+ presumptions about system administration procedures.
+ </para>
+</sect1>
diff --git a/doc/src/sgml/oid2name.sgml b/doc/src/sgml/oid2name.sgml
new file mode 100644
index 0000000..dfe3682
--- /dev/null
+++ b/doc/src/sgml/oid2name.sgml
@@ -0,0 +1,376 @@
+<!-- doc/src/sgml/oid2name.sgml -->
+
+<refentry id="oid2name">
+ <indexterm zone="oid2name">
+ <primary>oid2name</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>oid2name</refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>oid2name</refname>
+ <refpurpose>resolve OIDs and file nodes in a <productname>PostgreSQL</productname> data directory</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>oid2name</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>oid2name</application> is a utility program that helps administrators to
+ examine the file structure used by PostgreSQL. To make use of it, you need
+ to be familiar with the database file structure, which is described in
+ <xref linkend="storage"/>.
+ </para>
+
+ <note>
+ <para>
+ The name <quote>oid2name</quote> is historical, and is actually rather
+ misleading, since most of the time when you use it, you will really
+ be concerned with tables' filenode numbers (which are the file names
+ visible in the database directories). Be sure you understand the
+ difference between table OIDs and table filenodes!
+ </para>
+ </note>
+
+ <para>
+ <application>oid2name</application> connects to a target database and
+ extracts OID, filenode, and/or table name information. You can also have
+ it show database OIDs or tablespace OIDs.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>oid2name</application> accepts the following command-line arguments:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-f <replaceable class="parameter">filenode</replaceable></option></term>
+ <term><option>--filenode=<replaceable class="parameter">filenode</replaceable></option></term>
+ <listitem><para>show info for table with filenode <replaceable>filenode</replaceable>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <term><option>--indexes</option></term>
+ <listitem><para>include indexes and sequences in the listing.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable class="parameter">oid</replaceable></option></term>
+ <term><option>--oid=<replaceable class="parameter">oid</replaceable></option></term>
+ <listitem><para>show info for table with OID <replaceable>oid</replaceable>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem><para>omit headers (useful for scripting).</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--tablespaces</option></term>
+ <listitem><para>show tablespace OIDs.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S</option></term>
+ <term><option>--system-objects</option></term>
+ <listitem><para>include system objects (those in
+ <option>information_schema</option>, <option>pg_toast</option>
+ and <option>pg_catalog</option> schemas).
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">tablename_pattern</replaceable></option></term>
+ <term><option>--table=<replaceable class="parameter">tablename_pattern</replaceable></option></term>
+ <listitem><para>show info for table(s) matching <replaceable class="parameter">tablename_pattern</replaceable>.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>oid2name</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option></term>
+ <term><option>--extended</option></term>
+ <listitem><para>display more information about each object shown: tablespace name,
+ schema name, and OID.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>oid2name</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <application>oid2name</application> also accepts the following command-line
+ arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">database</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">database</replaceable></option></term>
+ <listitem><para>database to connect to.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem><para>database server's host.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-H <replaceable class="parameter">host</replaceable></option></term>
+ <listitem><para>database server's host. Use of this parameter is
+ <emphasis>deprecated</emphasis> as of
+ <productname>PostgreSQL</productname> 12.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem><para>database server's port.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem><para>user name to connect as.</para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ To display specific tables, select which tables to show by
+ using <option>-o</option>, <option>-f</option> and/or <option>-t</option>.
+ <option>-o</option> takes an OID,
+ <option>-f</option> takes a filenode,
+ and <option>-t</option> takes a table name (actually, it's a <literal>LIKE</literal>
+ pattern, so you can use things like <literal>foo%</literal>).
+ You can use as many
+ of these options as you like, and the listing will include all objects
+ matched by any of the options. But note that these options can only
+ show objects in the database given by <option>-d</option>.
+ </para>
+
+ <para>
+ If you don't give any of <option>-o</option>, <option>-f</option> or <option>-t</option>,
+ but do give <option>-d</option>, it will list all tables in the database
+ named by <option>-d</option>. In this mode, the <option>-S</option> and
+ <option>-i</option> options control what gets listed.
+ </para>
+
+ <para>
+ If you don't give <option>-d</option> either, it will show a listing of database
+ OIDs. Alternatively you can give <option>-s</option> to get a tablespace
+ listing.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname>
+ utilities, also uses the environment variables supported by
+ <application>libpq</application> (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>oid2name</application> requires a running database server with
+ non-corrupt system catalogs. It is therefore of only limited use
+ for recovering from catastrophic database corruption situations.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<screen>
+$ # what's in this database server, anyway?
+$ oid2name
+All databases:
+ Oid Database Name Tablespace
+----------------------------------
+ 17228 alvherre pg_default
+ 17255 regression pg_default
+ 17227 template0 pg_default
+ 1 template1 pg_default
+
+$ oid2name -s
+All tablespaces:
+ Oid Tablespace Name
+-------------------------
+ 1663 pg_default
+ 1664 pg_global
+ 155151 fastdisk
+ 155152 bigdisk
+
+$ # OK, let's look into database alvherre
+$ cd $PGDATA/base/17228
+
+$ # get top 10 db objects in the default tablespace, ordered by size
+$ ls -lS * | head -10
+-rw------- 1 alvherre alvherre 136536064 sep 14 09:51 155173
+-rw------- 1 alvherre alvherre 17965056 sep 14 09:51 1155291
+-rw------- 1 alvherre alvherre 1204224 sep 14 09:51 16717
+-rw------- 1 alvherre alvherre 581632 sep 6 17:51 1255
+-rw------- 1 alvherre alvherre 237568 sep 14 09:50 16674
+-rw------- 1 alvherre alvherre 212992 sep 14 09:51 1249
+-rw------- 1 alvherre alvherre 204800 sep 14 09:51 16684
+-rw------- 1 alvherre alvherre 196608 sep 14 09:50 16700
+-rw------- 1 alvherre alvherre 163840 sep 14 09:50 16699
+-rw------- 1 alvherre alvherre 122880 sep 6 17:51 16751
+
+$ # I wonder what file 155173 is ...
+$ oid2name -d alvherre -f 155173
+From database "alvherre":
+ Filenode Table Name
+----------------------
+ 155173 accounts
+
+$ # you can ask for more than one object
+$ oid2name -d alvherre -f 155173 -f 1155291
+From database "alvherre":
+ Filenode Table Name
+-------------------------
+ 155173 accounts
+ 1155291 accounts_pkey
+
+$ # you can mix the options, and get more details with -x
+$ oid2name -d alvherre -t accounts -f 1155291 -x
+From database "alvherre":
+ Filenode Table Name Oid Schema Tablespace
+------------------------------------------------------
+ 155173 accounts 155173 public pg_default
+ 1155291 accounts_pkey 1155291 public pg_default
+
+$ # show disk space for every db object
+$ du [0-9]* |
+> while read SIZE FILENODE
+> do
+> echo "$SIZE `oid2name -q -d alvherre -i -f $FILENODE`"
+> done
+16 1155287 branches_pkey
+16 1155289 tellers_pkey
+17561 1155291 accounts_pkey
+...
+
+$ # same, but sort by size
+$ du [0-9]* | sort -rn | while read SIZE FN
+> do
+> echo "$SIZE `oid2name -q -d alvherre -f $FN`"
+> done
+133466 155173 accounts
+17561 1155291 accounts_pkey
+1177 16717 pg_proc_proname_args_nsp_index
+...
+
+$ # If you want to see what's in tablespaces, use the pg_tblspc directory
+$ cd $PGDATA/pg_tblspc
+$ oid2name -s
+All tablespaces:
+ Oid Tablespace Name
+-------------------------
+ 1663 pg_default
+ 1664 pg_global
+ 155151 fastdisk
+ 155152 bigdisk
+
+$ # what databases have objects in tablespace "fastdisk"?
+$ ls -d 155151/*
+155151/17228/ 155151/PG_VERSION
+
+$ # Oh, what was database 17228 again?
+$ oid2name
+All databases:
+ Oid Database Name Tablespace
+----------------------------------
+ 17228 alvherre pg_default
+ 17255 regression pg_default
+ 17227 template0 pg_default
+ 1 template1 pg_default
+
+$ # Let's see what objects does this database have in the tablespace.
+$ cd 155151/17228
+$ ls -l
+total 0
+-rw------- 1 postgres postgres 0 sep 13 23:20 155156
+
+$ # OK, this is a pretty small table ... but which one is it?
+$ oid2name -d alvherre -f 155156
+From database "alvherre":
+ Filenode Table Name
+----------------------
+ 155156 foo
+</screen>
+ </refsect1>
+
+ <refsect1>
+ <title>Author</title>
+
+ <para>
+ B. Palmer <email>bpalmer@crimelabs.net</email>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/oldsnapshot.sgml b/doc/src/sgml/oldsnapshot.sgml
new file mode 100644
index 0000000..a665ae7
--- /dev/null
+++ b/doc/src/sgml/oldsnapshot.sgml
@@ -0,0 +1,33 @@
+<!-- doc/src/sgml/oldsnapshot.sgml -->
+
+<sect1 id="oldsnapshot" xreflabel="old_snapshot">
+ <title>old_snapshot</title>
+
+ <indexterm zone="oldsnapshot">
+ <primary>old_snapshot</primary>
+ </indexterm>
+
+ <para>
+ The <filename>old_snapshot</filename> module allows inspection
+ of the server state that is used to implement
+ <xref linkend="guc-old-snapshot-threshold" />.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>pg_old_snapshot_time_mapping(array_offset OUT int4, end_timestamp OUT timestamptz, newest_xmin OUT xid) returns setof record</function></term>
+ <listitem>
+ <para>
+ Returns all of the entries in the server's timestamp to XID mapping.
+ Each entry represents the newest xmin of any snapshot taken in the
+ corresponding minute.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml
new file mode 100644
index 0000000..b807bfd
--- /dev/null
+++ b/doc/src/sgml/pageinspect.sgml
@@ -0,0 +1,914 @@
+<!-- doc/src/sgml/pageinspect.sgml -->
+
+<sect1 id="pageinspect" xreflabel="pageinspect">
+ <title>pageinspect</title>
+
+ <indexterm zone="pageinspect">
+ <primary>pageinspect</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pageinspect</filename> module provides functions that allow you to
+ inspect the contents of database pages at a low level, which is useful for
+ debugging purposes. All of these functions may be used only by superusers.
+ </para>
+
+ <sect2>
+ <title>General Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>get_raw_page(relname text, fork text, blkno bigint) returns bytea</function>
+ <indexterm>
+ <primary>get_raw_page</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>get_raw_page</function> reads the specified block of the named
+ relation and returns a copy as a <type>bytea</type> value. This allows a
+ single time-consistent copy of the block to be obtained.
+ <replaceable>fork</replaceable> should be <literal>'main'</literal> for
+ the main data fork, <literal>'fsm'</literal> for the
+ <link linkend="storage-fsm">free space map</link>,
+ <literal>'vm'</literal> for the
+ <link linkend="storage-vm">visibility map</link>, or
+ <literal>'init'</literal> for the initialization fork.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>get_raw_page(relname text, blkno bigint) returns bytea</function>
+ </term>
+
+ <listitem>
+ <para>
+ A shorthand version of <function>get_raw_page</function>, for reading
+ from the main fork. Equivalent to
+ <literal>get_raw_page(relname, 'main', blkno)</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>page_header(page bytea) returns record</function>
+ <indexterm>
+ <primary>page_header</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>page_header</function> shows fields that are common to all
+ <productname>PostgreSQL</productname> heap and index pages.
+ </para>
+
+ <para>
+ A page image obtained with <function>get_raw_page</function> should be
+ passed as argument. For example:
+<screen>
+test=# SELECT * FROM page_header(get_raw_page('pg_class', 0));
+ lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid
+-----------+----------+--------+-------+-------+---------+----------+---------+-----------
+ 0/24A1B50 | 0 | 1 | 232 | 368 | 8192 | 8192 | 4 | 0
+</screen>
+ The returned columns correspond to the fields in the
+ <structname>PageHeaderData</structname> struct.
+ See <filename>src/include/storage/bufpage.h</filename> for details.
+ </para>
+
+ <para>
+ The <structfield>checksum</structfield> field is the checksum stored in
+ the page, which might be incorrect if the page is somehow corrupted. If
+ data checksums are not enabled for this instance, then the value stored
+ is meaningless.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>page_checksum(page bytea, blkno bigint) returns smallint</function>
+ <indexterm>
+ <primary>page_checksum</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>page_checksum</function> computes the checksum for the page, as if
+ it was located at the given block.
+ </para>
+
+ <para>
+ A page image obtained with <function>get_raw_page</function> should be
+ passed as argument. For example:
+<screen>
+test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0);
+ page_checksum
+---------------
+ 13443
+</screen>
+ Note that the checksum depends on the block number, so matching block
+ numbers should be passed (except when doing esoteric debugging).
+ </para>
+
+ <para>
+ The checksum computed with this function can be compared with
+ the <structfield>checksum</structfield> result field of the
+ function <function>page_header</function>. If data checksums are
+ enabled for this instance, then the two values should be equal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>fsm_page_contents(page bytea) returns text</function>
+ <indexterm>
+ <primary>fsm_page_contents</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>fsm_page_contents</function> shows the internal node structure
+ of an <acronym>FSM</acronym> page. For example:
+<screen>
+test=# SELECT fsm_page_contents(get_raw_page('pg_class', 'fsm', 0));
+</screen>
+ The output is a multiline string, with one line per node in the binary
+ tree within the page. Only those nodes that are not zero are printed.
+ The so-called "next" pointer, which points to the next slot to be
+ returned from the page, is also printed.
+ </para>
+ <para>
+ See <filename>src/backend/storage/freespace/README</filename> for more
+ information on the structure of an <acronym>FSM</acronym> page.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Heap Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>heap_page_items(page bytea) returns setof record</function>
+ <indexterm>
+ <primary>heap_page_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>heap_page_items</function> shows all line pointers on a heap
+ page. For those line pointers that are in use, tuple headers as well
+ as tuple raw data are also shown. All tuples are shown, whether or not
+ the tuples were visible to an MVCC snapshot at the time the raw page
+ was copied.
+ </para>
+ <para>
+ A heap page image obtained with <function>get_raw_page</function> should
+ be passed as argument. For example:
+<screen>
+test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0));
+</screen>
+ See <filename>src/include/storage/itemid.h</filename> and
+ <filename>src/include/access/htup_details.h</filename> for explanations of the fields
+ returned.
+ </para>
+ <para>
+ The <function>heap_tuple_infomask_flags</function> function can be
+ used to unpack the flag bits of <structfield>t_infomask</structfield>
+ and <structfield>t_infomask2</structfield> for heap tuples.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>tuple_data_split(rel_oid oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[]</function>
+ <indexterm>
+ <primary>tuple_data_split</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <function>tuple_data_split</function> splits tuple data into attributes
+ in the same way as backend internals.
+<screen>
+test=# SELECT tuple_data_split('pg_class'::regclass, t_data, t_infomask, t_infomask2, t_bits) FROM heap_page_items(get_raw_page('pg_class', 0));
+</screen>
+ This function should be called with the same arguments as the return
+ attributes of <function>heap_page_items</function>.
+ </para>
+ <para>
+ If <parameter>do_detoast</parameter> is <literal>true</literal>,
+ attributes will be detoasted as needed. Default value is
+ <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>heap_page_item_attrs(page bytea, rel_oid regclass [, do_detoast bool]) returns setof record</function>
+ <indexterm>
+ <primary>heap_page_item_attrs</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <function>heap_page_item_attrs</function> is equivalent to
+ <function>heap_page_items</function> except that it returns
+ tuple raw data as an array of attributes that can optionally
+ be detoasted by <parameter>do_detoast</parameter> which is
+ <literal>false</literal> by default.
+ </para>
+ <para>
+ A heap page image obtained with <function>get_raw_page</function> should
+ be passed as argument. For example:
+<screen>
+test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class'::regclass);
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>heap_tuple_infomask_flags(t_infomask integer, t_infomask2 integer) returns record</function>
+ <indexterm>
+ <primary>heap_tuple_infomask_flags</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <function>heap_tuple_infomask_flags</function> decodes the
+ <structfield>t_infomask</structfield> and
+ <structfield>t_infomask2</structfield> returned by
+ <function>heap_page_items</function> into a human-readable
+ set of arrays made of flag names, with one column for all
+ the flags and one column for combined flags. For example:
+<screen>
+test=# SELECT t_ctid, raw_flags, combined_flags
+ FROM heap_page_items(get_raw_page('pg_class', 0)),
+ LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2)
+ WHERE t_infomask IS NOT NULL OR t_infomask2 IS NOT NULL;
+</screen>
+ This function should be called with the same arguments as the return
+ attributes of <function>heap_page_items</function>.
+ </para>
+ <para>
+ Combined flags are displayed for source-level macros that take into
+ account the value of more than one raw bit, such as
+ <literal>HEAP_XMIN_FROZEN</literal>.
+ </para>
+ <para>
+ See <filename>src/include/access/htup_details.h</filename> for
+ explanations of the flag names returned.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>B-Tree Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>bt_metap(relname text) returns record</function>
+ <indexterm>
+ <primary>bt_metap</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>bt_metap</function> returns information about a B-tree
+ index's metapage. For example:
+<screen>
+test=# SELECT * FROM bt_metap('pg_cast_oid_index');
+-[ RECORD 1 ]-------------+-------
+magic | 340322
+version | 4
+root | 1
+level | 0
+fastroot | 1
+fastlevel | 0
+last_cleanup_num_delpages | 0
+last_cleanup_num_tuples | 230
+allequalimage | f
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>bt_page_stats(relname text, blkno bigint) returns record</function>
+ <indexterm>
+ <primary>bt_page_stats</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>bt_page_stats</function> returns summary information about
+ single pages of B-tree indexes. For example:
+<screen>
+test=# SELECT * FROM bt_page_stats('pg_cast_oid_index', 1);
+-[ RECORD 1 ]-+-----
+blkno | 1
+type | l
+live_items | 224
+dead_items | 0
+avg_item_size | 16
+page_size | 8192
+free_size | 3668
+btpo_prev | 0
+btpo_next | 0
+btpo_level | 0
+btpo_flags | 3
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>bt_page_items(relname text, blkno bigint) returns setof record</function>
+ <indexterm>
+ <primary>bt_page_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>bt_page_items</function> returns detailed information about
+ all of the items on a B-tree index page. For example:
+<screen>
+test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids
+ FROM bt_page_items('tenk2_hundred', 5);
+ itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids
+------------+-----------+---------+-------+------+-------------------------+------+--------+---------------------
+ 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | |
+ 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"}
+ 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"}
+ 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"}
+ 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"}
+ 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"}
+ 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"}
+ 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"}
+ 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"}
+ 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"}
+ 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"}
+ 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"}
+ 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"}
+(13 rows)
+</screen>
+ This is a B-tree leaf page. All tuples that point to the table
+ happen to be posting list tuples (all of which store a total of
+ 100 6 byte TIDs). There is also a <quote>high key</quote> tuple
+ at <literal>itemoffset</literal> number 1.
+ <structfield>ctid</structfield> is used to store encoded
+ information about each tuple in this example, though leaf page
+ tuples often store a heap TID directly in the
+ <structfield>ctid</structfield> field instead.
+ <structfield>tids</structfield> is the list of TIDs stored as a
+ posting list.
+ </para>
+ <para>
+ In an internal page (not shown), the block number part of
+ <structfield>ctid</structfield> is a <quote>downlink</quote>,
+ which is a block number of another page in the index itself.
+ The offset part (the second number) of
+ <structfield>ctid</structfield> stores encoded information about
+ the tuple, such as the number of columns present (suffix
+ truncation may have removed unneeded suffix columns). Truncated
+ columns are treated as having the value <quote>minus
+ infinity</quote>.
+ </para>
+ <para>
+ <structfield>htid</structfield> shows a heap TID for the tuple,
+ regardless of the underlying tuple representation. This value
+ may match <structfield>ctid</structfield>, or may be decoded
+ from the alternative representations used by posting list tuples
+ and tuples from internal pages. Tuples in internal pages
+ usually have the implementation level heap TID column truncated
+ away, which is represented as a NULL
+ <structfield>htid</structfield> value.
+ </para>
+ <para>
+ Note that the first item on any non-rightmost page (any page with
+ a non-zero value in the <structfield>btpo_next</structfield> field) is the
+ page's <quote>high key</quote>, meaning its <structfield>data</structfield>
+ serves as an upper bound on all items appearing on the page, while
+ its <structfield>ctid</structfield> field does not point to
+ another block. Also, on internal pages, the first real data
+ item (the first item that is not a high key) reliably has every
+ column truncated away, leaving no actual value in its
+ <structfield>data</structfield> field. Such an item does have a
+ valid downlink in its <structfield>ctid</structfield> field,
+ however.
+ </para>
+ <para>
+ For more details about the structure of B-tree indexes, see
+ <xref linkend="btree-structure"/>. For more details about
+ deduplication and posting lists, see <xref
+ linkend="btree-deduplication"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>bt_page_items(page bytea) returns setof record</function>
+ <indexterm>
+ <primary>bt_page_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ It is also possible to pass a page to <function>bt_page_items</function>
+ as a <type>bytea</type> value. A page image obtained
+ with <function>get_raw_page</function> should be passed as argument. So
+ the last example could also be rewritten like this:
+<screen>
+test=# SELECT itemoffset, ctid, itemlen, nulls, vars, data, dead, htid, tids[0:2] AS some_tids
+ FROM bt_page_items(get_raw_page('tenk2_hundred', 5));
+ itemoffset | ctid | itemlen | nulls | vars | data | dead | htid | some_tids
+------------+-----------+---------+-------+------+-------------------------+------+--------+---------------------
+ 1 | (16,1) | 16 | f | f | 30 00 00 00 00 00 00 00 | | |
+ 2 | (16,8292) | 616 | f | f | 24 00 00 00 00 00 00 00 | f | (1,6) | {"(1,6)","(10,22)"}
+ 3 | (16,8292) | 616 | f | f | 25 00 00 00 00 00 00 00 | f | (1,18) | {"(1,18)","(4,22)"}
+ 4 | (16,8292) | 616 | f | f | 26 00 00 00 00 00 00 00 | f | (4,18) | {"(4,18)","(6,17)"}
+ 5 | (16,8292) | 616 | f | f | 27 00 00 00 00 00 00 00 | f | (1,2) | {"(1,2)","(1,19)"}
+ 6 | (16,8292) | 616 | f | f | 28 00 00 00 00 00 00 00 | f | (2,24) | {"(2,24)","(4,11)"}
+ 7 | (16,8292) | 616 | f | f | 29 00 00 00 00 00 00 00 | f | (2,17) | {"(2,17)","(11,2)"}
+ 8 | (16,8292) | 616 | f | f | 2a 00 00 00 00 00 00 00 | f | (0,25) | {"(0,25)","(3,20)"}
+ 9 | (16,8292) | 616 | f | f | 2b 00 00 00 00 00 00 00 | f | (0,10) | {"(0,10)","(0,14)"}
+ 10 | (16,8292) | 616 | f | f | 2c 00 00 00 00 00 00 00 | f | (1,3) | {"(1,3)","(3,9)"}
+ 11 | (16,8292) | 616 | f | f | 2d 00 00 00 00 00 00 00 | f | (6,28) | {"(6,28)","(11,1)"}
+ 12 | (16,8292) | 616 | f | f | 2e 00 00 00 00 00 00 00 | f | (0,27) | {"(0,27)","(1,13)"}
+ 13 | (16,8292) | 616 | f | f | 2f 00 00 00 00 00 00 00 | f | (4,17) | {"(4,17)","(4,21)"}
+(13 rows)
+</screen>
+ All the other details are the same as explained in the previous item.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>BRIN Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>brin_page_type(page bytea) returns text</function>
+ <indexterm>
+ <primary>brin_page_type</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>brin_page_type</function> returns the page type of the given
+ <acronym>BRIN</acronym> index page, or throws an error if the page is
+ not a valid <acronym>BRIN</acronym> page. For example:
+<screen>
+test=# SELECT brin_page_type(get_raw_page('brinidx', 0));
+ brin_page_type
+----------------
+ meta
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>brin_metapage_info(page bytea) returns record</function>
+ <indexterm>
+ <primary>brin_metapage_info</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>brin_metapage_info</function> returns assorted information
+ about a <acronym>BRIN</acronym> index metapage. For example:
+<screen>
+test=# SELECT * FROM brin_metapage_info(get_raw_page('brinidx', 0));
+ magic | version | pagesperrange | lastrevmappage
+------------+---------+---------------+----------------
+ 0xA8109CFA | 1 | 4 | 2
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>brin_revmap_data(page bytea) returns setof tid</function>
+ <indexterm>
+ <primary>brin_revmap_data</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>brin_revmap_data</function> returns the list of tuple
+ identifiers in a <acronym>BRIN</acronym> index range map page.
+ For example:
+<screen>
+test=# SELECT * FROM brin_revmap_data(get_raw_page('brinidx', 2)) LIMIT 5;
+ pages
+---------
+ (6,137)
+ (6,138)
+ (6,139)
+ (6,140)
+ (6,141)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>brin_page_items(page bytea, index oid) returns setof record</function>
+ <indexterm>
+ <primary>brin_page_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>brin_page_items</function> returns the data stored in the
+ <acronym>BRIN</acronym> data page. For example:
+<screen>
+test=# SELECT * FROM brin_page_items(get_raw_page('brinidx', 5),
+ 'brinidx')
+ ORDER BY blknum, attnum LIMIT 6;
+ itemoffset | blknum | attnum | allnulls | hasnulls | placeholder | value
+------------+--------+--------+----------+----------+-------------+--------------
+ 137 | 0 | 1 | t | f | f |
+ 137 | 0 | 2 | f | f | f | {1 .. 88}
+ 138 | 4 | 1 | t | f | f |
+ 138 | 4 | 2 | f | f | f | {89 .. 176}
+ 139 | 8 | 1 | t | f | f |
+ 139 | 8 | 2 | f | f | f | {177 .. 264}
+</screen>
+ The returned columns correspond to the fields in the
+ <structname>BrinMemTuple</structname> and <structname>BrinValues</structname> structs.
+ See <filename>src/include/access/brin_tuple.h</filename> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>GIN Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>gin_metapage_info(page bytea) returns record</function>
+ <indexterm>
+ <primary>gin_metapage_info</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>gin_metapage_info</function> returns information about
+ a <acronym>GIN</acronym> index metapage. For example:
+<screen>
+test=# SELECT * FROM gin_metapage_info(get_raw_page('gin_index', 0));
+-[ RECORD 1 ]----+-----------
+pending_head | 4294967295
+pending_tail | 4294967295
+tail_free_size | 0
+n_pending_pages | 0
+n_pending_tuples | 0
+n_total_pages | 7
+n_entry_pages | 6
+n_data_pages | 0
+n_entries | 693
+version | 2
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>gin_page_opaque_info(page bytea) returns record</function>
+ <indexterm>
+ <primary>gin_page_opaque_info</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>gin_page_opaque_info</function> returns information about
+ a <acronym>GIN</acronym> index opaque area, like the page type.
+ For example:
+<screen>
+test=# SELECT * FROM gin_page_opaque_info(get_raw_page('gin_index', 2));
+ rightlink | maxoff | flags
+-----------+--------+------------------------
+ 5 | 0 | {data,leaf,compressed}
+(1 row)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>gin_leafpage_items(page bytea) returns setof record</function>
+ <indexterm>
+ <primary>gin_leafpage_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>gin_leafpage_items</function> returns information about
+ the data stored in a <acronym>GIN</acronym> leaf page. For example:
+<screen>
+test=# SELECT first_tid, nbytes, tids[0:5] AS some_tids
+ FROM gin_leafpage_items(get_raw_page('gin_test_idx', 2));
+ first_tid | nbytes | some_tids
+-----------+--------+----------------------------------------------------------
+ (8,41) | 244 | {"(8,41)","(8,43)","(8,44)","(8,45)","(8,46)"}
+ (10,45) | 248 | {"(10,45)","(10,46)","(10,47)","(10,48)","(10,49)"}
+ (12,52) | 248 | {"(12,52)","(12,53)","(12,54)","(12,55)","(12,56)"}
+ (14,59) | 320 | {"(14,59)","(14,60)","(14,61)","(14,62)","(14,63)"}
+ (167,16) | 376 | {"(167,16)","(167,17)","(167,18)","(167,19)","(167,20)"}
+ (170,30) | 376 | {"(170,30)","(170,31)","(170,32)","(170,33)","(170,34)"}
+ (173,44) | 197 | {"(173,44)","(173,45)","(173,46)","(173,47)","(173,48)"}
+(7 rows)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>GiST Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>gist_page_opaque_info(page bytea) returns record</function>
+ <indexterm>
+ <primary>gist_page_opaque_info</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>gist_page_opaque_info</function> returns information from
+ a <acronym>GiST</acronym> index page's opaque area, such as the NSN,
+ rightlink and page type.
+ For example:
+<screen>
+test=# SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2));
+ lsn | nsn | rightlink | flags
+-----+-----+-----------+--------
+ 0/1 | 0/0 | 1 | {leaf}
+(1 row)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>gist_page_items(page bytea, index_oid regclass) returns setof record</function>
+ <indexterm>
+ <primary>gist_page_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>gist_page_items</function> returns information about
+ the data stored in a page of a <acronym>GiST</acronym> index. For example:
+<screen>
+test=# SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx');
+ itemoffset | ctid | itemlen | dead | keys
+------------+-----------+---------+------+-------------------------------
+ 1 | (1,65535) | 40 | f | (p)=("(185,185),(1,1)")
+ 2 | (2,65535) | 40 | f | (p)=("(370,370),(186,186)")
+ 3 | (3,65535) | 40 | f | (p)=("(555,555),(371,371)")
+ 4 | (4,65535) | 40 | f | (p)=("(740,740),(556,556)")
+ 5 | (5,65535) | 40 | f | (p)=("(870,870),(741,741)")
+ 6 | (6,65535) | 40 | f | (p)=("(1000,1000),(871,871)")
+(6 rows)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>gist_page_items_bytea(page bytea) returns setof record</function>
+ <indexterm>
+ <primary>gist_page_items_bytea</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ Same as <function>gist_page_items</function>, but returns the key data
+ as a raw <type>bytea</type> blob. Since it does not attempt to decode
+ the key, it does not need to know which index is involved. For
+ example:
+<screen>
+test=# SELECT * FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0));
+ itemoffset | ctid | itemlen | dead | key_data
+------------+-----------+---------+------+-----------------------------------------&zwsp;-------------------------------------------
+ 1 | (1,65535) | 40 | f | \x00000100ffff28000000000000c0644000000000&zwsp;00c06440000000000000f03f000000000000f03f
+ 2 | (2,65535) | 40 | f | \x00000200ffff28000000000000c0744000000000&zwsp;00c074400000000000e064400000000000e06440
+ 3 | (3,65535) | 40 | f | \x00000300ffff28000000000000207f4000000000&zwsp;00207f400000000000d074400000000000d07440
+ 4 | (4,65535) | 40 | f | \x00000400ffff28000000000000c0844000000000&zwsp;00c084400000000000307f400000000000307f40
+ 5 | (5,65535) | 40 | f | \x00000500ffff28000000000000f0894000000000&zwsp;00f089400000000000c884400000000000c88440
+ 6 | (6,65535) | 40 | f | \x00000600ffff28000000000000208f4000000000&zwsp;00208f400000000000f889400000000000f88940
+ 7 | (7,65535) | 40 | f | \x00000700ffff28000000000000408f4000000000&zwsp;00408f400000000000288f400000000000288f40
+(7 rows)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Hash Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>hash_page_type(page bytea) returns text</function>
+ <indexterm>
+ <primary>hash_page_type</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>hash_page_type</function> returns page type of
+ the given <acronym>HASH</acronym> index page. For example:
+<screen>
+test=# SELECT hash_page_type(get_raw_page('con_hash_index', 0));
+ hash_page_type
+----------------
+ metapage
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>hash_page_stats(page bytea) returns setof record</function>
+ <indexterm>
+ <primary>hash_page_stats</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>hash_page_stats</function> returns information about
+ a bucket or overflow page of a <acronym>HASH</acronym> index.
+ For example:
+<screen>
+test=# SELECT * FROM hash_page_stats(get_raw_page('con_hash_index', 1));
+-[ RECORD 1 ]---+-----------
+live_items | 407
+dead_items | 0
+page_size | 8192
+free_size | 8
+hasho_prevblkno | 4096
+hasho_nextblkno | 8474
+hasho_bucket | 0
+hasho_flag | 66
+hasho_page_id | 65408
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>hash_page_items(page bytea) returns setof record</function>
+ <indexterm>
+ <primary>hash_page_items</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>hash_page_items</function> returns information about
+ the data stored in a bucket or overflow page of a <acronym>HASH</acronym>
+ index page. For example:
+<screen>
+test=# SELECT * FROM hash_page_items(get_raw_page('con_hash_index', 1)) LIMIT 5;
+ itemoffset | ctid | data
+------------+-----------+------------
+ 1 | (899,77) | 1053474816
+ 2 | (897,29) | 1053474816
+ 3 | (894,207) | 1053474816
+ 4 | (892,159) | 1053474816
+ 5 | (890,111) | 1053474816
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>hash_bitmap_info(index oid, blkno bigint) returns record</function>
+ <indexterm>
+ <primary>hash_bitmap_info</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>hash_bitmap_info</function> shows the status of a bit
+ in the bitmap page for a particular overflow page of <acronym>HASH</acronym>
+ index. For example:
+<screen>
+test=# SELECT * FROM hash_bitmap_info('con_hash_index', 2052);
+ bitmapblkno | bitmapbit | bitstatus
+-------------+-----------+-----------
+ 65 | 3 | t
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>hash_metapage_info(page bytea) returns record</function>
+ <indexterm>
+ <primary>hash_metapage_info</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>hash_metapage_info</function> returns information stored
+ in the meta page of a <acronym>HASH</acronym> index. For example:
+<screen>
+test=# SELECT magic, version, ntuples, ffactor, bsize, bmsize, bmshift,
+test-# maxbucket, highmask, lowmask, ovflpoint, firstfree, nmaps, procid,
+test-# regexp_replace(spares::text, '(,0)*}', '}') as spares,
+test-# regexp_replace(mapp::text, '(,0)*}', '}') as mapp
+test-# FROM hash_metapage_info(get_raw_page('con_hash_index', 0));
+-[ RECORD 1 ]-------------------------------------------------&zwsp;------------------------------
+magic | 105121344
+version | 4
+ntuples | 500500
+ffactor | 40
+bsize | 8152
+bmsize | 4096
+bmshift | 15
+maxbucket | 12512
+highmask | 16383
+lowmask | 8191
+ovflpoint | 28
+firstfree | 1204
+nmaps | 1
+procid | 450
+spares | {0,0,0,0,0,0,1,1,1,1,1,1,1,1,3,4,4,4,45,55,58,59,&zwsp;508,567,628,704,1193,1202,1204}
+mapp | {65}
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/parallel.sgml b/doc/src/sgml/parallel.sgml
new file mode 100644
index 0000000..5acc953
--- /dev/null
+++ b/doc/src/sgml/parallel.sgml
@@ -0,0 +1,598 @@
+<!-- doc/src/sgml/parallel.sgml -->
+
+ <chapter id="parallel-query">
+ <title>Parallel Query</title>
+
+ <indexterm zone="parallel-query">
+ <primary>parallel query</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> can devise query plans that can leverage
+ multiple CPUs in order to answer queries faster. This feature is known
+ as parallel query. Many queries cannot benefit from parallel query, either
+ due to limitations of the current implementation or because there is no
+ imaginable query plan that is any faster than the serial query plan.
+ However, for queries that can benefit, the speedup from parallel query
+ is often very significant. Many queries can run more than twice as fast
+ when using parallel query, and some queries can run four times faster or
+ even more. Queries that touch a large amount of data but return only a
+ few rows to the user will typically benefit most. This chapter explains
+ some details of how parallel query works and in which situations it can be
+ used so that users who wish to make use of it can understand what to expect.
+ </para>
+
+ <sect1 id="how-parallel-query-works">
+ <title>How Parallel Query Works</title>
+
+ <para>
+ When the optimizer determines that parallel query is the fastest execution
+ strategy for a particular query, it will create a query plan that includes
+ a <firstterm>Gather</firstterm> or <firstterm>Gather Merge</firstterm>
+ node. Here is a simple example:
+
+<screen>
+EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------------
+ Gather (cost=1000.00..217018.43 rows=1 width=97)
+ Workers Planned: 2
+ -> Parallel Seq Scan on pgbench_accounts (cost=0.00..216018.33 rows=1 width=97)
+ Filter: (filler ~~ '%x%'::text)
+(4 rows)
+</screen>
+ </para>
+
+ <para>
+ In all cases, the <literal>Gather</literal> or
+ <literal>Gather Merge</literal> node will have exactly one
+ child plan, which is the portion of the plan that will be executed in
+ parallel. If the <literal>Gather</literal> or <literal>Gather Merge</literal> node is
+ at the very top of the plan tree, then the entire query will execute in
+ parallel. If it is somewhere else in the plan tree, then only the portion
+ of the plan below it will run in parallel. In the example above, the
+ query accesses only one table, so there is only one plan node other than
+ the <literal>Gather</literal> node itself; since that plan node is a child of the
+ <literal>Gather</literal> node, it will run in parallel.
+ </para>
+
+ <para>
+ <link linkend="using-explain">Using EXPLAIN</link>, you can see the number of
+ workers chosen by the planner. When the <literal>Gather</literal> node is reached
+ during query execution, the process that is implementing the user's
+ session will request a number of <link linkend="bgworker">background
+ worker processes</link> equal to the number
+ of workers chosen by the planner. The number of background workers that
+ the planner will consider using is limited to at most
+ <xref linkend="guc-max-parallel-workers-per-gather"/>. The total number
+ of background workers that can exist at any one time is limited by both
+ <xref linkend="guc-max-worker-processes"/> and
+ <xref linkend="guc-max-parallel-workers"/>. Therefore, it is possible for a
+ parallel query to run with fewer workers than planned, or even with
+ no workers at all. The optimal plan may depend on the number of workers
+ that are available, so this can result in poor query performance. If this
+ occurrence is frequent, consider increasing
+ <varname>max_worker_processes</varname> and <varname>max_parallel_workers</varname>
+ so that more workers can be run simultaneously or alternatively reducing
+ <varname>max_parallel_workers_per_gather</varname> so that the planner
+ requests fewer workers.
+ </para>
+
+ <para>
+ Every background worker process that is successfully started for a given
+ parallel query will execute the parallel portion of the plan. The leader
+ will also execute that portion of the plan, but it has an additional
+ responsibility: it must also read all of the tuples generated by the
+ workers. When the parallel portion of the plan generates only a small
+ number of tuples, the leader will often behave very much like an additional
+ worker, speeding up query execution. Conversely, when the parallel portion
+ of the plan generates a large number of tuples, the leader may be almost
+ entirely occupied with reading the tuples generated by the workers and
+ performing any further processing steps that are required by plan nodes
+ above the level of the <literal>Gather</literal> node or
+ <literal>Gather Merge</literal> node. In such cases, the leader will
+ do very little of the work of executing the parallel portion of the plan.
+ </para>
+
+ <para>
+ When the node at the top of the parallel portion of the plan is
+ <literal>Gather Merge</literal> rather than <literal>Gather</literal>, it indicates that
+ each process executing the parallel portion of the plan is producing
+ tuples in sorted order, and that the leader is performing an
+ order-preserving merge. In contrast, <literal>Gather</literal> reads tuples
+ from the workers in whatever order is convenient, destroying any sort
+ order that may have existed.
+ </para>
+ </sect1>
+
+ <sect1 id="when-can-parallel-query-be-used">
+ <title>When Can Parallel Query Be Used?</title>
+
+ <para>
+ There are several settings that can cause the query planner not to
+ generate a parallel query plan under any circumstances. In order for
+ any parallel query plans whatsoever to be generated, the following
+ settings must be configured as indicated.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <xref linkend="guc-max-parallel-workers-per-gather"/> must be set to a
+ value that is greater than zero. This is a special case of the more
+ general principle that no more workers should be used than the number
+ configured via <varname>max_parallel_workers_per_gather</varname>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ In addition, the system must not be running in single-user mode. Since
+ the entire database system is running as a single process in this situation,
+ no background workers will be available.
+ </para>
+
+ <para>
+ Even when it is in general possible for parallel query plans to be
+ generated, the planner will not generate them for a given query
+ if any of the following are true:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The query writes any data or locks any database rows. If a query
+ contains a data-modifying operation either at the top level or within
+ a CTE, no parallel plans for that query will be generated. As an
+ exception, the following commands, which create a new table and populate
+ it, can use a parallel plan for the underlying <literal>SELECT</literal>
+ part of the query:
+
+ <itemizedlist>
+ <listitem>
+ <para><command>CREATE TABLE ... AS</command></para>
+ </listitem>
+ <listitem>
+ <para><command>SELECT INTO</command></para>
+ </listitem>
+ <listitem>
+ <para><command>CREATE MATERIALIZED VIEW</command></para>
+ </listitem>
+ <listitem>
+ <para><command>REFRESH MATERIALIZED VIEW</command></para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The query might be suspended during execution. In any situation in
+ which the system thinks that partial or incremental execution might
+ occur, no parallel plan is generated. For example, a cursor created
+ using <link linkend="sql-declare">DECLARE CURSOR</link> will never use
+ a parallel plan. Similarly, a PL/pgSQL loop of the form
+ <literal>FOR x IN query LOOP .. END LOOP</literal> will never use a
+ parallel plan, because the parallel query system is unable to verify
+ that the code in the loop is safe to execute while parallel query is
+ active.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The query uses any function marked <literal>PARALLEL UNSAFE</literal>.
+ Most system-defined functions are <literal>PARALLEL SAFE</literal>,
+ but user-defined functions are marked <literal>PARALLEL
+ UNSAFE</literal> by default. See the discussion of
+ <xref linkend="parallel-safety"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The query is running inside of another query that is already parallel.
+ For example, if a function called by a parallel query issues an SQL
+ query itself, that query will never use a parallel plan. This is a
+ limitation of the current implementation, but it may not be desirable
+ to remove this limitation, since it could result in a single query
+ using a very large number of processes.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Even when parallel query plan is generated for a particular query, there
+ are several circumstances under which it will be impossible to execute
+ that plan in parallel at execution time. If this occurs, the leader
+ will execute the portion of the plan below the <literal>Gather</literal>
+ node entirely by itself, almost as if the <literal>Gather</literal> node were
+ not present. This will happen if any of the following conditions are met:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ No background workers can be obtained because of the limitation that
+ the total number of background workers cannot exceed
+ <xref linkend="guc-max-worker-processes"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ No background workers can be obtained because of the limitation that
+ the total number of background workers launched for purposes of
+ parallel query cannot exceed <xref linkend="guc-max-parallel-workers"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The client sends an Execute message with a non-zero fetch count.
+ See the discussion of the
+ <link linkend="protocol-flow-ext-query">extended query protocol</link>.
+ Since <link linkend="libpq">libpq</link> currently provides no way to
+ send such a message, this can only occur when using a client that
+ does not rely on libpq. If this is a frequent
+ occurrence, it may be a good idea to set
+ <xref linkend="guc-max-parallel-workers-per-gather"/> to zero in
+ sessions where it is likely, so as to avoid generating query plans
+ that may be suboptimal when run serially.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect1>
+
+ <sect1 id="parallel-plans">
+ <title>Parallel Plans</title>
+
+ <para>
+ Because each worker executes the parallel portion of the plan to
+ completion, it is not possible to simply take an ordinary query plan
+ and run it using multiple workers. Each worker would produce a full
+ copy of the output result set, so the query would not run any faster
+ than normal but would produce incorrect results. Instead, the parallel
+ portion of the plan must be what is known internally to the query
+ optimizer as a <firstterm>partial plan</firstterm>; that is, it must be constructed
+ so that each process that executes the plan will generate only a
+ subset of the output rows in such a way that each required output row
+ is guaranteed to be generated by exactly one of the cooperating processes.
+ Generally, this means that the scan on the driving table of the query
+ must be a parallel-aware scan.
+ </para>
+
+ <sect2 id="parallel-scans">
+ <title>Parallel Scans</title>
+
+ <para>
+ The following types of parallel-aware table scans are currently supported.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ In a <emphasis>parallel sequential scan</emphasis>, the table's blocks will
+ be divided into ranges and shared among the cooperating processes. Each
+ worker process will complete the scanning of its given range of blocks before
+ requesting an additional range of blocks.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In a <emphasis>parallel bitmap heap scan</emphasis>, one process is chosen
+ as the leader. That process performs a scan of one or more indexes
+ and builds a bitmap indicating which table blocks need to be visited.
+ These blocks are then divided among the cooperating processes as in
+ a parallel sequential scan. In other words, the heap scan is performed
+ in parallel, but the underlying index scan is not.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In a <emphasis>parallel index scan</emphasis> or <emphasis>parallel index-only
+ scan</emphasis>, the cooperating processes take turns reading data from the
+ index. Currently, parallel index scans are supported only for
+ btree indexes. Each process will claim a single index block and will
+ scan and return all tuples referenced by that block; other processes can
+ at the same time be returning tuples from a different index block.
+ The results of a parallel btree scan are returned in sorted order
+ within each worker process.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Other scan types, such as scans of non-btree indexes, may support
+ parallel scans in the future.
+ </para>
+ </sect2>
+
+ <sect2 id="parallel-joins">
+ <title>Parallel Joins</title>
+
+ <para>
+ Just as in a non-parallel plan, the driving table may be joined to one or
+ more other tables using a nested loop, hash join, or merge join. The
+ inner side of the join may be any kind of non-parallel plan that is
+ otherwise supported by the planner provided that it is safe to run within
+ a parallel worker. Depending on the join type, the inner side may also be
+ a parallel plan.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ In a <emphasis>nested loop join</emphasis>, the inner side is always
+ non-parallel. Although it is executed in full, this is efficient if
+ the inner side is an index scan, because the outer tuples and thus
+ the loops that look up values in the index are divided over the
+ cooperating processes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In a <emphasis>merge join</emphasis>, the inner side is always
+ a non-parallel plan and therefore executed in full. This may be
+ inefficient, especially if a sort must be performed, because the work
+ and resulting data are duplicated in every cooperating process.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In a <emphasis>hash join</emphasis> (without the "parallel" prefix),
+ the inner side is executed in full by every cooperating process
+ to build identical copies of the hash table. This may be inefficient
+ if the hash table is large or the plan is expensive. In a
+ <emphasis>parallel hash join</emphasis>, the inner side is a
+ <emphasis>parallel hash</emphasis> that divides the work of building
+ a shared hash table over the cooperating processes.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect2>
+
+ <sect2 id="parallel-aggregation">
+ <title>Parallel Aggregation</title>
+ <para>
+ <productname>PostgreSQL</productname> supports parallel aggregation by aggregating in
+ two stages. First, each process participating in the parallel portion of
+ the query performs an aggregation step, producing a partial result for
+ each group of which that process is aware. This is reflected in the plan
+ as a <literal>Partial Aggregate</literal> node. Second, the partial results are
+ transferred to the leader via <literal>Gather</literal> or <literal>Gather
+ Merge</literal>. Finally, the leader re-aggregates the results across all
+ workers in order to produce the final result. This is reflected in the
+ plan as a <literal>Finalize Aggregate</literal> node.
+ </para>
+
+ <para>
+ Because the <literal>Finalize Aggregate</literal> node runs on the leader
+ process, queries that produce a relatively large number of groups in
+ comparison to the number of input rows will appear less favorable to the
+ query planner. For example, in the worst-case scenario the number of
+ groups seen by the <literal>Finalize Aggregate</literal> node could be as many as
+ the number of input rows that were seen by all worker processes in the
+ <literal>Partial Aggregate</literal> stage. For such cases, there is clearly
+ going to be no performance benefit to using parallel aggregation. The
+ query planner takes this into account during the planning process and is
+ unlikely to choose parallel aggregate in this scenario.
+ </para>
+
+ <para>
+ Parallel aggregation is not supported in all situations. Each aggregate
+ must be <link linkend="parallel-safety">safe</link> for parallelism and must
+ have a combine function. If the aggregate has a transition state of type
+ <literal>internal</literal>, it must have serialization and deserialization
+ functions. See <xref linkend="sql-createaggregate"/> for more details.
+ Parallel aggregation is not supported if any aggregate function call
+ contains <literal>DISTINCT</literal> or <literal>ORDER BY</literal> clause and is also
+ not supported for ordered set aggregates or when the query involves
+ <literal>GROUPING SETS</literal>. It can only be used when all joins involved in
+ the query are also part of the parallel portion of the plan.
+ </para>
+
+ </sect2>
+
+ <sect2 id="parallel-append">
+ <title>Parallel Append</title>
+
+ <para>
+ Whenever <productname>PostgreSQL</productname> needs to combine rows
+ from multiple sources into a single result set, it uses an
+ <literal>Append</literal> or <literal>MergeAppend</literal> plan node.
+ This commonly happens when implementing <literal>UNION ALL</literal> or
+ when scanning a partitioned table. Such nodes can be used in parallel
+ plans just as they can in any other plan. However, in a parallel plan,
+ the planner may instead use a <literal>Parallel Append</literal> node.
+ </para>
+
+ <para>
+ When an <literal>Append</literal> node is used in a parallel plan, each
+ process will execute the child plans in the order in which they appear,
+ so that all participating processes cooperate to execute the first child
+ plan until it is complete and then move to the second plan at around the
+ same time. When a <literal>Parallel Append</literal> is used instead, the
+ executor will instead spread out the participating processes as evenly as
+ possible across its child plans, so that multiple child plans are executed
+ simultaneously. This avoids contention, and also avoids paying the startup
+ cost of a child plan in those processes that never execute it.
+ </para>
+
+ <para>
+ Also, unlike a regular <literal>Append</literal> node, which can only have
+ partial children when used within a parallel plan, a <literal>Parallel
+ Append</literal> node can have both partial and non-partial child plans.
+ Non-partial children will be scanned by only a single process, since
+ scanning them more than once would produce duplicate results. Plans that
+ involve appending multiple results sets can therefore achieve
+ coarse-grained parallelism even when efficient partial plans are not
+ available. For example, consider a query against a partitioned table
+ that can only be implemented efficiently by using an index that does
+ not support parallel scans. The planner might choose a <literal>Parallel
+ Append</literal> of regular <literal>Index Scan</literal> plans; each
+ individual index scan would have to be executed to completion by a single
+ process, but different scans could be performed at the same time by
+ different processes.
+ </para>
+
+ <para>
+ <xref linkend="guc-enable-parallel-append" /> can be used to disable
+ this feature.
+ </para>
+ </sect2>
+
+ <sect2 id="parallel-plan-tips">
+ <title>Parallel Plan Tips</title>
+
+ <para>
+ If a query that is expected to do so does not produce a parallel plan,
+ you can try reducing <xref linkend="guc-parallel-setup-cost"/> or
+ <xref linkend="guc-parallel-tuple-cost"/>. Of course, this plan may turn
+ out to be slower than the serial plan that the planner preferred, but
+ this will not always be the case. If you don't get a parallel
+ plan even with very small values of these settings (e.g., after setting
+ them both to zero), there may be some reason why the query planner is
+ unable to generate a parallel plan for your query. See
+ <xref linkend="when-can-parallel-query-be-used"/> and
+ <xref linkend="parallel-safety"/> for information on why this may be
+ the case.
+ </para>
+
+ <para>
+ When executing a parallel plan, you can use <literal>EXPLAIN (ANALYZE,
+ VERBOSE)</literal> to display per-worker statistics for each plan node.
+ This may be useful in determining whether the work is being evenly
+ distributed between all plan nodes and more generally in understanding the
+ performance characteristics of the plan.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="parallel-safety">
+ <title>Parallel Safety</title>
+
+ <para>
+ The planner classifies operations involved in a query as either
+ <firstterm>parallel safe</firstterm>, <firstterm>parallel restricted</firstterm>,
+ or <firstterm>parallel unsafe</firstterm>. A parallel safe operation is one that
+ does not conflict with the use of parallel query. A parallel restricted
+ operation is one that cannot be performed in a parallel worker, but that
+ can be performed in the leader while parallel query is in use. Therefore,
+ parallel restricted operations can never occur below a <literal>Gather</literal>
+ or <literal>Gather Merge</literal> node, but can occur elsewhere in a plan that
+ contains such a node. A parallel unsafe operation is one that cannot
+ be performed while parallel query is in use, not even in the leader.
+ When a query contains anything that is parallel unsafe, parallel query
+ is completely disabled for that query.
+ </para>
+
+ <para>
+ The following operations are always parallel restricted:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Scans of common table expressions (CTEs).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Scans of temporary tables.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Scans of foreign tables, unless the foreign data wrapper has
+ an <literal>IsForeignScanParallelSafe</literal> API that indicates otherwise.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Plan nodes to which an <literal>InitPlan</literal> is attached.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Plan nodes that reference a correlated <literal>SubPlan</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 id="parallel-labeling">
+ <title>Parallel Labeling for Functions and Aggregates</title>
+
+ <para>
+ The planner cannot automatically determine whether a user-defined
+ function or aggregate is parallel safe, parallel restricted, or parallel
+ unsafe, because this would require predicting every operation that the
+ function could possibly perform. In general, this is equivalent to the
+ Halting Problem and therefore impossible. Even for simple functions
+ where it could conceivably be done, we do not try, since this would be expensive
+ and error-prone. Instead, all user-defined functions are assumed to
+ be parallel unsafe unless otherwise marked. When using
+ <xref linkend="sql-createfunction"/> or
+ <xref linkend="sql-alterfunction"/>, markings can be set by specifying
+ <literal>PARALLEL SAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or
+ <literal>PARALLEL UNSAFE</literal> as appropriate. When using
+ <xref linkend="sql-createaggregate"/>, the
+ <literal>PARALLEL</literal> option can be specified with <literal>SAFE</literal>,
+ <literal>RESTRICTED</literal>, or <literal>UNSAFE</literal> as the corresponding value.
+ </para>
+
+ <para>
+ Functions and aggregates must be marked <literal>PARALLEL UNSAFE</literal> if
+ they write to the database, access sequences, change the transaction state
+ even temporarily (e.g., a PL/pgSQL function that establishes an
+ <literal>EXCEPTION</literal> block to catch errors), or make persistent changes to
+ settings. Similarly, functions must be marked <literal>PARALLEL
+ RESTRICTED</literal> if they access temporary tables, client connection state,
+ cursors, prepared statements, or miscellaneous backend-local state that
+ the system cannot synchronize across workers. For example,
+ <literal>setseed</literal> and <literal>random</literal> are parallel restricted for
+ this last reason.
+ </para>
+
+ <para>
+ In general, if a function is labeled as being safe when it is restricted or
+ unsafe, or if it is labeled as being restricted when it is in fact unsafe,
+ it may throw errors or produce wrong answers when used in a parallel query.
+ C-language functions could in theory exhibit totally undefined behavior if
+ mislabeled, since there is no way for the system to protect itself against
+ arbitrary C code, but in most likely cases the result will be no worse than
+ for any other function. If in doubt, it is probably best to label functions
+ as <literal>UNSAFE</literal>.
+ </para>
+
+ <para>
+ If a function executed within a parallel worker acquires locks that are
+ not held by the leader, for example by querying a table not referenced in
+ the query, those locks will be released at worker exit, not end of
+ transaction. If you write a function that does this, and this behavior
+ difference is important to you, mark such functions as
+ <literal>PARALLEL RESTRICTED</literal>
+ to ensure that they execute only in the leader.
+ </para>
+
+ <para>
+ Note that the query planner does not consider deferring the evaluation of
+ parallel-restricted functions or aggregates involved in the query in
+ order to obtain a superior plan. So, for example, if a <literal>WHERE</literal>
+ clause applied to a particular table is parallel restricted, the query
+ planner will not consider performing a scan of that table in the parallel
+ portion of a plan. In some cases, it would be
+ possible (and perhaps even efficient) to include the scan of that table in
+ the parallel portion of the query and defer the evaluation of the
+ <literal>WHERE</literal> clause so that it happens above the <literal>Gather</literal>
+ node. However, the planner does not do this.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/passwordcheck.sgml b/doc/src/sgml/passwordcheck.sgml
new file mode 100644
index 0000000..0d89bb9
--- /dev/null
+++ b/doc/src/sgml/passwordcheck.sgml
@@ -0,0 +1,62 @@
+<!-- doc/src/sgml/passwordcheck.sgml -->
+
+<sect1 id="passwordcheck" xreflabel="passwordcheck">
+ <title>passwordcheck</title>
+
+ <indexterm zone="passwordcheck">
+ <primary>passwordcheck</primary>
+ </indexterm>
+
+ <para>
+ The <filename>passwordcheck</filename> module checks users' passwords
+ whenever they are set with
+ <xref linkend="sql-createrole"/> or
+ <xref linkend="sql-alterrole"/>.
+ If a password is considered too weak, it will be rejected and
+ the command will terminate with an error.
+ </para>
+
+ <para>
+ To enable this module, add <literal>'$libdir/passwordcheck'</literal>
+ to <xref linkend="guc-shared-preload-libraries"/> in
+ <filename>postgresql.conf</filename>, then restart the server.
+ </para>
+
+ <para>
+ You can adapt this module to your needs by changing the source code.
+ For example, you can use
+ <ulink url="https://github.com/cracklib/cracklib">CrackLib</ulink>
+ to check passwords &mdash; this only requires uncommenting
+ two lines in the <filename>Makefile</filename> and rebuilding the
+ module. (We cannot include <productname>CrackLib</productname>
+ by default for license reasons.)
+ Without <productname>CrackLib</productname>, the module enforces a few
+ simple rules for password strength, which you can modify or extend
+ as you see fit.
+ </para>
+
+ <caution>
+ <para>
+ To prevent unencrypted passwords from being sent across the network,
+ written to the server log or otherwise stolen by a database administrator,
+ <productname>PostgreSQL</productname> allows the user to supply
+ pre-encrypted passwords. Many client programs make use of this
+ functionality and encrypt the password before sending it to the server.
+ </para>
+ <para>
+ This limits the usefulness of the <filename>passwordcheck</filename>
+ module, because in that case it can only try to guess the password.
+ For this reason, <filename>passwordcheck</filename> is not
+ recommended if your security requirements are high.
+ It is more secure to use an external authentication method such as GSSAPI
+ (see <xref linkend="client-authentication"/>) than to rely on
+ passwords within the database.
+ </para>
+ <para>
+ Alternatively, you could modify <filename>passwordcheck</filename>
+ to reject pre-encrypted passwords, but forcing users to set their
+ passwords in clear text carries its own security risks.
+ </para>
+ </caution>
+
+</sect1>
diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml
new file mode 100644
index 0000000..ad21cec
--- /dev/null
+++ b/doc/src/sgml/perform.sgml
@@ -0,0 +1,1961 @@
+<!-- doc/src/sgml/perform.sgml -->
+
+ <chapter id="performance-tips">
+ <title>Performance Tips</title>
+
+ <indexterm zone="performance-tips">
+ <primary>performance</primary>
+ </indexterm>
+
+ <para>
+ Query performance can be affected by many things. Some of these can
+ be controlled by the user, while others are fundamental to the underlying
+ design of the system. This chapter provides some hints about understanding
+ and tuning <productname>PostgreSQL</productname> performance.
+ </para>
+
+ <sect1 id="using-explain">
+ <title>Using <command>EXPLAIN</command></title>
+
+ <indexterm zone="using-explain">
+ <primary>EXPLAIN</primary>
+ </indexterm>
+
+ <indexterm zone="using-explain">
+ <primary>query plan</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> devises a <firstterm>query
+ plan</firstterm> for each query it receives. Choosing the right
+ plan to match the query structure and the properties of the data
+ is absolutely critical for good performance, so the system includes
+ a complex <firstterm>planner</firstterm> that tries to choose good plans.
+ You can use the <link linkend="sql-explain"><command>EXPLAIN</command></link> command
+ to see what query plan the planner creates for any query.
+ Plan-reading is an art that requires some experience to master,
+ but this section attempts to cover the basics.
+ </para>
+
+ <para>
+ Examples in this section are drawn from the regression test database
+ after doing a <command>VACUUM ANALYZE</command>, using 9.3 development sources.
+ You should be able to get similar results if you try the examples
+ yourself, but your estimated costs and row counts might vary slightly
+ because <command>ANALYZE</command>'s statistics are random samples rather
+ than exact, and because costs are inherently somewhat platform-dependent.
+ </para>
+
+ <para>
+ The examples use <command>EXPLAIN</command>'s default <quote>text</quote> output
+ format, which is compact and convenient for humans to read.
+ If you want to feed <command>EXPLAIN</command>'s output to a program for further
+ analysis, you should use one of its machine-readable output formats
+ (XML, JSON, or YAML) instead.
+ </para>
+
+ <sect2 id="using-explain-basics">
+ <title><command>EXPLAIN</command> Basics</title>
+
+ <para>
+ The structure of a query plan is a tree of <firstterm>plan nodes</firstterm>.
+ Nodes at the bottom level of the tree are scan nodes: they return raw rows
+ from a table. There are different types of scan nodes for different
+ table access methods: sequential scans, index scans, and bitmap index
+ scans. There are also non-table row sources, such as <literal>VALUES</literal>
+ clauses and set-returning functions in <literal>FROM</literal>, which have their
+ own scan node types.
+ If the query requires joining, aggregation, sorting, or other
+ operations on the raw rows, then there will be additional nodes
+ above the scan nodes to perform these operations. Again,
+ there is usually more than one possible way to do these operations,
+ so different node types can appear here too. The output
+ of <command>EXPLAIN</command> has one line for each node in the plan
+ tree, showing the basic node type plus the cost estimates that the planner
+ made for the execution of that plan node. Additional lines might appear,
+ indented from the node's summary line,
+ to show additional properties of the node.
+ The very first line (the summary line for the topmost
+ node) has the estimated total execution cost for the plan; it is this
+ number that the planner seeks to minimize.
+ </para>
+
+ <para>
+ Here is a trivial example, just to show what the output looks like:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1;
+
+ QUERY PLAN
+-------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
+</screen>
+ </para>
+
+ <para>
+ Since this query has no <literal>WHERE</literal> clause, it must scan all the
+ rows of the table, so the planner has chosen to use a simple sequential
+ scan plan. The numbers that are quoted in parentheses are (left
+ to right):
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Estimated start-up cost. This is the time expended before the output
+ phase can begin, e.g., time to do the sorting in a sort node.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Estimated total cost. This is stated on the assumption that the plan
+ node is run to completion, i.e., all available rows are retrieved.
+ In practice a node's parent node might stop short of reading all
+ available rows (see the <literal>LIMIT</literal> example below).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Estimated number of rows output by this plan node. Again, the node
+ is assumed to be run to completion.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Estimated average width of rows output by this plan node (in bytes).
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The costs are measured in arbitrary units determined by the planner's
+ cost parameters (see <xref linkend="runtime-config-query-constants"/>).
+ Traditional practice is to measure the costs in units of disk page
+ fetches; that is, <xref linkend="guc-seq-page-cost"/> is conventionally
+ set to <literal>1.0</literal> and the other cost parameters are set relative
+ to that. The examples in this section are run with the default cost
+ parameters.
+ </para>
+
+ <para>
+ It's important to understand that the cost of an upper-level node includes
+ the cost of all its child nodes. It's also important to realize that
+ the cost only reflects things that the planner cares about.
+ In particular, the cost does not consider the time spent transmitting
+ result rows to the client, which could be an important
+ factor in the real elapsed time; but the planner ignores it because
+ it cannot change it by altering the plan. (Every correct plan will
+ output the same row set, we trust.)
+ </para>
+
+ <para>
+ The <literal>rows</literal> value is a little tricky because it is
+ not the number of rows processed or scanned by the
+ plan node, but rather the number emitted by the node. This is often
+ less than the number scanned, as a result of filtering by any
+ <literal>WHERE</literal>-clause conditions that are being applied at the node.
+ Ideally the top-level rows estimate will approximate the number of rows
+ actually returned, updated, or deleted by the query.
+ </para>
+
+ <para>
+ Returning to our example:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1;
+
+ QUERY PLAN
+-------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
+</screen>
+ </para>
+
+ <para>
+ These numbers are derived very straightforwardly. If you do:
+
+<programlisting>
+SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
+</programlisting>
+
+ you will find that <classname>tenk1</classname> has 358 disk
+ pages and 10000 rows. The estimated cost is computed as (disk pages read *
+ <xref linkend="guc-seq-page-cost"/>) + (rows scanned *
+ <xref linkend="guc-cpu-tuple-cost"/>). By default,
+ <varname>seq_page_cost</varname> is 1.0 and <varname>cpu_tuple_cost</varname> is 0.01,
+ so the estimated cost is (358 * 1.0) + (10000 * 0.01) = 458.
+ </para>
+
+ <para>
+ Now let's modify the query to add a <literal>WHERE</literal> condition:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 7000;
+
+ QUERY PLAN
+------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=7001 width=244)
+ Filter: (unique1 &lt; 7000)
+</screen>
+
+ Notice that the <command>EXPLAIN</command> output shows the <literal>WHERE</literal>
+ clause being applied as a <quote>filter</quote> condition attached to the Seq
+ Scan plan node. This means that
+ the plan node checks the condition for each row it scans, and outputs
+ only the ones that pass the condition.
+ The estimate of output rows has been reduced because of the
+ <literal>WHERE</literal> clause.
+ However, the scan will still have to visit all 10000 rows, so the cost
+ hasn't decreased; in fact it has gone up a bit (by 10000 * <xref
+ linkend="guc-cpu-operator-cost"/>, to be exact) to reflect the extra CPU
+ time spent checking the <literal>WHERE</literal> condition.
+ </para>
+
+ <para>
+ The actual number of rows this query would select is 7000, but the <literal>rows</literal>
+ estimate is only approximate. If you try to duplicate this experiment,
+ you will probably get a slightly different estimate; moreover, it can
+ change after each <command>ANALYZE</command> command, because the
+ statistics produced by <command>ANALYZE</command> are taken from a
+ randomized sample of the table.
+ </para>
+
+ <para>
+ Now, let's make the condition more restrictive:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------
+ Bitmap Heap Scan on tenk1 (cost=5.07..229.20 rows=101 width=244)
+ Recheck Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+</screen>
+
+ Here the planner has decided to use a two-step plan: the child plan
+ node visits an index to find the locations of rows matching the index
+ condition, and then the upper plan node actually fetches those rows
+ from the table itself. Fetching rows separately is much more
+ expensive than reading them sequentially, but because not all the pages
+ of the table have to be visited, this is still cheaper than a sequential
+ scan. (The reason for using two plan levels is that the upper plan
+ node sorts the row locations identified by the index into physical order
+ before reading them, to minimize the cost of separate fetches.
+ The <quote>bitmap</quote> mentioned in the node names is the mechanism that
+ does the sorting.)
+ </para>
+
+ <para>
+ Now let's add another condition to the <literal>WHERE</literal> clause:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND stringu1 = 'xxx';
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------
+ Bitmap Heap Scan on tenk1 (cost=5.04..229.43 rows=1 width=244)
+ Recheck Cond: (unique1 &lt; 100)
+ Filter: (stringu1 = 'xxx'::name)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+</screen>
+
+ The added condition <literal>stringu1 = 'xxx'</literal> reduces the
+ output row count estimate, but not the cost because we still have to visit
+ the same set of rows. Notice that the <literal>stringu1</literal> clause
+ cannot be applied as an index condition, since this index is only on
+ the <literal>unique1</literal> column. Instead it is applied as a filter on
+ the rows retrieved by the index. Thus the cost has actually gone up
+ slightly to reflect this extra checking.
+ </para>
+
+ <para>
+ In some cases the planner will prefer a <quote>simple</quote> index scan plan:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;----------
+ Index Scan using tenk1_unique1 on tenk1 (cost=0.29..8.30 rows=1 width=244)
+ Index Cond: (unique1 = 42)
+</screen>
+
+ In this type of plan the table rows are fetched in index order, which
+ makes them even more expensive to read, but there are so few that the
+ extra cost of sorting the row locations is not worth it. You'll most
+ often see this plan type for queries that fetch just a single row. It's
+ also often used for queries that have an <literal>ORDER BY</literal> condition
+ that matches the index order, because then no extra sorting step is needed
+ to satisfy the <literal>ORDER BY</literal>. In this example, adding
+ <literal>ORDER BY unique1</literal> would use the same plan because the
+ index already implicitly provides the requested ordering.
+ </para>
+
+ <para>
+ The planner may implement an <literal>ORDER BY</literal> clause in several
+ ways. The above example shows that such an ordering clause may be
+ implemented implicitly. The planner may also add an explicit
+ <literal>sort</literal> step:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 ORDER BY unique1;
+ QUERY PLAN
+-------------------------------------------------------------------
+ Sort (cost=1109.39..1134.39 rows=10000 width=244)
+ Sort Key: unique1
+ -> Seq Scan on tenk1 (cost=0.00..445.00 rows=10000 width=244)
+</screen>
+
+ If a part of the plan guarantees an ordering on a prefix of the
+ required sort keys, then the planner may instead decide to use an
+ <literal>incremental sort</literal> step:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 ORDER BY four, ten LIMIT 100;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------------------
+ Limit (cost=521.06..538.05 rows=100 width=244)
+ -> Incremental Sort (cost=521.06..2220.95 rows=10000 width=244)
+ Sort Key: four, ten
+ Presorted Key: four
+ -> Index Scan using index_tenk1_on_four on tenk1 (cost=0.29..1510.08 rows=10000 width=244)
+</screen>
+
+ Compared to regular sorts, sorting incrementally allows returning tuples
+ before the entire result set has been sorted, which particularly enables
+ optimizations with <literal>LIMIT</literal> queries. It may also reduce
+ memory usage and the likelihood of spilling sorts to disk, but it comes at
+ the cost of the increased overhead of splitting the result set into multiple
+ sorting batches.
+ </para>
+
+ <para>
+ If there are separate indexes on several of the columns referenced
+ in <literal>WHERE</literal>, the planner might choose to use an AND or OR
+ combination of the indexes:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------------
+ Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244)
+ Recheck Cond: ((unique1 &lt; 100) AND (unique2 &gt; 9000))
+ -&gt; BitmapAnd (cost=25.08..25.08 rows=10 width=0)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0)
+ Index Cond: (unique2 &gt; 9000)
+</screen>
+
+ But this requires visiting both indexes, so it's not necessarily a win
+ compared to using just one index and treating the other condition as
+ a filter. If you vary the ranges involved you'll see the plan change
+ accordingly.
+ </para>
+
+ <para>
+ Here is an example showing the effects of <literal>LIMIT</literal>:
+
+<screen>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------------
+ Limit (cost=0.29..14.48 rows=2 width=244)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 (cost=0.29..71.27 rows=10 width=244)
+ Index Cond: (unique2 &gt; 9000)
+ Filter: (unique1 &lt; 100)
+</screen>
+ </para>
+
+ <para>
+ This is the same query as above, but we added a <literal>LIMIT</literal> so that
+ not all the rows need be retrieved, and the planner changed its mind about
+ what to do. Notice that the total cost and row count of the Index Scan
+ node are shown as if it were run to completion. However, the Limit node
+ is expected to stop after retrieving only a fifth of those rows, so its
+ total cost is only a fifth as much, and that's the actual estimated cost
+ of the query. This plan is preferred over adding a Limit node to the
+ previous plan because the Limit could not avoid paying the startup cost
+ of the bitmap scan, so the total cost would be something over 25 units
+ with that approach.
+ </para>
+
+ <para>
+ Let's try joining two tables, using the columns we have been discussing:
+
+<screen>
+EXPLAIN SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------
+ Nested Loop (cost=4.65..118.62 rows=10 width=488)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244)
+ Recheck Cond: (unique1 &lt; 10)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0)
+ Index Cond: (unique1 &lt; 10)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244)
+ Index Cond: (unique2 = t1.unique2)
+</screen>
+ </para>
+
+ <para>
+ In this plan, we have a nested-loop join node with two table scans as
+ inputs, or children. The indentation of the node summary lines reflects
+ the plan tree structure. The join's first, or <quote>outer</quote>, child
+ is a bitmap scan similar to those we saw before. Its cost and row count
+ are the same as we'd get from <literal>SELECT ... WHERE unique1 &lt; 10</literal>
+ because we are
+ applying the <literal>WHERE</literal> clause <literal>unique1 &lt; 10</literal>
+ at that node.
+ The <literal>t1.unique2 = t2.unique2</literal> clause is not relevant yet,
+ so it doesn't affect the row count of the outer scan. The nested-loop
+ join node will run its second,
+ or <quote>inner</quote> child once for each row obtained from the outer child.
+ Column values from the current outer row can be plugged into the inner
+ scan; here, the <literal>t1.unique2</literal> value from the outer row is available,
+ so we get a plan and costs similar to what we saw above for a simple
+ <literal>SELECT ... WHERE t2.unique2 = <replaceable>constant</replaceable></literal> case.
+ (The estimated cost is actually a bit lower than what was seen above,
+ as a result of caching that's expected to occur during the repeated
+ index scans on <literal>t2</literal>.) The
+ costs of the loop node are then set on the basis of the cost of the outer
+ scan, plus one repetition of the inner scan for each outer row (10 * 7.91,
+ here), plus a little CPU time for join processing.
+ </para>
+
+ <para>
+ In this example the join's output row count is the same as the product
+ of the two scans' row counts, but that's not true in all cases because
+ there can be additional <literal>WHERE</literal> clauses that mention both tables
+ and so can only be applied at the join point, not to either input scan.
+ Here's an example:
+
+<screen>
+EXPLAIN SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 10 AND t2.unique2 &lt; 10 AND t1.hundred &lt; t2.hundred;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------------------------
+ Nested Loop (cost=4.65..49.46 rows=33 width=488)
+ Join Filter: (t1.hundred &lt; t2.hundred)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244)
+ Recheck Cond: (unique1 &lt; 10)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0)
+ Index Cond: (unique1 &lt; 10)
+ -&gt; Materialize (cost=0.29..8.51 rows=10 width=244)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..8.46 rows=10 width=244)
+ Index Cond: (unique2 &lt; 10)
+</screen>
+
+ The condition <literal>t1.hundred &lt; t2.hundred</literal> can't be
+ tested in the <literal>tenk2_unique2</literal> index, so it's applied at the
+ join node. This reduces the estimated output row count of the join node,
+ but does not change either input scan.
+ </para>
+
+ <para>
+ Notice that here the planner has chosen to <quote>materialize</quote> the inner
+ relation of the join, by putting a Materialize plan node atop it. This
+ means that the <literal>t2</literal> index scan will be done just once, even
+ though the nested-loop join node needs to read that data ten times, once
+ for each row from the outer relation. The Materialize node saves the data
+ in memory as it's read, and then returns the data from memory on each
+ subsequent pass.
+ </para>
+
+ <para>
+ When dealing with outer joins, you might see join plan nodes with both
+ <quote>Join Filter</quote> and plain <quote>Filter</quote> conditions attached.
+ Join Filter conditions come from the outer join's <literal>ON</literal> clause,
+ so a row that fails the Join Filter condition could still get emitted as
+ a null-extended row. But a plain Filter condition is applied after the
+ outer-join rules and so acts to remove rows unconditionally. In an inner
+ join there is no semantic difference between these types of filters.
+ </para>
+
+ <para>
+ If we change the query's selectivity a bit, we might get a very different
+ join plan:
+
+<screen>
+EXPLAIN SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------
+ Hash Join (cost=230.47..713.98 rows=101 width=488)
+ Hash Cond: (t2.unique2 = t1.unique2)
+ -&gt; Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244)
+ -&gt; Hash (cost=229.20..229.20 rows=101 width=244)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244)
+ Recheck Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
+ Index Cond: (unique1 &lt; 100)
+</screen>
+ </para>
+
+ <para>
+ Here, the planner has chosen to use a hash join, in which rows of one
+ table are entered into an in-memory hash table, after which the other
+ table is scanned and the hash table is probed for matches to each row.
+ Again note how the indentation reflects the plan structure: the bitmap
+ scan on <literal>tenk1</literal> is the input to the Hash node, which constructs
+ the hash table. That's then returned to the Hash Join node, which reads
+ rows from its outer child plan and searches the hash table for each one.
+ </para>
+
+ <para>
+ Another possible type of join is a merge join, illustrated here:
+
+<screen>
+EXPLAIN SELECT *
+FROM tenk1 t1, onek t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------
+ Merge Join (cost=198.11..268.19 rows=10 width=488)
+ Merge Cond: (t1.unique2 = t2.unique2)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244)
+ Filter: (unique1 &lt; 100)
+ -&gt; Sort (cost=197.83..200.33 rows=1000 width=244)
+ Sort Key: t2.unique2
+ -&gt; Seq Scan on onek t2 (cost=0.00..148.00 rows=1000 width=244)
+</screen>
+ </para>
+
+ <para>
+ Merge join requires its input data to be sorted on the join keys. In this
+ plan the <literal>tenk1</literal> data is sorted by using an index scan to visit
+ the rows in the correct order, but a sequential scan and sort is preferred
+ for <literal>onek</literal>, because there are many more rows to be visited in
+ that table.
+ (Sequential-scan-and-sort frequently beats an index scan for sorting many rows,
+ because of the nonsequential disk access required by the index scan.)
+ </para>
+
+ <para>
+ One way to look at variant plans is to force the planner to disregard
+ whatever strategy it thought was the cheapest, using the enable/disable
+ flags described in <xref linkend="runtime-config-query-enable"/>.
+ (This is a crude tool, but useful. See
+ also <xref linkend="explicit-joins"/>.)
+ For example, if we're unconvinced that sequential-scan-and-sort is the best way to
+ deal with table <literal>onek</literal> in the previous example, we could try
+
+<screen>
+SET enable_sort = off;
+
+EXPLAIN SELECT *
+FROM tenk1 t1, onek t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------
+ Merge Join (cost=0.56..292.65 rows=10 width=488)
+ Merge Cond: (t1.unique2 = t2.unique2)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244)
+ Filter: (unique1 &lt; 100)
+ -&gt; Index Scan using onek_unique2 on onek t2 (cost=0.28..224.79 rows=1000 width=244)
+</screen>
+
+ which shows that the planner thinks that sorting <literal>onek</literal> by
+ index-scanning is about 12% more expensive than sequential-scan-and-sort.
+ Of course, the next question is whether it's right about that.
+ We can investigate that using <command>EXPLAIN ANALYZE</command>, as discussed
+ below.
+ </para>
+
+ </sect2>
+
+ <sect2 id="using-explain-analyze">
+ <title><command>EXPLAIN ANALYZE</command></title>
+
+ <para>
+ It is possible to check the accuracy of the planner's estimates
+ by using <command>EXPLAIN</command>'s <literal>ANALYZE</literal> option. With this
+ option, <command>EXPLAIN</command> actually executes the query, and then displays
+ the true row counts and true run time accumulated within each plan node,
+ along with the same estimates that a plain <command>EXPLAIN</command>
+ shows. For example, we might get a result like this:
+
+<screen>
+EXPLAIN ANALYZE SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
+ Nested Loop (cost=4.65..118.62 rows=10 width=488) (actual time=0.128..0.377 rows=10 loops=1)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244) (actual time=0.057..0.121 rows=10 loops=1)
+ Recheck Cond: (unique1 &lt; 10)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) (actual time=0.024..0.024 rows=10 loops=1)
+ Index Cond: (unique1 &lt; 10)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244) (actual time=0.021..0.022 rows=1 loops=10)
+ Index Cond: (unique2 = t1.unique2)
+ Planning time: 0.181 ms
+ Execution time: 0.501 ms
+</screen>
+
+ Note that the <quote>actual time</quote> values are in milliseconds of
+ real time, whereas the <literal>cost</literal> estimates are expressed in
+ arbitrary units; so they are unlikely to match up.
+ The thing that's usually most important to look for is whether the
+ estimated row counts are reasonably close to reality. In this example
+ the estimates were all dead-on, but that's quite unusual in practice.
+ </para>
+
+ <para>
+ In some query plans, it is possible for a subplan node to be executed more
+ than once. For example, the inner index scan will be executed once per
+ outer row in the above nested-loop plan. In such cases, the
+ <literal>loops</literal> value reports the
+ total number of executions of the node, and the actual time and rows
+ values shown are averages per-execution. This is done to make the numbers
+ comparable with the way that the cost estimates are shown. Multiply by
+ the <literal>loops</literal> value to get the total time actually spent in
+ the node. In the above example, we spent a total of 0.220 milliseconds
+ executing the index scans on <literal>tenk2</literal>.
+ </para>
+
+ <para>
+ In some cases <command>EXPLAIN ANALYZE</command> shows additional execution
+ statistics beyond the plan node execution times and row counts.
+ For example, Sort and Hash nodes provide extra information:
+
+<screen>
+EXPLAIN ANALYZE SELECT *
+FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------------------------------------------------------&zwsp;------
+ Sort (cost=717.34..717.59 rows=101 width=488) (actual time=7.761..7.774 rows=100 loops=1)
+ Sort Key: t1.fivethous
+ Sort Method: quicksort Memory: 77kB
+ -&gt; Hash Join (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1)
+ Hash Cond: (t2.unique2 = t1.unique2)
+ -&gt; Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1)
+ -&gt; Hash (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1)
+ Buckets: 1024 Batches: 1 Memory Usage: 28kB
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)
+ Recheck Cond: (unique1 &lt; 100)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.049..0.049 rows=100 loops=1)
+ Index Cond: (unique1 &lt; 100)
+ Planning time: 0.194 ms
+ Execution time: 8.008 ms
+</screen>
+
+ The Sort node shows the sort method used (in particular, whether the sort
+ was in-memory or on-disk) and the amount of memory or disk space needed.
+ The Hash node shows the number of hash buckets and batches as well as the
+ peak amount of memory used for the hash table. (If the number of batches
+ exceeds one, there will also be disk space usage involved, but that is not
+ shown.)
+ </para>
+
+ <para>
+ Another type of extra information is the number of rows removed by a
+ filter condition:
+
+<screen>
+EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten &lt; 7;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=7000 width=244) (actual time=0.016..5.107 rows=7000 loops=1)
+ Filter: (ten &lt; 7)
+ Rows Removed by Filter: 3000
+ Planning time: 0.083 ms
+ Execution time: 5.905 ms
+</screen>
+
+ These counts can be particularly valuable for filter conditions applied at
+ join nodes. The <quote>Rows Removed</quote> line only appears when at least
+ one scanned row, or potential join pair in the case of a join node,
+ is rejected by the filter condition.
+ </para>
+
+ <para>
+ A case similar to filter conditions occurs with <quote>lossy</quote>
+ index scans. For example, consider this search for polygons containing a
+ specific point:
+
+<screen>
+EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; polygon '(0.5,2.0)';
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------------------
+ Seq Scan on polygon_tbl (cost=0.00..1.05 rows=1 width=32) (actual time=0.044..0.044 rows=0 loops=1)
+ Filter: (f1 @&gt; '((0.5,2))'::polygon)
+ Rows Removed by Filter: 4
+ Planning time: 0.040 ms
+ Execution time: 0.083 ms
+</screen>
+
+ The planner thinks (quite correctly) that this sample table is too small
+ to bother with an index scan, so we have a plain sequential scan in which
+ all the rows got rejected by the filter condition. But if we force an
+ index scan to be used, we see:
+
+<screen>
+SET enable_seqscan TO off;
+
+EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; polygon '(0.5,2.0)';
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------------------------------------------
+ Index Scan using gpolygonind on polygon_tbl (cost=0.13..8.15 rows=1 width=32) (actual time=0.062..0.062 rows=0 loops=1)
+ Index Cond: (f1 @&gt; '((0.5,2))'::polygon)
+ Rows Removed by Index Recheck: 1
+ Planning time: 0.034 ms
+ Execution time: 0.144 ms
+</screen>
+
+ Here we can see that the index returned one candidate row, which was
+ then rejected by a recheck of the index condition. This happens because a
+ GiST index is <quote>lossy</quote> for polygon containment tests: it actually
+ returns the rows with polygons that overlap the target, and then we have
+ to do the exact containment test on those rows.
+ </para>
+
+ <para>
+ <command>EXPLAIN</command> has a <literal>BUFFERS</literal> option that can be used with
+ <literal>ANALYZE</literal> to get even more run time statistics:
+
+<screen>
+EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
+ Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244) (actual time=0.323..0.342 rows=10 loops=1)
+ Recheck Cond: ((unique1 &lt; 100) AND (unique2 &gt; 9000))
+ Buffers: shared hit=15
+ -&gt; BitmapAnd (cost=25.08..25.08 rows=10 width=0) (actual time=0.309..0.309 rows=0 loops=1)
+ Buffers: shared hit=7
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.043..0.043 rows=100 loops=1)
+ Index Cond: (unique1 &lt; 100)
+ Buffers: shared hit=2
+ -&gt; Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) (actual time=0.227..0.227 rows=999 loops=1)
+ Index Cond: (unique2 &gt; 9000)
+ Buffers: shared hit=5
+ Planning time: 0.088 ms
+ Execution time: 0.423 ms
+</screen>
+
+ The numbers provided by <literal>BUFFERS</literal> help to identify which parts
+ of the query are the most I/O-intensive.
+ </para>
+
+ <para>
+ Keep in mind that because <command>EXPLAIN ANALYZE</command> actually
+ runs the query, any side-effects will happen as usual, even though
+ whatever results the query might output are discarded in favor of
+ printing the <command>EXPLAIN</command> data. If you want to analyze a
+ data-modifying query without changing your tables, you can
+ roll the command back afterwards, for example:
+
+<screen>
+BEGIN;
+
+EXPLAIN ANALYZE UPDATE tenk1 SET hundred = hundred + 1 WHERE unique1 &lt; 100;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------------------------------------------------
+ Update on tenk1 (cost=5.08..230.08 rows=0 width=0) (actual time=3.791..3.792 rows=0 loops=1)
+ -&gt; Bitmap Heap Scan on tenk1 (cost=5.08..230.08 rows=102 width=10) (actual time=0.069..0.513 rows=100 loops=1)
+ Recheck Cond: (unique1 &lt; 100)
+ Heap Blocks: exact=90
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.05 rows=102 width=0) (actual time=0.036..0.037 rows=300 loops=1)
+ Index Cond: (unique1 &lt; 100)
+ Planning Time: 0.113 ms
+ Execution Time: 3.850 ms
+
+ROLLBACK;
+</screen>
+ </para>
+
+ <para>
+ As seen in this example, when the query is an <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, or
+ <command>MERGE</command> command, the actual work of
+ applying the table changes is done by a top-level Insert, Update,
+ Delete, or Merge plan node. The plan nodes underneath this node perform
+ the work of locating the old rows and/or computing the new data.
+ So above, we see the same sort of bitmap table scan we've seen already,
+ and its output is fed to an Update node that stores the updated rows.
+ It's worth noting that although the data-modifying node can take a
+ considerable amount of run time (here, it's consuming the lion's share
+ of the time), the planner does not currently add anything to the cost
+ estimates to account for that work. That's because the work to be done is
+ the same for every correct query plan, so it doesn't affect planning
+ decisions.
+ </para>
+
+ <para>
+ When an <command>UPDATE</command>, <command>DELETE</command>, or
+ <command>MERGE</command> command affects an
+ inheritance hierarchy, the output might look like this:
+
+<screen>
+EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------------------
+ Update on parent (cost=0.00..24.59 rows=0 width=0)
+ Update on parent parent_1
+ Update on child1 parent_2
+ Update on child2 parent_3
+ Update on child3 parent_4
+ -&gt; Result (cost=0.00..24.59 rows=4 width=14)
+ -&gt; Append (cost=0.00..24.54 rows=4 width=14)
+ -&gt; Seq Scan on parent parent_1 (cost=0.00..0.00 rows=1 width=14)
+ Filter: (f1 = 101)
+ -&gt; Index Scan using child1_pkey on child1 parent_2 (cost=0.15..8.17 rows=1 width=14)
+ Index Cond: (f1 = 101)
+ -&gt; Index Scan using child2_pkey on child2 parent_3 (cost=0.15..8.17 rows=1 width=14)
+ Index Cond: (f1 = 101)
+ -&gt; Index Scan using child3_pkey on child3 parent_4 (cost=0.15..8.17 rows=1 width=14)
+ Index Cond: (f1 = 101)
+</screen>
+
+ In this example the Update node needs to consider three child tables as
+ well as the originally-mentioned parent table. So there are four input
+ scanning subplans, one per table. For clarity, the Update node is
+ annotated to show the specific target tables that will be updated, in the
+ same order as the corresponding subplans.
+ </para>
+
+ <para>
+ The <literal>Planning time</literal> shown by <command>EXPLAIN
+ ANALYZE</command> is the time it took to generate the query plan from the
+ parsed query and optimize it. It does not include parsing or rewriting.
+ </para>
+
+ <para>
+ The <literal>Execution time</literal> shown by <command>EXPLAIN
+ ANALYZE</command> includes executor start-up and shut-down time, as well
+ as the time to run any triggers that are fired, but it does not include
+ parsing, rewriting, or planning time.
+ Time spent executing <literal>BEFORE</literal> triggers, if any, is included in
+ the time for the related Insert, Update, or Delete node; but time
+ spent executing <literal>AFTER</literal> triggers is not counted there because
+ <literal>AFTER</literal> triggers are fired after completion of the whole plan.
+ The total time spent in each trigger
+ (either <literal>BEFORE</literal> or <literal>AFTER</literal>) is also shown separately.
+ Note that deferred constraint triggers will not be executed
+ until end of transaction and are thus not considered at all by
+ <command>EXPLAIN ANALYZE</command>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="using-explain-caveats">
+ <title>Caveats</title>
+
+ <para>
+ There are two significant ways in which run times measured by
+ <command>EXPLAIN ANALYZE</command> can deviate from normal execution of
+ the same query. First, since no output rows are delivered to the client,
+ network transmission costs and I/O conversion costs are not included.
+ Second, the measurement overhead added by <command>EXPLAIN
+ ANALYZE</command> can be significant, especially on machines with slow
+ <function>gettimeofday()</function> operating-system calls. You can use the
+ <xref linkend="pgtesttiming"/> tool to measure the overhead of timing
+ on your system.
+ </para>
+
+ <para>
+ <command>EXPLAIN</command> results should not be extrapolated to situations
+ much different from the one you are actually testing; for example,
+ results on a toy-sized table cannot be assumed to apply to large tables.
+ The planner's cost estimates are not linear and so it might choose
+ a different plan for a larger or smaller table. An extreme example
+ is that on a table that only occupies one disk page, you'll nearly
+ always get a sequential scan plan whether indexes are available or not.
+ The planner realizes that it's going to take one disk page read to
+ process the table in any case, so there's no value in expending additional
+ page reads to look at an index. (We saw this happening in the
+ <literal>polygon_tbl</literal> example above.)
+ </para>
+
+ <para>
+ There are cases in which the actual and estimated values won't match up
+ well, but nothing is really wrong. One such case occurs when
+ plan node execution is stopped short by a <literal>LIMIT</literal> or similar
+ effect. For example, in the <literal>LIMIT</literal> query we used before,
+
+<screen>
+EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------------------------------------------------------
+ Limit (cost=0.29..14.71 rows=2 width=244) (actual time=0.177..0.249 rows=2 loops=1)
+ -&gt; Index Scan using tenk1_unique2 on tenk1 (cost=0.29..72.42 rows=10 width=244) (actual time=0.174..0.244 rows=2 loops=1)
+ Index Cond: (unique2 &gt; 9000)
+ Filter: (unique1 &lt; 100)
+ Rows Removed by Filter: 287
+ Planning time: 0.096 ms
+ Execution time: 0.336 ms
+</screen>
+
+ the estimated cost and row count for the Index Scan node are shown as
+ though it were run to completion. But in reality the Limit node stopped
+ requesting rows after it got two, so the actual row count is only 2 and
+ the run time is less than the cost estimate would suggest. This is not
+ an estimation error, only a discrepancy in the way the estimates and true
+ values are displayed.
+ </para>
+
+ <para>
+ Merge joins also have measurement artifacts that can confuse the unwary.
+ A merge join will stop reading one input if it's exhausted the other input
+ and the next key value in the one input is greater than the last key value
+ of the other input; in such a case there can be no more matches and so no
+ need to scan the rest of the first input. This results in not reading all
+ of one child, with results like those mentioned for <literal>LIMIT</literal>.
+ Also, if the outer (first) child contains rows with duplicate key values,
+ the inner (second) child is backed up and rescanned for the portion of its
+ rows matching that key value. <command>EXPLAIN ANALYZE</command> counts these
+ repeated emissions of the same inner rows as if they were real additional
+ rows. When there are many outer duplicates, the reported actual row count
+ for the inner child plan node can be significantly larger than the number
+ of rows that are actually in the inner relation.
+ </para>
+
+ <para>
+ BitmapAnd and BitmapOr nodes always report their actual row counts as zero,
+ due to implementation limitations.
+ </para>
+
+ <para>
+ Normally, <command>EXPLAIN</command> will display every plan node
+ created by the planner. However, there are cases where the executor
+ can determine that certain nodes need not be executed because they
+ cannot produce any rows, based on parameter values that were not
+ available at planning time. (Currently this can only happen for child
+ nodes of an Append or MergeAppend node that is scanning a partitioned
+ table.) When this happens, those plan nodes are omitted from
+ the <command>EXPLAIN</command> output and a <literal>Subplans
+ Removed: <replaceable>N</replaceable></literal> annotation appears
+ instead.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="planner-stats">
+ <title>Statistics Used by the Planner</title>
+
+ <indexterm zone="planner-stats">
+ <primary>statistics</primary>
+ <secondary>of the planner</secondary>
+ </indexterm>
+
+ <sect2>
+ <title>Single-Column Statistics</title>
+ <para>
+ As we saw in the previous section, the query planner needs to estimate
+ the number of rows retrieved by a query in order to make good choices
+ of query plans. This section provides a quick look at the statistics
+ that the system uses for these estimates.
+ </para>
+
+ <para>
+ One component of the statistics is the total number of entries in
+ each table and index, as well as the number of disk blocks occupied
+ by each table and index. This information is kept in the table
+ <link linkend="catalog-pg-class"><structname>pg_class</structname></link>,
+ in the columns <structfield>reltuples</structfield> and
+ <structfield>relpages</structfield>. We can look at it with
+ queries similar to this one:
+
+<screen>
+SELECT relname, relkind, reltuples, relpages
+FROM pg_class
+WHERE relname LIKE 'tenk1%';
+
+ relname | relkind | reltuples | relpages
+----------------------+---------+-----------+----------
+ tenk1 | r | 10000 | 358
+ tenk1_hundred | i | 10000 | 30
+ tenk1_thous_tenthous | i | 10000 | 30
+ tenk1_unique1 | i | 10000 | 30
+ tenk1_unique2 | i | 10000 | 30
+(5 rows)
+</screen>
+
+ Here we can see that <structname>tenk1</structname> contains 10000
+ rows, as do its indexes, but the indexes are (unsurprisingly) much
+ smaller than the table.
+ </para>
+
+ <para>
+ For efficiency reasons, <structfield>reltuples</structfield>
+ and <structfield>relpages</structfield> are not updated on-the-fly,
+ and so they usually contain somewhat out-of-date values.
+ They are updated by <command>VACUUM</command>, <command>ANALYZE</command>, and a
+ few DDL commands such as <command>CREATE INDEX</command>. A <command>VACUUM</command>
+ or <command>ANALYZE</command> operation that does not scan the entire table
+ (which is commonly the case) will incrementally update the
+ <structfield>reltuples</structfield> count on the basis of the part
+ of the table it did scan, resulting in an approximate value.
+ In any case, the planner
+ will scale the values it finds in <structname>pg_class</structname>
+ to match the current physical table size, thus obtaining a closer
+ approximation.
+ </para>
+
+ <indexterm>
+ <primary>pg_statistic</primary>
+ </indexterm>
+
+ <para>
+ Most queries retrieve only a fraction of the rows in a table, due
+ to <literal>WHERE</literal> clauses that restrict the rows to be
+ examined. The planner thus needs to make an estimate of the
+ <firstterm>selectivity</firstterm> of <literal>WHERE</literal> clauses, that is,
+ the fraction of rows that match each condition in the
+ <literal>WHERE</literal> clause. The information used for this task is
+ stored in the
+ <link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>
+ system catalog. Entries in <structname>pg_statistic</structname>
+ are updated by the <command>ANALYZE</command> and <command>VACUUM
+ ANALYZE</command> commands, and are always approximate even when freshly
+ updated.
+ </para>
+
+ <indexterm>
+ <primary>pg_stats</primary>
+ </indexterm>
+
+ <para>
+ Rather than look at <structname>pg_statistic</structname> directly,
+ it's better to look at its view
+ <link linkend="view-pg-stats"><structname>pg_stats</structname></link>
+ when examining the statistics manually. <structname>pg_stats</structname>
+ is designed to be more easily readable. Furthermore,
+ <structname>pg_stats</structname> is readable by all, whereas
+ <structname>pg_statistic</structname> is only readable by a superuser.
+ (This prevents unprivileged users from learning something about
+ the contents of other people's tables from the statistics. The
+ <structname>pg_stats</structname> view is restricted to show only
+ rows about tables that the current user can read.)
+ For example, we might do:
+
+<screen>
+SELECT attname, inherited, n_distinct,
+ array_to_string(most_common_vals, E'\n') as most_common_vals
+FROM pg_stats
+WHERE tablename = 'road';
+
+ attname | inherited | n_distinct | most_common_vals
+---------+-----------+------------+------------------------------------
+ name | f | -0.363388 | I- 580 Ramp+
+ | | | I- 880 Ramp+
+ | | | Sp Railroad +
+ | | | I- 580 +
+ | | | I- 680 Ramp
+ name | t | -0.284859 | I- 880 Ramp+
+ | | | I- 580 Ramp+
+ | | | I- 680 Ramp+
+ | | | I- 580 +
+ | | | State Hwy 13 Ramp
+(2 rows)
+</screen>
+
+ Note that two rows are displayed for the same column, one corresponding
+ to the complete inheritance hierarchy starting at the
+ <literal>road</literal> table (<literal>inherited</literal>=<literal>t</literal>),
+ and another one including only the <literal>road</literal> table itself
+ (<literal>inherited</literal>=<literal>f</literal>).
+ </para>
+
+ <para>
+ The amount of information stored in <structname>pg_statistic</structname>
+ by <command>ANALYZE</command>, in particular the maximum number of entries in the
+ <structfield>most_common_vals</structfield> and <structfield>histogram_bounds</structfield>
+ arrays for each column, can be set on a
+ column-by-column basis using the <command>ALTER TABLE SET STATISTICS</command>
+ command, or globally by setting the
+ <xref linkend="guc-default-statistics-target"/> configuration variable.
+ The default limit is presently 100 entries. Raising the limit
+ might allow more accurate planner estimates to be made, particularly for
+ columns with irregular data distributions, at the price of consuming
+ more space in <structname>pg_statistic</structname> and slightly more
+ time to compute the estimates. Conversely, a lower limit might be
+ sufficient for columns with simple data distributions.
+ </para>
+
+ <para>
+ Further details about the planner's use of statistics can be found in
+ <xref linkend="planner-stats-details"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="planner-stats-extended">
+ <title>Extended Statistics</title>
+
+ <indexterm zone="planner-stats-extended">
+ <primary>statistics</primary>
+ <secondary>of the planner</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>correlation</primary>
+ <secondary>in the query planner</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pg_statistic_ext</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pg_statistic_ext_data</primary>
+ </indexterm>
+
+ <para>
+ It is common to see slow queries running bad execution plans because
+ multiple columns used in the query clauses are correlated.
+ The planner normally assumes that multiple conditions
+ are independent of each other,
+ an assumption that does not hold when column values are correlated.
+ Regular statistics, because of their per-individual-column nature,
+ cannot capture any knowledge about cross-column correlation.
+ However, <productname>PostgreSQL</productname> has the ability to compute
+ <firstterm>multivariate statistics</firstterm>, which can capture
+ such information.
+ </para>
+
+ <para>
+ Because the number of possible column combinations is very large,
+ it's impractical to compute multivariate statistics automatically.
+ Instead, <firstterm>extended statistics objects</firstterm>, more often
+ called just <firstterm>statistics objects</firstterm>, can be created to instruct
+ the server to obtain statistics across interesting sets of columns.
+ </para>
+
+ <para>
+ Statistics objects are created using the
+ <link linkend="sql-createstatistics"><command>CREATE STATISTICS</command></link> command.
+ Creation of such an object merely creates a catalog entry expressing
+ interest in the statistics. Actual data collection is performed
+ by <command>ANALYZE</command> (either a manual command, or background
+ auto-analyze). The collected values can be examined in the
+ <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>
+ catalog.
+ </para>
+
+ <para>
+ <command>ANALYZE</command> computes extended statistics based on the same
+ sample of table rows that it takes for computing regular single-column
+ statistics. Since the sample size is increased by increasing the
+ statistics target for the table or any of its columns (as described in
+ the previous section), a larger statistics target will normally result in
+ more accurate extended statistics, as well as more time spent calculating
+ them.
+ </para>
+
+ <para>
+ The following subsections describe the kinds of extended statistics
+ that are currently supported.
+ </para>
+
+ <sect3>
+ <title>Functional Dependencies</title>
+
+ <para>
+ The simplest kind of extended statistics tracks <firstterm>functional
+ dependencies</firstterm>, a concept used in definitions of database normal forms.
+ We say that column <structfield>b</structfield> is functionally dependent on
+ column <structfield>a</structfield> if knowledge of the value of
+ <structfield>a</structfield> is sufficient to determine the value
+ of <structfield>b</structfield>, that is there are no two rows having the same value
+ of <structfield>a</structfield> but different values of <structfield>b</structfield>.
+ In a fully normalized database, functional dependencies should exist
+ only on primary keys and superkeys. However, in practice many data sets
+ are not fully normalized for various reasons; intentional
+ denormalization for performance reasons is a common example.
+ Even in a fully normalized database, there may be partial correlation
+ between some columns, which can be expressed as partial functional
+ dependency.
+ </para>
+
+ <para>
+ The existence of functional dependencies directly affects the accuracy
+ of estimates in certain queries. If a query contains conditions on
+ both the independent and the dependent column(s), the
+ conditions on the dependent columns do not further reduce the result
+ size; but without knowledge of the functional dependency, the query
+ planner will assume that the conditions are independent, resulting
+ in underestimating the result size.
+ </para>
+
+ <para>
+ To inform the planner about functional dependencies, <command>ANALYZE</command>
+ can collect measurements of cross-column dependency. Assessing the
+ degree of dependency between all sets of columns would be prohibitively
+ expensive, so data collection is limited to those groups of columns
+ appearing together in a statistics object defined with
+ the <literal>dependencies</literal> option. It is advisable to create
+ <literal>dependencies</literal> statistics only for column groups that are
+ strongly correlated, to avoid unnecessary overhead in both
+ <command>ANALYZE</command> and later query planning.
+ </para>
+
+ <para>
+ Here is an example of collecting functional-dependency statistics:
+<programlisting>
+CREATE STATISTICS stts (dependencies) ON city, zip FROM zipcodes;
+
+ANALYZE zipcodes;
+
+SELECT stxname, stxkeys, stxddependencies
+ FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid)
+ WHERE stxname = 'stts';
+ stxname | stxkeys | stxddependencies
+---------+---------+------------------------------------------
+ stts | 1 5 | {"1 => 5": 1.000000, "5 => 1": 0.423130}
+(1 row)
+</programlisting>
+ Here it can be seen that column 1 (zip code) fully determines column
+ 5 (city) so the coefficient is 1.0, while city only determines zip code
+ about 42% of the time, meaning that there are many cities (58%) that are
+ represented by more than a single ZIP code.
+ </para>
+
+ <para>
+ When computing the selectivity for a query involving functionally
+ dependent columns, the planner adjusts the per-condition selectivity
+ estimates using the dependency coefficients so as not to produce
+ an underestimate.
+ </para>
+
+ <sect4>
+ <title>Limitations of Functional Dependencies</title>
+
+ <para>
+ Functional dependencies are currently only applied when considering
+ simple equality conditions that compare columns to constant values,
+ and <literal>IN</literal> clauses with constant values.
+ They are not used to improve estimates for equality conditions
+ comparing two columns or comparing a column to an expression, nor for
+ range clauses, <literal>LIKE</literal> or any other type of condition.
+ </para>
+
+ <para>
+ When estimating with functional dependencies, the planner assumes that
+ conditions on the involved columns are compatible and hence redundant.
+ If they are incompatible, the correct estimate would be zero rows, but
+ that possibility is not considered. For example, given a query like
+<programlisting>
+SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '94105';
+</programlisting>
+ the planner will disregard the <structfield>city</structfield> clause as not
+ changing the selectivity, which is correct. However, it will make
+ the same assumption about
+<programlisting>
+SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210';
+</programlisting>
+ even though there will really be zero rows satisfying this query.
+ Functional dependency statistics do not provide enough information
+ to conclude that, however.
+ </para>
+
+ <para>
+ In many practical situations, this assumption is usually satisfied;
+ for example, there might be a GUI in the application that only allows
+ selecting compatible city and ZIP code values to use in a query.
+ But if that's not the case, functional dependencies may not be a viable
+ option.
+ </para>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Multivariate N-Distinct Counts</title>
+
+ <para>
+ Single-column statistics store the number of distinct values in each
+ column. Estimates of the number of distinct values when combining more
+ than one column (for example, for <literal>GROUP BY a, b</literal>) are
+ frequently wrong when the planner only has single-column statistical
+ data, causing it to select bad plans.
+ </para>
+
+ <para>
+ To improve such estimates, <command>ANALYZE</command> can collect n-distinct
+ statistics for groups of columns. As before, it's impractical to do
+ this for every possible column grouping, so data is collected only for
+ those groups of columns appearing together in a statistics object
+ defined with the <literal>ndistinct</literal> option. Data will be collected
+ for each possible combination of two or more columns from the set of
+ listed columns.
+ </para>
+
+ <para>
+ Continuing the previous example, the n-distinct counts in a
+ table of ZIP codes might look like the following:
+<programlisting>
+CREATE STATISTICS stts2 (ndistinct) ON city, state, zip FROM zipcodes;
+
+ANALYZE zipcodes;
+
+SELECT stxkeys AS k, stxdndistinct AS nd
+ FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid)
+ WHERE stxname = 'stts2';
+-[ RECORD 1 ]------------------------------------------------------&zwsp;--
+k | 1 2 5
+nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
+(1 row)
+</programlisting>
+ This indicates that there are three combinations of columns that
+ have 33178 distinct values: ZIP code and state; ZIP code and city;
+ and ZIP code, city and state (the fact that they are all equal is
+ expected given that ZIP code alone is unique in this table). On the
+ other hand, the combination of city and state has only 27435 distinct
+ values.
+ </para>
+
+ <para>
+ It's advisable to create <literal>ndistinct</literal> statistics objects only
+ on combinations of columns that are actually used for grouping, and
+ for which misestimation of the number of groups is resulting in bad
+ plans. Otherwise, the <command>ANALYZE</command> cycles are just wasted.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Multivariate MCV Lists</title>
+
+ <para>
+ Another type of statistic stored for each column are most-common value
+ lists. This allows very accurate estimates for individual columns, but
+ may result in significant misestimates for queries with conditions on
+ multiple columns.
+ </para>
+
+ <para>
+ To improve such estimates, <command>ANALYZE</command> can collect MCV
+ lists on combinations of columns. Similarly to functional dependencies
+ and n-distinct coefficients, it's impractical to do this for every
+ possible column grouping. Even more so in this case, as the MCV list
+ (unlike functional dependencies and n-distinct coefficients) does store
+ the common column values. So data is collected only for those groups
+ of columns appearing together in a statistics object defined with the
+ <literal>mcv</literal> option.
+ </para>
+
+ <para>
+ Continuing the previous example, the MCV list for a table of ZIP codes
+ might look like the following (unlike for simpler types of statistics,
+ a function is required for inspection of MCV contents):
+
+<programlisting>
+CREATE STATISTICS stts3 (mcv) ON city, state FROM zipcodes;
+
+ANALYZE zipcodes;
+
+SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
+ pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts3';
+
+ index | values | nulls | frequency | base_frequency
+-------+------------------------+-------+-----------+----------------
+ 0 | {Washington, DC} | {f,f} | 0.003467 | 2.7e-05
+ 1 | {Apo, AE} | {f,f} | 0.003067 | 1.9e-05
+ 2 | {Houston, TX} | {f,f} | 0.002167 | 0.000133
+ 3 | {El Paso, TX} | {f,f} | 0.002 | 0.000113
+ 4 | {New York, NY} | {f,f} | 0.001967 | 0.000114
+ 5 | {Atlanta, GA} | {f,f} | 0.001633 | 3.3e-05
+ 6 | {Sacramento, CA} | {f,f} | 0.001433 | 7.8e-05
+ 7 | {Miami, FL} | {f,f} | 0.0014 | 6e-05
+ 8 | {Dallas, TX} | {f,f} | 0.001367 | 8.8e-05
+ 9 | {Chicago, IL} | {f,f} | 0.001333 | 5.1e-05
+ ...
+(99 rows)
+</programlisting>
+ This indicates that the most common combination of city and state is
+ Washington in DC, with actual frequency (in the sample) about 0.35%.
+ The base frequency of the combination (as computed from the simple
+ per-column frequencies) is only 0.0027%, resulting in two orders of
+ magnitude under-estimates.
+ </para>
+
+ <para>
+ It's advisable to create <acronym>MCV</acronym> statistics objects only
+ on combinations of columns that are actually used in conditions together,
+ and for which misestimation of the number of groups is resulting in bad
+ plans. Otherwise, the <command>ANALYZE</command> and planning cycles
+ are just wasted.
+ </para>
+ </sect3>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="explicit-joins">
+ <title>Controlling the Planner with Explicit <literal>JOIN</literal> Clauses</title>
+
+ <indexterm zone="explicit-joins">
+ <primary>join</primary>
+ <secondary>controlling the order</secondary>
+ </indexterm>
+
+ <para>
+ It is possible
+ to control the query planner to some extent by using the explicit <literal>JOIN</literal>
+ syntax. To see why this matters, we first need some background.
+ </para>
+
+ <para>
+ In a simple join query, such as:
+<programlisting>
+SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
+</programlisting>
+ the planner is free to join the given tables in any order. For
+ example, it could generate a query plan that joins A to B, using
+ the <literal>WHERE</literal> condition <literal>a.id = b.id</literal>, and then
+ joins C to this joined table, using the other <literal>WHERE</literal>
+ condition. Or it could join B to C and then join A to that result.
+ Or it could join A to C and then join them with B &mdash; but that
+ would be inefficient, since the full Cartesian product of A and C
+ would have to be formed, there being no applicable condition in the
+ <literal>WHERE</literal> clause to allow optimization of the join. (All
+ joins in the <productname>PostgreSQL</productname> executor happen
+ between two input tables, so it's necessary to build up the result
+ in one or another of these fashions.) The important point is that
+ these different join possibilities give semantically equivalent
+ results but might have hugely different execution costs. Therefore,
+ the planner will explore all of them to try to find the most
+ efficient query plan.
+ </para>
+
+ <para>
+ When a query only involves two or three tables, there aren't many join
+ orders to worry about. But the number of possible join orders grows
+ exponentially as the number of tables expands. Beyond ten or so input
+ tables it's no longer practical to do an exhaustive search of all the
+ possibilities, and even for six or seven tables planning might take an
+ annoyingly long time. When there are too many input tables, the
+ <productname>PostgreSQL</productname> planner will switch from exhaustive
+ search to a <firstterm>genetic</firstterm> probabilistic search
+ through a limited number of possibilities. (The switch-over threshold is
+ set by the <xref linkend="guc-geqo-threshold"/> run-time
+ parameter.)
+ The genetic search takes less time, but it won't
+ necessarily find the best possible plan.
+ </para>
+
+ <para>
+ When the query involves outer joins, the planner has less freedom
+ than it does for plain (inner) joins. For example, consider:
+<programlisting>
+SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
+</programlisting>
+ Although this query's restrictions are superficially similar to the
+ previous example, the semantics are different because a row must be
+ emitted for each row of A that has no matching row in the join of B and C.
+ Therefore the planner has no choice of join order here: it must join
+ B to C and then join A to that result. Accordingly, this query takes
+ less time to plan than the previous query. In other cases, the planner
+ might be able to determine that more than one join order is safe.
+ For example, given:
+<programlisting>
+SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id);
+</programlisting>
+ it is valid to join A to either B or C first. Currently, only
+ <literal>FULL JOIN</literal> completely constrains the join order. Most
+ practical cases involving <literal>LEFT JOIN</literal> or <literal>RIGHT JOIN</literal>
+ can be rearranged to some extent.
+ </para>
+
+ <para>
+ Explicit inner join syntax (<literal>INNER JOIN</literal>, <literal>CROSS
+ JOIN</literal>, or unadorned <literal>JOIN</literal>) is semantically the same as
+ listing the input relations in <literal>FROM</literal>, so it does not
+ constrain the join order.
+ </para>
+
+ <para>
+ Even though most kinds of <literal>JOIN</literal> don't completely constrain
+ the join order, it is possible to instruct the
+ <productname>PostgreSQL</productname> query planner to treat all
+ <literal>JOIN</literal> clauses as constraining the join order anyway.
+ For example, these three queries are logically equivalent:
+<programlisting>
+SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
+SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id;
+SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
+</programlisting>
+ But if we tell the planner to honor the <literal>JOIN</literal> order,
+ the second and third take less time to plan than the first. This effect
+ is not worth worrying about for only three tables, but it can be a
+ lifesaver with many tables.
+ </para>
+
+ <para>
+ To force the planner to follow the join order laid out by explicit
+ <literal>JOIN</literal>s,
+ set the <xref linkend="guc-join-collapse-limit"/> run-time parameter to 1.
+ (Other possible values are discussed below.)
+ </para>
+
+ <para>
+ You do not need to constrain the join order completely in order to
+ cut search time, because it's OK to use <literal>JOIN</literal> operators
+ within items of a plain <literal>FROM</literal> list. For example, consider:
+<programlisting>
+SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;
+</programlisting>
+ With <varname>join_collapse_limit</varname> = 1, this
+ forces the planner to join A to B before joining them to other tables,
+ but doesn't constrain its choices otherwise. In this example, the
+ number of possible join orders is reduced by a factor of 5.
+ </para>
+
+ <para>
+ Constraining the planner's search in this way is a useful technique
+ both for reducing planning time and for directing the planner to a
+ good query plan. If the planner chooses a bad join order by default,
+ you can force it to choose a better order via <literal>JOIN</literal> syntax
+ &mdash; assuming that you know of a better order, that is. Experimentation
+ is recommended.
+ </para>
+
+ <para>
+ A closely related issue that affects planning time is collapsing of
+ subqueries into their parent query. For example, consider:
+<programlisting>
+SELECT *
+FROM x, y,
+ (SELECT * FROM a, b, c WHERE something) AS ss
+WHERE somethingelse;
+</programlisting>
+ This situation might arise from use of a view that contains a join;
+ the view's <literal>SELECT</literal> rule will be inserted in place of the view
+ reference, yielding a query much like the above. Normally, the planner
+ will try to collapse the subquery into the parent, yielding:
+<programlisting>
+SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;
+</programlisting>
+ This usually results in a better plan than planning the subquery
+ separately. (For example, the outer <literal>WHERE</literal> conditions might be such that
+ joining X to A first eliminates many rows of A, thus avoiding the need to
+ form the full logical output of the subquery.) But at the same time,
+ we have increased the planning time; here, we have a five-way join
+ problem replacing two separate three-way join problems. Because of the
+ exponential growth of the number of possibilities, this makes a big
+ difference. The planner tries to avoid getting stuck in huge join search
+ problems by not collapsing a subquery if more than <varname>from_collapse_limit</varname>
+ <literal>FROM</literal> items would result in the parent
+ query. You can trade off planning time against quality of plan by
+ adjusting this run-time parameter up or down.
+ </para>
+
+ <para>
+ <xref linkend="guc-from-collapse-limit"/> and <xref
+ linkend="guc-join-collapse-limit"/>
+ are similarly named because they do almost the same thing: one controls
+ when the planner will <quote>flatten out</quote> subqueries, and the
+ other controls when it will flatten out explicit joins. Typically
+ you would either set <varname>join_collapse_limit</varname> equal to
+ <varname>from_collapse_limit</varname> (so that explicit joins and subqueries
+ act similarly) or set <varname>join_collapse_limit</varname> to 1 (if you want
+ to control join order with explicit joins). But you might set them
+ differently if you are trying to fine-tune the trade-off between planning
+ time and run time.
+ </para>
+ </sect1>
+
+ <sect1 id="populate">
+ <title>Populating a Database</title>
+
+ <para>
+ One might need to insert a large amount of data when first populating
+ a database. This section contains some suggestions on how to make
+ this process as efficient as possible.
+ </para>
+
+ <sect2 id="disable-autocommit">
+ <title>Disable Autocommit</title>
+
+ <indexterm>
+ <primary>autocommit</primary>
+ <secondary>bulk-loading data</secondary>
+ </indexterm>
+
+ <para>
+ When using multiple <command>INSERT</command>s, turn off autocommit and just do
+ one commit at the end. (In plain
+ SQL, this means issuing <command>BEGIN</command> at the start and
+ <command>COMMIT</command> at the end. Some client libraries might
+ do this behind your back, in which case you need to make sure the
+ library does it when you want it done.) If you allow each
+ insertion to be committed separately,
+ <productname>PostgreSQL</productname> is doing a lot of work for
+ each row that is added. An additional benefit of doing all
+ insertions in one transaction is that if the insertion of one row
+ were to fail then the insertion of all rows inserted up to that
+ point would be rolled back, so you won't be stuck with partially
+ loaded data.
+ </para>
+ </sect2>
+
+ <sect2 id="populate-copy-from">
+ <title>Use <command>COPY</command></title>
+
+ <para>
+ Use <link linkend="sql-copy"><command>COPY</command></link> to load
+ all the rows in one command, instead of using a series of
+ <command>INSERT</command> commands. The <command>COPY</command>
+ command is optimized for loading large numbers of rows; it is less
+ flexible than <command>INSERT</command>, but incurs significantly
+ less overhead for large data loads. Since <command>COPY</command>
+ is a single command, there is no need to disable autocommit if you
+ use this method to populate a table.
+ </para>
+
+ <para>
+ If you cannot use <command>COPY</command>, it might help to use <link
+ linkend="sql-prepare"><command>PREPARE</command></link> to create a
+ prepared <command>INSERT</command> statement, and then use
+ <command>EXECUTE</command> as many times as required. This avoids
+ some of the overhead of repeatedly parsing and planning
+ <command>INSERT</command>. Different interfaces provide this facility
+ in different ways; look for <quote>prepared statements</quote> in the interface
+ documentation.
+ </para>
+
+ <para>
+ Note that loading a large number of rows using
+ <command>COPY</command> is almost always faster than using
+ <command>INSERT</command>, even if <command>PREPARE</command> is used and
+ multiple insertions are batched into a single transaction.
+ </para>
+
+ <para>
+ <command>COPY</command> is fastest when used within the same
+ transaction as an earlier <command>CREATE TABLE</command> or
+ <command>TRUNCATE</command> command. In such cases no WAL
+ needs to be written, because in case of an error, the files
+ containing the newly loaded data will be removed anyway.
+ However, this consideration only applies when
+ <xref linkend="guc-wal-level"/> is <literal>minimal</literal>
+ as all commands must write WAL otherwise.
+ </para>
+
+ </sect2>
+
+ <sect2 id="populate-rm-indexes">
+ <title>Remove Indexes</title>
+
+ <para>
+ If you are loading a freshly created table, the fastest method is to
+ create the table, bulk load the table's data using
+ <command>COPY</command>, then create any indexes needed for the
+ table. Creating an index on pre-existing data is quicker than
+ updating it incrementally as each row is loaded.
+ </para>
+
+ <para>
+ If you are adding large amounts of data to an existing table,
+ it might be a win to drop the indexes,
+ load the table, and then recreate the indexes. Of course, the
+ database performance for other users might suffer
+ during the time the indexes are missing. One should also think
+ twice before dropping a unique index, since the error checking
+ afforded by the unique constraint will be lost while the index is
+ missing.
+ </para>
+ </sect2>
+
+ <sect2 id="populate-rm-fkeys">
+ <title>Remove Foreign Key Constraints</title>
+
+ <para>
+ Just as with indexes, a foreign key constraint can be checked
+ <quote>in bulk</quote> more efficiently than row-by-row. So it might be
+ useful to drop foreign key constraints, load data, and re-create
+ the constraints. Again, there is a trade-off between data load
+ speed and loss of error checking while the constraint is missing.
+ </para>
+
+ <para>
+ What's more, when you load data into a table with existing foreign key
+ constraints, each new row requires an entry in the server's list of
+ pending trigger events (since it is the firing of a trigger that checks
+ the row's foreign key constraint). Loading many millions of rows can
+ cause the trigger event queue to overflow available memory, leading to
+ intolerable swapping or even outright failure of the command. Therefore
+ it may be <emphasis>necessary</emphasis>, not just desirable, to drop and re-apply
+ foreign keys when loading large amounts of data. If temporarily removing
+ the constraint isn't acceptable, the only other recourse may be to split
+ up the load operation into smaller transactions.
+ </para>
+ </sect2>
+
+ <sect2 id="populate-work-mem">
+ <title>Increase <varname>maintenance_work_mem</varname></title>
+
+ <para>
+ Temporarily increasing the <xref linkend="guc-maintenance-work-mem"/>
+ configuration variable when loading large amounts of data can
+ lead to improved performance. This will help to speed up <command>CREATE
+ INDEX</command> commands and <command>ALTER TABLE ADD FOREIGN KEY</command> commands.
+ It won't do much for <command>COPY</command> itself, so this advice is
+ only useful when you are using one or both of the above techniques.
+ </para>
+ </sect2>
+
+ <sect2 id="populate-max-wal-size">
+ <title>Increase <varname>max_wal_size</varname></title>
+
+ <para>
+ Temporarily increasing the <xref linkend="guc-max-wal-size"/>
+ configuration variable can also
+ make large data loads faster. This is because loading a large
+ amount of data into <productname>PostgreSQL</productname> will
+ cause checkpoints to occur more often than the normal checkpoint
+ frequency (specified by the <varname>checkpoint_timeout</varname>
+ configuration variable). Whenever a checkpoint occurs, all dirty
+ pages must be flushed to disk. By increasing
+ <varname>max_wal_size</varname> temporarily during bulk
+ data loads, the number of checkpoints that are required can be
+ reduced.
+ </para>
+ </sect2>
+
+ <sect2 id="populate-pitr">
+ <title>Disable WAL Archival and Streaming Replication</title>
+
+ <para>
+ When loading large amounts of data into an installation that uses
+ WAL archiving or streaming replication, it might be faster to take a
+ new base backup after the load has completed than to process a large
+ amount of incremental WAL data. To prevent incremental WAL logging
+ while loading, disable archiving and streaming replication, by setting
+ <xref linkend="guc-wal-level"/> to <literal>minimal</literal>,
+ <xref linkend="guc-archive-mode"/> to <literal>off</literal>, and
+ <xref linkend="guc-max-wal-senders"/> to zero.
+ But note that changing these settings requires a server restart,
+ and makes any base backups taken before unavailable for archive
+ recovery and standby server, which may lead to data loss.
+ </para>
+
+ <para>
+ Aside from avoiding the time for the archiver or WAL sender to process the
+ WAL data, doing this will actually make certain commands faster, because
+ they do not to write WAL at all if <varname>wal_level</varname>
+ is <literal>minimal</literal> and the current subtransaction (or top-level
+ transaction) created or truncated the table or index they change. (They
+ can guarantee crash safety more cheaply by doing
+ an <function>fsync</function> at the end than by writing WAL.)
+ </para>
+ </sect2>
+
+ <sect2 id="populate-analyze">
+ <title>Run <command>ANALYZE</command> Afterwards</title>
+
+ <para>
+ Whenever you have significantly altered the distribution of data
+ within a table, running <link linkend="sql-analyze"><command>ANALYZE</command></link> is strongly recommended. This
+ includes bulk loading large amounts of data into the table. Running
+ <command>ANALYZE</command> (or <command>VACUUM ANALYZE</command>)
+ ensures that the planner has up-to-date statistics about the
+ table. With no statistics or obsolete statistics, the planner might
+ make poor decisions during query planning, leading to poor
+ performance on any tables with inaccurate or nonexistent
+ statistics. Note that if the autovacuum daemon is enabled, it might
+ run <command>ANALYZE</command> automatically; see
+ <xref linkend="vacuum-for-statistics"/>
+ and <xref linkend="autovacuum"/> for more information.
+ </para>
+ </sect2>
+
+ <sect2 id="populate-pg-dump">
+ <title>Some Notes about <application>pg_dump</application></title>
+
+ <para>
+ Dump scripts generated by <application>pg_dump</application> automatically apply
+ several, but not all, of the above guidelines. To restore a
+ <application>pg_dump</application> dump as quickly as possible, you need to
+ do a few extra things manually. (Note that these points apply while
+ <emphasis>restoring</emphasis> a dump, not while <emphasis>creating</emphasis> it.
+ The same points apply whether loading a text dump with
+ <application>psql</application> or using <application>pg_restore</application> to load
+ from a <application>pg_dump</application> archive file.)
+ </para>
+
+ <para>
+ By default, <application>pg_dump</application> uses <command>COPY</command>, and when
+ it is generating a complete schema-and-data dump, it is careful to
+ load data before creating indexes and foreign keys. So in this case
+ several guidelines are handled automatically. What is left
+ for you to do is to:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Set appropriate (i.e., larger than normal) values for
+ <varname>maintenance_work_mem</varname> and
+ <varname>max_wal_size</varname>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If using WAL archiving or streaming replication, consider disabling
+ them during the restore. To do that, set <varname>archive_mode</varname>
+ to <literal>off</literal>,
+ <varname>wal_level</varname> to <literal>minimal</literal>, and
+ <varname>max_wal_senders</varname> to zero before loading the dump.
+ Afterwards, set them back to the right values and take a fresh
+ base backup.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Experiment with the parallel dump and restore modes of both
+ <application>pg_dump</application> and <application>pg_restore</application> and find the
+ optimal number of concurrent jobs to use. Dumping and restoring in
+ parallel by means of the <option>-j</option> option should give you a
+ significantly higher performance over the serial mode.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Consider whether the whole dump should be restored as a single
+ transaction. To do that, pass the <option>-1</option> or
+ <option>--single-transaction</option> command-line option to
+ <application>psql</application> or <application>pg_restore</application>. When using this
+ mode, even the smallest of errors will rollback the entire restore,
+ possibly discarding many hours of processing. Depending on how
+ interrelated the data is, that might seem preferable to manual cleanup,
+ or not. <command>COPY</command> commands will run fastest if you use a single
+ transaction and have WAL archiving turned off.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If multiple CPUs are available in the database server, consider using
+ <application>pg_restore</application>'s <option>--jobs</option> option. This
+ allows concurrent data loading and index creation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Run <command>ANALYZE</command> afterwards.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ A data-only dump will still use <command>COPY</command>, but it does not
+ drop or recreate indexes, and it does not normally touch foreign
+ keys.
+
+ <footnote>
+ <para>
+ You can get the effect of disabling foreign keys by using
+ the <option>--disable-triggers</option> option &mdash; but realize that
+ that eliminates, rather than just postpones, foreign key
+ validation, and so it is possible to insert bad data if you use it.
+ </para>
+ </footnote>
+
+ So when loading a data-only dump, it is up to you to drop and recreate
+ indexes and foreign keys if you wish to use those techniques.
+ It's still useful to increase <varname>max_wal_size</varname>
+ while loading the data, but don't bother increasing
+ <varname>maintenance_work_mem</varname>; rather, you'd do that while
+ manually recreating indexes and foreign keys afterwards.
+ And don't forget to <command>ANALYZE</command> when you're done; see
+ <xref linkend="vacuum-for-statistics"/>
+ and <xref linkend="autovacuum"/> for more information.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="non-durability">
+ <title>Non-Durable Settings</title>
+
+ <indexterm zone="non-durability">
+ <primary>non-durable</primary>
+ </indexterm>
+
+ <para>
+ Durability is a database feature that guarantees the recording of
+ committed transactions even if the server crashes or loses
+ power. However, durability adds significant database overhead,
+ so if your site does not require such a guarantee,
+ <productname>PostgreSQL</productname> can be configured to run
+ much faster. The following are configuration changes you can make
+ to improve performance in such cases. Except as noted below, durability
+ is still guaranteed in case of a crash of the database software;
+ only an abrupt operating system crash creates a risk of data loss
+ or corruption when these settings are used.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Place the database cluster's data directory in a memory-backed
+ file system (i.e., <acronym>RAM</acronym> disk). This eliminates all
+ database disk I/O, but limits data storage to the amount of
+ available memory (and perhaps swap).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Turn off <xref linkend="guc-fsync"/>; there is no need to flush
+ data to disk.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Turn off <xref linkend="guc-synchronous-commit"/>; there might be no
+ need to force <acronym>WAL</acronym> writes to disk on every
+ commit. This setting does risk transaction loss (though not data
+ corruption) in case of a crash of the <emphasis>database</emphasis>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Turn off <xref linkend="guc-full-page-writes"/>; there is no need
+ to guard against partial page writes.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Increase <xref linkend="guc-max-wal-size"/> and <xref
+ linkend="guc-checkpoint-timeout"/>; this reduces the frequency
+ of checkpoints, but increases the storage requirements of
+ <filename>/pg_wal</filename>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Create <link linkend="sql-createtable-unlogged">unlogged
+ tables</link> to avoid <acronym>WAL</acronym> writes, though it
+ makes the tables non-crash-safe.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/pgbuffercache.sgml b/doc/src/sgml/pgbuffercache.sgml
new file mode 100644
index 0000000..a06fd3e
--- /dev/null
+++ b/doc/src/sgml/pgbuffercache.sgml
@@ -0,0 +1,213 @@
+<!-- doc/src/sgml/pgbuffercache.sgml -->
+
+<sect1 id="pgbuffercache" xreflabel="pg_buffercache">
+ <title>pg_buffercache</title>
+
+ <indexterm zone="pgbuffercache">
+ <primary>pg_buffercache</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_buffercache</filename> module provides a means for
+ examining what's happening in the shared buffer cache in real time.
+ </para>
+
+ <indexterm>
+ <primary>pg_buffercache_pages</primary>
+ </indexterm>
+
+ <para>
+ The module provides a C function <function>pg_buffercache_pages</function>
+ that returns a set of records, plus a view
+ <structname>pg_buffercache</structname> that wraps the function for
+ convenient use.
+ </para>
+
+ <para>
+ By default, use is restricted to superusers and roles with privileges of the
+ <literal>pg_monitor</literal> role. Access may be granted to others
+ using <command>GRANT</command>.
+ </para>
+
+ <sect2>
+ <title>The <structname>pg_buffercache</structname> View</title>
+
+ <para>
+ The definitions of the columns exposed by the view are shown in <xref linkend="pgbuffercache-columns"/>.
+ </para>
+
+ <table id="pgbuffercache-columns">
+ <title><structname>pg_buffercache</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>bufferid</structfield> <type>integer</type>
+ </para>
+ <para>
+ ID, in the range 1..<varname>shared_buffers</varname>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relfilenode</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relfilenode</structfield>)
+ </para>
+ <para>
+ Filenode number of the relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reltablespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Tablespace OID of the relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reldatabase</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Database OID of the relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relforknumber</structfield> <type>smallint</type>
+ </para>
+ <para>
+ Fork number within the relation; see
+ <filename>common/relpath.h</filename>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relblocknumber</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Page number within the relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>isdirty</structfield> <type>boolean</type>
+ </para>
+ <para>
+ Is the page dirty?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usagecount</structfield> <type>smallint</type>
+ </para>
+ <para>
+ Clock-sweep access count
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pinning_backends</structfield> <type>integer</type>
+ </para>
+ <para>
+ Number of backends pinning this buffer
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ There is one row for each buffer in the shared cache. Unused buffers are
+ shown with all fields null except <structfield>bufferid</structfield>. Shared system
+ catalogs are shown as belonging to database zero.
+ </para>
+
+ <para>
+ Because the cache is shared by all the databases, there will normally be
+ pages from relations not belonging to the current database. This means
+ that there may not be matching join rows in <structname>pg_class</structname> for
+ some rows, or that there could even be incorrect joins. If you are
+ trying to join against <structname>pg_class</structname>, it's a good idea to
+ restrict the join to rows having <structfield>reldatabase</structfield> equal to
+ the current database's OID or zero.
+ </para>
+
+ <para>
+ Since buffer manager locks are not taken to copy the buffer state data that
+ the view will display, accessing <structname>pg_buffercache</structname> view
+ has less impact on normal buffer activity but it doesn't provide a consistent
+ set of results across all buffers. However, we ensure that the information of
+ each buffer is self-consistent.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Sample Output</title>
+
+<screen>
+regression=# SELECT n.nspname, c.relname, count(*) AS buffers
+ FROM pg_buffercache b JOIN pg_class c
+ ON b.relfilenode = pg_relation_filenode(c.oid) AND
+ b.reldatabase IN (0, (SELECT oid FROM pg_database
+ WHERE datname = current_database()))
+ JOIN pg_namespace n ON n.oid = c.relnamespace
+ GROUP BY n.nspname, c.relname
+ ORDER BY 3 DESC
+ LIMIT 10;
+
+ nspname | relname | buffers
+------------+------------------------+---------
+ public | delete_test_table | 593
+ public | delete_test_table_pkey | 494
+ pg_catalog | pg_attribute | 472
+ public | quad_poly_tbl | 353
+ public | tenk2 | 349
+ public | tenk1 | 349
+ public | gin_test_idx | 306
+ pg_catalog | pg_largeobject | 206
+ public | gin_test_tbl | 188
+ public | spgist_text_tbl | 182
+(10 rows)
+</screen>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Mark Kirkwood <email>markir@paradise.net.nz</email>
+ </para>
+
+ <para>
+ Design suggestions: Neil Conway <email>neilc@samurai.com</email>
+ </para>
+
+ <para>
+ Debugging advice: Tom Lane <email>tgl@sss.pgh.pa.us</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
new file mode 100644
index 0000000..43fb8db
--- /dev/null
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -0,0 +1,1332 @@
+<!-- doc/src/sgml/pgcrypto.sgml -->
+
+<sect1 id="pgcrypto" xreflabel="pgcrypto">
+ <title>pgcrypto</title>
+
+ <indexterm zone="pgcrypto">
+ <primary>pgcrypto</primary>
+ </indexterm>
+
+ <indexterm zone="pgcrypto">
+ <primary>encryption</primary>
+ <secondary>for specific columns</secondary>
+ </indexterm>
+
+ <para>
+ The <filename>pgcrypto</filename> module provides cryptographic functions for
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <para>
+ <filename>pgcrypto</filename> requires OpenSSL and won't be installed if
+ OpenSSL support was not selected when PostgreSQL was built.
+ </para>
+
+ <sect2>
+ <title>General Hashing Functions</title>
+
+ <sect3>
+ <title><function>digest()</function></title>
+
+ <indexterm>
+ <primary>digest</primary>
+ </indexterm>
+
+<synopsis>
+digest(data text, type text) returns bytea
+digest(data bytea, type text) returns bytea
+</synopsis>
+
+ <para>
+ Computes a binary hash of the given <parameter>data</parameter>.
+ <parameter>type</parameter> is the algorithm to use.
+ Standard algorithms are <literal>md5</literal>, <literal>sha1</literal>,
+ <literal>sha224</literal>, <literal>sha256</literal>,
+ <literal>sha384</literal> and <literal>sha512</literal>.
+ Moreover, any digest algorithm <productname>OpenSSL</productname> supports
+ is automatically picked up.
+ </para>
+
+ <para>
+ If you want the digest as a hexadecimal string, use
+ <function>encode()</function> on the result. For example:
+<programlisting>
+CREATE OR REPLACE FUNCTION sha1(bytea) returns text AS $$
+ SELECT encode(digest($1, 'sha1'), 'hex')
+$$ LANGUAGE SQL STRICT IMMUTABLE;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>hmac()</function></title>
+
+ <indexterm>
+ <primary>hmac</primary>
+ </indexterm>
+
+<synopsis>
+hmac(data text, key text, type text) returns bytea
+hmac(data bytea, key bytea, type text) returns bytea
+</synopsis>
+
+ <para>
+ Calculates hashed MAC for <parameter>data</parameter> with key <parameter>key</parameter>.
+ <parameter>type</parameter> is the same as in <function>digest()</function>.
+ </para>
+
+ <para>
+ This is similar to <function>digest()</function> but the hash can only be
+ recalculated knowing the key. This prevents the scenario of someone
+ altering data and also changing the hash to match.
+ </para>
+
+ <para>
+ If the key is larger than the hash block size it will first be hashed and
+ the result will be used as key.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Password Hashing Functions</title>
+
+ <para>
+ The functions <function>crypt()</function> and <function>gen_salt()</function>
+ are specifically designed for hashing passwords.
+ <function>crypt()</function> does the hashing and <function>gen_salt()</function>
+ prepares algorithm parameters for it.
+ </para>
+
+ <para>
+ The algorithms in <function>crypt()</function> differ from the usual
+ MD5 or SHA1 hashing algorithms in the following respects:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ They are slow. As the amount of data is so small, this is the only
+ way to make brute-forcing passwords hard.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ They use a random value, called the <firstterm>salt</firstterm>, so that users
+ having the same password will have different encrypted passwords.
+ This is also an additional defense against reversing the algorithm.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ They include the algorithm type in the result, so passwords hashed with
+ different algorithms can co-exist.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Some of them are adaptive &mdash; that means when computers get
+ faster, you can tune the algorithm to be slower, without
+ introducing incompatibility with existing passwords.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ <xref linkend="pgcrypto-crypt-algorithms"/> lists the algorithms
+ supported by the <function>crypt()</function> function.
+ </para>
+
+ <table id="pgcrypto-crypt-algorithms">
+ <title>Supported Algorithms for <function>crypt()</function></title>
+ <tgroup cols="6">
+ <thead>
+ <row>
+ <entry>Algorithm</entry>
+ <entry>Max Password Length</entry>
+ <entry>Adaptive?</entry>
+ <entry>Salt Bits</entry>
+ <entry>Output Length</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>bf</literal></entry>
+ <entry>72</entry>
+ <entry>yes</entry>
+ <entry>128</entry>
+ <entry>60</entry>
+ <entry>Blowfish-based, variant 2a</entry>
+ </row>
+ <row>
+ <entry><literal>md5</literal></entry>
+ <entry>unlimited</entry>
+ <entry>no</entry>
+ <entry>48</entry>
+ <entry>34</entry>
+ <entry>MD5-based crypt</entry>
+ </row>
+ <row>
+ <entry><literal>xdes</literal></entry>
+ <entry>8</entry>
+ <entry>yes</entry>
+ <entry>24</entry>
+ <entry>20</entry>
+ <entry>Extended DES</entry>
+ </row>
+ <row>
+ <entry><literal>des</literal></entry>
+ <entry>8</entry>
+ <entry>no</entry>
+ <entry>12</entry>
+ <entry>13</entry>
+ <entry>Original UNIX crypt</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect3>
+ <title><function>crypt()</function></title>
+
+ <indexterm>
+ <primary>crypt</primary>
+ </indexterm>
+
+<synopsis>
+crypt(password text, salt text) returns text
+</synopsis>
+
+ <para>
+ Calculates a crypt(3)-style hash of <parameter>password</parameter>.
+ When storing a new password, you need to use
+ <function>gen_salt()</function> to generate a new <parameter>salt</parameter> value.
+ To check a password, pass the stored hash value as <parameter>salt</parameter>,
+ and test whether the result matches the stored value.
+ </para>
+ <para>
+ Example of setting a new password:
+<programlisting>
+UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
+</programlisting>
+ </para>
+ <para>
+ Example of authentication:
+<programlisting>
+SELECT (pswhash = crypt('entered password', pswhash)) AS pswmatch FROM ... ;
+</programlisting>
+ This returns <literal>true</literal> if the entered password is correct.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>gen_salt()</function></title>
+
+ <indexterm>
+ <primary>gen_salt</primary>
+ </indexterm>
+
+<synopsis>
+gen_salt(type text [, iter_count integer ]) returns text
+</synopsis>
+
+ <para>
+ Generates a new random salt string for use in <function>crypt()</function>.
+ The salt string also tells <function>crypt()</function> which algorithm to use.
+ </para>
+
+ <para>
+ The <parameter>type</parameter> parameter specifies the hashing algorithm.
+ The accepted types are: <literal>des</literal>, <literal>xdes</literal>,
+ <literal>md5</literal> and <literal>bf</literal>.
+ </para>
+
+ <para>
+ The <parameter>iter_count</parameter> parameter lets the user specify the iteration
+ count, for algorithms that have one.
+ The higher the count, the more time it takes to hash
+ the password and therefore the more time to break it. Although with
+ too high a count the time to calculate a hash may be several years
+ &mdash; which is somewhat impractical. If the <parameter>iter_count</parameter>
+ parameter is omitted, the default iteration count is used.
+ Allowed values for <parameter>iter_count</parameter> depend on the algorithm and
+ are shown in <xref linkend="pgcrypto-icfc-table"/>.
+ </para>
+
+ <table id="pgcrypto-icfc-table">
+ <title>Iteration Counts for <function>crypt()</function></title>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Algorithm</entry>
+ <entry>Default</entry>
+ <entry>Min</entry>
+ <entry>Max</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>xdes</literal></entry>
+ <entry>725</entry>
+ <entry>1</entry>
+ <entry>16777215</entry>
+ </row>
+ <row>
+ <entry><literal>bf</literal></entry>
+ <entry>6</entry>
+ <entry>4</entry>
+ <entry>31</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ For <literal>xdes</literal> there is an additional limitation that the
+ iteration count must be an odd number.
+ </para>
+
+ <para>
+ To pick an appropriate iteration count, consider that
+ the original DES crypt was designed to have the speed of 4 hashes per
+ second on the hardware of that time.
+ Slower than 4 hashes per second would probably dampen usability.
+ Faster than 100 hashes per second is probably too fast.
+ </para>
+
+ <para>
+ <xref linkend="pgcrypto-hash-speed-table"/> gives an overview of the relative slowness
+ of different hashing algorithms.
+ The table shows how much time it would take to try all
+ combinations of characters in an 8-character password, assuming
+ that the password contains either only lower case letters, or
+ upper- and lower-case letters and numbers.
+ In the <literal>crypt-bf</literal> entries, the number after a slash is
+ the <parameter>iter_count</parameter> parameter of
+ <function>gen_salt</function>.
+ </para>
+
+ <table id="pgcrypto-hash-speed-table">
+ <title>Hash Algorithm Speeds</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>Algorithm</entry>
+ <entry>Hashes/sec</entry>
+ <entry>For <literal>[a-z]</literal></entry>
+ <entry>For <literal>[A-Za-z0-9]</literal></entry>
+ <entry>Duration relative to <literal>md5 hash</literal></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>crypt-bf/8</literal></entry>
+ <entry>1792</entry>
+ <entry>4 years</entry>
+ <entry>3927 years</entry>
+ <entry>100k</entry>
+ </row>
+ <row>
+ <entry><literal>crypt-bf/7</literal></entry>
+ <entry>3648</entry>
+ <entry>2 years</entry>
+ <entry>1929 years</entry>
+ <entry>50k</entry>
+ </row>
+ <row>
+ <entry><literal>crypt-bf/6</literal></entry>
+ <entry>7168</entry>
+ <entry>1 year</entry>
+ <entry>982 years</entry>
+ <entry>25k</entry>
+ </row>
+ <row>
+ <entry><literal>crypt-bf/5</literal></entry>
+ <entry>13504</entry>
+ <entry>188 days</entry>
+ <entry>521 years</entry>
+ <entry>12.5k</entry>
+ </row>
+ <row>
+ <entry><literal>crypt-md5</literal></entry>
+ <entry>171584</entry>
+ <entry>15 days</entry>
+ <entry>41 years</entry>
+ <entry>1k</entry>
+ </row>
+ <row>
+ <entry><literal>crypt-des</literal></entry>
+ <entry>23221568</entry>
+ <entry>157.5 minutes</entry>
+ <entry>108 days</entry>
+ <entry>7</entry>
+ </row>
+ <row>
+ <entry><literal>sha1</literal></entry>
+ <entry>37774272</entry>
+ <entry>90 minutes</entry>
+ <entry>68 days</entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry><literal>md5</literal> (hash)</entry>
+ <entry>150085504</entry>
+ <entry>22.5 minutes</entry>
+ <entry>17 days</entry>
+ <entry>1</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Notes:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The machine used is an Intel Mobile Core i3.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>crypt-des</literal> and <literal>crypt-md5</literal> algorithm numbers are
+ taken from John the Ripper v1.6.38 <literal>-test</literal> output.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>md5 hash</literal> numbers are from mdcrack 1.2.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>sha1</literal> numbers are from lcrack-20031130-beta.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>crypt-bf</literal> numbers are taken using a simple program that
+ loops over 1000 8-character passwords. That way I can show the speed
+ with different numbers of iterations. For reference: <literal>john
+ -test</literal> shows 13506 loops/sec for <literal>crypt-bf/5</literal>.
+ (The very small
+ difference in results is in accordance with the fact that the
+ <literal>crypt-bf</literal> implementation in <filename>pgcrypto</filename>
+ is the same one used in John the Ripper.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Note that <quote>try all combinations</quote> is not a realistic exercise.
+ Usually password cracking is done with the help of dictionaries, which
+ contain both regular words and various mutations of them. So, even
+ somewhat word-like passwords could be cracked much faster than the above
+ numbers suggest, while a 6-character non-word-like password may escape
+ cracking. Or not.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>PGP Encryption Functions</title>
+
+ <para>
+ The functions here implement the encryption part of the OpenPGP
+ (<ulink url="https://tools.ietf.org/html/rfc4880">RFC 4880</ulink>)
+ standard. Supported are both symmetric-key and public-key encryption.
+ </para>
+
+ <para>
+ An encrypted PGP message consists of 2 parts, or <firstterm>packets</firstterm>:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Packet containing a session key &mdash; either symmetric-key or public-key
+ encrypted.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Packet containing data encrypted with the session key.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ When encrypting with a symmetric key (i.e., a password):
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ The given password is hashed using a String2Key (S2K) algorithm. This is
+ rather similar to <function>crypt()</function> algorithms &mdash; purposefully
+ slow and with random salt &mdash; but it produces a full-length binary
+ key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a separate session key is requested, a new random key will be
+ generated. Otherwise the S2K key will be used directly as the session
+ key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the S2K key is to be used directly, then only S2K settings will be put
+ into the session key packet. Otherwise the session key will be encrypted
+ with the S2K key and put into the session key packet.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ When encrypting with a public key:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ A new random session key is generated.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It is encrypted using the public key and put into the session key packet.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ In either case the data to be encrypted is processed as follows:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ Optional data-manipulation: compression, conversion to UTF-8,
+ and/or conversion of line-endings.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The data is prefixed with a block of random bytes. This is equivalent
+ to using a random IV.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A SHA1 hash of the random prefix and data is appended.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All this is encrypted with the session key and placed in the data packet.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <sect3>
+ <title><function>pgp_sym_encrypt()</function></title>
+
+ <indexterm>
+ <primary>pgp_sym_encrypt</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pgp_sym_encrypt_bytea</primary>
+ </indexterm>
+
+<synopsis>
+pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
+pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea
+</synopsis>
+ <para>
+ Encrypt <parameter>data</parameter> with a symmetric PGP key <parameter>psw</parameter>.
+ The <parameter>options</parameter> parameter can contain option settings,
+ as described below.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>pgp_sym_decrypt()</function></title>
+
+ <indexterm>
+ <primary>pgp_sym_decrypt</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pgp_sym_decrypt_bytea</primary>
+ </indexterm>
+
+<synopsis>
+pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text
+pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea
+</synopsis>
+ <para>
+ Decrypt a symmetric-key-encrypted PGP message.
+ </para>
+ <para>
+ Decrypting <type>bytea</type> data with <function>pgp_sym_decrypt</function> is disallowed.
+ This is to avoid outputting invalid character data. Decrypting
+ originally textual data with <function>pgp_sym_decrypt_bytea</function> is fine.
+ </para>
+ <para>
+ The <parameter>options</parameter> parameter can contain option settings,
+ as described below.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>pgp_pub_encrypt()</function></title>
+
+ <indexterm>
+ <primary>pgp_pub_encrypt</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pgp_pub_encrypt_bytea</primary>
+ </indexterm>
+
+<synopsis>
+pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
+pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea
+</synopsis>
+ <para>
+ Encrypt <parameter>data</parameter> with a public PGP key <parameter>key</parameter>.
+ Giving this function a secret key will produce an error.
+ </para>
+ <para>
+ The <parameter>options</parameter> parameter can contain option settings,
+ as described below.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>pgp_pub_decrypt()</function></title>
+
+ <indexterm>
+ <primary>pgp_pub_decrypt</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>pgp_pub_decrypt_bytea</primary>
+ </indexterm>
+
+<synopsis>
+pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns text
+pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea
+</synopsis>
+ <para>
+ Decrypt a public-key-encrypted message. <parameter>key</parameter> must be the
+ secret key corresponding to the public key that was used to encrypt.
+ If the secret key is password-protected, you must give the password in
+ <parameter>psw</parameter>. If there is no password, but you want to specify
+ options, you need to give an empty password.
+ </para>
+ <para>
+ Decrypting <type>bytea</type> data with <function>pgp_pub_decrypt</function> is disallowed.
+ This is to avoid outputting invalid character data. Decrypting
+ originally textual data with <function>pgp_pub_decrypt_bytea</function> is fine.
+ </para>
+ <para>
+ The <parameter>options</parameter> parameter can contain option settings,
+ as described below.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>pgp_key_id()</function></title>
+
+ <indexterm>
+ <primary>pgp_key_id</primary>
+ </indexterm>
+
+<synopsis>
+pgp_key_id(bytea) returns text
+</synopsis>
+ <para>
+ <function>pgp_key_id</function> extracts the key ID of a PGP public or secret key.
+ Or it gives the key ID that was used for encrypting the data, if given
+ an encrypted message.
+ </para>
+ <para>
+ It can return 2 special key IDs:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>SYMKEY</literal>
+ </para>
+ <para>
+ The message is encrypted with a symmetric key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ANYKEY</literal>
+ </para>
+ <para>
+ The message is public-key encrypted, but the key ID has been removed.
+ That means you will need to try all your secret keys on it to see
+ which one decrypts it. <filename>pgcrypto</filename> itself does not produce
+ such messages.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Note that different keys may have the same ID. This is rare but a normal
+ event. The client application should then try to decrypt with each one,
+ to see which fits &mdash; like handling <literal>ANYKEY</literal>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>armor()</function>, <function>dearmor()</function></title>
+
+ <indexterm>
+ <primary>armor</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>dearmor</primary>
+ </indexterm>
+
+<synopsis>
+armor(data bytea [ , keys text[], values text[] ]) returns text
+dearmor(data text) returns bytea
+</synopsis>
+ <para>
+ These functions wrap/unwrap binary data into PGP ASCII-armor format,
+ which is basically Base64 with CRC and additional formatting.
+ </para>
+
+ <para>
+ If the <parameter>keys</parameter> and <parameter>values</parameter> arrays are specified,
+ an <firstterm>armor header</firstterm> is added to the armored format for each
+ key/value pair. Both arrays must be single-dimensional, and they must
+ be of the same length. The keys and values cannot contain any non-ASCII
+ characters.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><function>pgp_armor_headers</function></title>
+
+ <indexterm>
+ <primary>pgp_armor_headers</primary>
+ </indexterm>
+
+<synopsis>
+pgp_armor_headers(data text, key out text, value out text) returns setof record
+</synopsis>
+ <para>
+ <function>pgp_armor_headers()</function> extracts the armor headers from
+ <parameter>data</parameter>. The return value is a set of rows with two columns,
+ key and value. If the keys or values contain any non-ASCII characters,
+ they are treated as UTF-8.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Options for PGP Functions</title>
+
+ <para>
+ Options are named to be similar to GnuPG. An option's value should be
+ given after an equal sign; separate options from each other with commas.
+ For example:
+<programlisting>
+pgp_sym_encrypt(data, psw, 'compress-algo=1, cipher-algo=aes256')
+</programlisting>
+ </para>
+
+ <para>
+ All of the options except <literal>convert-crlf</literal> apply only to
+ encrypt functions. Decrypt functions get the parameters from the PGP
+ data.
+ </para>
+
+ <para>
+ The most interesting options are probably
+ <literal>compress-algo</literal> and <literal>unicode-mode</literal>.
+ The rest should have reasonable defaults.
+ </para>
+
+ <sect4>
+ <title>cipher-algo</title>
+
+ <para>
+ Which cipher algorithm to use.
+ </para>
+<literallayout>
+Values: bf, aes128, aes192, aes256, 3des, cast5
+Default: aes128
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>compress-algo</title>
+
+ <para>
+ Which compression algorithm to use. Only available if
+ <productname>PostgreSQL</productname> was built with zlib.
+ </para>
+<literallayout>
+Values:
+ 0 - no compression
+ 1 - ZIP compression
+ 2 - ZLIB compression (= ZIP plus meta-data and block CRCs)
+Default: 0
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>compress-level</title>
+
+ <para>
+ How much to compress. Higher levels compress smaller but are slower.
+ 0 disables compression.
+ </para>
+<literallayout>
+Values: 0, 1-9
+Default: 6
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>convert-crlf</title>
+
+ <para>
+ Whether to convert <literal>\n</literal> into <literal>\r\n</literal> when
+ encrypting and <literal>\r\n</literal> to <literal>\n</literal> when
+ decrypting. <acronym>RFC</acronym> 4880 specifies that text data should be stored using
+ <literal>\r\n</literal> line-feeds. Use this to get fully RFC-compliant
+ behavior.
+ </para>
+<literallayout>
+Values: 0, 1
+Default: 0
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt, pgp_sym_decrypt, pgp_pub_decrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>disable-mdc</title>
+
+ <para>
+ Do not protect data with SHA-1. The only good reason to use this
+ option is to achieve compatibility with ancient PGP products, predating
+ the addition of SHA-1 protected packets to <acronym>RFC</acronym> 4880.
+ Recent gnupg.org and pgp.com software supports it fine.
+ </para>
+<literallayout>
+Values: 0, 1
+Default: 0
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>sess-key</title>
+
+ <para>
+ Use separate session key. Public-key encryption always uses a separate
+ session key; this option is for symmetric-key encryption, which by default
+ uses the S2K key directly.
+ </para>
+<literallayout>
+Values: 0, 1
+Default: 0
+Applies to: pgp_sym_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>s2k-mode</title>
+
+ <para>
+ Which S2K algorithm to use.
+ </para>
+<literallayout>
+Values:
+ 0 - Without salt. Dangerous!
+ 1 - With salt but with fixed iteration count.
+ 3 - Variable iteration count.
+Default: 3
+Applies to: pgp_sym_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>s2k-count</title>
+
+ <para>
+ The number of iterations of the S2K algorithm to use. It must
+ be a value between 1024 and 65011712, inclusive.
+ </para>
+<literallayout>
+Default: A random value between 65536 and 253952
+Applies to: pgp_sym_encrypt, only with s2k-mode=3
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>s2k-digest-algo</title>
+
+ <para>
+ Which digest algorithm to use in S2K calculation.
+ </para>
+<literallayout>
+Values: md5, sha1
+Default: sha1
+Applies to: pgp_sym_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>s2k-cipher-algo</title>
+
+ <para>
+ Which cipher to use for encrypting separate session key.
+ </para>
+<literallayout>
+Values: bf, aes, aes128, aes192, aes256
+Default: use cipher-algo
+Applies to: pgp_sym_encrypt
+</literallayout>
+ </sect4>
+
+ <sect4>
+ <title>unicode-mode</title>
+
+ <para>
+ Whether to convert textual data from database internal encoding to
+ UTF-8 and back. If your database already is UTF-8, no conversion will
+ be done, but the message will be tagged as UTF-8. Without this option
+ it will not be.
+ </para>
+<literallayout>
+Values: 0, 1
+Default: 0
+Applies to: pgp_sym_encrypt, pgp_pub_encrypt
+</literallayout>
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Generating PGP Keys with GnuPG</title>
+
+ <para>
+ To generate a new key:
+<programlisting>
+gpg --gen-key
+</programlisting>
+ </para>
+ <para>
+ The preferred key type is <quote>DSA and Elgamal</quote>.
+ </para>
+ <para>
+ For RSA encryption you must create either DSA or RSA sign-only key
+ as master and then add an RSA encryption subkey with
+ <literal>gpg --edit-key</literal>.
+ </para>
+ <para>
+ To list keys:
+<programlisting>
+gpg --list-secret-keys
+</programlisting>
+ </para>
+ <para>
+ To export a public key in ASCII-armor format:
+<programlisting>
+gpg -a --export KEYID > public.key
+</programlisting>
+ </para>
+ <para>
+ To export a secret key in ASCII-armor format:
+<programlisting>
+gpg -a --export-secret-keys KEYID > secret.key
+</programlisting>
+ </para>
+ <para>
+ You need to use <function>dearmor()</function> on these keys before giving them to
+ the PGP functions. Or if you can handle binary data, you can drop
+ <literal>-a</literal> from the command.
+ </para>
+ <para>
+ For more details see <literal>man gpg</literal>,
+ <ulink url="https://www.gnupg.org/gph/en/manual.html">The GNU
+ Privacy Handbook</ulink> and other documentation on
+ <ulink url="https://www.gnupg.org/"></ulink>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Limitations of PGP Code</title>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ No support for signing. That also means that it is not checked
+ whether the encryption subkey belongs to the master key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ No support for encryption key as master key. As such practice
+ is generally discouraged, this should not be a problem.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ No support for several subkeys. This may seem like a problem, as this
+ is common practice. On the other hand, you should not use your regular
+ GPG/PGP keys with <filename>pgcrypto</filename>, but create new ones,
+ as the usage scenario is rather different.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Raw Encryption Functions</title>
+
+ <para>
+ These functions only run a cipher over data; they don't have any advanced
+ features of PGP encryption. Therefore they have some major problems:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ They use user key directly as cipher key.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ They don't provide any integrity checking, to see
+ if the encrypted data was modified.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ They expect that users manage all encryption parameters
+ themselves, even IV.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ They don't handle text.
+ </para>
+ </listitem>
+ </orderedlist>
+ <para>
+ So, with the introduction of PGP encryption, usage of raw
+ encryption functions is discouraged.
+ </para>
+
+ <indexterm>
+ <primary>encrypt</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>decrypt</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>encrypt_iv</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>decrypt_iv</primary>
+ </indexterm>
+
+<synopsis>
+encrypt(data bytea, key bytea, type text) returns bytea
+decrypt(data bytea, key bytea, type text) returns bytea
+
+encrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
+decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea
+</synopsis>
+
+ <para>
+ Encrypt/decrypt data using the cipher method specified by
+ <parameter>type</parameter>. The syntax of the
+ <parameter>type</parameter> string is:
+
+<synopsis>
+<replaceable>algorithm</replaceable> <optional> <literal>-</literal> <replaceable>mode</replaceable> </optional> <optional> <literal>/pad:</literal> <replaceable>padding</replaceable> </optional>
+</synopsis>
+ where <replaceable>algorithm</replaceable> is one of:
+
+ <itemizedlist>
+ <listitem><para><literal>bf</literal> &mdash; Blowfish</para></listitem>
+ <listitem><para><literal>aes</literal> &mdash; AES (Rijndael-128, -192 or -256)</para></listitem>
+ </itemizedlist>
+ and <replaceable>mode</replaceable> is one of:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>cbc</literal> &mdash; next block depends on previous (default)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ecb</literal> &mdash; each block is encrypted separately (for
+ testing only)
+ </para>
+ </listitem>
+ </itemizedlist>
+ and <replaceable>padding</replaceable> is one of:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>pkcs</literal> &mdash; data may be any length (default)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>none</literal> &mdash; data must be multiple of cipher block size
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ So, for example, these are equivalent:
+<programlisting>
+encrypt(data, 'fooz', 'bf')
+encrypt(data, 'fooz', 'bf-cbc/pad:pkcs')
+</programlisting>
+ </para>
+ <para>
+ In <function>encrypt_iv</function> and <function>decrypt_iv</function>, the
+ <parameter>iv</parameter> parameter is the initial value for the CBC mode;
+ it is ignored for ECB.
+ It is clipped or padded with zeroes if not exactly block size.
+ It defaults to all zeroes in the functions without this parameter.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Random-Data Functions</title>
+
+ <indexterm>
+ <primary>gen_random_bytes</primary>
+ </indexterm>
+
+<synopsis>
+gen_random_bytes(count integer) returns bytea
+</synopsis>
+ <para>
+ Returns <parameter>count</parameter> cryptographically strong random bytes.
+ At most 1024 bytes can be extracted at a time. This is to avoid
+ draining the randomness generator pool.
+ </para>
+
+ <indexterm>
+ <primary>gen_random_uuid</primary>
+ </indexterm>
+
+<synopsis>
+gen_random_uuid() returns uuid
+</synopsis>
+ <para>
+ Returns a version 4 (random) UUID. (Obsolete, this function
+ internally calls the <link linkend="functions-uuid">core
+ function</link> of the same name.)
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Notes</title>
+
+ <sect3>
+ <title>Configuration</title>
+
+ <para>
+ <filename>pgcrypto</filename> configures itself according to the findings of the
+ main PostgreSQL <literal>configure</literal> script. The options that
+ affect it are <literal>--with-zlib</literal> and
+ <literal>--with-ssl=openssl</literal>.
+ </para>
+
+ <para>
+ When compiled with zlib, PGP encryption functions are able to
+ compress data before encrypting.
+ </para>
+
+ <para>
+ <filename>pgcrypto</filename> requires <productname>OpenSSL</productname>.
+ Otherwise, it will not be built or installed.
+ </para>
+
+ <para>
+ When compiled against <productname>OpenSSL</productname> 3.0.0 and later
+ versions, the legacy provider must be activated in the
+ <filename>openssl.cnf</filename> configuration file in order to use older
+ ciphers like DES or Blowfish.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>NULL Handling</title>
+
+ <para>
+ As is standard in SQL, all functions return NULL, if any of the arguments
+ are NULL. This may create security risks on careless usage.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Security Limitations</title>
+
+ <para>
+ All <filename>pgcrypto</filename> functions run inside the database server.
+ That means that all
+ the data and passwords move between <filename>pgcrypto</filename> and client
+ applications in clear text. Thus you must:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>Connect locally or use SSL connections.</para>
+ </listitem>
+ <listitem>
+ <para>Trust both system and database administrator.</para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ If you cannot, then better do crypto inside client application.
+ </para>
+
+ <para>
+ The implementation does not resist
+ <ulink url="https://en.wikipedia.org/wiki/Side-channel_attack">side-channel
+ attacks</ulink>. For example, the time required for
+ a <filename>pgcrypto</filename> decryption function to complete varies among
+ ciphertexts of a given size.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Useful Reading</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="https://www.gnupg.org/gph/en/manual.html"></ulink></para>
+ <para>The GNU Privacy Handbook.</para>
+ </listitem>
+ <listitem>
+ <para><ulink url="https://www.openwall.com/crypt/"></ulink></para>
+ <para>Describes the crypt-blowfish algorithm.</para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="https://www.iusmentis.com/security/passphrasefaq/"></ulink>
+ </para>
+ <para>How to choose a good password.</para>
+ </listitem>
+ <listitem>
+ <para><ulink url="http://world.std.com/~reinhold/diceware.html"></ulink></para>
+ <para>Interesting idea for picking passwords.</para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://www.interhack.net/people/cmcurtin/snake-oil-faq.html"></ulink>
+ </para>
+ <para>Describes good and bad cryptography.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+
+ <sect3>
+ <title>Technical References</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><ulink url="https://tools.ietf.org/html/rfc4880"></ulink></para>
+ <para>OpenPGP message format.</para>
+ </listitem>
+ <listitem>
+ <para><ulink url="https://tools.ietf.org/html/rfc1321"></ulink></para>
+ <para>The MD5 Message-Digest Algorithm.</para>
+ </listitem>
+ <listitem>
+ <para><ulink url="https://tools.ietf.org/html/rfc2104"></ulink></para>
+ <para>HMAC: Keyed-Hashing for Message Authentication.</para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="https://www.usenix.org/legacy/events/usenix99/provos.html"></ulink>
+ </para>
+ <para>Comparison of crypt-des, crypt-md5 and bcrypt algorithms.</para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="https://en.wikipedia.org/wiki/Fortuna_(PRNG)"></ulink>
+ </para>
+ <para>Description of Fortuna CSPRNG.</para>
+ </listitem>
+ <listitem>
+ <para><ulink url="https://jlcooke.ca/random/"></ulink></para>
+ <para>Jean-Luc Cooke Fortuna-based <filename>/dev/random</filename> driver for Linux.</para>
+ </listitem>
+ </itemizedlist>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Marko Kreen <email>markokr@gmail.com</email>
+ </para>
+
+ <para>
+ <filename>pgcrypto</filename> uses code from the following sources:
+ </para>
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Algorithm</entry>
+ <entry>Author</entry>
+ <entry>Source origin</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>DES crypt</entry>
+ <entry>David Burren and others</entry>
+ <entry>FreeBSD libcrypt</entry>
+ </row>
+ <row>
+ <entry>MD5 crypt</entry>
+ <entry>Poul-Henning Kamp</entry>
+ <entry>FreeBSD libcrypt</entry>
+ </row>
+ <row>
+ <entry>Blowfish crypt</entry>
+ <entry>Solar Designer</entry>
+ <entry>www.openwall.com</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgfreespacemap.sgml b/doc/src/sgml/pgfreespacemap.sgml
new file mode 100644
index 0000000..4dd7a08
--- /dev/null
+++ b/doc/src/sgml/pgfreespacemap.sgml
@@ -0,0 +1,121 @@
+<!-- doc/src/sgml/pgfreespacemap.sgml -->
+
+<sect1 id="pgfreespacemap" xreflabel="pg_freespacemap">
+ <title>pg_freespacemap</title>
+
+ <indexterm zone="pgfreespacemap">
+ <primary>pg_freespacemap</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_freespacemap</filename> module provides a means for examining the
+ <link linkend="storage-fsm">free space map</link> (<acronym>FSM</acronym>).
+ It provides a function called <function>pg_freespace</function>, or two
+ overloaded functions, to be precise. The functions show the value recorded in
+ the free space map for a given page, or for all pages in the relation.
+ </para>
+
+ <para>
+ By default use is restricted to superusers and roles with privileges of the
+ <literal>pg_stat_scan_tables</literal> role. Access may be granted to others
+ using <command>GRANT</command>.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>pg_freespace(rel regclass IN, blkno bigint IN) returns int2</function>
+ <indexterm>
+ <primary>pg_freespace</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the amount of free space on the page of the relation, specified
+ by <literal>blkno</literal>, according to the <acronym>FSM</acronym>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>
+ <function>pg_freespace(rel regclass IN, blkno OUT bigint, avail OUT int2)</function>
+ </term>
+
+ <listitem>
+ <para>
+ Displays the amount of free space on each page of the relation,
+ according to the <acronym>FSM</acronym>. A set of
+ <literal>(blkno bigint, avail int2)</literal>
+ tuples is returned, one tuple for each page in the relation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The values stored in the free space map are not exact. They're rounded
+ to precision of 1/256th of <symbol>BLCKSZ</symbol> (32 bytes with default <symbol>BLCKSZ</symbol>), and
+ they're not kept fully up-to-date as tuples are inserted and updated.
+ </para>
+
+ <para>
+ For indexes, what is tracked is entirely-unused pages, rather than free
+ space within pages. Therefore, the values are not meaningful, just
+ whether a page is full or empty.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Sample Output</title>
+
+<screen>
+postgres=# SELECT * FROM pg_freespace('foo');
+ blkno | avail
+-------+-------
+ 0 | 0
+ 1 | 0
+ 2 | 0
+ 3 | 32
+ 4 | 704
+ 5 | 704
+ 6 | 704
+ 7 | 1216
+ 8 | 704
+ 9 | 704
+ 10 | 704
+ 11 | 704
+ 12 | 704
+ 13 | 704
+ 14 | 704
+ 15 | 704
+ 16 | 704
+ 17 | 704
+ 18 | 704
+ 19 | 3648
+(20 rows)
+
+postgres=# SELECT * FROM pg_freespace('foo', 7);
+ pg_freespace
+--------------
+ 1216
+(1 row)
+</screen>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Original version by Mark Kirkwood <email>markir@paradise.net.nz</email>.
+ Rewritten in version 8.4 to suit new <acronym>FSM</acronym> implementation
+ by Heikki Linnakangas <email>heikki@enterprisedb.com</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgprewarm.sgml b/doc/src/sgml/pgprewarm.sgml
new file mode 100644
index 0000000..754a21a
--- /dev/null
+++ b/doc/src/sgml/pgprewarm.sgml
@@ -0,0 +1,148 @@
+<!-- doc/src/sgml/pgprewarm.sgml -->
+
+<sect1 id="pgprewarm" xreflabel="pg_prewarm">
+ <title>pg_prewarm</title>
+
+ <indexterm zone="pgprewarm">
+ <primary>pg_prewarm</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_prewarm</filename> module provides a convenient way
+ to load relation data into either the operating system buffer cache
+ or the <productname>PostgreSQL</productname> buffer cache. Prewarming
+ can be performed manually using the <filename>pg_prewarm</filename> function,
+ or can be performed automatically by including <literal>pg_prewarm</literal> in
+ <xref linkend="guc-shared-preload-libraries"/>. In the latter case, the
+ system will run a background worker which periodically records the contents
+ of shared buffers in a file called <filename>autoprewarm.blocks</filename> and
+ will, using 2 background workers, reload those same blocks after a restart.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+<synopsis>
+pg_prewarm(regclass, mode text default 'buffer', fork text default 'main',
+ first_block int8 default null,
+ last_block int8 default null) RETURNS int8
+</synopsis>
+
+ <para>
+ The first argument is the relation to be prewarmed. The second argument
+ is the prewarming method to be used, as further discussed below; the third
+ is the relation fork to be prewarmed, usually <literal>main</literal>.
+ The fourth argument is the first block number to prewarm
+ (<literal>NULL</literal> is accepted as a synonym for zero). The fifth
+ argument is the last block number to prewarm (<literal>NULL</literal>
+ means prewarm through the last block in the relation). The return value
+ is the number of blocks prewarmed.
+ </para>
+
+ <para>
+ There are three available prewarming methods. <literal>prefetch</literal>
+ issues asynchronous prefetch requests to the operating system, if this is
+ supported, or throws an error otherwise. <literal>read</literal> reads
+ the requested range of blocks; unlike <literal>prefetch</literal>, this is
+ synchronous and supported on all platforms and builds, but may be slower.
+ <literal>buffer</literal> reads the requested range of blocks into the
+ database buffer cache.
+ </para>
+
+ <para>
+ Note that with any of these methods, attempting to prewarm more blocks than
+ can be cached &mdash; by the OS when using <literal>prefetch</literal> or
+ <literal>read</literal>, or by <productname>PostgreSQL</productname> when
+ using <literal>buffer</literal> &mdash; will likely result in lower-numbered
+ blocks being evicted as higher numbered blocks are read in. Prewarmed data
+ also enjoys no special protection from cache evictions, so it is possible
+ that other system activity may evict the newly prewarmed blocks shortly
+ after they are read; conversely, prewarming may also evict other data from
+ cache. For these reasons, prewarming is typically most useful at startup,
+ when caches are largely empty.
+ </para>
+
+<synopsis>
+autoprewarm_start_worker() RETURNS void
+</synopsis>
+
+ <para>
+ Launch the main autoprewarm worker. This will normally happen
+ automatically, but is useful if automatic prewarm was not configured at
+ server startup time and you wish to start up the worker at a later time.
+ </para>
+
+<synopsis>
+autoprewarm_dump_now() RETURNS int8
+</synopsis>
+
+ <para>
+ Update <filename>autoprewarm.blocks</filename> immediately. This may be useful
+ if the autoprewarm worker is not running but you anticipate running it
+ after the next restart. The return value is the number of records written
+ to <filename>autoprewarm.blocks</filename>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>pg_prewarm.autoprewarm</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>pg_prewarm.autoprewarm</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls whether the server should run the autoprewarm worker. This is
+ on by default. This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>pg_prewarm.autoprewarm_interval</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>pg_prewarm.autoprewarm_interval</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This is the interval between updates to <literal>autoprewarm.blocks</literal>.
+ The default is 300 seconds. If set to 0, the file will not be
+ dumped at regular intervals, but only when the server is shut down.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ These parameters must be set in <filename>postgresql.conf</filename>.
+ Typical usage might be:
+ </para>
+
+<programlisting>
+# postgresql.conf
+shared_preload_libraries = 'pg_prewarm'
+
+pg_prewarm.autoprewarm = true
+pg_prewarm.autoprewarm_interval = 300s
+
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Robert Haas <email>rhaas@postgresql.org</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgrowlocks.sgml b/doc/src/sgml/pgrowlocks.sgml
new file mode 100644
index 0000000..2914bf6
--- /dev/null
+++ b/doc/src/sgml/pgrowlocks.sgml
@@ -0,0 +1,150 @@
+<!-- doc/src/sgml/pgrowlocks.sgml -->
+
+<sect1 id="pgrowlocks" xreflabel="pgrowlocks">
+ <title>pgrowlocks</title>
+
+ <indexterm zone="pgrowlocks">
+ <primary>pgrowlocks</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pgrowlocks</filename> module provides a function to show row
+ locking information for a specified table.
+ </para>
+
+ <para>
+ By default use is restricted to superusers, roles with privileges of the
+ <literal>pg_stat_scan_tables</literal> role, and users with
+ <literal>SELECT</literal> permissions on the table.
+ </para>
+
+
+ <sect2>
+ <title>Overview</title>
+
+ <indexterm>
+ <primary>pgrowlocks</primary>
+ </indexterm>
+
+<synopsis>
+pgrowlocks(text) returns setof record
+</synopsis>
+
+ <para>
+ The parameter is the name of a table. The result is a set of records,
+ with one row for each locked row within the table. The output columns
+ are shown in <xref linkend="pgrowlocks-columns"/>.
+ </para>
+
+ <table id="pgrowlocks-columns">
+ <title><function>pgrowlocks</function> Output Columns</title>
+
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+
+ <row>
+ <entry><structfield>locked_row</structfield></entry>
+ <entry><type>tid</type></entry>
+ <entry>Tuple ID (TID) of locked row</entry>
+ </row>
+ <row>
+ <entry><structfield>locker</structfield></entry>
+ <entry><type>xid</type></entry>
+ <entry>Transaction ID of locker, or multixact ID if multitransaction</entry>
+ </row>
+ <row>
+ <entry><structfield>multi</structfield></entry>
+ <entry><type>boolean</type></entry>
+ <entry>True if locker is a multitransaction</entry>
+ </row>
+ <row>
+ <entry><structfield>xids</structfield></entry>
+ <entry><type>xid[]</type></entry>
+ <entry>Transaction IDs of lockers (more than one if multitransaction)</entry>
+ </row>
+ <row>
+ <entry><structfield>modes</structfield></entry>
+ <entry><type>text[]</type></entry>
+ <entry>Lock mode of lockers (more than one if multitransaction),
+ an array of <literal>Key Share</literal>, <literal>Share</literal>,
+ <literal>For No Key Update</literal>, <literal>No Key Update</literal>,
+ <literal>For Update</literal>, <literal>Update</literal>.</entry>
+ </row>
+
+ <row>
+ <entry><structfield>pids</structfield></entry>
+ <entry><type>integer[]</type></entry>
+ <entry>Process IDs of locking backends (more than one if multitransaction)</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <function>pgrowlocks</function> takes <literal>AccessShareLock</literal> for the
+ target table and reads each row one by one to collect the row locking
+ information. This is not very speedy for a large table. Note that:
+ </para>
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If an <literal>ACCESS EXCLUSIVE</literal> lock is taken on the table,
+ <function>pgrowlocks</function> will be blocked.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>pgrowlocks</function> is not guaranteed to produce a
+ self-consistent snapshot. It is possible that a new row lock is taken,
+ or an old lock is freed, during its execution.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ <para>
+ <function>pgrowlocks</function> does not show the contents of locked
+ rows. If you want to take a look at the row contents at the same time, you
+ could do something like this:
+
+<programlisting>
+SELECT * FROM accounts AS a, pgrowlocks('accounts') AS p
+ WHERE p.locked_row = a.ctid;
+</programlisting>
+
+ Be aware however that such a query will be very inefficient.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Sample Output</title>
+
+ <screen>
+=# SELECT * FROM pgrowlocks('t1');
+ locked_row | locker | multi | xids | modes | pids
+------------+--------+-------+-------+----------------+--------
+ (0,1) | 609 | f | {609} | {"For Share"} | {3161}
+ (0,2) | 609 | f | {609} | {"For Share"} | {3161}
+ (0,3) | 607 | f | {607} | {"For Update"} | {3107}
+ (0,4) | 607 | f | {607} | {"For Update"} | {3107}
+(4 rows)
+</screen>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Tatsuo Ishii
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml
new file mode 100644
index 0000000..ea90365
--- /dev/null
+++ b/doc/src/sgml/pgstatstatements.sgml
@@ -0,0 +1,973 @@
+<!-- doc/src/sgml/pgstatstatements.sgml -->
+
+<sect1 id="pgstatstatements" xreflabel="pg_stat_statements">
+ <title>pg_stat_statements</title>
+
+ <indexterm zone="pgstatstatements">
+ <primary>pg_stat_statements</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_stat_statements</filename> module provides a means for
+ tracking planning and execution statistics of all SQL statements executed by
+ a server.
+ </para>
+
+ <para>
+ The module must be loaded by adding <literal>pg_stat_statements</literal> to
+ <xref linkend="guc-shared-preload-libraries"/> in
+ <filename>postgresql.conf</filename>, because it requires additional shared memory.
+ This means that a server restart is needed to add or remove the module.
+ In addition, query identifier calculation must be enabled in order for the
+ module to be active, which is done automatically if <xref linkend="guc-compute-query-id"/>
+ is set to <literal>auto</literal> or <literal>on</literal>, or any third-party
+ module that calculates query identifiers is loaded.
+ </para>
+
+ <para>
+ When <filename>pg_stat_statements</filename> is active, it tracks
+ statistics across all databases of the server. To access and manipulate
+ these statistics, the module provides views
+ <structname>pg_stat_statements</structname> and
+ <structname>pg_stat_statements_info</structname>,
+ and the utility functions <function>pg_stat_statements_reset</function> and
+ <function>pg_stat_statements</function>. These are not available globally but
+ can be enabled for a specific database with
+ <command>CREATE EXTENSION pg_stat_statements</command>.
+ </para>
+
+ <sect2>
+ <title>The <structname>pg_stat_statements</structname> View</title>
+
+ <para>
+ The statistics gathered by the module are made available via a
+ view named <structname>pg_stat_statements</structname>. This view
+ contains one row for each distinct combination of database ID, user
+ ID, query ID and whether it's a top-level statement or not (up to
+ the maximum number of distinct statements that the module can track).
+ The columns of the view are shown in
+ <xref linkend="pgstatstatements-columns"/>.
+ </para>
+
+ <table id="pgstatstatements-columns">
+ <title><structname>pg_stat_statements</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>userid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of user who executed the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dbid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of database in which the statement was executed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>toplevel</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the query was executed as a top-level statement
+ (always true if <varname>pg_stat_statements.track</varname> is set to
+ <literal>top</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>queryid</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Hash code to identify identical normalized queries.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>query</structfield> <type>text</type>
+ </para>
+ <para>
+ Text of a representative statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>plans</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times the statement was planned
+ (if <varname>pg_stat_statements.track_planning</varname> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_plan_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent planning the statement, in milliseconds
+ (if <varname>pg_stat_statements.track_planning</varname> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>min_plan_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Minimum time spent planning the statement, in milliseconds
+ (if <varname>pg_stat_statements.track_planning</varname> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>max_plan_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Maximum time spent planning the statement, in milliseconds
+ (if <varname>pg_stat_statements.track_planning</varname> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mean_plan_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Mean time spent planning the statement, in milliseconds
+ (if <varname>pg_stat_statements.track_planning</varname> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stddev_plan_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Population standard deviation of time spent planning the statement,
+ in milliseconds
+ (if <varname>pg_stat_statements.track_planning</varname> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>calls</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times the statement was executed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_exec_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent executing the statement, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>min_exec_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Minimum time spent executing the statement, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>max_exec_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Maximum time spent executing the statement, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mean_exec_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Mean time spent executing the statement, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stddev_exec_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Population standard deviation of time spent executing the statement, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rows</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of rows retrieved or affected by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>shared_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of shared block cache hits by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>shared_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of shared blocks read by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>shared_blks_dirtied</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of shared blocks dirtied by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>shared_blks_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of shared blocks written by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>local_blks_hit</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of local block cache hits by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>local_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of local blocks read by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>local_blks_dirtied</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of local blocks dirtied by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>local_blks_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of local blocks written by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temp_blks_read</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of temp blocks read by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temp_blks_written</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of temp blocks written by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blk_read_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time the statement spent reading data file blocks, in milliseconds
+ (if <xref linkend="guc-track-io-timing"/> is enabled, otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>blk_write_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time the statement spent writing data file blocks, in milliseconds
+ (if <xref linkend="guc-track-io-timing"/> is enabled, otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temp_blk_read_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time the statement spent reading temporary file blocks, in
+ milliseconds (if <xref linkend="guc-track-io-timing"/> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temp_blk_write_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time the statement spent writing temporary file blocks, in
+ milliseconds (if <xref linkend="guc-track-io-timing"/> is enabled,
+ otherwise zero)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_records</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of WAL records generated by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_fpi</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of WAL full page images generated by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_bytes</structfield> <type>numeric</type>
+ </para>
+ <para>
+ Total amount of WAL generated by the statement in bytes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_functions</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of functions JIT-compiled by the statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_generation_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent by the statement on generating JIT code, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_inlining_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times functions have been inlined
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_inlining_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent by the statement on inlining functions, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_optimization_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times the statement has been optimized
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_optimization_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent by the statement on optimizing, in milliseconds
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_emission_count</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Number of times code has been emitted
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>jit_emission_time</structfield> <type>double precision</type>
+ </para>
+ <para>
+ Total time spent by the statement on emitting code, in milliseconds
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ For security reasons, only superusers and roles with privileges of the
+ <literal>pg_read_all_stats</literal> role are allowed to see the SQL text and
+ <structfield>queryid</structfield> of queries executed by other users.
+ Other users can see the statistics, however, if the view has been installed
+ in their database.
+ </para>
+
+ <para>
+ Plannable queries (that is, <command>SELECT</command>, <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, and <command>MERGE</command>) are combined into a single
+ <structname>pg_stat_statements</structname> entry whenever they have identical query
+ structures according to an internal hash calculation. Typically, two
+ queries will be considered the same for this purpose if they are
+ semantically equivalent except for the values of literal constants
+ appearing in the query. Utility commands (that is, all other commands)
+ are compared strictly on the basis of their textual query strings, however.
+ </para>
+
+ <note>
+ <para>
+ The following details about constant replacement and
+ <structfield>queryid</structfield> only apply when <xref
+ linkend="guc-compute-query-id"/> is enabled. If you use an external
+ module instead to compute <structfield>queryid</structfield>, you
+ should refer to its documentation for details.
+ </para>
+ </note>
+
+ <para>
+ When a constant's value has been ignored for purposes of matching the query
+ to other queries, the constant is replaced by a parameter symbol, such
+ as <literal>$1</literal>, in the <structname>pg_stat_statements</structname>
+ display.
+ The rest of the query text is that of the first query that had the
+ particular <structfield>queryid</structfield> hash value associated with the
+ <structname>pg_stat_statements</structname> entry.
+ </para>
+
+ <para>
+ In some cases, queries with visibly different texts might get merged into a
+ single <structname>pg_stat_statements</structname> entry. Normally this will happen
+ only for semantically equivalent queries, but there is a small chance of
+ hash collisions causing unrelated queries to be merged into one entry.
+ (This cannot happen for queries belonging to different users or databases,
+ however.)
+ </para>
+
+ <para>
+ Since the <structfield>queryid</structfield> hash value is computed on the
+ post-parse-analysis representation of the queries, the opposite is
+ also possible: queries with identical texts might appear as
+ separate entries, if they have different meanings as a result of
+ factors such as different <varname>search_path</varname> settings.
+ </para>
+
+ <para>
+ Consumers of <structname>pg_stat_statements</structname> may wish to use
+ <structfield>queryid</structfield> (perhaps in combination with
+ <structfield>dbid</structfield> and <structfield>userid</structfield>) as a more stable
+ and reliable identifier for each entry than its query text.
+ However, it is important to understand that there are only limited
+ guarantees around the stability of the <structfield>queryid</structfield> hash
+ value. Since the identifier is derived from the
+ post-parse-analysis tree, its value is a function of, among other
+ things, the internal object identifiers appearing in this representation.
+ This has some counterintuitive implications. For example,
+ <filename>pg_stat_statements</filename> will consider two apparently-identical
+ queries to be distinct, if they reference a table that was dropped
+ and recreated between the executions of the two queries.
+ The hashing process is also sensitive to differences in
+ machine architecture and other facets of the platform.
+ Furthermore, it is not safe to assume that <structfield>queryid</structfield>
+ will be stable across major versions of <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ As a rule of thumb, <structfield>queryid</structfield> values can be assumed to be
+ stable and comparable only so long as the underlying server version and
+ catalog metadata details stay exactly the same. Two servers
+ participating in replication based on physical WAL replay can be expected
+ to have identical <structfield>queryid</structfield> values for the same query.
+ However, logical replication schemes do not promise to keep replicas
+ identical in all relevant details, so <structfield>queryid</structfield> will
+ not be a useful identifier for accumulating costs across a set of logical
+ replicas. If in doubt, direct testing is recommended.
+ </para>
+
+ <para>
+ The parameter symbols used to replace constants in
+ representative query texts start from the next number after the
+ highest <literal>$</literal><replaceable>n</replaceable> parameter in the original query
+ text, or <literal>$1</literal> if there was none. It's worth noting that in
+ some cases there may be hidden parameter symbols that affect this
+ numbering. For example, <application>PL/pgSQL</application> uses hidden parameter
+ symbols to insert values of function local variables into queries, so that
+ a <application>PL/pgSQL</application> statement like <literal>SELECT i + 1 INTO j</literal>
+ would have representative text like <literal>SELECT i + $2</literal>.
+ </para>
+
+ <para>
+ The representative query texts are kept in an external disk file, and do
+ not consume shared memory. Therefore, even very lengthy query texts can
+ be stored successfully. However, if many long query texts are
+ accumulated, the external file might grow unmanageably large. As a
+ recovery method if that happens, <filename>pg_stat_statements</filename> may
+ choose to discard the query texts, whereupon all existing entries in
+ the <structname>pg_stat_statements</structname> view will show
+ null <structfield>query</structfield> fields, though the statistics associated with
+ each <structfield>queryid</structfield> are preserved. If this happens, consider
+ reducing <varname>pg_stat_statements.max</varname> to prevent
+ recurrences.
+ </para>
+
+ <para>
+ <structfield>plans</structfield> and <structfield>calls</structfield> aren't
+ always expected to match because planning and execution statistics are
+ updated at their respective end phase, and only for successful operations.
+ For example, if a statement is successfully planned but fails during
+ the execution phase, only its planning statistics will be updated.
+ If planning is skipped because a cached plan is used, only its execution
+ statistics will be updated.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>The <structname>pg_stat_statements_info</structname> View</title>
+
+ <indexterm>
+ <primary>pg_stat_statements_info</primary>
+ </indexterm>
+
+ <para>
+ The statistics of the <filename>pg_stat_statements</filename> module
+ itself are tracked and made available via a view named
+ <structname>pg_stat_statements_info</structname>. This view contains
+ only a single row. The columns of the view are shown in
+ <xref linkend="pgstatstatementsinfo-columns"/>.
+ </para>
+
+ <table id="pgstatstatementsinfo-columns">
+ <title><structname>pg_stat_statements_info</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dealloc</structfield> <type>bigint</type>
+ </para>
+ <para>
+ Total number of times <structname>pg_stat_statements</structname>
+ entries about the least-executed statements were deallocated
+ because more distinct statements than
+ <varname>pg_stat_statements.max</varname> were observed
+ </para></entry>
+ </row>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>stats_reset</structfield> <type>timestamp with time zone</type>
+ </para>
+ <para>
+ Time at which all statistics in the
+ <structname>pg_stat_statements</structname> view were last reset.
+ </para></entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>pg_stat_statements_reset(userid Oid, dbid Oid, queryid bigint) returns void</function>
+ <indexterm>
+ <primary>pg_stat_statements_reset</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pg_stat_statements_reset</function> discards statistics
+ gathered so far by <filename>pg_stat_statements</filename> corresponding
+ to the specified <structfield>userid</structfield>, <structfield>dbid</structfield>
+ and <structfield>queryid</structfield>. If any of the parameters are not
+ specified, the default value <literal>0</literal>(invalid) is used for
+ each of them and the statistics that match with other parameters will be
+ reset. If no parameter is specified or all the specified parameters are
+ <literal>0</literal>(invalid), it will discard all statistics.
+ If all statistics in the <filename>pg_stat_statements</filename>
+ view are discarded, it will also reset the statistics in the
+ <structname>pg_stat_statements_info</structname> view.
+ By default, this function can only be executed by superusers.
+ Access may be granted to others using <command>GRANT</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>pg_stat_statements(showtext boolean) returns setof record</function>
+ <indexterm>
+ <primary>pg_stat_statements</primary>
+ <secondary>function</secondary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ The <structname>pg_stat_statements</structname> view is defined in
+ terms of a function also named <function>pg_stat_statements</function>.
+ It is possible for clients to call
+ the <function>pg_stat_statements</function> function directly, and by
+ specifying <literal>showtext := false</literal> have query text be
+ omitted (that is, the <literal>OUT</literal> argument that corresponds
+ to the view's <structfield>query</structfield> column will return nulls). This
+ feature is intended to support external tools that might wish to avoid
+ the overhead of repeatedly retrieving query texts of indeterminate
+ length. Such tools can instead cache the first query text observed
+ for each entry themselves, since that is
+ all <filename>pg_stat_statements</filename> itself does, and then retrieve
+ query texts only as needed. Since the server stores query texts in a
+ file, this approach may reduce physical I/O for repeated examination
+ of the <structname>pg_stat_statements</structname> data.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>pg_stat_statements.max</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>pg_stat_statements.max</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <varname>pg_stat_statements.max</varname> is the maximum number of
+ statements tracked by the module (i.e., the maximum number of rows
+ in the <structname>pg_stat_statements</structname> view). If more distinct
+ statements than that are observed, information about the least-executed
+ statements is discarded. The number of times such information was
+ discarded can be seen in the
+ <structname>pg_stat_statements_info</structname> view.
+ The default value is 5000.
+ This parameter can only be set at server start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>pg_stat_statements.track</varname> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>pg_stat_statements.track</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <varname>pg_stat_statements.track</varname> controls which statements
+ are counted by the module.
+ Specify <literal>top</literal> to track top-level statements (those issued
+ directly by clients), <literal>all</literal> to also track nested statements
+ (such as statements invoked within functions), or <literal>none</literal> to
+ disable statement statistics collection.
+ The default value is <literal>top</literal>.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>pg_stat_statements.track_utility</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>pg_stat_statements.track_utility</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <varname>pg_stat_statements.track_utility</varname> controls whether
+ utility commands are tracked by the module. Utility commands are
+ all those other than <command>SELECT</command>, <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, and <command>MERGE</command>.
+ The default value is <literal>on</literal>.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>pg_stat_statements.track_planning</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>pg_stat_statements.track_planning</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <varname>pg_stat_statements.track_planning</varname> controls whether
+ planning operations and duration are tracked by the module.
+ Enabling this parameter may incur a noticeable performance penalty,
+ especially when statements with identical query structure are executed
+ by many concurrent connections which compete to update a small number of
+ <structname>pg_stat_statements</structname> entries.
+ The default value is <literal>off</literal>.
+ Only superusers can change this setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>pg_stat_statements.save</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>pg_stat_statements.save</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <varname>pg_stat_statements.save</varname> specifies whether to
+ save statement statistics across server shutdowns.
+ If it is <literal>off</literal> then statistics are not saved at
+ shutdown nor reloaded at server start.
+ The default value is <literal>on</literal>.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The module requires additional shared memory proportional to
+ <varname>pg_stat_statements.max</varname>. Note that this
+ memory is consumed whenever the module is loaded, even if
+ <varname>pg_stat_statements.track</varname> is set to <literal>none</literal>.
+ </para>
+
+ <para>
+ These parameters must be set in <filename>postgresql.conf</filename>.
+ Typical usage might be:
+
+<programlisting>
+# postgresql.conf
+shared_preload_libraries = 'pg_stat_statements'
+
+compute_query_id = on
+pg_stat_statements.max = 10000
+pg_stat_statements.track = all
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Sample Output</title>
+
+<screen>
+bench=# SELECT pg_stat_statements_reset();
+
+$ pgbench -i bench
+$ pgbench -c10 -t300 bench
+
+bench=# \x
+bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit /
+ nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
+ FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
+-[ RECORD 1 ]---+--------------------------------------------------&zwsp;------------------
+query | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2
+calls | 3000
+total_exec_time | 25565.855387
+rows | 3000
+hit_percent | 100.0000000000000000
+-[ RECORD 2 ]---+--------------------------------------------------&zwsp;------------------
+query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2
+calls | 3000
+total_exec_time | 20756.669379
+rows | 3000
+hit_percent | 100.0000000000000000
+-[ RECORD 3 ]---+--------------------------------------------------&zwsp;------------------
+query | copy pgbench_accounts from stdin
+calls | 1
+total_exec_time | 291.865911
+rows | 100000
+hit_percent | 100.0000000000000000
+-[ RECORD 4 ]---+--------------------------------------------------&zwsp;------------------
+query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2
+calls | 3000
+total_exec_time | 271.232977
+rows | 3000
+hit_percent | 98.8454011741682975
+-[ RECORD 5 ]---+--------------------------------------------------&zwsp;------------------
+query | alter table pgbench_accounts add primary key (aid)
+calls | 1
+total_exec_time | 160.588563
+rows | 0
+hit_percent | 100.0000000000000000
+
+
+bench=# SELECT pg_stat_statements_reset(0,0,s.queryid) FROM pg_stat_statements AS s
+ WHERE s.query = 'UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2';
+
+bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit /
+ nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
+ FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
+-[ RECORD 1 ]---+--------------------------------------------------&zwsp;------------------
+query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2
+calls | 3000
+total_exec_time | 20756.669379
+rows | 3000
+hit_percent | 100.0000000000000000
+-[ RECORD 2 ]---+--------------------------------------------------&zwsp;------------------
+query | copy pgbench_accounts from stdin
+calls | 1
+total_exec_time | 291.865911
+rows | 100000
+hit_percent | 100.0000000000000000
+-[ RECORD 3 ]---+--------------------------------------------------&zwsp;------------------
+query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2
+calls | 3000
+total_exec_time | 271.232977
+rows | 3000
+hit_percent | 98.8454011741682975
+-[ RECORD 4 ]---+--------------------------------------------------&zwsp;------------------
+query | alter table pgbench_accounts add primary key (aid)
+calls | 1
+total_exec_time | 160.588563
+rows | 0
+hit_percent | 100.0000000000000000
+-[ RECORD 5 ]---+--------------------------------------------------&zwsp;------------------
+query | vacuum analyze pgbench_accounts
+calls | 1
+total_exec_time | 136.448116
+rows | 0
+hit_percent | 99.9201915403032721
+
+bench=# SELECT pg_stat_statements_reset(0,0,0);
+
+bench=# SELECT query, calls, total_exec_time, rows, 100.0 * shared_blks_hit /
+ nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
+ FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 5;
+-[ RECORD 1 ]---+--------------------------------------------------&zwsp;---------------------------
+query | SELECT pg_stat_statements_reset(0,0,0)
+calls | 1
+total_exec_time | 0.189497
+rows | 1
+hit_percent |
+-[ RECORD 2 ]---+--------------------------------------------------&zwsp;---------------------------
+query | SELECT query, calls, total_exec_time, rows, $1 * shared_blks_hit / +
+ | nullif(shared_blks_hit + shared_blks_read, $2) AS hit_percent+
+ | FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT $3
+calls | 0
+total_exec_time | 0
+rows | 0
+hit_percent |
+
+</screen>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Takahiro Itagaki <email>itagaki.takahiro@oss.ntt.co.jp</email>.
+ Query normalization added by Peter Geoghegan <email>peter@2ndquadrant.com</email>.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgstattuple.sgml b/doc/src/sgml/pgstattuple.sgml
new file mode 100644
index 0000000..b17b3c5
--- /dev/null
+++ b/doc/src/sgml/pgstattuple.sgml
@@ -0,0 +1,629 @@
+<!-- doc/src/sgml/pgstattuple.sgml -->
+
+<sect1 id="pgstattuple" xreflabel="pgstattuple">
+ <title>pgstattuple</title>
+
+ <indexterm zone="pgstattuple">
+ <primary>pgstattuple</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pgstattuple</filename> module provides various functions to
+ obtain tuple-level statistics.
+ </para>
+
+ <para>
+ Because these functions return detailed page-level information, access is
+ restricted by default. By default, only the
+ role <literal>pg_stat_scan_tables</literal> has <literal>EXECUTE</literal>
+ privilege. Superusers of course bypass this restriction. After the
+ extension has been installed, users may issue <command>GRANT</command>
+ commands to change the privileges on the functions to allow others to
+ execute them. However, it might be preferable to add those users to
+ the <literal>pg_stat_scan_tables</literal> role instead.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>pgstattuple</primary>
+ </indexterm>
+ <function>pgstattuple(regclass) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pgstattuple</function> returns a relation's physical length,
+ percentage of <quote>dead</quote> tuples, and other info. This may help users
+ to determine whether vacuum is necessary or not. The argument is the
+ target relation's name (optionally schema-qualified) or OID.
+ For example:
+<programlisting>
+test=&gt; SELECT * FROM pgstattuple('pg_catalog.pg_proc');
+-[ RECORD 1 ]------+-------
+table_len | 458752
+tuple_count | 1470
+tuple_len | 438896
+tuple_percent | 95.67
+dead_tuple_count | 11
+dead_tuple_len | 3157
+dead_tuple_percent | 0.69
+free_space | 8932
+free_percent | 1.95
+</programlisting>
+ The output columns are described in <xref linkend="pgstattuple-columns"/>.
+ </para>
+
+ <table id="pgstattuple-columns">
+ <title><function>pgstattuple</function> Output Columns</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>table_len</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Physical relation length in bytes</entry>
+ </row>
+ <row>
+ <entry><structfield>tuple_count</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of live tuples</entry>
+ </row>
+ <row>
+ <entry><structfield>tuple_len</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total length of live tuples in bytes</entry>
+ </row>
+ <row>
+ <entry><structfield>tuple_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of live tuples</entry>
+ </row>
+ <row>
+ <entry><structfield>dead_tuple_count</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of dead tuples</entry>
+ </row>
+ <row>
+ <entry><structfield>dead_tuple_len</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total length of dead tuples in bytes</entry>
+ </row>
+ <row>
+ <entry><structfield>dead_tuple_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of dead tuples</entry>
+ </row>
+ <row>
+ <entry><structfield>free_space</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total free space in bytes</entry>
+ </row>
+ <row>
+ <entry><structfield>free_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of free space</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The <literal>table_len</literal> will always be greater than the sum
+ of the <literal>tuple_len</literal>, <literal>dead_tuple_len</literal>
+ and <literal>free_space</literal>. The difference is accounted for by
+ fixed page overhead, the per-page table of pointers to tuples, and
+ padding to ensure that tuples are correctly aligned.
+ </para>
+ </note>
+
+ <para>
+ <function>pgstattuple</function> acquires only a read lock on the
+ relation. So the results do not reflect an instantaneous snapshot;
+ concurrent updates will affect them.
+ </para>
+
+ <para>
+ <function>pgstattuple</function> judges a tuple is <quote>dead</quote> if
+ <function>HeapTupleSatisfiesDirty</function> returns false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>pgstattuple(text) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ This is the same as <function>pgstattuple(regclass)</function>, except
+ that the target relation is specified as TEXT. This function is kept
+ because of backward-compatibility so far, and will be deprecated in
+ some future release.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>pgstatindex</primary>
+ </indexterm>
+ <function>pgstatindex(regclass) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pgstatindex</function> returns a record showing information
+ about a B-tree index. For example:
+<programlisting>
+test=&gt; SELECT * FROM pgstatindex('pg_cast_oid_index');
+-[ RECORD 1 ]------+------
+version | 2
+tree_level | 0
+index_size | 16384
+root_block_no | 1
+internal_pages | 0
+leaf_pages | 1
+empty_pages | 0
+deleted_pages | 0
+avg_leaf_density | 54.27
+leaf_fragmentation | 0
+</programlisting>
+ </para>
+
+ <para>
+ The output columns are:
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>version</structfield></entry>
+ <entry><type>integer</type></entry>
+ <entry>B-tree version number</entry>
+ </row>
+
+ <row>
+ <entry><structfield>tree_level</structfield></entry>
+ <entry><type>integer</type></entry>
+ <entry>Tree level of the root page</entry>
+ </row>
+
+ <row>
+ <entry><structfield>index_size</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total index size in bytes</entry>
+ </row>
+
+ <row>
+ <entry><structfield>root_block_no</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Location of root page (zero if none)</entry>
+ </row>
+
+ <row>
+ <entry><structfield>internal_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of <quote>internal</quote> (upper-level) pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>leaf_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of leaf pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>empty_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of empty pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>deleted_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of deleted pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>avg_leaf_density</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Average density of leaf pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>leaf_fragmentation</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Leaf page fragmentation</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+
+ <para>
+ The reported <literal>index_size</literal> will normally correspond to one more
+ page than is accounted for by <literal>internal_pages + leaf_pages +
+ empty_pages + deleted_pages</literal>, because it also includes the
+ index's metapage.
+ </para>
+
+ <para>
+ As with <function>pgstattuple</function>, the results are accumulated
+ page-by-page, and should not be expected to represent an
+ instantaneous snapshot of the whole index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>pgstatindex(text) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ This is the same as <function>pgstatindex(regclass)</function>, except
+ that the target index is specified as TEXT. This function is kept
+ because of backward-compatibility so far, and will be deprecated in
+ some future release.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>pgstatginindex</primary>
+ </indexterm>
+ <function>pgstatginindex(regclass) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pgstatginindex</function> returns a record showing information
+ about a GIN index. For example:
+<programlisting>
+test=&gt; SELECT * FROM pgstatginindex('test_gin_index');
+-[ RECORD 1 ]--+--
+version | 1
+pending_pages | 0
+pending_tuples | 0
+</programlisting>
+ </para>
+
+ <para>
+ The output columns are:
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>version</structfield></entry>
+ <entry><type>integer</type></entry>
+ <entry>GIN version number</entry>
+ </row>
+
+ <row>
+ <entry><structfield>pending_pages</structfield></entry>
+ <entry><type>integer</type></entry>
+ <entry>Number of pages in the pending list</entry>
+ </row>
+
+ <row>
+ <entry><structfield>pending_tuples</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of tuples in the pending list</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>pgstathashindex</primary>
+ </indexterm>
+ <function>pgstathashindex(regclass) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pgstathashindex</function> returns a record showing information
+ about a HASH index. For example:
+<programlisting>
+test=&gt; select * from pgstathashindex('con_hash_index');
+-[ RECORD 1 ]--+-----------------
+version | 4
+bucket_pages | 33081
+overflow_pages | 0
+bitmap_pages | 1
+unused_pages | 32455
+live_items | 10204006
+dead_items | 0
+free_percent | 61.8005949100872
+</programlisting>
+ </para>
+
+ <para>
+ The output columns are:
+
+ <informaltable>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>version</structfield></entry>
+ <entry><type>integer</type></entry>
+ <entry>HASH version number</entry>
+ </row>
+
+ <row>
+ <entry><structfield>bucket_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of bucket pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>overflow_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of overflow pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>bitmap_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of bitmap pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>unused_pages</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of unused pages</entry>
+ </row>
+
+ <row>
+ <entry><structfield>live_items</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of live tuples</entry>
+ </row>
+
+ <row>
+ <entry><structfield>dead_tuples</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of dead tuples</entry>
+ </row>
+
+ <row>
+ <entry><structfield>free_percent</structfield></entry>
+ <entry><type>float</type></entry>
+ <entry>Percentage of free space</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>pg_relpages</primary>
+ </indexterm>
+ <function>pg_relpages(regclass) returns bigint</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pg_relpages</function> returns the number of pages in the
+ relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>pg_relpages(text) returns bigint</function>
+ </term>
+
+ <listitem>
+ <para>
+ This is the same as <function>pg_relpages(regclass)</function>, except
+ that the target relation is specified as TEXT. This function is kept
+ because of backward-compatibility so far, and will be deprecated in
+ some future release.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>pgstattuple_approx</primary>
+ </indexterm>
+ <function>pgstattuple_approx(regclass) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>pgstattuple_approx</function> is a faster alternative to
+ <function>pgstattuple</function> that returns approximate results.
+ The argument is the target relation's name or OID.
+ For example:
+<programlisting>
+test=&gt; SELECT * FROM pgstattuple_approx('pg_catalog.pg_proc'::regclass);
+-[ RECORD 1 ]--------+-------
+table_len | 573440
+scanned_percent | 2
+approx_tuple_count | 2740
+approx_tuple_len | 561210
+approx_tuple_percent | 97.87
+dead_tuple_count | 0
+dead_tuple_len | 0
+dead_tuple_percent | 0
+approx_free_space | 11996
+approx_free_percent | 2.09
+</programlisting>
+ The output columns are described in <xref linkend="pgstatapprox-columns"/>.
+ </para>
+
+ <para>
+ Whereas <function>pgstattuple</function> always performs a
+ full-table scan and returns an exact count of live and dead tuples
+ (and their sizes) and free space, <function>pgstattuple_approx</function>
+ tries to avoid the full-table scan and returns exact dead tuple
+ statistics along with an approximation of the number and
+ size of live tuples and free space.
+ </para>
+
+ <para>
+ It does this by skipping pages that have only visible tuples
+ according to the visibility map (if a page has the corresponding VM
+ bit set, then it is assumed to contain no dead tuples). For such
+ pages, it derives the free space value from the free space map, and
+ assumes that the rest of the space on the page is taken up by live
+ tuples.
+ </para>
+
+ <para>
+ For pages that cannot be skipped, it scans each tuple, recording its
+ presence and size in the appropriate counters, and adding up the
+ free space on the page. At the end, it estimates the total number of
+ live tuples based on the number of pages and tuples scanned (in the
+ same way that VACUUM estimates pg_class.reltuples).
+ </para>
+
+ <table id="pgstatapprox-columns">
+ <title><function>pgstattuple_approx</function> Output Columns</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>table_len</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Physical relation length in bytes (exact)</entry>
+ </row>
+ <row>
+ <entry><structfield>scanned_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of table scanned</entry>
+ </row>
+ <row>
+ <entry><structfield>approx_tuple_count</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of live tuples (estimated)</entry>
+ </row>
+ <row>
+ <entry><structfield>approx_tuple_len</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total length of live tuples in bytes (estimated)</entry>
+ </row>
+ <row>
+ <entry><structfield>approx_tuple_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of live tuples</entry>
+ </row>
+ <row>
+ <entry><structfield>dead_tuple_count</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Number of dead tuples (exact)</entry>
+ </row>
+ <row>
+ <entry><structfield>dead_tuple_len</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total length of dead tuples in bytes (exact)</entry>
+ </row>
+ <row>
+ <entry><structfield>dead_tuple_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of dead tuples</entry>
+ </row>
+ <row>
+ <entry><structfield>approx_free_space</structfield></entry>
+ <entry><type>bigint</type></entry>
+ <entry>Total free space in bytes (estimated)</entry>
+ </row>
+ <row>
+ <entry><structfield>approx_free_percent</structfield></entry>
+ <entry><type>float8</type></entry>
+ <entry>Percentage of free space</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In the above output, the free space figures may not match the
+ <function>pgstattuple</function> output exactly, because the free
+ space map gives us an exact figure, but is not guaranteed to be
+ accurate to the byte.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Tatsuo Ishii, Satoshi Nagayasu and Abhijit Menon-Sen
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgsurgery.sgml b/doc/src/sgml/pgsurgery.sgml
new file mode 100644
index 0000000..4bba14f
--- /dev/null
+++ b/doc/src/sgml/pgsurgery.sgml
@@ -0,0 +1,107 @@
+<!-- doc/src/sgml/pgsurgery.sgml -->
+
+<sect1 id="pgsurgery" xreflabel="pg_surgery">
+ <title>pg_surgery</title>
+
+ <indexterm zone="pgsurgery">
+ <primary>pg_surgery</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_surgery</filename> module provides various functions to
+ perform surgery on a damaged relation. These functions are unsafe by design
+ and using them may corrupt (or further corrupt) your database. For example,
+ these functions can easily be used to make a table inconsistent with its
+ own indexes, to cause <literal>UNIQUE</literal> or
+ <literal>FOREIGN KEY</literal> constraint violations, or even to make
+ tuples visible which, when read, will cause a database server crash.
+ They should be used with great caution and only as a last resort.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>heap_force_kill(regclass, tid[]) returns void</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>heap_force_kill</function> marks <quote>used</quote> line
+ pointers as <quote>dead</quote> without examining the tuples. The
+ intended use of this function is to forcibly remove tuples that are not
+ otherwise accessible. For example:
+<programlisting>
+test=&gt; select * from t1 where ctid = '(0, 1)';
+ERROR: could not access status of transaction 4007513275
+DETAIL: Could not open file "pg_xact/0EED": No such file or directory.
+
+test=# select heap_force_kill('t1'::regclass, ARRAY['(0, 1)']::tid[]);
+ heap_force_kill
+-----------------
+
+(1 row)
+
+test=# select * from t1 where ctid = '(0, 1)';
+(0 rows)
+
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>heap_force_freeze(regclass, tid[]) returns void</function>
+ </term>
+
+ <listitem>
+ <para>
+ <function>heap_force_freeze</function> marks tuples as frozen without
+ examining the tuple data. The intended use of this function is to
+ make accessible tuples which are inaccessible due to corrupted
+ visibility information, or which prevent the table from being
+ successfully vacuumed due to corrupted visibility information.
+ For example:
+<programlisting>
+test=&gt; vacuum t1;
+ERROR: found xmin 507 from before relfrozenxid 515
+CONTEXT: while scanning block 0 of relation "public.t1"
+
+test=# select ctid from t1 where xmin = 507;
+ ctid
+-------
+ (0,3)
+(1 row)
+
+test=# select heap_force_freeze('t1'::regclass, ARRAY['(0, 3)']::tid[]);
+ heap_force_freeze
+-------------------
+
+(1 row)
+
+test=# select ctid from t1 where xmin = 2;
+ ctid
+-------
+ (0,3)
+(1 row)
+
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Ashutosh Sharma <email>ashu.coek88@gmail.com</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgtrgm.sgml b/doc/src/sgml/pgtrgm.sgml
new file mode 100644
index 0000000..7e29282
--- /dev/null
+++ b/doc/src/sgml/pgtrgm.sgml
@@ -0,0 +1,642 @@
+<!-- doc/src/sgml/pgtrgm.sgml -->
+
+<sect1 id="pgtrgm" xreflabel="pg_trgm">
+ <title>pg_trgm</title>
+
+ <indexterm zone="pgtrgm">
+ <primary>pg_trgm</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_trgm</filename> module provides functions and operators
+ for determining the similarity of
+ alphanumeric text based on trigram matching, as
+ well as index operator classes that support fast searching for similar
+ strings.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Trigram (or Trigraph) Concepts</title>
+
+ <para>
+ A trigram is a group of three consecutive characters taken
+ from a string. We can measure the similarity of two strings by
+ counting the number of trigrams they share. This simple idea
+ turns out to be very effective for measuring the similarity of
+ words in many natural languages.
+ </para>
+
+ <note>
+ <para>
+ <filename>pg_trgm</filename> ignores non-word characters
+ (non-alphanumerics) when extracting trigrams from a string.
+ Each word is considered to have two spaces
+ prefixed and one space suffixed when determining the set
+ of trigrams contained in the string.
+ For example, the set of trigrams in the string
+ <quote><literal>cat</literal></quote> is
+ <quote><literal> c</literal></quote>,
+ <quote><literal> ca</literal></quote>,
+ <quote><literal>cat</literal></quote>, and
+ <quote><literal>at </literal></quote>.
+ The set of trigrams in the string
+ <quote><literal>foo|bar</literal></quote> is
+ <quote><literal> f</literal></quote>,
+ <quote><literal> fo</literal></quote>,
+ <quote><literal>foo</literal></quote>,
+ <quote><literal>oo </literal></quote>,
+ <quote><literal> b</literal></quote>,
+ <quote><literal> ba</literal></quote>,
+ <quote><literal>bar</literal></quote>, and
+ <quote><literal>ar </literal></quote>.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Functions and Operators</title>
+
+ <para>
+ The functions provided by the <filename>pg_trgm</filename> module
+ are shown in <xref linkend="pgtrgm-func-table"/>, the operators
+ in <xref linkend="pgtrgm-op-table"/>.
+ </para>
+
+ <table id="pgtrgm-func-table">
+ <title><filename>pg_trgm</filename> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>similarity</primary></indexterm>
+ <function>similarity</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Returns a number that indicates how similar the two arguments are.
+ The range of the result is zero (indicating that the two strings are
+ completely dissimilar) to one (indicating that the two strings are
+ identical).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>show_trgm</primary></indexterm>
+ <function>show_trgm</function> ( <type>text</type> )
+ <returnvalue>text[]</returnvalue>
+ </para>
+ <para>
+ Returns an array of all the trigrams in the given string.
+ (In practice this is seldom useful except for debugging.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>word_similarity</primary></indexterm>
+ <function>word_similarity</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Returns a number that indicates the greatest similarity between
+ the set of trigrams in the first string and any continuous extent
+ of an ordered set of trigrams in the second string. For details, see
+ the explanation below.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>strict_word_similarity</primary></indexterm>
+ <function>strict_word_similarity</function> ( <type>text</type>, <type>text</type> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Same as <function>word_similarity</function>, but forces
+ extent boundaries to match word boundaries. Since we don't have
+ cross-word trigrams, this function actually returns greatest similarity
+ between first string and any continuous extent of words of the second
+ string.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>show_limit</primary></indexterm>
+ <function>show_limit</function> ()
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Returns the current similarity threshold used by the <literal>%</literal>
+ operator. This sets the minimum similarity between
+ two words for them to be considered similar enough to
+ be misspellings of each other, for example.
+ (<emphasis>Deprecated</emphasis>; instead use <command>SHOW</command>
+ <varname>pg_trgm.similarity_threshold</varname>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>set_limit</primary></indexterm>
+ <function>set_limit</function> ( <type>real</type> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Sets the current similarity threshold that is used by the <literal>%</literal>
+ operator. The threshold must be between 0 and 1 (default is 0.3).
+ Returns the same value passed in.
+ (<emphasis>Deprecated</emphasis>; instead use <command>SET</command>
+ <varname>pg_trgm.similarity_threshold</varname>.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Consider the following example:
+
+<programlisting>
+# SELECT word_similarity('word', 'two words');
+ word_similarity
+-----------------
+ 0.8
+(1 row)
+</programlisting>
+
+ In the first string, the set of trigrams is
+ <literal>{" w"," wo","wor","ord","rd "}</literal>.
+ In the second string, the ordered set of trigrams is
+ <literal>{" t"," tw","two","wo "," w"," wo","wor","ord","rds","ds "}</literal>.
+ The most similar extent of an ordered set of trigrams in the second string
+ is <literal>{" w"," wo","wor","ord"}</literal>, and the similarity is
+ <literal>0.8</literal>.
+ </para>
+
+ <para>
+ This function returns a value that can be approximately understood as the
+ greatest similarity between the first string and any substring of the second
+ string. However, this function does not add padding to the boundaries of
+ the extent. Thus, the number of additional characters present in the
+ second string is not considered, except for the mismatched word boundaries.
+ </para>
+
+ <para>
+ At the same time, <function>strict_word_similarity</function>
+ selects an extent of words in the second string. In the example above,
+ <function>strict_word_similarity</function> would select the
+ extent of a single word <literal>'words'</literal>, whose set of trigrams is
+ <literal>{" w"," wo","wor","ord","rds","ds "}</literal>.
+
+<programlisting>
+# SELECT strict_word_similarity('word', 'two words'), similarity('word', 'words');
+ strict_word_similarity | similarity
+------------------------+------------
+ 0.571429 | 0.571429
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Thus, the <function>strict_word_similarity</function> function
+ is useful for finding the similarity to whole words, while
+ <function>word_similarity</function> is more suitable for
+ finding the similarity for parts of words.
+ </para>
+
+ <table id="pgtrgm-op-table">
+ <title><filename>pg_trgm</filename> Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>%</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns <literal>true</literal> if its arguments have a similarity
+ that is greater than the current similarity threshold set by
+ <varname>pg_trgm.similarity_threshold</varname>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;%</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns <literal>true</literal> if the similarity between the trigram
+ set in the first argument and a continuous extent of an ordered trigram
+ set in the second argument is greater than the current word similarity
+ threshold set by <varname>pg_trgm.word_similarity_threshold</varname>
+ parameter.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>%&gt;</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Commutator of the <literal>&lt;%</literal> operator.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;&lt;%</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Returns <literal>true</literal> if its second argument has a continuous
+ extent of an ordered trigram set that matches word boundaries,
+ and its similarity to the trigram set of the first argument is greater
+ than the current strict word similarity threshold set by the
+ <varname>pg_trgm.strict_word_similarity_threshold</varname> parameter.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>%&gt;&gt;</literal> <type>text</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Commutator of the <literal>&lt;&lt;%</literal> operator.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;-&gt;</literal> <type>text</type>
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Returns the <quote>distance</quote> between the arguments, that is
+ one minus the <function>similarity()</function> value.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;&lt;-&gt;</literal> <type>text</type>
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Returns the <quote>distance</quote> between the arguments, that is
+ one minus the <function>word_similarity()</function> value.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;-&gt;&gt;</literal> <type>text</type>
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Commutator of the <literal>&lt;&lt;-&gt;</literal> operator.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;&lt;&lt;-&gt;</literal> <type>text</type>
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Returns the <quote>distance</quote> between the arguments, that is
+ one minus the <function>strict_word_similarity()</function> value.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>text</type> <literal>&lt;-&gt;&gt;&gt;</literal> <type>text</type>
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Commutator of the <literal>&lt;&lt;&lt;-&gt;</literal> operator.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>GUC Parameters</title>
+
+ <variablelist>
+ <varlistentry id="guc-pgtrgm-similarity-threshold" xreflabel="pg_trgm.similarity_threshold">
+ <term>
+ <varname>pg_trgm.similarity_threshold</varname> (<type>real</type>)
+ <indexterm>
+ <primary><varname>pg_trgm.similarity_threshold</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the current similarity threshold that is used by the <literal>%</literal>
+ operator. The threshold must be between 0 and 1 (default is 0.3).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry id="guc-pgtrgm-word-similarity-threshold" xreflabel="pg_trgm.word_similarity_threshold">
+ <term>
+ <varname>pg_trgm.word_similarity_threshold</varname> (<type>real</type>)
+ <indexterm>
+ <primary><varname>pg_trgm.word_similarity_threshold</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the current word similarity threshold that is used by the
+ <literal>&lt;%</literal> and <literal>%&gt;</literal> operators. The threshold
+ must be between 0 and 1 (default is 0.6).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry id="guc-pgtrgm-strict-word-similarity-threshold" xreflabel="pg_trgm.strict_word_similarity_threshold">
+ <term>
+ <varname>pg_trgm.strict_word_similarity_threshold</varname> (<type>real</type>)
+ <indexterm>
+ <primary><varname>pg_trgm.strict_word_similarity_threshold</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the current strict word similarity threshold that is used by the
+ <literal>&lt;&lt;%</literal> and <literal>%&gt;&gt;</literal> operators. The threshold
+ must be between 0 and 1 (default is 0.5).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Index Support</title>
+
+ <para>
+ The <filename>pg_trgm</filename> module provides GiST and GIN index
+ operator classes that allow you to create an index over a text column for
+ the purpose of very fast similarity searches. These index types support
+ the above-described similarity operators, and additionally support
+ trigram-based index searches for <literal>LIKE</literal>, <literal>ILIKE</literal>,
+ <literal>~</literal>, <literal>~*</literal> and <literal>=</literal> queries.
+ Inequality operators are not supported.
+ Note that those indexes may not be as efficient as regular B-tree indexes
+ for equality operator.
+ </para>
+
+ <para>
+ Example:
+
+<programlisting>
+CREATE TABLE test_trgm (t text);
+CREATE INDEX trgm_idx ON test_trgm USING GIST (t gist_trgm_ops);
+</programlisting>
+or
+<programlisting>
+CREATE INDEX trgm_idx ON test_trgm USING GIN (t gin_trgm_ops);
+</programlisting>
+ </para>
+
+ <para>
+ <literal>gist_trgm_ops</literal> GiST opclass approximates a set of
+ trigrams as a bitmap signature. Its optional integer parameter
+ <literal>siglen</literal> determines the
+ signature length in bytes. The default length is 12 bytes.
+ Valid values of signature length are between 1 and 2024 bytes. Longer
+ signatures lead to a more precise search (scanning a smaller fraction of the index and
+ fewer heap pages), at the cost of a larger index.
+ </para>
+
+ <para>
+ Example of creating such an index with a signature length of 32 bytes:
+ </para>
+<programlisting>
+CREATE INDEX trgm_idx ON test_trgm USING GIST (t gist_trgm_ops(siglen=32));
+</programlisting>
+
+ <para>
+ At this point, you will have an index on the <structfield>t</structfield> column that
+ you can use for similarity searching. A typical query is
+<programlisting>
+SELECT t, similarity(t, '<replaceable>word</replaceable>') AS sml
+ FROM test_trgm
+ WHERE t % '<replaceable>word</replaceable>'
+ ORDER BY sml DESC, t;
+</programlisting>
+ This will return all values in the text column that are sufficiently
+ similar to <replaceable>word</replaceable>, sorted from best match to worst. The
+ index will be used to make this a fast operation even over very large data
+ sets.
+ </para>
+
+ <para>
+ A variant of the above query is
+<programlisting>
+SELECT t, t &lt;-&gt; '<replaceable>word</replaceable>' AS dist
+ FROM test_trgm
+ ORDER BY dist LIMIT 10;
+</programlisting>
+ This can be implemented quite efficiently by GiST indexes, but not
+ by GIN indexes. It will usually beat the first formulation when only
+ a small number of the closest matches is wanted.
+ </para>
+
+ <para>
+ Also you can use an index on the <structfield>t</structfield> column for word
+ similarity or strict word similarity. Typical queries are:
+<programlisting>
+SELECT t, word_similarity('<replaceable>word</replaceable>', t) AS sml
+ FROM test_trgm
+ WHERE '<replaceable>word</replaceable>' &lt;% t
+ ORDER BY sml DESC, t;
+</programlisting>
+ and
+<programlisting>
+SELECT t, strict_word_similarity('<replaceable>word</replaceable>', t) AS sml
+ FROM test_trgm
+ WHERE '<replaceable>word</replaceable>' &lt;&lt;% t
+ ORDER BY sml DESC, t;
+</programlisting>
+ This will return all values in the text column for which there is a
+ continuous extent in the corresponding ordered trigram set that is
+ sufficiently similar to the trigram set of <replaceable>word</replaceable>,
+ sorted from best match to worst. The index will be used to make this
+ a fast operation even over very large data sets.
+ </para>
+
+ <para>
+ Possible variants of the above queries are:
+<programlisting>
+SELECT t, '<replaceable>word</replaceable>' &lt;&lt;-&gt; t AS dist
+ FROM test_trgm
+ ORDER BY dist LIMIT 10;
+</programlisting>
+ and
+<programlisting>
+SELECT t, '<replaceable>word</replaceable>' &lt;&lt;&lt;-&gt; t AS dist
+ FROM test_trgm
+ ORDER BY dist LIMIT 10;
+</programlisting>
+ This can be implemented quite efficiently by GiST indexes, but not
+ by GIN indexes.
+ </para>
+
+
+ <para>
+ Beginning in <productname>PostgreSQL</productname> 9.1, these index types also support
+ index searches for <literal>LIKE</literal> and <literal>ILIKE</literal>, for example
+<programlisting>
+SELECT * FROM test_trgm WHERE t LIKE '%foo%bar';
+</programlisting>
+ The index search works by extracting trigrams from the search string
+ and then looking these up in the index. The more trigrams in the search
+ string, the more effective the index search is. Unlike B-tree based
+ searches, the search string need not be left-anchored.
+ </para>
+
+ <para>
+ Beginning in <productname>PostgreSQL</productname> 9.3, these index types also support
+ index searches for regular-expression matches
+ (<literal>~</literal> and <literal>~*</literal> operators), for example
+<programlisting>
+SELECT * FROM test_trgm WHERE t ~ '(foo|bar)';
+</programlisting>
+ The index search works by extracting trigrams from the regular expression
+ and then looking these up in the index. The more trigrams that can be
+ extracted from the regular expression, the more effective the index search
+ is. Unlike B-tree based searches, the search string need not be
+ left-anchored.
+ </para>
+
+ <para>
+ For both <literal>LIKE</literal> and regular-expression searches, keep in mind
+ that a pattern with no extractable trigrams will degenerate to a full-index
+ scan.
+ </para>
+
+ <para>
+ The choice between GiST and GIN indexing depends on the relative
+ performance characteristics of GiST and GIN, which are discussed elsewhere.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Text Search Integration</title>
+
+ <para>
+ Trigram matching is a very useful tool when used in conjunction
+ with a full text index. In particular it can help to recognize
+ misspelled input words that will not be matched directly by the
+ full text search mechanism.
+ </para>
+
+ <para>
+ The first step is to generate an auxiliary table containing all
+ the unique words in the documents:
+
+<programlisting>
+CREATE TABLE words AS SELECT word FROM
+ ts_stat('SELECT to_tsvector(''simple'', bodytext) FROM documents');
+</programlisting>
+
+ where <structname>documents</structname> is a table that has a text field
+ <structfield>bodytext</structfield> that we wish to search. The reason for using
+ the <literal>simple</literal> configuration with the <function>to_tsvector</function>
+ function, instead of using a language-specific configuration,
+ is that we want a list of the original (unstemmed) words.
+ </para>
+
+ <para>
+ Next, create a trigram index on the word column:
+
+<programlisting>
+CREATE INDEX words_idx ON words USING GIN (word gin_trgm_ops);
+</programlisting>
+
+ Now, a <command>SELECT</command> query similar to the previous example can
+ be used to suggest spellings for misspelled words in user search terms.
+ A useful extra test is to require that the selected words are also of
+ similar length to the misspelled word.
+ </para>
+
+ <note>
+ <para>
+ Since the <structname>words</structname> table has been generated as a separate,
+ static table, it will need to be periodically regenerated so that
+ it remains reasonably up-to-date with the document collection.
+ Keeping it exactly current is usually unnecessary.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>References</title>
+
+ <para>
+ GiST Development Site
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/"></ulink>
+ </para>
+ <para>
+ Tsearch2 Development Site
+ <ulink url="http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/"></ulink>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Authors</title>
+
+ <para>
+ Oleg Bartunov <email>oleg@sai.msu.su</email>, Moscow, Moscow University, Russia
+ </para>
+ <para>
+ Teodor Sigaev <email>teodor@sigaev.ru</email>, Moscow, Delta-Soft Ltd.,Russia
+ </para>
+ <para>
+ Alexander Korotkov <email>a.korotkov@postgrespro.ru</email>, Moscow, Postgres Professional, Russia
+ </para>
+ <para>
+ Documentation: Christopher Kings-Lynne
+ </para>
+ <para>
+ This module is sponsored by Delta-Soft Ltd., Moscow, Russia.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgvisibility.sgml b/doc/src/sgml/pgvisibility.sgml
new file mode 100644
index 0000000..8090aa5
--- /dev/null
+++ b/doc/src/sgml/pgvisibility.sgml
@@ -0,0 +1,158 @@
+<!-- doc/src/sgml/pgvisibility.sgml -->
+
+<sect1 id="pgvisibility" xreflabel="pg_visibility">
+ <title>pg_visibility</title>
+
+ <indexterm zone="pgvisibility">
+ <primary>pg_visibility</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_visibility</filename> module provides a means for examining the
+ visibility map (VM) and page-level visibility information of a table.
+ It also provides functions to check the integrity of a visibility map and to
+ force it to be rebuilt.
+ </para>
+
+ <para>
+ Three different bits are used to store information about page-level
+ visibility. The all-visible bit in the visibility map indicates that every
+ tuple in the corresponding page of the relation is visible to every current
+ and future transaction. The all-frozen bit in the visibility map indicates
+ that every tuple in the page is frozen; that is, no future vacuum will need
+ to modify the page until such time as a tuple is inserted, updated, deleted,
+ or locked on that page.
+ The page header's <literal>PD_ALL_VISIBLE</literal> bit has the
+ same meaning as the all-visible bit in the visibility map, but is stored
+ within the data page itself rather than in a separate data structure.
+ These two bits will normally agree, but the page's all-visible bit can
+ sometimes be set while the visibility map bit is clear after a crash
+ recovery. The reported values can also disagree because of a change that
+ occurs after <literal>pg_visibility</literal> examines the visibility map and
+ before it examines the data page. Any event that causes data corruption
+ can also cause these bits to disagree.
+ </para>
+
+ <para>
+ Functions that display information about <literal>PD_ALL_VISIBLE</literal> bits
+ are much more costly than those that only consult the visibility map,
+ because they must read the relation's data blocks rather than only the
+ (much smaller) visibility map. Functions that check the relation's
+ data blocks are similarly expensive.
+ </para>
+
+ <sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>pg_visibility_map(relation regclass, blkno bigint, all_visible OUT boolean, all_frozen OUT boolean) returns record</function></term>
+ <listitem>
+ <para>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ the given block of the given relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_visibility(relation regclass, blkno bigint, all_visible OUT boolean, all_frozen OUT boolean, pd_all_visible OUT boolean) returns record</function></term>
+ <listitem>
+ <para>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ the given block of the given relation, plus the
+ <literal>PD_ALL_VISIBLE</literal> bit of that block.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_visibility_map(relation regclass, blkno OUT bigint, all_visible OUT boolean, all_frozen OUT boolean) returns setof record</function></term>
+ <listitem>
+ <para>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ each block of the given relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_visibility(relation regclass, blkno OUT bigint, all_visible OUT boolean, all_frozen OUT boolean, pd_all_visible OUT boolean) returns setof record</function></term>
+
+ <listitem>
+ <para>
+ Returns the all-visible and all-frozen bits in the visibility map for
+ each block of the given relation, plus the <literal>PD_ALL_VISIBLE</literal>
+ bit of each block.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_visibility_map_summary(relation regclass, all_visible OUT bigint, all_frozen OUT bigint) returns record</function></term>
+
+ <listitem>
+ <para>
+ Returns the number of all-visible pages and the number of all-frozen
+ pages in the relation according to the visibility map.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_check_frozen(relation regclass, t_ctid OUT tid) returns setof tid</function></term>
+
+ <listitem>
+ <para>
+ Returns the TIDs of non-frozen tuples stored in pages marked all-frozen
+ in the visibility map. If this function returns a non-empty set of
+ TIDs, the visibility map is corrupt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_check_visible(relation regclass, t_ctid OUT tid) returns setof tid</function></term>
+
+ <listitem>
+ <para>
+ Returns the TIDs of non-all-visible tuples stored in pages marked
+ all-visible in the visibility map. If this function returns a non-empty
+ set of TIDs, the visibility map is corrupt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>pg_truncate_visibility_map(relation regclass) returns void</function></term>
+
+ <listitem>
+ <para>
+ Truncates the visibility map for the given relation. This function is
+ useful if you believe that the visibility map for the relation is
+ corrupt and wish to force rebuilding it. The first <command>VACUUM</command>
+ executed on the given relation after this function is executed will scan
+ every page in the relation and rebuild the visibility map. (Until that
+ is done, queries will treat the visibility map as containing all zeroes.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ By default, these functions are executable only by superusers and roles with privileges
+ of the <literal>pg_stat_scan_tables</literal> role, with the exception of
+ <function>pg_truncate_visibility_map(relation regclass)</function> which can only
+ be executed by superusers.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Robert Haas <email>rhaas@postgresql.org</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/pgwalinspect.sgml b/doc/src/sgml/pgwalinspect.sgml
new file mode 100644
index 0000000..51592a5
--- /dev/null
+++ b/doc/src/sgml/pgwalinspect.sgml
@@ -0,0 +1,203 @@
+<!-- doc/src/sgml/pgwalinspect.sgml -->
+
+<sect1 id="pgwalinspect" xreflabel="pg_walinspect">
+ <title>pg_walinspect</title>
+
+ <indexterm zone="pgwalinspect">
+ <primary>pg_walinspect</primary>
+ </indexterm>
+
+ <para>
+ The <filename>pg_walinspect</filename> module provides SQL functions that
+ allow you to inspect the contents of write-ahead log of
+ a running <productname>PostgreSQL</productname> database cluster at a low
+ level, which is useful for debugging, analytical, reporting or
+ educational purposes. It is similar to <xref linkend="pgwaldump"/>, but
+ accessible through SQL rather than a separate utility.
+ </para>
+
+ <para>
+ All the functions of this module will provide the WAL information using the
+ current server's timeline ID.
+ </para>
+
+ <para>
+ All the functions of this module will try to find the first valid WAL record
+ that is at or after the given <replaceable>in_lsn</replaceable> or
+ <replaceable>start_lsn</replaceable> and will emit error if no such record
+ is available. Similarly, the <replaceable>end_lsn</replaceable> must be
+ available, and if it falls in the middle of a record, the entire record must
+ be available.
+ </para>
+
+ <note>
+ <para>
+ Some functions, such as <function><link
+ linkend="pg-logical-emit-message">pg_logical_emit_message</link></function>,
+ return the LSN <emphasis>after</emphasis> the record just
+ inserted. Therefore, if you pass that LSN as
+ <replaceable>in_lsn</replaceable> or <replaceable>start_lsn</replaceable>
+ to one of these functions, it will return the <emphasis>next</emphasis>
+ record.
+ </para>
+ </note>
+ <para>
+ By default, use of these functions is restricted to superusers and members of
+ the <literal>pg_read_server_files</literal> role. Access may be granted by
+ superusers to others using <command>GRANT</command>.
+ </para>
+
+ <sect2>
+ <title>General Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>pg_get_wal_record_info(in_lsn pg_lsn) returns record</function>
+ </term>
+
+ <listitem>
+ <para>
+ Gets WAL record information of a given LSN. If the given LSN isn't
+ at the start of a WAL record, it gives the information of the next
+ available valid WAL record; or an error if no such record is found.
+ For example, usage of the function is as
+ follows:
+<screen>
+postgres=# SELECT * FROM pg_get_wal_record_info('0/1E826E98');
+-[ RECORD 1 ]----+----------------------------------------------------
+start_lsn | 0/1E826F20
+end_lsn | 0/1E826F60
+prev_lsn | 0/1E826C80
+xid | 0
+resource_manager | Heap2
+record_type | PRUNE
+record_length | 58
+main_data_length | 8
+fpi_length | 0
+description | snapshotConflictHorizon 33748 nredirected 0 ndead 2
+block_ref | blkref #0: rel 1663/5/60221 fork main blk 2
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>
+ pg_get_wal_records_info(start_lsn pg_lsn, end_lsn pg_lsn)
+ returns setof record
+ </function>
+ </term>
+
+ <listitem>
+ <para>
+ Gets information of all the valid WAL records between
+ <replaceable>start_lsn</replaceable> and <replaceable>end_lsn</replaceable>.
+ Returns one row per WAL record. If <replaceable>start_lsn</replaceable>
+ or <replaceable>end_lsn</replaceable> are not yet available, the
+ function will raise an error. For example:
+<screen>
+postgres=# SELECT * FROM pg_get_wal_records_info('0/1E913618', '0/1E913740') LIMIT 1;
+-[ RECORD 1 ]----+--------------------------------------------------------------
+start_lsn | 0/1E913618
+end_lsn | 0/1E913650
+prev_lsn | 0/1E9135A0
+xid | 0
+resource_manager | Standby
+record_type | RUNNING_XACTS
+record_length | 50
+main_data_length | 24
+fpi_length | 0
+description | nextXid 33775 latestCompletedXid 33774 oldestRunningXid 33775
+block_ref |
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>
+ pg_get_wal_records_info_till_end_of_wal(start_lsn pg_lsn)
+ returns setof record
+ </function>
+ </term>
+
+ <listitem>
+ <para>
+ This function is the same as <function>pg_get_wal_records_info()</function>,
+ except that it gets information of all the valid WAL records from
+ <replaceable>start_lsn</replaceable> till the end of WAL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>
+ pg_get_wal_stats(start_lsn pg_lsn, end_lsn pg_lsn, per_record boolean DEFAULT false)
+ returns setof record
+ </function>
+ </term>
+
+ <listitem>
+ <para>
+ Gets statistics of all the valid WAL records between
+ <replaceable>start_lsn</replaceable> and
+ <replaceable>end_lsn</replaceable>. By default, it returns one row per
+ <replaceable>resource_manager</replaceable> type. When
+ <replaceable>per_record</replaceable> is set to <literal>true</literal>,
+ it returns one row per <replaceable>record_type</replaceable>.
+ If <replaceable>start_lsn</replaceable>
+ or <replaceable>end_lsn</replaceable> are not yet available, the
+ function will raise an error. For example:
+<screen>
+postgres=# SELECT * FROM pg_get_wal_stats('0/1E847D00', '0/1E84F500')
+ WHERE count > 0 AND
+ "resource_manager/record_type" = 'Transaction'
+ LIMIT 1;
+-[ RECORD 1 ]----------------+-------------------
+resource_manager/record_type | Transaction
+count | 2
+count_percentage | 8
+record_size | 875
+record_size_percentage | 41.23468426013195
+fpi_size | 0
+fpi_size_percentage | 0
+combined_size | 875
+combined_size_percentage | 2.8634072910530795
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>
+ pg_get_wal_stats_till_end_of_wal(start_lsn pg_lsn, per_record boolean DEFAULT false)
+ returns setof record
+ </function>
+ </term>
+
+ <listitem>
+ <para>
+ This function is the same as <function>pg_get_wal_stats()</function>,
+ except that it gets statistics of all the valid WAL records from
+ <replaceable>start_lsn</replaceable> till end of WAL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Bharath Rupireddy <email>bharath.rupireddyforpostgres@gmail.com</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/planstats.sgml b/doc/src/sgml/planstats.sgml
new file mode 100644
index 0000000..df85ea5
--- /dev/null
+++ b/doc/src/sgml/planstats.sgml
@@ -0,0 +1,762 @@
+<!-- doc/src/sgml/planstats.sgml -->
+
+<chapter id="planner-stats-details">
+ <title>How the Planner Uses Statistics</title>
+
+ <para>
+ This chapter builds on the material covered in <xref
+ linkend="using-explain"/> and <xref linkend="planner-stats"/> to show some
+ additional details about how the planner uses the
+ system statistics to estimate the number of rows each part of a query might
+ return. This is a significant part of the planning process,
+ providing much of the raw material for cost calculation.
+ </para>
+
+ <para>
+ The intent of this chapter is not to document the code in detail,
+ but to present an overview of how it works.
+ This will perhaps ease the learning curve for someone who subsequently
+ wishes to read the code.
+ </para>
+
+ <sect1 id="row-estimation-examples">
+ <title>Row Estimation Examples</title>
+
+ <indexterm zone="row-estimation-examples">
+ <primary>row estimation</primary>
+ <secondary>planner</secondary>
+ </indexterm>
+
+ <para>
+ The examples shown below use tables in the <productname>PostgreSQL</productname>
+ regression test database.
+ The outputs shown are taken from version 8.3.
+ The behavior of earlier (or later) versions might vary.
+ Note also that since <command>ANALYZE</command> uses random sampling
+ while producing statistics, the results will change slightly after
+ any new <command>ANALYZE</command>.
+ </para>
+
+ <para>
+ Let's start with a very simple query:
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1;
+
+ QUERY PLAN
+-------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
+</programlisting>
+
+ How the planner determines the cardinality of <structname>tenk1</structname>
+ is covered in <xref linkend="planner-stats"/>, but is repeated here for
+ completeness. The number of pages and rows is looked up in
+ <structname>pg_class</structname>:
+
+<programlisting>
+SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
+
+ relpages | reltuples
+----------+-----------
+ 358 | 10000
+</programlisting>
+
+ These numbers are current as of the last <command>VACUUM</command> or
+ <command>ANALYZE</command> on the table. The planner then fetches the
+ actual current number of pages in the table (this is a cheap operation,
+ not requiring a table scan). If that is different from
+ <structfield>relpages</structfield> then
+ <structfield>reltuples</structfield> is scaled accordingly to
+ arrive at a current number-of-rows estimate. In the example above, the value of
+ <structfield>relpages</structfield> is up-to-date so the rows estimate is
+ the same as <structfield>reltuples</structfield>.
+ </para>
+
+ <para>
+ Let's move on to an example with a range condition in its
+ <literal>WHERE</literal> clause:
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 1000;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------
+ Bitmap Heap Scan on tenk1 (cost=24.06..394.64 rows=1007 width=244)
+ Recheck Cond: (unique1 &lt; 1000)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
+ Index Cond: (unique1 &lt; 1000)
+</programlisting>
+
+ The planner examines the <literal>WHERE</literal> clause condition
+ and looks up the selectivity function for the operator
+ <literal>&lt;</literal> in <structname>pg_operator</structname>.
+ This is held in the column <structfield>oprrest</structfield>,
+ and the entry in this case is <function>scalarltsel</function>.
+ The <function>scalarltsel</function> function retrieves the histogram for
+ <structfield>unique1</structfield> from
+ <structname>pg_statistic</structname>. For manual queries it is more
+ convenient to look in the simpler <structname>pg_stats</structname>
+ view:
+
+<programlisting>
+SELECT histogram_bounds FROM pg_stats
+WHERE tablename='tenk1' AND attname='unique1';
+
+ histogram_bounds
+------------------------------------------------------
+ {0,993,1997,3050,4040,5036,5957,7057,8029,9016,9995}
+</programlisting>
+
+ Next the fraction of the histogram occupied by <quote>&lt; 1000</quote>
+ is worked out. This is the selectivity. The histogram divides the range
+ into equal frequency buckets, so all we have to do is locate the bucket
+ that our value is in and count <emphasis>part</emphasis> of it and
+ <emphasis>all</emphasis> of the ones before. The value 1000 is clearly in
+ the second bucket (993&ndash;1997). Assuming a linear distribution of
+ values inside each bucket, we can calculate the selectivity as:
+
+<programlisting>
+selectivity = (1 + (1000 - bucket[2].min)/(bucket[2].max - bucket[2].min))/num_buckets
+ = (1 + (1000 - 993)/(1997 - 993))/10
+ = 0.100697
+</programlisting>
+
+ that is, one whole bucket plus a linear fraction of the second, divided by
+ the number of buckets. The estimated number of rows can now be calculated as
+ the product of the selectivity and the cardinality of
+ <structname>tenk1</structname>:
+
+<programlisting>
+rows = rel_cardinality * selectivity
+ = 10000 * 0.100697
+ = 1007 (rounding off)
+</programlisting>
+ </para>
+
+ <para>
+ Next let's consider an example with an equality condition in its
+ <literal>WHERE</literal> clause:
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'CRAAAA';
+
+ QUERY PLAN
+----------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=30 width=244)
+ Filter: (stringu1 = 'CRAAAA'::name)
+</programlisting>
+
+ Again the planner examines the <literal>WHERE</literal> clause condition
+ and looks up the selectivity function for <literal>=</literal>, which is
+ <function>eqsel</function>. For equality estimation the histogram is
+ not useful; instead the list of <firstterm>most
+ common values</firstterm> (<acronym>MCV</acronym>s) is used to determine the
+ selectivity. Let's have a look at the MCVs, with some additional columns
+ that will be useful later:
+
+<programlisting>
+SELECT null_frac, n_distinct, most_common_vals, most_common_freqs FROM pg_stats
+WHERE tablename='tenk1' AND attname='stringu1';
+
+null_frac | 0
+n_distinct | 676
+most_common_vals | {EJAAAA,BBAAAA,CRAAAA,FCAAAA,FEAAAA,GSAAAA,&zwsp;JOAAAA,MCAAAA,NAAAAA,WGAAAA}
+most_common_freqs | {0.00333333,0.003,0.003,0.003,0.003,0.003,&zwsp;0.003,0.003,0.003,0.003}
+
+</programlisting>
+
+ Since <literal>CRAAAA</literal> appears in the list of MCVs, the selectivity is
+ merely the corresponding entry in the list of most common frequencies
+ (<acronym>MCF</acronym>s):
+
+<programlisting>
+selectivity = mcf[3]
+ = 0.003
+</programlisting>
+
+ As before, the estimated number of rows is just the product of this with the
+ cardinality of <structname>tenk1</structname>:
+
+<programlisting>
+rows = 10000 * 0.003
+ = 30
+</programlisting>
+ </para>
+
+ <para>
+ Now consider the same query, but with a constant that is not in the
+ <acronym>MCV</acronym> list:
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'xxx';
+
+ QUERY PLAN
+----------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=15 width=244)
+ Filter: (stringu1 = 'xxx'::name)
+</programlisting>
+
+ This is quite a different problem: how to estimate the selectivity when the
+ value is <emphasis>not</emphasis> in the <acronym>MCV</acronym> list.
+ The approach is to use the fact that the value is not in the list,
+ combined with the knowledge of the frequencies for all of the
+ <acronym>MCV</acronym>s:
+
+<programlisting>
+selectivity = (1 - sum(mvf))/(num_distinct - num_mcv)
+ = (1 - (0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003 +
+ 0.003 + 0.003 + 0.003 + 0.003))/(676 - 10)
+ = 0.0014559
+</programlisting>
+
+ That is, add up all the frequencies for the <acronym>MCV</acronym>s and
+ subtract them from one, then
+ divide by the number of <emphasis>other</emphasis> distinct values.
+ This amounts to assuming that the fraction of the column that is not any
+ of the MCVs is evenly distributed among all the other distinct values.
+ Notice that there are no null values so we don't have to worry about those
+ (otherwise we'd subtract the null fraction from the numerator as well).
+ The estimated number of rows is then calculated as usual:
+
+<programlisting>
+rows = 10000 * 0.0014559
+ = 15 (rounding off)
+</programlisting>
+ </para>
+
+ <para>
+ The previous example with <literal>unique1 &lt; 1000</literal> was an
+ oversimplification of what <function>scalarltsel</function> really does;
+ now that we have seen an example of the use of MCVs, we can fill in some
+ more detail. The example was correct as far as it went, because since
+ <structfield>unique1</structfield> is a unique column it has no MCVs (obviously, no
+ value is any more common than any other value). For a non-unique
+ column, there will normally be both a histogram and an MCV list, and
+ <emphasis>the histogram does not include the portion of the column
+ population represented by the MCVs</emphasis>. We do things this way because
+ it allows more precise estimation. In this situation
+ <function>scalarltsel</function> directly applies the condition (e.g.,
+ <quote>&lt; 1000</quote>) to each value of the MCV list, and adds up the
+ frequencies of the MCVs for which the condition is true. This gives
+ an exact estimate of the selectivity within the portion of the table
+ that is MCVs. The histogram is then used in the same way as above
+ to estimate the selectivity in the portion of the table that is not
+ MCVs, and then the two numbers are combined to estimate the overall
+ selectivity. For example, consider
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1 WHERE stringu1 &lt; 'IAAAAA';
+
+ QUERY PLAN
+------------------------------------------------------------
+ Seq Scan on tenk1 (cost=0.00..483.00 rows=3077 width=244)
+ Filter: (stringu1 &lt; 'IAAAAA'::name)
+</programlisting>
+
+ We already saw the MCV information for <structfield>stringu1</structfield>,
+ and here is its histogram:
+
+<programlisting>
+SELECT histogram_bounds FROM pg_stats
+WHERE tablename='tenk1' AND attname='stringu1';
+
+ histogram_bounds
+-------------------------------------------------------------------&zwsp;-------------
+ {AAAAAA,CQAAAA,FRAAAA,IBAAAA,KRAAAA,NFAAAA,PSAAAA,SGAAAA,VAAAAA,&zwsp;XLAAAA,ZZAAAA}
+</programlisting>
+
+ Checking the MCV list, we find that the condition <literal>stringu1 &lt;
+ 'IAAAAA'</literal> is satisfied by the first six entries and not the last four,
+ so the selectivity within the MCV part of the population is
+
+<programlisting>
+selectivity = sum(relevant mvfs)
+ = 0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003
+ = 0.01833333
+</programlisting>
+
+ Summing all the MCFs also tells us that the total fraction of the
+ population represented by MCVs is 0.03033333, and therefore the
+ fraction represented by the histogram is 0.96966667 (again, there
+ are no nulls, else we'd have to exclude them here). We can see
+ that the value <literal>IAAAAA</literal> falls nearly at the end of the
+ third histogram bucket. Using some rather cheesy assumptions
+ about the frequency of different characters, the planner arrives
+ at the estimate 0.298387 for the portion of the histogram population
+ that is less than <literal>IAAAAA</literal>. We then combine the estimates
+ for the MCV and non-MCV populations:
+
+<programlisting>
+selectivity = mcv_selectivity + histogram_selectivity * histogram_fraction
+ = 0.01833333 + 0.298387 * 0.96966667
+ = 0.307669
+
+rows = 10000 * 0.307669
+ = 3077 (rounding off)
+</programlisting>
+
+ In this particular example, the correction from the MCV list is fairly
+ small, because the column distribution is actually quite flat (the
+ statistics showing these particular values as being more common than
+ others are mostly due to sampling error). In a more typical case where
+ some values are significantly more common than others, this complicated
+ process gives a useful improvement in accuracy because the selectivity
+ for the most common values is found exactly.
+ </para>
+
+ <para>
+ Now let's consider a case with more than one
+ condition in the <literal>WHERE</literal> clause:
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 1000 AND stringu1 = 'xxx';
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------
+ Bitmap Heap Scan on tenk1 (cost=23.80..396.91 rows=1 width=244)
+ Recheck Cond: (unique1 &lt; 1000)
+ Filter: (stringu1 = 'xxx'::name)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
+ Index Cond: (unique1 &lt; 1000)
+</programlisting>
+
+ The planner assumes that the two conditions are independent, so that
+ the individual selectivities of the clauses can be multiplied together:
+
+<programlisting>
+selectivity = selectivity(unique1 &lt; 1000) * selectivity(stringu1 = 'xxx')
+ = 0.100697 * 0.0014559
+ = 0.0001466
+
+rows = 10000 * 0.0001466
+ = 1 (rounding off)
+</programlisting>
+
+ Notice that the number of rows estimated to be returned from the bitmap
+ index scan reflects only the condition used with the index; this is
+ important since it affects the cost estimate for the subsequent heap
+ fetches.
+ </para>
+
+ <para>
+ Finally we will examine a query that involves a join:
+
+<programlisting>
+EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2
+WHERE t1.unique1 &lt; 50 AND t1.unique2 = t2.unique2;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------
+ Nested Loop (cost=4.64..456.23 rows=50 width=488)
+ -&gt; Bitmap Heap Scan on tenk1 t1 (cost=4.64..142.17 rows=50 width=244)
+ Recheck Cond: (unique1 &lt; 50)
+ -&gt; Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.63 rows=50 width=0)
+ Index Cond: (unique1 &lt; 50)
+ -&gt; Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..6.27 rows=1 width=244)
+ Index Cond: (unique2 = t1.unique2)
+</programlisting>
+
+ The restriction on <structname>tenk1</structname>,
+ <literal>unique1 &lt; 50</literal>,
+ is evaluated before the nested-loop join.
+ This is handled analogously to the previous range example. This time the
+ value 50 falls into the first bucket of the
+ <structfield>unique1</structfield> histogram:
+
+<programlisting>
+selectivity = (0 + (50 - bucket[1].min)/(bucket[1].max - bucket[1].min))/num_buckets
+ = (0 + (50 - 0)/(993 - 0))/10
+ = 0.005035
+
+rows = 10000 * 0.005035
+ = 50 (rounding off)
+</programlisting>
+
+ The restriction for the join is <literal>t2.unique2 = t1.unique2</literal>.
+ The operator is just
+ our familiar <literal>=</literal>, however the selectivity function is
+ obtained from the <structfield>oprjoin</structfield> column of
+ <structname>pg_operator</structname>, and is <function>eqjoinsel</function>.
+ <function>eqjoinsel</function> looks up the statistical information for both
+ <structname>tenk2</structname> and <structname>tenk1</structname>:
+
+<programlisting>
+SELECT tablename, null_frac,n_distinct, most_common_vals FROM pg_stats
+WHERE tablename IN ('tenk1', 'tenk2') AND attname='unique2';
+
+tablename | null_frac | n_distinct | most_common_vals
+-----------+-----------+------------+------------------
+ tenk1 | 0 | -1 |
+ tenk2 | 0 | -1 |
+</programlisting>
+
+ In this case there is no <acronym>MCV</acronym> information for
+ <structfield>unique2</structfield> because all the values appear to be
+ unique, so we use an algorithm that relies only on the number of
+ distinct values for both relations together with their null fractions:
+
+<programlisting>
+selectivity = (1 - null_frac1) * (1 - null_frac2) * min(1/num_distinct1, 1/num_distinct2)
+ = (1 - 0) * (1 - 0) / max(10000, 10000)
+ = 0.0001
+</programlisting>
+
+ This is, subtract the null fraction from one for each of the relations,
+ and divide by the maximum of the numbers of distinct values.
+ The number of rows
+ that the join is likely to emit is calculated as the cardinality of the
+ Cartesian product of the two inputs, multiplied by the
+ selectivity:
+
+<programlisting>
+rows = (outer_cardinality * inner_cardinality) * selectivity
+ = (50 * 10000) * 0.0001
+ = 50
+</programlisting>
+ </para>
+
+ <para>
+ Had there been MCV lists for the two columns,
+ <function>eqjoinsel</function> would have used direct comparison of the MCV
+ lists to determine the join selectivity within the part of the column
+ populations represented by the MCVs. The estimate for the remainder of the
+ populations follows the same approach shown here.
+ </para>
+
+ <para>
+ Notice that we showed <literal>inner_cardinality</literal> as 10000, that is,
+ the unmodified size of <structname>tenk2</structname>. It might appear from
+ inspection of the <command>EXPLAIN</command> output that the estimate of
+ join rows comes from 50 * 1, that is, the number of outer rows times
+ the estimated number of rows obtained by each inner index scan on
+ <structname>tenk2</structname>. But this is not the case: the join relation size
+ is estimated before any particular join plan has been considered. If
+ everything is working well then the two ways of estimating the join
+ size will produce about the same answer, but due to round-off error and
+ other factors they sometimes diverge significantly.
+ </para>
+
+ <para>
+ For those interested in further details, estimation of the size of
+ a table (before any <literal>WHERE</literal> clauses) is done in
+ <filename>src/backend/optimizer/util/plancat.c</filename>. The generic
+ logic for clause selectivities is in
+ <filename>src/backend/optimizer/path/clausesel.c</filename>. The
+ operator-specific selectivity functions are mostly found
+ in <filename>src/backend/utils/adt/selfuncs.c</filename>.
+ </para>
+ </sect1>
+
+ <sect1 id="multivariate-statistics-examples">
+ <title>Multivariate Statistics Examples</title>
+
+ <indexterm>
+ <primary>row estimation</primary>
+ <secondary>multivariate</secondary>
+ </indexterm>
+
+ <sect2 id="functional-dependencies">
+ <title>Functional Dependencies</title>
+
+ <para>
+ Multivariate correlation can be demonstrated with a very simple data set
+ &mdash; a table with two columns, both containing the same values:
+
+<programlisting>
+CREATE TABLE t (a INT, b INT);
+INSERT INTO t SELECT i % 100, i % 100 FROM generate_series(1, 10000) s(i);
+ANALYZE t;
+</programlisting>
+
+ As explained in <xref linkend="planner-stats"/>, the planner can determine
+ cardinality of <structname>t</structname> using the number of pages and
+ rows obtained from <structname>pg_class</structname>:
+
+<programlisting>
+SELECT relpages, reltuples FROM pg_class WHERE relname = 't';
+
+ relpages | reltuples
+----------+-----------
+ 45 | 10000
+</programlisting>
+
+ The data distribution is very simple; there are only 100 distinct values
+ in each column, uniformly distributed.
+ </para>
+
+ <para>
+ The following example shows the result of estimating a <literal>WHERE</literal>
+ condition on the <structfield>a</structfield> column:
+
+<programlisting>
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------
+ Seq Scan on t (cost=0.00..170.00 rows=100 width=8) (actual rows=100 loops=1)
+ Filter: (a = 1)
+ Rows Removed by Filter: 9900
+</programlisting>
+
+ The planner examines the condition and determines the selectivity
+ of this clause to be 1%. By comparing this estimate and the actual
+ number of rows, we see that the estimate is very accurate
+ (in fact exact, as the table is very small). Changing the
+ <literal>WHERE</literal> condition to use the <structfield>b</structfield> column, an
+ identical plan is generated. But observe what happens if we apply the same
+ condition on both columns, combining them with <literal>AND</literal>:
+
+<programlisting>
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;----------
+ Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=100 loops=1)
+ Filter: ((a = 1) AND (b = 1))
+ Rows Removed by Filter: 9900
+</programlisting>
+
+ The planner estimates the selectivity for each condition individually,
+ arriving at the same 1% estimates as above. Then it assumes that the
+ conditions are independent, and so it multiplies their selectivities,
+ producing a final selectivity estimate of just 0.01%.
+ This is a significant underestimate, as the actual number of rows
+ matching the conditions (100) is two orders of magnitude higher.
+ </para>
+
+ <para>
+ This problem can be fixed by creating a statistics object that
+ directs <command>ANALYZE</command> to calculate functional-dependency
+ multivariate statistics on the two columns:
+
+<programlisting>
+CREATE STATISTICS stts (dependencies) ON a, b FROM t;
+ANALYZE t;
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------
+ Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
+ Filter: ((a = 1) AND (b = 1))
+ Rows Removed by Filter: 9900
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="multivariate-ndistinct-counts">
+ <title>Multivariate N-Distinct Counts</title>
+
+ <para>
+ A similar problem occurs with estimation of the cardinality of sets of
+ multiple columns, such as the number of groups that would be generated by
+ a <command>GROUP BY</command> clause. When <command>GROUP BY</command>
+ lists a single column, the n-distinct estimate (which is visible as the
+ estimated number of rows returned by the HashAggregate node) is very
+ accurate:
+<programlisting>
+EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;----------------------
+ HashAggregate (cost=195.00..196.00 rows=100 width=12) (actual rows=100 loops=1)
+ Group Key: a
+ -&gt; Seq Scan on t (cost=0.00..145.00 rows=10000 width=4) (actual rows=10000 loops=1)
+</programlisting>
+ But without multivariate statistics, the estimate for the number of
+ groups in a query with two columns in <command>GROUP BY</command>, as
+ in the following example, is off by an order of magnitude:
+<programlisting>
+EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------------
+ HashAggregate (cost=220.00..230.00 rows=1000 width=16) (actual rows=100 loops=1)
+ Group Key: a, b
+ -&gt; Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (actual rows=10000 loops=1)
+</programlisting>
+ By redefining the statistics object to include n-distinct counts for the
+ two columns, the estimate is much improved:
+<programlisting>
+DROP STATISTICS stts;
+CREATE STATISTICS stts (dependencies, ndistinct) ON a, b FROM t;
+ANALYZE t;
+EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-------------------------
+ HashAggregate (cost=220.00..221.00 rows=100 width=16) (actual rows=100 loops=1)
+ Group Key: a, b
+ -&gt; Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (actual rows=10000 loops=1)
+</programlisting>
+ </para>
+
+ </sect2>
+
+ <sect2 id="mcv-lists">
+ <title>MCV Lists</title>
+
+ <para>
+ As explained in <xref linkend="functional-dependencies"/>, functional
+ dependencies are very cheap and efficient type of statistics, but their
+ main limitation is their global nature (only tracking dependencies at
+ the column level, not between individual column values).
+ </para>
+
+ <para>
+ This section introduces multivariate variant of <acronym>MCV</acronym>
+ (most-common values) lists, a straightforward extension of the per-column
+ statistics described in <xref linkend="row-estimation-examples"/>. These
+ statistics address the limitation by storing individual values, but it is
+ naturally more expensive, both in terms of building the statistics in
+ <command>ANALYZE</command>, storage and planning time.
+ </para>
+
+ <para>
+ Let's look at the query from <xref linkend="functional-dependencies"/>
+ again, but this time with a <acronym>MCV</acronym> list created on the
+ same set of columns (be sure to drop the functional dependencies, to
+ make sure the planner uses the newly created statistics).
+
+<programlisting>
+DROP STATISTICS stts;
+CREATE STATISTICS stts2 (mcv) ON a, b FROM t;
+ANALYZE t;
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;------------
+ Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
+ Filter: ((a = 1) AND (b = 1))
+ Rows Removed by Filter: 9900
+</programlisting>
+
+ The estimate is as accurate as with the functional dependencies, mostly
+ thanks to the table being fairly small and having a simple distribution
+ with a low number of distinct values. Before looking at the second query,
+ which was not handled by functional dependencies particularly well,
+ let's inspect the <acronym>MCV</acronym> list a bit.
+ </para>
+
+ <para>
+ Inspecting the <acronym>MCV</acronym> list is possible using
+ <function>pg_mcv_list_items</function> set-returning function.
+
+<programlisting>
+SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid),
+ pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts2';
+ index | values | nulls | frequency | base_frequency
+-------+----------+-------+-----------+----------------
+ 0 | {0, 0} | {f,f} | 0.01 | 0.0001
+ 1 | {1, 1} | {f,f} | 0.01 | 0.0001
+ ...
+ 49 | {49, 49} | {f,f} | 0.01 | 0.0001
+ 50 | {50, 50} | {f,f} | 0.01 | 0.0001
+ ...
+ 97 | {97, 97} | {f,f} | 0.01 | 0.0001
+ 98 | {98, 98} | {f,f} | 0.01 | 0.0001
+ 99 | {99, 99} | {f,f} | 0.01 | 0.0001
+(100 rows)
+</programlisting>
+
+ This confirms there are 100 distinct combinations in the two columns, and
+ all of them are about equally likely (1% frequency for each one). The
+ base frequency is the frequency computed from per-column statistics, as if
+ there were no multi-column statistics. Had there been any null values in
+ either of the columns, this would be identified in the
+ <structfield>nulls</structfield> column.
+ </para>
+
+ <para>
+ When estimating the selectivity, the planner applies all the conditions
+ on items in the <acronym>MCV</acronym> list, and then sums the frequencies
+ of the matching ones. See <function>mcv_clauselist_selectivity</function>
+ in <filename>src/backend/statistics/mcv.c</filename> for details.
+ </para>
+
+ <para>
+ Compared to functional dependencies, <acronym>MCV</acronym> lists have two
+ major advantages. Firstly, the list stores actual values, making it possible
+ to decide which combinations are compatible.
+
+<programlisting>
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 10;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------
+ Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
+ Filter: ((a = 1) AND (b = 10))
+ Rows Removed by Filter: 10000
+</programlisting>
+
+ Secondly, <acronym>MCV</acronym> lists handle a wider range of clause types,
+ not just equality clauses like functional dependencies. For example,
+ consider the following range query for the same table:
+
+<programlisting>
+EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a &lt;= 49 AND b &gt; 49;
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--------
+ Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1)
+ Filter: ((a &lt;= 49) AND (b &gt; 49))
+ Rows Removed by Filter: 10000
+</programlisting>
+
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="planner-stats-security">
+ <title>Planner Statistics and Security</title>
+
+ <para>
+ Access to the table <structname>pg_statistic</structname> is restricted to
+ superusers, so that ordinary users cannot learn about the contents of the
+ tables of other users from it. Some selectivity estimation functions will
+ use a user-provided operator (either the operator appearing in the query or
+ a related operator) to analyze the stored statistics. For example, in order
+ to determine whether a stored most common value is applicable, the
+ selectivity estimator will have to run the appropriate <literal>=</literal>
+ operator to compare the constant in the query to the stored value.
+ Thus the data in <structname>pg_statistic</structname> is potentially
+ passed to user-defined operators. An appropriately crafted operator can
+ intentionally leak the passed operands (for example, by logging them
+ or writing them to a different table), or accidentally leak them by showing
+ their values in error messages, in either case possibly exposing data from
+ <structname>pg_statistic</structname> to a user who should not be able to
+ see it.
+ </para>
+
+ <para>
+ In order to prevent this, the following applies to all built-in selectivity
+ estimation functions. When planning a query, in order to be able to use
+ stored statistics, the current user must either
+ have <literal>SELECT</literal> privilege on the table or the involved
+ columns, or the operator used must be <literal>LEAKPROOF</literal> (more
+ accurately, the function that the operator is based on). If not, then the
+ selectivity estimator will behave as if no statistics are available, and
+ the planner will proceed with default or fall-back assumptions.
+ </para>
+
+ <para>
+ If a user does not have the required privilege on the table or columns,
+ then in many cases the query will ultimately receive a permission-denied
+ error, in which case this mechanism is invisible in practice. But if the
+ user is reading from a security-barrier view, then the planner might wish
+ to check the statistics of an underlying table that is otherwise
+ inaccessible to the user. In that case, the operator should be leak-proof
+ or the statistics will not be used. There is no direct feedback about
+ that, except that the plan might be suboptimal. If one suspects that this
+ is the case, one could try running the query as a more privileged user,
+ to see if a different plan results.
+ </para>
+
+ <para>
+ This restriction applies only to cases where the planner would need to
+ execute a user-defined operator on one or more values
+ from <structname>pg_statistic</structname>. Thus the planner is permitted
+ to use generic statistical information, such as the fraction of null values
+ or the number of distinct values in a column, regardless of access
+ privileges.
+ </para>
+
+ <para>
+ Selectivity estimation functions contained in third-party extensions that
+ potentially operate on statistics with user-defined operators should follow
+ the same security rules. Consult the PostgreSQL source code for guidance.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/plhandler.sgml b/doc/src/sgml/plhandler.sgml
new file mode 100644
index 0000000..980c95e
--- /dev/null
+++ b/doc/src/sgml/plhandler.sgml
@@ -0,0 +1,192 @@
+<!-- doc/src/sgml/plhandler.sgml -->
+
+ <chapter id="plhandler">
+ <title>Writing a Procedural Language Handler</title>
+
+ <indexterm zone="plhandler">
+ <primary>procedural language</primary>
+ <secondary>handler for</secondary>
+ </indexterm>
+
+ <para>
+ All calls to functions that are written in a language other than
+ the current <quote>version 1</quote> interface for compiled
+ languages (this includes functions in user-defined procedural languages
+ and functions written in SQL) go through a <firstterm>call handler</firstterm>
+ function for the specific language. It is the responsibility of
+ the call handler to execute the function in a meaningful way, such
+ as by interpreting the supplied source text. This chapter outlines
+ how a new procedural language's call handler can be written.
+ </para>
+
+ <para>
+ The call handler for a procedural language is a
+ <quote>normal</quote> function that must be written in a compiled
+ language such as C, using the version-1 interface, and registered
+ with <productname>PostgreSQL</productname> as taking no arguments
+ and returning the type <type>language_handler</type>. This
+ special pseudo-type identifies the function as a call handler and
+ prevents it from being called directly in SQL commands.
+ For more details on C language calling conventions and dynamic loading,
+ see <xref linkend="xfunc-c"/>.
+ </para>
+
+ <para>
+ The call handler is called in the same way as any other function:
+ It receives a pointer to a
+ <structname>FunctionCallInfoBaseData</structname> <type>struct</type> containing
+ argument values and information about the called function, and it
+ is expected to return a <type>Datum</type> result (and possibly
+ set the <structfield>isnull</structfield> field of the
+ <structname>FunctionCallInfoBaseData</structname> structure, if it wishes
+ to return an SQL null result). The difference between a call
+ handler and an ordinary callee function is that the
+ <structfield>flinfo-&gt;fn_oid</structfield> field of the
+ <structname>FunctionCallInfoBaseData</structname> structure will contain
+ the OID of the actual function to be called, not of the call
+ handler itself. The call handler must use this field to determine
+ which function to execute. Also, the passed argument list has
+ been set up according to the declaration of the target function,
+ not of the call handler.
+ </para>
+
+ <para>
+ It's up to the call handler to fetch the entry of the function from the
+ <classname>pg_proc</classname> system catalog and to analyze the argument
+ and return types of the called function. The <literal>AS</literal> clause from the
+ <command>CREATE FUNCTION</command> command for the function will be found
+ in the <literal>prosrc</literal> column of the
+ <classname>pg_proc</classname> row. This is commonly source
+ text in the procedural language, but in theory it could be something else,
+ such as a path name to a file, or anything else that tells the call handler
+ what to do in detail.
+ </para>
+
+ <para>
+ Often, the same function is called many times per SQL statement.
+ A call handler can avoid repeated lookups of information about the
+ called function by using the
+ <structfield>flinfo-&gt;fn_extra</structfield> field. This will
+ initially be <symbol>NULL</symbol>, but can be set by the call handler to point at
+ information about the called function. On subsequent calls, if
+ <structfield>flinfo-&gt;fn_extra</structfield> is already non-<symbol>NULL</symbol>
+ then it can be used and the information lookup step skipped. The
+ call handler must make sure that
+ <structfield>flinfo-&gt;fn_extra</structfield> is made to point at
+ memory that will live at least until the end of the current query,
+ since an <structname>FmgrInfo</structname> data structure could be
+ kept that long. One way to do this is to allocate the extra data
+ in the memory context specified by
+ <structfield>flinfo-&gt;fn_mcxt</structfield>; such data will
+ normally have the same lifespan as the
+ <structname>FmgrInfo</structname> itself. But the handler could
+ also choose to use a longer-lived memory context so that it can cache
+ function definition information across queries.
+ </para>
+
+ <para>
+ When a procedural-language function is invoked as a trigger, no arguments
+ are passed in the usual way, but the
+ <structname>FunctionCallInfoBaseData</structname>'s
+ <structfield>context</structfield> field points at a
+ <structname>TriggerData</structname> structure, rather than being <symbol>NULL</symbol>
+ as it is in a plain function call. A language handler should
+ provide mechanisms for procedural-language functions to get at the trigger
+ information.
+ </para>
+
+ <para>
+ A template for a procedural-language handler written as a C extension is
+ provided in <literal>src/test/modules/plsample</literal>. This is a
+ working sample demonstrating one way to create a procedural-language
+ handler, process parameters, and return a value.
+ </para>
+
+ <para>
+ Although providing a call handler is sufficient to create a minimal
+ procedural language, there are two other functions that can optionally
+ be provided to make the language more convenient to use. These
+ are a <firstterm>validator</firstterm> and an
+ <firstterm>inline handler</firstterm>. A validator can be provided
+ to allow language-specific checking to be done during
+ <xref linkend="sql-createfunction"/>.
+ An inline handler can be provided to allow the language to support
+ anonymous code blocks executed via the <xref linkend="sql-do"/> command.
+ </para>
+
+ <para>
+ If a validator is provided by a procedural language, it
+ must be declared as a function taking a single parameter of type
+ <type>oid</type>. The validator's result is ignored, so it is customarily
+ declared to return <type>void</type>. The validator will be called at
+ the end of a <command>CREATE FUNCTION</command> command that has created
+ or updated a function written in the procedural language.
+ The passed-in OID is the OID of the function's <classname>pg_proc</classname>
+ row. The validator must fetch this row in the usual way, and do
+ whatever checking is appropriate.
+ First, call <function>CheckFunctionValidatorAccess()</function> to diagnose
+ explicit calls to the validator that the user could not achieve through
+ <command>CREATE FUNCTION</command>. Typical checks then include verifying
+ that the function's argument and result types are supported by the
+ language, and that the function's body is syntactically correct
+ in the language. If the validator finds the function to be okay,
+ it should just return. If it finds an error, it should report that
+ via the normal <function>ereport()</function> error reporting mechanism.
+ Throwing an error will force a transaction rollback and thus prevent
+ the incorrect function definition from being committed.
+ </para>
+
+ <para>
+ Validator functions should typically honor the <xref
+ linkend="guc-check-function-bodies"/> parameter: if it is turned off then
+ any expensive or context-sensitive checking should be skipped. If the
+ language provides for code execution at compilation time, the validator
+ must suppress checks that would induce such execution. In particular,
+ this parameter is turned off by <application>pg_dump</application> so that it can
+ load procedural language functions without worrying about side effects or
+ dependencies of the function bodies on other database objects.
+ (Because of this requirement, the call handler should avoid
+ assuming that the validator has fully checked the function. The point
+ of having a validator is not to let the call handler omit checks, but
+ to notify the user immediately if there are obvious errors in a
+ <command>CREATE FUNCTION</command> command.)
+ While the choice of exactly what to check is mostly left to the
+ discretion of the validator function, note that the core
+ <command>CREATE FUNCTION</command> code only executes <literal>SET</literal> clauses
+ attached to a function when <varname>check_function_bodies</varname> is on.
+ Therefore, checks whose results might be affected by GUC parameters
+ definitely should be skipped when <varname>check_function_bodies</varname> is
+ off, to avoid false failures when restoring a dump.
+ </para>
+
+ <para>
+ If an inline handler is provided by a procedural language, it
+ must be declared as a function taking a single parameter of type
+ <type>internal</type>. The inline handler's result is ignored, so it is
+ customarily declared to return <type>void</type>. The inline handler
+ will be called when a <command>DO</command> statement is executed specifying
+ the procedural language. The parameter actually passed is a pointer
+ to an <structname>InlineCodeBlock</structname> struct, which contains information
+ about the <command>DO</command> statement's parameters, in particular the
+ text of the anonymous code block to be executed. The inline handler
+ should execute this code and return.
+ </para>
+
+ <para>
+ It's recommended that you wrap all these function declarations,
+ as well as the <command>CREATE LANGUAGE</command> command itself, into
+ an <firstterm>extension</firstterm> so that a simple <command>CREATE EXTENSION</command>
+ command is sufficient to install the language. See
+ <xref linkend="extend-extensions"/> for information about writing
+ extensions.
+ </para>
+
+ <para>
+ The procedural languages included in the standard distribution
+ are good references when trying to write your own language handler.
+ Look into the <filename>src/pl</filename> subdirectory of the source tree.
+ The <xref linkend="sql-createlanguage"/>
+ reference page also has some useful details.
+ </para>
+
+ </chapter>
diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml
new file mode 100644
index 0000000..25b1077
--- /dev/null
+++ b/doc/src/sgml/plperl.sgml
@@ -0,0 +1,1595 @@
+<!-- doc/src/sgml/plperl.sgml -->
+
+ <chapter id="plperl">
+ <title>PL/Perl &mdash; Perl Procedural Language</title>
+
+ <indexterm zone="plperl">
+ <primary>PL/Perl</primary>
+ </indexterm>
+
+ <indexterm zone="plperl">
+ <primary>Perl</primary>
+ </indexterm>
+
+ <para>
+ PL/Perl is a loadable procedural language that enables you to write
+ <productname>PostgreSQL</productname> functions and procedures in the
+ <ulink url="https://www.perl.org">Perl programming language</ulink>.
+ </para>
+
+ <para>
+ The main advantage to using PL/Perl is that this allows use,
+ within stored functions and procedures, of the manyfold <quote>string
+ munging</quote> operators and functions available for Perl. Parsing
+ complex strings might be easier using Perl than it is with the
+ string functions and control structures provided in PL/pgSQL.
+ </para>
+
+ <para>
+ To install PL/Perl in a particular database, use
+ <literal>CREATE EXTENSION plperl</literal>.
+ </para>
+
+ <tip>
+ <para>
+ If a language is installed into <literal>template1</literal>, all subsequently
+ created databases will have the language installed automatically.
+ </para>
+ </tip>
+
+ <note>
+ <para>
+ Users of source packages must specially enable the build of
+ PL/Perl during the installation process. (Refer to <xref
+ linkend="installation"/> for more information.) Users of
+ binary packages might find PL/Perl in a separate subpackage.
+ </para>
+ </note>
+
+ <sect1 id="plperl-funcs">
+ <title>PL/Perl Functions and Arguments</title>
+
+ <para>
+ To create a function in the PL/Perl language, use the standard
+ <xref linkend="sql-createfunction"/>
+ syntax:
+
+<programlisting>
+CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>)
+RETURNS <replaceable>return-type</replaceable>
+-- function attributes can go here
+AS $$
+ # PL/Perl function body goes here
+$$ LANGUAGE plperl;
+</programlisting>
+
+ The body of the function is ordinary Perl code. In fact, the PL/Perl
+ glue code wraps it inside a Perl subroutine. A PL/Perl function is
+ called in a scalar context, so it can't return a list. You can return
+ non-scalar values (arrays, records, and sets) by returning a reference,
+ as discussed below.
+ </para>
+
+ <para>
+ In a PL/Perl procedure, any return value from the Perl code is ignored.
+ </para>
+
+ <para>
+ PL/Perl also supports anonymous code blocks called with the
+ <xref linkend="sql-do"/> statement:
+
+<programlisting>
+DO $$
+ # PL/Perl code
+$$ LANGUAGE plperl;
+</programlisting>
+
+ An anonymous code block receives no arguments, and whatever value it
+ might return is discarded. Otherwise it behaves just like a function.
+ </para>
+
+ <note>
+ <para>
+ The use of named nested subroutines is dangerous in Perl, especially if
+ they refer to lexical variables in the enclosing scope. Because a PL/Perl
+ function is wrapped in a subroutine, any named subroutine you place inside
+ one will be nested. In general, it is far safer to create anonymous
+ subroutines which you call via a coderef. For more information, see the
+ entries for <literal>Variable "%s" will not stay shared</literal> and
+ <literal>Variable "%s" is not available</literal> in the
+ <citerefentry><refentrytitle>perldiag</refentrytitle></citerefentry> man page, or
+ search the Internet for <quote>perl nested named subroutine</quote>.
+ </para>
+ </note>
+
+ <para>
+ The syntax of the <command>CREATE FUNCTION</command> command requires
+ the function body to be written as a string constant. It is usually
+ most convenient to use dollar quoting (see <xref
+ linkend="sql-syntax-dollar-quoting"/>) for the string constant.
+ If you choose to use escape string syntax <literal>E''</literal>,
+ you must double any single quote marks (<literal>'</literal>) and backslashes
+ (<literal>\</literal>) used in the body of the function
+ (see <xref linkend="sql-syntax-strings"/>).
+ </para>
+
+ <para>
+ Arguments and results are handled as in any other Perl subroutine:
+ arguments are passed in <varname>@_</varname>, and a result value
+ is returned with <literal>return</literal> or as the last expression
+ evaluated in the function.
+ </para>
+
+ <para>
+ For example, a function returning the greater of two integer values
+ could be defined as:
+
+<programlisting>
+CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
+ if ($_[0] &gt; $_[1]) { return $_[0]; }
+ return $_[1];
+$$ LANGUAGE plperl;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ Arguments will be converted from the database's encoding to UTF-8
+ for use inside PL/Perl, and then converted from UTF-8 back to the
+ database encoding upon return.
+ </para>
+ </note>
+
+ <para>
+ If an SQL null value<indexterm><primary>null value</primary><secondary
+ sortas="PL/Perl">in PL/Perl</secondary></indexterm> is passed to a function,
+ the argument value will appear as <quote>undefined</quote> in Perl. The
+ above function definition will not behave very nicely with null
+ inputs (in fact, it will act as though they are zeroes). We could
+ add <literal>STRICT</literal> to the function definition to make
+ <productname>PostgreSQL</productname> do something more reasonable:
+ if a null value is passed, the function will not be called at all,
+ but will just return a null result automatically. Alternatively,
+ we could check for undefined inputs in the function body. For
+ example, suppose that we wanted <function>perl_max</function> with
+ one null and one nonnull argument to return the nonnull argument,
+ rather than a null value:
+
+<programlisting>
+CREATE FUNCTION perl_max (integer, integer) RETURNS integer AS $$
+ my ($x, $y) = @_;
+ if (not defined $x) {
+ return undef if not defined $y;
+ return $y;
+ }
+ return $x if not defined $y;
+ return $x if $x &gt; $y;
+ return $y;
+$$ LANGUAGE plperl;
+</programlisting>
+ As shown above, to return an SQL null value from a PL/Perl
+ function, return an undefined value. This can be done whether the
+ function is strict or not.
+ </para>
+
+ <para>
+ Anything in a function argument that is not a reference is
+ a string, which is in the standard <productname>PostgreSQL</productname>
+ external text representation for the relevant data type. In the case of
+ ordinary numeric or text types, Perl will just do the right thing and
+ the programmer will normally not have to worry about it. However, in
+ other cases the argument will need to be converted into a form that is
+ more usable in Perl. For example, the <function>decode_bytea</function>
+ function can be used to convert an argument of
+ type <type>bytea</type> into unescaped binary.
+ </para>
+
+ <para>
+ Similarly, values passed back to <productname>PostgreSQL</productname>
+ must be in the external text representation format. For example, the
+ <function>encode_bytea</function> function can be used to
+ escape binary data for a return value of type <type>bytea</type>.
+ </para>
+
+ <para>
+ One case that is particularly important is boolean values. As just
+ stated, the default behavior for <type>bool</type> values is that they
+ are passed to Perl as text, thus either <literal>'t'</literal>
+ or <literal>'f'</literal>. This is problematic, since Perl will not
+ treat <literal>'f'</literal> as false! It is possible to improve matters
+ by using a <quote>transform</quote> (see
+ <xref linkend="sql-createtransform"/>). Suitable transforms are provided
+ by the <filename>bool_plperl</filename> extension. To use it, install
+ the extension:
+<programlisting>
+CREATE EXTENSION bool_plperl; -- or bool_plperlu for PL/PerlU
+</programlisting>
+ Then use the <literal>TRANSFORM</literal> function attribute for a
+ PL/Perl function that takes or returns <type>bool</type>, for example:
+<programlisting>
+CREATE FUNCTION perl_and(bool, bool) RETURNS bool
+TRANSFORM FOR TYPE bool
+AS $$
+ my ($a, $b) = @_;
+ return $a &amp;&amp; $b;
+$$ LANGUAGE plperl;
+</programlisting>
+ When this transform is applied, <type>bool</type> arguments will be seen
+ by Perl as being <literal>1</literal> or empty, thus properly true or
+ false. If the function result is type <type>bool</type>, it will be true
+ or false according to whether Perl would evaluate the returned value as
+ true.
+ Similar transformations are also performed for boolean query arguments
+ and results of SPI queries performed inside the function
+ (<xref linkend="plperl-database"/>).
+ </para>
+
+ <para>
+ Perl can return <productname>PostgreSQL</productname> arrays as
+ references to Perl arrays. Here is an example:
+
+<programlisting>
+CREATE OR REPLACE function returns_array()
+RETURNS text[][] AS $$
+ return [['a&quot;b','c,d'],['e\\f','g']];
+$$ LANGUAGE plperl;
+
+select returns_array();
+</programlisting>
+ </para>
+
+ <para>
+ Perl passes <productname>PostgreSQL</productname> arrays as a blessed
+ <type>PostgreSQL::InServer::ARRAY</type> object. This object may be treated as an array
+ reference or a string, allowing for backward compatibility with Perl
+ code written for <productname>PostgreSQL</productname> versions below 9.1 to
+ run. For example:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION concat_array_elements(text[]) RETURNS TEXT AS $$
+ my $arg = shift;
+ my $result = "";
+ return undef if (!defined $arg);
+
+ # as an array reference
+ for (@$arg) {
+ $result .= $_;
+ }
+
+ # also works as a string
+ $result .= $arg;
+
+ return $result;
+$$ LANGUAGE plperl;
+
+SELECT concat_array_elements(ARRAY['PL','/','Perl']);
+</programlisting>
+
+ <note>
+ <para>
+ Multidimensional arrays are represented as references to
+ lower-dimensional arrays of references in a way common to every Perl
+ programmer.
+ </para>
+ </note>
+ </para>
+
+ <para>
+ Composite-type arguments are passed to the function as references
+ to hashes. The keys of the hash are the attribute names of the
+ composite type. Here is an example:
+
+<programlisting>
+CREATE TABLE employee (
+ name text,
+ basesalary integer,
+ bonus integer
+);
+
+CREATE FUNCTION empcomp(employee) RETURNS integer AS $$
+ my ($emp) = @_;
+ return $emp-&gt;{basesalary} + $emp-&gt;{bonus};
+$$ LANGUAGE plperl;
+
+SELECT name, empcomp(employee.*) FROM employee;
+</programlisting>
+ </para>
+
+ <para>
+ A PL/Perl function can return a composite-type result using the same
+ approach: return a reference to a hash that has the required attributes.
+ For example:
+
+<programlisting>
+CREATE TYPE testrowperl AS (f1 integer, f2 text, f3 text);
+
+CREATE OR REPLACE FUNCTION perl_row() RETURNS testrowperl AS $$
+ return {f2 =&gt; 'hello', f1 =&gt; 1, f3 =&gt; 'world'};
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_row();
+</programlisting>
+
+ Any columns in the declared result data type that are not present in the
+ hash will be returned as null values.
+ </para>
+
+ <para>
+ Similarly, output arguments of procedures can be returned as a hash
+ reference:
+
+<programlisting>
+CREATE PROCEDURE perl_triple(INOUT a integer, INOUT b integer) AS $$
+ my ($a, $b) = @_;
+ return {a =&gt; $a * 3, b =&gt; $b * 3};
+$$ LANGUAGE plperl;
+
+CALL perl_triple(5, 10);
+</programlisting>
+ </para>
+
+ <para>
+ PL/Perl functions can also return sets of either scalar or
+ composite types. Usually you'll want to return rows one at a
+ time, both to speed up startup time and to keep from queuing up
+ the entire result set in memory. You can do this with
+ <function>return_next</function> as illustrated below. Note that
+ after the last <function>return_next</function>, you must put
+ either <literal>return</literal> or (better) <literal>return
+ undef</literal>.
+
+<programlisting>
+CREATE OR REPLACE FUNCTION perl_set_int(int)
+RETURNS SETOF INTEGER AS $$
+ foreach (0..$_[0]) {
+ return_next($_);
+ }
+ return undef;
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set_int(5);
+
+CREATE OR REPLACE FUNCTION perl_set()
+RETURNS SETOF testrowperl AS $$
+ return_next({ f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' });
+ return_next({ f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' });
+ return_next({ f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' });
+ return undef;
+$$ LANGUAGE plperl;
+</programlisting>
+
+ For small result sets, you can return a reference to an array that
+ contains either scalars, references to arrays, or references to
+ hashes for simple types, array types, and composite types,
+ respectively. Here are some simple examples of returning the entire
+ result set as an array reference:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION perl_set_int(int) RETURNS SETOF INTEGER AS $$
+ return [0..$_[0]];
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set_int(5);
+
+CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
+ return [
+ { f1 =&gt; 1, f2 =&gt; 'Hello', f3 =&gt; 'World' },
+ { f1 =&gt; 2, f2 =&gt; 'Hello', f3 =&gt; 'PostgreSQL' },
+ { f1 =&gt; 3, f2 =&gt; 'Hello', f3 =&gt; 'PL/Perl' }
+ ];
+$$ LANGUAGE plperl;
+
+SELECT * FROM perl_set();
+</programlisting>
+ </para>
+
+ <para>
+ If you wish to use the <literal>strict</literal> pragma with your code you
+ have a few options. For temporary global use you can <command>SET</command>
+ <literal>plperl.use_strict</literal> to true.
+ This will affect subsequent compilations of <application>PL/Perl</application>
+ functions, but not functions already compiled in the current session.
+ For permanent global use you can set <literal>plperl.use_strict</literal>
+ to true in the <filename>postgresql.conf</filename> file.
+ </para>
+
+ <para>
+ For permanent use in specific functions you can simply put:
+<programlisting>
+use strict;
+</programlisting>
+ at the top of the function body.
+ </para>
+
+ <para>
+ The <literal>feature</literal> pragma is also available to <function>use</function> if your Perl is version 5.10.0 or higher.
+ </para>
+
+ </sect1>
+
+ <sect1 id="plperl-data">
+ <title>Data Values in PL/Perl</title>
+
+ <para>
+ The argument values supplied to a PL/Perl function's code are
+ simply the input arguments converted to text form (just as if they
+ had been displayed by a <command>SELECT</command> statement).
+ Conversely, the <function>return</function> and <function>return_next</function>
+ commands will accept any string that is acceptable input format
+ for the function's declared return type.
+ </para>
+
+ <para>
+ If this behavior is inconvenient for a particular case, it can be
+ improved by using a transform, as already illustrated
+ for <type>bool</type> values. Several examples of transform modules
+ are included in the <productname>PostgreSQL</productname> distribution.
+ </para>
+ </sect1>
+
+ <sect1 id="plperl-builtins">
+ <title>Built-in Functions</title>
+
+ <sect2 id="plperl-database">
+ <title>Database Access from PL/Perl</title>
+
+ <para>
+ Access to the database itself from your Perl function can be done
+ via the following functions:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal><function>spi_exec_query</function>(<replaceable>query</replaceable> [, <replaceable>limit</replaceable>])</literal>
+ <indexterm>
+ <primary>spi_exec_query</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ <function>spi_exec_query</function> executes an SQL command and
+returns the entire row set as a reference to an array of hash references.
+If <replaceable>limit</replaceable> is specified and is greater than zero,
+then <function>spi_exec_query</function> retrieves at
+most <replaceable>limit</replaceable> rows, much as if the query included
+a <literal>LIMIT</literal> clause. Omitting <replaceable>limit</replaceable>
+or specifying it as zero results in no row limit.
+ </para>
+
+ <para>
+<emphasis>You should only use this command when you know
+that the result set will be relatively small.</emphasis> Here is an
+example of a query (<command>SELECT</command> command) with the
+optional maximum number of rows:
+
+<programlisting>
+$rv = spi_exec_query('SELECT * FROM my_table', 5);
+</programlisting>
+ This returns up to 5 rows from the table
+ <literal>my_table</literal>. If <literal>my_table</literal>
+ has a column <literal>my_column</literal>, you can get that
+ value from row <literal>$i</literal> of the result like this:
+<programlisting>
+$foo = $rv-&gt;{rows}[$i]-&gt;{my_column};
+</programlisting>
+ The total number of rows returned from a <command>SELECT</command>
+ query can be accessed like this:
+<programlisting>
+$nrows = $rv-&gt;{processed}
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example using a different command type:
+<programlisting>
+$query = "INSERT INTO my_table VALUES (1, 'test')";
+$rv = spi_exec_query($query);
+</programlisting>
+ You can then access the command status (e.g.,
+ <literal>SPI_OK_INSERT</literal>) like this:
+<programlisting>
+$res = $rv-&gt;{status};
+</programlisting>
+ To get the number of rows affected, do:
+<programlisting>
+$nrows = $rv-&gt;{processed};
+</programlisting>
+ </para>
+
+ <para>
+ Here is a complete example:
+<programlisting>
+CREATE TABLE test (
+ i int,
+ v varchar
+);
+
+INSERT INTO test (i, v) VALUES (1, 'first line');
+INSERT INTO test (i, v) VALUES (2, 'second line');
+INSERT INTO test (i, v) VALUES (3, 'third line');
+INSERT INTO test (i, v) VALUES (4, 'immortal');
+
+CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$
+ my $rv = spi_exec_query('select i, v from test;');
+ my $status = $rv-&gt;{status};
+ my $nrows = $rv-&gt;{processed};
+ foreach my $rn (0 .. $nrows - 1) {
+ my $row = $rv-&gt;{rows}[$rn];
+ $row-&gt;{i} += 200 if defined($row-&gt;{i});
+ $row-&gt;{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row-&gt;{v}));
+ return_next($row);
+ }
+ return undef;
+$$ LANGUAGE plperl;
+
+SELECT * FROM test_munge();
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>spi_query(<replaceable>command</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_query</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>spi_fetchrow(<replaceable>cursor</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_fetchrow</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>spi_cursor_close(<replaceable>cursor</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_cursor_close</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <literal>spi_query</literal> and <literal>spi_fetchrow</literal>
+ work together as a pair for row sets which might be large, or for cases
+ where you wish to return rows as they arrive.
+ <literal>spi_fetchrow</literal> works <emphasis>only</emphasis> with
+ <literal>spi_query</literal>. The following example illustrates how
+ you use them together:
+
+<programlisting>
+CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);
+
+CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
+ use Digest::MD5 qw(md5_hex);
+ my $file = '/usr/share/dict/words';
+ my $t = localtime;
+ elog(NOTICE, "opening file $file at $t" );
+ open my $fh, '&lt;', $file # ooh, it's a file access!
+ or elog(ERROR, "cannot open $file for reading: $!");
+ my @words = &lt;$fh&gt;;
+ close $fh;
+ $t = localtime;
+ elog(NOTICE, "closed file $file at $t");
+ chomp(@words);
+ my $row;
+ my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
+ while (defined ($row = spi_fetchrow($sth))) {
+ return_next({
+ the_num =&gt; $row-&gt;{a},
+ the_text =&gt; md5_hex($words[rand @words])
+ });
+ }
+ return;
+$$ LANGUAGE plperlu;
+
+SELECT * from lotsa_md5(500);
+</programlisting>
+ </para>
+
+ <para>
+ Normally, <function>spi_fetchrow</function> should be repeated until it
+ returns <literal>undef</literal>, indicating that there are no more
+ rows to read. The cursor returned by <literal>spi_query</literal>
+ is automatically freed when
+ <function>spi_fetchrow</function> returns <literal>undef</literal>.
+ If you do not wish to read all the rows, instead call
+ <function>spi_cursor_close</function> to free the cursor.
+ Failure to do so will result in memory leaks.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>spi_prepare(<replaceable>command</replaceable>, <replaceable>argument types</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_prepare</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>spi_query_prepared(<replaceable>plan</replaceable>, <replaceable>arguments</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_query_prepared</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>spi_exec_prepared(<replaceable>plan</replaceable> [, <replaceable>attributes</replaceable>], <replaceable>arguments</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_exec_prepared</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>spi_freeplan(<replaceable>plan</replaceable>)</function></literal>
+ <indexterm>
+ <primary>spi_freeplan</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ <literal>spi_prepare</literal>, <literal>spi_query_prepared</literal>, <literal>spi_exec_prepared</literal>,
+ and <literal>spi_freeplan</literal> implement the same functionality but for prepared queries.
+ <literal>spi_prepare</literal> accepts a query string with numbered argument placeholders ($1, $2, etc.)
+ and a string list of argument types:
+<programlisting>
+$plan = spi_prepare('SELECT * FROM test WHERE id &gt; $1 AND name = $2',
+ 'INTEGER', 'TEXT');
+</programlisting>
+ Once a query plan is prepared by a call to <literal>spi_prepare</literal>, the plan can be used instead
+ of the string query, either in <literal>spi_exec_prepared</literal>, where the result is the same as returned
+ by <literal>spi_exec_query</literal>, or in <literal>spi_query_prepared</literal> which returns a cursor
+ exactly as <literal>spi_query</literal> does, which can be later passed to <literal>spi_fetchrow</literal>.
+ The optional second parameter to <literal>spi_exec_prepared</literal> is a hash reference of attributes;
+ the only attribute currently supported is <literal>limit</literal>, which
+ sets the maximum number of rows returned from the query.
+ Omitting <literal>limit</literal> or specifying it as zero results in no
+ row limit.
+ </para>
+
+ <para>
+ The advantage of prepared queries is that is it possible to use one prepared plan for more
+ than one query execution. After the plan is not needed anymore, it can be freed with
+ <literal>spi_freeplan</literal>:
+<programlisting>
+CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$
+ $_SHARED{my_plan} = spi_prepare('SELECT (now() + $1)::date AS now',
+ 'INTERVAL');
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
+ return spi_exec_prepared(
+ $_SHARED{my_plan},
+ $_[0]
+ )->{rows}->[0]->{now};
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$
+ spi_freeplan( $_SHARED{my_plan});
+ undef $_SHARED{my_plan};
+$$ LANGUAGE plperl;
+
+SELECT init();
+SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
+SELECT done();
+
+ add_time | add_time | add_time
+------------+------------+------------
+ 2005-12-10 | 2005-12-11 | 2005-12-12
+</programlisting>
+ Note that the parameter subscript in <literal>spi_prepare</literal> is defined via
+ $1, $2, $3, etc., so avoid declaring query strings in double quotes that might easily
+ lead to hard-to-catch bugs.
+ </para>
+
+ <para>
+ Another example illustrates usage of an optional parameter in <literal>spi_exec_prepared</literal>:
+<programlisting>
+CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address
+ FROM generate_series(1,3) AS id;
+
+CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$
+ $_SHARED{plan} = spi_prepare('SELECT * FROM hosts
+ WHERE address &lt;&lt; $1', 'inet');
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$
+ return spi_exec_prepared(
+ $_SHARED{plan},
+ {limit =&gt; 2},
+ $_[0]
+ )->{rows};
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION release_hosts_query() RETURNS VOID AS $$
+ spi_freeplan($_SHARED{plan});
+ undef $_SHARED{plan};
+$$ LANGUAGE plperl;
+
+SELECT init_hosts_query();
+SELECT query_hosts('192.168.1.0/30');
+SELECT release_hosts_query();
+
+ query_hosts
+-----------------
+ (1,192.168.1.1)
+ (2,192.168.1.2)
+(2 rows)
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>spi_commit()</function></literal>
+ <indexterm>
+ <primary>spi_commit</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>spi_rollback()</function></literal>
+ <indexterm>
+ <primary>spi_rollback</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Commit or roll back the current transaction. This can only be called
+ in a procedure or anonymous code block (<command>DO</command> command)
+ called from the top level. (Note that it is not possible to run the
+ SQL commands <command>COMMIT</command> or <command>ROLLBACK</command>
+ via <function>spi_exec_query</function> or similar. It has to be done
+ using these functions.) After a transaction is ended, a new
+ transaction is automatically started, so there is no separate function
+ for that.
+ </para>
+
+ <para>
+ Here is an example:
+<programlisting>
+CREATE PROCEDURE transaction_test1()
+LANGUAGE plperl
+AS $$
+foreach my $i (0..9) {
+ spi_exec_query("INSERT INTO test1 (a) VALUES ($i)");
+ if ($i % 2 == 0) {
+ spi_commit();
+ } else {
+ spi_rollback();
+ }
+}
+$$;
+
+CALL transaction_test1();
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="plperl-utility-functions">
+ <title>Utility Functions in PL/Perl</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <literal><function>elog(<replaceable>level</replaceable>, <replaceable>msg</replaceable>)</function></literal>
+ <indexterm>
+ <primary>elog</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Emit a log or error message. Possible levels are
+ <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>,
+ <literal>NOTICE</literal>, <literal>WARNING</literal>, and <literal>ERROR</literal>.
+ <literal>ERROR</literal>
+ raises an error condition; if this is not trapped by the surrounding
+ Perl code, the error propagates out to the calling query, causing
+ the current transaction or subtransaction to be aborted. This
+ is effectively the same as the Perl <literal>die</literal> command.
+ The other levels only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <xref linkend="guc-log-min-messages"/> and
+ <xref linkend="guc-client-min-messages"/> configuration
+ variables. See <xref linkend="runtime-config"/> for more
+ information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>quote_literal(<replaceable>string</replaceable>)</function></literal>
+ <indexterm>
+ <primary>quote_literal</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Return the given string suitably quoted to be used as a string literal in an SQL
+ statement string. Embedded single-quotes and backslashes are properly doubled.
+ Note that <function>quote_literal</function> returns undef on undef input; if the argument
+ might be undef, <function>quote_nullable</function> is often more suitable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>quote_nullable(<replaceable>string</replaceable>)</function></literal>
+ <indexterm>
+ <primary>quote_nullable</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Return the given string suitably quoted to be used as a string literal in an SQL
+ statement string; or, if the argument is undef, return the unquoted string "NULL".
+ Embedded single-quotes and backslashes are properly doubled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>quote_ident(<replaceable>string</replaceable>)</function></literal>
+ <indexterm>
+ <primary>quote_ident</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Return the given string suitably quoted to be used as an identifier in
+ an SQL statement string. Quotes are added only if necessary (i.e., if
+ the string contains non-identifier characters or would be case-folded).
+ Embedded quotes are properly doubled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>decode_bytea(<replaceable>string</replaceable>)</function></literal>
+ <indexterm>
+ <primary>decode_bytea</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Return the unescaped binary data represented by the contents of the given string,
+ which should be <type>bytea</type> encoded.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>encode_bytea(<replaceable>string</replaceable>)</function></literal>
+ <indexterm>
+ <primary>encode_bytea</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Return the <type>bytea</type> encoded form of the binary data contents of the given string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>encode_array_literal(<replaceable>array</replaceable>)</function></literal>
+ <indexterm>
+ <primary>encode_array_literal</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <term>
+ <literal><function>encode_array_literal(<replaceable>array</replaceable>, <replaceable>delimiter</replaceable>)</function></literal>
+ </term>
+ <listitem>
+ <para>
+ Returns the contents of the referenced array as a string in array literal format
+ (see <xref linkend="arrays-input"/>).
+ Returns the argument value unaltered if it's not a reference to an array.
+ The delimiter used between elements of the array literal defaults to "<literal>, </literal>"
+ if a delimiter is not specified or is undef.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>encode_typed_literal(<replaceable>value</replaceable>, <replaceable>typename</replaceable>)</function></literal>
+ <indexterm>
+ <primary>encode_typed_literal</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Converts a Perl variable to the value of the data type passed as a
+ second argument and returns a string representation of this value.
+ Correctly handles nested arrays and values of composite types.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>encode_array_constructor(<replaceable>array</replaceable>)</function></literal>
+ <indexterm>
+ <primary>encode_array_constructor</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns the contents of the referenced array as a string in array constructor format
+ (see <xref linkend="sql-syntax-array-constructors"/>).
+ Individual values are quoted using <function>quote_nullable</function>.
+ Returns the argument value, quoted using <function>quote_nullable</function>,
+ if it's not a reference to an array.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>looks_like_number(<replaceable>string</replaceable>)</function></literal>
+ <indexterm>
+ <primary>looks_like_number</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns a true value if the content of the given string looks like a
+ number, according to Perl, returns false otherwise.
+ Returns undef if the argument is undef. Leading and trailing space is
+ ignored. <literal>Inf</literal> and <literal>Infinity</literal> are regarded as numbers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal><function>is_array_ref(<replaceable>argument</replaceable>)</function></literal>
+ <indexterm>
+ <primary>is_array_ref</primary>
+ <secondary>in PL/Perl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns a true value if the given argument may be treated as an
+ array reference, that is, if ref of the argument is <literal>ARRAY</literal> or
+ <literal>PostgreSQL::InServer::ARRAY</literal>. Returns false otherwise.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plperl-global">
+ <title>Global Values in PL/Perl</title>
+
+ <para>
+ You can use the global hash <varname>%_SHARED</varname> to store
+ data, including code references, between function calls for the
+ lifetime of the current session.
+ </para>
+
+ <para>
+ Here is a simple example for shared data:
+<programlisting>
+CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$
+ if ($_SHARED{$_[0]} = $_[1]) {
+ return 'ok';
+ } else {
+ return "cannot set shared variable $_[0] to $_[1]";
+ }
+$$ LANGUAGE plperl;
+
+CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$
+ return $_SHARED{$_[0]};
+$$ LANGUAGE plperl;
+
+SELECT set_var('sample', 'Hello, PL/Perl! How''s tricks?');
+SELECT get_var('sample');
+</programlisting>
+ </para>
+
+ <para>
+ Here is a slightly more complicated example using a code reference:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$
+ $_SHARED{myquote} = sub {
+ my $arg = shift;
+ $arg =~ s/(['\\])/\\$1/g;
+ return "'$arg'";
+ };
+$$ LANGUAGE plperl;
+
+SELECT myfuncs(); /* initializes the function */
+
+/* Set up a function that uses the quote function */
+
+CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$
+ my $text_to_quote = shift;
+ my $qfunc = $_SHARED{myquote};
+ return &amp;$qfunc($text_to_quote);
+$$ LANGUAGE plperl;
+</programlisting>
+
+ (You could have replaced the above with the one-liner
+ <literal>return $_SHARED{myquote}-&gt;($_[0]);</literal>
+ at the expense of readability.)
+ </para>
+
+ <para>
+ For security reasons, PL/Perl executes functions called by any one SQL role
+ in a separate Perl interpreter for that role. This prevents accidental or
+ malicious interference by one user with the behavior of another user's
+ PL/Perl functions. Each such interpreter has its own value of the
+ <varname>%_SHARED</varname> variable and other global state. Thus, two
+ PL/Perl functions will share the same value of <varname>%_SHARED</varname>
+ if and only if they are executed by the same SQL role. In an application
+ wherein a single session executes code under multiple SQL roles (via
+ <literal>SECURITY DEFINER</literal> functions, use of <command>SET ROLE</command>, etc.)
+ you may need to take explicit steps to ensure that PL/Perl functions can
+ share data via <varname>%_SHARED</varname>. To do that, make sure that
+ functions that should communicate are owned by the same user, and mark
+ them <literal>SECURITY DEFINER</literal>. You must of course take care that
+ such functions can't be used to do anything unintended.
+ </para>
+ </sect1>
+
+ <sect1 id="plperl-trusted">
+ <title>Trusted and Untrusted PL/Perl</title>
+
+ <indexterm zone="plperl-trusted">
+ <primary>trusted</primary>
+ <secondary>PL/Perl</secondary>
+ </indexterm>
+
+ <para>
+ Normally, PL/Perl is installed as a <quote>trusted</quote> programming
+ language named <literal>plperl</literal>. In this setup, certain Perl
+ operations are disabled to preserve security. In general, the
+ operations that are restricted are those that interact with the
+ environment. This includes file handle operations,
+ <literal>require</literal>, and <literal>use</literal> (for
+ external modules). There is no way to access internals of the
+ database server process or to gain OS-level access with the
+ permissions of the server process,
+ as a C function can do. Thus, any unprivileged database user can
+ be permitted to use this language.
+ </para>
+
+ <para>
+ Here is an example of a function that will not work because file
+ system operations are not allowed for security reasons:
+<programlisting>
+CREATE FUNCTION badfunc() RETURNS integer AS $$
+ my $tmpfile = "/tmp/badfile";
+ open my $fh, '&gt;', $tmpfile
+ or elog(ERROR, qq{could not open the file "$tmpfile": $!});
+ print $fh "Testing writing to a file\n";
+ close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!});
+ return 1;
+$$ LANGUAGE plperl;
+</programlisting>
+ The creation of this function will fail as its use of a forbidden
+ operation will be caught by the validator.
+ </para>
+
+ <para>
+ Sometimes it is desirable to write Perl functions that are not
+ restricted. For example, one might want a Perl function that sends
+ mail. To handle these cases, PL/Perl can also be installed as an
+ <quote>untrusted</quote> language (usually called
+ <application>PL/PerlU</application><indexterm><primary>PL/PerlU</primary></indexterm>).
+ In this case the full Perl language is available. When installing the
+ language, the language name <literal>plperlu</literal> will select
+ the untrusted PL/Perl variant.
+ </para>
+
+ <para>
+ The writer of a <application>PL/PerlU</application> function must take care that the function
+ cannot be used to do anything unwanted, since it will be able to do
+ anything that could be done by a user logged in as the database
+ administrator. Note that the database system allows only database
+ superusers to create functions in untrusted languages.
+ </para>
+
+ <para>
+ If the above function was created by a superuser using the language
+ <literal>plperlu</literal>, execution would succeed.
+ </para>
+
+ <para>
+ In the same way, anonymous code blocks written in Perl can use
+ restricted operations if the language is specified as
+ <literal>plperlu</literal> rather than <literal>plperl</literal>, but the caller
+ must be a superuser.
+ </para>
+
+ <note>
+ <para>
+ While <application>PL/Perl</application> functions run in a separate Perl
+ interpreter for each SQL role, all <application>PL/PerlU</application> functions
+ executed in a given session run in a single Perl interpreter (which is
+ not any of the ones used for <application>PL/Perl</application> functions).
+ This allows <application>PL/PerlU</application> functions to share data freely,
+ but no communication can occur between <application>PL/Perl</application> and
+ <application>PL/PerlU</application> functions.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Perl cannot support multiple interpreters within one process unless
+ it was built with the appropriate flags, namely either
+ <literal>usemultiplicity</literal> or <literal>useithreads</literal>.
+ (<literal>usemultiplicity</literal> is preferred unless you actually need
+ to use threads. For more details, see the
+ <citerefentry><refentrytitle>perlembed</refentrytitle></citerefentry> man page.)
+ If <application>PL/Perl</application> is used with a copy of Perl that was not built
+ this way, then it is only possible to have one Perl interpreter per
+ session, and so any one session can only execute either
+ <application>PL/PerlU</application> functions, or <application>PL/Perl</application> functions
+ that are all called by the same SQL role.
+ </para>
+ </note>
+
+ </sect1>
+
+ <sect1 id="plperl-triggers">
+ <title>PL/Perl Triggers</title>
+
+ <para>
+ PL/Perl can be used to write trigger functions. In a trigger function,
+ the hash reference <varname>$_TD</varname> contains information about the
+ current trigger event. <varname>$_TD</varname> is a global variable,
+ which gets a separate local value for each invocation of the trigger.
+ The fields of the <varname>$_TD</varname> hash reference are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>$_TD-&gt;{new}{foo}</literal></term>
+ <listitem>
+ <para>
+ <literal>NEW</literal> value of column <literal>foo</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{old}{foo}</literal></term>
+ <listitem>
+ <para>
+ <literal>OLD</literal> value of column <literal>foo</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{name}</literal></term>
+ <listitem>
+ <para>
+ Name of the trigger being called
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{event}</literal></term>
+ <listitem>
+ <para>
+ Trigger event: <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, <literal>TRUNCATE</literal>, or <literal>UNKNOWN</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{when}</literal></term>
+ <listitem>
+ <para>
+ When the trigger was called: <literal>BEFORE</literal>,
+ <literal>AFTER</literal>, <literal>INSTEAD OF</literal>, or
+ <literal>UNKNOWN</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{level}</literal></term>
+ <listitem>
+ <para>
+ The trigger level: <literal>ROW</literal>, <literal>STATEMENT</literal>, or <literal>UNKNOWN</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{relid}</literal></term>
+ <listitem>
+ <para>
+ OID of the table on which the trigger fired
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{table_name}</literal></term>
+ <listitem>
+ <para>
+ Name of the table on which the trigger fired
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{relname}</literal></term>
+ <listitem>
+ <para>
+ Name of the table on which the trigger fired. This has been deprecated,
+ and could be removed in a future release.
+ Please use $_TD-&gt;{table_name} instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{table_schema}</literal></term>
+ <listitem>
+ <para>
+ Name of the schema in which the table on which the trigger fired, is
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{argc}</literal></term>
+ <listitem>
+ <para>
+ Number of arguments of the trigger function
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>@{$_TD-&gt;{args}}</literal></term>
+ <listitem>
+ <para>
+ Arguments of the trigger function. Does not exist if <literal>$_TD-&gt;{argc}</literal> is 0.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ Row-level triggers can return one of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>return;</literal></term>
+ <listitem>
+ <para>
+ Execute the operation
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>"SKIP"</literal></term>
+ <listitem>
+ <para>
+ Don't execute the operation
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>"MODIFY"</literal></term>
+ <listitem>
+ <para>
+ Indicates that the <literal>NEW</literal> row was modified by
+ the trigger function
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Here is an example of a trigger function, illustrating some of the
+ above:
+<programlisting>
+CREATE TABLE test (
+ i int,
+ v varchar
+);
+
+CREATE OR REPLACE FUNCTION valid_id() RETURNS trigger AS $$
+ if (($_TD-&gt;{new}{i} &gt;= 100) || ($_TD-&gt;{new}{i} &lt;= 0)) {
+ return "SKIP"; # skip INSERT/UPDATE command
+ } elsif ($_TD-&gt;{new}{v} ne "immortal") {
+ $_TD-&gt;{new}{v} .= "(modified by trigger)";
+ return "MODIFY"; # modify row and execute INSERT/UPDATE command
+ } else {
+ return; # execute INSERT/UPDATE command
+ }
+$$ LANGUAGE plperl;
+
+CREATE TRIGGER test_valid_id_trig
+ BEFORE INSERT OR UPDATE ON test
+ FOR EACH ROW EXECUTE FUNCTION valid_id();
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="plperl-event-triggers">
+ <title>PL/Perl Event Triggers</title>
+
+ <para>
+ PL/Perl can be used to write event trigger functions. In an event trigger
+ function, the hash reference <varname>$_TD</varname> contains information
+ about the current trigger event. <varname>$_TD</varname> is a global variable,
+ which gets a separate local value for each invocation of the trigger. The
+ fields of the <varname>$_TD</varname> hash reference are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>$_TD-&gt;{event}</literal></term>
+ <listitem>
+ <para>
+ The name of the event the trigger is fired for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>$_TD-&gt;{tag}</literal></term>
+ <listitem>
+ <para>
+ The command tag for which the trigger is fired.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The return value of the trigger function is ignored.
+ </para>
+
+ <para>
+ Here is an example of an event trigger function, illustrating some of the
+ above:
+<programlisting>
+CREATE OR REPLACE FUNCTION perlsnitch() RETURNS event_trigger AS $$
+ elog(NOTICE, "perlsnitch: " . $_TD->{event} . " " . $_TD->{tag} . " ");
+$$ LANGUAGE plperl;
+
+CREATE EVENT TRIGGER perl_a_snitch
+ ON ddl_command_start
+ EXECUTE FUNCTION perlsnitch();
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="plperl-under-the-hood">
+ <title>PL/Perl Under the Hood</title>
+
+ <sect2 id="plperl-config">
+ <title>Configuration</title>
+
+ <para>
+ This section lists configuration parameters that affect <application>PL/Perl</application>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-plperl-on-init" xreflabel="plperl.on_init">
+ <term>
+ <varname>plperl.on_init</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>plperl.on_init</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies Perl code to be executed when a Perl interpreter is first
+ initialized, before it is specialized for use by <literal>plperl</literal> or
+ <literal>plperlu</literal>.
+ The SPI functions are not available when this code is executed.
+ If the code fails with an error it will abort the initialization of
+ the interpreter and propagate out to the calling query, causing the
+ current transaction or subtransaction to be aborted.
+ </para>
+ <para>
+ The Perl code is limited to a single string. Longer code can be placed
+ into a module and loaded by the <literal>on_init</literal> string.
+ Examples:
+<programlisting>
+plperl.on_init = 'require "plperlinit.pl"'
+plperl.on_init = 'use lib "/my/app"; use MyApp::PgInit;'
+</programlisting>
+ </para>
+ <para>
+ Any modules loaded by <literal>plperl.on_init</literal>, either directly or
+ indirectly, will be available for use by <literal>plperl</literal>. This may
+ create a security risk. To see what modules have been loaded you can use:
+<programlisting>
+DO 'elog(WARNING, join ", ", sort keys %INC)' LANGUAGE plperl;
+</programlisting>
+ </para>
+ <para>
+ Initialization will happen in the postmaster if the <literal>plperl</literal> library is
+ included in <xref linkend="guc-shared-preload-libraries"/>, in which
+ case extra consideration should be given to the risk of destabilizing
+ the postmaster. The principal reason for making use of this feature
+ is that Perl modules loaded by <literal>plperl.on_init</literal> need be
+ loaded only at postmaster start, and will be instantly available
+ without loading overhead in individual database sessions. However,
+ keep in mind that the overhead is avoided only for the first Perl
+ interpreter used by a database session &mdash; either PL/PerlU, or
+ PL/Perl for the first SQL role that calls a PL/Perl function. Any
+ additional Perl interpreters created in a database session will have
+ to execute <literal>plperl.on_init</literal> afresh. Also, on Windows there
+ will be no savings whatsoever from preloading, since the Perl
+ interpreter created in the postmaster process does not propagate to
+ child processes.
+ </para>
+ <para>
+ This parameter can only be set in the <filename>postgresql.conf</filename> file or on the server command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-plperl-on-plperl-init" xreflabel="plperl.on_plperl_init">
+ <term>
+ <varname>plperl.on_plperl_init</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>plperl.on_plperl_init</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <term>
+ <varname>plperl.on_plperlu_init</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>plperl.on_plperlu_init</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ These parameters specify Perl code to be executed when a Perl
+ interpreter is specialized for <literal>plperl</literal> or
+ <literal>plperlu</literal> respectively. This will happen when a PL/Perl or
+ PL/PerlU function is first executed in a database session, or when
+ an additional interpreter has to be created because the other language
+ is called or a PL/Perl function is called by a new SQL role. This
+ follows any initialization done by <literal>plperl.on_init</literal>.
+ The SPI functions are not available when this code is executed.
+ The Perl code in <literal>plperl.on_plperl_init</literal> is executed after
+ <quote>locking down</quote> the interpreter, and thus it can only perform
+ trusted operations.
+ </para>
+ <para>
+ If the code fails with an error it will abort the initialization and
+ propagate out to the calling query, causing the current transaction or
+ subtransaction to be aborted. Any actions already done within Perl
+ won't be undone; however, that interpreter won't be used again.
+ If the language is used again the initialization will be attempted
+ again within a fresh Perl interpreter.
+ </para>
+ <para>
+ Only superusers can change these settings. Although these settings
+ can be changed within a session, such changes will not affect Perl
+ interpreters that have already been used to execute functions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-plperl-use-strict" xreflabel="plperl.use_strict">
+ <term>
+ <varname>plperl.use_strict</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>plperl.use_strict</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set true subsequent compilations of PL/Perl functions will have
+ the <literal>strict</literal> pragma enabled. This parameter does not affect
+ functions already compiled in the current session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+</sect2>
+
+ <sect2 id="plperl-missing">
+ <title>Limitations and Missing Features</title>
+
+ <para>
+ The following features are currently missing from PL/Perl, but they
+ would make welcome contributions.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ PL/Perl functions cannot call each other directly.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ SPI is not yet fully implemented.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you are fetching very large data sets using
+ <literal>spi_exec_query</literal>, you should be aware that
+ these will all go into memory. You can avoid this by using
+ <literal>spi_query</literal>/<literal>spi_fetchrow</literal> as
+ illustrated earlier.
+ </para>
+ <para>
+ A similar problem occurs if a set-returning function passes a
+ large set of rows back to PostgreSQL via <literal>return</literal>. You
+ can avoid this problem too by instead using
+ <literal>return_next</literal> for each row returned, as shown
+ previously.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When a session ends normally, not due to a fatal error, any
+ <literal>END</literal> blocks that have been defined are executed.
+ Currently no other actions are performed. Specifically,
+ file handles are not automatically flushed and objects are
+ not automatically destroyed.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
new file mode 100644
index 0000000..21cc7c6
--- /dev/null
+++ b/doc/src/sgml/plpgsql.sgml
@@ -0,0 +1,6092 @@
+<!-- doc/src/sgml/plpgsql.sgml -->
+
+<chapter id="plpgsql">
+ <title><application>PL/pgSQL</application> &mdash; <acronym>SQL</acronym> Procedural Language</title>
+
+ <indexterm zone="plpgsql">
+ <primary>PL/pgSQL</primary>
+ </indexterm>
+
+ <sect1 id="plpgsql-overview">
+ <title>Overview</title>
+
+ <para>
+ <application>PL/pgSQL</application> is a loadable procedural
+ language for the <productname>PostgreSQL</productname> database
+ system. The design goals of <application>PL/pgSQL</application> were to create
+ a loadable procedural language that
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ can be used to create functions, procedures, and triggers,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ adds control structures to the <acronym>SQL</acronym> language,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ can perform complex computations,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ inherits all user-defined types, functions, procedures, and operators,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ can be defined to be trusted by the server,
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ is easy to use.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Functions created with <application>PL/pgSQL</application> can be
+ used anywhere that built-in functions could be used.
+ For example, it is possible to
+ create complex conditional computation functions and later use
+ them to define operators or use them in index expressions.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname> 9.0 and later,
+ <application>PL/pgSQL</application> is installed by default.
+ However it is still a loadable module, so especially security-conscious
+ administrators could choose to remove it.
+ </para>
+
+ <sect2 id="plpgsql-advantages">
+ <title>Advantages of Using <application>PL/pgSQL</application></title>
+
+ <para>
+ <acronym>SQL</acronym> is the language <productname>PostgreSQL</productname>
+ and most other relational databases use as query language. It's
+ portable and easy to learn. But every <acronym>SQL</acronym>
+ statement must be executed individually by the database server.
+ </para>
+
+ <para>
+ That means that your client application must send each query to
+ the database server, wait for it to be processed, receive and
+ process the results, do some computation, then send further
+ queries to the server. All this incurs interprocess
+ communication and will also incur network overhead if your client
+ is on a different machine than the database server.
+ </para>
+
+ <para>
+ With <application>PL/pgSQL</application> you can group a block of
+ computation and a series of queries <emphasis>inside</emphasis>
+ the database server, thus having the power of a procedural
+ language and the ease of use of SQL, but with considerable
+ savings of client/server communication overhead.
+ </para>
+ <itemizedlist>
+
+ <listitem><para> Extra round trips between
+ client and server are eliminated </para></listitem>
+
+ <listitem><para> Intermediate results that the client does not
+ need do not have to be marshaled or transferred between server
+ and client </para></listitem>
+
+ <listitem><para> Multiple rounds of query
+ parsing can be avoided </para></listitem>
+
+ </itemizedlist>
+ <para> This can result in a considerable performance increase as
+ compared to an application that does not use stored functions.
+ </para>
+
+ <para>
+ Also, with <application>PL/pgSQL</application> you can use all
+ the data types, operators and functions of SQL.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-args-results">
+ <title>Supported Argument and Result Data Types</title>
+
+ <para>
+ Functions written in <application>PL/pgSQL</application> can accept
+ as arguments any scalar or array data type supported by the server,
+ and they can return a result of any of these types. They can also
+ accept or return any composite type (row type) specified by name.
+ It is also possible to declare a <application>PL/pgSQL</application>
+ function as accepting <type>record</type>, which means that any
+ composite type will do as input, or
+ as returning <type>record</type>, which means that the result
+ is a row type whose columns are determined by specification in the
+ calling query, as discussed in <xref linkend="queries-tablefunctions"/>.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> functions can be declared to accept a variable
+ number of arguments by using the <literal>VARIADIC</literal> marker. This
+ works exactly the same way as for SQL functions, as discussed in
+ <xref linkend="xfunc-sql-variadic-functions"/>.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> functions can also be declared to
+ accept and return the polymorphic types described in
+ <xref linkend="extend-types-polymorphic"/>, thus allowing the actual data
+ types handled by the function to vary from call to call.
+ Examples appear in <xref linkend="plpgsql-declaration-parameters"/>.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> functions can also be declared to return
+ a <quote>set</quote> (or table) of any data type that can be returned as
+ a single instance. Such a function generates its output by executing
+ <command>RETURN NEXT</command> for each desired element of the result
+ set, or by using <command>RETURN QUERY</command> to output the result of
+ evaluating a query.
+ </para>
+
+ <para>
+ Finally, a <application>PL/pgSQL</application> function can be declared to return
+ <type>void</type> if it has no useful return value. (Alternatively, it
+ could be written as a procedure in that case.)
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> functions can also be declared with output
+ parameters in place of an explicit specification of the return type.
+ This does not add any fundamental capability to the language, but
+ it is often convenient, especially for returning multiple values.
+ The <literal>RETURNS TABLE</literal> notation can also be used in place
+ of <literal>RETURNS SETOF</literal>.
+ </para>
+
+ <para>
+ Specific examples appear in
+ <xref linkend="plpgsql-declaration-parameters"/> and
+ <xref linkend="plpgsql-statements-returning"/>.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpgsql-structure">
+ <title>Structure of <application>PL/pgSQL</application></title>
+
+ <para>
+ Functions written in <application>PL/pgSQL</application> are defined
+ to the server by executing <xref linkend="sql-createfunction"/> commands.
+ Such a command would normally look like, say,
+<programlisting>
+CREATE FUNCTION somefunc(integer, text) RETURNS integer
+AS '<replaceable>function body text</replaceable>'
+LANGUAGE plpgsql;
+</programlisting>
+ The function body is simply a string literal so far as <command>CREATE
+ FUNCTION</command> is concerned. It is often helpful to use dollar quoting
+ (see <xref linkend="sql-syntax-dollar-quoting"/>) to write the function
+ body, rather than the normal single quote syntax. Without dollar quoting,
+ any single quotes or backslashes in the function body must be escaped by
+ doubling them. Almost all the examples in this chapter use dollar-quoted
+ literals for their function bodies.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> is a block-structured language.
+ The complete text of a function body must be a
+ <firstterm>block</firstterm>. A block is defined as:
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+<optional> DECLARE
+ <replaceable>declarations</replaceable> </optional>
+BEGIN
+ <replaceable>statements</replaceable>
+END <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+ </para>
+
+ <para>
+ Each declaration and each statement within a block is terminated
+ by a semicolon. A block that appears within another block must
+ have a semicolon after <literal>END</literal>, as shown above;
+ however the final <literal>END</literal> that
+ concludes a function body does not require a semicolon.
+ </para>
+
+ <tip>
+ <para>
+ A common mistake is to write a semicolon immediately after
+ <literal>BEGIN</literal>. This is incorrect and will result in a syntax error.
+ </para>
+ </tip>
+
+ <para>
+ A <replaceable>label</replaceable> is only needed if you want to
+ identify the block for use
+ in an <literal>EXIT</literal> statement, or to qualify the names of the
+ variables declared in the block. If a label is given after
+ <literal>END</literal>, it must match the label at the block's beginning.
+ </para>
+
+ <para>
+ All key words are case-insensitive.
+ Identifiers are implicitly converted to lower case
+ unless double-quoted, just as they are in ordinary SQL commands.
+ </para>
+
+ <para>
+ Comments work the same way in <application>PL/pgSQL</application> code as in
+ ordinary SQL. A double dash (<literal>--</literal>) starts a comment
+ that extends to the end of the line. A <literal>/*</literal> starts a
+ block comment that extends to the matching occurrence of
+ <literal>*/</literal>. Block comments nest.
+ </para>
+
+ <para>
+ Any statement in the statement section of a block
+ can be a <firstterm>subblock</firstterm>. Subblocks can be used for
+ logical grouping or to localize variables to a small group
+ of statements. Variables declared in a subblock mask any
+ similarly-named variables of outer blocks for the duration
+ of the subblock; but you can access the outer variables anyway
+ if you qualify their names with their block's label. For example:
+<programlisting>
+CREATE FUNCTION somefunc() RETURNS integer AS $$
+&lt;&lt; outerblock &gt;&gt;
+DECLARE
+ quantity integer := 30;
+BEGIN
+ RAISE NOTICE 'Quantity here is %', quantity; -- Prints 30
+ quantity := 50;
+ --
+ -- Create a subblock
+ --
+ DECLARE
+ quantity integer := 80;
+ BEGIN
+ RAISE NOTICE 'Quantity here is %', quantity; -- Prints 80
+ RAISE NOTICE 'Outer quantity here is %', outerblock.quantity; -- Prints 50
+ END;
+
+ RAISE NOTICE 'Quantity here is %', quantity; -- Prints 50
+
+ RETURN quantity;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ There is actually a hidden <quote>outer block</quote> surrounding the body
+ of any <application>PL/pgSQL</application> function. This block provides the
+ declarations of the function's parameters (if any), as well as some
+ special variables such as <literal>FOUND</literal> (see
+ <xref linkend="plpgsql-statements-diagnostics"/>). The outer block is
+ labeled with the function's name, meaning that parameters and special
+ variables can be qualified with the function's name.
+ </para>
+ </note>
+
+ <para>
+ It is important not to confuse the use of
+ <command>BEGIN</command>/<command>END</command> for grouping statements in
+ <application>PL/pgSQL</application> with the similarly-named SQL commands
+ for transaction
+ control. <application>PL/pgSQL</application>'s <command>BEGIN</command>/<command>END</command>
+ are only for grouping; they do not start or end a transaction.
+ See <xref linkend="plpgsql-transactions"/> for information on managing
+ transactions in <application>PL/pgSQL</application>.
+ Also, a block containing an <literal>EXCEPTION</literal> clause effectively
+ forms a subtransaction that can be rolled back without affecting the
+ outer transaction. For more about that see <xref
+ linkend="plpgsql-error-trapping"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="plpgsql-declarations">
+ <title>Declarations</title>
+
+ <para>
+ All variables used in a block must be declared in the
+ declarations section of the block.
+ (The only exceptions are that the loop variable of a <literal>FOR</literal> loop
+ iterating over a range of integer values is automatically declared as an
+ integer variable, and likewise the loop variable of a <literal>FOR</literal> loop
+ iterating over a cursor's result is automatically declared as a
+ record variable.)
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> variables can have any SQL data type, such as
+ <type>integer</type>, <type>varchar</type>, and
+ <type>char</type>.
+ </para>
+
+ <para>
+ Here are some examples of variable declarations:
+<programlisting>
+user_id integer;
+quantity numeric(5);
+url varchar;
+myrow tablename%ROWTYPE;
+myfield tablename.columnname%TYPE;
+arow RECORD;
+</programlisting>
+ </para>
+
+ <para>
+ The general syntax of a variable declaration is:
+<synopsis>
+<replaceable>name</replaceable> <optional> CONSTANT </optional> <replaceable>type</replaceable> <optional> COLLATE <replaceable>collation_name</replaceable> </optional> <optional> NOT NULL </optional> <optional> { DEFAULT | := | = } <replaceable>expression</replaceable> </optional>;
+</synopsis>
+ The <literal>DEFAULT</literal> clause, if given, specifies the initial value assigned
+ to the variable when the block is entered. If the <literal>DEFAULT</literal> clause
+ is not given then the variable is initialized to the
+ <acronym>SQL</acronym> null value.
+ The <literal>CONSTANT</literal> option prevents the variable from being
+ assigned to after initialization, so that its value will remain constant
+ for the duration of the block.
+ The <literal>COLLATE</literal> option specifies a collation to use for the
+ variable (see <xref linkend="plpgsql-declaration-collation"/>).
+ If <literal>NOT NULL</literal>
+ is specified, an assignment of a null value results in a run-time
+ error. All variables declared as <literal>NOT NULL</literal>
+ must have a nonnull default value specified.
+ Equal (<literal>=</literal>) can be used instead of PL/SQL-compliant
+ <literal>:=</literal>.
+ </para>
+
+ <para>
+ A variable's default value is evaluated and assigned to the variable
+ each time the block is entered (not just once per function call).
+ So, for example, assigning <literal>now()</literal> to a variable of type
+ <type>timestamp</type> causes the variable to have the
+ time of the current function call, not the time when the function was
+ precompiled.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+quantity integer DEFAULT 32;
+url varchar := 'http://mysite.com';
+transaction_time CONSTANT timestamp with time zone := now();
+</programlisting>
+ </para>
+
+ <para>
+ Once declared, a variable's value can be used in later initialization
+ expressions in the same block, for example:
+<programlisting>
+DECLARE
+ x integer := 1;
+ y integer := x + 1;
+</programlisting>
+ </para>
+
+ <sect2 id="plpgsql-declaration-parameters">
+ <title>Declaring Function Parameters</title>
+
+ <para>
+ Parameters passed to functions are named with the identifiers
+ <literal>$1</literal>, <literal>$2</literal>,
+ etc. Optionally, aliases can be declared for
+ <literal>$<replaceable>n</replaceable></literal>
+ parameter names for increased readability. Either the alias or the
+ numeric identifier can then be used to refer to the parameter value.
+ </para>
+
+ <para>
+ There are two ways to create an alias. The preferred way is to give a
+ name to the parameter in the <command>CREATE FUNCTION</command> command,
+ for example:
+<programlisting>
+CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
+BEGIN
+ RETURN subtotal * 0.06;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ The other way is to explicitly declare an alias, using the
+ declaration syntax
+
+<synopsis>
+<replaceable>name</replaceable> ALIAS FOR $<replaceable>n</replaceable>;
+</synopsis>
+
+ The same example in this style looks like:
+<programlisting>
+CREATE FUNCTION sales_tax(real) RETURNS real AS $$
+DECLARE
+ subtotal ALIAS FOR $1;
+BEGIN
+ RETURN subtotal * 0.06;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ These two examples are not perfectly equivalent. In the first case,
+ <literal>subtotal</literal> could be referenced as
+ <literal>sales_tax.subtotal</literal>, but in the second case it could not.
+ (Had we attached a label to the inner block, <literal>subtotal</literal> could
+ be qualified with that label, instead.)
+ </para>
+ </note>
+
+ <para>
+ Some more examples:
+<programlisting>
+CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$
+DECLARE
+ v_string ALIAS FOR $1;
+ index ALIAS FOR $2;
+BEGIN
+ -- some computations using v_string and index here
+END;
+$$ LANGUAGE plpgsql;
+
+
+CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURNS text AS $$
+BEGIN
+ RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ When a <application>PL/pgSQL</application> function is declared
+ with output parameters, the output parameters are given
+ <literal>$<replaceable>n</replaceable></literal> names and optional
+ aliases in just the same way as the normal input parameters. An
+ output parameter is effectively a variable that starts out NULL;
+ it should be assigned to during the execution of the function.
+ The final value of the parameter is what is returned. For instance,
+ the sales-tax example could also be done this way:
+
+<programlisting>
+CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
+BEGIN
+ tax := subtotal * 0.06;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ Notice that we omitted <literal>RETURNS real</literal> &mdash; we could have
+ included it, but it would be redundant.
+ </para>
+
+ <para>
+ To call a function with <literal>OUT</literal> parameters, omit the
+ output parameter(s) in the function call:
+<programlisting>
+SELECT sales_tax(100.00);
+</programlisting>
+ </para>
+
+ <para>
+ Output parameters are most useful when returning multiple values.
+ A trivial example is:
+
+<programlisting>
+CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$
+BEGIN
+ sum := x + y;
+ prod := x * y;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT * FROM sum_n_product(2, 4);
+ sum | prod
+-----+------
+ 6 | 8
+</programlisting>
+
+ As discussed in <xref linkend="xfunc-output-parameters"/>, this
+ effectively creates an anonymous record type for the function's
+ results. If a <literal>RETURNS</literal> clause is given, it must say
+ <literal>RETURNS record</literal>.
+ </para>
+
+ <para>
+ This also works with procedures, for example:
+
+<programlisting>
+CREATE PROCEDURE sum_n_product(x int, y int, OUT sum int, OUT prod int) AS $$
+BEGIN
+ sum := x + y;
+ prod := x * y;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ In a call to a procedure, all the parameters must be specified. For
+ output parameters, <literal>NULL</literal> may be specified when
+ calling the procedure from plain SQL:
+<programlisting>
+CALL sum_n_product(2, 4, NULL, NULL);
+ sum | prod
+-----+------
+ 6 | 8
+</programlisting>
+
+ However, when calling a procedure
+ from <application>PL/pgSQL</application>, you should instead write a
+ variable for any output parameter; the variable will receive the result
+ of the call. See <xref linkend="plpgsql-statements-calling-procedure"/>
+ for details.
+ </para>
+
+ <para>
+ Another way to declare a <application>PL/pgSQL</application> function
+ is with <literal>RETURNS TABLE</literal>, for example:
+
+<programlisting>
+CREATE FUNCTION extended_sales(p_itemno int)
+RETURNS TABLE(quantity int, total numeric) AS $$
+BEGIN
+ RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales AS s
+ WHERE s.itemno = p_itemno;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ This is exactly equivalent to declaring one or more <literal>OUT</literal>
+ parameters and specifying <literal>RETURNS SETOF
+ <replaceable>sometype</replaceable></literal>.
+ </para>
+
+ <para>
+ When the return type of a <application>PL/pgSQL</application> function
+ is declared as a polymorphic type (see
+ <xref linkend="extend-types-polymorphic"/>), a special
+ parameter <literal>$0</literal> is created. Its data type is the actual
+ return type of the function, as deduced from the actual input types.
+ This allows the function to access its actual return type
+ as shown in <xref linkend="plpgsql-declaration-type"/>.
+ <literal>$0</literal> is initialized to null and can be modified by
+ the function, so it can be used to hold the return value if desired,
+ though that is not required. <literal>$0</literal> can also be
+ given an alias. For example, this function works on any data type
+ that has a <literal>+</literal> operator:
+
+<programlisting>
+CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
+RETURNS anyelement AS $$
+DECLARE
+ result ALIAS FOR $0;
+BEGIN
+ result := v1 + v2 + v3;
+ RETURN result;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ The same effect can be obtained by declaring one or more output parameters as
+ polymorphic types. In this case the
+ special <literal>$0</literal> parameter is not used; the output
+ parameters themselves serve the same purpose. For example:
+
+<programlisting>
+CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement,
+ OUT sum anyelement)
+AS $$
+BEGIN
+ sum := v1 + v2 + v3;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ In practice it might be more useful to declare a polymorphic function
+ using the <type>anycompatible</type> family of types, so that automatic
+ promotion of the input arguments to a common type will occur.
+ For example:
+
+<programlisting>
+CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible)
+RETURNS anycompatible AS $$
+BEGIN
+ RETURN v1 + v2 + v3;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ With this example, a call such as
+
+<programlisting>
+SELECT add_three_values(1, 2, 4.7);
+</programlisting>
+
+ will work, automatically promoting the integer inputs to numeric.
+ The function using <type>anyelement</type> would require you to
+ cast the three inputs to the same type manually.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-declaration-alias">
+ <title><literal>ALIAS</literal></title>
+
+<synopsis>
+<replaceable>newname</replaceable> ALIAS FOR <replaceable>oldname</replaceable>;
+</synopsis>
+
+ <para>
+ The <literal>ALIAS</literal> syntax is more general than is suggested in the
+ previous section: you can declare an alias for any variable, not just
+ function parameters. The main practical use for this is to assign
+ a different name for variables with predetermined names, such as
+ <varname>NEW</varname> or <varname>OLD</varname> within
+ a trigger function.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+DECLARE
+ prior ALIAS FOR old;
+ updated ALIAS FOR new;
+</programlisting>
+ </para>
+
+ <para>
+ Since <literal>ALIAS</literal> creates two different ways to name the same
+ object, unrestricted use can be confusing. It's best to use it only
+ for the purpose of overriding predetermined names.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-declaration-type">
+ <title>Copying Types</title>
+
+<synopsis>
+<replaceable>variable</replaceable>%TYPE
+</synopsis>
+
+ <para>
+ <literal>%TYPE</literal> provides the data type of a variable or
+ table column. You can use this to declare variables that will hold
+ database values. For example, let's say you have a column named
+ <literal>user_id</literal> in your <literal>users</literal>
+ table. To declare a variable with the same data type as
+ <literal>users.user_id</literal> you write:
+<programlisting>
+user_id users.user_id%TYPE;
+</programlisting>
+ </para>
+
+ <para>
+ By using <literal>%TYPE</literal> you don't need to know the data
+ type of the structure you are referencing, and most importantly,
+ if the data type of the referenced item changes in the future (for
+ instance: you change the type of <literal>user_id</literal>
+ from <type>integer</type> to <type>real</type>), you might not need
+ to change your function definition.
+ </para>
+
+ <para>
+ <literal>%TYPE</literal> is particularly valuable in polymorphic
+ functions, since the data types needed for internal variables can
+ change from one call to the next. Appropriate variables can be
+ created by applying <literal>%TYPE</literal> to the function's
+ arguments or result placeholders.
+ </para>
+
+ </sect2>
+
+ <sect2 id="plpgsql-declaration-rowtypes">
+ <title>Row Types</title>
+
+<synopsis>
+<replaceable>name</replaceable> <replaceable>table_name</replaceable><literal>%ROWTYPE</literal>;
+<replaceable>name</replaceable> <replaceable>composite_type_name</replaceable>;
+</synopsis>
+
+ <para>
+ A variable of a composite type is called a <firstterm>row</firstterm>
+ variable (or <firstterm>row-type</firstterm> variable). Such a variable
+ can hold a whole row of a <command>SELECT</command> or <command>FOR</command>
+ query result, so long as that query's column set matches the
+ declared type of the variable.
+ The individual fields of the row value
+ are accessed using the usual dot notation, for example
+ <literal>rowvar.field</literal>.
+ </para>
+
+ <para>
+ A row variable can be declared to have the same type as the rows of
+ an existing table or view, by using the
+ <replaceable>table_name</replaceable><literal>%ROWTYPE</literal>
+ notation; or it can be declared by giving a composite type's name.
+ (Since every table has an associated composite type of the same name,
+ it actually does not matter in <productname>PostgreSQL</productname> whether you
+ write <literal>%ROWTYPE</literal> or not. But the form with
+ <literal>%ROWTYPE</literal> is more portable.)
+ </para>
+
+ <para>
+ Parameters to a function can be
+ composite types (complete table rows). In that case, the
+ corresponding identifier <literal>$<replaceable>n</replaceable></literal> will be a row variable, and fields can
+ be selected from it, for example <literal>$1.user_id</literal>.
+ </para>
+
+ <para>
+ Here is an example of using composite types. <structname>table1</structname>
+ and <structname>table2</structname> are existing tables having at least the
+ mentioned fields:
+
+<programlisting>
+CREATE FUNCTION merge_fields(t_row table1) RETURNS text AS $$
+DECLARE
+ t2_row table2%ROWTYPE;
+BEGIN
+ SELECT * INTO t2_row FROM table2 WHERE ... ;
+ RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT merge_fields(t.*) FROM table1 t WHERE ... ;
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-declaration-records">
+ <title>Record Types</title>
+
+<synopsis>
+<replaceable>name</replaceable> RECORD;
+</synopsis>
+
+ <para>
+ Record variables are similar to row-type variables, but they have no
+ predefined structure. They take on the actual row structure of the
+ row they are assigned during a <command>SELECT</command> or <command>FOR</command> command. The substructure
+ of a record variable can change each time it is assigned to.
+ A consequence of this is that until a record variable is first assigned
+ to, it has no substructure, and any attempt to access a
+ field in it will draw a run-time error.
+ </para>
+
+ <para>
+ Note that <literal>RECORD</literal> is not a true data type, only a placeholder.
+ One should also realize that when a <application>PL/pgSQL</application>
+ function is declared to return type <type>record</type>, this is not quite the
+ same concept as a record variable, even though such a function might
+ use a record variable to hold its result. In both cases the actual row
+ structure is unknown when the function is written, but for a function
+ returning <type>record</type> the actual structure is determined when the
+ calling query is parsed, whereas a record variable can change its row
+ structure on-the-fly.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-declaration-collation">
+ <title>Collation of <application>PL/pgSQL</application> Variables</title>
+
+ <indexterm>
+ <primary>collation</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ When a <application>PL/pgSQL</application> function has one or more
+ parameters of collatable data types, a collation is identified for each
+ function call depending on the collations assigned to the actual
+ arguments, as described in <xref linkend="collation"/>. If a collation is
+ successfully identified (i.e., there are no conflicts of implicit
+ collations among the arguments) then all the collatable parameters are
+ treated as having that collation implicitly. This will affect the
+ behavior of collation-sensitive operations within the function.
+ For example, consider
+
+<programlisting>
+CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
+BEGIN
+ RETURN a &lt; b;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT less_than(text_field_1, text_field_2) FROM table1;
+SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1;
+</programlisting>
+
+ The first use of <function>less_than</function> will use the common collation
+ of <structfield>text_field_1</structfield> and <structfield>text_field_2</structfield> for
+ the comparison, while the second use will use <literal>C</literal> collation.
+ </para>
+
+ <para>
+ Furthermore, the identified collation is also assumed as the collation of
+ any local variables that are of collatable types. Thus this function
+ would not work any differently if it were written as
+
+<programlisting>
+CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
+DECLARE
+ local_a text := a;
+ local_b text := b;
+BEGIN
+ RETURN local_a &lt; local_b;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ If there are no parameters of collatable data types, or no common
+ collation can be identified for them, then parameters and local variables
+ use the default collation of their data type (which is usually the
+ database's default collation, but could be different for variables of
+ domain types).
+ </para>
+
+ <para>
+ A local variable of a collatable data type can have a different collation
+ associated with it by including the <literal>COLLATE</literal> option in its
+ declaration, for example
+
+<programlisting>
+DECLARE
+ local_a text COLLATE "en_US";
+</programlisting>
+
+ This option overrides the collation that would otherwise be
+ given to the variable according to the rules above.
+ </para>
+
+ <para>
+ Also, of course explicit <literal>COLLATE</literal> clauses can be written inside
+ a function if it is desired to force a particular collation to be used in
+ a particular operation. For example,
+
+<programlisting>
+CREATE FUNCTION less_than_c(a text, b text) RETURNS boolean AS $$
+BEGIN
+ RETURN a &lt; b COLLATE "C";
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ This overrides the collations associated with the table columns,
+ parameters, or local variables used in the expression, just as would
+ happen in a plain SQL command.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpgsql-expressions">
+ <title>Expressions</title>
+
+ <para>
+ All expressions used in <application>PL/pgSQL</application>
+ statements are processed using the server's main
+ <acronym>SQL</acronym> executor. For example, when you write
+ a <application>PL/pgSQL</application> statement like
+<synopsis>
+IF <replaceable>expression</replaceable> THEN ...
+</synopsis>
+ <application>PL/pgSQL</application> will evaluate the expression by
+ feeding a query like
+<synopsis>
+SELECT <replaceable>expression</replaceable>
+</synopsis>
+ to the main SQL engine. While forming the <command>SELECT</command> command,
+ any occurrences of <application>PL/pgSQL</application> variable names
+ are replaced by query parameters, as discussed in detail in
+ <xref linkend="plpgsql-var-subst"/>.
+ This allows the query plan for the <command>SELECT</command> to
+ be prepared just once and then reused for subsequent
+ evaluations with different values of the variables. Thus, what
+ really happens on first use of an expression is essentially a
+ <command>PREPARE</command> command. For example, if we have declared
+ two integer variables <literal>x</literal> and <literal>y</literal>, and we write
+<programlisting>
+IF x &lt; y THEN ...
+</programlisting>
+ what happens behind the scenes is equivalent to
+<programlisting>
+PREPARE <replaceable>statement_name</replaceable>(integer, integer) AS SELECT $1 &lt; $2;
+</programlisting>
+ and then this prepared statement is <command>EXECUTE</command>d for each
+ execution of the <command>IF</command> statement, with the current values
+ of the <application>PL/pgSQL</application> variables supplied as
+ parameter values. Normally these details are
+ not important to a <application>PL/pgSQL</application> user, but
+ they are useful to know when trying to diagnose a problem.
+ More information appears in <xref linkend="plpgsql-plan-caching"/>.
+ </para>
+
+ <para>
+ Since an <replaceable>expression</replaceable> is converted to a
+ <literal>SELECT</literal> command, it can contain the same clauses
+ that an ordinary <literal>SELECT</literal> would, except that it
+ cannot include a top-level <literal>UNION</literal>,
+ <literal>INTERSECT</literal>, or <literal>EXCEPT</literal> clause.
+ Thus for example one could test whether a table is non-empty with
+<programlisting>
+IF count(*) &gt; 0 FROM my_table THEN ...
+</programlisting>
+ since the <replaceable>expression</replaceable>
+ between <literal>IF</literal> and <literal>THEN</literal> is parsed as
+ though it were <literal>SELECT count(*) &gt; 0 FROM my_table</literal>.
+ The <literal>SELECT</literal> must produce a single column, and not
+ more than one row. (If it produces no rows, the result is taken as
+ NULL.)
+ </para>
+ </sect1>
+
+ <sect1 id="plpgsql-statements">
+ <title>Basic Statements</title>
+
+ <para>
+ In this section and the following ones, we describe all the statement
+ types that are explicitly understood by
+ <application>PL/pgSQL</application>.
+ Anything not recognized as one of these statement types is presumed
+ to be an SQL command and is sent to the main database engine to execute,
+ as described in <xref linkend="plpgsql-statements-general-sql"/>.
+ </para>
+
+ <sect2 id="plpgsql-statements-assignment">
+ <title>Assignment</title>
+
+ <para>
+ An assignment of a value to a <application>PL/pgSQL</application>
+ variable is written as:
+<synopsis>
+<replaceable>variable</replaceable> { := | = } <replaceable>expression</replaceable>;
+</synopsis>
+ As explained previously, the expression in such a statement is evaluated
+ by means of an SQL <command>SELECT</command> command sent to the main
+ database engine. The expression must yield a single value (possibly
+ a row value, if the variable is a row or record variable). The target
+ variable can be a simple variable (optionally qualified with a block
+ name), a field of a row or record target, or an element or slice of
+ an array target. Equal (<literal>=</literal>) can be
+ used instead of PL/SQL-compliant <literal>:=</literal>.
+ </para>
+
+ <para>
+ If the expression's result data type doesn't match the variable's
+ data type, the value will be coerced as though by an assignment cast
+ (see <xref linkend="typeconv-query"/>). If no assignment cast is known
+ for the pair of data types involved, the <application>PL/pgSQL</application>
+ interpreter will attempt to convert the result value textually, that is
+ by applying the result type's output function followed by the variable
+ type's input function. Note that this could result in run-time errors
+ generated by the input function, if the string form of the result value
+ is not acceptable to the input function.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+tax := subtotal * 0.06;
+my_record.user_id := 20;
+my_array[j] := 20;
+my_array[1:3] := array[1,2,3];
+complex_array[n].realpart = 12.3;
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-statements-general-sql">
+ <title>Executing SQL Commands</title>
+
+ <para>
+ In general, any SQL command that does not return rows can be executed
+ within a <application>PL/pgSQL</application> function just by writing
+ the command. For example, you could create and fill a table by writing
+<programlisting>
+CREATE TABLE mytable (id int primary key, data text);
+INSERT INTO mytable VALUES (1,'one'), (2,'two');
+</programlisting>
+ </para>
+
+ <para>
+ If the command does return rows (for example <command>SELECT</command>,
+ or <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>
+ with <literal>RETURNING</literal>), there are two ways to proceed.
+ When the command will return at most one row, or you only care about
+ the first row of output, write the command as usual but add
+ an <literal>INTO</literal> clause to capture the output, as described
+ in <xref linkend="plpgsql-statements-sql-onerow"/>.
+ To process all of the output rows, write the command as the data
+ source for a <command>FOR</command> loop, as described in
+ <xref linkend="plpgsql-records-iterating"/>.
+ </para>
+
+ <para>
+ Usually it is not sufficient just to execute statically-defined SQL
+ commands. Typically you'll want a command to use varying data values,
+ or even to vary in more fundamental ways such as by using different
+ table names at different times. Again, there are two ways to proceed
+ depending on the situation.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> variable values can be
+ automatically inserted into optimizable SQL commands, which
+ are <command>SELECT</command>, <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>,
+ <command>MERGE</command>, and certain
+ utility commands that incorporate one of these, such
+ as <command>EXPLAIN</command> and <command>CREATE TABLE ... AS
+ SELECT</command>. In these commands,
+ any <application>PL/pgSQL</application> variable name appearing
+ in the command text is replaced by a query parameter, and then the
+ current value of the variable is provided as the parameter value
+ at run time. This is exactly like the processing described earlier
+ for expressions; for details see <xref linkend="plpgsql-var-subst"/>.
+ </para>
+
+ <para>
+ When executing an optimizable SQL command in this way,
+ <application>PL/pgSQL</application> may cache and re-use the execution
+ plan for the command, as discussed in
+ <xref linkend="plpgsql-plan-caching"/>.
+ </para>
+
+ <para>
+ Non-optimizable SQL commands (also called utility commands) are not
+ capable of accepting query parameters. So automatic substitution
+ of <application>PL/pgSQL</application> variables does not work in such
+ commands. To include non-constant text in a utility command executed
+ from <application>PL/pgSQL</application>, you must build the utility
+ command as a string and then <command>EXECUTE</command> it, as
+ discussed in <xref linkend="plpgsql-statements-executing-dyn"/>.
+ </para>
+
+ <para>
+ <command>EXECUTE</command> must also be used if you want to modify
+ the command in some other way than supplying a data value, for example
+ by changing a table name.
+ </para>
+
+ <para>
+ Sometimes it is useful to evaluate an expression or <command>SELECT</command>
+ query but discard the result, for example when calling a function
+ that has side-effects but no useful result value. To do
+ this in <application>PL/pgSQL</application>, use the
+ <command>PERFORM</command> statement:
+
+<synopsis>
+PERFORM <replaceable>query</replaceable>;
+</synopsis>
+
+ This executes <replaceable>query</replaceable> and discards the
+ result. Write the <replaceable>query</replaceable> the same
+ way you would write an SQL <command>SELECT</command> command, but replace the
+ initial keyword <command>SELECT</command> with <command>PERFORM</command>.
+ For <command>WITH</command> queries, use <command>PERFORM</command> and then
+ place the query in parentheses. (In this case, the query can only
+ return one row.)
+ <application>PL/pgSQL</application> variables will be
+ substituted into the query just as described above,
+ and the plan is cached in the same way. Also, the special variable
+ <literal>FOUND</literal> is set to true if the query produced at
+ least one row, or false if it produced no rows (see
+ <xref linkend="plpgsql-statements-diagnostics"/>).
+ </para>
+
+ <note>
+ <para>
+ One might expect that writing <command>SELECT</command> directly
+ would accomplish this result, but at
+ present the only accepted way to do it is
+ <command>PERFORM</command>. An SQL command that can return rows,
+ such as <command>SELECT</command>, will be rejected as an error
+ unless it has an <literal>INTO</literal> clause as discussed in the
+ next section.
+ </para>
+ </note>
+
+ <para>
+ An example:
+<programlisting>
+PERFORM create_mv('cs_session_page_requests_mv', my_query);
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-statements-sql-onerow">
+ <title>Executing a Command with a Single-Row Result</title>
+
+ <indexterm zone="plpgsql-statements-sql-onerow">
+ <primary>SELECT INTO</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm zone="plpgsql-statements-sql-onerow">
+ <primary>RETURNING INTO</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ The result of an SQL command yielding a single row (possibly of multiple
+ columns) can be assigned to a record variable, row-type variable, or list
+ of scalar variables. This is done by writing the base SQL command and
+ adding an <literal>INTO</literal> clause. For example,
+
+<synopsis>
+SELECT <replaceable>select_expressions</replaceable> INTO <optional>STRICT</optional> <replaceable>target</replaceable> FROM ...;
+INSERT ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRICT</optional> <replaceable>target</replaceable>;
+UPDATE ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRICT</optional> <replaceable>target</replaceable>;
+DELETE ... RETURNING <replaceable>expressions</replaceable> INTO <optional>STRICT</optional> <replaceable>target</replaceable>;
+</synopsis>
+
+ where <replaceable>target</replaceable> can be a record variable, a row
+ variable, or a comma-separated list of simple variables and
+ record/row fields.
+ <application>PL/pgSQL</application> variables will be
+ substituted into the rest of the command (that is, everything but the
+ <literal>INTO</literal> clause) just as described above,
+ and the plan is cached in the same way.
+ This works for <command>SELECT</command>,
+ <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> with
+ <literal>RETURNING</literal>, and certain utility commands
+ that return row sets, such as <command>EXPLAIN</command>.
+ Except for the <literal>INTO</literal> clause, the SQL command is the same
+ as it would be written outside <application>PL/pgSQL</application>.
+ </para>
+
+ <tip>
+ <para>
+ Note that this interpretation of <command>SELECT</command> with <literal>INTO</literal>
+ is quite different from <productname>PostgreSQL</productname>'s regular
+ <command>SELECT INTO</command> command, wherein the <literal>INTO</literal>
+ target is a newly created table. If you want to create a table from a
+ <command>SELECT</command> result inside a
+ <application>PL/pgSQL</application> function, use the syntax
+ <command>CREATE TABLE ... AS SELECT</command>.
+ </para>
+ </tip>
+
+ <para>
+ If a row variable or a variable list is used as target,
+ the command's result columns
+ must exactly match the structure of the target as to number and data
+ types, or else a run-time error
+ occurs. When a record variable is the target, it automatically
+ configures itself to the row type of the command's result columns.
+ </para>
+
+ <para>
+ The <literal>INTO</literal> clause can appear almost anywhere in the SQL
+ command. Customarily it is written either just before or just after
+ the list of <replaceable>select_expressions</replaceable> in a
+ <command>SELECT</command> command, or at the end of the command for other
+ command types. It is recommended that you follow this convention
+ in case the <application>PL/pgSQL</application> parser becomes
+ stricter in future versions.
+ </para>
+
+ <para>
+ If <literal>STRICT</literal> is not specified in the <literal>INTO</literal>
+ clause, then <replaceable>target</replaceable> will be set to the first
+ row returned by the command, or to nulls if the command returned no rows.
+ (Note that <quote>the first row</quote> is not
+ well-defined unless you've used <literal>ORDER BY</literal>.) Any result rows
+ after the first row are discarded.
+ You can check the special <literal>FOUND</literal> variable (see
+ <xref linkend="plpgsql-statements-diagnostics"/>) to
+ determine whether a row was returned:
+
+<programlisting>
+SELECT * INTO myrec FROM emp WHERE empname = myname;
+IF NOT FOUND THEN
+ RAISE EXCEPTION 'employee % not found', myname;
+END IF;
+</programlisting>
+
+ If the <literal>STRICT</literal> option is specified, the command must
+ return exactly one row or a run-time error will be reported, either
+ <literal>NO_DATA_FOUND</literal> (no rows) or <literal>TOO_MANY_ROWS</literal>
+ (more than one row). You can use an exception block if you wish
+ to catch the error, for example:
+
+<programlisting>
+BEGIN
+ SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
+ EXCEPTION
+ WHEN NO_DATA_FOUND THEN
+ RAISE EXCEPTION 'employee % not found', myname;
+ WHEN TOO_MANY_ROWS THEN
+ RAISE EXCEPTION 'employee % not unique', myname;
+END;
+</programlisting>
+ Successful execution of a command with <literal>STRICT</literal>
+ always sets <literal>FOUND</literal> to true.
+ </para>
+
+ <para>
+ For <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> with
+ <literal>RETURNING</literal>, <application>PL/pgSQL</application> reports
+ an error for more than one returned row, even when
+ <literal>STRICT</literal> is not specified. This is because there
+ is no option such as <literal>ORDER BY</literal> with which to determine
+ which affected row should be returned.
+ </para>
+
+ <para>
+ If <literal>print_strict_params</literal> is enabled for the function,
+ then when an error is thrown because the requirements
+ of <literal>STRICT</literal> are not met, the <literal>DETAIL</literal> part of
+ the error message will include information about the parameters
+ passed to the command.
+ You can change the <literal>print_strict_params</literal>
+ setting for all functions by setting
+ <varname>plpgsql.print_strict_params</varname>, though only subsequent
+ function compilations will be affected. You can also enable it
+ on a per-function basis by using a compiler option, for example:
+<programlisting>
+CREATE FUNCTION get_userid(username text) RETURNS int
+AS $$
+#print_strict_params on
+DECLARE
+userid int;
+BEGIN
+ SELECT users.userid INTO STRICT userid
+ FROM users WHERE users.username = get_userid.username;
+ RETURN userid;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ On failure, this function might produce an error message such as
+<programlisting>
+ERROR: query returned no rows
+DETAIL: parameters: $1 = 'nosuchuser'
+CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ The <literal>STRICT</literal> option matches the behavior of
+ Oracle PL/SQL's <command>SELECT INTO</command> and related statements.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="plpgsql-statements-executing-dyn">
+ <title>Executing Dynamic Commands</title>
+
+ <para>
+ Oftentimes you will want to generate dynamic commands inside your
+ <application>PL/pgSQL</application> functions, that is, commands
+ that will involve different tables or different data types each
+ time they are executed. <application>PL/pgSQL</application>'s
+ normal attempts to cache plans for commands (as discussed in
+ <xref linkend="plpgsql-plan-caching"/>) will not work in such
+ scenarios. To handle this sort of problem, the
+ <command>EXECUTE</command> statement is provided:
+
+<synopsis>
+EXECUTE <replaceable class="command">command-string</replaceable> <optional> INTO <optional>STRICT</optional> <replaceable>target</replaceable> </optional> <optional> USING <replaceable>expression</replaceable> <optional>, ... </optional> </optional>;
+</synopsis>
+
+ where <replaceable>command-string</replaceable> is an expression
+ yielding a string (of type <type>text</type>) containing the
+ command to be executed. The optional <replaceable>target</replaceable>
+ is a record variable, a row variable, or a comma-separated list of
+ simple variables and record/row fields, into which the results of
+ the command will be stored. The optional <literal>USING</literal> expressions
+ supply values to be inserted into the command.
+ </para>
+
+ <para>
+ No substitution of <application>PL/pgSQL</application> variables is done on the
+ computed command string. Any required variable values must be inserted
+ in the command string as it is constructed; or you can use parameters
+ as described below.
+ </para>
+
+ <para>
+ Also, there is no plan caching for commands executed via
+ <command>EXECUTE</command>. Instead, the command is always planned
+ each time the statement is run. Thus the command
+ string can be dynamically created within the function to perform
+ actions on different tables and columns.
+ </para>
+
+ <para>
+ The <literal>INTO</literal> clause specifies where the results of
+ an SQL command returning rows should be assigned. If a row variable
+ or variable list is provided, it must exactly match the structure
+ of the command's results; if a
+ record variable is provided, it will configure itself to match the
+ result structure automatically. If multiple rows are returned,
+ only the first will be assigned to the <literal>INTO</literal>
+ variable(s). If no rows are returned, NULL is assigned to the
+ <literal>INTO</literal> variable(s). If no <literal>INTO</literal>
+ clause is specified, the command results are discarded.
+ </para>
+
+ <para>
+ If the <literal>STRICT</literal> option is given, an error is reported
+ unless the command produces exactly one row.
+ </para>
+
+ <para>
+ The command string can use parameter values, which are referenced
+ in the command as <literal>$1</literal>, <literal>$2</literal>, etc.
+ These symbols refer to values supplied in the <literal>USING</literal>
+ clause. This method is often preferable to inserting data values
+ into the command string as text: it avoids run-time overhead of
+ converting the values to text and back, and it is much less prone
+ to SQL-injection attacks since there is no need for quoting or escaping.
+ An example is:
+<programlisting>
+EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted &lt;= $2'
+ INTO c
+ USING checked_user, checked_date;
+</programlisting>
+ </para>
+
+ <para>
+ Note that parameter symbols can only be used for data values
+ &mdash; if you want to use dynamically determined table or column
+ names, you must insert them into the command string textually.
+ For example, if the preceding query needed to be done against a
+ dynamically selected table, you could do this:
+<programlisting>
+EXECUTE 'SELECT count(*) FROM '
+ || quote_ident(tabname)
+ || ' WHERE inserted_by = $1 AND inserted &lt;= $2'
+ INTO c
+ USING checked_user, checked_date;
+</programlisting>
+ A cleaner approach is to use <function>format()</function>'s <literal>%I</literal>
+ specification to insert table or column names with automatic quoting:
+<programlisting>
+EXECUTE format('SELECT count(*) FROM %I '
+ 'WHERE inserted_by = $1 AND inserted &lt;= $2', tabname)
+ INTO c
+ USING checked_user, checked_date;
+</programlisting>
+ (This example relies on the SQL rule that string literals separated by a
+ newline are implicitly concatenated.)
+ </para>
+
+ <para>
+ Another restriction on parameter symbols is that they only work in
+ optimizable SQL commands
+ (<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, <command>MERGE</command>, and certain commands containing one of these).
+ In other statement
+ types (generically called utility statements), you must insert
+ values textually even if they are just data values.
+ </para>
+
+ <para>
+ An <command>EXECUTE</command> with a simple constant command string and some
+ <literal>USING</literal> parameters, as in the first example above, is
+ functionally equivalent to just writing the command directly in
+ <application>PL/pgSQL</application> and allowing replacement of
+ <application>PL/pgSQL</application> variables to happen automatically.
+ The important difference is that <command>EXECUTE</command> will re-plan
+ the command on each execution, generating a plan that is specific
+ to the current parameter values; whereas
+ <application>PL/pgSQL</application> may otherwise create a generic plan
+ and cache it for re-use. In situations where the best plan depends
+ strongly on the parameter values, it can be helpful to use
+ <command>EXECUTE</command> to positively ensure that a generic plan is not
+ selected.
+ </para>
+
+ <para>
+ <command>SELECT INTO</command> is not currently supported within
+ <command>EXECUTE</command>; instead, execute a plain <command>SELECT</command>
+ command and specify <literal>INTO</literal> as part of the <command>EXECUTE</command>
+ itself.
+ </para>
+
+ <note>
+ <para>
+ The <application>PL/pgSQL</application>
+ <command>EXECUTE</command> statement is not related to the
+ <link linkend="sql-execute"><command>EXECUTE</command></link> SQL
+ statement supported by the
+ <productname>PostgreSQL</productname> server. The server's
+ <command>EXECUTE</command> statement cannot be used directly within
+ <application>PL/pgSQL</application> functions (and is not needed).
+ </para>
+ </note>
+
+ <example id="plpgsql-quote-literal-example">
+ <title>Quoting Values in Dynamic Queries</title>
+
+ <indexterm>
+ <primary>quote_ident</primary>
+ <secondary>use in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>quote_literal</primary>
+ <secondary>use in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>quote_nullable</primary>
+ <secondary>use in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>format</primary>
+ <secondary>use in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ When working with dynamic commands you will often have to handle escaping
+ of single quotes. The recommended method for quoting fixed text in your
+ function body is dollar quoting. (If you have legacy code that does
+ not use dollar quoting, please refer to the
+ overview in <xref linkend="plpgsql-quote-tips"/>, which can save you
+ some effort when translating said code to a more reasonable scheme.)
+ </para>
+
+ <para>
+ Dynamic values require careful handling since they might contain
+ quote characters.
+ An example using <function>format()</function> (this assumes that you are
+ dollar quoting the function body so quote marks need not be doubled):
+<programlisting>
+EXECUTE format('UPDATE tbl SET %I = $1 '
+ 'WHERE key = $2', colname) USING newvalue, keyvalue;
+</programlisting>
+ It is also possible to call the quoting functions directly:
+<programlisting>
+EXECUTE 'UPDATE tbl SET '
+ || quote_ident(colname)
+ || ' = '
+ || quote_literal(newvalue)
+ || ' WHERE key = '
+ || quote_literal(keyvalue);
+</programlisting>
+ </para>
+
+ <para>
+ This example demonstrates the use of the
+ <function>quote_ident</function> and
+ <function>quote_literal</function> functions (see <xref
+ linkend="functions-string"/>). For safety, expressions containing column
+ or table identifiers should be passed through
+ <function>quote_ident</function> before insertion in a dynamic query.
+ Expressions containing values that should be literal strings in the
+ constructed command should be passed through <function>quote_literal</function>.
+ These functions take the appropriate steps to return the input text
+ enclosed in double or single quotes respectively, with any embedded
+ special characters properly escaped.
+ </para>
+
+ <para>
+ Because <function>quote_literal</function> is labeled
+ <literal>STRICT</literal>, it will always return null when called with a
+ null argument. In the above example, if <literal>newvalue</literal> or
+ <literal>keyvalue</literal> were null, the entire dynamic query string would
+ become null, leading to an error from <command>EXECUTE</command>.
+ You can avoid this problem by using the <function>quote_nullable</function>
+ function, which works the same as <function>quote_literal</function> except that
+ when called with a null argument it returns the string <literal>NULL</literal>.
+ For example,
+<programlisting>
+EXECUTE 'UPDATE tbl SET '
+ || quote_ident(colname)
+ || ' = '
+ || quote_nullable(newvalue)
+ || ' WHERE key = '
+ || quote_nullable(keyvalue);
+</programlisting>
+ If you are dealing with values that might be null, you should usually
+ use <function>quote_nullable</function> in place of <function>quote_literal</function>.
+ </para>
+
+ <para>
+ As always, care must be taken to ensure that null values in a query do
+ not deliver unintended results. For example the <literal>WHERE</literal> clause
+<programlisting>
+'WHERE key = ' || quote_nullable(keyvalue)
+</programlisting>
+ will never succeed if <literal>keyvalue</literal> is null, because the
+ result of using the equality operator <literal>=</literal> with a null operand
+ is always null. If you wish null to work like an ordinary key value,
+ you would need to rewrite the above as
+<programlisting>
+'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue)
+</programlisting>
+ (At present, <literal>IS NOT DISTINCT FROM</literal> is handled much less
+ efficiently than <literal>=</literal>, so don't do this unless you must.
+ See <xref linkend="functions-comparison"/> for
+ more information on nulls and <literal>IS DISTINCT</literal>.)
+ </para>
+
+ <para>
+ Note that dollar quoting is only useful for quoting fixed text.
+ It would be a very bad idea to try to write this example as:
+<programlisting>
+EXECUTE 'UPDATE tbl SET '
+ || quote_ident(colname)
+ || ' = $$'
+ || newvalue
+ || '$$ WHERE key = '
+ || quote_literal(keyvalue);
+</programlisting>
+ because it would break if the contents of <literal>newvalue</literal>
+ happened to contain <literal>$$</literal>. The same objection would
+ apply to any other dollar-quoting delimiter you might pick.
+ So, to safely quote text that is not known in advance, you
+ <emphasis>must</emphasis> use <function>quote_literal</function>,
+ <function>quote_nullable</function>, or <function>quote_ident</function>, as appropriate.
+ </para>
+
+ <para>
+ Dynamic SQL statements can also be safely constructed using the
+ <function>format</function> function (see <xref
+ linkend="functions-string-format"/>). For example:
+<programlisting>
+EXECUTE format('UPDATE tbl SET %I = %L '
+ 'WHERE key = %L', colname, newvalue, keyvalue);
+</programlisting>
+ <literal>%I</literal> is equivalent to <function>quote_ident</function>, and
+ <literal>%L</literal> is equivalent to <function>quote_nullable</function>.
+ The <function>format</function> function can be used in conjunction with
+ the <literal>USING</literal> clause:
+<programlisting>
+EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname)
+ USING newvalue, keyvalue;
+</programlisting>
+ This form is better because the variables are handled in their native
+ data type format, rather than unconditionally converting them to
+ text and quoting them via <literal>%L</literal>. It is also more efficient.
+ </para>
+ </example>
+
+ <para>
+ A much larger example of a dynamic command and
+ <command>EXECUTE</command> can be seen in <xref
+ linkend="plpgsql-porting-ex2"/>, which builds and executes a
+ <command>CREATE FUNCTION</command> command to define a new function.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-statements-diagnostics">
+ <title>Obtaining the Result Status</title>
+
+ <para>
+ There are several ways to determine the effect of a command. The
+ first method is to use the <command>GET DIAGNOSTICS</command>
+ command, which has the form:
+
+<synopsis>
+GET <optional> CURRENT </optional> DIAGNOSTICS <replaceable>variable</replaceable> { = | := } <replaceable>item</replaceable> <optional> , ... </optional>;
+</synopsis>
+
+ This command allows retrieval of system status indicators.
+ <literal>CURRENT</literal> is a noise word (but see also <command>GET STACKED
+ DIAGNOSTICS</command> in <xref linkend="plpgsql-exception-diagnostics"/>).
+ Each <replaceable>item</replaceable> is a key word identifying a status
+ value to be assigned to the specified <replaceable>variable</replaceable>
+ (which should be of the right data type to receive it). The currently
+ available status items are shown
+ in <xref linkend="plpgsql-current-diagnostics-values"/>. Colon-equal
+ (<literal>:=</literal>) can be used instead of the SQL-standard <literal>=</literal>
+ token. An example:
+<programlisting>
+GET DIAGNOSTICS integer_var = ROW_COUNT;
+</programlisting>
+ </para>
+
+ <table id="plpgsql-current-diagnostics-values">
+ <title>Available Diagnostics Items</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><varname>ROW_COUNT</varname></entry>
+ <entry><type>bigint</type></entry>
+ <entry>the number of rows processed by the most
+ recent <acronym>SQL</acronym> command</entry>
+ </row>
+ <row>
+ <entry><literal>PG_CONTEXT</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>line(s) of text describing the current call stack
+ (see <xref linkend="plpgsql-call-stack"/>)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The second method to determine the effects of a command is to check the
+ special variable named <literal>FOUND</literal>, which is of
+ type <type>boolean</type>. <literal>FOUND</literal> starts out
+ false within each <application>PL/pgSQL</application> function call.
+ It is set by each of the following types of statements:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A <command>SELECT INTO</command> statement sets
+ <literal>FOUND</literal> true if a row is assigned, false if no
+ row is returned.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <command>PERFORM</command> statement sets <literal>FOUND</literal>
+ true if it produces (and discards) one or more rows, false if
+ no row is produced.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>UPDATE</command>, <command>INSERT</command>, <command>DELETE</command>,
+ and <command>MERGE</command>
+ statements set <literal>FOUND</literal> true if at least one
+ row is affected, false if no row is affected.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <command>FETCH</command> statement sets <literal>FOUND</literal>
+ true if it returns a row, false if no row is returned.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <command>MOVE</command> statement sets <literal>FOUND</literal>
+ true if it successfully repositions the cursor, false otherwise.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <command>FOR</command> or <command>FOREACH</command> statement sets
+ <literal>FOUND</literal> true
+ if it iterates one or more times, else false.
+ <literal>FOUND</literal> is set this way when the
+ loop exits; inside the execution of the loop,
+ <literal>FOUND</literal> is not modified by the
+ loop statement, although it might be changed by the
+ execution of other statements within the loop body.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <command>RETURN QUERY</command> and <command>RETURN QUERY
+ EXECUTE</command> statements set <literal>FOUND</literal>
+ true if the query returns at least one row, false if no row
+ is returned.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Other <application>PL/pgSQL</application> statements do not change
+ the state of <literal>FOUND</literal>.
+ Note in particular that <command>EXECUTE</command>
+ changes the output of <command>GET DIAGNOSTICS</command>, but
+ does not change <literal>FOUND</literal>.
+ </para>
+
+ <para>
+ <literal>FOUND</literal> is a local variable within each
+ <application>PL/pgSQL</application> function; any changes to it
+ affect only the current function.
+ </para>
+
+ </sect2>
+
+ <sect2 id="plpgsql-statements-null">
+ <title>Doing Nothing At All</title>
+
+ <para>
+ Sometimes a placeholder statement that does nothing is useful.
+ For example, it can indicate that one arm of an if/then/else
+ chain is deliberately empty. For this purpose, use the
+ <command>NULL</command> statement:
+
+<synopsis>
+NULL;
+</synopsis>
+ </para>
+
+ <para>
+ For example, the following two fragments of code are equivalent:
+<programlisting>
+BEGIN
+ y := x / 0;
+EXCEPTION
+ WHEN division_by_zero THEN
+ NULL; -- ignore the error
+END;
+</programlisting>
+
+<programlisting>
+BEGIN
+ y := x / 0;
+EXCEPTION
+ WHEN division_by_zero THEN -- ignore the error
+END;
+</programlisting>
+ Which is preferable is a matter of taste.
+ </para>
+
+ <note>
+ <para>
+ In Oracle's PL/SQL, empty statement lists are not allowed, and so
+ <command>NULL</command> statements are <emphasis>required</emphasis> for situations
+ such as this. <application>PL/pgSQL</application> allows you to
+ just write nothing, instead.
+ </para>
+ </note>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpgsql-control-structures">
+ <title>Control Structures</title>
+
+ <para>
+ Control structures are probably the most useful (and
+ important) part of <application>PL/pgSQL</application>. With
+ <application>PL/pgSQL</application>'s control structures,
+ you can manipulate <productname>PostgreSQL</productname> data in a very
+ flexible and powerful way.
+ </para>
+
+ <sect2 id="plpgsql-statements-returning">
+ <title>Returning from a Function</title>
+
+ <para>
+ There are two commands available that allow you to return data
+ from a function: <command>RETURN</command> and <command>RETURN
+ NEXT</command>.
+ </para>
+
+ <sect3>
+ <title><command>RETURN</command></title>
+
+<synopsis>
+RETURN <replaceable>expression</replaceable>;
+</synopsis>
+
+ <para>
+ <command>RETURN</command> with an expression terminates the
+ function and returns the value of
+ <replaceable>expression</replaceable> to the caller. This form
+ is used for <application>PL/pgSQL</application> functions that do
+ not return a set.
+ </para>
+
+ <para>
+ In a function that returns a scalar type, the expression's result will
+ automatically be cast into the function's return type as described for
+ assignments. But to return a composite (row) value, you must write an
+ expression delivering exactly the requested column set. This may
+ require use of explicit casting.
+ </para>
+
+ <para>
+ If you declared the function with output parameters, write just
+ <command>RETURN</command> with no expression. The current values
+ of the output parameter variables will be returned.
+ </para>
+
+ <para>
+ If you declared the function to return <type>void</type>, a
+ <command>RETURN</command> statement can be used to exit the function
+ early; but do not write an expression following
+ <command>RETURN</command>.
+ </para>
+
+ <para>
+ The return value of a function cannot be left undefined. If
+ control reaches the end of the top-level block of the function
+ without hitting a <command>RETURN</command> statement, a run-time
+ error will occur. This restriction does not apply to functions
+ with output parameters and functions returning <type>void</type>,
+ however. In those cases a <command>RETURN</command> statement is
+ automatically executed if the top-level block finishes.
+ </para>
+
+ <para>
+ Some examples:
+
+<programlisting>
+-- functions returning a scalar type
+RETURN 1 + 2;
+RETURN scalar_var;
+
+-- functions returning a composite type
+RETURN composite_type_var;
+RETURN (1, 2, 'three'::text); -- must cast columns to correct types
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><command>RETURN NEXT</command> and <command>RETURN QUERY</command></title>
+ <indexterm>
+ <primary>RETURN NEXT</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>RETURN QUERY</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+<synopsis>
+RETURN NEXT <replaceable>expression</replaceable>;
+RETURN QUERY <replaceable>query</replaceable>;
+RETURN QUERY EXECUTE <replaceable class="command">command-string</replaceable> <optional> USING <replaceable>expression</replaceable> <optional>, ... </optional> </optional>;
+</synopsis>
+
+ <para>
+ When a <application>PL/pgSQL</application> function is declared to return
+ <literal>SETOF <replaceable>sometype</replaceable></literal>, the procedure
+ to follow is slightly different. In that case, the individual
+ items to return are specified by a sequence of <command>RETURN
+ NEXT</command> or <command>RETURN QUERY</command> commands, and
+ then a final <command>RETURN</command> command with no argument
+ is used to indicate that the function has finished executing.
+ <command>RETURN NEXT</command> can be used with both scalar and
+ composite data types; with a composite result type, an entire
+ <quote>table</quote> of results will be returned.
+ <command>RETURN QUERY</command> appends the results of executing
+ a query to the function's result set. <command>RETURN
+ NEXT</command> and <command>RETURN QUERY</command> can be freely
+ intermixed in a single set-returning function, in which case
+ their results will be concatenated.
+ </para>
+
+ <para>
+ <command>RETURN NEXT</command> and <command>RETURN
+ QUERY</command> do not actually return from the function &mdash;
+ they simply append zero or more rows to the function's result
+ set. Execution then continues with the next statement in the
+ <application>PL/pgSQL</application> function. As successive
+ <command>RETURN NEXT</command> or <command>RETURN
+ QUERY</command> commands are executed, the result set is built
+ up. A final <command>RETURN</command>, which should have no
+ argument, causes control to exit the function (or you can just
+ let control reach the end of the function).
+ </para>
+
+ <para>
+ <command>RETURN QUERY</command> has a variant
+ <command>RETURN QUERY EXECUTE</command>, which specifies the
+ query to be executed dynamically. Parameter expressions can
+ be inserted into the computed query string via <literal>USING</literal>,
+ in just the same way as in the <command>EXECUTE</command> command.
+ </para>
+
+ <para>
+ If you declared the function with output parameters, write just
+ <command>RETURN NEXT</command> with no expression. On each
+ execution, the current values of the output parameter
+ variable(s) will be saved for eventual return as a row of the
+ result. Note that you must declare the function as returning
+ <literal>SETOF record</literal> when there are multiple output
+ parameters, or <literal>SETOF <replaceable>sometype</replaceable></literal>
+ when there is just one output parameter of type
+ <replaceable>sometype</replaceable>, in order to create a set-returning
+ function with output parameters.
+ </para>
+
+ <para>
+ Here is an example of a function using <command>RETURN
+ NEXT</command>:
+
+<programlisting>
+CREATE TABLE foo (fooid INT, foosubid INT, fooname TEXT);
+INSERT INTO foo VALUES (1, 2, 'three');
+INSERT INTO foo VALUES (4, 5, 'six');
+
+CREATE OR REPLACE FUNCTION get_all_foo() RETURNS SETOF foo AS
+$BODY$
+DECLARE
+ r foo%rowtype;
+BEGIN
+ FOR r IN
+ SELECT * FROM foo WHERE fooid &gt; 0
+ LOOP
+ -- can do some processing here
+ RETURN NEXT r; -- return current row of SELECT
+ END LOOP;
+ RETURN;
+END;
+$BODY$
+LANGUAGE plpgsql;
+
+SELECT * FROM get_all_foo();
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example of a function using <command>RETURN
+ QUERY</command>:
+
+<programlisting>
+CREATE FUNCTION get_available_flightid(date) RETURNS SETOF integer AS
+$BODY$
+BEGIN
+ RETURN QUERY SELECT flightid
+ FROM flight
+ WHERE flightdate &gt;= $1
+ AND flightdate &lt; ($1 + 1);
+
+ -- Since execution is not finished, we can check whether rows were returned
+ -- and raise exception if not.
+ IF NOT FOUND THEN
+ RAISE EXCEPTION 'No flight at %.', $1;
+ END IF;
+
+ RETURN;
+ END;
+$BODY$
+LANGUAGE plpgsql;
+
+-- Returns available flights or raises exception if there are no
+-- available flights.
+SELECT * FROM get_available_flightid(CURRENT_DATE);
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ The current implementation of <command>RETURN NEXT</command>
+ and <command>RETURN QUERY</command> stores the entire result set
+ before returning from the function, as discussed above. That
+ means that if a <application>PL/pgSQL</application> function produces a
+ very large result set, performance might be poor: data will be
+ written to disk to avoid memory exhaustion, but the function
+ itself will not return until the entire result set has been
+ generated. A future version of <application>PL/pgSQL</application> might
+ allow users to define set-returning functions
+ that do not have this limitation. Currently, the point at
+ which data begins being written to disk is controlled by the
+ <xref linkend="guc-work-mem"/>
+ configuration variable. Administrators who have sufficient
+ memory to store larger result sets in memory should consider
+ increasing this parameter.
+ </para>
+ </note>
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-statements-returning-procedure">
+ <title>Returning from a Procedure</title>
+
+ <para>
+ A procedure does not have a return value. A procedure can therefore end
+ without a <command>RETURN</command> statement. If you wish to use
+ a <command>RETURN</command> statement to exit the code early, write
+ just <command>RETURN</command> with no expression.
+ </para>
+
+ <para>
+ If the procedure has output parameters, the final values of the output
+ parameter variables will be returned to the caller.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-statements-calling-procedure">
+ <title>Calling a Procedure</title>
+
+ <para>
+ A <application>PL/pgSQL</application> function, procedure,
+ or <command>DO</command> block can call a procedure
+ using <command>CALL</command>. Output parameters are handled
+ differently from the way that <command>CALL</command> works in plain
+ SQL. Each <literal>OUT</literal> or <literal>INOUT</literal>
+ parameter of the procedure must
+ correspond to a variable in the <command>CALL</command> statement, and
+ whatever the procedure returns is assigned back to that variable after
+ it returns. For example:
+<programlisting>
+CREATE PROCEDURE triple(INOUT x int)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ x := x * 3;
+END;
+$$;
+
+DO $$
+DECLARE myvar int := 5;
+BEGIN
+ CALL triple(myvar);
+ RAISE NOTICE 'myvar = %', myvar; -- prints 15
+END;
+$$;
+</programlisting>
+ The variable corresponding to an output parameter can be a simple
+ variable or a field of a composite-type variable. Currently,
+ it cannot be an element of an array.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-conditionals">
+ <title>Conditionals</title>
+
+ <para>
+ <command>IF</command> and <command>CASE</command> statements let you execute
+ alternative commands based on certain conditions.
+ <application>PL/pgSQL</application> has three forms of <command>IF</command>:
+ <itemizedlist>
+ <listitem>
+ <para><literal>IF ... THEN ... END IF</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>IF ... THEN ... ELSE ... END IF</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>IF ... THEN ... ELSIF ... THEN ... ELSE ... END IF</literal></para>
+ </listitem>
+ </itemizedlist>
+
+ and two forms of <command>CASE</command>:
+ <itemizedlist>
+ <listitem>
+ <para><literal>CASE ... WHEN ... THEN ... ELSE ... END CASE</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>CASE WHEN ... THEN ... ELSE ... END CASE</literal></para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <sect3>
+ <title><literal>IF-THEN</literal></title>
+
+<synopsis>
+IF <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+END IF;
+</synopsis>
+
+ <para>
+ <literal>IF-THEN</literal> statements are the simplest form of
+ <literal>IF</literal>. The statements between
+ <literal>THEN</literal> and <literal>END IF</literal> will be
+ executed if the condition is true. Otherwise, they are
+ skipped.
+ </para>
+
+ <para>
+ Example:
+<programlisting>
+IF v_user_id &lt;&gt; 0 THEN
+ UPDATE users SET email = v_email WHERE user_id = v_user_id;
+END IF;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>IF-THEN-ELSE</literal></title>
+
+<synopsis>
+IF <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+ELSE
+ <replaceable>statements</replaceable>
+END IF;
+</synopsis>
+
+ <para>
+ <literal>IF-THEN-ELSE</literal> statements add to
+ <literal>IF-THEN</literal> by letting you specify an
+ alternative set of statements that should be executed if the
+ condition is not true. (Note this includes the case where the
+ condition evaluates to NULL.)
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+IF parentid IS NULL OR parentid = ''
+THEN
+ RETURN fullname;
+ELSE
+ RETURN hp_true_filename(parentid) || '/' || fullname;
+END IF;
+</programlisting>
+
+<programlisting>
+IF v_count &gt; 0 THEN
+ INSERT INTO users_count (count) VALUES (v_count);
+ RETURN 't';
+ELSE
+ RETURN 'f';
+END IF;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>IF-THEN-ELSIF</literal></title>
+
+<synopsis>
+IF <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+<optional> ELSIF <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+<optional> ELSIF <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+ ...
+</optional>
+</optional>
+<optional> ELSE
+ <replaceable>statements</replaceable> </optional>
+END IF;
+</synopsis>
+
+ <para>
+ Sometimes there are more than just two alternatives.
+ <literal>IF-THEN-ELSIF</literal> provides a convenient
+ method of checking several alternatives in turn.
+ The <literal>IF</literal> conditions are tested successively
+ until the first one that is true is found. Then the
+ associated statement(s) are executed, after which control
+ passes to the next statement after <literal>END IF</literal>.
+ (Any subsequent <literal>IF</literal> conditions are <emphasis>not</emphasis>
+ tested.) If none of the <literal>IF</literal> conditions is true,
+ then the <literal>ELSE</literal> block (if any) is executed.
+ </para>
+
+ <para>
+ Here is an example:
+
+<programlisting>
+IF number = 0 THEN
+ result := 'zero';
+ELSIF number &gt; 0 THEN
+ result := 'positive';
+ELSIF number &lt; 0 THEN
+ result := 'negative';
+ELSE
+ -- hmm, the only other possibility is that number is null
+ result := 'NULL';
+END IF;
+</programlisting>
+ </para>
+
+ <para>
+ The key word <literal>ELSIF</literal> can also be spelled
+ <literal>ELSEIF</literal>.
+ </para>
+
+ <para>
+ An alternative way of accomplishing the same task is to nest
+ <literal>IF-THEN-ELSE</literal> statements, as in the
+ following example:
+
+<programlisting>
+IF demo_row.sex = 'm' THEN
+ pretty_sex := 'man';
+ELSE
+ IF demo_row.sex = 'f' THEN
+ pretty_sex := 'woman';
+ END IF;
+END IF;
+</programlisting>
+ </para>
+
+ <para>
+ However, this method requires writing a matching <literal>END IF</literal>
+ for each <literal>IF</literal>, so it is much more cumbersome than
+ using <literal>ELSIF</literal> when there are many alternatives.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Simple <literal>CASE</literal></title>
+
+<synopsis>
+CASE <replaceable>search-expression</replaceable>
+ WHEN <replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> <optional> ... </optional></optional> THEN
+ <replaceable>statements</replaceable>
+ <optional> WHEN <replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> <optional> ... </optional></optional> THEN
+ <replaceable>statements</replaceable>
+ ... </optional>
+ <optional> ELSE
+ <replaceable>statements</replaceable> </optional>
+END CASE;
+</synopsis>
+
+ <para>
+ The simple form of <command>CASE</command> provides conditional execution
+ based on equality of operands. The <replaceable>search-expression</replaceable>
+ is evaluated (once) and successively compared to each
+ <replaceable>expression</replaceable> in the <literal>WHEN</literal> clauses.
+ If a match is found, then the corresponding
+ <replaceable>statements</replaceable> are executed, and then control
+ passes to the next statement after <literal>END CASE</literal>. (Subsequent
+ <literal>WHEN</literal> expressions are not evaluated.) If no match is
+ found, the <literal>ELSE</literal> <replaceable>statements</replaceable> are
+ executed; but if <literal>ELSE</literal> is not present, then a
+ <literal>CASE_NOT_FOUND</literal> exception is raised.
+ </para>
+
+ <para>
+ Here is a simple example:
+
+<programlisting>
+CASE x
+ WHEN 1, 2 THEN
+ msg := 'one or two';
+ ELSE
+ msg := 'other value than one or two';
+END CASE;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Searched <literal>CASE</literal></title>
+
+<synopsis>
+CASE
+ WHEN <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+ <optional> WHEN <replaceable>boolean-expression</replaceable> THEN
+ <replaceable>statements</replaceable>
+ ... </optional>
+ <optional> ELSE
+ <replaceable>statements</replaceable> </optional>
+END CASE;
+</synopsis>
+
+ <para>
+ The searched form of <command>CASE</command> provides conditional execution
+ based on truth of Boolean expressions. Each <literal>WHEN</literal> clause's
+ <replaceable>boolean-expression</replaceable> is evaluated in turn,
+ until one is found that yields <literal>true</literal>. Then the
+ corresponding <replaceable>statements</replaceable> are executed, and
+ then control passes to the next statement after <literal>END CASE</literal>.
+ (Subsequent <literal>WHEN</literal> expressions are not evaluated.)
+ If no true result is found, the <literal>ELSE</literal>
+ <replaceable>statements</replaceable> are executed;
+ but if <literal>ELSE</literal> is not present, then a
+ <literal>CASE_NOT_FOUND</literal> exception is raised.
+ </para>
+
+ <para>
+ Here is an example:
+
+<programlisting>
+CASE
+ WHEN x BETWEEN 0 AND 10 THEN
+ msg := 'value is between zero and ten';
+ WHEN x BETWEEN 11 AND 20 THEN
+ msg := 'value is between eleven and twenty';
+END CASE;
+</programlisting>
+ </para>
+
+ <para>
+ This form of <command>CASE</command> is entirely equivalent to
+ <literal>IF-THEN-ELSIF</literal>, except for the rule that reaching
+ an omitted <literal>ELSE</literal> clause results in an error rather
+ than doing nothing.
+ </para>
+
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-control-structures-loops">
+ <title>Simple Loops</title>
+
+ <indexterm zone="plpgsql-control-structures-loops">
+ <primary>loop</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ With the <literal>LOOP</literal>, <literal>EXIT</literal>,
+ <literal>CONTINUE</literal>, <literal>WHILE</literal>, <literal>FOR</literal>,
+ and <literal>FOREACH</literal> statements, you can arrange for your
+ <application>PL/pgSQL</application> function to repeat a series of commands.
+ </para>
+
+ <sect3>
+ <title><literal>LOOP</literal></title>
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+
+ <para>
+ <literal>LOOP</literal> defines an unconditional loop that is repeated
+ indefinitely until terminated by an <literal>EXIT</literal> or
+ <command>RETURN</command> statement. The optional
+ <replaceable>label</replaceable> can be used by <literal>EXIT</literal>
+ and <literal>CONTINUE</literal> statements within nested loops to
+ specify which loop those statements refer to.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>EXIT</literal></title>
+
+ <indexterm>
+ <primary>EXIT</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+<synopsis>
+EXIT <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <replaceable>boolean-expression</replaceable> </optional>;
+</synopsis>
+
+ <para>
+ If no <replaceable>label</replaceable> is given, the innermost
+ loop is terminated and the statement following <literal>END
+ LOOP</literal> is executed next. If <replaceable>label</replaceable>
+ is given, it must be the label of the current or some outer
+ level of nested loop or block. Then the named loop or block is
+ terminated and control continues with the statement after the
+ loop's/block's corresponding <literal>END</literal>.
+ </para>
+
+ <para>
+ If <literal>WHEN</literal> is specified, the loop exit occurs only if
+ <replaceable>boolean-expression</replaceable> is true. Otherwise, control passes
+ to the statement after <literal>EXIT</literal>.
+ </para>
+
+ <para>
+ <literal>EXIT</literal> can be used with all types of loops; it is
+ not limited to use with unconditional loops.
+ </para>
+
+ <para>
+ When used with a
+ <literal>BEGIN</literal> block, <literal>EXIT</literal> passes
+ control to the next statement after the end of the block.
+ Note that a label must be used for this purpose; an unlabeled
+ <literal>EXIT</literal> is never considered to match a
+ <literal>BEGIN</literal> block. (This is a change from
+ pre-8.4 releases of <productname>PostgreSQL</productname>, which
+ would allow an unlabeled <literal>EXIT</literal> to match
+ a <literal>BEGIN</literal> block.)
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+LOOP
+ -- some computations
+ IF count &gt; 0 THEN
+ EXIT; -- exit loop
+ END IF;
+END LOOP;
+
+LOOP
+ -- some computations
+ EXIT WHEN count &gt; 0; -- same result as previous example
+END LOOP;
+
+&lt;&lt;ablock&gt;&gt;
+BEGIN
+ -- some computations
+ IF stocks &gt; 100000 THEN
+ EXIT ablock; -- causes exit from the BEGIN block
+ END IF;
+ -- computations here will be skipped when stocks &gt; 100000
+END;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>CONTINUE</literal></title>
+
+ <indexterm>
+ <primary>CONTINUE</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+<synopsis>
+CONTINUE <optional> <replaceable>label</replaceable> </optional> <optional> WHEN <replaceable>boolean-expression</replaceable> </optional>;
+</synopsis>
+
+ <para>
+ If no <replaceable>label</replaceable> is given, the next iteration of
+ the innermost loop is begun. That is, all statements remaining
+ in the loop body are skipped, and control returns
+ to the loop control expression (if any) to determine whether
+ another loop iteration is needed.
+ If <replaceable>label</replaceable> is present, it
+ specifies the label of the loop whose execution will be
+ continued.
+ </para>
+
+ <para>
+ If <literal>WHEN</literal> is specified, the next iteration of the
+ loop is begun only if <replaceable>boolean-expression</replaceable> is
+ true. Otherwise, control passes to the statement after
+ <literal>CONTINUE</literal>.
+ </para>
+
+ <para>
+ <literal>CONTINUE</literal> can be used with all types of loops; it
+ is not limited to use with unconditional loops.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+LOOP
+ -- some computations
+ EXIT WHEN count &gt; 100;
+ CONTINUE WHEN count &lt; 50;
+ -- some computations for count IN [50 .. 100]
+END LOOP;
+</programlisting>
+ </para>
+ </sect3>
+
+
+ <sect3>
+ <title><literal>WHILE</literal></title>
+
+ <indexterm>
+ <primary>WHILE</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+WHILE <replaceable>boolean-expression</replaceable> LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+
+ <para>
+ The <literal>WHILE</literal> statement repeats a
+ sequence of statements so long as the
+ <replaceable>boolean-expression</replaceable>
+ evaluates to true. The expression is checked just before
+ each entry to the loop body.
+ </para>
+
+ <para>
+ For example:
+<programlisting>
+WHILE amount_owed &gt; 0 AND gift_certificate_balance &gt; 0 LOOP
+ -- some computations here
+END LOOP;
+
+WHILE NOT done LOOP
+ -- some computations here
+END LOOP;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3 id="plpgsql-integer-for">
+ <title><literal>FOR</literal> (Integer Variant)</title>
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+FOR <replaceable>name</replaceable> IN <optional> REVERSE </optional> <replaceable>expression</replaceable> .. <replaceable>expression</replaceable> <optional> BY <replaceable>expression</replaceable> </optional> LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+
+ <para>
+ This form of <literal>FOR</literal> creates a loop that iterates over a range
+ of integer values. The variable
+ <replaceable>name</replaceable> is automatically defined as type
+ <type>integer</type> and exists only inside the loop (any existing
+ definition of the variable name is ignored within the loop).
+ The two expressions giving
+ the lower and upper bound of the range are evaluated once when entering
+ the loop. If the <literal>BY</literal> clause isn't specified the iteration
+ step is 1, otherwise it's the value specified in the <literal>BY</literal>
+ clause, which again is evaluated once on loop entry.
+ If <literal>REVERSE</literal> is specified then the step value is
+ subtracted, rather than added, after each iteration.
+ </para>
+
+ <para>
+ Some examples of integer <literal>FOR</literal> loops:
+<programlisting>
+FOR i IN 1..10 LOOP
+ -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
+END LOOP;
+
+FOR i IN REVERSE 10..1 LOOP
+ -- i will take on the values 10,9,8,7,6,5,4,3,2,1 within the loop
+END LOOP;
+
+FOR i IN REVERSE 10..1 BY 2 LOOP
+ -- i will take on the values 10,8,6,4,2 within the loop
+END LOOP;
+</programlisting>
+ </para>
+
+ <para>
+ If the lower bound is greater than the upper bound (or less than,
+ in the <literal>REVERSE</literal> case), the loop body is not
+ executed at all. No error is raised.
+ </para>
+
+ <para>
+ If a <replaceable>label</replaceable> is attached to the
+ <literal>FOR</literal> loop then the integer loop variable can be
+ referenced with a qualified name, using that
+ <replaceable>label</replaceable>.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-records-iterating">
+ <title>Looping through Query Results</title>
+
+ <para>
+ Using a different type of <literal>FOR</literal> loop, you can iterate through
+ the results of a query and manipulate that data
+ accordingly. The syntax is:
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+FOR <replaceable>target</replaceable> IN <replaceable>query</replaceable> LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+ The <replaceable>target</replaceable> is a record variable, row variable,
+ or comma-separated list of scalar variables.
+ The <replaceable>target</replaceable> is successively assigned each row
+ resulting from the <replaceable>query</replaceable> and the loop body is
+ executed for each row. Here is an example:
+<programlisting>
+CREATE FUNCTION refresh_mviews() RETURNS integer AS $$
+DECLARE
+ mviews RECORD;
+BEGIN
+ RAISE NOTICE 'Refreshing all materialized views...';
+
+ FOR mviews IN
+ SELECT n.nspname AS mv_schema,
+ c.relname AS mv_name,
+ pg_catalog.pg_get_userbyid(c.relowner) AS owner
+ FROM pg_catalog.pg_class c
+ LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace)
+ WHERE c.relkind = 'm'
+ ORDER BY 1
+ LOOP
+
+ -- Now "mviews" has one record with information about the materialized view
+
+ RAISE NOTICE 'Refreshing materialized view %.% (owner: %)...',
+ quote_ident(mviews.mv_schema),
+ quote_ident(mviews.mv_name),
+ quote_ident(mviews.owner);
+ EXECUTE format('REFRESH MATERIALIZED VIEW %I.%I', mviews.mv_schema, mviews.mv_name);
+ END LOOP;
+
+ RAISE NOTICE 'Done refreshing materialized views.';
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ If the loop is terminated by an <literal>EXIT</literal> statement, the last
+ assigned row value is still accessible after the loop.
+ </para>
+
+ <para>
+ The <replaceable>query</replaceable> used in this type of <literal>FOR</literal>
+ statement can be any SQL command that returns rows to the caller:
+ <command>SELECT</command> is the most common case,
+ but you can also use <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> with a <literal>RETURNING</literal> clause. Some utility
+ commands such as <command>EXPLAIN</command> will work too.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> variables are replaced by query parameters,
+ and the query plan is cached for possible re-use, as discussed in
+ detail in <xref linkend="plpgsql-var-subst"/> and
+ <xref linkend="plpgsql-plan-caching"/>.
+ </para>
+
+ <para>
+ The <literal>FOR-IN-EXECUTE</literal> statement is another way to iterate over
+ rows:
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+FOR <replaceable>target</replaceable> IN EXECUTE <replaceable>text_expression</replaceable> <optional> USING <replaceable>expression</replaceable> <optional>, ... </optional> </optional> LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+ This is like the previous form, except that the source query
+ is specified as a string expression, which is evaluated and replanned
+ on each entry to the <literal>FOR</literal> loop. This allows the programmer to
+ choose the speed of a preplanned query or the flexibility of a dynamic
+ query, just as with a plain <command>EXECUTE</command> statement.
+ As with <command>EXECUTE</command>, parameter values can be inserted
+ into the dynamic command via <literal>USING</literal>.
+ </para>
+
+ <para>
+ Another way to specify the query whose results should be iterated
+ through is to declare it as a cursor. This is described in
+ <xref linkend="plpgsql-cursor-for-loop"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-foreach-array">
+ <title>Looping through Arrays</title>
+
+ <para>
+ The <literal>FOREACH</literal> loop is much like a <literal>FOR</literal> loop,
+ but instead of iterating through the rows returned by an SQL query,
+ it iterates through the elements of an array value.
+ (In general, <literal>FOREACH</literal> is meant for looping through
+ components of a composite-valued expression; variants for looping
+ through composites besides arrays may be added in future.)
+ The <literal>FOREACH</literal> statement to loop over an array is:
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+FOREACH <replaceable>target</replaceable> <optional> SLICE <replaceable>number</replaceable> </optional> IN ARRAY <replaceable>expression</replaceable> LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+ </para>
+
+ <para>
+ Without <literal>SLICE</literal>, or if <literal>SLICE 0</literal> is specified,
+ the loop iterates through individual elements of the array produced
+ by evaluating the <replaceable>expression</replaceable>.
+ The <replaceable>target</replaceable> variable is assigned each
+ element value in sequence, and the loop body is executed for each element.
+ Here is an example of looping through the elements of an integer
+ array:
+
+<programlisting>
+CREATE FUNCTION sum(int[]) RETURNS int8 AS $$
+DECLARE
+ s int8 := 0;
+ x int;
+BEGIN
+ FOREACH x IN ARRAY $1
+ LOOP
+ s := s + x;
+ END LOOP;
+ RETURN s;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ The elements are visited in storage order, regardless of the number of
+ array dimensions. Although the <replaceable>target</replaceable> is
+ usually just a single variable, it can be a list of variables when
+ looping through an array of composite values (records). In that case,
+ for each array element, the variables are assigned from successive
+ columns of the composite value.
+ </para>
+
+ <para>
+ With a positive <literal>SLICE</literal> value, <literal>FOREACH</literal>
+ iterates through slices of the array rather than single elements.
+ The <literal>SLICE</literal> value must be an integer constant not larger
+ than the number of dimensions of the array. The
+ <replaceable>target</replaceable> variable must be an array,
+ and it receives successive slices of the array value, where each slice
+ is of the number of dimensions specified by <literal>SLICE</literal>.
+ Here is an example of iterating through one-dimensional slices:
+
+<programlisting>
+CREATE FUNCTION scan_rows(int[]) RETURNS void AS $$
+DECLARE
+ x int[];
+BEGIN
+ FOREACH x SLICE 1 IN ARRAY $1
+ LOOP
+ RAISE NOTICE 'row = %', x;
+ END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT scan_rows(ARRAY[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]);
+
+NOTICE: row = {1,2,3}
+NOTICE: row = {4,5,6}
+NOTICE: row = {7,8,9}
+NOTICE: row = {10,11,12}
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-error-trapping">
+ <title>Trapping Errors</title>
+
+ <indexterm>
+ <primary>exceptions</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ By default, any error occurring in a <application>PL/pgSQL</application>
+ function aborts execution of the function and the
+ surrounding transaction. You can trap errors and recover
+ from them by using a <command>BEGIN</command> block with an
+ <literal>EXCEPTION</literal> clause. The syntax is an extension of the
+ normal syntax for a <command>BEGIN</command> block:
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+<optional> DECLARE
+ <replaceable>declarations</replaceable> </optional>
+BEGIN
+ <replaceable>statements</replaceable>
+EXCEPTION
+ WHEN <replaceable>condition</replaceable> <optional> OR <replaceable>condition</replaceable> ... </optional> THEN
+ <replaceable>handler_statements</replaceable>
+ <optional> WHEN <replaceable>condition</replaceable> <optional> OR <replaceable>condition</replaceable> ... </optional> THEN
+ <replaceable>handler_statements</replaceable>
+ ... </optional>
+END;
+</synopsis>
+ </para>
+
+ <para>
+ If no error occurs, this form of block simply executes all the
+ <replaceable>statements</replaceable>, and then control passes
+ to the next statement after <literal>END</literal>. But if an error
+ occurs within the <replaceable>statements</replaceable>, further
+ processing of the <replaceable>statements</replaceable> is
+ abandoned, and control passes to the <literal>EXCEPTION</literal> list.
+ The list is searched for the first <replaceable>condition</replaceable>
+ matching the error that occurred. If a match is found, the
+ corresponding <replaceable>handler_statements</replaceable> are
+ executed, and then control passes to the next statement after
+ <literal>END</literal>. If no match is found, the error propagates out
+ as though the <literal>EXCEPTION</literal> clause were not there at all:
+ the error can be caught by an enclosing block with
+ <literal>EXCEPTION</literal>, or if there is none it aborts processing
+ of the function.
+ </para>
+
+ <para>
+ The <replaceable>condition</replaceable> names can be any of
+ those shown in <xref linkend="errcodes-appendix"/>. A category
+ name matches any error within its category. The special
+ condition name <literal>OTHERS</literal> matches every error type except
+ <literal>QUERY_CANCELED</literal> and <literal>ASSERT_FAILURE</literal>.
+ (It is possible, but often unwise, to trap those two error types
+ by name.) Condition names are
+ not case-sensitive. Also, an error condition can be specified
+ by <literal>SQLSTATE</literal> code; for example these are equivalent:
+<programlisting>
+WHEN division_by_zero THEN ...
+WHEN SQLSTATE '22012' THEN ...
+</programlisting>
+ </para>
+
+ <para>
+ If a new error occurs within the selected
+ <replaceable>handler_statements</replaceable>, it cannot be caught
+ by this <literal>EXCEPTION</literal> clause, but is propagated out.
+ A surrounding <literal>EXCEPTION</literal> clause could catch it.
+ </para>
+
+ <para>
+ When an error is caught by an <literal>EXCEPTION</literal> clause,
+ the local variables of the <application>PL/pgSQL</application> function
+ remain as they were when the error occurred, but all changes
+ to persistent database state within the block are rolled back.
+ As an example, consider this fragment:
+
+<programlisting>
+INSERT INTO mytab(firstname, lastname) VALUES('Tom', 'Jones');
+BEGIN
+ UPDATE mytab SET firstname = 'Joe' WHERE lastname = 'Jones';
+ x := x + 1;
+ y := x / 0;
+EXCEPTION
+ WHEN division_by_zero THEN
+ RAISE NOTICE 'caught division_by_zero';
+ RETURN x;
+END;
+</programlisting>
+
+ When control reaches the assignment to <literal>y</literal>, it will
+ fail with a <literal>division_by_zero</literal> error. This will be caught by
+ the <literal>EXCEPTION</literal> clause. The value returned in the
+ <command>RETURN</command> statement will be the incremented value of
+ <literal>x</literal>, but the effects of the <command>UPDATE</command> command will
+ have been rolled back. The <command>INSERT</command> command preceding the
+ block is not rolled back, however, so the end result is that the database
+ contains <literal>Tom Jones</literal> not <literal>Joe Jones</literal>.
+ </para>
+
+ <tip>
+ <para>
+ A block containing an <literal>EXCEPTION</literal> clause is significantly
+ more expensive to enter and exit than a block without one. Therefore,
+ don't use <literal>EXCEPTION</literal> without need.
+ </para>
+ </tip>
+
+ <example id="plpgsql-upsert-example">
+ <title>Exceptions with <command>UPDATE</command>/<command>INSERT</command></title>
+ <para>
+
+ This example uses exception handling to perform either
+ <command>UPDATE</command> or <command>INSERT</command>, as appropriate. It is
+ recommended that applications use <command>INSERT</command> with
+ <literal>ON CONFLICT DO UPDATE</literal> rather than actually using
+ this pattern. This example serves primarily to illustrate use of
+ <application>PL/pgSQL</application> control flow structures:
+
+<programlisting>
+CREATE TABLE db (a INT PRIMARY KEY, b TEXT);
+
+CREATE FUNCTION merge_db(key INT, data TEXT) RETURNS VOID AS
+$$
+BEGIN
+ LOOP
+ -- first try to update the key
+ UPDATE db SET b = data WHERE a = key;
+ IF found THEN
+ RETURN;
+ END IF;
+ -- not there, so try to insert the key
+ -- if someone else inserts the same key concurrently,
+ -- we could get a unique-key failure
+ BEGIN
+ INSERT INTO db(a,b) VALUES (key, data);
+ RETURN;
+ EXCEPTION WHEN unique_violation THEN
+ -- Do nothing, and loop to try the UPDATE again.
+ END;
+ END LOOP;
+END;
+$$
+LANGUAGE plpgsql;
+
+SELECT merge_db(1, 'david');
+SELECT merge_db(1, 'dennis');
+</programlisting>
+
+ This coding assumes the <literal>unique_violation</literal> error is caused by
+ the <command>INSERT</command>, and not by, say, an <command>INSERT</command> in a
+ trigger function on the table. It might also misbehave if there is
+ more than one unique index on the table, since it will retry the
+ operation regardless of which index caused the error.
+ More safety could be had by using the
+ features discussed next to check that the trapped error was the one
+ expected.
+ </para>
+ </example>
+
+ <sect3 id="plpgsql-exception-diagnostics">
+ <title>Obtaining Information about an Error</title>
+
+ <para>
+ Exception handlers frequently need to identify the specific error that
+ occurred. There are two ways to get information about the current
+ exception in <application>PL/pgSQL</application>: special variables and the
+ <command>GET STACKED DIAGNOSTICS</command> command.
+ </para>
+
+ <para>
+ Within an exception handler, the special variable
+ <varname>SQLSTATE</varname> contains the error code that corresponds to
+ the exception that was raised (refer to <xref linkend="errcodes-table"/>
+ for a list of possible error codes). The special variable
+ <varname>SQLERRM</varname> contains the error message associated with the
+ exception. These variables are undefined outside exception handlers.
+ </para>
+
+ <para>
+ Within an exception handler, one may also retrieve
+ information about the current exception by using the
+ <command>GET STACKED DIAGNOSTICS</command> command, which has the form:
+
+<synopsis>
+GET STACKED DIAGNOSTICS <replaceable>variable</replaceable> { = | := } <replaceable>item</replaceable> <optional> , ... </optional>;
+</synopsis>
+
+ Each <replaceable>item</replaceable> is a key word identifying a status
+ value to be assigned to the specified <replaceable>variable</replaceable>
+ (which should be of the right data type to receive it). The currently
+ available status items are shown
+ in <xref linkend="plpgsql-exception-diagnostics-values"/>.
+ </para>
+
+ <table id="plpgsql-exception-diagnostics-values">
+ <title>Error Diagnostics Items</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>RETURNED_SQLSTATE</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the SQLSTATE error code of the exception</entry>
+ </row>
+ <row>
+ <entry><literal>COLUMN_NAME</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the name of the column related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>CONSTRAINT_NAME</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the name of the constraint related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>PG_DATATYPE_NAME</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the name of the data type related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>MESSAGE_TEXT</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the text of the exception's primary message</entry>
+ </row>
+ <row>
+ <entry><literal>TABLE_NAME</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the name of the table related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>SCHEMA_NAME</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the name of the schema related to exception</entry>
+ </row>
+ <row>
+ <entry><literal>PG_EXCEPTION_DETAIL</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the text of the exception's detail message, if any</entry>
+ </row>
+ <row>
+ <entry><literal>PG_EXCEPTION_HINT</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>the text of the exception's hint message, if any</entry>
+ </row>
+ <row>
+ <entry><literal>PG_EXCEPTION_CONTEXT</literal></entry>
+ <entry><type>text</type></entry>
+ <entry>line(s) of text describing the call stack at the time of the
+ exception (see <xref linkend="plpgsql-call-stack"/>)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ If the exception did not set a value for an item, an empty string
+ will be returned.
+ </para>
+
+ <para>
+ Here is an example:
+<programlisting>
+DECLARE
+ text_var1 text;
+ text_var2 text;
+ text_var3 text;
+BEGIN
+ -- some processing which might cause an exception
+ ...
+EXCEPTION WHEN OTHERS THEN
+ GET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,
+ text_var2 = PG_EXCEPTION_DETAIL,
+ text_var3 = PG_EXCEPTION_HINT;
+END;
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-call-stack">
+ <title>Obtaining Execution Location Information</title>
+
+ <para>
+ The <command>GET DIAGNOSTICS</command> command, previously described
+ in <xref linkend="plpgsql-statements-diagnostics"/>, retrieves information
+ about current execution state (whereas the <command>GET STACKED
+ DIAGNOSTICS</command> command discussed above reports information about
+ the execution state as of a previous error). Its <literal>PG_CONTEXT</literal>
+ status item is useful for identifying the current execution
+ location. <literal>PG_CONTEXT</literal> returns a text string with line(s)
+ of text describing the call stack. The first line refers to the current
+ function and currently executing <command>GET DIAGNOSTICS</command>
+ command. The second and any subsequent lines refer to calling functions
+ further up the call stack. For example:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION outer_func() RETURNS integer AS $$
+BEGIN
+ RETURN inner_func();
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION inner_func() RETURNS integer AS $$
+DECLARE
+ stack text;
+BEGIN
+ GET DIAGNOSTICS stack = PG_CONTEXT;
+ RAISE NOTICE E'--- Call Stack ---\n%', stack;
+ RETURN 1;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT outer_func();
+
+NOTICE: --- Call Stack ---
+PL/pgSQL function inner_func() line 5 at GET DIAGNOSTICS
+PL/pgSQL function outer_func() line 3 at RETURN
+CONTEXT: PL/pgSQL function outer_func() line 3 at RETURN
+ outer_func
+ ------------
+ 1
+(1 row)
+</programlisting>
+
+ </para>
+
+ <para>
+ <literal>GET STACKED DIAGNOSTICS ... PG_EXCEPTION_CONTEXT</literal>
+ returns the same sort of stack trace, but describing the location
+ at which an error was detected, rather than the current location.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpgsql-cursors">
+ <title>Cursors</title>
+
+ <indexterm zone="plpgsql-cursors">
+ <primary>cursor</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ Rather than executing a whole query at once, it is possible to set
+ up a <firstterm>cursor</firstterm> that encapsulates the query, and then read
+ the query result a few rows at a time. One reason for doing this is
+ to avoid memory overrun when the result contains a large number of
+ rows. (However, <application>PL/pgSQL</application> users do not normally need
+ to worry about that, since <literal>FOR</literal> loops automatically use a cursor
+ internally to avoid memory problems.) A more interesting usage is to
+ return a reference to a cursor that a function has created, allowing the
+ caller to read the rows. This provides an efficient way to return
+ large row sets from functions.
+ </para>
+
+ <sect2 id="plpgsql-cursor-declarations">
+ <title>Declaring Cursor Variables</title>
+
+ <para>
+ All access to cursors in <application>PL/pgSQL</application> goes through
+ cursor variables, which are always of the special data type
+ <type>refcursor</type>. One way to create a cursor variable
+ is just to declare it as a variable of type <type>refcursor</type>.
+ Another way is to use the cursor declaration syntax,
+ which in general is:
+<synopsis>
+<replaceable>name</replaceable> <optional> <optional> NO </optional> SCROLL </optional> CURSOR <optional> ( <replaceable>arguments</replaceable> ) </optional> FOR <replaceable>query</replaceable>;
+</synopsis>
+ (<literal>FOR</literal> can be replaced by <literal>IS</literal> for
+ <productname>Oracle</productname> compatibility.)
+ If <literal>SCROLL</literal> is specified, the cursor will be capable of
+ scrolling backward; if <literal>NO SCROLL</literal> is specified, backward
+ fetches will be rejected; if neither specification appears, it is
+ query-dependent whether backward fetches will be allowed.
+ <replaceable>arguments</replaceable>, if specified, is a
+ comma-separated list of pairs <literal><replaceable>name</replaceable>
+ <replaceable>datatype</replaceable></literal> that define names to be
+ replaced by parameter values in the given query. The actual
+ values to substitute for these names will be specified later,
+ when the cursor is opened.
+ </para>
+ <para>
+ Some examples:
+<programlisting>
+DECLARE
+ curs1 refcursor;
+ curs2 CURSOR FOR SELECT * FROM tenk1;
+ curs3 CURSOR (key integer) FOR SELECT * FROM tenk1 WHERE unique1 = key;
+</programlisting>
+ All three of these variables have the data type <type>refcursor</type>,
+ but the first can be used with any query, while the second has
+ a fully specified query already <firstterm>bound</firstterm> to it, and the last
+ has a parameterized query bound to it. (<literal>key</literal> will be
+ replaced by an integer parameter value when the cursor is opened.)
+ The variable <literal>curs1</literal>
+ is said to be <firstterm>unbound</firstterm> since it is not bound to
+ any particular query.
+ </para>
+
+ <para>
+ The <literal>SCROLL</literal> option cannot be used when the cursor's
+ query uses <literal>FOR UPDATE/SHARE</literal>. Also, it is
+ best to use <literal>NO SCROLL</literal> with a query that involves
+ volatile functions. The implementation of <literal>SCROLL</literal>
+ assumes that re-reading the query's output will give consistent
+ results, which a volatile function might not do.
+ </para>
+ </sect2>
+
+ <sect2 id="plpgsql-cursor-opening">
+ <title>Opening Cursors</title>
+
+ <para>
+ Before a cursor can be used to retrieve rows, it must be
+ <firstterm>opened</firstterm>. (This is the equivalent action to the SQL
+ command <command>DECLARE CURSOR</command>.) <application>PL/pgSQL</application> has
+ three forms of the <command>OPEN</command> statement, two of which use unbound
+ cursor variables while the third uses a bound cursor variable.
+ </para>
+
+ <note>
+ <para>
+ Bound cursor variables can also be used without explicitly opening the cursor,
+ via the <command>FOR</command> statement described in
+ <xref linkend="plpgsql-cursor-for-loop"/>.
+ </para>
+ </note>
+
+ <sect3>
+ <title><command>OPEN FOR</command> <replaceable>query</replaceable></title>
+
+<synopsis>
+OPEN <replaceable>unbound_cursorvar</replaceable> <optional> <optional> NO </optional> SCROLL </optional> FOR <replaceable>query</replaceable>;
+</synopsis>
+
+ <para>
+ The cursor variable is opened and given the specified query to
+ execute. The cursor cannot be open already, and it must have been
+ declared as an unbound cursor variable (that is, as a simple
+ <type>refcursor</type> variable). The query must be a
+ <command>SELECT</command>, or something else that returns rows
+ (such as <command>EXPLAIN</command>). The query
+ is treated in the same way as other SQL commands in
+ <application>PL/pgSQL</application>: <application>PL/pgSQL</application>
+ variable names are substituted, and the query plan is cached for
+ possible reuse. When a <application>PL/pgSQL</application>
+ variable is substituted into the cursor query, the value that is
+ substituted is the one it has at the time of the <command>OPEN</command>;
+ subsequent changes to the variable will not affect the cursor's
+ behavior.
+ The <literal>SCROLL</literal> and <literal>NO SCROLL</literal>
+ options have the same meanings as for a bound cursor.
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+OPEN curs1 FOR SELECT * FROM foo WHERE key = mykey;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><command>OPEN FOR EXECUTE</command></title>
+
+<synopsis>
+OPEN <replaceable>unbound_cursorvar</replaceable> <optional> <optional> NO </optional> SCROLL </optional> FOR EXECUTE <replaceable class="command">query_string</replaceable>
+ <optional> USING <replaceable>expression</replaceable> <optional>, ... </optional> </optional>;
+</synopsis>
+
+ <para>
+ The cursor variable is opened and given the specified query to
+ execute. The cursor cannot be open already, and it must have been
+ declared as an unbound cursor variable (that is, as a simple
+ <type>refcursor</type> variable). The query is specified as a string
+ expression, in the same way as in the <command>EXECUTE</command>
+ command. As usual, this gives flexibility so the query plan can vary
+ from one run to the next (see <xref linkend="plpgsql-plan-caching"/>),
+ and it also means that variable substitution is not done on the
+ command string. As with <command>EXECUTE</command>, parameter values
+ can be inserted into the dynamic command via
+ <literal>format()</literal> and <literal>USING</literal>.
+ The <literal>SCROLL</literal> and
+ <literal>NO SCROLL</literal> options have the same meanings as for a bound
+ cursor.
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+OPEN curs1 FOR EXECUTE format('SELECT * FROM %I WHERE col1 = $1',tabname) USING keyvalue;
+</programlisting>
+ In this example, the table name is inserted into the query via
+ <function>format()</function>. The comparison value for <literal>col1</literal>
+ is inserted via a <literal>USING</literal> parameter, so it needs
+ no quoting.
+ </para>
+ </sect3>
+
+ <sect3 id="plpgsql-open-bound-cursor">
+ <title>Opening a Bound Cursor</title>
+
+<synopsis>
+OPEN <replaceable>bound_cursorvar</replaceable> <optional> ( <optional> <replaceable>argument_name</replaceable> := </optional> <replaceable>argument_value</replaceable> <optional>, ...</optional> ) </optional>;
+</synopsis>
+
+ <para>
+ This form of <command>OPEN</command> is used to open a cursor
+ variable whose query was bound to it when it was declared. The
+ cursor cannot be open already. A list of actual argument value
+ expressions must appear if and only if the cursor was declared to
+ take arguments. These values will be substituted in the query.
+ </para>
+
+ <para>
+ The query plan for a bound cursor is always considered cacheable;
+ there is no equivalent of <command>EXECUTE</command> in this case.
+ Notice that <literal>SCROLL</literal> and <literal>NO SCROLL</literal> cannot be
+ specified in <command>OPEN</command>, as the cursor's scrolling
+ behavior was already determined.
+ </para>
+
+ <para>
+ Argument values can be passed using either <firstterm>positional</firstterm>
+ or <firstterm>named</firstterm> notation. In positional
+ notation, all arguments are specified in order. In named notation,
+ each argument's name is specified using <literal>:=</literal> to
+ separate it from the argument expression. Similar to calling
+ functions, described in <xref linkend="sql-syntax-calling-funcs"/>, it
+ is also allowed to mix positional and named notation.
+ </para>
+
+ <para>
+ Examples (these use the cursor declaration examples above):
+<programlisting>
+OPEN curs2;
+OPEN curs3(42);
+OPEN curs3(key := 42);
+</programlisting>
+ </para>
+
+ <para>
+ Because variable substitution is done on a bound cursor's query,
+ there are really two ways to pass values into the cursor: either
+ with an explicit argument to <command>OPEN</command>, or implicitly by
+ referencing a <application>PL/pgSQL</application> variable in the query.
+ However, only variables declared before the bound cursor was
+ declared will be substituted into it. In either case the value to
+ be passed is determined at the time of the <command>OPEN</command>.
+ For example, another way to get the same effect as the
+ <literal>curs3</literal> example above is
+<programlisting>
+DECLARE
+ key integer;
+ curs4 CURSOR FOR SELECT * FROM tenk1 WHERE unique1 = key;
+BEGIN
+ key := 42;
+ OPEN curs4;
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-cursor-using">
+ <title>Using Cursors</title>
+
+ <para>
+ Once a cursor has been opened, it can be manipulated with the
+ statements described here.
+ </para>
+
+ <para>
+ These manipulations need not occur in the same function that
+ opened the cursor to begin with. You can return a <type>refcursor</type>
+ value out of a function and let the caller operate on the cursor.
+ (Internally, a <type>refcursor</type> value is simply the string name
+ of a so-called portal containing the active query for the cursor. This name
+ can be passed around, assigned to other <type>refcursor</type> variables,
+ and so on, without disturbing the portal.)
+ </para>
+
+ <para>
+ All portals are implicitly closed at transaction end. Therefore
+ a <type>refcursor</type> value is usable to reference an open cursor
+ only until the end of the transaction.
+ </para>
+
+ <sect3>
+ <title><literal>FETCH</literal></title>
+
+<synopsis>
+FETCH <optional> <replaceable>direction</replaceable> { FROM | IN } </optional> <replaceable>cursor</replaceable> INTO <replaceable>target</replaceable>;
+</synopsis>
+
+ <para>
+ <command>FETCH</command> retrieves the next row from the
+ cursor into a target, which might be a row variable, a record
+ variable, or a comma-separated list of simple variables, just like
+ <command>SELECT INTO</command>. If there is no next row, the
+ target is set to NULL(s). As with <command>SELECT
+ INTO</command>, the special variable <literal>FOUND</literal> can
+ be checked to see whether a row was obtained or not.
+ </para>
+
+ <para>
+ The <replaceable>direction</replaceable> clause can be any of the
+ variants allowed in the SQL <xref linkend="sql-fetch"/>
+ command except the ones that can fetch
+ more than one row; namely, it can be
+ <literal>NEXT</literal>,
+ <literal>PRIOR</literal>,
+ <literal>FIRST</literal>,
+ <literal>LAST</literal>,
+ <literal>ABSOLUTE</literal> <replaceable>count</replaceable>,
+ <literal>RELATIVE</literal> <replaceable>count</replaceable>,
+ <literal>FORWARD</literal>, or
+ <literal>BACKWARD</literal>.
+ Omitting <replaceable>direction</replaceable> is the same
+ as specifying <literal>NEXT</literal>.
+ In the forms using a <replaceable>count</replaceable>,
+ the <replaceable>count</replaceable> can be any integer-valued
+ expression (unlike the SQL <command>FETCH</command> command,
+ which only allows an integer constant).
+ <replaceable>direction</replaceable> values that require moving
+ backward are likely to fail unless the cursor was declared or opened
+ with the <literal>SCROLL</literal> option.
+ </para>
+
+ <para>
+ <replaceable>cursor</replaceable> must be the name of a <type>refcursor</type>
+ variable that references an open cursor portal.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+FETCH curs1 INTO rowvar;
+FETCH curs2 INTO foo, bar, baz;
+FETCH LAST FROM curs3 INTO x, y;
+FETCH RELATIVE -2 FROM curs4 INTO x;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>MOVE</literal></title>
+
+<synopsis>
+MOVE <optional> <replaceable>direction</replaceable> { FROM | IN } </optional> <replaceable>cursor</replaceable>;
+</synopsis>
+
+ <para>
+ <command>MOVE</command> repositions a cursor without retrieving
+ any data. <command>MOVE</command> works exactly like the
+ <command>FETCH</command> command, except it only repositions the
+ cursor and does not return the row moved to. As with <command>SELECT
+ INTO</command>, the special variable <literal>FOUND</literal> can
+ be checked to see whether there was a next row to move to.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+MOVE curs1;
+MOVE LAST FROM curs3;
+MOVE RELATIVE -2 FROM curs4;
+MOVE FORWARD 2 FROM curs4;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>UPDATE/DELETE WHERE CURRENT OF</literal></title>
+
+<synopsis>
+UPDATE <replaceable>table</replaceable> SET ... WHERE CURRENT OF <replaceable>cursor</replaceable>;
+DELETE FROM <replaceable>table</replaceable> WHERE CURRENT OF <replaceable>cursor</replaceable>;
+</synopsis>
+
+ <para>
+ When a cursor is positioned on a table row, that row can be updated
+ or deleted using the cursor to identify the row. There are
+ restrictions on what the cursor's query can be (in particular,
+ no grouping) and it's best to use <literal>FOR UPDATE</literal> in the
+ cursor. For more information see the
+ <xref linkend="sql-declare"/>
+ reference page.
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+UPDATE foo SET dataval = myval WHERE CURRENT OF curs1;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><literal>CLOSE</literal></title>
+
+<synopsis>
+CLOSE <replaceable>cursor</replaceable>;
+</synopsis>
+
+ <para>
+ <command>CLOSE</command> closes the portal underlying an open
+ cursor. This can be used to release resources earlier than end of
+ transaction, or to free up the cursor variable to be opened again.
+ </para>
+
+ <para>
+ An example:
+<programlisting>
+CLOSE curs1;
+</programlisting>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Returning Cursors</title>
+
+ <para>
+ <application>PL/pgSQL</application> functions can return cursors to the
+ caller. This is useful to return multiple rows or columns,
+ especially with very large result sets. To do this, the function
+ opens the cursor and returns the cursor name to the caller (or simply
+ opens the cursor using a portal name specified by or otherwise known
+ to the caller). The caller can then fetch rows from the cursor. The
+ cursor can be closed by the caller, or it will be closed automatically
+ when the transaction closes.
+ </para>
+
+ <para>
+ The portal name used for a cursor can be specified by the
+ programmer or automatically generated. To specify a portal name,
+ simply assign a string to the <type>refcursor</type> variable before
+ opening it. The string value of the <type>refcursor</type> variable
+ will be used by <command>OPEN</command> as the name of the underlying portal.
+ However, if the <type>refcursor</type> variable is null,
+ <command>OPEN</command> automatically generates a name that does not
+ conflict with any existing portal, and assigns it to the
+ <type>refcursor</type> variable.
+ </para>
+
+ <note>
+ <para>
+ A bound cursor variable is initialized to the string value
+ representing its name, so that the portal name is the same as
+ the cursor variable name, unless the programmer overrides it
+ by assignment before opening the cursor. But an unbound cursor
+ variable defaults to the null value initially, so it will receive
+ an automatically-generated unique name, unless overridden.
+ </para>
+ </note>
+
+ <para>
+ The following example shows one way a cursor name can be supplied by
+ the caller:
+
+<programlisting>
+CREATE TABLE test (col text);
+INSERT INTO test VALUES ('123');
+
+CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
+BEGIN
+ OPEN $1 FOR SELECT col FROM test;
+ RETURN $1;
+END;
+' LANGUAGE plpgsql;
+
+BEGIN;
+SELECT reffunc('funccursor');
+FETCH ALL IN funccursor;
+COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ The following example uses automatic cursor name generation:
+
+<programlisting>
+CREATE FUNCTION reffunc2() RETURNS refcursor AS '
+DECLARE
+ ref refcursor;
+BEGIN
+ OPEN ref FOR SELECT col FROM test;
+ RETURN ref;
+END;
+' LANGUAGE plpgsql;
+
+-- need to be in a transaction to use cursors.
+BEGIN;
+SELECT reffunc2();
+
+ reffunc2
+--------------------
+ &lt;unnamed cursor 1&gt;
+(1 row)
+
+FETCH ALL IN "&lt;unnamed cursor 1&gt;";
+COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ The following example shows one way to return multiple cursors
+ from a single function:
+
+<programlisting>
+CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$
+BEGIN
+ OPEN $1 FOR SELECT * FROM table_1;
+ RETURN NEXT $1;
+ OPEN $2 FOR SELECT * FROM table_2;
+ RETURN NEXT $2;
+END;
+$$ LANGUAGE plpgsql;
+
+-- need to be in a transaction to use cursors.
+BEGIN;
+
+SELECT * FROM myfunc('a', 'b');
+
+FETCH ALL FROM a;
+FETCH ALL FROM b;
+COMMIT;
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-cursor-for-loop">
+ <title>Looping through a Cursor's Result</title>
+
+ <para>
+ There is a variant of the <command>FOR</command> statement that allows
+ iterating through the rows returned by a cursor. The syntax is:
+
+<synopsis>
+<optional> &lt;&lt;<replaceable>label</replaceable>&gt;&gt; </optional>
+FOR <replaceable>recordvar</replaceable> IN <replaceable>bound_cursorvar</replaceable> <optional> ( <optional> <replaceable>argument_name</replaceable> := </optional> <replaceable>argument_value</replaceable> <optional>, ...</optional> ) </optional> LOOP
+ <replaceable>statements</replaceable>
+END LOOP <optional> <replaceable>label</replaceable> </optional>;
+</synopsis>
+
+ The cursor variable must have been bound to some query when it was
+ declared, and it <emphasis>cannot</emphasis> be open already. The
+ <command>FOR</command> statement automatically opens the cursor, and it closes
+ the cursor again when the loop exits. A list of actual argument value
+ expressions must appear if and only if the cursor was declared to take
+ arguments. These values will be substituted in the query, in just
+ the same way as during an <command>OPEN</command> (see <xref
+ linkend="plpgsql-open-bound-cursor"/>).
+ </para>
+
+ <para>
+ The variable <replaceable>recordvar</replaceable> is automatically
+ defined as type <type>record</type> and exists only inside the loop (any
+ existing definition of the variable name is ignored within the loop).
+ Each row returned by the cursor is successively assigned to this
+ record variable and the loop body is executed.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="plpgsql-transactions">
+ <title>Transaction Management</title>
+
+ <para>
+ In procedures invoked by the <command>CALL</command> command
+ as well as in anonymous code blocks (<command>DO</command> command),
+ it is possible to end transactions using the
+ commands <command>COMMIT</command> and <command>ROLLBACK</command>. A new
+ transaction is started automatically after a transaction is ended using
+ these commands, so there is no separate <command>START
+ TRANSACTION</command> command. (Note that <command>BEGIN</command> and
+ <command>END</command> have different meanings in PL/pgSQL.)
+ </para>
+
+ <para>
+ Here is a simple example:
+<programlisting>
+CREATE PROCEDURE transaction_test1()
+LANGUAGE plpgsql
+AS $$
+BEGIN
+ FOR i IN 0..9 LOOP
+ INSERT INTO test1 (a) VALUES (i);
+ IF i % 2 = 0 THEN
+ COMMIT;
+ ELSE
+ ROLLBACK;
+ END IF;
+ END LOOP;
+END;
+$$;
+
+CALL transaction_test1();
+</programlisting>
+ </para>
+
+ <indexterm zone="plpgsql-transaction-chain">
+ <primary>chained transactions</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para id="plpgsql-transaction-chain">
+ A new transaction starts out with default transaction characteristics such
+ as transaction isolation level. In cases where transactions are committed
+ in a loop, it might be desirable to start new transactions automatically
+ with the same characteristics as the previous one. The commands
+ <command>COMMIT AND CHAIN</command> and <command>ROLLBACK AND
+ CHAIN</command> accomplish this.
+ </para>
+
+ <para>
+ Transaction control is only possible in <command>CALL</command> or
+ <command>DO</command> invocations from the top level or nested
+ <command>CALL</command> or <command>DO</command> invocations without any
+ other intervening command. For example, if the call stack is
+ <command>CALL proc1()</command> &rarr; <command>CALL proc2()</command>
+ &rarr; <command>CALL proc3()</command>, then the second and third
+ procedures can perform transaction control actions. But if the call stack
+ is <command>CALL proc1()</command> &rarr; <command>SELECT
+ func2()</command> &rarr; <command>CALL proc3()</command>, then the last
+ procedure cannot do transaction control, because of the
+ <command>SELECT</command> in between.
+ </para>
+
+ <para>
+ Special considerations apply to cursor loops. Consider this example:
+<programlisting>
+CREATE PROCEDURE transaction_test2()
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ r RECORD;
+BEGIN
+ FOR r IN SELECT * FROM test2 ORDER BY x LOOP
+ INSERT INTO test1 (a) VALUES (r.x);
+ COMMIT;
+ END LOOP;
+END;
+$$;
+
+CALL transaction_test2();
+</programlisting>
+ Normally, cursors are automatically closed at transaction commit.
+ However, a cursor created as part of a loop like this is automatically
+ converted to a holdable cursor by the first <command>COMMIT</command> or
+ <command>ROLLBACK</command>. That means that the cursor is fully
+ evaluated at the first <command>COMMIT</command> or
+ <command>ROLLBACK</command> rather than row by row. The cursor is still
+ removed automatically after the loop, so this is mostly invisible to the
+ user.
+ </para>
+
+ <para>
+ Transaction commands are not allowed in cursor loops driven by commands
+ that are not read-only (for example <command>UPDATE
+ ... RETURNING</command>).
+ </para>
+
+ <para>
+ A transaction cannot be ended inside a block with exception handlers.
+ </para>
+ </sect1>
+
+ <sect1 id="plpgsql-errors-and-messages">
+ <title>Errors and Messages</title>
+
+ <sect2 id="plpgsql-statements-raise">
+ <title>Reporting Errors and Messages</title>
+
+ <indexterm>
+ <primary>RAISE</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>reporting errors</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ Use the <command>RAISE</command> statement to report messages and
+ raise errors.
+
+<synopsis>
+RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> '<replaceable class="parameter">format</replaceable>' <optional>, <replaceable class="parameter">expression</replaceable> <optional>, ... </optional></optional> <optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional> </optional>;
+RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> <replaceable class="parameter">condition_name</replaceable> <optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional> </optional>;
+RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> SQLSTATE '<replaceable class="parameter">sqlstate</replaceable>' <optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional> </optional>;
+RAISE <optional> <replaceable class="parameter">level</replaceable> </optional> USING <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">expression</replaceable> <optional>, ... </optional>;
+RAISE ;
+</synopsis>
+
+ The <replaceable class="parameter">level</replaceable> option specifies
+ the error severity. Allowed levels are <literal>DEBUG</literal>,
+ <literal>LOG</literal>, <literal>INFO</literal>,
+ <literal>NOTICE</literal>, <literal>WARNING</literal>,
+ and <literal>EXCEPTION</literal>, with <literal>EXCEPTION</literal>
+ being the default.
+ <literal>EXCEPTION</literal> raises an error (which normally aborts the
+ current transaction); the other levels only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <xref linkend="guc-log-min-messages"/> and
+ <xref linkend="guc-client-min-messages"/> configuration
+ variables. See <xref linkend="runtime-config"/> for more
+ information.
+ </para>
+
+ <para>
+ After <replaceable class="parameter">level</replaceable> if any,
+ you can specify a <replaceable class="parameter">format</replaceable> string
+ (which must be a simple string literal, not an expression). The
+ format string specifies the error message text to be reported.
+ The format string can be followed
+ by optional argument expressions to be inserted into the message.
+ Inside the format string, <literal>%</literal> is replaced by the
+ string representation of the next optional argument's value. Write
+ <literal>%%</literal> to emit a literal <literal>%</literal>.
+ The number of arguments must match the number of <literal>%</literal>
+ placeholders in the format string, or an error is raised during
+ the compilation of the function.
+ </para>
+
+ <para>
+ In this example, the value of <literal>v_job_id</literal> will replace the
+ <literal>%</literal> in the string:
+<programlisting>
+RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;
+</programlisting>
+ </para>
+
+ <para>
+ You can attach additional information to the error report by writing
+ <literal>USING</literal> followed by <replaceable
+ class="parameter">option</replaceable> = <replaceable
+ class="parameter">expression</replaceable> items. Each
+ <replaceable class="parameter">expression</replaceable> can be any
+ string-valued expression. The allowed <replaceable
+ class="parameter">option</replaceable> key words are:
+
+ <variablelist id="raise-using-options">
+ <varlistentry>
+ <term><literal>MESSAGE</literal></term>
+ <listitem>
+ <para>Sets the error message text. This option can't be used in the
+ form of <command>RAISE</command> that includes a format string
+ before <literal>USING</literal>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DETAIL</literal></term>
+ <listitem>
+ <para>Supplies an error detail message.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HINT</literal></term>
+ <listitem>
+ <para>Supplies a hint message.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ERRCODE</literal></term>
+ <listitem>
+ <para>Specifies the error code (SQLSTATE) to report, either by condition
+ name, as shown in <xref linkend="errcodes-appendix"/>, or directly as a
+ five-character SQLSTATE code.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COLUMN</literal></term>
+ <term><literal>CONSTRAINT</literal></term>
+ <term><literal>DATATYPE</literal></term>
+ <term><literal>TABLE</literal></term>
+ <term><literal>SCHEMA</literal></term>
+ <listitem>
+ <para>Supplies the name of a related object.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ This example will abort the transaction with the given error message
+ and hint:
+<programlisting>
+RAISE EXCEPTION 'Nonexistent ID --> %', user_id
+ USING HINT = 'Please check your user ID';
+</programlisting>
+ </para>
+
+ <para>
+ These two examples show equivalent ways of setting the SQLSTATE:
+<programlisting>
+RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
+RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
+</programlisting>
+ </para>
+
+ <para>
+ There is a second <command>RAISE</command> syntax in which the main argument
+ is the condition name or SQLSTATE to be reported, for example:
+<programlisting>
+RAISE division_by_zero;
+RAISE SQLSTATE '22012';
+</programlisting>
+ In this syntax, <literal>USING</literal> can be used to supply a custom
+ error message, detail, or hint. Another way to do the earlier
+ example is
+<programlisting>
+RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;
+</programlisting>
+ </para>
+
+ <para>
+ Still another variant is to write <literal>RAISE USING</literal> or <literal>RAISE
+ <replaceable class="parameter">level</replaceable> USING</literal> and put
+ everything else into the <literal>USING</literal> list.
+ </para>
+
+ <para>
+ The last variant of <command>RAISE</command> has no parameters at all.
+ This form can only be used inside a <literal>BEGIN</literal> block's
+ <literal>EXCEPTION</literal> clause;
+ it causes the error currently being handled to be re-thrown.
+ </para>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 9.1, <command>RAISE</command> without
+ parameters was interpreted as re-throwing the error from the block
+ containing the active exception handler. Thus an <literal>EXCEPTION</literal>
+ clause nested within that handler could not catch it, even if the
+ <command>RAISE</command> was within the nested <literal>EXCEPTION</literal> clause's
+ block. This was deemed surprising as well as being incompatible with
+ Oracle's PL/SQL.
+ </para>
+ </note>
+
+ <para>
+ If no condition name nor SQLSTATE is specified in a
+ <command>RAISE EXCEPTION</command> command, the default is to use
+ <literal>ERRCODE_RAISE_EXCEPTION</literal> (<literal>P0001</literal>).
+ If no message text is specified, the default is to use the condition
+ name or SQLSTATE as message text.
+ </para>
+
+ <note>
+ <para>
+ When specifying an error code by SQLSTATE code, you are not
+ limited to the predefined error codes, but can select any
+ error code consisting of five digits and/or upper-case ASCII
+ letters, other than <literal>00000</literal>. It is recommended that
+ you avoid throwing error codes that end in three zeroes, because
+ these are category codes and can only be trapped by trapping
+ the whole category.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="plpgsql-statements-assert">
+ <title>Checking Assertions</title>
+
+ <indexterm>
+ <primary>ASSERT</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>assertions</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary><varname>plpgsql.check_asserts</varname> configuration parameter</primary>
+ </indexterm>
+
+ <para>
+ The <command>ASSERT</command> statement is a convenient shorthand for
+ inserting debugging checks into <application>PL/pgSQL</application>
+ functions.
+
+<synopsis>
+ASSERT <replaceable class="parameter">condition</replaceable> <optional> , <replaceable class="parameter">message</replaceable> </optional>;
+</synopsis>
+
+ The <replaceable class="parameter">condition</replaceable> is a Boolean
+ expression that is expected to always evaluate to true; if it does,
+ the <command>ASSERT</command> statement does nothing further. If the
+ result is false or null, then an <literal>ASSERT_FAILURE</literal> exception
+ is raised. (If an error occurs while evaluating
+ the <replaceable class="parameter">condition</replaceable>, it is
+ reported as a normal error.)
+ </para>
+
+ <para>
+ If the optional <replaceable class="parameter">message</replaceable> is
+ provided, it is an expression whose result (if not null) replaces the
+ default error message text <quote>assertion failed</quote>, should
+ the <replaceable class="parameter">condition</replaceable> fail.
+ The <replaceable class="parameter">message</replaceable> expression is
+ not evaluated in the normal case where the assertion succeeds.
+ </para>
+
+ <para>
+ Testing of assertions can be enabled or disabled via the configuration
+ parameter <literal>plpgsql.check_asserts</literal>, which takes a Boolean
+ value; the default is <literal>on</literal>. If this parameter
+ is <literal>off</literal> then <command>ASSERT</command> statements do nothing.
+ </para>
+
+ <para>
+ Note that <command>ASSERT</command> is meant for detecting program
+ bugs, not for reporting ordinary error conditions. Use
+ the <command>RAISE</command> statement, described above, for that.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="plpgsql-trigger">
+ <title>Trigger Functions</title>
+
+ <indexterm zone="plpgsql-trigger">
+ <primary>trigger</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ <application>PL/pgSQL</application> can be used to define trigger
+ functions on data changes or database events.
+ A trigger function is created with the <command>CREATE FUNCTION</command>
+ command, declaring it as a function with no arguments and a return type of
+ <type>trigger</type> (for data change triggers) or
+ <type>event_trigger</type> (for database event triggers).
+ Special local variables named <varname>TG_<replaceable>something</replaceable></varname> are
+ automatically defined to describe the condition that triggered the call.
+ </para>
+
+ <sect2 id="plpgsql-dml-trigger">
+ <title>Triggers on Data Changes</title>
+
+ <para>
+ A <link linkend="triggers">data change trigger</link> is declared as a
+ function with no arguments and a return type of <type>trigger</type>.
+ Note that the function must be declared with no arguments even if it
+ expects to receive some arguments specified in <command>CREATE TRIGGER</command>
+ &mdash; such arguments are passed via <varname>TG_ARGV</varname>, as described
+ below.
+ </para>
+
+ <para>
+ When a <application>PL/pgSQL</application> function is called as a
+ trigger, several special variables are created automatically in the
+ top-level block. They are:
+
+ <variablelist>
+ <varlistentry>
+ <term><varname>NEW</varname></term>
+ <listitem>
+ <para>
+ Data type <type>RECORD</type>; variable holding the new
+ database row for <command>INSERT</command>/<command>UPDATE</command> operations in row-level
+ triggers. This variable is null in statement-level triggers
+ and for <command>DELETE</command> operations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>OLD</varname></term>
+ <listitem>
+ <para>
+ Data type <type>RECORD</type>; variable holding the old
+ database row for <command>UPDATE</command>/<command>DELETE</command> operations in row-level
+ triggers. This variable is null in statement-level triggers
+ and for <command>INSERT</command> operations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_NAME</varname></term>
+ <listitem>
+ <para>
+ Data type <type>name</type>; variable that contains the name of the trigger actually
+ fired.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_WHEN</varname></term>
+ <listitem>
+ <para>
+ Data type <type>text</type>; a string of
+ <literal>BEFORE</literal>, <literal>AFTER</literal>, or
+ <literal>INSTEAD OF</literal>, depending on the trigger's definition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_LEVEL</varname></term>
+ <listitem>
+ <para>
+ Data type <type>text</type>; a string of either
+ <literal>ROW</literal> or <literal>STATEMENT</literal>
+ depending on the trigger's definition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_OP</varname></term>
+ <listitem>
+ <para>
+ Data type <type>text</type>; a string of
+ <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, or <literal>TRUNCATE</literal>
+ telling for which operation the trigger was fired.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_RELID</varname></term>
+ <listitem>
+ <para>
+ Data type <type>oid</type>; the object ID of the table that caused the
+ trigger invocation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_RELNAME</varname></term>
+ <listitem>
+ <para>
+ Data type <type>name</type>; the name of the table that caused the trigger
+ invocation. This is now deprecated, and could disappear in a future
+ release. Use <literal>TG_TABLE_NAME</literal> instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_TABLE_NAME</varname></term>
+ <listitem>
+ <para>
+ Data type <type>name</type>; the name of the table that
+ caused the trigger invocation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_TABLE_SCHEMA</varname></term>
+ <listitem>
+ <para>
+ Data type <type>name</type>; the name of the schema of the
+ table that caused the trigger invocation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_NARGS</varname></term>
+ <listitem>
+ <para>
+ Data type <type>integer</type>; the number of arguments given to the trigger
+ function in the <command>CREATE TRIGGER</command> statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_ARGV[]</varname></term>
+ <listitem>
+ <para>
+ Data type array of <type>text</type>; the arguments from
+ the <command>CREATE TRIGGER</command> statement.
+ The index counts from 0. Invalid
+ indexes (less than 0 or greater than or equal to <varname>tg_nargs</varname>)
+ result in a null value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ A trigger function must return either <symbol>NULL</symbol> or a
+ record/row value having exactly the structure of the table the
+ trigger was fired for.
+ </para>
+
+ <para>
+ Row-level triggers fired <literal>BEFORE</literal> can return null to signal the
+ trigger manager to skip the rest of the operation for this row
+ (i.e., subsequent triggers are not fired, and the
+ <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> does not occur
+ for this row). If a nonnull
+ value is returned then the operation proceeds with that row value.
+ Returning a row value different from the original value
+ of <varname>NEW</varname> alters the row that will be inserted or
+ updated. Thus, if the trigger function wants the triggering
+ action to succeed normally without altering the row
+ value, <varname>NEW</varname> (or a value equal thereto) has to be
+ returned. To alter the row to be stored, it is possible to
+ replace single values directly in <varname>NEW</varname> and return the
+ modified <varname>NEW</varname>, or to build a complete new record/row to
+ return. In the case of a before-trigger
+ on <command>DELETE</command>, the returned value has no direct
+ effect, but it has to be nonnull to allow the trigger action to
+ proceed. Note that <varname>NEW</varname> is null
+ in <command>DELETE</command> triggers, so returning that is
+ usually not sensible. The usual idiom in <command>DELETE</command>
+ triggers is to return <varname>OLD</varname>.
+ </para>
+
+ <para>
+ <literal>INSTEAD OF</literal> triggers (which are always row-level triggers,
+ and may only be used on views) can return null to signal that they did
+ not perform any updates, and that the rest of the operation for this
+ row should be skipped (i.e., subsequent triggers are not fired, and the
+ row is not counted in the rows-affected status for the surrounding
+ <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>).
+ Otherwise a nonnull value should be returned, to signal
+ that the trigger performed the requested operation. For
+ <command>INSERT</command> and <command>UPDATE</command> operations, the return value
+ should be <varname>NEW</varname>, which the trigger function may modify to
+ support <command>INSERT RETURNING</command> and <command>UPDATE RETURNING</command>
+ (this will also affect the row value passed to any subsequent triggers,
+ or passed to a special <varname>EXCLUDED</varname> alias reference within
+ an <command>INSERT</command> statement with an <literal>ON CONFLICT DO
+ UPDATE</literal> clause). For <command>DELETE</command> operations, the return
+ value should be <varname>OLD</varname>.
+ </para>
+
+ <para>
+ The return value of a row-level trigger
+ fired <literal>AFTER</literal> or a statement-level trigger
+ fired <literal>BEFORE</literal> or <literal>AFTER</literal> is
+ always ignored; it might as well be null. However, any of these types of
+ triggers might still abort the entire operation by raising an error.
+ </para>
+
+ <para>
+ <xref linkend="plpgsql-trigger-example"/> shows an example of a
+ trigger function in <application>PL/pgSQL</application>.
+ </para>
+
+ <example id="plpgsql-trigger-example">
+ <title>A <application>PL/pgSQL</application> Trigger Function</title>
+
+ <para>
+ This example trigger ensures that any time a row is inserted or updated
+ in the table, the current user name and time are stamped into the
+ row. And it checks that an employee's name is given and that the
+ salary is a positive value.
+ </para>
+
+<programlisting>
+CREATE TABLE emp (
+ empname text,
+ salary integer,
+ last_date timestamp,
+ last_user text
+);
+
+CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
+ BEGIN
+ -- Check that empname and salary are given
+ IF NEW.empname IS NULL THEN
+ RAISE EXCEPTION 'empname cannot be null';
+ END IF;
+ IF NEW.salary IS NULL THEN
+ RAISE EXCEPTION '% cannot have null salary', NEW.empname;
+ END IF;
+
+ -- Who works for us when they must pay for it?
+ IF NEW.salary &lt; 0 THEN
+ RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
+ END IF;
+
+ -- Remember who changed the payroll when
+ NEW.last_date := current_timestamp;
+ NEW.last_user := current_user;
+ RETURN NEW;
+ END;
+$emp_stamp$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
+ FOR EACH ROW EXECUTE FUNCTION emp_stamp();
+</programlisting>
+ </example>
+
+ <para>
+ Another way to log changes to a table involves creating a new table that
+ holds a row for each insert, update, or delete that occurs. This approach
+ can be thought of as auditing changes to a table.
+ <xref linkend="plpgsql-trigger-audit-example"/> shows an example of an
+ audit trigger function in <application>PL/pgSQL</application>.
+ </para>
+
+ <example id="plpgsql-trigger-audit-example">
+ <title>A <application>PL/pgSQL</application> Trigger Function for Auditing</title>
+
+ <para>
+ This example trigger ensures that any insert, update or delete of a row
+ in the <literal>emp</literal> table is recorded (i.e., audited) in the <literal>emp_audit</literal> table.
+ The current time and user name are stamped into the row, together with
+ the type of operation performed on it.
+ </para>
+
+<programlisting>
+CREATE TABLE emp (
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE TABLE emp_audit(
+ operation char(1) NOT NULL,
+ stamp timestamp NOT NULL,
+ userid text NOT NULL,
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$
+ BEGIN
+ --
+ -- Create a row in emp_audit to reflect the operation performed on emp,
+ -- making use of the special variable TG_OP to work out the operation.
+ --
+ IF (TG_OP = 'DELETE') THEN
+ INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*;
+ ELSIF (TG_OP = 'UPDATE') THEN
+ INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;
+ END IF;
+ RETURN NULL; -- result is ignored since this is an AFTER trigger
+ END;
+$emp_audit$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_audit
+AFTER INSERT OR UPDATE OR DELETE ON emp
+ FOR EACH ROW EXECUTE FUNCTION process_emp_audit();
+</programlisting>
+ </example>
+
+ <para>
+ A variation of the previous example uses a view joining the main table
+ to the audit table, to show when each entry was last modified. This
+ approach still records the full audit trail of changes to the table,
+ but also presents a simplified view of the audit trail, showing just
+ the last modified timestamp derived from the audit trail for each entry.
+ <xref linkend="plpgsql-view-trigger-audit-example"/> shows an example
+ of an audit trigger on a view in <application>PL/pgSQL</application>.
+ </para>
+
+ <example id="plpgsql-view-trigger-audit-example">
+ <title>A <application>PL/pgSQL</application> View Trigger Function for Auditing</title>
+
+ <para>
+ This example uses a trigger on the view to make it updatable, and
+ ensure that any insert, update or delete of a row in the view is
+ recorded (i.e., audited) in the <literal>emp_audit</literal> table. The current time
+ and user name are recorded, together with the type of operation
+ performed, and the view displays the last modified time of each row.
+ </para>
+
+<programlisting>
+CREATE TABLE emp (
+ empname text PRIMARY KEY,
+ salary integer
+);
+
+CREATE TABLE emp_audit(
+ operation char(1) NOT NULL,
+ userid text NOT NULL,
+ empname text NOT NULL,
+ salary integer,
+ stamp timestamp NOT NULL
+);
+
+CREATE VIEW emp_view AS
+ SELECT e.empname,
+ e.salary,
+ max(ea.stamp) AS last_updated
+ FROM emp e
+ LEFT JOIN emp_audit ea ON ea.empname = e.empname
+ GROUP BY 1, 2;
+
+CREATE OR REPLACE FUNCTION update_emp_view() RETURNS TRIGGER AS $$
+ BEGIN
+ --
+ -- Perform the required operation on emp, and create a row in emp_audit
+ -- to reflect the change made to emp.
+ --
+ IF (TG_OP = 'DELETE') THEN
+ DELETE FROM emp WHERE empname = OLD.empname;
+ IF NOT FOUND THEN RETURN NULL; END IF;
+
+ OLD.last_updated = now();
+ INSERT INTO emp_audit VALUES('D', user, OLD.*);
+ RETURN OLD;
+ ELSIF (TG_OP = 'UPDATE') THEN
+ UPDATE emp SET salary = NEW.salary WHERE empname = OLD.empname;
+ IF NOT FOUND THEN RETURN NULL; END IF;
+
+ NEW.last_updated = now();
+ INSERT INTO emp_audit VALUES('U', user, NEW.*);
+ RETURN NEW;
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO emp VALUES(NEW.empname, NEW.salary);
+
+ NEW.last_updated = now();
+ INSERT INTO emp_audit VALUES('I', user, NEW.*);
+ RETURN NEW;
+ END IF;
+ END;
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_audit
+INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view
+ FOR EACH ROW EXECUTE FUNCTION update_emp_view();
+</programlisting>
+ </example>
+
+ <para>
+ One use of triggers is to maintain a summary table
+ of another table. The resulting summary can be used in place of the
+ original table for certain queries &mdash; often with vastly reduced run
+ times.
+ This technique is commonly used in Data Warehousing, where the tables
+ of measured or observed data (called fact tables) might be extremely large.
+ <xref linkend="plpgsql-trigger-summary-example"/> shows an example of a
+ trigger function in <application>PL/pgSQL</application> that maintains
+ a summary table for a fact table in a data warehouse.
+ </para>
+
+
+ <example id="plpgsql-trigger-summary-example">
+ <title>A <application>PL/pgSQL</application> Trigger Function for Maintaining a Summary Table</title>
+
+ <para>
+ The schema detailed here is partly based on the <emphasis>Grocery Store
+ </emphasis> example from <emphasis>The Data Warehouse Toolkit</emphasis>
+ by Ralph Kimball.
+ </para>
+
+<programlisting>
+--
+-- Main tables - time dimension and sales fact.
+--
+CREATE TABLE time_dimension (
+ time_key integer NOT NULL,
+ day_of_week integer NOT NULL,
+ day_of_month integer NOT NULL,
+ month integer NOT NULL,
+ quarter integer NOT NULL,
+ year integer NOT NULL
+);
+CREATE UNIQUE INDEX time_dimension_key ON time_dimension(time_key);
+
+CREATE TABLE sales_fact (
+ time_key integer NOT NULL,
+ product_key integer NOT NULL,
+ store_key integer NOT NULL,
+ amount_sold numeric(12,2) NOT NULL,
+ units_sold integer NOT NULL,
+ amount_cost numeric(12,2) NOT NULL
+);
+CREATE INDEX sales_fact_time ON sales_fact(time_key);
+
+--
+-- Summary table - sales by time.
+--
+CREATE TABLE sales_summary_bytime (
+ time_key integer NOT NULL,
+ amount_sold numeric(15,2) NOT NULL,
+ units_sold numeric(12) NOT NULL,
+ amount_cost numeric(15,2) NOT NULL
+);
+CREATE UNIQUE INDEX sales_summary_bytime_key ON sales_summary_bytime(time_key);
+
+--
+-- Function and trigger to amend summarized column(s) on UPDATE, INSERT, DELETE.
+--
+CREATE OR REPLACE FUNCTION maint_sales_summary_bytime() RETURNS TRIGGER
+AS $maint_sales_summary_bytime$
+ DECLARE
+ delta_time_key integer;
+ delta_amount_sold numeric(15,2);
+ delta_units_sold numeric(12);
+ delta_amount_cost numeric(15,2);
+ BEGIN
+
+ -- Work out the increment/decrement amount(s).
+ IF (TG_OP = 'DELETE') THEN
+
+ delta_time_key = OLD.time_key;
+ delta_amount_sold = -1 * OLD.amount_sold;
+ delta_units_sold = -1 * OLD.units_sold;
+ delta_amount_cost = -1 * OLD.amount_cost;
+
+ ELSIF (TG_OP = 'UPDATE') THEN
+
+ -- forbid updates that change the time_key -
+ -- (probably not too onerous, as DELETE + INSERT is how most
+ -- changes will be made).
+ IF ( OLD.time_key != NEW.time_key) THEN
+ RAISE EXCEPTION 'Update of time_key : % -&gt; % not allowed',
+ OLD.time_key, NEW.time_key;
+ END IF;
+
+ delta_time_key = OLD.time_key;
+ delta_amount_sold = NEW.amount_sold - OLD.amount_sold;
+ delta_units_sold = NEW.units_sold - OLD.units_sold;
+ delta_amount_cost = NEW.amount_cost - OLD.amount_cost;
+
+ ELSIF (TG_OP = 'INSERT') THEN
+
+ delta_time_key = NEW.time_key;
+ delta_amount_sold = NEW.amount_sold;
+ delta_units_sold = NEW.units_sold;
+ delta_amount_cost = NEW.amount_cost;
+
+ END IF;
+
+
+ -- Insert or update the summary row with the new values.
+ &lt;&lt;insert_update&gt;&gt;
+ LOOP
+ UPDATE sales_summary_bytime
+ SET amount_sold = amount_sold + delta_amount_sold,
+ units_sold = units_sold + delta_units_sold,
+ amount_cost = amount_cost + delta_amount_cost
+ WHERE time_key = delta_time_key;
+
+ EXIT insert_update WHEN found;
+
+ BEGIN
+ INSERT INTO sales_summary_bytime (
+ time_key,
+ amount_sold,
+ units_sold,
+ amount_cost)
+ VALUES (
+ delta_time_key,
+ delta_amount_sold,
+ delta_units_sold,
+ delta_amount_cost
+ );
+
+ EXIT insert_update;
+
+ EXCEPTION
+ WHEN UNIQUE_VIOLATION THEN
+ -- do nothing
+ END;
+ END LOOP insert_update;
+
+ RETURN NULL;
+
+ END;
+$maint_sales_summary_bytime$ LANGUAGE plpgsql;
+
+CREATE TRIGGER maint_sales_summary_bytime
+AFTER INSERT OR UPDATE OR DELETE ON sales_fact
+ FOR EACH ROW EXECUTE FUNCTION maint_sales_summary_bytime();
+
+INSERT INTO sales_fact VALUES(1,1,1,10,3,15);
+INSERT INTO sales_fact VALUES(1,2,1,20,5,35);
+INSERT INTO sales_fact VALUES(2,2,1,40,15,135);
+INSERT INTO sales_fact VALUES(2,3,1,10,1,13);
+SELECT * FROM sales_summary_bytime;
+DELETE FROM sales_fact WHERE product_key = 1;
+SELECT * FROM sales_summary_bytime;
+UPDATE sales_fact SET units_sold = units_sold * 2;
+SELECT * FROM sales_summary_bytime;
+</programlisting>
+ </example>
+
+ <para>
+ <literal>AFTER</literal> triggers can also make use of <firstterm>transition
+ tables</firstterm> to inspect the entire set of rows changed by the triggering
+ statement. The <command>CREATE TRIGGER</command> command assigns names to one
+ or both transition tables, and then the function can refer to those names
+ as though they were read-only temporary tables.
+ <xref linkend="plpgsql-trigger-audit-transition-example"/> shows an example.
+ </para>
+
+ <example id="plpgsql-trigger-audit-transition-example">
+ <title>Auditing with Transition Tables</title>
+
+ <para>
+ This example produces the same results as
+ <xref linkend="plpgsql-trigger-audit-example"/>, but instead of using a
+ trigger that fires for every row, it uses a trigger that fires once
+ per statement, after collecting the relevant information in a transition
+ table. This can be significantly faster than the row-trigger approach
+ when the invoking statement has modified many rows. Notice that we must
+ make a separate trigger declaration for each kind of event, since the
+ <literal>REFERENCING</literal> clauses must be different for each case. But
+ this does not stop us from using a single trigger function if we choose.
+ (In practice, it might be better to use three separate functions and
+ avoid the run-time tests on <varname>TG_OP</varname>.)
+ </para>
+
+<programlisting>
+CREATE TABLE emp (
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE TABLE emp_audit(
+ operation char(1) NOT NULL,
+ stamp timestamp NOT NULL,
+ userid text NOT NULL,
+ empname text NOT NULL,
+ salary integer
+);
+
+CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$
+ BEGIN
+ --
+ -- Create rows in emp_audit to reflect the operations performed on emp,
+ -- making use of the special variable TG_OP to work out the operation.
+ --
+ IF (TG_OP = 'DELETE') THEN
+ INSERT INTO emp_audit
+ SELECT 'D', now(), user, o.* FROM old_table o;
+ ELSIF (TG_OP = 'UPDATE') THEN
+ INSERT INTO emp_audit
+ SELECT 'U', now(), user, n.* FROM new_table n;
+ ELSIF (TG_OP = 'INSERT') THEN
+ INSERT INTO emp_audit
+ SELECT 'I', now(), user, n.* FROM new_table n;
+ END IF;
+ RETURN NULL; -- result is ignored since this is an AFTER trigger
+ END;
+$emp_audit$ LANGUAGE plpgsql;
+
+CREATE TRIGGER emp_audit_ins
+ AFTER INSERT ON emp
+ REFERENCING NEW TABLE AS new_table
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
+CREATE TRIGGER emp_audit_upd
+ AFTER UPDATE ON emp
+ REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
+CREATE TRIGGER emp_audit_del
+ AFTER DELETE ON emp
+ REFERENCING OLD TABLE AS old_table
+ FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit();
+</programlisting>
+ </example>
+
+</sect2>
+
+ <sect2 id="plpgsql-event-trigger">
+ <title>Triggers on Events</title>
+
+ <para>
+ <application>PL/pgSQL</application> can be used to define
+ <link linkend="event-triggers">event triggers</link>.
+ <productname>PostgreSQL</productname> requires that a function that
+ is to be called as an event trigger must be declared as a function with
+ no arguments and a return type of <literal>event_trigger</literal>.
+ </para>
+
+ <para>
+ When a <application>PL/pgSQL</application> function is called as an
+ event trigger, several special variables are created automatically
+ in the top-level block. They are:
+
+ <variablelist>
+ <varlistentry>
+ <term><varname>TG_EVENT</varname></term>
+ <listitem>
+ <para>
+ Data type <type>text</type>; a string representing the event the
+ trigger is fired for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>TG_TAG</varname></term>
+ <listitem>
+ <para>
+ Data type <type>text</type>; variable that contains the command tag
+ for which the trigger is fired.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <xref linkend="plpgsql-event-trigger-example"/> shows an example of an
+ event trigger function in <application>PL/pgSQL</application>.
+ </para>
+
+ <example id="plpgsql-event-trigger-example">
+ <title>A <application>PL/pgSQL</application> Event Trigger Function</title>
+
+ <para>
+ This example trigger simply raises a <literal>NOTICE</literal> message
+ each time a supported command is executed.
+ </para>
+
+<programlisting>
+CREATE OR REPLACE FUNCTION snitch() RETURNS event_trigger AS $$
+BEGIN
+ RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch();
+</programlisting>
+ </example>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="plpgsql-implementation">
+ <title><application>PL/pgSQL</application> under the Hood</title>
+
+ <para>
+ This section discusses some implementation details that are
+ frequently important for <application>PL/pgSQL</application> users to know.
+ </para>
+
+ <sect2 id="plpgsql-var-subst">
+ <title>Variable Substitution</title>
+
+ <para>
+ SQL statements and expressions within a <application>PL/pgSQL</application> function
+ can refer to variables and parameters of the function. Behind the scenes,
+ <application>PL/pgSQL</application> substitutes query parameters for such references.
+ Query parameters will only be substituted in places where they are
+ syntactically permissible. As an extreme case, consider
+ this example of poor programming style:
+<programlisting>
+INSERT INTO foo (foo) VALUES (foo(foo));
+</programlisting>
+ The first occurrence of <literal>foo</literal> must syntactically be a table
+ name, so it will not be substituted, even if the function has a variable
+ named <literal>foo</literal>. The second occurrence must be the name of a
+ column of that table, so it will not be substituted either. Likewise
+ the third occurrence must be a function name, so it also will not be
+ substituted for. Only the last occurrence is a candidate to be a
+ reference to a variable of the <application>PL/pgSQL</application>
+ function.
+ </para>
+
+ <para>
+ Another way to understand this is that variable substitution can only
+ insert data values into an SQL command; it cannot dynamically change which
+ database objects are referenced by the command. (If you want to do
+ that, you must build a command string dynamically, as explained in
+ <xref linkend="plpgsql-statements-executing-dyn"/>.)
+ </para>
+
+ <para>
+ Since the names of variables are syntactically no different from the names
+ of table columns, there can be ambiguity in statements that also refer to
+ tables: is a given name meant to refer to a table column, or a variable?
+ Let's change the previous example to
+<programlisting>
+INSERT INTO dest (col) SELECT foo + bar FROM src;
+</programlisting>
+ Here, <literal>dest</literal> and <literal>src</literal> must be table names, and
+ <literal>col</literal> must be a column of <literal>dest</literal>, but <literal>foo</literal>
+ and <literal>bar</literal> might reasonably be either variables of the function
+ or columns of <literal>src</literal>.
+ </para>
+
+ <para>
+ By default, <application>PL/pgSQL</application> will report an error if a name
+ in an SQL statement could refer to either a variable or a table column.
+ You can fix such a problem by renaming the variable or column,
+ or by qualifying the ambiguous reference, or by telling
+ <application>PL/pgSQL</application> which interpretation to prefer.
+ </para>
+
+ <para>
+ The simplest solution is to rename the variable or column.
+ A common coding rule is to use a
+ different naming convention for <application>PL/pgSQL</application>
+ variables than you use for column names. For example,
+ if you consistently name function variables
+ <literal>v_<replaceable>something</replaceable></literal> while none of your
+ column names start with <literal>v_</literal>, no conflicts will occur.
+ </para>
+
+ <para>
+ Alternatively you can qualify ambiguous references to make them clear.
+ In the above example, <literal>src.foo</literal> would be an unambiguous reference
+ to the table column. To create an unambiguous reference to a variable,
+ declare it in a labeled block and use the block's label
+ (see <xref linkend="plpgsql-structure"/>). For example,
+<programlisting>
+&lt;&lt;block&gt;&gt;
+DECLARE
+ foo int;
+BEGIN
+ foo := ...;
+ INSERT INTO dest (col) SELECT block.foo + bar FROM src;
+</programlisting>
+ Here <literal>block.foo</literal> means the variable even if there is a column
+ <literal>foo</literal> in <literal>src</literal>. Function parameters, as well as
+ special variables such as <literal>FOUND</literal>, can be qualified by the
+ function's name, because they are implicitly declared in an outer block
+ labeled with the function's name.
+ </para>
+
+ <para>
+ Sometimes it is impractical to fix all the ambiguous references in a
+ large body of <application>PL/pgSQL</application> code. In such cases you can
+ specify that <application>PL/pgSQL</application> should resolve ambiguous references
+ as the variable (which is compatible with <application>PL/pgSQL</application>'s
+ behavior before <productname>PostgreSQL</productname> 9.0), or as the
+ table column (which is compatible with some other systems such as
+ <productname>Oracle</productname>).
+ </para>
+
+ <indexterm>
+ <primary><varname>plpgsql.variable_conflict</varname> configuration parameter</primary>
+ </indexterm>
+
+ <para>
+ To change this behavior on a system-wide basis, set the configuration
+ parameter <literal>plpgsql.variable_conflict</literal> to one of
+ <literal>error</literal>, <literal>use_variable</literal>, or
+ <literal>use_column</literal> (where <literal>error</literal> is the factory default).
+ This parameter affects subsequent compilations
+ of statements in <application>PL/pgSQL</application> functions, but not statements
+ already compiled in the current session.
+ Because changing this setting
+ can cause unexpected changes in the behavior of <application>PL/pgSQL</application>
+ functions, it can only be changed by a superuser.
+ </para>
+
+ <para>
+ You can also set the behavior on a function-by-function basis, by
+ inserting one of these special commands at the start of the function
+ text:
+<programlisting>
+#variable_conflict error
+#variable_conflict use_variable
+#variable_conflict use_column
+</programlisting>
+ These commands affect only the function they are written in, and override
+ the setting of <literal>plpgsql.variable_conflict</literal>. An example is
+<programlisting>
+CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
+ #variable_conflict use_variable
+ DECLARE
+ curtime timestamp := now();
+ BEGIN
+ UPDATE users SET last_modified = curtime, comment = comment
+ WHERE users.id = id;
+ END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ In the <literal>UPDATE</literal> command, <literal>curtime</literal>, <literal>comment</literal>,
+ and <literal>id</literal> will refer to the function's variable and parameters
+ whether or not <literal>users</literal> has columns of those names. Notice
+ that we had to qualify the reference to <literal>users.id</literal> in the
+ <literal>WHERE</literal> clause to make it refer to the table column.
+ But we did not have to qualify the reference to <literal>comment</literal>
+ as a target in the <literal>UPDATE</literal> list, because syntactically
+ that must be a column of <literal>users</literal>. We could write the same
+ function without depending on the <literal>variable_conflict</literal> setting
+ in this way:
+<programlisting>
+CREATE FUNCTION stamp_user(id int, comment text) RETURNS void AS $$
+ &lt;&lt;fn&gt;&gt;
+ DECLARE
+ curtime timestamp := now();
+ BEGIN
+ UPDATE users SET last_modified = fn.curtime, comment = stamp_user.comment
+ WHERE users.id = stamp_user.id;
+ END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ Variable substitution does not happen in a command string given
+ to <command>EXECUTE</command> or one of its variants. If you need to
+ insert a varying value into such a command, do so as part of
+ constructing the string value, or use <literal>USING</literal>, as illustrated in
+ <xref linkend="plpgsql-statements-executing-dyn"/>.
+ </para>
+
+ <para>
+ Variable substitution currently works only in <command>SELECT</command>,
+ <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, and commands containing one of
+ these (such as <command>EXPLAIN</command> and <command>CREATE TABLE
+ ... AS SELECT</command>),
+ because the main SQL engine allows query parameters only in these
+ commands. To use a non-constant name or value in other statement
+ types (generically called utility statements), you must construct
+ the utility statement as a string and <command>EXECUTE</command> it.
+ </para>
+
+ </sect2>
+
+ <sect2 id="plpgsql-plan-caching">
+ <title>Plan Caching</title>
+
+ <para>
+ The <application>PL/pgSQL</application> interpreter parses the function's source
+ text and produces an internal binary instruction tree the first time the
+ function is called (within each session). The instruction tree
+ fully translates the
+ <application>PL/pgSQL</application> statement structure, but individual
+ <acronym>SQL</acronym> expressions and <acronym>SQL</acronym> commands
+ used in the function are not translated immediately.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>preparing a query</primary>
+ <secondary>in PL/pgSQL</secondary>
+ </indexterm>
+ As each expression and <acronym>SQL</acronym> command is first
+ executed in the function, the <application>PL/pgSQL</application> interpreter
+ parses and analyzes the command to create a prepared statement,
+ using the <acronym>SPI</acronym> manager's
+ <function>SPI_prepare</function> function.
+ Subsequent visits to that expression or command
+ reuse the prepared statement. Thus, a function with conditional code
+ paths that are seldom visited will never incur the overhead of
+ analyzing those commands that are never executed within the current
+ session. A disadvantage is that errors
+ in a specific expression or command cannot be detected until that
+ part of the function is reached in execution. (Trivial syntax
+ errors will be detected during the initial parsing pass, but
+ anything deeper will not be detected until execution.)
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> (or more precisely, the SPI manager) can
+ furthermore attempt to cache the execution plan associated with any
+ particular prepared statement. If a cached plan is not used, then
+ a fresh execution plan is generated on each visit to the statement,
+ and the current parameter values (that is, <application>PL/pgSQL</application>
+ variable values) can be used to optimize the selected plan. If the
+ statement has no parameters, or is executed many times, the SPI manager
+ will consider creating a <firstterm>generic</firstterm> plan that is not dependent
+ on specific parameter values, and caching that for re-use. Typically
+ this will happen only if the execution plan is not very sensitive to
+ the values of the <application>PL/pgSQL</application> variables referenced in it.
+ If it is, generating a plan each time is a net win. See <xref
+ linkend="sql-prepare"/> for more information about the behavior of
+ prepared statements.
+ </para>
+
+ <para>
+ Because <application>PL/pgSQL</application> saves prepared statements
+ and sometimes execution plans in this way,
+ SQL commands that appear directly in a
+ <application>PL/pgSQL</application> function must refer to the
+ same tables and columns on every execution; that is, you cannot use
+ a parameter as the name of a table or column in an SQL command. To get
+ around this restriction, you can construct dynamic commands using
+ the <application>PL/pgSQL</application> <command>EXECUTE</command>
+ statement &mdash; at the price of performing new parse analysis and
+ constructing a new execution plan on every execution.
+ </para>
+
+ <para>
+ The mutable nature of record variables presents another problem in this
+ connection. When fields of a record variable are used in
+ expressions or statements, the data types of the fields must not
+ change from one call of the function to the next, since each
+ expression will be analyzed using the data type that is present
+ when the expression is first reached. <command>EXECUTE</command> can be
+ used to get around this problem when necessary.
+ </para>
+
+ <para>
+ If the same function is used as a trigger for more than one table,
+ <application>PL/pgSQL</application> prepares and caches statements
+ independently for each such table &mdash; that is, there is a cache
+ for each trigger function and table combination, not just for each
+ function. This alleviates some of the problems with varying
+ data types; for instance, a trigger function will be able to work
+ successfully with a column named <literal>key</literal> even if it happens
+ to have different types in different tables.
+ </para>
+
+ <para>
+ Likewise, functions having polymorphic argument types have a separate
+ statement cache for each combination of actual argument types they have
+ been invoked for, so that data type differences do not cause unexpected
+ failures.
+ </para>
+
+ <para>
+ Statement caching can sometimes have surprising effects on the
+ interpretation of time-sensitive values. For example there
+ is a difference between what these two functions do:
+
+<programlisting>
+CREATE FUNCTION logfunc1(logtxt text) RETURNS void AS $$
+ BEGIN
+ INSERT INTO logtable VALUES (logtxt, 'now');
+ END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ and:
+
+<programlisting>
+CREATE FUNCTION logfunc2(logtxt text) RETURNS void AS $$
+ DECLARE
+ curtime timestamp;
+ BEGIN
+ curtime := 'now';
+ INSERT INTO logtable VALUES (logtxt, curtime);
+ END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ In the case of <function>logfunc1</function>, the
+ <productname>PostgreSQL</productname> main parser knows when
+ analyzing the <command>INSERT</command> that the
+ string <literal>'now'</literal> should be interpreted as
+ <type>timestamp</type>, because the target column of
+ <classname>logtable</classname> is of that type. Thus,
+ <literal>'now'</literal> will be converted to a <type>timestamp</type>
+ constant when the
+ <command>INSERT</command> is analyzed, and then used in all
+ invocations of <function>logfunc1</function> during the lifetime
+ of the session. Needless to say, this isn't what the programmer
+ wanted. A better idea is to use the <literal>now()</literal> or
+ <literal>current_timestamp</literal> function.
+ </para>
+
+ <para>
+ In the case of <function>logfunc2</function>, the
+ <productname>PostgreSQL</productname> main parser does not know
+ what type <literal>'now'</literal> should become and therefore
+ it returns a data value of type <type>text</type> containing the string
+ <literal>now</literal>. During the ensuing assignment
+ to the local variable <varname>curtime</varname>, the
+ <application>PL/pgSQL</application> interpreter casts this
+ string to the <type>timestamp</type> type by calling the
+ <function>textout</function> and <function>timestamp_in</function>
+ functions for the conversion. So, the computed time stamp is updated
+ on each execution as the programmer expects. Even though this
+ happens to work as expected, it's not terribly efficient, so
+ use of the <literal>now()</literal> function would still be a better idea.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="plpgsql-development-tips">
+ <title>Tips for Developing in <application>PL/pgSQL</application></title>
+
+ <para>
+ One good way to develop in
+ <application>PL/pgSQL</application> is to use the text editor of your
+ choice to create your functions, and in another window, use
+ <application>psql</application> to load and test those functions.
+ If you are doing it this way, it
+ is a good idea to write the function using <command>CREATE OR
+ REPLACE FUNCTION</command>. That way you can just reload the file to update
+ the function definition. For example:
+<programlisting>
+CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $$
+ ....
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ While running <application>psql</application>, you can load or reload such
+ a function definition file with:
+<programlisting>
+\i filename.sql
+</programlisting>
+ and then immediately issue SQL commands to test the function.
+ </para>
+
+ <para>
+ Another good way to develop in <application>PL/pgSQL</application> is with a
+ GUI database access tool that facilitates development in a
+ procedural language. One example of such a tool is
+ <application>pgAdmin</application>, although others exist. These tools often
+ provide convenient features such as escaping single quotes and
+ making it easier to recreate and debug functions.
+ </para>
+
+ <sect2 id="plpgsql-quote-tips">
+ <title>Handling of Quotation Marks</title>
+
+ <para>
+ The code of a <application>PL/pgSQL</application> function is specified in
+ <command>CREATE FUNCTION</command> as a string literal. If you
+ write the string literal in the ordinary way with surrounding
+ single quotes, then any single quotes inside the function body
+ must be doubled; likewise any backslashes must be doubled (assuming
+ escape string syntax is used).
+ Doubling quotes is at best tedious, and in more complicated cases
+ the code can become downright incomprehensible, because you can
+ easily find yourself needing half a dozen or more adjacent quote marks.
+ It's recommended that you instead write the function body as a
+ <quote>dollar-quoted</quote> string literal (see <xref
+ linkend="sql-syntax-dollar-quoting"/>). In the dollar-quoting
+ approach, you never double any quote marks, but instead take care to
+ choose a different dollar-quoting delimiter for each level of
+ nesting you need. For example, you might write the <command>CREATE
+ FUNCTION</command> command as:
+<programlisting>
+CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$
+ ....
+$PROC$ LANGUAGE plpgsql;
+</programlisting>
+ Within this, you might use quote marks for simple literal strings in
+ SQL commands and <literal>$$</literal> to delimit fragments of SQL commands
+ that you are assembling as strings. If you need to quote text that
+ includes <literal>$$</literal>, you could use <literal>$Q$</literal>, and so on.
+ </para>
+
+ <para>
+ The following chart shows what you have to do when writing quote
+ marks without dollar quoting. It might be useful when translating
+ pre-dollar quoting code into something more comprehensible.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>1 quotation mark</term>
+ <listitem>
+ <para>
+ To begin and end the function body, for example:
+<programlisting>
+CREATE FUNCTION foo() RETURNS integer AS '
+ ....
+' LANGUAGE plpgsql;
+</programlisting>
+ Anywhere within a single-quoted function body, quote marks
+ <emphasis>must</emphasis> appear in pairs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>2 quotation marks</term>
+ <listitem>
+ <para>
+ For string literals inside the function body, for example:
+<programlisting>
+a_output := ''Blah'';
+SELECT * FROM users WHERE f_name=''foobar'';
+</programlisting>
+ In the dollar-quoting approach, you'd just write:
+<programlisting>
+a_output := 'Blah';
+SELECT * FROM users WHERE f_name='foobar';
+</programlisting>
+ which is exactly what the <application>PL/pgSQL</application> parser would see
+ in either case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>4 quotation marks</term>
+ <listitem>
+ <para>
+ When you need a single quotation mark in a string constant inside the
+ function body, for example:
+<programlisting>
+a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz''
+</programlisting>
+ The value actually appended to <literal>a_output</literal> would be:
+ <literal> AND name LIKE 'foobar' AND xyz</literal>.
+ </para>
+ <para>
+ In the dollar-quoting approach, you'd write:
+<programlisting>
+a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$
+</programlisting>
+ being careful that any dollar-quote delimiters around this are not
+ just <literal>$$</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>6 quotation marks</term>
+ <listitem>
+ <para>
+ When a single quotation mark in a string inside the function body is
+ adjacent to the end of that string constant, for example:
+<programlisting>
+a_output := a_output || '' AND name LIKE ''''foobar''''''
+</programlisting>
+ The value appended to <literal>a_output</literal> would then be:
+ <literal> AND name LIKE 'foobar'</literal>.
+ </para>
+ <para>
+ In the dollar-quoting approach, this becomes:
+<programlisting>
+a_output := a_output || $$ AND name LIKE 'foobar'$$
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>10 quotation marks</term>
+ <listitem>
+ <para>
+ When you want two single quotation marks in a string constant (which
+ accounts for 8 quotation marks) and this is adjacent to the end of that
+ string constant (2 more). You will probably only need that if
+ you are writing a function that generates other functions, as in
+ <xref linkend="plpgsql-porting-ex2"/>.
+ For example:
+<programlisting>
+a_output := a_output || '' if v_'' ||
+ referrer_keys.kind || '' like ''''''''''
+ || referrer_keys.key_string || ''''''''''
+ then return '''''' || referrer_keys.referrer_type
+ || ''''''; end if;'';
+</programlisting>
+ The value of <literal>a_output</literal> would then be:
+<programlisting>
+if v_... like ''...'' then return ''...''; end if;
+</programlisting>
+ </para>
+ <para>
+ In the dollar-quoting approach, this becomes:
+<programlisting>
+a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$
+ || referrer_keys.key_string || $$'
+ then return '$$ || referrer_keys.referrer_type
+ || $$'; end if;$$;
+</programlisting>
+ where we assume we only need to put single quote marks into
+ <literal>a_output</literal>, because it will be re-quoted before use.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+ <sect2 id="plpgsql-extra-checks">
+ <title>Additional Compile-Time and Run-Time Checks</title>
+
+ <para>
+ To aid the user in finding instances of simple but common problems before
+ they cause harm, <application>PL/pgSQL</application> provides additional
+ <replaceable>checks</replaceable>. When enabled, depending on the configuration, they
+ can be used to emit either a <literal>WARNING</literal> or an <literal>ERROR</literal>
+ during the compilation of a function. A function which has received
+ a <literal>WARNING</literal> can be executed without producing further messages,
+ so you are advised to test in a separate development environment.
+ </para>
+
+ <para>
+ Setting <varname>plpgsql.extra_warnings</varname>, or
+ <varname>plpgsql.extra_errors</varname>, as appropriate, to <literal>"all"</literal>
+ is encouraged in development and/or testing environments.
+ </para>
+
+ <para>
+ These additional checks are enabled through the configuration variables
+ <varname>plpgsql.extra_warnings</varname> for warnings and
+ <varname>plpgsql.extra_errors</varname> for errors. Both can be set either to
+ a comma-separated list of checks, <literal>"none"</literal> or
+ <literal>"all"</literal>. The default is <literal>"none"</literal>. Currently
+ the list of available checks includes:
+ <variablelist>
+ <varlistentry>
+ <term><varname>shadowed_variables</varname></term>
+ <listitem>
+ <para>
+ Checks if a declaration shadows a previously defined variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>strict_multi_assignment</varname></term>
+ <listitem>
+ <para>
+ Some <application>PL/PgSQL</application> commands allow assigning
+ values to more than one variable at a time, such as
+ <command>SELECT INTO</command>. Typically, the number of target
+ variables and the number of source variables should match, though
+ <application>PL/PgSQL</application> will use <literal>NULL</literal>
+ for missing values and extra variables are ignored. Enabling this
+ check will cause <application>PL/PgSQL</application> to throw a
+ <literal>WARNING</literal> or <literal>ERROR</literal> whenever the
+ number of target variables and the number of source variables are
+ different.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>too_many_rows</varname></term>
+ <listitem>
+ <para>
+ Enabling this check will cause <application>PL/PgSQL</application> to
+ check if a given query returns more than one row when an
+ <literal>INTO</literal> clause is used. As an <literal>INTO</literal>
+ statement will only ever use one row, having a query return multiple
+ rows is generally either inefficient and/or nondeterministic and
+ therefore is likely an error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The following example shows the effect of <varname>plpgsql.extra_warnings</varname>
+ set to <varname>shadowed_variables</varname>:
+<programlisting>
+SET plpgsql.extra_warnings TO 'shadowed_variables';
+
+CREATE FUNCTION foo(f1 int) RETURNS int AS $$
+DECLARE
+f1 int;
+BEGIN
+RETURN f1;
+END;
+$$ LANGUAGE plpgsql;
+WARNING: variable "f1" shadows a previously defined variable
+LINE 3: f1 int;
+ ^
+CREATE FUNCTION
+</programlisting>
+ The below example shows the effects of setting
+ <varname>plpgsql.extra_warnings</varname> to
+ <varname>strict_multi_assignment</varname>:
+<programlisting>
+SET plpgsql.extra_warnings TO 'strict_multi_assignment';
+
+CREATE OR REPLACE FUNCTION public.foo()
+ RETURNS void
+ LANGUAGE plpgsql
+AS $$
+DECLARE
+ x int;
+ y int;
+BEGIN
+ SELECT 1 INTO x, y;
+ SELECT 1, 2 INTO x, y;
+ SELECT 1, 2, 3 INTO x, y;
+END;
+$$;
+
+SELECT foo();
+WARNING: number of source and target fields in assignment does not match
+DETAIL: strict_multi_assignment check of extra_warnings is active.
+HINT: Make sure the query returns the exact list of columns.
+WARNING: number of source and target fields in assignment does not match
+DETAIL: strict_multi_assignment check of extra_warnings is active.
+HINT: Make sure the query returns the exact list of columns.
+
+ foo
+-----
+
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <!-- **** Porting from Oracle PL/SQL **** -->
+
+ <sect1 id="plpgsql-porting">
+ <title>Porting from <productname>Oracle</productname> PL/SQL</title>
+
+ <indexterm zone="plpgsql-porting">
+ <primary>Oracle</primary>
+ <secondary>porting from PL/SQL to PL/pgSQL</secondary>
+ </indexterm>
+
+ <indexterm zone="plpgsql-porting">
+ <primary>PL/SQL (Oracle)</primary>
+ <secondary>porting to PL/pgSQL</secondary>
+ </indexterm>
+
+ <para>
+ This section explains differences between
+ <productname>PostgreSQL</productname>'s <application>PL/pgSQL</application>
+ language and Oracle's <application>PL/SQL</application> language,
+ to help developers who port applications from
+ <trademark class="registered">Oracle</trademark> to <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> is similar to PL/SQL in many
+ aspects. It is a block-structured, imperative language, and all
+ variables have to be declared. Assignments, loops, and conditionals
+ are similar. The main differences you should keep in mind when
+ porting from <application>PL/SQL</application> to
+ <application>PL/pgSQL</application> are:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If a name used in an SQL command could be either a column name of a
+ table used in the command or a reference to a variable of the function,
+ <application>PL/SQL</application> treats it as a column name.
+ By default, <application>PL/pgSQL</application> will throw an error
+ complaining that the name is ambiguous. You can specify
+ <literal>plpgsql.variable_conflict</literal> = <literal>use_column</literal>
+ to change this behavior to match <application>PL/SQL</application>,
+ as explained in <xref linkend="plpgsql-var-subst"/>.
+ It's often best to avoid such ambiguities in the first place,
+ but if you have to port a large amount of code that depends on
+ this behavior, setting <literal>variable_conflict</literal> may be the
+ best solution.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <productname>PostgreSQL</productname> the function body must be written as
+ a string literal. Therefore you need to use dollar quoting or escape
+ single quotes in the function body. (See <xref
+ linkend="plpgsql-quote-tips"/>.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Data type names often need translation. For example, in Oracle string
+ values are commonly declared as being of type <type>varchar2</type>, which
+ is a non-SQL-standard type. In <productname>PostgreSQL</productname>,
+ use type <type>varchar</type> or <type>text</type> instead. Similarly, replace
+ type <type>number</type> with <type>numeric</type>, or use some other numeric
+ data type if there's a more appropriate one.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Instead of packages, use schemas to organize your functions
+ into groups.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Since there are no packages, there are no package-level variables
+ either. This is somewhat annoying. You can keep per-session state
+ in temporary tables instead.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Integer <command>FOR</command> loops with <literal>REVERSE</literal> work
+ differently: <application>PL/SQL</application> counts down from the second
+ number to the first, while <application>PL/pgSQL</application> counts down
+ from the first number to the second, requiring the loop bounds
+ to be swapped when porting. This incompatibility is unfortunate
+ but is unlikely to be changed. (See <xref
+ linkend="plpgsql-integer-for"/>.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <command>FOR</command> loops over queries (other than cursors) also work
+ differently: the target variable(s) must have been declared,
+ whereas <application>PL/SQL</application> always declares them implicitly.
+ An advantage of this is that the variable values are still accessible
+ after the loop exits.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ There are various notational differences for the use of cursor
+ variables.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <sect2>
+ <title>Porting Examples</title>
+
+ <para>
+ <xref linkend="pgsql-porting-ex1"/> shows how to port a simple
+ function from <application>PL/SQL</application> to <application>PL/pgSQL</application>.
+ </para>
+
+ <example id="pgsql-porting-ex1">
+ <title>Porting a Simple Function from <application>PL/SQL</application> to <application>PL/pgSQL</application></title>
+
+ <para>
+ Here is an <productname>Oracle</productname> <application>PL/SQL</application> function:
+<programlisting>
+CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar2,
+ v_version varchar2)
+RETURN varchar2 IS
+BEGIN
+ IF v_version IS NULL THEN
+ RETURN v_name;
+ END IF;
+ RETURN v_name || '/' || v_version;
+END;
+/
+show errors;
+</programlisting>
+ </para>
+
+ <para>
+ Let's go through this function and see the differences compared to
+ <application>PL/pgSQL</application>:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The type name <type>varchar2</type> has to be changed to <type>varchar</type>
+ or <type>text</type>. In the examples in this section, we'll
+ use <type>varchar</type>, but <type>text</type> is often a better choice if
+ you do not need specific string length limits.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <literal>RETURN</literal> key word in the function
+ prototype (not the function body) becomes
+ <literal>RETURNS</literal> in
+ <productname>PostgreSQL</productname>.
+ Also, <literal>IS</literal> becomes <literal>AS</literal>, and you need to
+ add a <literal>LANGUAGE</literal> clause because <application>PL/pgSQL</application>
+ is not the only possible function language.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In <productname>PostgreSQL</productname>, the function body is considered
+ to be a string literal, so you need to use quote marks or dollar
+ quotes around it. This substitutes for the terminating <literal>/</literal>
+ in the Oracle approach.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <literal>show errors</literal> command does not exist in
+ <productname>PostgreSQL</productname>, and is not needed since errors are
+ reported automatically.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ This is how this function would look when ported to
+ <productname>PostgreSQL</productname>:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION cs_fmt_browser_version(v_name varchar,
+ v_version varchar)
+RETURNS varchar AS $$
+BEGIN
+ IF v_version IS NULL THEN
+ RETURN v_name;
+ END IF;
+ RETURN v_name || '/' || v_version;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+ </example>
+
+ <para>
+ <xref linkend="plpgsql-porting-ex2"/> shows how to port a
+ function that creates another function and how to handle the
+ ensuing quoting problems.
+ </para>
+
+ <example id="plpgsql-porting-ex2">
+ <title>Porting a Function that Creates Another Function from <application>PL/SQL</application> to <application>PL/pgSQL</application></title>
+
+ <para>
+ The following procedure grabs rows from a
+ <command>SELECT</command> statement and builds a large function
+ with the results in <literal>IF</literal> statements, for the
+ sake of efficiency.
+ </para>
+
+ <para>
+ This is the Oracle version:
+<programlisting>
+CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc IS
+ CURSOR referrer_keys IS
+ SELECT * FROM cs_referrer_keys
+ ORDER BY try_order;
+ func_cmd VARCHAR(4000);
+BEGIN
+ func_cmd := 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host IN VARCHAR2,
+ v_domain IN VARCHAR2, v_url IN VARCHAR2) RETURN VARCHAR2 IS BEGIN';
+
+ FOR referrer_key IN referrer_keys LOOP
+ func_cmd := func_cmd ||
+ ' IF v_' || referrer_key.kind
+ || ' LIKE ''' || referrer_key.key_string
+ || ''' THEN RETURN ''' || referrer_key.referrer_type
+ || '''; END IF;';
+ END LOOP;
+
+ func_cmd := func_cmd || ' RETURN NULL; END;';
+
+ EXECUTE IMMEDIATE func_cmd;
+END;
+/
+show errors;
+</programlisting>
+ </para>
+
+ <para>
+ Here is how this function would end up in <productname>PostgreSQL</productname>:
+<programlisting>
+CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc() AS $func$
+DECLARE
+ referrer_keys CURSOR IS
+ SELECT * FROM cs_referrer_keys
+ ORDER BY try_order;
+ func_body text;
+ func_cmd text;
+BEGIN
+ func_body := 'BEGIN';
+
+ FOR referrer_key IN referrer_keys LOOP
+ func_body := func_body ||
+ ' IF v_' || referrer_key.kind
+ || ' LIKE ' || quote_literal(referrer_key.key_string)
+ || ' THEN RETURN ' || quote_literal(referrer_key.referrer_type)
+ || '; END IF;' ;
+ END LOOP;
+
+ func_body := func_body || ' RETURN NULL; END;';
+
+ func_cmd :=
+ 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host varchar,
+ v_domain varchar,
+ v_url varchar)
+ RETURNS varchar AS '
+ || quote_literal(func_body)
+ || ' LANGUAGE plpgsql;' ;
+
+ EXECUTE func_cmd;
+END;
+$func$ LANGUAGE plpgsql;
+</programlisting>
+ Notice how the body of the function is built separately and passed
+ through <literal>quote_literal</literal> to double any quote marks in it. This
+ technique is needed because we cannot safely use dollar quoting for
+ defining the new function: we do not know for sure what strings will
+ be interpolated from the <structfield>referrer_key.key_string</structfield> field.
+ (We are assuming here that <structfield>referrer_key.kind</structfield> can be
+ trusted to always be <literal>host</literal>, <literal>domain</literal>, or
+ <literal>url</literal>, but <structfield>referrer_key.key_string</structfield> might be
+ anything, in particular it might contain dollar signs.) This function
+ is actually an improvement on the Oracle original, because it will
+ not generate broken code when <structfield>referrer_key.key_string</structfield> or
+ <structfield>referrer_key.referrer_type</structfield> contain quote marks.
+ </para>
+ </example>
+
+ <para>
+ <xref linkend="plpgsql-porting-ex3"/> shows how to port a function
+ with <literal>OUT</literal> parameters and string manipulation.
+ <productname>PostgreSQL</productname> does not have a built-in
+ <function>instr</function> function, but you can create one
+ using a combination of other
+ functions. In <xref linkend="plpgsql-porting-appendix"/> there is a
+ <application>PL/pgSQL</application> implementation of
+ <function>instr</function> that you can use to make your porting
+ easier.
+ </para>
+
+ <example id="plpgsql-porting-ex3">
+ <title>Porting a Procedure With String Manipulation and
+ <literal>OUT</literal> Parameters from <application>PL/SQL</application> to
+ <application>PL/pgSQL</application></title>
+
+ <para>
+ The following <productname>Oracle</productname> PL/SQL procedure is used
+ to parse a URL and return several elements (host, path, and query).
+ </para>
+
+ <para>
+ This is the Oracle version:
+<programlisting>
+CREATE OR REPLACE PROCEDURE cs_parse_url(
+ v_url IN VARCHAR2,
+ v_host OUT VARCHAR2, -- This will be passed back
+ v_path OUT VARCHAR2, -- This one too
+ v_query OUT VARCHAR2) -- And this one
+IS
+ a_pos1 INTEGER;
+ a_pos2 INTEGER;
+BEGIN
+ v_host := NULL;
+ v_path := NULL;
+ v_query := NULL;
+ a_pos1 := instr(v_url, '//');
+
+ IF a_pos1 = 0 THEN
+ RETURN;
+ END IF;
+ a_pos2 := instr(v_url, '/', a_pos1 + 2);
+ IF a_pos2 = 0 THEN
+ v_host := substr(v_url, a_pos1 + 2);
+ v_path := '/';
+ RETURN;
+ END IF;
+
+ v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
+ a_pos1 := instr(v_url, '?', a_pos2 + 1);
+
+ IF a_pos1 = 0 THEN
+ v_path := substr(v_url, a_pos2);
+ RETURN;
+ END IF;
+
+ v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
+ v_query := substr(v_url, a_pos1 + 1);
+END;
+/
+show errors;
+</programlisting>
+ </para>
+
+ <para>
+ Here is a possible translation into <application>PL/pgSQL</application>:
+<programlisting>
+CREATE OR REPLACE FUNCTION cs_parse_url(
+ v_url IN VARCHAR,
+ v_host OUT VARCHAR, -- This will be passed back
+ v_path OUT VARCHAR, -- This one too
+ v_query OUT VARCHAR) -- And this one
+AS $$
+DECLARE
+ a_pos1 INTEGER;
+ a_pos2 INTEGER;
+BEGIN
+ v_host := NULL;
+ v_path := NULL;
+ v_query := NULL;
+ a_pos1 := instr(v_url, '//');
+
+ IF a_pos1 = 0 THEN
+ RETURN;
+ END IF;
+ a_pos2 := instr(v_url, '/', a_pos1 + 2);
+ IF a_pos2 = 0 THEN
+ v_host := substr(v_url, a_pos1 + 2);
+ v_path := '/';
+ RETURN;
+ END IF;
+
+ v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
+ a_pos1 := instr(v_url, '?', a_pos2 + 1);
+
+ IF a_pos1 = 0 THEN
+ v_path := substr(v_url, a_pos2);
+ RETURN;
+ END IF;
+
+ v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
+ v_query := substr(v_url, a_pos1 + 1);
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ This function could be used like this:
+<programlisting>
+SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz');
+</programlisting>
+ </para>
+ </example>
+
+ <para>
+ <xref linkend="plpgsql-porting-ex4"/> shows how to port a procedure
+ that uses numerous features that are specific to Oracle.
+ </para>
+
+ <example id="plpgsql-porting-ex4">
+ <title>Porting a Procedure from <application>PL/SQL</application> to <application>PL/pgSQL</application></title>
+
+ <para>
+ The Oracle version:
+
+<programlisting>
+CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS
+ a_running_job_count INTEGER;
+BEGIN
+ LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
+
+ SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
+
+ IF a_running_job_count &gt; 0 THEN
+ COMMIT; -- free lock
+ raise_application_error(-20000,
+ 'Unable to create a new job: a job is currently running.');
+ END IF;
+
+ DELETE FROM cs_active_job;
+ INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
+
+ BEGIN
+ INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
+ EXCEPTION
+ WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists
+ END;
+ COMMIT;
+END;
+/
+show errors
+</programlisting>
+ </para>
+
+ <para>
+ This is how we could port this procedure to <application>PL/pgSQL</application>:
+
+<programlisting>
+CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$
+DECLARE
+ a_running_job_count integer;
+BEGIN
+ LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
+
+ SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
+
+ IF a_running_job_count &gt; 0 THEN
+ COMMIT; -- free lock
+ RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- <co id="co.plpgsql-porting-raise"/>
+ END IF;
+
+ DELETE FROM cs_active_job;
+ INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
+
+ BEGIN
+ INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
+ EXCEPTION
+ WHEN unique_violation THEN -- <co id="co.plpgsql-porting-exception"/>
+ -- don't worry if it already exists
+ END;
+ COMMIT;
+END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+
+ <calloutlist>
+ <callout arearefs="co.plpgsql-porting-raise">
+ <para>
+ The syntax of <literal>RAISE</literal> is considerably different from
+ Oracle's statement, although the basic case <literal>RAISE</literal>
+ <replaceable class="parameter">exception_name</replaceable> works
+ similarly.
+ </para>
+ </callout>
+ <callout arearefs="co.plpgsql-porting-exception">
+ <para>
+ The exception names supported by <application>PL/pgSQL</application> are
+ different from Oracle's. The set of built-in exception names
+ is much larger (see <xref linkend="errcodes-appendix"/>). There
+ is not currently a way to declare user-defined exception names,
+ although you can throw user-chosen SQLSTATE values instead.
+ </para>
+ </callout>
+ </calloutlist>
+ </para>
+ </example>
+ </sect2>
+
+ <sect2 id="plpgsql-porting-other">
+ <title>Other Things to Watch For</title>
+
+ <para>
+ This section explains a few other things to watch for when porting
+ Oracle <application>PL/SQL</application> functions to
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <sect3 id="plpgsql-porting-exceptions">
+ <title>Implicit Rollback after Exceptions</title>
+
+ <para>
+ In <application>PL/pgSQL</application>, when an exception is caught by an
+ <literal>EXCEPTION</literal> clause, all database changes since the block's
+ <literal>BEGIN</literal> are automatically rolled back. That is, the behavior
+ is equivalent to what you'd get in Oracle with:
+
+<programlisting>
+BEGIN
+ SAVEPOINT s1;
+ ... code here ...
+EXCEPTION
+ WHEN ... THEN
+ ROLLBACK TO s1;
+ ... code here ...
+ WHEN ... THEN
+ ROLLBACK TO s1;
+ ... code here ...
+END;
+</programlisting>
+
+ If you are translating an Oracle procedure that uses
+ <command>SAVEPOINT</command> and <command>ROLLBACK TO</command> in this style,
+ your task is easy: just omit the <command>SAVEPOINT</command> and
+ <command>ROLLBACK TO</command>. If you have a procedure that uses
+ <command>SAVEPOINT</command> and <command>ROLLBACK TO</command> in a different way
+ then some actual thought will be required.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title><command>EXECUTE</command></title>
+
+ <para>
+ The <application>PL/pgSQL</application> version of
+ <command>EXECUTE</command> works similarly to the
+ <application>PL/SQL</application> version, but you have to remember to use
+ <function>quote_literal</function> and
+ <function>quote_ident</function> as described in <xref
+ linkend="plpgsql-statements-executing-dyn"/>. Constructs of the
+ type <literal>EXECUTE 'SELECT * FROM $1';</literal> will not work
+ reliably unless you use these functions.
+ </para>
+ </sect3>
+
+ <sect3 id="plpgsql-porting-optimization">
+ <title>Optimizing <application>PL/pgSQL</application> Functions</title>
+
+ <para>
+ <productname>PostgreSQL</productname> gives you two function creation
+ modifiers to optimize execution: <quote>volatility</quote> (whether
+ the function always returns the same result when given the same
+ arguments) and <quote>strictness</quote> (whether the function
+ returns null if any argument is null). Consult the <xref
+ linkend="sql-createfunction"/>
+ reference page for details.
+ </para>
+
+ <para>
+ When making use of these optimization attributes, your
+ <command>CREATE FUNCTION</command> statement might look something
+ like this:
+
+<programlisting>
+CREATE FUNCTION foo(...) RETURNS integer AS $$
+...
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="plpgsql-porting-appendix">
+ <title>Appendix</title>
+
+ <para>
+ This section contains the code for a set of Oracle-compatible
+ <function>instr</function> functions that you can use to simplify
+ your porting efforts.
+ </para>
+
+ <indexterm>
+ <primary><function>instr</function> function</primary>
+ </indexterm>
+
+<programlisting><![CDATA[
+--
+-- instr functions that mimic Oracle's counterpart
+-- Syntax: instr(string1, string2 [, n [, m]])
+-- where [] denotes optional parameters.
+--
+-- Search string1, beginning at the nth character, for the mth occurrence
+-- of string2. If n is negative, search backwards, starting at the abs(n)'th
+-- character from the end of string1.
+-- If n is not passed, assume 1 (search starts at first character).
+-- If m is not passed, assume 1 (find first occurrence).
+-- Returns starting index of string2 in string1, or 0 if string2 is not found.
+--
+
+CREATE FUNCTION instr(varchar, varchar) RETURNS integer AS $$
+BEGIN
+ RETURN instr($1, $2, 1);
+END;
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+
+
+CREATE FUNCTION instr(string varchar, string_to_search_for varchar,
+ beg_index integer)
+RETURNS integer AS $$
+DECLARE
+ pos integer NOT NULL DEFAULT 0;
+ temp_str varchar;
+ beg integer;
+ length integer;
+ ss_length integer;
+BEGIN
+ IF beg_index > 0 THEN
+ temp_str := substring(string FROM beg_index);
+ pos := position(string_to_search_for IN temp_str);
+
+ IF pos = 0 THEN
+ RETURN 0;
+ ELSE
+ RETURN pos + beg_index - 1;
+ END IF;
+ ELSIF beg_index < 0 THEN
+ ss_length := char_length(string_to_search_for);
+ length := char_length(string);
+ beg := length + 1 + beg_index;
+
+ WHILE beg > 0 LOOP
+ temp_str := substring(string FROM beg FOR ss_length);
+ IF string_to_search_for = temp_str THEN
+ RETURN beg;
+ END IF;
+
+ beg := beg - 1;
+ END LOOP;
+
+ RETURN 0;
+ ELSE
+ RETURN 0;
+ END IF;
+END;
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+
+
+CREATE FUNCTION instr(string varchar, string_to_search_for varchar,
+ beg_index integer, occur_index integer)
+RETURNS integer AS $$
+DECLARE
+ pos integer NOT NULL DEFAULT 0;
+ occur_number integer NOT NULL DEFAULT 0;
+ temp_str varchar;
+ beg integer;
+ i integer;
+ length integer;
+ ss_length integer;
+BEGIN
+ IF occur_index <= 0 THEN
+ RAISE 'argument ''%'' is out of range', occur_index
+ USING ERRCODE = '22003';
+ END IF;
+
+ IF beg_index > 0 THEN
+ beg := beg_index - 1;
+ FOR i IN 1..occur_index LOOP
+ temp_str := substring(string FROM beg + 1);
+ pos := position(string_to_search_for IN temp_str);
+ IF pos = 0 THEN
+ RETURN 0;
+ END IF;
+ beg := beg + pos;
+ END LOOP;
+
+ RETURN beg;
+ ELSIF beg_index < 0 THEN
+ ss_length := char_length(string_to_search_for);
+ length := char_length(string);
+ beg := length + 1 + beg_index;
+
+ WHILE beg > 0 LOOP
+ temp_str := substring(string FROM beg FOR ss_length);
+ IF string_to_search_for = temp_str THEN
+ occur_number := occur_number + 1;
+ IF occur_number = occur_index THEN
+ RETURN beg;
+ END IF;
+ END IF;
+
+ beg := beg - 1;
+ END LOOP;
+
+ RETURN 0;
+ ELSE
+ RETURN 0;
+ END IF;
+END;
+$$ LANGUAGE plpgsql STRICT IMMUTABLE;
+]]>
+</programlisting>
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml
new file mode 100644
index 0000000..742d360
--- /dev/null
+++ b/doc/src/sgml/plpython.sgml
@@ -0,0 +1,1397 @@
+<!-- doc/src/sgml/plpython.sgml -->
+
+<chapter id="plpython">
+ <title>PL/Python &mdash; Python Procedural Language</title>
+
+ <indexterm zone="plpython"><primary>PL/Python</primary></indexterm>
+ <indexterm zone="plpython"><primary>Python</primary></indexterm>
+
+ <para>
+ The <application>PL/Python</application> procedural language allows
+ <productname>PostgreSQL</productname> functions and procedures to be written in the
+ <ulink url="https://www.python.org">Python language</ulink>.
+ </para>
+
+ <para>
+ To install PL/Python in a particular database, use
+ <literal>CREATE EXTENSION plpython3u</literal>.
+ </para>
+
+ <tip>
+ <para>
+ If a language is installed into <literal>template1</literal>, all subsequently
+ created databases will have the language installed automatically.
+ </para>
+ </tip>
+
+ <para>
+ PL/Python is only available as an <quote>untrusted</quote> language, meaning
+ it does not offer any way of restricting what users can do in it and
+ is therefore named <literal>plpython3u</literal>. A trusted
+ variant <literal>plpython</literal> might become available in the future
+ if a secure execution mechanism is developed in Python. The
+ writer of a function in untrusted PL/Python must take care that the
+ function cannot be used to do anything unwanted, since it will be
+ able to do anything that could be done by a user logged in as the
+ database administrator. Only superusers can create functions in
+ untrusted languages such as <literal>plpython3u</literal>.
+ </para>
+
+ <note>
+ <para>
+ Users of source packages must specially enable the build of
+ PL/Python during the installation process. (Refer to the
+ installation instructions for more information.) Users of binary
+ packages might find PL/Python in a separate subpackage.
+ </para>
+ </note>
+
+ <sect1 id="plpython-funcs">
+ <title>PL/Python Functions</title>
+
+ <para>
+ Functions in PL/Python are declared via the
+ standard <xref linkend="sql-createfunction"/> syntax:
+
+<programlisting>
+CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-list</replaceable>)
+ RETURNS <replaceable>return-type</replaceable>
+AS $$
+ # PL/Python function body
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+
+ <para>
+ The body of a function is simply a Python script. When the function
+ is called, its arguments are passed as elements of the list
+ <varname>args</varname>; named arguments are also passed as
+ ordinary variables to the Python script. Use of named arguments is
+ usually more readable. The result is returned from the Python code
+ in the usual way, with <literal>return</literal> or
+ <literal>yield</literal> (in case of a result-set statement). If
+ you do not provide a return value, Python returns the default
+ <symbol>None</symbol>. <application>PL/Python</application> translates
+ Python's <symbol>None</symbol> into the SQL null value. In a procedure,
+ the result from the Python code must be <symbol>None</symbol> (typically
+ achieved by ending the procedure without a <literal>return</literal>
+ statement or by using a <literal>return</literal> statement without
+ argument); otherwise, an error will be raised.
+ </para>
+
+ <para>
+ For example, a function to return the greater of two integers can be
+ defined as:
+
+<programlisting>
+CREATE FUNCTION pymax (a integer, b integer)
+ RETURNS integer
+AS $$
+ if a &gt; b:
+ return a
+ return b
+$$ LANGUAGE plpython3u;
+</programlisting>
+
+ The Python code that is given as the body of the function definition
+ is transformed into a Python function. For example, the above results in:
+
+<programlisting>
+def __plpython_procedure_pymax_23456():
+ if a &gt; b:
+ return a
+ return b
+</programlisting>
+
+ assuming that 23456 is the OID assigned to the function by
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ The arguments are set as global variables. Because of the scoping
+ rules of Python, this has the subtle consequence that an argument
+ variable cannot be reassigned inside the function to the value of
+ an expression that involves the variable name itself, unless the
+ variable is redeclared as global in the block. For example, the
+ following won't work:
+<programlisting>
+CREATE FUNCTION pystrip(x text)
+ RETURNS text
+AS $$
+ x = x.strip() # error
+ return x
+$$ LANGUAGE plpython3u;
+</programlisting>
+ because assigning to <varname>x</varname>
+ makes <varname>x</varname> a local variable for the entire block,
+ and so the <varname>x</varname> on the right-hand side of the
+ assignment refers to a not-yet-assigned local
+ variable <varname>x</varname>, not the PL/Python function
+ parameter. Using the <literal>global</literal> statement, this can
+ be made to work:
+<programlisting>
+CREATE FUNCTION pystrip(x text)
+ RETURNS text
+AS $$
+ global x
+ x = x.strip() # ok now
+ return x
+$$ LANGUAGE plpython3u;
+</programlisting>
+ But it is advisable not to rely on this implementation detail of
+ PL/Python. It is better to treat the function parameters as
+ read-only.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-data">
+ <title>Data Values</title>
+ <para>
+ Generally speaking, the aim of PL/Python is to provide
+ a <quote>natural</quote> mapping between the PostgreSQL and the
+ Python worlds. This informs the data mapping rules described
+ below.
+ </para>
+
+ <sect2>
+ <title>Data Type Mapping</title>
+ <para>
+ When a PL/Python function is called, its arguments are converted from
+ their PostgreSQL data type to a corresponding Python type:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ PostgreSQL <type>boolean</type> is converted to Python <type>bool</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>smallint</type>, <type>int</type>, <type>bigint</type>
+ and <type>oid</type> are converted to Python <type>int</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>real</type> and <type>double</type> are converted to
+ Python <type>float</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>numeric</type> is converted to
+ Python <type>Decimal</type>. This type is imported from
+ the <literal>cdecimal</literal> package if that is available.
+ Otherwise,
+ <literal>decimal.Decimal</literal> from the standard library will be
+ used. <literal>cdecimal</literal> is significantly faster
+ than <literal>decimal</literal>. In Python 3.3 and up,
+ however, <literal>cdecimal</literal> has been integrated into the
+ standard library under the name <literal>decimal</literal>, so there is
+ no longer any difference.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ PostgreSQL <type>bytea</type> is converted to Python <type>bytes</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All other data types, including the PostgreSQL character string types,
+ are converted to a Python <type>str</type> (in Unicode like all Python
+ strings).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For nonscalar data types, see below.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ When a PL/Python function returns, its return value is converted to the
+ function's declared PostgreSQL return data type as follows:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ When the PostgreSQL return type is <type>boolean</type>, the
+ return value will be evaluated for truth according to the
+ <emphasis>Python</emphasis> rules. That is, 0 and empty string
+ are false, but notably <literal>'f'</literal> is true.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When the PostgreSQL return type is <type>bytea</type>, the return value
+ will be converted to Python <type>bytes</type> using the respective
+ Python built-ins, with the result being converted to
+ <type>bytea</type>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For all other PostgreSQL return types, the return value is converted
+ to a string using the Python built-in <literal>str</literal>, and the
+ result is passed to the input function of the PostgreSQL data type.
+ (If the Python value is a <type>float</type>, it is converted using
+ the <literal>repr</literal> built-in instead of <literal>str</literal>, to
+ avoid loss of precision.)
+ </para>
+
+ <para>
+ Strings are automatically converted to the PostgreSQL server encoding
+ when they are passed to PostgreSQL.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For nonscalar data types, see below.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Note that logical mismatches between the declared PostgreSQL
+ return type and the Python data type of the actual return object
+ are not flagged; the value will be converted in any case.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Null, None</title>
+ <para>
+ If an SQL null value<indexterm><primary>null value</primary><secondary
+ sortas="PL/Python">in PL/Python</secondary></indexterm> is passed to a
+ function, the argument value will appear as <symbol>None</symbol> in
+ Python. For example, the function definition of <function>pymax</function>
+ shown in <xref linkend="plpython-funcs"/> will return the wrong answer for null
+ inputs. We could add <literal>STRICT</literal> to the function definition
+ to make <productname>PostgreSQL</productname> do something more reasonable:
+ if a null value is passed, the function will not be called at all,
+ but will just return a null result automatically. Alternatively,
+ we could check for null inputs in the function body:
+
+<programlisting>
+CREATE FUNCTION pymax (a integer, b integer)
+ RETURNS integer
+AS $$
+ if (a is None) or (b is None):
+ return None
+ if a &gt; b:
+ return a
+ return b
+$$ LANGUAGE plpython3u;
+</programlisting>
+
+ As shown above, to return an SQL null value from a PL/Python
+ function, return the value <symbol>None</symbol>. This can be done whether the
+ function is strict or not.
+ </para>
+ </sect2>
+
+ <sect2 id="plpython-arrays">
+ <title>Arrays, Lists</title>
+ <para>
+ SQL array values are passed into PL/Python as a Python list. To
+ return an SQL array value out of a PL/Python function, return a
+ Python list:
+
+<programlisting>
+CREATE FUNCTION return_arr()
+ RETURNS int[]
+AS $$
+return [1, 2, 3, 4, 5]
+$$ LANGUAGE plpython3u;
+
+SELECT return_arr();
+ return_arr
+-------------
+ {1,2,3,4,5}
+(1 row)
+</programlisting>
+
+ Multidimensional arrays are passed into PL/Python as nested Python lists.
+ A 2-dimensional array is a list of lists, for example. When returning
+ a multi-dimensional SQL array out of a PL/Python function, the inner
+ lists at each level must all be of the same size. For example:
+
+<programlisting>
+CREATE FUNCTION test_type_conversion_array_int4(x int4[]) RETURNS int4[] AS $$
+plpy.info(x, type(x))
+return x
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM test_type_conversion_array_int4(ARRAY[[1,2,3],[4,5,6]]);
+INFO: ([[1, 2, 3], [4, 5, 6]], &lt;type 'list'&gt;)
+ test_type_conversion_array_int4
+---------------------------------
+ {{1,2,3},{4,5,6}}
+(1 row)
+</programlisting>
+
+ Other Python sequences, like tuples, are also accepted for
+ backwards-compatibility with PostgreSQL versions 9.6 and below, when
+ multi-dimensional arrays were not supported. However, they are always
+ treated as one-dimensional arrays, because they are ambiguous with
+ composite types. For the same reason, when a composite type is used in a
+ multi-dimensional array, it must be represented by a tuple, rather than a
+ list.
+ </para>
+ <para>
+ Note that in Python, strings are sequences, which can have
+ undesirable effects that might be familiar to Python programmers:
+
+<programlisting>
+CREATE FUNCTION return_str_arr()
+ RETURNS varchar[]
+AS $$
+return "hello"
+$$ LANGUAGE plpython3u;
+
+SELECT return_str_arr();
+ return_str_arr
+----------------
+ {h,e,l,l,o}
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Composite Types</title>
+ <para>
+ Composite-type arguments are passed to the function as Python mappings. The
+ element names of the mapping are the attribute names of the composite type.
+ If an attribute in the passed row has the null value, it has the value
+ <symbol>None</symbol> in the mapping. Here is an example:
+
+<programlisting>
+CREATE TABLE employee (
+ name text,
+ salary integer,
+ age integer
+);
+
+CREATE FUNCTION overpaid (e employee)
+ RETURNS boolean
+AS $$
+ if e["salary"] &gt; 200000:
+ return True
+ if (e["age"] &lt; 30) and (e["salary"] &gt; 100000):
+ return True
+ return False
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+
+ <para>
+ There are multiple ways to return row or composite types from a Python
+ function. The following examples assume we have:
+
+<programlisting>
+CREATE TYPE named_value AS (
+ name text,
+ value integer
+);
+</programlisting>
+
+ A composite result can be returned as a:
+
+ <variablelist>
+ <varlistentry>
+ <term>Sequence type (a tuple or list, but not a set because
+ it is not indexable)</term>
+ <listitem>
+ <para>
+ Returned sequence objects must have the same number of items as the
+ composite result type has fields. The item with index 0 is assigned to
+ the first field of the composite type, 1 to the second and so on. For
+ example:
+
+<programlisting>
+CREATE FUNCTION make_pair (name text, value integer)
+ RETURNS named_value
+AS $$
+ return ( name, value )
+ # or alternatively, as list: return [ name, value ]
+$$ LANGUAGE plpython3u;
+</programlisting>
+
+ To return an SQL null for any column, insert <symbol>None</symbol> at
+ the corresponding position.
+ </para>
+ <para>
+ When an array of composite types is returned, it cannot be returned as a list,
+ because it is ambiguous whether the Python list represents a composite type,
+ or another array dimension.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Mapping (dictionary)</term>
+ <listitem>
+ <para>
+ The value for each result type column is retrieved from the mapping
+ with the column name as key. Example:
+
+<programlisting>
+CREATE FUNCTION make_pair (name text, value integer)
+ RETURNS named_value
+AS $$
+ return { "name": name, "value": value }
+$$ LANGUAGE plpython3u;
+</programlisting>
+
+ Any extra dictionary key/value pairs are ignored. Missing keys are
+ treated as errors.
+ To return an SQL null value for any column, insert
+ <symbol>None</symbol> with the corresponding column name as the key.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Object (any object providing method <literal>__getattr__</literal>)</term>
+ <listitem>
+ <para>
+ This works the same as a mapping.
+ Example:
+
+<programlisting>
+CREATE FUNCTION make_pair (name text, value integer)
+ RETURNS named_value
+AS $$
+ class named_value:
+ def __init__ (self, n, v):
+ self.name = n
+ self.value = v
+ return named_value(name, value)
+
+ # or simply
+ class nv: pass
+ nv.name = name
+ nv.value = value
+ return nv
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Functions with <literal>OUT</literal> parameters are also supported. For example:
+<programlisting>
+CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer) AS $$
+return (1, 2)
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM multiout_simple();
+</programlisting>
+ </para>
+
+ <para>
+ Output parameters of procedures are passed back the same way. For example:
+<programlisting>
+CREATE PROCEDURE python_triple(INOUT a integer, INOUT b integer) AS $$
+return (a * 3, b * 3)
+$$ LANGUAGE plpython3u;
+
+CALL python_triple(5, 10);
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Set-Returning Functions</title>
+ <para>
+ A <application>PL/Python</application> function can also return sets of
+ scalar or composite types. There are several ways to achieve this because
+ the returned object is internally turned into an iterator. The following
+ examples assume we have composite type:
+
+<programlisting>
+CREATE TYPE greeting AS (
+ how text,
+ who text
+);
+</programlisting>
+
+ A set result can be returned from a:
+
+ <variablelist>
+ <varlistentry>
+ <term>Sequence type (tuple, list, set)</term>
+ <listitem>
+ <para>
+<programlisting>
+CREATE FUNCTION greet (how text)
+ RETURNS SETOF greeting
+AS $$
+ # return tuple containing lists as composite types
+ # all other combinations work also
+ return ( [ how, "World" ], [ how, "PostgreSQL" ], [ how, "PL/Python" ] )
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Iterator (any object providing <symbol>__iter__</symbol> and
+ <symbol>next</symbol> methods)</term>
+ <listitem>
+ <para>
+<programlisting>
+CREATE FUNCTION greet (how text)
+ RETURNS SETOF greeting
+AS $$
+ class producer:
+ def __init__ (self, how, who):
+ self.how = how
+ self.who = who
+ self.ndx = -1
+
+ def __iter__ (self):
+ return self
+
+ def next (self):
+ self.ndx += 1
+ if self.ndx == len(self.who):
+ raise StopIteration
+ return ( self.how, self.who[self.ndx] )
+
+ return producer(how, [ "World", "PostgreSQL", "PL/Python" ])
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Generator (<literal>yield</literal>)</term>
+ <listitem>
+ <para>
+<programlisting>
+CREATE FUNCTION greet (how text)
+ RETURNS SETOF greeting
+AS $$
+ for who in [ "World", "PostgreSQL", "PL/Python" ]:
+ yield ( how, who )
+$$ LANGUAGE plpython3u;
+</programlisting>
+
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Set-returning functions with <literal>OUT</literal> parameters
+ (using <literal>RETURNS SETOF record</literal>) are also
+ supported. For example:
+<programlisting>
+CREATE FUNCTION multiout_simple_setof(n integer, OUT integer, OUT integer) RETURNS SETOF record AS $$
+return [(1, 2)] * n
+$$ LANGUAGE plpython3u;
+
+SELECT * FROM multiout_simple_setof(3);
+</programlisting>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpython-sharing">
+ <title>Sharing Data</title>
+ <para>
+ The global dictionary <varname>SD</varname> is available to store
+ private data between repeated calls to the same function.
+ The global dictionary <varname>GD</varname> is public data,
+ that is available to all Python functions within a session; use with
+ care.<indexterm><primary>global data</primary>
+ <secondary>in PL/Python</secondary></indexterm>
+ </para>
+
+ <para>
+ Each function gets its own execution environment in the
+ Python interpreter, so that global data and function arguments from
+ <function>myfunc</function> are not available to
+ <function>myfunc2</function>. The exception is the data in the
+ <varname>GD</varname> dictionary, as mentioned above.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-do">
+ <title>Anonymous Code Blocks</title>
+
+ <para>
+ PL/Python also supports anonymous code blocks called with the
+ <xref linkend="sql-do"/> statement:
+
+<programlisting>
+DO $$
+ # PL/Python code
+$$ LANGUAGE plpython3u;
+</programlisting>
+
+ An anonymous code block receives no arguments, and whatever value it
+ might return is discarded. Otherwise it behaves just like a function.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-trigger">
+ <title>Trigger Functions</title>
+
+ <indexterm zone="plpython-trigger">
+ <primary>trigger</primary>
+ <secondary>in PL/Python</secondary>
+ </indexterm>
+
+ <para>
+ When a function is used as a trigger, the dictionary
+ <literal>TD</literal> contains trigger-related values:
+ <variablelist>
+ <varlistentry>
+ <term><literal>TD["event"]</literal></term>
+ <listitem>
+ <para>
+ contains the event as a string:
+ <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, or <literal>TRUNCATE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["when"]</literal></term>
+ <listitem>
+ <para>
+ contains one of <literal>BEFORE</literal>, <literal>AFTER</literal>, or
+ <literal>INSTEAD OF</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["level"]</literal></term>
+ <listitem>
+ <para>
+ contains <literal>ROW</literal> or <literal>STATEMENT</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["new"]</literal></term>
+ <term><literal>TD["old"]</literal></term>
+ <listitem>
+ <para>
+ For a row-level trigger, one or both of these fields contain
+ the respective trigger rows, depending on the trigger event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["name"]</literal></term>
+ <listitem>
+ <para>
+ contains the trigger name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["table_name"]</literal></term>
+ <listitem>
+ <para>
+ contains the name of the table on which the trigger occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["table_schema"]</literal></term>
+ <listitem>
+ <para>
+ contains the schema of the table on which the trigger occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["relid"]</literal></term>
+ <listitem>
+ <para>
+ contains the OID of the table on which the trigger occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TD["args"]</literal></term>
+ <listitem>
+ <para>
+ If the <command>CREATE TRIGGER</command> command
+ included arguments, they are available in <literal>TD["args"][0]</literal> to
+ <literal>TD["args"][<replaceable>n</replaceable>-1]</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ If <literal>TD["when"]</literal> is <literal>BEFORE</literal> or
+ <literal>INSTEAD OF</literal> and
+ <literal>TD["level"]</literal> is <literal>ROW</literal>, you can
+ return <literal>None</literal> or <literal>"OK"</literal> from the
+ Python function to indicate the row is unmodified,
+ <literal>"SKIP"</literal> to abort the event, or if <literal>TD["event"]</literal>
+ is <command>INSERT</command> or <command>UPDATE</command> you can return
+ <literal>"MODIFY"</literal> to indicate you've modified the new row.
+ Otherwise the return value is ignored.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-database">
+ <title>Database Access</title>
+
+ <para>
+ The PL/Python language module automatically imports a Python module
+ called <literal>plpy</literal>. The functions and constants in
+ this module are available to you in the Python code as
+ <literal>plpy.<replaceable>foo</replaceable></literal>.
+ </para>
+
+ <sect2>
+ <title>Database Access Functions</title>
+
+ <para>
+ The <literal>plpy</literal> module provides several functions to execute
+ database commands:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>plpy.<function>execute</function>(<replaceable>query</replaceable> [, <replaceable>limit</replaceable>])</literal></term>
+ <listitem>
+ <para>
+ Calling <function>plpy.execute</function> with a query string and an
+ optional row limit argument causes that query to be run and the result to
+ be returned in a result object.
+ </para>
+
+ <para>
+ If <replaceable>limit</replaceable> is specified and is greater than
+ zero, then <function>plpy.execute</function> retrieves at
+ most <replaceable>limit</replaceable> rows, much as if the query
+ included a <literal>LIMIT</literal>
+ clause. Omitting <replaceable>limit</replaceable> or specifying it as
+ zero results in no row limit.
+ </para>
+
+ <para>
+ The result object emulates a list or dictionary object. The result
+ object can be accessed by row number and column name. For example:
+<programlisting>
+rv = plpy.execute("SELECT * FROM my_table", 5)
+</programlisting>
+ returns up to 5 rows from <literal>my_table</literal>. If
+ <literal>my_table</literal> has a column
+ <literal>my_column</literal>, it would be accessed as:
+<programlisting>
+foo = rv[i]["my_column"]
+</programlisting>
+ The number of rows returned can be obtained using the built-in
+ <function>len</function> function.
+ </para>
+
+ <para>
+ The result object has these additional methods:
+ <variablelist>
+ <varlistentry>
+ <term><literal><function>nrows</function>()</literal></term>
+ <listitem>
+ <para>
+ Returns the number of rows processed by the command. Note that this
+ is not necessarily the same as the number of rows returned. For
+ example, an <command>UPDATE</command> command will set this value but
+ won't return any rows (unless <literal>RETURNING</literal> is used).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><function>status</function>()</literal></term>
+ <listitem>
+ <para>
+ The <function>SPI_execute()</function> return value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><function>colnames</function>()</literal></term>
+ <term><literal><function>coltypes</function>()</literal></term>
+ <term><literal><function>coltypmods</function>()</literal></term>
+ <listitem>
+ <para>
+ Return a list of column names, list of column type OIDs, and list of
+ type-specific type modifiers for the columns, respectively.
+ </para>
+
+ <para>
+ These methods raise an exception when called on a result object from
+ a command that did not produce a result set, e.g.,
+ <command>UPDATE</command> without <literal>RETURNING</literal>, or
+ <command>DROP TABLE</command>. But it is OK to use these methods on
+ a result set containing zero rows.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><function>__str__</function>()</literal></term>
+ <listitem>
+ <para>
+ The standard <literal>__str__</literal> method is defined so that it
+ is possible for example to debug query execution results
+ using <literal>plpy.debug(rv)</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The result object can be modified.
+ </para>
+
+ <para>
+ Note that calling <literal>plpy.execute</literal> will cause the entire
+ result set to be read into memory. Only use that function when you are
+ sure that the result set will be relatively small. If you don't want to
+ risk excessive memory usage when fetching large results,
+ use <literal>plpy.cursor</literal> rather
+ than <literal>plpy.execute</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>plpy.<function>prepare</function>(<replaceable>query</replaceable> [, <replaceable>argtypes</replaceable>])</literal></term>
+ <term><literal>plpy.<function>execute</function>(<replaceable>plan</replaceable> [, <replaceable>arguments</replaceable> [, <replaceable>limit</replaceable>]])</literal></term>
+ <listitem>
+ <para>
+ <indexterm><primary>preparing a query</primary><secondary>in PL/Python</secondary></indexterm>
+ <function>plpy.prepare</function> prepares the execution plan for a
+ query. It is called with a query string and a list of parameter types,
+ if you have parameter references in the query. For example:
+<programlisting>
+plan = plpy.prepare("SELECT last_name FROM my_users WHERE first_name = $1", ["text"])
+</programlisting>
+ <literal>text</literal> is the type of the variable you will be passing
+ for <literal>$1</literal>. The second argument is optional if you don't
+ want to pass any parameters to the query.
+ </para>
+ <para>
+ After preparing a statement, you use a variant of the
+ function <function>plpy.execute</function> to run it:
+<programlisting>
+rv = plpy.execute(plan, ["name"], 5)
+</programlisting>
+ Pass the plan as the first argument (instead of the query string), and a
+ list of values to substitute into the query as the second argument. The
+ second argument is optional if the query does not expect any parameters.
+ The third argument is the optional row limit as before.
+ </para>
+
+ <para>
+ Alternatively, you can call the <function>execute</function> method on
+ the plan object:
+<programlisting>
+rv = plan.execute(["name"], 5)
+</programlisting>
+ </para>
+
+ <para>
+ Query parameters and result row fields are converted between PostgreSQL
+ and Python data types as described in <xref linkend="plpython-data"/>.
+ </para>
+
+ <para>
+ When you prepare a plan using the PL/Python module it is automatically
+ saved. Read the SPI documentation (<xref linkend="spi"/>) for a
+ description of what this means. In order to make effective use of this
+ across function calls one needs to use one of the persistent storage
+ dictionaries <literal>SD</literal> or <literal>GD</literal> (see
+ <xref linkend="plpython-sharing"/>). For example:
+<programlisting>
+CREATE FUNCTION usesavedplan() RETURNS trigger AS $$
+ if "plan" in SD:
+ plan = SD["plan"]
+ else:
+ plan = plpy.prepare("SELECT 1")
+ SD["plan"] = plan
+ # rest of function
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>plpy.<function>cursor</function>(<replaceable>query</replaceable>)</literal></term>
+ <term><literal>plpy.<function>cursor</function>(<replaceable>plan</replaceable> [, <replaceable>arguments</replaceable>])</literal></term>
+ <listitem>
+ <para>
+ The <literal>plpy.cursor</literal> function accepts the same arguments
+ as <literal>plpy.execute</literal> (except for the row limit) and returns
+ a cursor object, which allows you to process large result sets in smaller
+ chunks. As with <literal>plpy.execute</literal>, either a query string
+ or a plan object along with a list of arguments can be used, or
+ the <function>cursor</function> function can be called as a method of
+ the plan object.
+ </para>
+
+ <para>
+ The cursor object provides a <literal>fetch</literal> method that accepts
+ an integer parameter and returns a result object. Each time you
+ call <literal>fetch</literal>, the returned object will contain the next
+ batch of rows, never larger than the parameter value. Once all rows are
+ exhausted, <literal>fetch</literal> starts returning an empty result
+ object. Cursor objects also provide an
+ <ulink url="https://docs.python.org/library/stdtypes.html#iterator-types">iterator
+ interface</ulink>, yielding one row at a time until all rows are
+ exhausted. Data fetched that way is not returned as result objects, but
+ rather as dictionaries, each dictionary corresponding to a single result
+ row.
+ </para>
+
+ <para>
+ An example of two ways of processing data from a large table is:
+<programlisting>
+CREATE FUNCTION count_odd_iterator() RETURNS integer AS $$
+odd = 0
+for row in plpy.cursor("select num from largetable"):
+ if row['num'] % 2:
+ odd += 1
+return odd
+$$ LANGUAGE plpython3u;
+
+CREATE FUNCTION count_odd_fetch(batch_size integer) RETURNS integer AS $$
+odd = 0
+cursor = plpy.cursor("select num from largetable")
+while True:
+ rows = cursor.fetch(batch_size)
+ if not rows:
+ break
+ for row in rows:
+ if row['num'] % 2:
+ odd += 1
+return odd
+$$ LANGUAGE plpython3u;
+
+CREATE FUNCTION count_odd_prepared() RETURNS integer AS $$
+odd = 0
+plan = plpy.prepare("select num from largetable where num % $1 &lt;&gt; 0", ["integer"])
+rows = list(plpy.cursor(plan, [2])) # or: = list(plan.cursor([2]))
+
+return len(rows)
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+
+ <para>
+ Cursors are automatically disposed of. But if you want to explicitly
+ release all resources held by a cursor, use the <literal>close</literal>
+ method. Once closed, a cursor cannot be fetched from anymore.
+ </para>
+
+ <tip>
+ <para>
+ Do not confuse objects created by <literal>plpy.cursor</literal> with
+ DB-API cursors as defined by
+ the <ulink url="https://www.python.org/dev/peps/pep-0249/">Python
+ Database API specification</ulink>. They don't have anything in common
+ except for the name.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="plpython-trapping">
+ <title>Trapping Errors</title>
+
+ <para>
+ Functions accessing the database might encounter errors, which
+ will cause them to abort and raise an exception. Both
+ <function>plpy.execute</function> and
+ <function>plpy.prepare</function> can raise an instance of a subclass of
+ <literal>plpy.SPIError</literal>, which by default will terminate
+ the function. This error can be handled just like any other
+ Python exception, by using the <literal>try/except</literal>
+ construct. For example:
+<programlisting>
+CREATE FUNCTION try_adding_joe() RETURNS text AS $$
+ try:
+ plpy.execute("INSERT INTO users(username) VALUES ('joe')")
+ except plpy.SPIError:
+ return "something went wrong"
+ else:
+ return "Joe added"
+$$ LANGUAGE plpython3u;
+</programlisting>
+ </para>
+
+ <para>
+ The actual class of the exception being raised corresponds to the
+ specific condition that caused the error. Refer
+ to <xref linkend="errcodes-table"/> for a list of possible
+ conditions. The module
+ <literal>plpy.spiexceptions</literal> defines an exception class
+ for each <productname>PostgreSQL</productname> condition, deriving
+ their names from the condition name. For
+ instance, <literal>division_by_zero</literal>
+ becomes <literal>DivisionByZero</literal>, <literal>unique_violation</literal>
+ becomes <literal>UniqueViolation</literal>, <literal>fdw_error</literal>
+ becomes <literal>FdwError</literal>, and so on. Each of these
+ exception classes inherits from <literal>SPIError</literal>. This
+ separation makes it easier to handle specific errors, for
+ instance:
+<programlisting>
+CREATE FUNCTION insert_fraction(numerator int, denominator int) RETURNS text AS $$
+from plpy import spiexceptions
+try:
+ plan = plpy.prepare("INSERT INTO fractions (frac) VALUES ($1 / $2)", ["int", "int"])
+ plpy.execute(plan, [numerator, denominator])
+except spiexceptions.DivisionByZero:
+ return "denominator cannot equal zero"
+except spiexceptions.UniqueViolation:
+ return "already have that fraction"
+except plpy.SPIError as e:
+ return "other error, SQLSTATE %s" % e.sqlstate
+else:
+ return "fraction inserted"
+$$ LANGUAGE plpython3u;
+</programlisting>
+ Note that because all exceptions from
+ the <literal>plpy.spiexceptions</literal> module inherit
+ from <literal>SPIError</literal>, an <literal>except</literal>
+ clause handling it will catch any database access error.
+ </para>
+
+ <para>
+ As an alternative way of handling different error conditions, you
+ can catch the <literal>SPIError</literal> exception and determine
+ the specific error condition inside the <literal>except</literal>
+ block by looking at the <literal>sqlstate</literal> attribute of
+ the exception object. This attribute is a string value containing
+ the <quote>SQLSTATE</quote> error code. This approach provides
+ approximately the same functionality
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpython-subtransaction">
+ <title>Explicit Subtransactions</title>
+
+ <para>
+ Recovering from errors caused by database access as described in
+ <xref linkend="plpython-trapping"/> can lead to an undesirable
+ situation where some operations succeed before one of them fails,
+ and after recovering from that error the data is left in an
+ inconsistent state. PL/Python offers a solution to this problem in
+ the form of explicit subtransactions.
+ </para>
+
+ <sect2>
+ <title>Subtransaction Context Managers</title>
+
+ <para>
+ Consider a function that implements a transfer between two
+ accounts:
+<programlisting>
+CREATE FUNCTION transfer_funds() RETURNS void AS $$
+try:
+ plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'")
+ plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'")
+except plpy.SPIError as e:
+ result = "error transferring funds: %s" % e.args
+else:
+ result = "funds transferred correctly"
+plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"])
+plpy.execute(plan, [result])
+$$ LANGUAGE plpython3u;
+</programlisting>
+ If the second <literal>UPDATE</literal> statement results in an
+ exception being raised, this function will report the error, but
+ the result of the first <literal>UPDATE</literal> will
+ nevertheless be committed. In other words, the funds will be
+ withdrawn from Joe's account, but will not be transferred to
+ Mary's account.
+ </para>
+
+ <para>
+ To avoid such issues, you can wrap your
+ <literal>plpy.execute</literal> calls in an explicit
+ subtransaction. The <literal>plpy</literal> module provides a
+ helper object to manage explicit subtransactions that gets created
+ with the <literal>plpy.subtransaction()</literal> function.
+ Objects created by this function implement the
+ <ulink url="https://docs.python.org/library/stdtypes.html#context-manager-types">
+ context manager interface</ulink>. Using explicit subtransactions
+ we can rewrite our function as:
+<programlisting>
+CREATE FUNCTION transfer_funds2() RETURNS void AS $$
+try:
+ with plpy.subtransaction():
+ plpy.execute("UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'")
+ plpy.execute("UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'")
+except plpy.SPIError as e:
+ result = "error transferring funds: %s" % e.args
+else:
+ result = "funds transferred correctly"
+plan = plpy.prepare("INSERT INTO operations (result) VALUES ($1)", ["text"])
+plpy.execute(plan, [result])
+$$ LANGUAGE plpython3u;
+</programlisting>
+ Note that the use of <literal>try/catch</literal> is still
+ required. Otherwise the exception would propagate to the top of
+ the Python stack and would cause the whole function to abort with
+ a <productname>PostgreSQL</productname> error, so that the
+ <literal>operations</literal> table would not have any row
+ inserted into it. The subtransaction context manager does not
+ trap errors, it only assures that all database operations executed
+ inside its scope will be atomically committed or rolled back. A
+ rollback of the subtransaction block occurs on any kind of
+ exception exit, not only ones caused by errors originating from
+ database access. A regular Python exception raised inside an
+ explicit subtransaction block would also cause the subtransaction
+ to be rolled back.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plpython-transactions">
+ <title>Transaction Management</title>
+
+ <para>
+ In a procedure called from the top level or an anonymous code block
+ (<command>DO</command> command) called from the top level it is possible to
+ control transactions. To commit the current transaction, call
+ <literal>plpy.commit()</literal>. To roll back the current transaction,
+ call <literal>plpy.rollback()</literal>. (Note that it is not possible to
+ run the SQL commands <command>COMMIT</command> or
+ <command>ROLLBACK</command> via <function>plpy.execute</function> or
+ similar. It has to be done using these functions.) After a transaction is
+ ended, a new transaction is automatically started, so there is no separate
+ function for that.
+ </para>
+
+ <para>
+ Here is an example:
+<programlisting>
+CREATE PROCEDURE transaction_test1()
+LANGUAGE plpython3u
+AS $$
+for i in range(0, 10):
+ plpy.execute("INSERT INTO test1 (a) VALUES (%d)" % i)
+ if i % 2 == 0:
+ plpy.commit()
+ else:
+ plpy.rollback()
+$$;
+
+CALL transaction_test1();
+</programlisting>
+ </para>
+
+ <para>
+ Transactions cannot be ended when an explicit subtransaction is active.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-util">
+ <title>Utility Functions</title>
+ <para>
+ The <literal>plpy</literal> module also provides the functions
+ <simplelist>
+ <member><literal>plpy.debug(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ <member><literal>plpy.log(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ <member><literal>plpy.info(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ <member><literal>plpy.notice(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ <member><literal>plpy.warning(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ <member><literal>plpy.error(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ <member><literal>plpy.fatal(<replaceable>msg, **kwargs</replaceable>)</literal></member>
+ </simplelist>
+ <indexterm><primary>elog</primary><secondary>in PL/Python</secondary></indexterm>
+ <function>plpy.error</function> and <function>plpy.fatal</function>
+ actually raise a Python exception which, if uncaught, propagates out to
+ the calling query, causing the current transaction or subtransaction to
+ be aborted. <literal>raise plpy.Error(<replaceable>msg</replaceable>)</literal> and
+ <literal>raise plpy.Fatal(<replaceable>msg</replaceable>)</literal> are
+ equivalent to calling <literal>plpy.error(<replaceable>msg</replaceable>)</literal> and
+ <literal>plpy.fatal(<replaceable>msg</replaceable>)</literal>, respectively but
+ the <literal>raise</literal> form does not allow passing keyword arguments.
+ The other functions only generate messages of different priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <xref linkend="guc-log-min-messages"/> and
+ <xref linkend="guc-client-min-messages"/> configuration
+ variables. See <xref linkend="runtime-config"/> for more information.
+ </para>
+
+ <para>
+ The <replaceable>msg</replaceable> argument is given as a positional argument. For
+ backward compatibility, more than one positional argument can be given. In
+ that case, the string representation of the tuple of positional arguments
+ becomes the message reported to the client.
+ </para>
+
+ <para>
+ The following keyword-only arguments are accepted:
+ <simplelist>
+ <member><literal>detail</literal></member>
+ <member><literal>hint</literal></member>
+ <member><literal>sqlstate</literal></member>
+ <member><literal>schema_name</literal></member>
+ <member><literal>table_name</literal></member>
+ <member><literal>column_name</literal></member>
+ <member><literal>datatype_name</literal></member>
+ <member><literal>constraint_name</literal></member>
+ </simplelist>
+ The string representation of the objects passed as keyword-only arguments
+ is used to enrich the messages reported to the client. For example:
+
+<programlisting>
+CREATE FUNCTION raise_custom_exception() RETURNS void AS $$
+plpy.error("custom exception message",
+ detail="some info about exception",
+ hint="hint for users")
+$$ LANGUAGE plpython3u;
+
+=# SELECT raise_custom_exception();
+ERROR: plpy.Error: custom exception message
+DETAIL: some info about exception
+HINT: hint for users
+CONTEXT: Traceback (most recent call last):
+ PL/Python function "raise_custom_exception", line 4, in &lt;module&gt;
+ hint="hint for users")
+PL/Python function "raise_custom_exception"
+</programlisting>
+ </para>
+
+ <para>
+ Another set of utility functions are
+ <literal>plpy.quote_literal(<replaceable>string</replaceable>)</literal>,
+ <literal>plpy.quote_nullable(<replaceable>string</replaceable>)</literal>, and
+ <literal>plpy.quote_ident(<replaceable>string</replaceable>)</literal>. They
+ are equivalent to the built-in quoting functions described in <xref
+ linkend="functions-string"/>. They are useful when constructing
+ ad-hoc queries. A PL/Python equivalent of dynamic SQL from <xref
+ linkend="plpgsql-quote-literal-example"/> would be:
+<programlisting>
+plpy.execute("UPDATE tbl SET %s = %s WHERE key = %s" % (
+ plpy.quote_ident(colname),
+ plpy.quote_nullable(newvalue),
+ plpy.quote_literal(keyvalue)))
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-python23">
+ <title>Python 2 vs. Python 3</title>
+
+ <para>
+ PL/Python supports only Python 3. Past versions of
+ <productname>PostgreSQL</productname> supported Python 2, using the
+ <literal>plpythonu</literal> and <literal>plpython2u</literal> language
+ names.
+ </para>
+ </sect1>
+
+ <sect1 id="plpython-envar">
+ <title>Environment Variables</title>
+
+ <para>
+ Some of the environment variables that are accepted by the Python
+ interpreter can also be used to affect PL/Python behavior. They
+ would need to be set in the environment of the main PostgreSQL
+ server process, for example in a start script. The available
+ environment variables depend on the version of Python; see the
+ Python documentation for details. At the time of this writing, the
+ following environment variables have an affect on PL/Python,
+ assuming an adequate Python version:
+ <itemizedlist>
+ <listitem>
+ <para><envar>PYTHONHOME</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONPATH</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONY2K</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONOPTIMIZE</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONDEBUG</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONVERBOSE</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONCASEOK</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONDONTWRITEBYTECODE</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONIOENCODING</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONUSERBASE</envar></para>
+ </listitem>
+
+ <listitem>
+ <para><envar>PYTHONHASHSEED</envar></para>
+ </listitem>
+ </itemizedlist>
+
+ (It appears to be a Python implementation detail beyond the control
+ of PL/Python that some of the environment variables listed on
+ the <command>python</command> man page are only effective in a
+ command-line interpreter and not an embedded Python interpreter.)
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml
new file mode 100644
index 0000000..b31f2c1
--- /dev/null
+++ b/doc/src/sgml/pltcl.sgml
@@ -0,0 +1,1135 @@
+<!-- doc/src/sgml/pltcl.sgml -->
+
+ <chapter id="pltcl">
+ <title>PL/Tcl &mdash; Tcl Procedural Language</title>
+
+ <indexterm zone="pltcl">
+ <primary>PL/Tcl</primary>
+ </indexterm>
+
+ <indexterm zone="pltcl">
+ <primary>Tcl</primary>
+ </indexterm>
+
+ <para>
+ PL/Tcl is a loadable procedural language for the
+ <productname>PostgreSQL</productname> database system
+ that enables the <ulink url="https://www.tcl.tk/">
+ Tcl language</ulink> to be used to write
+ <productname>PostgreSQL</productname> functions and procedures.
+ </para>
+
+ <!-- **** PL/Tcl overview **** -->
+
+ <sect1 id="pltcl-overview">
+ <title>Overview</title>
+
+ <para>
+ PL/Tcl offers most of the capabilities a function writer has in
+ the C language, with a few restrictions, and with the addition of
+ the powerful string processing libraries that are available for
+ Tcl.
+ </para>
+ <para>
+ One compelling <emphasis>good</emphasis> restriction is that
+ everything is executed from within the safety of the context of a
+ Tcl interpreter. In addition to the limited command set of safe
+ Tcl, only a few commands are available to access the database via
+ SPI and to raise messages via <function>elog()</function>. PL/Tcl
+ provides no way to access internals of the database server or to
+ gain OS-level access under the permissions of the
+ <productname>PostgreSQL</productname> server process, as a C
+ function can do. Thus, unprivileged database users can be trusted
+ to use this language; it does not give them unlimited authority.
+ </para>
+ <para>
+ The other notable implementation restriction is that Tcl functions
+ cannot be used to create input/output functions for new data
+ types.
+ </para>
+ <para>
+ Sometimes it is desirable to write Tcl functions that are not restricted
+ to safe Tcl. For example, one might want a Tcl function that sends
+ email. To handle these cases, there is a variant of <application>PL/Tcl</application> called <literal>PL/TclU</literal>
+ (for untrusted Tcl). This is exactly the same language except that a full
+ Tcl interpreter is used. <emphasis>If <application>PL/TclU</application> is used, it must be
+ installed as an untrusted procedural language</emphasis> so that only
+ database superusers can create functions in it. The writer of a <application>PL/TclU</application>
+ function must take care that the function cannot be used to do anything
+ unwanted, since it will be able to do anything that could be done by
+ a user logged in as the database administrator.
+ </para>
+ <para>
+ The shared object code for the <application>PL/Tcl</application> and
+ <application>PL/TclU</application> call handlers is automatically built and
+ installed in the <productname>PostgreSQL</productname> library
+ directory if Tcl support is specified in the configuration step of
+ the installation procedure. To install <application>PL/Tcl</application>
+ and/or <application>PL/TclU</application> in a particular database, use the
+ <command>CREATE EXTENSION</command> command, for example
+ <literal>CREATE EXTENSION pltcl</literal> or
+ <literal>CREATE EXTENSION pltclu</literal>.
+ </para>
+ </sect1>
+
+ <!-- **** PL/Tcl description **** -->
+
+ <sect1 id="pltcl-functions">
+ <title>PL/Tcl Functions and Arguments</title>
+
+ <para>
+ To create a function in the <application>PL/Tcl</application> language, use
+ the standard <xref linkend="sql-createfunction"/> syntax:
+
+<programlisting>
+CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS $$
+ # PL/Tcl function body
+$$ LANGUAGE pltcl;
+</programlisting>
+
+ <application>PL/TclU</application> is the same, except that the language has to be specified as
+ <literal>pltclu</literal>.
+ </para>
+
+ <para>
+ The body of the function is simply a piece of Tcl script.
+ When the function is called, the argument values are passed to the
+ Tcl script as variables named <literal>1</literal>
+ ... <literal><replaceable>n</replaceable></literal>. The result is
+ returned from the Tcl code in the usual way, with
+ a <literal>return</literal> statement. In a procedure, the return value
+ from the Tcl code is ignored.
+ </para>
+
+ <para>
+ For example, a function
+ returning the greater of two integer values could be defined as:
+
+<programlisting>
+CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
+ if {$1 &gt; $2} {return $1}
+ return $2
+$$ LANGUAGE pltcl STRICT;
+</programlisting>
+
+ Note the clause <literal>STRICT</literal>, which saves us from
+ having to think about null input values: if a null value is passed, the
+ function will not be called at all, but will just return a null
+ result automatically.
+ </para>
+
+ <para>
+ In a nonstrict function,
+ if the actual value of an argument is null, the corresponding
+ <literal>$<replaceable>n</replaceable></literal> variable will be set to an empty string.
+ To detect whether a particular argument is null, use the function
+ <literal>argisnull</literal>. For example, suppose that we wanted <function>tcl_max</function>
+ with one null and one nonnull argument to return the nonnull
+ argument, rather than null:
+
+<programlisting>
+CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
+ if {[argisnull 1]} {
+ if {[argisnull 2]} { return_null }
+ return $2
+ }
+ if {[argisnull 2]} { return $1 }
+ if {$1 &gt; $2} {return $1}
+ return $2
+$$ LANGUAGE pltcl;
+</programlisting>
+ </para>
+
+ <para>
+ As shown above,
+ to return a null value from a PL/Tcl function, execute
+ <literal>return_null</literal>. This can be done whether the
+ function is strict or not.
+ </para>
+
+ <para>
+ Composite-type arguments are passed to the function as Tcl
+ arrays. The element names of the array are the attribute names
+ of the composite type. If an attribute in the passed row has the
+ null value, it will not appear in the array. Here is an example:
+
+<programlisting>
+CREATE TABLE employee (
+ name text,
+ salary integer,
+ age integer
+);
+
+CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
+ if {200000.0 &lt; $1(salary)} {
+ return "t"
+ }
+ if {$1(age) &lt; 30 &amp;&amp; 100000.0 &lt; $1(salary)} {
+ return "t"
+ }
+ return "f"
+$$ LANGUAGE pltcl;
+</programlisting>
+ </para>
+
+ <para>
+ PL/Tcl functions can return composite-type results, too. To do this,
+ the Tcl code must return a list of column name/value pairs matching
+ the expected result type. Any column names omitted from the list
+ are returned as nulls, and an error is raised if there are unexpected
+ column names. Here is an example:
+
+<programlisting>
+CREATE FUNCTION square_cube(in int, out squared int, out cubed int) AS $$
+ return [list squared [expr {$1 * $1}] cubed [expr {$1 * $1 * $1}]]
+$$ LANGUAGE pltcl;
+</programlisting>
+ </para>
+
+ <para>
+ Output arguments of procedures are returned in the same way, for example:
+
+<programlisting>
+CREATE PROCEDURE tcl_triple(INOUT a integer, INOUT b integer) AS $$
+ return [list a [expr {$1 * 3}] b [expr {$2 * 3}]]
+$$ LANGUAGE pltcl;
+
+CALL tcl_triple(5, 10);
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ The result list can be made from an array representation of the
+ desired tuple with the <literal>array get</literal> Tcl command. For example:
+
+<programlisting>
+CREATE FUNCTION raise_pay(employee, delta int) RETURNS employee AS $$
+ set 1(salary) [expr {$1(salary) + $2}]
+ return [array get 1]
+$$ LANGUAGE pltcl;
+</programlisting>
+ </para>
+ </tip>
+
+ <para>
+ PL/Tcl functions can return sets. To do this, the Tcl code should
+ call <function>return_next</function> once per row to be returned,
+ passing either the appropriate value when returning a scalar type,
+ or a list of column name/value pairs when returning a composite type.
+ Here is an example returning a scalar type:
+
+<programlisting>
+CREATE FUNCTION sequence(int, int) RETURNS SETOF int AS $$
+ for {set i $1} {$i &lt; $2} {incr i} {
+ return_next $i
+ }
+$$ LANGUAGE pltcl;
+</programlisting>
+
+ and here is one returning a composite type:
+
+<programlisting>
+CREATE FUNCTION table_of_squares(int, int) RETURNS TABLE (x int, x2 int) AS $$
+ for {set i $1} {$i &lt; $2} {incr i} {
+ return_next [list x $i x2 [expr {$i * $i}]]
+ }
+$$ LANGUAGE pltcl;
+</programlisting>
+ </para>
+
+ </sect1>
+
+ <sect1 id="pltcl-data">
+ <title>Data Values in PL/Tcl</title>
+
+ <para>
+ The argument values supplied to a PL/Tcl function's code are simply
+ the input arguments converted to text form (just as if they had been
+ displayed by a <command>SELECT</command> statement). Conversely, the
+ <literal>return</literal> and <literal>return_next</literal> commands will accept
+ any string that is acceptable input format for the function's declared
+ result type, or for the specified column of a composite result type.
+ </para>
+
+ </sect1>
+
+ <sect1 id="pltcl-global">
+ <title>Global Data in PL/Tcl</title>
+
+ <indexterm zone="pltcl-global">
+ <primary>global data</primary>
+ <secondary>in PL/Tcl</secondary>
+ </indexterm>
+
+ <para>
+ Sometimes it
+ is useful to have some global data that is held between two
+ calls to a function or is shared between different functions.
+ This is easily done in PL/Tcl, but there are some restrictions that
+ must be understood.
+ </para>
+
+ <para>
+ For security reasons, PL/Tcl executes functions called by any one SQL
+ role in a separate Tcl interpreter for that role. This prevents
+ accidental or malicious interference by one user with the behavior of
+ another user's PL/Tcl functions. Each such interpreter will have its own
+ values for any <quote>global</quote> Tcl variables. Thus, two PL/Tcl
+ functions will share the same global variables if and only if they are
+ executed by the same SQL role. In an application wherein a single
+ session executes code under multiple SQL roles (via <literal>SECURITY
+ DEFINER</literal> functions, use of <command>SET ROLE</command>, etc.) you may need to
+ take explicit steps to ensure that PL/Tcl functions can share data. To
+ do that, make sure that functions that should communicate are owned by
+ the same user, and mark them <literal>SECURITY DEFINER</literal>. You must of
+ course take care that such functions can't be used to do anything
+ unintended.
+ </para>
+
+ <para>
+ All PL/TclU functions used in a session execute in the same Tcl
+ interpreter, which of course is distinct from the interpreter(s)
+ used for PL/Tcl functions. So global data is automatically shared
+ between PL/TclU functions. This is not considered a security risk
+ because all PL/TclU functions execute at the same trust level,
+ namely that of a database superuser.
+ </para>
+
+ <para>
+ To help protect PL/Tcl functions from unintentionally interfering
+ with each other, a global
+ array is made available to each function via the <function>upvar</function>
+ command. The global name of this variable is the function's internal
+ name, and the local name is <literal>GD</literal>. It is recommended that
+ <literal>GD</literal> be used
+ for persistent private data of a function. Use regular Tcl global
+ variables only for values that you specifically intend to be shared among
+ multiple functions. (Note that the <literal>GD</literal> arrays are only
+ global within a particular interpreter, so they do not bypass the
+ security restrictions mentioned above.)
+ </para>
+
+ <para>
+ An example of using <literal>GD</literal> appears in the
+ <function>spi_execp</function> example below.
+ </para>
+ </sect1>
+
+ <sect1 id="pltcl-dbaccess">
+ <title>Database Access from PL/Tcl</title>
+
+ <para>
+ In this section, we follow the usual Tcl convention of using question
+ marks, rather than brackets, to indicate an optional element in a
+ syntax synopsis. The following commands are available to access
+ the database from the body of a PL/Tcl function:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal><function>spi_exec</function> <optional role="tcl">-count <replaceable>n</replaceable></optional> <optional role="tcl">-array <replaceable>name</replaceable></optional> <replaceable>command</replaceable> <optional role="tcl"><replaceable>loop-body</replaceable></optional></literal></term>
+ <listitem>
+ <para>
+ Executes an SQL command given as a string. An error in the command
+ causes an error to be raised. Otherwise, the return value of <function>spi_exec</function>
+ is the number of rows processed (selected, inserted, updated, or
+ deleted) by the command, or zero if the command is a utility
+ statement. In addition, if the command is a <command>SELECT</command> statement, the
+ values of the selected columns are placed in Tcl variables as
+ described below.
+ </para>
+ <para>
+ The optional <literal>-count</literal> value tells
+ <function>spi_exec</function> to stop
+ once <replaceable>n</replaceable> rows have been retrieved,
+ much as if the query included a <literal>LIMIT</literal> clause.
+ If <replaceable>n</replaceable> is zero, the query is run to
+ completion, the same as when <literal>-count</literal> is omitted.
+ </para>
+ <para>
+ If the command is a <command>SELECT</command> statement, the values of the
+ result columns are placed into Tcl variables named after the columns.
+ If the <literal>-array</literal> option is given, the column values are
+ instead stored into elements of the named associative array, with the
+ column names used as array indexes. In addition, the current row
+ number within the result (counting from zero) is stored into the array
+ element named <quote><literal>.tupno</literal></quote>, unless that name is
+ in use as a column name in the result.
+ </para>
+ <para>
+ If the command is a <command>SELECT</command> statement and no <replaceable>loop-body</replaceable>
+ script is given, then only the first row of results are stored into
+ Tcl variables or array elements; remaining rows, if any, are ignored.
+ No storing occurs if the query returns no rows. (This case can be
+ detected by checking the result of <function>spi_exec</function>.)
+ For example:
+<programlisting>
+spi_exec "SELECT count(*) AS cnt FROM pg_proc"
+</programlisting>
+ will set the Tcl variable <literal>$cnt</literal> to the number of rows in
+ the <structname>pg_proc</structname> system catalog.
+ </para>
+ <para>
+ If the optional <replaceable>loop-body</replaceable> argument is given, it is
+ a piece of Tcl script that is executed once for each row in the
+ query result. (<replaceable>loop-body</replaceable> is ignored if the given
+ command is not a <command>SELECT</command>.)
+ The values of the current row's columns
+ are stored into Tcl variables or array elements before each iteration.
+ For example:
+<programlisting>
+spi_exec -array C "SELECT * FROM pg_class" {
+ elog DEBUG "have table $C(relname)"
+}
+</programlisting>
+ will print a log message for every row of <literal>pg_class</literal>. This
+ feature works similarly to other Tcl looping constructs; in
+ particular <literal>continue</literal> and <literal>break</literal> work in the
+ usual way inside the loop body.
+ </para>
+ <para>
+ If a column of a query result is null, the target
+ variable for it is <quote>unset</quote> rather than being set.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>spi_prepare</function> <replaceable>query</replaceable> <replaceable>typelist</replaceable></term>
+ <listitem>
+ <para>
+ Prepares and saves a query plan for later execution. The
+ saved plan will be retained for the life of the current
+ session.<indexterm><primary>preparing a query</primary>
+ <secondary>in PL/Tcl</secondary></indexterm>
+ </para>
+ <para>
+ The query can use parameters, that is, placeholders for
+ values to be supplied whenever the plan is actually executed.
+ In the query string, refer to parameters
+ by the symbols <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal>.
+ If the query uses parameters, the names of the parameter types
+ must be given as a Tcl list. (Write an empty list for
+ <replaceable>typelist</replaceable> if no parameters are used.)
+ </para>
+ <para>
+ The return value from <function>spi_prepare</function> is a query ID
+ to be used in subsequent calls to <function>spi_execp</function>. See
+ <function>spi_execp</function> for an example.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><function>spi_execp</function> <optional role="tcl">-count <replaceable>n</replaceable></optional> <optional role="tcl">-array <replaceable>name</replaceable></optional> <optional role="tcl">-nulls <replaceable>string</replaceable></optional> <replaceable>queryid</replaceable> <optional role="tcl"><replaceable>value-list</replaceable></optional> <optional role="tcl"><replaceable>loop-body</replaceable></optional></literal></term>
+ <listitem>
+ <para>
+ Executes a query previously prepared with <function>spi_prepare</function>.
+ <replaceable>queryid</replaceable> is the ID returned by
+ <function>spi_prepare</function>. If the query references parameters,
+ a <replaceable>value-list</replaceable> must be supplied. This
+ is a Tcl list of actual values for the parameters. The list must be
+ the same length as the parameter type list previously given to
+ <function>spi_prepare</function>. Omit <replaceable>value-list</replaceable>
+ if the query has no parameters.
+ </para>
+ <para>
+ The optional value for <literal>-nulls</literal> is a string of spaces and
+ <literal>'n'</literal> characters telling <function>spi_execp</function>
+ which of the parameters are null values. If given, it must have exactly the
+ same length as the <replaceable>value-list</replaceable>. If it
+ is not given, all the parameter values are nonnull.
+ </para>
+ <para>
+ Except for the way in which the query and its parameters are specified,
+ <function>spi_execp</function> works just like <function>spi_exec</function>.
+ The <literal>-count</literal>, <literal>-array</literal>, and
+ <replaceable>loop-body</replaceable> options are the same,
+ and so is the result value.
+ </para>
+ <para>
+ Here's an example of a PL/Tcl function using a prepared plan:
+
+<programlisting>
+CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
+ if {![ info exists GD(plan) ]} {
+ # prepare the saved plan on the first call
+ set GD(plan) [ spi_prepare \
+ "SELECT count(*) AS cnt FROM t1 WHERE num &gt;= \$1 AND num &lt;= \$2" \
+ [ list int4 int4 ] ]
+ }
+ spi_execp -count 1 $GD(plan) [ list $1 $2 ]
+ return $cnt
+$$ LANGUAGE pltcl;
+</programlisting>
+
+ We need backslashes inside the query string given to
+ <function>spi_prepare</function> to ensure that the
+ <literal>$<replaceable>n</replaceable></literal> markers will be passed
+ through to <function>spi_prepare</function> as-is, and not replaced by Tcl
+ variable substitution.
+
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>subtransaction</function> <replaceable>command</replaceable></term>
+ <listitem>
+ <para>
+ The Tcl script contained in <replaceable>command</replaceable> is
+ executed within an SQL subtransaction. If the script returns an
+ error, that entire subtransaction is rolled back before returning the
+ error out to the surrounding Tcl code.
+ See <xref linkend="pltcl-subtransactions"/> for more details and an
+ example.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>quote</function> <replaceable>string</replaceable></term>
+ <listitem>
+ <para>
+ Doubles all occurrences of single quote and backslash characters
+ in the given string. This can be used to safely quote strings
+ that are to be inserted into SQL commands given
+ to <function>spi_exec</function> or
+ <function>spi_prepare</function>.
+ For example, think about an SQL command string like:
+
+<programlisting>
+"SELECT '$val' AS ret"
+</programlisting>
+
+ where the Tcl variable <literal>val</literal> actually contains
+ <literal>doesn't</literal>. This would result
+ in the final command string:
+
+<programlisting>
+SELECT 'doesn't' AS ret
+</programlisting>
+
+ which would cause a parse error during
+ <function>spi_exec</function> or
+ <function>spi_prepare</function>.
+ To work properly, the submitted command should contain:
+
+<programlisting>
+SELECT 'doesn''t' AS ret
+</programlisting>
+
+ which can be formed in PL/Tcl using:
+
+<programlisting>
+"SELECT '[ quote $val ]' AS ret"
+</programlisting>
+
+ One advantage of <function>spi_execp</function> is that you don't
+ have to quote parameter values like this, since the parameters are never
+ parsed as part of an SQL command string.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>elog</function> <replaceable>level</replaceable> <replaceable>msg</replaceable>
+ <indexterm>
+ <primary>elog</primary>
+ <secondary>in PL/Tcl</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Emits a log or error message. Possible levels are
+ <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>,
+ <literal>NOTICE</literal>, <literal>WARNING</literal>, <literal>ERROR</literal>, and
+ <literal>FATAL</literal>. <literal>ERROR</literal>
+ raises an error condition; if this is not trapped by the surrounding
+ Tcl code, the error propagates out to the calling query, causing
+ the current transaction or subtransaction to be aborted. This
+ is effectively the same as the Tcl <literal>error</literal> command.
+ <literal>FATAL</literal> aborts the transaction and causes the current
+ session to shut down. (There is probably no good reason to use
+ this error level in PL/Tcl functions, but it's provided for
+ completeness.) The other levels only generate messages of different
+ priority levels.
+ Whether messages of a particular priority are reported to the client,
+ written to the server log, or both is controlled by the
+ <xref linkend="guc-log-min-messages"/> and
+ <xref linkend="guc-client-min-messages"/> configuration
+ variables. See <xref linkend="runtime-config"/>
+ and <xref linkend="pltcl-error-handling"/>
+ for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </sect1>
+
+ <sect1 id="pltcl-trigger">
+ <title>Trigger Functions in PL/Tcl</title>
+
+ <indexterm>
+ <primary>trigger</primary>
+ <secondary>in PL/Tcl</secondary>
+ </indexterm>
+
+ <para>
+ Trigger functions can be written in PL/Tcl.
+ <productname>PostgreSQL</productname> requires that a function that is to be called
+ as a trigger must be declared as a function with no arguments
+ and a return type of <literal>trigger</literal>.
+ </para>
+ <para>
+ The information from the trigger manager is passed to the function body
+ in the following variables:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><varname>$TG_name</varname></term>
+ <listitem>
+ <para>
+ The name of the trigger from the <command>CREATE TRIGGER</command> statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_relid</varname></term>
+ <listitem>
+ <para>
+ The object ID of the table that caused the trigger function
+ to be invoked.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_table_name</varname></term>
+ <listitem>
+ <para>
+ The name of the table that caused the trigger function
+ to be invoked.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_table_schema</varname></term>
+ <listitem>
+ <para>
+ The schema of the table that caused the trigger function
+ to be invoked.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_relatts</varname></term>
+ <listitem>
+ <para>
+ A Tcl list of the table column names, prefixed with an empty list
+ element. So looking up a column name in the list with <application>Tcl</application>'s
+ <function>lsearch</function> command returns the element's number starting
+ with 1 for the first column, the same way the columns are customarily
+ numbered in <productname>PostgreSQL</productname>. (Empty list
+ elements also appear in the positions of columns that have been
+ dropped, so that the attribute numbering is correct for columns
+ to their right.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_when</varname></term>
+ <listitem>
+ <para>
+ The string <literal>BEFORE</literal>, <literal>AFTER</literal>, or
+ <literal>INSTEAD OF</literal>, depending on the type of trigger event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_level</varname></term>
+ <listitem>
+ <para>
+ The string <literal>ROW</literal> or <literal>STATEMENT</literal> depending on the
+ type of trigger event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_op</varname></term>
+ <listitem>
+ <para>
+ The string <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, or <literal>TRUNCATE</literal> depending on the type of
+ trigger event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$NEW</varname></term>
+ <listitem>
+ <para>
+ An associative array containing the values of the new table
+ row for <command>INSERT</command> or <command>UPDATE</command> actions, or
+ empty for <command>DELETE</command>. The array is indexed by column
+ name. Columns that are null will not appear in the array.
+ This is not set for statement-level triggers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$OLD</varname></term>
+ <listitem>
+ <para>
+ An associative array containing the values of the old table
+ row for <command>UPDATE</command> or <command>DELETE</command> actions, or
+ empty for <command>INSERT</command>. The array is indexed by column
+ name. Columns that are null will not appear in the array.
+ This is not set for statement-level triggers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$args</varname></term>
+ <listitem>
+ <para>
+ A Tcl list of the arguments to the function as given in the
+ <command>CREATE TRIGGER</command> statement. These arguments are also accessible as
+ <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal> in the function body.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ The return value from a trigger function can be one of the strings
+ <literal>OK</literal> or <literal>SKIP</literal>, or a list of column name/value pairs.
+ If the return value is <literal>OK</literal>,
+ the operation (<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>)
+ that fired the trigger will proceed
+ normally. <literal>SKIP</literal> tells the trigger manager to silently suppress
+ the operation for this row. If a list is returned, it tells PL/Tcl to
+ return a modified row to the trigger manager; the contents of the
+ modified row are specified by the column names and values in the list.
+ Any columns not mentioned in the list are set to null.
+ Returning a modified row is only meaningful
+ for row-level <literal>BEFORE</literal> <command>INSERT</command> or <command>UPDATE</command>
+ triggers, for which the modified row will be inserted instead of the one
+ given in <varname>$NEW</varname>; or for row-level <literal>INSTEAD OF</literal>
+ <command>INSERT</command> or <command>UPDATE</command> triggers where the returned row
+ is used as the source data for <command>INSERT RETURNING</command> or
+ <command>UPDATE RETURNING</command> clauses.
+ In row-level <literal>BEFORE</literal> <command>DELETE</command> or <literal>INSTEAD
+ OF</literal> <command>DELETE</command> triggers, returning a modified row has the same
+ effect as returning <literal>OK</literal>, that is the operation proceeds.
+ The trigger return value is ignored for all other types of triggers.
+ </para>
+
+ <tip>
+ <para>
+ The result list can be made from an array representation of the
+ modified tuple with the <literal>array get</literal> Tcl command.
+ </para>
+ </tip>
+
+ <para>
+ Here's a little example trigger function that forces an integer value
+ in a table to keep track of the number of updates that are performed on the
+ row. For new rows inserted, the value is initialized to 0 and then
+ incremented on every update operation.
+
+<programlisting>
+CREATE FUNCTION trigfunc_modcount() RETURNS trigger AS $$
+ switch $TG_op {
+ INSERT {
+ set NEW($1) 0
+ }
+ UPDATE {
+ set NEW($1) $OLD($1)
+ incr NEW($1)
+ }
+ default {
+ return OK
+ }
+ }
+ return [array get NEW]
+$$ LANGUAGE pltcl;
+
+CREATE TABLE mytab (num integer, description text, modcnt integer);
+
+CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab
+ FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt');
+</programlisting>
+
+ Notice that the trigger function itself does not know the column
+ name; that's supplied from the trigger arguments. This lets the
+ trigger function be reused with different tables.
+ </para>
+ </sect1>
+
+ <sect1 id="pltcl-event-trigger">
+ <title>Event Trigger Functions in PL/Tcl</title>
+
+ <indexterm>
+ <primary>event trigger</primary>
+ <secondary>in PL/Tcl</secondary>
+ </indexterm>
+
+ <para>
+ Event trigger functions can be written in PL/Tcl.
+ <productname>PostgreSQL</productname> requires that a function that is
+ to be called as an event trigger must be declared as a function with no
+ arguments and a return type of <literal>event_trigger</literal>.
+ </para>
+ <para>
+ The information from the trigger manager is passed to the function body
+ in the following variables:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><varname>$TG_event</varname></term>
+ <listitem>
+ <para>
+ The name of the event the trigger is fired for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>$TG_tag</varname></term>
+ <listitem>
+ <para>
+ The command tag for which the trigger is fired.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The return value of the trigger function is ignored.
+ </para>
+
+ <para>
+ Here's a little example event trigger function that simply raises
+ a <literal>NOTICE</literal> message each time a supported command is
+ executed:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$
+ elog NOTICE "tclsnitch: $TG_event $TG_tag"
+$$ LANGUAGE pltcl;
+
+CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitch();
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="pltcl-error-handling">
+ <title>Error Handling in PL/Tcl</title>
+
+ <indexterm>
+ <primary>exceptions</primary>
+ <secondary>in PL/Tcl</secondary>
+ </indexterm>
+
+ <para>
+ Tcl code within or called from a PL/Tcl function can raise an error,
+ either by executing some invalid operation or by generating an error
+ using the Tcl <function>error</function> command or
+ PL/Tcl's <function>elog</function> command. Such errors can be caught
+ within Tcl using the Tcl <function>catch</function> command. If an
+ error is not caught but is allowed to propagate out to the top level of
+ execution of the PL/Tcl function, it is reported as an SQL error in the
+ function's calling query.
+ </para>
+
+ <para>
+ Conversely, SQL errors that occur within PL/Tcl's
+ <function>spi_exec</function>, <function>spi_prepare</function>,
+ and <function>spi_execp</function> commands are reported as Tcl errors,
+ so they are catchable by Tcl's <function>catch</function> command.
+ (Each of these PL/Tcl commands runs its SQL operation in a
+ subtransaction, which is rolled back on error, so that any
+ partially-completed operation is automatically cleaned up.)
+ Again, if an error propagates out to the top level without being caught,
+ it turns back into an SQL error.
+ </para>
+
+ <para>
+ Tcl provides an <varname>errorCode</varname> variable that can represent
+ additional information about an error in a form that is easy for Tcl
+ programs to interpret. The contents are in Tcl list format, and the
+ first word identifies the subsystem or library reporting the error;
+ beyond that the contents are left to the individual subsystem or
+ library. For database errors reported by PL/Tcl commands, the first
+ word is <literal>POSTGRES</literal>, the second word is the PostgreSQL
+ version number, and additional words are field name/value pairs
+ providing detailed information about the error.
+ Fields <varname>SQLSTATE</varname>, <varname>condition</varname>,
+ and <varname>message</varname> are always supplied
+ (the first two represent the error code and condition name as shown
+ in <xref linkend="errcodes-appendix"/>).
+ Fields that may be present include
+ <varname>detail</varname>, <varname>hint</varname>, <varname>context</varname>,
+ <varname>schema</varname>, <varname>table</varname>, <varname>column</varname>,
+ <varname>datatype</varname>, <varname>constraint</varname>,
+ <varname>statement</varname>, <varname>cursor_position</varname>,
+ <varname>filename</varname>, <varname>lineno</varname>, and
+ <varname>funcname</varname>.
+ </para>
+
+ <para>
+ A convenient way to work with PL/Tcl's <varname>errorCode</varname>
+ information is to load it into an array, so that the field names become
+ array subscripts. Code for doing that might look like
+<programlisting>
+if {[catch { spi_exec $sql_command }]} {
+ if {[lindex $::errorCode 0] == "POSTGRES"} {
+ array set errorArray $::errorCode
+ if {$errorArray(condition) == "undefined_table"} {
+ # deal with missing table
+ } else {
+ # deal with some other type of SQL error
+ }
+ }
+}
+</programlisting>
+ (The double colons explicitly specify that <varname>errorCode</varname>
+ is a global variable.)
+ </para>
+ </sect1>
+
+ <sect1 id="pltcl-subtransactions">
+ <title>Explicit Subtransactions in PL/Tcl</title>
+
+ <indexterm>
+ <primary>subtransactions</primary>
+ <secondary>in PL/Tcl</secondary>
+ </indexterm>
+
+ <para>
+ Recovering from errors caused by database access as described in
+ <xref linkend="pltcl-error-handling"/> can lead to an undesirable
+ situation where some operations succeed before one of them fails,
+ and after recovering from that error the data is left in an
+ inconsistent state. PL/Tcl offers a solution to this problem in
+ the form of explicit subtransactions.
+ </para>
+
+ <para>
+ Consider a function that implements a transfer between two accounts:
+<programlisting>
+CREATE FUNCTION transfer_funds() RETURNS void AS $$
+ if [catch {
+ spi_exec "UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'"
+ spi_exec "UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'"
+ } errormsg] {
+ set result [format "error transferring funds: %s" $errormsg]
+ } else {
+ set result "funds transferred successfully"
+ }
+ spi_exec "INSERT INTO operations (result) VALUES ('[quote $result]')"
+$$ LANGUAGE pltcl;
+</programlisting>
+ If the second <command>UPDATE</command> statement results in an
+ exception being raised, this function will log the failure, but
+ the result of the first <command>UPDATE</command> will
+ nevertheless be committed. In other words, the funds will be
+ withdrawn from Joe's account, but will not be transferred to
+ Mary's account. This happens because each <function>spi_exec</function>
+ is a separate subtransaction, and only one of those subtransactions
+ got rolled back.
+ </para>
+
+ <para>
+ To handle such cases, you can wrap multiple database operations in an
+ explicit subtransaction, which will succeed or roll back as a whole.
+ PL/Tcl provides a <function>subtransaction</function> command to manage
+ this. We can rewrite our function as:
+<programlisting>
+CREATE FUNCTION transfer_funds2() RETURNS void AS $$
+ if [catch {
+ subtransaction {
+ spi_exec "UPDATE accounts SET balance = balance - 100 WHERE account_name = 'joe'"
+ spi_exec "UPDATE accounts SET balance = balance + 100 WHERE account_name = 'mary'"
+ }
+ } errormsg] {
+ set result [format "error transferring funds: %s" $errormsg]
+ } else {
+ set result "funds transferred successfully"
+ }
+ spi_exec "INSERT INTO operations (result) VALUES ('[quote $result]')"
+$$ LANGUAGE pltcl;
+</programlisting>
+ Note that use of <function>catch</function> is still required for this
+ purpose. Otherwise the error would propagate to the top level of the
+ function, preventing the desired insertion into
+ the <structname>operations</structname> table.
+ The <function>subtransaction</function> command does not trap errors, it
+ only assures that all database operations executed inside its scope will
+ be rolled back together when an error is reported.
+ </para>
+
+ <para>
+ A rollback of an explicit subtransaction occurs on any error reported
+ by the contained Tcl code, not only errors originating from database
+ access. Thus a regular Tcl exception raised inside
+ a <function>subtransaction</function> command will also cause the
+ subtransaction to be rolled back. However, non-error exits out of the
+ contained Tcl code (for instance, due to <function>return</function>) do
+ not cause a rollback.
+ </para>
+ </sect1>
+
+ <sect1 id="pltcl-transactions">
+ <title>Transaction Management</title>
+
+ <para>
+ In a procedure called from the top level or an anonymous code block
+ (<command>DO</command> command) called from the top level it is possible
+ to control transactions. To commit the current transaction, call the
+ <literal>commit</literal> command. To roll back the current transaction,
+ call the <literal>rollback</literal> command. (Note that it is not
+ possible to run the SQL commands <command>COMMIT</command> or
+ <command>ROLLBACK</command> via <function>spi_exec</function> or similar.
+ It has to be done using these functions.) After a transaction is ended,
+ a new transaction is automatically started, so there is no separate
+ command for that.
+ </para>
+
+ <para>
+ Here is an example:
+<programlisting>
+CREATE PROCEDURE transaction_test1()
+LANGUAGE pltcl
+AS $$
+for {set i 0} {$i &lt; 10} {incr i} {
+ spi_exec "INSERT INTO test1 (a) VALUES ($i)"
+ if {$i % 2 == 0} {
+ commit
+ } else {
+ rollback
+ }
+}
+$$;
+
+CALL transaction_test1();
+</programlisting>
+ </para>
+
+ <para>
+ Transactions cannot be ended when an explicit subtransaction is active.
+ </para>
+ </sect1>
+
+ <sect1 id="pltcl-config">
+ <title>PL/Tcl Configuration</title>
+
+ <para>
+ This section lists configuration parameters that
+ affect <application>PL/Tcl</application>.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="guc-pltcl-start-proc" xreflabel="pltcl.start_proc">
+ <term>
+ <varname>pltcl.start_proc</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>pltcl.start_proc</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter, if set to a nonempty string, specifies the name
+ (possibly schema-qualified) of a parameterless PL/Tcl function that
+ is to be executed whenever a new Tcl interpreter is created for
+ PL/Tcl. Such a function can perform per-session initialization, such
+ as loading additional Tcl code. A new Tcl interpreter is created
+ when a PL/Tcl function is first executed in a database session, or
+ when an additional interpreter has to be created because a PL/Tcl
+ function is called by a new SQL role.
+ </para>
+
+ <para>
+ The referenced function must be written in the <literal>pltcl</literal>
+ language, and must not be marked <literal>SECURITY DEFINER</literal>.
+ (These restrictions ensure that it runs in the interpreter it's
+ supposed to initialize.) The current user must have permission to
+ call it, too.
+ </para>
+
+ <para>
+ If the function fails with an error it will abort the function call
+ that caused the new interpreter to be created and propagate out to
+ the calling query, causing the current transaction or subtransaction
+ to be aborted. Any actions already done within Tcl won't be undone;
+ however, that interpreter won't be used again. If the language is
+ used again the initialization will be attempted again within a fresh
+ Tcl interpreter.
+ </para>
+
+ <para>
+ Only superusers can change this setting. Although this setting
+ can be changed within a session, such changes will not affect Tcl
+ interpreters that have already been created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="guc-pltclu-start-proc" xreflabel="pltclu.start_proc">
+ <term>
+ <varname>pltclu.start_proc</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>pltclu.start_proc</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter is exactly like <varname>pltcl.start_proc</varname>,
+ except that it applies to PL/TclU. The referenced function must
+ be written in the <literal>pltclu</literal> language.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect1>
+
+ <sect1 id="pltcl-procnames">
+ <title>Tcl Procedure Names</title>
+
+ <para>
+ In <productname>PostgreSQL</productname>, the same function name can be used for
+ different function definitions as long as the number of arguments or their types
+ differ. Tcl, however, requires all procedure names to be distinct.
+ PL/Tcl deals with this by making the internal Tcl procedure names contain
+ the object
+ ID of the function from the system table <structname>pg_proc</structname> as part of their name. Thus,
+ <productname>PostgreSQL</productname> functions with the same name
+ and different argument types will be different Tcl procedures, too. This
+ is not normally a concern for a PL/Tcl programmer, but it might be visible
+ when debugging.
+ </para>
+
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml
new file mode 100644
index 0000000..bfd344c
--- /dev/null
+++ b/doc/src/sgml/postgres-fdw.sgml
@@ -0,0 +1,1155 @@
+<!-- doc/src/sgml/postgres-fdw.sgml -->
+
+<sect1 id="postgres-fdw" xreflabel="postgres_fdw">
+ <title>postgres_fdw</title>
+
+ <indexterm zone="postgres-fdw">
+ <primary>postgres_fdw</primary>
+ </indexterm>
+
+ <para>
+ The <filename>postgres_fdw</filename> module provides the foreign-data wrapper
+ <literal>postgres_fdw</literal>, which can be used to access data
+ stored in external <productname>PostgreSQL</productname> servers.
+ </para>
+
+ <para>
+ The functionality provided by this module overlaps substantially
+ with the functionality of the older <xref linkend="dblink"/> module.
+ But <filename>postgres_fdw</filename> provides more transparent and
+ standards-compliant syntax for accessing remote tables, and can give
+ better performance in many cases.
+ </para>
+
+ <para>
+ To prepare for remote access using <filename>postgres_fdw</filename>:
+ <orderedlist spacing="compact">
+ <listitem>
+ <para>
+ Install the <filename>postgres_fdw</filename> extension using <xref
+ linkend="sql-createextension"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Create a foreign server object, using <xref linkend="sql-createserver"/>,
+ to represent each remote database you want to connect to.
+ Specify connection information, except <literal>user</literal> and
+ <literal>password</literal>, as options of the server object.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Create a user mapping, using <xref linkend="sql-createusermapping"/>, for
+ each database user you want to allow to access each foreign server.
+ Specify the remote user name and password to use as
+ <literal>user</literal> and <literal>password</literal> options of the
+ user mapping.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Create a foreign table, using <xref linkend="sql-createforeigntable"/>
+ or <xref linkend="sql-importforeignschema"/>,
+ for each remote table you want to access. The columns of the foreign
+ table must match the referenced remote table. You can, however, use
+ table and/or column names different from the remote table's, if you
+ specify the correct remote names as options of the foreign table object.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ Now you need only <command>SELECT</command> from a foreign table to access
+ the data stored in its underlying remote table. You can also modify
+ the remote table using <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, <command>COPY</command>, or
+ <command>TRUNCATE</command>.
+ (Of course, the remote user you have specified in your user mapping must
+ have privileges to do these things.)
+ </para>
+
+ <para>
+ Note that the <literal>ONLY</literal> option specified in
+ <command>SELECT</command>, <command>UPDATE</command>,
+ <command>DELETE</command> or <command>TRUNCATE</command>
+ has no effect when accessing or modifying the remote table.
+ </para>
+
+ <para>
+ Note that <filename>postgres_fdw</filename> currently lacks support for
+ <command>INSERT</command> statements with an <literal>ON CONFLICT DO
+ UPDATE</literal> clause. However, the <literal>ON CONFLICT DO NOTHING</literal>
+ clause is supported, provided a unique index inference specification
+ is omitted.
+ Note also that <filename>postgres_fdw</filename> supports row movement
+ invoked by <command>UPDATE</command> statements executed on partitioned
+ tables, but it currently does not handle the case where a remote partition
+ chosen to insert a moved row into is also an <command>UPDATE</command>
+ target partition that will be updated elsewhere in the same command.
+ </para>
+
+ <para>
+ It is generally recommended that the columns of a foreign table be declared
+ with exactly the same data types, and collations if applicable, as the
+ referenced columns of the remote table. Although <filename>postgres_fdw</filename>
+ is currently rather forgiving about performing data type conversions at
+ need, surprising semantic anomalies may arise when types or collations do
+ not match, due to the remote server interpreting query conditions
+ differently from the local server.
+ </para>
+
+ <para>
+ Note that a foreign table can be declared with fewer columns, or with a
+ different column order, than its underlying remote table has. Matching
+ of columns to the remote table is by name, not position.
+ </para>
+
+ <sect2>
+ <title>FDW Options of postgres_fdw</title>
+
+ <sect3>
+ <title>Connection Options</title>
+
+ <para>
+ A foreign server using the <filename>postgres_fdw</filename> foreign data wrapper
+ can have the same options that <application>libpq</application> accepts in
+ connection strings, as described in <xref linkend="libpq-paramkeywords"/>,
+ except that these options are not allowed or have special handling:
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <literal>user</literal>, <literal>password</literal> and <literal>sslpassword</literal> (specify these
+ in a user mapping, instead, or use a service file)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>client_encoding</literal> (this is automatically set from the local
+ server encoding)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>application_name</literal> - this may appear in
+ <emphasis>either or both</emphasis> a connection and
+ <xref linkend="guc-pgfdw-application-name"/>.
+ If both are present, <varname>postgres_fdw.application_name</varname>
+ overrides the connection setting.
+ Unlike <application>libpq</application>,
+ <filename>postgres_fdw</filename> allows
+ <varname>application_name</varname> to include
+ <quote>escape sequences</quote>.
+ See <xref linkend="guc-pgfdw-application-name"/> for details.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>fallback_application_name</literal> (always set to
+ <literal>postgres_fdw</literal>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>sslkey</literal> and <literal>sslcert</literal> - these may
+ appear in <emphasis>either or both</emphasis> a connection and a user
+ mapping. If both are present, the user mapping setting overrides the
+ connection setting.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Only superusers may create or modify user mappings with the
+ <literal>sslcert</literal> or <literal>sslkey</literal> settings.
+ </para>
+ <para>
+ Only superusers may connect to foreign servers without password
+ authentication, so always specify the <literal>password</literal> option
+ for user mappings belonging to non-superusers.
+ </para>
+ <para>
+ A superuser may override this check on a per-user-mapping basis by setting
+ the user mapping option <literal>password_required 'false'</literal>, e.g.,
+<programlisting>
+ALTER USER MAPPING FOR some_non_superuser SERVER loopback_nopw
+OPTIONS (ADD password_required 'false');
+</programlisting>
+ To prevent unprivileged users from exploiting the authentication rights
+ of the unix user the postgres server is running as to escalate to superuser
+ rights, only the superuser may set this option on a user mapping.
+ </para>
+ <para>
+ Care is required to ensure that this does not allow the mapped
+ user the ability to connect as superuser to the mapped database per
+ CVE-2007-3278 and CVE-2007-6601. Don't set
+ <literal>password_required=false</literal>
+ on the <literal>public</literal> role. Keep in mind that the mapped
+ user can potentially use any client certificates,
+ <filename>.pgpass</filename>,
+ <filename>.pg_service.conf</filename> etc. in the unix home directory of the
+ system user the postgres server runs as. They can also use any trust
+ relationship granted by authentication modes like <literal>peer</literal>
+ or <literal>ident</literal> authentication.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Object Name Options</title>
+
+ <para>
+ These options can be used to control the names used in SQL statements
+ sent to the remote <productname>PostgreSQL</productname> server. These
+ options are needed when a foreign table is created with names different
+ from the underlying remote table's names.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>schema_name</literal> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This option, which can be specified for a foreign table, gives the
+ schema name to use for the foreign table on the remote server. If this
+ option is omitted, the name of the foreign table's schema is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>table_name</literal> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This option, which can be specified for a foreign table, gives the
+ table name to use for the foreign table on the remote server. If this
+ option is omitted, the foreign table's name is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>column_name</literal> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This option, which can be specified for a column of a foreign table,
+ gives the column name to use for the column on the remote server.
+ If this option is omitted, the column's name is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3>
+ <title>Cost Estimation Options</title>
+
+ <para>
+ <filename>postgres_fdw</filename> retrieves remote data by executing queries
+ against remote servers, so ideally the estimated cost of scanning a
+ foreign table should be whatever it costs to be done on the remote
+ server, plus some overhead for communication. The most reliable way to
+ get such an estimate is to ask the remote server and then add something
+ for overhead &mdash; but for simple queries, it may not be worth the cost
+ of an additional remote query to get a cost estimate.
+ So <filename>postgres_fdw</filename> provides the following options to control
+ how cost estimation is done:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>use_remote_estimate</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option, which can be specified for a foreign table or a foreign
+ server, controls whether <filename>postgres_fdw</filename> issues remote
+ <command>EXPLAIN</command> commands to obtain cost estimates.
+ A setting for a foreign table overrides any setting for its server,
+ but only for that table.
+ The default is <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>fdw_startup_cost</literal> (<type>floating point</type>)</term>
+ <listitem>
+ <para>
+ This option, which can be specified for a foreign server, is a floating
+ point value that is added to the estimated startup cost of any
+ foreign-table scan on that server. This represents the additional
+ overhead of establishing a connection, parsing and planning the query on
+ the remote side, etc.
+ The default value is <literal>100</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>fdw_tuple_cost</literal> (<type>floating point</type>)</term>
+ <listitem>
+ <para>
+ This option, which can be specified for a foreign server, is a floating
+ point value that is used as extra cost per-tuple for foreign-table
+ scans on that server. This represents the additional overhead of
+ data transfer between servers. You might increase or decrease this
+ number to reflect higher or lower network delay to the remote server.
+ The default value is <literal>0.01</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ When <literal>use_remote_estimate</literal> is true,
+ <filename>postgres_fdw</filename> obtains row count and cost estimates from the
+ remote server and then adds <literal>fdw_startup_cost</literal> and
+ <literal>fdw_tuple_cost</literal> to the cost estimates. When
+ <literal>use_remote_estimate</literal> is false,
+ <filename>postgres_fdw</filename> performs local row count and cost estimation
+ and then adds <literal>fdw_startup_cost</literal> and
+ <literal>fdw_tuple_cost</literal> to the cost estimates. This local
+ estimation is unlikely to be very accurate unless local copies of the
+ remote table's statistics are available. Running
+ <xref linkend="sql-analyze"/> on the foreign table is the way to update
+ the local statistics; this will perform a scan of the remote table and
+ then calculate and store statistics just as though the table were local.
+ Keeping local statistics can be a useful way to reduce per-query planning
+ overhead for a remote table &mdash; but if the remote table is
+ frequently updated, the local statistics will soon be obsolete.
+ </para>
+
+ </sect3>
+
+ <sect3>
+ <title>Remote Execution Options</title>
+
+ <para>
+ By default, only <literal>WHERE</literal> clauses using built-in operators and
+ functions will be considered for execution on the remote server. Clauses
+ involving non-built-in functions are checked locally after rows are
+ fetched. If such functions are available on the remote server and can be
+ relied on to produce the same results as they do locally, performance can
+ be improved by sending such <literal>WHERE</literal> clauses for remote
+ execution. This behavior can be controlled using the following option:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>extensions</literal> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This option is a comma-separated list of names
+ of <productname>PostgreSQL</productname> extensions that are installed, in
+ compatible versions, on both the local and remote servers. Functions
+ and operators that are immutable and belong to a listed extension will
+ be considered shippable to the remote server.
+ This option can only be specified for foreign servers, not per-table.
+ </para>
+
+ <para>
+ When using the <literal>extensions</literal> option, <emphasis>it is the
+ user's responsibility</emphasis> that the listed extensions exist and behave
+ identically on both the local and remote servers. Otherwise, remote
+ queries may fail or behave unexpectedly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>fetch_size</literal> (<type>integer</type>)</term>
+ <listitem>
+ <para>
+ This option specifies the number of rows <filename>postgres_fdw</filename>
+ should get in each fetch operation. It can be specified for a foreign
+ table or a foreign server. The option specified on a table overrides
+ an option specified for the server.
+ The default is <literal>100</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>batch_size</literal> (<type>integer</type>)</term>
+ <listitem>
+ <para>
+ This option specifies the number of rows <filename>postgres_fdw</filename>
+ should insert in each insert operation. It can be specified for a
+ foreign table or a foreign server. The option specified on a table
+ overrides an option specified for the server.
+ The default is <literal>1</literal>.
+ </para>
+
+ <para>
+ Note the actual number of rows <filename>postgres_fdw</filename> inserts at
+ once depends on the number of columns and the provided
+ <literal>batch_size</literal> value. The batch is executed as a single
+ query, and the libpq protocol (which <filename>postgres_fdw</filename>
+ uses to connect to a remote server) limits the number of parameters in a
+ single query to 65535. When the number of columns * <literal>batch_size</literal>
+ exceeds the limit, the <literal>batch_size</literal> will be adjusted to
+ avoid an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3>
+ <title>Asynchronous Execution Options</title>
+
+ <para>
+ <filename>postgres_fdw</filename> supports asynchronous execution, which
+ runs multiple parts of an <structname>Append</structname> node
+ concurrently rather than serially to improve performance.
+ This execution can be controlled using the following option:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>async_capable</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether <filename>postgres_fdw</filename> allows
+ foreign tables to be scanned concurrently for asynchronous execution.
+ It can be specified for a foreign table or a foreign server.
+ A table-level option overrides a server-level option.
+ The default is <literal>false</literal>.
+ </para>
+
+ <para>
+ In order to ensure that the data being returned from a foreign server
+ is consistent, <filename>postgres_fdw</filename> will only open one
+ connection for a given foreign server and will run all queries against
+ that server sequentially even if there are multiple foreign tables
+ involved, unless those tables are subject to different user mappings.
+ In such a case, it may be more performant to disable this option to
+ eliminate the overhead associated with running queries asynchronously.
+ </para>
+
+ <para>
+ Asynchronous execution is applied even when an
+ <structname>Append</structname> node contains subplan(s) executed
+ synchronously as well as subplan(s) executed asynchronously.
+ In such a case, if the asynchronous subplans are ones processed using
+ <filename>postgres_fdw</filename>, tuples from the asynchronous
+ subplans are not returned until after at least one synchronous subplan
+ returns all tuples, as that subplan is executed while the asynchronous
+ subplans are waiting for the results of asynchronous queries sent to
+ foreign servers.
+ This behavior might change in a future release.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect3>
+
+ <sect3>
+ <title>Transaction Management Options</title>
+
+ <para>
+ As described in the Transaction Management section, in
+ <filename>postgres_fdw</filename> transactions are managed by creating
+ corresponding remote transactions, and subtransactions are managed by
+ creating corresponding remote subtransactions. When multiple remote
+ transactions are involved in the current local transaction, by default
+ <filename>postgres_fdw</filename> commits those remote transactions
+ serially when the local transaction is committed. When multiple remote
+ subtransactions are involved in the current local subtransaction, by
+ default <filename>postgres_fdw</filename> commits those remote
+ subtransactions serially when the local subtransaction is committed.
+ Performance can be improved with the following option:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>parallel_commit</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether <filename>postgres_fdw</filename> commits
+ in parallel remote transactions opened on a foreign server in a local
+ transaction when the local transaction is committed. This setting also
+ applies to remote and local subtransactions. This option can only be
+ specified for foreign servers, not per-table. The default is
+ <literal>false</literal>.
+ </para>
+
+ <para>
+ If multiple foreign servers with this option enabled are involved in a
+ local transaction, multiple remote transactions on those foreign
+ servers are committed in parallel across those foreign servers when
+ the local transaction is committed.
+ </para>
+
+ <para>
+ When this option is enabled, a foreign server with many remote
+ transactions may see a negative performance impact when the local
+ transaction is committed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3>
+ <title>Updatability Options</title>
+
+ <para>
+ By default all foreign tables using <filename>postgres_fdw</filename> are assumed
+ to be updatable. This may be overridden using the following option:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>updatable</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether <filename>postgres_fdw</filename> allows foreign
+ tables to be modified using <command>INSERT</command>, <command>UPDATE</command> and
+ <command>DELETE</command> commands. It can be specified for a foreign table
+ or a foreign server. A table-level option overrides a server-level
+ option.
+ The default is <literal>true</literal>.
+ </para>
+
+ <para>
+ Of course, if the remote table is not in fact updatable, an error
+ would occur anyway. Use of this option primarily allows the error to
+ be thrown locally without querying the remote server. Note however
+ that the <literal>information_schema</literal> views will report a
+ <filename>postgres_fdw</filename> foreign table to be updatable (or not)
+ according to the setting of this option, without any check of the
+ remote server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect3>
+
+ <sect3>
+ <title>Truncatability Options</title>
+
+ <para>
+ By default all foreign tables using <filename>postgres_fdw</filename> are assumed
+ to be truncatable. This may be overridden using the following option:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>truncatable</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether <filename>postgres_fdw</filename> allows
+ foreign tables to be truncated using the <command>TRUNCATE</command>
+ command. It can be specified for a foreign table or a foreign server.
+ A table-level option overrides a server-level option.
+ The default is <literal>true</literal>.
+ </para>
+
+ <para>
+ Of course, if the remote table is not in fact truncatable, an error
+ would occur anyway. Use of this option primarily allows the error to
+ be thrown locally without querying the remote server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect3>
+
+ <sect3>
+ <title>Importing Options</title>
+
+ <para>
+ <filename>postgres_fdw</filename> is able to import foreign table definitions
+ using <xref linkend="sql-importforeignschema"/>. This command creates
+ foreign table definitions on the local server that match tables or
+ views present on the remote server. If the remote tables to be imported
+ have columns of user-defined data types, the local server must have
+ compatible types of the same names.
+ </para>
+
+ <para>
+ Importing behavior can be customized with the following options
+ (given in the <command>IMPORT FOREIGN SCHEMA</command> command):
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>import_collate</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether column <literal>COLLATE</literal> options
+ are included in the definitions of foreign tables imported
+ from a foreign server. The default is <literal>true</literal>. You might
+ need to turn this off if the remote server has a different set of
+ collation names than the local server does, which is likely to be the
+ case if it's running on a different operating system.
+ If you do so, however, there is a very severe risk that the imported
+ table columns' collations will not match the underlying data, resulting
+ in anomalous query behavior.
+ </para>
+
+ <para>
+ Even when this parameter is set to <literal>true</literal>, importing
+ columns whose collation is the remote server's default can be risky.
+ They will be imported with <literal>COLLATE "default"</literal>, which
+ will select the local server's default collation, which could be
+ different.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>import_default</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether column <literal>DEFAULT</literal> expressions
+ are included in the definitions of foreign tables imported
+ from a foreign server. The default is <literal>false</literal>. If you
+ enable this option, be wary of defaults that might get computed
+ differently on the local server than they would be on the remote
+ server; <function>nextval()</function> is a common source of problems.
+ The <command>IMPORT</command> will fail altogether if an imported default
+ expression uses a function or operator that does not exist locally.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>import_generated</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether column <literal>GENERATED</literal> expressions
+ are included in the definitions of foreign tables imported
+ from a foreign server. The default is <literal>true</literal>.
+ The <command>IMPORT</command> will fail altogether if an imported generated
+ expression uses a function or operator that does not exist locally.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>import_not_null</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether column <literal>NOT NULL</literal>
+ constraints are included in the definitions of foreign tables imported
+ from a foreign server. The default is <literal>true</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Note that constraints other than <literal>NOT NULL</literal> will never be
+ imported from the remote tables. Although <productname>PostgreSQL</productname>
+ does support check constraints on foreign tables, there is no
+ provision for importing them automatically, because of the risk that a
+ constraint expression could evaluate differently on the local and remote
+ servers. Any such inconsistency in the behavior of a check
+ constraint could lead to hard-to-detect errors in query optimization.
+ So if you wish to import check constraints, you must do so
+ manually, and you should verify the semantics of each one carefully.
+ For more detail about the treatment of check constraints on
+ foreign tables, see <xref linkend="sql-createforeigntable"/>.
+ </para>
+
+ <para>
+ Tables or foreign tables which are partitions of some other table are
+ imported only when they are explicitly specified in
+ <literal>LIMIT TO</literal> clause. Otherwise they are automatically
+ excluded from <xref linkend="sql-importforeignschema"/>.
+ Since all data can be accessed through the partitioned table
+ which is the root of the partitioning hierarchy, importing only
+ partitioned tables should allow access to all the data without
+ creating extra objects.
+ </para>
+
+ </sect3>
+
+ <sect3>
+ <title>Connection Management Options</title>
+
+ <para>
+ By default, all connections that <filename>postgres_fdw</filename>
+ establishes to foreign servers are kept open in the local session
+ for re-use.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>keep_connections</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option controls whether <filename>postgres_fdw</filename> keeps
+ the connections to the foreign server open so that subsequent
+ queries can re-use them. It can only be specified for a foreign server.
+ The default is <literal>on</literal>. If set to <literal>off</literal>,
+ all connections to this foreign server will be discarded at the end of
+ each transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </sect3>
+ </sect2>
+
+<sect2>
+ <title>Functions</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>postgres_fdw_get_connections(OUT server_name text, OUT valid boolean) returns setof record</function></term>
+ <listitem>
+ <para>
+ This function returns the foreign server names of all the open
+ connections that <filename>postgres_fdw</filename> established from
+ the local session to the foreign servers. It also returns whether
+ each connection is valid or not. <literal>false</literal> is returned
+ if the foreign server connection is used in the current local
+ transaction but its foreign server or user mapping is changed or
+ dropped (Note that server name of an invalid connection will be
+ <literal>NULL</literal> if the server is dropped),
+ and then such invalid connection will be closed at
+ the end of that transaction. <literal>true</literal> is returned
+ otherwise. If there are no open connections, no record is returned.
+ Example usage of the function:
+<screen>
+postgres=# SELECT * FROM postgres_fdw_get_connections() ORDER BY 1;
+ server_name | valid
+-------------+-------
+ loopback1 | t
+ loopback2 | f
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>postgres_fdw_disconnect(server_name text) returns boolean</function></term>
+ <listitem>
+ <para>
+ This function discards the open connections that are established by
+ <filename>postgres_fdw</filename> from the local session to
+ the foreign server with the given name. Note that there can be
+ multiple connections to the given server using different user mappings.
+ If the connections are used in the current local transaction,
+ they are not disconnected and warning messages are reported.
+ This function returns <literal>true</literal> if it disconnects
+ at least one connection, otherwise <literal>false</literal>.
+ If no foreign server with the given name is found, an error is reported.
+ Example usage of the function:
+<screen>
+postgres=# SELECT postgres_fdw_disconnect('loopback1');
+ postgres_fdw_disconnect
+-------------------------
+ t
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>postgres_fdw_disconnect_all() returns boolean</function></term>
+ <listitem>
+ <para>
+ This function discards all the open connections that are established by
+ <filename>postgres_fdw</filename> from the local session to
+ foreign servers. If the connections are used in the current local
+ transaction, they are not disconnected and warning messages are reported.
+ This function returns <literal>true</literal> if it disconnects
+ at least one connection, otherwise <literal>false</literal>.
+ Example usage of the function:
+<screen>
+postgres=# SELECT postgres_fdw_disconnect_all();
+ postgres_fdw_disconnect_all
+-----------------------------
+ t
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+</sect2>
+
+ <sect2>
+ <title>Connection Management</title>
+
+ <para>
+ <filename>postgres_fdw</filename> establishes a connection to a
+ foreign server during the first query that uses a foreign table
+ associated with the foreign server. By default this connection
+ is kept and re-used for subsequent queries in the same session.
+ This behavior can be controlled using
+ <literal>keep_connections</literal> option for a foreign server. If
+ multiple user identities (user mappings) are used to access the foreign
+ server, a connection is established for each user mapping.
+ </para>
+
+ <para>
+ When changing the definition of or removing a foreign server or
+ a user mapping, the associated connections are closed.
+ But note that if any connections are in use in the current local transaction,
+ they are kept until the end of the transaction.
+ Closed connections will be re-established when they are necessary
+ by future queries using a foreign table.
+ </para>
+
+ <para>
+ Once a connection to a foreign server has been established,
+ it's by default kept until the local or corresponding remote
+ session exits. To disconnect a connection explicitly,
+ <literal>keep_connections</literal> option for a foreign server
+ may be disabled, or
+ <function>postgres_fdw_disconnect</function> and
+ <function>postgres_fdw_disconnect_all</function> functions
+ may be used. For example, these are useful to close
+ connections that are no longer necessary, thereby releasing
+ connections on the foreign server.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Transaction Management</title>
+
+ <para>
+ During a query that references any remote tables on a foreign server,
+ <filename>postgres_fdw</filename> opens a transaction on the
+ remote server if one is not already open corresponding to the current
+ local transaction. The remote transaction is committed or aborted when
+ the local transaction commits or aborts. Savepoints are similarly
+ managed by creating corresponding remote savepoints.
+ </para>
+
+ <para>
+ The remote transaction uses <literal>SERIALIZABLE</literal>
+ isolation level when the local transaction has <literal>SERIALIZABLE</literal>
+ isolation level; otherwise it uses <literal>REPEATABLE READ</literal>
+ isolation level. This choice ensures that if a query performs multiple
+ table scans on the remote server, it will get snapshot-consistent results
+ for all the scans. A consequence is that successive queries within a
+ single transaction will see the same data from the remote server, even if
+ concurrent updates are occurring on the remote server due to other
+ activities. That behavior would be expected anyway if the local
+ transaction uses <literal>SERIALIZABLE</literal> or <literal>REPEATABLE READ</literal>
+ isolation level, but it might be surprising for a <literal>READ
+ COMMITTED</literal> local transaction. A future
+ <productname>PostgreSQL</productname> release might modify these rules.
+ </para>
+
+ <para>
+ Note that it is currently not supported by
+ <filename>postgres_fdw</filename> to prepare the remote transaction for
+ two-phase commit.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Remote Query Optimization</title>
+
+ <para>
+ <filename>postgres_fdw</filename> attempts to optimize remote queries to reduce
+ the amount of data transferred from foreign servers. This is done by
+ sending query <literal>WHERE</literal> clauses to the remote server for
+ execution, and by not retrieving table columns that are not needed for
+ the current query. To reduce the risk of misexecution of queries,
+ <literal>WHERE</literal> clauses are not sent to the remote server unless they use
+ only data types, operators, and functions that are built-in or belong to an
+ extension that's listed in the foreign server's <literal>extensions</literal>
+ option. Operators and functions in such clauses must
+ be <literal>IMMUTABLE</literal> as well.
+ For an <command>UPDATE</command> or <command>DELETE</command> query,
+ <filename>postgres_fdw</filename> attempts to optimize the query execution by
+ sending the whole query to the remote server if there are no query
+ <literal>WHERE</literal> clauses that cannot be sent to the remote server,
+ no local joins for the query, no row-level local <literal>BEFORE</literal> or
+ <literal>AFTER</literal> triggers or stored generated columns on the target
+ table, and no <literal>CHECK OPTION</literal> constraints from parent
+ views. In <command>UPDATE</command>,
+ expressions to assign to target columns must use only built-in data types,
+ <literal>IMMUTABLE</literal> operators, or <literal>IMMUTABLE</literal> functions,
+ to reduce the risk of misexecution of the query.
+ </para>
+
+ <para>
+ When <filename>postgres_fdw</filename> encounters a join between foreign tables on
+ the same foreign server, it sends the entire join to the foreign server,
+ unless for some reason it believes that it will be more efficient to fetch
+ rows from each table individually, or unless the table references involved
+ are subject to different user mappings. While sending the <literal>JOIN</literal>
+ clauses, it takes the same precautions as mentioned above for the
+ <literal>WHERE</literal> clauses.
+ </para>
+
+ <para>
+ The query that is actually sent to the remote server for execution can
+ be examined using <command>EXPLAIN VERBOSE</command>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Remote Query Execution Environment</title>
+
+ <para>
+ In the remote sessions opened by <filename>postgres_fdw</filename>,
+ the <xref linkend="guc-search-path"/> parameter is set to
+ just <literal>pg_catalog</literal>, so that only built-in objects are visible
+ without schema qualification. This is not an issue for queries
+ generated by <filename>postgres_fdw</filename> itself, because it always
+ supplies such qualification. However, this can pose a hazard for
+ functions that are executed on the remote server via triggers or rules
+ on remote tables. For example, if a remote table is actually a view,
+ any functions used in that view will be executed with the restricted
+ search path. It is recommended to schema-qualify all names in such
+ functions, or else attach <literal>SET search_path</literal> options
+ (see <xref linkend="sql-createfunction"/>) to such functions
+ to establish their expected search path environment.
+ </para>
+
+ <para>
+ <filename>postgres_fdw</filename> likewise establishes remote session settings
+ for various parameters:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ <xref linkend="guc-timezone"/> is set to <literal>UTC</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="guc-datestyle"/> is set to <literal>ISO</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="guc-intervalstyle"/> is set to <literal>postgres</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <xref linkend="guc-extra-float-digits"/> is set to <literal>3</literal> for remote
+ servers 9.0 and newer and is set to <literal>2</literal> for older versions
+ </para>
+ </listitem>
+ </itemizedlist>
+ These are less likely to be problematic than <varname>search_path</varname>, but
+ can be handled with function <literal>SET</literal> options if the need arises.
+ </para>
+
+ <para>
+ It is <emphasis>not</emphasis> recommended that you override this behavior by
+ changing the session-level settings of these parameters; that is likely
+ to cause <filename>postgres_fdw</filename> to malfunction.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Cross-Version Compatibility</title>
+
+ <para>
+ <filename>postgres_fdw</filename> can be used with remote servers dating back
+ to <productname>PostgreSQL</productname> 8.3. Read-only capability is available
+ back to 8.1. A limitation however is that <filename>postgres_fdw</filename>
+ generally assumes that immutable built-in functions and operators are
+ safe to send to the remote server for execution, if they appear in a
+ <literal>WHERE</literal> clause for a foreign table. Thus, a built-in
+ function that was added since the remote server's release might be sent
+ to it for execution, resulting in <quote>function does not exist</quote> or
+ a similar error. This type of failure can be worked around by
+ rewriting the query, for example by embedding the foreign table
+ reference in a sub-<literal>SELECT</literal> with <literal>OFFSET 0</literal> as an
+ optimization fence, and placing the problematic function or operator
+ outside the sub-<literal>SELECT</literal>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <variablelist>
+ <varlistentry id="guc-pgfdw-application-name" xreflabel="postgres_fdw.application_name">
+ <term>
+ <varname>postgres_fdw.application_name</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>postgres_fdw.application_name</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a value for <xref linkend="guc-application-name"/>
+ configuration parameter used when <filename>postgres_fdw</filename>
+ establishes a connection to a foreign server. This overrides
+ <varname>application_name</varname> option of the server object.
+ Note that change of this parameter doesn't affect any existing
+ connections until they are re-established.
+ </para>
+ <para>
+ <varname>postgres_fdw.application_name</varname> can be any string
+ of any length and contain even non-ASCII characters. However when
+ it's passed to and used as <varname>application_name</varname>
+ in a foreign server, note that it will be truncated to less than
+ <symbol>NAMEDATALEN</symbol> characters and anything other than
+ printable ASCII characters will be replaced with question
+ marks (<literal>?</literal>).
+ See <xref linkend="guc-application-name"/> for details.
+ </para>
+
+ <para>
+ <literal>%</literal> characters begin <quote>escape sequences</quote>
+ that are replaced with status information as outlined below.
+ Unrecognized escapes are ignored. Other characters are copied straight
+ to the application name. Note that it's not allowed to specify a
+ plus/minus sign or a numeric literal after the <literal>%</literal>
+ and before the option, for alignment and padding.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Escape</entry>
+ <entry>Effect</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>%a</literal></entry>
+ <entry>Application name on local server</entry>
+ </row>
+ <row>
+ <entry><literal>%c</literal></entry>
+ <entry>
+ Session ID on local server
+ (see <xref linkend="guc-log-line-prefix"/> for details)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>%C</literal></entry>
+ <entry>
+ Cluster name on local server
+ (see <xref linkend="guc-cluster-name"/> for details)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>%u</literal></entry>
+ <entry>User name on local server</entry>
+ </row>
+ <row>
+ <entry><literal>%d</literal></entry>
+ <entry>Database name on local server</entry>
+ </row>
+ <row>
+ <entry><literal>%p</literal></entry>
+ <entry>Process ID of backend on local server</entry>
+ </row>
+ <row>
+ <entry><literal>%%</literal></entry>
+ <entry>Literal %</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ For example, suppose user <literal>local_user</literal> establishes
+ a connection from database <literal>local_db</literal> to
+ <literal>foreign_db</literal> as user <literal>foreign_user</literal>,
+ the setting <literal>'db=%d, user=%u'</literal> is replaced with
+ <literal>'db=local_db, user=local_user'</literal>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>
+ Here is an example of creating a foreign table with
+ <literal>postgres_fdw</literal>. First install the extension:
+ </para>
+
+<programlisting>
+CREATE EXTENSION postgres_fdw;
+</programlisting>
+
+ <para>
+ Then create a foreign server using <xref linkend="sql-createserver"/>.
+ In this example we wish to connect to a <productname>PostgreSQL</productname> server
+ on host <literal>192.83.123.89</literal> listening on
+ port <literal>5432</literal>. The database to which the connection is made
+ is named <literal>foreign_db</literal> on the remote server:
+
+<programlisting>
+CREATE SERVER foreign_server
+ FOREIGN DATA WRAPPER postgres_fdw
+ OPTIONS (host '192.83.123.89', port '5432', dbname 'foreign_db');
+</programlisting>
+ </para>
+
+ <para>
+ A user mapping, defined with <xref linkend="sql-createusermapping"/>, is
+ needed as well to identify the role that will be used on the remote
+ server:
+
+<programlisting>
+CREATE USER MAPPING FOR local_user
+ SERVER foreign_server
+ OPTIONS (user 'foreign_user', password 'password');
+</programlisting>
+ </para>
+
+ <para>
+ Now it is possible to create a foreign table with
+ <xref linkend="sql-createforeigntable"/>. In this example we
+ wish to access the table named <structname>some_schema.some_table</structname>
+ on the remote server. The local name for it will
+ be <structname>foreign_table</structname>:
+
+<programlisting>
+CREATE FOREIGN TABLE foreign_table (
+ id integer NOT NULL,
+ data text
+)
+ SERVER foreign_server
+ OPTIONS (schema_name 'some_schema', table_name 'some_table');
+</programlisting>
+
+ It's essential that the data types and other properties of the columns
+ declared in <command>CREATE FOREIGN TABLE</command> match the actual remote table.
+ Column names must match as well, unless you attach <literal>column_name</literal>
+ options to the individual columns to show how they are named in the remote
+ table.
+ In many cases, use of <link linkend="sql-importforeignschema"><command>IMPORT FOREIGN SCHEMA</command></link> is
+ preferable to constructing foreign table definitions manually.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+ <para>
+ Shigeru Hanada <email>shigeru.hanada@gmail.com</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml
new file mode 100644
index 0000000..73439c0
--- /dev/null
+++ b/doc/src/sgml/postgres.sgml
@@ -0,0 +1,303 @@
+<!-- doc/src/sgml/postgres.sgml -->
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"
+[
+
+<!ENTITY % version SYSTEM "version.sgml">
+%version;
+<!ENTITY % filelist SYSTEM "filelist.sgml">
+%filelist;
+
+<!ENTITY reference SYSTEM "reference.sgml">
+
+<!--
+Zero-width space. Use this to allow line breaks at desirable places in
+table cells, examples, etc. without causing an unwanted space when the
+break is not needed in a wider output rendering.
+-->
+<!ENTITY zwsp "&#x200B;">
+
+]>
+
+<book id="postgres">
+ <title>PostgreSQL &version; Documentation</title>
+
+ <bookinfo>
+ <corpauthor>The PostgreSQL Global Development Group</corpauthor>
+ <productname>PostgreSQL</productname>
+ <productnumber>&version;</productnumber>
+ &legal;
+ </bookinfo>
+
+ &intro;
+
+ <part id="tutorial">
+ <title>Tutorial</title>
+
+ <partintro>
+ <para>
+ Welcome to the <productname>PostgreSQL</productname> Tutorial. The
+ following few chapters are intended to give a simple introduction
+ to <productname>PostgreSQL</productname>, relational database
+ concepts, and the SQL language to those who are new to any one of
+ these aspects. We only assume some general knowledge about how to
+ use computers. No particular Unix or programming experience is
+ required. This part is mainly intended to give you some hands-on
+ experience with important aspects of the
+ <productname>PostgreSQL</productname> system. It makes no attempt
+ to be a complete or thorough treatment of the topics it covers.
+ </para>
+
+ <para>
+ After you have worked through this tutorial you might want to move
+ on to reading <xref linkend="sql"/> to gain a more formal knowledge
+ of the SQL language, or <xref linkend="client-interfaces"/> for
+ information about developing applications for
+ <productname>PostgreSQL</productname>. Those who set up and
+ manage their own server should also read <xref linkend="admin"/>.
+ </para>
+ </partintro>
+
+ &start;
+ &query;
+ &advanced;
+
+ </part>
+
+ <part id="sql">
+ <title>The SQL Language</title>
+
+ <partintro>
+ <para>
+ This part describes the use of the <acronym>SQL</acronym> language
+ in <productname>PostgreSQL</productname>. We start with
+ describing the general syntax of <acronym>SQL</acronym>, then
+ explain how to create the structures to hold data, how to populate
+ the database, and how to query it. The middle part lists the
+ available data types and functions for use in
+ <acronym>SQL</acronym> commands. The rest treats several
+ aspects that are important for tuning a database for optimal
+ performance.
+ </para>
+
+ <para>
+ The information in this part is arranged so that a novice user can
+ follow it start to end to gain a full understanding of the topics
+ without having to refer forward too many times. The chapters are
+ intended to be self-contained, so that advanced users can read the
+ chapters individually as they choose. The information in this
+ part is presented in a narrative fashion in topical units.
+ Readers looking for a complete description of a particular command
+ should see <xref linkend="reference"/>.
+ </para>
+
+ <para>
+ Readers of this part should know how to connect to a
+ <productname>PostgreSQL</productname> database and issue
+ <acronym>SQL</acronym> commands. Readers that are unfamiliar with
+ these issues are encouraged to read <xref linkend="tutorial"/>
+ first. <acronym>SQL</acronym> commands are typically entered
+ using the <productname>PostgreSQL</productname> interactive terminal
+ <application>psql</application>, but other programs that have
+ similar functionality can be used as well.
+ </para>
+ </partintro>
+
+ &syntax;
+ &ddl;
+ &dml;
+ &queries;
+ &datatype;
+ &func;
+ &typeconv;
+ &indices;
+ &textsearch;
+ &mvcc;
+ &perform;
+ &parallel;
+
+ </part>
+
+ <part id="admin">
+ <title>Server Administration</title>
+
+ <partintro>
+ <para>
+ This part covers topics that are of interest to a
+ <productname>PostgreSQL</productname> database administrator. This includes
+ installation of the software, set up and configuration of the
+ server, management of users and databases, and maintenance tasks.
+ Anyone who runs a <productname>PostgreSQL</productname> server, even for
+ personal use, but especially in production, should be familiar
+ with the topics covered in this part.
+ </para>
+
+ <para>
+ The information in this part is arranged approximately in the
+ order in which a new user should read it. But the chapters are
+ self-contained and can be read individually as desired. The
+ information in this part is presented in a narrative fashion in
+ topical units. Readers looking for a complete description of a
+ particular command should see <xref linkend="reference"/>.
+ </para>
+
+ <para>
+ The first few chapters are written so they can be understood
+ without prerequisite knowledge, so new users who need to set
+ up their own server can begin their exploration with this part.
+ The rest of this part is about tuning and management; that material
+ assumes that the reader is familiar with the general use of
+ the <productname>PostgreSQL</productname> database system. Readers are
+ encouraged to look at <xref linkend="tutorial"/> and <xref
+ linkend="sql"/> for additional information.
+ </para>
+ </partintro>
+
+ &installbin;
+ &installation;
+ &installw;
+ &runtime;
+ &config;
+ &client-auth;
+ &user-manag;
+ &manage-ag;
+ &charset;
+ &maintenance;
+ &backup;
+ &high-availability;
+ &monitoring;
+ &diskusage;
+ &wal;
+ &logical-replication;
+ &jit;
+ &regress;
+
+ </part>
+
+ <part id="client-interfaces">
+ <title>Client Interfaces</title>
+
+ <partintro>
+ <para>
+ This part describes the client programming interfaces distributed
+ with <productname>PostgreSQL</productname>. Each of these chapters can be
+ read independently. Note that there are many other programming
+ interfaces for client programs that are distributed separately and
+ contain their own documentation (<xref linkend="external-projects"/>
+ lists some of the more popular ones). Readers of this part should be
+ familiar with using <acronym>SQL</acronym> commands to manipulate
+ and query the database (see <xref linkend="sql"/>) and of course
+ with the programming language that the interface uses.
+ </para>
+ </partintro>
+
+ &libpq;
+ &lobj;
+ &ecpg;
+ &infoschema;
+
+ </part>
+
+ <part id="server-programming">
+ <title>Server Programming</title>
+
+ <partintro>
+ <para>
+ This part is about extending the server functionality with
+ user-defined functions, data types, triggers, etc. These are
+ advanced topics which should probably be approached only after all
+ the other user documentation about <productname>PostgreSQL</productname> has
+ been understood. Later chapters in this part describe the server-side
+ programming languages available in the
+ <productname>PostgreSQL</productname> distribution as well as
+ general issues concerning server-side programming languages. It
+ is essential to read at least the earlier sections of <xref
+ linkend="extend"/> (covering functions) before diving into the
+ material about server-side programming languages.
+ </para>
+ </partintro>
+
+ &extend;
+ &trigger;
+ &event-trigger;
+ &rules;
+
+ &xplang;
+ &plsql;
+ &pltcl;
+ &plperl;
+ &plpython;
+
+ &spi;
+ &bgworker;
+ &logicaldecoding;
+ &replication-origins;
+ &archive-modules;
+
+ </part>
+
+ &reference;
+
+ <part id="internals">
+ <title>Internals</title>
+
+ <partintro>
+ <para>
+ This part contains assorted information that might be of use to
+ <productname>PostgreSQL</productname> developers.
+ </para>
+ </partintro>
+
+ &arch-dev;
+ &catalogs;
+ &system-views;
+ &protocol;
+ &sources;
+ &nls;
+ &plhandler;
+ &fdwhandler;
+ &tablesample-method;
+ &custom-scan;
+ &geqo;
+ &tableam;
+ &indexam;
+ &generic-wal;
+ &custom-rmgr;
+ &btree;
+ &gist;
+ &spgist;
+ &gin;
+ &brin;
+ &hash;
+ &storage;
+ &bki;
+ &planstats;
+ &backup-manifest;
+
+ </part>
+
+ <part id="appendixes">
+ <title>Appendixes</title>
+
+ &errcodes;
+ &datetime;
+ &keywords;
+ &features;
+ &release;
+ &contrib;
+ &external-projects;
+ &sourcerepo;
+ &docguide;
+ &limits;
+ &acronyms;
+ &glossary;
+ &color;
+ &obsolete;
+
+ </part>
+
+ &biblio;
+ <index id="bookindex"></index>
+
+</book>
diff --git a/doc/src/sgml/problems.sgml b/doc/src/sgml/problems.sgml
new file mode 100644
index 0000000..cf43262
--- /dev/null
+++ b/doc/src/sgml/problems.sgml
@@ -0,0 +1,362 @@
+<!-- doc/src/sgml/problems.sgml -->
+
+<sect1 id="bug-reporting">
+ <title>Bug Reporting Guidelines</title>
+
+ <para>
+ When you find a bug in <productname>PostgreSQL</productname> we want to
+ hear about it. Your bug reports play an important part in making
+ <productname>PostgreSQL</productname> more reliable because even the utmost
+ care cannot guarantee that every part of
+ <productname>PostgreSQL</productname>
+ will work on every platform under every circumstance.
+ </para>
+
+ <para>
+ The following suggestions are intended to assist you in forming bug reports
+ that can be handled in an effective fashion. No one is required to follow
+ them but doing so tends to be to everyone's advantage.
+ </para>
+
+ <para>
+ We cannot promise to fix every bug right away. If the bug is obvious, critical,
+ or affects a lot of users, chances are good that someone will look into it. It
+ could also happen that we tell you to update to a newer version to see if the
+ bug happens there. Or we might decide that the bug
+ cannot be fixed before some major rewrite we might be planning is done. Or
+ perhaps it is simply too hard and there are more important things on the agenda.
+ If you need help immediately, consider obtaining a commercial support contract.
+ </para>
+
+ <sect2>
+ <title>Identifying Bugs</title>
+
+ <para>
+ Before you report a bug, please read and re-read the
+ documentation to verify that you can really do whatever it is you are
+ trying. If it is not clear from the documentation whether you can do
+ something or not, please report that too; it is a bug in the documentation.
+ If it turns out that a program does something different from what the
+ documentation says, that is a bug. That might include, but is not limited to,
+ the following circumstances:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A program terminates with a fatal signal or an operating system
+ error message that would point to a problem in the program. (A
+ counterexample might be a <quote>disk full</quote> message,
+ since you have to fix that yourself.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A program produces the wrong output for any given input.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A program refuses to accept valid input (as defined in the documentation).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A program accepts invalid input without a notice or error message.
+ But keep in mind that your idea of invalid input might be our idea of
+ an extension or compatibility with traditional practice.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> fails to compile, build, or
+ install according to the instructions on supported platforms.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Here <quote>program</quote> refers to any executable, not only the backend process.
+ </para>
+
+ <para>
+ Being slow or resource-hogging is not necessarily a bug. Read the
+ documentation or ask on one of the mailing lists for help in tuning your
+ applications. Failing to comply to the <acronym>SQL</acronym> standard is
+ not necessarily a bug either, unless compliance for the
+ specific feature is explicitly claimed.
+ </para>
+
+ <para>
+ Before you continue, check on the TODO list and in the FAQ to see if your bug is
+ already known. If you cannot decode the information on the TODO list, report your
+ problem. The least we can do is make the TODO list clearer.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>What to Report</title>
+
+ <para>
+ The most important thing to remember about bug reporting is to state all
+ the facts and only facts. Do not speculate what you think went wrong, what
+ <quote>it seemed to do</quote>, or which part of the program has a fault.
+ If you are not familiar with the implementation you would probably guess
+ wrong and not help us a bit. And even if you are, educated explanations are
+ a great supplement to but no substitute for facts. If we are going to fix
+ the bug we still have to see it happen for ourselves first.
+ Reporting the bare facts
+ is relatively straightforward (you can probably copy and paste them from the
+ screen) but all too often important details are left out because someone
+ thought it does not matter or the report would be understood
+ anyway.
+ </para>
+
+ <para>
+ The following items should be contained in every bug report:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The exact sequence of steps <emphasis>from program
+ start-up</emphasis> necessary to reproduce the problem. This
+ should be self-contained; it is not enough to send in a bare
+ <command>SELECT</command> statement without the preceding
+ <command>CREATE TABLE</command> and <command>INSERT</command>
+ statements, if the output should depend on the data in the
+ tables. We do not have the time to reverse-engineer your
+ database schema, and if we are supposed to make up our own data
+ we would probably miss the problem.
+ </para>
+
+ <para>
+ The best format for a test case for SQL-related problems is a
+ file that can be run through the <application>psql</application>
+ frontend that shows the problem. (Be sure to not have anything
+ in your <filename>~/.psqlrc</filename> start-up file.) An easy
+ way to create this file is to use <application>pg_dump</application>
+ to dump out the table declarations and data needed to set the
+ scene, then add the problem query. You are encouraged to
+ minimize the size of your example, but this is not absolutely
+ necessary. If the bug is reproducible, we will find it either
+ way.
+ </para>
+
+ <para>
+ If your application uses some other client interface, such as <application>PHP</application>, then
+ please try to isolate the offending queries. We will probably not set up a
+ web server to reproduce your problem. In any case remember to provide
+ the exact input files; do not guess that the problem happens for
+ <quote>large files</quote> or <quote>midsize databases</quote>, etc. since this
+ information is too inexact to be of use.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The output you got. Please do not say that it <quote>didn't work</quote> or
+ <quote>crashed</quote>. If there is an error message,
+ show it, even if you do not understand it. If the program terminates with
+ an operating system error, say which. If nothing at all happens, say so.
+ Even if the result of your test case is a program crash or otherwise obvious
+ it might not happen on our platform. The easiest thing is to copy the output
+ from the terminal, if possible.
+ </para>
+ <note>
+ <para>
+ If you are reporting an error message, please obtain the most verbose
+ form of the message. In <application>psql</application>, say <literal>\set
+ VERBOSITY verbose</literal> beforehand. If you are extracting the message
+ from the server log, set the run-time parameter
+ <xref linkend="guc-log-error-verbosity"/> to <literal>verbose</literal> so that all
+ details are logged.
+ </para>
+ </note>
+ <note>
+ <para>
+ In case of fatal errors, the error message reported by the client might
+ not contain all the information available. Please also look at the
+ log output of the database server. If you do not keep your server's log
+ output, this would be a good time to start doing so.
+ </para>
+ </note>
+ </listitem>
+
+ <listitem>
+ <para>
+ The output you expected is very important to state. If you just write
+ <quote>This command gives me that output.</quote> or <quote>This is not
+ what I expected.</quote>, we might run it ourselves, scan the output, and
+ think it looks OK and is exactly what we expected. We should not have to
+ spend the time to decode the exact semantics behind your commands.
+ Especially refrain from merely saying that <quote>This is not what SQL says/Oracle
+ does.</quote> Digging out the correct behavior from <acronym>SQL</acronym>
+ is not a fun undertaking, nor do we all know how all the other relational
+ databases out there behave. (If your problem is a program crash, you can
+ obviously omit this item.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Any command line options and other start-up options, including
+ any relevant environment variables or configuration files that
+ you changed from the default. Again, please provide exact
+ information. If you are using a prepackaged distribution that
+ starts the database server at boot time, you should try to find
+ out how that is done.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Anything you did at all differently from the installation
+ instructions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <productname>PostgreSQL</productname> version. You can run the command
+ <literal>SELECT version();</literal> to
+ find out the version of the server you are connected to. Most executable
+ programs also support a <option>--version</option> option; at least
+ <literal>postgres --version</literal> and <literal>psql --version</literal>
+ should work.
+ If the function or the options do not exist then your version is
+ more than old enough to warrant an upgrade.
+ If you run a prepackaged version, such as RPMs, say so, including any
+ subversion the package might have. If you are talking about a Git
+ snapshot, mention that, including the commit hash.
+ </para>
+
+ <para>
+ If your version is older than &version; we will almost certainly
+ tell you to upgrade. There are many bug fixes and improvements
+ in each new release, so it is quite possible that a bug you have
+ encountered in an older release of <productname>PostgreSQL</productname>
+ has already been fixed. We can only provide limited support for
+ sites using older releases of <productname>PostgreSQL</productname>; if you
+ require more than we can provide, consider acquiring a
+ commercial support contract.
+ </para>
+ <para>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Platform information. This includes the kernel name and version,
+ C library, processor, memory information, and so on. In most
+ cases it is sufficient to report the vendor and version, but do
+ not assume everyone knows what exactly <quote>Debian</quote>
+ contains or that everyone runs on x86_64. If you have
+ installation problems then information about the toolchain on
+ your machine (compiler, <application>make</application>, and so
+ on) is also necessary.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Do not be afraid if your bug report becomes rather lengthy. That is a fact of life.
+ It is better to report everything the first time than us having to squeeze the
+ facts out of you. On the other hand, if your input files are huge, it is
+ fair to ask first whether somebody is interested in looking into it. Here is
+ an <ulink url="https://www.chiark.greenend.org.uk/~sgtatham/bugs.html">article</ulink>
+ that outlines some more tips on reporting bugs.
+ </para>
+
+ <para>
+ Do not spend all your time to figure out which changes in the input make
+ the problem go away. This will probably not help solving it. If it turns
+ out that the bug cannot be fixed right away, you will still have time to
+ find and share your work-around. Also, once again, do not waste your time
+ guessing why the bug exists. We will find that out soon enough.
+ </para>
+
+ <para>
+ When writing a bug report, please avoid confusing terminology.
+ The software package in total is called <quote>PostgreSQL</quote>,
+ sometimes <quote>Postgres</quote> for short. If you
+ are specifically talking about the backend process, mention that, do not
+ just say <quote>PostgreSQL crashes</quote>. A crash of a single
+ backend process is quite different from crash of the parent
+ <quote>postgres</quote> process; please don't say <quote>the server
+ crashed</quote> when you mean a single backend process went down, nor vice versa.
+ Also, client programs such as the interactive frontend <quote><application>psql</application></quote>
+ are completely separate from the backend. Please try to be specific
+ about whether the problem is on the client or server side.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Where to Report Bugs</title>
+
+ <para>
+ In general, send bug reports to the bug report mailing list at
+ <email>pgsql-bugs@lists.postgresql.org</email>.
+ You are requested to use a descriptive subject for your email
+ message, perhaps parts of the error message.
+ </para>
+
+ <para>
+ Another method is to fill in the bug report web-form available
+ at the project's
+ <ulink url="https://www.postgresql.org/">web site</ulink>.
+ Entering a bug report this way causes it to be mailed to the
+ <email>pgsql-bugs@lists.postgresql.org</email> mailing list.
+ </para>
+
+ <para>
+ If your bug report has security implications and you'd prefer that it
+ not become immediately visible in public archives, don't send it to
+ <literal>pgsql-bugs</literal>. Security issues can be
+ reported privately to <email>security@postgresql.org</email>.
+ </para>
+
+ <para>
+ Do not send bug reports to any of the user mailing lists, such as
+ <email>pgsql-sql@lists.postgresql.org</email> or
+ <email>pgsql-general@lists.postgresql.org</email>.
+ These mailing lists are for answering
+ user questions, and their subscribers normally do not wish to receive
+ bug reports. More importantly, they are unlikely to fix them.
+ </para>
+
+ <para>
+ Also, please do <emphasis>not</emphasis> send reports to
+ the developers' mailing list <email>pgsql-hackers@lists.postgresql.org</email>.
+ This list is for discussing the
+ development of <productname>PostgreSQL</productname>, and it would be nice
+ if we could keep the bug reports separate. We might choose to take up a
+ discussion about your bug report on <literal>pgsql-hackers</literal>,
+ if the problem needs more review.
+ </para>
+
+ <para>
+ If you have a problem with the documentation, the best place to report it
+ is the documentation mailing list <email>pgsql-docs@lists.postgresql.org</email>.
+ Please be specific about what part of the documentation you are unhappy
+ with.
+ </para>
+
+ <para>
+ If your bug is a portability problem on a non-supported platform,
+ send mail to <email>pgsql-hackers@lists.postgresql.org</email>,
+ so we (and you) can work on
+ porting <productname>PostgreSQL</productname> to your platform.
+ </para>
+
+ <note>
+ <para>
+ Due to the unfortunate amount of spam going around, all of the above
+ lists will be moderated unless you are subscribed. That means there
+ will be some delay before the email is delivered. If you wish to subscribe
+ to the lists, please visit
+ <ulink url="https://lists.postgresql.org/"></ulink> for instructions.
+ </para>
+ </note>
+ </sect2>
+</sect1>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
new file mode 100644
index 0000000..405046f
--- /dev/null
+++ b/doc/src/sgml/protocol.sgml
@@ -0,0 +1,7455 @@
+<!-- doc/src/sgml/protocol.sgml -->
+
+<chapter id="protocol">
+ <title>Frontend/Backend Protocol</title>
+
+ <indexterm zone="protocol">
+ <primary>protocol</primary>
+ <secondary>frontend-backend</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> uses a message-based protocol
+ for communication between frontends and backends (clients and servers).
+ The protocol is supported over <acronym>TCP/IP</acronym> and also over
+ Unix-domain sockets. Port number 5432 has been registered with IANA as
+ the customary TCP port number for servers supporting this protocol, but
+ in practice any non-privileged port number can be used.
+ </para>
+
+ <para>
+ This document describes version 3.0 of the protocol, implemented in
+ <productname>PostgreSQL</productname> 7.4 and later. For descriptions
+ of the earlier protocol versions, see previous releases of the
+ <productname>PostgreSQL</productname> documentation. A single server
+ can support multiple protocol versions. The initial startup-request
+ message tells the server which protocol version the client is attempting to
+ use. If the major version requested by the client is not supported by
+ the server, the connection will be rejected (for example, this would occur
+ if the client requested protocol version 4.0, which does not exist as of
+ this writing). If the minor version requested by the client is not
+ supported by the server (e.g., the client requests version 3.1, but the
+ server supports only 3.0), the server may either reject the connection or
+ may respond with a NegotiateProtocolVersion message containing the highest
+ minor protocol version which it supports. The client may then choose either
+ to continue with the connection using the specified protocol version or
+ to abort the connection.
+ </para>
+
+ <para>
+ In order to serve multiple clients efficiently, the server launches
+ a new <quote>backend</quote> process for each client.
+ In the current implementation, a new child
+ process is created immediately after an incoming connection is detected.
+ This is transparent to the protocol, however. For purposes of the
+ protocol, the terms <quote>backend</quote> and <quote>server</quote> are
+ interchangeable; likewise <quote>frontend</quote> and <quote>client</quote>
+ are interchangeable.
+ </para>
+
+ <sect1 id="protocol-overview">
+ <title>Overview</title>
+
+ <para>
+ The protocol has separate phases for startup and normal operation.
+ In the startup phase, the frontend opens a connection to the server
+ and authenticates itself to the satisfaction of the server. (This might
+ involve a single message, or multiple messages depending on the
+ authentication method being used.) If all goes well, the server then sends
+ status information to the frontend, and finally enters normal operation.
+ Except for the initial startup-request message, this part of the
+ protocol is driven by the server.
+ </para>
+
+ <para>
+ During normal operation, the frontend sends queries and
+ other commands to the backend, and the backend sends back query results
+ and other responses. There are a few cases (such as <command>NOTIFY</command>)
+ wherein the
+ backend will send unsolicited messages, but for the most part this portion
+ of a session is driven by frontend requests.
+ </para>
+
+ <para>
+ Termination of the session is normally by frontend choice, but can be
+ forced by the backend in certain cases. In any case, when the backend
+ closes the connection, it will roll back any open (incomplete) transaction
+ before exiting.
+ </para>
+
+ <para>
+ Within normal operation, SQL commands can be executed through either of
+ two sub-protocols. In the <quote>simple query</quote> protocol, the frontend
+ just sends a textual query string, which is parsed and immediately
+ executed by the backend. In the <quote>extended query</quote> protocol,
+ processing of queries is separated into multiple steps: parsing,
+ binding of parameter values, and execution. This offers flexibility
+ and performance benefits, at the cost of extra complexity.
+ </para>
+
+ <para>
+ Normal operation has additional sub-protocols for special operations
+ such as <command>COPY</command>.
+ </para>
+
+ <sect2 id="protocol-message-concepts">
+ <title>Messaging Overview</title>
+
+ <para>
+ All communication is through a stream of messages. The first byte of a
+ message identifies the message type, and the next four bytes specify the
+ length of the rest of the message (this length count includes itself, but
+ not the message-type byte). The remaining contents of the message are
+ determined by the message type. For historical reasons, the very first
+ message sent by the client (the startup message) has no initial
+ message-type byte.
+ </para>
+
+ <para>
+ To avoid losing synchronization with the message stream, both servers and
+ clients typically read an entire message into a buffer (using the byte
+ count) before attempting to process its contents. This allows easy
+ recovery if an error is detected while processing the contents. In
+ extreme situations (such as not having enough memory to buffer the
+ message), the receiver can use the byte count to determine how much
+ input to skip before it resumes reading messages.
+ </para>
+
+ <para>
+ Conversely, both servers and clients must take care never to send an
+ incomplete message. This is commonly done by marshaling the entire message
+ in a buffer before beginning to send it. If a communications failure
+ occurs partway through sending or receiving a message, the only sensible
+ response is to abandon the connection, since there is little hope of
+ recovering message-boundary synchronization.
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-query-concepts">
+ <title>Extended Query Overview</title>
+
+ <para>
+ In the extended-query protocol, execution of SQL commands is divided
+ into multiple steps. The state retained between steps is represented
+ by two types of objects: <firstterm>prepared statements</firstterm> and
+ <firstterm>portals</firstterm>. A prepared statement represents the result of
+ parsing and semantic analysis of a textual query string.
+ A prepared statement is not in itself ready to execute, because it might
+ lack specific values for <firstterm>parameters</firstterm>. A portal represents
+ a ready-to-execute or already-partially-executed statement, with any
+ missing parameter values filled in. (For <command>SELECT</command> statements,
+ a portal is equivalent to an open cursor, but we choose to use a different
+ term since cursors don't handle non-<command>SELECT</command> statements.)
+ </para>
+
+ <para>
+ The overall execution cycle consists of a <firstterm>parse</firstterm> step,
+ which creates a prepared statement from a textual query string; a
+ <firstterm>bind</firstterm> step, which creates a portal given a prepared
+ statement and values for any needed parameters; and an
+ <firstterm>execute</firstterm> step that runs a portal's query. In the case of
+ a query that returns rows (<command>SELECT</command>, <command>SHOW</command>, etc.),
+ the execute step can be told to fetch only
+ a limited number of rows, so that multiple execute steps might be needed
+ to complete the operation.
+ </para>
+
+ <para>
+ The backend can keep track of multiple prepared statements and portals
+ (but note that these exist only within a session, and are never shared
+ across sessions). Existing prepared statements and portals are
+ referenced by names assigned when they were created. In addition,
+ an <quote>unnamed</quote> prepared statement and portal exist. Although these
+ behave largely the same as named objects, operations on them are optimized
+ for the case of executing a query only once and then discarding it,
+ whereas operations on named objects are optimized on the expectation
+ of multiple uses.
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-format-codes">
+ <title>Formats and Format Codes</title>
+
+ <para>
+ Data of a particular data type might be transmitted in any of several
+ different <firstterm>formats</firstterm>. As of <productname>PostgreSQL</productname> 7.4
+ the only supported formats are <quote>text</quote> and <quote>binary</quote>,
+ but the protocol makes provision for future extensions. The desired
+ format for any value is specified by a <firstterm>format code</firstterm>.
+ Clients can specify a format code for each transmitted parameter value
+ and for each column of a query result. Text has format code zero,
+ binary has format code one, and all other format codes are reserved
+ for future definition.
+ </para>
+
+ <para>
+ The text representation of values is whatever strings are produced
+ and accepted by the input/output conversion functions for the
+ particular data type. In the transmitted representation, there is
+ no trailing null character; the frontend must add one to received
+ values if it wants to process them as C strings.
+ (The text format does not allow embedded nulls, by the way.)
+ </para>
+
+ <para>
+ Binary representations for integers use network byte order (most
+ significant byte first). For other data types consult the documentation
+ or source code to learn about the binary representation. Keep in mind
+ that binary representations for complex data types might change across
+ server versions; the text format is usually the more portable choice.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="protocol-flow">
+ <title>Message Flow</title>
+
+ <para>
+ This section describes the message flow and the semantics of each
+ message type. (Details of the exact representation of each message
+ appear in <xref linkend="protocol-message-formats"/>.) There are
+ several different sub-protocols depending on the state of the
+ connection: start-up, query, function call,
+ <command>COPY</command>, and termination. There are also special
+ provisions for asynchronous operations (including notification
+ responses and command cancellation), which can occur at any time
+ after the start-up phase.
+ </para>
+
+ <sect2>
+ <title>Start-up</title>
+
+ <para>
+ To begin a session, a frontend opens a connection to the server and sends
+ a startup message. This message includes the names of the user and of the
+ database the user wants to connect to; it also identifies the particular
+ protocol version to be used. (Optionally, the startup message can include
+ additional settings for run-time parameters.)
+ The server then uses this information and
+ the contents of its configuration files (such as
+ <filename>pg_hba.conf</filename>) to determine
+ whether the connection is provisionally acceptable, and what additional
+ authentication is required (if any).
+ </para>
+
+ <para>
+ The server then sends an appropriate authentication request message,
+ to which the frontend must reply with an appropriate authentication
+ response message (such as a password).
+ For all authentication methods except GSSAPI, SSPI and SASL, there is at
+ most one request and one response. In some methods, no response
+ at all is needed from the frontend, and so no authentication request
+ occurs. For GSSAPI, SSPI and SASL, multiple exchanges of packets may be
+ needed to complete the authentication.
+ </para>
+
+ <para>
+ The authentication cycle ends with the server either rejecting the
+ connection attempt (ErrorResponse), or sending AuthenticationOk.
+ </para>
+
+ <para>
+ The possible messages from the server in this phase are:
+
+ <variablelist>
+ <varlistentry>
+ <term>ErrorResponse</term>
+ <listitem>
+ <para>
+ The connection attempt has been rejected.
+ The server then immediately closes the connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationOk</term>
+ <listitem>
+ <para>
+ The authentication exchange is successfully completed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationKerberosV5</term>
+ <listitem>
+ <para>
+ The frontend must now take part in a Kerberos V5
+ authentication dialog (not described here, part of the
+ Kerberos specification) with the server. If this is
+ successful, the server responds with an AuthenticationOk,
+ otherwise it responds with an ErrorResponse. This is no
+ longer supported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationCleartextPassword</term>
+ <listitem>
+ <para>
+ The frontend must now send a PasswordMessage containing the
+ password in clear-text form. If
+ this is the correct password, the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationMD5Password</term>
+ <listitem>
+ <para>
+ The frontend must now send a PasswordMessage containing the
+ password (with user name) encrypted via MD5, then encrypted
+ again using the 4-byte random salt specified in the
+ AuthenticationMD5Password message. If this is the correct
+ password, the server responds with an AuthenticationOk,
+ otherwise it responds with an ErrorResponse. The actual
+ PasswordMessage can be computed in SQL as <literal>concat('md5',
+ md5(concat(md5(concat(password, username)), random-salt)))</literal>.
+ (Keep in mind the <function>md5()</function> function returns its
+ result as a hex string.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSCMCredential</term>
+ <listitem>
+ <para>
+ This response is only possible for local Unix-domain connections
+ on platforms that support SCM credential messages. The frontend
+ must issue an SCM credential message and then send a single data
+ byte. (The contents of the data byte are uninteresting; it's
+ only used to ensure that the server waits long enough to receive
+ the credential message.) If the credential is acceptable,
+ the server responds with an
+ AuthenticationOk, otherwise it responds with an ErrorResponse.
+ (This message type is only issued by pre-9.1 servers. It may
+ eventually be removed from the protocol specification.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationGSS</term>
+ <listitem>
+ <para>
+ The frontend must now initiate a GSSAPI negotiation. The frontend
+ will send a GSSResponse message with the first part of the GSSAPI
+ data stream in response to this. If further messages are needed,
+ the server will respond with AuthenticationGSSContinue.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSSPI</term>
+ <listitem>
+ <para>
+ The frontend must now initiate an SSPI negotiation. The frontend
+ will send a GSSResponse with the first part of the SSPI
+ data stream in response to this. If further messages are needed,
+ the server will respond with AuthenticationGSSContinue.
+ </para>
+ </listitem>
+
+ </varlistentry>
+ <varlistentry>
+ <term>AuthenticationGSSContinue</term>
+ <listitem>
+ <para>
+ This message contains the response data from the previous step
+ of GSSAPI or SSPI negotiation (AuthenticationGSS, AuthenticationSSPI
+ or a previous AuthenticationGSSContinue). If the GSSAPI
+ or SSPI data in this message
+ indicates more data is needed to complete the authentication,
+ the frontend must send that data as another GSSResponse message. If
+ GSSAPI or SSPI authentication is completed by this message, the server
+ will next send AuthenticationOk to indicate successful authentication
+ or ErrorResponse to indicate failure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSASL</term>
+ <listitem>
+ <para>
+ The frontend must now initiate a SASL negotiation, using one of the
+ SASL mechanisms listed in the message. The frontend will send a
+ SASLInitialResponse with the name of the selected mechanism, and the
+ first part of the SASL data stream in response to this. If further
+ messages are needed, the server will respond with
+ AuthenticationSASLContinue. See <xref linkend="sasl-authentication"/>
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSASLContinue</term>
+ <listitem>
+ <para>
+ This message contains challenge data from the previous step of SASL
+ negotiation (AuthenticationSASL, or a previous
+ AuthenticationSASLContinue). The frontend must respond with a
+ SASLResponse message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>AuthenticationSASLFinal</term>
+ <listitem>
+ <para>
+ SASL authentication has completed with additional mechanism-specific
+ data for the client. The server will next send AuthenticationOk to
+ indicate successful authentication, or an ErrorResponse to indicate
+ failure. This message is sent only if the SASL mechanism specifies
+ additional data to be sent from server to client at completion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NegotiateProtocolVersion</term>
+ <listitem>
+ <para>
+ The server does not support the minor protocol version requested
+ by the client, but does support an earlier version of the protocol;
+ this message indicates the highest supported minor version. This
+ message will also be sent if the client requested unsupported protocol
+ options (i.e., beginning with <literal>_pq_.</literal>) in the
+ startup packet. This message will be followed by an ErrorResponse or
+ a message indicating the success or failure of authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ If the frontend does not support the authentication method
+ requested by the server, then it should immediately close the
+ connection.
+ </para>
+
+ <para>
+ After having received AuthenticationOk, the frontend must wait
+ for further messages from the server. In this phase a backend process
+ is being started, and the frontend is just an interested bystander.
+ It is still possible for the startup attempt
+ to fail (ErrorResponse) or the server to decline support for the requested
+ minor protocol version (NegotiateProtocolVersion), but in the normal case
+ the backend will send some ParameterStatus messages, BackendKeyData, and
+ finally ReadyForQuery.
+ </para>
+
+ <para>
+ During this phase the backend will attempt to apply any additional
+ run-time parameter settings that were given in the startup message.
+ If successful, these values become session defaults. An error causes
+ ErrorResponse and exit.
+ </para>
+
+ <para>
+ The possible messages from the backend in this phase are:
+
+ <variablelist>
+ <varlistentry>
+ <term>BackendKeyData</term>
+ <listitem>
+ <para>
+ This message provides secret-key data that the frontend must
+ save if it wants to be able to issue cancel requests later.
+ The frontend should not respond to this message, but should
+ continue listening for a ReadyForQuery message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ParameterStatus</term>
+ <listitem>
+ <para>
+ This message informs the frontend about the current (initial)
+ setting of backend parameters, such as <xref
+ linkend="guc-client-encoding"/> or <xref linkend="guc-datestyle"/>.
+ The frontend can ignore this message, or record the settings
+ for its future use; see <xref linkend="protocol-async"/> for
+ more details. The frontend should not respond to this
+ message, but should continue listening for a ReadyForQuery
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ReadyForQuery</term>
+ <listitem>
+ <para>
+ Start-up is completed. The frontend can now issue commands.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ErrorResponse</term>
+ <listitem>
+ <para>
+ Start-up failed. The connection is closed after sending this
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NoticeResponse</term>
+ <listitem>
+ <para>
+ A warning message has been issued. The frontend should
+ display the message but continue listening for ReadyForQuery
+ or ErrorResponse.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The ReadyForQuery message is the same one that the backend will
+ issue after each command cycle. Depending on the coding needs of
+ the frontend, it is reasonable to consider ReadyForQuery as
+ starting a command cycle, or to consider ReadyForQuery as ending the
+ start-up phase and each subsequent command cycle.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Simple Query</title>
+
+ <para>
+ A simple query cycle is initiated by the frontend sending a Query message
+ to the backend. The message includes an SQL command (or commands)
+ expressed as a text string.
+ The backend then sends one or more response
+ messages depending on the contents of the query command string,
+ and finally a ReadyForQuery response message. ReadyForQuery
+ informs the frontend that it can safely send a new command.
+ (It is not actually necessary for the frontend to wait for
+ ReadyForQuery before issuing another command, but the frontend must
+ then take responsibility for figuring out what happens if the earlier
+ command fails and already-issued later commands succeed.)
+ </para>
+
+ <para>
+ The possible response messages from the backend are:
+
+ <variablelist>
+ <varlistentry>
+ <term>CommandComplete</term>
+ <listitem>
+ <para>
+ An SQL command completed normally.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>CopyInResponse</term>
+ <listitem>
+ <para>
+ The backend is ready to copy data from the frontend to a
+ table; see <xref linkend="protocol-copy"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>CopyOutResponse</term>
+ <listitem>
+ <para>
+ The backend is ready to copy data from a table to the
+ frontend; see <xref linkend="protocol-copy"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>RowDescription</term>
+ <listitem>
+ <para>
+ Indicates that rows are about to be returned in response to
+ a <command>SELECT</command>, <command>FETCH</command>, etc. query.
+ The contents of this message describe the column layout of the rows.
+ This will be followed by a DataRow message for each row being returned
+ to the frontend.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>DataRow</term>
+ <listitem>
+ <para>
+ One of the set of rows returned by
+ a <command>SELECT</command>, <command>FETCH</command>, etc. query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>EmptyQueryResponse</term>
+ <listitem>
+ <para>
+ An empty query string was recognized.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ErrorResponse</term>
+ <listitem>
+ <para>
+ An error has occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ReadyForQuery</term>
+ <listitem>
+ <para>
+ Processing of the query string is complete. A separate
+ message is sent to indicate this because the query string might
+ contain multiple SQL commands. (CommandComplete marks the
+ end of processing one SQL command, not the whole string.)
+ ReadyForQuery will always be sent, whether processing
+ terminates successfully or with an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NoticeResponse</term>
+ <listitem>
+ <para>
+ A warning message has been issued in relation to the query.
+ Notices are in addition to other responses, i.e., the backend
+ will continue processing the command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ The response to a <command>SELECT</command> query (or other queries that
+ return row sets, such as <command>EXPLAIN</command> or <command>SHOW</command>)
+ normally consists of RowDescription, zero or more
+ DataRow messages, and then CommandComplete.
+ <command>COPY</command> to or from the frontend invokes special protocol
+ as described in <xref linkend="protocol-copy"/>.
+ All other query types normally produce only
+ a CommandComplete message.
+ </para>
+
+ <para>
+ Since a query string could contain several queries (separated by
+ semicolons), there might be several such response sequences before the
+ backend finishes processing the query string. ReadyForQuery is issued
+ when the entire string has been processed and the backend is ready to
+ accept a new query string.
+ </para>
+
+ <para>
+ If a completely empty (no contents other than whitespace) query string
+ is received, the response is EmptyQueryResponse followed by ReadyForQuery.
+ </para>
+
+ <para>
+ In the event of an error, ErrorResponse is issued followed by
+ ReadyForQuery. All further processing of the query string is aborted by
+ ErrorResponse (even if more queries remained in it). Note that this
+ might occur partway through the sequence of messages generated by an
+ individual query.
+ </para>
+
+ <para>
+ In simple Query mode, the format of retrieved values is always text,
+ except when the given command is a <command>FETCH</command> from a cursor
+ declared with the <literal>BINARY</literal> option. In that case, the
+ retrieved values are in binary format. The format codes given in
+ the RowDescription message tell which format is being used.
+ </para>
+
+ <para>
+ A frontend must be prepared to accept ErrorResponse and
+ NoticeResponse messages whenever it is expecting any other type of
+ message. See also <xref linkend="protocol-async"/> concerning messages
+ that the backend might generate due to outside events.
+ </para>
+
+ <para>
+ Recommended practice is to code frontends in a state-machine style
+ that will accept any message type at any time that it could make sense,
+ rather than wiring in assumptions about the exact sequence of messages.
+ </para>
+
+ <sect3 id="protocol-flow-multi-statement">
+ <title>Multiple Statements in a Simple Query</title>
+
+ <para>
+ When a simple Query message contains more than one SQL statement
+ (separated by semicolons), those statements are executed as a single
+ transaction, unless explicit transaction control commands are included
+ to force a different behavior. For example, if the message contains
+<programlisting>
+INSERT INTO mytable VALUES(1);
+SELECT 1/0;
+INSERT INTO mytable VALUES(2);
+</programlisting>
+ then the divide-by-zero failure in the <command>SELECT</command> will force
+ rollback of the first <command>INSERT</command>. Furthermore, because
+ execution of the message is abandoned at the first error, the second
+ <command>INSERT</command> is never attempted at all.
+ </para>
+
+ <para>
+ If instead the message contains
+<programlisting>
+BEGIN;
+INSERT INTO mytable VALUES(1);
+COMMIT;
+INSERT INTO mytable VALUES(2);
+SELECT 1/0;
+</programlisting>
+ then the first <command>INSERT</command> is committed by the
+ explicit <command>COMMIT</command> command. The second <command>INSERT</command>
+ and the <command>SELECT</command> are still treated as a single transaction,
+ so that the divide-by-zero failure will roll back the
+ second <command>INSERT</command>, but not the first one.
+ </para>
+
+ <para>
+ This behavior is implemented by running the statements in a
+ multi-statement Query message in an <firstterm>implicit transaction
+ block</firstterm> unless there is some explicit transaction block for them to
+ run in. The main difference between an implicit transaction block and
+ a regular one is that an implicit block is closed automatically at the
+ end of the Query message, either by an implicit commit if there was no
+ error, or an implicit rollback if there was an error. This is similar
+ to the implicit commit or rollback that happens for a statement
+ executed by itself (when not in a transaction block).
+ </para>
+
+ <para>
+ If the session is already in a transaction block, as a result of
+ a <command>BEGIN</command> in some previous message, then the Query message
+ simply continues that transaction block, whether the message contains
+ one statement or several. However, if the Query message contains
+ a <command>COMMIT</command> or <command>ROLLBACK</command> closing the existing
+ transaction block, then any following statements are executed in an
+ implicit transaction block.
+ Conversely, if a <command>BEGIN</command> appears in a multi-statement Query
+ message, then it starts a regular transaction block that will only be
+ terminated by an explicit <command>COMMIT</command> or <command>ROLLBACK</command>,
+ whether that appears in this Query message or a later one.
+ If the <command>BEGIN</command> follows some statements that were executed as
+ an implicit transaction block, those statements are not immediately
+ committed; in effect, they are retroactively included into the new
+ regular transaction block.
+ </para>
+
+ <para>
+ A <command>COMMIT</command> or <command>ROLLBACK</command> appearing in an implicit
+ transaction block is executed as normal, closing the implicit block;
+ however, a warning will be issued since a <command>COMMIT</command>
+ or <command>ROLLBACK</command> without a previous <command>BEGIN</command> might
+ represent a mistake. If more statements follow, a new implicit
+ transaction block will be started for them.
+ </para>
+
+ <para>
+ Savepoints are not allowed in an implicit transaction block, since
+ they would conflict with the behavior of automatically closing the
+ block upon any error.
+ </para>
+
+ <para>
+ Remember that, regardless of any transaction control commands that may
+ be present, execution of the Query message stops at the first error.
+ Thus for example given
+<programlisting>
+BEGIN;
+SELECT 1/0;
+ROLLBACK;
+</programlisting>
+ in a single Query message, the session will be left inside a failed
+ regular transaction block, since the <command>ROLLBACK</command> is not
+ reached after the divide-by-zero error. Another <command>ROLLBACK</command>
+ will be needed to restore the session to a usable state.
+ </para>
+
+ <para>
+ Another behavior of note is that initial lexical and syntactic
+ analysis is done on the entire query string before any of it is
+ executed. Thus simple errors (such as a misspelled keyword) in later
+ statements can prevent execution of any of the statements. This
+ is normally invisible to users since the statements would all roll
+ back anyway when done as an implicit transaction block. However,
+ it can be visible when attempting to do multiple transactions within a
+ multi-statement Query. For instance, if a typo turned our previous
+ example into
+<programlisting>
+BEGIN;
+INSERT INTO mytable VALUES(1);
+COMMIT;
+INSERT INTO mytable VALUES(2);
+SELCT 1/0;<!-- this typo is intentional -->
+</programlisting>
+ then none of the statements would get run, resulting in the visible
+ difference that the first <command>INSERT</command> is not committed.
+ Errors detected at semantic analysis or later, such as a misspelled
+ table or column name, do not have this effect.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="protocol-flow-ext-query">
+ <title>Extended Query</title>
+
+ <para>
+ The extended query protocol breaks down the above-described simple
+ query protocol into multiple steps. The results of preparatory
+ steps can be re-used multiple times for improved efficiency.
+ Furthermore, additional features are available, such as the possibility
+ of supplying data values as separate parameters instead of having to
+ insert them directly into a query string.
+ </para>
+
+ <para>
+ In the extended protocol, the frontend first sends a Parse message,
+ which contains a textual query string, optionally some information
+ about data types of parameter placeholders, and the
+ name of a destination prepared-statement object (an empty string
+ selects the unnamed prepared statement). The response is
+ either ParseComplete or ErrorResponse. Parameter data types can be
+ specified by OID; if not given, the parser attempts to infer the
+ data types in the same way as it would do for untyped literal string
+ constants.
+ </para>
+
+ <note>
+ <para>
+ A parameter data type can be left unspecified by setting it to zero,
+ or by making the array of parameter type OIDs shorter than the
+ number of parameter symbols (<literal>$</literal><replaceable>n</replaceable>)
+ used in the query string. Another special case is that a parameter's
+ type can be specified as <type>void</type> (that is, the OID of the
+ <type>void</type> pseudo-type). This is meant to allow parameter symbols
+ to be used for function parameters that are actually OUT parameters.
+ Ordinarily there is no context in which a <type>void</type> parameter
+ could be used, but if such a parameter symbol appears in a function's
+ parameter list, it is effectively ignored. For example, a function
+ call such as <literal>foo($1,$2,$3,$4)</literal> could match a function with
+ two IN and two OUT arguments, if <literal>$3</literal> and <literal>$4</literal>
+ are specified as having type <type>void</type>.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ The query string contained in a Parse message cannot include more
+ than one SQL statement; else a syntax error is reported. This
+ restriction does not exist in the simple-query protocol, but it
+ does exist in the extended protocol, because allowing prepared
+ statements or portals to contain multiple commands would complicate
+ the protocol unduly.
+ </para>
+ </note>
+
+ <para>
+ If successfully created, a named prepared-statement object lasts till
+ the end of the current session, unless explicitly destroyed. An unnamed
+ prepared statement lasts only until the next Parse statement specifying
+ the unnamed statement as destination is issued. (Note that a simple
+ Query message also destroys the unnamed statement.) Named prepared
+ statements must be explicitly closed before they can be redefined by
+ another Parse message, but this is not required for the unnamed statement.
+ Named prepared statements can also be created and accessed at the SQL
+ command level, using <command>PREPARE</command> and <command>EXECUTE</command>.
+ </para>
+
+ <para>
+ Once a prepared statement exists, it can be readied for execution using a
+ Bind message. The Bind message gives the name of the source prepared
+ statement (empty string denotes the unnamed prepared statement), the name
+ of the destination portal (empty string denotes the unnamed portal), and
+ the values to use for any parameter placeholders present in the prepared
+ statement. The
+ supplied parameter set must match those needed by the prepared statement.
+ (If you declared any <type>void</type> parameters in the Parse message,
+ pass NULL values for them in the Bind message.)
+ Bind also specifies the format to use for any data returned
+ by the query; the format can be specified overall, or per-column.
+ The response is either BindComplete or ErrorResponse.
+ </para>
+
+ <note>
+ <para>
+ The choice between text and binary output is determined by the format
+ codes given in Bind, regardless of the SQL command involved. The
+ <literal>BINARY</literal> attribute in cursor declarations is irrelevant when
+ using extended query protocol.
+ </para>
+ </note>
+
+ <para>
+ Query planning typically occurs when the Bind message is processed.
+ If the prepared statement has no parameters, or is executed repeatedly,
+ the server might save the created plan and re-use it during subsequent
+ Bind messages for the same prepared statement. However, it will do so
+ only if it finds that a generic plan can be created that is not much
+ less efficient than a plan that depends on the specific parameter values
+ supplied. This happens transparently so far as the protocol is concerned.
+ </para>
+
+ <para>
+ If successfully created, a named portal object lasts till the end of the
+ current transaction, unless explicitly destroyed. An unnamed portal is
+ destroyed at the end of the transaction, or as soon as the next Bind
+ statement specifying the unnamed portal as destination is issued. (Note
+ that a simple Query message also destroys the unnamed portal.) Named
+ portals must be explicitly closed before they can be redefined by another
+ Bind message, but this is not required for the unnamed portal.
+ Named portals can also be created and accessed at the SQL
+ command level, using <command>DECLARE CURSOR</command> and <command>FETCH</command>.
+ </para>
+
+ <para>
+ Once a portal exists, it can be executed using an Execute message.
+ The Execute message specifies the portal name (empty string denotes the
+ unnamed portal) and
+ a maximum result-row count (zero meaning <quote>fetch all rows</quote>).
+ The result-row count is only meaningful for portals
+ containing commands that return row sets; in other cases the command is
+ always executed to completion, and the row count is ignored.
+ The possible
+ responses to Execute are the same as those described above for queries
+ issued via simple query protocol, except that Execute doesn't cause
+ ReadyForQuery or RowDescription to be issued.
+ </para>
+
+ <para>
+ If Execute terminates before completing the execution of a portal
+ (due to reaching a nonzero result-row count), it will send a
+ PortalSuspended message; the appearance of this message tells the frontend
+ that another Execute should be issued against the same portal to
+ complete the operation. The CommandComplete message indicating
+ completion of the source SQL command is not sent until
+ the portal's execution is completed. Therefore, an Execute phase is
+ always terminated by the appearance of exactly one of these messages:
+ CommandComplete, EmptyQueryResponse (if the portal was created from
+ an empty query string), ErrorResponse, or PortalSuspended.
+ </para>
+
+ <para>
+ At completion of each series of extended-query messages, the frontend
+ should issue a Sync message. This parameterless message causes the
+ backend to close the current transaction if it's not inside a
+ <command>BEGIN</command>/<command>COMMIT</command> transaction block (<quote>close</quote>
+ meaning to commit if no error, or roll back if error). Then a
+ ReadyForQuery response is issued. The purpose of Sync is to provide
+ a resynchronization point for error recovery. When an error is detected
+ while processing any extended-query message, the backend issues
+ ErrorResponse, then reads and discards messages until a Sync is reached,
+ then issues ReadyForQuery and returns to normal message processing.
+ (But note that no skipping occurs if an error is detected
+ <emphasis>while</emphasis> processing Sync &mdash; this ensures that there is one
+ and only one ReadyForQuery sent for each Sync.)
+ </para>
+
+ <note>
+ <para>
+ Sync does not cause a transaction block opened with <command>BEGIN</command>
+ to be closed. It is possible to detect this situation since the
+ ReadyForQuery message includes transaction status information.
+ </para>
+ </note>
+
+ <para>
+ In addition to these fundamental, required operations, there are several
+ optional operations that can be used with extended-query protocol.
+ </para>
+
+ <para>
+ The Describe message (portal variant) specifies the name of an existing
+ portal (or an empty string for the unnamed portal). The response is a
+ RowDescription message describing the rows that will be returned by
+ executing the portal; or a NoData message if the portal does not contain a
+ query that will return rows; or ErrorResponse if there is no such portal.
+ </para>
+
+ <para>
+ The Describe message (statement variant) specifies the name of an existing
+ prepared statement (or an empty string for the unnamed prepared
+ statement). The response is a ParameterDescription message describing the
+ parameters needed by the statement, followed by a RowDescription message
+ describing the rows that will be returned when the statement is eventually
+ executed (or a NoData message if the statement will not return rows).
+ ErrorResponse is issued if there is no such prepared statement. Note that
+ since Bind has not yet been issued, the formats to be used for returned
+ columns are not yet known to the backend; the format code fields in the
+ RowDescription message will be zeroes in this case.
+ </para>
+
+ <tip>
+ <para>
+ In most scenarios the frontend should issue one or the other variant
+ of Describe before issuing Execute, to ensure that it knows how to
+ interpret the results it will get back.
+ </para>
+ </tip>
+
+ <para>
+ The Close message closes an existing prepared statement or portal
+ and releases resources. It is not an error to issue Close against
+ a nonexistent statement or portal name. The response is normally
+ CloseComplete, but could be ErrorResponse if some difficulty is
+ encountered while releasing resources. Note that closing a prepared
+ statement implicitly closes any open portals that were constructed
+ from that statement.
+ </para>
+
+ <para>
+ The Flush message does not cause any specific output to be generated,
+ but forces the backend to deliver any data pending in its output
+ buffers. A Flush must be sent after any extended-query command except
+ Sync, if the frontend wishes to examine the results of that command before
+ issuing more commands. Without Flush, messages returned by the backend
+ will be combined into the minimum possible number of packets to minimize
+ network overhead.
+ </para>
+
+ <note>
+ <para>
+ The simple Query message is approximately equivalent to the series Parse,
+ Bind, portal Describe, Execute, Close, Sync, using the unnamed prepared
+ statement and portal objects and no parameters. One difference is that
+ it will accept multiple SQL statements in the query string, automatically
+ performing the bind/describe/execute sequence for each one in succession.
+ Another difference is that it will not return ParseComplete, BindComplete,
+ CloseComplete, or NoData messages.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="protocol-flow-pipelining">
+ <title>Pipelining</title>
+
+ <indexterm zone="protocol-flow-pipelining">
+ <primary>pipelining</primary>
+ <secondary>protocol specification</secondary>
+ </indexterm>
+
+ <para>
+ Use of the extended query protocol
+ allows <firstterm>pipelining</firstterm>, which means sending a series
+ of queries without waiting for earlier ones to complete. This reduces
+ the number of network round trips needed to complete a given series of
+ operations. However, the user must carefully consider the required
+ behavior if one of the steps fails, since later queries will already
+ be in flight to the server.
+ </para>
+
+ <para>
+ One way to deal with that is to make the whole query series be a
+ single transaction, that is wrap it in <command>BEGIN</command> ...
+ <command>COMMIT</command>. However, this does not help if one wishes
+ for some of the commands to commit independently of others.
+ </para>
+
+ <para>
+ The extended query protocol provides another way to manage this
+ concern, which is to omit sending Sync messages between steps that
+ are dependent. Since, after an error, the backend will skip command
+ messages until it finds Sync, this allows later commands in a pipeline
+ to be skipped automatically when an earlier one fails, without the
+ client having to manage that explicitly with <command>BEGIN</command>
+ and <command>COMMIT</command>. Independently-committable segments
+ of the pipeline can be separated by Sync messages.
+ </para>
+
+ <para>
+ If the client has not issued an explicit <command>BEGIN</command>,
+ then each Sync ordinarily causes an implicit <command>COMMIT</command>
+ if the preceding step(s) succeeded, or an
+ implicit <command>ROLLBACK</command> if they failed. However, there
+ are a few DDL commands (such as <command>CREATE DATABASE</command>)
+ that cannot be executed inside a transaction block. If one of
+ these is executed in a pipeline, it will fail unless it is the first
+ command in the pipeline. Furthermore, upon success it will force an
+ immediate commit to preserve database consistency. Thus a Sync
+ immediately following one of these commands has no effect except to
+ respond with ReadyForQuery.
+ </para>
+
+ <para>
+ When using this method, completion of the pipeline must be determined
+ by counting ReadyForQuery messages and waiting for that to reach the
+ number of Syncs sent. Counting command completion responses is
+ unreliable, since some of the commands may be skipped and thus not
+ produce a completion message.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Function Call</title>
+
+ <para>
+ The Function Call sub-protocol allows the client to request a direct
+ call of any function that exists in the database's
+ <structname>pg_proc</structname> system catalog. The client must have
+ execute permission for the function.
+ </para>
+
+ <note>
+ <para>
+ The Function Call sub-protocol is a legacy feature that is probably best
+ avoided in new code. Similar results can be accomplished by setting up
+ a prepared statement that does <literal>SELECT function($1, ...)</literal>.
+ The Function Call cycle can then be replaced with Bind/Execute.
+ </para>
+ </note>
+
+ <para>
+ A Function Call cycle is initiated by the frontend sending a
+ FunctionCall message to the backend. The backend then sends one
+ or more response messages depending on the results of the function
+ call, and finally a ReadyForQuery response message. ReadyForQuery
+ informs the frontend that it can safely send a new query or
+ function call.
+ </para>
+
+ <para>
+ The possible response messages from the backend are:
+
+ <variablelist>
+ <varlistentry>
+ <term>ErrorResponse</term>
+ <listitem>
+ <para>
+ An error has occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>FunctionCallResponse</term>
+ <listitem>
+ <para>
+ The function call was completed and returned the result given
+ in the message.
+ (Note that the Function Call protocol can only handle a single
+ scalar result, not a row type or set of results.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ReadyForQuery</term>
+ <listitem>
+ <para>
+ Processing of the function call is complete. ReadyForQuery
+ will always be sent, whether processing terminates
+ successfully or with an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>NoticeResponse</term>
+ <listitem>
+ <para>
+ A warning message has been issued in relation to the function
+ call. Notices are in addition to other responses, i.e., the
+ backend will continue processing the command.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-copy">
+ <title>COPY Operations</title>
+
+ <para>
+ The <command>COPY</command> command allows high-speed bulk data transfer
+ to or from the server. Copy-in and copy-out operations each switch
+ the connection into a distinct sub-protocol, which lasts until the
+ operation is completed.
+ </para>
+
+ <para>
+ Copy-in mode (data transfer to the server) is initiated when the
+ backend executes a <command>COPY FROM STDIN</command> SQL statement. The backend
+ sends a CopyInResponse message to the frontend. The frontend should
+ then send zero or more CopyData messages, forming a stream of input
+ data. (The message boundaries are not required to have anything to do
+ with row boundaries, although that is often a reasonable choice.)
+ The frontend can terminate the copy-in mode by sending either a CopyDone
+ message (allowing successful termination) or a CopyFail message (which
+ will cause the <command>COPY</command> SQL statement to fail with an
+ error). The backend then reverts to the command-processing mode it was
+ in before the <command>COPY</command> started, which will be either simple or
+ extended query protocol. It will next send either CommandComplete
+ (if successful) or ErrorResponse (if not).
+ </para>
+
+ <para>
+ In the event of a backend-detected error during copy-in mode (including
+ receipt of a CopyFail message), the backend will issue an ErrorResponse
+ message. If the <command>COPY</command> command was issued via an extended-query
+ message, the backend will now discard frontend messages until a Sync
+ message is received, then it will issue ReadyForQuery and return to normal
+ processing. If the <command>COPY</command> command was issued in a simple
+ Query message, the rest of that message is discarded and ReadyForQuery
+ is issued. In either case, any subsequent CopyData, CopyDone, or CopyFail
+ messages issued by the frontend will simply be dropped.
+ </para>
+
+ <para>
+ The backend will ignore Flush and Sync messages received during copy-in
+ mode. Receipt of any other non-copy message type constitutes an error
+ that will abort the copy-in state as described above. (The exception for
+ Flush and Sync is for the convenience of client libraries that always
+ send Flush or Sync after an Execute message, without checking whether
+ the command to be executed is a <command>COPY FROM STDIN</command>.)
+ </para>
+
+ <para>
+ Copy-out mode (data transfer from the server) is initiated when the
+ backend executes a <command>COPY TO STDOUT</command> SQL statement. The backend
+ sends a CopyOutResponse message to the frontend, followed by
+ zero or more CopyData messages (always one per row), followed by CopyDone.
+ The backend then reverts to the command-processing mode it was
+ in before the <command>COPY</command> started, and sends CommandComplete.
+ The frontend cannot abort the transfer (except by closing the connection
+ or issuing a Cancel request),
+ but it can discard unwanted CopyData and CopyDone messages.
+ </para>
+
+ <para>
+ In the event of a backend-detected error during copy-out mode,
+ the backend will issue an ErrorResponse message and revert to normal
+ processing. The frontend should treat receipt of ErrorResponse as
+ terminating the copy-out mode.
+ </para>
+
+ <para>
+ It is possible for NoticeResponse and ParameterStatus messages to be
+ interspersed between CopyData messages; frontends must handle these cases,
+ and should be prepared for other asynchronous message types as well (see
+ <xref linkend="protocol-async"/>). Otherwise, any message type other than
+ CopyData or CopyDone may be treated as terminating copy-out mode.
+ </para>
+
+ <para>
+ There is another Copy-related mode called copy-both, which allows
+ high-speed bulk data transfer to <emphasis>and</emphasis> from the server.
+ Copy-both mode is initiated when a backend in walsender mode
+ executes a <command>START_REPLICATION</command> statement. The
+ backend sends a CopyBothResponse message to the frontend. Both
+ the backend and the frontend may then send CopyData messages
+ until either end sends a CopyDone message. After the client
+ sends a CopyDone message, the connection goes from copy-both mode to
+ copy-out mode, and the client may not send any more CopyData messages.
+ Similarly, when the server sends a CopyDone message, the connection
+ goes into copy-in mode, and the server may not send any more CopyData
+ messages. After both sides have sent a CopyDone message, the copy mode
+ is terminated, and the backend reverts to the command-processing mode.
+ In the event of a backend-detected error during copy-both mode,
+ the backend will issue an ErrorResponse message, discard frontend messages
+ until a Sync message is received, and then issue ReadyForQuery and return
+ to normal processing. The frontend should treat receipt of ErrorResponse
+ as terminating the copy in both directions; no CopyDone should be sent
+ in this case. See <xref linkend="protocol-replication"/> for more
+ information on the subprotocol transmitted over copy-both mode.
+ </para>
+
+ <para>
+ The CopyInResponse, CopyOutResponse and CopyBothResponse messages
+ include fields that inform the frontend of the number of columns
+ per row and the format codes being used for each column. (As of
+ the present implementation, all columns in a given <command>COPY</command>
+ operation will use the same format, but the message design does not
+ assume this.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="protocol-async">
+ <title>Asynchronous Operations</title>
+
+ <para>
+ There are several cases in which the backend will send messages that
+ are not specifically prompted by the frontend's command stream.
+ Frontends must be prepared to deal with these messages at any time,
+ even when not engaged in a query.
+ At minimum, one should check for these cases before beginning to
+ read a query response.
+ </para>
+
+ <para>
+ It is possible for NoticeResponse messages to be generated due to
+ outside activity; for example, if the database administrator commands
+ a <quote>fast</quote> database shutdown, the backend will send a NoticeResponse
+ indicating this fact before closing the connection. Accordingly,
+ frontends should always be prepared to accept and display NoticeResponse
+ messages, even when the connection is nominally idle.
+ </para>
+
+ <para>
+ ParameterStatus messages will be generated whenever the active
+ value changes for any of the parameters the backend believes the
+ frontend should know about. Most commonly this occurs in response
+ to a <command>SET</command> SQL command executed by the frontend, and
+ this case is effectively synchronous &mdash; but it is also possible
+ for parameter status changes to occur because the administrator
+ changed a configuration file and then sent the
+ <systemitem>SIGHUP</systemitem> signal to the server. Also,
+ if a <command>SET</command> command is rolled back, an appropriate
+ ParameterStatus message will be generated to report the current
+ effective value.
+ </para>
+
+ <para>
+ At present there is a hard-wired set of parameters for which
+ ParameterStatus will be generated: they are
+ <varname>server_version</varname>,
+ <varname>server_encoding</varname>,
+ <varname>client_encoding</varname>,
+ <varname>application_name</varname>,
+ <varname>default_transaction_read_only</varname>,
+ <varname>in_hot_standby</varname>,
+ <varname>is_superuser</varname>,
+ <varname>session_authorization</varname>,
+ <varname>DateStyle</varname>,
+ <varname>IntervalStyle</varname>,
+ <varname>TimeZone</varname>,
+ <varname>integer_datetimes</varname>, and
+ <varname>standard_conforming_strings</varname>.
+ (<varname>server_encoding</varname>, <varname>TimeZone</varname>, and
+ <varname>integer_datetimes</varname> were not reported by releases before 8.0;
+ <varname>standard_conforming_strings</varname> was not reported by releases
+ before 8.1;
+ <varname>IntervalStyle</varname> was not reported by releases before 8.4;
+ <varname>application_name</varname> was not reported by releases before
+ 9.0;
+ <varname>default_transaction_read_only</varname> and
+ <varname>in_hot_standby</varname> were not reported by releases before
+ 14.)
+ Note that
+ <varname>server_version</varname>,
+ <varname>server_encoding</varname> and
+ <varname>integer_datetimes</varname>
+ are pseudo-parameters that cannot change after startup.
+ This set might change in the future, or even become configurable.
+ Accordingly, a frontend should simply ignore ParameterStatus for
+ parameters that it does not understand or care about.
+ </para>
+
+ <para>
+ If a frontend issues a <command>LISTEN</command> command, then the
+ backend will send a NotificationResponse message (not to be
+ confused with NoticeResponse!) whenever a
+ <command>NOTIFY</command> command is executed for the same
+ channel name.
+ </para>
+
+ <note>
+ <para>
+ At present, NotificationResponse can only be sent outside a
+ transaction, and thus it will not occur in the middle of a
+ command-response series, though it might occur just before ReadyForQuery.
+ It is unwise to design frontend logic that assumes that, however.
+ Good practice is to be able to accept NotificationResponse at any
+ point in the protocol.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2>
+ <title>Canceling Requests in Progress</title>
+
+ <para>
+ During the processing of a query, the frontend might request
+ cancellation of the query. The cancel request is not sent
+ directly on the open connection to the backend for reasons of
+ implementation efficiency: we don't want to have the backend
+ constantly checking for new input from the frontend during query
+ processing. Cancel requests should be relatively infrequent, so
+ we make them slightly cumbersome in order to avoid a penalty in
+ the normal case.
+ </para>
+
+ <para>
+ To issue a cancel request, the frontend opens a new connection to
+ the server and sends a CancelRequest message, rather than the
+ StartupMessage message that would ordinarily be sent across a new
+ connection. The server will process this request and then close
+ the connection. For security reasons, no direct reply is made to
+ the cancel request message.
+ </para>
+
+ <para>
+ A CancelRequest message will be ignored unless it contains the
+ same key data (PID and secret key) passed to the frontend during
+ connection start-up. If the request matches the PID and secret
+ key for a currently executing backend, the processing of the
+ current query is aborted. (In the existing implementation, this is
+ done by sending a special signal to the backend process that is
+ processing the query.)
+ </para>
+
+ <para>
+ The cancellation signal might or might not have any effect &mdash; for
+ example, if it arrives after the backend has finished processing
+ the query, then it will have no effect. If the cancellation is
+ effective, it results in the current command being terminated
+ early with an error message.
+ </para>
+
+ <para>
+ The upshot of all this is that for reasons of both security and
+ efficiency, the frontend has no direct way to tell whether a
+ cancel request has succeeded. It must continue to wait for the
+ backend to respond to the query. Issuing a cancel simply improves
+ the odds that the current query will finish soon, and improves the
+ odds that it will fail with an error message instead of
+ succeeding.
+ </para>
+
+ <para>
+ Since the cancel request is sent across a new connection to the
+ server and not across the regular frontend/backend communication
+ link, it is possible for the cancel request to be issued by any
+ process, not just the frontend whose query is to be canceled.
+ This might provide additional flexibility when building
+ multiple-process applications. It also introduces a security
+ risk, in that unauthorized persons might try to cancel queries.
+ The security risk is addressed by requiring a dynamically
+ generated secret key to be supplied in cancel requests.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Termination</title>
+
+ <para>
+ The normal, graceful termination procedure is that the frontend
+ sends a Terminate message and immediately closes the connection.
+ On receipt of this message, the backend closes the connection and
+ terminates.
+ </para>
+
+ <para>
+ In rare cases (such as an administrator-commanded database shutdown)
+ the backend might disconnect without any frontend request to do so.
+ In such cases the backend will attempt to send an error or notice message
+ giving the reason for the disconnection before it closes the connection.
+ </para>
+
+ <para>
+ Other termination scenarios arise from various failure cases, such as core
+ dump at one end or the other, loss of the communications link, loss of
+ message-boundary synchronization, etc. If either frontend or backend sees
+ an unexpected closure of the connection, it should clean
+ up and terminate. The frontend has the option of launching a new backend
+ by recontacting the server if it doesn't want to terminate itself.
+ Closing the connection is also advisable if an unrecognizable message type
+ is received, since this probably indicates loss of message-boundary sync.
+ </para>
+
+ <para>
+ For either normal or abnormal termination, any open transaction is
+ rolled back, not committed. One should note however that if a
+ frontend disconnects while a non-<command>SELECT</command> query
+ is being processed, the backend will probably finish the query
+ before noticing the disconnection. If the query is outside any
+ transaction block (<command>BEGIN</command> ... <command>COMMIT</command>
+ sequence) then its results might be committed before the
+ disconnection is recognized.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><acronym>SSL</acronym> Session Encryption</title>
+
+ <para>
+ If <productname>PostgreSQL</productname> was built with
+ <acronym>SSL</acronym> support, frontend/backend communications
+ can be encrypted using <acronym>SSL</acronym>. This provides
+ communication security in environments where attackers might be
+ able to capture the session traffic. For more information on
+ encrypting <productname>PostgreSQL</productname> sessions with
+ <acronym>SSL</acronym>, see <xref linkend="ssl-tcp"/>.
+ </para>
+
+ <para>
+ To initiate an <acronym>SSL</acronym>-encrypted connection, the
+ frontend initially sends an SSLRequest message rather than a
+ StartupMessage. The server then responds with a single byte
+ containing <literal>S</literal> or <literal>N</literal>, indicating that it is
+ willing or unwilling to perform <acronym>SSL</acronym>,
+ respectively. The frontend might close the connection at this point
+ if it is dissatisfied with the response. To continue after
+ <literal>S</literal>, perform an <acronym>SSL</acronym> startup handshake
+ (not described here, part of the <acronym>SSL</acronym>
+ specification) with the server. If this is successful, continue
+ with sending the usual StartupMessage. In this case the
+ StartupMessage and all subsequent data will be
+ <acronym>SSL</acronym>-encrypted. To continue after
+ <literal>N</literal>, send the usual StartupMessage and proceed without
+ encryption.
+ (Alternatively, it is permissible to issue a GSSENCRequest message
+ after an <literal>N</literal> response to try to
+ use <acronym>GSSAPI</acronym> encryption instead
+ of <acronym>SSL</acronym>.)
+ </para>
+
+ <para>
+ The frontend should also be prepared to handle an ErrorMessage
+ response to SSLRequest from the server. This would only occur if
+ the server predates the addition of <acronym>SSL</acronym> support
+ to <productname>PostgreSQL</productname>. (Such servers are now very ancient,
+ and likely do not exist in the wild anymore.)
+ In this case the connection must
+ be closed, but the frontend might choose to open a fresh connection
+ and proceed without requesting <acronym>SSL</acronym>.
+ </para>
+
+ <para>
+ When <acronym>SSL</acronym> encryption can be performed, the server
+ is expected to send only the single <literal>S</literal> byte and then
+ wait for the frontend to initiate an <acronym>SSL</acronym> handshake.
+ If additional bytes are available to read at this point, it likely
+ means that a man-in-the-middle is attempting to perform a
+ buffer-stuffing attack
+ (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
+ Frontends should be coded either to read exactly one byte from the
+ socket before turning the socket over to their SSL library, or to
+ treat it as a protocol violation if they find they have read additional
+ bytes.
+ </para>
+
+ <para>
+ An initial SSLRequest can also be used in a connection that is being
+ opened to send a CancelRequest message.
+ </para>
+
+ <para>
+ While the protocol itself does not provide a way for the server to
+ force <acronym>SSL</acronym> encryption, the administrator can
+ configure the server to reject unencrypted sessions as a byproduct
+ of authentication checking.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><acronym>GSSAPI</acronym> Session Encryption</title>
+
+ <para>
+ If <productname>PostgreSQL</productname> was built with
+ <acronym>GSSAPI</acronym> support, frontend/backend communications
+ can be encrypted using <acronym>GSSAPI</acronym>. This provides
+ communication security in environments where attackers might be
+ able to capture the session traffic. For more information on
+ encrypting <productname>PostgreSQL</productname> sessions with
+ <acronym>GSSAPI</acronym>, see <xref linkend="gssapi-enc"/>.
+ </para>
+
+ <para>
+ To initiate a <acronym>GSSAPI</acronym>-encrypted connection, the
+ frontend initially sends a GSSENCRequest message rather than a
+ StartupMessage. The server then responds with a single byte
+ containing <literal>G</literal> or <literal>N</literal>, indicating that it
+ is willing or unwilling to perform <acronym>GSSAPI</acronym> encryption,
+ respectively. The frontend might close the connection at this point
+ if it is dissatisfied with the response. To continue after
+ <literal>G</literal>, using the GSSAPI C bindings as discussed in
+ <ulink url="https://tools.ietf.org/html/rfc2744">RFC 2744</ulink>
+ or equivalent, perform a <acronym>GSSAPI</acronym> initialization by
+ calling <function>gss_init_sec_context()</function> in a loop and sending
+ the result to the server, starting with an empty input and then with each
+ result from the server, until it returns no output. When sending the
+ results of <function>gss_init_sec_context()</function> to the server,
+ prepend the length of the message as a four byte integer in network byte
+ order.
+ To continue after
+ <literal>N</literal>, send the usual StartupMessage and proceed without
+ encryption.
+ (Alternatively, it is permissible to issue an SSLRequest message
+ after an <literal>N</literal> response to try to
+ use <acronym>SSL</acronym> encryption instead
+ of <acronym>GSSAPI</acronym>.)
+ </para>
+
+ <para>
+ The frontend should also be prepared to handle an ErrorMessage
+ response to GSSENCRequest from the server. This would only occur if
+ the server predates the addition of <acronym>GSSAPI</acronym> encryption
+ support to <productname>PostgreSQL</productname>. In this case the
+ connection must be closed, but the frontend might choose to open a fresh
+ connection and proceed without requesting <acronym>GSSAPI</acronym>
+ encryption.
+ </para>
+
+ <para>
+ When <acronym>GSSAPI</acronym> encryption can be performed, the server
+ is expected to send only the single <literal>G</literal> byte and then
+ wait for the frontend to initiate a <acronym>GSSAPI</acronym> handshake.
+ If additional bytes are available to read at this point, it likely
+ means that a man-in-the-middle is attempting to perform a
+ buffer-stuffing attack
+ (<ulink url="https://www.postgresql.org/support/security/CVE-2021-23222/">CVE-2021-23222</ulink>).
+ Frontends should be coded either to read exactly one byte from the
+ socket before turning the socket over to their GSSAPI library, or to
+ treat it as a protocol violation if they find they have read additional
+ bytes.
+ </para>
+
+ <para>
+ An initial GSSENCRequest can also be used in a connection that is being
+ opened to send a CancelRequest message.
+ </para>
+
+ <para>
+ Once <acronym>GSSAPI</acronym> encryption has been successfully
+ established, use <function>gss_wrap()</function> to
+ encrypt the usual StartupMessage and all subsequent data, prepending the
+ length of the result from <function>gss_wrap()</function> as a four byte
+ integer in network byte order to the actual encrypted payload. Note that
+ the server will only accept encrypted packets from the client which are less
+ than 16kB; <function>gss_wrap_size_limit()</function> should be used by the
+ client to determine the size of the unencrypted message which will fit
+ within this limit and larger messages should be broken up into multiple
+ <function>gss_wrap()</function> calls. Typical segments are 8kB of
+ unencrypted data, resulting in encrypted packets of slightly larger than 8kB
+ but well within the 16kB maximum. The server can be expected to not send
+ encrypted packets of larger than 16kB to the client.
+ </para>
+
+ <para>
+ While the protocol itself does not provide a way for the server to
+ force <acronym>GSSAPI</acronym> encryption, the administrator can
+ configure the server to reject unencrypted sessions as a byproduct
+ of authentication checking.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="sasl-authentication">
+ <title>SASL Authentication</title>
+
+ <para>
+ <firstterm>SASL</firstterm> is a framework for authentication in connection-oriented
+ protocols. At the moment, <productname>PostgreSQL</productname> implements two SASL
+ authentication mechanisms, SCRAM-SHA-256 and SCRAM-SHA-256-PLUS. More
+ might be added in the future. The below steps illustrate how SASL
+ authentication is performed in general, while the next subsection gives
+ more details on SCRAM-SHA-256 and SCRAM-SHA-256-PLUS.
+ </para>
+
+ <procedure>
+ <title>SASL Authentication Message Flow</title>
+
+ <step id="sasl-auth-begin">
+ <para>
+ To begin a SASL authentication exchange, the server sends an
+ AuthenticationSASL message. It includes a list of SASL authentication
+ mechanisms that the server can accept, in the server's preferred order.
+ </para>
+ </step>
+
+ <step id="sasl-auth-initial-response">
+ <para>
+ The client selects one of the supported mechanisms from the list, and sends
+ a SASLInitialResponse message to the server. The message includes the name
+ of the selected mechanism, and an optional Initial Client Response, if the
+ selected mechanism uses that.
+ </para>
+ </step>
+
+ <step id="sasl-auth-continue">
+ <para>
+ One or more server-challenge and client-response message will follow. Each
+ server-challenge is sent in an AuthenticationSASLContinue message, followed
+ by a response from client in a SASLResponse message. The particulars of
+ the messages are mechanism specific.
+ </para>
+ </step>
+
+ <step id="sasl-auth-end">
+ <para>
+ Finally, when the authentication exchange is completed successfully, the
+ server sends an AuthenticationSASLFinal message, followed
+ immediately by an AuthenticationOk message. The AuthenticationSASLFinal
+ contains additional server-to-client data, whose content is particular to the
+ selected authentication mechanism. If the authentication mechanism doesn't
+ use additional data that's sent at completion, the AuthenticationSASLFinal
+ message is not sent.
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ On error, the server can abort the authentication at any stage, and send an
+ ErrorMessage.
+ </para>
+
+ <sect2 id="sasl-scram-sha-256">
+ <title>SCRAM-SHA-256 Authentication</title>
+
+ <para>
+ The implemented SASL mechanisms at the moment
+ are <literal>SCRAM-SHA-256</literal> and its variant with channel
+ binding <literal>SCRAM-SHA-256-PLUS</literal>. They are described in
+ detail in <ulink url="https://tools.ietf.org/html/rfc7677">RFC 7677</ulink>
+ and <ulink url="https://tools.ietf.org/html/rfc5802">RFC 5802</ulink>.
+ </para>
+
+ <para>
+ When SCRAM-SHA-256 is used in PostgreSQL, the server will ignore the user name
+ that the client sends in the <structname>client-first-message</structname>. The user name
+ that was already sent in the startup message is used instead.
+ <productname>PostgreSQL</productname> supports multiple character encodings, while SCRAM
+ dictates UTF-8 to be used for the user name, so it might be impossible to
+ represent the PostgreSQL user name in UTF-8.
+ </para>
+
+ <para>
+ The SCRAM specification dictates that the password is also in UTF-8, and is
+ processed with the <firstterm>SASLprep</firstterm> algorithm.
+ <productname>PostgreSQL</productname>, however, does not require UTF-8 to be used for
+ the password. When a user's password is set, it is processed with SASLprep
+ as if it was in UTF-8, regardless of the actual encoding used. However, if
+ it is not a legal UTF-8 byte sequence, or it contains UTF-8 byte sequences
+ that are prohibited by the SASLprep algorithm, the raw password will be used
+ without SASLprep processing, instead of throwing an error. This allows the
+ password to be normalized when it is in UTF-8, but still allows a non-UTF-8
+ password to be used, and doesn't require the system to know which encoding
+ the password is in.
+ </para>
+
+ <para>
+ <firstterm>Channel binding</firstterm> is supported in PostgreSQL builds with
+ SSL support. The SASL mechanism name for SCRAM with channel binding is
+ <literal>SCRAM-SHA-256-PLUS</literal>. The channel binding type used by
+ PostgreSQL is <literal>tls-server-end-point</literal>.
+ </para>
+
+ <para>
+ In <acronym>SCRAM</acronym> without channel binding, the server chooses
+ a random number that is transmitted to the client to be mixed with the
+ user-supplied password in the transmitted password hash. While this
+ prevents the password hash from being successfully retransmitted in
+ a later session, it does not prevent a fake server between the real
+ server and client from passing through the server's random value
+ and successfully authenticating.
+ </para>
+
+ <para>
+ <acronym>SCRAM</acronym> with channel binding prevents such
+ man-in-the-middle attacks by mixing the signature of the server's
+ certificate into the transmitted password hash. While a fake server can
+ retransmit the real server's certificate, it doesn't have access to the
+ private key matching that certificate, and therefore cannot prove it is
+ the owner, causing SSL connection failure.
+ </para>
+
+ <procedure>
+ <title>Example</title>
+ <step id="scram-begin">
+ <para>
+ The server sends an AuthenticationSASL message. It includes a list of
+ SASL authentication mechanisms that the server can accept.
+ This will be <literal>SCRAM-SHA-256-PLUS</literal>
+ and <literal>SCRAM-SHA-256</literal> if the server is built with SSL
+ support, or else just the latter.
+ </para>
+ </step>
+
+ <step id="scram-client-first">
+ <para>
+ The client responds by sending a SASLInitialResponse message, which
+ indicates the chosen mechanism, <literal>SCRAM-SHA-256</literal> or
+ <literal>SCRAM-SHA-256-PLUS</literal>. (A client is free to choose either
+ mechanism, but for better security it should choose the channel-binding
+ variant if it can support it.) In the Initial Client response field, the
+ message contains the SCRAM <structname>client-first-message</structname>.
+ The <structname>client-first-message</structname> also contains the channel
+ binding type chosen by the client.
+ </para>
+ </step>
+
+ <step id="scram-server-first">
+ <para>
+ Server sends an AuthenticationSASLContinue message, with a SCRAM
+ <structname>server-first-message</structname> as the content.
+ </para>
+ </step>
+
+ <step id="scram-client-final">
+ <para>
+ Client sends a SASLResponse message, with SCRAM
+ <structname>client-final-message</structname> as the content.
+ </para>
+ </step>
+
+ <step id="scram-server-final">
+ <para>
+ Server sends an AuthenticationSASLFinal message, with the SCRAM
+ <structname>server-final-message</structname>, followed immediately by
+ an AuthenticationOk message.
+ </para>
+ </step>
+ </procedure>
+ </sect2>
+ </sect1>
+
+ <sect1 id="protocol-replication">
+ <title>Streaming Replication Protocol</title>
+
+ <para>
+ To initiate streaming replication, the frontend sends the
+ <literal>replication</literal> parameter in the startup message. A Boolean
+ value of <literal>true</literal> (or <literal>on</literal>,
+ <literal>yes</literal>, <literal>1</literal>) tells the backend to go into
+ physical replication walsender mode, wherein a small set of replication
+ commands, shown below, can be issued instead of SQL statements.
+ </para>
+
+ <para>
+ Passing <literal>database</literal> as the value for the
+ <literal>replication</literal> parameter instructs the backend to go into
+ logical replication walsender mode, connecting to the database specified in
+ the <literal>dbname</literal> parameter. In logical replication walsender
+ mode, the replication commands shown below as well as normal SQL commands can
+ be issued.
+ </para>
+
+ <para>
+ In either physical replication or logical replication walsender mode, only the
+ simple query protocol can be used.
+ </para>
+
+ <para>
+ For the purpose of testing replication commands, you can make a replication
+ connection via <application>psql</application> or any other
+ <application>libpq</application>-using tool with a connection string including
+ the <literal>replication</literal> option,
+ e.g.:
+<programlisting>
+psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
+</programlisting>
+ However, it is often more useful to use
+ <xref linkend="app-pgreceivewal"/> (for physical replication) or
+ <xref linkend="app-pgrecvlogical"/> (for logical replication).
+ </para>
+
+ <para>
+ Replication commands are logged in the server log when
+ <xref linkend="guc-log-replication-commands"/> is enabled.
+ </para>
+
+ <para>
+ The commands accepted in replication mode are:
+
+ <variablelist>
+ <varlistentry id="protocol-replication-identify-system">
+ <term><literal>IDENTIFY_SYSTEM</literal>
+ <indexterm><primary>IDENTIFY_SYSTEM</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Requests the server to identify itself. Server replies with a result
+ set of a single row, containing four fields:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>systemid</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The unique system identifier identifying the cluster. This
+ can be used to check that the base backup used to initialize the
+ standby came from the same cluster.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>timeline</literal> (<type>int4</type>)</term>
+ <listitem>
+ <para>
+ Current timeline ID. Also useful to check that the standby is
+ consistent with the primary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>xlogpos</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ Current WAL flush location. Useful to get a known location in the
+ write-ahead log where streaming can start.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>dbname</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ Database connected to or null.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-show">
+ <term><literal>SHOW</literal> <replaceable class="parameter">name</replaceable>
+ <indexterm><primary>SHOW</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Requests the server to send the current setting of a run-time parameter.
+ This is similar to the SQL command <xref linkend="sql-show"/>.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a run-time parameter. Available parameters are documented
+ in <xref linkend="runtime-config"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-timeline-history">
+ <term><literal>TIMELINE_HISTORY</literal> <replaceable class="parameter">tli</replaceable>
+ <indexterm><primary>TIMELINE_HISTORY</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Requests the server to send over the timeline history file for timeline
+ <replaceable class="parameter">tli</replaceable>. Server replies with a
+ result set of a single row, containing two fields. While the fields
+ are labeled as <type>text</type>, they effectively return raw bytes,
+ with no encoding conversion:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>filename</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ File name of the timeline history file, e.g., <filename>00000002.history</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>content</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ Contents of the timeline history file.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-create-replication-slot" xreflabel="CREATE_REPLICATION_SLOT">
+ <term><literal>CREATE_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> [ <literal>TEMPORARY</literal> ] { <literal>PHYSICAL</literal> | <literal>LOGICAL</literal> <replaceable class="parameter">output_plugin</replaceable> } [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ]
+ <indexterm><primary>CREATE_REPLICATION_SLOT</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Create a physical or logical replication
+ slot. See <xref linkend="streaming-replication-slots"/> for more about
+ replication slots.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">slot_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the slot to create. Must be a valid replication slot
+ name (see <xref linkend="streaming-replication-slots-manipulation"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_plugin</replaceable></term>
+ <listitem>
+ <para>
+ The name of the output plugin used for logical decoding
+ (see <xref linkend="logicaldecoding-output-plugin"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TEMPORARY</literal></term>
+ <listitem>
+ <para>
+ Specify that this replication slot is a temporary one. Temporary
+ slots are not saved to disk and are automatically dropped on error
+ or when the session has finished.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>The following options are supported:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TWO_PHASE [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If true, this logical replication slot supports decoding of two-phase
+ commit. With this option, commands related to two-phase commit such as
+ <literal>PREPARE TRANSACTION</literal>, <literal>COMMIT PREPARED</literal>
+ and <literal>ROLLBACK PREPARED</literal> are decoded and transmitted.
+ The transaction will be decoded and transmitted at
+ <literal>PREPARE TRANSACTION</literal> time.
+ The default is false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESERVE_WAL [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If true, this physical replication slot reserves <acronym>WAL</acronym>
+ immediately. Otherwise, <acronym>WAL</acronym> is only reserved upon
+ connection from a streaming replication client.
+ The default is false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SNAPSHOT { 'export' | 'use' | 'nothing' }</literal></term>
+ <listitem>
+ <para>
+ Decides what to do with the snapshot created during logical slot
+ initialization. <literal>'export'</literal>, which is the default,
+ will export the snapshot for use in other sessions. This option can't
+ be used inside a transaction. <literal>'use'</literal> will use the
+ snapshot for the current transaction executing the command. This
+ option must be used in a transaction, and
+ <literal>CREATE_REPLICATION_SLOT</literal> must be the first command
+ run in that transaction. Finally, <literal>'nothing'</literal> will
+ just use the snapshot for logical decoding as normal but won't do
+ anything else with it.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ In response to this command, the server will send a one-row result set
+ containing the following fields:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>slot_name</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The name of the newly-created replication slot.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>consistent_point</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The WAL location at which the slot became consistent. This is the
+ earliest location from which streaming can start on this replication
+ slot.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>snapshot_name</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The identifier of the snapshot exported by the command. The
+ snapshot is valid until a new command is executed on this connection
+ or the replication connection is closed. Null if the created slot
+ is physical.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>output_plugin</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The name of the output plugin used by the newly-created replication
+ slot. Null if the created slot is physical.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-create-replication-slot-legacy">
+ <term><literal>CREATE_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> [ <literal>TEMPORARY</literal> ] { <literal>PHYSICAL</literal> [ <literal>RESERVE_WAL</literal> ] | <literal>LOGICAL</literal> <replaceable class="parameter">output_plugin</replaceable> [ <literal>EXPORT_SNAPSHOT</literal> | <literal>NOEXPORT_SNAPSHOT</literal> | <literal>USE_SNAPSHOT</literal> | <literal>TWO_PHASE</literal> ] }
+ </term>
+ <listitem>
+ <para>
+ For compatibility with older releases, this alternative syntax for
+ the <literal>CREATE_REPLICATION_SLOT</literal> command is still supported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-read-replication-slot">
+ <term><literal>READ_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable>
+ <indexterm><primary>READ_REPLICATION_SLOT</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Read some information associated with a replication slot. Returns a tuple
+ with <literal>NULL</literal> values if the replication slot does not
+ exist. This command is currently only supported for physical replication
+ slots.
+ </para>
+
+ <para>
+ In response to this command, the server will return a one-row result set,
+ containing the following fields:
+ <variablelist>
+ <varlistentry>
+ <term><literal>slot_type</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The replication slot's type, either <literal>physical</literal> or
+ <literal>NULL</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>restart_lsn</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The replication slot's <literal>restart_lsn</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>restart_tli</literal> (<type>int8</type>)</term>
+ <listitem>
+ <para>
+ The timeline ID associated with <literal>restart_lsn</literal>,
+ following the current timeline history.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-start-replication">
+ <term><literal>START_REPLICATION</literal> [ <literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable> ] [ <literal>PHYSICAL</literal> ] <replaceable class="parameter">XXX/XXX</replaceable> [ <literal>TIMELINE</literal> <replaceable class="parameter">tli</replaceable> ]
+ <indexterm><primary>START_REPLICATION</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Instructs server to start streaming WAL, starting at
+ WAL location <replaceable class="parameter">XXX/XXX</replaceable>.
+ If <literal>TIMELINE</literal> option is specified,
+ streaming starts on timeline <replaceable class="parameter">tli</replaceable>;
+ otherwise, the server's current timeline is selected. The server can
+ reply with an error, for example if the requested section of WAL has already
+ been recycled. On success, the server responds with a CopyBothResponse
+ message, and then starts to stream WAL to the frontend.
+ </para>
+
+ <para>
+ If a slot's name is provided
+ via <replaceable class="parameter">slot_name</replaceable>, it will be updated
+ as replication progresses so that the server knows which WAL segments,
+ and if <varname>hot_standby_feedback</varname> is on which transactions,
+ are still needed by the standby.
+ </para>
+
+ <para>
+ If the client requests a timeline that's not the latest but is part of
+ the history of the server, the server will stream all the WAL on that
+ timeline starting from the requested start point up to the point where
+ the server switched to another timeline. If the client requests
+ streaming at exactly the end of an old timeline, the server skips COPY
+ mode entirely.
+ </para>
+
+ <para>
+ After streaming all the WAL on a timeline that is not the latest one,
+ the server will end streaming by exiting the COPY mode. When the client
+ acknowledges this by also exiting COPY mode, the server sends a result
+ set with one row and two columns, indicating the next timeline in this
+ server's history. The first column is the next timeline's ID (type <type>int8</type>), and the
+ second column is the WAL location where the switch happened (type <type>text</type>). Usually,
+ the switch position is the end of the WAL that was streamed, but there
+ are corner cases where the server can send some WAL from the old
+ timeline that it has not itself replayed before promoting. Finally, the
+ server sends two CommandComplete messages (one that ends the CopyData
+ and the other ends the <literal>START_REPLICATION</literal> itself), and
+ is ready to accept a new command.
+ </para>
+
+ <para>
+ WAL data is sent as a series of CopyData messages. (This allows
+ other information to be intermixed; in particular the server can send
+ an ErrorResponse message if it encounters a failure after beginning
+ to stream.) The payload of each CopyData message from server to the
+ client contains a message of one of the following formats:
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-replication-xlogdata">
+ <term>XLogData (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('w')</term>
+ <listitem>
+ <para>
+ Identifies the message as WAL data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The starting point of the WAL data in this message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The current end of WAL on the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ A section of the WAL data stream.
+ </para>
+
+ <para>
+ A single WAL record is never split across two XLogData messages.
+ When a WAL record crosses a WAL page boundary, and is therefore
+ already split using continuation records, it can be split at the page
+ boundary. In other words, the first main WAL record and its
+ continuation records can be sent in different XLogData messages.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-primary-keepalive-message">
+ <term>Primary keepalive message (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('k')</term>
+ <listitem>
+ <para>
+ Identifies the message as a sender keepalive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The current end of WAL on the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The server's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ 1 means that the client should reply to this message as soon as
+ possible, to avoid a timeout disconnect. 0 otherwise.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The receiving process can send replies back to the sender at any time,
+ using one of the following message formats (also in the payload of a
+ CopyData message):
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-replication-standby-status-update">
+ <term>Standby status update (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('r')</term>
+ <listitem>
+ <para>
+ Identifies the message as a receiver status update.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The location of the last WAL byte + 1 received and written to disk
+ in the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The location of the last WAL byte + 1 flushed to disk in
+ the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The location of the last WAL byte + 1 applied in the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ If 1, the client requests the server to reply to this message
+ immediately. This can be used to ping the server, to test if
+ the connection is still healthy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-hot-standby-feedback-message">
+ <term>Hot standby feedback message (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('h')</term>
+ <listitem>
+ <para>
+ Identifies the message as a hot standby feedback message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem>
+ <para>
+ The client's system clock at the time of transmission, as
+ microseconds since midnight on 2000-01-01.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The standby's current global xmin, excluding the catalog_xmin from any
+ replication slots. If both this value and the following
+ catalog_xmin are 0 this is treated as a notification that hot standby
+ feedback will no longer be sent on this connection. Later non-zero
+ messages may reinitiate the feedback mechanism.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The epoch of the global xmin xid on the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The lowest catalog_xmin of any replication slots on the standby. Set to 0
+ if no catalog_xmin exists on the standby or if hot standby feedback is being
+ disabled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The epoch of the catalog_xmin xid on the standby.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-start-replication-slot-logical">
+ <term><literal>START_REPLICATION</literal> <literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable> <literal>LOGICAL</literal> <replaceable class="parameter">XXX/XXX</replaceable> [ ( <replaceable>option_name</replaceable> [ <replaceable>option_value</replaceable> ] [, ...] ) ]</term>
+ <listitem>
+ <para>
+ Instructs server to start streaming WAL for logical replication,
+ starting at either WAL location <replaceable
+ class="parameter">XXX/XXX</replaceable> or the slot's
+ <literal>confirmed_flush_lsn</literal> (see <xref
+ linkend="view-pg-replication-slots"/>), whichever is greater. This
+ behavior makes it easier for clients to avoid updating their local LSN
+ status when there is no data to process. However, starting at a
+ different LSN than requested might not catch certain kinds of client
+ errors; so the client may wish to check that
+ <literal>confirmed_flush_lsn</literal> matches its expectations before
+ issuing <literal>START_REPLICATION</literal>.
+ </para>
+
+ <para>
+ The server can reply with an error, for example if the
+ slot does not exist. On success, the server responds with a CopyBothResponse
+ message, and then starts to stream WAL to the frontend.
+ </para>
+
+ <para>
+ The messages inside the CopyBothResponse messages are of the same format
+ documented for <literal>START_REPLICATION ... PHYSICAL</literal>, including
+ two CommandComplete messages.
+ </para>
+
+ <para>
+ The output plugin associated with the selected slot is used
+ to process the output for streaming.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the slot to stream changes from. This parameter is required,
+ and must correspond to an existing logical replication slot created
+ with <literal>CREATE_REPLICATION_SLOT</literal> in
+ <literal>LOGICAL</literal> mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">XXX/XXX</replaceable></term>
+ <listitem>
+ <para>
+ The WAL location to begin streaming at.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">option_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an option passed to the slot's logical decoding plugin.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">option_value</replaceable></term>
+ <listitem>
+ <para>
+ Optional value, in the form of a string constant, associated with the
+ specified option.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-drop-replication-slot">
+ <term>
+ <literal>DROP_REPLICATION_SLOT</literal> <replaceable class="parameter">slot_name</replaceable> <optional> <literal>WAIT</literal> </optional>
+ <indexterm><primary>DROP_REPLICATION_SLOT</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Drops a replication slot, freeing any reserved server-side resources.
+ If the slot is a logical slot that was created in a database other than
+ the database the walsender is connected to, this command fails.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">slot_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the slot to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAIT</literal></term>
+ <listitem>
+ <para>
+ This option causes the command to wait if the slot is active until
+ it becomes inactive, instead of the default behavior of raising an
+ error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-replication-base-backup" xreflabel="BASE_BACKUP">
+ <term><literal>BASE_BACKUP</literal> [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ]
+ <indexterm><primary>BASE_BACKUP</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ Instructs the server to start streaming a base backup.
+ The system will automatically be put in backup mode before the backup
+ is started, and taken out of it when the backup is complete. The
+ following options are accepted:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>LABEL</literal> <replaceable>'label'</replaceable></term>
+ <listitem>
+ <para>
+ Sets the label of the backup. If none is specified, a backup label
+ of <literal>base backup</literal> will be used. The quoting rules
+ for the label are the same as a standard SQL string with
+ <xref linkend="guc-standard-conforming-strings"/> turned on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TARGET</literal> <replaceable>'target'</replaceable></term>
+ <listitem>
+ <para>
+ Tells the server where to send the backup. If the target is
+ <literal>client</literal>, which is the default, the backup data is
+ sent to the client. If it is <literal>server</literal>, the backup
+ data is written to the server at the pathname specified by the
+ <literal>TARGET_DETAIL</literal> option. If it is
+ <literal>blackhole</literal>, the backup data is not sent
+ anywhere; it is simply discarded.
+ </para>
+
+ <para>
+ The <literal>server</literal> target requires superuser privilege or
+ being granted the <literal>pg_write_server_files</literal> role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TARGET_DETAIL</literal> <replaceable>'detail'</replaceable></term>
+ <listitem>
+ <para>
+ Provides additional information about the backup target.
+ </para>
+
+ <para>
+ Currently, this option can only be used when the backup target is
+ <literal>server</literal>. It specifies the server directory
+ to which the backup should be written.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROGRESS [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If set to true, request information required to generate a progress
+ report. This will send back an approximate size in the header of each
+ tablespace, which can be used to calculate how far along the stream
+ is done. This is calculated by enumerating all the file sizes once
+ before the transfer is even started, and might as such have a
+ negative impact on the performance. In particular, it might take
+ longer before the first data
+ is streamed. Since the database files can change during the backup,
+ the size is only approximate and might both grow and shrink between
+ the time of approximation and the sending of the actual files.
+ The default is false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CHECKPOINT { 'fast' | 'spread' }</literal></term>
+ <listitem>
+ <para>
+ Sets the type of checkpoint to be performed at the beginning of the
+ base backup. The default is <literal>spread</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAL [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If set to true, include the necessary WAL segments in the backup.
+ This will include all the files between start and stop backup in the
+ <filename>pg_wal</filename> directory of the base directory tar
+ file. The default is false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAIT [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If set to true, the backup will wait until the last required WAL
+ segment has been archived, or emit a warning if log archiving is
+ not enabled. If false, the backup will neither wait nor warn,
+ leaving the client responsible for ensuring the required log is
+ available. The default is true.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COMPRESSION</literal> <replaceable>'method'</replaceable></term>
+ <listitem>
+ <para>
+ Instructs the server to compress the backup using the specified
+ method. Currently, the supported methods are <literal>gzip</literal>,
+ <literal>lz4</literal>, and <literal>zstd</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COMPRESSION_DETAIL</literal> <replaceable>detail</replaceable></term>
+ <listitem>
+ <para>
+ Specifies details for the chosen compression method. This should only
+ be used in conjunction with the <literal>COMPRESSION</literal>
+ option. If the value is an integer, it specifies the compression
+ level. Otherwise, it should be a comma-separated list of items,
+ each of the form <replaceable>keyword</replaceable> or
+ <replaceable>keyword=value</replaceable>. Currently, the supported
+ keywords are <literal>level</literal> and <literal>workers</literal>.
+ </para>
+
+ <para>
+ The <literal>level</literal> keyword sets the compression level.
+ For <literal>gzip</literal> the compression level should be an
+ integer between <literal>1</literal> and <literal>9</literal>
+ (default <literal>Z_DEFAULT_COMPRESSION</literal> or
+ <literal>-1</literal>), for <literal>lz4</literal> an integer
+ between 1 and 12 (default <literal>0</literal> for fast compression
+ mode), and for <literal>zstd</literal> an integer between
+ <literal>ZSTD_minCLevel()</literal> (usually <literal>-131072</literal>)
+ and <literal>ZSTD_maxCLevel()</literal> (usually <literal>22</literal>),
+ (default <literal>ZSTD_CLEVEL_DEFAULT</literal> or
+ <literal>3</literal>).
+ </para>
+
+ <para>
+ The <literal>workers</literal> keyword sets the number of threads
+ that should be used for parallel compression. Parallel compression
+ is supported only for <literal>zstd</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MAX_RATE</literal> <replaceable>rate</replaceable></term>
+ <listitem>
+ <para>
+ Limit (throttle) the maximum amount of data transferred from server
+ to client per unit of time. The expected unit is kilobytes per second.
+ If this option is specified, the value must either be equal to zero
+ or it must fall within the range from 32 kB through 1 GB (inclusive).
+ If zero is passed or the option is not specified, no restriction is
+ imposed on the transfer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLESPACE_MAP [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If true, include information about symbolic links present in the
+ directory <filename>pg_tblspc</filename> in a file named
+ <filename>tablespace_map</filename>. The tablespace map file includes
+ each symbolic link name as it exists in the directory
+ <filename>pg_tblspc/</filename> and the full path of that symbolic link.
+ The default is false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VERIFY_CHECKSUMS [ <replaceable class="parameter">boolean</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ If true, checksums are verified during a base backup if they are
+ enabled. If false, this is skipped. The default is true.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MANIFEST</literal> <replaceable>manifest_option</replaceable></term>
+ <listitem>
+ <para>
+ When this option is specified with a value of <literal>yes</literal>
+ or <literal>force-encode</literal>, a backup manifest is created
+ and sent along with the backup. The manifest is a list of every
+ file present in the backup with the exception of any WAL files that
+ may be included. It also stores the size, last modification time, and
+ optionally a checksum for each file.
+ A value of <literal>force-encode</literal> forces all filenames
+ to be hex-encoded; otherwise, this type of encoding is performed only
+ for files whose names are non-UTF8 octet sequences.
+ <literal>force-encode</literal> is intended primarily for testing
+ purposes, to be sure that clients which read the backup manifest
+ can handle this case. For compatibility with previous releases,
+ the default is <literal>MANIFEST 'no'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MANIFEST_CHECKSUMS</literal> <replaceable>checksum_algorithm</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the checksum algorithm that should be applied to each file included
+ in the backup manifest. Currently, the available
+ algorithms are <literal>NONE</literal>, <literal>CRC32C</literal>,
+ <literal>SHA224</literal>, <literal>SHA256</literal>,
+ <literal>SHA384</literal>, and <literal>SHA512</literal>.
+ The default is <literal>CRC32C</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ When the backup is started, the server will first send two
+ ordinary result sets, followed by one or more CopyOutResponse
+ results.
+ </para>
+
+ <para>
+ The first ordinary result set contains the starting position of the
+ backup, in a single row with two columns. The first column contains
+ the start position given in XLogRecPtr format, and the second column
+ contains the corresponding timeline ID.
+ </para>
+
+ <para>
+ The second ordinary result set has one row for each tablespace.
+ The fields in this row are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>spcoid</literal> (<type>oid</type>)</term>
+ <listitem>
+ <para>
+ The OID of the tablespace, or null if it's the base
+ directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>spclocation</literal> (<type>text</type>)</term>
+ <listitem>
+ <para>
+ The full path of the tablespace directory, or null
+ if it's the base directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>size</literal> (<type>int8</type>)</term>
+ <listitem>
+ <para>
+ The approximate size of the tablespace, in kilobytes (1024 bytes),
+ if progress report has been requested; otherwise it's null.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ After the second regular result set, a CopyOutResponse will be sent.
+ The payload of each CopyData message will contain a message in one of
+ the following formats:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>new archive (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('n')</term>
+ <listitem><para>
+ Identifies the message as indicating the start of a new archive.
+ There will be one archive for the main data directory and one
+ for each additional tablespace; each will use tar format
+ (following the <quote>ustar interchange format</quote> specified
+ in the POSIX 1003.1-2008 standard).
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem><para>
+ The file name for this archive.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem><para>
+ For the main data directory, an empty string. For other
+ tablespaces, the full path to the directory from which this
+ archive was created.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>manifest (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('m')</term>
+ <listitem><para>
+ Identifies the message as indicating the start of the backup
+ manifest.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>archive or manifest data (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('d')</term>
+ <listitem><para>
+ Identifies the message as containing archive or manifest data.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem><para>
+ Data bytes.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>progress report (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem><para>
+ Identifies the message as a progress report.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64</term>
+ <listitem><para>
+ The number of bytes from the current tablespace for which
+ processing has been completed.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ After the CopyOutResponse, or all such responses, have been sent, a
+ final ordinary result set will be sent, containing the WAL end position
+ of the backup, in the same format as the start position.
+ </para>
+
+ <para>
+ The tar archive for the data directory and each tablespace will contain
+ all files in the directories, regardless of whether they are
+ <productname>PostgreSQL</productname> files or other files added to the same
+ directory. The only excluded files are:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <filename>postmaster.pid</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>postmaster.opts</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_internal.init</filename> (found in multiple directories)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Various temporary files and directories created during the operation
+ of the PostgreSQL server, such as any file or directory beginning
+ with <filename>pgsql_tmp</filename> and temporary relations.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Unlogged relations, except for the init fork which is required to
+ recreate the (empty) unlogged relation on recovery.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_wal</filename>, including subdirectories. If the backup is run
+ with WAL files included, a synthesized version of <filename>pg_wal</filename> will be
+ included, but it will only contain the files necessary for the
+ backup to work, not the rest of the contents.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <filename>pg_dynshmem</filename>, <filename>pg_notify</filename>,
+ <filename>pg_replslot</filename>, <filename>pg_serial</filename>,
+ <filename>pg_snapshots</filename>, <filename>pg_stat_tmp</filename>, and
+ <filename>pg_subtrans</filename> are copied as empty directories (even if
+ they are symbolic links).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Files other than regular files and directories, such as symbolic
+ links (other than for the directories listed above) and special
+ device files, are skipped. (Symbolic links
+ in <filename>pg_tblspc</filename> are maintained.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ Owner, group, and file mode are set if the underlying file system on
+ the server supports it.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </sect1>
+
+<sect1 id="protocol-logical-replication">
+ <title>Logical Streaming Replication Protocol</title>
+
+ <para>
+ This section describes the logical replication protocol, which is the message
+ flow started by the <literal>START_REPLICATION</literal>
+ <literal>SLOT</literal> <replaceable class="parameter">slot_name</replaceable>
+ <literal>LOGICAL</literal> replication command.
+ </para>
+
+ <para>
+ The logical streaming replication protocol builds on the primitives of
+ the physical streaming replication protocol.
+ </para>
+
+ <sect2 id="protocol-logical-replication-params">
+ <title>Logical Streaming Replication Parameters</title>
+
+ <para>
+ The logical replication <literal>START_REPLICATION</literal> command
+ accepts following parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ proto_version
+ </term>
+ <listitem>
+ <para>
+ Protocol version. Currently versions <literal>1</literal>, <literal>2</literal>,
+ and <literal>3</literal> are supported.
+ </para>
+ <para>
+ Version <literal>2</literal> is supported only for server version 14
+ and above, and it allows streaming of large in-progress transactions.
+ </para>
+ <para>
+ Version <literal>3</literal> is supported only for server version 15
+ and above, and it allows streaming of two-phase commits.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ publication_names
+ </term>
+ <listitem>
+ <para>
+ Comma separated list of publication names for which to subscribe
+ (receive changes). The individual publication names are treated
+ as standard objects names and can be quoted the same as needed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </sect2>
+
+ <sect2 id="protocol-logical-messages">
+ <title>Logical Replication Protocol Messages</title>
+
+ <para>
+ The individual protocol messages are discussed in the following
+ subsections. Individual messages are described in
+ <xref linkend="protocol-logicalrep-message-formats"/>.
+ </para>
+
+ <para>
+ All top-level protocol messages begin with a message type byte.
+ While represented in code as a character, this is a signed byte with no
+ associated encoding.
+ </para>
+
+ <para>
+ Since the streaming replication protocol supplies a message length there
+ is no need for top-level protocol messages to embed a length in their
+ header.
+ </para>
+
+ </sect2>
+
+ <sect2 id="protocol-logical-messages-flow">
+ <title>Logical Replication Protocol Message Flow</title>
+
+ <para>
+ With the exception of the <literal>START_REPLICATION</literal> command and
+ the replay progress messages, all information flows only from the backend
+ to the frontend.
+ </para>
+
+ <para>
+ The logical replication protocol sends individual transactions one by one.
+ This means that all messages between a pair of Begin and Commit messages
+ belong to the same transaction. Similarly, all messages between a pair of
+ Begin Prepare and Prepare messages belong to the same transaction.
+ It also sends changes of large in-progress transactions between a pair of
+ Stream Start and Stream Stop messages. The last stream of such a transaction
+ contains a Stream Commit or Stream Abort message.
+ </para>
+
+ <para>
+ Every sent transaction contains zero or more DML messages (Insert,
+ Update, Delete). In case of a cascaded setup it can also contain Origin
+ messages. The origin message indicates that the transaction originated on
+ different replication node. Since a replication node in the scope of logical
+ replication protocol can be pretty much anything, the only identifier
+ is the origin name. It's downstream's responsibility to handle this as
+ needed (if needed). The Origin message is always sent before any DML
+ messages in the transaction.
+ </para>
+
+ <para>
+ Every DML message contains a relation OID, identifying the publisher's
+ relation that was acted on. Before the first DML message for a given
+ relation OID, a Relation message will be sent, describing the schema of
+ that relation. Subsequently, a new Relation message will be sent if
+ the relation's definition has changed since the last Relation message
+ was sent for it. (The protocol assumes that the client is capable of
+ remembering this metadata for as many relations as needed.)
+ </para>
+
+ <para>
+ Relation messages identify column types by their OIDs. In the case
+ of a built-in type, it is assumed that the client can look up that
+ type OID locally, so no additional data is needed. For a non-built-in
+ type OID, a Type message will be sent before the Relation message,
+ to provide the type name associated with that OID. Thus, a client that
+ needs to specifically identify the types of relation columns should
+ cache the contents of Type messages, and first consult that cache to
+ see if the type OID is defined there. If not, look up the type OID
+ locally.
+ </para>
+ </sect2>
+</sect1>
+
+ <sect1 id="protocol-message-types">
+ <title>Message Data Types</title>
+
+ <para>
+ This section describes the base data types used in messages.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int<replaceable>n</replaceable>(<replaceable>i</replaceable>)</term>
+ <listitem>
+ <para>
+ An <replaceable>n</replaceable>-bit integer in network byte
+ order (most significant byte first).
+ If <replaceable>i</replaceable> is specified it
+ is the exact value that will appear, otherwise the value
+ is variable. Eg. Int16, Int32(42).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int<replaceable>n</replaceable>[<replaceable>k</replaceable>]</term>
+ <listitem>
+ <para>
+ An array of <replaceable>k</replaceable>
+ <replaceable>n</replaceable>-bit integers, each in network
+ byte order. The array length <replaceable>k</replaceable>
+ is always determined by an earlier field in the message.
+ Eg. Int16[M].
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String(<replaceable>s</replaceable>)</term>
+ <listitem>
+ <para>
+ A null-terminated string (C-style string). There is no
+ specific length limitation on strings.
+ If <replaceable>s</replaceable> is specified it is the exact
+ value that will appear, otherwise the value is variable.
+ Eg. String, String("user").
+ </para>
+
+ <note>
+ <para>
+ <emphasis>There is no predefined limit</emphasis> on the length of a string
+ that can be returned by the backend. Good coding strategy for a frontend
+ is to use an expandable buffer so that anything that fits in memory can be
+ accepted. If that's not feasible, read the full string and discard trailing
+ characters that don't fit into your fixed-size buffer.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable>(<replaceable>c</replaceable>)</term>
+ <listitem>
+ <para>
+ Exactly <replaceable>n</replaceable> bytes. If the field
+ width <replaceable>n</replaceable> is not a constant, it is
+ always determinable from an earlier field in the message.
+ If <replaceable>c</replaceable> is specified it is the exact
+ value. Eg. Byte2, Byte1('\n').
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="protocol-message-formats">
+ <title>Message Formats</title>
+
+ <para>
+ This section describes the detailed format of each message. Each is marked to
+ indicate that it can be sent by a frontend (F), a backend (B), or both
+ (F &amp; B).
+ Notice that although each message includes a byte count at the beginning,
+ the message format is defined so that the message end can be found without
+ reference to the byte count. This aids validity checking. (The CopyData
+ message is an exception, because it forms part of a data stream; the contents
+ of any individual CopyData message cannot be interpretable on their own.)
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-message-formats-AuthenticationOk">
+ <term>AuthenticationOk (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(0)</term>
+ <listitem>
+ <para>
+ Specifies that the authentication was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationKerberosV5">
+ <term>AuthenticationKerberosV5 (B)</term>
+ <listitem>
+
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(2)</term>
+ <listitem>
+ <para>
+ Specifies that Kerberos V5 authentication is required.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationCleartextPassword">
+ <term>AuthenticationCleartextPassword (B)</term>
+ <listitem>
+
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(3)</term>
+ <listitem>
+ <para>
+ Specifies that a clear-text password is required.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationMD5Password">
+ <term>AuthenticationMD5Password (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(12)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(5)</term>
+ <listitem>
+ <para>
+ Specifies that an MD5-encrypted password is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte4</term>
+ <listitem>
+ <para>
+ The salt to use when encrypting the password.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationSCMCredential">
+ <term>AuthenticationSCMCredential (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(6)</term>
+ <listitem>
+ <para>
+ Specifies that an SCM credentials message is required.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationGSS">
+ <term>AuthenticationGSS (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(7)</term>
+ <listitem>
+ <para>
+ Specifies that GSSAPI authentication is required.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationGSSContinue">
+ <term>AuthenticationGSSContinue (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Specifies that this message contains GSSAPI or SSPI data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ GSSAPI or SSPI authentication data.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationSSPI">
+ <term>AuthenticationSSPI (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(9)</term>
+ <listitem>
+ <para>
+ Specifies that SSPI authentication is required.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationSASL">
+ <term>AuthenticationSASL (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(10)</term>
+ <listitem>
+ <para>
+ Specifies that SASL authentication is required.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The message body is a list of SASL authentication mechanisms, in the
+ server's order of preference. A zero byte is required as terminator after
+ the last authentication mechanism name. For each mechanism, there is the
+ following:
+
+ <variablelist>
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Name of a SASL authentication mechanism.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationSASLContinue">
+ <term>AuthenticationSASLContinue (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(11)</term>
+ <listitem>
+ <para>
+ Specifies that this message contains a SASL challenge.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ SASL data, specific to the SASL mechanism being used.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-AuthenticationSASLFinal">
+ <term>AuthenticationSASLFinal (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as an authentication request.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(12)</term>
+ <listitem>
+ <para>
+ Specifies that SASL authentication has completed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ SASL outcome "additional data", specific to the SASL mechanism
+ being used.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-BackendKeyData">
+ <term>BackendKeyData (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('K')</term>
+ <listitem>
+ <para>
+ Identifies the message as cancellation key data.
+ The frontend must save these values if it wishes to be
+ able to issue CancelRequest messages later.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(12)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The process ID of this backend.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The secret key of this backend.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Bind">
+ <term>Bind (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('B')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Bind command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the destination portal
+ (an empty string selects the unnamed portal).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the source prepared statement
+ (an empty string selects the unnamed prepared statement).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of parameter format codes that follow
+ (denoted <replaceable>C</replaceable> below).
+ This can be zero to indicate that there are no parameters
+ or that the parameters all use the default format (text);
+ or one, in which case the specified format code is applied
+ to all parameters; or it can equal the actual number of
+ parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16[<replaceable>C</replaceable>]</term>
+ <listitem>
+ <para>
+ The parameter format codes. Each must presently be
+ zero (text) or one (binary).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of parameter values that follow (possibly zero).
+ This must match the number of parameters needed by the query.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Next, the following pair of fields appear for each parameter:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The length of the parameter value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL parameter value.
+ No value bytes follow in the NULL case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ The value of the parameter, in the format indicated by the
+ associated format code.
+ <replaceable>n</replaceable> is the above length.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ After the last parameter, the following fields appear:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of result-column format codes that follow
+ (denoted <replaceable>R</replaceable> below).
+ This can be zero to indicate that there are no result columns
+ or that the result columns should all use the default format
+ (text);
+ or one, in which case the specified format code is applied
+ to all result columns (if any); or it can equal the actual
+ number of result columns of the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16[<replaceable>R</replaceable>]</term>
+ <listitem>
+ <para>
+ The result-column format codes. Each must presently be
+ zero (text) or one (binary).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-BindComplete">
+ <term>BindComplete (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('2')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Bind-complete indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CancelRequest">
+ <term>CancelRequest (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Int32(16)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(80877102)</term>
+ <listitem>
+ <para>
+ The cancel request code. The value is chosen to contain
+ <literal>1234</literal> in the most significant 16 bits, and <literal>5678</literal> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The process ID of the target backend.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The secret key for the target backend.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Close">
+ <term>Close (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('C')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Close command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ '<literal>S</literal>' to close a prepared statement; or
+ '<literal>P</literal>' to close a portal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the prepared statement or portal to close
+ (an empty string selects the unnamed prepared statement
+ or portal).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CloseComplete">
+ <term>CloseComplete (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('3')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Close-complete indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CommandComplete">
+ <term>CommandComplete (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('C')</term>
+ <listitem>
+ <para>
+ Identifies the message as a command-completed response.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The command tag. This is usually a single
+ word that identifies which SQL command was completed.
+ </para>
+
+ <para>
+ For an <command>INSERT</command> command, the tag is
+ <literal>INSERT <replaceable>oid</replaceable>
+ <replaceable>rows</replaceable></literal>, where
+ <replaceable>rows</replaceable> is the number of rows
+ inserted. <replaceable>oid</replaceable> used to be the object ID
+ of the inserted row if <replaceable>rows</replaceable> was 1
+ and the target table had OIDs, but OIDs system columns are
+ not supported anymore; therefore <replaceable>oid</replaceable>
+ is always 0.
+ </para>
+
+ <para>
+ For a <command>DELETE</command> command, the tag is
+ <literal>DELETE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows deleted.
+ </para>
+
+ <para>
+ For an <command>UPDATE</command> command, the tag is
+ <literal>UPDATE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows updated.
+ </para>
+
+ <para>
+ For a <command>MERGE</command> command, the tag is
+ <literal>MERGE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows inserted,
+ updated, or deleted.
+ </para>
+
+ <para>
+ For a <command>SELECT</command> or <command>CREATE TABLE AS</command>
+ command, the tag is <literal>SELECT <replaceable>rows</replaceable></literal>
+ where <replaceable>rows</replaceable> is the number of rows retrieved.
+ </para>
+
+ <para>
+ For a <command>MOVE</command> command, the tag is
+ <literal>MOVE <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows the
+ cursor's position has been changed by.
+ </para>
+
+ <para>
+ For a <command>FETCH</command> command, the tag is
+ <literal>FETCH <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows that
+ have been retrieved from the cursor.
+ </para>
+
+ <para>
+ For a <command>COPY</command> command, the tag is
+ <literal>COPY <replaceable>rows</replaceable></literal> where
+ <replaceable>rows</replaceable> is the number of rows copied.
+ (Note: the row count appears only in
+ <productname>PostgreSQL</productname> 8.2 and later.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CopyData">
+ <term>CopyData (F &amp; B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('d')</term>
+ <listitem>
+ <para>
+ Identifies the message as <command>COPY</command> data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ Data that forms part of a <command>COPY</command> data stream. Messages sent
+ from the backend will always correspond to single data rows,
+ but messages sent by frontends might divide the data stream
+ arbitrarily.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CopyDone">
+ <term>CopyDone (F &amp; B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('c')</term>
+ <listitem>
+ <para>
+ Identifies the message as a <command>COPY</command>-complete indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CopyFail">
+ <term>CopyFail (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('f')</term>
+ <listitem>
+ <para>
+ Identifies the message as a <command>COPY</command>-failure indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ An error message to report as the cause of failure.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CopyInResponse">
+ <term>CopyInResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('G')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Start Copy In response.
+ The frontend must now send copy-in data (if not
+ prepared to do so, send a CopyFail message).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ 0 indicates the overall <command>COPY</command> format is textual (rows
+ separated by newlines, columns separated by separator
+ characters, etc.).
+ 1 indicates the overall copy format is binary (similar
+ to DataRow format).
+ See <xref linkend="sql-copy"/>
+ for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of columns in the data to be copied
+ (denoted <replaceable>N</replaceable> below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16[<replaceable>N</replaceable>]</term>
+ <listitem>
+ <para>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CopyOutResponse">
+ <term>CopyOutResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('H')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Start Copy Out response.
+ This message will be followed by copy-out data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ 0 indicates the overall <command>COPY</command> format
+ is textual (rows separated by newlines, columns
+ separated by separator characters, etc.). 1 indicates
+ the overall copy format is binary (similar to DataRow
+ format). See <xref linkend="sql-copy"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of columns in the data to be copied
+ (denoted <replaceable>N</replaceable> below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16[<replaceable>N</replaceable>]</term>
+ <listitem>
+ <para>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-CopyBothResponse">
+ <term>CopyBothResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('W')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Start Copy Both response.
+ This message is used only for Streaming Replication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ 0 indicates the overall <command>COPY</command> format
+ is textual (rows separated by newlines, columns
+ separated by separator characters, etc.). 1 indicates
+ the overall copy format is binary (similar to DataRow
+ format). See <xref linkend="sql-copy"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of columns in the data to be copied
+ (denoted <replaceable>N</replaceable> below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16[<replaceable>N</replaceable>]</term>
+ <listitem>
+ <para>
+ The format codes to be used for each column.
+ Each must presently be zero (text) or one (binary).
+ All must be zero if the overall copy format is textual.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-DataRow">
+ <term>DataRow (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('D')</term>
+ <listitem>
+ <para>
+ Identifies the message as a data row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of column values that follow (possibly zero).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Next, the following pair of fields appear for each column:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The length of the column value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL column value.
+ No value bytes follow in the NULL case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ The value of the column, in the format indicated by the
+ associated format code.
+ <replaceable>n</replaceable> is the above length.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Describe">
+ <term>Describe (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('D')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Describe command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ '<literal>S</literal>' to describe a prepared statement; or
+ '<literal>P</literal>' to describe a portal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the prepared statement or portal to describe
+ (an empty string selects the unnamed prepared statement
+ or portal).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-EmptyQueryResponse">
+ <term>EmptyQueryResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('I')</term>
+ <listitem>
+ <para>
+ Identifies the message as a response to an empty query string.
+ (This substitutes for CommandComplete.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-ErrorResponse">
+ <term>ErrorResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('E')</term>
+ <listitem>
+ <para>
+ Identifies the message as an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The message body consists of one or more identified fields,
+ followed by a zero byte as a terminator. Fields can appear in
+ any order. For each field there is the following:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ A code identifying the field type; if zero, this is
+ the message terminator and no string follows.
+ The presently defined field types are listed in
+ <xref linkend="protocol-error-fields"/>.
+ Since more field types might be added in future,
+ frontends should silently ignore fields of unrecognized
+ type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The field value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Execute">
+ <term>Execute (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('E')</term>
+ <listitem>
+ <para>
+ Identifies the message as an Execute command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the portal to execute
+ (an empty string selects the unnamed portal).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Maximum number of rows to return, if portal contains
+ a query that returns rows (ignored otherwise). Zero
+ denotes <quote>no limit</quote>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Flush">
+ <term>Flush (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('H')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Flush command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-FunctionCall">
+ <term>FunctionCall (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('F')</term>
+ <listitem>
+ <para>
+ Identifies the message as a function call.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Specifies the object ID of the function to call.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of argument format codes that follow
+ (denoted <replaceable>C</replaceable> below).
+ This can be zero to indicate that there are no arguments
+ or that the arguments all use the default format (text);
+ or one, in which case the specified format code is applied
+ to all arguments; or it can equal the actual number of
+ arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16[<replaceable>C</replaceable>]</term>
+ <listitem>
+ <para>
+ The argument format codes. Each must presently be
+ zero (text) or one (binary).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ Specifies the number of arguments being supplied to the
+ function.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Next, the following pair of fields appear for each argument:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The length of the argument value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL argument value.
+ No value bytes follow in the NULL case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ The value of the argument, in the format indicated by the
+ associated format code.
+ <replaceable>n</replaceable> is the above length.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ After the last argument, the following field appears:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The format code for the function result. Must presently be
+ zero (text) or one (binary).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-FunctionCallResponse">
+ <term>FunctionCallResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('V')</term>
+ <listitem>
+ <para>
+ Identifies the message as a function call result.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The length of the function result value, in bytes (this count
+ does not include itself). Can be zero.
+ As a special case, -1 indicates a NULL function result.
+ No value bytes follow in the NULL case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ The value of the function result, in the format indicated by
+ the associated format code.
+ <replaceable>n</replaceable> is the above length.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-GSSENCRequest">
+ <term>GSSENCRequest (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(80877104)</term>
+ <listitem>
+ <para>
+ The <acronym>GSSAPI</acronym> Encryption request code. The value is chosen to contain
+ <literal>1234</literal> in the most significant 16 bits, and <literal>5680</literal> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-GSSResponse">
+ <term>GSSResponse (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem>
+ <para>
+ Identifies the message as a GSSAPI or SSPI response. Note that
+ this is also used for SASL and password response messages.
+ The exact message type can be deduced from the context.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ GSSAPI/SSPI specific message data.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-NegotiateProtocolVersion">
+ <term>NegotiateProtocolVersion (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('v')</term>
+ <listitem>
+ <para>
+ Identifies the message as a protocol version negotiation
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Newest minor protocol version supported by the server
+ for the major protocol version requested by the client.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Number of protocol options not recognized by the server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Then, for protocol option not recognized by the server, there
+ is the following:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The option name.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-NoData">
+ <term>NoData (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('n')</term>
+ <listitem>
+ <para>
+ Identifies the message as a no-data indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-NoticeResponse">
+ <term>NoticeResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('N')</term>
+ <listitem>
+ <para>
+ Identifies the message as a notice.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The message body consists of one or more identified fields,
+ followed by a zero byte as a terminator. Fields can appear in
+ any order. For each field there is the following:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ A code identifying the field type; if zero, this is
+ the message terminator and no string follows.
+ The presently defined field types are listed in
+ <xref linkend="protocol-error-fields"/>.
+ Since more field types might be added in future,
+ frontends should silently ignore fields of unrecognized
+ type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The field value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-NotificationResponse">
+ <term>NotificationResponse (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('A')</term>
+ <listitem>
+ <para>
+ Identifies the message as a notification response.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The process ID of the notifying backend process.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the channel that the notify has been raised on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The <quote>payload</quote> string passed from the notifying process.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-ParameterDescription">
+ <term>ParameterDescription (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('t')</term>
+ <listitem>
+ <para>
+ Identifies the message as a parameter description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of parameters used by the statement
+ (can be zero).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Then, for each parameter, there is the following:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Specifies the object ID of the parameter data type.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-ParameterStatus">
+ <term>ParameterStatus (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('S')</term>
+ <listitem>
+ <para>
+ Identifies the message as a run-time parameter status report.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the run-time parameter being reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The current value of the parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Parse">
+ <term>Parse (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('P')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Parse command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The name of the destination prepared statement
+ (an empty string selects the unnamed prepared statement).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The query string to be parsed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The number of parameter data types specified
+ (can be zero). Note that this is not an indication of
+ the number of parameters that might appear in the
+ query string, only the number that the frontend wants to
+ prespecify types for.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Then, for each parameter, there is the following:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Specifies the object ID of the parameter data type.
+ Placing a zero here is equivalent to leaving the type
+ unspecified.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-ParseComplete">
+ <term>ParseComplete (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('1')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Parse-complete indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-PasswordMessage">
+ <term>PasswordMessage (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem>
+ <para>
+ Identifies the message as a password response. Note that
+ this is also used for GSSAPI, SSPI and SASL response messages.
+ The exact message type can be deduced from the context.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The password (encrypted, if requested).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-PortalSuspended">
+ <term>PortalSuspended (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('s')</term>
+ <listitem>
+ <para>
+ Identifies the message as a portal-suspended indicator.
+ Note this only appears if an Execute message's row-count limit
+ was reached.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Query">
+ <term>Query (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('Q')</term>
+ <listitem>
+ <para>
+ Identifies the message as a simple query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The query string itself.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-ReadyForQuery">
+ <term>ReadyForQuery (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('Z')</term>
+ <listitem>
+ <para>
+ Identifies the message type. ReadyForQuery is sent
+ whenever the backend is ready for a new query cycle.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(5)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1</term>
+ <listitem>
+ <para>
+ Current backend transaction status indicator.
+ Possible values are '<literal>I</literal>' if idle (not in
+ a transaction block); '<literal>T</literal>' if in a transaction
+ block; or '<literal>E</literal>' if in a failed transaction
+ block (queries will be rejected until block is ended).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-RowDescription">
+ <term>RowDescription (B)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('T')</term>
+ <listitem>
+ <para>
+ Identifies the message as a row description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ Specifies the number of fields in a row (can be zero).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Then, for each field, there is the following:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The field name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ If the field can be identified as a column of a specific
+ table, the object ID of the table; otherwise zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ If the field can be identified as a column of a specific
+ table, the attribute number of the column; otherwise zero.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The object ID of the field's data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The data type size (see <varname>pg_type.typlen</varname>).
+ Note that negative values denote variable-width types.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ The type modifier (see <varname>pg_attribute.atttypmod</varname>).
+ The meaning of the modifier is type-specific.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ The format code being used for the field. Currently will
+ be zero (text) or one (binary). In a RowDescription
+ returned from the statement variant of Describe, the
+ format code is not yet known and will always be zero.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-SASLInitialResponse">
+ <term>SASLInitialResponse (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem>
+ <para>
+ Identifies the message as an initial SASL response. Note that
+ this is also used for GSSAPI, SSPI and password response messages.
+ The exact message type is deduced from the context.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Name of the SASL authentication mechanism that the client
+ selected.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of SASL mechanism specific "Initial Client Response" that
+ follows, or -1 if there is no Initial Response.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ SASL mechanism specific "Initial Response".
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-SASLResponse">
+ <term>SASLResponse (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem>
+ <para>
+ Identifies the message as a SASL response. Note that
+ this is also used for GSSAPI, SSPI and password response messages.
+ The exact message type can be deduced from the context.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ SASL mechanism specific message data.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-SSLRequest">
+ <term>SSLRequest (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Int32(8)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(80877103)</term>
+ <listitem>
+ <para>
+ The <acronym>SSL</acronym> request code. The value is chosen to contain
+ <literal>1234</literal> in the most significant 16 bits, and <literal>5679</literal> in the
+ least significant 16 bits. (To avoid confusion, this code
+ must not be the same as any protocol version number.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-StartupMessage">
+ <term>StartupMessage (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(196608)</term>
+ <listitem>
+ <para>
+ The protocol version number. The most significant 16 bits are
+ the major version number (3 for the protocol described here).
+ The least significant 16 bits are the minor version number
+ (0 for the protocol described here).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The protocol version number is followed by one or more pairs of
+ parameter name and value strings. A zero byte is required as a
+ terminator after the last name/value pair.
+ Parameters can appear in any
+ order. <literal>user</literal> is required, others are optional.
+ Each parameter is specified as:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The parameter name. Currently recognized names are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>user</literal></term>
+ <listitem>
+ <para>
+ The database user name to connect as. Required;
+ there is no default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>database</literal></term>
+ <listitem>
+ <para>
+ The database to connect to. Defaults to the user name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>options</literal></term>
+ <listitem>
+ <para>
+ Command-line arguments for the backend. (This is
+ deprecated in favor of setting individual run-time
+ parameters.) Spaces within this string are
+ considered to separate arguments, unless escaped with
+ a backslash (<literal>\</literal>); write <literal>\\</literal> to
+ represent a literal backslash.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>replication</literal></term>
+ <listitem>
+ <para>
+ Used to connect in streaming replication mode, where
+ a small set of replication commands can be issued
+ instead of SQL statements. Value can be
+ <literal>true</literal>, <literal>false</literal>, or
+ <literal>database</literal>, and the default is
+ <literal>false</literal>. See
+ <xref linkend="protocol-replication"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ In addition to the above, other parameters may be listed.
+ Parameter names beginning with <literal>_pq_.</literal> are
+ reserved for use as protocol extensions, while others are
+ treated as run-time parameters to be set at backend start
+ time. Such settings will be applied during backend start
+ (after parsing the command-line arguments if any) and will
+ act as session defaults.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The parameter value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Sync">
+ <term>Sync (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('S')</term>
+ <listitem>
+ <para>
+ Identifies the message as a Sync command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-message-formats-Terminate">
+ <term>Terminate (F)</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('X')</term>
+ <listitem>
+ <para>
+ Identifies the message as a termination.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32(4)</term>
+ <listitem>
+ <para>
+ Length of message contents in bytes, including self.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="protocol-error-fields">
+ <title>Error and Notice Message Fields</title>
+
+ <para>
+ This section describes the fields that can appear in ErrorResponse and
+ NoticeResponse messages. Each field type has a single-byte identification
+ token. Note that any given field type should appear at most once per
+ message.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>S</literal></term>
+ <listitem>
+ <para>
+ Severity: the field contents are
+ <literal>ERROR</literal>, <literal>FATAL</literal>, or
+ <literal>PANIC</literal> (in an error message), or
+ <literal>WARNING</literal>, <literal>NOTICE</literal>, <literal>DEBUG</literal>,
+ <literal>INFO</literal>, or <literal>LOG</literal> (in a notice message),
+ or a localized translation of one of these. Always present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>V</literal></term>
+ <listitem>
+ <para>
+ Severity: the field contents are
+ <literal>ERROR</literal>, <literal>FATAL</literal>, or
+ <literal>PANIC</literal> (in an error message), or
+ <literal>WARNING</literal>, <literal>NOTICE</literal>, <literal>DEBUG</literal>,
+ <literal>INFO</literal>, or <literal>LOG</literal> (in a notice message).
+ This is identical to the <literal>S</literal> field except
+ that the contents are never localized. This is present only in
+ messages generated by <productname>PostgreSQL</productname> versions 9.6
+ and later.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>C</literal></term>
+ <listitem>
+ <para>
+ Code: the SQLSTATE code for the error (see <xref
+ linkend="errcodes-appendix"/>). Not localizable. Always present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>M</literal></term>
+ <listitem>
+ <para>
+ Message: the primary human-readable error message.
+ This should be accurate but terse (typically one line).
+ Always present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>D</literal></term>
+ <listitem>
+ <para>
+ Detail: an optional secondary error message carrying more
+ detail about the problem. Might run to multiple lines.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>H</literal></term>
+ <listitem>
+ <para>
+ Hint: an optional suggestion what to do about the problem.
+ This is intended to differ from Detail in that it offers advice
+ (potentially inappropriate) rather than hard facts.
+ Might run to multiple lines.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>P</literal></term>
+ <listitem>
+ <para>
+ Position: the field value is a decimal ASCII integer, indicating
+ an error cursor position as an index into the original query string.
+ The first character has index 1, and positions are measured in
+ characters not bytes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>p</literal></term>
+ <listitem>
+ <para>
+ Internal position: this is defined the same as the <literal>P</literal>
+ field, but it is used when the cursor position refers to an internally
+ generated command rather than the one submitted by the client.
+ The <literal>q</literal> field will always appear when this field appears.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>q</literal></term>
+ <listitem>
+ <para>
+ Internal query: the text of a failed internally-generated command.
+ This could be, for example, an SQL query issued by a PL/pgSQL function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>W</literal></term>
+ <listitem>
+ <para>
+ Where: an indication of the context in which the error occurred.
+ Presently this includes a call stack traceback of active
+ procedural language functions and internally-generated queries.
+ The trace is one entry per line, most recent first.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>s</literal></term>
+ <listitem>
+ <para>
+ Schema name: if the error was associated with a specific database
+ object, the name of the schema containing that object, if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>t</literal></term>
+ <listitem>
+ <para>
+ Table name: if the error was associated with a specific table, the
+ name of the table. (Refer to the schema name field for the name of
+ the table's schema.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>c</literal></term>
+ <listitem>
+ <para>
+ Column name: if the error was associated with a specific table column,
+ the name of the column. (Refer to the schema and table name fields to
+ identify the table.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>d</literal></term>
+ <listitem>
+ <para>
+ Data type name: if the error was associated with a specific data type,
+ the name of the data type. (Refer to the schema name field for the
+ name of the data type's schema.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>n</literal></term>
+ <listitem>
+ <para>
+ Constraint name: if the error was associated with a specific
+ constraint, the name of the constraint. Refer to fields listed above
+ for the associated table or domain. (For this purpose, indexes are
+ treated as constraints, even if they weren't created with constraint
+ syntax.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>F</literal></term>
+ <listitem>
+ <para>
+ File: the file name of the source-code location where the error
+ was reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>L</literal></term>
+ <listitem>
+ <para>
+ Line: the line number of the source-code location where the error
+ was reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>R</literal></term>
+ <listitem>
+ <para>
+ Routine: the name of the source-code routine reporting the error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <note>
+ <para>
+ The fields for schema name, table name, column name, data type name, and
+ constraint name are supplied only for a limited number of error types;
+ see <xref linkend="errcodes-appendix"/>. Frontends should not assume that
+ the presence of any of these fields guarantees the presence of another
+ field. Core error sources observe the interrelationships noted above, but
+ user-defined functions may use these fields in other ways. In the same
+ vein, clients should not assume that these fields denote contemporary
+ objects in the current database.
+ </para>
+ </note>
+
+ <para>
+ The client is responsible for formatting displayed information to meet its
+ needs; in particular it should break long lines as needed. Newline characters
+ appearing in the error message fields should be treated as paragraph breaks,
+ not line breaks.
+ </para>
+ </sect1>
+
+ <sect1 id="protocol-logicalrep-message-formats">
+ <title>Logical Replication Message Formats</title>
+
+ <para>
+ This section describes the detailed format of each logical replication
+ message. These messages are either returned by the replication slot SQL
+ interface or are sent by a walsender. In the case of a walsender, they are
+ encapsulated inside replication protocol WAL messages as described in
+ <xref linkend="protocol-replication"/>, and generally obey the same message
+ flow as physical replication.
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-logicalrep-message-formats-Begin">
+ <term>Begin</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('B')</term>
+ <listitem>
+ <para>
+ Identifies the message as a begin message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The final LSN of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Message">
+ <term>Message</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('M')</term>
+ <listitem>
+ <para>
+ Identifies the message as a logical decoding message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ Flags; Either 0 for no flags or 1 if the logical decoding
+ message is transactional.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the logical decoding message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The prefix of the logical decoding message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of the content.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ The content of the logical decoding message.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Commit">
+ <term>Commit</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('C')</term>
+ <listitem>
+ <para>
+ Identifies the message as a commit message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8(0)</term>
+ <listitem>
+ <para>
+ Flags; currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the commit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Origin">
+ <term>Origin</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('O')</term>
+ <listitem>
+ <para>
+ Identifies the message as an origin message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the commit on the origin server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Name of the origin.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Note that there can be multiple Origin messages inside a single transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Relation">
+ <term>Relation</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('R')</term>
+ <listitem>
+ <para>
+ Identifies the message as a relation message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Namespace (empty string for <literal>pg_catalog</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Relation name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ Replica identity setting for the relation (same as
+ <structfield>relreplident</structfield> in <structname>pg_class</structname>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ Number of columns.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Next, the following message part appears for each column included in
+ the publication (except generated columns):
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ Flags for the column. Currently can be either 0 for no flags
+ or 1 which marks the column as part of the key.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Name of the column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the column's data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Type modifier of the column (<structfield>atttypmod</structfield>).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Type">
+ <term>Type</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('Y')</term>
+ <listitem>
+ <para>
+ Identifies the message as a type message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Namespace (empty string for <literal>pg_catalog</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ Name of the data type.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Insert">
+ <term>Insert</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('I')</term>
+ <listitem>
+ <para>
+ Identifies the message as an insert message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the relation corresponding to the ID in the relation
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1('N')</term>
+ <listitem>
+ <para>
+ Identifies the following TupleData message as a new tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>TupleData</term>
+ <listitem>
+ <para>
+ TupleData message part representing the contents of new tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Update">
+ <term>Update</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('U')</term>
+ <listitem>
+ <para>
+ Identifies the message as an update message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the relation corresponding to the ID in the relation
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1('K')</term>
+ <listitem>
+ <para>
+ Identifies the following TupleData submessage as a key.
+ This field is optional and is only present if
+ the update changed data in any of the column(s) that are
+ part of the REPLICA IDENTITY index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1('O')</term>
+ <listitem>
+ <para>
+ Identifies the following TupleData submessage as an old tuple.
+ This field is optional and is only present if table in which
+ the update happened has REPLICA IDENTITY set to FULL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>TupleData</term>
+ <listitem>
+ <para>
+ TupleData message part representing the contents of the old tuple
+ or primary key. Only present if the previous 'O' or 'K' part
+ is present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1('N')</term>
+ <listitem>
+ <para>
+ Identifies the following TupleData message as a new tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>TupleData</term>
+ <listitem>
+ <para>
+ TupleData message part representing the contents of a new tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The Update message may contain either a 'K' message part or an 'O' message part
+ or neither of them, but never both of them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Delete">
+ <term>Delete</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('D')</term>
+ <listitem>
+ <para>
+ Identifies the message as a delete message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the relation corresponding to the ID in the relation
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1('K')</term>
+ <listitem>
+ <para>
+ Identifies the following TupleData submessage as a key.
+ This field is present if the table in which the delete has
+ happened uses an index as REPLICA IDENTITY.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte1('O')</term>
+ <listitem>
+ <para>
+ Identifies the following TupleData message as an old tuple.
+ This field is present if the table in which the delete
+ happened has REPLICA IDENTITY set to FULL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>TupleData</term>
+ <listitem>
+ <para>
+ TupleData message part representing the contents of the old tuple
+ or primary key, depending on the previous field.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The Delete message may contain either a 'K' message part or an 'O' message part,
+ but never both of them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Truncate">
+ <term>Truncate</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('T')</term>
+ <listitem>
+ <para>
+ Identifies the message as a truncate message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction (only present for streamed transactions).
+ This field is available since protocol version 2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Number of relations
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ Option bits for <command>TRUNCATE</command>:
+ 1 for <literal>CASCADE</literal>, 2 for <literal>RESTART IDENTITY</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (Oid)</term>
+ <listitem>
+ <para>
+ OID of the relation corresponding to the ID in the relation
+ message. This field is repeated for each relation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The following messages (Stream Start, Stream Stop, Stream Commit, and
+ Stream Abort) are available since protocol version 2.
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-logicalrep-message-formats-Stream-Start">
+ <term>Stream Start</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('S')</term>
+ <listitem>
+ <para>
+ Identifies the message as a stream start message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8</term>
+ <listitem>
+ <para>
+ A value of 1 indicates this is the first stream segment for
+ this XID, 0 for any other stream segment.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Stream-Stop">
+ <term>Stream Stop</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('E')</term>
+ <listitem>
+ <para>
+ Identifies the message as a stream stop message.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Stream-Commit">
+ <term>Stream Commit</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('c')</term>
+ <listitem>
+ <para>
+ Identifies the message as a stream commit message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8(0)</term>
+ <listitem>
+ <para>
+ Flags; currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the commit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Stream-Abort">
+ <term>Stream Abort</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('A')</term>
+ <listitem>
+ <para>
+ Identifies the message as a stream abort message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the subtransaction (will be same as xid of the transaction for top-level
+ transactions).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The following messages (Begin Prepare, Prepare, Commit Prepared, Rollback Prepared, Stream Prepare)
+ are available since protocol version 3.
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-logicalrep-message-formats-Begin-Prepare">
+ <term>Begin Prepare</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('b')</term>
+ <listitem>
+ <para>
+ Identifies the message as the beginning of a prepared transaction message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the prepare.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The user defined GID of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Prepare">
+ <term>Prepare</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('P')</term>
+ <listitem>
+ <para>
+ Identifies the message as a prepared transaction message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8(0)</term>
+ <listitem>
+ <para>
+ Flags; currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the prepare.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The user defined GID of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Commit-Prepared">
+ <term>Commit Prepared</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('K')</term>
+ <listitem>
+ <para>
+ Identifies the message as the commit of a prepared transaction message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8(0)</term>
+ <listitem>
+ <para>
+ Flags; currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the commit of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the commit of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Commit timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The user defined GID of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Rollback-Prepared">
+ <term>Rollback Prepared</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('r')</term>
+ <listitem>
+ <para>
+ Identifies the message as the rollback of a prepared transaction message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8(0)</term>
+ <listitem>
+ <para>
+ Flags; currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the rollback of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Rollback timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The user defined GID of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="protocol-logicalrep-message-formats-Stream-Prepare">
+ <term>Stream Prepare</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('p')</term>
+ <listitem>
+ <para>
+ Identifies the message as a stream prepared transaction message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int8(0)</term>
+ <listitem>
+ <para>
+ Flags; currently unused.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The LSN of the prepare.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (XLogRecPtr)</term>
+ <listitem>
+ <para>
+ The end LSN of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int64 (TimestampTz)</term>
+ <listitem>
+ <para>
+ Prepare timestamp of the transaction. The value is in number
+ of microseconds since PostgreSQL epoch (2000-01-01).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32 (TransactionId)</term>
+ <listitem>
+ <para>
+ Xid of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>String</term>
+ <listitem>
+ <para>
+ The user defined GID of the prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The following message parts are shared by the above messages.
+ </para>
+
+ <variablelist>
+ <varlistentry id="protocol-logicalrep-message-formats-TupleData">
+ <term>TupleData</term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Int16</term>
+ <listitem>
+ <para>
+ Number of columns.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Next, one of the following submessages appears for each column (except generated columns):
+
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('n')</term>
+ <listitem>
+ <para>
+ Identifies the data as NULL value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ Or
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('u')</term>
+ <listitem>
+ <para>
+ Identifies unchanged TOASTed value (the actual value is not
+ sent).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ Or
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('t')</term>
+ <listitem>
+ <para>
+ Identifies the data as text formatted value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ Or
+ <variablelist>
+ <varlistentry>
+ <term>Byte1('b')</term>
+ <listitem>
+ <para>
+ Identifies the data as binary formatted value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Int32</term>
+ <listitem>
+ <para>
+ Length of the column value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Byte<replaceable>n</replaceable></term>
+ <listitem>
+ <para>
+ The value of the column, either in binary or in text format.
+ (As specified in the preceding format byte).
+ <replaceable>n</replaceable> is the above length.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect1>
+
+ <sect1 id="protocol-changes">
+ <title>Summary of Changes since Protocol 2.0</title>
+
+ <para>
+ This section provides a quick checklist of changes, for the benefit of
+ developers trying to update existing client libraries to protocol 3.0.
+ </para>
+
+ <para>
+ The initial startup packet uses a flexible list-of-strings format
+ instead of a fixed format. Notice that session default values for run-time
+ parameters can now be specified directly in the startup packet. (Actually,
+ you could do that before using the <literal>options</literal> field, but given the
+ limited width of <literal>options</literal> and the lack of any way to quote
+ whitespace in the values, it wasn't a very safe technique.)
+ </para>
+
+ <para>
+ All messages now have a length count immediately following the message type
+ byte (except for startup packets, which have no type byte). Also note that
+ PasswordMessage now has a type byte.
+ </para>
+
+ <para>
+ ErrorResponse and NoticeResponse ('<literal>E</literal>' and '<literal>N</literal>')
+ messages now contain multiple fields, from which the client code can
+ assemble an error message of the desired level of verbosity. Note that
+ individual fields will typically not end with a newline, whereas the single
+ string sent in the older protocol always did.
+ </para>
+
+ <para>
+ The ReadyForQuery ('<literal>Z</literal>') message includes a transaction status
+ indicator.
+ </para>
+
+ <para>
+ The distinction between BinaryRow and DataRow message types is gone; the
+ single DataRow message type serves for returning data in all formats.
+ Note that the layout of DataRow has changed to make it easier to parse.
+ Also, the representation of binary values has changed: it is no longer
+ directly tied to the server's internal representation.
+ </para>
+
+ <para>
+ There is a new <quote>extended query</quote> sub-protocol, which adds the frontend
+ message types Parse, Bind, Execute, Describe, Close, Flush, and Sync, and the
+ backend message types ParseComplete, BindComplete, PortalSuspended,
+ ParameterDescription, NoData, and CloseComplete. Existing clients do not
+ have to concern themselves with this sub-protocol, but making use of it
+ might allow improvements in performance or functionality.
+ </para>
+
+ <para>
+ <command>COPY</command> data is now encapsulated into CopyData and CopyDone messages. There
+ is a well-defined way to recover from errors during <command>COPY</command>. The special
+ <quote><literal>\.</literal></quote> last line is not needed anymore, and is not sent
+ during <command>COPY OUT</command>.
+ (It is still recognized as a terminator during <command>COPY IN</command>, but its use is
+ deprecated and will eventually be removed.) Binary <command>COPY</command> is supported.
+ The CopyInResponse and CopyOutResponse messages include fields indicating
+ the number of columns and the format of each column.
+ </para>
+
+ <para>
+ The layout of FunctionCall and FunctionCallResponse messages has changed.
+ FunctionCall can now support passing NULL arguments to functions. It also
+ can handle passing parameters and retrieving results in either text or
+ binary format. There is no longer any reason to consider FunctionCall a
+ potential security hole, since it does not offer direct access to internal
+ server data representations.
+ </para>
+
+ <para>
+ The backend sends ParameterStatus ('<literal>S</literal>') messages during connection
+ startup for all parameters it considers interesting to the client library.
+ Subsequently, a ParameterStatus message is sent whenever the active value
+ changes for any of these parameters.
+ </para>
+
+ <para>
+ The RowDescription ('<literal>T</literal>') message carries new table OID and column
+ number fields for each column of the described row. It also shows the format
+ code for each column.
+ </para>
+
+ <para>
+ The CursorResponse ('<literal>P</literal>') message is no longer generated by
+ the backend.
+ </para>
+
+ <para>
+ The NotificationResponse ('<literal>A</literal>') message has an additional string
+ field, which can carry a <quote>payload</quote> string passed
+ from the <command>NOTIFY</command> event sender.
+ </para>
+
+ <para>
+ The EmptyQueryResponse ('<literal>I</literal>') message used to include an empty
+ string parameter; this has been removed.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/queries.sgml b/doc/src/sgml/queries.sgml
new file mode 100644
index 0000000..c0d8415
--- /dev/null
+++ b/doc/src/sgml/queries.sgml
@@ -0,0 +1,2740 @@
+<!-- doc/src/sgml/queries.sgml -->
+
+<chapter id="queries">
+ <title>Queries</title>
+
+ <indexterm zone="queries">
+ <primary>query</primary>
+ </indexterm>
+
+ <indexterm zone="queries">
+ <primary>SELECT</primary>
+ </indexterm>
+
+ <para>
+ The previous chapters explained how to create tables, how to fill
+ them with data, and how to manipulate that data. Now we finally
+ discuss how to retrieve the data from the database.
+ </para>
+
+
+ <sect1 id="queries-overview">
+ <title>Overview</title>
+
+ <para>
+ The process of retrieving or the command to retrieve data from a
+ database is called a <firstterm>query</firstterm>. In SQL the
+ <link linkend="sql-select"><command>SELECT</command></link> command is
+ used to specify queries. The general syntax of the
+ <command>SELECT</command> command is
+<synopsis>
+<optional>WITH <replaceable>with_queries</replaceable></optional> SELECT <replaceable>select_list</replaceable> FROM <replaceable>table_expression</replaceable> <optional><replaceable>sort_specification</replaceable></optional>
+</synopsis>
+ The following sections describe the details of the select list, the
+ table expression, and the sort specification. <literal>WITH</literal>
+ queries are treated last since they are an advanced feature.
+ </para>
+
+ <para>
+ A simple kind of query has the form:
+<programlisting>
+SELECT * FROM table1;
+</programlisting>
+ Assuming that there is a table called <literal>table1</literal>,
+ this command would retrieve all rows and all user-defined columns from
+ <literal>table1</literal>. (The method of retrieval depends on the
+ client application. For example, the
+ <application>psql</application> program will display an ASCII-art
+ table on the screen, while client libraries will offer functions to
+ extract individual values from the query result.) The select list
+ specification <literal>*</literal> means all columns that the table
+ expression happens to provide. A select list can also select a
+ subset of the available columns or make calculations using the
+ columns. For example, if
+ <literal>table1</literal> has columns named <literal>a</literal>,
+ <literal>b</literal>, and <literal>c</literal> (and perhaps others) you can make
+ the following query:
+<programlisting>
+SELECT a, b + c FROM table1;
+</programlisting>
+ (assuming that <literal>b</literal> and <literal>c</literal> are of a numerical
+ data type).
+ See <xref linkend="queries-select-lists"/> for more details.
+ </para>
+
+ <para>
+ <literal>FROM table1</literal> is a simple kind of
+ table expression: it reads just one table. In general, table
+ expressions can be complex constructs of base tables, joins, and
+ subqueries. But you can also omit the table expression entirely and
+ use the <command>SELECT</command> command as a calculator:
+<programlisting>
+SELECT 3 * 4;
+</programlisting>
+ This is more useful if the expressions in the select list return
+ varying results. For example, you could call a function this way:
+<programlisting>
+SELECT random();
+</programlisting>
+ </para>
+ </sect1>
+
+
+ <sect1 id="queries-table-expressions">
+ <title>Table Expressions</title>
+
+ <indexterm zone="queries-table-expressions">
+ <primary>table expression</primary>
+ </indexterm>
+
+ <para>
+ A <firstterm>table expression</firstterm> computes a table. The
+ table expression contains a <literal>FROM</literal> clause that is
+ optionally followed by <literal>WHERE</literal>, <literal>GROUP BY</literal>, and
+ <literal>HAVING</literal> clauses. Trivial table expressions simply refer
+ to a table on disk, a so-called base table, but more complex
+ expressions can be used to modify or combine base tables in various
+ ways.
+ </para>
+
+ <para>
+ The optional <literal>WHERE</literal>, <literal>GROUP BY</literal>, and
+ <literal>HAVING</literal> clauses in the table expression specify a
+ pipeline of successive transformations performed on the table
+ derived in the <literal>FROM</literal> clause. All these transformations
+ produce a virtual table that provides the rows that are passed to
+ the select list to compute the output rows of the query.
+ </para>
+
+ <sect2 id="queries-from">
+ <title>The <literal>FROM</literal> Clause</title>
+
+ <para>
+ The <link linkend="sql-from"><literal>FROM</literal></link> clause derives a
+ table from one or more other tables given in a comma-separated
+ table reference list.
+<synopsis>
+FROM <replaceable>table_reference</replaceable> <optional>, <replaceable>table_reference</replaceable> <optional>, ...</optional></optional>
+</synopsis>
+
+ A table reference can be a table name (possibly schema-qualified),
+ or a derived table such as a subquery, a <literal>JOIN</literal> construct, or
+ complex combinations of these. If more than one table reference is
+ listed in the <literal>FROM</literal> clause, the tables are cross-joined
+ (that is, the Cartesian product of their rows is formed; see below).
+ The result of the <literal>FROM</literal> list is an intermediate virtual
+ table that can then be subject to
+ transformations by the <literal>WHERE</literal>, <literal>GROUP BY</literal>,
+ and <literal>HAVING</literal> clauses and is finally the result of the
+ overall table expression.
+ </para>
+
+ <indexterm>
+ <primary>ONLY</primary>
+ </indexterm>
+
+ <para>
+ When a table reference names a table that is the parent of a
+ table inheritance hierarchy, the table reference produces rows of
+ not only that table but all of its descendant tables, unless the
+ key word <literal>ONLY</literal> precedes the table name. However, the
+ reference produces only the columns that appear in the named table
+ &mdash; any columns added in subtables are ignored.
+ </para>
+
+ <para>
+ Instead of writing <literal>ONLY</literal> before the table name, you can write
+ <literal>*</literal> after the table name to explicitly specify that descendant
+ tables are included. There is no real reason to use this syntax any more,
+ because searching descendant tables is now always the default behavior.
+ However, it is supported for compatibility with older releases.
+ </para>
+
+ <sect3 id="queries-join">
+ <title>Joined Tables</title>
+
+ <indexterm zone="queries-join">
+ <primary>join</primary>
+ </indexterm>
+
+ <para>
+ A joined table is a table derived from two other (real or
+ derived) tables according to the rules of the particular join
+ type. Inner, outer, and cross-joins are available.
+ The general syntax of a joined table is
+<synopsis>
+<replaceable>T1</replaceable> <replaceable>join_type</replaceable> <replaceable>T2</replaceable> <optional> <replaceable>join_condition</replaceable> </optional>
+</synopsis>
+ Joins of all types can be chained together, or nested: either or
+ both <replaceable>T1</replaceable> and
+ <replaceable>T2</replaceable> can be joined tables. Parentheses
+ can be used around <literal>JOIN</literal> clauses to control the join
+ order. In the absence of parentheses, <literal>JOIN</literal> clauses
+ nest left-to-right.
+ </para>
+
+ <variablelist>
+ <title>Join Types</title>
+
+ <varlistentry>
+ <term>Cross join
+ <indexterm>
+ <primary>join</primary>
+ <secondary>cross</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>cross join</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+<synopsis>
+<replaceable>T1</replaceable> CROSS JOIN <replaceable>T2</replaceable>
+</synopsis>
+
+ <para>
+ For every possible combination of rows from
+ <replaceable>T1</replaceable> and
+ <replaceable>T2</replaceable> (i.e., a Cartesian product),
+ the joined table will contain a
+ row consisting of all columns in <replaceable>T1</replaceable>
+ followed by all columns in <replaceable>T2</replaceable>. If
+ the tables have N and M rows respectively, the joined
+ table will have N * M rows.
+ </para>
+
+ <para>
+ <literal>FROM <replaceable>T1</replaceable> CROSS JOIN
+ <replaceable>T2</replaceable></literal> is equivalent to
+ <literal>FROM <replaceable>T1</replaceable> INNER JOIN
+ <replaceable>T2</replaceable> ON TRUE</literal> (see below).
+ It is also equivalent to
+ <literal>FROM <replaceable>T1</replaceable>,
+ <replaceable>T2</replaceable></literal>.
+ <note>
+ <para>
+ This latter equivalence does not hold exactly when more than two
+ tables appear, because <literal>JOIN</literal> binds more tightly than
+ comma. For example
+ <literal>FROM <replaceable>T1</replaceable> CROSS JOIN
+ <replaceable>T2</replaceable> INNER JOIN <replaceable>T3</replaceable>
+ ON <replaceable>condition</replaceable></literal>
+ is not the same as
+ <literal>FROM <replaceable>T1</replaceable>,
+ <replaceable>T2</replaceable> INNER JOIN <replaceable>T3</replaceable>
+ ON <replaceable>condition</replaceable></literal>
+ because the <replaceable>condition</replaceable> can
+ reference <replaceable>T1</replaceable> in the first case but not
+ the second.
+ </para>
+ </note>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Qualified joins
+ <indexterm>
+ <primary>join</primary>
+ <secondary>outer</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>outer join</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+<synopsis>
+<replaceable>T1</replaceable> { <optional>INNER</optional> | { LEFT | RIGHT | FULL } <optional>OUTER</optional> } JOIN <replaceable>T2</replaceable> ON <replaceable>boolean_expression</replaceable>
+<replaceable>T1</replaceable> { <optional>INNER</optional> | { LEFT | RIGHT | FULL } <optional>OUTER</optional> } JOIN <replaceable>T2</replaceable> USING ( <replaceable>join column list</replaceable> )
+<replaceable>T1</replaceable> NATURAL { <optional>INNER</optional> | { LEFT | RIGHT | FULL } <optional>OUTER</optional> } JOIN <replaceable>T2</replaceable>
+</synopsis>
+
+ <para>
+ The words <literal>INNER</literal> and
+ <literal>OUTER</literal> are optional in all forms.
+ <literal>INNER</literal> is the default;
+ <literal>LEFT</literal>, <literal>RIGHT</literal>, and
+ <literal>FULL</literal> imply an outer join.
+ </para>
+
+ <para>
+ The <firstterm>join condition</firstterm> is specified in the
+ <literal>ON</literal> or <literal>USING</literal> clause, or implicitly by
+ the word <literal>NATURAL</literal>. The join condition determines
+ which rows from the two source tables are considered to
+ <quote>match</quote>, as explained in detail below.
+ </para>
+
+ <para>
+ The possible types of qualified join are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>INNER JOIN</literal></term>
+
+ <listitem>
+ <para>
+ For each row R1 of T1, the joined table has a row for each
+ row in T2 that satisfies the join condition with R1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LEFT OUTER JOIN</literal>
+ <indexterm>
+ <primary>join</primary>
+ <secondary>left</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>left join</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ First, an inner join is performed. Then, for each row in
+ T1 that does not satisfy the join condition with any row in
+ T2, a joined row is added with null values in columns of
+ T2. Thus, the joined table always has at least
+ one row for each row in T1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RIGHT OUTER JOIN</literal>
+ <indexterm>
+ <primary>join</primary>
+ <secondary>right</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>right join</primary>
+ </indexterm>
+ </term>
+
+ <listitem>
+ <para>
+ First, an inner join is performed. Then, for each row in
+ T2 that does not satisfy the join condition with any row in
+ T1, a joined row is added with null values in columns of
+ T1. This is the converse of a left join: the result table
+ will always have a row for each row in T2.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FULL OUTER JOIN</literal></term>
+
+ <listitem>
+ <para>
+ First, an inner join is performed. Then, for each row in
+ T1 that does not satisfy the join condition with any row in
+ T2, a joined row is added with null values in columns of
+ T2. Also, for each row of T2 that does not satisfy the
+ join condition with any row in T1, a joined row with null
+ values in the columns of T1 is added.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <literal>ON</literal> clause is the most general kind of join
+ condition: it takes a Boolean value expression of the same
+ kind as is used in a <literal>WHERE</literal> clause. A pair of rows
+ from <replaceable>T1</replaceable> and <replaceable>T2</replaceable> match if the
+ <literal>ON</literal> expression evaluates to true.
+ </para>
+
+ <para>
+ The <literal>USING</literal> clause is a shorthand that allows you to take
+ advantage of the specific situation where both sides of the join use
+ the same name for the joining column(s). It takes a
+ comma-separated list of the shared column names
+ and forms a join condition that includes an equality comparison
+ for each one. For example, joining <replaceable>T1</replaceable>
+ and <replaceable>T2</replaceable> with <literal>USING (a, b)</literal> produces
+ the join condition <literal>ON <replaceable>T1</replaceable>.a
+ = <replaceable>T2</replaceable>.a AND <replaceable>T1</replaceable>.b
+ = <replaceable>T2</replaceable>.b</literal>.
+ </para>
+
+ <para>
+ Furthermore, the output of <literal>JOIN USING</literal> suppresses
+ redundant columns: there is no need to print both of the matched
+ columns, since they must have equal values. While <literal>JOIN
+ ON</literal> produces all columns from <replaceable>T1</replaceable> followed by all
+ columns from <replaceable>T2</replaceable>, <literal>JOIN USING</literal> produces one
+ output column for each of the listed column pairs (in the listed
+ order), followed by any remaining columns from <replaceable>T1</replaceable>,
+ followed by any remaining columns from <replaceable>T2</replaceable>.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>join</primary>
+ <secondary>natural</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>natural join</primary>
+ </indexterm>
+ Finally, <literal>NATURAL</literal> is a shorthand form of
+ <literal>USING</literal>: it forms a <literal>USING</literal> list
+ consisting of all column names that appear in both
+ input tables. As with <literal>USING</literal>, these columns appear
+ only once in the output table. If there are no common
+ column names, <literal>NATURAL JOIN</literal> behaves like
+ <literal>JOIN ... ON TRUE</literal>, producing a cross-product join.
+ </para>
+
+ <note>
+ <para>
+ <literal>USING</literal> is reasonably safe from column changes
+ in the joined relations since only the listed columns
+ are combined. <literal>NATURAL</literal> is considerably more risky since
+ any schema changes to either relation that cause a new matching
+ column name to be present will cause the join to combine that new
+ column as well.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ To put this together, assume we have tables <literal>t1</literal>:
+<programlisting>
+ num | name
+-----+------
+ 1 | a
+ 2 | b
+ 3 | c
+</programlisting>
+ and <literal>t2</literal>:
+<programlisting>
+ num | value
+-----+-------
+ 1 | xxx
+ 3 | yyy
+ 5 | zzz
+</programlisting>
+ then we get the following results for the various joins:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 CROSS JOIN t2;</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 1 | a | 3 | yyy
+ 1 | a | 5 | zzz
+ 2 | b | 1 | xxx
+ 2 | b | 3 | yyy
+ 2 | b | 5 | zzz
+ 3 | c | 1 | xxx
+ 3 | c | 3 | yyy
+ 3 | c | 5 | zzz
+(9 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 3 | c | 3 | yyy
+(2 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 INNER JOIN t2 USING (num);</userinput>
+ num | name | value
+-----+------+-------
+ 1 | a | xxx
+ 3 | c | yyy
+(2 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 NATURAL INNER JOIN t2;</userinput>
+ num | name | value
+-----+------+-------
+ 1 | a | xxx
+ 3 | c | yyy
+(2 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 2 | b | |
+ 3 | c | 3 | yyy
+(3 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 USING (num);</userinput>
+ num | name | value
+-----+------+-------
+ 1 | a | xxx
+ 2 | b |
+ 3 | c | yyy
+(3 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 3 | c | 3 | yyy
+ | | 5 | zzz
+(3 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 2 | b | |
+ 3 | c | 3 | yyy
+ | | 5 | zzz
+(4 rows)
+</screen>
+ </para>
+
+ <para>
+ The join condition specified with <literal>ON</literal> can also contain
+ conditions that do not relate directly to the join. This can
+ prove useful for some queries but needs to be thought out
+ carefully. For example:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+ 2 | b | |
+ 3 | c | |
+(3 rows)
+</screen>
+ Notice that placing the restriction in the <literal>WHERE</literal> clause
+ produces a different result:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num WHERE t2.value = 'xxx';</userinput>
+ num | name | num | value
+-----+------+-----+-------
+ 1 | a | 1 | xxx
+(1 row)
+</screen>
+ This is because a restriction placed in the <literal>ON</literal>
+ clause is processed <emphasis>before</emphasis> the join, while
+ a restriction placed in the <literal>WHERE</literal> clause is processed
+ <emphasis>after</emphasis> the join.
+ That does not matter with inner joins, but it matters a lot with outer
+ joins.
+ </para>
+ </sect3>
+
+ <sect3 id="queries-table-aliases">
+ <title>Table and Column Aliases</title>
+
+ <indexterm zone="queries-table-aliases">
+ <primary>alias</primary>
+ <secondary>in the FROM clause</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>label</primary>
+ <see>alias</see>
+ </indexterm>
+
+ <para>
+ A temporary name can be given to tables and complex table
+ references to be used for references to the derived table in
+ the rest of the query. This is called a <firstterm>table
+ alias</firstterm>.
+ </para>
+
+ <para>
+ To create a table alias, write
+<synopsis>
+FROM <replaceable>table_reference</replaceable> AS <replaceable>alias</replaceable>
+</synopsis>
+ or
+<synopsis>
+FROM <replaceable>table_reference</replaceable> <replaceable>alias</replaceable>
+</synopsis>
+ The <literal>AS</literal> key word is optional noise.
+ <replaceable>alias</replaceable> can be any identifier.
+ </para>
+
+ <para>
+ A typical application of table aliases is to assign short
+ identifiers to long table names to keep the join clauses
+ readable. For example:
+<programlisting>
+SELECT * FROM some_very_long_table_name s JOIN another_fairly_long_name a ON s.id = a.num;
+</programlisting>
+ </para>
+
+ <para>
+ The alias becomes the new name of the table reference so far as the
+ current query is concerned &mdash; it is not allowed to refer to the
+ table by the original name elsewhere in the query. Thus, this is not
+ valid:
+<programlisting>
+SELECT * FROM my_table AS m WHERE my_table.a &gt; 5; -- wrong
+</programlisting>
+ </para>
+
+ <para>
+ Table aliases are mainly for notational convenience, but it is
+ necessary to use them when joining a table to itself, e.g.:
+<programlisting>
+SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id;
+</programlisting>
+ Additionally, an alias is required if the table reference is a
+ subquery (see <xref linkend="queries-subqueries"/>).
+ </para>
+
+ <para>
+ Parentheses are used to resolve ambiguities. In the following example,
+ the first statement assigns the alias <literal>b</literal> to the second
+ instance of <literal>my_table</literal>, but the second statement assigns the
+ alias to the result of the join:
+<programlisting>
+SELECT * FROM my_table AS a CROSS JOIN my_table AS b ...
+SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b ...
+</programlisting>
+ </para>
+
+ <para>
+ Another form of table aliasing gives temporary names to the columns of
+ the table, as well as the table itself:
+<synopsis>
+FROM <replaceable>table_reference</replaceable> <optional>AS</optional> <replaceable>alias</replaceable> ( <replaceable>column1</replaceable> <optional>, <replaceable>column2</replaceable> <optional>, ...</optional></optional> )
+</synopsis>
+ If fewer column aliases are specified than the actual table has
+ columns, the remaining columns are not renamed. This syntax is
+ especially useful for self-joins or subqueries.
+ </para>
+
+ <para>
+ When an alias is applied to the output of a <literal>JOIN</literal>
+ clause, the alias hides the original
+ name(s) within the <literal>JOIN</literal>. For example:
+<programlisting>
+SELECT a.* FROM my_table AS a JOIN your_table AS b ON ...
+</programlisting>
+ is valid SQL, but:
+<programlisting>
+SELECT a.* FROM (my_table AS a JOIN your_table AS b ON ...) AS c
+</programlisting>
+ is not valid; the table alias <literal>a</literal> is not visible
+ outside the alias <literal>c</literal>.
+ </para>
+ </sect3>
+
+ <sect3 id="queries-subqueries">
+ <title>Subqueries</title>
+
+ <indexterm zone="queries-subqueries">
+ <primary>subquery</primary>
+ </indexterm>
+
+ <para>
+ Subqueries specifying a derived table must be enclosed in
+ parentheses and <emphasis>must</emphasis> be assigned a table
+ alias name (as in <xref linkend="queries-table-aliases"/>). For
+ example:
+<programlisting>
+FROM (SELECT * FROM table1) AS alias_name
+</programlisting>
+ </para>
+
+ <para>
+ This example is equivalent to <literal>FROM table1 AS
+ alias_name</literal>. More interesting cases, which cannot be
+ reduced to a plain join, arise when the subquery involves
+ grouping or aggregation.
+ </para>
+
+ <para>
+ A subquery can also be a <command>VALUES</command> list:
+<programlisting>
+FROM (VALUES ('anne', 'smith'), ('bob', 'jones'), ('joe', 'blow'))
+ AS names(first, last)
+</programlisting>
+ Again, a table alias is required. Assigning alias names to the columns
+ of the <command>VALUES</command> list is optional, but is good practice.
+ For more information see <xref linkend="queries-values"/>.
+ </para>
+ </sect3>
+
+ <sect3 id="queries-tablefunctions">
+ <title>Table Functions</title>
+
+ <indexterm zone="queries-tablefunctions"><primary>table function</primary></indexterm>
+
+ <indexterm zone="queries-tablefunctions">
+ <primary>function</primary>
+ <secondary>in the FROM clause</secondary>
+ </indexterm>
+
+ <para>
+ Table functions are functions that produce a set of rows, made up
+ of either base data types (scalar types) or composite data types
+ (table rows). They are used like a table, view, or subquery in
+ the <literal>FROM</literal> clause of a query. Columns returned by table
+ functions can be included in <literal>SELECT</literal>,
+ <literal>JOIN</literal>, or <literal>WHERE</literal> clauses in the same manner
+ as columns of a table, view, or subquery.
+ </para>
+
+ <para>
+ Table functions may also be combined using the <literal>ROWS FROM</literal>
+ syntax, with the results returned in parallel columns; the number of
+ result rows in this case is that of the largest function result, with
+ smaller results padded with null values to match.
+ </para>
+
+<synopsis>
+<replaceable>function_call</replaceable> <optional>WITH ORDINALITY</optional> <optional><optional>AS</optional> <replaceable>table_alias</replaceable> <optional>(<replaceable>column_alias</replaceable> <optional>, ... </optional>)</optional></optional>
+ROWS FROM( <replaceable>function_call</replaceable> <optional>, ... </optional> ) <optional>WITH ORDINALITY</optional> <optional><optional>AS</optional> <replaceable>table_alias</replaceable> <optional>(<replaceable>column_alias</replaceable> <optional>, ... </optional>)</optional></optional>
+</synopsis>
+
+ <para>
+ If the <literal>WITH ORDINALITY</literal> clause is specified, an
+ additional column of type <type>bigint</type> will be added to the
+ function result columns. This column numbers the rows of the function
+ result set, starting from 1. (This is a generalization of the
+ SQL-standard syntax for <literal>UNNEST ... WITH ORDINALITY</literal>.)
+ By default, the ordinal column is called <literal>ordinality</literal>, but
+ a different column name can be assigned to it using
+ an <literal>AS</literal> clause.
+ </para>
+
+ <para>
+ The special table function <literal>UNNEST</literal> may be called with
+ any number of array parameters, and it returns a corresponding number of
+ columns, as if <literal>UNNEST</literal>
+ (<xref linkend="functions-array"/>) had been called on each parameter
+ separately and combined using the <literal>ROWS FROM</literal> construct.
+ </para>
+
+<synopsis>
+UNNEST( <replaceable>array_expression</replaceable> <optional>, ... </optional> ) <optional>WITH ORDINALITY</optional> <optional><optional>AS</optional> <replaceable>table_alias</replaceable> <optional>(<replaceable>column_alias</replaceable> <optional>, ... </optional>)</optional></optional>
+</synopsis>
+
+ <para>
+ If no <replaceable>table_alias</replaceable> is specified, the function
+ name is used as the table name; in the case of a <literal>ROWS FROM()</literal>
+ construct, the first function's name is used.
+ </para>
+
+ <para>
+ If column aliases are not supplied, then for a function returning a base
+ data type, the column name is also the same as the function name. For a
+ function returning a composite type, the result columns get the names
+ of the individual attributes of the type.
+ </para>
+
+ <para>
+ Some examples:
+<programlisting>
+CREATE TABLE foo (fooid int, foosubid int, fooname text);
+
+CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
+ SELECT * FROM foo WHERE fooid = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM getfoo(1) AS t1;
+
+SELECT * FROM foo
+ WHERE foosubid IN (
+ SELECT foosubid
+ FROM getfoo(foo.fooid) z
+ WHERE z.fooid = foo.fooid
+ );
+
+CREATE VIEW vw_getfoo AS SELECT * FROM getfoo(1);
+
+SELECT * FROM vw_getfoo;
+</programlisting>
+ </para>
+
+ <para>
+ In some cases it is useful to define table functions that can
+ return different column sets depending on how they are invoked.
+ To support this, the table function can be declared as returning
+ the pseudo-type <type>record</type> with no <literal>OUT</literal>
+ parameters. When such a function is used in
+ a query, the expected row structure must be specified in the
+ query itself, so that the system can know how to parse and plan
+ the query. This syntax looks like:
+ </para>
+
+<synopsis>
+<replaceable>function_call</replaceable> <optional>AS</optional> <replaceable>alias</replaceable> (<replaceable>column_definition</replaceable> <optional>, ... </optional>)
+<replaceable>function_call</replaceable> AS <optional><replaceable>alias</replaceable></optional> (<replaceable>column_definition</replaceable> <optional>, ... </optional>)
+ROWS FROM( ... <replaceable>function_call</replaceable> AS (<replaceable>column_definition</replaceable> <optional>, ... </optional>) <optional>, ... </optional> )
+</synopsis>
+
+ <para>
+ When not using the <literal>ROWS FROM()</literal> syntax,
+ the <replaceable>column_definition</replaceable> list replaces the column
+ alias list that could otherwise be attached to the <literal>FROM</literal>
+ item; the names in the column definitions serve as column aliases.
+ When using the <literal>ROWS FROM()</literal> syntax,
+ a <replaceable>column_definition</replaceable> list can be attached to
+ each member function separately; or if there is only one member function
+ and no <literal>WITH ORDINALITY</literal> clause,
+ a <replaceable>column_definition</replaceable> list can be written in
+ place of a column alias list following <literal>ROWS FROM()</literal>.
+ </para>
+
+ <para>
+ Consider this example:
+<programlisting>
+SELECT *
+ FROM dblink('dbname=mydb', 'SELECT proname, prosrc FROM pg_proc')
+ AS t1(proname name, prosrc text)
+ WHERE proname LIKE 'bytea%';
+</programlisting>
+ The <xref linkend="contrib-dblink-function"/> function
+ (part of the <xref linkend="dblink"/> module) executes
+ a remote query. It is declared to return
+ <type>record</type> since it might be used for any kind of query.
+ The actual column set must be specified in the calling query so
+ that the parser knows, for example, what <literal>*</literal> should
+ expand to.
+ </para>
+
+ <para>
+ This example uses <literal>ROWS FROM</literal>:
+<programlisting>
+SELECT *
+FROM ROWS FROM
+ (
+ json_to_recordset('[{"a":40,"b":"foo"},{"a":"100","b":"bar"}]')
+ AS (a INTEGER, b TEXT),
+ generate_series(1, 3)
+ ) AS x (p, q, s)
+ORDER BY p;
+
+ p | q | s
+-----+-----+---
+ 40 | foo | 1
+ 100 | bar | 2
+ | | 3
+</programlisting>
+ It joins two functions into a single <literal>FROM</literal>
+ target. <function>json_to_recordset()</function> is instructed
+ to return two columns, the first <type>integer</type>
+ and the second <type>text</type>. The result of
+ <function>generate_series()</function> is used directly.
+ The <literal>ORDER BY</literal> clause sorts the column values
+ as integers.
+ </para>
+ </sect3>
+
+ <sect3 id="queries-lateral">
+ <title><literal>LATERAL</literal> Subqueries</title>
+
+ <indexterm zone="queries-lateral">
+ <primary>LATERAL</primary>
+ <secondary>in the FROM clause</secondary>
+ </indexterm>
+
+ <para>
+ Subqueries appearing in <literal>FROM</literal> can be
+ preceded by the key word <literal>LATERAL</literal>. This allows them to
+ reference columns provided by preceding <literal>FROM</literal> items.
+ (Without <literal>LATERAL</literal>, each subquery is
+ evaluated independently and so cannot cross-reference any other
+ <literal>FROM</literal> item.)
+ </para>
+
+ <para>
+ Table functions appearing in <literal>FROM</literal> can also be
+ preceded by the key word <literal>LATERAL</literal>, but for functions the
+ key word is optional; the function's arguments can contain references
+ to columns provided by preceding <literal>FROM</literal> items in any case.
+ </para>
+
+ <para>
+ A <literal>LATERAL</literal> item can appear at the top level in the
+ <literal>FROM</literal> list, or within a <literal>JOIN</literal> tree. In the latter
+ case it can also refer to any items that are on the left-hand side of a
+ <literal>JOIN</literal> that it is on the right-hand side of.
+ </para>
+
+ <para>
+ When a <literal>FROM</literal> item contains <literal>LATERAL</literal>
+ cross-references, evaluation proceeds as follows: for each row of the
+ <literal>FROM</literal> item providing the cross-referenced column(s), or
+ set of rows of multiple <literal>FROM</literal> items providing the
+ columns, the <literal>LATERAL</literal> item is evaluated using that
+ row or row set's values of the columns. The resulting row(s) are
+ joined as usual with the rows they were computed from. This is
+ repeated for each row or set of rows from the column source table(s).
+ </para>
+
+ <para>
+ A trivial example of <literal>LATERAL</literal> is
+<programlisting>
+SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;
+</programlisting>
+ This is not especially useful since it has exactly the same result as
+ the more conventional
+<programlisting>
+SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;
+</programlisting>
+ <literal>LATERAL</literal> is primarily useful when the cross-referenced
+ column is necessary for computing the row(s) to be joined. A common
+ application is providing an argument value for a set-returning function.
+ For example, supposing that <function>vertices(polygon)</function> returns the
+ set of vertices of a polygon, we could identify close-together vertices
+ of polygons stored in a table with:
+<programlisting>
+SELECT p1.id, p2.id, v1, v2
+FROM polygons p1, polygons p2,
+ LATERAL vertices(p1.poly) v1,
+ LATERAL vertices(p2.poly) v2
+WHERE (v1 &lt;-&gt; v2) &lt; 10 AND p1.id != p2.id;
+</programlisting>
+ This query could also be written
+<programlisting>
+SELECT p1.id, p2.id, v1, v2
+FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,
+ polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2
+WHERE (v1 &lt;-&gt; v2) &lt; 10 AND p1.id != p2.id;
+</programlisting>
+ or in several other equivalent formulations. (As already mentioned,
+ the <literal>LATERAL</literal> key word is unnecessary in this example, but
+ we use it for clarity.)
+ </para>
+
+ <para>
+ It is often particularly handy to <literal>LEFT JOIN</literal> to a
+ <literal>LATERAL</literal> subquery, so that source rows will appear in
+ the result even if the <literal>LATERAL</literal> subquery produces no
+ rows for them. For example, if <function>get_product_names()</function> returns
+ the names of products made by a manufacturer, but some manufacturers in
+ our table currently produce no products, we could find out which ones
+ those are like this:
+<programlisting>
+SELECT m.name
+FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true
+WHERE pname IS NULL;
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="queries-where">
+ <title>The <literal>WHERE</literal> Clause</title>
+
+ <indexterm zone="queries-where">
+ <primary>WHERE</primary>
+ </indexterm>
+
+ <para>
+ The syntax of the <link linkend="sql-where"><literal>WHERE</literal></link>
+ clause is
+<synopsis>
+WHERE <replaceable>search_condition</replaceable>
+</synopsis>
+ where <replaceable>search_condition</replaceable> is any value
+ expression (see <xref linkend="sql-expressions"/>) that
+ returns a value of type <type>boolean</type>.
+ </para>
+
+ <para>
+ After the processing of the <literal>FROM</literal> clause is done, each
+ row of the derived virtual table is checked against the search
+ condition. If the result of the condition is true, the row is
+ kept in the output table, otherwise (i.e., if the result is
+ false or null) it is discarded. The search condition typically
+ references at least one column of the table generated in the
+ <literal>FROM</literal> clause; this is not required, but otherwise the
+ <literal>WHERE</literal> clause will be fairly useless.
+ </para>
+
+ <note>
+ <para>
+ The join condition of an inner join can be written either in
+ the <literal>WHERE</literal> clause or in the <literal>JOIN</literal> clause.
+ For example, these table expressions are equivalent:
+<programlisting>
+FROM a, b WHERE a.id = b.id AND b.val &gt; 5
+</programlisting>
+ and:
+<programlisting>
+FROM a INNER JOIN b ON (a.id = b.id) WHERE b.val &gt; 5
+</programlisting>
+ or perhaps even:
+<programlisting>
+FROM a NATURAL JOIN b WHERE b.val &gt; 5
+</programlisting>
+ Which one of these you use is mainly a matter of style. The
+ <literal>JOIN</literal> syntax in the <literal>FROM</literal> clause is
+ probably not as portable to other SQL database management systems,
+ even though it is in the SQL standard. For
+ outer joins there is no choice: they must be done in
+ the <literal>FROM</literal> clause. The <literal>ON</literal> or <literal>USING</literal>
+ clause of an outer join is <emphasis>not</emphasis> equivalent to a
+ <literal>WHERE</literal> condition, because it results in the addition
+ of rows (for unmatched input rows) as well as the removal of rows
+ in the final result.
+ </para>
+ </note>
+
+ <para>
+ Here are some examples of <literal>WHERE</literal> clauses:
+<programlisting>
+SELECT ... FROM fdt WHERE c1 &gt; 5
+
+SELECT ... FROM fdt WHERE c1 IN (1, 2, 3)
+
+SELECT ... FROM fdt WHERE c1 IN (SELECT c1 FROM t2)
+
+SELECT ... FROM fdt WHERE c1 IN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10)
+
+SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100
+
+SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 &gt; fdt.c1)
+</programlisting>
+ <literal>fdt</literal> is the table derived in the
+ <literal>FROM</literal> clause. Rows that do not meet the search
+ condition of the <literal>WHERE</literal> clause are eliminated from
+ <literal>fdt</literal>. Notice the use of scalar subqueries as
+ value expressions. Just like any other query, the subqueries can
+ employ complex table expressions. Notice also how
+ <literal>fdt</literal> is referenced in the subqueries.
+ Qualifying <literal>c1</literal> as <literal>fdt.c1</literal> is only necessary
+ if <literal>c1</literal> is also the name of a column in the derived
+ input table of the subquery. But qualifying the column name adds
+ clarity even when it is not needed. This example shows how the column
+ naming scope of an outer query extends into its inner queries.
+ </para>
+ </sect2>
+
+
+ <sect2 id="queries-group">
+ <title>The <literal>GROUP BY</literal> and <literal>HAVING</literal> Clauses</title>
+
+ <indexterm zone="queries-group">
+ <primary>GROUP BY</primary>
+ </indexterm>
+
+ <indexterm zone="queries-group">
+ <primary>grouping</primary>
+ </indexterm>
+
+ <para>
+ After passing the <literal>WHERE</literal> filter, the derived input
+ table might be subject to grouping, using the <literal>GROUP BY</literal>
+ clause, and elimination of group rows using the <literal>HAVING</literal>
+ clause.
+ </para>
+
+<synopsis>
+SELECT <replaceable>select_list</replaceable>
+ FROM ...
+ <optional>WHERE ...</optional>
+ GROUP BY <replaceable>grouping_column_reference</replaceable> <optional>, <replaceable>grouping_column_reference</replaceable></optional>...
+</synopsis>
+
+ <para>
+ The <link linkend="sql-groupby"><literal>GROUP BY</literal></link> clause is
+ used to group together those rows in a table that have the same
+ values in all the columns listed. The order in which the columns
+ are listed does not matter. The effect is to combine each set
+ of rows having common values into one group row that
+ represents all rows in the group. This is done to
+ eliminate redundancy in the output and/or compute aggregates that
+ apply to these groups. For instance:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM test1;</userinput>
+ x | y
+---+---
+ a | 3
+ c | 2
+ b | 5
+ a | 1
+(4 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT x FROM test1 GROUP BY x;</userinput>
+ x
+---
+ a
+ b
+ c
+(3 rows)
+</screen>
+ </para>
+
+ <para>
+ In the second query, we could not have written <literal>SELECT *
+ FROM test1 GROUP BY x</literal>, because there is no single value
+ for the column <literal>y</literal> that could be associated with each
+ group. The grouped-by columns can be referenced in the select list since
+ they have a single value in each group.
+ </para>
+
+ <para>
+ In general, if a table is grouped, columns that are not
+ listed in <literal>GROUP BY</literal> cannot be referenced except in aggregate
+ expressions. An example with aggregate expressions is:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x;</userinput>
+ x | sum
+---+-----
+ a | 4
+ b | 5
+ c | 2
+(3 rows)
+</screen>
+ Here <literal>sum</literal> is an aggregate function that
+ computes a single value over the entire group. More information
+ about the available aggregate functions can be found in <xref
+ linkend="functions-aggregate"/>.
+ </para>
+
+ <tip>
+ <para>
+ Grouping without aggregate expressions effectively calculates the
+ set of distinct values in a column. This can also be achieved
+ using the <literal>DISTINCT</literal> clause (see <xref
+ linkend="queries-distinct"/>).
+ </para>
+ </tip>
+
+ <para>
+ Here is another example: it calculates the total sales for each
+ product (rather than the total sales of all products):
+<programlisting>
+SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
+ FROM products p LEFT JOIN sales s USING (product_id)
+ GROUP BY product_id, p.name, p.price;
+</programlisting>
+ In this example, the columns <literal>product_id</literal>,
+ <literal>p.name</literal>, and <literal>p.price</literal> must be
+ in the <literal>GROUP BY</literal> clause since they are referenced in
+ the query select list (but see below). The column
+ <literal>s.units</literal> does not have to be in the <literal>GROUP
+ BY</literal> list since it is only used in an aggregate expression
+ (<literal>sum(...)</literal>), which represents the sales
+ of a product. For each product, the query returns a summary row about
+ all sales of the product.
+ </para>
+
+ <indexterm><primary>functional dependency</primary></indexterm>
+
+ <para>
+ If the products table is set up so that, say,
+ <literal>product_id</literal> is the primary key, then it would be
+ enough to group by <literal>product_id</literal> in the above example,
+ since name and price would be <firstterm>functionally
+ dependent</firstterm> on the product ID, and so there would be no
+ ambiguity about which name and price value to return for each product
+ ID group.
+ </para>
+
+ <para>
+ In strict SQL, <literal>GROUP BY</literal> can only group by columns of
+ the source table but <productname>PostgreSQL</productname> extends
+ this to also allow <literal>GROUP BY</literal> to group by columns in the
+ select list. Grouping by value expressions instead of simple
+ column names is also allowed.
+ </para>
+
+ <indexterm>
+ <primary>HAVING</primary>
+ </indexterm>
+
+ <para>
+ If a table has been grouped using <literal>GROUP BY</literal>,
+ but only certain groups are of interest, the
+ <literal>HAVING</literal> clause can be used, much like a
+ <literal>WHERE</literal> clause, to eliminate groups from the result.
+ The syntax is:
+<synopsis>
+SELECT <replaceable>select_list</replaceable> FROM ... <optional>WHERE ...</optional> GROUP BY ... HAVING <replaceable>boolean_expression</replaceable>
+</synopsis>
+ Expressions in the <literal>HAVING</literal> clause can refer both to
+ grouped expressions and to ungrouped expressions (which necessarily
+ involve an aggregate function).
+ </para>
+
+ <para>
+ Example:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) &gt; 3;</userinput>
+ x | sum
+---+-----
+ a | 4
+ b | 5
+(2 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x HAVING x &lt; 'c';</userinput>
+ x | sum
+---+-----
+ a | 4
+ b | 5
+(2 rows)
+</screen>
+ </para>
+
+ <para>
+ Again, a more realistic example:
+<programlisting>
+SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit
+ FROM products p LEFT JOIN sales s USING (product_id)
+ WHERE s.date &gt; CURRENT_DATE - INTERVAL '4 weeks'
+ GROUP BY product_id, p.name, p.price, p.cost
+ HAVING sum(p.price * s.units) &gt; 5000;
+</programlisting>
+ In the example above, the <literal>WHERE</literal> clause is selecting
+ rows by a column that is not grouped (the expression is only true for
+ sales during the last four weeks), while the <literal>HAVING</literal>
+ clause restricts the output to groups with total gross sales over
+ 5000. Note that the aggregate expressions do not necessarily need
+ to be the same in all parts of the query.
+ </para>
+
+ <para>
+ If a query contains aggregate function calls, but no <literal>GROUP BY</literal>
+ clause, grouping still occurs: the result is a single group row (or
+ perhaps no rows at all, if the single row is then eliminated by
+ <literal>HAVING</literal>).
+ The same is true if it contains a <literal>HAVING</literal> clause, even
+ without any aggregate function calls or <literal>GROUP BY</literal> clause.
+ </para>
+ </sect2>
+
+ <sect2 id="queries-grouping-sets">
+ <title><literal>GROUPING SETS</literal>, <literal>CUBE</literal>, and <literal>ROLLUP</literal></title>
+
+ <indexterm zone="queries-grouping-sets">
+ <primary>GROUPING SETS</primary>
+ </indexterm>
+ <indexterm zone="queries-grouping-sets">
+ <primary>CUBE</primary>
+ </indexterm>
+ <indexterm zone="queries-grouping-sets">
+ <primary>ROLLUP</primary>
+ </indexterm>
+
+ <para>
+ More complex grouping operations than those described above are possible
+ using the concept of <firstterm>grouping sets</firstterm>. The data selected by
+ the <literal>FROM</literal> and <literal>WHERE</literal> clauses is grouped separately
+ by each specified grouping set, aggregates computed for each group just as
+ for simple <literal>GROUP BY</literal> clauses, and then the results returned.
+ For example:
+<screen>
+<prompt>=&gt;</prompt> <userinput>SELECT * FROM items_sold;</userinput>
+ brand | size | sales
+-------+------+-------
+ Foo | L | 10
+ Foo | M | 20
+ Bar | M | 15
+ Bar | L | 5
+(4 rows)
+
+<prompt>=&gt;</prompt> <userinput>SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());</userinput>
+ brand | size | sum
+-------+------+-----
+ Foo | | 30
+ Bar | | 20
+ | L | 15
+ | M | 35
+ | | 50
+(5 rows)
+</screen>
+ </para>
+
+ <para>
+ Each sublist of <literal>GROUPING SETS</literal> may specify zero or more columns
+ or expressions and is interpreted the same way as though it were directly
+ in the <literal>GROUP BY</literal> clause. An empty grouping set means that all
+ rows are aggregated down to a single group (which is output even if no
+ input rows were present), as described above for the case of aggregate
+ functions with no <literal>GROUP BY</literal> clause.
+ </para>
+
+ <para>
+ References to the grouping columns or expressions are replaced
+ by null values in result rows for grouping sets in which those
+ columns do not appear. To distinguish which grouping a particular output
+ row resulted from, see <xref linkend="functions-grouping-table"/>.
+ </para>
+
+ <para>
+ A shorthand notation is provided for specifying two common types of grouping set.
+ A clause of the form
+<programlisting>
+ROLLUP ( <replaceable>e1</replaceable>, <replaceable>e2</replaceable>, <replaceable>e3</replaceable>, ... )
+</programlisting>
+ represents the given list of expressions and all prefixes of the list including
+ the empty list; thus it is equivalent to
+<programlisting>
+GROUPING SETS (
+ ( <replaceable>e1</replaceable>, <replaceable>e2</replaceable>, <replaceable>e3</replaceable>, ... ),
+ ...
+ ( <replaceable>e1</replaceable>, <replaceable>e2</replaceable> ),
+ ( <replaceable>e1</replaceable> ),
+ ( )
+)
+</programlisting>
+ This is commonly used for analysis over hierarchical data; e.g., total
+ salary by department, division, and company-wide total.
+ </para>
+
+ <para>
+ A clause of the form
+<programlisting>
+CUBE ( <replaceable>e1</replaceable>, <replaceable>e2</replaceable>, ... )
+</programlisting>
+ represents the given list and all of its possible subsets (i.e., the power
+ set). Thus
+<programlisting>
+CUBE ( a, b, c )
+</programlisting>
+ is equivalent to
+<programlisting>
+GROUPING SETS (
+ ( a, b, c ),
+ ( a, b ),
+ ( a, c ),
+ ( a ),
+ ( b, c ),
+ ( b ),
+ ( c ),
+ ( )
+)
+</programlisting>
+ </para>
+
+ <para>
+ The individual elements of a <literal>CUBE</literal> or <literal>ROLLUP</literal>
+ clause may be either individual expressions, or sublists of elements in
+ parentheses. In the latter case, the sublists are treated as single
+ units for the purposes of generating the individual grouping sets.
+ For example:
+<programlisting>
+CUBE ( (a, b), (c, d) )
+</programlisting>
+ is equivalent to
+<programlisting>
+GROUPING SETS (
+ ( a, b, c, d ),
+ ( a, b ),
+ ( c, d ),
+ ( )
+)
+</programlisting>
+ and
+<programlisting>
+ROLLUP ( a, (b, c), d )
+</programlisting>
+ is equivalent to
+<programlisting>
+GROUPING SETS (
+ ( a, b, c, d ),
+ ( a, b, c ),
+ ( a ),
+ ( )
+)
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>CUBE</literal> and <literal>ROLLUP</literal> constructs can be used either
+ directly in the <literal>GROUP BY</literal> clause, or nested inside a
+ <literal>GROUPING SETS</literal> clause. If one <literal>GROUPING SETS</literal> clause
+ is nested inside another, the effect is the same as if all the elements of
+ the inner clause had been written directly in the outer clause.
+ </para>
+
+ <para>
+ If multiple grouping items are specified in a single <literal>GROUP BY</literal>
+ clause, then the final list of grouping sets is the cross product of the
+ individual items. For example:
+<programlisting>
+GROUP BY a, CUBE (b, c), GROUPING SETS ((d), (e))
+</programlisting>
+ is equivalent to
+<programlisting>
+GROUP BY GROUPING SETS (
+ (a, b, c, d), (a, b, c, e),
+ (a, b, d), (a, b, e),
+ (a, c, d), (a, c, e),
+ (a, d), (a, e)
+)
+</programlisting>
+ </para>
+
+ <para>
+ <indexterm zone="queries-grouping-sets">
+ <primary>ALL</primary>
+ <secondary>GROUP BY ALL</secondary>
+ </indexterm>
+ <indexterm zone="queries-grouping-sets">
+ <primary>DISTINCT</primary>
+ <secondary>GROUP BY DISTINCT</secondary>
+ </indexterm>
+ When specifying multiple grouping items together, the final set of grouping
+ sets might contain duplicates. For example:
+<programlisting>
+GROUP BY ROLLUP (a, b), ROLLUP (a, c)
+</programlisting>
+ is equivalent to
+<programlisting>
+GROUP BY GROUPING SETS (
+ (a, b, c),
+ (a, b),
+ (a, b),
+ (a, c),
+ (a),
+ (a),
+ (a, c),
+ (a),
+ ()
+)
+</programlisting>
+ If these duplicates are undesirable, they can be removed using the
+ <literal>DISTINCT</literal> clause directly on the <literal>GROUP BY</literal>.
+ Therefore:
+<programlisting>
+GROUP BY <emphasis>DISTINCT</emphasis> ROLLUP (a, b), ROLLUP (a, c)
+</programlisting>
+ is equivalent to
+<programlisting>
+GROUP BY GROUPING SETS (
+ (a, b, c),
+ (a, b),
+ (a, c),
+ (a),
+ ()
+)
+</programlisting>
+ This is not the same as using <literal>SELECT DISTINCT</literal> because the output
+ rows may still contain duplicates. If any of the ungrouped columns contains NULL,
+ it will be indistinguishable from the NULL used when that same column is grouped.
+ </para>
+
+ <note>
+ <para>
+ The construct <literal>(a, b)</literal> is normally recognized in expressions as
+ a <link linkend="sql-syntax-row-constructors">row constructor</link>.
+ Within the <literal>GROUP BY</literal> clause, this does not apply at the top
+ levels of expressions, and <literal>(a, b)</literal> is parsed as a list of
+ expressions as described above. If for some reason you <emphasis>need</emphasis>
+ a row constructor in a grouping expression, use <literal>ROW(a, b)</literal>.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="queries-window">
+ <title>Window Function Processing</title>
+
+ <indexterm zone="queries-window">
+ <primary>window function</primary>
+ <secondary>order of execution</secondary>
+ </indexterm>
+
+ <para>
+ If the query contains any window functions (see
+ <xref linkend="tutorial-window"/>,
+ <xref linkend="functions-window"/> and
+ <xref linkend="syntax-window-functions"/>), these functions are evaluated
+ after any grouping, aggregation, and <literal>HAVING</literal> filtering is
+ performed. That is, if the query uses any aggregates, <literal>GROUP
+ BY</literal>, or <literal>HAVING</literal>, then the rows seen by the window functions
+ are the group rows instead of the original table rows from
+ <literal>FROM</literal>/<literal>WHERE</literal>.
+ </para>
+
+ <para>
+ When multiple window functions are used, all the window functions having
+ syntactically equivalent <literal>PARTITION BY</literal> and <literal>ORDER BY</literal>
+ clauses in their window definitions are guaranteed to be evaluated in a
+ single pass over the data. Therefore they will see the same sort ordering,
+ even if the <literal>ORDER BY</literal> does not uniquely determine an ordering.
+ However, no guarantees are made about the evaluation of functions having
+ different <literal>PARTITION BY</literal> or <literal>ORDER BY</literal> specifications.
+ (In such cases a sort step is typically required between the passes of
+ window function evaluations, and the sort is not guaranteed to preserve
+ ordering of rows that its <literal>ORDER BY</literal> sees as equivalent.)
+ </para>
+
+ <para>
+ Currently, window functions always require presorted data, and so the
+ query output will be ordered according to one or another of the window
+ functions' <literal>PARTITION BY</literal>/<literal>ORDER BY</literal> clauses.
+ It is not recommended to rely on this, however. Use an explicit
+ top-level <literal>ORDER BY</literal> clause if you want to be sure the
+ results are sorted in a particular way.
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="queries-select-lists">
+ <title>Select Lists</title>
+
+ <indexterm>
+ <primary>SELECT</primary>
+ <secondary>select list</secondary>
+ </indexterm>
+
+ <para>
+ As shown in the previous section,
+ the table expression in the <command>SELECT</command> command
+ constructs an intermediate virtual table by possibly combining
+ tables, views, eliminating rows, grouping, etc. This table is
+ finally passed on to processing by the <firstterm>select list</firstterm>. The select
+ list determines which <emphasis>columns</emphasis> of the
+ intermediate table are actually output.
+ </para>
+
+ <sect2 id="queries-select-list-items">
+ <title>Select-List Items</title>
+
+ <indexterm>
+ <primary>*</primary>
+ </indexterm>
+
+ <para>
+ The simplest kind of select list is <literal>*</literal> which
+ emits all columns that the table expression produces. Otherwise,
+ a select list is a comma-separated list of value expressions (as
+ defined in <xref linkend="sql-expressions"/>). For instance, it
+ could be a list of column names:
+<programlisting>
+SELECT a, b, c FROM ...
+</programlisting>
+ The columns names <literal>a</literal>, <literal>b</literal>, and <literal>c</literal>
+ are either the actual names of the columns of tables referenced
+ in the <literal>FROM</literal> clause, or the aliases given to them as
+ explained in <xref linkend="queries-table-aliases"/>. The name
+ space available in the select list is the same as in the
+ <literal>WHERE</literal> clause, unless grouping is used, in which case
+ it is the same as in the <literal>HAVING</literal> clause.
+ </para>
+
+ <para>
+ If more than one table has a column of the same name, the table
+ name must also be given, as in:
+<programlisting>
+SELECT tbl1.a, tbl2.a, tbl1.b FROM ...
+</programlisting>
+ When working with multiple tables, it can also be useful to ask for
+ all the columns of a particular table:
+<programlisting>
+SELECT tbl1.*, tbl2.a FROM ...
+</programlisting>
+ See <xref linkend="rowtypes-usage"/> for more about
+ the <replaceable>table_name</replaceable><literal>.*</literal> notation.
+ </para>
+
+ <para>
+ If an arbitrary value expression is used in the select list, it
+ conceptually adds a new virtual column to the returned table. The
+ value expression is evaluated once for each result row, with
+ the row's values substituted for any column references. But the
+ expressions in the select list do not have to reference any
+ columns in the table expression of the <literal>FROM</literal> clause;
+ they can be constant arithmetic expressions, for instance.
+ </para>
+ </sect2>
+
+ <sect2 id="queries-column-labels">
+ <title>Column Labels</title>
+
+ <indexterm zone="queries-column-labels">
+ <primary>alias</primary>
+ <secondary>in the select list</secondary>
+ </indexterm>
+
+ <para>
+ The entries in the select list can be assigned names for subsequent
+ processing, such as for use in an <literal>ORDER BY</literal> clause
+ or for display by the client application. For example:
+<programlisting>
+SELECT a AS value, b + c AS sum FROM ...
+</programlisting>
+ </para>
+
+ <para>
+ If no output column name is specified using <literal>AS</literal>,
+ the system assigns a default column name. For simple column references,
+ this is the name of the referenced column. For function
+ calls, this is the name of the function. For complex expressions,
+ the system will generate a generic name.
+ </para>
+
+ <para>
+ The <literal>AS</literal> key word is usually optional, but in some
+ cases where the desired column name matches a
+ <productname>PostgreSQL</productname> key word, you must write
+ <literal>AS</literal> or double-quote the column name in order to
+ avoid ambiguity.
+ (<xref linkend="sql-keywords-appendix"/> shows which key words
+ require <literal>AS</literal> to be used as a column label.)
+ For example, <literal>FROM</literal> is one such key word, so this
+ does not work:
+<programlisting>
+SELECT a from, b + c AS sum FROM ...
+</programlisting>
+ but either of these do:
+<programlisting>
+SELECT a AS from, b + c AS sum FROM ...
+SELECT a "from", b + c AS sum FROM ...
+</programlisting>
+ For greatest safety against possible
+ future key word additions, it is recommended that you always either
+ write <literal>AS</literal> or double-quote the output column name.
+ </para>
+
+ <note>
+ <para>
+ The naming of output columns here is different from that done in
+ the <literal>FROM</literal> clause (see <xref
+ linkend="queries-table-aliases"/>). It is possible
+ to rename the same column twice, but the name assigned in
+ the select list is the one that will be passed on.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="queries-distinct">
+ <title><literal>DISTINCT</literal></title>
+
+ <indexterm zone="queries-distinct">
+ <primary>ALL</primary>
+ <secondary>SELECT ALL</secondary>
+ </indexterm>
+ <indexterm zone="queries-distinct">
+ <primary>DISTINCT</primary>
+ <secondary>SELECT DISTINCT</secondary>
+ </indexterm>
+
+ <indexterm zone="queries-distinct">
+ <primary>duplicates</primary>
+ </indexterm>
+
+ <para>
+ After the select list has been processed, the result table can
+ optionally be subject to the elimination of duplicate rows. The
+ <literal>DISTINCT</literal> key word is written directly after
+ <literal>SELECT</literal> to specify this:
+<synopsis>
+SELECT DISTINCT <replaceable>select_list</replaceable> ...
+</synopsis>
+ (Instead of <literal>DISTINCT</literal> the key word <literal>ALL</literal>
+ can be used to specify the default behavior of retaining all rows.)
+ </para>
+
+ <indexterm>
+ <primary>null value</primary>
+ <secondary sortas="DISTINCT">in DISTINCT</secondary>
+ </indexterm>
+
+ <para>
+ Obviously, two rows are considered distinct if they differ in at
+ least one column value. Null values are considered equal in this
+ comparison.
+ </para>
+
+ <para>
+ Alternatively, an arbitrary expression can determine what rows are
+ to be considered distinct:
+<synopsis>
+SELECT DISTINCT ON (<replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ...</optional>) <replaceable>select_list</replaceable> ...
+</synopsis>
+ Here <replaceable>expression</replaceable> is an arbitrary value
+ expression that is evaluated for all rows. A set of rows for
+ which all the expressions are equal are considered duplicates, and
+ only the first row of the set is kept in the output. Note that
+ the <quote>first row</quote> of a set is unpredictable unless the
+ query is sorted on enough columns to guarantee a unique ordering
+ of the rows arriving at the <literal>DISTINCT</literal> filter.
+ (<literal>DISTINCT ON</literal> processing occurs after <literal>ORDER
+ BY</literal> sorting.)
+ </para>
+
+ <para>
+ The <literal>DISTINCT ON</literal> clause is not part of the SQL standard
+ and is sometimes considered bad style because of the potentially
+ indeterminate nature of its results. With judicious use of
+ <literal>GROUP BY</literal> and subqueries in <literal>FROM</literal>, this
+ construct can be avoided, but it is often the most convenient
+ alternative.
+ </para>
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="queries-union">
+ <title>Combining Queries (<literal>UNION</literal>, <literal>INTERSECT</literal>, <literal>EXCEPT</literal>)</title>
+
+ <indexterm zone="queries-union">
+ <primary>UNION</primary>
+ </indexterm>
+ <indexterm zone="queries-union">
+ <primary>INTERSECT</primary>
+ </indexterm>
+ <indexterm zone="queries-union">
+ <primary>EXCEPT</primary>
+ </indexterm>
+ <indexterm zone="queries-union">
+ <primary>set union</primary>
+ </indexterm>
+ <indexterm zone="queries-union">
+ <primary>set intersection</primary>
+ </indexterm>
+ <indexterm zone="queries-union">
+ <primary>set difference</primary>
+ </indexterm>
+ <indexterm zone="queries-union">
+ <primary>set operation</primary>
+ </indexterm>
+
+ <para>
+ The results of two queries can be combined using the set operations
+ union, intersection, and difference. The syntax is
+<synopsis>
+<replaceable>query1</replaceable> UNION <optional>ALL</optional> <replaceable>query2</replaceable>
+<replaceable>query1</replaceable> INTERSECT <optional>ALL</optional> <replaceable>query2</replaceable>
+<replaceable>query1</replaceable> EXCEPT <optional>ALL</optional> <replaceable>query2</replaceable>
+</synopsis>
+ where <replaceable>query1</replaceable> and
+ <replaceable>query2</replaceable> are queries that can use any of
+ the features discussed up to this point.
+ </para>
+
+ <para>
+ <literal>UNION</literal> effectively appends the result of
+ <replaceable>query2</replaceable> to the result of
+ <replaceable>query1</replaceable> (although there is no guarantee
+ that this is the order in which the rows are actually returned).
+ Furthermore, it eliminates duplicate rows from its result, in the same
+ way as <literal>DISTINCT</literal>, unless <literal>UNION ALL</literal> is used.
+ </para>
+
+ <para>
+ <literal>INTERSECT</literal> returns all rows that are both in the result
+ of <replaceable>query1</replaceable> and in the result of
+ <replaceable>query2</replaceable>. Duplicate rows are eliminated
+ unless <literal>INTERSECT ALL</literal> is used.
+ </para>
+
+ <para>
+ <literal>EXCEPT</literal> returns all rows that are in the result of
+ <replaceable>query1</replaceable> but not in the result of
+ <replaceable>query2</replaceable>. (This is sometimes called the
+ <firstterm>difference</firstterm> between two queries.) Again, duplicates
+ are eliminated unless <literal>EXCEPT ALL</literal> is used.
+ </para>
+
+ <para>
+ In order to calculate the union, intersection, or difference of two
+ queries, the two queries must be <quote>union compatible</quote>,
+ which means that they return the same number of columns and
+ the corresponding columns have compatible data types, as
+ described in <xref linkend="typeconv-union-case"/>.
+ </para>
+
+ <para>
+ Set operations can be combined, for example
+<synopsis>
+<replaceable>query1</replaceable> UNION <replaceable>query2</replaceable> EXCEPT <replaceable>query3</replaceable>
+</synopsis>
+ which is equivalent to
+<synopsis>
+(<replaceable>query1</replaceable> UNION <replaceable>query2</replaceable>) EXCEPT <replaceable>query3</replaceable>
+</synopsis>
+ As shown here, you can use parentheses to control the order of
+ evaluation. Without parentheses, <literal>UNION</literal>
+ and <literal>EXCEPT</literal> associate left-to-right,
+ but <literal>INTERSECT</literal> binds more tightly than those two
+ operators. Thus
+<synopsis>
+<replaceable>query1</replaceable> UNION <replaceable>query2</replaceable> INTERSECT <replaceable>query3</replaceable>
+</synopsis>
+ means
+<synopsis>
+<replaceable>query1</replaceable> UNION (<replaceable>query2</replaceable> INTERSECT <replaceable>query3</replaceable>)
+</synopsis>
+ You can also surround an individual <replaceable>query</replaceable>
+ with parentheses. This is important if
+ the <replaceable>query</replaceable> needs to use any of the clauses
+ discussed in following sections, such as <literal>LIMIT</literal>.
+ Without parentheses, you'll get a syntax error, or else the clause will
+ be understood as applying to the output of the set operation rather
+ than one of its inputs. For example,
+<synopsis>
+SELECT a FROM b UNION SELECT x FROM y LIMIT 10
+</synopsis>
+ is accepted, but it means
+<synopsis>
+(SELECT a FROM b UNION SELECT x FROM y) LIMIT 10
+</synopsis>
+ not
+<synopsis>
+SELECT a FROM b UNION (SELECT x FROM y LIMIT 10)
+</synopsis>
+ </para>
+ </sect1>
+
+
+ <sect1 id="queries-order">
+ <title>Sorting Rows (<literal>ORDER BY</literal>)</title>
+
+ <indexterm zone="queries-order">
+ <primary>sorting</primary>
+ </indexterm>
+
+ <indexterm zone="queries-order">
+ <primary>ORDER BY</primary>
+ </indexterm>
+
+ <para>
+ After a query has produced an output table (after the select list
+ has been processed) it can optionally be sorted. If sorting is not
+ chosen, the rows will be returned in an unspecified order. The actual
+ order in that case will depend on the scan and join plan types and
+ the order on disk, but it must not be relied on. A particular
+ output ordering can only be guaranteed if the sort step is explicitly
+ chosen.
+ </para>
+
+ <para>
+ The <literal>ORDER BY</literal> clause specifies the sort order:
+<synopsis>
+SELECT <replaceable>select_list</replaceable>
+ FROM <replaceable>table_expression</replaceable>
+ ORDER BY <replaceable>sort_expression1</replaceable> <optional>ASC | DESC</optional> <optional>NULLS { FIRST | LAST }</optional>
+ <optional>, <replaceable>sort_expression2</replaceable> <optional>ASC | DESC</optional> <optional>NULLS { FIRST | LAST }</optional> ...</optional>
+</synopsis>
+ The sort expression(s) can be any expression that would be valid in the
+ query's select list. An example is:
+<programlisting>
+SELECT a, b FROM table1 ORDER BY a + b, c;
+</programlisting>
+ When more than one expression is specified,
+ the later values are used to sort rows that are equal according to the
+ earlier values. Each expression can be followed by an optional
+ <literal>ASC</literal> or <literal>DESC</literal> keyword to set the sort direction to
+ ascending or descending. <literal>ASC</literal> order is the default.
+ Ascending order puts smaller values first, where
+ <quote>smaller</quote> is defined in terms of the
+ <literal>&lt;</literal> operator. Similarly, descending order is
+ determined with the <literal>&gt;</literal> operator.
+ <footnote>
+ <para>
+ Actually, <productname>PostgreSQL</productname> uses the <firstterm>default B-tree
+ operator class</firstterm> for the expression's data type to determine the sort
+ ordering for <literal>ASC</literal> and <literal>DESC</literal>. Conventionally,
+ data types will be set up so that the <literal>&lt;</literal> and
+ <literal>&gt;</literal> operators correspond to this sort ordering,
+ but a user-defined data type's designer could choose to do something
+ different.
+ </para>
+ </footnote>
+ </para>
+
+ <para>
+ The <literal>NULLS FIRST</literal> and <literal>NULLS LAST</literal> options can be
+ used to determine whether nulls appear before or after non-null values
+ in the sort ordering. By default, null values sort as if larger than any
+ non-null value; that is, <literal>NULLS FIRST</literal> is the default for
+ <literal>DESC</literal> order, and <literal>NULLS LAST</literal> otherwise.
+ </para>
+
+ <para>
+ Note that the ordering options are considered independently for each
+ sort column. For example <literal>ORDER BY x, y DESC</literal> means
+ <literal>ORDER BY x ASC, y DESC</literal>, which is not the same as
+ <literal>ORDER BY x DESC, y DESC</literal>.
+ </para>
+
+ <para>
+ A <replaceable>sort_expression</replaceable> can also be the column label or number
+ of an output column, as in:
+<programlisting>
+SELECT a + b AS sum, c FROM table1 ORDER BY sum;
+SELECT a, max(b) FROM table1 GROUP BY a ORDER BY 1;
+</programlisting>
+ both of which sort by the first output column. Note that an output
+ column name has to stand alone, that is, it cannot be used in an expression
+ &mdash; for example, this is <emphasis>not</emphasis> correct:
+<programlisting>
+SELECT a + b AS sum, c FROM table1 ORDER BY sum + c; -- wrong
+</programlisting>
+ This restriction is made to reduce ambiguity. There is still
+ ambiguity if an <literal>ORDER BY</literal> item is a simple name that
+ could match either an output column name or a column from the table
+ expression. The output column is used in such cases. This would
+ only cause confusion if you use <literal>AS</literal> to rename an output
+ column to match some other table column's name.
+ </para>
+
+ <para>
+ <literal>ORDER BY</literal> can be applied to the result of a
+ <literal>UNION</literal>, <literal>INTERSECT</literal>, or <literal>EXCEPT</literal>
+ combination, but in this case it is only permitted to sort by
+ output column names or numbers, not by expressions.
+ </para>
+ </sect1>
+
+
+ <sect1 id="queries-limit">
+ <title><literal>LIMIT</literal> and <literal>OFFSET</literal></title>
+
+ <indexterm zone="queries-limit">
+ <primary>LIMIT</primary>
+ </indexterm>
+
+ <indexterm zone="queries-limit">
+ <primary>OFFSET</primary>
+ </indexterm>
+
+ <para>
+ <literal>LIMIT</literal> and <literal>OFFSET</literal> allow you to retrieve just
+ a portion of the rows that are generated by the rest of the query:
+<synopsis>
+SELECT <replaceable>select_list</replaceable>
+ FROM <replaceable>table_expression</replaceable>
+ <optional> ORDER BY ... </optional>
+ <optional> LIMIT { <replaceable>number</replaceable> | ALL } </optional> <optional> OFFSET <replaceable>number</replaceable> </optional>
+</synopsis>
+ </para>
+
+ <para>
+ If a limit count is given, no more than that many rows will be
+ returned (but possibly fewer, if the query itself yields fewer rows).
+ <literal>LIMIT ALL</literal> is the same as omitting the <literal>LIMIT</literal>
+ clause, as is <literal>LIMIT</literal> with a NULL argument.
+ </para>
+
+ <para>
+ <literal>OFFSET</literal> says to skip that many rows before beginning to
+ return rows. <literal>OFFSET 0</literal> is the same as omitting the
+ <literal>OFFSET</literal> clause, as is <literal>OFFSET</literal> with a NULL argument.
+ </para>
+
+ <para>
+ If both <literal>OFFSET</literal>
+ and <literal>LIMIT</literal> appear, then <literal>OFFSET</literal> rows are
+ skipped before starting to count the <literal>LIMIT</literal> rows that
+ are returned.
+ </para>
+
+ <para>
+ When using <literal>LIMIT</literal>, it is important to use an
+ <literal>ORDER BY</literal> clause that constrains the result rows into a
+ unique order. Otherwise you will get an unpredictable subset of
+ the query's rows. You might be asking for the tenth through
+ twentieth rows, but tenth through twentieth in what ordering? The
+ ordering is unknown, unless you specified <literal>ORDER BY</literal>.
+ </para>
+
+ <para>
+ The query optimizer takes <literal>LIMIT</literal> into account when
+ generating query plans, so you are very likely to get different
+ plans (yielding different row orders) depending on what you give
+ for <literal>LIMIT</literal> and <literal>OFFSET</literal>. Thus, using
+ different <literal>LIMIT</literal>/<literal>OFFSET</literal> values to select
+ different subsets of a query result <emphasis>will give
+ inconsistent results</emphasis> unless you enforce a predictable
+ result ordering with <literal>ORDER BY</literal>. This is not a bug; it
+ is an inherent consequence of the fact that SQL does not promise to
+ deliver the results of a query in any particular order unless
+ <literal>ORDER BY</literal> is used to constrain the order.
+ </para>
+
+ <para>
+ The rows skipped by an <literal>OFFSET</literal> clause still have to be
+ computed inside the server; therefore a large <literal>OFFSET</literal>
+ might be inefficient.
+ </para>
+ </sect1>
+
+
+ <sect1 id="queries-values">
+ <title><literal>VALUES</literal> Lists</title>
+
+ <indexterm zone="queries-values">
+ <primary>VALUES</primary>
+ </indexterm>
+
+ <para>
+ <literal>VALUES</literal> provides a way to generate a <quote>constant table</quote>
+ that can be used in a query without having to actually create and populate
+ a table on-disk. The syntax is
+<synopsis>
+VALUES ( <replaceable class="parameter">expression</replaceable> [, ...] ) [, ...]
+</synopsis>
+ Each parenthesized list of expressions generates a row in the table.
+ The lists must all have the same number of elements (i.e., the number
+ of columns in the table), and corresponding entries in each list must
+ have compatible data types. The actual data type assigned to each column
+ of the result is determined using the same rules as for <literal>UNION</literal>
+ (see <xref linkend="typeconv-union-case"/>).
+ </para>
+
+ <para>
+ As an example:
+<programlisting>
+VALUES (1, 'one'), (2, 'two'), (3, 'three');
+</programlisting>
+
+ will return a table of two columns and three rows. It's effectively
+ equivalent to:
+<programlisting>
+SELECT 1 AS column1, 'one' AS column2
+UNION ALL
+SELECT 2, 'two'
+UNION ALL
+SELECT 3, 'three';
+</programlisting>
+
+ By default, <productname>PostgreSQL</productname> assigns the names
+ <literal>column1</literal>, <literal>column2</literal>, etc. to the columns of a
+ <literal>VALUES</literal> table. The column names are not specified by the
+ SQL standard and different database systems do it differently, so
+ it's usually better to override the default names with a table alias
+ list, like this:
+<programlisting>
+=&gt; SELECT * FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three')) AS t (num,letter);
+ num | letter
+-----+--------
+ 1 | one
+ 2 | two
+ 3 | three
+(3 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Syntactically, <literal>VALUES</literal> followed by expression lists is
+ treated as equivalent to:
+<synopsis>
+SELECT <replaceable>select_list</replaceable> FROM <replaceable>table_expression</replaceable>
+</synopsis>
+ and can appear anywhere a <literal>SELECT</literal> can. For example, you can
+ use it as part of a <literal>UNION</literal>, or attach a
+ <replaceable>sort_specification</replaceable> (<literal>ORDER BY</literal>,
+ <literal>LIMIT</literal>, and/or <literal>OFFSET</literal>) to it. <literal>VALUES</literal>
+ is most commonly used as the data source in an <command>INSERT</command> command,
+ and next most commonly as a subquery.
+ </para>
+
+ <para>
+ For more information see <xref linkend="sql-values"/>.
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="queries-with">
+ <title><literal>WITH</literal> Queries (Common Table Expressions)</title>
+
+ <indexterm zone="queries-with">
+ <primary>WITH</primary>
+ <secondary>in SELECT</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>common table expression</primary>
+ <see>WITH</see>
+ </indexterm>
+
+ <para>
+ <literal>WITH</literal> provides a way to write auxiliary statements for use in a
+ larger query. These statements, which are often referred to as Common
+ Table Expressions or <acronym>CTE</acronym>s, can be thought of as defining
+ temporary tables that exist just for one query. Each auxiliary statement
+ in a <literal>WITH</literal> clause can be a <command>SELECT</command>,
+ <command>INSERT</command>, <command>UPDATE</command>, or <command>DELETE</command>; and the
+ <literal>WITH</literal> clause itself is attached to a primary statement that can
+ be a <command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, or <command>MERGE</command>.
+ </para>
+
+ <sect2 id="queries-with-select">
+ <title><command>SELECT</command> in <literal>WITH</literal></title>
+
+ <para>
+ The basic value of <command>SELECT</command> in <literal>WITH</literal> is to
+ break down complicated queries into simpler parts. An example is:
+
+<programlisting>
+WITH regional_sales AS (
+ SELECT region, SUM(amount) AS total_sales
+ FROM orders
+ GROUP BY region
+), top_regions AS (
+ SELECT region
+ FROM regional_sales
+ WHERE total_sales &gt; (SELECT SUM(total_sales)/10 FROM regional_sales)
+)
+SELECT region,
+ product,
+ SUM(quantity) AS product_units,
+ SUM(amount) AS product_sales
+FROM orders
+WHERE region IN (SELECT region FROM top_regions)
+GROUP BY region, product;
+</programlisting>
+
+ which displays per-product sales totals in only the top sales regions.
+ The <literal>WITH</literal> clause defines two auxiliary statements named
+ <structname>regional_sales</structname> and <structname>top_regions</structname>,
+ where the output of <structname>regional_sales</structname> is used in
+ <structname>top_regions</structname> and the output of <structname>top_regions</structname>
+ is used in the primary <command>SELECT</command> query.
+ This example could have been written without <literal>WITH</literal>,
+ but we'd have needed two levels of nested sub-<command>SELECT</command>s. It's a bit
+ easier to follow this way.
+ </para>
+ </sect2>
+
+ <sect2 id="queries-with-recursive">
+ <title>Recursive Queries</title>
+
+ <para>
+ <indexterm>
+ <primary>RECURSIVE</primary>
+ <secondary>in common table expressions</secondary>
+ </indexterm>
+ The optional <literal>RECURSIVE</literal> modifier changes <literal>WITH</literal>
+ from a mere syntactic convenience into a feature that accomplishes
+ things not otherwise possible in standard SQL. Using
+ <literal>RECURSIVE</literal>, a <literal>WITH</literal> query can refer to its own
+ output. A very simple example is this query to sum the integers from 1
+ through 100:
+
+<programlisting>
+WITH RECURSIVE t(n) AS (
+ VALUES (1)
+ UNION ALL
+ SELECT n+1 FROM t WHERE n &lt; 100
+)
+SELECT sum(n) FROM t;
+</programlisting>
+
+ The general form of a recursive <literal>WITH</literal> query is always a
+ <firstterm>non-recursive term</firstterm>, then <literal>UNION</literal> (or
+ <literal>UNION ALL</literal>), then a
+ <firstterm>recursive term</firstterm>, where only the recursive term can contain
+ a reference to the query's own output. Such a query is executed as
+ follows:
+ </para>
+
+ <procedure>
+ <title>Recursive Query Evaluation</title>
+
+ <step performance="required">
+ <para>
+ Evaluate the non-recursive term. For <literal>UNION</literal> (but not
+ <literal>UNION ALL</literal>), discard duplicate rows. Include all remaining
+ rows in the result of the recursive query, and also place them in a
+ temporary <firstterm>working table</firstterm>.
+ </para>
+ </step>
+
+ <step performance="required">
+ <para>
+ So long as the working table is not empty, repeat these steps:
+ </para>
+ <substeps>
+ <step performance="required">
+ <para>
+ Evaluate the recursive term, substituting the current contents of
+ the working table for the recursive self-reference.
+ For <literal>UNION</literal> (but not <literal>UNION ALL</literal>), discard
+ duplicate rows and rows that duplicate any previous result row.
+ Include all remaining rows in the result of the recursive query, and
+ also place them in a temporary <firstterm>intermediate table</firstterm>.
+ </para>
+ </step>
+
+ <step performance="required">
+ <para>
+ Replace the contents of the working table with the contents of the
+ intermediate table, then empty the intermediate table.
+ </para>
+ </step>
+ </substeps>
+ </step>
+ </procedure>
+
+ <note>
+ <para>
+ While <literal>RECURSIVE</literal> allows queries to be specified
+ recursively, internally such queries are evaluated iteratively.
+ </para>
+ </note>
+
+ <para>
+ In the example above, the working table has just a single row in each step,
+ and it takes on the values from 1 through 100 in successive steps. In
+ the 100th step, there is no output because of the <literal>WHERE</literal>
+ clause, and so the query terminates.
+ </para>
+
+ <para>
+ Recursive queries are typically used to deal with hierarchical or
+ tree-structured data. A useful example is this query to find all the
+ direct and indirect sub-parts of a product, given only a table that
+ shows immediate inclusions:
+
+<programlisting>
+WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
+ SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
+ UNION ALL
+ SELECT p.sub_part, p.part, p.quantity * pr.quantity
+ FROM included_parts pr, parts p
+ WHERE p.part = pr.sub_part
+)
+SELECT sub_part, SUM(quantity) as total_quantity
+FROM included_parts
+GROUP BY sub_part
+</programlisting>
+ </para>
+
+ <sect3 id="queries-with-search">
+ <title>Search Order</title>
+
+ <para>
+ When computing a tree traversal using a recursive query, you might want to
+ order the results in either depth-first or breadth-first order. This can
+ be done by computing an ordering column alongside the other data columns
+ and using that to sort the results at the end. Note that this does not
+ actually control in which order the query evaluation visits the rows; that
+ is as always in SQL implementation-dependent. This approach merely
+ provides a convenient way to order the results afterwards.
+ </para>
+
+ <para>
+ To create a depth-first order, we compute for each result row an array of
+ rows that we have visited so far. For example, consider the following
+ query that searches a table <structname>tree</structname> using a
+ <structfield>link</structfield> field:
+
+<programlisting>
+WITH RECURSIVE search_tree(id, link, data) AS (
+ SELECT t.id, t.link, t.data
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree;
+</programlisting>
+
+ To add depth-first ordering information, you can write this:
+
+<programlisting>
+WITH RECURSIVE search_tree(id, link, data, <emphasis>path</emphasis>) AS (
+ SELECT t.id, t.link, t.data, <emphasis>ARRAY[t.id]</emphasis>
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data, <emphasis>path || t.id</emphasis>
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree <emphasis>ORDER BY path</emphasis>;
+</programlisting>
+ </para>
+
+ <para>
+ In the general case where more than one field needs to be used to identify
+ a row, use an array of rows. For example, if we needed to track fields
+ <structfield>f1</structfield> and <structfield>f2</structfield>:
+
+<programlisting>
+WITH RECURSIVE search_tree(id, link, data, <emphasis>path</emphasis>) AS (
+ SELECT t.id, t.link, t.data, <emphasis>ARRAY[ROW(t.f1, t.f2)]</emphasis>
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data, <emphasis>path || ROW(t.f1, t.f2)</emphasis>
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree <emphasis>ORDER BY path</emphasis>;
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ Omit the <literal>ROW()</literal> syntax in the common case where only one
+ field needs to be tracked. This allows a simple array rather than a
+ composite-type array to be used, gaining efficiency.
+ </para>
+ </tip>
+
+ <para>
+ To create a breadth-first order, you can add a column that tracks the depth
+ of the search, for example:
+
+<programlisting>
+WITH RECURSIVE search_tree(id, link, data, <emphasis>depth</emphasis>) AS (
+ SELECT t.id, t.link, t.data, <emphasis>0</emphasis>
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data, <emphasis>depth + 1</emphasis>
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+)
+SELECT * FROM search_tree <emphasis>ORDER BY depth</emphasis>;
+</programlisting>
+
+ To get a stable sort, add data columns as secondary sorting columns.
+ </para>
+
+ <tip>
+ <para>
+ The recursive query evaluation algorithm produces its output in
+ breadth-first search order. However, this is an implementation detail and
+ it is perhaps unsound to rely on it. The order of the rows within each
+ level is certainly undefined, so some explicit ordering might be desired
+ in any case.
+ </para>
+ </tip>
+
+ <para>
+ There is built-in syntax to compute a depth- or breadth-first sort column.
+ For example:
+
+<programlisting>
+WITH RECURSIVE search_tree(id, link, data) AS (
+ SELECT t.id, t.link, t.data
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+) <emphasis>SEARCH DEPTH FIRST BY id SET ordercol</emphasis>
+SELECT * FROM search_tree ORDER BY ordercol;
+
+WITH RECURSIVE search_tree(id, link, data) AS (
+ SELECT t.id, t.link, t.data
+ FROM tree t
+ UNION ALL
+ SELECT t.id, t.link, t.data
+ FROM tree t, search_tree st
+ WHERE t.id = st.link
+) <emphasis>SEARCH BREADTH FIRST BY id SET ordercol</emphasis>
+SELECT * FROM search_tree ORDER BY ordercol;
+</programlisting>
+ This syntax is internally expanded to something similar to the above
+ hand-written forms. The <literal>SEARCH</literal> clause specifies whether
+ depth- or breadth first search is wanted, the list of columns to track for
+ sorting, and a column name that will contain the result data that can be
+ used for sorting. That column will implicitly be added to the output rows
+ of the CTE.
+ </para>
+ </sect3>
+
+ <sect3 id="queries-with-cycle">
+ <title>Cycle Detection</title>
+
+ <para>
+ When working with recursive queries it is important to be sure that
+ the recursive part of the query will eventually return no tuples,
+ or else the query will loop indefinitely. Sometimes, using
+ <literal>UNION</literal> instead of <literal>UNION ALL</literal> can accomplish this
+ by discarding rows that duplicate previous output rows. However, often a
+ cycle does not involve output rows that are completely duplicate: it may be
+ necessary to check just one or a few fields to see if the same point has
+ been reached before. The standard method for handling such situations is
+ to compute an array of the already-visited values. For example, consider again
+ the following query that searches a table <structname>graph</structname> using a
+ <structfield>link</structfield> field:
+
+<programlisting>
+WITH RECURSIVE search_graph(id, link, data, depth) AS (
+ SELECT g.id, g.link, g.data, 0
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link
+)
+SELECT * FROM search_graph;
+</programlisting>
+
+ This query will loop if the <structfield>link</structfield> relationships contain
+ cycles. Because we require a <quote>depth</quote> output, just changing
+ <literal>UNION ALL</literal> to <literal>UNION</literal> would not eliminate the looping.
+ Instead we need to recognize whether we have reached the same row again
+ while following a particular path of links. We add two columns
+ <structfield>is_cycle</structfield> and <structfield>path</structfield> to the loop-prone query:
+
+<programlisting>
+WITH RECURSIVE search_graph(id, link, data, depth, <emphasis>is_cycle, path</emphasis>) AS (
+ SELECT g.id, g.link, g.data, 0,
+ <emphasis>false,
+ ARRAY[g.id]</emphasis>
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1,
+ <emphasis>g.id = ANY(path),
+ path || g.id</emphasis>
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link <emphasis>AND NOT is_cycle</emphasis>
+)
+SELECT * FROM search_graph;
+</programlisting>
+
+ Aside from preventing cycles, the array value is often useful in its own
+ right as representing the <quote>path</quote> taken to reach any particular row.
+ </para>
+
+ <para>
+ In the general case where more than one field needs to be checked to
+ recognize a cycle, use an array of rows. For example, if we needed to
+ compare fields <structfield>f1</structfield> and <structfield>f2</structfield>:
+
+<programlisting>
+WITH RECURSIVE search_graph(id, link, data, depth, <emphasis>is_cycle, path</emphasis>) AS (
+ SELECT g.id, g.link, g.data, 0,
+ <emphasis>false,
+ ARRAY[ROW(g.f1, g.f2)]</emphasis>
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1,
+ <emphasis>ROW(g.f1, g.f2) = ANY(path),
+ path || ROW(g.f1, g.f2)</emphasis>
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link <emphasis>AND NOT is_cycle</emphasis>
+)
+SELECT * FROM search_graph;
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ Omit the <literal>ROW()</literal> syntax in the common case where only one field
+ needs to be checked to recognize a cycle. This allows a simple array
+ rather than a composite-type array to be used, gaining efficiency.
+ </para>
+ </tip>
+
+ <para>
+ There is built-in syntax to simplify cycle detection. The above query can
+ also be written like this:
+<programlisting>
+WITH RECURSIVE search_graph(id, link, data, depth) AS (
+ SELECT g.id, g.link, g.data, 1
+ FROM graph g
+ UNION ALL
+ SELECT g.id, g.link, g.data, sg.depth + 1
+ FROM graph g, search_graph sg
+ WHERE g.id = sg.link
+) <emphasis>CYCLE id SET is_cycle USING path</emphasis>
+SELECT * FROM search_graph;
+</programlisting>
+ and it will be internally rewritten to the above form. The
+ <literal>CYCLE</literal> clause specifies first the list of columns to
+ track for cycle detection, then a column name that will show whether a
+ cycle has been detected, and finally the name of another column that will track the
+ path. The cycle and path columns will implicitly be added to the output
+ rows of the CTE.
+ </para>
+
+ <tip>
+ <para>
+ The cycle path column is computed in the same way as the depth-first
+ ordering column show in the previous section. A query can have both a
+ <literal>SEARCH</literal> and a <literal>CYCLE</literal> clause, but a
+ depth-first search specification and a cycle detection specification would
+ create redundant computations, so it's more efficient to just use the
+ <literal>CYCLE</literal> clause and order by the path column. If
+ breadth-first ordering is wanted, then specifying both
+ <literal>SEARCH</literal> and <literal>CYCLE</literal> can be useful.
+ </para>
+ </tip>
+
+ <para>
+ A helpful trick for testing queries
+ when you are not certain if they might loop is to place a <literal>LIMIT</literal>
+ in the parent query. For example, this query would loop forever without
+ the <literal>LIMIT</literal>:
+
+<programlisting>
+WITH RECURSIVE t(n) AS (
+ SELECT 1
+ UNION ALL
+ SELECT n+1 FROM t
+)
+SELECT n FROM t <emphasis>LIMIT 100</emphasis>;
+</programlisting>
+
+ This works because <productname>PostgreSQL</productname>'s implementation
+ evaluates only as many rows of a <literal>WITH</literal> query as are actually
+ fetched by the parent query. Using this trick in production is not
+ recommended, because other systems might work differently. Also, it
+ usually won't work if you make the outer query sort the recursive query's
+ results or join them to some other table, because in such cases the
+ outer query will usually try to fetch all of the <literal>WITH</literal> query's
+ output anyway.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Common Table Expression Materialization</title>
+
+ <para>
+ A useful property of <literal>WITH</literal> queries is that they are
+ normally evaluated only once per execution of the parent query, even if
+ they are referred to more than once by the parent query or
+ sibling <literal>WITH</literal> queries.
+ Thus, expensive calculations that are needed in multiple places can be
+ placed within a <literal>WITH</literal> query to avoid redundant work. Another
+ possible application is to prevent unwanted multiple evaluations of
+ functions with side-effects.
+ However, the other side of this coin is that the optimizer is not able to
+ push restrictions from the parent query down into a multiply-referenced
+ <literal>WITH</literal> query, since that might affect all uses of the
+ <literal>WITH</literal> query's output when it should affect only one.
+ The multiply-referenced <literal>WITH</literal> query will be
+ evaluated as written, without suppression of rows that the parent query
+ might discard afterwards. (But, as mentioned above, evaluation might stop
+ early if the reference(s) to the query demand only a limited number of
+ rows.)
+ </para>
+
+ <para>
+ However, if a <literal>WITH</literal> query is non-recursive and
+ side-effect-free (that is, it is a <literal>SELECT</literal> containing
+ no volatile functions) then it can be folded into the parent query,
+ allowing joint optimization of the two query levels. By default, this
+ happens if the parent query references the <literal>WITH</literal> query
+ just once, but not if it references the <literal>WITH</literal> query
+ more than once. You can override that decision by
+ specifying <literal>MATERIALIZED</literal> to force separate calculation
+ of the <literal>WITH</literal> query, or by specifying <literal>NOT
+ MATERIALIZED</literal> to force it to be merged into the parent query.
+ The latter choice risks duplicate computation of
+ the <literal>WITH</literal> query, but it can still give a net savings if
+ each usage of the <literal>WITH</literal> query needs only a small part
+ of the <literal>WITH</literal> query's full output.
+ </para>
+
+ <para>
+ A simple example of these rules is
+<programlisting>
+WITH w AS (
+ SELECT * FROM big_table
+)
+SELECT * FROM w WHERE key = 123;
+</programlisting>
+ This <literal>WITH</literal> query will be folded, producing the same
+ execution plan as
+<programlisting>
+SELECT * FROM big_table WHERE key = 123;
+</programlisting>
+ In particular, if there's an index on <structfield>key</structfield>,
+ it will probably be used to fetch just the rows having <literal>key =
+ 123</literal>. On the other hand, in
+<programlisting>
+WITH w AS (
+ SELECT * FROM big_table
+)
+SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
+WHERE w2.key = 123;
+</programlisting>
+ the <literal>WITH</literal> query will be materialized, producing a
+ temporary copy of <structname>big_table</structname> that is then
+ joined with itself &mdash; without benefit of any index. This query
+ will be executed much more efficiently if written as
+<programlisting>
+WITH w AS NOT MATERIALIZED (
+ SELECT * FROM big_table
+)
+SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref
+WHERE w2.key = 123;
+</programlisting>
+ so that the parent query's restrictions can be applied directly
+ to scans of <structname>big_table</structname>.
+ </para>
+
+ <para>
+ An example where <literal>NOT MATERIALIZED</literal> could be
+ undesirable is
+<programlisting>
+WITH w AS (
+ SELECT key, very_expensive_function(val) as f FROM some_table
+)
+SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f;
+</programlisting>
+ Here, materialization of the <literal>WITH</literal> query ensures
+ that <function>very_expensive_function</function> is evaluated only
+ once per table row, not twice.
+ </para>
+
+ <para>
+ The examples above only show <literal>WITH</literal> being used with
+ <command>SELECT</command>, but it can be attached in the same way to
+ <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, or <command>MERGE</command>.
+ In each case it effectively provides temporary table(s) that can
+ be referred to in the main command.
+ </para>
+ </sect2>
+
+ <sect2 id="queries-with-modifying">
+ <title>Data-Modifying Statements in <literal>WITH</literal></title>
+
+ <para>
+ You can use most data-modifying statements (<command>INSERT</command>,
+ <command>UPDATE</command>, or <command>DELETE</command>, but not
+ <command>MERGE</command>) in <literal>WITH</literal>. This
+ allows you to perform several different operations in the same query.
+ An example is:
+
+<programlisting>
+WITH moved_rows AS (
+ DELETE FROM products
+ WHERE
+ "date" &gt;= '2010-10-01' AND
+ "date" &lt; '2010-11-01'
+ RETURNING *
+)
+INSERT INTO products_log
+SELECT * FROM moved_rows;
+</programlisting>
+
+ This query effectively moves rows from <structname>products</structname> to
+ <structname>products_log</structname>. The <command>DELETE</command> in <literal>WITH</literal>
+ deletes the specified rows from <structname>products</structname>, returning their
+ contents by means of its <literal>RETURNING</literal> clause; and then the
+ primary query reads that output and inserts it into
+ <structname>products_log</structname>.
+ </para>
+
+ <para>
+ A fine point of the above example is that the <literal>WITH</literal> clause is
+ attached to the <command>INSERT</command>, not the sub-<command>SELECT</command> within
+ the <command>INSERT</command>. This is necessary because data-modifying
+ statements are only allowed in <literal>WITH</literal> clauses that are attached
+ to the top-level statement. However, normal <literal>WITH</literal> visibility
+ rules apply, so it is possible to refer to the <literal>WITH</literal>
+ statement's output from the sub-<command>SELECT</command>.
+ </para>
+
+ <para>
+ Data-modifying statements in <literal>WITH</literal> usually have
+ <literal>RETURNING</literal> clauses (see <xref linkend="dml-returning"/>),
+ as shown in the example above.
+ It is the output of the <literal>RETURNING</literal> clause, <emphasis>not</emphasis> the
+ target table of the data-modifying statement, that forms the temporary
+ table that can be referred to by the rest of the query. If a
+ data-modifying statement in <literal>WITH</literal> lacks a <literal>RETURNING</literal>
+ clause, then it forms no temporary table and cannot be referred to in
+ the rest of the query. Such a statement will be executed nonetheless.
+ A not-particularly-useful example is:
+
+<programlisting>
+WITH t AS (
+ DELETE FROM foo
+)
+DELETE FROM bar;
+</programlisting>
+
+ This example would remove all rows from tables <structname>foo</structname> and
+ <structname>bar</structname>. The number of affected rows reported to the client
+ would only include rows removed from <structname>bar</structname>.
+ </para>
+
+ <para>
+ Recursive self-references in data-modifying statements are not
+ allowed. In some cases it is possible to work around this limitation by
+ referring to the output of a recursive <literal>WITH</literal>, for example:
+
+<programlisting>
+WITH RECURSIVE included_parts(sub_part, part) AS (
+ SELECT sub_part, part FROM parts WHERE part = 'our_product'
+ UNION ALL
+ SELECT p.sub_part, p.part
+ FROM included_parts pr, parts p
+ WHERE p.part = pr.sub_part
+)
+DELETE FROM parts
+ WHERE part IN (SELECT part FROM included_parts);
+</programlisting>
+
+ This query would remove all direct and indirect subparts of a product.
+ </para>
+
+ <para>
+ Data-modifying statements in <literal>WITH</literal> are executed exactly once,
+ and always to completion, independently of whether the primary query
+ reads all (or indeed any) of their output. Notice that this is different
+ from the rule for <command>SELECT</command> in <literal>WITH</literal>: as stated in the
+ previous section, execution of a <command>SELECT</command> is carried only as far
+ as the primary query demands its output.
+ </para>
+
+ <para>
+ The sub-statements in <literal>WITH</literal> are executed concurrently with
+ each other and with the main query. Therefore, when using data-modifying
+ statements in <literal>WITH</literal>, the order in which the specified updates
+ actually happen is unpredictable. All the statements are executed with
+ the same <firstterm>snapshot</firstterm> (see <xref linkend="mvcc"/>), so they
+ cannot <quote>see</quote> one another's effects on the target tables. This
+ alleviates the effects of the unpredictability of the actual order of row
+ updates, and means that <literal>RETURNING</literal> data is the only way to
+ communicate changes between different <literal>WITH</literal> sub-statements and
+ the main query. An example of this is that in
+
+<programlisting>
+WITH t AS (
+ UPDATE products SET price = price * 1.05
+ RETURNING *
+)
+SELECT * FROM products;
+</programlisting>
+
+ the outer <command>SELECT</command> would return the original prices before the
+ action of the <command>UPDATE</command>, while in
+
+<programlisting>
+WITH t AS (
+ UPDATE products SET price = price * 1.05
+ RETURNING *
+)
+SELECT * FROM t;
+</programlisting>
+
+ the outer <command>SELECT</command> would return the updated data.
+ </para>
+
+ <para>
+ Trying to update the same row twice in a single statement is not
+ supported. Only one of the modifications takes place, but it is not easy
+ (and sometimes not possible) to reliably predict which one. This also
+ applies to deleting a row that was already updated in the same statement:
+ only the update is performed. Therefore you should generally avoid trying
+ to modify a single row twice in a single statement. In particular avoid
+ writing <literal>WITH</literal> sub-statements that could affect the same rows
+ changed by the main statement or a sibling sub-statement. The effects
+ of such a statement will not be predictable.
+ </para>
+
+ <para>
+ At present, any table used as the target of a data-modifying statement in
+ <literal>WITH</literal> must not have a conditional rule, nor an <literal>ALSO</literal>
+ rule, nor an <literal>INSTEAD</literal> rule that expands to multiple statements.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/query.sgml b/doc/src/sgml/query.sgml
new file mode 100644
index 0000000..a864d14
--- /dev/null
+++ b/doc/src/sgml/query.sgml
@@ -0,0 +1,910 @@
+<!-- doc/src/sgml/query.sgml -->
+
+ <chapter id="tutorial-sql">
+ <title>The <acronym>SQL</acronym> Language</title>
+
+ <sect1 id="tutorial-sql-intro">
+ <title>Introduction</title>
+
+ <para>
+ This chapter provides an overview of how to use
+ <acronym>SQL</acronym> to perform simple operations. This
+ tutorial is only intended to give you an introduction and is in no
+ way a complete tutorial on <acronym>SQL</acronym>. Numerous books
+ have been written on <acronym>SQL</acronym>, including <xref
+ linkend="melt93"/> and <xref linkend="date97"/>.
+ You should be aware that some <productname>PostgreSQL</productname>
+ language features are extensions to the standard.
+ </para>
+
+ <para>
+ In the examples that follow, we assume that you have created a
+ database named <literal>mydb</literal>, as described in the previous
+ chapter, and have been able to start <application>psql</application>.
+ </para>
+
+ <para>
+ Examples in this manual can also be found in the
+ <productname>PostgreSQL</productname> source distribution
+ in the directory <filename>src/tutorial/</filename>. (Binary
+ distributions of <productname>PostgreSQL</productname> might not
+ provide those files.) To use those
+ files, first change to that directory and run <application>make</application>:
+
+<screen>
+<prompt>$</prompt> <userinput>cd <replaceable>...</replaceable>/src/tutorial</userinput>
+<prompt>$</prompt> <userinput>make</userinput>
+</screen>
+
+ This creates the scripts and compiles the C files containing user-defined
+ functions and types. Then, to start the tutorial, do the following:
+
+<screen>
+<prompt>$</prompt> <userinput>psql -s mydb</userinput>
+<computeroutput>
+...
+</computeroutput>
+<prompt>mydb=&gt;</prompt> <userinput>\i basics.sql</userinput>
+</screen>
+
+ The <literal>\i</literal> command reads in commands from the
+ specified file. <command>psql</command>'s <literal>-s</literal> option puts you in
+ single step mode which pauses before sending each statement to the
+ server. The commands used in this section are in the file
+ <filename>basics.sql</filename>.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-concepts">
+ <title>Concepts</title>
+
+ <para>
+ <indexterm><primary>relational database</primary></indexterm>
+ <indexterm><primary>hierarchical database</primary></indexterm>
+ <indexterm><primary>object-oriented database</primary></indexterm>
+ <indexterm><primary>relation</primary></indexterm>
+ <indexterm><primary>table</primary></indexterm>
+
+ <productname>PostgreSQL</productname> is a <firstterm>relational
+ database management system</firstterm> (<acronym>RDBMS</acronym>).
+ That means it is a system for managing data stored in
+ <firstterm>relations</firstterm>. Relation is essentially a
+ mathematical term for <firstterm>table</firstterm>. The notion of
+ storing data in tables is so commonplace today that it might
+ seem inherently obvious, but there are a number of other ways of
+ organizing databases. Files and directories on Unix-like
+ operating systems form an example of a hierarchical database. A
+ more modern development is the object-oriented database.
+ </para>
+
+ <para>
+ <indexterm><primary>row</primary></indexterm>
+ <indexterm><primary>column</primary></indexterm>
+
+ Each table is a named collection of <firstterm>rows</firstterm>.
+ Each row of a given table has the same set of named
+ <firstterm>columns</firstterm>,
+ and each column is of a specific data type. Whereas columns have
+ a fixed order in each row, it is important to remember that SQL
+ does not guarantee the order of the rows within the table in any
+ way (although they can be explicitly sorted for display).
+ </para>
+
+ <para>
+ <indexterm><primary>database cluster</primary></indexterm>
+ <indexterm><primary>cluster</primary><secondary>of databases</secondary><see>database cluster</see></indexterm>
+
+ Tables are grouped into databases, and a collection of databases
+ managed by a single <productname>PostgreSQL</productname> server
+ instance constitutes a database <firstterm>cluster</firstterm>.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-table">
+ <title>Creating a New Table</title>
+
+ <indexterm zone="tutorial-table">
+ <primary>CREATE TABLE</primary>
+ </indexterm>
+
+ <para>
+ You can create a new table by specifying the table
+ name, along with all column names and their types:
+
+<programlisting>
+CREATE TABLE weather (
+ city varchar(80),
+ temp_lo int, -- low temperature
+ temp_hi int, -- high temperature
+ prcp real, -- precipitation
+ date date
+);
+</programlisting>
+
+ You can enter this into <command>psql</command> with the line
+ breaks. <command>psql</command> will recognize that the command
+ is not terminated until the semicolon.
+ </para>
+
+ <para>
+ White space (i.e., spaces, tabs, and newlines) can be used freely
+ in SQL commands. That means you can type the command aligned
+ differently than above, or even all on one line. Two dashes
+ (<quote><literal>--</literal></quote>) introduce comments.
+ Whatever follows them is ignored up to the end of the line. SQL
+ is case insensitive about key words and identifiers, except
+ when identifiers are double-quoted to preserve the case (not done
+ above).
+ </para>
+
+ <para>
+ <type>varchar(80)</type> specifies a data type that can store
+ arbitrary character strings up to 80 characters in length.
+ <type>int</type> is the normal integer type. <type>real</type> is
+ a type for storing single precision floating-point numbers.
+ <type>date</type> should be self-explanatory. (Yes, the column of
+ type <type>date</type> is also named <structfield>date</structfield>.
+ This might be convenient or confusing &mdash; you choose.)
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> supports the standard
+ <acronym>SQL</acronym> types <type>int</type>,
+ <type>smallint</type>, <type>real</type>, <type>double
+ precision</type>, <type>char(<replaceable>N</replaceable>)</type>,
+ <type>varchar(<replaceable>N</replaceable>)</type>, <type>date</type>,
+ <type>time</type>, <type>timestamp</type>, and
+ <type>interval</type>, as well as other types of general utility
+ and a rich set of geometric types.
+ <productname>PostgreSQL</productname> can be customized with an
+ arbitrary number of user-defined data types. Consequently, type
+ names are not key words in the syntax, except where required to
+ support special cases in the <acronym>SQL</acronym> standard.
+ </para>
+
+ <para>
+ The second example will store cities and their associated
+ geographical location:
+<programlisting>
+CREATE TABLE cities (
+ name varchar(80),
+ location point
+);
+</programlisting>
+ The <type>point</type> type is an example of a
+ <productname>PostgreSQL</productname>-specific data type.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>DROP TABLE</primary>
+ </indexterm>
+
+ Finally, it should be mentioned that if you don't need a table any
+ longer or want to recreate it differently you can remove it using
+ the following command:
+<synopsis>
+DROP TABLE <replaceable>tablename</replaceable>;
+</synopsis>
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-populate">
+ <title>Populating a Table With Rows</title>
+
+ <indexterm zone="tutorial-populate">
+ <primary>INSERT</primary>
+ </indexterm>
+
+ <para>
+ The <command>INSERT</command> statement is used to populate a table with
+ rows:
+
+<programlisting>
+INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
+</programlisting>
+
+ Note that all data types use rather obvious input formats.
+ Constants that are not simple numeric values usually must be
+ surrounded by single quotes (<literal>'</literal>), as in the example.
+ The
+ <type>date</type> type is actually quite flexible in what it
+ accepts, but for this tutorial we will stick to the unambiguous
+ format shown here.
+ </para>
+
+ <para>
+ The <type>point</type> type requires a coordinate pair as input,
+ as shown here:
+<programlisting>
+INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
+</programlisting>
+ </para>
+
+ <para>
+ The syntax used so far requires you to remember the order of the
+ columns. An alternative syntax allows you to list the columns
+ explicitly:
+<programlisting>
+INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
+ VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');
+</programlisting>
+ You can list the columns in a different order if you wish or
+ even omit some columns, e.g., if the precipitation is unknown:
+<programlisting>
+INSERT INTO weather (date, city, temp_hi, temp_lo)
+ VALUES ('1994-11-29', 'Hayward', 54, 37);
+</programlisting>
+ Many developers consider explicitly listing the columns better
+ style than relying on the order implicitly.
+ </para>
+
+ <para>
+ Please enter all the commands shown above so you have some data to
+ work with in the following sections.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>COPY</primary>
+ </indexterm>
+
+ You could also have used <command>COPY</command> to load large
+ amounts of data from flat-text files. This is usually faster
+ because the <command>COPY</command> command is optimized for this
+ application while allowing less flexibility than
+ <command>INSERT</command>. An example would be:
+
+<programlisting>
+COPY weather FROM '/home/user/weather.txt';
+</programlisting>
+
+ where the file name for the source file must be available on the
+ machine running the backend process, not the client, since the backend process
+ reads the file directly. You can read more about the
+ <command>COPY</command> command in <xref linkend="sql-copy"/>.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-select">
+ <title>Querying a Table</title>
+
+ <para>
+ <indexterm><primary>query</primary></indexterm>
+ <indexterm><primary>SELECT</primary></indexterm>
+
+ To retrieve data from a table, the table is
+ <firstterm>queried</firstterm>. An <acronym>SQL</acronym>
+ <command>SELECT</command> statement is used to do this. The
+ statement is divided into a select list (the part that lists the
+ columns to be returned), a table list (the part that lists the
+ tables from which to retrieve the data), and an optional
+ qualification (the part that specifies any restrictions). For
+ example, to retrieve all the rows of table
+ <structname>weather</structname>, type:
+<programlisting>
+SELECT * FROM weather;
+</programlisting>
+ Here <literal>*</literal> is a shorthand for <quote>all columns</quote>.
+ <footnote>
+ <para>
+ While <literal>SELECT *</literal> is useful for off-the-cuff
+ queries, it is widely considered bad style in production code,
+ since adding a column to the table would change the results.
+ </para>
+ </footnote>
+ So the same result would be had with:
+<programlisting>
+SELECT city, temp_lo, temp_hi, prcp, date FROM weather;
+</programlisting>
+
+ The output should be:
+
+<screen>
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 43 | 57 | 0 | 1994-11-29
+ Hayward | 37 | 54 | | 1994-11-29
+(3 rows)
+</screen>
+ </para>
+
+ <para>
+ You can write expressions, not just simple column references, in the
+ select list. For example, you can do:
+<programlisting>
+SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
+</programlisting>
+ This should give:
+<screen>
+ city | temp_avg | date
+---------------+----------+------------
+ San Francisco | 48 | 1994-11-27
+ San Francisco | 50 | 1994-11-29
+ Hayward | 45 | 1994-11-29
+(3 rows)
+</screen>
+ Notice how the <literal>AS</literal> clause is used to relabel the
+ output column. (The <literal>AS</literal> clause is optional.)
+ </para>
+
+ <para>
+ A query can be <quote>qualified</quote> by adding a <literal>WHERE</literal>
+ clause that specifies which rows are wanted. The <literal>WHERE</literal>
+ clause contains a Boolean (truth value) expression, and only rows for
+ which the Boolean expression is true are returned. The usual
+ Boolean operators (<literal>AND</literal>,
+ <literal>OR</literal>, and <literal>NOT</literal>) are allowed in
+ the qualification. For example, the following
+ retrieves the weather of San Francisco on rainy days:
+
+<programlisting>
+SELECT * FROM weather
+ WHERE city = 'San Francisco' AND prcp &gt; 0.0;
+</programlisting>
+ Result:
+<screen>
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ <indexterm><primary>ORDER BY</primary></indexterm>
+
+ You can request that the results of a query
+ be returned in sorted order:
+
+<programlisting>
+SELECT * FROM weather
+ ORDER BY city;
+</programlisting>
+
+<screen>
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ Hayward | 37 | 54 | | 1994-11-29
+ San Francisco | 43 | 57 | 0 | 1994-11-29
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+</screen>
+
+ In this example, the sort order isn't fully specified, and so you
+ might get the San Francisco rows in either order. But you'd always
+ get the results shown above if you do:
+
+<programlisting>
+SELECT * FROM weather
+ ORDER BY city, temp_lo;
+</programlisting>
+ </para>
+
+ <para>
+ <indexterm><primary>DISTINCT</primary></indexterm>
+ <indexterm><primary>duplicate</primary></indexterm>
+
+ You can request that duplicate rows be removed from the result of
+ a query:
+
+<programlisting>
+SELECT DISTINCT city
+ FROM weather;
+</programlisting>
+
+<screen>
+ city
+---------------
+ Hayward
+ San Francisco
+(2 rows)
+</screen>
+
+ Here again, the result row ordering might vary.
+ You can ensure consistent results by using <literal>DISTINCT</literal> and
+ <literal>ORDER BY</literal> together:
+ <footnote>
+ <para>
+ In some database systems, including older versions of
+ <productname>PostgreSQL</productname>, the implementation of
+ <literal>DISTINCT</literal> automatically orders the rows and
+ so <literal>ORDER BY</literal> is unnecessary. But this is not
+ required by the SQL standard, and current
+ <productname>PostgreSQL</productname> does not guarantee that
+ <literal>DISTINCT</literal> causes the rows to be ordered.
+ </para>
+ </footnote>
+
+<programlisting>
+SELECT DISTINCT city
+ FROM weather
+ ORDER BY city;
+</programlisting>
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-join">
+ <title>Joins Between Tables</title>
+
+ <indexterm zone="tutorial-join">
+ <primary>join</primary>
+ </indexterm>
+
+ <para>
+ Thus far, our queries have only accessed one table at a time.
+ Queries can access multiple tables at once, or access the same
+ table in such a way that multiple rows of the table are being
+ processed at the same time. Queries that access multiple tables
+ (or multiple instances of the same table) at one time are called
+ <firstterm>join</firstterm> queries. They combine rows from one table
+ with rows from a second table, with an expression specifying which rows
+ are to be paired. For example, to return all the weather records together
+ with the location of the associated city, the database needs to compare
+ the <structfield>city</structfield>
+ column of each row of the <structname>weather</structname> table with the
+ <structfield>name</structfield> column of all rows in the <structname>cities</structname>
+ table, and select the pairs of rows where these values match.<footnote>
+ <para>
+ This is only a conceptual model. The join is usually performed
+ in a more efficient manner than actually comparing each possible
+ pair of rows, but this is invisible to the user.
+ </para>
+ </footnote>
+ This would be accomplished by the following query:
+
+<programlisting>
+SELECT * FROM weather JOIN cities ON city = name;
+</programlisting>
+
+<screen>
+ city | temp_lo | temp_hi | prcp | date | name | location
+---------------+---------+---------+------+------------+---------------+-----------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
+ San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
+(2 rows)
+</screen>
+
+ </para>
+
+ <para>
+ Observe two things about the result set:
+ <itemizedlist>
+ <listitem>
+ <para>
+ There is no result row for the city of Hayward. This is
+ because there is no matching entry in the
+ <structname>cities</structname> table for Hayward, so the join
+ ignores the unmatched rows in the <structname>weather</structname> table. We will see
+ shortly how this can be fixed.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ There are two columns containing the city name. This is
+ correct because the lists of columns from the
+ <structname>weather</structname> and
+ <structname>cities</structname> tables are concatenated. In
+ practice this is undesirable, though, so you will probably want
+ to list the output columns explicitly rather than using
+ <literal>*</literal>:
+<programlisting>
+SELECT city, temp_lo, temp_hi, prcp, date, location
+ FROM weather JOIN cities ON city = name;
+</programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Since the columns all had different names, the parser
+ automatically found which table they belong to. If there
+ were duplicate column names in the two tables you'd need to
+ <firstterm>qualify</firstterm> the column names to show which one you
+ meant, as in:
+
+<programlisting>
+SELECT weather.city, weather.temp_lo, weather.temp_hi,
+ weather.prcp, weather.date, cities.location
+ FROM weather JOIN cities ON weather.city = cities.name;
+</programlisting>
+
+ It is widely considered good style to qualify all column names
+ in a join query, so that the query won't fail if a duplicate
+ column name is later added to one of the tables.
+ </para>
+
+ <para>
+ Join queries of the kind seen thus far can also be written in this
+ form:
+
+<programlisting>
+SELECT *
+ FROM weather, cities
+ WHERE city = name;
+</programlisting>
+
+ This syntax pre-dates the <literal>JOIN</literal>/<literal>ON</literal>
+ syntax, which was introduced in SQL-92. The tables are simply listed in
+ the <literal>FROM</literal> clause, and the comparison expression is added
+ to the <literal>WHERE</literal> clause. The results from this older
+ implicit syntax and the newer explicit
+ <literal>JOIN</literal>/<literal>ON</literal> syntax are identical. But
+ for a reader of the query, the explicit syntax makes its meaning easier to
+ understand: The join condition is introduced by its own key word whereas
+ previously the condition was mixed into the <literal>WHERE</literal>
+ clause together with other conditions.
+ </para>
+
+ <indexterm><primary>join</primary><secondary>outer</secondary></indexterm>
+
+ <para>
+ Now we will figure out how we can get the Hayward records back in.
+ What we want the query to do is to scan the
+ <structname>weather</structname> table and for each row to find the
+ matching <structname>cities</structname> row(s). If no matching row is
+ found we want some <quote>empty values</quote> to be substituted
+ for the <structname>cities</structname> table's columns. This kind
+ of query is called an <firstterm>outer join</firstterm>. (The
+ joins we have seen so far are <firstterm>inner joins</firstterm>.)
+ The command looks like this:
+
+<programlisting>
+SELECT *
+ FROM weather LEFT OUTER JOIN cities ON weather.city = cities.name;
+</programlisting>
+
+<screen>
+ city | temp_lo | temp_hi | prcp | date | name | location
+---------------+---------+---------+------+------------+---------------+-----------
+ Hayward | 37 | 54 | | 1994-11-29 | |
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
+ San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
+(3 rows)
+</screen>
+
+ This query is called a <firstterm>left outer
+ join</firstterm> because the table mentioned on the left of the
+ join operator will have each of its rows in the output at least
+ once, whereas the table on the right will only have those rows
+ output that match some row of the left table. When outputting a
+ left-table row for which there is no right-table match, empty (null)
+ values are substituted for the right-table columns.
+ </para>
+
+ <formalpara>
+ <title>Exercise:</title>
+
+ <para>
+ There are also right outer joins and full outer joins. Try to
+ find out what those do.
+ </para>
+ </formalpara>
+
+ <indexterm><primary>join</primary><secondary>self</secondary></indexterm>
+ <indexterm><primary>alias</primary><secondary>for table name in query</secondary></indexterm>
+ <para>
+ We can also join a table against itself. This is called a
+ <firstterm>self join</firstterm>. As an example, suppose we wish
+ to find all the weather records that are in the temperature range
+ of other weather records. So we need to compare the
+ <structfield>temp_lo</structfield> and <structfield>temp_hi</structfield> columns of
+ each <structname>weather</structname> row to the
+ <structfield>temp_lo</structfield> and
+ <structfield>temp_hi</structfield> columns of all other
+ <structname>weather</structname> rows. We can do this with the
+ following query:
+
+<programlisting>
+SELECT w1.city, w1.temp_lo AS low, w1.temp_hi AS high,
+ w2.city, w2.temp_lo AS low, w2.temp_hi AS high
+ FROM weather w1 JOIN weather w2
+ ON w1.temp_lo &lt; w2.temp_lo AND w1.temp_hi &gt; w2.temp_hi;
+</programlisting>
+
+<screen>
+ city | low | high | city | low | high
+---------------+-----+------+---------------+-----+------
+ San Francisco | 43 | 57 | San Francisco | 46 | 50
+ Hayward | 37 | 54 | San Francisco | 46 | 50
+(2 rows)
+</screen>
+
+ Here we have relabeled the weather table as <literal>w1</literal> and
+ <literal>w2</literal> to be able to distinguish the left and right side
+ of the join. You can also use these kinds of aliases in other
+ queries to save some typing, e.g.:
+<programlisting>
+SELECT *
+ FROM weather w JOIN cities c ON w.city = c.name;
+</programlisting>
+ You will encounter this style of abbreviating quite frequently.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-agg">
+ <title>Aggregate Functions</title>
+
+ <indexterm zone="tutorial-agg">
+ <primary>aggregate function</primary>
+ </indexterm>
+
+ <para>
+ Like most other relational database products,
+ <productname>PostgreSQL</productname> supports
+ <firstterm>aggregate functions</firstterm>.
+ An aggregate function computes a single result from multiple input rows.
+ For example, there are aggregates to compute the
+ <function>count</function>, <function>sum</function>,
+ <function>avg</function> (average), <function>max</function> (maximum) and
+ <function>min</function> (minimum) over a set of rows.
+ </para>
+
+ <para>
+ As an example, we can find the highest low-temperature reading anywhere
+ with:
+
+<programlisting>
+SELECT max(temp_lo) FROM weather;
+</programlisting>
+
+<screen>
+ max
+-----
+ 46
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ <indexterm><primary>subquery</primary></indexterm>
+
+ If we wanted to know what city (or cities) that reading occurred in,
+ we might try:
+
+<programlisting>
+SELECT city FROM weather WHERE temp_lo = max(temp_lo); <lineannotation>WRONG</lineannotation>
+</programlisting>
+
+ but this will not work since the aggregate
+ <function>max</function> cannot be used in the
+ <literal>WHERE</literal> clause. (This restriction exists because
+ the <literal>WHERE</literal> clause determines which rows will be
+ included in the aggregate calculation; so obviously it has to be evaluated
+ before aggregate functions are computed.)
+ However, as is often the case
+ the query can be restated to accomplish the desired result, here
+ by using a <firstterm>subquery</firstterm>:
+
+<programlisting>
+SELECT city FROM weather
+ WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
+</programlisting>
+
+<screen>
+ city
+---------------
+ San Francisco
+(1 row)
+</screen>
+
+ This is OK because the subquery is an independent computation
+ that computes its own aggregate separately from what is happening
+ in the outer query.
+ </para>
+
+ <para>
+ <indexterm><primary>GROUP BY</primary></indexterm>
+ <indexterm><primary>HAVING</primary></indexterm>
+
+ Aggregates are also very useful in combination with <literal>GROUP
+ BY</literal> clauses. For example, we can get the number of readings
+ and the maximum low temperature observed in each city with:
+
+<programlisting>
+SELECT city, count(*), max(temp_lo)
+ FROM weather
+ GROUP BY city;
+</programlisting>
+
+<screen>
+ city | count | max
+---------------+-------+-----
+ Hayward | 1 | 37
+ San Francisco | 2 | 46
+(2 rows)
+</screen>
+
+ which gives us one output row per city. Each aggregate result is
+ computed over the table rows matching that city.
+ We can filter these grouped
+ rows using <literal>HAVING</literal>:
+
+<programlisting>
+SELECT city, count(*), max(temp_lo)
+ FROM weather
+ GROUP BY city
+ HAVING max(temp_lo) &lt; 40;
+</programlisting>
+
+<screen>
+ city | count | max
+---------+-------+-----
+ Hayward | 1 | 37
+(1 row)
+</screen>
+
+ which gives us the same results for only the cities that have all
+ <structfield>temp_lo</structfield> values below 40. Finally, if we only care about
+ cities whose
+ names begin with <quote><literal>S</literal></quote>, we might do:
+
+<programlisting>
+SELECT city, count(*), max(temp_lo)
+ FROM weather
+ WHERE city LIKE 'S%' -- <co id="co.tutorial-agg-like"/>
+ GROUP BY city;
+</programlisting>
+
+<screen>
+ city | count | max
+---------------+-------+-----
+ San Francisco | 2 | 46
+(1 row)
+</screen>
+ <calloutlist>
+ <callout arearefs="co.tutorial-agg-like">
+ <para>
+ The <literal>LIKE</literal> operator does pattern matching and
+ is explained in <xref linkend="functions-matching"/>.
+ </para>
+ </callout>
+ </calloutlist>
+ </para>
+
+ <para>
+ It is important to understand the interaction between aggregates and
+ <acronym>SQL</acronym>'s <literal>WHERE</literal> and <literal>HAVING</literal> clauses.
+ The fundamental difference between <literal>WHERE</literal> and
+ <literal>HAVING</literal> is this: <literal>WHERE</literal> selects
+ input rows before groups and aggregates are computed (thus, it controls
+ which rows go into the aggregate computation), whereas
+ <literal>HAVING</literal> selects group rows after groups and
+ aggregates are computed. Thus, the
+ <literal>WHERE</literal> clause must not contain aggregate functions;
+ it makes no sense to try to use an aggregate to determine which rows
+ will be inputs to the aggregates. On the other hand, the
+ <literal>HAVING</literal> clause always contains aggregate functions.
+ (Strictly speaking, you are allowed to write a <literal>HAVING</literal>
+ clause that doesn't use aggregates, but it's seldom useful. The same
+ condition could be used more efficiently at the <literal>WHERE</literal>
+ stage.)
+ </para>
+
+ <para>
+ In the previous example, we can apply the city name restriction in
+ <literal>WHERE</literal>, since it needs no aggregate. This is
+ more efficient than adding the restriction to <literal>HAVING</literal>,
+ because we avoid doing the grouping and aggregate calculations
+ for all rows that fail the <literal>WHERE</literal> check.
+ </para>
+
+ <para>
+ Another way to select the rows that go into an aggregate
+ computation is to use <literal>FILTER</literal>, which is a
+ per-aggregate option:
+
+<programlisting>
+SELECT city, count(*) FILTER (WHERE temp_lo &lt; 45), max(temp_lo)
+ FROM weather
+ GROUP BY city;
+</programlisting>
+
+<screen>
+ city | count | max
+---------------+-------+-----
+ Hayward | 1 | 37
+ San Francisco | 1 | 46
+(2 rows)
+</screen>
+
+ <literal>FILTER</literal> is much like <literal>WHERE</literal>,
+ except that it removes rows only from the input of the particular
+ aggregate function that it is attached to.
+ Here, the <literal>count</literal> aggregate counts only
+ rows with <literal>temp_lo</literal> below 45; but the
+ <literal>max</literal> aggregate is still applied to all rows,
+ so it still finds the reading of 46.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-update">
+ <title>Updates</title>
+
+ <indexterm zone="tutorial-update">
+ <primary>UPDATE</primary>
+ </indexterm>
+
+ <para>
+ You can update existing rows using the
+ <command>UPDATE</command> command.
+ Suppose you discover the temperature readings are
+ all off by 2 degrees after November 28. You can correct the
+ data as follows:
+
+<programlisting>
+UPDATE weather
+ SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
+ WHERE date &gt; '1994-11-28';
+</programlisting>
+ </para>
+
+ <para>
+ Look at the new state of the data:
+<programlisting>
+SELECT * FROM weather;
+
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 41 | 55 | 0 | 1994-11-29
+ Hayward | 35 | 52 | | 1994-11-29
+(3 rows)
+</programlisting>
+ </para>
+ </sect1>
+
+ <sect1 id="tutorial-delete">
+ <title>Deletions</title>
+
+ <indexterm zone="tutorial-delete">
+ <primary>DELETE</primary>
+ </indexterm>
+
+ <para>
+ Rows can be removed from a table using the <command>DELETE</command>
+ command.
+ Suppose you are no longer interested in the weather of Hayward.
+ Then you can do the following to delete those rows from the table:
+<programlisting>
+DELETE FROM weather WHERE city = 'Hayward';
+</programlisting>
+
+ All weather records belonging to Hayward are removed.
+
+<programlisting>
+SELECT * FROM weather;
+</programlisting>
+
+<screen>
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 41 | 55 | 0 | 1994-11-29
+(2 rows)
+</screen>
+ </para>
+
+ <para>
+ One should be wary of statements of the form
+<synopsis>
+DELETE FROM <replaceable>tablename</replaceable>;
+</synopsis>
+
+ Without a qualification, <command>DELETE</command> will
+ remove <emphasis>all</emphasis> rows from the given table, leaving it
+ empty. The system will not request confirmation before
+ doing this!
+ </para>
+ </sect1>
+
+ </chapter>
diff --git a/doc/src/sgml/rangetypes.sgml b/doc/src/sgml/rangetypes.sgml
new file mode 100644
index 0000000..92ea0e8
--- /dev/null
+++ b/doc/src/sgml/rangetypes.sgml
@@ -0,0 +1,592 @@
+<!-- doc/src/sgml/rangetypes.sgml -->
+
+<sect1 id="rangetypes">
+ <title>Range Types</title>
+
+ <indexterm>
+ <primary>range type</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>multirange type</primary>
+ </indexterm>
+
+ <para>
+ Range types are data types representing a range of values of some
+ element type (called the range's <firstterm>subtype</firstterm>).
+ For instance, ranges
+ of <type>timestamp</type> might be used to represent the ranges of
+ time that a meeting room is reserved. In this case the data type
+ is <type>tsrange</type> (short for <quote>timestamp range</quote>),
+ and <type>timestamp</type> is the subtype. The subtype must have
+ a total order so that it is well-defined whether element values are
+ within, before, or after a range of values.
+ </para>
+
+ <para>
+ Range types are useful because they represent many element values in a
+ single range value, and because concepts such as overlapping ranges can
+ be expressed clearly. The use of time and date ranges for scheduling
+ purposes is the clearest example; but price ranges, measurement
+ ranges from an instrument, and so forth can also be useful.
+ </para>
+
+ <para>
+ Every range type has a corresponding multirange type. A multirange is
+ an ordered list of non-contiguous, non-empty, non-null ranges. Most
+ range operators also work on multiranges, and they have a few functions
+ of their own.
+ </para>
+
+ <sect2 id="rangetypes-builtin">
+ <title>Built-in Range and Multirange Types</title>
+
+ <para>
+ PostgreSQL comes with the following built-in range types:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <type>int4range</type> &mdash; Range of <type>integer</type>,
+ <type>int4multirange</type> &mdash; corresponding Multirange
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <type>int8range</type> &mdash; Range of <type>bigint</type>,
+ <type>int8multirange</type> &mdash; corresponding Multirange
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <type>numrange</type> &mdash; Range of <type>numeric</type>,
+ <type>nummultirange</type> &mdash; corresponding Multirange
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <type>tsrange</type> &mdash; Range of <type>timestamp without time zone</type>,
+ <type>tsmultirange</type> &mdash; corresponding Multirange
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <type>tstzrange</type> &mdash; Range of <type>timestamp with time zone</type>,
+ <type>tstzmultirange</type> &mdash; corresponding Multirange
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <type>daterange</type> &mdash; Range of <type>date</type>,
+ <type>datemultirange</type> &mdash; corresponding Multirange
+ </para>
+ </listitem>
+ </itemizedlist>
+ In addition, you can define your own range types;
+ see <xref linkend="sql-createtype"/> for more information.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-examples">
+ <title>Examples</title>
+
+ <para>
+<programlisting>
+CREATE TABLE reservation (room int, during tsrange);
+INSERT INTO reservation VALUES
+ (1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
+
+-- Containment
+SELECT int4range(10, 20) @&gt; 3;
+
+-- Overlaps
+SELECT numrange(11.1, 22.2) &amp;&amp; numrange(20.0, 30.0);
+
+-- Extract the upper bound
+SELECT upper(int8range(15, 25));
+
+-- Compute the intersection
+SELECT int4range(10, 20) * int4range(15, 25);
+
+-- Is the range empty?
+SELECT isempty(numrange(1, 5));
+</programlisting>
+
+ See <xref linkend="range-operators-table"/>
+ and <xref linkend="range-functions-table"/> for complete lists of
+ operators and functions on range types.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-inclusivity">
+ <title>Inclusive and Exclusive Bounds</title>
+
+ <para>
+ Every non-empty range has two bounds, the lower bound and the upper
+ bound. All points between these values are included in the range. An
+ inclusive bound means that the boundary point itself is included in
+ the range as well, while an exclusive bound means that the boundary
+ point is not included in the range.
+ </para>
+
+ <para>
+ In the text form of a range, an inclusive lower bound is represented by
+ <quote><literal>[</literal></quote> while an exclusive lower bound is
+ represented by <quote><literal>(</literal></quote>. Likewise, an inclusive upper bound is represented by
+ <quote><literal>]</literal></quote>, while an exclusive upper bound is
+ represented by <quote><literal>)</literal></quote>.
+ (See <xref linkend="rangetypes-io"/> for more details.)
+ </para>
+
+ <para>
+ The functions <literal>lower_inc</literal>
+ and <literal>upper_inc</literal> test the inclusivity of the lower
+ and upper bounds of a range value, respectively.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-infinite">
+ <title>Infinite (Unbounded) Ranges</title>
+
+ <para>
+ The lower bound of a range can be omitted, meaning that all
+ values less than the upper bound are included in the range, e.g.,
+ <literal>(,3]</literal>. Likewise, if the upper bound of the range
+ is omitted, then all values greater than the lower bound are included
+ in the range. If both lower and upper bounds are omitted, all values
+ of the element type are considered to be in the range. Specifying a
+ missing bound as inclusive is automatically converted to exclusive,
+ e.g., <literal>[,]</literal> is converted to <literal>(,)</literal>.
+ You can think of these missing values as +/-infinity, but they are
+ special range type values and are considered to be beyond any range
+ element type's +/-infinity values.
+ </para>
+
+ <para>
+ Element types that have the notion of <quote>infinity</quote> can
+ use them as explicit bound values. For example, with timestamp
+ ranges, <literal>[today,infinity)</literal> excludes the special
+ <type>timestamp</type> value <literal>infinity</literal>,
+ while <literal>[today,infinity]</literal> include it, as does
+ <literal>[today,)</literal> and <literal>[today,]</literal>.
+ </para>
+
+ <para>
+ The functions <literal>lower_inf</literal>
+ and <literal>upper_inf</literal> test for infinite lower
+ and upper bounds of a range, respectively.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-io">
+ <title>Range Input/Output</title>
+
+ <para>
+ The input for a range value must follow one of the following patterns:
+<synopsis>
+(<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>)
+(<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>]
+[<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>)
+[<replaceable>lower-bound</replaceable>,<replaceable>upper-bound</replaceable>]
+empty
+</synopsis>
+ The parentheses or brackets indicate whether the lower and upper bounds
+ are exclusive or inclusive, as described previously.
+ Notice that the final pattern is <literal>empty</literal>, which
+ represents an empty range (a range that contains no points).
+ </para>
+
+ <para>
+ The <replaceable>lower-bound</replaceable> may be either a string
+ that is valid input for the subtype, or empty to indicate no
+ lower bound. Likewise, <replaceable>upper-bound</replaceable> may be
+ either a string that is valid input for the subtype, or empty to
+ indicate no upper bound.
+ </para>
+
+ <para>
+ Each bound value can be quoted using <literal>"</literal> (double quote)
+ characters. This is necessary if the bound value contains parentheses,
+ brackets, commas, double quotes, or backslashes, since these characters
+ would otherwise be taken as part of the range syntax. To put a double
+ quote or backslash in a quoted bound value, precede it with a
+ backslash. (Also, a pair of double quotes within a double-quoted bound
+ value is taken to represent a double quote character, analogously to the
+ rules for single quotes in SQL literal strings.) Alternatively, you can
+ avoid quoting and use backslash-escaping to protect all data characters
+ that would otherwise be taken as range syntax. Also, to write a bound
+ value that is an empty string, write <literal>""</literal>, since writing
+ nothing means an infinite bound.
+ </para>
+
+ <para>
+ Whitespace is allowed before and after the range value, but any whitespace
+ between the parentheses or brackets is taken as part of the lower or upper
+ bound value. (Depending on the element type, it might or might not be
+ significant.)
+ </para>
+
+ <note>
+ <para>
+ These rules are very similar to those for writing field values in
+ composite-type literals. See <xref linkend="rowtypes-io-syntax"/> for
+ additional commentary.
+ </para>
+ </note>
+
+ <para>
+ Examples:
+<programlisting>
+-- includes 3, does not include 7, and does include all points in between
+SELECT '[3,7)'::int4range;
+
+-- does not include either 3 or 7, but includes all points in between
+SELECT '(3,7)'::int4range;
+
+-- includes only the single point 4
+SELECT '[4,4]'::int4range;
+
+-- includes no points (and will be normalized to 'empty')
+SELECT '[4,4)'::int4range;
+</programlisting>
+ </para>
+
+ <para>
+ The input for a multirange is curly brackets (<literal>{</literal> and
+ <literal>}</literal>) containing zero or more valid ranges,
+ separated by commas. Whitespace is permitted around the brackets and
+ commas. This is intended to be reminiscent of array syntax, although
+ multiranges are much simpler: they have just one dimension and there is
+ no need to quote their contents. (The bounds of their ranges may be
+ quoted as above however.)
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+SELECT '{}'::int4multirange;
+SELECT '{[3,7)}'::int4multirange;
+SELECT '{[3,7), [8,9)}'::int4multirange;
+</programlisting>
+ </para>
+
+ </sect2>
+
+ <sect2 id="rangetypes-construct">
+ <title>Constructing Ranges and Multiranges</title>
+
+ <para>
+ Each range type has a constructor function with the same name as the range
+ type. Using the constructor function is frequently more convenient than
+ writing a range literal constant, since it avoids the need for extra
+ quoting of the bound values. The constructor function
+ accepts two or three arguments. The two-argument form constructs a range
+ in standard form (lower bound inclusive, upper bound exclusive), while
+ the three-argument form constructs a range with bounds of the form
+ specified by the third argument.
+ The third argument must be one of the strings
+ <quote><literal>()</literal></quote>,
+ <quote><literal>(]</literal></quote>,
+ <quote><literal>[)</literal></quote>, or
+ <quote><literal>[]</literal></quote>.
+ For example:
+
+<programlisting>
+-- The full form is: lower bound, upper bound, and text argument indicating
+-- inclusivity/exclusivity of bounds.
+SELECT numrange(1.0, 14.0, '(]');
+
+-- If the third argument is omitted, '[)' is assumed.
+SELECT numrange(1.0, 14.0);
+
+-- Although '(]' is specified here, on display the value will be converted to
+-- canonical form, since int8range is a discrete range type (see below).
+SELECT int8range(1, 14, '(]');
+
+-- Using NULL for either bound causes the range to be unbounded on that side.
+SELECT numrange(NULL, 2.2);
+</programlisting>
+ </para>
+
+ <para>
+ Each range type also has a multirange constructor with the same name as the
+ multirange type. The constructor function takes zero or more arguments
+ which are all ranges of the appropriate type.
+ For example:
+
+<programlisting>
+SELECT nummultirange();
+SELECT nummultirange(numrange(1.0, 14.0));
+SELECT nummultirange(numrange(1.0, 14.0), numrange(20.0, 25.0));
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-discrete">
+ <title>Discrete Range Types</title>
+
+ <para>
+ A discrete range is one whose element type has a well-defined
+ <quote>step</quote>, such as <type>integer</type> or <type>date</type>.
+ In these types two elements can be said to be adjacent, when there are
+ no valid values between them. This contrasts with continuous ranges,
+ where it's always (or almost always) possible to identify other element
+ values between two given values. For example, a range over the
+ <type>numeric</type> type is continuous, as is a range over <type>timestamp</type>.
+ (Even though <type>timestamp</type> has limited precision, and so could
+ theoretically be treated as discrete, it's better to consider it continuous
+ since the step size is normally not of interest.)
+ </para>
+
+ <para>
+ Another way to think about a discrete range type is that there is a clear
+ idea of a <quote>next</quote> or <quote>previous</quote> value for each element value.
+ Knowing that, it is possible to convert between inclusive and exclusive
+ representations of a range's bounds, by choosing the next or previous
+ element value instead of the one originally given.
+ For example, in an integer range type <literal>[4,8]</literal> and
+ <literal>(3,9)</literal> denote the same set of values; but this would not be so
+ for a range over numeric.
+ </para>
+
+ <para>
+ A discrete range type should have a <firstterm>canonicalization</firstterm>
+ function that is aware of the desired step size for the element type.
+ The canonicalization function is charged with converting equivalent values
+ of the range type to have identical representations, in particular
+ consistently inclusive or exclusive bounds.
+ If a canonicalization function is not specified, then ranges with different
+ formatting will always be treated as unequal, even though they might
+ represent the same set of values in reality.
+ </para>
+
+ <para>
+ The built-in range types <type>int4range</type>, <type>int8range</type>,
+ and <type>daterange</type> all use a canonical form that includes
+ the lower bound and excludes the upper bound; that is,
+ <literal>[)</literal>. User-defined range types can use other conventions,
+ however.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-defining">
+ <title>Defining New Range Types</title>
+
+ <para>
+ Users can define their own range types. The most common reason to do
+ this is to use ranges over subtypes not provided among the built-in
+ range types.
+ For example, to define a new range type of subtype <type>float8</type>:
+
+<programlisting>
+CREATE TYPE floatrange AS RANGE (
+ subtype = float8,
+ subtype_diff = float8mi
+);
+
+SELECT '[1.234, 5.678]'::floatrange;
+</programlisting>
+
+ Because <type>float8</type> has no meaningful
+ <quote>step</quote>, we do not define a canonicalization
+ function in this example.
+ </para>
+
+ <para>
+ When you define your own range you automatically get a corresponding
+ multirange type.
+ </para>
+
+ <para>
+ Defining your own range type also allows you to specify a different
+ subtype B-tree operator class or collation to use, so as to change the sort
+ ordering that determines which values fall into a given range.
+ </para>
+
+ <para>
+ If the subtype is considered to have discrete rather than continuous
+ values, the <command>CREATE TYPE</command> command should specify a
+ <literal>canonical</literal> function.
+ The canonicalization function takes an input range value, and must return
+ an equivalent range value that may have different bounds and formatting.
+ The canonical output for two ranges that represent the same set of values,
+ for example the integer ranges <literal>[1, 7]</literal> and <literal>[1,
+ 8)</literal>, must be identical. It doesn't matter which representation
+ you choose to be the canonical one, so long as two equivalent values with
+ different formattings are always mapped to the same value with the same
+ formatting. In addition to adjusting the inclusive/exclusive bounds
+ format, a canonicalization function might round off boundary values, in
+ case the desired step size is larger than what the subtype is capable of
+ storing. For instance, a range type over <type>timestamp</type> could be
+ defined to have a step size of an hour, in which case the canonicalization
+ function would need to round off bounds that weren't a multiple of an hour,
+ or perhaps throw an error instead.
+ </para>
+
+ <para>
+ In addition, any range type that is meant to be used with GiST or SP-GiST
+ indexes should define a subtype difference, or <literal>subtype_diff</literal>,
+ function. (The index will still work without <literal>subtype_diff</literal>,
+ but it is likely to be considerably less efficient than if a difference
+ function is provided.) The subtype difference function takes two input
+ values of the subtype, and returns their difference
+ (i.e., <replaceable>X</replaceable> minus <replaceable>Y</replaceable>) represented as
+ a <type>float8</type> value. In our example above, the
+ function <function>float8mi</function> that underlies the regular <type>float8</type>
+ minus operator can be used; but for any other subtype, some type
+ conversion would be necessary. Some creative thought about how to
+ represent differences as numbers might be needed, too. To the greatest
+ extent possible, the <literal>subtype_diff</literal> function should agree with
+ the sort ordering implied by the selected operator class and collation;
+ that is, its result should be positive whenever its first argument is
+ greater than its second according to the sort ordering.
+ </para>
+
+ <para>
+ A less-oversimplified example of a <literal>subtype_diff</literal> function is:
+ </para>
+
+<programlisting>
+CREATE FUNCTION time_subtype_diff(x time, y time) RETURNS float8 AS
+'SELECT EXTRACT(EPOCH FROM (x - y))' LANGUAGE sql STRICT IMMUTABLE;
+
+CREATE TYPE timerange AS RANGE (
+ subtype = time,
+ subtype_diff = time_subtype_diff
+);
+
+SELECT '[11:10, 23:00]'::timerange;
+</programlisting>
+
+ <para>
+ See <xref linkend="sql-createtype"/> for more information about creating
+ range types.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-indexing">
+ <title>Indexing</title>
+
+ <indexterm>
+ <primary>range type</primary>
+ <secondary>indexes on</secondary>
+ </indexterm>
+
+ <para>
+ GiST and SP-GiST indexes can be created for table columns of range types.
+ GiST indexes can be also created for table columns of multirange types.
+ For instance, to create a GiST index:
+<programlisting>
+CREATE INDEX reservation_idx ON reservation USING GIST (during);
+</programlisting>
+ A GiST or SP-GiST index on ranges can accelerate queries involving these
+ range operators:
+ <literal>=</literal>,
+ <literal>&amp;&amp;</literal>,
+ <literal>&lt;@</literal>,
+ <literal>@&gt;</literal>,
+ <literal>&lt;&lt;</literal>,
+ <literal>&gt;&gt;</literal>,
+ <literal>-|-</literal>,
+ <literal>&amp;&lt;</literal>, and
+ <literal>&amp;&gt;</literal>.
+ A GiST index on multiranges can accelerate queries involving the same
+ set of multirange operators.
+ A GiST index on ranges and GiST index on multiranges can also accelerate
+ queries involving these cross-type range to multirange and multirange to
+ range operators correspondingly:
+ <literal>&amp;&amp;</literal>,
+ <literal>&lt;@</literal>,
+ <literal>@&gt;</literal>,
+ <literal>&lt;&lt;</literal>,
+ <literal>&gt;&gt;</literal>,
+ <literal>-|-</literal>,
+ <literal>&amp;&lt;</literal>, and
+ <literal>&amp;&gt;</literal>.
+ See <xref linkend="range-operators-table"/> for more information.
+ </para>
+
+ <para>
+ In addition, B-tree and hash indexes can be created for table columns of
+ range types. For these index types, basically the only useful range
+ operation is equality. There is a B-tree sort ordering defined for range
+ values, with corresponding <literal>&lt;</literal> and <literal>&gt;</literal> operators,
+ but the ordering is rather arbitrary and not usually useful in the real
+ world. Range types' B-tree and hash support is primarily meant to
+ allow sorting and hashing internally in queries, rather than creation of
+ actual indexes.
+ </para>
+ </sect2>
+
+ <sect2 id="rangetypes-constraint">
+ <title>Constraints on Ranges</title>
+
+ <indexterm>
+ <primary>range type</primary>
+ <secondary>exclude</secondary>
+ </indexterm>
+
+ <para>
+ While <literal>UNIQUE</literal> is a natural constraint for scalar
+ values, it is usually unsuitable for range types. Instead, an
+ exclusion constraint is often more appropriate
+ (see <link linkend="sql-createtable-exclude">CREATE TABLE
+ ... CONSTRAINT ... EXCLUDE</link>). Exclusion constraints allow the
+ specification of constraints such as <quote>non-overlapping</quote> on a
+ range type. For example:
+
+<programlisting>
+CREATE TABLE reservation (
+ during tsrange,
+ EXCLUDE USING GIST (during WITH &amp;&amp;)
+);
+</programlisting>
+
+ That constraint will prevent any overlapping values from existing
+ in the table at the same time:
+
+<programlisting>
+INSERT INTO reservation VALUES
+ ('[2010-01-01 11:30, 2010-01-01 15:00)');
+INSERT 0 1
+
+INSERT INTO reservation VALUES
+ ('[2010-01-01 14:45, 2010-01-01 15:45)');
+ERROR: conflicting key value violates exclusion constraint "reservation_during_excl"
+DETAIL: Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts
+with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")).
+</programlisting>
+ </para>
+
+ <para>
+ You can use the <link linkend="btree-gist"><literal>btree_gist</literal></link>
+ extension to define exclusion constraints on plain scalar data types, which
+ can then be combined with range exclusions for maximum flexibility. For
+ example, after <literal>btree_gist</literal> is installed, the following
+ constraint will reject overlapping ranges only if the meeting room numbers
+ are equal:
+
+<programlisting>
+CREATE EXTENSION btree_gist;
+CREATE TABLE room_reservation (
+ room text,
+ during tsrange,
+ EXCLUDE USING GIST (room WITH =, during WITH &amp;&amp;)
+);
+
+INSERT INTO room_reservation VALUES
+ ('123A', '[2010-01-01 14:00, 2010-01-01 15:00)');
+INSERT 0 1
+
+INSERT INTO room_reservation VALUES
+ ('123A', '[2010-01-01 14:30, 2010-01-01 15:30)');
+ERROR: conflicting key value violates exclusion constraint "room_reservation_room_during_excl"
+DETAIL: Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts
+with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")).
+
+INSERT INTO room_reservation VALUES
+ ('123B', '[2010-01-01 14:30, 2010-01-01 15:30)');
+INSERT 0 1
+</programlisting>
+ </para>
+ </sect2>
+</sect1>
diff --git a/doc/src/sgml/ref/abort.sgml b/doc/src/sgml/ref/abort.sgml
new file mode 100644
index 0000000..16b5602
--- /dev/null
+++ b/doc/src/sgml/ref/abort.sgml
@@ -0,0 +1,112 @@
+<!--
+doc/src/sgml/ref/abort.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-abort">
+ <indexterm zone="sql-abort">
+ <primary>ABORT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ABORT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ABORT</refname>
+ <refpurpose>abort the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ABORT</command> rolls back the current transaction and causes
+ all the updates made by the transaction to be discarded.
+ This command is identical
+ in behavior to the standard <acronym>SQL</acronym> command
+ <link linkend="sql-rollback"><command>ROLLBACK</command></link>,
+ and is present only for historical reasons.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>WORK</literal></term>
+ <term><literal>TRANSACTION</literal></term>
+ <listitem>
+ <para>
+ Optional key words. They have no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>AND CHAIN</literal></term>
+ <listitem>
+ <para>
+ If <literal>AND CHAIN</literal> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <link
+ linkend="sql-set-transaction"><command>SET TRANSACTION</command></link>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-commit"><command>COMMIT</command></link> to
+ successfully terminate a transaction.
+ </para>
+
+ <para>
+ Issuing <command>ABORT</command> outside of a transaction block
+ emits a warning and otherwise has no effect.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To abort all changes:
+<programlisting>
+ABORT;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command is a <productname>PostgreSQL</productname> extension
+ present for historical reasons. <command>ROLLBACK</command> is the
+ equivalent standard SQL command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
new file mode 100644
index 0000000..e90a0e1
--- /dev/null
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -0,0 +1,225 @@
+<!--
+doc/src/sgml/ref/allfiles.sgml
+PostgreSQL documentation
+Complete list of usable sgml source files in this directory.
+-->
+
+<!-- SQL commands -->
+<!ENTITY abort SYSTEM "abort.sgml">
+<!ENTITY alterAggregate SYSTEM "alter_aggregate.sgml">
+<!ENTITY alterCollation SYSTEM "alter_collation.sgml">
+<!ENTITY alterConversion SYSTEM "alter_conversion.sgml">
+<!ENTITY alterDatabase SYSTEM "alter_database.sgml">
+<!ENTITY alterDefaultPrivileges SYSTEM "alter_default_privileges.sgml">
+<!ENTITY alterDomain SYSTEM "alter_domain.sgml">
+<!ENTITY alterEventTrigger SYSTEM "alter_event_trigger.sgml">
+<!ENTITY alterExtension SYSTEM "alter_extension.sgml">
+<!ENTITY alterForeignDataWrapper SYSTEM "alter_foreign_data_wrapper.sgml">
+<!ENTITY alterForeignTable SYSTEM "alter_foreign_table.sgml">
+<!ENTITY alterFunction SYSTEM "alter_function.sgml">
+<!ENTITY alterGroup SYSTEM "alter_group.sgml">
+<!ENTITY alterIndex SYSTEM "alter_index.sgml">
+<!ENTITY alterLanguage SYSTEM "alter_language.sgml">
+<!ENTITY alterLargeObject SYSTEM "alter_large_object.sgml">
+<!ENTITY alterMaterializedView SYSTEM "alter_materialized_view.sgml">
+<!ENTITY alterOperator SYSTEM "alter_operator.sgml">
+<!ENTITY alterOperatorClass SYSTEM "alter_opclass.sgml">
+<!ENTITY alterOperatorFamily SYSTEM "alter_opfamily.sgml">
+<!ENTITY alterPolicy SYSTEM "alter_policy.sgml">
+<!ENTITY alterProcedure SYSTEM "alter_procedure.sgml">
+<!ENTITY alterPublication SYSTEM "alter_publication.sgml">
+<!ENTITY alterRole SYSTEM "alter_role.sgml">
+<!ENTITY alterRoutine SYSTEM "alter_routine.sgml">
+<!ENTITY alterRule SYSTEM "alter_rule.sgml">
+<!ENTITY alterSchema SYSTEM "alter_schema.sgml">
+<!ENTITY alterServer SYSTEM "alter_server.sgml">
+<!ENTITY alterSequence SYSTEM "alter_sequence.sgml">
+<!ENTITY alterSubscription SYSTEM "alter_subscription.sgml">
+<!ENTITY alterSystem SYSTEM "alter_system.sgml">
+<!ENTITY alterStatistics SYSTEM "alter_statistics.sgml">
+<!ENTITY alterTable SYSTEM "alter_table.sgml">
+<!ENTITY alterTableSpace SYSTEM "alter_tablespace.sgml">
+<!ENTITY alterTSConfig SYSTEM "alter_tsconfig.sgml">
+<!ENTITY alterTSDictionary SYSTEM "alter_tsdictionary.sgml">
+<!ENTITY alterTSParser SYSTEM "alter_tsparser.sgml">
+<!ENTITY alterTSTemplate SYSTEM "alter_tstemplate.sgml">
+<!ENTITY alterTrigger SYSTEM "alter_trigger.sgml">
+<!ENTITY alterType SYSTEM "alter_type.sgml">
+<!ENTITY alterUser SYSTEM "alter_user.sgml">
+<!ENTITY alterUserMapping SYSTEM "alter_user_mapping.sgml">
+<!ENTITY alterView SYSTEM "alter_view.sgml">
+<!ENTITY analyze SYSTEM "analyze.sgml">
+<!ENTITY begin SYSTEM "begin.sgml">
+<!ENTITY call SYSTEM "call.sgml">
+<!ENTITY checkpoint SYSTEM "checkpoint.sgml">
+<!ENTITY close SYSTEM "close.sgml">
+<!ENTITY cluster SYSTEM "cluster.sgml">
+<!ENTITY commentOn SYSTEM "comment.sgml">
+<!ENTITY commit SYSTEM "commit.sgml">
+<!ENTITY commitPrepared SYSTEM "commit_prepared.sgml">
+<!ENTITY copyTable SYSTEM "copy.sgml">
+<!ENTITY createAccessMethod SYSTEM "create_access_method.sgml">
+<!ENTITY createAggregate SYSTEM "create_aggregate.sgml">
+<!ENTITY createCast SYSTEM "create_cast.sgml">
+<!ENTITY createCollation SYSTEM "create_collation.sgml">
+<!ENTITY createConversion SYSTEM "create_conversion.sgml">
+<!ENTITY createDatabase SYSTEM "create_database.sgml">
+<!ENTITY createDomain SYSTEM "create_domain.sgml">
+<!ENTITY createEventTrigger SYSTEM "create_event_trigger.sgml">
+<!ENTITY createExtension SYSTEM "create_extension.sgml">
+<!ENTITY createForeignDataWrapper SYSTEM "create_foreign_data_wrapper.sgml">
+<!ENTITY createForeignTable SYSTEM "create_foreign_table.sgml">
+<!ENTITY createFunction SYSTEM "create_function.sgml">
+<!ENTITY createGroup SYSTEM "create_group.sgml">
+<!ENTITY createIndex SYSTEM "create_index.sgml">
+<!ENTITY createLanguage SYSTEM "create_language.sgml">
+<!ENTITY createMaterializedView SYSTEM "create_materialized_view.sgml">
+<!ENTITY createOperator SYSTEM "create_operator.sgml">
+<!ENTITY createOperatorClass SYSTEM "create_opclass.sgml">
+<!ENTITY createOperatorFamily SYSTEM "create_opfamily.sgml">
+<!ENTITY createPolicy SYSTEM "create_policy.sgml">
+<!ENTITY createProcedure SYSTEM "create_procedure.sgml">
+<!ENTITY createPublication SYSTEM "create_publication.sgml">
+<!ENTITY createRole SYSTEM "create_role.sgml">
+<!ENTITY createRule SYSTEM "create_rule.sgml">
+<!ENTITY createSchema SYSTEM "create_schema.sgml">
+<!ENTITY createSequence SYSTEM "create_sequence.sgml">
+<!ENTITY createServer SYSTEM "create_server.sgml">
+<!ENTITY createStatistics SYSTEM "create_statistics.sgml">
+<!ENTITY createSubscription SYSTEM "create_subscription.sgml">
+<!ENTITY createTable SYSTEM "create_table.sgml">
+<!ENTITY createTableAs SYSTEM "create_table_as.sgml">
+<!ENTITY createTableSpace SYSTEM "create_tablespace.sgml">
+<!ENTITY createTransform SYSTEM "create_transform.sgml">
+<!ENTITY createTrigger SYSTEM "create_trigger.sgml">
+<!ENTITY createTSConfig SYSTEM "create_tsconfig.sgml">
+<!ENTITY createTSDictionary SYSTEM "create_tsdictionary.sgml">
+<!ENTITY createTSParser SYSTEM "create_tsparser.sgml">
+<!ENTITY createTSTemplate SYSTEM "create_tstemplate.sgml">
+<!ENTITY createType SYSTEM "create_type.sgml">
+<!ENTITY createUser SYSTEM "create_user.sgml">
+<!ENTITY createUserMapping SYSTEM "create_user_mapping.sgml">
+<!ENTITY createView SYSTEM "create_view.sgml">
+<!ENTITY deallocate SYSTEM "deallocate.sgml">
+<!ENTITY declare SYSTEM "declare.sgml">
+<!ENTITY delete SYSTEM "delete.sgml">
+<!ENTITY discard SYSTEM "discard.sgml">
+<!ENTITY do SYSTEM "do.sgml">
+<!ENTITY dropAccessMethod SYSTEM "drop_access_method.sgml">
+<!ENTITY dropAggregate SYSTEM "drop_aggregate.sgml">
+<!ENTITY dropCast SYSTEM "drop_cast.sgml">
+<!ENTITY dropCollation SYSTEM "drop_collation.sgml">
+<!ENTITY dropConversion SYSTEM "drop_conversion.sgml">
+<!ENTITY dropDatabase SYSTEM "drop_database.sgml">
+<!ENTITY dropDomain SYSTEM "drop_domain.sgml">
+<!ENTITY dropEventTrigger SYSTEM "drop_event_trigger.sgml">
+<!ENTITY dropExtension SYSTEM "drop_extension.sgml">
+<!ENTITY dropForeignDataWrapper SYSTEM "drop_foreign_data_wrapper.sgml">
+<!ENTITY dropForeignTable SYSTEM "drop_foreign_table.sgml">
+<!ENTITY dropFunction SYSTEM "drop_function.sgml">
+<!ENTITY dropGroup SYSTEM "drop_group.sgml">
+<!ENTITY dropIndex SYSTEM "drop_index.sgml">
+<!ENTITY dropLanguage SYSTEM "drop_language.sgml">
+<!ENTITY dropMaterializedView SYSTEM "drop_materialized_view.sgml">
+<!ENTITY dropOperator SYSTEM "drop_operator.sgml">
+<!ENTITY dropOperatorClass SYSTEM "drop_opclass.sgml">
+<!ENTITY dropOperatorFamily SYSTEM "drop_opfamily.sgml">
+<!ENTITY dropOwned SYSTEM "drop_owned.sgml">
+<!ENTITY dropPolicy SYSTEM "drop_policy.sgml">
+<!ENTITY dropProcedure SYSTEM "drop_procedure.sgml">
+<!ENTITY dropPublication SYSTEM "drop_publication.sgml">
+<!ENTITY dropRole SYSTEM "drop_role.sgml">
+<!ENTITY dropRoutine SYSTEM "drop_routine.sgml">
+<!ENTITY dropRule SYSTEM "drop_rule.sgml">
+<!ENTITY dropSchema SYSTEM "drop_schema.sgml">
+<!ENTITY dropSequence SYSTEM "drop_sequence.sgml">
+<!ENTITY dropServer SYSTEM "drop_server.sgml">
+<!ENTITY dropStatistics SYSTEM "drop_statistics.sgml">
+<!ENTITY dropSubscription SYSTEM "drop_subscription.sgml">
+<!ENTITY dropTable SYSTEM "drop_table.sgml">
+<!ENTITY dropTableSpace SYSTEM "drop_tablespace.sgml">
+<!ENTITY dropTransform SYSTEM "drop_transform.sgml">
+<!ENTITY dropTrigger SYSTEM "drop_trigger.sgml">
+<!ENTITY dropTSConfig SYSTEM "drop_tsconfig.sgml">
+<!ENTITY dropTSDictionary SYSTEM "drop_tsdictionary.sgml">
+<!ENTITY dropTSParser SYSTEM "drop_tsparser.sgml">
+<!ENTITY dropTSTemplate SYSTEM "drop_tstemplate.sgml">
+<!ENTITY dropType SYSTEM "drop_type.sgml">
+<!ENTITY dropUser SYSTEM "drop_user.sgml">
+<!ENTITY dropUserMapping SYSTEM "drop_user_mapping.sgml">
+<!ENTITY dropView SYSTEM "drop_view.sgml">
+<!ENTITY end SYSTEM "end.sgml">
+<!ENTITY execute SYSTEM "execute.sgml">
+<!ENTITY explain SYSTEM "explain.sgml">
+<!ENTITY fetch SYSTEM "fetch.sgml">
+<!ENTITY grant SYSTEM "grant.sgml">
+<!ENTITY importForeignSchema SYSTEM "import_foreign_schema.sgml">
+<!ENTITY insert SYSTEM "insert.sgml">
+<!ENTITY listen SYSTEM "listen.sgml">
+<!ENTITY load SYSTEM "load.sgml">
+<!ENTITY lock SYSTEM "lock.sgml">
+<!ENTITY merge SYSTEM "merge.sgml">
+<!ENTITY move SYSTEM "move.sgml">
+<!ENTITY notify SYSTEM "notify.sgml">
+<!ENTITY prepare SYSTEM "prepare.sgml">
+<!ENTITY prepareTransaction SYSTEM "prepare_transaction.sgml">
+<!ENTITY reassignOwned SYSTEM "reassign_owned.sgml">
+<!ENTITY refreshMaterializedView SYSTEM "refresh_materialized_view.sgml">
+<!ENTITY reindex SYSTEM "reindex.sgml">
+<!ENTITY releaseSavepoint SYSTEM "release_savepoint.sgml">
+<!ENTITY reset SYSTEM "reset.sgml">
+<!ENTITY revoke SYSTEM "revoke.sgml">
+<!ENTITY rollback SYSTEM "rollback.sgml">
+<!ENTITY rollbackPrepared SYSTEM "rollback_prepared.sgml">
+<!ENTITY rollbackTo SYSTEM "rollback_to.sgml">
+<!ENTITY savepoint SYSTEM "savepoint.sgml">
+<!ENTITY securityLabel SYSTEM "security_label.sgml">
+<!ENTITY select SYSTEM "select.sgml">
+<!ENTITY selectInto SYSTEM "select_into.sgml">
+<!ENTITY set SYSTEM "set.sgml">
+<!ENTITY setConstraints SYSTEM "set_constraints.sgml">
+<!ENTITY setRole SYSTEM "set_role.sgml">
+<!ENTITY setSessionAuth SYSTEM "set_session_auth.sgml">
+<!ENTITY setTransaction SYSTEM "set_transaction.sgml">
+<!ENTITY show SYSTEM "show.sgml">
+<!ENTITY startTransaction SYSTEM "start_transaction.sgml">
+<!ENTITY truncate SYSTEM "truncate.sgml">
+<!ENTITY unlisten SYSTEM "unlisten.sgml">
+<!ENTITY update SYSTEM "update.sgml">
+<!ENTITY vacuum SYSTEM "vacuum.sgml">
+<!ENTITY values SYSTEM "values.sgml">
+
+<!-- applications and utilities -->
+<!ENTITY clusterdb SYSTEM "clusterdb.sgml">
+<!ENTITY createdb SYSTEM "createdb.sgml">
+<!ENTITY createuser SYSTEM "createuser.sgml">
+<!ENTITY dropdb SYSTEM "dropdb.sgml">
+<!ENTITY dropuser SYSTEM "dropuser.sgml">
+<!ENTITY ecpgRef SYSTEM "ecpg-ref.sgml">
+<!ENTITY initdb SYSTEM "initdb.sgml">
+<!ENTITY pgamcheck SYSTEM "pg_amcheck.sgml">
+<!ENTITY pgarchivecleanup SYSTEM "pgarchivecleanup.sgml">
+<!ENTITY pgBasebackup SYSTEM "pg_basebackup.sgml">
+<!ENTITY pgbench SYSTEM "pgbench.sgml">
+<!ENTITY pgChecksums SYSTEM "pg_checksums.sgml">
+<!ENTITY pgConfig SYSTEM "pg_config-ref.sgml">
+<!ENTITY pgControldata SYSTEM "pg_controldata.sgml">
+<!ENTITY pgCtl SYSTEM "pg_ctl-ref.sgml">
+<!ENTITY pgDump SYSTEM "pg_dump.sgml">
+<!ENTITY pgDumpall SYSTEM "pg_dumpall.sgml">
+<!ENTITY pgIsready SYSTEM "pg_isready.sgml">
+<!ENTITY pgReceivewal SYSTEM "pg_receivewal.sgml">
+<!ENTITY pgRecvlogical SYSTEM "pg_recvlogical.sgml">
+<!ENTITY pgResetwal SYSTEM "pg_resetwal.sgml">
+<!ENTITY pgRestore SYSTEM "pg_restore.sgml">
+<!ENTITY pgRewind SYSTEM "pg_rewind.sgml">
+<!ENTITY pgVerifyBackup SYSTEM "pg_verifybackup.sgml">
+<!ENTITY pgtestfsync SYSTEM "pgtestfsync.sgml">
+<!ENTITY pgtesttiming SYSTEM "pgtesttiming.sgml">
+<!ENTITY pgupgrade SYSTEM "pgupgrade.sgml">
+<!ENTITY pgwaldump SYSTEM "pg_waldump.sgml">
+<!ENTITY postgres SYSTEM "postgres-ref.sgml">
+<!ENTITY postmaster SYSTEM "postmaster.sgml">
+<!ENTITY psqlRef SYSTEM "psql-ref.sgml">
+<!ENTITY reindexdb SYSTEM "reindexdb.sgml">
+<!ENTITY vacuumdb SYSTEM "vacuumdb.sgml">
diff --git a/doc/src/sgml/ref/alter_aggregate.sgml b/doc/src/sgml/ref/alter_aggregate.sgml
new file mode 100644
index 0000000..aee10a5
--- /dev/null
+++ b/doc/src/sgml/ref/alter_aggregate.sgml
@@ -0,0 +1,202 @@
+<!--
+doc/src/sgml/ref/alter_aggregate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alteraggregate">
+ <indexterm zone="sql-alteraggregate">
+ <primary>ALTER AGGREGATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER AGGREGATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER AGGREGATE</refname>
+ <refpurpose>change the definition of an aggregate function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) RENAME TO <replaceable>new_name</replaceable>
+ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> )
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER AGGREGATE <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) SET SCHEMA <replaceable>new_schema</replaceable>
+
+<phrase>where <replaceable>aggregate_signature</replaceable> is:</phrase>
+
+* |
+[ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] |
+[ [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] ] ORDER BY [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER AGGREGATE</command> changes the definition of an
+ aggregate function.
+ </para>
+
+ <para>
+ You must own the aggregate function to use <command>ALTER AGGREGATE</command>.
+ To change the schema of an aggregate function, you must also have
+ <literal>CREATE</literal> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the aggregate function's schema. (These restrictions enforce that altering
+ the owner doesn't do anything you couldn't do by dropping and recreating
+ the aggregate function. However, a superuser can alter ownership of any
+ aggregate function anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing aggregate function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal> or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ Note that <command>ALTER AGGREGATE</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the aggregate function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+ <listitem>
+ <para>
+ An input data type on which the aggregate function operates.
+ To reference a zero-argument aggregate function, write <literal>*</literal>
+ in place of the list of argument specifications.
+ To reference an ordered-set aggregate function, write
+ <literal>ORDER BY</literal> between the direct and aggregated argument
+ specifications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the aggregate function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the aggregate function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the aggregate function.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The recommended syntax for referencing an ordered-set aggregate
+ is to write <literal>ORDER BY</literal> between the direct and aggregated
+ argument specifications, in the same style as in
+ <link linkend="sql-createaggregate"><command>CREATE AGGREGATE</command></link>. However, it will also work to
+ omit <literal>ORDER BY</literal> and just run the direct and aggregated
+ argument specifications into a single list. In this abbreviated form,
+ if <literal>VARIADIC "any"</literal> was used in both the direct and
+ aggregated argument lists, write <literal>VARIADIC "any"</literal> only once.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the aggregate function <literal>myavg</literal> for type
+ <type>integer</type> to <literal>my_average</literal>:
+<programlisting>
+ALTER AGGREGATE myavg(integer) RENAME TO my_average;
+</programlisting>
+ </para>
+
+ <para>
+ To change the owner of the aggregate function <literal>myavg</literal> for type
+ <type>integer</type> to <literal>joe</literal>:
+<programlisting>
+ALTER AGGREGATE myavg(integer) OWNER TO joe;
+</programlisting>
+ </para>
+
+ <para>
+ To move the ordered-set aggregate <literal>mypercentile</literal> with
+ direct argument of type <type>float8</type> and aggregated argument
+ of type <type>integer</type> into schema <literal>myschema</literal>:
+<programlisting>
+ALTER AGGREGATE mypercentile(float8 ORDER BY integer) SET SCHEMA myschema;
+</programlisting>
+ This will work too:
+<programlisting>
+ALTER AGGREGATE mypercentile(float8, integer) SET SCHEMA myschema;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER AGGREGATE</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createaggregate"/></member>
+ <member><xref linkend="sql-dropaggregate"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_collation.sgml b/doc/src/sgml/ref/alter_collation.sgml
new file mode 100644
index 0000000..a8c831d
--- /dev/null
+++ b/doc/src/sgml/ref/alter_collation.sgml
@@ -0,0 +1,207 @@
+<!--
+doc/src/sgml/ref/alter_collation.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altercollation">
+ <indexterm zone="sql-altercollation">
+ <primary>ALTER COLLATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER COLLATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER COLLATION</refname>
+ <refpurpose>change the definition of a collation</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER COLLATION <replaceable>name</replaceable> REFRESH VERSION
+
+ALTER COLLATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER COLLATION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER COLLATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER COLLATION</command> changes the definition of a
+ collation.
+ </para>
+
+ <para>
+ You must own the collation to use <command>ALTER COLLATION</command>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the collation's schema. (These restrictions enforce that altering the
+ owner doesn't do anything you couldn't do by dropping and recreating the
+ collation. However, a superuser can alter ownership of any collation
+ anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing collation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the collation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the collation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the collation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REFRESH VERSION</literal></term>
+ <listitem>
+ <para>
+ Update the collation's version.
+ See <xref linkend="sql-altercollation-notes"/> below.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-altercollation-notes" xreflabel="Notes">
+ <title>Notes</title>
+
+ <para>
+ When a collation object is created, the provider-specific version of the
+ collation is recorded in the system catalog. When the collation is used,
+ the current version is
+ checked against the recorded version, and a warning is issued when there is
+ a mismatch, for example:
+<screen>
+WARNING: collation "xx-x-icu" has version mismatch
+DETAIL: The collation in the database was created using version 1.2.3.4, but the operating system provides version 2.3.4.5.
+HINT: Rebuild all objects affected by this collation and run ALTER COLLATION pg_catalog."xx-x-icu" REFRESH VERSION, or build PostgreSQL with the right library version.
+</screen>
+ A change in collation definitions can lead to corrupt indexes and other
+ problems because the database system relies on stored objects having a
+ certain sort order. Generally, this should be avoided, but it can happen
+ in legitimate circumstances, such as when upgrading the operating system
+ to a new major version or when
+ using <command>pg_upgrade</command> to upgrade to server binaries linked
+ with a newer version of ICU. When this happens, all objects depending on
+ the collation should be rebuilt, for example,
+ using <command>REINDEX</command>. When that is done, the collation version
+ can be refreshed using the command <literal>ALTER COLLATION ... REFRESH
+ VERSION</literal>. This will update the system catalog to record the
+ current collation version and will make the warning go away. Note that this
+ does not actually check whether all affected objects have been rebuilt
+ correctly.
+ </para>
+ <para>
+ When using collations provided by <literal>libc</literal>, version
+ information is recorded on systems using the GNU C library (most Linux
+ systems), FreeBSD and Windows. When using collations provided by ICU, the
+ version information is provided by the ICU library and is available on all
+ platforms.
+ </para>
+ <note>
+ <para>
+ When using the GNU C library for collations, the C library's version
+ is used as a proxy for the collation version. Many Linux distributions
+ change collation definitions only when upgrading the C library, but this
+ approach is imperfect as maintainers are free to back-port newer
+ collation definitions to older C library releases.
+ </para>
+ <para>
+ When using Windows for collations, version information is only available
+ for collations defined with BCP 47 language tags such as
+ <literal>en-US</literal>.
+ </para>
+ </note>
+ <para>
+ For the database default collation, there is an analogous command
+ <literal>ALTER DATABASE ... REFRESH COLLATION VERSION</literal>.
+ </para>
+
+ <para>
+ The following query can be used to identify all collations in the current
+ database that need to be refreshed and the objects that depend on them:
+<programlisting><![CDATA[
+SELECT pg_describe_object(refclassid, refobjid, refobjsubid) AS "Collation",
+ pg_describe_object(classid, objid, objsubid) AS "Object"
+ FROM pg_depend d JOIN pg_collation c
+ ON refclassid = 'pg_collation'::regclass AND refobjid = c.oid
+ WHERE c.collversion <> pg_collation_actual_version(c.oid)
+ ORDER BY 1, 2;
+]]></programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the collation <literal>de_DE</literal> to
+ <literal>german</literal>:
+<programlisting>
+ALTER COLLATION "de_DE" RENAME TO german;
+</programlisting>
+ </para>
+
+ <para>
+ To change the owner of the collation <literal>en_US</literal> to
+ <literal>joe</literal>:
+<programlisting>
+ALTER COLLATION "en_US" OWNER TO joe;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER COLLATION</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createcollation"/></member>
+ <member><xref linkend="sql-dropcollation"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_conversion.sgml b/doc/src/sgml/ref/alter_conversion.sgml
new file mode 100644
index 0000000..a128f20
--- /dev/null
+++ b/doc/src/sgml/ref/alter_conversion.sgml
@@ -0,0 +1,127 @@
+<!--
+doc/src/sgml/ref/alter_conversion.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterconversion">
+ <indexterm zone="sql-alterconversion">
+ <primary>ALTER CONVERSION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER CONVERSION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER CONVERSION</refname>
+ <refpurpose>change the definition of a conversion</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER CONVERSION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER CONVERSION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER CONVERSION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER CONVERSION</command> changes the definition of a
+ conversion.
+ </para>
+
+ <para>
+ You must own the conversion to use <command>ALTER CONVERSION</command>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the conversion's schema. (These restrictions enforce that altering the
+ owner doesn't do anything you couldn't do by dropping and recreating the
+ conversion. However, a superuser can alter ownership of any conversion
+ anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing conversion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the conversion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the conversion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the conversion.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the conversion <literal>iso_8859_1_to_utf8</literal> to
+ <literal>latin1_to_unicode</literal>:
+<programlisting>
+ALTER CONVERSION iso_8859_1_to_utf8 RENAME TO latin1_to_unicode;
+</programlisting>
+ </para>
+
+ <para>
+ To change the owner of the conversion <literal>iso_8859_1_to_utf8</literal> to
+ <literal>joe</literal>:
+<programlisting>
+ALTER CONVERSION iso_8859_1_to_utf8 OWNER TO joe;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER CONVERSION</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createconversion"/></member>
+ <member><xref linkend="sql-dropconversion"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_database.sgml b/doc/src/sgml/ref/alter_database.sgml
new file mode 100644
index 0000000..89ed261
--- /dev/null
+++ b/doc/src/sgml/ref/alter_database.sgml
@@ -0,0 +1,255 @@
+<!--
+doc/src/sgml/ref/alter_database.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterdatabase">
+ <indexterm zone="sql-alterdatabase">
+ <primary>ALTER DATABASE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER DATABASE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER DATABASE</refname>
+ <refpurpose>change a database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER DATABASE <replaceable class="parameter">name</replaceable> [ [ WITH ] <replaceable class="parameter">option</replaceable> [ ... ] ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ ALLOW_CONNECTIONS <replaceable class="parameter">allowconn</replaceable>
+ CONNECTION LIMIT <replaceable class="parameter">connlimit</replaceable>
+ IS_TEMPLATE <replaceable class="parameter">istemplate</replaceable>
+
+ALTER DATABASE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+
+ALTER DATABASE <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER DATABASE <replaceable class="parameter">name</replaceable> SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable>
+
+ALTER DATABASE <replaceable class="parameter">name</replaceable> REFRESH COLLATION VERSION
+
+ALTER DATABASE <replaceable class="parameter">name</replaceable> SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
+ALTER DATABASE <replaceable class="parameter">name</replaceable> SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
+ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET <replaceable>configuration_parameter</replaceable>
+ALTER DATABASE <replaceable class="parameter">name</replaceable> RESET ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER DATABASE</command> changes the attributes
+ of a database.
+ </para>
+
+ <para>
+ The first form changes certain per-database settings. (See below for
+ details.) Only the database owner or a superuser can change these settings.
+ </para>
+
+ <para>
+ The second form changes the name of the database. Only the database
+ owner or a superuser can rename a database; non-superuser owners must
+ also have the
+ <literal>CREATEDB</literal> privilege. The current database cannot
+ be renamed. (Connect to a different database if you need to do
+ that.)
+ </para>
+
+ <para>
+ The third form changes the owner of the database.
+ To alter the owner, you must own the database and also be a direct or
+ indirect member of the new owning role, and you must have the
+ <literal>CREATEDB</literal> privilege.
+ (Note that superusers have all these privileges automatically.)
+ </para>
+
+ <para>
+ The fourth form changes the default tablespace of the database.
+ Only the database owner or a superuser can do this; you must also have
+ create privilege for the new tablespace.
+ This command physically moves any tables or indexes in the database's old
+ default tablespace to the new tablespace. The new default tablespace
+ must be empty for this database, and no one can be connected to
+ the database. Tables and indexes in non-default tablespaces are
+ unaffected.
+ </para>
+
+ <para>
+ The remaining forms change the session default for a run-time
+ configuration variable for a <productname>PostgreSQL</productname>
+ database. Whenever a new session is subsequently started in that
+ database, the specified value becomes the session default value.
+ The database-specific default overrides whatever setting is present
+ in <filename>postgresql.conf</filename> or has been received from the
+ <command>postgres</command> command line. Only the database
+ owner or a superuser can change the session defaults for a
+ database. Certain variables cannot be set this way, or can only be
+ set by a superuser.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the database whose attributes are to be altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">allowconn</replaceable></term>
+ <listitem>
+ <para>
+ If false then no one can connect to this database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">connlimit</replaceable></term>
+ <listitem>
+ <para>
+ How many concurrent connections can be made
+ to this database. -1 means no limit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">istemplate</replaceable></term>
+ <listitem>
+ <para>
+ If true, then this database can be cloned by any user with <literal>CREATEDB</literal>
+ privileges; if false, then only superusers or the owner of the
+ database can clone it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_tablespace</replaceable></term>
+ <listitem>
+ <para>
+ The new default tablespace of the database.
+ </para>
+
+ <para>
+ This form of the command cannot be executed inside a transaction block.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REFRESH COLLATION VERSION</literal></term>
+ <listitem>
+ <para>
+ Update the database collation version. See <xref
+ linkend="sql-altercollation-notes"/> for background.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>configuration_parameter</replaceable></term>
+ <term><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ Set this database's session default for the specified configuration
+ parameter to the given value. If
+ <replaceable>value</replaceable> is <literal>DEFAULT</literal>
+ or, equivalently, <literal>RESET</literal> is used, the
+ database-specific setting is removed, so the system-wide default
+ setting will be inherited in new sessions. Use <literal>RESET
+ ALL</literal> to clear all database-specific settings.
+ <literal>SET FROM CURRENT</literal> saves the session's current value of
+ the parameter as the database-specific value.
+ </para>
+
+ <para>
+ See <xref linkend="sql-set"/> and <xref linkend="runtime-config"/>
+ for more information about allowed parameter names
+ and values.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ It is also possible to tie a session default to a specific role
+ rather than to a database; see
+ <xref linkend="sql-alterrole"/>.
+ Role-specific settings override database-specific
+ ones if there is a conflict.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To disable index scans by default in the database
+ <literal>test</literal>:
+
+<programlisting>
+ALTER DATABASE test SET enable_indexscan TO off;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>ALTER DATABASE</command> statement is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createdatabase"/></member>
+ <member><xref linkend="sql-dropdatabase"/></member>
+ <member><xref linkend="sql-set"/></member>
+ <member><xref linkend="sql-createtablespace"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_default_privileges.sgml b/doc/src/sgml/ref/alter_default_privileges.sgml
new file mode 100644
index 0000000..f1d54f5
--- /dev/null
+++ b/doc/src/sgml/ref/alter_default_privileges.sgml
@@ -0,0 +1,255 @@
+<!--
+doc/src/sgml/ref/alter_default_privileges.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterdefaultprivileges">
+ <indexterm zone="sql-alterdefaultprivileges">
+ <primary>ALTER DEFAULT PRIVILEGES</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER DEFAULT PRIVILEGES</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER DEFAULT PRIVILEGES</refname>
+ <refpurpose>define default access privileges</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER DEFAULT PRIVILEGES
+ [ FOR { ROLE | USER } <replaceable>target_role</replaceable> [, ...] ]
+ [ IN SCHEMA <replaceable>schema_name</replaceable> [, ...] ]
+ <replaceable class="parameter">abbreviated_grant_or_revoke</replaceable>
+
+<phrase>where <replaceable class="parameter">abbreviated_grant_or_revoke</replaceable> is one of:</phrase>
+
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON TABLES
+ TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON SEQUENCES
+ TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { FUNCTIONS | ROUTINES }
+ TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPES
+ TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+GRANT { USAGE | CREATE | ALL [ PRIVILEGES ] }
+ ON SCHEMAS
+ TO { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...] [ WITH GRANT OPTION ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON TABLES
+ FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON SEQUENCES
+ FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { FUNCTIONS | ROUTINES }
+ FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPES
+ FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | CREATE | ALL [ PRIVILEGES ] }
+ ON SCHEMAS
+ FROM { [ GROUP ] <replaceable class="parameter">role_name</replaceable> | PUBLIC } [, ...]
+ [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-alterdefaultprivileges-description">
+ <title>Description</title>
+
+ <para>
+ <command>ALTER DEFAULT PRIVILEGES</command> allows you to set the privileges
+ that will be applied to objects created in the future. (It does not
+ affect privileges assigned to already-existing objects.) Currently,
+ only the privileges for schemas, tables (including views and foreign
+ tables), sequences, functions, and types (including domains) can be
+ altered. For this command, functions include aggregates and procedures.
+ The words <literal>FUNCTIONS</literal> and <literal>ROUTINES</literal> are
+ equivalent in this command. (<literal>ROUTINES</literal> is preferred
+ going forward as the standard term for functions and procedures taken
+ together. In earlier PostgreSQL releases, only the
+ word <literal>FUNCTIONS</literal> was allowed. It is not possible to set
+ default privileges for functions and procedures separately.)
+ </para>
+
+ <para>
+ You can change default privileges only for objects that will be created by
+ yourself or by roles that you are a member of. The privileges can be set
+ globally (i.e., for all objects created in the current database),
+ or just for objects created in specified schemas.
+ </para>
+
+ <para>
+ As explained in <xref linkend="ddl-priv"/>,
+ the default privileges for any object type normally grant all grantable
+ permissions to the object owner, and may grant some privileges to
+ <literal>PUBLIC</literal> as well. However, this behavior can be changed by
+ altering the global default privileges with
+ <command>ALTER DEFAULT PRIVILEGES</command>.
+ </para>
+
+ <para>
+ Default privileges that are specified per-schema are added to whatever
+ the global default privileges are for the particular object type.
+ This means you cannot revoke privileges per-schema if they are granted
+ globally (either by default, or according to a previous <command>ALTER
+ DEFAULT PRIVILEGES</command> command that did not specify a schema).
+ Per-schema <literal>REVOKE</literal> is only useful to reverse the
+ effects of a previous per-schema <literal>GRANT</literal>.
+ </para>
+
+ <refsect2>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>target_role</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing role of which the current role is a member.
+ If <literal>FOR ROLE</literal> is omitted, the current role is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>schema_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing schema. If specified, the default privileges
+ are altered for objects later created in that schema.
+ If <literal>IN SCHEMA</literal> is omitted, the global default privileges
+ are altered.
+ <literal>IN SCHEMA</literal> is not allowed when setting privileges
+ for schemas, since schemas can't be nested.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>role_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing role to grant or revoke privileges for.
+ This parameter, and all the other parameters in
+ <replaceable class="parameter">abbreviated_grant_or_revoke</replaceable>,
+ act as described under
+ <xref linkend="sql-grant"/> or
+ <xref linkend="sql-revoke"/>,
+ except that one is setting permissions for a whole class of objects
+ rather than specific named objects.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+ </refsect1>
+
+ <refsect1 id="sql-alterdefaultprivileges-notes">
+ <title>Notes</title>
+
+ <para>
+ Use <xref linkend="app-psql"/>'s <command>\ddp</command> command
+ to obtain information about existing assignments of default privileges.
+ The meaning of the privilege display is the same as explained for
+ <command>\dp</command> in <xref linkend="ddl-priv"/>.
+ </para>
+
+ <para>
+ If you wish to drop a role for which the default privileges have been
+ altered, it is necessary to reverse the changes in its default privileges
+ or use <command>DROP OWNED BY</command> to get rid of the default privileges entry
+ for the role.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-alterdefaultprivileges-examples">
+ <title>Examples</title>
+
+ <para>
+ Grant SELECT privilege to everyone for all tables (and views) you
+ subsequently create in schema <literal>myschema</literal>, and allow
+ role <literal>webuser</literal> to INSERT into them too:
+
+<programlisting>
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO PUBLIC;
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT INSERT ON TABLES TO webuser;
+</programlisting>
+ </para>
+
+ <para>
+ Undo the above, so that subsequently-created tables won't have any
+ more permissions than normal:
+
+<programlisting>
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE SELECT ON TABLES FROM PUBLIC;
+ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE INSERT ON TABLES FROM webuser;
+</programlisting>
+ </para>
+
+ <para>
+ Remove the public EXECUTE permission that is normally granted on functions,
+ for all functions subsequently created by role <literal>admin</literal>:
+<programlisting>
+ALTER DEFAULT PRIVILEGES FOR ROLE admin REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
+</programlisting>
+ Note however that you <emphasis>cannot</emphasis> accomplish that effect
+ with a command limited to a single schema. This command has no effect,
+ unless it is undoing a matching <literal>GRANT</literal>:
+<programlisting>
+ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
+</programlisting>
+ That's because per-schema default privileges can only add privileges to
+ the global setting, not remove privileges granted by it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER DEFAULT PRIVILEGES</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-grant"/></member>
+ <member><xref linkend="sql-revoke"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml
new file mode 100644
index 0000000..2db5372
--- /dev/null
+++ b/doc/src/sgml/ref/alter_domain.sgml
@@ -0,0 +1,365 @@
+<!--
+doc/src/sgml/ref/alter_domain.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterdomain">
+ <indexterm zone="sql-alterdomain">
+ <primary>ALTER DOMAIN</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER DOMAIN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER DOMAIN</refname>
+ <refpurpose>
+ change the definition of a domain
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ { SET DEFAULT <replaceable class="parameter">expression</replaceable> | DROP DEFAULT }
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ { SET | DROP } NOT NULL
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ ADD <replaceable class="parameter">domain_constraint</replaceable> [ NOT VALID ]
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ DROP CONSTRAINT [ IF EXISTS ] <replaceable class="parameter">constraint_name</replaceable> [ RESTRICT | CASCADE ]
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ RENAME CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> TO <replaceable class="parameter">new_constraint_name</replaceable>
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ VALIDATE CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER DOMAIN <replaceable class="parameter">name</replaceable>
+ SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER DOMAIN</command> changes the definition of an existing domain.
+ There are several sub-forms:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP DEFAULT</literal></term>
+ <listitem>
+ <para>
+ These forms set or remove the default value for a domain. Note
+ that defaults only apply to subsequent <command>INSERT</command>
+ commands; they do not affect rows already in a table using the domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP NOT NULL</literal></term>
+ <listitem>
+ <para>
+ These forms change whether a domain is marked to allow NULL
+ values or to reject NULL values. You can only <literal>SET NOT NULL</literal>
+ when the columns using the domain contain no null values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD <replaceable class="parameter">domain_constraint</replaceable> [ NOT VALID ]</literal></term>
+ <listitem>
+ <para>
+ This form adds a new constraint to a domain using the same syntax as
+ <link linkend="sql-createdomain"><command>CREATE DOMAIN</command></link>.
+ When a new constraint is added to a domain, all columns using that
+ domain will be checked against the newly added constraint. These
+ checks can be suppressed by adding the new constraint using the
+ <literal>NOT VALID</literal> option; the constraint can later be made
+ valid using <command>ALTER DOMAIN ... VALIDATE CONSTRAINT</command>.
+ Newly inserted or updated rows are always checked against all
+ constraints, even those marked <literal>NOT VALID</literal>.
+ <literal>NOT VALID</literal> is only accepted for <literal>CHECK</literal> constraints.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP CONSTRAINT [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form drops constraints on a domain.
+ If <literal>IF EXISTS</literal> is specified and the constraint
+ does not exist, no error is thrown. In this case a notice is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME CONSTRAINT</literal></term>
+ <listitem>
+ <para>
+ This form changes the name of a constraint on a domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALIDATE CONSTRAINT</literal></term>
+ <listitem>
+ <para>
+ This form validates a constraint previously added as
+ <literal>NOT VALID</literal>, that is, it verifies that all values in
+ table columns of the domain type satisfy the specified constraint.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OWNER</literal></term>
+ <listitem>
+ <para>
+ This form changes the owner of the domain to the specified user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME</literal></term>
+ <listitem>
+ <para>
+ This form changes the name of the domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET SCHEMA</literal></term>
+ <listitem>
+ <para>
+ This form changes the schema of the domain. Any constraints
+ associated with the domain are moved into the new schema as well.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ You must own the domain to use <command>ALTER DOMAIN</command>.
+ To change the schema of a domain, you must also have
+ <literal>CREATE</literal> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the domain's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the domain.
+ However, a superuser can alter ownership of any domain anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of an existing domain to
+ alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">domain_constraint</replaceable></term>
+ <listitem>
+ <para>
+ New domain constraint for the domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">constraint_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of an existing constraint to drop or rename.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOT VALID</literal></term>
+ <listitem>
+ <para>
+ Do not verify existing stored data for constraint validity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the constraint,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the constraint if there are any dependent
+ objects. This is the default behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_constraint_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the constraint.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Although <command>ALTER DOMAIN ADD CONSTRAINT</command> attempts to verify
+ that existing stored data satisfies the new constraint, this check is not
+ bulletproof, because the command cannot <quote>see</quote> table rows that
+ are newly inserted or updated and not yet committed. If there is a hazard
+ that concurrent operations might insert bad data, the way to proceed is to
+ add the constraint using the <literal>NOT VALID</literal> option, commit
+ that command, wait until all transactions started before that commit have
+ finished, and then issue <command>ALTER DOMAIN VALIDATE
+ CONSTRAINT</command> to search for data violating the constraint. This
+ method is reliable because once the constraint is committed, all new
+ transactions are guaranteed to enforce it against new values of the domain
+ type.
+ </para>
+
+ <para>
+ Currently, <command>ALTER DOMAIN ADD CONSTRAINT</command>, <command>ALTER
+ DOMAIN VALIDATE CONSTRAINT</command>, and <command>ALTER DOMAIN SET NOT
+ NULL</command> will fail if the named domain or any derived domain is used
+ within a container-type column (a composite, array, or range column) in
+ any table in the database. They should eventually be improved to be able
+ to verify the new constraint for such nested values.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To add a <literal>NOT NULL</literal> constraint to a domain:
+<programlisting>
+ALTER DOMAIN zipcode SET NOT NULL;
+</programlisting>
+ To remove a <literal>NOT NULL</literal> constraint from a domain:
+<programlisting>
+ALTER DOMAIN zipcode DROP NOT NULL;
+</programlisting>
+ </para>
+
+ <para>
+ To add a check constraint to a domain:
+<programlisting>
+ALTER DOMAIN zipcode ADD CONSTRAINT zipchk CHECK (char_length(VALUE) = 5);
+</programlisting>
+ </para>
+
+ <para>
+ To remove a check constraint from a domain:
+<programlisting>
+ALTER DOMAIN zipcode DROP CONSTRAINT zipchk;
+</programlisting>
+ </para>
+
+ <para>
+ To rename a check constraint on a domain:
+<programlisting>
+ALTER DOMAIN zipcode RENAME CONSTRAINT zipchk TO zip_check;
+</programlisting>
+ </para>
+
+ <para>
+ To move the domain into a different schema:
+<programlisting>
+ALTER DOMAIN zipcode SET SCHEMA customers;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-alterdomain-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER DOMAIN</command> conforms to the <acronym>SQL</acronym>
+ standard, except for the <literal>OWNER</literal>, <literal>RENAME</literal>, <literal>SET SCHEMA</literal>, and
+ <literal>VALIDATE CONSTRAINT</literal> variants, which are
+ <productname>PostgreSQL</productname> extensions. The <literal>NOT VALID</literal>
+ clause of the <literal>ADD CONSTRAINT</literal> variant is also a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-alterdomain-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createdomain"/></member>
+ <member><xref linkend="sql-dropdomain"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_event_trigger.sgml b/doc/src/sgml/ref/alter_event_trigger.sgml
new file mode 100644
index 0000000..ef5253b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_event_trigger.sgml
@@ -0,0 +1,105 @@
+<!--
+doc/src/sgml/ref/alter_event_trigger.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altereventtrigger">
+ <indexterm zone="sql-altereventtrigger">
+ <primary>ALTER EVENT TRIGGER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER EVENT TRIGGER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER EVENT TRIGGER</refname>
+ <refpurpose>change the definition of an event trigger</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER EVENT TRIGGER <replaceable class="parameter">name</replaceable> DISABLE
+ALTER EVENT TRIGGER <replaceable class="parameter">name</replaceable> ENABLE [ REPLICA | ALWAYS ]
+ALTER EVENT TRIGGER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER EVENT TRIGGER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER EVENT TRIGGER</command> changes properties of an
+ existing event trigger.
+ </para>
+
+ <para>
+ You must be superuser to alter an event trigger.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing trigger to alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the event trigger.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the event trigger.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE</literal>/<literal>ENABLE [ REPLICA | ALWAYS ] TRIGGER</literal></term>
+ <listitem>
+ <para>
+ These forms configure the firing of event triggers. A disabled trigger
+ is still known to the system, but is not executed when its triggering
+ event occurs. See also <xref linkend="guc-session-replication-role"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-alterventtrigger-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER EVENT TRIGGER</command> statement in the
+ SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createeventtrigger"/></member>
+ <member><xref linkend="sql-dropeventtrigger"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_extension.sgml b/doc/src/sgml/ref/alter_extension.sgml
new file mode 100644
index 0000000..c819c7b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_extension.sgml
@@ -0,0 +1,334 @@
+<!--
+doc/src/sgml/ref/alter_extension.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterextension">
+ <indexterm zone="sql-alterextension">
+ <primary>ALTER EXTENSION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER EXTENSION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER EXTENSION</refname>
+ <refpurpose>
+ change the definition of an extension
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER EXTENSION <replaceable class="parameter">name</replaceable> UPDATE [ TO <replaceable class="parameter">new_version</replaceable> ]
+ALTER EXTENSION <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+ALTER EXTENSION <replaceable class="parameter">name</replaceable> ADD <replaceable class="parameter">member_object</replaceable>
+ALTER EXTENSION <replaceable class="parameter">name</replaceable> DROP <replaceable class="parameter">member_object</replaceable>
+
+<phrase>where <replaceable class="parameter">member_object</replaceable> is:</phrase>
+
+ ACCESS METHOD <replaceable class="parameter">object_name</replaceable> |
+ AGGREGATE <replaceable class="parameter">aggregate_name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) |
+ CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>) |
+ COLLATION <replaceable class="parameter">object_name</replaceable> |
+ CONVERSION <replaceable class="parameter">object_name</replaceable> |
+ DOMAIN <replaceable class="parameter">object_name</replaceable> |
+ EVENT TRIGGER <replaceable class="parameter">object_name</replaceable> |
+ FOREIGN DATA WRAPPER <replaceable class="parameter">object_name</replaceable> |
+ FOREIGN TABLE <replaceable class="parameter">object_name</replaceable> |
+ FUNCTION <replaceable class="parameter">function_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ MATERIALIZED VIEW <replaceable class="parameter">object_name</replaceable> |
+ OPERATOR <replaceable class="parameter">operator_name</replaceable> (<replaceable class="parameter">left_type</replaceable>, <replaceable class="parameter">right_type</replaceable>) |
+ OPERATOR CLASS <replaceable class="parameter">object_name</replaceable> USING <replaceable class="parameter">index_method</replaceable> |
+ OPERATOR FAMILY <replaceable class="parameter">object_name</replaceable> USING <replaceable class="parameter">index_method</replaceable> |
+ [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">object_name</replaceable> |
+ PROCEDURE <replaceable class="parameter">procedure_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ ROUTINE <replaceable class="parameter">routine_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ SCHEMA <replaceable class="parameter">object_name</replaceable> |
+ SEQUENCE <replaceable class="parameter">object_name</replaceable> |
+ SERVER <replaceable class="parameter">object_name</replaceable> |
+ TABLE <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH CONFIGURATION <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH DICTIONARY <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH PARSER <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH TEMPLATE <replaceable class="parameter">object_name</replaceable> |
+ TRANSFORM FOR <replaceable>type_name</replaceable> LANGUAGE <replaceable>lang_name</replaceable> |
+ TYPE <replaceable class="parameter">object_name</replaceable> |
+ VIEW <replaceable class="parameter">object_name</replaceable>
+
+<phrase>and <replaceable>aggregate_signature</replaceable> is:</phrase>
+
+* |
+[ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] |
+[ [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] ] ORDER BY [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER EXTENSION</command> changes the definition of an installed
+ extension. There are several subforms:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>UPDATE</literal></term>
+ <listitem>
+ <para>
+ This form updates the extension to a newer version. The extension
+ must supply a suitable update script (or series of scripts) that can
+ modify the currently-installed version into the requested version.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET SCHEMA</literal></term>
+ <listitem>
+ <para>
+ This form moves the extension's objects into another schema. The
+ extension has to be <firstterm>relocatable</firstterm> for this command to
+ succeed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD <replaceable class="parameter">member_object</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form adds an existing object to the extension. This is mainly
+ useful in extension update scripts. The object will subsequently
+ be treated as a member of the extension; notably, it can only be
+ dropped by dropping the extension.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP <replaceable class="parameter">member_object</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form removes a member object from the extension. This is mainly
+ useful in extension update scripts. The object is not dropped, only
+ disassociated from the extension.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ See <xref linkend="extend-extensions"/> for more information about these
+ operations.
+ </para>
+
+ <para>
+ You must own the extension to use <command>ALTER EXTENSION</command>.
+ The <literal>ADD</literal>/<literal>DROP</literal> forms require ownership of the
+ added/dropped object as well.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an installed extension.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_version</replaceable></term>
+ <listitem>
+ <para>
+ The desired new version of the extension. This can be written as
+ either an identifier or a string literal. If not specified,
+ <command>ALTER EXTENSION UPDATE</command> attempts to update to whatever is
+ shown as the default version in the extension's control file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the extension.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">object_name</replaceable></term>
+ <term><replaceable class="parameter">aggregate_name</replaceable></term>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <term><replaceable class="parameter">operator_name</replaceable></term>
+ <term><replaceable class="parameter">procedure_name</replaceable></term>
+ <term><replaceable class="parameter">routine_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an object to be added to or removed from the extension.
+ Names of tables,
+ aggregates, domains, foreign tables, functions, operators,
+ operator classes, operator families, procedures, routines, sequences, text search objects,
+ types, and views can be schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>source_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of the source data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>target_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of the target data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of a function, procedure, or aggregate
+ argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ Note that <command>ALTER EXTENSION</command> does not actually pay
+ any attention to <literal>OUT</literal> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <literal>IN</literal>, <literal>INOUT</literal>,
+ and <literal>VARIADIC</literal> arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of a function, procedure, or aggregate argument.
+ Note that <command>ALTER EXTENSION</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type of a function, procedure, or aggregate argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">left_type</replaceable></term>
+ <term><replaceable class="parameter">right_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type(s) of the operator's arguments (optionally
+ schema-qualified). Write <literal>NONE</literal> for the missing argument
+ of a prefix operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROCEDURAL</literal></term>
+
+ <listitem>
+ <para>
+ This is a noise word.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>type_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the data type of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>lang_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the language of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To update the <literal>hstore</literal> extension to version 2.0:
+<programlisting>
+ALTER EXTENSION hstore UPDATE TO '2.0';
+</programlisting>
+ </para>
+
+ <para>
+ To change the schema of the <literal>hstore</literal> extension
+ to <literal>utils</literal>:
+<programlisting>
+ALTER EXTENSION hstore SET SCHEMA utils;
+</programlisting>
+ </para>
+
+ <para>
+ To add an existing function to the <literal>hstore</literal> extension:
+<programlisting>
+ALTER EXTENSION hstore ADD FUNCTION populate_record(anyelement, hstore);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER EXTENSION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-alterextension-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createextension"/></member>
+ <member><xref linkend="sql-dropextension"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml
new file mode 100644
index 0000000..54f34c2
--- /dev/null
+++ b/doc/src/sgml/ref/alter_foreign_data_wrapper.sgml
@@ -0,0 +1,188 @@
+<!--
+doc/src/sgml/ref/alter_foreign_data_wrapper.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterforeigndatawrapper">
+ <indexterm zone="sql-alterforeigndatawrapper">
+ <primary>ALTER FOREIGN DATA WRAPPER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER FOREIGN DATA WRAPPER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER FOREIGN DATA WRAPPER</refname>
+ <refpurpose>change the definition of a foreign-data wrapper</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
+ [ HANDLER <replaceable class="parameter">handler_function</replaceable> | NO HANDLER ]
+ [ VALIDATOR <replaceable class="parameter">validator_function</replaceable> | NO VALIDATOR ]
+ [ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ]) ]
+ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER FOREIGN DATA WRAPPER</command> changes the
+ definition of a foreign-data wrapper. The first form of the
+ command changes the support functions or the generic options of the
+ foreign-data wrapper (at least one clause is required). The second
+ form changes the owner of the foreign-data wrapper.
+ </para>
+
+ <para>
+ Only superusers can alter foreign-data wrappers. Additionally,
+ only superusers can own foreign-data wrappers.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HANDLER <replaceable class="parameter">handler_function</replaceable></literal></term>
+ <listitem>
+ <para>
+ Specifies a new handler function for the foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NO HANDLER</literal></term>
+ <listitem>
+ <para>
+ This is used to specify that the foreign-data wrapper should no
+ longer have a handler function.
+ </para>
+ <para>
+ Note that foreign tables that use a foreign-data wrapper with no
+ handler cannot be accessed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALIDATOR <replaceable class="parameter">validator_function</replaceable></literal></term>
+ <listitem>
+ <para>
+ Specifies a new validator function for the foreign-data wrapper.
+ </para>
+
+ <para>
+ Note that it is possible that pre-existing options of the foreign-data
+ wrapper, or of dependent servers, user mappings, or foreign tables, are
+ invalid according to the new validator. <productname>PostgreSQL</productname> does
+ not check for this. It is up to the user to make sure that these
+ options are correct before using the modified foreign-data wrapper.
+ However, any options specified in this <command>ALTER FOREIGN DATA
+ WRAPPER</command> command will be checked using the new validator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NO VALIDATOR</literal></term>
+ <listitem>
+ <para>
+ This is used to specify that the foreign-data wrapper should no
+ longer have a validator function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ Change options for the foreign-data
+ wrapper. <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
+ specify the action to be performed. <literal>ADD</literal> is assumed
+ if no operation is explicitly specified. Option names must be
+ unique; names and values are also validated using the foreign
+ data wrapper's validator function, if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change a foreign-data wrapper <literal>dbi</literal>, add
+ option <literal>foo</literal>, drop <literal>bar</literal>:
+<programlisting>
+ALTER FOREIGN DATA WRAPPER dbi OPTIONS (ADD foo '1', DROP 'bar');
+</programlisting>
+ </para>
+
+ <para>
+ Change the foreign-data wrapper <literal>dbi</literal> validator
+ to <literal>bob.myvalidator</literal>:
+<programlisting>
+ALTER FOREIGN DATA WRAPPER dbi VALIDATOR bob.myvalidator;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
+ 9075-9 (SQL/MED), except that the <literal>HANDLER</literal>,
+ <literal>VALIDATOR</literal>, <literal>OWNER TO</literal>, and <literal>RENAME</literal>
+ clauses are extensions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createforeigndatawrapper"/></member>
+ <member><xref linkend="sql-dropforeigndatawrapper"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml
new file mode 100644
index 0000000..5d373ae
--- /dev/null
+++ b/doc/src/sgml/ref/alter_foreign_table.sgml
@@ -0,0 +1,556 @@
+<!--
+doc/src/sgml/rel/alter_foreign_table.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterforeigntable">
+ <indexterm zone="sql-alterforeigntable">
+ <primary>ALTER FOREIGN TABLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER FOREIGN TABLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER FOREIGN TABLE</refname>
+ <refpurpose>change the definition of a foreign table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
+ <replaceable class="parameter">action</replaceable> [, ... ]
+ALTER FOREIGN TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
+ RENAME [ COLUMN ] <replaceable class="parameter">column_name</replaceable> TO <replaceable class="parameter">new_column_name</replaceable>
+ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ ADD [ COLUMN ] <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="parameter">column_name</replaceable> [ RESTRICT | CASCADE ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> [ SET DATA ] TYPE <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET DEFAULT <replaceable class="parameter">expression</replaceable>
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP DEFAULT
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> { SET | DROP } NOT NULL
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STATISTICS <replaceable class="parameter">integer</replaceable>
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ])
+ ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]
+ VALIDATE CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
+ DROP CONSTRAINT [ IF EXISTS ] <replaceable class="parameter">constraint_name</replaceable> [ RESTRICT | CASCADE ]
+ DISABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
+ ENABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
+ ENABLE REPLICA TRIGGER <replaceable class="parameter">trigger_name</replaceable>
+ ENABLE ALWAYS TRIGGER <replaceable class="parameter">trigger_name</replaceable>
+ SET WITHOUT OIDS
+ INHERIT <replaceable class="parameter">parent_table</replaceable>
+ NO INHERIT <replaceable class="parameter">parent_table</replaceable>
+ OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ])
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER FOREIGN TABLE</command> changes the definition of an
+ existing foreign table. There are several subforms:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ADD COLUMN</literal></term>
+ <listitem>
+ <para>
+ This form adds a new column to the foreign table, using the same syntax as
+ <link linkend="sql-createforeigntable"><command>CREATE FOREIGN TABLE</command></link>.
+ Unlike the case when adding a column to a regular table, nothing happens
+ to the underlying storage: this action simply declares that
+ some new column is now accessible through the foreign table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP COLUMN [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form drops a column from a foreign table.
+ You will need to say <literal>CASCADE</literal> if
+ anything outside the table depends on the column; for example,
+ views.
+ If <literal>IF EXISTS</literal> is specified and the column
+ does not exist, no error is thrown. In this case a notice
+ is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET DATA TYPE</literal></term>
+ <listitem>
+ <para>
+ This form changes the type of a column of a foreign table.
+ Again, this has no effect on any underlying storage: this action simply
+ changes the type that <productname>PostgreSQL</productname> believes the column to
+ have.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP DEFAULT</literal></term>
+ <listitem>
+ <para>
+ These forms set or remove the default value for a column.
+ Default values only apply in subsequent <command>INSERT</command>
+ or <command>UPDATE</command> commands; they do not cause rows already in the
+ table to change.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP NOT NULL</literal></term>
+ <listitem>
+ <para>
+ Mark a column as allowing, or not allowing, null values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET STATISTICS</literal></term>
+ <listitem>
+ <para>
+ This form
+ sets the per-column statistics-gathering target for subsequent
+ <link linkend="sql-analyze"><command>ANALYZE</command></link> operations.
+ See the similar form of <link linkend="sql-altertable"><command>ALTER TABLE</command></link>
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )</literal></term>
+ <term><literal>RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This form sets or resets per-attribute options.
+ See the similar form of <link linkend="sql-altertable"><command>ALTER TABLE</command></link>
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SET STORAGE</literal>
+ </term>
+ <listitem>
+ <para>
+ This form sets the storage mode for a column.
+ See the similar form of <link linkend="sql-altertable"><command>ALTER TABLE</command></link>
+ for more details.
+ Note that the storage mode has no effect unless the table's
+ foreign-data wrapper chooses to pay attention to it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]</literal></term>
+ <listitem>
+ <para>
+ This form adds a new constraint to a foreign table, using the same
+ syntax as <link linkend="sql-createforeigntable"><command>CREATE FOREIGN TABLE</command></link>.
+ Currently only <literal>CHECK</literal> constraints are supported.
+ </para>
+
+ <para>
+ Unlike the case when adding a constraint to a regular table, nothing is
+ done to verify the constraint is correct; rather, this action simply
+ declares that some new condition should be assumed to hold for all rows
+ in the foreign table. (See the discussion
+ in <link linkend="sql-createforeigntable"><command>CREATE FOREIGN TABLE</command></link>.)
+ If the constraint is marked <literal>NOT VALID</literal>, then it isn't
+ assumed to hold, but is only recorded for possible future use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALIDATE CONSTRAINT</literal></term>
+ <listitem>
+ <para>
+ This form marks as valid a constraint that was previously marked
+ as <literal>NOT VALID</literal>. No action is taken to verify the
+ constraint, but future queries will assume that it holds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP CONSTRAINT [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form drops the specified constraint on a foreign table.
+ If <literal>IF EXISTS</literal> is specified and the constraint
+ does not exist, no error is thrown.
+ In this case a notice is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE</literal>/<literal>ENABLE [ REPLICA | ALWAYS ] TRIGGER</literal></term>
+ <listitem>
+ <para>
+ These forms configure the firing of trigger(s) belonging to the foreign
+ table. See the similar form of <link linkend="sql-altertable"><command>ALTER TABLE</command></link> for more
+ details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET WITHOUT OIDS</literal></term>
+ <listitem>
+ <para>
+ Backward compatibility syntax for removing the <literal>oid</literal>
+ system column. As <literal>oid</literal> system columns cannot be added
+ anymore, this never has an effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INHERIT <replaceable class="parameter">parent_table</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form adds the target foreign table as a new child of the specified
+ parent table.
+ See the similar form of <link linkend="sql-altertable"><command>ALTER TABLE</command></link>
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NO INHERIT <replaceable class="parameter">parent_table</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form removes the target foreign table from the list of children of
+ the specified parent table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OWNER</literal></term>
+ <listitem>
+ <para>
+ This form changes the owner of the foreign table to the
+ specified user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ Change options for the foreign table or one of its columns.
+ <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
+ specify the action to be performed. <literal>ADD</literal> is assumed
+ if no operation is explicitly specified. Duplicate option names are not
+ allowed (although it's OK for a table option and a column option to have
+ the same name). Option names and values are also validated using the
+ foreign data wrapper library.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME</literal></term>
+ <listitem>
+ <para>
+ The <literal>RENAME</literal> forms change the name of a foreign table
+ or the name of an individual column in a foreign table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET SCHEMA</literal></term>
+ <listitem>
+ <para>
+ This form moves the foreign table into another schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ All the actions except <literal>RENAME</literal> and <literal>SET SCHEMA</literal>
+ can be combined into
+ a list of multiple alterations to apply in parallel. For example, it
+ is possible to add several columns and/or alter the type of several
+ columns in a single command.
+ </para>
+
+ <para>
+ If the command is written as <literal>ALTER FOREIGN TABLE IF EXISTS ...</literal>
+ and the foreign table does not exist, no error is thrown. A notice is
+ issued in this case.
+ </para>
+
+ <para>
+ You must own the table to use <command>ALTER FOREIGN TABLE</command>.
+ To change the schema of a foreign table, you must also have
+ <literal>CREATE</literal> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the table's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the table.
+ However, a superuser can alter ownership of any table anyway.)
+ To add a column or alter a column type, you must also
+ have <literal>USAGE</literal> privilege on the data type.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of an existing foreign table to
+ alter. If <literal>ONLY</literal> is specified before the table name, only
+ that table is altered. If <literal>ONLY</literal> is not specified, the table
+ and all its descendant tables (if any) are altered. Optionally,
+ <literal>*</literal> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a new or existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_column_name</replaceable></term>
+ <listitem>
+ <para>
+ New name for an existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ New name for the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ Data type of the new column, or new data type for an existing
+ column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_constraint</replaceable></term>
+ <listitem>
+ <para>
+ New table constraint for the foreign table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">constraint_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of an existing constraint to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the dropped column
+ or constraint (for example, views referencing the column),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the column or constraint if there are any dependent
+ objects. This is the default behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">trigger_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a single trigger to disable or enable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Disable or enable all triggers belonging to the foreign table. (This
+ requires superuser privilege if any of the triggers are internally
+ generated triggers. The core system does not add such triggers to
+ foreign tables, but add-on code could do so.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USER</literal></term>
+ <listitem>
+ <para>
+ Disable or enable all triggers belonging to the foreign table except
+ for internally generated triggers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">parent_table</replaceable></term>
+ <listitem>
+ <para>
+ A parent table to associate or de-associate with this foreign table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The name of the schema to which the table will be moved.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The key word <literal>COLUMN</literal> is noise and can be omitted.
+ </para>
+
+ <para>
+ Consistency with the foreign server is not checked when a column is added
+ or removed with <literal>ADD COLUMN</literal> or
+ <literal>DROP COLUMN</literal>, a <literal>NOT NULL</literal>
+ or <literal>CHECK</literal> constraint is added, or a column type is changed
+ with <literal>SET DATA TYPE</literal>. It is the user's responsibility to ensure
+ that the table definition matches the remote side.
+ </para>
+
+ <para>
+ Refer to <link linkend="sql-createforeigntable"><command>CREATE FOREIGN TABLE</command></link> for a further description of valid
+ parameters.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To mark a column as not-null:
+<programlisting>
+ALTER FOREIGN TABLE distributors ALTER COLUMN street SET NOT NULL;
+</programlisting>
+ </para>
+
+ <para>
+ To change options of a foreign table:
+<programlisting>
+ALTER FOREIGN TABLE myschema.distributors OPTIONS (ADD opt1 'value', SET opt2 'value2', DROP opt3);
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The forms <literal>ADD</literal>, <literal>DROP</literal>,
+ and <literal>SET DATA TYPE</literal>
+ conform with the SQL standard. The other forms are
+ <productname>PostgreSQL</productname> extensions of the SQL standard.
+ Also, the ability to specify more than one manipulation in a single
+ <command>ALTER FOREIGN TABLE</command> command is an extension.
+ </para>
+
+ <para>
+ <command>ALTER FOREIGN TABLE DROP COLUMN</command> can be used to drop the only
+ column of a foreign table, leaving a zero-column table. This is an
+ extension of SQL, which disallows zero-column foreign tables.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createforeigntable"/></member>
+ <member><xref linkend="sql-dropforeigntable"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml
new file mode 100644
index 0000000..2e8e116
--- /dev/null
+++ b/doc/src/sgml/ref/alter_function.sgml
@@ -0,0 +1,392 @@
+<!--
+doc/src/sgml/ref/alter_function.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterfunction">
+ <indexterm zone="sql-alterfunction">
+ <primary>ALTER FUNCTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER FUNCTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER FUNCTION</refname>
+ <refpurpose>change the definition of a function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ <replaceable class="parameter">action</replaceable> [ ... ] [ RESTRICT ]
+ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ RENAME TO <replaceable>new_name</replaceable>
+ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ SET SCHEMA <replaceable>new_schema</replaceable>
+ALTER FUNCTION <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION <replaceable>extension_name</replaceable>
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
+ IMMUTABLE | STABLE | VOLATILE
+ [ NOT ] LEAKPROOF
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ COST <replaceable class="parameter">execution_cost</replaceable>
+ ROWS <replaceable class="parameter">result_rows</replaceable>
+ SUPPORT <replaceable class="parameter">support_function</replaceable>
+ SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
+ SET <replaceable class="parameter">configuration_parameter</replaceable> FROM CURRENT
+ RESET <replaceable class="parameter">configuration_parameter</replaceable>
+ RESET ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER FUNCTION</command> changes the definition of a
+ function.
+ </para>
+
+ <para>
+ You must own the function to use <command>ALTER FUNCTION</command>.
+ To change a function's schema, you must also have <literal>CREATE</literal>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the function's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the function.
+ However, a superuser can alter ownership of any function anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing function. If no
+ argument list is specified, the name must be unique in its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ Note that <command>ALTER FUNCTION</command> does not actually pay
+ any attention to <literal>OUT</literal> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <literal>IN</literal>, <literal>INOUT</literal>,
+ and <literal>VARIADIC</literal> arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ Note that <command>ALTER FUNCTION</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type(s) of the function's arguments (optionally
+ schema-qualified), if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the function. Note that if the function is
+ marked <literal>SECURITY DEFINER</literal>, it will subsequently
+ execute as the new owner.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>
+ <term><literal>NO DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form marks the function as dependent on the extension, or no longer
+ dependent on that extension if <literal>NO</literal> is specified.
+ A function that's marked as dependent on an extension is dropped when the
+ extension is dropped, even if <literal>CASCADE</literal> is not specified.
+ A function can depend upon multiple extensions, and will be dropped when
+ any one of those extensions is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CALLED ON NULL INPUT</literal></term>
+ <term><literal>RETURNS NULL ON NULL INPUT</literal></term>
+ <term><literal>STRICT</literal></term>
+
+ <listitem>
+ <para><literal>CALLED ON NULL INPUT</literal> changes the function so
+ that it will be invoked when some or all of its arguments are
+ null. <literal>RETURNS NULL ON NULL INPUT</literal> or
+ <literal>STRICT</literal> changes the function so that it is not
+ invoked if any of its arguments are null; instead, a null result
+ is assumed automatically. See <xref linkend="sql-createfunction"/>
+ for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IMMUTABLE</literal></term>
+ <term><literal>STABLE</literal></term>
+ <term><literal>VOLATILE</literal></term>
+
+ <listitem>
+ <para>
+ Change the volatility of the function to the specified setting.
+ See <xref linkend="sql-createfunction"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><optional> EXTERNAL </optional> SECURITY INVOKER</literal></term>
+ <term><literal><optional> EXTERNAL </optional> SECURITY DEFINER</literal></term>
+
+ <listitem>
+ <para>
+ Change whether the function is a security definer or not. The
+ key word <literal>EXTERNAL</literal> is ignored for SQL
+ conformance. See <xref linkend="sql-createfunction"/> for more information about
+ this capability.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PARALLEL</literal></term>
+
+ <listitem>
+ <para>
+ Change whether the function is deemed safe for parallelism.
+ See <xref linkend="sql-createfunction"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LEAKPROOF</literal></term>
+ <listitem>
+ <para>
+ Change whether the function is considered leakproof or not.
+ See <xref linkend="sql-createfunction"/> for more information about
+ this capability.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COST</literal> <replaceable class="parameter">execution_cost</replaceable></term>
+
+ <listitem>
+ <para>
+ Change the estimated execution cost of the function.
+ See <xref linkend="sql-createfunction"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ROWS</literal> <replaceable class="parameter">result_rows</replaceable></term>
+
+ <listitem>
+ <para>
+ Change the estimated number of rows returned by a set-returning
+ function. See <xref linkend="sql-createfunction"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SUPPORT</literal> <replaceable class="parameter">support_function</replaceable></term>
+
+ <listitem>
+ <para>
+ Set or change the planner support function to use for this function.
+ See <xref linkend="xfunc-optimization"/> for details. You must be
+ superuser to use this option.
+ </para>
+
+ <para>
+ This option cannot be used to remove the support function altogether,
+ since it must name a new support function. Use <command>CREATE OR
+ REPLACE FUNCTION</command> if you need to do that.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>configuration_parameter</replaceable></term>
+ <term><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ Add or change the assignment to be made to a configuration parameter
+ when the function is called. If
+ <replaceable>value</replaceable> is <literal>DEFAULT</literal>
+ or, equivalently, <literal>RESET</literal> is used, the function-local
+ setting is removed, so that the function executes with the value
+ present in its environment. Use <literal>RESET
+ ALL</literal> to clear all function-local settings.
+ <literal>SET FROM CURRENT</literal> saves the value of the parameter that
+ is current when <command>ALTER FUNCTION</command> is executed as the value
+ to be applied when the function is entered.
+ </para>
+
+ <para>
+ See <xref linkend="sql-set"/> and
+ <xref linkend="runtime-config"/>
+ for more information about allowed parameter names and values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ Ignored for conformance with the SQL standard.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the function <literal>sqrt</literal> for type
+ <type>integer</type> to <literal>square_root</literal>:
+<programlisting>
+ALTER FUNCTION sqrt(integer) RENAME TO square_root;
+</programlisting>
+ </para>
+
+ <para>
+ To change the owner of the function <literal>sqrt</literal> for type
+ <type>integer</type> to <literal>joe</literal>:
+<programlisting>
+ALTER FUNCTION sqrt(integer) OWNER TO joe;
+</programlisting>
+ </para>
+
+ <para>
+ To change the schema of the function <literal>sqrt</literal> for type
+ <type>integer</type> to <literal>maths</literal>:
+<programlisting>
+ALTER FUNCTION sqrt(integer) SET SCHEMA maths;
+</programlisting>
+ </para>
+
+ <para>
+ To mark the function <literal>sqrt</literal> for type
+ <type>integer</type> as being dependent on the extension
+ <literal>mathlib</literal>:
+<programlisting>
+ALTER FUNCTION sqrt(integer) DEPENDS ON EXTENSION mathlib;
+</programlisting>
+ </para>
+
+ <para>
+ To adjust the search path that is automatically set for a function:
+<programlisting>
+ALTER FUNCTION check_password(text) SET search_path = admin, pg_temp;
+</programlisting>
+ </para>
+
+ <para>
+ To disable automatic setting of <varname>search_path</varname> for a function:
+<programlisting>
+ALTER FUNCTION check_password(text) RESET search_path;
+</programlisting>
+ The function will now execute with whatever search path is used by its
+ caller.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This statement is partially compatible with the <command>ALTER
+ FUNCTION</command> statement in the SQL standard. The standard allows more
+ properties of a function to be modified, but does not provide the
+ ability to rename a function, make a function a security definer,
+ attach configuration parameter values to a function,
+ or change the owner, schema, or volatility of a function. The standard also
+ requires the <literal>RESTRICT</literal> key word, which is optional in
+ <productname>PostgreSQL</productname>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createfunction"/></member>
+ <member><xref linkend="sql-dropfunction"/></member>
+ <member><xref linkend="sql-alterprocedure"/></member>
+ <member><xref linkend="sql-alterroutine"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_group.sgml b/doc/src/sgml/ref/alter_group.sgml
new file mode 100644
index 0000000..fa4a8df
--- /dev/null
+++ b/doc/src/sgml/ref/alter_group.sgml
@@ -0,0 +1,135 @@
+<!--
+doc/src/sgml/ref/alter_group.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altergroup">
+ <indexterm zone="sql-altergroup">
+ <primary>ALTER GROUP</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER GROUP</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER GROUP</refname>
+ <refpurpose>change role name or membership</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER GROUP <replaceable class="parameter">role_specification</replaceable> ADD USER <replaceable class="parameter">user_name</replaceable> [, ... ]
+ALTER GROUP <replaceable class="parameter">role_specification</replaceable> DROP USER <replaceable class="parameter">user_name</replaceable> [, ... ]
+
+<phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase>
+
+ <replaceable class="parameter">role_name</replaceable>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+
+ALTER GROUP <replaceable class="parameter">group_name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER GROUP</command> changes the attributes of a user group.
+ This is an obsolete command, though still accepted for backwards
+ compatibility, because groups (and users too) have been superseded by the
+ more general concept of roles.
+ </para>
+
+ <para>
+ The first two variants add users to a group or remove them from a group.
+ (Any role can play the part of either a <quote>user</quote> or a
+ <quote>group</quote> for this purpose.) These variants are effectively
+ equivalent to granting or revoking membership in the role named as the
+ <quote>group</quote>; so the preferred way to do this is to use
+ <link linkend="sql-grant"><command>GRANT</command></link> or
+ <link linkend="sql-revoke"><command>REVOKE</command></link>.
+ </para>
+
+ <para>
+ The third variant changes the name of the group. This is exactly
+ equivalent to renaming the role with
+ <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">group_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the group (role) to modify.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ Users (roles) that are to be added to or removed from the group.
+ The users must already exist; <command>ALTER GROUP</command> does not
+ create or drop users.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the group.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ Add users to a group:
+
+<programlisting>
+ALTER GROUP staff ADD USER karl, john;
+</programlisting>
+
+ Remove a user from a group:
+
+<programlisting>
+ALTER GROUP workers DROP USER beth;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER GROUP</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-grant"/></member>
+ <member><xref linkend="sql-revoke"/></member>
+ <member><xref linkend="sql-alterrole"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgml
new file mode 100644
index 0000000..e26efec
--- /dev/null
+++ b/doc/src/sgml/ref/alter_index.sgml
@@ -0,0 +1,323 @@
+<!--
+doc/src/sgml/ref/alter_index.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterindex">
+ <indexterm zone="sql-alterindex">
+ <primary>ALTER INDEX</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER INDEX</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER INDEX</refname>
+ <refpurpose>change the definition of an index</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET TABLESPACE <replaceable class="parameter">tablespace_name</replaceable>
+ALTER INDEX <replaceable class="parameter">name</replaceable> ATTACH PARTITION <replaceable class="parameter">index_name</replaceable>
+ALTER INDEX <replaceable class="parameter">name</replaceable> [ NO ] DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable>
+ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
+ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )
+ALTER INDEX [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="parameter">column_number</replaceable>
+ SET STATISTICS <replaceable class="parameter">integer</replaceable>
+ALTER INDEX ALL IN TABLESPACE <replaceable class="parameter">name</replaceable> [ OWNED BY <replaceable class="parameter">role_name</replaceable> [, ... ] ]
+ SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> [ NOWAIT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER INDEX</command> changes the definition of an existing index.
+ There are several subforms described below. Note that the lock level required
+ may differ for each subform. An <literal>ACCESS EXCLUSIVE</literal> lock is held
+ unless explicitly noted. When multiple subcommands are listed, the lock
+ held will be the strictest one required from any subcommand.
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>RENAME</literal></term>
+ <listitem>
+ <para>
+ The <literal>RENAME</literal> form changes the name of the index.
+ If the index is associated with a table constraint (either
+ <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>,
+ or <literal>EXCLUDE</literal>), the constraint is renamed as well.
+ There is no effect on the stored data.
+ </para>
+ <para>
+ Renaming an index acquires a <literal>SHARE UPDATE EXCLUSIVE</literal>
+ lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET TABLESPACE</literal></term>
+ <listitem>
+ <para>
+ This form changes the index's tablespace to the specified tablespace and
+ moves the data file(s) associated with the index to the new tablespace.
+ To change the tablespace of an index, you must own the index and have
+ <literal>CREATE</literal> privilege on the new tablespace.
+ All indexes in the current database in a tablespace can be moved by using
+ the <literal>ALL IN TABLESPACE</literal> form, which will lock all
+ indexes to be moved and then move each one. This form also supports
+ <literal>OWNED BY</literal>, which will only move indexes owned by the
+ roles specified. If the <literal>NOWAIT</literal> option is specified
+ then the command will fail if it is unable to acquire all of the locks
+ required immediately. Note that system catalogs will not be moved by
+ this command, use <command>ALTER DATABASE</command> or explicit
+ <command>ALTER INDEX</command> invocations instead if desired.
+ See also
+ <link linkend="sql-createtablespace"><command>CREATE TABLESPACE</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ATTACH PARTITION</literal></term>
+ <listitem>
+ <para>
+ Causes the named index to become attached to the altered index.
+ The named index must be on a partition of the table containing the
+ index being altered, and have an equivalent definition. An attached
+ index cannot be dropped by itself, and will automatically be dropped
+ if its parent index is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>
+ <term><literal>NO DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form marks the index as dependent on the extension, or no longer
+ dependent on that extension if <literal>NO</literal> is specified.
+ An index that's marked as dependent on an extension is automatically
+ dropped when the extension is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This form changes one or more index-method-specific storage parameters
+ for the index. See
+ <link linkend="sql-createindex"><command>CREATE INDEX</command></link>
+ for details on the available parameters. Note that the index contents
+ will not be modified immediately by this command; depending on the
+ parameter you might need to rebuild the index with
+ <link linkend="sql-reindex"><command>REINDEX</command></link>
+ to get the desired effects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This form resets one or more index-method-specific storage parameters to
+ their defaults. As with <literal>SET</literal>, a <literal>REINDEX</literal>
+ might be needed to update the index entirely.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALTER [ COLUMN ] <replaceable class="parameter">column_number</replaceable> SET STATISTICS <replaceable class="parameter">integer</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form sets the per-column statistics-gathering target for
+ subsequent <link linkend="sql-analyze"><command>ANALYZE</command></link> operations, though can
+ be used only on index columns that are defined as an expression.
+ Since expressions lack a unique name, we refer to them using the
+ ordinal number of the index column.
+ The target can be set in the range 0 to 10000; alternatively, set it
+ to -1 to revert to using the system default statistics
+ target (<xref linkend="guc-default-statistics-target"/>).
+ For more information on the use of statistics by the
+ <productname>PostgreSQL</productname> query planner, refer to
+ <xref linkend="planner-stats"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the index does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_number</replaceable></term>
+ <listitem>
+ <para>
+ The ordinal number refers to the ordinal (left-to-right) position
+ of the index column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of an existing index to
+ alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">tablespace_name</replaceable></term>
+ <listitem>
+ <para>
+ The tablespace to which the index will be moved.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">extension_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the extension that the index is to depend on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">storage_parameter</replaceable></term>
+ <listitem>
+ <para>
+ The name of an index-method-specific storage parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ The new value for an index-method-specific storage parameter.
+ This might be a number or a word depending on the parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ These operations are also possible using
+ <link linkend="sql-altertable"><command>ALTER TABLE</command></link>.
+ <command>ALTER INDEX</command> is in fact just an alias for the forms
+ of <command>ALTER TABLE</command> that apply to indexes.
+ </para>
+
+ <para>
+ There was formerly an <command>ALTER INDEX OWNER</command> variant, but
+ this is now ignored (with a warning). An index cannot have an owner
+ different from its table's owner. Changing the table's owner
+ automatically changes the index as well.
+ </para>
+
+ <para>
+ Changing any part of a system catalog index is not permitted.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ To rename an existing index:
+<programlisting>
+ALTER INDEX distributors RENAME TO suppliers;
+</programlisting>
+ </para>
+
+ <para>
+ To move an index to a different tablespace:
+<programlisting>
+ALTER INDEX distributors SET TABLESPACE fasttablespace;
+</programlisting>
+ </para>
+
+ <para>
+ To change an index's fill factor (assuming that the index method
+ supports it):
+<programlisting>
+ALTER INDEX distributors SET (fillfactor = 75);
+REINDEX INDEX distributors;
+</programlisting></para>
+
+ <para>
+ Set the statistics-gathering target for an expression index:
+<programlisting>
+CREATE INDEX coord_idx ON measured (x, y, (z + t));
+ALTER INDEX coord_idx ALTER COLUMN 3 SET STATISTICS 1000;
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER INDEX</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createindex"/></member>
+ <member><xref linkend="sql-reindex"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_language.sgml b/doc/src/sgml/ref/alter_language.sgml
new file mode 100644
index 0000000..0b61c18
--- /dev/null
+++ b/doc/src/sgml/ref/alter_language.sgml
@@ -0,0 +1,91 @@
+<!--
+doc/src/sgml/ref/alter_language.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterlanguage">
+ <indexterm zone="sql-alterlanguage">
+ <primary>ALTER LANGUAGE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER LANGUAGE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER LANGUAGE</refname>
+ <refpurpose>change the definition of a procedural language</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER [ PROCEDURAL ] LANGUAGE <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER LANGUAGE</command> changes the definition of a
+ procedural language. The only functionality is to rename the language or
+ assign a new owner. You must be superuser or owner of the language to
+ use <command>ALTER LANGUAGE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a language
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the language
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the language
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER LANGUAGE</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createlanguage"/></member>
+ <member><xref linkend="sql-droplanguage"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_large_object.sgml b/doc/src/sgml/ref/alter_large_object.sgml
new file mode 100644
index 0000000..17ea149
--- /dev/null
+++ b/doc/src/sgml/ref/alter_large_object.sgml
@@ -0,0 +1,86 @@
+<!--
+doc/src/sgml/ref/alter_large_object.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterlargeobject">
+ <indexterm zone="sql-alterlargeobject">
+ <primary>ALTER LARGE OBJECT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER LARGE OBJECT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER LARGE OBJECT</refname>
+ <refpurpose>change the definition of a large object</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER LARGE OBJECT <replaceable class="parameter">large_object_oid</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER LARGE OBJECT</command> changes the definition of a
+ large object.
+ </para>
+
+ <para>
+ You must own the large object to use <command>ALTER LARGE OBJECT</command>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role. (However, a superuser can alter any large object anyway.)
+ Currently, the only functionality is to assign a new owner, so both
+ restrictions always apply.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>large_object_oid</replaceable></term>
+ <listitem>
+ <para>
+ OID of the large object to be altered
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the large object
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER LARGE OBJECT</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="largeobjects"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_materialized_view.sgml b/doc/src/sgml/ref/alter_materialized_view.sgml
new file mode 100644
index 0000000..cae135c
--- /dev/null
+++ b/doc/src/sgml/ref/alter_materialized_view.sgml
@@ -0,0 +1,186 @@
+<!--
+doc/src/sgml/ref/alter_materialized_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altermaterializedview">
+ <indexterm zone="sql-altermaterializedview">
+ <primary>ALTER MATERIALIZED VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER MATERIALIZED VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER MATERIALIZED VIEW</refname>
+ <refpurpose>change the definition of a materialized view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ <replaceable class="parameter">action</replaceable> [, ... ]
+ALTER MATERIALIZED VIEW <replaceable class="parameter">name</replaceable>
+ [ NO ] DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ RENAME [ COLUMN ] <replaceable class="parameter">column_name</replaceable> TO <replaceable class="parameter">new_column_name</replaceable>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+ALTER MATERIALIZED VIEW ALL IN TABLESPACE <replaceable class="parameter">name</replaceable> [ OWNED BY <replaceable class="parameter">role_name</replaceable> [, ... ] ]
+ SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> [ NOWAIT ]
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STATISTICS <replaceable class="parameter">integer</replaceable>
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET COMPRESSION <replaceable class="parameter">compression_method</replaceable>
+ CLUSTER ON <replaceable class="parameter">index_name</replaceable>
+ SET WITHOUT CLUSTER
+ SET ACCESS METHOD <replaceable class="parameter">new_access_method</replaceable>
+ SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable>
+ SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
+ RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )
+ OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER MATERIALIZED VIEW</command> changes various auxiliary
+ properties of an existing materialized view.
+ </para>
+
+ <para>
+ You must own the materialized view to use <command>ALTER MATERIALIZED
+ VIEW</command>. To change a materialized view's schema, you must also have
+ <literal>CREATE</literal> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the materialized view's schema. (These restrictions enforce that altering
+ the owner doesn't do anything you couldn't do by dropping and recreating the
+ materialized view. However, a superuser can alter ownership of any view
+ anyway.)
+ </para>
+
+ <para>
+ The statement subforms and actions available for
+ <command>ALTER MATERIALIZED VIEW</command> are a subset of those available
+ for <command>ALTER TABLE</command>, and have the same meaning when used for
+ materialized views. See the descriptions for
+ <link linkend="sql-altertable"><command>ALTER TABLE</command></link>
+ for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing materialized view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a new or existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">extension_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the extension that the materialized view is to depend on (or no longer
+ dependent on, if <literal>NO</literal> is specified). A materialized view
+ that's marked as dependent on an extension is automatically dropped when
+ the extension is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_column_name</replaceable></term>
+ <listitem>
+ <para>
+ New name for an existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the materialized view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the materialized view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the materialized view.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the materialized view <literal>foo</literal> to
+ <literal>bar</literal>:
+<programlisting>
+ALTER MATERIALIZED VIEW foo RENAME TO bar;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER MATERIALIZED VIEW</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-creatematerializedview"/></member>
+ <member><xref linkend="sql-dropmaterializedview"/></member>
+ <member><xref linkend="sql-refreshmaterializedview"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_opclass.sgml b/doc/src/sgml/ref/alter_opclass.sgml
new file mode 100644
index 0000000..b1db459
--- /dev/null
+++ b/doc/src/sgml/ref/alter_opclass.sgml
@@ -0,0 +1,124 @@
+<!--
+doc/src/sgml/ref/alter_opclass.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alteropclass">
+ <indexterm zone="sql-alteropclass">
+ <primary>ALTER OPERATOR CLASS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER OPERATOR CLASS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER OPERATOR CLASS</refname>
+ <refpurpose>change the definition of an operator class</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+ RENAME TO <replaceable>new_name</replaceable>
+
+ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+ SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER OPERATOR CLASS</command> changes the definition of
+ an operator class.
+ </para>
+
+ <para>
+ You must own the operator class to use <command>ALTER OPERATOR CLASS</command>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the operator class's schema. (These restrictions enforce that altering the
+ owner doesn't do anything you couldn't do by dropping and recreating the
+ operator class. However, a superuser can alter ownership of any operator
+ class anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing operator
+ class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index method this operator class is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER OPERATOR CLASS</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-dropopclass"/></member>
+ <member><xref linkend="sql-alteropfamily"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_operator.sgml b/doc/src/sgml/ref/alter_operator.sgml
new file mode 100644
index 0000000..ad90c13
--- /dev/null
+++ b/doc/src/sgml/ref/alter_operator.sgml
@@ -0,0 +1,160 @@
+<!--
+doc/src/sgml/ref/alter_operator.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alteroperator">
+ <indexterm zone="sql-alteroperator">
+ <primary>ALTER OPERATOR</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER OPERATOR</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER OPERATOR</refname>
+ <refpurpose>change the definition of an operator</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , <replaceable>right_type</replaceable> )
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , <replaceable>right_type</replaceable> )
+ SET SCHEMA <replaceable>new_schema</replaceable>
+
+ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , <replaceable>right_type</replaceable> )
+ SET ( { RESTRICT = { <replaceable class="parameter">res_proc</replaceable> | NONE }
+ | JOIN = { <replaceable class="parameter">join_proc</replaceable> | NONE }
+ } [, ... ] )
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER OPERATOR</command> changes the definition of
+ an operator.
+ </para>
+
+ <para>
+ You must own the operator to use <command>ALTER OPERATOR</command>.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the operator's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the operator.
+ However, a superuser can alter ownership of any operator anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">left_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the operator's left operand; write
+ <literal>NONE</literal> if the operator has no left operand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">right_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the operator's right operand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">res_proc</replaceable></term>
+ <listitem>
+ <para>
+ The restriction selectivity estimator function for this operator; write NONE to remove existing selectivity estimator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">join_proc</replaceable></term>
+ <listitem>
+ <para>
+ The join selectivity estimator function for this operator; write NONE to remove existing selectivity estimator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change the owner of a custom operator <literal>a @@ b</literal> for type <type>text</type>:
+<programlisting>
+ALTER OPERATOR @@ (text, text) OWNER TO joe;
+</programlisting></para>
+
+ <para>
+ Change the restriction and join selectivity estimator functions of a custom operator <literal>a &amp;&amp; b</literal> for type <type>int[]</type>:
+<programlisting>
+ALTER OPERATOR &amp;&amp; (_int4, _int4) SET (RESTRICT = _int_contsel, JOIN = _int_contjoinsel);
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER OPERATOR</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createoperator"/></member>
+ <member><xref linkend="sql-dropoperator"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml
new file mode 100644
index 0000000..b2e5b9b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_opfamily.sgml
@@ -0,0 +1,360 @@
+<!--
+doc/src/sgml/ref/alter_opfamily.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alteropfamily">
+ <indexterm zone="sql-alteropfamily">
+ <primary>ALTER OPERATOR FAMILY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER OPERATOR FAMILY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER OPERATOR FAMILY</refname>
+ <refpurpose>change the definition of an operator family</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> ADD
+ { OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> )
+ [ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ]
+ | FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ]
+ <replaceable class="parameter">function_name</replaceable> [ ( <replaceable class="parameter">argument_type</replaceable> [, ...] ) ]
+ } [, ... ]
+
+ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> DROP
+ { OPERATOR <replaceable class="parameter">strategy_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] )
+ | FUNCTION <replaceable class="parameter">support_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] )
+ } [, ... ]
+
+ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+ RENAME TO <replaceable>new_name</replaceable>
+
+ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+
+ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+ SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER OPERATOR FAMILY</command> changes the definition of
+ an operator family. You can add operators and support functions
+ to the family, remove them from the family,
+ or change the family's name or owner.
+ </para>
+
+ <para>
+ When operators and support functions are added to a family with
+ <command>ALTER OPERATOR FAMILY</command>, they are not part of any
+ specific operator class within the family, but are just <quote>loose</quote>
+ within the family. This indicates that these operators and functions
+ are compatible with the family's semantics, but are not required for
+ correct functioning of any specific index. (Operators and functions
+ that are so required should be declared as part of an operator class,
+ instead; see <xref linkend="sql-createopclass"/>.)
+ <productname>PostgreSQL</productname> will allow loose members of a
+ family to be dropped from the family at any time, but members of an
+ operator class cannot be dropped without dropping the whole class and
+ any indexes that depend on it.
+ Typically, single-data-type operators
+ and functions are part of operator classes because they are needed to
+ support an index on that specific data type, while cross-data-type
+ operators and functions are made loose members of the family.
+ </para>
+
+ <para>
+ You must be a superuser to use <command>ALTER OPERATOR FAMILY</command>.
+ (This restriction is made because an erroneous operator family definition
+ could confuse or even crash the server.)
+ </para>
+
+ <para>
+ <command>ALTER OPERATOR FAMILY</command> does not presently check
+ whether the operator family definition includes all the operators and
+ functions required by the index method, nor whether the operators and
+ functions form a self-consistent set. It is the user's
+ responsibility to define a valid operator family.
+ </para>
+
+ <para>
+ Refer to <xref linkend="xindex"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing operator
+ family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index method this operator family is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">strategy_number</replaceable></term>
+ <listitem>
+ <para>
+ The index method's strategy number for an operator
+ associated with the operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">operator_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an operator associated
+ with the operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">op_type</replaceable></term>
+ <listitem>
+ <para>
+ In an <literal>OPERATOR</literal> clause,
+ the operand data type(s) of the operator, or <literal>NONE</literal> to
+ signify a prefix operator. Unlike the comparable
+ syntax in <command>CREATE OPERATOR CLASS</command>, the operand data types
+ must always be specified.
+ </para>
+
+ <para>
+ In an <literal>ADD FUNCTION</literal> clause, the operand data type(s) the
+ function is intended to support, if different from
+ the input data type(s) of the function. For B-tree comparison functions
+ and hash functions it is not necessary to specify <replaceable
+ class="parameter">op_type</replaceable> since the function's input
+ data type(s) are always the correct ones to use. For B-tree sort
+ support functions, B-Tree equal image functions, and all
+ functions in GiST, SP-GiST and GIN operator classes, it is
+ necessary to specify the operand data type(s) the function is to
+ be used with.
+ </para>
+
+ <para>
+ In a <literal>DROP FUNCTION</literal> clause, the operand data type(s) the
+ function is intended to support must be specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sort_family_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing <literal>btree</literal> operator
+ family that describes the sort ordering associated with an ordering
+ operator.
+ </para>
+
+ <para>
+ If neither <literal>FOR SEARCH</literal> nor <literal>FOR ORDER BY</literal> is
+ specified, <literal>FOR SEARCH</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">support_number</replaceable></term>
+ <listitem>
+ <para>
+ The index method's support function number for a
+ function associated with the operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a function that is an index
+ method support function for the operator family. If no argument list
+ is specified, the name must be unique in its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argument_type</replaceable></term>
+ <listitem>
+ <para>
+ The parameter data type(s) of the function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The <literal>OPERATOR</literal> and <literal>FUNCTION</literal>
+ clauses can appear in any order.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Notice that the <literal>DROP</literal> syntax only specifies the <quote>slot</quote>
+ in the operator family, by strategy or support number and input data
+ type(s). The name of the operator or function occupying the slot is not
+ mentioned. Also, for <literal>DROP FUNCTION</literal> the type(s) to specify
+ are the input data type(s) the function is intended to support; for
+ GiST, SP-GiST and GIN indexes this might have nothing to do with the actual
+ input argument types of the function.
+ </para>
+
+ <para>
+ Because the index machinery does not check access permissions on functions
+ before using them, including a function or operator in an operator family
+ is tantamount to granting public execute permission on it. This is usually
+ not an issue for the sorts of functions that are useful in an operator
+ family.
+ </para>
+
+ <para>
+ The operators should not be defined by SQL functions. An SQL function
+ is likely to be inlined into the calling query, which will prevent
+ the optimizer from recognizing that the query matches an index.
+ </para>
+
+ <para>
+ Before <productname>PostgreSQL</productname> 8.4, the <literal>OPERATOR</literal>
+ clause could include a <literal>RECHECK</literal> option. This is no longer
+ supported because whether an index operator is <quote>lossy</quote> is now
+ determined on-the-fly at run time. This allows efficient handling of
+ cases where an operator might or might not be lossy.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example command adds cross-data-type operators and
+ support functions to an operator family that already contains B-tree
+ operator classes for data types <type>int4</type> and <type>int2</type>.
+ </para>
+
+<programlisting>
+ALTER OPERATOR FAMILY integer_ops USING btree ADD
+
+ -- int4 vs int2
+ OPERATOR 1 &lt; (int4, int2) ,
+ OPERATOR 2 &lt;= (int4, int2) ,
+ OPERATOR 3 = (int4, int2) ,
+ OPERATOR 4 &gt;= (int4, int2) ,
+ OPERATOR 5 &gt; (int4, int2) ,
+ FUNCTION 1 btint42cmp(int4, int2) ,
+
+ -- int2 vs int4
+ OPERATOR 1 &lt; (int2, int4) ,
+ OPERATOR 2 &lt;= (int2, int4) ,
+ OPERATOR 3 = (int2, int4) ,
+ OPERATOR 4 &gt;= (int2, int4) ,
+ OPERATOR 5 &gt; (int2, int4) ,
+ FUNCTION 1 btint24cmp(int2, int4) ;
+</programlisting>
+
+ <para>
+ To remove these entries again:
+ </para>
+
+<programlisting>
+ALTER OPERATOR FAMILY integer_ops USING btree DROP
+
+ -- int4 vs int2
+ OPERATOR 1 (int4, int2) ,
+ OPERATOR 2 (int4, int2) ,
+ OPERATOR 3 (int4, int2) ,
+ OPERATOR 4 (int4, int2) ,
+ OPERATOR 5 (int4, int2) ,
+ FUNCTION 1 (int4, int2) ,
+
+ -- int2 vs int4
+ OPERATOR 1 (int2, int4) ,
+ OPERATOR 2 (int2, int4) ,
+ OPERATOR 3 (int2, int4) ,
+ OPERATOR 4 (int2, int4) ,
+ OPERATOR 5 (int2, int4) ,
+ FUNCTION 1 (int2, int4) ;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER OPERATOR FAMILY</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createopfamily"/></member>
+ <member><xref linkend="sql-dropopfamily"/></member>
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-alteropclass"/></member>
+ <member><xref linkend="sql-dropopclass"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_policy.sgml b/doc/src/sgml/ref/alter_policy.sgml
new file mode 100644
index 0000000..fbc262b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_policy.sgml
@@ -0,0 +1,143 @@
+<!--
+doc/src/sgml/ref/alter_policy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterpolicy">
+ <indexterm zone="sql-alterpolicy">
+ <primary>ALTER POLICY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER POLICY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER POLICY</refname>
+ <refpurpose>change the definition of a row-level security policy</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER POLICY <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+
+ALTER POLICY <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable>
+ [ TO { <replaceable class="parameter">role_name</replaceable> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
+ [ USING ( <replaceable class="parameter">using_expression</replaceable> ) ]
+ [ WITH CHECK ( <replaceable class="parameter">check_expression</replaceable> ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER POLICY</command> changes the definition of an existing
+ row-level security policy. Note that <command>ALTER POLICY</command>
+ only allows the set of roles to which the policy applies and the
+ <literal>USING</literal> and <literal>WITH CHECK</literal> expressions to
+ be modified. To change other properties of a policy, such as the command
+ to which it applies or whether it is permissive or restrictive, the policy
+ must be dropped and recreated.
+ </para>
+
+ <para>
+ To use <command>ALTER POLICY</command>, you must own the table that
+ the policy applies to.
+ </para>
+
+ <para>
+ In the second form of <command>ALTER POLICY</command>, the role list,
+ <replaceable class="parameter">using_expression</replaceable>, and
+ <replaceable class="parameter">check_expression</replaceable> are replaced
+ independently if specified. When one of those clauses is omitted, the
+ corresponding part of the policy is unchanged.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing policy to alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table that the
+ policy is on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the policy.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The role(s) to which the policy applies. Multiple roles can be
+ specified at one time. To apply the policy to all roles,
+ use <literal>PUBLIC</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">using_expression</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>USING</literal> expression for the policy.
+ See <xref linkend="sql-createpolicy"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">check_expression</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>WITH CHECK</literal> expression for the policy.
+ See <xref linkend="sql-createpolicy"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER POLICY</command> is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createpolicy"/></member>
+ <member><xref linkend="sql-droppolicy"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_procedure.sgml b/doc/src/sgml/ref/alter_procedure.sgml
new file mode 100644
index 0000000..20a6238
--- /dev/null
+++ b/doc/src/sgml/ref/alter_procedure.sgml
@@ -0,0 +1,289 @@
+<!--
+doc/src/sgml/ref/alter_procedure.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterprocedure">
+ <indexterm zone="sql-alterprocedure">
+ <primary>ALTER PROCEDURE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER PROCEDURE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER PROCEDURE</refname>
+ <refpurpose>change the definition of a procedure</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER PROCEDURE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ <replaceable class="parameter">action</replaceable> [ ... ] [ RESTRICT ]
+ALTER PROCEDURE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ RENAME TO <replaceable>new_name</replaceable>
+ALTER PROCEDURE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER PROCEDURE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ SET SCHEMA <replaceable>new_schema</replaceable>
+ALTER PROCEDURE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION <replaceable>extension_name</replaceable>
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
+ SET <replaceable class="parameter">configuration_parameter</replaceable> FROM CURRENT
+ RESET <replaceable class="parameter">configuration_parameter</replaceable>
+ RESET ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER PROCEDURE</command> changes the definition of a
+ procedure.
+ </para>
+
+ <para>
+ You must own the procedure to use <command>ALTER PROCEDURE</command>.
+ To change a procedure's schema, you must also have <literal>CREATE</literal>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the procedure's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the procedure.
+ However, a superuser can alter ownership of any procedure anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing procedure. If no
+ argument list is specified, the name must be unique in its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>. If omitted,
+ the default is <literal>IN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ Note that <command>ALTER PROCEDURE</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are used to determine the procedure's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type(s) of the procedure's arguments (optionally
+ schema-qualified), if any.
+ See <xref linkend="sql-dropprocedure"/> for the details of how
+ the procedure is looked up using the argument data type(s).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the procedure. Note that if the procedure is
+ marked <literal>SECURITY DEFINER</literal>, it will subsequently
+ execute as the new owner.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">extension_name</replaceable></term>
+ <listitem>
+ <para>
+ This form marks the procedure as dependent on the extension, or no longer
+ dependent on the extension if <literal>NO</literal> is specified.
+ A procedure that's marked as dependent on an extension is dropped when the
+ extension is dropped, even if cascade is not specified.
+ A procedure can depend upon multiple extensions, and will be dropped when
+ any one of those extensions is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><optional> EXTERNAL </optional> SECURITY INVOKER</literal></term>
+ <term><literal><optional> EXTERNAL </optional> SECURITY DEFINER</literal></term>
+
+ <listitem>
+ <para>
+ Change whether the procedure is a security definer or not. The
+ key word <literal>EXTERNAL</literal> is ignored for SQL
+ conformance. See <xref linkend="sql-createprocedure"/> for more information about
+ this capability.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>configuration_parameter</replaceable></term>
+ <term><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ Add or change the assignment to be made to a configuration parameter
+ when the procedure is called. If
+ <replaceable>value</replaceable> is <literal>DEFAULT</literal>
+ or, equivalently, <literal>RESET</literal> is used, the procedure-local
+ setting is removed, so that the procedure executes with the value
+ present in its environment. Use <literal>RESET
+ ALL</literal> to clear all procedure-local settings.
+ <literal>SET FROM CURRENT</literal> saves the value of the parameter that
+ is current when <command>ALTER PROCEDURE</command> is executed as the value
+ to be applied when the procedure is entered.
+ </para>
+
+ <para>
+ See <xref linkend="sql-set"/> and
+ <xref linkend="runtime-config"/>
+ for more information about allowed parameter names and values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ Ignored for conformance with the SQL standard.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the procedure <literal>insert_data</literal> with two arguments
+ of type <type>integer</type> to <literal>insert_record</literal>:
+<programlisting>
+ALTER PROCEDURE insert_data(integer, integer) RENAME TO insert_record;
+</programlisting>
+ </para>
+
+ <para>
+ To change the owner of the procedure <literal>insert_data</literal> with
+ two arguments of type <type>integer</type> to <literal>joe</literal>:
+<programlisting>
+ALTER PROCEDURE insert_data(integer, integer) OWNER TO joe;
+</programlisting>
+ </para>
+
+ <para>
+ To change the schema of the procedure <literal>insert_data</literal> with
+ two arguments of type <type>integer</type>
+ to <literal>accounting</literal>:
+<programlisting>
+ALTER PROCEDURE insert_data(integer, integer) SET SCHEMA accounting;
+</programlisting>
+ </para>
+
+ <para>
+ To mark the procedure <literal>insert_data(integer, integer)</literal> as
+ being dependent on the extension <literal>myext</literal>:
+<programlisting>
+ALTER PROCEDURE insert_data(integer, integer) DEPENDS ON EXTENSION myext;
+</programlisting>
+ </para>
+
+ <para>
+ To adjust the search path that is automatically set for a procedure:
+<programlisting>
+ALTER PROCEDURE check_password(text) SET search_path = admin, pg_temp;
+</programlisting>
+ </para>
+
+ <para>
+ To disable automatic setting of <varname>search_path</varname> for a procedure:
+<programlisting>
+ALTER PROCEDURE check_password(text) RESET search_path;
+</programlisting>
+ The procedure will now execute with whatever search path is used by its
+ caller.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This statement is partially compatible with the <command>ALTER
+ PROCEDURE</command> statement in the SQL standard. The standard allows more
+ properties of a procedure to be modified, but does not provide the
+ ability to rename a procedure, make a procedure a security definer,
+ attach configuration parameter values to a procedure,
+ or change the owner, schema, or volatility of a procedure. The standard also
+ requires the <literal>RESTRICT</literal> key word, which is optional in
+ <productname>PostgreSQL</productname>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createprocedure"/></member>
+ <member><xref linkend="sql-dropprocedure"/></member>
+ <member><xref linkend="sql-alterfunction"/></member>
+ <member><xref linkend="sql-alterroutine"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_publication.sgml b/doc/src/sgml/ref/alter_publication.sgml
new file mode 100644
index 0000000..c84b11f
--- /dev/null
+++ b/doc/src/sgml/ref/alter_publication.sgml
@@ -0,0 +1,235 @@
+<!--
+doc/src/sgml/ref/alter_publication.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterpublication">
+ <indexterm zone="sql-alterpublication">
+ <primary>ALTER PUBLICATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER PUBLICATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER PUBLICATION</refname>
+ <refpurpose>change the definition of a publication</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER PUBLICATION <replaceable class="parameter">name</replaceable> ADD <replaceable class="parameter">publication_object</replaceable> [, ...]
+ALTER PUBLICATION <replaceable class="parameter">name</replaceable> SET <replaceable class="parameter">publication_object</replaceable> [, ...]
+ALTER PUBLICATION <replaceable class="parameter">name</replaceable> DROP <replaceable class="parameter">publication_object</replaceable> [, ...]
+ALTER PUBLICATION <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
+ALTER PUBLICATION <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER PUBLICATION <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+
+<phrase>where <replaceable class="parameter">publication_object</replaceable> is one of:</phrase>
+
+ TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] [ WHERE ( <replaceable class="parameter">expression</replaceable> ) ] [, ... ]
+ TABLES IN SCHEMA { <replaceable class="parameter">schema_name</replaceable> | CURRENT_SCHEMA } [, ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The command <command>ALTER PUBLICATION</command> can change the attributes
+ of a publication.
+ </para>
+
+ <para>
+ The first three variants change which tables/schemas are part of the
+ publication. The <literal>SET</literal> clause will replace the list of
+ tables/schemas in the publication with the specified list; the existing
+ tables/schemas that were present in the publication will be removed. The
+ <literal>ADD</literal> and <literal>DROP</literal> clauses will add and
+ remove one or more tables/schemas from the publication. Note that adding
+ tables/schemas to a publication that is already subscribed to will require an
+ <literal>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</literal> action on the
+ subscribing side in order to become effective. Note also that
+ <literal>DROP TABLES IN SCHEMA</literal> will not drop any schema tables
+ that were specified using <literal>FOR TABLE</literal>/
+ <literal>ADD TABLE</literal>, and the combination of <literal>DROP</literal>
+ with a <literal>WHERE</literal> clause is not allowed.
+ </para>
+
+ <para>
+ The fourth variant of this command listed in the synopsis can change
+ all of the publication properties specified in
+ <xref linkend="sql-createpublication"/>. Properties not mentioned in the
+ command retain their previous settings.
+ </para>
+
+ <para>
+ The remaining variants change the owner and the name of the publication.
+ </para>
+
+ <para>
+ You must own the publication to use <command>ALTER PUBLICATION</command>.
+ Adding a table to a publication additionally requires owning that table.
+ The <literal>ADD TABLES IN SCHEMA</literal> and
+ <literal>SET TABLES IN SCHEMA</literal> to a publication requires the
+ invoking user to be a superuser. To alter the owner, you must also be a
+ direct or indirect member of the new owning role. The new owner must have
+ <literal>CREATE</literal> privilege on the database. Also, the new owner
+ of a <literal>FOR ALL TABLES</literal> or <literal>FOR TABLES IN SCHEMA</literal>
+ publication must be a superuser. However, a superuser can
+ change the ownership of a publication regardless of these restrictions.
+ </para>
+
+ <para>
+ Adding/Setting any schema when the publication also publishes a table with a
+ column list, and vice versa is not supported.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing publication whose definition is to be altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of an existing table. If <literal>ONLY</literal> is specified before the
+ table name, only that table is affected. If <literal>ONLY</literal> is not
+ specified, the table and all its descendant tables (if any) are
+ affected. Optionally, <literal>*</literal> can be specified after the table
+ name to explicitly indicate that descendant tables are included.
+ </para>
+
+ <para>
+ Optionally, a column list can be specified. See <xref
+ linkend="sql-createpublication"/> for details. Note that a subscription
+ having several publications in which the same table has been published
+ with different column lists is not supported. See
+ <xref linkend="logical-replication-col-list-combining"/> for details of
+ potential problems when altering column lists.
+ </para>
+
+ <para>
+ If the optional <literal>WHERE</literal> clause is specified, rows for
+ which the <replaceable class="parameter">expression</replaceable>
+ evaluates to false or null will not be published. Note that parentheses
+ are required around the expression. The
+ <replaceable class="parameter">expression</replaceable> is evaluated with
+ the role used for the replication connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">schema_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of an existing schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause alters publication parameters originally set by
+ <xref linkend="sql-createpublication"/>. See there for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the publication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the publication.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change the publication to publish only deletes and updates:
+<programlisting>
+ALTER PUBLICATION noinsert SET (publish = 'update, delete');
+</programlisting>
+ </para>
+
+ <para>
+ Add some tables to the publication:
+<programlisting>
+ALTER PUBLICATION mypublication ADD TABLE users (user_id, firstname), departments;
+</programlisting></para>
+
+ <para>
+ Change the set of columns published for a table:
+<programlisting>
+ALTER PUBLICATION mypublication SET TABLE users (user_id, firstname, lastname), TABLE departments;
+</programlisting></para>
+
+ <para>
+ Add schemas <structname>marketing</structname> and
+ <structname>sales</structname> to the publication
+ <structname>sales_publication</structname>:
+<programlisting>
+ALTER PUBLICATION sales_publication ADD TABLES IN SCHEMA marketing, sales;
+</programlisting>
+ </para>
+
+ <para>
+ Add tables <structname>users</structname>,
+ <structname>departments</structname> and schema
+ <structname>production</structname> to the publication
+ <structname>production_publication</structname>:
+<programlisting>
+ALTER PUBLICATION production_publication ADD TABLE users, departments, TABLES IN SCHEMA production;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER PUBLICATION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createpublication"/></member>
+ <member><xref linkend="sql-droppublication"/></member>
+ <member><xref linkend="sql-createsubscription"/></member>
+ <member><xref linkend="sql-altersubscription"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml
new file mode 100644
index 0000000..922686e
--- /dev/null
+++ b/doc/src/sgml/ref/alter_role.sgml
@@ -0,0 +1,354 @@
+<!--
+doc/src/sgml/ref/alter_role.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterrole">
+ <indexterm zone="sql-alterrole">
+ <primary>ALTER ROLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER ROLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER ROLE</refname>
+ <refpurpose>change a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER ROLE <replaceable class="parameter">role_specification</replaceable> [ WITH ] <replaceable class="parameter">option</replaceable> [ ... ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <replaceable class="parameter">connlimit</replaceable>
+ | [ ENCRYPTED ] PASSWORD '<replaceable class="parameter">password</replaceable>' | PASSWORD NULL
+ | VALID UNTIL '<replaceable class="parameter">timestamp</replaceable>'
+
+ALTER ROLE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+
+ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
+ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
+ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
+ALTER ROLE { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
+
+<phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase>
+
+ <replaceable class="parameter">role_name</replaceable>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER ROLE</command> changes the attributes of a
+ <productname>PostgreSQL</productname> role.
+ </para>
+
+ <para>
+ The first variant of this command listed in the synopsis can change
+ many of the role attributes that can be specified in
+ <link linkend="sql-createrole"><command>CREATE ROLE</command></link>.
+ (All the possible attributes are covered,
+ except that there are no options for adding or removing memberships; use
+ <link linkend="sql-grant"><command>GRANT</command></link> and
+ <link linkend="sql-revoke"><command>REVOKE</command></link> for that.)
+ Attributes not mentioned in the command retain their previous settings.
+ Database superusers can change any of these settings for any role.
+ Roles having <literal>CREATEROLE</literal> privilege can change any of these
+ settings except <literal>SUPERUSER</literal>, <literal>REPLICATION</literal>,
+ and <literal>BYPASSRLS</literal>; but only for non-superuser and
+ non-replication roles.
+ Ordinary roles can only change their own password.
+ </para>
+
+ <para>
+ The second variant changes the name of the role.
+ Database superusers can rename any role.
+ Roles having <literal>CREATEROLE</literal> privilege can rename non-superuser
+ roles.
+ The current session user cannot be renamed.
+ (Connect as a different user if you need to do that.)
+ Because <literal>MD5</literal>-encrypted passwords use the role name as
+ cryptographic salt, renaming a role clears its password if the
+ password is <literal>MD5</literal>-encrypted.
+ </para>
+
+ <para>
+ The remaining variants change a role's session default for a configuration
+ variable, either for all databases or, when the <literal>IN
+ DATABASE</literal> clause is specified, only for sessions in the named
+ database. If <literal>ALL</literal> is specified instead of a role name,
+ this changes the setting for all roles. Using <literal>ALL</literal>
+ with <literal>IN DATABASE</literal> is effectively the same as using the
+ command <literal>ALTER DATABASE ... SET ...</literal>.
+ </para>
+
+ <para>
+ Whenever the role subsequently
+ starts a new session, the specified value becomes the session
+ default, overriding whatever setting is present in
+ <filename>postgresql.conf</filename> or has been received from the <command>postgres</command>
+ command line. This only happens at login time; executing
+ <link linkend="sql-set-role"><command>SET ROLE</command></link> or
+ <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link> does not cause new
+ configuration values to be set.
+ Settings set for all databases are overridden by database-specific settings
+ attached to a role. Settings for specific databases or specific roles override
+ settings for all roles.
+ </para>
+
+ <para>
+ Superusers can change anyone's session defaults. Roles having
+ <literal>CREATEROLE</literal> privilege can change defaults for non-superuser
+ roles. Ordinary roles can only set defaults for themselves.
+ Certain configuration variables cannot be set this way, or can only be
+ set if a superuser issues the command. Only superusers can change a setting
+ for all roles in all databases.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the role whose attributes are to be altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CURRENT_ROLE</literal></term>
+ <term><literal>CURRENT_USER</literal></term>
+ <listitem>
+ <para>
+ Alter the current user instead of an explicitly identified role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SESSION_USER</literal></term>
+ <listitem>
+ <para>
+ Alter the current session user instead of an explicitly identified
+ role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SUPERUSER</literal></term>
+ <term><literal>NOSUPERUSER</literal></term>
+ <term><literal>CREATEDB</literal></term>
+ <term><literal>NOCREATEDB</literal></term>
+ <term><literal>CREATEROLE</literal></term>
+ <term><literal>NOCREATEROLE</literal></term>
+ <term><literal>INHERIT</literal></term>
+ <term><literal>NOINHERIT</literal></term>
+ <term><literal>LOGIN</literal></term>
+ <term><literal>NOLOGIN</literal></term>
+ <term><literal>REPLICATION</literal></term>
+ <term><literal>NOREPLICATION</literal></term>
+ <term><literal>BYPASSRLS</literal></term>
+ <term><literal>NOBYPASSRLS</literal></term>
+ <term><literal>CONNECTION LIMIT</literal> <replaceable class="parameter">connlimit</replaceable></term>
+ <term>[ <literal>ENCRYPTED</literal> ] <literal>PASSWORD</literal> '<replaceable class="parameter">password</replaceable>'</term>
+ <term><literal>PASSWORD NULL</literal></term>
+ <term><literal>VALID UNTIL</literal> '<replaceable class="parameter">timestamp</replaceable>'</term>
+ <listitem>
+ <para>
+ These clauses alter attributes originally set by
+ <link linkend="sql-createrole"><command>CREATE ROLE</command></link>. For more information, see the
+ <command>CREATE ROLE</command> reference page.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>database_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the database the configuration variable should be set in.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>configuration_parameter</replaceable></term>
+ <term><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ Set this role's session default for the specified configuration
+ parameter to the given value. If
+ <replaceable>value</replaceable> is <literal>DEFAULT</literal>
+ or, equivalently, <literal>RESET</literal> is used, the
+ role-specific variable setting is removed, so the role will
+ inherit the system-wide default setting in new sessions. Use
+ <literal>RESET ALL</literal> to clear all role-specific settings.
+ <literal>SET FROM CURRENT</literal> saves the session's current value of
+ the parameter as the role-specific value.
+ If <literal>IN DATABASE</literal> is specified, the configuration
+ parameter is set or removed for the given role and database only.
+ </para>
+
+ <para>
+ Role-specific variable settings take effect only at login;
+ <link linkend="sql-set-role"><command>SET ROLE</command></link> and
+ <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>
+ do not process role-specific variable settings.
+ </para>
+
+ <para>
+ See <xref linkend="sql-set"/> and <xref
+ linkend="runtime-config"/> for more information about allowed
+ parameter names and values.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-createrole"><command>CREATE ROLE</command></link>
+ to add new roles, and <link linkend="sql-droprole"><command>DROP ROLE</command></link> to remove a role.
+ </para>
+
+ <para>
+ <command>ALTER ROLE</command> cannot change a role's memberships.
+ Use <link linkend="sql-grant"><command>GRANT</command></link> and
+ <link linkend="sql-revoke"><command>REVOKE</command></link>
+ to do that.
+ </para>
+
+ <para>
+ Caution must be exercised when specifying an unencrypted password
+ with this command. The password will be transmitted to the server
+ in cleartext, and it might also be logged in the client's command
+ history or the server log. <xref linkend="app-psql"/>
+ contains a command
+ <command>\password</command> that can be used to change a
+ role's password without exposing the cleartext password.
+ </para>
+
+ <para>
+ It is also possible to tie a
+ session default to a specific database rather than to a role; see
+ <xref linkend="sql-alterdatabase"/>.
+ If there is a conflict, database-role-specific settings override role-specific
+ ones, which in turn override database-specific ones.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change a role's password:
+
+<programlisting>
+ALTER ROLE davide WITH PASSWORD 'hu8jmn3';
+</programlisting>
+ </para>
+
+ <para>
+ Remove a role's password:
+
+<programlisting>
+ALTER ROLE davide WITH PASSWORD NULL;
+</programlisting>
+ </para>
+
+ <para>
+ Change a password expiration date, specifying that the password
+ should expire at midday on 4th May 2015 using
+ the time zone which is one hour ahead of <acronym>UTC</acronym>:
+<programlisting>
+ALTER ROLE chris VALID UNTIL 'May 4 12:00:00 2015 +1';
+</programlisting>
+ </para>
+
+ <para>
+ Make a password valid forever:
+<programlisting>
+ALTER ROLE fred VALID UNTIL 'infinity';
+</programlisting>
+ </para>
+
+ <para>
+ Give a role the ability to manage other roles and create new databases:
+
+<programlisting>
+ALTER ROLE miriam CREATEROLE CREATEDB;
+</programlisting>
+ </para>
+
+ <para>
+ Give a role a non-default setting of the
+ <xref linkend="guc-maintenance-work-mem"/> parameter:
+
+<programlisting>
+ALTER ROLE worker_bee SET maintenance_work_mem = 100000;
+</programlisting>
+ </para>
+
+ <para>
+ Give a role a non-default, database-specific setting of the
+ <xref linkend="guc-client-min-messages"/> parameter:
+
+<programlisting>
+ALTER ROLE fred IN DATABASE devel SET client_min_messages = DEBUG;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>ALTER ROLE</command> statement is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createrole"/></member>
+ <member><xref linkend="sql-droprole"/></member>
+ <member><xref linkend="sql-alterdatabase"/></member>
+ <member><xref linkend="sql-set"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_routine.sgml b/doc/src/sgml/ref/alter_routine.sgml
new file mode 100644
index 0000000..d6c9dea
--- /dev/null
+++ b/doc/src/sgml/ref/alter_routine.sgml
@@ -0,0 +1,103 @@
+<!--
+doc/src/sgml/ref/alter_routine.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterroutine">
+ <indexterm zone="sql-alterroutine">
+ <primary>ALTER ROUTINE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER ROUTINE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER ROUTINE</refname>
+ <refpurpose>change the definition of a routine</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER ROUTINE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ <replaceable class="parameter">action</replaceable> [ ... ] [ RESTRICT ]
+ALTER ROUTINE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ RENAME TO <replaceable>new_name</replaceable>
+ALTER ROUTINE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER ROUTINE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ SET SCHEMA <replaceable>new_schema</replaceable>
+ALTER ROUTINE <replaceable>name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ]
+ [ NO ] DEPENDS ON EXTENSION <replaceable>extension_name</replaceable>
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ IMMUTABLE | STABLE | VOLATILE
+ [ NOT ] LEAKPROOF
+ [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ COST <replaceable class="parameter">execution_cost</replaceable>
+ ROWS <replaceable class="parameter">result_rows</replaceable>
+ SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | DEFAULT }
+ SET <replaceable class="parameter">configuration_parameter</replaceable> FROM CURRENT
+ RESET <replaceable class="parameter">configuration_parameter</replaceable>
+ RESET ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER ROUTINE</command> changes the definition of a routine, which
+ can be an aggregate function, a normal function, or a procedure. See
+ under <xref linkend="sql-alteraggregate"/>, <xref linkend="sql-alterfunction"/>,
+ and <xref linkend="sql-alterprocedure"/> for the description of the
+ parameters, more examples, and further details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the routine <literal>foo</literal> for type
+ <type>integer</type> to <literal>foobar</literal>:
+<programlisting>
+ALTER ROUTINE foo(integer) RENAME TO foobar;
+</programlisting>
+ This command will work independent of whether <literal>foo</literal> is an
+ aggregate, function, or procedure.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This statement is partially compatible with the <command>ALTER
+ ROUTINE</command> statement in the SQL standard. See
+ under <xref linkend="sql-alterfunction"/>
+ and <xref linkend="sql-alterprocedure"/> for more details. Allowing
+ routine names to refer to aggregate functions is
+ a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteraggregate"/></member>
+ <member><xref linkend="sql-alterfunction"/></member>
+ <member><xref linkend="sql-alterprocedure"/></member>
+ <member><xref linkend="sql-droproutine"/></member>
+ </simplelist>
+
+ <para>
+ Note that there is no <literal>CREATE ROUTINE</literal> command.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_rule.sgml b/doc/src/sgml/ref/alter_rule.sgml
new file mode 100644
index 0000000..c20bfb3
--- /dev/null
+++ b/doc/src/sgml/ref/alter_rule.sgml
@@ -0,0 +1,105 @@
+<!--
+doc/src/sgml/ref/alter_rule.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterrule">
+ <indexterm zone="sql-alterrule">
+ <primary>ALTER RULE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER RULE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER RULE</refname>
+ <refpurpose>change the definition of a rule</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER RULE <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER RULE</command> changes properties of an existing
+ rule. Currently, the only available action is to change the rule's name.
+ </para>
+
+ <para>
+ To use <command>ALTER RULE</command>, you must own the table or view that
+ the rule applies to.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing rule to alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table or view that the
+ rule applies to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the rule.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename an existing rule:
+<programlisting>
+ALTER RULE notify_all ON emp RENAME TO notify_me;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER RULE</command> is a
+ <productname>PostgreSQL</productname> language extension, as is the
+ entire query rewrite system.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createrule"/></member>
+ <member><xref linkend="sql-droprule"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_schema.sgml b/doc/src/sgml/ref/alter_schema.sgml
new file mode 100644
index 0000000..04624c5
--- /dev/null
+++ b/doc/src/sgml/ref/alter_schema.sgml
@@ -0,0 +1,100 @@
+<!--
+doc/src/sgml/ref/alter_schema.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterschema">
+ <indexterm zone="sql-alterschema">
+ <primary>ALTER SCHEMA</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER SCHEMA</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER SCHEMA</refname>
+ <refpurpose>change the definition of a schema</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER SCHEMA <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER SCHEMA <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER SCHEMA</command> changes the definition of a schema.
+ </para>
+
+ <para>
+ You must own the schema to use <command>ALTER SCHEMA</command>.
+ To rename a schema you must also have the
+ <literal>CREATE</literal> privilege for the database.
+ To alter the owner, you must also be a direct or
+ indirect member of the new owning role, and you must have the
+ <literal>CREATE</literal> privilege for the database.
+ (Note that superusers have all these privileges automatically.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the schema. The new name cannot
+ begin with <literal>pg_</literal>, as such names
+ are reserved for system schemas.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the schema.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER SCHEMA</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createschema"/></member>
+ <member><xref linkend="sql-dropschema"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_sequence.sgml b/doc/src/sgml/ref/alter_sequence.sgml
new file mode 100644
index 0000000..148085d
--- /dev/null
+++ b/doc/src/sgml/ref/alter_sequence.sgml
@@ -0,0 +1,363 @@
+<!--
+doc/src/sgml/ref/alter_sequence.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altersequence">
+ <indexterm zone="sql-altersequence">
+ <primary>ALTER SEQUENCE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER SEQUENCE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER SEQUENCE</refname>
+ <refpurpose>
+ change the definition of a sequence generator
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ [ AS <replaceable class="parameter">data_type</replaceable> ]
+ [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
+ [ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
+ [ START [ WITH ] <replaceable class="parameter">start</replaceable> ]
+ [ RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] ]
+ [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
+ [ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ]
+ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET { LOGGED | UNLOGGED }
+ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER SEQUENCE</command> changes the parameters of an existing
+ sequence generator. Any parameters not specifically set in the
+ <command>ALTER SEQUENCE</command> command retain their prior settings.
+ </para>
+
+ <para>
+ You must own the sequence to use <command>ALTER SEQUENCE</command>.
+ To change a sequence's schema, you must also have <literal>CREATE</literal>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the sequence's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the sequence.
+ However, a superuser can alter ownership of any sequence anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a sequence to be altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the sequence does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The optional
+ clause <literal>AS <replaceable class="parameter">data_type</replaceable></literal>
+ changes the data type of the sequence. Valid types are
+ <literal>smallint</literal>, <literal>integer</literal>,
+ and <literal>bigint</literal>.
+ </para>
+
+ <para>
+ Changing the data type automatically changes the minimum and maximum
+ values of the sequence if and only if the previous minimum and maximum
+ values were the minimum or maximum value of the old data type (in
+ other words, if the sequence had been created using <literal>NO
+ MINVALUE</literal> or <literal>NO MAXVALUE</literal>, implicitly or
+ explicitly). Otherwise, the minimum and maximum values are preserved,
+ unless new values are given as part of the same command. If the
+ minimum and maximum values do not fit into the new data type, an error
+ will be generated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">increment</replaceable></term>
+ <listitem>
+ <para>
+ The clause <literal>INCREMENT BY <replaceable
+ class="parameter">increment</replaceable></literal> is
+ optional. A positive value will make an ascending sequence, a
+ negative one a descending sequence. If unspecified, the old
+ increment value will be maintained.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">minvalue</replaceable></term>
+ <term><literal>NO MINVALUE</literal></term>
+ <listitem>
+ <para>
+ The optional clause <literal>MINVALUE <replaceable
+ class="parameter">minvalue</replaceable></literal> determines
+ the minimum value a sequence can generate. If <literal>NO
+ MINVALUE</literal> is specified, the defaults of 1 and
+ the minimum value of the data type for ascending and descending sequences,
+ respectively, will be used. If neither option is specified,
+ the current minimum value will be maintained.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">maxvalue</replaceable></term>
+ <term><literal>NO MAXVALUE</literal></term>
+ <listitem>
+ <para>
+ The optional clause <literal>MAXVALUE <replaceable
+ class="parameter">maxvalue</replaceable></literal> determines
+ the maximum value for the sequence. If <literal>NO
+ MAXVALUE</literal> is specified, the defaults of
+ the maximum value of the data type and -1 for ascending and descending
+ sequences, respectively, will be used. If neither option is
+ specified, the current maximum value will be maintained.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">start</replaceable></term>
+ <listitem>
+ <para>
+ The optional clause <literal>START WITH <replaceable
+ class="parameter">start</replaceable></literal> changes the
+ recorded start value of the sequence. This has no effect on the
+ <emphasis>current</emphasis> sequence value; it simply sets the value
+ that future <command>ALTER SEQUENCE RESTART</command> commands will use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">restart</replaceable></term>
+ <listitem>
+ <para>
+ The optional clause <literal>RESTART [ WITH <replaceable
+ class="parameter">restart</replaceable> ]</literal> changes the
+ current value of the sequence. This is similar to calling the
+ <function>setval</function> function with <literal>is_called</literal> =
+ <literal>false</literal>: the specified value will be returned by the
+ <emphasis>next</emphasis> call of <function>nextval</function>.
+ Writing <literal>RESTART</literal> with no <replaceable
+ class="parameter">restart</replaceable> value is equivalent to supplying
+ the start value that was recorded by <command>CREATE SEQUENCE</command>
+ or last set by <command>ALTER SEQUENCE START WITH</command>.
+ </para>
+
+ <para>
+ In contrast to a <function>setval</function> call,
+ a <literal>RESTART</literal> operation on a sequence is transactional
+ and blocks concurrent transactions from obtaining numbers from the
+ same sequence. If that's not the desired mode of
+ operation, <function>setval</function> should be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cache</replaceable></term>
+ <listitem>
+ <para>
+ The clause <literal>CACHE <replaceable
+ class="parameter">cache</replaceable></literal> enables
+ sequence numbers to be preallocated and stored in memory for
+ faster access. The minimum value is 1 (only one value can be
+ generated at a time, i.e., no cache). If unspecified, the old
+ cache value will be maintained.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYCLE</literal></term>
+ <listitem>
+ <para>
+ The optional <literal>CYCLE</literal> key word can be used to enable
+ the sequence to wrap around when the
+ <replaceable class="parameter">maxvalue</replaceable> or
+ <replaceable class="parameter">minvalue</replaceable> has been
+ reached by
+ an ascending or descending sequence respectively. If the limit is
+ reached, the next number generated will be the
+ <replaceable class="parameter">minvalue</replaceable> or
+ <replaceable class="parameter">maxvalue</replaceable>,
+ respectively.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NO CYCLE</literal></term>
+ <listitem>
+ <para>
+ If the optional <literal>NO CYCLE</literal> key word is
+ specified, any calls to <function>nextval</function> after the
+ sequence has reached its maximum value will return an error.
+ If neither <literal>CYCLE</literal> or <literal>NO
+ CYCLE</literal> are specified, the old cycle behavior will be
+ maintained.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET { LOGGED | UNLOGGED }</literal></term>
+ <listitem>
+ <para>
+ This form changes the sequence from unlogged to logged or vice-versa
+ (see <xref linkend="sql-createsequence"/>). It cannot be applied to a
+ temporary sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OWNED BY</literal> <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable></term>
+ <term><literal>OWNED BY NONE</literal></term>
+ <listitem>
+ <para>
+ The <literal>OWNED BY</literal> option causes the sequence to be
+ associated with a specific table column, such that if that column
+ (or its whole table) is dropped, the sequence will be automatically
+ dropped as well. If specified, this association replaces any
+ previously specified association for the sequence. The specified
+ table must have the same owner and be in the same schema as the
+ sequence.
+ Specifying <literal>OWNED BY NONE</literal> removes any existing
+ association, making the sequence <quote>free-standing</quote>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>ALTER SEQUENCE</command> will not immediately affect
+ <function>nextval</function> results in backends,
+ other than the current one, that have preallocated (cached) sequence
+ values. They will use up all cached values prior to noticing the changed
+ sequence generation parameters. The current backend will be affected
+ immediately.
+ </para>
+
+ <para>
+ <command>ALTER SEQUENCE</command> does not affect the <function>currval</function>
+ status for the sequence. (Before <productname>PostgreSQL</productname>
+ 8.3, it sometimes did.)
+ </para>
+
+ <para>
+ <command>ALTER SEQUENCE</command> blocks
+ concurrent <function>nextval</function>, <function>currval</function>,
+ <function>lastval</function>, and <command>setval</command> calls.
+ </para>
+
+ <para>
+ For historical reasons, <command>ALTER TABLE</command> can be used with
+ sequences too; but the only variants of <command>ALTER TABLE</command>
+ that are allowed with sequences are equivalent to the forms shown above.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Restart a sequence called <literal>serial</literal>, at 105:
+<programlisting>
+ALTER SEQUENCE serial RESTART WITH 105;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER SEQUENCE</command> conforms to the <acronym>SQL</acronym>
+ standard, except for the <literal>AS</literal>, <literal>START WITH</literal>,
+ <literal>OWNED BY</literal>, <literal>OWNER TO</literal>, <literal>RENAME TO</literal>, and
+ <literal>SET SCHEMA</literal> clauses, which are
+ <productname>PostgreSQL</productname> extensions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createsequence"/></member>
+ <member><xref linkend="sql-dropsequence"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_server.sgml b/doc/src/sgml/ref/alter_server.sgml
new file mode 100644
index 0000000..186f38b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_server.sgml
@@ -0,0 +1,144 @@
+<!--
+doc/src/sgml/ref/alter_server.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterserver">
+ <indexterm zone="sql-alterserver">
+ <primary>ALTER SERVER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER SERVER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER SERVER</refname>
+ <refpurpose>change the definition of a foreign server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER SERVER <replaceable class="parameter">name</replaceable> [ VERSION '<replaceable class="parameter">new_version</replaceable>' ]
+ [ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] ) ]
+ALTER SERVER <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SERVER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER SERVER</command> changes the definition of a foreign
+ server. The first form changes the server version string or the
+ generic options of the server (at least one clause is required).
+ The second form changes the owner of the server.
+ </para>
+
+ <para>
+ To alter the server you must be the owner of the server.
+ Additionally to alter the owner, you must own the server and also
+ be a direct or indirect member of the new owning role, and you must
+ have <literal>USAGE</literal> privilege on the server's foreign-data
+ wrapper. (Note that superusers satisfy all these criteria
+ automatically.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_version</replaceable></term>
+ <listitem>
+ <para>
+ New server version.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ Change options for the
+ server. <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
+ specify the action to be performed. <literal>ADD</literal> is assumed
+ if no operation is explicitly specified. Option names must be
+ unique; names and values are also validated using the server's
+ foreign-data wrapper library.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the foreign server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the foreign server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Alter server <literal>foo</literal>, add connection options:
+<programlisting>
+ALTER SERVER foo OPTIONS (host 'foo', dbname 'foodb');
+</programlisting>
+ </para>
+
+ <para>
+ Alter server <literal>foo</literal>, change version,
+ change <literal>host</literal> option:
+<programlisting>
+ALTER SERVER foo VERSION '8.4' OPTIONS (SET host 'baz');
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER SERVER</command> conforms to ISO/IEC 9075-9 (SQL/MED).
+ The <literal>OWNER TO</literal> and <literal>RENAME</literal> forms are
+ PostgreSQL extensions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createserver"/></member>
+ <member><xref linkend="sql-dropserver"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_statistics.sgml b/doc/src/sgml/ref/alter_statistics.sgml
new file mode 100644
index 0000000..ce6cdf2
--- /dev/null
+++ b/doc/src/sgml/ref/alter_statistics.sgml
@@ -0,0 +1,135 @@
+<!--
+doc/src/sgml/ref/alter_statistics.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterstatistics">
+ <indexterm zone="sql-alterstatistics">
+ <primary>ALTER STATISTICS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER STATISTICS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER STATISTICS</refname>
+ <refpurpose>
+ change the definition of an extended statistics object
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER STATISTICS <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER STATISTICS <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+ALTER STATISTICS <replaceable class="parameter">name</replaceable> SET STATISTICS <replaceable class="parameter">new_target</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER STATISTICS</command> changes the parameters of an existing
+ extended statistics object. Any parameters not specifically set in the
+ <command>ALTER STATISTICS</command> command retain their prior settings.
+ </para>
+
+ <para>
+ You must own the statistics object to use <command>ALTER STATISTICS</command>.
+ To change a statistics object's schema, you must also
+ have <literal>CREATE</literal> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the statistics object's schema. (These restrictions enforce that altering
+ the owner doesn't do anything you couldn't do by dropping and recreating
+ the statistics object. However, a superuser can alter ownership of any
+ statistics object anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the statistics object to be
+ altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the statistics object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the statistics object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the statistics object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_target</replaceable></term>
+ <listitem>
+ <para>
+ The statistic-gathering target for this statistics object for subsequent
+ <link linkend="sql-analyze"><command>ANALYZE</command></link> operations.
+ The target can be set in the range 0 to 10000; alternatively, set it
+ to -1 to revert to using the maximum of the statistics target of the
+ referenced columns, if set, or the system default statistics
+ target (<xref linkend="guc-default-statistics-target"/>).
+ For more information on the use of statistics by the
+ <productname>PostgreSQL</productname> query planner, refer to
+ <xref linkend="planner-stats"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER STATISTICS</command> command in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createstatistics"/></member>
+ <member><xref linkend="sql-dropstatistics"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_subscription.sgml b/doc/src/sgml/ref/alter_subscription.sgml
new file mode 100644
index 0000000..353ea5d
--- /dev/null
+++ b/doc/src/sgml/ref/alter_subscription.sgml
@@ -0,0 +1,313 @@
+<!--
+doc/src/sgml/ref/alter_subscription.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altersubscription">
+ <indexterm zone="sql-altersubscription">
+ <primary>ALTER SUBSCRIPTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER SUBSCRIPTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER SUBSCRIPTION</refname>
+ <refpurpose>change the definition of a subscription</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> CONNECTION '<replaceable>conninfo</replaceable>'
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> SET PUBLICATION <replaceable class="parameter">publication_name</replaceable> [, ...] [ WITH ( <replaceable class="parameter">publication_option</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> ADD PUBLICATION <replaceable class="parameter">publication_name</replaceable> [, ...] [ WITH ( <replaceable class="parameter">publication_option</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> DROP PUBLICATION <replaceable class="parameter">publication_name</replaceable> [, ...] [ WITH ( <replaceable class="parameter">publication_option</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> REFRESH PUBLICATION [ WITH ( <replaceable class="parameter">refresh_option</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> ENABLE
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> DISABLE
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> SKIP ( <replaceable class="parameter">skip_option</replaceable> = <replaceable class="parameter">value</replaceable> )
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER SUBSCRIPTION <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER SUBSCRIPTION</command> can change most of the subscription
+ properties that can be specified
+ in <xref linkend="sql-createsubscription"/>.
+ </para>
+
+ <para>
+ You must own the subscription to use <command>ALTER SUBSCRIPTION</command>.
+ To alter the owner, you must also be a direct or indirect member of the
+ new owning role. The new owner has to be a superuser.
+ (Currently, all subscription owners must be superusers, so the owner checks
+ will be bypassed in practice. But this might change in the future.)
+ </para>
+
+ <para>
+ When refreshing a publication we remove the relations that are no longer
+ part of the publication and we also remove the table synchronization slots
+ if there are any. It is necessary to remove these slots so that the resources
+ allocated for the subscription on the remote host are released. If due to
+ network breakdown or some other error, <productname>PostgreSQL</productname>
+ is unable to remove the slots, an error will be reported. To proceed in this
+ situation, the user either needs to retry the operation or disassociate the
+ slot from the subscription and drop the subscription as explained in
+ <xref linkend="sql-dropsubscription"/>.
+ </para>
+
+ <para>
+ Commands <command>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</command> and
+ <command>ALTER SUBSCRIPTION ... {SET|ADD|DROP} PUBLICATION ...</command>
+ with <literal>refresh</literal> option as <literal>true</literal> cannot be
+ executed inside a transaction block.
+
+ These commands also cannot be executed when the subscription has
+ <literal>two_phase</literal> commit enabled,
+ unless <literal>copy_data</literal> is <literal>false</literal>.
+ See column <structfield>subtwophasestate</structfield> of
+ <link linkend="catalog-pg-subscription"><structname>pg_subscription</structname></link>
+ to know the actual two-phase state.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a subscription whose properties are to be altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
+ <listitem>
+ <para>
+ This clause replaces the connection string originally set by
+ <xref linkend="sql-createsubscription"/>. See there for more
+ information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
+ <term><literal>ADD PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
+ <term><literal>DROP PUBLICATION <replaceable class="parameter">publication_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ These forms change the list of subscribed publications.
+ <literal>SET</literal>
+ replaces the entire list of publications with a new list,
+ <literal>ADD</literal> adds additional publications to the list of
+ publications, and <literal>DROP</literal> removes the publications from
+ the list of publications. We allow non-existent publications to be
+ specified in <literal>ADD</literal> and <literal>SET</literal> variants
+ so that users can add those later. See <xref linkend="sql-createsubscription"/>
+ for more information. By default, this command will also act like
+ <literal>REFRESH PUBLICATION</literal>.
+ </para>
+
+ <para>
+ <replaceable>publication_option</replaceable> specifies additional
+ options for this operation. The supported options are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>refresh</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ When false, the command will not try to refresh table information.
+ <literal>REFRESH PUBLICATION</literal> should then be executed separately.
+ The default is <literal>true</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Additionally, the options described under
+ <literal>REFRESH PUBLICATION</literal> may be specified, to control the
+ implicit refresh operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REFRESH PUBLICATION</literal></term>
+ <listitem>
+ <para>
+ Fetch missing table information from publisher. This will start
+ replication of tables that were added to the subscribed-to publications
+ since <command>CREATE SUBSCRIPTION</command> or
+ the last invocation of <command>REFRESH PUBLICATION</command>.
+ </para>
+
+ <para>
+ <replaceable>refresh_option</replaceable> specifies additional options for the
+ refresh operation. The supported options are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>copy_data</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether to copy pre-existing data in the publications
+ that are being subscribed to when the replication starts.
+ The default is <literal>true</literal>.
+ </para>
+ <para>
+ Previously subscribed tables are not copied, even if a table's row
+ filter <literal>WHERE</literal> clause has since been modified.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ENABLE</literal></term>
+ <listitem>
+ <para>
+ Enables a previously disabled subscription, starting the logical
+ replication worker at the end of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE</literal></term>
+ <listitem>
+ <para>
+ Disables a running subscription, stopping the logical replication
+ worker at the end of the transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause alters parameters originally set by
+ <xref linkend="sql-createsubscription"/>. See there for more
+ information. The parameters that can be altered
+ are <literal>slot_name</literal>,
+ <literal>synchronous_commit</literal>,
+ <literal>binary</literal>, <literal>streaming</literal>, and
+ <literal>disable_on_error</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SKIP ( <replaceable class="parameter">skip_option</replaceable> = <replaceable class="parameter">value</replaceable> )</literal></term>
+ <listitem>
+ <para>
+ Skips applying all changes of the remote transaction. If incoming data
+ violates any constraints, logical replication will stop until it is
+ resolved. By using the <command>ALTER SUBSCRIPTION ... SKIP</command> command,
+ the logical replication worker skips all data modification changes within
+ the transaction. This option has no effect on the transactions that are
+ already prepared by enabling <literal>two_phase</literal> on
+ subscriber.
+ After the logical replication worker successfully skips the transaction or
+ finishes a transaction, the LSN (stored in
+ <structname>pg_subscription</structname>.<structfield>subskiplsn</structfield>)
+ is cleared. See <xref linkend="logical-replication-conflicts"/> for
+ the details of logical replication conflicts. Using this command requires
+ superuser privilege.
+ </para>
+
+ <para>
+ <replaceable>skip_option</replaceable> specifies options for this operation.
+ The supported option is:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>lsn</literal> (<type>pg_lsn</type>)</term>
+ <listitem>
+ <para>
+ Specifies the finish LSN of the remote transaction whose changes
+ are to be skipped by the logical replication worker. The finish LSN
+ is the LSN at which the transaction is either committed or prepared.
+ Skipping individual subtransactions is not supported. Setting
+ <literal>NONE</literal> resets the LSN.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the subscription.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the subscription.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change the publication subscribed by a subscription to
+ <literal>insert_only</literal>:
+<programlisting>
+ALTER SUBSCRIPTION mysub SET PUBLICATION insert_only;
+</programlisting>
+ </para>
+
+ <para>
+ Disable (stop) the subscription:
+<programlisting>
+ALTER SUBSCRIPTION mysub DISABLE;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER SUBSCRIPTION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createsubscription"/></member>
+ <member><xref linkend="sql-dropsubscription"/></member>
+ <member><xref linkend="sql-createpublication"/></member>
+ <member><xref linkend="sql-alterpublication"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_system.sgml b/doc/src/sgml/ref/alter_system.sgml
new file mode 100644
index 0000000..6f8bd39
--- /dev/null
+++ b/doc/src/sgml/ref/alter_system.sgml
@@ -0,0 +1,144 @@
+<!--
+doc/src/sgml/ref/alter_system.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altersystem">
+ <indexterm zone="sql-altersystem">
+ <primary>ALTER SYSTEM</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER SYSTEM</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER SYSTEM</refname>
+ <refpurpose>change a server configuration parameter</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER SYSTEM SET <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | '<replaceable class="parameter">value</replaceable>' | DEFAULT }
+
+ALTER SYSTEM RESET <replaceable class="parameter">configuration_parameter</replaceable>
+ALTER SYSTEM RESET ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER SYSTEM</command> is used for changing server configuration
+ parameters across the entire database cluster. It can be more convenient
+ than the traditional method of manually editing
+ the <filename>postgresql.conf</filename> file.
+ <command>ALTER SYSTEM</command> writes the given parameter setting to
+ the <filename>postgresql.auto.conf</filename> file, which is read in
+ addition to <filename>postgresql.conf</filename>.
+ Setting a parameter to <literal>DEFAULT</literal>, or using the
+ <command>RESET</command> variant, removes that configuration entry from the
+ <filename>postgresql.auto.conf</filename> file. Use <literal>RESET
+ ALL</literal> to remove all such configuration entries.
+ </para>
+
+ <para>
+ Values set with <command>ALTER SYSTEM</command> will be effective after
+ the next server configuration reload, or after the next server restart
+ in the case of parameters that can only be changed at server start.
+ A server configuration reload can be commanded by calling the SQL
+ function <function>pg_reload_conf()</function>, running <literal>pg_ctl reload</literal>,
+ or sending a <systemitem>SIGHUP</systemitem> signal to the main server process.
+ </para>
+
+ <para>
+ Only superusers and users granted <literal>ALTER SYSTEM</literal> privilege
+ on a parameter can change it using <command>ALTER SYSTEM</command>. Also, since
+ this command acts directly on the file system and cannot be rolled back,
+ it is not allowed inside a transaction block or function.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">configuration_parameter</replaceable></term>
+ <listitem>
+ <para>
+ Name of a settable configuration parameter. Available parameters are
+ documented in <xref linkend="runtime-config"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ New value of the parameter. Values can be specified as string
+ constants, identifiers, numbers, or comma-separated lists of
+ these, as appropriate for the particular parameter.
+ <literal>DEFAULT</literal> can be written to specify removing the
+ parameter and its value from <filename>postgresql.auto.conf</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ This command can't be used to set <xref linkend="guc-data-directory"/>,
+ nor parameters that are not allowed in <filename>postgresql.conf</filename>
+ (e.g., <link linkend="runtime-config-preset">preset options</link>).
+ </para>
+
+ <para>
+ See <xref linkend="config-setting"/> for other ways to set the parameters.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Set the <literal>wal_level</literal>:
+<programlisting>
+ALTER SYSTEM SET wal_level = replica;
+</programlisting>
+ </para>
+
+ <para>
+ Undo that, restoring whatever setting was effective
+ in <filename>postgresql.conf</filename>:
+<programlisting>
+ALTER SYSTEM RESET wal_level;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>ALTER SYSTEM</command> statement is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-set"/></member>
+ <member><xref linkend="sql-show"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
new file mode 100644
index 0000000..6fd8faf
--- /dev/null
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -0,0 +1,1785 @@
+<!--
+doc/src/sgml/ref/alter_table.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertable">
+ <indexterm zone="sql-altertable">
+ <primary>ALTER TABLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TABLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TABLE</refname>
+ <refpurpose>change the definition of a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
+ <replaceable class="parameter">action</replaceable> [, ... ]
+ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
+ RENAME [ COLUMN ] <replaceable class="parameter">column_name</replaceable> TO <replaceable class="parameter">new_column_name</replaceable>
+ALTER TABLE [ IF EXISTS ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ]
+ RENAME CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> TO <replaceable class="parameter">new_constraint_name</replaceable>
+ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+ALTER TABLE ALL IN TABLESPACE <replaceable class="parameter">name</replaceable> [ OWNED BY <replaceable class="parameter">role_name</replaceable> [, ... ] ]
+ SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> [ NOWAIT ]
+ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
+ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+ DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ ADD [ COLUMN ] [ IF NOT EXISTS ] <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ DROP [ COLUMN ] [ IF EXISTS ] <replaceable class="parameter">column_name</replaceable> [ RESTRICT | CASCADE ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> [ SET DATA ] TYPE <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ USING <replaceable class="parameter">expression</replaceable> ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET DEFAULT <replaceable class="parameter">expression</replaceable>
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP DEFAULT
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> { SET | DROP } NOT NULL
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP EXPRESSION [ IF EXISTS ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> { SET GENERATED { ALWAYS | BY DEFAULT } | SET <replaceable>sequence_option</replaceable> | RESTART [ [ WITH ] <replaceable class="parameter">restart</replaceable> ] } [...]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP IDENTITY [ IF EXISTS ]
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STATISTICS <replaceable class="parameter">integer</replaceable>
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
+ ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET COMPRESSION <replaceable class="parameter">compression_method</replaceable>
+ ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]
+ ADD <replaceable class="parameter">table_constraint_using_index</replaceable>
+ ALTER CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+ VALIDATE CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
+ DROP CONSTRAINT [ IF EXISTS ] <replaceable class="parameter">constraint_name</replaceable> [ RESTRICT | CASCADE ]
+ DISABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
+ ENABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
+ ENABLE REPLICA TRIGGER <replaceable class="parameter">trigger_name</replaceable>
+ ENABLE ALWAYS TRIGGER <replaceable class="parameter">trigger_name</replaceable>
+ DISABLE RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
+ ENABLE RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
+ ENABLE REPLICA RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
+ ENABLE ALWAYS RULE <replaceable class="parameter">rewrite_rule_name</replaceable>
+ DISABLE ROW LEVEL SECURITY
+ ENABLE ROW LEVEL SECURITY
+ FORCE ROW LEVEL SECURITY
+ NO FORCE ROW LEVEL SECURITY
+ CLUSTER ON <replaceable class="parameter">index_name</replaceable>
+ SET WITHOUT CLUSTER
+ SET WITHOUT OIDS
+ SET ACCESS METHOD <replaceable class="parameter">new_access_method</replaceable>
+ SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable>
+ SET { LOGGED | UNLOGGED }
+ SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )
+ RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )
+ INHERIT <replaceable class="parameter">parent_table</replaceable>
+ NO INHERIT <replaceable class="parameter">parent_table</replaceable>
+ OF <replaceable class="parameter">type_name</replaceable>
+ NOT OF
+ OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ REPLICA IDENTITY { DEFAULT | USING INDEX <replaceable class="parameter">index_name</replaceable> | FULL | NOTHING }
+
+<phrase>and <replaceable class="parameter">partition_bound_spec</replaceable> is:</phrase>
+
+IN ( <replaceable class="parameter">partition_bound_expr</replaceable> [, ...] ) |
+FROM ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] )
+ TO ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] ) |
+WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REMAINDER <replaceable class="parameter">numeric_literal</replaceable> )
+
+<phrase>and <replaceable class="parameter">column_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+{ NOT NULL |
+ NULL |
+ CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
+ DEFAULT <replaceable>default_expr</replaceable> |
+ GENERATED ALWAYS AS ( <replaceable>generation_expr</replaceable> ) STORED |
+ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] <replaceable class="parameter">index_parameters</replaceable> |
+ PRIMARY KEY <replaceable class="parameter">index_parameters</replaceable> |
+ REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+ [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<phrase>and <replaceable class="parameter">table_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+{ CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> |
+ PRIMARY KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> |
+ EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ] |
+ FOREIGN KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> [, ... ] ) ]
+ [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<phrase>and <replaceable class="parameter">table_constraint_using_index</replaceable> is:</phrase>
+
+ [ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+ { UNIQUE | PRIMARY KEY } USING INDEX <replaceable class="parameter">index_name</replaceable>
+ [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<phrase><replaceable class="parameter">index_parameters</replaceable> in <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>, and <literal>EXCLUDE</literal> constraints are:</phrase>
+
+[ INCLUDE ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+[ USING INDEX TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+
+<phrase><replaceable class="parameter">exclude_element</replaceable> in an <literal>EXCLUDE</literal> constraint is:</phrase>
+
+{ <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
+
+<phrase><replaceable class="parameter">referential_action</replaceable> in a <literal>FOREIGN KEY</literal>/<literal>REFERENCES</literal> constraint is:</phrase>
+
+{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] | SET DEFAULT [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TABLE</command> changes the definition of an existing table.
+ There are several subforms described below. Note that the lock level required
+ may differ for each subform. An <literal>ACCESS EXCLUSIVE</literal> lock is
+ acquired unless explicitly noted. When multiple subcommands are given, the
+ lock acquired will be the strictest one required by any subcommand.
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ADD COLUMN [ IF NOT EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form adds a new column to the table, using the same syntax as
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link>. If <literal>IF NOT EXISTS</literal>
+ is specified and a column already exists with this name,
+ no error is thrown.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP COLUMN [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form drops a column from a table. Indexes and
+ table constraints involving the column will be automatically
+ dropped as well.
+ Multivariate statistics referencing the dropped column will also be
+ removed if the removal of the column would cause the statistics to
+ contain data for only a single column.
+ You will need to say <literal>CASCADE</literal> if anything outside the table
+ depends on the column, for example, foreign key references or views.
+ If <literal>IF EXISTS</literal> is specified and the column
+ does not exist, no error is thrown. In this case a notice
+ is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET DATA TYPE</literal></term>
+ <listitem>
+ <para>
+ This form changes the type of a column of a table. Indexes and
+ simple table constraints involving the column will be automatically
+ converted to use the new column type by reparsing the originally
+ supplied expression.
+ The optional <literal>COLLATE</literal> clause specifies a collation
+ for the new column; if omitted, the collation is the default for the
+ new column type.
+ The optional <literal>USING</literal>
+ clause specifies how to compute the new column value from the old;
+ if omitted, the default conversion is the same as an assignment
+ cast from old data type to new. A <literal>USING</literal>
+ clause must be provided if there is no implicit or assignment
+ cast from old to new type.
+ </para>
+
+ <para>
+ When this form is used, the column's statistics are removed,
+ so running <link linkend="sql-analyze"><command>ANALYZE</command></link>
+ on the table afterwards is recommended.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP DEFAULT</literal></term>
+ <listitem>
+ <para>
+ These forms set or remove the default value for a column (where
+ removal is equivalent to setting the default value to NULL). The new
+ default value will only apply in subsequent <command>INSERT</command>
+ or <command>UPDATE</command> commands; it does not cause rows already
+ in the table to change.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP NOT NULL</literal></term>
+ <listitem>
+ <para>
+ These forms change whether a column is marked to allow null
+ values or to reject null values.
+ </para>
+
+ <para>
+ <literal>SET NOT NULL</literal> may only be applied to a column
+ provided none of the records in the table contain a
+ <literal>NULL</literal> value for the column. Ordinarily this is
+ checked during the <literal>ALTER TABLE</literal> by scanning the
+ entire table; however, if a valid <literal>CHECK</literal> constraint is
+ found which proves no <literal>NULL</literal> can exist, then the
+ table scan is skipped.
+ </para>
+
+ <para>
+ If this table is a partition, one cannot perform <literal>DROP NOT NULL</literal>
+ on a column if it is marked <literal>NOT NULL</literal> in the parent
+ table. To drop the <literal>NOT NULL</literal> constraint from all the
+ partitions, perform <literal>DROP NOT NULL</literal> on the parent
+ table. Even if there is no <literal>NOT NULL</literal> constraint on the
+ parent, such a constraint can still be added to individual partitions,
+ if desired; that is, the children can disallow nulls even if the parent
+ allows them, but not the other way around.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP EXPRESSION [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form turns a stored generated column into a normal base column.
+ Existing data in the columns is retained, but future changes will no
+ longer apply the generation expression.
+ </para>
+
+ <para>
+ If <literal>DROP EXPRESSION IF EXISTS</literal> is specified and the
+ column is not a stored generated column, no error is thrown. In this
+ case a notice is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY</literal></term>
+ <term><literal>SET GENERATED { ALWAYS | BY DEFAULT }</literal></term>
+ <term><literal>DROP IDENTITY [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ These forms change whether a column is an identity column or change the
+ generation attribute of an existing identity column.
+ See <link linkend="sql-createtable"><command>CREATE TABLE</command></link> for details.
+ Like <literal>SET DEFAULT</literal>, these forms only affect the
+ behavior of subsequent <command>INSERT</command>
+ and <command>UPDATE</command> commands; they do not cause rows
+ already in the table to change.
+ </para>
+
+ <para>
+ If <literal>DROP IDENTITY IF EXISTS</literal> is specified and the
+ column is not an identity column, no error is thrown. In this case a
+ notice is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET <replaceable>sequence_option</replaceable></literal></term>
+ <term><literal>RESTART</literal></term>
+ <listitem>
+ <para>
+ These forms alter the sequence that underlies an existing identity
+ column. <replaceable>sequence_option</replaceable> is an option
+ supported by <link linkend="sql-altersequence"><command>ALTER SEQUENCE</command></link> such
+ as <literal>INCREMENT BY</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET STATISTICS</literal></term>
+ <listitem>
+ <para>
+ This form
+ sets the per-column statistics-gathering target for subsequent
+ <link linkend="sql-analyze"><command>ANALYZE</command></link> operations.
+ The target can be set in the range 0 to 10000; alternatively, set it
+ to -1 to revert to using the system default statistics
+ target (<xref linkend="guc-default-statistics-target"/>).
+ For more information on the use of statistics by the
+ <productname>PostgreSQL</productname> query planner, refer to
+ <xref linkend="planner-stats"/>.
+ </para>
+ <para>
+ <literal>SET STATISTICS</literal> acquires a
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">attribute_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )</literal></term>
+ <term><literal>RESET ( <replaceable class="parameter">attribute_option</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This form sets or resets per-attribute options. Currently, the only
+ defined per-attribute options are <literal>n_distinct</literal> and
+ <literal>n_distinct_inherited</literal>, which override the
+ number-of-distinct-values estimates made by subsequent
+ <link linkend="sql-analyze"><command>ANALYZE</command></link>
+ operations. <literal>n_distinct</literal> affects the statistics for the table
+ itself, while <literal>n_distinct_inherited</literal> affects the statistics
+ gathered for the table plus its inheritance children. When set to a
+ positive value, <command>ANALYZE</command> will assume that the column contains
+ exactly the specified number of distinct nonnull values. When set to a
+ negative value, which must be greater
+ than or equal to -1, <command>ANALYZE</command> will assume that the number of
+ distinct nonnull values in the column is linear in the size of the
+ table; the exact count is to be computed by multiplying the estimated
+ table size by the absolute value of the given number. For example,
+ a value of -1 implies that all values in the column are distinct, while
+ a value of -0.5 implies that each value appears twice on the average.
+ This can be useful when the size of the table changes over time, since
+ the multiplication by the number of rows in the table is not performed
+ until query planning time. Specify a value of 0 to revert to estimating
+ the number of distinct values normally. For more information on the use
+ of statistics by the <productname>PostgreSQL</productname> query
+ planner, refer to <xref linkend="planner-stats"/>.
+ </para>
+ <para>
+ Changing per-attribute options acquires a
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SET STORAGE</literal>
+ <indexterm>
+ <primary>TOAST</primary>
+ <secondary>per-column storage settings</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This form sets the storage mode for a column. This controls whether this
+ column is held inline or in a secondary <acronym>TOAST</acronym> table, and
+ whether the data
+ should be compressed or not. <literal>PLAIN</literal> must be used
+ for fixed-length values such as <type>integer</type> and is
+ inline, uncompressed. <literal>MAIN</literal> is for inline,
+ compressible data. <literal>EXTERNAL</literal> is for external,
+ uncompressed data, and <literal>EXTENDED</literal> is for external,
+ compressed data. <literal>EXTENDED</literal> is the default for most
+ data types that support non-<literal>PLAIN</literal> storage.
+ Use of <literal>EXTERNAL</literal> will make substring operations on
+ very large <type>text</type> and <type>bytea</type> values run faster,
+ at the penalty of increased storage space. Note that
+ <literal>SET STORAGE</literal> doesn't itself change anything in the table,
+ it just sets the strategy to be pursued during future table updates.
+ See <xref linkend="storage-toast"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SET COMPRESSION <replaceable class="parameter">compression_method</replaceable></literal>
+ </term>
+ <listitem>
+ <para>
+ This form sets the compression method for a column, determining how
+ values inserted in future will be compressed (if the storage mode
+ permits compression at all).
+ This does not cause the table to be rewritten, so existing data may still
+ be compressed with other compression methods. If the table is restored
+ with <application>pg_restore</application>, then all values are rewritten
+ with the configured compression method.
+ However, when data is inserted from another relation (for example,
+ by <command>INSERT ... SELECT</command>), values from the source table are
+ not necessarily detoasted, so any previously compressed data may retain
+ its existing compression method, rather than being recompressed with the
+ compression method of the target column.
+ The supported compression
+ methods are <literal>pglz</literal> and <literal>lz4</literal>.
+ (<literal>lz4</literal> is available only if <option>--with-lz4</option>
+ was used when building <productname>PostgreSQL</productname>.) In
+ addition, <replaceable class="parameter">compression_method</replaceable>
+ can be <literal>default</literal>, which selects the default behavior of
+ consulting the <xref linkend="guc-default-toast-compression"/> setting
+ at the time of data insertion to determine the method to use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD <replaceable class="parameter">table_constraint</replaceable> [ NOT VALID ]</literal></term>
+ <listitem>
+ <para>
+ This form adds a new constraint to a table using the same constraint
+ syntax as <link linkend="sql-createtable"><command>CREATE TABLE</command></link>, plus the option <literal>NOT
+ VALID</literal>, which is currently only allowed for foreign key
+ and CHECK constraints.
+ </para>
+
+ <para>
+ Normally, this form will cause a scan of the table to verify that all
+ existing rows in the table satisfy the new constraint. But if
+ the <literal>NOT VALID</literal> option is used, this
+ potentially-lengthy scan is skipped. The constraint will still be
+ enforced against subsequent inserts or updates (that is, they'll fail
+ unless there is a matching row in the referenced table, in the case
+ of foreign keys, or they'll fail unless the new row matches the
+ specified check condition). But the
+ database will not assume that the constraint holds for all rows in
+ the table, until it is validated by using the <literal>VALIDATE
+ CONSTRAINT</literal> option.
+ See <xref linkend="sql-altertable-notes"/> below for more information
+ about using the <literal>NOT VALID</literal> option.
+ </para>
+
+ <para>
+ Although most forms of <literal>ADD
+ <replaceable class="parameter">table_constraint</replaceable></literal>
+ require an <literal>ACCESS EXCLUSIVE</literal> lock, <literal>ADD
+ FOREIGN KEY</literal> requires only a <literal>SHARE ROW
+ EXCLUSIVE</literal> lock. Note that <literal>ADD FOREIGN KEY</literal>
+ also acquires a <literal>SHARE ROW EXCLUSIVE</literal> lock on the
+ referenced table, in addition to the lock on the table on which the
+ constraint is declared.
+ </para>
+
+ <para>
+ Additional restrictions apply when unique or primary key constraints
+ are added to partitioned tables; see <link linkend="sql-createtable"><command>CREATE TABLE</command></link>.
+ Also, foreign key constraints on partitioned
+ tables may not be declared <literal>NOT VALID</literal> at present.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD <replaceable class="parameter">table_constraint_using_index</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form adds a new <literal>PRIMARY KEY</literal> or <literal>UNIQUE</literal>
+ constraint to a table based on an existing unique index. All the
+ columns of the index will be included in the constraint.
+ </para>
+
+ <para>
+ The index cannot have expression columns nor be a partial index.
+ Also, it must be a b-tree index with default sort ordering. These
+ restrictions ensure that the index is equivalent to one that would be
+ built by a regular <literal>ADD PRIMARY KEY</literal> or <literal>ADD UNIQUE</literal>
+ command.
+ </para>
+
+ <para>
+ If <literal>PRIMARY KEY</literal> is specified, and the index's columns are not
+ already marked <literal>NOT NULL</literal>, then this command will attempt to
+ do <literal>ALTER COLUMN SET NOT NULL</literal> against each such column.
+ That requires a full table scan to verify the column(s) contain no
+ nulls. In all other cases, this is a fast operation.
+ </para>
+
+ <para>
+ If a constraint name is provided then the index will be renamed to match
+ the constraint name. Otherwise the constraint will be named the same as
+ the index.
+ </para>
+
+ <para>
+ After this command is executed, the index is <quote>owned</quote> by the
+ constraint, in the same way as if the index had been built by
+ a regular <literal>ADD PRIMARY KEY</literal> or <literal>ADD UNIQUE</literal>
+ command. In particular, dropping the constraint will make the index
+ disappear too.
+ </para>
+
+ <para>
+ This form is not currently supported on partitioned tables.
+ </para>
+
+ <note>
+ <para>
+ Adding a constraint using an existing index can be helpful in
+ situations where a new constraint needs to be added without blocking
+ table updates for a long time. To do that, create the index using
+ <command>CREATE INDEX CONCURRENTLY</command>, and then install it as an
+ official constraint using this syntax. See the example below.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALTER CONSTRAINT</literal></term>
+ <listitem>
+ <para>
+ This form alters the attributes of a constraint that was previously
+ created. Currently only foreign key constraints may be altered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALIDATE CONSTRAINT</literal></term>
+ <listitem>
+ <para>
+ This form validates a foreign key or check constraint that was
+ previously created as <literal>NOT VALID</literal>, by scanning the
+ table to ensure there are no rows for which the constraint is not
+ satisfied. Nothing happens if the constraint is already marked valid.
+ (See <xref linkend="sql-altertable-notes"/> below for an explanation
+ of the usefulness of this command.)
+ </para>
+ <para>
+ This command acquires a <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP CONSTRAINT [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form drops the specified constraint on a table, along with
+ any index underlying the constraint.
+ If <literal>IF EXISTS</literal> is specified and the constraint
+ does not exist, no error is thrown. In this case a notice is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE</literal>/<literal>ENABLE [ REPLICA | ALWAYS ] TRIGGER</literal></term>
+ <listitem>
+ <para>
+ These forms configure the firing of trigger(s) belonging to the table.
+ A disabled trigger is still known to the system, but is not executed
+ when its triggering event occurs. (For a deferred trigger, the enable
+ status is checked when the event occurs, not when the trigger function
+ is actually executed.) One can disable or enable a single
+ trigger specified by name, or all triggers on the table, or only
+ user triggers (this option excludes internally generated constraint
+ triggers, such as those that are used to implement foreign key
+ constraints or deferrable uniqueness and exclusion constraints).
+ Disabling or enabling internally generated constraint triggers
+ requires superuser privileges; it should be done with caution since
+ of course the integrity of the constraint cannot be guaranteed if the
+ triggers are not executed.
+ </para>
+
+ <para>
+ The trigger firing mechanism is also affected by the configuration
+ variable <xref linkend="guc-session-replication-role"/>. Simply enabled
+ triggers (the default) will fire when the replication role is <quote>origin</quote>
+ (the default) or <quote>local</quote>. Triggers configured as <literal>ENABLE
+ REPLICA</literal> will only fire if the session is in <quote>replica</quote>
+ mode, and triggers configured as <literal>ENABLE ALWAYS</literal> will
+ fire regardless of the current replication role.
+ </para>
+
+ <para>
+ The effect of this mechanism is that in the default configuration,
+ triggers do not fire on replicas. This is useful because if a trigger
+ is used on the origin to propagate data between tables, then the
+ replication system will also replicate the propagated data; so the
+ trigger should not fire a second time on the replica, because that would
+ lead to duplication. However, if a trigger is used for another purpose
+ such as creating external alerts, then it might be appropriate to set it
+ to <literal>ENABLE ALWAYS</literal> so that it is also fired on
+ replicas.
+ </para>
+
+ <para>
+ When this command is applied to a partitioned table, the states of
+ corresponding clone triggers in the partitions are updated too,
+ unless <literal>ONLY</literal> is specified.
+ </para>
+
+ <para>
+ This command acquires a <literal>SHARE ROW EXCLUSIVE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE</literal>/<literal>ENABLE [ REPLICA | ALWAYS ] RULE</literal></term>
+ <listitem>
+ <para>
+ These forms configure the firing of rewrite rules belonging to the table.
+ A disabled rule is still known to the system, but is not applied
+ during query rewriting. The semantics are as for disabled/enabled
+ triggers. This configuration is ignored for <literal>ON SELECT</literal> rules, which
+ are always applied in order to keep views working even if the current
+ session is in a non-default replication role.
+ </para>
+
+ <para>
+ The rule firing mechanism is also affected by the configuration variable
+ <xref linkend="guc-session-replication-role"/>, analogous to triggers as
+ described above.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE</literal>/<literal>ENABLE ROW LEVEL SECURITY</literal></term>
+ <listitem>
+ <para>
+ These forms control the application of row security policies belonging
+ to the table. If enabled and no policies exist for the table, then a
+ default-deny policy is applied. Note that policies can exist for a table
+ even if row-level security is disabled. In this case, the policies will
+ <emphasis>not</emphasis> be applied and the policies will be ignored.
+ See also
+ <link linkend="sql-createpolicy"><command>CREATE POLICY</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NO FORCE</literal>/<literal>FORCE ROW LEVEL SECURITY</literal></term>
+ <listitem>
+ <para>
+ These forms control the application of row security policies belonging
+ to the table when the user is the table owner. If enabled, row-level
+ security policies will be applied when the user is the table owner. If
+ disabled (the default) then row-level security will not be applied when
+ the user is the table owner.
+ See also
+ <link linkend="sql-createpolicy"><command>CREATE POLICY</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CLUSTER ON</literal></term>
+ <listitem>
+ <para>
+ This form selects the default index for future
+ <link linkend="sql-cluster"><command>CLUSTER</command></link>
+ operations. It does not actually re-cluster the table.
+ </para>
+ <para>
+ Changing cluster options acquires a <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET WITHOUT CLUSTER</literal></term>
+ <listitem>
+ <para>
+ This form removes the most recently used
+ <link linkend="sql-cluster"><command>CLUSTER</command></link>
+ index specification from the table. This affects
+ future cluster operations that don't specify an index.
+ </para>
+ <para>
+ Changing cluster options acquires a <literal>SHARE UPDATE EXCLUSIVE</literal> lock.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET WITHOUT OIDS</literal></term>
+ <listitem>
+ <para>
+ Backward-compatible syntax for removing the <literal>oid</literal>
+ system column. As <literal>oid</literal> system columns cannot be
+ added anymore, this never has an effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ACCESS METHOD</literal></term>
+ <listitem>
+ <para>
+ This form changes the access method of the table by rewriting it. See
+ <xref linkend="tableam"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET TABLESPACE</literal></term>
+ <listitem>
+ <para>
+ This form changes the table's tablespace to the specified tablespace and
+ moves the data file(s) associated with the table to the new tablespace.
+ Indexes on the table, if any, are not moved; but they can be moved
+ separately with additional <literal>SET TABLESPACE</literal> commands.
+ When applied to a partitioned table, nothing is moved, but any
+ partitions created afterwards with
+ <command>CREATE TABLE PARTITION OF</command> will use that tablespace,
+ unless overridden by a <literal>TABLESPACE</literal> clause.
+ </para>
+
+ <para>
+ All tables in the current database in a tablespace can be moved by using
+ the <literal>ALL IN TABLESPACE</literal> form, which will lock all tables
+ to be moved first and then move each one. This form also supports
+ <literal>OWNED BY</literal>, which will only move tables owned by the
+ roles specified. If the <literal>NOWAIT</literal> option is specified
+ then the command will fail if it is unable to acquire all of the locks
+ required immediately. Note that system catalogs are not moved by this
+ command; use <command>ALTER DATABASE</command> or explicit
+ <command>ALTER TABLE</command> invocations instead if desired. The
+ <literal>information_schema</literal> relations are not considered part
+ of the system catalogs and will be moved.
+ See also
+ <link linkend="sql-createtablespace"><command>CREATE TABLESPACE</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET { LOGGED | UNLOGGED }</literal></term>
+ <listitem>
+ <para>
+ This form changes the table from unlogged to logged or vice-versa
+ (see <xref linkend="sql-createtable-unlogged"/>). It cannot be applied
+ to a temporary table.
+ </para>
+
+ <para>
+ This also changes the persistence of any sequences linked to the table
+ (for identity or serial columns). However, it is also possible to
+ change the persistence of such sequences separately.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This form changes one or more storage parameters for the table. See
+ <xref linkend="sql-createtable-storage-parameters"/> in the
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link> documentation
+ for details on the available parameters. Note that the table contents
+ will not be modified immediately by this command; depending on the
+ parameter you might need to rewrite the table to get the desired effects.
+ That can be done with <link linkend="sql-vacuum"><command>VACUUM
+ FULL</command></link>, <link linkend="sql-cluster"><command>CLUSTER</command></link> or one of the forms
+ of <command>ALTER TABLE</command> that forces a table rewrite.
+ For planner related parameters, changes will take effect from the next
+ time the table is locked so currently executing queries will not be
+ affected.
+ </para>
+
+ <para>
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock will be taken for
+ fillfactor, toast and autovacuum storage parameters, as well as the
+ planner parameter <varname>parallel_workers</varname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESET ( <replaceable class="parameter">storage_parameter</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This form resets one or more storage parameters to their
+ defaults. As with <literal>SET</literal>, a table rewrite might be
+ needed to update the table entirely.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INHERIT <replaceable class="parameter">parent_table</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form adds the target table as a new child of the specified parent
+ table. Subsequently, queries against the parent will include records
+ of the target table. To be added as a child, the target table must
+ already contain all the same columns as the parent (it could have
+ additional columns, too). The columns must have matching data types,
+ and if they have <literal>NOT NULL</literal> constraints in the parent
+ then they must also have <literal>NOT NULL</literal> constraints in the
+ child.
+ </para>
+
+ <para>
+ There must also be matching child-table constraints for all
+ <literal>CHECK</literal> constraints of the parent, except those
+ marked non-inheritable (that is, created with <literal>ALTER TABLE ... ADD CONSTRAINT ... NO INHERIT</literal>)
+ in the parent, which are ignored; all child-table constraints matched
+ must not be marked non-inheritable.
+ Currently
+ <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>, and
+ <literal>FOREIGN KEY</literal> constraints are not considered, but
+ this might change in the future.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NO INHERIT <replaceable class="parameter">parent_table</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form removes the target table from the list of children of the
+ specified parent table.
+ Queries against the parent table will no longer include records drawn
+ from the target table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OF <replaceable class="parameter">type_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ This form links the table to a composite type as though <command>CREATE
+ TABLE OF</command> had formed it. The table's list of column names and types
+ must precisely match that of the composite type. The table must
+ not inherit from any other table. These restrictions ensure
+ that <command>CREATE TABLE OF</command> would permit an equivalent table
+ definition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOT OF</literal></term>
+ <listitem>
+ <para>
+ This form dissociates a typed table from its type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OWNER TO</literal></term>
+ <listitem>
+ <para>
+ This form changes the owner of the table, sequence, view, materialized view,
+ or foreign table to the specified user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-altertable-replica-identity">
+ <term><literal>REPLICA IDENTITY</literal></term>
+ <listitem>
+ <para>
+ This form changes the information which is written to the write-ahead log
+ to identify rows which are updated or deleted.
+ In most cases, the old value of each column is only logged if it differs
+ from the new value; however, if the old value is stored externally, it is
+ always logged regardless of whether it changed.
+ This option has no effect except when logical replication is in use.
+ <variablelist>
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Records the old values of the columns of the primary key, if any.
+ This is the default for non-system tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USING INDEX <replaceable class="parameter">index_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ Records the old values of the columns covered by the named index,
+ that must be unique, not partial, not deferrable, and include only
+ columns marked <literal>NOT NULL</literal>. If this index is
+ dropped, the behavior is the same as <literal>NOTHING</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FULL</literal></term>
+ <listitem>
+ <para>
+ Records the old values of all columns in the row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOTHING</literal></term>
+ <listitem>
+ <para>
+ Records no information about the old row. This is the default for
+ system tables.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME</literal></term>
+ <listitem>
+ <para>
+ The <literal>RENAME</literal> forms change the name of a table
+ (or an index, sequence, view, materialized view, or foreign table), the
+ name of an individual column in a table, or the name of a constraint of
+ the table. When renaming a constraint that has an underlying index,
+ the index is renamed as well.
+ There is no effect on the stored data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET SCHEMA</literal></term>
+ <listitem>
+ <para>
+ This form moves the table into another schema. Associated indexes,
+ constraints, and sequences owned by table columns are moved as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-altertable-attach-partition">
+ <term><literal>ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }</literal></term>
+ <listitem>
+ <para>
+ This form attaches an existing table (which might itself be partitioned)
+ as a partition of the target table. The table can be attached
+ as a partition for specific values using <literal>FOR VALUES</literal>
+ or as a default partition by using <literal>DEFAULT</literal>.
+ For each index in the target table, a corresponding
+ one will be created in the attached table; or, if an equivalent
+ index already exists, it will be attached to the target table's index,
+ as if <command>ALTER INDEX ATTACH PARTITION</command> had been executed.
+ Note that if the existing table is a foreign table, it is currently not
+ allowed to attach the table as a partition of the target table if there
+ are <literal>UNIQUE</literal> indexes on the target table. (See also
+ <xref linkend="sql-createforeigntable"/>.) For each user-defined
+ row-level trigger that exists in the target table, a corresponding one
+ is created in the attached table.
+ </para>
+
+ <para>
+ A partition using <literal>FOR VALUES</literal> uses same syntax for
+ <replaceable class="parameter">partition_bound_spec</replaceable> as
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link>. The partition bound specification
+ must correspond to the partitioning strategy and partition key of the
+ target table. The table to be attached must have all the same columns
+ as the target table and no more; moreover, the column types must also
+ match. Also, it must have all the <literal>NOT NULL</literal> and
+ <literal>CHECK</literal> constraints of the target table. Currently
+ <literal>FOREIGN KEY</literal> constraints are not considered.
+ <literal>UNIQUE</literal> and <literal>PRIMARY KEY</literal> constraints
+ from the parent table will be created in the partition, if they don't
+ already exist.
+ If any of the <literal>CHECK</literal> constraints of the table being
+ attached are marked <literal>NO INHERIT</literal>, the command will fail;
+ such constraints must be recreated without the
+ <literal>NO INHERIT</literal> clause.
+ </para>
+
+ <para>
+ If the new partition is a regular table, a full table scan is performed
+ to check that existing rows in the table do not violate the partition
+ constraint. It is possible to avoid this scan by adding a valid
+ <literal>CHECK</literal> constraint to the table that allows only
+ rows satisfying the desired partition constraint before running this
+ command. The <literal>CHECK</literal> constraint will be used to
+ determine that the table need not be scanned to validate the partition
+ constraint. This does not work, however, if any of the partition keys
+ is an expression and the partition does not accept
+ <literal>NULL</literal> values. If attaching a list partition that will
+ not accept <literal>NULL</literal> values, also add a
+ <literal>NOT NULL</literal> constraint to the partition key column,
+ unless it's an expression.
+ </para>
+
+ <para>
+ If the new partition is a foreign table, nothing is done to verify
+ that all the rows in the foreign table obey the partition constraint.
+ (See the discussion in <xref linkend="sql-createforeigntable"/> about
+ constraints on the foreign table.)
+ </para>
+
+ <para>
+ When a table has a default partition, defining a new partition changes
+ the partition constraint for the default partition. The default
+ partition can't contain any rows that would need to be moved to the new
+ partition, and will be scanned to verify that none are present. This
+ scan, like the scan of the new partition, can be avoided if an
+ appropriate <literal>CHECK</literal> constraint is present. Also like
+ the scan of the new partition, it is always skipped when the default
+ partition is a foreign table.
+ </para>
+
+ <para>
+ Attaching a partition acquires a
+ <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the parent table,
+ in addition to the <literal>ACCESS EXCLUSIVE</literal> locks on the table
+ being attached and on the default partition (if any).
+ </para>
+
+ <para>
+ Further locks must also be held on all sub-partitions if the table being
+ attached is itself a partitioned table. Likewise if the default
+ partition is itself a partitioned table. The locking of the
+ sub-partitions can be avoided by adding a <literal>CHECK</literal>
+ constraint as described in
+ <xref linkend="ddl-partitioning-declarative-maintenance"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-altertable-detach-partition">
+ <term><literal>DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]</literal></term>
+
+ <listitem>
+ <para>
+ This form detaches the specified partition of the target table. The detached
+ partition continues to exist as a standalone table, but no longer has any
+ ties to the table from which it was detached. Any indexes that were
+ attached to the target table's indexes are detached. Any triggers that
+ were created as clones of those in the target table are removed.
+ <literal>SHARE</literal> lock is obtained on any tables that reference
+ this partitioned table in foreign key constraints.
+ </para>
+ <para>
+ If <literal>CONCURRENTLY</literal> is specified, it runs using a reduced
+ lock level to avoid blocking other sessions that might be accessing the
+ partitioned table. In this mode, two transactions are used internally.
+ During the first transaction, a <literal>SHARE UPDATE EXCLUSIVE</literal>
+ lock is taken on both parent table and partition, and the partition is
+ marked as undergoing detach; at that point, the transaction is committed
+ and all other transactions using the partitioned table are waited for.
+ Once all those transactions have completed, the second transaction
+ acquires <literal>SHARE UPDATE EXCLUSIVE</literal> on the partitioned
+ table and <literal>ACCESS EXCLUSIVE</literal> on the partition,
+ and the detach process completes. A <literal>CHECK</literal> constraint
+ that duplicates the partition constraint is added to the partition.
+ <literal>CONCURRENTLY</literal> cannot be run in a transaction block and
+ is not allowed if the partitioned table contains a default partition.
+ </para>
+ <para>
+ If <literal>FINALIZE</literal> is specified, a previous
+ <literal>DETACH CONCURRENTLY</literal> invocation that was canceled or
+ interrupted is completed.
+ At most one partition in a partitioned table can be pending detach at
+ a time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ All the forms of ALTER TABLE that act on a single table, except
+ <literal>RENAME</literal>, <literal>SET SCHEMA</literal>,
+ <literal>ATTACH PARTITION</literal>, and
+ <literal>DETACH PARTITION</literal> can be combined into
+ a list of multiple alterations to be applied together. For example, it
+ is possible to add several columns and/or alter the type of several
+ columns in a single command. This is particularly useful with large
+ tables, since only one pass over the table need be made.
+ </para>
+
+ <para>
+ You must own the table to use <command>ALTER TABLE</command>.
+ To change the schema or tablespace of a table, you must also have
+ <literal>CREATE</literal> privilege on the new schema or tablespace.
+ To add the table as a new child of a parent table, you must own the parent
+ table as well. Also, to attach a table as a new partition of the table,
+ you must own the table being attached.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the table's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the table.
+ However, a superuser can alter ownership of any table anyway.)
+ To add a column or alter a column type or use the <literal>OF</literal>
+ clause, you must also have <literal>USAGE</literal> privilege on the data
+ type.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the table does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing table to
+ alter. If <literal>ONLY</literal> is specified before the table name, only
+ that table is altered. If <literal>ONLY</literal> is not specified, the table
+ and all its descendant tables (if any) are altered. Optionally,
+ <literal>*</literal> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a new or existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_column_name</replaceable></term>
+ <listitem>
+ <para>
+ New name for an existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ New name for the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ Data type of the new column, or new data type for an existing
+ column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_constraint</replaceable></term>
+ <listitem>
+ <para>
+ New table constraint for the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">constraint_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a new or existing constraint.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the dropped column
+ or constraint (for example, views referencing the column),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the column or constraint if there are any dependent
+ objects. This is the default behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">trigger_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of a single trigger to disable or enable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Disable or enable all triggers belonging to the table.
+ (This requires superuser privilege if any of the triggers are
+ internally generated constraint triggers, such as those that are used
+ to implement foreign key constraints or deferrable uniqueness and
+ exclusion constraints.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USER</literal></term>
+ <listitem>
+ <para>
+ Disable or enable all triggers belonging to the table except for
+ internally generated constraint triggers, such as those that are used
+ to implement foreign key constraints or deferrable uniqueness and
+ exclusion constraints.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">storage_parameter</replaceable></term>
+ <listitem>
+ <para>
+ The name of a table storage parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ The new value for a table storage parameter.
+ This might be a number or a word depending on the parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">parent_table</replaceable></term>
+ <listitem>
+ <para>
+ A parent table to associate or de-associate with this table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_access_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the access method to which the table will be converted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_tablespace</replaceable></term>
+ <listitem>
+ <para>
+ The name of the tablespace to which the table will be moved.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The name of the schema to which the table will be moved.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">partition_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the table to attach as a new partition or to detach from this table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">partition_bound_spec</replaceable></term>
+ <listitem>
+ <para>
+ The partition bound specification for a new partition. Refer to
+ <xref linkend="sql-createtable"/> for more details on the syntax of the same.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-altertable-notes" xreflabel="Notes">
+ <title>Notes</title>
+
+ <para>
+ The key word <literal>COLUMN</literal> is noise and can be omitted.
+ </para>
+
+ <para>
+ When a column is added with <literal>ADD COLUMN</literal> and a
+ non-volatile <literal>DEFAULT</literal> is specified, the default is
+ evaluated at the time of the statement and the result stored in the
+ table's metadata. That value will be used for the column for all existing
+ rows. If no <literal>DEFAULT</literal> is specified, NULL is used. In
+ neither case is a rewrite of the table required.
+ </para>
+
+ <para>
+ Adding a column with a volatile <literal>DEFAULT</literal> or
+ changing the type of an existing column will require the entire table and
+ its indexes to be rewritten. As an exception, when changing the type of an
+ existing column, if the <literal>USING</literal> clause does not change
+ the column contents and the old type is either binary coercible to the new
+ type or an unconstrained domain over the new type, a table rewrite is not
+ needed. However, indexes must always be rebuilt unless the system can
+ verify that the new index would be logically equivalent to the existing
+ one. For example, if the collation for a column has been changed, an index
+ rebuild is always required because the new sort order might be different.
+ However, in the absence of a collation change, a column can be changed
+ from <type>text</type> to <type>varchar</type> (or vice versa) without
+ rebuilding the indexes because these data types sort identically.
+ Table and/or index rebuilds may take a
+ significant amount of time for a large table; and will temporarily require
+ as much as double the disk space.
+ </para>
+
+ <para>
+ Adding a <literal>CHECK</literal> or <literal>NOT NULL</literal> constraint requires
+ scanning the table to verify that existing rows meet the constraint,
+ but does not require a table rewrite.
+ </para>
+
+ <para>
+ Similarly, when attaching a new partition it may be scanned to verify that
+ existing rows meet the partition constraint.
+ </para>
+
+ <para>
+ The main reason for providing the option to specify multiple changes
+ in a single <command>ALTER TABLE</command> is that multiple table scans or
+ rewrites can thereby be combined into a single pass over the table.
+ </para>
+
+ <para>
+ Scanning a large table to verify a new foreign key or check constraint
+ can take a long time, and other updates to the table are locked out
+ until the <command>ALTER TABLE ADD CONSTRAINT</command> command is
+ committed. The main purpose of the <literal>NOT VALID</literal>
+ constraint option is to reduce the impact of adding a constraint on
+ concurrent updates. With <literal>NOT VALID</literal>,
+ the <command>ADD CONSTRAINT</command> command does not scan the table
+ and can be committed immediately. After that, a <literal>VALIDATE
+ CONSTRAINT</literal> command can be issued to verify that existing rows
+ satisfy the constraint. The validation step does not need to lock out
+ concurrent updates, since it knows that other transactions will be
+ enforcing the constraint for rows that they insert or update; only
+ pre-existing rows need to be checked. Hence, validation acquires only
+ a <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the table being
+ altered. (If the constraint is a foreign key then a <literal>ROW
+ SHARE</literal> lock is also required on the table referenced by the
+ constraint.) In addition to improving concurrency, it can be useful to
+ use <literal>NOT VALID</literal> and <literal>VALIDATE
+ CONSTRAINT</literal> in cases where the table is known to contain
+ pre-existing violations. Once the constraint is in place, no new
+ violations can be inserted, and the existing problems can be corrected
+ at leisure until <literal>VALIDATE CONSTRAINT</literal> finally
+ succeeds.
+ </para>
+
+ <para>
+ The <literal>DROP COLUMN</literal> form does not physically remove
+ the column, but simply makes it invisible to SQL operations. Subsequent
+ insert and update operations in the table will store a null value for the
+ column. Thus, dropping a column is quick but it will not immediately
+ reduce the on-disk size of your table, as the space occupied
+ by the dropped column is not reclaimed. The space will be
+ reclaimed over time as existing rows are updated.
+ </para>
+
+ <para>
+ To force immediate reclamation of space occupied by a dropped column,
+ you can execute one of the forms of <command>ALTER TABLE</command> that
+ performs a rewrite of the whole table. This results in reconstructing
+ each row with the dropped column replaced by a null value.
+ </para>
+
+ <para>
+ The rewriting forms of <command>ALTER TABLE</command> are not MVCC-safe.
+ After a table rewrite, the table will appear empty to concurrent
+ transactions, if they are using a snapshot taken before the rewrite
+ occurred. See <xref linkend="mvcc-caveats"/> for more details.
+ </para>
+
+ <para>
+ The <literal>USING</literal> option of <literal>SET DATA TYPE</literal> can actually
+ specify any expression involving the old values of the row; that is, it
+ can refer to other columns as well as the one being converted. This allows
+ very general conversions to be done with the <literal>SET DATA TYPE</literal>
+ syntax. Because of this flexibility, the <literal>USING</literal>
+ expression is not applied to the column's default value (if any); the
+ result might not be a constant expression as required for a default.
+ This means that when there is no implicit or assignment cast from old to
+ new type, <literal>SET DATA TYPE</literal> might fail to convert the default even
+ though a <literal>USING</literal> clause is supplied. In such cases,
+ drop the default with <literal>DROP DEFAULT</literal>, perform the <literal>ALTER
+ TYPE</literal>, and then use <literal>SET DEFAULT</literal> to add a suitable new
+ default. Similar considerations apply to indexes and constraints involving
+ the column.
+ </para>
+
+ <para>
+ If a table has any descendant tables, it is not permitted to add,
+ rename, or change the type of a column in the parent table without doing
+ the same to the descendants. This ensures that the descendants always
+ have columns matching the parent. Similarly, a <literal>CHECK</literal>
+ constraint cannot be renamed in the parent without also renaming it in
+ all descendants, so that <literal>CHECK</literal> constraints also match
+ between the parent and its descendants. (That restriction does not apply
+ to index-based constraints, however.)
+ Also, because selecting from the parent also selects from its descendants,
+ a constraint on the parent cannot be marked valid unless it is also marked
+ valid for those descendants. In all of these cases, <command>ALTER TABLE
+ ONLY</command> will be rejected.
+ </para>
+
+ <para>
+ A recursive <literal>DROP COLUMN</literal> operation will remove a
+ descendant table's column only if the descendant does not inherit
+ that column from any other parents and never had an independent
+ definition of the column. A nonrecursive <literal>DROP
+ COLUMN</literal> (i.e., <command>ALTER TABLE ONLY ... DROP
+ COLUMN</command>) never removes any descendant columns, but
+ instead marks them as independently defined rather than inherited.
+ A nonrecursive <literal>DROP COLUMN</literal> command will fail for a
+ partitioned table, because all partitions of a table must have the same
+ columns as the partitioning root.
+ </para>
+
+ <para>
+ The actions for identity columns (<literal>ADD
+ GENERATED</literal>, <literal>SET</literal> etc., <literal>DROP
+ IDENTITY</literal>), as well as the actions
+ <literal>CLUSTER</literal>, <literal>OWNER</literal>,
+ and <literal>TABLESPACE</literal> never recurse to descendant tables;
+ that is, they always act as though <literal>ONLY</literal> were specified.
+ Actions affecting trigger states recurse to partitions of partitioned
+ tables (unless <literal>ONLY</literal> is specified), but never to
+ traditional-inheritance descendants.
+ Adding a constraint recurses only for <literal>CHECK</literal> constraints
+ that are not marked <literal>NO INHERIT</literal>.
+ </para>
+
+ <para>
+ Changing any part of a system catalog table is not permitted.
+ </para>
+
+ <para>
+ Refer to <xref linkend="sql-createtable"/> for a further description of valid
+ parameters. <xref linkend="ddl"/> has further information on
+ inheritance.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To add a column of type <type>varchar</type> to a table:
+<programlisting>
+ALTER TABLE distributors ADD COLUMN address varchar(30);
+</programlisting>
+ That will cause all existing rows in the table to be filled with null
+ values for the new column.
+ </para>
+
+ <para>
+ To add a column with a non-null default:
+<programlisting>
+ALTER TABLE measurements
+ ADD COLUMN mtime timestamp with time zone DEFAULT now();
+</programlisting>
+ Existing rows will be filled with the current time as the value of the
+ new column, and then new rows will receive the time of their insertion.
+ </para>
+
+ <para>
+ To add a column and fill it with a value different from the default to
+ be used later:
+<programlisting>
+ALTER TABLE transactions
+ ADD COLUMN status varchar(30) DEFAULT 'old',
+ ALTER COLUMN status SET default 'current';
+</programlisting>
+ Existing rows will be filled with <literal>old</literal>, but then
+ the default for subsequent commands will be <literal>current</literal>.
+ The effects are the same as if the two sub-commands had been issued
+ in separate <command>ALTER TABLE</command> commands.
+ </para>
+
+ <para>
+ To drop a column from a table:
+<programlisting>
+ALTER TABLE distributors DROP COLUMN address RESTRICT;
+</programlisting>
+ </para>
+
+ <para>
+ To change the types of two existing columns in one operation:
+<programlisting>
+ALTER TABLE distributors
+ ALTER COLUMN address TYPE varchar(80),
+ ALTER COLUMN name TYPE varchar(100);
+</programlisting>
+ </para>
+
+ <para>
+ To change an integer column containing Unix timestamps to <type>timestamp
+ with time zone</type> via a <literal>USING</literal> clause:
+<programlisting>
+ALTER TABLE foo
+ ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
+ USING
+ timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';
+</programlisting>
+ </para>
+
+ <para>
+ The same, when the column has a default expression that won't automatically
+ cast to the new data type:
+<programlisting>
+ALTER TABLE foo
+ ALTER COLUMN foo_timestamp DROP DEFAULT,
+ ALTER COLUMN foo_timestamp TYPE timestamp with time zone
+ USING
+ timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
+ ALTER COLUMN foo_timestamp SET DEFAULT now();
+</programlisting>
+ </para>
+
+ <para>
+ To rename an existing column:
+<programlisting>
+ALTER TABLE distributors RENAME COLUMN address TO city;
+</programlisting>
+ </para>
+
+ <para>
+ To rename an existing table:
+<programlisting>
+ALTER TABLE distributors RENAME TO suppliers;
+</programlisting>
+ </para>
+
+ <para>
+ To rename an existing constraint:
+<programlisting>
+ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
+</programlisting>
+ </para>
+
+ <para>
+ To add a not-null constraint to a column:
+<programlisting>
+ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
+</programlisting>
+ To remove a not-null constraint from a column:
+<programlisting>
+ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
+</programlisting>
+ </para>
+
+ <para>
+ To add a check constraint to a table and all its children:
+<programlisting>
+ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
+</programlisting>
+ </para>
+
+ <para>
+ To add a check constraint only to a table and not to its children:
+<programlisting>
+ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;
+</programlisting>
+ (The check constraint will not be inherited by future children, either.)
+ </para>
+
+ <para>
+ To remove a check constraint from a table and all its children:
+<programlisting>
+ALTER TABLE distributors DROP CONSTRAINT zipchk;
+</programlisting>
+ </para>
+
+ <para>
+ To remove a check constraint from one table only:
+<programlisting>
+ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
+</programlisting>
+ (The check constraint remains in place for any child tables.)
+ </para>
+
+ <para>
+ To add a foreign key constraint to a table:
+<programlisting>
+ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address);
+</programlisting>
+ </para>
+
+ <para>
+ To add a foreign key constraint to a table with the least impact on other work:
+<programlisting>
+ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) NOT VALID;
+ALTER TABLE distributors VALIDATE CONSTRAINT distfk;
+</programlisting>
+ </para>
+
+ <para>
+ To add a (multicolumn) unique constraint to a table:
+<programlisting>
+ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
+</programlisting>
+ </para>
+
+ <para>
+ To add an automatically named primary key constraint to a table, noting
+ that a table can only ever have one primary key:
+<programlisting>
+ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
+</programlisting>
+ </para>
+
+ <para>
+ To move a table to a different tablespace:
+<programlisting>
+ALTER TABLE distributors SET TABLESPACE fasttablespace;
+</programlisting>
+ </para>
+
+ <para>
+ To move a table to a different schema:
+<programlisting>
+ALTER TABLE myschema.distributors SET SCHEMA yourschema;
+</programlisting>
+ </para>
+
+ <para>
+ To recreate a primary key constraint, without blocking updates while the
+ index is rebuilt:
+<programlisting>
+CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
+ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
+ ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
+</programlisting></para>
+
+ <para>
+ To attach a partition to a range-partitioned table:
+<programlisting>
+ALTER TABLE measurement
+ ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
+</programlisting></para>
+
+ <para>
+ To attach a partition to a list-partitioned table:
+<programlisting>
+ALTER TABLE cities
+ ATTACH PARTITION cities_ab FOR VALUES IN ('a', 'b');
+</programlisting></para>
+
+ <para>
+ To attach a partition to a hash-partitioned table:
+<programlisting>
+ALTER TABLE orders
+ ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3);
+</programlisting></para>
+
+ <para>
+ To attach a default partition to a partitioned table:
+<programlisting>
+ALTER TABLE cities
+ ATTACH PARTITION cities_partdef DEFAULT;
+</programlisting></para>
+
+ <para>
+ To detach a partition from a partitioned table:
+<programlisting>
+ALTER TABLE measurement
+ DETACH PARTITION measurement_y2015m12;
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The forms <literal>ADD</literal> (without <literal>USING INDEX</literal>),
+ <literal>DROP [COLUMN]</literal>, <literal>DROP IDENTITY</literal>, <literal>RESTART</literal>,
+ <literal>SET DEFAULT</literal>, <literal>SET DATA TYPE</literal> (without <literal>USING</literal>),
+ <literal>SET GENERATED</literal>, and <literal>SET <replaceable>sequence_option</replaceable></literal>
+ conform with the SQL standard. The other forms are
+ <productname>PostgreSQL</productname> extensions of the SQL standard.
+ Also, the ability to specify more than one manipulation in a single
+ <command>ALTER TABLE</command> command is an extension.
+ </para>
+
+ <para>
+ <command>ALTER TABLE DROP COLUMN</command> can be used to drop the only
+ column of a table, leaving a zero-column table. This is an
+ extension of SQL, which disallows zero-column tables.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtable"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_tablespace.sgml b/doc/src/sgml/ref/alter_tablespace.sgml
new file mode 100644
index 0000000..6de8074
--- /dev/null
+++ b/doc/src/sgml/ref/alter_tablespace.sgml
@@ -0,0 +1,140 @@
+<!--
+doc/src/sgml/ref/alter_tablespace.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertablespace">
+ <indexterm zone="sql-altertablespace">
+ <primary>ALTER TABLESPACE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TABLESPACE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TABLESPACE</refname>
+ <refpurpose>change the definition of a tablespace</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TABLESPACE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER TABLESPACE <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TABLESPACE <replaceable>name</replaceable> SET ( <replaceable class="parameter">tablespace_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
+ALTER TABLESPACE <replaceable>name</replaceable> RESET ( <replaceable class="parameter">tablespace_option</replaceable> [, ... ] )
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TABLESPACE</command> can be used to change the definition of
+ a tablespace.
+ </para>
+
+ <para>
+ You must own the tablespace to change the definition of a tablespace.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role.
+ (Note that superusers have these privileges automatically.)
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing tablespace.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the tablespace. The new name cannot
+ begin with <literal>pg_</literal>, as such names
+ are reserved for system tablespaces.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the tablespace.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">tablespace_option</replaceable></term>
+ <listitem>
+ <para>
+ A tablespace parameter to be set or reset. Currently, the only
+ available parameters are <varname>seq_page_cost</varname>,
+ <varname>random_page_cost</varname>, <varname>effective_io_concurrency</varname>
+ and <varname>maintenance_io_concurrency</varname>.
+ Setting these values for a particular tablespace will override the
+ planner's usual estimate of the cost of reading pages from tables in
+ that tablespace, and the executor's prefetching behavior, as established
+ by the configuration parameters of the
+ same name (see <xref linkend="guc-seq-page-cost"/>,
+ <xref linkend="guc-random-page-cost"/>,
+ <xref linkend="guc-effective-io-concurrency"/>,
+ <xref linkend="guc-maintenance-io-concurrency"/>). This may be useful if
+ one tablespace is located on a disk which is faster or slower than the
+ remainder of the I/O subsystem.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Rename tablespace <literal>index_space</literal> to <literal>fast_raid</literal>:
+<programlisting>
+ALTER TABLESPACE index_space RENAME TO fast_raid;
+</programlisting>
+ </para>
+
+ <para>
+ Change the owner of tablespace <literal>index_space</literal>:
+<programlisting>
+ALTER TABLESPACE index_space OWNER TO mary;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER TABLESPACE</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtablespace"/></member>
+ <member><xref linkend="sql-droptablespace"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_trigger.sgml b/doc/src/sgml/ref/alter_trigger.sgml
new file mode 100644
index 0000000..ece9cb5
--- /dev/null
+++ b/doc/src/sgml/ref/alter_trigger.sgml
@@ -0,0 +1,146 @@
+<!--
+doc/src/sgml/ref/alter_trigger.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertrigger">
+ <indexterm zone="sql-altertrigger">
+ <primary>ALTER TRIGGER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TRIGGER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TRIGGER</refname>
+ <refpurpose>change the definition of a trigger</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TRIGGER <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER TRIGGER <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> [ NO ] DEPENDS ON EXTENSION <replaceable class="parameter">extension_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TRIGGER</command> changes properties of an existing
+ trigger.
+ </para>
+
+ <para>
+ The <literal>RENAME</literal> clause changes the name of
+ the given trigger without otherwise changing the trigger
+ definition.
+ If the table that the trigger is on is a partitioned table,
+ then corresponding clone triggers in the partitions are
+ renamed too.
+ </para>
+
+ <para>
+ The <literal>DEPENDS ON EXTENSION</literal> clause marks
+ the trigger as dependent on an extension, such that if the extension is
+ dropped, the trigger will automatically be dropped as well.
+ </para>
+
+ <para>
+ You must own the table on which the trigger acts to be allowed to change its properties.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing trigger to alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the table on which this trigger acts.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the trigger.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">extension_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the extension that the trigger is to depend on (or no longer
+ dependent on, if <literal>NO</literal> is specified). A trigger
+ that's marked as dependent on an extension is automatically dropped when
+ the extension is dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The ability to temporarily enable or disable a trigger is provided by
+ <link linkend="sql-altertable"><command>ALTER TABLE</command></link>, not by
+ <command>ALTER TRIGGER</command>, because <command>ALTER TRIGGER</command> has no
+ convenient way to express the option of enabling or disabling all of
+ a table's triggers at once.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename an existing trigger:
+<programlisting>
+ALTER TRIGGER emp_stamp ON emp RENAME TO emp_track_chgs;
+</programlisting></para>
+
+ <para>
+ To mark a trigger as being dependent on an extension:
+<programlisting>
+ALTER TRIGGER emp_stamp ON emp DEPENDS ON EXTENSION emplib;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER TRIGGER</command> is a <productname>PostgreSQL</productname>
+ extension of the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertable"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_tsconfig.sgml b/doc/src/sgml/ref/alter_tsconfig.sgml
new file mode 100644
index 0000000..8fafcd3
--- /dev/null
+++ b/doc/src/sgml/ref/alter_tsconfig.sgml
@@ -0,0 +1,189 @@
+<!--
+doc/src/sgml/ref/alter_tsconfig.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertsconfig">
+ <indexterm zone="sql-altertsconfig">
+ <primary>ALTER TEXT SEARCH CONFIGURATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TEXT SEARCH CONFIGURATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TEXT SEARCH CONFIGURATION</refname>
+ <refpurpose>change the definition of a text search configuration</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
+ ADD MAPPING FOR <replaceable class="parameter">token_type</replaceable> [, ... ] WITH <replaceable class="parameter">dictionary_name</replaceable> [, ... ]
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
+ ALTER MAPPING FOR <replaceable class="parameter">token_type</replaceable> [, ... ] WITH <replaceable class="parameter">dictionary_name</replaceable> [, ... ]
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
+ ALTER MAPPING REPLACE <replaceable class="parameter">old_dictionary</replaceable> WITH <replaceable class="parameter">new_dictionary</replaceable>
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
+ ALTER MAPPING FOR <replaceable class="parameter">token_type</replaceable> [, ... ] REPLACE <replaceable class="parameter">old_dictionary</replaceable> WITH <replaceable class="parameter">new_dictionary</replaceable>
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
+ DROP MAPPING [ IF EXISTS ] FOR <replaceable class="parameter">token_type</replaceable> [, ... ]
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TEXT SEARCH CONFIGURATION</command> changes the definition of
+ a text search configuration. You can modify
+ its mappings from token types to dictionaries,
+ or change the configuration's name or owner.
+ </para>
+
+ <para>
+ You must be the owner of the configuration to use
+ <command>ALTER TEXT SEARCH CONFIGURATION</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search
+ configuration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">token_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of a token type that is emitted by the configuration's
+ parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">dictionary_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a text search dictionary to be consulted for the
+ specified token type(s). If multiple dictionaries are listed,
+ they are consulted in the specified order.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">old_dictionary</replaceable></term>
+ <listitem>
+ <para>
+ The name of a text search dictionary to be replaced in the mapping.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_dictionary</replaceable></term>
+ <listitem>
+ <para>
+ The name of a text search dictionary to be substituted for
+ <replaceable class="parameter">old_dictionary</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the text search configuration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the text search configuration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the text search configuration.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The <literal>ADD MAPPING FOR</literal> form installs a list of dictionaries to be
+ consulted for the specified token type(s); it is an error if there is
+ already a mapping for any of the token types.
+ The <literal>ALTER MAPPING FOR</literal> form does the same, but first removing
+ any existing mapping for those token types.
+ The <literal>ALTER MAPPING REPLACE</literal> forms substitute <replaceable
+ class="parameter">new_dictionary</replaceable> for <replaceable
+ class="parameter">old_dictionary</replaceable> anywhere the latter appears.
+ This is done for only the specified token types when <literal>FOR</literal>
+ appears, or for all mappings of the configuration when it doesn't.
+ The <literal>DROP MAPPING</literal> form removes all dictionaries for the
+ specified token type(s), causing tokens of those types to be ignored
+ by the text search configuration. It is an error if there is no mapping
+ for the token types, unless <literal>IF EXISTS</literal> appears.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example replaces the <literal>english</literal> dictionary
+ with the <literal>swedish</literal> dictionary anywhere that <literal>english</literal>
+ is used within <literal>my_config</literal>.
+ </para>
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION my_config
+ ALTER MAPPING REPLACE english WITH swedish;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER TEXT SEARCH CONFIGURATION</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtsconfig"/></member>
+ <member><xref linkend="sql-droptsconfig"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_tsdictionary.sgml b/doc/src/sgml/ref/alter_tsdictionary.sgml
new file mode 100644
index 0000000..d1923ef
--- /dev/null
+++ b/doc/src/sgml/ref/alter_tsdictionary.sgml
@@ -0,0 +1,170 @@
+<!--
+doc/src/sgml/ref/alter_tsdictionary.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertsdictionary">
+ <indexterm zone="sql-altertsdictionary">
+ <primary>ALTER TEXT SEARCH DICTIONARY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TEXT SEARCH DICTIONARY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TEXT SEARCH DICTIONARY</refname>
+ <refpurpose>change the definition of a text search dictionary</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> (
+ <replaceable class="parameter">option</replaceable> [ = <replaceable class="parameter">value</replaceable> ] [, ... ]
+)
+ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TEXT SEARCH DICTIONARY</command> changes the definition of
+ a text search dictionary. You can change the dictionary's
+ template-specific options, or change the dictionary's name or owner.
+ </para>
+
+ <para>
+ You must be the owner of the dictionary to use
+ <command>ALTER TEXT SEARCH DICTIONARY</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search
+ dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">option</replaceable></term>
+ <listitem>
+ <para>
+ The name of a template-specific option to be set for this dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ The new value to use for a template-specific option.
+ If the equal sign and value are omitted, then any previous
+ setting for the option is removed from the dictionary,
+ allowing the default to be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the text search dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The new owner of the text search dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the text search dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Template-specific options can appear in any order.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example command changes the stopword list
+ for a Snowball-based dictionary. Other parameters remain unchanged.
+ </para>
+
+<programlisting>
+ALTER TEXT SEARCH DICTIONARY my_dict ( StopWords = newrussian );
+</programlisting>
+
+ <para>
+ The following example command changes the language option to <literal>dutch</literal>,
+ and removes the stopword option entirely.
+ </para>
+
+<programlisting>
+ALTER TEXT SEARCH DICTIONARY my_dict ( language = dutch, StopWords );
+</programlisting>
+
+ <para>
+ The following example command <quote>updates</quote> the dictionary's
+ definition without actually changing anything.
+
+<programlisting>
+ALTER TEXT SEARCH DICTIONARY my_dict ( dummy );
+</programlisting>
+
+ (The reason this works is that the option removal code doesn't complain
+ if there is no such option.) This trick is useful when changing
+ configuration files for the dictionary: the <command>ALTER</command> will
+ force existing database sessions to re-read the configuration files,
+ which otherwise they would never do if they had read them earlier.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER TEXT SEARCH DICTIONARY</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtsdictionary"/></member>
+ <member><xref linkend="sql-droptsdictionary"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_tsparser.sgml b/doc/src/sgml/ref/alter_tsparser.sgml
new file mode 100644
index 0000000..9edff4b
--- /dev/null
+++ b/doc/src/sgml/ref/alter_tsparser.sgml
@@ -0,0 +1,93 @@
+<!--
+doc/src/sgml/ref/alter_tsparser.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertsparser">
+ <indexterm zone="sql-altertsparser">
+ <primary>ALTER TEXT SEARCH PARSER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TEXT SEARCH PARSER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TEXT SEARCH PARSER</refname>
+ <refpurpose>change the definition of a text search parser</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TEXT SEARCH PARSER <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER TEXT SEARCH PARSER <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TEXT SEARCH PARSER</command> changes the definition of
+ a text search parser. Currently, the only supported functionality
+ is to change the parser's name.
+ </para>
+
+ <para>
+ You must be a superuser to use <command>ALTER TEXT SEARCH PARSER</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the text search parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the text search parser.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER TEXT SEARCH PARSER</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtsparser"/></member>
+ <member><xref linkend="sql-droptsparser"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_tstemplate.sgml b/doc/src/sgml/ref/alter_tstemplate.sgml
new file mode 100644
index 0000000..5d3c826
--- /dev/null
+++ b/doc/src/sgml/ref/alter_tstemplate.sgml
@@ -0,0 +1,93 @@
+<!--
+doc/src/sgml/ref/alter_tstemplate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertstemplate">
+ <indexterm zone="sql-altertstemplate">
+ <primary>ALTER TEXT SEARCH TEMPLATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TEXT SEARCH TEMPLATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TEXT SEARCH TEMPLATE</refname>
+ <refpurpose>change the definition of a text search template</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TEXT SEARCH TEMPLATE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ALTER TEXT SEARCH TEMPLATE <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TEXT SEARCH TEMPLATE</command> changes the definition of
+ a text search template. Currently, the only supported functionality
+ is to change the template's name.
+ </para>
+
+ <para>
+ You must be a superuser to use <command>ALTER TEXT SEARCH TEMPLATE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search template.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the text search template.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the text search template.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ALTER TEXT SEARCH TEMPLATE</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtstemplate"/></member>
+ <member><xref linkend="sql-droptstemplate"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml
new file mode 100644
index 0000000..1460651
--- /dev/null
+++ b/doc/src/sgml/ref/alter_type.sgml
@@ -0,0 +1,494 @@
+<!--
+doc/src/sgml/ref/alter_type.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-altertype">
+ <indexterm zone="sql-altertype">
+ <primary>ALTER TYPE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER TYPE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER TYPE</refname>
+ <refpurpose>
+ change the definition of a type
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER TYPE <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER TYPE <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER TYPE <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+ALTER TYPE <replaceable class="parameter">name</replaceable> RENAME ATTRIBUTE <replaceable class="parameter">attribute_name</replaceable> TO <replaceable class="parameter">new_attribute_name</replaceable> [ CASCADE | RESTRICT ]
+ALTER TYPE <replaceable class="parameter">name</replaceable> <replaceable class="parameter">action</replaceable> [, ... ]
+ALTER TYPE <replaceable class="parameter">name</replaceable> ADD VALUE [ IF NOT EXISTS ] <replaceable class="parameter">new_enum_value</replaceable> [ { BEFORE | AFTER } <replaceable class="parameter">neighbor_enum_value</replaceable> ]
+ALTER TYPE <replaceable class="parameter">name</replaceable> RENAME VALUE <replaceable class="parameter">existing_enum_value</replaceable> TO <replaceable class="parameter">new_enum_value</replaceable>
+ALTER TYPE <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">property</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )
+
+<phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
+
+ ADD ATTRIBUTE <replaceable class="parameter">attribute_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ CASCADE | RESTRICT ]
+ DROP ATTRIBUTE [ IF EXISTS ] <replaceable class="parameter">attribute_name</replaceable> [ CASCADE | RESTRICT ]
+ ALTER ATTRIBUTE <replaceable class="parameter">attribute_name</replaceable> [ SET DATA ] TYPE <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER TYPE</command> changes the definition of an existing type.
+ There are several subforms:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>OWNER</literal></term>
+ <listitem>
+ <para>
+ This form changes the owner of the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME</literal></term>
+ <listitem>
+ <para>
+ This form changes the name of the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET SCHEMA</literal></term>
+ <listitem>
+ <para>
+ This form moves the type into another schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME ATTRIBUTE</literal></term>
+ <listitem>
+ <para>
+ This form is only usable with composite types.
+ It changes the name of an individual attribute of the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD ATTRIBUTE</literal></term>
+ <listitem>
+ <para>
+ This form adds a new attribute to a composite type, using the same syntax as
+ <link linkend="sql-createtype"><command>CREATE TYPE</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP ATTRIBUTE [ IF EXISTS ]</literal></term>
+ <listitem>
+ <para>
+ This form drops an attribute from a composite type.
+ If <literal>IF EXISTS</literal> is specified and the attribute
+ does not exist, no error is thrown. In this case a notice
+ is issued instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALTER ATTRIBUTE ... SET DATA TYPE</literal></term>
+ <listitem>
+ <para>
+ This form changes the type of an attribute of a composite type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADD VALUE [ IF NOT EXISTS ] [ BEFORE | AFTER ]</literal></term>
+ <listitem>
+ <para>
+ This form adds a new value to an enum type. The new value's place in
+ the enum's ordering can be specified as being <literal>BEFORE</literal>
+ or <literal>AFTER</literal> one of the existing values. Otherwise,
+ the new item is added at the end of the list of values.
+ </para>
+ <para>
+ If <literal>IF NOT EXISTS</literal> is specified, it is not an error if
+ the type already contains the new value: a notice is issued but no other
+ action is taken. Otherwise, an error will occur if the new value is
+ already present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RENAME VALUE</literal></term>
+ <listitem>
+ <para>
+ This form renames a value of an enum type.
+ The value's place in the enum's ordering is not affected.
+ An error will occur if the specified value is not present or the new
+ name is already present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>SET ( <replaceable class="parameter">property</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] )</literal>
+ </term>
+ <listitem>
+ <para>
+ This form is only applicable to base types. It allows adjustment of a
+ subset of the base-type properties that can be set in <command>CREATE
+ TYPE</command>. Specifically, these properties can be changed:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>RECEIVE</literal> can be set to the name of a binary input
+ function, or <literal>NONE</literal> to remove the type's binary
+ input function. Using this option requires superuser privilege.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SEND</literal> can be set to the name of a binary output
+ function, or <literal>NONE</literal> to remove the type's binary
+ output function. Using this option requires superuser privilege.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>TYPMOD_IN</literal> can be set to the name of a type
+ modifier input function, or <literal>NONE</literal> to remove the
+ type's type modifier input function. Using this option requires
+ superuser privilege.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>TYPMOD_OUT</literal> can be set to the name of a type
+ modifier output function, or <literal>NONE</literal> to remove the
+ type's type modifier output function. Using this option requires
+ superuser privilege.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ANALYZE</literal> can be set to the name of a type-specific
+ statistics collection function, or <literal>NONE</literal> to remove
+ the type's statistics collection function. Using this option
+ requires superuser privilege.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>SUBSCRIPT</literal> can be set to the name of a type-specific
+ subscripting handler function, or <literal>NONE</literal> to remove
+ the type's subscripting handler function. Using this option
+ requires superuser privilege.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>STORAGE</literal><indexterm>
+ <primary>TOAST</primary>
+ <secondary>per-type storage settings</secondary>
+ </indexterm>
+ can be set to <literal>plain</literal>,
+ <literal>extended</literal>, <literal>external</literal>,
+ or <literal>main</literal> (see <xref linkend="storage-toast"/> for
+ more information about what these mean). However, changing
+ from <literal>plain</literal> to another setting requires superuser
+ privilege (because it requires that the type's C functions all be
+ TOAST-ready), and changing to <literal>plain</literal> from another
+ setting is not allowed at all (since the type may already have
+ TOASTed values present in the database). Note that changing this
+ option doesn't by itself change any stored data, it just sets the
+ default TOAST strategy to be used for table columns created in the
+ future. See <xref linkend="sql-altertable"/> to change the TOAST
+ strategy for existing table columns.
+ </para>
+ </listitem>
+ </itemizedlist>
+ See <xref linkend="sql-createtype"/> for more details about these
+ type properties. Note that where appropriate, a change in these
+ properties for a base type will be propagated automatically to domains
+ based on that type.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <literal>ADD ATTRIBUTE</literal>, <literal>DROP
+ ATTRIBUTE</literal>, and <literal>ALTER ATTRIBUTE</literal> actions
+ can be combined into a list of multiple alterations to apply in
+ parallel. For example, it is possible to add several attributes
+ and/or alter the type of several attributes in a single command.
+ </para>
+
+ <para>
+ You must own the type to use <command>ALTER TYPE</command>.
+ To change the schema of a type, you must also have
+ <literal>CREATE</literal> privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the type's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the type.
+ However, a superuser can alter ownership of any type anyway.)
+ To add an attribute or alter an attribute type, you must also
+ have <literal>USAGE</literal> privilege on the attribute's data type.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of an existing type to
+ alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">attribute_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the attribute to add, alter, or drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_attribute_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name of the attribute to be renamed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the attribute to add, or the new type of the
+ attribute to alter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_enum_value</replaceable></term>
+ <listitem>
+ <para>
+ The new value to be added to an enum type's list of values,
+ or the new name to be given to an existing value.
+ Like all enum literals, it needs to be quoted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">neighbor_enum_value</replaceable></term>
+ <listitem>
+ <para>
+ The existing enum value that the new value should be added immediately
+ before or after in the enum type's sort ordering.
+ Like all enum literals, it needs to be quoted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">existing_enum_value</replaceable></term>
+ <listitem>
+ <para>
+ The existing enum value that should be renamed.
+ Like all enum literals, it needs to be quoted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">property</replaceable></term>
+ <listitem>
+ <para>
+ The name of a base-type property to be modified; see above for
+ possible values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically propagate the operation to typed tables of the
+ type being altered, and their descendants.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse the operation if the type being altered is the type of a
+ typed table. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If <command>ALTER TYPE ... ADD VALUE</command> (the form that adds a new
+ value to an enum type) is executed inside a transaction block, the new
+ value cannot be used until after the transaction has been committed.
+ </para>
+
+ <para>
+ Comparisons involving an added enum value will sometimes be slower than
+ comparisons involving only original members of the enum type. This will
+ usually only occur if <literal>BEFORE</literal> or <literal>AFTER</literal>
+ is used to set the new value's sort position somewhere other than at the
+ end of the list. However, sometimes it will happen even though the new
+ value is added at the end (this occurs if the OID counter <quote>wrapped
+ around</quote> since the original creation of the enum type). The slowdown is
+ usually insignificant; but if it matters, optimal performance can be
+ regained by dropping and recreating the enum type, or by dumping and
+ restoring the database.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename a data type:
+<programlisting>
+ALTER TYPE electronic_mail RENAME TO email;
+</programlisting>
+ </para>
+
+ <para>
+ To change the owner of the type <literal>email</literal>
+ to <literal>joe</literal>:
+<programlisting>
+ALTER TYPE email OWNER TO joe;
+</programlisting>
+ </para>
+
+ <para>
+ To change the schema of the type <literal>email</literal>
+ to <literal>customers</literal>:
+<programlisting>
+ALTER TYPE email SET SCHEMA customers;
+</programlisting>
+ </para>
+
+ <para>
+ To add a new attribute to a composite type:
+<programlisting>
+ALTER TYPE compfoo ADD ATTRIBUTE f3 int;
+</programlisting>
+ </para>
+
+ <para>
+ To add a new value to an enum type in a particular sort position:
+<programlisting>
+ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';
+</programlisting>
+ </para>
+
+ <para>
+ To rename an enum value:
+<programlisting>
+ALTER TYPE colors RENAME VALUE 'purple' TO 'mauve';
+</programlisting>
+ </para>
+
+ <para>
+ To create binary I/O functions for an existing base type:
+<programlisting>
+CREATE FUNCTION mytypesend(mytype) RETURNS bytea ...;
+CREATE FUNCTION mytyperecv(internal, oid, integer) RETURNS mytype ...;
+ALTER TYPE mytype SET (
+ SEND = mytypesend,
+ RECEIVE = mytyperecv
+);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The variants to add and drop attributes are part of the SQL
+ standard; the other variants are PostgreSQL extensions.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-altertype-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtype"/></member>
+ <member><xref linkend="sql-droptype"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml
new file mode 100644
index 0000000..0ee89f5
--- /dev/null
+++ b/doc/src/sgml/ref/alter_user.sgml
@@ -0,0 +1,81 @@
+<!--
+doc/src/sgml/ref/alter_user.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alteruser">
+ <indexterm zone="sql-alteruser">
+ <primary>ALTER USER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER USER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER USER</refname>
+ <refpurpose>change a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER USER <replaceable class="parameter">role_specification</replaceable> [ WITH ] <replaceable class="parameter">option</replaceable> [ ... ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <replaceable class="parameter">connlimit</replaceable>
+ | [ ENCRYPTED ] PASSWORD '<replaceable class="parameter">password</replaceable>' | PASSWORD NULL
+ | VALID UNTIL '<replaceable class="parameter">timestamp</replaceable>'
+
+ALTER USER <replaceable class="parameter">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+
+ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> { TO | = } { <replaceable>value</replaceable> | DEFAULT }
+ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] SET <replaceable>configuration_parameter</replaceable> FROM CURRENT
+ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET <replaceable>configuration_parameter</replaceable>
+ALTER USER { <replaceable class="parameter">role_specification</replaceable> | ALL } [ IN DATABASE <replaceable class="parameter">database_name</replaceable> ] RESET ALL
+
+<phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase>
+
+ <replaceable class="parameter">role_name</replaceable>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER USER</command> is now an alias for
+ <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>ALTER USER</command> statement is a
+ <productname>PostgreSQL</productname> extension. The SQL standard
+ leaves the definition of users to the implementation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterrole"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/alter_user_mapping.sgml b/doc/src/sgml/ref/alter_user_mapping.sgml
new file mode 100644
index 0000000..ee5aee9
--- /dev/null
+++ b/doc/src/sgml/ref/alter_user_mapping.sgml
@@ -0,0 +1,124 @@
+<!--
+doc/src/sgml/ref/alter_user_mapping.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterusermapping">
+ <indexterm zone="sql-alterusermapping">
+ <primary>ALTER USER MAPPING</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER USER MAPPING</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER USER MAPPING</refname>
+ <refpurpose>change the definition of a user mapping</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER USER MAPPING FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_ROLE | CURRENT_USER | SESSION_USER | PUBLIC }
+ SERVER <replaceable class="parameter">server_name</replaceable>
+ OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER USER MAPPING</command> changes the definition of a
+ user mapping.
+ </para>
+
+ <para>
+ The owner of a foreign server can alter user mappings for that
+ server for any user. Also, a user can alter a user mapping for
+ their own user name if <literal>USAGE</literal> privilege on the server has
+ been granted to the user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ User name of the mapping. <literal>CURRENT_ROLE</literal>, <literal>CURRENT_USER</literal>,
+ and <literal>USER</literal> match the name of the current
+ user. <literal>PUBLIC</literal> is used to match all present and future
+ user names in the system.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_name</replaceable></term>
+ <listitem>
+ <para>
+ Server name of the user mapping.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( [ ADD | SET | DROP ] <replaceable class="parameter">option</replaceable> ['<replaceable class="parameter">value</replaceable>'] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ Change options for the user mapping. The new options override
+ any previously specified
+ options. <literal>ADD</literal>, <literal>SET</literal>, and <literal>DROP</literal>
+ specify the action to be performed. <literal>ADD</literal> is assumed
+ if no operation is explicitly specified. Option names must be
+ unique; options are also validated by the server's foreign-data
+ wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change the password for user mapping <literal>bob</literal>, server <literal>foo</literal>:
+<programlisting>
+ALTER USER MAPPING FOR bob SERVER foo OPTIONS (SET password 'public');
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER USER MAPPING</command> conforms to ISO/IEC 9075-9
+ (SQL/MED). There is a subtle syntax issue: The standard omits
+ the <literal>FOR</literal> key word. Since both <literal>CREATE
+ USER MAPPING</literal> and <literal>DROP USER MAPPING</literal> use
+ <literal>FOR</literal> in analogous positions, and IBM DB2 (being
+ the other major SQL/MED implementation) also requires it
+ for <literal>ALTER USER MAPPING</literal>, PostgreSQL diverges from
+ the standard here in the interest of consistency and
+ interoperability.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createusermapping"/></member>
+ <member><xref linkend="sql-dropusermapping"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/alter_view.sgml b/doc/src/sgml/ref/alter_view.sgml
new file mode 100644
index 0000000..8bdc90a
--- /dev/null
+++ b/doc/src/sgml/ref/alter_view.sgml
@@ -0,0 +1,229 @@
+<!--
+doc/src/sgml/ref/alter_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-alterview">
+ <indexterm zone="sql-alterview">
+ <primary>ALTER VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ALTER VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ALTER VIEW</refname>
+ <refpurpose>change the definition of a view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> SET DEFAULT <replaceable class="parameter">expression</replaceable>
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ALTER [ COLUMN ] <replaceable class="parameter">column_name</replaceable> DROP DEFAULT
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> OWNER TO { <replaceable class="parameter">new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME [ COLUMN ] <replaceable class="parameter">column_name</replaceable> TO <replaceable class="parameter">new_column_name</replaceable>
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RENAME TO <replaceable class="parameter">new_name</replaceable>
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET SCHEMA <replaceable class="parameter">new_schema</replaceable>
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> SET ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] )
+ALTER VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> RESET ( <replaceable class="parameter">view_option_name</replaceable> [, ... ] )
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ALTER VIEW</command> changes various auxiliary properties
+ of a view. (If you want to modify the view's defining query,
+ use <command>CREATE OR REPLACE VIEW</command>.)
+ </para>
+
+ <para>
+ You must own the view to use <command>ALTER VIEW</command>.
+ To change a view's schema, you must also have <literal>CREATE</literal>
+ privilege on the new schema.
+ To alter the owner, you must also be a direct or indirect member of the new
+ owning role, and that role must have <literal>CREATE</literal> privilege on
+ the view's schema. (These restrictions enforce that altering the owner
+ doesn't do anything you couldn't do by dropping and recreating the view.
+ However, a superuser can alter ownership of any view anyway.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ Name of an existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_column_name</replaceable></term>
+ <listitem>
+ <para>
+ New name for an existing column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the view does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET</literal>/<literal>DROP DEFAULT</literal></term>
+ <listitem>
+ <para>
+ These forms set or remove the default value for a column.
+ A view column's default value is substituted into any
+ <command>INSERT</command> or <command>UPDATE</command> command whose target is the
+ view, before applying any rules or triggers for the view. The view's
+ default will therefore take precedence over any default values from
+ underlying relations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_owner</replaceable></term>
+ <listitem>
+ <para>
+ The user name of the new owner of the view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_name</replaceable></term>
+ <listitem>
+ <para>
+ The new name for the view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_schema</replaceable></term>
+ <listitem>
+ <para>
+ The new schema for the view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] )</literal></term>
+ <term><literal>RESET ( <replaceable class="parameter">view_option_name</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ Sets or resets a view option. Currently supported options are:
+ <variablelist>
+ <varlistentry>
+ <term><literal>check_option</literal> (<type>enum</type>)</term>
+ <listitem>
+ <para>
+ Changes the check option of the view. The value must
+ be <literal>local</literal> or <literal>cascaded</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>security_barrier</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Changes the security-barrier property of the view. The value must
+ be a Boolean value, such as <literal>true</literal>
+ or <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>security_invoker</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Changes the security-invoker property of the view. The value must
+ be a Boolean value, such as <literal>true</literal>
+ or <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ For historical reasons, <command>ALTER TABLE</command> can be used with
+ views too; but the only variants of <command>ALTER TABLE</command>
+ that are allowed with views are equivalent to the ones shown above.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To rename the view <literal>foo</literal> to
+ <literal>bar</literal>:
+<programlisting>
+ALTER VIEW foo RENAME TO bar;
+</programlisting>
+ </para>
+
+ <para>
+ To attach a default column value to an updatable view:
+<programlisting>
+CREATE TABLE base_table (id int, ts timestamptz);
+CREATE VIEW a_view AS SELECT * FROM base_table;
+ALTER VIEW a_view ALTER COLUMN ts SET DEFAULT now();
+INSERT INTO base_table(id) VALUES(1); -- ts will receive a NULL
+INSERT INTO a_view(id) VALUES(2); -- ts will receive the current time
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ALTER VIEW</command> is a <productname>PostgreSQL</productname>
+ extension of the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createview"/></member>
+ <member><xref linkend="sql-dropview"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml
new file mode 100644
index 0000000..2ba115d
--- /dev/null
+++ b/doc/src/sgml/ref/analyze.sgml
@@ -0,0 +1,321 @@
+<!--
+doc/src/sgml/ref/analyze.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-analyze">
+ <indexterm zone="sql-analyze">
+ <primary>ANALYZE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ANALYZE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ANALYZE</refname>
+ <refpurpose>collect statistics about a database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ANALYZE [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
+ANALYZE [ VERBOSE ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
+
+ VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
+ SKIP_LOCKED [ <replaceable class="parameter">boolean</replaceable> ]
+
+<phrase>and <replaceable class="parameter">table_and_columns</replaceable> is:</phrase>
+
+ <replaceable class="parameter">table_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ANALYZE</command> collects statistics about the contents
+ of tables in the database, and stores the results in the <link
+ linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>
+ system catalog. Subsequently, the query planner uses these
+ statistics to help determine the most efficient execution plans for
+ queries.
+ </para>
+
+ <para>
+ Without a <replaceable class="parameter">table_and_columns</replaceable>
+ list, <command>ANALYZE</command> processes every table and materialized view
+ in the current database that the current user has permission to analyze.
+ With a list, <command>ANALYZE</command> processes only those table(s).
+ It is further possible to give a list of column names for a table,
+ in which case only the statistics for those columns are collected.
+ </para>
+
+ <para>
+ When the option list is surrounded by parentheses, the options can be
+ written in any order. The parenthesized syntax was added in
+ <productname>PostgreSQL</productname> 11; the unparenthesized syntax
+ is deprecated.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>VERBOSE</literal></term>
+ <listitem>
+ <para>
+ Enables display of progress messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SKIP_LOCKED</literal></term>
+ <listitem>
+ <para>
+ Specifies that <command>ANALYZE</command> should not wait for any
+ conflicting locks to be released when beginning work on a relation:
+ if a relation cannot be locked immediately without waiting, the relation
+ is skipped. Note that even with this option, <command>ANALYZE</command>
+ may still block when opening the relation's indexes or when acquiring
+ sample rows from partitions, table inheritance children, and some
+ types of foreign tables. Also, while <command>ANALYZE</command>
+ ordinarily processes all partitions of specified partitioned tables,
+ this option will cause <command>ANALYZE</command> to skip all
+ partitions if there is a conflicting lock on the partitioned table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">boolean</replaceable></term>
+ <listitem>
+ <para>
+ Specifies whether the selected option should be turned on or off.
+ You can write <literal>TRUE</literal>, <literal>ON</literal>, or
+ <literal>1</literal> to enable the option, and <literal>FALSE</literal>,
+ <literal>OFF</literal>, or <literal>0</literal> to disable it. The
+ <replaceable class="parameter">boolean</replaceable> value can also
+ be omitted, in which case <literal>TRUE</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of a specific table to
+ analyze. If omitted, all regular tables, partitioned tables, and
+ materialized views in the current database are analyzed (but not
+ foreign tables). If the specified table is a partitioned table, both the
+ inheritance statistics of the partitioned table as a whole and
+ statistics of the individual partitions are updated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a specific column to analyze. Defaults to all columns.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ When <literal>VERBOSE</literal> is specified, <command>ANALYZE</command> emits
+ progress messages to indicate which table is currently being
+ processed. Various statistics about the tables are printed as well.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ To analyze a table, one must ordinarily be the table's owner or a
+ superuser. However, database owners are allowed to
+ analyze all tables in their databases, except shared catalogs.
+ (The restriction for shared catalogs means that a true database-wide
+ <command>ANALYZE</command> can only be performed by a superuser.)
+ <command>ANALYZE</command> will skip over any tables that the calling user
+ does not have permission to analyze.
+ </para>
+
+ <para>
+ Foreign tables are analyzed only when explicitly selected. Not all
+ foreign data wrappers support <command>ANALYZE</command>. If the table's
+ wrapper does not support <command>ANALYZE</command>, the command prints a
+ warning and does nothing.
+ </para>
+
+ <para>
+ In the default <productname>PostgreSQL</productname> configuration,
+ the autovacuum daemon (see <xref linkend="autovacuum"/>)
+ takes care of automatic analyzing of tables when they are first loaded
+ with data, and as they change throughout regular operation.
+ When autovacuum is disabled,
+ it is a good idea to run <command>ANALYZE</command> periodically, or
+ just after making major changes in the contents of a table. Accurate
+ statistics will help the planner to choose the most appropriate query
+ plan, and thereby improve the speed of query processing. A common
+ strategy for read-mostly databases is to run <link linkend="sql-vacuum"><command>VACUUM</command></link>
+ and <command>ANALYZE</command> once a day during a low-usage time of day.
+ (This will not be sufficient if there is heavy update activity.)
+ </para>
+
+ <para>
+ <command>ANALYZE</command>
+ requires only a read lock on the target table, so it can run in
+ parallel with other activity on the table.
+ </para>
+
+ <para>
+ The statistics collected by <command>ANALYZE</command> usually
+ include a list of some of the most common values in each column and
+ a histogram showing the approximate data distribution in each
+ column. One or both of these can be omitted if
+ <command>ANALYZE</command> deems them uninteresting (for example,
+ in a unique-key column, there are no common values) or if the
+ column data type does not support the appropriate operators. There
+ is more information about the statistics in <xref
+ linkend="maintenance"/>.
+ </para>
+
+ <para>
+ For large tables, <command>ANALYZE</command> takes a random sample
+ of the table contents, rather than examining every row. This
+ allows even very large tables to be analyzed in a small amount of
+ time. Note, however, that the statistics are only approximate, and
+ will change slightly each time <command>ANALYZE</command> is run,
+ even if the actual table contents did not change. This might result
+ in small changes in the planner's estimated costs shown by
+ <link linkend="sql-explain"><command>EXPLAIN</command></link>.
+ In rare situations, this non-determinism will cause the planner's
+ choices of query plans to change after <command>ANALYZE</command> is run.
+ To avoid this, raise the amount of statistics collected by
+ <command>ANALYZE</command>, as described below.
+ </para>
+
+ <para>
+ The extent of analysis can be controlled by adjusting the
+ <xref linkend="guc-default-statistics-target"/> configuration variable, or
+ on a column-by-column basis by setting the per-column statistics
+ target with <link linkend="sql-altertable"><command>ALTER TABLE ... ALTER COLUMN ... SET
+ STATISTICS</command></link>.
+ The target value sets the
+ maximum number of entries in the most-common-value list and the
+ maximum number of bins in the histogram. The default target value
+ is 100, but this can be adjusted up or down to trade off accuracy of
+ planner estimates against the time taken for
+ <command>ANALYZE</command> and the amount of space occupied in
+ <literal>pg_statistic</literal>. In particular, setting the
+ statistics target to zero disables collection of statistics for
+ that column. It might be useful to do that for columns that are
+ never used as part of the <literal>WHERE</literal>, <literal>GROUP BY</literal>,
+ or <literal>ORDER BY</literal> clauses of queries, since the planner will
+ have no use for statistics on such columns.
+ </para>
+
+ <para>
+ The largest statistics target among the columns being analyzed determines
+ the number of table rows sampled to prepare the statistics. Increasing
+ the target causes a proportional increase in the time and space needed
+ to do <command>ANALYZE</command>.
+ </para>
+
+ <para>
+ One of the values estimated by <command>ANALYZE</command> is the number of
+ distinct values that appear in each column. Because only a subset of the
+ rows are examined, this estimate can sometimes be quite inaccurate, even
+ with the largest possible statistics target. If this inaccuracy leads to
+ bad query plans, a more accurate value can be determined manually and then
+ installed with
+ <link linkend="sql-altertable"><command>ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)</command></link>.
+ </para>
+
+ <para>
+ If the table being analyzed has inheritance children,
+ <command>ANALYZE</command> gathers two sets of statistics: one on the rows
+ of the parent table only, and a second including rows of both the parent
+ table and all of its children. This second set of statistics is needed when
+ planning queries that process the inheritance tree as a whole. The child
+ tables themselves are not individually analyzed in this case.
+ The autovacuum daemon, however, will only consider inserts or
+ updates on the parent table itself when deciding whether to trigger an
+ automatic analyze for that table. If that table is rarely inserted into
+ or updated, the inheritance statistics will not be up to date unless you
+ run <command>ANALYZE</command> manually.
+ </para>
+
+ <para>
+ For partitioned tables, <command>ANALYZE</command> gathers statistics by
+ sampling rows from all partitions; in addition, it will recurse into each
+ partition and update its statistics. Each leaf partition is analyzed only
+ once, even with multi-level partitioning. No statistics are collected for
+ only the parent table (without data from its partitions), because with
+ partitioning it's guaranteed to be empty.
+ </para>
+
+ <para>
+ The autovacuum daemon does not process partitioned tables, nor does it
+ process inheritance parents if only the children are ever modified.
+ It is usually necessary to periodically run a manual
+ <command>ANALYZE</command> to keep the statistics of the table hierarchy
+ up to date.
+ </para>
+
+ <para>
+ If any child tables or partitions are foreign tables whose foreign
+ data wrappers do not support <command>ANALYZE</command>, those tables are
+ ignored while gathering inheritance statistics.
+ </para>
+
+ <para>
+ If the table being analyzed is completely empty, <command>ANALYZE</command>
+ will not record new statistics for that table. Any existing statistics
+ will be retained.
+ </para>
+
+ <para>
+ Each backend running <command>ANALYZE</command> will report its progress
+ in the <structname>pg_stat_progress_analyze</structname> view. See
+ <xref linkend="analyze-progress-reporting"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>ANALYZE</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-vacuum"/></member>
+ <member><xref linkend="app-vacuumdb"/></member>
+ <member><xref linkend="runtime-config-resource-vacuum-cost"/></member>
+ <member><xref linkend="autovacuum"/></member>
+ <member><xref linkend="analyze-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/begin.sgml b/doc/src/sgml/ref/begin.sgml
new file mode 100644
index 0000000..016b021
--- /dev/null
+++ b/doc/src/sgml/ref/begin.sgml
@@ -0,0 +1,161 @@
+<!--
+doc/src/sgml/ref/begin.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-begin">
+ <indexterm zone="sql-begin">
+ <primary>BEGIN</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>BEGIN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>BEGIN</refname>
+ <refpurpose>start a transaction block</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+BEGIN [ WORK | TRANSACTION ] [ <replaceable class="parameter">transaction_mode</replaceable> [, ...] ]
+
+<phrase>where <replaceable class="parameter">transaction_mode</replaceable> is one of:</phrase>
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>BEGIN</command> initiates a transaction block, that is,
+ all statements after a <command>BEGIN</command> command will be
+ executed in a single transaction until an explicit <link
+ linkend="sql-commit"><command>COMMIT</command></link> or <link
+ linkend="sql-rollback"><command>ROLLBACK</command></link> is given.
+ By default (without <command>BEGIN</command>),
+ <productname>PostgreSQL</productname> executes
+ transactions in <quote>autocommit</quote> mode, that is, each
+ statement is executed in its own transaction and a commit is
+ implicitly performed at the end of the statement (if execution was
+ successful, otherwise a rollback is done).
+ </para>
+
+ <para>
+ Statements are executed more quickly in a transaction block, because
+ transaction start/commit requires significant CPU and disk
+ activity. Execution of multiple statements inside a transaction is
+ also useful to ensure consistency when making several related changes:
+ other sessions will be unable to see the intermediate states
+ wherein not all the related updates have been done.
+ </para>
+
+ <para>
+ If the isolation level, read/write mode, or deferrable mode is specified, the new
+ transaction has those characteristics, as if
+ <link linkend="sql-set-transaction"><command>SET TRANSACTION</command></link>
+ was executed.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>WORK</literal></term>
+ <term><literal>TRANSACTION</literal></term>
+ <listitem>
+ <para>
+ Optional key words. They have no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Refer to <xref linkend="sql-set-transaction"/> for information on the meaning
+ of the other parameters to this statement.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <link linkend="sql-start-transaction"><command>START TRANSACTION</command></link> has the same functionality
+ as <command>BEGIN</command>.
+ </para>
+
+ <para>
+ Use <link linkend="sql-commit"><command>COMMIT</command></link> or
+ <link linkend="sql-rollback"><command>ROLLBACK</command></link>
+ to terminate a transaction block.
+ </para>
+
+ <para>
+ Issuing <command>BEGIN</command> when already inside a transaction block will
+ provoke a warning message. The state of the transaction is not affected.
+ To nest transactions within a transaction block, use savepoints
+ (see <xref linkend="sql-savepoint"/>).
+ </para>
+
+ <para>
+ For reasons of backwards compatibility, the commas between successive
+ <replaceable class="parameter">transaction_modes</replaceable> can be
+ omitted.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To begin a transaction block:
+
+<programlisting>
+BEGIN;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>BEGIN</command> is a <productname>PostgreSQL</productname>
+ language extension. It is equivalent to the SQL-standard command
+ <link linkend="sql-start-transaction"><command>START TRANSACTION</command></link>, whose reference page
+ contains additional compatibility information.
+ </para>
+
+ <para>
+ The <literal>DEFERRABLE</literal>
+ <replaceable class="parameter">transaction_mode</replaceable>
+ is a <productname>PostgreSQL</productname> language extension.
+ </para>
+
+ <para>
+ Incidentally, the <literal>BEGIN</literal> key word is used for a
+ different purpose in embedded SQL. You are advised to be careful
+ about the transaction semantics when porting database applications.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ <member><xref linkend="sql-start-transaction"/></member>
+ <member><xref linkend="sql-savepoint"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/call.sgml b/doc/src/sgml/ref/call.sgml
new file mode 100644
index 0000000..9e83a77
--- /dev/null
+++ b/doc/src/sgml/ref/call.sgml
@@ -0,0 +1,133 @@
+<!--
+doc/src/sgml/ref/call.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-call">
+ <indexterm zone="sql-call">
+ <primary>CALL</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CALL</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CALL</refname>
+ <refpurpose>invoke a procedure</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CALL <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> ] [, ...] )
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CALL</command> executes a procedure.
+ </para>
+
+ <para>
+ If the procedure has any output parameters, then a result row will be
+ returned, containing the values of those parameters.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argument</replaceable></term>
+ <listitem>
+ <para>
+ An argument expression for the procedure call.
+ </para>
+
+ <para>
+ Arguments can include parameter names, using the syntax
+ <literal><replaceable class="parameter">name</replaceable> =&gt; <replaceable class="parameter">value</replaceable></literal>.
+ This works the same as in ordinary function calls; see
+ <xref linkend="sql-syntax-calling-funcs"/> for details.
+ </para>
+
+ <para>
+ Arguments must be supplied for all procedure parameters that lack
+ defaults, including <literal>OUT</literal> parameters. However,
+ arguments matching <literal>OUT</literal> parameters are not evaluated,
+ so it's customary to just write <literal>NULL</literal> for them.
+ (Writing something else for an <literal>OUT</literal> parameter
+ might cause compatibility problems with
+ future <productname>PostgreSQL</productname> versions.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The user must have <literal>EXECUTE</literal> privilege on the procedure in
+ order to be allowed to invoke it.
+ </para>
+
+ <para>
+ To call a function (not a procedure), use <command>SELECT</command> instead.
+ </para>
+
+ <para>
+ If <command>CALL</command> is executed in a transaction block, then the
+ called procedure cannot execute transaction control statements.
+ Transaction control statements are only allowed if <command>CALL</command>
+ is executed in its own transaction.
+ </para>
+
+ <para>
+ <application>PL/pgSQL</application> handles output parameters
+ in <command>CALL</command> commands differently;
+ see <xref linkend="plpgsql-statements-calling-procedure"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+<programlisting>
+CALL do_db_maintenance();
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CALL</command> conforms to the SQL standard,
+ except for the handling of output parameters. The standard
+ says that users should write variables to receive the values
+ of output parameters.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createprocedure"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/checkpoint.sgml b/doc/src/sgml/ref/checkpoint.sgml
new file mode 100644
index 0000000..28a1d71
--- /dev/null
+++ b/doc/src/sgml/ref/checkpoint.sgml
@@ -0,0 +1,69 @@
+<!--
+doc/src/sgml/ref/checkpoint.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-checkpoint">
+ <indexterm zone="sql-checkpoint">
+ <primary>CHECKPOINT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CHECKPOINT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CHECKPOINT</refname>
+ <refpurpose>force a write-ahead log checkpoint</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CHECKPOINT
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ A checkpoint is a point in the write-ahead log sequence at which
+ all data files have been updated to reflect the information in the
+ log. All data files will be flushed to disk. Refer to
+ <xref linkend="wal-configuration"/> for more details about what happens
+ during a checkpoint.
+ </para>
+
+ <para>
+ The <command>CHECKPOINT</command> command forces an immediate
+ checkpoint when the command is issued, without waiting for a
+ regular checkpoint scheduled by the system (controlled by the settings in
+ <xref linkend="runtime-config-wal-checkpoints"/>).
+ <command>CHECKPOINT</command> is not intended for use during normal
+ operation.
+ </para>
+
+ <para>
+ If executed during recovery, the <command>CHECKPOINT</command> command
+ will force a restartpoint (see <xref linkend="wal-configuration"/>)
+ rather than writing a new checkpoint.
+ </para>
+
+ <para>
+ Only superusers or users with the privileges of
+ the <link linkend="predefined-roles-table"><literal>pg_checkpoint</literal></link>
+ role can call <command>CHECKPOINT</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>CHECKPOINT</command> command is a
+ <productname>PostgreSQL</productname> language extension.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/close.sgml b/doc/src/sgml/ref/close.sgml
new file mode 100644
index 0000000..32d20ed
--- /dev/null
+++ b/doc/src/sgml/ref/close.sgml
@@ -0,0 +1,132 @@
+<!--
+doc/src/sgml/ref/close.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-close">
+ <indexterm zone="sql-close">
+ <primary>CLOSE</primary>
+ </indexterm>
+
+ <indexterm zone="sql-close">
+ <primary>cursor</primary>
+ <secondary>CLOSE</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CLOSE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CLOSE</refname>
+ <refpurpose>close a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CLOSE { <replaceable class="parameter">name</replaceable> | ALL }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CLOSE</command> frees the resources associated with an open cursor.
+ After the cursor is closed, no subsequent operations
+ are allowed on it. A cursor should be closed when it is
+ no longer needed.
+ </para>
+
+ <para>
+ Every non-holdable open cursor is implicitly closed when a
+ transaction is terminated by <command>COMMIT</command> or
+ <command>ROLLBACK</command>. A holdable cursor is implicitly
+ closed if the transaction that created it aborts via
+ <command>ROLLBACK</command>. If the creating transaction
+ successfully commits, the holdable cursor remains open until an
+ explicit <command>CLOSE</command> is executed, or the client
+ disconnects.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an open cursor to close.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Close all open cursors.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <productname>PostgreSQL</productname> does not have an explicit
+ <command>OPEN</command> cursor statement; a cursor is considered
+ open when it is declared. Use the
+ <link linkend="sql-declare"><command>DECLARE</command></link>
+ statement to declare a cursor.
+ </para>
+
+ <para>
+ You can see all available cursors by querying the <link
+ linkend="view-pg-cursors"><structname>pg_cursors</structname></link> system view.
+ </para>
+
+ <para>
+ If a cursor is closed after a savepoint which is later rolled back,
+ the <command>CLOSE</command> is not rolled back; that is, the cursor
+ remains closed.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Close the cursor <literal>liahona</literal>:
+<programlisting>
+CLOSE liahona;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CLOSE</command> is fully conforming with the SQL
+ standard. <command>CLOSE ALL</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-declare"/></member>
+ <member><xref linkend="sql-fetch"/></member>
+ <member><xref linkend="sql-move"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/cluster.sgml b/doc/src/sgml/ref/cluster.sgml
new file mode 100644
index 0000000..c37f423
--- /dev/null
+++ b/doc/src/sgml/ref/cluster.sgml
@@ -0,0 +1,259 @@
+<!--
+doc/src/sgml/ref/cluster.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-cluster">
+ <indexterm zone="sql-cluster">
+ <primary>CLUSTER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CLUSTER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CLUSTER</refname>
+ <refpurpose>cluster a table according to an index</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CLUSTER [VERBOSE] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
+CLUSTER ( <replaceable class="parameter">option</replaceable> [, ...] ) <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">index_name</replaceable> ]
+CLUSTER [VERBOSE]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
+
+ VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CLUSTER</command> instructs <productname>PostgreSQL</productname>
+ to cluster the table specified
+ by <replaceable class="parameter">table_name</replaceable>
+ based on the index specified by
+ <replaceable class="parameter">index_name</replaceable>. The index must
+ already have been defined on
+ <replaceable class="parameter">table_name</replaceable>.
+ </para>
+
+ <para>
+ When a table is clustered, it is physically reordered
+ based on the index information. Clustering is a one-time operation:
+ when the table is subsequently updated, the changes are
+ not clustered. That is, no attempt is made to store new or
+ updated rows according to their index order. (If one wishes, one can
+ periodically recluster by issuing the command again. Also, setting
+ the table's <literal>fillfactor</literal> storage parameter to less than
+ 100% can aid in preserving cluster ordering during updates, since updated
+ rows are kept on the same page if enough space is available there.)
+ </para>
+
+ <para>
+ When a table is clustered, <productname>PostgreSQL</productname>
+ remembers which index it was clustered by. The form
+ <command>CLUSTER <replaceable class="parameter">table_name</replaceable></command>
+ reclusters the table using the same index as before. You can also
+ use the <literal>CLUSTER</literal> or <literal>SET WITHOUT CLUSTER</literal>
+ forms of <link linkend="sql-altertable"><command>ALTER TABLE</command></link> to set the index to be used for
+ future cluster operations, or to clear any previous setting.
+ </para>
+
+ <para>
+ <command>CLUSTER</command> without any parameter reclusters all the
+ previously-clustered tables in the current database that the calling user
+ owns, or all such tables if called by a superuser. This
+ form of <command>CLUSTER</command> cannot be executed inside a transaction
+ block.
+ </para>
+
+ <para>
+ When a table is being clustered, an <literal>ACCESS
+ EXCLUSIVE</literal> lock is acquired on it. This prevents any other
+ database operations (both reads and writes) from operating on the
+ table until the <command>CLUSTER</command> is finished.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VERBOSE</literal></term>
+ <listitem>
+ <para>
+ Prints a progress report as each table is clustered.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">boolean</replaceable></term>
+ <listitem>
+ <para>
+ Specifies whether the selected option should be turned on or off.
+ You can write <literal>TRUE</literal>, <literal>ON</literal>, or
+ <literal>1</literal> to enable the option, and <literal>FALSE</literal>,
+ <literal>OFF</literal>, or <literal>0</literal> to disable it. The
+ <replaceable class="parameter">boolean</replaceable> value can also
+ be omitted, in which case <literal>TRUE</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ In cases where you are accessing single rows randomly
+ within a table, the actual order of the data in the
+ table is unimportant. However, if you tend to access some
+ data more than others, and there is an index that groups
+ them together, you will benefit from using <command>CLUSTER</command>.
+ If you are requesting a range of indexed values from a table, or a
+ single indexed value that has multiple rows that match,
+ <command>CLUSTER</command> will help because once the index identifies the
+ table page for the first row that matches, all other rows
+ that match are probably already on the same table page,
+ and so you save disk accesses and speed up the query.
+ </para>
+
+ <para>
+ <command>CLUSTER</command> can re-sort the table using either an index scan
+ on the specified index, or (if the index is a b-tree) a sequential
+ scan followed by sorting. It will attempt to choose the method that
+ will be faster, based on planner cost parameters and available statistical
+ information.
+ </para>
+
+ <para>
+ When an index scan is used, a temporary copy of the table is created that
+ contains the table data in the index order. Temporary copies of each
+ index on the table are created as well. Therefore, you need free space on
+ disk at least equal to the sum of the table size and the index sizes.
+ </para>
+
+ <para>
+ When a sequential scan and sort is used, a temporary sort file is
+ also created, so that the peak temporary space requirement is as much
+ as double the table size, plus the index sizes. This method is often
+ faster than the index scan method, but if the disk space requirement is
+ intolerable, you can disable this choice by temporarily setting <xref
+ linkend="guc-enable-sort"/> to <literal>off</literal>.
+ </para>
+
+ <para>
+ It is advisable to set <xref linkend="guc-maintenance-work-mem"/> to
+ a reasonably large value (but not more than the amount of RAM you can
+ dedicate to the <command>CLUSTER</command> operation) before clustering.
+ </para>
+
+ <para>
+ Because the planner records statistics about the ordering of
+ tables, it is advisable to run <link linkend="sql-analyze"><command>ANALYZE</command></link>
+ on the newly clustered table.
+ Otherwise, the planner might make poor choices of query plans.
+ </para>
+
+ <para>
+ Because <command>CLUSTER</command> remembers which indexes are clustered,
+ one can cluster the tables one wants clustered manually the first time,
+ then set up a periodic maintenance script that executes
+ <command>CLUSTER</command> without any parameters, so that the desired tables
+ are periodically reclustered.
+ </para>
+
+ <para>
+ Each backend running <command>CLUSTER</command> will report its progress
+ in the <structname>pg_stat_progress_cluster</structname> view. See
+ <xref linkend="cluster-progress-reporting"/> for details.
+ </para>
+
+ <para>
+ Clustering a partitioned table clusters each of its partitions using the
+ partition of the specified partitioned index. When clustering a partitioned
+ table, the index may not be omitted.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Cluster the table <literal>employees</literal> on the basis of
+ its index <literal>employees_ind</literal>:
+<programlisting>
+CLUSTER employees USING employees_ind;
+</programlisting>
+ </para>
+
+ <para>
+ Cluster the <literal>employees</literal> table using the same
+ index that was used before:
+<programlisting>
+CLUSTER employees;
+</programlisting>
+ </para>
+
+ <para>
+ Cluster all tables in the database that have previously been clustered:
+<programlisting>
+CLUSTER;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CLUSTER</command> statement in the SQL standard.
+ </para>
+
+ <para>
+ The syntax
+<synopsis>
+CLUSTER <replaceable class="parameter">index_name</replaceable> ON <replaceable class="parameter">table_name</replaceable>
+</synopsis>
+ is also supported for compatibility with pre-8.3 <productname>PostgreSQL</productname>
+ versions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-clusterdb"/></member>
+ <member><xref linkend="cluster-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
new file mode 100644
index 0000000..c838b22
--- /dev/null
+++ b/doc/src/sgml/ref/clusterdb.sgml
@@ -0,0 +1,352 @@
+<!--
+doc/src/sgml/ref/clusterdb.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-clusterdb">
+ <indexterm zone="app-clusterdb">
+ <primary>clusterdb</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>clusterdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>clusterdb</refname>
+ <refpurpose>cluster a <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>clusterdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>--table</option></arg>
+ <arg choice="plain"><option>-t</option></arg>
+ </group>
+ <replaceable>table</replaceable>
+ </arg>
+ </arg>
+
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>clusterdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
+ <group choice="plain"><arg choice="plain"><option>--all</option></arg><arg choice="plain"><option>-a</option></arg></group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>clusterdb</application> is a utility for reclustering tables
+ in a <productname>PostgreSQL</productname> database. It finds tables
+ that have previously been clustered, and clusters them again on the same
+ index that was last used. Tables that have never been clustered are not
+ affected.
+ </para>
+
+ <para>
+ <application>clusterdb</application> is a wrapper around the SQL
+ command <xref linkend="sql-cluster"/>.
+ There is no effective difference between clustering databases via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>clusterdb</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--all</option></term>
+ <listitem>
+ <para>
+ Cluster all databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option><optional>-d</optional> <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be clustered,
+ when <option>-a</option>/<option>--all</option> is not used.
+ If this is not specified, the database name is read
+ from the environment variable <envar>PGDATABASE</envar>. If
+ that is not set, the user name specified for the connection is
+ used. The <replaceable>dbname</replaceable> can be a <link
+ linkend="libpq-connstring">connection string</link>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>clusterdb</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Do not display progress messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">table</replaceable></option></term>
+ <term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
+ <listitem>
+ <para>
+ Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Print detailed information during processing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>clusterdb</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>clusterdb</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ <application>clusterdb</application> also accepts
+ the following command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>clusterdb</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>clusterdb</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>clusterdb</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to to discover which
+ databases should be clustered,
+ when <option>-a</option>/<option>--all</option> is used.
+ If not specified, the <literal>postgres</literal> database will be used,
+ or if that does not exist, <literal>template1</literal> will be used.
+ This can be a <link linkend="libpq-connstring">connection
+ string</link>. If so, connection string parameters will override any
+ conflicting command line options. Also, connection string parameters
+ other than the database name itself will be re-used when connecting
+ to other databases.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-cluster"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To cluster the database <literal>test</literal>:
+<screen>
+<prompt>$ </prompt><userinput>clusterdb test</userinput>
+</screen>
+ </para>
+
+ <para>
+ To cluster a single table
+ <literal>foo</literal> in a database named
+ <literal>xyzzy</literal>:
+<screen>
+<prompt>$ </prompt><userinput>clusterdb --table=foo xyzzy</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-cluster"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/comment.sgml b/doc/src/sgml/ref/comment.sgml
new file mode 100644
index 0000000..fd3f465
--- /dev/null
+++ b/doc/src/sgml/ref/comment.sgml
@@ -0,0 +1,374 @@
+<!--
+doc/src/sgml/ref/comment.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-comment">
+ <indexterm zone="sql-comment">
+ <primary>COMMENT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>COMMENT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>COMMENT</refname>
+ <refpurpose>define or change the comment of an object</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+COMMENT ON
+{
+ ACCESS METHOD <replaceable class="parameter">object_name</replaceable> |
+ AGGREGATE <replaceable class="parameter">aggregate_name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) |
+ CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>) |
+ COLLATION <replaceable class="parameter">object_name</replaceable> |
+ COLUMN <replaceable class="parameter">relation_name</replaceable>.<replaceable class="parameter">column_name</replaceable> |
+ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ON <replaceable class="parameter">table_name</replaceable> |
+ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ON DOMAIN <replaceable class="parameter">domain_name</replaceable> |
+ CONVERSION <replaceable class="parameter">object_name</replaceable> |
+ DATABASE <replaceable class="parameter">object_name</replaceable> |
+ DOMAIN <replaceable class="parameter">object_name</replaceable> |
+ EXTENSION <replaceable class="parameter">object_name</replaceable> |
+ EVENT TRIGGER <replaceable class="parameter">object_name</replaceable> |
+ FOREIGN DATA WRAPPER <replaceable class="parameter">object_name</replaceable> |
+ FOREIGN TABLE <replaceable class="parameter">object_name</replaceable> |
+ FUNCTION <replaceable class="parameter">function_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ INDEX <replaceable class="parameter">object_name</replaceable> |
+ LARGE OBJECT <replaceable class="parameter">large_object_oid</replaceable> |
+ MATERIALIZED VIEW <replaceable class="parameter">object_name</replaceable> |
+ OPERATOR <replaceable class="parameter">operator_name</replaceable> (<replaceable class="parameter">left_type</replaceable>, <replaceable class="parameter">right_type</replaceable>) |
+ OPERATOR CLASS <replaceable class="parameter">object_name</replaceable> USING <replaceable class="parameter">index_method</replaceable> |
+ OPERATOR FAMILY <replaceable class="parameter">object_name</replaceable> USING <replaceable class="parameter">index_method</replaceable> |
+ POLICY <replaceable class="parameter">policy_name</replaceable> ON <replaceable class="parameter">table_name</replaceable> |
+ [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">object_name</replaceable> |
+ PROCEDURE <replaceable class="parameter">procedure_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ PUBLICATION <replaceable class="parameter">object_name</replaceable> |
+ ROLE <replaceable class="parameter">object_name</replaceable> |
+ ROUTINE <replaceable class="parameter">routine_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ RULE <replaceable class="parameter">rule_name</replaceable> ON <replaceable class="parameter">table_name</replaceable> |
+ SCHEMA <replaceable class="parameter">object_name</replaceable> |
+ SEQUENCE <replaceable class="parameter">object_name</replaceable> |
+ SERVER <replaceable class="parameter">object_name</replaceable> |
+ STATISTICS <replaceable class="parameter">object_name</replaceable> |
+ SUBSCRIPTION <replaceable class="parameter">object_name</replaceable> |
+ TABLE <replaceable class="parameter">object_name</replaceable> |
+ TABLESPACE <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH CONFIGURATION <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH DICTIONARY <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH PARSER <replaceable class="parameter">object_name</replaceable> |
+ TEXT SEARCH TEMPLATE <replaceable class="parameter">object_name</replaceable> |
+ TRANSFORM FOR <replaceable>type_name</replaceable> LANGUAGE <replaceable>lang_name</replaceable> |
+ TRIGGER <replaceable class="parameter">trigger_name</replaceable> ON <replaceable class="parameter">table_name</replaceable> |
+ TYPE <replaceable class="parameter">object_name</replaceable> |
+ VIEW <replaceable class="parameter">object_name</replaceable>
+} IS { <replaceable class="parameter">string_literal</replaceable> | NULL }
+
+<phrase>where <replaceable>aggregate_signature</replaceable> is:</phrase>
+
+* |
+[ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] |
+[ [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] ] ORDER BY [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>COMMENT</command> stores a comment about a database object.
+ </para>
+
+ <para>
+ Only one comment string is stored for each object, so to modify a comment,
+ issue a new <command>COMMENT</command> command for the same object. To remove a
+ comment, write <literal>NULL</literal> in place of the text string.
+ Comments are automatically dropped when their object is dropped.
+ </para>
+
+ <para>
+ A <literal>SHARE UPDATE EXCLUSIVE</literal> lock is acquired on the
+ object to be commented.
+ </para>
+
+ <para>
+ For most kinds of object, only the object's owner can set the comment.
+ Roles don't have owners, so the rule for <literal>COMMENT ON ROLE</literal> is
+ that you must be superuser to comment on a superuser role, or have the
+ <literal>CREATEROLE</literal> privilege to comment on non-superuser roles.
+ Likewise, access methods don't have owners either; you must be superuser
+ to comment on an access method.
+ Of course, a superuser can comment on anything.
+ </para>
+
+ <para>
+ Comments can be viewed using <application>psql</application>'s
+ <command>\d</command> family of commands.
+ Other user interfaces to retrieve comments can be built atop
+ the same built-in functions that <application>psql</application> uses, namely
+ <function>obj_description</function>, <function>col_description</function>,
+ and <function>shobj_description</function>
+ (see <xref linkend="functions-info-comment-table"/>).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">object_name</replaceable></term>
+ <term><replaceable class="parameter">relation_name</replaceable>.<replaceable>column_name</replaceable></term>
+ <term><replaceable class="parameter">aggregate_name</replaceable></term>
+ <term><replaceable class="parameter">constraint_name</replaceable></term>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <term><replaceable class="parameter">operator_name</replaceable></term>
+ <term><replaceable class="parameter">policy_name</replaceable></term>
+ <term><replaceable class="parameter">procedure_name</replaceable></term>
+ <term><replaceable class="parameter">routine_name</replaceable></term>
+ <term><replaceable class="parameter">rule_name</replaceable></term>
+ <term><replaceable class="parameter">trigger_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the object to be commented. Names of objects that reside in
+ schemas (tables, functions, etc.) can be
+ schema-qualified. When commenting on a column,
+ <replaceable class="parameter">relation_name</replaceable> must refer
+ to a table, view, composite type, or foreign table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <term><replaceable class="parameter">domain_name</replaceable></term>
+ <listitem>
+ <para>
+ When creating a comment on a constraint, a trigger, a rule or
+ a policy these parameters specify the name of the table or domain on
+ which that object is defined.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>source_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of the source data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>target_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of the target data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+ <listitem>
+ <para>
+ The mode of a function, procedure, or aggregate
+ argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ Note that <command>COMMENT</command> does not actually pay
+ any attention to <literal>OUT</literal> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <literal>IN</literal>, <literal>INOUT</literal>,
+ and <literal>VARIADIC</literal> arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function, procedure, or aggregate argument.
+ Note that <command>COMMENT</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+ <listitem>
+ <para>
+ The data type of a function, procedure, or aggregate argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">large_object_oid</replaceable></term>
+ <listitem>
+ <para>
+ The OID of the large object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">left_type</replaceable></term>
+ <term><replaceable class="parameter">right_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type(s) of the operator's arguments (optionally
+ schema-qualified). Write <literal>NONE</literal> for the missing argument
+ of a prefix operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROCEDURAL</literal></term>
+ <listitem>
+ <para>
+ This is a noise word.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>type_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the data type of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>lang_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the language of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">string_literal</replaceable></term>
+ <listitem>
+ <para>
+ The new comment contents, written as a string literal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULL</literal></term>
+ <listitem>
+ <para>
+ Write <literal>NULL</literal> to drop the comment.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ There is presently no security mechanism for viewing comments: any user
+ connected to a database can see all the comments for objects in
+ that database. For shared objects such as
+ databases, roles, and tablespaces, comments are stored globally so any
+ user connected to any database in the cluster can see all the comments
+ for shared objects. Therefore, don't put security-critical
+ information in comments.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Attach a comment to the table <literal>mytable</literal>:
+
+<programlisting>
+COMMENT ON TABLE mytable IS 'This is my table.';
+</programlisting>
+
+ Remove it again:
+
+<programlisting>
+COMMENT ON TABLE mytable IS NULL;
+</programlisting>
+ </para>
+
+ <para>
+ Some more examples:
+
+<programlisting>
+COMMENT ON ACCESS METHOD gin IS 'GIN index access method';
+COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
+COMMENT ON CAST (text AS int4) IS 'Allow casts from text to int4';
+COMMENT ON COLLATION "fr_CA" IS 'Canadian French';
+COMMENT ON COLUMN my_table.my_column IS 'Employee ID number';
+COMMENT ON CONVERSION my_conv IS 'Conversion to UTF8';
+COMMENT ON CONSTRAINT bar_col_cons ON bar IS 'Constrains column col';
+COMMENT ON CONSTRAINT dom_col_constr ON DOMAIN dom IS 'Constrains col of domain';
+COMMENT ON DATABASE my_database IS 'Development Database';
+COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
+COMMENT ON EVENT TRIGGER abort_ddl IS 'Aborts all DDL commands';
+COMMENT ON EXTENSION hstore IS 'implements the hstore data type';
+COMMENT ON FOREIGN DATA WRAPPER mywrapper IS 'my foreign data wrapper';
+COMMENT ON FOREIGN TABLE my_foreign_table IS 'Employee Information in other database';
+COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral';
+COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee ID';
+COMMENT ON LANGUAGE plpython IS 'Python support for stored procedures';
+COMMENT ON LARGE OBJECT 346344 IS 'Planning document';
+COMMENT ON MATERIALIZED VIEW my_matview IS 'Summary of order history';
+COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts';
+COMMENT ON OPERATOR - (NONE, integer) IS 'Unary minus';
+COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for btrees';
+COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'all integer operators for btrees';
+COMMENT ON POLICY my_policy ON mytable IS 'Filter rows by users';
+COMMENT ON PROCEDURE my_proc (integer, integer) IS 'Runs a report';
+COMMENT ON PUBLICATION alltables IS 'Publishes all operations on all tables';
+COMMENT ON ROLE my_role IS 'Administration group for finance tables';
+COMMENT ON ROUTINE my_routine (integer, integer) IS 'Runs a routine (which is a function or procedure)';
+COMMENT ON RULE my_rule ON my_table IS 'Logs updates of employee records';
+COMMENT ON SCHEMA my_schema IS 'Departmental data';
+COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
+COMMENT ON SERVER myserver IS 'my foreign server';
+COMMENT ON STATISTICS my_statistics IS 'Improves planner row estimations';
+COMMENT ON SUBSCRIPTION alltables IS 'Subscription for all operations on all tables';
+COMMENT ON TABLE my_schema.my_table IS 'Employee Information';
+COMMENT ON TABLESPACE my_tablespace IS 'Tablespace for indexes';
+COMMENT ON TEXT SEARCH CONFIGURATION my_config IS 'Special word filtering';
+COMMENT ON TEXT SEARCH DICTIONARY swedish IS 'Snowball stemmer for Swedish language';
+COMMENT ON TEXT SEARCH PARSER my_parser IS 'Splits text into words';
+COMMENT ON TEXT SEARCH TEMPLATE snowball IS 'Snowball stemmer';
+COMMENT ON TRANSFORM FOR hstore LANGUAGE plpython3u IS 'Transform between hstore and Python dict';
+COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for RI';
+COMMENT ON TYPE complex IS 'Complex number data type';
+COMMENT ON VIEW my_view IS 'View of departmental costs';
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>COMMENT</command> command in the SQL standard.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/commit.sgml b/doc/src/sgml/ref/commit.sgml
new file mode 100644
index 0000000..5f244cd
--- /dev/null
+++ b/doc/src/sgml/ref/commit.sgml
@@ -0,0 +1,112 @@
+<!--
+doc/src/sgml/ref/commit.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-commit">
+ <indexterm zone="sql-commit">
+ <primary>COMMIT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>COMMIT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>COMMIT</refname>
+ <refpurpose>commit the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>COMMIT</command> commits the current transaction. All
+ changes made by the transaction become visible to others
+ and are guaranteed to be durable if a crash occurs.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <indexterm zone="sql-commit-chain">
+ <primary>chained transactions</primary>
+ </indexterm>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>WORK</literal></term>
+ <term><literal>TRANSACTION</literal></term>
+ <listitem>
+ <para>
+ Optional key words. They have no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-commit-chain">
+ <term><literal>AND CHAIN</literal></term>
+ <listitem>
+ <para>
+ If <literal>AND CHAIN</literal> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <xref
+ linkend="sql-set-transaction"/>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <xref linkend="sql-rollback"/> to
+ abort a transaction.
+ </para>
+
+ <para>
+ Issuing <command>COMMIT</command> when not inside a transaction does
+ no harm, but it will provoke a warning message. <command>COMMIT AND
+ CHAIN</command> when not inside a transaction is an error.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To commit the current transaction and make all changes permanent:
+<programlisting>
+COMMIT;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The command <command>COMMIT</command> conforms to the SQL standard. The
+ form <literal>COMMIT TRANSACTION</literal> is a PostgreSQL extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/commit_prepared.sgml b/doc/src/sgml/ref/commit_prepared.sgml
new file mode 100644
index 0000000..7299f73
--- /dev/null
+++ b/doc/src/sgml/ref/commit_prepared.sgml
@@ -0,0 +1,107 @@
+<!--
+doc/src/sgml/ref/commit_prepared.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-commit-prepared">
+ <indexterm zone="sql-commit-prepared">
+ <primary>COMMIT PREPARED</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>COMMIT PREPARED</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>COMMIT PREPARED</refname>
+ <refpurpose>commit a transaction that was earlier prepared for two-phase commit</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+COMMIT PREPARED <replaceable class="parameter">transaction_id</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>COMMIT PREPARED</command> commits a transaction that is in
+ prepared state.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">transaction_id</replaceable></term>
+ <listitem>
+ <para>
+ The transaction identifier of the transaction that is to be
+ committed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ To commit a prepared transaction, you must be either the same user that
+ executed the transaction originally, or a superuser. But you do not
+ have to be in the same session that executed the transaction.
+ </para>
+
+ <para>
+ This command cannot be executed inside a transaction block. The prepared
+ transaction is committed immediately.
+ </para>
+
+ <para>
+ All currently available prepared transactions are listed in the
+ <link linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>
+ system view.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-commit-prepared-examples">
+ <title>Examples</title>
+ <para>
+ Commit the transaction identified by the transaction
+ identifier <literal>foobar</literal>:
+
+<programlisting>
+COMMIT PREPARED 'foobar';
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>COMMIT PREPARED</command> is a
+ <productname>PostgreSQL</productname> extension. It is intended for use by
+ external transaction management systems, some of which are covered by
+ standards (such as X/Open XA), but the SQL side of those systems is not
+ standardized.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-prepare-transaction"/></member>
+ <member><xref linkend="sql-rollback-prepared"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
new file mode 100644
index 0000000..63afa0d
--- /dev/null
+++ b/doc/src/sgml/ref/copy.sgml
@@ -0,0 +1,1081 @@
+<!--
+doc/src/sgml/ref/copy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-copy">
+ <indexterm zone="sql-copy">
+ <primary>COPY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>COPY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>COPY</refname>
+ <refpurpose>copy data between a file and a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+COPY <replaceable class="parameter">table_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+ FROM { '<replaceable class="parameter">filename</replaceable>' | PROGRAM '<replaceable class="parameter">command</replaceable>' | STDIN }
+ [ [ WITH ] ( <replaceable class="parameter">option</replaceable> [, ...] ) ]
+ [ WHERE <replaceable class="parameter">condition</replaceable> ]
+
+COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ] | ( <replaceable class="parameter">query</replaceable> ) }
+ TO { '<replaceable class="parameter">filename</replaceable>' | PROGRAM '<replaceable class="parameter">command</replaceable>' | STDOUT }
+ [ [ WITH ] ( <replaceable class="parameter">option</replaceable> [, ...] ) ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
+
+ FORMAT <replaceable class="parameter">format_name</replaceable>
+ FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
+ NULL '<replaceable class="parameter">null_string</replaceable>'
+ HEADER [ <replaceable class="parameter">boolean</replaceable> | MATCH ]
+ QUOTE '<replaceable class="parameter">quote_character</replaceable>'
+ ESCAPE '<replaceable class="parameter">escape_character</replaceable>'
+ FORCE_QUOTE { ( <replaceable class="parameter">column_name</replaceable> [, ...] ) | * }
+ FORCE_NOT_NULL ( <replaceable class="parameter">column_name</replaceable> [, ...] )
+ FORCE_NULL ( <replaceable class="parameter">column_name</replaceable> [, ...] )
+ ENCODING '<replaceable class="parameter">encoding_name</replaceable>'
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>COPY</command> moves data between
+ <productname>PostgreSQL</productname> tables and standard file-system
+ files. <command>COPY TO</command> copies the contents of a table
+ <emphasis>to</emphasis> a file, while <command>COPY FROM</command> copies
+ data <emphasis>from</emphasis> a file to a table (appending the data to
+ whatever is in the table already). <command>COPY TO</command>
+ can also copy the results of a <command>SELECT</command> query.
+ </para>
+
+ <para>
+ If a column list is specified, <command>COPY TO</command> copies only
+ the data in the specified columns to the file. For <command>COPY
+ FROM</command>, each field in the file is inserted, in order, into the
+ specified column. Table columns not specified in the <command>COPY
+ FROM</command> column list will receive their default values.
+ </para>
+
+ <para>
+ <command>COPY</command> with a file name instructs the
+ <productname>PostgreSQL</productname> server to directly read from
+ or write to a file. The file must be accessible by the
+ <productname>PostgreSQL</productname> user (the user ID the server
+ runs as) and the name must be specified from the viewpoint of the
+ server. When <literal>PROGRAM</literal> is specified, the server
+ executes the given command and reads from the standard output of the
+ program, or writes to the standard input of the program. The command
+ must be specified from the viewpoint of the server, and be executable
+ by the <productname>PostgreSQL</productname> user. When
+ <literal>STDIN</literal> or <literal>STDOUT</literal> is
+ specified, data is transmitted via the connection between the
+ client and the server.
+ </para>
+
+ <para>
+ Each backend running <command>COPY</command> will report its progress
+ in the <structname>pg_stat_progress_copy</structname> view. See
+ <xref linkend="copy-progress-reporting"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ An optional list of columns to be copied. If no column list is
+ specified, all columns of the table except generated columns will be
+ copied.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">query</replaceable></term>
+ <listitem>
+ <para>
+ A <link linkend="sql-select"><command>SELECT</command></link>,
+ <link linkend="sql-values"><command>VALUES</command></link>,
+ <link linkend="sql-insert"><command>INSERT</command></link>,
+ <link linkend="sql-update"><command>UPDATE</command></link>, or
+ <link linkend="sql-delete"><command>DELETE</command></link> command whose results are to be
+ copied. Note that parentheses are required around the query.
+ </para>
+ <para>
+ For <command>INSERT</command>, <command>UPDATE</command> and
+ <command>DELETE</command> queries a RETURNING clause must be provided,
+ and the target relation must not have a conditional rule, nor
+ an <literal>ALSO</literal> rule, nor an <literal>INSTEAD</literal> rule
+ that expands to multiple statements.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">filename</replaceable></term>
+ <listitem>
+ <para>
+ The path name of the input or output file. An input file name can be
+ an absolute or relative path, but an output file name must be an absolute
+ path. Windows users might need to use an <literal>E''</literal> string and
+ double any backslashes used in the path name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROGRAM</literal></term>
+ <listitem>
+ <para>
+ A command to execute. In <command>COPY FROM</command>, the input is
+ read from standard output of the command, and in <command>COPY TO</command>,
+ the output is written to the standard input of the command.
+ </para>
+ <para>
+ Note that the command is invoked by the shell, so if you need to pass
+ any arguments to shell command that come from an untrusted source, you
+ must be careful to strip or escape any special characters that might
+ have a special meaning for the shell. For security reasons, it is best
+ to use a fixed command string, or at least avoid passing any user input
+ in it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>STDIN</literal></term>
+ <listitem>
+ <para>
+ Specifies that input comes from the client application.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>STDOUT</literal></term>
+ <listitem>
+ <para>
+ Specifies that output goes to the client application.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">boolean</replaceable></term>
+ <listitem>
+ <para>
+ Specifies whether the selected option should be turned on or off.
+ You can write <literal>TRUE</literal>, <literal>ON</literal>, or
+ <literal>1</literal> to enable the option, and <literal>FALSE</literal>,
+ <literal>OFF</literal>, or <literal>0</literal> to disable it. The
+ <replaceable class="parameter">boolean</replaceable> value can also
+ be omitted, in which case <literal>TRUE</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORMAT</literal></term>
+ <listitem>
+ <para>
+ Selects the data format to be read or written:
+ <literal>text</literal>,
+ <literal>csv</literal> (Comma Separated Values),
+ or <literal>binary</literal>.
+ The default is <literal>text</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FREEZE</literal></term>
+ <listitem>
+ <para>
+ Requests copying the data with rows already frozen, just as they
+ would be after running the <command>VACUUM FREEZE</command> command.
+ This is intended as a performance option for initial data loading.
+ Rows will be frozen only if the table being loaded has been created
+ or truncated in the current subtransaction, there are no cursors
+ open and there are no older snapshots held by this transaction. It is
+ currently not possible to perform a <command>COPY FREEZE</command> on
+ a partitioned table.
+ </para>
+ <para>
+ Note that all other sessions will immediately be able to see the data
+ once it has been successfully loaded. This violates the normal rules
+ of MVCC visibility and users specifying should be aware of the
+ potential problems this might cause.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DELIMITER</literal></term>
+ <listitem>
+ <para>
+ Specifies the character that separates columns within each row
+ (line) of the file. The default is a tab character in text format,
+ a comma in <literal>CSV</literal> format.
+ This must be a single one-byte character.
+ This option is not allowed when using <literal>binary</literal> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULL</literal></term>
+ <listitem>
+ <para>
+ Specifies the string that represents a null value. The default is
+ <literal>\N</literal> (backslash-N) in text format, and an unquoted empty
+ string in <literal>CSV</literal> format. You might prefer an
+ empty string even in text format for cases where you don't want to
+ distinguish nulls from empty strings.
+ This option is not allowed when using <literal>binary</literal> format.
+ </para>
+
+ <note>
+ <para>
+ When using <command>COPY FROM</command>, any data item that matches
+ this string will be stored as a null value, so you should make
+ sure that you use the same string as you used with
+ <command>COPY TO</command>.
+ </para>
+ </note>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HEADER</literal></term>
+ <listitem>
+ <para>
+ Specifies that the file contains a header line with the names of each
+ column in the file. On output, the first line contains the column
+ names from the table. On input, the first line is discarded when this
+ option is set to <literal>true</literal> (or equivalent Boolean value).
+ If this option is set to <literal>MATCH</literal>, the number and names
+ of the columns in the header line must match the actual column names of
+ the table, in order; otherwise an error is raised.
+ This option is not allowed when using <literal>binary</literal> format.
+ The <literal>MATCH</literal> option is only valid for <command>COPY
+ FROM</command> commands.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>QUOTE</literal></term>
+ <listitem>
+ <para>
+ Specifies the quoting character to be used when a data value is quoted.
+ The default is double-quote.
+ This must be a single one-byte character.
+ This option is allowed only when using <literal>CSV</literal> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ESCAPE</literal></term>
+ <listitem>
+ <para>
+ Specifies the character that should appear before a
+ data character that matches the <literal>QUOTE</literal> value.
+ The default is the same as the <literal>QUOTE</literal> value (so that
+ the quoting character is doubled if it appears in the data).
+ This must be a single one-byte character.
+ This option is allowed only when using <literal>CSV</literal> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORCE_QUOTE</literal></term>
+ <listitem>
+ <para>
+ Forces quoting to be
+ used for all non-<literal>NULL</literal> values in each specified column.
+ <literal>NULL</literal> output is never quoted. If <literal>*</literal> is specified,
+ non-<literal>NULL</literal> values will be quoted in all columns.
+ This option is allowed only in <command>COPY TO</command>, and only when
+ using <literal>CSV</literal> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORCE_NOT_NULL</literal></term>
+ <listitem>
+ <para>
+ Do not match the specified columns' values against the null string.
+ In the default case where the null string is empty, this means that
+ empty values will be read as zero-length strings rather than nulls,
+ even when they are not quoted.
+ This option is allowed only in <command>COPY FROM</command>, and only when
+ using <literal>CSV</literal> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORCE_NULL</literal></term>
+ <listitem>
+ <para>
+ Match the specified columns' values against the null string, even
+ if it has been quoted, and if a match is found set the value to
+ <literal>NULL</literal>. In the default case where the null string is empty,
+ this converts a quoted empty string into NULL.
+ This option is allowed only in <command>COPY FROM</command>, and only when
+ using <literal>CSV</literal> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ENCODING</literal></term>
+ <listitem>
+ <para>
+ Specifies that the file is encoded in the <replaceable
+ class="parameter">encoding_name</replaceable>. If this option is
+ omitted, the current client encoding is used. See the Notes below
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WHERE</literal></term>
+ <listitem>
+ <para>
+ The optional <literal>WHERE</literal> clause has the general form
+<synopsis>
+WHERE <replaceable class="parameter">condition</replaceable>
+</synopsis>
+ where <replaceable class="parameter">condition</replaceable> is
+ any expression that evaluates to a result of type
+ <type>boolean</type>. Any row that does not satisfy this
+ condition will not be inserted to the table. A row satisfies the
+ condition if it returns true when the actual row values are
+ substituted for any variable references.
+ </para>
+
+ <para>
+ Currently, subqueries are not allowed in <literal>WHERE</literal>
+ expressions, and the evaluation does not see any changes made by the
+ <command>COPY</command> itself (this matters when the expression
+ contains calls to <literal>VOLATILE</literal> functions).
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, a <command>COPY</command> command returns a command
+ tag of the form
+<screen>
+COPY <replaceable class="parameter">count</replaceable>
+</screen>
+ The <replaceable class="parameter">count</replaceable> is the number
+ of rows copied.
+ </para>
+
+ <note>
+ <para>
+ <application>psql</application> will print this command tag only if the command
+ was not <literal>COPY ... TO STDOUT</literal>, or the
+ equivalent <application>psql</application> meta-command
+ <literal>\copy ... to stdout</literal>. This is to prevent confusing the
+ command tag with the data that was just printed.
+ </para>
+ </note>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>COPY TO</command> can be used only with plain
+ tables, not views, and does not copy rows from child tables
+ or child partitions. For example, <literal>COPY <replaceable
+ class="parameter">table</replaceable> TO</literal> copies
+ the same rows as <literal>SELECT * FROM ONLY <replaceable
+ class="parameter">table</replaceable></literal>.
+ The syntax <literal>COPY (SELECT * FROM <replaceable
+ class="parameter">table</replaceable>) TO ...</literal> can be used to
+ dump all of the rows in an inheritance hierarchy, partitioned table,
+ or view.
+ </para>
+
+ <para>
+ <command>COPY FROM</command> can be used with plain, foreign, or
+ partitioned tables or with views that have
+ <literal>INSTEAD OF INSERT</literal> triggers.
+ </para>
+
+ <para>
+ You must have select privilege on the table
+ whose values are read by <command>COPY TO</command>, and
+ insert privilege on the table into which values
+ are inserted by <command>COPY FROM</command>. It is sufficient
+ to have column privileges on the column(s) listed in the command.
+ </para>
+
+ <para>
+ If row-level security is enabled for the table, the relevant
+ <command>SELECT</command> policies will apply to <literal>COPY
+ <replaceable class="parameter">table</replaceable> TO</literal> statements.
+ Currently, <command>COPY FROM</command> is not supported for tables
+ with row-level security. Use equivalent <command>INSERT</command>
+ statements instead.
+ </para>
+
+ <para>
+ Files named in a <command>COPY</command> command are read or written
+ directly by the server, not by the client application. Therefore,
+ they must reside on or be accessible to the database server machine,
+ not the client. They must be accessible to and readable or writable
+ by the <productname>PostgreSQL</productname> user (the user ID the
+ server runs as), not the client. Similarly,
+ the command specified with <literal>PROGRAM</literal> is executed directly
+ by the server, not by the client application, must be executable by the
+ <productname>PostgreSQL</productname> user.
+ <command>COPY</command> naming a file or command is only allowed to
+ database superusers or users who are granted one of the roles
+ <literal>pg_read_server_files</literal>,
+ <literal>pg_write_server_files</literal>,
+ or <literal>pg_execute_server_program</literal>, since it allows reading
+ or writing any file or running a program that the server has privileges to
+ access.
+ </para>
+
+ <para>
+ Do not confuse <command>COPY</command> with the
+ <application>psql</application> instruction
+ <command><link linkend="app-psql-meta-commands-copy">\copy</link></command>. <command>\copy</command> invokes
+ <command>COPY FROM STDIN</command> or <command>COPY TO
+ STDOUT</command>, and then fetches/stores the data in a file
+ accessible to the <application>psql</application> client. Thus,
+ file accessibility and access rights depend on the client rather
+ than the server when <command>\copy</command> is used.
+ </para>
+
+ <para>
+ It is recommended that the file name used in <command>COPY</command>
+ always be specified as an absolute path. This is enforced by the
+ server in the case of <command>COPY TO</command>, but for
+ <command>COPY FROM</command> you do have the option of reading from
+ a file specified by a relative path. The path will be interpreted
+ relative to the working directory of the server process (normally
+ the cluster's data directory), not the client's working directory.
+ </para>
+
+ <para>
+ Executing a command with <literal>PROGRAM</literal> might be restricted
+ by the operating system's access control mechanisms, such as SELinux.
+ </para>
+
+ <para>
+ <command>COPY FROM</command> will invoke any triggers and check
+ constraints on the destination table. However, it will not invoke rules.
+ </para>
+
+ <para>
+ For identity columns, the <command>COPY FROM</command> command will always
+ write the column values provided in the input data, like
+ the <command>INSERT</command> option <literal>OVERRIDING SYSTEM
+ VALUE</literal>.
+ </para>
+
+ <para>
+ <command>COPY</command> input and output is affected by
+ <varname>DateStyle</varname>. To ensure portability to other
+ <productname>PostgreSQL</productname> installations that might use
+ non-default <varname>DateStyle</varname> settings,
+ <varname>DateStyle</varname> should be set to <literal>ISO</literal> before
+ using <command>COPY TO</command>. It is also a good idea to avoid dumping
+ data with <varname>IntervalStyle</varname> set to
+ <literal>sql_standard</literal>, because negative interval values might be
+ misinterpreted by a server that has a different setting for
+ <varname>IntervalStyle</varname>.
+ </para>
+
+ <para>
+ Input data is interpreted according to <literal>ENCODING</literal>
+ option or the current client encoding, and output data is encoded
+ in <literal>ENCODING</literal> or the current client encoding, even
+ if the data does not pass through the client but is read from or
+ written to a file directly by the server.
+ </para>
+
+ <para>
+ <command>COPY</command> stops operation at the first error. This
+ should not lead to problems in the event of a <command>COPY
+ TO</command>, but the target table will already have received
+ earlier rows in a <command>COPY FROM</command>. These rows will not
+ be visible or accessible, but they still occupy disk space. This might
+ amount to a considerable amount of wasted disk space if the failure
+ happened well into a large copy operation. You might wish to invoke
+ <command>VACUUM</command> to recover the wasted space.
+ </para>
+
+ <para>
+ <literal>FORCE_NULL</literal> and <literal>FORCE_NOT_NULL</literal> can be used
+ simultaneously on the same column. This results in converting quoted
+ null strings to null values and unquoted null strings to empty strings.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>File Formats</title>
+
+ <refsect2>
+ <title>Text Format</title>
+
+ <para>
+ When the <literal>text</literal> format is used,
+ the data read or written is a text file with one line per table row.
+ Columns in a row are separated by the delimiter character.
+ The column values themselves are strings generated by the
+ output function, or acceptable to the input function, of each
+ attribute's data type. The specified null string is used in
+ place of columns that are null.
+ <command>COPY FROM</command> will raise an error if any line of the
+ input file contains more or fewer columns than are expected.
+ </para>
+
+ <para>
+ End of data can be represented by a single line containing just
+ backslash-period (<literal>\.</literal>). An end-of-data marker is
+ not necessary when reading from a file, since the end of file
+ serves perfectly well; it is needed only when copying data to or from
+ client applications using pre-3.0 client protocol.
+ </para>
+
+ <para>
+ Backslash characters (<literal>\</literal>) can be used in the
+ <command>COPY</command> data to quote data characters that might
+ otherwise be taken as row or column delimiters. In particular, the
+ following characters <emphasis>must</emphasis> be preceded by a backslash if
+ they appear as part of a column value: backslash itself,
+ newline, carriage return, and the current delimiter character.
+ </para>
+
+ <para>
+ The specified null string is sent by <command>COPY TO</command> without
+ adding any backslashes; conversely, <command>COPY FROM</command> matches
+ the input against the null string before removing backslashes. Therefore,
+ a null string such as <literal>\N</literal> cannot be confused with
+ the actual data value <literal>\N</literal> (which would be represented
+ as <literal>\\N</literal>).
+ </para>
+
+ <para>
+ The following special backslash sequences are recognized by
+ <command>COPY FROM</command>:
+
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Sequence</entry>
+ <entry>Represents</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>\b</literal></entry>
+ <entry>Backspace (ASCII 8)</entry>
+ </row>
+ <row>
+ <entry><literal>\f</literal></entry>
+ <entry>Form feed (ASCII 12)</entry>
+ </row>
+ <row>
+ <entry><literal>\n</literal></entry>
+ <entry>Newline (ASCII 10)</entry>
+ </row>
+ <row>
+ <entry><literal>\r</literal></entry>
+ <entry>Carriage return (ASCII 13)</entry>
+ </row>
+ <row>
+ <entry><literal>\t</literal></entry>
+ <entry>Tab (ASCII 9)</entry>
+ </row>
+ <row>
+ <entry><literal>\v</literal></entry>
+ <entry>Vertical tab (ASCII 11)</entry>
+ </row>
+ <row>
+ <entry><literal>\</literal><replaceable>digits</replaceable></entry>
+ <entry>Backslash followed by one to three octal digits specifies
+ the byte with that numeric code</entry>
+ </row>
+ <row>
+ <entry><literal>\x</literal><replaceable>digits</replaceable></entry>
+ <entry>Backslash <literal>x</literal> followed by one or two hex digits specifies
+ the byte with that numeric code</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ Presently, <command>COPY TO</command> will never emit an octal or
+ hex-digits backslash sequence, but it does use the other sequences
+ listed above for those control characters.
+ </para>
+
+ <para>
+ Any other backslashed character that is not mentioned in the above table
+ will be taken to represent itself. However, beware of adding backslashes
+ unnecessarily, since that might accidentally produce a string matching the
+ end-of-data marker (<literal>\.</literal>) or the null string (<literal>\N</literal> by
+ default). These strings will be recognized before any other backslash
+ processing is done.
+ </para>
+
+ <para>
+ It is strongly recommended that applications generating <command>COPY</command> data convert
+ data newlines and carriage returns to the <literal>\n</literal> and
+ <literal>\r</literal> sequences respectively. At present it is
+ possible to represent a data carriage return by a backslash and carriage
+ return, and to represent a data newline by a backslash and newline.
+ However, these representations might not be accepted in future releases.
+ They are also highly vulnerable to corruption if the <command>COPY</command> file is
+ transferred across different machines (for example, from Unix to Windows
+ or vice versa).
+ </para>
+
+ <para>
+ All backslash sequences are interpreted after encoding conversion.
+ The bytes specified with the octal and hex-digit backslash sequences must
+ form valid characters in the database encoding.
+ </para>
+
+ <para>
+ <command>COPY TO</command> will terminate each row with a Unix-style
+ newline (<quote><literal>\n</literal></quote>). Servers running on Microsoft Windows instead
+ output carriage return/newline (<quote><literal>\r\n</literal></quote>), but only for
+ <command>COPY</command> to a server file; for consistency across platforms,
+ <command>COPY TO STDOUT</command> always sends <quote><literal>\n</literal></quote>
+ regardless of server platform.
+ <command>COPY FROM</command> can handle lines ending with newlines,
+ carriage returns, or carriage return/newlines. To reduce the risk of
+ error due to un-backslashed newlines or carriage returns that were
+ meant as data, <command>COPY FROM</command> will complain if the line
+ endings in the input are not all alike.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>CSV Format</title>
+
+ <para>
+ This format option is used for importing and exporting the Comma
+ Separated Value (<literal>CSV</literal>) file format used by many other
+ programs, such as spreadsheets. Instead of the escaping rules used by
+ <productname>PostgreSQL</productname>'s standard text format, it
+ produces and recognizes the common CSV escaping mechanism.
+ </para>
+
+ <para>
+ The values in each record are separated by the <literal>DELIMITER</literal>
+ character. If the value contains the delimiter character, the
+ <literal>QUOTE</literal> character, the <literal>NULL</literal> string, a carriage
+ return, or line feed character, then the whole value is prefixed and
+ suffixed by the <literal>QUOTE</literal> character, and any occurrence
+ within the value of a <literal>QUOTE</literal> character or the
+ <literal>ESCAPE</literal> character is preceded by the escape character.
+ You can also use <literal>FORCE_QUOTE</literal> to force quotes when outputting
+ non-<literal>NULL</literal> values in specific columns.
+ </para>
+
+ <para>
+ The <literal>CSV</literal> format has no standard way to distinguish a
+ <literal>NULL</literal> value from an empty string.
+ <productname>PostgreSQL</productname>'s <command>COPY</command> handles this by quoting.
+ A <literal>NULL</literal> is output as the <literal>NULL</literal> parameter string
+ and is not quoted, while a non-<literal>NULL</literal> value matching the
+ <literal>NULL</literal> parameter string is quoted. For example, with the
+ default settings, a <literal>NULL</literal> is written as an unquoted empty
+ string, while an empty string data value is written with double quotes
+ (<literal>""</literal>). Reading values follows similar rules. You can
+ use <literal>FORCE_NOT_NULL</literal> to prevent <literal>NULL</literal> input
+ comparisons for specific columns. You can also use
+ <literal>FORCE_NULL</literal> to convert quoted null string data values to
+ <literal>NULL</literal>.
+ </para>
+
+ <para>
+ Because backslash is not a special character in the <literal>CSV</literal>
+ format, <literal>\.</literal>, the end-of-data marker, could also appear
+ as a data value. To avoid any misinterpretation, a <literal>\.</literal>
+ data value appearing as a lone entry on a line is automatically
+ quoted on output, and on input, if quoted, is not interpreted as the
+ end-of-data marker. If you are loading a file created by another
+ application that has a single unquoted column and might have a
+ value of <literal>\.</literal>, you might need to quote that value in the
+ input file.
+ </para>
+
+ <note>
+ <para>
+ In <literal>CSV</literal> format, all characters are significant. A quoted value
+ surrounded by white space, or any characters other than
+ <literal>DELIMITER</literal>, will include those characters. This can cause
+ errors if you import data from a system that pads <literal>CSV</literal>
+ lines with white space out to some fixed width. If such a situation
+ arises you might need to preprocess the <literal>CSV</literal> file to remove
+ the trailing white space, before importing the data into
+ <productname>PostgreSQL</productname>.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ CSV format will both recognize and produce CSV files with quoted
+ values containing embedded carriage returns and line feeds. Thus
+ the files are not strictly one line per table row like text-format
+ files.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Many programs produce strange and occasionally perverse CSV files,
+ so the file format is more a convention than a standard. Thus you
+ might encounter some files that cannot be imported using this
+ mechanism, and <command>COPY</command> might produce files that other
+ programs cannot process.
+ </para>
+ </note>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Binary Format</title>
+
+ <para>
+ The <literal>binary</literal> format option causes all data to be
+ stored/read as binary format rather than as text. It is
+ somewhat faster than the text and <literal>CSV</literal> formats,
+ but a binary-format file is less portable across machine architectures and
+ <productname>PostgreSQL</productname> versions.
+ Also, the binary format is very data type specific; for example
+ it will not work to output binary data from a <type>smallint</type> column
+ and read it into an <type>integer</type> column, even though that would work
+ fine in text format.
+ </para>
+
+ <para>
+ The <literal>binary</literal> file format consists
+ of a file header, zero or more tuples containing the row data, and
+ a file trailer. Headers and data are in network byte order.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> releases before 7.4 used a
+ different binary file format.
+ </para>
+ </note>
+
+ <refsect3>
+ <title>File Header</title>
+
+ <para>
+ The file header consists of 15 bytes of fixed fields, followed
+ by a variable-length header extension area. The fixed fields are:
+
+ <variablelist>
+ <varlistentry>
+ <term>Signature</term>
+ <listitem>
+ <para>
+11-byte sequence <literal>PGCOPY\n\377\r\n\0</literal> &mdash; note that the zero byte
+is a required part of the signature. (The signature is designed to allow
+easy identification of files that have been munged by a non-8-bit-clean
+transfer. This signature will be changed by end-of-line-translation
+filters, dropped zero bytes, dropped high bits, or parity changes.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Flags field</term>
+ <listitem>
+ <para>
+32-bit integer bit mask to denote important aspects of the file format. Bits
+are numbered from 0 (<acronym>LSB</acronym>) to 31 (<acronym>MSB</acronym>). Note that
+this field is stored in network byte order (most significant byte first),
+as are all the integer fields used in the file format. Bits
+16&ndash;31 are reserved to denote critical file format issues; a reader
+should abort if it finds an unexpected bit set in this range. Bits 0&ndash;15
+are reserved to signal backwards-compatible format issues; a reader
+should simply ignore any unexpected bits set in this range. Currently
+only one flag bit is defined, and the rest must be zero:
+ <variablelist>
+ <varlistentry>
+ <term>Bit 16</term>
+ <listitem>
+ <para>
+ If 1, OIDs are included in the data; if 0, not. Oid system columns
+ are not supported in <productname>PostgreSQL</productname>
+ anymore, but the format still contains the indicator.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Header extension area length</term>
+ <listitem>
+ <para>
+32-bit integer, length in bytes of remainder of header, not including self.
+Currently, this is zero, and the first tuple follows
+immediately. Future changes to the format might allow additional data
+to be present in the header. A reader should silently skip over any header
+extension data it does not know what to do with.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+The header extension area is envisioned to contain a sequence of
+self-identifying chunks. The flags field is not intended to tell readers
+what is in the extension area. Specific design of header extension contents
+is left for a later release.
+ </para>
+
+ <para>
+ This design allows for both backwards-compatible header additions (add
+ header extension chunks, or set low-order flag bits) and
+ non-backwards-compatible changes (set high-order flag bits to signal such
+ changes, and add supporting data to the extension area if needed).
+ </para>
+ </refsect3>
+
+ <refsect3>
+ <title>Tuples</title>
+ <para>
+Each tuple begins with a 16-bit integer count of the number of fields in the
+tuple. (Presently, all tuples in a table will have the same count, but that
+might not always be true.) Then, repeated for each field in the tuple, there
+is a 32-bit length word followed by that many bytes of field data. (The
+length word does not include itself, and can be zero.) As a special case,
+-1 indicates a NULL field value. No value bytes follow in the NULL case.
+ </para>
+
+ <para>
+There is no alignment padding or any other extra data between fields.
+ </para>
+
+ <para>
+Presently, all data values in a binary-format file are
+assumed to be in binary format (format code one). It is anticipated that a
+future extension might add a header field that allows per-column format codes
+to be specified.
+ </para>
+
+ <para>
+To determine the appropriate binary format for the actual tuple data you
+should consult the <productname>PostgreSQL</productname> source, in
+particular the <function>*send</function> and <function>*recv</function> functions for
+each column's data type (typically these functions are found in the
+<filename>src/backend/utils/adt/</filename> directory of the source
+distribution).
+ </para>
+
+ <para>
+If OIDs are included in the file, the OID field immediately follows the
+field-count word. It is a normal field except that it's not included in the
+field-count. Note that oid system columns are not supported in current
+versions of <productname>PostgreSQL</productname>.
+ </para>
+ </refsect3>
+
+ <refsect3>
+ <title>File Trailer</title>
+
+ <para>
+ The file trailer consists of a 16-bit integer word containing -1. This
+ is easily distinguished from a tuple's field-count word.
+ </para>
+
+ <para>
+ A reader should report an error if a field-count word is neither -1
+ nor the expected number of columns. This provides an extra
+ check against somehow getting out of sync with the data.
+ </para>
+ </refsect3>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example copies a table to the client
+ using the vertical bar (<literal>|</literal>) as the field delimiter:
+<programlisting>
+COPY country TO STDOUT (DELIMITER '|');
+</programlisting>
+ </para>
+
+ <para>
+ To copy data from a file into the <literal>country</literal> table:
+<programlisting>
+COPY country FROM '/usr1/proj/bray/sql/country_data';
+</programlisting>
+ </para>
+
+ <para>
+ To copy into a file just the countries whose names start with 'A':
+<programlisting>
+COPY (SELECT * FROM country WHERE country_name LIKE 'A%') TO '/usr1/proj/bray/sql/a_list_countries.copy';
+</programlisting>
+ </para>
+
+ <para>
+ To copy into a compressed file, you can pipe the output through an external
+ compression program:
+<programlisting>
+COPY country TO PROGRAM 'gzip > /usr1/proj/bray/sql/country_data.gz';
+</programlisting>
+ </para>
+
+ <para>
+ Here is a sample of data suitable for copying into a table from
+ <literal>STDIN</literal>:
+<programlisting>
+AF AFGHANISTAN
+AL ALBANIA
+DZ ALGERIA
+ZM ZAMBIA
+ZW ZIMBABWE
+</programlisting>
+ Note that the white space on each line is actually a tab character.
+ </para>
+
+ <para>
+ The following is the same data, output in binary format.
+ The data is shown after filtering through the
+ Unix utility <command>od -c</command>. The table has three columns;
+ the first has type <type>char(2)</type>, the second has type <type>text</type>,
+ and the third has type <type>integer</type>. All the rows have a null value
+ in the third column.
+<programlisting>
+0000000 P G C O P Y \n 377 \r \n \0 \0 \0 \0 \0 \0
+0000020 \0 \0 \0 \0 003 \0 \0 \0 002 A F \0 \0 \0 013 A
+0000040 F G H A N I S T A N 377 377 377 377 \0 003
+0000060 \0 \0 \0 002 A L \0 \0 \0 007 A L B A N I
+0000100 A 377 377 377 377 \0 003 \0 \0 \0 002 D Z \0 \0 \0
+0000120 007 A L G E R I A 377 377 377 377 \0 003 \0 \0
+0000140 \0 002 Z M \0 \0 \0 006 Z A M B I A 377 377
+0000160 377 377 \0 003 \0 \0 \0 002 Z W \0 \0 \0 \b Z I
+0000200 M B A B W E 377 377 377 377 377 377
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>COPY</command> statement in the SQL standard.
+ </para>
+
+ <para>
+ The following syntax was used before <productname>PostgreSQL</productname>
+ version 9.0 and is still supported:
+
+<synopsis>
+COPY <replaceable class="parameter">table_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+ FROM { '<replaceable class="parameter">filename</replaceable>' | STDIN }
+ [ [ WITH ]
+ [ BINARY ]
+ [ DELIMITER [ AS ] '<replaceable class="parameter">delimiter_character</replaceable>' ]
+ [ NULL [ AS ] '<replaceable class="parameter">null_string</replaceable>' ]
+ [ CSV [ HEADER ]
+ [ QUOTE [ AS ] '<replaceable class="parameter">quote_character</replaceable>' ]
+ [ ESCAPE [ AS ] '<replaceable class="parameter">escape_character</replaceable>' ]
+ [ FORCE NOT NULL <replaceable class="parameter">column_name</replaceable> [, ...] ] ] ]
+
+COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ] | ( <replaceable class="parameter">query</replaceable> ) }
+ TO { '<replaceable class="parameter">filename</replaceable>' | STDOUT }
+ [ [ WITH ]
+ [ BINARY ]
+ [ DELIMITER [ AS ] '<replaceable class="parameter">delimiter_character</replaceable>' ]
+ [ NULL [ AS ] '<replaceable class="parameter">null_string</replaceable>' ]
+ [ CSV [ HEADER ]
+ [ QUOTE [ AS ] '<replaceable class="parameter">quote_character</replaceable>' ]
+ [ ESCAPE [ AS ] '<replaceable class="parameter">escape_character</replaceable>' ]
+ [ FORCE QUOTE { <replaceable class="parameter">column_name</replaceable> [, ...] | * } ] ] ]
+</synopsis>
+
+ Note that in this syntax, <literal>BINARY</literal> and <literal>CSV</literal> are
+ treated as independent keywords, not as arguments of a <literal>FORMAT</literal>
+ option.
+ </para>
+
+ <para>
+ The following syntax was used before <productname>PostgreSQL</productname>
+ version 7.3 and is still supported:
+
+<synopsis>
+COPY [ BINARY ] <replaceable class="parameter">table_name</replaceable>
+ FROM { '<replaceable class="parameter">filename</replaceable>' | STDIN }
+ [ [USING] DELIMITERS '<replaceable class="parameter">delimiter_character</replaceable>' ]
+ [ WITH NULL AS '<replaceable class="parameter">null_string</replaceable>' ]
+
+COPY [ BINARY ] <replaceable class="parameter">table_name</replaceable>
+ TO { '<replaceable class="parameter">filename</replaceable>' | STDOUT }
+ [ [USING] DELIMITERS '<replaceable class="parameter">delimiter_character</replaceable>' ]
+ [ WITH NULL AS '<replaceable class="parameter">null_string</replaceable>' ]
+</synopsis></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="copy-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_access_method.sgml b/doc/src/sgml/ref/create_access_method.sgml
new file mode 100644
index 0000000..dae43db
--- /dev/null
+++ b/doc/src/sgml/ref/create_access_method.sgml
@@ -0,0 +1,122 @@
+<!--
+doc/src/sgml/ref/create_access_method.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-create-access-method">
+ <indexterm zone="sql-create-access-method">
+ <primary>CREATE ACCESS METHOD</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE ACCESS METHOD</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE ACCESS METHOD</refname>
+ <refpurpose>define a new access method</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE ACCESS METHOD <replaceable class="parameter">name</replaceable>
+ TYPE <replaceable class="parameter">access_method_type</replaceable>
+ HANDLER <replaceable class="parameter">handler_function</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE ACCESS METHOD</command> creates a new access method.
+ </para>
+
+ <para>
+ The access method name must be unique within the database.
+ </para>
+
+ <para>
+ Only superusers can define new access methods.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the access method to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">access_method_type</replaceable></term>
+ <listitem>
+ <para>
+ This clause specifies the type of access method to define.
+ Only <literal>TABLE</literal> and <literal>INDEX</literal>
+ are supported at present.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">handler_function</replaceable></term>
+ <listitem>
+ <para>
+ <replaceable class="parameter">handler_function</replaceable> is the
+ name (possibly schema-qualified) of a previously registered function
+ that represents the access method. The handler function must be
+ declared to take a single argument of type <type>internal</type>,
+ and its return type depends on the type of access method;
+ for <literal>TABLE</literal> access methods, it must
+ be <type>table_am_handler</type> and for <literal>INDEX</literal>
+ access methods, it must be <type>index_am_handler</type>.
+ The C-level API that the handler function must implement varies
+ depending on the type of access method. The table access method API
+ is described in <xref linkend="tableam"/> and the index access method
+ API is described in <xref linkend="indexam"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create an index access method <literal>heptree</literal> with
+ handler function <literal>heptree_handler</literal>:
+<programlisting>
+CREATE ACCESS METHOD heptree TYPE INDEX HANDLER heptree_handler;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE ACCESS METHOD</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-drop-access-method"/></member>
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-createopfamily"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml
new file mode 100644
index 0000000..222e0aa
--- /dev/null
+++ b/doc/src/sgml/ref/create_aggregate.sgml
@@ -0,0 +1,805 @@
+<!--
+doc/src/sgml/ref/create_aggregate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createaggregate">
+ <indexterm zone="sql-createaggregate">
+ <primary>CREATE AGGREGATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE AGGREGATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE AGGREGATE</refname>
+ <refpurpose>define a new aggregate function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] AGGREGATE <replaceable class="parameter">name</replaceable> ( [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">arg_data_type</replaceable> [ , ... ] ) (
+ SFUNC = <replaceable class="parameter">sfunc</replaceable>,
+ STYPE = <replaceable class="parameter">state_data_type</replaceable>
+ [ , SSPACE = <replaceable class="parameter">state_data_size</replaceable> ]
+ [ , FINALFUNC = <replaceable class="parameter">ffunc</replaceable> ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , COMBINEFUNC = <replaceable class="parameter">combinefunc</replaceable> ]
+ [ , SERIALFUNC = <replaceable class="parameter">serialfunc</replaceable> ]
+ [ , DESERIALFUNC = <replaceable class="parameter">deserialfunc</replaceable> ]
+ [ , INITCOND = <replaceable class="parameter">initial_condition</replaceable> ]
+ [ , MSFUNC = <replaceable class="parameter">msfunc</replaceable> ]
+ [ , MINVFUNC = <replaceable class="parameter">minvfunc</replaceable> ]
+ [ , MSTYPE = <replaceable class="parameter">mstate_data_type</replaceable> ]
+ [ , MSSPACE = <replaceable class="parameter">mstate_data_size</replaceable> ]
+ [ , MFINALFUNC = <replaceable class="parameter">mffunc</replaceable> ]
+ [ , MFINALFUNC_EXTRA ]
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , MINITCOND = <replaceable class="parameter">minitial_condition</replaceable> ]
+ [ , SORTOP = <replaceable class="parameter">sort_operator</replaceable> ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+)
+
+CREATE [ OR REPLACE ] AGGREGATE <replaceable class="parameter">name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">arg_data_type</replaceable> [ , ... ] ]
+ ORDER BY [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">arg_data_type</replaceable> [ , ... ] ) (
+ SFUNC = <replaceable class="parameter">sfunc</replaceable>,
+ STYPE = <replaceable class="parameter">state_data_type</replaceable>
+ [ , SSPACE = <replaceable class="parameter">state_data_size</replaceable> ]
+ [ , FINALFUNC = <replaceable class="parameter">ffunc</replaceable> ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , INITCOND = <replaceable class="parameter">initial_condition</replaceable> ]
+ [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
+ [ , HYPOTHETICAL ]
+)
+
+<phrase>or the old syntax</phrase>
+
+CREATE [ OR REPLACE ] AGGREGATE <replaceable class="parameter">name</replaceable> (
+ BASETYPE = <replaceable class="parameter">base_type</replaceable>,
+ SFUNC = <replaceable class="parameter">sfunc</replaceable>,
+ STYPE = <replaceable class="parameter">state_data_type</replaceable>
+ [ , SSPACE = <replaceable class="parameter">state_data_size</replaceable> ]
+ [ , FINALFUNC = <replaceable class="parameter">ffunc</replaceable> ]
+ [ , FINALFUNC_EXTRA ]
+ [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , COMBINEFUNC = <replaceable class="parameter">combinefunc</replaceable> ]
+ [ , SERIALFUNC = <replaceable class="parameter">serialfunc</replaceable> ]
+ [ , DESERIALFUNC = <replaceable class="parameter">deserialfunc</replaceable> ]
+ [ , INITCOND = <replaceable class="parameter">initial_condition</replaceable> ]
+ [ , MSFUNC = <replaceable class="parameter">msfunc</replaceable> ]
+ [ , MINVFUNC = <replaceable class="parameter">minvfunc</replaceable> ]
+ [ , MSTYPE = <replaceable class="parameter">mstate_data_type</replaceable> ]
+ [ , MSSPACE = <replaceable class="parameter">mstate_data_size</replaceable> ]
+ [ , MFINALFUNC = <replaceable class="parameter">mffunc</replaceable> ]
+ [ , MFINALFUNC_EXTRA ]
+ [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
+ [ , MINITCOND = <replaceable class="parameter">minitial_condition</replaceable> ]
+ [ , SORTOP = <replaceable class="parameter">sort_operator</replaceable> ]
+)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE AGGREGATE</command> defines a new aggregate function.
+ <command>CREATE OR REPLACE AGGREGATE</command> will either define a new
+ aggregate function or replace an existing definition. Some basic and
+ commonly-used aggregate functions are included with the distribution; they
+ are documented in <xref linkend="functions-aggregate"/>. If one defines new
+ types or needs an aggregate function not already provided, then
+ <command>CREATE AGGREGATE</command> can be used to provide the desired
+ features.
+ </para>
+
+ <para>
+ When replacing an existing definition, the argument types, result type,
+ and number of direct arguments may not be changed. Also, the new definition
+ must be of the same kind (ordinary aggregate, ordered-set aggregate, or
+ hypothetical-set aggregate) as the old one.
+ </para>
+
+ <para>
+ If a schema name is given (for example, <literal>CREATE AGGREGATE
+ myschema.myagg ...</literal>) then the aggregate function is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </para>
+
+ <para>
+ An aggregate function is identified by its name and input data type(s).
+ Two aggregates in the same schema can have the same name if they operate on
+ different input types. The
+ name and input data type(s) of an aggregate must also be distinct from
+ the name and input data type(s) of every ordinary function in the same
+ schema.
+ This behavior is identical to overloading of ordinary function names
+ (see <xref linkend="sql-createfunction"/>).
+ </para>
+
+ <para>
+ A simple aggregate function is made from one or two ordinary
+ functions:
+ a state transition function
+ <replaceable class="parameter">sfunc</replaceable>,
+ and an optional final calculation function
+ <replaceable class="parameter">ffunc</replaceable>.
+ These are used as follows:
+<programlisting>
+<replaceable class="parameter">sfunc</replaceable>( internal-state, next-data-values ) ---> next-internal-state
+<replaceable class="parameter">ffunc</replaceable>( internal-state ) ---> aggregate-value
+</programlisting>
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> creates a temporary variable
+ of data type <replaceable class="parameter">stype</replaceable>
+ to hold the current internal state of the aggregate. At each input row,
+ the aggregate argument value(s) are calculated and
+ the state transition function is invoked with the current state value
+ and the new argument value(s) to calculate a new
+ internal state value. After all the rows have been processed,
+ the final function is invoked once to calculate the aggregate's return
+ value. If there is no final function then the ending state value
+ is returned as-is.
+ </para>
+
+ <para>
+ An aggregate function can provide an initial condition,
+ that is, an initial value for the internal state value.
+ This is specified and stored in the database as a value of type
+ <type>text</type>, but it must be a valid external representation
+ of a constant of the state value data type. If it is not supplied
+ then the state value starts out null.
+ </para>
+
+ <para>
+ If the state transition function is declared <quote>strict</quote>,
+ then it cannot be called with null inputs. With such a transition
+ function, aggregate execution behaves as follows. Rows with any null input
+ values are ignored (the function is not called and the previous state value
+ is retained). If the initial state value is null, then at the first row
+ with all-nonnull input values, the first argument value replaces the state
+ value, and the transition function is invoked at each subsequent row with
+ all-nonnull input values.
+ This is handy for implementing aggregates like <function>max</function>.
+ Note that this behavior is only available when
+ <replaceable class="parameter">state_data_type</replaceable>
+ is the same as the first
+ <replaceable class="parameter">arg_data_type</replaceable>.
+ When these types are different, you must supply a nonnull initial
+ condition or use a nonstrict transition function.
+ </para>
+
+ <para>
+ If the state transition function is not strict, then it will be called
+ unconditionally at each input row, and must deal with null inputs
+ and null state values for itself. This allows the aggregate
+ author to have full control over the aggregate's handling of null values.
+ </para>
+
+ <para>
+ If the final function is declared <quote>strict</quote>, then it will not
+ be called when the ending state value is null; instead a null result
+ will be returned automatically. (Of course this is just the normal
+ behavior of strict functions.) In any case the final function has
+ the option of returning a null value. For example, the final function for
+ <function>avg</function> returns null when it sees there were zero
+ input rows.
+ </para>
+
+ <para>
+ Sometimes it is useful to declare the final function as taking not just
+ the state value, but extra parameters corresponding to the aggregate's
+ input values. The main reason for doing this is if the final function
+ is polymorphic and the state value's data type would be inadequate to
+ pin down the result type. These extra parameters are always passed as
+ NULL (and so the final function must not be strict when
+ the <literal>FINALFUNC_EXTRA</literal> option is used), but nonetheless they
+ are valid parameters. The final function could for example make use
+ of <function>get_fn_expr_argtype</function> to identify the actual argument type
+ in the current call.
+ </para>
+
+ <para>
+ An aggregate can optionally support <firstterm>moving-aggregate mode</firstterm>,
+ as described in <xref linkend="xaggr-moving-aggregates"/>. This requires
+ specifying the <literal>MSFUNC</literal>, <literal>MINVFUNC</literal>,
+ and <literal>MSTYPE</literal> parameters, and optionally
+ the <literal>MSSPACE</literal>, <literal>MFINALFUNC</literal>,
+ <literal>MFINALFUNC_EXTRA</literal>, <literal>MFINALFUNC_MODIFY</literal>,
+ and <literal>MINITCOND</literal> parameters. Except for <literal>MINVFUNC</literal>,
+ these parameters work like the corresponding simple-aggregate parameters
+ without <literal>M</literal>; they define a separate implementation of the
+ aggregate that includes an inverse transition function.
+ </para>
+
+ <para>
+ The syntax with <literal>ORDER BY</literal> in the parameter list creates
+ a special type of aggregate called an <firstterm>ordered-set
+ aggregate</firstterm>; or if <literal>HYPOTHETICAL</literal> is specified, then
+ a <firstterm>hypothetical-set aggregate</firstterm> is created. These
+ aggregates operate over groups of sorted values in order-dependent ways,
+ so that specification of an input sort order is an essential part of a
+ call. Also, they can have <firstterm>direct</firstterm> arguments, which are
+ arguments that are evaluated only once per aggregation rather than once
+ per input row. Hypothetical-set aggregates are a subclass of ordered-set
+ aggregates in which some of the direct arguments are required to match,
+ in number and data types, the aggregated argument columns. This allows
+ the values of those direct arguments to be added to the collection of
+ aggregate-input rows as an additional <quote>hypothetical</quote> row.
+ </para>
+
+ <para>
+ An aggregate can optionally support <firstterm>partial aggregation</firstterm>,
+ as described in <xref linkend="xaggr-partial-aggregates"/>.
+ This requires specifying the <literal>COMBINEFUNC</literal> parameter.
+ If the <replaceable class="parameter">state_data_type</replaceable>
+ is <type>internal</type>, it's usually also appropriate to provide the
+ <literal>SERIALFUNC</literal> and <literal>DESERIALFUNC</literal> parameters so that
+ parallel aggregation is possible. Note that the aggregate must also be
+ marked <literal>PARALLEL SAFE</literal> to enable parallel aggregation.
+ </para>
+
+ <para>
+ Aggregates that behave like <function>MIN</function> or <function>MAX</function> can
+ sometimes be optimized by looking into an index instead of scanning every
+ input row. If this aggregate can be so optimized, indicate it by
+ specifying a <firstterm>sort operator</firstterm>. The basic requirement is that
+ the aggregate must yield the first element in the sort ordering induced by
+ the operator; in other words:
+<programlisting>
+SELECT agg(col) FROM tab;
+</programlisting>
+ must be equivalent to:
+<programlisting>
+SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
+</programlisting>
+ Further assumptions are that the aggregate ignores null inputs, and that
+ it delivers a null result if and only if there were no non-null inputs.
+ Ordinarily, a data type's <literal>&lt;</literal> operator is the proper sort
+ operator for <function>MIN</function>, and <literal>&gt;</literal> is the proper sort
+ operator for <function>MAX</function>. Note that the optimization will never
+ actually take effect unless the specified operator is the <quote>less
+ than</quote> or <quote>greater than</quote> strategy member of a B-tree
+ index operator class.
+ </para>
+
+ <para>
+ To be able to create an aggregate function, you must
+ have <literal>USAGE</literal> privilege on the argument types, the state
+ type(s), and the return type, as well as <literal>EXECUTE</literal>
+ privilege on the supporting functions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the aggregate function
+ to create.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal> or <literal>VARIADIC</literal>.
+ (Aggregate functions do not support <literal>OUT</literal> arguments.)
+ If omitted, the default is <literal>IN</literal>. Only the last argument
+ can be marked <literal>VARIADIC</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument. This is currently only useful for
+ documentation purposes. If omitted, the argument has no name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">arg_data_type</replaceable></term>
+ <listitem>
+ <para>
+ An input data type on which this aggregate function operates.
+ To create a zero-argument aggregate function, write <literal>*</literal>
+ in place of the list of argument specifications. (An example of such an
+ aggregate is <function>count(*)</function>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">base_type</replaceable></term>
+ <listitem>
+ <para>
+ In the old syntax for <command>CREATE AGGREGATE</command>, the input data type
+ is specified by a <literal>basetype</literal> parameter rather than being
+ written next to the aggregate name. Note that this syntax allows
+ only one input parameter. To define a zero-argument aggregate function
+ with this syntax, specify the <literal>basetype</literal> as
+ <literal>"ANY"</literal> (not <literal>*</literal>).
+ Ordered-set aggregates cannot be defined with the old syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sfunc</replaceable></term>
+ <listitem>
+ <para>
+ The name of the state transition function to be called for each
+ input row. For a normal <replaceable class="parameter">N</replaceable>-argument
+ aggregate function, the <replaceable class="parameter">sfunc</replaceable>
+ must take <replaceable class="parameter">N</replaceable>+1 arguments,
+ the first being of type <replaceable
+ class="parameter">state_data_type</replaceable> and the rest
+ matching the declared input data type(s) of the aggregate.
+ The function must return a value of type <replaceable
+ class="parameter">state_data_type</replaceable>. This function
+ takes the current state value and the current input data value(s),
+ and returns the next state value.
+ </para>
+
+ <para>
+ For ordered-set (including hypothetical-set) aggregates, the state
+ transition function receives only the current state value and the
+ aggregated arguments, not the direct arguments. Otherwise it is the
+ same.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">state_data_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type for the aggregate's state value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">state_data_size</replaceable></term>
+ <listitem>
+ <para>
+ The approximate average size (in bytes) of the aggregate's state value.
+ If this parameter is omitted or is zero, a default estimate is used
+ based on the <replaceable>state_data_type</replaceable>.
+ The planner uses this value to estimate the memory required for a
+ grouped aggregate query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">ffunc</replaceable></term>
+ <listitem>
+ <para>
+ The name of the final function called to compute the aggregate's
+ result after all input rows have been traversed.
+ For a normal aggregate, this function
+ must take a single argument of type <replaceable
+ class="parameter">state_data_type</replaceable>. The return
+ data type of the aggregate is defined as the return type of this
+ function. If <replaceable class="parameter">ffunc</replaceable>
+ is not specified, then the ending state value is used as the
+ aggregate's result, and the return type is <replaceable
+ class="parameter">state_data_type</replaceable>.
+ </para>
+
+ <para>
+ For ordered-set (including hypothetical-set) aggregates, the
+ final function receives not only the final state value,
+ but also the values of all the direct arguments.
+ </para>
+
+ <para>
+ If <literal>FINALFUNC_EXTRA</literal> is specified, then in addition to the
+ final state value and any direct arguments, the final function
+ receives extra NULL values corresponding to the aggregate's regular
+ (aggregated) arguments. This is mainly useful to allow correct
+ resolution of the aggregate result type when a polymorphic aggregate
+ is being defined.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FINALFUNC_MODIFY</literal> = { <literal>READ_ONLY</literal> | <literal>SHAREABLE</literal> | <literal>READ_WRITE</literal> }</term>
+ <listitem>
+ <para>
+ This option specifies whether the final function is a pure function
+ that does not modify its arguments. <literal>READ_ONLY</literal> indicates
+ it does not; the other two values indicate that it may change the
+ transition state value. See <xref linkend="sql-createaggregate-notes"/>
+ below for more detail. The
+ default is <literal>READ_ONLY</literal>, except for ordered-set aggregates,
+ for which the default is <literal>READ_WRITE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">combinefunc</replaceable></term>
+ <listitem>
+ <para>
+ The <replaceable class="parameter">combinefunc</replaceable> function
+ may optionally be specified to allow the aggregate function to support
+ partial aggregation. If provided,
+ the <replaceable class="parameter">combinefunc</replaceable> must
+ combine two <replaceable class="parameter">state_data_type</replaceable>
+ values, each containing the result of aggregation over some subset of
+ the input values, to produce a
+ new <replaceable class="parameter">state_data_type</replaceable> that
+ represents the result of aggregating over both sets of inputs. This
+ function can be thought of as
+ an <replaceable class="parameter">sfunc</replaceable>, where instead of
+ acting upon an individual input row and adding it to the running
+ aggregate state, it adds another aggregate state to the running state.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">combinefunc</replaceable> must be
+ declared as taking two arguments of
+ the <replaceable class="parameter">state_data_type</replaceable> and
+ returning a value of
+ the <replaceable class="parameter">state_data_type</replaceable>.
+ Optionally this function may be <quote>strict</quote>. In this case the
+ function will not be called when either of the input states are null;
+ the other state will be taken as the correct result.
+ </para>
+
+ <para>
+ For aggregate functions
+ whose <replaceable class="parameter">state_data_type</replaceable>
+ is <type>internal</type>,
+ the <replaceable class="parameter">combinefunc</replaceable> must not
+ be strict. In this case
+ the <replaceable class="parameter">combinefunc</replaceable> must
+ ensure that null states are handled correctly and that the state being
+ returned is properly stored in the aggregate memory context.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">serialfunc</replaceable></term>
+ <listitem>
+ <para>
+ An aggregate function
+ whose <replaceable class="parameter">state_data_type</replaceable>
+ is <type>internal</type> can participate in parallel aggregation only if it
+ has a <replaceable class="parameter">serialfunc</replaceable> function,
+ which must serialize the aggregate state into a <type>bytea</type> value for
+ transmission to another process. This function must take a single
+ argument of type <type>internal</type> and return type <type>bytea</type>. A
+ corresponding <replaceable class="parameter">deserialfunc</replaceable>
+ is also required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">deserialfunc</replaceable></term>
+ <listitem>
+ <para>
+ Deserialize a previously serialized aggregate state back into
+ <replaceable class="parameter">state_data_type</replaceable>. This
+ function must take two arguments of types <type>bytea</type>
+ and <type>internal</type>, and produce a result of type <type>internal</type>.
+ (Note: the second, <type>internal</type> argument is unused, but is required
+ for type safety reasons.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">initial_condition</replaceable></term>
+ <listitem>
+ <para>
+ The initial setting for the state value. This must be a string
+ constant in the form accepted for the data type <replaceable
+ class="parameter">state_data_type</replaceable>. If not
+ specified, the state value starts out null.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">msfunc</replaceable></term>
+ <listitem>
+ <para>
+ The name of the forward state transition function to be called for each
+ input row in moving-aggregate mode. This is exactly like the regular
+ transition function, except that its first argument and result are of
+ type <replaceable>mstate_data_type</replaceable>, which might be different
+ from <replaceable>state_data_type</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">minvfunc</replaceable></term>
+ <listitem>
+ <para>
+ The name of the inverse state transition function to be used in
+ moving-aggregate mode. This function has the same argument and
+ result types as <replaceable>msfunc</replaceable>, but it is used to remove
+ a value from the current aggregate state, rather than add a value to
+ it. The inverse transition function must have the same strictness
+ attribute as the forward state transition function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">mstate_data_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type for the aggregate's state value, when using
+ moving-aggregate mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">mstate_data_size</replaceable></term>
+ <listitem>
+ <para>
+ The approximate average size (in bytes) of the aggregate's state
+ value, when using moving-aggregate mode. This works the same as
+ <replaceable>state_data_size</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">mffunc</replaceable></term>
+ <listitem>
+ <para>
+ The name of the final function called to compute the aggregate's
+ result after all input rows have been traversed, when using
+ moving-aggregate mode. This works the same as <replaceable>ffunc</replaceable>,
+ except that its first argument's type
+ is <replaceable>mstate_data_type</replaceable> and extra dummy arguments are
+ specified by writing <literal>MFINALFUNC_EXTRA</literal>.
+ The aggregate result type determined by <replaceable>mffunc</replaceable>
+ or <replaceable>mstate_data_type</replaceable> must match that determined by the
+ aggregate's regular implementation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MFINALFUNC_MODIFY</literal> = { <literal>READ_ONLY</literal> | <literal>SHAREABLE</literal> | <literal>READ_WRITE</literal> }</term>
+ <listitem>
+ <para>
+ This option is like <literal>FINALFUNC_MODIFY</literal>, but it describes
+ the behavior of the moving-aggregate final function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">minitial_condition</replaceable></term>
+ <listitem>
+ <para>
+ The initial setting for the state value, when using moving-aggregate
+ mode. This works the same as <replaceable>initial_condition</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sort_operator</replaceable></term>
+ <listitem>
+ <para>
+ The associated sort operator for a <function>MIN</function>- or
+ <function>MAX</function>-like aggregate.
+ This is just an operator name (possibly schema-qualified).
+ The operator is assumed to have the same input data types as
+ the aggregate (which must be a single-argument normal aggregate).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PARALLEL =</literal> { <literal>SAFE</literal> | <literal>RESTRICTED</literal> | <literal>UNSAFE</literal> }</term>
+ <listitem>
+ <para>
+ The meanings of <literal>PARALLEL SAFE</literal>, <literal>PARALLEL
+ RESTRICTED</literal>, and <literal>PARALLEL UNSAFE</literal> are the same as
+ in <link linkend="sql-createfunction"><command>CREATE FUNCTION</command></link>. An aggregate will not be
+ considered for parallelization if it is marked <literal>PARALLEL
+ UNSAFE</literal> (which is the default!) or <literal>PARALLEL RESTRICTED</literal>.
+ Note that the parallel-safety markings of the aggregate's support
+ functions are not consulted by the planner, only the marking of the
+ aggregate itself.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HYPOTHETICAL</literal></term>
+ <listitem>
+ <para>
+ For ordered-set aggregates only, this flag specifies that the aggregate
+ arguments are to be processed according to the requirements for
+ hypothetical-set aggregates: that is, the last few direct arguments must
+ match the data types of the aggregated (<literal>WITHIN GROUP</literal>)
+ arguments. The <literal>HYPOTHETICAL</literal> flag has no effect on
+ run-time behavior, only on parse-time resolution of the data types and
+ collations of the aggregate's arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The parameters of <command>CREATE AGGREGATE</command> can be
+ written in any order, not just the order illustrated above.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createaggregate-notes" xreflabel="Notes">
+ <title>Notes</title>
+
+ <para>
+ In parameters that specify support function names, you can write
+ a schema name if needed, for example <literal>SFUNC = public.sum</literal>.
+ Do not write argument types there, however &mdash; the argument types
+ of the support functions are determined from other parameters.
+ </para>
+
+ <para>
+ Ordinarily, PostgreSQL functions are expected to be true functions that
+ do not modify their input values. However, an aggregate transition
+ function, <emphasis>when used in the context of an aggregate</emphasis>,
+ is allowed to cheat and modify its transition-state argument in place.
+ This can provide substantial performance benefits compared to making
+ a fresh copy of the transition state each time.
+ </para>
+
+ <para>
+ Likewise, while an aggregate final function is normally expected not to
+ modify its input values, sometimes it is impractical to avoid modifying
+ the transition-state argument. Such behavior must be declared using
+ the <literal>FINALFUNC_MODIFY</literal> parameter.
+ The <literal>READ_WRITE</literal>
+ value indicates that the final function modifies the transition state in
+ unspecified ways. This value prevents use of the aggregate as a window
+ function, and it also prevents merging of transition states for aggregate
+ calls that share the same input values and transition functions.
+ The <literal>SHAREABLE</literal> value indicates that the transition function
+ cannot be applied after the final function, but multiple final-function
+ calls can be performed on the ending transition state value. This value
+ prevents use of the aggregate as a window function, but it allows merging
+ of transition states. (That is, the optimization of interest here is not
+ applying the same final function repeatedly, but applying different final
+ functions to the same ending transition state value. This is allowed as
+ long as none of the final functions are marked <literal>READ_WRITE</literal>.)
+ </para>
+
+ <para>
+ If an aggregate supports moving-aggregate mode, it will improve
+ calculation efficiency when the aggregate is used as a window function
+ for a window with moving frame start (that is, a frame start mode other
+ than <literal>UNBOUNDED PRECEDING</literal>). Conceptually, the forward
+ transition function adds input values to the aggregate's state when
+ they enter the window frame from the bottom, and the inverse transition
+ function removes them again when they leave the frame at the top. So,
+ when values are removed, they are always removed in the same order they
+ were added. Whenever the inverse transition function is invoked, it will
+ thus receive the earliest added but not yet removed argument value(s).
+ The inverse transition function can assume that at least one row will
+ remain in the current state after it removes the oldest row. (When this
+ would not be the case, the window function mechanism simply starts a
+ fresh aggregation, rather than using the inverse transition function.)
+ </para>
+
+ <para>
+ The forward transition function for moving-aggregate mode is not
+ allowed to return NULL as the new state value. If the inverse
+ transition function returns NULL, this is taken as an indication that
+ the inverse function cannot reverse the state calculation for this
+ particular input, and so the aggregate calculation will be redone from
+ scratch for the current frame starting position. This convention
+ allows moving-aggregate mode to be used in situations where there are
+ some infrequent cases that are impractical to reverse out of the
+ running state value.
+ </para>
+
+ <para>
+ If no moving-aggregate implementation is supplied,
+ the aggregate can still be used with moving frames,
+ but <productname>PostgreSQL</productname> will recompute the whole
+ aggregation whenever the start of the frame moves.
+ Note that whether or not the aggregate supports moving-aggregate
+ mode, <productname>PostgreSQL</productname> can handle a moving frame
+ end without recalculation; this is done by continuing to add new values
+ to the aggregate's state. This is why use of an aggregate as a window
+ function requires that the final function be read-only: it must
+ not damage the aggregate's state value, so that the aggregation can be
+ continued even after an aggregate result value has been obtained for
+ one set of frame boundaries.
+ </para>
+
+ <para>
+ The syntax for ordered-set aggregates allows <literal>VARIADIC</literal>
+ to be specified for both the last direct parameter and the last
+ aggregated (<literal>WITHIN GROUP</literal>) parameter. However, the
+ current implementation restricts use of <literal>VARIADIC</literal>
+ in two ways. First, ordered-set aggregates can only use
+ <literal>VARIADIC "any"</literal>, not other variadic array types.
+ Second, if the last direct parameter is <literal>VARIADIC "any"</literal>,
+ then there can be only one aggregated parameter and it must also
+ be <literal>VARIADIC "any"</literal>. (In the representation used in the
+ system catalogs, these two parameters are merged into a single
+ <literal>VARIADIC "any"</literal> item, since <structname>pg_proc</structname> cannot
+ represent functions with more than one <literal>VARIADIC</literal> parameter.)
+ If the aggregate is a hypothetical-set aggregate, the direct arguments
+ that match the <literal>VARIADIC "any"</literal> parameter are the hypothetical
+ ones; any preceding parameters represent additional direct arguments
+ that are not constrained to match the aggregated arguments.
+ </para>
+
+ <para>
+ Currently, ordered-set aggregates do not need to support
+ moving-aggregate mode, since they cannot be used as window functions.
+ </para>
+
+ <para>
+ Partial (including parallel) aggregation is currently not supported for
+ ordered-set aggregates. Also, it will never be used for aggregate calls
+ that include <literal>DISTINCT</literal> or <literal>ORDER BY</literal> clauses, since
+ those semantics cannot be supported during partial aggregation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ See <xref linkend="xaggr"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE AGGREGATE</command> is a
+ <productname>PostgreSQL</productname> language extension. The SQL
+ standard does not provide for user-defined aggregate functions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteraggregate"/></member>
+ <member><xref linkend="sql-dropaggregate"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_cast.sgml b/doc/src/sgml/ref/create_cast.sgml
new file mode 100644
index 0000000..bad75bc
--- /dev/null
+++ b/doc/src/sgml/ref/create_cast.sgml
@@ -0,0 +1,424 @@
+<!--
+doc/src/sgml/ref/create_cast.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createcast">
+ <indexterm zone="sql-createcast">
+ <primary>CREATE CAST</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE CAST</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE CAST</refname>
+ <refpurpose>define a new cast</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
+ WITH FUNCTION <replaceable>function_name</replaceable> [ (<replaceable>argument_type</replaceable> [, ...]) ]
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
+ WITHOUT FUNCTION
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+
+CREATE CAST (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>)
+ WITH INOUT
+ [ AS ASSIGNMENT | AS IMPLICIT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createcast-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE CAST</command> defines a new cast. A cast
+ specifies how to perform a conversion between
+ two data types. For example,
+<programlisting>
+SELECT CAST(42 AS float8);
+</programlisting>
+ converts the integer constant 42 to type <type>float8</type> by
+ invoking a previously specified function, in this case
+ <literal>float8(int4)</literal>. (If no suitable cast has been defined, the
+ conversion fails.)
+ </para>
+
+ <para>
+ Two types can be <firstterm>binary coercible</firstterm>, which
+ means that the conversion can be performed <quote>for free</quote>
+ without invoking any function. This requires that corresponding
+ values use the same internal representation. For instance, the
+ types <type>text</type> and <type>varchar</type> are binary
+ coercible both ways. Binary coercibility is not necessarily a
+ symmetric relationship. For example, the cast
+ from <type>xml</type> to <type>text</type> can be performed for
+ free in the present implementation, but the reverse direction
+ requires a function that performs at least a syntax check. (Two
+ types that are binary coercible both ways are also referred to as
+ binary compatible.)
+ </para>
+
+ <para>
+ You can define a cast as an <firstterm>I/O conversion cast</firstterm> by using
+ the <literal>WITH INOUT</literal> syntax. An I/O conversion cast is
+ performed by invoking the output function of the source data type, and
+ passing the resulting string to the input function of the target data type.
+ In many common cases, this feature avoids the need to write a separate
+ cast function for conversion. An I/O conversion cast acts the same as
+ a regular function-based cast; only the implementation is different.
+ </para>
+
+ <para>
+ By default, a cast can be invoked only by an explicit cast request,
+ that is an explicit <literal>CAST(<replaceable>x</replaceable> AS
+ <replaceable>typename</replaceable>)</literal> or
+ <replaceable>x</replaceable><literal>::</literal><replaceable>typename</replaceable>
+ construct.
+ </para>
+
+ <para>
+ If the cast is marked <literal>AS ASSIGNMENT</literal> then it can be invoked
+ implicitly when assigning a value to a column of the target data type.
+ For example, supposing that <literal>foo.f1</literal> is a column of
+ type <type>text</type>, then:
+<programlisting>
+INSERT INTO foo (f1) VALUES (42);
+</programlisting>
+ will be allowed if the cast from type <type>integer</type> to type
+ <type>text</type> is marked <literal>AS ASSIGNMENT</literal>, otherwise not.
+ (We generally use the term <firstterm>assignment
+ cast</firstterm> to describe this kind of cast.)
+ </para>
+
+ <para>
+ If the cast is marked <literal>AS IMPLICIT</literal> then it can be invoked
+ implicitly in any context, whether assignment or internally in an
+ expression. (We generally use the term <firstterm>implicit
+ cast</firstterm> to describe this kind of cast.)
+ For example, consider this query:
+<programlisting>
+SELECT 2 + 4.0;
+</programlisting>
+ The parser initially marks the constants as being of type <type>integer</type>
+ and <type>numeric</type> respectively. There is no <type>integer</type>
+ <literal>+</literal> <type>numeric</type> operator in the system catalogs,
+ but there is a <type>numeric</type> <literal>+</literal> <type>numeric</type> operator.
+ The query will therefore succeed if a cast from <type>integer</type> to
+ <type>numeric</type> is available and is marked <literal>AS IMPLICIT</literal> &mdash;
+ which in fact it is. The parser will apply the implicit cast and resolve
+ the query as if it had been written
+<programlisting>
+SELECT CAST ( 2 AS numeric ) + 4.0;
+</programlisting>
+ </para>
+
+ <para>
+ Now, the catalogs also provide a cast from <type>numeric</type> to
+ <type>integer</type>. If that cast were marked <literal>AS IMPLICIT</literal> &mdash;
+ which it is not &mdash; then the parser would be faced with choosing
+ between the above interpretation and the alternative of casting the
+ <type>numeric</type> constant to <type>integer</type> and applying the
+ <type>integer</type> <literal>+</literal> <type>integer</type> operator. Lacking any
+ knowledge of which choice to prefer, it would give up and declare the
+ query ambiguous. The fact that only one of the two casts is
+ implicit is the way in which we teach the parser to prefer resolution
+ of a mixed <type>numeric</type>-and-<type>integer</type> expression as
+ <type>numeric</type>; there is no built-in knowledge about that.
+ </para>
+
+ <para>
+ It is wise to be conservative about marking casts as implicit. An
+ overabundance of implicit casting paths can cause
+ <productname>PostgreSQL</productname> to choose surprising
+ interpretations of commands, or to be unable to resolve commands at
+ all because there are multiple possible interpretations. A good
+ rule of thumb is to make a cast implicitly invokable only for
+ information-preserving transformations between types in the same
+ general type category. For example, the cast from <type>int2</type> to
+ <type>int4</type> can reasonably be implicit, but the cast from
+ <type>float8</type> to <type>int4</type> should probably be
+ assignment-only. Cross-type-category casts, such as <type>text</type>
+ to <type>int4</type>, are best made explicit-only.
+ </para>
+
+ <note>
+ <para>
+ Sometimes it is necessary for usability or standards-compliance reasons
+ to provide multiple implicit casts among a set of types, resulting in
+ ambiguity that cannot be avoided as above. The parser has a fallback
+ heuristic based on <firstterm>type categories</firstterm> and <firstterm>preferred
+ types</firstterm> that can help to provide desired behavior in such cases. See
+ <xref linkend="sql-createtype"/> for
+ more information.
+ </para>
+ </note>
+
+ <para>
+ To be able to create a cast, you must own the source or the target data type
+ and have <literal>USAGE</literal> privilege on the other type. To create a
+ binary-coercible cast, you must be superuser. (This restriction is made
+ because an erroneous binary-coercible cast conversion can easily crash the
+ server.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>source_type</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the source data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>target_type</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the target data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable>function_name</replaceable>[(<replaceable>argument_type</replaceable> [, ...])]</literal></term>
+
+ <listitem>
+ <para>
+ The function used to perform the cast. The function name can
+ be schema-qualified. If it is not, the function will be looked
+ up in the schema search path. The function's result data type must
+ match the target type of the cast. Its arguments are discussed below.
+ If no argument list is specified, the function name must be unique in
+ its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITHOUT FUNCTION</literal></term>
+
+ <listitem>
+ <para>
+ Indicates that the source type is binary-coercible to the target type,
+ so no function is required to perform the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH INOUT</literal></term>
+
+ <listitem>
+ <para>
+ Indicates that the cast is an I/O conversion cast, performed by
+ invoking the output function of the source data type, and passing the
+ resulting string to the input function of the target data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>AS ASSIGNMENT</literal></term>
+
+ <listitem>
+ <para>
+ Indicates that the cast can be invoked implicitly in assignment
+ contexts.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>AS IMPLICIT</literal></term>
+
+ <listitem>
+ <para>
+ Indicates that the cast can be invoked implicitly in any context.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Cast implementation functions can have one to three arguments.
+ The first argument type must be identical to or binary-coercible from
+ the cast's source type. The second argument,
+ if present, must be type <type>integer</type>; it receives the type
+ modifier associated with the destination type, or <literal>-1</literal>
+ if there is none. The third argument,
+ if present, must be type <type>boolean</type>; it receives <literal>true</literal>
+ if the cast is an explicit cast, <literal>false</literal> otherwise.
+ (Bizarrely, the SQL standard demands different behaviors for explicit and
+ implicit casts in some cases. This argument is supplied for functions
+ that must implement such casts. It is not recommended that you design
+ your own data types so that this matters.)
+ </para>
+
+ <para>
+ The return type of a cast function must be identical to or
+ binary-coercible to the cast's target type.
+ </para>
+
+ <para>
+ Ordinarily a cast must have different source and target data types.
+ However, it is allowed to declare a cast with identical source and
+ target types if it has a cast implementation function with more than one
+ argument. This is used to represent type-specific length coercion
+ functions in the system catalogs. The named function is used to
+ coerce a value of the type to the type modifier value given by its
+ second argument.
+ </para>
+
+ <para>
+ When a cast has different source and
+ target types and a function that takes more than one argument, it
+ supports converting from one type to another and applying a length
+ coercion in a single step. When no such entry is available, coercion
+ to a type that uses a type modifier involves two cast steps, one to
+ convert between data types and a second to apply the modifier.
+ </para>
+
+ <para>
+ A cast to or from a domain type currently has no effect. Casting
+ to or from a domain uses the casts associated with its underlying type.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="sql-createcast-notes">
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-dropcast"><command>DROP CAST</command></link> to remove user-defined casts.
+ </para>
+
+ <para>
+ Remember that if you want to be able to convert types both ways you
+ need to declare casts both ways explicitly.
+ </para>
+
+ <indexterm zone="sql-createcast">
+ <primary>cast</primary>
+ <secondary>I/O conversion</secondary>
+ </indexterm>
+
+ <para>
+ It is normally not necessary to create casts between user-defined types
+ and the standard string types (<type>text</type>, <type>varchar</type>, and
+ <type>char(<replaceable>n</replaceable>)</type>, as well as user-defined types that
+ are defined to be in the string category). <productname>PostgreSQL</productname>
+ provides automatic I/O conversion casts for that. The automatic casts to
+ string types are treated as assignment casts, while the automatic casts
+ from string types are
+ explicit-only. You can override this behavior by declaring your own
+ cast to replace an automatic cast, but usually the only reason to
+ do so is if you want the conversion to be more easily invokable than the
+ standard assignment-only or explicit-only setting. Another possible
+ reason is that you want the conversion to behave differently from the
+ type's I/O function; but that is sufficiently surprising that you
+ should think twice about whether it's a good idea. (A small number of
+ the built-in types do indeed have different behaviors for conversions,
+ mostly because of requirements of the SQL standard.)
+ </para>
+
+ <para>
+ While not required, it is recommended that you continue to follow this old
+ convention of naming cast implementation functions after the target data
+ type. Many users are used to being able to cast data types using a
+ function-style notation, that is
+ <replaceable>typename</replaceable>(<replaceable>x</replaceable>). This notation is in fact
+ nothing more nor less than a call of the cast implementation function; it
+ is not specially treated as a cast. If your conversion functions are not
+ named to support this convention then you will have surprised users.
+ Since <productname>PostgreSQL</productname> allows overloading of the same function
+ name with different argument types, there is no difficulty in having
+ multiple conversion functions from different types that all use the
+ target type's name.
+ </para>
+
+ <note>
+ <para>
+ Actually the preceding paragraph is an oversimplification: there are
+ two cases in which a function-call construct will be treated as a cast
+ request without having matched it to an actual function.
+ If a function call <replaceable>name</replaceable>(<replaceable>x</replaceable>) does not
+ exactly match any existing function, but <replaceable>name</replaceable> is the name
+ of a data type and <structname>pg_cast</structname> provides a binary-coercible cast
+ to this type from the type of <replaceable>x</replaceable>, then the call will be
+ construed as a binary-coercible cast. This exception is made so that
+ binary-coercible casts can be invoked using functional syntax, even
+ though they lack any function. Likewise, if there is no
+ <structname>pg_cast</structname> entry but the cast would be to or from a string
+ type, the call will be construed as an I/O conversion cast. This
+ exception allows I/O conversion casts to be invoked using functional
+ syntax.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ There is also an exception to the exception: I/O conversion casts from
+ composite types to string types cannot be invoked using functional
+ syntax, but must be written in explicit cast syntax (either
+ <literal>CAST</literal> or <literal>::</literal> notation). This exception was added
+ because after the introduction of automatically-provided I/O conversion
+ casts, it was found too easy to accidentally invoke such a cast when
+ a function or column reference was intended.
+ </para>
+ </note>
+ </refsect1>
+
+
+ <refsect1 id="sql-createcast-examples">
+ <title>Examples</title>
+
+ <para>
+ To create an assignment cast from type <type>bigint</type> to type
+ <type>int4</type> using the function <literal>int4(bigint)</literal>:
+<programlisting>
+CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;
+</programlisting>
+ (This cast is already predefined in the system.)
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createcast-compat">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>CREATE CAST</command> command conforms to the
+ <acronym>SQL</acronym> standard,
+ except that SQL does not make provisions for binary-coercible
+ types or extra arguments to implementation functions.
+ <literal>AS IMPLICIT</literal> is a <productname>PostgreSQL</productname>
+ extension, too.
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="sql-createcast-seealso">
+ <title>See Also</title>
+
+ <para>
+ <xref linkend="sql-createfunction"/>,
+ <xref linkend="sql-createtype"/>,
+ <xref linkend="sql-dropcast"/>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml
new file mode 100644
index 0000000..58f5f0c
--- /dev/null
+++ b/doc/src/sgml/ref/create_collation.sgml
@@ -0,0 +1,263 @@
+<!--
+doc/src/sgml/ref/create_collation.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createcollation">
+ <indexterm zone="sql-createcollation">
+ <primary>CREATE COLLATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE COLLATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE COLLATION</refname>
+ <refpurpose>define a new collation</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> (
+ [ LOCALE = <replaceable>locale</replaceable>, ]
+ [ LC_COLLATE = <replaceable>lc_collate</replaceable>, ]
+ [ LC_CTYPE = <replaceable>lc_ctype</replaceable>, ]
+ [ PROVIDER = <replaceable>provider</replaceable>, ]
+ [ DETERMINISTIC = <replaceable>boolean</replaceable>, ]
+ [ VERSION = <replaceable>version</replaceable> ]
+)
+CREATE COLLATION [ IF NOT EXISTS ] <replaceable>name</replaceable> FROM <replaceable>existing_collation</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createcollation-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE COLLATION</command> defines a new collation using
+ the specified operating system locale settings,
+ or by copying an existing collation.
+ </para>
+
+ <para>
+ To be able to create a collation, you must
+ have <literal>CREATE</literal> privilege on the destination schema.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a collation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing collation is anything like the one that would have been created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the collation. The collation name can be
+ schema-qualified. If it is not, the collation is defined in the
+ current schema. The collation name must be unique within that
+ schema. (The system catalogs can contain collations with the
+ same name for other encodings, but these are ignored if the
+ database encoding does not match.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>locale</replaceable></term>
+
+ <listitem>
+ <para>
+ This is a shortcut for setting <symbol>LC_COLLATE</symbol>
+ and <symbol>LC_CTYPE</symbol> at once. If you specify this,
+ you cannot specify either of those parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>lc_collate</replaceable></term>
+
+ <listitem>
+ <para>
+ Use the specified operating system locale for
+ the <symbol>LC_COLLATE</symbol> locale category.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>lc_ctype</replaceable></term>
+
+ <listitem>
+ <para>
+ Use the specified operating system locale for
+ the <symbol>LC_CTYPE</symbol> locale category.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>provider</replaceable></term>
+
+ <listitem>
+ <para>
+ Specifies the provider to use for locale services associated with this
+ collation. Possible values
+ are: <literal>icu</literal>,<indexterm><primary>ICU</primary></indexterm>
+ <literal>libc</literal>.
+ <literal>libc</literal> is the default.
+ The available choices depend on the operating system and build options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DETERMINISTIC</literal></term>
+
+ <listitem>
+ <para>
+ Specifies whether the collation should use deterministic comparisons.
+ The default is true. A deterministic comparison considers strings that
+ are not byte-wise equal to be unequal even if they are considered
+ logically equal by the comparison. PostgreSQL breaks ties using a
+ byte-wise comparison. Comparison that is not deterministic can make the
+ collation be, say, case- or accent-insensitive. For that, you need to
+ choose an appropriate <literal>LC_COLLATE</literal> setting
+ <emphasis>and</emphasis> set the collation to not deterministic here.
+ </para>
+
+ <para>
+ Nondeterministic collations are only supported with the ICU provider.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>version</replaceable></term>
+
+ <listitem>
+ <para>
+ Specifies the version string to store with the collation. Normally,
+ this should be omitted, which will cause the version to be computed
+ from the actual version of the collation as provided by the operating
+ system. This option is intended to be used
+ by <command>pg_upgrade</command> for copying the version from an
+ existing installation.
+ </para>
+
+ <para>
+ See also <xref linkend="sql-altercollation"/> for how to handle
+ collation version mismatches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>existing_collation</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an existing collation to copy. The new collation
+ will have the same properties as the existing one, but it
+ will be an independent object.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1 id="sql-createcollation-notes">
+ <title>Notes</title>
+
+ <para>
+ <command>CREATE COLLATION</command> takes a <literal>SHARE ROW
+ EXCLUSIVE</literal> lock, which is self-conflicting, on the
+ <structname>pg_collation</structname> system catalog, so only one
+ <command>CREATE COLLATION</command> command can run at a time.
+ </para>
+
+ <para>
+ Use <command>DROP COLLATION</command> to remove user-defined collations.
+ </para>
+
+ <para>
+ See <xref linkend="collation-create"/> for more information on how to create collations.
+ </para>
+
+ <para>
+ When using the <literal>libc</literal> collation provider, the locale must
+ be applicable to the current database encoding.
+ See <xref linkend="sql-createdatabase"/> for the precise rules.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createcollation-examples">
+ <title>Examples</title>
+
+ <para>
+ To create a collation from the operating system locale
+ <literal>fr_FR.utf8</literal>
+ (assuming the current database encoding is <literal>UTF8</literal>):
+<programlisting>
+CREATE COLLATION french (locale = 'fr_FR.utf8');
+</programlisting>
+ </para>
+
+ <para>
+ To create a collation using the ICU provider using German phone book sort order:
+<programlisting>
+CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk');
+</programlisting>
+ </para>
+
+ <para>
+ To create a collation from an existing collation:
+<programlisting>
+CREATE COLLATION german FROM "de_DE";
+</programlisting>
+ This can be convenient to be able to use operating-system-independent
+ collation names in applications.
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="sql-createcollation-compat">
+ <title>Compatibility</title>
+
+ <para>
+ There is a <command>CREATE COLLATION</command> statement in the SQL
+ standard, but it is limited to copying an existing collation. The
+ syntax to create a new collation is
+ a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="sql-createcollation-seealso">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altercollation"/></member>
+ <member><xref linkend="sql-dropcollation"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_conversion.sgml b/doc/src/sgml/ref/create_conversion.sgml
new file mode 100644
index 0000000..75d7b00
--- /dev/null
+++ b/doc/src/sgml/ref/create_conversion.sgml
@@ -0,0 +1,189 @@
+<!--
+doc/src/sgml/ref/create_conversion.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createconversion">
+ <indexterm zone="sql-createconversion">
+ <primary>CREATE CONVERSION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE CONVERSION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE CONVERSION</refname>
+ <refpurpose>define a new encoding conversion</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ DEFAULT ] CONVERSION <replaceable>name</replaceable>
+ FOR <replaceable>source_encoding</replaceable> TO <replaceable>dest_encoding</replaceable> FROM <replaceable>function_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createconversion-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE CONVERSION</command> defines a new conversion between
+ two character set encodings.
+ </para>
+
+ <para>
+ Conversions that are marked <literal>DEFAULT</literal> can be used for
+ automatic encoding conversion between client and server. To support that
+ usage, two conversions, from encoding A to B <emphasis>and</emphasis>
+ from encoding B to A, must be defined.
+ </para>
+
+ <para>
+ To be able to create a conversion, you must have <literal>EXECUTE</literal> privilege
+ on the function and <literal>CREATE</literal> privilege on the destination schema.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+
+ <listitem>
+ <para>
+ The <literal>DEFAULT</literal> clause indicates that this conversion
+ is the default for this particular source to destination
+ encoding. There should be only one default encoding in a schema
+ for the encoding pair.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the conversion. The conversion name can be
+ schema-qualified. If it is not, the conversion is defined in the
+ current schema. The conversion name must be unique within a
+ schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>source_encoding</replaceable></term>
+
+ <listitem>
+ <para>
+ The source encoding name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>dest_encoding</replaceable></term>
+
+ <listitem>
+ <para>
+ The destination encoding name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>function_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The function used to perform the conversion. The function name can
+ be schema-qualified. If it is not, the function will be looked
+ up in the path.
+ </para>
+
+ <para>
+ The function must have the following signature:
+
+<programlisting>
+conv_proc(
+ integer, -- source encoding ID
+ integer, -- destination encoding ID
+ cstring, -- source string (null terminated C string)
+ internal, -- destination (fill with a null terminated C string)
+ integer, -- source string length
+ boolean -- if true, don't throw an error if conversion fails
+) RETURNS integer;
+</programlisting>
+ The return value is the number of source bytes that were successfully
+ converted. If the last argument is false, the function must throw an
+ error on invalid input, and the return value is always equal to the
+ source string length.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createconversion-notes">
+ <title>Notes</title>
+
+ <para>
+ Neither the source nor the destination encoding can
+ be <literal>SQL_ASCII</literal>, as the server's behavior for cases
+ involving the <literal>SQL_ASCII</literal> <quote>encoding</quote> is
+ hard-wired.
+ </para>
+
+ <para>
+ Use <command>DROP CONVERSION</command> to remove user-defined conversions.
+ </para>
+
+ <para>
+ The privileges required to create a conversion might be changed in a future
+ release.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createconversion-examples">
+ <title>Examples</title>
+
+ <para>
+ To create a conversion from encoding <literal>UTF8</literal> to
+ <literal>LATIN1</literal> using <function>myfunc</function>:
+<programlisting>
+CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;
+</programlisting></para>
+ </refsect1>
+
+
+ <refsect1 id="sql-createconversion-compat">
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE CONVERSION</command>
+ is a <productname>PostgreSQL</productname> extension.
+ There is no <command>CREATE CONVERSION</command>
+ statement in the SQL standard, but a <command>CREATE TRANSLATION</command>
+ statement that is very similar in purpose and syntax.
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="sql-createconversion-seealso">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterconversion"/></member>
+ <member><xref linkend="sql-createfunction"/></member>
+ <member><xref linkend="sql-dropconversion"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml
new file mode 100644
index 0000000..ea38c64
--- /dev/null
+++ b/doc/src/sgml/ref/create_database.sgml
@@ -0,0 +1,449 @@
+<!--
+doc/src/sgml/ref/create_database.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createdatabase">
+ <indexterm zone="sql-createdatabase">
+ <primary>CREATE DATABASE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE DATABASE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE DATABASE</refname>
+ <refpurpose>create a new database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE DATABASE <replaceable class="parameter">name</replaceable>
+ [ WITH ] [ OWNER [=] <replaceable class="parameter">user_name</replaceable> ]
+ [ TEMPLATE [=] <replaceable class="parameter">template</replaceable> ]
+ [ ENCODING [=] <replaceable class="parameter">encoding</replaceable> ]
+ [ STRATEGY [=] <replaceable class="parameter">strategy</replaceable> ] ]
+ [ LOCALE [=] <replaceable class="parameter">locale</replaceable> ]
+ [ LC_COLLATE [=] <replaceable class="parameter">lc_collate</replaceable> ]
+ [ LC_CTYPE [=] <replaceable class="parameter">lc_ctype</replaceable> ]
+ [ ICU_LOCALE [=] <replaceable class="parameter">icu_locale</replaceable> ]
+ [ LOCALE_PROVIDER [=] <replaceable class="parameter">locale_provider</replaceable> ]
+ [ COLLATION_VERSION = <replaceable>collation_version</replaceable> ]
+ [ TABLESPACE [=] <replaceable class="parameter">tablespace_name</replaceable> ]
+ [ ALLOW_CONNECTIONS [=] <replaceable class="parameter">allowconn</replaceable> ]
+ [ CONNECTION LIMIT [=] <replaceable class="parameter">connlimit</replaceable> ]
+ [ IS_TEMPLATE [=] <replaceable class="parameter">istemplate</replaceable> ]
+ [ OID [=] <replaceable class="parameter">oid</replaceable> ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE DATABASE</command> creates a new
+ <productname>PostgreSQL</productname> database.
+ </para>
+
+ <para>
+ To create a database, you must be a superuser or have the special
+ <literal>CREATEDB</literal> privilege.
+ See <xref linkend="sql-createrole"/>.
+ </para>
+
+ <para>
+ By default, the new database will be created by cloning the standard
+ system database <literal>template1</literal>. A different template can be
+ specified by writing <literal>TEMPLATE
+ <replaceable class="parameter">name</replaceable></literal>. In particular,
+ by writing <literal>TEMPLATE template0</literal>, you can create a pristine
+ database (one where no user-defined objects exist and where the system
+ objects have not been altered)
+ containing only the standard objects predefined by your
+ version of <productname>PostgreSQL</productname>. This is useful
+ if you wish to avoid copying
+ any installation-local objects that might have been added to
+ <literal>template1</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a database to create.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ The role name of the user who will own the new database,
+ or <literal>DEFAULT</literal> to use the default (namely, the
+ user executing the command). To create a database owned by another
+ role, you must be a direct or indirect member of that role,
+ or be a superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">template</replaceable></term>
+ <listitem>
+ <para>
+ The name of the template from which to create the new database,
+ or <literal>DEFAULT</literal> to use the default template
+ (<literal>template1</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">encoding</replaceable></term>
+ <listitem>
+ <para>
+ Character set encoding to use in the new database. Specify
+ a string constant (e.g., <literal>'SQL_ASCII'</literal>),
+ or an integer encoding number, or <literal>DEFAULT</literal>
+ to use the default encoding (namely, the encoding of the
+ template database). The character sets supported by the
+ <productname>PostgreSQL</productname> server are described in
+ <xref linkend="multibyte-charset-supported"/>. See below for
+ additional restrictions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry id="create-database-strategy" xreflabel="CREATE DATABASE STRATEGY">
+ <term><replaceable class="parameter">strategy</replaceable></term>
+ <listitem>
+ <para>
+ Strategy to be used in creating the new database. If
+ the <literal>WAL_LOG</literal> strategy is used, the database will be
+ copied block by block and each block will be separately written
+ to the write-ahead log. This is the most efficient strategy in
+ cases where the template database is small, and therefore it is the
+ default. The older <literal>FILE_COPY</literal> strategy is also
+ available. This strategy writes a small record to the write-ahead log
+ for each tablespace used by the target database. Each such record
+ represents copying an entire directory to a new location at the
+ filesystem level. While this does reduce the write-ahead
+ log volume substantially, especially if the template database is large,
+ it also forces the system to perform a checkpoint both before and
+ after the creation of the new database. In some situations, this may
+ have a noticeable negative impact on overall system performance.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">locale</replaceable></term>
+ <listitem>
+ <para>
+ This is a shortcut for setting <symbol>LC_COLLATE</symbol>
+ and <symbol>LC_CTYPE</symbol> at once.
+ </para>
+ <tip>
+ <para>
+ The other locale settings <xref linkend="guc-lc-messages"/>, <xref
+ linkend="guc-lc-monetary"/>, <xref linkend="guc-lc-numeric"/>, and
+ <xref linkend="guc-lc-time"/> are not fixed per database and are not
+ set by this command. If you want to make them the default for a
+ specific database, you can use <literal>ALTER DATABASE
+ ... SET</literal>.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">lc_collate</replaceable></term>
+ <listitem>
+ <para>
+ Collation order (<literal>LC_COLLATE</literal>) to use in the new database.
+ This affects the sort order applied to strings, e.g., in queries with
+ ORDER BY, as well as the order used in indexes on text columns.
+ The default is to use the collation order of the template database.
+ See below for additional restrictions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">lc_ctype</replaceable></term>
+ <listitem>
+ <para>
+ Character classification (<literal>LC_CTYPE</literal>) to use in the new
+ database. This affects the categorization of characters, e.g., lower,
+ upper and digit. The default is to use the character classification of
+ the template database. See below for additional restrictions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">icu_locale</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the ICU locale ID if the ICU locale provider is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>locale_provider</replaceable></term>
+
+ <listitem>
+ <para>
+ Specifies the provider to use for the default collation in this
+ database. Possible values are:
+ <literal>icu</literal>,<indexterm><primary>ICU</primary></indexterm>
+ <literal>libc</literal>. <literal>libc</literal> is the default. The
+ available choices depend on the operating system and build options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>collation_version</replaceable></term>
+
+ <listitem>
+ <para>
+ Specifies the collation version string to store with the database.
+ Normally, this should be omitted, which will cause the version to be
+ computed from the actual version of the database collation as provided
+ by the operating system. This option is intended to be used by
+ <command>pg_upgrade</command> for copying the version from an existing
+ installation.
+ </para>
+
+ <para>
+ See also <xref linkend="sql-alterdatabase"/> for how to handle
+ database collation version mismatches.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">tablespace_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the tablespace that will be associated with the
+ new database, or <literal>DEFAULT</literal> to use the
+ template database's tablespace. This
+ tablespace will be the default tablespace used for objects
+ created in this database. See
+ <xref linkend="sql-createtablespace"/>
+ for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">allowconn</replaceable></term>
+ <listitem>
+ <para>
+ If false then no one can connect to this database. The default is
+ true, allowing connections (except as restricted by other mechanisms,
+ such as <literal>GRANT</literal>/<literal>REVOKE CONNECT</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">connlimit</replaceable></term>
+ <listitem>
+ <para>
+ How many concurrent connections can be made
+ to this database. -1 (the default) means no limit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">istemplate</replaceable></term>
+ <listitem>
+ <para>
+ If true, then this database can be cloned by any user with <literal>CREATEDB</literal>
+ privileges; if false (the default), then only superusers or the owner
+ of the database can clone it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">oid</replaceable></term>
+ <listitem>
+ <para>
+ The object identifier to be used for the new database. If this
+ parameter is not specified, <productname>PostgreSQL</productname>
+ will choose a suitable OID automatically. This parameter is primarily
+ intended for internal use by <application>pg_upgrade</application>,
+ and only <application>pg_upgrade</application> can specify a value
+ less than 16384.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Optional parameters can be written in any order, not only the order
+ illustrated above.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>CREATE DATABASE</command> cannot be executed inside a transaction
+ block.
+ </para>
+
+ <para>
+ Errors along the line of <quote>could not initialize database directory</quote>
+ are most likely related to insufficient permissions on the data
+ directory, a full disk, or other file system problems.
+ </para>
+
+ <para>
+ Use <link linkend="sql-dropdatabase"><command>DROP DATABASE</command></link> to remove a database.
+ </para>
+
+ <para>
+ The program <xref linkend="app-createdb"/> is a
+ wrapper program around this command, provided for convenience.
+ </para>
+
+ <para>
+ Database-level configuration parameters (set via <link
+ linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>) and database-level permissions (set via
+ <link linkend="sql-grant"><command>GRANT</command></link>) are not copied from the template database.
+ </para>
+
+ <para>
+ Although it is possible to copy a database other than <literal>template1</literal>
+ by specifying its name as the template, this is not (yet) intended as
+ a general-purpose <quote><command>COPY DATABASE</command></quote> facility.
+ The principal limitation is that no other sessions can be connected to
+ the template database while it is being copied. <command>CREATE
+ DATABASE</command> will fail if any other connection exists when it starts;
+ otherwise, new connections to the template database are locked out
+ until <command>CREATE DATABASE</command> completes.
+ See <xref linkend="manage-ag-templatedbs"/> for more information.
+ </para>
+
+ <para>
+ The character set encoding specified for the new database must be
+ compatible with the chosen locale settings (<literal>LC_COLLATE</literal> and
+ <literal>LC_CTYPE</literal>). If the locale is <literal>C</literal> (or equivalently
+ <literal>POSIX</literal>), then all encodings are allowed, but for other
+ locale settings there is only one encoding that will work properly.
+ (On Windows, however, UTF-8 encoding can be used with any locale.)
+ <command>CREATE DATABASE</command> will allow superusers to specify
+ <literal>SQL_ASCII</literal> encoding regardless of the locale settings,
+ but this choice is deprecated and may result in misbehavior of
+ character-string functions if data that is not encoding-compatible
+ with the locale is stored in the database.
+ </para>
+
+ <para>
+ The encoding and locale settings must match those of the template database,
+ except when <literal>template0</literal> is used as template. This is because
+ other databases might contain data that does not match the specified
+ encoding, or might contain indexes whose sort ordering is affected by
+ <literal>LC_COLLATE</literal> and <literal>LC_CTYPE</literal>. Copying such data would
+ result in a database that is corrupt according to the new settings.
+ <literal>template0</literal>, however, is known to not contain any data or
+ indexes that would be affected.
+ </para>
+
+ <para>
+ There is currently no option to use a database locale with nondeterministic
+ comparisons (see <link linkend="sql-createcollation"><command>CREATE
+ COLLATION</command></link> for an explanation). If this is needed, then
+ per-column collations would need to be used.
+ </para>
+
+ <para>
+ The <literal>CONNECTION LIMIT</literal> option is only enforced approximately;
+ if two new sessions start at about the same time when just one
+ connection <quote>slot</quote> remains for the database, it is possible that
+ both will fail. Also, the limit is not enforced against superusers or
+ background worker processes.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create a new database:
+
+<programlisting>
+CREATE DATABASE lusiadas;
+</programlisting>
+ </para>
+
+ <para>
+ To create a database <literal>sales</literal> owned by user <literal>salesapp</literal>
+ with a default tablespace of <literal>salesspace</literal>:
+
+<programlisting>
+CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace;
+</programlisting>
+ </para>
+
+ <para>
+ To create a database <literal>music</literal> with a different locale:
+<programlisting>
+CREATE DATABASE music
+ LOCALE 'sv_SE.utf8'
+ TEMPLATE template0;
+</programlisting>
+ In this example, the <literal>TEMPLATE template0</literal> clause is required if
+ the specified locale is different from the one in <literal>template1</literal>.
+ (If it is not, then specifying the locale explicitly is redundant.)
+ </para>
+
+ <para>
+ To create a database <literal>music2</literal> with a different locale and a
+ different character set encoding:
+<programlisting>
+CREATE DATABASE music2
+ LOCALE 'sv_SE.iso885915'
+ ENCODING LATIN9
+ TEMPLATE template0;
+</programlisting>
+ The specified locale and encoding settings must match, or an error will be
+ reported.
+ </para>
+
+ <para>
+ Note that locale names are specific to the operating system, so that the
+ above commands might not work in the same way everywhere.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CREATE DATABASE</command> statement in the SQL
+ standard. Databases are equivalent to catalogs, whose creation is
+ implementation-defined.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterdatabase"/></member>
+ <member><xref linkend="sql-dropdatabase"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_domain.sgml b/doc/src/sgml/ref/create_domain.sgml
new file mode 100644
index 0000000..82a0b87
--- /dev/null
+++ b/doc/src/sgml/ref/create_domain.sgml
@@ -0,0 +1,288 @@
+<!--
+doc/src/sgml/ref/create_domain.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createdomain">
+ <indexterm zone="sql-createdomain">
+ <primary>CREATE DOMAIN</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE DOMAIN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE DOMAIN</refname>
+ <refpurpose>define a new domain</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE DOMAIN <replaceable class="parameter">name</replaceable> [ AS ] <replaceable class="parameter">data_type</replaceable>
+ [ COLLATE <replaceable>collation</replaceable> ]
+ [ DEFAULT <replaceable>expression</replaceable> ]
+ [ <replaceable class="parameter">constraint</replaceable> [ ... ] ]
+
+<phrase>where <replaceable class="parameter">constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+{ NOT NULL | NULL | CHECK (<replaceable class="parameter">expression</replaceable>) }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE DOMAIN</command> creates a new domain. A domain is
+ essentially a data type with optional constraints (restrictions on
+ the allowed set of values).
+ The user who defines a domain becomes its owner.
+ </para>
+
+ <para>
+ If a schema name is given (for example, <literal>CREATE DOMAIN
+ myschema.mydomain ...</literal>) then the domain is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The domain name must be unique among the types and domains existing
+ in its schema.
+ </para>
+
+ <para>
+ Domains are useful for abstracting common constraints on fields into
+ a single location for maintenance. For example, several tables might
+ contain email address columns, all requiring the same CHECK constraint
+ to verify the address syntax.
+ Define a domain rather than setting up each table's constraint
+ individually.
+ </para>
+
+ <para>
+ To be able to create a domain, you must have <literal>USAGE</literal>
+ privilege on the underlying type.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a domain to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The underlying data type of the domain. This can include array
+ specifiers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>collation</replaceable></term>
+ <listitem>
+ <para>
+ An optional collation for the domain. If no collation is
+ specified, the domain has the same collation behavior as its
+ underlying data type.
+ The underlying type must be collatable if <literal>COLLATE</literal>
+ is specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT <replaceable>expression</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ The <literal>DEFAULT</literal> clause specifies a default value for
+ columns of the domain data type. The value is any
+ variable-free expression (but subqueries are not allowed).
+ The data type of the default expression must match the data
+ type of the domain. If no default value is specified, then
+ the default value is the null value.
+ </para>
+
+ <para>
+ The default expression will be used in any insert operation
+ that does not specify a value for the column. If a default
+ value is defined for a particular column, it overrides any
+ default associated with the domain. In turn, the domain
+ default overrides any default value associated with the
+ underlying data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONSTRAINT <replaceable class="parameter">constraint_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ An optional name for a constraint. If not specified,
+ the system generates a name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOT NULL</literal></term>
+ <listitem>
+ <para>
+ Values of this domain are prevented from being null
+ (but see notes below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULL</literal></term>
+ <listitem>
+ <para>
+ Values of this domain are allowed to be null. This is the default.
+ </para>
+
+ <para>
+ This clause is only intended for compatibility with
+ nonstandard SQL databases. Its use is discouraged in new
+ applications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CHECK (<replaceable class="parameter">expression</replaceable>)</literal></term>
+ <listitem>
+ <para><literal>CHECK</literal> clauses specify integrity constraints or tests
+ which values of the domain must satisfy.
+ Each constraint must be an expression
+ producing a Boolean result. It should use the key word <literal>VALUE</literal>
+ to refer to the value being tested. Expressions evaluating
+ to TRUE or UNKNOWN succeed. If the expression produces a FALSE result,
+ an error is reported and the value is not allowed to be converted
+ to the domain type.
+ </para>
+
+ <para>
+ Currently, <literal>CHECK</literal> expressions cannot contain
+ subqueries nor refer to variables other than <literal>VALUE</literal>.
+ </para>
+
+ <para>
+ When a domain has multiple <literal>CHECK</literal> constraints,
+ they will be tested in alphabetical order by name.
+ (<productname>PostgreSQL</productname> versions before 9.5 did not honor any
+ particular firing order for <literal>CHECK</literal> constraints.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Domain constraints, particularly <literal>NOT NULL</literal>, are checked when
+ converting a value to the domain type. It is possible for a column that
+ is nominally of the domain type to read as null despite there being such
+ a constraint. For example, this can happen in an outer-join query, if
+ the domain column is on the nullable side of the outer join. A more
+ subtle example is
+<programlisting>
+INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));
+</programlisting>
+ The empty scalar sub-SELECT will produce a null value that is considered
+ to be of the domain type, so no further constraint checking is applied
+ to it, and the insertion will succeed.
+ </para>
+
+ <para>
+ It is very difficult to avoid such problems, because of SQL's general
+ assumption that a null value is a valid value of every data type. Best practice
+ therefore is to design a domain's constraints so that a null value is allowed,
+ and then to apply column <literal>NOT NULL</literal> constraints to columns of
+ the domain type as needed, rather than directly to the domain type.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> assumes that
+ <literal>CHECK</literal> constraints' conditions are immutable, that is,
+ they will always give the same result for the same input value. This
+ assumption is what justifies examining <literal>CHECK</literal>
+ constraints only when a value is first converted to be of a domain type,
+ and not at other times. (This is essentially the same as the treatment
+ of table <literal>CHECK</literal> constraints, as described in
+ <xref linkend="ddl-constraints-check-constraints"/>.)
+ </para>
+
+ <para>
+ An example of a common way to break this assumption is to reference a
+ user-defined function in a <literal>CHECK</literal> expression, and then
+ change the behavior of that
+ function. <productname>PostgreSQL</productname> does not disallow that,
+ but it will not notice if there are stored values of the domain type that
+ now violate the <literal>CHECK</literal> constraint. That would cause a
+ subsequent database dump and restore to fail. The recommended way to
+ handle such a change is to drop the constraint (using <command>ALTER
+ DOMAIN</command>), adjust the function definition, and re-add the
+ constraint, thereby rechecking it against stored data.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This example creates the <type>us_postal_code</type> data type and
+ then uses the type in a table definition. A regular expression test
+ is used to verify that the value looks like a valid US postal code:
+
+<programlisting>
+CREATE DOMAIN us_postal_code AS TEXT
+CHECK(
+ VALUE ~ '^\d{5}$'
+OR VALUE ~ '^\d{5}-\d{4}$'
+);
+
+CREATE TABLE us_snail_addy (
+ address_id SERIAL PRIMARY KEY,
+ street1 TEXT NOT NULL,
+ street2 TEXT,
+ street3 TEXT,
+ city TEXT NOT NULL,
+ postal us_postal_code NOT NULL
+);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-createdomain-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The command <command>CREATE DOMAIN</command> conforms to the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createdomain-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterdomain"/></member>
+ <member><xref linkend="sql-dropdomain"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_event_trigger.sgml b/doc/src/sgml/ref/create_event_trigger.sgml
new file mode 100644
index 0000000..22c8119
--- /dev/null
+++ b/doc/src/sgml/ref/create_event_trigger.sgml
@@ -0,0 +1,170 @@
+<!--
+doc/src/sgml/ref/create_event_trigger.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createeventtrigger">
+ <indexterm zone="sql-createeventtrigger">
+ <primary>CREATE EVENT TRIGGER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE EVENT TRIGGER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE EVENT TRIGGER</refname>
+ <refpurpose>define a new event trigger</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE EVENT TRIGGER <replaceable class="parameter">name</replaceable>
+ ON <replaceable class="parameter">event</replaceable>
+ [ WHEN <replaceable class="parameter">filter_variable</replaceable> IN (<replaceable class="parameter">filter_value</replaceable> [, ... ]) [ AND ... ] ]
+ EXECUTE { FUNCTION | PROCEDURE } <replaceable class="parameter">function_name</replaceable>()
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE EVENT TRIGGER</command> creates a new event trigger.
+ Whenever the designated event occurs and the <literal>WHEN</literal> condition
+ associated with the trigger, if any, is satisfied, the trigger function
+ will be executed. For a general introduction to event triggers, see
+ <xref linkend="event-triggers"/>. The user who creates an event trigger
+ becomes its owner.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name to give the new trigger. This name must be unique within
+ the database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">event</replaceable></term>
+ <listitem>
+ <para>
+ The name of the event that triggers a call to the given function.
+ See <xref linkend="event-trigger-definition"/> for more information
+ on event names.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">filter_variable</replaceable></term>
+ <listitem>
+ <para>
+ The name of a variable used to filter events. This makes it possible
+ to restrict the firing of the trigger to a subset of the cases in which
+ it is supported. Currently the only supported
+ <replaceable class="parameter">filter_variable</replaceable>
+ is <literal>TAG</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">filter_value</replaceable></term>
+ <listitem>
+ <para>
+ A list of values for the
+ associated <replaceable class="parameter">filter_variable</replaceable>
+ for which the trigger should fire. For <literal>TAG</literal>, this means a
+ list of command tags (e.g., <literal>'DROP FUNCTION'</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <listitem>
+ <para>
+ A user-supplied function that is declared as taking no argument and
+ returning type <literal>event_trigger</literal>.
+ </para>
+
+ <para>
+ In the syntax of <literal>CREATE EVENT TRIGGER</literal>, the keywords
+ <literal>FUNCTION</literal> and <literal>PROCEDURE</literal> are
+ equivalent, but the referenced function must in any case be a function,
+ not a procedure. The use of the keyword <literal>PROCEDURE</literal>
+ here is historical and deprecated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createeventtrigger-notes">
+ <title>Notes</title>
+
+ <para>
+ Only superusers can create event triggers.
+ </para>
+
+ <para>
+ Event triggers are disabled in single-user mode (see <xref
+ linkend="app-postgres"/>). If an erroneous event trigger disables the
+ database so much that you can't even drop the trigger, restart in
+ single-user mode and you'll be able to do that.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createeventtrigger-examples">
+ <title>Examples</title>
+
+ <para>
+ Forbid the execution of any <link linkend="ddl">DDL</link> command:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION abort_any_command()
+ RETURNS event_trigger
+ LANGUAGE plpgsql
+ AS $$
+BEGIN
+ RAISE EXCEPTION 'command % is disabled', tg_tag;
+END;
+$$;
+
+CREATE EVENT TRIGGER abort_ddl ON ddl_command_start
+ EXECUTE FUNCTION abort_any_command();
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-createeventtrigger-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CREATE EVENT TRIGGER</command> statement in the
+ SQL standard.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altereventtrigger"/></member>
+ <member><xref linkend="sql-dropeventtrigger"/></member>
+ <member><xref linkend="sql-createfunction"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_extension.sgml b/doc/src/sgml/ref/create_extension.sgml
new file mode 100644
index 0000000..ca2b80d
--- /dev/null
+++ b/doc/src/sgml/ref/create_extension.sgml
@@ -0,0 +1,247 @@
+<!--
+doc/src/sgml/ref/create_extension.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createextension">
+ <indexterm zone="sql-createextension">
+ <primary>CREATE EXTENSION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE EXTENSION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE EXTENSION</refname>
+ <refpurpose>install an extension</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE EXTENSION [ IF NOT EXISTS ] <replaceable class="parameter">extension_name</replaceable>
+ [ WITH ] [ SCHEMA <replaceable class="parameter">schema_name</replaceable> ]
+ [ VERSION <replaceable class="parameter">version</replaceable> ]
+ [ CASCADE ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE EXTENSION</command> loads a new extension into the current
+ database. There must not be an extension of the same name already loaded.
+ </para>
+
+ <para>
+ Loading an extension essentially amounts to running the extension's script
+ file. The script will typically create new <acronym>SQL</acronym> objects such as
+ functions, data types, operators and index support methods.
+ <command>CREATE EXTENSION</command> additionally records the identities
+ of all the created objects, so that they can be dropped again if
+ <command>DROP EXTENSION</command> is issued.
+ </para>
+
+ <para>
+ The user who runs <command>CREATE EXTENSION</command> becomes the
+ owner of the extension for purposes of later privilege checks, and
+ normally also becomes the owner of any objects created by the
+ extension's script.
+ </para>
+
+ <para>
+ Loading an extension ordinarily requires the same privileges that would
+ be required to create its component objects. For many extensions this
+ means superuser privileges are needed.
+ However, if the extension is marked <firstterm>trusted</firstterm> in
+ its control file, then it can be installed by any user who has
+ <literal>CREATE</literal> privilege on the current database.
+ In this case the extension object itself will be owned by the calling
+ user, but the contained objects will be owned by the bootstrap superuser
+ (unless the extension's script explicitly assigns them to the calling
+ user). This configuration gives the calling user the right to drop the
+ extension, but not to modify individual objects within it.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if an extension with the same name already
+ exists. A notice is issued in this case. Note that there is no
+ guarantee that the existing extension is anything like the one that
+ would have been created from the currently-available script file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">extension_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the extension to be
+ installed. <productname>PostgreSQL</productname> will create the
+ extension using details from the file
+ <literal>SHAREDIR/extension/</literal><replaceable class="parameter">extension_name</replaceable><literal>.control</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">schema_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the schema in which to install the extension's
+ objects, given that the extension allows its contents to be
+ relocated. The named schema must already exist.
+ If not specified, and the extension's control file does not specify a
+ schema either, the current default object creation schema is used.
+ </para>
+
+ <para>
+ If the extension specifies a <literal>schema</literal> parameter in its
+ control file, then that schema cannot be overridden with
+ a <literal>SCHEMA</literal> clause. Normally, an error will be raised if
+ a <literal>SCHEMA</literal> clause is given and it conflicts with the
+ extension's <literal>schema</literal> parameter. However, if
+ the <literal>CASCADE</literal> clause is also given,
+ then <replaceable class="parameter">schema_name</replaceable> is
+ ignored when it conflicts. The
+ given <replaceable class="parameter">schema_name</replaceable> will be
+ used for installation of any needed extensions that do not
+ specify <literal>schema</literal> in their control files.
+ </para>
+
+ <para>
+ Remember that the extension itself is not considered to be within any
+ schema: extensions have unqualified names that must be unique
+ database-wide. But objects belonging to the extension can be within
+ schemas.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">version</replaceable></term>
+ <listitem>
+ <para>
+ The version of the extension to install. This can be written as
+ either an identifier or a string literal. The default version is
+ whatever is specified in the extension's control file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically install any extensions that this extension depends on
+ that are not already installed. Their dependencies are likewise
+ automatically installed, recursively. The <literal>SCHEMA</literal> clause,
+ if given, applies to all extensions that get installed this way.
+ Other options of the statement are not applied to
+ automatically-installed extensions; in particular, their default
+ versions are always selected.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Before you can use <command>CREATE EXTENSION</command> to load an extension
+ into a database, the extension's supporting files must be installed.
+ Information about installing the extensions supplied with
+ <productname>PostgreSQL</productname> can be found in
+ <link linkend="contrib">Additional Supplied Modules</link>.
+ </para>
+
+ <para>
+ The extensions currently available for loading can be identified from the
+ <link linkend="view-pg-available-extensions"><structname>pg_available_extensions</structname></link>
+ or
+ <link linkend="view-pg-available-extension-versions"><structname>pg_available_extension_versions</structname></link>
+ system views.
+ </para>
+
+ <caution>
+ <para>
+ Installing an extension as superuser requires trusting that the
+ extension's author wrote the extension installation script in a secure
+ fashion. It is not terribly difficult for a malicious user to create
+ trojan-horse objects that will compromise later execution of a
+ carelessly-written extension script, allowing that user to acquire
+ superuser privileges. However, trojan-horse objects are only hazardous
+ if they are in the <varname>search_path</varname> during script
+ execution, meaning that they are in the extension's installation target
+ schema or in the schema of some extension it depends on. Therefore, a
+ good rule of thumb when dealing with extensions whose scripts have not
+ been carefully vetted is to install them only into schemas for which
+ CREATE privilege has not been and will not be granted to any untrusted
+ users. Likewise for any extensions they depend on.
+ </para>
+
+ <para>
+ The extensions supplied with <productname>PostgreSQL</productname> are
+ believed to be secure against installation-time attacks of this sort,
+ except for a few that depend on other extensions. As stated in the
+ documentation for those extensions, they should be installed into secure
+ schemas, or installed into the same schemas as the extensions they
+ depend on, or both.
+ </para>
+ </caution>
+
+ <para>
+ For information about writing new extensions, see
+ <xref linkend="extend-extensions"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Install the <link linkend="hstore">hstore</link> extension into the
+ current database, placing its objects in schema <literal>addons</literal>:
+<programlisting>
+CREATE EXTENSION hstore SCHEMA addons;
+</programlisting>
+ Another way to accomplish the same thing:
+<programlisting>
+SET search_path = addons;
+CREATE EXTENSION hstore;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE EXTENSION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterextension"/></member>
+ <member><xref linkend="sql-dropextension"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_foreign_data_wrapper.sgml b/doc/src/sgml/ref/create_foreign_data_wrapper.sgml
new file mode 100644
index 0000000..0fcba18
--- /dev/null
+++ b/doc/src/sgml/ref/create_foreign_data_wrapper.sgml
@@ -0,0 +1,183 @@
+<!--
+doc/src/sgml/ref/create_foreign_data_wrapper.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createforeigndatawrapper">
+ <indexterm zone="sql-createforeigndatawrapper">
+ <primary>CREATE FOREIGN DATA WRAPPER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE FOREIGN DATA WRAPPER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE FOREIGN DATA WRAPPER</refname>
+ <refpurpose>define a new foreign-data wrapper</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE FOREIGN DATA WRAPPER <replaceable class="parameter">name</replaceable>
+ [ HANDLER <replaceable class="parameter">handler_function</replaceable> | NO HANDLER ]
+ [ VALIDATOR <replaceable class="parameter">validator_function</replaceable> | NO VALIDATOR ]
+ [ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE FOREIGN DATA WRAPPER</command> creates a new
+ foreign-data wrapper. The user who defines a foreign-data wrapper
+ becomes its owner.
+ </para>
+
+ <para>
+ The foreign-data wrapper name must be unique within the database.
+ </para>
+
+ <para>
+ Only superusers can create foreign-data wrappers.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the foreign-data wrapper to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HANDLER <replaceable class="parameter">handler_function</replaceable></literal></term>
+ <listitem>
+ <para><replaceable class="parameter">handler_function</replaceable> is the
+ name of a previously registered function that will be called to
+ retrieve the execution functions for foreign tables.
+ The handler function must take no arguments, and
+ its return type must be <type>fdw_handler</type>.
+ </para>
+
+ <para>
+ It is possible to create a foreign-data wrapper with no handler
+ function, but foreign tables using such a wrapper can only be declared,
+ not accessed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALIDATOR <replaceable class="parameter">validator_function</replaceable></literal></term>
+ <listitem>
+ <para><replaceable class="parameter">validator_function</replaceable>
+ is the name of a previously registered function that will be called to
+ check the generic options given to the foreign-data wrapper, as
+ well as options for foreign servers, user mappings and foreign tables
+ using the foreign-data wrapper. If no validator function or <literal>NO
+ VALIDATOR</literal> is specified, then options will not be
+ checked at creation time. (Foreign-data wrappers will possibly
+ ignore or reject invalid option specifications at run time,
+ depending on the implementation.) The validator function must
+ take two arguments: one of type <type>text[]</type>, which will
+ contain the array of options as stored in the system catalogs,
+ and one of type <type>oid</type>, which will be the OID of the
+ system catalog containing the options. The return type is ignored;
+ the function should report invalid options using the
+ <function>ereport(ERROR)</function> function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies options for the new foreign-data wrapper.
+ The allowed option names and values are specific to each foreign
+ data wrapper and are validated using the foreign-data wrapper's
+ validator function. Option names must be unique.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <productname>PostgreSQL</productname>'s foreign-data functionality is still under
+ active development. Optimization of queries is primitive (and mostly left
+ to the wrapper, too). Thus, there is considerable room for future
+ performance improvements.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a useless foreign-data wrapper <literal>dummy</literal>:
+<programlisting>
+CREATE FOREIGN DATA WRAPPER dummy;
+</programlisting>
+ </para>
+
+ <para>
+ Create a foreign-data wrapper <literal>file</literal> with
+ handler function <literal>file_fdw_handler</literal>:
+<programlisting>
+CREATE FOREIGN DATA WRAPPER file HANDLER file_fdw_handler;
+</programlisting>
+ </para>
+
+ <para>
+ Create a foreign-data wrapper <literal>mywrapper</literal> with some
+ options:
+<programlisting>
+CREATE FOREIGN DATA WRAPPER mywrapper
+ OPTIONS (debug 'true');
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
+ 9075-9 (SQL/MED), with the exception that the <literal>HANDLER</literal>
+ and <literal>VALIDATOR</literal> clauses are extensions and the standard
+ clauses <literal>LIBRARY</literal> and <literal>LANGUAGE</literal>
+ are not implemented in <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ Note, however, that the SQL/MED functionality as a whole is not yet
+ conforming.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterforeigndatawrapper"/></member>
+ <member><xref linkend="sql-dropforeigndatawrapper"/></member>
+ <member><xref linkend="sql-createserver"/></member>
+ <member><xref linkend="sql-createusermapping"/></member>
+ <member><xref linkend="sql-createforeigntable"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_foreign_table.sgml b/doc/src/sgml/ref/create_foreign_table.sgml
new file mode 100644
index 0000000..ae1f94b
--- /dev/null
+++ b/doc/src/sgml/ref/create_foreign_table.sgml
@@ -0,0 +1,455 @@
+<!--
+doc/src/sgml/ref/create_foreign_table.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createforeigntable">
+ <indexterm zone="sql-createforeigntable">
+ <primary>CREATE FOREIGN TABLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE FOREIGN TABLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE FOREIGN TABLE</refname>
+ <refpurpose>define a new foreign table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="parameter">table_name</replaceable> ( [
+ { <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] ) ] [ COLLATE <replaceable>collation</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ | <replaceable>table_constraint</replaceable> }
+ [, ... ]
+] )
+[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
+ SERVER <replaceable class="parameter">server_name</replaceable>
+[ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] ) ]
+
+CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="parameter">table_name</replaceable>
+ PARTITION OF <replaceable class="parameter">parent_table</replaceable> [ (
+ { <replaceable class="parameter">column_name</replaceable> [ WITH OPTIONS ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ | <replaceable>table_constraint</replaceable> }
+ [, ... ]
+) ]
+{ FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
+ SERVER <replaceable class="parameter">server_name</replaceable>
+[ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] ) ]
+
+<phrase>where <replaceable class="parameter">column_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+{ NOT NULL |
+ NULL |
+ CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
+ DEFAULT <replaceable>default_expr</replaceable> |
+ GENERATED ALWAYS AS ( <replaceable>generation_expr</replaceable> ) STORED }
+
+<phrase>and <replaceable class="parameter">table_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ]
+
+<phrase>and <replaceable class="parameter">partition_bound_spec</replaceable> is:</phrase>
+
+IN ( <replaceable class="parameter">partition_bound_expr</replaceable> [, ...] ) |
+FROM ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] )
+ TO ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] ) |
+WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REMAINDER <replaceable class="parameter">numeric_literal</replaceable> )
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createforeigntable-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE FOREIGN TABLE</command> creates a new foreign table
+ in the current database. The table will be owned by the user issuing the
+ command.
+ </para>
+
+ <para>
+ If a schema name is given (for example, <literal>CREATE FOREIGN TABLE
+ myschema.mytable ...</literal>) then the table is created in the specified
+ schema. Otherwise it is created in the current schema.
+ The name of the foreign table must be
+ distinct from the name of any other relation (table, sequence, index, view,
+ materialized view, or foreign table) in the same schema.
+ </para>
+
+ <para>
+ <command>CREATE FOREIGN TABLE</command> also automatically creates a data
+ type that represents the composite type corresponding to one row of
+ the foreign table. Therefore, foreign tables cannot have the same
+ name as any existing data type in the same schema.
+ </para>
+
+ <para>
+ If <literal>PARTITION OF</literal> clause is specified then the table is
+ created as a partition of <literal>parent_table</literal> with specified
+ bounds.
+ </para>
+
+ <para>
+ To be able to create a foreign table, you must have <literal>USAGE</literal>
+ privilege on the foreign server, as well as <literal>USAGE</literal>
+ privilege on all column types used in the table.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing relation is anything like the one that would have been
+ created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column to be created in the new table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the column. This can include array
+ specifiers. For more information on the data types supported by
+ <productname>PostgreSQL</productname>, refer to <xref
+ linkend="datatype"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COLLATE <replaceable>collation</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <literal>COLLATE</literal> clause assigns a collation to
+ the column (which must be of a collatable data type).
+ If not specified, the column data type's default collation is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INHERITS ( <replaceable>parent_table</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ The optional <literal>INHERITS</literal> clause specifies a list of
+ tables from which the new foreign table automatically inherits
+ all columns. Parent tables can be plain tables or foreign tables.
+ See the similar form of
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link> for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PARTITION OF <replaceable>parent_table</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }</literal></term>
+ <listitem>
+ <para>
+ This form can be used to create the foreign table as partition of
+ the given parent table with specified partition bound values.
+ See the similar form of
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link> for more details.
+ Note that it is currently not allowed to create the foreign table as a
+ partition of the parent table if there are <literal>UNIQUE</literal>
+ indexes on the parent table. (See also
+ <link linkend="sql-altertable"><command>ALTER TABLE ATTACH PARTITION</command></link>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONSTRAINT <replaceable class="parameter">constraint_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ An optional name for a column or table constraint. If the
+ constraint is violated, the constraint name is present in error messages,
+ so constraint names like <literal>col must be positive</literal> can be used
+ to communicate helpful constraint information to client applications.
+ (Double-quotes are needed to specify constraint names that contain spaces.)
+ If a constraint name is not specified, the system generates a name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOT NULL</literal></term>
+ <listitem>
+ <para>
+ The column is not allowed to contain null values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULL</literal></term>
+ <listitem>
+ <para>
+ The column is allowed to contain null values. This is the default.
+ </para>
+
+ <para>
+ This clause is only provided for compatibility with
+ non-standard SQL databases. Its use is discouraged in new
+ applications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] </literal></term>
+ <listitem>
+ <para>
+ The <literal>CHECK</literal> clause specifies an expression producing a
+ Boolean result which each row in the foreign table is expected
+ to satisfy; that is, the expression should produce TRUE or UNKNOWN,
+ never FALSE, for all rows in the foreign table.
+ A check constraint specified as a column constraint should
+ reference that column's value only, while an expression
+ appearing in a table constraint can reference multiple columns.
+ </para>
+
+ <para>
+ Currently, <literal>CHECK</literal> expressions cannot contain
+ subqueries nor refer to variables other than columns of the
+ current row. The system column <literal>tableoid</literal>
+ may be referenced, but not any other system column.
+ </para>
+
+ <para>
+ A constraint marked with <literal>NO INHERIT</literal> will not propagate to
+ child tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT
+ <replaceable>default_expr</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <literal>DEFAULT</literal> clause assigns a default data value for
+ the column whose column definition it appears within. The value
+ is any variable-free expression (subqueries and cross-references
+ to other columns in the current table are not allowed). The
+ data type of the default expression must match the data type of the
+ column.
+ </para>
+
+ <para>
+ The default expression will be used in any insert operation that
+ does not specify a value for the column. If there is no default
+ for a column, then the default is null.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>GENERATED ALWAYS AS ( <replaceable>generation_expr</replaceable> ) STORED</literal><indexterm><primary>generated column</primary></indexterm></term>
+ <listitem>
+ <para>
+ This clause creates the column as a <firstterm>generated
+ column</firstterm>. The column cannot be written to, and when read the
+ result of the specified expression will be returned.
+ </para>
+
+ <para>
+ The keyword <literal>STORED</literal> is required to signify that the
+ column will be computed on write. (The computed value will be presented
+ to the foreign-data wrapper for storage and must be returned on
+ reading.)
+ </para>
+
+ <para>
+ The generation expression can refer to other columns in the table, but
+ not other generated columns. Any functions and operators used must be
+ immutable. References to other tables are not allowed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing foreign server to use for the foreign table.
+ For details on defining a server, see <xref
+ linkend="sql-createserver"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ...] )</literal></term>
+ <listitem>
+ <para>
+ Options to be associated with the new foreign table or one of its
+ columns.
+ The allowed option names and values are specific to each foreign
+ data wrapper and are validated using the foreign-data wrapper's
+ validator function. Duplicate option names are not allowed (although
+ it's OK for a table option and a column option to have the same name).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Constraints on foreign tables (such as <literal>CHECK</literal>
+ or <literal>NOT NULL</literal> clauses) are not enforced by the
+ core <productname>PostgreSQL</productname> system, and most foreign data wrappers
+ do not attempt to enforce them either; that is, the constraint is
+ simply assumed to hold true. There would be little point in such
+ enforcement since it would only apply to rows inserted or updated via
+ the foreign table, and not to rows modified by other means, such as
+ directly on the remote server. Instead, a constraint attached to a
+ foreign table should represent a constraint that is being enforced by
+ the remote server.
+ </para>
+
+ <para>
+ Some special-purpose foreign data wrappers might be the only access
+ mechanism for the data they access, and in that case it might be
+ appropriate for the foreign data wrapper itself to perform constraint
+ enforcement. But you should not assume that a wrapper does that
+ unless its documentation says so.
+ </para>
+
+ <para>
+ Although <productname>PostgreSQL</productname> does not attempt to enforce
+ constraints on foreign tables, it does assume that they are correct
+ for purposes of query optimization. If there are rows visible in the
+ foreign table that do not satisfy a declared constraint, queries on
+ the table might produce errors or incorrect answers. It is the user's
+ responsibility to ensure that the constraint definition matches
+ reality.
+ </para>
+
+ <caution>
+ <para>
+ When a foreign table is used as a partition of a partitioned table,
+ there is an implicit constraint that its contents must satisfy the
+ partitioning rule. Again, it is the user's responsibility to ensure
+ that that is true, which is best done by installing a matching
+ constraint on the remote server.
+ </para>
+ </caution>
+
+ <para>
+ Within a partitioned table containing foreign-table partitions,
+ an <command>UPDATE</command> that changes the partition key value can
+ cause a row to be moved from a local partition to a foreign-table
+ partition, provided the foreign data wrapper supports tuple routing.
+ However it is not currently possible to move a row from a
+ foreign-table partition to another partition.
+ An <command>UPDATE</command> that would require doing that will fail
+ due to the partitioning constraint, assuming that that is properly
+ enforced by the remote server.
+ </para>
+
+ <para>
+ Similar considerations apply to generated columns. Stored generated
+ columns are computed on insert or update on the local
+ <productname>PostgreSQL</productname> server and handed to the
+ foreign-data wrapper for writing out to the foreign data store, but it is
+ not enforced that a query of the foreign table returns values for stored
+ generated columns that are consistent with the generation expression.
+ Again, this might result in incorrect query results.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createforeigntable-examples">
+ <title>Examples</title>
+
+ <para>
+ Create foreign table <structname>films</structname>, which will be accessed through
+ the server <structname>film_server</structname>:
+
+<programlisting>
+CREATE FOREIGN TABLE films (
+ code char(5) NOT NULL,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+)
+SERVER film_server;
+</programlisting></para>
+
+ <para>
+ Create foreign table <structname>measurement_y2016m07</structname>, which will be
+ accessed through the server <structname>server_07</structname>, as a partition
+ of the range partitioned table <structname>measurement</structname>:
+
+<programlisting>
+CREATE FOREIGN TABLE measurement_y2016m07
+ PARTITION OF measurement FOR VALUES FROM ('2016-07-01') TO ('2016-08-01')
+ SERVER server_07;
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1 id="sql-createforeigntable-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>CREATE FOREIGN TABLE</command> command largely conforms to the
+ <acronym>SQL</acronym> standard; however, much as with
+ <link linkend="sql-createtable"><command>CREATE TABLE</command></link>,
+ <literal>NULL</literal> constraints and zero-column foreign tables are permitted.
+ The ability to specify column default values is also
+ a <productname>PostgreSQL</productname> extension. Table inheritance, in the form
+ defined by <productname>PostgreSQL</productname>, is nonstandard.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterforeigntable"/></member>
+ <member><xref linkend="sql-dropforeigntable"/></member>
+ <member><xref linkend="sql-createtable"/></member>
+ <member><xref linkend="sql-createserver"/></member>
+ <member><xref linkend="sql-importforeignschema"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml
new file mode 100644
index 0000000..7e6d52c
--- /dev/null
+++ b/doc/src/sgml/ref/create_function.sgml
@@ -0,0 +1,935 @@
+<!--
+doc/src/sgml/ref/create_function.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createfunction">
+ <indexterm zone="sql-createfunction">
+ <primary>CREATE FUNCTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE FUNCTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE FUNCTION</refname>
+ <refpurpose>define a new function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] FUNCTION
+ <replaceable class="parameter">name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [ { DEFAULT | = } <replaceable class="parameter">default_expr</replaceable> ] [, ...] ] )
+ [ RETURNS <replaceable class="parameter">rettype</replaceable>
+ | RETURNS TABLE ( <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">column_type</replaceable> [, ...] ) ]
+ { LANGUAGE <replaceable class="parameter">lang_name</replaceable>
+ | TRANSFORM { FOR TYPE <replaceable class="parameter">type_name</replaceable> } [, ... ]
+ | WINDOW
+ | { IMMUTABLE | STABLE | VOLATILE }
+ | [ NOT ] LEAKPROOF
+ | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
+ | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
+ | PARALLEL { UNSAFE | RESTRICTED | SAFE }
+ | COST <replaceable class="parameter">execution_cost</replaceable>
+ | ROWS <replaceable class="parameter">result_rows</replaceable>
+ | SUPPORT <replaceable class="parameter">support_function</replaceable>
+ | SET <replaceable class="parameter">configuration_parameter</replaceable> { TO <replaceable class="parameter">value</replaceable> | = <replaceable class="parameter">value</replaceable> | FROM CURRENT }
+ | AS '<replaceable class="parameter">definition</replaceable>'
+ | AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
+ | <replaceable class="parameter">sql_body</replaceable>
+ } ...
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createfunction-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE FUNCTION</command> defines a new function.
+ <command>CREATE OR REPLACE FUNCTION</command> will either create a
+ new function, or replace an existing definition.
+ To be able to define a function, the user must have the
+ <literal>USAGE</literal> privilege on the language.
+ </para>
+
+ <para>
+ If a schema name is included, then the function is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The name of the new function must not match any existing function or procedure
+ with the same input argument types in the same schema. However,
+ functions and procedures of different argument types can share a name (this is
+ called <firstterm>overloading</firstterm>).
+ </para>
+
+ <para>
+ To replace the current definition of an existing function, use
+ <command>CREATE OR REPLACE FUNCTION</command>. It is not possible
+ to change the name or argument types of a function this way (if you
+ tried, you would actually be creating a new, distinct function).
+ Also, <command>CREATE OR REPLACE FUNCTION</command> will not let
+ you change the return type of an existing function. To do that,
+ you must drop and recreate the function. (When using <literal>OUT</literal>
+ parameters, that means you cannot change the types of any
+ <literal>OUT</literal> parameters except by dropping the function.)
+ </para>
+
+ <para>
+ When <command>CREATE OR REPLACE FUNCTION</command> is used to replace an
+ existing function, the ownership and permissions of the function
+ do not change. All other function properties are assigned the
+ values specified or implied in the command. You must own the function
+ to replace it (this includes being a member of the owning role).
+ </para>
+
+ <para>
+ If you drop and then recreate a function, the new function is not
+ the same entity as the old; you will have to drop existing rules, views,
+ triggers, etc. that refer to the old function. Use
+ <command>CREATE OR REPLACE FUNCTION</command> to change a function
+ definition without breaking objects that refer to the function.
+ Also, <command>ALTER FUNCTION</command> can be used to change most of the
+ auxiliary properties of an existing function.
+ </para>
+
+ <para>
+ The user that creates the function becomes the owner of the function.
+ </para>
+
+ <para>
+ To be able to create a function, you must have <literal>USAGE</literal>
+ privilege on the argument types and the return type.
+ </para>
+
+ <para>
+ Refer to <xref linkend="xfunc"/> for further information on writing
+ functions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the function to create.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ Only <literal>OUT</literal> arguments can follow a <literal>VARIADIC</literal> one.
+ Also, <literal>OUT</literal> and <literal>INOUT</literal> arguments cannot be used
+ together with the <literal>RETURNS TABLE</literal> notation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument. Some languages (including SQL and PL/pgSQL)
+ let you use the name in the function body. For other languages the
+ name of an input argument is just extra documentation, so far as
+ the function itself is concerned; but you can use input argument names
+ when calling a function to improve readability (see <xref
+ linkend="sql-syntax-calling-funcs"/>). In any case, the name
+ of an output argument is significant, because it defines the column
+ name in the result row type. (If you omit the name for an output
+ argument, the system will choose a default column name.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type(s) of the function's arguments (optionally
+ schema-qualified), if any. The argument types can be base, composite,
+ or domain types, or can reference the type of a table column.
+ </para>
+ <para>
+ Depending on the implementation language it might also be allowed
+ to specify <quote>pseudo-types</quote> such as <type>cstring</type>.
+ Pseudo-types indicate that the actual argument type is either
+ incompletely specified, or outside the set of ordinary SQL data types.
+ </para>
+ <para>
+ The type of a column is referenced by writing
+ <literal><replaceable
+ class="parameter">table_name</replaceable>.<replaceable
+ class="parameter">column_name</replaceable>%TYPE</literal>.
+ Using this feature can sometimes help make a function independent of
+ changes to the definition of a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">default_expr</replaceable></term>
+
+ <listitem>
+ <para>
+ An expression to be used as default value if the parameter is
+ not specified. The expression has to be coercible to the
+ argument type of the parameter.
+ Only input (including <literal>INOUT</literal>) parameters can have a default
+ value. All input parameters following a
+ parameter with a default value must have default values as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">rettype</replaceable></term>
+
+ <listitem>
+ <para>
+ The return data type (optionally schema-qualified). The return type
+ can be a base, composite, or domain type,
+ or can reference the type of a table column.
+ Depending on the implementation language it might also be allowed
+ to specify <quote>pseudo-types</quote> such as <type>cstring</type>.
+ If the function is not supposed to return a value, specify
+ <type>void</type> as the return type.
+ </para>
+ <para>
+ When there are <literal>OUT</literal> or <literal>INOUT</literal> parameters,
+ the <literal>RETURNS</literal> clause can be omitted. If present, it
+ must agree with the result type implied by the output parameters:
+ <literal>RECORD</literal> if there are multiple output parameters, or
+ the same type as the single output parameter.
+ </para>
+ <para>
+ The <literal>SETOF</literal>
+ modifier indicates that the function will return a set of
+ items, rather than a single item.
+ </para>
+ <para>
+ The type of a column is referenced by writing
+ <literal><replaceable
+ class="parameter">table_name</replaceable>.<replaceable
+ class="parameter">column_name</replaceable>%TYPE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an output column in the <literal>RETURNS TABLE</literal>
+ syntax. This is effectively another way of declaring a named
+ <literal>OUT</literal> parameter, except that <literal>RETURNS TABLE</literal>
+ also implies <literal>RETURNS SETOF</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_type</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type of an output column in the <literal>RETURNS TABLE</literal>
+ syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">lang_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the language that the function is implemented in.
+ It can be <literal>sql</literal>, <literal>c</literal>,
+ <literal>internal</literal>, or the name of a user-defined
+ procedural language, e.g., <literal>plpgsql</literal>. The default is
+ <literal>sql</literal> if <replaceable
+ class="parameter">sql_body</replaceable> is specified. Enclosing the
+ name in single quotes is deprecated and requires matching case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRANSFORM { FOR TYPE <replaceable class="parameter">type_name</replaceable> } [, ... ] }</literal></term>
+
+ <listitem>
+ <para>
+ Lists which transforms a call to the function should apply. Transforms
+ convert between SQL types and language-specific data types;
+ see <xref linkend="sql-createtransform"/>. Procedural language
+ implementations usually have hardcoded knowledge of the built-in types,
+ so those don't need to be listed here. If a procedural language
+ implementation does not know how to handle a type and no transform is
+ supplied, it will fall back to a default behavior for converting data
+ types, but this depends on the implementation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WINDOW</literal></term>
+
+ <listitem>
+ <para><literal>WINDOW</literal> indicates that the function is a
+ <firstterm>window function</firstterm> rather than a plain function.
+ This is currently only useful for functions written in C.
+ The <literal>WINDOW</literal> attribute cannot be changed when
+ replacing an existing function definition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IMMUTABLE</literal></term>
+ <term><literal>STABLE</literal></term>
+ <term><literal>VOLATILE</literal></term>
+
+ <listitem>
+ <para>
+ These attributes inform the query optimizer about the behavior
+ of the function. At most one choice
+ can be specified. If none of these appear,
+ <literal>VOLATILE</literal> is the default assumption.
+ </para>
+
+ <para><literal>IMMUTABLE</literal> indicates that the function
+ cannot modify the database and always
+ returns the same result when given the same argument values; that
+ is, it does not do database lookups or otherwise use information not
+ directly present in its argument list. If this option is given,
+ any call of the function with all-constant arguments can be
+ immediately replaced with the function value.
+ </para>
+
+ <para><literal>STABLE</literal> indicates that the function
+ cannot modify the database,
+ and that within a single table scan it will consistently
+ return the same result for the same argument values, but that its
+ result could change across SQL statements. This is the appropriate
+ selection for functions whose results depend on database lookups,
+ parameter variables (such as the current time zone), etc. (It is
+ inappropriate for <literal>AFTER</literal> triggers that wish to
+ query rows modified by the current command.) Also note
+ that the <function>current_timestamp</function> family of functions qualify
+ as stable, since their values do not change within a transaction.
+ </para>
+
+ <para><literal>VOLATILE</literal> indicates that the function value can
+ change even within a single table scan, so no optimizations can be
+ made. Relatively few database functions are volatile in this sense;
+ some examples are <literal>random()</literal>, <literal>currval()</literal>,
+ <literal>timeofday()</literal>. But note that any function that has
+ side-effects must be classified volatile, even if its result is quite
+ predictable, to prevent calls from being optimized away; an example is
+ <literal>setval()</literal>.
+ </para>
+
+ <para>
+ For additional details see <xref linkend="xfunc-volatility"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LEAKPROOF</literal></term>
+ <listitem>
+ <para>
+ <literal>LEAKPROOF</literal> indicates that the function has no side
+ effects. It reveals no information about its arguments other than by
+ its return value. For example, a function which throws an error message
+ for some argument values but not others, or which includes the argument
+ values in any error message, is not leakproof. This affects how the
+ system executes queries against views created with the
+ <literal>security_barrier</literal> option or tables with row level
+ security enabled. The system will enforce conditions from security
+ policies and security barrier views before any user-supplied conditions
+ from the query itself that contain non-leakproof functions, in order to
+ prevent the inadvertent exposure of data. Functions and operators
+ marked as leakproof are assumed to be trustworthy, and may be executed
+ before conditions from security policies and security barrier views.
+ In addition, functions which do not take arguments or which are not
+ passed any arguments from the security barrier view or table do not have
+ to be marked as leakproof to be executed before security conditions. See
+ <xref linkend="sql-createview"/> and <xref linkend="rules-privileges"/>.
+ This option can only be set by the superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CALLED ON NULL INPUT</literal></term>
+ <term><literal>RETURNS NULL ON NULL INPUT</literal></term>
+ <term><literal>STRICT</literal></term>
+
+ <listitem>
+ <para><literal>CALLED ON NULL INPUT</literal> (the default) indicates
+ that the function will be called normally when some of its
+ arguments are null. It is then the function author's
+ responsibility to check for null values if necessary and respond
+ appropriately.
+ </para>
+
+ <para><literal>RETURNS NULL ON NULL INPUT</literal> or
+ <literal>STRICT</literal> indicates that the function always
+ returns null whenever any of its arguments are null. If this
+ parameter is specified, the function is not executed when there
+ are null arguments; instead a null result is assumed
+ automatically.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><optional>EXTERNAL</optional> SECURITY INVOKER</literal></term>
+ <term><literal><optional>EXTERNAL</optional> SECURITY DEFINER</literal></term>
+
+ <listitem>
+ <para><literal>SECURITY INVOKER</literal> indicates that the function
+ is to be executed with the privileges of the user that calls it.
+ That is the default. <literal>SECURITY DEFINER</literal>
+ specifies that the function is to be executed with the
+ privileges of the user that owns it.
+ </para>
+
+ <para>
+ The key word <literal>EXTERNAL</literal> is allowed for SQL
+ conformance, but it is optional since, unlike in SQL, this feature
+ applies to all functions not only external ones.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PARALLEL</literal></term>
+
+ <listitem>
+ <para><literal>PARALLEL UNSAFE</literal> indicates that the function
+ can't be executed in parallel mode and the presence of such a
+ function in an SQL statement forces a serial execution plan. This is
+ the default. <literal>PARALLEL RESTRICTED</literal> indicates that
+ the function can be executed in parallel mode, but the execution is
+ restricted to parallel group leader. <literal>PARALLEL SAFE</literal>
+ indicates that the function is safe to run in parallel mode without
+ restriction.
+ </para>
+
+ <para>
+ Functions should be labeled parallel unsafe if they modify any database
+ state, or if they make changes to the transaction such as using
+ sub-transactions, or if they access sequences or attempt to make
+ persistent changes to settings (e.g., <literal>setval</literal>). They should
+ be labeled as parallel restricted if they access temporary tables,
+ client connection state, cursors, prepared statements, or miscellaneous
+ backend-local state which the system cannot synchronize in parallel mode
+ (e.g., <literal>setseed</literal> cannot be executed other than by the group
+ leader because a change made by another process would not be reflected
+ in the leader). In general, if a function is labeled as being safe when
+ it is restricted or unsafe, or if it is labeled as being restricted when
+ it is in fact unsafe, it may throw errors or produce wrong answers
+ when used in a parallel query. C-language functions could in theory
+ exhibit totally undefined behavior if mislabeled, since there is no way
+ for the system to protect itself against arbitrary C code, but in most
+ likely cases the result will be no worse than for any other function.
+ If in doubt, functions should be labeled as <literal>UNSAFE</literal>, which is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COST</literal> <replaceable class="parameter">execution_cost</replaceable></term>
+
+ <listitem>
+ <para>
+ A positive number giving the estimated execution cost for the function,
+ in units of <xref linkend="guc-cpu-operator-cost"/>. If the function
+ returns a set, this is the cost per returned row. If the cost is
+ not specified, 1 unit is assumed for C-language and internal functions,
+ and 100 units for functions in all other languages. Larger values
+ cause the planner to try to avoid evaluating the function more often
+ than necessary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ROWS</literal> <replaceable class="parameter">result_rows</replaceable></term>
+
+ <listitem>
+ <para>
+ A positive number giving the estimated number of rows that the planner
+ should expect the function to return. This is only allowed when the
+ function is declared to return a set. The default assumption is
+ 1000 rows.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SUPPORT</literal> <replaceable class="parameter">support_function</replaceable></term>
+
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a <firstterm>planner support
+ function</firstterm> to use for this function. See
+ <xref linkend="xfunc-optimization"/> for details.
+ You must be superuser to use this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>configuration_parameter</replaceable></term>
+ <term><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>SET</literal> clause causes the specified configuration
+ parameter to be set to the specified value when the function is
+ entered, and then restored to its prior value when the function exits.
+ <literal>SET FROM CURRENT</literal> saves the value of the parameter that
+ is current when <command>CREATE FUNCTION</command> is executed as the value
+ to be applied when the function is entered.
+ </para>
+
+ <para>
+ If a <literal>SET</literal> clause is attached to a function, then
+ the effects of a <command>SET LOCAL</command> command executed inside the
+ function for the same variable are restricted to the function: the
+ configuration parameter's prior value is still restored at function exit.
+ However, an ordinary
+ <command>SET</command> command (without <literal>LOCAL</literal>) overrides the
+ <literal>SET</literal> clause, much as it would do for a previous <command>SET
+ LOCAL</command> command: the effects of such a command will persist after
+ function exit, unless the current transaction is rolled back.
+ </para>
+
+ <para>
+ See <xref linkend="sql-set"/> and
+ <xref linkend="runtime-config"/>
+ for more information about allowed parameter names and values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">definition</replaceable></term>
+
+ <listitem>
+ <para>
+ A string constant defining the function; the meaning depends on the
+ language. It can be an internal function name, the path to an
+ object file, an SQL command, or text in a procedural language.
+ </para>
+
+ <para>
+ It is often helpful to use dollar quoting (see <xref
+ linkend="sql-syntax-dollar-quoting"/>) to write the function definition
+ string, rather than the normal single quote syntax. Without dollar
+ quoting, any single quotes or backslashes in the function definition must
+ be escaped by doubling them.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable class="parameter">obj_file</replaceable>, <replaceable class="parameter">link_symbol</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ This form of the <literal>AS</literal> clause is used for
+ dynamically loadable C language functions when the function name
+ in the C language source code is not the same as the name of
+ the SQL function. The string <replaceable
+ class="parameter">obj_file</replaceable> is the name of the shared
+ library file containing the compiled C function, and is interpreted
+ as for the <link linkend="sql-load"><command>LOAD</command></link> command. The string
+ <replaceable class="parameter">link_symbol</replaceable> is the
+ function's link symbol, that is, the name of the function in the C
+ language source code. If the link symbol is omitted, it is assumed to
+ be the same as the name of the SQL function being defined. The C names
+ of all functions must be different, so you must give overloaded C
+ functions different C names (for example, use the argument types as
+ part of the C names).
+ </para>
+
+ <para>
+ When repeated <command>CREATE FUNCTION</command> calls refer to
+ the same object file, the file is only loaded once per session.
+ To unload and
+ reload the file (perhaps during development), start a new session.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sql_body</replaceable></term>
+
+ <listitem>
+ <para>
+ The body of a <literal>LANGUAGE SQL</literal> function. This can
+ either be a single statement
+<programlisting>
+RETURN <replaceable>expression</replaceable>
+</programlisting>
+ or a block
+<programlisting>
+BEGIN ATOMIC
+ <replaceable>statement</replaceable>;
+ <replaceable>statement</replaceable>;
+ ...
+ <replaceable>statement</replaceable>;
+END
+</programlisting>
+ </para>
+
+ <para>
+ This is similar to writing the text of the function body as a string
+ constant (see <replaceable>definition</replaceable> above), but there
+ are some differences: This form only works for <literal>LANGUAGE
+ SQL</literal>, the string constant form works for all languages. This
+ form is parsed at function definition time, the string constant form is
+ parsed at execution time; therefore this form cannot support
+ polymorphic argument types and other constructs that are not resolvable
+ at function definition time. This form tracks dependencies between the
+ function and objects used in the function body, so <literal>DROP
+ ... CASCADE</literal> will work correctly, whereas the form using
+ string literals may leave dangling functions. Finally, this form is
+ more compatible with the SQL standard and other SQL implementations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createfunction-overloading">
+ <title>Overloading</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows function
+ <firstterm>overloading</firstterm>; that is, the same name can be
+ used for several different functions so long as they have distinct
+ input argument types. Whether or not you use it, this capability entails
+ security precautions when calling functions in databases where some users
+ mistrust other users; see <xref linkend="typeconv-func"/>.
+ </para>
+
+ <para>
+ Two functions are considered the same if they have the same names and
+ <emphasis>input</emphasis> argument types, ignoring any <literal>OUT</literal>
+ parameters. Thus for example these declarations conflict:
+<programlisting>
+CREATE FUNCTION foo(int) ...
+CREATE FUNCTION foo(int, out text) ...
+</programlisting>
+ </para>
+
+ <para>
+ Functions that have different argument type lists will not be considered
+ to conflict at creation time, but if defaults are provided they might
+ conflict in use. For example, consider
+<programlisting>
+CREATE FUNCTION foo(int) ...
+CREATE FUNCTION foo(int, int default 42) ...
+</programlisting>
+ A call <literal>foo(10)</literal> will fail due to the ambiguity about which
+ function should be called.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="sql-createfunction-notes">
+ <title>Notes</title>
+
+ <para>
+ The full <acronym>SQL</acronym> type syntax is allowed for
+ declaring a function's arguments and return value. However,
+ parenthesized type modifiers (e.g., the precision field for
+ type <type>numeric</type>) are discarded by <command>CREATE FUNCTION</command>.
+ Thus for example
+ <literal>CREATE FUNCTION foo (varchar(10)) ...</literal>
+ is exactly the same as
+ <literal>CREATE FUNCTION foo (varchar) ...</literal>.
+ </para>
+
+ <para>
+ When replacing an existing function with <command>CREATE OR REPLACE
+ FUNCTION</command>, there are restrictions on changing parameter names.
+ You cannot change the name already assigned to any input parameter
+ (although you can add names to parameters that had none before).
+ If there is more than one output parameter, you cannot change the
+ names of the output parameters, because that would change the
+ column names of the anonymous composite type that describes the
+ function's result. These restrictions are made to ensure that
+ existing calls of the function do not stop working when it is replaced.
+ </para>
+
+ <para>
+ If a function is declared <literal>STRICT</literal> with a <literal>VARIADIC</literal>
+ argument, the strictness check tests that the variadic array <emphasis>as
+ a whole</emphasis> is non-null. The function will still be called if the
+ array has null elements.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="sql-createfunction-examples">
+ <title>Examples</title>
+
+ <para>
+ Add two integers using an SQL function:
+<programlisting>
+CREATE FUNCTION add(integer, integer) RETURNS integer
+ AS 'select $1 + $2;'
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT;
+</programlisting>
+ The same function written in a more SQL-conforming style, using argument
+ names and an unquoted body:
+<programlisting>
+CREATE FUNCTION add(a integer, b integer) RETURNS integer
+ LANGUAGE SQL
+ IMMUTABLE
+ RETURNS NULL ON NULL INPUT
+ RETURN a + b;
+</programlisting>
+ </para>
+
+ <para>
+ Increment an integer, making use of an argument name, in
+ <application>PL/pgSQL</application>:
+<programlisting>
+CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
+ BEGIN
+ RETURN i + 1;
+ END;
+$$ LANGUAGE plpgsql;
+</programlisting>
+ </para>
+
+ <para>
+ Return a record containing multiple output parameters:
+<programlisting>
+CREATE FUNCTION dup(in int, out f1 int, out f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+</programlisting>
+ You can do the same thing more verbosely with an explicitly named
+ composite type:
+<programlisting>
+CREATE TYPE dup_result AS (f1 int, f2 text);
+
+CREATE FUNCTION dup(int) RETURNS dup_result
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+</programlisting>
+ Another way to return multiple columns is to use a <literal>TABLE</literal>
+ function:
+<programlisting>
+CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
+ AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
+ LANGUAGE SQL;
+
+SELECT * FROM dup(42);
+</programlisting>
+ However, a <literal>TABLE</literal> function is different from the
+ preceding examples, because it actually returns a <emphasis>set</emphasis>
+ of records, not just one record.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createfunction-security">
+ <title>Writing <literal>SECURITY DEFINER</literal> Functions Safely</title>
+
+ <indexterm>
+ <primary><varname>search_path</varname> configuration parameter</primary>
+ <secondary>use in securing functions</secondary>
+ </indexterm>
+
+ <para>
+ Because a <literal>SECURITY DEFINER</literal> function is executed
+ with the privileges of the user that owns it, care is needed to
+ ensure that the function cannot be misused. For security,
+ <xref linkend="guc-search-path"/> should be set to exclude any schemas
+ writable by untrusted users. This prevents
+ malicious users from creating objects (e.g., tables, functions, and
+ operators) that mask objects intended to be used by the function.
+ Particularly important in this regard is the
+ temporary-table schema, which is searched first by default, and
+ is normally writable by anyone. A secure arrangement can be obtained
+ by forcing the temporary schema to be searched last. To do this,
+ write <literal>pg_temp</literal><indexterm><primary>pg_temp</primary><secondary>securing functions</secondary></indexterm> as the last entry in <varname>search_path</varname>.
+ This function illustrates safe usage:
+
+<programlisting>
+CREATE FUNCTION check_password(uname TEXT, pass TEXT)
+RETURNS BOOLEAN AS $$
+DECLARE passed BOOLEAN;
+BEGIN
+ SELECT (pwd = $2) INTO passed
+ FROM pwds
+ WHERE username = $1;
+
+ RETURN passed;
+END;
+$$ LANGUAGE plpgsql
+ SECURITY DEFINER
+ -- Set a secure search_path: trusted schema(s), then 'pg_temp'.
+ SET search_path = admin, pg_temp;
+</programlisting>
+
+ This function's intention is to access a table <literal>admin.pwds</literal>.
+ But without the <literal>SET</literal> clause, or with a <literal>SET</literal> clause
+ mentioning only <literal>admin</literal>, the function could be subverted by
+ creating a temporary table named <literal>pwds</literal>.
+ </para>
+
+ <para>
+ Before <productname>PostgreSQL</productname> version 8.3, the
+ <literal>SET</literal> clause was not available, and so older functions may
+ contain rather complicated logic to save, set, and restore
+ <varname>search_path</varname>. The <literal>SET</literal> clause is far easier
+ to use for this purpose.
+ </para>
+
+ <para>
+ Another point to keep in mind is that by default, execute privilege
+ is granted to <literal>PUBLIC</literal> for newly created functions
+ (see <xref linkend="ddl-priv"/> for more
+ information). Frequently you will wish to restrict use of a security
+ definer function to only some users. To do that, you must revoke
+ the default <literal>PUBLIC</literal> privileges and then grant execute
+ privilege selectively. To avoid having a window where the new function
+ is accessible to all, create it and set the privileges within a single
+ transaction. For example:
+ </para>
+
+<programlisting>
+BEGIN;
+CREATE FUNCTION check_password(uname TEXT, pass TEXT) ... SECURITY DEFINER;
+REVOKE ALL ON FUNCTION check_password(uname TEXT, pass TEXT) FROM PUBLIC;
+GRANT EXECUTE ON FUNCTION check_password(uname TEXT, pass TEXT) TO admins;
+COMMIT;
+</programlisting>
+
+ </refsect1>
+
+ <refsect1 id="sql-createfunction-compat">
+ <title>Compatibility</title>
+
+ <para>
+ A <command>CREATE FUNCTION</command> command is defined in the SQL
+ standard. The <productname>PostgreSQL</productname> implementation can be
+ used in a compatible way but has many extensions. Conversely, the SQL
+ standard specifies a number of optional features that are not implemented
+ in <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ The following are important compatibility issues:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>OR REPLACE</literal> is a PostgreSQL extension.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For compatibility with some other database systems, <replaceable
+ class="parameter">argmode</replaceable> can be written either before or
+ after <replaceable class="parameter">argname</replaceable>. But only
+ the first way is standard-compliant.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For parameter defaults, the SQL standard specifies only the syntax with
+ the <literal>DEFAULT</literal> key word. The syntax with
+ <literal>=</literal> is used in T-SQL and Firebird.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <literal>SETOF</literal> modifier is a PostgreSQL extension.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Only <literal>SQL</literal> is standardized as a language.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All other attributes except <literal>CALLED ON NULL INPUT</literal> and
+ <literal>RETURNS NULL ON NULL INPUT</literal> are not standardized.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For the body of <literal>LANGUAGE SQL</literal> functions, the SQL
+ standard only specifies the <replaceable>sql_body</replaceable> form.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Simple <literal>LANGUAGE SQL</literal> functions can be written in a way
+ that is both standard-conforming and portable to other implementations.
+ More complex functions using advanced features, optimization attributes, or
+ other languages will necessarily be specific to PostgreSQL in a significant
+ way.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterfunction"/></member>
+ <member><xref linkend="sql-dropfunction"/></member>
+ <member><xref linkend="sql-grant"/></member>
+ <member><xref linkend="sql-load"/></member>
+ <member><xref linkend="sql-revoke"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_group.sgml b/doc/src/sgml/ref/create_group.sgml
new file mode 100644
index 0000000..d124c98
--- /dev/null
+++ b/doc/src/sgml/ref/create_group.sgml
@@ -0,0 +1,72 @@
+<!--
+doc/src/sgml/ref/create_group.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-creategroup">
+ <indexterm zone="sql-creategroup">
+ <primary>CREATE GROUP</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE GROUP</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE GROUP</refname>
+ <refpurpose>define a new database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE GROUP <replaceable class="parameter">name</replaceable> [ [ WITH ] <replaceable class="parameter">option</replaceable> [ ... ] ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <replaceable class="parameter">connlimit</replaceable>
+ | [ ENCRYPTED ] PASSWORD '<replaceable class="parameter">password</replaceable>' | PASSWORD NULL
+ | VALID UNTIL '<replaceable class="parameter">timestamp</replaceable>'
+ | IN ROLE <replaceable class="parameter">role_name</replaceable> [, ...]
+ | IN GROUP <replaceable class="parameter">role_name</replaceable> [, ...]
+ | ROLE <replaceable class="parameter">role_name</replaceable> [, ...]
+ | ADMIN <replaceable class="parameter">role_name</replaceable> [, ...]
+ | USER <replaceable class="parameter">role_name</replaceable> [, ...]
+ | SYSID <replaceable class="parameter">uid</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE GROUP</command> is now an alias for
+ <xref linkend="sql-createrole"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CREATE GROUP</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createrole"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml
new file mode 100644
index 0000000..40986aa
--- /dev/null
+++ b/doc/src/sgml/ref/create_index.sgml
@@ -0,0 +1,999 @@
+<!--
+doc/src/sgml/ref/create_index.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createindex">
+ <indexterm zone="sql-createindex">
+ <primary>CREATE INDEX</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE INDEX</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE INDEX</refname>
+ <refpurpose>define a new index</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> ] ON [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
+ ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> [ ( <replaceable class="parameter">opclass_parameter</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] ) ] ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
+ [ INCLUDE ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+ [ NULLS [ NOT ] DISTINCT ]
+ [ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+ [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+ [ WHERE <replaceable class="parameter">predicate</replaceable> ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE INDEX</command> constructs an index on the specified column(s)
+ of the specified relation, which can be a table or a materialized view.
+ Indexes are primarily used to enhance database performance (though
+ inappropriate use can result in slower performance).
+ </para>
+
+ <para>
+ The key field(s) for the index are specified as column names,
+ or alternatively as expressions written in parentheses.
+ Multiple fields can be specified if the index method supports
+ multicolumn indexes.
+ </para>
+
+ <para>
+ An index field can be an expression computed from the values of
+ one or more columns of the table row. This feature can be used
+ to obtain fast access to data based on some transformation of
+ the basic data. For example, an index computed on
+ <literal>upper(col)</literal> would allow the clause
+ <literal>WHERE upper(col) = 'JIM'</literal> to use an index.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> provides the index methods
+ B-tree, hash, GiST, SP-GiST, GIN, and BRIN. Users can also define their own
+ index methods, but that is fairly complicated.
+ </para>
+
+ <para>
+ When the <literal>WHERE</literal> clause is present, a
+ <firstterm>partial index</firstterm> is created.
+ A partial index is an index that contains entries for only a portion of
+ a table, usually a portion that is more useful for indexing than the
+ rest of the table. For example, if you have a table that contains both
+ billed and unbilled orders where the unbilled orders take up a small
+ fraction of the total table and yet that is an often used section, you
+ can improve performance by creating an index on just that portion.
+ Another possible application is to use <literal>WHERE</literal> with
+ <literal>UNIQUE</literal> to enforce uniqueness over a subset of a
+ table. See <xref linkend="indexes-partial"/> for more discussion.
+ </para>
+
+ <para>
+ The expression used in the <literal>WHERE</literal> clause can refer
+ only to columns of the underlying table, but it can use all columns,
+ not just the ones being indexed. Presently, subqueries and
+ aggregate expressions are also forbidden in <literal>WHERE</literal>.
+ The same restrictions apply to index fields that are expressions.
+ </para>
+
+ <para>
+ All functions and operators used in an index definition must be
+ <quote>immutable</quote>, that is, their results must depend only on
+ their arguments and never on any outside influence (such as
+ the contents of another table or the current time). This restriction
+ ensures that the behavior of the index is well-defined. To use a
+ user-defined function in an index expression or <literal>WHERE</literal>
+ clause, remember to mark the function immutable when you create it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>UNIQUE</literal></term>
+ <listitem>
+ <para>
+ Causes the system to check for
+ duplicate values in the table when the index is created (if data
+ already exist) and each time data is added. Attempts to
+ insert or update data which would result in duplicate entries
+ will generate an error.
+ </para>
+
+ <para>
+ Additional restrictions apply when unique indexes are applied to
+ partitioned tables; see <xref linkend="sql-createtable" />.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONCURRENTLY</literal></term>
+ <listitem>
+ <para>
+ When this option is used, <productname>PostgreSQL</productname> will build the
+ index without taking any locks that prevent concurrent inserts,
+ updates, or deletes on the table; whereas a standard index build
+ locks out writes (but not reads) on the table until it's done.
+ There are several caveats to be aware of when using this option
+ &mdash; see <xref linkend="sql-createindex-concurrently"/> below.
+ </para>
+ <para>
+ For temporary tables, <command>CREATE INDEX</command> is always
+ non-concurrent, as no other session can access them, and
+ non-concurrent index creation is cheaper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing index is anything like the one that would have been created.
+ Index name is required when <literal>IF NOT EXISTS</literal> is specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDE</literal></term>
+ <listitem>
+ <para>
+ The optional <literal>INCLUDE</literal> clause specifies a
+ list of columns which will be included in the index
+ as <firstterm>non-key</firstterm> columns. A non-key column cannot
+ be used in an index scan search qualification, and it is disregarded
+ for purposes of any uniqueness or exclusion constraint enforced by
+ the index. However, an index-only scan can return the contents of
+ non-key columns without having to visit the index's table, since
+ they are available directly from the index entry. Thus, addition of
+ non-key columns allows index-only scans to be used for queries that
+ otherwise could not use them.
+ </para>
+
+ <para>
+ It's wise to be conservative about adding non-key columns to an
+ index, especially wide columns. If an index tuple exceeds the
+ maximum size allowed for the index type, data insertion will fail.
+ In any case, non-key columns duplicate data from the index's table
+ and bloat the size of the index, thus potentially slowing searches.
+ Furthermore, B-tree deduplication is never used with indexes
+ that have a non-key column.
+ </para>
+
+ <para>
+ Columns listed in the <literal>INCLUDE</literal> clause don't need
+ appropriate operator classes; the clause can include
+ columns whose data types don't have operator classes defined for
+ a given access method.
+ </para>
+
+ <para>
+ Expressions are not supported as included columns since they cannot be
+ used in index-only scans.
+ </para>
+
+ <para>
+ Currently, the B-tree, GiST and SP-GiST index access methods support
+ this feature. In these indexes, the values of columns listed
+ in the <literal>INCLUDE</literal> clause are included in leaf tuples
+ which correspond to heap tuples, but are not included in upper-level
+ index entries used for tree navigation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index to be created. No schema name can be included
+ here; the index is always created in the same schema as its parent
+ table. The name of the index must be distinct from the name of any
+ other relation (table, sequence, index, view, materialized view, or
+ foreign table) in that schema.
+ If the name is omitted, <productname>PostgreSQL</productname> chooses a
+ suitable name based on the parent table's name and the indexed column
+ name(s).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ONLY</literal></term>
+ <listitem>
+ <para>
+ Indicates not to recurse creating indexes on partitions, if the
+ table is partitioned. The default is to recurse.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (possibly schema-qualified) of the table to be indexed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index method to be used. Choices are
+ <literal>btree</literal>, <literal>hash</literal>,
+ <literal>gist</literal>, <literal>spgist</literal>, <literal>gin</literal>,
+ <literal>brin</literal>, or user-installed access methods like
+ <link linkend="bloom">bloom</link>.
+ The default method is <literal>btree</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column of the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression based on one or more columns of the table. The
+ expression usually must be written with surrounding parentheses,
+ as shown in the syntax. However, the parentheses can be omitted
+ if the expression has the form of a function call.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">collation</replaceable></term>
+ <listitem>
+ <para>
+ The name of the collation to use for the index. By default,
+ the index uses the collation declared for the column to be
+ indexed or the result collation of the expression to be
+ indexed. Indexes with non-default collations can be useful for
+ queries that involve expressions using non-default collations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">opclass</replaceable></term>
+ <listitem>
+ <para>
+ The name of an operator class. See below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">opclass_parameter</replaceable></term>
+ <listitem>
+ <para>
+ The name of an operator class parameter. See below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ASC</literal></term>
+ <listitem>
+ <para>
+ Specifies ascending sort order (which is the default).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DESC</literal></term>
+ <listitem>
+ <para>
+ Specifies descending sort order.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULLS FIRST</literal></term>
+ <listitem>
+ <para>
+ Specifies that nulls sort before non-nulls. This is the default
+ when <literal>DESC</literal> is specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULLS LAST</literal></term>
+ <listitem>
+ <para>
+ Specifies that nulls sort after non-nulls. This is the default
+ when <literal>DESC</literal> is not specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULLS DISTINCT</literal></term>
+ <term><literal>NULLS NOT DISTINCT</literal></term>
+ <listitem>
+ <para>
+ Specifies whether for a unique index, null values should be considered
+ distinct (not equal). The default is that they are distinct, so that
+ a unique index could contain multiple null values in a column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">storage_parameter</replaceable></term>
+ <listitem>
+ <para>
+ The name of an index-method-specific storage parameter. See
+ <xref linkend="sql-createindex-storage-parameters"/> below
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">tablespace_name</replaceable></term>
+ <listitem>
+ <para>
+ The tablespace in which to create the index. If not specified,
+ <xref linkend="guc-default-tablespace"/> is consulted, or
+ <xref linkend="guc-temp-tablespaces"/> for indexes on temporary
+ tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">predicate</replaceable></term>
+ <listitem>
+ <para>
+ The constraint expression for a partial index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <refsect2 id="sql-createindex-storage-parameters" xreflabel="Index Storage Parameters">
+ <title>Index Storage Parameters</title>
+
+ <para>
+ The optional <literal>WITH</literal> clause specifies <firstterm>storage
+ parameters</firstterm> for the index. Each index method has its own set of allowed
+ storage parameters. The B-tree, hash, GiST and SP-GiST index methods all
+ accept this parameter:
+ </para>
+
+ <variablelist>
+ <varlistentry id="index-reloption-fillfactor" xreflabel="fillfactor">
+ <term><literal>fillfactor</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>fillfactor</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The fillfactor for an index is a percentage that determines how full
+ the index method will try to pack index pages. For B-trees, leaf pages
+ are filled to this percentage during initial index builds, and also
+ when extending the index at the right (adding new largest key values).
+ If pages
+ subsequently become completely full, they will be split, leading to
+ fragmentation of the on-disk index structure. B-trees use a default
+ fillfactor of 90, but any integer value from 10 to 100 can be selected.
+ </para>
+ <para>
+ B-tree indexes on tables where many inserts and/or updates are
+ anticipated can benefit from lower fillfactor settings at
+ <command>CREATE INDEX</command> time (following bulk loading into the
+ table). Values in the range of 50 - 90 can usefully <quote>smooth
+ out</quote> the <emphasis>rate</emphasis> of page splits during the
+ early life of the B-tree index (lowering fillfactor like this may even
+ lower the absolute number of page splits, though this effect is highly
+ workload dependent). The B-tree bottom-up index deletion technique
+ described in <xref linkend="btree-deletion"/> is dependent on having
+ some <quote>extra</quote> space on pages to store <quote>extra</quote>
+ tuple versions, and so can be affected by fillfactor (though the effect
+ is usually not significant).
+ </para>
+ <para>
+ In other specific cases it might be useful to increase fillfactor to
+ 100 at <command>CREATE INDEX</command> time as a way of maximizing
+ space utilization. You should only consider this when you are
+ completely sure that the table is static (i.e. that it will never be
+ affected by either inserts or updates). A fillfactor setting of 100
+ otherwise risks <emphasis>harming</emphasis> performance: even a few
+ updates or inserts will cause a sudden flood of page splits.
+ </para>
+ <para>
+ The other index methods use fillfactor in different but roughly
+ analogous ways; the default fillfactor varies between methods.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ B-tree indexes additionally accept this parameter:
+ </para>
+
+ <variablelist>
+ <varlistentry id="index-reloption-deduplicate-items" xreflabel="deduplicate_items">
+ <term><literal>deduplicate_items</literal> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>deduplicate_items</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Controls usage of the B-tree deduplication technique described
+ in <xref linkend="btree-deduplication"/>. Set to
+ <literal>ON</literal> or <literal>OFF</literal> to enable or
+ disable the optimization. (Alternative spellings of
+ <literal>ON</literal> and <literal>OFF</literal> are allowed as
+ described in <xref linkend="config-setting"/>.) The default is
+ <literal>ON</literal>.
+ </para>
+
+ <note>
+ <para>
+ Turning <literal>deduplicate_items</literal> off via
+ <command>ALTER INDEX</command> prevents future insertions from
+ triggering deduplication, but does not in itself make existing
+ posting list tuples use the standard tuple representation.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ GiST indexes additionally accept this parameter:
+ </para>
+
+ <variablelist>
+ <varlistentry id="index-reloption-buffering" xreflabel="buffering">
+ <term><literal>buffering</literal> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>buffering</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Determines whether the buffered build technique described in
+ <xref linkend="gist-buffering-build"/> is used to build the index. With
+ <literal>OFF</literal> buffering is disabled, with <literal>ON</literal>
+ it is enabled, and with <literal>AUTO</literal> it is initially disabled,
+ but is turned on on-the-fly once the index size reaches
+ <xref linkend="guc-effective-cache-size"/>. The default
+ is <literal>AUTO</literal>.
+ Note that if sorted build is possible, it will be used instead of
+ buffered build unless <literal>buffering=ON</literal> is specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ GIN indexes accept different parameters:
+ </para>
+
+ <variablelist>
+ <varlistentry id="index-reloption-fastupdate" xreflabel="fastupdate">
+ <term><literal>fastupdate</literal> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>fastupdate</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This setting controls usage of the fast update technique described in
+ <xref linkend="gin-fast-update"/>. It is a Boolean parameter:
+ <literal>ON</literal> enables fast update, <literal>OFF</literal> disables it.
+ The default is <literal>ON</literal>.
+ </para>
+
+ <note>
+ <para>
+ Turning <literal>fastupdate</literal> off via <command>ALTER INDEX</command> prevents
+ future insertions from going into the list of pending index entries,
+ but does not in itself flush previous entries. You might want to
+ <command>VACUUM</command> the table or call <function>gin_clean_pending_list</function>
+ function afterward to ensure the pending list is emptied.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <varlistentry id="index-reloption-gin-pending-list-limit" xreflabel="gin_pending_list_limit">
+ <term><literal>gin_pending_list_limit</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>gin_pending_list_limit</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Custom <xref linkend="guc-gin-pending-list-limit"/> parameter.
+ This value is specified in kilobytes.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ <acronym>BRIN</acronym> indexes accept different parameters:
+ </para>
+
+ <variablelist>
+ <varlistentry id="index-reloption-pages-per-range" xreflabel="pages_per_range">
+ <term><literal>pages_per_range</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>pages_per_range</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Defines the number of table blocks that make up one block range for
+ each entry of a <acronym>BRIN</acronym> index (see <xref linkend="brin-intro"/>
+ for more details). The default is <literal>128</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="index-reloption-autosummarize" xreflabel="autosummarize">
+ <term><literal>autosummarize</literal> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>autosummarize</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Defines whether a summarization run is queued for the previous page
+ range whenever an insertion is detected on the next one.
+ See <xref linkend="brin-operation"/> for more details.
+ The default is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+
+ <refsect2 id="sql-createindex-concurrently" xreflabel="Building Indexes Concurrently">
+ <title>Building Indexes Concurrently</title>
+
+ <indexterm zone="sql-createindex-concurrently">
+ <primary>index</primary>
+ <secondary>building concurrently</secondary>
+ </indexterm>
+
+ <para>
+ Creating an index can interfere with regular operation of a database.
+ Normally <productname>PostgreSQL</productname> locks the table to be indexed against
+ writes and performs the entire index build with a single scan of the
+ table. Other transactions can still read the table, but if they try to
+ insert, update, or delete rows in the table they will block until the
+ index build is finished. This could have a severe effect if the system is
+ a live production database. Very large tables can take many hours to be
+ indexed, and even for smaller tables, an index build can lock out writers
+ for periods that are unacceptably long for a production system.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> supports building indexes without locking
+ out writes. This method is invoked by specifying the
+ <literal>CONCURRENTLY</literal> option of <command>CREATE INDEX</command>.
+ When this option is used,
+ <productname>PostgreSQL</productname> must perform two scans of the table, and in
+ addition it must wait for all existing transactions that could potentially
+ modify or use the index to terminate. Thus
+ this method requires more total work than a standard index build and takes
+ significantly longer to complete. However, since it allows normal
+ operations to continue while the index is built, this method is useful for
+ adding new indexes in a production environment. Of course, the extra CPU
+ and I/O load imposed by the index creation might slow other operations.
+ </para>
+
+ <para>
+ In a concurrent index build, the index is actually entered as an
+ <quote>invalid</quote> index into
+ the system catalogs in one transaction, then two table scans occur in
+ two more transactions. Before each table scan, the index build must
+ wait for existing transactions that have modified the table to terminate.
+ After the second scan, the index build must wait for any transactions
+ that have a snapshot (see <xref linkend="mvcc"/>) predating the second
+ scan to terminate, including transactions used by any phase of concurrent
+ index builds on other tables, if the indexes involved are partial or have
+ columns that are not simple column references.
+ Then finally the index can be marked <quote>valid</quote> and ready for use,
+ and the <command>CREATE INDEX</command> command terminates.
+ Even then, however, the index may not be immediately usable for queries:
+ in the worst case, it cannot be used as long as transactions exist that
+ predate the start of the index build.
+ </para>
+
+ <para>
+ If a problem arises while scanning the table, such as a deadlock or a
+ uniqueness violation in a unique index, the <command>CREATE INDEX</command>
+ command will fail but leave behind an <quote>invalid</quote> index. This index
+ will be ignored for querying purposes because it might be incomplete;
+ however it will still consume update overhead. The <application>psql</application>
+ <command>\d</command> command will report such an index as <literal>INVALID</literal>:
+
+<programlisting>
+postgres=# \d tab
+ Table "public.tab"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ col | integer | | |
+Indexes:
+ "idx" btree (col) INVALID
+</programlisting>
+
+ The recommended recovery
+ method in such cases is to drop the index and try again to perform
+ <command>CREATE INDEX CONCURRENTLY</command>. (Another possibility is
+ to rebuild the index with <command>REINDEX INDEX CONCURRENTLY</command>).
+ </para>
+
+ <para>
+ Another caveat when building a unique index concurrently is that the
+ uniqueness constraint is already being enforced against other transactions
+ when the second table scan begins. This means that constraint violations
+ could be reported in other queries prior to the index becoming available
+ for use, or even in cases where the index build eventually fails. Also,
+ if a failure does occur in the second scan, the <quote>invalid</quote> index
+ continues to enforce its uniqueness constraint afterwards.
+ </para>
+
+ <para>
+ Concurrent builds of expression indexes and partial indexes are supported.
+ Errors occurring in the evaluation of these expressions could cause
+ behavior similar to that described above for unique constraint violations.
+ </para>
+
+ <para>
+ Regular index builds permit other regular index builds on the
+ same table to occur simultaneously, but only one concurrent index build
+ can occur on a table at a time. In either case, schema modification of the
+ table is not allowed while the index is being built. Another difference is
+ that a regular <command>CREATE INDEX</command> command can be performed
+ within a transaction block, but <command>CREATE INDEX CONCURRENTLY</command>
+ cannot.
+ </para>
+
+ <para>
+ Concurrent builds for indexes on partitioned tables are currently not
+ supported. However, you may concurrently build the index on each
+ partition individually and then finally create the partitioned index
+ non-concurrently in order to reduce the time where writes to the
+ partitioned table will be locked out. In this case, building the
+ partitioned index is a metadata only operation.
+ </para>
+
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ See <xref linkend="indexes"/> for information about when indexes can
+ be used, when they are not used, and in which particular situations
+ they can be useful.
+ </para>
+
+ <para>
+ Currently, only the B-tree, GiST, GIN, and BRIN index methods support
+ multiple-key-column indexes. Whether there can be multiple key
+ columns is independent of whether <literal>INCLUDE</literal> columns
+ can be added to the index. Indexes can have up to 32 columns,
+ including <literal>INCLUDE</literal> columns.
+ (This limit can be altered when building
+ <productname>PostgreSQL</productname>.) Only B-tree currently
+ supports unique indexes.
+ </para>
+
+ <para>
+ An <firstterm>operator class</firstterm> with optional parameters
+ can be specified for each column of an index.
+ The operator class identifies the operators to be
+ used by the index for that column. For example, a B-tree index on
+ four-byte integers would use the <literal>int4_ops</literal> class;
+ this operator class includes comparison functions for four-byte
+ integers. In practice the default operator class for the column's data
+ type is usually sufficient. The main point of having operator classes
+ is that for some data types, there could be more than one meaningful
+ ordering. For example, we might want to sort a complex-number data
+ type either by absolute value or by real part. We could do this by
+ defining two operator classes for the data type and then selecting
+ the proper class when creating an index. More information about
+ operator classes is in <xref linkend="indexes-opclass"/> and in <xref
+ linkend="xindex"/>.
+ </para>
+
+ <para>
+ When <literal>CREATE INDEX</literal> is invoked on a partitioned
+ table, the default behavior is to recurse to all partitions to ensure
+ they all have matching indexes.
+ Each partition is first checked to determine whether an equivalent
+ index already exists, and if so, that index will become attached as a
+ partition index to the index being created, which will become its
+ parent index.
+ If no matching index exists, a new index will be created and
+ automatically attached; the name of the new index in each partition
+ will be determined as if no index name had been specified in the
+ command.
+ If the <literal>ONLY</literal> option is specified, no recursion
+ is done, and the index is marked invalid.
+ (<command>ALTER INDEX ... ATTACH PARTITION</command> marks the index
+ valid, once all partitions acquire matching indexes.) Note, however,
+ that any partition that is created in the future using
+ <command>CREATE TABLE ... PARTITION OF</command> will automatically
+ have a matching index, regardless of whether <literal>ONLY</literal> is
+ specified.
+ </para>
+
+ <para>
+ For index methods that support ordered scans (currently, only B-tree),
+ the optional clauses <literal>ASC</literal>, <literal>DESC</literal>, <literal>NULLS
+ FIRST</literal>, and/or <literal>NULLS LAST</literal> can be specified to modify
+ the sort ordering of the index. Since an ordered index can be
+ scanned either forward or backward, it is not normally useful to create a
+ single-column <literal>DESC</literal> index &mdash; that sort ordering is already
+ available with a regular index. The value of these options is that
+ multicolumn indexes can be created that match the sort ordering requested
+ by a mixed-ordering query, such as <literal>SELECT ... ORDER BY x ASC, y
+ DESC</literal>. The <literal>NULLS</literal> options are useful if you need to support
+ <quote>nulls sort low</quote> behavior, rather than the default <quote>nulls
+ sort high</quote>, in queries that depend on indexes to avoid sorting steps.
+ </para>
+
+ <para>
+ The system regularly collects statistics on all of a table's
+ columns. Newly-created non-expression indexes can immediately
+ use these statistics to determine an index's usefulness.
+ For new expression indexes, it is necessary to run <link
+ linkend="sql-analyze"><command>ANALYZE</command></link> or wait for
+ the <link linkend="autovacuum">autovacuum daemon</link> to analyze
+ the table to generate statistics for these indexes.
+ </para>
+
+ <para>
+ For most index methods, the speed of creating an index is
+ dependent on the setting of <xref linkend="guc-maintenance-work-mem"/>.
+ Larger values will reduce the time needed for index creation, so long
+ as you don't make it larger than the amount of memory really available,
+ which would drive the machine into swapping.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> can build indexes while
+ leveraging multiple CPUs in order to process the table rows faster.
+ This feature is known as <firstterm>parallel index
+ build</firstterm>. For index methods that support building indexes
+ in parallel (currently, only B-tree),
+ <varname>maintenance_work_mem</varname> specifies the maximum
+ amount of memory that can be used by each index build operation as
+ a whole, regardless of how many worker processes were started.
+ Generally, a cost model automatically determines how many worker
+ processes should be requested, if any.
+ </para>
+
+ <para>
+ Parallel index builds may benefit from increasing
+ <varname>maintenance_work_mem</varname> where an equivalent serial
+ index build will see little or no benefit. Note that
+ <varname>maintenance_work_mem</varname> may influence the number of
+ worker processes requested, since parallel workers must have at
+ least a <literal>32MB</literal> share of the total
+ <varname>maintenance_work_mem</varname> budget. There must also be
+ a remaining <literal>32MB</literal> share for the leader process.
+ Increasing <xref linkend="guc-max-parallel-maintenance-workers"/>
+ may allow more workers to be used, which will reduce the time
+ needed for index creation, so long as the index build is not
+ already I/O bound. Of course, there should also be sufficient
+ CPU capacity that would otherwise lie idle.
+ </para>
+
+ <para>
+ Setting a value for <literal>parallel_workers</literal> via <link
+ linkend="sql-altertable"><command>ALTER TABLE</command></link> directly controls how many parallel
+ worker processes will be requested by a <command>CREATE
+ INDEX</command> against the table. This bypasses the cost model
+ completely, and prevents <varname>maintenance_work_mem</varname>
+ from affecting how many parallel workers are requested. Setting
+ <literal>parallel_workers</literal> to 0 via <command>ALTER
+ TABLE</command> will disable parallel index builds on the table in
+ all cases.
+ </para>
+
+ <tip>
+ <para>
+ You might want to reset <literal>parallel_workers</literal> after
+ setting it as part of tuning an index build. This avoids
+ inadvertent changes to query plans, since
+ <literal>parallel_workers</literal> affects
+ <emphasis>all</emphasis> parallel table scans.
+ </para>
+ </tip>
+
+ <para>
+ While <command>CREATE INDEX</command> with the
+ <literal>CONCURRENTLY</literal> option supports parallel builds
+ without special restrictions, only the first table scan is actually
+ performed in parallel.
+ </para>
+
+ <para>
+ Use <link linkend="sql-dropindex"><command>DROP INDEX</command></link>
+ to remove an index.
+ </para>
+
+ <para>
+ Like any long-running transaction, <command>CREATE INDEX</command> on a
+ table can affect which tuples can be removed by concurrent
+ <command>VACUUM</command> on any other table.
+ </para>
+
+ <para>
+ Prior releases of <productname>PostgreSQL</productname> also had an
+ R-tree index method. This method has been removed because
+ it had no significant advantages over the GiST method.
+ If <literal>USING rtree</literal> is specified, <command>CREATE INDEX</command>
+ will interpret it as <literal>USING gist</literal>, to simplify conversion
+ of old databases to GiST.
+ </para>
+
+ <para>
+ Each backend running <command>CREATE INDEX</command> will report its
+ progress in the <structname>pg_stat_progress_create_index</structname>
+ view. See <xref linkend="create-index-progress-reporting"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create a unique B-tree index on the column <literal>title</literal> in
+ the table <literal>films</literal>:
+<programlisting>
+CREATE UNIQUE INDEX title_idx ON films (title);
+</programlisting>
+ </para>
+
+ <para>
+ To create a unique B-tree index on the column <literal>title</literal>
+ with included columns <literal>director</literal>
+ and <literal>rating</literal> in the table <literal>films</literal>:
+<programlisting>
+CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);
+</programlisting>
+ </para>
+
+ <para>
+ To create a B-Tree index with deduplication disabled:
+<programlisting>
+CREATE INDEX title_idx ON films (title) WITH (deduplicate_items = off);
+</programlisting>
+ </para>
+
+ <para>
+ To create an index on the expression <literal>lower(title)</literal>,
+ allowing efficient case-insensitive searches:
+<programlisting>
+CREATE INDEX ON films ((lower(title)));
+</programlisting>
+ (In this example we have chosen to omit the index name, so the system
+ will choose a name, typically <literal>films_lower_idx</literal>.)
+ </para>
+
+ <para>
+ To create an index with non-default collation:
+<programlisting>
+CREATE INDEX title_idx_german ON films (title COLLATE "de_DE");
+</programlisting>
+ </para>
+
+ <para>
+ To create an index with non-default sort ordering of nulls:
+<programlisting>
+CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);
+</programlisting>
+ </para>
+
+ <para>
+ To create an index with non-default fill factor:
+<programlisting>
+CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70);
+</programlisting>
+ </para>
+
+ <para>
+ To create a <acronym>GIN</acronym> index with fast updates disabled:
+<programlisting>
+CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off);
+</programlisting>
+ </para>
+
+ <para>
+ To create an index on the column <literal>code</literal> in the table
+ <literal>films</literal> and have the index reside in the tablespace
+ <literal>indexspace</literal>:
+<programlisting>
+CREATE INDEX code_idx ON films (code) TABLESPACE indexspace;
+</programlisting>
+ </para>
+
+ <para>
+ To create a GiST index on a point attribute so that we
+ can efficiently use box operators on the result of the
+ conversion function:
+<programlisting>
+CREATE INDEX pointloc
+ ON points USING gist (box(location,location));
+SELECT * FROM points
+ WHERE box(location,location) &amp;&amp; '(0,0),(1,1)'::box;
+</programlisting>
+ </para>
+
+ <para>
+ To create an index without locking out writes to the table:
+<programlisting>
+CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE INDEX</command> is a
+ <productname>PostgreSQL</productname> language extension. There
+ are no provisions for indexes in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterindex"/></member>
+ <member><xref linkend="sql-dropindex"/></member>
+ <member><xref linkend="sql-reindex"/></member>
+ <member><xref linkend="create-index-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml
new file mode 100644
index 0000000..102efe5
--- /dev/null
+++ b/doc/src/sgml/ref/create_language.sgml
@@ -0,0 +1,250 @@
+<!--
+doc/src/sgml/ref/create_language.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createlanguage">
+ <indexterm zone="sql-createlanguage">
+ <primary>CREATE LANGUAGE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE LANGUAGE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE LANGUAGE</refname>
+ <refpurpose>define a new procedural language</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</replaceable>
+ HANDLER <replaceable class="parameter">call_handler</replaceable> [ INLINE <replaceable class="parameter">inline_handler</replaceable> ] [ VALIDATOR <replaceable>valfunction</replaceable> ]
+CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createlanguage-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE LANGUAGE</command> registers a new
+ procedural language with a <productname>PostgreSQL</productname>
+ database. Subsequently, functions and procedures can be
+ defined in this new language.
+ </para>
+
+ <para>
+ <command>CREATE LANGUAGE</command> effectively associates the
+ language name with handler function(s) that are responsible for executing
+ functions written in the language. Refer to <xref linkend="plhandler"/>
+ for more information about language handlers.
+ </para>
+
+ <para>
+ <command>CREATE OR REPLACE LANGUAGE</command> will either create a
+ new language, or replace an existing definition. If the language
+ already exists, its parameters are updated according to the command,
+ but the language's ownership and permissions settings do not change,
+ and any existing functions written in the language are assumed to still
+ be valid.
+ </para>
+
+ <para>
+ One must have the
+ <productname>PostgreSQL</productname> superuser privilege to
+ register a new language or change an existing language's parameters.
+ However, once the language is created it is valid to assign ownership of
+ it to a non-superuser, who may then drop it, change its permissions,
+ rename it, or assign it to a new owner. (Do not, however, assign
+ ownership of the underlying C functions to a non-superuser; that would
+ create a privilege escalation path for that user.)
+ </para>
+
+ <para>
+ The form of <command>CREATE LANGUAGE</command> that does not supply
+ any handler function is obsolete. For backwards compatibility with
+ old dump files, it is interpreted as <command>CREATE EXTENSION</command>.
+ That will work if the language has been packaged into an extension of
+ the same name, which is the conventional way to set up procedural
+ languages.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createlanguage-parameters">
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TRUSTED</literal></term>
+
+ <listitem>
+ <para><literal>TRUSTED</literal> specifies that the language does
+ not grant access to data that the user would not otherwise
+ have. If this key word is omitted
+ when registering the language, only users with the
+ <productname>PostgreSQL</productname> superuser privilege can
+ use this language to create new functions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROCEDURAL</literal></term>
+
+ <listitem>
+ <para>
+ This is a noise word.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the new procedural language.
+ The name must be unique among the languages in the database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HANDLER</literal> <replaceable class="parameter">call_handler</replaceable></term>
+
+ <listitem>
+ <para><replaceable class="parameter">call_handler</replaceable> is
+ the name of a previously registered function that will be
+ called to execute the procedural language's functions. The call
+ handler for a procedural language must be written in a compiled
+ language such as C with version 1 call convention and
+ registered with <productname>PostgreSQL</productname> as a
+ function taking no arguments and returning the
+ <type>language_handler</type> type, a placeholder type that is
+ simply used to identify the function as a call handler.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INLINE</literal> <replaceable class="parameter">inline_handler</replaceable></term>
+
+ <listitem>
+ <para><replaceable class="parameter">inline_handler</replaceable> is the
+ name of a previously registered function that will be called
+ to execute an anonymous code block
+ (<link linkend="sql-do"><command>DO</command></link> command)
+ in this language.
+ If no <replaceable class="parameter">inline_handler</replaceable>
+ function is specified, the language does not support anonymous code
+ blocks.
+ The handler function must take one argument of
+ type <type>internal</type>, which will be the <command>DO</command> command's
+ internal representation, and it will typically return
+ <type>void</type>. The return value of the handler is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALIDATOR</literal> <replaceable class="parameter">valfunction</replaceable></term>
+
+ <listitem>
+ <para><replaceable class="parameter">valfunction</replaceable> is the
+ name of a previously registered function that will be called
+ when a new function in the language is created, to validate the
+ new function.
+ If no
+ validator function is specified, then a new function will not
+ be checked when it is created.
+ The validator function must take one argument of
+ type <type>oid</type>, which will be the OID of the
+ to-be-created function, and will typically return <type>void</type>.
+ </para>
+
+ <para>
+ A validator function would typically inspect the function body
+ for syntactical correctness, but it can also look at other
+ properties of the function, for example if the language cannot
+ handle certain argument types. To signal an error, the
+ validator function should use the <function>ereport()</function>
+ function. The return value of the function is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createlanguage-notes">
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-droplanguage"><command>DROP LANGUAGE</command></link> to drop procedural languages.
+ </para>
+
+ <para>
+ The system catalog <classname>pg_language</classname> (see <xref
+ linkend="catalog-pg-language"/>) records information about the
+ currently installed languages. Also, the <application>psql</application>
+ command <command>\dL</command> lists the installed languages.
+ </para>
+
+ <para>
+ To create functions in a procedural language, a user must have the
+ <literal>USAGE</literal> privilege for the language. By default,
+ <literal>USAGE</literal> is granted to <literal>PUBLIC</literal> (i.e., everyone)
+ for trusted languages. This can be revoked if desired.
+ </para>
+
+ <para>
+ Procedural languages are local to individual databases.
+ However, a language can be installed into the <literal>template1</literal>
+ database, which will cause it to be available automatically in
+ all subsequently-created databases.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createlanguage-examples">
+ <title>Examples</title>
+
+ <para>
+ A minimal sequence for creating a new procedural language is:
+<programlisting>
+CREATE FUNCTION plsample_call_handler() RETURNS language_handler
+ AS '$libdir/plsample'
+ LANGUAGE C;
+CREATE LANGUAGE plsample
+ HANDLER plsample_call_handler;
+</programlisting>
+ Typically that would be written in an extension's creation script,
+ and users would do this to install the extension:
+<programlisting>
+CREATE EXTENSION plsample;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-createlanguage-compat">
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE LANGUAGE</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterlanguage"/></member>
+ <member><xref linkend="sql-createfunction"/></member>
+ <member><xref linkend="sql-droplanguage"/></member>
+ <member><xref linkend="sql-grant"/></member>
+ <member><xref linkend="sql-revoke"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_materialized_view.sgml b/doc/src/sgml/ref/create_materialized_view.sgml
new file mode 100644
index 0000000..0d2fea2
--- /dev/null
+++ b/doc/src/sgml/ref/create_materialized_view.sgml
@@ -0,0 +1,187 @@
+<!--
+doc/src/sgml/ref/create_materialized_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-creatematerializedview">
+ <indexterm zone="sql-creatematerializedview">
+ <primary>CREATE MATERIALIZED VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE MATERIALIZED VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE MATERIALIZED VIEW</refname>
+ <refpurpose>define a new materialized view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable>
+ [ (<replaceable>column_name</replaceable> [, ...] ) ]
+ [ USING <replaceable class="parameter">method</replaceable> ]
+ [ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+ [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+ AS <replaceable>query</replaceable>
+ [ WITH [ NO ] DATA ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE MATERIALIZED VIEW</command> defines a materialized view of
+ a query. The query is executed and used to populate the view at the time
+ the command is issued (unless <command>WITH NO DATA</command> is used) and may be
+ refreshed later using <command>REFRESH MATERIALIZED VIEW</command>.
+ </para>
+
+ <para>
+ <command>CREATE MATERIALIZED VIEW</command> is similar to
+ <command>CREATE TABLE AS</command>, except that it also remembers the query used
+ to initialize the view, so that it can be refreshed later upon demand.
+ A materialized view has many of the same properties as a table, but there
+ is no support for temporary materialized views.
+ </para>
+
+ <para>
+ <command>CREATE MATERIALIZED VIEW</command> requires
+ <literal>CREATE</literal> privilege on the schema used for the materialized
+ view.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a materialized view with the same name already
+ exists. A notice is issued in this case. Note that there is no guarantee
+ that the existing materialized view is anything like the one that would
+ have been created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the materialized view to be
+ created. The name must be distinct from the name of any other relation
+ (table, sequence, index, view, materialized view, or foreign table) in
+ the same schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column in the new materialized view. If column names are
+ not provided, they are taken from the output column names of the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USING <replaceable class="parameter">method</replaceable></literal></term>
+ <listitem>
+ <para>
+ This optional clause specifies the table access method to use to store
+ the contents for the new materialized view; the method needs be an
+ access method of type <literal>TABLE</literal>. See <xref
+ linkend="tableam"/> for more information. If this option is not
+ specified, the default table access method is chosen for the new
+ materialized view. See <xref linkend="guc-default-table-access-method"/>
+ for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies optional storage parameters for the new
+ materialized view; see
+ <xref linkend="sql-createtable-storage-parameters"/> in the
+ <xref linkend="sql-createtable"/> documentation for more
+ information. All parameters supported for <literal>CREATE
+ TABLE</literal> are also supported for <literal>CREATE MATERIALIZED
+ VIEW</literal>.
+ See <xref linkend="sql-createtable"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLESPACE <replaceable class="parameter">tablespace_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <replaceable class="parameter">tablespace_name</replaceable> is the name
+ of the tablespace in which the new materialized view is to be created.
+ If not specified, <xref linkend="guc-default-tablespace"/> is consulted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>query</replaceable></term>
+ <listitem>
+ <para>
+ A <link linkend="sql-select"><command>SELECT</command></link>, <link linkend="sql-table"><command>TABLE</command></link>,
+ or <link linkend="sql-values"><command>VALUES</command></link> command. This query will run within a
+ security-restricted operation; in particular, calls to functions that
+ themselves create temporary tables will fail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH [ NO ] DATA</literal></term>
+ <listitem>
+ <para>
+ This clause specifies whether or not the materialized view should be
+ populated at creation time. If not, the materialized view will be
+ flagged as unscannable and cannot be queried until <command>REFRESH
+ MATERIALIZED VIEW</command> is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE MATERIALIZED VIEW</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altermaterializedview"/></member>
+ <member><xref linkend="sql-createtableas"/></member>
+ <member><xref linkend="sql-createview"/></member>
+ <member><xref linkend="sql-dropmaterializedview"/></member>
+ <member><xref linkend="sql-refreshmaterializedview"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml
new file mode 100644
index 0000000..f1d6a4c
--- /dev/null
+++ b/doc/src/sgml/ref/create_opclass.sgml
@@ -0,0 +1,330 @@
+<!--
+doc/src/sgml/ref/create_opclass.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createopclass">
+ <indexterm zone="sql-createopclass">
+ <primary>CREATE OPERATOR CLASS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE OPERATOR CLASS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE OPERATOR CLASS</refname>
+ <refpurpose>define a new operator class</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAULT ] FOR TYPE <replaceable class="parameter">data_type</replaceable>
+ USING <replaceable class="parameter">index_method</replaceable> [ FAMILY <replaceable class="parameter">family_name</replaceable> ] AS
+ { OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> [ ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) ] [ FOR SEARCH | FOR ORDER BY <replaceable class="parameter">sort_family_name</replaceable> ]
+ | FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
+ | STORAGE <replaceable class="parameter">storage_type</replaceable>
+ } [, ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE OPERATOR CLASS</command> creates a new operator class.
+ An operator class defines how a particular data type can be used with
+ an index. The operator class specifies that certain operators will fill
+ particular roles or <quote>strategies</quote> for this data type and this
+ index method. The operator class also specifies the support functions to
+ be used by
+ the index method when the operator class is selected for an
+ index column. All the operators and functions used by an operator
+ class must be defined before the operator class can be created.
+ </para>
+
+ <para>
+ If a schema name is given then the operator class is created in the
+ specified schema. Otherwise it is created in the current schema.
+ Two operator classes in the same schema can have the same name only if they
+ are for different index methods.
+ </para>
+
+ <para>
+ The user who defines an operator class becomes its owner. Presently,
+ the creating user must be a superuser. (This restriction is made because
+ an erroneous operator class definition could confuse or even crash the
+ server.)
+ </para>
+
+ <para>
+ <command>CREATE OPERATOR CLASS</command> does not presently check
+ whether the operator class definition includes all the operators and
+ functions required by the index method, nor whether the operators and
+ functions form a self-consistent set. It is the user's
+ responsibility to define a valid operator class.
+ </para>
+
+ <para>
+ Related operator classes can be grouped into <firstterm>operator
+ families</firstterm>. To add a new operator class to an existing family,
+ specify the <literal>FAMILY</literal> option in <command>CREATE OPERATOR
+ CLASS</command>. Without this option, the new class is placed into
+ a family named the same as the new class (creating that family if
+ it doesn't already exist).
+ </para>
+
+ <para>
+ Refer to <xref linkend="xindex"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the operator class to be created. The name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ If present, the operator class will become the default
+ operator class for its data type. At most one operator class
+ can be the default for a specific data type and index method.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The column data type that this operator class is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index method this operator class is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">family_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the existing operator family to add this operator class to.
+ If not specified, a family named the same as the operator class is
+ used (creating it, if it doesn't already exist).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">strategy_number</replaceable></term>
+ <listitem>
+ <para>
+ The index method's strategy number for an operator
+ associated with the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">operator_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an operator associated
+ with the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">op_type</replaceable></term>
+ <listitem>
+ <para>
+ In an <literal>OPERATOR</literal> clause,
+ the operand data type(s) of the operator, or <literal>NONE</literal> to
+ signify a prefix operator. The operand data
+ types can be omitted in the normal case where they are the same
+ as the operator class's data type.
+ </para>
+
+ <para>
+ In a <literal>FUNCTION</literal> clause, the operand data type(s) the
+ function is intended to support, if different from
+ the input data type(s) of the function (for B-tree comparison functions
+ and hash functions)
+ or the class's data type (for B-tree sort support functions,
+ B-tree equal image functions, and all functions in GiST,
+ SP-GiST, GIN and BRIN operator classes). These defaults are
+ correct, and so <replaceable
+ class="parameter">op_type</replaceable> need not be specified
+ in <literal>FUNCTION</literal> clauses, except for the case of a
+ B-tree sort support function that is meant to support
+ cross-data-type comparisons.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sort_family_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing <literal>btree</literal> operator
+ family that describes the sort ordering associated with an ordering
+ operator.
+ </para>
+
+ <para>
+ If neither <literal>FOR SEARCH</literal> nor <literal>FOR ORDER BY</literal> is
+ specified, <literal>FOR SEARCH</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">support_number</replaceable></term>
+ <listitem>
+ <para>
+ The index method's support function number for a
+ function associated with the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a function that is an
+ index method support function for the operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argument_type</replaceable></term>
+ <listitem>
+ <para>
+ The parameter data type(s) of the function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">storage_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type actually stored in the index. Normally this is
+ the same as the column data type, but some index methods
+ (currently GiST, GIN, SP-GiST and BRIN) allow it to be different. The
+ <literal>STORAGE</literal> clause must be omitted unless the index
+ method allows a different type to be used.
+ If the column <replaceable class="parameter">data_type</replaceable> is specified
+ as <type>anyarray</type>, the <replaceable class="parameter">storage_type</replaceable>
+ can be declared as <type>anyelement</type> to indicate that the index
+ entries are members of the element type belonging to the actual array
+ type that each particular index is created for.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The <literal>OPERATOR</literal>, <literal>FUNCTION</literal>, and <literal>STORAGE</literal>
+ clauses can appear in any order.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Because the index machinery does not check access permissions on functions
+ before using them, including a function or operator in an operator class
+ is tantamount to granting public execute permission on it. This is usually
+ not an issue for the sorts of functions that are useful in an operator
+ class.
+ </para>
+
+ <para>
+ The operators should not be defined by SQL functions. An SQL function
+ is likely to be inlined into the calling query, which will prevent
+ the optimizer from recognizing that the query matches an index.
+ </para>
+
+ <para>
+ Before <productname>PostgreSQL</productname> 8.4, the <literal>OPERATOR</literal>
+ clause could include a <literal>RECHECK</literal> option. This is no longer
+ supported because whether an index operator is <quote>lossy</quote> is now
+ determined on-the-fly at run time. This allows efficient handling of
+ cases where an operator might or might not be lossy.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example command defines a GiST index operator class
+ for the data type <literal>_int4</literal> (array of <type>int4</type>). See the
+ <xref linkend="intarray"/> module for the complete example.
+ </para>
+
+<programlisting>
+CREATE OPERATOR CLASS gist__int_ops
+ DEFAULT FOR TYPE _int4 USING gist AS
+ OPERATOR 3 &amp;&amp;,
+ OPERATOR 6 = (anyarray, anyarray),
+ OPERATOR 7 @&gt;,
+ OPERATOR 8 &lt;@,
+ OPERATOR 20 @@ (_int4, query_int),
+ FUNCTION 1 g_int_consistent (internal, _int4, smallint, oid, internal),
+ FUNCTION 2 g_int_union (internal, internal),
+ FUNCTION 3 g_int_compress (internal),
+ FUNCTION 4 g_int_decompress (internal),
+ FUNCTION 5 g_int_penalty (internal, internal, internal),
+ FUNCTION 6 g_int_picksplit (internal, internal),
+ FUNCTION 7 g_int_same (_int4, _int4, internal);
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE OPERATOR CLASS</command> is a
+ <productname>PostgreSQL</productname> extension. There is no
+ <command>CREATE OPERATOR CLASS</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteropclass"/></member>
+ <member><xref linkend="sql-dropopclass"/></member>
+ <member><xref linkend="sql-createopfamily"/></member>
+ <member><xref linkend="sql-alteropfamily"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml
new file mode 100644
index 0000000..e27512f
--- /dev/null
+++ b/doc/src/sgml/ref/create_operator.sgml
@@ -0,0 +1,299 @@
+<!--
+doc/src/sgml/ref/create_operator.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createoperator">
+ <indexterm zone="sql-createoperator">
+ <primary>CREATE OPERATOR</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE OPERATOR</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE OPERATOR</refname>
+ <refpurpose>define a new operator</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE OPERATOR <replaceable>name</replaceable> (
+ {FUNCTION|PROCEDURE} = <replaceable class="parameter">function_name</replaceable>
+ [, LEFTARG = <replaceable class="parameter">left_type</replaceable> ] [, RIGHTARG = <replaceable class="parameter">right_type</replaceable> ]
+ [, COMMUTATOR = <replaceable class="parameter">com_op</replaceable> ] [, NEGATOR = <replaceable class="parameter">neg_op</replaceable> ]
+ [, RESTRICT = <replaceable class="parameter">res_proc</replaceable> ] [, JOIN = <replaceable class="parameter">join_proc</replaceable> ]
+ [, HASHES ] [, MERGES ]
+)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE OPERATOR</command> defines a new operator,
+ <replaceable class="parameter">name</replaceable>. The user who
+ defines an operator becomes its owner. If a schema name is given
+ then the operator is created in the specified schema. Otherwise it
+ is created in the current schema.
+ </para>
+
+ <para>
+ The operator name is a sequence of up to <symbol>NAMEDATALEN</symbol>-1
+ (63 by default) characters from the following list:
+<literallayout>
++ - * / &lt; &gt; = ~ ! @ # % ^ &amp; | ` ?
+</literallayout>
+
+ There are a few restrictions on your choice of name:
+ <itemizedlist>
+ <listitem>
+ <para><literal>--</literal> and <literal>/*</literal> cannot appear anywhere in an operator name,
+ since they will be taken as the start of a comment.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A multicharacter operator name cannot end in <literal>+</literal> or
+ <literal>-</literal>,
+ unless the name also contains at least one of these characters:
+<literallayout>
+~ ! @ # % ^ &amp; | ` ?
+</literallayout>
+ For example, <literal>@-</literal> is an allowed operator name,
+ but <literal>*-</literal> is not.
+ This restriction allows <productname>PostgreSQL</productname> to
+ parse SQL-compliant commands without requiring spaces between tokens.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The use of <literal>=&gt;</literal> as an operator name is deprecated. It may
+ be disallowed altogether in a future release.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The operator <literal>!=</literal> is mapped to
+ <literal>&lt;&gt;</literal> on input, so these two names are always
+ equivalent.
+ </para>
+
+ <para>
+ For binary operators, both <literal>LEFTARG</literal> and
+ <literal>RIGHTARG</literal> must be defined. For prefix operators only
+ <literal>RIGHTARG</literal> should be defined.
+ The <replaceable class="parameter">function_name</replaceable>
+ function must have been previously defined using <command>CREATE
+ FUNCTION</command> and must be defined to accept the correct number
+ of arguments (either one or two) of the indicated types.
+ </para>
+
+ <para>
+ In the syntax of <literal>CREATE OPERATOR</literal>, the keywords
+ <literal>FUNCTION</literal> and <literal>PROCEDURE</literal> are
+ equivalent, but the referenced function must in any case be a function, not
+ a procedure. The use of the keyword <literal>PROCEDURE</literal> here is
+ historical and deprecated.
+ </para>
+
+ <para>
+ The other clauses specify optional operator optimization clauses.
+ Their meaning is detailed in <xref linkend="xoper-optimization"/>.
+ </para>
+
+ <para>
+ To be able to create an operator, you must have <literal>USAGE</literal>
+ privilege on the argument types and the return type, as well
+ as <literal>EXECUTE</literal> privilege on the underlying function. If a
+ commutator or negator operator is specified, you must own these operators.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the operator to be defined. See above for allowable
+ characters. The name can be schema-qualified, for example
+ <literal>CREATE OPERATOR myschema.+ (...)</literal>. If not, then
+ the operator is created in the current schema. Two operators
+ in the same schema can have the same name if they operate on
+ different data types. This is called
+ <firstterm>overloading</firstterm>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <listitem>
+ <para>
+ The function used to implement this operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">left_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the operator's left operand, if any.
+ This option would be omitted for a prefix operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">right_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the operator's right operand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">com_op</replaceable></term>
+ <listitem>
+ <para>
+ The commutator of this operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">neg_op</replaceable></term>
+ <listitem>
+ <para>
+ The negator of this operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">res_proc</replaceable></term>
+ <listitem>
+ <para>
+ The restriction selectivity estimator function for this operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">join_proc</replaceable></term>
+ <listitem>
+ <para>
+ The join selectivity estimator function for this operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HASHES</literal></term>
+ <listitem>
+ <para>
+ Indicates this operator can support a hash join.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>MERGES</literal></term>
+ <listitem>
+ <para>
+ Indicates this operator can support a merge join.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ To give a schema-qualified operator name in <replaceable
+ class="parameter">com_op</replaceable> or the other optional
+ arguments, use the <literal>OPERATOR()</literal> syntax, for example:
+<programlisting>
+COMMUTATOR = OPERATOR(myschema.===) ,
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Refer to <xref linkend="xoper"/> for further information.
+ </para>
+
+ <para>
+ It is not possible to specify an operator's lexical precedence in
+ <command>CREATE OPERATOR</command>, because the parser's precedence behavior
+ is hard-wired. See <xref linkend="sql-precedence"/> for precedence details.
+ </para>
+
+ <para>
+ The obsolete options <literal>SORT1</literal>, <literal>SORT2</literal>,
+ <literal>LTCMP</literal>, and <literal>GTCMP</literal> were formerly used to
+ specify the names of sort operators associated with a merge-joinable
+ operator. This is no longer necessary, since information about
+ associated operators is found by looking at B-tree operator families
+ instead. If one of these options is given, it is ignored except
+ for implicitly setting <literal>MERGES</literal> true.
+ </para>
+
+ <para>
+ Use <link linkend="sql-dropoperator"><command>DROP OPERATOR</command></link> to delete user-defined operators
+ from a database. Use <link linkend="sql-alteroperator"><command>ALTER OPERATOR</command></link> to modify operators in a
+ database.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following command defines a new operator, area-equality, for
+ the data type <type>box</type>:
+<programlisting>
+CREATE OPERATOR === (
+ LEFTARG = box,
+ RIGHTARG = box,
+ FUNCTION = area_equal_function,
+ COMMUTATOR = ===,
+ NEGATOR = !==,
+ RESTRICT = area_restriction_function,
+ JOIN = area_join_function,
+ HASHES, MERGES
+);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE OPERATOR</command> is a
+ <productname>PostgreSQL</productname> extension. There are no
+ provisions for user-defined operators in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteroperator"/></member>
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-dropoperator"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_opfamily.sgml b/doc/src/sgml/ref/create_opfamily.sgml
new file mode 100644
index 0000000..ba612c2
--- /dev/null
+++ b/doc/src/sgml/ref/create_opfamily.sgml
@@ -0,0 +1,118 @@
+<!--
+doc/src/sgml/ref/create_opfamily.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createopfamily">
+ <indexterm zone="sql-createopfamily">
+ <primary>CREATE OPERATOR FAMILY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE OPERATOR FAMILY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE OPERATOR FAMILY</refname>
+ <refpurpose>define a new operator family</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE OPERATOR FAMILY <replaceable class="parameter">name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE OPERATOR FAMILY</command> creates a new operator family.
+ An operator family defines a collection of related operator classes,
+ and perhaps some additional operators and support functions that are
+ compatible with these operator classes but not essential for the
+ functioning of any individual index. (Operators and functions that
+ are essential to indexes should be grouped within the relevant operator
+ class, rather than being <quote>loose</quote> in the operator family.
+ Typically, single-data-type operators are bound to operator classes,
+ while cross-data-type operators can be loose in an operator family
+ containing operator classes for both data types.)
+ </para>
+
+ <para>
+ The new operator family is initially empty. It should be populated
+ by issuing subsequent <command>CREATE OPERATOR CLASS</command> commands
+ to add contained operator classes, and optionally
+ <command>ALTER OPERATOR FAMILY</command> commands to add <quote>loose</quote>
+ operators and their corresponding support functions.
+ </para>
+
+ <para>
+ If a schema name is given then the operator family is created in the
+ specified schema. Otherwise it is created in the current schema.
+ Two operator families in the same schema can have the same name only if they
+ are for different index methods.
+ </para>
+
+ <para>
+ The user who defines an operator family becomes its owner. Presently,
+ the creating user must be a superuser. (This restriction is made because
+ an erroneous operator family definition could confuse or even crash the
+ server.)
+ </para>
+
+ <para>
+ Refer to <xref linkend="xindex"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the operator family to be created. The name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index method this operator family is for.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE OPERATOR FAMILY</command> is a
+ <productname>PostgreSQL</productname> extension. There is no
+ <command>CREATE OPERATOR FAMILY</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteropfamily"/></member>
+ <member><xref linkend="sql-dropopfamily"/></member>
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-alteropclass"/></member>
+ <member><xref linkend="sql-dropopclass"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml
new file mode 100644
index 0000000..e76c342
--- /dev/null
+++ b/doc/src/sgml/ref/create_policy.sgml
@@ -0,0 +1,655 @@
+<!--
+doc/src/sgml/ref/create_policy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createpolicy">
+ <indexterm zone="sql-createpolicy">
+ <primary>CREATE POLICY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE POLICY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE POLICY</refname>
+ <refpurpose>define a new row-level security policy for a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE POLICY <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable>
+ [ AS { PERMISSIVE | RESTRICTIVE } ]
+ [ FOR { ALL | SELECT | INSERT | UPDATE | DELETE } ]
+ [ TO { <replaceable class="parameter">role_name</replaceable> | PUBLIC | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] ]
+ [ USING ( <replaceable class="parameter">using_expression</replaceable> ) ]
+ [ WITH CHECK ( <replaceable class="parameter">check_expression</replaceable> ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>CREATE POLICY</command> command defines a new row-level
+ security policy for a table. Note that row-level security must be
+ enabled on the table (using <command>ALTER TABLE ... ENABLE ROW LEVEL
+ SECURITY</command>) in order for created policies to be applied.
+ </para>
+
+ <para>
+ A policy grants the permission to select, insert, update, or delete rows
+ that match the relevant policy expression. Existing table rows are
+ checked against the expression specified in <literal>USING</literal>,
+ while new rows that would be created via <literal>INSERT</literal>
+ or <literal>UPDATE</literal> are checked against the expression specified
+ in <literal>WITH CHECK</literal>. When a <literal>USING</literal>
+ expression returns true for a given row then that row is visible to the
+ user, while if false or null is returned then the row is not visible.
+ When a <literal>WITH CHECK</literal> expression returns true for a row
+ then that row is inserted or updated, while if false or null is returned
+ then an error occurs.
+ </para>
+
+ <para>
+ For <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>MERGE</command> statements,
+ <literal>WITH CHECK</literal> expressions are enforced after
+ <literal>BEFORE</literal> triggers are fired, and before any actual data
+ modifications are made. Thus a <literal>BEFORE ROW</literal> trigger may
+ modify the data to be inserted, affecting the result of the security
+ policy check. <literal>WITH CHECK</literal> expressions are enforced
+ before any other constraints.
+ </para>
+
+ <para>
+ Policy names are per-table. Therefore, one policy name can be used for many
+ different tables and have a definition for each table which is appropriate to
+ that table.
+ </para>
+
+ <para>
+ Policies can be applied for specific commands or for specific roles. The
+ default for newly created policies is that they apply for all commands and
+ roles, unless otherwise specified. Multiple policies may apply to a single
+ command; see below for more details.
+ <xref linkend="sql-createpolicy-summary"/> summarizes how the different types
+ of policy apply to specific commands.
+ </para>
+
+ <para>
+ For policies that can have both <literal>USING</literal>
+ and <literal>WITH CHECK</literal> expressions (<literal>ALL</literal>
+ and <literal>UPDATE</literal>), if no <literal>WITH CHECK</literal>
+ expression is defined, then the <literal>USING</literal> expression will be
+ used both to determine which rows are visible (normal
+ <literal>USING</literal> case) and which new rows will be allowed to be
+ added (<literal>WITH CHECK</literal> case).
+ </para>
+
+ <para>
+ If row-level security is enabled for a table, but no applicable policies
+ exist, a <quote>default deny</quote> policy is assumed, so that no rows will
+ be visible or updatable.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the policy to be created. This must be distinct from the
+ name of any other policy for the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table the
+ policy applies to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PERMISSIVE</literal></term>
+ <listitem>
+ <para>
+ Specify that the policy is to be created as a permissive policy.
+ All permissive policies which are applicable to a given query will
+ be combined together using the Boolean <quote>OR</quote> operator. By creating
+ permissive policies, administrators can add to the set of records
+ which can be accessed. Policies are permissive by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICTIVE</literal></term>
+ <listitem>
+ <para>
+ Specify that the policy is to be created as a restrictive policy.
+ All restrictive policies which are applicable to a given query will
+ be combined together using the Boolean <quote>AND</quote> operator. By creating
+ restrictive policies, administrators can reduce the set of records
+ which can be accessed as all restrictive policies must be passed for
+ each record.
+ </para>
+
+ <para>
+ Note that there needs to be at least one permissive policy to grant
+ access to records before restrictive policies can be usefully used to
+ reduce that access. If only restrictive policies exist, then no records
+ will be accessible. When a mix of permissive and restrictive policies
+ are present, a record is only accessible if at least one of the
+ permissive policies passes, in addition to all the restrictive
+ policies.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">command</replaceable></term>
+ <listitem>
+ <para>
+ The command to which the policy applies. Valid options are
+ <command>ALL</command>, <command>SELECT</command>,
+ <command>INSERT</command>, <command>UPDATE</command>,
+ and <command>DELETE</command>.
+ <command>ALL</command> is the default.
+ See below for specifics regarding how these are applied.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The role(s) to which the policy is to be applied. The default is
+ <literal>PUBLIC</literal>, which will apply the policy to all roles.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">using_expression</replaceable></term>
+ <listitem>
+ <para>
+ Any <acronym>SQL</acronym> conditional expression (returning
+ <type>boolean</type>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be added
+ to queries that refer to the table if row-level security is enabled.
+ Rows for which the expression returns true will be visible. Any
+ rows for which the expression returns false or null will not be
+ visible to the user (in a <command>SELECT</command>), and will not be
+ available for modification (in an <command>UPDATE</command>
+ or <command>DELETE</command>). Such rows are silently suppressed; no error
+ is reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">check_expression</replaceable></term>
+ <listitem>
+ <para>
+ Any <acronym>SQL</acronym> conditional expression (returning
+ <type>boolean</type>). The conditional expression cannot contain
+ any aggregate or window functions. This expression will be used in
+ <command>INSERT</command> and <command>UPDATE</command> queries against
+ the table if row-level security is enabled. Only rows for which the
+ expression evaluates to true will be allowed. An error will be thrown
+ if the expression evaluates to false or null for any of the records
+ inserted or any of the records that result from the update. Note that
+ the <replaceable class="parameter">check_expression</replaceable> is
+ evaluated against the proposed new contents of the row, not the
+ original contents.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <refsect2>
+ <title>Per-Command Policies</title>
+
+ <variablelist>
+
+ <varlistentry id="sql-createpolicy-all">
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Using <literal>ALL</literal> for a policy means that it will apply
+ to all commands, regardless of the type of command. If an
+ <literal>ALL</literal> policy exists and more specific policies
+ exist, then both the <literal>ALL</literal> policy and the more
+ specific policy (or policies) will be applied.
+ Additionally, <literal>ALL</literal> policies will be applied to
+ both the selection side of a query and the modification side, using
+ the <literal>USING</literal> expression for both cases if only
+ a <literal>USING</literal> expression has been defined.
+ </para>
+ <para>
+ As an example, if an <literal>UPDATE</literal> is issued, then the
+ <literal>ALL</literal> policy will be applicable both to what the
+ <literal>UPDATE</literal> will be able to select as rows to be
+ updated (applying the <literal>USING</literal> expression),
+ and to the resulting updated rows, to check if they are permitted
+ to be added to the table (applying the <literal>WITH CHECK</literal>
+ expression, if defined, and the <literal>USING</literal> expression
+ otherwise). If an <command>INSERT</command>
+ or <command>UPDATE</command> command attempts to add rows to the
+ table that do not pass the <literal>ALL</literal>
+ policy's <literal>WITH CHECK</literal> expression, the entire
+ command will be aborted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createpolicy-select">
+ <term><literal>SELECT</literal></term>
+ <listitem>
+ <para>
+ Using <literal>SELECT</literal> for a policy means that it will apply
+ to <literal>SELECT</literal> queries and whenever
+ <literal>SELECT</literal> permissions are required on the relation the
+ policy is defined for. The result is that only those records from the
+ relation that pass the <literal>SELECT</literal> policy will be
+ returned during a <literal>SELECT</literal> query, and that queries
+ that require <literal>SELECT</literal> permissions, such as
+ <literal>UPDATE</literal>, will also only see those records
+ that are allowed by the <literal>SELECT</literal> policy.
+ A <literal>SELECT</literal> policy cannot have a <literal>WITH
+ CHECK</literal> expression, as it only applies in cases where
+ records are being retrieved from the relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createpolicy-insert">
+ <term><literal>INSERT</literal></term>
+ <listitem>
+ <para>
+ Using <literal>INSERT</literal> for a policy means that it will apply
+ to <literal>INSERT</literal> commands and <literal>MERGE</literal>
+ commands that contain <literal>INSERT</literal> actions.
+ Rows being inserted that do
+ not pass this policy will result in a policy violation error, and the
+ entire <literal>INSERT</literal> command will be aborted.
+ An <literal>INSERT</literal> policy cannot have
+ a <literal>USING</literal> expression, as it only applies in cases
+ where records are being added to the relation.
+ </para>
+ <para>
+ Note that <literal>INSERT</literal> with <literal>ON CONFLICT DO
+ UPDATE</literal> checks <literal>INSERT</literal> policies'
+ <literal>WITH CHECK</literal> expressions only for rows appended
+ to the relation by the <literal>INSERT</literal> path.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createpolicy-update">
+ <term><literal>UPDATE</literal></term>
+ <listitem>
+ <para>
+ Using <literal>UPDATE</literal> for a policy means that it will apply
+ to <literal>UPDATE</literal>, <literal>SELECT FOR UPDATE</literal>
+ and <literal>SELECT FOR SHARE</literal> commands, as well as
+ auxiliary <literal>ON CONFLICT DO UPDATE</literal> clauses of
+ <literal>INSERT</literal> commands.
+ <literal>MERGE</literal> commands containing <literal>UPDATE</literal>
+ actions are affected as well. Since <literal>UPDATE</literal>
+ involves pulling an existing record and replacing it with a new
+ modified record, <literal>UPDATE</literal>
+ policies accept both a <literal>USING</literal> expression and
+ a <literal>WITH CHECK</literal> expression.
+ The <literal>USING</literal> expression determines which records
+ the <literal>UPDATE</literal> command will see to operate against,
+ while the <literal>WITH CHECK</literal> expression defines which
+ modified rows are allowed to be stored back into the relation.
+ </para>
+
+ <para>
+ Any rows whose updated values do not pass the
+ <literal>WITH CHECK</literal> expression will cause an error, and the
+ entire command will be aborted. If only a <literal>USING</literal>
+ clause is specified, then that clause will be used for both
+ <literal>USING</literal> and <literal>WITH CHECK</literal> cases.
+ </para>
+
+ <para>
+ Typically an <literal>UPDATE</literal> command also needs to read
+ data from columns in the relation being updated (e.g., in a
+ <literal>WHERE</literal> clause or a <literal>RETURNING</literal>
+ clause, or in an expression on the right hand side of the
+ <literal>SET</literal> clause). In this case,
+ <literal>SELECT</literal> rights are also required on the relation
+ being updated, and the appropriate <literal>SELECT</literal> or
+ <literal>ALL</literal> policies will be applied in addition to
+ the <literal>UPDATE</literal> policies. Thus the user must have
+ access to the row(s) being updated through a <literal>SELECT</literal>
+ or <literal>ALL</literal> policy in addition to being granted
+ permission to update the row(s) via an <literal>UPDATE</literal>
+ or <literal>ALL</literal> policy.
+ </para>
+
+ <para>
+ When an <literal>INSERT</literal> command has an auxiliary
+ <literal>ON CONFLICT DO UPDATE</literal> clause, if the
+ <literal>UPDATE</literal> path is taken, the row to be updated is
+ first checked against the <literal>USING</literal> expressions of
+ any <literal>UPDATE</literal> policies, and then the new updated row
+ is checked against the <literal>WITH CHECK</literal> expressions.
+ Note, however, that unlike a standalone <literal>UPDATE</literal>
+ command, if the existing row does not pass the
+ <literal>USING</literal> expressions, an error will be thrown (the
+ <literal>UPDATE</literal> path will <emphasis>never</emphasis> be silently
+ avoided).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createpolicy-delete">
+ <term><literal>DELETE</literal></term>
+ <listitem>
+ <para>
+ Using <literal>DELETE</literal> for a policy means that it will apply
+ to <literal>DELETE</literal> commands. Only rows that pass this
+ policy will be seen by a <literal>DELETE</literal> command. There can
+ be rows that are visible through a <literal>SELECT</literal> that are
+ not available for deletion, if they do not pass the
+ <literal>USING</literal> expression for
+ the <literal>DELETE</literal> policy.
+ </para>
+
+ <para>
+ In most cases a <literal>DELETE</literal> command also needs to read
+ data from columns in the relation that it is deleting from (e.g.,
+ in a <literal>WHERE</literal> clause or a
+ <literal>RETURNING</literal> clause). In this case,
+ <literal>SELECT</literal> rights are also required on the relation,
+ and the appropriate <literal>SELECT</literal> or
+ <literal>ALL</literal> policies will be applied in addition to
+ the <literal>DELETE</literal> policies. Thus the user must have
+ access to the row(s) being deleted through a <literal>SELECT</literal>
+ or <literal>ALL</literal> policy in addition to being granted
+ permission to delete the row(s) via a <literal>DELETE</literal> or
+ <literal>ALL</literal> policy.
+ </para>
+
+ <para>
+ A <literal>DELETE</literal> policy cannot have a <literal>WITH
+ CHECK</literal> expression, as it only applies in cases where
+ records are being deleted from the relation, so that there is no
+ new row to check.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <table id="sql-createpolicy-summary">
+ <title>Policies Applied by Command Type</title>
+ <tgroup cols="6">
+ <colspec colnum="4" colname="update-using"/>
+ <colspec colnum="5" colname="update-check"/>
+ <spanspec namest="update-using" nameend="update-check" spanname="update"/>
+ <thead>
+ <row>
+ <entry morerows="1">Command</entry>
+ <entry><literal>SELECT/ALL policy</literal></entry>
+ <entry><literal>INSERT/ALL policy</literal></entry>
+ <entry spanname="update"><literal>UPDATE/ALL policy</literal></entry>
+ <entry><literal>DELETE/ALL policy</literal></entry>
+ </row>
+ <row>
+ <entry><literal>USING expression</literal></entry>
+ <entry><literal>WITH CHECK expression</literal></entry>
+ <entry><literal>USING expression</literal></entry>
+ <entry><literal>WITH CHECK expression</literal></entry>
+ <entry><literal>USING expression</literal></entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><command>SELECT</command></entry>
+ <entry>Existing row</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ </row>
+ <row>
+ <entry><command>SELECT FOR UPDATE/SHARE</command></entry>
+ <entry>Existing row</entry>
+ <entry>&mdash;</entry>
+ <entry>Existing row</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ </row>
+ <row>
+ <entry><command>INSERT</command> / <command>MERGE ... THEN INSERT</command></entry>
+ <entry>&mdash;</entry>
+ <entry>New row</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ </row>
+ <row>
+ <entry><command>INSERT ... RETURNING</command></entry>
+ <entry>
+ New row <footnote id="rls-select-priv">
+ <para>
+ If read access is required to the existing or new row (for example,
+ a <literal>WHERE</literal> or <literal>RETURNING</literal> clause
+ that refers to columns from the relation).
+ </para>
+ </footnote>
+ </entry>
+ <entry>New row</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ </row>
+ <row>
+ <entry><command>UPDATE</command> / <command>MERGE ... THEN UPDATE</command></entry>
+ <entry>
+ Existing &amp; new rows <footnoteref linkend="rls-select-priv"/>
+ </entry>
+ <entry>&mdash;</entry>
+ <entry>Existing row</entry>
+ <entry>New row</entry>
+ <entry>&mdash;</entry>
+ </row>
+ <row>
+ <entry><command>DELETE</command></entry>
+ <entry>
+ Existing row <footnoteref linkend="rls-select-priv"/>
+ </entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ <entry>&mdash;</entry>
+ <entry>Existing row</entry>
+ </row>
+ <row>
+ <entry><command>ON CONFLICT DO UPDATE</command></entry>
+ <entry>Existing &amp; new rows</entry>
+ <entry>&mdash;</entry>
+ <entry>Existing row</entry>
+ <entry>New row</entry>
+ <entry>&mdash;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Application of Multiple Policies</title>
+
+ <para>
+ When multiple policies of different command types apply to the same command
+ (for example, <literal>SELECT</literal> and <literal>UPDATE</literal>
+ policies applied to an <literal>UPDATE</literal> command), then the user
+ must have both types of permissions (for example, permission to select rows
+ from the relation as well as permission to update them). Thus the
+ expressions for one type of policy are combined with the expressions for
+ the other type of policy using the <literal>AND</literal> operator.
+ </para>
+
+ <para>
+ When multiple policies of the same command type apply to the same command,
+ then there must be at least one <literal>PERMISSIVE</literal> policy
+ granting access to the relation, and all of the
+ <literal>RESTRICTIVE</literal> policies must pass. Thus all the
+ <literal>PERMISSIVE</literal> policy expressions are combined using
+ <literal>OR</literal>, all the <literal>RESTRICTIVE</literal> policy
+ expressions are combined using <literal>AND</literal>, and the results are
+ combined using <literal>AND</literal>. If there are no
+ <literal>PERMISSIVE</literal> policies, then access is denied.
+ </para>
+
+ <para>
+ Note that, for the purposes of combining multiple policies,
+ <literal>ALL</literal> policies are treated as having the same type as
+ whichever other type of policy is being applied.
+ </para>
+
+ <para>
+ For example, in an <literal>UPDATE</literal> command requiring both
+ <literal>SELECT</literal> and <literal>UPDATE</literal> permissions, if
+ there are multiple applicable policies of each type, they will be combined
+ as follows:
+
+<programlisting>
+<replaceable>expression</replaceable> from RESTRICTIVE SELECT/ALL policy 1
+AND
+<replaceable>expression</replaceable> from RESTRICTIVE SELECT/ALL policy 2
+AND
+...
+AND
+(
+ <replaceable>expression</replaceable> from PERMISSIVE SELECT/ALL policy 1
+ OR
+ <replaceable>expression</replaceable> from PERMISSIVE SELECT/ALL policy 2
+ OR
+ ...
+)
+AND
+<replaceable>expression</replaceable> from RESTRICTIVE UPDATE/ALL policy 1
+AND
+<replaceable>expression</replaceable> from RESTRICTIVE UPDATE/ALL policy 2
+AND
+...
+AND
+(
+ <replaceable>expression</replaceable> from PERMISSIVE UPDATE/ALL policy 1
+ OR
+ <replaceable>expression</replaceable> from PERMISSIVE UPDATE/ALL policy 2
+ OR
+ ...
+)
+</programlisting></para>
+
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ You must be the owner of a table to create or change policies for it.
+ </para>
+
+ <para>
+ While policies will be applied for explicit queries against tables
+ in the database, they are not applied when the system is performing internal
+ referential integrity checks or validating constraints. This means there are
+ indirect ways to determine that a given value exists. An example of this is
+ attempting to insert a duplicate value into a column that is a primary key
+ or has a unique constraint. If the insert fails then the user can infer that
+ the value already exists. (This example assumes that the user is permitted by
+ policy to insert records which they are not allowed to see.) Another example
+ is where a user is allowed to insert into a table which references another,
+ otherwise hidden table. Existence can be determined by the user inserting
+ values into the referencing table, where success would indicate that the
+ value exists in the referenced table. These issues can be addressed by
+ carefully crafting policies to prevent users from being able to insert,
+ delete, or update records at all which might possibly indicate a value they
+ are not otherwise able to see, or by using generated values (e.g., surrogate
+ keys) instead of keys with external meanings.
+ </para>
+
+ <para>
+ Generally, the system will enforce filter conditions imposed using
+ security policies prior to qualifications that appear in user queries,
+ in order to prevent inadvertent exposure of the protected data to
+ user-defined functions which might not be trustworthy. However,
+ functions and operators marked by the system (or the system
+ administrator) as <literal>LEAKPROOF</literal> may be evaluated before
+ policy expressions, as they are assumed to be trustworthy.
+ </para>
+
+ <para>
+ Since policy expressions
+ are added to the user's query directly, they will be run with the rights of
+ the user running the overall query. Therefore, users who are using a given
+ policy must be able to access any tables or functions referenced in the
+ expression or they will simply receive a permission denied error when
+ attempting to query the table that has row-level security enabled.
+ This does not change how views
+ work, however. As with normal queries and views, permission checks and
+ policies for the tables which are referenced by a view will use the view
+ owner's rights and any policies which apply to the view owner, except if
+ the view is defined using the <literal>security_invoker</literal> option
+ (see <link linkend="sql-createview"><command>CREATE VIEW</command></link>).
+ </para>
+
+ <para>
+ No separate policy exists for <command>MERGE</command>. Instead, the policies
+ defined for <command>SELECT</command>, <command>INSERT</command>,
+ <command>UPDATE</command>, and <command>DELETE</command> are applied
+ while executing <command>MERGE</command>, depending on the actions that are
+ performed.
+ </para>
+
+ <para>
+ Additional discussion and practical examples can be found
+ in <xref linkend="ddl-rowsecurity"/>.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE POLICY</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterpolicy"/></member>
+ <member><xref linkend="sql-droppolicy"/></member>
+ <member><xref linkend="sql-altertable"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_procedure.sgml b/doc/src/sgml/ref/create_procedure.sgml
new file mode 100644
index 0000000..03a14c8
--- /dev/null
+++ b/doc/src/sgml/ref/create_procedure.sgml
@@ -0,0 +1,411 @@
+<!--
+doc/src/sgml/ref/create_procedure.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createprocedure">
+ <indexterm zone="sql-createprocedure">
+ <primary>CREATE PROCEDURE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE PROCEDURE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE PROCEDURE</refname>
+ <refpurpose>define a new procedure</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] PROCEDURE
+ <replaceable class="parameter">name</replaceable> ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [ { DEFAULT | = } <replaceable class="parameter">default_expr</replaceable> ] [, ...] ] )
+ { LANGUAGE <replaceable class="parameter">lang_name</replaceable>
+ | TRANSFORM { FOR TYPE <replaceable class="parameter">type_name</replaceable> } [, ... ]
+ | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
+ | SET <replaceable class="parameter">configuration_parameter</replaceable> { TO <replaceable class="parameter">value</replaceable> | = <replaceable class="parameter">value</replaceable> | FROM CURRENT }
+ | AS '<replaceable class="parameter">definition</replaceable>'
+ | AS '<replaceable class="parameter">obj_file</replaceable>', '<replaceable class="parameter">link_symbol</replaceable>'
+ | <replaceable class="parameter">sql_body</replaceable>
+ } ...
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createprocedure-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE PROCEDURE</command> defines a new procedure.
+ <command>CREATE OR REPLACE PROCEDURE</command> will either create a
+ new procedure, or replace an existing definition.
+ To be able to define a procedure, the user must have the
+ <literal>USAGE</literal> privilege on the language.
+ </para>
+
+ <para>
+ If a schema name is included, then the procedure is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The name of the new procedure must not match any existing procedure or function
+ with the same input argument types in the same schema. However,
+ procedures and functions of different argument types can share a name (this is
+ called <firstterm>overloading</firstterm>).
+ </para>
+
+ <para>
+ To replace the current definition of an existing procedure, use
+ <command>CREATE OR REPLACE PROCEDURE</command>. It is not possible
+ to change the name or argument types of a procedure this way (if you
+ tried, you would actually be creating a new, distinct procedure).
+ </para>
+
+ <para>
+ When <command>CREATE OR REPLACE PROCEDURE</command> is used to replace an
+ existing procedure, the ownership and permissions of the procedure
+ do not change. All other procedure properties are assigned the
+ values specified or implied in the command. You must own the procedure
+ to replace it (this includes being a member of the owning role).
+ </para>
+
+ <para>
+ The user that creates the procedure becomes the owner of the procedure.
+ </para>
+
+ <para>
+ To be able to create a procedure, you must have <literal>USAGE</literal>
+ privilege on the argument types.
+ </para>
+
+ <para>
+ Refer to <xref linkend="xproc"/> for further information on writing
+ procedures.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the procedure to create.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>. If omitted,
+ the default is <literal>IN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type(s) of the procedure's arguments (optionally
+ schema-qualified), if any. The argument types can be base, composite,
+ or domain types, or can reference the type of a table column.
+ </para>
+ <para>
+ Depending on the implementation language it might also be allowed
+ to specify <quote>pseudo-types</quote> such as <type>cstring</type>.
+ Pseudo-types indicate that the actual argument type is either
+ incompletely specified, or outside the set of ordinary SQL data types.
+ </para>
+ <para>
+ The type of a column is referenced by writing
+ <literal><replaceable
+ class="parameter">table_name</replaceable>.<replaceable
+ class="parameter">column_name</replaceable>%TYPE</literal>.
+ Using this feature can sometimes help make a procedure independent of
+ changes to the definition of a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">default_expr</replaceable></term>
+
+ <listitem>
+ <para>
+ An expression to be used as default value if the parameter is
+ not specified. The expression has to be coercible to the
+ argument type of the parameter.
+ All input parameters following a
+ parameter with a default value must have default values as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">lang_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the language that the procedure is implemented in.
+ It can be <literal>sql</literal>, <literal>c</literal>,
+ <literal>internal</literal>, or the name of a user-defined
+ procedural language, e.g., <literal>plpgsql</literal>. The default is
+ <literal>sql</literal> if <replaceable
+ class="parameter">sql_body</replaceable> is specified. Enclosing the
+ name in single quotes is deprecated and requires matching case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRANSFORM { FOR TYPE <replaceable class="parameter">type_name</replaceable> } [, ... ] }</literal></term>
+
+ <listitem>
+ <para>
+ Lists which transforms a call to the procedure should apply. Transforms
+ convert between SQL types and language-specific data types;
+ see <xref linkend="sql-createtransform"/>. Procedural language
+ implementations usually have hardcoded knowledge of the built-in types,
+ so those don't need to be listed here. If a procedural language
+ implementation does not know how to handle a type and no transform is
+ supplied, it will fall back to a default behavior for converting data
+ types, but this depends on the implementation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><optional>EXTERNAL</optional> SECURITY INVOKER</literal></term>
+ <term><literal><optional>EXTERNAL</optional> SECURITY DEFINER</literal></term>
+
+ <listitem>
+ <para><literal>SECURITY INVOKER</literal> indicates that the procedure
+ is to be executed with the privileges of the user that calls it.
+ That is the default. <literal>SECURITY DEFINER</literal>
+ specifies that the procedure is to be executed with the
+ privileges of the user that owns it.
+ </para>
+
+ <para>
+ The key word <literal>EXTERNAL</literal> is allowed for SQL
+ conformance, but it is optional since, unlike in SQL, this feature
+ applies to all procedures not only external ones.
+ </para>
+
+ <para>
+ A <literal>SECURITY DEFINER</literal> procedure cannot execute
+ transaction control statements (for example, <command>COMMIT</command>
+ and <command>ROLLBACK</command>, depending on the language).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>configuration_parameter</replaceable></term>
+ <term><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>SET</literal> clause causes the specified configuration
+ parameter to be set to the specified value when the procedure is
+ entered, and then restored to its prior value when the procedure exits.
+ <literal>SET FROM CURRENT</literal> saves the value of the parameter that
+ is current when <command>CREATE PROCEDURE</command> is executed as the value
+ to be applied when the procedure is entered.
+ </para>
+
+ <para>
+ If a <literal>SET</literal> clause is attached to a procedure, then
+ the effects of a <command>SET LOCAL</command> command executed inside the
+ procedure for the same variable are restricted to the procedure: the
+ configuration parameter's prior value is still restored at procedure exit.
+ However, an ordinary
+ <command>SET</command> command (without <literal>LOCAL</literal>) overrides the
+ <literal>SET</literal> clause, much as it would do for a previous <command>SET
+ LOCAL</command> command: the effects of such a command will persist after
+ procedure exit, unless the current transaction is rolled back.
+ </para>
+
+ <para>
+ If a <literal>SET</literal> clause is attached to a procedure, then
+ that procedure cannot execute transaction control statements (for
+ example, <command>COMMIT</command> and <command>ROLLBACK</command>,
+ depending on the language).
+ </para>
+
+ <para>
+ See <xref linkend="sql-set"/> and
+ <xref linkend="runtime-config"/>
+ for more information about allowed parameter names and values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">definition</replaceable></term>
+
+ <listitem>
+ <para>
+ A string constant defining the procedure; the meaning depends on the
+ language. It can be an internal procedure name, the path to an
+ object file, an SQL command, or text in a procedural language.
+ </para>
+
+ <para>
+ It is often helpful to use dollar quoting (see <xref
+ linkend="sql-syntax-dollar-quoting"/>) to write the procedure definition
+ string, rather than the normal single quote syntax. Without dollar
+ quoting, any single quotes or backslashes in the procedure definition must
+ be escaped by doubling them.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable class="parameter">obj_file</replaceable>, <replaceable class="parameter">link_symbol</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ This form of the <literal>AS</literal> clause is used for
+ dynamically loadable C language procedures when the procedure name
+ in the C language source code is not the same as the name of
+ the SQL procedure. The string <replaceable
+ class="parameter">obj_file</replaceable> is the name of the shared
+ library file containing the compiled C procedure, and is interpreted
+ as for the <link linkend="sql-load"><command>LOAD</command></link> command. The string
+ <replaceable class="parameter">link_symbol</replaceable> is the
+ procedure's link symbol, that is, the name of the procedure in the C
+ language source code. If the link symbol is omitted, it is assumed
+ to be the same as the name of the SQL procedure being defined.
+ </para>
+
+ <para>
+ When repeated <command>CREATE PROCEDURE</command> calls refer to
+ the same object file, the file is only loaded once per session.
+ To unload and
+ reload the file (perhaps during development), start a new session.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sql_body</replaceable></term>
+
+ <listitem>
+ <para>
+ The body of a <literal>LANGUAGE SQL</literal> procedure. This should
+ be a block
+<programlisting>
+BEGIN ATOMIC
+ <replaceable>statement</replaceable>;
+ <replaceable>statement</replaceable>;
+ ...
+ <replaceable>statement</replaceable>;
+END
+</programlisting>
+ </para>
+
+ <para>
+ This is similar to writing the text of the procedure body as a string
+ constant (see <replaceable>definition</replaceable> above), but there
+ are some differences: This form only works for <literal>LANGUAGE
+ SQL</literal>, the string constant form works for all languages. This
+ form is parsed at procedure definition time, the string constant form is
+ parsed at execution time; therefore this form cannot support
+ polymorphic argument types and other constructs that are not resolvable
+ at procedure definition time. This form tracks dependencies between the
+ procedure and objects used in the procedure body, so <literal>DROP
+ ... CASCADE</literal> will work correctly, whereas the form using
+ string literals may leave dangling procedures. Finally, this form is
+ more compatible with the SQL standard and other SQL implementations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createprocedure-notes">
+ <title>Notes</title>
+
+ <para>
+ See <xref linkend="sql-createfunction"/> for more details on function
+ creation that also apply to procedures.
+ </para>
+
+ <para>
+ Use <xref linkend="sql-call"/> to execute a procedure.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createprocedure-examples">
+ <title>Examples</title>
+
+ <para>
+<programlisting>
+CREATE PROCEDURE insert_data(a integer, b integer)
+LANGUAGE SQL
+AS $$
+INSERT INTO tbl VALUES (a);
+INSERT INTO tbl VALUES (b);
+$$;
+</programlisting>
+ or
+<programlisting>
+CREATE PROCEDURE insert_data(a integer, b integer)
+LANGUAGE SQL
+BEGIN ATOMIC
+ INSERT INTO tbl VALUES (a);
+ INSERT INTO tbl VALUES (b);
+END;
+</programlisting>
+ and call like this:
+<programlisting>
+CALL insert_data(1, 2);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-createprocedure-compat">
+ <title>Compatibility</title>
+
+ <para>
+ A <command>CREATE PROCEDURE</command> command is defined in the SQL
+ standard. The <productname>PostgreSQL</productname> implementation can be
+ used in a compatible way but has many extensions. For details see also
+ <xref linkend="sql-createfunction"/>.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterprocedure"/></member>
+ <member><xref linkend="sql-dropprocedure"/></member>
+ <member><xref linkend="sql-call"/></member>
+ <member><xref linkend="sql-createfunction"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml
new file mode 100644
index 0000000..7ab7e77
--- /dev/null
+++ b/doc/src/sgml/ref/create_publication.sgml
@@ -0,0 +1,409 @@
+<!--
+doc/src/sgml/ref/create_publication.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createpublication">
+ <indexterm zone="sql-createpublication">
+ <primary>CREATE PUBLICATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE PUBLICATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE PUBLICATION</refname>
+ <refpurpose>define a new publication</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
+ [ FOR ALL TABLES
+ | FOR <replaceable class="parameter">publication_object</replaceable> [, ... ] ]
+ [ WITH ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+
+<phrase>where <replaceable class="parameter">publication_object</replaceable> is one of:</phrase>
+
+ TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] [ WHERE ( <replaceable class="parameter">expression</replaceable> ) ] [, ... ]
+ TABLES IN SCHEMA { <replaceable class="parameter">schema_name</replaceable> | CURRENT_SCHEMA } [, ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE PUBLICATION</command> adds a new publication
+ into the current database. The publication name must be distinct from
+ the name of any existing publication in the current database.
+ </para>
+
+ <para>
+ A publication is essentially a group of tables whose data changes are
+ intended to be replicated through logical replication. See
+ <xref linkend="logical-replication-publication"/> for details about how
+ publications fit into the logical replication setup.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the new publication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FOR TABLE</literal></term>
+ <listitem>
+ <para>
+ Specifies a list of tables to add to the publication. If
+ <literal>ONLY</literal> is specified before the table name, only
+ that table is added to the publication. If <literal>ONLY</literal> is not
+ specified, the table and all its descendant tables (if any) are added.
+ Optionally, <literal>*</literal> can be specified after the table name to
+ explicitly indicate that descendant tables are included.
+ This does not apply to a partitioned table, however. The partitions of
+ a partitioned table are always implicitly considered part of the
+ publication, so they are never explicitly added to the publication.
+ </para>
+
+ <para>
+ If the optional <literal>WHERE</literal> clause is specified, it defines a
+ <firstterm>row filter</firstterm> expression. Rows for
+ which the <replaceable class="parameter">expression</replaceable>
+ evaluates to false or null will not be published. Note that parentheses
+ are required around the expression. It has no effect on
+ <literal>TRUNCATE</literal> commands.
+ </para>
+
+ <para>
+ When a column list is specified, only the named columns are replicated.
+ If no column list is specified, all columns of the table are replicated
+ through this publication, including any columns added later. It has no
+ effect on <literal>TRUNCATE</literal> commands. See
+ <xref linkend="logical-replication-col-lists"/> for details about column
+ lists.
+ </para>
+
+ <para>
+ Only persistent base tables and partitioned tables can be part of a
+ publication. Temporary tables, unlogged tables, foreign tables,
+ materialized views, and regular views cannot be part of a publication.
+ </para>
+
+ <para>
+ Specifying a column list when the publication also publishes
+ <literal>FOR TABLES IN SCHEMA</literal> is not supported.
+ </para>
+
+ <para>
+ When a partitioned table is added to a publication, all of its existing
+ and future partitions are implicitly considered to be part of the
+ publication. So, even operations that are performed directly on a
+ partition are also published via publications that its ancestors are
+ part of.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FOR ALL TABLES</literal></term>
+ <listitem>
+ <para>
+ Marks the publication as one that replicates changes for all tables in
+ the database, including tables created in the future.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FOR TABLES IN SCHEMA</literal></term>
+ <listitem>
+ <para>
+ Marks the publication as one that replicates changes for all tables in
+ the specified list of schemas, including tables created in the future.
+ </para>
+
+ <para>
+ Specifying a schema when the publication also publishes a table with a
+ column list is not supported.
+ </para>
+
+ <para>
+ Only persistent base tables and partitioned tables present in the schema
+ will be included as part of the publication. Temporary tables, unlogged
+ tables, foreign tables, materialized views, and regular views from the
+ schema will not be part of the publication.
+ </para>
+
+ <para>
+ When a partitioned table is published via schema level publication, all
+ of its existing and future partitions are implicitly considered to be part of the
+ publication, regardless of whether they are from the publication schema or not.
+ So, even operations that are performed directly on a
+ partition are also published via publications that its ancestors are
+ part of.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH ( <replaceable class="parameter">publication_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies optional parameters for a publication. The
+ following parameters are supported:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>publish</literal> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ This parameter determines which DML operations will be published by
+ the new publication to the subscribers. The value is
+ comma-separated list of operations. The allowed operations are
+ <literal>insert</literal>, <literal>update</literal>,
+ <literal>delete</literal>, and <literal>truncate</literal>.
+ The default is to publish all actions,
+ and so the default value for this option is
+ <literal>'insert, update, delete, truncate'</literal>.
+ </para>
+ <para>
+ This parameter only affects DML operations. In particular, the initial
+ data synchronization (see <xref linkend="logical-replication-snapshot"/>)
+ for logical replication does not take this parameter into account when
+ copying existing table data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>publish_via_partition_root</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This parameter determines whether changes in a partitioned table (or
+ on its partitions) contained in the publication will be published
+ using the identity and schema of the partitioned table rather than
+ that of the individual partitions that are actually changed; the
+ latter is the default. Enabling this allows the changes to be
+ replicated into a non-partitioned table or a partitioned table
+ consisting of a different set of partitions.
+ </para>
+
+ <para>
+ This parameter also affects how row filters and column lists are
+ chosen for partitions; see below for details.
+ </para>
+
+ <para>
+ If this is enabled, <literal>TRUNCATE</literal> operations performed
+ directly on partitions are not replicated.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If <literal>FOR TABLE</literal>, <literal>FOR ALL TABLES</literal> or
+ <literal>FOR TABLES IN SCHEMA</literal> are not specified, then the
+ publication starts out with an empty set of tables. That is useful if
+ tables or schemas are to be added later.
+ </para>
+
+ <para>
+ The creation of a publication does not start replication. It only defines
+ a grouping and filtering logic for future subscribers.
+ </para>
+
+ <para>
+ To create a publication, the invoking user must have the
+ <literal>CREATE</literal> privilege for the current database.
+ (Of course, superusers bypass this check.)
+ </para>
+
+ <para>
+ To add a table to a publication, the invoking user must have ownership
+ rights on the table. The <command>FOR ALL TABLES</command> and
+ <command>FOR TABLES IN SCHEMA</command> clauses require the invoking
+ user to be a superuser.
+ </para>
+
+ <para>
+ The tables added to a publication that publishes <command>UPDATE</command>
+ and/or <command>DELETE</command> operations must have
+ <literal>REPLICA IDENTITY</literal> defined. Otherwise those operations will be
+ disallowed on those tables.
+ </para>
+
+ <para>
+ Any column list must include the <literal>REPLICA IDENTITY</literal> columns
+ in order for <command>UPDATE</command> or <command>DELETE</command>
+ operations to be published. There are no column list restrictions if the
+ publication publishes only <command>INSERT</command> operations.
+ </para>
+
+ <para>
+ A row filter expression (i.e., the <literal>WHERE</literal> clause) must contain only
+ columns that are covered by the <literal>REPLICA IDENTITY</literal>, in
+ order for <command>UPDATE</command> and <command>DELETE</command> operations
+ to be published. For publication of <command>INSERT</command> operations,
+ any column may be used in the <literal>WHERE</literal> expression. The
+ row filter allows simple expressions that don't have
+ user-defined functions, user-defined operators, user-defined types,
+ user-defined collations, non-immutable built-in functions, or references to
+ system columns.
+ </para>
+
+ <para>
+ The row filter on a table becomes redundant if
+ <literal>FOR TABLES IN SCHEMA</literal> is specified and the table
+ belongs to the referred schema.
+ </para>
+
+ <para>
+ For published partitioned tables, the row filter for each
+ partition is taken from the published partitioned table if the
+ publication parameter <literal>publish_via_partition_root</literal> is true,
+ or from the partition itself if it is false (the default).
+ See <xref linkend="logical-replication-row-filter"/> for details about row
+ filters.
+ Similarly, for published partitioned tables, the column list for each
+ partition is taken from the published partitioned table if the
+ publication parameter <literal>publish_via_partition_root</literal> is true,
+ or from the partition itself if it is false.
+ </para>
+
+ <para>
+ For an <command>INSERT ... ON CONFLICT</command> command, the publication will
+ publish the operation that results from the command. Depending
+ on the outcome, it may be published as either <command>INSERT</command> or
+ <command>UPDATE</command>, or it may not be published at all.
+ </para>
+
+ <para>
+ For a <command>MERGE</command> command, the publication will publish an
+ <command>INSERT</command>, <command>UPDATE</command>, or <command>DELETE</command>
+ for each row inserted, updated, or deleted.
+ </para>
+
+ <para>
+ <command>ATTACH</command>ing a table into a partition tree whose root is
+ published using a publication with <literal>publish_via_partition_root</literal>
+ set to <literal>true</literal> does not result in the table's existing contents
+ being replicated.
+ </para>
+
+ <para>
+ <command>COPY ... FROM</command> commands are published
+ as <command>INSERT</command> operations.
+ </para>
+
+ <para>
+ <acronym>DDL</acronym> operations are not published.
+ </para>
+
+ <para>
+ The <literal>WHERE</literal> clause expression is executed with the role used
+ for the replication connection.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a publication that publishes all changes in two tables:
+<programlisting>
+CREATE PUBLICATION mypublication FOR TABLE users, departments;
+</programlisting>
+ </para>
+
+ <para>
+ Create a publication that publishes all changes from active departments:
+<programlisting>
+CREATE PUBLICATION active_departments FOR TABLE departments WHERE (active IS TRUE);
+</programlisting>
+ </para>
+
+ <para>
+ Create a publication that publishes all changes in all tables:
+<programlisting>
+CREATE PUBLICATION alltables FOR ALL TABLES;
+</programlisting>
+ </para>
+
+ <para>
+ Create a publication that only publishes <command>INSERT</command>
+ operations in one table:
+<programlisting>
+CREATE PUBLICATION insert_only FOR TABLE mydata
+ WITH (publish = 'insert');
+</programlisting>
+ </para>
+
+ <para>
+ Create a publication that publishes all changes for tables
+ <structname>users</structname>, <structname>departments</structname> and
+ all changes for all the tables present in the schema
+ <structname>production</structname>:
+<programlisting>
+CREATE PUBLICATION production_publication FOR TABLE users, departments, TABLES IN SCHEMA production;
+</programlisting>
+ </para>
+
+ <para>
+ Create a publication that publishes all changes for all the tables present in
+ the schemas <structname>marketing</structname> and
+ <structname>sales</structname>:
+<programlisting>
+CREATE PUBLICATION sales_publication FOR TABLES IN SCHEMA marketing, sales;
+</programlisting></para>
+
+ <para>
+ Create a publication that publishes all changes for table <structname>users</structname>,
+ but replicates only columns <structname>user_id</structname> and
+ <structname>firstname</structname>:
+<programlisting>
+CREATE PUBLICATION users_filtered FOR TABLE users (user_id, firstname);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE PUBLICATION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterpublication"/></member>
+ <member><xref linkend="sql-droppublication"/></member>
+ <member><xref linkend="sql-createsubscription"/></member>
+ <member><xref linkend="sql-altersubscription"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml
new file mode 100644
index 0000000..89df6db
--- /dev/null
+++ b/doc/src/sgml/ref/create_role.sgml
@@ -0,0 +1,504 @@
+<!--
+doc/src/sgml/ref/create_role.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createrole">
+ <indexterm zone="sql-createrole">
+ <primary>CREATE ROLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE ROLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE ROLE</refname>
+ <refpurpose>define a new database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE ROLE <replaceable class="parameter">name</replaceable> [ [ WITH ] <replaceable class="parameter">option</replaceable> [ ... ] ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <replaceable class="parameter">connlimit</replaceable>
+ | [ ENCRYPTED ] PASSWORD '<replaceable class="parameter">password</replaceable>' | PASSWORD NULL
+ | VALID UNTIL '<replaceable class="parameter">timestamp</replaceable>'
+ | IN ROLE <replaceable class="parameter">role_name</replaceable> [, ...]
+ | IN GROUP <replaceable class="parameter">role_name</replaceable> [, ...]
+ | ROLE <replaceable class="parameter">role_name</replaceable> [, ...]
+ | ADMIN <replaceable class="parameter">role_name</replaceable> [, ...]
+ | USER <replaceable class="parameter">role_name</replaceable> [, ...]
+ | SYSID <replaceable class="parameter">uid</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+<!--
+CAUTION: remember to keep create_user.sgml and create_group.sgml
+in sync when changing the above synopsis!
+-->
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE ROLE</command> adds a new role to a
+ <productname>PostgreSQL</productname> database cluster. A role is
+ an entity that can own database objects and have database privileges;
+ a role can be considered a <quote>user</quote>, a <quote>group</quote>, or both
+ depending on how it is used. Refer to
+ <xref linkend="user-manag"/> and <xref
+ linkend="client-authentication"/> for information about managing
+ users and authentication. You must have <literal>CREATEROLE</literal>
+ privilege or be a database superuser to use this command.
+ </para>
+
+ <para>
+ Note that roles are defined at the database cluster
+ level, and so are valid in all databases in the cluster.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the new role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SUPERUSER</literal></term>
+ <term><literal>NOSUPERUSER</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether the new role is a <quote>superuser</quote>,
+ who can override all access restrictions within the database.
+ Superuser status is dangerous and should be used only when really
+ needed. You must yourself be a superuser to create a new superuser.
+ If not specified,
+ <literal>NOSUPERUSER</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATEDB</literal></term>
+ <term><literal>NOCREATEDB</literal></term>
+ <listitem>
+ <para>
+ These clauses define a role's ability to create databases. If
+ <literal>CREATEDB</literal> is specified, the role being
+ defined will be allowed to create new databases. Specifying
+ <literal>NOCREATEDB</literal> will deny a role the ability to
+ create databases. If not specified,
+ <literal>NOCREATEDB</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CREATEROLE</literal></term>
+ <term><literal>NOCREATEROLE</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether a role will be permitted to
+ create, alter, drop, comment on, change the security label for,
+ and grant or revoke membership in other roles.
+ See <xref linkend='role-creation' /> for more details about what
+ capabilities are conferred by this privilege.
+ If not specified, <literal>NOCREATEROLE</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INHERIT</literal></term>
+ <term><literal>NOINHERIT</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether a role <quote>inherits</quote> the
+ privileges of roles it is a member of.
+ A role with the <literal>INHERIT</literal> attribute can automatically
+ use whatever database privileges have been granted to all roles
+ it is directly or indirectly a member of.
+ Without <literal>INHERIT</literal>, membership in another role
+ only grants the ability to <command>SET ROLE</command> to that other role;
+ the privileges of the other role are only available after having
+ done so.
+ If not specified,
+ <literal>INHERIT</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LOGIN</literal></term>
+ <term><literal>NOLOGIN</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether a role is allowed to log in;
+ that is, whether the role can be given as the initial session
+ authorization name during client connection. A role having
+ the <literal>LOGIN</literal> attribute can be thought of as a user.
+ Roles without this attribute are useful for managing database
+ privileges, but are not users in the usual sense of the word.
+ If not specified,
+ <literal>NOLOGIN</literal> is the default, except when
+ <command>CREATE ROLE</command> is invoked through its alternative spelling
+ <link linkend="sql-createuser"><command>CREATE USER</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REPLICATION</literal></term>
+ <term><literal>NOREPLICATION</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether a role is a replication role. A role
+ must have this attribute (or be a superuser) in order to be able to
+ connect to the server in replication mode (physical or logical
+ replication) and in order to be able to create or drop replication
+ slots.
+ A role having the <literal>REPLICATION</literal> attribute is a very
+ highly privileged role, and should only be used on roles actually
+ used for replication. If not specified,
+ <literal>NOREPLICATION</literal> is the default.
+ You must be a superuser to create a new role having the
+ <literal>REPLICATION</literal> attribute.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BYPASSRLS</literal></term>
+ <term><literal>NOBYPASSRLS</literal></term>
+ <listitem>
+ <para>
+ These clauses determine whether a role bypasses every row-level
+ security (RLS) policy. <literal>NOBYPASSRLS</literal> is the default.
+ You must be a superuser to create a new role having
+ the <literal>BYPASSRLS</literal> attribute.
+ </para>
+
+ <para>
+ Note that pg_dump will set <literal>row_security</literal> to
+ <literal>OFF</literal> by default, to ensure all contents of a table are
+ dumped out. If the user running pg_dump does not have appropriate
+ permissions, an error will be returned. However, superusers and the
+ owner of the table being dumped always bypass RLS.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONNECTION LIMIT</literal> <replaceable class="parameter">connlimit</replaceable></term>
+ <listitem>
+ <para>
+ If role can log in, this specifies how many concurrent connections
+ the role can make. -1 (the default) means no limit. Note that only
+ normal connections are counted towards this limit. Neither prepared
+ transactions nor background worker connections are counted towards
+ this limit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>[ <literal>ENCRYPTED</literal> ] <literal>PASSWORD</literal> '<replaceable class="parameter">password</replaceable>'</term>
+ <term><literal>PASSWORD NULL</literal></term>
+ <listitem>
+ <para>
+ Sets the role's password. (A password is only of use for
+ roles having the <literal>LOGIN</literal> attribute, but you
+ can nonetheless define one for roles without it.) If you do
+ not plan to use password authentication you can omit this
+ option. If no password is specified, the password will be set
+ to null and password authentication will always fail for that
+ user. A null password can optionally be written explicitly as
+ <literal>PASSWORD NULL</literal>.
+ </para>
+ <note>
+ <para>
+ Specifying an empty string will also set the password to null,
+ but that was not the case before <productname>PostgreSQL</productname>
+ version 10. In earlier versions, an empty string could be used,
+ or not, depending on the authentication method and the exact
+ version, and libpq would refuse to use it in any case.
+ To avoid the ambiguity, specifying an empty string should be
+ avoided.
+ </para>
+ </note>
+ <para>
+ The password is always stored encrypted in the system catalogs. The
+ <literal>ENCRYPTED</literal> keyword has no effect, but is accepted for
+ backwards compatibility. The method of encryption is determined
+ by the configuration parameter <xref linkend="guc-password-encryption"/>.
+ If the presented password string is already in MD5-encrypted or
+ SCRAM-encrypted format, then it is stored as-is regardless of
+ <varname>password_encryption</varname> (since the system cannot decrypt
+ the specified encrypted password string, to encrypt it in a
+ different format). This allows reloading of encrypted passwords
+ during dump/restore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VALID UNTIL</literal> '<replaceable class="parameter">timestamp</replaceable>'</term>
+ <listitem>
+ <para>
+ The <literal>VALID UNTIL</literal> clause sets a date and
+ time after which the role's password is no longer valid. If
+ this clause is omitted the password will be valid for all time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IN ROLE</literal> <replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>IN ROLE</literal> clause lists one or more existing
+ roles to which the new role will be immediately added as a new
+ member. (Note that there is no option to add the new role as an
+ administrator; use a separate <command>GRANT</command> command to do that.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IN GROUP</literal> <replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para><literal>IN GROUP</literal> is an obsolete spelling of
+ <literal>IN ROLE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ROLE</literal> <replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>ROLE</literal> clause lists one or more existing
+ roles which are automatically added as members of the new role.
+ (This in effect makes the new role a <quote>group</quote>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ADMIN</literal> <replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>ADMIN</literal> clause is like <literal>ROLE</literal>,
+ but the named roles are added to the new role <literal>WITH ADMIN
+ OPTION</literal>, giving them the right to grant membership in this role
+ to others.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USER</literal> <replaceable class="parameter">role_name</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>USER</literal> clause is an obsolete spelling of
+ the <literal>ROLE</literal> clause.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SYSID</literal> <replaceable class="parameter">uid</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>SYSID</literal> clause is ignored, but is accepted
+ for backwards compatibility.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-alterrole"><command>ALTER ROLE</command></link> to
+ change the attributes of a role, and <link linkend="sql-droprole"><command>DROP ROLE</command></link>
+ to remove a role. All the attributes
+ specified by <command>CREATE ROLE</command> can be modified by later
+ <command>ALTER ROLE</command> commands.
+ </para>
+
+ <para>
+ The preferred way to add and remove members of roles that are being
+ used as groups is to use
+ <link linkend="sql-grant"><command>GRANT</command></link> and
+ <link linkend="sql-revoke"><command>REVOKE</command></link>.
+ </para>
+
+ <para>
+ The <literal>VALID UNTIL</literal> clause defines an expiration time for a
+ password only, not for the role per se. In
+ particular, the expiration time is not enforced when logging in using
+ a non-password-based authentication method.
+ </para>
+
+ <para>
+ The <literal>INHERIT</literal> attribute governs inheritance of grantable
+ privileges (that is, access privileges for database objects and role
+ memberships). It does not apply to the special role attributes set by
+ <command>CREATE ROLE</command> and <command>ALTER ROLE</command>. For example, being
+ a member of a role with <literal>CREATEDB</literal> privilege does not immediately
+ grant the ability to create databases, even if <literal>INHERIT</literal> is set;
+ it would be necessary to become that role via
+ <link linkend="sql-set-role"><command>SET ROLE</command></link> before
+ creating a database.
+ </para>
+
+ <para>
+ The <literal>INHERIT</literal> attribute is the default for reasons of backwards
+ compatibility: in prior releases of <productname>PostgreSQL</productname>,
+ users always had access to all privileges of groups they were members of.
+ However, <literal>NOINHERIT</literal> provides a closer match to the semantics
+ specified in the SQL standard.
+ </para>
+
+ <para>
+ Be careful with the <literal>CREATEROLE</literal> privilege. There is no concept of
+ inheritance for the privileges of a <literal>CREATEROLE</literal>-role. That
+ means that even if a role does not have a certain privilege but is allowed
+ to create other roles, it can easily create another role with different
+ privileges than its own (except for creating roles with superuser
+ privileges). For example, if the role <quote>user</quote> has the
+ <literal>CREATEROLE</literal> privilege but not the <literal>CREATEDB</literal> privilege,
+ nonetheless it can create a new role with the <literal>CREATEDB</literal>
+ privilege. Therefore, regard roles that have the <literal>CREATEROLE</literal>
+ privilege as almost-superuser-roles.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> includes a program <xref
+ linkend="app-createuser"/> that has
+ the same functionality as <command>CREATE ROLE</command> (in fact,
+ it calls this command) but can be run from the command shell.
+ </para>
+
+ <para>
+ The <literal>CONNECTION LIMIT</literal> option is only enforced approximately;
+ if two new sessions start at about the same time when just one
+ connection <quote>slot</quote> remains for the role, it is possible that
+ both will fail. Also, the limit is never enforced for superusers.
+ </para>
+
+ <para>
+ Caution must be exercised when specifying an unencrypted password
+ with this command. The password will be transmitted to the server
+ in cleartext, and it might also be logged in the client's command
+ history or the server log. The command <xref
+ linkend="app-createuser"/>, however, transmits
+ the password encrypted. Also, <xref linkend="app-psql"/>
+ contains a command
+ <command>\password</command> that can be used to safely change the
+ password later.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a role that can log in, but don't give it a password:
+<programlisting>
+CREATE ROLE jonathan LOGIN;
+</programlisting>
+ </para>
+
+ <para>
+ Create a role with a password:
+<programlisting>
+CREATE USER davide WITH PASSWORD 'jw8s0F4';
+</programlisting>
+ (<command>CREATE USER</command> is the same as <command>CREATE ROLE</command> except
+ that it implies <literal>LOGIN</literal>.)
+ </para>
+
+ <para>
+ Create a role with a password that is valid until the end of 2004.
+ After one second has ticked in 2005, the password is no longer
+ valid.
+
+<programlisting>
+CREATE ROLE miriam WITH LOGIN PASSWORD 'jw8s0F4' VALID UNTIL '2005-01-01';
+</programlisting>
+ </para>
+
+ <para>
+ Create a role that can create databases and manage roles:
+<programlisting>
+CREATE ROLE admin WITH CREATEDB CREATEROLE;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>CREATE ROLE</command> statement is in the SQL standard,
+ but the standard only requires the syntax
+<synopsis>
+CREATE ROLE <replaceable class="parameter">name</replaceable> [ WITH ADMIN <replaceable class="parameter">role_name</replaceable> ]
+</synopsis>
+ Multiple initial administrators, and all the other options of
+ <command>CREATE ROLE</command>, are
+ <productname>PostgreSQL</productname> extensions.
+ </para>
+
+ <para>
+ The SQL standard defines the concepts of users and roles, but it
+ regards them as distinct concepts and leaves all commands defining
+ users to be specified by each database implementation. In
+ <productname>PostgreSQL</productname> we have chosen to unify
+ users and roles into a single kind of entity. Roles therefore
+ have many more optional attributes than they do in the standard.
+ </para>
+
+ <para>
+ The behavior specified by the SQL standard is most closely approximated
+ by giving users the <literal>NOINHERIT</literal> attribute, while roles are
+ given the <literal>INHERIT</literal> attribute.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-set-role"/></member>
+ <member><xref linkend="sql-alterrole"/></member>
+ <member><xref linkend="sql-droprole"/></member>
+ <member><xref linkend="sql-grant"/></member>
+ <member><xref linkend="sql-revoke"/></member>
+ <member><xref linkend="app-createuser"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml
new file mode 100644
index 0000000..dbf4c93
--- /dev/null
+++ b/doc/src/sgml/ref/create_rule.sgml
@@ -0,0 +1,305 @@
+<!--
+doc/src/sgml/ref/create_rule.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createrule">
+ <indexterm zone="sql-createrule">
+ <primary>CREATE RULE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE RULE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE RULE</refname>
+ <refpurpose>define a new rewrite rule</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable class="parameter">event</replaceable>
+ TO <replaceable class="parameter">table_name</replaceable> [ WHERE <replaceable class="parameter">condition</replaceable> ]
+ DO [ ALSO | INSTEAD ] { NOTHING | <replaceable class="parameter">command</replaceable> | ( <replaceable class="parameter">command</replaceable> ; <replaceable class="parameter">command</replaceable> ... ) }
+
+<phrase>where <replaceable class="parameter">event</replaceable> can be one of:</phrase>
+
+ SELECT | INSERT | UPDATE | DELETE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE RULE</command> defines a new rule applying to a specified
+ table or view.
+ <command>CREATE OR REPLACE RULE</command> will either create a
+ new rule, or replace an existing rule of the same name for the same
+ table.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> rule system allows one to
+ define an alternative action to be performed on insertions, updates,
+ or deletions in database tables. Roughly speaking, a rule causes
+ additional commands to be executed when a given command on a given
+ table is executed. Alternatively, an <literal>INSTEAD</literal>
+ rule can replace a given command by another, or cause a command
+ not to be executed at all. Rules are used to implement SQL
+ views as well. It is important to realize that a rule is really
+ a command transformation mechanism, or command macro. The
+ transformation happens before the execution of the command starts.
+ If you actually want an operation that fires independently for each
+ physical row, you probably want to use a trigger, not a rule.
+ More information about the rules system is in <xref linkend="rules"/>.
+ </para>
+
+ <para>
+ Presently, <literal>ON SELECT</literal> rules must be unconditional
+ <literal>INSTEAD</literal> rules and must have actions that consist
+ of a single <command>SELECT</command> command. Thus, an
+ <literal>ON SELECT</literal> rule effectively turns the table into
+ a view, whose visible contents are the rows returned by the rule's
+ <command>SELECT</command> command rather than whatever had been
+ stored in the table (if anything). It is considered better style
+ to write a <command>CREATE VIEW</command> command than to create a
+ real table and define an <literal>ON SELECT</literal> rule for it.
+ </para>
+
+ <para>
+ You can create the illusion of an updatable view by defining
+ <literal>ON INSERT</literal>, <literal>ON UPDATE</literal>, and
+ <literal>ON DELETE</literal> rules (or any subset of those that's
+ sufficient for your purposes) to replace update actions on the view
+ with appropriate updates on other tables. If you want to support
+ <command>INSERT RETURNING</command> and so on, then be sure to put a suitable
+ <literal>RETURNING</literal> clause into each of these rules.
+ </para>
+
+ <para>
+ There is a catch if you try to use conditional rules for complex view
+ updates: there <emphasis>must</emphasis> be an unconditional
+ <literal>INSTEAD</literal> rule for each action you wish to allow
+ on the view. If the rule is conditional, or is not
+ <literal>INSTEAD</literal>, then the system will still reject
+ attempts to perform the update action, because it thinks it might
+ end up trying to perform the action on the dummy table of the view
+ in some cases. If you want to handle all the useful cases in
+ conditional rules, add an unconditional <literal>DO
+ INSTEAD NOTHING</literal> rule to ensure that the system
+ understands it will never be called on to update the dummy table.
+ Then make the conditional rules non-<literal>INSTEAD</literal>; in
+ the cases where they are applied, they add to the default
+ <literal>INSTEAD NOTHING</literal> action. (This method does not
+ currently work to support <literal>RETURNING</literal> queries, however.)
+ </para>
+
+ <note>
+ <para>
+ A view that is simple enough to be automatically updatable (see <xref
+ linkend="sql-createview"/>) does not require a user-created rule in
+ order to be updatable. While you can create an explicit rule anyway,
+ the automatic update transformation will generally outperform an
+ explicit rule.
+ </para>
+
+ <para>
+ Another alternative worth considering is to use <literal>INSTEAD OF</literal>
+ triggers (see <xref linkend="sql-createtrigger"/>) in place of rules.
+ </para>
+ </note>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a rule to create. This must be distinct from the
+ name of any other rule for the same table. Multiple rules on
+ the same table and same event type are applied in alphabetical
+ name order.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">event</replaceable></term>
+ <listitem>
+ <para>
+ The event is one of <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>, or
+ <literal>DELETE</literal>. Note that an
+ <command>INSERT</command> containing an <literal>ON
+ CONFLICT</literal> clause cannot be used on tables that have
+ either <literal>INSERT</literal> or <literal>UPDATE</literal>
+ rules. Consider using an updatable view instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table or view the
+ rule applies to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">condition</replaceable></term>
+ <listitem>
+ <para>
+ Any <acronym>SQL</acronym> conditional expression (returning
+ <type>boolean</type>). The condition expression cannot refer
+ to any tables except <literal>NEW</literal> and <literal>OLD</literal>, and
+ cannot contain aggregate functions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>INSTEAD</option></term>
+ <listitem>
+ <para><literal>INSTEAD</literal> indicates that the commands should be
+ executed <emphasis>instead of</emphasis> the original command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>ALSO</option></term>
+ <listitem>
+ <para><literal>ALSO</literal> indicates that the commands should be
+ executed <emphasis>in addition to</emphasis> the original
+ command.
+ </para>
+
+ <para>
+ If neither <literal>ALSO</literal> nor
+ <literal>INSTEAD</literal> is specified, <literal>ALSO</literal>
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">command</replaceable></term>
+ <listitem>
+ <para>
+ The command or commands that make up the rule action. Valid
+ commands are <command>SELECT</command>,
+ <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, or <command>NOTIFY</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Within <replaceable class="parameter">condition</replaceable> and
+ <replaceable class="parameter">command</replaceable>, the special
+ table names <literal>NEW</literal> and <literal>OLD</literal> can
+ be used to refer to values in the referenced table.
+ <literal>NEW</literal> is valid in <literal>ON INSERT</literal> and
+ <literal>ON UPDATE</literal> rules to refer to the new row being
+ inserted or updated. <literal>OLD</literal> is valid in
+ <literal>ON UPDATE</literal> and <literal>ON DELETE</literal> rules
+ to refer to the existing row being updated or deleted.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ You must be the owner of a table to create or change rules for it.
+ </para>
+
+ <para>
+ In a rule for <literal>INSERT</literal>, <literal>UPDATE</literal>, or
+ <literal>DELETE</literal> on a view, you can add a <literal>RETURNING</literal>
+ clause that emits the view's columns. This clause will be used to compute
+ the outputs if the rule is triggered by an <command>INSERT RETURNING</command>,
+ <command>UPDATE RETURNING</command>, or <command>DELETE RETURNING</command> command
+ respectively. When the rule is triggered by a command without
+ <literal>RETURNING</literal>, the rule's <literal>RETURNING</literal> clause will be
+ ignored. The current implementation allows only unconditional
+ <literal>INSTEAD</literal> rules to contain <literal>RETURNING</literal>; furthermore
+ there can be at most one <literal>RETURNING</literal> clause among all the rules
+ for the same event. (This ensures that there is only one candidate
+ <literal>RETURNING</literal> clause to be used to compute the results.)
+ <literal>RETURNING</literal> queries on the view will be rejected if
+ there is no <literal>RETURNING</literal> clause in any available rule.
+ </para>
+
+ <para>
+ It is very important to take care to avoid circular rules. For
+ example, though each of the following two rule definitions are
+ accepted by <productname>PostgreSQL</productname>, the
+ <command>SELECT</command> command would cause
+ <productname>PostgreSQL</productname> to report an error because
+ of recursive expansion of a rule:
+
+<programlisting>
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t1
+ DO INSTEAD
+ SELECT * FROM t2;
+
+CREATE RULE "_RETURN" AS
+ ON SELECT TO t2
+ DO INSTEAD
+ SELECT * FROM t1;
+
+SELECT * FROM t1;
+</programlisting>
+ </para>
+
+ <para>
+ Presently, if a rule action contains a <command>NOTIFY</command>
+ command, the <command>NOTIFY</command> command will be executed
+ unconditionally, that is, the <command>NOTIFY</command> will be
+ issued even if there are not any rows that the rule should apply
+ to. For example, in:
+<programlisting>
+CREATE RULE notify_me AS ON UPDATE TO mytable DO ALSO NOTIFY mytable;
+
+UPDATE mytable SET name = 'foo' WHERE id = 42;
+</programlisting>
+ one <command>NOTIFY</command> event will be sent during the
+ <command>UPDATE</command>, whether or not there are any rows that
+ match the condition <literal>id = 42</literal>. This is an
+ implementation restriction that might be fixed in future releases.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE RULE</command> is a
+ <productname>PostgreSQL</productname> language extension, as is the
+ entire query rewrite system.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterrule"/></member>
+ <member><xref linkend="sql-droprule"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_schema.sgml b/doc/src/sgml/ref/create_schema.sgml
new file mode 100644
index 0000000..3c2dddb
--- /dev/null
+++ b/doc/src/sgml/ref/create_schema.sgml
@@ -0,0 +1,228 @@
+<!--
+doc/src/sgml/ref/create_schema.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createschema">
+ <indexterm zone="sql-createschema">
+ <primary>CREATE SCHEMA</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE SCHEMA</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE SCHEMA</refname>
+ <refpurpose>define a new schema</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE SCHEMA <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">role_specification</replaceable> ] [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
+CREATE SCHEMA AUTHORIZATION <replaceable class="parameter">role_specification</replaceable> [ <replaceable class="parameter">schema_element</replaceable> [ ... ] ]
+CREATE SCHEMA IF NOT EXISTS <replaceable class="parameter">schema_name</replaceable> [ AUTHORIZATION <replaceable class="parameter">role_specification</replaceable> ]
+CREATE SCHEMA IF NOT EXISTS AUTHORIZATION <replaceable class="parameter">role_specification</replaceable>
+
+<phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase>
+
+ <replaceable class="parameter">user_name</replaceable>
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE SCHEMA</command> enters a new schema
+ into the current database.
+ The schema name must be distinct from the name of any existing schema
+ in the current database.
+ </para>
+
+ <para>
+ A schema is essentially a namespace:
+ it contains named objects (tables, data types, functions, and operators)
+ whose names can duplicate those of other objects existing in other
+ schemas. Named objects are accessed either by <quote>qualifying</quote>
+ their names with the schema name as a prefix, or by setting a search
+ path that includes the desired schema(s). A <literal>CREATE</literal> command
+ specifying an unqualified object name creates the object
+ in the current schema (the one at the front of the search path,
+ which can be determined with the function <function>current_schema</function>).
+ </para>
+
+ <para>
+ Optionally, <command>CREATE SCHEMA</command> can include subcommands
+ to create objects within the new schema. The subcommands are treated
+ essentially the same as separate commands issued after creating the
+ schema, except that if the <literal>AUTHORIZATION</literal> clause is used,
+ all the created objects will be owned by that user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">schema_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a schema to be created. If this is omitted, the
+ <replaceable class="parameter">user_name</replaceable>
+ is used as the schema name. The name cannot
+ begin with <literal>pg_</literal>, as such names
+ are reserved for system schemas.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ The role name of the user who will own the new schema. If omitted,
+ defaults to the user executing the command. To create a schema
+ owned by another role, you must be a direct or indirect member of
+ that role, or be a superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">schema_element</replaceable></term>
+ <listitem>
+ <para>
+ An SQL statement defining an object to be created within the
+ schema. Currently, only <command>CREATE
+ TABLE</command>, <command>CREATE VIEW</command>, <command>CREATE
+ INDEX</command>, <command>CREATE SEQUENCE</command>, <command>CREATE
+ TRIGGER</command> and <command>GRANT</command> are accepted as clauses
+ within <command>CREATE SCHEMA</command>. Other kinds of objects may
+ be created in separate commands after the schema is created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do nothing (except issuing a notice) if a schema with the same name
+ already exists. <replaceable class="parameter">schema_element</replaceable>
+ subcommands cannot be included when this option is used.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ To create a schema, the invoking user must have the
+ <literal>CREATE</literal> privilege for the current database.
+ (Of course, superusers bypass this check.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a schema:
+<programlisting>
+CREATE SCHEMA myschema;
+</programlisting>
+ </para>
+
+ <para>
+ Create a schema for user <literal>joe</literal>; the schema will also be
+ named <literal>joe</literal>:
+<programlisting>
+CREATE SCHEMA AUTHORIZATION joe;
+</programlisting>
+ </para>
+
+ <para>
+ Create a schema named <literal>test</literal> that will be owned by user
+ <literal>joe</literal>, unless there already is a schema named <literal>test</literal>.
+ (It does not matter whether <literal>joe</literal> owns the pre-existing schema.)
+<programlisting>
+CREATE SCHEMA IF NOT EXISTS test AUTHORIZATION joe;
+</programlisting>
+ </para>
+
+ <para>
+ Create a schema and create a table and view within it:
+<programlisting>
+CREATE SCHEMA hollywood
+ CREATE TABLE films (title text, release date, awards text[])
+ CREATE VIEW winners AS
+ SELECT title, release FROM films WHERE awards IS NOT NULL;
+</programlisting>
+ Notice that the individual subcommands do not end with semicolons.
+ </para>
+
+ <para>
+ The following is an equivalent way of accomplishing the same result:
+<programlisting>
+CREATE SCHEMA hollywood;
+CREATE TABLE hollywood.films (title text, release date, awards text[]);
+CREATE VIEW hollywood.winners AS
+ SELECT title, release FROM hollywood.films WHERE awards IS NOT NULL;
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard allows a <literal>DEFAULT CHARACTER SET</literal> clause
+ in <command>CREATE SCHEMA</command>, as well as more subcommand
+ types than are presently accepted by
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ The SQL standard specifies that the subcommands in <command>CREATE
+ SCHEMA</command> can appear in any order. The present
+ <productname>PostgreSQL</productname> implementation does not
+ handle all cases of forward references in subcommands; it might
+ sometimes be necessary to reorder the subcommands in order to avoid
+ forward references.
+ </para>
+
+ <para>
+ According to the SQL standard, the owner of a schema always owns
+ all objects within it. <productname>PostgreSQL</productname>
+ allows schemas to contain objects owned by users other than the
+ schema owner. This can happen only if the schema owner grants the
+ <literal>CREATE</literal> privilege on their schema to someone else, or a
+ superuser chooses to create objects in it.
+ </para>
+
+ <para>
+ The <literal>IF NOT EXISTS</literal> option is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterschema"/></member>
+ <member><xref linkend="sql-dropschema"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml
new file mode 100644
index 0000000..34e9084
--- /dev/null
+++ b/doc/src/sgml/ref/create_sequence.sgml
@@ -0,0 +1,413 @@
+<!--
+doc/src/sgml/ref/create_sequence.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createsequence">
+ <indexterm zone="sql-createsequence">
+ <primary>CREATE SEQUENCE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE SEQUENCE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE SEQUENCE</refname>
+ <refpurpose>define a new sequence generator</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable>
+ [ AS <replaceable class="parameter">data_type</replaceable> ]
+ [ INCREMENT [ BY ] <replaceable class="parameter">increment</replaceable> ]
+ [ MINVALUE <replaceable class="parameter">minvalue</replaceable> | NO MINVALUE ] [ MAXVALUE <replaceable class="parameter">maxvalue</replaceable> | NO MAXVALUE ]
+ [ START [ WITH ] <replaceable class="parameter">start</replaceable> ] [ CACHE <replaceable class="parameter">cache</replaceable> ] [ [ NO ] CYCLE ]
+ [ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE SEQUENCE</command> creates a new sequence number
+ generator. This involves creating and initializing a new special
+ single-row table with the name <replaceable
+ class="parameter">name</replaceable>. The generator will be
+ owned by the user issuing the command.
+ </para>
+
+ <para>
+ If a schema name is given then the sequence is created in the
+ specified schema. Otherwise it is created in the current schema.
+ Temporary sequences exist in a special schema, so a schema name cannot be
+ given when creating a temporary sequence.
+ The sequence name must be distinct from the name of any other relation
+ (table, sequence, index, view, materialized view, or foreign table) in
+ the same schema.
+ </para>
+
+ <para>
+ After a sequence is created, you use the functions
+ <function>nextval</function>,
+ <function>currval</function>, and
+ <function>setval</function>
+ to operate on the sequence. These functions are documented in
+ <xref linkend="functions-sequence"/>.
+ </para>
+
+ <para>
+ Although you cannot update a sequence directly, you can use a query like:
+
+<programlisting>
+SELECT * FROM <replaceable>name</replaceable>;
+</programlisting>
+
+ to examine the parameters and current state of a sequence. In particular,
+ the <literal>last_value</literal> field of the sequence shows the last value
+ allocated by any session. (Of course, this value might be obsolete
+ by the time it's printed, if other sessions are actively doing
+ <function>nextval</function> calls.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ If specified, the sequence object is created only for this
+ session, and is automatically dropped on session exit. Existing
+ permanent sequences with the same name are not visible (in this
+ session) while the temporary sequence exists, unless they are
+ referenced with schema-qualified names.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>UNLOGGED</literal></term>
+ <listitem>
+ <para>
+ If specified, the sequence is created as an unlogged sequence. Changes
+ to unlogged sequences are not written to the write-ahead log. They are
+ not crash-safe: an unlogged sequence is automatically reset to its
+ initial state after a crash or unclean shutdown. Unlogged sequences are
+ also not replicated to standby servers.
+ </para>
+
+ <para>
+ Unlike unlogged tables, unlogged sequences do not offer a significant
+ performance advantage. This option is mainly intended for sequences
+ associated with unlogged tables via identity columns or serial columns.
+ In those cases, it usually wouldn't make sense to have the sequence
+ WAL-logged and replicated but not its associated table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing relation is anything like the sequence that would have
+ been created &mdash; it might not even be a sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the sequence to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The optional
+ clause <literal>AS <replaceable class="parameter">data_type</replaceable></literal>
+ specifies the data type of the sequence. Valid types are
+ <literal>smallint</literal>, <literal>integer</literal>,
+ and <literal>bigint</literal>. <literal>bigint</literal> is the
+ default. The data type determines the default minimum and maximum
+ values of the sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">increment</replaceable></term>
+ <listitem>
+ <para>
+ The optional clause <literal>INCREMENT BY <replaceable
+ class="parameter">increment</replaceable></literal> specifies
+ which value is added to the current sequence value to create a
+ new value. A positive value will make an ascending sequence, a
+ negative one a descending sequence. The default value is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">minvalue</replaceable></term>
+ <term><literal>NO MINVALUE</literal></term>
+ <listitem>
+ <para>
+ The optional clause <literal>MINVALUE <replaceable
+ class="parameter">minvalue</replaceable></literal> determines
+ the minimum value a sequence can generate. If this clause is not
+ supplied or <option>NO MINVALUE</option> is specified, then
+ defaults will be used. The default for an ascending sequence is 1. The
+ default for a descending sequence is the minimum value of the data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">maxvalue</replaceable></term>
+ <term><literal>NO MAXVALUE</literal></term>
+ <listitem>
+ <para>
+ The optional clause <literal>MAXVALUE <replaceable
+ class="parameter">maxvalue</replaceable></literal> determines
+ the maximum value for the sequence. If this clause is not
+ supplied or <option>NO MAXVALUE</option> is specified, then
+ default values will be used. The default for an ascending sequence is
+ the maximum value of the data type. The default for a descending
+ sequence is -1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">start</replaceable></term>
+ <listitem>
+ <para>
+ The optional clause <literal>START WITH <replaceable
+ class="parameter">start</replaceable> </literal> allows the
+ sequence to begin anywhere. The default starting value is
+ <replaceable class="parameter">minvalue</replaceable> for
+ ascending sequences and <replaceable
+ class="parameter">maxvalue</replaceable> for descending ones.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cache</replaceable></term>
+ <listitem>
+ <para>
+ The optional clause <literal>CACHE <replaceable
+ class="parameter">cache</replaceable></literal> specifies how
+ many sequence numbers are to be preallocated and stored in
+ memory for faster access. The minimum value is 1 (only one value
+ can be generated at a time, i.e., no cache), and this is also the
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CYCLE</literal></term>
+ <term><literal>NO CYCLE</literal></term>
+ <listitem>
+ <para>
+ The <literal>CYCLE</literal> option allows the sequence to wrap
+ around when the <replaceable
+ class="parameter">maxvalue</replaceable> or <replaceable
+ class="parameter">minvalue</replaceable> has been reached by an
+ ascending or descending sequence respectively. If the limit is
+ reached, the next number generated will be the <replaceable
+ class="parameter">minvalue</replaceable> or <replaceable
+ class="parameter">maxvalue</replaceable>, respectively.
+ </para>
+
+ <para>
+ If <literal>NO CYCLE</literal> is specified, any calls to
+ <function>nextval</function> after the sequence has reached its
+ maximum value will return an error. If neither
+ <literal>CYCLE</literal> or <literal>NO CYCLE</literal> are
+ specified, <literal>NO CYCLE</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OWNED BY</literal> <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable></term>
+ <term><literal>OWNED BY NONE</literal></term>
+ <listitem>
+ <para>
+ The <literal>OWNED BY</literal> option causes the sequence to be
+ associated with a specific table column, such that if that column
+ (or its whole table) is dropped, the sequence will be automatically
+ dropped as well. The specified table must have the same owner and be in
+ the same schema as the sequence.
+ <literal>OWNED BY NONE</literal>, the default, specifies that there
+ is no such association.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <command>DROP SEQUENCE</command> to remove a sequence.
+ </para>
+
+ <para>
+ Sequences are based on <type>bigint</type> arithmetic, so the range
+ cannot exceed the range of an eight-byte integer
+ (-9223372036854775808 to 9223372036854775807).
+ </para>
+
+ <para>
+ Because <function>nextval</function> and <function>setval</function> calls are never
+ rolled back, sequence objects cannot be used if <quote>gapless</quote>
+ assignment of sequence numbers is needed. It is possible to build
+ gapless assignment by using exclusive locking of a table containing a
+ counter; but this solution is much more expensive than sequence
+ objects, especially if many transactions need sequence numbers
+ concurrently.
+ </para>
+
+ <para>
+ Unexpected results might be obtained if a <replaceable
+ class="parameter">cache</replaceable> setting greater than one is
+ used for a sequence object that will be used concurrently by
+ multiple sessions. Each session will allocate and cache successive
+ sequence values during one access to the sequence object and
+ increase the sequence object's <literal>last_value</literal> accordingly.
+ Then, the next <replaceable class="parameter">cache</replaceable>-1
+ uses of <function>nextval</function> within that session simply return the
+ preallocated values without touching the sequence object. So, any
+ numbers allocated but not used within a session will be lost when
+ that session ends, resulting in <quote>holes</quote> in the
+ sequence.
+ </para>
+
+ <para>
+ Furthermore, although multiple sessions are guaranteed to allocate
+ distinct sequence values, the values might be generated out of
+ sequence when all the sessions are considered. For example, with
+ a <replaceable class="parameter">cache</replaceable> setting of 10,
+ session A might reserve values 1..10 and return
+ <function>nextval</function>=1, then session B might reserve values
+ 11..20 and return <function>nextval</function>=11 before session A
+ has generated <function>nextval</function>=2. Thus, with a
+ <replaceable class="parameter">cache</replaceable> setting of one
+ it is safe to assume that <function>nextval</function> values are generated
+ sequentially; with a <replaceable
+ class="parameter">cache</replaceable> setting greater than one you
+ should only assume that the <function>nextval</function> values are all
+ distinct, not that they are generated purely sequentially. Also,
+ <literal>last_value</literal> will reflect the latest value reserved by
+ any session, whether or not it has yet been returned by
+ <function>nextval</function>.
+ </para>
+
+ <para>
+ Another consideration is that a <function>setval</function> executed on
+ such a sequence will not be noticed by other sessions until they
+ have used up any preallocated values they have cached.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create an ascending sequence called <literal>serial</literal>, starting at 101:
+<programlisting>
+CREATE SEQUENCE serial START 101;
+</programlisting>
+ </para>
+
+ <para>
+ Select the next number from this sequence:
+<programlisting>
+SELECT nextval('serial');
+
+ nextval
+---------
+ 101
+</programlisting>
+ </para>
+
+ <para>
+ Select the next number from this sequence:
+<programlisting>
+SELECT nextval('serial');
+
+ nextval
+---------
+ 102
+</programlisting>
+ </para>
+
+ <para>
+ Use this sequence in an <command>INSERT</command> command:
+<programlisting>
+INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
+</programlisting>
+ </para>
+
+ <para>
+ Update the sequence value after a <command>COPY FROM</command>:
+<programlisting>
+BEGIN;
+COPY distributors FROM 'input_file';
+SELECT setval('serial', max(id)) FROM distributors;
+END;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE SEQUENCE</command> conforms to the <acronym>SQL</acronym>
+ standard, with the following exceptions:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Obtaining the next value is done using the <function>nextval()</function>
+ function instead of the standard's <command>NEXT VALUE FOR</command>
+ expression.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <literal>OWNED BY</literal> clause is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </listitem>
+ </itemizedlist></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altersequence"/></member>
+ <member><xref linkend="sql-dropsequence"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_server.sgml b/doc/src/sgml/ref/create_server.sgml
new file mode 100644
index 0000000..af0a7a0
--- /dev/null
+++ b/doc/src/sgml/ref/create_server.sgml
@@ -0,0 +1,167 @@
+<!--
+doc/src/sgml/ref/create_server.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createserver">
+ <indexterm zone="sql-createserver">
+ <primary>CREATE SERVER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE SERVER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE SERVER</refname>
+ <refpurpose>define a new foreign server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE SERVER [ IF NOT EXISTS ] <replaceable class="parameter">server_name</replaceable> [ TYPE '<replaceable class="parameter">server_type</replaceable>' ] [ VERSION '<replaceable class="parameter">server_version</replaceable>' ]
+ FOREIGN DATA WRAPPER <replaceable class="parameter">fdw_name</replaceable>
+ [ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE SERVER</command> defines a new foreign server. The
+ user who defines the server becomes its owner.
+ </para>
+
+ <para>
+ A foreign server typically encapsulates connection information that
+ a foreign-data wrapper uses to access an external data resource.
+ Additional user-specific connection information may be specified by
+ means of user mappings.
+ </para>
+
+ <para>
+ The server name must be unique within the database.
+ </para>
+
+ <para>
+ Creating a server requires <literal>USAGE</literal> privilege on the
+ foreign-data wrapper being used.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a server with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing server is anything like the one that would have been
+ created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the foreign server to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_type</replaceable></term>
+ <listitem>
+ <para>
+ Optional server type, potentially useful to foreign-data wrappers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_version</replaceable></term>
+ <listitem>
+ <para>
+ Optional server version, potentially useful to foreign-data wrappers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">fdw_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the foreign-data wrapper that manages the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies the options for the server. The options
+ typically define the connection details of the server, but the
+ actual names and values are dependent on the server's
+ foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When using the <xref linkend="dblink"/> module,
+ a foreign server's name can be used
+ as an argument of the <xref linkend="contrib-dblink-connect"/>
+ function to indicate the connection parameters. It is necessary to have
+ the <literal>USAGE</literal> privilege on the foreign server to be
+ able to use it in this way.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a server <literal>myserver</literal> that uses the
+ foreign-data wrapper <literal>postgres_fdw</literal>:
+<programlisting>
+CREATE SERVER myserver FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foo', dbname 'foodb', port '5432');
+</programlisting>
+ See <xref linkend="postgres-fdw"/> for more details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE SERVER</command> conforms to ISO/IEC 9075-9 (SQL/MED).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterserver"/></member>
+ <member><xref linkend="sql-dropserver"/></member>
+ <member><xref linkend="sql-createforeigndatawrapper"/></member>
+ <member><xref linkend="sql-createforeigntable"/></member>
+ <member><xref linkend="sql-createusermapping"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_statistics.sgml b/doc/src/sgml/ref/create_statistics.sgml
new file mode 100644
index 0000000..a145c41
--- /dev/null
+++ b/doc/src/sgml/ref/create_statistics.sgml
@@ -0,0 +1,331 @@
+<!--
+doc/src/sgml/ref/create_statistics.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createstatistics">
+ <indexterm zone="sql-createstatistics">
+ <primary>CREATE STATISTICS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE STATISTICS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE STATISTICS</refname>
+ <refpurpose>define extended statistics</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE STATISTICS [ IF NOT EXISTS ] <replaceable class="parameter">statistics_name</replaceable>
+ ON ( <replaceable class="parameter">expression</replaceable> )
+ FROM <replaceable class="parameter">table_name</replaceable>
+
+CREATE STATISTICS [ IF NOT EXISTS ] <replaceable class="parameter">statistics_name</replaceable>
+ [ ( <replaceable class="parameter">statistics_kind</replaceable> [, ... ] ) ]
+ ON { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) }, { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [, ...]
+ FROM <replaceable class="parameter">table_name</replaceable>
+</synopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createstatistics-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE STATISTICS</command> will create a new extended statistics
+ object tracking data about the specified table, foreign table or
+ materialized view. The statistics object will be created in the current
+ database and will be owned by the user issuing the command.
+ </para>
+
+ <para>
+ The <command>CREATE STATISTICS</command> command has two basic forms. The
+ first form allows univariate statistics for a single expression to be
+ collected, providing benefits similar to an expression index without the
+ overhead of index maintenance. This form does not allow the statistics
+ kind to be specified, since the various statistics kinds refer only to
+ multivariate statistics. The second form of the command allows
+ multivariate statistics on multiple columns and/or expressions to be
+ collected, optionally specifying which statistics kinds to include. This
+ form will also automatically cause univariate statistics to be collected on
+ any expressions included in the list.
+ </para>
+
+ <para>
+ If a schema name is given (for example, <literal>CREATE STATISTICS
+ myschema.mystat ...</literal>) then the statistics object is created in the
+ specified schema. Otherwise it is created in the current schema.
+ The name of the statistics object must be distinct from the name of any
+ other statistics object in the same schema.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a statistics object with the same name already
+ exists. A notice is issued in this case. Note that only the name of
+ the statistics object is considered here, not the details of its
+ definition.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">statistics_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the statistics object to be
+ created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">statistics_kind</replaceable></term>
+ <listitem>
+ <para>
+ A multivariate statistics kind to be computed in this statistics object.
+ Currently supported kinds are
+ <literal>ndistinct</literal>, which enables n-distinct statistics,
+ <literal>dependencies</literal>, which enables functional
+ dependency statistics, and <literal>mcv</literal> which enables
+ most-common values lists.
+ If this clause is omitted, all supported statistics kinds are
+ included in the statistics object. Univariate expression statistics are
+ built automatically if the statistics definition includes any complex
+ expressions rather than just simple column references.
+ For more information, see <xref linkend="planner-stats-extended"/>
+ and <xref linkend="multivariate-statistics-examples"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a table column to be covered by the computed statistics.
+ This is only allowed when building multivariate statistics. At least
+ two column names or expressions must be specified, and their order is
+ not significant.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression to be covered by the computed statistics. This may be
+ used to build univariate statistics on a single expression, or as part
+ of a list of multiple column names and/or expressions to build
+ multivariate statistics. In the latter case, separate univariate
+ statistics are built automatically for each expression in the list.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table containing the
+ column(s) the statistics are computed on; see <xref
+ linkend="sql-analyze"/> for an explanation of the handling of
+ inheritance and partitions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ You must be the owner of a table to create a statistics object
+ reading it. Once created, however, the ownership of the statistics
+ object is independent of the underlying table(s).
+ </para>
+
+ <para>
+ Expression statistics are per-expression and are similar to creating an
+ index on the expression, except that they avoid the overhead of index
+ maintenance. Expression statistics are built automatically for each
+ expression in the statistics object definition.
+ </para>
+
+ <para>
+ Extended statistics are not currently used by the planner for selectivity
+ estimations made for table joins. This limitation will likely be removed
+ in a future version of <productname>PostgreSQL</productname>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createstatistics-examples">
+ <title>Examples</title>
+
+ <para>
+ Create table <structname>t1</structname> with two functionally dependent columns, i.e.,
+ knowledge of a value in the first column is sufficient for determining the
+ value in the other column. Then functional dependency statistics are built
+ on those columns:
+
+<programlisting>
+CREATE TABLE t1 (
+ a int,
+ b int
+);
+
+INSERT INTO t1 SELECT i/100, i/500
+ FROM generate_series(1,1000000) s(i);
+
+ANALYZE t1;
+
+-- the number of matching rows will be drastically underestimated:
+EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
+
+CREATE STATISTICS s1 (dependencies) ON a, b FROM t1;
+
+ANALYZE t1;
+
+-- now the row count estimate is more accurate:
+EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
+</programlisting>
+
+ Without functional-dependency statistics, the planner would assume
+ that the two <literal>WHERE</literal> conditions are independent, and would
+ multiply their selectivities together to arrive at a much-too-small
+ row count estimate.
+ With such statistics, the planner recognizes that the <literal>WHERE</literal>
+ conditions are redundant and does not underestimate the row count.
+ </para>
+
+ <para>
+ Create table <structname>t2</structname> with two perfectly correlated columns
+ (containing identical data), and an MCV list on those columns:
+
+<programlisting>
+CREATE TABLE t2 (
+ a int,
+ b int
+);
+
+INSERT INTO t2 SELECT mod(i,100), mod(i,100)
+ FROM generate_series(1,1000000) s(i);
+
+CREATE STATISTICS s2 (mcv) ON a, b FROM t2;
+
+ANALYZE t2;
+
+-- valid combination (found in MCV)
+EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1);
+
+-- invalid combination (not found in MCV)
+EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);
+</programlisting>
+
+ The MCV list gives the planner more detailed information about the
+ specific values that commonly appear in the table, as well as an upper
+ bound on the selectivities of combinations of values that do not appear
+ in the table, allowing it to generate better estimates in both cases.
+ </para>
+
+ <para>
+ Create table <structname>t3</structname> with a single timestamp column,
+ and run queries using expressions on that column. Without extended
+ statistics, the planner has no information about the data distribution for
+ the expressions, and uses default estimates. The planner also does not
+ realize that the value of the date truncated to the month is fully
+ determined by the value of the date truncated to the day. Then expression
+ and ndistinct statistics are built on those two expressions:
+
+<programlisting>
+CREATE TABLE t3 (
+ a timestamp
+);
+
+INSERT INTO t3 SELECT i FROM generate_series('2020-01-01'::timestamp,
+ '2020-12-31'::timestamp,
+ '1 minute'::interval) s(i);
+
+ANALYZE t3;
+
+-- the number of matching rows will be drastically underestimated:
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('month', a) = '2020-01-01'::timestamp;
+
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp
+ AND '2020-06-30'::timestamp;
+
+EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a)
+ FROM t3 GROUP BY 1, 2;
+
+-- build ndistinct statistics on the pair of expressions (per-expression
+-- statistics are built automatically)
+CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3;
+
+ANALYZE t3;
+
+-- now the row count estimates are more accurate:
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('month', a) = '2020-01-01'::timestamp;
+
+EXPLAIN ANALYZE SELECT * FROM t3
+ WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp
+ AND '2020-06-30'::timestamp;
+
+EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a)
+ FROM t3 GROUP BY 1, 2;
+</programlisting>
+
+ Without expression and ndistinct statistics, the planner has no information
+ about the number of distinct values for the expressions, and has to rely
+ on default estimates. The equality and range conditions are assumed to have
+ 0.5% selectivity, and the number of distinct values in the expression is
+ assumed to be the same as for the column (i.e. unique). This results in a
+ significant underestimate of the row count in the first two queries. Moreover,
+ the planner has no information about the relationship between the expressions,
+ so it assumes the two <literal>WHERE</literal> and <literal>GROUP BY</literal>
+ conditions are independent, and multiplies their selectivities together to
+ arrive at a severe overestimate of the group count in the aggregate query.
+ This is further exacerbated by the lack of accurate statistics for the
+ expressions, forcing the planner to use a default ndistinct estimate for the
+ expression derived from ndistinct for the column. With such statistics, the
+ planner recognizes that the conditions are correlated, and arrives at much
+ more accurate estimates.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CREATE STATISTICS</command> command in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterstatistics"/></member>
+ <member><xref linkend="sql-dropstatistics"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml
new file mode 100644
index 0000000..3eb1ead
--- /dev/null
+++ b/doc/src/sgml/ref/create_subscription.sgml
@@ -0,0 +1,422 @@
+<!--
+doc/src/sgml/ref/create_subscription.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createsubscription">
+ <indexterm zone="sql-createsubscription">
+ <primary>CREATE SUBSCRIPTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE SUBSCRIPTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE SUBSCRIPTION</refname>
+ <refpurpose>define a new subscription</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceable>
+ CONNECTION '<replaceable class="parameter">conninfo</replaceable>'
+ PUBLICATION <replaceable class="parameter">publication_name</replaceable> [, ...]
+ [ WITH ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE SUBSCRIPTION</command> adds a new logical-replication
+ subscription. The subscription name must be distinct from the name of
+ any existing subscription in the current database.
+ </para>
+
+ <para>
+ A subscription represents a replication connection to the publisher.
+ Hence, in addition to adding definitions in the local catalogs, this
+ command normally creates a replication slot on the publisher.
+ </para>
+
+ <para>
+ A logical replication worker will be started to replicate data for the new
+ subscription at the commit of the transaction where this command is run,
+ unless the subscription is initially disabled.
+ </para>
+
+ <para>
+ Additional information about subscriptions and logical replication as a
+ whole is available at <xref linkend="logical-replication-subscription"/> and
+ <xref linkend="logical-replication"/>.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">subscription_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the new subscription.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONNECTION '<replaceable class="parameter">conninfo</replaceable>'</literal></term>
+ <listitem>
+ <para>
+ The <application>libpq</application> connection string defining how
+ to connect to the publisher database. For details see
+ <xref linkend="libpq-connstring"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PUBLICATION <replaceable class="parameter">publication_name</replaceable> [, ...]</literal></term>
+ <listitem>
+ <para>
+ Names of the publications on the publisher to subscribe to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH ( <replaceable class="parameter">subscription_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies optional parameters for a subscription.
+ </para>
+
+ <para>
+ The following parameters control what happens during subscription creation:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>connect</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether the <command>CREATE SUBSCRIPTION</command>
+ command should connect to the publisher at all. The default
+ is <literal>true</literal>. Setting this to
+ <literal>false</literal> will force the values of
+ <literal>create_slot</literal>, <literal>enabled</literal> and
+ <literal>copy_data</literal> to <literal>false</literal>.
+ (You cannot combine setting <literal>connect</literal>
+ to <literal>false</literal> with
+ setting <literal>create_slot</literal>, <literal>enabled</literal>,
+ or <literal>copy_data</literal> to <literal>true</literal>.)
+ </para>
+
+ <para>
+ Since no connection is made when this option is
+ <literal>false</literal>, no tables are subscribed, and so
+ after you enable the subscription nothing will be replicated.
+ You will need to then run
+ <literal>ALTER SUBSCRIPTION ... REFRESH PUBLICATION</literal>
+ for tables to be subscribed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>create_slot</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether the command should create the replication slot on
+ the publisher. The default is <literal>true</literal>.
+ If set to <literal>false</literal>, you are responsible for
+ creating the publisher's slot in some other way.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>enabled</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether the subscription should be actively replicating
+ or whether it should just be set up but not started yet. The default
+ is <literal>true</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>slot_name</literal> (<type>string</type>)</term>
+ <listitem>
+ <para>
+ Name of the publisher's replication slot to use. The default is
+ to use the name of the subscription for the slot name.
+ </para>
+
+ <para>
+ Setting <literal>slot_name</literal> to <literal>NONE</literal>
+ means there will be no replication slot
+ associated with the subscription. Use this when you will be
+ creating the replication slot later manually. Such
+ subscriptions must also have both <literal>enabled</literal> and
+ <literal>create_slot</literal> set to <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following parameters control the subscription's replication
+ behavior after it has been created:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>binary</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether the subscription will request the publisher to
+ send the data in binary format (as opposed to text).
+ The default is <literal>false</literal>.
+ Even when this option is enabled, only data types having
+ binary send and receive functions will be transferred in binary.
+ </para>
+
+ <para>
+ When doing cross-version replication, it could be that the
+ publisher has a binary send function for some data type, but the
+ subscriber lacks a binary receive function for that type. In
+ such a case, data transfer will fail, and
+ the <literal>binary</literal> option cannot be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>copy_data</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether to copy pre-existing data in the publications
+ that are being subscribed to when the replication starts.
+ The default is <literal>true</literal>.
+ </para>
+ <para>
+ If the publications contain <literal>WHERE</literal> clauses, it
+ will affect what data is copied. Refer to the
+ <xref linkend="sql-createsubscription-notes" /> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>streaming</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether to enable streaming of in-progress transactions
+ for this subscription. By default, all transactions
+ are fully decoded on the publisher and only then sent to the
+ subscriber as a whole.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>synchronous_commit</literal> (<type>enum</type>)</term>
+ <listitem>
+ <para>
+ The value of this parameter overrides the
+ <xref linkend="guc-synchronous-commit"/> setting within this
+ subscription's apply worker processes. The default value
+ is <literal>off</literal>.
+ </para>
+
+ <para>
+ It is safe to use <literal>off</literal> for logical replication:
+ If the subscriber loses transactions because of missing
+ synchronization, the data will be sent again from the publisher.
+ </para>
+
+ <para>
+ A different setting might be appropriate when doing synchronous
+ logical replication. The logical replication workers report the
+ positions of writes and flushes to the publisher, and when using
+ synchronous replication, the publisher will wait for the actual
+ flush. This means that setting
+ <literal>synchronous_commit</literal> for the subscriber to
+ <literal>off</literal> when the subscription is used for
+ synchronous replication might increase the latency for
+ <command>COMMIT</command> on the publisher. In this scenario, it
+ can be advantageous to set <literal>synchronous_commit</literal>
+ to <literal>local</literal> or higher.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>two_phase</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether two-phase commit is enabled for this subscription.
+ The default is <literal>false</literal>.
+ </para>
+
+ <para>
+ When two-phase commit is enabled, prepared transactions are sent
+ to the subscriber at the time of <command>PREPARE
+ TRANSACTION</command>, and are processed as two-phase
+ transactions on the subscriber too. Otherwise, prepared
+ transactions are sent to the subscriber only when committed, and
+ are then processed immediately by the subscriber.
+ </para>
+
+ <para>
+ The implementation of two-phase commit requires that replication
+ has successfully finished the initial table synchronization
+ phase. So even when <literal>two_phase</literal> is enabled for a
+ subscription, the internal two-phase state remains
+ temporarily <quote>pending</quote> until the initialization phase
+ completes. See column <structfield>subtwophasestate</structfield>
+ of <link linkend="catalog-pg-subscription"><structname>pg_subscription</structname></link>
+ to know the actual two-phase state.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>disable_on_error</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ Specifies whether the subscription should be automatically disabled
+ if any errors are detected by subscription workers during data
+ replication from the publisher. The default is
+ <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createsubscription-notes" xreflabel="Notes">
+ <title>Notes</title>
+
+ <para>
+ See <xref linkend="logical-replication-security"/> for details on
+ how to configure access control between the subscription and the
+ publication instance.
+ </para>
+
+ <para>
+ When creating a replication slot (the default behavior), <command>CREATE
+ SUBSCRIPTION</command> cannot be executed inside a transaction block.
+ </para>
+
+ <para>
+ Creating a subscription that connects to the same database cluster (for
+ example, to replicate between databases in the same cluster or to replicate
+ within the same database) will only succeed if the replication slot is not
+ created as part of the same command. Otherwise, the <command>CREATE
+ SUBSCRIPTION</command> call will hang. To make this work, create the
+ replication slot separately (using the
+ function <function>pg_create_logical_replication_slot</function> with the
+ plugin name <literal>pgoutput</literal>) and create the subscription using
+ the parameter <literal>create_slot = false</literal>. This is an
+ implementation restriction that might be lifted in a future release.
+ </para>
+
+ <para>
+ If any table in the publication has a <literal>WHERE</literal> clause, rows
+ for which the <replaceable class="parameter">expression</replaceable>
+ evaluates to false or null will not be published. If the subscription has
+ several publications in which the same table has been published with
+ different <literal>WHERE</literal> clauses, a row will be published if any
+ of the expressions (referring to that publish operation) are satisfied. In
+ the case of different <literal>WHERE</literal> clauses, if one of the
+ publications has no <literal>WHERE</literal> clause (referring to that
+ publish operation) or the publication is declared as
+ <literal>FOR ALL TABLES</literal> or
+ <literal>FOR TABLES IN SCHEMA</literal>, rows are always published
+ regardless of the definition of the other expressions.
+ If the subscriber is a <productname>PostgreSQL</productname> version before
+ 15, then any row filtering is ignored during the initial data synchronization
+ phase. For this case, the user might want to consider deleting any initially
+ copied data that would be incompatible with subsequent filtering.
+ Because initial data synchronization does not take into account the publication
+ <literal>publish</literal> parameter when copying existing table data, some rows
+ may be copied that would not be replicated using DML. See
+ <xref linkend="logical-replication-subscription-examples"/> for examples.
+ </para>
+
+ <para>
+ Subscriptions having several publications in which the same table has been
+ published with different column lists are not supported.
+ </para>
+
+ <para>
+ We allow non-existent publications to be specified so that users can add
+ those later. This means
+ <link linkend="catalog-pg-subscription"><structname>pg_subscription</structname></link>
+ can have non-existent publications.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a subscription to a remote server that replicates tables in
+ the publications <literal>mypublication</literal> and
+ <literal>insert_only</literal> and starts replicating immediately on
+ commit:
+<programlisting>
+CREATE SUBSCRIPTION mysub
+ CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
+ PUBLICATION mypublication, insert_only;
+</programlisting>
+ </para>
+
+ <para>
+ Create a subscription to a remote server that replicates tables in
+ the <literal>insert_only</literal> publication and does not start replicating
+ until enabled at a later time.
+<programlisting>
+CREATE SUBSCRIPTION mysub
+ CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
+ PUBLICATION insert_only
+ WITH (enabled = false);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE SUBSCRIPTION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altersubscription"/></member>
+ <member><xref linkend="sql-dropsubscription"/></member>
+ <member><xref linkend="sql-createpublication"/></member>
+ <member><xref linkend="sql-alterpublication"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
new file mode 100644
index 0000000..c1b6beb
--- /dev/null
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -0,0 +1,2422 @@
+<!--
+doc/src/sgml/ref/create_table.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtable">
+ <indexterm zone="sql-createtable">
+ <primary>CREATE TABLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TABLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TABLE</refname>
+ <refpurpose>define a new table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable class="parameter">table_name</replaceable> ( [
+ { <replaceable class="parameter">column_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COMPRESSION <replaceable>compression_method</replaceable> ] [ COLLATE <replaceable>collation</replaceable> ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ | <replaceable>table_constraint</replaceable>
+ | LIKE <replaceable>source_table</replaceable> [ <replaceable>like_option</replaceable> ... ] }
+ [, ... ]
+] )
+[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
+[ PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ... ] ) ]
+[ USING <replaceable class="parameter">method</replaceable> ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable class="parameter">table_name</replaceable>
+ OF <replaceable class="parameter">type_name</replaceable> [ (
+ { <replaceable class="parameter">column_name</replaceable> [ WITH OPTIONS ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ | <replaceable>table_constraint</replaceable> }
+ [, ... ]
+) ]
+[ PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ... ] ) ]
+[ USING <replaceable class="parameter">method</replaceable> ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable class="parameter">table_name</replaceable>
+ PARTITION OF <replaceable class="parameter">parent_table</replaceable> [ (
+ { <replaceable class="parameter">column_name</replaceable> [ WITH OPTIONS ] [ <replaceable class="parameter">column_constraint</replaceable> [ ... ] ]
+ | <replaceable>table_constraint</replaceable> }
+ [, ... ]
+) ] { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
+[ PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ... ] ) ]
+[ USING <replaceable class="parameter">method</replaceable> ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
+[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+[ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+
+<phrase>where <replaceable class="parameter">column_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+{ NOT NULL |
+ NULL |
+ CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
+ DEFAULT <replaceable>default_expr</replaceable> |
+ GENERATED ALWAYS AS ( <replaceable>generation_expr</replaceable> ) STORED |
+ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] <replaceable class="parameter">index_parameters</replaceable> |
+ PRIMARY KEY <replaceable class="parameter">index_parameters</replaceable> |
+ REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
+ [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<phrase>and <replaceable class="parameter">table_constraint</replaceable> is:</phrase>
+
+[ CONSTRAINT <replaceable class="parameter">constraint_name</replaceable> ]
+{ CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] |
+ UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> |
+ PRIMARY KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> |
+ EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ] |
+ FOREIGN KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> [, ... ] ) ]
+ [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable
+class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ] }
+[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
+
+<phrase>and <replaceable class="parameter">like_option</replaceable> is:</phrase>
+
+{ INCLUDING | EXCLUDING } { COMMENTS | COMPRESSION | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL }
+
+<phrase>and <replaceable class="parameter">partition_bound_spec</replaceable> is:</phrase>
+
+IN ( <replaceable class="parameter">partition_bound_expr</replaceable> [, ...] ) |
+FROM ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] )
+ TO ( { <replaceable class="parameter">partition_bound_expr</replaceable> | MINVALUE | MAXVALUE } [, ...] ) |
+WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REMAINDER <replaceable class="parameter">numeric_literal</replaceable> )
+
+<phrase><replaceable class="parameter">index_parameters</replaceable> in <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>, and <literal>EXCLUDE</literal> constraints are:</phrase>
+
+[ INCLUDE ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ]
+[ USING INDEX TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+
+<phrase><replaceable class="parameter">exclude_element</replaceable> in an <literal>EXCLUDE</literal> constraint is:</phrase>
+
+{ <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
+
+<phrase><replaceable class="parameter">referential_action</replaceable> in a <literal>FOREIGN KEY</literal>/<literal>REFERENCES</literal> constraint is:</phrase>
+
+{ NO ACTION | RESTRICT | CASCADE | SET NULL [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] | SET DEFAULT [ ( <replaceable class="parameter">column_name</replaceable> [, ... ] ) ] }
+</synopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createtable-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TABLE</command> will create a new, initially empty table
+ in the current database. The table will be owned by the user issuing the
+ command.
+ </para>
+
+ <para>
+ If a schema name is given (for example, <literal>CREATE TABLE
+ myschema.mytable ...</literal>) then the table is created in the specified
+ schema. Otherwise it is created in the current schema. Temporary
+ tables exist in a special schema, so a schema name cannot be given
+ when creating a temporary table. The name of the table must be
+ distinct from the name of any other relation (table, sequence, index, view,
+ materialized view, or foreign table) in the same schema.
+ </para>
+
+ <para>
+ <command>CREATE TABLE</command> also automatically creates a data
+ type that represents the composite type corresponding
+ to one row of the table. Therefore, tables cannot have the same
+ name as any existing data type in the same schema.
+ </para>
+
+ <para>
+ The optional constraint clauses specify constraints (tests) that
+ new or updated rows must satisfy for an insert or update operation
+ to succeed. A constraint is an SQL object that helps define the
+ set of valid values in the table in various ways.
+ </para>
+
+ <para>
+ There are two ways to define constraints: table constraints and
+ column constraints. A column constraint is defined as part of a
+ column definition. A table constraint definition is not tied to a
+ particular column, and it can encompass more than one column.
+ Every column constraint can also be written as a table constraint;
+ a column constraint is only a notational convenience for use when the
+ constraint only affects one column.
+ </para>
+
+ <para>
+ To be able to create a table, you must have <literal>USAGE</literal>
+ privilege on all column types or the type in the <literal>OF</literal>
+ clause, respectively.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry id="sql-createtable-temporary">
+ <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ If specified, the table is created as a temporary table.
+ Temporary tables are automatically dropped at the end of a
+ session, or optionally at the end of the current transaction
+ (see <literal>ON COMMIT</literal> below). The default
+ search_path includes the temporary schema first and so identically
+ named existing permanent tables are not chosen for new plans
+ while the temporary table exists, unless they are referenced
+ with schema-qualified names. Any indexes created on a temporary
+ table are automatically temporary as well.
+ </para>
+
+ <para>
+ The <link linkend="autovacuum">autovacuum daemon</link> cannot
+ access and therefore cannot vacuum or analyze temporary tables.
+ For this reason, appropriate vacuum and analyze operations should be
+ performed via session SQL commands. For example, if a temporary
+ table is going to be used in complex queries, it is wise to run
+ <command>ANALYZE</command> on the temporary table after it is populated.
+ </para>
+
+ <para>
+ Optionally, <literal>GLOBAL</literal> or <literal>LOCAL</literal>
+ can be written before <literal>TEMPORARY</literal> or <literal>TEMP</literal>.
+ This presently makes no difference in <productname>PostgreSQL</productname>
+ and is deprecated; see
+ <xref linkend="sql-createtable-compatibility"/> below.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createtable-unlogged">
+ <term><literal>UNLOGGED</literal></term>
+ <listitem>
+ <para>
+ If specified, the table is created as an unlogged table. Data written
+ to unlogged tables is not written to the write-ahead log (see <xref
+ linkend="wal"/>), which makes them considerably faster than ordinary
+ tables. However, they are not crash-safe: an unlogged table is
+ automatically truncated after a crash or unclean shutdown. The contents
+ of an unlogged table are also not replicated to standby servers.
+ Any indexes created on an unlogged table are automatically unlogged as
+ well.
+ </para>
+
+ <para>
+ If this is specified, any sequences created together with the unlogged
+ table (for identity or serial columns) are also created as unlogged.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a relation with the same name already exists.
+ A notice is issued in this case. Note that there is no guarantee that
+ the existing relation is anything like the one that would have been
+ created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OF <replaceable class="parameter">type_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ Creates a <firstterm>typed table</firstterm>, which takes its
+ structure from the specified composite type (name optionally
+ schema-qualified). A typed table is tied to its type; for
+ example the table will be dropped if the type is dropped
+ (with <literal>DROP TYPE ... CASCADE</literal>).
+ </para>
+
+ <para>
+ When a typed table is created, then the data types of the
+ columns are determined by the underlying composite type and are
+ not specified by the <literal>CREATE TABLE</literal> command.
+ But the <literal>CREATE TABLE</literal> command can add defaults
+ and constraints to the table and can specify storage parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column to be created in the new table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the column. This can include array
+ specifiers. For more information on the data types supported by
+ <productname>PostgreSQL</productname>, refer to <xref
+ linkend="datatype"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COLLATE <replaceable>collation</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <literal>COLLATE</literal> clause assigns a collation to
+ the column (which must be of a collatable data type).
+ If not specified, the column data type's default collation is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COMPRESSION <replaceable class="parameter">compression_method</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <literal>COMPRESSION</literal> clause sets the compression method
+ for the column. Compression is supported only for variable-width data
+ types, and is used only when the column's storage mode
+ is <literal>main</literal> or <literal>extended</literal>.
+ (See <xref linkend="sql-altertable"/> for information on
+ column storage modes.) Setting this property for a partitioned table
+ has no direct effect, because such tables have no storage of their own,
+ but the configured value will be inherited by newly-created partitions.
+ The supported compression methods are <literal>pglz</literal> and
+ <literal>lz4</literal>. (<literal>lz4</literal> is available only if
+ <option>--with-lz4</option> was used when building
+ <productname>PostgreSQL</productname>.) In addition,
+ <replaceable class="parameter">compression_method</replaceable>
+ can be <literal>default</literal> to explicitly specify the default
+ behavior, which is to consult the
+ <xref linkend="guc-default-toast-compression"/> setting at the time of
+ data insertion to determine the method to use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INHERITS ( <replaceable>parent_table</replaceable> [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ The optional <literal>INHERITS</literal> clause specifies a list of
+ tables from which the new table automatically inherits all
+ columns. Parent tables can be plain tables or foreign tables.
+ </para>
+
+ <para>
+ Use of <literal>INHERITS</literal> creates a persistent relationship
+ between the new child table and its parent table(s). Schema
+ modifications to the parent(s) normally propagate to children
+ as well, and by default the data of the child table is included in
+ scans of the parent(s).
+ </para>
+
+ <para>
+ If the same column name exists in more than one parent
+ table, an error is reported unless the data types of the columns
+ match in each of the parent tables. If there is no conflict,
+ then the duplicate columns are merged to form a single column in
+ the new table. If the column name list of the new table
+ contains a column name that is also inherited, the data type must
+ likewise match the inherited column(s), and the column
+ definitions are merged into one. If the
+ new table explicitly specifies a default value for the column,
+ this default overrides any defaults from inherited declarations
+ of the column. Otherwise, any parents that specify default
+ values for the column must all specify the same default, or an
+ error will be reported.
+ </para>
+
+ <para>
+ <literal>CHECK</literal> constraints are merged in essentially the same way as
+ columns: if multiple parent tables and/or the new table definition
+ contain identically-named <literal>CHECK</literal> constraints, these
+ constraints must all have the same check expression, or an error will be
+ reported. Constraints having the same name and expression will
+ be merged into one copy. A constraint marked <literal>NO INHERIT</literal> in a
+ parent will not be considered. Notice that an unnamed <literal>CHECK</literal>
+ constraint in the new table will never be merged, since a unique name
+ will always be chosen for it.
+ </para>
+
+ <para>
+ Column <literal>STORAGE</literal> settings are also copied from parent tables.
+ </para>
+
+ <para>
+ If a column in the parent table is an identity column, that property is
+ not inherited. A column in the child table can be declared identity
+ column if desired.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [, ...] ) </literal></term>
+ <listitem>
+ <para>
+ The optional <literal>PARTITION BY</literal> clause specifies a strategy
+ of partitioning the table. The table thus created is called a
+ <firstterm>partitioned</firstterm> table. The parenthesized list of
+ columns or expressions forms the <firstterm>partition key</firstterm>
+ for the table. When using range or hash partitioning, the partition key
+ can include multiple columns or expressions (up to 32, but this limit can
+ be altered when building <productname>PostgreSQL</productname>), but for
+ list partitioning, the partition key must consist of a single column or
+ expression.
+ </para>
+
+ <para>
+ Range and list partitioning require a btree operator class, while hash
+ partitioning requires a hash operator class. If no operator class is
+ specified explicitly, the default operator class of the appropriate
+ type will be used; if no default operator class exists, an error will
+ be raised. When hash partitioning is used, the operator class used
+ must implement support function 2 (see <xref linkend="xindex-support"/>
+ for details).
+ </para>
+
+ <para>
+ A partitioned table is divided into sub-tables (called partitions),
+ which are created using separate <literal>CREATE TABLE</literal> commands.
+ The partitioned table is itself empty. A data row inserted into the
+ table is routed to a partition based on the value of columns or
+ expressions in the partition key. If no existing partition matches
+ the values in the new row, an error will be reported.
+ </para>
+
+ <para>
+ Partitioned tables do not support <literal>EXCLUDE</literal> constraints;
+ however, you can define these constraints on individual partitions.
+ </para>
+
+ <para>
+ See <xref linkend="ddl-partitioning"/> for more discussion on table
+ partitioning.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createtable-partition">
+ <term><literal>PARTITION OF <replaceable class="parameter">parent_table</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }</literal></term>
+ <listitem>
+ <para>
+ Creates the table as a <firstterm>partition</firstterm> of the specified
+ parent table. The table can be created either as a partition for specific
+ values using <literal>FOR VALUES</literal> or as a default partition
+ using <literal>DEFAULT</literal>. Any indexes, constraints and
+ user-defined row-level triggers that exist in the parent table are cloned
+ on the new partition.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">partition_bound_spec</replaceable>
+ must correspond to the partitioning method and partition key of the
+ parent table, and must not overlap with any existing partition of that
+ parent. The form with <literal>IN</literal> is used for list partitioning,
+ the form with <literal>FROM</literal> and <literal>TO</literal> is used
+ for range partitioning, and the form with <literal>WITH</literal> is used
+ for hash partitioning.
+ </para>
+
+ <para>
+ <replaceable class="parameter">partition_bound_expr</replaceable> is
+ any variable-free expression (subqueries, window functions, aggregate
+ functions, and set-returning functions are not allowed). Its data type
+ must match the data type of the corresponding partition key column.
+ The expression is evaluated once at table creation time, so it can
+ even contain volatile expressions such as
+ <literal><function>CURRENT_TIMESTAMP</function></literal>.
+ </para>
+
+ <para>
+ When creating a list partition, <literal>NULL</literal> can be
+ specified to signify that the partition allows the partition key
+ column to be null. However, there cannot be more than one such
+ list partition for a given parent table. <literal>NULL</literal>
+ cannot be specified for range partitions.
+ </para>
+
+ <para>
+ When creating a range partition, the lower bound specified with
+ <literal>FROM</literal> is an inclusive bound, whereas the upper
+ bound specified with <literal>TO</literal> is an exclusive bound.
+ That is, the values specified in the <literal>FROM</literal> list
+ are valid values of the corresponding partition key columns for this
+ partition, whereas those in the <literal>TO</literal> list are
+ not. Note that this statement must be understood according to the
+ rules of row-wise comparison (<xref linkend="row-wise-comparison"/>).
+ For example, given <literal>PARTITION BY RANGE (x,y)</literal>, a partition
+ bound <literal>FROM (1, 2) TO (3, 4)</literal>
+ allows <literal>x=1</literal> with any <literal>y&gt;=2</literal>,
+ <literal>x=2</literal> with any non-null <literal>y</literal>,
+ and <literal>x=3</literal> with any <literal>y&lt;4</literal>.
+ </para>
+
+ <para>
+ The special values <literal>MINVALUE</literal> and <literal>MAXVALUE</literal>
+ may be used when creating a range partition to indicate that there
+ is no lower or upper bound on the column's value. For example, a
+ partition defined using <literal>FROM (MINVALUE) TO (10)</literal> allows
+ any values less than 10, and a partition defined using
+ <literal>FROM (10) TO (MAXVALUE)</literal> allows any values greater than
+ or equal to 10.
+ </para>
+
+ <para>
+ When creating a range partition involving more than one column, it
+ can also make sense to use <literal>MAXVALUE</literal> as part of the lower
+ bound, and <literal>MINVALUE</literal> as part of the upper bound. For
+ example, a partition defined using
+ <literal>FROM (0, MAXVALUE) TO (10, MAXVALUE)</literal> allows any rows
+ where the first partition key column is greater than 0 and less than
+ or equal to 10. Similarly, a partition defined using
+ <literal>FROM ('a', MINVALUE) TO ('b', MINVALUE)</literal> allows any rows
+ where the first partition key column starts with "a".
+ </para>
+
+ <para>
+ Note that if <literal>MINVALUE</literal> or <literal>MAXVALUE</literal> is used for
+ one column of a partitioning bound, the same value must be used for all
+ subsequent columns. For example, <literal>(10, MINVALUE, 0)</literal> is not
+ a valid bound; you should write <literal>(10, MINVALUE, MINVALUE)</literal>.
+ </para>
+
+ <para>
+ Also note that some element types, such as <literal>timestamp</literal>,
+ have a notion of "infinity", which is just another value that can
+ be stored. This is different from <literal>MINVALUE</literal> and
+ <literal>MAXVALUE</literal>, which are not real values that can be stored,
+ but rather they are ways of saying that the value is unbounded.
+ <literal>MAXVALUE</literal> can be thought of as being greater than any
+ other value, including "infinity" and <literal>MINVALUE</literal> as being
+ less than any other value, including "minus infinity". Thus the range
+ <literal>FROM ('infinity') TO (MAXVALUE)</literal> is not an empty range; it
+ allows precisely one value to be stored &mdash; "infinity".
+ </para>
+
+ <para>
+ If <literal>DEFAULT</literal> is specified, the table will be
+ created as the default partition of the parent table. This option
+ is not available for hash-partitioned tables. A partition key value
+ not fitting into any other partition of the given parent will be
+ routed to the default partition.
+ </para>
+
+ <para>
+ When a table has an existing <literal>DEFAULT</literal> partition and
+ a new partition is added to it, the default partition must
+ be scanned to verify that it does not contain any rows which properly
+ belong in the new partition. If the default partition contains a
+ large number of rows, this may be slow. The scan will be skipped if
+ the default partition is a foreign table or if it has a constraint which
+ proves that it cannot contain rows which should be placed in the new
+ partition.
+ </para>
+
+ <para>
+ When creating a hash partition, a modulus and remainder must be specified.
+ The modulus must be a positive integer, and the remainder must be a
+ non-negative integer less than the modulus. Typically, when initially
+ setting up a hash-partitioned table, you should choose a modulus equal to
+ the number of partitions and assign every table the same modulus and a
+ different remainder (see examples, below). However, it is not required
+ that every partition have the same modulus, only that every modulus which
+ occurs among the partitions of a hash-partitioned table is a factor of the
+ next larger modulus. This allows the number of partitions to be increased
+ incrementally without needing to move all the data at once. For example,
+ suppose you have a hash-partitioned table with 8 partitions, each of which
+ has modulus 8, but find it necessary to increase the number of partitions
+ to 16. You can detach one of the modulus-8 partitions, create two new
+ modulus-16 partitions covering the same portion of the key space (one with
+ a remainder equal to the remainder of the detached partition, and the
+ other with a remainder equal to that value plus 8), and repopulate them
+ with data. You can then repeat this -- perhaps at a later time -- for
+ each modulus-8 partition until none remain. While this may still involve
+ a large amount of data movement at each step, it is still better than
+ having to create a whole new table and move all the data at once.
+ </para>
+
+ <para>
+ A partition must have the same column names and types as the partitioned
+ table to which it belongs. Modifications to the column names or types of
+ a partitioned table will automatically propagate to all partitions.
+ <literal>CHECK</literal> constraints will be inherited automatically by
+ every partition, but an individual partition may specify additional
+ <literal>CHECK</literal> constraints; additional constraints with the
+ same name and condition as in the parent will be merged with the parent
+ constraint. Defaults may be specified separately for each partition.
+ But note that a partition's default value is not applied when inserting
+ a tuple through a partitioned table.
+ </para>
+
+ <para>
+ Rows inserted into a partitioned table will be automatically routed to
+ the correct partition. If no suitable partition exists, an error will
+ occur.
+ </para>
+
+ <para>
+ Operations such as <command>TRUNCATE</command>
+ which normally affect a table and all of its
+ inheritance children will cascade to all partitions, but may also be
+ performed on an individual partition.
+ </para>
+
+ <para>
+ Note that creating a partition using <literal>PARTITION OF</literal>
+ requires taking an <literal>ACCESS EXCLUSIVE</literal> lock on the
+ parent partitioned table. Likewise, dropping a partition
+ with <command>DROP TABLE</command> requires taking
+ an <literal>ACCESS EXCLUSIVE</literal> lock on the parent table.
+ It is possible to use <link linkend="sql-altertable"><command>ALTER
+ TABLE ATTACH/DETACH PARTITION</command></link> to perform these
+ operations with a weaker lock, thus reducing interference with
+ concurrent operations on the partitioned table.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LIKE <replaceable>source_table</replaceable> [ <replaceable>like_option</replaceable> ... ]</literal></term>
+ <listitem>
+ <para>
+ The <literal>LIKE</literal> clause specifies a table from which
+ the new table automatically copies all column names, their data types,
+ and their not-null constraints.
+ </para>
+ <para>
+ Unlike <literal>INHERITS</literal>, the new table and original table
+ are completely decoupled after creation is complete. Changes to the
+ original table will not be applied to the new table, and it is not
+ possible to include data of the new table in scans of the original
+ table.
+ </para>
+ <para>
+ Also unlike <literal>INHERITS</literal>, columns and
+ constraints copied by <literal>LIKE</literal> are not merged with similarly
+ named columns and constraints.
+ If the same name is specified explicitly or in another
+ <literal>LIKE</literal> clause, an error is signaled.
+ </para>
+ <para>
+ The optional <replaceable>like_option</replaceable> clauses specify
+ which additional properties of the original table to copy. Specifying
+ <literal>INCLUDING</literal> copies the property, specifying
+ <literal>EXCLUDING</literal> omits the property.
+ <literal>EXCLUDING</literal> is the default. If multiple specifications
+ are made for the same kind of object, the last one is used. The
+ available options are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>INCLUDING COMMENTS</literal></term>
+ <listitem>
+ <para>
+ Comments for the copied columns, constraints, and indexes will be
+ copied. The default behavior is to exclude comments, resulting in
+ the copied columns and constraints in the new table having no
+ comments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING COMPRESSION</literal></term>
+ <listitem>
+ <para>
+ Compression method of the columns will be copied. The default
+ behavior is to exclude compression methods, resulting in columns
+ having the default compression method.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING CONSTRAINTS</literal></term>
+ <listitem>
+ <para>
+ <literal>CHECK</literal> constraints will be copied. No distinction
+ is made between column constraints and table constraints. Not-null
+ constraints are always copied to the new table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING DEFAULTS</literal></term>
+ <listitem>
+ <para>
+ Default expressions for the copied column definitions will be
+ copied. Otherwise, default expressions are not copied, resulting in
+ the copied columns in the new table having null defaults. Note that
+ copying defaults that call database-modification functions, such as
+ <function>nextval</function>, may create a functional linkage
+ between the original and new tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING GENERATED</literal></term>
+ <listitem>
+ <para>
+ Any generation expressions of copied column definitions will be
+ copied. By default, new columns will be regular base columns.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING IDENTITY</literal></term>
+ <listitem>
+ <para>
+ Any identity specifications of copied column definitions will be
+ copied. A new sequence is created for each identity column of the
+ new table, separate from the sequences associated with the old
+ table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING INDEXES</literal></term>
+ <listitem>
+ <para>
+ Indexes, <literal>PRIMARY KEY</literal>, <literal>UNIQUE</literal>,
+ and <literal>EXCLUDE</literal> constraints on the original table
+ will be created on the new table. Names for the new indexes and
+ constraints are chosen according to the default rules, regardless of
+ how the originals were named. (This behavior avoids possible
+ duplicate-name failures for the new indexes.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING STATISTICS</literal></term>
+ <listitem>
+ <para>
+ Extended statistics are copied to the new table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING STORAGE</literal></term>
+ <listitem>
+ <para>
+ <literal>STORAGE</literal> settings for the copied column
+ definitions will be copied. The default behavior is to exclude
+ <literal>STORAGE</literal> settings, resulting in the copied columns
+ in the new table having type-specific default settings. For more on
+ <literal>STORAGE</literal> settings, see <xref
+ linkend="storage-toast"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INCLUDING ALL</literal></term>
+ <listitem>
+ <para>
+ <literal>INCLUDING ALL</literal> is an abbreviated form selecting
+ all the available individual options. (It could be useful to write
+ individual <literal>EXCLUDING</literal> clauses after
+ <literal>INCLUDING ALL</literal> to select all but some specific
+ options.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <literal>LIKE</literal> clause can also be used to copy column
+ definitions from views, foreign tables, or composite types.
+ Inapplicable options (e.g., <literal>INCLUDING INDEXES</literal> from
+ a view) are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONSTRAINT <replaceable class="parameter">constraint_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ An optional name for a column or table constraint. If the
+ constraint is violated, the constraint name is present in error messages,
+ so constraint names like <literal>col must be positive</literal> can be used
+ to communicate helpful constraint information to client applications.
+ (Double-quotes are needed to specify constraint names that contain spaces.)
+ If a constraint name is not specified, the system generates a name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOT NULL</literal></term>
+ <listitem>
+ <para>
+ The column is not allowed to contain null values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULL</literal></term>
+ <listitem>
+ <para>
+ The column is allowed to contain null values. This is the default.
+ </para>
+
+ <para>
+ This clause is only provided for compatibility with
+ non-standard SQL databases. Its use is discouraged in new
+ applications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CHECK ( <replaceable class="parameter">expression</replaceable> ) [ NO INHERIT ] </literal></term>
+ <listitem>
+ <para>
+ The <literal>CHECK</literal> clause specifies an expression producing a
+ Boolean result which new or updated rows must satisfy for an
+ insert or update operation to succeed. Expressions evaluating
+ to TRUE or UNKNOWN succeed. Should any row of an insert or
+ update operation produce a FALSE result, an error exception is
+ raised and the insert or update does not alter the database. A
+ check constraint specified as a column constraint should
+ reference that column's value only, while an expression
+ appearing in a table constraint can reference multiple columns.
+ </para>
+
+ <para>
+ Currently, <literal>CHECK</literal> expressions cannot contain
+ subqueries nor refer to variables other than columns of the
+ current row (see <xref linkend="ddl-constraints-check-constraints"/>).
+ The system column <literal>tableoid</literal>
+ may be referenced, but not any other system column.
+ </para>
+
+ <para>
+ A constraint marked with <literal>NO INHERIT</literal> will not propagate to
+ child tables.
+ </para>
+
+ <para>
+ When a table has multiple <literal>CHECK</literal> constraints,
+ they will be tested for each row in alphabetical order by name,
+ after checking <literal>NOT NULL</literal> constraints.
+ (<productname>PostgreSQL</productname> versions before 9.5 did not honor any
+ particular firing order for <literal>CHECK</literal> constraints.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT
+ <replaceable>default_expr</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <literal>DEFAULT</literal> clause assigns a default data value for
+ the column whose column definition it appears within. The value
+ is any variable-free expression (in particular, cross-references
+ to other columns in the current table are not allowed). Subqueries
+ are not allowed either. The data type of the default expression must
+ match the data type of the column.
+ </para>
+
+ <para>
+ The default expression will be used in any insert operation that
+ does not specify a value for the column. If there is no default
+ for a column, then the default is null.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>GENERATED ALWAYS AS ( <replaceable>generation_expr</replaceable> ) STORED</literal><indexterm><primary>generated column</primary></indexterm></term>
+ <listitem>
+ <para>
+ This clause creates the column as a <firstterm>generated
+ column</firstterm>. The column cannot be written to, and when read the
+ result of the specified expression will be returned.
+ </para>
+
+ <para>
+ The keyword <literal>STORED</literal> is required to signify that the
+ column will be computed on write and will be stored on disk.
+ </para>
+
+ <para>
+ The generation expression can refer to other columns in the table, but
+ not other generated columns. Any functions and operators used must be
+ immutable. References to other tables are not allowed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( <replaceable>sequence_options</replaceable> ) ]</literal></term>
+ <listitem>
+ <para>
+ This clause creates the column as an <firstterm>identity
+ column</firstterm>. It will have an implicit sequence attached to it
+ and the column in new rows will automatically have values from the
+ sequence assigned to it.
+ Such a column is implicitly <literal>NOT NULL</literal>.
+ </para>
+
+ <para>
+ The clauses <literal>ALWAYS</literal> and <literal>BY DEFAULT</literal>
+ determine how explicitly user-specified values are handled in
+ <command>INSERT</command> and <command>UPDATE</command> commands.
+ </para>
+
+ <para>
+ In an <command>INSERT</command> command, if <literal>ALWAYS</literal> is
+ selected, a user-specified value is only accepted if the
+ <command>INSERT</command> statement specifies <literal>OVERRIDING SYSTEM
+ VALUE</literal>. If <literal>BY DEFAULT</literal> is selected, then the
+ user-specified value takes precedence. See <xref linkend="sql-insert"/>
+ for details. (In the <command>COPY</command> command, user-specified
+ values are always used regardless of this setting.)
+ </para>
+
+ <para>
+ In an <command>UPDATE</command> command, if <literal>ALWAYS</literal> is
+ selected, any update of the column to any value other than
+ <literal>DEFAULT</literal> will be rejected. If <literal>BY
+ DEFAULT</literal> is selected, the column can be updated normally.
+ (There is no <literal>OVERRIDING</literal> clause for the
+ <command>UPDATE</command> command.)
+ </para>
+
+ <para>
+ The optional <replaceable>sequence_options</replaceable> clause can be
+ used to override the options of the sequence.
+ See <xref linkend="sql-createsequence"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>UNIQUE [ NULLS [ NOT ] DISTINCT ]</literal> (column constraint)</term>
+ <term><literal>UNIQUE [ NULLS [ NOT ] DISTINCT ] ( <replaceable class="parameter">column_name</replaceable> [, ... ] )</literal>
+ <optional> <literal>INCLUDE ( <replaceable class="parameter">column_name</replaceable> [, ...])</literal> </optional> (table constraint)</term>
+
+ <listitem>
+ <para>
+ The <literal>UNIQUE</literal> constraint specifies that a
+ group of one or more columns of a table can contain
+ only unique values. The behavior of a unique table constraint
+ is the same as that of a unique column constraint, with the
+ additional capability to span multiple columns. The constraint
+ therefore enforces that any two rows must differ in at least one
+ of these columns.
+ </para>
+
+ <para>
+ For the purpose of a unique constraint, null values are not
+ considered equal, unless <literal>NULLS NOT DISTINCT</literal> is
+ specified.
+ </para>
+
+ <para>
+ Each unique constraint should name a set of columns that is
+ different from the set of columns named by any other unique or
+ primary key constraint defined for the table. (Otherwise, redundant
+ unique constraints will be discarded.)
+ </para>
+
+ <para>
+ When establishing a unique constraint for a multi-level partition
+ hierarchy, all the columns in the partition key of the target
+ partitioned table, as well as those of all its descendant partitioned
+ tables, must be included in the constraint definition.
+ </para>
+
+ <para>
+ Adding a unique constraint will automatically create a unique btree
+ index on the column or group of columns used in the constraint.
+ </para>
+
+ <para>
+ The optional <literal>INCLUDE</literal> clause adds to that index
+ one or more columns that are simply <quote>payload</quote>: uniqueness
+ is not enforced on them, and the index cannot be searched on the basis
+ of those columns. However they can be retrieved by an index-only scan.
+ Note that although the constraint is not enforced on included columns,
+ it still depends on them. Consequently, some operations on such columns
+ (e.g., <literal>DROP COLUMN</literal>) can cause cascaded constraint and
+ index deletion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PRIMARY KEY</literal> (column constraint)</term>
+ <term><literal>PRIMARY KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] )</literal>
+ <optional> <literal>INCLUDE ( <replaceable class="parameter">column_name</replaceable> [, ...])</literal> </optional> (table constraint)</term>
+ <listitem>
+ <para>
+ The <literal>PRIMARY KEY</literal> constraint specifies that a column or
+ columns of a table can contain only unique (non-duplicate), nonnull
+ values. Only one primary key can be specified for a table, whether as a
+ column constraint or a table constraint.
+ </para>
+
+ <para>
+ The primary key constraint should name a set of columns that is
+ different from the set of columns named by any unique
+ constraint defined for the same table. (Otherwise, the unique
+ constraint is redundant and will be discarded.)
+ </para>
+
+ <para>
+ <literal>PRIMARY KEY</literal> enforces the same data constraints as
+ a combination of <literal>UNIQUE</literal> and <literal>NOT
+ NULL</literal>. However,
+ identifying a set of columns as the primary key also provides metadata
+ about the design of the schema, since a primary key implies that other
+ tables can rely on this set of columns as a unique identifier for rows.
+ </para>
+
+ <para>
+ When placed on a partitioned table, <literal>PRIMARY KEY</literal>
+ constraints share the restrictions previously described
+ for <literal>UNIQUE</literal> constraints.
+ </para>
+
+ <para>
+ Adding a <literal>PRIMARY KEY</literal> constraint will automatically
+ create a unique btree index on the column or group of columns used in the
+ constraint.
+ </para>
+
+ <para>
+ The optional <literal>INCLUDE</literal> clause adds to that index
+ one or more columns that are simply <quote>payload</quote>: uniqueness
+ is not enforced on them, and the index cannot be searched on the basis
+ of those columns. However they can be retrieved by an index-only scan.
+ Note that although the constraint is not enforced on included columns,
+ it still depends on them. Consequently, some operations on such columns
+ (e.g., <literal>DROP COLUMN</literal>) can cause cascaded constraint and
+ index deletion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createtable-exclude">
+ <term><literal>EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ]</literal></term>
+ <listitem>
+ <para>
+ The <literal>EXCLUDE</literal> clause defines an exclusion
+ constraint, which guarantees that if
+ any two rows are compared on the specified column(s) or
+ expression(s) using the specified operator(s), not all of these
+ comparisons will return <literal>TRUE</literal>. If all of the
+ specified operators test for equality, this is equivalent to a
+ <literal>UNIQUE</literal> constraint, although an ordinary unique constraint
+ will be faster. However, exclusion constraints can specify
+ constraints that are more general than simple equality.
+ For example, you can specify a constraint that
+ no two rows in the table contain overlapping circles
+ (see <xref linkend="datatype-geometric"/>) by using the
+ <literal>&amp;&amp;</literal> operator.
+ </para>
+
+ <para>
+ Exclusion constraints are implemented using
+ an index, so each specified operator must be associated with an
+ appropriate operator class
+ (see <xref linkend="indexes-opclass"/>) for the index access
+ method <replaceable>index_method</replaceable>.
+ The operators are required to be commutative.
+ Each <replaceable class="parameter">exclude_element</replaceable>
+ can optionally specify an operator class and/or ordering options;
+ these are described fully under
+ <xref linkend="sql-createindex"/>.
+ </para>
+
+ <para>
+ The access method must support <literal>amgettuple</literal> (see <xref
+ linkend="indexam"/>); at present this means <acronym>GIN</acronym>
+ cannot be used. Although it's allowed, there is little point in using
+ B-tree or hash indexes with an exclusion constraint, because this
+ does nothing that an ordinary unique constraint doesn't do better.
+ So in practice the access method will always be <acronym>GiST</acronym> or
+ <acronym>SP-GiST</acronym>.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">predicate</replaceable> allows you to specify an
+ exclusion constraint on a subset of the table; internally this creates a
+ partial index. Note that parentheses are required around the predicate.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> ) ] [ MATCH <replaceable class="parameter">matchtype</replaceable> ] [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ] [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ]</literal> (column constraint)</term>
+
+ <term><literal>FOREIGN KEY ( <replaceable class="parameter">column_name</replaceable> [, ... ] )
+ REFERENCES <replaceable class="parameter">reftable</replaceable> [ ( <replaceable class="parameter">refcolumn</replaceable> [, ... ] ) ]
+ [ MATCH <replaceable class="parameter">matchtype</replaceable> ]
+ [ ON DELETE <replaceable class="parameter">referential_action</replaceable> ]
+ [ ON UPDATE <replaceable class="parameter">referential_action</replaceable> ]</literal>
+ (table constraint)</term>
+
+ <listitem>
+ <para>
+ These clauses specify a foreign key constraint, which requires
+ that a group of one or more columns of the new table must only
+ contain values that match values in the referenced
+ column(s) of some row of the referenced table. If the <replaceable
+ class="parameter">refcolumn</replaceable> list is omitted, the
+ primary key of the <replaceable class="parameter">reftable</replaceable>
+ is used. The referenced columns must be the columns of a non-deferrable
+ unique or primary key constraint in the referenced table. The user
+ must have <literal>REFERENCES</literal> permission on the referenced table
+ (either the whole table, or the specific referenced columns). The
+ addition of a foreign key constraint requires a
+ <literal>SHARE ROW EXCLUSIVE</literal> lock on the referenced table.
+ Note that foreign key constraints cannot be defined between temporary
+ tables and permanent tables.
+ </para>
+
+ <para>
+ A value inserted into the referencing column(s) is matched against the
+ values of the referenced table and referenced columns using the
+ given match type. There are three match types: <literal>MATCH
+ FULL</literal>, <literal>MATCH PARTIAL</literal>, and <literal>MATCH
+ SIMPLE</literal> (which is the default). <literal>MATCH
+ FULL</literal> will not allow one column of a multicolumn foreign key
+ to be null unless all foreign key columns are null; if they are all
+ null, the row is not required to have a match in the referenced table.
+ <literal>MATCH SIMPLE</literal> allows any of the foreign key columns
+ to be null; if any of them are null, the row is not required to have a
+ match in the referenced table.
+ <literal>MATCH PARTIAL</literal> is not yet implemented.
+ (Of course, <literal>NOT NULL</literal> constraints can be applied to the
+ referencing column(s) to prevent these cases from arising.)
+ </para>
+
+ <para>
+ In addition, when the data in the referenced columns is changed,
+ certain actions are performed on the data in this table's
+ columns. The <literal>ON DELETE</literal> clause specifies the
+ action to perform when a referenced row in the referenced table is
+ being deleted. Likewise, the <literal>ON UPDATE</literal>
+ clause specifies the action to perform when a referenced column
+ in the referenced table is being updated to a new value. If the
+ row is updated, but the referenced column is not actually
+ changed, no action is done. Referential actions other than the
+ <literal>NO ACTION</literal> check cannot be deferred, even if
+ the constraint is declared deferrable. There are the following possible
+ actions for each clause:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>NO ACTION</literal></term>
+ <listitem>
+ <para>
+ Produce an error indicating that the deletion or update
+ would create a foreign key constraint violation.
+ If the constraint is deferred, this
+ error will be produced at constraint check time if there still
+ exist any referencing rows. This is the default action.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Produce an error indicating that the deletion or update
+ would create a foreign key constraint violation.
+ This is the same as <literal>NO ACTION</literal> except that
+ the check is not deferrable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Delete any rows referencing the deleted row, or update the
+ values of the referencing column(s) to the new values of the
+ referenced columns, respectively.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET NULL [ ( <replaceable>column_name</replaceable> [, ... ] ) ]</literal></term>
+ <listitem>
+ <para>
+ Set all of the referencing columns, or a specified subset of the
+ referencing columns, to null. A subset of columns can only be
+ specified for <literal>ON DELETE</literal> actions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SET DEFAULT [ ( <replaceable>column_name</replaceable> [, ... ] ) ]</literal></term>
+ <listitem>
+ <para>
+ Set all of the referencing columns, or a specified subset of the
+ referencing columns, to their default values. A subset of columns
+ can only be specified for <literal>ON DELETE</literal> actions.
+ (There must be a row in the referenced table matching the default
+ values, if they are not null, or the operation will fail.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ If the referenced column(s) are changed frequently, it might be wise to
+ add an index to the referencing column(s) so that referential actions
+ associated with the foreign key constraint can be performed more
+ efficiently.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFERRABLE</literal></term>
+ <term><literal>NOT DEFERRABLE</literal></term>
+ <listitem>
+ <para>
+ This controls whether the constraint can be deferred. A
+ constraint that is not deferrable will be checked immediately
+ after every command. Checking of constraints that are
+ deferrable can be postponed until the end of the transaction
+ (using the <link linkend="sql-set-constraints"><command>SET CONSTRAINTS</command></link> command).
+ <literal>NOT DEFERRABLE</literal> is the default.
+ Currently, only <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>,
+ <literal>EXCLUDE</literal>, and
+ <literal>REFERENCES</literal> (foreign key) constraints accept this
+ clause. <literal>NOT NULL</literal> and <literal>CHECK</literal> constraints are not
+ deferrable. Note that deferrable constraints cannot be used as
+ conflict arbitrators in an <command>INSERT</command> statement that
+ includes an <literal>ON CONFLICT DO UPDATE</literal> clause.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INITIALLY IMMEDIATE</literal></term>
+ <term><literal>INITIALLY DEFERRED</literal></term>
+ <listitem>
+ <para>
+ If a constraint is deferrable, this clause specifies the default
+ time to check the constraint. If the constraint is
+ <literal>INITIALLY IMMEDIATE</literal>, it is checked after each
+ statement. This is the default. If the constraint is
+ <literal>INITIALLY DEFERRED</literal>, it is checked only at the
+ end of the transaction. The constraint check time can be
+ altered with the <link linkend="sql-set-constraints"><command>SET CONSTRAINTS</command></link> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createtable-method">
+ <term><literal>USING <replaceable class="parameter">method</replaceable></literal></term>
+ <listitem>
+ <para>
+ This optional clause specifies the table access method to use to store
+ the contents for the new table; the method needs be an access method of
+ type <literal>TABLE</literal>. See <xref linkend="tableam"/> for more
+ information. If this option is not specified, the default table access
+ method is chosen for the new table. See <xref
+ linkend="guc-default-table-access-method"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies optional storage parameters for a table or index;
+ see <xref linkend="sql-createtable-storage-parameters"/> below for more
+ information. For backward-compatibility the <literal>WITH</literal>
+ clause for a table can also include <literal>OIDS=FALSE</literal> to
+ specify that rows of the new table should not contain OIDs (object
+ identifiers), <literal>OIDS=TRUE</literal> is not supported anymore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITHOUT OIDS</literal></term>
+ <listitem>
+ <para>
+ This is backward-compatible syntax for declaring a table
+ <literal>WITHOUT OIDS</literal>, creating a table <literal>WITH
+ OIDS</literal> is not supported anymore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ON COMMIT</literal></term>
+ <listitem>
+ <para>
+ The behavior of temporary tables at the end of a transaction
+ block can be controlled using <literal>ON COMMIT</literal>.
+ The three options are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>PRESERVE ROWS</literal></term>
+ <listitem>
+ <para>
+ No special action is taken at the ends of transactions.
+ This is the default behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DELETE ROWS</literal></term>
+ <listitem>
+ <para>
+ All rows in the temporary table will be deleted at the end
+ of each transaction block. Essentially, an automatic <link
+ linkend="sql-truncate"><command>TRUNCATE</command></link> is done
+ at each commit. When used on a partitioned table, this
+ is not cascaded to its partitions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP</literal></term>
+ <listitem>
+ <para>
+ The temporary table will be dropped at the end of the current
+ transaction block. When used on a partitioned table, this action
+ drops its partitions and when used on tables with inheritance
+ children, it drops the dependent children.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-createtable-tablespace">
+ <term><literal>TABLESPACE <replaceable class="parameter">tablespace_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <replaceable class="parameter">tablespace_name</replaceable> is the name
+ of the tablespace in which the new table is to be created.
+ If not specified,
+ <xref linkend="guc-default-tablespace"/> is consulted, or
+ <xref linkend="guc-temp-tablespaces"/> if the table is temporary. For
+ partitioned tables, since no storage is required for the table itself,
+ the tablespace specified overrides <literal>default_tablespace</literal>
+ as the default tablespace to use for any newly created partitions when no
+ other tablespace is explicitly specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USING INDEX TABLESPACE <replaceable class="parameter">tablespace_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ This clause allows selection of the tablespace in which the index
+ associated with a <literal>UNIQUE</literal>, <literal>PRIMARY
+ KEY</literal>, or <literal>EXCLUDE</literal> constraint will be created.
+ If not specified,
+ <xref linkend="guc-default-tablespace"/> is consulted, or
+ <xref linkend="guc-temp-tablespaces"/> if the table is temporary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <refsect2 id="sql-createtable-storage-parameters" xreflabel="Storage Parameters">
+ <title>Storage Parameters</title>
+
+ <indexterm zone="sql-createtable-storage-parameters">
+ <primary>storage parameters</primary>
+ </indexterm>
+
+ <para>
+ The <literal>WITH</literal> clause can specify <firstterm>storage parameters</firstterm>
+ for tables, and for indexes associated with a <literal>UNIQUE</literal>,
+ <literal>PRIMARY KEY</literal>, or <literal>EXCLUDE</literal> constraint.
+ Storage parameters for
+ indexes are documented in <xref linkend="sql-createindex"/>.
+ The storage parameters currently
+ available for tables are listed below. For many of these parameters, as
+ shown, there is an additional parameter with the same name prefixed with
+ <literal>toast.</literal>, which controls the behavior of the
+ table's secondary <acronym>TOAST</acronym> table, if any
+ (see <xref linkend="storage-toast"/> for more information about TOAST).
+ If a table parameter value is set and the
+ equivalent <literal>toast.</literal> parameter is not, the TOAST table
+ will use the table's parameter value.
+ Specifying these parameters for partitioned tables is not supported,
+ but you may specify them for individual leaf partitions.
+ </para>
+
+ <variablelist>
+
+ <varlistentry id="reloption-fillfactor" xreflabel="fillfactor">
+ <term><varname>fillfactor</varname> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>fillfactor</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The fillfactor for a table is a percentage between 10 and 100.
+ 100 (complete packing) is the default. When a smaller fillfactor
+ is specified, <command>INSERT</command> operations pack table pages only
+ to the indicated percentage; the remaining space on each page is
+ reserved for updating rows on that page. This gives <command>UPDATE</command>
+ a chance to place the updated copy of a row on the same page as the
+ original, which is more efficient than placing it on a different
+ page, and makes <link linkend="storage-hot">heap-only tuple
+ updates</link> more likely.
+ For a table whose entries are never updated, complete packing is the
+ best choice, but in heavily updated tables smaller fillfactors are
+ appropriate. This parameter cannot be set for TOAST tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-toast-tuple-target" xreflabel="toast_tuple_target">
+ <term><literal>toast_tuple_target</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>toast_tuple_target</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ The toast_tuple_target specifies the minimum tuple length required before
+ we try to compress and/or move long column values into TOAST tables, and
+ is also the target length we try to reduce the length below once toasting
+ begins. This affects columns marked as External (for move),
+ Main (for compression), or Extended (for both) and applies only to new
+ tuples. There is no effect on existing rows.
+ By default this parameter is set to allow at least 4 tuples per block,
+ which with the default block size will be 2040 bytes. Valid values are
+ between 128 bytes and the (block size - header), by default 8160 bytes.
+ Changing this value may not be useful for very short or very long rows.
+ Note that the default setting is often close to optimal, and
+ it is possible that setting this parameter could have negative
+ effects in some cases.
+ This parameter cannot be set for TOAST tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-parallel-workers" xreflabel="parallel_workers">
+ <term><literal>parallel_workers</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>parallel_workers</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This sets the number of workers that should be used to assist a parallel
+ scan of this table. If not set, the system will determine a value based
+ on the relation size. The actual number of workers chosen by the planner
+ or by utility statements that use parallel scans may be less, for example
+ due to the setting of <xref linkend="guc-max-worker-processes"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-enabled" xreflabel="autovacuum_enabled">
+ <term><literal>autovacuum_enabled</literal>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>autovacuum_enabled</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables the autovacuum daemon for a particular table.
+ If true, the autovacuum daemon will perform automatic <command>VACUUM</command>
+ and/or <command>ANALYZE</command> operations on this table following the rules
+ discussed in <xref linkend="autovacuum"/>.
+ If false, this table will not be autovacuumed, except to prevent
+ transaction ID wraparound. See <xref linkend="vacuum-for-wraparound"/> for
+ more about wraparound prevention.
+ Note that the autovacuum daemon does not run at all (except to prevent
+ transaction ID wraparound) if the <xref linkend="guc-autovacuum"/>
+ parameter is false; setting individual tables' storage parameters does
+ not override that. Therefore there is seldom much point in explicitly
+ setting this storage parameter to <literal>true</literal>, only
+ to <literal>false</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-vacuum-index-cleanup" xreflabel="vacuum_index_cleanup">
+ <term><literal>vacuum_index_cleanup</literal>, <literal>toast.vacuum_index_cleanup</literal> (<type>enum</type>)
+ <indexterm>
+ <primary><varname>vacuum_index_cleanup</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Forces or disables index cleanup when <command>VACUUM</command>
+ is run on this table. The default value is
+ <literal>AUTO</literal>. With <literal>OFF</literal>, index
+ cleanup is disabled, with <literal>ON</literal> it is enabled,
+ and with <literal>AUTO</literal> a decision is made dynamically,
+ each time <command>VACUUM</command> runs. The dynamic behavior
+ allows <command>VACUUM</command> to avoid needlessly scanning
+ indexes to remove very few dead tuples. Forcibly disabling all
+ index cleanup can speed up <command>VACUUM</command> very
+ significantly, but may also lead to severely bloated indexes if
+ table modifications are frequent. The
+ <literal>INDEX_CLEANUP</literal> parameter of <link
+ linkend="sql-vacuum"><command>VACUUM</command></link>, if
+ specified, overrides the value of this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-vacuum-truncate" xreflabel="vacuum_truncate">
+ <term><literal>vacuum_truncate</literal>, <literal>toast.vacuum_truncate</literal> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>vacuum_truncate</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Enables or disables vacuum to try to truncate off any empty pages
+ at the end of this table. The default value is <literal>true</literal>.
+ If <literal>true</literal>, <command>VACUUM</command> and
+ autovacuum do the truncation and the disk space for
+ the truncated pages is returned to the operating system.
+ Note that the truncation requires <literal>ACCESS EXCLUSIVE</literal>
+ lock on the table. The <literal>TRUNCATE</literal> parameter
+ of <link linkend="sql-vacuum"><command>VACUUM</command></link>, if specified, overrides the value
+ of this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-vacuum-threshold" xreflabel="autovacuum_vacuum_threshold">
+ <term><literal>autovacuum_vacuum_threshold</literal>, <literal>toast.autovacuum_vacuum_threshold</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_threshold</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-vacuum-threshold"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-vacuum-scale-factor" xreflabel="autovacuum_vacuum_scale_factor">
+ <term><literal>autovacuum_vacuum_scale_factor</literal>, <literal>toast.autovacuum_vacuum_scale_factor</literal> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_scale_factor</varname> </primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-vacuum-scale-factor"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-vacuum-insert-threshold" xreflabel="autovacuum_vacuum_insert_threshold">
+ <term><literal>autovacuum_vacuum_insert_threshold</literal>, <literal>toast.autovacuum_vacuum_insert_threshold</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_insert_threshold</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-vacuum-insert-threshold"/>
+ parameter. The special value of -1 may be used to disable insert vacuums on the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-vacuum-insert-scale-factor" xreflabel="autovacuum_vacuum_insert_scale_factor">
+ <term><literal>autovacuum_vacuum_insert_scale_factor</literal>, <literal>toast.autovacuum_vacuum_insert_scale_factor</literal> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_insert_scale_factor</varname> </primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-vacuum-insert-scale-factor"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-analyze-threshold" xreflabel="autovacuum_analyze_threshold">
+ <term><literal>autovacuum_analyze_threshold</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_analyze_threshold</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-analyze-threshold"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-analyze-scale-factor" xreflabel="autovacuum_analyze_scale_factor">
+ <term><literal>autovacuum_analyze_scale_factor</literal> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_analyze_scale_factor</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-analyze-scale-factor"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-vacuum-cost-delay" xreflabel="autovacuum_vacuum_cost_delay">
+ <term><literal>autovacuum_vacuum_cost_delay</literal>, <literal>toast.autovacuum_vacuum_cost_delay</literal> (<type>floating point</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_cost_delay</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-vacuum-cost-delay"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-vacuum-cost-limit" xreflabel="autovacuum_vacuum_cost_limit">
+ <term><literal>autovacuum_vacuum_cost_limit</literal>, <literal>toast.autovacuum_vacuum_cost_limit</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_vacuum_cost_limit</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-vacuum-cost-limit"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-freeze-min-age" xreflabel="autovacuum_freeze_min_age">
+ <term><literal>autovacuum_freeze_min_age</literal>, <literal>toast.autovacuum_freeze_min_age</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_freeze_min_age</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-vacuum-freeze-min-age"/>
+ parameter. Note that autovacuum will ignore
+ per-table <literal>autovacuum_freeze_min_age</literal> parameters that are
+ larger than half the
+ system-wide <xref linkend="guc-autovacuum-freeze-max-age"/> setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-freeze-max-age" xreflabel="autovacuum_freeze_max_age">
+ <term><literal>autovacuum_freeze_max_age</literal>, <literal>toast.autovacuum_freeze_max_age</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_freeze_max_age</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-autovacuum-freeze-max-age"/>
+ parameter. Note that autovacuum will ignore
+ per-table <literal>autovacuum_freeze_max_age</literal> parameters that are
+ larger than the system-wide setting (it can only be set smaller).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-freeze-table-age" xreflabel="autovacuum_freeze_table_age">
+ <term><literal>autovacuum_freeze_table_age</literal>, <literal>toast.autovacuum_freeze_table_age</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_freeze_table_age</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-vacuum-freeze-table-age"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-multixact-freeze-min-age" xreflabel="autovacuum_multixact_freeze_min_age">
+ <term><literal>autovacuum_multixact_freeze_min_age</literal>, <literal>toast.autovacuum_multixact_freeze_min_age</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_multixact_freeze_min_age</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-vacuum-multixact-freeze-min-age"/>
+ parameter. Note that autovacuum will ignore
+ per-table <literal>autovacuum_multixact_freeze_min_age</literal> parameters
+ that are larger than half the
+ system-wide <xref linkend="guc-autovacuum-multixact-freeze-max-age"/>
+ setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-multixact-freeze-max-age" xreflabel="autovacuum_multixact_freeze_max_age">
+ <term><literal>autovacuum_multixact_freeze_max_age</literal>, <literal>toast.autovacuum_multixact_freeze_max_age</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_multixact_freeze_max_age</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value
+ for <xref linkend="guc-autovacuum-multixact-freeze-max-age"/> parameter.
+ Note that autovacuum will ignore
+ per-table <literal>autovacuum_multixact_freeze_max_age</literal> parameters
+ that are larger than the system-wide setting (it can only be set
+ smaller).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-autovacuum-multixact-freeze-table-age" xreflabel="autovacuum_multixact_freeze_table_age">
+ <term><literal>autovacuum_multixact_freeze_table_age</literal>, <literal>toast.autovacuum_multixact_freeze_table_age</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>autovacuum_multixact_freeze_table_age</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value
+ for <xref linkend="guc-vacuum-multixact-freeze-table-age"/> parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-log-autovacuum-min-duration" xreflabel="log_autovacuum_min_duration">
+ <term><literal>log_autovacuum_min_duration</literal>, <literal>toast.log_autovacuum_min_duration</literal> (<type>integer</type>)
+ <indexterm>
+ <primary><varname>log_autovacuum_min_duration</varname></primary>
+ <secondary>storage parameter</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Per-table value for <xref linkend="guc-log-autovacuum-min-duration"/>
+ parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="reloption-user-catalog-table" xreflabel="user_catalog_table">
+ <term><literal>user_catalog_table</literal> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>user_catalog_table</varname> storage parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Declare the table as an additional catalog table for purposes of
+ logical replication. See
+ <xref linkend="logicaldecoding-capabilities"/> for details.
+ This parameter cannot be set for TOAST tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </refsect2>
+ </refsect1>
+
+ <refsect1 id="sql-createtable-notes">
+ <title>Notes</title>
+ <para>
+ <productname>PostgreSQL</productname> automatically creates an
+ index for each unique constraint and primary key constraint to
+ enforce uniqueness. Thus, it is not necessary to create an
+ index explicitly for primary key columns. (See <xref
+ linkend="sql-createindex"/> for more information.)
+ </para>
+
+ <para>
+ Unique constraints and primary keys are not inherited in the
+ current implementation. This makes the combination of
+ inheritance and unique constraints rather dysfunctional.
+ </para>
+
+ <para>
+ A table cannot have more than 1600 columns. (In practice, the
+ effective limit is usually lower because of tuple-length constraints.)
+ </para>
+
+ </refsect1>
+
+
+ <refsect1 id="sql-createtable-examples">
+ <title>Examples</title>
+
+ <para>
+ Create table <structname>films</structname> and table
+ <structname>distributors</structname>:
+
+<programlisting>
+CREATE TABLE films (
+ code char(5) CONSTRAINT firstkey PRIMARY KEY,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
+ name varchar(40) NOT NULL CHECK (name &lt;&gt; '')
+);
+</programlisting>
+ </para>
+
+ <para>
+ Create a table with a 2-dimensional array:
+
+<programlisting>
+CREATE TABLE array_int (
+ vector int[][]
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define a unique table constraint for the table
+ <literal>films</literal>. Unique table constraints can be defined
+ on one or more columns of the table:
+
+<programlisting>
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT production UNIQUE(date_prod)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define a check column constraint:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer CHECK (did &gt; 100),
+ name varchar(40)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define a check table constraint:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ CONSTRAINT con1 CHECK (did &gt; 100 AND name &lt;&gt; '')
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define a primary key table constraint for the table
+ <structname>films</structname>:
+
+<programlisting>
+CREATE TABLE films (
+ code char(5),
+ title varchar(40),
+ did integer,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute,
+ CONSTRAINT code_title PRIMARY KEY(code,title)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define a primary key constraint for table
+ <structname>distributors</structname>. The following two examples are
+ equivalent, the first using the table constraint syntax, the second
+ the column constraint syntax:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ PRIMARY KEY(did)
+);
+
+CREATE TABLE distributors (
+ did integer PRIMARY KEY,
+ name varchar(40)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Assign a literal constant default value for the column
+ <literal>name</literal>, arrange for the default value of column
+ <literal>did</literal> to be generated by selecting the next value
+ of a sequence object, and make the default value of
+ <literal>modtime</literal> be the time at which the row is
+ inserted:
+
+<programlisting>
+CREATE TABLE distributors (
+ name varchar(40) DEFAULT 'Luso Films',
+ did integer DEFAULT nextval('distributors_serial'),
+ modtime timestamp DEFAULT current_timestamp
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define two <literal>NOT NULL</literal> column constraints on the table
+ <classname>distributors</classname>, one of which is explicitly
+ given a name:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer CONSTRAINT no_null NOT NULL,
+ name varchar(40) NOT NULL
+);
+</programlisting>
+ </para>
+
+ <para>
+ Define a unique constraint for the <literal>name</literal> column:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40) UNIQUE
+);
+</programlisting>
+
+ The same, specified as a table constraint:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Create the same table, specifying 70% fill factor for both the table
+ and its unique index:
+
+<programlisting>
+CREATE TABLE distributors (
+ did integer,
+ name varchar(40),
+ UNIQUE(name) WITH (fillfactor=70)
+)
+WITH (fillfactor=70);
+</programlisting>
+ </para>
+
+ <para>
+ Create table <structname>circles</structname> with an exclusion
+ constraint that prevents any two circles from overlapping:
+
+<programlisting>
+CREATE TABLE circles (
+ c circle,
+ EXCLUDE USING gist (c WITH &amp;&amp;)
+);
+</programlisting>
+ </para>
+
+ <para>
+ Create table <structname>cinemas</structname> in tablespace <structname>diskvol1</structname>:
+
+<programlisting>
+CREATE TABLE cinemas (
+ id serial,
+ name text,
+ location text
+) TABLESPACE diskvol1;
+</programlisting>
+ </para>
+
+ <para>
+ Create a composite type and a typed table:
+<programlisting>
+CREATE TYPE employee_type AS (name text, salary numeric);
+
+CREATE TABLE employees OF employee_type (
+ PRIMARY KEY (name),
+ salary WITH OPTIONS DEFAULT 1000
+);
+</programlisting></para>
+
+ <para>
+ Create a range partitioned table:
+<programlisting>
+CREATE TABLE measurement (
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (logdate);
+</programlisting></para>
+
+ <para>
+ Create a range partitioned table with multiple columns in the partition key:
+<programlisting>
+CREATE TABLE measurement_year_month (
+ logdate date not null,
+ peaktemp int,
+ unitsales int
+) PARTITION BY RANGE (EXTRACT(YEAR FROM logdate), EXTRACT(MONTH FROM logdate));
+</programlisting></para>
+
+ <para>
+ Create a list partitioned table:
+<programlisting>
+CREATE TABLE cities (
+ city_id bigserial not null,
+ name text not null,
+ population bigint
+) PARTITION BY LIST (left(lower(name), 1));
+</programlisting></para>
+
+ <para>
+ Create a hash partitioned table:
+<programlisting>
+CREATE TABLE orders (
+ order_id bigint not null,
+ cust_id bigint not null,
+ status text
+) PARTITION BY HASH (order_id);
+</programlisting></para>
+
+ <para>
+ Create partition of a range partitioned table:
+<programlisting>
+CREATE TABLE measurement_y2016m07
+ PARTITION OF measurement (
+ unitsales DEFAULT 0
+) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
+</programlisting></para>
+
+ <para>
+ Create a few partitions of a range partitioned table with multiple
+ columns in the partition key:
+<programlisting>
+CREATE TABLE measurement_ym_older
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (MINVALUE, MINVALUE) TO (2016, 11);
+
+CREATE TABLE measurement_ym_y2016m11
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2016, 11) TO (2016, 12);
+
+CREATE TABLE measurement_ym_y2016m12
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2016, 12) TO (2017, 01);
+
+CREATE TABLE measurement_ym_y2017m01
+ PARTITION OF measurement_year_month
+ FOR VALUES FROM (2017, 01) TO (2017, 02);
+</programlisting></para>
+
+ <para>
+ Create partition of a list partitioned table:
+<programlisting>
+CREATE TABLE cities_ab
+ PARTITION OF cities (
+ CONSTRAINT city_id_nonzero CHECK (city_id != 0)
+) FOR VALUES IN ('a', 'b');
+</programlisting></para>
+
+ <para>
+ Create partition of a list partitioned table that is itself further
+ partitioned and then add a partition to it:
+<programlisting>
+CREATE TABLE cities_ab
+ PARTITION OF cities (
+ CONSTRAINT city_id_nonzero CHECK (city_id != 0)
+) FOR VALUES IN ('a', 'b') PARTITION BY RANGE (population);
+
+CREATE TABLE cities_ab_10000_to_100000
+ PARTITION OF cities_ab FOR VALUES FROM (10000) TO (100000);
+</programlisting></para>
+
+ <para>
+ Create partitions of a hash partitioned table:
+<programlisting>
+CREATE TABLE orders_p1 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 0);
+CREATE TABLE orders_p2 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 1);
+CREATE TABLE orders_p3 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 2);
+CREATE TABLE orders_p4 PARTITION OF orders
+ FOR VALUES WITH (MODULUS 4, REMAINDER 3);
+</programlisting></para>
+
+ <para>
+ Create a default partition:
+<programlisting>
+CREATE TABLE cities_partdef
+ PARTITION OF cities DEFAULT;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-createtable-compatibility" xreflabel="Compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>CREATE TABLE</command> command conforms to the
+ <acronym>SQL</acronym> standard, with exceptions listed below.
+ </para>
+
+ <refsect2>
+ <title>Temporary Tables</title>
+
+ <para>
+ Although the syntax of <literal>CREATE TEMPORARY TABLE</literal>
+ resembles that of the SQL standard, the effect is not the same. In the
+ standard,
+ temporary tables are defined just once and automatically exist (starting
+ with empty contents) in every session that needs them.
+ <productname>PostgreSQL</productname> instead
+ requires each session to issue its own <literal>CREATE TEMPORARY
+ TABLE</literal> command for each temporary table to be used. This allows
+ different sessions to use the same temporary table name for different
+ purposes, whereas the standard's approach constrains all instances of a
+ given temporary table name to have the same table structure.
+ </para>
+
+ <para>
+ The standard's definition of the behavior of temporary tables is
+ widely ignored. <productname>PostgreSQL</productname>'s behavior
+ on this point is similar to that of several other SQL databases.
+ </para>
+
+ <para>
+ The SQL standard also distinguishes between global and local temporary
+ tables, where a local temporary table has a separate set of contents for
+ each SQL module within each session, though its definition is still shared
+ across sessions. Since <productname>PostgreSQL</productname> does not
+ support SQL modules, this distinction is not relevant in
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ For compatibility's sake, <productname>PostgreSQL</productname> will
+ accept the <literal>GLOBAL</literal> and <literal>LOCAL</literal> keywords
+ in a temporary table declaration, but they currently have no effect.
+ Use of these keywords is discouraged, since future versions of
+ <productname>PostgreSQL</productname> might adopt a more
+ standard-compliant interpretation of their meaning.
+ </para>
+
+ <para>
+ The <literal>ON COMMIT</literal> clause for temporary tables
+ also resembles the SQL standard, but has some differences.
+ If the <literal>ON COMMIT</literal> clause is omitted, SQL specifies that the
+ default behavior is <literal>ON COMMIT DELETE ROWS</literal>. However, the
+ default behavior in <productname>PostgreSQL</productname> is
+ <literal>ON COMMIT PRESERVE ROWS</literal>. The <literal>ON COMMIT
+ DROP</literal> option does not exist in SQL.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Non-Deferred Uniqueness Constraints</title>
+
+ <para>
+ When a <literal>UNIQUE</literal> or <literal>PRIMARY KEY</literal> constraint is
+ not deferrable, <productname>PostgreSQL</productname> checks for
+ uniqueness immediately whenever a row is inserted or modified.
+ The SQL standard says that uniqueness should be enforced only at
+ the end of the statement; this makes a difference when, for example,
+ a single command updates multiple key values. To obtain
+ standard-compliant behavior, declare the constraint as
+ <literal>DEFERRABLE</literal> but not deferred (i.e., <literal>INITIALLY
+ IMMEDIATE</literal>). Be aware that this can be significantly slower than
+ immediate uniqueness checking.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Column Check Constraints</title>
+
+ <para>
+ The SQL standard says that <literal>CHECK</literal> column constraints
+ can only refer to the column they apply to; only <literal>CHECK</literal>
+ table constraints can refer to multiple columns.
+ <productname>PostgreSQL</productname> does not enforce this
+ restriction; it treats column and table check constraints alike.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>EXCLUDE</literal> Constraint</title>
+
+ <para>
+ The <literal>EXCLUDE</literal> constraint type is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Foreign-Key Constraint Actions</title>
+
+ <para>
+ The ability to specify column lists in the foreign-key actions
+ <literal>SET DEFAULT</literal> and <literal>SET NULL</literal> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>NULL</literal> <quote>Constraint</quote></title>
+
+ <para>
+ The <literal>NULL</literal> <quote>constraint</quote> (actually a
+ non-constraint) is a <productname>PostgreSQL</productname>
+ extension to the SQL standard that is included for compatibility with some
+ other database systems (and for symmetry with the <literal>NOT
+ NULL</literal> constraint). Since it is the default for any
+ column, its presence is simply noise.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Constraint Naming</title>
+
+ <para>
+ The SQL standard says that table and domain constraints must have names
+ that are unique across the schema containing the table or domain.
+ <productname>PostgreSQL</productname> is laxer: it only requires
+ constraint names to be unique across the constraints attached to a
+ particular table or domain. However, this extra freedom does not exist
+ for index-based constraints (<literal>UNIQUE</literal>,
+ <literal>PRIMARY KEY</literal>, and <literal>EXCLUDE</literal>
+ constraints), because the associated index is named the same as the
+ constraint, and index names must be unique across all relations within
+ the same schema.
+ </para>
+
+ <para>
+ Currently, <productname>PostgreSQL</productname> does not record names
+ for <literal>NOT NULL</literal> constraints at all, so they are not
+ subject to the uniqueness restriction. This might change in a future
+ release.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Inheritance</title>
+
+ <para>
+ Multiple inheritance via the <literal>INHERITS</literal> clause is
+ a <productname>PostgreSQL</productname> language extension.
+ SQL:1999 and later define single inheritance using a
+ different syntax and different semantics. SQL:1999-style
+ inheritance is not yet supported by
+ <productname>PostgreSQL</productname>.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Zero-Column Tables</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows a table of no columns
+ to be created (for example, <literal>CREATE TABLE foo();</literal>). This
+ is an extension from the SQL standard, which does not allow zero-column
+ tables. Zero-column tables are not in themselves very useful, but
+ disallowing them creates odd special cases for <command>ALTER TABLE
+ DROP COLUMN</command>, so it seems cleaner to ignore this spec restriction.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Multiple Identity Columns</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows a table to have more than one
+ identity column. The standard specifies that a table can have at most one
+ identity column. This is relaxed mainly to give more flexibility for
+ doing schema changes or migrations. Note that
+ the <command>INSERT</command> command supports only one override clause
+ that applies to the entire statement, so having multiple identity columns
+ with different behaviors is not well supported.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Generated Columns</title>
+
+ <para>
+ The option <literal>STORED</literal> is not standard but is also used by
+ other SQL implementations. The SQL standard does not specify the storage
+ of generated columns.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>LIKE</literal> Clause</title>
+
+ <para>
+ While a <literal>LIKE</literal> clause exists in the SQL standard, many of the
+ options that <productname>PostgreSQL</productname> accepts for it are not
+ in the standard, and some of the standard's options are not implemented
+ by <productname>PostgreSQL</productname>.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>WITH</literal> Clause</title>
+
+ <para>
+ The <literal>WITH</literal> clause is a <productname>PostgreSQL</productname>
+ extension; storage parameters are not in the standard.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Tablespaces</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> concept of tablespaces is not
+ part of the standard. Hence, the clauses <literal>TABLESPACE</literal>
+ and <literal>USING INDEX TABLESPACE</literal> are extensions.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Typed Tables</title>
+
+ <para>
+ Typed tables implement a subset of the SQL standard. According to
+ the standard, a typed table has columns corresponding to the
+ underlying composite type as well as one other column that is
+ the <quote>self-referencing column</quote>.
+ <productname>PostgreSQL</productname> does not support self-referencing
+ columns explicitly.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>PARTITION BY</literal> Clause</title>
+
+ <para>
+ The <literal>PARTITION BY</literal> clause is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>PARTITION OF</literal> Clause</title>
+
+ <para>
+ The <literal>PARTITION OF</literal> clause is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect2>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertable"/></member>
+ <member><xref linkend="sql-droptable"/></member>
+ <member><xref linkend="sql-createtableas"/></member>
+ <member><xref linkend="sql-createtablespace"/></member>
+ <member><xref linkend="sql-createtype"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml
new file mode 100644
index 0000000..8429333
--- /dev/null
+++ b/doc/src/sgml/ref/create_table_as.sgml
@@ -0,0 +1,362 @@
+<!--
+doc/src/sgml/ref/create_table_as.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtableas">
+ <indexterm zone="sql-createtableas">
+ <primary>CREATE TABLE AS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TABLE AS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TABLE AS</refname>
+ <refpurpose>define a new table from the results of a query</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable>table_name</replaceable>
+ [ (<replaceable>column_name</replaceable> [, ...] ) ]
+ [ USING <replaceable class="parameter">method</replaceable> ]
+ [ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
+ [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
+ [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
+ AS <replaceable>query</replaceable>
+ [ WITH [ NO ] DATA ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TABLE AS</command> creates a table and fills it
+ with data computed by a <command>SELECT</command> command.
+ The table columns have the
+ names and data types associated with the output columns of the
+ <command>SELECT</command> (except that you can override the column
+ names by giving an explicit list of new column names).
+ </para>
+
+ <para>
+ <command>CREATE TABLE AS</command> bears some resemblance to
+ creating a view, but it is really quite different: it creates a new
+ table and evaluates the query just once to fill the new table
+ initially. The new table will not track subsequent changes to the
+ source tables of the query. In contrast, a view re-evaluates its
+ defining <command>SELECT</command> statement whenever it is
+ queried.
+ </para>
+
+ <para>
+ <command>CREATE TABLE AS</command> requires <literal>CREATE</literal>
+ privilege on the schema used for the table.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>GLOBAL</literal> or <literal>LOCAL</literal></term>
+ <listitem>
+ <para>
+ Ignored for compatibility. Use of these keywords is deprecated;
+ refer to <xref linkend="sql-createtable"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ If specified, the table is created as a temporary table.
+ Refer to <xref linkend="sql-createtable"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>UNLOGGED</literal></term>
+ <listitem>
+ <para>
+ If specified, the table is created as an unlogged table.
+ Refer to <xref linkend="sql-createtable"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a relation with the same name already
+ exists; simply issue a notice and leave the table unmodified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column in the new table. If column names are not
+ provided, they are taken from the output column names of the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USING <replaceable class="parameter">method</replaceable></literal></term>
+ <listitem>
+ <para>
+ This optional clause specifies the table access method to use to store
+ the contents for the new table; the method needs be an access method of
+ type <literal>TABLE</literal>. See <xref linkend="tableam"/> for more
+ information. If this option is not specified, the default table access
+ method is chosen for the new table. See <xref
+ linkend="guc-default-table-access-method"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies optional storage parameters for the new table;
+ see <xref linkend="sql-createtable-storage-parameters"/> in the
+ <xref linkend="sql-createtable"/> documentation for more
+ information. For backward-compatibility the <literal>WITH</literal>
+ clause for a table can also include <literal>OIDS=FALSE</literal> to
+ specify that rows of the new table should contain no OIDs (object
+ identifiers), <literal>OIDS=TRUE</literal> is not supported anymore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITHOUT OIDS</literal></term>
+ <listitem>
+ <para>
+ This is backward-compatible syntax for declaring a table
+ <literal>WITHOUT OIDS</literal>, creating a table <literal>WITH
+ OIDS</literal> is not supported anymore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ON COMMIT</literal></term>
+ <listitem>
+ <para>
+ The behavior of temporary tables at the end of a transaction
+ block can be controlled using <literal>ON COMMIT</literal>.
+ The three options are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>PRESERVE ROWS</literal></term>
+ <listitem>
+ <para>
+ No special action is taken at the ends of transactions.
+ This is the default behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DELETE ROWS</literal></term>
+ <listitem>
+ <para>
+ All rows in the temporary table will be deleted at the end
+ of each transaction block. Essentially, an automatic <link
+ linkend="sql-truncate"><command>TRUNCATE</command></link> is done
+ at each commit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DROP</literal></term>
+ <listitem>
+ <para>
+ The temporary table will be dropped at the end of the current
+ transaction block.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLESPACE <replaceable class="parameter">tablespace_name</replaceable></literal></term>
+ <listitem>
+ <para>
+ The <replaceable class="parameter">tablespace_name</replaceable> is the name
+ of the tablespace in which the new table is to be created.
+ If not specified,
+ <xref linkend="guc-default-tablespace"/> is consulted, or
+ <xref linkend="guc-temp-tablespaces"/> if the table is temporary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>query</replaceable></term>
+ <listitem>
+ <para>
+ A <link linkend="sql-select"><command>SELECT</command></link>, <link
+ linkend="sql-table"><command>TABLE</command></link>, or <link linkend="sql-values"><command>VALUES</command></link>
+ command, or an <link linkend="sql-execute"><command>EXECUTE</command></link> command that runs a
+ prepared <command>SELECT</command>, <command>TABLE</command>, or
+ <command>VALUES</command> query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH [ NO ] DATA</literal></term>
+ <listitem>
+ <para>
+ This clause specifies whether or not the data produced by the query
+ should be copied into the new table. If not, only the table structure
+ is copied. The default is to copy the data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ This command is functionally similar to <xref
+ linkend="sql-selectinto"/>, but it is
+ preferred since it is less likely to be confused with other uses of
+ the <command>SELECT INTO</command> syntax. Furthermore, <command>CREATE
+ TABLE AS</command> offers a superset of the functionality offered
+ by <command>SELECT INTO</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a new table <literal>films_recent</literal> consisting of only
+ recent entries from the table <literal>films</literal>:
+
+<programlisting>
+CREATE TABLE films_recent AS
+ SELECT * FROM films WHERE date_prod &gt;= '2002-01-01';
+</programlisting>
+ </para>
+
+ <para>
+ To copy a table completely, the short form using
+ the <literal>TABLE</literal> command can also be used:
+
+<programlisting>
+CREATE TABLE films2 AS
+ TABLE films;
+</programlisting>
+ </para>
+
+ <para>
+ Create a new temporary table <literal>films_recent</literal>, consisting of
+ only recent entries from the table <literal>films</literal>, using a
+ prepared statement. The new table will be dropped at commit:
+
+<programlisting>
+PREPARE recentfilms(date) AS
+ SELECT * FROM films WHERE date_prod &gt; $1;
+CREATE TEMP TABLE films_recent ON COMMIT DROP AS
+ EXECUTE recentfilms('2002-01-01');
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE TABLE AS</command> conforms to the <acronym>SQL</acronym>
+ standard. The following are nonstandard extensions:
+
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>
+ The standard requires parentheses around the subquery clause; in
+ <productname>PostgreSQL</productname>, these parentheses are
+ optional.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ In the standard, the <literal>WITH [ NO ] DATA</literal> clause
+ is required; in PostgreSQL it is optional.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><productname>PostgreSQL</productname> handles temporary tables in a way
+ rather different from the standard; see
+ <xref linkend="sql-createtable"/>
+ for details.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <literal>WITH</literal> clause is a <productname>PostgreSQL</productname>
+ extension; storage parameters are not in the standard.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The <productname>PostgreSQL</productname> concept of tablespaces is not
+ part of the standard. Hence, the clause <literal>TABLESPACE</literal>
+ is an extension.
+ </para>
+ </listitem>
+ </itemizedlist></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-creatematerializedview"/></member>
+ <member><xref linkend="sql-createtable"/></member>
+ <member><xref linkend="sql-execute"/></member>
+ <member><xref linkend="sql-select"/></member>
+ <member><xref linkend="sql-selectinto"/></member>
+ <member><xref linkend="sql-values"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml
new file mode 100644
index 0000000..84fa7ee
--- /dev/null
+++ b/doc/src/sgml/ref/create_tablespace.sgml
@@ -0,0 +1,187 @@
+<!--
+doc/src/sgml/ref/create_tablespace.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtablespace">
+ <indexterm zone="sql-createtablespace">
+ <primary>CREATE TABLESPACE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TABLESPACE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TABLESPACE</refname>
+ <refpurpose>define a new tablespace</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TABLESPACE <replaceable class="parameter">tablespace_name</replaceable>
+ [ OWNER { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER } ]
+ LOCATION '<replaceable class="parameter">directory</replaceable>'
+ [ WITH ( <replaceable class="parameter">tablespace_option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TABLESPACE</command> registers a new cluster-wide
+ tablespace. The tablespace name must be distinct from the name of any
+ existing tablespace in the database cluster.
+ </para>
+
+ <para>
+ A tablespace allows superusers to define an alternative location on
+ the file system where the data files containing database objects
+ (such as tables and indexes) can reside.
+ </para>
+
+ <para>
+ A user with appropriate privileges can pass
+ <replaceable class="parameter">tablespace_name</replaceable> to
+ <command>CREATE DATABASE</command>, <command>CREATE TABLE</command>,
+ <command>CREATE INDEX</command> or <command>ADD CONSTRAINT</command> to have the data
+ files for these objects stored within the specified tablespace.
+ </para>
+
+ <warning>
+ <para>
+ A tablespace cannot be used independently of the cluster in which it
+ is defined; see <xref linkend="manage-ag-tablespaces"/>.
+ </para>
+ </warning>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">tablespace_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a tablespace to be created. The name cannot
+ begin with <literal>pg_</literal>, as such names
+ are reserved for system tablespaces.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the user who will own the tablespace. If omitted,
+ defaults to the user executing the command. Only superusers
+ can create tablespaces, but they can assign ownership of tablespaces
+ to non-superusers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">directory</replaceable></term>
+ <listitem>
+ <para>
+ The directory that will be used for the tablespace. The directory
+ must exist (<command>CREATE TABLESPACE</command> will not create it),
+ should be empty, and must be owned by the
+ <productname>PostgreSQL</productname> system user. The directory must be
+ specified by an absolute path name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">tablespace_option</replaceable></term>
+ <listitem>
+ <para>
+ A tablespace parameter to be set or reset. Currently, the only
+ available parameters are <varname>seq_page_cost</varname>,
+ <varname>random_page_cost</varname>, <varname>effective_io_concurrency</varname>
+ and <varname>maintenance_io_concurrency</varname>.
+ Setting these values for a particular tablespace will override the
+ planner's usual estimate of the cost of reading pages from tables in
+ that tablespace, and the executor's prefetching behavior, as established
+ by the configuration parameters of the
+ same name (see <xref linkend="guc-seq-page-cost"/>,
+ <xref linkend="guc-random-page-cost"/>,
+ <xref linkend="guc-effective-io-concurrency"/>,
+ <xref linkend="guc-maintenance-io-concurrency"/>). This may be useful if
+ one tablespace is located on a disk which is faster or slower than the
+ remainder of the I/O subsystem.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Tablespaces are only supported on systems that support symbolic links.
+ </para>
+
+ <para>
+ <command>CREATE TABLESPACE</command> cannot be executed inside a transaction
+ block.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create a tablespace <literal>dbspace</literal> at file system location
+ <literal>/data/dbs</literal>, first create the directory using operating
+ system facilities and set the correct ownership:
+<programlisting>
+mkdir /data/dbs
+chown postgres:postgres /data/dbs
+</programlisting>
+ Then issue the tablespace creation command inside
+ <productname>PostgreSQL</productname>:
+<programlisting>
+CREATE TABLESPACE dbspace LOCATION '/data/dbs';
+</programlisting>
+ </para>
+
+ <para>
+ To create a tablespace owned by a different database user, use a command
+ like this:
+<programlisting>
+CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes';
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE TABLESPACE</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createdatabase"/></member>
+ <member><xref linkend="sql-createtable"/></member>
+ <member><xref linkend="sql-createindex"/></member>
+ <member><xref linkend="sql-droptablespace"/></member>
+ <member><xref linkend="sql-altertablespace"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_transform.sgml b/doc/src/sgml/ref/create_transform.sgml
new file mode 100644
index 0000000..34bdc60
--- /dev/null
+++ b/doc/src/sgml/ref/create_transform.sgml
@@ -0,0 +1,214 @@
+<!--
+doc/src/sgml/ref/create_transform.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtransform">
+ <indexterm zone="sql-createtransform">
+ <primary>CREATE TRANSFORM</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TRANSFORM</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TRANSFORM</refname>
+ <refpurpose>define a new transform</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] TRANSFORM FOR <replaceable>type_name</replaceable> LANGUAGE <replaceable>lang_name</replaceable> (
+ FROM SQL WITH FUNCTION <replaceable>from_sql_function_name</replaceable> [ (<replaceable>argument_type</replaceable> [, ...]) ],
+ TO SQL WITH FUNCTION <replaceable>to_sql_function_name</replaceable> [ (<replaceable>argument_type</replaceable> [, ...]) ]
+);
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-createtransform-description">
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TRANSFORM</command> defines a new transform.
+ <command>CREATE OR REPLACE TRANSFORM</command> will either create a new
+ transform, or replace an existing definition.
+ </para>
+
+ <para>
+ A transform specifies how to adapt a data type to a procedural language.
+ For example, when writing a function in PL/Python using
+ the <type>hstore</type> type, PL/Python has no prior knowledge how to
+ present <type>hstore</type> values in the Python environment. Language
+ implementations usually default to using the text representation, but that
+ is inconvenient when, for example, an associative array or a list would be
+ more appropriate.
+ </para>
+
+ <para>
+ A transform specifies two functions:
+ <itemizedlist>
+ <listitem>
+ <para>
+ A <quote>from SQL</quote> function that converts the type from the SQL
+ environment to the language. This function will be invoked on the
+ arguments of a function written in the language.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A <quote>to SQL</quote> function that converts the type from the
+ language to the SQL environment. This function will be invoked on the
+ return value of a function written in the language.
+ </para>
+ </listitem>
+ </itemizedlist>
+ It is not necessary to provide both of these functions. If one is not
+ specified, the language-specific default behavior will be used if
+ necessary. (To prevent a transformation in a certain direction from
+ happening at all, you could also write a transform function that always
+ errors out.)
+ </para>
+
+ <para>
+ To be able to create a transform, you must own and
+ have <literal>USAGE</literal> privilege on the type, have
+ <literal>USAGE</literal> privilege on the language, and own and
+ have <literal>EXECUTE</literal> privilege on the from-SQL and to-SQL
+ functions, if specified.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>type_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the data type of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>lang_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the language of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable>from_sql_function_name</replaceable>[(<replaceable>argument_type</replaceable> [, ...])]</literal></term>
+
+ <listitem>
+ <para>
+ The name of the function for converting the type from the SQL
+ environment to the language. It must take one argument of
+ type <type>internal</type> and return type <type>internal</type>. The
+ actual argument will be of the type for the transform, and the function
+ should be coded as if it were. (But it is not allowed to declare an
+ SQL-level function returning <type>internal</type> without at
+ least one argument of type <type>internal</type>.) The actual return
+ value will be something specific to the language implementation.
+ If no argument list is specified, the function name must be unique in
+ its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable>to_sql_function_name</replaceable>[(<replaceable>argument_type</replaceable> [, ...])]</literal></term>
+
+ <listitem>
+ <para>
+ The name of the function for converting the type from the language to
+ the SQL environment. It must take one argument of type
+ <type>internal</type> and return the type that is the type for the
+ transform. The actual argument value will be something specific to the
+ language implementation.
+ If no argument list is specified, the function name must be unique in
+ its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createtransform-notes">
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-droptransform"><command>DROP TRANSFORM</command></link> to remove transforms.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtransform-examples">
+ <title>Examples</title>
+
+ <para>
+ To create a transform for type <type>hstore</type> and language
+ <literal>plpython3u</literal>, first set up the type and the language:
+<programlisting>
+CREATE TYPE hstore ...;
+
+CREATE EXTENSION plpython3u;
+</programlisting>
+ Then create the necessary functions:
+<programlisting>
+CREATE FUNCTION hstore_to_plpython(val internal) RETURNS internal
+LANGUAGE C STRICT IMMUTABLE
+AS ...;
+
+CREATE FUNCTION plpython_to_hstore(val internal) RETURNS hstore
+LANGUAGE C STRICT IMMUTABLE
+AS ...;
+</programlisting>
+ And finally create the transform to connect them all together:
+<programlisting>
+CREATE TRANSFORM FOR hstore LANGUAGE plpython3u (
+ FROM SQL WITH FUNCTION hstore_to_plpython(internal),
+ TO SQL WITH FUNCTION plpython_to_hstore(internal)
+);
+</programlisting>
+ In practice, these commands would be wrapped up in an extension.
+ </para>
+
+ <para>
+ The <filename>contrib</filename> section contains a number of extensions
+ that provide transforms, which can serve as real-world examples.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtransform-compat">
+ <title>Compatibility</title>
+
+ <para>
+ This form of <command>CREATE TRANSFORM</command> is a
+ <productname>PostgreSQL</productname> extension. There is a <command>CREATE
+ TRANSFORM</command> command in the <acronym>SQL</acronym> standard, but it
+ is for adapting data types to client languages. That usage is not supported
+ by <productname>PostgreSQL</productname>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtransform-seealso">
+ <title>See Also</title>
+
+ <para>
+ <xref linkend="sql-createfunction"/>,
+ <xref linkend="sql-createlanguage"/>,
+ <xref linkend="sql-createtype"/>,
+ <xref linkend="sql-droptransform"/>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml
new file mode 100644
index 0000000..ee42f41
--- /dev/null
+++ b/doc/src/sgml/ref/create_trigger.sgml
@@ -0,0 +1,777 @@
+<!--
+doc/src/sgml/ref/create_trigger.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtrigger">
+ <indexterm zone="sql-createtrigger">
+ <primary>CREATE TRIGGER</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>transition tables</primary>
+ <seealso>ephemeral named relation</seealso>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TRIGGER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TRIGGER</refname>
+ <refpurpose>define a new trigger</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER <replaceable class="parameter">name</replaceable> { BEFORE | AFTER | INSTEAD OF } { <replaceable class="parameter">event</replaceable> [ OR ... ] }
+ ON <replaceable class="parameter">table_name</replaceable>
+ [ FROM <replaceable class="parameter">referenced_table_name</replaceable> ]
+ [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
+ [ REFERENCING { { OLD | NEW } TABLE [ AS ] <replaceable class="parameter">transition_relation_name</replaceable> } [ ... ] ]
+ [ FOR [ EACH ] { ROW | STATEMENT } ]
+ [ WHEN ( <replaceable class="parameter">condition</replaceable> ) ]
+ EXECUTE { FUNCTION | PROCEDURE } <replaceable class="parameter">function_name</replaceable> ( <replaceable class="parameter">arguments</replaceable> )
+
+<phrase>where <replaceable class="parameter">event</replaceable> can be one of:</phrase>
+
+ INSERT
+ UPDATE [ OF <replaceable class="parameter">column_name</replaceable> [, ... ] ]
+ DELETE
+ TRUNCATE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TRIGGER</command> creates a new trigger.
+ <command>CREATE OR REPLACE TRIGGER</command> will either create a
+ new trigger, or replace an existing trigger. The
+ trigger will be associated with the specified table, view, or foreign table
+ and will execute the specified
+ function <replaceable class="parameter">function_name</replaceable> when
+ certain operations are performed on that table.
+ </para>
+
+ <para>
+ To replace the current definition of an existing trigger, use
+ <command>CREATE OR REPLACE TRIGGER</command>, specifying the existing
+ trigger's name and parent table. All other properties are replaced.
+ </para>
+
+ <para>
+ The trigger can be specified to fire before the
+ operation is attempted on a row (before constraints are checked and
+ the <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> is attempted); or after the operation has
+ completed (after constraints are checked and the
+ <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> has completed); or instead of the operation
+ (in the case of inserts, updates or deletes on a view).
+ If the trigger fires before or instead of the event, the trigger can skip
+ the operation for the current row, or change the row being inserted (for
+ <command>INSERT</command> and <command>UPDATE</command> operations
+ only). If the trigger fires after the event, all changes, including
+ the effects of other triggers, are <quote>visible</quote>
+ to the trigger.
+ </para>
+
+ <para>
+ A trigger that is marked <literal>FOR EACH ROW</literal> is called
+ once for every row that the operation modifies. For example, a
+ <command>DELETE</command> that affects 10 rows will cause any
+ <literal>ON DELETE</literal> triggers on the target relation to be
+ called 10 separate times, once for each deleted row. In contrast, a
+ trigger that is marked <literal>FOR EACH STATEMENT</literal> only
+ executes once for any given operation, regardless of how many rows
+ it modifies (in particular, an operation that modifies zero rows
+ will still result in the execution of any applicable <literal>FOR
+ EACH STATEMENT</literal> triggers).
+ </para>
+
+ <para>
+ Triggers that are specified to fire <literal>INSTEAD OF</literal> the trigger
+ event must be marked <literal>FOR EACH ROW</literal>, and can only be defined
+ on views. <literal>BEFORE</literal> and <literal>AFTER</literal> triggers on a view
+ must be marked as <literal>FOR EACH STATEMENT</literal>.
+ </para>
+
+ <para>
+ In addition, triggers may be defined to fire for
+ <command>TRUNCATE</command>, though only
+ <literal>FOR EACH STATEMENT</literal>.
+ </para>
+
+ <para>
+ The following table summarizes which types of triggers may be used on
+ tables, views, and foreign tables:
+ </para>
+
+ <informaltable id="supported-trigger-types">
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>When</entry>
+ <entry>Event</entry>
+ <entry>Row-level</entry>
+ <entry>Statement-level</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry align="center" morerows="1"><literal>BEFORE</literal></entry>
+ <entry align="center"><command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command></entry>
+ <entry align="center">Tables and foreign tables</entry>
+ <entry align="center">Tables, views, and foreign tables</entry>
+ </row>
+ <row>
+ <entry align="center"><command>TRUNCATE</command></entry>
+ <entry align="center">&mdash;</entry>
+ <entry align="center">Tables</entry>
+ </row>
+ <row>
+ <entry align="center" morerows="1"><literal>AFTER</literal></entry>
+ <entry align="center"><command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command></entry>
+ <entry align="center">Tables and foreign tables</entry>
+ <entry align="center">Tables, views, and foreign tables</entry>
+ </row>
+ <row>
+ <entry align="center"><command>TRUNCATE</command></entry>
+ <entry align="center">&mdash;</entry>
+ <entry align="center">Tables</entry>
+ </row>
+ <row>
+ <entry align="center" morerows="1"><literal>INSTEAD OF</literal></entry>
+ <entry align="center"><command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command></entry>
+ <entry align="center">Views</entry>
+ <entry align="center">&mdash;</entry>
+ </row>
+ <row>
+ <entry align="center"><command>TRUNCATE</command></entry>
+ <entry align="center">&mdash;</entry>
+ <entry align="center">&mdash;</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ Also, a trigger definition can specify a Boolean <literal>WHEN</literal>
+ condition, which will be tested to see whether the trigger should
+ be fired. In row-level triggers the <literal>WHEN</literal> condition can
+ examine the old and/or new values of columns of the row. Statement-level
+ triggers can also have <literal>WHEN</literal> conditions, although the feature
+ is not so useful for them since the condition cannot refer to any values
+ in the table.
+ </para>
+
+ <para>
+ If multiple triggers of the same kind are defined for the same event,
+ they will be fired in alphabetical order by name.
+ </para>
+
+ <para>
+ When the <literal>CONSTRAINT</literal> option is specified, this command creates a
+ <firstterm>constraint trigger</firstterm>.<indexterm><primary>trigger</primary>
+ <secondary>constraint trigger</secondary></indexterm>
+ This is the same as a regular trigger
+ except that the timing of the trigger firing can be adjusted using
+ <link linkend="sql-set-constraints"><command>SET CONSTRAINTS</command></link>.
+ Constraint triggers must be <literal>AFTER ROW</literal> triggers on plain
+ tables (not foreign tables). They
+ can be fired either at the end of the statement causing the triggering
+ event, or at the end of the containing transaction; in the latter case they
+ are said to be <firstterm>deferred</firstterm>. A pending deferred-trigger firing
+ can also be forced to happen immediately by using <command>SET
+ CONSTRAINTS</command>. Constraint triggers are expected to raise an exception
+ when the constraints they implement are violated.
+ </para>
+
+ <para>
+ The <literal>REFERENCING</literal> option enables collection
+ of <firstterm>transition relations</firstterm>, which are row sets that include all
+ of the rows inserted, deleted, or modified by the current SQL statement.
+ This feature lets the trigger see a global view of what the statement did,
+ not just one row at a time. This option is only allowed for
+ an <literal>AFTER</literal> trigger that is not a constraint trigger; also, if
+ the trigger is an <literal>UPDATE</literal> trigger, it must not specify
+ a <replaceable class="parameter">column_name</replaceable> list.
+ <literal>OLD TABLE</literal> may only be specified once, and only for a trigger
+ that can fire on <literal>UPDATE</literal> or <literal>DELETE</literal>; it creates a
+ transition relation containing the <firstterm>before-images</firstterm> of all rows
+ updated or deleted by the statement.
+ Similarly, <literal>NEW TABLE</literal> may only be specified once, and only for
+ a trigger that can fire on <literal>UPDATE</literal> or <literal>INSERT</literal>;
+ it creates a transition relation containing the <firstterm>after-images</firstterm>
+ of all rows updated or inserted by the statement.
+ </para>
+
+ <para>
+ <command>SELECT</command> does not modify any rows so you cannot
+ create <command>SELECT</command> triggers. Rules and views may provide
+ workable solutions to problems that seem to need <command>SELECT</command>
+ triggers.
+ </para>
+
+ <para>
+ Refer to <xref linkend="triggers"/> for more information about triggers.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name to give the new trigger. This must be distinct from
+ the name of any other trigger for the same table.
+ The name cannot be schema-qualified &mdash; the trigger inherits the
+ schema of its table. For a constraint trigger, this is also the name to
+ use when modifying the trigger's behavior using
+ <command>SET CONSTRAINTS</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BEFORE</literal></term>
+ <term><literal>AFTER</literal></term>
+ <term><literal>INSTEAD OF</literal></term>
+ <listitem>
+ <para>
+ Determines whether the function is called before, after, or instead of
+ the event. A constraint trigger can only be specified as
+ <literal>AFTER</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">event</replaceable></term>
+ <listitem>
+ <para>
+ One of <literal>INSERT</literal>, <literal>UPDATE</literal>,
+ <literal>DELETE</literal>, or <literal>TRUNCATE</literal>;
+ this specifies the event that will fire the trigger. Multiple
+ events can be specified using <literal>OR</literal>, except when
+ transition relations are requested.
+ </para>
+
+ <para>
+ For <literal>UPDATE</literal> events, it is possible to
+ specify a list of columns using this syntax:
+<synopsis>
+UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</replaceable> ... ]
+</synopsis>
+ The trigger will only fire if at least one of the listed columns
+ is mentioned as a target of the <command>UPDATE</command> command
+ or if one of the listed columns is a generated column that depends on a
+ column that is the target of the <command>UPDATE</command>.
+ </para>
+
+ <para>
+ <literal>INSTEAD OF UPDATE</literal> events do not allow a list of columns.
+ A column list cannot be specified when requesting transition relations,
+ either.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table, view, or foreign
+ table the trigger is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">referenced_table_name</replaceable></term>
+ <listitem>
+ <para>
+ The (possibly schema-qualified) name of another table referenced by the
+ constraint. This option is used for foreign-key constraints and is not
+ recommended for general use. This can only be specified for
+ constraint triggers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFERRABLE</literal></term>
+ <term><literal>NOT DEFERRABLE</literal></term>
+ <term><literal>INITIALLY IMMEDIATE</literal></term>
+ <term><literal>INITIALLY DEFERRED</literal></term>
+ <listitem>
+ <para>
+ The default timing of the trigger.
+ See the <xref linkend="sql-createtable"/> documentation for details of
+ these constraint options. This can only be specified for constraint
+ triggers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REFERENCING</literal></term>
+ <listitem>
+ <para>
+ This keyword immediately precedes the declaration of one or two
+ relation names that provide access to the transition relations of the
+ triggering statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OLD TABLE</literal></term>
+ <term><literal>NEW TABLE</literal></term>
+ <listitem>
+ <para>
+ This clause indicates whether the following relation name is for the
+ before-image transition relation or the after-image transition
+ relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">transition_relation_name</replaceable></term>
+ <listitem>
+ <para>
+ The (unqualified) name to be used within the trigger for this
+ transition relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FOR EACH ROW</literal></term>
+ <term><literal>FOR EACH STATEMENT</literal></term>
+
+ <listitem>
+ <para>
+ This specifies whether the trigger function should be fired
+ once for every row affected by the trigger event, or just once
+ per SQL statement. If neither is specified, <literal>FOR EACH
+ STATEMENT</literal> is the default. Constraint triggers can only
+ be specified <literal>FOR EACH ROW</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">condition</replaceable></term>
+ <listitem>
+ <para>
+ A Boolean expression that determines whether the trigger function
+ will actually be executed. If <literal>WHEN</literal> is specified, the
+ function will only be called if the <replaceable
+ class="parameter">condition</replaceable> returns <literal>true</literal>.
+ In <literal>FOR EACH ROW</literal> triggers, the <literal>WHEN</literal>
+ condition can refer to columns of the old and/or new row values
+ by writing <literal>OLD.<replaceable
+ class="parameter">column_name</replaceable></literal> or
+ <literal>NEW.<replaceable
+ class="parameter">column_name</replaceable></literal> respectively.
+ Of course, <literal>INSERT</literal> triggers cannot refer to <literal>OLD</literal>
+ and <literal>DELETE</literal> triggers cannot refer to <literal>NEW</literal>.
+ </para>
+
+ <para><literal>INSTEAD OF</literal> triggers do not support <literal>WHEN</literal>
+ conditions.
+ </para>
+
+ <para>
+ Currently, <literal>WHEN</literal> expressions cannot contain
+ subqueries.
+ </para>
+
+ <para>
+ Note that for constraint triggers, evaluation of the <literal>WHEN</literal>
+ condition is not deferred, but occurs immediately after the row update
+ operation is performed. If the condition does not evaluate to true then
+ the trigger is not queued for deferred execution.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <listitem>
+ <para>
+ A user-supplied function that is declared as taking no arguments
+ and returning type <literal>trigger</literal>, which is executed when
+ the trigger fires.
+ </para>
+
+ <para>
+ In the syntax of <literal>CREATE TRIGGER</literal>, the keywords
+ <literal>FUNCTION</literal> and <literal>PROCEDURE</literal> are
+ equivalent, but the referenced function must in any case be a function,
+ not a procedure. The use of the keyword <literal>PROCEDURE</literal>
+ here is historical and deprecated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">arguments</replaceable></term>
+ <listitem>
+ <para>
+ An optional comma-separated list of arguments to be provided to
+ the function when the trigger is executed. The arguments are
+ literal string constants. Simple names and numeric constants
+ can be written here, too, but they will all be converted to
+ strings. Please check the description of the implementation
+ language of the trigger function to find out how these arguments
+ can be accessed within the function; it might be different from
+ normal function arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createtrigger-notes">
+ <title>Notes</title>
+
+ <para>
+ To create or replace a trigger on a table, the user must have the
+ <literal>TRIGGER</literal> privilege on the table. The user must
+ also have <literal>EXECUTE</literal> privilege on the trigger function.
+ </para>
+
+ <para>
+ Use <link linkend="sql-droptrigger"><command>DROP TRIGGER</command></link> to remove a trigger.
+ </para>
+
+ <para>
+ Creating a row-level trigger on a partitioned table will cause an
+ identical <quote>clone</quote> trigger to be created on each of its
+ existing partitions; and any partitions created or attached later will have
+ an identical trigger, too. If there is a conflictingly-named trigger on a
+ child partition already, an error occurs unless <command>CREATE OR REPLACE
+ TRIGGER</command> is used, in which case that trigger is replaced with a
+ clone trigger. When a partition is detached from its parent, its clone
+ triggers are removed.
+ </para>
+
+ <para>
+ A column-specific trigger (one defined using the <literal>UPDATE OF
+ <replaceable>column_name</replaceable></literal> syntax) will fire when any
+ of its columns are listed as targets in the <command>UPDATE</command>
+ command's <literal>SET</literal> list. It is possible for a column's value
+ to change even when the trigger is not fired, because changes made to the
+ row's contents by <literal>BEFORE UPDATE</literal> triggers are not considered.
+ Conversely, a command such as <literal>UPDATE ... SET x = x ...</literal>
+ will fire a trigger on column <literal>x</literal>, even though the column's
+ value did not change.
+ </para>
+
+ <para>
+ In a <literal>BEFORE</literal> trigger, the <literal>WHEN</literal> condition is
+ evaluated just before the function is or would be executed, so using
+ <literal>WHEN</literal> is not materially different from testing the same
+ condition at the beginning of the trigger function. Note in particular
+ that the <literal>NEW</literal> row seen by the condition is the current value,
+ as possibly modified by earlier triggers. Also, a <literal>BEFORE</literal>
+ trigger's <literal>WHEN</literal> condition is not allowed to examine the
+ system columns of the <literal>NEW</literal> row (such as <literal>ctid</literal>),
+ because those won't have been set yet.
+ </para>
+
+ <para>
+ In an <literal>AFTER</literal> trigger, the <literal>WHEN</literal> condition is
+ evaluated just after the row update occurs, and it determines whether an
+ event is queued to fire the trigger at the end of statement. So when an
+ <literal>AFTER</literal> trigger's <literal>WHEN</literal> condition does not return
+ true, it is not necessary to queue an event nor to re-fetch the row at end
+ of statement. This can result in significant speedups in statements that
+ modify many rows, if the trigger only needs to be fired for a few of the
+ rows.
+ </para>
+
+ <para>
+ In some cases it is possible for a single SQL command to fire more than
+ one kind of trigger. For instance an <command>INSERT</command> with
+ an <literal>ON CONFLICT DO UPDATE</literal> clause may cause both insert and
+ update operations, so it will fire both kinds of triggers as needed.
+ The transition relations supplied to triggers are
+ specific to their event type; thus an <command>INSERT</command> trigger
+ will see only the inserted rows, while an <command>UPDATE</command>
+ trigger will see only the updated rows.
+ </para>
+
+ <para>
+ Row updates or deletions caused by foreign-key enforcement actions, such
+ as <literal>ON UPDATE CASCADE</literal> or <literal>ON DELETE SET NULL</literal>, are
+ treated as part of the SQL command that caused them (note that such
+ actions are never deferred). Relevant triggers on the affected table will
+ be fired, so that this provides another way in which an SQL command might
+ fire triggers not directly matching its type. In simple cases, triggers
+ that request transition relations will see all changes caused in their
+ table by a single original SQL command as a single transition relation.
+ However, there are cases in which the presence of an <literal>AFTER ROW</literal>
+ trigger that requests transition relations will cause the foreign-key
+ enforcement actions triggered by a single SQL command to be split into
+ multiple steps, each with its own transition relation(s). In such cases,
+ any statement-level triggers that are present will be fired once per
+ creation of a transition relation set, ensuring that the triggers see
+ each affected row in a transition relation once and only once.
+ </para>
+
+ <para>
+ Statement-level triggers on a view are fired only if the action on the
+ view is handled by a row-level <literal>INSTEAD OF</literal> trigger.
+ If the action is handled by an <literal>INSTEAD</literal> rule, then
+ whatever statements are emitted by the rule are executed in place of the
+ original statement naming the view, so that the triggers that will be
+ fired are those on tables named in the replacement statements.
+ Similarly, if the view is automatically updatable, then the action is
+ handled by automatically rewriting the statement into an action on the
+ view's base table, so that the base table's statement-level triggers are
+ the ones that are fired.
+ </para>
+
+ <para>
+ Modifying a partitioned table or a table with inheritance children fires
+ statement-level triggers attached to the explicitly named table, but not
+ statement-level triggers for its partitions or child tables. In contrast,
+ row-level triggers are fired on the rows in affected partitions or
+ child tables, even if they are not explicitly named in the query.
+ If a statement-level trigger has been defined with transition relations
+ named by a <literal>REFERENCING</literal> clause, then before and after
+ images of rows are visible from all affected partitions or child tables.
+ In the case of inheritance children, the row images include only columns
+ that are present in the table that the trigger is attached to.
+ </para>
+
+ <para>
+ Currently, row-level triggers with transition relations cannot be defined
+ on partitions or inheritance child tables. Also, triggers on partitioned
+ tables may not be <literal>INSTEAD OF</literal>.
+ </para>
+
+ <para>
+ Currently, the <literal>OR REPLACE</literal> option is not supported for
+ constraint triggers.
+ </para>
+
+ <para>
+ Replacing an existing trigger within a transaction that has already
+ performed updating actions on the trigger's table is not recommended.
+ Trigger firing decisions, or portions of firing decisions, that have
+ already been made will not be reconsidered, so the effects could be
+ surprising.
+ </para>
+
+ <para>
+ There are a few built-in trigger functions that can be used to
+ solve common problems without having to write your own trigger code;
+ see <xref linkend="functions-trigger"/>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtrigger-examples">
+ <title>Examples</title>
+
+ <para>
+ Execute the function <function>check_account_update</function> whenever
+ a row of the table <literal>accounts</literal> is about to be updated:
+
+<programlisting>
+CREATE TRIGGER check_update
+ BEFORE UPDATE ON accounts
+ FOR EACH ROW
+ EXECUTE FUNCTION check_account_update();
+</programlisting>
+
+ Modify that trigger definition to only execute the function if
+ column <literal>balance</literal> is specified as a target in
+ the <command>UPDATE</command> command:
+
+<programlisting>
+CREATE OR REPLACE TRIGGER check_update
+ BEFORE UPDATE OF balance ON accounts
+ FOR EACH ROW
+ EXECUTE FUNCTION check_account_update();
+</programlisting>
+
+ This form only executes the function if column <literal>balance</literal>
+ has in fact changed value:
+
+<programlisting>
+CREATE TRIGGER check_update
+ BEFORE UPDATE ON accounts
+ FOR EACH ROW
+ WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
+ EXECUTE FUNCTION check_account_update();
+</programlisting>
+
+ Call a function to log updates of <literal>accounts</literal>, but only if
+ something changed:
+
+<programlisting>
+CREATE TRIGGER log_update
+ AFTER UPDATE ON accounts
+ FOR EACH ROW
+ WHEN (OLD.* IS DISTINCT FROM NEW.*)
+ EXECUTE FUNCTION log_account_update();
+</programlisting>
+
+ Execute the function <function>view_insert_row</function> for each row to insert
+ rows into the tables underlying a view:
+
+<programlisting>
+CREATE TRIGGER view_insert
+ INSTEAD OF INSERT ON my_view
+ FOR EACH ROW
+ EXECUTE FUNCTION view_insert_row();
+</programlisting>
+
+ Execute the function <function>check_transfer_balances_to_zero</function> for each
+ statement to confirm that the <literal>transfer</literal> rows offset to a net of
+ zero:
+
+<programlisting>
+CREATE TRIGGER transfer_insert
+ AFTER INSERT ON transfer
+ REFERENCING NEW TABLE AS inserted
+ FOR EACH STATEMENT
+ EXECUTE FUNCTION check_transfer_balances_to_zero();
+</programlisting>
+
+ Execute the function <function>check_matching_pairs</function> for each row to
+ confirm that changes are made to matching pairs at the same time (by the
+ same statement):
+
+<programlisting>
+CREATE TRIGGER paired_items_update
+ AFTER UPDATE ON paired_items
+ REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab
+ FOR EACH ROW
+ EXECUTE FUNCTION check_matching_pairs();
+</programlisting>
+ </para>
+
+ <para>
+ <xref linkend="trigger-example"/> contains a complete example of a trigger
+ function written in C.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtrigger-compatibility">
+ <title>Compatibility</title>
+
+ <!--
+ It's not clear whether SQL/MED contemplates triggers on foreign tables.
+ Its <drop basic column definition> General Rules do mention the possibility
+ of a reference from a trigger column list. On the other hand, nothing
+ overrides the fact that CREATE TRIGGER only targets base tables. For now,
+ do not document the compatibility status of triggers on foreign tables.
+ -->
+
+ <para>
+ The <command>CREATE TRIGGER</command> statement in
+ <productname>PostgreSQL</productname> implements a subset of the
+ <acronym>SQL</acronym> standard. The following functionalities are currently
+ missing:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ While transition table names for <literal>AFTER</literal> triggers are
+ specified using the <literal>REFERENCING</literal> clause in the standard way,
+ the row variables used in <literal>FOR EACH ROW</literal> triggers may not be
+ specified in a <literal>REFERENCING</literal> clause. They are available in a
+ manner that is dependent on the language in which the trigger function
+ is written, but is fixed for any one language. Some languages
+ effectively behave as though there is a <literal>REFERENCING</literal> clause
+ containing <literal>OLD ROW AS OLD NEW ROW AS NEW</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The standard allows transition tables to be used with
+ column-specific <literal>UPDATE</literal> triggers, but then the set of rows
+ that should be visible in the transition tables depends on the
+ trigger's column list. This is not currently implemented by
+ <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> only allows the execution
+ of a user-defined function for the triggered action. The standard
+ allows the execution of a number of other SQL commands, such as
+ <command>CREATE TABLE</command>, as the triggered action. This
+ limitation is not hard to work around by creating a user-defined
+ function that executes the desired commands.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ SQL specifies that multiple triggers should be fired in
+ time-of-creation order. <productname>PostgreSQL</productname> uses
+ name order, which was judged to be more convenient.
+ </para>
+
+ <para>
+ SQL specifies that <literal>BEFORE DELETE</literal> triggers on cascaded
+ deletes fire <emphasis>after</emphasis> the cascaded <literal>DELETE</literal> completes.
+ The <productname>PostgreSQL</productname> behavior is for <literal>BEFORE
+ DELETE</literal> to always fire before the delete action, even a cascading
+ one. This is considered more consistent. There is also nonstandard
+ behavior if <literal>BEFORE</literal> triggers modify rows or prevent
+ updates during an update that is caused by a referential action. This can
+ lead to constraint violations or stored data that does not honor the
+ referential constraint.
+ </para>
+
+ <para>
+ The ability to specify multiple actions for a single trigger using
+ <literal>OR</literal> is a <productname>PostgreSQL</productname> extension of
+ the SQL standard.
+ </para>
+
+ <para>
+ The ability to fire triggers for <command>TRUNCATE</command> is a
+ <productname>PostgreSQL</productname> extension of the SQL standard, as is the
+ ability to define statement-level triggers on views.
+ </para>
+
+ <para>
+ <command>CREATE CONSTRAINT TRIGGER</command> is a
+ <productname>PostgreSQL</productname> extension of the <acronym>SQL</acronym>
+ standard.
+ So is the <literal>OR REPLACE</literal> option.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertrigger"/></member>
+ <member><xref linkend="sql-droptrigger"/></member>
+ <member><xref linkend="sql-createfunction"/></member>
+ <member><xref linkend="sql-set-constraints"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_tsconfig.sgml b/doc/src/sgml/ref/create_tsconfig.sgml
new file mode 100644
index 0000000..390d3cf
--- /dev/null
+++ b/doc/src/sgml/ref/create_tsconfig.sgml
@@ -0,0 +1,126 @@
+<!--
+doc/src/sgml/ref/create_tsconfig.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtsconfig">
+ <indexterm zone="sql-createtsconfig">
+ <primary>CREATE TEXT SEARCH CONFIGURATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TEXT SEARCH CONFIGURATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TEXT SEARCH CONFIGURATION</refname>
+ <refpurpose>define a new text search configuration</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TEXT SEARCH CONFIGURATION <replaceable class="parameter">name</replaceable> (
+ PARSER = <replaceable class="parameter">parser_name</replaceable> |
+ COPY = <replaceable class="parameter">source_config</replaceable>
+)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TEXT SEARCH CONFIGURATION</command> creates a new text
+ search configuration. A text search configuration specifies a text
+ search parser that can divide a string into tokens, plus dictionaries
+ that can be used to determine which tokens are of interest for searching.
+ </para>
+
+ <para>
+ If only the parser is specified, then the new text search configuration
+ initially has no mappings from token types to dictionaries, and therefore
+ will ignore all words. Subsequent <command>ALTER TEXT SEARCH
+ CONFIGURATION</command> commands must be used to create mappings to
+ make the configuration useful. Alternatively, an existing text search
+ configuration can be copied.
+ </para>
+
+ <para>
+ If a schema name is given then the text search configuration is created in
+ the specified schema. Otherwise it is created in the current schema.
+ </para>
+
+ <para>
+ The user who defines a text search configuration becomes its owner.
+ </para>
+
+ <para>
+ Refer to <xref linkend="textsearch"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the text search configuration to be created. The name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">parser_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the text search parser to use for this configuration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">source_config</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing text search configuration to copy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The <literal>PARSER</literal> and <literal>COPY</literal> options are mutually
+ exclusive, because when an existing configuration is copied, its
+ parser selection is copied too.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CREATE TEXT SEARCH CONFIGURATION</command> statement
+ in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertsconfig"/></member>
+ <member><xref linkend="sql-droptsconfig"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_tsdictionary.sgml b/doc/src/sgml/ref/create_tsdictionary.sgml
new file mode 100644
index 0000000..0608104
--- /dev/null
+++ b/doc/src/sgml/ref/create_tsdictionary.sgml
@@ -0,0 +1,141 @@
+<!--
+doc/src/sgml/ref/create_tsdictionary.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtsdictionary">
+ <indexterm zone="sql-createtsdictionary">
+ <primary>CREATE TEXT SEARCH DICTIONARY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TEXT SEARCH DICTIONARY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TEXT SEARCH DICTIONARY</refname>
+ <refpurpose>define a new text search dictionary</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TEXT SEARCH DICTIONARY <replaceable class="parameter">name</replaceable> (
+ TEMPLATE = <replaceable class="parameter">template</replaceable>
+ [, <replaceable class="parameter">option</replaceable> = <replaceable class="parameter">value</replaceable> [, ... ]]
+)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TEXT SEARCH DICTIONARY</command> creates a new text search
+ dictionary. A text search dictionary specifies a way of recognizing
+ interesting or uninteresting words for searching. A dictionary depends
+ on a text search template, which specifies the functions that actually
+ perform the work. Typically the dictionary provides some options that
+ control the detailed behavior of the template's functions.
+ </para>
+
+ <para>
+ If a schema name is given then the text search dictionary is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </para>
+
+ <para>
+ The user who defines a text search dictionary becomes its owner.
+ </para>
+
+ <para>
+ Refer to <xref linkend="textsearch"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the text search dictionary to be created. The name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">template</replaceable></term>
+ <listitem>
+ <para>
+ The name of the text search template that will define the basic
+ behavior of this dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">option</replaceable></term>
+ <listitem>
+ <para>
+ The name of a template-specific option to be set for this dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ The value to use for a template-specific option. If the value
+ is not a simple identifier or number, it must be quoted (but you can
+ always quote it, if you wish).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The options can appear in any order.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example command creates a Snowball-based dictionary
+ with a nonstandard list of stop words.
+ </para>
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY my_russian (
+ template = snowball,
+ language = russian,
+ stopwords = myrussian
+);
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>CREATE TEXT SEARCH DICTIONARY</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertsdictionary"/></member>
+ <member><xref linkend="sql-droptsdictionary"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_tsparser.sgml b/doc/src/sgml/ref/create_tsparser.sgml
new file mode 100644
index 0000000..088d923
--- /dev/null
+++ b/doc/src/sgml/ref/create_tsparser.sgml
@@ -0,0 +1,153 @@
+<!--
+doc/src/sgml/ref/create_tsparser.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtsparser">
+ <indexterm zone="sql-createtsparser">
+ <primary>CREATE TEXT SEARCH PARSER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TEXT SEARCH PARSER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TEXT SEARCH PARSER</refname>
+ <refpurpose>define a new text search parser</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TEXT SEARCH PARSER <replaceable class="parameter">name</replaceable> (
+ START = <replaceable class="parameter">start_function</replaceable> ,
+ GETTOKEN = <replaceable class="parameter">gettoken_function</replaceable> ,
+ END = <replaceable class="parameter">end_function</replaceable> ,
+ LEXTYPES = <replaceable class="parameter">lextypes_function</replaceable>
+ [, HEADLINE = <replaceable class="parameter">headline_function</replaceable> ]
+)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TEXT SEARCH PARSER</command> creates a new text search
+ parser. A text search parser defines a method for splitting a text
+ string into tokens and assigning types (categories) to the tokens.
+ A parser is not particularly useful by itself, but must be bound into a
+ text search configuration along with some text search dictionaries
+ to be used for searching.
+ </para>
+
+ <para>
+ If a schema name is given then the text search parser is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </para>
+
+ <para>
+ You must be a superuser to use <command>CREATE TEXT SEARCH PARSER</command>.
+ (This restriction is made because an erroneous text search parser
+ definition could confuse or even crash the server.)
+ </para>
+
+ <para>
+ Refer to <xref linkend="textsearch"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the text search parser to be created. The name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">start_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the start function for the parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">gettoken_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the get-next-token function for the parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">end_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the end function for the parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">lextypes_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the lextypes function for the parser (a function that
+ returns information about the set of token types it produces).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">headline_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the headline function for the parser (a function that
+ summarizes a set of tokens).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The function names can be schema-qualified if necessary. Argument types
+ are not given, since the argument list for each type of function is
+ predetermined. All except the headline function are required.
+ </para>
+
+ <para>
+ The arguments can appear in any order, not only the one shown above.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no
+ <command>CREATE TEXT SEARCH PARSER</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertsparser"/></member>
+ <member><xref linkend="sql-droptsparser"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_tstemplate.sgml b/doc/src/sgml/ref/create_tstemplate.sgml
new file mode 100644
index 0000000..5b82d55
--- /dev/null
+++ b/doc/src/sgml/ref/create_tstemplate.sgml
@@ -0,0 +1,126 @@
+<!--
+doc/src/sgml/ref/create_tstemplate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtstemplate">
+ <indexterm zone="sql-createtstemplate">
+ <primary>CREATE TEXT SEARCH TEMPLATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TEXT SEARCH TEMPLATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TEXT SEARCH TEMPLATE</refname>
+ <refpurpose>define a new text search template</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TEXT SEARCH TEMPLATE <replaceable class="parameter">name</replaceable> (
+ [ INIT = <replaceable class="parameter">init_function</replaceable> , ]
+ LEXIZE = <replaceable class="parameter">lexize_function</replaceable>
+)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TEXT SEARCH TEMPLATE</command> creates a new text search
+ template. Text search templates define the functions that implement
+ text search dictionaries. A template is not useful by itself, but must
+ be instantiated as a dictionary to be used. The dictionary typically
+ specifies parameters to be given to the template functions.
+ </para>
+
+ <para>
+ If a schema name is given then the text search template is created in the
+ specified schema. Otherwise it is created in the current schema.
+ </para>
+
+ <para>
+ You must be a superuser to use <command>CREATE TEXT SEARCH
+ TEMPLATE</command>. This restriction is made because an erroneous text
+ search template definition could confuse or even crash the server.
+ The reason for separating templates from dictionaries is that a template
+ encapsulates the <quote>unsafe</quote> aspects of defining a dictionary.
+ The parameters that can be set when defining a dictionary are safe for
+ unprivileged users to set, and so creating a dictionary need not be a
+ privileged operation.
+ </para>
+
+ <para>
+ Refer to <xref linkend="textsearch"/> for further information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the text search template to be created. The name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">init_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the init function for the template.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">lexize_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the lexize function for the template.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The function names can be schema-qualified if necessary. Argument types
+ are not given, since the argument list for each type of function is
+ predetermined. The lexize function is required, but the init function
+ is optional.
+ </para>
+
+ <para>
+ The arguments can appear in any order, not only the one shown above.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no
+ <command>CREATE TEXT SEARCH TEMPLATE</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertstemplate"/></member>
+ <member><xref linkend="sql-droptstemplate"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
new file mode 100644
index 0000000..693423e
--- /dev/null
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -0,0 +1,1029 @@
+<!--
+doc/src/sgml/ref/create_type.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createtype">
+ <indexterm zone="sql-createtype">
+ <primary>CREATE TYPE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE TYPE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE TYPE</refname>
+ <refpurpose>define a new data type</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE TYPE <replaceable class="parameter">name</replaceable> AS
+ ( [ <replaceable class="parameter">attribute_name</replaceable> <replaceable class="parameter">data_type</replaceable> [ COLLATE <replaceable>collation</replaceable> ] [, ... ] ] )
+
+CREATE TYPE <replaceable class="parameter">name</replaceable> AS ENUM
+ ( [ '<replaceable class="parameter">label</replaceable>' [, ... ] ] )
+
+CREATE TYPE <replaceable class="parameter">name</replaceable> AS RANGE (
+ SUBTYPE = <replaceable class="parameter">subtype</replaceable>
+ [ , SUBTYPE_OPCLASS = <replaceable class="parameter">subtype_operator_class</replaceable> ]
+ [ , COLLATION = <replaceable class="parameter">collation</replaceable> ]
+ [ , CANONICAL = <replaceable class="parameter">canonical_function</replaceable> ]
+ [ , SUBTYPE_DIFF = <replaceable class="parameter">subtype_diff_function</replaceable> ]
+ [ , MULTIRANGE_TYPE_NAME = <replaceable class="parameter">multirange_type_name</replaceable> ]
+)
+
+CREATE TYPE <replaceable class="parameter">name</replaceable> (
+ INPUT = <replaceable class="parameter">input_function</replaceable>,
+ OUTPUT = <replaceable class="parameter">output_function</replaceable>
+ [ , RECEIVE = <replaceable class="parameter">receive_function</replaceable> ]
+ [ , SEND = <replaceable class="parameter">send_function</replaceable> ]
+ [ , TYPMOD_IN = <replaceable class="parameter">type_modifier_input_function</replaceable> ]
+ [ , TYPMOD_OUT = <replaceable class="parameter">type_modifier_output_function</replaceable> ]
+ [ , ANALYZE = <replaceable class="parameter">analyze_function</replaceable> ]
+ [ , SUBSCRIPT = <replaceable class="parameter">subscript_function</replaceable> ]
+ [ , INTERNALLENGTH = { <replaceable class="parameter">internallength</replaceable> | VARIABLE } ]
+ [ , PASSEDBYVALUE ]
+ [ , ALIGNMENT = <replaceable class="parameter">alignment</replaceable> ]
+ [ , STORAGE = <replaceable class="parameter">storage</replaceable> ]
+ [ , LIKE = <replaceable class="parameter">like_type</replaceable> ]
+ [ , CATEGORY = <replaceable class="parameter">category</replaceable> ]
+ [ , PREFERRED = <replaceable class="parameter">preferred</replaceable> ]
+ [ , DEFAULT = <replaceable class="parameter">default</replaceable> ]
+ [ , ELEMENT = <replaceable class="parameter">element</replaceable> ]
+ [ , DELIMITER = <replaceable class="parameter">delimiter</replaceable> ]
+ [ , COLLATABLE = <replaceable class="parameter">collatable</replaceable> ]
+)
+
+CREATE TYPE <replaceable class="parameter">name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TYPE</command> registers a new data type for use in
+ the current database. The user who defines a type becomes its
+ owner.
+ </para>
+
+ <para>
+ If a schema name is given then the type is created in the specified
+ schema. Otherwise it is created in the current schema. The type
+ name must be distinct from the name of any existing type or domain
+ in the same schema. (Because tables have associated data types,
+ the type name must also be distinct from the name of any existing
+ table in the same schema.)
+ </para>
+
+ <para>
+ There are five forms of <command>CREATE TYPE</command>, as shown in the
+ syntax synopsis above. They respectively create a <firstterm>composite
+ type</firstterm>, an <firstterm>enum type</firstterm>, a <firstterm>range type</firstterm>, a
+ <firstterm>base type</firstterm>, or a <firstterm>shell type</firstterm>. The first four
+ of these are discussed in turn below. A shell type is simply a placeholder
+ for a type to be defined later; it is created by issuing <command>CREATE
+ TYPE</command> with no parameters except for the type name. Shell types
+ are needed as forward references when creating range types and base types,
+ as discussed in those sections.
+ </para>
+
+ <refsect2>
+ <title>Composite Types</title>
+
+ <para>
+ The first form of <command>CREATE TYPE</command>
+ creates a composite type.
+ The composite type is specified by a list of attribute names and data types.
+ An attribute's collation can be specified too, if its data type is
+ collatable. A composite type is essentially the same as the row type
+ of a table, but using <command>CREATE TYPE</command> avoids the need to
+ create an actual table when all that is wanted is to define a type.
+ A stand-alone composite type is useful, for example, as the argument or
+ return type of a function.
+ </para>
+
+ <para>
+ To be able to create a composite type, you must
+ have <literal>USAGE</literal> privilege on all attribute types.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-createtype-enum">
+ <title>Enumerated Types</title>
+
+ <para>
+ The second form of <command>CREATE TYPE</command> creates an enumerated
+ (enum) type, as described in <xref linkend="datatype-enum"/>.
+ Enum types take a list of quoted labels, each of which
+ must be less than <symbol>NAMEDATALEN</symbol> bytes long (64 bytes in a
+ standard <productname>PostgreSQL</productname> build). (It is possible to
+ create an enumerated type with zero labels, but such a type cannot be used
+ to hold values before at least one label is added using <link
+ linkend="sql-altertype"><command>ALTER TYPE</command></link>.)
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-createtype-range">
+ <title>Range Types</title>
+
+ <para>
+ The third form of <command>CREATE TYPE</command> creates a new
+ range type, as described in <xref linkend="rangetypes"/>.
+ </para>
+
+ <para>
+ The range type's <replaceable class="parameter">subtype</replaceable> can
+ be any type with an associated b-tree operator class (to determine the
+ ordering of values for the range type). Normally the subtype's default
+ b-tree operator class is used to determine ordering; to use a non-default
+ operator class, specify its name with <replaceable
+ class="parameter">subtype_opclass</replaceable>. If the subtype is
+ collatable, and you want to use a non-default collation in the range's
+ ordering, specify the desired collation with the <replaceable
+ class="parameter">collation</replaceable> option.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">canonical</replaceable>
+ function must take one argument of the range type being defined, and
+ return a value of the same type. This is used to convert range values
+ to a canonical form, when applicable. See <xref
+ linkend="rangetypes-defining"/> for more information. Creating a
+ <replaceable class="parameter">canonical</replaceable> function
+ is a bit tricky, since it must be defined before the range type can be
+ declared. To do this, you must first create a shell type, which is a
+ placeholder type that has no properties except a name and an
+ owner. This is done by issuing the command <literal>CREATE TYPE
+ <replaceable>name</replaceable></literal>, with no additional parameters. Then
+ the function can be declared using the shell type as argument and result,
+ and finally the range type can be declared using the same name. This
+ automatically replaces the shell type entry with a valid range type.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">subtype_diff</replaceable>
+ function must take two values of the
+ <replaceable class="parameter">subtype</replaceable> type as argument,
+ and return a <type>double precision</type> value representing the
+ difference between the two given values. While this is optional,
+ providing it allows much greater efficiency of GiST indexes on columns of
+ the range type. See <xref linkend="rangetypes-defining"/> for more
+ information.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">multirange_type_name</replaceable>
+ parameter specifies the name of the corresponding multirange type. If not
+ specified, this name is chosen automatically as follows.
+ If the range type name contains the substring <literal>range</literal>, then
+ the multirange type name is formed by replacement of the <literal>range</literal>
+ substring with <literal>multirange</literal> in the range
+ type name. Otherwise, the multirange type name is formed by appending a
+ <literal>_multirange</literal> suffix to the range type name.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Base Types</title>
+
+ <para>
+ The fourth form of <command>CREATE TYPE</command> creates a new base type
+ (scalar type). To create a new base type, you must be a superuser.
+ (This restriction is made because an erroneous type definition could
+ confuse or even crash the server.)
+ </para>
+
+ <para>
+ The parameters can appear in any order, not only that
+ illustrated above, and most are optional. You must register
+ two or more functions (using <command>CREATE FUNCTION</command>) before
+ defining the type. The support functions
+ <replaceable class="parameter">input_function</replaceable> and
+ <replaceable class="parameter">output_function</replaceable>
+ are required, while the functions
+ <replaceable class="parameter">receive_function</replaceable>,
+ <replaceable class="parameter">send_function</replaceable>,
+ <replaceable class="parameter">type_modifier_input_function</replaceable>,
+ <replaceable class="parameter">type_modifier_output_function</replaceable>,
+ <replaceable class="parameter">analyze_function</replaceable>, and
+ <replaceable class="parameter">subscript_function</replaceable>
+ are optional. Generally these functions have to be coded in C
+ or another low-level language.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">input_function</replaceable>
+ converts the type's external textual representation to the internal
+ representation used by the operators and functions defined for the type.
+ <replaceable class="parameter">output_function</replaceable>
+ performs the reverse transformation. The input function can be
+ declared as taking one argument of type <type>cstring</type>,
+ or as taking three arguments of types
+ <type>cstring</type>, <type>oid</type>, <type>integer</type>.
+ The first argument is the input text as a C string, the second
+ argument is the type's own OID (except for array types, which instead
+ receive their element type's OID),
+ and the third is the <literal>typmod</literal> of the destination column, if known
+ (-1 will be passed if not).
+ The input function must return a value of the data type itself.
+ Usually, an input function should be declared STRICT; if it is not,
+ it will be called with a NULL first parameter when reading a NULL
+ input value. The function must still return NULL in this case, unless
+ it raises an error.
+ (This case is mainly meant to support domain input functions, which
+ might need to reject NULL inputs.)
+ The output function must be
+ declared as taking one argument of the new data type.
+ The output function must return type <type>cstring</type>.
+ Output functions are not invoked for NULL values.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">receive_function</replaceable>
+ converts the type's external binary representation to the internal
+ representation. If this function is not supplied, the type cannot
+ participate in binary input. The binary representation should be
+ chosen to be cheap to convert to internal form, while being reasonably
+ portable. (For example, the standard integer data types use network
+ byte order as the external binary representation, while the internal
+ representation is in the machine's native byte order.) The receive
+ function should perform adequate checking to ensure that the value is
+ valid.
+ The receive function can be declared as taking one argument of type
+ <type>internal</type>, or as taking three arguments of types
+ <type>internal</type>, <type>oid</type>, <type>integer</type>.
+ The first argument is a pointer to a <type>StringInfo</type> buffer
+ holding the received byte string; the optional arguments are the
+ same as for the text input function.
+ The receive function must return a value of the data type itself.
+ Usually, a receive function should be declared STRICT; if it is not,
+ it will be called with a NULL first parameter when reading a NULL
+ input value. The function must still return NULL in this case, unless
+ it raises an error.
+ (This case is mainly meant to support domain receive functions, which
+ might need to reject NULL inputs.)
+ Similarly, the optional
+ <replaceable class="parameter">send_function</replaceable> converts
+ from the internal representation to the external binary representation.
+ If this function is not supplied, the type cannot participate in binary
+ output. The send function must be
+ declared as taking one argument of the new data type.
+ The send function must return type <type>bytea</type>.
+ Send functions are not invoked for NULL values.
+ </para>
+
+ <para>
+ You should at this point be wondering how the input and output functions
+ can be declared to have results or arguments of the new type, when they
+ have to be created before the new type can be created. The answer is that
+ the type should first be defined as a <firstterm>shell type</firstterm>, which is a
+ placeholder type that has no properties except a name and an owner. This
+ is done by issuing the command <literal>CREATE TYPE
+ <replaceable>name</replaceable></literal>, with no additional parameters. Then the
+ C I/O functions can be defined referencing the shell type. Finally,
+ <command>CREATE TYPE</command> with a full definition replaces the shell entry
+ with a complete, valid type definition, after which the new type can be
+ used normally.
+ </para>
+
+ <para>
+ The optional
+ <replaceable class="parameter">type_modifier_input_function</replaceable>
+ and <replaceable class="parameter">type_modifier_output_function</replaceable>
+ are needed if the type supports modifiers, that is optional constraints
+ attached to a type declaration, such as <literal>char(5)</literal> or
+ <literal>numeric(30,2)</literal>. <productname>PostgreSQL</productname> allows
+ user-defined types to take one or more simple constants or identifiers as
+ modifiers. However, this information must be capable of being packed into a
+ single non-negative integer value for storage in the system catalogs. The
+ <replaceable class="parameter">type_modifier_input_function</replaceable>
+ is passed the declared modifier(s) in the form of a <type>cstring</type>
+ array. It must check the values for validity (throwing an error if they
+ are wrong), and if they are correct, return a single non-negative
+ <type>integer</type> value that will be stored as the column <quote>typmod</quote>.
+ Type modifiers will be rejected if the type does not have a
+ <replaceable class="parameter">type_modifier_input_function</replaceable>.
+ The <replaceable class="parameter">type_modifier_output_function</replaceable>
+ converts the internal integer typmod value back to the correct form for
+ user display. It must return a <type>cstring</type> value that is the exact
+ string to append to the type name; for example <type>numeric</type>'s
+ function might return <literal>(30,2)</literal>.
+ It is allowed to omit the
+ <replaceable class="parameter">type_modifier_output_function</replaceable>,
+ in which case the default display format is just the stored typmod integer
+ value enclosed in parentheses.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">analyze_function</replaceable>
+ performs type-specific statistics collection for columns of the data type.
+ By default, <command>ANALYZE</command> will attempt to gather statistics using
+ the type's <quote>equals</quote> and <quote>less-than</quote> operators, if there
+ is a default b-tree operator class for the type. For non-scalar types
+ this behavior is likely to be unsuitable, so it can be overridden by
+ specifying a custom analysis function. The analysis function must be
+ declared to take a single argument of type <type>internal</type>, and return
+ a <type>boolean</type> result. The detailed API for analysis functions appears
+ in <filename>src/include/commands/vacuum.h</filename>.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">subscript_function</replaceable>
+ allows the data type to be subscripted in SQL commands. Specifying this
+ function does not cause the type to be considered a <quote>true</quote>
+ array type; for example, it will not be a candidate for the result type
+ of <literal>ARRAY[]</literal> constructs. But if subscripting a value
+ of the type is a natural notation for extracting data from it, then
+ a <replaceable class="parameter">subscript_function</replaceable> can
+ be written to define what that means. The subscript function must be
+ declared to take a single argument of type <type>internal</type>, and
+ return an <type>internal</type> result, which is a pointer to a struct
+ of methods (functions) that implement subscripting.
+ The detailed API for subscript functions appears
+ in <filename>src/include/nodes/subscripting.h</filename>.
+ It may also be useful to read the array implementation
+ in <filename>src/backend/utils/adt/arraysubs.c</filename>,
+ or the simpler code
+ in <filename>contrib/hstore/hstore_subs.c</filename>.
+ Additional information appears in
+ <xref linkend="sql-createtype-array"/> below.
+ </para>
+
+ <para>
+ While the details of the new type's internal representation are only
+ known to the I/O functions and other functions you create to work with
+ the type, there are several properties of the internal representation
+ that must be declared to <productname>PostgreSQL</productname>.
+ Foremost of these is
+ <replaceable class="parameter">internallength</replaceable>.
+ Base data types can be fixed-length, in which case
+ <replaceable class="parameter">internallength</replaceable> is a
+ positive integer, or variable-length, indicated by setting
+ <replaceable class="parameter">internallength</replaceable>
+ to <literal>VARIABLE</literal>. (Internally, this is represented
+ by setting <literal>typlen</literal> to -1.) The internal representation of all
+ variable-length types must start with a 4-byte integer giving the total
+ length of this value of the type. (Note that the length field is often
+ encoded, as described in <xref linkend="storage-toast"/>; it's unwise
+ to access it directly.)
+ </para>
+
+ <para>
+ The optional flag <literal>PASSEDBYVALUE</literal> indicates that
+ values of this data type are passed by value, rather than by
+ reference. Types passed by value must be fixed-length, and their internal
+ representation cannot be larger than the size of the <type>Datum</type> type
+ (4 bytes on some machines, 8 bytes on others).
+ </para>
+
+ <para>
+ The <replaceable class="parameter">alignment</replaceable> parameter
+ specifies the storage alignment required for the data type. The
+ allowed values equate to alignment on 1, 2, 4, or 8 byte boundaries.
+ Note that variable-length types must have an alignment of at least
+ 4, since they necessarily contain an <type>int4</type> as their first component.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">storage</replaceable> parameter
+ allows selection of storage strategies for variable-length data
+ types. (Only <literal>plain</literal> is allowed for fixed-length
+ types.) <literal>plain</literal> specifies that data of the type
+ will always be stored in-line and not compressed.
+ <literal>extended</literal> specifies that the system will first
+ try to compress a long data value, and will move the value out of
+ the main table row if it's still too long.
+ <literal>external</literal> allows the value to be moved out of the
+ main table, but the system will not try to compress it.
+ <literal>main</literal> allows compression, but discourages moving
+ the value out of the main table. (Data items with this storage
+ strategy might still be moved out of the main table if there is no
+ other way to make a row fit, but they will be kept in the main
+ table preferentially over <literal>extended</literal> and
+ <literal>external</literal> items.)
+ </para>
+
+ <para>
+ All <replaceable class="parameter">storage</replaceable> values other
+ than <literal>plain</literal> imply that the functions of the data type
+ can handle values that have been <firstterm>toasted</firstterm>, as described
+ in <xref linkend="storage-toast"/> and <xref linkend="xtypes-toast"/>.
+ The specific other value given merely determines the default TOAST
+ storage strategy for columns of a toastable data type; users can pick
+ other strategies for individual columns using <literal>ALTER TABLE
+ SET STORAGE</literal>.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">like_type</replaceable> parameter
+ provides an alternative method for specifying the basic representation
+ properties of a data type: copy them from some existing type. The values of
+ <replaceable class="parameter">internallength</replaceable>,
+ <replaceable class="parameter">passedbyvalue</replaceable>,
+ <replaceable class="parameter">alignment</replaceable>, and
+ <replaceable class="parameter">storage</replaceable> are copied from the
+ named type. (It is possible, though usually undesirable, to override
+ some of these values by specifying them along with the <literal>LIKE</literal>
+ clause.) Specifying representation this way is especially useful when
+ the low-level implementation of the new type <quote>piggybacks</quote> on an
+ existing type in some fashion.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">category</replaceable> and
+ <replaceable class="parameter">preferred</replaceable> parameters can be
+ used to help control which implicit cast will be applied in ambiguous
+ situations. Each data type belongs to a category named by a single ASCII
+ character, and each type is either <quote>preferred</quote> or not within its
+ category. The parser will prefer casting to preferred types (but only from
+ other types within the same category) when this rule is helpful in
+ resolving overloaded functions or operators. For more details see <xref
+ linkend="typeconv"/>. For types that have no implicit casts to or from any
+ other types, it is sufficient to leave these settings at the defaults.
+ However, for a group of related types that have implicit casts, it is often
+ helpful to mark them all as belonging to a category and select one or two
+ of the <quote>most general</quote> types as being preferred within the category.
+ The <replaceable class="parameter">category</replaceable> parameter is
+ especially useful when adding a user-defined type to an existing built-in
+ category, such as the numeric or string types. However, it is also
+ possible to create new entirely-user-defined type categories. Select any
+ ASCII character other than an upper-case letter to name such a category.
+ </para>
+
+ <para>
+ A default value can be specified, in case a user wants columns of the
+ data type to default to something other than the null value.
+ Specify the default with the <literal>DEFAULT</literal> key word.
+ (Such a default can be overridden by an explicit <literal>DEFAULT</literal>
+ clause attached to a particular column.)
+ </para>
+
+ <para>
+ To indicate that a type is a fixed-length array type,
+ specify the type of the array
+ elements using the <literal>ELEMENT</literal> key word. For example, to
+ define an array of 4-byte integers (<type>int4</type>), specify
+ <literal>ELEMENT = int4</literal>. For more details,
+ see <xref linkend="sql-createtype-array"/> below.
+ </para>
+
+ <para>
+ To indicate the delimiter to be used between values in the external
+ representation of arrays of this type, <replaceable
+ class="parameter">delimiter</replaceable> can be
+ set to a specific character. The default delimiter is the comma
+ (<literal>,</literal>). Note that the delimiter is associated
+ with the array element type, not the array type itself.
+ </para>
+
+ <para>
+ If the optional Boolean
+ parameter <replaceable class="parameter">collatable</replaceable>
+ is true, column definitions and expressions of the type may carry
+ collation information through use of
+ the <literal>COLLATE</literal> clause. It is up to the
+ implementations of the functions operating on the type to actually
+ make use of the collation information; this does not happen
+ automatically merely by marking the type collatable.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-createtype-array" xreflabel="Array Types">
+ <title>Array Types</title>
+
+ <para>
+ Whenever a user-defined type is created,
+ <productname>PostgreSQL</productname> automatically creates an
+ associated array type, whose name consists of the element type's
+ name prepended with an underscore, and truncated if necessary to keep
+ it less than <symbol>NAMEDATALEN</symbol> bytes long. (If the name
+ so generated collides with an existing type name, the process is
+ repeated until a non-colliding name is found.)
+ This implicitly-created array type is variable length and uses the
+ built-in input and output functions <literal>array_in</literal> and
+ <literal>array_out</literal>. Furthermore, this type is what the system
+ uses for constructs such as <literal>ARRAY[]</literal> over the
+ user-defined type. The array type tracks any changes in its
+ element type's owner or schema, and is dropped if the element type is.
+ </para>
+
+ <para>
+ You might reasonably ask why there is an <option>ELEMENT</option>
+ option, if the system makes the correct array type automatically.
+ The main case where it's useful to use <option>ELEMENT</option> is when you are
+ making a fixed-length type that happens to be internally an array of a number of
+ identical things, and you want to allow these things to be accessed
+ directly by subscripting, in addition to whatever operations you plan
+ to provide for the type as a whole. For example, type <type>point</type>
+ is represented as just two floating-point numbers, which can be accessed
+ using <literal>point[0]</literal> and <literal>point[1]</literal>.
+ Note that
+ this facility only works for fixed-length types whose internal form
+ is exactly a sequence of identical fixed-length fields.
+ For historical reasons (i.e., this is clearly wrong but it's far too
+ late to change it), subscripting of fixed-length array types starts from
+ zero, rather than from one as for variable-length arrays.
+ </para>
+
+ <para>
+ Specifying the <option>SUBSCRIPT</option> option allows a data type to
+ be subscripted, even though the system does not otherwise regard it as
+ an array type. The behavior just described for fixed-length arrays is
+ actually implemented by the <option>SUBSCRIPT</option> handler
+ function <function>raw_array_subscript_handler</function>, which is
+ used automatically if you specify <option>ELEMENT</option> for a
+ fixed-length type without also writing <option>SUBSCRIPT</option>.
+ </para>
+
+ <para>
+ When specifying a custom <option>SUBSCRIPT</option> function, it is
+ not necessary to specify <option>ELEMENT</option> unless
+ the <option>SUBSCRIPT</option> handler function needs to
+ consult <structfield>typelem</structfield> to find out what to return.
+ Be aware that specifying <option>ELEMENT</option> causes the system to
+ assume that the new type contains, or is somehow physically dependent on,
+ the element type; thus for example changing properties of the element
+ type won't be allowed if there are any columns of the dependent type.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a type to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">attribute_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an attribute (column) for the composite type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing data type to become a column of the
+ composite type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">collation</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing collation to be associated with a column of
+ a composite type, or with a range type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">label</replaceable></term>
+ <listitem>
+ <para>
+ A string literal representing the textual label associated with
+ one value of an enum type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">subtype</replaceable></term>
+ <listitem>
+ <para>
+ The name of the element type that the range type will represent ranges
+ of.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">subtype_operator_class</replaceable></term>
+ <listitem>
+ <para>
+ The name of a b-tree operator class for the subtype.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">canonical_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of the canonicalization function for the range type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">subtype_diff_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a difference function for the subtype.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">multirange_type_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the corresponding multirange type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">input_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that converts data from the type's
+ external textual form to its internal form.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that converts data from the type's
+ internal form to its external textual form.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">receive_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that converts data from the type's
+ external binary form to its internal form.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">send_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that converts data from the type's
+ internal form to its external binary form.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">type_modifier_input_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that converts an array of modifier(s) for the type
+ into internal form.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">type_modifier_output_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that converts the internal form of the type's
+ modifier(s) to external textual form.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">analyze_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that performs statistical analysis for the
+ data type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">subscript_function</replaceable></term>
+ <listitem>
+ <para>
+ The name of a function that defines what subscripting a value of the
+ data type does.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">internallength</replaceable></term>
+ <listitem>
+ <para>
+ A numeric constant that specifies the length in bytes of the new
+ type's internal representation. The default assumption is that
+ it is variable-length.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">alignment</replaceable></term>
+ <listitem>
+ <para>
+ The storage alignment requirement of the data type. If specified,
+ it must be <literal>char</literal>, <literal>int2</literal>,
+ <literal>int4</literal>, or <literal>double</literal>; the
+ default is <literal>int4</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">storage</replaceable></term>
+ <listitem>
+ <para>
+ The storage strategy for the data type. If specified, must be
+ <literal>plain</literal>, <literal>external</literal>,
+ <literal>extended</literal>, or <literal>main</literal>; the
+ default is <literal>plain</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">like_type</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing data type that the new type will have the
+ same representation as. The values of
+ <replaceable class="parameter">internallength</replaceable>,
+ <replaceable class="parameter">passedbyvalue</replaceable>,
+ <replaceable class="parameter">alignment</replaceable>, and
+ <replaceable class="parameter">storage</replaceable>
+ are copied from that type, unless overridden by explicit
+ specification elsewhere in this <command>CREATE TYPE</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">category</replaceable></term>
+ <listitem>
+ <para>
+ The category code (a single ASCII character) for this type.
+ The default is <literal>'U'</literal> for <quote>user-defined type</quote>.
+ Other standard category codes can be found in
+ <xref linkend="catalog-typcategory-table"/>. You may also choose
+ other ASCII characters in order to create custom categories.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">preferred</replaceable></term>
+ <listitem>
+ <para>
+ True if this type is a preferred type within its type category,
+ else false. The default is false. Be very careful about creating
+ a new preferred type within an existing type category, as this
+ could cause surprising changes in behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">default</replaceable></term>
+ <listitem>
+ <para>
+ The default value for the data type. If this is omitted, the
+ default is null.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">element</replaceable></term>
+ <listitem>
+ <para>
+ The type being created is an array; this specifies the type of
+ the array elements.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">delimiter</replaceable></term>
+ <listitem>
+ <para>
+ The delimiter character to be used between values in arrays made
+ of this type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">collatable</replaceable></term>
+ <listitem>
+ <para>
+ True if this type's operations can use collation information.
+ The default is false.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-createtype-notes">
+ <title>Notes</title>
+
+ <para>
+ Because there are no restrictions on use of a data type once it's been
+ created, creating a base type or range type is tantamount to granting
+ public execute permission on the functions mentioned in the type definition.
+ This is usually
+ not an issue for the sorts of functions that are useful in a type
+ definition. But you might want to think twice before designing a type
+ in a way that would require <quote>secret</quote> information to be used
+ while converting it to or from external form.
+ </para>
+
+ <para>
+ Before <productname>PostgreSQL</productname> version 8.3, the name of
+ a generated array type was always exactly the element type's name with one
+ underscore character (<literal>_</literal>) prepended. (Type names were
+ therefore restricted in length to one fewer character than other names.)
+ While this is still usually the case, the array type name may vary from
+ this in case of maximum-length names or collisions with user type names
+ that begin with underscore. Writing code that depends on this convention
+ is therefore deprecated. Instead, use
+ <structname>pg_type</structname>.<structfield>typarray</structfield> to locate the array type
+ associated with a given type.
+ </para>
+
+ <para>
+ It may be advisable to avoid using type and table names that begin with
+ underscore. While the server will change generated array type names to
+ avoid collisions with user-given names, there is still risk of confusion,
+ particularly with old client software that may assume that type names
+ beginning with underscores always represent arrays.
+ </para>
+
+ <para>
+ Before <productname>PostgreSQL</productname> version 8.2, the shell-type
+ creation syntax
+ <literal>CREATE TYPE <replaceable>name</replaceable></literal> did not exist.
+ The way to create a new base type was to create its input function first.
+ In this approach, <productname>PostgreSQL</productname> will first see
+ the name of the new data type as the return type of the input function.
+ The shell type is implicitly created in this situation, and then it
+ can be referenced in the definitions of the remaining I/O functions.
+ This approach still works, but is deprecated and might be disallowed in
+ some future release. Also, to avoid accidentally cluttering
+ the catalogs with shell types as a result of simple typos in function
+ definitions, a shell type will only be made this way when the input
+ function is written in C.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This example creates a composite type and uses it in
+ a function definition:
+<programlisting>
+CREATE TYPE compfoo AS (f1 int, f2 text);
+
+CREATE FUNCTION getfoo() RETURNS SETOF compfoo AS $$
+ SELECT fooid, fooname FROM foo
+$$ LANGUAGE SQL;
+</programlisting>
+ </para>
+
+ <para>
+ This example creates an enumerated type and uses it in
+ a table definition:
+<programlisting>
+CREATE TYPE bug_status AS ENUM ('new', 'open', 'closed');
+
+CREATE TABLE bug (
+ id serial,
+ description text,
+ status bug_status
+);
+</programlisting>
+ </para>
+
+ <para>
+ This example creates a range type:
+<programlisting>
+CREATE TYPE float8_range AS RANGE (subtype = float8, subtype_diff = float8mi);
+</programlisting>
+ </para>
+
+ <para>
+ This example creates the base data type <type>box</type> and then uses the
+ type in a table definition:
+<programlisting>
+CREATE TYPE box;
+
+CREATE FUNCTION my_box_in_function(cstring) RETURNS box AS ... ;
+CREATE FUNCTION my_box_out_function(box) RETURNS cstring AS ... ;
+
+CREATE TYPE box (
+ INTERNALLENGTH = 16,
+ INPUT = my_box_in_function,
+ OUTPUT = my_box_out_function
+);
+
+CREATE TABLE myboxes (
+ id integer,
+ description box
+);
+</programlisting>
+ </para>
+
+ <para>
+ If the internal structure of <type>box</type> were an array of four
+ <type>float4</type> elements, we might instead use:
+<programlisting>
+CREATE TYPE box (
+ INTERNALLENGTH = 16,
+ INPUT = my_box_in_function,
+ OUTPUT = my_box_out_function,
+ ELEMENT = float4
+);
+</programlisting>
+ which would allow a box value's component numbers to be accessed
+ by subscripting. Otherwise the type behaves the same as before.
+ </para>
+
+ <para>
+ This example creates a large object type and uses it in
+ a table definition:
+<programlisting>
+CREATE TYPE bigobj (
+ INPUT = lo_filein, OUTPUT = lo_fileout,
+ INTERNALLENGTH = VARIABLE
+);
+CREATE TABLE big_objs (
+ id integer,
+ obj bigobj
+);
+</programlisting>
+ </para>
+
+ <para>
+ More examples, including suitable input and output functions, are
+ in <xref linkend="xtypes"/>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtype-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The first form of the <command>CREATE TYPE</command> command, which
+ creates a composite type, conforms to the <acronym>SQL</acronym> standard.
+ The other forms are <productname>PostgreSQL</productname>
+ extensions. The <command>CREATE TYPE</command> statement in
+ the <acronym>SQL</acronym> standard also defines other forms that are not
+ implemented in <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ The ability to create a composite type with zero attributes is
+ a <productname>PostgreSQL</productname>-specific deviation from the
+ standard (analogous to the same case in <command>CREATE TABLE</command>).
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-createtype-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertype"/></member>
+ <member><xref linkend="sql-createdomain"/></member>
+ <member><xref linkend="sql-createfunction"/></member>
+ <member><xref linkend="sql-droptype"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_user.sgml b/doc/src/sgml/ref/create_user.sgml
new file mode 100644
index 0000000..48d2089
--- /dev/null
+++ b/doc/src/sgml/ref/create_user.sgml
@@ -0,0 +1,78 @@
+<!--
+doc/src/sgml/ref/create_user.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createuser">
+ <indexterm zone="sql-createuser">
+ <primary>CREATE USER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE USER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE USER</refname>
+ <refpurpose>define a new database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE USER <replaceable class="parameter">name</replaceable> [ [ WITH ] <replaceable class="parameter">option</replaceable> [ ... ] ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ SUPERUSER | NOSUPERUSER
+ | CREATEDB | NOCREATEDB
+ | CREATEROLE | NOCREATEROLE
+ | INHERIT | NOINHERIT
+ | LOGIN | NOLOGIN
+ | REPLICATION | NOREPLICATION
+ | BYPASSRLS | NOBYPASSRLS
+ | CONNECTION LIMIT <replaceable class="parameter">connlimit</replaceable>
+ | [ ENCRYPTED ] PASSWORD '<replaceable class="parameter">password</replaceable>' | PASSWORD NULL
+ | VALID UNTIL '<replaceable class="parameter">timestamp</replaceable>'
+ | IN ROLE <replaceable class="parameter">role_name</replaceable> [, ...]
+ | IN GROUP <replaceable class="parameter">role_name</replaceable> [, ...]
+ | ROLE <replaceable class="parameter">role_name</replaceable> [, ...]
+ | ADMIN <replaceable class="parameter">role_name</replaceable> [, ...]
+ | USER <replaceable class="parameter">role_name</replaceable> [, ...]
+ | SYSID <replaceable class="parameter">uid</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE USER</command> is now an alias for
+ <link linkend="sql-createrole"><command>CREATE ROLE</command></link>.
+ The only difference is that when the command is spelled
+ <command>CREATE USER</command>, <literal>LOGIN</literal> is assumed
+ by default, whereas <literal>NOLOGIN</literal> is assumed when
+ the command is spelled
+ <command>CREATE ROLE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>CREATE USER</command> statement is a
+ <productname>PostgreSQL</productname> extension. The SQL standard
+ leaves the definition of users to the implementation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createrole"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/create_user_mapping.sgml b/doc/src/sgml/ref/create_user_mapping.sgml
new file mode 100644
index 0000000..55debd5
--- /dev/null
+++ b/doc/src/sgml/ref/create_user_mapping.sgml
@@ -0,0 +1,132 @@
+<!--
+doc/src/sgml/ref/create_user_mapping.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createusermapping">
+ <indexterm zone="sql-createusermapping">
+ <primary>CREATE USER MAPPING</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE USER MAPPING</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE USER MAPPING</refname>
+ <refpurpose>define a new mapping of a user to a foreign server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE USER MAPPING [ IF NOT EXISTS ] FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC }
+ SERVER <replaceable class="parameter">server_name</replaceable>
+ [ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [ , ... ] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE USER MAPPING</command> defines a mapping of a user
+ to a foreign server. A user mapping typically encapsulates
+ connection information that a foreign-data wrapper uses together
+ with the information encapsulated by a foreign server to access an
+ external data resource.
+ </para>
+
+ <para>
+ The owner of a foreign server can create user mappings for that
+ server for any user. Also, a user can create a user mapping for
+ their own user name if <literal>USAGE</literal> privilege on the server has
+ been granted to the user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF NOT EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if a mapping of the given user to the given foreign
+ server already exists. A notice is issued in this case. Note that there
+ is no guarantee that the existing user mapping is anything like the one
+ that would have been created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing user that is mapped to foreign server.
+ <literal>CURRENT_ROLE</literal>, <literal>CURRENT_USER</literal>, and <literal>USER</literal> match the name of
+ the current user. When <literal>PUBLIC</literal> is specified, a
+ so-called public mapping is created that is used when no
+ user-specific mapping is applicable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing server for which the user mapping is
+ to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies the options of the user mapping. The
+ options typically define the actual user name and password of
+ the mapping. Option names must be unique. The allowed option
+ names and values are specific to the server's foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a user mapping for user <literal>bob</literal>, server <literal>foo</literal>:
+<programlisting>
+CREATE USER MAPPING FOR bob SERVER foo OPTIONS (user 'bob', password 'secret');
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE USER MAPPING</command> conforms to ISO/IEC 9075-9 (SQL/MED).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterusermapping"/></member>
+ <member><xref linkend="sql-dropusermapping"/></member>
+ <member><xref linkend="sql-createforeigndatawrapper"/></member>
+ <member><xref linkend="sql-createserver"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/create_view.sgml b/doc/src/sgml/ref/create_view.sgml
new file mode 100644
index 0000000..3b26205
--- /dev/null
+++ b/doc/src/sgml/ref/create_view.sgml
@@ -0,0 +1,575 @@
+<!--
+doc/src/sgml/ref/create_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-createview">
+ <indexterm zone="sql-createview">
+ <primary>CREATE VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>CREATE VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>CREATE VIEW</refname>
+ <refpurpose>define a new view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW <replaceable class="parameter">name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+ [ WITH ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] ) ]
+ AS <replaceable class="parameter">query</replaceable>
+ [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE VIEW</command> defines a view of a query. The view
+ is not physically materialized. Instead, the query is run every time
+ the view is referenced in a query.
+ </para>
+
+ <para>
+ <command>CREATE OR REPLACE VIEW</command> is similar, but if a view
+ of the same name already exists, it is replaced. The new query must
+ generate the same columns that were generated by the existing view query
+ (that is, the same column names in the same order and with the same data
+ types), but it may add additional columns to the end of the list. The
+ calculations giving rise to the output columns may be completely different.
+ </para>
+
+ <para>
+ If a schema name is given (for example, <literal>CREATE VIEW
+ myschema.myview ...</literal>) then the view is created in the specified
+ schema. Otherwise it is created in the current schema. Temporary
+ views exist in a special schema, so a schema name cannot be given
+ when creating a temporary view. The name of the view must be
+ distinct from the name of any other relation (table, sequence, index, view,
+ materialized view, or foreign table) in the same schema.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ If specified, the view is created as a temporary view.
+ Temporary views are automatically dropped at the end of the
+ current session. Existing
+ permanent relations with the same name are not visible to the
+ current session while the temporary view exists, unless they are
+ referenced with schema-qualified names.
+ </para>
+
+ <para>
+ If any of the tables referenced by the view are temporary,
+ the view is created as a temporary view (whether
+ <literal>TEMPORARY</literal> is specified or not).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RECURSIVE</literal>
+ <indexterm zone="sql-createview">
+ <primary>RECURSIVE</primary>
+ <secondary>in views</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Creates a recursive view. The syntax
+<synopsis>
+CREATE RECURSIVE VIEW [ <replaceable>schema</replaceable> . ] <replaceable>view_name</replaceable> (<replaceable>column_names</replaceable>) AS SELECT <replaceable>...</replaceable>;
+</synopsis>
+ is equivalent to
+<synopsis>
+CREATE VIEW [ <replaceable>schema</replaceable> . ] <replaceable>view_name</replaceable> AS WITH RECURSIVE <replaceable>view_name</replaceable> (<replaceable>column_names</replaceable>) AS (SELECT <replaceable>...</replaceable>) SELECT <replaceable>column_names</replaceable> FROM <replaceable>view_name</replaceable>;
+</synopsis>
+ A view column name list must be specified for a recursive view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a view to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ An optional list of names to be used for columns of the view.
+ If not given, the column names are deduced from the query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH ( <replaceable class="parameter">view_option_name</replaceable> [= <replaceable class="parameter">view_option_value</replaceable>] [, ... ] )</literal></term>
+ <listitem>
+ <para>
+ This clause specifies optional parameters for a view; the following
+ parameters are supported:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>check_option</literal> (<type>enum</type>)</term>
+ <listitem>
+ <para>
+ This parameter may be either <literal>local</literal> or
+ <literal>cascaded</literal>, and is equivalent to specifying
+ <literal>WITH [ CASCADED | LOCAL ] CHECK OPTION</literal> (see below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>security_barrier</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This should be used if the view is intended to provide row-level
+ security. See <xref linkend="rules-privileges"/> for full details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>security_invoker</literal> (<type>boolean</type>)</term>
+ <listitem>
+ <para>
+ This option causes the underlying base relations to be checked
+ against the privileges of the user of the view rather than the view
+ owner. See the notes below for full details.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ All of the above options can be changed on existing views using <link
+ linkend="sql-alterview"><command>ALTER VIEW</command></link>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">query</replaceable></term>
+ <listitem>
+ <para>
+ A <link linkend="sql-select"><command>SELECT</command></link> or
+ <link linkend="sql-values"><command>VALUES</command></link> command
+ which will provide the columns and rows of the view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH [ CASCADED | LOCAL ] CHECK OPTION</literal>
+ <indexterm zone="sql-createview">
+ <primary>CHECK OPTION</primary>
+ </indexterm>
+ <indexterm zone="sql-createview">
+ <primary>WITH CHECK OPTION</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This option controls the behavior of automatically updatable views. When
+ this option is specified, <command>INSERT</command> and <command>UPDATE</command>
+ commands on the view will be checked to ensure that new rows satisfy the
+ view-defining condition (that is, the new rows are checked to ensure that
+ they are visible through the view). If they are not, the update will be
+ rejected. If the <literal>CHECK OPTION</literal> is not specified,
+ <command>INSERT</command> and <command>UPDATE</command> commands on the view are
+ allowed to create rows that are not visible through the view. The
+ following check options are supported:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>LOCAL</literal></term>
+ <listitem>
+ <para>
+ New rows are only checked against the conditions defined directly in
+ the view itself. Any conditions defined on underlying base views are
+ not checked (unless they also specify the <literal>CHECK OPTION</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADED</literal></term>
+ <listitem>
+ <para>
+ New rows are checked against the conditions of the view and all
+ underlying base views. If the <literal>CHECK OPTION</literal> is specified,
+ and neither <literal>LOCAL</literal> nor <literal>CASCADED</literal> is specified,
+ then <literal>CASCADED</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <literal>CHECK OPTION</literal> may not be used with <literal>RECURSIVE</literal>
+ views.
+ </para>
+
+ <para>
+ Note that the <literal>CHECK OPTION</literal> is only supported on views that
+ are automatically updatable, and do not have <literal>INSTEAD OF</literal>
+ triggers or <literal>INSTEAD</literal> rules. If an automatically updatable
+ view is defined on top of a base view that has <literal>INSTEAD OF</literal>
+ triggers, then the <literal>LOCAL CHECK OPTION</literal> may be used to check
+ the conditions on the automatically updatable view, but the conditions
+ on the base view with <literal>INSTEAD OF</literal> triggers will not be
+ checked (a cascaded check option will not cascade down to a
+ trigger-updatable view, and any check options defined directly on a
+ trigger-updatable view will be ignored). If the view or any of its base
+ relations has an <literal>INSTEAD</literal> rule that causes the
+ <command>INSERT</command> or <command>UPDATE</command> command to be rewritten, then
+ all check options will be ignored in the rewritten query, including any
+ checks from automatically updatable views defined on top of the relation
+ with the <literal>INSTEAD</literal> rule.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use the <link linkend="sql-dropview"><command>DROP VIEW</command></link>
+ statement to drop views.
+ </para>
+
+ <para>
+ Be careful that the names and types of the view's columns will be
+ assigned the way you want. For example:
+<programlisting>
+CREATE VIEW vista AS SELECT 'Hello World';
+</programlisting>
+ is bad form because the column name defaults to <literal>?column?</literal>;
+ also, the column data type defaults to <type>text</type>, which might not
+ be what you wanted. Better style for a string literal in a view's
+ result is something like:
+<programlisting>
+CREATE VIEW vista AS SELECT text 'Hello World' AS hello;
+</programlisting>
+ </para>
+
+ <para>
+ By default, access to the underlying base relations referenced in the view
+ is determined by the permissions of the view owner. In some cases, this
+ can be used to provide secure but restricted access to the underlying
+ tables. However, not all views are secure against tampering; see <xref
+ linkend="rules-privileges"/> for details.
+ </para>
+
+ <para>
+ If the view has the <literal>security_invoker</literal> property set to
+ <literal>true</literal>, access to the underlying base relations is
+ determined by the permissions of the user executing the query, rather than
+ the view owner. Thus, the user of a security invoker view must have the
+ relevant permissions on the view and its underlying base relations.
+ </para>
+
+ <para>
+ If any of the underlying base relations is a security invoker view, it
+ will be treated as if it had been accessed directly from the original
+ query. Thus, a security invoker view will always check its underlying
+ base relations using the permissions of the current user, even if it is
+ accessed from a view without the <literal>security_invoker</literal>
+ property.
+ </para>
+
+ <para>
+ If any of the underlying base relations has
+ <link linkend="ddl-rowsecurity">row-level security</link> enabled, then
+ by default, the row-level security policies of the view owner are applied,
+ and access to any additional relations referred to by those policies is
+ determined by the permissions of the view owner. However, if the view has
+ <literal>security_invoker</literal> set to <literal>true</literal>, then
+ the policies and permissions of the invoking user are used instead, as if
+ the base relations had been referenced directly from the query using the
+ view.
+ </para>
+
+ <para>
+ Functions called in the view are treated the same as if they had been
+ called directly from the query using the view. Therefore, the user of
+ a view must have permissions to call all functions used by the view.
+ Functions in the view are executed with the privileges of the user
+ executing the query or the function owner, depending on whether the
+ functions are defined as <literal>SECURITY INVOKER</literal> or
+ <literal>SECURITY DEFINER</literal>. Thus, for example, calling
+ <literal>CURRENT_USER</literal> directly in a view will always return the
+ invoking user, not the view owner. This is not affected by the view's
+ <literal>security_invoker</literal> setting, and so a view with
+ <literal>security_invoker</literal> set to <literal>false</literal> is
+ <emphasis>not</emphasis> equivalent to a
+ <literal>SECURITY DEFINER</literal> function and those concepts should not
+ be confused.
+ </para>
+
+ <para>
+ The user creating or replacing a view must have <literal>USAGE</literal>
+ privileges on any schemas referred to in the view query, in order to look
+ up the referenced objects in those schemas. Note, however, that this
+ lookup only happens when the view is created or replaced. Therefore, the
+ user of the view only requires the <literal>USAGE</literal> privilege on
+ the schema containing the view, not on the schemas referred to in the view
+ query, even for a security invoker view.
+ </para>
+
+ <para>
+ When <command>CREATE OR REPLACE VIEW</command> is used on an existing
+ view, only the view's defining SELECT rule, plus any
+ <literal>WITH ( ... )</literal> parameters and its
+ <literal>CHECK OPTION</literal> are changed.
+ Other view properties, including ownership, permissions, and non-SELECT
+ rules, remain unchanged. You must own the view
+ to replace it (this includes being a member of the owning role).
+ </para>
+
+ <refsect2 id="sql-createview-updatable-views">
+ <title>Updatable Views</title>
+
+ <indexterm zone="sql-createview-updatable-views">
+ <primary>updatable views</primary>
+ </indexterm>
+
+ <para>
+ Simple views are automatically updatable: the system will allow
+ <command>INSERT</command>, <command>UPDATE</command> and <command>DELETE</command> statements
+ to be used on the view in the same way as on a regular table. A view is
+ automatically updatable if it satisfies all of the following conditions:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The view must have exactly one entry in its <literal>FROM</literal> list,
+ which must be a table or another updatable view.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The view definition must not contain <literal>WITH</literal>,
+ <literal>DISTINCT</literal>, <literal>GROUP BY</literal>, <literal>HAVING</literal>,
+ <literal>LIMIT</literal>, or <literal>OFFSET</literal> clauses at the top level.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The view definition must not contain set operations (<literal>UNION</literal>,
+ <literal>INTERSECT</literal> or <literal>EXCEPT</literal>) at the top level.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The view's select list must not contain any aggregates, window functions
+ or set-returning functions.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ An automatically updatable view may contain a mix of updatable and
+ non-updatable columns. A column is updatable if it is a simple reference
+ to an updatable column of the underlying base relation; otherwise the
+ column is read-only, and an error will be raised if an <command>INSERT</command>
+ or <command>UPDATE</command> statement attempts to assign a value to it.
+ </para>
+
+ <para>
+ If the view is automatically updatable the system will convert any
+ <command>INSERT</command>, <command>UPDATE</command> or <command>DELETE</command> statement
+ on the view into the corresponding statement on the underlying base
+ relation. <command>INSERT</command> statements that have an <literal>ON
+ CONFLICT UPDATE</literal> clause are fully supported.
+ </para>
+
+ <para>
+ If an automatically updatable view contains a <literal>WHERE</literal>
+ condition, the condition restricts which rows of the base relation are
+ available to be modified by <command>UPDATE</command> and <command>DELETE</command>
+ statements on the view. However, an <command>UPDATE</command> is allowed to
+ change a row so that it no longer satisfies the <literal>WHERE</literal>
+ condition, and thus is no longer visible through the view. Similarly,
+ an <command>INSERT</command> command can potentially insert base-relation rows
+ that do not satisfy the <literal>WHERE</literal> condition and thus are not
+ visible through the view (<literal>ON CONFLICT UPDATE</literal> may
+ similarly affect an existing row not visible through the view).
+ The <literal>CHECK OPTION</literal> may be used to prevent
+ <command>INSERT</command> and <command>UPDATE</command> commands from creating
+ such rows that are not visible through the view.
+ </para>
+
+ <para>
+ If an automatically updatable view is marked with the
+ <literal>security_barrier</literal> property then all the view's <literal>WHERE</literal>
+ conditions (and any conditions using operators which are marked as <literal>LEAKPROOF</literal>)
+ will always be evaluated before any conditions that a user of the view has
+ added. See <xref linkend="rules-privileges"/> for full details. Note that,
+ due to this, rows which are not ultimately returned (because they do not
+ pass the user's <literal>WHERE</literal> conditions) may still end up being locked.
+ <command>EXPLAIN</command> can be used to see which conditions are
+ applied at the relation level (and therefore do not lock rows) and which are
+ not.
+ </para>
+
+ <para>
+ A more complex view that does not satisfy all these conditions is
+ read-only by default: the system will not allow an insert, update, or
+ delete on the view. You can get the effect of an updatable view by
+ creating <literal>INSTEAD OF</literal> triggers on the view, which must
+ convert attempted inserts, etc. on the view into appropriate actions
+ on other tables. For more information see <xref
+ linkend="sql-createtrigger"/>. Another possibility is to create rules
+ (see <xref linkend="sql-createrule"/>), but in practice triggers are
+ easier to understand and use correctly.
+ </para>
+
+ <para>
+ Note that the user performing the insert, update or delete on the view
+ must have the corresponding insert, update or delete privilege on the
+ view. In addition, by default, the view's owner must have the relevant
+ privileges on the underlying base relations, whereas the user performing
+ the update does not need any permissions on the underlying base relations
+ (see <xref linkend="rules-privileges"/>). However, if the view has
+ <literal>security_invoker</literal> set to <literal>true</literal>, the
+ user performing the update, rather than the view owner, must have the
+ relevant privileges on the underlying base relations.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a view consisting of all comedy films:
+
+<programlisting>
+CREATE VIEW comedies AS
+ SELECT *
+ FROM films
+ WHERE kind = 'Comedy';
+</programlisting>
+ This will create a view containing the columns that are in the
+ <literal>film</literal> table at the time of view creation. Though
+ <literal>*</literal> was used to create the view, columns added later to
+ the table will not be part of the view.
+ </para>
+
+ <para>
+ Create a view with <literal>LOCAL CHECK OPTION</literal>:
+
+<programlisting>
+CREATE VIEW universal_comedies AS
+ SELECT *
+ FROM comedies
+ WHERE classification = 'U'
+ WITH LOCAL CHECK OPTION;
+</programlisting>
+ This will create a view based on the <literal>comedies</literal> view, showing
+ only films with <literal>kind = 'Comedy'</literal> and
+ <literal>classification = 'U'</literal>. Any attempt to <command>INSERT</command> or
+ <command>UPDATE</command> a row in the view will be rejected if the new row
+ doesn't have <literal>classification = 'U'</literal>, but the film
+ <literal>kind</literal> will not be checked.
+ </para>
+
+ <para>
+ Create a view with <literal>CASCADED CHECK OPTION</literal>:
+
+<programlisting>
+CREATE VIEW pg_comedies AS
+ SELECT *
+ FROM comedies
+ WHERE classification = 'PG'
+ WITH CASCADED CHECK OPTION;
+</programlisting>
+ This will create a view that checks both the <literal>kind</literal> and
+ <literal>classification</literal> of new rows.
+ </para>
+
+ <para>
+ Create a view with a mix of updatable and non-updatable columns:
+
+<programlisting>
+CREATE VIEW comedies AS
+ SELECT f.*,
+ country_code_to_name(f.country_code) AS country,
+ (SELECT avg(r.rating)
+ FROM user_ratings r
+ WHERE r.film_id = f.id) AS avg_rating
+ FROM films f
+ WHERE f.kind = 'Comedy';
+</programlisting>
+ This view will support <command>INSERT</command>, <command>UPDATE</command> and
+ <command>DELETE</command>. All the columns from the <literal>films</literal> table will
+ be updatable, whereas the computed columns <literal>country</literal> and
+ <literal>avg_rating</literal> will be read-only.
+ </para>
+
+ <para>
+ Create a recursive view consisting of the numbers from 1 to 100:
+<programlisting>
+CREATE RECURSIVE VIEW public.nums_1_100 (n) AS
+ VALUES (1)
+UNION ALL
+ SELECT n+1 FROM nums_1_100 WHERE n &lt; 100;
+</programlisting>
+ Notice that although the recursive view's name is schema-qualified in this
+ <command>CREATE</command>, its internal self-reference is not schema-qualified.
+ This is because the implicitly-created CTE's name cannot be
+ schema-qualified.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>CREATE OR REPLACE VIEW</command> is a
+ <productname>PostgreSQL</productname> language extension.
+ So is the concept of a temporary view.
+ The <literal>WITH ( ... )</literal> clause is an extension as well, as are
+ security barrier views and security invoker views.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterview"/></member>
+ <member><xref linkend="sql-dropview"/></member>
+ <member><xref linkend="sql-creatematerializedview"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml
new file mode 100644
index 0000000..671cd36
--- /dev/null
+++ b/doc/src/sgml/ref/createdb.sgml
@@ -0,0 +1,426 @@
+<!--
+doc/src/sgml/ref/createdb.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-createdb">
+ <indexterm zone="app-createdb">
+ <primary>createdb</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>createdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>createdb</refname>
+ <refpurpose>create a new <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>createdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>dbname</replaceable>
+ <arg choice="opt"><replaceable>description</replaceable></arg></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="r1-app-createdb-1">
+ <title>Description</title>
+ <para>
+ <application>createdb</application> creates a new <productname>PostgreSQL</productname>
+ database.
+ </para>
+
+ <para>
+ Normally, the database user who executes this command becomes the owner of
+ the new database.
+ However, a different owner can be specified via the <option>-O</option>
+ option, if the executing user has appropriate privileges.
+ </para>
+
+ <para>
+ <application>createdb</application> is a wrapper around the
+ <acronym>SQL</acronym> command <link linkend="sql-createdatabase"><command>CREATE DATABASE</command></link>.
+ There is no effective difference between creating databases via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>createdb</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">dbname</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be created. The name must be
+ unique among all <productname>PostgreSQL</productname> databases in this cluster.
+ The default is to create a database with the same name as the
+ current system user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">description</replaceable></term>
+ <listitem>
+ <para>
+ Specifies a comment to be associated with the newly created
+ database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">tablespace</replaceable></option></term>
+ <term><option>--tablespace=<replaceable class="parameter">tablespace</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the default tablespace for the database. (This name
+ is processed as a double-quoted identifier.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>createdb</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E <replaceable class="parameter">encoding</replaceable></option></term>
+ <term><option>--encoding=<replaceable class="parameter">encoding</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the character encoding scheme to be used in this
+ database. The character sets supported by the
+ <productname>PostgreSQL</productname> server are described in
+ <xref linkend="multibyte-charset-supported"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l <replaceable class="parameter">locale</replaceable></option></term>
+ <term><option>--locale=<replaceable class="parameter">locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the locale to be used in this database. This is equivalent
+ to specifying both <option>--lc-collate</option> and <option>--lc-ctype</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--lc-collate=<replaceable class="parameter">locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the LC_COLLATE setting to be used in this database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--lc-ctype=<replaceable class="parameter">locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the LC_CTYPE setting to be used in this database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--icu-locale=<replaceable class="parameter">locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the ICU locale ID to be used in this database, if the
+ ICU locale provider is selected.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <listitem>
+ <para>
+ Specifies the locale provider for the database's default collation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O <replaceable class="parameter">owner</replaceable></option></term>
+ <term><option>--owner=<replaceable class="parameter">owner</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the database user who will own the new database.
+ (This name is processed as a double-quoted identifier.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">template</replaceable></option></term>
+ <term><option>--strategy=<replaceable class="parameter">strategy</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the database creation strategy. See
+ <xref linkend="create-database-strategy" /> for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable class="parameter">template</replaceable></option></term>
+ <term><option>--template=<replaceable class="parameter">template</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the template database from which to build this
+ database. (This name is processed as a double-quoted identifier.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>createdb</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>createdb</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ The options <option>-D</option>, <option>-l</option>, <option>-E</option>,
+ <option>-O</option>, and
+ <option>-T</option> correspond to options of the underlying
+ SQL command <link linkend="sql-createdatabase"><command>CREATE DATABASE</command></link>; see there for more information
+ about them.
+ </para>
+
+ <para>
+ <application>createdb</application> also accepts the following
+ command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the
+ server is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or the local Unix domain socket file
+ extension on which the server is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>createdb</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>createdb</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>createdb</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to when creating the
+ new database. If not specified, the <literal>postgres</literal>
+ database will be used; if that does not exist (or if it is the name
+ of the new database being created), <literal>template1</literal> will
+ be used.
+ This can be a <link linkend="libpq-connstring">connection
+ string</link>. If so, connection string parameters will override any
+ conflicting command line options.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <listitem>
+ <para>
+ If set, the name of the database to create, unless overridden on
+ the command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters. <envar>PGUSER</envar> also
+ determines the name of the database to create, if it is not
+ specified on the command line or by <envar>PGDATABASE</envar>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-createdatabase"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create the database <literal>demo</literal> using the default
+ database server:
+<screen>
+<prompt>$ </prompt><userinput>createdb demo</userinput>
+</screen>
+ </para>
+
+ <para>
+ To create the database <literal>demo</literal> using the
+ server on host <literal>eden</literal>, port 5000, using the
+ <literal>template0</literal> template database, here is the
+ command-line command and the underlying SQL command:
+<screen>
+<prompt>$ </prompt><userinput>createdb -p 5000 -h eden -T template0 -e demo</userinput>
+<computeroutput>CREATE DATABASE demo TEMPLATE template0;</computeroutput>
+</screen></para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-dropdb"/></member>
+ <member><xref linkend="sql-createdatabase"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml
new file mode 100644
index 0000000..0e1a39a
--- /dev/null
+++ b/doc/src/sgml/ref/createuser.sgml
@@ -0,0 +1,506 @@
+<!--
+doc/src/sgml/ref/createuser.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-createuser">
+ <indexterm zone="app-createuser">
+ <primary>createuser</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>createuser</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>createuser</refname>
+ <refpurpose>define a new <productname>PostgreSQL</productname> user account</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>createuser</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>username</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ <application>createuser</application> creates a
+ new <productname>PostgreSQL</productname> user (or more precisely, a role).
+ Only superusers and users with <literal>CREATEROLE</literal> privilege can create
+ new users, so <application>createuser</application> must be
+ invoked by someone who can connect as a superuser or a user with
+ <literal>CREATEROLE</literal> privilege.
+ </para>
+
+ <para>
+ If you wish to create a role with the <literal>SUPERUSER</literal>,
+ <literal>REPLICATION</literal>, or <literal>BYPASSRLS</literal> privilege,
+ you must connect as a superuser, not merely with
+ <literal>CREATEROLE</literal> privilege.
+ Being a superuser implies the ability to bypass all access permission
+ checks within the database, so superuser access should not be granted
+ lightly. <literal>CREATEROLE</literal> also conveys
+ <link linkend='role-creation'>very extensive privileges</link>.
+ </para>
+
+ <para>
+ <application>createuser</application> is a wrapper around the
+ <acronym>SQL</acronym> command <link linkend="sql-createrole"><command>CREATE ROLE</command></link>.
+ There is no effective difference between creating users via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>createuser</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">username</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the <productname>PostgreSQL</productname> user
+ to be created.
+ This name must be different from all existing roles in this
+ <productname>PostgreSQL</productname> installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c <replaceable class="parameter">number</replaceable></option></term>
+ <term><option>--connection-limit=<replaceable class="parameter">number</replaceable></option></term>
+ <listitem>
+ <para>
+ Set a maximum number of connections for the new user.
+ The default is to set no limit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d</option></term>
+ <term><option>--createdb</option></term>
+ <listitem>
+ <para>
+ The new user will be allowed to create databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D</option></term>
+ <term><option>--no-createdb</option></term>
+ <listitem>
+ <para>
+ The new user will not be allowed to create databases. This is the
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>createuser</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E</option></term>
+ <term><option>--encrypted</option></term>
+ <listitem>
+ <para>
+ This option is obsolete but still accepted for backward
+ compatibility.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-g <replaceable class="parameter">role</replaceable></option></term>
+ <term><option>--role=<replaceable class="parameter">role</replaceable></option></term>
+ <listitem>
+ <para>
+ Indicates role to which this role will be added immediately as a new
+ member. Multiple roles to which this role will be added as a member
+ can be specified by writing multiple
+ <option>-g</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <term><option>--inherit</option></term>
+ <listitem>
+ <para>
+ The new role will automatically inherit privileges of roles
+ it is a member of.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-I</option></term>
+ <term><option>--no-inherit</option></term>
+ <listitem>
+ <para>
+ The new role will not automatically inherit privileges of roles
+ it is a member of.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--interactive</option></term>
+ <listitem>
+ <para>
+ Prompt for the user name if none is specified on the command line, and
+ also prompt for whichever of the options
+ <option>-d</option>/<option>-D</option>,
+ <option>-r</option>/<option>-R</option>,
+ <option>-s</option>/<option>-S</option> is not specified on the command
+ line. (This was the default behavior up to PostgreSQL 9.1.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l</option></term>
+ <term><option>--login</option></term>
+ <listitem>
+ <para>
+ The new user will be allowed to log in (that is, the user name
+ can be used as the initial session user identifier).
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-L</option></term>
+ <term><option>--no-login</option></term>
+ <listitem>
+ <para>
+ The new user will not be allowed to log in.
+ (A role without login privilege is still useful as a means of
+ managing database permissions.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+ <term><option>--pwprompt</option></term>
+ <listitem>
+ <para>
+ If given, <application>createuser</application> will issue a prompt for
+ the password of the new user. This is not necessary if you do not plan
+ on using password authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+ <term><option>--createrole</option></term>
+ <listitem>
+ <para>
+ The new user will be allowed to create, alter, drop, comment on,
+ change the security label for, and grant or revoke membership in
+ other roles; that is,
+ this user will have <literal>CREATEROLE</literal> privilege.
+ See <xref linkend='role-creation' /> for more details about what
+ capabilities are conferred by this privilege.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R</option></term>
+ <term><option>--no-createrole</option></term>
+ <listitem>
+ <para>
+ The new user will not be allowed to create new roles. This is the
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--superuser</option></term>
+ <listitem>
+ <para>
+ The new user will be a superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S</option></term>
+ <term><option>--no-superuser</option></term>
+ <listitem>
+ <para>
+ The new user will not be a superuser. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>createuser</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--replication</option></term>
+ <listitem>
+ <para>
+ The new user will have the <literal>REPLICATION</literal> privilege,
+ which is described more fully in the documentation for <xref
+ linkend="sql-createrole"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-replication</option></term>
+ <listitem>
+ <para>
+ The new user will not have the <literal>REPLICATION</literal>
+ privilege, which is described more fully in the documentation for <xref
+ linkend="sql-createrole"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>createuser</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ <application>createuser</application> also accepts the following
+ command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the
+ server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as (not the user name to create).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>createuser</application> to prompt for a
+ password (for connecting to the server, not for the
+ password of the new user).
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>createuser</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>createuser</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-createrole"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create a user <literal>joe</literal> on the default database
+ server:
+<screen>
+<prompt>$ </prompt><userinput>createuser joe</userinput>
+</screen>
+ </para>
+
+ <para>
+ To create a user <literal>joe</literal> on the default database
+ server with prompting for some additional attributes:
+<screen>
+<prompt>$ </prompt><userinput>createuser --interactive joe</userinput>
+<computeroutput>Shall the new role be a superuser? (y/n) </computeroutput><userinput>n</userinput>
+<computeroutput>Shall the new role be allowed to create databases? (y/n) </computeroutput><userinput>n</userinput>
+<computeroutput>Shall the new role be allowed to create more new roles? (y/n) </computeroutput><userinput>n</userinput>
+</screen>
+ </para>
+
+ <para>
+ To create the same user <literal>joe</literal> using the
+ server on host <literal>eden</literal>, port 5000, with attributes explicitly specified,
+ taking a look at the underlying command:
+<screen>
+<prompt>$ </prompt><userinput>createuser -h eden -p 5000 -S -D -R -e joe</userinput>
+<computeroutput>CREATE ROLE joe NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ To create the user <literal>joe</literal> as a superuser,
+ and assign a password immediately:
+<screen>
+<prompt>$ </prompt><userinput>createuser -P -s -e joe</userinput>
+<computeroutput>Enter password for new role: </computeroutput><userinput>xyzzy</userinput>
+<computeroutput>Enter it again: </computeroutput><userinput>xyzzy</userinput>
+<computeroutput>CREATE ROLE joe PASSWORD 'md5b5f5ba1a423792b526f799ae4eb3d59e' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;</computeroutput>
+</screen>
+ In the above example, the new password isn't actually echoed when typed,
+ but we show what was typed for clarity. As you see, the password is
+ encrypted before it is sent to the client.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-dropuser"/></member>
+ <member><xref linkend="sql-createrole"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/deallocate.sgml b/doc/src/sgml/ref/deallocate.sgml
new file mode 100644
index 0000000..3875e50
--- /dev/null
+++ b/doc/src/sgml/ref/deallocate.sgml
@@ -0,0 +1,98 @@
+<!--
+doc/src/sgml/ref/deallocate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-deallocate">
+ <indexterm zone="sql-deallocate">
+ <primary>DEALLOCATE</primary>
+ </indexterm>
+
+ <indexterm zone="sql-deallocate">
+ <primary>prepared statements</primary>
+ <secondary>removing</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DEALLOCATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DEALLOCATE</refname>
+ <refpurpose>deallocate a prepared statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DEALLOCATE [ PREPARE ] { <replaceable class="parameter">name</replaceable> | ALL }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DEALLOCATE</command> is used to deallocate a previously
+ prepared SQL statement. If you do not explicitly deallocate a
+ prepared statement, it is deallocated when the session ends.
+ </para>
+
+ <para>
+ For more information on prepared statements, see <xref
+ linkend="sql-prepare"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>PREPARE</literal></term>
+ <listitem>
+ <para>
+ This key word is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the prepared statement to deallocate.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Deallocate all prepared statements.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard includes a <command>DEALLOCATE</command>
+ statement, but it is only for use in embedded SQL.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-execute"/></member>
+ <member><xref linkend="sql-prepare"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/declare.sgml b/doc/src/sgml/ref/declare.sgml
new file mode 100644
index 0000000..bbbd335
--- /dev/null
+++ b/doc/src/sgml/ref/declare.sgml
@@ -0,0 +1,361 @@
+<!--
+doc/src/sgml/ref/declare.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-declare">
+ <indexterm zone="sql-declare">
+ <primary>DECLARE</primary>
+ </indexterm>
+
+ <indexterm zone="sql-declare">
+ <primary>cursor</primary>
+ <secondary>DECLARE</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DECLARE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DECLARE</refname>
+ <refpurpose>define a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DECLARE <replaceable class="parameter">name</replaceable> [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
+ CURSOR [ { WITH | WITHOUT } HOLD ] FOR <replaceable class="parameter">query</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DECLARE</command> allows a user to create cursors, which
+ can be used to retrieve
+ a small number of rows at a time out of a larger query.
+ After the cursor is created, rows are fetched from it using
+ <link linkend="sql-fetch"><command>FETCH</command></link>.
+ </para>
+
+ <note>
+ <para>
+ This page describes usage of cursors at the SQL command level.
+ If you are trying to use cursors inside a <application>PL/pgSQL</application>
+ function, the rules are different &mdash;
+ see <xref linkend="plpgsql-cursors"/>.
+ </para>
+ </note>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the cursor to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BINARY</literal></term>
+ <listitem>
+ <para>
+ Causes the cursor to return data in binary rather than in text format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ASENSITIVE</literal></term>
+ <term><literal>INSENSITIVE</literal></term>
+ <listitem>
+ <para>
+ Cursor sensitivity determines whether changes to the data underlying the
+ cursor, done in the same transaction, after the cursor has been
+ declared, are visible in the cursor. <literal>INSENSITIVE</literal>
+ means they are not visible, <literal>ASENSITIVE</literal> means the
+ behavior is implementation-dependent. A third behavior,
+ <literal>SENSITIVE</literal>, meaning that such changes are visible in
+ the cursor, is not available in <productname>PostgreSQL</productname>.
+ In <productname>PostgreSQL</productname>, all cursors are insensitive;
+ so these key words have no effect and are only accepted for
+ compatibility with the SQL standard.
+ </para>
+
+ <para>
+ Specifying <literal>INSENSITIVE</literal> together with <literal>FOR
+ UPDATE</literal> or <literal>FOR SHARE</literal> is an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SCROLL</literal></term>
+ <term><literal>NO SCROLL</literal></term>
+ <listitem>
+ <para><literal>SCROLL</literal> specifies that the cursor can be used
+ to retrieve rows in a nonsequential fashion (e.g.,
+ backward). Depending upon the complexity of the query's
+ execution plan, specifying <literal>SCROLL</literal> might impose
+ a performance penalty on the query's execution time.
+ <literal>NO SCROLL</literal> specifies that the cursor cannot be
+ used to retrieve rows in a nonsequential fashion. The default is to
+ allow scrolling in some cases; this is not the same as specifying
+ <literal>SCROLL</literal>. See <xref linkend="sql-declare-notes"/>
+ below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WITH HOLD</literal></term>
+ <term><literal>WITHOUT HOLD</literal></term>
+ <listitem>
+ <para><literal>WITH HOLD</literal> specifies that the cursor can
+ continue to be used after the transaction that created it
+ successfully commits. <literal>WITHOUT HOLD</literal> specifies
+ that the cursor cannot be used outside of the transaction that
+ created it. If neither <literal>WITHOUT HOLD</literal> nor
+ <literal>WITH HOLD</literal> is specified, <literal>WITHOUT
+ HOLD</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">query</replaceable></term>
+ <listitem>
+ <para>
+ A <link linkend="sql-select"><command>SELECT</command></link> or
+ <link linkend="sql-values"><command>VALUES</command></link> command
+ which will provide the rows to be returned by the cursor.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The key words <literal>ASENSITIVE</literal>, <literal>BINARY</literal>,
+ <literal>INSENSITIVE</literal>, and <literal>SCROLL</literal> can
+ appear in any order.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-declare-notes" xreflabel="Notes">
+ <title>Notes</title>
+
+ <para>
+ Normal cursors return data in text format, the same as a
+ <command>SELECT</command> would produce. The <literal>BINARY</literal> option
+ specifies that the cursor should return data in binary format.
+ This reduces conversion effort for both the server and client,
+ at the cost of more programmer effort to deal with platform-dependent
+ binary data formats.
+ As an example, if a query returns a value of one from an integer column,
+ you would get a string of <literal>1</literal> with a default cursor,
+ whereas with a binary cursor you would get
+ a 4-byte field containing the internal representation of the value
+ (in big-endian byte order).
+ </para>
+
+ <para>
+ Binary cursors should be used carefully. Many applications,
+ including <application>psql</application>, are not prepared to
+ handle binary cursors and expect data to come back in the text
+ format.
+ </para>
+
+ <note>
+ <para>
+ When the client application uses the <quote>extended query</quote> protocol
+ to issue a <command>FETCH</command> command, the Bind protocol message
+ specifies whether data is to be retrieved in text or binary format.
+ This choice overrides the way that the cursor is defined. The concept
+ of a binary cursor as such is thus obsolete when using extended query
+ protocol &mdash; any cursor can be treated as either text or binary.
+ </para>
+ </note>
+
+ <para>
+ Unless <literal>WITH HOLD</literal> is specified, the cursor
+ created by this command can only be used within the current
+ transaction. Thus, <command>DECLARE</command> without <literal>WITH
+ HOLD</literal> is useless outside a transaction block: the cursor would
+ survive only to the completion of the statement. Therefore
+ <productname>PostgreSQL</productname> reports an error if such a
+ command is used outside a transaction block.
+ Use
+ <link linkend="sql-begin"><command>BEGIN</command></link> and
+ <link linkend="sql-commit"><command>COMMIT</command></link>
+ (or <link linkend="sql-rollback"><command>ROLLBACK</command></link>)
+ to define a transaction block.
+ </para>
+
+ <para>
+ If <literal>WITH HOLD</literal> is specified and the transaction
+ that created the cursor successfully commits, the cursor can
+ continue to be accessed by subsequent transactions in the same
+ session. (But if the creating transaction is aborted, the cursor
+ is removed.) A cursor created with <literal>WITH HOLD</literal>
+ is closed when an explicit <command>CLOSE</command> command is
+ issued on it, or the session ends. In the current implementation,
+ the rows represented by a held cursor are copied into a temporary
+ file or memory area so that they remain available for subsequent
+ transactions.
+ </para>
+
+ <para>
+ <literal>WITH HOLD</literal> may not be specified when the query
+ includes <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>.
+ </para>
+
+ <para>
+ The <literal>SCROLL</literal> option should be specified when defining a
+ cursor that will be used to fetch backwards. This is required by
+ the SQL standard. However, for compatibility with earlier
+ versions, <productname>PostgreSQL</productname> will allow
+ backward fetches without <literal>SCROLL</literal>, if the cursor's query
+ plan is simple enough that no extra overhead is needed to support
+ it. However, application developers are advised not to rely on
+ using backward fetches from a cursor that has not been created
+ with <literal>SCROLL</literal>. If <literal>NO SCROLL</literal> is
+ specified, then backward fetches are disallowed in any case.
+ </para>
+
+ <para>
+ Backward fetches are also disallowed when the query
+ includes <literal>FOR UPDATE</literal> or <literal>FOR SHARE</literal>; therefore
+ <literal>SCROLL</literal> may not be specified in this case.
+ </para>
+
+ <caution>
+ <para>
+ Scrollable cursors may give unexpected
+ results if they invoke any volatile functions (see <xref
+ linkend="xfunc-volatility"/>). When a previously fetched row is
+ re-fetched, the functions might be re-executed, perhaps leading to
+ results different from the first time. It's best to
+ specify <literal>NO SCROLL</literal> for a query involving volatile
+ functions. If that is not practical, one workaround
+ is to declare the cursor <literal>SCROLL WITH HOLD</literal> and commit the
+ transaction before reading any rows from it. This will force the
+ entire output of the cursor to be materialized in temporary storage,
+ so that volatile functions are executed exactly once for each row.
+ </para>
+ </caution>
+
+ <para>
+ If the cursor's query includes <literal>FOR UPDATE</literal> or <literal>FOR
+ SHARE</literal>, then returned rows are locked at the time they are first
+ fetched, in the same way as for a regular
+ <link linkend="sql-select"><command>SELECT</command></link> command with
+ these options.
+ In addition, the returned rows will be the most up-to-date versions.
+ </para>
+
+ <caution>
+ <para>
+ It is generally recommended to use <literal>FOR UPDATE</literal> if the cursor
+ is intended to be used with <command>UPDATE ... WHERE CURRENT OF</command> or
+ <command>DELETE ... WHERE CURRENT OF</command>. Using <literal>FOR UPDATE</literal>
+ prevents other sessions from changing the rows between the time they are
+ fetched and the time they are updated. Without <literal>FOR UPDATE</literal>,
+ a subsequent <literal>WHERE CURRENT OF</literal> command will have no effect if
+ the row was changed since the cursor was created.
+ </para>
+
+ <para>
+ Another reason to use <literal>FOR UPDATE</literal> is that without it, a
+ subsequent <literal>WHERE CURRENT OF</literal> might fail if the cursor query
+ does not meet the SQL standard's rules for being <quote>simply
+ updatable</quote> (in particular, the cursor must reference just one table
+ and not use grouping or <literal>ORDER BY</literal>). Cursors
+ that are not simply updatable might work, or might not, depending on plan
+ choice details; so in the worst case, an application might work in testing
+ and then fail in production. If <literal>FOR UPDATE</literal> is
+ specified, the cursor is guaranteed to be updatable.
+ </para>
+
+ <para>
+ The main reason not to use <literal>FOR UPDATE</literal> with <literal>WHERE
+ CURRENT OF</literal> is if you need the cursor to be scrollable, or to be
+ isolated from concurrent updates (that is, continue to show the old
+ data). If this is a requirement, pay close heed to the caveats shown
+ above.
+ </para>
+ </caution>
+
+ <para>
+ The SQL standard only makes provisions for cursors in embedded
+ <acronym>SQL</acronym>. The <productname>PostgreSQL</productname>
+ server does not implement an <command>OPEN</command> statement for
+ cursors; a cursor is considered to be open when it is declared.
+ However, <application>ECPG</application>, the embedded SQL
+ preprocessor for <productname>PostgreSQL</productname>, supports
+ the standard SQL cursor conventions, including those involving
+ <command>DECLARE</command> and <command>OPEN</command> statements.
+ </para>
+
+ <para>
+ You can see all available cursors by querying the <link
+ linkend="view-pg-cursors"><structname>pg_cursors</structname></link>
+ system view.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To declare a cursor:
+<programlisting>
+DECLARE liahona CURSOR FOR SELECT * FROM films;
+</programlisting>
+ See <xref linkend="sql-fetch"/> for more
+ examples of cursor usage.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard allows cursors only in embedded
+ <acronym>SQL</acronym> and in modules. <productname>PostgreSQL</productname>
+ permits cursors to be used interactively.
+ </para>
+
+ <para>
+ According to the SQL standard, changes made to insensitive cursors by
+ <literal>UPDATE ... WHERE CURRENT OF</literal> and <literal>DELETE
+ ... WHERE CURRENT OF</literal> statements are visible in that same
+ cursor. <productname>PostgreSQL</productname> treats these statements like
+ all other data changing statements in that they are not visible in
+ insensitive cursors.
+ </para>
+
+ <para>
+ Binary cursors are a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-close"/></member>
+ <member><xref linkend="sql-fetch"/></member>
+ <member><xref linkend="sql-move"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/delete.sgml b/doc/src/sgml/ref/delete.sgml
new file mode 100644
index 0000000..1b81b4e
--- /dev/null
+++ b/doc/src/sgml/ref/delete.sgml
@@ -0,0 +1,289 @@
+<!--
+doc/src/sgml/ref/delete.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-delete">
+ <indexterm zone="sql-delete">
+ <primary>DELETE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DELETE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DELETE</refname>
+ <refpurpose>delete rows of a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
+DELETE FROM [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
+ [ USING <replaceable class="parameter">from_item</replaceable> [, ...] ]
+ [ WHERE <replaceable class="parameter">condition</replaceable> | WHERE CURRENT OF <replaceable class="parameter">cursor_name</replaceable> ]
+ [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DELETE</command> deletes rows that satisfy the
+ <literal>WHERE</literal> clause from the specified table. If the
+ <literal>WHERE</literal> clause is absent, the effect is to delete
+ all rows in the table. The result is a valid, but empty table.
+ </para>
+
+ <tip>
+ <para>
+ <link linkend="sql-truncate"><command>TRUNCATE</command></link> provides a
+ faster mechanism to remove all rows from a table.
+ </para>
+ </tip>
+
+ <para>
+ There are two ways to delete rows in a table using information
+ contained in other tables in the database: using sub-selects, or
+ specifying additional tables in the <literal>USING</literal> clause.
+ Which technique is more appropriate depends on the specific
+ circumstances.
+ </para>
+
+ <para>
+ The optional <literal>RETURNING</literal> clause causes <command>DELETE</command>
+ to compute and return value(s) based on each row actually deleted.
+ Any expression using the table's columns, and/or columns of other
+ tables mentioned in <literal>USING</literal>, can be computed.
+ The syntax of the <literal>RETURNING</literal> list is identical to that of the
+ output list of <command>SELECT</command>.
+ </para>
+
+ <para>
+ You must have the <literal>DELETE</literal> privilege on the table
+ to delete from it, as well as the <literal>SELECT</literal>
+ privilege for any table in the <literal>USING</literal> clause or
+ whose values are read in the <replaceable
+ class="parameter">condition</replaceable>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">with_query</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>WITH</literal> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <command>DELETE</command>
+ query. See <xref linkend="queries-with"/> and <xref linkend="sql-select"/>
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to delete rows
+ from. If <literal>ONLY</literal> is specified before the table name,
+ matching rows are deleted from the named table only. If
+ <literal>ONLY</literal> is not specified, matching rows are also deleted
+ from any tables inheriting from the named table. Optionally,
+ <literal>*</literal> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <literal>DELETE FROM foo AS f</literal>, the remainder
+ of the <command>DELETE</command> statement must refer to this
+ table as <literal>f</literal> not <literal>foo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">from_item</replaceable></term>
+ <listitem>
+ <para>
+ A table expression allowing columns from other tables to appear
+ in the <literal>WHERE</literal> condition. This uses the same
+ syntax as the <link linkend="sql-from"><literal>FROM</literal></link>
+ clause of a <command>SELECT</command> statement; for example, an alias
+ for the table name can be specified. Do not repeat the target
+ table as a <replaceable class="parameter">from_item</replaceable>
+ unless you wish to set up a self-join (in which case it must appear
+ with an alias in the <replaceable>from_item</replaceable>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">condition</replaceable></term>
+ <listitem>
+ <para>
+ An expression that returns a value of type <type>boolean</type>.
+ Only rows for which this expression returns <literal>true</literal>
+ will be deleted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cursor_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the cursor to use in a <literal>WHERE CURRENT OF</literal>
+ condition. The row to be deleted is the one most recently fetched
+ from this cursor. The cursor must be a non-grouping
+ query on the <command>DELETE</command>'s target table.
+ Note that <literal>WHERE CURRENT OF</literal> cannot be
+ specified together with a Boolean condition. See
+ <xref linkend="sql-declare"/>
+ for more information about using cursors with
+ <literal>WHERE CURRENT OF</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression to be computed and returned by the <command>DELETE</command>
+ command after each row is deleted. The expression can use any
+ column names of the table named by <replaceable class="parameter">table_name</replaceable>
+ or table(s) listed in <literal>USING</literal>.
+ Write <literal>*</literal> to return all columns.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_name</replaceable></term>
+ <listitem>
+ <para>
+ A name to use for a returned column.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, a <command>DELETE</command> command returns a command
+ tag of the form
+<screen>
+DELETE <replaceable class="parameter">count</replaceable>
+</screen>
+ The <replaceable class="parameter">count</replaceable> is the number
+ of rows deleted. Note that the number may be less than the number of
+ rows that matched the <replaceable
+ class="parameter">condition</replaceable> when deletes were
+ suppressed by a <literal>BEFORE DELETE</literal> trigger. If <replaceable
+ class="parameter">count</replaceable> is 0, no rows were deleted by
+ the query (this is not considered an error).
+ </para>
+
+ <para>
+ If the <command>DELETE</command> command contains a <literal>RETURNING</literal>
+ clause, the result will be similar to that of a <command>SELECT</command>
+ statement containing the columns and values defined in the
+ <literal>RETURNING</literal> list, computed over the row(s) deleted by the
+ command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <productname>PostgreSQL</productname> lets you reference columns of
+ other tables in the <literal>WHERE</literal> condition by specifying the
+ other tables in the <literal>USING</literal> clause. For example,
+ to delete all films produced by a given producer, one can do:
+<programlisting>
+DELETE FROM films USING producers
+ WHERE producer_id = producers.id AND producers.name = 'foo';
+</programlisting>
+ What is essentially happening here is a join between <structname>films</structname>
+ and <structname>producers</structname>, with all successfully joined
+ <structname>films</structname> rows being marked for deletion.
+ This syntax is not standard. A more standard way to do it is:
+<programlisting>
+DELETE FROM films
+ WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
+</programlisting>
+ In some cases the join style is easier to write or faster to
+ execute than the sub-select style.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Delete all films but musicals:
+<programlisting>
+DELETE FROM films WHERE kind &lt;&gt; 'Musical';
+</programlisting>
+ </para>
+
+ <para>
+ Clear the table <literal>films</literal>:
+<programlisting>
+DELETE FROM films;
+</programlisting>
+ </para>
+
+ <para>
+ Delete completed tasks, returning full details of the deleted rows:
+<programlisting>
+DELETE FROM tasks WHERE status = 'DONE' RETURNING *;
+</programlisting>
+ </para>
+
+ <para>
+ Delete the row of <structname>tasks</structname> on which the cursor
+ <literal>c_tasks</literal> is currently positioned:
+<programlisting>
+DELETE FROM tasks WHERE CURRENT OF c_tasks;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the <acronym>SQL</acronym> standard, except
+ that the <literal>USING</literal> and <literal>RETURNING</literal> clauses
+ are <productname>PostgreSQL</productname> extensions, as is the ability
+ to use <literal>WITH</literal> with <command>DELETE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-truncate"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/discard.sgml b/doc/src/sgml/ref/discard.sgml
new file mode 100644
index 0000000..bf44c52
--- /dev/null
+++ b/doc/src/sgml/ref/discard.sgml
@@ -0,0 +1,118 @@
+<!--
+doc/src/sgml/ref/discard.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-discard">
+ <indexterm zone="sql-discard">
+ <primary>DISCARD</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DISCARD</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DISCARD</refname>
+ <refpurpose>discard session state</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DISCARD</command> releases internal resources associated with a
+ database session. This command is useful for partially or fully
+ resetting the session's state. There are several subcommands to
+ release different types of resources; the <command>DISCARD ALL</command>
+ variant subsumes all the others, and also resets additional state.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>PLANS</literal></term>
+ <listitem>
+ <para>
+ Releases all cached query plans, forcing re-planning to occur
+ the next time the associated prepared statement is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SEQUENCES</literal></term>
+ <listitem>
+ <para>
+ Discards all cached sequence-related state,
+ including <function>currval()</function>/<function>lastval()</function>
+ information and any preallocated sequence values that have not
+ yet been returned by <function>nextval()</function>.
+ (See <xref linkend="sql-createsequence"/> for a description of
+ preallocated sequence values.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ Drops all temporary tables created in the current session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Releases all temporary resources associated with the current
+ session and resets the session to its initial state.
+ Currently, this has the same effect as executing the following sequence
+ of statements:
+<programlisting>
+CLOSE ALL;
+SET SESSION AUTHORIZATION DEFAULT;
+RESET ALL;
+DEALLOCATE ALL;
+UNLISTEN *;
+SELECT pg_advisory_unlock_all();
+DISCARD PLANS;
+DISCARD TEMP;
+DISCARD SEQUENCES;
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>DISCARD ALL</command> cannot be executed inside a transaction block.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DISCARD</command> is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/do.sgml b/doc/src/sgml/ref/do.sgml
new file mode 100644
index 0000000..96901b7
--- /dev/null
+++ b/doc/src/sgml/ref/do.sgml
@@ -0,0 +1,135 @@
+<!--
+doc/src/sgml/ref/do.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-do">
+ <indexterm zone="sql-do">
+ <primary>DO</primary>
+ </indexterm>
+
+ <indexterm zone="sql-do">
+ <primary>anonymous code blocks</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DO</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DO</refname>
+ <refpurpose>execute an anonymous code block</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DO [ LANGUAGE <replaceable class="parameter">lang_name</replaceable> ] <replaceable class="parameter">code</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DO</command> executes an anonymous code block, or in other
+ words a transient anonymous function in a procedural language.
+ </para>
+
+ <para>
+ The code block is treated as though it were the body of a function
+ with no parameters, returning <type>void</type>. It is parsed and
+ executed a single time.
+ </para>
+
+ <para>
+ The optional <literal>LANGUAGE</literal> clause can be written either
+ before or after the code block.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">code</replaceable></term>
+ <listitem>
+ <para>
+ The procedural language code to be executed. This must be specified
+ as a string literal, just as in <command>CREATE FUNCTION</command>.
+ Use of a dollar-quoted literal is recommended.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">lang_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the procedural language the code is written in.
+ If omitted, the default is <literal>plpgsql</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The procedural language to be used must already have been installed
+ into the current database by means of <command>CREATE EXTENSION</command>.
+ <literal>plpgsql</literal> is installed by default, but other languages are not.
+ </para>
+
+ <para>
+ The user must have <literal>USAGE</literal> privilege for the procedural
+ language, or must be a superuser if the language is untrusted.
+ This is the same privilege requirement as for creating a function
+ in the language.
+ </para>
+
+ <para>
+ If <command>DO</command> is executed in a transaction block, then the
+ procedure code cannot execute transaction control statements. Transaction
+ control statements are only allowed if <command>DO</command> is executed in
+ its own transaction.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-do-examples">
+ <title>Examples</title>
+ <para>
+ Grant all privileges on all views in schema <literal>public</literal> to
+ role <literal>webuser</literal>:
+<programlisting>
+DO $$DECLARE r record;
+BEGIN
+ FOR r IN SELECT table_schema, table_name FROM information_schema.tables
+ WHERE table_type = 'VIEW' AND table_schema = 'public'
+ LOOP
+ EXECUTE 'GRANT ALL ON ' || quote_ident(r.table_schema) || '.' || quote_ident(r.table_name) || ' TO webuser';
+ END LOOP;
+END$$;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DO</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createlanguage"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/drop_access_method.sgml b/doc/src/sgml/ref/drop_access_method.sgml
new file mode 100644
index 0000000..a908a64
--- /dev/null
+++ b/doc/src/sgml/ref/drop_access_method.sgml
@@ -0,0 +1,111 @@
+<!--
+doc/src/sgml/ref/drop_access_method.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-drop-access-method">
+ <indexterm zone="sql-drop-access-method">
+ <primary>DROP ACCESS METHOD</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP ACCESS METHOD</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP ACCESS METHOD</refname>
+ <refpurpose>remove an access method</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP ACCESS METHOD [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP ACCESS METHOD</command> removes an existing access method.
+ Only superusers can drop access methods.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the access method does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing access method.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the access method
+ (such as operator classes, operator families, and indexes),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the access method if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Drop the access method <literal>heptree</literal>:
+<programlisting>
+DROP ACCESS METHOD heptree;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP ACCESS METHOD</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-create-access-method"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_aggregate.sgml b/doc/src/sgml/ref/drop_aggregate.sgml
new file mode 100644
index 0000000..ba74f4f
--- /dev/null
+++ b/doc/src/sgml/ref/drop_aggregate.sgml
@@ -0,0 +1,184 @@
+<!--
+doc/src/sgml/ref/drop_aggregate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropaggregate">
+ <indexterm zone="sql-dropaggregate">
+ <primary>DROP AGGREGATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP AGGREGATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP AGGREGATE</refname>
+ <refpurpose>remove an aggregate function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP AGGREGATE [ IF EXISTS ] <replaceable>name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) [, ...] [ CASCADE | RESTRICT ]
+
+<phrase>where <replaceable>aggregate_signature</replaceable> is:</phrase>
+
+* |
+[ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] |
+[ [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] ] ORDER BY [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP AGGREGATE</command> removes an existing
+ aggregate function. To execute this command the current
+ user must be the owner of the aggregate function.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the aggregate does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing aggregate function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal> or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ Note that <command>DROP AGGREGATE</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the aggregate function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+ <listitem>
+ <para>
+ An input data type on which the aggregate function operates.
+ To reference a zero-argument aggregate function, write <literal>*</literal>
+ in place of the list of argument specifications.
+ To reference an ordered-set aggregate function, write
+ <literal>ORDER BY</literal> between the direct and aggregated argument
+ specifications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the aggregate function
+ (such as views using it),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the aggregate function if any objects depend on
+ it. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Alternative syntaxes for referencing ordered-set aggregates
+ are described under <xref linkend="sql-alteraggregate"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To remove the aggregate function <literal>myavg</literal> for type
+ <type>integer</type>:
+<programlisting>
+DROP AGGREGATE myavg(integer);
+</programlisting>
+ </para>
+
+ <para>
+ To remove the hypothetical-set aggregate function <literal>myrank</literal>,
+ which takes an arbitrary list of ordering columns and a matching list
+ of direct arguments:
+<programlisting>
+DROP AGGREGATE myrank(VARIADIC "any" ORDER BY VARIADIC "any");
+</programlisting>
+ </para>
+
+ <para>
+ To remove multiple aggregate functions in one command:
+<programlisting>
+DROP AGGREGATE myavg(integer), myavg(bigint);
+</programlisting></para>
+</refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP AGGREGATE</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteraggregate"/></member>
+ <member><xref linkend="sql-createaggregate"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_cast.sgml b/doc/src/sgml/ref/drop_cast.sgml
new file mode 100644
index 0000000..5cb704b
--- /dev/null
+++ b/doc/src/sgml/ref/drop_cast.sgml
@@ -0,0 +1,117 @@
+<!--
+doc/src/sgml/ref/drop_cast.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropcast">
+ <indexterm zone="sql-dropcast">
+ <primary>DROP CAST</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP CAST</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP CAST</refname>
+ <refpurpose>remove a cast</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP CAST [ IF EXISTS ] (<replaceable>source_type</replaceable> AS <replaceable>target_type</replaceable>) [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-dropcast-description">
+ <title>Description</title>
+
+ <para>
+ <command>DROP CAST</command> removes a previously defined cast.
+ </para>
+
+ <para>
+ To be able to drop a cast, you must own the source or the target
+ data type. These are the same privileges that are required to
+ create a cast.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the cast does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>source_type</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the source data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>target_type</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the target data type of the cast.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ These key words do not have any effect, since there are no
+ dependencies on casts.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropcast-examples">
+ <title>Examples</title>
+
+ <para>
+ To drop the cast from type <type>text</type> to type <type>int</type>:
+<programlisting>
+DROP CAST (text AS int);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-dropcast-compat">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>DROP CAST</command> command conforms to the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createcast"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_collation.sgml b/doc/src/sgml/ref/drop_collation.sgml
new file mode 100644
index 0000000..60867b0
--- /dev/null
+++ b/doc/src/sgml/ref/drop_collation.sgml
@@ -0,0 +1,114 @@
+<!--
+doc/src/sgml/ref/drop_collation.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropcollation">
+ <indexterm zone="sql-dropcollation">
+ <primary>DROP COLLATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP COLLATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP COLLATION</refname>
+ <refpurpose>remove a collation</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP COLLATION [ IF EXISTS ] <replaceable>name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-dropcollation-description">
+ <title>Description</title>
+
+ <para>
+ <command>DROP COLLATION</command> removes a previously defined collation.
+ To be able to drop a collation, you must own the collation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the collation does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the collation. The collation name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the collation,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the collation if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropcollation-examples">
+ <title>Examples</title>
+
+ <para>
+ To drop the collation named <literal>german</literal>:
+<programlisting>
+DROP COLLATION german;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-dropcollation-compat">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>DROP COLLATION</command> command conforms to the
+ <acronym>SQL</acronym> standard, apart from the <literal>IF
+ EXISTS</literal> option, which is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altercollation"/></member>
+ <member><xref linkend="sql-createcollation"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_conversion.sgml b/doc/src/sgml/ref/drop_conversion.sgml
new file mode 100644
index 0000000..08558ad
--- /dev/null
+++ b/doc/src/sgml/ref/drop_conversion.sgml
@@ -0,0 +1,107 @@
+<!--
+doc/src/sgml/ref/drop_conversion.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropconversion">
+ <indexterm zone="sql-dropconversion">
+ <primary>DROP CONVERSION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP CONVERSION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP CONVERSION</refname>
+ <refpurpose>remove a conversion</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP CONVERSION [ IF EXISTS ] <replaceable>name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-dropconversion-description">
+ <title>Description</title>
+
+ <para>
+ <command>DROP CONVERSION</command> removes a previously defined conversion.
+ To be able to drop a conversion, you must own the conversion.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the conversion does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the conversion. The conversion name can be
+ schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ These key words do not have any effect, since there are no
+ dependencies on conversions.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropconversion-examples">
+ <title>Examples</title>
+
+ <para>
+ To drop the conversion named <literal>myname</literal>:
+<programlisting>
+DROP CONVERSION myname;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-dropconversion-compat">
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP CONVERSION</command> statement in the SQL
+ standard, but a <command>DROP TRANSLATION</command> statement that
+ goes along with the <command>CREATE TRANSLATION</command> statement
+ that is similar to the <command>CREATE CONVERSION</command>
+ statement in PostgreSQL.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterconversion"/></member>
+ <member><xref linkend="sql-createconversion"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_database.sgml b/doc/src/sgml/ref/drop_database.sgml
new file mode 100644
index 0000000..ff01450
--- /dev/null
+++ b/doc/src/sgml/ref/drop_database.sgml
@@ -0,0 +1,126 @@
+<!--
+doc/src/sgml/ref/drop_database.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropdatabase">
+ <indexterm zone="sql-dropdatabase">
+ <primary>DROP DATABASE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP DATABASE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP DATABASE</refname>
+ <refpurpose>remove a database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP DATABASE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ [ WITH ] ( <replaceable class="parameter">option</replaceable> [, ...] ) ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be:</phrase>
+
+ FORCE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP DATABASE</command> drops a database. It removes the
+ catalog entries for the database and deletes the directory
+ containing the data. It can only be executed by the database owner.
+ It cannot be executed while you are connected to the target database.
+ (Connect to <literal>postgres</literal> or any other database to issue this
+ command.)
+ Also, if anyone else is connected to the target database, this command will
+ fail unless you use the <literal>FORCE</literal> option described below.
+ </para>
+
+ <para>
+ <command>DROP DATABASE</command> cannot be undone. Use it with care!
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the database does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the database to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORCE</literal></term>
+ <listitem>
+ <para>
+ Attempt to terminate all existing connections to the target database.
+ It doesn't terminate if prepared transactions, active logical replication
+ slots or subscriptions are present in the target database.
+ </para>
+ <para>
+ This will fail if the current user has no permissions to terminate other
+ connections. Required permissions are the same as with
+ <literal>pg_terminate_backend</literal>, described in
+ <xref linkend="functions-admin-signal"/>. This will also fail if we
+ are not able to terminate connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>DROP DATABASE</command> cannot be executed inside a transaction
+ block.
+ </para>
+
+ <para>
+ This command cannot be executed while connected to the target
+ database. Thus, it might be more convenient to use the program
+ <xref linkend="app-dropdb"/> instead,
+ which is a wrapper around this command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP DATABASE</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createdatabase"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/drop_domain.sgml b/doc/src/sgml/ref/drop_domain.sgml
new file mode 100644
index 0000000..b18faf3
--- /dev/null
+++ b/doc/src/sgml/ref/drop_domain.sgml
@@ -0,0 +1,114 @@
+<!--
+doc/src/sgml/ref/drop_domain.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropdomain">
+ <indexterm zone="sql-dropdomain">
+ <primary>DROP DOMAIN</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP DOMAIN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP DOMAIN</refname>
+ <refpurpose>remove a domain</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP DOMAIN [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP DOMAIN</command> removes a domain. Only the owner of
+ a domain can remove it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the domain does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing domain.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the domain (such as
+ table columns),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the domain if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropdomain-examples">
+ <title>Examples</title>
+
+ <para>
+ To remove the domain <type>box</type>:
+
+<programlisting>
+DROP DOMAIN box;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-dropdomain-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the SQL standard, except for the
+ <literal>IF EXISTS</literal> option, which is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-dropdomain-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createdomain"/></member>
+ <member><xref linkend="sql-alterdomain"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_event_trigger.sgml b/doc/src/sgml/ref/drop_event_trigger.sgml
new file mode 100644
index 0000000..137884c
--- /dev/null
+++ b/doc/src/sgml/ref/drop_event_trigger.sgml
@@ -0,0 +1,115 @@
+<!--
+doc/src/sgml/ref/drop_event_trigger.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropeventtrigger">
+ <indexterm zone="sql-dropeventtrigger">
+ <primary>DROP EVENT TRIGGER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP EVENT TRIGGER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP EVENT TRIGGER</refname>
+ <refpurpose>remove an event trigger</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP EVENT TRIGGER [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP EVENT TRIGGER</command> removes an existing event trigger.
+ To execute this command, the current user must be the owner of the event
+ trigger.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the event trigger does not exist. A notice
+ is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the event trigger to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the trigger,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the trigger if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropeventtrigger-examples">
+ <title>Examples</title>
+
+ <para>
+ Destroy the trigger <literal>snitch</literal>:
+
+<programlisting>
+DROP EVENT TRIGGER snitch;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-dropeventtrigger-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP EVENT TRIGGER</command> statement in the
+ SQL standard.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createeventtrigger"/></member>
+ <member><xref linkend="sql-altereventtrigger"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_extension.sgml b/doc/src/sgml/ref/drop_extension.sgml
new file mode 100644
index 0000000..484e5d9
--- /dev/null
+++ b/doc/src/sgml/ref/drop_extension.sgml
@@ -0,0 +1,126 @@
+<!--
+doc/src/sgml/ref/drop_extension.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropextension">
+ <indexterm zone="sql-dropextension">
+ <primary>DROP EXTENSION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP EXTENSION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP EXTENSION</refname>
+ <refpurpose>remove an extension</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP EXTENSION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP EXTENSION</command> removes extensions from the database.
+ Dropping an extension causes its member objects, and other explicitly
+ dependent routines (see <xref linkend="sql-alterroutine"/>,
+ the <literal>DEPENDS ON EXTENSION <replaceable>extension_name</replaceable>
+ </literal> action), to be dropped as well.
+ </para>
+
+ <para>
+ You must own the extension to use <command>DROP EXTENSION</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the extension does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an installed extension.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the extension,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ This option prevents the specified extensions from being dropped if
+ other objects, besides these extensions, their members, and their
+ explicitly dependent routines, depend on them.  This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To remove the extension <literal>hstore</literal> from the current
+ database:
+<programlisting>
+DROP EXTENSION hstore;
+</programlisting>
+ This command will fail if any of <literal>hstore</literal>'s objects
+ are in use in the database, for example if any tables have columns
+ of the <type>hstore</type> type. Add the <literal>CASCADE</literal> option to
+ forcibly remove those dependent objects as well.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP EXTENSION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createextension"/></member>
+ <member><xref linkend="sql-alterextension"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_foreign_data_wrapper.sgml b/doc/src/sgml/ref/drop_foreign_data_wrapper.sgml
new file mode 100644
index 0000000..e53178b
--- /dev/null
+++ b/doc/src/sgml/ref/drop_foreign_data_wrapper.sgml
@@ -0,0 +1,114 @@
+<!--
+doc/src/sgml/ref/drop_foreign_data_wrapper.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropforeigndatawrapper">
+ <indexterm zone="sql-dropforeigndatawrapper">
+ <primary>DROP FOREIGN DATA WRAPPER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP FOREIGN DATA WRAPPER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP FOREIGN DATA WRAPPER</refname>
+ <refpurpose>remove a foreign-data wrapper</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP FOREIGN DATA WRAPPER [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP FOREIGN DATA WRAPPER</command> removes an existing
+ foreign-data wrapper. To execute this command, the current user
+ must be the owner of the foreign-data wrapper.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the foreign-data wrapper does not
+ exist. A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing foreign-data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the foreign-data
+ wrapper (such as foreign tables and servers),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the foreign-data wrapper if any objects depend
+ on it. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Drop the foreign-data wrapper <literal>dbi</literal>:
+<programlisting>
+DROP FOREIGN DATA WRAPPER dbi;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP FOREIGN DATA WRAPPER</command> conforms to ISO/IEC
+ 9075-9 (SQL/MED). The <literal>IF EXISTS</literal> clause is
+ a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createforeigndatawrapper"/></member>
+ <member><xref linkend="sql-alterforeigndatawrapper"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_foreign_table.sgml b/doc/src/sgml/ref/drop_foreign_table.sgml
new file mode 100644
index 0000000..07b3fd4
--- /dev/null
+++ b/doc/src/sgml/ref/drop_foreign_table.sgml
@@ -0,0 +1,115 @@
+<!--
+doc/src/sgml/ref/drop_foreign_table.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropforeigntable">
+ <indexterm zone="sql-dropforeigntable">
+ <primary>DROP FOREIGN TABLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP FOREIGN TABLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP FOREIGN TABLE</refname>
+ <refpurpose>remove a foreign table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP FOREIGN TABLE</command> removes a foreign table.
+ Only the owner of a foreign table can remove it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the foreign table does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the foreign table to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the foreign table (such as
+ views), and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the foreign table if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To destroy two foreign tables, <literal>films</literal> and
+ <literal>distributors</literal>:
+
+<programlisting>
+DROP FOREIGN TABLE films, distributors;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to ISO/IEC 9075-9 (SQL/MED), except that the
+ standard only allows one foreign table to be dropped per command, and apart
+ from the <literal>IF EXISTS</literal> option, which is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterforeigntable"/></member>
+ <member><xref linkend="sql-createforeigntable"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_function.sgml b/doc/src/sgml/ref/drop_function.sgml
new file mode 100644
index 0000000..d84bebc
--- /dev/null
+++ b/doc/src/sgml/ref/drop_function.sgml
@@ -0,0 +1,192 @@
+<!--
+doc/src/sgml/ref/drop_function.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropfunction">
+ <indexterm zone="sql-dropfunction">
+ <primary>DROP FUNCTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP FUNCTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP FUNCTION</refname>
+ <refpurpose>remove a function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP FUNCTION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] [, ...]
+ [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP FUNCTION</command> removes the definition of an existing
+ function. To execute this command the user must be the
+ owner of the function. The argument types to the
+ function must be specified, since several different functions
+ can exist with the same name and different argument lists.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the function does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing function. If no
+ argument list is specified, the name must be unique in its schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ Note that <command>DROP FUNCTION</command> does not actually pay
+ any attention to <literal>OUT</literal> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <literal>IN</literal>, <literal>INOUT</literal>,
+ and <literal>VARIADIC</literal> arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ Note that <command>DROP FUNCTION</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type(s) of the function's arguments (optionally
+ schema-qualified), if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the function (such as
+ operators or triggers),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the function if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropfunction-examples">
+ <title>Examples</title>
+
+ <para>
+ This command removes the square root function:
+
+<programlisting>
+DROP FUNCTION sqrt(integer);
+</programlisting></para>
+
+ <para>
+ Drop multiple functions in one command:
+<programlisting>
+DROP FUNCTION sqrt(integer), sqrt(bigint);
+</programlisting></para>
+
+ <para>
+ If the function name is unique in its schema, it can be referred to without
+ an argument list:
+<programlisting>
+DROP FUNCTION update_employee_salaries;
+</programlisting>
+ Note that this is different from
+<programlisting>
+DROP FUNCTION update_employee_salaries();
+</programlisting>
+ which refers to a function with zero arguments, whereas the first variant
+ can refer to a function with any number of arguments, including zero, as
+ long as the name is unique.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-dropfunction-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the SQL standard, with
+ these <productname>PostgreSQL</productname> extensions:
+ <itemizedlist>
+ <listitem>
+ <para>The standard only allows one function to be dropped per command.</para>
+ </listitem>
+ <listitem>
+ <para>The <literal>IF EXISTS</literal> option</para>
+ </listitem>
+ <listitem>
+ <para>The ability to specify argument modes and names</para>
+ </listitem>
+ </itemizedlist></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createfunction"/></member>
+ <member><xref linkend="sql-alterfunction"/></member>
+ <member><xref linkend="sql-dropprocedure"/></member>
+ <member><xref linkend="sql-droproutine"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_group.sgml b/doc/src/sgml/ref/drop_group.sgml
new file mode 100644
index 0000000..eb7dc18
--- /dev/null
+++ b/doc/src/sgml/ref/drop_group.sgml
@@ -0,0 +1,53 @@
+<!--
+doc/src/sgml/ref/drop_group.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropgroup">
+ <indexterm zone="sql-dropgroup">
+ <primary>DROP GROUP</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP GROUP</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP GROUP</refname>
+ <refpurpose>remove a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP GROUP [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP GROUP</command> is now an alias for
+ <link linkend="sql-droprole"><command>DROP ROLE</command></link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP GROUP</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-droprole"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_index.sgml b/doc/src/sgml/ref/drop_index.sgml
new file mode 100644
index 0000000..aabc85e
--- /dev/null
+++ b/doc/src/sgml/ref/drop_index.sgml
@@ -0,0 +1,143 @@
+<!--
+doc/src/sgml/ref/drop_index.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropindex">
+ <indexterm zone="sql-dropindex">
+ <primary>DROP INDEX</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP INDEX</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP INDEX</refname>
+ <refpurpose>remove an index</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP INDEX [ CONCURRENTLY ] [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP INDEX</command> drops an existing index from the database
+ system. To execute this command you must be the owner of
+ the index.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>CONCURRENTLY</literal></term>
+ <listitem>
+ <para>
+ Drop the index without locking out concurrent selects, inserts, updates,
+ and deletes on the index's table. A normal <command>DROP INDEX</command>
+ acquires an <literal>ACCESS EXCLUSIVE</literal> lock on the table,
+ blocking other accesses until the index drop can be completed. With
+ this option, the command instead waits until conflicting transactions
+ have completed.
+ </para>
+ <para>
+ There are several caveats to be aware of when using this option.
+ Only one index name can be specified, and the <literal>CASCADE</literal> option
+ is not supported. (Thus, an index that supports a <literal>UNIQUE</literal> or
+ <literal>PRIMARY KEY</literal> constraint cannot be dropped this way.)
+ Also, regular <command>DROP INDEX</command> commands can be
+ performed within a transaction block, but
+ <command>DROP INDEX CONCURRENTLY</command> cannot.
+ Lastly, indexes on partitioned tables cannot be dropped using this
+ option.
+ </para>
+ <para>
+ For temporary tables, <command>DROP INDEX</command> is always
+ non-concurrent, as no other session can access them, and
+ non-concurrent index drop is cheaper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the index does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an index to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the index,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the index if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This command will remove the index <literal>title_idx</literal>:
+
+<programlisting>
+DROP INDEX title_idx;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP INDEX</command> is a
+ <productname>PostgreSQL</productname> language extension. There
+ are no provisions for indexes in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createindex"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_language.sgml b/doc/src/sgml/ref/drop_language.sgml
new file mode 100644
index 0000000..8ba6621
--- /dev/null
+++ b/doc/src/sgml/ref/drop_language.sgml
@@ -0,0 +1,125 @@
+<!--
+doc/src/sgml/ref/drop_language.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droplanguage">
+ <indexterm zone="sql-droplanguage">
+ <primary>DROP LANGUAGE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP LANGUAGE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP LANGUAGE</refname>
+ <refpurpose>remove a procedural language</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP LANGUAGE</command> removes the definition of a
+ previously registered procedural language. You must be a superuser
+ or the owner of the language to use <command>DROP LANGUAGE</command>.
+ </para>
+
+ <note>
+ <para>
+ As of <productname>PostgreSQL</productname> 9.1, most procedural
+ languages have been made into <quote>extensions</quote>, and should
+ therefore be removed with <link linkend="sql-dropextension"><command>DROP EXTENSION</command></link>
+ not <command>DROP LANGUAGE</command>.
+ </para>
+ </note>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the language does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing procedural language.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the language (such as
+ functions in the language),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the language if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This command removes the procedural language
+ <literal>plsample</literal>:
+
+<programlisting>
+DROP LANGUAGE plsample;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP LANGUAGE</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterlanguage"/></member>
+ <member><xref linkend="sql-createlanguage"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_materialized_view.sgml b/doc/src/sgml/ref/drop_materialized_view.sgml
new file mode 100644
index 0000000..c8f3bc5
--- /dev/null
+++ b/doc/src/sgml/ref/drop_materialized_view.sgml
@@ -0,0 +1,116 @@
+<!--
+doc/src/sgml/ref/drop_materialized_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropmaterializedview">
+ <indexterm zone="sql-dropmaterializedview">
+ <primary>DROP MATERIALIZED VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP MATERIALIZED VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP MATERIALIZED VIEW</refname>
+ <refpurpose>remove a materialized view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP MATERIALIZED VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP MATERIALIZED VIEW</command> drops an existing materialized
+ view. To execute this command you must be the owner of the materialized
+ view.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the materialized view does not exist. A notice
+ is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the materialized view to
+ remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the materialized view (such as
+ other materialized views, or regular views),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the materialized view if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This command will remove the materialized view called
+ <literal>order_summary</literal>:
+<programlisting>
+DROP MATERIALIZED VIEW order_summary;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP MATERIALIZED VIEW</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-creatematerializedview"/></member>
+ <member><xref linkend="sql-altermaterializedview"/></member>
+ <member><xref linkend="sql-refreshmaterializedview"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_opclass.sgml b/doc/src/sgml/ref/drop_opclass.sgml
new file mode 100644
index 0000000..4cb4cc3
--- /dev/null
+++ b/doc/src/sgml/ref/drop_opclass.sgml
@@ -0,0 +1,149 @@
+<!--
+doc/src/sgml/ref/drop_opclass.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropopclass">
+ <indexterm zone="sql-dropopclass">
+ <primary>DROP OPERATOR CLASS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP OPERATOR CLASS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP OPERATOR CLASS</refname>
+ <refpurpose>remove an operator class</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP OPERATOR CLASS [ IF EXISTS ] <replaceable class="parameter">name</replaceable> USING <replaceable class="parameter">index_method</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP OPERATOR CLASS</command> drops an existing operator class.
+ To execute this command you must be the owner of the operator class.
+ </para>
+
+ <para>
+ <command>DROP OPERATOR CLASS</command> does not drop any of the operators
+ or functions referenced by the class. If there are any indexes depending
+ on the operator class, you will need to specify
+ <literal>CASCADE</literal> for the drop to complete.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the operator class does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing operator class.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index access method the operator class is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the operator class (such as
+ indexes), and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the operator class if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>DROP OPERATOR CLASS</command> will not drop the operator family
+ containing the class, even if there is nothing else left in the
+ family (in particular, in the case where the family was implicitly
+ created by <command>CREATE OPERATOR CLASS</command>). An empty operator
+ family is harmless, but for the sake of tidiness you might wish to
+ remove the family with <command>DROP OPERATOR FAMILY</command>; or perhaps
+ better, use <command>DROP OPERATOR FAMILY</command> in the first place.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the B-tree operator class <literal>widget_ops</literal>:
+
+<programlisting>
+DROP OPERATOR CLASS widget_ops USING btree;
+</programlisting>
+
+ This command will not succeed if there are any existing indexes
+ that use the operator class. Add <literal>CASCADE</literal> to drop
+ such indexes along with the operator class.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP OPERATOR CLASS</command> statement in the
+ SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteropclass"/></member>
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-dropopfamily"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_operator.sgml b/doc/src/sgml/ref/drop_operator.sgml
new file mode 100644
index 0000000..7bcdd08
--- /dev/null
+++ b/doc/src/sgml/ref/drop_operator.sgml
@@ -0,0 +1,146 @@
+<!--
+doc/src/sgml/ref/drop_operator.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropoperator">
+ <indexterm zone="sql-dropoperator">
+ <primary>DROP OPERATOR</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP OPERATOR</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP OPERATOR</refname>
+ <refpurpose>remove an operator</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP OPERATOR [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ( { <replaceable class="parameter">left_type</replaceable> | NONE } , <replaceable class="parameter">right_type</replaceable> ) [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP OPERATOR</command> drops an existing operator from
+ the database system. To execute this command you must be the owner
+ of the operator.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the operator does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing operator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">left_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the operator's left operand; write
+ <literal>NONE</literal> if the operator has no left operand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">right_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of the operator's right operand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the operator (such as views
+ using it), and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the operator if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the power operator <literal>a^b</literal> for type <type>integer</type>:
+<programlisting>
+DROP OPERATOR ^ (integer, integer);
+</programlisting>
+ </para>
+
+ <para>
+ Remove the bitwise-complement prefix operator
+ <literal>~b</literal> for type <type>bit</type>:
+<programlisting>
+DROP OPERATOR ~ (none, bit);
+</programlisting>
+ </para>
+
+ <para>
+ Remove multiple operators in one command:
+<programlisting>
+DROP OPERATOR ~ (none, bit), ^ (integer, integer);
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP OPERATOR</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createoperator"/></member>
+ <member><xref linkend="sql-alteroperator"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_opfamily.sgml b/doc/src/sgml/ref/drop_opfamily.sgml
new file mode 100644
index 0000000..c1bcd0d
--- /dev/null
+++ b/doc/src/sgml/ref/drop_opfamily.sgml
@@ -0,0 +1,138 @@
+<!--
+doc/src/sgml/ref/drop_opfamily.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropopfamily">
+ <indexterm zone="sql-dropopfamily">
+ <primary>DROP OPERATOR FAMILY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP OPERATOR FAMILY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP OPERATOR FAMILY</refname>
+ <refpurpose>remove an operator family</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP OPERATOR FAMILY [ IF EXISTS ] <replaceable class="parameter">name</replaceable> USING <replaceable class="parameter">index_method</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP OPERATOR FAMILY</command> drops an existing operator family.
+ To execute this command you must be the owner of the operator family.
+ </para>
+
+ <para>
+ <command>DROP OPERATOR FAMILY</command> includes dropping any operator
+ classes contained in the family, but it does not drop any of the operators
+ or functions referenced by the family. If there are any indexes depending
+ on operator classes within the family, you will need to specify
+ <literal>CASCADE</literal> for the drop to complete.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the operator family does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing operator family.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_method</replaceable></term>
+ <listitem>
+ <para>
+ The name of the index access method the operator family is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the operator family,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the operator family if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the B-tree operator family <literal>float_ops</literal>:
+
+<programlisting>
+DROP OPERATOR FAMILY float_ops USING btree;
+</programlisting>
+
+ This command will not succeed if there are any existing indexes
+ that use operator classes within the family. Add <literal>CASCADE</literal> to
+ drop such indexes along with the operator family.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP OPERATOR FAMILY</command> statement in the
+ SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alteropfamily"/></member>
+ <member><xref linkend="sql-createopfamily"/></member>
+ <member><xref linkend="sql-alteropclass"/></member>
+ <member><xref linkend="sql-createopclass"/></member>
+ <member><xref linkend="sql-dropopclass"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_owned.sgml b/doc/src/sgml/ref/drop_owned.sgml
new file mode 100644
index 0000000..efda01a
--- /dev/null
+++ b/doc/src/sgml/ref/drop_owned.sgml
@@ -0,0 +1,126 @@
+<!--
+doc/src/sgml/ref/drop_owned.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-drop-owned">
+ <indexterm zone="sql-drop-owned">
+ <primary>DROP OWNED</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP OWNED</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP OWNED</refname>
+ <refpurpose>remove database objects owned by a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP OWNED BY { <replaceable class="parameter">name</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP OWNED</command> drops all the objects within the current
+ database that are owned by one of the specified roles. Any
+ privileges granted to the given roles on objects in the current
+ database or on shared objects (databases, tablespaces, configuration
+ parameters) will also be revoked.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a role whose objects will be dropped, and whose
+ privileges will be revoked.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the affected objects,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the objects owned by a role if any other database
+ objects depend on one of the affected objects. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ <command>DROP OWNED</command> is often used to prepare for the
+ removal of one or more roles. Because <command>DROP OWNED</command>
+ only affects the objects in the current database, it is usually
+ necessary to execute this command in each database that contains
+ objects owned by a role that is to be removed.
+ </para>
+
+ <para>
+ Using the <literal>CASCADE</literal> option might make the command
+ recurse to objects owned by other users.
+ </para>
+
+ <para>
+ The <link linkend="sql-reassign-owned"><command>REASSIGN OWNED</command></link> command is an alternative that
+ reassigns the ownership of all the database objects owned by one or
+ more roles. However, <command>REASSIGN OWNED</command> does not deal with
+ privileges for other objects.
+ </para>
+
+ <para>
+ Databases and tablespaces owned by the role(s) will not be removed.
+ </para>
+
+ <para>
+ See <xref linkend="role-removal"/> for more discussion.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>DROP OWNED</command> command is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-reassign-owned"/></member>
+ <member><xref linkend="sql-droprole"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_policy.sgml b/doc/src/sgml/ref/drop_policy.sgml
new file mode 100644
index 0000000..d7d3771
--- /dev/null
+++ b/doc/src/sgml/ref/drop_policy.sgml
@@ -0,0 +1,119 @@
+<!--
+doc/src/sgml/ref/drop_policy.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droppolicy">
+ <indexterm zone="sql-droppolicy">
+ <primary>DROP POLICY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP POLICY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP POLICY</refname>
+ <refpurpose>remove a row-level security policy from a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP POLICY [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP POLICY</command> removes the specified policy from the table.
+ Note that if the last policy is removed for a table and the table still has
+ row-level security enabled via <command>ALTER TABLE</command>, then the
+ default-deny policy will be used. <literal>ALTER TABLE ... DISABLE ROW
+ LEVEL SECURITY</literal> can be used to disable row-level security for a
+ table, whether policies for the table exist or not.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the policy does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the policy to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table that
+ the policy is on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ These key words do not have any effect, since there are no
+ dependencies on policies.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To drop the policy called <literal>p1</literal> on the table named
+ <literal>my_table</literal>:
+
+<programlisting>
+DROP POLICY p1 ON my_table;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP POLICY</command> is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createpolicy"/></member>
+ <member><xref linkend="sql-alterpolicy"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_procedure.sgml b/doc/src/sgml/ref/drop_procedure.sgml
new file mode 100644
index 0000000..84e6b09
--- /dev/null
+++ b/doc/src/sgml/ref/drop_procedure.sgml
@@ -0,0 +1,231 @@
+<!--
+doc/src/sgml/ref/drop_procedure.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropprocedure">
+ <indexterm zone="sql-dropprocedure">
+ <primary>DROP PROCEDURE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP PROCEDURE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP PROCEDURE</refname>
+ <refpurpose>remove a procedure</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP PROCEDURE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] [, ...]
+ [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP PROCEDURE</command> removes the definition of one or more
+ existing procedures. To execute this command the user must be the
+ owner of the procedure(s). The argument types to the
+ procedure(s) usually must be specified, since several different procedures
+ can exist with the same name and different argument lists.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the procedure does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing procedure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of an argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>. If omitted,
+ the default is <literal>IN</literal> (but see below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of an argument.
+ Note that <command>DROP PROCEDURE</command> does not actually pay
+ any attention to argument names, since only the argument data
+ types are used to determine the procedure's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type(s) of the procedure's arguments (optionally
+ schema-qualified), if any.
+ See below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the procedure,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the procedure if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-dropprocedure-notes">
+ <title>Notes</title>
+
+ <para>
+ If there is only one procedure of the given name, the argument list
+ can be omitted. Omit the parentheses too in this case.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname>, it's sufficient to list the
+ input (including <literal>INOUT</literal>) arguments,
+ because no two routines of the same name are allowed to share the same
+ input-argument list. Moreover, the <command>DROP</command> command
+ will not actually check that you wrote the types
+ of <literal>OUT</literal> arguments correctly; so any arguments that
+ are explicitly marked <literal>OUT</literal> are just noise. But
+ writing them is recommendable for consistency with the
+ corresponding <command>CREATE</command> command.
+ </para>
+
+ <para>
+ For compatibility with the SQL standard, it is also allowed to write
+ all the argument data types (including those of <literal>OUT</literal>
+ arguments) without
+ any <replaceable class="parameter">argmode</replaceable> markers.
+ When this is done, the types of the procedure's <literal>OUT</literal>
+ argument(s) <emphasis>will</emphasis> be verified against the command.
+ This provision creates an ambiguity, in that when the argument list
+ contains no <replaceable class="parameter">argmode</replaceable>
+ markers, it's unclear which rule is intended.
+ The <command>DROP</command> command will attempt the lookup both ways,
+ and will throw an error if two different procedures are found.
+ To avoid the risk of such ambiguity, it's recommendable to
+ write <literal>IN</literal> markers explicitly rather than letting them
+ be defaulted, thus forcing the
+ traditional <productname>PostgreSQL</productname> interpretation to be
+ used.
+ </para>
+
+ <para>
+ The lookup rules just explained are also used by other commands that
+ act on existing procedures, such as <command>ALTER PROCEDURE</command>
+ and <command>COMMENT ON PROCEDURE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-dropprocedure-examples">
+ <title>Examples</title>
+
+ <para>
+ If there is only one procedure <literal>do_db_maintenance</literal>,
+ this command is sufficient to drop it:
+<programlisting>
+DROP PROCEDURE do_db_maintenance;
+</programlisting>
+ </para>
+
+ <para>
+ Given this procedure definition:
+<programlisting>
+CREATE PROCEDURE do_db_maintenance(IN target_schema text, OUT results text) ...
+</programlisting>
+ any one of these commands would work to drop it:
+<programlisting>
+DROP PROCEDURE do_db_maintenance(IN target_schema text, OUT results text);
+DROP PROCEDURE do_db_maintenance(IN text, OUT text);
+DROP PROCEDURE do_db_maintenance(IN text);
+DROP PROCEDURE do_db_maintenance(text);
+DROP PROCEDURE do_db_maintenance(text, text); -- potentially ambiguous
+</programlisting>
+ However, the last example would be ambiguous if there is also, say,
+<programlisting>
+CREATE PROCEDURE do_db_maintenance(IN target_schema text, IN options text) ...
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-dropprocedure-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the SQL standard, with
+ these <productname>PostgreSQL</productname> extensions:
+ <itemizedlist>
+ <listitem>
+ <para>The standard only allows one procedure to be dropped per command.</para>
+ </listitem>
+ <listitem>
+ <para>The <literal>IF EXISTS</literal> option is an extension.</para>
+ </listitem>
+ <listitem>
+ <para>The ability to specify argument modes and names is an
+ extension, and the lookup rules differ when modes are given.</para>
+ </listitem>
+ </itemizedlist></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createprocedure"/></member>
+ <member><xref linkend="sql-alterprocedure"/></member>
+ <member><xref linkend="sql-dropfunction"/></member>
+ <member><xref linkend="sql-droproutine"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_publication.sgml b/doc/src/sgml/ref/drop_publication.sgml
new file mode 100644
index 0000000..5dcbb83
--- /dev/null
+++ b/doc/src/sgml/ref/drop_publication.sgml
@@ -0,0 +1,105 @@
+<!--
+doc/src/sgml/ref/drop_publication.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droppublication">
+ <indexterm zone="sql-droppublication">
+ <primary>DROP PUBLICATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP PUBLICATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP PUBLICATION</refname>
+ <refpurpose>remove a publication</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP PUBLICATION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP PUBLICATION</command> removes an existing publication from
+ the database.
+ </para>
+
+ <para>
+ A publication can only be dropped by its owner or a superuser.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the publication does not exist. A notice is
+ issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing publication.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ These key words do not have any effect, since there are no dependencies
+ on publications.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Drop a publication:
+<programlisting>
+DROP PUBLICATION mypublication;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP PUBLICATION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createpublication"/></member>
+ <member><xref linkend="sql-alterpublication"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/drop_role.sgml b/doc/src/sgml/ref/drop_role.sgml
new file mode 100644
index 0000000..13dc1cc
--- /dev/null
+++ b/doc/src/sgml/ref/drop_role.sgml
@@ -0,0 +1,124 @@
+<!--
+doc/src/sgml/ref/drop_role.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droprole">
+ <indexterm zone="sql-droprole">
+ <primary>DROP ROLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP ROLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP ROLE</refname>
+ <refpurpose>remove a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP ROLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP ROLE</command> removes the specified role(s).
+ To drop a superuser role, you must be a superuser yourself;
+ to drop non-superuser roles, you must have <literal>CREATEROLE</literal>
+ privilege.
+ </para>
+
+ <para>
+ A role cannot be removed if it is still referenced in any database
+ of the cluster; an error will be raised if so. Before dropping the role,
+ you must drop all the objects it owns (or reassign their ownership)
+ and revoke any privileges the role has been granted on other objects.
+ The <link linkend="sql-reassign-owned"><command>REASSIGN
+ OWNED</command></link> and <link linkend="sql-drop-owned"><command>DROP
+ OWNED</command></link>
+ commands can be useful for this purpose; see <xref linkend="role-removal"/>
+ for more discussion.
+ </para>
+
+ <para>
+ However, it is not necessary to remove role memberships involving
+ the role; <command>DROP ROLE</command> automatically revokes any memberships
+ of the target role in other roles, and of other roles in the target role.
+ The other roles are not dropped nor otherwise affected.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the role does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the role to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <productname>PostgreSQL</productname> includes a program <xref
+ linkend="app-dropuser"/> that has the
+ same functionality as this command (in fact, it calls this command)
+ but can be run from the command shell.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To drop a role:
+<programlisting>
+DROP ROLE jonathan;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard defines <command>DROP ROLE</command>, but it allows
+ only one role to be dropped at a time, and it specifies different
+ privilege requirements than <productname>PostgreSQL</productname> uses.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createrole"/></member>
+ <member><xref linkend="sql-alterrole"/></member>
+ <member><xref linkend="sql-set-role"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_routine.sgml b/doc/src/sgml/ref/drop_routine.sgml
new file mode 100644
index 0000000..0a0a140
--- /dev/null
+++ b/doc/src/sgml/ref/drop_routine.sgml
@@ -0,0 +1,123 @@
+<!--
+doc/src/sgml/ref/drop_routine.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droproutine">
+ <indexterm zone="sql-droproutine">
+ <primary>DROP ROUTINE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP ROUTINE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP ROUTINE</refname>
+ <refpurpose>remove a routine</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP ROUTINE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] [, ...]
+ [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP ROUTINE</command> removes the definition of one or more
+ existing routines. The term <quote>routine</quote> includes
+ aggregate functions, normal functions, and procedures. See
+ under <xref linkend="sql-dropaggregate"/>, <xref linkend="sql-dropfunction"/>,
+ and <xref linkend="sql-dropprocedure"/> for the description of the
+ parameters, more examples, and further details.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-droproutine-notes">
+ <title>Notes</title>
+
+ <para>
+ The lookup rules used by <command>DROP ROUTINE</command> are
+ fundamentally the same as for <command>DROP PROCEDURE</command>; in
+ particular, <command>DROP ROUTINE</command> shares that command's
+ behavior of considering an argument list that has
+ no <replaceable class="parameter">argmode</replaceable> markers to be
+ possibly using the SQL standard's definition that <literal>OUT</literal>
+ arguments are included in the list. (<command>DROP AGGREGATE</command>
+ and <command>DROP FUNCTION</command> do not do that.)
+ </para>
+
+ <para>
+ In some cases where the same name is shared by routines of different
+ kinds, it is possible for <command>DROP ROUTINE</command> to fail with
+ an ambiguity error when a more specific command (<command>DROP
+ FUNCTION</command>, etc.) would work. Specifying the argument type
+ list more carefully will also resolve such problems.
+ </para>
+
+ <para>
+ These lookup rules are also used by other commands that
+ act on existing routines, such as <command>ALTER ROUTINE</command>
+ and <command>COMMENT ON ROUTINE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-droproutine-examples">
+ <title>Examples</title>
+
+ <para>
+ To drop the routine <literal>foo</literal> for type
+ <type>integer</type>:
+<programlisting>
+DROP ROUTINE foo(integer);
+</programlisting>
+ This command will work independent of whether <literal>foo</literal> is an
+ aggregate, function, or procedure.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-droproutine-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the SQL standard, with
+ these <productname>PostgreSQL</productname> extensions:
+ <itemizedlist>
+ <listitem>
+ <para>The standard only allows one routine to be dropped per command.</para>
+ </listitem>
+ <listitem>
+ <para>The <literal>IF EXISTS</literal> option is an extension.</para>
+ </listitem>
+ <listitem>
+ <para>The ability to specify argument modes and names is an
+ extension, and the lookup rules differ when modes are given.</para>
+ </listitem>
+ <listitem>
+ <para>User-definable aggregate functions are an extension.</para>
+ </listitem>
+ </itemizedlist></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-dropaggregate"/></member>
+ <member><xref linkend="sql-dropfunction"/></member>
+ <member><xref linkend="sql-dropprocedure"/></member>
+ <member><xref linkend="sql-alterroutine"/></member>
+ </simplelist>
+
+ <para>
+ Note that there is no <literal>CREATE ROUTINE</literal> command.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_rule.sgml b/doc/src/sgml/ref/drop_rule.sgml
new file mode 100644
index 0000000..cc5d00e
--- /dev/null
+++ b/doc/src/sgml/ref/drop_rule.sgml
@@ -0,0 +1,123 @@
+<!--
+doc/src/sgml/ref/drop_rule.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droprule">
+ <indexterm zone="sql-droprule">
+ <primary>DROP RULE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP RULE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP RULE</refname>
+ <refpurpose>remove a rewrite rule</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP RULE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP RULE</command> drops a rewrite rule.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the rule does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the rule to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table or view that
+ the rule applies to.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the rule,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the rule if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To drop the rewrite rule <literal>newrule</literal>:
+
+<programlisting>
+DROP RULE newrule ON mytable;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP RULE</command> is a
+ <productname>PostgreSQL</productname> language extension, as is the
+ entire query rewrite system.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createrule"/></member>
+ <member><xref linkend="sql-alterrule"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_schema.sgml b/doc/src/sgml/ref/drop_schema.sgml
new file mode 100644
index 0000000..4d5d9f5
--- /dev/null
+++ b/doc/src/sgml/ref/drop_schema.sgml
@@ -0,0 +1,131 @@
+<!--
+doc/src/sgml/ref/drop_schema.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropschema">
+ <indexterm zone="sql-dropschema">
+ <primary>DROP SCHEMA</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP SCHEMA</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP SCHEMA</refname>
+ <refpurpose>remove a schema</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP SCHEMA [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP SCHEMA</command> removes schemas from the database.
+ </para>
+
+ <para>
+ A schema can only be dropped by its owner or a superuser. Note that
+ the owner can drop the schema (and thereby all contained objects)
+ even if they do not own some of the objects within the schema.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the schema does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a schema.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects (tables, functions, etc.) that are
+ contained in the schema,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the schema if it contains any objects. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Using the <literal>CASCADE</literal> option might make the command
+ remove objects in other schemas besides the one(s) named.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To remove schema <literal>mystuff</literal> from the database,
+ along with everything it contains:
+
+<programlisting>
+DROP SCHEMA mystuff CASCADE;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP SCHEMA</command> is fully conforming with the SQL
+ standard, except that the standard only allows one schema to be
+ dropped per command, and apart from the
+ <literal>IF EXISTS</literal> option, which is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterschema"/></member>
+ <member><xref linkend="sql-createschema"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_sequence.sgml b/doc/src/sgml/ref/drop_sequence.sgml
new file mode 100644
index 0000000..387c98e
--- /dev/null
+++ b/doc/src/sgml/ref/drop_sequence.sgml
@@ -0,0 +1,115 @@
+<!--
+doc/src/sgml/ref/drop_sequence.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropsequence">
+ <indexterm zone="sql-dropsequence">
+ <primary>DROP SEQUENCE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP SEQUENCE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP SEQUENCE</refname>
+ <refpurpose>remove a sequence</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP SEQUENCE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP SEQUENCE</command> removes sequence number
+ generators. A sequence can only be dropped by its owner or a superuser.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the sequence does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a sequence.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the sequence,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the sequence if any objects depend on it. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To remove the sequence <literal>serial</literal>:
+
+<programlisting>
+DROP SEQUENCE serial;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP SEQUENCE</command> conforms to the <acronym>SQL</acronym>
+ standard, except that the standard only allows one
+ sequence to be dropped per command, and apart from the
+ <literal>IF EXISTS</literal> option, which is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createsequence"/></member>
+ <member><xref linkend="sql-altersequence"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_server.sgml b/doc/src/sgml/ref/drop_server.sgml
new file mode 100644
index 0000000..f83a661
--- /dev/null
+++ b/doc/src/sgml/ref/drop_server.sgml
@@ -0,0 +1,114 @@
+<!--
+doc/src/sgml/ref/drop_server.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropserver">
+ <indexterm zone="sql-dropserver">
+ <primary>DROP SERVER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP SERVER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP SERVER</refname>
+ <refpurpose>remove a foreign server descriptor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP SERVER [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP SERVER</command> removes an existing foreign server
+ descriptor. To execute this command, the current user must be the
+ owner of the server.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the server does not exist. A notice is
+ issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of an existing server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the server (such as
+ user mappings),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the server if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Drop a server <literal>foo</literal> if it exists:
+<programlisting>
+DROP SERVER IF EXISTS foo;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP SERVER</command> conforms to ISO/IEC 9075-9
+ (SQL/MED). The <literal>IF EXISTS</literal> clause is
+ a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createserver"/></member>
+ <member><xref linkend="sql-alterserver"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_statistics.sgml b/doc/src/sgml/ref/drop_statistics.sgml
new file mode 100644
index 0000000..1532ca9
--- /dev/null
+++ b/doc/src/sgml/ref/drop_statistics.sgml
@@ -0,0 +1,108 @@
+<!--
+doc/src/sgml/ref/drop_statistics.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropstatistics">
+ <indexterm zone="sql-dropstatistics">
+ <primary>DROP STATISTICS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP STATISTICS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP STATISTICS</refname>
+ <refpurpose>remove extended statistics</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP STATISTICS [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP STATISTICS</command> removes statistics object(s) from the
+ database. Only the statistics object's owner, the schema owner, or a
+ superuser can drop a statistics object.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the statistics object does not exist. A notice
+ is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the statistics object to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ These key words do not have any effect, since there are no dependencies
+ on statistics.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To destroy two statistics objects in different schemas, without failing
+ if they don't exist:
+
+<programlisting>
+DROP STATISTICS IF EXISTS
+ accounting.users_uid_creation,
+ public.grants_user_role;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP STATISTICS</command> command in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterstatistics"/></member>
+ <member><xref linkend="sql-createstatistics"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_subscription.sgml b/doc/src/sgml/ref/drop_subscription.sgml
new file mode 100644
index 0000000..d79f137
--- /dev/null
+++ b/doc/src/sgml/ref/drop_subscription.sgml
@@ -0,0 +1,134 @@
+<!--
+doc/src/sgml/ref/drop_subscription.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropsubscription">
+ <indexterm zone="sql-dropsubscription">
+ <primary>DROP SUBSCRIPTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP SUBSCRIPTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP SUBSCRIPTION</refname>
+ <refpurpose>remove a subscription</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP SUBSCRIPTION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP SUBSCRIPTION</command> removes a subscription from the
+ database cluster.
+ </para>
+
+ <para>
+ A subscription can only be dropped by a superuser.
+ </para>
+
+ <para>
+ <command>DROP SUBSCRIPTION</command> cannot be executed inside a
+ transaction block if the subscription is associated with a replication
+ slot. (You can use <command>ALTER SUBSCRIPTION</command> to unset the
+ slot.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a subscription to be dropped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <term><literal>RESTRICT</literal></term>
+
+ <listitem>
+ <para>
+ These key words do not have any effect, since there are no dependencies
+ on subscriptions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When dropping a subscription that is associated with a replication slot on
+ the remote host (the normal state), <command>DROP SUBSCRIPTION</command>
+ will connect to the remote host and try to drop the replication slot (and
+ any remaining table synchronization slots) as
+ part of its operation. This is necessary so that the resources allocated
+ for the subscription on the remote host are released. If this fails,
+ either because the remote host is not reachable or because the remote
+ replication slot cannot be dropped or does not exist or never existed,
+ the <command>DROP SUBSCRIPTION</command> command will fail. To proceed
+ in this situation, first disable the subscription by executing
+ <literal>ALTER SUBSCRIPTION ... DISABLE</literal>, and then disassociate
+ it from the replication slot by executing
+ <literal>ALTER SUBSCRIPTION ... SET (slot_name = NONE)</literal>.
+ After that, <command>DROP SUBSCRIPTION</command> will no longer attempt any
+ actions on a remote host. Note that if the remote replication slot still
+ exists, it (and any related table synchronization slots) should then be
+ dropped manually; otherwise it/they will continue to
+ reserve WAL and might eventually cause the disk to fill up. See
+ also <xref linkend="logical-replication-subscription-slot"/>.
+ </para>
+
+ <para>
+ If a subscription is associated with a replication slot, then <command>DROP
+ SUBSCRIPTION</command> cannot be executed inside a transaction block.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Drop a subscription:
+<programlisting>
+DROP SUBSCRIPTION mysub;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP SUBSCRIPTION</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createsubscription"/></member>
+ <member><xref linkend="sql-altersubscription"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/drop_table.sgml b/doc/src/sgml/ref/drop_table.sgml
new file mode 100644
index 0000000..450458f
--- /dev/null
+++ b/doc/src/sgml/ref/drop_table.sgml
@@ -0,0 +1,129 @@
+<!--
+doc/src/sgml/ref/drop_table.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptable">
+ <indexterm zone="sql-droptable">
+ <primary>DROP TABLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TABLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TABLE</refname>
+ <refpurpose>remove a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TABLE</command> removes tables from the database.
+ Only the table owner, the schema owner, and superuser can drop a
+ table. To empty a table of rows
+ without destroying the table, use <link linkend="sql-delete"><command>DELETE</command></link>
+ or <link linkend="sql-truncate"><command>TRUNCATE</command></link>.
+ </para>
+
+ <para>
+ <command>DROP TABLE</command> always removes any indexes, rules,
+ triggers, and constraints that exist for the target table.
+ However, to drop a table that is referenced by a view or a foreign-key
+ constraint of another table, <literal>CASCADE</literal> must be
+ specified. (<literal>CASCADE</literal> will remove a dependent view entirely,
+ but in the foreign-key case it will only remove the foreign-key
+ constraint, not the other table entirely.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the table does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to drop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the table (such as
+ views),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the table if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To destroy two tables, <literal>films</literal> and
+ <literal>distributors</literal>:
+
+<programlisting>
+DROP TABLE films, distributors;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the SQL standard, except that the standard only
+ allows one table to be dropped per command, and apart from the
+ <literal>IF EXISTS</literal> option, which is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertable"/></member>
+ <member><xref linkend="sql-createtable"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_tablespace.sgml b/doc/src/sgml/ref/drop_tablespace.sgml
new file mode 100644
index 0000000..047e4e0
--- /dev/null
+++ b/doc/src/sgml/ref/drop_tablespace.sgml
@@ -0,0 +1,110 @@
+<!--
+doc/src/sgml/ref/drop_tablespace.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptablespace">
+ <indexterm zone="sql-droptablespace">
+ <primary>DROP TABLESPACE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TABLESPACE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TABLESPACE</refname>
+ <refpurpose>remove a tablespace</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TABLESPACE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TABLESPACE</command> removes a tablespace from the system.
+ </para>
+
+ <para>
+ A tablespace can only be dropped by its owner or a superuser.
+ The tablespace must be empty of all database objects before it can be
+ dropped. It is possible that objects in other databases might still reside
+ in the tablespace even if no objects in the current database are using
+ the tablespace. Also, if the tablespace is listed in the <xref
+ linkend="guc-temp-tablespaces"/> setting of any active session, the
+ <command>DROP</command> might fail due to temporary files residing in the
+ tablespace.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the tablespace does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a tablespace.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>DROP TABLESPACE</command> cannot be executed inside a transaction block.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To remove tablespace <literal>mystuff</literal> from the system:
+<programlisting>
+DROP TABLESPACE mystuff;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP TABLESPACE</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtablespace"/></member>
+ <member><xref linkend="sql-altertablespace"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_transform.sgml b/doc/src/sgml/ref/drop_transform.sgml
new file mode 100644
index 0000000..544a966
--- /dev/null
+++ b/doc/src/sgml/ref/drop_transform.sgml
@@ -0,0 +1,128 @@
+<!--
+doc/src/sgml/ref/drop_transform.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptransform">
+ <indexterm zone="sql-droptransform">
+ <primary>DROP TRANSFORM</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TRANSFORM</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TRANSFORM</refname>
+ <refpurpose>remove a transform</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TRANSFORM [ IF EXISTS ] FOR <replaceable>type_name</replaceable> LANGUAGE <replaceable>lang_name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-droptransform-description">
+ <title>Description</title>
+
+ <para>
+ <command>DROP TRANSFORM</command> removes a previously defined transform.
+ </para>
+
+ <para>
+ To be able to drop a transform, you must own the type and the language.
+ These are the same privileges that are required to create a transform.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the transform does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>type_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the data type of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>lang_name</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of the language of the transform.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the transform,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the transform if any objects depend on it. This is the
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-droptransform-examples">
+ <title>Examples</title>
+
+ <para>
+ To drop the transform for type <type>hstore</type> and language
+ <literal>plpython3u</literal>:
+<programlisting>
+DROP TRANSFORM FOR hstore LANGUAGE plpython3u;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-droptransform-compat">
+ <title>Compatibility</title>
+
+ <para>
+ This form of <command>DROP TRANSFORM</command> is a
+ <productname>PostgreSQL</productname> extension. See <xref
+ linkend="sql-createtransform"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtransform"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_trigger.sgml b/doc/src/sgml/ref/drop_trigger.sgml
new file mode 100644
index 0000000..728541e
--- /dev/null
+++ b/doc/src/sgml/ref/drop_trigger.sgml
@@ -0,0 +1,127 @@
+<!--
+doc/src/sgml/ref/drop_trigger.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptrigger">
+ <indexterm zone="sql-droptrigger">
+ <primary>DROP TRIGGER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TRIGGER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TRIGGER</refname>
+ <refpurpose>remove a trigger</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TRIGGER [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table_name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TRIGGER</command> removes an existing
+ trigger definition. To execute this command, the current
+ user must be the owner of the table for which the trigger is defined.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the trigger does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the trigger to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table for which
+ the trigger is defined.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the trigger,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the trigger if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-droptrigger-examples">
+ <title>Examples</title>
+
+ <para>
+ Destroy the trigger <literal>if_dist_exists</literal> on the table
+ <literal>films</literal>:
+
+<programlisting>
+DROP TRIGGER if_dist_exists ON films;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-droptrigger-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>DROP TRIGGER</command> statement in
+ <productname>PostgreSQL</productname> is incompatible with the SQL
+ standard. In the SQL standard, trigger names are not local to
+ tables, so the command is simply <literal>DROP TRIGGER
+ <replaceable>name</replaceable></literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtrigger"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_tsconfig.sgml b/doc/src/sgml/ref/drop_tsconfig.sgml
new file mode 100644
index 0000000..9eec4ba
--- /dev/null
+++ b/doc/src/sgml/ref/drop_tsconfig.sgml
@@ -0,0 +1,121 @@
+<!--
+doc/src/sgml/ref/drop_tsconfig.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptsconfig">
+ <indexterm zone="sql-droptsconfig">
+ <primary>DROP TEXT SEARCH CONFIGURATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TEXT SEARCH CONFIGURATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TEXT SEARCH CONFIGURATION</refname>
+ <refpurpose>remove a text search configuration</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TEXT SEARCH CONFIGURATION</command> drops an existing text
+ search configuration. To execute this command you must be the owner of the
+ configuration.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the text search configuration does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search
+ configuration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the text search configuration,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the text search configuration if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the text search configuration <literal>my_english</literal>:
+
+<programlisting>
+DROP TEXT SEARCH CONFIGURATION my_english;
+</programlisting>
+
+ This command will not succeed if there are any existing indexes
+ that reference the configuration in <function>to_tsvector</function> calls.
+ Add <literal>CASCADE</literal> to
+ drop such indexes along with the text search configuration.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP TEXT SEARCH CONFIGURATION</command> statement in
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertsconfig"/></member>
+ <member><xref linkend="sql-createtsconfig"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_tsdictionary.sgml b/doc/src/sgml/ref/drop_tsdictionary.sgml
new file mode 100644
index 0000000..8d22cfd
--- /dev/null
+++ b/doc/src/sgml/ref/drop_tsdictionary.sgml
@@ -0,0 +1,120 @@
+<!--
+doc/src/sgml/ref/drop_tsdictionary.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptsdictionary">
+ <indexterm zone="sql-droptsdictionary">
+ <primary>DROP TEXT SEARCH DICTIONARY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TEXT SEARCH DICTIONARY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TEXT SEARCH DICTIONARY</refname>
+ <refpurpose>remove a text search dictionary</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TEXT SEARCH DICTIONARY</command> drops an existing text
+ search dictionary. To execute this command you must be the owner of the
+ dictionary.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the text search dictionary does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search
+ dictionary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the text search dictionary,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the text search dictionary if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the text search dictionary <literal>english</literal>:
+
+<programlisting>
+DROP TEXT SEARCH DICTIONARY english;
+</programlisting>
+
+ This command will not succeed if there are any existing text search
+ configurations that use the dictionary. Add <literal>CASCADE</literal> to
+ drop such configurations along with the dictionary.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP TEXT SEARCH DICTIONARY</command> statement in the
+ SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertsdictionary"/></member>
+ <member><xref linkend="sql-createtsdictionary"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_tsparser.sgml b/doc/src/sgml/ref/drop_tsparser.sgml
new file mode 100644
index 0000000..2b647cc
--- /dev/null
+++ b/doc/src/sgml/ref/drop_tsparser.sgml
@@ -0,0 +1,118 @@
+<!--
+doc/src/sgml/ref/drop_tsparser.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptsparser">
+ <indexterm zone="sql-droptsparser">
+ <primary>DROP TEXT SEARCH PARSER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TEXT SEARCH PARSER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TEXT SEARCH PARSER</refname>
+ <refpurpose>remove a text search parser</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TEXT SEARCH PARSER [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TEXT SEARCH PARSER</command> drops an existing text search
+ parser. You must be a superuser to use this command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the text search parser does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search parser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the text search parser,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the text search parser if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the text search parser <literal>my_parser</literal>:
+
+<programlisting>
+DROP TEXT SEARCH PARSER my_parser;
+</programlisting>
+
+ This command will not succeed if there are any existing text search
+ configurations that use the parser. Add <literal>CASCADE</literal> to
+ drop such configurations along with the parser.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP TEXT SEARCH PARSER</command> statement in the
+ SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertsparser"/></member>
+ <member><xref linkend="sql-createtsparser"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_tstemplate.sgml b/doc/src/sgml/ref/drop_tstemplate.sgml
new file mode 100644
index 0000000..972b90a
--- /dev/null
+++ b/doc/src/sgml/ref/drop_tstemplate.sgml
@@ -0,0 +1,119 @@
+<!--
+doc/src/sgml/ref/drop_tstemplate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptstemplate">
+ <indexterm zone="sql-droptstemplate">
+ <primary>DROP TEXT SEARCH TEMPLATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TEXT SEARCH TEMPLATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TEXT SEARCH TEMPLATE</refname>
+ <refpurpose>remove a text search template</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TEXT SEARCH TEMPLATE</command> drops an existing text search
+ template. You must be a superuser to use this command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the text search template does not exist.
+ A notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing text search
+ template.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the text search template,
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the text search template if any objects depend on it.
+ This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Remove the text search template <literal>thesaurus</literal>:
+
+<programlisting>
+DROP TEXT SEARCH TEMPLATE thesaurus;
+</programlisting>
+
+ This command will not succeed if there are any existing text search
+ dictionaries that use the template. Add <literal>CASCADE</literal> to
+ drop such dictionaries along with the template.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>DROP TEXT SEARCH TEMPLATE</command> statement in the
+ SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertstemplate"/></member>
+ <member><xref linkend="sql-createtstemplate"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_type.sgml b/doc/src/sgml/ref/drop_type.sgml
new file mode 100644
index 0000000..9e555c0
--- /dev/null
+++ b/doc/src/sgml/ref/drop_type.sgml
@@ -0,0 +1,116 @@
+<!--
+doc/src/sgml/ref/drop_type.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-droptype">
+ <indexterm zone="sql-droptype">
+ <primary>DROP TYPE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP TYPE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP TYPE</refname>
+ <refpurpose>remove a data type</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP TYPE [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP TYPE</command> removes a user-defined data type.
+ Only the owner of a type can remove it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the type does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the data type to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the type (such as
+ table columns, functions, and operators),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the type if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-droptype-examples">
+ <title>Examples</title>
+
+ <para>
+ To remove the data type <type>box</type>:
+<programlisting>
+DROP TYPE box;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-droptype-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ This command is similar to the corresponding command in the SQL
+ standard, apart from the <literal>IF EXISTS</literal>
+ option, which is a <productname>PostgreSQL</productname> extension.
+ But note that much of the <command>CREATE TYPE</command> command
+ and the data type extension mechanisms in
+ <productname>PostgreSQL</productname> differ from the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-droptype-see-also">
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-altertype"/></member>
+ <member><xref linkend="sql-createtype"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_user.sgml b/doc/src/sgml/ref/drop_user.sgml
new file mode 100644
index 0000000..74e736b
--- /dev/null
+++ b/doc/src/sgml/ref/drop_user.sgml
@@ -0,0 +1,55 @@
+<!--
+doc/src/sgml/ref/drop_user.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropuser">
+ <indexterm zone="sql-dropuser">
+ <primary>DROP USER</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP USER</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP USER</refname>
+ <refpurpose>remove a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP USER [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP USER</command> is simply an alternate spelling of
+ <link linkend="sql-droprole"><command>DROP ROLE</command></link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>DROP USER</command> statement is a
+ <productname>PostgreSQL</productname> extension. The SQL standard
+ leaves the definition of users to the implementation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-droprole"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_user_mapping.sgml b/doc/src/sgml/ref/drop_user_mapping.sgml
new file mode 100644
index 0000000..9e8896a
--- /dev/null
+++ b/doc/src/sgml/ref/drop_user_mapping.sgml
@@ -0,0 +1,110 @@
+<!--
+doc/src/sgml/ref/drop_user_mapping.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropusermapping">
+ <indexterm zone="sql-dropusermapping">
+ <primary>DROP USER MAPPING</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP USER MAPPING</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP USER MAPPING</refname>
+ <refpurpose>remove a user mapping for a foreign server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP USER MAPPING [ IF EXISTS ] FOR { <replaceable class="parameter">user_name</replaceable> | USER | CURRENT_ROLE | CURRENT_USER | PUBLIC } SERVER <replaceable class="parameter">server_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP USER MAPPING</command> removes an existing user
+ mapping from foreign server.
+ </para>
+
+ <para>
+ The owner of a foreign server can drop user mappings for that server
+ for any user. Also, a user can drop a user mapping for their own
+ user name if <literal>USAGE</literal> privilege on the server has been
+ granted to the user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the user mapping does not exist. A
+ notice is issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">user_name</replaceable></term>
+ <listitem>
+ <para>
+ User name of the mapping. <literal>CURRENT_ROLE</literal>, <literal>CURRENT_USER</literal>,
+ and <literal>USER</literal> match the name of the current
+ user. <literal>PUBLIC</literal> is used to match all present and
+ future user names in the system.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_name</replaceable></term>
+ <listitem>
+ <para>
+ Server name of the user mapping.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Drop a user mapping <literal>bob</literal>, server <literal>foo</literal> if it exists:
+<programlisting>
+DROP USER MAPPING IF EXISTS FOR bob SERVER foo;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>DROP USER MAPPING</command> conforms to ISO/IEC 9075-9
+ (SQL/MED). The <literal>IF EXISTS</literal> clause is
+ a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createusermapping"/></member>
+ <member><xref linkend="sql-alterusermapping"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/drop_view.sgml b/doc/src/sgml/ref/drop_view.sgml
new file mode 100644
index 0000000..a1c550e
--- /dev/null
+++ b/doc/src/sgml/ref/drop_view.sgml
@@ -0,0 +1,114 @@
+<!--
+doc/src/sgml/ref/drop_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-dropview">
+ <indexterm zone="sql-dropview">
+ <primary>DROP VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>DROP VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>DROP VIEW</refname>
+ <refpurpose>remove a view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+DROP VIEW [ IF EXISTS ] <replaceable class="parameter">name</replaceable> [, ...] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>DROP VIEW</command> drops an existing view. To execute
+ this command you must be the owner of the view.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>IF EXISTS</literal></term>
+ <listitem>
+ <para>
+ Do not throw an error if the view does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the view to remove.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically drop objects that depend on the view (such as
+ other views),
+ and in turn all objects that depend on those objects
+ (see <xref linkend="ddl-depend"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to drop the view if any objects depend on it. This is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This command will remove the view called <literal>kinds</literal>:
+<programlisting>
+DROP VIEW kinds;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the SQL standard, except that the standard only
+ allows one view to be dropped per command, and apart from the
+ <literal>IF EXISTS</literal> option, which is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-alterview"/></member>
+ <member><xref linkend="sql-createview"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/dropdb.sgml b/doc/src/sgml/ref/dropdb.sgml
new file mode 100644
index 0000000..d36aed3
--- /dev/null
+++ b/doc/src/sgml/ref/dropdb.sgml
@@ -0,0 +1,317 @@
+<!--
+doc/src/sgml/ref/dropdb.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-dropdb">
+ <indexterm zone="app-dropdb">
+ <primary>dropdb</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>dropdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dropdb</refname>
+ <refpurpose>remove a <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dropdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="plain"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>dropdb</application> destroys an existing
+ <productname>PostgreSQL</productname> database.
+ The user who executes this command must be a database
+ superuser or the owner of the database.
+ </para>
+
+ <para>
+ <application>dropdb</application> is a wrapper around the
+ <acronym>SQL</acronym> command <link linkend="sql-dropdatabase"><command>DROP DATABASE</command></link>.
+ There is no effective difference between dropping databases via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>dropdb</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">dbname</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be removed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>dropdb</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+ <term><option>--force</option></term>
+ <listitem>
+ <para>
+ Attempt to terminate all existing connections to the target database
+ before dropping it. See <xref linkend="sql-dropdatabase"/> for more
+ information on this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <term><option>--interactive</option></term>
+ <listitem>
+ <para>
+ Issues a verification prompt before doing anything destructive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>dropdb</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-exists</option></term>
+ <listitem>
+ <para>
+ Do not throw an error if the database does not exist. A notice is issued
+ in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>dropdb</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+
+ <para>
+ <application>dropdb</application> also accepts the following
+ command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the
+ server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>dropdb</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>dropdb</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>dropdb</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to in order to drop the
+ target database. If not specified, the <literal>postgres</literal>
+ database will be used; if that does not exist (or is the database
+ being dropped), <literal>template1</literal> will be used.
+ This can be a <link linkend="libpq-connstring">connection
+ string</link>. If so, connection string parameters will override any
+ conflicting command line options.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-dropdatabase"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To destroy the database <literal>demo</literal> on the default
+ database server:
+<screen>
+<prompt>$ </prompt><userinput>dropdb demo</userinput>
+</screen>
+ </para>
+
+ <para>
+ To destroy the database <literal>demo</literal> using the
+ server on host <literal>eden</literal>, port 5000, with verification and a peek
+ at the underlying command:
+<screen>
+<prompt>$ </prompt><userinput>dropdb -p 5000 -h eden -i -e demo</userinput>
+<computeroutput>Database "demo" will be permanently deleted.
+Are you sure? (y/n) </computeroutput><userinput>y</userinput>
+<computeroutput>DROP DATABASE demo;</computeroutput>
+</screen></para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-createdb"/></member>
+ <member><xref linkend="sql-dropdatabase"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/dropuser.sgml b/doc/src/sgml/ref/dropuser.sgml
new file mode 100644
index 0000000..8158050
--- /dev/null
+++ b/doc/src/sgml/ref/dropuser.sgml
@@ -0,0 +1,294 @@
+<!--
+doc/src/sgml/ref/dropuser.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-dropuser">
+ <indexterm zone="app-dropuser">
+ <primary>dropuser</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>dropuser</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>dropuser</refname>
+ <refpurpose>remove a <productname>PostgreSQL</productname> user account</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>dropuser</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>username</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>dropuser</application> removes an existing
+ <productname>PostgreSQL</productname> user.
+ Only superusers and users with the <literal>CREATEROLE</literal> privilege can
+ remove <productname>PostgreSQL</productname> users. (To remove a
+ superuser, you must yourself be a superuser.)
+ </para>
+
+ <para>
+ <application>dropuser</application> is a wrapper around the
+ <acronym>SQL</acronym> command <link linkend="sql-droprole"><command>DROP ROLE</command></link>.
+ There is no effective difference between dropping users via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>dropuser</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">username</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the <productname>PostgreSQL</productname> user to be removed.
+ You will be prompted for a name if none is specified on the command
+ line and the <option>-i</option>/<option>--interactive</option> option
+ is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>dropuser</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <term><option>--interactive</option></term>
+ <listitem>
+ <para>
+ Prompt for confirmation before actually removing the user, and prompt
+ for the user name if none is specified on the command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>dropuser</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-exists</option></term>
+ <listitem>
+ <para>
+ Do not throw an error if the user does not exist. A notice is
+ issued in this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>dropuser</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ <application>dropuser</application> also accepts the following
+ command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the
+ server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as (not the user name to drop).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>dropuser</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>dropuser</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>dropuser</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-droprole"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To remove user <literal>joe</literal> from the default database
+ server:
+<screen>
+<prompt>$ </prompt><userinput>dropuser joe</userinput>
+</screen>
+ </para>
+
+ <para>
+ To remove user <literal>joe</literal> using the server on host
+ <literal>eden</literal>, port 5000, with verification and a peek at the underlying
+ command:
+<screen>
+<prompt>$ </prompt><userinput>dropuser -p 5000 -h eden -i -e joe</userinput>
+<computeroutput>Role "joe" will be permanently removed.
+Are you sure? (y/n) </computeroutput><userinput>y</userinput>
+<computeroutput>DROP ROLE joe;</computeroutput>
+</screen></para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-createuser"/></member>
+ <member><xref linkend="sql-droprole"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/ecpg-ref.sgml b/doc/src/sgml/ref/ecpg-ref.sgml
new file mode 100644
index 0000000..f3b6034
--- /dev/null
+++ b/doc/src/sgml/ref/ecpg-ref.sgml
@@ -0,0 +1,278 @@
+<!--
+doc/src/sgml/ref/ecpg-ref.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-ecpg">
+ <indexterm zone="app-ecpg">
+ <primary>ecpg</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>ecpg</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>ecpg</application></refname>
+ <refpurpose>embedded SQL C preprocessor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ecpg</command>
+ <arg choice="opt" rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="plain" rep="repeat"><replaceable>file</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="app-ecpg-description">
+ <title>Description</title>
+
+ <para>
+ <command>ecpg</command> is the embedded SQL preprocessor for C
+ programs. It converts C programs with embedded SQL statements to
+ normal C code by replacing the SQL invocations with special
+ function calls. The output files can then be processed with any C
+ compiler tool chain.
+ </para>
+
+ <para>
+ <command>ecpg</command> will convert each input file given on the
+ command line to the corresponding C output file. If an input file
+ name does not have any extension, <filename>.pgc</filename> is
+ assumed. The file's extension will be replaced
+ by <filename>.c</filename> to construct the output file name.
+ But the output file name can be overridden using the
+ <option>-o</option> option.
+ </para>
+
+ <para>
+ If an input file name is just <literal>-</literal>,
+ <command>ecpg</command> reads the program from standard input
+ (and writes to standard output, unless that is overridden
+ with <option>-o</option>).
+ </para>
+
+ <para>
+ This reference page does not describe the embedded SQL language.
+ See <xref linkend="ecpg"/> for more information on that topic.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <command>ecpg</command> accepts the following command-line
+ arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-c</option></term>
+ <listitem>
+ <para>
+ Automatically generate certain C code from SQL code. Currently, this
+ works for <literal>EXEC SQL TYPE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C <replaceable>mode</replaceable></option></term>
+ <listitem>
+ <para>
+ Set a compatibility mode. <replaceable>mode</replaceable> can
+ be <literal>INFORMIX</literal>,
+ <literal>INFORMIX_SE</literal>, or <literal>ORACLE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D <replaceable>symbol</replaceable></option></term>
+ <listitem>
+ <para>
+ Define a C preprocessor symbol.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h</option></term>
+ <listitem>
+ <para>
+ Process header files. When this option is specified, the output file
+ extension becomes <literal>.h</literal> not <literal>.c</literal>,
+ and the default input file extension is <literal>.pgh</literal>
+ not <literal>.pgc</literal>. Also, the <option>-c</option> option is
+ forced on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <listitem>
+ <para>
+ Parse system include files as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-I <replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify an additional include path, used to find files included
+ via <literal>EXEC SQL INCLUDE</literal>. Defaults are
+ <filename>.</filename> (current directory),
+ <filename>/usr/local/include</filename>, the
+ <productname>PostgreSQL</productname> include directory which
+ is defined at compile time (default:
+ <filename>/usr/local/pgsql/include</filename>), and
+ <filename>/usr/include</filename>, in that order.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable>filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies that <command>ecpg</command> should write all
+ its output to the given <replaceable>filename</replaceable>.
+ Write <literal>-o -</literal> to send all output to standard output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r <replaceable>option</replaceable></option></term>
+ <listitem>
+ <para>
+ Selects run-time behavior. <replaceable>Option</replaceable> can be
+ one of the following:
+ <variablelist>
+ <varlistentry>
+ <term><option>no_indicator</option></term>
+ <listitem>
+ <para>
+ Do not use indicators but instead use special values to represent
+ null values. Historically there have been databases using this approach.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>prepare</option></term>
+ <listitem>
+ <para>
+ Prepare all statements before using them. Libecpg will keep a cache of
+ prepared statements and reuse a statement if it gets executed again. If the
+ cache runs full, libecpg will free the least used statement.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>questionmarks</option></term>
+ <listitem>
+ <para>
+ Allow question mark as placeholder for compatibility reasons.
+ This used to be the default long ago.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option></term>
+ <listitem>
+ <para>
+ Turn on autocommit of transactions. In this mode, each SQL command is
+ automatically committed unless it is inside an explicit
+ transaction block. In the default mode, commands are committed
+ only when <command>EXEC SQL COMMIT</command> is issued.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <listitem>
+ <para>
+ Print additional information including the version and the
+ "include" path.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>ecpg</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>ecpg</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When compiling the preprocessed C code files, the compiler needs to
+ be able to find the <application>ECPG</application> header files in the
+ <productname>PostgreSQL</productname> include directory. Therefore, you might
+ have to use the <option>-I</option> option when invoking the compiler
+ (e.g., <literal>-I/usr/local/pgsql/include</literal>).
+ </para>
+
+ <para>
+ Programs using C code with embedded SQL have to be linked against
+ the <filename>libecpg</filename> library, for example using the
+ linker options <literal>-L/usr/local/pgsql/lib -lecpg</literal>.
+ </para>
+
+ <para>
+ The value of either of these directories that is appropriate for
+ the installation can be found out using <xref
+ linkend="app-pgconfig"/>.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ If you have an embedded SQL C source file named
+ <filename>prog1.pgc</filename>, you can create an executable
+ program using the following sequence of commands:
+<programlisting>
+ecpg prog1.pgc
+cc -I/usr/local/pgsql/include -c prog1.c
+cc -o prog1 prog1.o -L/usr/local/pgsql/lib -lecpg
+</programlisting></para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/end.sgml b/doc/src/sgml/ref/end.sgml
new file mode 100644
index 0000000..4986529
--- /dev/null
+++ b/doc/src/sgml/ref/end.sgml
@@ -0,0 +1,112 @@
+<!--
+doc/src/sgml/ref/end.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-end">
+ <indexterm zone="sql-end">
+ <primary>END</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>END</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>END</refname>
+ <refpurpose>commit the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>END</command> commits the current transaction. All changes
+ made by the transaction become visible to others and are guaranteed
+ to be durable if a crash occurs. This command is a
+ <productname>PostgreSQL</productname> extension
+ that is equivalent to <link linkend="sql-commit"><command>COMMIT</command></link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>WORK</literal></term>
+ <term><literal>TRANSACTION</literal></term>
+ <listitem>
+ <para>
+ Optional key words. They have no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>AND CHAIN</literal></term>
+ <listitem>
+ <para>
+ If <literal>AND CHAIN</literal> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <xref
+ linkend="sql-set-transaction"/>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-rollback"><command>ROLLBACK</command></link> to
+ abort a transaction.
+ </para>
+
+ <para>
+ Issuing <command>END</command> when not inside a transaction does
+ no harm, but it will provoke a warning message.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To commit the current transaction and make all changes permanent:
+<programlisting>
+END;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>END</command> is a <productname>PostgreSQL</productname>
+ extension that provides functionality equivalent to <link
+ linkend="sql-commit"><command>COMMIT</command></link>, which is
+ specified in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/execute.sgml b/doc/src/sgml/ref/execute.sgml
new file mode 100644
index 0000000..1d887f3
--- /dev/null
+++ b/doc/src/sgml/ref/execute.sgml
@@ -0,0 +1,121 @@
+<!--
+doc/src/sgml/ref/execute.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-execute">
+ <indexterm zone="sql-execute">
+ <primary>EXECUTE</primary>
+ </indexterm>
+
+ <indexterm zone="sql-execute">
+ <primary>prepared statements</primary>
+ <secondary>executing</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>EXECUTE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>EXECUTE</refname>
+ <refpurpose>execute a prepared statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+EXECUTE <replaceable class="parameter">name</replaceable> [ ( <replaceable class="parameter">parameter</replaceable> [, ...] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>EXECUTE</command> is used to execute a previously prepared
+ statement. Since prepared statements only exist for the duration of a
+ session, the prepared statement must have been created by a
+ <command>PREPARE</command> statement executed earlier in the
+ current session.
+ </para>
+
+ <para>
+ If the <command>PREPARE</command> statement that created the statement
+ specified some parameters, a compatible set of parameters must be
+ passed to the <command>EXECUTE</command> statement, or else an
+ error is raised. Note that (unlike functions) prepared statements are
+ not overloaded based on the type or number of their parameters; the
+ name of a prepared statement must be unique within a database session.
+ </para>
+
+ <para>
+ For more information on the creation and usage of prepared statements,
+ see <xref linkend="sql-prepare"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the prepared statement to execute.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">parameter</replaceable></term>
+ <listitem>
+ <para>
+ The actual value of a parameter to the prepared statement. This
+ must be an expression yielding a value that is compatible with
+ the data type of this parameter, as was determined when the
+ prepared statement was created.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+ <para>
+ The command tag returned by <command>EXECUTE</command>
+ is that of the prepared statement, and not <literal>EXECUTE</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+ <para>
+ Examples are given in <xref linkend="sql-prepare-examples"/>
+ in the <xref linkend="sql-prepare"/> documentation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard includes an <command>EXECUTE</command> statement,
+ but it is only for use in embedded SQL. This version of the
+ <command>EXECUTE</command> statement also uses a somewhat different
+ syntax.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-deallocate"/></member>
+ <member><xref linkend="sql-prepare"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml
new file mode 100644
index 0000000..0fce622
--- /dev/null
+++ b/doc/src/sgml/ref/explain.sgml
@@ -0,0 +1,487 @@
+<!--
+doc/src/sgml/ref/explain.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-explain">
+ <indexterm zone="sql-explain">
+ <primary>EXPLAIN</primary>
+ </indexterm>
+
+ <indexterm zone="sql-explain">
+ <primary>prepared statements</primary>
+ <secondary>showing the query plan</secondary>
+ </indexterm>
+
+ <indexterm zone="sql-explain">
+ <primary>cursor</primary>
+ <secondary>showing the query plan</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>EXPLAIN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>EXPLAIN</refname>
+ <refpurpose>show the execution plan of a statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+EXPLAIN [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] <replaceable class="parameter">statement</replaceable>
+EXPLAIN [ ANALYZE ] [ VERBOSE ] <replaceable class="parameter">statement</replaceable>
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
+
+ ANALYZE [ <replaceable class="parameter">boolean</replaceable> ]
+ VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
+ COSTS [ <replaceable class="parameter">boolean</replaceable> ]
+ SETTINGS [ <replaceable class="parameter">boolean</replaceable> ]
+ BUFFERS [ <replaceable class="parameter">boolean</replaceable> ]
+ WAL [ <replaceable class="parameter">boolean</replaceable> ]
+ TIMING [ <replaceable class="parameter">boolean</replaceable> ]
+ SUMMARY [ <replaceable class="parameter">boolean</replaceable> ]
+ FORMAT { TEXT | XML | JSON | YAML }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ This command displays the execution plan that the
+ <productname>PostgreSQL</productname> planner generates for the
+ supplied statement. The execution plan shows how the table(s)
+ referenced by the statement will be scanned &mdash; by plain sequential scan,
+ index scan, etc. &mdash; and if multiple tables are referenced, what join
+ algorithms will be used to bring together the required rows from
+ each input table.
+ </para>
+
+ <para>
+ The most critical part of the display is the estimated statement execution
+ cost, which is the planner's guess at how long it will take to run the
+ statement (measured in cost units that are arbitrary, but conventionally
+ mean disk page fetches). Actually two numbers
+ are shown: the start-up cost before the first row can be returned, and
+ the total cost to return all the rows. For most queries the total cost
+ is what matters, but in contexts such as a subquery in <literal>EXISTS</literal>, the planner
+ will choose the smallest start-up cost instead of the smallest total cost
+ (since the executor will stop after getting one row, anyway).
+ Also, if you limit the number of rows to return with a <literal>LIMIT</literal> clause,
+ the planner makes an appropriate interpolation between the endpoint
+ costs to estimate which plan is really the cheapest.
+ </para>
+
+ <para>
+ The <literal>ANALYZE</literal> option causes the statement to be actually
+ executed, not only planned. Then actual run time statistics are added to
+ the display, including the total elapsed time expended within each plan
+ node (in milliseconds) and the total number of rows it actually returned.
+ This is useful for seeing whether the planner's estimates
+ are close to reality.
+ </para>
+
+ <important>
+ <para>
+ Keep in mind that the statement is actually executed when
+ the <literal>ANALYZE</literal> option is used. Although
+ <command>EXPLAIN</command> will discard any output that a
+ <command>SELECT</command> would return, other side effects of the
+ statement will happen as usual. If you wish to use
+ <command>EXPLAIN ANALYZE</command> on an
+ <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, <command>MERGE</command>,
+ <command>CREATE TABLE AS</command>,
+ or <command>EXECUTE</command> statement
+ without letting the command affect your data, use this approach:
+<programlisting>
+BEGIN;
+EXPLAIN ANALYZE ...;
+ROLLBACK;
+</programlisting>
+ </para>
+ </important>
+
+ <para>
+ Only the <literal>ANALYZE</literal> and <literal>VERBOSE</literal> options
+ can be specified, and only in that order, without surrounding the option
+ list in parentheses. Prior to <productname>PostgreSQL</productname> 9.0,
+ the unparenthesized syntax was the only one supported. It is expected that
+ all new options will be supported only in the parenthesized syntax.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ANALYZE</literal></term>
+ <listitem>
+ <para>
+ Carry out the command and show actual run times and other statistics.
+ This parameter defaults to <literal>FALSE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VERBOSE</literal></term>
+ <listitem>
+ <para>
+ Display additional information regarding the plan. Specifically, include
+ the output column list for each node in the plan tree, schema-qualify
+ table and function names, always label variables in expressions with
+ their range table alias, and always print the name of each trigger for
+ which statistics are displayed. The query identifier will also be
+ displayed if one has been computed, see <xref
+ linkend="guc-compute-query-id"/> for more details. This parameter
+ defaults to <literal>FALSE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>COSTS</literal></term>
+ <listitem>
+ <para>
+ Include information on the estimated startup and total cost of each
+ plan node, as well as the estimated number of rows and the estimated
+ width of each row.
+ This parameter defaults to <literal>TRUE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SETTINGS</literal></term>
+ <listitem>
+ <para>
+ Include information on configuration parameters. Specifically, include
+ options affecting query planning with value different from the built-in
+ default value. This parameter defaults to <literal>FALSE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BUFFERS</literal></term>
+ <listitem>
+ <para>
+ Include information on buffer usage. Specifically, include the number of
+ shared blocks hit, read, dirtied, and written, the number of local blocks
+ hit, read, dirtied, and written, the number of temp blocks read and
+ written, and the time spent reading and writing data file blocks and
+ temporary file blocks (in milliseconds) if
+ <xref linkend="guc-track-io-timing"/> is enabled. A
+ <emphasis>hit</emphasis> means that a read was avoided because the block
+ was found already in cache when needed.
+ Shared blocks contain data from regular tables and indexes;
+ local blocks contain data from temporary tables and indexes;
+ while temporary blocks contain short-term working data used in sorts,
+ hashes, Materialize plan nodes, and similar cases.
+ The number of blocks <emphasis>dirtied</emphasis> indicates the number of
+ previously unmodified blocks that were changed by this query; while the
+ number of blocks <emphasis>written</emphasis> indicates the number of
+ previously-dirtied blocks evicted from cache by this backend during
+ query processing.
+ The number of blocks shown for an
+ upper-level node includes those used by all its child nodes. In text
+ format, only non-zero values are printed. It defaults to
+ <literal>FALSE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>WAL</literal></term>
+ <listitem>
+ <para>
+ Include information on WAL record generation. Specifically, include the
+ number of records, number of full page images (fpi) and the amount of WAL
+ generated in bytes. In text format, only non-zero values are printed.
+ This parameter may only be used when <literal>ANALYZE</literal> is also
+ enabled. It defaults to <literal>FALSE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TIMING</literal></term>
+ <listitem>
+ <para>
+ Include actual startup time and time spent in each node in the output.
+ The overhead of repeatedly reading the system clock can slow down the
+ query significantly on some systems, so it may be useful to set this
+ parameter to <literal>FALSE</literal> when only actual row counts, and
+ not exact times, are needed. Run time of the entire statement is
+ always measured, even when node-level timing is turned off with this
+ option.
+ This parameter may only be used when <literal>ANALYZE</literal> is also
+ enabled. It defaults to <literal>TRUE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SUMMARY</literal></term>
+ <listitem>
+ <para>
+ Include summary information (e.g., totaled timing information) after the
+ query plan. Summary information is included by default when
+ <literal>ANALYZE</literal> is used but otherwise is not included by
+ default, but can be enabled using this option. Planning time in
+ <command>EXPLAIN EXECUTE</command> includes the time required to fetch
+ the plan from the cache and the time required for re-planning, if
+ necessary.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORMAT</literal></term>
+ <listitem>
+ <para>
+ Specify the output format, which can be TEXT, XML, JSON, or YAML.
+ Non-text output contains the same information as the text output
+ format, but is easier for programs to parse. This parameter defaults to
+ <literal>TEXT</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">boolean</replaceable></term>
+ <listitem>
+ <para>
+ Specifies whether the selected option should be turned on or off.
+ You can write <literal>TRUE</literal>, <literal>ON</literal>, or
+ <literal>1</literal> to enable the option, and <literal>FALSE</literal>,
+ <literal>OFF</literal>, or <literal>0</literal> to disable it. The
+ <replaceable class="parameter">boolean</replaceable> value can also
+ be omitted, in which case <literal>TRUE</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">statement</replaceable></term>
+ <listitem>
+ <para>
+ Any <command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, <command>MERGE</command>,
+ <command>VALUES</command>, <command>EXECUTE</command>,
+ <command>DECLARE</command>, <command>CREATE TABLE AS</command>, or
+ <command>CREATE MATERIALIZED VIEW AS</command> statement, whose execution
+ plan you wish to see.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ The command's result is a textual description of the plan selected
+ for the <replaceable class="parameter">statement</replaceable>,
+ optionally annotated with execution statistics.
+ <xref linkend="using-explain"/> describes the information provided.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ In order to allow the <productname>PostgreSQL</productname> query
+ planner to make reasonably informed decisions when optimizing
+ queries, the <link
+ linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>
+ data should be up-to-date for all tables used in the query. Normally
+ the <link linkend="autovacuum">autovacuum daemon</link> will take care
+ of that automatically. But if a table has recently had substantial
+ changes in its contents, you might need to do a manual
+ <link linkend="sql-analyze"><command>ANALYZE</command></link> rather than wait for autovacuum to catch up
+ with the changes.
+ </para>
+
+ <para>
+ In order to measure the run-time cost of each node in the execution
+ plan, the current implementation of <command>EXPLAIN
+ ANALYZE</command> adds profiling overhead to query execution.
+ As a result, running <command>EXPLAIN ANALYZE</command>
+ on a query can sometimes take significantly longer than executing
+ the query normally. The amount of overhead depends on the nature of
+ the query, as well as the platform being used. The worst case occurs
+ for plan nodes that in themselves require very little time per
+ execution, and on machines that have relatively slow operating
+ system calls for obtaining the time of day.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To show the plan for a simple query on a table with a single
+ <type>integer</type> column and 10000 rows:
+
+<programlisting>
+EXPLAIN SELECT * FROM foo;
+
+ QUERY PLAN
+---------------------------------------------------------
+ Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4)
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Here is the same query, with JSON output formatting:
+<programlisting>
+EXPLAIN (FORMAT JSON) SELECT * FROM foo;
+ QUERY PLAN
+--------------------------------
+ [ +
+ { +
+ "Plan": { +
+ "Node Type": "Seq Scan",+
+ "Relation Name": "foo", +
+ "Alias": "foo", +
+ "Startup Cost": 0.00, +
+ "Total Cost": 155.00, +
+ "Plan Rows": 10000, +
+ "Plan Width": 4 +
+ } +
+ } +
+ ]
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ If there is an index and we use a query with an indexable
+ <literal>WHERE</literal> condition, <command>EXPLAIN</command>
+ might show a different plan:
+
+<programlisting>
+EXPLAIN SELECT * FROM foo WHERE i = 4;
+
+ QUERY PLAN
+--------------------------------------------------------------
+ Index Scan using fi on foo (cost=0.00..5.98 rows=1 width=4)
+ Index Cond: (i = 4)
+(2 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Here is the same query, but in YAML format:
+<programlisting>
+EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i='4';
+ QUERY PLAN
+-------------------------------
+ - Plan: +
+ Node Type: "Index Scan" +
+ Scan Direction: "Forward"+
+ Index Name: "fi" +
+ Relation Name: "foo" +
+ Alias: "foo" +
+ Startup Cost: 0.00 +
+ Total Cost: 5.98 +
+ Plan Rows: 1 +
+ Plan Width: 4 +
+ Index Cond: "(i = 4)"
+(1 row)
+</programlisting>
+
+ XML format is left as an exercise for the reader.
+ </para>
+ <para>
+ Here is the same plan with cost estimates suppressed:
+
+<programlisting>
+EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4;
+
+ QUERY PLAN
+----------------------------
+ Index Scan using fi on foo
+ Index Cond: (i = 4)
+(2 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example of a query plan for a query using an aggregate
+ function:
+
+<programlisting>
+EXPLAIN SELECT sum(i) FROM foo WHERE i &lt; 10;
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;--
+ Aggregate (cost=23.93..23.93 rows=1 width=4)
+ -&gt; Index Scan using fi on foo (cost=0.00..23.92 rows=6 width=4)
+ Index Cond: (i &lt; 10)
+(3 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example of using <command>EXPLAIN EXECUTE</command> to
+ display the execution plan for a prepared query:
+
+<programlisting>
+PREPARE query(int, int) AS SELECT sum(bar) FROM test
+ WHERE id &gt; $1 AND id &lt; $2
+ GROUP BY foo;
+
+EXPLAIN ANALYZE EXECUTE query(100, 200);
+
+ QUERY PLAN
+-------------------------------------------------------------------&zwsp;-----------------------------------------------------
+ HashAggregate (cost=9.54..9.54 rows=1 width=8) (actual time=0.156..0.161 rows=11 loops=1)
+ Group Key: foo
+ -&gt; Index Scan using test_pkey on test (cost=0.29..9.29 rows=50 width=8) (actual time=0.039..0.091 rows=99 loops=1)
+ Index Cond: ((id &gt; $1) AND (id &lt; $2))
+ Planning time: 0.197 ms
+ Execution time: 0.225 ms
+(6 rows)
+</programlisting>
+ </para>
+
+ <para>
+ Of course, the specific numbers shown here depend on the actual
+ contents of the tables involved. Also note that the numbers, and
+ even the selected query strategy, might vary between
+ <productname>PostgreSQL</productname> releases due to planner
+ improvements. In addition, the <command>ANALYZE</command> command
+ uses random sampling to estimate data statistics; therefore, it is
+ possible for cost estimates to change after a fresh run of
+ <command>ANALYZE</command>, even if the actual distribution of data
+ in the table has not changed.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>EXPLAIN</command> statement defined in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-analyze"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/fetch.sgml b/doc/src/sgml/ref/fetch.sgml
new file mode 100644
index 0000000..f0f3ac2
--- /dev/null
+++ b/doc/src/sgml/ref/fetch.sgml
@@ -0,0 +1,418 @@
+<!--
+doc/src/sgml/ref/fetch.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-fetch">
+
+ <indexterm zone="sql-fetch">
+ <primary>FETCH</primary>
+ </indexterm>
+
+ <indexterm zone="sql-fetch">
+ <primary>cursor</primary>
+ <secondary>FETCH</secondary>
+ </indexterm>
+ <refmeta>
+ <refentrytitle>FETCH</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>FETCH</refname>
+ <refpurpose>retrieve rows from a query using a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<!-- Note the "direction" bit is also in ref/move.sgml -->
+<synopsis>
+FETCH [ <replaceable class="parameter">direction</replaceable> ] [ FROM | IN ] <replaceable class="parameter">cursor_name</replaceable>
+
+<phrase>where <replaceable class="parameter">direction</replaceable> can be one of:</phrase>
+
+ NEXT
+ PRIOR
+ FIRST
+ LAST
+ ABSOLUTE <replaceable class="parameter">count</replaceable>
+ RELATIVE <replaceable class="parameter">count</replaceable>
+ <replaceable class="parameter">count</replaceable>
+ ALL
+ FORWARD
+ FORWARD <replaceable class="parameter">count</replaceable>
+ FORWARD ALL
+ BACKWARD
+ BACKWARD <replaceable class="parameter">count</replaceable>
+ BACKWARD ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>FETCH</command> retrieves rows using a previously-created cursor.
+ </para>
+
+ <para>
+ A cursor has an associated position, which is used by
+ <command>FETCH</command>. The cursor position can be before the first row of the
+ query result, on any particular row of the result, or after the last row
+ of the result. When created, a cursor is positioned before the first row.
+ After fetching some rows, the cursor is positioned on the row most recently
+ retrieved. If <command>FETCH</command> runs off the end of the available rows
+ then the cursor is left positioned after the last row, or before the first
+ row if fetching backward. <command>FETCH ALL</command> or <command>FETCH BACKWARD
+ ALL</command> will always leave the cursor positioned after the last row or before
+ the first row.
+ </para>
+
+ <para>
+ The forms <literal>NEXT</literal>, <literal>PRIOR</literal>, <literal>FIRST</literal>,
+ <literal>LAST</literal>, <literal>ABSOLUTE</literal>, <literal>RELATIVE</literal> fetch
+ a single row after moving the cursor appropriately. If there is no
+ such row, an empty result is returned, and the cursor is left
+ positioned before the first row or after the last row as
+ appropriate.
+ </para>
+
+ <para>
+ The forms using <literal>FORWARD</literal> and <literal>BACKWARD</literal>
+ retrieve the indicated number of rows moving in the forward or
+ backward direction, leaving the cursor positioned on the
+ last-returned row (or after/before all rows, if the <replaceable
+ class="parameter">count</replaceable> exceeds the number of rows
+ available).
+ </para>
+
+ <para>
+ <literal>RELATIVE 0</literal>, <literal>FORWARD 0</literal>, and
+ <literal>BACKWARD 0</literal> all request fetching the current row without
+ moving the cursor, that is, re-fetching the most recently fetched
+ row. This will succeed unless the cursor is positioned before the
+ first row or after the last row; in which case, no row is returned.
+ </para>
+
+ <note>
+ <para>
+ This page describes usage of cursors at the SQL command level.
+ If you are trying to use cursors inside a <application>PL/pgSQL</application>
+ function, the rules are different &mdash;
+ see <xref linkend="plpgsql-cursor-using"/>.
+ </para>
+ </note>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">direction</replaceable></term>
+ <listitem>
+ <para><replaceable class="parameter">direction</replaceable> defines
+ the fetch direction and number of rows to fetch. It can be one
+ of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>NEXT</literal></term>
+ <listitem>
+ <para>
+ Fetch the next row. This is the default if <replaceable
+ class="parameter">direction</replaceable> is omitted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PRIOR</literal></term>
+ <listitem>
+ <para>
+ Fetch the prior row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FIRST</literal></term>
+ <listitem>
+ <para>
+ Fetch the first row of the query (same as <literal>ABSOLUTE 1</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LAST</literal></term>
+ <listitem>
+ <para>
+ Fetch the last row of the query (same as <literal>ABSOLUTE -1</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ABSOLUTE <replaceable class="parameter">count</replaceable></literal></term>
+ <listitem>
+ <para>
+ Fetch the <replaceable
+ class="parameter">count</replaceable>'th row of the query,
+ or the <literal>abs(<replaceable
+ class="parameter">count</replaceable>)</literal>'th row from
+ the end if <replaceable
+ class="parameter">count</replaceable> is negative. Position
+ before first row or after last row if <replaceable
+ class="parameter">count</replaceable> is out of range; in
+ particular, <literal>ABSOLUTE 0</literal> positions before
+ the first row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RELATIVE <replaceable class="parameter">count</replaceable></literal></term>
+ <listitem>
+ <para>
+ Fetch the <replaceable
+ class="parameter">count</replaceable>'th succeeding row, or
+ the <literal>abs(<replaceable
+ class="parameter">count</replaceable>)</literal>'th prior
+ row if <replaceable class="parameter">count</replaceable> is
+ negative. <literal>RELATIVE 0</literal> re-fetches the
+ current row, if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">count</replaceable></term>
+ <listitem>
+ <para>
+ Fetch the next <replaceable
+ class="parameter">count</replaceable> rows (same as
+ <literal>FORWARD <replaceable
+ class="parameter">count</replaceable></literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Fetch all remaining rows (same as <literal>FORWARD ALL</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORWARD</literal></term>
+ <listitem>
+ <para>
+ Fetch the next row (same as <literal>NEXT</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORWARD <replaceable class="parameter">count</replaceable></literal></term>
+ <listitem>
+ <para>
+ Fetch the next <replaceable
+ class="parameter">count</replaceable> rows.
+ <literal>FORWARD 0</literal> re-fetches the current row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FORWARD ALL</literal></term>
+ <listitem>
+ <para>
+ Fetch all remaining rows.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BACKWARD</literal></term>
+ <listitem>
+ <para>
+ Fetch the prior row (same as <literal>PRIOR</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BACKWARD <replaceable class="parameter">count</replaceable></literal></term>
+ <listitem>
+ <para>
+ Fetch the prior <replaceable
+ class="parameter">count</replaceable> rows (scanning
+ backwards). <literal>BACKWARD 0</literal> re-fetches the
+ current row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BACKWARD ALL</literal></term>
+ <listitem>
+ <para>
+ Fetch all prior rows (scanning backwards).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">count</replaceable></term>
+ <listitem>
+ <para><replaceable class="parameter">count</replaceable> is a
+ possibly-signed integer constant, determining the location or
+ number of rows to fetch. For <literal>FORWARD</literal> and
+ <literal>BACKWARD</literal> cases, specifying a negative <replaceable
+ class="parameter">count</replaceable> is equivalent to changing
+ the sense of <literal>FORWARD</literal> and <literal>BACKWARD</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cursor_name</replaceable></term>
+ <listitem>
+ <para>
+ An open cursor's name.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, a <command>FETCH</command> command returns a command
+ tag of the form
+<screen>
+FETCH <replaceable class="parameter">count</replaceable>
+</screen>
+ The <replaceable class="parameter">count</replaceable> is the number
+ of rows fetched (possibly zero). Note that in
+ <application>psql</application>, the command tag will not actually be
+ displayed, since <application>psql</application> displays the fetched
+ rows instead.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The cursor should be declared with the <literal>SCROLL</literal>
+ option if one intends to use any variants of <command>FETCH</command>
+ other than <command>FETCH NEXT</command> or <command>FETCH FORWARD</command> with
+ a positive count. For simple queries
+ <productname>PostgreSQL</productname> will allow backwards fetch
+ from cursors not declared with <literal>SCROLL</literal>, but this
+ behavior is best not relied on. If the cursor is declared with
+ <literal>NO SCROLL</literal>, no backward fetches are allowed.
+ </para>
+
+ <para>
+ <literal>ABSOLUTE</literal> fetches are not any faster than
+ navigating to the desired row with a relative move: the underlying
+ implementation must traverse all the intermediate rows anyway.
+ Negative absolute fetches are even worse: the query must be read to
+ the end to find the last row, and then traversed backward from
+ there. However, rewinding to the start of the query (as with
+ <literal>FETCH ABSOLUTE 0</literal>) is fast.
+ </para>
+
+ <para>
+ <link linkend="sql-declare"><command>DECLARE</command></link>
+ is used to define a cursor. Use
+ <link linkend="sql-move"><command>MOVE</command></link>
+ to change cursor position without retrieving data.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example traverses a table using a cursor:
+
+<programlisting>
+BEGIN WORK;
+
+-- Set up a cursor:
+DECLARE liahona SCROLL CURSOR FOR SELECT * FROM films;
+
+-- Fetch the first 5 rows in the cursor liahona:
+FETCH FORWARD 5 FROM liahona;
+
+ code | title | did | date_prod | kind | len
+-------+-------------------------+-----+------------+----------+-------
+ BL101 | The Third Man | 101 | 1949-12-23 | Drama | 01:44
+ BL102 | The African Queen | 101 | 1951-08-11 | Romantic | 01:43
+ JL201 | Une Femme est une Femme | 102 | 1961-03-12 | Romantic | 01:25
+ P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
+ P_302 | Becket | 103 | 1964-02-03 | Drama | 02:28
+
+-- Fetch the previous row:
+FETCH PRIOR FROM liahona;
+
+ code | title | did | date_prod | kind | len
+-------+---------+-----+------------+--------+-------
+ P_301 | Vertigo | 103 | 1958-11-14 | Action | 02:08
+
+-- Close the cursor and end the transaction:
+CLOSE liahona;
+COMMIT WORK;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard defines <command>FETCH</command> for use in
+ embedded SQL only. The variant of <command>FETCH</command>
+ described here returns the data as if it were a
+ <command>SELECT</command> result rather than placing it in host
+ variables. Other than this point, <command>FETCH</command> is
+ fully upward-compatible with the SQL standard.
+ </para>
+
+ <para>
+ The <command>FETCH</command> forms involving
+ <literal>FORWARD</literal> and <literal>BACKWARD</literal>, as well
+ as the forms <literal>FETCH <replaceable
+ class="parameter">count</replaceable></literal> and <literal>FETCH
+ ALL</literal>, in which <literal>FORWARD</literal> is implicit, are
+ <productname>PostgreSQL</productname> extensions.
+ </para>
+
+ <para>
+ The SQL standard allows only <literal>FROM</literal> preceding the cursor
+ name; the option to use <literal>IN</literal>, or to leave them out altogether, is
+ an extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-close"/></member>
+ <member><xref linkend="sql-declare"/></member>
+ <member><xref linkend="sql-move"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml
new file mode 100644
index 0000000..f744b05
--- /dev/null
+++ b/doc/src/sgml/ref/grant.sgml
@@ -0,0 +1,479 @@
+<!--
+doc/src/sgml/ref/grant.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-grant">
+ <indexterm zone="sql-grant">
+ <primary>GRANT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>GRANT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>GRANT</refname>
+ <refpurpose>define access privileges</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
+ | ALL TABLES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="parameter">column_name</replaceable> [, ...] )
+ [, ...] | ALL [ PRIVILEGES ] ( <replaceable class="parameter">column_name</replaceable> [, ...] ) }
+ ON [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { SEQUENCE <replaceable class="parameter">sequence_name</replaceable> [, ...]
+ | ALL SEQUENCES IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
+ ON DATABASE <replaceable>database_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON DOMAIN <replaceable>domain_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { { FUNCTION | PROCEDURE | ROUTINE } <replaceable>routine_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) ] [, ...]
+ | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <replaceable class="parameter">schema_name</replaceable> [, ...] }
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON LANGUAGE <replaceable>lang_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
+ ON LARGE OBJECT <replaceable class="parameter">loid</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { { SET | ALTER SYSTEM } [, ... ] | ALL [ PRIVILEGES ] }
+ ON PARAMETER <replaceable class="parameter">configuration_parameter</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
+ ON SCHEMA <replaceable>schema_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { CREATE | ALL [ PRIVILEGES ] }
+ ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPE <replaceable>type_name</replaceable> [, ...]
+ TO <replaceable class="parameter">role_specification</replaceable> [, ...] [ WITH GRANT OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+GRANT <replaceable class="parameter">role_name</replaceable> [, ...] TO <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ WITH ADMIN OPTION ]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+
+<phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase>
+
+ [ GROUP ] <replaceable class="parameter">role_name</replaceable>
+ | PUBLIC
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-grant-description">
+ <title>Description</title>
+
+ <para>
+ The <command>GRANT</command> command has two basic variants: one
+ that grants privileges on a database object (table, column, view,
+ foreign table, sequence, database, foreign-data wrapper, foreign server,
+ function, procedure, procedural language, large object, configuration
+ parameter, schema, tablespace, or type), and one that grants
+ membership in a role. These variants are similar in many ways, but
+ they are different enough to be described separately.
+ </para>
+
+ <refsect2 id="sql-grant-description-objects">
+ <title>GRANT on Database Objects</title>
+
+ <para>
+ This variant of the <command>GRANT</command> command gives specific
+ privileges on a database object to
+ one or more roles. These privileges are added
+ to those already granted, if any.
+ </para>
+
+ <para>
+ The key word <literal>PUBLIC</literal> indicates that the
+ privileges are to be granted to all roles, including those that might
+ be created later. <literal>PUBLIC</literal> can be thought of as an
+ implicitly defined group that always includes all roles.
+ Any particular role will have the sum
+ of privileges granted directly to it, privileges granted to any role it
+ is presently a member of, and privileges granted to
+ <literal>PUBLIC</literal>.
+ </para>
+
+ <para>
+ If <literal>WITH GRANT OPTION</literal> is specified, the recipient
+ of the privilege can in turn grant it to others. Without a grant
+ option, the recipient cannot do that. Grant options cannot be granted
+ to <literal>PUBLIC</literal>.
+ </para>
+
+ <para>
+ If <literal>GRANTED BY</literal> is specified, the specified grantor must
+ be the current user. This clause is currently present in this form only
+ for SQL compatibility.
+ </para>
+
+ <para>
+ There is no need to grant privileges to the owner of an object
+ (usually the user that created it),
+ as the owner has all privileges by default. (The owner could,
+ however, choose to revoke some of their own privileges for safety.)
+ </para>
+
+ <para>
+ The right to drop an object, or to alter its definition in any way, is
+ not treated as a grantable privilege; it is inherent in the owner,
+ and cannot be granted or revoked. (However, a similar effect can be
+ obtained by granting or revoking membership in the role that owns
+ the object; see below.) The owner implicitly has all grant
+ options for the object, too.
+ </para>
+
+ <para>
+ The possible privileges are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SELECT</literal></term>
+ <term><literal>INSERT</literal></term>
+ <term><literal>UPDATE</literal></term>
+ <term><literal>DELETE</literal></term>
+ <term><literal>TRUNCATE</literal></term>
+ <term><literal>REFERENCES</literal></term>
+ <term><literal>TRIGGER</literal></term>
+ <term><literal>CREATE</literal></term>
+ <term><literal>CONNECT</literal></term>
+ <term><literal>TEMPORARY</literal></term>
+ <term><literal>EXECUTE</literal></term>
+ <term><literal>USAGE</literal></term>
+ <term><literal>SET</literal></term>
+ <term><literal>ALTER SYSTEM</literal></term>
+ <listitem>
+ <para>
+ Specific types of privileges, as defined in <xref linkend="ddl-priv"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ Alternative spelling for <literal>TEMPORARY</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL PRIVILEGES</literal></term>
+ <listitem>
+ <para>
+ Grant all of the privileges available for the object's type.
+ The <literal>PRIVILEGES</literal> key word is optional in
+ <productname>PostgreSQL</productname>, though it is required by
+ strict SQL.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <literal>FUNCTION</literal> syntax works for plain functions,
+ aggregate functions, and window functions, but not for procedures;
+ use <literal>PROCEDURE</literal> for those.
+ Alternatively, use <literal>ROUTINE</literal> to refer to a function,
+ aggregate function, window function, or procedure regardless of its
+ precise type.
+ </para>
+
+ <para>
+ There is also an option to grant privileges on all objects of the same
+ type within one or more schemas. This functionality is currently supported
+ only for tables, sequences, functions, and procedures. <literal>ALL
+ TABLES</literal> also affects views and foreign tables, just like the
+ specific-object <command>GRANT</command> command. <literal>ALL
+ FUNCTIONS</literal> also affects aggregate and window functions, but not
+ procedures, again just like the specific-object <command>GRANT</command>
+ command. Use <literal>ALL ROUTINES</literal> to include procedures.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-grant-description-roles">
+ <title>GRANT on Roles</title>
+
+ <para>
+ This variant of the <command>GRANT</command> command grants membership
+ in a role to one or more other roles. Membership in a role is significant
+ because it conveys the privileges granted to a role to each of its
+ members.
+ </para>
+
+ <para>
+ If <literal>WITH ADMIN OPTION</literal> is specified, the member can
+ in turn grant membership in the role to others, and revoke membership
+ in the role as well. Without the admin option, ordinary users cannot
+ do that. A role is not considered to hold <literal>WITH ADMIN
+ OPTION</literal> on itself. Database superusers can grant or revoke
+ membership in any role to anyone. Roles having
+ <literal>CREATEROLE</literal> privilege can grant or revoke membership
+ in any role that is not a superuser.
+ </para>
+
+ <para>
+ If <literal>GRANTED BY</literal> is specified, the grant is recorded as
+ having been done by the specified role. Only database superusers may
+ use this option, except when it names the same role executing the command.
+ </para>
+
+ <para>
+ Unlike the case with privileges, membership in a role cannot be granted
+ to <literal>PUBLIC</literal>. Note also that this form of the command
+ does not allow the noise word <literal>GROUP</literal>
+ in <replaceable class="parameter">role_specification</replaceable>.
+ </para>
+ </refsect2>
+ </refsect1>
+
+
+ <refsect1 id="sql-grant-notes">
+ <title>Notes</title>
+
+ <para>
+ The <link linkend="sql-revoke"><command>REVOKE</command></link> command is used
+ to revoke access privileges.
+ </para>
+
+ <para>
+ Since <productname>PostgreSQL</productname> 8.1, the concepts of users and
+ groups have been unified into a single kind of entity called a role.
+ It is therefore no longer necessary to use the keyword <literal>GROUP</literal>
+ to identify whether a grantee is a user or a group. <literal>GROUP</literal>
+ is still allowed in the command, but it is a noise word.
+ </para>
+
+ <para>
+ A user may perform <command>SELECT</command>, <command>INSERT</command>, etc. on a
+ column if they hold that privilege for either the specific column or
+ its whole table. Granting the privilege at the table level and then
+ revoking it for one column will not do what one might wish: the
+ table-level grant is unaffected by a column-level operation.
+ </para>
+
+ <para>
+ When a non-owner of an object attempts to <command>GRANT</command> privileges
+ on the object, the command will fail outright if the user has no
+ privileges whatsoever on the object. As long as some privilege is
+ available, the command will proceed, but it will grant only those
+ privileges for which the user has grant options. The <command>GRANT ALL
+ PRIVILEGES</command> forms will issue a warning message if no grant options are
+ held, while the other forms will issue a warning if grant options for
+ any of the privileges specifically named in the command are not held.
+ (In principle these statements apply to the object owner as well, but
+ since the owner is always treated as holding all grant options, the
+ cases can never occur.)
+ </para>
+
+ <para>
+ It should be noted that database superusers can access
+ all objects regardless of object privilege settings. This
+ is comparable to the rights of <literal>root</literal> in a Unix system.
+ As with <literal>root</literal>, it's unwise to operate as a superuser
+ except when absolutely necessary.
+ </para>
+
+ <para>
+ If a superuser chooses to issue a <command>GRANT</command> or <command>REVOKE</command>
+ command, the command is performed as though it were issued by the
+ owner of the affected object. In particular, privileges granted via
+ such a command will appear to have been granted by the object owner.
+ (For role membership, the membership appears to have been granted
+ by the containing role itself.)
+ </para>
+
+ <para>
+ <command>GRANT</command> and <command>REVOKE</command> can also be done by a role
+ that is not the owner of the affected object, but is a member of the role
+ that owns the object, or is a member of a role that holds privileges
+ <literal>WITH GRANT OPTION</literal> on the object. In this case the
+ privileges will be recorded as having been granted by the role that
+ actually owns the object or holds the privileges
+ <literal>WITH GRANT OPTION</literal>. For example, if table
+ <literal>t1</literal> is owned by role <literal>g1</literal>, of which role
+ <literal>u1</literal> is a member, then <literal>u1</literal> can grant privileges
+ on <literal>t1</literal> to <literal>u2</literal>, but those privileges will appear
+ to have been granted directly by <literal>g1</literal>. Any other member
+ of role <literal>g1</literal> could revoke them later.
+ </para>
+
+ <para>
+ If the role executing <command>GRANT</command> holds the required privileges
+ indirectly via more than one role membership path, it is unspecified
+ which containing role will be recorded as having done the grant. In such
+ cases it is best practice to use <command>SET ROLE</command> to become the
+ specific role you want to do the <command>GRANT</command> as.
+ </para>
+
+ <para>
+ Granting permission on a table does not automatically extend
+ permissions to any sequences used by the table, including
+ sequences tied to <type>SERIAL</type> columns. Permissions on
+ sequences must be set separately.
+ </para>
+
+ <para>
+ See <xref linkend="ddl-priv"/> for more information about specific
+ privilege types, as well as how to inspect objects' privileges.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-grant-examples">
+ <title>Examples</title>
+
+ <para>
+ Grant insert privilege to all users on table <literal>films</literal>:
+
+<programlisting>
+GRANT INSERT ON films TO PUBLIC;
+</programlisting>
+ </para>
+
+ <para>
+ Grant all available privileges to user <literal>manuel</literal> on view
+ <literal>kinds</literal>:
+
+<programlisting>
+GRANT ALL PRIVILEGES ON kinds TO manuel;
+</programlisting>
+
+ Note that while the above will indeed grant all privileges if executed by a
+ superuser or the owner of <literal>kinds</literal>, when executed by someone
+ else it will only grant those permissions for which the someone else has
+ grant options.
+ </para>
+
+ <para>
+ Grant membership in role <literal>admins</literal> to user <literal>joe</literal>:
+
+<programlisting>
+GRANT admins TO joe;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-grant-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ According to the SQL standard, the <literal>PRIVILEGES</literal>
+ key word in <literal>ALL PRIVILEGES</literal> is required. The
+ SQL standard does not support setting the privileges on more than
+ one object per command.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> allows an object owner to revoke their
+ own ordinary privileges: for example, a table owner can make the table
+ read-only to themselves by revoking their own <literal>INSERT</literal>,
+ <literal>UPDATE</literal>, <literal>DELETE</literal>, and <literal>TRUNCATE</literal>
+ privileges. This is not possible according to the SQL standard. The
+ reason is that <productname>PostgreSQL</productname> treats the owner's
+ privileges as having been granted by the owner to themselves; therefore they
+ can revoke them too. In the SQL standard, the owner's privileges are
+ granted by an assumed entity <quote>_SYSTEM</quote>. Not being
+ <quote>_SYSTEM</quote>, the owner cannot revoke these rights.
+ </para>
+
+ <para>
+ According to the SQL standard, grant options can be granted to
+ <literal>PUBLIC</literal>; PostgreSQL only supports granting grant options
+ to roles.
+ </para>
+
+ <para>
+ The SQL standard allows the <literal>GRANTED BY</literal> option to
+ specify only <literal>CURRENT_USER</literal> or
+ <literal>CURRENT_ROLE</literal>. The other variants are PostgreSQL
+ extensions.
+ </para>
+
+ <para>
+ The SQL standard provides for a <literal>USAGE</literal> privilege
+ on other kinds of objects: character sets, collations,
+ translations.
+ </para>
+
+ <para>
+ In the SQL standard, sequences only have a <literal>USAGE</literal>
+ privilege, which controls the use of the <literal>NEXT VALUE FOR</literal>
+ expression, which is equivalent to the
+ function <function>nextval</function> in PostgreSQL. The sequence
+ privileges <literal>SELECT</literal> and <literal>UPDATE</literal> are
+ PostgreSQL extensions. The application of the
+ sequence <literal>USAGE</literal> privilege to
+ the <literal>currval</literal> function is also a PostgreSQL extension (as
+ is the function itself).
+ </para>
+
+ <para>
+ Privileges on databases, tablespaces, schemas, languages, and
+ configuration parameters are
+ <productname>PostgreSQL</productname> extensions.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-revoke"/></member>
+ <member><xref linkend="sql-alterdefaultprivileges"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/import_foreign_schema.sgml b/doc/src/sgml/ref/import_foreign_schema.sgml
new file mode 100644
index 0000000..f07f757
--- /dev/null
+++ b/doc/src/sgml/ref/import_foreign_schema.sgml
@@ -0,0 +1,166 @@
+<!--
+doc/src/sgml/ref/import_foreign_schema.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-importforeignschema">
+ <indexterm zone="sql-importforeignschema">
+ <primary>IMPORT FOREIGN SCHEMA</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>IMPORT FOREIGN SCHEMA</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>IMPORT FOREIGN SCHEMA</refname>
+ <refpurpose>import table definitions from a foreign server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+IMPORT FOREIGN SCHEMA <replaceable class="parameter">remote_schema</replaceable>
+ [ { LIMIT TO | EXCEPT } ( <replaceable class="parameter">table_name</replaceable> [, ...] ) ]
+ FROM SERVER <replaceable class="parameter">server_name</replaceable>
+ INTO <replaceable class="parameter">local_schema</replaceable>
+ [ OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ... ] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-importforeignschema-description">
+ <title>Description</title>
+
+ <para>
+ <command>IMPORT FOREIGN SCHEMA</command> creates foreign tables that
+ represent tables existing on a foreign server. The new foreign tables
+ will be owned by the user issuing the command and are created with
+ the correct column definitions and options to match the remote tables.
+ </para>
+
+ <para>
+ By default, all tables and views existing in a particular schema on the
+ foreign server are imported. Optionally, the list of tables can be limited
+ to a specified subset, or specific tables can be excluded. The new foreign
+ tables are all created in the target schema, which must already exist.
+ </para>
+
+ <para>
+ To use <command>IMPORT FOREIGN SCHEMA</command>, the user must have
+ <literal>USAGE</literal> privilege on the foreign server, as well as
+ <literal>CREATE</literal> privilege on the target schema.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">remote_schema</replaceable></term>
+ <listitem>
+ <para>
+ The remote schema to import from. The specific meaning of a remote schema
+ depends on the foreign data wrapper in use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LIMIT TO ( <replaceable class="parameter">table_name</replaceable> [, ...] )</literal></term>
+ <listitem>
+ <para>
+ Import only foreign tables matching one of the given table names.
+ Other tables existing in the foreign schema will be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>EXCEPT ( <replaceable class="parameter">table_name</replaceable> [, ...] )</literal></term>
+ <listitem>
+ <para>
+ Exclude specified foreign tables from the import. All tables
+ existing in the foreign schema will be imported except the
+ ones listed here.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">server_name</replaceable></term>
+ <listitem>
+ <para>
+ The foreign server to import from.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">local_schema</replaceable></term>
+ <listitem>
+ <para>
+ The schema in which the imported foreign tables will be created.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OPTIONS ( <replaceable class="parameter">option</replaceable> '<replaceable class="parameter">value</replaceable>' [, ...] )</literal></term>
+ <listitem>
+ <para>
+ Options to be used during the import.
+ The allowed option names and values are specific to each foreign
+ data wrapper.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-importforeignschema-examples">
+ <title>Examples</title>
+
+ <para>
+ Import table definitions from a remote schema <structname>foreign_films</structname>
+ on server <structname>film_server</structname>, creating the foreign tables in
+ local schema <structname>films</structname>:
+
+<programlisting>
+IMPORT FOREIGN SCHEMA foreign_films
+ FROM SERVER film_server INTO films;
+</programlisting>
+ </para>
+
+ <para>
+ As above, but import only the two tables <structname>actors</structname> and
+ <literal>directors</literal> (if they exist):
+
+<programlisting>
+IMPORT FOREIGN SCHEMA foreign_films LIMIT TO (actors, directors)
+ FROM SERVER film_server INTO films;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-importforeignschema-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The <command>IMPORT FOREIGN SCHEMA</command> command conforms to the
+ <acronym>SQL</acronym> standard, except that the <literal>OPTIONS</literal>
+ clause is a <productname>PostgreSQL</productname> extension.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createforeigntable"/></member>
+ <member><xref linkend="sql-createserver"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
new file mode 100644
index 0000000..8158896
--- /dev/null
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -0,0 +1,588 @@
+<!--
+doc/src/sgml/ref/initdb.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-initdb">
+ <indexterm zone="app-initdb">
+ <primary>initdb</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>initdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>initdb</refname>
+ <refpurpose>create a new <productname>PostgreSQL</productname> database cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>initdb</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <group choice="plain">
+ <group choice="opt">
+ <arg choice="plain"><option>--pgdata</option></arg>
+ <arg choice="plain"><option>-D</option></arg>
+ </group>
+ <replaceable> directory</replaceable>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="r1-app-initdb-1">
+ <title>Description</title>
+ <para>
+ <command>initdb</command> creates a new
+ <productname>PostgreSQL</productname> database cluster. A database
+ cluster is a collection of databases that are managed by a single
+ server instance.
+ </para>
+
+ <para>
+ Creating a database cluster consists of creating the directories in
+ which the database data will live, generating the shared catalog
+ tables (tables that belong to the whole cluster rather than to any
+ particular database), and creating the <literal>postgres</literal>,
+ <literal>template1</literal>, and <literal>template0</literal> databases.
+ The <literal>postgres</literal> database is a default database meant
+ for use by users, utilities and third party applications.
+ <literal>template1</literal> and <literal>template0</literal> are
+ meant as source databases to be copied by later <command>CREATE
+ DATABASE</command> commands. <literal>template0</literal> should never
+ be modified, but you can add objects to <literal>template1</literal>,
+ which by default will be copied into databases created later. See
+ <xref linkend="manage-ag-templatedbs"/> for more details.
+ </para>
+
+ <para>
+ Although <command>initdb</command> will attempt to create the
+ specified data directory, it might not have permission if the parent
+ directory of the desired data directory is root-owned. To initialize
+ in such a setup, create an empty data directory as root, then use
+ <command>chown</command> to assign ownership of that directory to the
+ database user account, then <command>su</command> to become the
+ database user to run <command>initdb</command>.
+ </para>
+
+ <para>
+ <command>initdb</command> must be run as the user that will own the
+ server process, because the server needs to have access to the
+ files and directories that <command>initdb</command> creates.
+ Since the server cannot be run as root, you must not run
+ <command>initdb</command> as root either. (It will in fact refuse
+ to do so.)
+ </para>
+
+ <para>
+ For security reasons the new cluster created by <command>initdb</command>
+ will only be accessible by the cluster owner by default. The
+ <option>--allow-group-access</option> option allows any user in the same
+ group as the cluster owner to read files in the cluster. This is useful
+ for performing backups as a non-privileged user.
+ </para>
+
+ <para>
+ <command>initdb</command> initializes the database cluster's default locale
+ and character set encoding. These can also be set separately for each
+ database when it is created. <command>initdb</command> determines those
+ settings for the template databases, which will serve as the default for
+ all other databases. By default, <command>initdb</command> uses the
+ locale provider <literal>libc</literal>, takes the locale settings from
+ the environment, and determines the encoding from the locale settings.
+ This is almost always sufficient, unless there are special requirements.
+ </para>
+
+ <para>
+ To choose a different locale for the cluster, use the option
+ <option>--locale</option>. There are also individual options
+ <option>--lc-*</option> (see below) to set values for the individual locale
+ categories. Note that inconsistent settings for different locale
+ categories can give nonsensical results, so this should be used with care.
+ </para>
+
+ <para>
+ Alternatively, the ICU library can be used to provide locale services.
+ (Again, this only sets the default for subsequently created databases.) To
+ select this option, specify <literal>--locale-provider=icu</literal>.
+ To choose the specific ICU locale ID to apply, use the option
+ <option>--icu-locale</option>. Note that
+ for implementation reasons and to support legacy code,
+ <command>initdb</command> will still select and initialize libc locale
+ settings when the ICU locale provider is used.
+ </para>
+
+ <para>
+ When <command>initdb</command> runs, it will print out the locale settings
+ it has chosen. If you have complex requirements or specified multiple
+ options, it is advisable to check that the result matches what was
+ intended.
+ </para>
+
+ <para>
+ More details about locale settings can be found in <xref
+ linkend="locale"/>.
+ </para>
+
+ <para>
+ To alter the default encoding, use the <option>--encoding</option>.
+ More details can be found in <xref linkend="multibyte"/>.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term><option>-A <replaceable class="parameter">authmethod</replaceable></option></term>
+ <term><option>--auth=<replaceable class="parameter">authmethod</replaceable></option></term>
+ <listitem>
+ <para>
+ This option specifies the default authentication method for local
+ users used in <filename>pg_hba.conf</filename> (<literal>host</literal>
+ and <literal>local</literal> lines). See <xref linkend="auth-pg-hba-conf"/>
+ for an overview of valid values.
+ </para>
+
+ <para>
+ <command>initdb</command> will
+ prepopulate <filename>pg_hba.conf</filename> entries using the
+ specified authentication method for non-replication as well as
+ replication connections.
+ </para>
+
+ <para>
+ Do not use <literal>trust</literal> unless you trust all local users on your
+ system. <literal>trust</literal> is the default for ease of installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--auth-host=<replaceable class="parameter">authmethod</replaceable></option></term>
+ <listitem>
+ <para>
+ This option specifies the authentication method for local users via
+ TCP/IP connections used in <filename>pg_hba.conf</filename>
+ (<literal>host</literal> lines).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--auth-local=<replaceable class="parameter">authmethod</replaceable></option></term>
+ <listitem>
+ <para>
+ This option specifies the authentication method for local users via
+ Unix-domain socket connections used in <filename>pg_hba.conf</filename>
+ (<literal>local</literal> lines).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">directory</replaceable></option></term>
+ <term><option>--pgdata=<replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ This option specifies the directory where the database cluster
+ should be stored. This is the only information required by
+ <command>initdb</command>, but you can avoid writing it by
+ setting the <envar>PGDATA</envar> environment variable, which
+ can be convenient since the database server
+ (<command>postgres</command>) can find the database
+ directory later by the same variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E <replaceable class="parameter">encoding</replaceable></option></term>
+ <term><option>--encoding=<replaceable class="parameter">encoding</replaceable></option></term>
+ <listitem>
+ <para>
+ Selects the encoding of the template databases. This will also
+ be the default encoding of any database you create later,
+ unless you override it then. The default is derived from the locale,
+ if the libc locale provider is used, or <literal>UTF8</literal> if the
+ ICU locale provider is used. The character sets supported by
+ the <productname>PostgreSQL</productname> server are described
+ in <xref linkend="multibyte-charset-supported"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="app-initdb-allow-group-access" xreflabel="group access">
+ <term><option>-g</option></term>
+ <term><option>--allow-group-access</option></term>
+ <listitem>
+ <para>
+ Allows users in the same group as the cluster owner to read all cluster
+ files created by <command>initdb</command>. This option is ignored
+ on <productname>Windows</productname> as it does not support
+ <acronym>POSIX</acronym>-style group permissions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--icu-locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the ICU locale ID, if the ICU locale provider is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="app-initdb-data-checksums" xreflabel="data checksums">
+ <term><option>-k</option></term>
+ <term><option>--data-checksums</option></term>
+ <listitem>
+ <para>
+ Use checksums on data pages to help detect corruption by the
+ I/O system that would otherwise be silent. Enabling checksums
+ may incur a noticeable performance penalty. If set, checksums
+ are calculated for all objects, in all databases. All checksum
+ failures will be reported in the
+ <link linkend="monitoring-pg-stat-database-view">
+ <structname>pg_stat_database</structname></link> view.
+ See <xref linkend="checksums" /> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--locale=<replaceable>locale</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the default locale for the database cluster. If this
+ option is not specified, the locale is inherited from the
+ environment that <command>initdb</command> runs in. Locale
+ support is described in <xref linkend="locale"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--lc-collate=<replaceable>locale</replaceable></option></term>
+ <term><option>--lc-ctype=<replaceable>locale</replaceable></option></term>
+ <term><option>--lc-messages=<replaceable>locale</replaceable></option></term>
+ <term><option>--lc-monetary=<replaceable>locale</replaceable></option></term>
+ <term><option>--lc-numeric=<replaceable>locale</replaceable></option></term>
+ <term><option>--lc-time=<replaceable>locale</replaceable></option></term>
+
+ <listitem>
+ <para>
+ Like <option>--locale</option>, but only sets the locale in
+ the specified category.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-locale</option></term>
+ <listitem>
+ <para>
+ Equivalent to <option>--locale=C</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--locale-provider={<literal>libc</literal>|<literal>icu</literal>}</option></term>
+ <listitem>
+ <para>
+ This option sets the locale provider for databases created in the
+ new cluster. It can be overridden in the <command>CREATE
+ DATABASE</command> command when new databases are subsequently
+ created. The default is <literal>libc</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>initdb</command> will wait for all files to be
+ written safely to disk. This option causes <command>initdb</command>
+ to return without waiting, which is faster, but means that a
+ subsequent operating system crash can leave the data directory
+ corrupt. Generally, this option is useful for testing, but should not
+ be used when creating a production installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-instructions</option></term>
+ <listitem>
+ <para>
+ By default, <command>initdb</command> will write instructions for how
+ to start the cluster at the end of its output. This option causes
+ those instructions to be left out. This is primarily intended for use
+ by tools that wrap <command>initdb</command> in platform-specific
+ behavior, where those instructions are likely to be incorrect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--pwfile=<replaceable>filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Makes <command>initdb</command> read the database superuser's password
+ from a file. The first line of the file is taken as the password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S</option></term>
+ <term><option>--sync-only</option></term>
+ <listitem>
+ <para>
+ Safely write all database files to disk and exit. This does not
+ perform any of the normal <application>initdb</application> operations.
+ Generally, this option is useful for ensuring reliable recovery after
+ changing <xref linkend="guc-fsync"/> from <literal>off</literal> to
+ <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable>config</replaceable></option></term>
+ <term><option>--text-search-config=<replaceable>config</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the default text search configuration.
+ See <xref linkend="guc-default-text-search-config"/> for further information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Selects the user name of the database superuser. This defaults
+ to the name of the effective user running
+ <command>initdb</command>. It is really not important what the
+ superuser's name is, but one might choose to keep the
+ customary name <systemitem>postgres</systemitem>, even if the operating
+ system user's name is different.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--pwprompt</option></term>
+ <listitem>
+ <para>
+ Makes <command>initdb</command> prompt for a password
+ to give the database superuser. If you don't plan on using password
+ authentication, this is not important. Otherwise you won't be
+ able to use password authentication until you have a password
+ set up.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-X <replaceable class="parameter">directory</replaceable></option></term>
+ <term><option>--waldir=<replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ This option specifies the directory where the write-ahead log
+ should be stored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--wal-segsize=<replaceable>size</replaceable></option></term>
+ <listitem>
+ <para>
+ Set the <firstterm>WAL segment size</firstterm>, in megabytes. This
+ is the size of each individual file in the WAL log. The default size
+ is 16 megabytes. The value must be a power of 2 between 1 and 1024
+ (megabytes). This option can only be set during initialization, and
+ cannot be changed later.
+ </para>
+
+ <para>
+ It may be useful to adjust this size to control the granularity of
+ WAL log shipping or archiving. Also, in databases with a high volume
+ of WAL, the sheer number of WAL files per directory can become a
+ performance and management problem. Increasing the WAL file size
+ will reduce the number of WAL files.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Other, less commonly used, options are also available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d</option></term>
+ <term><option>--debug</option></term>
+ <listitem>
+ <para>
+ Print debugging output from the bootstrap backend and a few other
+ messages of lesser interest for the general public.
+ The bootstrap backend is the program <command>initdb</command>
+ uses to create the catalog tables. This option generates a tremendous
+ amount of extremely boring output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--discard-caches</option></term>
+ <listitem>
+ <para>
+ Run the bootstrap backend with the
+ <literal>debug_discard_caches=1</literal> option.
+ This takes a very long time and is only of use for deep debugging.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-L <replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies where <command>initdb</command> should find
+ its input files to initialize the database cluster. This is
+ normally not necessary. You will be told if you need to
+ specify their location explicitly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-clean</option></term>
+ <listitem>
+ <para>
+ By default, when <command>initdb</command>
+ determines that an error prevented it from completely creating the database
+ cluster, it removes any files it might have created before discovering
+ that it cannot finish the job. This option inhibits tidying-up and is
+ thus useful for debugging.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Other options:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>initdb</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>initdb</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATA</envar></term>
+
+ <listitem>
+ <para>
+ Specifies the directory where the database cluster is to be
+ stored; can be overridden using the <option>-D</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>TZ</envar></term>
+
+ <listitem>
+ <para>
+ Specifies the default time zone of the created database cluster. The
+ value should be a full time zone name
+ (see <xref linkend="datatype-timezones"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>initdb</command> can also be invoked via
+ <command>pg_ctl initdb</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pg-ctl"/></member>
+ <member><xref linkend="app-postgres"/></member>
+ <member><xref linkend="auth-pg-hba-conf"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/insert.sgml b/doc/src/sgml/ref/insert.sgml
new file mode 100644
index 0000000..7cea703
--- /dev/null
+++ b/doc/src/sgml/ref/insert.sgml
@@ -0,0 +1,792 @@
+<!--
+doc/src/sgml/ref/insert.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-insert">
+ <indexterm zone="sql-insert">
+ <primary>INSERT</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>INSERT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>INSERT</refname>
+ <refpurpose>create new rows in a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
+INSERT INTO <replaceable class="parameter">table_name</replaceable> [ AS <replaceable class="parameter">alias</replaceable> ] [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+ [ OVERRIDING { SYSTEM | USER } VALUE ]
+ { DEFAULT VALUES | VALUES ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) [, ...] | <replaceable class="parameter">query</replaceable> }
+ [ ON CONFLICT [ <replaceable class="parameter">conflict_target</replaceable> ] <replaceable class="parameter">conflict_action</replaceable> ]
+ [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
+
+<phrase>where <replaceable class="parameter">conflict_target</replaceable> can be one of:</phrase>
+
+ ( { <replaceable class="parameter">index_column_name</replaceable> | ( <replaceable class="parameter">index_expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ...] ) [ WHERE <replaceable class="parameter">index_predicate</replaceable> ]
+ ON CONSTRAINT <replaceable class="parameter">constraint_name</replaceable>
+
+<phrase>and <replaceable class="parameter">conflict_action</replaceable> is one of:</phrase>
+
+ DO NOTHING
+ DO UPDATE SET { <replaceable class="parameter">column_name</replaceable> = { <replaceable class="parameter">expression</replaceable> | DEFAULT } |
+ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) = [ ROW ] ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) |
+ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) = ( <replaceable class="parameter">sub-SELECT</replaceable> )
+ } [, ...]
+ [ WHERE <replaceable class="parameter">condition</replaceable> ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>INSERT</command> inserts new rows into a table.
+ One can insert one or more rows specified by value expressions,
+ or zero or more rows resulting from a query.
+ </para>
+
+ <para>
+ The target column names can be listed in any order. If no list of
+ column names is given at all, the default is all the columns of the
+ table in their declared order; or the first <replaceable>N</replaceable> column
+ names, if there are only <replaceable>N</replaceable> columns supplied by the
+ <literal>VALUES</literal> clause or <replaceable>query</replaceable>. The values
+ supplied by the <literal>VALUES</literal> clause or <replaceable>query</replaceable> are
+ associated with the explicit or implicit column list left-to-right.
+ </para>
+
+ <para>
+ Each column not present in the explicit or implicit column list will be
+ filled with a default value, either its declared default value
+ or null if there is none.
+ </para>
+
+ <para>
+ If the expression for any column is not of the correct data type,
+ automatic type conversion will be attempted.
+ </para>
+
+ <para>
+ <command>INSERT</command> into tables that lack unique indexes will
+ not be blocked by concurrent activity. Tables with unique indexes
+ might block if concurrent sessions perform actions that lock or modify
+ rows matching the unique index values being inserted; the details
+ are covered in <xref linkend="index-unique-checks"/>.
+ <literal>ON CONFLICT</literal> can be used to specify an alternative
+ action to raising a unique constraint or exclusion constraint
+ violation error. (See <xref linkend="sql-on-conflict"/> below.)
+ </para>
+
+ <para>
+ The optional <literal>RETURNING</literal> clause causes <command>INSERT</command>
+ to compute and return value(s) based on each row actually inserted
+ (or updated, if an <literal>ON CONFLICT DO UPDATE</literal> clause was
+ used). This is primarily useful for obtaining values that were
+ supplied by defaults, such as a serial sequence number. However,
+ any expression using the table's columns is allowed. The syntax of
+ the <literal>RETURNING</literal> list is identical to that of the output
+ list of <command>SELECT</command>. Only rows that were successfully
+ inserted or updated will be returned. For example, if a row was
+ locked but not updated because an <literal>ON CONFLICT DO UPDATE
+ ... WHERE</literal> clause <replaceable
+ class="parameter">condition</replaceable> was not satisfied, the
+ row will not be returned.
+ </para>
+
+ <para>
+ You must have <literal>INSERT</literal> privilege on a table in
+ order to insert into it. If <literal>ON CONFLICT DO UPDATE</literal> is
+ present, <literal>UPDATE</literal> privilege on the table is also
+ required.
+ </para>
+
+ <para>
+ If a column list is specified, you only need
+ <literal>INSERT</literal> privilege on the listed columns.
+ Similarly, when <literal>ON CONFLICT DO UPDATE</literal> is specified, you
+ only need <literal>UPDATE</literal> privilege on the column(s) that are
+ listed to be updated. However, <literal>ON CONFLICT DO UPDATE</literal>
+ also requires <literal>SELECT</literal> privilege on any column whose
+ values are read in the <literal>ON CONFLICT DO UPDATE</literal>
+ expressions or <replaceable>condition</replaceable>.
+ </para>
+
+ <para>
+ Use of the <literal>RETURNING</literal> clause requires <literal>SELECT</literal>
+ privilege on all columns mentioned in <literal>RETURNING</literal>.
+ If you use the <replaceable
+ class="parameter">query</replaceable> clause to insert rows from a
+ query, you of course need to have <literal>SELECT</literal> privilege on
+ any table or column used in the query.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <refsect2>
+ <title>Inserting</title>
+
+ <para>
+ This section covers parameters that may be used when only
+ inserting new rows. Parameters <emphasis>exclusively</emphasis>
+ used with the <literal>ON CONFLICT</literal> clause are described
+ separately.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">with_query</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>WITH</literal> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <command>INSERT</command>
+ query. See <xref linkend="queries-with"/> and <xref linkend="sql-select"/>
+ for details.
+ </para>
+ <para>
+ It is possible for the <replaceable class="parameter">query</replaceable>
+ (<command>SELECT</command> statement)
+ to also contain a <literal>WITH</literal> clause. In such a case both
+ sets of <replaceable>with_query</replaceable> can be referenced within
+ the <replaceable class="parameter">query</replaceable>, but the
+ second one takes precedence since it is more closely nested.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for <replaceable
+ class="parameter">table_name</replaceable>. When an alias is
+ provided, it completely hides the actual name of the table.
+ This is particularly useful when <literal>ON CONFLICT DO UPDATE</literal>
+ targets a table named <varname>excluded</varname>, since that will otherwise
+ be taken as the name of the special table representing the row proposed
+ for insertion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column in the table named by <replaceable
+ class="parameter">table_name</replaceable>. The column name
+ can be qualified with a subfield name or array subscript, if
+ needed. (Inserting into only some fields of a composite
+ column leaves the other fields null.) When referencing a
+ column with <literal>ON CONFLICT DO UPDATE</literal>, do not include
+ the table's name in the specification of a target column. For
+ example, <literal>INSERT INTO table_name ... ON CONFLICT DO UPDATE
+ SET table_name.col = 1</literal> is invalid (this follows the general
+ behavior for <command>UPDATE</command>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OVERRIDING SYSTEM VALUE</literal></term>
+ <listitem>
+ <para>
+ If this clause is specified, then any values supplied for identity
+ columns will override the default sequence-generated values.
+ </para>
+
+ <para>
+ For an identity column defined as <literal>GENERATED ALWAYS</literal>,
+ it is an error to insert an explicit value (other than
+ <literal>DEFAULT</literal>) without specifying either
+ <literal>OVERRIDING SYSTEM VALUE</literal> or <literal>OVERRIDING USER
+ VALUE</literal>. (For an identity column defined as
+ <literal>GENERATED BY DEFAULT</literal>, <literal>OVERRIDING SYSTEM
+ VALUE</literal> is the normal behavior and specifying it does nothing,
+ but <productname>PostgreSQL</productname> allows it as an extension.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OVERRIDING USER VALUE</literal></term>
+ <listitem>
+ <para>
+ If this clause is specified, then any values supplied for identity
+ columns are ignored and the default sequence-generated values are
+ applied.
+ </para>
+
+ <para>
+ This clause is useful for example when copying values between tables.
+ Writing <literal>INSERT INTO tbl2 OVERRIDING USER VALUE SELECT * FROM
+ tbl1</literal> will copy from <literal>tbl1</literal> all columns that
+ are not identity columns in <literal>tbl2</literal> while values for
+ the identity columns in <literal>tbl2</literal> will be generated by
+ the sequences associated with <literal>tbl2</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT VALUES</literal></term>
+ <listitem>
+ <para>
+ All columns will be filled with their default values, as if
+ <literal>DEFAULT</literal> were explicitly specified for each column.
+ (An <literal>OVERRIDING</literal> clause is not permitted in this
+ form.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression or value to assign to the corresponding column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ The corresponding column will be filled with its default value. An
+ identity column will be filled with a new value generated by the
+ associated sequence. For a generated column, specifying this is
+ permitted but merely specifies the normal behavior of computing the
+ column from its generation expression.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">query</replaceable></term>
+ <listitem>
+ <para>
+ A query (<command>SELECT</command> statement) that supplies the
+ rows to be inserted. Refer to the
+ <xref linkend="sql-select"/>
+ statement for a description of the syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression to be computed and returned by the
+ <command>INSERT</command> command after each row is inserted or
+ updated. The expression can use any column names of the table
+ named by <replaceable
+ class="parameter">table_name</replaceable>. Write
+ <literal>*</literal> to return all columns of the inserted or updated
+ row(s).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_name</replaceable></term>
+ <listitem>
+ <para>
+ A name to use for a returned column.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+
+ <refsect2 id="sql-on-conflict" xreflabel="ON CONFLICT Clause">
+ <title><literal>ON CONFLICT</literal> Clause</title>
+ <indexterm zone="sql-insert">
+ <primary>UPSERT</primary>
+ </indexterm>
+ <indexterm zone="sql-insert">
+ <primary>ON CONFLICT</primary>
+ </indexterm>
+ <para>
+ The optional <literal>ON CONFLICT</literal> clause specifies an
+ alternative action to raising a unique violation or exclusion
+ constraint violation error. For each individual row proposed for
+ insertion, either the insertion proceeds, or, if an
+ <emphasis>arbiter</emphasis> constraint or index specified by
+ <parameter>conflict_target</parameter> is violated, the
+ alternative <parameter>conflict_action</parameter> is taken.
+ <literal>ON CONFLICT DO NOTHING</literal> simply avoids inserting
+ a row as its alternative action. <literal>ON CONFLICT DO
+ UPDATE</literal> updates the existing row that conflicts with the
+ row proposed for insertion as its alternative action.
+ </para>
+
+ <para>
+ <parameter>conflict_target</parameter> can perform
+ <emphasis>unique index inference</emphasis>. When performing
+ inference, it consists of one or more <replaceable
+ class="parameter">index_column_name</replaceable> columns and/or
+ <replaceable class="parameter">index_expression</replaceable>
+ expressions, and an optional <replaceable class="parameter">index_predicate</replaceable>. All <replaceable
+ class="parameter">table_name</replaceable> unique indexes that,
+ without regard to order, contain exactly the
+ <parameter>conflict_target</parameter>-specified
+ columns/expressions are inferred (chosen) as arbiter indexes. If
+ an <replaceable class="parameter">index_predicate</replaceable> is
+ specified, it must, as a further requirement for inference,
+ satisfy arbiter indexes. Note that this means a non-partial
+ unique index (a unique index without a predicate) will be inferred
+ (and thus used by <literal>ON CONFLICT</literal>) if such an index
+ satisfying every other criteria is available. If an attempt at
+ inference is unsuccessful, an error is raised.
+ </para>
+
+ <para>
+ <literal>ON CONFLICT DO UPDATE</literal> guarantees an atomic
+ <command>INSERT</command> or <command>UPDATE</command> outcome;
+ provided there is no independent error, one of those two outcomes
+ is guaranteed, even under high concurrency. This is also known as
+ <firstterm>UPSERT</firstterm> &mdash; <quote>UPDATE or
+ INSERT</quote>.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">conflict_target</replaceable></term>
+ <listitem>
+ <para>
+ Specifies which conflicts <literal>ON CONFLICT</literal> takes
+ the alternative action on by choosing <firstterm>arbiter
+ indexes</firstterm>. Either performs <emphasis>unique index
+ inference</emphasis>, or names a constraint explicitly. For
+ <literal>ON CONFLICT DO NOTHING</literal>, it is optional to
+ specify a <parameter>conflict_target</parameter>; when
+ omitted, conflicts with all usable constraints (and unique
+ indexes) are handled. For <literal>ON CONFLICT DO
+ UPDATE</literal>, a <parameter>conflict_target</parameter>
+ <emphasis>must</emphasis> be provided.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">conflict_action</replaceable></term>
+ <listitem>
+ <para>
+ <parameter>conflict_action</parameter> specifies an
+ alternative <literal>ON CONFLICT</literal> action. It can be
+ either <literal>DO NOTHING</literal>, or a <literal>DO
+ UPDATE</literal> clause specifying the exact details of the
+ <literal>UPDATE</literal> action to be performed in case of a
+ conflict. The <literal>SET</literal> and
+ <literal>WHERE</literal> clauses in <literal>ON CONFLICT DO
+ UPDATE</literal> have access to the existing row using the
+ table's name (or an alias), and to the row proposed for insertion
+ using the special <varname>excluded</varname> table.
+ <literal>SELECT</literal> privilege is required on any column in the
+ target table where corresponding <varname>excluded</varname>
+ columns are read.
+ </para>
+ <para>
+ Note that the effects of all per-row <literal>BEFORE
+ INSERT</literal> triggers are reflected in
+ <varname>excluded</varname> values, since those effects may
+ have contributed to the row being excluded from insertion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a <replaceable
+ class="parameter">table_name</replaceable> column. Used to
+ infer arbiter indexes. Follows <command>CREATE
+ INDEX</command> format. <literal>SELECT</literal> privilege on
+ <replaceable class="parameter">index_column_name</replaceable>
+ is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_expression</replaceable></term>
+ <listitem>
+ <para>
+ Similar to <replaceable
+ class="parameter">index_column_name</replaceable>, but used to
+ infer expressions on <replaceable
+ class="parameter">table_name</replaceable> columns appearing
+ within index definitions (not simple columns). Follows
+ <command>CREATE INDEX</command> format. <literal>SELECT</literal>
+ privilege on any column appearing within <replaceable
+ class="parameter">index_expression</replaceable> is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">collation</replaceable></term>
+ <listitem>
+ <para>
+ When specified, mandates that corresponding <replaceable
+ class="parameter">index_column_name</replaceable> or
+ <replaceable class="parameter">index_expression</replaceable>
+ use a particular collation in order to be matched during
+ inference. Typically this is omitted, as collations usually
+ do not affect whether or not a constraint violation occurs.
+ Follows <command>CREATE INDEX</command> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">opclass</replaceable></term>
+ <listitem>
+ <para>
+ When specified, mandates that corresponding <replaceable
+ class="parameter">index_column_name</replaceable> or
+ <replaceable class="parameter">index_expression</replaceable>
+ use particular operator class in order to be matched during
+ inference. Typically this is omitted, as the
+ <emphasis>equality</emphasis> semantics are often equivalent
+ across a type's operator classes anyway, or because it's
+ sufficient to trust that the defined unique indexes have the
+ pertinent definition of equality. Follows <command>CREATE
+ INDEX</command> format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">index_predicate</replaceable></term>
+ <listitem>
+ <para>
+ Used to allow inference of partial unique indexes. Any
+ indexes that satisfy the predicate (which need not actually be
+ partial indexes) can be inferred. Follows <command>CREATE
+ INDEX</command> format. <literal>SELECT</literal> privilege on any
+ column appearing within <replaceable
+ class="parameter">index_predicate</replaceable> is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">constraint_name</replaceable></term>
+ <listitem>
+ <para>
+ Explicitly specifies an arbiter
+ <emphasis>constraint</emphasis> by name, rather than inferring
+ a constraint or index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">condition</replaceable></term>
+ <listitem>
+ <para>
+ An expression that returns a value of type
+ <type>boolean</type>. Only rows for which this expression
+ returns <literal>true</literal> will be updated, although all
+ rows will be locked when the <literal>ON CONFLICT DO UPDATE</literal>
+ action is taken. Note that
+ <replaceable>condition</replaceable> is evaluated last, after
+ a conflict has been identified as a candidate to update.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Note that exclusion constraints are not supported as arbiters with
+ <literal>ON CONFLICT DO UPDATE</literal>. In all cases, only
+ <literal>NOT DEFERRABLE</literal> constraints and unique indexes
+ are supported as arbiters.
+ </para>
+
+ <para>
+ <command>INSERT</command> with an <literal>ON CONFLICT DO UPDATE</literal>
+ clause is a <quote>deterministic</quote> statement. This means
+ that the command will not be allowed to affect any single existing
+ row more than once; a cardinality violation error will be raised
+ when this situation arises. Rows proposed for insertion should
+ not duplicate each other in terms of attributes constrained by an
+ arbiter index or constraint.
+ </para>
+
+ <para>
+ Note that it is currently not supported for the
+ <literal>ON CONFLICT DO UPDATE</literal> clause of an
+ <command>INSERT</command> applied to a partitioned table to update the
+ partition key of a conflicting row such that it requires the row be moved
+ to a new partition.
+ </para>
+ <tip>
+ <para>
+ It is often preferable to use unique index inference rather than
+ naming a constraint directly using <literal>ON CONFLICT ON
+ CONSTRAINT</literal> <replaceable class="parameter">
+ constraint_name</replaceable>. Inference will continue to work
+ correctly when the underlying index is replaced by another more
+ or less equivalent index in an overlapping way, for example when
+ using <literal>CREATE UNIQUE INDEX ... CONCURRENTLY</literal>
+ before dropping the index being replaced.
+ </para>
+ </tip>
+
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, an <command>INSERT</command> command returns a command
+ tag of the form
+<screen>
+INSERT <replaceable>oid</replaceable> <replaceable class="parameter">count</replaceable>
+</screen>
+ The <replaceable class="parameter">count</replaceable> is the number of
+ rows inserted or updated. <replaceable>oid</replaceable> is always 0 (it
+ used to be the <acronym>OID</acronym> assigned to the inserted row if
+ <replaceable>count</replaceable> was exactly one and the target table was
+ declared <literal>WITH OIDS</literal> and 0 otherwise, but creating a table
+ <literal>WITH OIDS</literal> is not supported anymore).
+ </para>
+
+ <para>
+ If the <command>INSERT</command> command contains a <literal>RETURNING</literal>
+ clause, the result will be similar to that of a <command>SELECT</command>
+ statement containing the columns and values defined in the
+ <literal>RETURNING</literal> list, computed over the row(s) inserted or
+ updated by the command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If the specified table is a partitioned table, each row is routed to
+ the appropriate partition and inserted into it. If the specified table
+ is a partition, an error will occur if one of the input rows violates
+ the partition constraint.
+ </para>
+
+ <para>
+ You may also wish to consider using <command>MERGE</command>, since that
+ allows mixing <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> within a single statement.
+ See <xref linkend="sql-merge"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Insert a single row into table <literal>films</literal>:
+
+<programlisting>
+INSERT INTO films VALUES
+ ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');
+</programlisting>
+ </para>
+
+ <para>
+ In this example, the <literal>len</literal> column is
+ omitted and therefore it will have the default value:
+
+<programlisting>
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
+</programlisting>
+ </para>
+
+ <para>
+ This example uses the <literal>DEFAULT</literal> clause for
+ the date columns rather than specifying a value:
+
+<programlisting>
+INSERT INTO films VALUES
+ ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes');
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama');
+</programlisting>
+ </para>
+
+ <para>
+ To insert a row consisting entirely of default values:
+
+<programlisting>
+INSERT INTO films DEFAULT VALUES;
+</programlisting>
+ </para>
+
+ <para>
+ To insert multiple rows using the multirow <command>VALUES</command> syntax:
+
+<programlisting>
+INSERT INTO films (code, title, did, date_prod, kind) VALUES
+ ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
+ ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
+</programlisting>
+ </para>
+
+ <para>
+ This example inserts some rows into table
+ <literal>films</literal> from a table <literal>tmp_films</literal>
+ with the same column layout as <literal>films</literal>:
+
+<programlisting>
+INSERT INTO films SELECT * FROM tmp_films WHERE date_prod &lt; '2004-05-07';
+</programlisting>
+ </para>
+
+ <para>
+ This example inserts into array columns:
+
+<programlisting>
+-- Create an empty 3x3 gameboard for noughts-and-crosses
+INSERT INTO tictactoe (game, board[1:3][1:3])
+ VALUES (1, '{{" "," "," "},{" "," "," "},{" "," "," "}}');
+-- The subscripts in the above example aren't really needed
+INSERT INTO tictactoe (game, board)
+ VALUES (2, '{{X," "," "},{" ",O," "},{" ",X," "}}');
+</programlisting>
+ </para>
+
+ <para>
+ Insert a single row into table <literal>distributors</literal>, returning
+ the sequence number generated by the <literal>DEFAULT</literal> clause:
+
+<programlisting>
+INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')
+ RETURNING did;
+</programlisting>
+ </para>
+
+ <para>
+ Increment the sales count of the salesperson who manages the
+ account for Acme Corporation, and record the whole updated row
+ along with current time in a log table:
+<programlisting>
+WITH upd AS (
+ UPDATE employees SET sales_count = sales_count + 1 WHERE id =
+ (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
+ RETURNING *
+)
+INSERT INTO employees_log SELECT *, current_timestamp FROM upd;
+</programlisting>
+ </para>
+ <para>
+ Insert or update new distributors as appropriate. Assumes a unique
+ index has been defined that constrains values appearing in the
+ <literal>did</literal> column. Note that the special
+ <varname>excluded</varname> table is used to reference values originally
+ proposed for insertion:
+<programlisting>
+INSERT INTO distributors (did, dname)
+ VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
+ ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
+</programlisting>
+ </para>
+ <para>
+ Insert a distributor, or do nothing for rows proposed for insertion
+ when an existing, excluded row (a row with a matching constrained
+ column or columns after before row insert triggers fire) exists.
+ Example assumes a unique index has been defined that constrains
+ values appearing in the <literal>did</literal> column:
+<programlisting>
+INSERT INTO distributors (did, dname) VALUES (7, 'Redline GmbH')
+ ON CONFLICT (did) DO NOTHING;
+</programlisting>
+ </para>
+ <para>
+ Insert or update new distributors as appropriate. Example assumes
+ a unique index has been defined that constrains values appearing in
+ the <literal>did</literal> column. <literal>WHERE</literal> clause is
+ used to limit the rows actually updated (any existing row not
+ updated will still be locked, though):
+<programlisting>
+-- Don't update existing distributors based in a certain ZIP code
+INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
+ ON CONFLICT (did) DO UPDATE
+ SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
+ WHERE d.zipcode &lt;&gt; '21201';
+
+-- Name a constraint directly in the statement (uses associated
+-- index to arbitrate taking the DO NOTHING action)
+INSERT INTO distributors (did, dname) VALUES (9, 'Antwerp Design')
+ ON CONFLICT ON CONSTRAINT distributors_pkey DO NOTHING;
+</programlisting>
+ </para>
+ <para>
+ Insert new distributor if possible; otherwise
+ <literal>DO NOTHING</literal>. Example assumes a unique index has been
+ defined that constrains values appearing in the
+ <literal>did</literal> column on a subset of rows where the
+ <literal>is_active</literal> Boolean column evaluates to
+ <literal>true</literal>:
+<programlisting>
+-- This statement could infer a partial unique index on "did"
+-- with a predicate of "WHERE is_active", but it could also
+-- just use a regular unique constraint on "did"
+INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
+ ON CONFLICT (did) WHERE is_active DO NOTHING;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>INSERT</command> conforms to the SQL standard, except that
+ the <literal>RETURNING</literal> clause is a
+ <productname>PostgreSQL</productname> extension, as is the ability
+ to use <literal>WITH</literal> with <command>INSERT</command>, and the ability to
+ specify an alternative action with <literal>ON CONFLICT</literal>.
+ Also, the case in
+ which a column name list is omitted, but not all the columns are
+ filled from the <literal>VALUES</literal> clause or <replaceable>query</replaceable>,
+ is disallowed by the standard. If you prefer a more SQL standard
+ conforming statement than <literal>ON CONFLICT</literal>, see
+ <xref linkend="sql-merge"/>.
+ </para>
+
+ <para>
+ The SQL standard specifies that <literal>OVERRIDING SYSTEM VALUE</literal>
+ can only be specified if an identity column that is generated always
+ exists. PostgreSQL allows the clause in any case and ignores it if it is
+ not applicable.
+ </para>
+
+ <para>
+ Possible limitations of the <replaceable
+ class="parameter">query</replaceable> clause are documented under
+ <xref linkend="sql-select"/>.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/listen.sgml b/doc/src/sgml/ref/listen.sgml
new file mode 100644
index 0000000..2fab9d6
--- /dev/null
+++ b/doc/src/sgml/ref/listen.sgml
@@ -0,0 +1,153 @@
+<!--
+doc/src/sgml/ref/listen.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-listen">
+ <indexterm zone="sql-listen">
+ <primary>LISTEN</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>LISTEN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>LISTEN</refname>
+ <refpurpose>listen for a notification</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+LISTEN <replaceable class="parameter">channel</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>LISTEN</command> registers the current session as a
+ listener on the notification channel named <replaceable
+ class="parameter">channel</replaceable>.
+ If the current session is already registered as a listener for
+ this notification channel, nothing is done.
+ </para>
+
+ <para>
+ Whenever the command <command>NOTIFY <replaceable
+ class="parameter">channel</replaceable></command> is invoked, either
+ by this session or another one connected to the same database, all
+ the sessions currently listening on that notification channel are
+ notified, and each will in turn notify its connected client
+ application.
+ </para>
+
+ <para>
+ A session can be unregistered for a given notification channel with the
+ <command>UNLISTEN</command> command. A session's listen
+ registrations are automatically cleared when the session ends.
+ </para>
+
+ <para>
+ The method a client application must use to detect notification events depends on
+ which <productname>PostgreSQL</productname> application programming interface it
+ uses. With the <application>libpq</application> library, the application issues
+ <command>LISTEN</command> as an ordinary SQL command, and then must
+ periodically call the function <function>PQnotifies</function> to find out
+ whether any notification events have been received. Other interfaces such as
+ <application>libpgtcl</application> provide higher-level methods for handling notify events; indeed,
+ with <application>libpgtcl</application> the application programmer should not even issue
+ <command>LISTEN</command> or <command>UNLISTEN</command> directly. See the
+ documentation for the interface you are using for more details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">channel</replaceable></term>
+ <listitem>
+ <para>
+ Name of a notification channel (any identifier).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>LISTEN</command> takes effect at transaction commit.
+ If <command>LISTEN</command> or <command>UNLISTEN</command> is executed
+ within a transaction that later rolls back, the set of notification
+ channels being listened to is unchanged.
+ </para>
+
+ <para>
+ A transaction that has executed <command>LISTEN</command> cannot be
+ prepared for two-phase commit.
+ </para>
+
+ <para>
+ There is a race condition when first setting up a listening session:
+ if concurrently-committing transactions are sending notify events,
+ exactly which of those will the newly listening session receive?
+ The answer is that the session will receive all events committed after
+ an instant during the transaction's commit step. But that is slightly
+ later than any database state that the transaction could have observed
+ in queries. This leads to the following rule for
+ using <command>LISTEN</command>: first execute (and commit!) that
+ command, then in a new transaction inspect the database state as needed
+ by the application logic, then rely on notifications to find out about
+ subsequent changes to the database state. The first few received
+ notifications might refer to updates already observed in the initial
+ database inspection, but this is usually harmless.
+ </para>
+
+ <para>
+ <xref linkend="sql-notify"/>
+ contains a more extensive
+ discussion of the use of <command>LISTEN</command> and
+ <command>NOTIFY</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Configure and execute a listen/notify sequence from
+ <application>psql</application>:
+
+<programlisting>
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448.
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>LISTEN</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-notify"/></member>
+ <member><xref linkend="sql-unlisten"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/load.sgml b/doc/src/sgml/ref/load.sgml
new file mode 100644
index 0000000..2c214dd
--- /dev/null
+++ b/doc/src/sgml/ref/load.sgml
@@ -0,0 +1,81 @@
+<!--
+doc/src/sgml/ref/load.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-load">
+ <indexterm zone="sql-load">
+ <primary>LOAD</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>LOAD</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>LOAD</refname>
+ <refpurpose>load a shared library file</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+LOAD '<replaceable class="parameter">filename</replaceable>'
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-load-description">
+ <title>Description</title>
+
+ <para>
+ This command loads a shared library file into the <productname>PostgreSQL</productname>
+ server's address space. If the file has been loaded already,
+ the command does nothing. Shared library files that contain C functions
+ are automatically loaded whenever one of their functions is called.
+ Therefore, an explicit <command>LOAD</command> is usually only needed to
+ load a library that modifies the server's behavior through <quote>hooks</quote>
+ rather than providing a set of functions.
+ </para>
+
+ <para>
+ The library file name is typically given as just a bare file name,
+ which is sought in the server's library search path (set
+ by <xref linkend="guc-dynamic-library-path"/>). Alternatively it can be
+ given as a full path name. In either case the platform's standard shared
+ library file name extension may be omitted.
+ See <xref linkend="xfunc-c-dynload"/> for more information on this topic.
+ </para>
+
+ <indexterm>
+ <primary><filename>$libdir/plugins</filename></primary>
+ </indexterm>
+
+ <para>
+ Non-superusers can only apply <command>LOAD</command> to library files
+ located in <filename>$libdir/plugins/</filename> &mdash; the specified
+ <replaceable class="parameter">filename</replaceable> must begin
+ with exactly that string. (It is the database administrator's
+ responsibility to ensure that only <quote>safe</quote> libraries
+ are installed there.)
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-load-compat">
+ <title>Compatibility</title>
+
+ <para>
+ <command>LOAD</command> is a <productname>PostgreSQL</productname>
+ extension.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <xref linkend="sql-createfunction"/>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml
new file mode 100644
index 0000000..19e7194
--- /dev/null
+++ b/doc/src/sgml/ref/lock.sgml
@@ -0,0 +1,266 @@
+<!--
+doc/src/sgml/ref/lock.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-lock">
+ <indexterm zone="sql-lock">
+ <primary>LOCK</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>LOCK</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>LOCK</refname>
+ <refpurpose>lock a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+LOCK [ TABLE ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ] [, ...] [ IN <replaceable class="parameter">lockmode</replaceable> MODE ] [ NOWAIT ]
+
+<phrase>where <replaceable class="parameter">lockmode</replaceable> is one of:</phrase>
+
+ ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
+ | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>LOCK TABLE</command> obtains a table-level lock, waiting
+ if necessary for any conflicting locks to be released. If
+ <literal>NOWAIT</literal> is specified, <command>LOCK
+ TABLE</command> does not wait to acquire the desired lock: if it
+ cannot be acquired immediately, the command is aborted and an
+ error is emitted. Once obtained, the lock is held for the
+ remainder of the current transaction. (There is no <command>UNLOCK
+ TABLE</command> command; locks are always released at transaction
+ end.)
+ </para>
+
+ <para>
+ When a view is locked, all relations appearing in the view definition
+ query are also locked recursively with the same lock mode.
+ </para>
+
+ <para>
+ When acquiring locks automatically for commands that reference
+ tables, <productname>PostgreSQL</productname> always uses the least
+ restrictive lock mode possible. <command>LOCK TABLE</command>
+ provides for cases when you might need more restrictive locking.
+ For example, suppose an application runs a transaction at the
+ <literal>READ COMMITTED</literal> isolation level and needs to ensure that
+ data in a table remains stable for the duration of the transaction.
+ To achieve this you could obtain <literal>SHARE</literal> lock mode over the
+ table before querying. This will prevent concurrent data changes
+ and ensure subsequent reads of the table see a stable view of
+ committed data, because <literal>SHARE</literal> lock mode conflicts with
+ the <literal>ROW EXCLUSIVE</literal> lock acquired by writers, and your
+ <command>LOCK TABLE <replaceable
+ class="parameter">name</replaceable> IN SHARE MODE</command>
+ statement will wait until any concurrent holders of <literal>ROW
+ EXCLUSIVE</literal> mode locks commit or roll back. Thus, once you
+ obtain the lock, there are no uncommitted writes outstanding;
+ furthermore none can begin until you release the lock.
+ </para>
+
+ <para>
+ To achieve a similar effect when running a transaction at the
+ <literal>REPEATABLE READ</literal> or <literal>SERIALIZABLE</literal>
+ isolation level, you have to execute the <command>LOCK TABLE</command> statement
+ before executing any <command>SELECT</command> or data modification statement.
+ A <literal>REPEATABLE READ</literal> or <literal>SERIALIZABLE</literal> transaction's
+ view of data will be frozen when its first
+ <command>SELECT</command> or data modification statement begins. A <command>LOCK
+ TABLE</command> later in the transaction will still prevent concurrent writes
+ &mdash; but it won't ensure that what the transaction reads corresponds to
+ the latest committed values.
+ </para>
+
+ <para>
+ If a transaction of this sort is going to change the data in the
+ table, then it should use <literal>SHARE ROW EXCLUSIVE</literal> lock mode
+ instead of <literal>SHARE</literal> mode. This ensures that only one
+ transaction of this type runs at a time. Without this, a deadlock
+ is possible: two transactions might both acquire <literal>SHARE</literal>
+ mode, and then be unable to also acquire <literal>ROW EXCLUSIVE</literal>
+ mode to actually perform their updates. (Note that a transaction's
+ own locks never conflict, so a transaction can acquire <literal>ROW
+ EXCLUSIVE</literal> mode when it holds <literal>SHARE</literal> mode &mdash; but not
+ if anyone else holds <literal>SHARE</literal> mode.) To avoid deadlocks,
+ make sure all transactions acquire locks on the same objects in the
+ same order, and if multiple lock modes are involved for a single
+ object, then transactions should always acquire the most
+ restrictive mode first.
+ </para>
+
+ <para>
+ More information about the lock modes and locking strategies can be
+ found in <xref linkend="explicit-locking"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing table to
+ lock. If <literal>ONLY</literal> is specified before the table name, only that
+ table is locked. If <literal>ONLY</literal> is not specified, the table and all
+ its descendant tables (if any) are locked. Optionally, <literal>*</literal>
+ can be specified after the table name to explicitly indicate that
+ descendant tables are included.
+ </para>
+
+ <para>
+ The command <literal>LOCK TABLE a, b;</literal> is equivalent to
+ <literal>LOCK TABLE a; LOCK TABLE b;</literal>. The tables are locked
+ one-by-one in the order specified in the <command>LOCK
+ TABLE</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">lockmode</replaceable></term>
+ <listitem>
+ <para>
+ The lock mode specifies which locks this lock conflicts with.
+ Lock modes are described in <xref linkend="explicit-locking"/>.
+ </para>
+
+ <para>
+ If no lock mode is specified, then <literal>ACCESS
+ EXCLUSIVE</literal>, the most restrictive mode, is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NOWAIT</literal></term>
+ <listitem>
+ <para>
+ Specifies that <command>LOCK TABLE</command> should not wait for
+ any conflicting locks to be released: if the specified lock(s)
+ cannot be acquired immediately without waiting, the transaction
+ is aborted.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <literal>LOCK TABLE ... IN ACCESS SHARE MODE</literal> requires <literal>SELECT</literal>
+ privileges on the target table. <literal>LOCK TABLE ... IN ROW EXCLUSIVE
+ MODE</literal> requires <literal>INSERT</literal>, <literal>UPDATE</literal>, <literal>DELETE</literal>,
+ or <literal>TRUNCATE</literal> privileges on the target table. All other forms of
+ <command>LOCK</command> require table-level <literal>UPDATE</literal>, <literal>DELETE</literal>,
+ or <literal>TRUNCATE</literal> privileges.
+ </para>
+
+ <para>
+ The user performing the lock on the view must have the corresponding
+ privilege on the view. In addition, by default, the view's owner must
+ have the relevant privileges on the underlying base relations, whereas the
+ user performing the lock does not need any permissions on the underlying
+ base relations. However, if the view has
+ <literal>security_invoker</literal> set to <literal>true</literal>
+ (see <link linkend="sql-createview"><command>CREATE VIEW</command></link>),
+ the user performing the lock, rather than the view owner, must have the
+ relevant privileges on the underlying base relations.
+ </para>
+
+ <para>
+ <command>LOCK TABLE</command> is useless outside a transaction block: the lock
+ would remain held only to the completion of the statement. Therefore
+ <productname>PostgreSQL</productname> reports an error if <command>LOCK</command>
+ is used outside a transaction block.
+ Use
+ <link linkend="sql-begin"><command>BEGIN</command></link> and
+ <link linkend="sql-commit"><command>COMMIT</command></link>
+ (or <link linkend="sql-rollback"><command>ROLLBACK</command></link>)
+ to define a transaction block.
+ </para>
+
+ <para>
+ <command>LOCK TABLE</command> only deals with table-level locks, and so
+ the mode names involving <literal>ROW</literal> are all misnomers. These
+ mode names should generally be read as indicating the intention of
+ the user to acquire row-level locks within the locked table. Also,
+ <literal>ROW EXCLUSIVE</literal> mode is a shareable table lock. Keep in
+ mind that all the lock modes have identical semantics so far as
+ <command>LOCK TABLE</command> is concerned, differing only in the rules
+ about which modes conflict with which. For information on how to
+ acquire an actual row-level lock, see <xref linkend="locking-rows"/>
+ and <xref linkend="sql-for-update-share"/>
+ in the <xref linkend="sql-select"/> documentation.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Obtain a <literal>SHARE</literal> lock on a primary key table when going to perform
+ inserts into a foreign key table:
+
+<programlisting>
+BEGIN WORK;
+LOCK TABLE films IN SHARE MODE;
+SELECT id FROM films
+ WHERE name = 'Star Wars: Episode I - The Phantom Menace';
+-- Do ROLLBACK if record was not returned
+INSERT INTO films_user_comments VALUES
+ (_id_, 'GREAT! I was waiting for it for so long!');
+COMMIT WORK;
+</programlisting>
+ </para>
+
+ <para>
+ Take a <literal>SHARE ROW EXCLUSIVE</literal> lock on a primary key table when going to perform
+ a delete operation:
+
+<programlisting>
+BEGIN WORK;
+LOCK TABLE films IN SHARE ROW EXCLUSIVE MODE;
+DELETE FROM films_user_comments WHERE id IN
+ (SELECT id FROM films WHERE rating &lt; 5);
+DELETE FROM films WHERE rating &lt; 5;
+COMMIT WORK;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>LOCK TABLE</command> in the SQL standard,
+ which instead uses <command>SET TRANSACTION</command> to specify
+ concurrency levels on transactions. <productname>PostgreSQL</productname> supports that too;
+ see <xref linkend="sql-set-transaction"/> for details.
+ </para>
+
+ <para>
+ Except for <literal>ACCESS SHARE</literal>, <literal>ACCESS EXCLUSIVE</literal>,
+ and <literal>SHARE UPDATE EXCLUSIVE</literal> lock modes, the
+ <productname>PostgreSQL</productname> lock modes and the
+ <command>LOCK TABLE</command> syntax are compatible with those
+ present in <productname>Oracle</productname>.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/merge.sgml b/doc/src/sgml/ref/merge.sgml
new file mode 100644
index 0000000..0995fe0
--- /dev/null
+++ b/doc/src/sgml/ref/merge.sgml
@@ -0,0 +1,634 @@
+<!--
+doc/src/sgml/ref/merge.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-merge">
+ <indexterm zone="sql-merge">
+ <primary>MERGE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>MERGE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>MERGE</refname>
+ <refpurpose>conditionally insert, update, or delete rows of a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+[ WITH <replaceable class="parameter">with_query</replaceable> [, ...] ]
+MERGE INTO [ ONLY ] <replaceable class="parameter">target_table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">target_alias</replaceable> ]
+USING <replaceable class="parameter">data_source</replaceable> ON <replaceable class="parameter">join_condition</replaceable>
+<replaceable class="parameter">when_clause</replaceable> [...]
+
+<phrase>where <replaceable class="parameter">data_source</replaceable> is:</phrase>
+
+{ [ ONLY ] <replaceable class="parameter">source_table_name</replaceable> [ * ] | ( <replaceable class="parameter">source_query</replaceable> ) } [ [ AS ] <replaceable class="parameter">source_alias</replaceable> ]
+
+<phrase>and <replaceable class="parameter">when_clause</replaceable> is:</phrase>
+
+{ WHEN MATCHED [ AND <replaceable class="parameter">condition</replaceable> ] THEN { <replaceable class="parameter">merge_update</replaceable> | <replaceable class="parameter">merge_delete</replaceable> | DO NOTHING } |
+ WHEN NOT MATCHED [ AND <replaceable class="parameter">condition</replaceable> ] THEN { <replaceable class="parameter">merge_insert</replaceable> | DO NOTHING } }
+
+<phrase>and <replaceable class="parameter">merge_insert</replaceable> is:</phrase>
+
+INSERT [( <replaceable class="parameter">column_name</replaceable> [, ...] )]
+[ OVERRIDING { SYSTEM | USER } VALUE ]
+{ VALUES ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) | DEFAULT VALUES }
+
+<phrase>and <replaceable class="parameter">merge_update</replaceable> is:</phrase>
+
+UPDATE SET { <replaceable class="parameter">column_name</replaceable> = { <replaceable class="parameter">expression</replaceable> | DEFAULT } |
+ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) = ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) } [, ...]
+
+<phrase>and <replaceable class="parameter">merge_delete</replaceable> is:</phrase>
+
+DELETE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>MERGE</command> performs actions that modify rows in the
+ <replaceable class="parameter">target_table_name</replaceable>,
+ using the <replaceable class="parameter">data_source</replaceable>.
+ <command>MERGE</command> provides a single <acronym>SQL</acronym>
+ statement that can conditionally <command>INSERT</command>,
+ <command>UPDATE</command> or <command>DELETE</command> rows, a task
+ that would otherwise require multiple procedural language statements.
+ </para>
+
+ <para>
+ First, the <command>MERGE</command> command performs a join
+ from <replaceable class="parameter">data_source</replaceable> to
+ <replaceable class="parameter">target_table_name</replaceable>
+ producing zero or more candidate change rows. For each candidate change
+ row, the status of <literal>MATCHED</literal> or <literal>NOT MATCHED</literal>
+ is set just once, after which <literal>WHEN</literal> clauses are evaluated
+ in the order specified. For each candidate change row, the first clause to
+ evaluate as true is executed. No more than one <literal>WHEN</literal>
+ clause is executed for any candidate change row.
+ </para>
+
+ <para>
+ <command>MERGE</command> actions have the same effect as
+ regular <command>UPDATE</command>, <command>INSERT</command>, or
+ <command>DELETE</command> commands of the same names. The syntax of
+ those commands is different, notably that there is no <literal>WHERE</literal>
+ clause and no table name is specified. All actions refer to the
+ <replaceable class="parameter">target_table_name</replaceable>,
+ though modifications to other tables may be made using triggers.
+ </para>
+
+ <para>
+ When <literal>DO NOTHING</literal> is specified, the source row is
+ skipped. Since actions are evaluated in their specified order, <literal>DO
+ NOTHING</literal> can be handy to skip non-interesting source rows before
+ more fine-grained handling.
+ </para>
+
+ <para>
+ There is no separate <literal>MERGE</literal> privilege.
+ If you specify an update action, you must have the
+ <literal>UPDATE</literal> privilege on the column(s)
+ of the <replaceable class="parameter">target_table_name</replaceable>
+ that are referred to in the <literal>SET</literal> clause.
+ If you specify an insert action, you must have the <literal>INSERT</literal>
+ privilege on the <replaceable class="parameter">target_table_name</replaceable>.
+ If you specify an delete action, you must have the <literal>DELETE</literal>
+ privilege on the <replaceable class="parameter">target_table_name</replaceable>.
+ Privileges are tested once at statement start and are checked
+ whether or not particular <literal>WHEN</literal> clauses are executed.
+ You will require the <literal>SELECT</literal> privilege on the
+ <replaceable class="parameter">data_source</replaceable> and any column(s)
+ of the <replaceable class="parameter">target_table_name</replaceable>
+ referred to in a <literal>condition</literal>.
+ </para>
+
+ <para>
+ <command>MERGE</command> is not supported if the
+ <replaceable class="parameter">target_table_name</replaceable> is a
+ materialized view, foreign table, or if it has any
+ rules defined on it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">target_table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the target table to merge into.
+ If <literal>ONLY</literal> is specified before the table name, matching
+ rows are updated or deleted in the named table only. If
+ <literal>ONLY</literal> is not specified, matching rows are also updated
+ or deleted in any tables inheriting from the named table. Optionally,
+ <literal>*</literal> can be specified after the table name to explicitly
+ indicate that descendant tables are included. The
+ <literal>ONLY</literal> keyword and <literal>*</literal> option do not
+ affect insert actions, which always insert into the named table only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">target_alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <literal>MERGE INTO foo AS f</literal>, the remainder of the
+ <command>MERGE</command> statement must refer to this table as
+ <literal>f</literal> not <literal>foo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">source_table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the source table, view, or
+ transition table. If <literal>ONLY</literal> is specified before the
+ table name, matching rows are included from the named table only. If
+ <literal>ONLY</literal> is not specified, matching rows are also included
+ from any tables inheriting from the named table. Optionally,
+ <literal>*</literal> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">source_query</replaceable></term>
+ <listitem>
+ <para>
+ A query (<command>SELECT</command> statement or <command>VALUES</command>
+ statement) that supplies the rows to be merged into the
+ <replaceable class="parameter">target_table_name</replaceable>.
+ Refer to the <xref linkend="sql-select"/>
+ statement or <xref linkend="sql-values"/>
+ statement for a description of the syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">source_alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the data source. When an alias is
+ provided, it completely hides the actual name of the table or the fact
+ that a query was issued.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">join_condition</replaceable></term>
+ <listitem>
+ <para>
+ <replaceable class="parameter">join_condition</replaceable> is
+ an expression resulting in a value of type
+ <type>boolean</type> (similar to a <literal>WHERE</literal>
+ clause) that specifies which rows in the
+ <replaceable class="parameter">data_source</replaceable>
+ match rows in the
+ <replaceable class="parameter">target_table_name</replaceable>.
+ </para>
+ <warning>
+ <para>
+ Only columns from <replaceable class="parameter">target_table_name</replaceable>
+ that attempt to match <replaceable class="parameter">data_source</replaceable>
+ rows should appear in <replaceable class="parameter">join_condition</replaceable>.
+ <replaceable class="parameter">join_condition</replaceable> subexpressions that
+ only reference <replaceable class="parameter">target_table_name</replaceable>
+ columns can affect which action is taken, often in surprising ways.
+ </para>
+ </warning>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">when_clause</replaceable></term>
+ <listitem>
+ <para>
+ At least one <literal>WHEN</literal> clause is required.
+ </para>
+ <para>
+ If the <literal>WHEN</literal> clause specifies <literal>WHEN MATCHED</literal>
+ and the candidate change row matches a row in the
+ <replaceable class="parameter">target_table_name</replaceable>,
+ the <literal>WHEN</literal> clause is executed if the
+ <replaceable class="parameter">condition</replaceable> is
+ absent or it evaluates to <literal>true</literal>.
+ </para>
+ <para>
+ Conversely, if the <literal>WHEN</literal> clause specifies
+ <literal>WHEN NOT MATCHED</literal>
+ and the candidate change row does not match a row in the
+ <replaceable class="parameter">target_table_name</replaceable>,
+ the <literal>WHEN</literal> clause is executed if the
+ <replaceable class="parameter">condition</replaceable> is
+ absent or it evaluates to <literal>true</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">condition</replaceable></term>
+ <listitem>
+ <para>
+ An expression that returns a value of type <type>boolean</type>.
+ If this expression for a <literal>WHEN</literal> clause
+ returns <literal>true</literal>, then the action for that clause
+ is executed for that row.
+ </para>
+ <para>
+ A condition on a <literal>WHEN MATCHED</literal> clause can refer to columns
+ in both the source and the target relations. A condition on a
+ <literal>WHEN NOT MATCHED</literal> clause can only refer to columns from
+ the source relation, since by definition there is no matching target row.
+ Only the system attributes from the target table are accessible.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">merge_insert</replaceable></term>
+ <listitem>
+ <para>
+ The specification of an <literal>INSERT</literal> action that inserts
+ one row into the target table.
+ The target column names can be listed in any order. If no list of
+ column names is given at all, the default is all the columns of the
+ table in their declared order.
+ </para>
+ <para>
+ Each column not present in the explicit or implicit column list will be
+ filled with a default value, either its declared default value
+ or null if there is none.
+ </para>
+ <para>
+ If <replaceable class="parameter">target_table_name</replaceable>
+ is a partitioned table, each row is routed to the appropriate partition
+ and inserted into it.
+ If <replaceable class="parameter">target_table_name</replaceable>
+ is a partition, an error will occur if any input row violates the
+ partition constraint.
+ </para>
+ <para>
+ Column names may not be specified more than once.
+ <command>INSERT</command> actions cannot contain sub-selects.
+ </para>
+ <para>
+ Only one <literal>VALUES</literal> clause can be specified.
+ The <literal>VALUES</literal> clause can only refer to columns from
+ the source relation, since by definition there is no matching target row.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">merge_update</replaceable></term>
+ <listitem>
+ <para>
+ The specification of an <literal>UPDATE</literal> action that updates
+ the current row of the <replaceable class="parameter">target_table_name</replaceable>.
+ Column names may not be specified more than once.
+ </para>
+ <para>
+ Neither a table name nor a <literal>WHERE</literal> clause are allowed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">merge_delete</replaceable></term>
+ <listitem>
+ <para>
+ Specifies a <literal>DELETE</literal> action that deletes the current row
+ of the <replaceable class="parameter">target_table_name</replaceable>.
+ Do not include the table name or any other clauses, as you would normally
+ do with a <xref linkend="sql-delete"/> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column in the <replaceable
+ class="parameter">target_table_name</replaceable>. The column name
+ can be qualified with a subfield name or array subscript, if
+ needed. (Inserting into only some fields of a composite
+ column leaves the other fields null.)
+ Do not include the table's name in the specification
+ of a target column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OVERRIDING SYSTEM VALUE</literal></term>
+ <listitem>
+ <para>
+ Without this clause, it is an error to specify an explicit value
+ (other than <literal>DEFAULT</literal>) for an identity column defined
+ as <literal>GENERATED ALWAYS</literal>. This clause overrides that
+ restriction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>OVERRIDING USER VALUE</literal></term>
+ <listitem>
+ <para>
+ If this clause is specified, then any values supplied for identity
+ columns defined as <literal>GENERATED BY DEFAULT</literal> are ignored
+ and the default sequence-generated values are applied.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT VALUES</literal></term>
+ <listitem>
+ <para>
+ All columns will be filled with their default values.
+ (An <literal>OVERRIDING</literal> clause is not permitted in this
+ form.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression to assign to the column. If used in a
+ <literal>WHEN MATCHED</literal> clause, the expression can use values
+ from the original row in the target table, and values from the
+ <literal>data_source</literal> row.
+ If used in a <literal>WHEN NOT MATCHED</literal> clause, the
+ expression can use values from the <literal>data_source</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Set the column to its default value (which will be <literal>NULL</literal>
+ if no specific default expression has been assigned to it).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">with_query</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>WITH</literal> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <command>MERGE</command>
+ query. See <xref linkend="queries-with"/> and <xref linkend="sql-select"/>
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, a <command>MERGE</command> command returns a command
+ tag of the form
+<screen>
+MERGE <replaceable class="parameter">total_count</replaceable>
+</screen>
+ The <replaceable class="parameter">total_count</replaceable> is the total
+ number of rows changed (whether inserted, updated, or deleted).
+ If <replaceable class="parameter">total_count</replaceable> is 0, no rows
+ were changed in any way.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The following steps take place during the execution of
+ <command>MERGE</command>.
+ <orderedlist>
+ <listitem>
+ <para>
+ Perform any <literal>BEFORE STATEMENT</literal> triggers for all
+ actions specified, whether or not their <literal>WHEN</literal>
+ clauses match.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Perform a join from source to target table.
+ The resulting query will be optimized normally and will produce
+ a set of candidate change rows. For each candidate change row,
+ <orderedlist>
+ <listitem>
+ <para>
+ Evaluate whether each row is <literal>MATCHED</literal> or
+ <literal>NOT MATCHED</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Test each <literal>WHEN</literal> condition in the order
+ specified until one returns true.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ When a condition returns true, perform the following actions:
+ <orderedlist>
+ <listitem>
+ <para>
+ Perform any <literal>BEFORE ROW</literal> triggers that fire
+ for the action's event type.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Perform the specified action, invoking any check constraints on the
+ target table.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Perform any <literal>AFTER ROW</literal> triggers that fire for
+ the action's event type.
+ </para>
+ </listitem>
+ </orderedlist></para>
+ </listitem>
+ </orderedlist></para>
+ </listitem>
+ <listitem>
+ <para>
+ Perform any <literal>AFTER STATEMENT</literal> triggers for actions
+ specified, whether or not they actually occur. This is similar to the
+ behavior of an <command>UPDATE</command> statement that modifies no rows.
+ </para>
+ </listitem>
+ </orderedlist>
+ In summary, statement triggers for an event type (say,
+ <command>INSERT</command>) will be fired whenever we
+ <emphasis>specify</emphasis> an action of that kind.
+ In contrast, row-level triggers will fire only for the specific event type
+ being <emphasis>executed</emphasis>.
+ So a <command>MERGE</command> command might fire statement triggers for both
+ <command>UPDATE</command> and <command>INSERT</command>, even though only
+ <command>UPDATE</command> row triggers were fired.
+ </para>
+
+ <para>
+ You should ensure that the join produces at most one candidate change row
+ for each target row. In other words, a target row shouldn't join to more
+ than one data source row. If it does, then only one of the candidate change
+ rows will be used to modify the target row; later attempts to modify the
+ row will cause an error.
+ This can also occur if row triggers make changes to the target table
+ and the rows so modified are then subsequently also modified by
+ <command>MERGE</command>.
+ If the repeated action is an <command>INSERT</command>, this will
+ cause a uniqueness violation, while a repeated <command>UPDATE</command>
+ or <command>DELETE</command> will cause a cardinality violation; the
+ latter behavior is required by the <acronym>SQL</acronym> standard.
+ This differs from historical <productname>PostgreSQL</productname>
+ behavior of joins in <command>UPDATE</command> and
+ <command>DELETE</command> statements where second and subsequent
+ attempts to modify the same row are simply ignored.
+ </para>
+
+ <para>
+ If a <literal>WHEN</literal> clause omits an <literal>AND</literal>
+ sub-clause, it becomes the final reachable clause of that
+ kind (<literal>MATCHED</literal> or <literal>NOT MATCHED</literal>).
+ If a later <literal>WHEN</literal> clause of that kind
+ is specified it would be provably unreachable and an error is raised.
+ If no final reachable clause is specified of either kind, it is
+ possible that no action will be taken for a candidate change row.
+ </para>
+
+ <para>
+ The order in which rows are generated from the data source is
+ indeterminate by default.
+ A <replaceable class="parameter">source_query</replaceable> can be
+ used to specify a consistent ordering, if required, which might be
+ needed to avoid deadlocks between concurrent transactions.
+ </para>
+
+ <para>
+ There is no <literal>RETURNING</literal> clause with
+ <command>MERGE</command>. Actions of <command>INSERT</command>,
+ <command>UPDATE</command> and <command>DELETE</command> cannot contain
+ <literal>RETURNING</literal> or <literal>WITH</literal> clauses.
+ </para>
+
+ <para>
+ When <command>MERGE</command> is run concurrently with other commands
+ that modify the target table, the usual transaction isolation rules
+ apply; see <xref linkend="transaction-iso"/> for an explanation
+ on the behavior at each isolation level.
+ You may also wish to consider using <command>INSERT ... ON CONFLICT</command>
+ as an alternative statement which offers the ability to run an
+ <command>UPDATE</command> if a concurrent <command>INSERT</command>
+ occurs. There are a variety of differences and restrictions between
+ the two statement types and they are not interchangeable.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Perform maintenance on <literal>customer_accounts</literal> based
+ upon new <literal>recent_transactions</literal>.
+
+<programlisting>
+MERGE INTO customer_account ca
+USING recent_transactions t
+ON t.customer_id = ca.customer_id
+WHEN MATCHED THEN
+ UPDATE SET balance = balance + transaction_value
+WHEN NOT MATCHED THEN
+ INSERT (customer_id, balance)
+ VALUES (t.customer_id, t.transaction_value);
+</programlisting>
+ </para>
+
+ <para>
+ Notice that this would be exactly equivalent to the following
+ statement because the <literal>MATCHED</literal> result does not change
+ during execution.
+
+<programlisting>
+MERGE INTO customer_account ca
+USING (SELECT customer_id, transaction_value FROM recent_transactions) AS t
+ON t.customer_id = ca.customer_id
+WHEN MATCHED THEN
+ UPDATE SET balance = balance + transaction_value
+WHEN NOT MATCHED THEN
+ INSERT (customer_id, balance)
+ VALUES (t.customer_id, t.transaction_value);
+</programlisting>
+ </para>
+
+ <para>
+ Attempt to insert a new stock item along with the quantity of stock. If
+ the item already exists, instead update the stock count of the existing
+ item. Don't allow entries that have zero stock.
+<programlisting>
+MERGE INTO wines w
+USING wine_stock_changes s
+ON s.winename = w.winename
+WHEN NOT MATCHED AND s.stock_delta > 0 THEN
+ INSERT VALUES(s.winename, s.stock_delta)
+WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN
+ UPDATE SET stock = w.stock + s.stock_delta
+WHEN MATCHED THEN
+ DELETE;
+</programlisting>
+
+ The <literal>wine_stock_changes</literal> table might be, for example, a
+ temporary table recently loaded into the database.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+ <para>
+ This command conforms to the <acronym>SQL</acronym> standard.
+ </para>
+ <para>
+ The WITH clause and <literal>DO NOTHING</literal> action are extensions to
+ the <acronym>SQL</acronym> standard.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/move.sgml b/doc/src/sgml/ref/move.sgml
new file mode 100644
index 0000000..89b5a24
--- /dev/null
+++ b/doc/src/sgml/ref/move.sgml
@@ -0,0 +1,124 @@
+<!--
+doc/src/sgml/ref/move.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-move">
+ <indexterm zone="sql-move">
+ <primary>MOVE</primary>
+ </indexterm>
+
+ <indexterm zone="sql-move">
+ <primary>cursor</primary>
+ <secondary>MOVE</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>MOVE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>MOVE</refname>
+ <refpurpose>position a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<!-- Note the "direction" bit is also in ref/fetch.sgml -->
+<synopsis>
+MOVE [ <replaceable class="parameter">direction</replaceable> ] [ FROM | IN ] <replaceable class="parameter">cursor_name</replaceable>
+
+<phrase>where <replaceable class="parameter">direction</replaceable> can be one of:</phrase>
+
+ NEXT
+ PRIOR
+ FIRST
+ LAST
+ ABSOLUTE <replaceable class="parameter">count</replaceable>
+ RELATIVE <replaceable class="parameter">count</replaceable>
+ <replaceable class="parameter">count</replaceable>
+ ALL
+ FORWARD
+ FORWARD <replaceable class="parameter">count</replaceable>
+ FORWARD ALL
+ BACKWARD
+ BACKWARD <replaceable class="parameter">count</replaceable>
+ BACKWARD ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>MOVE</command> repositions a cursor without retrieving any data.
+ <command>MOVE</command> works exactly like the <command>FETCH</command>
+ command, except it only positions the cursor and does not return rows.
+ </para>
+
+ <para>
+ The parameters for the <command>MOVE</command> command are identical to
+ those of the <command>FETCH</command> command; refer to
+ <xref linkend="sql-fetch"/>
+ for details on syntax and usage.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, a <command>MOVE</command> command returns a command
+ tag of the form
+<screen>
+MOVE <replaceable class="parameter">count</replaceable>
+</screen>
+ The <replaceable class="parameter">count</replaceable> is the number
+ of rows that a <command>FETCH</command> command with the same parameters
+ would have returned (possibly zero).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+BEGIN WORK;
+DECLARE liahona CURSOR FOR SELECT * FROM films;
+
+-- Skip the first 5 rows:
+MOVE FORWARD 5 IN liahona;
+MOVE 5
+
+-- Fetch the 6th row from the cursor liahona:
+FETCH 1 FROM liahona;
+ code | title | did | date_prod | kind | len
+-------+--------+-----+------------+--------+-------
+ P_303 | 48 Hrs | 103 | 1982-10-22 | Action | 01:37
+(1 row)
+
+-- Close the cursor liahona and end the transaction:
+CLOSE liahona;
+COMMIT WORK;
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>MOVE</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-close"/></member>
+ <member><xref linkend="sql-declare"/></member>
+ <member><xref linkend="sql-fetch"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/notify.sgml b/doc/src/sgml/ref/notify.sgml
new file mode 100644
index 0000000..d7dcbea
--- /dev/null
+++ b/doc/src/sgml/ref/notify.sgml
@@ -0,0 +1,233 @@
+<!--
+doc/src/sgml/ref/notify.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-notify">
+ <indexterm zone="sql-notify">
+ <primary>NOTIFY</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>NOTIFY</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>NOTIFY</refname>
+ <refpurpose>generate a notification</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+NOTIFY <replaceable class="parameter">channel</replaceable> [ , <replaceable class="parameter">payload</replaceable> ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>NOTIFY</command> command sends a notification event together
+ with an optional <quote>payload</quote> string to each client application that
+ has previously executed
+ <command>LISTEN <replaceable class="parameter">channel</replaceable></command>
+ for the specified channel name in the current database.
+ Notifications are visible to all users.
+ </para>
+
+ <para>
+ <command>NOTIFY</command> provides a simple
+ interprocess communication mechanism for a collection of processes
+ accessing the same <productname>PostgreSQL</productname> database.
+ A payload string can be sent along with the notification, and
+ higher-level mechanisms for passing structured data can be built by using
+ tables in the database to pass additional data from notifier to listener(s).
+ </para>
+
+ <para>
+ The information passed to the client for a notification event includes the
+ notification channel
+ name, the notifying session's server process <acronym>PID</acronym>, and the
+ payload string, which is an empty string if it has not been specified.
+ </para>
+
+ <para>
+ It is up to the database designer to define the channel names that will
+ be used in a given database and what each one means.
+ Commonly, the channel name is the same as the name of some table in
+ the database, and the notify event essentially means, <quote>I changed this table,
+ take a look at it to see what's new</quote>. But no such association is enforced by
+ the <command>NOTIFY</command> and <command>LISTEN</command> commands. For
+ example, a database designer could use several different channel names
+ to signal different sorts of changes to a single table. Alternatively,
+ the payload string could be used to differentiate various cases.
+ </para>
+
+ <para>
+ When <command>NOTIFY</command> is used to signal the occurrence of changes
+ to a particular table, a useful programming technique is to put the
+ <command>NOTIFY</command> in a statement trigger that is triggered by table updates.
+ In this way, notification happens automatically when the table is changed,
+ and the application programmer cannot accidentally forget to do it.
+ </para>
+
+ <para>
+ <command>NOTIFY</command> interacts with SQL transactions in some important
+ ways. Firstly, if a <command>NOTIFY</command> is executed inside a
+ transaction, the notify events are not delivered until and unless the
+ transaction is committed. This is appropriate, since if the transaction
+ is aborted, all the commands within it have had no
+ effect, including <command>NOTIFY</command>. But it can be disconcerting if one
+ is expecting the notification events to be delivered immediately. Secondly, if
+ a listening session receives a notification signal while it is within a transaction,
+ the notification event will not be delivered to its connected client until just
+ after the transaction is completed (either committed or aborted). Again, the
+ reasoning is that if a notification were delivered within a transaction that was
+ later aborted, one would want the notification to be undone somehow &mdash;
+ but
+ the server cannot <quote>take back</quote> a notification once it has sent it to the client.
+ So notification events are only delivered between transactions. The upshot of this
+ is that applications using <command>NOTIFY</command> for real-time signaling
+ should try to keep their transactions short.
+ </para>
+
+ <para>
+ If the same channel name is signaled multiple times with identical
+ payload strings within the same transaction, only one instance of the
+ notification event is delivered to listeners.
+ On the other hand, notifications with distinct payload strings will
+ always be delivered as distinct notifications. Similarly, notifications from
+ different transactions will never get folded into one notification.
+ Except for dropping later instances of duplicate notifications,
+ <command>NOTIFY</command> guarantees that notifications from the same
+ transaction get delivered in the order they were sent. It is also
+ guaranteed that messages from different transactions are delivered in
+ the order in which the transactions committed.
+ </para>
+
+ <para>
+ It is common for a client that executes <command>NOTIFY</command>
+ to be listening on the same notification channel itself. In that case
+ it will get back a notification event, just like all the other
+ listening sessions. Depending on the application logic, this could
+ result in useless work, for example, reading a database table to
+ find the same updates that that session just wrote out. It is
+ possible to avoid such extra work by noticing whether the notifying
+ session's server process <acronym>PID</acronym> (supplied in the
+ notification event message) is the same as one's own session's
+ <acronym>PID</acronym> (available from <application>libpq</application>). When they
+ are the same, the notification event is one's own work bouncing
+ back, and can be ignored.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">channel</replaceable></term>
+ <listitem>
+ <para>
+ Name of the notification channel to be signaled (any identifier).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable class="parameter">payload</replaceable></term>
+ <listitem>
+ <para>
+ The <quote>payload</quote> string to be communicated along with the
+ notification. This must be specified as a simple string literal.
+ In the default configuration it must be shorter than 8000 bytes.
+ (If binary data or large amounts of information need to be communicated,
+ it's best to put it in a database table and send the key of the record.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ There is a queue that holds notifications that have been sent but not
+ yet processed by all listening sessions. If this queue becomes full,
+ transactions calling <command>NOTIFY</command> will fail at commit.
+ The queue is quite large (8GB in a standard installation) and should be
+ sufficiently sized for almost every use case. However, no cleanup can take
+ place if a session executes <command>LISTEN</command> and then enters a
+ transaction for a very long time. Once the queue is half full you will see
+ warnings in the log file pointing you to the session that is preventing
+ cleanup. In this case you should make sure that this session ends its
+ current transaction so that cleanup can proceed.
+ </para>
+ <para>
+ The function <function>pg_notification_queue_usage</function> returns the
+ fraction of the queue that is currently occupied by pending notifications.
+ See <xref linkend="functions-info"/> for more information.
+ </para>
+ <para>
+ A transaction that has executed <command>NOTIFY</command> cannot be
+ prepared for two-phase commit.
+ </para>
+
+ <refsect2>
+ <title>pg_notify</title>
+
+ <indexterm>
+ <primary>pg_notify</primary>
+ </indexterm>
+
+ <para>
+ To send a notification you can also use the function
+ <literal><function>pg_notify</function>(<type>text</type>,
+ <type>text</type>)</literal>. The function takes the channel name as the
+ first argument and the payload as the second. The function is much easier
+ to use than the <command>NOTIFY</command> command if you need to work with
+ non-constant channel names and payloads.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Configure and execute a listen/notify sequence from
+ <application>psql</application>:
+
+<programlisting>
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448.
+NOTIFY virtual, 'This is the payload';
+Asynchronous notification "virtual" with payload "This is the payload" received from server process with PID 8448.
+
+LISTEN foo;
+SELECT pg_notify('fo' || 'o', 'pay' || 'load');
+Asynchronous notification "foo" with payload "payload" received from server process with PID 14728.
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>NOTIFY</command> statement in the SQL
+ standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-listen"/></member>
+ <member><xref linkend="sql-unlisten"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_amcheck.sgml b/doc/src/sgml/ref/pg_amcheck.sgml
new file mode 100644
index 0000000..20c2897
--- /dev/null
+++ b/doc/src/sgml/ref/pg_amcheck.sgml
@@ -0,0 +1,652 @@
+<!--
+doc/src/sgml/ref/pg_amcheck.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgamcheck">
+ <indexterm zone="app-pgamcheck">
+ <primary>pg_amcheck</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_amcheck</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_amcheck</refname>
+ <refpurpose>checks for corruption in one or more
+ <productname>PostgreSQL</productname> databases</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_amcheck</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>pg_amcheck</application> supports running
+ <xref linkend="amcheck"/>'s corruption checking functions against one or
+ more databases, with options to select which schemas, tables and indexes to
+ check, which kinds of checking to perform, and whether to perform the checks
+ in parallel, and if so, the number of parallel connections to establish and
+ use.
+ </para>
+
+ <para>
+ Only ordinary and toast table relations, materialized views, sequences, and
+ btree indexes are currently supported. Other relation types are silently
+ skipped.
+ </para>
+
+ <para>
+ If <literal>dbname</literal> is specified, it should be the name of a
+ single database to check, and no other database selection options should
+ be present. Otherwise, if any database selection options are present,
+ all matching databases will be checked. If no such options are present,
+ the default database will be checked. Database selection options include
+ <option>--all</option>, <option>--database</option> and
+ <option>--exclude-database</option>. They also include
+ <option>--relation</option>, <option>--exclude-relation</option>,
+ <option>--table</option>, <option>--exclude-table</option>,
+ <option>--index</option>, and <option>--exclude-index</option>,
+ but only when such options are used with a three-part pattern
+ (e.g. <option>mydb*.myschema*.myrel*</option>). Finally, they include
+ <option>--schema</option> and <option>--exclude-schema</option>
+ when such options are used with a two-part pattern
+ (e.g. <option>mydb*.myschema*</option>).
+ </para>
+
+ <para>
+ <replaceable>dbname</replaceable> can also be a
+ <link linkend="libpq-connstring">connection string</link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ The following command-line options control what is checked:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--all</option></term>
+ <listitem>
+ <para>
+ Check all databases, except for any excluded via
+ <option>--exclude-database</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--database=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Check databases matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>,
+ except for any excluded by <option>--exclude-database</option>.
+ This option can be specified more than once.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-database=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Exclude databases matching the given
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>.
+ This option can be specified more than once.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--index=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Check indexes matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>,
+ unless they are otherwise excluded.
+ This option can be specified more than once.
+ </para>
+ <para>
+ This is similar to the <option>--relation</option> option, except that
+ it applies only to indexes, not to other relation types.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-I <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-index=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Exclude indexes matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>.
+ This option can be specified more than once.
+ </para>
+ <para>
+ This is similar to the <option>--exclude-relation</option> option,
+ except that it applies only to indexes, not other relation types.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--relation=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Check relations matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>,
+ unless they are otherwise excluded.
+ This option can be specified more than once.
+ </para>
+ <para>
+ Patterns may be unqualified, e.g. <literal>myrel*</literal>, or they
+ may be schema-qualified, e.g. <literal>myschema*.myrel*</literal> or
+ database-qualified and schema-qualified, e.g.
+ <literal>mydb*.myschema*.myrel*</literal>. A database-qualified
+ pattern will add matching databases to the list of databases to be
+ checked.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-relation=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Exclude relations matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>.
+ This option can be specified more than once.
+ </para>
+ <para>
+ As with <option>--relation</option>, the
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> may be unqualified, schema-qualified,
+ or database- and schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--schema=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Check tables and indexes in schemas matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>, unless they are otherwise excluded.
+ This option can be specified more than once.
+ </para>
+ <para>
+ To select only tables in schemas matching a particular pattern,
+ consider using something like
+ <literal>--table=SCHEMAPAT.* --no-dependent-indexes</literal>.
+ To select only indexes, consider using something like
+ <literal>--index=SCHEMAPAT.*</literal>.
+ </para>
+ <para>
+ A schema pattern may be database-qualified. For example, you may
+ write <literal>--schema=mydb*.myschema*</literal> to select
+ schemas matching <literal>myschema*</literal> in databases matching
+ <literal>mydb*</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-schema=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Exclude tables and indexes in schemas matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>.
+ This option can be specified more than once.
+ </para>
+ <para>
+ As with <option>--schema</option>, the pattern may be
+ database-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--table=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Check tables matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>,
+ unless they are otherwise excluded.
+ This option can be specified more than once.
+ </para>
+ <para>
+ This is similar to the <option>--relation</option> option, except that
+ it applies only to tables, materialized views, and sequences, not to
+ indexes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-table=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Exclude tables matching the specified
+ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link>.
+ This option can be specified more than once.
+ </para>
+ <para>
+ This is similar to the <option>--exclude-relation</option> option,
+ except that it applies only to tables, materialized views, and
+ sequences, not to indexes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-dependent-indexes</option></term>
+ <listitem>
+ <para>
+ By default, if a table is checked, any btree indexes of that table
+ will also be checked, even if they are not explicitly selected by
+ an option such as <literal>--index</literal> or
+ <literal>--relation</literal>. This option suppresses that behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-dependent-toast</option></term>
+ <listitem>
+ <para>
+ By default, if a table is checked, its toast table, if any, will also
+ be checked, even if it is not explicitly selected by an option
+ such as <literal>--table</literal> or <literal>--relation</literal>.
+ This option suppresses that behavior.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-strict-names</option></term>
+ <listitem>
+ <para>
+ By default, if an argument to <literal>--database</literal>,
+ <literal>--table</literal>, <literal>--index</literal>,
+ or <literal>--relation</literal> matches no objects, it is a fatal
+ error. This option downgrades that error to a warning.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following command-line options control checking of tables:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--exclude-toast-pointers</option></term>
+ <listitem>
+ <para>
+ By default, whenever a toast pointer is encountered in a table,
+ a lookup is performed to ensure that it references apparently-valid
+ entries in the toast table. These checks can be quite slow, and this
+ option can be used to skip them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--on-error-stop</option></term>
+ <listitem>
+ <para>
+ After reporting all corruptions on the first page of a table where
+ corruption is found, stop processing that table relation and move on
+ to the next table or index.
+ </para>
+ <para>
+ Note that index checking always stops after the first corrupt page.
+ This option only has meaning relative to table relations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--skip=<replaceable class="parameter">option</replaceable></option></term>
+ <listitem>
+ <para>
+ If <literal>all-frozen</literal> is given, table corruption checks
+ will skip over pages in all tables that are marked as all frozen.
+ </para>
+ <para>
+ If <literal>all-visible</literal> is given, table corruption checks
+ will skip over pages in all tables that are marked as all visible.
+ </para>
+ <para>
+ By default, no pages are skipped. This can be specified as
+ <literal>none</literal>, but since this is the default, it need not be
+ mentioned.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--startblock=<replaceable class="parameter">block</replaceable></option></term>
+ <listitem>
+ <para>
+ Start checking at the specified block number. An error will occur if
+ the table relation being checked has fewer than this number of blocks.
+ This option does not apply to indexes, and is probably only useful
+ when checking a single table relation. See <literal>--endblock</literal>
+ for further caveats.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--endblock=<replaceable class="parameter">block</replaceable></option></term>
+ <listitem>
+ <para>
+ End checking at the specified block number. An error will occur if the
+ table relation being checked has fewer than this number of blocks.
+ This option does not apply to indexes, and is probably only useful when
+ checking a single table relation. If both a regular table and a toast
+ table are checked, this option will apply to both, but higher-numbered
+ toast blocks may still be accessed while validating toast pointers,
+ unless that is suppressed using
+ <option>--exclude-toast-pointers</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following command-line options control checking of B-tree indexes:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--heapallindexed</option></term>
+ <listitem>
+ <para>
+ For each index checked, verify the presence of all heap tuples as index
+ tuples in the index using <xref linkend="amcheck"/>'s
+ <option>heapallindexed</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--parent-check</option></term>
+ <listitem>
+ <para>
+ For each btree index checked, use <xref linkend="amcheck"/>'s
+ <function>bt_index_parent_check</function> function, which performs
+ additional checks of parent/child relationships during index checking.
+ </para>
+ <para>
+ The default is to use <application>amcheck</application>'s
+ <function>bt_index_check</function> function, but note that use of the
+ <option>--rootdescend</option> option implicitly selects
+ <function>bt_index_parent_check</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--rootdescend</option></term>
+ <listitem>
+ <para>
+ For each index checked, re-find tuples on the leaf level by performing a
+ new search from the root page for each tuple using
+ <xref linkend="amcheck"/>'s <option>rootdescend</option> option.
+ </para>
+ <para>
+ Use of this option implicitly also selects the
+ <option>--parent-check</option> option.
+ </para>
+ <para>
+ This form of verification was originally written to help in the
+ development of btree index features. It may be of limited use or even
+ of no use in helping detect the kinds of corruption that occur in
+ practice. It may also cause corruption checking to take considerably
+ longer and consume considerably more resources on the server.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <warning>
+ <para>
+ The extra checks performed against B-tree indexes when the
+ <option>--parent-check</option> option or the
+ <option>--rootdescend</option> option is specified require
+ relatively strong relation-level locks. These checks are the only
+ checks that will block concurrent data modification from
+ <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> commands.
+ </para>
+ </warning>
+
+ <para>
+ The following command-line options control the connection to the server:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">hostname</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">hostname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is running.
+ If the value begins with a slash, it is used as the directory for the
+ Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file extension on
+ which the server is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U</option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires password
+ authentication and a password is not available by other means such as
+ a <filename>.pgpass</filename> file, the connection attempt will fail.
+ This option can be useful in batch jobs and scripts where no user is
+ present to enter a password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>pg_amcheck</application> to prompt for a password
+ before connecting to a database.
+ </para>
+ <para>
+ This option is never essential, since
+ <application>pg_amcheck</application> will automatically prompt for a
+ password if the server demands password authentication. However,
+ <application>pg_amcheck</application> will waste a connection attempt
+ finding out that the server wants a password. In some cases it is
+ worth typing <option>-W</option> to avoid the extra connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies a database or
+ <link linkend="libpq-connstring">connection string</link> to be
+ used to discover the list of databases to be checked. If neither
+ <option>--all</option> nor any option including a database pattern is
+ used, no such connection is required and this option does nothing.
+ Otherwise, any connection string parameters other than
+ the database name which are included in the value for this option
+ will also be used when connecting to the databases
+ being checked. If this option is omitted, the default is
+ <literal>postgres</literal> or, if that fails,
+ <literal>template1</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Other options are also available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo to stdout all SQL sent to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j <replaceable class="parameter">num</replaceable></option></term>
+ <term><option>--jobs=<replaceable class="parameter">num</replaceable></option></term>
+ <listitem>
+ <para>
+ Use <replaceable>num</replaceable> concurrent connections to the server,
+ or one per object to be checked, whichever is less.
+ </para>
+ <para>
+ The default is to use a single connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+ <term><option>--progress</option></term>
+ <listitem>
+ <para>
+ Show progress information. Progress information includes the number
+ of relations for which checking has been completed, and the total
+ size of those relations. It also includes the total number of relations
+ that will eventually be checked, and the estimated size of those
+ relations.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Print more messages. In particular, this will print a message for
+ each relation being checked, and will increase the level of detail
+ shown for server errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_amcheck</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--install-missing</option></term>
+ <term><option>--install-missing=<replaceable class="parameter">schema</replaceable></option></term>
+ <listitem>
+ <para>
+ Install any missing extensions that are required to check the
+ database(s). If not yet installed, each extension's objects will be
+ installed into the given
+ <replaceable class="parameter">schema</replaceable>, or if not specified
+ into schema <literal>pg_catalog</literal>.
+ </para>
+ <para>
+ At present, the only required extension is <xref linkend="amcheck"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_amcheck</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>pg_amcheck</application> is designed to work with
+ <productname>PostgreSQL</productname> 14.0 and later.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="amcheck"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml
new file mode 100644
index 0000000..a5f63bd
--- /dev/null
+++ b/doc/src/sgml/ref/pg_basebackup.sgml
@@ -0,0 +1,1008 @@
+<!--
+doc/src/sgml/ref/pg_basebackup.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgbasebackup">
+ <indexterm zone="app-pgbasebackup">
+ <primary>pg_basebackup</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_basebackup</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_basebackup</refname>
+ <refpurpose>take a base backup of a <productname>PostgreSQL</productname> cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_basebackup</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ <application>pg_basebackup</application> is used to take a base backup of
+ a running <productname>PostgreSQL</productname> database cluster. The backup
+ is taken without affecting other clients of the database, and can be used
+ both for point-in-time recovery (see <xref linkend="continuous-archiving"/>)
+ and as the starting point for a log-shipping or streaming-replication standby
+ server (see <xref linkend="warm-standby"/>).
+ </para>
+
+ <para>
+ <application>pg_basebackup</application> makes an exact copy of the database
+ cluster's files, while making sure the server is put into and
+ out of backup mode automatically. Backups are always taken of the entire
+ database cluster; it is not possible to back up individual databases or
+ database objects. For selective backups, another tool such as
+ <xref linkend="app-pgdump"/> must be used.
+ </para>
+
+ <para>
+ The backup is made over a regular <productname>PostgreSQL</productname>
+ connection that uses the replication protocol. The connection must be made
+ with a user ID that has <literal>REPLICATION</literal> permissions
+ (see <xref linkend="role-attributes"/>) or is a superuser,
+ and <link linkend="auth-pg-hba-conf"><filename>pg_hba.conf</filename></link>
+ must permit the replication connection. The server must also be configured
+ with <xref linkend="guc-max-wal-senders"/> set high enough to provide at
+ least one walsender for the backup plus one for WAL streaming (if used).
+ </para>
+
+ <para>
+ There can be multiple <command>pg_basebackup</command>s running at the same time, but it is usually
+ better from a performance point of view to take only one backup, and copy
+ the result.
+ </para>
+
+ <para>
+ <application>pg_basebackup</application> can make a base backup from
+ not only a primary server but also a standby. To take a backup from a standby,
+ set up the standby so that it can accept replication connections (that is, set
+ <varname>max_wal_senders</varname> and <xref linkend="guc-hot-standby"/>,
+ and configure its <filename>pg_hba.conf</filename> appropriately).
+ You will also need to enable <xref linkend="guc-full-page-writes"/> on the primary.
+ </para>
+
+ <para>
+ Note that there are some limitations in taking a backup from a standby:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The backup history file is not created in the database cluster backed up.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <application>pg_basebackup</application> cannot force the standby
+ to switch to a new WAL file at the end of backup.
+ When you are using <literal>-X none</literal>, if write activity on
+ the primary is low, <application>pg_basebackup</application> may
+ need to wait a long time for the last WAL file required for the backup
+ to be switched and archived. In this case, it may be useful to run
+ <function>pg_switch_wal</function> on the primary in order to
+ trigger an immediate WAL file switch.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the standby is promoted to be primary during backup, the backup fails.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All WAL records required for the backup must contain sufficient full-page writes,
+ which requires you to enable <varname>full_page_writes</varname> on the primary.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Whenever <application>pg_basebackup</application> is taking a base
+ backup, the server's <structname>pg_stat_progress_basebackup</structname>
+ view will report the progress of the backup.
+ See <xref linkend="basebackup-progress-reporting"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ The following command-line options control the location and format of the
+ output:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">directory</replaceable></option></term>
+ <term><option>--pgdata=<replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the target directory to write the output to.
+ <application>pg_basebackup</application> will create this directory
+ (and any missing parent directories) if it does not exist. If it
+ already exists, it must be empty.
+ </para>
+ <para>
+ When the backup is in tar format, the target directory may be
+ specified as <literal>-</literal> (dash), causing the tar file to be
+ written to <literal>stdout</literal>.
+ </para>
+ <para>
+ This option is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F <replaceable class="parameter">format</replaceable></option></term>
+ <term><option>--format=<replaceable class="parameter">format</replaceable></option></term>
+ <listitem>
+ <para>
+ Selects the format for the output. <replaceable>format</replaceable>
+ can be one of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>p</literal></term>
+ <term><literal>plain</literal></term>
+ <listitem>
+ <para>
+ Write the output as plain files, with the same layout as the
+ source server's data directory and tablespaces. When the cluster has
+ no additional tablespaces, the whole database will be placed in
+ the target directory. If the cluster contains additional
+ tablespaces, the main data directory will be placed in the
+ target directory, but all other tablespaces will be placed
+ in the same absolute path as they have on the source server.
+ (See <option>--tablespace-mapping</option> to change that.)
+ </para>
+ <para>
+ This is the default format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>t</literal></term>
+ <term><literal>tar</literal></term>
+ <listitem>
+ <para>
+ Write the output as tar files in the target directory. The main
+ data directory's contents will be written to a file named
+ <filename>base.tar</filename>, and each other tablespace will be
+ written to a separate tar file named after that tablespace's OID.
+ </para>
+ <para>
+ If the target directory is specified as <literal>-</literal>
+ (dash), the tar contents will be written to
+ standard output, suitable for piping to (for example)
+ <productname>gzip</productname>. This is only allowed if
+ the cluster has no additional tablespaces and WAL
+ streaming is not used.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R</option></term>
+ <term><option>--write-recovery-conf</option></term>
+ <listitem>
+
+ <para>
+ Creates a
+ <link linkend="file-standby-signal"><filename>standby.signal</filename></link>
+ <indexterm><primary><filename>standby.signal</filename></primary><secondary>pg_basebackup --write-recovery-conf</secondary></indexterm>
+ file and appends
+ connection settings to the <filename>postgresql.auto.conf</filename>
+ file in the target directory (or within the base archive file when
+ using tar format). This eases setting up a standby server using the
+ results of the backup.
+ </para>
+ <para>
+ The <filename>postgresql.auto.conf</filename> file will record the connection
+ settings and, if specified, the replication slot
+ that <application>pg_basebackup</application> is using, so that
+ streaming replication will use the same settings later on.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">target</replaceable></option></term>
+ <term><option>--target=<replaceable class="parameter">target</replaceable></option></term>
+ <listitem>
+
+ <para>
+ Instructs the server where to place the base backup. The default target
+ is <literal>client</literal>, which specifies that the backup should
+ be sent to the machine where <application>pg_basebackup</application>
+ is running. If the target is instead set to
+ <literal>server:/some/path</literal>, the backup will be stored on
+ the machine where the server is running in the
+ <literal>/some/path</literal> directory. Storing a backup on the
+ server requires superuser privileges or having privileges of the
+ <literal>pg_write_server_files</literal> role. If the target is set to
+ <literal>blackhole</literal>, the contents are discarded and not
+ stored anywhere. This should only be used for testing purposes, as you
+ will not end up with an actual backup.
+ </para>
+
+ <para>
+ Since WAL streaming is implemented by
+ <application>pg_basebackup</application> rather than by the server,
+ this option cannot be used together with <literal>-Xstream</literal>.
+ Since that is the default, when this option is specified, you must also
+ specify either <literal>-Xfetch</literal> or <literal>-Xnone</literal>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable class="parameter">olddir</replaceable>=<replaceable class="parameter">newdir</replaceable></option></term>
+ <term><option>--tablespace-mapping=<replaceable class="parameter">olddir</replaceable>=<replaceable class="parameter">newdir</replaceable></option></term>
+ <listitem>
+ <para>
+ Relocates the tablespace in directory <replaceable>olddir</replaceable>
+ to <replaceable>newdir</replaceable> during the backup. To be
+ effective, <replaceable>olddir</replaceable> must exactly match the
+ path specification of the tablespace as it is defined on the source
+ server. (But it is not an error if there is no tablespace
+ in <replaceable>olddir</replaceable> on the source server.)
+ Meanwhile <replaceable>newdir</replaceable> is a directory in the
+ receiving host's filesystem. As with the main target directory,
+ <replaceable>newdir</replaceable> need not exist already, but if
+ it does exist it must be empty.
+ Both <replaceable>olddir</replaceable>
+ and <replaceable>newdir</replaceable> must be absolute paths. If
+ either path needs to contain an equal sign (<literal>=</literal>),
+ precede that with a backslash. This option can be specified multiple
+ times for multiple tablespaces.
+ </para>
+
+ <para>
+ If a tablespace is relocated in this way, the symbolic links inside
+ the main data directory are updated to point to the new location. So
+ the new data directory is ready to be used for a new server instance
+ with all tablespaces in the updated locations.
+ </para>
+
+ <para>
+ Currently, this option only works with plain output format; it is
+ ignored if tar format is selected.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--waldir=<replaceable class="parameter">waldir</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the directory to write WAL (write-ahead log) files to.
+ By default WAL files will be placed in
+ the <filename>pg_wal</filename> subdirectory of the target
+ directory, but this option can be used to place them elsewhere.
+ <replaceable>waldir</replaceable> must be an absolute path.
+ As with the main target directory,
+ <replaceable>waldir</replaceable> need not exist already, but if
+ it does exist it must be empty.
+ This option can only be specified when
+ the backup is in plain format.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-X <replaceable class="parameter">method</replaceable></option></term>
+ <term><option>--wal-method=<replaceable class="parameter">method</replaceable></option></term>
+ <listitem>
+ <para>
+ Includes the required WAL (write-ahead log) files in the
+ backup. This will include all write-ahead logs generated during
+ the backup. Unless the method <literal>none</literal> is specified,
+ it is possible to start a postmaster in the target
+ directory without the need to consult the log archive, thus
+ making the output a completely standalone backup.
+ </para>
+ <para>
+ The following <replaceable>method</replaceable>s for collecting the
+ write-ahead logs are supported:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>n</literal></term>
+ <term><literal>none</literal></term>
+ <listitem>
+ <para>
+ Don't include write-ahead logs in the backup.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>f</literal></term>
+ <term><literal>fetch</literal></term>
+ <listitem>
+ <para>
+ The write-ahead log files are collected at the end of the backup.
+ Therefore, it is necessary for the source server's
+ <xref linkend="guc-wal-keep-size"/> parameter to be set high
+ enough that the required log data is not removed before the end
+ of the backup. If the required log data has been recycled
+ before it's time to transfer it, the backup will fail and be
+ unusable.
+ </para>
+ <para>
+ When tar format is used, the write-ahead log files will be
+ included in the <filename>base.tar</filename> file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>s</literal></term>
+ <term><literal>stream</literal></term>
+ <listitem>
+ <para>
+ Stream write-ahead log data while the backup is being taken.
+ This method will open a second connection to the server and
+ start streaming the write-ahead log in parallel while running
+ the backup. Therefore, it will require two replication
+ connections not just one. As long as the client can keep up
+ with the write-ahead log data, using this method requires no
+ extra write-ahead logs to be saved on the source server.
+ </para>
+ <para>
+ When tar format is used, the write-ahead log files will be
+ written to a separate file named <filename>pg_wal.tar</filename>
+ (if the server is a version earlier than 10, the file will be named
+ <filename>pg_xlog.tar</filename>).
+ </para>
+ <para>
+ This value is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-z</option></term>
+ <term><option>--gzip</option></term>
+ <listitem>
+ <para>
+ Enables gzip compression of tar file output, with the default
+ compression level. Compression is only available when using
+ the tar format, and the suffix <filename>.gz</filename> will
+ automatically be added to all tar filenames.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-Z <replaceable class="parameter">level</replaceable></option></term>
+ <term><option>-Z [{client|server}-]<replaceable class="parameter">method</replaceable>[:<replaceable>detail</replaceable>]</option></term>
+ <term><option>--compress=<replaceable class="parameter">level</replaceable></option></term>
+ <term><option>--compress=[{client|server}-]<replaceable class="parameter">method</replaceable>[:<replaceable>detail</replaceable>]</option></term>
+ <listitem>
+ <para>
+ Requests compression of the backup. If <literal>client</literal> or
+ <literal>server</literal> is included, it specifies where the
+ compression is to be performed. Compressing on the server will reduce
+ transfer bandwidth but will increase server CPU consumption. The
+ default is <literal>client</literal> except when
+ <literal>--target</literal> is used. In that case, the backup is not
+ being sent to the client, so only server compression is sensible.
+ When <literal>-Xstream</literal>, which is the default, is used,
+ server-side compression will not be applied to the WAL. To compress
+ the WAL, use client-side compression, or
+ specify <literal>-Xfetch</literal>.
+ </para>
+ <para>
+ The compression method can be set to <literal>gzip</literal>,
+ <literal>lz4</literal>, <literal>zstd</literal>, or
+ <literal>none</literal> for no compression. A compression detail
+ string can optionally be specified. If the detail string is an
+ integer, it specifies the compression level. Otherwise, it should be
+ a comma-separated list of items, each of the form
+ <literal>keyword</literal> or <literal>keyword=value</literal>.
+ Currently, the supported keywords are <literal>level</literal>
+ and <literal>workers</literal>.
+ </para>
+ <para>
+ If no compression level is specified, the default compression level
+ will be used. If only a level is specified without mentioning an
+ algorithm, <literal>gzip</literal> compression will be used if the
+ level is greater than 0, and no compression will be used if the level
+ is 0.
+ </para>
+ <para>
+ When the tar format is used with <literal>gzip</literal>,
+ <literal>lz4</literal>, or <literal>zstd</literal>, the suffix
+ <filename>.gz</filename>, <filename>.lz4</filename>, or
+ <filename>.zst</filename>, respectively, will be automatically added to
+ all tar filenames. When the plain format is used, client-side
+ compression may not be specified, but it is still possible to request
+ server-side compression. If this is done, the server will compress the
+ backup for transmission, and the client will decompress and extract it.
+ </para>
+ <para>
+ When this option is used in combination with
+ <literal>-Xstream</literal>, <literal>pg_wal.tar</literal> will
+ be compressed using <literal>gzip</literal> if client-side gzip
+ compression is selected, but will not be compressed if any other
+ compression algorithm is selected, or if server-side compression
+ is selected.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ <para>
+ The following command-line options control the generation of the
+ backup and the invocation of the program:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-c {fast|spread}</option></term>
+ <term><option>--checkpoint={fast|spread}</option></term>
+ <listitem>
+ <para>
+ Sets checkpoint mode to fast (immediate) or spread (the default)
+ (see <xref linkend="backup-lowlevel-base-backup"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C</option></term>
+ <term><option>--create-slot</option></term>
+ <listitem>
+ <para>
+ Specifies that the replication slot named by the
+ <literal>--slot</literal> option should be created before starting
+ the backup. An error is raised if the slot already exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l <replaceable class="parameter">label</replaceable></option></term>
+ <term><option>--label=<replaceable class="parameter">label</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the label for the backup. If none is specified, a default value of
+ <quote><literal>pg_basebackup base backup</literal></quote> will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-clean</option></term>
+ <listitem>
+ <para>
+ By default, when <command>pg_basebackup</command> aborts with an
+ error, it removes any directories it might have created before
+ discovering that it cannot finish the job (for example, the target
+ directory and write-ahead log directory). This option inhibits
+ tidying-up and is thus useful for debugging.
+ </para>
+
+ <para>
+ Note that tablespace directories are not cleaned up either way.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>pg_basebackup</command> will wait for all files
+ to be written safely to disk. This option causes
+ <command>pg_basebackup</command> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the base backup corrupt. Generally, this option is useful for testing
+ but should not be used when creating a production installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+ <term><option>--progress</option></term>
+ <listitem>
+ <para>
+ Enables progress reporting. Turning this on will deliver an approximate
+ progress report during the backup. Since the database may change during
+ the backup, this is only an approximation and may not end at exactly
+ <literal>100%</literal>. In particular, when WAL log is included in the
+ backup, the total amount of data cannot be estimated in advance, and
+ in this case the estimated target size will increase once it passes the
+ total estimate without WAL.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r <replaceable class="parameter">rate</replaceable></option></term>
+ <term><option>--max-rate=<replaceable class="parameter">rate</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the maximum transfer rate at which data is collected from the
+ source server. This can be useful to limit the impact
+ of <application>pg_basebackup</application> on the server. Values
+ are in kilobytes per second. Use a suffix of <literal>M</literal>
+ to indicate megabytes per second. A suffix of <literal>k</literal>
+ is also accepted, and has no effect. Valid values are between 32
+ kilobytes per second and 1024 megabytes per second.
+ </para>
+ <para>
+ This option always affects transfer of the data directory. Transfer of
+ WAL files is only affected if the collection method
+ is <literal>fetch</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable>slotname</replaceable></option></term>
+ <term><option>--slot=<replaceable class="parameter">slotname</replaceable></option></term>
+ <listitem>
+ <para>
+ This option can only be used together with <literal>-X
+ stream</literal>. It causes WAL streaming to use the specified
+ replication slot. If the base backup is intended to be used as a
+ streaming-replication standby using a replication slot, the standby
+ should then use the same replication slot name as
+ <xref linkend="guc-primary-slot-name"/>. This ensures that the
+ primary server does not remove any necessary WAL data in the time
+ between the end of the base backup and the start of streaming
+ replication on the new standby.
+ </para>
+ <para>
+ The specified replication slot has to exist unless the
+ option <option>-C</option> is also used.
+ </para>
+ <para>
+ If this option is not specified and the server supports temporary
+ replication slots (version 10 and later), then a temporary replication
+ slot is automatically used for WAL streaming.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Enables verbose mode. Will output some extra steps during startup and
+ shutdown, as well as show the exact file name that is currently being
+ processed if progress reporting is also enabled.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--manifest-checksums=<replaceable class="parameter">algorithm</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the checksum algorithm that should be applied to each file
+ included in the backup manifest. Currently, the available
+ algorithms are <literal>NONE</literal>, <literal>CRC32C</literal>,
+ <literal>SHA224</literal>, <literal>SHA256</literal>,
+ <literal>SHA384</literal>, and <literal>SHA512</literal>.
+ The default is <literal>CRC32C</literal>.
+ </para>
+ <para>
+ If <literal>NONE</literal> is selected, the backup manifest will
+ not contain any checksums. Otherwise, it will contain a checksum
+ of each file in the backup using the specified algorithm. In addition,
+ the manifest will always contain a <literal>SHA256</literal>
+ checksum of its own contents. The <literal>SHA</literal> algorithms
+ are significantly more CPU-intensive than <literal>CRC32C</literal>,
+ so selecting one of them may increase the time required to complete
+ the backup.
+ </para>
+ <para>
+ Using a SHA hash function provides a cryptographically secure digest
+ of each file for users who wish to verify that the backup has not been
+ tampered with, while the CRC32C algorithm provides a checksum that is
+ much faster to calculate; it is good at catching errors due to accidental
+ changes but is not resistant to malicious modifications. Note that, to
+ be useful against an adversary who has access to the backup, the backup
+ manifest would need to be stored securely elsewhere or otherwise
+ verified not to have been modified since the backup was taken.
+ </para>
+ <para>
+ <xref linkend="app-pgverifybackup"/> can be used to check the
+ integrity of a backup against the backup manifest.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--manifest-force-encode</option></term>
+ <listitem>
+ <para>
+ Forces all filenames in the backup manifest to be hex-encoded.
+ If this option is not specified, only non-UTF8 filenames are
+ hex-encoded. This option is mostly intended to test that tools which
+ read a backup manifest file properly handle this case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-estimate-size</option></term>
+ <listitem>
+ <para>
+ Prevents the server from estimating the total
+ amount of backup data that will be streamed, resulting in the
+ <structfield>backup_total</structfield> column in the
+ <structname>pg_stat_progress_basebackup</structname> view
+ always being <literal>NULL</literal>.
+ </para>
+ <para>
+ Without this option, the backup will start by enumerating
+ the size of the entire database, and then go back and send
+ the actual contents. This may make the backup take slightly
+ longer, and in particular it will take longer before the first
+ data is sent. This option is useful to avoid such estimation
+ time if it's too long.
+ </para>
+ <para>
+ This option is not allowed when using <option>--progress</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-manifest</option></term>
+ <listitem>
+ <para>
+ Disables generation of a backup manifest. If this option is not
+ specified, the server will generate and send a backup manifest
+ which can be verified using <xref linkend="app-pgverifybackup"/>.
+ The manifest is a list of every file present in the backup with the
+ exception of any WAL files that may be included. It also stores the
+ size, last modification time, and an optional checksum for each file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-slot</option></term>
+ <listitem>
+ <para>
+ Prevents the creation of a temporary replication slot
+ for the backup.
+ </para>
+ <para>
+ By default, if log streaming is selected but no slot name is given
+ with the <option>-S</option> option, then a temporary replication
+ slot is created (if supported by the source server).
+ </para>
+ <para>
+ The main purpose of this option is to allow taking a base backup when
+ the server has no free replication slots. Using a replication slot
+ is almost always preferred, because it prevents needed WAL from being
+ removed by the server during the backup.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-verify-checksums</option></term>
+ <listitem>
+ <para>
+ Disables verification of checksums, if they are enabled on the server
+ the base backup is taken from.
+ </para>
+ <para>
+ By default, checksums are verified and checksum failures will result
+ in a non-zero exit status. However, the base backup will not be
+ removed in such a case, as if the <option>--no-clean</option> option
+ had been used. Checksum verification failures will also be reported
+ in the <link linkend="monitoring-pg-stat-database-view">
+ <structname>pg_stat_database</structname></link> view.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following command-line options control the connection to the source
+ server:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies parameters used to connect to the server, as a <link
+ linkend="libpq-connstring">connection string</link>; these
+ will override any conflicting command line options.
+ </para>
+ <para>
+ The option is called <literal>--dbname</literal> for consistency with other
+ client applications, but because <application>pg_basebackup</application>
+ doesn't connect to any particular database in the cluster, any database
+ name in the connection string will be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for a Unix domain socket. The default is taken
+ from the <envar>PGHOST</envar> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <envar>PGPORT</envar> environment variable, if
+ set, or a compiled-in default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s <replaceable class="parameter">interval</replaceable></option></term>
+ <term><option>--status-interval=<replaceable class="parameter">interval</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the number of seconds between status packets sent back to
+ the source server. Smaller values allow more accurate monitoring of
+ backup progress from the server.
+ A value of zero disables periodic status updates completely,
+ although an update will still be sent when requested by the server, to
+ avoid timeout-based disconnects. The default value is 10 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the user name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Prevents issuing a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Forces <application>pg_basebackup</application> to prompt for a
+ password before connecting to the source server.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>pg_basebackup</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>pg_basebackup</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Other options are also available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Prints the <application>pg_basebackup</application> version and exits.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Shows help about <application>pg_basebackup</application> command line
+ arguments, and exits.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ At the beginning of the backup, a checkpoint needs to be performed on the
+ source server. This can take some time (especially if the option
+ <literal>--checkpoint=fast</literal> is not used), during
+ which <application>pg_basebackup</application> will appear to be idle.
+ </para>
+
+ <para>
+ The backup will include all files in the data directory and tablespaces,
+ including the configuration files and any additional files placed in the
+ directory by third parties, except certain temporary files managed by
+ PostgreSQL. But only regular files and directories are copied, except that
+ symbolic links used for tablespaces are preserved. Symbolic links pointing
+ to certain directories known to PostgreSQL are copied as empty directories.
+ Other symbolic links and special device files are skipped.
+ See <xref linkend="protocol-replication"/> for the precise details.
+ </para>
+
+ <para>
+ In plain format, tablespaces will be backed up to the same path
+ they have on the source server, unless the
+ option <literal>--tablespace-mapping</literal> is used. Without
+ this option, running a plain format base backup on the same host as the
+ server will not work if tablespaces are in use, because the backup would
+ have to be written to the same directory locations as the original
+ tablespaces.
+ </para>
+
+ <para>
+ When tar format is used, it is the user's responsibility to unpack each
+ tar file before starting a PostgreSQL server that uses the data. If there
+ are additional tablespaces, the
+ tar files for them need to be unpacked in the correct locations. In this
+ case the symbolic links for those tablespaces will be created by the server
+ according to the contents of the <filename>tablespace_map</filename> file that is
+ included in the <filename>base.tar</filename> file.
+ </para>
+
+ <para>
+ <application>pg_basebackup</application> works with servers of the same
+ or an older major version, down to 9.1. However, WAL streaming mode (<literal>-X
+ stream</literal>) only works with server version 9.3 and later, and tar format
+ (<literal>--format=tar</literal>) only works with server version 9.5
+ and later.
+ </para>
+
+ <para>
+ <application>pg_basebackup</application> will preserve group permissions
+ for data files if group permissions are enabled on the source cluster.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create a base backup of the server at <literal>mydbserver</literal>
+ and store it in the local directory
+ <filename>/usr/local/pgsql/data</filename>:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -h mydbserver -D /usr/local/pgsql/data</userinput>
+</screen>
+ </para>
+
+ <para>
+ To create a backup of the local server with one compressed
+ tar file for each tablespace, and store it in the directory
+ <filename>backup</filename>, showing a progress report while running:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -D backup -Ft -z -P</userinput>
+</screen>
+ </para>
+
+ <para>
+ To create a backup of a single-tablespace local database and compress
+ this with <productname>bzip2</productname>:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -D - -Ft -X fetch | bzip2 &gt; backup.tar.bz2</userinput>
+</screen>
+ (This command will fail if there are multiple tablespaces in the
+ database.)
+ </para>
+
+ <para>
+ To create a backup of a local database where the tablespace in
+ <filename>/opt/ts</filename> is relocated
+ to <filename>./backup/ts</filename>:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -D backup/data -T /opt/ts=$(pwd)/backup/ts</userinput>
+</screen></para>
+
+ <para>
+ To create a backup of a local server with one tar file for each tablespace
+ compressed with <application>gzip</application> at level 9, stored in the
+ directory <filename>backup</filename>:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -D backup -Ft --compress=gzip:9</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pgdump"/></member>
+ <member><xref linkend="basebackup-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_checksums.sgml b/doc/src/sgml/ref/pg_checksums.sgml
new file mode 100644
index 0000000..bab9501
--- /dev/null
+++ b/doc/src/sgml/ref/pg_checksums.sgml
@@ -0,0 +1,229 @@
+<!--
+doc/src/sgml/ref/pg_checksums.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgchecksums">
+ <indexterm zone="app-pgchecksums">
+ <primary>pg_checksums</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_checksums</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_checksums</refname>
+ <refpurpose>enable, disable or check data checksums in a <productname>PostgreSQL</productname> database cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_checksums</command>
+ <arg rep="repeat" choice="opt"><replaceable class="parameter">option</replaceable></arg>
+ <group choice="opt">
+ <group choice="opt">
+ <arg choice="plain"><option>-D</option></arg>
+ <arg choice="plain"><option>--pgdata</option></arg>
+ </group>
+ <replaceable class="parameter">datadir</replaceable>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="r1-app-pg_checksums-1">
+ <title>Description</title>
+ <para>
+ <application>pg_checksums</application> checks, enables or disables data
+ checksums in a <productname>PostgreSQL</productname> cluster. The server
+ must be shut down cleanly before running
+ <application>pg_checksums</application>. When verifying checksums, the exit
+ status is zero if there are no checksum errors, and nonzero if at least one
+ checksum failure is detected. When enabling or disabling checksums, the
+ exit status is nonzero if the operation failed.
+ </para>
+
+ <para>
+ When verifying checksums, every file in the cluster is scanned. When
+ enabling checksums, each relation file block with a changed checksum is
+ rewritten in-place.
+ Disabling checksums only updates the file <filename>pg_control</filename>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ The following command-line options are available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-D <replaceable>directory</replaceable></option></term>
+ <term><option>--pgdata=<replaceable>directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the directory where the database cluster is stored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--check</option></term>
+ <listitem>
+ <para>
+ Checks checksums. This is the default mode if nothing else is
+ specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d</option></term>
+ <term><option>--disable</option></term>
+ <listitem>
+ <para>
+ Disables checksums.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--enable</option></term>
+ <listitem>
+ <para>
+ Enables checksums.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f <replaceable>filenode</replaceable></option></term>
+ <term><option>--filenode=<replaceable>filenode</replaceable></option></term>
+ <listitem>
+ <para>
+ Only validate checksums in the relation with filenode
+ <replaceable>filenode</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>pg_checksums</command> will wait for all files
+ to be written safely to disk. This option causes
+ <command>pg_checksums</command> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the updated data directory corrupt. Generally, this option is useful
+ for testing but should not be used on a production installation.
+ This option has no effect when using <literal>--check</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+ <term><option>--progress</option></term>
+ <listitem>
+ <para>
+ Enable progress reporting. Turning this on will deliver a progress
+ report while checking or enabling checksums.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Enable verbose output. Lists all checked files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_checksums</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_checksums</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATA</envar></term>
+
+ <listitem>
+ <para>
+ Specifies the directory where the database cluster is
+ stored; can be overridden using the <option>-D</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ Enabling checksums in a large cluster can potentially take a long time.
+ During this operation, the cluster or other programs that write to the
+ data directory must not be started or else data loss may occur.
+ </para>
+ <para>
+ When using a replication setup with tools which perform direct copies
+ of relation file blocks (for example <xref linkend="app-pgrewind"/>),
+ enabling or disabling checksums can lead to page corruptions in the
+ shape of incorrect checksums if the operation is not done consistently
+ across all nodes. When enabling or disabling checksums in a replication
+ setup, it is thus recommended to stop all the clusters before switching
+ them all consistently. Destroying all standbys, performing the operation
+ on the primary and finally recreating the standbys from scratch is also
+ safe.
+ </para>
+ <para>
+ If <application>pg_checksums</application> is aborted or killed while
+ enabling or disabling checksums, the cluster's data checksum configuration
+ remains unchanged, and <application>pg_checksums</application> can be
+ re-run to perform the same operation.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_config-ref.sgml b/doc/src/sgml/ref/pg_config-ref.sgml
new file mode 100644
index 0000000..e177769
--- /dev/null
+++ b/doc/src/sgml/ref/pg_config-ref.sgml
@@ -0,0 +1,332 @@
+<!--
+doc/src/sgml/ref/pg_config-ref.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgconfig">
+ <indexterm zone="app-pgconfig">
+ <primary>pg_config</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_config</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_config</refname>
+ <refpurpose>retrieve information about the installed version of <productname>PostgreSQL</productname></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_config</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ The <application>pg_config</application> utility prints configuration parameters
+ of the currently installed version of <productname>PostgreSQL</productname>. It is
+ intended, for example, to be used by software packages that want to interface
+ to <productname>PostgreSQL</productname> to facilitate finding the required header files
+ and libraries.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ To use <application>pg_config</application>, supply one or more of the following
+ options:
+ <variablelist>
+ <varlistentry>
+ <term><option>--bindir</option></term>
+ <listitem>
+ <para>
+ Print the location of user executables. Use this, for example, to find
+ the <command>psql</command> program. This is normally also the location
+ where the <filename>pg_config</filename> program resides.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--docdir</option></term>
+ <listitem>
+ <para>
+ Print the location of documentation files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--htmldir</option></term>
+ <listitem>
+ <para>
+ Print the location of HTML documentation files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--includedir</option></term>
+ <listitem>
+ <para>
+ Print the location of C header files of the client interfaces.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--pkgincludedir</option></term>
+ <listitem>
+ <para>
+ Print the location of other C header files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--includedir-server</option></term>
+ <listitem>
+ <para>
+ Print the location of C header files for server programming.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--libdir</option></term>
+ <listitem>
+ <para>
+ Print the location of object code libraries.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--pkglibdir</option></term>
+ <listitem>
+ <para>
+ Print the location of dynamically loadable modules, or where
+ the server would search for them. (Other
+ architecture-dependent data files might also be installed in this
+ directory.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--localedir</option></term>
+ <listitem>
+ <para>
+ Print the location of locale support files. (This will be an empty
+ string if locale support was not configured when
+ <productname>PostgreSQL</productname> was built.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--mandir</option></term>
+ <listitem>
+ <para>
+ Print the location of manual pages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--sharedir</option></term>
+ <listitem>
+ <para>
+ Print the location of architecture-independent support files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--sysconfdir</option></term>
+ <listitem>
+ <para>
+ Print the location of system-wide configuration files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--pgxs</option></term>
+ <listitem>
+ <para>
+ Print the location of extension makefiles.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--configure</option></term>
+ <listitem>
+ <para>
+ Print the options that were given to the <filename>configure</filename>
+ script when <productname>PostgreSQL</productname> was configured for building.
+ This can be used to reproduce the identical configuration, or
+ to find out with what options a binary package was built. (Note
+ however that binary packages often contain vendor-specific custom
+ patches.) See also the examples below.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--cc</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>CC</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows the C compiler used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--cppflags</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>CPPFLAGS</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows C compiler switches needed
+ at preprocessing time (typically, <literal>-I</literal> switches).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--cflags</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>CFLAGS</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows C compiler switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--cflags_sl</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>CFLAGS_SL</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows extra C compiler switches
+ used for building shared libraries.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--ldflags</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>LDFLAGS</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows linker switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--ldflags_ex</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>LDFLAGS_EX</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows linker switches
+ used for building executables only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--ldflags_sl</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>LDFLAGS_SL</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This shows linker switches
+ used for building shared libraries only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--libs</option></term>
+ <listitem>
+ <para>
+ Print the value of the <varname>LIBS</varname> variable that was used for building
+ <productname>PostgreSQL</productname>. This normally contains <literal>-l</literal>
+ switches for external libraries linked into <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the version of <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_config</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ If more than one option is given, the information is printed in that order,
+ one item per line. If no options are given, all available information
+ is printed, with labels.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The options <option>--docdir</option>, <option>--pkgincludedir</option>,
+ <option>--localedir</option>, <option>--mandir</option>,
+ <option>--sharedir</option>, <option>--sysconfdir</option>,
+ <option>--cc</option>, <option>--cppflags</option>,
+ <option>--cflags</option>, <option>--cflags_sl</option>,
+ <option>--ldflags</option>, <option>--ldflags_sl</option>,
+ and <option>--libs</option> were added in <productname>PostgreSQL</productname> 8.1.
+ The option <option>--htmldir</option> was added in <productname>PostgreSQL</productname> 8.4.
+ The option <option>--ldflags_ex</option> was added in <productname>PostgreSQL</productname> 9.0.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Example</title>
+
+ <para>
+ To reproduce the build configuration of the current PostgreSQL
+ installation, run the following command:
+<programlisting>
+eval ./configure `pg_config --configure`
+</programlisting>
+ The output of <literal>pg_config --configure</literal> contains
+ shell quotation marks so arguments with spaces are represented
+ correctly. Therefore, using <literal>eval</literal> is required
+ for proper results.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_controldata.sgml b/doc/src/sgml/ref/pg_controldata.sgml
new file mode 100644
index 0000000..b47fdca
--- /dev/null
+++ b/doc/src/sgml/ref/pg_controldata.sgml
@@ -0,0 +1,84 @@
+<!--
+doc/src/sgml/ref/pg_controldata.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgcontroldata">
+ <indexterm zone="app-pgcontroldata">
+ <primary>pg_controldata</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_controldata</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_controldata</refname>
+ <refpurpose>display control information of a <productname>PostgreSQL</productname> database cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_controldata</command>
+ <arg choice="opt"><replaceable class="parameter">option</replaceable></arg>
+ <group choice="opt">
+ <group choice="opt">
+ <arg choice="plain"><option>-D</option></arg>
+ <arg choice="plain"><option>--pgdata</option></arg>
+ </group>
+ <replaceable class="parameter">datadir</replaceable>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="r1-app-pgcontroldata-1">
+ <title>Description</title>
+ <para>
+ <command>pg_controldata</command> prints information initialized during
+ <command>initdb</command>, such as the catalog version.
+ It also shows information about write-ahead logging and checkpoint
+ processing. This information is cluster-wide, and not specific to any one
+ database.
+ </para>
+
+ <para>
+ This utility can only be run by the user who initialized the cluster because
+ it requires read access to the data directory.
+ You can specify the data directory on the command line, or use
+ the environment variable <envar>PGDATA</envar>. This utility supports the options
+ <option>-V</option> and <option>--version</option>, which print the
+ <application>pg_controldata</application> version and exit. It also
+ supports options <option>-?</option> and <option>--help</option>, which output the
+ supported arguments.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATA</envar></term>
+
+ <listitem>
+ <para>
+ Default data directory location
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml
new file mode 100644
index 0000000..4690696
--- /dev/null
+++ b/doc/src/sgml/ref/pg_ctl-ref.sgml
@@ -0,0 +1,713 @@
+<!--
+doc/src/sgml/ref/pg_ctl-ref.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pg-ctl">
+ <indexterm zone="app-pg-ctl">
+ <primary>pg_ctl</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_ctl</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_ctl</refname>
+ <refpurpose>initialize, start, stop, or control a <productname>PostgreSQL</productname> server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>init[db]</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ <arg choice="opt"><option>-o</option> <replaceable>initdb-options</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>start</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-l</option> <replaceable>filename</replaceable></arg>
+ <arg choice="opt"><option>-W</option></arg>
+ <arg choice="opt"><option>-t</option> <replaceable>seconds</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ <arg choice="opt"><option>-o</option> <replaceable>options</replaceable></arg>
+ <arg choice="opt"><option>-p</option> <replaceable>path</replaceable></arg>
+ <arg choice="opt"><option>-c</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>stop</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-m</option>
+ <group choice="plain">
+ <arg choice="plain"><option>s[mart]</option></arg>
+ <arg choice="plain"><option>f[ast]</option></arg>
+ <arg choice="plain"><option>i[mmediate]</option></arg>
+ </group>
+ </arg>
+ <arg choice="opt"><option>-W</option></arg>
+ <arg choice="opt"><option>-t</option> <replaceable>seconds</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>restart</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-m</option>
+ <group choice="plain">
+ <arg choice="plain"><option>s[mart]</option></arg>
+ <arg choice="plain"><option>f[ast]</option></arg>
+ <arg choice="plain"><option>i[mmediate]</option></arg>
+ </group>
+ </arg>
+ <arg choice="opt"><option>-W</option></arg>
+ <arg choice="opt"><option>-t</option> <replaceable>seconds</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ <arg choice="opt"><option>-o</option> <replaceable>options</replaceable></arg>
+ <arg choice="opt"><option>-c</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>reload</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>status</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>promote</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-W</option></arg>
+ <arg choice="opt"><option>-t</option> <replaceable>seconds</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>logrotate</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>kill</option></arg>
+ <arg choice="plain"><replaceable>signal_name</replaceable></arg>
+ <arg choice="plain"><replaceable>process_id</replaceable></arg>
+ </cmdsynopsis>
+
+ <para>On Microsoft Windows, also:</para>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>register</option></arg>
+ <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
+ <arg choice="opt"><option>-N</option> <replaceable>servicename</replaceable></arg>
+ <arg choice="opt"><option>-U</option> <replaceable>username</replaceable></arg>
+ <arg choice="opt"><option>-P</option> <replaceable>password</replaceable></arg>
+ <arg choice="opt"><option>-S</option>
+ <group choice="plain">
+ <arg choice="plain"><option>a[uto]</option></arg>
+ <arg choice="plain"><option>d[emand]</option></arg>
+ </group>
+ </arg>
+ <arg choice="opt"><option>-e</option> <replaceable>source</replaceable></arg>
+ <arg choice="opt"><option>-W</option></arg>
+ <arg choice="opt"><option>-t</option> <replaceable>seconds</replaceable></arg>
+ <arg choice="opt"><option>-s</option></arg>
+ <arg choice="opt"><option>-o</option> <replaceable>options</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>pg_ctl</command>
+ <arg choice="plain"><option>unregister</option></arg>
+ <arg choice="opt"><option>-N</option> <replaceable>servicename</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="app-pg-ctl-description">
+ <title>Description</title>
+ <para>
+ <application>pg_ctl</application> is a utility for initializing a
+ <productname>PostgreSQL</productname> database cluster, starting,
+ stopping, or restarting the <productname>PostgreSQL</productname>
+ database server (<xref linkend="app-postgres"/>), or displaying the
+ status of a running server. Although the server can be started
+ manually, <application>pg_ctl</application> encapsulates tasks such
+ as redirecting log output and properly detaching from the terminal
+ and process group. It also provides convenient options for
+ controlled shutdown.
+ </para>
+
+ <para>
+ The <option>init</option> or <option>initdb</option> mode creates a new
+ <productname>PostgreSQL</productname> database cluster, that is,
+ a collection of databases that will be managed by a single
+ server instance. This mode invokes the <command>initdb</command>
+ command. See <xref linkend="app-initdb"/> for details.
+ </para>
+
+ <para>
+ <option>start</option> mode launches a new server. The
+ server is started in the background, and its standard input is attached
+ to <filename>/dev/null</filename> (or <literal>nul</literal> on Windows).
+ On Unix-like systems, by default, the server's standard output and
+ standard error are sent to <application>pg_ctl</application>'s
+ standard output (not standard error). The standard output of
+ <application>pg_ctl</application> should then be redirected to a
+ file or piped to another process such as a log rotating program
+ like <application>rotatelogs</application>; otherwise <command>postgres</command>
+ will write its output to the controlling terminal (from the
+ background) and will not leave the shell's process group. On
+ Windows, by default the server's standard output and standard error
+ are sent to the terminal. These default behaviors can be changed
+ by using <option>-l</option> to append the server's output to a log file.
+ Use of either <option>-l</option> or output redirection is recommended.
+ </para>
+
+ <para>
+ <option>stop</option> mode shuts down the server that is running in
+ the specified data directory. Three different
+ shutdown methods can be selected with the <option>-m</option>
+ option. <quote>Smart</quote> mode disallows new connections, then waits
+ for all existing clients to disconnect.
+ If the server is in hot standby, recovery and streaming replication
+ will be terminated once all clients have disconnected.
+ <quote>Fast</quote> mode (the default) does not wait for clients to disconnect.
+ All active transactions are
+ rolled back and clients are forcibly disconnected, then the
+ server is shut down. <quote>Immediate</quote> mode will abort
+ all server processes immediately, without a clean shutdown. This choice
+ will lead to a crash-recovery cycle during the next server start.
+ </para>
+
+ <para>
+ <option>restart</option> mode effectively executes a stop followed
+ by a start. This allows changing the <command>postgres</command>
+ command-line options, or changing configuration-file options that
+ cannot be changed without restarting the server.
+ If relative paths were used on the command line during server
+ start, <option>restart</option> might fail unless
+ <application>pg_ctl</application> is executed in the same current
+ directory as it was during server start.
+ </para>
+
+ <para>
+ <option>reload</option> mode simply sends the
+ <command>postgres</command> server process a <systemitem>SIGHUP</systemitem>
+ signal, causing it to reread its configuration files
+ (<filename>postgresql.conf</filename>,
+ <filename>pg_hba.conf</filename>, etc.). This allows changing
+ configuration-file options that do not require a full server restart
+ to take effect.
+ </para>
+
+ <para>
+ <option>status</option> mode checks whether a server is running in
+ the specified data directory. If it is, the server's <acronym>PID</acronym>
+ and the command line options that were used to invoke it are displayed.
+ If the server is not running, <application>pg_ctl</application> returns
+ an exit status of 3. If an accessible data directory is not
+ specified, <application>pg_ctl</application> returns an exit status of 4.
+ </para>
+
+ <para>
+ <option>promote</option> mode commands the standby server that is
+ running in the specified data directory to end standby mode
+ and begin read-write operations.
+ </para>
+
+ <para>
+ <option>logrotate</option> mode rotates the server log file.
+ For details on how to use this mode with external log rotation tools, see
+ <xref linkend="logfile-maintenance"/>.
+ </para>
+
+ <para>
+ <option>kill</option> mode sends a signal to a specified process.
+ This is primarily valuable on <productname>Microsoft Windows</productname>
+ which does not have a built-in <application>kill</application> command. Use
+ <literal>--help</literal> to see a list of supported signal names.
+ </para>
+
+ <para>
+ <option>register</option> mode registers the <productname>PostgreSQL</productname>
+ server as a system service on <productname>Microsoft Windows</productname>.
+ The <option>-S</option> option allows selection of service start type,
+ either <quote>auto</quote> (start service automatically on system startup)
+ or <quote>demand</quote> (start service on demand).
+ </para>
+
+ <para>
+ <option>unregister</option> mode unregisters a system service
+ on <productname>Microsoft Windows</productname>. This undoes the effects of the
+ <option>register</option> command.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-pg-ctl-options">
+ <title>Options</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--core-files</option></term>
+ <listitem>
+ <para>
+ Attempt to allow server crashes to produce core files, on platforms
+ where this is possible, by lifting any soft resource limit placed on
+ core files.
+ This is useful in debugging or diagnosing problems by allowing a
+ stack trace to be obtained from a failed server process.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">datadir</replaceable></option></term>
+ <term><option>--pgdata=<replaceable class="parameter">datadir</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the file system location of the database configuration files. If
+ this option is omitted, the environment variable
+ <envar>PGDATA</envar> is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l <replaceable class="parameter">filename</replaceable></option></term>
+ <term><option>--log=<replaceable class="parameter">filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Append the server log output to
+ <replaceable>filename</replaceable>. If the file does not
+ exist, it is created. The <systemitem>umask</systemitem> is set to 077,
+ so access to the log file is disallowed to other users by default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-m <replaceable class="parameter">mode</replaceable></option></term>
+ <term><option>--mode=<replaceable class="parameter">mode</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the shutdown mode. <replaceable>mode</replaceable>
+ can be <literal>smart</literal>, <literal>fast</literal>, or
+ <literal>immediate</literal>, or the first letter of one of
+ these three. If this option is omitted, <literal>fast</literal> is
+ the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable class="parameter">options</replaceable></option></term>
+ <term><option>--options=<replaceable class="parameter">options</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies options to be passed directly to the
+ <command>postgres</command> command.
+ <option>-o</option> can be specified multiple times, with all the given
+ options being passed through.
+ </para>
+ <para>
+ The <replaceable>options</replaceable> should usually be surrounded by single or
+ double quotes to ensure that they are passed through as a group.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable class="parameter">initdb-options</replaceable></option></term>
+ <term><option>--options=<replaceable class="parameter">initdb-options</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies options to be passed directly to the
+ <command>initdb</command> command.
+ <option>-o</option> can be specified multiple times, with all the given
+ options being passed through.
+ </para>
+ <para>
+ The <replaceable>initdb-options</replaceable> should usually be surrounded by single or
+ double quotes to ensure that they are passed through as a group.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">path</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the location of the <filename>postgres</filename>
+ executable. By default the <filename>postgres</filename> executable is taken from the same
+ directory as <command>pg_ctl</command>, or failing that, the hard-wired
+ installation directory. It is not necessary to use this
+ option unless you are doing something unusual and get errors
+ that the <filename>postgres</filename> executable was not found.
+ </para>
+
+ <para>
+ In <literal>init</literal> mode, this option analogously
+ specifies the location of the <filename>initdb</filename>
+ executable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--silent</option></term>
+ <listitem>
+ <para>
+ Print only errors, no informational messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">seconds</replaceable></option></term>
+ <term><option>--timeout=<replaceable class="parameter">seconds</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the maximum number of seconds to wait when waiting for an
+ operation to complete (see option <option>-w</option>). Defaults to
+ the value of the <envar>PGCTLTIMEOUT</envar> environment variable or, if
+ not set, to 60 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_ctl</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--wait</option></term>
+ <listitem>
+ <para>
+ Wait for the operation to complete. This is supported for the
+ modes <literal>start</literal>, <literal>stop</literal>,
+ <literal>restart</literal>, <literal>promote</literal>,
+ and <literal>register</literal>, and is the default for those modes.
+ </para>
+
+ <para>
+ When waiting, <command>pg_ctl</command> repeatedly checks the
+ server's <acronym>PID</acronym> file, sleeping for a short amount
+ of time between checks. Startup is considered complete when
+ the <acronym>PID</acronym> file indicates that the server is ready to
+ accept connections. Shutdown is considered complete when the server
+ removes the <acronym>PID</acronym> file.
+ <command>pg_ctl</command> returns an exit code based on the
+ success of the startup or shutdown.
+ </para>
+
+ <para>
+ If the operation does not complete within the timeout (see
+ option <option>-t</option>), then <command>pg_ctl</command> exits with
+ a nonzero exit status. But note that the operation might continue in
+ the background and eventually succeed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--no-wait</option></term>
+ <listitem>
+ <para>
+ Do not wait for the operation to complete. This is the opposite of
+ the option <option>-w</option>.
+ </para>
+
+ <para>
+ If waiting is disabled, the requested action is triggered, but there
+ is no feedback about its success. In that case, the server log file
+ or an external monitoring system would have to be used to check the
+ progress and success of the operation.
+ </para>
+
+ <para>
+ In prior releases of PostgreSQL, this was the default except for
+ the <literal>stop</literal> mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_ctl</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ If an option is specified that is valid, but not relevant to the selected
+ operating mode, <application>pg_ctl</application> ignores it.
+ </para>
+
+ <refsect2 id="app-pg-ctl-windows-options">
+ <title>Options for Windows</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-e <replaceable class="parameter">source</replaceable></option></term>
+ <listitem>
+ <para>
+ Name of the event source for <application>pg_ctl</application> to use
+ for logging to the event log when running as a Windows service. The
+ default is <literal>PostgreSQL</literal>. Note that this only controls
+ messages sent from <application>pg_ctl</application> itself; once
+ started, the server will use the event source specified
+ by its <xref linkend="guc-event-source"/> parameter. Should the server
+ fail very early in startup, before that parameter has been set,
+ it might also log using the default event
+ source name <literal>PostgreSQL</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N <replaceable class="parameter">servicename</replaceable></option></term>
+ <listitem>
+ <para>
+ Name of the system service to register. This name will be used
+ as both the service name and the display name.
+ The default is <literal>PostgreSQL</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P <replaceable class="parameter">password</replaceable></option></term>
+ <listitem>
+ <para>
+ Password for the user to run the service as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">start-type</replaceable></option></term>
+ <listitem>
+ <para>
+ Start type of the system service. <replaceable>start-type</replaceable> can
+ be <literal>auto</literal>, or <literal>demand</literal>, or
+ the first letter of one of these two. If this option is omitted,
+ <literal>auto</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name for the user to run the service as. For domain users, use the
+ format <literal>DOMAIN\username</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGCTLTIMEOUT</envar></term>
+
+ <listitem>
+ <para>
+ Default limit on the number of seconds to wait when waiting for startup
+ or shutdown to complete. If not set, the default is 60 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PGDATA</envar></term>
+
+ <listitem>
+ <para>
+ Default data directory location.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Most <command>pg_ctl</command> modes require knowing the data directory
+ location; therefore, the <option>-D</option> option is required
+ unless <envar>PGDATA</envar> is set.
+ </para>
+
+ <para>
+ <command>pg_ctl</command>, like most other <productname>PostgreSQL</productname>
+ utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ For additional variables that affect the server,
+ see <xref linkend="app-postgres"/>.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Files</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>postmaster.pid</filename></term>
+
+ <listitem>
+ <para>
+ <application>pg_ctl</application> examines this file in the data
+ directory to determine whether the server is currently running.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>postmaster.opts</filename></term>
+
+ <listitem>
+ <para>If this file exists in the data directory,
+ <application>pg_ctl</application> (in <option>restart</option> mode)
+ will pass the contents of the file as options to
+ <application>postgres</application>, unless overridden
+ by the <option>-o</option> option. The contents of this file
+ are also displayed in <option>status</option> mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1 id="r1-app-pgctl-2">
+ <title>Examples</title>
+
+ <refsect2 id="r2-app-pgctl-3">
+ <title>Starting the Server</title>
+
+ <para>
+ To start the server, waiting until the server is
+ accepting connections:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl start</userinput>
+</screen>
+ </para>
+
+ <para>
+ To start the server using port 5433, and
+ running without <function>fsync</function>, use:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl -o "-F -p 5433" start</userinput>
+</screen></para>
+ </refsect2>
+
+ <refsect2 id="r2-app-pgctl-4">
+ <title>Stopping the Server</title>
+ <para>
+ To stop the server, use:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl stop</userinput>
+</screen>
+ The <option>-m</option> option allows control over
+ <emphasis>how</emphasis> the server shuts down:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl stop -m smart</userinput>
+</screen></para>
+ </refsect2>
+
+ <refsect2 id="r2-app-pgctl-5">
+ <title>Restarting the Server</title>
+
+ <para>
+ Restarting the server is almost equivalent to stopping the
+ server and starting it again, except that by default,
+ <command>pg_ctl</command> saves and reuses the command line options that
+ were passed to the previously-running instance. To restart
+ the server using the same options as before, use:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl restart</userinput>
+</screen>
+ </para>
+
+ <para>
+ But if <option>-o</option> is specified, that replaces any previous options.
+ To restart using port 5433, disabling <function>fsync</function> upon restart:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl -o "-F -p 5433" restart</userinput>
+</screen></para>
+ </refsect2>
+
+ <refsect2 id="r2-app-pgctl-6">
+ <title>Showing the Server Status</title>
+
+ <para>
+ Here is sample status output from
+ <application>pg_ctl</application>:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl status</userinput>
+<computeroutput>
+pg_ctl: server is running (PID: 13718)
+/usr/local/pgsql/bin/postgres "-D" "/usr/local/pgsql/data" "-p" "5433" "-B" "128"
+</computeroutput></screen>
+ The second line is the command that would be invoked in restart mode.
+ </para>
+ </refsect2>
+ </refsect1>
+
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-initdb"/></member>
+ <member><xref linkend="app-postgres"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml
new file mode 100644
index 0000000..3bbbc7c
--- /dev/null
+++ b/doc/src/sgml/ref/pg_dump.sgml
@@ -0,0 +1,1535 @@
+<!--
+doc/src/sgml/ref/pg_dump.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgdump">
+ <indexterm zone="app-pgdump">
+ <primary>pg_dump</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_dump</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_dump</refname>
+
+ <refpurpose>
+ extract a <productname>PostgreSQL</productname> database into a script file or other archive file
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_dump</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pg-dump-description">
+ <title>Description</title>
+
+ <para>
+ <application>pg_dump</application> is a utility for backing up a
+ <productname>PostgreSQL</productname> database. It makes consistent
+ backups even if the database is being used concurrently.
+ <application>pg_dump</application> does not block other users
+ accessing the database (readers or writers).
+ </para>
+
+ <para>
+ <application>pg_dump</application> only dumps a single database.
+ To back up an entire cluster, or to back up global objects that are
+ common to all databases in a cluster (such as roles and tablespaces),
+ use <xref linkend="app-pg-dumpall"/>.
+ </para>
+
+ <para>
+ Dumps can be output in script or archive file formats. Script
+ dumps are plain-text files containing the SQL commands required
+ to reconstruct the database to the state it was in at the time it was
+ saved. To restore from such a script, feed it to <xref
+ linkend="app-psql"/>. Script files
+ can be used to reconstruct the database even on other machines and
+ other architectures; with some modifications, even on other SQL
+ database products.
+ </para>
+
+ <para>
+ The alternative archive file formats must be used with
+ <xref linkend="app-pgrestore"/> to rebuild the database. They
+ allow <application>pg_restore</application> to be selective about
+ what is restored, or even to reorder the items prior to being
+ restored.
+ The archive file formats are designed to be portable across
+ architectures.
+ </para>
+
+ <para>
+ When used with one of the archive file formats and combined with
+ <application>pg_restore</application>,
+ <application>pg_dump</application> provides a flexible archival and
+ transfer mechanism. <application>pg_dump</application> can be used to
+ backup an entire database, then <application>pg_restore</application>
+ can be used to examine the archive and/or select which parts of the
+ database are to be restored. The most flexible output file formats are
+ the <quote>custom</quote> format (<option>-Fc</option>) and the
+ <quote>directory</quote> format (<option>-Fd</option>). They allow
+ for selection and reordering of all archived items, support parallel
+ restoration, and are compressed by default. The <quote>directory</quote>
+ format is the only format that supports parallel dumps.
+ </para>
+
+ <para>
+ While running <application>pg_dump</application>, one should examine the
+ output for any warnings (printed on standard error), especially in
+ light of the limitations listed below.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pg-dump-options">
+ <title>Options</title>
+
+ <para>
+ The following command-line options control the content and
+ format of the output.
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">dbname</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be dumped. If this is
+ not specified, the environment variable
+ <envar>PGDATABASE</envar> is used. If that is not set, the
+ user name specified for the connection is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--data-only</option></term>
+ <listitem>
+ <para>
+ Dump only the data, not the schema (data definitions).
+ Table data, large objects, and sequence values are dumped.
+ </para>
+
+ <para>
+ This option is similar to, but for historical reasons not identical
+ to, specifying <option>--section=data</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-b</option></term>
+ <term><option>--blobs</option></term>
+ <listitem>
+ <para>
+ Include large objects in the dump. This is the default behavior
+ except when <option>--schema</option>, <option>--table</option>, or
+ <option>--schema-only</option> is specified. The <option>-b</option>
+ switch is therefore only useful to add large objects to dumps
+ where a specific schema or table has been requested. Note that
+ blobs are considered data and therefore will be included when
+ <option>--data-only</option> is used, but not
+ when <option>--schema-only</option> is.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-B</option></term>
+ <term><option>--no-blobs</option></term>
+ <listitem>
+ <para>
+ Exclude large objects in the dump.
+ </para>
+
+ <para>
+ When both <option>-b</option> and <option>-B</option> are given, the behavior
+ is to output large objects, when data is being dumped, see the
+ <option>-b</option> documentation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--clean</option></term>
+ <listitem>
+ <para>
+ Output commands to clean (drop)
+ database objects prior to outputting the commands for creating them.
+ (Unless <option>--if-exists</option> is also specified,
+ restore might generate some harmless error messages, if any objects
+ were not present in the destination database.)
+ </para>
+
+ <para>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <command>pg_restore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C</option></term>
+ <term><option>--create</option></term>
+ <listitem>
+ <para>
+ Begin the output with a command to create the
+ database itself and reconnect to the created database. (With a
+ script of this form, it doesn't matter which database in the
+ destination installation you connect to before running the script.)
+ If <option>--clean</option> is also specified, the script drops and
+ recreates the target database before reconnecting to it.
+ </para>
+
+ <para>
+ With <option>--create</option>, the output also includes the
+ database's comment if any, and any configuration variable settings
+ that are specific to this database, that is,
+ any <command>ALTER DATABASE ... SET ...</command>
+ and <command>ALTER ROLE ... IN DATABASE ... SET ...</command>
+ commands that mention this database.
+ Access privileges for the database itself are also dumped,
+ unless <option>--no-acl</option> is specified.
+ </para>
+
+ <para>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <command>pg_restore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--extension=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump only extensions matching <replaceable
+ class="parameter">pattern</replaceable>. When this option is not
+ specified, all non-system extensions in the target database will be
+ dumped. Multiple extensions can be selected by writing multiple
+ <option>-e</option> switches. The <replaceable
+ class="parameter">pattern</replaceable> parameter is interpreted as a
+ pattern according to the same rules used by
+ <application>psql</application>'s <literal>\d</literal> commands (see
+ <xref linkend="app-psql-patterns"/>), so multiple extensions can also
+ be selected by writing wildcard characters in the pattern. When using
+ wildcards, be careful to quote the pattern if needed to prevent the
+ shell from expanding the wildcards.
+ </para>
+
+ <para>
+ Any configuration relation registered by
+ <function>pg_extension_config_dump</function> is included in the
+ dump if its extension is specified by <option>--extension</option>.
+ </para>
+
+ <note>
+ <para>
+ When <option>-e</option> is specified,
+ <application>pg_dump</application> makes no attempt to dump any other
+ database objects that the selected extension(s) might depend upon.
+ Therefore, there is no guarantee that the results of a
+ specific-extension dump can be successfully restored by themselves
+ into a clean database.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E <replaceable class="parameter">encoding</replaceable></option></term>
+ <term><option>--encoding=<replaceable class="parameter">encoding</replaceable></option></term>
+ <listitem>
+ <para>
+ Create the dump in the specified character set encoding. By default,
+ the dump is created in the database encoding. (Another way to get the
+ same result is to set the <envar>PGCLIENTENCODING</envar> environment
+ variable to the desired dump encoding.) The supported encodings are
+ described in <xref linkend="multibyte-charset-supported"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f <replaceable class="parameter">file</replaceable></option></term>
+ <term><option>--file=<replaceable class="parameter">file</replaceable></option></term>
+ <listitem>
+ <para>
+ Send output to the specified file. This parameter can be omitted for
+ file based output formats, in which case the standard output is used.
+ It must be given for the directory output format however, where it
+ specifies the target directory instead of a file. In this case the
+ directory is created by <command>pg_dump</command> and must not exist
+ before.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F <replaceable class="parameter">format</replaceable></option></term>
+ <term><option>--format=<replaceable class="parameter">format</replaceable></option></term>
+ <listitem>
+ <para>
+ Selects the format of the output.
+ <replaceable>format</replaceable> can be one of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>p</literal></term>
+ <term><literal>plain</literal></term>
+ <listitem>
+ <para>
+ Output a plain-text <acronym>SQL</acronym> script file (the default).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>c</literal></term>
+ <term><literal>custom</literal></term>
+ <listitem>
+ <para>
+ Output a custom-format archive suitable for input into
+ <application>pg_restore</application>.
+ Together with the directory output format, this is the most flexible
+ output format in that it allows manual selection and reordering of
+ archived items during restore. This format is also compressed by
+ default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>d</literal></term>
+ <term><literal>directory</literal></term>
+ <listitem>
+ <para>
+ Output a directory-format archive suitable for input into
+ <application>pg_restore</application>. This will create a directory
+ with one file for each table and blob being dumped, plus a
+ so-called Table of Contents file describing the dumped objects in a
+ machine-readable format that <application>pg_restore</application>
+ can read. A directory format archive can be manipulated with
+ standard Unix tools; for example, files in an uncompressed archive
+ can be compressed with the <application>gzip</application> tool.
+ This format is compressed by default and also supports parallel
+ dumps.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>t</literal></term>
+ <term><literal>tar</literal></term>
+ <listitem>
+ <para>
+ Output a <command>tar</command>-format archive suitable for input
+ into <application>pg_restore</application>. The tar format is
+ compatible with the directory format: extracting a tar-format
+ archive produces a valid directory-format archive.
+ However, the tar format does not support compression. Also, when
+ using tar format the relative order of table data items cannot be
+ changed during restore.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j <replaceable class="parameter">njobs</replaceable></option></term>
+ <term><option>--jobs=<replaceable class="parameter">njobs</replaceable></option></term>
+ <listitem>
+ <para>
+ Run the dump in parallel by dumping <replaceable class="parameter">njobs</replaceable>
+ tables simultaneously. This option may reduce the time needed to perform the dump but it also
+ increases the load on the database server. You can only use this option with the
+ directory output format because this is the only output format where multiple processes
+ can write their data at the same time.
+ </para>
+ <para><application>pg_dump</application> will open <replaceable class="parameter">njobs</replaceable>
+ + 1 connections to the database, so make sure your <xref linkend="guc-max-connections"/>
+ setting is high enough to accommodate all connections.
+ </para>
+ <para>
+ Requesting exclusive locks on database objects while running a parallel dump could
+ cause the dump to fail. The reason is that the <application>pg_dump</application> leader process
+ requests shared locks (<link linkend="locking-tables">ACCESS SHARE</link>) on the
+ objects that the worker processes are going to dump later in order to
+ make sure that nobody deletes them and makes them go away while the dump is running.
+ If another client then requests an exclusive lock on a table, that lock will not be
+ granted but will be queued waiting for the shared lock of the leader process to be
+ released. Consequently any other access to the table will not be granted either and
+ will queue after the exclusive lock request. This includes the worker process trying
+ to dump the table. Without any precautions this would be a classic deadlock situation.
+ To detect this conflict, the <application>pg_dump</application> worker process requests another
+ shared lock using the <literal>NOWAIT</literal> option. If the worker process is not granted
+ this shared lock, somebody else must have requested an exclusive lock in the meantime
+ and there is no way to continue with the dump, so <application>pg_dump</application> has no choice
+ but to abort the dump.
+ </para>
+ <para>
+ To perform a parallel dump, the database server needs to support
+ synchronized snapshots, a feature that was introduced in
+ <productname>PostgreSQL</productname> 9.2 for primary servers and 10
+ for standbys. With this feature, database clients can ensure they see
+ the same data set even though they use different connections.
+ <command>pg_dump -j</command> uses multiple database connections; it
+ connects to the database once with the leader process and once again
+ for each worker job. Without the synchronized snapshot feature, the
+ different worker jobs wouldn't be guaranteed to see the same data in
+ each connection, which could lead to an inconsistent backup.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--schema=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump only schemas matching <replaceable
+ class="parameter">pattern</replaceable>; this selects both the
+ schema itself, and all its contained objects. When this option is
+ not specified, all non-system schemas in the target database will be
+ dumped. Multiple schemas can be
+ selected by writing multiple <option>-n</option> switches. The
+ <replaceable class="parameter">pattern</replaceable> parameter is
+ interpreted as a pattern according to the same rules used by
+ <application>psql</application>'s <literal>\d</literal> commands
+ (see <xref linkend="app-psql-patterns"/> below),
+ so multiple schemas can also be selected by writing wildcard characters
+ in the pattern. When using wildcards, be careful to quote the pattern
+ if needed to prevent the shell from expanding the wildcards; see
+ <xref linkend="pg-dump-examples"/> below.
+ </para>
+
+ <note>
+ <para>
+ When <option>-n</option> is specified, <application>pg_dump</application>
+ makes no attempt to dump any other database objects that the selected
+ schema(s) might depend upon. Therefore, there is no guarantee
+ that the results of a specific-schema dump can be successfully
+ restored by themselves into a clean database.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Non-schema objects such as blobs are not dumped when <option>-n</option> is
+ specified. You can add blobs back to the dump with the
+ <option>--blobs</option> switch.
+ </para>
+ </note>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-schema=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not dump any schemas matching <replaceable
+ class="parameter">pattern</replaceable>. The pattern is
+ interpreted according to the same rules as for <option>-n</option>.
+ <option>-N</option> can be given more than once to exclude schemas
+ matching any of several patterns.
+ </para>
+
+ <para>
+ When both <option>-n</option> and <option>-N</option> are given, the behavior
+ is to dump just the schemas that match at least one <option>-n</option>
+ switch but no <option>-N</option> switches. If <option>-N</option> appears
+ without <option>-n</option>, then schemas matching <option>-N</option> are
+ excluded from what is otherwise a normal dump.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option></term>
+ <term><option>--no-owner</option></term>
+ <listitem>
+ <para>
+ Do not output commands to set
+ ownership of objects to match the original database.
+ By default, <application>pg_dump</application> issues
+ <command>ALTER OWNER</command> or
+ <command>SET SESSION AUTHORIZATION</command>
+ statements to set ownership of created database objects.
+ These statements
+ will fail when the script is run unless it is started by a superuser
+ (or the same user that owns all of the objects in the script).
+ To make a script that can be restored by any user, but will give
+ that user ownership of all the objects, specify <option>-O</option>.
+ </para>
+
+ <para>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <command>pg_restore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R</option></term>
+ <term><option>--no-reconnect</option></term>
+ <listitem>
+ <para>
+ This option is obsolete but still accepted for backwards
+ compatibility.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--schema-only</option></term>
+ <listitem>
+ <para>
+ Dump only the object definitions (schema), not data.
+ </para>
+ <para>
+ This option is the inverse of <option>--data-only</option>.
+ It is similar to, but for historical reasons not identical to,
+ specifying
+ <option>--section=pre-data --section=post-data</option>.
+ </para>
+ <para>
+ (Do not confuse this with the <option>--schema</option> option, which
+ uses the word <quote>schema</quote> in a different meaning.)
+ </para>
+ <para>
+ To exclude table data for only a subset of tables in the database,
+ see <option>--exclude-table-data</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--superuser=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify the superuser user name to use when disabling triggers.
+ This is relevant only if <option>--disable-triggers</option> is used.
+ (Usually, it's better to leave this out, and instead start the
+ resulting script as superuser.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--table=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump only tables with names matching
+ <replaceable class="parameter">pattern</replaceable>. Multiple tables
+ can be selected by writing multiple <option>-t</option> switches. The
+ <replaceable class="parameter">pattern</replaceable> parameter is
+ interpreted as a pattern according to the same rules used by
+ <application>psql</application>'s <literal>\d</literal> commands
+ (see <xref linkend="app-psql-patterns"/> below),
+ so multiple tables can also be selected by writing wildcard characters
+ in the pattern. When using wildcards, be careful to quote the pattern
+ if needed to prevent the shell from expanding the wildcards; see
+ <xref linkend="pg-dump-examples"/> below.
+ </para>
+
+ <para>
+ As well as tables, this option can be used to dump the definition of matching
+ views, materialized views, foreign tables, and sequences. It will not dump the
+ contents of views or materialized views, and the contents of foreign tables will
+ only be dumped if the corresponding foreign server is specified with
+ <option>--include-foreign-data</option>.
+ </para>
+
+ <para>
+ The <option>-n</option> and <option>-N</option> switches have no effect when
+ <option>-t</option> is used, because tables selected by <option>-t</option> will
+ be dumped regardless of those switches, and non-table objects will not
+ be dumped.
+ </para>
+
+ <note>
+ <para>
+ When <option>-t</option> is specified, <application>pg_dump</application>
+ makes no attempt to dump any other database objects that the selected
+ table(s) might depend upon. Therefore, there is no guarantee
+ that the results of a specific-table dump can be successfully
+ restored by themselves into a clean database.
+ </para>
+ </note>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable class="parameter">pattern</replaceable></option></term>
+ <term><option>--exclude-table=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not dump any tables matching <replaceable
+ class="parameter">pattern</replaceable>. The pattern is
+ interpreted according to the same rules as for <option>-t</option>.
+ <option>-T</option> can be given more than once to exclude tables
+ matching any of several patterns.
+ </para>
+
+ <para>
+ When both <option>-t</option> and <option>-T</option> are given, the behavior
+ is to dump just the tables that match at least one <option>-t</option>
+ switch but no <option>-T</option> switches. If <option>-T</option> appears
+ without <option>-t</option>, then tables matching <option>-T</option> are
+ excluded from what is otherwise a normal dump.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Specifies verbose mode. This will cause
+ <application>pg_dump</application> to output detailed object
+ comments and start/stop times to the dump file, and progress
+ messages to standard error.
+ Repeating the option causes additional debug-level messages
+ to appear on standard error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_dump</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option></term>
+ <term><option>--no-privileges</option></term>
+ <term><option>--no-acl</option></term>
+ <listitem>
+ <para>
+ Prevent dumping of access privileges (grant/revoke commands).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-Z <replaceable class="parameter">0..9</replaceable></option></term>
+ <term><option>--compress=<replaceable class="parameter">0..9</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify the compression level to use. Zero means no compression.
+ For the custom and directory archive formats, this specifies compression of
+ individual table-data segments, and the default is to compress
+ at a moderate level.
+ For plain text output, setting a nonzero compression level causes
+ the entire output file to be compressed, as though it had been
+ fed through <application>gzip</application>; but the default is not to compress.
+ The tar archive format currently does not support compression at all.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--binary-upgrade</option></term>
+ <listitem>
+ <para>
+ This option is for use by in-place upgrade utilities. Its use
+ for other purposes is not recommended or supported. The
+ behavior of the option may change in future releases without
+ notice.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--column-inserts</option></term>
+ <term><option>--attribute-inserts</option></term>
+ <listitem>
+ <para>
+ Dump data as <command>INSERT</command> commands with explicit
+ column names (<literal>INSERT INTO
+ <replaceable>table</replaceable>
+ (<replaceable>column</replaceable>, ...) VALUES
+ ...</literal>). This will make restoration very slow; it is mainly
+ useful for making dumps that can be loaded into
+ non-<productname>PostgreSQL</productname> databases.
+ Any error during restoring will cause only rows that are part of the
+ problematic <command>INSERT</command> to be lost, rather than the
+ entire table contents.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-dollar-quoting</option></term>
+ <listitem>
+ <para>
+ This option disables the use of dollar quoting for function bodies,
+ and forces them to be quoted using SQL standard string syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-triggers</option></term>
+ <listitem>
+ <para>
+ This option is relevant only when creating a data-only dump.
+ It instructs <application>pg_dump</application> to include commands
+ to temporarily disable triggers on the target tables while
+ the data is restored. Use this if you have referential
+ integrity checks or other triggers on the tables that you
+ do not want to invoke during data restore.
+ </para>
+
+ <para>
+ Presently, the commands emitted for <option>--disable-triggers</option>
+ must be done as superuser. So, you should also specify
+ a superuser name with <option>-S</option>, or preferably be careful to
+ start the resulting script as a superuser.
+ </para>
+
+ <para>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <command>pg_restore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-row-security</option></term>
+ <listitem>
+ <para>
+ This option is relevant only when dumping the contents of a table
+ which has row security. By default, <application>pg_dump</application> will set
+ <xref linkend="guc-row-security"/> to off, to ensure
+ that all data is dumped from the table. If the user does not have
+ sufficient privileges to bypass row security, then an error is thrown.
+ This parameter instructs <application>pg_dump</application> to set
+ <xref linkend="guc-row-security"/> to on instead, allowing the user
+ to dump the parts of the contents of the table that they have access to.
+ </para>
+
+ <para>
+ Note that if you use this option currently, you probably also want
+ the dump be in <command>INSERT</command> format, as the
+ <command>COPY FROM</command> during restore does not support row security.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--exclude-table-data=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not dump data for any tables matching <replaceable
+ class="parameter">pattern</replaceable>. The pattern is
+ interpreted according to the same rules as for <option>-t</option>.
+ <option>--exclude-table-data</option> can be given more than once to
+ exclude tables matching any of several patterns. This option is
+ useful when you need the definition of a particular table even
+ though you do not need the data in it.
+ </para>
+ <para>
+ To exclude data for all tables in the database, see <option>--schema-only</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--extra-float-digits=<replaceable class="parameter">ndigits</replaceable></option></term>
+ <listitem>
+ <para>
+ Use the specified value of <option>extra_float_digits</option> when dumping
+ floating-point data, instead of the maximum available precision.
+ Routine dumps made for backup purposes should not use this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-exists</option></term>
+ <listitem>
+ <para>
+ Use conditional commands (i.e., add an <literal>IF EXISTS</literal>
+ clause) when cleaning database objects. This option is not valid
+ unless <option>--clean</option> is also specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--include-foreign-data=<replaceable class="parameter">foreignserver</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump the data for any foreign table with a foreign server
+ matching <replaceable class="parameter">foreignserver</replaceable>
+ pattern. Multiple foreign servers can be selected by writing multiple
+ <option>--include-foreign-data</option> switches.
+ Also, the <replaceable class="parameter">foreignserver</replaceable> parameter is
+ interpreted as a pattern according to the same rules used by
+ <application>psql</application>'s <literal>\d</literal> commands
+ (see <xref linkend="app-psql-patterns"/> below),
+ so multiple foreign servers can also be selected by writing wildcard characters
+ in the pattern. When using wildcards, be careful to quote the pattern
+ if needed to prevent the shell from expanding the wildcards; see
+ <xref linkend="pg-dump-examples"/> below.
+ The only exception is that an empty pattern is disallowed.
+ </para>
+
+ <note>
+ <para>
+ When <option>--include-foreign-data</option> is specified,
+ <application>pg_dump</application> does not check that the foreign
+ table is writable. Therefore, there is no guarantee that the
+ results of a foreign table dump can be successfully restored.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--inserts</option></term>
+ <listitem>
+ <para>
+ Dump data as <command>INSERT</command> commands (rather
+ than <command>COPY</command>). This will make restoration very slow;
+ it is mainly useful for making dumps that can be loaded into
+ non-<productname>PostgreSQL</productname> databases.
+ Any error during restoring will cause only rows that are part of the
+ problematic <command>INSERT</command> to be lost, rather than the
+ entire table contents. Note that the restore might fail altogether if
+ you have rearranged column order. The
+ <option>--column-inserts</option> option is safe against column order
+ changes, though even slower.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--load-via-partition-root</option></term>
+ <listitem>
+ <para>
+ When dumping data for a table partition, make
+ the <command>COPY</command> or <command>INSERT</command> statements
+ target the root of the partitioning hierarchy that contains it, rather
+ than the partition itself. This causes the appropriate partition to
+ be re-determined for each row when the data is loaded. This may be
+ useful when restoring data on a server where rows do not always fall
+ into the same partitions as they did on the original server. That
+ could happen, for example, if the partitioning column is of type text
+ and the two systems have different definitions of the collation used
+ to sort the partitioning column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--lock-wait-timeout=<replaceable class="parameter">timeout</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not wait forever to acquire shared table locks at the beginning of
+ the dump. Instead fail if unable to lock a table within the specified
+ <replaceable class="parameter">timeout</replaceable>. The timeout may be
+ specified in any of the formats accepted by <command>SET
+ statement_timeout</command>. (Allowed formats vary depending on the server
+ version you are dumping from, but an integer number of milliseconds
+ is accepted by all versions.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-comments</option></term>
+ <listitem>
+ <para>
+ Do not dump comments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-publications</option></term>
+ <listitem>
+ <para>
+ Do not dump publications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-security-labels</option></term>
+ <listitem>
+ <para>
+ Do not dump security labels.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-subscriptions</option></term>
+ <listitem>
+ <para>
+ Do not dump subscriptions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>pg_dump</command> will wait for all files
+ to be written safely to disk. This option causes
+ <command>pg_dump</command> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the dump corrupt. Generally, this option is useful for testing
+ but should not be used when dumping data from production installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-table-access-method</option></term>
+ <listitem>
+ <para>
+ Do not output commands to select table access methods.
+ With this option, all objects will be created with whichever
+ table access method is the default during restore.
+ </para>
+
+ <para>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <command>pg_restore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-tablespaces</option></term>
+ <listitem>
+ <para>
+ Do not output commands to select tablespaces.
+ With this option, all objects will be created in whichever
+ tablespace is the default during restore.
+ </para>
+
+ <para>
+ This option is ignored when emitting an archive (non-text) output
+ file. For the archive formats, you can specify the option when you
+ call <command>pg_restore</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-toast-compression</option></term>
+ <listitem>
+ <para>
+ Do not output commands to set <acronym>TOAST</acronym> compression
+ methods.
+ With this option, all columns will be restored with the default
+ compression setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-unlogged-table-data</option></term>
+ <listitem>
+ <para>
+ Do not dump the contents of unlogged tables and sequences. This
+ option has no effect on whether or not the table and sequence
+ definitions (schema) are dumped; it only suppresses dumping the table
+ and sequence data. Data in unlogged tables and sequences
+ is always excluded when dumping from a standby server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--on-conflict-do-nothing</option></term>
+ <listitem>
+ <para>
+ Add <literal>ON CONFLICT DO NOTHING</literal> to
+ <command>INSERT</command> commands.
+ This option is not valid unless <option>--inserts</option>,
+ <option>--column-inserts</option> or
+ <option>--rows-per-insert</option> is also specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--quote-all-identifiers</option></term>
+ <listitem>
+ <para>
+ Force quoting of all identifiers. This option is recommended when
+ dumping a database from a server whose <productname>PostgreSQL</productname>
+ major version is different from <application>pg_dump</application>'s, or when
+ the output is intended to be loaded into a server of a different
+ major version. By default, <application>pg_dump</application> quotes only
+ identifiers that are reserved words in its own major version.
+ This sometimes results in compatibility issues when dealing with
+ servers of other versions that may have slightly different sets
+ of reserved words. Using <option>--quote-all-identifiers</option> prevents
+ such issues, at the price of a harder-to-read dump script.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--rows-per-insert=<replaceable class="parameter">nrows</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump data as <command>INSERT</command> commands (rather than
+ <command>COPY</command>). Controls the maximum number of rows per
+ <command>INSERT</command> command. The value specified must be a
+ number greater than zero. Any error during restoring will cause only
+ rows that are part of the problematic <command>INSERT</command> to be
+ lost, rather than the entire table contents.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
+ <listitem>
+ <para>
+ Only dump the named section. The section name can be
+ <option>pre-data</option>, <option>data</option>, or <option>post-data</option>.
+ This option can be specified more than once to select multiple
+ sections. The default is to dump all sections.
+ </para>
+ <para>
+ The data section contains actual table data, large-object
+ contents, and sequence values.
+ Post-data items include definitions of indexes, triggers, rules,
+ and constraints other than validated check constraints.
+ Pre-data items include all other data definition items.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--serializable-deferrable</option></term>
+ <listitem>
+ <para>
+ Use a <literal>serializable</literal> transaction for the dump, to
+ ensure that the snapshot used is consistent with later database
+ states; but do this by waiting for a point in the transaction stream
+ at which no anomalies can be present, so that there isn't a risk of
+ the dump failing or causing other transactions to roll back with a
+ <literal>serialization_failure</literal>. See <xref linkend="mvcc"/>
+ for more information about transaction isolation and concurrency
+ control.
+ </para>
+
+ <para>
+ This option is not beneficial for a dump which is intended only for
+ disaster recovery. It could be useful for a dump used to load a
+ copy of the database for reporting or other read-only load sharing
+ while the original database continues to be updated. Without it the
+ dump may reflect a state which is not consistent with any serial
+ execution of the transactions eventually committed. For example, if
+ batch processing techniques are used, a batch may show as closed in
+ the dump without all of the items which are in the batch appearing.
+ </para>
+
+ <para>
+ This option will make no difference if there are no read-write
+ transactions active when pg_dump is started. If read-write
+ transactions are active, the start of the dump may be delayed for an
+ indeterminate length of time. Once running, performance with or
+ without the switch is the same.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--snapshot=<replaceable class="parameter">snapshotname</replaceable></option></term>
+ <listitem>
+ <para>
+ Use the specified synchronized snapshot when making a dump of the
+ database (see
+ <xref linkend="functions-snapshot-synchronization-table"/> for more
+ details).
+ </para>
+ <para>
+ This option is useful when needing to synchronize the dump with
+ a logical replication slot (see <xref linkend="logicaldecoding"/>)
+ or with a concurrent session.
+ </para>
+ <para>
+ In the case of a parallel dump, the snapshot name defined by this
+ option is used rather than taking a new snapshot.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--strict-names</option></term>
+ <listitem>
+ <para>
+ Require that each
+ extension (<option>-e</option>/<option>--extension</option>),
+ schema (<option>-n</option>/<option>--schema</option>) and
+ table (<option>-t</option>/<option>--table</option>) qualifier
+ match at least one extension/schema/table in the database to be dumped.
+ Note that if none of the extension/schema/table qualifiers find
+ matches, <application>pg_dump</application> will generate an error
+ even without <option>--strict-names</option>.
+ </para>
+ <para>
+ This option has no effect
+ on <option>-N</option>/<option>--exclude-schema</option>,
+ <option>-T</option>/<option>--exclude-table</option>,
+ or <option>--exclude-table-data</option>. An exclude pattern failing
+ to match any objects is not considered an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--use-set-session-authorization</option></term>
+ <listitem>
+ <para>
+ Output SQL-standard <command>SET SESSION AUTHORIZATION</command> commands
+ instead of <command>ALTER OWNER</command> commands to determine object
+ ownership. This makes the dump more standards-compatible, but
+ depending on the history of the objects in the dump, might not restore
+ properly. Also, a dump using <command>SET SESSION AUTHORIZATION</command>
+ will certainly require superuser privileges to restore correctly,
+ whereas <command>ALTER OWNER</command> requires lesser privileges.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_dump</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ The following command-line options control the database connection parameters.
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to. This is
+ equivalent to specifying <replaceable
+ class="parameter">dbname</replaceable> as the first non-option
+ argument on the command line. The <replaceable>dbname</replaceable>
+ can be a <link linkend="libpq-connstring">connection string</link>.
+ If so, connection string parameters will override any conflicting
+ command line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <envar>PGHOST</envar> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <envar>PGPORT</envar> environment variable, if
+ set, or a compiled-in default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>pg_dump</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>pg_dump</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>pg_dump</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--role=<replaceable class="parameter">rolename</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies a role name to be used to create the dump.
+ This option causes <application>pg_dump</application> to issue a
+ <command>SET ROLE</command> <replaceable class="parameter">rolename</replaceable>
+ command after connecting to the database. It is useful when the
+ authenticated user (specified by <option>-U</option>) lacks privileges
+ needed by <application>pg_dump</application>, but can switch to a role with
+ the required rights. Some installations have a policy against
+ logging in directly as a superuser, and use of this option allows
+ dumps to be made without violating the policy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGOPTIONS</envar></term>
+ <term><envar>PGPORT</envar></term>
+
+ <term><envar>PGUSER</envar></term>
+ <listitem>
+ <para>
+ Default connection parameters.
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="app-pgdump-diagnostics">
+ <title>Diagnostics</title>
+
+ <para>
+ <application>pg_dump</application> internally executes
+ <command>SELECT</command> statements. If you have problems running
+ <application>pg_dump</application>, make sure you are able to
+ select information from the database using, for example, <xref
+ linkend="app-psql"/>. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ <para>
+ The database activity of <application>pg_dump</application> is
+ normally collected by the cumulative statistics system. If this is
+ undesirable, you can set parameter <varname>track_counts</varname>
+ to false via <envar>PGOPTIONS</envar> or the <literal>ALTER
+ USER</literal> command.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1 id="pg-dump-notes">
+ <title>Notes</title>
+
+ <para>
+ If your database cluster has any local additions to the <literal>template1</literal> database,
+ be careful to restore the output of <application>pg_dump</application> into a
+ truly empty database; otherwise you are likely to get errors due to
+ duplicate definitions of the added objects. To make an empty database
+ without any local additions, copy from <literal>template0</literal> not <literal>template1</literal>,
+ for example:
+<programlisting>
+CREATE DATABASE foo WITH TEMPLATE template0;
+</programlisting>
+ </para>
+
+ <para>
+ When a data-only dump is chosen and the option <option>--disable-triggers</option>
+ is used, <application>pg_dump</application> emits commands
+ to disable triggers on user tables before inserting the data,
+ and then commands to re-enable them after the data has been
+ inserted. If the restore is stopped in the middle, the system
+ catalogs might be left in the wrong state.
+ </para>
+
+ <para>
+ The dump file produced by <application>pg_dump</application>
+ does not contain the statistics used by the optimizer to make
+ query planning decisions. Therefore, it is wise to run
+ <command>ANALYZE</command> after restoring from a dump file
+ to ensure optimal performance; see <xref linkend="vacuum-for-statistics"/>
+ and <xref linkend="autovacuum"/> for more information.
+ </para>
+
+ <para>
+ Because <application>pg_dump</application> is used to transfer data
+ to newer versions of <productname>PostgreSQL</productname>, the output of
+ <application>pg_dump</application> can be expected to load into
+ <productname>PostgreSQL</productname> server versions newer than
+ <application>pg_dump</application>'s version. <application>pg_dump</application> can also
+ dump from <productname>PostgreSQL</productname> servers older than its own version.
+ (Currently, servers back to version 9.2 are supported.)
+ However, <application>pg_dump</application> cannot dump from
+ <productname>PostgreSQL</productname> servers newer than its own major version;
+ it will refuse to even try, rather than risk making an invalid dump.
+ Also, it is not guaranteed that <application>pg_dump</application>'s output can
+ be loaded into a server of an older major version &mdash; not even if the
+ dump was taken from a server of that version. Loading a dump file
+ into an older server may require manual editing of the dump file
+ to remove syntax not understood by the older server.
+ Use of the <option>--quote-all-identifiers</option> option is recommended
+ in cross-version cases, as it can prevent problems arising from varying
+ reserved-word lists in different <productname>PostgreSQL</productname> versions.
+ </para>
+
+ <para>
+ When dumping logical replication subscriptions,
+ <application>pg_dump</application> will generate <command>CREATE
+ SUBSCRIPTION</command> commands that use the <literal>connect = false</literal>
+ option, so that restoring the subscription does not make remote connections
+ for creating a replication slot or for initial table copy. That way, the
+ dump can be restored without requiring network access to the remote
+ servers. It is then up to the user to reactivate the subscriptions in a
+ suitable way. If the involved hosts have changed, the connection
+ information might have to be changed. It might also be appropriate to
+ truncate the target tables before initiating a new full table copy. If users
+ intend to copy initial data during refresh they must create the slot with
+ <literal>two_phase = false</literal>. After the initial sync, the
+ <literal>two_phase</literal> option will be automatically enabled by the
+ subscriber if the subscription had been originally created with
+ <literal>two_phase = true</literal> option.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pg-dump-examples" xreflabel="Examples">
+ <title>Examples</title>
+
+ <para>
+ To dump a database called <literal>mydb</literal> into an SQL-script file:
+<screen>
+<prompt>$</prompt> <userinput>pg_dump mydb &gt; db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ To reload such a script into a (freshly created) database named
+ <literal>newdb</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>psql -d newdb -f db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump a database into a custom-format archive file:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -Fc mydb &gt; db.dump</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump a database into a directory-format archive:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -Fd mydb -f dumpdir</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump a database into a directory-format archive in parallel with
+ 5 worker jobs:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -Fd mydb -j 5 -f dumpdir</userinput>
+</screen>
+ </para>
+
+ <para>
+ To reload an archive file into a (freshly created) database named
+ <literal>newdb</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_restore -d newdb db.dump</userinput>
+</screen>
+ </para>
+
+ <para>
+ To reload an archive file into the same database it was dumped from,
+ discarding the current contents of that database:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_restore -d postgres --clean --create db.dump</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump a single table named <literal>mytab</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -t mytab mydb &gt; db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump all tables whose names start with <literal>emp</literal> in the
+ <literal>detroit</literal> schema, except for the table named
+ <literal>employee_log</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -t 'detroit.emp*' -T detroit.employee_log mydb &gt; db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump all schemas whose names start with <literal>east</literal> or
+ <literal>west</literal> and end in <literal>gsm</literal>, excluding any schemas whose
+ names contain the word <literal>test</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -n 'east*gsm' -n 'west*gsm' -N '*test*' mydb &gt; db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ The same, using regular expression notation to consolidate the switches:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -n '(east|west)*gsm' -N '*test*' mydb &gt; db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ To dump all database objects except for tables whose names begin with
+ <literal>ts_</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -T 'ts_*' mydb &gt; db.sql</userinput>
+</screen>
+ </para>
+
+ <para>
+ To specify an upper-case or mixed-case name in <option>-t</option> and related
+ switches, you need to double-quote the name; else it will be folded to
+ lower case (see <xref linkend="app-psql-patterns"/> below). But
+ double quotes are special to the shell, so in turn they must be quoted.
+ Thus, to dump a single table with a mixed-case name, you need something
+ like
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -t "\"MixedCaseName\"" mydb &gt; mytab.sql</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pg-dumpall"/></member>
+ <member><xref linkend="app-pgrestore"/></member>
+ <member><xref linkend="app-psql"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml
new file mode 100644
index 0000000..a56bf5d
--- /dev/null
+++ b/doc/src/sgml/ref/pg_dumpall.sgml
@@ -0,0 +1,821 @@
+<!--
+doc/src/sgml/ref/pg_dumpall.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pg-dumpall">
+ <indexterm zone="app-pg-dumpall">
+ <primary>pg_dumpall</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_dumpall</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_dumpall</refname>
+ <refpurpose>extract a <productname>PostgreSQL</productname> database cluster into a script file</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_dumpall</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="app-pg-dumpall-description">
+ <title>Description</title>
+
+ <para>
+ <application>pg_dumpall</application> is a utility for writing out
+ (<quote>dumping</quote>) all <productname>PostgreSQL</productname> databases
+ of a cluster into one script file. The script file contains
+ <acronym>SQL</acronym> commands that can be used as input to <xref
+ linkend="app-psql"/> to restore the databases. It does this by
+ calling <xref linkend="app-pgdump"/> for each database in the cluster.
+ <application>pg_dumpall</application> also dumps global objects
+ that are common to all databases, namely database roles, tablespaces,
+ and privilege grants for configuration parameters.
+ (<application>pg_dump</application> does not save these objects.)
+ </para>
+
+ <para>
+ Since <application>pg_dumpall</application> reads tables from all
+ databases you will most likely have to connect as a database
+ superuser in order to produce a complete dump. Also you will need
+ superuser privileges to execute the saved script in order to be
+ allowed to add roles and create databases.
+ </para>
+
+ <para>
+ The SQL script will be written to the standard output. Use the
+ <option>-f</option>/<option>--file</option> option or shell operators to
+ redirect it into a file.
+ </para>
+
+ <para>
+ <application>pg_dumpall</application> needs to connect several
+ times to the <productname>PostgreSQL</productname> server (once per
+ database). If you use password authentication it will ask for
+ a password each time. It is convenient to have a
+ <filename>~/.pgpass</filename> file in such cases. See <xref
+ linkend="libpq-pgpass"/> for more information.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ The following command-line options control the content and
+ format of the output.
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--data-only</option></term>
+ <listitem>
+ <para>
+ Dump only the data, not the schema (data definitions).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--clean</option></term>
+ <listitem>
+ <para>
+ Include SQL commands to clean (drop) databases before
+ recreating them. <command>DROP</command> commands for roles and
+ tablespaces are added as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E <replaceable class="parameter">encoding</replaceable></option></term>
+ <term><option>--encoding=<replaceable class="parameter">encoding</replaceable></option></term>
+ <listitem>
+ <para>
+ Create the dump in the specified character set encoding. By default,
+ the dump is created in the database encoding. (Another way to get the
+ same result is to set the <envar>PGCLIENTENCODING</envar> environment
+ variable to the desired dump encoding.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f <replaceable class="parameter">filename</replaceable></option></term>
+ <term><option>--file=<replaceable class="parameter">filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Send output to the specified file. If this is omitted, the
+ standard output is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-g</option></term>
+ <term><option>--globals-only</option></term>
+ <listitem>
+ <para>
+ Dump only global objects (roles and tablespaces), no databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option></term>
+ <term><option>--no-owner</option></term>
+ <listitem>
+ <para>
+ Do not output commands to set
+ ownership of objects to match the original database.
+ By default, <application>pg_dumpall</application> issues
+ <command>ALTER OWNER</command> or
+ <command>SET SESSION AUTHORIZATION</command>
+ statements to set ownership of created schema elements.
+ These statements
+ will fail when the script is run unless it is started by a superuser
+ (or the same user that owns all of the objects in the script).
+ To make a script that can be restored by any user, but will give
+ that user ownership of all the objects, specify <option>-O</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+ <term><option>--roles-only</option></term>
+ <listitem>
+ <para>
+ Dump only roles, no databases or tablespaces.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--schema-only</option></term>
+ <listitem>
+ <para>
+ Dump only the object definitions (schema), not data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--superuser=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify the superuser user name to use when disabling triggers.
+ This is relevant only if <option>--disable-triggers</option> is used.
+ (Usually, it's better to leave this out, and instead start the
+ resulting script as superuser.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option></term>
+ <term><option>--tablespaces-only</option></term>
+ <listitem>
+ <para>
+ Dump only tablespaces, no databases or roles.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Specifies verbose mode. This will cause
+ <application>pg_dumpall</application> to output start/stop
+ times to the dump file, and progress messages to standard error.
+ Repeating the option causes additional debug-level messages
+ to appear on standard error.
+ The option is also passed down to <application>pg_dump</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_dumpall</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option></term>
+ <term><option>--no-privileges</option></term>
+ <term><option>--no-acl</option></term>
+ <listitem>
+ <para>
+ Prevent dumping of access privileges (grant/revoke commands).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--binary-upgrade</option></term>
+ <listitem>
+ <para>
+ This option is for use by in-place upgrade utilities. Its use
+ for other purposes is not recommended or supported. The
+ behavior of the option may change in future releases without
+ notice.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--column-inserts</option></term>
+ <term><option>--attribute-inserts</option></term>
+ <listitem>
+ <para>
+ Dump data as <command>INSERT</command> commands with explicit
+ column names (<literal>INSERT INTO
+ <replaceable>table</replaceable>
+ (<replaceable>column</replaceable>, ...) VALUES
+ ...</literal>). This will make restoration very slow; it is mainly
+ useful for making dumps that can be loaded into
+ non-<productname>PostgreSQL</productname> databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-dollar-quoting</option></term>
+ <listitem>
+ <para>
+ This option disables the use of dollar quoting for function bodies,
+ and forces them to be quoted using SQL standard string syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-triggers</option></term>
+ <listitem>
+ <para>
+ This option is relevant only when creating a data-only dump.
+ It instructs <application>pg_dumpall</application> to include commands
+ to temporarily disable triggers on the target tables while
+ the data is restored. Use this if you have referential
+ integrity checks or other triggers on the tables that you
+ do not want to invoke during data restore.
+ </para>
+
+ <para>
+ Presently, the commands emitted for <option>--disable-triggers</option>
+ must be done as superuser. So, you should also specify
+ a superuser name with <option>-S</option>, or preferably be careful to
+ start the resulting script as a superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--exclude-database=<replaceable class="parameter">pattern</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not dump databases whose name matches
+ <replaceable class="parameter">pattern</replaceable>.
+ Multiple patterns can be excluded by writing multiple
+ <option>--exclude-database</option> switches. The
+ <replaceable class="parameter">pattern</replaceable> parameter is
+ interpreted as a pattern according to the same rules used by
+ <application>psql</application>'s <literal>\d</literal>
+ commands (see <xref linkend="app-psql-patterns"/> below),
+ so multiple databases can also be excluded by writing wildcard
+ characters in the pattern. When using wildcards, be careful to
+ quote the pattern if needed to prevent shell wildcard expansion.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--extra-float-digits=<replaceable class="parameter">ndigits</replaceable></option></term>
+ <listitem>
+ <para>
+ Use the specified value of extra_float_digits when dumping
+ floating-point data, instead of the maximum available precision.
+ Routine dumps made for backup purposes should not use this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-exists</option></term>
+ <listitem>
+ <para>
+ Use conditional commands (i.e., add an <literal>IF EXISTS</literal>
+ clause) to drop databases and other objects. This option is not valid
+ unless <option>--clean</option> is also specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--inserts</option></term>
+ <listitem>
+ <para>
+ Dump data as <command>INSERT</command> commands (rather
+ than <command>COPY</command>). This will make restoration very slow;
+ it is mainly useful for making dumps that can be loaded into
+ non-<productname>PostgreSQL</productname> databases. Note that
+ the restore might fail altogether if you have rearranged column order.
+ The <option>--column-inserts</option> option is safer, though even
+ slower.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--load-via-partition-root</option></term>
+ <listitem>
+ <para>
+ When dumping data for a table partition, make
+ the <command>COPY</command> or <command>INSERT</command> statements
+ target the root of the partitioning hierarchy that contains it, rather
+ than the partition itself. This causes the appropriate partition to
+ be re-determined for each row when the data is loaded. This may be
+ useful when restoring data on a server where rows do not always fall
+ into the same partitions as they did on the original server. That
+ could happen, for example, if the partitioning column is of type text
+ and the two systems have different definitions of the collation used
+ to sort the partitioning column.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--lock-wait-timeout=<replaceable class="parameter">timeout</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not wait forever to acquire shared table locks at the beginning of
+ the dump. Instead, fail if unable to lock a table within the specified
+ <replaceable class="parameter">timeout</replaceable>. The timeout may be
+ specified in any of the formats accepted by <command>SET
+ statement_timeout</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-comments</option></term>
+ <listitem>
+ <para>
+ Do not dump comments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-publications</option></term>
+ <listitem>
+ <para>
+ Do not dump publications.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-role-passwords</option></term>
+ <listitem>
+ <para>
+ Do not dump passwords for roles. When restored, roles will have a
+ null password, and password authentication will always fail until the
+ password is set. Since password values aren't needed when this option
+ is specified, the role information is read from the catalog
+ view <structname>pg_roles</structname> instead
+ of <structname>pg_authid</structname>. Therefore, this option also
+ helps if access to <structname>pg_authid</structname> is restricted by
+ some security policy.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-security-labels</option></term>
+ <listitem>
+ <para>
+ Do not dump security labels.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-subscriptions</option></term>
+ <listitem>
+ <para>
+ Do not dump subscriptions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>pg_dumpall</command> will wait for all files
+ to be written safely to disk. This option causes
+ <command>pg_dumpall</command> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the dump corrupt. Generally, this option is useful for testing
+ but should not be used when dumping data from production installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-table-access-method</option></term>
+ <listitem>
+ <para>
+ Do not output commands to select table access methods.
+ With this option, all objects will be created with whichever
+ table access method is the default during restore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-tablespaces</option></term>
+ <listitem>
+ <para>
+ Do not output commands to create tablespaces nor select tablespaces
+ for objects.
+ With this option, all objects will be created in whichever
+ tablespace is the default during restore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-toast-compression</option></term>
+ <listitem>
+ <para>
+ Do not output commands to set <acronym>TOAST</acronym> compression
+ methods.
+ With this option, all columns will be restored with the default
+ compression setting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-unlogged-table-data</option></term>
+ <listitem>
+ <para>
+ Do not dump the contents of unlogged tables. This option has no
+ effect on whether or not the table definitions (schema) are dumped;
+ it only suppresses dumping the table data.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--on-conflict-do-nothing</option></term>
+ <listitem>
+ <para>
+ Add <literal>ON CONFLICT DO NOTHING</literal> to
+ <command>INSERT</command> commands.
+ This option is not valid unless <option>--inserts</option> or
+ <option>--column-inserts</option> is also specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--quote-all-identifiers</option></term>
+ <listitem>
+ <para>
+ Force quoting of all identifiers. This option is recommended when
+ dumping a database from a server whose <productname>PostgreSQL</productname>
+ major version is different from <application>pg_dumpall</application>'s, or when
+ the output is intended to be loaded into a server of a different
+ major version. By default, <application>pg_dumpall</application> quotes only
+ identifiers that are reserved words in its own major version.
+ This sometimes results in compatibility issues when dealing with
+ servers of other versions that may have slightly different sets
+ of reserved words. Using <option>--quote-all-identifiers</option> prevents
+ such issues, at the price of a harder-to-read dump script.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--rows-per-insert=<replaceable class="parameter">nrows</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump data as <command>INSERT</command> commands (rather than
+ <command>COPY</command>). Controls the maximum number of rows per
+ <command>INSERT</command> command. The value specified must be a
+ number greater than zero. Any error during restoring will cause only
+ rows that are part of the problematic <command>INSERT</command> to be
+ lost, rather than the entire table contents.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--use-set-session-authorization</option></term>
+ <listitem>
+ <para>
+ Output SQL-standard <command>SET SESSION AUTHORIZATION</command> commands
+ instead of <command>ALTER OWNER</command> commands to determine object
+ ownership. This makes the dump more standards compatible, but
+ depending on the history of the objects in the dump, might not restore
+ properly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_dumpall</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ The following command-line options control the database connection parameters.
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies parameters used to connect to the server, as a <link
+ linkend="libpq-connstring">connection string</link>; these
+ will override any conflicting command line options.
+ </para>
+ <para>
+ The option is called <literal>--dbname</literal> for consistency with other
+ client applications, but because <application>pg_dumpall</application>
+ needs to connect to many databases, the database name in the
+ connection string will be ignored. Use the <literal>-l</literal>
+ option to specify the name of the database used for the initial
+ connection, which will dump global objects and discover what other
+ databases should be dumped.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable>host</replaceable></option></term>
+ <term><option>--host=<replaceable>host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the database
+ server is running. If the value begins with a slash, it is
+ used as the directory for the Unix domain socket. The default
+ is taken from the <envar>PGHOST</envar> environment variable,
+ if set, else a Unix domain socket connection is attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l <replaceable>dbname</replaceable></option></term>
+ <term><option>--database=<replaceable>dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to for dumping global
+ objects and discovering what other databases should be dumped. If
+ not specified, the <literal>postgres</literal> database will be used,
+ and if that does not exist, <literal>template1</literal> will be used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable>port</replaceable></option></term>
+ <term><option>--port=<replaceable>port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <envar>PGPORT</envar> environment variable, if
+ set, or a compiled-in default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>username</replaceable></option></term>
+ <term><option>--username=<replaceable>username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>pg_dumpall</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>pg_dumpall</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>pg_dumpall</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+
+ <para>
+ Note that the password prompt will occur again for each database
+ to be dumped. Usually, it's better to set up a
+ <filename>~/.pgpass</filename> file than to rely on manual password entry.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--role=<replaceable class="parameter">rolename</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies a role name to be used to create the dump.
+ This option causes <application>pg_dumpall</application> to issue a
+ <command>SET ROLE</command> <replaceable class="parameter">rolename</replaceable>
+ command after connecting to the database. It is useful when the
+ authenticated user (specified by <option>-U</option>) lacks privileges
+ needed by <application>pg_dumpall</application>, but can switch to a role with
+ the required rights. Some installations have a policy against
+ logging in directly as a superuser, and use of this option allows
+ dumps to be made without violating the policy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGOPTIONS</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Since <application>pg_dumpall</application> calls
+ <application>pg_dump</application> internally, some diagnostic
+ messages will refer to <application>pg_dump</application>.
+ </para>
+
+ <para>
+ The <option>--clean</option> option can be useful even when your
+ intention is to restore the dump script into a fresh cluster. Use of
+ <option>--clean</option> authorizes the script to drop and re-create the
+ built-in <literal>postgres</literal> and <literal>template1</literal>
+ databases, ensuring that those databases will retain the same properties
+ (for instance, locale and encoding) that they had in the source cluster.
+ Without the option, those databases will retain their existing
+ database-level properties, as well as any pre-existing contents.
+ </para>
+
+ <para>
+ Once restored, it is wise to run <command>ANALYZE</command> on each
+ database so the optimizer has useful statistics. You
+ can also run <command>vacuumdb -a -z</command> to analyze all
+ databases.
+ </para>
+
+ <para>
+ The dump script should not be expected to run completely without errors.
+ In particular, because the script will issue <command>CREATE ROLE</command>
+ for every role existing in the source cluster, it is certain to get a
+ <quote>role already exists</quote> error for the bootstrap superuser,
+ unless the destination cluster was initialized with a different bootstrap
+ superuser name. This error is harmless and should be ignored. Use of
+ the <option>--clean</option> option is likely to produce additional
+ harmless error messages about non-existent objects, although you can
+ minimize those by adding <option>--if-exists</option>.
+ </para>
+
+ <para>
+ <application>pg_dumpall</application> requires all needed
+ tablespace directories to exist before the restore; otherwise,
+ database creation will fail for databases in non-default
+ locations.
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="app-pg-dumpall-ex">
+ <title>Examples</title>
+ <para>
+ To dump all databases:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dumpall &gt; db.out</userinput>
+</screen>
+ </para>
+
+ <para>
+ To restore database(s) from this file, you can use:
+<screen>
+<prompt>$</prompt> <userinput>psql -f db.out postgres</userinput>
+</screen>
+ It is not important to which database you connect here since the
+ script file created by <application>pg_dumpall</application> will
+ contain the appropriate commands to create and connect to the saved
+ databases. An exception is that if you specified <option>--clean</option>,
+ you must connect to the <literal>postgres</literal> database initially;
+ the script will attempt to drop other databases immediately, and that
+ will fail for the database you are connected to.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ Check <xref linkend="app-pgdump"/> for details on possible
+ error conditions.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_isready.sgml b/doc/src/sgml/ref/pg_isready.sgml
new file mode 100644
index 0000000..ba25ca6
--- /dev/null
+++ b/doc/src/sgml/ref/pg_isready.sgml
@@ -0,0 +1,217 @@
+<!--
+doc/src/sgml/ref/pg_isready.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pg-isready">
+ <indexterm zone="app-pg-isready">
+ <primary>pg_isready</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_isready</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_isready</refname>
+ <refpurpose>check the connection status of a <productname>PostgreSQL</productname> server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_isready</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="app-pg-isready-description">
+ <title>Description</title>
+ <para>
+ <application>pg_isready</application> is a utility for checking the connection
+ status of a <productname>PostgreSQL</productname> database server. The exit
+ status specifies the result of the connection check.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-pg-isready-options">
+ <title>Options</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to. The
+ <replaceable>dbname</replaceable> can be a <link
+ linkend="libpq-connstring">connection string</link>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">hostname</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">hostname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the
+ server is running. If the value begins
+ with a slash, it is used as the directory for the Unix-domain
+ socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or the local Unix-domain
+ socket file extension on which the server is listening for
+ connections. Defaults to the value of the <envar>PGPORT</envar>
+ environment variable or, if not set, to the port specified at
+ compile time, usually 5432.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Do not display status message. This is useful when scripting.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">seconds</replaceable></option></term>
+ <term><option>--timeout=<replaceable class="parameter">seconds</replaceable></option></term>
+ <listitem>
+ <para>
+ The maximum number of seconds to wait when attempting connection before
+ returning that the server is not responding. Setting to 0 disables. The
+ default is 3 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Connect to the database as the user <replaceable
+ class="parameter">username</replaceable> instead of the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_isready</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_isready</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Exit Status</title>
+
+ <para>
+ <application>pg_isready</application> returns <literal>0</literal> to the shell if the server
+ is accepting connections normally, <literal>1</literal> if the server is rejecting
+ connections (for example during startup), <literal>2</literal> if there was no response to the
+ connection attempt, and <literal>3</literal> if no attempt was made (for example due to invalid
+ parameters).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ <command>pg_isready</command>, like most other <productname>PostgreSQL</productname>
+ utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-pg-isready-notes">
+ <title>Notes</title>
+
+ <para>
+ It is not necessary to supply correct user name, password, or database
+ name values to obtain the server status; however, if incorrect values
+ are provided, the server will log a failed connection attempt.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-pg-isready-examples">
+ <title>Examples</title>
+
+ <para>
+ Standard Usage:
+<screen>
+<prompt>$</prompt> <userinput>pg_isready</userinput>
+<computeroutput>/tmp:5432 - accepting connections</computeroutput>
+<prompt>$</prompt> <userinput>echo $?</userinput>
+<computeroutput>0</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ Running with connection parameters to a <productname>PostgreSQL</productname> cluster in startup:
+<screen>
+<prompt>$ </prompt><userinput>pg_isready -h localhost -p 5433</userinput>
+<computeroutput>localhost:5433 - rejecting connections</computeroutput>
+<prompt>$</prompt> <userinput>echo $?</userinput>
+<computeroutput>1</computeroutput>
+</screen>
+ </para>
+
+ <para>
+ Running with connection parameters to a non-responsive <productname>PostgreSQL</productname> cluster:
+<screen>
+<prompt>$ </prompt><userinput>pg_isready -h someremotehost</userinput>
+<computeroutput>someremotehost:5432 - no response</computeroutput>
+<prompt>$</prompt> <userinput>echo $?</userinput>
+<computeroutput>2</computeroutput>
+</screen>
+ </para>
+
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_receivewal.sgml b/doc/src/sgml/ref/pg_receivewal.sgml
new file mode 100644
index 0000000..409e502
--- /dev/null
+++ b/doc/src/sgml/ref/pg_receivewal.sgml
@@ -0,0 +1,530 @@
+<!--
+doc/src/sgml/ref/pg_receivewal.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgreceivewal">
+ <indexterm zone="app-pgreceivewal">
+ <primary>pg_receivewal</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_receivewal</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_receivewal</refname>
+ <refpurpose>stream write-ahead logs from a <productname>PostgreSQL</productname> server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_receivewal</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ <application>pg_receivewal</application> is used to stream the write-ahead log
+ from a running <productname>PostgreSQL</productname> cluster. The write-ahead
+ log is streamed using the streaming replication protocol, and is written
+ to a local directory of files. This directory can be used as the archive
+ location for doing a restore using point-in-time recovery (see
+ <xref linkend="continuous-archiving"/>).
+ </para>
+
+ <para>
+ <application>pg_receivewal</application> streams the write-ahead
+ log in real time as it's being generated on the server, and does not wait
+ for segments to complete like <xref linkend="guc-archive-command"/> and
+ <xref linkend="guc-archive-library"/> do.
+ For this reason, it is not necessary to set
+ <xref linkend="guc-archive-timeout"/> when using
+ <application>pg_receivewal</application>.
+ </para>
+
+ <para>
+ Unlike the WAL receiver of a PostgreSQL standby server, <application>pg_receivewal</application>
+ by default flushes WAL data only when a WAL file is closed.
+ The option <option>--synchronous</option> must be specified to flush WAL data
+ in real time. Since <application>pg_receivewal</application> does not
+ apply WAL, you should not allow it to become a synchronous standby when
+ <xref linkend="guc-synchronous-commit"/> equals
+ <literal>remote_apply</literal>. If it does, it will appear to be a
+ standby that never catches up, and will cause transaction commits to
+ block. To avoid this, you should either configure an appropriate value
+ for <xref linkend="guc-synchronous-standby-names"/>, or specify
+ <varname>application_name</varname> for
+ <application>pg_receivewal</application> that does not match it, or
+ change the value of <varname>synchronous_commit</varname> to
+ something other than <literal>remote_apply</literal>.
+ </para>
+
+ <para>
+ The write-ahead log is streamed over a regular
+ <productname>PostgreSQL</productname> connection and uses the replication
+ protocol. The connection must be made with a user having
+ <literal>REPLICATION</literal> permissions (see
+ <xref linkend="role-attributes"/>) or a superuser, and
+ <filename>pg_hba.conf</filename> must permit the replication connection.
+ The server must also be configured with
+ <xref linkend="guc-max-wal-senders"/> set high enough to leave at least
+ one session available for the stream.
+ </para>
+
+ <para>
+ The starting point of the write-ahead log streaming is calculated when
+ <application>pg_receivewal</application> starts:
+ <orderedlist>
+ <listitem>
+ <para>
+ First, scan the directory where the WAL segment files are written and
+ find the newest completed segment file, using as the starting point the
+ beginning of the next WAL segment file.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If a starting point cannot be calculated with the previous method,
+ and if a replication slot is used, an extra
+ <command>READ_REPLICATION_SLOT</command> command is issued to retrieve
+ the slot's <literal>restart_lsn</literal> to use as the starting point.
+ This option is only available when streaming write-ahead logs from
+ <productname>PostgreSQL</productname> 15 and up.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If a starting point cannot be calculated with the previous method,
+ the latest WAL flush location is used as reported by the server from
+ an <literal>IDENTIFY_SYSTEM</literal> command.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ If the connection is lost, or if it cannot be initially established,
+ with a non-fatal error, <application>pg_receivewal</application> will
+ retry the connection indefinitely, and reestablish streaming as soon
+ as possible. To avoid this behavior, use the <literal>-n</literal>
+ parameter.
+ </para>
+
+ <para>
+ In the absence of fatal errors, <application>pg_receivewal</application>
+ will run until terminated by the <systemitem>SIGINT</systemitem> signal
+ (<keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">directory</replaceable></option></term>
+ <term><option>--directory=<replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Directory to write the output to.
+ </para>
+ <para>
+ This parameter is required.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E <replaceable>lsn</replaceable></option></term>
+ <term><option>--endpos=<replaceable>lsn</replaceable></option></term>
+ <listitem>
+ <para>
+ Automatically stop replication and exit with normal exit status 0 when
+ receiving reaches the specified LSN.
+ </para>
+
+ <para>
+ If there is a record with LSN exactly equal to <replaceable>lsn</replaceable>,
+ the record will be processed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-not-exists</option></term>
+ <listitem>
+ <para>
+ Do not error out when <option>--create-slot</option> is specified
+ and a slot with the specified name already exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-loop</option></term>
+ <listitem>
+ <para>
+ Don't loop on connection errors. Instead, exit right away with
+ an error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ This option causes <command>pg_receivewal</command> to not force WAL
+ data to be flushed to disk. This is faster, but means that a
+ subsequent operating system crash can leave the WAL segments corrupt.
+ Generally, this option is useful for testing but should not be used
+ when doing WAL archiving on a production deployment.
+ </para>
+
+ <para>
+ This option is incompatible with <literal>--synchronous</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s <replaceable class="parameter">interval</replaceable></option></term>
+ <term><option>--status-interval=<replaceable class="parameter">interval</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the number of seconds between status packets sent back to the
+ server. This allows for easier monitoring of the progress from server.
+ A value of zero disables the periodic status updates completely,
+ although an update will still be sent when requested by the server, to
+ avoid timeout disconnect. The default value is 10 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable>slotname</replaceable></option></term>
+ <term><option>--slot=<replaceable class="parameter">slotname</replaceable></option></term>
+ <listitem>
+ <para>
+ Require <application>pg_receivewal</application> to use an existing
+ replication slot (see <xref linkend="streaming-replication-slots"/>).
+ When this option is used, <application>pg_receivewal</application> will report
+ a flush position to the server, indicating when each segment has been
+ synchronized to disk so that the server can remove that segment if it
+ is not otherwise needed.
+ </para>
+
+ <para>
+ When the replication client
+ of <application>pg_receivewal</application> is configured on the
+ server as a synchronous standby, then using a replication slot will
+ report the flush position to the server, but only when a WAL file is
+ closed. Therefore, that configuration will cause transactions on the
+ primary to wait for a long time and effectively not work
+ satisfactorily. The option <literal>--synchronous</literal> (see
+ below) must be specified in addition to make this work correctly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--synchronous</option></term>
+ <listitem>
+ <para>
+ Flush the WAL data to disk immediately after it has been received. Also
+ send a status packet back to the server immediately after flushing,
+ regardless of <literal>--status-interval</literal>.
+ </para>
+
+ <para>
+ This option should be specified if the replication client
+ of <application>pg_receivewal</application> is configured on the
+ server as a synchronous standby, to ensure that timely feedback is
+ sent to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Enables verbose mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-Z <replaceable class="parameter">level</replaceable></option></term>
+ <term><option>-Z <replaceable class="parameter">method</replaceable>[:<replaceable>detail</replaceable>]</option></term>
+ <term><option>--compress=<replaceable class="parameter">level</replaceable></option></term>
+ <term><option>--compress=<replaceable class="parameter">method</replaceable>[:<replaceable>detail</replaceable>]</option></term>
+ <listitem>
+ <para>
+ Enables compression of write-ahead logs.
+ </para>
+ <para>
+ The compression method can be set to <literal>gzip</literal>,
+ <literal>lz4</literal> (if <productname>PostgreSQL</productname>
+ was compiled with <option>--with-lz4</option>) or
+ <literal>none</literal> for no compression.
+ A compression detail string can optionally be specified. If the
+ detail string is an integer, it specifies the compression level.
+ Otherwise, it should be a comma-separated list of items, each of the
+ form <literal>keyword</literal> or <literal>keyword=value</literal>.
+ Currently, the only supported keyword is <literal>level</literal>.
+ </para>
+ <para>
+ If no compression level is specified, the default compression level
+ will be used. If only a level is specified without mentioning an
+ algorithm, <literal>gzip</literal> compression will be used if the
+ level is greater than 0, and no compression will be used if the level
+ is 0.
+ </para>
+ <para>
+ The suffix <filename>.gz</filename> will automatically be added to
+ all filenames when using <literal>gzip</literal>, and the suffix
+ <filename>.lz4</filename> is added when using <literal>lz4</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The following command-line options control the database connection parameters.
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">connstr</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">connstr</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies parameters used to connect to the server, as a <link
+ linkend="libpq-connstring">connection string</link>; these
+ will override any conflicting command line options.
+ </para>
+ <para>
+ The option is called <literal>--dbname</literal> for consistency with other
+ client applications, but because <application>pg_receivewal</application>
+ doesn't connect to any particular database in the cluster, database
+ name in the connection string will be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <envar>PGHOST</envar> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <envar>PGPORT</envar> environment variable, if
+ set, or a compiled-in default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>pg_receivewal</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>pg_receivewal</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>pg_receivewal</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <application>pg_receivewal</application> can perform one of the two
+ following actions in order to control physical replication slots:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--create-slot</option></term>
+ <listitem>
+ <para>
+ Create a new physical replication slot with the name specified in
+ <option>--slot</option>, then exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--drop-slot</option></term>
+ <listitem>
+ <para>
+ Drop the replication slot with the name specified in
+ <option>--slot</option>, then exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Other options are also available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_receivewal</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_receivewal</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Exit Status</title>
+
+ <para>
+ <application>pg_receivewal</application> will exit with status 0 when
+ terminated by the <systemitem>SIGINT</systemitem> signal. (That is the
+ normal way to end it. Hence it is not an error.) For fatal errors or
+ other signals, the exit status will be nonzero.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When using <application>pg_receivewal</application> instead of
+ <xref linkend="guc-archive-command"/> or
+ <xref linkend="guc-archive-library"/> as the main WAL backup method, it is
+ strongly recommended to use replication slots. Otherwise, the server is
+ free to recycle or remove write-ahead log files before they are backed up,
+ because it does not have any information, either
+ from <xref linkend="guc-archive-command"/> or
+ <xref linkend="guc-archive-library"/> or the replication slots, about
+ how far the WAL stream has been archived. Note, however, that a
+ replication slot will fill up the server's disk space if the receiver does
+ not keep up with fetching the WAL data.
+ </para>
+
+ <para>
+ <application>pg_receivewal</application> will preserve group permissions on
+ the received WAL files if group permissions are enabled on the source
+ cluster.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To stream the write-ahead log from the server at
+ <literal>mydbserver</literal> and store it in the local directory
+ <filename>/usr/local/pgsql/archive</filename>:
+<screen>
+<prompt>$</prompt> <userinput>pg_receivewal -h mydbserver -D /usr/local/pgsql/archive</userinput>
+</screen></para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pgbasebackup"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_recvlogical.sgml b/doc/src/sgml/ref/pg_recvlogical.sgml
new file mode 100644
index 0000000..7c01a5c
--- /dev/null
+++ b/doc/src/sgml/ref/pg_recvlogical.sgml
@@ -0,0 +1,453 @@
+<!--
+doc/src/sgml/ref/pg_recvlogical.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgrecvlogical">
+ <indexterm zone="app-pgrecvlogical">
+ <primary>pg_recvlogical</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_recvlogical</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_recvlogical</refname>
+ <refpurpose>control <productname>PostgreSQL</productname> logical decoding streams</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_recvlogical</command>
+ <arg rep="repeat" choice="opt"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ <command>pg_recvlogical</command> controls logical decoding replication
+ slots and streams data from such replication slots.
+ </para>
+
+ <para>
+ It creates a replication-mode connection, so it is subject to the same
+ constraints as <xref linkend="app-pgreceivewal"/>, plus those for logical
+ replication (see <xref linkend="logicaldecoding"/>).
+ </para>
+
+ <para>
+ <command>pg_recvlogical</command> has no equivalent to the logical decoding
+ SQL interface's peek and get modes. It sends replay confirmations for
+ data lazily as it receives it and on clean exit. To examine pending data on
+ a slot without consuming it, use
+ <link linkend="functions-replication"><function>pg_logical_slot_peek_changes</function></link>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ At least one of the following options must be specified to select an action:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--create-slot</option></term>
+ <listitem>
+ <para>
+ Create a new logical replication slot with the name specified by
+ <option>--slot</option>, using the output plugin specified by
+ <option>--plugin</option>, for the database specified
+ by <option>--dbname</option>.
+ </para>
+
+ <para>
+ The <option>--two-phase</option> can be specified with
+ <option>--create-slot</option> to enable decoding of prepared transactions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--drop-slot</option></term>
+ <listitem>
+ <para>
+ Drop the replication slot with the name specified
+ by <option>--slot</option>, then exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--start</option></term>
+ <listitem>
+ <para>
+ Begin streaming changes from the logical replication slot specified
+ by <option>--slot</option>, continuing until terminated by a
+ signal. If the server side change stream ends with a server shutdown
+ or disconnect, retry in a loop unless
+ <option>--no-loop</option> is specified.
+ </para>
+
+ <para>
+ The stream format is determined by the output plugin specified when
+ the slot was created.
+ </para>
+
+ <para>
+ The connection must be to the same database used to create the slot.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <option>--create-slot</option> and <option>--start</option> can be
+ specified together. <option>--drop-slot</option> cannot be combined with
+ another action.
+ </para>
+
+ <para>
+ The following command-line options control the location and format of the
+ output and other replication behavior:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-E <replaceable>lsn</replaceable></option></term>
+ <term><option>--endpos=<replaceable>lsn</replaceable></option></term>
+ <listitem>
+ <para>
+ In <option>--start</option> mode, automatically stop replication
+ and exit with normal exit status 0 when receiving reaches the
+ specified LSN. If specified when not in <option>--start</option>
+ mode, an error is raised.
+ </para>
+
+ <para>
+ If there's a record with LSN exactly equal to <replaceable>lsn</replaceable>,
+ the record will be output.
+ </para>
+
+ <para>
+ The <option>--endpos</option> option is not aware of transaction
+ boundaries and may truncate output partway through a transaction.
+ Any partially output transaction will not be consumed and will be
+ replayed again when the slot is next read from. Individual messages
+ are never truncated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f <replaceable>filename</replaceable></option></term>
+ <term><option>--file=<replaceable>filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Write received and decoded transaction data into this
+ file. Use <literal>-</literal> for <systemitem>stdout</systemitem>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F <replaceable>interval_seconds</replaceable></option></term>
+ <term><option>--fsync-interval=<replaceable>interval_seconds</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies how often <application>pg_recvlogical</application> should
+ issue <function>fsync()</function> calls to ensure the output file is
+ safely flushed to disk.
+ </para>
+
+ <para>
+ The server will occasionally request the client to perform a flush and
+ report the flush position to the server. This setting is in addition
+ to that, to perform flushes more frequently.
+ </para>
+
+ <para>
+ Specifying an interval of <literal>0</literal> disables
+ issuing <function>fsync()</function> calls altogether, while still
+ reporting progress to the server. In this case, data could be lost in
+ the event of a crash.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-I <replaceable>lsn</replaceable></option></term>
+ <term><option>--startpos=<replaceable>lsn</replaceable></option></term>
+ <listitem>
+ <para>
+ In <option>--start</option> mode, start replication from the given
+ LSN. For details on the effect of this, see the documentation
+ in <xref linkend="logicaldecoding"/>
+ and <xref linkend="protocol-replication"/>. Ignored in other modes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-not-exists</option></term>
+ <listitem>
+ <para>
+ Do not error out when <option>--create-slot</option> is specified
+ and a slot with the specified name already exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-loop</option></term>
+ <listitem>
+ <para>
+ When the connection to the server is lost, do not retry in a loop, just exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable>name</replaceable>[=<replaceable>value</replaceable>]</option></term>
+ <term><option>--option=<replaceable>name</replaceable>[=<replaceable>value</replaceable>]</option></term>
+ <listitem>
+ <para>
+ Pass the option <replaceable>name</replaceable> to the output plugin with,
+ if specified, the option value <replaceable>value</replaceable>. Which
+ options exist and their effects depends on the used output plugin.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P <replaceable>plugin</replaceable></option></term>
+ <term><option>--plugin=<replaceable>plugin</replaceable></option></term>
+ <listitem>
+ <para>
+ When creating a slot, use the specified logical decoding output
+ plugin. See <xref linkend="logicaldecoding"/>. This option has no
+ effect if the slot already exists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s <replaceable>interval_seconds</replaceable></option></term>
+ <term><option>--status-interval=<replaceable>interval_seconds</replaceable></option></term>
+ <listitem>
+ <para>
+ This option has the same effect as the option of the same name
+ in <xref linkend="app-pgreceivewal"/>. See the description there.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable>slot_name</replaceable></option></term>
+ <term><option>--slot=<replaceable>slot_name</replaceable></option></term>
+ <listitem>
+ <para>
+ In <option>--start</option> mode, use the existing logical replication slot named
+ <replaceable>slot_name</replaceable>. In <option>--create-slot</option>
+ mode, create the slot with this name. In <option>--drop-slot</option>
+ mode, delete the slot with this name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option></term>
+ <term><option>--two-phase</option></term>
+ <listitem>
+ <para>
+ Enables decoding of prepared transactions. This option may only be specified with
+ <option>--create-slot</option>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Enables verbose mode.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following command-line options control the database connection parameters.
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-d <replaceable>dbname</replaceable></option></term>
+ <term><option>--dbname=<replaceable>dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ The database to connect to. See the description
+ of the actions for what this means in detail.
+ The <replaceable>dbname</replaceable> can be a <link
+ linkend="libpq-connstring">connection string</link>. If so,
+ connection string parameters will override any conflicting
+ command line options. Defaults to the user name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable>hostname-or-ip</replaceable></option></term>
+ <term><option>--host=<replaceable>hostname-or-ip</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <envar>PGHOST</envar> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable>port</replaceable></option></term>
+ <term><option>--port=<replaceable>port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <envar>PGPORT</envar> environment variable, if
+ set, or a compiled-in default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>user</replaceable></option></term>
+ <term><option>--username=<replaceable>user</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as. Defaults to current operating system user
+ name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>pg_recvlogical</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>pg_recvlogical</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>pg_recvlogical</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The following additional options are available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_recvlogical</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_recvlogical</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>pg_recvlogical</application> will preserve group permissions on
+ the received WAL files if group permissions are enabled on the source
+ cluster.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ See <xref linkend="logicaldecoding-example"/> for an example.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pgreceivewal"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml
new file mode 100644
index 0000000..fd539f5
--- /dev/null
+++ b/doc/src/sgml/ref/pg_resetwal.sgml
@@ -0,0 +1,386 @@
+<!--
+doc/src/sgml/ref/pg_resetwal.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgresetwal">
+ <indexterm zone="app-pgresetwal">
+ <primary>pg_resetwal</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_resetwal</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_resetwal</refname>
+ <refpurpose>reset the write-ahead log and other control information of a <productname>PostgreSQL</productname> database cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_resetwal</command>
+ <group choice="opt">
+ <arg choice="plain"><option>-f</option></arg>
+ <arg choice="plain"><option>--force</option></arg>
+ </group>
+ <group choice="opt">
+ <arg choice="plain"><option>-n</option></arg>
+ <arg choice="plain"><option>--dry-run</option></arg>
+ </group>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <group choice="plain">
+ <group choice="opt">
+ <arg choice="plain"><option>-D</option></arg>
+ <arg choice="plain"><option>--pgdata</option></arg>
+ </group>
+ <replaceable class="parameter">datadir</replaceable>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="r1-app-pgresetwal-1">
+ <title>Description</title>
+ <para>
+ <command>pg_resetwal</command> clears the write-ahead log (WAL) and
+ optionally resets some other control information stored in the
+ <filename>pg_control</filename> file. This function is sometimes needed
+ if these files have become corrupted. It should be used only as a
+ last resort, when the server will not start due to such corruption.
+ </para>
+
+ <para>
+ After running this command, it should be possible to start the server,
+ but bear in mind that the database might contain inconsistent data due to
+ partially-committed transactions. You should immediately dump your data,
+ run <command>initdb</command>, and restore. After restore, check for
+ inconsistencies and repair as needed.
+ </para>
+
+ <para>
+ This utility can only be run by the user who installed the server, because
+ it requires read/write access to the data directory.
+ For safety reasons, you must specify the data directory on the command line.
+ <command>pg_resetwal</command> does not use the environment variable
+ <envar>PGDATA</envar>.
+ </para>
+
+ <para>
+ If <command>pg_resetwal</command> complains that it cannot determine
+ valid data for <filename>pg_control</filename>, you can force it to proceed anyway
+ by specifying the <option>-f</option> (force) option. In this case plausible
+ values will be substituted for the missing data. Most of the fields can be
+ expected to match, but manual assistance might be needed for the next OID,
+ next transaction ID and epoch, next multitransaction ID and offset, and
+ WAL starting location fields. These fields can be set using the options
+ discussed below. If you are not able to determine correct values for all
+ these fields, <option>-f</option> can still be used, but
+ the recovered database must be treated with even more suspicion than
+ usual: an immediate dump and restore is imperative. <emphasis>Do not</emphasis>
+ execute any data-modifying operations in the database before you dump,
+ as any such action is likely to make the corruption worse.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-f</option></term>
+ <term><option>--force</option></term>
+ <listitem>
+ <para>
+ Force <command>pg_resetwal</command> to proceed even if it cannot determine
+ valid data for <filename>pg_control</filename>, as explained above.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--dry-run</option></term>
+ <listitem>
+ <para>
+ The <option>-n</option>/<option>--dry-run</option> option instructs
+ <command>pg_resetwal</command> to print the values reconstructed from
+ <filename>pg_control</filename> and values about to be changed, and then exit
+ without modifying anything. This is mainly a debugging tool, but can be
+ useful as a sanity check before allowing <command>pg_resetwal</command>
+ to proceed for real.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem><para>Display version information, then exit.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem><para>Show help, then exit.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The following options are only needed when
+ <command>pg_resetwal</command> is unable to determine appropriate values
+ by reading <filename>pg_control</filename>. Safe values can be determined as
+ described below. For values that take numeric arguments, hexadecimal
+ values can be specified by using the prefix <literal>0x</literal>.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-c <replaceable class="parameter">xid</replaceable>,<replaceable class="parameter">xid</replaceable></option></term>
+ <term><option>--commit-timestamp-ids=<replaceable class="parameter">xid</replaceable>,<replaceable class="parameter">xid</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the oldest and newest transaction IDs for which the commit
+ time can be retrieved.
+ </para>
+
+ <para>
+ A safe value for the oldest transaction ID for which the commit time can
+ be retrieved (first part) can be determined by looking
+ for the numerically smallest file name in the directory
+ <filename>pg_commit_ts</filename> under the data directory. Conversely, a safe
+ value for the newest transaction ID for which the commit time can be
+ retrieved (second part) can be determined by looking for the numerically
+ greatest file name in the same directory. The file names are in
+ hexadecimal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e <replaceable class="parameter">xid_epoch</replaceable></option></term>
+ <term><option>--epoch=<replaceable class="parameter">xid_epoch</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the next transaction ID's epoch.
+ </para>
+
+ <para>
+ The transaction ID epoch is not actually stored anywhere in the database
+ except in the field that is set by <command>pg_resetwal</command>,
+ so any value will work so far as the database itself is concerned.
+ You might need to adjust this value to ensure that replication
+ systems such as <application>Slony-I</application> and
+ <application>Skytools</application> work correctly &mdash;
+ if so, an appropriate value should be obtainable from the state of
+ the downstream replicated database.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l <replaceable class="parameter">walfile</replaceable></option></term>
+ <term><option>--next-wal-file=<replaceable class="parameter">walfile</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the WAL starting location by specifying the name of the
+ next WAL segment file.
+ </para>
+
+ <para>
+ The name of next WAL segment file should be
+ larger than any WAL segment file name currently existing in
+ the directory <filename>pg_wal</filename> under the data directory.
+ These names are also in hexadecimal and have three parts. The first
+ part is the <quote>timeline ID</quote> and should usually be kept the same.
+ For example, if <filename>00000001000000320000004A</filename> is the
+ largest entry in <filename>pg_wal</filename>, use <literal>-l 00000001000000320000004B</literal> or higher.
+ </para>
+
+ <para>
+ Note that when using nondefault WAL segment sizes, the numbers in the WAL
+ file names are different from the LSNs that are reported by system
+ functions and system views. This option takes a WAL file name, not an
+ LSN.
+ </para>
+
+ <note>
+ <para>
+ <command>pg_resetwal</command> itself looks at the files in
+ <filename>pg_wal</filename> and chooses a default <option>-l</option> setting
+ beyond the last existing file name. Therefore, manual adjustment of
+ <option>-l</option> should only be needed if you are aware of WAL segment
+ files that are not currently present in <filename>pg_wal</filename>, such as
+ entries in an offline archive; or if the contents of
+ <filename>pg_wal</filename> have been lost entirely.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-m <replaceable class="parameter">mxid</replaceable>,<replaceable class="parameter">mxid</replaceable></option></term>
+ <term><option>--multixact-ids=<replaceable class="parameter">mxid</replaceable>,<replaceable class="parameter">mxid</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the next and oldest multitransaction ID.
+ </para>
+
+ <para>
+ A safe value for the next multitransaction ID (first part) can be
+ determined by looking for the numerically largest file name in the
+ directory <filename>pg_multixact/offsets</filename> under the data directory,
+ adding one, and then multiplying by 65536 (0x10000). Conversely, a safe
+ value for the oldest multitransaction ID (second part of
+ <option>-m</option>) can be determined by looking for the numerically smallest
+ file name in the same directory and multiplying by 65536. The file
+ names are in hexadecimal, so the easiest way to do this is to specify
+ the option value in hexadecimal and append four zeroes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable class="parameter">oid</replaceable></option></term>
+ <term><option>--next-oid=<replaceable class="parameter">oid</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the next OID.
+ </para>
+
+ <para>
+ There is no comparably easy way to determine a next OID that's beyond
+ the largest one in the database, but fortunately it is not critical to
+ get the next-OID setting right.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O <replaceable class="parameter">mxoff</replaceable></option></term>
+ <term><option>--multixact-offset=<replaceable class="parameter">mxoff</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the next multitransaction offset.
+ </para>
+
+ <para>
+ A safe value can be determined by looking for the numerically largest
+ file name in the directory <filename>pg_multixact/members</filename> under the
+ data directory, adding one, and then multiplying by 52352 (0xCC80).
+ The file names are in hexadecimal. There is no simple recipe such as
+ the ones for other options of appending zeroes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--wal-segsize=<replaceable class="parameter">wal_segment_size</replaceable></option></term>
+ <listitem>
+ <para>
+ Set the new WAL segment size, in megabytes. The value must be set to a
+ power of 2 between 1 and 1024 (megabytes). See the same option of <xref
+ linkend="app-initdb"/> for more information.
+ </para>
+
+ <note>
+ <para>
+ While <command>pg_resetwal</command> will set the WAL starting address
+ beyond the latest existing WAL segment file, some segment size changes
+ can cause previous WAL file names to be reused. It is recommended to
+ use <option>-l</option> together with this option to manually set the
+ WAL starting address if WAL file name overlap will cause problems with
+ your archiving strategy.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-u <replaceable class="parameter">xid</replaceable></option></term>
+ <term><option>--oldest-transaction-id=<replaceable class="parameter">xid</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the oldest unfrozen transaction ID.
+ </para>
+
+ <para>
+ A safe value can be determined by looking for the numerically smallest
+ file name in the directory <filename>pg_xact</filename> under the data directory
+ and then multiplying by 1048576 (0x100000). Note that the file names are in
+ hexadecimal. It is usually easiest to specify the option value in
+ hexadecimal too. For example, if <filename>0007</filename> is the smallest entry
+ in <filename>pg_xact</filename>, <literal>-u 0x700000</literal> will work (five
+ trailing zeroes provide the proper multiplier).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x <replaceable class="parameter">xid</replaceable></option></term>
+ <term><option>--next-transaction-id=<replaceable class="parameter">xid</replaceable></option></term>
+ <listitem>
+ <para>
+ Manually set the next transaction ID.
+ </para>
+
+ <para>
+ A safe value can be determined by looking for the numerically largest
+ file name in the directory <filename>pg_xact</filename> under the data directory,
+ adding one,
+ and then multiplying by 1048576 (0x100000). Note that the file names are in
+ hexadecimal. It is usually easiest to specify the option value in
+ hexadecimal too. For example, if <filename>0011</filename> is the largest entry
+ in <filename>pg_xact</filename>, <literal>-x 0x1200000</literal> will work (five
+ trailing zeroes provide the proper multiplier).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ This command must not be used when the server is
+ running. <command>pg_resetwal</command> will refuse to start up if
+ it finds a server lock file in the data directory. If the
+ server crashed then a lock file might have been left
+ behind; in that case you can remove the lock file to allow
+ <command>pg_resetwal</command> to run. But before you do
+ so, make doubly certain that there is no server process still alive.
+ </para>
+
+ <para>
+ <command>pg_resetwal</command> works only with servers of the same
+ major version.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pgcontroldata"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
new file mode 100644
index 0000000..47bd7db
--- /dev/null
+++ b/doc/src/sgml/ref/pg_restore.sgml
@@ -0,0 +1,1044 @@
+<!--
+doc/src/sgml/ref/pg_restore.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgrestore">
+ <indexterm zone="app-pgrestore">
+ <primary>pg_restore</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_restore</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_restore</refname>
+
+ <refpurpose>
+ restore a <productname>PostgreSQL</productname> database from an
+ archive file created by <application>pg_dump</application>
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_restore</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>filename</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="app-pgrestore-description">
+ <title>Description</title>
+
+ <para>
+ <application>pg_restore</application> is a utility for restoring a
+ <productname>PostgreSQL</productname> database from an archive
+ created by <xref linkend="app-pgdump"/> in one of the non-plain-text
+ formats. It will issue the commands necessary to reconstruct the
+ database to the state it was in at the time it was saved. The
+ archive files also allow <application>pg_restore</application> to
+ be selective about what is restored, or even to reorder the items
+ prior to being restored. The archive files are designed to be
+ portable across architectures.
+ </para>
+
+ <para>
+ <application>pg_restore</application> can operate in two modes.
+ If a database name is specified, <application>pg_restore</application>
+ connects to that database and restores archive contents directly into
+ the database. Otherwise, a script containing the SQL
+ commands necessary to rebuild the database is created and written
+ to a file or standard output. This script output is equivalent to
+ the plain text output format of <application>pg_dump</application>.
+ Some of the options controlling the output are therefore analogous to
+ <application>pg_dump</application> options.
+ </para>
+
+ <para>
+ Obviously, <application>pg_restore</application> cannot restore information
+ that is not present in the archive file. For instance, if the
+ archive was made using the <quote>dump data as
+ <command>INSERT</command> commands</quote> option,
+ <application>pg_restore</application> will not be able to load the data
+ using <command>COPY</command> statements.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-pgrestore-options">
+ <title>Options</title>
+
+ <para>
+ <application>pg_restore</application> accepts the following command
+ line arguments.
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">filename</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the location of the archive file (or directory, for a
+ directory-format archive) to be restored.
+ If not specified, the standard input is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--data-only</option></term>
+ <listitem>
+ <para>
+ Restore only the data, not the schema (data definitions).
+ Table data, large objects, and sequence values are restored,
+ if present in the archive.
+ </para>
+
+ <para>
+ This option is similar to, but for historical reasons not identical
+ to, specifying <option>--section=data</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--clean</option></term>
+ <listitem>
+ <para>
+ Clean (drop) database objects before recreating them.
+ (Unless <option>--if-exists</option> is used,
+ this might generate some harmless error messages, if any objects
+ were not present in the destination database.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C</option></term>
+ <term><option>--create</option></term>
+ <listitem>
+ <para>
+ Create the database before restoring into it.
+ If <option>--clean</option> is also specified, drop and
+ recreate the target database before connecting to it.
+ </para>
+
+ <para>
+ With <option>--create</option>, <application>pg_restore</application>
+ also restores the database's comment if any, and any configuration
+ variable settings that are specific to this database, that is,
+ any <command>ALTER DATABASE ... SET ...</command>
+ and <command>ALTER ROLE ... IN DATABASE ... SET ...</command>
+ commands that mention this database.
+ Access privileges for the database itself are also restored,
+ unless <option>--no-acl</option> is specified.
+ </para>
+
+ <para>
+ When this option is used, the database named with <option>-d</option>
+ is used only to issue the initial <command>DROP DATABASE</command> and
+ <command>CREATE DATABASE</command> commands. All data is restored into the
+ database name that appears in the archive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Connect to database <replaceable
+ class="parameter">dbname</replaceable> and restore directly
+ into the database. The <replaceable>dbname</replaceable> can
+ be a <link linkend="libpq-connstring">connection string</link>.
+ If so, connection string parameters will override any conflicting
+ command line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--exit-on-error</option></term>
+ <listitem>
+ <para>
+ Exit if an error is encountered while sending SQL commands to
+ the database. The default is to continue and to display a count of
+ errors at the end of the restoration.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f <replaceable>filename</replaceable></option></term>
+ <term><option>--file=<replaceable>filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify output file for generated script, or for the listing
+ when used with <option>-l</option>. Use <literal>-</literal>
+ for <systemitem>stdout</systemitem>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F <replaceable class="parameter">format</replaceable></option></term>
+ <term><option>--format=<replaceable class="parameter">format</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify format of the archive. It is not necessary to specify
+ the format, since <application>pg_restore</application> will
+ determine the format automatically. If specified, it can be
+ one of the following:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>c</literal></term>
+ <term><literal>custom</literal></term>
+ <listitem>
+ <para>
+ The archive is in the custom format of
+ <application>pg_dump</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>d</literal></term>
+ <term><literal>directory</literal></term>
+ <listitem>
+ <para>
+ The archive is a directory archive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>t</literal></term>
+ <term><literal>tar</literal></term>
+ <listitem>
+ <para>
+ The archive is a <command>tar</command> archive.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-I <replaceable class="parameter">index</replaceable></option></term>
+ <term><option>--index=<replaceable class="parameter">index</replaceable></option></term>
+ <listitem>
+ <para>
+ Restore definition of named index only. Multiple indexes
+ may be specified with multiple <option>-I</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j <replaceable class="parameter">number-of-jobs</replaceable></option></term>
+ <term><option>--jobs=<replaceable class="parameter">number-of-jobs</replaceable></option></term>
+ <listitem>
+ <para>
+ Run the most time-consuming steps
+ of <application>pg_restore</application> &mdash; those that load data,
+ create indexes, or create constraints &mdash; concurrently, using up
+ to <replaceable class="parameter">number-of-jobs</replaceable>
+ concurrent sessions. This option can dramatically reduce the time
+ to restore a large database to a server running on a
+ multiprocessor machine. This option is ignored when emitting a script
+ rather than connecting directly to a database server.
+ </para>
+
+ <para>
+ Each job is one process or one thread, depending on the
+ operating system, and uses a separate connection to the
+ server.
+ </para>
+
+ <para>
+ The optimal value for this option depends on the hardware
+ setup of the server, of the client, and of the network.
+ Factors include the number of CPU cores and the disk setup. A
+ good place to start is the number of CPU cores on the server,
+ but values larger than that can also lead to faster restore
+ times in many cases. Of course, values that are too high will
+ lead to decreased performance because of thrashing.
+ </para>
+
+ <para>
+ Only the custom and directory archive formats are supported
+ with this option.
+ The input must be a regular file or directory (not, for example, a
+ pipe or standard input). Also, multiple
+ jobs cannot be used together with the
+ option <option>--single-transaction</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l</option></term>
+ <term><option>--list</option></term>
+ <listitem>
+ <para>
+ List the table of contents of the archive. The output of this operation
+ can be used as input to the <option>-L</option> option. Note that
+ if filtering switches such as <option>-n</option> or <option>-t</option> are
+ used with <option>-l</option>, they will restrict the items listed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-L <replaceable class="parameter">list-file</replaceable></option></term>
+ <term><option>--use-list=<replaceable class="parameter">list-file</replaceable></option></term>
+ <listitem>
+ <para>
+ Restore only those archive elements that are listed in <replaceable
+ class="parameter">list-file</replaceable>, and restore them in the
+ order they appear in the file. Note that
+ if filtering switches such as <option>-n</option> or <option>-t</option> are
+ used with <option>-L</option>, they will further restrict the items restored.
+ </para>
+ <para><replaceable class="parameter">list-file</replaceable> is normally created by
+ editing the output of a previous <option>-l</option> operation.
+ Lines can be moved or removed, and can also
+ be commented out by placing a semicolon (<literal>;</literal>) at the
+ start of the line. See below for examples.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n <replaceable class="parameter">schema</replaceable></option></term>
+ <term><option>--schema=<replaceable class="parameter">schema</replaceable></option></term>
+ <listitem>
+ <para>
+ Restore only objects that are in the named schema. Multiple schemas
+ may be specified with multiple <option>-n</option> switches. This can be
+ combined with the <option>-t</option> option to restore just a
+ specific table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N <replaceable class="parameter">schema</replaceable></option></term>
+ <term><option>--exclude-schema=<replaceable class="parameter">schema</replaceable></option></term>
+ <listitem>
+ <para>
+ Do not restore objects that are in the named schema. Multiple schemas
+ to be excluded may be specified with multiple <option>-N</option> switches.
+ </para>
+
+ <para>
+ When both <option>-n</option> and <option>-N</option> are given for the same
+ schema name, the <option>-N</option> switch wins and the schema is excluded.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option></term>
+ <term><option>--no-owner</option></term>
+ <listitem>
+ <para>
+ Do not output commands to set
+ ownership of objects to match the original database.
+ By default, <application>pg_restore</application> issues
+ <command>ALTER OWNER</command> or
+ <command>SET SESSION AUTHORIZATION</command>
+ statements to set ownership of created schema elements.
+ These statements will fail unless the initial connection to the
+ database is made by a superuser
+ (or the same user that owns all of the objects in the script).
+ With <option>-O</option>, any user name can be used for the
+ initial connection, and this user will own all the created objects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P <replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term>
+ <term><option>--function=<replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term>
+ <listitem>
+ <para>
+ Restore the named function only. Be careful to spell the function
+ name and arguments exactly as they appear in the dump file's table
+ of contents. Multiple functions may be specified with multiple
+ <option>-P</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R</option></term>
+ <term><option>--no-reconnect</option></term>
+ <listitem>
+ <para>
+ This option is obsolete but still accepted for backwards
+ compatibility.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--schema-only</option></term>
+ <listitem>
+ <para>
+ Restore only the schema (data definitions), not data,
+ to the extent that schema entries are present in the archive.
+ </para>
+ <para>
+ This option is the inverse of <option>--data-only</option>.
+ It is similar to, but for historical reasons not identical to,
+ specifying
+ <option>--section=pre-data --section=post-data</option>.
+ </para>
+ <para>
+ (Do not confuse this with the <option>--schema</option> option, which
+ uses the word <quote>schema</quote> in a different meaning.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--superuser=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify the superuser user name to use when disabling triggers.
+ This is relevant only if <option>--disable-triggers</option> is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">table</replaceable></option></term>
+ <term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
+ <listitem>
+ <para>
+ Restore definition and/or data of only the named table.
+ For this purpose, <quote>table</quote> includes views, materialized views,
+ sequences, and foreign tables. Multiple tables
+ can be selected by writing multiple <option>-t</option> switches.
+ This option can be combined with the <option>-n</option> option to
+ specify table(s) in a particular schema.
+ </para>
+
+ <note>
+ <para>
+ When <option>-t</option> is specified, <application>pg_restore</application>
+ makes no attempt to restore any other database objects that the
+ selected table(s) might depend upon. Therefore, there is no
+ guarantee that a specific-table restore into a clean database will
+ succeed.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ This flag does not behave identically to the <option>-t</option>
+ flag of <application>pg_dump</application>. There is not currently
+ any provision for wild-card matching in <application>pg_restore</application>,
+ nor can you include a schema name within its <option>-t</option>.
+ And, while <application>pg_dump</application>'s <option>-t</option>
+ flag will also dump subsidiary objects (such as indexes) of the
+ selected table(s),
+ <application>pg_restore</application>'s <option>-t</option>
+ flag does not include such subsidiary objects.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ In versions prior to <productname>PostgreSQL</productname> 9.6, this flag
+ matched only tables, not any other type of relation.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable class="parameter">trigger</replaceable></option></term>
+ <term><option>--trigger=<replaceable class="parameter">trigger</replaceable></option></term>
+ <listitem>
+ <para>
+ Restore named trigger only. Multiple triggers may be specified with
+ multiple <option>-T</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Specifies verbose mode. This will cause
+ <application>pg_restore</application> to output detailed object
+ comments and start/stop times to the output file, and progress
+ messages to standard error.
+ Repeating the option causes additional debug-level messages
+ to appear on standard error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_restore</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option></term>
+ <term><option>--no-privileges</option></term>
+ <term><option>--no-acl</option></term>
+ <listitem>
+ <para>
+ Prevent restoration of access privileges (grant/revoke commands).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-1</option></term>
+ <term><option>--single-transaction</option></term>
+ <listitem>
+ <para>
+ Execute the restore as a single transaction (that is, wrap the
+ emitted commands in <command>BEGIN</command>/<command>COMMIT</command>). This
+ ensures that either all the commands complete successfully, or no
+ changes are applied. This option implies
+ <option>--exit-on-error</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-triggers</option></term>
+ <listitem>
+ <para>
+ This option is relevant only when performing a data-only restore.
+ It instructs <application>pg_restore</application> to execute commands
+ to temporarily disable triggers on the target tables while
+ the data is restored. Use this if you have referential
+ integrity checks or other triggers on the tables that you
+ do not want to invoke during data restore.
+ </para>
+
+ <para>
+ Presently, the commands emitted for
+ <option>--disable-triggers</option> must be done as superuser. So you
+ should also specify a superuser name with <option>-S</option> or,
+ preferably, run <application>pg_restore</application> as a
+ <productname>PostgreSQL</productname> superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--enable-row-security</option></term>
+ <listitem>
+ <para>
+ This option is relevant only when restoring the contents of a table
+ which has row security. By default, <application>pg_restore</application> will set
+ <xref linkend="guc-row-security"/> to off, to ensure
+ that all data is restored in to the table. If the user does not have
+ sufficient privileges to bypass row security, then an error is thrown.
+ This parameter instructs <application>pg_restore</application> to set
+ <xref linkend="guc-row-security"/> to on instead, allowing the user to attempt to restore
+ the contents of the table with row security enabled. This might still
+ fail if the user does not have the right to insert the rows from the
+ dump into the table.
+ </para>
+
+ <para>
+ Note that this option currently also requires the dump be in <command>INSERT</command>
+ format, as <command>COPY FROM</command> does not support row security.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--if-exists</option></term>
+ <listitem>
+ <para>
+ Use conditional commands (i.e., add an <literal>IF EXISTS</literal>
+ clause) to drop database objects. This option is not valid
+ unless <option>--clean</option> is also specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-comments</option></term>
+ <listitem>
+ <para>
+ Do not output commands to restore comments, even if the archive
+ contains them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-data-for-failed-tables</option></term>
+ <listitem>
+ <para>
+ By default, table data is restored even if the creation command
+ for the table failed (e.g., because it already exists).
+ With this option, data for such a table is skipped.
+ This behavior is useful if the target database already
+ contains the desired table contents. For example,
+ auxiliary tables for <productname>PostgreSQL</productname> extensions
+ such as <productname>PostGIS</productname> might already be loaded in
+ the target database; specifying this option prevents duplicate
+ or obsolete data from being loaded into them.
+ </para>
+
+ <para>
+ This option is effective only when restoring directly into a
+ database, not when producing SQL script output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-publications</option></term>
+ <listitem>
+ <para>
+ Do not output commands to restore publications, even if the archive
+ contains them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-security-labels</option></term>
+ <listitem>
+ <para>
+ Do not output commands to restore security labels,
+ even if the archive contains them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-subscriptions</option></term>
+ <listitem>
+ <para>
+ Do not output commands to restore subscriptions, even if the archive
+ contains them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-table-access-method</option></term>
+ <listitem>
+ <para>
+ Do not output commands to select table access methods.
+ With this option, all objects will be created with whichever
+ access method is the default during restore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-tablespaces</option></term>
+ <listitem>
+ <para>
+ Do not output commands to select tablespaces.
+ With this option, all objects will be created in whichever
+ tablespace is the default during restore.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--section=<replaceable class="parameter">sectionname</replaceable></option></term>
+ <listitem>
+ <para>
+ Only restore the named section. The section name can be
+ <option>pre-data</option>, <option>data</option>, or <option>post-data</option>.
+ This option can be specified more than once to select multiple
+ sections. The default is to restore all sections.
+ </para>
+ <para>
+ The data section contains actual table data as well as large-object
+ definitions.
+ Post-data items consist of definitions of indexes, triggers, rules
+ and constraints other than validated check constraints.
+ Pre-data items consist of all other data definition items.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--strict-names</option></term>
+ <listitem>
+ <para>
+ Require that each schema
+ (<option>-n</option>/<option>--schema</option>) and table
+ (<option>-t</option>/<option>--table</option>) qualifier match at
+ least one schema/table in the backup file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--use-set-session-authorization</option></term>
+ <listitem>
+ <para>
+ Output SQL-standard <command>SET SESSION AUTHORIZATION</command> commands
+ instead of <command>ALTER OWNER</command> commands to determine object
+ ownership. This makes the dump more standards-compatible, but
+ depending on the history of the objects in the dump, might not restore
+ properly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_restore</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ <application>pg_restore</application> also accepts
+ the following command line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket. The default is taken
+ from the <envar>PGHOST</envar> environment variable, if set,
+ else a Unix domain socket connection is attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server is listening for connections.
+ Defaults to the <envar>PGPORT</envar> environment variable, if
+ set, or a compiled-in default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>pg_restore</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>pg_restore</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>pg_restore</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--role=<replaceable class="parameter">rolename</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies a role name to be used to perform the restore.
+ This option causes <application>pg_restore</application> to issue a
+ <command>SET ROLE</command> <replaceable class="parameter">rolename</replaceable>
+ command after connecting to the database. It is useful when the
+ authenticated user (specified by <option>-U</option>) lacks privileges
+ needed by <application>pg_restore</application>, but can switch to a role with
+ the required rights. Some installations have a policy against
+ logging in directly as a superuser, and use of this option allows
+ restores to be performed without violating the policy.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGOPTIONS</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>). However, it does not read
+ <envar>PGDATABASE</envar> when a database name is not supplied.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1 id="app-pgrestore-diagnostics">
+ <title>Diagnostics</title>
+
+ <para>
+ When a direct database connection is specified using the
+ <option>-d</option> option, <application>pg_restore</application>
+ internally executes <acronym>SQL</acronym> statements. If you have
+ problems running <application>pg_restore</application>, make sure
+ you are able to select information from the database using, for
+ example, <xref linkend="app-psql"/>. Also, any default connection
+ settings and environment variables used by the
+ <application>libpq</application> front-end library will apply.
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="app-pgrestore-notes">
+ <title>Notes</title>
+
+ <para>
+ If your installation has any local additions to the
+ <literal>template1</literal> database, be careful to load the output of
+ <application>pg_restore</application> into a truly empty database;
+ otherwise you are likely to get errors due to duplicate definitions
+ of the added objects. To make an empty database without any local
+ additions, copy from <literal>template0</literal> not <literal>template1</literal>, for example:
+<programlisting>
+CREATE DATABASE foo WITH TEMPLATE template0;
+</programlisting>
+ </para>
+
+ <para>
+ The limitations of <application>pg_restore</application> are detailed below.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ When restoring data to a pre-existing table and the option
+ <option>--disable-triggers</option> is used,
+ <application>pg_restore</application> emits commands
+ to disable triggers on user tables before inserting the data, then emits commands to
+ re-enable them after the data has been inserted. If the restore is stopped in the
+ middle, the system catalogs might be left in the wrong state.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><application>pg_restore</application> cannot restore large objects
+ selectively; for instance, only those for a specific table. If
+ an archive contains large objects, then all large objects will be
+ restored, or none of them if they are excluded via <option>-L</option>,
+ <option>-t</option>, or other options.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ See also the <xref linkend="app-pgdump"/> documentation for details on
+ limitations of <application>pg_dump</application>.
+ </para>
+
+ <para>
+ Once restored, it is wise to run <command>ANALYZE</command> on each
+ restored table so the optimizer has useful statistics; see
+ <xref linkend="vacuum-for-statistics"/> and
+ <xref linkend="autovacuum"/> for more information.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1 id="app-pgrestore-examples">
+ <title>Examples</title>
+
+ <para>
+ Assume we have dumped a database called <literal>mydb</literal> into a
+ custom-format dump file:
+
+<screen>
+<prompt>$</prompt> <userinput>pg_dump -Fc mydb &gt; db.dump</userinput>
+</screen>
+ </para>
+
+ <para>
+ To drop the database and recreate it from the dump:
+
+<screen>
+<prompt>$</prompt> <userinput>dropdb mydb</userinput>
+<prompt>$</prompt> <userinput>pg_restore -C -d postgres db.dump</userinput>
+</screen>
+
+ The database named in the <option>-d</option> switch can be any database existing
+ in the cluster; <application>pg_restore</application> only uses it to issue the
+ <command>CREATE DATABASE</command> command for <literal>mydb</literal>. With
+ <option>-C</option>, data is always restored into the database name that appears
+ in the dump file.
+ </para>
+
+ <para>
+ To restore the dump into a new database called <literal>newdb</literal>:
+
+<screen>
+<prompt>$</prompt> <userinput>createdb -T template0 newdb</userinput>
+<prompt>$</prompt> <userinput>pg_restore -d newdb db.dump</userinput>
+</screen>
+
+ Notice we don't use <option>-C</option>, and instead connect directly to the
+ database to be restored into. Also note that we clone the new database
+ from <literal>template0</literal> not <literal>template1</literal>, to ensure it is
+ initially empty.
+ </para>
+
+ <para>
+ To reorder database items, it is first necessary to dump the table of
+ contents of the archive:
+<screen>
+<prompt>$</prompt> <userinput>pg_restore -l db.dump &gt; db.list</userinput>
+</screen>
+ The listing file consists of a header and one line for each item, e.g.:
+<programlisting>
+;
+; Archive created at Mon Sep 14 13:55:39 2009
+; dbname: DBDEMOS
+; TOC Entries: 81
+; Compression: 9
+; Dump Version: 1.10-0
+; Format: CUSTOM
+; Integer: 4 bytes
+; Offset: 8 bytes
+; Dumped from database version: 8.3.5
+; Dumped by pg_dump version: 8.3.8
+;
+;
+; Selected TOC Entries:
+;
+3; 2615 2200 SCHEMA - public pasha
+1861; 0 0 COMMENT - SCHEMA public pasha
+1862; 0 0 ACL - public pasha
+317; 1247 17715 TYPE public composite pasha
+319; 1247 25899 DOMAIN public domain0 pasha
+</programlisting>
+ Semicolons start a comment, and the numbers at the start of lines refer to the
+ internal archive ID assigned to each item.
+ </para>
+
+ <para>
+ Lines in the file can be commented out, deleted, and reordered. For example:
+<programlisting>
+10; 145433 TABLE map_resolutions postgres
+;2; 145344 TABLE species postgres
+;4; 145359 TABLE nt_header postgres
+6; 145402 TABLE species_records postgres
+;8; 145416 TABLE ss_old postgres
+</programlisting>
+ could be used as input to <application>pg_restore</application> and would only restore
+ items 10 and 6, in that order:
+<screen>
+<prompt>$</prompt> <userinput>pg_restore -L db.list db.dump</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pgdump"/></member>
+ <member><xref linkend="app-pg-dumpall"/></member>
+ <member><xref linkend="app-psql"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml
new file mode 100644
index 0000000..69d6924
--- /dev/null
+++ b/doc/src/sgml/ref/pg_rewind.sgml
@@ -0,0 +1,418 @@
+<!--
+doc/src/sgml/ref/pg_rewind.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgrewind">
+ <indexterm zone="app-pgrewind">
+ <primary>pg_rewind</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_rewind</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_rewind</refname>
+ <refpurpose>synchronize a <productname>PostgreSQL</productname> data directory with another data directory that was forked from it</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_rewind</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <group choice="plain">
+ <group choice="req">
+ <arg choice="plain"><option>-D</option></arg>
+ <arg choice="plain"><option>--target-pgdata</option></arg>
+ </group>
+ <replaceable> directory</replaceable>
+ <group choice="req">
+ <arg choice="plain"><option>--source-pgdata=<replaceable>directory</replaceable></option></arg>
+ <arg choice="plain"><option>--source-server=<replaceable>connstr</replaceable></option></arg>
+ </group>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>pg_rewind</application> is a tool for synchronizing a PostgreSQL cluster
+ with another copy of the same cluster, after the clusters' timelines have
+ diverged. A typical scenario is to bring an old primary server back online
+ after failover as a standby that follows the new primary.
+ </para>
+
+ <para>
+ After a successful rewind, the state of the target data directory is
+ analogous to a base backup of the source data directory. Unlike taking
+ a new base backup or using a tool like <application>rsync</application>,
+ <application>pg_rewind</application> does not require comparing or copying
+ unchanged relation blocks in the cluster. Only changed blocks from existing
+ relation files are copied; all other files, including new relation files,
+ configuration files, and WAL segments, are copied in full. As such the
+ rewind operation is significantly faster than other approaches when the
+ database is large and only a small fraction of blocks differ between the
+ clusters.
+ </para>
+
+ <para>
+ <application>pg_rewind</application> examines the timeline histories of the source
+ and target clusters to determine the point where they diverged, and
+ expects to find WAL in the target cluster's <filename>pg_wal</filename> directory
+ reaching all the way back to the point of divergence. The point of divergence
+ can be found either on the target timeline, the source timeline, or their common
+ ancestor. In the typical failover scenario where the target cluster was
+ shut down soon after the divergence, this is not a problem, but if the
+ target cluster ran for a long time after the divergence, its old WAL
+ files might no longer be present. In this case, you can manually copy them
+ from the WAL archive to the <filename>pg_wal</filename> directory, or run
+ <application>pg_rewind</application> with the <literal>-c</literal> option to
+ automatically retrieve them from the WAL archive. The use of
+ <application>pg_rewind</application> is not limited to failover, e.g., a standby
+ server can be promoted, run some write transactions, and then rewound
+ to become a standby again.
+ </para>
+
+ <para>
+ After running <application>pg_rewind</application>, WAL replay needs to
+ complete for the data directory to be in a consistent state. When the
+ target server is started again it will enter archive recovery and replay
+ all WAL generated in the source server from the last checkpoint before
+ the point of divergence. If some of the WAL was no longer available in the
+ source server when <application>pg_rewind</application> was run, and
+ therefore could not be copied by the <application>pg_rewind</application>
+ session, it must be made available when the target server is started.
+ This can be done by creating a <filename>recovery.signal</filename> file
+ in the target data directory and by configuring a suitable
+ <xref linkend="guc-restore-command"/> in
+ <filename>postgresql.conf</filename>.
+ </para>
+
+ <para>
+ <application>pg_rewind</application> requires that the target server either has
+ the <xref linkend="guc-wal-log-hints"/> option enabled
+ in <filename>postgresql.conf</filename> or data checksums enabled when
+ the cluster was initialized with <application>initdb</application>. Neither of these
+ are currently on by default. <xref linkend="guc-full-page-writes"/>
+ must also be set to <literal>on</literal>, but is enabled by default.
+ </para>
+
+ <warning>
+ <para>
+ If <application>pg_rewind</application> fails while processing, then
+ the data folder of the target is likely not in a state that can be
+ recovered. In such a case, taking a new fresh backup is recommended.
+ </para>
+
+ <para>
+ As <application>pg_rewind</application> copies configuration files
+ entirely from the source, it may be required to correct the configuration
+ used for recovery before restarting the target server, especially if
+ the target is reintroduced as a standby of the source. If you restart
+ the server after the rewind operation has finished but without configuring
+ recovery, the target may again diverge from the primary.
+ </para>
+
+ <para>
+ <application>pg_rewind</application> will fail immediately if it finds
+ files it cannot write directly to. This can happen for example when
+ the source and the target server use the same file mapping for read-only
+ SSL keys and certificates. If such files are present on the target server
+ it is recommended to remove them before running
+ <application>pg_rewind</application>. After doing the rewind, some of
+ those files may have been copied from the source, in which case it may
+ be necessary to remove the data copied and restore back the set of links
+ used before the rewind.
+ </para>
+ </warning>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>pg_rewind</application> accepts the following command-line
+ arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">directory</replaceable></option></term>
+ <term><option>--target-pgdata=<replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ This option specifies the target data directory that is synchronized
+ with the source. The target server must be shut down cleanly before
+ running <application>pg_rewind</application>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--source-pgdata=<replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the file system path to the data directory of the source
+ server to synchronize the target with. This option requires the
+ source server to be cleanly shut down.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--source-server=<replaceable class="parameter">connstr</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies a libpq connection string to connect to the source
+ <productname>PostgreSQL</productname> server to synchronize the target
+ with. The connection must be a normal (non-replication) connection
+ with a role having sufficient permissions to execute the functions
+ used by <application>pg_rewind</application> on the source server
+ (see Notes section for details) or a superuser role. This option
+ requires the source server to be running and accepting connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R</option></term>
+ <term><option>--write-recovery-conf</option></term>
+ <listitem>
+ <para>
+ Create <filename>standby.signal</filename> and append connection
+ settings to <filename>postgresql.auto.conf</filename> in the output
+ directory. <literal>--source-server</literal> is mandatory with
+ this option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--dry-run</option></term>
+ <listitem>
+ <para>
+ Do everything except actually modifying the target directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>pg_rewind</command> will wait for all files
+ to be written safely to disk. This option causes
+ <command>pg_rewind</command> to return without waiting, which is
+ faster, but means that a subsequent operating system crash can leave
+ the data directory corrupt. Generally, this option is useful for
+ testing but should not be used on a production
+ installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+ <term><option>--progress</option></term>
+ <listitem>
+ <para>
+ Enables progress reporting. Turning this on will deliver an approximate
+ progress report while copying data from the source cluster.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--restore-target-wal</option></term>
+ <listitem>
+ <para>
+ Use <varname>restore_command</varname> defined in the target cluster
+ configuration to retrieve WAL files from the WAL archive if these
+ files are no longer available in the <filename>pg_wal</filename>
+ directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--config-file=<replaceable class="parameter">filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Use the specified main server configuration file for the target
+ cluster. This affects <application>pg_rewind</application> when
+ it uses internally the <application>postgres</application> command
+ for the rewind operation on this cluster (when retrieving
+ <varname>restore_command</varname> with the option
+ <option>-c/--restore-target-wal</option> and when forcing a
+ completion of crash recovery).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--debug</option></term>
+ <listitem>
+ <para>
+ Print verbose debugging output that is mostly useful for developers
+ debugging <application>pg_rewind</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-ensure-shutdown</option></term>
+ <listitem>
+ <para>
+ <application>pg_rewind</application> requires that the target server
+ is cleanly shut down before rewinding. By default, if the target server
+ is not shut down cleanly, <application>pg_rewind</application> starts
+ the target server in single-user mode to complete crash recovery first,
+ and stops it.
+ By passing this option, <application>pg_rewind</application> skips
+ this and errors out immediately if the server is not cleanly shut
+ down. Users are expected to handle the situation themselves in that
+ case.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem><para>Display version information, then exit.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem><para>Show help, then exit.</para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ When <option>--source-server</option> option is used,
+ <application>pg_rewind</application> also uses the environment variables
+ supported by <application>libpq</application> (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When executing <application>pg_rewind</application> using an online
+ cluster as source, a role having sufficient permissions to execute the
+ functions used by <application>pg_rewind</application> on the source
+ cluster can be used instead of a superuser. Here is how to create such
+ a role, named <literal>rewind_user</literal> here:
+<programlisting>
+CREATE USER rewind_user LOGIN;
+GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
+GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;
+</programlisting>
+ </para>
+
+ <para>
+ When executing <application>pg_rewind</application> using an online
+ cluster as source which has been recently promoted, it is necessary
+ to execute a <command>CHECKPOINT</command> after promotion such that its
+ control file reflects up-to-date timeline information, which is used by
+ <application>pg_rewind</application> to check if the target cluster
+ can be rewound using the designated source cluster.
+ </para>
+
+ <refsect2>
+ <title>How It Works</title>
+
+ <para>
+ The basic idea is to copy all file system-level changes from the source
+ cluster to the target cluster:
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ Scan the WAL log of the target cluster, starting from the last
+ checkpoint before the point where the source cluster's timeline
+ history forked off from the target cluster. For each WAL record,
+ record each data block that was touched. This yields a list of all
+ the data blocks that were changed in the target cluster, after the
+ source cluster forked off. If some of the WAL files are no longer
+ available, try re-running <application>pg_rewind</application> with
+ the <option>-c</option> option to search for the missing files in
+ the WAL archive.
+ </para>
+ </step>
+ <step>
+ <para>
+ Copy all those changed blocks from the source cluster to
+ the target cluster, either using direct file system access
+ (<option>--source-pgdata</option>) or SQL (<option>--source-server</option>).
+ Relation files are now in a state equivalent to the moment of the last
+ completed checkpoint prior to the point at which the WAL timelines of the
+ source and target diverged plus the current state on the source of any
+ blocks changed on the target after that divergence.
+ </para>
+ </step>
+ <step>
+ <para>
+ Copy all other files, including new relation files, WAL segments,
+ <filename>pg_xact</filename>, and configuration files from the source
+ cluster to the target cluster. Similarly to base backups, the contents
+ of the directories <filename>pg_dynshmem/</filename>,
+ <filename>pg_notify/</filename>, <filename>pg_replslot/</filename>,
+ <filename>pg_serial/</filename>, <filename>pg_snapshots/</filename>,
+ <filename>pg_stat_tmp/</filename>, and <filename>pg_subtrans/</filename>
+ are omitted from the data copied from the source cluster. The files
+ <filename>backup_label</filename>,
+ <filename>tablespace_map</filename>,
+ <filename>pg_internal.init</filename>,
+ <filename>postmaster.opts</filename>, and
+ <filename>postmaster.pid</filename>, as well as any file or directory
+ beginning with <filename>pgsql_tmp</filename>, are omitted.
+ </para>
+ </step>
+ <step>
+ <para>
+ Create a <filename>backup_label</filename> file to begin WAL replay at
+ the checkpoint created at failover and configure the
+ <filename>pg_control</filename> file with a minimum consistency LSN
+ defined as the result of <literal>pg_current_wal_insert_lsn()</literal>
+ when rewinding from a live source or the last checkpoint LSN when
+ rewinding from a stopped source.
+ </para>
+ </step>
+ <step>
+ <para>
+ When starting the target, <productname>PostgreSQL</productname> replays
+ all the required WAL, resulting in a data directory in a consistent
+ state.
+ </para>
+ </step>
+ </procedure>
+ </refsect2>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_verifybackup.sgml b/doc/src/sgml/ref/pg_verifybackup.sgml
new file mode 100644
index 0000000..5f83c98
--- /dev/null
+++ b/doc/src/sgml/ref/pg_verifybackup.sgml
@@ -0,0 +1,289 @@
+<!--
+doc/src/sgml/ref/pg_verifybackup.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-pgverifybackup">
+ <indexterm zone="app-pgverifybackup">
+ <primary>pg_verifybackup</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_verifybackup</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_verifybackup</refname>
+ <refpurpose>verify the integrity of a base backup of a
+ <productname>PostgreSQL</productname> cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_verifybackup</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ <application>pg_verifybackup</application> is used to check the
+ integrity of a database cluster backup taken using
+ <command>pg_basebackup</command> against a
+ <literal>backup_manifest</literal> generated by the server at the time
+ of the backup. The backup must be stored in the "plain"
+ format; a "tar" format backup can be checked after extracting it.
+ </para>
+
+ <para>
+ It is important to note that the validation which is performed by
+ <application>pg_verifybackup</application> does not and cannot include
+ every check which will be performed by a running server when attempting
+ to make use of the backup. Even if you use this tool, you should still
+ perform test restores and verify that the resulting databases work as
+ expected and that they appear to contain the correct data. However,
+ <application>pg_verifybackup</application> can detect many problems
+ that commonly occur due to storage problems or user error.
+ </para>
+
+ <para>
+ Backup verification proceeds in four stages. First,
+ <literal>pg_verifybackup</literal> reads the
+ <literal>backup_manifest</literal> file. If that file
+ does not exist, cannot be read, is malformed, or fails verification
+ against its own internal checksum, <literal>pg_verifybackup</literal>
+ will terminate with a fatal error.
+ </para>
+
+ <para>
+ Second, <literal>pg_verifybackup</literal> will attempt to verify that
+ the data files currently stored on disk are exactly the same as the data
+ files which the server intended to send, with some exceptions that are
+ described below. Extra and missing files will be detected, with a few
+ exceptions. This step will ignore the presence or absence of, or any
+ modifications to, <literal>postgresql.auto.conf</literal>,
+ <literal>standby.signal</literal>, and <literal>recovery.signal</literal>,
+ because it is expected that these files may have been created or modified
+ as part of the process of taking the backup. It also won't complain about
+ a <literal>backup_manifest</literal> file in the target directory or
+ about anything inside <literal>pg_wal</literal>, even though these
+ files won't be listed in the backup manifest. Only files are checked;
+ the presence or absence of directories is not verified, except
+ indirectly: if a directory is missing, any files it should have contained
+ will necessarily also be missing.
+ </para>
+
+ <para>
+ Next, <literal>pg_verifybackup</literal> will checksum all the files,
+ compare the checksums against the values in the manifest, and emit errors
+ for any files for which the computed checksum does not match the
+ checksum stored in the manifest. This step is not performed for any files
+ which produced errors in the previous step, since they are already known
+ to have problems. Files which were ignored in the previous step are also
+ ignored in this step.
+ </para>
+
+ <para>
+ Finally, <literal>pg_verifybackup</literal> will use the manifest to
+ verify that the write-ahead log records which will be needed to recover
+ the backup are present and that they can be read and parsed. The
+ <literal>backup_manifest</literal> contains information about which
+ write-ahead log records will be needed, and
+ <literal>pg_verifybackup</literal> will use that information to
+ invoke <literal>pg_waldump</literal> to parse those write-ahead log
+ records. The <literal>--quiet</literal> flag will be used, so that
+ <literal>pg_waldump</literal> will only report errors, without producing
+ any other output. While this level of verification is sufficient to
+ detect obvious problems such as a missing file or one whose internal
+ checksums do not match, they aren't extensive enough to detect every
+ possible problem that might occur when attempting to recover. For
+ instance, a server bug that produces write-ahead log records that have
+ the correct checksums but specify nonsensical actions can't be detected
+ by this method.
+ </para>
+
+ <para>
+ Note that if extra WAL files which are not required to recover the backup
+ are present, they will not be checked by this tool, although
+ a separate invocation of <literal>pg_waldump</literal> could be used for
+ that purpose. Also note that WAL verification is version-specific: you
+ must use the version of <literal>pg_verifybackup</literal>, and thus of
+ <literal>pg_waldump</literal>, which pertains to the backup being checked.
+ In contrast, the data file integrity checks should work with any version
+ of the server that generates a <literal>backup_manifest</literal> file.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>pg_verifybackup</application> accepts the following
+ command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--exit-on-error</option></term>
+ <listitem>
+ <para>
+ Exit as soon as a problem with the backup is detected. If this option
+ is not specified, <literal>pg_verifybackup</literal> will continue
+ checking the backup even after a problem has been detected, and will
+ report all problems detected as errors.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i <replaceable class="parameter">path</replaceable></option></term>
+ <term><option>--ignore=<replaceable class="parameter">path</replaceable></option></term>
+ <listitem>
+ <para>
+ Ignore the specified file or directory, which should be expressed
+ as a relative path name, when comparing the list of data files
+ actually present in the backup to those listed in the
+ <literal>backup_manifest</literal> file. If a directory is
+ specified, this option affects the entire subtree rooted at that
+ location. Complaints about extra files, missing files, file size
+ differences, or checksum mismatches will be suppressed if the
+ relative path name matches the specified path name. This option
+ can be specified multiple times.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-m <replaceable class="parameter">path</replaceable></option></term>
+ <term><option>--manifest-path=<replaceable class="parameter">path</replaceable></option></term>
+ <listitem>
+ <para>
+ Use the manifest file at the specified path, rather than one located
+ in the root of the backup directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-parse-wal</option></term>
+ <listitem>
+ <para>
+ Don't attempt to parse write-ahead log data that will be needed
+ to recover from this backup.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Don't print anything when a backup is successfully verified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--skip-checksums</option></term>
+ <listitem>
+ <para>
+ Do not verify data file checksums. The presence or absence of
+ files and the sizes of those files will still be checked. This is
+ much faster, because the files themselves do not need to be read.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w <replaceable class="parameter">path</replaceable></option></term>
+ <term><option>--wal-directory=<replaceable class="parameter">path</replaceable></option></term>
+ <listitem>
+ <para>
+ Try to parse WAL files stored in the specified directory, rather than
+ in <literal>pg_wal</literal>. This may be useful if the backup is
+ stored in a separate location from the WAL archive.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Other options are also available:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_verifybackup</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_verifybackup</application> command
+ line arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To create a base backup of the server at <literal>mydbserver</literal> and
+ verify the integrity of the backup:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -h mydbserver -D /usr/local/pgsql/data</userinput>
+<prompt>$</prompt> <userinput>pg_verifybackup /usr/local/pgsql/data</userinput>
+</screen>
+ </para>
+
+ <para>
+ To create a base backup of the server at <literal>mydbserver</literal>, move
+ the manifest somewhere outside the backup directory, and verify the
+ backup:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -h mydbserver -D /usr/local/pgsql/backup1234</userinput>
+<prompt>$</prompt> <userinput>mv /usr/local/pgsql/backup1234/backup_manifest /my/secure/location/backup_manifest.1234</userinput>
+<prompt>$</prompt> <userinput>pg_verifybackup -m /my/secure/location/backup_manifest.1234 /usr/local/pgsql/backup1234</userinput>
+</screen>
+ </para>
+
+ <para>
+ To verify a backup while ignoring a file that was added manually to the
+ backup directory, and also skipping checksum verification:
+<screen>
+<prompt>$</prompt> <userinput>pg_basebackup -h mydbserver -D /usr/local/pgsql/data</userinput>
+<prompt>$</prompt> <userinput>edit /usr/local/pgsql/data/note.to.self</userinput>
+<prompt>$</prompt> <userinput>pg_verifybackup --ignore=note.to.self --skip-checksums /usr/local/pgsql/data</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-pgbasebackup"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pg_waldump.sgml b/doc/src/sgml/ref/pg_waldump.sgml
new file mode 100644
index 0000000..c887ac1
--- /dev/null
+++ b/doc/src/sgml/ref/pg_waldump.sgml
@@ -0,0 +1,340 @@
+<!--
+doc/src/sgml/ref/pg_waldump.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="pgwaldump">
+ <indexterm zone="pgwaldump">
+ <primary>pg_waldump</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_waldump</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_waldump</refname>
+ <refpurpose>display a human-readable rendering of the write-ahead log of a <productname>PostgreSQL</productname> database cluster</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_waldump</command>
+ <arg rep="repeat" choice="opt"><option>option</option></arg>
+ <arg choice="opt"><option>startseg</option><arg choice="opt"><option>endseg</option></arg></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="r1-app-pgwaldump-1">
+ <title>Description</title>
+ <para>
+ <command>pg_waldump</command> displays the write-ahead log (WAL) and is mainly
+ useful for debugging or educational purposes.
+ </para>
+
+ <para>
+ This utility can only be run by the user who installed the server, because
+ it requires read-only access to the data directory.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ The following command-line options control the location and format of the
+ output:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">startseg</replaceable></term>
+ <listitem>
+ <para>
+ Start reading at the specified log segment file. This implicitly determines
+ the path in which files will be searched for, and the timeline to use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">endseg</replaceable></term>
+ <listitem>
+ <para>
+ Stop after reading the specified log segment file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-b</option></term>
+ <term><option>--bkp-details</option></term>
+ <listitem>
+ <para>
+ Output detailed information about backup blocks.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-B <replaceable>block</replaceable></option></term>
+ <term><option>--block=<replaceable>block</replaceable></option></term>
+ <listitem>
+ <para>
+ Only display records that modify the given block. The relation must
+ also be provided with <option>--relation</option> or
+ <option>-R</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e <replaceable>end</replaceable></option></term>
+ <term><option>--end=<replaceable>end</replaceable></option></term>
+ <listitem>
+ <para>
+ Stop reading at the specified WAL location, instead of reading to the
+ end of the log stream.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+ <term><option>--follow</option></term>
+ <listitem>
+ <para>
+ After reaching the end of valid WAL, keep polling once per second for
+ new WAL to appear.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F <replaceable>fork</replaceable></option></term>
+ <term><option>--fork=<replaceable>fork</replaceable></option></term>
+ <listitem>
+ <para>
+ If provided, only display records that modify blocks in the given fork.
+ The valid values are <literal>main</literal> for the main fork,
+ <literal>fsm</literal> for the free space map,
+ <literal>vm</literal> for the visibility map,
+ and <literal>init</literal> for the init fork.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n <replaceable>limit</replaceable></option></term>
+ <term><option>--limit=<replaceable>limit</replaceable></option></term>
+ <listitem>
+ <para>
+ Display the specified number of records, then stop.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable>path</replaceable></option></term>
+ <term><option>--path=<replaceable>path</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies a directory to search for log segment files or a
+ directory with a <literal>pg_wal</literal> subdirectory that
+ contains such files. The default is to search in the current
+ directory, the <literal>pg_wal</literal> subdirectory of the
+ current directory, and the <literal>pg_wal</literal> subdirectory
+ of <envar>PGDATA</envar>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Do not print any output, except for errors. This option can be useful
+ when you want to know whether a range of WAL records can be
+ successfully parsed but don't care about the record contents.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r <replaceable>rmgr</replaceable></option></term>
+ <term><option>--rmgr=<replaceable>rmgr</replaceable></option></term>
+ <listitem>
+ <para>
+ Only display records generated by the specified resource manager. You can
+ specify the option multiple times to select multiple resource managers.
+ If <literal>list</literal> is passed as name, print a list of valid resource manager
+ names, and exit.
+ </para>
+ <para>
+ Extensions may define custom resource managers, but pg_waldump does
+ not load the extension module and therefore does not recognize custom
+ resource managers by name. Instead, you can specify the custom
+ resource managers as <literal>custom###</literal> where
+ "<literal>###</literal>" is the three-digit resource manager ID. Names
+ of this form will always be considered valid.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R <replaceable>tblspc</replaceable>/<replaceable>db</replaceable>/<replaceable>rel</replaceable></option></term>
+ <term><option>--relation=<replaceable>tblspc</replaceable>/<replaceable>db</replaceable>/<replaceable>rel</replaceable></option></term>
+ <listitem>
+ <para>
+ Only display records that modify blocks in the given relation. The
+ relation is specified with tablespace OID, database OID, and relfilenode
+ separated by slashes, for example <literal>1234/12345/12345</literal>.
+ This is the same format used for relations in the program's output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s <replaceable>start</replaceable></option></term>
+ <term><option>--start=<replaceable>start</replaceable></option></term>
+ <listitem>
+ <para>
+ WAL location at which to start reading. The default is to start reading
+ the first valid log record found in the earliest file found.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable>timeline</replaceable></option></term>
+ <term><option>--timeline=<replaceable>timeline</replaceable></option></term>
+ <listitem>
+ <para>
+ Timeline from which to read log records. The default is to use the
+ value in <replaceable>startseg</replaceable>, if that is specified; otherwise, the
+ default is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_waldump</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--fullpage</option></term>
+ <listitem>
+ <para>
+ Only display records that include full page images.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x <replaceable>xid</replaceable></option></term>
+ <term><option>--xid=<replaceable>xid</replaceable></option></term>
+ <listitem>
+ <para>
+ Only display records marked with the given transaction ID.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-z</option></term>
+ <term><option>--stats[=record]</option></term>
+ <listitem>
+ <para>
+ Display summary statistics (number and size of records and
+ full-page images) instead of individual records. Optionally
+ generate statistics per-record instead of per-rmgr.
+ </para>
+
+ <para>
+ If <application>pg_waldump</application> is terminated by signal
+ <systemitem>SIGINT</systemitem>
+ (<keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>),
+ the summary of the statistics computed is displayed up to the
+ termination point. This operation is not supported on
+ <productname>Windows</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_waldump</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATA</envar></term>
+ <listitem>
+ <para>
+ Data directory; see also the <option>-p</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+ <para>
+ Can give wrong results when the server is running.
+ </para>
+
+ <para>
+ Only the specified timeline is displayed (or the default, if none is
+ specified). Records in other timelines are ignored.
+ </para>
+
+ <para>
+ <application>pg_waldump</application> cannot read WAL files with suffix
+ <literal>.partial</literal>. If those files need to be read, <literal>.partial</literal>
+ suffix needs to be removed from the file name.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="wal-internals"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pgarchivecleanup.sgml b/doc/src/sgml/ref/pgarchivecleanup.sgml
new file mode 100644
index 0000000..635e7c7
--- /dev/null
+++ b/doc/src/sgml/ref/pgarchivecleanup.sgml
@@ -0,0 +1,207 @@
+<!--
+doc/src/sgml/ref/pgarchivecleanup.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="pgarchivecleanup">
+ <indexterm zone="pgarchivecleanup">
+ <primary>pg_archivecleanup</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_archivecleanup</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_archivecleanup</refname>
+ <refpurpose>clean up <productname>PostgreSQL</productname> WAL archive files</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_archivecleanup</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="plain"><replaceable>archivelocation</replaceable></arg>
+ <arg choice="plain"><replaceable>oldestkeptwalfile</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>pg_archivecleanup</application> is designed to be used as an
+ <literal>archive_cleanup_command</literal> to clean up WAL file archives when
+ running as a standby server (see <xref linkend="warm-standby"/>).
+ <application>pg_archivecleanup</application> can also be used as a standalone program to
+ clean WAL file archives.
+ </para>
+
+ <para>
+ To configure a standby
+ server to use <application>pg_archivecleanup</application>, put this into its
+ <filename>postgresql.conf</filename> configuration file:
+<programlisting>
+archive_cleanup_command = 'pg_archivecleanup <replaceable>archivelocation</replaceable> %r'
+</programlisting>
+ where <replaceable>archivelocation</replaceable> is the directory from which WAL segment
+ files should be removed.
+ </para>
+ <para>
+ When used within <xref linkend="guc-archive-cleanup-command"/>, all WAL files
+ logically preceding the value of the <literal>%r</literal> argument will be removed
+ from <replaceable>archivelocation</replaceable>. This minimizes the number of files
+ that need to be retained, while preserving crash-restart capability. Use of
+ this parameter is appropriate if the <replaceable>archivelocation</replaceable> is a
+ transient staging area for this particular standby server, but
+ <emphasis>not</emphasis> when the <replaceable>archivelocation</replaceable> is intended as a
+ long-term WAL archive area, or when multiple standby servers are recovering
+ from the same archive location.
+ </para>
+ <para>
+ When used as a standalone program all WAL files logically preceding the
+ <replaceable>oldestkeptwalfile</replaceable> will be removed from <replaceable>archivelocation</replaceable>.
+ In this mode, if you specify a <filename>.partial</filename> or <filename>.backup</filename>
+ file name, then only the file prefix will be used as the
+ <replaceable>oldestkeptwalfile</replaceable>. This treatment of <filename>.backup</filename>
+ file name allows you to remove
+ all WAL files archived prior to a specific base backup without error.
+ For example, the following example will remove all files older than
+ WAL file name <filename>000000010000003700000010</filename>:
+<programlisting>
+pg_archivecleanup -d archive 000000010000003700000010.00000020.backup
+
+pg_archivecleanup: keep WAL file "archive/000000010000003700000010" and later
+pg_archivecleanup: removing file "archive/00000001000000370000000F"
+pg_archivecleanup: removing file "archive/00000001000000370000000E"
+</programlisting>
+ </para>
+ <para>
+ <application>pg_archivecleanup</application> assumes that
+ <replaceable>archivelocation</replaceable> is a directory readable and writable by the
+ server-owning user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>pg_archivecleanup</application> accepts the following command-line arguments:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-d</option></term>
+ <listitem>
+ <para>
+ Print lots of debug logging output on <filename>stderr</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <listitem>
+ <para>
+ Print the names of the files that would have been removed on <filename>stdout</filename> (performs a dry run).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_archivecleanup</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option> <replaceable>extension</replaceable></term>
+ <listitem>
+ <para>
+ Provide an extension
+ that will be stripped from all file names before deciding if they
+ should be deleted. This is typically useful for cleaning up archives
+ that have been compressed during storage, and therefore have had an
+ extension added by the compression program. For example: <literal>-x
+ .gz</literal>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_archivecleanup</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>pg_archivecleanup</application> is designed to work with
+ <productname>PostgreSQL</productname> 8.0 and later when used as a standalone utility,
+ or with <productname>PostgreSQL</productname> 9.0 and later when used as an
+ archive cleanup command.
+ </para>
+
+ <para>
+ <application>pg_archivecleanup</application> is written in C and has an
+ easy-to-modify source code, with specifically designated sections to modify
+ for your own needs
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>On Linux or Unix systems, you might use:
+<programlisting>
+archive_cleanup_command = 'pg_archivecleanup -d /mnt/standby/archive %r 2>>cleanup.log'
+</programlisting>
+ where the archive directory is physically located on the standby server,
+ so that the <varname>archive_command</varname> is accessing it across NFS,
+ but the files are local to the standby.
+ This will:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ produce debugging output in <filename>cleanup.log</filename>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ remove no-longer-needed files from the archive directory
+ </para>
+ </listitem>
+ </itemizedlist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
new file mode 100644
index 0000000..7d66679
--- /dev/null
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -0,0 +1,2950 @@
+<!--
+doc/src/sgml/ref/pgbench.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="pgbench">
+ <indexterm zone="pgbench">
+ <primary>pgbench</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pgbench</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pgbench</refname>
+ <refpurpose>run a benchmark test on <productname>PostgreSQL</productname></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pgbench</command>
+ <arg choice="plain"><option>-i</option></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ <cmdsynopsis>
+ <command>pgbench</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ <application>pgbench</application> is a simple program for running benchmark
+ tests on <productname>PostgreSQL</productname>. It runs the same sequence of SQL
+ commands over and over, possibly in multiple concurrent database sessions,
+ and then calculates the average transaction rate (transactions per second).
+ By default, <application>pgbench</application> tests a scenario that is
+ loosely based on TPC-B, involving five <command>SELECT</command>,
+ <command>UPDATE</command>, and <command>INSERT</command> commands per transaction.
+ However, it is easy to test other cases by writing your own transaction
+ script files.
+ </para>
+
+ <para>
+ Typical output from <application>pgbench</application> looks like:
+
+<screen>
+transaction type: &lt;builtin: TPC-B (sort of)&gt;
+scaling factor: 10
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+number of failed transactions: 0 (0.000%)
+latency average = 11.013 ms
+latency stddev = 7.351 ms
+initial connection time = 45.758 ms
+tps = 896.967014 (without initial connection time)
+</screen>
+
+ The first seven lines report some of the most important parameter
+ settings.
+ The sixth line reports the maximum number of tries for transactions with
+ serialization or deadlock errors (see <xref linkend="failures-and-retries"/>
+ for more information).
+ The eighth line reports the number of transactions completed
+ and intended (the latter being just the product of number of clients
+ and number of transactions per client); these will be equal unless the run
+ failed before completion or some SQL command(s) failed. (In
+ <option>-T</option> mode, only the actual number of transactions is printed.)
+ The next line reports the number of failed transactions due to
+ serialization or deadlock errors (see <xref linkend="failures-and-retries"/>
+ for more information).
+ The last line reports the number of transactions per second.
+ </para>
+
+ <para>
+ The default TPC-B-like transaction test requires specific tables to be
+ set up beforehand. <application>pgbench</application> should be invoked with
+ the <option>-i</option> (initialize) option to create and populate these
+ tables. (When you are testing a custom script, you don't need this
+ step, but will instead need to do whatever setup your test needs.)
+ Initialization looks like:
+
+<programlisting>
+pgbench -i <optional> <replaceable>other-options</replaceable> </optional> <replaceable>dbname</replaceable>
+</programlisting>
+
+ where <replaceable>dbname</replaceable> is the name of the already-created
+ database to test in. (You may also need <option>-h</option>,
+ <option>-p</option>, and/or <option>-U</option> options to specify how to
+ connect to the database server.)
+ </para>
+
+ <caution>
+ <para>
+ <literal>pgbench -i</literal> creates four tables <structname>pgbench_accounts</structname>,
+ <structname>pgbench_branches</structname>, <structname>pgbench_history</structname>, and
+ <structname>pgbench_tellers</structname>,
+ destroying any existing tables of these names.
+ Be very careful to use another database if you have tables having these
+ names!
+ </para>
+ </caution>
+
+ <para>
+ At the default <quote>scale factor</quote> of 1, the tables initially
+ contain this many rows:
+<screen>
+table # of rows
+---------------------------------
+pgbench_branches 1
+pgbench_tellers 10
+pgbench_accounts 100000
+pgbench_history 0
+</screen>
+ You can (and, for most purposes, probably should) increase the number
+ of rows by using the <option>-s</option> (scale factor) option. The
+ <option>-F</option> (fillfactor) option might also be used at this point.
+ </para>
+
+ <para>
+ Once you have done the necessary setup, you can run your benchmark
+ with a command that doesn't include <option>-i</option>, that is
+
+<programlisting>
+pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>dbname</replaceable>
+</programlisting>
+
+ In nearly all cases, you'll need some options to make a useful test.
+ The most important options are <option>-c</option> (number of clients),
+ <option>-t</option> (number of transactions), <option>-T</option> (time limit),
+ and <option>-f</option> (specify a custom script file).
+ See below for a full list.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ The following is divided into three subsections. Different options are
+ used during database initialization and while running benchmarks, but some
+ options are useful in both cases.
+ </para>
+
+ <refsect2 id="pgbench-init-options">
+ <title>Initialization Options</title>
+
+ <para>
+ <application>pgbench</application> accepts the following command-line
+ initialization arguments:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><replaceable class="parameter">dbname</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to test in. If this is
+ not specified, the environment variable
+ <envar>PGDATABASE</envar> is used. If that is not set, the
+ user name specified for the connection is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <term><option>--initialize</option></term>
+ <listitem>
+ <para>
+ Required to invoke initialization mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-I <replaceable>init_steps</replaceable></option></term>
+ <term><option>--init-steps=<replaceable>init_steps</replaceable></option></term>
+ <listitem>
+ <para>
+ Perform just a selected set of the normal initialization steps.
+ <replaceable>init_steps</replaceable> specifies the
+ initialization steps to be performed, using one character per step.
+ Each step is invoked in the specified order.
+ The default is <literal>dtgvp</literal>.
+ The available steps are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>d</literal> (Drop)</term>
+ <listitem>
+ <para>
+ Drop any existing <application>pgbench</application> tables.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>t</literal> (create Tables)</term>
+ <listitem>
+ <para>
+ Create the tables used by the
+ standard <application>pgbench</application> scenario, namely
+ <structname>pgbench_accounts</structname>,
+ <structname>pgbench_branches</structname>,
+ <structname>pgbench_history</structname>, and
+ <structname>pgbench_tellers</structname>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>g</literal> or <literal>G</literal> (Generate data, client-side or server-side)</term>
+ <listitem>
+ <para>
+ Generate data and load it into the standard tables,
+ replacing any data already present.
+ </para>
+ <para>
+ With <literal>g</literal> (client-side data generation),
+ data is generated in <command>pgbench</command> client and then
+ sent to the server. This uses the client/server bandwidth
+ extensively through a <command>COPY</command>.
+ <command>pgbench</command> uses the FREEZE option with version 14 or later
+ of <productname>PostgreSQL</productname> to speed up
+ subsequent <command>VACUUM</command>, unless partitions are enabled.
+ Using <literal>g</literal> causes logging to print one message
+ every 100,000 rows while generating data for the
+ <structname>pgbench_accounts</structname> table.
+ </para>
+ <para>
+ With <literal>G</literal> (server-side data generation),
+ only small queries are sent from the <command>pgbench</command>
+ client and then data is actually generated in the server.
+ No significant bandwidth is required for this variant, but
+ the server will do more work.
+ Using <literal>G</literal> causes logging not to print any progress
+ message while generating data.
+ </para>
+ <para>
+ The default initialization behavior uses client-side data
+ generation (equivalent to <literal>g</literal>).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>v</literal> (Vacuum)</term>
+ <listitem>
+ <para>
+ Invoke <command>VACUUM</command> on the standard tables.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>p</literal> (create Primary keys)</term>
+ <listitem>
+ <para>
+ Create primary key indexes on the standard tables.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>f</literal> (create Foreign keys)</term>
+ <listitem>
+ <para>
+ Create foreign key constraints between the standard tables.
+ (Note that this step is not performed by default.)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F</option> <replaceable>fillfactor</replaceable></term>
+ <term><option>--fillfactor=</option><replaceable>fillfactor</replaceable></term>
+ <listitem>
+ <para>
+ Create the <structname>pgbench_accounts</structname>,
+ <structname>pgbench_tellers</structname> and
+ <structname>pgbench_branches</structname> tables with the given fillfactor.
+ Default is 100.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-vacuum</option></term>
+ <listitem>
+ <para>
+ Perform no vacuuming during initialization.
+ (This option suppresses the <literal>v</literal> initialization step,
+ even if it was specified in <option>-I</option>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Switch logging to quiet mode, producing only one progress message per 5
+ seconds. The default logging prints one message each 100,000 rows, which
+ often outputs many lines per second (especially on good hardware).
+ </para>
+ <para>
+ This setting has no effect if <literal>G</literal> is specified
+ in <option>-I</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option> <replaceable>scale_factor</replaceable></term>
+ <term><option>--scale=</option><replaceable>scale_factor</replaceable></term>
+ <listitem>
+ <para>
+ Multiply the number of rows generated by the scale factor.
+ For example, <literal>-s 100</literal> will create 10,000,000 rows
+ in the <structname>pgbench_accounts</structname> table. Default is 1.
+ When the scale is 20,000 or larger, the columns used to
+ hold account identifiers (<structfield>aid</structfield> columns)
+ will switch to using larger integers (<type>bigint</type>),
+ in order to be big enough to hold the range of account
+ identifiers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--foreign-keys</option></term>
+ <listitem>
+ <para>
+ Create foreign key constraints between the standard tables.
+ (This option adds the <literal>f</literal> step to the initialization
+ step sequence, if it is not already present.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--index-tablespace=<replaceable>index_tablespace</replaceable></option></term>
+ <listitem>
+ <para>
+ Create indexes in the specified tablespace, rather than the default
+ tablespace.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--partition-method=<replaceable>NAME</replaceable></option></term>
+ <listitem>
+ <para>
+ Create a partitioned <literal>pgbench_accounts</literal> table with
+ <replaceable>NAME</replaceable> method.
+ Expected values are <literal>range</literal> or <literal>hash</literal>.
+ This option requires that <option>--partitions</option> is set to non-zero.
+ If unspecified, default is <literal>range</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--partitions=<replaceable>NUM</replaceable></option></term>
+ <listitem>
+ <para>
+ Create a partitioned <literal>pgbench_accounts</literal> table with
+ <replaceable>NUM</replaceable> partitions of nearly equal size for
+ the scaled number of accounts.
+ Default is <literal>0</literal>, meaning no partitioning.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--tablespace=<replaceable>tablespace</replaceable></option></term>
+ <listitem>
+ <para>
+ Create tables in the specified tablespace, rather than the default
+ tablespace.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--unlogged-tables</option></term>
+ <listitem>
+ <para>
+ Create all tables as unlogged tables, rather than permanent tables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect2>
+
+ <refsect2 id="pgbench-run-options">
+ <title>Benchmarking Options</title>
+
+ <para>
+ <application>pgbench</application> accepts the following command-line
+ benchmarking arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-b</option> <replaceable>scriptname[@weight]</replaceable></term>
+ <term><option>--builtin</option>=<replaceable>scriptname[@weight]</replaceable></term>
+ <listitem>
+ <para>
+ Add the specified built-in script to the list of scripts to be executed.
+ Available built-in scripts are: <literal>tpcb-like</literal>,
+ <literal>simple-update</literal> and <literal>select-only</literal>.
+ Unambiguous prefixes of built-in names are accepted.
+ With the special name <literal>list</literal>, show the list of built-in scripts
+ and exit immediately.
+ </para>
+ <para>
+ Optionally, write an integer weight after <literal>@</literal> to
+ adjust the probability of selecting this script versus other ones.
+ The default weight is 1.
+ See below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option> <replaceable>clients</replaceable></term>
+ <term><option>--client=</option><replaceable>clients</replaceable></term>
+ <listitem>
+ <para>
+ Number of clients simulated, that is, number of concurrent database
+ sessions. Default is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C</option></term>
+ <term><option>--connect</option></term>
+ <listitem>
+ <para>
+ Establish a new connection for each transaction, rather than
+ doing it just once per client session.
+ This is useful to measure the connection overhead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d</option></term>
+ <term><option>--debug</option></term>
+ <listitem>
+ <para>
+ Print debugging output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D</option> <replaceable>varname</replaceable><literal>=</literal><replaceable>value</replaceable></term>
+ <term><option>--define=</option><replaceable>varname</replaceable><literal>=</literal><replaceable>value</replaceable></term>
+ <listitem>
+ <para>
+ Define a variable for use by a custom script (see below).
+ Multiple <option>-D</option> options are allowed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option> <replaceable>filename[@weight]</replaceable></term>
+ <term><option>--file=</option><replaceable>filename[@weight]</replaceable></term>
+ <listitem>
+ <para>
+ Add a transaction script read from <replaceable>filename</replaceable>
+ to the list of scripts to be executed.
+ </para>
+ <para>
+ Optionally, write an integer weight after <literal>@</literal> to
+ adjust the probability of selecting this script versus other ones.
+ The default weight is 1.
+ (To use a script file name that includes an <literal>@</literal>
+ character, append a weight so that there is no ambiguity, for
+ example <literal>filen@me@1</literal>.)
+ See below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j</option> <replaceable>threads</replaceable></term>
+ <term><option>--jobs=</option><replaceable>threads</replaceable></term>
+ <listitem>
+ <para>
+ Number of worker threads within <application>pgbench</application>.
+ Using more than one thread can be helpful on multi-CPU machines.
+ Clients are distributed as evenly as possible among available threads.
+ Default is 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l</option></term>
+ <term><option>--log</option></term>
+ <listitem>
+ <para>
+ Write information about each transaction to a log file.
+ See below for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-L</option> <replaceable>limit</replaceable></term>
+ <term><option>--latency-limit=</option><replaceable>limit</replaceable></term>
+ <listitem>
+ <para>
+ Transactions that last more than <replaceable>limit</replaceable> milliseconds
+ are counted and reported separately, as <firstterm>late</firstterm>.
+ </para>
+ <para>
+ When throttling is used (<option>--rate=...</option>), transactions that
+ lag behind schedule by more than <replaceable>limit</replaceable> ms, and thus
+ have no hope of meeting the latency limit, are not sent to the server
+ at all. They are counted and reported separately as
+ <firstterm>skipped</firstterm>.
+ </para>
+ <para>
+ When the <option>--max-tries</option> option is used, a transaction
+ which fails due to a serialization anomaly or from a deadlock will not
+ be retried if the total time of all its tries is greater than
+ <replaceable>limit</replaceable> ms. To limit only the time of tries
+ and not their number, use <literal>--max-tries=0</literal>. By
+ default, the option <option>--max-tries</option> is set to 1 and
+ transactions with serialization/deadlock errors are not retried. See
+ <xref linkend="failures-and-retries"/> for more information about
+ retrying such transactions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-M</option> <replaceable>querymode</replaceable></term>
+ <term><option>--protocol=</option><replaceable>querymode</replaceable></term>
+ <listitem>
+ <para>
+ Protocol to use for submitting queries to the server:
+ <itemizedlist>
+ <listitem>
+ <para><literal>simple</literal>: use simple query protocol.</para>
+ </listitem>
+ <listitem>
+ <para><literal>extended</literal>: use extended query protocol.</para>
+ </listitem>
+ <listitem>
+ <para><literal>prepared</literal>: use extended query protocol with prepared statements.</para>
+ </listitem>
+ </itemizedlist>
+
+ In the <literal>prepared</literal> mode, <application>pgbench</application>
+ reuses the parse analysis result starting from the second query
+ iteration, so <application>pgbench</application> runs faster
+ than in other modes.
+ </para>
+ <para>
+ The default is simple query protocol. (See <xref linkend="protocol"/>
+ for more information.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-vacuum</option></term>
+ <listitem>
+ <para>
+ Perform no vacuuming before running the test.
+ This option is <emphasis>necessary</emphasis>
+ if you are running a custom test scenario that does not include
+ the standard tables <structname>pgbench_accounts</structname>,
+ <structname>pgbench_branches</structname>, <structname>pgbench_history</structname>, and
+ <structname>pgbench_tellers</structname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+ <term><option>--skip-some-updates</option></term>
+ <listitem>
+ <para>
+ Run built-in simple-update script.
+ Shorthand for <option>-b simple-update</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option> <replaceable>sec</replaceable></term>
+ <term><option>--progress=</option><replaceable>sec</replaceable></term>
+ <listitem>
+ <para>
+ Show progress report every <replaceable>sec</replaceable> seconds. The report
+ includes the time since the beginning of the run, the TPS since the
+ last report, and the transaction latency average, standard deviation,
+ and the number of failed transactions since the last report. Under
+ throttling (<option>-R</option>), the latency is computed with respect
+ to the transaction scheduled start time, not the actual transaction
+ beginning time, thus it also includes the average schedule lag time.
+ When <option>--max-tries</option> is used to enable transaction retries
+ after serialization/deadlock errors, the report includes the number of
+ retried transactions and the sum of all retries.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+ <term><option>--report-per-command</option></term>
+ <listitem>
+ <para>
+ Report the following statistics for each command after the benchmark
+ finishes: the average per-statement latency (execution time from the
+ perspective of the client), the number of failures, and the number of
+ retries after serialization or deadlock errors in this command. The
+ report displays retry statistics only if the
+ <option>--max-tries</option> option is not equal to 1.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R</option> <replaceable>rate</replaceable></term>
+ <term><option>--rate=</option><replaceable>rate</replaceable></term>
+ <listitem>
+ <para>
+ Execute transactions targeting the specified rate instead of running
+ as fast as possible (the default). The rate is given in transactions
+ per second. If the targeted rate is above the maximum possible rate,
+ the rate limit won't impact the results.
+ </para>
+ <para>
+ The rate is targeted by starting transactions along a
+ Poisson-distributed schedule time line. The expected start time
+ schedule moves forward based on when the client first started, not
+ when the previous transaction ended. That approach means that when
+ transactions go past their original scheduled end time, it is
+ possible for later ones to catch up again.
+ </para>
+ <para>
+ When throttling is active, the transaction latency reported at the
+ end of the run is calculated from the scheduled start times, so it
+ includes the time each transaction had to wait for the previous
+ transaction to finish. The wait time is called the schedule lag time,
+ and its average and maximum are also reported separately. The
+ transaction latency with respect to the actual transaction start time,
+ i.e., the time spent executing the transaction in the database, can be
+ computed by subtracting the schedule lag time from the reported
+ latency.
+ </para>
+
+ <para>
+ If <option>--latency-limit</option> is used together with <option>--rate</option>,
+ a transaction can lag behind so much that it is already over the
+ latency limit when the previous transaction ends, because the latency
+ is calculated from the scheduled start time. Such transactions are
+ not sent to the server, but are skipped altogether and counted
+ separately.
+ </para>
+
+ <para>
+ A high schedule lag time is an indication that the system cannot
+ process transactions at the specified rate, with the chosen number of
+ clients and threads. When the average transaction execution time is
+ longer than the scheduled interval between each transaction, each
+ successive transaction will fall further behind, and the schedule lag
+ time will keep increasing the longer the test run is. When that
+ happens, you will have to reduce the specified transaction rate.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option> <replaceable>scale_factor</replaceable></term>
+ <term><option>--scale=</option><replaceable>scale_factor</replaceable></term>
+ <listitem>
+ <para>
+ Report the specified scale factor in <application>pgbench</application>'s
+ output. With the built-in tests, this is not necessary; the
+ correct scale factor will be detected by counting the number of
+ rows in the <structname>pgbench_branches</structname> table.
+ However, when testing only custom benchmarks (<option>-f</option> option),
+ the scale factor will be reported as 1 unless this option is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S</option></term>
+ <term><option>--select-only</option></term>
+ <listitem>
+ <para>
+ Run built-in select-only script.
+ Shorthand for <option>-b select-only</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option> <replaceable>transactions</replaceable></term>
+ <term><option>--transactions=</option><replaceable>transactions</replaceable></term>
+ <listitem>
+ <para>
+ Number of transactions each client runs. Default is 10.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T</option> <replaceable>seconds</replaceable></term>
+ <term><option>--time=</option><replaceable>seconds</replaceable></term>
+ <listitem>
+ <para>
+ Run the test for this many seconds, rather than a fixed number of
+ transactions per client. <option>-t</option> and
+ <option>-T</option> are mutually exclusive.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--vacuum-all</option></term>
+ <listitem>
+ <para>
+ Vacuum all four standard tables before running the test.
+ With neither <option>-n</option> nor <option>-v</option>, <application>pgbench</application> will vacuum the
+ <structname>pgbench_tellers</structname> and <structname>pgbench_branches</structname>
+ tables, and will truncate <structname>pgbench_history</structname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--aggregate-interval=<replaceable>seconds</replaceable></option></term>
+ <listitem>
+ <para>
+ Length of aggregation interval (in seconds). May be used only
+ with <option>-l</option> option. With this option, the log contains
+ per-interval summary data, as described below.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--failures-detailed</option></term>
+ <listitem>
+ <para>
+ Report failures in per-transaction and aggregation logs, as well as in
+ the main and per-script reports, grouped by the following types:
+ <itemizedlist>
+ <listitem>
+ <para>serialization failures;</para>
+ </listitem>
+ <listitem>
+ <para>deadlock failures;</para>
+ </listitem>
+ </itemizedlist>
+ See <xref linkend="failures-and-retries"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--log-prefix=<replaceable>prefix</replaceable></option></term>
+ <listitem>
+ <para>
+ Set the filename prefix for the log files created by
+ <option>--log</option>. The default is <literal>pgbench_log</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--max-tries=<replaceable>number_of_tries</replaceable></option></term>
+ <listitem>
+ <para>
+ Enable retries for transactions with serialization/deadlock errors and
+ set the maximum number of these tries. This option can be combined with
+ the <option>--latency-limit</option> option which limits the total time
+ of all transaction tries; moreover, you cannot use an unlimited number
+ of tries (<literal>--max-tries=0</literal>) without
+ <option>--latency-limit</option> or <option>--time</option>.
+ The default value is 1 and transactions with serialization/deadlock
+ errors are not retried. See <xref linkend="failures-and-retries"/>
+ for more information about retrying such transactions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--progress-timestamp</option></term>
+ <listitem>
+ <para>
+ When showing progress (option <option>-P</option>), use a timestamp
+ (Unix epoch) instead of the number of seconds since the
+ beginning of the run. The unit is in seconds, with millisecond
+ precision after the dot.
+ This helps compare logs generated by various tools.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--random-seed=</option><replaceable>seed</replaceable></term>
+ <listitem>
+ <para>
+ Set random generator seed. Seeds the system random number generator,
+ which then produces a sequence of initial generator states, one for
+ each thread.
+ Values for <replaceable>seed</replaceable> may be:
+ <literal>time</literal> (the default, the seed is based on the current time),
+ <literal>rand</literal> (use a strong random source, failing if none
+ is available), or an unsigned decimal integer value.
+ The random generator is invoked explicitly from a pgbench script
+ (<literal>random...</literal> functions) or implicitly (for instance option
+ <option>--rate</option> uses it to schedule transactions).
+ When explicitly set, the value used for seeding is shown on the terminal.
+ Any value allowed for <replaceable>seed</replaceable> may also be
+ provided through the environment variable
+ <literal>PGBENCH_RANDOM_SEED</literal>.
+ To ensure that the provided seed impacts all possible uses, put this option
+ first or use the environment variable.
+ </para>
+ <para>
+ Setting the seed explicitly allows to reproduce a <command>pgbench</command>
+ run exactly, as far as random numbers are concerned.
+ As the random state is managed per thread, this means the exact same
+ <command>pgbench</command> run for an identical invocation if there is one
+ client per thread and there are no external or data dependencies.
+ From a statistical viewpoint reproducing runs exactly is a bad idea because
+ it can hide the performance variability or improve performance unduly,
+ e.g., by hitting the same pages as a previous run.
+ However, it may also be of great help for debugging, for instance
+ re-running a tricky case which leads to an error.
+ Use wisely.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--sampling-rate=<replaceable>rate</replaceable></option></term>
+ <listitem>
+ <para>
+ Sampling rate, used when writing data into the log, to reduce the
+ amount of log generated. If this option is given, only the specified
+ fraction of transactions are logged. 1.0 means all transactions will
+ be logged, 0.05 means only 5% of the transactions will be logged.
+ </para>
+ <para>
+ Remember to take the sampling rate into account when processing the
+ log file. For example, when computing TPS values, you need to multiply
+ the numbers accordingly (e.g., with 0.01 sample rate, you'll only get
+ 1/100 of the actual TPS).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--show-script=</option><replaceable>scriptname</replaceable></term>
+ <listitem>
+ <para>
+ Show the actual code of builtin script <replaceable>scriptname</replaceable>
+ on stderr, and exit immediately.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--verbose-errors</option></term>
+ <listitem>
+ <para>
+ Print messages about all errors and failures (errors without retrying)
+ including which limit for retries was exceeded and how far it was
+ exceeded for the serialization/deadlock failures. (Note that in this
+ case the output can be significantly increased.).
+ See <xref linkend="failures-and-retries"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect2>
+
+ <refsect2 id="pgbench-common-options">
+ <title>Common Options</title>
+
+ <para>
+ <application>pgbench</application> also accepts the following common command-line
+ arguments for connection parameters:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-h</option> <replaceable>hostname</replaceable></term>
+ <term><option>--host=</option><replaceable>hostname</replaceable></term>
+ <listitem>
+ <para>
+ The database server's host name
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p</option> <replaceable>port</replaceable></term>
+ <term><option>--port=</option><replaceable>port</replaceable></term>
+ <listitem>
+ <para>
+ The database server's port number
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U</option> <replaceable>login</replaceable></term>
+ <term><option>--username=</option><replaceable>login</replaceable></term>
+ <listitem>
+ <para>
+ The user name to connect as
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pgbench</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pgbench</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Exit Status</title>
+
+ <para>
+ A successful run will exit with status 0. Exit status 1 indicates static
+ problems such as invalid command-line options or internal errors which
+ are supposed to never occur. Early errors that occur when starting
+ benchmark such as initial connection failures also exit with status 1.
+ Errors during the run such as database errors or problems in the script
+ will result in exit status 2. In the latter case,
+ <application>pgbench</application> will print partial results.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <refsect2 id="transactions-and-scripts" xreflabel="What Is the &quot;Transaction&quot; Actually Performed in pgbench?">
+ <title>What Is the <quote>Transaction</quote> Actually Performed in <application>pgbench</application>?</title>
+
+ <para>
+ <application>pgbench</application> executes test scripts chosen randomly
+ from a specified list.
+ The scripts may include built-in scripts specified with <option>-b</option>
+ and user-provided scripts specified with <option>-f</option>.
+ Each script may be given a relative weight specified after an
+ <literal>@</literal> so as to change its selection probability.
+ The default weight is <literal>1</literal>.
+ Scripts with a weight of <literal>0</literal> are ignored.
+ </para>
+
+ <para>
+ The default built-in transaction script (also invoked with <option>-b tpcb-like</option>)
+ issues seven commands per transaction over randomly chosen <literal>aid</literal>,
+ <literal>tid</literal>, <literal>bid</literal> and <literal>delta</literal>.
+ The scenario is inspired by the TPC-B benchmark, but is not actually TPC-B,
+ hence the name.
+ </para>
+
+ <orderedlist>
+ <listitem><para><literal>BEGIN;</literal></para></listitem>
+ <listitem><para><literal>UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;</literal></para></listitem>
+ <listitem><para><literal>SELECT abalance FROM pgbench_accounts WHERE aid = :aid;</literal></para></listitem>
+ <listitem><para><literal>UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;</literal></para></listitem>
+ <listitem><para><literal>UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;</literal></para></listitem>
+ <listitem><para><literal>INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);</literal></para></listitem>
+ <listitem><para><literal>END;</literal></para></listitem>
+ </orderedlist>
+
+ <para>
+ If you select the <literal>simple-update</literal> built-in (also <option>-N</option>),
+ steps 4 and 5 aren't included in the transaction.
+ This will avoid update contention on these tables, but
+ it makes the test case even less like TPC-B.
+ </para>
+
+ <para>
+ If you select the <literal>select-only</literal> built-in (also <option>-S</option>),
+ only the <command>SELECT</command> is issued.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Custom Scripts</title>
+
+ <para>
+ <application>pgbench</application> has support for running custom
+ benchmark scenarios by replacing the default transaction script
+ (described above) with a transaction script read from a file
+ (<option>-f</option> option). In this case a <quote>transaction</quote>
+ counts as one execution of a script file.
+ </para>
+
+ <para>
+ A script file contains one or more SQL commands terminated by
+ semicolons. Empty lines and lines beginning with
+ <literal>--</literal> are ignored. Script files can also contain
+ <quote>meta commands</quote>, which are interpreted by <application>pgbench</application>
+ itself, as described below.
+ </para>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 9.6, SQL commands in script files
+ were terminated by newlines, and so they could not be continued across
+ lines. Now a semicolon is <emphasis>required</emphasis> to separate consecutive
+ SQL commands (though an SQL command does not need one if it is followed
+ by a meta command). If you need to create a script file that works with
+ both old and new versions of <application>pgbench</application>, be sure to write
+ each SQL command on a single line ending with a semicolon.
+ </para>
+ <para>
+ It is assumed that pgbench scripts do not contain incomplete blocks of SQL
+ transactions. If at runtime the client reaches the end of the script without
+ completing the last transaction block, it will be aborted.
+ </para>
+ </note>
+
+ <para>
+ There is a simple variable-substitution facility for script files.
+ Variable names must consist of letters (including non-Latin letters),
+ digits, and underscores, with the first character not being a digit.
+ Variables can be set by the command-line <option>-D</option> option,
+ explained above, or by the meta commands explained below.
+ In addition to any variables preset by <option>-D</option> command-line options,
+ there are a few variables that are preset automatically, listed in
+ <xref linkend="pgbench-automatic-variables"/>. A value specified for these
+ variables using <option>-D</option> takes precedence over the automatic presets.
+ Once set, a variable's
+ value can be inserted into an SQL command by writing
+ <literal>:</literal><replaceable>variablename</replaceable>. When running more than
+ one client session, each session has its own set of variables.
+ <application>pgbench</application> supports up to 255 variable uses in one
+ statement.
+ </para>
+
+ <table id="pgbench-automatic-variables">
+ <title>pgbench Automatic Variables</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry> <literal>client_id</literal> </entry>
+ <entry>unique number identifying the client session (starts from zero)</entry>
+ </row>
+
+ <row>
+ <entry> <literal>default_seed</literal> </entry>
+ <entry>seed used in hash and pseudorandom permutation functions by default</entry>
+ </row>
+
+ <row>
+ <entry> <literal>random_seed</literal> </entry>
+ <entry>random generator seed (unless overwritten with <option>-D</option>)</entry>
+ </row>
+
+ <row>
+ <entry> <literal>scale</literal> </entry>
+ <entry>current scale factor</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Script file meta commands begin with a backslash (<literal>\</literal>) and
+ normally extend to the end of the line, although they can be continued
+ to additional lines by writing backslash-return.
+ Arguments to a meta command are separated by white space.
+ These meta commands are supported:
+ </para>
+
+ <variablelist>
+ <varlistentry id='pgbench-metacommand-gset'>
+ <term>
+ <literal>\gset [<replaceable>prefix</replaceable>]</literal>
+ <literal>\aset [<replaceable>prefix</replaceable>]</literal>
+ </term>
+
+ <listitem>
+ <para>
+ These commands may be used to end SQL queries, taking the place of the
+ terminating semicolon (<literal>;</literal>).
+ </para>
+
+ <para>
+ When the <literal>\gset</literal> command is used, the preceding SQL query is
+ expected to return one row, the columns of which are stored into variables
+ named after column names, and prefixed with <replaceable>prefix</replaceable>
+ if provided.
+ </para>
+
+ <para>
+ When the <literal>\aset</literal> command is used, all combined SQL queries
+ (separated by <literal>\;</literal>) have their columns stored into variables
+ named after column names, and prefixed with <replaceable>prefix</replaceable>
+ if provided. If a query returns no row, no assignment is made and the variable
+ can be tested for existence to detect this. If a query returns more than one
+ row, the last value is kept.
+ </para>
+
+ <para>
+ <literal>\gset</literal> and <literal>\aset</literal> cannot be used in
+ pipeline mode, since the query results are not yet available by the time
+ the commands would need them.
+ </para>
+
+ <para>
+ The following example puts the final account balance from the first query
+ into variable <replaceable>abalance</replaceable>, and fills variables
+ <replaceable>p_two</replaceable> and <replaceable>p_three</replaceable>
+ with integers from the third query.
+ The result of the second query is discarded.
+ The result of the two last combined queries are stored in variables
+ <replaceable>four</replaceable> and <replaceable>five</replaceable>.
+<programlisting>
+UPDATE pgbench_accounts
+ SET abalance = abalance + :delta
+ WHERE aid = :aid
+ RETURNING abalance \gset
+-- compound of two queries
+SELECT 1 \;
+SELECT 2 AS two, 3 AS three \gset p_
+SELECT 4 AS four \; SELECT 5 AS five \aset
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\if</literal> <replaceable class="parameter">expression</replaceable></term>
+ <term><literal>\elif</literal> <replaceable class="parameter">expression</replaceable></term>
+ <term><literal>\else</literal></term>
+ <term><literal>\endif</literal></term>
+ <listitem>
+ <para>
+ This group of commands implements nestable conditional blocks,
+ similarly to <literal>psql</literal>'s <xref linkend="psql-metacommand-if"/>.
+ Conditional expressions are identical to those with <literal>\set</literal>,
+ with non-zero values interpreted as true.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='pgbench-metacommand-set'>
+ <term>
+ <literal>\set <replaceable>varname</replaceable> <replaceable>expression</replaceable></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Sets variable <replaceable>varname</replaceable> to a value calculated
+ from <replaceable>expression</replaceable>.
+ The expression may contain the <literal>NULL</literal> constant,
+ Boolean constants <literal>TRUE</literal> and <literal>FALSE</literal>,
+ integer constants such as <literal>5432</literal>,
+ double constants such as <literal>3.14159</literal>,
+ references to variables <literal>:</literal><replaceable>variablename</replaceable>,
+ <link linkend="pgbench-builtin-operators">operators</link>
+ with their usual SQL precedence and associativity,
+ <link linkend="pgbench-builtin-functions">function calls</link>,
+ SQL <link linkend="functions-case"><token>CASE</token> generic conditional
+ expressions</link> and parentheses.
+ </para>
+
+ <para>
+ Functions and most operators return <literal>NULL</literal> on
+ <literal>NULL</literal> input.
+ </para>
+
+ <para>
+ For conditional purposes, non zero numerical values are
+ <literal>TRUE</literal>, zero numerical values and <literal>NULL</literal>
+ are <literal>FALSE</literal>.
+ </para>
+
+ <para>
+ Too large or small integer and double constants, as well as
+ integer arithmetic operators (<literal>+</literal>,
+ <literal>-</literal>, <literal>*</literal> and <literal>/</literal>)
+ raise errors on overflows.
+ </para>
+
+ <para>
+ When no final <token>ELSE</token> clause is provided to a
+ <token>CASE</token>, the default value is <literal>NULL</literal>.
+ </para>
+
+ <para>
+ Examples:
+<programlisting>
+\set ntellers 10 * :scale
+\set aid (1021 * random(1, 100000 * :scale)) % \
+ (100000 * :scale) + 1
+\set divx CASE WHEN :x &lt;&gt; 0 THEN :y/:x ELSE NULL END
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\sleep <replaceable>number</replaceable> [ us | ms | s ]</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Causes script execution to sleep for the specified duration in
+ microseconds (<literal>us</literal>), milliseconds (<literal>ms</literal>) or seconds
+ (<literal>s</literal>). If the unit is omitted then seconds are the default.
+ <replaceable>number</replaceable> can be either an integer constant or a
+ <literal>:</literal><replaceable>variablename</replaceable> reference to a variable
+ having an integer value.
+ </para>
+
+ <para>
+ Example:
+<programlisting>
+\sleep 10 ms
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\setshell <replaceable>varname</replaceable> <replaceable>command</replaceable> [ <replaceable>argument</replaceable> ... ]</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Sets variable <replaceable>varname</replaceable> to the result of the shell command
+ <replaceable>command</replaceable> with the given <replaceable>argument</replaceable>(s).
+ The command must return an integer value through its standard output.
+ </para>
+
+ <para>
+ <replaceable>command</replaceable> and each <replaceable>argument</replaceable> can be either
+ a text constant or a <literal>:</literal><replaceable>variablename</replaceable> reference
+ to a variable. If you want to use an <replaceable>argument</replaceable> starting
+ with a colon, write an additional colon at the beginning of
+ <replaceable>argument</replaceable>.
+ </para>
+
+ <para>
+ Example:
+<programlisting>
+\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\shell <replaceable>command</replaceable> [ <replaceable>argument</replaceable> ... ]</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Same as <literal>\setshell</literal>, but the result of the command
+ is discarded.
+ </para>
+
+ <para>
+ Example:
+<programlisting>
+\shell command literal_argument :variable ::literal_starting_with_colon
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id='pgbench-metacommand-pipeline'>
+ <term><literal>\startpipeline</literal></term>
+ <term><literal>\endpipeline</literal></term>
+
+ <listitem>
+ <para>
+ These commands delimit the start and end of a pipeline of SQL
+ statements. In pipeline mode, statements are sent to the server
+ without waiting for the results of previous statements. See
+ <xref linkend="libpq-pipeline-mode"/> for more details.
+ Pipeline mode requires the use of extended query protocol.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect2>
+
+ <refsect2 id="pgbench-builtin-operators">
+ <title>Built-in Operators</title>
+
+ <para>
+ The arithmetic, bitwise, comparison and logical operators listed in
+ <xref linkend="pgbench-operators"/> are built into <application>pgbench</application>
+ and may be used in expressions appearing in
+ <link linkend="pgbench-metacommand-set"><literal>\set</literal></link>.
+ The operators are listed in increasing precedence order.
+ Except as noted, operators taking two numeric inputs will produce
+ a double value if either input is double, otherwise they produce
+ an integer result.
+ </para>
+
+ <table id="pgbench-operators">
+ <title>pgbench Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>boolean</replaceable> <literal>OR</literal> <replaceable>boolean</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Logical OR
+ </para>
+ <para>
+ <literal>5 or 0</literal>
+ <returnvalue>TRUE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>boolean</replaceable> <literal>AND</literal> <replaceable>boolean</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Logical AND
+ </para>
+ <para>
+ <literal>3 and 0</literal>
+ <returnvalue>FALSE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>NOT</literal> <replaceable>boolean</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Logical NOT
+ </para>
+ <para>
+ <literal>not false</literal>
+ <returnvalue>TRUE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>boolean</replaceable> <literal>IS [NOT] (NULL|TRUE|FALSE)</literal>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Boolean value tests
+ </para>
+ <para>
+ <literal>1 is null</literal>
+ <returnvalue>FALSE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>value</replaceable> <literal>ISNULL|NOTNULL</literal>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Nullness tests
+ </para>
+ <para>
+ <literal>1 notnull</literal>
+ <returnvalue>TRUE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>=</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Equal
+ </para>
+ <para>
+ <literal>5 = 4</literal>
+ <returnvalue>FALSE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>&lt;&gt;</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Not equal
+ </para>
+ <para>
+ <literal>5 &lt;&gt; 4</literal>
+ <returnvalue>TRUE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>!=</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Not equal
+ </para>
+ <para>
+ <literal>5 != 5</literal>
+ <returnvalue>FALSE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>&lt;</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Less than
+ </para>
+ <para>
+ <literal>5 &lt; 4</literal>
+ <returnvalue>FALSE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>&lt;=</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Less than or equal to
+ </para>
+ <para>
+ <literal>5 &lt;= 4</literal>
+ <returnvalue>FALSE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>&gt;</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Greater than
+ </para>
+ <para>
+ <literal>5 &gt; 4</literal>
+ <returnvalue>TRUE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>&gt;=</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>boolean</replaceable></returnvalue>
+ </para>
+ <para>
+ Greater than or equal to
+ </para>
+ <para>
+ <literal>5 &gt;= 4</literal>
+ <returnvalue>TRUE</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integer</replaceable> <literal>|</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise OR
+ </para>
+ <para>
+ <literal>1 | 2</literal>
+ <returnvalue>3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integer</replaceable> <literal>#</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise XOR
+ </para>
+ <para>
+ <literal>1 # 3</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integer</replaceable> <literal>&amp;</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise AND
+ </para>
+ <para>
+ <literal>1 &amp; 3</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>~</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise NOT
+ </para>
+ <para>
+ <literal>~ 1</literal>
+ <returnvalue>-2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integer</replaceable> <literal>&lt;&lt;</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise shift left
+ </para>
+ <para>
+ <literal>1 &lt;&lt; 2</literal>
+ <returnvalue>4</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integer</replaceable> <literal>&gt;&gt;</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Bitwise shift right
+ </para>
+ <para>
+ <literal>8 &gt;&gt; 2</literal>
+ <returnvalue>2</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>+</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Addition
+ </para>
+ <para>
+ <literal>5 + 4</literal>
+ <returnvalue>9</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>-</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Subtraction
+ </para>
+ <para>
+ <literal>3 - 2.0</literal>
+ <returnvalue>1.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>*</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Multiplication
+ </para>
+ <para>
+ <literal>5 * 4</literal>
+ <returnvalue>20</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>number</replaceable> <literal>/</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Division (truncates the result towards zero if both inputs are integers)
+ </para>
+ <para>
+ <literal>5 / 3</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <replaceable>integer</replaceable> <literal>%</literal> <replaceable>integer</replaceable>
+ <returnvalue><replaceable>integer</replaceable></returnvalue>
+ </para>
+ <para>
+ Modulo (remainder)
+ </para>
+ <para>
+ <literal>3 % 2</literal>
+ <returnvalue>1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <literal>-</literal> <replaceable>number</replaceable>
+ <returnvalue><replaceable>number</replaceable></returnvalue>
+ </para>
+ <para>
+ Negation
+ </para>
+ <para>
+ <literal>- 2.0</literal>
+ <returnvalue>-2.0</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </refsect2>
+
+ <refsect2 id="pgbench-builtin-functions">
+ <title>Built-In Functions</title>
+
+ <para>
+ The functions listed in <xref linkend="pgbench-functions"/> are built
+ into <application>pgbench</application> and may be used in expressions appearing in
+ <link linkend="pgbench-metacommand-set"><literal>\set</literal></link>.
+ </para>
+
+ <!-- list pgbench functions in alphabetical order -->
+ <table id="pgbench-functions">
+ <title>pgbench Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para>
+ <para>
+ Example(s)
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>abs</function> ( <replaceable>number</replaceable> )
+ <returnvalue></returnvalue> same type as input
+ </para>
+ <para>
+ Absolute value
+ </para>
+ <para>
+ <literal>abs(-17)</literal>
+ <returnvalue>17</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>debug</function> ( <replaceable>number</replaceable> )
+ <returnvalue></returnvalue> same type as input
+ </para>
+ <para>
+ Prints the argument to <systemitem>stderr</systemitem>,
+ and returns the argument.
+ </para>
+ <para>
+ <literal>debug(5432.1)</literal>
+ <returnvalue>5432.1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>double</function> ( <replaceable>number</replaceable> )
+ <returnvalue>double</returnvalue>
+ </para>
+ <para>
+ Casts to double.
+ </para>
+ <para>
+ <literal>double(5432)</literal>
+ <returnvalue>5432.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>exp</function> ( <replaceable>number</replaceable> )
+ <returnvalue>double</returnvalue>
+ </para>
+ <para>
+ Exponential (<literal>e</literal> raised to the given power)
+ </para>
+ <para>
+ <literal>exp(1.0)</literal>
+ <returnvalue>2.718281828459045</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>greatest</function> ( <replaceable>number</replaceable> <optional>, <literal>...</literal> </optional> )
+ <returnvalue></returnvalue> <type>double</type> if any argument is double, else <type>integer</type>
+ </para>
+ <para>
+ Selects the largest value among the arguments.
+ </para>
+ <para>
+ <literal>greatest(5, 4, 3, 2)</literal>
+ <returnvalue>5</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>hash</function> ( <parameter>value</parameter> <optional>, <parameter>seed</parameter> </optional> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ This is an alias for <function>hash_murmur2</function>.
+ </para>
+ <para>
+ <literal>hash(10, 5432)</literal>
+ <returnvalue>-5817877081768721676</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>hash_fnv1a</function> ( <parameter>value</parameter> <optional>, <parameter>seed</parameter> </optional> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Computes <ulink url="https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function">FNV-1a hash</ulink>.
+ </para>
+ <para>
+ <literal>hash_fnv1a(10, 5432)</literal>
+ <returnvalue>-7793829335365542153</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>hash_murmur2</function> ( <parameter>value</parameter> <optional>, <parameter>seed</parameter> </optional> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Computes <ulink url="https://en.wikipedia.org/wiki/MurmurHash">MurmurHash2 hash</ulink>.
+ </para>
+ <para>
+ <literal>hash_murmur2(10, 5432)</literal>
+ <returnvalue>-5817877081768721676</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>int</function> ( <replaceable>number</replaceable> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Casts to integer.
+ </para>
+ <para>
+ <literal>int(5.4 + 3.8)</literal>
+ <returnvalue>9</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>least</function> ( <replaceable>number</replaceable> <optional>, <literal>...</literal> </optional> )
+ <returnvalue></returnvalue> <type>double</type> if any argument is double, else <type>integer</type>
+ </para>
+ <para>
+ Selects the smallest value among the arguments.
+ </para>
+ <para>
+ <literal>least(5, 4, 3, 2.1)</literal>
+ <returnvalue>2.1</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>ln</function> ( <replaceable>number</replaceable> )
+ <returnvalue>double</returnvalue>
+ </para>
+ <para>
+ Natural logarithm
+ </para>
+ <para>
+ <literal>ln(2.718281828459045)</literal>
+ <returnvalue>1.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+<function>mod</function> ( <replaceable>integer</replaceable>, <replaceable>integer</replaceable> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Modulo (remainder)
+ </para>
+ <para>
+ <literal>mod(54, 32)</literal>
+ <returnvalue>22</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>permute</function> ( <parameter>i</parameter>, <parameter>size</parameter> [, <parameter>seed</parameter> ] )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Permuted value of <parameter>i</parameter>, in the range
+ <literal>[0, size)</literal>. This is the new position of
+ <parameter>i</parameter> (modulo <parameter>size</parameter>) in a
+ pseudorandom permutation of the integers <literal>0...size-1</literal>,
+ parameterized by <parameter>seed</parameter>, see below.
+ </para>
+ <para>
+ <literal>permute(0, 4)</literal>
+ <returnvalue>an integer between 0 and 3</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pi</function> ()
+ <returnvalue>double</returnvalue>
+ </para>
+ <para>
+ Approximate value of <phrase role="symbol_font">&pi;</phrase>
+ </para>
+ <para>
+ <literal>pi()</literal>
+ <returnvalue>3.14159265358979323846</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>pow</function> ( <parameter>x</parameter>, <parameter>y</parameter> )
+ <returnvalue>double</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>power</function> ( <parameter>x</parameter>, <parameter>y</parameter> )
+ <returnvalue>double</returnvalue>
+ </para>
+ <para>
+ <parameter>x</parameter> raised to the power of <parameter>y</parameter>
+ </para>
+ <para>
+ <literal>pow(2.0, 10)</literal>
+ <returnvalue>1024.0</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>random</function> ( <parameter>lb</parameter>, <parameter>ub</parameter> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Computes a uniformly-distributed random integer in <literal>[lb,
+ ub]</literal>.
+ </para>
+ <para>
+ <literal>random(1, 10)</literal>
+ <returnvalue>an integer between 1 and 10</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>random_exponential</function> ( <parameter>lb</parameter>, <parameter>ub</parameter>, <parameter>parameter</parameter> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Computes an exponentially-distributed random integer in <literal>[lb,
+ ub]</literal>, see below.
+ </para>
+ <para>
+ <literal>random_exponential(1, 10, 3.0)</literal>
+ <returnvalue>an integer between 1 and 10</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>random_gaussian</function> ( <parameter>lb</parameter>, <parameter>ub</parameter>, <parameter>parameter</parameter> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Computes a Gaussian-distributed random integer in <literal>[lb,
+ ub]</literal>, see below.
+ </para>
+ <para>
+ <literal>random_gaussian(1, 10, 2.5)</literal>
+ <returnvalue>an integer between 1 and 10</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>random_zipfian</function> ( <parameter>lb</parameter>, <parameter>ub</parameter>, <parameter>parameter</parameter> )
+ <returnvalue>integer</returnvalue>
+ </para>
+ <para>
+ Computes a Zipfian-distributed random integer in <literal>[lb,
+ ub]</literal>, see below.
+ </para>
+ <para>
+ <literal>random_zipfian(1, 10, 1.5)</literal>
+ <returnvalue>an integer between 1 and 10</returnvalue>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sqrt</function> ( <replaceable>number</replaceable> )
+ <returnvalue>double</returnvalue>
+ </para>
+ <para>
+ Square root
+ </para>
+ <para>
+ <literal>sqrt(2.0)</literal>
+ <returnvalue>1.414213562</returnvalue>
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <literal>random</literal> function generates values using a uniform
+ distribution, that is all the values are drawn within the specified
+ range with equal probability. The <literal>random_exponential</literal>,
+ <literal>random_gaussian</literal> and <literal>random_zipfian</literal>
+ functions require an additional double parameter which determines the precise
+ shape of the distribution.
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ For an exponential distribution, <replaceable>parameter</replaceable>
+ controls the distribution by truncating a quickly-decreasing
+ exponential distribution at <replaceable>parameter</replaceable>, and then
+ projecting onto integers between the bounds.
+ To be precise, with
+<literallayout>
+f(x) = exp(-parameter * (x - min) / (max - min + 1)) / (1 - exp(-parameter))
+</literallayout>
+ Then value <replaceable>i</replaceable> between <replaceable>min</replaceable> and
+ <replaceable>max</replaceable> inclusive is drawn with probability:
+ <literal>f(i) - f(i + 1)</literal>.
+ </para>
+
+ <para>
+ Intuitively, the larger the <replaceable>parameter</replaceable>, the more
+ frequently values close to <replaceable>min</replaceable> are accessed, and the
+ less frequently values close to <replaceable>max</replaceable> are accessed.
+ The closer to 0 <replaceable>parameter</replaceable> is, the flatter (more
+ uniform) the access distribution.
+ A crude approximation of the distribution is that the most frequent 1%
+ values in the range, close to <replaceable>min</replaceable>, are drawn
+ <replaceable>parameter</replaceable>% of the time.
+ The <replaceable>parameter</replaceable> value must be strictly positive.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For a Gaussian distribution, the interval is mapped onto a standard
+ normal distribution (the classical bell-shaped Gaussian curve) truncated
+ at <literal>-parameter</literal> on the left and <literal>+parameter</literal>
+ on the right.
+ Values in the middle of the interval are more likely to be drawn.
+ To be precise, if <literal>PHI(x)</literal> is the cumulative distribution
+ function of the standard normal distribution, with mean <literal>mu</literal>
+ defined as <literal>(max + min) / 2.0</literal>, with
+<literallayout>
+f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) /
+ (2.0 * PHI(parameter) - 1)
+</literallayout>
+ then value <replaceable>i</replaceable> between <replaceable>min</replaceable> and
+ <replaceable>max</replaceable> inclusive is drawn with probability:
+ <literal>f(i + 0.5) - f(i - 0.5)</literal>.
+ Intuitively, the larger the <replaceable>parameter</replaceable>, the more
+ frequently values close to the middle of the interval are drawn, and the
+ less frequently values close to the <replaceable>min</replaceable> and
+ <replaceable>max</replaceable> bounds. About 67% of values are drawn from the
+ middle <literal>1.0 / parameter</literal>, that is a relative
+ <literal>0.5 / parameter</literal> around the mean, and 95% in the middle
+ <literal>2.0 / parameter</literal>, that is a relative
+ <literal>1.0 / parameter</literal> around the mean; for instance, if
+ <replaceable>parameter</replaceable> is 4.0, 67% of values are drawn from the
+ middle quarter (1.0 / 4.0) of the interval (i.e., from
+ <literal>3.0 / 8.0</literal> to <literal>5.0 / 8.0</literal>) and 95% from
+ the middle half (<literal>2.0 / 4.0</literal>) of the interval (second and third
+ quartiles). The minimum allowed <replaceable>parameter</replaceable>
+ value is 2.0.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>random_zipfian</literal> generates a bounded Zipfian
+ distribution.
+ <replaceable>parameter</replaceable> defines how skewed the distribution
+ is. The larger the <replaceable>parameter</replaceable>, the more
+ frequently values closer to the beginning of the interval are drawn.
+ The distribution is such that, assuming the range starts from 1,
+ the ratio of the probability of drawing <replaceable>k</replaceable>
+ versus drawing <replaceable>k+1</replaceable> is
+ <literal>((<replaceable>k</replaceable>+1)/<replaceable>k</replaceable>)**<replaceable>parameter</replaceable></literal>.
+ For example, <literal>random_zipfian(1, ..., 2.5)</literal> produces
+ the value <literal>1</literal> about <literal>(2/1)**2.5 =
+ 5.66</literal> times more frequently than <literal>2</literal>, which
+ itself is produced <literal>(3/2)**2.5 = 2.76</literal> times more
+ frequently than <literal>3</literal>, and so on.
+ </para>
+ <para>
+ <application>pgbench</application>'s implementation is based on
+ "Non-Uniform Random Variate Generation", Luc Devroye, p. 550-551,
+ Springer 1986. Due to limitations of that algorithm,
+ the <replaceable>parameter</replaceable> value is restricted to
+ the range [1.001, 1000].
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <note>
+ <para>
+ When designing a benchmark which selects rows non-uniformly, be aware
+ that the rows chosen may be correlated with other data such as IDs from
+ a sequence or the physical row ordering, which may skew performance
+ measurements.
+ </para>
+ <para>
+ To avoid this, you may wish to use the <function>permute</function>
+ function, or some other additional step with similar effect, to shuffle
+ the selected rows and remove such correlations.
+ </para>
+ </note>
+
+ <para>
+ Hash functions <literal>hash</literal>, <literal>hash_murmur2</literal> and
+ <literal>hash_fnv1a</literal> accept an input value and an optional seed parameter.
+ In case the seed isn't provided the value of <literal>:default_seed</literal>
+ is used, which is initialized randomly unless set by the command-line
+ <literal>-D</literal> option.
+ </para>
+
+ <para>
+ <literal>permute</literal> accepts an input value, a size, and an optional
+ seed parameter. It generates a pseudorandom permutation of integers in
+ the range <literal>[0, size)</literal>, and returns the index of the input
+ value in the permuted values. The permutation chosen is parameterized by
+ the seed, which defaults to <literal>:default_seed</literal>, if not
+ specified. Unlike the hash functions, <literal>permute</literal> ensures
+ that there are no collisions or holes in the output values. Input values
+ outside the interval are interpreted modulo the size. The function raises
+ an error if the size is not positive. <function>permute</function> can be
+ used to scatter the distribution of non-uniform random functions such as
+ <literal>random_zipfian</literal> or <literal>random_exponential</literal>
+ so that values drawn more often are not trivially correlated. For
+ instance, the following <application>pgbench</application> script
+ simulates a possible real world workload typical for social media and
+ blogging platforms where a few accounts generate excessive load:
+
+<programlisting>
+\set size 1000000
+\set r random_zipfian(1, :size, 1.07)
+\set k 1 + permute(:r, :size)
+</programlisting>
+
+ In some cases several distinct distributions are needed which don't correlate
+ with each other and this is when the optional seed parameter comes in handy:
+
+<programlisting>
+\set k1 1 + permute(:r, :size, :default_seed + 123)
+\set k2 1 + permute(:r, :size, :default_seed + 321)
+</programlisting>
+
+ A similar behavior can also be approximated with <function>hash</function>:
+
+<programlisting>
+\set size 1000000
+\set r random_zipfian(1, 100 * :size, 1.07)
+\set k 1 + abs(hash(:r)) % :size
+</programlisting>
+
+ However, since <function>hash</function> generates collisions, some values
+ will not be reachable and others will be more frequent than expected from
+ the original distribution.
+ </para>
+
+ <para>
+ As an example, the full definition of the built-in TPC-B-like
+ transaction is:
+
+<programlisting>
+\set aid random(1, 100000 * :scale)
+\set bid random(1, 1 * :scale)
+\set tid random(1, 10 * :scale)
+\set delta random(-5000, 5000)
+BEGIN;
+UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+END;
+</programlisting>
+
+ This script allows each iteration of the transaction to reference
+ different, randomly-chosen rows. (This example also shows why it's
+ important for each client session to have its own variables &mdash;
+ otherwise they'd not be independently touching different rows.)
+ </para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Per-Transaction Logging</title>
+
+ <para>
+ With the <option>-l</option> option (but without
+ the <option>--aggregate-interval</option> option),
+ <application>pgbench</application> writes information about each transaction
+ to a log file. The log file will be named
+ <filename><replaceable>prefix</replaceable>.<replaceable>nnn</replaceable></filename>,
+ where <replaceable>prefix</replaceable> defaults to <literal>pgbench_log</literal>, and
+ <replaceable>nnn</replaceable> is the PID of the
+ <application>pgbench</application> process.
+ The prefix can be changed by using the <option>--log-prefix</option> option.
+ If the <option>-j</option> option is 2 or higher, so that there are multiple
+ worker threads, each will have its own log file. The first worker will
+ use the same name for its log file as in the standard single worker case.
+ The additional log files for the other workers will be named
+ <filename><replaceable>prefix</replaceable>.<replaceable>nnn</replaceable>.<replaceable>mmm</replaceable></filename>,
+ where <replaceable>mmm</replaceable> is a sequential number for each worker starting
+ with 1.
+ </para>
+
+ <para>
+ Each line in a log file describes one transaction.
+ It contains the following space-separated fields:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>client_id</replaceable></term>
+ <listitem>
+ <para>
+ identifies the client session that ran the transaction
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>transaction_no</replaceable></term>
+ <listitem>
+ <para>
+ counts how many transactions have been run by that session
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>time</replaceable></term>
+ <listitem>
+ <para>
+ transaction's elapsed time, in microseconds
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>script_no</replaceable></term>
+ <listitem>
+ <para>
+ identifies the script file that was used for the transaction
+ (useful when multiple scripts are specified
+ with <option>-f</option> or <option>-b</option>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>time_epoch</replaceable></term>
+ <listitem>
+ <para>
+ transaction's completion time, as a Unix-epoch time stamp
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>time_us</replaceable></term>
+ <listitem>
+ <para>
+ fractional-second part of transaction's completion time, in
+ microseconds
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>schedule_lag</replaceable></term>
+ <listitem>
+ <para>
+ transaction start delay, that is the difference between the
+ transaction's scheduled start time and the time it actually
+ started, in microseconds
+ (present only if <option>--rate</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>retries</replaceable></term>
+ <listitem>
+ <para>
+ count of retries after serialization or deadlock errors during the
+ transaction
+ (present only if <option>--max-tries</option> is not equal to one)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ When both <option>--rate</option> and <option>--latency-limit</option> are used,
+ the <replaceable>time</replaceable> for a skipped transaction will be reported as
+ <literal>skipped</literal>.
+ If the transaction ends with a failure, its <replaceable>time</replaceable>
+ will be reported as <literal>failed</literal>. If you use the
+ <option>--failures-detailed</option> option, the
+ <replaceable>time</replaceable> of the failed transaction will be reported as
+ <literal>serialization</literal> or
+ <literal>deadlock</literal> depending on the type of failure (see
+ <xref linkend="failures-and-retries"/> for more information).
+ </para>
+
+ <para>
+ Here is a snippet of a log file generated in a single-client run:
+<screen>
+0 199 2241 0 1175850568 995598
+0 200 2465 0 1175850568 998079
+0 201 2513 0 1175850569 608
+0 202 2038 0 1175850569 2663
+</screen>
+
+ Another example with <literal>--rate=100</literal>
+ and <literal>--latency-limit=5</literal> (note the additional
+ <replaceable>schedule_lag</replaceable> column):
+<screen>
+0 81 4621 0 1412881037 912698 3005
+0 82 6173 0 1412881037 914578 4304
+0 83 skipped 0 1412881037 914578 5217
+0 83 skipped 0 1412881037 914578 5099
+0 83 4722 0 1412881037 916203 3108
+0 84 4142 0 1412881037 918023 2333
+0 85 2465 0 1412881037 919759 740
+</screen>
+ In this example, transaction 82 was late, because its latency (6.173 ms) was
+ over the 5 ms limit. The next two transactions were skipped, because they
+ were already late before they were even started.
+ </para>
+
+ <para>
+ The following example shows a snippet of a log file with failures and
+ retries, with the maximum number of tries set to 10 (note the additional
+ <replaceable>retries</replaceable> column):
+<screen>
+3 0 47423 0 1499414498 34501 3
+3 1 8333 0 1499414498 42848 0
+3 2 8358 0 1499414498 51219 0
+4 0 72345 0 1499414498 59433 6
+1 3 41718 0 1499414498 67879 4
+1 4 8416 0 1499414498 76311 0
+3 3 33235 0 1499414498 84469 3
+0 0 failed 0 1499414498 84905 9
+2 0 failed 0 1499414498 86248 9
+3 4 8307 0 1499414498 92788 0
+</screen>
+ </para>
+
+ <para>
+ If the <option>--failures-detailed</option> option is used, the type of
+ failure is reported in the <replaceable>time</replaceable> like this:
+<screen>
+3 0 47423 0 1499414498 34501 3
+3 1 8333 0 1499414498 42848 0
+3 2 8358 0 1499414498 51219 0
+4 0 72345 0 1499414498 59433 6
+1 3 41718 0 1499414498 67879 4
+1 4 8416 0 1499414498 76311 0
+3 3 33235 0 1499414498 84469 3
+0 0 serialization 0 1499414498 84905 9
+2 0 serialization 0 1499414498 86248 9
+3 4 8307 0 1499414498 92788 0
+</screen>
+ </para>
+
+ <para>
+ When running a long test on hardware that can handle a lot of transactions,
+ the log files can become very large. The <option>--sampling-rate</option> option
+ can be used to log only a random sample of transactions.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Aggregated Logging</title>
+
+ <para>
+ With the <option>--aggregate-interval</option> option, a different
+ format is used for the log files. Each log line describes one
+ aggregation interval. It contains the following space-separated
+ fields:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>interval_start</replaceable></term>
+ <listitem>
+ <para>
+ start time of the interval, as a Unix-epoch time stamp
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>num_transactions</replaceable></term>
+ <listitem>
+ <para>
+ number of transactions within the interval
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>sum_latency</replaceable></term>
+ <listitem>
+ <para>
+ sum of transaction latencies
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>sum_latency_2</replaceable></term>
+ <listitem>
+ <para>
+ sum of squares of transaction latencies
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>min_latency</replaceable></term>
+ <listitem>
+ <para>
+ minimum transaction latency
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>max_latency</replaceable></term>
+ <listitem>
+ <para>
+ maximum transaction latency
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>sum_lag</replaceable></term>
+ <listitem>
+ <para>
+ sum of transaction start delays
+ (zero unless <option>--rate</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>sum_lag_2</replaceable></term>
+ <listitem>
+ <para>
+ sum of squares of transaction start delays
+ (zero unless <option>--rate</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>min_lag</replaceable></term>
+ <listitem>
+ <para>
+ minimum transaction start delay
+ (zero unless <option>--rate</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>max_lag</replaceable></term>
+ <listitem>
+ <para>
+ maximum transaction start delay
+ (zero unless <option>--rate</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>skipped</replaceable></term>
+ <listitem>
+ <para>
+ number of transactions skipped because they would have started too late
+ (zero unless <option>--rate</option>
+ and <option>--latency-limit</option> are specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>retried</replaceable></term>
+ <listitem>
+ <para>
+ number of retried transactions
+ (zero unless <option>--max-tries</option> is not equal to one)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>retries</replaceable></term>
+ <listitem>
+ <para>
+ number of retries after serialization or deadlock errors
+ (zero unless <option>--max-tries</option> is not equal to one)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>serialization_failures</replaceable></term>
+ <listitem>
+ <para>
+ number of transactions that got a serialization error and were not
+ retried afterwards
+ (zero unless <option>--failures-detailed</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>deadlock_failures</replaceable></term>
+ <listitem>
+ <para>
+ number of transactions that got a deadlock error and were not
+ retried afterwards
+ (zero unless <option>--failures-detailed</option> is specified)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Here is some example output generated with these options:
+<screen>
+<userinput>pgbench --aggregate-interval=10 --time=20 --client=10 --log --rate=1000 --latency-limit=10 --failures-detailed --max-tries=10 test</userinput>
+
+1650260552 5178 26171317 177284491527 1136 44462 2647617 7321113867 0 9866 64 7564 28340 4148 0
+1650260562 4808 25573984 220121792172 1171 62083 3037380 9666800914 0 9998 598 7392 26621 4527 0
+</screen>
+ </para>
+
+ <para>
+ Notice that while the plain (unaggregated) log format shows which script
+ was used for each transaction, the aggregated format does not. Therefore if
+ you need per-script data, you need to aggregate the data on your own.
+ </para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Per-Statement Report</title>
+
+ <para>
+ With the <option>-r</option> option, <application>pgbench</application>
+ collects the following statistics for each statement:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>latency</literal> &mdash; elapsed transaction time for each
+ statement. <application>pgbench</application> reports an average value
+ of all successful runs of the statement.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The number of failures in this statement. See
+ <xref linkend="failures-and-retries"/> for more information.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The number of retries after a serialization or a deadlock error in this
+ statement. See <xref linkend="failures-and-retries"/> for more information.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The report displays retry statistics only if the <option>--max-tries</option>
+ option is not equal to 1.
+ </para>
+
+ <para>
+ All values are computed for each statement executed by every client and are
+ reported after the benchmark has finished.
+ </para>
+
+ <para>
+ For the default script, the output will look similar to this:
+<screen>
+starting vacuum...end.
+transaction type: &lt;builtin: TPC-B (sort of)&gt;
+scaling factor: 1
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 1
+number of transactions per client: 1000
+number of transactions actually processed: 10000/10000
+number of failed transactions: 0 (0.000%)
+number of transactions above the 50.0 ms latency limit: 1311/10000 (13.110 %)
+latency average = 28.488 ms
+latency stddev = 21.009 ms
+initial connection time = 69.068 ms
+tps = 346.224794 (without initial connection time)
+statement latencies in milliseconds and failures:
+ 0.012 0 \set aid random(1, 100000 * :scale)
+ 0.002 0 \set bid random(1, 1 * :scale)
+ 0.002 0 \set tid random(1, 10 * :scale)
+ 0.002 0 \set delta random(-5000, 5000)
+ 0.319 0 BEGIN;
+ 0.834 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+ 0.641 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+ 11.126 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+ 12.961 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+ 0.634 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+ 1.957 0 END;
+</screen>
+
+ Another example of output for the default script using serializable default
+ transaction isolation level (<command>PGOPTIONS='-c
+ default_transaction_isolation=serializable' pgbench ...</command>):
+<screen>
+starting vacuum...end.
+transaction type: &lt;builtin: TPC-B (sort of)&gt;
+scaling factor: 1
+query mode: simple
+number of clients: 10
+number of threads: 1
+maximum number of tries: 10
+number of transactions per client: 1000
+number of transactions actually processed: 6317/10000
+number of failed transactions: 3683 (36.830%)
+number of transactions retried: 7667 (76.670%)
+total number of retries: 45339
+number of transactions above the 50.0 ms latency limit: 106/6317 (1.678 %)
+latency average = 17.016 ms
+latency stddev = 13.283 ms
+initial connection time = 45.017 ms
+tps = 186.792667 (without initial connection time)
+statement latencies in milliseconds, failures and retries:
+ 0.006 0 0 \set aid random(1, 100000 * :scale)
+ 0.001 0 0 \set bid random(1, 1 * :scale)
+ 0.001 0 0 \set tid random(1, 10 * :scale)
+ 0.001 0 0 \set delta random(-5000, 5000)
+ 0.385 0 0 BEGIN;
+ 0.773 0 1 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
+ 0.624 0 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
+ 1.098 320 3762 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
+ 0.582 3363 41576 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
+ 0.465 0 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
+ 1.933 0 0 END;
+</screen></para>
+
+ <para>
+ If multiple script files are specified, all statistics are reported
+ separately for each script file.
+ </para>
+
+ <para>
+ Note that collecting the additional timing information needed for
+ per-statement latency computation adds some overhead. This will slow
+ average execution speed and lower the computed TPS. The amount
+ of slowdown varies significantly depending on platform and hardware.
+ Comparing average TPS values with and without latency reporting enabled
+ is a good way to measure if the timing overhead is significant.
+ </para>
+ </refsect2>
+
+ <refsect2 id="failures-and-retries" xreflabel="Failures and Serialization/Deadlock Retries">
+ <title>Failures and Serialization/Deadlock Retries</title>
+
+ <para>
+ When executing <application>pgbench</application>, there are three main types
+ of errors:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Errors of the main program. They are the most serious and always result
+ in an immediate exit from <application>pgbench</application> with the
+ corresponding error message. They include:
+ <itemizedlist>
+ <listitem>
+ <para>
+ errors at the beginning of <application>pgbench</application>
+ (e.g. an invalid option value);
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ errors in the initialization mode (e.g. the query to create
+ tables for built-in scripts fails);
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ errors before starting threads (e.g. could not connect to the
+ database server, syntax error in the meta command, thread
+ creation failure);
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ internal <application>pgbench</application> errors (which are
+ supposed to never occur...).
+ </para>
+ </listitem>
+ </itemizedlist></para>
+ </listitem>
+ <listitem>
+ <para>
+ Errors when the thread manages its clients (e.g. the client could not
+ start a connection to the database server / the socket for connecting
+ the client to the database server has become invalid). In such cases
+ all clients of this thread stop while other threads continue to work.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Direct client errors. They lead to immediate exit from
+ <application>pgbench</application> with the corresponding error message
+ only in the case of an internal <application>pgbench</application>
+ error (which are supposed to never occur...). Otherwise in the worst
+ case they only lead to the abortion of the failed client while other
+ clients continue their run (but some client errors are handled without
+ an abortion of the client and reported separately, see below). Later in
+ this section it is assumed that the discussed errors are only the
+ direct client errors and they are not internal
+ <application>pgbench</application> errors.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ A client's run is aborted in case of a serious error; for example, the
+ connection with the database server was lost or the end of script was reached
+ without completing the last transaction. In addition, if execution of an SQL
+ or meta command fails for reasons other than serialization or deadlock errors,
+ the client is aborted. Otherwise, if an SQL command fails with serialization or
+ deadlock errors, the client is not aborted. In such cases, the current
+ transaction is rolled back, which also includes setting the client variables
+ as they were before the run of this transaction (it is assumed that one
+ transaction script contains only one transaction; see
+ <xref linkend="transactions-and-scripts"/> for more information).
+ Transactions with serialization or deadlock errors are repeated after
+ rollbacks until they complete successfully or reach the maximum
+ number of tries (specified by the <option>--max-tries</option> option) / the maximum
+ time of retries (specified by the <option>--latency-limit</option> option) / the end
+ of benchmark (specified by the <option>--time</option> option). If
+ the last trial run fails, this transaction will be reported as failed but
+ the client is not aborted and continues to work.
+ </para>
+
+ <note>
+ <para>
+ Without specifying the <option>--max-tries</option> option, a transaction will
+ never be retried after a serialization or deadlock error because its default
+ value is 1. Use an unlimited number of tries (<literal>--max-tries=0</literal>)
+ and the <option>--latency-limit</option> option to limit only the maximum time
+ of tries. You can also use the <option>--time</option> option to limit the
+ benchmark duration under an unlimited number of tries.
+ </para>
+ <para>
+ Be careful when repeating scripts that contain multiple transactions: the
+ script is always retried completely, so successful transactions can be
+ performed several times.
+ </para>
+ <para>
+ Be careful when repeating transactions with shell commands. Unlike the
+ results of SQL commands, the results of shell commands are not rolled back,
+ except for the variable value of the <command>\setshell</command> command.
+ </para>
+ </note>
+
+ <para>
+ The latency of a successful transaction includes the entire time of
+ transaction execution with rollbacks and retries. The latency is measured
+ only for successful transactions and commands but not for failed transactions
+ or commands.
+ </para>
+
+ <para>
+ The main report contains the number of failed transactions. If the
+ <option>--max-tries</option> option is not equal to 1, the main report also
+ contains statistics related to retries: the total number of retried
+ transactions and total number of retries. The per-script report inherits all
+ these fields from the main report. The per-statement report displays retry
+ statistics only if the <option>--max-tries</option> option is not equal to 1.
+ </para>
+
+ <para>
+ If you want to group failures by basic types in per-transaction and
+ aggregation logs, as well as in the main and per-script reports, use the
+ <option>--failures-detailed</option> option. If you also want to distinguish
+ all errors and failures (errors without retrying) by type including which
+ limit for retries was exceeded and how much it was exceeded by for the
+ serialization/deadlock failures, use the <option>--verbose-errors</option>
+ option.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Good Practices</title>
+
+ <para>
+ It is very easy to use <application>pgbench</application> to produce completely
+ meaningless numbers. Here are some guidelines to help you get useful
+ results.
+ </para>
+
+ <para>
+ In the first place, <emphasis>never</emphasis> believe any test that runs
+ for only a few seconds. Use the <option>-t</option> or <option>-T</option> option
+ to make the run last at least a few minutes, so as to average out noise.
+ In some cases you could need hours to get numbers that are reproducible.
+ It's a good idea to try the test run a few times, to find out if your
+ numbers are reproducible or not.
+ </para>
+
+ <para>
+ For the default TPC-B-like test scenario, the initialization scale factor
+ (<option>-s</option>) should be at least as large as the largest number of
+ clients you intend to test (<option>-c</option>); else you'll mostly be
+ measuring update contention. There are only <option>-s</option> rows in
+ the <structname>pgbench_branches</structname> table, and every transaction wants to
+ update one of them, so <option>-c</option> values in excess of <option>-s</option>
+ will undoubtedly result in lots of transactions blocked waiting for
+ other transactions.
+ </para>
+
+ <para>
+ The default test scenario is also quite sensitive to how long it's been
+ since the tables were initialized: accumulation of dead rows and dead space
+ in the tables changes the results. To understand the results you must keep
+ track of the total number of updates and when vacuuming happens. If
+ autovacuum is enabled it can result in unpredictable changes in measured
+ performance.
+ </para>
+
+ <para>
+ A limitation of <application>pgbench</application> is that it can itself become
+ the bottleneck when trying to test a large number of client sessions.
+ This can be alleviated by running <application>pgbench</application> on a different
+ machine from the database server, although low network latency will be
+ essential. It might even be useful to run several <application>pgbench</application>
+ instances concurrently, on several client machines, against the same
+ database server.
+ </para>
+ </refsect2>
+ <refsect2>
+ <title>Security</title>
+
+ <para>
+ If untrusted users have access to a database that has not adopted a
+ <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
+ do not run <application>pgbench</application> in that
+ database. <application>pgbench</application> uses unqualified names and
+ does not manipulate the search path.
+ </para>
+ </refsect2>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pgtestfsync.sgml b/doc/src/sgml/ref/pgtestfsync.sgml
new file mode 100644
index 0000000..e811f80
--- /dev/null
+++ b/doc/src/sgml/ref/pgtestfsync.sgml
@@ -0,0 +1,127 @@
+<!--
+doc/src/sgml/ref/pgtestfsync.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="pgtestfsync">
+ <indexterm zone="pgtestfsync">
+ <primary>pg_test_fsync</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_test_fsync</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_test_fsync</refname>
+ <refpurpose>determine fastest <varname>wal_sync_method</varname> for <productname>PostgreSQL</productname></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_test_fsync</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>pg_test_fsync</application> is intended to give you a reasonable
+ idea of what the fastest <xref linkend="guc-wal-sync-method"/> is on your
+ specific system,
+ as well as supplying diagnostic information in the event of an identified I/O
+ problem. However, differences shown by
+ <application>pg_test_fsync</application> might not make any significant
+ difference in real database throughput, especially since many database servers
+ are not speed-limited by their write-ahead logs.
+ <application>pg_test_fsync</application> reports average file sync operation
+ time in microseconds for each <literal>wal_sync_method</literal>, which can also be used to
+ inform efforts to optimize the value of <xref linkend="guc-commit-delay"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>pg_test_fsync</application> accepts the following
+ command-line options:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+ <term><option>--filename</option></term>
+ <listitem>
+ <para>
+ Specifies the file name to write test data in.
+ This file should be in the same file system that the
+ <filename>pg_wal</filename> directory is or will be placed in.
+ (<filename>pg_wal</filename> contains the <acronym>WAL</acronym> files.)
+ The default is <filename>pg_test_fsync.out</filename> in the current
+ directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--secs-per-test</option></term>
+ <listitem>
+ <para>
+ Specifies the number of seconds for each test. The more time
+ per test, the greater the test's accuracy, but the longer it takes
+ to run. The default is 5 seconds, which allows the program to
+ complete in under 2 minutes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_test_fsync</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_test_fsync</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-postgres"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pgtesttiming.sgml b/doc/src/sgml/ref/pgtesttiming.sgml
new file mode 100644
index 0000000..a5eb3aa
--- /dev/null
+++ b/doc/src/sgml/ref/pgtesttiming.sgml
@@ -0,0 +1,303 @@
+<!--
+doc/src/sgml/ref/pgtesttiming.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="pgtesttiming">
+ <indexterm zone="pgtesttiming">
+ <primary>pg_test_timing</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_test_timing</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_test_timing</refname>
+ <refpurpose>measure timing overhead</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_test_timing</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>pg_test_timing</application> is a tool to measure the timing overhead
+ on your system and confirm that the system time never moves backwards.
+ Systems that are slow to collect timing data can give less accurate
+ <command>EXPLAIN ANALYZE</command> results.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>pg_test_timing</application> accepts the following
+ command-line options:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">duration</replaceable></option></term>
+ <term><option>--duration=<replaceable class="parameter">duration</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the test duration, in seconds. Longer durations
+ give slightly better accuracy, and are more likely to discover
+ problems with the system clock moving backwards. The default
+ test duration is 3 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>pg_test_timing</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>pg_test_timing</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Usage</title>
+
+ <refsect2>
+ <title>Interpreting Results</title>
+
+ <para>
+ Good results will show most (>90%) individual timing calls take less than
+ one microsecond. Average per loop overhead will be even lower, below 100
+ nanoseconds. This example from an Intel i7-860 system using a TSC clock
+ source shows excellent performance:
+
+<screen><![CDATA[
+Testing timing overhead for 3 seconds.
+Per loop time including overhead: 35.96 ns
+Histogram of timing durations:
+ < us % of total count
+ 1 96.40465 80435604
+ 2 3.59518 2999652
+ 4 0.00015 126
+ 8 0.00002 13
+ 16 0.00000 2
+]]></screen>
+ </para>
+
+ <para>
+ Note that different units are used for the per loop time than the
+ histogram. The loop can have resolution within a few nanoseconds (ns),
+ while the individual timing calls can only resolve down to one microsecond
+ (us).
+ </para>
+
+ </refsect2>
+ <refsect2>
+ <title>Measuring Executor Timing Overhead</title>
+
+ <para>
+ When the query executor is running a statement using
+ <command>EXPLAIN ANALYZE</command>, individual operations are timed as well
+ as showing a summary. The overhead of your system can be checked by
+ counting rows with the <application>psql</application> program:
+
+<screen>
+CREATE TABLE t AS SELECT * FROM generate_series(1,100000);
+\timing
+SELECT COUNT(*) FROM t;
+EXPLAIN ANALYZE SELECT COUNT(*) FROM t;
+</screen>
+ </para>
+
+ <para>
+ The i7-860 system measured runs the count query in 9.8 ms while
+ the <command>EXPLAIN ANALYZE</command> version takes 16.6 ms, each
+ processing just over 100,000 rows. That 6.8 ms difference means the timing
+ overhead per row is 68 ns, about twice what pg_test_timing estimated it
+ would be. Even that relatively small amount of overhead is making the fully
+ timed count statement take almost 70% longer. On more substantial queries,
+ the timing overhead would be less problematic.
+ </para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Changing Time Sources</title>
+ <para>
+ On some newer Linux systems, it's possible to change the clock source used
+ to collect timing data at any time. A second example shows the slowdown
+ possible from switching to the slower acpi_pm time source, on the same
+ system used for the fast results above:
+
+<screen><![CDATA[
+# cat /sys/devices/system/clocksource/clocksource0/available_clocksource
+tsc hpet acpi_pm
+# echo acpi_pm > /sys/devices/system/clocksource/clocksource0/current_clocksource
+# pg_test_timing
+Per loop time including overhead: 722.92 ns
+Histogram of timing durations:
+ < us % of total count
+ 1 27.84870 1155682
+ 2 72.05956 2990371
+ 4 0.07810 3241
+ 8 0.01357 563
+ 16 0.00007 3
+]]></screen>
+ </para>
+
+ <para>
+ In this configuration, the sample <command>EXPLAIN ANALYZE</command> above
+ takes 115.9 ms. That's 1061 ns of timing overhead, again a small multiple
+ of what's measured directly by this utility. That much timing overhead
+ means the actual query itself is only taking a tiny fraction of the
+ accounted for time, most of it is being consumed in overhead instead. In
+ this configuration, any <command>EXPLAIN ANALYZE</command> totals involving
+ many timed operations would be inflated significantly by timing overhead.
+ </para>
+
+ <para>
+ FreeBSD also allows changing the time source on the fly, and it logs
+ information about the timer selected during boot:
+
+<screen>
+# dmesg | grep "Timecounter"
+Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
+Timecounter "i8254" frequency 1193182 Hz quality 0
+Timecounters tick every 10.000 msec
+Timecounter "TSC" frequency 2531787134 Hz quality 800
+# sysctl kern.timecounter.hardware=TSC
+kern.timecounter.hardware: ACPI-fast -> TSC
+</screen>
+ </para>
+
+ <para>
+ Other systems may only allow setting the time source on boot. On older
+ Linux systems the "clock" kernel setting is the only way to make this sort
+ of change. And even on some more recent ones, the only option you'll see
+ for a clock source is "jiffies". Jiffies are the older Linux software clock
+ implementation, which can have good resolution when it's backed by fast
+ enough timing hardware, as in this example:
+
+<screen><![CDATA[
+$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
+jiffies
+$ dmesg | grep time.c
+time.c: Using 3.579545 MHz WALL PM GTOD PIT/TSC timer.
+time.c: Detected 2400.153 MHz processor.
+$ pg_test_timing
+Testing timing overhead for 3 seconds.
+Per timing duration including loop overhead: 97.75 ns
+Histogram of timing durations:
+ < us % of total count
+ 1 90.23734 27694571
+ 2 9.75277 2993204
+ 4 0.00981 3010
+ 8 0.00007 22
+ 16 0.00000 1
+ 32 0.00000 1
+]]></screen></para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Clock Hardware and Timing Accuracy</title>
+
+ <para>
+ Collecting accurate timing information is normally done on computers using
+ hardware clocks with various levels of accuracy. With some hardware the
+ operating systems can pass the system clock time almost directly to
+ programs. A system clock can also be derived from a chip that simply
+ provides timing interrupts, periodic ticks at some known time interval. In
+ either case, operating system kernels provide a clock source that hides
+ these details. But the accuracy of that clock source and how quickly it can
+ return results varies based on the underlying hardware.
+ </para>
+
+ <para>
+ Inaccurate time keeping can result in system instability. Test any change
+ to the clock source very carefully. Operating system defaults are sometimes
+ made to favor reliability over best accuracy. And if you are using a virtual
+ machine, look into the recommended time sources compatible with it. Virtual
+ hardware faces additional difficulties when emulating timers, and there are
+ often per operating system settings suggested by vendors.
+ </para>
+
+ <para>
+ The Time Stamp Counter (TSC) clock source is the most accurate one available
+ on current generation CPUs. It's the preferred way to track the system time
+ when it's supported by the operating system and the TSC clock is
+ reliable. There are several ways that TSC can fail to provide an accurate
+ timing source, making it unreliable. Older systems can have a TSC clock that
+ varies based on the CPU temperature, making it unusable for timing. Trying
+ to use TSC on some older multicore CPUs can give a reported time that's
+ inconsistent among multiple cores. This can result in the time going
+ backwards, a problem this program checks for. And even the newest systems
+ can fail to provide accurate TSC timing with very aggressive power saving
+ configurations.
+ </para>
+
+ <para>
+ Newer operating systems may check for the known TSC problems and switch to a
+ slower, more stable clock source when they are seen. If your system
+ supports TSC time but doesn't default to that, it may be disabled for a good
+ reason. And some operating systems may not detect all the possible problems
+ correctly, or will allow using TSC even in situations where it's known to be
+ inaccurate.
+ </para>
+
+ <para>
+ The High Precision Event Timer (HPET) is the preferred timer on systems
+ where it's available and TSC is not accurate. The timer chip itself is
+ programmable to allow up to 100 nanosecond resolution, but you may not see
+ that much accuracy in your system clock.
+ </para>
+
+ <para>
+ Advanced Configuration and Power Interface (ACPI) provides a Power
+ Management (PM) Timer, which Linux refers to as the acpi_pm. The clock
+ derived from acpi_pm will at best provide 300 nanosecond resolution.
+ </para>
+
+ <para>
+ Timers used on older PC hardware include the 8254 Programmable Interval
+ Timer (PIT), the real-time clock (RTC), the Advanced Programmable Interrupt
+ Controller (APIC) timer, and the Cyclone timer. These timers aim for
+ millisecond resolution.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-explain"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml
new file mode 100644
index 0000000..8f7a302
--- /dev/null
+++ b/doc/src/sgml/ref/pgupgrade.sgml
@@ -0,0 +1,857 @@
+<!--
+doc/src/sgml/ref/pgupgrade.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="pgupgrade">
+ <indexterm zone="pgupgrade">
+ <primary>pg_upgrade</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>pg_upgrade</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pg_upgrade</refname>
+ <refpurpose>upgrade a <productname>PostgreSQL</productname> server instance</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>pg_upgrade</command>
+ <arg choice="plain"><option>-b</option></arg>
+ <arg choice="plain"><replaceable>oldbindir</replaceable></arg>
+ <arg choice="opt"><option>-B</option> <replaceable>newbindir</replaceable></arg>
+ <arg choice="plain"><option>-d</option></arg>
+ <arg choice="plain"><replaceable>oldconfigdir</replaceable></arg>
+ <arg choice="plain"><option>-D</option></arg>
+ <arg choice="plain"><replaceable>newconfigdir</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>pg_upgrade</application> (formerly called <application>pg_migrator</application>) allows data
+ stored in <productname>PostgreSQL</productname> data files to be upgraded to a later <productname>PostgreSQL</productname>
+ major version without the data dump/restore typically required for
+ major version upgrades, e.g., from 9.5.8 to 9.6.4 or from 10.7 to 11.2.
+ It is not required for minor version upgrades, e.g., from 9.6.2 to 9.6.3
+ or from 10.1 to 10.2.
+ </para>
+
+ <para>
+ Major PostgreSQL releases regularly add new features that often
+ change the layout of the system tables, but the internal data storage
+ format rarely changes. <application>pg_upgrade</application> uses this fact
+ to perform rapid upgrades by creating new system tables and simply
+ reusing the old user data files. If a future major release ever
+ changes the data storage format in a way that makes the old data
+ format unreadable, <application>pg_upgrade</application> will not be usable
+ for such upgrades. (The community will attempt to avoid such
+ situations.)
+ </para>
+
+ <para>
+ <application>pg_upgrade</application> does its best to
+ make sure the old and new clusters are binary-compatible, e.g., by
+ checking for compatible compile-time settings, including 32/64-bit
+ binaries. It is important that
+ any external modules are also binary compatible, though this cannot
+ be checked by <application>pg_upgrade</application>.
+ </para>
+
+ <para>
+ pg_upgrade supports upgrades from 9.2.X and later to the current
+ major release of <productname>PostgreSQL</productname>, including snapshot and beta releases.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>pg_upgrade</application> accepts the following command-line arguments:
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>-b</option> <replaceable>bindir</replaceable></term>
+ <term><option>--old-bindir=</option><replaceable>bindir</replaceable></term>
+ <listitem><para>the old PostgreSQL executable directory;
+ environment variable <envar>PGBINOLD</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-B</option> <replaceable>bindir</replaceable></term>
+ <term><option>--new-bindir=</option><replaceable>bindir</replaceable></term>
+ <listitem><para>the new PostgreSQL executable directory;
+ default is the directory where <application>pg_upgrade</application> resides;
+ environment variable <envar>PGBINNEW</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c</option></term>
+ <term><option>--check</option></term>
+ <listitem><para>check clusters only, don't change any data</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d</option> <replaceable>configdir</replaceable></term>
+ <term><option>--old-datadir=</option><replaceable>configdir</replaceable></term>
+ <listitem><para>the old database cluster configuration directory; environment
+ variable <envar>PGDATAOLD</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D</option> <replaceable>configdir</replaceable></term>
+ <term><option>--new-datadir=</option><replaceable>configdir</replaceable></term>
+ <listitem><para>the new database cluster configuration directory; environment
+ variable <envar>PGDATANEW</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j <replaceable class="parameter">njobs</replaceable></option></term>
+ <term><option>--jobs=<replaceable class="parameter">njobs</replaceable></option></term>
+ <listitem><para>number of simultaneous processes or threads to use
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-k</option></term>
+ <term><option>--link</option></term>
+ <listitem><para>use hard links instead of copying files to the new
+ cluster</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N</option></term>
+ <term><option>--no-sync</option></term>
+ <listitem>
+ <para>
+ By default, <command>pg_upgrade</command> will wait for all files
+ of the upgraded cluster to be written safely to disk. This option
+ causes <command>pg_upgrade</command> to return without waiting, which
+ is faster, but means that a subsequent operating system crash can leave
+ the data directory corrupt. Generally, this option is
+ useful for testing but should not be used on a production
+ installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o</option> <replaceable class="parameter">options</replaceable></term>
+ <term><option>--old-options</option> <replaceable class="parameter">options</replaceable></term>
+ <listitem><para>options to be passed directly to the
+ old <command>postgres</command> command; multiple
+ option invocations are appended</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option> <replaceable class="parameter">options</replaceable></term>
+ <term><option>--new-options</option> <replaceable class="parameter">options</replaceable></term>
+ <listitem><para>options to be passed directly to the
+ new <command>postgres</command> command; multiple
+ option invocations are appended</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p</option> <replaceable>port</replaceable></term>
+ <term><option>--old-port=</option><replaceable>port</replaceable></term>
+ <listitem><para>the old cluster port number; environment
+ variable <envar>PGPORTOLD</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option> <replaceable>port</replaceable></term>
+ <term><option>--new-port=</option><replaceable>port</replaceable></term>
+ <listitem><para>the new cluster port number; environment
+ variable <envar>PGPORTNEW</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option></term>
+ <term><option>--retain</option></term>
+ <listitem><para>retain SQL and log files even after successful completion
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option> <replaceable>dir</replaceable></term>
+ <term><option>--socketdir=</option><replaceable>dir</replaceable></term>
+ <listitem><para>directory to use for postmaster sockets during upgrade;
+ default is current working directory; environment
+ variable <envar>PGSOCKETDIR</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U</option> <replaceable>username</replaceable></term>
+ <term><option>--username=</option><replaceable>username</replaceable></term>
+ <listitem><para>cluster's install user name; environment
+ variable <envar>PGUSER</envar></para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem><para>enable verbose internal logging</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem><para>display version information, then exit</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--clone</option></term>
+ <listitem>
+ <para>
+ Use efficient file cloning (also known as <quote>reflinks</quote> on
+ some systems) instead of copying files to the new cluster. This can
+ result in near-instantaneous copying of the data files, giving the
+ speed advantages of <option>-k</option>/<option>--link</option> while
+ leaving the old cluster untouched.
+ </para>
+
+ <para>
+ File cloning is only supported on some operating systems and file
+ systems. If it is selected but not supported, the
+ <application>pg_upgrade</application> run will error. At present, it
+ is supported on Linux (kernel 4.5 or later) with Btrfs and XFS (on
+ file systems created with reflink support), and on macOS with APFS.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem><para>show help, then exit</para></listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Usage</title>
+
+ <para>
+ These are the steps to perform an upgrade
+ with <application>pg_upgrade</application>:
+ </para>
+
+ <procedure>
+ <step performance="optional">
+ <title>Optionally move the old cluster</title>
+
+ <para>
+ If you are using a version-specific installation directory, e.g.,
+ <filename>/opt/PostgreSQL/&majorversion;</filename>, you do not need to move the old cluster. The
+ graphical installers all use version-specific installation directories.
+ </para>
+
+ <para>
+ If your installation directory is not version-specific, e.g.,
+ <filename>/usr/local/pgsql</filename>, it is necessary to move the current PostgreSQL install
+ directory so it does not interfere with the new <productname>PostgreSQL</productname> installation.
+ Once the current <productname>PostgreSQL</productname> server is shut down, it is safe to rename the
+ PostgreSQL installation directory; assuming the old directory is
+ <filename>/usr/local/pgsql</filename>, you can do:
+
+<programlisting>
+mv /usr/local/pgsql /usr/local/pgsql.old
+</programlisting>
+ to rename the directory.
+ </para>
+ </step>
+
+ <step>
+ <title>For source installs, build the new version</title>
+
+ <para>
+ Build the new PostgreSQL source with <command>configure</command> flags that are compatible
+ with the old cluster. <application>pg_upgrade</application> will check <command>pg_controldata</command> to make
+ sure all settings are compatible before starting the upgrade.
+ </para>
+ </step>
+
+ <step>
+ <title>Install the new PostgreSQL binaries</title>
+
+ <para>
+ Install the new server's binaries and support
+ files. <application>pg_upgrade</application> is included in a default installation.
+ </para>
+
+ <para>
+ For source installs, if you wish to install the new server in a custom
+ location, use the <literal>prefix</literal> variable:
+
+<programlisting>
+make prefix=/usr/local/pgsql.new install
+</programlisting></para>
+ </step>
+
+ <step>
+ <title>Initialize the new PostgreSQL cluster</title>
+
+ <para>
+ Initialize the new cluster using <command>initdb</command>.
+ Again, use compatible <command>initdb</command>
+ flags that match the old cluster. Many
+ prebuilt installers do this step automatically. There is no need to
+ start the new cluster.
+ </para>
+ </step>
+
+ <step>
+ <title>Install extension shared object files</title>
+
+ <para>
+ Many extensions and custom modules, whether from
+ <filename>contrib</filename> or another source, use shared object
+ files (or DLLs), e.g., <filename>pgcrypto.so</filename>. If the old
+ cluster used these, shared object files matching the new server binary
+ must be installed in the new cluster, usually via operating system
+ commands. Do not load the schema definitions, e.g., <command>CREATE
+ EXTENSION pgcrypto</command>, because these will be duplicated from
+ the old cluster. If extension updates are available,
+ <application>pg_upgrade</application> will report this and create
+ a script that can be run later to update them.
+ </para>
+ </step>
+
+ <step>
+ <title>Copy custom full-text search files</title>
+
+ <para>
+ Copy any custom full text search files (dictionary, synonym,
+ thesaurus, stop words) from the old to the new cluster.
+ </para>
+ </step>
+
+ <step>
+ <title>Adjust authentication</title>
+
+ <para>
+ <command>pg_upgrade</command> will connect to the old and new servers several
+ times, so you might want to set authentication to <literal>peer</literal>
+ in <filename>pg_hba.conf</filename> or use a <filename>~/.pgpass</filename> file
+ (see <xref linkend="libpq-pgpass"/>).
+ </para>
+ </step>
+
+ <step>
+ <title>Stop both servers</title>
+
+ <para>
+ Make sure both database servers are stopped using, on Unix, e.g.:
+
+<programlisting>
+pg_ctl -D /opt/PostgreSQL/9.6 stop
+pg_ctl -D /opt/PostgreSQL/&majorversion; stop
+</programlisting>
+
+ or on Windows, using the proper service names:
+
+<programlisting>
+NET STOP postgresql-9.6
+NET STOP postgresql-&majorversion;
+</programlisting>
+ </para>
+
+ <para>
+ Streaming replication and log-shipping standby servers can
+ remain running until a later step.
+ </para>
+ </step>
+
+ <step>
+ <title>Prepare for standby server upgrades</title>
+
+ <para>
+ If you are upgrading standby servers using methods outlined in section <xref
+ linkend="pgupgrade-step-replicas"/>, verify that the old standby
+ servers are caught up by running <application>pg_controldata</application>
+ against the old primary and standby clusters. Verify that the
+ <quote>Latest checkpoint location</quote> values match in all clusters.
+ (There will be a mismatch if old standby servers were shut down
+ before the old primary or if the old standby servers are still running.)
+ Also, make sure <varname>wal_level</varname> is not set to
+ <literal>minimal</literal> in the <filename>postgresql.conf</filename> file on the
+ new primary cluster.
+ </para>
+ </step>
+
+ <step>
+ <title>Run <application>pg_upgrade</application></title>
+
+ <para>
+ Always run the <application>pg_upgrade</application> binary of the new server, not the old one.
+ <application>pg_upgrade</application> requires the specification of the old and new cluster's
+ data and executable (<filename>bin</filename>) directories. You can also specify
+ user and port values, and whether you want the data files linked or cloned
+ instead of the default copy behavior.
+ </para>
+
+ <para>
+ If you use link mode, the upgrade will be much faster (no file
+ copying) and use less disk space, but you will not be able to access
+ your old cluster
+ once you start the new cluster after the upgrade. Link mode also
+ requires that the old and new cluster data directories be in the
+ same file system. (Tablespaces and <filename>pg_wal</filename> can be on
+ different file systems.)
+ Clone mode provides the same speed and disk space advantages but
+ does not cause the old cluster to be unusable once the new cluster
+ is started. Clone mode also requires that the old and new data
+ directories be in the same file system. This mode is only available
+ on certain operating systems and file systems.
+ </para>
+
+ <para>
+ The <option>--jobs</option> option allows multiple CPU cores to be used
+ for copying/linking of files and to dump and restore database schemas
+ in parallel; a good place to start is the maximum of the number of
+ CPU cores and tablespaces. This option can dramatically reduce the
+ time to upgrade a multi-database server running on a multiprocessor
+ machine.
+ </para>
+
+ <para>
+ For Windows users, you must be logged into an administrative account, and
+ then start a shell as the <literal>postgres</literal> user and set the proper path:
+
+<programlisting>
+RUNAS /USER:postgres "CMD.EXE"
+SET PATH=%PATH%;C:\Program Files\PostgreSQL\&majorversion;\bin;
+</programlisting>
+
+ and then run <application>pg_upgrade</application> with quoted directories, e.g.:
+
+<programlisting>
+pg_upgrade.exe
+ --old-datadir "C:/Program Files/PostgreSQL/9.6/data"
+ --new-datadir "C:/Program Files/PostgreSQL/&majorversion;/data"
+ --old-bindir "C:/Program Files/PostgreSQL/9.6/bin"
+ --new-bindir "C:/Program Files/PostgreSQL/&majorversion;/bin"
+</programlisting>
+
+ Once started, <command>pg_upgrade</command> will verify the two clusters are compatible
+ and then do the upgrade. You can use <command>pg_upgrade --check</command>
+ to perform only the checks, even if the old server is still
+ running. <command>pg_upgrade --check</command> will also outline any
+ manual adjustments you will need to make after the upgrade. If you
+ are going to be using link or clone mode, you should use the option
+ <option>--link</option> or <option>--clone</option> with
+ <option>--check</option> to enable mode-specific checks.
+ <command>pg_upgrade</command> requires write permission in the current directory.
+ </para>
+
+ <para>
+ Obviously, no one should be accessing the clusters during the
+ upgrade. <application>pg_upgrade</application> defaults to running servers
+ on port 50432 to avoid unintended client connections.
+ You can use the same port number for both clusters when doing an
+ upgrade because the old and new clusters will not be running at the
+ same time. However, when checking an old running server, the old
+ and new port numbers must be different.
+ </para>
+
+ <para>
+ If an error occurs while restoring the database schema, <command>pg_upgrade</command> will
+ exit and you will have to revert to the old cluster as outlined in <xref linkend="pgupgrade-step-revert"/>
+ below. To try <command>pg_upgrade</command> again, you will need to modify the old
+ cluster so the pg_upgrade schema restore succeeds. If the problem is a
+ <filename>contrib</filename> module, you might need to uninstall the <filename>contrib</filename> module from
+ the old cluster and install it in the new cluster after the upgrade,
+ assuming the module is not being used to store user data.
+ </para>
+ </step>
+
+ <step id="pgupgrade-step-replicas">
+ <title>Upgrade streaming replication and log-shipping standby servers</title>
+
+ <para>
+ If you used link mode and have Streaming Replication (see <xref
+ linkend="streaming-replication"/>) or Log-Shipping (see <xref
+ linkend="warm-standby"/>) standby servers, you can follow these steps to
+ quickly upgrade them. You will not be running <application>pg_upgrade</application> on
+ the standby servers, but rather <application>rsync</application> on the primary.
+ Do not start any servers yet.
+ </para>
+
+ <para>
+ If you did <emphasis>not</emphasis> use link mode, do not have or do not
+ want to use <application>rsync</application>, or want an easier solution, skip
+ the instructions in this section and simply recreate the standby
+ servers once <application>pg_upgrade</application> completes and the new primary
+ is running.
+ </para>
+
+ <procedure>
+
+ <step>
+ <title>Install the new PostgreSQL binaries on standby servers</title>
+
+ <para>
+ Make sure the new binaries and support files are installed on all
+ standby servers.
+ </para>
+ </step>
+
+ <step>
+ <title>Make sure the new standby data directories do <emphasis>not</emphasis> exist</title>
+
+ <para>
+ Make sure the new standby data directories do <emphasis>not</emphasis>
+ exist or are empty. If <application>initdb</application> was run, delete
+ the standby servers' new data directories.
+ </para>
+ </step>
+
+ <step>
+ <title>Install extension shared object files</title>
+
+ <para>
+ Install the same extension shared object files on the new standbys
+ that you installed in the new primary cluster.
+ </para>
+ </step>
+
+ <step>
+ <title>Stop standby servers</title>
+
+ <para>
+ If the standby servers are still running, stop them now using the
+ above instructions.
+ </para>
+ </step>
+
+ <step>
+ <title>Save configuration files</title>
+
+ <para>
+ Save any configuration files from the old standbys' configuration
+ directories you need to keep, e.g., <filename>postgresql.conf</filename>
+ (and any files included by it), <filename>postgresql.auto.conf</filename>,
+ <literal>pg_hba.conf</literal>, because these will be overwritten
+ or removed in the next step.
+ </para>
+ </step>
+
+ <step>
+ <title>Run <application>rsync</application></title>
+
+ <para>
+ When using link mode, standby servers can be quickly upgraded using
+ <application>rsync</application>. To accomplish this, from a directory on
+ the primary server that is above the old and new database cluster
+ directories, run this on the <emphasis>primary</emphasis> for each standby
+ server:
+
+<programlisting>
+rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir
+</programlisting>
+
+ where <option>old_cluster</option> and <option>new_cluster</option> are relative
+ to the current directory on the primary, and <option>remote_dir</option>
+ is <emphasis>above</emphasis> the old and new cluster directories
+ on the standby. The directory structure under the specified
+ directories on the primary and standbys must match. Consult the
+ <application>rsync</application> manual page for details on specifying the
+ remote directory, e.g.,
+
+<programlisting>
+rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/PostgreSQL/9.5 \
+ /opt/PostgreSQL/9.6 standby.example.com:/opt/PostgreSQL
+</programlisting>
+
+ You can verify what the command will do using
+ <application>rsync</application>'s <option>--dry-run</option> option. While
+ <application>rsync</application> must be run on the primary for at least one
+ standby, it is possible to run <application>rsync</application> on an upgraded
+ standby to upgrade other standbys, as long as the upgraded standby
+ has not been started.
+ </para>
+
+ <para>
+ What this does is to record the links created by
+ <application>pg_upgrade</application>'s link mode that connect files in the
+ old and new clusters on the primary server. It then finds matching
+ files in the standby's old cluster and creates links for them in the
+ standby's new cluster. Files that were not linked on the primary
+ are copied from the primary to the standby. (They are usually
+ small.) This provides rapid standby upgrades. Unfortunately,
+ <application>rsync</application> needlessly copies files associated with
+ temporary and unlogged tables because these files don't normally
+ exist on standby servers.
+ </para>
+
+ <para>
+ If you have tablespaces, you will need to run a similar
+ <application>rsync</application> command for each tablespace directory, e.g.:
+
+<programlisting>
+rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tblsp/PG_9.5_201510051 \
+ /vol1/pg_tblsp/PG_9.6_201608131 standby.example.com:/vol1/pg_tblsp
+</programlisting>
+
+ If you have relocated <filename>pg_wal</filename> outside the data
+ directories, <application>rsync</application> must be run on those directories
+ too.
+ </para>
+ </step>
+
+ <step>
+ <title>Configure streaming replication and log-shipping standby servers</title>
+
+ <para>
+ Configure the servers for log shipping. (You do not need to run
+ <function>pg_backup_start()</function> and <function>pg_backup_stop()</function>
+ or take a file system backup as the standbys are still synchronized
+ with the primary.) Replication slots are not copied and must
+ be recreated.
+ </para>
+ </step>
+
+ </procedure>
+
+ </step>
+
+ <step>
+ <title>Restore <filename>pg_hba.conf</filename></title>
+
+ <para>
+ If you modified <filename>pg_hba.conf</filename>, restore its original settings.
+ It might also be necessary to adjust other configuration files in the new
+ cluster to match the old cluster, e.g., <filename>postgresql.conf</filename>
+ (and any files included by it), <filename>postgresql.auto.conf</filename>.
+ </para>
+ </step>
+
+ <step>
+ <title>Start the new server</title>
+
+ <para>
+ The new server can now be safely started, and then any
+ <application>rsync</application>'ed standby servers.
+ </para>
+ </step>
+
+ <step>
+ <title>Post-upgrade processing</title>
+
+ <para>
+ If any post-upgrade processing is required, pg_upgrade will issue
+ warnings as it completes. It will also generate script files that must
+ be run by the administrator. The script files will connect to each
+ database that needs post-upgrade processing. Each script should be
+ run using:
+
+<programlisting>
+psql --username=postgres --file=script.sql postgres
+</programlisting>
+
+ The scripts can be run in any order and can be deleted once they have
+ been run.
+ </para>
+
+ <caution>
+ <para>
+ In general it is unsafe to access tables referenced in rebuild scripts
+ until the rebuild scripts have run to completion; doing so could yield
+ incorrect results or poor performance. Tables not referenced in rebuild
+ scripts can be accessed immediately.
+ </para>
+ </caution>
+ </step>
+
+ <step>
+ <title>Statistics</title>
+
+ <para>
+ Because optimizer statistics are not transferred by <command>pg_upgrade</command>, you will
+ be instructed to run a command to regenerate that information at the end
+ of the upgrade. You might need to set connection parameters to
+ match your new cluster.
+ </para>
+ </step>
+
+ <step>
+ <title>Delete old cluster</title>
+
+ <para>
+ Once you are satisfied with the upgrade, you can delete the old
+ cluster's data directories by running the script mentioned when
+ <command>pg_upgrade</command> completes. (Automatic deletion is not
+ possible if you have user-defined tablespaces inside the old data
+ directory.) You can also delete the old installation directories
+ (e.g., <filename>bin</filename>, <filename>share</filename>).
+ </para>
+ </step>
+
+ <step id="pgupgrade-step-revert" performance="optional">
+ <title>Reverting to old cluster</title>
+
+ <para>
+ If, after running <command>pg_upgrade</command>, you wish to revert to the old cluster,
+ there are several options:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If the <option>--check</option> option was used, the old cluster
+ was unmodified; it can be restarted.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the <option>--link</option> option was <emphasis>not</emphasis>
+ used, the old cluster was unmodified; it can be restarted.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the <option>--link</option> option was used, the data
+ files might be shared between the old and new cluster:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If <command>pg_upgrade</command> aborted before linking started,
+ the old cluster was unmodified; it can be restarted.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you did <emphasis>not</emphasis> start the new cluster, the old
+ cluster was unmodified except that, when linking started, a
+ <literal>.old</literal> suffix was appended to
+ <filename>$PGDATA/global/pg_control</filename>. To reuse the old
+ cluster, remove the <filename>.old</filename> suffix from
+ <filename>$PGDATA/global/pg_control</filename>; you can then restart
+ the old cluster.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If you did start the new cluster, it has written to shared files
+ and it is unsafe to use the old cluster. The old cluster will
+ need to be restored from backup in this case.
+ </para>
+ </listitem>
+
+ </itemizedlist></para>
+ </listitem>
+ </itemizedlist></para>
+ </step>
+ </procedure>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>pg_upgrade</application> creates various working files, such
+ as schema dumps, stored within <filename>pg_upgrade_output.d</filename> in
+ the directory of the new cluster. Each run creates a new subdirectory named
+ with a timestamp formatted as per ISO 8601
+ (<literal>%Y%m%dT%H%M%S</literal>), where all its generated files are
+ stored.
+ <filename>pg_upgrade_output.d</filename> and its contained files will be
+ removed automatically if <application>pg_upgrade</application> completes
+ successfully; but in the event of trouble, the files there may provide
+ useful debugging information.
+ </para>
+
+ <para>
+ <application>pg_upgrade</application> launches short-lived postmasters in
+ the old and new data directories. Temporary Unix socket files for
+ communication with these postmasters are, by default, made in the current
+ working directory. In some situations the path name for the current
+ directory might be too long to be a valid socket name. In that case you
+ can use the <option>-s</option> option to put the socket files in some
+ directory with a shorter path name. For security, be sure that that
+ directory is not readable or writable by any other users.
+ (This is not supported on Windows.)
+ </para>
+
+ <para>
+ All failure, rebuild, and reindex cases will be reported by
+ <application>pg_upgrade</application> if they affect your installation;
+ post-upgrade scripts to rebuild tables and indexes will be
+ generated automatically. If you are trying to automate the upgrade
+ of many clusters, you should find that clusters with identical database
+ schemas require the same post-upgrade steps for all cluster upgrades;
+ this is because the post-upgrade steps are based on the database
+ schemas, and not user data.
+ </para>
+
+ <para>
+ For deployment testing, create a schema-only copy of the old cluster,
+ insert dummy data, and upgrade that.
+ </para>
+
+ <para>
+ <application>pg_upgrade</application> does not support upgrading of databases
+ containing table columns using these <type>reg*</type> OID-referencing system data types:
+ <simplelist>
+ <member><type>regcollation</type></member>
+ <member><type>regconfig</type></member>
+ <member><type>regdictionary</type></member>
+ <member><type>regnamespace</type></member>
+ <member><type>regoper</type></member>
+ <member><type>regoperator</type></member>
+ <member><type>regproc</type></member>
+ <member><type>regprocedure</type></member>
+ </simplelist>
+ (<type>regclass</type>, <type>regrole</type>, and <type>regtype</type> can be upgraded.)
+ </para>
+
+ <para>
+ If you want to use link mode and you do not want your old cluster
+ to be modified when the new cluster is started, consider using the clone mode.
+ If that is not available, make a copy of the
+ old cluster and upgrade that in link mode. To make a valid copy
+ of the old cluster, use <command>rsync</command> to create a dirty
+ copy of the old cluster while the server is running, then shut down
+ the old server and run <command>rsync --checksum</command> again to update the
+ copy with any changes to make it consistent. (<option>--checksum</option>
+ is necessary because <command>rsync</command> only has file modification-time
+ granularity of one second.) You might want to exclude some
+ files, e.g., <filename>postmaster.pid</filename>, as documented in <xref
+ linkend="backup-lowlevel-base-backup"/>. If your file system supports
+ file system snapshots or copy-on-write file copies, you can use that
+ to make a backup of the old cluster and tablespaces, though the snapshot
+ and copies must be created simultaneously or while the database server
+ is down.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-initdb"/></member>
+ <member><xref linkend="app-pg-ctl"/></member>
+ <member><xref linkend="app-pgdump"/></member>
+ <member><xref linkend="app-postgres"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml
new file mode 100644
index 0000000..55a3f6c
--- /dev/null
+++ b/doc/src/sgml/ref/postgres-ref.sgml
@@ -0,0 +1,845 @@
+<!--
+doc/src/sgml/ref/postgres-ref.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-postgres">
+ <indexterm zone="app-postgres">
+ <primary>postgres</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>postgres</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>postgres</refname>
+ <refpurpose><productname>PostgreSQL</productname> database server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>postgres</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>postgres</command> is the
+ <productname>PostgreSQL</productname> database server. In order
+ for a client application to access a database it connects (over a
+ network or locally) to a running <command>postgres</command> instance.
+ The <command>postgres</command> instance then starts a separate server
+ process to handle the connection.
+ </para>
+
+ <para>
+ One <command>postgres</command> instance always manages the data of
+ exactly one database cluster. A database cluster is a collection
+ of databases that is stored at a common file system location (the
+ <quote>data area</quote>). More than one
+ <command>postgres</command> instance can run on a system at one
+ time, so long as they use different data areas and different
+ communication ports (see below). When
+ <command>postgres</command> starts it needs to know the location
+ of the data area. The location must be specified by the
+ <option>-D</option> option or the <envar>PGDATA</envar> environment
+ variable; there is no default. Typically, <option>-D</option> or
+ <envar>PGDATA</envar> points directly to the data area directory
+ created by <xref linkend="app-initdb"/>. Other possible file layouts are
+ discussed in <xref linkend="runtime-config-file-locations"/>.
+ </para>
+
+ <para>
+ By default <command>postgres</command> starts in the
+ foreground and prints log messages to the standard error stream. In
+ practical applications <command>postgres</command>
+ should be started as a background process, perhaps at boot time.
+ </para>
+
+ <para>
+ The <command>postgres</command> command can also be called in
+ single-user mode. The primary use for this mode is during
+ bootstrapping by <xref linkend="app-initdb"/>. Sometimes it is used
+ for debugging or disaster recovery; note that running a single-user
+ server is not truly suitable for debugging the server, since no
+ realistic interprocess communication and locking will happen.
+ When invoked in single-user
+ mode from the shell, the user can enter queries and the results
+ will be printed to the screen, but in a form that is more useful
+ for developers than end users. In the single-user mode,
+ the session user will be set to the user with ID 1, and implicit
+ superuser powers are granted to this user.
+ This user does not actually have to exist, so the single-user mode
+ can be used to manually recover from certain
+ kinds of accidental damage to the system catalogs.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-postgres-options">
+ <title>Options</title>
+
+ <para>
+ <command>postgres</command> accepts the following command-line
+ arguments. For a detailed discussion of the options consult <xref
+ linkend="runtime-config"/>. You can save typing most of these
+ options by setting up a configuration file. Some (safe) options
+ can also be set from the connecting client in an
+ application-dependent way to apply only for that session. For
+ example, if the environment variable <envar>PGOPTIONS</envar> is
+ set, then <application>libpq</application>-based clients will pass that
+ string to the server, which will interpret it as
+ <command>postgres</command> command-line options.
+ </para>
+
+ <refsect2>
+ <title>General Purpose</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-B <replaceable class="parameter">nbuffers</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the number of shared buffers for use by the server
+ processes. The default value of this parameter is chosen
+ automatically by <application>initdb</application>.
+ Specifying this option is equivalent to setting the
+ <xref linkend="guc-shared-buffers"/> configuration parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c <replaceable>name</replaceable>=<replaceable>value</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets a named run-time parameter. The configuration parameters
+ supported by <productname>PostgreSQL</productname> are
+ described in <xref linkend="runtime-config"/>. Most of the
+ other command line options are in fact short forms of such a
+ parameter assignment. <option>-c</option> can appear multiple times
+ to set multiple parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-C <replaceable>name</replaceable></option></term>
+ <listitem>
+ <para>
+ Prints the value of the named run-time parameter, and exits.
+ (See the <option>-c</option> option above for details.) This
+ returns values from
+ <filename>postgresql.conf</filename>, modified by any parameters
+ supplied in this invocation. It does not reflect parameters
+ supplied when the cluster was started.
+ </para>
+
+ <para>
+ This can be used on a running server for most parameters. However,
+ the server must be shut down for some runtime-computed parameters
+ (e.g., <xref linkend="guc-shared-memory-size"/>,
+ <xref linkend="guc-shared-memory-size-in-huge-pages"/>, and
+ <xref linkend="guc-wal-segment-size"/>).
+ </para>
+
+ <para>
+ This option is meant for other programs that interact with a server
+ instance, such as <xref linkend="app-pg-ctl"/>, to query configuration
+ parameter values. User-facing applications should instead use <link
+ linkend="sql-show"><command>SHOW</command></link> or the <structname>pg_settings</structname> view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d <replaceable>debug-level</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the debug level. The higher this value is set, the more
+ debugging output is written to the server log. Values are
+ from 1 to 5. It is also possible to pass <literal>-d
+ 0</literal> for a specific session, which will prevent the
+ server log level of the parent <command>postgres</command> process from being
+ propagated to this session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-D <replaceable class="parameter">datadir</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the file system location of the database
+ configuration files. See
+ <xref linkend="runtime-config-file-locations"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <listitem>
+ <para>
+ Sets the default date style to <quote>European</quote>, that is
+ <literal>DMY</literal> ordering of input date fields. This also causes
+ the day to be printed before the month in certain date output formats.
+ See <xref linkend="datatype-datetime"/> for more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F</option></term>
+ <listitem>
+ <para>
+ Disables <function>fsync</function> calls for improved
+ performance, at the risk of data corruption in the event of a
+ system crash. Specifying this option is equivalent to
+ disabling the <xref linkend="guc-fsync"/> configuration
+ parameter. Read the detailed documentation before using this!
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">hostname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the IP host name or address on which
+ <command>postgres</command> is to listen for TCP/IP
+ connections from client applications. The value can also be a
+ comma-separated list of addresses, or <literal>*</literal> to specify
+ listening on all available interfaces. An empty value
+ specifies not listening on any IP addresses, in which case
+ only Unix-domain sockets can be used to connect to the
+ server. Defaults to listening only on
+ <systemitem class="systemname">localhost</systemitem>.
+ Specifying this option is equivalent to setting the <xref
+ linkend="guc-listen-addresses"/> configuration parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i</option></term>
+ <listitem>
+ <para>
+ Allows remote clients to connect via TCP/IP (Internet domain)
+ connections. Without this option, only local connections are
+ accepted. This option is equivalent to setting
+ <varname>listen_addresses</varname> to <literal>*</literal> in
+ <filename>postgresql.conf</filename> or via <option>-h</option>.
+ </para>
+ <para>
+ This option is deprecated since it does not allow access to the
+ full functionality of <xref linkend="guc-listen-addresses"/>.
+ It's usually better to set <varname>listen_addresses</varname> directly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-k <replaceable class="parameter">directory</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the directory of the Unix-domain socket on which
+ <command>postgres</command> is to listen for
+ connections from client applications. The value can also be a
+ comma-separated list of directories. An empty value
+ specifies not listening on any Unix-domain sockets, in which case
+ only TCP/IP sockets can be used to connect to the server.
+ The default value is normally
+ <filename>/tmp</filename>, but that can be changed at build time.
+ Specifying this option is equivalent to setting the <xref
+ linkend="guc-unix-socket-directories"/> configuration parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l</option></term>
+ <listitem>
+ <para>
+ Enables secure connections using <acronym>SSL</acronym>.
+ <productname>PostgreSQL</productname> must have been compiled with
+ support for <acronym>SSL</acronym> for this option to be
+ available. For more information on using <acronym>SSL</acronym>,
+ refer to <xref linkend="ssl-tcp"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-N <replaceable class="parameter">max-connections</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets the maximum number of client connections that this
+ server will accept. The default value of this parameter is chosen
+ automatically by <application>initdb</application>.
+ Specifying this option is equivalent to setting the
+ <xref linkend="guc-max-connections"/> configuration parameter.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP/IP port or local Unix domain socket file
+ extension on which <command>postgres</command>
+ is to listen for connections from client applications.
+ Defaults to the value of the <envar>PGPORT</envar> environment
+ variable, or if <envar>PGPORT</envar> is not set, then
+ defaults to the value established during compilation (normally
+ 5432). If you specify a port other than the default port,
+ then all client applications must specify the same port using
+ either command-line options or <envar>PGPORT</envar>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <listitem>
+ <para>
+ Print time information and other statistics at the end of each command.
+ This is useful for benchmarking or for use in tuning the number of
+ buffers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S</option> <replaceable class="parameter">work-mem</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the base amount of memory to be used by sorts and
+ hash tables before resorting to temporary disk files. See the
+ description of the <varname>work_mem</varname> configuration
+ parameter in <xref linkend="runtime-config-resource-memory"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>postgres</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--<replaceable>name</replaceable>=<replaceable>value</replaceable></option></term>
+ <listitem>
+ <para>
+ Sets a named run-time parameter; a shorter form of
+ <option>-c</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--describe-config</option></term>
+ <listitem>
+ <para>
+ This option dumps out the server's internal configuration variables,
+ descriptions, and defaults in tab-delimited <command>COPY</command> format.
+ It is designed primarily for use by administration tools.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>postgres</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+
+ <refsect2>
+ <title>Semi-Internal Options</title>
+
+ <para>
+ The options described here are used
+ mainly for debugging purposes, and in some cases to assist with
+ recovery of severely damaged databases. There should be no reason
+ to use them in a production database setup. They are listed
+ here only for use by <productname>PostgreSQL</productname>
+ system developers. Furthermore, these options might
+ change or be removed in a future release without notice.
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-f</option> <literal>{ s | i | o | b | t | n | m | h }</literal></term>
+ <listitem>
+ <para>
+ Forbids the use of particular scan and join methods:
+ <literal>s</literal> and <literal>i</literal>
+ disable sequential and index scans respectively,
+ <literal>o</literal>, <literal>b</literal> and <literal>t</literal>
+ disable index-only scans, bitmap index scans, and TID scans
+ respectively, while
+ <literal>n</literal>, <literal>m</literal>, and <literal>h</literal>
+ disable nested-loop, merge and hash joins respectively.
+ </para>
+
+ <para>
+ Neither sequential scans nor nested-loop joins can be disabled
+ completely; the <literal>-fs</literal> and
+ <literal>-fn</literal> options simply discourage the optimizer
+ from using those plan types if it has any other alternative.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <listitem>
+ <para>
+ This option is for debugging problems that cause a server
+ process to die abnormally. The ordinary strategy in this
+ situation is to notify all other server processes that they
+ must terminate and then reinitialize the shared memory and
+ semaphores. This is because an errant server process could
+ have corrupted some shared state before terminating. This
+ option specifies that <command>postgres</command> will
+ not reinitialize shared data structures. A knowledgeable
+ system programmer can then use a debugger to examine shared
+ memory and semaphore state.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-O</option></term>
+ <listitem>
+ <para>
+ Allows the structure of system tables to be modified. This is
+ used by <command>initdb</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P</option></term>
+ <listitem>
+ <para>
+ Ignore system indexes when reading system tables, but still update
+ the indexes when modifying the tables. This is useful when
+ recovering from damaged system indexes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option> <literal>pa[rser] | pl[anner] | e[xecutor]</literal></term>
+ <listitem>
+ <para>
+ Print timing statistics for each query relating to each of the
+ major system modules. This option cannot be used together
+ with the <option>-s</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T</option></term>
+ <listitem>
+ <para>
+ This option is for debugging problems that cause a server
+ process to die abnormally. The ordinary strategy in this
+ situation is to notify all other server processes that they
+ must terminate and then reinitialize the shared memory and
+ semaphores. This is because an errant server process could
+ have corrupted some shared state before terminating. This
+ option specifies that <command>postgres</command> will
+ stop all other server processes by sending the signal
+ <literal>SIGSTOP</literal>, but will not cause them to
+ terminate. This permits system programmers to collect core
+ dumps from all server processes by hand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option> <replaceable class="parameter">protocol</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the version number of the frontend/backend protocol
+ to be used for a particular session. This option is for
+ internal use only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option> <replaceable class="parameter">seconds</replaceable></term>
+ <listitem>
+ <para>
+ A delay of this many seconds occurs when a new server process
+ is started, after it conducts the authentication procedure.
+ This is intended to give an opportunity to attach to the
+ server process with a debugger.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+
+ <refsect2>
+ <title>Options for Single-User Mode</title>
+
+ <indexterm>
+ <primary>single-user mode</primary>
+ </indexterm>
+
+ <para>
+ The following options only apply to the single-user mode
+ (see <xref linkend="app-postgres-single-user"/> below).
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>--single</option></term>
+ <listitem>
+ <para>
+ Selects the single-user mode. This must be the first argument
+ on the command line.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">database</replaceable></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be accessed. This must be
+ the last argument on the command line. If it is
+ omitted it defaults to the user name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E</option></term>
+ <listitem>
+ <para>
+ Echo all commands to standard output before executing them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j</option></term>
+ <listitem>
+ <para>
+ Use semicolon followed by two newlines, rather than just newline,
+ as the command entry terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-r</option> <replaceable class="parameter">filename</replaceable></term>
+ <listitem>
+ <para>
+ Send all server log output to <replaceable
+ class="parameter">filename</replaceable>. This option is only
+ honored when supplied as a command-line option.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGCLIENTENCODING</envar></term>
+
+ <listitem>
+ <para>
+ Default character encoding used by clients. (The clients can
+ override this individually.) This value can also be set in the
+ configuration file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PGDATA</envar></term>
+
+ <listitem>
+ <para>
+ Default data directory location
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PGDATESTYLE</envar></term>
+
+ <listitem>
+ <para>
+ Default value of the <xref linkend="guc-datestyle"/> run-time
+ parameter. (The use of this environment variable is deprecated.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PGPORT</envar></term>
+
+ <listitem>
+ <para>
+ Default port number (preferably set in the configuration file)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ A failure message mentioning <literal>semget</literal> or
+ <literal>shmget</literal> probably indicates you need to configure your
+ kernel to provide adequate shared memory and semaphores. For more
+ discussion see <xref linkend="kernel-resources"/>. You might be able
+ to postpone reconfiguring your kernel by decreasing <xref
+ linkend="guc-shared-buffers"/> to reduce the shared memory
+ consumption of <productname>PostgreSQL</productname>, and/or by reducing
+ <xref linkend="guc-max-connections"/> to reduce the semaphore
+ consumption.
+ </para>
+
+ <para>
+ A failure message suggesting that another server is already running
+ should be checked carefully, for example by using the command
+<screen>
+<prompt>$</prompt> <userinput>ps ax | grep postgres</userinput>
+</screen>
+ or
+<screen>
+<prompt>$</prompt> <userinput>ps -ef | grep postgres</userinput>
+</screen>
+ depending on your system. If you are certain that no conflicting
+ server is running, you can remove the lock file mentioned in the
+ message and try again.
+ </para>
+
+ <para>
+ A failure message indicating inability to bind to a port might
+ indicate that that port is already in use by some
+ non-<productname>PostgreSQL</productname> process. You might also
+ get this error if you terminate <command>postgres</command>
+ and immediately restart it using the same port; in this case, you
+ must simply wait a few seconds until the operating system closes
+ the port before trying again. Finally, you might get this error if
+ you specify a port number that your operating system considers to
+ be reserved. For example, many versions of Unix consider port
+ numbers under 1024 to be <quote>trusted</quote> and only permit
+ the Unix superuser to access them.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The utility command <xref linkend="app-pg-ctl"/> can be used to
+ start and shut down the <command>postgres</command> server
+ safely and comfortably.
+ </para>
+
+ <para>
+ If at all possible, <emphasis>do not</emphasis> use
+ <literal>SIGKILL</literal> to kill the main
+ <command>postgres</command> server. Doing so will prevent
+ <command>postgres</command> from freeing the system
+ resources (e.g., shared memory and semaphores) that it holds before
+ terminating. This might cause problems for starting a fresh
+ <command>postgres</command> run.
+ </para>
+
+ <para>
+ To terminate the <command>postgres</command> server normally, the
+ signals <literal>SIGTERM</literal>, <literal>SIGINT</literal>, or
+ <literal>SIGQUIT</literal> can be used. The first will wait for
+ all clients to terminate before quitting, the second will
+ forcefully disconnect all clients, and the third will quit
+ immediately without proper shutdown, resulting in a recovery run
+ during restart.
+ </para>
+
+ <para>
+ The <literal>SIGHUP</literal> signal will reload
+ the server configuration files. It is also possible to send
+ <literal>SIGHUP</literal> to an individual server process, but that
+ is usually not sensible.
+ </para>
+
+ <para>
+ To cancel a running query, send the <literal>SIGINT</literal> signal
+ to the process running that command. To terminate a backend process
+ cleanly, send <literal>SIGTERM</literal> to that process. See
+ also <function>pg_cancel_backend</function> and <function>pg_terminate_backend</function>
+ in <xref linkend="functions-admin-signal"/> for the SQL-callable equivalents
+ of these two actions.
+ </para>
+
+ <para>
+ The <command>postgres</command> server uses <literal>SIGQUIT</literal>
+ to tell subordinate server processes to terminate without normal
+ cleanup.
+ This signal <emphasis>should not</emphasis> be used by users. It
+ is also unwise to send <literal>SIGKILL</literal> to a server
+ process &mdash; the main <command>postgres</command> process will
+ interpret this as a crash and will force all the sibling processes
+ to quit as part of its standard crash-recovery procedure.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-postgres-bugs">
+ <title>Bugs</title>
+ <para>
+ The <option>--</option> options will not work on <systemitem
+ class="osname">FreeBSD</systemitem> or <systemitem class="osname">OpenBSD</systemitem>.
+ Use <option>-c</option> instead. This is a bug in the affected operating
+ systems; a future release of <productname>PostgreSQL</productname>
+ will provide a workaround if this is not fixed.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-postgres-single-user" xreflabel="Single-User Mode">
+ <title>Single-User Mode</title>
+
+ <para>
+ To start a single-user mode server, use a command like
+<screen>
+<userinput>postgres --single -D /usr/local/pgsql/data <replaceable>other-options</replaceable> my_database</userinput>
+</screen>
+ Provide the correct path to the database directory with <option>-D</option>, or
+ make sure that the environment variable <envar>PGDATA</envar> is set.
+ Also specify the name of the particular database you want to work in.
+ </para>
+
+ <para>
+ Normally, the single-user mode server treats newline as the command
+ entry terminator; there is no intelligence about semicolons,
+ as there is in <application>psql</application>. To continue a command
+ across multiple lines, you must type backslash just before each
+ newline except the last one. The backslash and adjacent newline are
+ both dropped from the input command. Note that this will happen even
+ when within a string literal or comment.
+ </para>
+
+ <para>
+ But if you use the <option>-j</option> command line switch, a single newline
+ does not terminate command entry; instead, the sequence
+ semicolon-newline-newline does. That is, type a semicolon immediately
+ followed by a completely empty line. Backslash-newline is not
+ treated specially in this mode. Again, there is no intelligence about
+ such a sequence appearing within a string literal or comment.
+ </para>
+
+ <para>
+ In either input mode, if you type a semicolon that is not just before or
+ part of a command entry terminator, it is considered a command separator.
+ When you do type a command entry terminator, the multiple statements
+ you've entered will be executed as a single transaction.
+ </para>
+
+ <para>
+ To quit the session, type <acronym>EOF</acronym>
+ (<keycombo action="simul"><keycap>Control</keycap><keycap>D</keycap></keycombo>, usually).
+ If you've entered any text since the last command entry terminator,
+ then <acronym>EOF</acronym> will be taken as a command entry terminator,
+ and another <acronym>EOF</acronym> will be needed to exit.
+ </para>
+
+ <para>
+ Note that the single-user mode server does not provide sophisticated
+ line-editing features (no command history, for example).
+ Single-user mode also does not do any background processing, such as
+ automatic checkpoints or replication.
+ </para>
+ </refsect1>
+
+ <refsect1 id="app-postgres-examples">
+ <title>Examples</title>
+
+ <para>
+ To start <command>postgres</command> in the background
+ using default values, type:
+
+<screen>
+<prompt>$</prompt> <userinput>nohup postgres &gt;logfile 2&gt;&amp;1 &lt;/dev/null &amp;</userinput>
+</screen>
+ </para>
+
+ <para>
+ To start <command>postgres</command> with a specific
+ port, e.g., 1234:
+<screen>
+<prompt>$</prompt> <userinput>postgres -p 1234</userinput>
+</screen>
+ To connect to this server using <application>psql</application>, specify this port with the -p option:
+<screen>
+<prompt>$</prompt> <userinput>psql -p 1234</userinput>
+</screen>
+ or set the environment variable <envar>PGPORT</envar>:
+<screen>
+<prompt>$</prompt> <userinput>export PGPORT=1234</userinput>
+<prompt>$</prompt> <userinput>psql</userinput>
+</screen>
+ </para>
+
+ <para>
+ Named run-time parameters can be set in either of these styles:
+<screen>
+<prompt>$</prompt> <userinput>postgres -c work_mem=1234</userinput>
+<prompt>$</prompt> <userinput>postgres --work-mem=1234</userinput>
+</screen>
+ Either form overrides whatever setting might exist for
+ <varname>work_mem</varname> in <filename>postgresql.conf</filename>. Notice that
+ underscores in parameter names can be written as either underscore
+ or dash on the command line. Except for short-term experiments,
+ it's probably better practice to edit the setting in
+ <filename>postgresql.conf</filename> than to rely on a command-line switch
+ to set a parameter.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <xref linkend="app-initdb"/>,
+ <xref linkend="app-pg-ctl"/>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/postmaster.sgml b/doc/src/sgml/ref/postmaster.sgml
new file mode 100644
index 0000000..7b544ed
--- /dev/null
+++ b/doc/src/sgml/ref/postmaster.sgml
@@ -0,0 +1,44 @@
+<!--
+doc/src/sgml/ref/postmaster.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-postmaster">
+ <indexterm zone="app-postmaster">
+ <primary>postmaster</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>postmaster</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>postmaster</refname>
+ <refpurpose><productname>PostgreSQL</productname> database server</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>postmaster</command>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>postmaster</command> is a deprecated alias of <command>postgres</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <para>
+ <xref linkend="app-postgres"/>
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/prepare.sgml b/doc/src/sgml/ref/prepare.sgml
new file mode 100644
index 0000000..d7b8539
--- /dev/null
+++ b/doc/src/sgml/ref/prepare.sgml
@@ -0,0 +1,258 @@
+<!--
+doc/src/sgml/ref/prepare.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-prepare">
+ <indexterm zone="sql-prepare">
+ <primary>PREPARE</primary>
+ </indexterm>
+
+ <indexterm zone="sql-prepare">
+ <primary>prepared statements</primary>
+ <secondary>creating</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>PREPARE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>PREPARE</refname>
+ <refpurpose>prepare a statement for execution</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+PREPARE <replaceable class="parameter">name</replaceable> [ ( <replaceable class="parameter">data_type</replaceable> [, ...] ) ] AS <replaceable class="parameter">statement</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>PREPARE</command> creates a prepared statement. A prepared
+ statement is a server-side object that can be used to optimize
+ performance. When the <command>PREPARE</command> statement is
+ executed, the specified statement is parsed, analyzed, and rewritten.
+ When an <command>EXECUTE</command> command is subsequently
+ issued, the prepared statement is planned and executed. This division
+ of labor avoids repetitive parse analysis work, while allowing
+ the execution plan to depend on the specific parameter values supplied.
+ </para>
+
+ <para>
+ Prepared statements can take parameters: values that are
+ substituted into the statement when it is executed. When creating
+ the prepared statement, refer to parameters by position, using
+ <literal>$1</literal>, <literal>$2</literal>, etc. A corresponding list of
+ parameter data types can optionally be specified. When a
+ parameter's data type is not specified or is declared as
+ <literal>unknown</literal>, the type is inferred from the context
+ in which the parameter is first referenced (if possible). When executing the
+ statement, specify the actual values for these parameters in the
+ <command>EXECUTE</command> statement. Refer to <xref
+ linkend="sql-execute"/> for more
+ information about that.
+ </para>
+
+ <para>
+ Prepared statements only last for the duration of the current
+ database session. When the session ends, the prepared statement is
+ forgotten, so it must be recreated before being used again. This
+ also means that a single prepared statement cannot be used by
+ multiple simultaneous database clients; however, each client can create
+ their own prepared statement to use. Prepared statements can be
+ manually cleaned up using the <link linkend="sql-deallocate"><command>DEALLOCATE</command></link> command.
+ </para>
+
+ <para>
+ Prepared statements potentially have the largest performance advantage
+ when a single session is being used to execute a large number of similar
+ statements. The performance difference will be particularly
+ significant if the statements are complex to plan or rewrite, e.g.,
+ if the query involves a join of many tables or requires
+ the application of several rules. If the statement is relatively simple
+ to plan and rewrite but relatively expensive to execute, the
+ performance advantage of prepared statements will be less noticeable.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ An arbitrary name given to this particular prepared
+ statement. It must be unique within a single session and is
+ subsequently used to execute or deallocate a previously prepared
+ statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">data_type</replaceable></term>
+ <listitem>
+ <para>
+ The data type of a parameter to the prepared statement. If the
+ data type of a particular parameter is unspecified or is
+ specified as <literal>unknown</literal>, it will be inferred
+ from the context in which the parameter is first referenced. To refer to the
+ parameters in the prepared statement itself, use
+ <literal>$1</literal>, <literal>$2</literal>, etc.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">statement</replaceable></term>
+ <listitem>
+ <para>
+ Any <command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, <command>MERGE</command>, or <command>VALUES</command>
+ statement.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="sql-prepare-notes">
+ <title>Notes</title>
+
+ <para>
+ A prepared statement can be executed with either a <firstterm>generic
+ plan</firstterm> or a <firstterm>custom plan</firstterm>. A generic
+ plan is the same across all executions, while a custom plan is generated
+ for a specific execution using the parameter values given in that call.
+ Use of a generic plan avoids planning overhead, but in some situations
+ a custom plan will be much more efficient to execute because the planner
+ can make use of knowledge of the parameter values. (Of course, if the
+ prepared statement has no parameters, then this is moot and a generic
+ plan is always used.)
+ </para>
+
+ <para>
+ By default (that is, when <xref linkend="guc-plan-cache_mode"/> is set
+ to <literal>auto</literal>), the server will automatically choose
+ whether to use a generic or custom plan for a prepared statement that
+ has parameters. The current rule for this is that the first five
+ executions are done with custom plans and the average estimated cost of
+ those plans is calculated. Then a generic plan is created and its
+ estimated cost is compared to the average custom-plan cost. Subsequent
+ executions use the generic plan if its cost is not so much higher than
+ the average custom-plan cost as to make repeated replanning seem
+ preferable.
+ </para>
+
+ <para>
+ This heuristic can be overridden, forcing the server to use either
+ generic or custom plans, by setting <varname>plan_cache_mode</varname>
+ to <literal>force_generic_plan</literal>
+ or <literal>force_custom_plan</literal> respectively.
+ This setting is primarily useful if the generic plan's cost estimate
+ is badly off for some reason, allowing it to be chosen even though
+ its actual cost is much more than that of a custom plan.
+ </para>
+
+ <para>
+ To examine the query plan <productname>PostgreSQL</productname> is using
+ for a prepared statement, use <link linkend="sql-explain"><command>EXPLAIN</command></link>, for example
+<programlisting>
+EXPLAIN EXECUTE <replaceable>name</replaceable>(<replaceable>parameter_values</replaceable>);
+</programlisting>
+ If a generic plan is in use, it will contain parameter symbols
+ <literal>$<replaceable>n</replaceable></literal>, while a custom plan
+ will have the supplied parameter values substituted into it.
+ </para>
+
+ <para>
+ For more information on query planning and the statistics collected
+ by <productname>PostgreSQL</productname> for that purpose, see
+ the <xref linkend="sql-analyze"/>
+ documentation.
+ </para>
+
+ <para>
+ Although the main point of a prepared statement is to avoid repeated parse
+ analysis and planning of the statement, <productname>PostgreSQL</productname> will
+ force re-analysis and re-planning of the statement before using it
+ whenever database objects used in the statement have undergone
+ definitional (DDL) changes or their planner statistics have
+ been updated since the previous use of the prepared
+ statement. Also, if the value of <xref linkend="guc-search-path"/> changes
+ from one use to the next, the statement will be re-parsed using the new
+ <varname>search_path</varname>. (This latter behavior is new as of
+ <productname>PostgreSQL</productname> 9.3.) These rules make use of a
+ prepared statement semantically almost equivalent to re-submitting the
+ same query text over and over, but with a performance benefit if no object
+ definitions are changed, especially if the best plan remains the same
+ across uses. An example of a case where the semantic equivalence is not
+ perfect is that if the statement refers to a table by an unqualified name,
+ and then a new table of the same name is created in a schema appearing
+ earlier in the <varname>search_path</varname>, no automatic re-parse will occur
+ since no object used in the statement changed. However, if some other
+ change forces a re-parse, the new table will be referenced in subsequent
+ uses.
+ </para>
+
+ <para>
+ You can see all prepared statements available in the session by querying the
+ <link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link>
+ system view.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-prepare-examples" xreflabel="Examples">
+ <title>Examples</title>
+ <para>
+ Create a prepared statement for an <command>INSERT</command>
+ statement, and then execute it:
+<programlisting>
+PREPARE fooplan (int, text, bool, numeric) AS
+ INSERT INTO foo VALUES($1, $2, $3, $4);
+EXECUTE fooplan(1, 'Hunter Valley', 't', 200.00);
+</programlisting>
+ </para>
+
+ <para>
+ Create a prepared statement for a <command>SELECT</command>
+ statement, and then execute it:
+<programlisting>
+PREPARE usrrptplan (int) AS
+ SELECT * FROM users u, logs l WHERE u.usrid=$1 AND u.usrid=l.usrid
+ AND l.date = $2;
+EXECUTE usrrptplan(1, current_date);
+</programlisting>
+
+ In this example, the data type of the second parameter is not specified,
+ so it is inferred from the context in which <literal>$2</literal> is used.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard includes a <command>PREPARE</command> statement,
+ but it is only for use in embedded SQL. This version of the
+ <command>PREPARE</command> statement also uses a somewhat different
+ syntax.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-deallocate"/></member>
+ <member><xref linkend="sql-execute"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/prepare_transaction.sgml b/doc/src/sgml/ref/prepare_transaction.sgml
new file mode 100644
index 0000000..f4f6118
--- /dev/null
+++ b/doc/src/sgml/ref/prepare_transaction.sgml
@@ -0,0 +1,181 @@
+<!--
+doc/src/sgml/ref/prepare_transaction.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-prepare-transaction">
+ <indexterm zone="sql-prepare-transaction">
+ <primary>PREPARE TRANSACTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>PREPARE TRANSACTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>PREPARE TRANSACTION</refname>
+ <refpurpose>prepare the current transaction for two-phase commit</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+PREPARE TRANSACTION <replaceable class="parameter">transaction_id</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>PREPARE TRANSACTION</command> prepares the current transaction
+ for two-phase commit. After this command, the transaction is no longer
+ associated with the current session; instead, its state is fully stored on
+ disk, and there is a very high probability that it can be committed
+ successfully, even if a database crash occurs before the commit is
+ requested.
+ </para>
+
+ <para>
+ Once prepared, a transaction can later be committed or rolled back
+ with <link linkend="sql-commit-prepared"><command>COMMIT PREPARED</command></link>
+ or <link linkend="sql-rollback-prepared"><command>ROLLBACK PREPARED</command></link>,
+ respectively. Those commands can be issued from any session, not
+ only the one that executed the original transaction.
+ </para>
+
+ <para>
+ From the point of view of the issuing session, <command>PREPARE
+ TRANSACTION</command> is not unlike a <command>ROLLBACK</command> command:
+ after executing it, there is no active current transaction, and the
+ effects of the prepared transaction are no longer visible. (The effects
+ will become visible again if the transaction is committed.)
+ </para>
+
+ <para>
+ If the <command>PREPARE TRANSACTION</command> command fails for any
+ reason, it becomes a <command>ROLLBACK</command>: the current transaction
+ is canceled.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">transaction_id</replaceable></term>
+ <listitem>
+ <para>
+ An arbitrary identifier that later identifies this transaction for
+ <command>COMMIT PREPARED</command> or <command>ROLLBACK PREPARED</command>.
+ The identifier must be written as a string literal, and must be
+ less than 200 bytes long. It must not be the same as the identifier
+ used for any currently prepared transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>PREPARE TRANSACTION</command> is not intended for use in applications
+ or interactive sessions. Its purpose is to allow an external
+ transaction manager to perform atomic global transactions across multiple
+ databases or other transactional resources. Unless you're writing a
+ transaction manager, you probably shouldn't be using <command>PREPARE
+ TRANSACTION</command>.
+ </para>
+
+ <para>
+ This command must be used inside a transaction block. Use <link
+ linkend="sql-begin"><command>BEGIN</command></link> to start one.
+ </para>
+
+ <para>
+ It is not currently allowed to <command>PREPARE</command> a transaction that
+ has executed any operations involving temporary tables or the session's
+ temporary namespace, created any cursors <literal>WITH HOLD</literal>, or
+ executed <command>LISTEN</command>, <command>UNLISTEN</command>, or
+ <command>NOTIFY</command>.
+ Those features are too tightly
+ tied to the current session to be useful in a transaction to be prepared.
+ </para>
+
+ <para>
+ If the transaction modified any run-time parameters with <command>SET</command>
+ (without the <literal>LOCAL</literal> option),
+ those effects persist after <command>PREPARE TRANSACTION</command>, and will not
+ be affected by any later <command>COMMIT PREPARED</command> or
+ <command>ROLLBACK PREPARED</command>. Thus, in this one respect
+ <command>PREPARE TRANSACTION</command> acts more like <command>COMMIT</command> than
+ <command>ROLLBACK</command>.
+ </para>
+
+ <para>
+ All currently available prepared transactions are listed in the
+ <link linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>
+ system view.
+ </para>
+
+ <caution>
+ <para>
+ It is unwise to leave transactions in the prepared state for a long time.
+ This will interfere with the ability of <command>VACUUM</command> to reclaim
+ storage, and in extreme cases could cause the database to shut down
+ to prevent transaction ID wraparound (see <xref
+ linkend="vacuum-for-wraparound"/>). Keep in mind also that the transaction
+ continues to hold whatever locks it held. The intended usage of the
+ feature is that a prepared transaction will normally be committed or
+ rolled back as soon as an external transaction manager has verified that
+ other databases are also prepared to commit.
+ </para>
+
+ <para>
+ If you have not set up an external transaction manager to track prepared
+ transactions and ensure they get closed out promptly, it is best to keep
+ the prepared-transaction feature disabled by setting
+ <xref linkend="guc-max-prepared-transactions"/> to zero. This will
+ prevent accidental creation of prepared transactions that might then
+ be forgotten and eventually cause problems.
+ </para>
+ </caution>
+ </refsect1>
+
+ <refsect1 id="sql-prepare-transaction-examples">
+ <title>Examples</title>
+ <para>
+ Prepare the current transaction for two-phase commit, using
+ <literal>foobar</literal> as the transaction identifier:
+
+<programlisting>
+PREPARE TRANSACTION 'foobar';
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>PREPARE TRANSACTION</command> is a
+ <productname>PostgreSQL</productname> extension. It is intended for use by
+ external transaction management systems, some of which are covered by
+ standards (such as X/Open XA), but the SQL side of those systems is not
+ standardized.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-commit-prepared"/></member>
+ <member><xref linkend="sql-rollback-prepared"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
new file mode 100644
index 0000000..dceb8cd
--- /dev/null
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -0,0 +1,5183 @@
+<!--
+doc/src/sgml/ref/psql-ref.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-psql">
+ <indexterm zone="app-psql">
+ <primary>psql</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>psql</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname><application>psql</application></refname>
+ <refpurpose>
+ <productname>PostgreSQL</productname> interactive terminal
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>psql</command>
+ <arg rep="repeat"><replaceable class="parameter">option</replaceable></arg>
+ <arg choice="opt"><replaceable class="parameter">dbname</replaceable>
+ <arg choice="opt"><replaceable class="parameter">username</replaceable></arg></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>psql</application> is a terminal-based front-end to
+ <productname>PostgreSQL</productname>. It enables you to type in
+ queries interactively, issue them to
+ <productname>PostgreSQL</productname>, and see the query results.
+ Alternatively, input can be from a file or from command line
+ arguments. In addition, <application>psql</application> provides a
+ number of meta-commands and various shell-like features to
+ facilitate writing scripts and automating a wide variety of tasks.
+ </para>
+ </refsect1>
+
+ <refsect1 id="r1-app-psql-3">
+ <title>Options</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--echo-all</option></term>
+ <listitem>
+ <para>
+ Print all nonempty input lines to standard output as they are read.
+ (This does not apply to lines read interactively.) This is
+ equivalent to setting the variable <varname>ECHO</varname> to
+ <literal>all</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-A</option></term>
+ <term><option>--no-align</option></term>
+ <listitem>
+ <para>
+ Switches to unaligned output mode. (The default output mode is
+ <literal>aligned</literal>.) This is equivalent to
+ <command>\pset format unaligned</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-b</option></term>
+ <term><option>--echo-errors</option></term>
+ <listitem>
+ <para>
+ Print failed SQL commands to standard error output. This is
+ equivalent to setting the variable <varname>ECHO</varname> to
+ <literal>errors</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-c <replaceable class="parameter">command</replaceable></option></term>
+ <term><option>--command=<replaceable class="parameter">command</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies that <application>psql</application> is to execute the given
+ command string, <replaceable class="parameter">command</replaceable>.
+ This option can be repeated and combined in any order with
+ the <option>-f</option> option. When either <option>-c</option>
+ or <option>-f</option> is specified, <application>psql</application>
+ does not read commands from standard input; instead it terminates
+ after processing all the <option>-c</option> and <option>-f</option>
+ options in sequence.
+ </para>
+ <para>
+ <replaceable class="parameter">command</replaceable> must be either
+ a command string that is completely parsable by the server (i.e.,
+ it contains no <application>psql</application>-specific features),
+ or a single backslash command. Thus you cannot mix
+ <acronym>SQL</acronym> and <application>psql</application>
+ meta-commands within a <option>-c</option> option. To achieve that,
+ you could use repeated <option>-c</option> options or pipe the string
+ into <application>psql</application>, for example:
+<programlisting>
+psql -c '\x' -c 'SELECT * FROM foo;'
+</programlisting>
+ or
+<programlisting>
+echo '\x \\ SELECT * FROM foo;' | psql
+</programlisting>
+ (<literal>\\</literal> is the separator meta-command.)
+ </para>
+ <para>
+ Each <acronym>SQL</acronym> command string passed
+ to <option>-c</option> is sent to the server as a single request.
+ Because of this, the server executes it as a single transaction even
+ if the string contains multiple <acronym>SQL</acronym> commands,
+ unless there are explicit <command>BEGIN</command>/<command>COMMIT</command>
+ commands included in the string to divide it into multiple
+ transactions. (See <xref linkend="protocol-flow-multi-statement"/>
+ for more details about how the server handles multi-query strings.)
+ </para>
+ <para>
+ If having several commands executed in one transaction is not desired,
+ use repeated <option>-c</option> commands or feed multiple commands to
+ <application>psql</application>'s standard input,
+ either using <application>echo</application> as illustrated above, or
+ via a shell here-document, for example:
+<programlisting>
+psql &lt;&lt;EOF
+\x
+SELECT * FROM foo;
+EOF
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--csv</option></term>
+ <listitem>
+ <para>
+ Switches to <acronym>CSV</acronym> (Comma-Separated Values) output
+ mode. This is equivalent to <command>\pset format csv</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-d <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option>--dbname=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to. This is
+ equivalent to specifying <replaceable
+ class="parameter">dbname</replaceable> as the first non-option
+ argument on the command line. The <replaceable>dbname</replaceable>
+ can be a <link linkend="libpq-connstring">connection string</link>.
+ If so, connection string parameters will override any conflicting
+ command line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo-queries</option></term>
+ <listitem>
+ <para>
+ Copy all SQL commands sent to the server to standard output as well.
+ This is equivalent
+ to setting the variable <varname>ECHO</varname> to
+ <literal>queries</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-E</option></term>
+ <term><option>--echo-hidden</option></term>
+ <listitem>
+ <para>
+ Echo the actual queries generated by <command>\d</command> and other backslash
+ commands. You can use this to study <application>psql</application>'s
+ internal operations. This is equivalent to
+ setting the variable <varname>ECHO_HIDDEN</varname> to <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f <replaceable class="parameter">filename</replaceable></option></term>
+ <term><option>--file=<replaceable class="parameter">filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Read commands from the
+ file <replaceable class="parameter">filename</replaceable>,
+ rather than standard input.
+ This option can be repeated and combined in any order with
+ the <option>-c</option> option. When either <option>-c</option>
+ or <option>-f</option> is specified, <application>psql</application>
+ does not read commands from standard input; instead it terminates
+ after processing all the <option>-c</option> and <option>-f</option>
+ options in sequence.
+ Except for that, this option is largely equivalent to the
+ meta-command <command>\i</command>.
+ </para>
+
+ <para>
+ If <replaceable>filename</replaceable> is <literal>-</literal>
+ (hyphen), then standard input is read until an EOF indication
+ or <command>\q</command> meta-command. This can be used to intersperse
+ interactive input with input from files. Note however that Readline
+ is not used in this case (much as if <option>-n</option> had been
+ specified).
+ </para>
+
+ <para>
+ Using this option is subtly different from writing <literal>psql
+ &lt; <replaceable
+ class="parameter">filename</replaceable></literal>. In general,
+ both will do what you expect, but using <literal>-f</literal>
+ enables some nice features such as error messages with line
+ numbers. There is also a slight chance that using this option will
+ reduce the start-up overhead. On the other hand, the variant using
+ the shell's input redirection is (in theory) guaranteed to yield
+ exactly the same output you would have received had you entered
+ everything by hand.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F <replaceable class="parameter">separator</replaceable></option></term>
+ <term><option>--field-separator=<replaceable class="parameter">separator</replaceable></option></term>
+ <listitem>
+ <para>
+ Use <replaceable class="parameter">separator</replaceable> as the
+ field separator for unaligned output. This is equivalent to
+ <command>\pset fieldsep</command> or <command>\f</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">hostname</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">hostname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the
+ server is running. If the value begins
+ with a slash, it is used as the directory for the Unix-domain
+ socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-H</option></term>
+ <term><option>--html</option></term>
+ <listitem>
+ <para>
+ Switches to <acronym>HTML</acronym> output mode. This is
+ equivalent to <command>\pset format html</command> or the
+ <command>\H</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-l</option></term>
+ <term><option>--list</option></term>
+ <listitem>
+ <para>
+ List all available databases, then exit. Other non-connection
+ options are ignored. This is similar to the meta-command
+ <command>\list</command>.
+ </para>
+
+ <para>
+ When this option is used, <application>psql</application> will connect
+ to the database <literal>postgres</literal>, unless a different database
+ is named on the command line (option <option>-d</option> or non-option
+ argument, possibly via a service entry, but not via an environment
+ variable).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-L <replaceable class="parameter">filename</replaceable></option></term>
+ <term><option>--log-file=<replaceable class="parameter">filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Write all query output into file <replaceable
+ class="parameter">filename</replaceable>, in addition to the
+ normal output destination.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--no-readline</option></term>
+ <listitem>
+ <para>
+ Do not use <application>Readline</application> for line editing and
+ do not use the command history (see
+ <xref linkend="app-psql-readline"/> below).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-o <replaceable class="parameter">filename</replaceable></option></term>
+ <term><option>--output=<replaceable class="parameter">filename</replaceable></option></term>
+ <listitem>
+ <para>
+ Put all query output into file <replaceable
+ class="parameter">filename</replaceable>. This is equivalent to
+ the command <command>\o</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or the local Unix-domain
+ socket file extension on which the server is listening for
+ connections. Defaults to the value of the <envar>PGPORT</envar>
+ environment variable or, if not set, to the port specified at
+ compile time, usually 5432.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P <replaceable class="parameter">assignment</replaceable></option></term>
+ <term><option>--pset=<replaceable class="parameter">assignment</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies printing options, in the style of
+ <command>\pset</command>. Note that here you
+ have to separate name and value with an equal sign instead of a
+ space. For example, to set the output format to <application>LaTeX</application>, you could write
+ <literal>-P format=latex</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Specifies that <application>psql</application> should do its work
+ quietly. By default, it prints welcome messages and various
+ informational output. If this option is used, none of this
+ happens. This is useful with the <option>-c</option> option.
+ This is equivalent to setting the variable <varname>QUIET</varname>
+ to <literal>on</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-R <replaceable class="parameter">separator</replaceable></option></term>
+ <term><option>--record-separator=<replaceable class="parameter">separator</replaceable></option></term>
+ <listitem>
+ <para>
+ Use <replaceable class="parameter">separator</replaceable> as the
+ record separator for unaligned output. This is equivalent to
+ <command>\pset recordsep</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--single-step</option></term>
+ <listitem>
+ <para>
+ Run in single-step mode. That means the user is prompted before
+ each command is sent to the server, with the option to cancel
+ execution as well. Use this to debug scripts.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S</option></term>
+ <term><option>--single-line</option></term>
+ <listitem>
+ <para>
+ Runs in single-line mode where a newline terminates an SQL command, as a
+ semicolon does.
+ </para>
+
+ <note>
+ <para>
+ This mode is provided for those who insist on it, but you are not
+ necessarily encouraged to use it. In particular, if you mix
+ <acronym>SQL</acronym> and meta-commands on a line the order of
+ execution might not always be clear to the inexperienced user.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t</option></term>
+ <term><option>--tuples-only</option></term>
+ <listitem>
+ <para>
+ Turn off printing of column names and result row count footers,
+ etc. This is equivalent to <command>\t</command> or
+ <command>\pset tuples_only</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-T <replaceable class="parameter">table_options</replaceable></option></term>
+ <term><option>--table-attr=<replaceable class="parameter">table_options</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies options to be placed within the
+ <acronym>HTML</acronym> <sgmltag>table</sgmltag> tag. See
+ <command>\pset tableattr</command> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ Connect to the database as the user <replaceable
+ class="parameter">username</replaceable> instead of the default.
+ (You must have permission to do so, of course.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v <replaceable class="parameter">assignment</replaceable></option></term>
+ <term><option>--set=<replaceable class="parameter">assignment</replaceable></option></term>
+ <term><option>--variable=<replaceable class="parameter">assignment</replaceable></option></term>
+ <listitem>
+ <para>
+ Perform a variable assignment, like the <command>\set</command>
+ meta-command. Note that you must separate name and value, if
+ any, by an equal sign on the command line. To unset a variable,
+ leave off the equal sign. To set a variable with an empty value,
+ use the equal sign but leave off the value. These assignments are
+ done during command line processing, so variables that reflect
+ connection state will get overwritten later.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>psql</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires password
+ authentication and a password is not available from other sources
+ such as a <filename>.pgpass</filename> file, the connection
+ attempt will fail. This option can be useful in batch jobs and
+ scripts where no user is present to enter a password.
+ </para>
+
+ <para>
+ Note that this option will remain set for the entire session,
+ and so it affects uses of the meta-command
+ <command>\connect</command> as well as the initial connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>psql</application> to prompt for a
+ password before connecting to a database, even if the password will
+ not be used.
+ </para>
+
+ <para>
+ If the server requires password authentication and a password is not
+ available from other sources such as a <filename>.pgpass</filename>
+ file, <application>psql</application> will prompt for a
+ password in any case. However, <application>psql</application>
+ will waste a connection attempt finding out that the server wants a
+ password. In some cases it is worth typing <option>-W</option> to avoid
+ the extra connection attempt.
+ </para>
+
+ <para>
+ Note that this option will remain set for the entire session,
+ and so it affects uses of the meta-command
+ <command>\connect</command> as well as the initial connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-x</option></term>
+ <term><option>--expanded</option></term>
+ <listitem>
+ <para>
+ Turn on the expanded table formatting mode. This is equivalent to
+ <command>\x</command> or <command>\pset expanded</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-X,</option></term>
+ <term><option>--no-psqlrc</option></term>
+ <listitem>
+ <para>
+ Do not read the start-up file (neither the system-wide
+ <filename>psqlrc</filename> file nor the user's
+ <filename>~/.psqlrc</filename> file).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-z</option></term>
+ <term><option>--field-separator-zero</option></term>
+ <listitem>
+ <para>
+ Set the field separator for unaligned output to a zero byte. This is
+ equivalent to <command>\pset fieldsep_zero</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-0</option></term>
+ <term><option>--record-separator-zero</option></term>
+ <listitem>
+ <para>
+ Set the record separator for unaligned output to a zero byte. This is
+ useful for interfacing, for example, with <literal>xargs -0</literal>.
+ This is equivalent to <command>\pset recordsep_zero</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-1</option></term>
+ <term><option>--single-transaction</option></term>
+ <listitem>
+ <para>
+ This option can only be used in combination with one or more
+ <option>-c</option> and/or <option>-f</option> options. It causes
+ <application>psql</application> to issue a <command>BEGIN</command> command
+ before the first such option and a <command>COMMIT</command> command after
+ the last one, thereby wrapping all the commands into a single
+ transaction. If any of the commands fails and the variable
+ <varname>ON_ERROR_STOP</varname> was set, a
+ <command>ROLLBACK</command> command is sent instead. This ensures that
+ either all the commands complete successfully, or no changes are
+ applied.
+ </para>
+
+ <para>
+ If the commands themselves
+ contain <command>BEGIN</command>, <command>COMMIT</command>,
+ or <command>ROLLBACK</command>, this option will not have the desired
+ effects. Also, if an individual command cannot be executed inside a
+ transaction block, specifying this option will cause the whole
+ transaction to fail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help[=<replaceable class="parameter">topic</replaceable>]</option></term>
+ <listitem>
+ <para>
+ Show help about <application>psql</application> and exit. The optional
+ <replaceable class="parameter">topic</replaceable> parameter (defaulting
+ to <literal>options</literal>) selects which part of <application>psql</application> is
+ explained: <literal>commands</literal> describes <application>psql</application>'s
+ backslash commands; <literal>options</literal> describes the command-line
+ options that can be passed to <application>psql</application>;
+ and <literal>variables</literal> shows help about <application>psql</application> configuration
+ variables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Exit Status</title>
+
+ <para>
+ <application>psql</application> returns 0 to the shell if it
+ finished normally, 1 if a fatal error of its own occurs (e.g., out of memory,
+ file not found), 2 if the connection to the server went bad
+ and the session was not interactive, and 3 if an error occurred in a
+ script and the variable <varname>ON_ERROR_STOP</varname> was set.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Usage</title>
+
+ <refsect2 id="r2-app-psql-connecting">
+ <title>Connecting to a Database</title>
+
+ <para>
+ <application>psql</application> is a regular
+ <productname>PostgreSQL</productname> client application. In order
+ to connect to a database you need to know the name of your target
+ database, the host name and port number of the server, and what user
+ name you want to connect as. <application>psql</application> can be
+ told about those parameters via command line options, namely
+ <option>-d</option>, <option>-h</option>, <option>-p</option>, and
+ <option>-U</option> respectively. If an argument is found that does
+ not belong to any option it will be interpreted as the database name
+ (or the user name, if the database name is already given). Not all
+ of these options are required; there are useful defaults. If you omit the host
+ name, <application>psql</application> will connect via a Unix-domain socket
+ to a server on the local host, or via TCP/IP to <literal>localhost</literal> on
+ machines that don't have Unix-domain sockets. The default port number is
+ determined at compile time.
+ Since the database server uses the same default, you will not have
+ to specify the port in most cases. The default user name is your
+ operating-system user name, as is the default database name.
+ Note that you cannot
+ just connect to any database under any user name. Your database
+ administrator should have informed you about your access rights.
+ </para>
+
+ <para>
+ When the defaults aren't quite right, you can save yourself
+ some typing by setting the environment variables
+ <envar>PGDATABASE</envar>, <envar>PGHOST</envar>,
+ <envar>PGPORT</envar> and/or <envar>PGUSER</envar> to appropriate
+ values. (For additional environment variables, see <xref
+ linkend="libpq-envars"/>.) It is also convenient to have a
+ <filename>~/.pgpass</filename> file to avoid regularly having to type in
+ passwords. See <xref linkend="libpq-pgpass"/> for more information.
+ </para>
+
+ <para>
+ An alternative way to specify connection parameters is in a
+ <parameter>conninfo</parameter> string or
+ a <acronym>URI</acronym>, which is used instead of a database
+ name. This mechanism give you very wide control over the
+ connection. For example:
+<programlisting>
+$ <userinput>psql "service=myservice sslmode=require"</userinput>
+$ <userinput>psql postgresql://dbmaster:5433/mydb?sslmode=require</userinput>
+</programlisting>
+ This way you can also use <acronym>LDAP</acronym> for connection
+ parameter lookup as described in <xref linkend="libpq-ldap"/>.
+ See <xref linkend="libpq-paramkeywords"/> for more information on all the
+ available connection options.
+ </para>
+
+ <para>
+ If the connection could not be made for any reason (e.g., insufficient
+ privileges, server is not running on the targeted host, etc.),
+ <application>psql</application> will return an error and terminate.
+ </para>
+
+ <para>
+ If both standard input and standard output are a
+ terminal, then <application>psql</application> sets the client
+ encoding to <quote>auto</quote>, which will detect the
+ appropriate client encoding from the locale settings
+ (<envar>LC_CTYPE</envar> environment variable on Unix systems).
+ If this doesn't work out as expected, the client encoding can be
+ overridden using the environment
+ variable <envar>PGCLIENTENCODING</envar>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="r2-app-psql-4">
+ <title>Entering SQL Commands</title>
+
+ <para>
+ In normal operation, <application>psql</application> provides a
+ prompt with the name of the database to which
+ <application>psql</application> is currently connected, followed by
+ the string <literal>=&gt;</literal>. For example:
+<programlisting>
+$ <userinput>psql testdb</userinput>
+psql (&version;)
+Type "help" for help.
+
+testdb=&gt;
+</programlisting>
+ </para>
+
+ <para>
+ At the prompt, the user can type in <acronym>SQL</acronym> commands.
+ Ordinarily, input lines are sent to the server when a
+ command-terminating semicolon is reached. An end of line does not
+ terminate a command. Thus commands can be spread over several lines for
+ clarity. If the command was sent and executed without error, the results
+ of the command are displayed on the screen.
+ </para>
+
+ <para>
+ If untrusted users have access to a database that has not adopted a
+ <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>,
+ begin your session by removing publicly-writable schemas
+ from <varname>search_path</varname>. One can
+ add <literal>options=-csearch_path=</literal> to the connection string or
+ issue <literal>SELECT pg_catalog.set_config('search_path', '',
+ false)</literal> before other SQL commands. This consideration is not
+ specific to <application>psql</application>; it applies to every interface
+ for executing arbitrary SQL commands.
+ </para>
+
+ <para>
+ Whenever a command is executed, <application>psql</application> also polls
+ for asynchronous notification events generated by
+ <link linkend="sql-listen"><command>LISTEN</command></link> and
+ <link linkend="sql-notify"><command>NOTIFY</command></link>.
+ </para>
+
+ <para>
+ While C-style block comments are passed to the server for
+ processing and removal, SQL-standard comments are removed by
+ <application>psql</application>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="app-psql-meta-commands">
+ <title>Meta-Commands</title>
+
+ <para>
+ Anything you enter in <application>psql</application> that begins
+ with an unquoted backslash is a <application>psql</application>
+ meta-command that is processed by <application>psql</application>
+ itself. These commands make
+ <application>psql</application> more useful for administration or
+ scripting. Meta-commands are often called slash or backslash commands.
+ </para>
+
+ <para>
+ The format of a <application>psql</application> command is the backslash,
+ followed immediately by a command verb, then any arguments. The arguments
+ are separated from the command verb and each other by any number of
+ whitespace characters.
+ </para>
+
+ <para>
+ To include whitespace in an argument you can quote it with
+ single quotes. To include a single quote in an argument,
+ write two single quotes within single-quoted text.
+ Anything contained in single quotes is
+ furthermore subject to C-like substitutions for
+ <literal>\n</literal> (new line), <literal>\t</literal> (tab),
+ <literal>\b</literal> (backspace), <literal>\r</literal> (carriage return),
+ <literal>\f</literal> (form feed),
+ <literal>\</literal><replaceable>digits</replaceable> (octal), and
+ <literal>\x</literal><replaceable>digits</replaceable> (hexadecimal).
+ A backslash preceding any other character within single-quoted text
+ quotes that single character, whatever it is.
+ </para>
+
+ <para>
+ If an unquoted colon (<literal>:</literal>) followed by a
+ <application>psql</application> variable name appears within an argument, it is
+ replaced by the variable's value, as described in <xref
+ linkend="app-psql-interpolation"/> below.
+ The forms <literal>:'<replaceable>variable_name</replaceable>'</literal> and
+ <literal>:"<replaceable>variable_name</replaceable>"</literal> described there
+ work as well.
+ The <literal>:{?<replaceable>variable_name</replaceable>}</literal> syntax allows
+ testing whether a variable is defined. It is substituted by
+ TRUE or FALSE.
+ Escaping the colon with a backslash protects it from substitution.
+ </para>
+
+ <para>
+ Within an argument, text that is enclosed in backquotes
+ (<literal>`</literal>) is taken as a command line that is passed to the
+ shell. The output of the command (with any trailing newline removed)
+ replaces the backquoted text. Within the text enclosed in backquotes,
+ no special quoting or other processing occurs, except that appearances
+ of <literal>:<replaceable>variable_name</replaceable></literal> where
+ <replaceable>variable_name</replaceable> is a <application>psql</application> variable name
+ are replaced by the variable's value. Also, appearances of
+ <literal>:'<replaceable>variable_name</replaceable>'</literal> are replaced by the
+ variable's value suitably quoted to become a single shell command
+ argument. (The latter form is almost always preferable, unless you are
+ very sure of what is in the variable.) Because carriage return and line
+ feed characters cannot be safely quoted on all platforms, the
+ <literal>:'<replaceable>variable_name</replaceable>'</literal> form prints an
+ error message and does not substitute the variable value when such
+ characters appear in the value.
+ </para>
+
+ <para>
+ Some commands take an <acronym>SQL</acronym> identifier (such as a
+ table name) as argument. These arguments follow the syntax rules
+ of <acronym>SQL</acronym>: Unquoted letters are forced to
+ lowercase, while double quotes (<literal>"</literal>) protect letters
+ from case conversion and allow incorporation of whitespace into
+ the identifier. Within double quotes, paired double quotes reduce
+ to a single double quote in the resulting name. For example,
+ <literal>FOO"BAR"BAZ</literal> is interpreted as <literal>fooBARbaz</literal>,
+ and <literal>"A weird"" name"</literal> becomes <literal>A weird"
+ name</literal>.
+ </para>
+
+ <para>
+ Parsing for arguments stops at the end of the line, or when another
+ unquoted backslash is found. An unquoted backslash
+ is taken as the beginning of a new meta-command. The special
+ sequence <literal>\\</literal> (two backslashes) marks the end of
+ arguments and continues parsing <acronym>SQL</acronym> commands, if
+ any. That way <acronym>SQL</acronym> and
+ <application>psql</application> commands can be freely mixed on a
+ line. But in any case, the arguments of a meta-command cannot
+ continue beyond the end of the line.
+ </para>
+
+ <para>
+ Many of the meta-commands act on the <firstterm>current query buffer</firstterm>.
+ This is simply a buffer holding whatever SQL command text has been typed
+ but not yet sent to the server for execution. This will include previous
+ input lines as well as any text appearing before the meta-command on the
+ same line.
+ </para>
+
+ <para>
+ The following meta-commands are defined:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>\a</literal></term>
+ <listitem>
+ <para>
+ If the current table output format is unaligned, it is switched to aligned.
+ If it is not unaligned, it is set to unaligned. This command is
+ kept for backwards compatibility. See <command>\pset</command> for a
+ more general solution.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\c</literal> or <literal>\connect [ -reuse-previous=<replaceable class="parameter">on|off</replaceable> ] [ <replaceable class="parameter">dbname</replaceable> [ <replaceable class="parameter">username</replaceable> ] [ <replaceable class="parameter">host</replaceable> ] [ <replaceable class="parameter">port</replaceable> ] | <replaceable class="parameter">conninfo</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Establishes a new connection to a <productname>PostgreSQL</productname>
+ server. The connection parameters to use can be specified either
+ using a positional syntax (one or more of database name, user,
+ host, and port), or using a <replaceable>conninfo</replaceable>
+ connection string as detailed in
+ <xref linkend="libpq-connstring"/>. If no arguments are given, a
+ new connection is made using the same parameters as before.
+ </para>
+
+ <para>
+ Specifying any
+ of <replaceable class="parameter">dbname</replaceable>,
+ <replaceable class="parameter">username</replaceable>,
+ <replaceable class="parameter">host</replaceable> or
+ <replaceable class="parameter">port</replaceable>
+ as <literal>-</literal> is equivalent to omitting that parameter.
+ </para>
+
+ <para>
+ The new connection can re-use connection parameters from the previous
+ connection; not only database name, user, host, and port, but other
+ settings such as <replaceable>sslmode</replaceable>. By default,
+ parameters are re-used in the positional syntax, but not when
+ a <replaceable>conninfo</replaceable> string is given. Passing a
+ first argument of <literal>-reuse-previous=on</literal>
+ or <literal>-reuse-previous=off</literal> overrides that default. If
+ parameters are re-used, then any parameter not explicitly specified as
+ a positional parameter or in the <replaceable>conninfo</replaceable>
+ string is taken from the existing connection's parameters. An
+ exception is that if the <replaceable>host</replaceable> setting
+ is changed from its previous value using the positional syntax,
+ any <replaceable>hostaddr</replaceable> setting present in the
+ existing connection's parameters is dropped.
+ Also, any password used for the existing connection will be re-used
+ only if the user, host, and port settings are not changed.
+ When the command neither specifies nor reuses a particular parameter,
+ the <application>libpq</application> default is used.
+ </para>
+
+ <para>
+ If the new connection is successfully made, the previous
+ connection is closed.
+ If the connection attempt fails (wrong user name, access
+ denied, etc.), the previous connection will be kept if
+ <application>psql</application> is in interactive mode. But when
+ executing a non-interactive script, the old connection is closed
+ and an error is reported. That may or may not terminate the
+ script; if it does not, all database-accessing commands will fail
+ until another <literal>\connect</literal> command is successfully
+ executed. This distinction was chosen as
+ a user convenience against typos on the one hand, and a safety
+ mechanism that scripts are not accidentally acting on the
+ wrong database on the other hand.
+ Note that whenever a <literal>\connect</literal> command attempts
+ to re-use parameters, the values re-used are those of the last
+ successful connection, not of any failed attempts made subsequently.
+ However, in the case of a
+ non-interactive <literal>\connect</literal> failure, no parameters
+ are allowed to be re-used later, since the script would likely be
+ expecting the values from the failed <literal>\connect</literal>
+ to be re-used.
+ </para>
+
+ <para>
+ Examples:
+ </para>
+<programlisting>
+=&gt; \c mydb myuser host.dom 6432
+=&gt; \c service=foo
+=&gt; \c "host=localhost port=5432 dbname=mydb connect_timeout=10 sslmode=disable"
+=&gt; \c -reuse-previous=on sslmode=require -- changes only sslmode
+=&gt; \c postgresql://tom@localhost/mydb?application_name=myapp
+</programlisting>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\C [ <replaceable class="parameter">title</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Sets the title of any tables being printed as the result of a
+ query or unset any such title. This command is equivalent to
+ <literal>\pset title <replaceable
+ class="parameter">title</replaceable></literal>. (The name of
+ this command derives from <quote>caption</quote>, as it was
+ previously only used to set the caption in an
+ <acronym>HTML</acronym> table.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\cd [ <replaceable>directory</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Changes the current working directory to
+ <replaceable>directory</replaceable>. Without argument, changes
+ to the current user's home directory.
+ </para>
+
+ <tip>
+ <para>
+ To print your current working directory, use <literal>\! pwd</literal>.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\conninfo</literal></term>
+ <listitem>
+ <para>
+ Outputs information about the current database connection.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="app-psql-meta-commands-copy">
+ <term><literal>\copy { <replaceable class="parameter">table</replaceable> [ ( <replaceable class="parameter">column_list</replaceable> ) ] }
+ <literal>from</literal>
+ { <replaceable class="parameter">'filename'</replaceable> | program <replaceable class="parameter">'command'</replaceable> | stdin | pstdin }
+ [ [ with ] ( <replaceable class="parameter">option</replaceable> [, ...] ) ]
+ [ where <replaceable class="parameter">condition</replaceable> ]</literal></term>
+
+ <term><literal>\copy { <replaceable class="parameter">table</replaceable> [ ( <replaceable class="parameter">column_list</replaceable> ) ] | ( <replaceable class="parameter">query</replaceable> ) }
+ <literal>to</literal>
+ { <replaceable class="parameter">'filename'</replaceable> | program <replaceable class="parameter">'command'</replaceable> | stdout | pstdout }
+ [ [ with ] ( <replaceable class="parameter">option</replaceable> [, ...] ) ]</literal></term>
+
+ <listitem>
+ <para>
+ Performs a frontend (client) copy. This is an operation that
+ runs an <acronym>SQL</acronym> <link linkend="sql-copy"><command>COPY</command></link>
+ command, but instead of the server
+ reading or writing the specified file,
+ <application>psql</application> reads or writes the file and
+ routes the data between the server and the local file system.
+ This means that file accessibility and privileges are those of
+ the local user, not the server, and no SQL superuser
+ privileges are required.
+ </para>
+
+ <para>
+ When <literal>program</literal> is specified,
+ <replaceable class="parameter">command</replaceable> is
+ executed by <application>psql</application> and the data passed from
+ or to <replaceable class="parameter">command</replaceable> is
+ routed between the server and the client.
+ Again, the execution privileges are those of
+ the local user, not the server, and no SQL superuser
+ privileges are required.
+ </para>
+
+ <para>
+ For <literal>\copy ... from stdin</literal>, data rows are read from the same
+ source that issued the command, continuing until <literal>\.</literal>
+ is read or the stream reaches <acronym>EOF</acronym>. This option is useful
+ for populating tables in-line within an SQL script file.
+ For <literal>\copy ... to stdout</literal>, output is sent to the same place
+ as <application>psql</application> command output, and
+ the <literal>COPY <replaceable>count</replaceable></literal> command status is
+ not printed (since it might be confused with a data row).
+ To read/write <application>psql</application>'s standard input or
+ output regardless of the current command source or <literal>\o</literal>
+ option, write <literal>from pstdin</literal> or <literal>to pstdout</literal>.
+ </para>
+
+ <para>
+ The syntax of this command is similar to that of the
+ <acronym>SQL</acronym> <link linkend="sql-copy"><command>COPY</command></link>
+ command. All options other than the data source/destination are
+ as specified for <command>COPY</command>.
+ Because of this, special parsing rules apply to the <command>\copy</command>
+ meta-command. Unlike most other meta-commands, the entire remainder
+ of the line is always taken to be the arguments of <command>\copy</command>,
+ and neither variable interpolation nor backquote expansion are
+ performed in the arguments.
+ </para>
+
+ <tip>
+ <para>
+ Another way to obtain the same result as <literal>\copy
+ ... to</literal> is to use the <acronym>SQL</acronym> <literal>COPY
+ ... TO STDOUT</literal> command and terminate it
+ with <literal>\g <replaceable>filename</replaceable></literal>
+ or <literal>\g |<replaceable>program</replaceable></literal>.
+ Unlike <literal>\copy</literal>, this method allows the command to
+ span multiple lines; also, variable interpolation and backquote
+ expansion can be used.
+ </para>
+ </tip>
+
+ <tip>
+ <para>
+ These operations are not as efficient as the <acronym>SQL</acronym>
+ <command>COPY</command> command with a file or program data source or
+ destination, because all data must pass through the client/server
+ connection. For large amounts of data the <acronym>SQL</acronym>
+ command might be preferable.
+ </para>
+ </tip>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\copyright</literal></term>
+ <listitem>
+ <para>
+ Shows the copyright and distribution terms of
+ <productname>PostgreSQL</productname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="app-psql-meta-commands-crosstabview">
+ <term><literal>\crosstabview [
+ <replaceable class="parameter">colV</replaceable>
+ [ <replaceable class="parameter">colH</replaceable>
+ [ <replaceable class="parameter">colD</replaceable>
+ [ <replaceable class="parameter">sortcolH</replaceable>
+ ] ] ] ] </literal></term>
+ <listitem>
+ <para>
+ Executes the current query buffer (like <literal>\g</literal>) and
+ shows the results in a crosstab grid.
+ The query must return at least three columns.
+ The output column identified by <replaceable class="parameter">colV</replaceable>
+ becomes a vertical header and the output column identified by
+ <replaceable class="parameter">colH</replaceable>
+ becomes a horizontal header.
+ <replaceable class="parameter">colD</replaceable> identifies
+ the output column to display within the grid.
+ <replaceable class="parameter">sortcolH</replaceable> identifies
+ an optional sort column for the horizontal header.
+ </para>
+
+ <para>
+ Each column specification can be a column number (starting at 1) or
+ a column name. The usual SQL case folding and quoting rules apply to
+ column names. If omitted,
+ <replaceable class="parameter">colV</replaceable> is taken as column 1
+ and <replaceable class="parameter">colH</replaceable> as column 2.
+ <replaceable class="parameter">colH</replaceable> must differ from
+ <replaceable class="parameter">colV</replaceable>.
+ If <replaceable class="parameter">colD</replaceable> is not
+ specified, then there must be exactly three columns in the query
+ result, and the column that is neither
+ <replaceable class="parameter">colV</replaceable> nor
+ <replaceable class="parameter">colH</replaceable>
+ is taken to be <replaceable class="parameter">colD</replaceable>.
+ </para>
+
+ <para>
+ The vertical header, displayed as the leftmost column, contains the
+ values found in column <replaceable class="parameter">colV</replaceable>, in the
+ same order as in the query results, but with duplicates removed.
+ </para>
+
+ <para>
+ The horizontal header, displayed as the first row, contains the values
+ found in column <replaceable class="parameter">colH</replaceable>,
+ with duplicates removed. By default, these appear in the same order
+ as in the query results. But if the
+ optional <replaceable class="parameter">sortcolH</replaceable> argument is given,
+ it identifies a column whose values must be integer numbers, and the
+ values from <replaceable class="parameter">colH</replaceable> will
+ appear in the horizontal header sorted according to the
+ corresponding <replaceable class="parameter">sortcolH</replaceable> values.
+ </para>
+
+ <para>
+ Inside the crosstab grid, for each distinct value <literal>x</literal>
+ of <replaceable class="parameter">colH</replaceable> and each distinct
+ value <literal>y</literal>
+ of <replaceable class="parameter">colV</replaceable>, the cell located
+ at the intersection <literal>(x,y)</literal> contains the value of
+ the <literal>colD</literal> column in the query result row for which
+ the value of <replaceable class="parameter">colH</replaceable>
+ is <literal>x</literal> and the value
+ of <replaceable class="parameter">colV</replaceable>
+ is <literal>y</literal>. If there is no such row, the cell is empty. If
+ there are multiple such rows, an error is reported.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\d[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+
+ <listitem>
+ <para>
+ For each relation (table, view, materialized view, index, sequence,
+ or foreign table)
+ or composite type matching the
+ <replaceable class="parameter">pattern</replaceable>, show all
+ columns, their types, the tablespace (if not the default) and any
+ special attributes such as <literal>NOT NULL</literal> or defaults.
+ Associated indexes, constraints, rules, and triggers are
+ also shown. For foreign tables, the associated foreign
+ server is shown as well.
+ (<quote>Matching the pattern</quote> is defined in
+ <xref linkend="app-psql-patterns"/> below.)
+ </para>
+
+ <para>
+ For some types of relation, <literal>\d</literal> shows additional information
+ for each column: column values for sequences, indexed expressions for
+ indexes, and foreign data wrapper options for foreign tables.
+ </para>
+
+ <para>
+ The command form <literal>\d+</literal> is identical, except that
+ more information is displayed: any comments associated with the
+ columns of the table are shown, as is the presence of OIDs in the
+ table, the view definition if the relation is a view, a non-default
+ <link linkend="sql-altertable-replica-identity">replica
+ identity</link> setting and the
+ <link linkend="sql-create-access-method">access method</link> name
+ if the relation has an access method.
+ </para>
+
+ <para>
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ </para>
+
+ <note>
+ <para>
+ If <command>\d</command> is used without a
+ <replaceable class="parameter">pattern</replaceable> argument, it is
+ equivalent to <command>\dtvmsE</command> which will show a list of
+ all visible tables, views, materialized views, sequences and
+ foreign tables.
+ This is purely a convenience measure.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\da[S] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+
+ <listitem>
+ <para>
+ Lists aggregate functions, together with their
+ return type and the data types they operate on. If <replaceable
+ class="parameter">pattern</replaceable>
+ is specified, only aggregates whose names match the pattern are shown.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dA[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+
+ <listitem>
+ <para>
+ Lists access methods. If <replaceable
+ class="parameter">pattern</replaceable> is specified, only access
+ methods whose names match the pattern are shown. If
+ <literal>+</literal> is appended to the command name, each access
+ method is listed with its associated handler function and description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\dAc[+]
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">access-method-pattern</replaceable></link>
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">input-type-pattern</replaceable></link>]]
+ </literal>
+ </term>
+ <listitem>
+ <para>
+ Lists operator classes
+ (see <xref linkend="xindex-opclass"/>).
+ If <replaceable class="parameter">access-method-pattern</replaceable>
+ is specified, only operator classes associated with access methods whose
+ names match that pattern are listed.
+ If <replaceable class="parameter">input-type-pattern</replaceable>
+ is specified, only operator classes associated with input types whose
+ names match that pattern are listed.
+ If <literal>+</literal> is appended to the command name, each operator
+ class is listed with its associated operator family and owner.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\dAf[+]
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">access-method-pattern</replaceable></link>
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">input-type-pattern</replaceable></link>]]
+ </literal>
+ </term>
+ <listitem>
+ <para>
+ Lists operator families
+ (see <xref linkend="xindex-opfamily"/>).
+ If <replaceable class="parameter">access-method-pattern</replaceable>
+ is specified, only operator families associated with access methods whose
+ names match that pattern are listed.
+ If <replaceable class="parameter">input-type-pattern</replaceable>
+ is specified, only operator families associated with input types whose
+ names match that pattern are listed.
+ If <literal>+</literal> is appended to the command name, each operator
+ family is listed with its owner.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\dAo[+]
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">access-method-pattern</replaceable></link>
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">operator-family-pattern</replaceable></link>]]
+ </literal>
+ </term>
+
+ <listitem>
+ <para>
+ Lists operators associated with operator families
+ (see <xref linkend="xindex-strategies"/>).
+ If <replaceable class="parameter">access-method-pattern</replaceable>
+ is specified, only members of operator families associated with access
+ methods whose names match that pattern are listed.
+ If <replaceable class="parameter">operator-family-pattern</replaceable>
+ is specified, only members of operator families whose names match that
+ pattern are listed.
+ If <literal>+</literal> is appended to the command name, each operator
+ is listed with its sort operator family (if it is an ordering operator).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <literal>\dAp[+]
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">access-method-pattern</replaceable></link>
+ [<link linkend="app-psql-patterns"><replaceable class="parameter">operator-family-pattern</replaceable></link>]]
+ </literal>
+ </term>
+ <listitem>
+ <para>
+ Lists support functions associated with operator families
+ (see <xref linkend="xindex-support"/>).
+ If <replaceable class="parameter">access-method-pattern</replaceable>
+ is specified, only functions of operator families associated with
+ access methods whose names match that pattern are listed.
+ If <replaceable class="parameter">operator-family-pattern</replaceable>
+ is specified, only functions of operator families whose names match
+ that pattern are listed.
+ If <literal>+</literal> is appended to the command name, functions are
+ displayed verbosely, with their actual parameter lists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\db[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+
+ <listitem>
+ <para>
+ Lists tablespaces. If <replaceable
+ class="parameter">pattern</replaceable>
+ is specified, only tablespaces whose names match the pattern are shown.
+ If <literal>+</literal> is appended to the command name, each tablespace
+ is listed with its associated options, on-disk size, permissions and
+ description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dc[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists conversions between character-set encodings.
+ If <replaceable class="parameter">pattern</replaceable>
+ is specified, only conversions whose names match the pattern are
+ listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ If <literal>+</literal> is appended to the command name, each object
+ is listed with its associated description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dconfig[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists server configuration parameters and their values.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only parameters whose names match the pattern are listed. Without
+ a <replaceable class="parameter">pattern</replaceable>, only
+ parameters that are set to non-default values are listed.
+ (Use <literal>\dconfig *</literal> to see all parameters.)
+ If <literal>+</literal> is appended to the command name, each
+ parameter is listed with its data type, context in which the
+ parameter can be set, and access privileges (if non-default access
+ privileges have been granted).
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dC[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists type casts.
+ If <replaceable class="parameter">pattern</replaceable>
+ is specified, only casts whose source or target types match the
+ pattern are listed.
+ If <literal>+</literal> is appended to the command name, each object
+ is listed with its associated description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dd[S] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Shows the descriptions of objects of type <literal>constraint</literal>,
+ <literal>operator class</literal>, <literal>operator family</literal>,
+ <literal>rule</literal>, and <literal>trigger</literal>. All
+ other comments may be viewed by the respective backslash commands for
+ those object types.
+ </para>
+
+ <para><literal>\dd</literal> displays descriptions for objects matching the
+ <replaceable class="parameter">pattern</replaceable>, or of visible
+ objects of the appropriate type if no argument is given. But in either
+ case, only objects that have a description are listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ </para>
+
+ <para>
+ Descriptions for objects can be created with the <link
+ linkend="sql-comment"><command>COMMENT</command></link>
+ <acronym>SQL</acronym> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dD[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists domains. If <replaceable
+ class="parameter">pattern</replaceable>
+ is specified, only domains whose names match the pattern are shown.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ If <literal>+</literal> is appended to the command name, each object
+ is listed with its associated permissions and description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\ddp [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists default access privilege settings. An entry is shown for
+ each role (and schema, if applicable) for which the default
+ privilege settings have been changed from the built-in defaults.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only entries whose role name or schema name matches
+ the pattern are listed.
+ </para>
+
+ <para>
+ The <link linkend="sql-alterdefaultprivileges"><command>ALTER DEFAULT
+ PRIVILEGES</command></link> command is used to set default access
+ privileges. The meaning of the privilege display is explained in
+ <xref linkend="ddl-priv"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dE[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <term><literal>\di[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <term><literal>\dm[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <term><literal>\ds[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <term><literal>\dt[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <term><literal>\dv[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+
+ <listitem>
+ <para>
+ In this group of commands, the letters <literal>E</literal>,
+ <literal>i</literal>, <literal>m</literal>, <literal>s</literal>,
+ <literal>t</literal>, and <literal>v</literal>
+ stand for foreign table, index, materialized view,
+ sequence, table, and view,
+ respectively.
+ You can specify any or all of
+ these letters, in any order, to obtain a listing of objects
+ of these types. For example, <literal>\dti</literal> lists
+ tables and indexes. If <literal>+</literal> is
+ appended to the command name, each object is listed with its
+ persistence status (permanent, temporary, or unlogged),
+ physical size on disk, and associated description if any.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only objects whose names match the pattern are listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\des[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists foreign servers (mnemonic: <quote>external
+ servers</quote>).
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only those servers whose name matches the pattern
+ are listed. If the form <literal>\des+</literal> is used, a
+ full description of each server is shown, including the
+ server's access privileges, type, version, options, and description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\det[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists foreign tables (mnemonic: <quote>external tables</quote>).
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only entries whose table name or schema name matches
+ the pattern are listed. If the form <literal>\det+</literal>
+ is used, generic options and the foreign table description
+ are also displayed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\deu[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists user mappings (mnemonic: <quote>external
+ users</quote>).
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only those mappings whose user names match the
+ pattern are listed. If the form <literal>\deu+</literal> is
+ used, additional information about each mapping is shown.
+ </para>
+
+ <caution>
+ <para>
+ <literal>\deu+</literal> might also display the user name and
+ password of the remote user, so care should be taken not to
+ disclose them.
+ </para>
+ </caution>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dew[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists foreign-data wrappers (mnemonic: <quote>external
+ wrappers</quote>).
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only those foreign-data wrappers whose name matches
+ the pattern are listed. If the form <literal>\dew+</literal>
+ is used, the access privileges, options, and description of the
+ foreign-data wrapper are also shown.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\df[anptwS+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> [ <replaceable class="parameter">arg_pattern</replaceable> ... ] ]</literal></term>
+
+ <listitem>
+ <para>
+ Lists functions, together with their result data types, argument data
+ types, and function types, which are classified as <quote>agg</quote>
+ (aggregate), <quote>normal</quote>, <quote>procedure</quote>, <quote>trigger</quote>, or <quote>window</quote>.
+ To display only functions
+ of specific type(s), add the corresponding letters <literal>a</literal>,
+ <literal>n</literal>, <literal>p</literal>, <literal>t</literal>, or <literal>w</literal> to the command.
+ If <replaceable
+ class="parameter">pattern</replaceable> is specified, only
+ functions whose names match the pattern are shown.
+ Any additional arguments are type-name patterns, which are matched
+ to the type names of the first, second, and so on arguments of the
+ function. (Matching functions can have more arguments than what
+ you specify. To prevent that, write a dash <literal>-</literal> as
+ the last <replaceable class="parameter">arg_pattern</replaceable>.)
+ By default, only user-created
+ objects are shown; supply a pattern or the <literal>S</literal>
+ modifier to include system objects.
+ If the form <literal>\df+</literal> is used, additional information
+ about each function is shown, including volatility,
+ parallel safety, owner, security classification, access privileges,
+ language, source code and description.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dF[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists text search configurations.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only configurations whose names match the pattern are shown.
+ If the form <literal>\dF+</literal> is used, a full description of
+ each configuration is shown, including the underlying text search
+ parser and the dictionary list for each parser token type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dFd[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists text search dictionaries.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only dictionaries whose names match the pattern are shown.
+ If the form <literal>\dFd+</literal> is used, additional information
+ is shown about each selected dictionary, including the underlying
+ text search template and the option values.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dFp[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists text search parsers.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only parsers whose names match the pattern are shown.
+ If the form <literal>\dFp+</literal> is used, a full description of
+ each parser is shown, including the underlying functions and the
+ list of recognized token types.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dFt[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists text search templates.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only templates whose names match the pattern are shown.
+ If the form <literal>\dFt+</literal> is used, additional information
+ is shown about each template, including the underlying function names.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dg[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists database roles.
+ (Since the concepts of <quote>users</quote> and <quote>groups</quote> have been
+ unified into <quote>roles</quote>, this command is now equivalent to
+ <literal>\du</literal>.)
+ By default, only user-created roles are shown; supply the
+ <literal>S</literal> modifier to include system roles.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only those roles whose names match the pattern are listed.
+ If the form <literal>\dg+</literal> is used, additional information
+ is shown about each role; currently this adds the comment for each
+ role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dl[+]</literal></term>
+ <listitem>
+ <para>
+ This is an alias for <command>\lo_list</command>, which shows a
+ list of large objects.
+ If <literal>+</literal> is appended to the command name,
+ each large object is listed with its associated permissions,
+ if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dL[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists procedural languages. If <replaceable
+ class="parameter">pattern</replaceable>
+ is specified, only languages whose names match the pattern are listed.
+ By default, only user-created languages
+ are shown; supply the <literal>S</literal> modifier to include system
+ objects. If <literal>+</literal> is appended to the command name, each
+ language is listed with its call handler, validator, access privileges,
+ and whether it is a system object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dn[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+
+ <listitem>
+ <para>
+ Lists schemas (namespaces). If <replaceable
+ class="parameter">pattern</replaceable>
+ is specified, only schemas whose names match the pattern are listed.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system objects.
+ If <literal>+</literal> is appended to the command name, each object
+ is listed with its associated permissions and description, if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\do[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> [ <replaceable class="parameter">arg_pattern</replaceable> [ <replaceable class="parameter">arg_pattern</replaceable> ] ] ]</literal></term>
+ <listitem>
+ <para>
+ Lists operators with their operand and result types.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only operators whose names match the pattern are listed.
+ If one <replaceable class="parameter">arg_pattern</replaceable> is
+ specified, only prefix operators whose right argument's type name
+ matches that pattern are listed.
+ If two <replaceable class="parameter">arg_pattern</replaceable>s
+ are specified, only binary operators whose argument type names match
+ those patterns are listed. (Alternatively, write <literal>-</literal>
+ for the unused argument of a unary operator.)
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ If <literal>+</literal> is appended to the command name,
+ additional information about each operator is shown, currently just
+ the name of the underlying function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dO[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists collations.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only collations whose names match the pattern are
+ listed. By default, only user-created objects are shown;
+ supply a pattern or the <literal>S</literal> modifier to
+ include system objects. If <literal>+</literal> is appended
+ to the command name, each collation is listed with its associated
+ description, if any.
+ Note that only collations usable with the current database's encoding
+ are shown, so the results may vary in different databases of the
+ same installation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dp [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists tables, views and sequences with their
+ associated access privileges.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only tables, views and sequences whose names match the
+ pattern are listed.
+ </para>
+
+ <para>
+ The <link linkend="sql-grant"><command>GRANT</command></link> and
+ <link linkend="sql-revoke"><command>REVOKE</command></link>
+ commands are used to set access privileges. The meaning of the
+ privilege display is explained in
+ <xref linkend="ddl-priv"/>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\dP[itn+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists partitioned relations.
+ If <replaceable class="parameter">pattern</replaceable>
+ is specified, only entries whose name matches the pattern are listed.
+ The modifiers <literal>t</literal> (tables) and <literal>i</literal>
+ (indexes) can be appended to the command, filtering the kind of
+ relations to list. By default, partitioned tables and indexes are
+ listed.
+ </para>
+
+ <para>
+ If the modifier <literal>n</literal> (<quote>nested</quote>) is used,
+ or a pattern is specified, then non-root partitioned relations are
+ included, and a column is shown displaying the parent of each
+ partitioned relation.
+ </para>
+
+ <para>
+ If <literal>+</literal> is appended to the command name, the sum of the
+ sizes of each relation's partitions is also displayed, along with the
+ relation's description.
+ If <literal>n</literal> is combined with <literal>+</literal>, two
+ sizes are shown: one including the total size of directly-attached
+ leaf partitions, and another showing the total size of all partitions,
+ including indirectly attached sub-partitions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\drds [ <link linkend="app-psql-patterns"><replaceable class="parameter">role-pattern</replaceable></link> [ <link linkend="app-psql-patterns"><replaceable class="parameter">database-pattern</replaceable></link> ] ]</literal></term>
+ <listitem>
+ <para>
+ Lists defined configuration settings. These settings can be
+ role-specific, database-specific, or both.
+ <replaceable>role-pattern</replaceable> and
+ <replaceable>database-pattern</replaceable> are used to select
+ specific roles and databases to list, respectively. If omitted, or if
+ <literal>*</literal> is specified, all settings are listed, including those
+ not role-specific or database-specific, respectively.
+ </para>
+
+ <para>
+ The <link linkend="sql-alterrole"><command>ALTER ROLE</command></link> and
+ <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>
+ commands are used to define per-role and per-database configuration
+ settings.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dRp[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists replication publications.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only those publications whose names match the pattern are
+ listed.
+ If <literal>+</literal> is appended to the command name, the tables and
+ schemas associated with each publication are shown as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dRs[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists replication subscriptions.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only those subscriptions whose names match the pattern are
+ listed.
+ If <literal>+</literal> is appended to the command name, additional
+ properties of the subscriptions are shown.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dT[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists data types.
+ If <replaceable class="parameter">pattern</replaceable> is
+ specified, only types whose names match the pattern are listed.
+ If <literal>+</literal> is appended to the command name, each type is
+ listed with its internal name and size, its allowed values
+ if it is an <type>enum</type> type, and its associated permissions.
+ By default, only user-created objects are shown; supply a
+ pattern or the <literal>S</literal> modifier to include system
+ objects.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\du[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists database roles.
+ (Since the concepts of <quote>users</quote> and <quote>groups</quote> have been
+ unified into <quote>roles</quote>, this command is now equivalent to
+ <literal>\dg</literal>.)
+ By default, only user-created roles are shown; supply the
+ <literal>S</literal> modifier to include system roles.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only those roles whose names match the pattern are listed.
+ If the form <literal>\du+</literal> is used, additional information
+ is shown about each role; currently this adds the comment for each
+ role.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dx[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists installed extensions.
+ If <replaceable class="parameter">pattern</replaceable>
+ is specified, only those extensions whose names match the pattern
+ are listed.
+ If the form <literal>\dx+</literal> is used, all the objects belonging
+ to each matching extension are listed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dX [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists extended statistics.
+ If <replaceable class="parameter">pattern</replaceable>
+ is specified, only those extended statistics whose names match the
+ pattern are listed.
+ </para>
+
+ <para>
+ The status of each kind of extended statistics is shown in a column
+ named after its statistic kind (e.g. Ndistinct).
+ <literal>defined</literal> means that it was requested when creating
+ the statistics, and NULL means it wasn't requested.
+ You can use <structname>pg_stats_ext</structname> if you'd like to
+ know whether <link linkend="sql-analyze"><command>ANALYZE</command></link>
+ was run and statistics are available to the planner.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dy[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists event triggers.
+ If <replaceable class="parameter">pattern</replaceable>
+ is specified, only those event triggers whose names match the pattern
+ are listed.
+ If <literal>+</literal> is appended to the command name, each object
+ is listed with its associated description.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\e</literal> or <literal>\edit</literal> <literal> <optional> <replaceable class="parameter">filename</replaceable> </optional> <optional> <replaceable class="parameter">line_number</replaceable> </optional> </literal></term>
+
+ <listitem>
+ <para>
+ If <replaceable class="parameter">filename</replaceable> is
+ specified, the file is edited; after the editor exits, the file's
+ content is copied into the current query buffer. If no <replaceable
+ class="parameter">filename</replaceable> is given, the current query
+ buffer is copied to a temporary file which is then edited in the same
+ fashion. Or, if the current query buffer is empty, the most recently
+ executed query is copied to a temporary file and edited in the same
+ fashion.
+ </para>
+
+ <para>
+ If you edit a file or the previous query, and you quit the editor without
+ modifying the file, the query buffer is cleared.
+ Otherwise, the new contents of the query buffer are re-parsed according to
+ the normal rules of <application>psql</application>, treating the
+ whole buffer as a single line. Any complete queries are immediately
+ executed; that is, if the query buffer contains or ends with a
+ semicolon, everything up to that point is executed and removed from
+ the query buffer. Whatever remains in the query buffer is
+ redisplayed. Type semicolon or <literal>\g</literal> to send it,
+ or <literal>\r</literal> to cancel it by clearing the query buffer.
+ </para>
+
+ <para>
+ Treating the buffer as a single line primarily affects meta-commands:
+ whatever is in the buffer after a meta-command will be taken as
+ argument(s) to the meta-command, even if it spans multiple lines.
+ (Thus you cannot make meta-command-using scripts this way.
+ Use <command>\i</command> for that.)
+ </para>
+
+ <para>
+ If a line number is specified, <application>psql</application> will
+ position the cursor on the specified line of the file or query buffer.
+ Note that if a single all-digits argument is given,
+ <application>psql</application> assumes it is a line number,
+ not a file name.
+ </para>
+
+ <tip>
+ <para>
+ See <xref linkend="app-psql-environment"/>, below, for how to
+ configure and customize your editor.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\echo <replaceable class="parameter">text</replaceable> [ ... ]</literal></term>
+ <listitem>
+ <para>
+ Prints the evaluated arguments to standard output, separated by
+ spaces and followed by a newline. This can be useful to
+ intersperse information in the output of scripts. For example:
+<programlisting>
+=&gt; <userinput>\echo `date`</userinput>
+Tue Oct 26 21:40:57 CEST 1999
+</programlisting>
+ If the first argument is an unquoted <literal>-n</literal> the trailing
+ newline is not written (nor is the first argument).
+ </para>
+
+ <tip>
+ <para>
+ If you use the <command>\o</command> command to redirect your
+ query output you might wish to use <command>\qecho</command>
+ instead of this command. See also <command>\warn</command>.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\ef <optional> <replaceable class="parameter">function_description</replaceable> <optional> <replaceable class="parameter">line_number</replaceable> </optional> </optional> </literal></term>
+
+ <listitem>
+ <para>
+ This command fetches and edits the definition of the named function or procedure,
+ in the form of a <command>CREATE OR REPLACE FUNCTION</command> or
+ <command>CREATE OR REPLACE PROCEDURE</command> command.
+ Editing is done in the same way as for <literal>\edit</literal>.
+ If you quit the editor without saving, the statement is discarded.
+ If you save and exit the editor, the updated command is executed immediately
+ if you added a semicolon to it. Otherwise it is redisplayed;
+ type semicolon or <literal>\g</literal> to send it, or <literal>\r</literal>
+ to cancel.
+ </para>
+
+ <para>
+ The target function can be specified by name alone, or by name
+ and arguments, for example <literal>foo(integer, text)</literal>.
+ The argument types must be given if there is more
+ than one function of the same name.
+ </para>
+
+ <para>
+ If no function is specified, a blank <command>CREATE FUNCTION</command>
+ template is presented for editing.
+ </para>
+
+ <para>
+ If a line number is specified, <application>psql</application> will
+ position the cursor on the specified line of the function body.
+ (Note that the function body typically does not begin on the first
+ line of the file.)
+ </para>
+
+ <para>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <command>\ef</command>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </para>
+
+ <tip>
+ <para>
+ See <xref linkend="app-psql-environment"/>, below, for how to
+ configure and customize your editor.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\encoding [ <replaceable class="parameter">encoding</replaceable> ]</literal></term>
+
+ <listitem>
+ <para>
+ Sets the client character set encoding. Without an argument, this command
+ shows the current encoding.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\errverbose</literal></term>
+
+ <listitem>
+ <para>
+ Repeats the most recent server error message at maximum
+ verbosity, as though <varname>VERBOSITY</varname> were set
+ to <literal>verbose</literal> and <varname>SHOW_CONTEXT</varname> were
+ set to <literal>always</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\ev <optional> <replaceable class="parameter">view_name</replaceable> <optional> <replaceable class="parameter">line_number</replaceable> </optional> </optional> </literal></term>
+
+ <listitem>
+ <para>
+ This command fetches and edits the definition of the named view,
+ in the form of a <command>CREATE OR REPLACE VIEW</command> command.
+ Editing is done in the same way as for <literal>\edit</literal>.
+ If you quit the editor without saving, the statement is discarded.
+ If you save and exit the editor, the updated command is executed immediately
+ if you added a semicolon to it. Otherwise it is redisplayed;
+ type semicolon or <literal>\g</literal> to send it, or <literal>\r</literal>
+ to cancel.
+ </para>
+
+ <para>
+ If no view is specified, a blank <command>CREATE VIEW</command>
+ template is presented for editing.
+ </para>
+
+ <para>
+ If a line number is specified, <application>psql</application> will
+ position the cursor on the specified line of the view definition.
+ </para>
+
+ <para>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <command>\ev</command>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\f [ <replaceable class="parameter">string</replaceable> ]</literal></term>
+
+ <listitem>
+ <para>
+ Sets the field separator for unaligned query output. The default
+ is the vertical bar (<literal>|</literal>). It is equivalent to
+ <command>\pset fieldsep</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\g [ (<replaceable class="parameter">option</replaceable>=<replaceable class="parameter">value</replaceable> [...]) ] [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
+ <term><literal>\g [ (<replaceable class="parameter">option</replaceable>=<replaceable class="parameter">value</replaceable> [...]) ] [ |<replaceable class="parameter">command</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Sends the current query buffer to the server for execution.
+ </para>
+ <para>
+ If parentheses appear after <literal>\g</literal>, they surround a
+ space-separated list
+ of <replaceable class="parameter">option</replaceable><literal>=</literal><replaceable class="parameter">value</replaceable>
+ formatting-option clauses, which are interpreted in the same way
+ as <literal>\pset</literal>
+ <replaceable class="parameter">option</replaceable>
+ <replaceable class="parameter">value</replaceable> commands, but take
+ effect only for the duration of this query. In this list, spaces are
+ not allowed around <literal>=</literal> signs, but are required
+ between option clauses.
+ If <literal>=</literal><replaceable class="parameter">value</replaceable>
+ is omitted, the
+ named <replaceable class="parameter">option</replaceable> is changed
+ in the same way as for
+ <literal>\pset</literal> <replaceable class="parameter">option</replaceable>
+ with no explicit <replaceable class="parameter">value</replaceable>.
+ </para>
+ <para>
+ If a <replaceable class="parameter">filename</replaceable>
+ or <literal>|</literal><replaceable class="parameter">command</replaceable>
+ argument is given, the query's output is written to the named
+ file or piped to the given shell command, instead of displaying it as
+ usual. The file or command is written to only if the query
+ successfully returns zero or more tuples, not if the query fails or
+ is a non-data-returning SQL command.
+ </para>
+ <para>
+ If the current query buffer is empty, the most recently sent query is
+ re-executed instead. Except for that behavior, <literal>\g</literal>
+ without any arguments is essentially equivalent to a semicolon.
+ With arguments, <literal>\g</literal> provides
+ a <quote>one-shot</quote> alternative to the <command>\o</command>
+ command, and additionally allows one-shot adjustments of the
+ output formatting options normally set by <literal>\pset</literal>.
+ </para>
+ <para>
+ When the last argument begins with <literal>|</literal>, the entire
+ remainder of the line is taken to be
+ the <replaceable class="parameter">command</replaceable> to execute,
+ and neither variable interpolation nor backquote expansion are
+ performed in it. The rest of the line is simply passed literally to
+ the shell.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\gdesc</literal></term>
+
+ <listitem>
+ <para>
+ Shows the description (that is, the column names and data types)
+ of the result of the current query buffer. The query is not
+ actually executed; however, if it contains some type of syntax
+ error, that error will be reported in the normal way.
+ </para>
+
+ <para>
+ If the current query buffer is empty, the most recently sent query
+ is described instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\getenv <replaceable class="parameter">psql_var</replaceable> <replaceable class="parameter">env_var</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ Gets the value of the environment
+ variable <replaceable class="parameter">env_var</replaceable>
+ and assigns it to the <application>psql</application>
+ variable <replaceable class="parameter">psql_var</replaceable>.
+ If <replaceable class="parameter">env_var</replaceable> is
+ not defined in the <application>psql</application> process's
+ environment, <replaceable class="parameter">psql_var</replaceable>
+ is not changed. Example:
+<programlisting>
+=&gt; <userinput>\getenv home HOME</userinput>
+=&gt; <userinput>\echo :home</userinput>
+/home/postgres
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\gexec</literal></term>
+
+ <listitem>
+ <para>
+ Sends the current query buffer to the server, then treats
+ each column of each row of the query's output (if any) as an SQL
+ statement to be executed. For example, to create an index on each
+ column of <structname>my_table</structname>:
+<programlisting>
+=&gt; <userinput>SELECT format('create index on my_table(%I)', attname)</userinput>
+-&gt; <userinput>FROM pg_attribute</userinput>
+-&gt; <userinput>WHERE attrelid = 'my_table'::regclass AND attnum &gt; 0</userinput>
+-&gt; <userinput>ORDER BY attnum</userinput>
+-&gt; <userinput>\gexec</userinput>
+CREATE INDEX
+CREATE INDEX
+CREATE INDEX
+CREATE INDEX
+</programlisting>
+ </para>
+
+ <para>
+ The generated queries are executed in the order in which the rows
+ are returned, and left-to-right within each row if there is more
+ than one column. NULL fields are ignored. The generated queries
+ are sent literally to the server for processing, so they cannot be
+ <application>psql</application> meta-commands nor contain <application>psql</application>
+ variable references. If any individual query fails, execution of
+ the remaining queries continues
+ unless <varname>ON_ERROR_STOP</varname> is set. Execution of each
+ query is subject to <varname>ECHO</varname> processing.
+ (Setting <varname>ECHO</varname> to <literal>all</literal>
+ or <literal>queries</literal> is often advisable when
+ using <command>\gexec</command>.) Query logging, single-step mode,
+ timing, and other query execution features apply to each generated
+ query as well.
+ </para>
+ <para>
+ If the current query buffer is empty, the most recently sent query
+ is re-executed instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\gset [ <replaceable class="parameter">prefix</replaceable> ]</literal></term>
+
+ <listitem>
+ <para>
+ Sends the current query buffer to the server and stores the
+ query's output into <application>psql</application> variables
+ (see <xref linkend="app-psql-variables"/> below).
+ The query to be executed must return exactly one row. Each column of
+ the row is stored into a separate variable, named the same as the
+ column. For example:
+<programlisting>
+=&gt; <userinput>SELECT 'hello' AS var1, 10 AS var2</userinput>
+-&gt; <userinput>\gset</userinput>
+=&gt; <userinput>\echo :var1 :var2</userinput>
+hello 10
+</programlisting>
+ </para>
+ <para>
+ If you specify a <replaceable class="parameter">prefix</replaceable>,
+ that string is prepended to the query's column names to create the
+ variable names to use:
+<programlisting>
+=&gt; <userinput>SELECT 'hello' AS var1, 10 AS var2</userinput>
+-&gt; <userinput>\gset result_</userinput>
+=&gt; <userinput>\echo :result_var1 :result_var2</userinput>
+hello 10
+</programlisting>
+ </para>
+ <para>
+ If a column result is NULL, the corresponding variable is unset
+ rather than being set.
+ </para>
+ <para>
+ If the query fails or does not return one row,
+ no variables are changed.
+ </para>
+ <para>
+ If the current query buffer is empty, the most recently sent query
+ is re-executed instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\gx [ (<replaceable class="parameter">option</replaceable>=<replaceable class="parameter">value</replaceable> [...]) ] [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
+ <term><literal>\gx [ (<replaceable class="parameter">option</replaceable>=<replaceable class="parameter">value</replaceable> [...]) ] [ |<replaceable class="parameter">command</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ <literal>\gx</literal> is equivalent to <literal>\g</literal>, except
+ that it forces expanded output mode for this query, as
+ if <literal>expanded=on</literal> were included in the list of
+ <literal>\pset</literal> options. See also <literal>\x</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\h</literal> or <literal>\help</literal> <literal>[ <replaceable class="parameter">command</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Gives syntax help on the specified <acronym>SQL</acronym>
+ command. If <replaceable class="parameter">command</replaceable>
+ is not specified, then <application>psql</application> will list
+ all the commands for which syntax help is available. If
+ <replaceable class="parameter">command</replaceable> is an
+ asterisk (<literal>*</literal>), then syntax help on all
+ <acronym>SQL</acronym> commands is shown.
+ </para>
+
+ <para>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <command>\help</command>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </para>
+
+ <note>
+ <para>
+ To simplify typing, commands that consists of several words do
+ not have to be quoted. Thus it is fine to type <userinput>\help
+ alter table</userinput>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\H</literal> or <literal>\html</literal></term>
+ <listitem>
+ <para>
+ Turns on <acronym>HTML</acronym> query output format. If the
+ <acronym>HTML</acronym> format is already on, it is switched
+ back to the default aligned text format. This command is for
+ compatibility and convenience, but see <command>\pset</command>
+ about setting other output options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\i</literal> or <literal>\include</literal> <replaceable class="parameter">filename</replaceable></term>
+ <listitem>
+ <para>
+ Reads input from the file <replaceable
+ class="parameter">filename</replaceable> and executes it as
+ though it had been typed on the keyboard.
+ </para>
+ <para>
+ If <replaceable>filename</replaceable> is <literal>-</literal>
+ (hyphen), then standard input is read until an EOF indication
+ or <command>\q</command> meta-command. This can be used to intersperse
+ interactive input with input from files. Note that Readline behavior
+ will be used only if it is active at the outermost level.
+ </para>
+ <note>
+ <para>
+ If you want to see the lines on the screen as they are read you
+ must set the variable <varname>ECHO</varname> to
+ <literal>all</literal>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry id="psql-metacommand-if">
+ <term><literal>\if</literal> <replaceable class="parameter">expression</replaceable></term>
+ <term><literal>\elif</literal> <replaceable class="parameter">expression</replaceable></term>
+ <term><literal>\else</literal></term>
+ <term><literal>\endif</literal></term>
+ <listitem>
+ <para>
+ This group of commands implements nestable conditional blocks.
+ A conditional block must begin with an <command>\if</command> and end
+ with an <command>\endif</command>. In between there may be any number
+ of <command>\elif</command> clauses, which may optionally be followed
+ by a single <command>\else</command> clause. Ordinary queries and
+ other types of backslash commands may (and usually do) appear between
+ the commands forming a conditional block.
+ </para>
+ <para>
+ The <command>\if</command> and <command>\elif</command> commands read
+ their argument(s) and evaluate them as a Boolean expression. If the
+ expression yields <literal>true</literal> then processing continues
+ normally; otherwise, lines are skipped until a
+ matching <command>\elif</command>, <command>\else</command>,
+ or <command>\endif</command> is reached. Once
+ an <command>\if</command> or <command>\elif</command> test has
+ succeeded, the arguments of later <command>\elif</command> commands in
+ the same block are not evaluated but are treated as false. Lines
+ following an <command>\else</command> are processed only if no earlier
+ matching <command>\if</command> or <command>\elif</command> succeeded.
+ </para>
+ <para>
+ The <replaceable class="parameter">expression</replaceable> argument
+ of an <command>\if</command> or <command>\elif</command> command
+ is subject to variable interpolation and backquote expansion, just
+ like any other backslash command argument. After that it is evaluated
+ like the value of an on/off option variable. So a valid value
+ is any unambiguous case-insensitive match for one of:
+ <literal>true</literal>, <literal>false</literal>, <literal>1</literal>,
+ <literal>0</literal>, <literal>on</literal>, <literal>off</literal>,
+ <literal>yes</literal>, <literal>no</literal>. For example,
+ <literal>t</literal>, <literal>T</literal>, and <literal>tR</literal>
+ will all be considered to be <literal>true</literal>.
+ </para>
+ <para>
+ Expressions that do not properly evaluate to true or false will
+ generate a warning and be treated as false.
+ </para>
+ <para>
+ Lines being skipped are parsed normally to identify queries and
+ backslash commands, but queries are not sent to the server, and
+ backslash commands other than conditionals
+ (<command>\if</command>, <command>\elif</command>,
+ <command>\else</command>, <command>\endif</command>) are
+ ignored. Conditional commands are checked only for valid nesting.
+ Variable references in skipped lines are not expanded, and backquote
+ expansion is not performed either.
+ </para>
+ <para>
+ All the backslash commands of a given conditional block must appear in
+ the same source file. If EOF is reached on the main input file or an
+ <command>\include</command>-ed file before all local
+ <command>\if</command>-blocks have been closed,
+ then <application>psql</application> will raise an error.
+ </para>
+ <para>
+ Here is an example:
+ </para>
+<programlisting>
+-- check for the existence of two separate records in the database and store
+-- the results in separate psql variables
+SELECT
+ EXISTS(SELECT 1 FROM customer WHERE customer_id = 123) as is_customer,
+ EXISTS(SELECT 1 FROM employee WHERE employee_id = 456) as is_employee
+\gset
+\if :is_customer
+ SELECT * FROM customer WHERE customer_id = 123;
+\elif :is_employee
+ \echo 'is not a customer but is an employee'
+ SELECT * FROM employee WHERE employee_id = 456;
+\else
+ \if yes
+ \echo 'not a customer or employee'
+ \else
+ \echo 'this will never print'
+ \endif
+\endif
+</programlisting>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\ir</literal> or <literal>\include_relative</literal> <replaceable class="parameter">filename</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>\ir</literal> command is similar to <literal>\i</literal>, but resolves
+ relative file names differently. When executing in interactive mode,
+ the two commands behave identically. However, when invoked from a
+ script, <literal>\ir</literal> interprets file names relative to the
+ directory in which the script is located, rather than the current
+ working directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\l[+]</literal> or <literal>\list[+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ List the databases in the server and show their names, owners,
+ character set encodings, and access privileges.
+ If <replaceable class="parameter">pattern</replaceable> is specified,
+ only databases whose names match the pattern are listed.
+ If <literal>+</literal> is appended to the command name, database
+ sizes, default tablespaces, and descriptions are also displayed.
+ (Size information is only available for databases that the current
+ user can connect to.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\lo_export <replaceable class="parameter">loid</replaceable> <replaceable class="parameter">filename</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ Reads the large object with <acronym>OID</acronym> <replaceable
+ class="parameter">loid</replaceable> from the database and
+ writes it to <replaceable
+ class="parameter">filename</replaceable>. Note that this is
+ subtly different from the server function
+ <function>lo_export</function>, which acts with the permissions
+ of the user that the database server runs as and on the server's
+ file system.
+ </para>
+ <tip>
+ <para>
+ Use <command>\lo_list</command> to find out the large object's
+ <acronym>OID</acronym>.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\lo_import <replaceable class="parameter">filename</replaceable> [ <replaceable class="parameter">comment</replaceable> ]</literal></term>
+
+ <listitem>
+ <para>
+ Stores the file into a <productname>PostgreSQL</productname>
+ large object. Optionally, it associates the given
+ comment with the object. Example:
+<programlisting>
+foo=&gt; <userinput>\lo_import '/home/peter/pictures/photo.xcf' 'a picture of me'</userinput>
+lo_import 152801
+</programlisting>
+ The response indicates that the large object received object
+ ID 152801, which can be used to access the newly-created large
+ object in the future. For the sake of readability, it is
+ recommended to always associate a human-readable comment with
+ every object. Both OIDs and comments can be viewed with the
+ <command>\lo_list</command> command.
+ </para>
+
+ <para>
+ Note that this command is subtly different from the server-side
+ <function>lo_import</function> because it acts as the local user
+ on the local file system, rather than the server's user and file
+ system.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\lo_list[+]</literal></term>
+ <listitem>
+ <para>
+ Shows a list of all <productname>PostgreSQL</productname>
+ large objects currently stored in the database,
+ along with any comments provided for them.
+ If <literal>+</literal> is appended to the command name,
+ each large object is listed with its associated permissions,
+ if any.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\lo_unlink <replaceable class="parameter">loid</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ Deletes the large object with <acronym>OID</acronym>
+ <replaceable class="parameter">loid</replaceable> from the
+ database.
+ </para>
+
+ <tip>
+ <para>
+ Use <command>\lo_list</command> to find out the large object's
+ <acronym>OID</acronym>.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\o</literal> or <literal>\out [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
+ <term><literal>\o</literal> or <literal>\out [ |<replaceable class="parameter">command</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Arranges to save future query results to the file <replaceable
+ class="parameter">filename</replaceable> or pipe future results
+ to the shell command <replaceable
+ class="parameter">command</replaceable>. If no argument is
+ specified, the query output is reset to the standard output.
+ </para>
+
+ <para>
+ If the argument begins with <literal>|</literal>, then the entire remainder
+ of the line is taken to be
+ the <replaceable class="parameter">command</replaceable> to execute,
+ and neither variable interpolation nor backquote expansion are
+ performed in it. The rest of the line is simply passed literally to
+ the shell.
+ </para>
+
+ <para>
+ <quote>Query results</quote> includes all tables, command
+ responses, and notices obtained from the database server, as
+ well as output of various backslash commands that query the
+ database (such as <command>\d</command>); but not error
+ messages.
+ </para>
+
+ <tip>
+ <para>
+ To intersperse text output in between query results, use
+ <command>\qecho</command>.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\p</literal> or <literal>\print</literal></term>
+ <listitem>
+ <para>
+ Print the current query buffer to the standard output.
+ If the current query buffer is empty, the most recently executed query
+ is printed instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\password [ <replaceable class="parameter">username</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Changes the password of the specified user (by default, the current
+ user). This command prompts for the new password, encrypts it, and
+ sends it to the server as an <command>ALTER ROLE</command> command. This
+ makes sure that the new password does not appear in cleartext in the
+ command history, the server log, or elsewhere.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\prompt [ <replaceable class="parameter">text</replaceable> ] <replaceable class="parameter">name</replaceable></literal></term>
+ <listitem>
+ <para>
+ Prompts the user to supply text, which is assigned to the variable
+ <replaceable class="parameter">name</replaceable>.
+ An optional prompt string, <replaceable
+ class="parameter">text</replaceable>, can be specified. (For multiword
+ prompts, surround the text with single quotes.)
+ </para>
+
+ <para>
+ By default, <literal>\prompt</literal> uses the terminal for input and
+ output. However, if the <option>-f</option> command line switch was
+ used, <literal>\prompt</literal> uses standard input and standard output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\pset [ <replaceable class="parameter">option</replaceable> [ <replaceable class="parameter">value</replaceable> ] ]</literal></term>
+
+ <listitem>
+ <para>
+ This command sets options affecting the output of query result tables.
+ <replaceable class="parameter">option</replaceable>
+ indicates which option is to be set. The semantics of
+ <replaceable class="parameter">value</replaceable> vary depending
+ on the selected option. For some options, omitting <replaceable
+ class="parameter">value</replaceable> causes the option to be toggled
+ or unset, as described under the particular option. If no such
+ behavior is mentioned, then omitting
+ <replaceable class="parameter">value</replaceable> just results in
+ the current setting being displayed.
+ </para>
+
+ <para>
+ <command>\pset</command> without any arguments displays the current status
+ of all printing options.
+ </para>
+
+ <para>
+ Adjustable printing options are:
+ <variablelist>
+ <varlistentry>
+ <term><literal>border</literal></term>
+ <listitem>
+ <para>
+ The <replaceable class="parameter">value</replaceable> must be a
+ number. In general, the higher
+ the number the more borders and lines the tables will have,
+ but details depend on the particular format.
+ In <acronym>HTML</acronym> format, this will translate directly
+ into the <literal>border=...</literal> attribute.
+ In most other formats only values 0 (no border), 1 (internal
+ dividing lines), and 2 (table frame) make sense, and values above 2
+ will be treated the same as <literal>border = 2</literal>.
+ The <literal>latex</literal> and <literal>latex-longtable</literal>
+ formats additionally allow a value of 3 to add dividing lines
+ between data rows.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>columns</literal></term>
+ <listitem>
+ <para>
+ Sets the target width for the <literal>wrapped</literal> format, and also
+ the width limit for determining whether output is wide enough to
+ require the pager or switch to the vertical display in expanded auto
+ mode.
+ Zero (the default) causes the target width to be controlled by the
+ environment variable <envar>COLUMNS</envar>, or the detected screen width
+ if <envar>COLUMNS</envar> is not set.
+ In addition, if <literal>columns</literal> is zero then the
+ <literal>wrapped</literal> format only affects screen output.
+ If <literal>columns</literal> is nonzero then file and pipe output is
+ wrapped to that width as well.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>csv_fieldsep</literal></term>
+ <listitem>
+ <para>
+ Specifies the field separator to be used in
+ <acronym>CSV</acronym> output format. If the separator character
+ appears in a field's value, that field is output within double
+ quotes, following standard <acronym>CSV</acronym> rules.
+ The default is a comma.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>expanded</literal> (or <literal>x</literal>)</term>
+ <listitem>
+ <para>
+ If <replaceable class="parameter">value</replaceable> is specified it
+ must be either <literal>on</literal> or <literal>off</literal>, which
+ will enable or disable expanded mode, or <literal>auto</literal>.
+ If <replaceable class="parameter">value</replaceable> is omitted the
+ command toggles between the on and off settings. When expanded mode
+ is enabled, query results are displayed in two columns, with the
+ column name on the left and the data on the right. This mode is
+ useful if the data wouldn't fit on the screen in the
+ normal <quote>horizontal</quote> mode. In the auto setting, the
+ expanded mode is used whenever the query output has more than one
+ column and is wider than the screen; otherwise, the regular mode is
+ used. The auto setting is only
+ effective in the aligned and wrapped formats. In other formats, it
+ always behaves as if the expanded mode is off.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>fieldsep</literal></term>
+ <listitem>
+ <para>
+ Specifies the field separator to be used in unaligned output
+ format. That way one can create, for example, tab-separated
+ output, which other programs might prefer. To
+ set a tab as field separator, type <literal>\pset fieldsep
+ '\t'</literal>. The default field separator is
+ <literal>'|'</literal> (a vertical bar).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>fieldsep_zero</literal></term>
+ <listitem>
+ <para>
+ Sets the field separator to use in unaligned output format to a zero
+ byte.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>footer</literal></term>
+ <listitem>
+ <para>
+ If <replaceable class="parameter">value</replaceable> is specified
+ it must be either <literal>on</literal> or <literal>off</literal>
+ which will enable or disable display of the table footer
+ (the <literal>(<replaceable>n</replaceable> rows)</literal> count).
+ If <replaceable class="parameter">value</replaceable> is omitted the
+ command toggles footer display on or off.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>format</literal></term>
+ <listitem>
+ <para>
+ Sets the output format to one of <literal>aligned</literal>,
+ <literal>asciidoc</literal>,
+ <literal>csv</literal>,
+ <literal>html</literal>,
+ <literal>latex</literal>,
+ <literal>latex-longtable</literal>, <literal>troff-ms</literal>,
+ <literal>unaligned</literal>, or <literal>wrapped</literal>.
+ Unique abbreviations are allowed.
+ </para>
+
+ <para><literal>aligned</literal> format is the standard,
+ human-readable, nicely formatted text output; this is the default.
+ </para>
+
+ <para><literal>unaligned</literal> format writes all columns of a row on one
+ line, separated by the currently active field separator. This
+ is useful for creating output that might be intended to be read
+ in by other programs, for example, tab-separated or comma-separated
+ format. However, the field separator character is not treated
+ specially if it appears in a column's value;
+ so <acronym>CSV</acronym> format may be better suited for such
+ purposes.
+ </para>
+
+ <para><literal>csv</literal> format
+ <indexterm>
+ <primary>CSV (Comma-Separated Values) format</primary>
+ <secondary>in psql</secondary>
+ </indexterm>
+ writes column values separated by commas, applying the quoting
+ rules described in
+ <ulink url="https://tools.ietf.org/html/rfc4180">RFC 4180</ulink>.
+ This output is compatible with the CSV format of the server's
+ <command>COPY</command> command.
+ A header line with column names is generated unless
+ the <literal>tuples_only</literal> parameter is
+ <literal>on</literal>. Titles and footers are not printed.
+ Each row is terminated by the system-dependent end-of-line character,
+ which is typically a single newline (<literal>\n</literal>) for
+ Unix-like systems or a carriage return and newline sequence
+ (<literal>\r\n</literal>) for Microsoft Windows.
+ Field separator characters other than comma can be selected with
+ <command>\pset csv_fieldsep</command>.
+ </para>
+
+ <para><literal>wrapped</literal> format is like <literal>aligned</literal> but wraps
+ wide data values across lines to make the output fit in the target
+ column width. The target width is determined as described under
+ the <literal>columns</literal> option. Note that <application>psql</application> will
+ not attempt to wrap column header titles; therefore,
+ <literal>wrapped</literal> format behaves the same as <literal>aligned</literal>
+ if the total width needed for column headers exceeds the target.
+ </para>
+
+ <para>
+ The <literal>asciidoc</literal>, <literal>html</literal>,
+ <literal>latex</literal>, <literal>latex-longtable</literal>, and
+ <literal>troff-ms</literal> formats put out tables that are intended
+ to be included in documents using the respective mark-up
+ language. They are not complete documents! This might not be
+ necessary in <acronym>HTML</acronym>, but in
+ <application>LaTeX</application> you must have a complete
+ document wrapper.
+ The <literal>latex</literal> format
+ uses <application>LaTeX</application>'s <literal>tabular</literal>
+ environment.
+ The <literal>latex-longtable</literal> format
+ requires the <application>LaTeX</application>
+ <literal>longtable</literal> and <literal>booktabs</literal> packages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>linestyle</literal></term>
+ <listitem>
+ <para>
+ Sets the border line drawing style to one
+ of <literal>ascii</literal>, <literal>old-ascii</literal>,
+ or <literal>unicode</literal>.
+ Unique abbreviations are allowed. (That would mean one
+ letter is enough.)
+ The default setting is <literal>ascii</literal>.
+ This option only affects the <literal>aligned</literal> and
+ <literal>wrapped</literal> output formats.
+ </para>
+
+ <para><literal>ascii</literal> style uses plain <acronym>ASCII</acronym>
+ characters. Newlines in data are shown using
+ a <literal>+</literal> symbol in the right-hand margin.
+ When the <literal>wrapped</literal> format wraps data from
+ one line to the next without a newline character, a dot
+ (<literal>.</literal>) is shown in the right-hand margin of the first line,
+ and again in the left-hand margin of the following line.
+ </para>
+
+ <para><literal>old-ascii</literal> style uses plain <acronym>ASCII</acronym>
+ characters, using the formatting style used
+ in <productname>PostgreSQL</productname> 8.4 and earlier.
+ Newlines in data are shown using a <literal>:</literal>
+ symbol in place of the left-hand column separator.
+ When the data is wrapped from one line
+ to the next without a newline character, a <literal>;</literal>
+ symbol is used in place of the left-hand column separator.
+ </para>
+
+ <para><literal>unicode</literal> style uses Unicode box-drawing characters.
+ Newlines in data are shown using a carriage return symbol
+ in the right-hand margin. When the data is wrapped from one line
+ to the next without a newline character, an ellipsis symbol
+ is shown in the right-hand margin of the first line, and
+ again in the left-hand margin of the following line.
+ </para>
+
+ <para>
+ When the <literal>border</literal> setting is greater than zero,
+ the <literal>linestyle</literal> option also determines the
+ characters with which the border lines are drawn.
+ Plain <acronym>ASCII</acronym> characters work everywhere, but
+ Unicode characters look nicer on displays that recognize them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>null</literal></term>
+ <listitem>
+ <para>
+ Sets the string to be printed in place of a null value.
+ The default is to print nothing, which can easily be mistaken for
+ an empty string. For example, one might prefer <literal>\pset null
+ '(null)'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>numericlocale</literal></term>
+ <listitem>
+ <para>
+ If <replaceable class="parameter">value</replaceable> is specified
+ it must be either <literal>on</literal> or <literal>off</literal>
+ which will enable or disable display of a locale-specific character
+ to separate groups of digits to the left of the decimal marker.
+ If <replaceable class="parameter">value</replaceable> is omitted the
+ command toggles between regular and locale-specific numeric output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>pager</literal></term>
+ <listitem>
+ <para>
+ Controls use of a pager program for query and <application>psql</application>
+ help output.
+ When the <literal>pager</literal> option is <literal>off</literal>, the pager
+ program is not used. When the <literal>pager</literal> option is
+ <literal>on</literal>, the pager is used when appropriate, i.e., when the
+ output is to a terminal and will not fit on the screen.
+ The <literal>pager</literal> option can also be set to <literal>always</literal>,
+ which causes the pager to be used for all terminal output regardless
+ of whether it fits on the screen. <literal>\pset pager</literal>
+ without a <replaceable class="parameter">value</replaceable>
+ toggles pager use on and off.
+ </para>
+
+ <para>
+ If the environment variable <envar>PSQL_PAGER</envar>
+ or <envar>PAGER</envar> is set, output to be paged is piped to the
+ specified program. Otherwise a platform-dependent default program
+ (such as <filename>more</filename>) is used.
+ </para>
+
+ <para>
+ When using the <literal>\watch</literal> command to execute a query
+ repeatedly, the environment variable <envar>PSQL_WATCH_PAGER</envar>
+ is used to find the pager program instead, on Unix systems. This is
+ configured separately because it may confuse traditional pagers, but
+ can be used to send output to tools that understand
+ <application>psql</application>'s output format (such as
+ <filename>pspg --stream</filename>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>pager_min_lines</literal></term>
+ <listitem>
+ <para>
+ If <literal>pager_min_lines</literal> is set to a number greater than the
+ page height, the pager program will not be called unless there are
+ at least this many lines of output to show. The default setting
+ is 0.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>recordsep</literal></term>
+ <listitem>
+ <para>
+ Specifies the record (line) separator to use in unaligned
+ output format. The default is a newline character.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>recordsep_zero</literal></term>
+ <listitem>
+ <para>
+ Sets the record separator to use in unaligned output format to a zero
+ byte.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>tableattr</literal> (or <literal>T</literal>)</term>
+ <listitem>
+ <para>
+ In <acronym>HTML</acronym> format, this specifies attributes
+ to be placed inside the <sgmltag>table</sgmltag> tag. This
+ could for example be <literal>cellpadding</literal> or
+ <literal>bgcolor</literal>. Note that you probably don't want
+ to specify <literal>border</literal> here, as that is already
+ taken care of by <literal>\pset border</literal>.
+ If no
+ <replaceable class="parameter">value</replaceable> is given,
+ the table attributes are unset.
+ </para>
+ <para>
+ In <literal>latex-longtable</literal> format, this controls
+ the proportional width of each column containing a left-aligned
+ data type. It is specified as a whitespace-separated list of values,
+ e.g., <literal>'0.2 0.2 0.6'</literal>. Unspecified output columns
+ use the last specified value.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>title</literal> (or <literal>C</literal>)</term>
+ <listitem>
+ <para>
+ Sets the table title for any subsequently printed tables. This
+ can be used to give your output descriptive tags. If no
+ <replaceable class="parameter">value</replaceable> is given,
+ the title is unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>tuples_only</literal> (or <literal>t</literal>)</term>
+ <listitem>
+ <para>
+ If <replaceable class="parameter">value</replaceable> is specified
+ it must be either <literal>on</literal> or <literal>off</literal>
+ which will enable or disable tuples-only mode.
+ If <replaceable class="parameter">value</replaceable> is omitted the
+ command toggles between regular and tuples-only output.
+ Regular output includes extra information such
+ as column headers, titles, and various footers. In tuples-only
+ mode, only actual table data is shown.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_border_linestyle</literal></term>
+ <listitem>
+ <para>
+ Sets the border drawing style for the <literal>unicode</literal>
+ line style to one of <literal>single</literal>
+ or <literal>double</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_column_linestyle</literal></term>
+ <listitem>
+ <para>
+ Sets the column drawing style for the <literal>unicode</literal>
+ line style to one of <literal>single</literal>
+ or <literal>double</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>unicode_header_linestyle</literal></term>
+ <listitem>
+ <para>
+ Sets the header drawing style for the <literal>unicode</literal>
+ line style to one of <literal>single</literal>
+ or <literal>double</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Illustrations of how these different formats look can be seen in
+ <xref linkend="app-psql-examples"/>, below.
+ </para>
+
+ <tip>
+ <para>
+ There are various shortcut commands for <command>\pset</command>. See
+ <command>\a</command>, <command>\C</command>, <command>\f</command>,
+ <command>\H</command>, <command>\t</command>, <command>\T</command>,
+ and <command>\x</command>.
+ </para>
+ </tip>
+
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\q</literal> or <literal>\quit</literal></term>
+ <listitem>
+ <para>
+ Quits the <application>psql</application> program.
+ In a script file, only execution of that script is terminated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\qecho <replaceable class="parameter">text</replaceable> [ ... ] </literal></term>
+ <listitem>
+ <para>
+ This command is identical to <command>\echo</command> except
+ that the output will be written to the query output channel, as
+ set by <command>\o</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\r</literal> or <literal>\reset</literal></term>
+ <listitem>
+ <para>
+ Resets (clears) the query buffer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\s [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Print <application>psql</application>'s command line history
+ to <replaceable class="parameter">filename</replaceable>.
+ If <replaceable class="parameter">filename</replaceable> is omitted,
+ the history is written to the standard output (using the pager if
+ appropriate). This command is not available
+ if <application>psql</application> was built
+ without <application>Readline</application> support.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\set [ <replaceable class="parameter">name</replaceable> [ <replaceable class="parameter">value</replaceable> [ ... ] ] ]</literal></term>
+
+ <listitem>
+ <para>
+ Sets the <application>psql</application> variable <replaceable
+ class="parameter">name</replaceable> to <replaceable
+ class="parameter">value</replaceable>, or if more than one value
+ is given, to the concatenation of all of them. If only one
+ argument is given, the variable is set to an empty-string value. To
+ unset a variable, use the <command>\unset</command> command.
+ </para>
+
+ <para><command>\set</command> without any arguments displays the names and values
+ of all currently-set <application>psql</application> variables.
+ </para>
+
+ <para>
+ Valid variable names can contain letters, digits, and
+ underscores. See <xref linkend="app-psql-variables"/> below for details.
+ Variable names are case-sensitive.
+ </para>
+
+ <para>
+ Certain variables are special, in that they
+ control <application>psql</application>'s behavior or are
+ automatically set to reflect connection state. These variables are
+ documented in <xref linkend="app-psql-variables"/>, below.
+ </para>
+
+ <note>
+ <para>
+ This command is unrelated to the <acronym>SQL</acronym>
+ command <link linkend="sql-set"><command>SET</command></link>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\setenv <replaceable class="parameter">name</replaceable> [ <replaceable class="parameter">value</replaceable> ]</literal></term>
+
+ <listitem>
+ <para>
+ Sets the environment variable <replaceable
+ class="parameter">name</replaceable> to <replaceable
+ class="parameter">value</replaceable>, or if the
+ <replaceable class="parameter">value</replaceable> is
+ not supplied, unsets the environment variable. Example:
+<programlisting>
+testdb=&gt; <userinput>\setenv PAGER less</userinput>
+testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\sf[+] <replaceable class="parameter">function_description</replaceable> </literal></term>
+
+ <listitem>
+ <para>
+ This command fetches and shows the definition of the named function or procedure,
+ in the form of a <command>CREATE OR REPLACE FUNCTION</command> or
+ <command>CREATE OR REPLACE PROCEDURE</command> command.
+ The definition is printed to the current query output channel,
+ as set by <command>\o</command>.
+ </para>
+
+ <para>
+ The target function can be specified by name alone, or by name
+ and arguments, for example <literal>foo(integer, text)</literal>.
+ The argument types must be given if there is more
+ than one function of the same name.
+ </para>
+
+ <para>
+ If <literal>+</literal> is appended to the command name, then the
+ output lines are numbered, with the first line of the function body
+ being line 1.
+ </para>
+
+ <para>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <command>\sf</command>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\sv[+] <replaceable class="parameter">view_name</replaceable> </literal></term>
+
+ <listitem>
+ <para>
+ This command fetches and shows the definition of the named view,
+ in the form of a <command>CREATE OR REPLACE VIEW</command> command.
+ The definition is printed to the current query output channel,
+ as set by <command>\o</command>.
+ </para>
+
+ <para>
+ If <literal>+</literal> is appended to the command name, then the
+ output lines are numbered from 1.
+ </para>
+
+ <para>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <command>\sv</command>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\t</literal></term>
+ <listitem>
+ <para>
+ Toggles the display of output column name headings and row count
+ footer. This command is equivalent to <literal>\pset
+ tuples_only</literal> and is provided for convenience.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\T <replaceable class="parameter">table_options</replaceable></literal></term>
+ <listitem>
+ <para>
+ Specifies attributes to be placed within the
+ <sgmltag>table</sgmltag> tag in <acronym>HTML</acronym>
+ output format. This command is equivalent to <literal>\pset
+ tableattr <replaceable
+ class="parameter">table_options</replaceable></literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\timing [ <replaceable class="parameter">on</replaceable> | <replaceable class="parameter">off</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ With a parameter, turns displaying of how long each SQL statement
+ takes on or off. Without a parameter, toggles the display between
+ on and off. The display is in milliseconds; intervals longer than
+ 1 second are also shown in minutes:seconds format, with hours and
+ days fields added if needed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\unset <replaceable class="parameter">name</replaceable></literal></term>
+
+ <listitem>
+ <para>
+ Unsets (deletes) the <application>psql</application> variable <replaceable
+ class="parameter">name</replaceable>.
+ </para>
+
+ <para>
+ Most variables that control <application>psql</application>'s behavior
+ cannot be unset; instead, an <literal>\unset</literal> command is interpreted
+ as setting them to their default values.
+ See <xref linkend="app-psql-variables"/> below.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\w</literal> or <literal>\write</literal> <replaceable class="parameter">filename</replaceable></term>
+ <term><literal>\w</literal> or <literal>\write</literal> <literal>|</literal><replaceable class="parameter">command</replaceable></term>
+ <listitem>
+ <para>
+ Writes the current query buffer to the file <replaceable
+ class="parameter">filename</replaceable> or pipes it to the shell
+ command <replaceable class="parameter">command</replaceable>.
+ If the current query buffer is empty, the most recently executed query
+ is written instead.
+ </para>
+
+ <para>
+ If the argument begins with <literal>|</literal>, then the entire remainder
+ of the line is taken to be
+ the <replaceable class="parameter">command</replaceable> to execute,
+ and neither variable interpolation nor backquote expansion are
+ performed in it. The rest of the line is simply passed literally to
+ the shell.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\warn <replaceable class="parameter">text</replaceable> [ ... ]</literal></term>
+ <listitem>
+ <para>
+ This command is identical to <command>\echo</command> except
+ that the output will be written to <application>psql</application>'s
+ standard error channel, rather than standard output.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\watch [ <replaceable class="parameter">seconds</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Repeatedly execute the current query buffer (as <literal>\g</literal> does)
+ until interrupted or the query fails. Wait the specified number of
+ seconds (default 2) between executions. Each query result is
+ displayed with a header that includes the <literal>\pset title</literal>
+ string (if any), the time as of query start, and the delay interval.
+ </para>
+ <para>
+ If the current query buffer is empty, the most recently sent query
+ is re-executed instead.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\x [ <replaceable class="parameter">on</replaceable> | <replaceable class="parameter">off</replaceable> | <replaceable class="parameter">auto</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Sets or toggles expanded table formatting mode. As such it is equivalent to
+ <literal>\pset expanded</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\z [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+ <listitem>
+ <para>
+ Lists tables, views and sequences with their
+ associated access privileges.
+ If a <replaceable class="parameter">pattern</replaceable> is
+ specified, only tables, views and sequences whose names match the
+ pattern are listed.
+ </para>
+
+ <para>
+ This is an alias for <command>\dp</command> (<quote>display
+ privileges</quote>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\! [ <replaceable class="parameter">command</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ With no argument, escapes to a sub-shell; <application>psql</application>
+ resumes when the sub-shell exits. With an argument, executes the
+ shell command <replaceable class="parameter">command</replaceable>.
+ </para>
+
+ <para>
+ Unlike most other meta-commands, the entire remainder of the line is
+ always taken to be the argument(s) of <command>\!</command>, and neither
+ variable interpolation nor backquote expansion are performed in the
+ arguments. The rest of the line is simply passed literally to the
+ shell.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\? [ <replaceable class="parameter">topic</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ Shows help information. The optional
+ <replaceable class="parameter">topic</replaceable> parameter
+ (defaulting to <literal>commands</literal>) selects which part of <application>psql</application> is
+ explained: <literal>commands</literal> describes <application>psql</application>'s
+ backslash commands; <literal>options</literal> describes the command-line
+ options that can be passed to <application>psql</application>;
+ and <literal>variables</literal> shows help about <application>psql</application> configuration
+ variables.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><literal>\;</literal></term>
+ <listitem>
+ <para>
+ Backslash-semicolon is not a meta-command in the same way as the
+ preceding commands; rather, it simply causes a semicolon to be
+ added to the query buffer without any further processing.
+ </para>
+
+ <para>
+ Normally, <application>psql</application> will dispatch an SQL command to the
+ server as soon as it reaches the command-ending semicolon, even if
+ more input remains on the current line. Thus for example entering
+<programlisting>
+select 1; select 2; select 3;
+</programlisting>
+ will result in the three SQL commands being individually sent to
+ the server, with each one's results being displayed before
+ continuing to the next command. However, a semicolon entered
+ as <literal>\;</literal> will not trigger command processing, so that the
+ command before it and the one after are effectively combined and
+ sent to the server in one request. So for example
+<programlisting>
+select 1\; select 2\; select 3;
+</programlisting>
+ results in sending the three SQL commands to the server in a single
+ request, when the non-backslashed semicolon is reached.
+ The server executes such a request as a single transaction,
+ unless there are explicit <command>BEGIN</command>/<command>COMMIT</command>
+ commands included in the string to divide it into multiple
+ transactions. (See <xref linkend="protocol-flow-multi-statement"/>
+ for more details about how the server handles multi-query strings.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <refsect3 id="app-psql-patterns" xreflabel="Patterns">
+ <title>Patterns</title>
+
+ <indexterm>
+ <primary>patterns</primary>
+ <secondary>in psql and pg_dump</secondary>
+ </indexterm>
+
+ <para>
+ The various <literal>\d</literal> commands accept a <replaceable
+ class="parameter">pattern</replaceable> parameter to specify the
+ object name(s) to be displayed. In the simplest case, a pattern
+ is just the exact name of the object. The characters within a
+ pattern are normally folded to lower case, just as in SQL names;
+ for example, <literal>\dt FOO</literal> will display the table named
+ <literal>foo</literal>. As in SQL names, placing double quotes around
+ a pattern stops folding to lower case. Should you need to include
+ an actual double quote character in a pattern, write it as a pair
+ of double quotes within a double-quote sequence; again this is in
+ accord with the rules for SQL quoted identifiers. For example,
+ <literal>\dt "FOO""BAR"</literal> will display the table named
+ <literal>FOO"BAR</literal> (not <literal>foo"bar</literal>). Unlike the normal
+ rules for SQL names, you can put double quotes around just part
+ of a pattern, for instance <literal>\dt FOO"FOO"BAR</literal> will display
+ the table named <literal>fooFOObar</literal>.
+ </para>
+
+ <para>
+ Whenever the <replaceable class="parameter">pattern</replaceable> parameter
+ is omitted completely, the <literal>\d</literal> commands display all objects
+ that are visible in the current schema search path &mdash; this is
+ equivalent to using <literal>*</literal> as the pattern.
+ (An object is said to be <firstterm>visible</firstterm> if its
+ containing schema is in the search path and no object of the same
+ kind and name appears earlier in the search path. This is equivalent to the
+ statement that the object can be referenced by name without explicit
+ schema qualification.)
+ To see all objects in the database regardless of visibility,
+ use <literal>*.*</literal> as the pattern.
+ </para>
+
+ <para>
+ Within a pattern, <literal>*</literal> matches any sequence of characters
+ (including no characters) and <literal>?</literal> matches any single character.
+ (This notation is comparable to Unix shell file name patterns.)
+ For example, <literal>\dt int*</literal> displays tables whose names
+ begin with <literal>int</literal>. But within double quotes, <literal>*</literal>
+ and <literal>?</literal> lose these special meanings and are just matched
+ literally.
+ </para>
+
+ <para>
+ A relation pattern that contains a dot (<literal>.</literal>) is interpreted as a schema
+ name pattern followed by an object name pattern. For example,
+ <literal>\dt foo*.*bar*</literal> displays all tables whose table name
+ includes <literal>bar</literal> that are in schemas whose schema name
+ starts with <literal>foo</literal>. When no dot appears, then the pattern
+ matches only objects that are visible in the current schema search path.
+ Again, a dot within double quotes loses its special meaning and is matched
+ literally. A relation pattern that contains two dots (<literal>.</literal>)
+ is interpreted as a database name followed by a schema name pattern followed
+ by an object name pattern. The database name portion will not be treated as
+ a pattern and must match the name of the currently connected database, else
+ an error will be raised.
+ </para>
+
+ <para>
+ A schema pattern that contains a dot (<literal>.</literal>) is interpreted
+ as a database name followed by a schema name pattern. For example,
+ <literal>\dn mydb.*foo*</literal> displays all schemas whose schema name
+ includes <literal>foo</literal>. The database name portion will not be
+ treated as a pattern and must match the name of the currently connected
+ database, else an error will be raised.
+ </para>
+
+ <para>
+ Advanced users can use regular-expression notations such as character
+ classes, for example <literal>[0-9]</literal> to match any digit. All regular
+ expression special characters work as specified in
+ <xref linkend="functions-posix-regexp"/>, except for <literal>.</literal> which
+ is taken as a separator as mentioned above, <literal>*</literal> which is
+ translated to the regular-expression notation <literal>.*</literal>,
+ <literal>?</literal> which is translated to <literal>.</literal>, and
+ <literal>$</literal> which is matched literally. You can emulate
+ these pattern characters at need by writing
+ <literal>?</literal> for <literal>.</literal>,
+ <literal>(<replaceable class="parameter">R</replaceable>+|)</literal> for
+ <literal><replaceable class="parameter">R</replaceable>*</literal>, or
+ <literal>(<replaceable class="parameter">R</replaceable>|)</literal> for
+ <literal><replaceable class="parameter">R</replaceable>?</literal>.
+ <literal>$</literal> is not needed as a regular-expression character since
+ the pattern must match the whole name, unlike the usual
+ interpretation of regular expressions (in other words, <literal>$</literal>
+ is automatically appended to your pattern). Write <literal>*</literal> at the
+ beginning and/or end if you don't wish the pattern to be anchored.
+ Note that within double quotes, all regular expression special characters
+ lose their special meanings and are matched literally. Also, the regular
+ expression special characters are matched literally in operator name
+ patterns (i.e., the argument of <literal>\do</literal>).
+ </para>
+ </refsect3>
+ </refsect2>
+
+ <refsect2>
+ <title>Advanced Features</title>
+
+ <refsect3 id="app-psql-variables" xreflabel="Variables">
+ <title>Variables</title>
+
+ <para>
+ <application>psql</application> provides variable substitution
+ features similar to common Unix command shells.
+ Variables are simply name/value pairs, where the value
+ can be any string of any length. The name must consist of letters
+ (including non-Latin letters), digits, and underscores.
+ </para>
+
+ <para>
+ To set a variable, use the <application>psql</application> meta-command
+ <command>\set</command>. For example,
+<programlisting>
+testdb=&gt; <userinput>\set foo bar</userinput>
+</programlisting>
+ sets the variable <literal>foo</literal> to the value
+ <literal>bar</literal>. To retrieve the content of the variable, precede
+ the name with a colon, for example:
+<programlisting>
+testdb=&gt; <userinput>\echo :foo</userinput>
+bar
+</programlisting>
+ This works in both regular SQL commands and meta-commands; there is
+ more detail in <xref linkend="app-psql-interpolation"/>, below.
+ </para>
+
+ <para>
+ If you call <command>\set</command> without a second argument, the
+ variable is set to an empty-string value. To unset (i.e., delete)
+ a variable, use the command <command>\unset</command>. To show the
+ values of all variables, call <command>\set</command> without any argument.
+ </para>
+
+ <note>
+ <para>
+ The arguments of <command>\set</command> are subject to the same
+ substitution rules as with other commands. Thus you can construct
+ interesting references such as <literal>\set :foo
+ 'something'</literal> and get <quote>soft links</quote> or
+ <quote>variable variables</quote> of <productname>Perl</productname>
+ or <productname><acronym>PHP</acronym></productname> fame,
+ respectively. Unfortunately (or fortunately?), there is no way to do
+ anything useful with these constructs. On the other hand,
+ <literal>\set bar :foo</literal> is a perfectly valid way to copy a
+ variable.
+ </para>
+ </note>
+
+ <para>
+ A number of these variables are treated specially
+ by <application>psql</application>. They represent certain option
+ settings that can be changed at run time by altering the value of
+ the variable, or in some cases represent changeable state of
+ <application>psql</application>.
+ By convention, all specially treated variables' names
+ consist of all upper-case ASCII letters (and possibly digits and
+ underscores). To ensure maximum compatibility in the future, avoid
+ using such variable names for your own purposes.
+ </para>
+
+ <para>
+ Variables that control <application>psql</application>'s behavior
+ generally cannot be unset or set to invalid values. An <literal>\unset</literal>
+ command is allowed but is interpreted as setting the variable to its
+ default value. A <literal>\set</literal> command without a second argument is
+ interpreted as setting the variable to <literal>on</literal>, for control
+ variables that accept that value, and is rejected for others. Also,
+ control variables that accept the values <literal>on</literal>
+ and <literal>off</literal> will also accept other common spellings of Boolean
+ values, such as <literal>true</literal> and <literal>false</literal>.
+ </para>
+
+ <para>
+ The specially treated variables are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <varname>AUTOCOMMIT</varname>
+ <indexterm>
+ <primary>autocommit</primary>
+ <secondary>psql</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When <literal>on</literal> (the default), each SQL command is automatically
+ committed upon successful completion. To postpone commit in this
+ mode, you must enter a <command>BEGIN</command> or <command>START
+ TRANSACTION</command> SQL command. When <literal>off</literal> or unset, SQL
+ commands are not committed until you explicitly issue
+ <command>COMMIT</command> or <command>END</command>. The autocommit-off
+ mode works by issuing an implicit <command>BEGIN</command> for you, just
+ before any command that is not already in a transaction block and
+ is not itself a <command>BEGIN</command> or other transaction-control
+ command, nor a command that cannot be executed inside a transaction
+ block (such as <command>VACUUM</command>).
+ </para>
+
+ <note>
+ <para>
+ In autocommit-off mode, you must explicitly abandon any failed
+ transaction by entering <command>ABORT</command> or <command>ROLLBACK</command>.
+ Also keep in mind that if you exit the session
+ without committing, your work will be lost.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ The autocommit-on mode is <productname>PostgreSQL</productname>'s traditional
+ behavior, but autocommit-off is closer to the SQL spec. If you
+ prefer autocommit-off, you might wish to set it in the system-wide
+ <filename>psqlrc</filename> file or your
+ <filename>~/.psqlrc</filename> file.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>COMP_KEYWORD_CASE</varname></term>
+ <listitem>
+ <para>
+ Determines which letter case to use when completing an SQL key word.
+ If set to <literal>lower</literal> or <literal>upper</literal>, the
+ completed word will be in lower or upper case, respectively. If set
+ to <literal>preserve-lower</literal>
+ or <literal>preserve-upper</literal> (the default), the completed word
+ will be in the case of the word already entered, but words being
+ completed without anything entered will be in lower or upper case,
+ respectively.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>DBNAME</varname></term>
+ <listitem>
+ <para>
+ The name of the database you are currently connected to. This is
+ set every time you connect to a database (including program
+ start-up), but can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ECHO</varname></term>
+ <listitem>
+ <para>
+ If set to <literal>all</literal>, all nonempty input lines are printed
+ to standard output as they are read. (This does not apply to lines
+ read interactively.) To select this behavior on program
+ start-up, use the switch <option>-a</option>. If set to
+ <literal>queries</literal>,
+ <application>psql</application> prints each query to standard output
+ as it is sent to the server. The switch to select this behavior is
+ <option>-e</option>. If set to <literal>errors</literal>, then only
+ failed queries are displayed on standard error output. The switch
+ for this behavior is <option>-b</option>. If set to
+ <literal>none</literal> (the default), then no queries are displayed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ECHO_HIDDEN</varname></term>
+ <listitem>
+ <para>
+ When this variable is set to <literal>on</literal> and a backslash command
+ queries the database, the query is first shown.
+ This feature helps you to study
+ <productname>PostgreSQL</productname> internals and provide
+ similar functionality in your own programs. (To select this behavior
+ on program start-up, use the switch <option>-E</option>.) If you set
+ this variable to the value <literal>noexec</literal>, the queries are
+ just shown but are not actually sent to the server and executed.
+ The default value is <literal>off</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ENCODING</varname></term>
+ <listitem>
+ <para>
+ The current client character set encoding.
+ This is set every time you connect to a database (including
+ program start-up), and when you change the encoding
+ with <literal>\encoding</literal>, but it can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ERROR</varname></term>
+ <listitem>
+ <para>
+ <literal>true</literal> if the last SQL query failed, <literal>false</literal> if
+ it succeeded. See also <varname>SQLSTATE</varname>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>FETCH_COUNT</varname></term>
+ <listitem>
+ <para>
+ If this variable is set to an integer value greater than zero,
+ the results of <command>SELECT</command> queries are fetched
+ and displayed in groups of that many rows, rather than the
+ default behavior of collecting the entire result set before
+ display. Therefore only a
+ limited amount of memory is used, regardless of the size of
+ the result set. Settings of 100 to 1000 are commonly used
+ when enabling this feature.
+ Keep in mind that when using this feature, a query might
+ fail after having already displayed some rows.
+ </para>
+
+ <tip>
+ <para>
+ Although you can use any output format with this feature,
+ the default <literal>aligned</literal> format tends to look bad
+ because each group of <varname>FETCH_COUNT</varname> rows
+ will be formatted separately, leading to varying column
+ widths across the row groups. The other output formats work better.
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HIDE_TABLEAM</varname></term>
+ <listitem>
+ <para>
+ If this variable is set to <literal>true</literal>, a table's access
+ method details are not displayed. This is mainly useful for
+ regression tests.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HIDE_TOAST_COMPRESSION</varname></term>
+ <listitem>
+ <para>
+ If this variable is set to <literal>true</literal>, column
+ compression method details are not displayed. This is mainly
+ useful for regression tests.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HISTCONTROL</varname></term>
+ <listitem>
+ <para>
+ If this variable is set to <literal>ignorespace</literal>,
+ lines which begin with a space are not entered into the history
+ list. If set to a value of <literal>ignoredups</literal>, lines
+ matching the previous history line are not entered. A value of
+ <literal>ignoreboth</literal> combines the two options. If
+ set to <literal>none</literal> (the default), all lines
+ read in interactive mode are saved on the history list.
+ </para>
+ <note>
+ <para>
+ This feature was shamelessly plagiarized from
+ <application>Bash</application>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HISTFILE</varname></term>
+ <listitem>
+ <para>
+ The file name that will be used to store the history list. If unset,
+ the file name is taken from the <envar>PSQL_HISTORY</envar>
+ environment variable. If that is not set either, the default
+ is <filename>~/.psql_history</filename>,
+ or <filename>%APPDATA%\postgresql\psql_history</filename> on Windows.
+ For example, putting:
+<programlisting>
+\set HISTFILE ~/.psql_history-:DBNAME
+</programlisting>
+ in <filename>~/.psqlrc</filename> will cause
+ <application>psql</application> to maintain a separate history for
+ each database.
+ </para>
+ <note>
+ <para>
+ This feature was shamelessly plagiarized from
+ <application>Bash</application>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HISTSIZE</varname></term>
+ <listitem>
+ <para>
+ The maximum number of commands to store in the command history
+ (default 500). If set to a negative value, no limit is applied.
+ </para>
+ <note>
+ <para>
+ This feature was shamelessly plagiarized from
+ <application>Bash</application>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>HOST</varname></term>
+ <listitem>
+ <para>
+ The database server host you are currently connected to. This is
+ set every time you connect to a database (including program
+ start-up), but can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>IGNOREEOF</varname></term>
+ <listitem>
+ <para>
+ If set to 1 or less, sending an <acronym>EOF</acronym> character (usually
+ <keycombo action="simul"><keycap>Control</keycap><keycap>D</keycap></keycombo>)
+ to an interactive session of <application>psql</application>
+ will terminate the application. If set to a larger numeric value,
+ that many consecutive <acronym>EOF</acronym> characters must be typed to
+ make an interactive session terminate. If the variable is set to a
+ non-numeric value, it is interpreted as 10. The default is 0.
+ </para>
+ <note>
+ <para>
+ This feature was shamelessly plagiarized from
+ <application>Bash</application>.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>LASTOID</varname></term>
+ <listitem>
+ <para>
+ The value of the last affected OID, as returned from an
+ <command>INSERT</command> or <command>\lo_import</command>
+ command. This variable is only guaranteed to be valid until
+ after the result of the next <acronym>SQL</acronym> command has
+ been displayed.
+ <productname>PostgreSQL</productname> servers since version 12 do not
+ support OID system columns anymore, thus LASTOID will always be 0
+ following <command>INSERT</command> when targeting such servers.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>LAST_ERROR_MESSAGE</varname></term>
+ <term><varname>LAST_ERROR_SQLSTATE</varname></term>
+ <listitem>
+ <para>
+ The primary error message and associated SQLSTATE code for the most
+ recent failed query in the current <application>psql</application> session, or
+ an empty string and <literal>00000</literal> if no error has occurred in
+ the current session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <varname>ON_ERROR_ROLLBACK</varname>
+ <indexterm>
+ <primary>rollback</primary>
+ <secondary>psql</secondary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ When set to <literal>on</literal>, if a statement in a transaction block
+ generates an error, the error is ignored and the transaction
+ continues. When set to <literal>interactive</literal>, such errors are only
+ ignored in interactive sessions, and not when reading script
+ files. When set to <literal>off</literal> (the default), a statement in a
+ transaction block that generates an error aborts the entire
+ transaction. The error rollback mode works by issuing an
+ implicit <command>SAVEPOINT</command> for you, just before each command
+ that is in a transaction block, and then rolling back to the
+ savepoint if the command fails.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ON_ERROR_STOP</varname></term>
+ <listitem>
+ <para>
+ By default, command processing continues after an error. When this
+ variable is set to <literal>on</literal>, processing will instead stop
+ immediately. In interactive mode,
+ <application>psql</application> will return to the command prompt;
+ otherwise, <application>psql</application> will exit, returning
+ error code 3 to distinguish this case from fatal error
+ conditions, which are reported using error code 1. In either case,
+ any currently running scripts (the top-level script, if any, and any
+ other scripts which it may have in invoked) will be terminated
+ immediately. If the top-level command string contained multiple SQL
+ commands, processing will stop with the current command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PORT</varname></term>
+ <listitem>
+ <para>
+ The database server port to which you are currently connected.
+ This is set every time you connect to a database (including
+ program start-up), but can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>PROMPT1</varname></term>
+ <term><varname>PROMPT2</varname></term>
+ <term><varname>PROMPT3</varname></term>
+ <listitem>
+ <para>
+ These specify what the prompts <application>psql</application>
+ issues should look like. See <xref
+ linkend="app-psql-prompting"/> below.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>QUIET</varname></term>
+ <listitem>
+ <para>
+ Setting this variable to <literal>on</literal> is equivalent to the command
+ line option <option>-q</option>. It is probably not too useful in
+ interactive mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>ROW_COUNT</varname></term>
+ <listitem>
+ <para>
+ The number of rows returned or affected by the last SQL query, or 0
+ if the query failed or did not report a row count.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SERVER_VERSION_NAME</varname></term>
+ <term><varname>SERVER_VERSION_NUM</varname></term>
+ <listitem>
+ <para>
+ The server's version number as a string, for
+ example <literal>9.6.2</literal>, <literal>10.1</literal> or <literal>11beta1</literal>,
+ and in numeric form, for
+ example <literal>90602</literal> or <literal>100001</literal>.
+ These are set every time you connect to a database
+ (including program start-up), but can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SHOW_ALL_RESULTS</varname></term>
+ <listitem>
+ <para>
+ When this variable is set to <literal>off</literal>, only the last
+ result of a combined query (<literal>\;</literal>) is shown instead of
+ all of them. The default is <literal>on</literal>. The off behavior
+ is for compatibility with older versions of psql.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SHOW_CONTEXT</varname></term>
+ <listitem>
+ <para>
+ This variable can be set to the
+ values <literal>never</literal>, <literal>errors</literal>, or <literal>always</literal>
+ to control whether <literal>CONTEXT</literal> fields are displayed in
+ messages from the server. The default is <literal>errors</literal> (meaning
+ that context will be shown in error messages, but not in notice or
+ warning messages). This setting has no effect
+ when <varname>VERBOSITY</varname> is set to <literal>terse</literal>
+ or <literal>sqlstate</literal>.
+ (See also <command>\errverbose</command>, for use when you want a verbose
+ version of the error you just got.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SINGLELINE</varname></term>
+ <listitem>
+ <para>
+ Setting this variable to <literal>on</literal> is equivalent to the command
+ line option <option>-S</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SINGLESTEP</varname></term>
+ <listitem>
+ <para>
+ Setting this variable to <literal>on</literal> is equivalent to the command
+ line option <option>-s</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>SQLSTATE</varname></term>
+ <listitem>
+ <para>
+ The error code (see <xref linkend="errcodes-appendix"/>) associated
+ with the last SQL query's failure, or <literal>00000</literal> if it
+ succeeded.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>USER</varname></term>
+ <listitem>
+ <para>
+ The database user you are currently connected as. This is set
+ every time you connect to a database (including program
+ start-up), but can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>VERBOSITY</varname></term>
+ <listitem>
+ <para>
+ This variable can be set to the values <literal>default</literal>,
+ <literal>verbose</literal>, <literal>terse</literal>,
+ or <literal>sqlstate</literal> to control the verbosity of error
+ reports.
+ (See also <command>\errverbose</command>, for use when you want a verbose
+ version of the error you just got.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>VERSION</varname></term>
+ <term><varname>VERSION_NAME</varname></term>
+ <term><varname>VERSION_NUM</varname></term>
+ <listitem>
+ <para>
+ These variables are set at program start-up to reflect
+ <application>psql</application>'s version, respectively as a verbose string,
+ a short string (e.g., <literal>9.6.2</literal>, <literal>10.1</literal>,
+ or <literal>11beta1</literal>), and a number (e.g., <literal>90602</literal>
+ or <literal>100001</literal>). They can be changed or unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </refsect3>
+
+ <refsect3 id="app-psql-interpolation" xreflabel="SQL Interpolation">
+ <title><acronym>SQL</acronym> Interpolation</title>
+
+ <para>
+ A key feature of <application>psql</application>
+ variables is that you can substitute (<quote>interpolate</quote>)
+ them into regular <acronym>SQL</acronym> statements, as well as the
+ arguments of meta-commands. Furthermore,
+ <application>psql</application> provides facilities for
+ ensuring that variable values used as SQL literals and identifiers are
+ properly quoted. The syntax for interpolating a value without
+ any quoting is to prepend the variable name with a colon
+ (<literal>:</literal>). For example,
+<programlisting>
+testdb=&gt; <userinput>\set foo 'my_table'</userinput>
+testdb=&gt; <userinput>SELECT * FROM :foo;</userinput>
+</programlisting>
+ would query the table <literal>my_table</literal>. Note that this
+ may be unsafe: the value of the variable is copied literally, so it can
+ contain unbalanced quotes, or even backslash commands. You must make sure
+ that it makes sense where you put it.
+ </para>
+
+ <para>
+ When a value is to be used as an SQL literal or identifier, it is
+ safest to arrange for it to be quoted. To quote the value of
+ a variable as an SQL literal, write a colon followed by the variable
+ name in single quotes. To quote the value as an SQL identifier, write
+ a colon followed by the variable name in double quotes.
+ These constructs deal correctly with quotes and other special
+ characters embedded within the variable value.
+ The previous example would be more safely written this way:
+<programlisting>
+testdb=&gt; <userinput>\set foo 'my_table'</userinput>
+testdb=&gt; <userinput>SELECT * FROM :"foo";</userinput>
+</programlisting>
+ </para>
+
+ <para>
+ Variable interpolation will not be performed within quoted
+ <acronym>SQL</acronym> literals and identifiers. Therefore, a
+ construction such as <literal>':foo'</literal> doesn't work to produce a quoted
+ literal from a variable's value (and it would be unsafe if it did work,
+ since it wouldn't correctly handle quotes embedded in the value).
+ </para>
+
+ <para>
+ One example use of this mechanism is to
+ copy the contents of a file into a table column.
+ First load the file into a variable and then interpolate the variable's
+ value as a quoted string:
+<programlisting>
+testdb=&gt; <userinput>\set content `cat my_file.txt`</userinput>
+testdb=&gt; <userinput>INSERT INTO my_table VALUES (:'content');</userinput>
+</programlisting>
+ (Note that this still won't work if <filename>my_file.txt</filename> contains NUL bytes.
+ <application>psql</application> does not support embedded NUL bytes in variable values.)
+ </para>
+
+ <para>
+ Since colons can legally appear in SQL commands, an apparent attempt
+ at interpolation (that is, <literal>:name</literal>,
+ <literal>:'name'</literal>, or <literal>:"name"</literal>) is not
+ replaced unless the named variable is currently set. In any case, you
+ can escape a colon with a backslash to protect it from substitution.
+ </para>
+
+ <para>
+ The <literal>:{?<replaceable>name</replaceable>}</literal> special syntax returns TRUE
+ or FALSE depending on whether the variable exists or not, and is thus
+ always substituted, unless the colon is backslash-escaped.
+ </para>
+
+ <para>
+ The colon syntax for variables is standard <acronym>SQL</acronym> for
+ embedded query languages, such as <application>ECPG</application>.
+ The colon syntaxes for array slices and type casts are
+ <productname>PostgreSQL</productname> extensions, which can sometimes
+ conflict with the standard usage. The colon-quote syntax for escaping a
+ variable's value as an SQL literal or identifier is a
+ <application>psql</application> extension.
+ </para>
+
+ </refsect3>
+
+ <refsect3 id="app-psql-prompting" xreflabel="Prompting">
+ <title>Prompting</title>
+
+ <para>
+ The prompts <application>psql</application> issues can be customized
+ to your preference. The three variables <varname>PROMPT1</varname>,
+ <varname>PROMPT2</varname>, and <varname>PROMPT3</varname> contain strings
+ and special escape sequences that describe the appearance of the
+ prompt. Prompt 1 is the normal prompt that is issued when
+ <application>psql</application> requests a new command. Prompt 2 is
+ issued when more input is expected during command entry, for example
+ because the command was not terminated with a semicolon or a quote
+ was not closed.
+ Prompt 3 is issued when you are running an <acronym>SQL</acronym>
+ <command>COPY FROM STDIN</command> command and you need to type in
+ a row value on the terminal.
+ </para>
+
+ <para>
+ The value of the selected prompt variable is printed literally,
+ except where a percent sign (<literal>%</literal>) is encountered.
+ Depending on the next character, certain other text is substituted
+ instead. Defined substitutions are:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>%M</literal></term>
+ <listitem>
+ <para>
+ The full host name (with domain name) of the database server,
+ or <literal>[local]</literal> if the connection is over a Unix
+ domain socket, or
+ <literal>[local:<replaceable>/dir/name</replaceable>]</literal>,
+ if the Unix domain socket is not at the compiled in default
+ location.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%m</literal></term>
+ <listitem>
+ <para>
+ The host name of the database server, truncated at the
+ first dot, or <literal>[local]</literal> if the connection is
+ over a Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%&gt;</literal></term>
+ <listitem><para>The port number at which the database server is listening.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%n</literal></term>
+ <listitem>
+ <para>
+ The database session user name. (The expansion of this
+ value might change during a database session as the result
+ of the command <command>SET SESSION
+ AUTHORIZATION</command>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%/</literal></term>
+ <listitem><para>The name of the current database.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%~</literal></term>
+ <listitem><para>Like <literal>%/</literal>, but the output is <literal>~</literal>
+ (tilde) if the database is your default database.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%#</literal></term>
+ <listitem>
+ <para>
+ If the session user is a database superuser, then a
+ <literal>#</literal>, otherwise a <literal>&gt;</literal>.
+ (The expansion of this value might change during a database
+ session as the result of the command <command>SET SESSION
+ AUTHORIZATION</command>.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%p</literal></term>
+ <listitem>
+ <para>The process ID of the backend currently connected to.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%R</literal></term>
+ <listitem>
+ <para>
+ In prompt 1 normally <literal>=</literal>,
+ but <literal>@</literal> if the session is in an inactive branch of a
+ conditional block, or <literal>^</literal> if in single-line mode,
+ or <literal>!</literal> if the session is disconnected from the
+ database (which can happen if <command>\connect</command> fails).
+ In prompt 2 <literal>%R</literal> is replaced by a character that
+ depends on why <application>psql</application> expects more input:
+ <literal>-</literal> if the command simply wasn't terminated yet,
+ but <literal>*</literal> if there is an unfinished
+ <literal>/* ... */</literal> comment,
+ a single quote if there is an unfinished quoted string,
+ a double quote if there is an unfinished quoted identifier,
+ a dollar sign if there is an unfinished dollar-quoted string,
+ or <literal>(</literal> if there is an unmatched left parenthesis.
+ In prompt 3 <literal>%R</literal> doesn't produce anything.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%x</literal></term>
+ <listitem>
+ <para>
+ Transaction status: an empty string when not in a transaction
+ block, or <literal>*</literal> when in a transaction block, or
+ <literal>!</literal> when in a failed transaction block, or <literal>?</literal>
+ when the transaction state is indeterminate (for example, because
+ there is no connection).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%l</literal></term>
+ <listitem>
+ <para>
+ The line number inside the current statement, starting from <literal>1</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%</literal><replaceable class="parameter">digits</replaceable></term>
+ <listitem>
+ <para>
+ The character with the indicated octal code is substituted.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%:</literal><replaceable class="parameter">name</replaceable><literal>:</literal></term>
+ <listitem>
+ <para>
+ The value of the <application>psql</application> variable
+ <replaceable class="parameter">name</replaceable>. See
+ <xref linkend="app-psql-variables"/>, above, for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%`</literal><replaceable class="parameter">command</replaceable><literal>`</literal></term>
+ <listitem>
+ <para>
+ The output of <replaceable
+ class="parameter">command</replaceable>, similar to ordinary
+ <quote>back-tick</quote> substitution.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%[</literal> ... <literal>%]</literal></term>
+ <listitem>
+ <para>
+ Prompts can contain terminal control characters which, for
+ example, change the color, background, or style of the prompt
+ text, or change the title of the terminal window. In order for
+ the line editing features of <application>Readline</application> to work properly, these
+ non-printing control characters must be designated as invisible
+ by surrounding them with <literal>%[</literal> and
+ <literal>%]</literal>. Multiple pairs of these can occur within
+ the prompt. For example:
+<programlisting>
+testdb=&gt; \set PROMPT1 '%[%033[1;33;40m%]%n@%/%R%[%033[0m%]%# '
+</programlisting>
+ results in a boldfaced (<literal>1;</literal>) yellow-on-black
+ (<literal>33;40</literal>) prompt on VT100-compatible, color-capable
+ terminals.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>%w</literal></term>
+ <listitem>
+ <para>
+ Whitespace of the same width as the most recent output of
+ <varname>PROMPT1</varname>. This can be used as a
+ <varname>PROMPT2</varname> setting, so that multi-line statements are
+ aligned with the first line, but there is no visible secondary prompt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ To insert a percent sign into your prompt, write
+ <literal>%%</literal>. The default prompts are
+ <literal>'%/%R%x%# '</literal> for prompts 1 and 2, and
+ <literal>'&gt;&gt; '</literal> for prompt 3.
+ </para>
+
+ <note>
+ <para>
+ This feature was shamelessly plagiarized from
+ <application>tcsh</application>.
+ </para>
+ </note>
+
+ </refsect3>
+
+ <refsect3 id="app-psql-readline">
+ <title>Command-Line Editing</title>
+
+ <indexterm>
+ <primary>Readline</primary>
+ <secondary>in psql</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>libedit</primary>
+ <secondary>in psql</secondary>
+ </indexterm>
+
+ <para>
+ <application>psql</application> uses
+ the <application>Readline</application>
+ or <application>libedit</application> library, if available, for
+ convenient line editing and retrieval. The command history is
+ automatically saved when <application>psql</application> exits and is
+ reloaded when <application>psql</application> starts up. Type
+ up-arrow or control-P to retrieve previous lines.
+ </para>
+
+ <para>
+ You can also use tab completion to fill in partially-typed keywords
+ and SQL object names in many (by no means all) contexts. For example,
+ at the start of a command, typing <literal>ins</literal> and pressing
+ TAB will fill in <literal>insert into </literal>. Then, typing a few
+ characters of a table or schema name and pressing <literal>TAB</literal>
+ will fill in the unfinished name, or offer a menu of possible completions
+ when there's more than one. (Depending on the library in use, you may need to
+ press <literal>TAB</literal> more than once to get a menu.)
+ </para>
+
+ <para>
+ Tab completion for SQL object names requires sending queries to the
+ server to find possible matches. In some contexts this can interfere
+ with other operations. For example, after <command>BEGIN</command>
+ it will be too late to issue <command>SET TRANSACTION ISOLATION
+ LEVEL</command> if a tab-completion query is issued in between.
+ If you do not want tab completion at all, you
+ can turn it off permanently by putting this in a file named
+ <filename>.inputrc</filename> in your home directory:
+<programlisting>
+$if psql
+set disable-completion on
+$endif
+</programlisting>
+ (This is not a <application>psql</application> but a
+ <application>Readline</application> feature. Read its documentation
+ for further details.)
+ </para>
+
+ <para>
+ The <option>-n</option> (<option>--no-readline</option>) command line
+ option can also be useful to disable use
+ of <application>Readline</application> for a single run
+ of <application>psql</application>. This prevents tab completion,
+ use or recording of command line history, and editing of multi-line
+ commands. It is particularly useful when you need to copy-and-paste
+ text that contains <literal>TAB</literal> characters.
+ </para>
+ </refsect3>
+ </refsect2>
+ </refsect1>
+
+
+ <refsect1 id="app-psql-environment" xreflabel="Environment">
+ <title>Environment</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><envar>COLUMNS</envar></term>
+
+ <listitem>
+ <para>
+ If <literal>\pset columns</literal> is zero, controls the
+ width for the <literal>wrapped</literal> format and width for determining
+ if wide output requires the pager or should be switched to the
+ vertical format in expanded auto mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters (see <xref linkend="libpq-envars"/>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PSQL_EDITOR</envar></term>
+ <term><envar>EDITOR</envar></term>
+ <term><envar>VISUAL</envar></term>
+
+ <listitem>
+ <para>
+ Editor used by the <command>\e</command>, <command>\ef</command>,
+ and <command>\ev</command> commands.
+ These variables are examined in the order listed;
+ the first that is set is used.
+ If none of them is set, the default is to use <filename>vi</filename>
+ on Unix systems or <filename>notepad.exe</filename> on Windows systems.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PSQL_EDITOR_LINENUMBER_ARG</envar></term>
+
+ <listitem>
+ <para>
+ When <command>\e</command>, <command>\ef</command>, or
+ <command>\ev</command> is used
+ with a line number argument, this variable specifies the
+ command-line argument used to pass the starting line number to
+ the user's editor. For editors such as <productname>Emacs</productname> or
+ <productname>vi</productname>, this is a plus sign. Include a trailing
+ space in the value of the variable if there needs to be space
+ between the option name and the line number. Examples:
+<programlisting>
+PSQL_EDITOR_LINENUMBER_ARG='+'
+PSQL_EDITOR_LINENUMBER_ARG='--line '
+</programlisting>
+ </para>
+
+ <para>
+ The default is <literal>+</literal> on Unix systems
+ (corresponding to the default editor <filename>vi</filename>,
+ and useful for many other common editors); but there is no
+ default on Windows systems.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PSQL_HISTORY</envar></term>
+
+ <listitem>
+ <para>
+ Alternative location for the command history file. Tilde (<literal>~</literal>) expansion is performed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PSQL_PAGER</envar></term>
+ <term><envar>PAGER</envar></term>
+
+ <listitem>
+ <para>
+ If a query's results do not fit on the screen, they are piped
+ through this command. Typical values are <literal>more</literal>
+ or <literal>less</literal>.
+ Use of the pager can be disabled by setting <envar>PSQL_PAGER</envar>
+ or <envar>PAGER</envar> to an empty string, or by adjusting the
+ pager-related options of the <command>\pset</command> command.
+ These variables are examined in the order listed;
+ the first that is set is used.
+ If neither of them is set, the default is to use <literal>more</literal> on most
+ platforms, but <literal>less</literal> on Cygwin.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PSQL_WATCH_PAGER</envar></term>
+
+ <listitem>
+ <para>
+ When a query is executed repeatedly with the <command>\watch</command>
+ command, a pager is not used by default. This behavior can be changed
+ by setting <envar>PSQL_WATCH_PAGER</envar> to a pager command, on Unix
+ systems. The <literal>pspg</literal> pager (not part of
+ <productname>PostgreSQL</productname> but available in many open source
+ software distributions) can display the output of
+ <command>\watch</command> if started with the option
+ <literal>--stream</literal>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PSQLRC</envar></term>
+
+ <listitem>
+ <para>
+ Alternative location of the user's <filename>.psqlrc</filename> file. Tilde (<literal>~</literal>) expansion is performed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>SHELL</envar></term>
+
+ <listitem>
+ <para>
+ Command executed by the <command>\!</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>TMPDIR</envar></term>
+
+ <listitem>
+ <para>
+ Directory for storing temporary files. The default is
+ <filename>/tmp</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Files</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><filename>psqlrc</filename> and <filename>~/.psqlrc</filename></term>
+ <listitem>
+ <para>
+ Unless it is passed an <option>-X</option> option,
+ <application>psql</application> attempts to read and execute commands
+ from the system-wide startup file (<filename>psqlrc</filename>) and then
+ the user's personal startup file (<filename>~/.psqlrc</filename>), after
+ connecting to the database but before accepting normal commands.
+ These files can be used to set up the client and/or the server to taste,
+ typically with <command>\set</command> and <command>SET</command>
+ commands.
+ </para>
+ <para>
+ The system-wide startup file is named <filename>psqlrc</filename>.
+ By default it is
+ sought in the installation's <quote>system configuration</quote> directory,
+ which is most reliably identified by running <literal>pg_config
+ --sysconfdir</literal>.
+ Typically this directory will be <filename>../etc/</filename>
+ relative to the directory containing
+ the <productname>PostgreSQL</productname> executables.
+ The directory to look in can be set explicitly via
+ the <envar>PGSYSCONFDIR</envar> environment variable.
+ </para>
+ <para>
+ The user's personal startup file is named <filename>.psqlrc</filename>
+ and is sought in the invoking user's home directory.
+ On Windows the personal startup file is instead named
+ <filename>%APPDATA%\postgresql\psqlrc.conf</filename>.
+ In either case, this default file path can be overridden by setting
+ the <envar>PSQLRC</envar> environment variable.
+ </para>
+ <para>
+ Both the system-wide startup file and the user's personal startup file
+ can be made <application>psql</application>-version-specific
+ by appending a dash and the <productname>PostgreSQL</productname>
+ major or minor release identifier to the file name,
+ for example <filename>~/.psqlrc-&majorversion;</filename> or
+ <filename>~/.psqlrc-&version;</filename>.
+ The most specific version-matching file will be read in preference
+ to a non-version-specific file.
+ These version suffixes are added after determining the file path
+ as explained above.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>.psql_history</filename></term>
+ <listitem>
+ <para>
+ The command-line history is stored in the file
+ <filename>~/.psql_history</filename>, or
+ <filename>%APPDATA%\postgresql\psql_history</filename> on Windows.
+ </para>
+ <para>
+ The location of the history file can be set explicitly via
+ the <varname>HISTFILE</varname> <application>psql</application> variable or
+ the <envar>PSQL_HISTORY</envar> environment variable.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <itemizedlist>
+ <listitem>
+ <para><application>psql</application> works best with servers of the same
+ or an older major version. Backslash commands are particularly likely
+ to fail if the server is of a newer version than <application>psql</application>
+ itself. However, backslash commands of the <literal>\d</literal> family should
+ work with servers of versions back to 9.2, though not necessarily with
+ servers newer than <application>psql</application> itself. The general
+ functionality of running SQL commands and displaying query results
+ should also work with servers of a newer major version, but this cannot
+ be guaranteed in all cases.
+ </para>
+ <para>
+ If you want to use <application>psql</application> to connect to several
+ servers of different major versions, it is recommended that you use the
+ newest version of <application>psql</application>. Alternatively, you
+ can keep around a copy of <application>psql</application> from each
+ major version and be sure to use the version that matches the
+ respective server. But in practice, this additional complication should
+ not be necessary.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Before <productname>PostgreSQL</productname> 9.6,
+ the <option>-c</option> option implied <option>-X</option>
+ (<option>--no-psqlrc</option>); this is no longer the case.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Before <productname>PostgreSQL</productname> 8.4,
+ <application>psql</application> allowed the
+ first argument of a single-letter backslash command to start
+ directly after the command, without intervening whitespace.
+ Now, some whitespace is required.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes for Windows Users</title>
+
+ <para>
+ <application>psql</application> is built as a <quote>console
+ application</quote>. Since the Windows console windows use a different
+ encoding than the rest of the system, you must take special care
+ when using 8-bit characters within <application>psql</application>.
+ If <application>psql</application> detects a problematic
+ console code page, it will warn you at startup. To change the
+ console code page, two things are necessary:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Set the code page by entering <userinput>cmd.exe /c chcp
+ 1252</userinput>. (1252 is a code page that is appropriate for
+ German; replace it with your value.) If you are using Cygwin,
+ you can put this command in <filename>/etc/profile</filename>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Set the console font to <literal>Lucida Console</literal>, because the
+ raster font does not work with the ANSI code page.
+ </para>
+ </listitem>
+ </itemizedlist></para>
+
+ </refsect1>
+
+
+ <refsect1 id="app-psql-examples" xreflabel="Examples">
+ <title>Examples</title>
+
+ <para>
+ The first example shows how to spread a command over several lines of
+ input. Notice the changing prompt:
+<programlisting>
+testdb=&gt; <userinput>CREATE TABLE my_table (</userinput>
+testdb(&gt; <userinput> first integer not null default 0,</userinput>
+testdb(&gt; <userinput> second text)</userinput>
+testdb-&gt; <userinput>;</userinput>
+CREATE TABLE
+</programlisting>
+ Now look at the table definition again:
+<programlisting>
+testdb=&gt; <userinput>\d my_table</userinput>
+ Table "public.my_table"
+ Column | Type | Collation | Nullable | Default
+--------+---------+-----------+----------+---------
+ first | integer | | not null | 0
+ second | text | | |
+</programlisting>
+ Now we change the prompt to something more interesting:
+<programlisting>
+testdb=&gt; <userinput>\set PROMPT1 '%n@%m %~%R%# '</userinput>
+peter@localhost testdb=&gt;
+</programlisting>
+ Let's assume you have filled the table with data and want to take a
+ look at it:
+<programlisting>
+peter@localhost testdb=&gt; SELECT * FROM my_table;
+ first | second
+-------+--------
+ 1 | one
+ 2 | two
+ 3 | three
+ 4 | four
+(4 rows)
+</programlisting>
+ You can display tables in different ways by using the
+ <command>\pset</command> command:
+<programlisting>
+peter@localhost testdb=&gt; <userinput>\pset border 2</userinput>
+Border style is 2.
+peter@localhost testdb=&gt; <userinput>SELECT * FROM my_table;</userinput>
++-------+--------+
+| first | second |
++-------+--------+
+| 1 | one |
+| 2 | two |
+| 3 | three |
+| 4 | four |
++-------+--------+
+(4 rows)
+
+peter@localhost testdb=&gt; <userinput>\pset border 0</userinput>
+Border style is 0.
+peter@localhost testdb=&gt; <userinput>SELECT * FROM my_table;</userinput>
+first second
+----- ------
+ 1 one
+ 2 two
+ 3 three
+ 4 four
+(4 rows)
+
+peter@localhost testdb=&gt; <userinput>\pset border 1</userinput>
+Border style is 1.
+peter@localhost testdb=&gt; <userinput>\pset format csv</userinput>
+Output format is csv.
+peter@localhost testdb=&gt; <userinput>\pset tuples_only</userinput>
+Tuples only is on.
+peter@localhost testdb=&gt; <userinput>SELECT second, first FROM my_table;</userinput>
+one,1
+two,2
+three,3
+four,4
+peter@localhost testdb=&gt; <userinput>\pset format unaligned</userinput>
+Output format is unaligned.
+peter@localhost testdb=&gt; <userinput>\pset fieldsep '\t'</userinput>
+Field separator is " ".
+peter@localhost testdb=&gt; <userinput>SELECT second, first FROM my_table;</userinput>
+one 1
+two 2
+three 3
+four 4
+</programlisting>
+ Alternatively, use the short commands:
+<programlisting>
+peter@localhost testdb=&gt; <userinput>\a \t \x</userinput>
+Output format is aligned.
+Tuples only is off.
+Expanded display is on.
+peter@localhost testdb=&gt; <userinput>SELECT * FROM my_table;</userinput>
+-[ RECORD 1 ]-
+first | 1
+second | one
+-[ RECORD 2 ]-
+first | 2
+second | two
+-[ RECORD 3 ]-
+first | 3
+second | three
+-[ RECORD 4 ]-
+first | 4
+second | four
+</programlisting>
+ </para>
+
+ <para>
+ Also, these output format options can be set for just one query by using
+ <literal>\g</literal>:
+<programlisting>
+peter@localhost testdb=&gt; <userinput>SELECT * FROM my_table</userinput>
+peter@localhost testdb-&gt; <userinput>\g (format=aligned tuples_only=off expanded=on)</userinput>
+-[ RECORD 1 ]-
+first | 1
+second | one
+-[ RECORD 2 ]-
+first | 2
+second | two
+-[ RECORD 3 ]-
+first | 3
+second | three
+-[ RECORD 4 ]-
+first | 4
+second | four
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example of using the <command>\df</command> command to
+ find only functions with names matching <literal>int*pl</literal>
+ and whose second argument is of type <type>bigint</type>:
+<programlisting>
+testdb=&gt; <userinput>\df int*pl * bigint</userinput>
+ List of functions
+ Schema | Name | Result data type | Argument data types | Type
+------------+---------+------------------+---------------------+------
+ pg_catalog | int28pl | bigint | smallint, bigint | func
+ pg_catalog | int48pl | bigint | integer, bigint | func
+ pg_catalog | int8pl | bigint | bigint, bigint | func
+(3 rows)
+</programlisting>
+ </para>
+
+ <para>
+ When suitable, query results can be shown in a crosstab representation
+ with the <command>\crosstabview</command> command:
+<programlisting>
+testdb=&gt; <userinput>SELECT first, second, first &gt; 2 AS gt2 FROM my_table;</userinput>
+ first | second | gt2
+-------+--------+-----
+ 1 | one | f
+ 2 | two | f
+ 3 | three | t
+ 4 | four | t
+(4 rows)
+
+testdb=&gt; <userinput>\crosstabview first second</userinput>
+ first | one | two | three | four
+-------+-----+-----+-------+------
+ 1 | f | | |
+ 2 | | f | |
+ 3 | | | t |
+ 4 | | | | t
+(4 rows)
+</programlisting>
+
+This second example shows a multiplication table with rows sorted in reverse
+numerical order and columns with an independent, ascending numerical order.
+<programlisting>
+testdb=&gt; <userinput>SELECT t1.first as "A", t2.first+100 AS "B", t1.first*(t2.first+100) as "AxB",</userinput>
+testdb(&gt; <userinput>row_number() over(order by t2.first) AS ord</userinput>
+testdb(&gt; <userinput>FROM my_table t1 CROSS JOIN my_table t2 ORDER BY 1 DESC</userinput>
+testdb(&gt; <userinput>\crosstabview "A" "B" "AxB" ord</userinput>
+ A | 101 | 102 | 103 | 104
+---+-----+-----+-----+-----
+ 4 | 404 | 408 | 412 | 416
+ 3 | 303 | 306 | 309 | 312
+ 2 | 202 | 204 | 206 | 208
+ 1 | 101 | 102 | 103 | 104
+(4 rows)
+</programlisting></para>
+
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/reassign_owned.sgml b/doc/src/sgml/ref/reassign_owned.sgml
new file mode 100644
index 0000000..ab692bd
--- /dev/null
+++ b/doc/src/sgml/ref/reassign_owned.sgml
@@ -0,0 +1,123 @@
+<!--
+doc/src/sgml/ref/reassign_owned.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-reassign-owned">
+ <indexterm zone="sql-reassign-owned">
+ <primary>REASSIGN OWNED</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>REASSIGN OWNED</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>REASSIGN OWNED</refname>
+ <refpurpose>change the ownership of database objects owned by a database role</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+REASSIGN OWNED BY { <replaceable class="parameter">old_role</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER } [, ...]
+ TO { <replaceable class="parameter">new_role</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>REASSIGN OWNED</command> instructs the system to change
+ the ownership of database objects owned by any of the
+ <replaceable class="parameter">old_roles</replaceable> to
+ <replaceable class="parameter">new_role</replaceable>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">old_role</replaceable></term>
+ <listitem>
+ <para>
+ The name of a role. The ownership of all the objects within the
+ current database, and of all shared objects (databases, tablespaces),
+ owned by this role will be reassigned to
+ <replaceable class="parameter">new_role</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_role</replaceable></term>
+ <listitem>
+ <para>
+ The name of the role that will be made the new owner of the
+ affected objects.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>REASSIGN OWNED</command> is often used to prepare for the
+ removal of one or more roles. Because <command>REASSIGN
+ OWNED</command> does not affect objects within other databases,
+ it is usually necessary to execute this command in each database
+ that contains objects owned by a role that is to be removed.
+ </para>
+
+ <para>
+ <command>REASSIGN OWNED</command> requires membership on both the
+ source role(s) and the target role.
+ </para>
+
+ <para>
+ The <link linkend="sql-drop-owned"><command>DROP OWNED</command></link> command is an alternative that
+ simply drops all the database objects owned by one or more roles.
+ </para>
+
+ <para>
+ The <command>REASSIGN OWNED</command> command does not affect any
+ privileges granted to
+ the <replaceable class="parameter">old_roles</replaceable> on objects
+ that are not owned by them. Likewise, it does not affect default
+ privileges created with <command>ALTER DEFAULT PRIVILEGES</command>.
+ Use <command>DROP OWNED</command> to revoke such privileges.
+ </para>
+
+ <para>
+ See <xref linkend="role-removal"/> for more discussion.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>REASSIGN OWNED</command> command is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-drop-owned"/></member>
+ <member><xref linkend="sql-droprole"/></member>
+ <member><xref linkend="sql-alterdatabase"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/refresh_materialized_view.sgml b/doc/src/sgml/ref/refresh_materialized_view.sgml
new file mode 100644
index 0000000..675d609
--- /dev/null
+++ b/doc/src/sgml/ref/refresh_materialized_view.sgml
@@ -0,0 +1,143 @@
+<!--
+doc/src/sgml/ref/refresh_materialized_view.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-refreshmaterializedview">
+ <indexterm zone="sql-refreshmaterializedview">
+ <primary>REFRESH MATERIALIZED VIEW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>REFRESH MATERIALIZED VIEW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>REFRESH MATERIALIZED VIEW</refname>
+ <refpurpose>replace the contents of a materialized view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] <replaceable class="parameter">name</replaceable>
+ [ WITH [ NO ] DATA ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>REFRESH MATERIALIZED VIEW</command> completely replaces the
+ contents of a materialized view. To execute this command you must be the
+ owner of the materialized view. The old contents are discarded. If
+ <literal>WITH DATA</literal> is specified (or defaults) the backing query
+ is executed to provide the new data, and the materialized view is left in a
+ scannable state. If <literal>WITH NO DATA</literal> is specified no new
+ data is generated and the materialized view is left in an unscannable
+ state.
+ </para>
+ <para>
+ <literal>CONCURRENTLY</literal> and <literal>WITH NO DATA</literal> may not
+ be specified together.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>CONCURRENTLY</literal></term>
+ <listitem>
+ <para>
+ Refresh the materialized view without locking out concurrent selects on
+ the materialized view. Without this option a refresh which affects a
+ lot of rows will tend to use fewer resources and complete more quickly,
+ but could block other connections which are trying to read from the
+ materialized view. This option may be faster in cases where a small
+ number of rows are affected.
+ </para>
+ <para>
+ This option is only allowed if there is at least one
+ <literal>UNIQUE</literal> index on the materialized view which uses only
+ column names and includes all rows; that is, it must not be an
+ expression index or include a <literal>WHERE</literal> clause.
+ </para>
+ <para>
+ This option may not be used when the materialized view is not already
+ populated.
+ </para>
+ <para>
+ Even with this option only one <literal>REFRESH</literal> at a time may
+ run against any one materialized view.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the materialized view to
+ refresh.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If there is an <literal>ORDER BY</literal> clause in the materialized
+ view's defining query, the original contents of the materialized view
+ will be ordered that way; but <command>REFRESH MATERIALIZED
+ VIEW</command> does not guarantee to preserve that ordering.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ This command will replace the contents of the materialized view called
+ <literal>order_summary</literal> using the query from the materialized
+ view's definition, and leave it in a scannable state:
+<programlisting>
+REFRESH MATERIALIZED VIEW order_summary;
+</programlisting>
+ </para>
+
+ <para>
+ This command will free storage associated with the materialized view
+ <literal>annual_statistics_basis</literal> and leave it in an unscannable
+ state:
+<programlisting>
+REFRESH MATERIALIZED VIEW annual_statistics_basis WITH NO DATA;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>REFRESH MATERIALIZED VIEW</command> is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-creatematerializedview"/></member>
+ <member><xref linkend="sql-altermaterializedview"/></member>
+ <member><xref linkend="sql-dropmaterializedview"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml
new file mode 100644
index 0000000..336ca24
--- /dev/null
+++ b/doc/src/sgml/ref/reindex.sgml
@@ -0,0 +1,560 @@
+<!--
+doc/src/sgml/ref/reindex.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-reindex">
+ <indexterm zone="sql-reindex">
+ <primary>REINDEX</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>REINDEX</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>REINDEX</refname>
+ <refpurpose>rebuild indexes</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] <replaceable class="parameter">name</replaceable>
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
+
+ CONCURRENTLY [ <replaceable class="parameter">boolean</replaceable> ]
+ TABLESPACE <replaceable class="parameter">new_tablespace</replaceable>
+ VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>REINDEX</command> rebuilds an index using the data
+ stored in the index's table, replacing the old copy of the index. There are
+ several scenarios in which to use <command>REINDEX</command>:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ An index has become corrupted, and no longer contains valid
+ data. Although in theory this should never happen, in
+ practice indexes can become corrupted due to software bugs or
+ hardware failures. <command>REINDEX</command> provides a
+ recovery method.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ An index has become <quote>bloated</quote>, that is it contains many
+ empty or nearly-empty pages. This can occur with B-tree indexes in
+ <productname>PostgreSQL</productname> under certain uncommon access
+ patterns. <command>REINDEX</command> provides a way to reduce
+ the space consumption of the index by writing a new version of
+ the index without the dead pages. See <xref
+ linkend="routine-reindex"/> for more information.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You have altered a storage parameter (such as fillfactor)
+ for an index, and wish to ensure that the change has taken full effect.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If an index build fails with the <literal>CONCURRENTLY</literal> option,
+ this index is left as <quote>invalid</quote>. Such indexes are useless
+ but it can be convenient to use <command>REINDEX</command> to rebuild
+ them. Note that only <command>REINDEX INDEX</command> is able
+ to perform a concurrent build on an invalid index.
+ </para>
+ </listitem>
+
+ </itemizedlist></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>INDEX</literal></term>
+ <listitem>
+ <para>
+ Recreate the specified index. This form of <command>REINDEX</command>
+ cannot be executed inside a transaction block when used with a
+ partitioned index.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLE</literal></term>
+ <listitem>
+ <para>
+ Recreate all indexes of the specified table. If the table has a
+ secondary <quote>TOAST</quote> table, that is reindexed as well.
+ This form of <command>REINDEX</command> cannot be executed inside a
+ transaction block when used with a partitioned table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SCHEMA</literal></term>
+ <listitem>
+ <para>
+ Recreate all indexes of the specified schema. If a table of this
+ schema has a secondary <quote>TOAST</quote> table, that is reindexed as
+ well. Indexes on shared system catalogs are also processed.
+ This form of <command>REINDEX</command> cannot be executed inside a
+ transaction block.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DATABASE</literal></term>
+ <listitem>
+ <para>
+ Recreate all indexes within the current database.
+ Indexes on shared system catalogs are also processed.
+ This form of <command>REINDEX</command> cannot be executed inside a
+ transaction block.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SYSTEM</literal></term>
+ <listitem>
+ <para>
+ Recreate all indexes on system catalogs within the current database.
+ Indexes on shared system catalogs are included.
+ Indexes on user tables are not processed.
+ This form of <command>REINDEX</command> cannot be executed inside a
+ transaction block.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the specific index, table, or database to be
+ reindexed. Index and table names can be schema-qualified.
+ Presently, <command>REINDEX DATABASE</command> and <command>REINDEX SYSTEM</command>
+ can only reindex the current database, so their parameter must match
+ the current database's name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONCURRENTLY</literal></term>
+ <listitem>
+ <para>
+ When this option is used, <productname>PostgreSQL</productname> will rebuild the
+ index without taking any locks that prevent concurrent inserts,
+ updates, or deletes on the table; whereas a standard index rebuild
+ locks out writes (but not reads) on the table until it's done.
+ There are several caveats to be aware of when using this option
+ &mdash; see <xref linkend="sql-reindex-concurrently"/> below.
+ </para>
+ <para>
+ For temporary tables, <command>REINDEX</command> is always
+ non-concurrent, as no other session can access them, and
+ non-concurrent reindex is cheaper.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLESPACE</literal></term>
+ <listitem>
+ <para>
+ Specifies that indexes will be rebuilt on a new tablespace.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VERBOSE</literal></term>
+ <listitem>
+ <para>
+ Prints a progress report as each index is reindexed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">boolean</replaceable></term>
+ <listitem>
+ <para>
+ Specifies whether the selected option should be turned on or off.
+ You can write <literal>TRUE</literal>, <literal>ON</literal>, or
+ <literal>1</literal> to enable the option, and <literal>FALSE</literal>,
+ <literal>OFF</literal>, or <literal>0</literal> to disable it. The
+ <replaceable class="parameter">boolean</replaceable> value can also
+ be omitted, in which case <literal>TRUE</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_tablespace</replaceable></term>
+ <listitem>
+ <para>
+ The tablespace where indexes will be rebuilt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If you suspect corruption of an index on a user table, you can
+ simply rebuild that index, or all indexes on the table, using
+ <command>REINDEX INDEX</command> or <command>REINDEX TABLE</command>.
+ </para>
+
+ <para>
+ Things are more difficult if you need to recover from corruption of
+ an index on a system table. In this case it's important for the
+ system to not have used any of the suspect indexes itself.
+ (Indeed, in this sort of scenario you might find that server
+ processes are crashing immediately at start-up, due to reliance on
+ the corrupted indexes.) To recover safely, the server must be started
+ with the <option>-P</option> option, which prevents it from using
+ indexes for system catalog lookups.
+ </para>
+
+ <para>
+ One way to do this is to shut down the server and start a single-user
+ <productname>PostgreSQL</productname> server
+ with the <option>-P</option> option included on its command line.
+ Then, <command>REINDEX DATABASE</command>, <command>REINDEX SYSTEM</command>,
+ <command>REINDEX TABLE</command>, or <command>REINDEX INDEX</command> can be
+ issued, depending on how much you want to reconstruct. If in
+ doubt, use <command>REINDEX SYSTEM</command> to select
+ reconstruction of all system indexes in the database. Then quit
+ the single-user server session and restart the regular server.
+ See the <xref linkend="app-postgres"/> reference page for more
+ information about how to interact with the single-user server
+ interface.
+ </para>
+
+ <para>
+ Alternatively, a regular server session can be started with
+ <option>-P</option> included in its command line options.
+ The method for doing this varies across clients, but in all
+ <application>libpq</application>-based clients, it is possible to set
+ the <envar>PGOPTIONS</envar> environment variable to <literal>-P</literal>
+ before starting the client. Note that while this method does not
+ require locking out other clients, it might still be wise to prevent
+ other users from connecting to the damaged database until repairs
+ have been completed.
+ </para>
+
+ <para>
+ <command>REINDEX</command> is similar to a drop and recreate of the index
+ in that the index contents are rebuilt from scratch. However, the locking
+ considerations are rather different. <command>REINDEX</command> locks out writes
+ but not reads of the index's parent table. It also takes an
+ <literal>ACCESS EXCLUSIVE</literal> lock on the specific index being processed,
+ which will block reads that attempt to use that index. In particular,
+ the query planner tries to take an <literal>ACCESS SHARE</literal>
+ lock on every index of the table, regardless of the query, and so
+ <command>REINDEX</command> blocks virtually any queries except for some
+ prepared queries whose plan has been cached and which don't use this very
+ index. In contrast,
+ <command>DROP INDEX</command> momentarily takes an
+ <literal>ACCESS EXCLUSIVE</literal> lock on the parent table, blocking both
+ writes and reads. The subsequent <command>CREATE INDEX</command> locks out
+ writes but not reads; since the index is not there, no read will attempt to
+ use it, meaning that there will be no blocking but reads might be forced
+ into expensive sequential scans.
+ </para>
+
+ <para>
+ Reindexing a single index or table requires being the owner of that
+ index or table. Reindexing a schema or database requires being the
+ owner of that schema or database. Note specifically that it's thus
+ possible for non-superusers to rebuild indexes of tables owned by
+ other users. However, as a special exception, when
+ <command>REINDEX DATABASE</command>, <command>REINDEX SCHEMA</command>
+ or <command>REINDEX SYSTEM</command> is issued by a non-superuser,
+ indexes on shared catalogs will be skipped unless the user owns the
+ catalog (which typically won't be the case). Of course, superusers
+ can always reindex anything.
+ </para>
+
+ <para>
+ Reindexing partitioned indexes or partitioned tables is supported
+ with <command>REINDEX INDEX</command> or <command>REINDEX TABLE</command>,
+ respectively. Each partition of the specified partitioned relation is
+ reindexed in a separate transaction. Those commands cannot be used inside
+ a transaction block when working on a partitioned table or index.
+ </para>
+
+ <para>
+ When using the <literal>TABLESPACE</literal> clause with
+ <command>REINDEX</command> on a partitioned index or table, only the
+ tablespace references of the leaf partitions are updated. As partitioned
+ indexes are not updated, it is recommended to separately use
+ <command>ALTER TABLE ONLY</command> on them so as any new partitions
+ attached inherit the new tablespace. On failure, it may not have moved
+ all the indexes to the new tablespace. Re-running the command will rebuild
+ all the leaf partitions and move previously-unprocessed indexes to the new
+ tablespace.
+ </para>
+
+ <para>
+ If <literal>SCHEMA</literal>, <literal>DATABASE</literal> or
+ <literal>SYSTEM</literal> is used with <literal>TABLESPACE</literal>,
+ system relations are skipped and a single <literal>WARNING</literal>
+ will be generated. Indexes on TOAST tables are rebuilt, but not moved
+ to the new tablespace.
+ </para>
+
+ <refsect2 id="sql-reindex-concurrently" xreflabel="Rebuilding Indexes Concurrently">
+ <title>Rebuilding Indexes Concurrently</title>
+
+ <indexterm zone="sql-reindex-concurrently">
+ <primary>index</primary>
+ <secondary>rebuilding concurrently</secondary>
+ </indexterm>
+
+ <para>
+ Rebuilding an index can interfere with regular operation of a database.
+ Normally <productname>PostgreSQL</productname> locks the table whose index is rebuilt
+ against writes and performs the entire index build with a single scan of the
+ table. Other transactions can still read the table, but if they try to
+ insert, update, or delete rows in the table they will block until the
+ index rebuild is finished. This could have a severe effect if the system is
+ a live production database. Very large tables can take many hours to be
+ indexed, and even for smaller tables, an index rebuild can lock out writers
+ for periods that are unacceptably long for a production system.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> supports rebuilding indexes with minimum locking
+ of writes. This method is invoked by specifying the
+ <literal>CONCURRENTLY</literal> option of <command>REINDEX</command>. When this option
+ is used, <productname>PostgreSQL</productname> must perform two scans of the table
+ for each index that needs to be rebuilt and wait for termination of
+ all existing transactions that could potentially use the index.
+ This method requires more total work than a standard index
+ rebuild and takes significantly longer to complete as it needs to wait
+ for unfinished transactions that might modify the index. However, since
+ it allows normal operations to continue while the index is being rebuilt, this
+ method is useful for rebuilding indexes in a production environment. Of
+ course, the extra CPU, memory and I/O load imposed by the index rebuild
+ may slow down other operations.
+ </para>
+
+ <para>
+ The following steps occur in a concurrent reindex. Each step is run in a
+ separate transaction. If there are multiple indexes to be rebuilt, then
+ each step loops through all the indexes before moving to the next step.
+
+ <orderedlist>
+ <listitem>
+ <para>
+ A new transient index definition is added to the catalog
+ <literal>pg_index</literal>. This definition will be used to replace
+ the old index. A <literal>SHARE UPDATE EXCLUSIVE</literal> lock at
+ session level is taken on the indexes being reindexed as well as their
+ associated tables to prevent any schema modification while processing.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A first pass to build the index is done for each new index. Once the
+ index is built, its flag <literal>pg_index.indisready</literal> is
+ switched to <quote>true</quote> to make it ready for inserts, making it
+ visible to other sessions once the transaction that performed the build
+ is finished. This step is done in a separate transaction for each
+ index.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Then a second pass is performed to add tuples that were added while the
+ first pass was running. This step is also done in a separate
+ transaction for each index.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All the constraints that refer to the index are changed to refer to the
+ new index definition, and the names of the indexes are changed. At
+ this point, <literal>pg_index.indisvalid</literal> is switched to
+ <quote>true</quote> for the new index and to <quote>false</quote> for
+ the old, and a cache invalidation is done causing all sessions that
+ referenced the old index to be invalidated.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The old indexes have <literal>pg_index.indisready</literal> switched to
+ <quote>false</quote> to prevent any new tuple insertions, after waiting
+ for running queries that might reference the old index to complete.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The old indexes are dropped. The <literal>SHARE UPDATE
+ EXCLUSIVE</literal> session locks for the indexes and the table are
+ released.
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ If a problem arises while rebuilding the indexes, such as a
+ uniqueness violation in a unique index, the <command>REINDEX</command>
+ command will fail but leave behind an <quote>invalid</quote> new index in addition to
+ the pre-existing one. This index will be ignored for querying purposes
+ because it might be incomplete; however it will still consume update
+ overhead. The <application>psql</application> <command>\d</command> command will report
+ such an index as <literal>INVALID</literal>:
+
+<programlisting>
+postgres=# \d tab
+ Table "public.tab"
+ Column | Type | Modifiers
+--------+---------+-----------
+ col | integer |
+Indexes:
+ "idx" btree (col)
+ "idx_ccnew" btree (col) INVALID
+</programlisting>
+
+ If the index marked <literal>INVALID</literal> is suffixed
+ <literal>ccnew</literal>, then it corresponds to the transient
+ index created during the concurrent operation, and the recommended
+ recovery method is to drop it using <literal>DROP INDEX</literal>,
+ then attempt <command>REINDEX CONCURRENTLY</command> again.
+ If the invalid index is instead suffixed <literal>ccold</literal>,
+ it corresponds to the original index which could not be dropped;
+ the recommended recovery method is to just drop said index, since the
+ rebuild proper has been successful.
+ </para>
+
+ <para>
+ Regular index builds permit other regular index builds on the same table
+ to occur simultaneously, but only one concurrent index build can occur on a
+ table at a time. In both cases, no other types of schema modification on
+ the table are allowed meanwhile. Another difference is that a regular
+ <command>REINDEX TABLE</command> or <command>REINDEX INDEX</command>
+ command can be performed within a transaction block, but <command>REINDEX
+ CONCURRENTLY</command> cannot.
+ </para>
+
+ <para>
+ Like any long-running transaction, <command>REINDEX</command> on a table
+ can affect which tuples can be removed by concurrent
+ <command>VACUUM</command> on any other table.
+ </para>
+
+ <para>
+ <command>REINDEX SYSTEM</command> does not support
+ <command>CONCURRENTLY</command> since system catalogs cannot be reindexed
+ concurrently.
+ </para>
+
+ <para>
+ Furthermore, indexes for exclusion constraints cannot be reindexed
+ concurrently. If such an index is named directly in this command, an
+ error is raised. If a table or database with exclusion constraint indexes
+ is reindexed concurrently, those indexes will be skipped. (It is possible
+ to reindex such indexes without the <command>CONCURRENTLY</command> option.)
+ </para>
+
+ <para>
+ Each backend running <command>REINDEX</command> will report its progress
+ in the <structname>pg_stat_progress_create_index</structname> view. See
+ <xref linkend="create-index-progress-reporting"/> for details.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Rebuild a single index:
+
+<programlisting>
+REINDEX INDEX my_index;
+</programlisting>
+ </para>
+
+ <para>
+ Rebuild all the indexes on the table <literal>my_table</literal>:
+
+<programlisting>
+REINDEX TABLE my_table;
+</programlisting>
+ </para>
+
+ <para>
+ Rebuild all indexes in a particular database, without trusting the
+ system indexes to be valid already:
+
+<programlisting>
+$ <userinput>export PGOPTIONS="-P"</userinput>
+$ <userinput>psql broken_db</userinput>
+...
+broken_db=&gt; REINDEX DATABASE broken_db;
+broken_db=&gt; \q
+</programlisting></para>
+
+ <para>
+ Rebuild indexes for a table, without blocking read and write operations
+ on involved relations while reindexing is in progress:
+
+<programlisting>
+REINDEX TABLE CONCURRENTLY my_broken_table;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>REINDEX</command> command in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createindex"/></member>
+ <member><xref linkend="sql-dropindex"/></member>
+ <member><xref linkend="app-reindexdb"/></member>
+ <member><xref linkend="create-index-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
new file mode 100644
index 0000000..8cb8bf4
--- /dev/null
+++ b/doc/src/sgml/ref/reindexdb.sgml
@@ -0,0 +1,476 @@
+<!--
+doc/src/sgml/ref/reindexdb.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-reindexdb">
+ <indexterm zone="app-reindexdb">
+ <primary>reindexdb</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>reindexdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>reindexdb</refname>
+ <refpurpose>reindex a <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>reindexdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>-S</option></arg>
+ <arg choice="plain"><option>--schema</option></arg>
+ </group>
+ <replaceable>schema</replaceable>
+ </arg>
+ </arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>-t</option></arg>
+ <arg choice="plain"><option>--table</option></arg>
+ </group>
+ <replaceable>table</replaceable>
+ </arg>
+ </arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>-i</option></arg>
+ <arg choice="plain"><option>--index</option></arg>
+ </group>
+ <replaceable>index</replaceable>
+ </arg>
+ </arg>
+
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>reindexdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+
+ <group choice="plain">
+ <arg choice="plain"><option>-a</option></arg>
+ <arg choice="plain"><option>--all</option></arg>
+ </group>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>reindexdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+
+ <group choice="plain">
+ <arg choice="plain"><option>-s</option></arg>
+ <arg choice="plain"><option>--system</option></arg>
+ </group>
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>reindexdb</application> is a utility for rebuilding indexes
+ in a <productname>PostgreSQL</productname> database.
+ </para>
+
+ <para>
+ <application>reindexdb</application> is a wrapper around the SQL
+ command <link linkend="sql-reindex"><command>REINDEX</command></link>.
+ There is no effective difference between reindexing databases via
+ this utility and via other methods for accessing the server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>reindexdb</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--all</option></term>
+ <listitem>
+ <para>
+ Reindex all databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--concurrently</option></term>
+ <listitem>
+ <para>
+ Use the <literal>CONCURRENTLY</literal> option. See
+ <xref linkend="sql-reindex"/>, where all the caveats of this option
+ are explained in detail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option><optional>-d</optional> <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be reindexed,
+ when <option>-a</option>/<option>--all</option> is not used.
+ If this is not specified, the database name is read
+ from the environment variable <envar>PGDATABASE</envar>. If
+ that is not set, the user name specified for the connection is
+ used. The <replaceable>dbname</replaceable> can be a <link
+ linkend="libpq-connstring">connection string</link>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>reindexdb</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-i <replaceable class="parameter">index</replaceable></option></term>
+ <term><option>--index=<replaceable class="parameter">index</replaceable></option></term>
+ <listitem>
+ <para>
+ Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j <replaceable class="parameter">njobs</replaceable></option></term>
+ <term><option>--jobs=<replaceable class="parameter">njobs</replaceable></option></term>
+ <listitem>
+ <para>
+ Execute the reindex commands in parallel by running
+ <replaceable class="parameter">njobs</replaceable>
+ commands simultaneously. This option may reduce the processing time
+ but it also increases the load on the database server.
+ </para>
+ <para>
+ <application>reindexdb</application> will open
+ <replaceable class="parameter">njobs</replaceable> connections to the
+ database, so make sure your <xref linkend="guc-max-connections"/>
+ setting is high enough to accommodate all connections.
+ </para>
+ <para>
+ Note that this option is incompatible with the <option>--index</option>
+ and <option>--system</option> options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Do not display progress messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-s</option></term>
+ <term><option>--system</option></term>
+ <listitem>
+ <para>
+ Reindex database's system catalogs only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-S <replaceable class="parameter">schema</replaceable></option></term>
+ <term><option>--schema=<replaceable class="parameter">schema</replaceable></option></term>
+ <listitem>
+ <para>
+ Reindex <replaceable class="parameter">schema</replaceable> only.
+ Multiple schemas can be reindexed by writing multiple
+ <option>-S</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">table</replaceable></option></term>
+ <term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
+ <listitem>
+ <para>
+ Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</option> switches.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--tablespace=<replaceable class="parameter">tablespace</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the tablespace where indexes are rebuilt. (This name is
+ processed as a double-quoted identifier.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Print detailed information during processing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>reindexdb</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>reindexdb</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+
+ <para>
+ <application>reindexdb</application> also accepts
+ the following command-line arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server is
+ running. If the value begins with a slash, it is used as the
+ directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>reindexdb</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>reindexdb</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>reindexdb</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to to discover which
+ databases should be reindexed,
+ when <option>-a</option>/<option>--all</option> is used.
+ If not specified, the <literal>postgres</literal> database will be used,
+ or if that does not exist, <literal>template1</literal> will be used.
+ This can be a <link linkend="libpq-connstring">connection
+ string</link>. If so, connection string parameters will override any
+ conflicting command line options. Also, connection string parameters
+ other than the database name itself will be re-used when connecting
+ to other databases.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-reindex"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>reindexdb</application> might need to connect several
+ times to the <productname>PostgreSQL</productname> server, asking
+ for a password each time. It is convenient to have a
+ <filename>~/.pgpass</filename> file in such cases. See <xref
+ linkend="libpq-pgpass"/> for more information.
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To reindex the database <literal>test</literal>:
+<screen>
+<prompt>$ </prompt><userinput>reindexdb test</userinput>
+</screen>
+ </para>
+
+ <para>
+ To reindex the table <literal>foo</literal> and the index
+ <literal>bar</literal> in a database named <literal>abcd</literal>:
+<screen>
+<prompt>$ </prompt><userinput>reindexdb --table=foo --index=bar abcd</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-reindex"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/release_savepoint.sgml b/doc/src/sgml/ref/release_savepoint.sgml
new file mode 100644
index 0000000..daf8eb9
--- /dev/null
+++ b/doc/src/sgml/ref/release_savepoint.sgml
@@ -0,0 +1,131 @@
+<!--
+doc/src/sgml/ref/release_savepoint.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-release-savepoint">
+ <indexterm zone="sql-release-savepoint">
+ <primary>RELEASE SAVEPOINT</primary>
+ </indexterm>
+
+ <indexterm zone="sql-release-savepoint">
+ <primary>savepoints</primary>
+ <secondary>releasing</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>RELEASE SAVEPOINT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>RELEASE SAVEPOINT</refname>
+ <refpurpose>destroy a previously defined savepoint</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+RELEASE [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>RELEASE SAVEPOINT</command> destroys a savepoint previously defined
+ in the current transaction.
+ </para>
+
+ <para>
+ Destroying a savepoint makes it unavailable as a rollback point,
+ but it has no other user visible behavior. It does not undo the
+ effects of commands executed after the savepoint was established.
+ (To do that, see <xref linkend="sql-rollback-to"/>.)
+ Destroying a savepoint when
+ it is no longer needed allows the system to reclaim some resources
+ earlier than transaction end.
+ </para>
+
+ <para>
+ <command>RELEASE SAVEPOINT</command> also destroys all savepoints that were
+ established after the named savepoint was established.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>savepoint_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the savepoint to destroy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Specifying a savepoint name that was not previously defined is an error.
+ </para>
+
+ <para>
+ It is not possible to release a savepoint when the transaction is in
+ an aborted state.
+ </para>
+
+ <para>
+ If multiple savepoints have the same name, only the most recently defined
+ unreleased one is released. Repeated commands will release progressively
+ older savepoints.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To establish and later destroy a savepoint:
+<programlisting>
+BEGIN;
+ INSERT INTO table1 VALUES (3);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (4);
+ RELEASE SAVEPOINT my_savepoint;
+COMMIT;
+</programlisting>
+ The above transaction will insert both 3 and 4.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the <acronym>SQL</acronym> standard. The standard
+ specifies that the key word <literal>SAVEPOINT</literal> is
+ mandatory, but <productname>PostgreSQL</productname> allows it to
+ be omitted.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ <member><xref linkend="sql-rollback-to"/></member>
+ <member><xref linkend="sql-savepoint"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/reset.sgml b/doc/src/sgml/ref/reset.sgml
new file mode 100644
index 0000000..9559907
--- /dev/null
+++ b/doc/src/sgml/ref/reset.sgml
@@ -0,0 +1,113 @@
+<!--
+doc/src/sgml/ref/reset.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-reset">
+ <indexterm zone="sql-reset">
+ <primary>RESET</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>RESET</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>RESET</refname>
+ <refpurpose>restore the value of a run-time parameter to the default value</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+RESET <replaceable class="parameter">configuration_parameter</replaceable>
+RESET ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>RESET</command> restores run-time parameters to their
+ default values. <command>RESET</command> is an alternative
+ spelling for
+<synopsis>
+SET <replaceable class="parameter">configuration_parameter</replaceable> TO DEFAULT
+</synopsis>
+ Refer to <xref linkend="sql-set"/> for
+ details.
+ </para>
+
+ <para>
+ The default value is defined as the value that the parameter would
+ have had, if no <command>SET</command> had ever been issued for it in the
+ current session. The actual source of this value might be a
+ compiled-in default, the configuration file, command-line options,
+ or per-database or per-user default settings. This is subtly different
+ from defining it as <quote>the value that the parameter had at session
+ start</quote>, because if the value came from the configuration file, it
+ will be reset to whatever is specified by the configuration file now.
+ See <xref linkend="runtime-config"/> for details.
+ </para>
+
+ <para>
+ The transactional behavior of <command>RESET</command> is the same as
+ <command>SET</command>: its effects will be undone by transaction rollback.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">configuration_parameter</replaceable></term>
+ <listitem>
+ <para>
+ Name of a settable run-time parameter. Available parameters are
+ documented in <xref linkend="runtime-config"/> and on the
+ <xref linkend="sql-set"/> reference page.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Resets all settable run-time parameters to default values.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Set the <varname>timezone</varname> configuration variable to its default value:
+<screen>
+RESET timezone;
+</screen></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>RESET</command> is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-set"/></member>
+ <member><xref linkend="sql-show"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml
new file mode 100644
index 0000000..62f1971
--- /dev/null
+++ b/doc/src/sgml/ref/revoke.sgml
@@ -0,0 +1,332 @@
+<!--
+doc/src/sgml/ref/revoke.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-revoke">
+ <indexterm zone="sql-revoke">
+ <primary>REVOKE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>REVOKE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>REVOKE</refname>
+ <refpurpose>remove access privileges</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
+ | ALL TABLES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | INSERT | UPDATE | REFERENCES } ( <replaceable class="parameter">column_name</replaceable> [, ...] )
+ [, ...] | ALL [ PRIVILEGES ] ( <replaceable class="parameter">column_name</replaceable> [, ...] ) }
+ ON [ TABLE ] <replaceable class="parameter">table_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { USAGE | SELECT | UPDATE }
+ [, ...] | ALL [ PRIVILEGES ] }
+ ON { SEQUENCE <replaceable class="parameter">sequence_name</replaceable> [, ...]
+ | ALL SEQUENCES IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { CREATE | CONNECT | TEMPORARY | TEMP } [, ...] | ALL [ PRIVILEGES ] }
+ ON DATABASE <replaceable>database_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON DOMAIN <replaceable>domain_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN DATA WRAPPER <replaceable>fdw_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON FOREIGN SERVER <replaceable>server_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { EXECUTE | ALL [ PRIVILEGES ] }
+ ON { { FUNCTION | PROCEDURE | ROUTINE } <replaceable>function_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">arg_name</replaceable> ] <replaceable class="parameter">arg_type</replaceable> [, ...] ] ) ] [, ...]
+ | ALL { FUNCTIONS | PROCEDURES | ROUTINES } IN SCHEMA <replaceable>schema_name</replaceable> [, ...] }
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON LANGUAGE <replaceable>lang_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SELECT | UPDATE } [, ...] | ALL [ PRIVILEGES ] }
+ ON LARGE OBJECT <replaceable class="parameter">loid</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { SET | ALTER SYSTEM } [, ...] | ALL [ PRIVILEGES ] }
+ ON PARAMETER <replaceable class="parameter">configuration_parameter</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { { CREATE | USAGE } [, ...] | ALL [ PRIVILEGES ] }
+ ON SCHEMA <replaceable>schema_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { CREATE | ALL [ PRIVILEGES ] }
+ ON TABLESPACE <replaceable>tablespace_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ GRANT OPTION FOR ]
+ { USAGE | ALL [ PRIVILEGES ] }
+ ON TYPE <replaceable>type_name</replaceable> [, ...]
+ FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+REVOKE [ ADMIN OPTION FOR ]
+ <replaceable class="parameter">role_name</replaceable> [, ...] FROM <replaceable class="parameter">role_specification</replaceable> [, ...]
+ [ GRANTED BY <replaceable class="parameter">role_specification</replaceable> ]
+ [ CASCADE | RESTRICT ]
+
+<phrase>where <replaceable class="parameter">role_specification</replaceable> can be:</phrase>
+
+ [ GROUP ] <replaceable class="parameter">role_name</replaceable>
+ | PUBLIC
+ | CURRENT_ROLE
+ | CURRENT_USER
+ | SESSION_USER
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="sql-revoke-description">
+ <title>Description</title>
+
+ <para>
+ The <command>REVOKE</command> command revokes previously granted
+ privileges from one or more roles. The key word
+ <literal>PUBLIC</literal> refers to the implicitly defined group of
+ all roles.
+ </para>
+
+ <para>
+ See the description of the <link linkend="sql-grant"><command>GRANT</command></link> command for
+ the meaning of the privilege types.
+ </para>
+
+ <para>
+ Note that any particular role will have the sum
+ of privileges granted directly to it, privileges granted to any role it
+ is presently a member of, and privileges granted to
+ <literal>PUBLIC</literal>. Thus, for example, revoking <literal>SELECT</literal> privilege
+ from <literal>PUBLIC</literal> does not necessarily mean that all roles
+ have lost <literal>SELECT</literal> privilege on the object: those who have it granted
+ directly or via another role will still have it. Similarly, revoking
+ <literal>SELECT</literal> from a user might not prevent that user from using
+ <literal>SELECT</literal> if <literal>PUBLIC</literal> or another membership
+ role still has <literal>SELECT</literal> rights.
+ </para>
+
+ <para>
+ If <literal>GRANT OPTION FOR</literal> is specified, only the grant
+ option for the privilege is revoked, not the privilege itself.
+ Otherwise, both the privilege and the grant option are revoked.
+ </para>
+
+ <para>
+ If a user holds a privilege with grant option and has granted it to
+ other users then the privileges held by those other users are
+ called dependent privileges. If the privilege or the grant option
+ held by the first user is being revoked and dependent privileges
+ exist, those dependent privileges are also revoked if
+ <literal>CASCADE</literal> is specified; if it is not, the revoke action
+ will fail. This recursive revocation only affects privileges that
+ were granted through a chain of users that is traceable to the user
+ that is the subject of this <literal>REVOKE</literal> command.
+ Thus, the affected users might effectively keep the privilege if it
+ was also granted through other users.
+ </para>
+
+ <para>
+ When revoking privileges on a table, the corresponding column privileges
+ (if any) are automatically revoked on each column of the table, as well.
+ On the other hand, if a role has been granted privileges on a table, then
+ revoking the same privileges from individual columns will have no effect.
+ </para>
+
+ <para>
+ When revoking membership in a role, <literal>GRANT OPTION</literal> is instead
+ called <literal>ADMIN OPTION</literal>, but the behavior is similar.
+ This form of the command also allows a <literal>GRANTED BY</literal>
+ option, but that option is currently ignored (except for checking
+ the existence of the named role).
+ Note also that this form of the command does not
+ allow the noise word <literal>GROUP</literal>
+ in <replaceable class="parameter">role_specification</replaceable>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-revoke-notes">
+ <title>Notes</title>
+
+ <para>
+ A user can only revoke privileges that were granted directly by
+ that user. If, for example, user A has granted a privilege with
+ grant option to user B, and user B has in turn granted it to user
+ C, then user A cannot revoke the privilege directly from C.
+ Instead, user A could revoke the grant option from user B and use
+ the <literal>CASCADE</literal> option so that the privilege is
+ in turn revoked from user C. For another example, if both A and B
+ have granted the same privilege to C, A can revoke their own grant
+ but not B's grant, so C will still effectively have the privilege.
+ </para>
+
+ <para>
+ When a non-owner of an object attempts to <command>REVOKE</command> privileges
+ on the object, the command will fail outright if the user has no
+ privileges whatsoever on the object. As long as some privilege is
+ available, the command will proceed, but it will revoke only those
+ privileges for which the user has grant options. The <command>REVOKE ALL
+ PRIVILEGES</command> forms will issue a warning message if no grant options are
+ held, while the other forms will issue a warning if grant options for
+ any of the privileges specifically named in the command are not held.
+ (In principle these statements apply to the object owner as well, but
+ since the owner is always treated as holding all grant options, the
+ cases can never occur.)
+ </para>
+
+ <para>
+ If a superuser chooses to issue a <command>GRANT</command> or <command>REVOKE</command>
+ command, the command is performed as though it were issued by the
+ owner of the affected object. Since all privileges ultimately come
+ from the object owner (possibly indirectly via chains of grant options),
+ it is possible for a superuser to revoke all privileges, but this might
+ require use of <literal>CASCADE</literal> as stated above.
+ </para>
+
+ <para>
+ <command>REVOKE</command> can also be done by a role
+ that is not the owner of the affected object, but is a member of the role
+ that owns the object, or is a member of a role that holds privileges
+ <literal>WITH GRANT OPTION</literal> on the object. In this case the
+ command is performed as though it were issued by the containing role that
+ actually owns the object or holds the privileges
+ <literal>WITH GRANT OPTION</literal>. For example, if table
+ <literal>t1</literal> is owned by role <literal>g1</literal>, of which role
+ <literal>u1</literal> is a member, then <literal>u1</literal> can revoke privileges
+ on <literal>t1</literal> that are recorded as being granted by <literal>g1</literal>.
+ This would include grants made by <literal>u1</literal> as well as by other
+ members of role <literal>g1</literal>.
+ </para>
+
+ <para>
+ If the role executing <command>REVOKE</command> holds privileges
+ indirectly via more than one role membership path, it is unspecified
+ which containing role will be used to perform the command. In such cases
+ it is best practice to use <command>SET ROLE</command> to become the specific
+ role you want to do the <command>REVOKE</command> as. Failure to do so might
+ lead to revoking privileges other than the ones you intended, or not
+ revoking anything at all.
+ </para>
+
+ <para>
+ See <xref linkend="ddl-priv"/> for more information about specific
+ privilege types, as well as how to inspect objects' privileges.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-revoke-examples">
+ <title>Examples</title>
+
+ <para>
+ Revoke insert privilege for the public on table
+ <literal>films</literal>:
+
+<programlisting>
+REVOKE INSERT ON films FROM PUBLIC;
+</programlisting>
+ </para>
+
+ <para>
+ Revoke all privileges from user <literal>manuel</literal> on view
+ <literal>kinds</literal>:
+
+<programlisting>
+REVOKE ALL PRIVILEGES ON kinds FROM manuel;
+</programlisting>
+
+ Note that this actually means <quote>revoke all privileges that I
+ granted</quote>.
+ </para>
+
+ <para>
+ Revoke membership in role <literal>admins</literal> from user <literal>joe</literal>:
+
+<programlisting>
+REVOKE admins FROM joe;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="sql-revoke-compatibility">
+ <title>Compatibility</title>
+
+ <para>
+ The compatibility notes of the <link linkend="sql-grant"><command>GRANT</command></link> command
+ apply analogously to <command>REVOKE</command>.
+ The keyword <literal>RESTRICT</literal> or <literal>CASCADE</literal>
+ is required according to the standard, but <productname>PostgreSQL</productname>
+ assumes <literal>RESTRICT</literal> by default.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-grant"/></member>
+ <member><xref linkend="sql-alterdefaultprivileges"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/rollback.sgml b/doc/src/sgml/ref/rollback.sgml
new file mode 100644
index 0000000..142f71e
--- /dev/null
+++ b/doc/src/sgml/ref/rollback.sgml
@@ -0,0 +1,112 @@
+<!--
+doc/src/sgml/ref/rollback.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-rollback">
+ <indexterm zone="sql-rollback">
+ <primary>ROLLBACK</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ROLLBACK</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ROLLBACK</refname>
+ <refpurpose>abort the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ROLLBACK</command> rolls back the current transaction and causes
+ all the updates made by the transaction to be discarded.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <indexterm zone="sql-rollback-chain">
+ <primary>chained transactions</primary>
+ </indexterm>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>WORK</literal></term>
+ <term><literal>TRANSACTION</literal></term>
+ <listitem>
+ <para>
+ Optional key words. They have no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry id="sql-rollback-chain">
+ <term><literal>AND CHAIN</literal></term>
+ <listitem>
+ <para>
+ If <literal>AND CHAIN</literal> is specified, a new transaction is
+ immediately started with the same transaction characteristics (see <xref
+ linkend="sql-set-transaction"/>) as the just finished one. Otherwise,
+ no new transaction is started.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-commit"><command>COMMIT</command></link> to
+ successfully terminate a transaction.
+ </para>
+
+ <para>
+ Issuing <command>ROLLBACK</command> outside of a transaction
+ block emits a warning and otherwise has no effect. <command>ROLLBACK AND
+ CHAIN</command> outside of a transaction block is an error.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To abort all changes:
+<programlisting>
+ROLLBACK;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The command <command>ROLLBACK</command> conforms to the SQL standard. The
+ form <literal>ROLLBACK TRANSACTION</literal> is a PostgreSQL extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-rollback-to"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/rollback_prepared.sgml b/doc/src/sgml/ref/rollback_prepared.sgml
new file mode 100644
index 0000000..175a3e9
--- /dev/null
+++ b/doc/src/sgml/ref/rollback_prepared.sgml
@@ -0,0 +1,107 @@
+<!--
+doc/src/sgml/ref/rollback_prepared.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-rollback-prepared">
+ <indexterm zone="sql-rollback-prepared">
+ <primary>ROLLBACK PREPARED</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ROLLBACK PREPARED</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ROLLBACK PREPARED</refname>
+ <refpurpose>cancel a transaction that was earlier prepared for two-phase commit</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ROLLBACK PREPARED <replaceable class="parameter">transaction_id</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>ROLLBACK PREPARED</command> rolls back a transaction that is in
+ prepared state.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">transaction_id</replaceable></term>
+ <listitem>
+ <para>
+ The transaction identifier of the transaction that is to be
+ rolled back.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ To roll back a prepared transaction, you must be either the same user that
+ executed the transaction originally, or a superuser. But you do not
+ have to be in the same session that executed the transaction.
+ </para>
+
+ <para>
+ This command cannot be executed inside a transaction block. The prepared
+ transaction is rolled back immediately.
+ </para>
+
+ <para>
+ All currently available prepared transactions are listed in the
+ <link linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>
+ system view.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sql-rollback-prepared-examples">
+ <title>Examples</title>
+ <para>
+ Roll back the transaction identified by the transaction
+ identifier <literal>foobar</literal>:
+
+<programlisting>
+ROLLBACK PREPARED 'foobar';
+</programlisting></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <command>ROLLBACK PREPARED</command> is a
+ <productname>PostgreSQL</productname> extension. It is intended for use by
+ external transaction management systems, some of which are covered by
+ standards (such as X/Open XA), but the SQL side of those systems is not
+ standardized.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-prepare-transaction"/></member>
+ <member><xref linkend="sql-commit-prepared"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/rollback_to.sgml b/doc/src/sgml/ref/rollback_to.sgml
new file mode 100644
index 0000000..27fa95c
--- /dev/null
+++ b/doc/src/sgml/ref/rollback_to.sgml
@@ -0,0 +1,158 @@
+<!--
+doc/src/sgml/ref/rollback_to.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-rollback-to">
+ <indexterm zone="sql-rollback-to">
+ <primary>ROLLBACK TO SAVEPOINT</primary>
+ </indexterm>
+
+ <indexterm zone="sql-rollback-to">
+ <primary>savepoints</primary>
+ <secondary>rolling back</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>ROLLBACK TO SAVEPOINT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>ROLLBACK TO SAVEPOINT</refname>
+ <refpurpose>roll back to a savepoint</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] <replaceable>savepoint_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ Roll back all commands that were executed after the savepoint was
+ established. The savepoint remains valid and can be rolled back to
+ again later, if needed.
+ </para>
+
+ <para>
+ <command>ROLLBACK TO SAVEPOINT</command> implicitly destroys all savepoints that
+ were established after the named savepoint.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">savepoint_name</replaceable></term>
+ <listitem>
+ <para>
+ The savepoint to roll back to.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-release-savepoint"><command>RELEASE SAVEPOINT</command></link> to destroy a savepoint
+ without discarding the effects of commands executed after it was
+ established.
+ </para>
+
+ <para>
+ Specifying a savepoint name that has not been established is an error.
+ </para>
+
+ <para>
+ Cursors have somewhat non-transactional behavior with respect to
+ savepoints. Any cursor that is opened inside a savepoint will be closed
+ when the savepoint is rolled back. If a previously opened cursor is
+ affected by a <command>FETCH</command> or <command>MOVE</command> command inside a
+ savepoint that is later rolled back, the cursor remains at the
+ position that <command>FETCH</command> left it pointing to (that is, the cursor
+ motion caused by <command>FETCH</command> is not rolled back).
+ Closing a cursor is not undone by rolling back, either.
+ However, other side-effects caused by the cursor's query (such as
+ side-effects of volatile functions called by the query) <emphasis>are</emphasis>
+ rolled back if they occur during a savepoint that is later rolled back.
+ A cursor whose execution causes a transaction to abort is put in a
+ cannot-execute state, so while the transaction can be restored using
+ <command>ROLLBACK TO SAVEPOINT</command>, the cursor can no longer be used.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To undo the effects of the commands executed after <literal>my_savepoint</literal>
+ was established:
+<programlisting>
+ROLLBACK TO SAVEPOINT my_savepoint;
+</programlisting>
+ </para>
+
+ <para>
+ Cursor positions are not affected by savepoint rollback:
+<programlisting>
+BEGIN;
+
+DECLARE foo CURSOR FOR SELECT 1 UNION SELECT 2;
+
+SAVEPOINT foo;
+
+FETCH 1 FROM foo;
+ ?column?
+----------
+ 1
+
+ROLLBACK TO SAVEPOINT foo;
+
+FETCH 1 FROM foo;
+ ?column?
+----------
+ 2
+
+COMMIT;
+</programlisting></para>
+
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <acronym>SQL</acronym> standard specifies that the key word
+ <literal>SAVEPOINT</literal> is mandatory, but <productname>PostgreSQL</productname>
+ and <productname>Oracle</productname> allow it to be omitted. SQL allows
+ only <literal>WORK</literal>, not <literal>TRANSACTION</literal>, as a noise word
+ after <literal>ROLLBACK</literal>. Also, SQL has an optional clause
+ <literal>AND [ NO ] CHAIN</literal> which is not currently supported by
+ <productname>PostgreSQL</productname>. Otherwise, this command conforms to
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-release-savepoint"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ <member><xref linkend="sql-savepoint"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/savepoint.sgml b/doc/src/sgml/ref/savepoint.sgml
new file mode 100644
index 0000000..f84ac3d
--- /dev/null
+++ b/doc/src/sgml/ref/savepoint.sgml
@@ -0,0 +1,165 @@
+<!--
+doc/src/sgml/ref/savepoint.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-savepoint">
+ <indexterm zone="sql-savepoint">
+ <primary>SAVEPOINT</primary>
+ </indexterm>
+
+ <indexterm zone="sql-savepoint">
+ <primary>savepoints</primary>
+ <secondary>defining</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SAVEPOINT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SAVEPOINT</refname>
+ <refpurpose>define a new savepoint within the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SAVEPOINT <replaceable>savepoint_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SAVEPOINT</command> establishes a new savepoint within
+ the current transaction.
+ </para>
+
+ <para>
+ A savepoint is a special mark inside a transaction that allows all commands
+ that are executed after it was established to be rolled back, restoring
+ the transaction state to what it was at the time of the savepoint.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable>savepoint_name</replaceable></term>
+ <listitem>
+ <para>
+ The name to give to the new savepoint. If savepoints with the
+ same name already exist, they will be inaccessible until newer
+ identically-named savepoints are released.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Use <link linkend="sql-rollback-to"><command>ROLLBACK TO</command></link> to
+ rollback to a savepoint. Use <link linkend="sql-release-savepoint"><command>RELEASE SAVEPOINT</command></link>
+ to destroy a savepoint, keeping
+ the effects of commands executed after it was established.
+ </para>
+
+ <para>
+ Savepoints can only be established when inside a transaction block.
+ There can be multiple savepoints defined within a transaction.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To establish a savepoint and later undo the effects of all commands executed
+ after it was established:
+<programlisting>
+BEGIN;
+ INSERT INTO table1 VALUES (1);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (2);
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (3);
+COMMIT;
+</programlisting>
+ The above transaction will insert the values 1 and 3, but not 2.
+ </para>
+
+ <para>
+ To establish and later destroy a savepoint:
+<programlisting>
+BEGIN;
+ INSERT INTO table1 VALUES (3);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (4);
+ RELEASE SAVEPOINT my_savepoint;
+COMMIT;
+</programlisting>
+ The above transaction will insert both 3 and 4.
+ </para>
+
+ <para>
+ To use a single savepoint name:
+<programlisting>
+BEGIN;
+ INSERT INTO table1 VALUES (1);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (2);
+ SAVEPOINT my_savepoint;
+ INSERT INTO table1 VALUES (3);
+
+ -- rollback to the second savepoint
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ SELECT * FROM table1; -- shows rows 1 and 2
+
+ -- release the second savepoint
+ RELEASE SAVEPOINT my_savepoint;
+
+ -- rollback to the first savepoint
+ ROLLBACK TO SAVEPOINT my_savepoint;
+ SELECT * FROM table1; -- shows only row 1
+COMMIT;
+</programlisting>
+ The above transaction shows row 3 being rolled back first, then row 2.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ SQL requires a savepoint to be destroyed automatically when another
+ savepoint with the same name is established. In
+ <productname>PostgreSQL</productname>, the old savepoint is kept, though only the more
+ recent one will be used when rolling back or releasing. (Releasing the
+ newer savepoint with <command>RELEASE SAVEPOINT</command> will cause the older one
+ to again become accessible to <command>ROLLBACK TO SAVEPOINT</command> and
+ <command>RELEASE SAVEPOINT</command>.) Otherwise, <command>SAVEPOINT</command> is
+ fully SQL conforming.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-release-savepoint"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ <member><xref linkend="sql-rollback-to"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/security_label.sgml b/doc/src/sgml/ref/security_label.sgml
new file mode 100644
index 0000000..5f96b7e
--- /dev/null
+++ b/doc/src/sgml/ref/security_label.sgml
@@ -0,0 +1,233 @@
+<!--
+doc/src/sgml/ref/security_label.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-security-label">
+ <indexterm zone="sql-security-label">
+ <primary>SECURITY LABEL</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SECURITY LABEL</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SECURITY LABEL</refname>
+ <refpurpose>define or change a security label applied to an object</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SECURITY LABEL [ FOR <replaceable class="parameter">provider</replaceable> ] ON
+{
+ TABLE <replaceable class="parameter">object_name</replaceable> |
+ COLUMN <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> |
+ AGGREGATE <replaceable class="parameter">aggregate_name</replaceable> ( <replaceable>aggregate_signature</replaceable> ) |
+ DATABASE <replaceable class="parameter">object_name</replaceable> |
+ DOMAIN <replaceable class="parameter">object_name</replaceable> |
+ EVENT TRIGGER <replaceable class="parameter">object_name</replaceable> |
+ FOREIGN TABLE <replaceable class="parameter">object_name</replaceable>
+ FUNCTION <replaceable class="parameter">function_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ LARGE OBJECT <replaceable class="parameter">large_object_oid</replaceable> |
+ MATERIALIZED VIEW <replaceable class="parameter">object_name</replaceable> |
+ [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">object_name</replaceable> |
+ PROCEDURE <replaceable class="parameter">procedure_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ PUBLICATION <replaceable class="parameter">object_name</replaceable> |
+ ROLE <replaceable class="parameter">object_name</replaceable> |
+ ROUTINE <replaceable class="parameter">routine_name</replaceable> [ ( [ [ <replaceable class="parameter">argmode</replaceable> ] [ <replaceable class="parameter">argname</replaceable> ] <replaceable class="parameter">argtype</replaceable> [, ...] ] ) ] |
+ SCHEMA <replaceable class="parameter">object_name</replaceable> |
+ SEQUENCE <replaceable class="parameter">object_name</replaceable> |
+ SUBSCRIPTION <replaceable class="parameter">object_name</replaceable> |
+ TABLESPACE <replaceable class="parameter">object_name</replaceable> |
+ TYPE <replaceable class="parameter">object_name</replaceable> |
+ VIEW <replaceable class="parameter">object_name</replaceable>
+} IS { <replaceable class="parameter">string_literal</replaceable> | NULL }
+
+<phrase>where <replaceable>aggregate_signature</replaceable> is:</phrase>
+
+* |
+[ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] |
+[ [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ] ] ORDER BY [ <replaceable>argmode</replaceable> ] [ <replaceable>argname</replaceable> ] <replaceable>argtype</replaceable> [ , ... ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SECURITY LABEL</command> applies a security label to a database
+ object. An arbitrary number of security labels, one per label provider, can
+ be associated with a given database object. Label providers are loadable
+ modules which register themselves by using the function
+ <function>register_label_provider</function>.
+ </para>
+
+ <note>
+ <para>
+ <function>register_label_provider</function> is not an SQL function; it can
+ only be called from C code loaded into the backend.
+ </para>
+ </note>
+
+ <para>
+ The label provider determines whether a given label is valid and whether
+ it is permissible to assign that label to a given object. The meaning of a
+ given label is likewise at the discretion of the label provider.
+ <productname>PostgreSQL</productname> places no restrictions on whether or how a
+ label provider must interpret security labels; it merely provides a
+ mechanism for storing them. In practice, this facility is intended to allow
+ integration with label-based mandatory access control (MAC) systems such as
+ <productname>SELinux</productname>. Such systems make all access control decisions
+ based on object labels, rather than traditional discretionary access control
+ (DAC) concepts such as users and groups.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">object_name</replaceable></term>
+ <term><replaceable class="parameter">table_name.column_name</replaceable></term>
+ <term><replaceable class="parameter">aggregate_name</replaceable></term>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <term><replaceable class="parameter">procedure_name</replaceable></term>
+ <term><replaceable class="parameter">routine_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the object to be labeled. Names of objects that reside in
+ schemas (tables, functions, etc.) can be schema-qualified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">provider</replaceable></term>
+ <listitem>
+ <para>
+ The name of the provider with which this label is to be associated. The
+ named provider must be loaded and must consent to the proposed labeling
+ operation. If exactly one provider is loaded, the provider name may be
+ omitted for brevity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argmode</replaceable></term>
+
+ <listitem>
+ <para>
+ The mode of a function, procedure, or aggregate
+ argument: <literal>IN</literal>, <literal>OUT</literal>,
+ <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ If omitted, the default is <literal>IN</literal>.
+ Note that <command>SECURITY LABEL</command> does not actually
+ pay any attention to <literal>OUT</literal> arguments, since only the input
+ arguments are needed to determine the function's identity.
+ So it is sufficient to list the <literal>IN</literal>, <literal>INOUT</literal>,
+ and <literal>VARIADIC</literal> arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argname</replaceable></term>
+
+ <listitem>
+ <para>
+ The name of a function, procedure, or aggregate argument.
+ Note that <command>SECURITY LABEL</command> does not actually
+ pay any attention to argument names, since only the argument data
+ types are needed to determine the function's identity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">argtype</replaceable></term>
+
+ <listitem>
+ <para>
+ The data type of a function, procedure, or aggregate argument.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">large_object_oid</replaceable></term>
+ <listitem>
+ <para>
+ The OID of the large object.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROCEDURAL</literal></term>
+
+ <listitem>
+ <para>
+ This is a noise word.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">string_literal</replaceable></term>
+ <listitem>
+ <para>
+ The new setting of the security label, written as a string literal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NULL</literal></term>
+ <listitem>
+ <para>
+ Write <literal>NULL</literal> to drop the security label.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ The following example shows how the security label of a table could
+ be set or changed:
+
+<programlisting>
+SECURITY LABEL FOR selinux ON TABLE mytable IS 'system_u:object_r:sepgsql_table_t:s0';
+</programlisting>
+
+ To remove the label:
+
+<programlisting>
+SECURITY LABEL FOR selinux ON TABLE mytable IS NULL;
+</programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+ <para>
+ There is no <command>SECURITY LABEL</command> command in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+ <simplelist type="inline">
+ <member><xref linkend="sepgsql"/></member>
+ <member><filename>src/test/modules/dummy_seclabel</filename></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml
new file mode 100644
index 0000000..bd72725
--- /dev/null
+++ b/doc/src/sgml/ref/select.sgml
@@ -0,0 +1,2197 @@
+<!--
+doc/src/sgml/ref/select.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-select">
+ <indexterm zone="sql-select">
+ <primary>SELECT</primary>
+ </indexterm>
+
+ <indexterm zone="sql-select">
+ <primary>TABLE command</primary>
+ </indexterm>
+
+ <indexterm zone="sql-select">
+ <primary>WITH</primary>
+ <secondary>in SELECT</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SELECT</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SELECT</refname>
+ <refname>TABLE</refname>
+ <refname>WITH</refname>
+ <refpurpose>retrieve rows from a table or view</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
+SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replaceable> [, ...] ) ] ]
+ [ * | <replaceable class="parameter">expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
+ [ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ]
+ [ WHERE <replaceable class="parameter">condition</replaceable> ]
+ [ GROUP BY [ ALL | DISTINCT ] <replaceable class="parameter">grouping_element</replaceable> [, ...] ]
+ [ HAVING <replaceable class="parameter">condition</replaceable> ]
+ [ WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceable class="parameter">window_definition</replaceable> ) [, ...] ]
+ [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] <replaceable class="parameter">select</replaceable> ]
+ [ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+ [ LIMIT { <replaceable class="parameter">count</replaceable> | ALL } ]
+ [ OFFSET <replaceable class="parameter">start</replaceable> [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } { ONLY | WITH TIES } ]
+ [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]
+
+<phrase>where <replaceable class="parameter">from_item</replaceable> can be one of:</phrase>
+
+ [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ] ]
+ [ TABLESAMPLE <replaceable class="parameter">sampling_method</replaceable> ( <replaceable class="parameter">argument</replaceable> [, ...] ) [ REPEATABLE ( <replaceable class="parameter">seed</replaceable> ) ] ]
+ [ LATERAL ] ( <replaceable class="parameter">select</replaceable> ) [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ]
+ <replaceable class="parameter">with_query_name</replaceable> [ [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ] ]
+ [ LATERAL ] <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] )
+ [ WITH ORDINALITY ] [ [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ] ]
+ [ LATERAL ] <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) [ AS ] <replaceable class="parameter">alias</replaceable> ( <replaceable class="parameter">column_definition</replaceable> [, ...] )
+ [ LATERAL ] <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) AS ( <replaceable class="parameter">column_definition</replaceable> [, ...] )
+ [ LATERAL ] ROWS FROM( <replaceable class="parameter">function_name</replaceable> ( [ <replaceable class="parameter">argument</replaceable> [, ...] ] ) [ AS ( <replaceable class="parameter">column_definition</replaceable> [, ...] ) ] [, ...] )
+ [ WITH ORDINALITY ] [ [ AS ] <replaceable class="parameter">alias</replaceable> [ ( <replaceable class="parameter">column_alias</replaceable> [, ...] ) ] ]
+ <replaceable class="parameter">from_item</replaceable> <replaceable class="parameter">join_type</replaceable> <replaceable class="parameter">from_item</replaceable> { ON <replaceable class="parameter">join_condition</replaceable> | USING ( <replaceable class="parameter">join_column</replaceable> [, ...] ) [ AS <replaceable class="parameter">join_using_alias</replaceable> ] }
+ <replaceable class="parameter">from_item</replaceable> NATURAL <replaceable class="parameter">join_type</replaceable> <replaceable class="parameter">from_item</replaceable>
+ <replaceable class="parameter">from_item</replaceable> CROSS JOIN <replaceable class="parameter">from_item</replaceable>
+
+<phrase>and <replaceable class="parameter">grouping_element</replaceable> can be one of:</phrase>
+
+ ( )
+ <replaceable class="parameter">expression</replaceable>
+ ( <replaceable class="parameter">expression</replaceable> [, ...] )
+ ROLLUP ( { <replaceable class="parameter">expression</replaceable> | ( <replaceable class="parameter">expression</replaceable> [, ...] ) } [, ...] )
+ CUBE ( { <replaceable class="parameter">expression</replaceable> | ( <replaceable class="parameter">expression</replaceable> [, ...] ) } [, ...] )
+ GROUPING SETS ( <replaceable class="parameter">grouping_element</replaceable> [, ...] )
+
+<phrase>and <replaceable class="parameter">with_query</replaceable> is:</phrase>
+
+ <replaceable class="parameter">with_query_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( <replaceable class="parameter">select</replaceable> | <replaceable class="parameter">values</replaceable> | <replaceable class="parameter">insert</replaceable> | <replaceable class="parameter">update</replaceable> | <replaceable class="parameter">delete</replaceable> )
+ [ SEARCH { BREADTH | DEPTH } FIRST BY <replaceable>column_name</replaceable> [, ...] SET <replaceable>search_seq_col_name</replaceable> ]
+ [ CYCLE <replaceable>column_name</replaceable> [, ...] SET <replaceable>cycle_mark_col_name</replaceable> [ TO <replaceable>cycle_mark_value</replaceable> DEFAULT <replaceable>cycle_mark_default</replaceable> ] USING <replaceable>cycle_path_col_name</replaceable> ]
+
+TABLE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ]
+</synopsis>
+
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SELECT</command> retrieves rows from zero or more tables.
+ The general processing of <command>SELECT</command> is as follows:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ All queries in the <literal>WITH</literal> list are computed.
+ These effectively serve as temporary tables that can be referenced
+ in the <literal>FROM</literal> list. A <literal>WITH</literal> query
+ that is referenced more than once in <literal>FROM</literal> is
+ computed only once,
+ unless specified otherwise with <literal>NOT MATERIALIZED</literal>.
+ (See <xref linkend="sql-with"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All elements in the <literal>FROM</literal> list are computed.
+ (Each element in the <literal>FROM</literal> list is a real or
+ virtual table.) If more than one element is specified in the
+ <literal>FROM</literal> list, they are cross-joined together.
+ (See <xref linkend="sql-from"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the <literal>WHERE</literal> clause is specified, all rows
+ that do not satisfy the condition are eliminated from the
+ output. (See <xref linkend="sql-where"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the <literal>GROUP BY</literal> clause is specified,
+ or if there are aggregate function calls, the
+ output is combined into groups of rows that match on one or more
+ values, and the results of aggregate functions are computed.
+ If the <literal>HAVING</literal> clause is present, it
+ eliminates groups that do not satisfy the given condition. (See
+ <xref linkend="sql-groupby"/> and
+ <xref linkend="sql-having"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The actual output rows are computed using the
+ <command>SELECT</command> output expressions for each selected
+ row or row group. (See <xref linkend="sql-select-list"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><literal>SELECT DISTINCT</literal> eliminates duplicate rows from the
+ result. <literal>SELECT DISTINCT ON</literal> eliminates rows that
+ match on all the specified expressions. <literal>SELECT ALL</literal>
+ (the default) will return all candidate rows, including
+ duplicates. (See <xref linkend="sql-distinct"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using the operators <literal>UNION</literal>,
+ <literal>INTERSECT</literal>, and <literal>EXCEPT</literal>, the
+ output of more than one <command>SELECT</command> statement can
+ be combined to form a single result set. The
+ <literal>UNION</literal> operator returns all rows that are in
+ one or both of the result sets. The
+ <literal>INTERSECT</literal> operator returns all rows that are
+ strictly in both result sets. The <literal>EXCEPT</literal>
+ operator returns the rows that are in the first result set but
+ not in the second. In all three cases, duplicate rows are
+ eliminated unless <literal>ALL</literal> is specified. The noise
+ word <literal>DISTINCT</literal> can be added to explicitly specify
+ eliminating duplicate rows. Notice that <literal>DISTINCT</literal> is
+ the default behavior here, even though <literal>ALL</literal> is
+ the default for <command>SELECT</command> itself. (See
+ <xref linkend="sql-union"/>, <xref linkend="sql-intersect"/>, and
+ <xref linkend="sql-except"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the <literal>ORDER BY</literal> clause is specified, the
+ returned rows are sorted in the specified order. If
+ <literal>ORDER BY</literal> is not given, the rows are returned
+ in whatever order the system finds fastest to produce. (See
+ <xref linkend="sql-orderby"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the <literal>LIMIT</literal> (or <literal>FETCH FIRST</literal>) or <literal>OFFSET</literal>
+ clause is specified, the <command>SELECT</command> statement
+ only returns a subset of the result rows. (See <xref
+ linkend="sql-limit"/> below.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If <literal>FOR UPDATE</literal>, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR SHARE</literal>
+ or <literal>FOR KEY SHARE</literal>
+ is specified, the
+ <command>SELECT</command> statement locks the selected rows
+ against concurrent updates. (See <xref linkend="sql-for-update-share"/>
+ below.)
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+
+ <para>
+ You must have <literal>SELECT</literal> privilege on each column used
+ in a <command>SELECT</command> command. The use of <literal>FOR NO KEY UPDATE</literal>,
+ <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal> or <literal>FOR KEY SHARE</literal> requires
+ <literal>UPDATE</literal> privilege as well (for at least one column
+ of each table so selected).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <refsect2 id="sql-with" xreflabel="WITH Clause">
+ <title><literal>WITH</literal> Clause</title>
+
+ <para>
+ The <literal>WITH</literal> clause allows you to specify one or more
+ subqueries that can be referenced by name in the primary query.
+ The subqueries effectively act as temporary tables or views
+ for the duration of the primary query.
+ Each subquery can be a <command>SELECT</command>, <command>TABLE</command>, <command>VALUES</command>,
+ <command>INSERT</command>, <command>UPDATE</command> or
+ <command>DELETE</command> statement.
+ When writing a data-modifying statement (<command>INSERT</command>,
+ <command>UPDATE</command> or <command>DELETE</command>) in
+ <literal>WITH</literal>, it is usual to include a <literal>RETURNING</literal> clause.
+ It is the output of <literal>RETURNING</literal>, <emphasis>not</emphasis> the underlying
+ table that the statement modifies, that forms the temporary table that is
+ read by the primary query. If <literal>RETURNING</literal> is omitted, the
+ statement is still executed, but it produces no output so it cannot be
+ referenced as a table by the primary query.
+ </para>
+
+ <para>
+ A name (without schema qualification) must be specified for each
+ <literal>WITH</literal> query. Optionally, a list of column names
+ can be specified; if this is omitted,
+ the column names are inferred from the subquery.
+ </para>
+
+ <para>
+ If <literal>RECURSIVE</literal> is specified, it allows a
+ <command>SELECT</command> subquery to reference itself by name. Such a
+ subquery must have the form
+<synopsis>
+<replaceable class="parameter">non_recursive_term</replaceable> UNION [ ALL | DISTINCT ] <replaceable class="parameter">recursive_term</replaceable>
+</synopsis>
+ where the recursive self-reference must appear on the right-hand
+ side of the <literal>UNION</literal>. Only one recursive self-reference
+ is permitted per query. Recursive data-modifying statements are not
+ supported, but you can use the results of a recursive
+ <command>SELECT</command> query in
+ a data-modifying statement. See <xref linkend="queries-with"/> for
+ an example.
+ </para>
+
+ <para>
+ Another effect of <literal>RECURSIVE</literal> is that
+ <literal>WITH</literal> queries need not be ordered: a query
+ can reference another one that is later in the list. (However,
+ circular references, or mutual recursion, are not implemented.)
+ Without <literal>RECURSIVE</literal>, <literal>WITH</literal> queries
+ can only reference sibling <literal>WITH</literal> queries
+ that are earlier in the <literal>WITH</literal> list.
+ </para>
+
+ <para>
+ When there are multiple queries in the <literal>WITH</literal>
+ clause, <literal>RECURSIVE</literal> should be written only once,
+ immediately after <literal>WITH</literal>. It applies to all queries
+ in the <literal>WITH</literal> clause, though it has no effect on
+ queries that do not use recursion or forward references.
+ </para>
+
+ <para>
+ The optional <literal>SEARCH</literal> clause computes a <firstterm>search
+ sequence column</firstterm> that can be used for ordering the results of a
+ recursive query in either breadth-first or depth-first order. The
+ supplied column name list specifies the row key that is to be used for
+ keeping track of visited rows. A column named
+ <replaceable>search_seq_col_name</replaceable> will be added to the result
+ column list of the <literal>WITH</literal> query. This column can be
+ ordered by in the outer query to achieve the respective ordering. See
+ <xref linkend="queries-with-search"/> for examples.
+ </para>
+
+ <para>
+ The optional <literal>CYCLE</literal> clause is used to detect cycles in
+ recursive queries. The supplied column name list specifies the row key
+ that is to be used for keeping track of visited rows. A column named
+ <replaceable>cycle_mark_col_name</replaceable> will be added to the result
+ column list of the <literal>WITH</literal> query. This column will be set
+ to <replaceable>cycle_mark_value</replaceable> when a cycle has been
+ detected, else to <replaceable>cycle_mark_default</replaceable>.
+ Furthermore, processing of the recursive union will stop when a cycle has
+ been detected. <replaceable>cycle_mark_value</replaceable> and
+ <replaceable>cycle_mark_default</replaceable> must be constants and they
+ must be coercible to a common data type, and the data type must have an
+ inequality operator. (The SQL standard requires that they be Boolean
+ constants or character strings, but PostgreSQL does not require that.) By
+ default, <literal>TRUE</literal> and <literal>FALSE</literal> (of type
+ <type>boolean</type>) are used. Furthermore, a column
+ named <replaceable>cycle_path_col_name</replaceable> will be added to the
+ result column list of the <literal>WITH</literal> query. This column is
+ used internally for tracking visited rows. See <xref
+ linkend="queries-with-cycle"/> for examples.
+ </para>
+
+ <para>
+ Both the <literal>SEARCH</literal> and the <literal>CYCLE</literal> clause
+ are only valid for recursive <literal>WITH</literal> queries. The
+ <replaceable>with_query</replaceable> must be a <literal>UNION</literal>
+ (or <literal>UNION ALL</literal>) of two <literal>SELECT</literal> (or
+ equivalent) commands (no nested <literal>UNION</literal>s). If both
+ clauses are used, the column added by the <literal>SEARCH</literal> clause
+ appears before the columns added by the <literal>CYCLE</literal> clause.
+ </para>
+
+ <para>
+ The primary query and the <literal>WITH</literal> queries are all
+ (notionally) executed at the same time. This implies that the effects of
+ a data-modifying statement in <literal>WITH</literal> cannot be seen from
+ other parts of the query, other than by reading its <literal>RETURNING</literal>
+ output. If two such data-modifying statements attempt to modify the same
+ row, the results are unspecified.
+ </para>
+
+ <para>
+ A key property of <literal>WITH</literal> queries is that they
+ are normally evaluated only once per execution of the primary query,
+ even if the primary query refers to them more than once.
+ In particular, data-modifying statements are guaranteed to be
+ executed once and only once, regardless of whether the primary query
+ reads all or any of their output.
+ </para>
+
+ <para>
+ However, a <literal>WITH</literal> query can be marked
+ <literal>NOT MATERIALIZED</literal> to remove this guarantee. In that
+ case, the <literal>WITH</literal> query can be folded into the primary
+ query much as though it were a simple sub-<literal>SELECT</literal> in
+ the primary query's <literal>FROM</literal> clause. This results in
+ duplicate computations if the primary query refers to
+ that <literal>WITH</literal> query more than once; but if each such use
+ requires only a few rows of the <literal>WITH</literal> query's total
+ output, <literal>NOT MATERIALIZED</literal> can provide a net savings by
+ allowing the queries to be optimized jointly.
+ <literal>NOT MATERIALIZED</literal> is ignored if it is attached to
+ a <literal>WITH</literal> query that is recursive or is not
+ side-effect-free (i.e., is not a plain <literal>SELECT</literal>
+ containing no volatile functions).
+ </para>
+
+ <para>
+ By default, a side-effect-free <literal>WITH</literal> query is folded
+ into the primary query if it is used exactly once in the primary
+ query's <literal>FROM</literal> clause. This allows joint optimization
+ of the two query levels in situations where that should be semantically
+ invisible. However, such folding can be prevented by marking the
+ <literal>WITH</literal> query as <literal>MATERIALIZED</literal>.
+ That might be useful, for example, if the <literal>WITH</literal> query
+ is being used as an optimization fence to prevent the planner from
+ choosing a bad plan.
+ <productname>PostgreSQL</productname> versions before v12 never did
+ such folding, so queries written for older versions might rely on
+ <literal>WITH</literal> to act as an optimization fence.
+ </para>
+
+ <para>
+ See <xref linkend="queries-with"/> for additional information.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-from" xreflabel="FROM Clause">
+ <title><literal>FROM</literal> Clause</title>
+
+ <para>
+ The <literal>FROM</literal> clause specifies one or more source
+ tables for the <command>SELECT</command>. If multiple sources are
+ specified, the result is the Cartesian product (cross join) of all
+ the sources. But usually qualification conditions are added (via
+ <literal>WHERE</literal>) to restrict the returned rows to a small subset of the
+ Cartesian product.
+ </para>
+
+ <para>
+ The <literal>FROM</literal> clause can contain the following
+ elements:
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of an existing table or view.
+ If <literal>ONLY</literal> is specified before the table name, only that
+ table is scanned. If <literal>ONLY</literal> is not specified, the table
+ and all its descendant tables (if any) are scanned. Optionally,
+ <literal>*</literal> can be specified after the table name to explicitly
+ indicate that descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the <literal>FROM</literal> item containing the
+ alias. An alias is used for brevity or to eliminate ambiguity
+ for self-joins (where the same table is scanned multiple
+ times). When an alias is provided, it completely hides the
+ actual name of the table or function; for example given
+ <literal>FROM foo AS f</literal>, the remainder of the
+ <command>SELECT</command> must refer to this <literal>FROM</literal>
+ item as <literal>f</literal> not <literal>foo</literal>. If an alias is
+ written, a column alias list can also be written to provide
+ substitute names for one or more columns of the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TABLESAMPLE <replaceable class="parameter">sampling_method</replaceable> ( <replaceable class="parameter">argument</replaceable> [, ...] ) [ REPEATABLE ( <replaceable class="parameter">seed</replaceable> ) ]</literal></term>
+ <listitem>
+ <para>
+ A <literal>TABLESAMPLE</literal> clause after
+ a <replaceable class="parameter">table_name</replaceable> indicates that the
+ specified <replaceable class="parameter">sampling_method</replaceable>
+ should be used to retrieve a subset of the rows in that table.
+ This sampling precedes the application of any other filters such
+ as <literal>WHERE</literal> clauses.
+ The standard <productname>PostgreSQL</productname> distribution
+ includes two sampling methods, <literal>BERNOULLI</literal>
+ and <literal>SYSTEM</literal>, and other sampling methods can be
+ installed in the database via extensions.
+ </para>
+
+ <para>
+ The <literal>BERNOULLI</literal> and <literal>SYSTEM</literal> sampling methods
+ each accept a single <replaceable class="parameter">argument</replaceable>
+ which is the fraction of the table to sample, expressed as a
+ percentage between 0 and 100. This argument can be
+ any <type>real</type>-valued expression. (Other sampling methods might
+ accept more or different arguments.) These two methods each return
+ a randomly-chosen sample of the table that will contain
+ approximately the specified percentage of the table's rows.
+ The <literal>BERNOULLI</literal> method scans the whole table and
+ selects or ignores individual rows independently with the specified
+ probability.
+ The <literal>SYSTEM</literal> method does block-level sampling with
+ each block having the specified chance of being selected; all rows
+ in each selected block are returned.
+ The <literal>SYSTEM</literal> method is significantly faster than
+ the <literal>BERNOULLI</literal> method when small sampling
+ percentages are specified, but it may return a less-random sample of
+ the table as a result of clustering effects.
+ </para>
+
+ <para>
+ The optional <literal>REPEATABLE</literal> clause specifies
+ a <replaceable class="parameter">seed</replaceable> number or expression to use
+ for generating random numbers within the sampling method. The seed
+ value can be any non-null floating-point value. Two queries that
+ specify the same seed and <replaceable class="parameter">argument</replaceable>
+ values will select the same sample of the table, if the table has
+ not been changed meanwhile. But different seed values will usually
+ produce different samples.
+ If <literal>REPEATABLE</literal> is not given then a new random
+ sample is selected for each query, based upon a system-generated seed.
+ Note that some add-on sampling methods do not
+ accept <literal>REPEATABLE</literal>, and will always produce new
+ samples on each use.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">select</replaceable></term>
+ <listitem>
+ <para>
+ A sub-<command>SELECT</command> can appear in the
+ <literal>FROM</literal> clause. This acts as though its
+ output were created as a temporary table for the duration of
+ this single <command>SELECT</command> command. Note that the
+ sub-<command>SELECT</command> must be surrounded by
+ parentheses, and an alias <emphasis>must</emphasis> be
+ provided for it. A
+ <link linkend="sql-values"><command>VALUES</command></link> command
+ can also be used here.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">with_query_name</replaceable></term>
+ <listitem>
+ <para>
+ A <literal>WITH</literal> query is referenced by writing its name,
+ just as though the query's name were a table name. (In fact,
+ the <literal>WITH</literal> query hides any real table of the same name
+ for the purposes of the primary query. If necessary, you can
+ refer to a real table of the same name by schema-qualifying
+ the table's name.)
+ An alias can be provided in the same way as for a table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">function_name</replaceable></term>
+ <listitem>
+ <para>
+ Function calls can appear in the <literal>FROM</literal>
+ clause. (This is especially useful for functions that return
+ result sets, but any function can be used.) This acts as
+ though the function's output were created as a temporary table for the
+ duration of this single <command>SELECT</command> command.
+ If the function's result type is composite (including the case of a
+ function with multiple <literal>OUT</literal> parameters), each
+ attribute becomes a separate column in the implicit table.
+ </para>
+
+ <para>
+ When the optional <command>WITH ORDINALITY</command> clause is added
+ to the function call, an additional column of type <type>bigint</type>
+ will be appended to the function's result column(s). This column
+ numbers the rows of the function's result set, starting from 1.
+ By default, this column is named <literal>ordinality</literal>.
+ </para>
+
+ <para>
+ An alias can be provided in the same way as for a table.
+ If an alias is written, a column
+ alias list can also be written to provide substitute names for
+ one or more attributes of the function's composite return
+ type, including the ordinality column if present.
+ </para>
+
+ <para>
+ Multiple function calls can be combined into a
+ single <literal>FROM</literal>-clause item by surrounding them
+ with <literal>ROWS FROM( ... )</literal>. The output of such an item is the
+ concatenation of the first row from each function, then the second
+ row from each function, etc. If some of the functions produce fewer
+ rows than others, null values are substituted for the missing data, so
+ that the total number of rows returned is always the same as for the
+ function that produced the most rows.
+ </para>
+
+ <para>
+ If the function has been defined as returning the
+ <type>record</type> data type, then an alias or the key word
+ <literal>AS</literal> must be present, followed by a column
+ definition list in the form <literal>( <replaceable
+ class="parameter">column_name</replaceable> <replaceable
+ class="parameter">data_type</replaceable> <optional>, ...
+ </optional>)</literal>. The column definition list must match the
+ actual number and types of columns returned by the function.
+ </para>
+
+ <para>
+ When using the <literal>ROWS FROM( ... )</literal> syntax, if one of the
+ functions requires a column definition list, it's preferred to put
+ the column definition list after the function call inside
+ <literal>ROWS FROM( ... )</literal>. A column definition list can be placed
+ after the <literal>ROWS FROM( ... )</literal> construct only if there's just
+ a single function and no <literal>WITH ORDINALITY</literal> clause.
+ </para>
+
+ <para>
+ To use <literal>ORDINALITY</literal> together with a column definition
+ list, you must use the <literal>ROWS FROM( ... )</literal> syntax and put the
+ column definition list inside <literal>ROWS FROM( ... )</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">join_type</replaceable></term>
+ <listitem>
+ <para>
+ One of
+ <itemizedlist>
+ <listitem>
+ <para><literal>[ INNER ] JOIN</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>LEFT [ OUTER ] JOIN</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>RIGHT [ OUTER ] JOIN</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>FULL [ OUTER ] JOIN</literal></para>
+ </listitem>
+ </itemizedlist>
+
+ For the <literal>INNER</literal> and <literal>OUTER</literal> join types, a
+ join condition must be specified, namely exactly one of
+ <literal>ON <replaceable
+ class="parameter">join_condition</replaceable></literal>,
+ <literal>USING (<replaceable
+ class="parameter">join_column</replaceable> [, ...])</literal>,
+ or <literal>NATURAL</literal>. See below for the meaning.
+ </para>
+
+ <para>
+ A <literal>JOIN</literal> clause combines two <literal>FROM</literal>
+ items, which for convenience we will refer to as <quote>tables</quote>,
+ though in reality they can be any type of <literal>FROM</literal> item.
+ Use parentheses if necessary to determine the order of nesting.
+ In the absence of parentheses, <literal>JOIN</literal>s nest
+ left-to-right. In any case <literal>JOIN</literal> binds more
+ tightly than the commas separating <literal>FROM</literal>-list items.
+ All the <literal>JOIN</literal> options are just a notational
+ convenience, since they do nothing you couldn't do with plain
+ <literal>FROM</literal> and <literal>WHERE</literal>.
+ </para>
+
+ <para><literal>LEFT OUTER JOIN</literal> returns all rows in the qualified
+ Cartesian product (i.e., all combined rows that pass its join
+ condition), plus one copy of each row in the left-hand table
+ for which there was no right-hand row that passed the join
+ condition. This left-hand row is extended to the full width
+ of the joined table by inserting null values for the
+ right-hand columns. Note that only the <literal>JOIN</literal>
+ clause's own condition is considered while deciding which rows
+ have matches. Outer conditions are applied afterwards.
+ </para>
+
+ <para>
+ Conversely, <literal>RIGHT OUTER JOIN</literal> returns all the
+ joined rows, plus one row for each unmatched right-hand row
+ (extended with nulls on the left). This is just a notational
+ convenience, since you could convert it to a <literal>LEFT
+ OUTER JOIN</literal> by switching the left and right tables.
+ </para>
+
+ <para><literal>FULL OUTER JOIN</literal> returns all the joined rows, plus
+ one row for each unmatched left-hand row (extended with nulls
+ on the right), plus one row for each unmatched right-hand row
+ (extended with nulls on the left).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ON <replaceable class="parameter">join_condition</replaceable></literal></term>
+ <listitem>
+ <para><replaceable class="parameter">join_condition</replaceable> is
+ an expression resulting in a value of type
+ <type>boolean</type> (similar to a <literal>WHERE</literal>
+ clause) that specifies which rows in a join are considered to
+ match.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>USING ( <replaceable class="parameter">join_column</replaceable> [, ...] ) [ AS <replaceable class="parameter">join_using_alias</replaceable> ]</literal></term>
+ <listitem>
+ <para>
+ A clause of the form <literal>USING ( a, b, ... )</literal> is
+ shorthand for <literal>ON left_table.a = right_table.a AND
+ left_table.b = right_table.b ...</literal>. Also,
+ <literal>USING</literal> implies that only one of each pair of
+ equivalent columns will be included in the join output, not
+ both.
+ </para>
+
+ <para>
+ If a <replaceable class="parameter">join_using_alias</replaceable>
+ name is specified, it provides a table alias for the join columns.
+ Only the join columns listed in the <literal>USING</literal> clause
+ are addressable by this name. Unlike a regular <replaceable
+ class="parameter">alias</replaceable>, this does not hide the names of
+ the joined tables from the rest of the query. Also unlike a regular
+ <replaceable class="parameter">alias</replaceable>, you cannot write a
+ column alias list &mdash; the output names of the join columns are the
+ same as they appear in the <literal>USING</literal> list.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NATURAL</literal></term>
+ <listitem>
+ <para>
+ <literal>NATURAL</literal> is shorthand for a
+ <literal>USING</literal> list that mentions all columns in the two
+ tables that have matching names. If there are no common
+ column names, <literal>NATURAL</literal> is equivalent
+ to <literal>ON TRUE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CROSS JOIN</literal></term>
+ <listitem>
+ <para>
+ <literal>CROSS JOIN</literal> is equivalent to <literal>INNER JOIN ON
+ (TRUE)</literal>, that is, no rows are removed by qualification.
+ They produce a simple Cartesian product, the same result as you get from
+ listing the two tables at the top level of <literal>FROM</literal>,
+ but restricted by the join condition (if any).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LATERAL</literal></term>
+ <listitem>
+ <para>
+ The <literal>LATERAL</literal> key word can precede a
+ sub-<command>SELECT</command> <literal>FROM</literal> item. This allows the
+ sub-<command>SELECT</command> to refer to columns of <literal>FROM</literal>
+ items that appear before it in the <literal>FROM</literal> list. (Without
+ <literal>LATERAL</literal>, each sub-<command>SELECT</command> is
+ evaluated independently and so cannot cross-reference any other
+ <literal>FROM</literal> item.)
+ </para>
+
+ <para><literal>LATERAL</literal> can also precede a function-call
+ <literal>FROM</literal> item, but in this case it is a noise word, because
+ the function expression can refer to earlier <literal>FROM</literal> items
+ in any case.
+ </para>
+
+ <para>
+ A <literal>LATERAL</literal> item can appear at top level in the
+ <literal>FROM</literal> list, or within a <literal>JOIN</literal> tree. In the
+ latter case it can also refer to any items that are on the left-hand
+ side of a <literal>JOIN</literal> that it is on the right-hand side of.
+ </para>
+
+ <para>
+ When a <literal>FROM</literal> item contains <literal>LATERAL</literal>
+ cross-references, evaluation proceeds as follows: for each row of the
+ <literal>FROM</literal> item providing the cross-referenced column(s), or
+ set of rows of multiple <literal>FROM</literal> items providing the
+ columns, the <literal>LATERAL</literal> item is evaluated using that
+ row or row set's values of the columns. The resulting row(s) are
+ joined as usual with the rows they were computed from. This is
+ repeated for each row or set of rows from the column source table(s).
+ </para>
+
+ <para>
+ The column source table(s) must be <literal>INNER</literal> or
+ <literal>LEFT</literal> joined to the <literal>LATERAL</literal> item, else
+ there would not be a well-defined set of rows from which to compute
+ each set of rows for the <literal>LATERAL</literal> item. Thus,
+ although a construct such as <literal><replaceable>X</replaceable> RIGHT JOIN
+ LATERAL <replaceable>Y</replaceable></literal> is syntactically valid, it is
+ not actually allowed for <replaceable>Y</replaceable> to reference
+ <replaceable>X</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-where" xreflabel="WHERE Clause">
+ <title><literal>WHERE</literal> Clause</title>
+
+ <para>
+ The optional <literal>WHERE</literal> clause has the general form
+<synopsis>
+WHERE <replaceable class="parameter">condition</replaceable>
+</synopsis>
+ where <replaceable class="parameter">condition</replaceable> is
+ any expression that evaluates to a result of type
+ <type>boolean</type>. Any row that does not satisfy this
+ condition will be eliminated from the output. A row satisfies the
+ condition if it returns true when the actual row values are
+ substituted for any variable references.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-groupby" xreflabel="GROUP BY Clause">
+ <title><literal>GROUP BY</literal> Clause</title>
+
+ <para>
+ The optional <literal>GROUP BY</literal> clause has the general form
+<synopsis>
+GROUP BY [ ALL | DISTINCT ] <replaceable class="parameter">grouping_element</replaceable> [, ...]
+</synopsis>
+ </para>
+
+ <para>
+ <literal>GROUP BY</literal> will condense into a single row all
+ selected rows that share the same values for the grouped
+ expressions. An <replaceable
+ class="parameter">expression</replaceable> used inside a
+ <replaceable class="parameter">grouping_element</replaceable>
+ can be an input column name, or the name or ordinal number of an
+ output column (<command>SELECT</command> list item), or an arbitrary
+ expression formed from input-column values. In case of ambiguity,
+ a <literal>GROUP BY</literal> name will be interpreted as an
+ input-column name rather than an output column name.
+ </para>
+
+ <para>
+ If any of <literal>GROUPING SETS</literal>, <literal>ROLLUP</literal> or
+ <literal>CUBE</literal> are present as grouping elements, then the
+ <literal>GROUP BY</literal> clause as a whole defines some number of
+ independent <replaceable>grouping sets</replaceable>. The effect of this is
+ equivalent to constructing a <literal>UNION ALL</literal> between
+ subqueries with the individual grouping sets as their
+ <literal>GROUP BY</literal> clauses. The optional <literal>DISTINCT</literal>
+ clause removes duplicate sets before processing; it does <emphasis>not</emphasis>
+ transform the <literal>UNION ALL</literal> into a <literal>UNION DISTINCT</literal>.
+ For further details on the handling
+ of grouping sets see <xref linkend="queries-grouping-sets"/>.
+ </para>
+
+ <para>
+ Aggregate functions, if any are used, are computed across all rows
+ making up each group, producing a separate value for each group.
+ (If there are aggregate functions but no <literal>GROUP BY</literal>
+ clause, the query is treated as having a single group comprising all
+ the selected rows.)
+ The set of rows fed to each aggregate function can be further filtered by
+ attaching a <literal>FILTER</literal> clause to the aggregate function
+ call; see <xref linkend="syntax-aggregates"/> for more information. When
+ a <literal>FILTER</literal> clause is present, only those rows matching it
+ are included in the input to that aggregate function.
+ </para>
+
+ <para>
+ When <literal>GROUP BY</literal> is present,
+ or any aggregate functions are present, it is not valid for
+ the <command>SELECT</command> list expressions to refer to
+ ungrouped columns except within aggregate functions or when the
+ ungrouped column is functionally dependent on the grouped columns,
+ since there would otherwise be more than one possible value to
+ return for an ungrouped column. A functional dependency exists if
+ the grouped columns (or a subset thereof) are the primary key of
+ the table containing the ungrouped column.
+ </para>
+
+ <para>
+ Keep in mind that all aggregate functions are evaluated before
+ evaluating any <quote>scalar</quote> expressions in the <literal>HAVING</literal>
+ clause or <literal>SELECT</literal> list. This means that, for example,
+ a <literal>CASE</literal> expression cannot be used to skip evaluation of
+ an aggregate function; see <xref linkend="syntax-express-eval"/>.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal> and <literal>FOR KEY SHARE</literal> cannot be
+ specified with <literal>GROUP BY</literal>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-having" xreflabel="HAVING Clause">
+ <title><literal>HAVING</literal> Clause</title>
+
+ <para>
+ The optional <literal>HAVING</literal> clause has the general form
+<synopsis>
+HAVING <replaceable class="parameter">condition</replaceable>
+</synopsis>
+ where <replaceable class="parameter">condition</replaceable> is
+ the same as specified for the <literal>WHERE</literal> clause.
+ </para>
+
+ <para>
+ <literal>HAVING</literal> eliminates group rows that do not
+ satisfy the condition. <literal>HAVING</literal> is different
+ from <literal>WHERE</literal>: <literal>WHERE</literal> filters
+ individual rows before the application of <literal>GROUP
+ BY</literal>, while <literal>HAVING</literal> filters group rows
+ created by <literal>GROUP BY</literal>. Each column referenced in
+ <replaceable class="parameter">condition</replaceable> must
+ unambiguously reference a grouping column, unless the reference
+ appears within an aggregate function or the ungrouped column is
+ functionally dependent on the grouping columns.
+ </para>
+
+ <para>
+ The presence of <literal>HAVING</literal> turns a query into a grouped
+ query even if there is no <literal>GROUP BY</literal> clause. This is the
+ same as what happens when the query contains aggregate functions but
+ no <literal>GROUP BY</literal> clause. All the selected rows are considered to
+ form a single group, and the <command>SELECT</command> list and
+ <literal>HAVING</literal> clause can only reference table columns from
+ within aggregate functions. Such a query will emit a single row if the
+ <literal>HAVING</literal> condition is true, zero rows if it is not true.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal> and <literal>FOR KEY SHARE</literal> cannot be
+ specified with <literal>HAVING</literal>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-window" xreflabel="WINDOW Clause">
+ <title><literal>WINDOW</literal> Clause</title>
+
+ <para>
+ The optional <literal>WINDOW</literal> clause has the general form
+<synopsis>
+WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceable class="parameter">window_definition</replaceable> ) [, ...]
+</synopsis>
+ where <replaceable class="parameter">window_name</replaceable> is
+ a name that can be referenced from <literal>OVER</literal> clauses or
+ subsequent window definitions, and
+ <replaceable class="parameter">window_definition</replaceable> is
+<synopsis>
+[ <replaceable class="parameter">existing_window_name</replaceable> ]
+[ PARTITION BY <replaceable class="parameter">expression</replaceable> [, ...] ]
+[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+[ <replaceable class="parameter">frame_clause</replaceable> ]
+</synopsis>
+ </para>
+
+ <para>
+ If an <replaceable class="parameter">existing_window_name</replaceable>
+ is specified it must refer to an earlier entry in the <literal>WINDOW</literal>
+ list; the new window copies its partitioning clause from that entry,
+ as well as its ordering clause if any. In this case the new window cannot
+ specify its own <literal>PARTITION BY</literal> clause, and it can specify
+ <literal>ORDER BY</literal> only if the copied window does not have one.
+ The new window always uses its own frame clause; the copied window
+ must not specify a frame clause.
+ </para>
+
+ <para>
+ The elements of the <literal>PARTITION BY</literal> list are interpreted in
+ much the same fashion as elements of a <link
+ linkend="sql-groupby"><literal>GROUP BY</literal></link> clause, except that
+ they are always simple expressions and never the name or number of an
+ output column.
+ Another difference is that these expressions can contain aggregate
+ function calls, which are not allowed in a regular <literal>GROUP BY</literal>
+ clause. They are allowed here because windowing occurs after grouping
+ and aggregation.
+ </para>
+
+ <para>
+ Similarly, the elements of the <literal>ORDER BY</literal> list are interpreted
+ in much the same fashion as elements of a statement-level <link
+ linkend="sql-orderby"><literal>ORDER BY</literal></link> clause, except that
+ the expressions are always taken as simple expressions and never the name
+ or number of an output column.
+ </para>
+
+ <para>
+ The optional <replaceable class="parameter">frame_clause</replaceable> defines
+ the <firstterm>window frame</firstterm> for window functions that depend on the
+ frame (not all do). The window frame is a set of related rows for
+ each row of the query (called the <firstterm>current row</firstterm>).
+ The <replaceable class="parameter">frame_clause</replaceable> can be one of
+
+<synopsis>
+{ RANGE | ROWS | GROUPS } <replaceable>frame_start</replaceable> [ <replaceable>frame_exclusion</replaceable> ]
+{ RANGE | ROWS | GROUPS } BETWEEN <replaceable>frame_start</replaceable> AND <replaceable>frame_end</replaceable> [ <replaceable>frame_exclusion</replaceable> ]
+</synopsis>
+
+ where <replaceable>frame_start</replaceable>
+ and <replaceable>frame_end</replaceable> can be one of
+
+<synopsis>
+UNBOUNDED PRECEDING
+<replaceable>offset</replaceable> PRECEDING
+CURRENT ROW
+<replaceable>offset</replaceable> FOLLOWING
+UNBOUNDED FOLLOWING
+</synopsis>
+
+ and <replaceable>frame_exclusion</replaceable> can be one of
+
+<synopsis>
+EXCLUDE CURRENT ROW
+EXCLUDE GROUP
+EXCLUDE TIES
+EXCLUDE NO OTHERS
+</synopsis>
+
+ If <replaceable>frame_end</replaceable> is omitted it defaults to <literal>CURRENT
+ ROW</literal>. Restrictions are that
+ <replaceable>frame_start</replaceable> cannot be <literal>UNBOUNDED FOLLOWING</literal>,
+ <replaceable>frame_end</replaceable> cannot be <literal>UNBOUNDED PRECEDING</literal>,
+ and the <replaceable>frame_end</replaceable> choice cannot appear earlier in the
+ above list of <replaceable>frame_start</replaceable>
+ and <replaceable>frame_end</replaceable> options than
+ the <replaceable>frame_start</replaceable> choice does &mdash; for example
+ <literal>RANGE BETWEEN CURRENT ROW AND <replaceable>offset</replaceable>
+ PRECEDING</literal> is not allowed.
+ </para>
+
+ <para>
+ The default framing option is <literal>RANGE UNBOUNDED PRECEDING</literal>,
+ which is the same as <literal>RANGE BETWEEN UNBOUNDED PRECEDING AND
+ CURRENT ROW</literal>; it sets the frame to be all rows from the partition start
+ up through the current row's last <firstterm>peer</firstterm> (a row
+ that the window's <literal>ORDER BY</literal> clause considers
+ equivalent to the current row; all rows are peers if there
+ is no <literal>ORDER BY</literal>).
+ In general, <literal>UNBOUNDED PRECEDING</literal> means that the frame
+ starts with the first row of the partition, and similarly
+ <literal>UNBOUNDED FOLLOWING</literal> means that the frame ends with the last
+ row of the partition, regardless
+ of <literal>RANGE</literal>, <literal>ROWS</literal>
+ or <literal>GROUPS</literal> mode.
+ In <literal>ROWS</literal> mode, <literal>CURRENT ROW</literal> means
+ that the frame starts or ends with the current row; but
+ in <literal>RANGE</literal> or <literal>GROUPS</literal> mode it means
+ that the frame starts or ends with the current row's first or last peer
+ in the <literal>ORDER BY</literal> ordering.
+ The <replaceable>offset</replaceable> <literal>PRECEDING</literal> and
+ <replaceable>offset</replaceable> <literal>FOLLOWING</literal> options
+ vary in meaning depending on the frame mode.
+ In <literal>ROWS</literal> mode, the <replaceable>offset</replaceable>
+ is an integer indicating that the frame starts or ends that many rows
+ before or after the current row.
+ In <literal>GROUPS</literal> mode, the <replaceable>offset</replaceable>
+ is an integer indicating that the frame starts or ends that many peer
+ groups before or after the current row's peer group, where
+ a <firstterm>peer group</firstterm> is a group of rows that are
+ equivalent according to the window's <literal>ORDER BY</literal> clause.
+ In <literal>RANGE</literal> mode, use of
+ an <replaceable>offset</replaceable> option requires that there be
+ exactly one <literal>ORDER BY</literal> column in the window definition.
+ Then the frame contains those rows whose ordering column value is no
+ more than <replaceable>offset</replaceable> less than
+ (for <literal>PRECEDING</literal>) or more than
+ (for <literal>FOLLOWING</literal>) the current row's ordering column
+ value. In these cases the data type of
+ the <replaceable>offset</replaceable> expression depends on the data
+ type of the ordering column. For numeric ordering columns it is
+ typically of the same type as the ordering column, but for datetime
+ ordering columns it is an <type>interval</type>.
+ In all these cases, the value of the <replaceable>offset</replaceable>
+ must be non-null and non-negative. Also, while
+ the <replaceable>offset</replaceable> does not have to be a simple
+ constant, it cannot contain variables, aggregate functions, or window
+ functions.
+ </para>
+
+ <para>
+ The <replaceable>frame_exclusion</replaceable> option allows rows around
+ the current row to be excluded from the frame, even if they would be
+ included according to the frame start and frame end options.
+ <literal>EXCLUDE CURRENT ROW</literal> excludes the current row from the
+ frame.
+ <literal>EXCLUDE GROUP</literal> excludes the current row and its
+ ordering peers from the frame.
+ <literal>EXCLUDE TIES</literal> excludes any peers of the current
+ row from the frame, but not the current row itself.
+ <literal>EXCLUDE NO OTHERS</literal> simply specifies explicitly the
+ default behavior of not excluding the current row or its peers.
+ </para>
+
+ <para>
+ Beware that the <literal>ROWS</literal> mode can produce unpredictable
+ results if the <literal>ORDER BY</literal> ordering does not order the rows
+ uniquely. The <literal>RANGE</literal> and <literal>GROUPS</literal>
+ modes are designed to ensure that rows that are peers in
+ the <literal>ORDER BY</literal> ordering are treated alike: all rows of
+ a given peer group will be in the frame or excluded from it.
+ </para>
+
+ <para>
+ The purpose of a <literal>WINDOW</literal> clause is to specify the
+ behavior of <firstterm>window functions</firstterm> appearing in the query's
+ <link linkend="sql-select-list"><command>SELECT</command> list</link> or
+ <link linkend="sql-orderby"><literal>ORDER BY</literal></link> clause.
+ These functions
+ can reference the <literal>WINDOW</literal> clause entries by name
+ in their <literal>OVER</literal> clauses. A <literal>WINDOW</literal> clause
+ entry does not have to be referenced anywhere, however; if it is not
+ used in the query it is simply ignored. It is possible to use window
+ functions without any <literal>WINDOW</literal> clause at all, since
+ a window function call can specify its window definition directly in
+ its <literal>OVER</literal> clause. However, the <literal>WINDOW</literal>
+ clause saves typing when the same window definition is needed for more
+ than one window function.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal> and <literal>FOR KEY SHARE</literal> cannot be
+ specified with <literal>WINDOW</literal>.
+ </para>
+
+ <para>
+ Window functions are described in detail in
+ <xref linkend="tutorial-window"/>,
+ <xref linkend="syntax-window-functions"/>, and
+ <xref linkend="queries-window"/>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-select-list" xreflabel="SELECT List">
+ <title><command>SELECT</command> List</title>
+
+ <para>
+ The <command>SELECT</command> list (between the key words
+ <literal>SELECT</literal> and <literal>FROM</literal>) specifies expressions
+ that form the output rows of the <command>SELECT</command>
+ statement. The expressions can (and usually do) refer to columns
+ computed in the <literal>FROM</literal> clause.
+ </para>
+
+ <para>
+ Just as in a table, every output column of a <command>SELECT</command>
+ has a name. In a simple <command>SELECT</command> this name is just
+ used to label the column for display, but when the <command>SELECT</command>
+ is a sub-query of a larger query, the name is seen by the larger query
+ as the column name of the virtual table produced by the sub-query.
+ To specify the name to use for an output column, write
+ <literal>AS</literal> <replaceable class="parameter">output_name</replaceable>
+ after the column's expression. (You can omit <literal>AS</literal>,
+ but only if the desired output name does not match any
+ <productname>PostgreSQL</productname> keyword (see <xref
+ linkend="sql-keywords-appendix"/>). For protection against possible
+ future keyword additions, it is recommended that you always either
+ write <literal>AS</literal> or double-quote the output name.)
+ If you do not specify a column name, a name is chosen automatically
+ by <productname>PostgreSQL</productname>. If the column's expression
+ is a simple column reference then the chosen name is the same as that
+ column's name. In more complex cases a function or type name may be
+ used, or the system may fall back on a generated name such as
+ <literal>?column?</literal>.
+ </para>
+
+ <para>
+ An output column's name can be used to refer to the column's value in
+ <literal>ORDER BY</literal> and <literal>GROUP BY</literal> clauses, but not in the
+ <literal>WHERE</literal> or <literal>HAVING</literal> clauses; there you must write
+ out the expression instead.
+ </para>
+
+ <para>
+ Instead of an expression, <literal>*</literal> can be written in
+ the output list as a shorthand for all the columns of the selected
+ rows. Also, you can write <literal><replaceable
+ class="parameter">table_name</replaceable>.*</literal> as a
+ shorthand for the columns coming from just that table. In these
+ cases it is not possible to specify new names with <literal>AS</literal>;
+ the output column names will be the same as the table columns' names.
+ </para>
+
+ <para>
+ According to the SQL standard, the expressions in the output list should
+ be computed before applying <literal>DISTINCT</literal>, <literal>ORDER
+ BY</literal>, or <literal>LIMIT</literal>. This is obviously necessary
+ when using <literal>DISTINCT</literal>, since otherwise it's not clear
+ what values are being made distinct. However, in many cases it is
+ convenient if output expressions are computed after <literal>ORDER
+ BY</literal> and <literal>LIMIT</literal>; particularly if the output list
+ contains any volatile or expensive functions. With that behavior, the
+ order of function evaluations is more intuitive and there will not be
+ evaluations corresponding to rows that never appear in the output.
+ <productname>PostgreSQL</productname> will effectively evaluate output expressions
+ after sorting and limiting, so long as those expressions are not
+ referenced in <literal>DISTINCT</literal>, <literal>ORDER BY</literal>
+ or <literal>GROUP BY</literal>. (As a counterexample, <literal>SELECT
+ f(x) FROM tab ORDER BY 1</literal> clearly must evaluate <function>f(x)</function>
+ before sorting.) Output expressions that contain set-returning functions
+ are effectively evaluated after sorting and before limiting, so
+ that <literal>LIMIT</literal> will act to cut off the output from a
+ set-returning function.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> versions before 9.6 did not provide any
+ guarantees about the timing of evaluation of output expressions versus
+ sorting and limiting; it depended on the form of the chosen query plan.
+ </para>
+ </note>
+ </refsect2>
+
+ <refsect2 id="sql-distinct" xreflabel="DISTINCT Clause">
+ <title><literal>DISTINCT</literal> Clause</title>
+
+ <para>
+ If <literal>SELECT DISTINCT</literal> is specified, all duplicate rows are
+ removed from the result set (one row is kept from each group of
+ duplicates). <literal>SELECT ALL</literal> specifies the opposite: all rows are
+ kept; that is the default.
+ </para>
+
+ <para>
+ <literal>SELECT DISTINCT ON ( <replaceable
+ class="parameter">expression</replaceable> [, ...] )</literal>
+ keeps only the first row of each set of rows where the given
+ expressions evaluate to equal. The <literal>DISTINCT ON</literal>
+ expressions are interpreted using the same rules as for
+ <literal>ORDER BY</literal> (see above). Note that the <quote>first
+ row</quote> of each set is unpredictable unless <literal>ORDER
+ BY</literal> is used to ensure that the desired row appears first. For
+ example:
+<programlisting>
+SELECT DISTINCT ON (location) location, time, report
+ FROM weather_reports
+ ORDER BY location, time DESC;
+</programlisting>
+ retrieves the most recent weather report for each location. But
+ if we had not used <literal>ORDER BY</literal> to force descending order
+ of time values for each location, we'd have gotten a report from
+ an unpredictable time for each location.
+ </para>
+
+ <para>
+ The <literal>DISTINCT ON</literal> expression(s) must match the leftmost
+ <literal>ORDER BY</literal> expression(s). The <literal>ORDER BY</literal> clause
+ will normally contain additional expression(s) that determine the
+ desired precedence of rows within each <literal>DISTINCT ON</literal> group.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal> and <literal>FOR KEY SHARE</literal> cannot be
+ specified with <literal>DISTINCT</literal>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-union" xreflabel="UNION Clause">
+ <title><literal>UNION</literal> Clause</title>
+
+ <para>
+ The <literal>UNION</literal> clause has this general form:
+<synopsis>
+<replaceable class="parameter">select_statement</replaceable> UNION [ ALL | DISTINCT ] <replaceable class="parameter">select_statement</replaceable>
+</synopsis><replaceable class="parameter">select_statement</replaceable> is
+ any <command>SELECT</command> statement without an <literal>ORDER
+ BY</literal>, <literal>LIMIT</literal>, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal>, or <literal>FOR KEY SHARE</literal> clause.
+ (<literal>ORDER BY</literal> and <literal>LIMIT</literal> can be attached to a
+ subexpression if it is enclosed in parentheses. Without
+ parentheses, these clauses will be taken to apply to the result of
+ the <literal>UNION</literal>, not to its right-hand input
+ expression.)
+ </para>
+
+ <para>
+ The <literal>UNION</literal> operator computes the set union of
+ the rows returned by the involved <command>SELECT</command>
+ statements. A row is in the set union of two result sets if it
+ appears in at least one of the result sets. The two
+ <command>SELECT</command> statements that represent the direct
+ operands of the <literal>UNION</literal> must produce the same
+ number of columns, and corresponding columns must be of compatible
+ data types.
+ </para>
+
+ <para>
+ The result of <literal>UNION</literal> does not contain any duplicate
+ rows unless the <literal>ALL</literal> option is specified.
+ <literal>ALL</literal> prevents elimination of duplicates. (Therefore,
+ <literal>UNION ALL</literal> is usually significantly quicker than
+ <literal>UNION</literal>; use <literal>ALL</literal> when you can.)
+ <literal>DISTINCT</literal> can be written to explicitly specify the
+ default behavior of eliminating duplicate rows.
+ </para>
+
+ <para>
+ Multiple <literal>UNION</literal> operators in the same
+ <command>SELECT</command> statement are evaluated left to right,
+ unless otherwise indicated by parentheses.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>, <literal>FOR SHARE</literal> and
+ <literal>FOR KEY SHARE</literal> cannot be
+ specified either for a <literal>UNION</literal> result or for any input of a
+ <literal>UNION</literal>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-intersect" xreflabel="INTERSECT Clause">
+ <title><literal>INTERSECT</literal> Clause</title>
+
+ <para>
+ The <literal>INTERSECT</literal> clause has this general form:
+<synopsis>
+<replaceable class="parameter">select_statement</replaceable> INTERSECT [ ALL | DISTINCT ] <replaceable class="parameter">select_statement</replaceable>
+</synopsis><replaceable class="parameter">select_statement</replaceable> is
+ any <command>SELECT</command> statement without an <literal>ORDER
+ BY</literal>, <literal>LIMIT</literal>, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal>, or <literal>FOR KEY SHARE</literal> clause.
+ </para>
+
+ <para>
+ The <literal>INTERSECT</literal> operator computes the set
+ intersection of the rows returned by the involved
+ <command>SELECT</command> statements. A row is in the
+ intersection of two result sets if it appears in both result sets.
+ </para>
+
+ <para>
+ The result of <literal>INTERSECT</literal> does not contain any
+ duplicate rows unless the <literal>ALL</literal> option is specified.
+ With <literal>ALL</literal>, a row that has <replaceable>m</replaceable> duplicates in the
+ left table and <replaceable>n</replaceable> duplicates in the right table will appear
+ min(<replaceable>m</replaceable>,<replaceable>n</replaceable>) times in the result set.
+ <literal>DISTINCT</literal> can be written to explicitly specify the
+ default behavior of eliminating duplicate rows.
+ </para>
+
+ <para>
+ Multiple <literal>INTERSECT</literal> operators in the same
+ <command>SELECT</command> statement are evaluated left to right,
+ unless parentheses dictate otherwise.
+ <literal>INTERSECT</literal> binds more tightly than
+ <literal>UNION</literal>. That is, <literal>A UNION B INTERSECT
+ C</literal> will be read as <literal>A UNION (B INTERSECT
+ C)</literal>.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>, <literal>FOR SHARE</literal> and
+ <literal>FOR KEY SHARE</literal> cannot be
+ specified either for an <literal>INTERSECT</literal> result or for any input of
+ an <literal>INTERSECT</literal>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-except" xreflabel="EXCEPT Clause">
+ <title><literal>EXCEPT</literal> Clause</title>
+
+ <para>
+ The <literal>EXCEPT</literal> clause has this general form:
+<synopsis>
+<replaceable class="parameter">select_statement</replaceable> EXCEPT [ ALL | DISTINCT ] <replaceable class="parameter">select_statement</replaceable>
+</synopsis><replaceable class="parameter">select_statement</replaceable> is
+ any <command>SELECT</command> statement without an <literal>ORDER
+ BY</literal>, <literal>LIMIT</literal>, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>,
+ <literal>FOR SHARE</literal>, or <literal>FOR KEY SHARE</literal> clause.
+ </para>
+
+ <para>
+ The <literal>EXCEPT</literal> operator computes the set of rows
+ that are in the result of the left <command>SELECT</command>
+ statement but not in the result of the right one.
+ </para>
+
+ <para>
+ The result of <literal>EXCEPT</literal> does not contain any
+ duplicate rows unless the <literal>ALL</literal> option is specified.
+ With <literal>ALL</literal>, a row that has <replaceable>m</replaceable> duplicates in the
+ left table and <replaceable>n</replaceable> duplicates in the right table will appear
+ max(<replaceable>m</replaceable>-<replaceable>n</replaceable>,0) times in the result set.
+ <literal>DISTINCT</literal> can be written to explicitly specify the
+ default behavior of eliminating duplicate rows.
+ </para>
+
+ <para>
+ Multiple <literal>EXCEPT</literal> operators in the same
+ <command>SELECT</command> statement are evaluated left to right,
+ unless parentheses dictate otherwise. <literal>EXCEPT</literal> binds at
+ the same level as <literal>UNION</literal>.
+ </para>
+
+ <para>
+ Currently, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>, <literal>FOR SHARE</literal> and
+ <literal>FOR KEY SHARE</literal> cannot be
+ specified either for an <literal>EXCEPT</literal> result or for any input of
+ an <literal>EXCEPT</literal>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-orderby" xreflabel="ORDER BY Clause">
+ <title><literal>ORDER BY</literal> Clause</title>
+
+ <para>
+ The optional <literal>ORDER BY</literal> clause has this general form:
+<synopsis>
+ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...]
+</synopsis>
+ The <literal>ORDER BY</literal> clause causes the result rows to
+ be sorted according to the specified expression(s). If two rows are
+ equal according to the leftmost expression, they are compared
+ according to the next expression and so on. If they are equal
+ according to all specified expressions, they are returned in
+ an implementation-dependent order.
+ </para>
+
+ <para>
+ Each <replaceable class="parameter">expression</replaceable> can be the
+ name or ordinal number of an output column
+ (<command>SELECT</command> list item), or it can be an arbitrary
+ expression formed from input-column values.
+ </para>
+
+ <para>
+ The ordinal number refers to the ordinal (left-to-right) position
+ of the output column. This feature makes it possible to define an
+ ordering on the basis of a column that does not have a unique
+ name. This is never absolutely necessary because it is always
+ possible to assign a name to an output column using the
+ <literal>AS</literal> clause.
+ </para>
+
+ <para>
+ It is also possible to use arbitrary expressions in the
+ <literal>ORDER BY</literal> clause, including columns that do not
+ appear in the <command>SELECT</command> output list. Thus the
+ following statement is valid:
+<programlisting>
+SELECT name FROM distributors ORDER BY code;
+</programlisting>
+ A limitation of this feature is that an <literal>ORDER BY</literal>
+ clause applying to the result of a <literal>UNION</literal>,
+ <literal>INTERSECT</literal>, or <literal>EXCEPT</literal> clause can only
+ specify an output column name or number, not an expression.
+ </para>
+
+ <para>
+ If an <literal>ORDER BY</literal> expression is a simple name that
+ matches both an output column name and an input column name,
+ <literal>ORDER BY</literal> will interpret it as the output column name.
+ This is the opposite of the choice that <literal>GROUP BY</literal> will
+ make in the same situation. This inconsistency is made to be
+ compatible with the SQL standard.
+ </para>
+
+ <para>
+ Optionally one can add the key word <literal>ASC</literal> (ascending) or
+ <literal>DESC</literal> (descending) after any expression in the
+ <literal>ORDER BY</literal> clause. If not specified, <literal>ASC</literal> is
+ assumed by default. Alternatively, a specific ordering operator
+ name can be specified in the <literal>USING</literal> clause.
+ An ordering operator must be a less-than or greater-than
+ member of some B-tree operator family.
+ <literal>ASC</literal> is usually equivalent to <literal>USING &lt;</literal> and
+ <literal>DESC</literal> is usually equivalent to <literal>USING &gt;</literal>.
+ (But the creator of a user-defined data type can define exactly what the
+ default sort ordering is, and it might correspond to operators with other
+ names.)
+ </para>
+
+ <para>
+ If <literal>NULLS LAST</literal> is specified, null values sort after all
+ non-null values; if <literal>NULLS FIRST</literal> is specified, null values
+ sort before all non-null values. If neither is specified, the default
+ behavior is <literal>NULLS LAST</literal> when <literal>ASC</literal> is specified
+ or implied, and <literal>NULLS FIRST</literal> when <literal>DESC</literal> is specified
+ (thus, the default is to act as though nulls are larger than non-nulls).
+ When <literal>USING</literal> is specified, the default nulls ordering depends
+ on whether the operator is a less-than or greater-than operator.
+ </para>
+
+ <para>
+ Note that ordering options apply only to the expression they follow;
+ for example <literal>ORDER BY x, y DESC</literal> does not mean
+ the same thing as <literal>ORDER BY x DESC, y DESC</literal>.
+ </para>
+
+ <para>
+ Character-string data is sorted according to the collation that applies
+ to the column being sorted. That can be overridden at need by including
+ a <literal>COLLATE</literal> clause in the
+ <replaceable class="parameter">expression</replaceable>, for example
+ <literal>ORDER BY mycolumn COLLATE "en_US"</literal>.
+ For more information see <xref linkend="sql-syntax-collate-exprs"/> and
+ <xref linkend="collation"/>.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-limit" xreflabel="LIMIT Clause">
+ <title><literal>LIMIT</literal> Clause</title>
+
+ <para>
+ The <literal>LIMIT</literal> clause consists of two independent
+ sub-clauses:
+<synopsis>
+LIMIT { <replaceable class="parameter">count</replaceable> | ALL }
+OFFSET <replaceable class="parameter">start</replaceable>
+</synopsis>
+ The parameter <replaceable class="parameter">count</replaceable> specifies the
+ maximum number of rows to return, while <replaceable
+ class="parameter">start</replaceable> specifies the number of rows
+ to skip before starting to return rows. When both are specified,
+ <replaceable class="parameter">start</replaceable> rows are skipped
+ before starting to count the <replaceable
+ class="parameter">count</replaceable> rows to be returned.
+ </para>
+
+ <para>
+ If the <replaceable class="parameter">count</replaceable> expression
+ evaluates to NULL, it is treated as <literal>LIMIT ALL</literal>, i.e., no
+ limit. If <replaceable class="parameter">start</replaceable> evaluates
+ to NULL, it is treated the same as <literal>OFFSET 0</literal>.
+ </para>
+
+ <para>
+ SQL:2008 introduced a different syntax to achieve the same result,
+ which <productname>PostgreSQL</productname> also supports. It is:
+<synopsis>
+OFFSET <replaceable class="parameter">start</replaceable> { ROW | ROWS }
+FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } { ONLY | WITH TIES }
+</synopsis>
+ In this syntax, the <replaceable class="parameter">start</replaceable>
+ or <replaceable class="parameter">count</replaceable> value is required by
+ the standard to be a literal constant, a parameter, or a variable name;
+ as a <productname>PostgreSQL</productname> extension, other expressions
+ are allowed, but will generally need to be enclosed in parentheses to avoid
+ ambiguity.
+ If <replaceable class="parameter">count</replaceable> is
+ omitted in a <literal>FETCH</literal> clause, it defaults to 1.
+ The <literal>WITH TIES</literal> option is used to return any additional
+ rows that tie for the last place in the result set according to
+ the <literal>ORDER BY</literal> clause; <literal>ORDER BY</literal>
+ is mandatory in this case, and <literal>SKIP LOCKED</literal> is
+ not allowed.
+ <literal>ROW</literal> and <literal>ROWS</literal> as well as
+ <literal>FIRST</literal> and <literal>NEXT</literal> are noise
+ words that don't influence the effects of these clauses.
+ According to the standard, the <literal>OFFSET</literal> clause must come
+ before the <literal>FETCH</literal> clause if both are present; but
+ <productname>PostgreSQL</productname> is laxer and allows either order.
+ </para>
+
+ <para>
+ When using <literal>LIMIT</literal>, it is a good idea to use an
+ <literal>ORDER BY</literal> clause that constrains the result rows into a
+ unique order. Otherwise you will get an unpredictable subset of
+ the query's rows &mdash; you might be asking for the tenth through
+ twentieth rows, but tenth through twentieth in what ordering? You
+ don't know what ordering unless you specify <literal>ORDER BY</literal>.
+ </para>
+
+ <para>
+ The query planner takes <literal>LIMIT</literal> into account when
+ generating a query plan, so you are very likely to get different
+ plans (yielding different row orders) depending on what you use
+ for <literal>LIMIT</literal> and <literal>OFFSET</literal>. Thus, using
+ different <literal>LIMIT</literal>/<literal>OFFSET</literal> values to select
+ different subsets of a query result <emphasis>will give
+ inconsistent results</emphasis> unless you enforce a predictable
+ result ordering with <literal>ORDER BY</literal>. This is not a bug; it
+ is an inherent consequence of the fact that SQL does not promise
+ to deliver the results of a query in any particular order unless
+ <literal>ORDER BY</literal> is used to constrain the order.
+ </para>
+
+ <para>
+ It is even possible for repeated executions of the same <literal>LIMIT</literal>
+ query to return different subsets of the rows of a table, if there
+ is not an <literal>ORDER BY</literal> to enforce selection of a deterministic
+ subset. Again, this is not a bug; determinism of the results is
+ simply not guaranteed in such a case.
+ </para>
+ </refsect2>
+
+ <refsect2 id="sql-for-update-share" xreflabel="The Locking Clause">
+ <title>The Locking Clause</title>
+
+ <para>
+ <literal>FOR UPDATE</literal>, <literal>FOR NO KEY UPDATE</literal>, <literal>FOR SHARE</literal>
+ and <literal>FOR KEY SHARE</literal>
+ are <firstterm>locking clauses</firstterm>; they affect how <literal>SELECT</literal>
+ locks rows as they are obtained from the table.
+ </para>
+
+ <para>
+ The locking clause has the general form
+
+<synopsis>
+FOR <replaceable>lock_strength</replaceable> [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT | SKIP LOCKED ]
+</synopsis>
+
+ where <replaceable>lock_strength</replaceable> can be one of
+
+<synopsis>
+UPDATE
+NO KEY UPDATE
+SHARE
+KEY SHARE
+</synopsis>
+ </para>
+
+ <para>
+ For more information on each row-level lock mode, refer to
+ <xref linkend="locking-rows"/>.
+ </para>
+
+ <para>
+ To prevent the operation from waiting for other transactions to commit,
+ use either the <literal>NOWAIT</literal> or <literal>SKIP LOCKED</literal>
+ option. With <literal>NOWAIT</literal>, the statement reports an error, rather
+ than waiting, if a selected row cannot be locked immediately.
+ With <literal>SKIP LOCKED</literal>, any selected rows that cannot be
+ immediately locked are skipped. Skipping locked rows provides an
+ inconsistent view of the data, so this is not suitable for general purpose
+ work, but can be used to avoid lock contention with multiple consumers
+ accessing a queue-like table.
+ Note that <literal>NOWAIT</literal> and <literal>SKIP LOCKED</literal> apply only
+ to the row-level lock(s) &mdash; the required <literal>ROW SHARE</literal>
+ table-level lock is still taken in the ordinary way (see
+ <xref linkend="mvcc"/>). You can use
+ <link linkend="sql-lock"><command>LOCK</command></link>
+ with the <literal>NOWAIT</literal> option first,
+ if you need to acquire the table-level lock without waiting.
+ </para>
+
+ <para>
+ If specific tables are named in a locking clause,
+ then only rows coming from those tables are locked; any other
+ tables used in the <command>SELECT</command> are simply read as
+ usual. A locking
+ clause without a table list affects all tables used in the statement.
+ If a locking clause is
+ applied to a view or sub-query, it affects all tables used in
+ the view or sub-query.
+ However, these clauses
+ do not apply to <literal>WITH</literal> queries referenced by the primary query.
+ If you want row locking to occur within a <literal>WITH</literal> query, specify
+ a locking clause within the <literal>WITH</literal> query.
+ </para>
+
+ <para>
+ Multiple locking
+ clauses can be written if it is necessary to specify different locking
+ behavior for different tables. If the same table is mentioned (or
+ implicitly affected) by more than one locking clause,
+ then it is processed as if it was only specified by the strongest one.
+ Similarly, a table is processed
+ as <literal>NOWAIT</literal> if that is specified in any of the clauses
+ affecting it. Otherwise, it is processed
+ as <literal>SKIP LOCKED</literal> if that is specified in any of the
+ clauses affecting it.
+ </para>
+
+ <para>
+ The locking clauses cannot be
+ used in contexts where returned rows cannot be clearly identified with
+ individual table rows; for example they cannot be used with aggregation.
+ </para>
+
+ <para>
+ When a locking clause
+ appears at the top level of a <command>SELECT</command> query, the rows that
+ are locked are exactly those that are returned by the query; in the
+ case of a join query, the rows locked are those that contribute to
+ returned join rows. In addition, rows that satisfied the query
+ conditions as of the query snapshot will be locked, although they
+ will not be returned if they were updated after the snapshot
+ and no longer satisfy the query conditions. If a
+ <literal>LIMIT</literal> is used, locking stops
+ once enough rows have been returned to satisfy the limit (but note that
+ rows skipped over by <literal>OFFSET</literal> will get locked). Similarly,
+ if a locking clause
+ is used in a cursor's query, only rows actually fetched or stepped past
+ by the cursor will be locked.
+ </para>
+
+ <para>
+ When a locking clause
+ appears in a sub-<command>SELECT</command>, the rows locked are those
+ returned to the outer query by the sub-query. This might involve
+ fewer rows than inspection of the sub-query alone would suggest,
+ since conditions from the outer query might be used to optimize
+ execution of the sub-query. For example,
+<programlisting>
+SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss WHERE col1 = 5;
+</programlisting>
+ will lock only rows having <literal>col1 = 5</literal>, even though that
+ condition is not textually within the sub-query.
+ </para>
+
+ <para>
+ Previous releases failed to preserve a lock which is upgraded by a later
+ savepoint. For example, this code:
+<programlisting>
+BEGIN;
+SELECT * FROM mytable WHERE key = 1 FOR UPDATE;
+SAVEPOINT s;
+UPDATE mytable SET ... WHERE key = 1;
+ROLLBACK TO s;
+</programlisting>
+ would fail to preserve the <literal>FOR UPDATE</literal> lock after the
+ <command>ROLLBACK TO</command>. This has been fixed in release 9.3.
+ </para>
+
+ <caution>
+ <para>
+ It is possible for a <command>SELECT</command> command running at the <literal>READ
+ COMMITTED</literal> transaction isolation level and using <literal>ORDER
+ BY</literal> and a locking clause to return rows out of
+ order. This is because <literal>ORDER BY</literal> is applied first.
+ The command sorts the result, but might then block trying to obtain a lock
+ on one or more of the rows. Once the <literal>SELECT</literal> unblocks, some
+ of the ordering column values might have been modified, leading to those
+ rows appearing to be out of order (though they are in order in terms
+ of the original column values). This can be worked around at need by
+ placing the <literal>FOR UPDATE/SHARE</literal> clause in a sub-query,
+ for example
+<programlisting>
+SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
+</programlisting>
+ Note that this will result in locking all rows of <structname>mytable</structname>,
+ whereas <literal>FOR UPDATE</literal> at the top level would lock only the
+ actually returned rows. This can make for a significant performance
+ difference, particularly if the <literal>ORDER BY</literal> is combined with
+ <literal>LIMIT</literal> or other restrictions. So this technique is recommended
+ only if concurrent updates of the ordering columns are expected and a
+ strictly sorted result is required.
+ </para>
+
+ <para>
+ At the <literal>REPEATABLE READ</literal> or <literal>SERIALIZABLE</literal>
+ transaction isolation level this would cause a serialization failure (with
+ an <literal>SQLSTATE</literal> of <literal>'40001'</literal>), so there is
+ no possibility of receiving rows out of order under these isolation levels.
+ </para>
+ </caution>
+ </refsect2>
+
+ <refsect2 id="sql-table">
+ <title><literal>TABLE</literal> Command</title>
+
+ <para>
+ The command
+<programlisting>
+TABLE <replaceable class="parameter">name</replaceable>
+</programlisting>
+ is equivalent to
+<programlisting>
+SELECT * FROM <replaceable class="parameter">name</replaceable>
+</programlisting>
+ It can be used as a top-level command or as a space-saving syntax
+ variant in parts of complex queries. Only the <literal>WITH</literal>,
+ <literal>UNION</literal>, <literal>INTERSECT</literal>, <literal>EXCEPT</literal>,
+ <literal>ORDER BY</literal>, <literal>LIMIT</literal>, <literal>OFFSET</literal>,
+ <literal>FETCH</literal> and <literal>FOR</literal> locking clauses can be used
+ with <command>TABLE</command>; the <literal>WHERE</literal> clause and any form of
+ aggregation cannot
+ be used.
+ </para>
+ </refsect2>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To join the table <literal>films</literal> with the table
+ <literal>distributors</literal>:
+
+<programlisting>
+SELECT f.title, f.did, d.name, f.date_prod, f.kind
+ FROM distributors d JOIN films f USING (did);
+
+ title | did | name | date_prod | kind
+-------------------+-----+--------------+------------+----------
+ The Third Man | 101 | British Lion | 1949-12-23 | Drama
+ The African Queen | 101 | British Lion | 1951-08-11 | Romantic
+ ...
+</programlisting>
+ </para>
+
+ <para>
+ To sum the column <literal>len</literal> of all films and group
+ the results by <literal>kind</literal>:
+
+<programlisting>
+SELECT kind, sum(len) AS total FROM films GROUP BY kind;
+
+ kind | total
+----------+-------
+ Action | 07:34
+ Comedy | 02:58
+ Drama | 14:28
+ Musical | 06:42
+ Romantic | 04:38
+</programlisting>
+ </para>
+
+ <para>
+ To sum the column <literal>len</literal> of all films, group
+ the results by <literal>kind</literal> and show those group totals
+ that are less than 5 hours:
+
+<programlisting>
+SELECT kind, sum(len) AS total
+ FROM films
+ GROUP BY kind
+ HAVING sum(len) &lt; interval '5 hours';
+
+ kind | total
+----------+-------
+ Comedy | 02:58
+ Romantic | 04:38
+</programlisting>
+ </para>
+
+ <para>
+ The following two examples are identical ways of sorting the individual
+ results according to the contents of the second column
+ (<literal>name</literal>):
+
+<programlisting>
+SELECT * FROM distributors ORDER BY name;
+SELECT * FROM distributors ORDER BY 2;
+
+ did | name
+-----+------------------
+ 109 | 20th Century Fox
+ 110 | Bavaria Atelier
+ 101 | British Lion
+ 107 | Columbia
+ 102 | Jean Luc Godard
+ 113 | Luso films
+ 104 | Mosfilm
+ 103 | Paramount
+ 106 | Toho
+ 105 | United Artists
+ 111 | Walt Disney
+ 112 | Warner Bros.
+ 108 | Westward
+</programlisting>
+ </para>
+
+ <para>
+ The next example shows how to obtain the union of the tables
+ <literal>distributors</literal> and
+ <literal>actors</literal>, restricting the results to those that begin
+ with the letter W in each table. Only distinct rows are wanted, so the
+ key word <literal>ALL</literal> is omitted.
+
+<programlisting>
+distributors: actors:
+ did | name id | name
+-----+-------------- ----+----------------
+ 108 | Westward 1 | Woody Allen
+ 111 | Walt Disney 2 | Warren Beatty
+ 112 | Warner Bros. 3 | Walter Matthau
+ ... ...
+
+SELECT distributors.name
+ FROM distributors
+ WHERE distributors.name LIKE 'W%'
+UNION
+SELECT actors.name
+ FROM actors
+ WHERE actors.name LIKE 'W%';
+
+ name
+----------------
+ Walt Disney
+ Walter Matthau
+ Warner Bros.
+ Warren Beatty
+ Westward
+ Woody Allen
+</programlisting>
+ </para>
+
+ <para>
+ This example shows how to use a function in the <literal>FROM</literal>
+ clause, both with and without a column definition list:
+
+<programlisting>
+CREATE FUNCTION distributors(int) RETURNS SETOF distributors AS $$
+ SELECT * FROM distributors WHERE did = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM distributors(111);
+ did | name
+-----+-------------
+ 111 | Walt Disney
+
+CREATE FUNCTION distributors_2(int) RETURNS SETOF record AS $$
+ SELECT * FROM distributors WHERE did = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM distributors_2(111) AS (f1 int, f2 text);
+ f1 | f2
+-----+-------------
+ 111 | Walt Disney
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example of a function with an ordinality column added:
+
+<programlisting>
+SELECT * FROM unnest(ARRAY['a','b','c','d','e','f']) WITH ORDINALITY;
+ unnest | ordinality
+--------+----------
+ a | 1
+ b | 2
+ c | 3
+ d | 4
+ e | 5
+ f | 6
+(6 rows)
+</programlisting>
+ </para>
+
+ <para>
+ This example shows how to use a simple <literal>WITH</literal> clause:
+
+<programlisting>
+WITH t AS (
+ SELECT random() as x FROM generate_series(1, 3)
+ )
+SELECT * FROM t
+UNION ALL
+SELECT * FROM t
+
+ x
+--------------------
+ 0.534150459803641
+ 0.520092216785997
+ 0.0735620250925422
+ 0.534150459803641
+ 0.520092216785997
+ 0.0735620250925422
+</programlisting>
+
+ Notice that the <literal>WITH</literal> query was evaluated only once,
+ so that we got two sets of the same three random values.
+ </para>
+
+ <para>
+ This example uses <literal>WITH RECURSIVE</literal> to find all
+ subordinates (direct or indirect) of the employee Mary, and their
+ level of indirectness, from a table that shows only direct
+ subordinates:
+
+<programlisting>
+WITH RECURSIVE employee_recursive(distance, employee_name, manager_name) AS (
+ SELECT 1, employee_name, manager_name
+ FROM employee
+ WHERE manager_name = 'Mary'
+ UNION ALL
+ SELECT er.distance + 1, e.employee_name, e.manager_name
+ FROM employee_recursive er, employee e
+ WHERE er.employee_name = e.manager_name
+ )
+SELECT distance, employee_name FROM employee_recursive;
+</programlisting>
+
+ Notice the typical form of recursive queries:
+ an initial condition, followed by <literal>UNION</literal>,
+ followed by the recursive part of the query. Be sure that the
+ recursive part of the query will eventually return no tuples, or
+ else the query will loop indefinitely. (See <xref linkend="queries-with"/>
+ for more examples.)
+ </para>
+
+ <para>
+ This example uses <literal>LATERAL</literal> to apply a set-returning function
+ <function>get_product_names()</function> for each row of the
+ <structname>manufacturers</structname> table:
+
+<programlisting>
+SELECT m.name AS mname, pname
+FROM manufacturers m, LATERAL get_product_names(m.id) pname;
+</programlisting>
+
+ Manufacturers not currently having any products would not appear in the
+ result, since it is an inner join. If we wished to include the names of
+ such manufacturers in the result, we could do:
+
+<programlisting>
+SELECT m.name AS mname, pname
+FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ Of course, the <command>SELECT</command> statement is compatible
+ with the SQL standard. But there are some extensions and some
+ missing features.
+ </para>
+
+ <refsect2>
+ <title>Omitted <literal>FROM</literal> Clauses</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows one to omit the
+ <literal>FROM</literal> clause. It has a straightforward use to
+ compute the results of simple expressions:
+<programlisting>
+SELECT 2+2;
+
+ ?column?
+----------
+ 4
+</programlisting>
+ Some other <acronym>SQL</acronym> databases cannot do this except
+ by introducing a dummy one-row table from which to do the
+ <command>SELECT</command>.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Empty <literal>SELECT</literal> Lists</title>
+
+ <para>
+ The list of output expressions after <literal>SELECT</literal> can be
+ empty, producing a zero-column result table.
+ This is not valid syntax according to the SQL standard.
+ <productname>PostgreSQL</productname> allows it to be consistent with
+ allowing zero-column tables.
+ However, an empty list is not allowed when <literal>DISTINCT</literal> is used.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Omitting the <literal>AS</literal> Key Word</title>
+
+ <para>
+ In the SQL standard, the optional key word <literal>AS</literal> can be
+ omitted before an output column name whenever the new column name
+ is a valid column name (that is, not the same as any reserved
+ keyword). <productname>PostgreSQL</productname> is slightly more
+ restrictive: <literal>AS</literal> is required if the new column name
+ matches any keyword at all, reserved or not. Recommended practice is
+ to use <literal>AS</literal> or double-quote output column names, to prevent
+ any possible conflict against future keyword additions.
+ </para>
+
+ <para>
+ In <literal>FROM</literal> items, both the standard and
+ <productname>PostgreSQL</productname> allow <literal>AS</literal> to
+ be omitted before an alias that is an unreserved keyword. But
+ this is impractical for output column names, because of syntactic
+ ambiguities.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>ONLY</literal> and Inheritance</title>
+
+ <para>
+ The SQL standard requires parentheses around the table name when
+ writing <literal>ONLY</literal>, for example <literal>SELECT * FROM ONLY
+ (tab1), ONLY (tab2) WHERE ...</literal>. <productname>PostgreSQL</productname>
+ considers these parentheses to be optional.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> allows a trailing <literal>*</literal> to be written to
+ explicitly specify the non-<literal>ONLY</literal> behavior of including
+ child tables. The standard does not allow this.
+ </para>
+
+ <para>
+ (These points apply equally to all SQL commands supporting the
+ <literal>ONLY</literal> option.)
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>TABLESAMPLE</literal> Clause Restrictions</title>
+
+ <para>
+ The <literal>TABLESAMPLE</literal> clause is currently accepted only on
+ regular tables and materialized views. According to the SQL standard
+ it should be possible to apply it to any <literal>FROM</literal> item.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Function Calls in <literal>FROM</literal></title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows a function call to be
+ written directly as a member of the <literal>FROM</literal> list. In the SQL
+ standard it would be necessary to wrap such a function call in a
+ sub-<command>SELECT</command>; that is, the syntax
+ <literal>FROM <replaceable>func</replaceable>(...) <replaceable>alias</replaceable></literal>
+ is approximately equivalent to
+ <literal>FROM LATERAL (SELECT <replaceable>func</replaceable>(...)) <replaceable>alias</replaceable></literal>.
+ Note that <literal>LATERAL</literal> is considered to be implicit; this is
+ because the standard requires <literal>LATERAL</literal> semantics for an
+ <literal>UNNEST()</literal> item in <literal>FROM</literal>.
+ <productname>PostgreSQL</productname> treats <literal>UNNEST()</literal> the
+ same as other set-returning functions.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Namespace Available to <literal>GROUP BY</literal> and <literal>ORDER BY</literal></title>
+
+ <para>
+ In the SQL-92 standard, an <literal>ORDER BY</literal> clause can
+ only use output column names or numbers, while a <literal>GROUP
+ BY</literal> clause can only use expressions based on input column
+ names. <productname>PostgreSQL</productname> extends each of
+ these clauses to allow the other choice as well (but it uses the
+ standard's interpretation if there is ambiguity).
+ <productname>PostgreSQL</productname> also allows both clauses to
+ specify arbitrary expressions. Note that names appearing in an
+ expression will always be taken as input-column names, not as
+ output-column names.
+ </para>
+
+ <para>
+ SQL:1999 and later use a slightly different definition which is not
+ entirely upward compatible with SQL-92.
+ In most cases, however, <productname>PostgreSQL</productname>
+ will interpret an <literal>ORDER BY</literal> or <literal>GROUP
+ BY</literal> expression the same way SQL:1999 does.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Functional Dependencies</title>
+
+ <para>
+ <productname>PostgreSQL</productname> recognizes functional dependency
+ (allowing columns to be omitted from <literal>GROUP BY</literal>) only when
+ a table's primary key is included in the <literal>GROUP BY</literal> list.
+ The SQL standard specifies additional conditions that should be
+ recognized.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>LIMIT</literal> and <literal>OFFSET</literal></title>
+
+ <para>
+ The clauses <literal>LIMIT</literal> and <literal>OFFSET</literal>
+ are <productname>PostgreSQL</productname>-specific syntax, also
+ used by <productname>MySQL</productname>. The SQL:2008 standard
+ has introduced the clauses <literal>OFFSET ... FETCH {FIRST|NEXT}
+ ...</literal> for the same functionality, as shown above
+ in <xref linkend="sql-limit"/>. This
+ syntax is also used by <productname>IBM DB2</productname>.
+ (Applications written for <productname>Oracle</productname>
+ frequently use a workaround involving the automatically
+ generated <literal>rownum</literal> column, which is not available in
+ PostgreSQL, to implement the effects of these clauses.)
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title><literal>FOR NO KEY UPDATE</literal>, <literal>FOR UPDATE</literal>, <literal>FOR SHARE</literal>, <literal>FOR KEY SHARE</literal></title>
+
+ <para>
+ Although <literal>FOR UPDATE</literal> appears in the SQL standard, the
+ standard allows it only as an option of <command>DECLARE CURSOR</command>.
+ <productname>PostgreSQL</productname> allows it in any <command>SELECT</command>
+ query as well as in sub-<command>SELECT</command>s, but this is an extension.
+ The <literal>FOR NO KEY UPDATE</literal>, <literal>FOR SHARE</literal> and
+ <literal>FOR KEY SHARE</literal> variants, as well as the <literal>NOWAIT</literal>
+ and <literal>SKIP LOCKED</literal> options, do not appear in the
+ standard.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Data-Modifying Statements in <literal>WITH</literal></title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows <command>INSERT</command>,
+ <command>UPDATE</command>, and <command>DELETE</command> to be used as <literal>WITH</literal>
+ queries. This is not found in the SQL standard.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Nonstandard Clauses</title>
+
+ <para>
+ <literal>DISTINCT ON ( ... )</literal> is an extension of the
+ SQL standard.
+ </para>
+
+ <para>
+ <literal>ROWS FROM( ... )</literal> is an extension of the SQL standard.
+ </para>
+
+ <para>
+ The <literal>MATERIALIZED</literal> and <literal>NOT
+ MATERIALIZED</literal> options of <literal>WITH</literal> are extensions
+ of the SQL standard.
+ </para>
+ </refsect2>
+
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/select_into.sgml b/doc/src/sgml/ref/select_into.sgml
new file mode 100644
index 0000000..82a7778
--- /dev/null
+++ b/doc/src/sgml/ref/select_into.sgml
@@ -0,0 +1,156 @@
+<!--
+doc/src/sgml/ref/select_into.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-selectinto">
+ <indexterm zone="sql-selectinto">
+ <primary>SELECT INTO</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SELECT INTO</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SELECT INTO</refname>
+ <refpurpose>define a new table from the results of a query</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
+SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replaceable> [, ...] ) ] ]
+ * | <replaceable class="parameter">expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...]
+ INTO [ TEMPORARY | TEMP | UNLOGGED ] [ TABLE ] <replaceable class="parameter">new_table</replaceable>
+ [ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ]
+ [ WHERE <replaceable class="parameter">condition</replaceable> ]
+ [ GROUP BY <replaceable class="parameter">expression</replaceable> [, ...] ]
+ [ HAVING <replaceable class="parameter">condition</replaceable> ]
+ [ WINDOW <replaceable class="parameter">window_name</replaceable> AS ( <replaceable class="parameter">window_definition</replaceable> ) [, ...] ]
+ [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] <replaceable class="parameter">select</replaceable> ]
+ [ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+ [ LIMIT { <replaceable class="parameter">count</replaceable> | ALL } ]
+ [ OFFSET <replaceable class="parameter">start</replaceable> [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY ]
+ [ FOR { UPDATE | SHARE } [ OF <replaceable class="parameter">table_name</replaceable> [, ...] ] [ NOWAIT ] [...] ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SELECT INTO</command> creates a new table and fills it
+ with data computed by a query. The data is not returned to the
+ client, as it is with a normal <command>SELECT</command>. The new
+ table's columns have the names and data types associated with the
+ output columns of the <command>SELECT</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TEMPORARY</literal> or <literal>TEMP</literal></term>
+ <listitem>
+ <para>
+ If specified, the table is created as a temporary table. Refer
+ to <xref linkend="sql-createtable"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>UNLOGGED</literal></term>
+ <listitem>
+ <para>
+ If specified, the table is created as an unlogged table. Refer
+ to <xref linkend="sql-createtable"/> for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">new_table</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to be created.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ All other parameters are described in detail under <xref
+ linkend="sql-select"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <link linkend="sql-createtableas"><command>CREATE TABLE AS</command></link> is functionally similar to
+ <command>SELECT INTO</command>. <command>CREATE TABLE AS</command>
+ is the recommended syntax, since this form of <command>SELECT
+ INTO</command> is not available in <application>ECPG</application>
+ or <application>PL/pgSQL</application>, because they interpret the
+ <literal>INTO</literal> clause differently. Furthermore,
+ <command>CREATE TABLE AS</command> offers a superset of the
+ functionality provided by <command>SELECT INTO</command>.
+ </para>
+
+ <para>
+ In contrast to <command>CREATE TABLE AS</command>, <command>SELECT
+ INTO</command> does not allow specifying properties like a table's access
+ method with <xref linkend="sql-createtable-method" /> or the table's
+ tablespace with <xref linkend="sql-createtable-tablespace" />. Use
+ <command>CREATE TABLE AS</command> if necessary. Therefore, the default table
+ access method is chosen for the new table. See <xref
+ linkend="guc-default-table-access-method"/> for more information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Create a new table <literal>films_recent</literal> consisting of only
+ recent entries from the table <literal>films</literal>:
+
+<programlisting>
+SELECT * INTO films_recent FROM films WHERE date_prod &gt;= '2002-01-01';
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard uses <command>SELECT INTO</command> to
+ represent selecting values into scalar variables of a host program,
+ rather than creating a new table. This indeed is the usage found
+ in <application>ECPG</application> (see <xref linkend="ecpg"/>) and
+ <application>PL/pgSQL</application> (see <xref linkend="plpgsql"/>).
+ The <productname>PostgreSQL</productname> usage of <command>SELECT
+ INTO</command> to represent table creation is historical. Some other SQL
+ implementations also use <command>SELECT INTO</command> in this way (but
+ most SQL implementations support <command>CREATE TABLE AS</command>
+ instead). Apart from such compatibility considerations, it is best to use
+ <command>CREATE TABLE AS</command> for this purpose in new code.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createtableas"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/set.sgml b/doc/src/sgml/ref/set.sgml
new file mode 100644
index 0000000..5459b29
--- /dev/null
+++ b/doc/src/sgml/ref/set.sgml
@@ -0,0 +1,332 @@
+<!--
+doc/src/sgml/ref/set.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-set">
+ <indexterm zone="sql-set">
+ <primary>SET</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SET</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SET</refname>
+ <refpurpose>change a run-time parameter</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET [ SESSION | LOCAL ] <replaceable class="parameter">configuration_parameter</replaceable> { TO | = } { <replaceable class="parameter">value</replaceable> | '<replaceable class="parameter">value</replaceable>' | DEFAULT }
+SET [ SESSION | LOCAL ] TIME ZONE { <replaceable class="parameter">value</replaceable> | '<replaceable class="parameter">value</replaceable>' | LOCAL | DEFAULT }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>SET</command> command changes run-time configuration
+ parameters. Many of the run-time parameters listed in
+ <xref linkend="runtime-config"/> can be changed on-the-fly with
+ <command>SET</command>.
+ (Some parameters can only be changed by superusers and users who
+ have been granted <literal>SET</literal> privilege on that parameter.
+ There are also parameters that cannot be changed after server or
+ session start.)
+ <command>SET</command> only affects the value used by the current
+ session.
+ </para>
+
+ <para>
+ If <command>SET</command> (or equivalently <command>SET SESSION</command>)
+ is issued within a transaction that is later aborted, the effects of the
+ <command>SET</command> command disappear when the transaction is rolled
+ back. Once the surrounding transaction is committed, the effects
+ will persist until the end of the session, unless overridden by another
+ <command>SET</command>.
+ </para>
+
+ <para>
+ The effects of <command>SET LOCAL</command> last only till the end of
+ the current transaction, whether committed or not. A special case is
+ <command>SET</command> followed by <command>SET LOCAL</command> within
+ a single transaction: the <command>SET LOCAL</command> value will be
+ seen until the end of the transaction, but afterwards (if the transaction
+ is committed) the <command>SET</command> value will take effect.
+ </para>
+
+ <para>
+ The effects of <command>SET</command> or <command>SET LOCAL</command> are
+ also canceled by rolling back to a savepoint that is earlier than the
+ command.
+ </para>
+
+ <para>
+ If <command>SET LOCAL</command> is used within a function that has a
+ <literal>SET</literal> option for the same variable (see
+ <xref linkend="sql-createfunction"/>),
+ the effects of the <command>SET LOCAL</command> command disappear at
+ function exit; that is, the value in effect when the function was called is
+ restored anyway. This allows <command>SET LOCAL</command> to be used for
+ dynamic or repeated changes of a parameter within a function, while still
+ having the convenience of using the <literal>SET</literal> option to save and
+ restore the caller's value. However, a regular <command>SET</command> command
+ overrides any surrounding function's <literal>SET</literal> option; its effects
+ will persist unless rolled back.
+ </para>
+
+ <note>
+ <para>
+ In <productname>PostgreSQL</productname> versions 8.0 through 8.2,
+ the effects of a <command>SET LOCAL</command> would be canceled by
+ releasing an earlier savepoint, or by successful exit from a
+ <application>PL/pgSQL</application> exception block. This behavior
+ has been changed because it was deemed unintuitive.
+ </para>
+ </note>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SESSION</literal></term>
+ <listitem>
+ <para>
+ Specifies that the command takes effect for the current session.
+ (This is the default if neither <literal>SESSION</literal> nor
+ <literal>LOCAL</literal> appears.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LOCAL</literal></term>
+ <listitem>
+ <para>
+ Specifies that the command takes effect for only the current
+ transaction. After <command>COMMIT</command> or <command>ROLLBACK</command>,
+ the session-level setting takes effect again. Issuing this
+ outside of a transaction block emits a warning and otherwise has
+ no effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">configuration_parameter</replaceable></term>
+ <listitem>
+ <para>
+ Name of a settable run-time parameter. Available parameters are
+ documented in <xref linkend="runtime-config"/> and below.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">value</replaceable></term>
+ <listitem>
+ <para>
+ New value of parameter. Values can be specified as string
+ constants, identifiers, numbers, or comma-separated lists of
+ these, as appropriate for the particular parameter.
+ <literal>DEFAULT</literal> can be written to specify
+ resetting the parameter to its default value (that is, whatever
+ value it would have had if no <command>SET</command> had been executed
+ in the current session).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Besides the configuration parameters documented in <xref
+ linkend="runtime-config"/>, there are a few that can only be
+ adjusted using the <command>SET</command> command or that have a
+ special syntax:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SCHEMA</literal></term>
+ <listitem>
+ <para><literal>SET SCHEMA '<replaceable>value</replaceable>'</literal> is an alias for
+ <literal>SET search_path TO <replaceable>value</replaceable></literal>. Only one
+ schema can be specified using this syntax.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>NAMES</literal></term>
+ <listitem>
+ <para><literal>SET NAMES <replaceable>value</replaceable></literal> is an alias for
+ <literal>SET client_encoding TO <replaceable>value</replaceable></literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SEED</literal></term>
+ <listitem>
+ <para>
+ Sets the internal seed for the random number generator (the
+ function <function>random</function>). Allowed values are
+ floating-point numbers between -1 and 1 inclusive.
+ </para>
+
+ <para>
+ The seed can also be set by invoking the function
+ <function>setseed</function>:
+<programlisting>
+SELECT setseed(<replaceable>value</replaceable>);
+</programlisting></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TIME ZONE</literal></term>
+ <listitem>
+ <para><literal>SET TIME ZONE '<replaceable>value</replaceable>'</literal> is an alias
+ for <literal>SET timezone TO '<replaceable>value</replaceable>'</literal>. The
+ syntax <literal>SET TIME ZONE</literal> allows special syntax
+ for the time zone specification. Here are examples of valid
+ values:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>'PST8PDT'</literal></term>
+ <listitem>
+ <para>
+ The time zone for Berkeley, California.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>'Europe/Rome'</literal></term>
+ <listitem>
+ <para>
+ The time zone for Italy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>-7</literal></term>
+ <listitem>
+ <para>
+ The time zone 7 hours west from UTC (equivalent
+ to PDT). Positive values are east from UTC.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>INTERVAL '-08:00' HOUR TO MINUTE</literal></term>
+ <listitem>
+ <para>
+ The time zone 8 hours west from UTC (equivalent
+ to PST).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>LOCAL</literal></term>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Set the time zone to your local time zone (that is, the
+ server's default value of <varname>timezone</varname>).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ Timezone settings given as numbers or intervals are internally
+ translated to POSIX timezone syntax. For example, after
+ <literal>SET TIME ZONE -7</literal>, <command>SHOW TIME ZONE</command> would
+ report <literal>&lt;-07&gt;+07</literal>.
+ </para>
+
+ <para>
+ Time zone abbreviations are not supported by <command>SET</command>;
+ see <xref linkend="datatype-timezones"/> for more information
+ about time zones.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The function <function>set_config</function> provides equivalent
+ functionality; see <xref linkend="functions-admin-set"/>.
+ Also, it is possible to UPDATE the
+ <link linkend="view-pg-settings"><structname>pg_settings</structname></link>
+ system view to perform the equivalent of <command>SET</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Set the schema search path:
+<programlisting>
+SET search_path TO my_schema, public;
+</programlisting>
+ </para>
+
+ <para>
+ Set the style of date to traditional
+ <productname>POSTGRES</productname> with <quote>day before month</quote>
+ input convention:
+<screen>
+SET datestyle TO postgres, dmy;
+</screen>
+ </para>
+
+ <para>
+ Set the time zone for Berkeley, California:
+<screen>
+SET TIME ZONE 'PST8PDT';
+</screen>
+ </para>
+
+ <para>
+ Set the time zone for Italy:
+<screen>
+SET TIME ZONE 'Europe/Rome';
+</screen></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <literal>SET TIME ZONE</literal> extends syntax defined in the SQL
+ standard. The standard allows only numeric time zone offsets while
+ <productname>PostgreSQL</productname> allows more flexible
+ time-zone specifications. All other <literal>SET</literal>
+ features are <productname>PostgreSQL</productname> extensions.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-reset"/></member>
+ <member><xref linkend="sql-show"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/set_constraints.sgml b/doc/src/sgml/ref/set_constraints.sgml
new file mode 100644
index 0000000..d91965a
--- /dev/null
+++ b/doc/src/sgml/ref/set_constraints.sgml
@@ -0,0 +1,125 @@
+<!--
+doc/src/sgml/ref/set_constraints.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-set-constraints">
+ <indexterm zone="sql-set-constraints">
+ <primary>SET CONSTRAINTS</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SET CONSTRAINTS</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SET CONSTRAINTS</refname>
+ <refpurpose>set constraint check timing for the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET CONSTRAINTS { ALL | <replaceable class="parameter">name</replaceable> [, ...] } { DEFERRED | IMMEDIATE }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SET CONSTRAINTS</command> sets the behavior of constraint
+ checking within the current transaction. <literal>IMMEDIATE</literal>
+ constraints are checked at the end of each
+ statement. <literal>DEFERRED</literal> constraints are not checked until
+ transaction commit. Each constraint has its own
+ <literal>IMMEDIATE</literal> or <literal>DEFERRED</literal> mode.
+ </para>
+
+ <para>
+ Upon creation, a constraint is given one of three
+ characteristics: <literal>DEFERRABLE INITIALLY DEFERRED</literal>,
+ <literal>DEFERRABLE INITIALLY IMMEDIATE</literal>, or
+ <literal>NOT DEFERRABLE</literal>. The third
+ class is always <literal>IMMEDIATE</literal> and is not affected by the
+ <command>SET CONSTRAINTS</command> command. The first two classes start
+ every transaction in the indicated mode, but their behavior can be changed
+ within a transaction by <command>SET CONSTRAINTS</command>.
+ </para>
+
+ <para>
+ <command>SET CONSTRAINTS</command> with a list of constraint names changes
+ the mode of just those constraints (which must all be deferrable). Each
+ constraint name can be schema-qualified. The
+ current schema search path is used to find the first matching name if
+ no schema name is specified. <command>SET CONSTRAINTS ALL</command>
+ changes the mode of all deferrable constraints.
+ </para>
+
+ <para>
+ When <command>SET CONSTRAINTS</command> changes the mode of a constraint
+ from <literal>DEFERRED</literal>
+ to <literal>IMMEDIATE</literal>, the new mode takes effect
+ retroactively: any outstanding data modifications that would have
+ been checked at the end of the transaction are instead checked during the
+ execution of the <command>SET CONSTRAINTS</command> command.
+ If any such constraint is violated, the <command>SET CONSTRAINTS</command>
+ fails (and does not change the constraint mode). Thus, <command>SET
+ CONSTRAINTS</command> can be used to force checking of constraints to
+ occur at a specific point in a transaction.
+ </para>
+
+ <para>
+ Currently, only <literal>UNIQUE</literal>, <literal>PRIMARY KEY</literal>,
+ <literal>REFERENCES</literal> (foreign key), and <literal>EXCLUDE</literal>
+ constraints are affected by this setting.
+ <literal>NOT NULL</literal> and <literal>CHECK</literal> constraints are
+ always checked immediately when a row is inserted or modified
+ (<emphasis>not</emphasis> at the end of the statement).
+ Uniqueness and exclusion constraints that have not been declared
+ <literal>DEFERRABLE</literal> are also checked immediately.
+ </para>
+
+ <para>
+ The firing of triggers that are declared as <quote>constraint triggers</quote>
+ is also controlled by this setting &mdash; they fire at the same time
+ that the associated constraint should be checked.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Because <productname>PostgreSQL</productname> does not require constraint
+ names to be unique within a schema (but only per-table), it is possible
+ that there is more than one match for a specified constraint name.
+ In this case <command>SET CONSTRAINTS</command> will act on all matches.
+ For a non-schema-qualified name, once a match or matches have been found in
+ some schema in the search path, schemas appearing later in the path are not
+ searched.
+ </para>
+
+ <para>
+ This command only alters the behavior of constraints within the
+ current transaction. Issuing this outside of a transaction block
+ emits a warning and otherwise has no effect.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command complies with the behavior defined in the SQL
+ standard, except for the limitation that, in
+ <productname>PostgreSQL</productname>, it does not apply to
+ <literal>NOT NULL</literal> and <literal>CHECK</literal> constraints.
+ Also, <productname>PostgreSQL</productname> checks non-deferrable
+ uniqueness constraints immediately, not at end of statement as the
+ standard would suggest.
+ </para>
+
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml
new file mode 100644
index 0000000..4e02322
--- /dev/null
+++ b/doc/src/sgml/ref/set_role.sgml
@@ -0,0 +1,155 @@
+<!--
+doc/src/sgml/ref/set_role.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-set-role">
+ <indexterm zone="sql-set-role">
+ <primary>SET ROLE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SET ROLE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SET ROLE</refname>
+ <refpurpose>set the current user identifier of the current session</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET [ SESSION | LOCAL ] ROLE <replaceable class="parameter">role_name</replaceable>
+SET [ SESSION | LOCAL ] ROLE NONE
+RESET ROLE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ This command sets the current user
+ identifier of the current SQL session to be <replaceable
+ class="parameter">role_name</replaceable>. The role name can be
+ written as either an identifier or a string literal.
+ After <command>SET ROLE</command>, permissions checking for SQL commands
+ is carried out as though the named role were the one that had logged
+ in originally.
+ </para>
+
+ <para>
+ The specified <replaceable class="parameter">role_name</replaceable>
+ must be a role that the current session user is a member of.
+ (If the session user is a superuser, any role can be selected.)
+ </para>
+
+ <para>
+ The <literal>SESSION</literal> and <literal>LOCAL</literal> modifiers act the same
+ as for the regular <link linkend="sql-set"><command>SET</command></link>
+ command.
+ </para>
+
+ <para>
+ <literal>SET ROLE NONE</literal> sets the current user identifier to the
+ current session user identifier, as returned by
+ <function>session_user</function>. <literal>RESET ROLE</literal> sets the
+ current user identifier to the connection-time setting specified by the
+ <link linkend="libpq-connect-options">command-line options</link>,
+ <link linkend="sql-alterrole"><command>ALTER ROLE</command></link>, or
+ <link linkend="sql-alterdatabase"><command>ALTER DATABASE</command></link>,
+ if any such settings exist. Otherwise, <literal>RESET ROLE</literal> sets
+ the current user identifier to the current session user identifier. These
+ forms can be executed by any user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Using this command, it is possible to either add privileges or restrict
+ one's privileges. If the session user role has the <literal>INHERIT</literal>
+ attribute, then it automatically has all the privileges of every role that
+ it could <command>SET ROLE</command> to; in this case <command>SET ROLE</command>
+ effectively drops all the privileges assigned directly to the session user
+ and to the other roles it is a member of, leaving only the privileges
+ available to the named role. On the other hand, if the session user role
+ has the <literal>NOINHERIT</literal> attribute, <command>SET ROLE</command> drops the
+ privileges assigned directly to the session user and instead acquires the
+ privileges available to the named role.
+ </para>
+
+ <para>
+ In particular, when a superuser chooses to <command>SET ROLE</command> to a
+ non-superuser role, they lose their superuser privileges.
+ </para>
+
+ <para>
+ <command>SET ROLE</command> has effects comparable to
+ <link linkend="sql-set-session-authorization"><command>SET SESSION AUTHORIZATION</command></link>, but the privilege
+ checks involved are quite different. Also,
+ <command>SET SESSION AUTHORIZATION</command> determines which roles are
+ allowable for later <command>SET ROLE</command> commands, whereas changing
+ roles with <command>SET ROLE</command> does not change the set of roles
+ allowed to a later <command>SET ROLE</command>.
+ </para>
+
+ <para>
+ <command>SET ROLE</command> does not process session variables as specified by
+ the role's <link linkend="sql-alterrole"><command>ALTER ROLE</command></link> settings; this only happens during
+ login.
+ </para>
+
+ <para>
+ <command>SET ROLE</command> cannot be used within a
+ <literal>SECURITY DEFINER</literal> function.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ peter | peter
+
+SET ROLE 'paul';
+
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ peter | paul
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ <productname>PostgreSQL</productname>
+ allows identifier syntax (<literal>"<replaceable>rolename</replaceable>"</literal>), while
+ the SQL standard requires the role name to be written as a string
+ literal. SQL does not allow this command during a transaction;
+ <productname>PostgreSQL</productname> does not make this
+ restriction because there is no reason to.
+ The <literal>SESSION</literal> and <literal>LOCAL</literal> modifiers are a
+ <productname>PostgreSQL</productname> extension, as is the
+ <literal>RESET</literal> syntax.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-set-session-authorization"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/set_session_auth.sgml b/doc/src/sgml/ref/set_session_auth.sgml
new file mode 100644
index 0000000..f8fcafc
--- /dev/null
+++ b/doc/src/sgml/ref/set_session_auth.sgml
@@ -0,0 +1,130 @@
+<!--
+doc/src/sgml/ref/set_session_auth.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-set-session-authorization">
+ <indexterm zone="sql-set-session-authorization">
+ <primary>SET SESSION AUTHORIZATION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SET SESSION AUTHORIZATION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SET SESSION AUTHORIZATION</refname>
+ <refpurpose>set the session user identifier and the current user identifier of the current session</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET [ SESSION | LOCAL ] SESSION AUTHORIZATION <replaceable class="parameter">user_name</replaceable>
+SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT
+RESET SESSION AUTHORIZATION
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ This command sets the session user identifier and the current user
+ identifier of the current SQL session to be <replaceable
+ class="parameter">user_name</replaceable>. The user name can be
+ written as either an identifier or a string literal. Using this
+ command, it is possible, for example, to temporarily become an
+ unprivileged user and later switch back to being a superuser.
+ </para>
+
+ <para>
+ The session user identifier is initially set to be the (possibly
+ authenticated) user name provided by the client. The current user
+ identifier is normally equal to the session user identifier, but
+ might change temporarily in the context of <literal>SECURITY DEFINER</literal>
+ functions and similar mechanisms; it can also be changed by
+ <link linkend="sql-set-role"><command>SET ROLE</command></link>.
+ The current user identifier is relevant for permission checking.
+ </para>
+
+ <para>
+ The session user identifier can be changed only if the initial session
+ user (the <firstterm>authenticated user</firstterm>) had the
+ superuser privilege. Otherwise, the command is accepted only if it
+ specifies the authenticated user name.
+ </para>
+
+ <para>
+ The <literal>SESSION</literal> and <literal>LOCAL</literal> modifiers act the same
+ as for the regular <link linkend="sql-set"><command>SET</command></link>
+ command.
+ </para>
+
+ <para>
+ The <literal>DEFAULT</literal> and <literal>RESET</literal> forms reset the session
+ and current user identifiers to be the originally authenticated user
+ name. These forms can be executed by any user.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>SET SESSION AUTHORIZATION</command> cannot be used within a
+ <literal>SECURITY DEFINER</literal> function.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+<programlisting>
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ peter | peter
+
+SET SESSION AUTHORIZATION 'paul';
+
+SELECT SESSION_USER, CURRENT_USER;
+
+ session_user | current_user
+--------------+--------------
+ paul | paul
+</programlisting>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL standard allows some other expressions to appear in place
+ of the literal <replaceable>user_name</replaceable>, but these options
+ are not important in practice. <productname>PostgreSQL</productname>
+ allows identifier syntax (<literal>"<replaceable>username</replaceable>"</literal>), which SQL
+ does not. SQL does not allow this command during a transaction;
+ <productname>PostgreSQL</productname> does not make this
+ restriction because there is no reason to.
+ The <literal>SESSION</literal> and <literal>LOCAL</literal> modifiers are a
+ <productname>PostgreSQL</productname> extension, as is the
+ <literal>RESET</literal> syntax.
+ </para>
+
+ <para>
+ The privileges necessary to execute this command are left
+ implementation-defined by the standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-set-role"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/set_transaction.sgml b/doc/src/sgml/ref/set_transaction.sgml
new file mode 100644
index 0000000..727a927
--- /dev/null
+++ b/doc/src/sgml/ref/set_transaction.sgml
@@ -0,0 +1,290 @@
+<!--
+doc/src/sgml/ref/set_transaction.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-set-transaction">
+ <indexterm zone="sql-set-transaction">
+ <primary>SET TRANSACTION</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>transaction isolation level</primary>
+ <secondary>setting</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>read-only transaction</primary>
+ <secondary>setting</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>deferrable transaction</primary>
+ <secondary>setting</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SET TRANSACTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SET TRANSACTION</refname>
+ <refpurpose>set the characteristics of the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SET TRANSACTION <replaceable class="parameter">transaction_mode</replaceable> [, ...]
+SET TRANSACTION SNAPSHOT <replaceable class="parameter">snapshot_id</replaceable>
+SET SESSION CHARACTERISTICS AS TRANSACTION <replaceable class="parameter">transaction_mode</replaceable> [, ...]
+
+<phrase>where <replaceable class="parameter">transaction_mode</replaceable> is one of:</phrase>
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ The <command>SET TRANSACTION</command> command sets the
+ characteristics of the current transaction. It has no effect on any
+ subsequent transactions. <command>SET SESSION
+ CHARACTERISTICS</command> sets the default transaction
+ characteristics for subsequent transactions of a session. These
+ defaults can be overridden by <command>SET TRANSACTION</command>
+ for an individual transaction.
+ </para>
+
+ <para>
+ The available transaction characteristics are the transaction
+ isolation level, the transaction access mode (read/write or
+ read-only), and the deferrable mode.
+ In addition, a snapshot can be selected, though only for the current
+ transaction, not as a session default.
+ </para>
+
+ <para>
+ The isolation level of a transaction determines what data the
+ transaction can see when other transactions are running concurrently:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>READ COMMITTED</literal></term>
+ <listitem>
+ <para>
+ A statement can only see rows committed before it began. This
+ is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>REPEATABLE READ</literal></term>
+ <listitem>
+ <para>
+ All statements of the current transaction can only see rows committed
+ before the first query or data-modification statement was executed in
+ this transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SERIALIZABLE</literal></term>
+ <listitem>
+ <para>
+ All statements of the current transaction can only see rows committed
+ before the first query or data-modification statement was executed in
+ this transaction. If a pattern of reads and writes among concurrent
+ serializable transactions would create a situation which could not
+ have occurred for any serial (one-at-a-time) execution of those
+ transactions, one of them will be rolled back with a
+ <literal>serialization_failure</literal> error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ The SQL standard defines one additional level, <literal>READ
+ UNCOMMITTED</literal>.
+ In <productname>PostgreSQL</productname> <literal>READ
+ UNCOMMITTED</literal> is treated as <literal>READ COMMITTED</literal>.
+ </para>
+
+ <para>
+ The transaction isolation level cannot be changed after the first query or
+ data-modification statement (<command>SELECT</command>,
+ <command>INSERT</command>, <command>DELETE</command>,
+ <command>UPDATE</command>, <command>MERGE</command>,
+ <command>FETCH</command>, or
+ <command>COPY</command>) of a transaction has been executed. See
+ <xref linkend="mvcc"/> for more information about transaction
+ isolation and concurrency control.
+ </para>
+
+ <para>
+ The transaction access mode determines whether the transaction is
+ read/write or read-only. Read/write is the default. When a
+ transaction is read-only, the following SQL commands are
+ disallowed: <command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, <command>MERGE</command>, and
+ <command>COPY FROM</command> if the
+ table they would write to is not a temporary table; all
+ <literal>CREATE</literal>, <literal>ALTER</literal>, and
+ <literal>DROP</literal> commands; <literal>COMMENT</literal>,
+ <literal>GRANT</literal>, <literal>REVOKE</literal>,
+ <literal>TRUNCATE</literal>; and <literal>EXPLAIN ANALYZE</literal>
+ and <literal>EXECUTE</literal> if the command they would execute is
+ among those listed. This is a high-level notion of read-only that
+ does not prevent all writes to disk.
+ </para>
+
+ <para>
+ The <literal>DEFERRABLE</literal> transaction property has no effect
+ unless the transaction is also <literal>SERIALIZABLE</literal> and
+ <literal>READ ONLY</literal>. When all three of these properties are
+ selected for a
+ transaction, the transaction may block when first acquiring its snapshot,
+ after which it is able to run without the normal overhead of a
+ <literal>SERIALIZABLE</literal> transaction and without any risk of
+ contributing to or being canceled by a serialization failure. This mode
+ is well suited for long-running reports or backups.
+ </para>
+
+ <para>
+ The <literal>SET TRANSACTION SNAPSHOT</literal> command allows a new
+ transaction to run with the same <firstterm>snapshot</firstterm> as an existing
+ transaction. The pre-existing transaction must have exported its snapshot
+ with the <literal>pg_export_snapshot</literal> function (see <xref
+ linkend="functions-snapshot-synchronization"/>). That function returns a
+ snapshot identifier, which must be given to <literal>SET TRANSACTION
+ SNAPSHOT</literal> to specify which snapshot is to be imported. The
+ identifier must be written as a string literal in this command, for example
+ <literal>'00000003-0000001B-1'</literal>.
+ <literal>SET TRANSACTION SNAPSHOT</literal> can only be executed at the
+ start of a transaction, before the first query or
+ data-modification statement (<command>SELECT</command>,
+ <command>INSERT</command>, <command>DELETE</command>,
+ <command>UPDATE</command>, <command>MERGE</command>,
+ <command>FETCH</command>, or
+ <command>COPY</command>) of the transaction. Furthermore, the transaction
+ must already be set to <literal>SERIALIZABLE</literal> or
+ <literal>REPEATABLE READ</literal> isolation level (otherwise, the snapshot
+ would be discarded immediately, since <literal>READ COMMITTED</literal> mode takes
+ a new snapshot for each command). If the importing transaction uses
+ <literal>SERIALIZABLE</literal> isolation level, then the transaction that
+ exported the snapshot must also use that isolation level. Also, a
+ non-read-only serializable transaction cannot import a snapshot from a
+ read-only transaction.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If <command>SET TRANSACTION</command> is executed without a prior
+ <command>START TRANSACTION</command> or <command>BEGIN</command>,
+ it emits a warning and otherwise has no effect.
+ </para>
+
+ <para>
+ It is possible to dispense with <command>SET TRANSACTION</command>
+ by instead specifying the desired <replaceable
+ class="parameter">transaction_modes</replaceable> in
+ <command>BEGIN</command> or <command>START TRANSACTION</command>.
+ But that option is not available for <command>SET TRANSACTION
+ SNAPSHOT</command>.
+ </para>
+
+ <para>
+ The session default transaction modes can also be set or examined via the
+ configuration parameters <xref linkend="guc-default-transaction-isolation"/>,
+ <xref linkend="guc-default-transaction-read-only"/>, and
+ <xref linkend="guc-default-transaction-deferrable"/>.
+ (In fact <command>SET SESSION CHARACTERISTICS</command> is just a
+ verbose equivalent for setting these variables with <command>SET</command>.)
+ This means the defaults can be set in the configuration file, via
+ <command>ALTER DATABASE</command>, etc. Consult <xref linkend="runtime-config"/>
+ for more information.
+ </para>
+
+ <para>
+ The current transaction's modes can similarly be set or examined via the
+ configuration parameters <xref linkend="guc-transaction-isolation"/>,
+ <xref linkend="guc-transaction-read-only"/>, and
+ <xref linkend="guc-transaction-deferrable"/>. Setting one of these
+ parameters acts the same as the corresponding <command>SET
+ TRANSACTION</command> option, with the same restrictions on when it can
+ be done. However, these parameters cannot be set in the configuration
+ file, or from any source other than live SQL.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To begin a new transaction with the same snapshot as an already
+ existing transaction, first export the snapshot from the existing
+ transaction. That will return the snapshot identifier, for example:
+
+<programlisting>
+BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SELECT pg_export_snapshot();
+ pg_export_snapshot
+---------------------
+ 00000003-0000001B-1
+(1 row)
+</programlisting>
+
+ Then give the snapshot identifier in a <command>SET TRANSACTION
+ SNAPSHOT</command> command at the beginning of the newly opened
+ transaction:
+
+<programlisting>
+BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+SET TRANSACTION SNAPSHOT '00000003-0000001B-1';
+</programlisting></para>
+ </refsect1>
+
+ <refsect1 id="r1-sql-set-transaction-3">
+ <title>Compatibility</title>
+
+ <para>
+ These commands are defined in the <acronym>SQL</acronym> standard,
+ except for the <literal>DEFERRABLE</literal> transaction mode
+ and the <command>SET TRANSACTION SNAPSHOT</command> form, which are
+ <productname>PostgreSQL</productname> extensions.
+ </para>
+
+ <para>
+ <literal>SERIALIZABLE</literal> is the default transaction
+ isolation level in the standard. In
+ <productname>PostgreSQL</productname> the default is ordinarily
+ <literal>READ COMMITTED</literal>, but you can change it as
+ mentioned above.
+ </para>
+
+ <para>
+ In the SQL standard, there is one other transaction characteristic
+ that can be set with these commands: the size of the diagnostics
+ area. This concept is specific to embedded SQL, and therefore is
+ not implemented in the <productname>PostgreSQL</productname> server.
+ </para>
+
+ <para>
+ The SQL standard requires commas between successive <replaceable
+ class="parameter">transaction_modes</replaceable>, but for historical
+ reasons <productname>PostgreSQL</productname> allows the commas to be
+ omitted.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/show.sgml b/doc/src/sgml/ref/show.sgml
new file mode 100644
index 0000000..b3747b1
--- /dev/null
+++ b/doc/src/sgml/ref/show.sgml
@@ -0,0 +1,200 @@
+<!--
+doc/src/sgml/ref/show.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-show">
+ <indexterm zone="sql-show">
+ <primary>SHOW</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SHOW</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SHOW</refname>
+ <refpurpose>show the value of a run-time parameter</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SHOW <replaceable class="parameter">name</replaceable>
+SHOW ALL
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>SHOW</command> will display the current setting of
+ run-time parameters. These variables can be set using the
+ <command>SET</command> statement, by editing the
+ <filename>postgresql.conf</filename> configuration file, through
+ the <envar>PGOPTIONS</envar> environmental variable (when using
+ <application>libpq</application> or a <application>libpq</application>-based
+ application), or through command-line flags when starting the
+ <command>postgres</command> server. See <xref
+ linkend="runtime-config"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a run-time parameter. Available parameters are
+ documented in <xref linkend="runtime-config"/> and on the <xref
+ linkend="sql-set"/> reference page. In
+ addition, there are a few parameters that can be shown but not
+ set:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SERVER_VERSION</literal></term>
+ <listitem>
+ <para>
+ Shows the server's version number.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SERVER_ENCODING</literal></term>
+ <listitem>
+ <para>
+ Shows the server-side character set encoding. At present,
+ this parameter can be shown but not set, because the
+ encoding is determined at database creation time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LC_COLLATE</literal></term>
+ <listitem>
+ <para>
+ Shows the database's locale setting for collation (text
+ ordering). At present, this parameter can be shown but not
+ set, because the setting is determined at database creation
+ time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>LC_CTYPE</literal></term>
+ <listitem>
+ <para>
+ Shows the database's locale setting for character
+ classification. At present, this parameter can be shown but
+ not set, because the setting is determined at database creation
+ time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>IS_SUPERUSER</literal></term>
+ <listitem>
+ <para>
+ True if the current role has superuser privileges.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist></para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ALL</literal></term>
+ <listitem>
+ <para>
+ Show the values of all configuration parameters, with descriptions.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The function <function>current_setting</function> produces
+ equivalent output; see <xref linkend="functions-admin-set"/>.
+ Also, the
+ <link linkend="view-pg-settings"><structname>pg_settings</structname></link>
+ system view produces the same information.
+
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Show the current setting of the parameter <varname>DateStyle</varname>:
+
+<programlisting>
+SHOW DateStyle;
+ DateStyle
+-----------
+ ISO, MDY
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Show the current setting of the parameter <varname>geqo</varname>:
+<programlisting>
+SHOW geqo;
+ geqo
+------
+ on
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Show all settings:
+<programlisting>
+SHOW ALL;
+ name | setting | description
+-------------------------+---------+-------------------------------------------------
+ allow_system_table_mods | off | Allows modifications of the structure of ...
+ .
+ .
+ .
+ xmloption | content | Sets whether XML data in implicit parsing ...
+ zero_damaged_pages | off | Continues processing past damaged page headers.
+(196 rows)
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The <command>SHOW</command> command is a
+ <productname>PostgreSQL</productname> extension.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-set"/></member>
+ <member><xref linkend="sql-reset"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/start_transaction.sgml b/doc/src/sgml/ref/start_transaction.sgml
new file mode 100644
index 0000000..74ccd7e
--- /dev/null
+++ b/doc/src/sgml/ref/start_transaction.sgml
@@ -0,0 +1,97 @@
+<!--
+doc/src/sgml/ref/start_transaction.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-start-transaction">
+ <indexterm zone="sql-start-transaction">
+ <primary>START TRANSACTION</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>START TRANSACTION</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>START TRANSACTION</refname>
+ <refpurpose>start a transaction block</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+START TRANSACTION [ <replaceable class="parameter">transaction_mode</replaceable> [, ...] ]
+
+<phrase>where <replaceable class="parameter">transaction_mode</replaceable> is one of:</phrase>
+
+ ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }
+ READ WRITE | READ ONLY
+ [ NOT ] DEFERRABLE
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ This command begins a new transaction block. If the isolation level,
+ read/write mode, or deferrable mode is specified, the new transaction has those
+ characteristics, as if <link linkend="sql-set-transaction"><command>SET TRANSACTION</command></link> was executed. This is the same
+ as the <link linkend="sql-begin"><command>BEGIN</command></link> command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <para>
+ Refer to <xref linkend="sql-set-transaction"/> for information on the meaning
+ of the parameters to this statement.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ In the standard, it is not necessary to issue <command>START TRANSACTION</command>
+ to start a transaction block: any SQL command implicitly begins a block.
+ <productname>PostgreSQL</productname>'s behavior can be seen as implicitly
+ issuing a <command>COMMIT</command> after each command that does not
+ follow <command>START TRANSACTION</command> (or <command>BEGIN</command>),
+ and it is therefore often called <quote>autocommit</quote>.
+ Other relational database systems might offer an autocommit feature
+ as a convenience.
+ </para>
+
+ <para>
+ The <literal>DEFERRABLE</literal>
+ <replaceable class="parameter">transaction_mode</replaceable>
+ is a <productname>PostgreSQL</productname> language extension.
+ </para>
+
+ <para>
+ The SQL standard requires commas between successive <replaceable
+ class="parameter">transaction_modes</replaceable>, but for historical
+ reasons <productname>PostgreSQL</productname> allows the commas to be
+ omitted.
+ </para>
+
+ <para>
+ See also the compatibility section of <xref linkend="sql-set-transaction"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-begin"/></member>
+ <member><xref linkend="sql-commit"/></member>
+ <member><xref linkend="sql-rollback"/></member>
+ <member><xref linkend="sql-savepoint"/></member>
+ <member><xref linkend="sql-set-transaction"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/truncate.sgml b/doc/src/sgml/ref/truncate.sgml
new file mode 100644
index 0000000..9d846f8
--- /dev/null
+++ b/doc/src/sgml/ref/truncate.sgml
@@ -0,0 +1,233 @@
+<!--
+doc/src/sgml/ref/truncate.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-truncate">
+ <indexterm zone="sql-truncate">
+ <primary>TRUNCATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>TRUNCATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>TRUNCATE</refname>
+ <refpurpose>empty a table or set of tables</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+TRUNCATE [ TABLE ] [ ONLY ] <replaceable class="parameter">name</replaceable> [ * ] [, ... ]
+ [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>TRUNCATE</command> quickly removes all rows from a set of
+ tables. It has the same effect as an unqualified
+ <command>DELETE</command> on each table, but since it does not actually
+ scan the tables it is faster. Furthermore, it reclaims disk space
+ immediately, rather than requiring a subsequent <command>VACUUM</command>
+ operation. This is most useful on large tables.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a table to truncate.
+ If <literal>ONLY</literal> is specified before the table name, only that table
+ is truncated. If <literal>ONLY</literal> is not specified, the table and all
+ its descendant tables (if any) are truncated. Optionally, <literal>*</literal>
+ can be specified after the table name to explicitly indicate that
+ descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTART IDENTITY</literal></term>
+ <listitem>
+ <para>
+ Automatically restart sequences owned by columns of
+ the truncated table(s).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CONTINUE IDENTITY</literal></term>
+ <listitem>
+ <para>
+ Do not change the values of sequences. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>CASCADE</literal></term>
+ <listitem>
+ <para>
+ Automatically truncate all tables that have foreign-key references
+ to any of the named tables, or to any tables added to the group
+ due to <literal>CASCADE</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RESTRICT</literal></term>
+ <listitem>
+ <para>
+ Refuse to truncate if any of the tables have foreign-key references
+ from tables that are not listed in the command. This is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ You must have the <literal>TRUNCATE</literal> privilege on a table
+ to truncate it.
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> acquires an <literal>ACCESS EXCLUSIVE</literal> lock on each
+ table it operates on, which blocks all other concurrent operations
+ on the table. When <literal>RESTART IDENTITY</literal> is specified, any
+ sequences that are to be restarted are likewise locked exclusively.
+ If concurrent access to a table is required, then
+ the <command>DELETE</command> command should be used instead.
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> cannot be used on a table that has foreign-key
+ references from other tables, unless all such tables are also truncated
+ in the same command. Checking validity in such cases would require table
+ scans, and the whole point is not to do one. The <literal>CASCADE</literal>
+ option can be used to automatically include all dependent tables &mdash;
+ but be very careful when using this option, or else you might lose data you
+ did not intend to!
+ Note in particular that when the table to be truncated is a partition,
+ siblings partitions are left untouched, but cascading occurs to all
+ referencing tables and all their partitions with no distinction.
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> will not fire any <literal>ON DELETE</literal>
+ triggers that might exist for the tables. But it will fire
+ <literal>ON TRUNCATE</literal> triggers.
+ If <literal>ON TRUNCATE</literal> triggers are defined for any of
+ the tables, then all <literal>BEFORE TRUNCATE</literal> triggers are
+ fired before any truncation happens, and all <literal>AFTER
+ TRUNCATE</literal> triggers are fired after the last truncation is
+ performed and any sequences are reset.
+ The triggers will fire in the order that the tables are
+ to be processed (first those listed in the command, and then any
+ that were added due to cascading).
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> is not MVCC-safe. After truncation, the table will
+ appear empty to concurrent transactions, if they are using a snapshot
+ taken before the truncation occurred.
+ See <xref linkend="mvcc-caveats"/> for more details.
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> is transaction-safe with respect to the data
+ in the tables: the truncation will be safely rolled back if the surrounding
+ transaction does not commit.
+ </para>
+
+ <para>
+ When <literal>RESTART IDENTITY</literal> is specified, the implied
+ <command>ALTER SEQUENCE RESTART</command> operations are also done
+ transactionally; that is, they will be rolled back if the surrounding
+ transaction does not commit. Be aware that if any additional
+ sequence operations are done on the restarted sequences before the
+ transaction rolls back, the effects of these operations on the sequences
+ will be rolled back, but not their effects on <function>currval()</function>;
+ that is, after the transaction <function>currval()</function> will continue to
+ reflect the last sequence value obtained inside the failed transaction,
+ even though the sequence itself may no longer be consistent with that.
+ This is similar to the usual behavior of <function>currval()</function> after
+ a failed transaction.
+ </para>
+
+ <para>
+ <command>TRUNCATE</command> can be used for foreign tables if
+ supported by the foreign data wrapper, for instance,
+ see <xref linkend="postgres-fdw"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Truncate the tables <literal>bigtable</literal> and
+ <literal>fattable</literal>:
+
+<programlisting>
+TRUNCATE bigtable, fattable;
+</programlisting>
+ </para>
+
+ <para>
+ The same, and also reset any associated sequence generators:
+
+<programlisting>
+TRUNCATE bigtable, fattable RESTART IDENTITY;
+</programlisting>
+ </para>
+
+ <para>
+ Truncate the table <literal>othertable</literal>, and cascade to any tables
+ that reference <literal>othertable</literal> via foreign-key
+ constraints:
+
+<programlisting>
+TRUNCATE othertable CASCADE;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ The SQL:2008 standard includes a <command>TRUNCATE</command> command
+ with the syntax <literal>TRUNCATE TABLE
+ <replaceable>tablename</replaceable></literal>. The clauses
+ <literal>CONTINUE IDENTITY</literal>/<literal>RESTART IDENTITY</literal>
+ also appear in that standard, but have slightly different though related
+ meanings. Some of the concurrency behavior of this command is left
+ implementation-defined by the standard, so the above notes should be
+ considered and compared with other implementations if necessary.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-delete"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/unlisten.sgml b/doc/src/sgml/ref/unlisten.sgml
new file mode 100644
index 0000000..687bf48
--- /dev/null
+++ b/doc/src/sgml/ref/unlisten.sgml
@@ -0,0 +1,133 @@
+<!--
+doc/src/sgml/ref/unlisten.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-unlisten">
+ <indexterm zone="sql-unlisten">
+ <primary>UNLISTEN</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>UNLISTEN</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>UNLISTEN</refname>
+ <refpurpose>stop listening for a notification</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+UNLISTEN { <replaceable class="parameter">channel</replaceable> | * }
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>UNLISTEN</command> is used to remove an existing
+ registration for <command>NOTIFY</command> events.
+ <command>UNLISTEN</command> cancels any existing registration of
+ the current <productname>PostgreSQL</productname> session as a
+ listener on the notification channel named <replaceable
+ class="parameter">channel</replaceable>. The special wildcard
+ <literal>*</literal> cancels all listener registrations for the
+ current session.
+ </para>
+
+ <para>
+ <xref linkend="sql-notify"/>
+ contains a more extensive
+ discussion of the use of <command>LISTEN</command> and
+ <command>NOTIFY</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">channel</replaceable></term>
+ <listitem>
+ <para>
+ Name of a notification channel (any identifier).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>*</literal></term>
+ <listitem>
+ <para>
+ All current listen registrations for this session are cleared.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ You can unlisten something you were not listening for; no warning or error
+ will appear.
+ </para>
+
+ <para>
+ At the end of each session, <command>UNLISTEN *</command> is
+ automatically executed.
+ </para>
+
+ <para>
+ A transaction that has executed <command>UNLISTEN</command> cannot be
+ prepared for two-phase commit.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To make a registration:
+
+<programlisting>
+LISTEN virtual;
+NOTIFY virtual;
+Asynchronous notification "virtual" received from server process with PID 8448.
+</programlisting>
+ </para>
+
+ <para>
+ Once <command>UNLISTEN</command> has been executed, further <command>NOTIFY</command>
+ messages will be ignored:
+
+<programlisting>
+UNLISTEN virtual;
+NOTIFY virtual;
+-- no NOTIFY event is received
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>UNLISTEN</command> command in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-listen"/></member>
+ <member><xref linkend="sql-notify"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml
new file mode 100644
index 0000000..2ab24b0
--- /dev/null
+++ b/doc/src/sgml/ref/update.sgml
@@ -0,0 +1,475 @@
+<!--
+doc/src/sgml/ref/update.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-update">
+ <indexterm zone="sql-update">
+ <primary>UPDATE</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>UPDATE</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>UPDATE</refname>
+ <refpurpose>update rows of a table</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+[ WITH [ RECURSIVE ] <replaceable class="parameter">with_query</replaceable> [, ...] ]
+UPDATE [ ONLY ] <replaceable class="parameter">table_name</replaceable> [ * ] [ [ AS ] <replaceable class="parameter">alias</replaceable> ]
+ SET { <replaceable class="parameter">column_name</replaceable> = { <replaceable class="parameter">expression</replaceable> | DEFAULT } |
+ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) = [ ROW ] ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) |
+ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) = ( <replaceable class="parameter">sub-SELECT</replaceable> )
+ } [, ...]
+ [ FROM <replaceable class="parameter">from_item</replaceable> [, ...] ]
+ [ WHERE <replaceable class="parameter">condition</replaceable> | WHERE CURRENT OF <replaceable class="parameter">cursor_name</replaceable> ]
+ [ RETURNING * | <replaceable class="parameter">output_expression</replaceable> [ [ AS ] <replaceable class="parameter">output_name</replaceable> ] [, ...] ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>UPDATE</command> changes the values of the specified
+ columns in all rows that satisfy the condition. Only the columns to
+ be modified need be mentioned in the <literal>SET</literal> clause;
+ columns not explicitly modified retain their previous values.
+ </para>
+
+ <para>
+ There are two ways to modify a table using information contained in
+ other tables in the database: using sub-selects, or specifying
+ additional tables in the <literal>FROM</literal> clause. Which
+ technique is more appropriate depends on the specific
+ circumstances.
+ </para>
+
+ <para>
+ The optional <literal>RETURNING</literal> clause causes <command>UPDATE</command>
+ to compute and return value(s) based on each row actually updated.
+ Any expression using the table's columns, and/or columns of other
+ tables mentioned in <literal>FROM</literal>, can be computed.
+ The new (post-update) values of the table's columns are used.
+ The syntax of the <literal>RETURNING</literal> list is identical to that of the
+ output list of <command>SELECT</command>.
+ </para>
+
+ <para>
+ You must have the <literal>UPDATE</literal> privilege on the table,
+ or at least on the column(s) that are listed to be updated.
+ You must also have the <literal>SELECT</literal>
+ privilege on any column whose values are read in the
+ <replaceable class="parameter">expressions</replaceable> or
+ <replaceable class="parameter">condition</replaceable>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">with_query</replaceable></term>
+ <listitem>
+ <para>
+ The <literal>WITH</literal> clause allows you to specify one or more
+ subqueries that can be referenced by name in the <command>UPDATE</command>
+ query. See <xref linkend="queries-with"/> and <xref linkend="sql-select"/>
+ for details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table to update.
+ If <literal>ONLY</literal> is specified before the table name, matching rows
+ are updated in the named table only. If <literal>ONLY</literal> is not
+ specified, matching rows are also updated in any tables inheriting from
+ the named table. Optionally, <literal>*</literal> can be specified after the
+ table name to explicitly indicate that descendant tables are included.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">alias</replaceable></term>
+ <listitem>
+ <para>
+ A substitute name for the target table. When an alias is
+ provided, it completely hides the actual name of the table. For
+ example, given <literal>UPDATE foo AS f</literal>, the remainder of the
+ <command>UPDATE</command> statement must refer to this table as
+ <literal>f</literal> not <literal>foo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a column in the table named by <replaceable
+ class="parameter">table_name</replaceable>.
+ The column name can be qualified with a subfield name or array
+ subscript, if needed. Do not include the table's name in the
+ specification of a target column &mdash; for example,
+ <literal>UPDATE table_name SET table_name.col = 1</literal> is invalid.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression to assign to the column. The expression can use the
+ old values of this and other columns in the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DEFAULT</literal></term>
+ <listitem>
+ <para>
+ Set the column to its default value (which will be NULL if no specific
+ default expression has been assigned to it). An identity column will be
+ set to a new value generated by the associated sequence. For a
+ generated column, specifying this is permitted but merely specifies the
+ normal behavior of computing the column from its generation expression.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sub-SELECT</replaceable></term>
+ <listitem>
+ <para>
+ A <literal>SELECT</literal> sub-query that produces as many output columns
+ as are listed in the parenthesized column list preceding it. The
+ sub-query must yield no more than one row when executed. If it
+ yields one row, its column values are assigned to the target columns;
+ if it yields no rows, NULL values are assigned to the target columns.
+ The sub-query can refer to old values of the current row of the table
+ being updated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">from_item</replaceable></term>
+ <listitem>
+ <para>
+ A table expression allowing columns from other tables to appear in
+ the <literal>WHERE</literal> condition and update expressions. This
+ uses the same syntax as the <link
+ linkend="sql-from"><literal>FROM</literal></link> clause of
+ a <command>SELECT</command> statement;
+ for example, an alias for the table name can be specified. Do not
+ repeat the target table as a <replaceable>from_item</replaceable>
+ unless you intend a self-join (in which case it must appear with
+ an alias in the <replaceable>from_item</replaceable>).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">condition</replaceable></term>
+ <listitem>
+ <para>
+ An expression that returns a value of type <type>boolean</type>.
+ Only rows for which this expression returns <literal>true</literal>
+ will be updated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">cursor_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of the cursor to use in a <literal>WHERE CURRENT OF</literal>
+ condition. The row to be updated is the one most recently fetched
+ from this cursor. The cursor must be a non-grouping
+ query on the <command>UPDATE</command>'s target table.
+ Note that <literal>WHERE CURRENT OF</literal> cannot be
+ specified together with a Boolean condition. See
+ <xref linkend="sql-declare"/>
+ for more information about using cursors with
+ <literal>WHERE CURRENT OF</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression to be computed and returned by the <command>UPDATE</command>
+ command after each row is updated. The expression can use any
+ column names of the table named by <replaceable class="parameter">table_name</replaceable>
+ or table(s) listed in <literal>FROM</literal>.
+ Write <literal>*</literal> to return all columns.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">output_name</replaceable></term>
+ <listitem>
+ <para>
+ A name to use for a returned column.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ On successful completion, an <command>UPDATE</command> command returns a command
+ tag of the form
+<screen>
+UPDATE <replaceable class="parameter">count</replaceable>
+</screen>
+ The <replaceable class="parameter">count</replaceable> is the number
+ of rows updated, including matched rows whose values did not change.
+ Note that the number may be less than the number of rows that matched
+ the <replaceable class="parameter">condition</replaceable> when
+ updates were suppressed by a <literal>BEFORE UPDATE</literal> trigger. If
+ <replaceable class="parameter">count</replaceable> is 0, no rows were
+ updated by the query (this is not considered an error).
+ </para>
+
+ <para>
+ If the <command>UPDATE</command> command contains a <literal>RETURNING</literal>
+ clause, the result will be similar to that of a <command>SELECT</command>
+ statement containing the columns and values defined in the
+ <literal>RETURNING</literal> list, computed over the row(s) updated by the
+ command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ When a <literal>FROM</literal> clause is present, what essentially happens
+ is that the target table is joined to the tables mentioned in the
+ <replaceable>from_item</replaceable> list, and each output row of the join
+ represents an update operation for the target table. When using
+ <literal>FROM</literal> you should ensure that the join
+ produces at most one output row for each row to be modified. In
+ other words, a target row shouldn't join to more than one row from
+ the other table(s). If it does, then only one of the join rows
+ will be used to update the target row, but which one will be used
+ is not readily predictable.
+ </para>
+
+ <para>
+ Because of this indeterminacy, referencing other tables only within
+ sub-selects is safer, though often harder to read and slower than
+ using a join.
+ </para>
+
+ <para>
+ In the case of a partitioned table, updating a row might cause it to no
+ longer satisfy the partition constraint of the containing partition. In that
+ case, if there is some other partition in the partition tree for which this
+ row satisfies its partition constraint, then the row is moved to that
+ partition. If there is no such partition, an error will occur. Behind the
+ scenes, the row movement is actually a <command>DELETE</command> and
+ <command>INSERT</command> operation.
+ </para>
+
+ <para>
+ There is a possibility that a concurrent <command>UPDATE</command> or
+ <command>DELETE</command> on the row being moved will get a serialization
+ failure error. Suppose session 1 is performing an <command>UPDATE</command>
+ on a partition key, and meanwhile a concurrent session 2 for which this
+ row is visible performs an <command>UPDATE</command> or
+ <command>DELETE</command> operation on this row. In such case,
+ session 2's <command>UPDATE</command> or <command>DELETE</command> will
+ detect the row movement and raise a serialization failure error (which
+ always returns with an SQLSTATE code '40001'). Applications may wish to
+ retry the transaction if this occurs. In the usual case where the table
+ is not partitioned, or where there is no row movement, session 2 would
+ have identified the newly updated row and carried out the
+ <command>UPDATE</command>/<command>DELETE</command> on this new row
+ version.
+ </para>
+
+ <para>
+ Note that while rows can be moved from local partitions to a foreign-table
+ partition (provided the foreign data wrapper supports tuple routing), they
+ cannot be moved from a foreign-table partition to another partition.
+ </para>
+
+ <para>
+ An attempt of moving a row from one partition to another will fail if a
+ foreign key is found to directly reference an ancestor of the source
+ partition that is not the same as the ancestor that's mentioned in the
+ <command>UPDATE</command> query.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ Change the word <literal>Drama</literal> to <literal>Dramatic</literal> in the
+ column <structfield>kind</structfield> of the table <structname>films</structname>:
+
+<programlisting>
+UPDATE films SET kind = 'Dramatic' WHERE kind = 'Drama';
+</programlisting>
+ </para>
+
+ <para>
+ Adjust temperature entries and reset precipitation to its default
+ value in one row of the table <structname>weather</structname>:
+
+<programlisting>
+UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
+ WHERE city = 'San Francisco' AND date = '2003-07-03';
+</programlisting>
+ </para>
+
+ <para>
+ Perform the same operation and return the updated entries:
+
+<programlisting>
+UPDATE weather SET temp_lo = temp_lo+1, temp_hi = temp_lo+15, prcp = DEFAULT
+ WHERE city = 'San Francisco' AND date = '2003-07-03'
+ RETURNING temp_lo, temp_hi, prcp;
+</programlisting>
+ </para>
+
+ <para>
+ Use the alternative column-list syntax to do the same update:
+<programlisting>
+UPDATE weather SET (temp_lo, temp_hi, prcp) = (temp_lo+1, temp_lo+15, DEFAULT)
+ WHERE city = 'San Francisco' AND date = '2003-07-03';
+</programlisting>
+ </para>
+
+ <para>
+ Increment the sales count of the salesperson who manages the
+ account for Acme Corporation, using the <literal>FROM</literal>
+ clause syntax:
+<programlisting>
+UPDATE employees SET sales_count = sales_count + 1 FROM accounts
+ WHERE accounts.name = 'Acme Corporation'
+ AND employees.id = accounts.sales_person;
+</programlisting>
+ </para>
+
+ <para>
+ Perform the same operation, using a sub-select in the
+ <literal>WHERE</literal> clause:
+<programlisting>
+UPDATE employees SET sales_count = sales_count + 1 WHERE id =
+ (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');
+</programlisting>
+ </para>
+
+ <para>
+ Update contact names in an accounts table to match the currently assigned
+ salespeople:
+<programlisting>
+UPDATE accounts SET (contact_first_name, contact_last_name) =
+ (SELECT first_name, last_name FROM employees
+ WHERE employees.id = accounts.sales_person);
+</programlisting>
+ A similar result could be accomplished with a join:
+<programlisting>
+UPDATE accounts SET contact_first_name = first_name,
+ contact_last_name = last_name
+ FROM employees WHERE employees.id = accounts.sales_person;
+</programlisting>
+ However, the second query may give unexpected results
+ if <structname>employees</structname>.<structfield>id</structfield> is not a unique key, whereas
+ the first query is guaranteed to raise an error if there are multiple
+ <structfield>id</structfield> matches. Also, if there is no match for a particular
+ <structname>accounts</structname>.<structfield>sales_person</structfield> entry, the first query
+ will set the corresponding name fields to NULL, whereas the second query
+ will not update that row at all.
+ </para>
+
+ <para>
+ Update statistics in a summary table to match the current data:
+<programlisting>
+UPDATE summary s SET (sum_x, sum_y, avg_x, avg_y) =
+ (SELECT sum(x), sum(y), avg(x), avg(y) FROM data d
+ WHERE d.group_id = s.group_id);
+</programlisting>
+ </para>
+
+ <para>
+ Attempt to insert a new stock item along with the quantity of stock. If
+ the item already exists, instead update the stock count of the existing
+ item. To do this without failing the entire transaction, use savepoints:
+<programlisting>
+BEGIN;
+-- other operations
+SAVEPOINT sp1;
+INSERT INTO wines VALUES('Chateau Lafite 2003', '24');
+-- Assume the above fails because of a unique key violation,
+-- so now we issue these commands:
+ROLLBACK TO sp1;
+UPDATE wines SET stock = stock + 24 WHERE winename = 'Chateau Lafite 2003';
+-- continue with other operations, and eventually
+COMMIT;
+</programlisting>
+ </para>
+
+ <para>
+ Change the <structfield>kind</structfield> column of the table
+ <structname>films</structname> in the row on which the cursor
+ <literal>c_films</literal> is currently positioned:
+<programlisting>
+UPDATE films SET kind = 'Dramatic' WHERE CURRENT OF c_films;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ This command conforms to the <acronym>SQL</acronym> standard, except
+ that the <literal>FROM</literal> and <literal>RETURNING</literal> clauses
+ are <productname>PostgreSQL</productname> extensions, as is the ability
+ to use <literal>WITH</literal> with <command>UPDATE</command>.
+ </para>
+
+ <para>
+ Some other database systems offer a <literal>FROM</literal> option in which
+ the target table is supposed to be listed again within <literal>FROM</literal>.
+ That is not how <productname>PostgreSQL</productname> interprets
+ <literal>FROM</literal>. Be careful when porting applications that use this
+ extension.
+ </para>
+
+ <para>
+ According to the standard, the source value for a parenthesized sub-list of
+ target column names can be any row-valued expression yielding the correct
+ number of columns. <productname>PostgreSQL</productname> only allows the
+ source value to be a <link linkend="sql-syntax-row-constructors">row
+ constructor</link> or a sub-<literal>SELECT</literal>. An individual column's
+ updated value can be specified as <literal>DEFAULT</literal> in the
+ row-constructor case, but not inside a sub-<literal>SELECT</literal>.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml
new file mode 100644
index 0000000..c582021
--- /dev/null
+++ b/doc/src/sgml/ref/vacuum.sgml
@@ -0,0 +1,453 @@
+<!--
+doc/src/sgml/ref/vacuum.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-vacuum">
+ <indexterm zone="sql-vacuum">
+ <primary>VACUUM</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>VACUUM</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>VACUUM</refname>
+ <refpurpose>garbage-collect and optionally analyze a database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+VACUUM [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
+VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="parameter">table_and_columns</replaceable> [, ...] ]
+
+<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
+
+ FULL [ <replaceable class="parameter">boolean</replaceable> ]
+ FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
+ VERBOSE [ <replaceable class="parameter">boolean</replaceable> ]
+ ANALYZE [ <replaceable class="parameter">boolean</replaceable> ]
+ DISABLE_PAGE_SKIPPING [ <replaceable class="parameter">boolean</replaceable> ]
+ SKIP_LOCKED [ <replaceable class="parameter">boolean</replaceable> ]
+ INDEX_CLEANUP { AUTO | ON | OFF }
+ PROCESS_TOAST [ <replaceable class="parameter">boolean</replaceable> ]
+ TRUNCATE [ <replaceable class="parameter">boolean</replaceable> ]
+ PARALLEL <replaceable class="parameter">integer</replaceable>
+
+<phrase>and <replaceable class="parameter">table_and_columns</replaceable> is:</phrase>
+
+ <replaceable class="parameter">table_name</replaceable> [ ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>VACUUM</command> reclaims storage occupied by dead tuples.
+ In normal <productname>PostgreSQL</productname> operation, tuples that
+ are deleted or obsoleted by an update are not physically removed from
+ their table; they remain present until a <command>VACUUM</command> is
+ done. Therefore it's necessary to do <command>VACUUM</command>
+ periodically, especially on frequently-updated tables.
+ </para>
+
+ <para>
+ Without a <replaceable class="parameter">table_and_columns</replaceable>
+ list, <command>VACUUM</command> processes every table and materialized view
+ in the current database that the current user has permission to vacuum.
+ With a list, <command>VACUUM</command> processes only those table(s).
+ </para>
+
+ <para>
+ <command>VACUUM ANALYZE</command> performs a <command>VACUUM</command>
+ and then an <command>ANALYZE</command> for each selected table. This
+ is a handy combination form for routine maintenance scripts. See
+ <xref linkend="sql-analyze"/>
+ for more details about its processing.
+ </para>
+
+ <para>
+ Plain <command>VACUUM</command> (without <literal>FULL</literal>) simply reclaims
+ space and makes it
+ available for re-use. This form of the command can operate in parallel
+ with normal reading and writing of the table, as an exclusive lock
+ is not obtained. However, extra space is not returned to the operating
+ system (in most cases); it's just kept available for re-use within the
+ same table. It also allows us to leverage multiple CPUs in order to process
+ indexes. This feature is known as <firstterm>parallel vacuum</firstterm>.
+ To disable this feature, one can use <literal>PARALLEL</literal> option and
+ specify parallel workers as zero. <command>VACUUM FULL</command> rewrites
+ the entire contents of the table into a new disk file with no extra space,
+ allowing unused space to be returned to the operating system. This form is
+ much slower and requires an <literal>ACCESS EXCLUSIVE</literal> lock on
+ each table while it is being processed.
+ </para>
+
+ <para>
+ When the option list is surrounded by parentheses, the options can be
+ written in any order. Without parentheses, options must be specified
+ in exactly the order shown above.
+ The parenthesized syntax was added in
+ <productname>PostgreSQL</productname> 9.0; the unparenthesized
+ syntax is deprecated.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>FULL</literal></term>
+ <listitem>
+ <para>
+ Selects <quote>full</quote> vacuum, which can reclaim more
+ space, but takes much longer and exclusively locks the table.
+ This method also requires extra disk space, since it writes a
+ new copy of the table and doesn't release the old copy until
+ the operation is complete. Usually this should only be used when a
+ significant amount of space needs to be reclaimed from within the table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FREEZE</literal></term>
+ <listitem>
+ <para>
+ Selects aggressive <quote>freezing</quote> of tuples.
+ Specifying <literal>FREEZE</literal> is equivalent to performing
+ <command>VACUUM</command> with the
+ <xref linkend="guc-vacuum-freeze-min-age"/> and
+ <xref linkend="guc-vacuum-freeze-table-age"/> parameters
+ set to zero. Aggressive freezing is always performed when the
+ table is rewritten, so this option is redundant when <literal>FULL</literal>
+ is specified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>VERBOSE</literal></term>
+ <listitem>
+ <para>
+ Prints a detailed vacuum activity report for each table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ANALYZE</literal></term>
+ <listitem>
+ <para>
+ Updates statistics used by the planner to determine the most
+ efficient way to execute a query.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DISABLE_PAGE_SKIPPING</literal></term>
+ <listitem>
+ <para>
+ Normally, <command>VACUUM</command> will skip pages based on the <link
+ linkend="vacuum-for-visibility-map">visibility map</link>. Pages where
+ all tuples are known to be frozen can always be skipped, and those
+ where all tuples are known to be visible to all transactions may be
+ skipped except when performing an aggressive vacuum. Furthermore,
+ except when performing an aggressive vacuum, some pages may be skipped
+ in order to avoid waiting for other sessions to finish using them.
+ This option disables all page-skipping behavior, and is intended to
+ be used only when the contents of the visibility map are
+ suspect, which should happen only if there is a hardware or software
+ issue causing database corruption.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SKIP_LOCKED</literal></term>
+ <listitem>
+ <para>
+ Specifies that <command>VACUUM</command> should not wait for any
+ conflicting locks to be released when beginning work on a relation:
+ if a relation cannot be locked immediately without waiting, the relation
+ is skipped. Note that even with this option,
+ <command>VACUUM</command> may still block when opening the relation's
+ indexes. Additionally, <command>VACUUM ANALYZE</command> may still
+ block when acquiring sample rows from partitions, table inheritance
+ children, and some types of foreign tables. Also, while
+ <command>VACUUM</command> ordinarily processes all partitions of
+ specified partitioned tables, this option will cause
+ <command>VACUUM</command> to skip all partitions if there is a
+ conflicting lock on the partitioned table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>INDEX_CLEANUP</literal></term>
+ <listitem>
+ <para>
+ Normally, <command>VACUUM</command> will skip index vacuuming
+ when there are very few dead tuples in the table. The cost of
+ processing all of the table's indexes is expected to greatly
+ exceed the benefit of removing dead index tuples when this
+ happens. This option can be used to force
+ <command>VACUUM</command> to process indexes when there are more
+ than zero dead tuples. The default is <literal>AUTO</literal>,
+ which allows <command>VACUUM</command> to skip index vacuuming
+ when appropriate. If <literal>INDEX_CLEANUP</literal> is set to
+ <literal>ON</literal>, <command>VACUUM</command> will
+ conservatively remove all dead tuples from indexes. This may be
+ useful for backwards compatibility with earlier releases of
+ <productname>PostgreSQL</productname> where this was the
+ standard behavior.
+ </para>
+ <para>
+ <literal>INDEX_CLEANUP</literal> can also be set to
+ <literal>OFF</literal> to force <command>VACUUM</command> to
+ <emphasis>always</emphasis> skip index vacuuming, even when
+ there are many dead tuples in the table. This may be useful
+ when it is necessary to make <command>VACUUM</command> run as
+ quickly as possible to avoid imminent transaction ID wraparound
+ (see <xref linkend="vacuum-for-wraparound"/>). However, the
+ wraparound failsafe mechanism controlled by <xref
+ linkend="guc-vacuum-failsafe-age"/> will generally trigger
+ automatically to avoid transaction ID wraparound failure, and
+ should be preferred. If index cleanup is not performed
+ regularly, performance may suffer, because as the table is
+ modified indexes will accumulate dead tuples and the table
+ itself will accumulate dead line pointers that cannot be removed
+ until index cleanup is completed.
+ </para>
+ <para>
+ This option has no effect for tables that have no index and is
+ ignored if the <literal>FULL</literal> option is used. It also
+ has no effect on the transaction ID wraparound failsafe
+ mechanism. When triggered it will skip index vacuuming, even
+ when <literal>INDEX_CLEANUP</literal> is set to
+ <literal>ON</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PROCESS_TOAST</literal></term>
+ <listitem>
+ <para>
+ Specifies that <command>VACUUM</command> should attempt to process the
+ corresponding <literal>TOAST</literal> table for each relation, if one
+ exists. This is usually the desired behavior and is the default.
+ Setting this option to false may be useful when it is only necessary to
+ vacuum the main relation. This option is required when the
+ <literal>FULL</literal> option is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRUNCATE</literal></term>
+ <listitem>
+ <para>
+ Specifies that <command>VACUUM</command> should attempt to
+ truncate off any empty pages at the end of the table and allow
+ the disk space for the truncated pages to be returned to
+ the operating system. This is normally the desired behavior
+ and is the default unless the <literal>vacuum_truncate</literal>
+ option has been set to false for the table to be vacuumed.
+ Setting this option to false may be useful to avoid
+ <literal>ACCESS EXCLUSIVE</literal> lock on the table that
+ the truncation requires. This option is ignored if the
+ <literal>FULL</literal> option is used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>PARALLEL</literal></term>
+ <listitem>
+ <para>
+ Perform index vacuum and index cleanup phases of <command>VACUUM</command>
+ in parallel using <replaceable class="parameter">integer</replaceable>
+ background workers (for the details of each vacuum phase, please
+ refer to <xref linkend="vacuum-phases"/>). The number of workers used
+ to perform the operation is equal to the number of indexes on the
+ relation that support parallel vacuum which is limited by the number of
+ workers specified with <literal>PARALLEL</literal> option if any which is
+ further limited by <xref linkend="guc-max-parallel-maintenance-workers"/>.
+ An index can participate in parallel vacuum if and only if the size of the
+ index is more than <xref linkend="guc-min-parallel-index-scan-size"/>.
+ Please note that it is not guaranteed that the number of parallel workers
+ specified in <replaceable class="parameter">integer</replaceable> will be
+ used during execution. It is possible for a vacuum to run with fewer
+ workers than specified, or even with no workers at all. Only one worker
+ can be used per index. So parallel workers are launched only when there
+ are at least <literal>2</literal> indexes in the table. Workers for
+ vacuum are launched before the start of each phase and exit at the end of
+ the phase. These behaviors might change in a future release. This
+ option can't be used with the <literal>FULL</literal> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">boolean</replaceable></term>
+ <listitem>
+ <para>
+ Specifies whether the selected option should be turned on or off.
+ You can write <literal>TRUE</literal>, <literal>ON</literal>, or
+ <literal>1</literal> to enable the option, and <literal>FALSE</literal>,
+ <literal>OFF</literal>, or <literal>0</literal> to disable it. The
+ <replaceable class="parameter">boolean</replaceable> value can also
+ be omitted, in which case <literal>TRUE</literal> is assumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">integer</replaceable></term>
+ <listitem>
+ <para>
+ Specifies a non-negative integer value passed to the selected option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">table_name</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of a specific table or
+ materialized view to vacuum. If the specified table is a partitioned
+ table, all of its leaf partitions are vacuumed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">column_name</replaceable></term>
+ <listitem>
+ <para>
+ The name of a specific column to analyze. Defaults to all columns.
+ If a column list is specified, <literal>ANALYZE</literal> must also be
+ specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Outputs</title>
+
+ <para>
+ When <literal>VERBOSE</literal> is specified, <command>VACUUM</command> emits
+ progress messages to indicate which table is currently being
+ processed. Various statistics about the tables are printed as well.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ To vacuum a table, one must ordinarily be the table's owner or a
+ superuser. However, database owners are allowed to
+ vacuum all tables in their databases, except shared catalogs.
+ (The restriction for shared catalogs means that a true database-wide
+ <command>VACUUM</command> can only be performed by a superuser.)
+ <command>VACUUM</command> will skip over any tables that the calling user
+ does not have permission to vacuum.
+ </para>
+
+ <para>
+ <command>VACUUM</command> cannot be executed inside a transaction block.
+ </para>
+
+ <para>
+ For tables with <acronym>GIN</acronym> indexes, <command>VACUUM</command> (in
+ any form) also completes any pending index insertions, by moving pending
+ index entries to the appropriate places in the main <acronym>GIN</acronym> index
+ structure. See <xref linkend="gin-fast-update"/> for details.
+ </para>
+
+ <para>
+ We recommend that all databases be vacuumed regularly in
+ order to remove dead rows. <productname>PostgreSQL</productname> includes
+ an <quote>autovacuum</quote> facility which can automate routine vacuum
+ maintenance. For more information about automatic and manual vacuuming,
+ see <xref linkend="routine-vacuuming"/>.
+ </para>
+
+ <para>
+ The <option>FULL</option> option is not recommended for routine use,
+ but might be useful in special cases. An example is when you have deleted
+ or updated most of the rows in a table and would like the table to
+ physically shrink to occupy less disk space and allow faster table
+ scans. <command>VACUUM FULL</command> will usually shrink the table
+ more than a plain <command>VACUUM</command> would.
+ </para>
+
+ <para>
+ The <option>PARALLEL</option> option is used only for vacuum purposes.
+ If this option is specified with the <option>ANALYZE</option> option,
+ it does not affect <option>ANALYZE</option>.
+ </para>
+
+ <para>
+ <command>VACUUM</command> causes a substantial increase in I/O traffic,
+ which might cause poor performance for other active sessions. Therefore,
+ it is sometimes advisable to use the cost-based vacuum delay feature. For
+ parallel vacuum, each worker sleeps in proportion to the work done by that
+ worker. See <xref linkend="runtime-config-resource-vacuum-cost"/> for
+ details.
+ </para>
+
+ <para>
+ Each backend running <command>VACUUM</command> without the
+ <literal>FULL</literal> option will report its progress in the
+ <structname>pg_stat_progress_vacuum</structname> view. Backends running
+ <command>VACUUM FULL</command> will instead report their progress in the
+ <structname>pg_stat_progress_cluster</structname> view. See
+ <xref linkend="vacuum-progress-reporting"/> and
+ <xref linkend="cluster-progress-reporting"/> for details.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To clean a single table <literal>onek</literal>, analyze it for
+ the optimizer and print a detailed vacuum activity report:
+
+<programlisting>
+VACUUM (VERBOSE, ANALYZE) onek;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para>
+ There is no <command>VACUUM</command> statement in the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="app-vacuumdb"/></member>
+ <member><xref linkend="runtime-config-resource-vacuum-cost"/></member>
+ <member><xref linkend="autovacuum"/></member>
+ <member><xref linkend="vacuum-progress-reporting"/></member>
+ <member><xref linkend="cluster-progress-reporting"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
new file mode 100644
index 0000000..956c0f0
--- /dev/null
+++ b/doc/src/sgml/ref/vacuumdb.sgml
@@ -0,0 +1,632 @@
+<!--
+doc/src/sgml/ref/vacuumdb.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="app-vacuumdb">
+ <indexterm zone="app-vacuumdb">
+ <primary>vacuumdb</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>vacuumdb</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>vacuumdb</refname>
+ <refpurpose>garbage-collect and analyze a <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>vacuumdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>-t</option></arg>
+ <arg choice="plain"><option>--table</option></arg>
+ </group>
+ <replaceable>table</replaceable>
+ <arg choice="opt">( <replaceable class="parameter">column</replaceable> [,...] )</arg>
+ </arg>
+ </arg>
+
+ <arg choice="opt"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+
+ <cmdsynopsis>
+ <command>vacuumdb</command>
+ <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
+ <arg rep="repeat"><replaceable>option</replaceable></arg>
+ <group choice="plain">
+ <arg choice="plain"><option>-a</option></arg>
+ <arg choice="plain"><option>--all</option></arg>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>vacuumdb</application> is a utility for cleaning a
+ <productname>PostgreSQL</productname> database.
+ <application>vacuumdb</application> will also generate internal statistics
+ used by the <productname>PostgreSQL</productname> query optimizer.
+ </para>
+
+ <para>
+ <application>vacuumdb</application> is a wrapper around the SQL
+ command <link linkend="sql-vacuum"><command>VACUUM</command></link>.
+ There is no effective difference between vacuuming and analyzing
+ databases via this utility and via other methods for accessing the
+ server.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>vacuumdb</application> accepts the following command-line arguments:
+ <variablelist>
+ <varlistentry>
+ <term><option>-a</option></term>
+ <term><option>--all</option></term>
+ <listitem>
+ <para>
+ Vacuum all databases.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option><optional>-d</optional> <replaceable class="parameter">dbname</replaceable></option></term>
+ <term><option><optional>--dbname=</optional><replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to be cleaned or analyzed,
+ when <option>-a</option>/<option>--all</option> is not used.
+ If this is not specified, the database name is read
+ from the environment variable <envar>PGDATABASE</envar>. If
+ that is not set, the user name specified for the connection is
+ used. The <replaceable>dbname</replaceable> can be a <link
+ linkend="libpq-connstring">connection string</link>. If so,
+ connection string parameters will override any conflicting command
+ line options.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--disable-page-skipping</option></term>
+ <listitem>
+ <para>
+ Disable skipping pages based on the contents of the visibility map.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 9.6 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-e</option></term>
+ <term><option>--echo</option></term>
+ <listitem>
+ <para>
+ Echo the commands that <application>vacuumdb</application> generates
+ and sends to the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-f</option></term>
+ <term><option>--full</option></term>
+ <listitem>
+ <para>
+ Perform <quote>full</quote> vacuuming.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-F</option></term>
+ <term><option>--freeze</option></term>
+ <listitem>
+ <para>
+ Aggressively <quote>freeze</quote> tuples.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--force-index-cleanup</option></term>
+ <listitem>
+ <para>
+ Always remove index entries pointing to dead tuples.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 12 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-j <replaceable class="parameter">njobs</replaceable></option></term>
+ <term><option>--jobs=<replaceable class="parameter">njobs</replaceable></option></term>
+ <listitem>
+ <para>
+ Execute the vacuum or analyze commands in parallel by running
+ <replaceable class="parameter">njobs</replaceable>
+ commands simultaneously. This option may reduce the processing time
+ but it also increases the load on the database server.
+ </para>
+ <para>
+ <application>vacuumdb</application> will open
+ <replaceable class="parameter">njobs</replaceable> connections to the
+ database, so make sure your <xref linkend="guc-max-connections"/>
+ setting is high enough to accommodate all connections.
+ </para>
+ <para>
+ Note that using this mode together with the <option>-f</option>
+ (<literal>FULL</literal>) option might cause deadlock failures if
+ certain system catalogs are processed in parallel.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--min-mxid-age <replaceable class="parameter">mxid_age</replaceable></option></term>
+ <listitem>
+ <para>
+ Only execute the vacuum or analyze commands on tables with a multixact
+ ID age of at least <replaceable class="parameter">mxid_age</replaceable>.
+ This setting is useful for prioritizing tables to process to prevent
+ multixact ID wraparound (see
+ <xref linkend="vacuum-for-multixact-wraparound"/>).
+ </para>
+ <para>
+ For the purposes of this option, the multixact ID age of a relation is
+ the greatest of the ages of the main relation and its associated
+ <acronym>TOAST</acronym> table, if one exists. Since the commands
+ issued by <application>vacuumdb</application> will also process the
+ <acronym>TOAST</acronym> table for the relation if necessary, it does
+ not need to be considered separately.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 9.6 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--min-xid-age <replaceable class="parameter">xid_age</replaceable></option></term>
+ <listitem>
+ <para>
+ Only execute the vacuum or analyze commands on tables with a
+ transaction ID age of at least
+ <replaceable class="parameter">xid_age</replaceable>. This setting
+ is useful for prioritizing tables to process to prevent transaction
+ ID wraparound (see <xref linkend="vacuum-for-wraparound"/>).
+ </para>
+ <para>
+ For the purposes of this option, the transaction ID age of a relation
+ is the greatest of the ages of the main relation and its associated
+ <acronym>TOAST</acronym> table, if one exists. Since the commands
+ issued by <application>vacuumdb</application> will also process the
+ <acronym>TOAST</acronym> table for the relation if necessary, it does
+ not need to be considered separately.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 9.6 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-index-cleanup</option></term>
+ <listitem>
+ <para>
+ Do not remove index entries pointing to dead tuples.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 12 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-process-toast</option></term>
+ <listitem>
+ <para>
+ Skip the TOAST table associated with the table to vacuum, if any.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 14 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--no-truncate</option></term>
+ <listitem>
+ <para>
+ Do not truncate empty pages at the end of the table.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 12 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-P <replaceable class="parameter">parallel_workers</replaceable></option></term>
+ <term><option>--parallel=<replaceable class="parameter">parallel_workers</replaceable></option></term>
+ <listitem>
+ <para>
+ Specify the number of parallel workers for <firstterm>parallel vacuum</firstterm>.
+ This allows the vacuum to leverage multiple CPUs to process indexes.
+ See <xref linkend="sql-vacuum"/>.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 13 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-q</option></term>
+ <term><option>--quiet</option></term>
+ <listitem>
+ <para>
+ Do not display progress messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--skip-locked</option></term>
+ <listitem>
+ <para>
+ Skip relations that cannot be immediately locked for processing.
+ </para>
+ <note>
+ <para>
+ This option is only available for servers running
+ <productname>PostgreSQL</productname> 12 and later.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-t <replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</option></term>
+ <term><option>--table=<replaceable class="parameter">table</replaceable> [ (<replaceable class="parameter">column</replaceable> [,...]) ]</option></term>
+ <listitem>
+ <para>
+ Clean or analyze <replaceable class="parameter">table</replaceable> only.
+ Column names can be specified only in conjunction with
+ the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</option> switches.
+ </para>
+ <tip>
+ <para>
+ If you specify columns, you probably have to escape the parentheses
+ from the shell. (See examples below.)
+ </para>
+ </tip>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>
+ Print detailed information during processing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>vacuumdb</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-z</option></term>
+ <term><option>--analyze</option></term>
+ <listitem>
+ <para>
+ Also calculate statistics for use by the optimizer.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-Z</option></term>
+ <term><option>--analyze-only</option></term>
+ <listitem>
+ <para>
+ Only calculate statistics for use by the optimizer (no vacuum).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--analyze-in-stages</option></term>
+ <listitem>
+ <para>
+ Only calculate statistics for use by the optimizer (no vacuum),
+ like <option>--analyze-only</option>. Run three
+ stages of analyze; the first stage uses the lowest possible statistics
+ target (see <xref linkend="guc-default-statistics-target"/>)
+ to produce usable statistics faster, and subsequent stages build the
+ full statistics.
+ </para>
+
+ <para>
+ This option is only useful to analyze a database that currently has
+ no statistics or has wholly incorrect ones, such as if it is newly
+ populated from a restored dump or by <command>pg_upgrade</command>.
+ Be aware that running with this option in a database with existing
+ statistics may cause the query optimizer choices to become
+ transiently worse due to the low statistics targets of the early
+ stages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>vacuumdb</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ <application>vacuumdb</application> also accepts
+ the following command-line arguments for connection parameters:
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the host name of the machine on which the server
+ is running. If the value begins with a slash, it is used
+ as the directory for the Unix domain socket.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable class="parameter">port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the TCP port or local Unix domain socket file
+ extension on which the server
+ is listening for connections.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable class="parameter">username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>
+ User name to connect as.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires
+ password authentication and a password is not available by
+ other means such as a <filename>.pgpass</filename> file, the
+ connection attempt will fail. This option can be useful in
+ batch jobs and scripts where no user is present to enter a
+ password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>vacuumdb</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>vacuumdb</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>vacuumdb</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--maintenance-db=<replaceable class="parameter">dbname</replaceable></option></term>
+ <listitem>
+ <para>
+ Specifies the name of the database to connect to to discover which
+ databases should be vacuumed,
+ when <option>-a</option>/<option>--all</option> is used.
+ If not specified, the <literal>postgres</literal> database will be used,
+ or if that does not exist, <literal>template1</literal> will be used.
+ This can be a <link linkend="libpq-connstring">connection
+ string</link>. If so, connection string parameters will override any
+ conflicting command line options. Also, connection string parameters
+ other than the database name itself will be re-used when connecting
+ to other databases.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGDATABASE</envar></term>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><envar>PG_COLOR</envar></term>
+ <listitem>
+ <para>
+ Specifies whether to use color in diagnostic messages. Possible values
+ are <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Diagnostics</title>
+
+ <para>
+ In case of difficulty, see <xref linkend="sql-vacuum"/>
+ and <xref linkend="app-psql"/> for
+ discussions of potential problems and error messages.
+ The database server must be running at the
+ targeted host. Also, any default connection settings and environment
+ variables used by the <application>libpq</application> front-end
+ library will apply.
+ </para>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>vacuumdb</application> might need to connect several
+ times to the <productname>PostgreSQL</productname> server, asking
+ for a password each time. It is convenient to have a
+ <filename>~/.pgpass</filename> file in such cases. See <xref
+ linkend="libpq-pgpass"/> for more information.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ To clean the database <literal>test</literal>:
+<screen>
+<prompt>$ </prompt><userinput>vacuumdb test</userinput>
+</screen>
+ </para>
+
+ <para>
+ To clean and analyze for the optimizer a database named
+ <literal>bigdb</literal>:
+<screen>
+<prompt>$ </prompt><userinput>vacuumdb --analyze bigdb</userinput>
+</screen>
+ </para>
+
+ <para>
+ To clean a single table
+ <literal>foo</literal> in a database named
+ <literal>xyzzy</literal>, and analyze a single column
+ <literal>bar</literal> of the table for the optimizer:
+<screen>
+<prompt>$ </prompt><userinput>vacuumdb --analyze --verbose --table='foo(bar)' xyzzy</userinput>
+</screen></para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-vacuum"/></member>
+ </simplelist>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/ref/values.sgml b/doc/src/sgml/ref/values.sgml
new file mode 100644
index 0000000..4bf7bfd
--- /dev/null
+++ b/doc/src/sgml/ref/values.sgml
@@ -0,0 +1,251 @@
+<!--
+doc/src/sgml/ref/values.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="sql-values">
+ <indexterm zone="sql-values">
+ <primary>VALUES</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>VALUES</refentrytitle>
+ <manvolnum>7</manvolnum>
+ <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>VALUES</refname>
+ <refpurpose>compute a set of rows</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+VALUES ( <replaceable class="parameter">expression</replaceable> [, ...] ) [, ...]
+ [ ORDER BY <replaceable class="parameter">sort_expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [, ...] ]
+ [ LIMIT { <replaceable class="parameter">count</replaceable> | ALL } ]
+ [ OFFSET <replaceable class="parameter">start</replaceable> [ ROW | ROWS ] ]
+ [ FETCH { FIRST | NEXT } [ <replaceable class="parameter">count</replaceable> ] { ROW | ROWS } ONLY ]
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>VALUES</command> computes a row value or set of row values
+ specified by value expressions. It is most commonly used to generate
+ a <quote>constant table</quote> within a larger command, but it can be
+ used on its own.
+ </para>
+
+ <para>
+ When more than one row is specified, all the rows must have the same
+ number of elements. The data types of the resulting table's columns are
+ determined by combining the explicit or inferred types of the expressions
+ appearing in that column, using the same rules as for <literal>UNION</literal>
+ (see <xref linkend="typeconv-union-case"/>).
+ </para>
+
+ <para>
+ Within larger commands, <command>VALUES</command> is syntactically allowed
+ anywhere that <command>SELECT</command> is. Because it is treated like a
+ <command>SELECT</command> by the grammar, it is possible to use
+ the <literal>ORDER BY</literal>, <literal>LIMIT</literal> (or
+ equivalently <literal>FETCH FIRST</literal>),
+ and <literal>OFFSET</literal> clauses with a
+ <command>VALUES</command> command.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">expression</replaceable></term>
+ <listitem>
+ <para>
+ A constant or expression to compute and insert at the indicated place
+ in the resulting table (set of rows). In a <command>VALUES</command> list
+ appearing at the top level of an <command>INSERT</command>, an
+ <replaceable class="parameter">expression</replaceable> can be replaced
+ by <literal>DEFAULT</literal> to indicate that the destination column's
+ default value should be inserted. <literal>DEFAULT</literal> cannot
+ be used when <command>VALUES</command> appears in other contexts.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">sort_expression</replaceable></term>
+ <listitem>
+ <para>
+ An expression or integer constant indicating how to sort the result
+ rows. This expression can refer to the columns of the
+ <command>VALUES</command> result as <literal>column1</literal>, <literal>column2</literal>,
+ etc. For more details see
+ <xref linkend="sql-orderby"/>
+ in the <xref linkend="sql-select"/> documentation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">operator</replaceable></term>
+ <listitem>
+ <para>
+ A sorting operator. For details see
+ <xref linkend="sql-orderby"/>
+ in the <xref linkend="sql-select"/> documentation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">count</replaceable></term>
+ <listitem>
+ <para>
+ The maximum number of rows to return. For details see
+ <xref linkend="sql-limit"/>
+ in the <xref linkend="sql-select"/> documentation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">start</replaceable></term>
+ <listitem>
+ <para>
+ The number of rows to skip before starting to return rows.
+ For details see <xref linkend="sql-limit"/>
+ in the <xref linkend="sql-select"/> documentation.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <command>VALUES</command> lists with very large numbers of rows should be avoided,
+ as you might encounter out-of-memory failures or poor performance.
+ <command>VALUES</command> appearing within <command>INSERT</command> is a special case
+ (because the desired column types are known from the <command>INSERT</command>'s
+ target table, and need not be inferred by scanning the <command>VALUES</command>
+ list), so it can handle larger lists than are practical in other contexts.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Examples</title>
+
+ <para>
+ A bare <command>VALUES</command> command:
+
+<programlisting>
+VALUES (1, 'one'), (2, 'two'), (3, 'three');
+</programlisting>
+
+ This will return a table of two columns and three rows. It's effectively
+ equivalent to:
+
+<programlisting>
+SELECT 1 AS column1, 'one' AS column2
+UNION ALL
+SELECT 2, 'two'
+UNION ALL
+SELECT 3, 'three';
+</programlisting>
+
+ </para>
+
+ <para>
+ More usually, <command>VALUES</command> is used within a larger SQL command.
+ The most common use is in <command>INSERT</command>:
+
+<programlisting>
+INSERT INTO films (code, title, did, date_prod, kind)
+ VALUES ('T_601', 'Yojimbo', 106, '1961-06-16', 'Drama');
+</programlisting>
+ </para>
+
+ <para>
+ In the context of <command>INSERT</command>, entries of a <command>VALUES</command> list
+ can be <literal>DEFAULT</literal> to indicate that the column default
+ should be used here instead of specifying a value:
+
+<programlisting>
+INSERT INTO films VALUES
+ ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes'),
+ ('T_601', 'Yojimbo', 106, DEFAULT, 'Drama', DEFAULT);
+</programlisting>
+ </para>
+
+ <para>
+ <command>VALUES</command> can also be used where a sub-<command>SELECT</command> might
+ be written, for example in a <literal>FROM</literal> clause:
+
+<programlisting>
+SELECT f.*
+ FROM films f, (VALUES('MGM', 'Horror'), ('UA', 'Sci-Fi')) AS t (studio, kind)
+ WHERE f.studio = t.studio AND f.kind = t.kind;
+
+UPDATE employees SET salary = salary * v.increase
+ FROM (VALUES(1, 200000, 1.2), (2, 400000, 1.4)) AS v (depno, target, increase)
+ WHERE employees.depno = v.depno AND employees.sales &gt;= v.target;
+</programlisting>
+
+ Note that an <literal>AS</literal> clause is required when <command>VALUES</command>
+ is used in a <literal>FROM</literal> clause, just as is true for
+ <command>SELECT</command>. It is not required that the <literal>AS</literal> clause
+ specify names for all the columns, but it's good practice to do so.
+ (The default column names for <command>VALUES</command> are <literal>column1</literal>,
+ <literal>column2</literal>, etc. in <productname>PostgreSQL</productname>, but
+ these names might be different in other database systems.)
+ </para>
+
+ <para>
+ When <command>VALUES</command> is used in <command>INSERT</command>, the values are all
+ automatically coerced to the data type of the corresponding destination
+ column. When it's used in other contexts, it might be necessary to specify
+ the correct data type. If the entries are all quoted literal constants,
+ coercing the first is sufficient to determine the assumed type for all:
+
+<programlisting>
+SELECT * FROM machines
+WHERE ip_address IN (VALUES('192.168.0.1'::inet), ('192.168.0.10'), ('192.168.1.43'));
+</programlisting></para>
+
+ <tip>
+ <para>
+ For simple <literal>IN</literal> tests, it's better to rely on the
+ <link linkend="functions-comparisons-in-scalar">list-of-scalars</link>
+ form of <literal>IN</literal> than to write a <command>VALUES</command>
+ query as shown above. The list of scalars method requires less writing
+ and is often more efficient.
+ </para>
+ </tip>
+ </refsect1>
+
+ <refsect1>
+ <title>Compatibility</title>
+
+ <para><command>VALUES</command> conforms to the SQL standard.
+ <literal>LIMIT</literal> and <literal>OFFSET</literal> are
+ <productname>PostgreSQL</productname> extensions; see also
+ under <xref linkend="sql-select"/>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-insert"/></member>
+ <member><xref linkend="sql-select"/></member>
+ </simplelist>
+ </refsect1>
+</refentry>
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
new file mode 100644
index 0000000..a3b743e
--- /dev/null
+++ b/doc/src/sgml/reference.sgml
@@ -0,0 +1,296 @@
+<!-- doc/src/sgml/reference.sgml -->
+
+<part id="reference">
+ <title>Reference</title>
+
+ <partintro>
+ <para>
+ The entries in this Reference are meant to provide in reasonable
+ length an authoritative, complete, and formal summary about their
+ respective subjects. More information about the use of
+ <productname>PostgreSQL</productname>, in narrative, tutorial, or
+ example form, can be found in other parts of this book. See the
+ cross-references listed on each reference page.
+ </para>
+
+ <para>
+ The reference entries are also available as traditional
+ <quote>man</quote> pages.
+ </para>
+ </partintro>
+
+ <reference id="sql-commands">
+ <title>SQL Commands</title>
+
+ <partintro>
+ <para>
+ This part contains reference information for the
+ <acronym>SQL</acronym> commands supported by
+ <productname>PostgreSQL</productname>. By <quote>SQL</quote> the
+ language in general is meant; information about the standards
+ conformance and compatibility of each command can be found on the
+ respective reference page.
+ </para>
+ </partintro>
+
+ &abort;
+ &alterAggregate;
+ &alterCollation;
+ &alterConversion;
+ &alterDatabase;
+ &alterDefaultPrivileges;
+ &alterDomain;
+ &alterEventTrigger;
+ &alterExtension;
+ &alterForeignDataWrapper;
+ &alterForeignTable;
+ &alterFunction;
+ &alterGroup;
+ &alterIndex;
+ &alterLanguage;
+ &alterLargeObject;
+ &alterMaterializedView;
+ &alterOperator;
+ &alterOperatorClass;
+ &alterOperatorFamily;
+ &alterPolicy;
+ &alterProcedure;
+ &alterPublication;
+ &alterRole;
+ &alterRoutine;
+ &alterRule;
+ &alterSchema;
+ &alterSequence;
+ &alterServer;
+ &alterStatistics;
+ &alterSubscription;
+ &alterSystem;
+ &alterTable;
+ &alterTableSpace;
+ &alterTSConfig;
+ &alterTSDictionary;
+ &alterTSParser;
+ &alterTSTemplate;
+ &alterTrigger;
+ &alterType;
+ &alterUser;
+ &alterUserMapping;
+ &alterView;
+ &analyze;
+ &begin;
+ &call;
+ &checkpoint;
+ &close;
+ &cluster;
+ &commentOn;
+ &commit;
+ &commitPrepared;
+ &copyTable;
+ &createAccessMethod;
+ &createAggregate;
+ &createCast;
+ &createCollation;
+ &createConversion;
+ &createDatabase;
+ &createDomain;
+ &createEventTrigger;
+ &createExtension;
+ &createForeignDataWrapper;
+ &createForeignTable;
+ &createFunction;
+ &createGroup;
+ &createIndex;
+ &createLanguage;
+ &createMaterializedView;
+ &createOperator;
+ &createOperatorClass;
+ &createOperatorFamily;
+ &createPolicy;
+ &createProcedure;
+ &createPublication;
+ &createRole;
+ &createRule;
+ &createSchema;
+ &createSequence;
+ &createServer;
+ &createStatistics;
+ &createSubscription;
+ &createTable;
+ &createTableAs;
+ &createTableSpace;
+ &createTSConfig;
+ &createTSDictionary;
+ &createTSParser;
+ &createTSTemplate;
+ &createTransform;
+ &createTrigger;
+ &createType;
+ &createUser;
+ &createUserMapping;
+ &createView;
+ &deallocate;
+ &declare;
+ &delete;
+ &discard;
+ &do;
+ &dropAccessMethod;
+ &dropAggregate;
+ &dropCast;
+ &dropCollation;
+ &dropConversion;
+ &dropDatabase;
+ &dropDomain;
+ &dropEventTrigger;
+ &dropExtension;
+ &dropForeignDataWrapper;
+ &dropForeignTable;
+ &dropFunction;
+ &dropGroup;
+ &dropIndex;
+ &dropLanguage;
+ &dropMaterializedView;
+ &dropOperator;
+ &dropOperatorClass;
+ &dropOperatorFamily;
+ &dropOwned;
+ &dropPolicy;
+ &dropProcedure;
+ &dropPublication;
+ &dropRole;
+ &dropRoutine;
+ &dropRule;
+ &dropSchema;
+ &dropSequence;
+ &dropServer;
+ &dropStatistics;
+ &dropSubscription;
+ &dropTable;
+ &dropTableSpace;
+ &dropTSConfig;
+ &dropTSDictionary;
+ &dropTSParser;
+ &dropTSTemplate;
+ &dropTransform;
+ &dropTrigger;
+ &dropType;
+ &dropUser;
+ &dropUserMapping;
+ &dropView;
+ &end;
+ &execute;
+ &explain;
+ &fetch;
+ &grant;
+ &importForeignSchema;
+ &insert;
+ &listen;
+ &load;
+ &lock;
+ &merge;
+ &move;
+ &notify;
+ &prepare;
+ &prepareTransaction;
+ &reassignOwned;
+ &refreshMaterializedView;
+ &reindex;
+ &releaseSavepoint;
+ &reset;
+ &revoke;
+ &rollback;
+ &rollbackPrepared;
+ &rollbackTo;
+ &savepoint;
+ &securityLabel;
+ &select;
+ &selectInto;
+ &set;
+ &setConstraints;
+ &setRole;
+ &setSessionAuth;
+ &setTransaction;
+ &show;
+ &startTransaction;
+ &truncate;
+ &unlisten;
+ &update;
+ &vacuum;
+ &values;
+
+ </reference>
+
+ <reference id="reference-client">
+ <title>PostgreSQL Client Applications</title>
+
+ <partintro>
+ <para>
+ This part contains reference information for
+ <productname>PostgreSQL</productname> client applications and
+ utilities. Not all of these commands are of general utility; some
+ might require special privileges. The common feature of these
+ applications is that they can be run on any host, independent of
+ where the database server resides.
+ </para>
+
+ <para>
+ When specified on the command line, user and database names have
+ their case preserved &mdash; the presence of spaces or special
+ characters might require quoting. Table names and other identifiers
+ do not have their case preserved, except where documented, and
+ might require quoting.
+ </para>
+ </partintro>
+
+ &clusterdb;
+ &createdb;
+ &createuser;
+ &dropdb;
+ &dropuser;
+ &ecpgRef;
+ &pgamcheck;
+ &pgBasebackup;
+ &pgbench;
+ &pgConfig;
+ &pgDump;
+ &pgDumpall;
+ &pgIsready;
+ &pgReceivewal;
+ &pgRecvlogical;
+ &pgRestore;
+ &pgVerifyBackup;
+ &psqlRef;
+ &reindexdb;
+ &vacuumdb;
+
+ </reference>
+
+ <reference id="reference-server">
+ <title>PostgreSQL Server Applications</title>
+
+ <partintro>
+ <para>
+ This part contains reference information for
+ <productname>PostgreSQL</productname> server applications and
+ support utilities. These commands can only be run usefully on the
+ host where the database server resides. Other utility programs
+ are listed in <xref linkend="reference-client"/>.
+ </para>
+ </partintro>
+
+ &initdb;
+ &pgarchivecleanup;
+ &pgChecksums;
+ &pgControldata;
+ &pgCtl;
+ &pgResetwal;
+ &pgRewind;
+ &pgtestfsync;
+ &pgtesttiming;
+ &pgupgrade;
+ &pgwaldump;
+ &postgres;
+ &postmaster;
+
+ </reference>
+
+</part>
diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
new file mode 100644
index 0000000..952139f
--- /dev/null
+++ b/doc/src/sgml/regress.sgml
@@ -0,0 +1,851 @@
+<!-- doc/src/sgml/regress.sgml -->
+
+ <chapter id="regress">
+ <title>Regression Tests</title>
+
+ <indexterm zone="regress">
+ <primary>regression tests</primary>
+ </indexterm>
+
+ <indexterm zone="regress">
+ <primary>test</primary>
+ </indexterm>
+
+ <para>
+ The regression tests are a comprehensive set of tests for the SQL
+ implementation in <productname>PostgreSQL</productname>. They test
+ standard SQL operations as well as the extended capabilities of
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <sect1 id="regress-run">
+ <title>Running the Tests</title>
+
+ <para>
+ The regression tests can be run against an already installed and
+ running server, or using a temporary installation within the build
+ tree. Furthermore, there is a <quote>parallel</quote> and a
+ <quote>sequential</quote> mode for running the tests. The
+ sequential method runs each test script alone, while the
+ parallel method starts up multiple server processes to run groups
+ of tests in parallel. Parallel testing adds confidence that
+ interprocess communication and locking are working correctly.
+ </para>
+
+ <sect2>
+ <title>Running the Tests Against a Temporary Installation</title>
+
+ <para>
+ To run the parallel regression tests after building but before installation,
+ type:
+<screen>
+make check
+</screen>
+ in the top-level directory. (Or you can change to
+ <filename>src/test/regress</filename> and run the command there.)
+ At the end you should see something like:
+<screen>
+<computeroutput>
+=======================
+ All 193 tests passed.
+=======================
+</computeroutput>
+</screen>
+ or otherwise a note about which tests failed. See <xref
+ linkend="regress-evaluation"/> below before assuming that a
+ <quote>failure</quote> represents a serious problem.
+ </para>
+
+ <para>
+ Because this test method runs a temporary server, it will not work
+ if you did the build as the root user, since the server will not start as
+ root. Recommended procedure is not to do the build as root, or else to
+ perform testing after completing the installation.
+ </para>
+
+ <para>
+ If you have configured <productname>PostgreSQL</productname> to install
+ into a location where an older <productname>PostgreSQL</productname>
+ installation already exists, and you perform <literal>make check</literal>
+ before installing the new version, you might find that the tests fail
+ because the new programs try to use the already-installed shared
+ libraries. (Typical symptoms are complaints about undefined symbols.)
+ If you wish to run the tests before overwriting the old installation,
+ you'll need to build with <literal>configure --disable-rpath</literal>.
+ It is not recommended that you use this option for the final installation,
+ however.
+ </para>
+
+ <para>
+ The parallel regression test starts quite a few processes under your
+ user ID. Presently, the maximum concurrency is twenty parallel test
+ scripts, which means forty processes: there's a server process and a
+ <application>psql</application> process for each test script.
+ So if your system enforces a per-user limit on the number of processes,
+ make sure this limit is at least fifty or so, else you might get
+ random-seeming failures in the parallel test. If you are not in
+ a position to raise the limit, you can cut down the degree of parallelism
+ by setting the <literal>MAX_CONNECTIONS</literal> parameter. For example:
+<screen>
+make MAX_CONNECTIONS=10 check
+</screen>
+ runs no more than ten tests concurrently.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Running the Tests Against an Existing Installation</title>
+
+ <para>
+ To run the tests after installation (see <xref linkend="installation"/>),
+ initialize a data directory and start the
+ server as explained in <xref linkend="runtime"/>, then type:
+<screen>
+make installcheck
+</screen>
+or for a parallel test:
+<screen>
+make installcheck-parallel
+</screen>
+ The tests will expect to contact the server at the local host and the
+ default port number, unless directed otherwise by <envar>PGHOST</envar> and
+ <envar>PGPORT</envar> environment variables. The tests will be run in a
+ database named <literal>regression</literal>; any existing database by this name
+ will be dropped.
+ </para>
+
+ <para>
+ The tests will also transiently create some cluster-wide objects, such as
+ roles, tablespaces, and subscriptions. These objects will have names
+ beginning with <literal>regress_</literal>. Beware of
+ using <literal>installcheck</literal> mode with an installation that has
+ any actual global objects named that way.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Additional Test Suites</title>
+
+ <para>
+ The <literal>make check</literal> and <literal>make installcheck</literal> commands
+ run only the <quote>core</quote> regression tests, which test built-in
+ functionality of the <productname>PostgreSQL</productname> server. The source
+ distribution contains many additional test suites, most of them having
+ to do with add-on functionality such as optional procedural languages.
+ </para>
+
+ <para>
+ To run all test suites applicable to the modules that have been selected
+ to be built, including the core tests, type one of these commands at the
+ top of the build tree:
+<screen>
+make check-world
+make installcheck-world
+</screen>
+ These commands run the tests using temporary servers or an
+ already-installed server, respectively, just as previously explained
+ for <literal>make check</literal> and <literal>make installcheck</literal>. Other
+ considerations are the same as previously explained for each method.
+ Note that <literal>make check-world</literal> builds a separate instance
+ (temporary data directory) for each tested module, so it requires more
+ time and disk space than <literal>make installcheck-world</literal>.
+ </para>
+
+ <para>
+ On a modern machine with multiple CPU cores and no tight operating-system
+ limits, you can make things go substantially faster with parallelism.
+ The recipe that most PostgreSQL developers actually use for running all
+ tests is something like
+<screen>
+make check-world -j8 >/dev/null
+</screen>
+ with a <option>-j</option> limit near to or a bit more than the number
+ of available cores. Discarding <systemitem>stdout</systemitem>
+ eliminates chatter that's not interesting when you just want to verify
+ success. (In case of failure, the <systemitem>stderr</systemitem>
+ messages are usually enough to determine where to look closer.)
+ </para>
+
+ <para>
+ Alternatively, you can run individual test suites by typing
+ <literal>make check</literal> or <literal>make installcheck</literal> in the appropriate
+ subdirectory of the build tree. Keep in mind that <literal>make
+ installcheck</literal> assumes you've installed the relevant module(s), not
+ only the core server.
+ </para>
+
+ <para>
+ The additional tests that can be invoked this way include:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Regression tests for optional procedural languages.
+ These are located under <filename>src/pl</filename>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Regression tests for <filename>contrib</filename> modules,
+ located under <filename>contrib</filename>.
+ Not all <filename>contrib</filename> modules have tests.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Regression tests for the ECPG interface library,
+ located in <filename>src/interfaces/ecpg/test</filename>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Tests for core-supported authentication methods,
+ located in <filename>src/test/authentication</filename>.
+ (See below for additional authentication-related tests.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Tests stressing behavior of concurrent sessions,
+ located in <filename>src/test/isolation</filename>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Tests for crash recovery and physical replication,
+ located in <filename>src/test/recovery</filename>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Tests for logical replication,
+ located in <filename>src/test/subscription</filename>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Tests of client programs, located under <filename>src/bin</filename>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ When using <literal>installcheck</literal> mode, these tests will create
+ and destroy test databases whose names
+ include <literal>regression</literal>, for
+ example <literal>pl_regression</literal>
+ or <literal>contrib_regression</literal>. Beware of
+ using <literal>installcheck</literal> mode with an installation that has
+ any non-test databases named that way.
+ </para>
+
+ <para>
+ Some of these auxiliary test suites use the TAP infrastructure explained
+ in <xref linkend="regress-tap"/>.
+ The TAP-based tests are run only when PostgreSQL was configured with the
+ option <option>--enable-tap-tests</option>. This is recommended for
+ development, but can be omitted if there is no suitable Perl installation.
+ </para>
+
+ <para>
+ Some test suites are not run by default, either because they are not secure
+ to run on a multiuser system or because they require special software. You
+ can decide which test suites to run additionally by setting the
+ <command>make</command> or environment variable
+ <varname>PG_TEST_EXTRA</varname> to a whitespace-separated list, for
+ example:
+<programlisting>
+make check-world PG_TEST_EXTRA='kerberos ldap ssl'
+</programlisting>
+ The following values are currently supported:
+ <variablelist>
+ <varlistentry>
+ <term><literal>kerberos</literal></term>
+ <listitem>
+ <para>
+ Runs the test suite under <filename>src/test/kerberos</filename>. This
+ requires an MIT Kerberos installation and opens TCP/IP listen sockets.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ldap</literal></term>
+ <listitem>
+ <para>
+ Runs the test suite under <filename>src/test/ldap</filename>. This
+ requires an <productname>OpenLDAP</productname> installation and opens
+ TCP/IP listen sockets.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ssl</literal></term>
+ <listitem>
+ <para>
+ Runs the test suite under <filename>src/test/ssl</filename>. This opens TCP/IP listen sockets.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>wal_consistency_checking</literal></term>
+ <listitem>
+ <para>
+ Uses <literal>wal_consistency_checking=all</literal> while running
+ certain tests under <filename>src/test/recovery</filename>. Not
+ enabled by default because it is resource intensive.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Tests for features that are not supported by the current build
+ configuration are not run even if they are mentioned in
+ <varname>PG_TEST_EXTRA</varname>.
+ </para>
+
+ <para>
+ In addition, there are tests in <filename>src/test/modules</filename>
+ which will be run by <literal>make check-world</literal> but not
+ by <literal>make installcheck-world</literal>. This is because they
+ install non-production extensions or have other side-effects that are
+ considered undesirable for a production installation. You can
+ use <literal>make install</literal> and <literal>make
+ installcheck</literal> in one of those subdirectories if you wish,
+ but it's not recommended to do so with a non-test server.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Locale and Encoding</title>
+
+ <para>
+ By default, tests using a temporary installation use the
+ locale defined in the current environment and the corresponding
+ database encoding as determined by <command>initdb</command>. It
+ can be useful to test different locales by setting the appropriate
+ environment variables, for example:
+<screen>
+make check LANG=C
+make check LC_COLLATE=en_US.utf8 LC_CTYPE=fr_CA.utf8
+</screen>
+ For implementation reasons, setting <envar>LC_ALL</envar> does not
+ work for this purpose; all the other locale-related environment
+ variables do work.
+ </para>
+
+ <para>
+ When testing against an existing installation, the locale is
+ determined by the existing database cluster and cannot be set
+ separately for the test run.
+ </para>
+
+ <para>
+ You can also choose the database encoding explicitly by setting
+ the variable <envar>ENCODING</envar>, for example:
+<screen>
+make check LANG=C ENCODING=EUC_JP
+</screen>
+ Setting the database encoding this way typically only makes sense
+ if the locale is C; otherwise the encoding is chosen automatically
+ from the locale, and specifying an encoding that does not match
+ the locale will result in an error.
+ </para>
+
+ <para>
+ The database encoding can be set for tests against either a temporary or
+ an existing installation, though in the latter case it must be
+ compatible with the installation's locale.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Custom Server Settings</title>
+
+ <para>
+ Custom server settings to use when running a regression test suite can be
+ set in the <varname>PGOPTIONS</varname> environment variable (for settings
+ that allow this):
+<screen>
+make check PGOPTIONS="-c force_parallel_mode=regress -c work_mem=50MB"
+</screen>
+ When running against a temporary installation, custom settings can also be
+ set by supplying a pre-written <filename>postgresql.conf</filename>:
+<screen>
+echo 'log_checkpoints = on' > test_postgresql.conf
+echo 'work_mem = 50MB' >> test_postgresql.conf
+make check EXTRA_REGRESS_OPTS="--temp-config=test_postgresql.conf"
+</screen>
+ </para>
+
+ <para>
+ This can be useful to enable additional logging, adjust resource limits,
+ or enable extra run-time checks such as <xref
+ linkend="guc-debug-discard-caches"/>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Extra Tests</title>
+
+ <para>
+ The core regression test suite contains a few test files that are not
+ run by default, because they might be platform-dependent or take a
+ very long time to run. You can run these or other extra test
+ files by setting the variable <envar>EXTRA_TESTS</envar>. For
+ example, to run the <literal>numeric_big</literal> test:
+<screen>
+make check EXTRA_TESTS=numeric_big
+</screen>
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="regress-evaluation">
+ <title>Test Evaluation</title>
+
+ <para>
+ Some properly installed and fully functional
+ <productname>PostgreSQL</productname> installations can
+ <quote>fail</quote> some of these regression tests due to
+ platform-specific artifacts such as varying floating-point representation
+ and message wording. The tests are currently evaluated using a simple
+ <command>diff</command> comparison against the outputs
+ generated on a reference system, so the results are sensitive to
+ small system differences. When a test is reported as
+ <quote>failed</quote>, always examine the differences between
+ expected and actual results; you might find that the
+ differences are not significant. Nonetheless, we still strive to
+ maintain accurate reference files across all supported platforms,
+ so it can be expected that all tests pass.
+ </para>
+
+ <para>
+ The actual outputs of the regression tests are in files in the
+ <filename>src/test/regress/results</filename> directory. The test
+ script uses <command>diff</command> to compare each output
+ file against the reference outputs stored in the
+ <filename>src/test/regress/expected</filename> directory. Any
+ differences are saved for your inspection in
+ <filename>src/test/regress/regression.diffs</filename>.
+ (When running a test suite other than the core tests, these files
+ of course appear in the relevant subdirectory,
+ not <filename>src/test/regress</filename>.)
+ </para>
+
+ <para>
+ If you don't
+ like the <command>diff</command> options that are used by default, set the
+ environment variable <envar>PG_REGRESS_DIFF_OPTS</envar>, for
+ instance <literal>PG_REGRESS_DIFF_OPTS='-c'</literal>. (Or you
+ can run <command>diff</command> yourself, if you prefer.)
+ </para>
+
+ <para>
+ If for some reason a particular platform generates a <quote>failure</quote>
+ for a given test, but inspection of the output convinces you that
+ the result is valid, you can add a new comparison file to silence
+ the failure report in future test runs. See
+ <xref linkend="regress-variant"/> for details.
+ </para>
+
+ <sect2>
+ <title>Error Message Differences</title>
+
+ <para>
+ Some of the regression tests involve intentional invalid input
+ values. Error messages can come from either the
+ <productname>PostgreSQL</productname> code or from the host
+ platform system routines. In the latter case, the messages can
+ vary between platforms, but should reflect similar
+ information. These differences in messages will result in a
+ <quote>failed</quote> regression test that can be validated by
+ inspection.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Locale Differences</title>
+
+ <para>
+ If you run the tests against a server that was
+ initialized with a collation-order locale other than C, then
+ there might be differences due to sort order and subsequent
+ failures. The regression test suite is set up to handle this
+ problem by providing alternate result files that together are
+ known to handle a large number of locales.
+ </para>
+
+ <para>
+ To run the tests in a different locale when using the
+ temporary-installation method, pass the appropriate
+ locale-related environment variables on
+ the <command>make</command> command line, for example:
+<programlisting>
+make check LANG=de_DE.utf8
+</programlisting>
+ (The regression test driver unsets <envar>LC_ALL</envar>, so it
+ does not work to choose the locale using that variable.) To use
+ no locale, either unset all locale-related environment variables
+ (or set them to <literal>C</literal>) or use the following
+ special invocation:
+<programlisting>
+make check NO_LOCALE=1
+</programlisting>
+ When running the tests against an existing installation, the
+ locale setup is determined by the existing installation. To
+ change it, initialize the database cluster with a different
+ locale by passing the appropriate options
+ to <command>initdb</command>.
+ </para>
+
+ <para>
+ In general, it is advisable to try to run the
+ regression tests in the locale setup that is wanted for
+ production use, as this will exercise the locale- and
+ encoding-related code portions that will actually be used in
+ production. Depending on the operating system environment, you
+ might get failures, but then you will at least know what
+ locale-specific behaviors to expect when running real
+ applications.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Date and Time Differences</title>
+
+ <para>
+ Most of the date and time results are dependent on the time zone
+ environment. The reference files are generated for time zone
+ <literal>PST8PDT</literal> (Berkeley, California), and there will be
+ apparent failures if the tests are not run with that time zone setting.
+ The regression test driver sets environment variable
+ <envar>PGTZ</envar> to <literal>PST8PDT</literal>, which normally
+ ensures proper results.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Floating-Point Differences</title>
+
+ <para>
+ Some of the tests involve computing 64-bit floating-point numbers (<type>double
+ precision</type>) from table columns. Differences in
+ results involving mathematical functions of <type>double
+ precision</type> columns have been observed. The <literal>float8</literal> and
+ <literal>geometry</literal> tests are particularly prone to small differences
+ across platforms, or even with different compiler optimization settings.
+ Human eyeball comparison is needed to determine the real
+ significance of these differences which are usually 10 places to
+ the right of the decimal point.
+ </para>
+
+ <para>
+ Some systems display minus zero as <literal>-0</literal>, while others
+ just show <literal>0</literal>.
+ </para>
+
+ <para>
+ Some systems signal errors from <function>pow()</function> and
+ <function>exp()</function> differently from the mechanism
+ expected by the current <productname>PostgreSQL</productname>
+ code.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Row Ordering Differences</title>
+
+ <para>
+You might see differences in which the same rows are output in a
+different order than what appears in the expected file. In most cases
+this is not, strictly speaking, a bug. Most of the regression test
+scripts are not so pedantic as to use an <literal>ORDER BY</literal> for every single
+<literal>SELECT</literal>, and so their result row orderings are not well-defined
+according to the SQL specification. In practice, since we are
+looking at the same queries being executed on the same data by the same
+software, we usually get the same result ordering on all platforms,
+so the lack of <literal>ORDER BY</literal> is not a problem. Some queries do exhibit
+cross-platform ordering differences, however. When testing against an
+already-installed server, ordering differences can also be caused by
+non-C locale settings or non-default parameter settings, such as custom values
+of <varname>work_mem</varname> or the planner cost parameters.
+ </para>
+
+ <para>
+Therefore, if you see an ordering difference, it's not something to
+worry about, unless the query does have an <literal>ORDER BY</literal> that your
+result is violating. However, please report it anyway, so that we can add an
+<literal>ORDER BY</literal> to that particular query to eliminate the bogus
+<quote>failure</quote> in future releases.
+ </para>
+
+ <para>
+You might wonder why we don't order all the regression test queries explicitly
+to get rid of this issue once and for all. The reason is that that would
+make the regression tests less useful, not more, since they'd tend
+to exercise query plan types that produce ordered results to the
+exclusion of those that don't.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Insufficient Stack Depth</title>
+
+ <para>
+ If the <literal>errors</literal> test results in a server crash
+ at the <literal>select infinite_recurse()</literal> command, it means that
+ the platform's limit on process stack size is smaller than the
+ <xref linkend="guc-max-stack-depth"/> parameter indicates. This
+ can be fixed by running the server under a higher stack
+ size limit (4MB is recommended with the default value of
+ <varname>max_stack_depth</varname>). If you are unable to do that, an
+ alternative is to reduce the value of <varname>max_stack_depth</varname>.
+ </para>
+
+ <para>
+ On platforms supporting <function>getrlimit()</function>, the server should
+ automatically choose a safe value of <varname>max_stack_depth</varname>;
+ so unless you've manually overridden this setting, a failure of this
+ kind is a reportable bug.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>The <quote>random</quote> Test</title>
+
+ <para>
+ The <literal>random</literal> test script is intended to produce
+ random results. In very rare cases, this causes that regression
+ test to fail. Typing:
+<programlisting>
+diff results/random.out expected/random.out
+</programlisting>
+ should produce only one or a few lines of differences. You need
+ not worry unless the random test fails repeatedly.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Configuration Parameters</title>
+
+ <para>
+ When running the tests against an existing installation, some non-default
+ parameter settings could cause the tests to fail. For example, changing
+ parameters such as <varname>enable_seqscan</varname> or
+ <varname>enable_indexscan</varname> could cause plan changes that would
+ affect the results of tests that use <command>EXPLAIN</command>.
+ </para>
+ </sect2>
+ </sect1>
+
+<!-- We might want to move the following section into the developer's guide. -->
+ <sect1 id="regress-variant">
+ <title>Variant Comparison Files</title>
+
+ <para>
+ Since some of the tests inherently produce environment-dependent
+ results, we have provided ways to specify alternate <quote>expected</quote>
+ result files. Each regression test can have several comparison files
+ showing possible results on different platforms. There are two
+ independent mechanisms for determining which comparison file is used
+ for each test.
+ </para>
+
+ <para>
+ The first mechanism allows comparison files to be selected for
+ specific platforms. There is a mapping file,
+ <filename>src/test/regress/resultmap</filename>, that defines
+ which comparison file to use for each platform.
+ To eliminate bogus test <quote>failures</quote> for a particular platform,
+ you first choose or make a variant result file, and then add a line to the
+ <filename>resultmap</filename> file.
+ </para>
+
+ <para>
+ Each line in the mapping file is of the form
+<synopsis>
+testname:output:platformpattern=comparisonfilename
+</synopsis>
+ The test name is just the name of the particular regression test
+ module. The output value indicates which output file to check. For the
+ standard regression tests, this is always <literal>out</literal>. The
+ value corresponds to the file extension of the output file.
+ The platform pattern is a pattern in the style of the Unix
+ tool <command>expr</command> (that is, a regular expression with an implicit
+ <literal>^</literal> anchor at the start). It is matched against the
+ platform name as printed by <command>config.guess</command>.
+ The comparison file name is the base name of the substitute result
+ comparison file.
+ </para>
+
+ <para>
+ For example: some systems lack a working <literal>strtof</literal> function,
+ for which our workaround causes rounding errors in the
+ <filename>float4</filename> regression test.
+ Therefore, we provide a variant comparison file,
+ <filename>float4-misrounded-input.out</filename>, which includes
+ the results to be expected on these systems. To silence the bogus
+ <quote>failure</quote> message on <systemitem>HP-UX 10</systemitem>
+ platforms, <filename>resultmap</filename> includes:
+<programlisting>
+float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out
+</programlisting>
+ which will trigger on any machine where the output of
+ <command>config.guess</command> matches <literal>hppa.*-hp-hpux10.*</literal>.
+ Other lines in <filename>resultmap</filename> select the variant comparison
+ file for other platforms where it's appropriate.
+ </para>
+
+ <para>
+ The second selection mechanism for variant comparison files is
+ much more automatic: it simply uses the <quote>best match</quote> among
+ several supplied comparison files. The regression test driver
+ script considers both the standard comparison file for a test,
+ <literal><replaceable>testname</replaceable>.out</literal>, and variant files named
+ <literal><replaceable>testname</replaceable>_<replaceable>digit</replaceable>.out</literal>
+ (where the <replaceable>digit</replaceable> is any single digit
+ <literal>0</literal>-<literal>9</literal>). If any such file is an exact match,
+ the test is considered to pass; otherwise, the one that generates
+ the shortest diff is used to create the failure report. (If
+ <filename>resultmap</filename> includes an entry for the particular
+ test, then the base <replaceable>testname</replaceable> is the substitute
+ name given in <filename>resultmap</filename>.)
+ </para>
+
+ <para>
+ For example, for the <literal>char</literal> test, the comparison file
+ <filename>char.out</filename> contains results that are expected
+ in the <literal>C</literal> and <literal>POSIX</literal> locales, while
+ the file <filename>char_1.out</filename> contains results sorted as
+ they appear in many other locales.
+ </para>
+
+ <para>
+ The best-match mechanism was devised to cope with locale-dependent
+ results, but it can be used in any situation where the test results
+ cannot be predicted easily from the platform name alone. A limitation of
+ this mechanism is that the test driver cannot tell which variant is
+ actually <quote>correct</quote> for the current environment; it will just pick
+ the variant that seems to work best. Therefore it is safest to use this
+ mechanism only for variant results that you are willing to consider
+ equally valid in all contexts.
+ </para>
+
+ </sect1>
+
+ <sect1 id="regress-tap">
+ <title>TAP Tests</title>
+
+ <para>
+ Various tests, particularly the client program tests
+ under <filename>src/bin</filename>, use the Perl TAP tools and are run
+ using the Perl testing program <command>prove</command>. You can pass
+ command-line options to <command>prove</command> by setting
+ the <command>make</command> variable <varname>PROVE_FLAGS</varname>, for example:
+<programlisting>
+make -C src/bin check PROVE_FLAGS='--timer'
+</programlisting>
+ See the manual page of <command>prove</command> for more information.
+ </para>
+
+ <para>
+ The <command>make</command> variable <varname>PROVE_TESTS</varname>
+ can be used to define a whitespace-separated list of paths relative
+ to the <filename>Makefile</filename> invoking <command>prove</command>
+ to run the specified subset of tests instead of the default
+ <filename>t/*.pl</filename>. For example:
+<programlisting>
+make check PROVE_TESTS='t/001_test1.pl t/003_test3.pl'
+</programlisting>
+ </para>
+
+ <para>
+ The TAP tests require the Perl module <literal>IPC::Run</literal>.
+ This module is available from CPAN or an operating system package.
+ They also require <productname>PostgreSQL</productname> to be
+ configured with the option <option>--enable-tap-tests</option>.
+ </para>
+
+ <para>
+ Generically speaking, the TAP tests will test the executables in a
+ previously-installed installation tree if you say <literal>make
+ installcheck</literal>, or will build a new local installation tree from
+ current sources if you say <literal>make check</literal>. In either
+ case they will initialize a local instance (data directory) and
+ transiently run a server in it. Some of these tests run more than one
+ server. Thus, these tests can be fairly resource-intensive.
+ </para>
+
+ <para>
+ It's important to realize that the TAP tests will start test server(s)
+ even when you say <literal>make installcheck</literal>; this is unlike
+ the traditional non-TAP testing infrastructure, which expects to use an
+ already-running test server in that case. Some PostgreSQL
+ subdirectories contain both traditional-style and TAP-style tests,
+ meaning that <literal>make installcheck</literal> will produce a mix of
+ results from temporary servers and the already-running test server.
+ </para>
+ </sect1>
+
+ <sect1 id="regress-coverage">
+ <title>Test Coverage Examination</title>
+
+ <para>
+ The PostgreSQL source code can be compiled with coverage testing
+ instrumentation, so that it becomes possible to examine which
+ parts of the code are covered by the regression tests or any other
+ test suite that is run with the code. This is currently supported
+ when compiling with GCC, and it requires the <command>gcov</command>
+ and <command>lcov</command> programs.
+ </para>
+
+ <para>
+ A typical workflow looks like this:
+<screen>
+./configure --enable-coverage ... OTHER OPTIONS ...
+make
+make check # or other test suite
+make coverage-html
+</screen>
+ Then point your HTML browser
+ to <filename>coverage/index.html</filename>.
+ </para>
+
+ <para>
+ If you don't have <command>lcov</command> or prefer text output over an
+ HTML report, you can run
+<screen>
+make coverage
+</screen>
+ instead of <literal>make coverage-html</literal>, which will
+ produce <filename>.gcov</filename> output files for each source file
+ relevant to the test. (<literal>make coverage</literal> and <literal>make
+ coverage-html</literal> will overwrite each other's files, so mixing them
+ might be confusing.)
+ </para>
+
+ <para>
+ You can run several different tests before making the coverage report;
+ the execution counts will accumulate. If you want
+ to reset the execution counts between test runs, run:
+<screen>
+make coverage-clean
+</screen>
+ </para>
+
+ <para>
+ You can run the <literal>make coverage-html</literal> or <literal>make
+ coverage</literal> command in a subdirectory if you want a coverage
+ report for only a portion of the code tree.
+ </para>
+
+ <para>
+ Use <literal>make distclean</literal> to clean up when done.
+ </para>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/release-15.sgml b/doc/src/sgml/release-15.sgml
new file mode 100644
index 0000000..09df673
--- /dev/null
+++ b/doc/src/sgml/release-15.sgml
@@ -0,0 +1,8633 @@
+<!-- doc/src/sgml/release-15.sgml -->
+<!-- See header comment in release.sgml about typical markup -->
+
+ <sect1 id="release-15-4">
+ <title>Release 15.4</title>
+
+ <formalpara>
+ <title>Release date:</title>
+ <para>2023-08-10</para>
+ </formalpara>
+
+ <para>
+ This release contains a variety of fixes from 15.3.
+ For information about new features in major release 15, see
+ <xref linkend="release-15"/>.
+ </para>
+
+ <sect2>
+ <title>Migration to Version 15.4</title>
+
+ <para>
+ A dump/restore is not required for those running 15.X.
+ </para>
+
+ <para>
+ However, if you use BRIN indexes, it may be advisable to reindex them;
+ see the third changelog entry below.
+ </para>
+
+ <para>
+ Also, if you are upgrading from a version earlier than 15.1,
+ see <xref linkend="release-15-1"/>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Changes</title>
+
+ <itemizedlist>
+
+ <listitem>
+<!--
+Author: Noah Misch <noah@leadboat.com>
+Branch: master [cd5f2a357] 2023-08-07 06:05:56 -0700
+Branch: REL_16_STABLE [f53511010] 2023-08-07 06:05:59 -0700
+Branch: REL_15_STABLE [de494ec14] 2023-08-07 06:06:00 -0700
+Branch: REL_14_STABLE [d4648a74b] 2023-08-07 06:06:00 -0700
+Branch: REL_13_STABLE [b1b585e0f] 2023-08-07 06:06:00 -0700
+Branch: REL_12_STABLE [eb044d8f0] 2023-08-07 06:06:00 -0700
+Branch: REL_11_STABLE [919ebb023] 2023-08-07 06:06:01 -0700
+-->
+ <para>
+ Disallow substituting a schema or owner name into an extension script
+ if the name contains a quote, backslash, or dollar sign (Noah Misch)
+ </para>
+
+ <para>
+ This restriction guards against SQL-injection hazards for trusted
+ extensions.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> Project thanks Micah Gate,
+ Valerie Woolard, Tim Carey-Smith, and Christoph Berg for reporting
+ this problem.
+ (CVE-2023-39417)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [c2e08b04c] 2023-08-07 09:28:47 +0100
+Branch: REL_16_STABLE [67a007dc0] 2023-08-07 09:27:09 +0100
+Branch: REL_15_STABLE [cb2ae5741] 2023-08-07 09:24:27 +0100
+-->
+ <para>
+ Fix <command>MERGE</command> to enforce row security policies
+ properly (Dean Rasheed)
+ </para>
+
+ <para>
+ When <command>MERGE</command> performs an <literal>UPDATE</literal>
+ action, it should enforce any <literal>UPDATE</literal> or
+ <literal>SELECT</literal> RLS policies defined on the target table,
+ to be consistent with the way that a plain <command>UPDATE</command>
+ with a <literal>WHERE</literal> clause works. Instead it was
+ enforcing <literal>INSERT</literal> RLS policies for both
+ <literal>INSERT</literal> and <literal>UPDATE</literal> actions.
+ </para>
+
+ <para>
+ In addition, when <command>MERGE</command> performs a <literal>DO
+ NOTHING</literal> action, it applied the target table's
+ <literal>DELETE</literal> RLS policies to existing rows, even though
+ those rows are not being deleted. While it's not a security
+ problem, this could result in unwanted errors.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> Project thanks
+ Dean Rasheed for reporting this problem.
+ (CVE-2023-39418)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master Release: REL_16_BR [3581cbdcd] 2023-05-19 01:29:44 +0200
+Branch: REL_15_STABLE [e18769323] 2023-05-19 00:15:13 +0200
+Branch: REL_14_STABLE [40d465caf] 2023-05-19 00:15:00 +0200
+Branch: REL_13_STABLE [6c512fc6e] 2023-05-19 00:14:05 +0200
+Branch: REL_12_STABLE [d78a66d92] 2023-05-19 00:16:13 +0200
+Branch: REL_11_STABLE [fc7dc728d] 2023-05-19 00:21:05 +0200
+Branch: master Release: REL_16_BR [3ec8a3bfb] 2023-05-18 23:33:23 +0200
+Branch: REL_15_STABLE [80f64b900] 2023-05-18 23:33:45 +0200
+Branch: REL_14_STABLE [3f1356e5d] 2023-05-18 23:34:10 +0200
+Branch: REL_13_STABLE [2b1ab28b9] 2023-05-18 23:34:35 +0200
+Branch: REL_12_STABLE [d42ffda68] 2023-05-18 23:34:56 +0200
+Branch: REL_11_STABLE [b511d7323] 2023-05-18 23:35:16 +0200
+-->
+ <para>
+ Fix confusion between empty (no rows) ranges and all-NULL ranges in
+ BRIN indexes, as well as incorrect merging of all-NULL summaries
+ (Tomas Vondra)
+ </para>
+
+ <para>
+ Each of these oversights could result in forgetting that a BRIN
+ index range contains any NULL values, potentially allowing
+ subsequent queries that should return NULL values to miss doing so.
+ </para>
+
+ <para>
+ This fix will not in itself correct faulty BRIN entries.
+ It's recommended to <command>REINDEX</command> any BRIN indexes that
+ may be used to search for nulls.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [c66a7d75e] 2023-07-13 13:03:28 -0700
+Branch: REL_16_STABLE [a4b4cc1d6] 2023-07-13 13:03:30 -0700
+Branch: REL_15_STABLE [f66403749] 2023-07-13 13:04:45 -0700
+Branch: REL_14_STABLE [d11efe830] 2023-07-13 13:03:33 -0700
+Branch: REL_13_STABLE [81ce00006] 2023-07-13 13:03:34 -0700
+Branch: REL_12_STABLE [034a9fcd2] 2023-07-13 13:03:36 -0700
+Branch: REL_11_STABLE [1c38e7ae1] 2023-07-13 13:03:37 -0700
+-->
+ <para>
+ Avoid leaving a corrupted database behind when <command>DROP
+ DATABASE</command> is interrupted (Andres Freund)
+ </para>
+
+ <para>
+ If <command>DROP DATABASE</command> was interrupted after it had
+ already begun taking irreversible steps, the target database
+ remained accessible (because the removal of
+ its <structname>pg_database</structname> row would roll back),
+ but it would have corrupt contents. Fix by marking the database
+ as inaccessible before we begin to perform irreversible operations.
+ A failure after that will leave the database still partially
+ present, but nothing can be done with it except to issue
+ another <command>DROP DATABASE</command>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [cfc43aeb3] 2023-06-30 13:54:48 +0900
+Branch: REL_16_STABLE [f4691e2e7] 2023-06-30 13:54:53 +0900
+Branch: REL_15_STABLE [cb4ac3e56] 2023-06-30 13:54:55 +0900
+Branch: REL_14_STABLE [663b35f2d] 2023-06-30 13:54:56 +0900
+Branch: REL_13_STABLE [537b70b82] 2023-06-30 13:54:59 +0900
+Branch: REL_12_STABLE [dbe0e5c56] 2023-06-30 13:55:02 +0900
+Branch: REL_11_STABLE [c75c33de5] 2023-06-30 13:55:07 +0900
+-->
+ <para>
+ Ensure that partitioned indexes are correctly marked as valid or not
+ at creation (Michael Paquier)
+ </para>
+
+ <para>
+ If a new partitioned index matches an existing but invalid index on
+ one of the partitions, the partitioned index could end up being
+ marked valid prematurely. This could lead to misbehavior or
+ assertion failures in subsequent queries on the partitioned table.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master Release: REL_16_BR [fc55c7ff8] 2023-06-28 15:57:31 +0900
+Branch: REL_15_STABLE [7aa17b498] 2023-06-28 15:57:43 +0900
+Branch: REL_14_STABLE [6160e221d] 2023-06-28 15:57:48 +0900
+Branch: REL_13_STABLE [f42844069] 2023-06-28 15:57:51 +0900
+Branch: REL_12_STABLE [63b292e73] 2023-06-28 15:57:53 +0900
+Branch: REL_11_STABLE [e90e9275f] 2023-06-28 15:57:55 +0900
+-->
+ <para>
+ Ignore invalid child indexes when matching partitioned indexes to
+ child indexes during <command>ALTER TABLE ATTACH PARTITION</command>
+ (Michael Paquier)
+ </para>
+
+ <para>
+ Such an index will now be ignored, and a new child index created
+ instead.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [38ea6aa90] 2023-07-14 10:12:48 +0900
+Branch: REL_16_STABLE [31f9d41d6] 2023-07-14 10:13:14 +0900
+Branch: REL_15_STABLE [c0dc97c7b] 2023-07-14 10:13:15 +0900
+Branch: REL_14_STABLE [954cc2139] 2023-07-14 10:13:17 +0900
+Branch: REL_13_STABLE [c89d74c18] 2023-07-14 10:13:20 +0900
+Branch: REL_12_STABLE [f1d6bcdd8] 2023-07-14 10:13:21 +0900
+Branch: REL_11_STABLE [ed2b58c15] 2023-07-14 10:13:22 +0900
+-->
+ <para>
+ Fix possible failure when marking a partitioned index valid after
+ all of its partitions have been attached (Michael Paquier)
+ </para>
+
+ <para>
+ The update of the index's <structname>pg_index</structname> entry
+ could use stale data for other columns. One reported symptom is
+ an <quote>attempted to update invisible tuple</quote> error.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [bd5ddbe86] 2023-07-10 09:40:07 +0900
+Branch: REL_16_STABLE [55c95f24c] 2023-07-10 09:40:12 +0900
+Branch: REL_15_STABLE [d1e0f408c] 2023-07-10 09:40:14 +0900
+Branch: REL_14_STABLE [235e716bc] 2023-07-10 09:40:15 +0900
+Branch: REL_13_STABLE [f5b075adc] 2023-07-10 09:40:17 +0900
+Branch: REL_12_STABLE [02021f1b2] 2023-07-10 09:40:22 +0900
+Branch: REL_11_STABLE [914e72e6e] 2023-07-10 09:40:24 +0900
+-->
+ <para>
+ Fix <command>ALTER EXTENSION SET SCHEMA</command> to complain if the
+ extension contains any objects outside the extension's schema
+ (Michael Paquier, Heikki Linnakangas)
+ </para>
+
+ <para>
+ Erroring out if the extension contains objects in multiple schemas
+ was always intended; but the check was mis-coded so that it would
+ fail to detect some cases, leading to surprising behavior.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master Release: REL_16_BR [97d891010] 2023-06-30 07:49:01 +0900
+Branch: REL_15_STABLE [93401ec02] 2023-06-30 07:49:07 +0900
+-->
+ <para>
+ Fix tracking of tables' access method dependencies (Michael Paquier)
+ </para>
+
+ <para>
+ <command>ALTER TABLE ... SET ACCESS METHOD</command> failed to
+ update relevant <structname>pg_depend</structname> entries when
+ changing a table's access method. When using non-built-in access
+ methods, this creates a risk that an access method could be dropped
+ even though tables still depend on it. This fix corrects the logic
+ in <command>ALTER TABLE</command>, but it will not adjust any
+ already-missing <structname>pg_depend</structname> entries.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master Release: REL_16_BR [7fcd7ef2a] 2023-06-19 13:00:42 +1200
+Branch: REL_15_STABLE [8f2ec8cc7] 2023-06-19 13:01:29 +1200
+Branch: REL_14_STABLE [73f1c17fc] 2023-06-19 13:01:58 +1200
+Branch: REL_13_STABLE [06286f8a2] 2023-06-19 13:02:24 +1200
+Branch: REL_12_STABLE [dcef5b052] 2023-06-19 13:02:52 +1200
+Branch: REL_11_STABLE [f6345f03f] 2023-06-19 13:03:17 +1200
+-->
+ <para>
+ Don't use partial unique indexes for uniqueness proofs in the
+ planner (David Rowley)
+ </para>
+
+ <para>
+ This could give rise to incorrect plans, since the presumed
+ uniqueness of rows read from a table might not hold if the index in
+ question isn't used to scan the table.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [990c3650c] 2023-08-07 22:14:21 +1200
+Branch: REL_16_STABLE [ae89129aa] 2023-08-07 22:14:54 +1200
+Branch: REL_15_STABLE [71662373b] 2023-08-07 22:15:23 +1200
+Branch: REL_14_STABLE [bf315354e] 2023-08-07 22:15:50 +1200
+-->
+ <para>
+ Don't Memoize lateral joins with volatile join conditions
+ (Richard Guo)
+ </para>
+
+ <para>
+ Applying Memoize to a sub-plan that contains volatile filter
+ conditions is likely to lead to wrong answers. The check to avoid
+ doing this missed some cases that can arise when
+ using <literal>LATERAL</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Etsuro Fujita <efujita@postgresql.org>
+Branch: master [6f80a8d9c] 2023-07-28 15:45:00 +0900
+Branch: REL_16_STABLE [695f5deb7] 2023-07-28 15:45:01 +0900
+Branch: REL_15_STABLE [d1ef5631e] 2023-07-28 15:45:02 +0900
+Branch: REL_14_STABLE [b0e390e6d] 2023-07-28 15:45:04 +0900
+Branch: REL_13_STABLE [730f983ef] 2023-07-28 15:45:06 +0900
+Branch: REL_12_STABLE [9edf72aa7] 2023-07-28 15:45:08 +0900
+Branch: REL_11_STABLE [db01f2696] 2023-07-28 15:45:09 +0900
+-->
+ <para>
+ Avoid producing incorrect plans for foreign joins with
+ pseudoconstant join clauses (Etsuro Fujita)
+ </para>
+
+ <para>
+ The planner currently lacks support for attaching pseudoconstant
+ join clauses to a pushed-down remote join, so disable generation
+ of remote joins in such cases. (A better solution will require
+ ABI-breaking changes of planner data structures, so it will have to
+ wait for a future major release.)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [792213f2e] 2023-06-13 15:58:43 -0400
+Branch: REL_15_STABLE [cc6974df1] 2023-06-13 15:58:37 -0400
+Branch: REL_14_STABLE [d1423c52e] 2023-06-13 15:58:37 -0400
+Branch: REL_13_STABLE [a36d0014f] 2023-06-13 15:58:37 -0400
+Branch: REL_12_STABLE [b4110bdbf] 2023-06-13 15:58:37 -0400
+Branch: REL_11_STABLE [13192a324] 2023-06-13 15:58:37 -0400
+-->
+ <para>
+ Correctly handle sub-SELECTs in RLS policy expressions and
+ security-barrier views when expanding rule actions (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [126552c85] 2023-07-04 09:07:31 +1200
+Branch: REL_16_STABLE [12529028a] 2023-07-04 09:04:35 +1200
+Branch: REL_15_STABLE [d34aa0a2f] 2023-07-04 09:10:37 +1200
+Branch: REL_14_STABLE [fb663f387] 2023-07-04 09:14:16 +1200
+Branch: REL_13_STABLE [fc1547384] 2023-07-04 09:20:55 +1200
+Branch: REL_12_STABLE [255a925d3] 2023-07-04 09:21:33 +1200
+Branch: REL_11_STABLE [13f127800] 2023-07-04 09:40:30 +1200
+Branch: master [bcc93a389] 2023-07-04 09:07:31 +1200
+Branch: REL_16_STABLE [d03d9a261] 2023-07-04 09:04:35 +1200
+Branch: REL_15_STABLE [ab265e985] 2023-07-04 09:10:37 +1200
+Branch: REL_14_STABLE [3f7d3a77e] 2023-07-04 09:14:16 +1200
+Branch: REL_13_STABLE [8976ac5c5] 2023-07-04 09:20:55 +1200
+Branch: REL_12_STABLE [17b8887c2] 2023-07-04 09:21:33 +1200
+Branch: REL_11_STABLE [814f3c8e4] 2023-07-04 09:40:30 +1200
+Branch: master [f9b7fc651] 2023-07-04 09:07:31 +1200
+Branch: REL_16_STABLE [0cb1fb2c9] 2023-07-04 09:04:35 +1200
+Branch: REL_15_STABLE [0f275b0ee] 2023-07-04 09:10:37 +1200
+Branch: REL_14_STABLE [ae6d536ed] 2023-07-04 09:14:16 +1200
+Branch: REL_13_STABLE [8f705d7b9] 2023-07-04 09:20:55 +1200
+Branch: REL_12_STABLE [fe88497b4] 2023-07-04 09:21:33 +1200
+Branch: REL_11_STABLE [0048c3b51] 2023-07-04 09:27:00 +1200
+-->
+ <para>
+ Fix race conditions in conflict detection
+ for <literal>SERIALIZABLE</literal> isolation mode
+ (Thomas Munro)
+ </para>
+
+ <para>
+ Conflicts could be missed when using bitmap heap scans, when using
+ GIN indexes, and when examining an initially-empty btree index.
+ All these cases could lead to serializability failures due to
+ improperly allowing conflicting transactions to commit.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [70b42f279] 2023-05-19 14:26:40 -0400
+Branch: REL_15_STABLE [4729d1e8a] 2023-05-19 14:26:34 -0400
+Branch: REL_14_STABLE [f8320cc72] 2023-05-19 14:26:34 -0400
+-->
+ <para>
+ Fix misbehavior of EvalPlanQual checks with inherited or partitioned
+ target tables (Tom Lane)
+ </para>
+
+ <para>
+ This oversight could lead to update or delete actions
+ in <literal>READ COMMITTED</literal> isolation mode getting
+ performed when they should have been skipped because of a
+ conflicting concurrent update.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [45392626c] 2023-06-20 17:47:53 -0400
+Branch: REL_15_STABLE [c2f974fff] 2023-06-20 17:47:53 -0400
+Branch: REL_14_STABLE [d911dce14] 2023-06-20 17:47:36 -0400
+Branch: REL_13_STABLE [2f97105e9] 2023-06-20 17:47:36 -0400
+Branch: REL_12_STABLE [9529b1eb1] 2023-06-20 17:47:36 -0400
+-->
+ <para>
+ Fix hash join with an inner-side hash key that contains Params
+ coming from an outer nested loop (Tom Lane)
+ </para>
+
+ <para>
+ When rescanning the join after the values of such Params have
+ changed, we must rebuild the hash table, but neglected to do so.
+ This could result in missing join output rows.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [43af714de] 2023-06-29 10:19:10 -0400
+Branch: REL_15_STABLE [cc8cca3c2] 2023-06-29 10:19:10 -0400
+Branch: REL_14_STABLE [0789b82a9] 2023-06-29 10:19:10 -0400
+Branch: REL_13_STABLE [d0ab203bc] 2023-06-29 10:19:10 -0400
+Branch: REL_12_STABLE [53b93e853] 2023-06-29 10:19:10 -0400
+Branch: REL_11_STABLE [7f11b7a9c] 2023-06-29 10:19:10 -0400
+-->
+ <para>
+ Fix intermittent failures when trying to update a field of a
+ composite column (Tom Lane)
+ </para>
+
+ <para>
+ If the overall value of the composite column is wide enough to
+ require out-of-line toasting, then an unluckily-timed cache flush
+ could cause errors or server crashes.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master Release: REL_16_BR [f24523672] 2023-06-07 18:54:34 +0200
+Branch: REL_15_STABLE [ee87f8b63] 2023-06-07 18:52:21 +0200
+Branch: REL_14_STABLE [7f528e96c] 2023-06-07 18:53:04 +0200
+Branch: REL_13_STABLE [c504aa857] 2023-06-07 18:53:16 +0200
+Branch: REL_12_STABLE [54e1b8587] 2023-06-07 18:53:30 +0200
+Branch: master [ce5aaea8c] 2023-07-02 22:21:02 +0200
+Branch: REL_16_STABLE [9cf85093b] 2023-07-02 22:22:31 +0200
+Branch: REL_15_STABLE [7ae4e7868] 2023-07-02 22:22:50 +0200
+Branch: REL_14_STABLE [260dbf19a] 2023-07-02 22:23:04 +0200
+Branch: REL_13_STABLE [984c23f6f] 2023-07-02 22:23:20 +0200
+-->
+ <para>
+ Prevent query-lifespan memory leaks in some <command>UPDATE</command>
+ queries with triggers (Tomas Vondra)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master [98640f960] 2023-07-02 20:03:30 +0200
+Branch: REL_16_STABLE [9ae7b5d1f] 2023-07-02 20:04:16 +0200
+Branch: REL_15_STABLE [0c5fe4ff6] 2023-07-02 20:04:40 +0200
+Branch: REL_14_STABLE [c1affa38c] 2023-07-02 20:05:14 +0200
+Branch: REL_13_STABLE [3ce761d5c] 2023-07-02 20:05:35 +0200
+-->
+ <para>
+ Prevent query-lifespan memory leaks when an Incremental Sort plan
+ node is rescanned (James Coleman, Laurenz Albe, Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [7398e2722] 2023-06-12 10:54:44 -0400
+Branch: REL_15_STABLE [bd590d1fe] 2023-06-12 10:54:28 -0400
+Branch: REL_14_STABLE [5eaa05f63] 2023-06-12 10:54:28 -0400
+Branch: REL_13_STABLE [6f23b5f74] 2023-06-12 10:54:28 -0400
+-->
+ <para>
+ Accept fractional seconds in the input to <type>jsonpath</type>'s
+ <function>datetime()</function> method (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [691594acd] 2023-06-24 17:18:08 -0400
+Branch: REL_15_STABLE [a77d90171] 2023-06-24 17:18:08 -0400
+Branch: REL_14_STABLE [4c61afa47] 2023-06-24 17:18:08 -0400
+Branch: REL_13_STABLE [b6ab18a99] 2023-06-24 17:18:08 -0400
+Branch: REL_12_STABLE [3b4580f5c] 2023-06-24 17:18:08 -0400
+Branch: REL_11_STABLE [c7f33a197] 2023-06-24 17:18:08 -0400
+-->
+ <para>
+ Prevent stack-overflow crashes with very complex text search
+ patterns (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [38df84c65] 2023-07-27 11:56:35 -0400
+Branch: REL_16_STABLE [de3f0e3fe] 2023-07-27 11:56:35 -0400
+Branch: REL_15_STABLE [313ceda2f] 2023-07-27 12:07:48 -0400
+Branch: REL_14_STABLE [341996248] 2023-07-27 12:07:48 -0400
+Branch: REL_13_STABLE [288b4288c] 2023-07-27 12:07:48 -0400
+Branch: REL_12_STABLE [0660f74e8] 2023-07-27 12:07:48 -0400
+Branch: REL_11_STABLE [1d031ad54] 2023-07-27 12:07:48 -0400
+-->
+ <para>
+ Allow tokens up to 10240 bytes long
+ in <filename>pg_hba.conf</filename>
+ and <filename>pg_ident.conf</filename> (Tom Lane)
+ </para>
+
+ <para>
+ The previous limit of 256 bytes has been found insufficient for some
+ use-cases.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+Branch: REL_15_STABLE [a5f312c58] 2023-07-06 13:05:25 +0300
+-->
+ <para>
+ Ensure that all existing placeholders are checked for matches when
+ an extension declares its GUC prefix to be reserved (Karina
+ Litskevich, Ekaterina Sokolova)
+ </para>
+
+ <para>
+ Faulty loop logic could cause some entries to be skipped.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+Branch: master [4f4d73466] 2023-07-05 13:13:13 +0300
+Branch: REL_16_STABLE [dc0b58417] 2023-07-05 13:25:59 +0300
+Branch: REL_15_STABLE [fa96a74a0] 2023-07-05 13:13:30 +0300
+Branch: REL_14_STABLE [bfb493dba] 2023-07-05 13:13:35 +0300
+Branch: REL_13_STABLE [59c2a6fe9] 2023-07-05 13:13:39 +0300
+Branch: REL_12_STABLE [162aa47c3] 2023-07-05 13:14:24 +0300
+Branch: REL_11_STABLE [2316ff1ae] 2023-07-05 13:14:33 +0300
+-->
+ <para>
+ Fix mishandling of C++ out-of-memory conditions (Heikki Linnakangas)
+ </para>
+
+ <para>
+ If JIT is in use, running out of memory in a
+ C++ <function>new</function> call would lead to
+ a <productname>PostgreSQL</productname> FATAL error, instead of the
+ expected C++ exception.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [9089287aa] 2023-07-20 14:23:46 -0400
+Branch: REL_16_STABLE [c0f531396] 2023-07-20 14:23:46 -0400
+Branch: REL_15_STABLE [fbaf65cd6] 2023-07-20 14:23:46 -0400
+Branch: REL_14_STABLE [10fd061bb] 2023-07-20 14:23:46 -0400
+Branch: REL_13_STABLE [291c02540] 2023-07-20 14:23:46 -0400
+-->
+ <para>
+ Fix rare null-pointer crash in <filename>plancache.c</filename>
+ (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Masahiko Sawada <msawada@postgresql.org>
+Branch: master [68a59f9e9] 2023-07-05 14:49:46 +0900
+Branch: REL_16_STABLE [be8cae7e2] 2023-07-05 14:49:58 +0900
+Branch: REL_15_STABLE [66f8a1397] 2023-07-05 14:49:53 +0900
+-->
+ <para>
+ Avoid leaking a stats entry for a subscription when it is dropped
+ (Masahiko Sawada)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [03f80daac] 2023-07-04 15:16:47 +1200
+Branch: REL_16_STABLE [af8f9ec66] 2023-07-04 15:21:36 +1200
+Branch: REL_15_STABLE [9ffb10f18] 2023-07-04 15:24:42 +1200
+Branch: REL_14_STABLE [b7ec66731] 2023-07-04 15:26:42 +1200
+Branch: REL_13_STABLE [a0003572f] 2023-07-04 15:28:29 +1200
+Branch: REL_12_STABLE [74ad9b0d1] 2023-07-04 15:29:41 +1200
+Branch: REL_11_STABLE [1605623ec] 2023-07-04 16:13:12 +1200
+-->
+ <para>
+ Avoid losing track of possibly-useful shared memory segments when a
+ page free results in coalescing ranges of free space (Dongming Liu)
+ </para>
+
+ <para>
+ Ensure that the segment is moved into the
+ appropriate <quote>bin</quote> for its new amount of free space, so
+ that it will be found by subsequent searches.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Peter Geoghegan <pg@bowt.ie>
+Branch: master Release: REL_16_BR [5f0762f14] 2023-06-21 17:41:58 -0700
+Branch: REL_15_STABLE [642bec1f8] 2023-06-21 17:41:56 -0700
+Branch: REL_14_STABLE [63fa0deb3] 2023-06-21 17:41:54 -0700
+Branch: REL_13_STABLE [b6311824f] 2023-06-21 17:41:52 -0700
+Branch: REL_12_STABLE [355917c07] 2023-06-21 17:41:50 -0700
+Branch: REL_11_STABLE [7ddba19eb] 2023-06-21 17:41:48 -0700
+Branch: master Release: REL_16_BR [5abff197c] 2023-05-25 15:33:00 -0700
+Branch: REL_15_STABLE [6983a5112] 2023-05-25 15:32:57 -0700
+Branch: REL_14_STABLE [322c9b340] 2023-05-25 15:32:53 -0700
+Branch: REL_13_STABLE [8f876d15c] 2023-05-25 15:32:50 -0700
+Branch: REL_12_STABLE [188dad680] 2023-05-25 15:32:48 -0700
+Branch: REL_11_STABLE [a72b503ca] 2023-05-25 15:32:45 -0700
+-->
+ <para>
+ Allow <command>VACUUM</command> to continue after detecting certain
+ types of b-tree index corruption (Peter Geoghegan)
+ </para>
+
+ <para>
+ If an invalid sibling-page link is detected, log the issue and press
+ on, rather than throwing an error as before. Nothing short
+ of <command>REINDEX</command> will fix the broken index, but
+ preventing <command>VACUUM</command> from completing until that is
+ done risks making matters far worse.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [83ecfa9fa] 2023-07-13 13:03:28 -0700
+Branch: REL_16_STABLE [03ccc9569] 2023-07-13 13:03:30 -0700
+Branch: REL_15_STABLE [82e97b864] 2023-07-13 13:03:31 -0700
+Branch: REL_14_STABLE [e246fd423] 2023-07-13 13:03:33 -0700
+Branch: REL_13_STABLE [53336e8f6] 2023-07-13 13:03:34 -0700
+Branch: REL_12_STABLE [7aec84e4c] 2023-07-13 13:03:36 -0700
+Branch: REL_11_STABLE [1386f0987] 2023-07-13 13:03:37 -0700
+-->
+ <para>
+ Ensure that <varname>WrapLimitsVacuumLock</varname> is released
+ after <command>VACUUM</command> detects invalid data
+ in <structname>pg_database</structname>.<structfield>datfrozenxid</structfield>
+ or <structname>pg_database</structname>.<structfield>datminmxid</structfield>
+ (Andres Freund)
+ </para>
+
+ <para>
+ Failure to release this lock could lead to a deadlock later,
+ although the lock would be cleaned up if the session exits or
+ encounters some other error.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [cb0cca188] 2023-07-18 13:43:44 +0900
+Branch: REL_16_STABLE [f88bc9f38] 2023-07-18 13:44:27 +0900
+Branch: REL_15_STABLE [a878eff6b] 2023-07-18 13:44:29 +0900
+Branch: REL_14_STABLE [442749100] 2023-07-18 13:44:31 +0900
+Branch: REL_13_STABLE [db59108a2] 2023-07-18 13:44:33 +0900
+Branch: REL_12_STABLE [d2ee542a2] 2023-07-18 13:44:34 +0900
+Branch: REL_11_STABLE [bc0581f8f] 2023-07-18 13:44:35 +0900
+Branch: master [4e465aac3] 2023-07-18 14:04:31 +0900
+Branch: REL_16_STABLE [926aa6d11] 2023-07-18 14:04:46 +0900
+Branch: REL_15_STABLE [f6ecd2622] 2023-07-18 14:04:48 +0900
+Branch: REL_14_STABLE [763d26205] 2023-07-18 14:04:50 +0900
+Branch: REL_13_STABLE [b3ca4f0a5] 2023-07-18 14:04:51 +0900
+Branch: REL_12_STABLE [410a0d6bd] 2023-07-18 14:04:52 +0900
+Branch: REL_11_STABLE [6c7bffc09] 2023-07-18 14:04:54 +0900
+-->
+ <para>
+ Avoid double replay of prepared transactions during crash
+ recovery (suyu.cmj, Michael Paquier)
+ </para>
+
+ <para>
+ After a crash partway through a checkpoint with some two-phase
+ transaction state data already flushed to disk by this checkpoint,
+ crash recovery could attempt to replay the prepared transaction(s)
+ twice, leading to a fatal error such as <quote>lock is already
+ held</quote> in the startup process.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+Branch: master [4b4798e13] 2023-07-04 17:57:03 +0300
+Branch: REL_16_STABLE [d431644b4] 2023-07-04 18:04:27 +0300
+Branch: REL_15_STABLE [e24c02e4d] 2023-07-04 18:07:27 +0300
+Branch: REL_14_STABLE [d85bf0719] 2023-07-04 18:07:46 +0300
+Branch: REL_13_STABLE [acc8cdff4] 2023-07-04 18:08:08 +0300
+Branch: REL_12_STABLE [1b4f1c6f8] 2023-07-04 18:08:26 +0300
+Branch: REL_11_STABLE [6377f705c] 2023-07-04 18:08:40 +0300
+-->
+ <para>
+ Ensure that a newly created, but still empty table
+ is <function>fsync</function>'ed at the next checkpoint (Heikki
+ Linnakangas)
+ </para>
+
+ <para>
+ Without this, if there is an operating system crash causing the
+ empty file to disappear, subsequent operations on the table might
+ fail with <quote>could not open file</quote> errors.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+Branch: master [3142a8845] 2023-07-06 17:25:29 +0300
+Branch: REL_16_STABLE [bf7b70e6b] 2023-07-06 17:28:50 +0300
+Branch: REL_15_STABLE [25624c5d3] 2023-07-06 17:29:12 +0300
+Branch: REL_14_STABLE [32f327f68] 2023-07-06 17:29:13 +0300
+Branch: REL_13_STABLE [c50b869ed] 2023-07-06 17:29:14 +0300
+Branch: REL_12_STABLE [80abec387] 2023-07-06 17:29:15 +0300
+Branch: REL_11_STABLE [988719b88] 2023-07-06 17:29:16 +0300
+-->
+ <para>
+ Ensure that creation of the init fork of an unlogged index is
+ WAL-logged (Heikki Linnakangas)
+ </para>
+
+ <para>
+ While an unlogged index's main data fork is not WAL-logged, its init
+ fork should be, to ensure that we have a consistent state to restore
+ the index to after a crash. This step was missed if the init fork
+ contains no data, which is a case not used by any standard index AM;
+ but perhaps some extension behaves that way.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [4637a6ac0] 2023-07-03 11:16:27 +1200
+Branch: REL_16_STABLE [76d5966b3] 2023-07-03 11:21:56 +1200
+Branch: REL_15_STABLE [f50200c01] 2023-07-03 11:22:10 +1200
+-->
+ <para>
+ Silence bogus <quote>missing contrecord</quote> errors (Thomas Munro)
+ </para>
+
+ <para>
+ Treat this case as plain end-of-WAL to avoid logging inaccurate
+ complaints from <application>pg_waldump</application>
+ and <application>walsender</application>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [deae1657e] 2023-08-02 01:39:47 +1200
+Branch: REL_16_STABLE [b25acc302] 2023-08-02 01:40:27 +1200
+Branch: REL_15_STABLE [67f3a697b] 2023-08-02 01:40:56 +1200
+Branch: REL_14_STABLE [f457f2ef1] 2023-08-02 01:41:21 +1200
+Branch: REL_13_STABLE [74a5bf1b6] 2023-08-02 01:41:55 +1200
+Branch: REL_12_STABLE [668990980] 2023-08-02 01:44:31 +1200
+-->
+ <para>
+ Fix overly strict assertion in <type>jsonpath</type> code
+ (David Rowley)
+ </para>
+
+ <para>
+ This assertion failed if a query applied
+ the <literal>.type()</literal> operator to
+ a <literal>like_regex</literal> result.
+ There was no bug in non-assert builds.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [555b929bb] 2023-06-21 11:07:24 -0400
+Branch: REL_15_STABLE [cb74f7bec] 2023-06-21 11:07:11 -0400
+Branch: REL_14_STABLE [120ea65b8] 2023-06-21 11:07:11 -0400
+Branch: REL_13_STABLE [d1fc0f382] 2023-06-21 11:07:11 -0400
+Branch: REL_12_STABLE [a98a04005] 2023-06-21 11:07:11 -0400
+Branch: REL_11_STABLE [a8be2356c] 2023-06-21 11:07:11 -0400
+-->
+ <para>
+ Avoid assertion failure when processing an empty statement via the
+ extended query protocol in an already-aborted transaction (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master Release: REL_16_BR [605994651] 2023-05-10 11:24:30 +0900
+Branch: REL_15_STABLE [ccd21e1cf] 2023-05-10 11:24:40 +0900
+-->
+ <para>
+ Avoid assertion failure when
+ the <varname>stats_fetch_consistency</varname> setting is changed
+ intra-transaction (Kyotaro Horiguchi)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [1d369c9e9] 2023-05-16 10:53:42 -0400
+Branch: REL_15_STABLE [eaf99e4c4] 2023-05-16 10:53:42 -0400
+Branch: REL_14_STABLE [ccd362325] 2023-05-16 10:53:42 -0400
+Branch: REL_13_STABLE [0409c7fc7] 2023-05-16 10:53:42 -0400
+Branch: REL_12_STABLE [0966291a4] 2023-05-16 10:53:42 -0400
+Branch: REL_11_STABLE [8084bf9a4] 2023-05-16 10:53:42 -0400
+-->
+ <para>
+ Fix <filename>contrib/fuzzystrmatch</filename>'s
+ Soundex <function>difference()</function> function to handle empty
+ input sanely (Alexander Lakhin, Tom Lane)
+ </para>
+
+ <para>
+ An input string containing no alphabetic characters resulted in
+ unpredictable output.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master Release: REL_16_BR [d522b05c8] 2023-06-12 09:14:03 +0900
+Branch: REL_15_STABLE [3a5222a43] 2023-06-12 09:14:13 +0900
+Branch: REL_14_STABLE [e0e682945] 2023-06-12 09:14:14 +0900
+Branch: REL_13_STABLE [78bf0a256] 2023-06-12 09:14:17 +0900
+Branch: REL_12_STABLE [edf1de65e] 2023-06-12 09:14:19 +0900
+Branch: REL_11_STABLE [bbfc26d86] 2023-06-12 09:14:20 +0900
+-->
+ <para>
+ Tighten whitespace checks in <filename>contrib/hstore</filename>
+ input (Evan Jones)
+ </para>
+
+ <para>
+ In some cases, characters would be falsely recognized as whitespace
+ and hence discarded.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master Release: REL_16_BR [c00fbe89d] 2023-06-15 13:45:34 +0900
+Branch: REL_15_STABLE [4be308ede] 2023-06-15 13:45:38 +0900
+Branch: REL_14_STABLE [019a40d61] 2023-06-15 13:45:40 +0900
+Branch: REL_13_STABLE [ae9aac64a] 2023-06-15 13:45:41 +0900
+Branch: REL_12_STABLE [6ecc1c02a] 2023-06-15 13:45:42 +0900
+Branch: REL_11_STABLE [ab40b0395] 2023-06-15 13:45:44 +0900
+-->
+ <para>
+ Disallow oversize input arrays
+ with <filename>contrib/intarray</filename>'s
+ <literal>gist__int_ops</literal> index opclass (Ankit Kumar Pandey,
+ Alexander Lakhin)
+ </para>
+
+ <para>
+ Previously this code would report a <literal>NOTICE</literal> but
+ press on anyway, creating an invalid index entry that presents a
+ risk of crashes when the index is read.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [8aac9759b] 2023-07-13 13:07:51 -0400
+Branch: REL_16_STABLE [e27f3f52c] 2023-07-13 13:08:08 -0400
+Branch: REL_15_STABLE [5cb461989] 2023-07-13 13:08:17 -0400
+Branch: REL_14_STABLE [a6991f763] 2023-07-13 13:08:23 -0400
+Branch: REL_13_STABLE [7fffcc2ee] 2023-07-13 13:08:28 -0400
+Branch: REL_12_STABLE [8d8f37149] 2023-07-13 13:08:33 -0400
+Branch: REL_11_STABLE [9f70f6d4c] 2023-07-13 13:08:40 -0400
+-->
+ <para>
+ Avoid useless double decompression of GiST index entries
+ in <filename>contrib/intarray</filename> (Konstantin Knizhnik,
+ Matthias van de Meent, Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master Release: REL_16_BR [e7bff46e5] 2023-05-19 12:37:58 +0900
+Branch: REL_15_STABLE [2dd778221] 2023-05-19 12:38:15 +0900
+Branch: REL_14_STABLE [e72580232] 2023-05-19 12:38:18 +0900
+-->
+ <para>
+ Fix <filename>contrib/pageinspect</filename>'s
+ <function>gist_page_items()</function> function to work when there
+ are included index columns (Alexander Lakhin, Michael Paquier)
+ </para>
+
+ <para>
+ Previously, if the index has included
+ columns, <function>gist_page_items()</function> would fail to
+ display those values on index leaf pages, or crash outright on
+ non-leaf pages.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [51b2c0879] 2023-05-12 16:11:14 -0400
+Branch: REL_15_STABLE [bc478a0a8] 2023-05-12 16:11:14 -0400
+-->
+ <para>
+ In <application>psql</application>, ignore
+ the <envar>PSQL_WATCH_PAGER</envar> environment variable when
+ stdin/stdout are not a terminal (Tom Lane)
+ </para>
+
+ <para>
+ This corresponds to the treatment of <envar>PSQL_PAGER</envar> in
+ commands besides <command>\watch</command>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [016107478] 2023-06-04 13:05:54 -0400
+Branch: REL_15_STABLE [ca9e79274] 2023-06-04 13:05:54 -0400
+Branch: REL_14_STABLE [d6f549d7a] 2023-06-04 13:05:54 -0400
+-->
+ <para>
+ Fix <application>pg_dump</application> to correctly handle new-style
+ SQL-language functions whose bodies require parse-time dependencies
+ on unique indexes (Tom Lane)
+ </para>
+
+ <para>
+ Such cases can arise from <literal>GROUP BY</literal>
+ and <literal>ON CONFLICT</literal> clauses, for example. The
+ function must then be postponed until after the unique index in the
+ dump output, but <application>pg_dump</application> did not do that
+ and instead printed a warning about <quote>could not resolve
+ dependency loop</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master Release: REL_16_BR [b3f32a6c3] 2023-06-04 11:22:05 -0400
+Branch: REL_15_STABLE [751ba1a7c] 2023-06-04 11:22:05 -0400
+-->
+ <para>
+ Improve <application>pg_dump</application>'s display of details
+ about dependency-loop problems (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master Release: REL_16_BR [8f5e42d33] 2023-05-25 12:36:18 +0200
+Branch: REL_15_STABLE [34f511965] 2023-05-25 12:36:18 +0200
+-->
+ <para>
+ Avoid crash in <application>pgbench</application> with an empty
+ pipeline and prepared mode (&Aacute;lvaro Herrera)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [a5ea825f9] 2023-07-14 11:15:34 +0900
+Branch: REL_16_STABLE [27da47122] 2023-07-14 11:16:03 +0900
+Branch: REL_15_STABLE [eb3abec4b] 2023-07-14 11:16:06 +0900
+Branch: REL_14_STABLE [7af65523a] 2023-07-14 11:16:08 +0900
+Branch: REL_13_STABLE [bdaaf1bf1] 2023-07-14 11:16:10 +0900
+Branch: REL_12_STABLE [7d27493b7] 2023-07-14 11:16:11 +0900
+Branch: REL_11_STABLE [db9813819] 2023-07-14 11:16:13 +0900
+-->
+ <para>
+ Ensure
+ that <structname>pg_index</structname>.<structfield>indisreplident</structfield>
+ is kept up-to-date in relation cache entries (Shruthi Gowda)
+ </para>
+
+ <para>
+ This value could be stale in some cases. There is no core code that
+ relies on the relation cache's copy, so this is only a latent bug as
+ far as Postgres itself is concerned; but there may be extensions for
+ which it is a live bug.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tatsuo Ishii <ishii@postgresql.org>
+Branch: master Release: REL_16_BR [ae66716bf] 2023-06-14 11:02:50 +0900
+Branch: REL_15_STABLE [af26f28b9] 2023-06-14 11:11:18 +0900
+-->
+ <para>
+ Fix <application>make_etags</application> script to work with
+ non-Exuberant <application>ctags</application> (Masahiko Sawada)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="release-15-3">
+ <title>Release 15.3</title>
+
+ <formalpara>
+ <title>Release date:</title>
+ <para>2023-05-11</para>
+ </formalpara>
+
+ <para>
+ This release contains a variety of fixes from 15.2.
+ For information about new features in major release 15, see
+ <xref linkend="release-15"/>.
+ </para>
+
+ <sect2>
+ <title>Migration to Version 15.3</title>
+
+ <para>
+ A dump/restore is not required for those running 15.X.
+ </para>
+
+ <para>
+ However, if you are upgrading from a version earlier than 15.1,
+ see <xref linkend="release-15-1"/>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Changes</title>
+
+ <itemizedlist>
+
+ <listitem>
+<!--
+Author: Noah Misch <noah@leadboat.com>
+Branch: master [681d9e462] 2023-05-08 06:14:07 -0700
+Branch: REL_15_STABLE [dbd5795e7] 2023-05-08 06:14:11 -0700
+Branch: REL_14_STABLE [01e8182c7] 2023-05-08 06:14:11 -0700
+Branch: REL_13_STABLE [2212f7db8] 2023-05-08 06:14:12 -0700
+Branch: REL_12_STABLE [78119a0bf] 2023-05-08 06:14:12 -0700
+Branch: REL_11_STABLE [23cb8eaeb] 2023-05-08 06:14:12 -0700
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [8d525d7b9] 2023-05-08 11:24:47 -0400
+Branch: REL_15_STABLE [1b761d896] 2023-05-08 11:24:47 -0400
+Branch: REL_14_STABLE [1913f63dc] 2023-05-08 11:24:47 -0400
+Branch: REL_13_STABLE [feb9e7fbb] 2023-05-08 11:24:47 -0400
+Branch: REL_12_STABLE [2cd843cc9] 2023-05-08 11:24:47 -0400
+Branch: REL_11_STABLE [766e06140] 2023-05-08 11:24:47 -0400
+-->
+ <para>
+ Prevent <command>CREATE SCHEMA</command> from defeating changes
+ in <varname>search_path</varname> (Alexander Lakhin)
+ </para>
+
+ <para>
+ Within a <command>CREATE SCHEMA</command> command, objects in the
+ prevailing <varname>search_path</varname>, as well as those in the
+ newly-created schema, would be visible even within a called
+ function or script that attempted to set a
+ secure <varname>search_path</varname>. This could allow any user
+ having permission to create a schema to hijack the privileges of a
+ security definer function or extension script.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> Project thanks
+ Alexander Lakhin for reporting this problem.
+ (CVE-2023-2454)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [ca73753b0] 2023-05-08 10:12:44 -0400
+Branch: REL_15_STABLE [04e560604] 2023-05-08 10:12:44 -0400
+Branch: REL_14_STABLE [f8d799eda] 2023-05-08 10:12:44 -0400
+Branch: REL_13_STABLE [b8e28f04f] 2023-05-08 10:12:44 -0400
+Branch: REL_12_STABLE [ee87b482c] 2023-05-08 10:12:45 -0400
+Branch: REL_11_STABLE [473626cf0] 2023-05-08 10:12:45 -0400
+-->
+ <para>
+ Enforce row-level security policies correctly after inlining a
+ set-returning function (Stephen Frost, Tom Lane)
+ </para>
+
+ <para>
+ If a set-returning SQL-language function refers to a table having
+ row-level security policies, and it can be inlined into a calling
+ query, those RLS policies would not get enforced properly in some
+ cases involving re-using a cached plan under a different role.
+ This could allow a user to see or modify rows that should have been
+ invisible.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> Project thanks
+ Wolfgang Walther for reporting this problem.
+ (CVE-2023-2455)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [8a8661828] 2023-02-22 10:14:52 +0900
+Branch: REL_15_STABLE [fa5dd460c] 2023-02-22 10:14:56 +0900
+-->
+ <para>
+ Fix potential corruption of the template (source) database after
+ <command>CREATE DATABASE</command> with the <literal>STRATEGY
+ WAL_LOG</literal> option (Nathan Bossart, Ryo Matsumura)
+ </para>
+
+ <para>
+ Improper buffer handling created a risk that any later modification
+ of the template's <structname>pg_class</structname> catalog would be
+ lost.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [5df319f3d] 2023-03-22 09:20:34 -0700
+Branch: REL_15_STABLE [560bb56c6] 2023-03-22 09:26:23 -0700
+-->
+ <para>
+ Fix memory leakage and unnecessary disk reads
+ during <command>CREATE DATABASE</command> with the <literal>STRATEGY
+ WAL_LOG</literal> option (Andres Freund)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [4dadd660f] 2023-04-28 19:29:12 +0900
+Branch: REL_15_STABLE [b9ad73ad2] 2023-04-28 19:29:36 +0900
+Branch: REL_14_STABLE [d29eba198] 2023-04-28 19:29:38 +0900
+Branch: REL_13_STABLE [7e95a33b4] 2023-04-28 19:29:40 +0900
+Branch: REL_12_STABLE [63f7e91ec] 2023-04-28 19:29:42 +0900
+Branch: REL_11_STABLE [a9212716b] 2023-04-28 19:29:44 +0900
+-->
+ <para>
+ Avoid crash when the new schema name is omitted
+ in <command>CREATE SCHEMA</command> (Michael Paquier)
+ </para>
+
+ <para>
+ The SQL standard allows writing <literal>CREATE SCHEMA AUTHORIZATION
+ <replaceable>owner_name</replaceable></literal>, with the schema
+ name defaulting to <replaceable>owner_name</replaceable>. However
+ some code paths expected the schema name to be present and would
+ fail.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [326a33a28] 2023-03-28 11:39:24 -0400
+Branch: REL_15_STABLE [bf5c4b3d9] 2023-03-28 11:36:50 -0400
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [e3ac85014] 2023-03-15 11:59:18 -0400
+Branch: REL_15_STABLE [3908d6ae1] 2023-03-15 11:59:18 -0400
+-->
+ <para>
+ Fix various planner failures with <command>MERGE</command>
+ commands (Tom Lane)
+ </para>
+
+ <para>
+ Planning could fail with errors like <quote>variable not found in
+ subplan target list</quote> or <quote>PlaceHolderVar found where not
+ expected</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [7b14e20b1] 2023-03-13 11:12:20 +0000
+Branch: REL_15_STABLE [da6257eee] 2023-03-13 11:11:10 +0000
+Branch: master [80a48e0f2] 2023-02-22 09:39:09 +0000
+Branch: REL_15_STABLE [018af1cc1] 2023-02-22 09:41:28 +0000
+-->
+ <para>
+ Fix the row count reported by <command>MERGE</command> for some
+ corner cases (Dean Rasheed)
+ </para>
+
+ <para>
+ The row count reported in the command tag counted rows that actually
+ hadn't been modified due to a <literal>BEFORE ROW</literal> trigger
+ returning NULL. This is inconsistent with what happens in
+ plain <command>UPDATE</command> or <command>DELETE</command>, so
+ change it to not count such rows. Also, avoid counting a row twice
+ when <command>MERGE</command> moves it into a different partition of
+ a partitioned table.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [9321c79c8] 2023-03-13 10:22:22 +0000
+Branch: REL_15_STABLE [7d9a75713] 2023-03-13 10:23:42 +0000
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [fd923b5de] 2023-02-15 20:37:44 +0100
+Branch: REL_15_STABLE [5d8ec1b9f] 2023-02-15 20:37:44 +0100
+-->
+ <para>
+ Fix <command>MERGE</command> problems with concurrent updates
+ (Dean Rasheed, &Aacute;lvaro Herrera)
+ </para>
+
+ <para>
+ Some cases misbehaved if a row to be updated or deleted
+ by <command>MERGE</command> had just been updated by a concurrent
+ transaction. This could lead to a crash, or the wrong merge action
+ being executed, or no action at all.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [41e2c52fd] 2023-05-07 11:01:15 -0400
+Branch: REL_15_STABLE [f200b9695] 2023-05-07 11:01:15 -0400
+-->
+ <para>
+ Add support for decompiling <command>MERGE</command>
+ commands (&Aacute;lvaro Herrera)
+ </para>
+
+ <para>
+ This was overlooked when <command>MERGE</command> was added, but
+ it's essential support for <command>MERGE</command> in new-style SQL
+ functions.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [6949b921d] 2023-03-04 13:32:35 -0500
+Branch: REL_15_STABLE [f61e60102] 2023-03-04 13:32:35 -0500
+-->
+ <para>
+ Fix enabling/disabling of foreign-key triggers in partitioned tables
+ (Tom Lane)
+ </para>
+
+ <para>
+ <command>ALTER TABLE ... ENABLE/DISABLE TRIGGER</command> failed if
+ applied to a partitioned table's foreign-key enforcement triggers,
+ because it tried to locate the clone triggers for the partitions by
+ name, and they do not have the same name. Locate them by
+ parent-trigger OID instead.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [a3c9d35ae] 2023-03-27 15:04:15 -0400
+Branch: REL_15_STABLE [d90d59e25] 2023-03-27 15:04:02 -0400
+Branch: REL_14_STABLE [334cc4c96] 2023-03-27 15:04:02 -0400
+Branch: REL_13_STABLE [29a20ff06] 2023-03-27 15:04:02 -0400
+Branch: REL_12_STABLE [cd07163c0] 2023-03-27 15:04:02 -0400
+Branch: REL_11_STABLE [78838bc3d] 2023-03-27 15:04:02 -0400
+-->
+ <para>
+ Disallow altering composite types that are stored in indexes
+ (Tom Lane)
+ </para>
+
+ <para>
+ <command>ALTER TYPE</command> disallows non-binary-compatible
+ modifications of composite types if they are stored in any table
+ columns. (Perhaps that will be allowed someday, but it hasn't
+ happened yet; the locking implications of rewriting many tables are
+ daunting.) We overlooked the possibility that an index might
+ contain a composite type that doesn't also appear in its table.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [f0d65c0ea] 2023-03-31 11:18:49 -0400
+Branch: REL_15_STABLE [6e3698173] 2023-03-31 11:18:49 -0400
+Branch: REL_14_STABLE [b0b55d8b8] 2023-03-31 11:18:49 -0400
+Branch: REL_13_STABLE [bfb993b1b] 2023-03-31 11:18:49 -0400
+Branch: REL_12_STABLE [e8d74aac5] 2023-03-31 11:18:49 -0400
+-->
+ <para>
+ Disallow system columns as elements of foreign keys (Tom Lane)
+ </para>
+
+ <para>
+ Since the removal of OID as a system column, there is no plausible
+ use-case for this, and various bits of code no longer support it.
+ Disallow it rather than trying to fix all the cases.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [d66bb048c] 2023-03-10 13:52:44 -0500
+Branch: REL_15_STABLE [59947bac7] 2023-03-10 13:52:28 -0500
+Branch: REL_14_STABLE [53a53ea33] 2023-03-10 13:52:28 -0500
+Branch: REL_13_STABLE [866fd004d] 2023-03-10 13:52:28 -0500
+Branch: REL_12_STABLE [a30310833] 2023-03-10 13:52:28 -0500
+Branch: REL_11_STABLE [6e2674d77] 2023-03-10 13:52:28 -0500
+-->
+ <para>
+ Ensure that <command>COPY TO</command> from an RLS-enabled parent
+ table does not copy any rows from child tables (Antonin Houska)
+ </para>
+
+ <para>
+ The documentation is quite clear that <command>COPY TO</command>
+ copies rows from only the named table, not any inheritance children
+ it may have. However, if row-level security was enabled on the table
+ then this stopped being true.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [4c40995f6] 2023-05-04 11:48:23 -0400
+Branch: REL_15_STABLE [ccb479e76] 2023-05-04 11:48:23 -0400
+Branch: REL_14_STABLE [d5de344a5] 2023-05-04 11:48:23 -0400
+Branch: REL_13_STABLE [9a72f499a] 2023-05-04 11:48:23 -0400
+Branch: REL_12_STABLE [580df5078] 2023-05-04 11:48:23 -0400
+Branch: REL_11_STABLE [4624aad61] 2023-05-04 11:48:23 -0400
+-->
+ <para>
+ Avoid possible crash when <function>array_position()</function>
+ or <function>array_positions()</function> is passed an empty array
+ (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [b081fe419] 2023-03-14 19:17:31 -0400
+Branch: REL_15_STABLE [a67c75f82] 2023-03-14 19:17:31 -0400
+Branch: REL_14_STABLE [7cac19105] 2023-03-14 19:17:31 -0400
+Branch: REL_13_STABLE [386a26023] 2023-03-14 19:17:31 -0400
+Branch: REL_12_STABLE [6d3a9a60f] 2023-03-14 19:17:31 -0400
+Branch: REL_11_STABLE [8e33fb9ef] 2023-03-14 19:17:31 -0400
+-->
+ <para>
+ Fix possible out-of-bounds fetch in <function>to_char()</function>
+ (Tom Lane)
+ </para>
+
+ <para>
+ With bad luck this could have resulted in a server crash.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [d7056bc1c] 2023-03-01 11:30:31 -0500
+Branch: REL_15_STABLE [eae09137d] 2023-03-01 11:30:17 -0500
+Branch: REL_14_STABLE [1a9356f65] 2023-03-01 11:30:17 -0500
+Branch: REL_13_STABLE [3b37e8442] 2023-03-01 11:30:17 -0500
+Branch: REL_12_STABLE [b162660d3] 2023-03-01 11:30:17 -0500
+Branch: REL_11_STABLE [b1a9d8ef2] 2023-03-01 11:30:17 -0500
+-->
+ <para>
+ Avoid buffer overread in <function>translate()</function> function
+ (Daniil Anisimov)
+ </para>
+
+ <para>
+ When using the deletion feature, the function might fetch the byte
+ just after the input string, creating a small risk of crash.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+Branch: master [f413941f4] 2023-03-17 12:08:46 -0700
+Branch: REL_15_STABLE [8b87e9291] 2023-03-17 12:07:47 -0700
+-->
+ <para>
+ Adjust text-search-related character classification logic to
+ correctly detect whether the prevailing locale
+ is <literal>C</literal> (Jeff Davis)
+ </para>
+
+ <para>
+ This code got confused if the database's default collation uses ICU.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [5e80d3515] 2023-02-12 12:50:55 -0500
+Branch: REL_15_STABLE [0ef65d0f5] 2023-02-12 12:50:55 -0500
+-->
+ <para>
+ Avoid possible crash on empty input for type <type>interval</type>
+ (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [f0d0394e8] 2023-02-20 16:55:59 -0500
+Branch: REL_15_STABLE [ded5ede27] 2023-02-20 16:55:59 -0500
+-->
+ <para>
+ Re-allow exponential notation in ISO-8601 interval fields
+ (Tom Lane)
+ </para>
+
+ <para>
+ Interval input like <literal>P0.1e10D</literal> isn't officially
+ sanctioned by ISO-8601, but we accepted it for a long time before
+ version 15, so re-allow it.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [25a7812cd] 2023-03-13 15:19:00 -0400
+Branch: REL_15_STABLE [74a1a36d7] 2023-03-13 15:19:00 -0400
+Branch: REL_14_STABLE [0ee9d685d] 2023-03-13 15:19:00 -0400
+Branch: REL_13_STABLE [52e9a7816] 2023-03-13 15:19:00 -0400
+Branch: REL_12_STABLE [c25a929a6] 2023-03-13 15:19:00 -0400
+Branch: REL_11_STABLE [234941a3b] 2023-03-13 15:19:00 -0400
+-->
+ <para>
+ Fix error cursor setting for parse errors in JSON string literals
+ (Tom Lane)
+ </para>
+
+ <para>
+ Most cases in which a syntax error is detected in a string literal
+ within a JSON value failed to set the error cursor appropriately.
+ This led at least to an unhelpful error message (pointing to the
+ token before the string, rather than the actual trouble spot), and
+ could even result in a crash in v14 and later.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [be504a3e9] 2023-03-07 21:52:32 -0800
+Branch: REL_15_STABLE [391f08fd6] 2023-03-07 21:36:48 -0800
+Branch: REL_14_STABLE [324281fd5] 2023-03-07 21:36:49 -0800
+Branch: REL_13_STABLE [e6d77f22c] 2023-03-07 21:36:51 -0800
+Branch: REL_12_STABLE [3c92f7e9d] 2023-03-07 21:36:52 -0800
+-->
+ <para>
+ Fix data corruption due to <varname>vacuum_defer_cleanup_age</varname>
+ being larger than the current 64-bit xid (Andres Freund)
+ </para>
+
+ <para>
+ In v14 and later with non-default settings
+ of <varname>vacuum_defer_cleanup_age</varname>, it was possible to
+ compute a very large vacuum cleanup horizon xid, leading to vacuum
+ removing rows that are still live. v12 and v13 have a lesser form
+ of the same problem affecting only GiST indexes, which could lead to
+ index pages getting recycled too early.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [30dbdbe75] 2023-03-13 12:40:28 -0400
+Branch: REL_15_STABLE [5fd61bdc1] 2023-03-13 12:40:28 -0400
+Branch: REL_14_STABLE [096e70805] 2023-03-13 12:40:28 -0400
+Branch: REL_13_STABLE [bc0bcce2e] 2023-03-13 12:40:28 -0400
+Branch: REL_12_STABLE [62a91a1b0] 2023-03-13 12:40:28 -0400
+Branch: REL_11_STABLE [0736b1131] 2023-03-13 12:40:28 -0400
+-->
+ <para>
+ Fix parser's failure to detect some cases of improperly-nested
+ aggregates (Tom Lane)
+ </para>
+
+ <para>
+ This oversight could lead to executor failures for queries that
+ should have been rejected as invalid.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [6c3b697b1] 2023-03-31 12:13:05 +1300
+Branch: REL_15_STABLE [df567fbf6] 2023-03-31 12:13:34 +1300
+Branch: REL_14_STABLE [211016220] 2023-03-31 12:14:04 +1300
+Branch: REL_13_STABLE [8d684c445] 2023-03-31 12:14:31 +1300
+Branch: REL_12_STABLE [33510bc64] 2023-03-31 12:15:07 +1300
+Branch: REL_11_STABLE [07554c99d] 2023-03-31 12:15:39 +1300
+-->
+ <para>
+ Fix data structure corruption during parsing of
+ serial <literal>SEQUENCE NAME</literal> options (David Rowley)
+ </para>
+
+ <para>
+ This can lead to trouble if an event trigger captures the corrupted
+ parse tree.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [88ceac5d7] 2023-04-12 10:46:38 -0400
+Branch: REL_15_STABLE [f4badbcf4] 2023-04-12 10:46:30 -0400
+Branch: REL_14_STABLE [0dd55ef9b] 2023-04-12 10:46:30 -0400
+Branch: REL_13_STABLE [96c698e3f] 2023-04-12 10:46:30 -0400
+Branch: REL_12_STABLE [953ff99c2] 2023-04-12 10:46:30 -0400
+Branch: REL_11_STABLE [60c8aeaf6] 2023-04-12 10:46:30 -0400
+-->
+ <para>
+ Correctly update plan nodes' parallel-safety markings when moving
+ initplans from one node to another (Tom Lane)
+ </para>
+
+ <para>
+ This planner oversight could lead to <quote>subplan was not
+ initialized</quote> errors at runtime.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [684ffac8c] 2023-03-14 11:10:45 -0400
+Branch: REL_15_STABLE [3b4594443] 2023-03-14 11:10:45 -0400
+Branch: REL_14_STABLE [7c509f7e5] 2023-03-14 11:10:45 -0400
+-->
+ <para>
+ Avoid failure with PlaceHolderVars in extended-statistics code
+ (Tom Lane)
+ </para>
+
+ <para>
+ Use of dependency-type extended statistics could fail with
+ <quote>PlaceHolderVar found where not expected</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [eb7d043c9] 2023-03-17 15:49:53 +1300
+Branch: REL_15_STABLE [371e3daaa] 2023-03-17 15:51:00 +1300
+-->
+ <para>
+ Fix incorrect tests for whether a qual clause applied to a subquery
+ can be transformed into a window aggregate <quote>run
+ condition</quote> within the subquery (David Rowley)
+ </para>
+
+ <para>
+ A SubPlan within such a clause would cause assertion failures or
+ incorrect answers, as would some other unusual cases.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [836c31ba5] 2023-02-13 17:11:03 +1300
+Branch: REL_15_STABLE [a9fa6d79a] 2023-02-13 17:10:31 +1300
+Branch: REL_14_STABLE [4aa43ba21] 2023-02-13 17:09:55 +1300
+Branch: REL_13_STABLE [301eb3ee4] 2023-02-13 17:09:26 +1300
+Branch: REL_12_STABLE [ac55abd33] 2023-02-13 17:08:46 +1300
+Branch: REL_11_STABLE [8d2a8581b] 2023-02-13 17:07:04 +1300
+-->
+ <para>
+ Disable the inverse-transition optimization for window aggregates
+ when the call contains sub-SELECTs (David Rowley)
+ </para>
+
+ <para>
+ This optimization requires that the aggregate's argument expressions
+ have repeatable results, which might not hold for a sub-SELECT.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [554841699] 2023-03-26 13:41:06 -0400
+Branch: REL_15_STABLE [7c4873438] 2023-03-26 13:41:06 -0400
+Branch: REL_14_STABLE [11213d446] 2023-03-26 13:41:06 -0400
+Branch: REL_13_STABLE [1bbbe1460] 2023-03-26 13:41:06 -0400
+Branch: REL_12_STABLE [ad5fe7420] 2023-03-26 13:41:06 -0400
+Branch: REL_11_STABLE [ae320fc21] 2023-03-26 13:41:06 -0400
+-->
+ <para>
+ Fix oversights in execution of nested <literal>ARRAY[]</literal>
+ constructs (Alexander Lakhin, Tom Lane)
+ </para>
+
+ <para>
+ Correctly detect overflow of the total space needed for the result
+ array, avoiding a possible crash due to undersized output
+ allocation. Also ensure that any trailing padding space in the
+ result array is zeroed; while leaving garbage there is harmless for
+ most purposes, it can result in odd behavior later.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [064eb89e8] 2023-04-15 12:01:39 -0400
+Branch: REL_15_STABLE [c53ed26ea] 2023-04-15 12:01:39 -0400
+Branch: REL_14_STABLE [9b104a27c] 2023-04-15 12:01:39 -0400
+Branch: REL_13_STABLE [7428aecdd] 2023-04-15 12:01:39 -0400
+Branch: REL_12_STABLE [048caf8d7] 2023-04-15 12:01:39 -0400
+-->
+ <para>
+ Prevent crash when updating a field within an
+ array-of-domain-over-composite-type column (Dmitry Dolgov)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [e0693faf7] 2023-04-14 16:20:27 +1200
+Branch: REL_15_STABLE [0c09160e1] 2023-04-14 16:21:07 +1200
+Branch: REL_14_STABLE [ae85fb828] 2023-04-14 16:21:42 +1200
+Branch: REL_13_STABLE [6848f0c67] 2023-04-14 16:22:11 +1200
+Branch: REL_12_STABLE [0b2e77ce2] 2023-04-14 16:22:46 +1200
+Branch: REL_11_STABLE [1c19e2863] 2023-04-14 16:23:11 +1200
+-->
+ <para>
+ Fix partition pruning logic for partitioning on boolean columns
+ (David Rowley)
+ </para>
+
+ <para>
+ Pruning with a condition like <literal>boolcol IS NOT TRUE</literal>
+ was done incorrectly, leading to possibly not returning rows in
+ which <literal>boolcol</literal> is NULL. Also, the rather unlikely
+ case of partitioning on <literal>NOT boolcol</literal> was handled
+ incorrectly.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [8d578b9b2] 2023-03-21 14:29:34 +1300
+Branch: REL_15_STABLE [c03c6e8cf] 2023-03-21 14:32:14 +1300
+Branch: REL_14_STABLE [1b9e42e82] 2023-03-21 14:37:33 +1300
+Branch: REL_13_STABLE [6e94d62e3] 2023-03-21 14:38:59 +1300
+Branch: REL_12_STABLE [44d44aa97] 2023-03-21 14:41:35 +1300
+Branch: REL_11_STABLE [ef16d2724] 2023-03-21 14:43:07 +1300
+-->
+ <para>
+ Fix race condition in per-batch cleanup during parallel hash join
+ (Thomas Munro, Melanie Plageman)
+ </para>
+
+ <para>
+ A crash was possible given unlucky timing and
+ <varname>parallel_leader_participation</varname>
+ = <literal>off</literal> (which is not the default).
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [7fee7871b] 2023-03-06 18:31:27 -0500
+Branch: REL_15_STABLE [70ef50954] 2023-03-06 18:31:16 -0500
+Branch: REL_14_STABLE [1e05ea51d] 2023-03-06 18:31:16 -0500
+Branch: REL_13_STABLE [4a94cbd02] 2023-03-06 18:31:16 -0500
+Branch: REL_12_STABLE [23b75dd03] 2023-03-06 18:31:16 -0500
+-->
+ <para>
+ Recalculate <literal>GENERATED</literal> columns after an
+ EvalPlanQual check (Tom Lane)
+ </para>
+
+ <para>
+ In <literal>READ COMMITTED</literal> isolation mode, the effects of
+ a row update might need to get reapplied to a newer version of the
+ row than the query found originally. If so, we need to recompute
+ any <literal>GENERATED</literal> columns, in case they depend on
+ columns that were changed by the concurrent update.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [579ee5df1] 2023-03-20 13:28:47 +1300
+Branch: REL_15_STABLE [8de4660a5] 2023-03-20 13:30:15 +1300
+Branch: REL_14_STABLE [f654f343c] 2023-03-20 13:30:55 +1300
+-->
+ <para>
+ Fix memory leak in Memoize plan execution (David Rowley)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [806fad757] 2023-04-25 09:42:19 +0900
+Branch: REL_15_STABLE [aa6177c88] 2023-04-25 09:42:33 +0900
+Branch: REL_14_STABLE [4cc56f8ed] 2023-04-25 09:42:36 +0900
+-->
+ <para>
+ Fix buffer refcount leak when using batched inserts for a foreign
+ table included in a partitioned tree (Alexander Pyhalov)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [720de00af] 2023-03-15 13:58:18 +1300
+Branch: REL_15_STABLE [d9c9c43af] 2023-03-15 14:02:49 +1300
+Branch: REL_14_STABLE [2bef57ee8] 2023-03-15 14:05:27 +1300
+-->
+ <para>
+ Restore support for
+ sub-millisecond <varname>vacuum_cost_delay</varname> settings
+ (Thomas Munro)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Daniel Gustafsson <dgustafsson@postgresql.org>
+Branch: master [bfac8f8bc] 2023-04-25 13:54:10 +0200
+Branch: REL_15_STABLE [0319b306e] 2023-04-25 13:54:10 +0200
+Branch: REL_14_STABLE [0e8e5e856] 2023-04-25 13:54:10 +0200
+Branch: REL_13_STABLE [b95f36f86] 2023-04-25 13:54:10 +0200
+Branch: REL_12_STABLE [cba3c8f6d] 2023-04-25 13:54:10 +0200
+Branch: REL_11_STABLE [0151d2c5f] 2023-04-25 13:54:10 +0200
+-->
+ <para>
+ Don't balance vacuum cost delay when a table has a
+ per-relation <varname>vacuum_cost_delay</varname> setting of zero
+ (Masahiko Sawada)
+ </para>
+
+ <para>
+ Delay balancing is supposed to be disabled whenever autovacuum is
+ processing a table with a
+ per-relation <varname>vacuum_cost_delay</varname> setting, but this
+ was done only for positive settings, not zero.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [99be6feec] 2023-03-07 18:21:53 -0500
+Branch: REL_15_STABLE [76d2177fb] 2023-03-07 18:21:53 -0500
+Branch: REL_14_STABLE [9f1e51b59] 2023-03-07 18:21:37 -0500
+Branch: REL_13_STABLE [695b34ab3] 2023-03-07 18:21:37 -0500
+Branch: REL_12_STABLE [5a19da58e] 2023-03-07 18:21:37 -0500
+Branch: REL_11_STABLE [721626cb5] 2023-03-07 18:21:37 -0500
+-->
+ <para>
+ Fix corner-case crashes when columns have been added to the end of a
+ view (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [87f3667ec] 2023-02-25 14:44:14 -0500
+Branch: REL_15_STABLE [a033f9165] 2023-02-25 14:44:14 -0500
+Branch: REL_14_STABLE [9eaba0602] 2023-02-25 14:44:14 -0500
+Branch: REL_13_STABLE [1e199c259] 2023-02-25 14:44:14 -0500
+Branch: REL_12_STABLE [904b171a4] 2023-02-25 14:44:14 -0500
+Branch: REL_11_STABLE [ffec64ba8] 2023-02-25 14:44:14 -0500
+-->
+ <para>
+ Repair rare failure of MULTIEXPR_SUBLINK subplans in partitioned
+ updates (Andres Freund, Tom Lane)
+ </para>
+
+ <para>
+ Use of the syntax <literal>INSERT ... ON CONFLICT DO UPDATE SET (c1,
+ ...) = (SELECT ...)</literal> with a partitioned target table could
+ result in failure if any child table is dissimilar from the parent
+ (for example, different physical column order).
+ This typically manifested as failure of consistency checks in the
+ executor; but a crash or incorrect data updates are also possible.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [75c737636] 2023-02-23 10:53:01 +0000
+Branch: REL_15_STABLE [940b54743] 2023-02-23 10:54:51 +0000
+Branch: REL_14_STABLE [f0423bea7] 2023-02-23 10:55:48 +0000
+Branch: REL_13_STABLE [226da3d47] 2023-02-23 10:56:41 +0000
+Branch: REL_12_STABLE [98b83b734] 2023-02-23 10:57:46 +0000
+Branch: REL_11_STABLE [e68b133c3] 2023-02-23 10:58:43 +0000
+-->
+ <para>
+ Fix handling of <literal>DEFAULT</literal> markers within a
+ multi-row <literal>INSERT ... VALUES</literal> query on a view that
+ has a <literal>DO ALSO INSERT ... SELECT</literal> rule (Dean
+ Rasheed)
+ </para>
+
+ <para>
+ Such cases typically failed with <quote>unrecognized node
+ type</quote> errors or assertion failures.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [a7d71c41d] 2023-02-25 14:41:12 +0000
+Branch: REL_15_STABLE [8e5b4e001] 2023-02-25 14:43:57 +0000
+Branch: REL_14_STABLE [27ff93d18] 2023-02-25 14:44:49 +0000
+Branch: REL_13_STABLE [39ad791e8] 2023-02-25 14:45:44 +0000
+Branch: REL_12_STABLE [4fd093af7] 2023-02-25 14:47:03 +0000
+Branch: REL_11_STABLE [79f194cc0] 2023-02-25 14:48:08 +0000
+-->
+ <para>
+ Support references to <literal>OLD</literal>
+ and <literal>NEW</literal> within subqueries in rule actions
+ (Dean Rasheed, Tom Lane)
+ </para>
+
+ <para>
+ Such references are really lateral references, but the server could
+ crash if the subquery wasn't explicitly marked
+ with <literal>LATERAL</literal>. Arrange to do that implicitly when
+ necessary.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [393430f57] 2023-02-17 16:40:34 -0500
+Branch: REL_15_STABLE [c8a5f1685] 2023-02-17 16:40:34 -0500
+Branch: REL_14_STABLE [14345f3c6] 2023-02-17 16:40:34 -0500
+Branch: REL_13_STABLE [4efb4f0d4] 2023-02-17 16:40:34 -0500
+Branch: REL_12_STABLE [3dd287c14] 2023-02-17 16:40:34 -0500
+Branch: REL_11_STABLE [df931e9ab] 2023-02-17 16:40:34 -0500
+-->
+ <para>
+ When decompiling a rule or SQL function body
+ containing <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>
+ within <command>WITH</command>, take care to print the correct alias
+ for the target table (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [47c0accbe] 2023-03-06 15:07:15 +1300
+Branch: REL_15_STABLE [055990904] 2023-03-06 16:05:47 +1300
+Branch: REL_14_STABLE [e9051ecd5] 2023-03-06 16:17:22 +1300
+Branch: REL_13_STABLE [a0f55fc86] 2023-03-06 16:28:34 +1300
+Branch: REL_12_STABLE [afa122e41] 2023-03-06 16:41:34 +1300
+Branch: master [65e388d41] 2023-03-09 16:33:24 +1300
+Branch: REL_15_STABLE [af397c6c2] 2023-03-09 16:56:51 +1300
+Branch: REL_14_STABLE [d811d74be] 2023-03-09 16:57:11 +1300
+Branch: REL_13_STABLE [ae632f7a3] 2023-03-09 17:09:57 +1300
+Branch: REL_12_STABLE [e30fd0942] 2023-03-09 17:25:20 +1300
+Branch: REL_11_STABLE [d1c0f81e7] 2023-03-09 17:26:06 +1300
+-->
+ <para>
+ Fix glitches in <literal>SERIALIZABLE READ ONLY</literal>
+ optimization (Thomas Munro)
+ </para>
+
+ <para>
+ Transactions already marked as <quote>doomed</quote> confused the
+ safe-snapshot optimization for <literal>SERIALIZABLE READ
+ ONLY</literal> transactions. The optimization was unnecessarily
+ skipped in some cases. In other cases an assertion failure occurred
+ (but there was no problem in non-assert builds).
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [05172f1f3] 2023-02-23 15:40:42 -0500
+Branch: REL_15_STABLE [cef1c9c0c] 2023-02-23 15:40:28 -0500
+Branch: REL_14_STABLE [0f78df719] 2023-02-23 15:40:28 -0500
+Branch: REL_13_STABLE [861e9e486] 2023-02-23 15:40:28 -0500
+Branch: REL_12_STABLE [95558bc8f] 2023-02-23 15:40:28 -0500
+Branch: REL_11_STABLE [44dbc960f] 2023-02-23 15:40:28 -0500
+-->
+ <para>
+ Avoid leaking cache callback slots in
+ the <literal>pgoutput</literal> logical decoding plugin (Shi Yu)
+ </para>
+
+ <para>
+ Multiple cycles of starting up and shutting down the plugin within a
+ single session would eventually lead to an <quote>out of
+ relcache_callback_list slots</quote> error.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alexander Korotkov <akorotkov@postgresql.org>
+Branch: master [cd115c353] 2023-04-23 13:58:41 +0300
+Branch: REL_15_STABLE [6e7361c85] 2023-04-23 14:00:06 +0300
+Branch: REL_14_STABLE [9ef5a3583] 2023-04-23 14:00:13 +0300
+Branch: REL_13_STABLE [02191136c] 2023-04-23 14:00:16 +0300
+-->
+ <para>
+ Avoid unnecessary calls to custom validators for index operator
+ class options (Alexander Korotkov)
+ </para>
+
+ <para>
+ This change fixes some cases where an unexpected error was thrown.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master [e72910f80] 2023-02-19 01:46:58 +0100
+Branch: REL_15_STABLE [305d89ad9] 2023-02-19 01:48:04 +0100
+Branch: REL_14_STABLE [f3daa3116] 2023-02-19 01:48:22 +0100
+-->
+ <para>
+ Avoid useless work while scanning a multi-column BRIN index with
+ multiple scan keys (Tomas Vondra)
+ </para>
+
+ <para>
+ The existing code effectively considered only the last scan key
+ while deciding whether a range matched, thus usually scanning more
+ of the index than it needed to.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master [e85831268] 2023-03-20 10:24:14 +0100
+Branch: REL_15_STABLE [0c7726c28] 2023-03-20 10:20:35 +0100
+Branch: REL_14_STABLE [6a78a42fe] 2023-03-20 10:16:54 +0100
+-->
+ <para>
+ Fix netmask handling in BRIN inet_minmax_multi_ops opclass
+ (Tomas Vondra)
+ </para>
+
+ <para>
+ This error triggered an assertion failure in assert-enabled builds,
+ but is mostly harmless in production builds.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [8e5eef50c] 2023-03-29 11:31:30 -0400
+Branch: REL_15_STABLE [2dc77adc7] 2023-03-29 11:31:30 -0400
+Branch: REL_14_STABLE [a1904c9ce] 2023-03-29 11:31:30 -0400
+Branch: REL_13_STABLE [2adb6adad] 2023-03-29 11:31:30 -0400
+Branch: REL_12_STABLE [d2a1d4b19] 2023-03-29 11:31:30 -0400
+Branch: REL_11_STABLE [b5c6776c1] 2023-03-29 11:31:30 -0400
+-->
+ <para>
+ Fix dereference of dangling pointer during buffering build of a GiST
+ index (Alexander Lakhin)
+ </para>
+
+ <para>
+ This error seems to usually be harmless in production builds, as the
+ fetched value is noncritical; but in principle it could cause a
+ server crash.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [adedf54e6] 2023-03-23 11:58:36 +0530
+Branch: REL_15_STABLE [b6bf90edc] 2023-03-23 11:46:16 +0530
+Branch: REL_14_STABLE [9dac02c77] 2023-03-23 11:32:22 +0530
+Branch: REL_13_STABLE [be52fff91] 2023-03-23 11:21:13 +0530
+Branch: REL_12_STABLE [0f2d4adbf] 2023-03-23 11:08:38 +0530
+Branch: master [b797def59] 2023-03-21 09:47:21 +0530
+Branch: REL_15_STABLE [3c12407f4] 2023-03-21 09:40:41 +0530
+Branch: REL_14_STABLE [65ead7696] 2023-03-21 09:18:51 +0530
+Branch: REL_13_STABLE [751d6676d] 2023-03-21 09:07:37 +0530
+Branch: REL_12_STABLE [fc63e6ba8] 2023-03-21 08:50:23 +0530
+Branch: REL_11_STABLE [4cdaea7a2] 2023-03-21 08:39:00 +0530
+-->
+ <para>
+ Ignore dropped columns and generated columns during logical
+ replication of an update or delete action (Onder Kalaci, Shi Yu)
+ </para>
+
+ <para>
+ Replication with the <literal>REPLICA IDENTITY FULL</literal> option
+ failed if the table contained such columns.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [58f5edf84] 2023-05-05 21:25:44 +0900
+Branch: REL_15_STABLE [d31dab9a5] 2023-05-05 21:25:50 +0900
+Branch: REL_14_STABLE [ae4ffa722] 2023-05-05 21:25:56 +0900
+Branch: REL_13_STABLE [cedcc4191] 2023-05-05 21:26:02 +0900
+-->
+ <para>
+ Correct the name of the wait event for SLRU buffer I/O for commit
+ timestamps (Alexander Lakhin)
+ </para>
+
+ <para>
+ This wait event is named <literal>CommitTsBuffer</literal> according
+ to the documentation, but the code had it
+ as <literal>CommitTSBuffer</literal>. Change the code to match the
+ documentation, as that way is more consistent with the naming of
+ related wait events.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [84cc14267] 2023-04-26 07:10:06 +0900
+Branch: REL_15_STABLE [1ed1b84bd] 2023-04-26 07:30:42 +0900
+Branch: REL_14_STABLE [aeb6f4b3b] 2023-04-26 07:30:47 +0900
+-->
+ <para>
+ Re-activate reporting of wait event <literal>SLRUFlushSync</literal>
+ (Thomas Munro)
+ </para>
+
+ <para>
+ Reporting of this type of wait was accidentally removed in code
+ refactoring.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Nathan Bossart <nathan@postgresql.org>
+Branch: master [b72623671] 2023-04-27 14:31:17 -0700
+Branch: REL_15_STABLE [c98b06e2f] 2023-04-27 14:31:33 -0700
+Branch: REL_14_STABLE [137003036] 2023-04-27 14:32:40 -0700
+Branch: REL_13_STABLE [be40dd63e] 2023-04-27 14:32:55 -0700
+-->
+ <para>
+ Avoid possible underflow when calculating how many WAL segments to
+ keep (Kyotaro Horiguchi)
+ </para>
+
+ <para>
+ This could result in not honoring <varname>wal_keep_size</varname>
+ accurately.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+Branch: master [8a2f783cc] 2023-02-06 10:51:08 -0500
+Branch: REL_15_STABLE [ecb01e6eb] 2023-02-10 16:27:05 -0500
+-->
+ <para>
+ Disable startup progress reporting overhead in standby mode
+ (Bharath Rupireddy)
+ </para>
+
+ <para>
+ In standby mode, we don't actually report progress of recovery,
+ but we were doing work to track it anyway.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [9244c11af] 2023-02-15 10:12:16 +0900
+Branch: REL_15_STABLE [5fd61055e] 2023-02-15 10:12:31 +0900
+Branch: REL_14_STABLE [864f80fea] 2023-02-15 10:12:33 +0900
+Branch: REL_13_STABLE [2eb8e54cc] 2023-02-15 10:12:36 +0900
+Branch: REL_12_STABLE [a40e7b75e] 2023-02-15 10:12:38 +0900
+Branch: REL_11_STABLE [88d606f7c] 2023-02-15 10:12:40 +0900
+-->
+ <para>
+ Support RSA-PSS certificates with SCRAM-SHA-256 channel binding
+ (Jacob Champion, Heikki Linnakangas)
+ </para>
+
+ <para>
+ This feature requires building with OpenSSL 1.1.1 or newer. Both
+ the server and <application>libpq</application> are affected.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [d41a178b3] 2023-03-15 13:24:47 +1300
+Branch: REL_15_STABLE [06066915d] 2023-03-15 13:25:56 +1300
+Branch: REL_14_STABLE [9b6e0b9c3] 2023-03-15 13:30:58 +1300
+Branch: REL_13_STABLE [9f1c64018] 2023-03-15 13:31:34 +1300
+Branch: REL_12_STABLE [836288427] 2023-03-15 13:32:21 +1300
+Branch: REL_11_STABLE [5ff8e69d8] 2023-03-15 13:32:41 +1300
+Branch: master [6a9229da6] 2023-03-17 10:44:46 +1300
+Branch: REL_15_STABLE [75e7378f6] 2023-03-17 10:45:20 +1300
+Branch: REL_14_STABLE [00fc4b3a3] 2023-03-17 09:52:45 +1300
+Branch: REL_13_STABLE [798dae9f6] 2023-03-17 09:54:03 +1300
+Branch: REL_12_STABLE [6f508b8bc] 2023-03-17 09:54:51 +1300
+Branch: REL_11_STABLE [9d6c34397] 2023-03-17 09:58:08 +1300
+Branch: master [10b6745d3] 2023-03-17 14:44:12 +1300
+Branch: REL_15_STABLE [e8a774d00] 2023-03-17 14:46:03 +1300
+Branch: REL_14_STABLE [1c0d4affa] 2023-03-17 14:46:50 +1300
+Branch: REL_13_STABLE [77a8133c9] 2023-03-17 14:47:16 +1300
+Branch: REL_12_STABLE [8fcd1517f] 2023-03-17 14:47:38 +1300
+Branch: REL_11_STABLE [b23f2a729] 2023-03-17 14:48:08 +1300
+-->
+ <para>
+ Avoid race condition with process ID tracking on Windows (Thomas Munro)
+ </para>
+
+ <para>
+ The operating system could recycle a PID before the postmaster
+ observed that that child process was gone. This could lead to
+ tracking more than one child with the same PID, resulting in
+ confusion.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [e35ded295] 2023-04-20 10:34:46 +1200
+Branch: REL_15_STABLE [63a03aea6] 2023-04-21 10:02:25 +1200
+-->
+ <para>
+ Fix <function>list_copy_head()</function> to work correctly on an
+ empty List (David Rowley)
+ </para>
+
+ <para>
+ This case is not known to be reached by any
+ core <productname>PostgreSQL</productname> code, but extensions
+ might rely on it working.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [d0460a31d] 2023-02-22 13:23:09 +0000
+Branch: REL_15_STABLE [576b25bfd] 2023-02-22 13:24:51 +0000
+Branch: REL_14_STABLE [482ab3e4f] 2023-02-22 13:26:20 +0000
+Branch: REL_13_STABLE [906356cf6] 2023-02-22 13:27:29 +0000
+Branch: REL_12_STABLE [52dbd9f84] 2023-02-22 13:28:30 +0000
+Branch: REL_11_STABLE [83a54d966] 2023-02-22 13:29:39 +0000
+-->
+ <para>
+ Add missing cases to <function>SPI_result_code_string()</function>
+ (Dean Rasheed)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [b3e184a5d] 2023-02-21 18:48:15 -0500
+Branch: REL_15_STABLE [f6a55c1d5] 2023-02-21 18:47:46 -0500
+Branch: REL_14_STABLE [dc44180f6] 2023-02-21 18:47:47 -0500
+Branch: REL_13_STABLE [99e74cd23] 2023-02-21 18:47:47 -0500
+Branch: REL_12_STABLE [463bef383] 2023-02-21 18:47:47 -0500
+Branch: REL_11_STABLE [21bd818d0] 2023-02-21 18:47:47 -0500
+-->
+ <para>
+ Fix erroneous Valgrind markings
+ in <function>AllocSetRealloc()</function> (Karina Litskevich)
+ </para>
+
+ <para>
+ In the unusual case where the size of a large (&gt;8kB) palloc chunk
+ is decreased, a Valgrind-aware build would mismark the defined-ness
+ state of the memory released from the chunk, possibly causing
+ incorrect results during Valgrind testing.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [0d3b49d4a] 2023-02-22 10:51:34 +0000
+Branch: REL_15_STABLE [d8c3b65db] 2023-02-22 10:54:57 +0000
+-->
+ <para>
+ Fix assertion failure for <command>MERGE</command> into a
+ partitioned table with row-level security enabled (Dean Rasheed)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master [7fe1aa991] 2023-02-22 15:24:18 +0100
+Branch: REL_15_STABLE [949ac32e1] 2023-02-22 16:48:30 +0100
+Branch: REL_14_STABLE [8b9cbd42b] 2023-02-22 16:25:45 +0100
+Branch: REL_13_STABLE [4df581fa0] 2023-02-22 16:09:30 +0100
+Branch: REL_12_STABLE [497f863f0] 2023-02-22 15:50:37 +0100
+Branch: REL_11_STABLE [8de91ebf2] 2023-02-22 15:35:19 +0100
+-->
+ <para>
+ Avoid assertion failure when decoding a transactional logical
+ replication message (Tomas Vondra)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+Branch: master [c04c6c5d6] 2023-04-21 08:19:41 -0700
+Branch: REL_15_STABLE [109363de0] 2023-04-21 08:20:17 -0700
+Branch: REL_14_STABLE [dde926b0f] 2023-04-21 08:20:32 -0700
+Branch: REL_13_STABLE [79a66c617] 2023-04-21 08:20:47 -0700
+Branch: REL_12_STABLE [5bcb15b81] 2023-04-21 08:21:04 -0700
+Branch: REL_11_STABLE [106a1bf82] 2023-04-21 08:21:18 -0700
+-->
+ <para>
+ Avoid locale sensitivity when processing regular expression escapes
+ (Jeff Davis)
+ </para>
+
+ <para>
+ A backslash followed by a non-ASCII character could sometimes cause
+ an assertion failure, depending on the prevailing locale.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [3e383f9b6] 2023-04-17 14:22:26 -0400
+Branch: REL_15_STABLE [2207df7c3] 2023-04-17 14:22:06 -0400
+Branch: REL_14_STABLE [72a914e9f] 2023-04-17 14:22:06 -0400
+Branch: REL_13_STABLE [86874a6df] 2023-04-17 14:22:06 -0400
+Branch: REL_12_STABLE [9b0c1f213] 2023-04-17 14:22:06 -0400
+Branch: REL_11_STABLE [c796d7296] 2023-04-17 14:22:06 -0400
+-->
+ <para>
+ Avoid trying to write an empty WAL record
+ in <function>log_newpage_range()</function> when the last few pages
+ in the specified range are empty (Matthias van de Meent)
+ </para>
+
+ <para>
+ It is not entirely clear whether this case is reachable in released
+ branches, but if it is then an assertion failure could occur.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [441ee1677] 2023-04-24 14:19:46 -0400
+Branch: REL_15_STABLE [c1598d85f] 2023-04-24 14:19:46 -0400
+Branch: REL_14_STABLE [2ba890ce7] 2023-04-24 14:19:46 -0400
+Branch: REL_13_STABLE [bfa691087] 2023-04-24 14:19:46 -0400
+Branch: REL_12_STABLE [ee71cad9a] 2023-04-24 14:19:46 -0400
+-->
+ <para>
+ Fix session-lifespan memory leakage in <application>plpgsql</application>
+ <literal>DO</literal> blocks that use cast expressions
+ (Ajit Awekar, Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [f47004add] 2023-04-29 13:06:44 -0400
+Branch: REL_15_STABLE [ce9a1a3ea] 2023-04-29 13:06:44 -0400
+Branch: REL_14_STABLE [1e868bb6c] 2023-04-29 13:06:44 -0400
+Branch: REL_13_STABLE [ee24b5e79] 2023-04-29 13:06:44 -0400
+Branch: REL_12_STABLE [900a8d526] 2023-04-29 13:06:44 -0400
+Branch: REL_11_STABLE [ea96fbe77] 2023-04-29 13:06:44 -0400
+-->
+ <para>
+ Tighten array dimensionality checks when converting Perl
+ list structures to multi-dimensional SQL arrays (Tom Lane)
+ </para>
+
+ <para>
+ <application>plperl</application> could misbehave when the nesting
+ of sub-lists is inconsistent so that the data does not represent a
+ rectangular array of values. Such cases now produce errors, but
+ previously they could result in a crash or garbage output.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [0553528e7] 2023-05-04 11:00:33 -0400
+Branch: REL_15_STABLE [b7001c6b6] 2023-05-04 11:00:33 -0400
+Branch: REL_14_STABLE [9d517339e] 2023-05-04 11:00:33 -0400
+Branch: REL_13_STABLE [0e6354ed9] 2023-05-04 11:00:33 -0400
+Branch: REL_12_STABLE [b7fcf3824] 2023-05-04 11:00:33 -0400
+Branch: REL_11_STABLE [aa7e5e404] 2023-05-04 11:00:33 -0400
+Branch: master [81eaaf65e] 2023-04-28 12:24:29 -0400
+Branch: REL_15_STABLE [512c55522] 2023-04-28 12:24:29 -0400
+Branch: REL_14_STABLE [a1d9aacc4] 2023-04-28 12:24:29 -0400
+Branch: REL_13_STABLE [7dcd9998c] 2023-04-28 12:24:29 -0400
+Branch: REL_12_STABLE [ff9203f46] 2023-04-28 12:24:29 -0400
+Branch: REL_11_STABLE [b7c6af375] 2023-04-28 12:24:29 -0400
+-->
+ <para>
+ Tighten array dimensionality checks when converting Python
+ list structures to multi-dimensional SQL arrays (Tom Lane)
+ </para>
+
+ <para>
+ <application>plpython</application> could misbehave when dealing
+ with empty sub-lists, or when the nesting of sub-lists is
+ inconsistent so that the data does not represent a rectangular array
+ of values. The former should result in an empty output array, and
+ the latter in an error. But some cases resulted in a crash, and
+ others in unexpected output.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Nathan Bossart <nathan@postgresql.org>
+Branch: master [57d005170] 2023-05-04 16:23:05 -0700
+Branch: REL_15_STABLE [825ebc984] 2023-05-04 16:24:48 -0700
+Branch: REL_14_STABLE [52c9cf323] 2023-05-04 16:25:05 -0700
+Branch: REL_13_STABLE [800531846] 2023-05-04 16:26:00 -0700
+Branch: REL_12_STABLE [24964394a] 2023-05-04 16:26:05 -0700
+Branch: REL_11_STABLE [0af386b0f] 2023-05-04 16:26:11 -0700
+-->
+ <para>
+ Fix unwinding of exception stack
+ in <application>plpython</application> (Xing Guo)
+ </para>
+
+ <para>
+ Some rare failure cases could return without cleaning up the PG_TRY
+ exception stack, risking a crash if another error was raised before
+ the next stack level was unwound.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [e0a09d4e3] 2023-03-13 16:36:20 +0900
+Branch: REL_15_STABLE [4493256c5] 2023-03-13 16:36:28 +0900
+Branch: REL_14_STABLE [7e319231c] 2023-03-13 16:36:31 +0900
+Branch: REL_13_STABLE [96bef4374] 2023-03-13 16:36:33 +0900
+Branch: REL_12_STABLE [2bc36a56c] 2023-03-13 16:36:34 +0900
+-->
+ <para>
+ Fix inconsistent GSS-encryption error handling
+ in <application>libpq</application>'s
+ <function>PQconnectPoll()</function>
+ (Michael Paquier)
+ </para>
+
+ <para>
+ With <option>gssencmode</option> set to <literal>require</literal>,
+ the connection was not marked dead after a GSS initialization
+ failure. Make it fail immediately, as the equivalent case for TLS
+ encryption has long done.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [f18029084] 2023-04-18 11:20:41 +0900
+Branch: REL_15_STABLE [8c746be44] 2023-04-18 11:20:47 +0900
+Branch: REL_14_STABLE [02f076454] 2023-04-18 11:20:50 +0900
+Branch: REL_13_STABLE [e9e457d22] 2023-04-18 11:20:51 +0900
+Branch: REL_12_STABLE [a28bd7713] 2023-04-18 11:20:53 +0900
+Branch: REL_11_STABLE [9eb44bb04] 2023-04-18 11:20:55 +0900
+Branch: REL_11_STABLE [dbd25dd0b] 2023-04-18 12:00:31 +0900
+-->
+ <para>
+ Fix possible data corruption in <application>ecpg</application>
+ programs built with the <option>-C ORACLE</option> option
+ (Kyotaro Horiguchi)
+ </para>
+
+ <para>
+ When <function>ecpg_get_data()</function> is called
+ with <varname>varcharsize</varname> set to zero, it could write a
+ terminating zero character into the last byte of the preceding
+ field, truncating the data in that field.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [bc8cd50fe] 2023-03-17 13:31:40 -0400
+Branch: REL_15_STABLE [2b216da1e] 2023-03-17 13:31:40 -0400
+Branch: REL_14_STABLE [5fc1ac151] 2023-03-17 13:31:40 -0400
+Branch: REL_13_STABLE [7e7c5b683] 2023-03-17 13:31:40 -0400
+Branch: REL_12_STABLE [8f83ce8c5] 2023-03-17 13:31:40 -0400
+Branch: REL_11_STABLE [012ffb365] 2023-03-17 13:31:40 -0400
+-->
+ <para>
+ Fix <application>pg_dump</application> so that partitioned tables
+ that are hash-partitioned on an enum-type column can be restored
+ successfully (Tom Lane)
+ </para>
+
+ <para>
+ Since the hash codes for enum values depend on the OIDs assigned to
+ the enum, they are typically different after a dump and restore,
+ meaning that rows often need to go into a different partition than
+ they were in originally. Users can work around that by specifying
+ the <option>--load-via-partition-root</option> option; but since
+ there is very little chance of success without that,
+ teach <application>pg_dump</application> to apply it automatically
+ to such tables.
+ </para>
+
+ <para>
+ Also, fix <application>pg_restore</application> to not try
+ to <command>TRUNCATE</command> target tables before restoring into
+ them when <option>--load-via-partition-root</option> mode is used.
+ This avoids a hazard of deadlocks and lost data.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [a923e2163] 2023-04-12 09:09:38 +0900
+Branch: REL_15_STABLE [5c3254946] 2023-04-12 09:09:53 +0900
+Branch: REL_14_STABLE [34105eea6] 2023-04-12 09:09:58 +0900
+Branch: master [765f5df72] 2023-03-15 12:55:51 +0900
+Branch: REL_15_STABLE [69b6032e0] 2023-03-15 12:56:06 +0900
+Branch: REL_14_STABLE [bbf18fe19] 2023-03-15 12:56:10 +0900
+-->
+ <para>
+ Correctly detect non-seekable files on Windows
+ (Juan José Santamaría Flecha, Michael Paquier, Daniel Watzinger)
+ </para>
+
+ <para>
+ This bug led to misbehavior when <application>pg_dump</application>
+ writes to a pipe or <application>pg_restore</application> reads from
+ one.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [038f586d5] 2023-02-21 10:56:37 +0100
+Branch: REL_15_STABLE [108a22bd1] 2023-02-21 10:56:37 +0100
+Branch: REL_14_STABLE [663e50e83] 2023-02-21 10:56:37 +0100
+-->
+ <para>
+ In <application>pgbench</application>'s <quote>prepared</quote>
+ mode, prepare all the commands in a pipeline before starting the
+ pipeline (&Aacute;lvaro Herrera)
+ </para>
+
+ <para>
+ This avoids a failure when a pgbench script tries to
+ start a serializable transaction inside a pipeline.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+Branch: master [e88754a19] 2023-03-24 10:56:10 -0400
+Branch: REL_15_STABLE [701ec5557] 2023-03-24 10:59:10 -0400
+Branch: REL_14_STABLE [8fd5aa76c] 2023-03-24 11:06:45 -0400
+Branch: master [b7cea5882] 2023-03-28 16:16:53 -0400
+Branch: REL_15_STABLE [453f53821] 2023-03-28 16:17:03 -0400
+Branch: REL_14_STABLE [e3363cda9] 2023-03-28 16:21:29 -0400
+-->
+ <para>
+ In <filename>contrib/amcheck</filename>'s heap checking code, deal
+ correctly with tuples having zero xmin or xmax (Robert Haas)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [4f5d461e0] 2023-03-11 14:12:52 -0800
+Branch: REL_15_STABLE [e8a9750d0] 2023-03-11 14:14:50 -0800
+Branch: REL_14_STABLE [b3a83055c] 2023-03-11 14:17:51 -0800
+-->
+ <para>
+ In <filename>contrib/amcheck</filename>, deal sanely with xids that
+ appear to be before epoch zero (Andres Freund)
+ </para>
+
+ <para>
+ In cases of corruption we might see a wrapped-around 32-bit xid that
+ appears to be before the first xid epoch. Promoting such a value to
+ 64-bit form produced a value far in the future, resulting in wrong
+ reports. Return FirstNormalFullTransactionId in such cases so that
+ things work reasonably sanely.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+Branch: master [8e82db97b] 2023-04-12 11:37:13 -0400
+Branch: REL_15_STABLE [fa83e9e23] 2023-04-12 11:51:09 -0400
+-->
+ <para>
+ In <filename>contrib/basebackup_to_shell</filename>, properly detect
+ failure to open a pipe (Robert Haas)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [df38157d9] 2023-04-27 11:55:06 -0400
+Branch: REL_15_STABLE [85ec8bcce] 2023-04-27 11:55:06 -0400
+Branch: REL_14_STABLE [c74f88c40] 2023-04-27 11:55:06 -0400
+Branch: REL_13_STABLE [de2dfa053] 2023-04-27 11:55:06 -0400
+Branch: REL_12_STABLE [ce9662598] 2023-04-27 11:55:06 -0400
+Branch: REL_11_STABLE [c3c1097dc] 2023-04-27 11:55:06 -0400
+-->
+ <para>
+ In <filename>contrib/hstore_plpython</filename>, avoid crashing if
+ the Python value to be transformed isn't a mapping (Dmitry Dolgov,
+ Tom Lane)
+ </para>
+
+ <para>
+ This should give an error, but Python 3 changed some APIs in a way
+ that caused the check to misbehave, allowing a crash to ensue.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alexander Korotkov <akorotkov@postgresql.org>
+Branch: master [8bbd0cce9] 2023-04-23 14:30:09 +0300
+Branch: REL_15_STABLE [214495dc5] 2023-04-23 14:30:51 +0300
+Branch: REL_14_STABLE [f4a4a18ec] 2023-04-23 14:31:11 +0300
+Branch: REL_13_STABLE [48c6825d0] 2023-04-23 14:00:16 +0300
+-->
+ <para>
+ Require the <literal>siglen</literal> option of a GiST index on
+ an <type>ltree</type> column, if specified, to be a multiple of 4
+ (Alexander Korotkov)
+ </para>
+
+ <para>
+ Other values result in misaligned accesses to index content, which
+ is harmless on Intel-compatible hardware but can cause a crash on
+ some other architectures.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [be753639d] 2023-03-02 14:03:02 +0900
+Branch: REL_15_STABLE [9d41ecfcd] 2023-03-02 14:03:08 +0900
+Branch: REL_14_STABLE [5ad63eee1] 2023-03-02 14:03:21 +0900
+-->
+ <para>
+ In <filename>contrib/pageinspect</filename>, add defenses against
+ incorrect input for the <function>gist_page_items()</function> function
+ (Dmitry Koval)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [1925ac281] 2023-03-11 12:15:41 -0500
+Branch: REL_15_STABLE [6170386c7] 2023-03-11 12:15:41 -0500
+Branch: REL_14_STABLE [786528039] 2023-03-11 12:15:41 -0500
+Branch: REL_13_STABLE [bc436e4a9] 2023-03-11 12:15:41 -0500
+Branch: REL_12_STABLE [1279414bc] 2023-03-11 12:15:41 -0500
+Branch: REL_11_STABLE [b18327489] 2023-03-11 12:15:41 -0500
+-->
+ <para>
+ Fix misbehavior in <filename>contrib/pg_trgm</filename> with an
+ unsatisfiable regular expression (Tom Lane)
+ </para>
+
+ <para>
+ A regex such as <literal>$foo</literal> is legal but unsatisfiable;
+ the regex compiler recognizes that and produces an empty NFA graph.
+ Attempting to optimize such a graph into a pg_trgm GIN or GiST index
+ qualification resulted in accessing off the end of a work array,
+ possibly leading to crashes.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [8427ce4c3] 2023-02-21 20:01:43 +0900
+Branch: REL_15_STABLE [5bace41ab] 2023-02-21 20:02:09 +0900
+-->
+ <para>
+ Fix handling of escape sequences
+ in <filename>contrib/postgres_fdw</filename>'s
+ <varname>application_name</varname> parameter (Kyotaro Horiguchi,
+ Michael Paquier)
+ </para>
+
+ <para>
+ The code to expand these could fail if executed in a background
+ process, as for example during auto-analyze of a foreign table.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+Branch: master [69e8c7cf1] 2023-02-20 11:07:24 -0800
+Branch: REL_15_STABLE [da32a99df] 2023-02-20 11:29:31 -0800
+-->
+ <para>
+ In <filename>contrib/pg_walinspect</filename>, limit memory usage
+ of <function>pg_get_wal_records_info()</function> (Bharath Rupireddy)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [eab2d3147] 2023-04-20 18:12:32 -0400
+Branch: REL_15_STABLE [a14afd3bd] 2023-04-20 18:12:48 -0400
+Branch: REL_14_STABLE [6d60b718c] 2023-04-20 18:12:32 -0400
+Branch: REL_13_STABLE [6dce37203] 2023-04-20 18:12:32 -0400
+Branch: REL_12_STABLE [e2e34dfff] 2023-04-20 18:12:32 -0400
+Branch: REL_11_STABLE [c976ccc9e] 2023-04-20 18:12:32 -0400
+-->
+ <para>
+ Use the <option>--strip-unneeded</option> option when stripping
+ static libraries with
+ GNU-compatible <application>strip</application> (Tom Lane)
+ </para>
+
+ <para>
+ Previously, <literal>make install-strip</literal> used
+ the <option>-x</option> option in this case. This change avoids
+ misbehavior of <application>llvm-strip</application>, and gives
+ slightly smaller output as well.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [969509c3f] 2023-02-08 17:15:25 -0500
+Branch: REL_15_STABLE [2ee703c9d] 2023-02-08 17:15:23 -0500
+Branch: REL_14_STABLE [7f8778fcf] 2023-02-08 17:15:23 -0500
+Branch: REL_13_STABLE [c7b608600] 2023-02-08 17:15:23 -0500
+Branch: REL_12_STABLE [11f1f9f4f] 2023-02-08 17:15:27 -0500
+Branch: REL_11_STABLE [36a646d99] 2023-02-08 17:15:27 -0500
+-->
+ <para>
+ Stop recommending auto-download of DTD files for building the
+ documentation, and indeed disable it (Aleksander Alekseev, Peter
+ Eisentraut, Tom Lane)
+ </para>
+
+ <para>
+ It appears no longer possible to build the SGML documentation
+ without a local installation of the DocBook DTD files.
+ Formerly <application>xsltproc</application> could download those
+ files on-the-fly from sourceforge.net; but sourceforge.net now
+ permits only HTTPS access, and no common version
+ of <application>xsltproc</application> supports that. Hence, remove
+ the bits of our documentation suggesting that that's possible or
+ useful, and instead
+ add <application>xsltproc</application>'s <option>--nonet</option>
+ option to the build recipes.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+Branch: master [5d42a9751] 2023-05-05 07:09:52 +0200
+Branch: REL_15_STABLE [3d37476f5] 2023-05-05 07:10:15 +0200
+Branch: REL_14_STABLE [e07022500] 2023-05-05 07:10:30 +0200
+Branch: REL_13_STABLE [670494477] 2023-05-05 07:11:58 +0200
+Branch: REL_12_STABLE [14bb2e76c] 2023-05-05 07:12:18 +0200
+Branch: REL_11_STABLE [b189f71e5] 2023-05-05 07:12:26 +0200
+-->
+ <para>
+ When running TAP tests in PGXS builds, use a saner location for the
+ temporary <filename>portlock</filename> directory (Peter Eisentraut)
+ </para>
+
+ <para>
+ Place it under <filename>tmp_check</filename> in the build
+ directory. With the previous coding, a PGXS build would try to place
+ it in the installation directory, which is not necessarily writable.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [4ddee4d9d] 2023-04-18 14:46:39 -0400
+Branch: REL_15_STABLE [62b22caa5] 2023-04-18 14:46:39 -0400
+Branch: REL_14_STABLE [b79b36f26] 2023-04-18 14:46:39 -0400
+Branch: REL_13_STABLE [87d8ec3e4] 2023-04-18 14:46:39 -0400
+Branch: REL_12_STABLE [2ad35cf06] 2023-04-18 14:46:39 -0400
+Branch: REL_11_STABLE [7228f2f81] 2023-04-18 14:46:39 -0400
+-->
+ <para>
+ Update time zone data files to <application>tzdata</application>
+ release 2023c for DST law changes in Egypt, Greenland, Morocco, and
+ Palestine.
+ </para>
+
+ <para>
+ When observing Moscow time, Europe/Kirov and Europe/Volgograd now
+ use the abbreviations MSK/MSD instead of numeric abbreviations,
+ for consistency with other timezones observing Moscow time.
+ Also, America/Yellowknife is no longer distinct from America/Edmonton;
+ this affects some pre-1948 timestamps in that area.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="release-15-2">
+ <title>Release 15.2</title>
+
+ <formalpara>
+ <title>Release date:</title>
+ <para>2023-02-09</para>
+ </formalpara>
+
+ <para>
+ This release contains a variety of fixes from 15.1.
+ For information about new features in major release 15, see
+ <xref linkend="release-15"/>.
+ </para>
+
+ <sect2>
+ <title>Migration to Version 15.2</title>
+
+ <para>
+ A dump/restore is not required for those running 15.X.
+ </para>
+
+ <para>
+ However, if you are upgrading from a version earlier than 15.1,
+ see <xref linkend="release-15-1"/>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Changes</title>
+
+ <itemizedlist>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [71c37797d] 2023-02-06 11:20:07 +0900
+Branch: REL_15_STABLE [715c345dd] 2023-02-06 11:20:20 +0900
+Branch: REL_14_STABLE [626f2c1d6] 2023-02-06 11:20:23 +0900
+Branch: REL_13_STABLE [45a945ee9] 2023-02-06 11:20:27 +0900
+Branch: REL_12_STABLE [3f7342671] 2023-02-06 11:20:31 +0900
+-->
+ <para>
+ <application>libpq</application> can leak memory contents after
+ GSSAPI transport encryption initiation fails (Jacob Champion)
+ </para>
+
+ <para>
+ A modified server, or an unauthenticated man-in-the-middle, can
+ send a not-zero-terminated error message during setup of GSSAPI
+ (Kerberos) transport encryption. <application>libpq</application>
+ will then copy that string, as well as following bytes in
+ application memory up to the next zero byte, to its error report.
+ Depending on what the calling application does with the error
+ report, this could result in disclosure of application memory
+ contents. There is also a small probability of a crash due to
+ reading beyond the end of memory. Fix by properly zero-terminating
+ the server message.
+ (CVE-2022-41862)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [3f7836ff6] 2023-01-05 14:12:17 -0500
+Branch: REL_15_STABLE [3706cc97a] 2023-01-05 14:12:17 -0500
+Branch: REL_14_STABLE [8cd190e13] 2023-01-05 14:12:17 -0500
+Branch: REL_13_STABLE [ad38e2f89] 2023-01-05 14:12:17 -0500
+Branch: master [3f244d020] 2023-01-15 13:14:52 -0500
+Branch: REL_15_STABLE [a8f7687a0] 2023-01-15 14:06:46 -0500
+Branch: REL_14_STABLE [a8b88c26f] 2023-01-15 14:06:46 -0500
+Branch: REL_13_STABLE [787db4be9] 2023-01-15 14:06:46 -0500
+-->
+ <para>
+ Fix calculation of which <literal>GENERATED</literal> columns need
+ to be updated in child tables during an <command>UPDATE</command> on
+ a partitioned table or inheritance tree (Amit Langote, Tom Lane)
+ </para>
+
+ <para>
+ This fixes failure to update <literal>GENERATED</literal> columns
+ that do not exist in the parent table, or that have different
+ dependencies than are in the parent column's generation expression.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [fe9e658f4] 2023-01-30 10:04:57 +0000
+Branch: REL_15_STABLE [4785af9e6] 2023-01-30 10:07:32 +0000
+-->
+ <para>
+ Fix possible failure of <command>MERGE</command> to compute
+ <literal>GENERATED</literal> columns (Dean Rasheed)
+ </para>
+
+ <para>
+ When the first row-level action of the <command>MERGE</command> was
+ an <literal>UPDATE</literal>, any
+ subsequent <literal>INSERT</literal> actions would fail to
+ compute <literal>GENERATED</literal> columns that were deemed
+ unnecessary to compute for the <literal>UPDATE</literal> action
+ (due to not depending on any of the <literal>UPDATE</literal> target
+ columns).
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [f026c16a2] 2023-01-10 14:17:47 +0000
+Branch: REL_15_STABLE [38255f2d0] 2023-01-10 14:16:27 +0000
+-->
+ <para>
+ Fix <command>MERGE</command>'s check for
+ unreachable <literal>WHEN</literal> clauses (Dean Rasheed)
+ </para>
+
+ <para>
+ A <literal>WHEN</literal> clause following an
+ unconditional <literal>WHEN</literal> clause should be rejected as
+ unreachable, but this case was not always detected.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [7b2ccc5e0] 2022-11-25 13:31:48 +0000
+Branch: REL_15_STABLE [04d61bfe6] 2022-11-25 13:29:51 +0000
+-->
+ <para>
+ Fix <command>MERGE</command>'s rule-detection test (Dean Rasheed)
+ </para>
+
+ <para>
+ <command>MERGE</command> is not supported on tables with rules;
+ but it also failed on tables that once had rules but no longer do.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [6ff5aa129] 2022-11-17 18:56:11 +0100
+Branch: REL_15_STABLE [3d45edcef] 2022-11-17 18:56:11 +0100
+-->
+ <para>
+ In <command>MERGE</command>, don't count a <literal>DO
+ NOTHING</literal> action as a processed tuple (&Aacute;lvaro Herrera)
+ </para>
+
+ <para>
+ This makes the code's behavior match the documentation.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [935277b24] 2022-12-16 13:07:42 -0500
+Branch: REL_15_STABLE [ae98debf7] 2022-12-16 13:07:42 -0500
+Branch: REL_14_STABLE [ea5ae4cae] 2022-12-16 13:07:42 -0500
+-->
+ <para>
+ Allow a <literal>WITH RECURSIVE ... CYCLE</literal> CTE
+ to access its output column (Tom Lane)
+ </para>
+
+ <para>
+ A reference to the <literal>SET</literal> column from within the CTE
+ would fail with <quote>cache lookup failed for type 0</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Etsuro Fujita <efujita@postgresql.org>
+Branch: master [ffbb7e65a] 2022-11-25 17:45:00 +0900
+Branch: REL_15_STABLE [fc02019c0] 2022-11-25 17:45:01 +0900
+Branch: REL_14_STABLE [e52245228] 2022-11-25 17:45:03 +0900
+Branch: master [4b3e37993] 2022-12-08 16:15:00 +0900
+Branch: REL_15_STABLE [a0bf7a0ec] 2022-12-08 16:15:01 +0900
+Branch: REL_14_STABLE [d43a97ef4] 2022-12-08 16:15:03 +0900
+-->
+ <para>
+ Fix handling of pending inserts when doing a bulk insertion to a
+ foreign table (Etsuro Fujita)
+ </para>
+
+ <para>
+ In some cases pending insertions were not flushed to the FDW soon
+ enough, leading to logical inconsistencies, for
+ example <literal>BEFORE ROW</literal> triggers not seeing rows they
+ should be able to see.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [c9f7f9264] 2023-01-21 13:10:29 -0500
+Branch: REL_15_STABLE [9e4288ce6] 2023-01-21 13:10:29 -0500
+Branch: REL_14_STABLE [70ec756b0] 2023-01-21 13:10:29 -0500
+Branch: REL_13_STABLE [72d611109] 2023-01-21 13:10:29 -0500
+Branch: REL_12_STABLE [a5f3f2fce] 2023-01-21 13:10:30 -0500
+Branch: REL_11_STABLE [6c122edde] 2023-01-21 13:10:30 -0500
+-->
+ <para>
+ Allow <literal>REPLICA IDENTITY</literal>
+ to be set on an index that's not (yet) valid (Tom Lane)
+ </para>
+
+ <para>
+ When <application>pg_dump</application> dumps a partitioned index
+ that's marked <literal>REPLICA IDENTITY</literal>, it generates a
+ command sequence that applies <literal>REPLICA IDENTITY</literal>
+ before the partitioned index has been marked valid, causing restore
+ to fail. There seems no very good reason to prohibit doing it in
+ that order, so allow it. The marking will have no effect anyway
+ until the index becomes valid.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [2605643a3] 2022-12-03 12:11:33 +0000
+Branch: REL_15_STABLE [c67204db6] 2022-12-03 12:14:36 +0000
+Branch: REL_14_STABLE [2c7ed9f75] 2022-12-03 12:16:07 +0000
+Branch: REL_13_STABLE [3bed88123] 2022-12-03 12:17:47 +0000
+Branch: REL_12_STABLE [33f600f04] 2022-12-03 12:18:58 +0000
+Branch: REL_11_STABLE [30f9b03a0] 2022-12-03 12:20:02 +0000
+-->
+ <para>
+ Fix handling of <literal>DEFAULT</literal> markers in rules that
+ perform an <command>INSERT</command> from a
+ multi-row <literal>VALUES</literal> list (Dean Rasheed)
+ </para>
+
+ <para>
+ In some cases a <literal>DEFAULT</literal> marker would not get
+ replaced with the proper default-value expression, leading to
+ an <quote>unrecognized node type</quote> error.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alexander Korotkov <akorotkov@postgresql.org>
+Branch: master [3161ae86c] 2023-01-12 18:16:34 +0300
+Branch: REL_15_STABLE [4dc3f94fa] 2023-01-12 18:17:43 +0300
+Branch: REL_14_STABLE [0d9221f1d] 2023-01-12 18:18:04 +0300
+Branch: REL_13_STABLE [2ff3ac3b5] 2023-01-12 18:18:31 +0300
+Branch: REL_12_STABLE [9e24e4781] 2023-01-12 18:19:19 +0300
+-->
+ <para>
+ Reject uses of undefined variables in <type>jsonpath</type>
+ existence checks (Alexander Korotkov, David G. Johnston)
+ </para>
+
+ <para>
+ While <type>jsonpath</type> match operators threw an error for an
+ undefined variable in the path pattern, the existence operators
+ silently treated it as a match.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [b0feda79f] 2022-12-12 16:17:54 -0500
+Branch: REL_15_STABLE [d79b76b10] 2022-12-12 16:17:49 -0500
+Branch: REL_14_STABLE [a18328bb3] 2022-12-12 16:17:49 -0500
+-->
+ <para>
+ Fix <type>jsonb</type> subscripting to cope with toasted subscript
+ values (Tom Lane, David G. Johnston)
+ </para>
+
+ <para>
+ Using a text value fetched directly from a table as
+ a <type>jsonb</type> subscript was likely to fail.
+ Fetches would usually not find any matching element.
+ Assignments could store the value with a garbage key,
+ although keys long enough to cause that problem are probably rare in
+ the field.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [ffcf6f4cf] 2023-01-26 14:52:19 +1300
+Branch: REL_15_STABLE [d9f5345bf] 2023-01-26 14:53:37 +1300
+Branch: REL_14_STABLE [2f65b8468] 2023-01-26 14:54:17 +1300
+Branch: REL_13_STABLE [1a5afe007] 2023-01-26 14:54:39 +1300
+Branch: REL_12_STABLE [b55303792] 2023-01-26 14:55:03 +1300
+Branch: REL_11_STABLE [d95dcc9ab] 2023-01-26 14:55:37 +1300
+-->
+ <para>
+ Fix edge-case data corruption in parallel hash joins (Dmitry Astapov)
+ </para>
+
+ <para>
+ If the final chunk of a large tuple being written out to a temporary
+ file was exactly 32760 bytes, it would be corrupted due to a
+ fencepost bug. The query would typically fail later with
+ corrupted-data symptoms.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [7e8a80d1f] 2023-01-19 13:13:05 +0900
+Branch: REL_15_STABLE [49e3a5e71] 2023-01-19 13:13:27 +0900
+Branch: REL_14_STABLE [2e21e2857] 2023-01-19 13:13:28 +0900
+Branch: REL_13_STABLE [fed4e92f3] 2023-01-19 13:13:30 +0900
+Branch: REL_12_STABLE [162a48287] 2023-01-19 13:13:32 +0900
+Branch: REL_11_STABLE [0c2f34af7] 2023-01-19 13:13:34 +0900
+-->
+ <para>
+ Honor non-default settings
+ of <varname>checkpoint_completion_target</varname>
+ (Bharath Rupireddy)
+ </para>
+
+ <para>
+ Internal state was not updated after a change
+ in <varname>checkpoint_completion_target</varname>, possibly
+ resulting in performing checkpoint I/O faster or slower than
+ desired, especially if that setting was changed on-the-fly.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [44e9e3426] 2023-01-19 12:23:20 -0500
+Branch: REL_15_STABLE [abe203304] 2023-01-19 12:23:20 -0500
+Branch: REL_14_STABLE [103450724] 2023-01-19 12:23:20 -0500
+Branch: REL_13_STABLE [1b9a0b96a] 2023-01-19 12:23:20 -0500
+Branch: REL_12_STABLE [87591db19] 2023-01-19 12:23:20 -0500
+Branch: REL_11_STABLE [0a269527f] 2023-01-19 12:23:20 -0500
+-->
+ <para>
+ Log the correct ending timestamp
+ in <varname>recovery_target_xid</varname> mode (Tom Lane)
+ </para>
+
+ <para>
+ When ending recovery based on the <varname>recovery_target_xid</varname>
+ setting with <varname>recovery_target_inclusive</varname>
+ = <literal>off</literal>, we printed an incorrect timestamp (always
+ 2000-01-01) in the <quote>recovery stopping before
+ ... transaction</quote> log message.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+Branch: master [1561612e3] 2023-01-16 09:44:04 +0100
+Branch: REL_15_STABLE [ac01fa647] 2023-01-16 09:45:03 +0100
+Branch: REL_14_STABLE [f463335e1] 2023-01-16 09:48:09 +0100
+Branch: REL_13_STABLE [cf74b6ead] 2023-01-16 09:54:15 +0100
+-->
+ <para>
+ Improve error reporting for some buffered file read failures
+ (Peter Eisentraut)
+ </para>
+
+ <para>
+ Correctly report a short read, giving the numbers of bytes desired
+ and actually read, instead of reporting an irrelevant error code.
+ Most places got this right already, but some recently-written
+ replication logic did not.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [647fa5005] 2023-01-15 17:32:09 -0500
+Branch: REL_15_STABLE [db9127c58] 2023-01-15 17:32:09 -0500
+-->
+ <para>
+ Remove arbitrary limit on number of elements
+ in <type>int2vector</type> and <type>oidvector</type> (Tom Lane)
+ </para>
+
+ <para>
+ The input functions for these types previously rejected more than
+ 100 elements. With the introduction of the logical replication
+ column list feature, it's necessary to
+ accept <type>int2vector</type>s having up to 1600 columns,
+ otherwise long column lists cause logical-replication failures.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [20432f873] 2022-12-13 14:23:58 -0500
+Branch: REL_15_STABLE [18431ee6f] 2022-12-13 14:23:59 -0500
+Branch: REL_14_STABLE [ae47f8a96] 2022-12-13 14:23:59 -0500
+Branch: REL_13_STABLE [942cc240f] 2022-12-13 14:23:59 -0500
+Branch: REL_12_STABLE [1cca4a75f] 2022-12-13 14:23:59 -0500
+Branch: REL_11_STABLE [f48aa5df4] 2022-12-13 14:23:59 -0500
+-->
+ <para>
+ In extended query protocol, avoid an immediate commit
+ after <command>ANALYZE</command> if we're running a pipeline
+ (Tom Lane)
+ </para>
+
+ <para>
+ If there's not been an explicit <command>BEGIN
+ TRANSACTION</command>, <command>ANALYZE</command> would take it on
+ itself to commit, which should not happen within a pipelined series
+ of commands.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Noah Misch <noah@leadboat.com>
+Branch: master [e52daaabf] 2023-01-21 06:08:00 -0800
+Branch: REL_15_STABLE [b152bb7b2] 2023-01-21 06:08:03 -0800
+Branch: REL_14_STABLE [6900aea67] 2023-01-21 06:08:04 -0800
+Branch: REL_13_STABLE [a9bccffe5] 2023-01-21 06:08:04 -0800
+Branch: REL_12_STABLE [e75b5c855] 2023-01-21 06:08:04 -0800
+Branch: REL_11_STABLE [8f70de7e0] 2023-01-21 06:08:05 -0800
+-->
+ <para>
+ Reject cancel request packets having the wrong length
+ (Andrey Borodin)
+ </para>
+
+ <para>
+ The server would process a cancel request even if its length word
+ was too small. This led to reading beyond the end of the allocated
+ buffer. In theory that could cause a segfault, but it seems quite
+ unlikely to happen in practice, since the buffer would have to be
+ very close to the end of memory. The more likely outcome was a bogus
+ log message about wrong backend PID or cancel code. Complain about
+ the wrong length, instead.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [94985c210] 2022-12-10 19:27:20 +1300
+Branch: REL_15_STABLE [04788ee4c] 2022-12-10 19:27:53 +1300
+-->
+ <para>
+ Fix planner preprocessing oversights for window function run-condition
+ expressions (Richard Guo, David Rowley)
+ </para>
+
+ <para>
+ This could lead to planner errors such as <quote>WindowFunc not
+ found in subplan target lists</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: David Rowley <drowley@postgresql.org>
+Branch: master [a85832722] 2022-12-07 00:09:36 +1300
+Branch: REL_15_STABLE [2a535620c] 2022-12-07 00:10:21 +1300
+-->
+ <para>
+ Fix possible dangling-pointer access during execution of window
+ function run-condition expressions (David Rowley)
+ </para>
+
+ <para>
+ In practice, because the run-condition optimization is only applied
+ to certain window functions that happen to all
+ return <type>int8</type>, this only manifested as a problem on
+ 32-bit builds.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [5beb7881f] 2022-12-22 10:35:02 -0500
+Branch: REL_15_STABLE [1a3daa5bb] 2022-12-22 10:35:02 -0500
+Branch: REL_14_STABLE [97431d673] 2022-12-22 10:35:02 -0500
+Branch: REL_13_STABLE [4fceb454f] 2022-12-22 10:35:03 -0500
+Branch: REL_12_STABLE [d572003f7] 2022-12-22 10:35:03 -0500
+Branch: REL_11_STABLE [8cd700cc5] 2022-12-22 10:35:03 -0500
+-->
+ <para>
+ Add recursion and looping defenses in subquery pullup (Tom Lane)
+ </para>
+
+ <para>
+ A contrived query can result in deep recursion and unreasonable
+ amounts of time spent trying to flatten subqueries. A proper fix
+ for that seems unduly invasive for a back-patch, but we can at least
+ add stack depth checks and an interrupt check to allow the query to
+ be cancelled.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [d69d01ba9] 2022-12-05 12:36:40 -0500
+Branch: REL_15_STABLE [c959f84c2] 2022-12-05 12:36:41 -0500
+Branch: REL_14_STABLE [dc3648f65] 2022-12-05 12:36:41 -0500
+Branch: master [e76913802] 2022-12-04 13:48:12 -0500
+Branch: REL_15_STABLE [834d97c32] 2022-12-04 13:48:12 -0500
+Branch: REL_14_STABLE [ce093aa18] 2022-12-04 13:48:12 -0500
+-->
+ <para>
+ Fix planner issues when combining Memoize nodes with partitionwise
+ joins or parameterized nestloops (Richard Guo)
+ </para>
+
+ <para>
+ These errors could lead to not using Memoize in contexts where it
+ would be useful, or possibly to wrong query plans.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [fe12f2f8f] 2022-12-04 13:17:18 -0500
+Branch: REL_15_STABLE [bf8fd64ff] 2022-12-04 13:17:18 -0500
+Branch: REL_14_STABLE [ec3daeec3] 2022-12-04 13:17:18 -0500
+Branch: REL_13_STABLE [4ebca555c] 2022-12-04 13:17:18 -0500
+Branch: REL_12_STABLE [1ff549e84] 2022-12-04 13:17:18 -0500
+Branch: REL_11_STABLE [2df073313] 2022-12-04 13:17:18 -0500
+-->
+ <para>
+ Fix partitionwise-join code to tolerate failure to produce a plan for
+ each partition (Tom Lane)
+ </para>
+
+ <para>
+ This could result in <quote>could not devise a query plan for the
+ given query</quote> errors.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [9c6ad5eaa] 2022-11-22 14:40:20 -0500
+Branch: REL_15_STABLE [2debceed2] 2022-11-22 14:40:44 -0500
+Branch: REL_14_STABLE [bd06fe4de] 2022-11-22 14:40:45 -0500
+Branch: REL_13_STABLE [6e639267a] 2022-11-22 14:40:45 -0500
+Branch: REL_12_STABLE [ec10b6139] 2022-11-22 14:40:45 -0500
+Branch: REL_11_STABLE [b96a096db] 2022-11-22 14:40:46 -0500
+-->
+ <para>
+ Limit the amount of cleanup work done
+ by <function>get_actual_variable_range</function> (Simon Riggs)
+ </para>
+
+ <para>
+ Planner runs occurring just after deletion of a large number of
+ tuples appearing at the end of an index could expend significant
+ amounts of work setting the <quote>killed</quote> bits for those
+ index entries. Limit the amount of work done in any one query by
+ giving up on this process after examining 100 heap pages. All the
+ cleanup will still happen eventually, but without so large a
+ performance hiccup.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [cb2e7ddfe] 2022-12-02 18:10:30 -0800
+Branch: REL_15_STABLE [c6a60471a] 2022-12-02 18:07:47 -0800
+-->
+ <para>
+ Prevent the statistics machinery from getting confused when a
+ relation's relkind changes (Andres Freund)
+ </para>
+
+ <para>
+ Converting a table to a view could lead to crashes or assertion
+ failures.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [1dd6700f4] 2022-12-01 11:38:14 -0500
+Branch: REL_15_STABLE [a711b36e5] 2022-12-01 11:38:15 -0500
+Branch: REL_14_STABLE [de0ff6088] 2022-12-01 11:38:15 -0500
+-->
+ <para>
+ Fix under-parenthesized display of <literal>AT TIME ZONE</literal>
+ constructs (Tom Lane)
+ </para>
+
+ <para>
+ This could result in dump/restore failures for rules or views in
+ which an argument of <literal>AT TIME ZONE</literal> is itself an
+ expression.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [8b47ccb62] 2022-11-29 11:46:33 -0500
+Branch: REL_15_STABLE [5dfc2b753] 2022-11-29 11:46:33 -0500
+Branch: REL_14_STABLE [7715a3c24] 2022-11-29 11:46:33 -0500
+-->
+ <para>
+ Prevent clobbering of cached parsetrees for utility statements in
+ SQL functions (Tom Lane, Daniel Gustafsson)
+ </para>
+
+ <para>
+ If a SQL-language function executes the same utility command more
+ than once within a single calling query, it could crash or report
+ strange errors such as <quote>unrecognized node type</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [5644d6f90] 2022-11-21 17:07:29 -0500
+Branch: REL_15_STABLE [0353db996] 2022-11-21 17:07:07 -0500
+Branch: REL_14_STABLE [1b9c04b13] 2022-11-21 17:07:07 -0500
+Branch: REL_13_STABLE [74670688f] 2022-11-21 17:07:07 -0500
+Branch: REL_12_STABLE [1aed4c4fd] 2022-11-21 17:07:07 -0500
+Branch: REL_11_STABLE [c0eed8891] 2022-11-21 17:07:07 -0500
+-->
+ <para>
+ Ensure that execution of full-text-search queries can be cancelled
+ while they are performing phrase matches (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+Branch: master [edf12e7bb] 2022-12-01 11:49:15 -0800
+Branch: REL_15_STABLE [9377b4f30] 2022-12-01 11:55:59 -0800
+Branch: REL_14_STABLE [47e1224d5] 2022-12-01 11:53:53 -0800
+Branch: REL_13_STABLE [a844052b5] 2022-12-01 11:52:06 -0800
+Branch: REL_12_STABLE [f98c4fb1d] 2022-12-01 11:49:43 -0800
+-->
+ <para>
+ Fix memory leak in hashing strings with nondeterministic collations
+ (Jeff Davis)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [6c6d6ba3e] 2023-01-24 09:25:36 +0530
+Branch: REL_15_STABLE [267135d01] 2023-01-24 09:12:04 +0530
+Branch: REL_14_STABLE [fd270b728] 2023-01-24 09:02:05 +0530
+-->
+ <para>
+ Fix deadlock between <command>DROP DATABASE</command> and logical
+ replication worker process (Hou Zhijie)
+ </para>
+
+ <para>
+ This was caused by an ill-advised choice to block interrupts while
+ creating a logical replication slot in the worker. In version 15
+ that could lead to an undetected deadlock. In version 14, no
+ deadlock has been observed, but it's still a bad idea to block
+ interrupts while waiting for network I/O.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [bc54ef4ec] 2023-01-23 18:27:42 -0800
+Branch: REL_15_STABLE [704a330a9] 2023-01-23 18:27:45 -0800
+Branch: REL_14_STABLE [0a796b8b3] 2023-01-23 18:27:48 -0800
+Branch: REL_13_STABLE [c5864805b] 2023-01-23 18:27:51 -0800
+Branch: REL_12_STABLE [92fc12787] 2023-01-23 18:27:55 -0800
+Branch: REL_11_STABLE [243373159] 2023-01-23 18:27:58 -0800
+-->
+ <para>
+ Clean up the <application>libpq</application> connection object
+ after a failed replication connection attempt (Andres Freund)
+ </para>
+
+ <para>
+ The previous coding leaked the connection object. In background
+ code paths that's pretty harmless because the calling process will
+ give up and exit. But in commands such as <command>CREATE
+ SUBSCRIPTION</command>, such a failure resulted in a small
+ session-lifespan memory leak.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [8242752f9] 2022-11-29 15:43:17 -0500
+Branch: REL_15_STABLE [55fa993d7] 2022-11-29 15:43:17 -0500
+Branch: REL_14_STABLE [06998eab1] 2022-11-29 15:43:17 -0500
+Branch: REL_13_STABLE [6e8ad1152] 2022-11-29 15:43:17 -0500
+Branch: REL_12_STABLE [c4a153d77] 2022-11-29 15:43:17 -0500
+Branch: REL_11_STABLE [a6c9e1db2] 2022-11-29 15:43:17 -0500
+-->
+ <para>
+ In hot-standby servers, reduce processing effort for tracking XIDs
+ known to be active on the primary (Simon Riggs, Michail Nikolaev)
+ </para>
+
+ <para>
+ Insufficiently-aggressive cleanup of the KnownAssignedXids array
+ could lead to poor performance, particularly
+ when <varname>max_connections</varname> is set to a large value on
+ the standby.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [0557e1770] 2022-11-22 10:56:07 +0100
+Branch: REL_15_STABLE [1ad033df1] 2022-11-22 10:56:07 +0100
+Branch: REL_14_STABLE [1b3ed7571] 2022-11-22 10:56:07 +0100
+Branch: REL_13_STABLE [36eeb37cd] 2022-11-22 10:56:07 +0100
+-->
+ <para>
+ Ignore invalidated logical-replication slots while determining
+ oldest catalog xmin (Sirisha Chamarthi)
+ </para>
+
+ <para>
+ A replication slot could prevent cleanup of dead tuples in the
+ system catalogs even after it becomes invalidated due to
+ exceeding <varname>max_slot_wal_keep_size</varname>. Thus, failure
+ of a replication consumer could lead to indefinitely-large catalog
+ bloat.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [2b6df0546] 2023-01-07 12:17:14 +0530
+Branch: REL_15_STABLE [18b81258a] 2023-01-07 12:04:33 +0530
+Branch: REL_14_STABLE [b2cc5b810] 2023-01-07 11:52:41 +0530
+-->
+ <para>
+ In logical decoding, notify the remote node when a transaction is
+ detected to have crashed (Hou Zhijie)
+ </para>
+
+ <para>
+ After a server restart, we'll re-stream the changes for transactions
+ occurring shortly before the restart. Some of these transactions
+ probably never completed; when we realize that one didn't we throw
+ away the relevant decoding state locally, but we neglected to tell
+ the subscriber about it. That led to the subscriber keeping useless
+ streaming files until it's next restarted.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: REL_15_STABLE [898ef41bf] 2022-11-25 09:38:03 +0530
+Branch: REL_14_STABLE [9f2cc1a73] 2022-11-25 09:25:50 +0530
+Branch: REL_13_STABLE [4ec157c15] 2022-11-25 09:15:31 +0530
+Branch: REL_12_STABLE [aa9d916f6] 2022-11-25 09:00:15 +0530
+Branch: REL_11_STABLE [9b788aafd] 2022-11-25 08:56:54 +0530
+-->
+ <para>
+ Fix uninitialized-memory usage in logical decoding (Masahiko Sawada)
+ </para>
+
+ <para>
+ In certain cases, resumption of logical decoding could try to re-use
+ XID data that had already been freed, leading to unpredictable
+ behavior.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [5ad165d2c] 2023-01-12 13:40:33 +0900
+Branch: REL_15_STABLE [6f25e4877] 2023-01-12 13:41:22 +0900
+-->
+ <para>
+ Acquire spinlock while updating shared state during logical decoding
+ context creation (Masahiko Sawada)
+ </para>
+
+ <para>
+ We neglected to acquire the appropriate lock while updating data
+ about two-phase transactions, potentially allowing other processes
+ to see inconsistent data.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [40b149135] 2022-12-02 10:52:58 +0530
+Branch: REL_15_STABLE [ebf87c019] 2022-12-02 11:14:42 +0530
+-->
+ <para>
+ Fix <application>pgoutput</application> replication plug-in to not
+ send columns not listed in a table's replication column list
+ (Hou Zhijie)
+ </para>
+
+ <para>
+ <literal>UPDATE</literal> and <literal>DELETE</literal> events did
+ not pay attention to the configured column list, thus sending more
+ data than expected. This did not cause a problem when the receiver
+ is our built-in logical replication code, but it might confuse other
+ receivers, and in any case it wasted network bandwidth.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [e848be60b] 2022-11-14 10:43:33 +0530
+Branch: REL_15_STABLE [e49e19181] 2022-11-14 10:32:47 +0530
+Branch: REL_14_STABLE [9693f1900] 2022-11-14 10:22:28 +0530
+Branch: REL_13_STABLE [20c223336] 2022-11-14 10:11:10 +0530
+Branch: REL_12_STABLE [4dccccb37] 2022-11-14 10:01:14 +0530
+Branch: REL_11_STABLE [1703033f8] 2022-11-14 09:52:06 +0530
+-->
+ <para>
+ Avoid rare <quote>failed to acquire cleanup lock</quote> panic
+ during WAL replay of hash-index page split operations (Robert Haas)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+Branch: master [d6a3dbe14] 2022-11-11 12:38:29 -0800
+Branch: REL_15_STABLE [7bf713dd2] 2022-11-11 12:46:11 -0800
+Branch: REL_14_STABLE [f893af496] 2022-11-11 12:46:22 -0800
+Branch: REL_13_STABLE [58a45bb1d] 2022-11-11 12:46:34 -0800
+Branch: REL_12_STABLE [7dd39e9e8] 2022-11-11 12:46:44 -0800
+Branch: REL_11_STABLE [5eaf3e375] 2022-11-11 12:46:52 -0800
+-->
+ <para>
+ Advance a heap page's LSN when setting its all-visible bit during
+ WAL replay (Jeff Davis)
+ </para>
+
+ <para>
+ Failure to do this left the page possibly different on standby
+ servers than the primary, and violated some other expectations about
+ when the LSN changes. This seems only a theoretical hazard so
+ far as <productname>PostgreSQL</productname> itself is concerned,
+ but it could upset third-party tools.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [b2d479289] 2023-02-03 11:13:34 +0000
+Branch: REL_15_STABLE [4f74741a5] 2023-02-03 11:11:59 +0000
+Branch: REL_14_STABLE [86bfbeab4] 2023-02-03 11:09:15 +0000
+-->
+ <para>
+ Fix <function>int64_div_fast_to_numeric()</function> to work for a
+ wider range of inputs (Dean Rasheed)
+ </para>
+
+ <para>
+ This function misbehaved with some values of its second argument.
+ No such usages exist in core <productname>PostgreSQL</productname>,
+ but it's clearly a hazard for external modules, so repair.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [f1821b58f] 2023-01-13 11:02:12 +1300
+Branch: REL_15_STABLE [8a98523a5] 2023-01-13 11:02:00 +1300
+Branch: REL_14_STABLE [547e60b83] 2023-01-13 10:57:29 +1300
+Branch: REL_13_STABLE [c159b0383] 2023-01-13 10:54:49 +1300
+Branch: REL_12_STABLE [bf388ab82] 2023-01-13 10:54:34 +1300
+Branch: REL_11_STABLE [1b40710a8] 2023-01-13 10:54:20 +1300
+-->
+ <para>
+ Fix latent buffer-overrun problem in <literal>WaitEventSet</literal>
+ logic (Thomas Munro)
+ </para>
+
+ <para>
+ The <function>epoll</function>-based
+ and <function>kqueue</function>-based implementations could ask the
+ kernel for too many events if the size of their internal buffer was
+ different from the size of the caller's output buffer. That case is
+ not known to occur in released <productname>PostgreSQL</productname>
+ versions, but this error is a hazard for external modules and future
+ bug fixes.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [8c954168c] 2022-11-19 12:22:04 -0800
+Branch: REL_15_STABLE [a0d35ebcc] 2022-11-19 12:33:11 -0800
+Branch: REL_14_STABLE [fc4154286] 2022-11-19 12:33:14 -0800
+Branch: REL_13_STABLE [c13667b51] 2022-11-19 12:36:33 -0800
+Branch: REL_12_STABLE [4cbcb7ed8] 2022-11-19 12:36:48 -0800
+Branch: REL_11_STABLE [140c80372] 2022-11-19 12:36:52 -0800
+-->
+ <para>
+ Avoid nominally-undefined behavior when accessing shared memory in
+ 32-bit builds (Andres Freund)
+ </para>
+
+ <para>
+ clang's undefined-behavior sanitizer complained about use of a
+ pointer that was less aligned than it should be. It's very unlikely
+ that this would cause a problem in non-debug builds, but it's worth
+ fixing for testing purposes.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+Branch: master [02699bc1f] 2022-12-30 20:49:50 +0100
+Branch: REL_15_STABLE [c4f64cfab] 2022-12-30 20:49:11 +0100
+Branch: REL_14_STABLE [883dc0214] 2022-12-30 20:47:58 +0100
+-->
+ <para>
+ Fix assertion failure in BRIN minmax-multi opclasses (Tomas Vondra)
+ </para>
+
+ <para>
+ The assertion was overly strict, so this mistake was harmless in
+ non-assert builds.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [51dfaa0b0] 2022-11-29 10:52:44 -0500
+Branch: REL_15_STABLE [556c0b913] 2022-11-29 10:52:44 -0500
+Branch: REL_14_STABLE [0224646be] 2022-11-29 10:52:44 -0500
+Branch: REL_13_STABLE [aca695fb6] 2022-11-29 10:52:44 -0500
+Branch: REL_12_STABLE [bb8d48cb9] 2022-11-29 10:52:44 -0500
+-->
+ <para>
+ Remove faulty assertion in useless-RESULT-RTE optimization logic
+ (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [2fcf685f6] 2022-12-23 10:04:18 +0900
+Branch: REL_15_STABLE [e3897a3a4] 2022-12-23 10:04:30 +0900
+Branch: REL_14_STABLE [7ad458e06] 2022-12-23 10:04:33 +0900
+Branch: REL_13_STABLE [4dbe72d61] 2022-12-23 10:04:34 +0900
+Branch: REL_12_STABLE [7445869e1] 2022-12-23 10:04:36 +0900
+Branch: REL_11_STABLE [df6fea51f] 2022-12-23 10:04:37 +0900
+-->
+ <para>
+ Fix copy-and-paste errors in cache-lookup-failure messages for ACL
+ checks (Justin Pryzby)
+ </para>
+
+ <para>
+ In principle these errors should never be reached. But if they are,
+ some of them reported the wrong type of object.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+Branch: master [45f5c81ad] 2022-12-12 10:26:48 -0500
+Branch: REL_15_STABLE [8b5ba2f3f] 2022-12-12 10:33:02 -0500
+-->
+ <para>
+ Fix possible corruption of very large tablespace map files
+ in <application>pg_basebackup</application> (Antonin Houska)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [74739d1d3] 2023-01-19 19:32:50 -0500
+Branch: REL_15_STABLE [488e89bf7] 2023-01-19 19:32:47 -0500
+-->
+ <para>
+ Avoid harmless warning from <application>pg_dump</application>
+ in <option>--if-exists</option> mode (Tom Lane)
+ </para>
+
+ <para>
+ If the <literal>public</literal> schema has a non-default owner then
+ use of <application>pg_dump</application>'s <option>--if-exists</option>
+ option resulted in a warning message <quote>warning: could not find
+ where to insert IF EXISTS in statement "-- *not* dropping schema,
+ since initdb creates it"</quote>. The dump output was okay, though.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [cabfb8241] 2022-12-02 14:24:44 -0500
+Branch: REL_15_STABLE [97299cf99] 2022-12-02 14:24:44 -0500
+Branch: REL_14_STABLE [303b26c1b] 2022-12-02 14:24:44 -0500
+-->
+ <para>
+ Fix <application>psql</application>'s <literal>\sf</literal>
+ and <literal>\ef</literal> commands to handle SQL-language functions
+ that have <acronym>SQL</acronym>-standard function bodies (Tom Lane)
+ </para>
+
+ <para>
+ These commands misidentified the start of the function body when it
+ used new-style syntax.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+Branch: master [e7a59094b] 2023-01-06 11:18:44 +0000
+Branch: REL_15_STABLE [2daf4664c] 2023-01-06 11:16:53 +0000
+Branch: REL_14_STABLE [48599a18d] 2023-01-06 11:15:22 +0000
+Branch: REL_13_STABLE [2ad4abedf] 2023-01-06 11:13:34 +0000
+Branch: REL_12_STABLE [274185d11] 2023-01-06 11:11:51 +0000
+Branch: REL_11_STABLE [c54b88870] 2023-01-06 11:09:56 +0000
+-->
+ <para>
+ Fix tab completion of <command>ALTER
+ FUNCTION/PROCEDURE/ROUTINE</command> ... <command>SET
+ SCHEMA</command> (Dean Rasheed)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [aeaaf520f] 2022-11-21 15:37:10 -0500
+Branch: REL_15_STABLE [b8988cf1d] 2022-11-21 15:37:10 -0500
+-->
+ <para>
+ Update <filename>contrib/pageinspect</filename> to mark its
+ disk-accessing functions as <literal>PARALLEL RESTRICTED</literal>
+ (Tom Lane)
+ </para>
+
+ <para>
+ This avoids possible failure if one of these functions is used to
+ examine a temporary table, since a session's temporary tables are not
+ accessible from parallel workers.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [701c881f7] 2022-12-21 17:51:50 -0500
+Branch: REL_15_STABLE [b87037b37] 2022-12-21 17:51:50 -0500
+Branch: REL_14_STABLE [f489b480f] 2022-12-21 17:51:50 -0500
+Branch: REL_13_STABLE [d35f1d485] 2022-12-21 17:51:50 -0500
+Branch: REL_12_STABLE [c8314d62a] 2022-12-21 17:51:50 -0500
+Branch: REL_11_STABLE [0ff4056b8] 2022-12-21 17:51:50 -0500
+-->
+ <para>
+ Fix <filename>contrib/seg</filename> to not crash or print garbage
+ if an input number has more than 127 digits (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: REL_15_STABLE [576506303] 2022-11-10 10:23:49 -0500
+Branch: REL_14_STABLE [06dca17ad] 2022-11-10 10:23:49 -0500
+Branch: REL_13_STABLE [0942acb73] 2022-11-10 10:23:49 -0500
+Branch: REL_12_STABLE [cf0f465c0] 2022-11-10 10:23:49 -0500
+-->
+ <para>
+ Fix build on Microsoft Visual Studio 2013 (Tom Lane)
+ </para>
+
+ <para>
+ A previous patch supposed that all platforms of interest
+ have <function>snprintf()</function>, but MSVC 2013 isn't quite
+ there yet. Revert to using <function>sprintf()</function> on that
+ platform.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andrew Dunstan <andrew@dunslane.net>
+Branch: master [341f4e002] 2022-11-25 15:28:38 -0500
+Branch: REL_15_STABLE [fed54fc9a] 2022-11-25 15:37:33 -0500
+Branch: REL_14_STABLE [f76191fd9] 2022-11-25 15:37:33 -0500
+Branch: REL_13_STABLE [9fe5cff14] 2022-11-25 15:37:33 -0500
+Branch: REL_12_STABLE [171c7fffa] 2022-11-25 15:37:34 -0500
+Branch: REL_11_STABLE [ae7c51213] 2022-11-25 15:37:34 -0500
+-->
+ <para>
+ Fix compile failure in building PL/Perl with MSVC when using
+ Strawberry Perl (Andrew Dunstan)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andrew Dunstan <andrew@dunslane.net>
+Branch: master [ccc59a83c] 2022-11-27 09:03:22 -0500
+Branch: REL_15_STABLE [b5d8fd418] 2022-11-27 09:18:14 -0500
+Branch: REL_14_STABLE [f3f70b8de] 2022-11-27 09:18:20 -0500
+Branch: REL_13_STABLE [68d89d80c] 2022-11-27 09:18:32 -0500
+Branch: REL_12_STABLE [85565cbca] 2022-11-27 09:18:40 -0500
+Branch: REL_11_STABLE [724dd5649] 2022-11-27 09:18:46 -0500
+-->
+ <para>
+ Fix mismatch of PL/Perl built with MSVC versus a Perl library built
+ with gcc (Andrew Dunstan)
+ </para>
+
+ <para>
+ Such combinations could previously fail with <quote>loadable library
+ and perl binaries are mismatched</quote> errors.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Andres Freund <andres@anarazel.de>
+Branch: master [388e80132] 2022-12-29 12:47:29 -0800
+Branch: REL_15_STABLE [c6e75e4c2] 2023-01-02 15:49:33 -0800
+Branch: REL_14_STABLE [7b5dec760] 2023-01-02 15:50:00 -0800
+Branch: REL_13_STABLE [ce073d014] 2023-01-02 15:50:33 -0800
+Branch: REL_12_STABLE [f0e13802f] 2023-01-02 15:51:03 -0800
+Branch: REL_11_STABLE [99f8bc335] 2023-01-02 15:51:05 -0800
+-->
+ <para>
+ Suppress compiler warnings from Perl's header files (Andres Freund)
+ </para>
+
+ <para>
+ Our preferred compiler options provoke warnings about constructs
+ appearing in recent versions of Perl's header files. When using
+ <application>gcc</application>, we can suppress these warnings with
+ a pragma.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: REL_15_STABLE [9a40a0311] 2023-01-20 11:58:12 -0500
+Branch: REL_14_STABLE [21c058648] 2023-01-20 11:58:12 -0500
+Branch: REL_13_STABLE [c78f109b8] 2023-01-20 11:58:12 -0500
+Branch: REL_12_STABLE [6d066d56b] 2023-01-20 11:58:12 -0500
+Branch: REL_11_STABLE [b69e9dfab] 2023-01-20 11:58:12 -0500
+-->
+ <para>
+ Fix <application>pg_waldump</application> to build on compilers that
+ don't discard unused static-inline functions (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [758f44bc3] 2023-01-31 17:36:55 -0500
+Branch: REL_15_STABLE [65f0d9d27] 2023-01-31 17:37:06 -0500
+Branch: REL_14_STABLE [7e6154779] 2023-01-31 17:37:14 -0500
+Branch: REL_13_STABLE [20d9da107] 2023-01-31 17:37:22 -0500
+Branch: REL_12_STABLE [2c95d8776] 2023-01-31 17:37:28 -0500
+Branch: REL_11_STABLE [7ddc428ef] 2023-01-31 17:37:34 -0500
+-->
+ <para>
+ Update time zone data files to <application>tzdata</application>
+ release 2022g for DST law changes in Greenland and Mexico,
+ plus historical corrections for northern Canada, Colombia, and
+ Singapore.
+ </para>
+
+ <para>
+ Notably, a new timezone America/Ciudad_Juarez has been split off
+ from America/Ojinaga.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="release-15-1">
+ <title>Release 15.1</title>
+
+ <formalpara>
+ <title>Release date:</title>
+ <para>2022-11-10</para>
+ </formalpara>
+
+ <para>
+ This release contains a variety of fixes from 15.0.
+ For information about new features in major release 15, see
+ <xref linkend="release-15"/>.
+ </para>
+
+ <sect2>
+ <title>Migration to Version 15.1</title>
+
+ <para>
+ A dump/restore is not required for those running 15.X.
+ </para>
+
+ <para>
+ However, if you regularly create and drop tables exceeding 1GB,
+ see the first changelog entry below.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Changes</title>
+
+ <itemizedlist>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [0e758ae89] 2022-11-07 11:36:45 -0500
+Branch: REL_15_STABLE [5fe0ab420] 2022-11-07 11:36:45 -0500
+-->
+ <para>
+ Fix failure to remove non-first segments of large tables
+ (Tom Lane)
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> splits large tables into
+ multiple files (normally with 1GB per file). The logic for dropping
+ a table was broken and would miss removing all but the first such
+ file, in two cases: drops of temporary tables and WAL replay of
+ drops of regular tables. Applications that routinely create
+ multi-gigabyte temporary tables could suffer significant disk space
+ leakage.
+ </para>
+
+ <para>
+ Orphaned temporary-table files are removed during postmaster start,
+ so the mere act of updating to 15.1 is sufficient to clear any
+ leaked temporary-table storage. However, if you suffered any
+ database crashes while using 15.0, and there might have been
+ large tables dropped just before such crashes, it's advisable
+ to check the database directories for files named according to the
+ pattern
+ <literal><replaceable>NNNN</replaceable>.<replaceable>NN</replaceable></literal>.
+ If there is no matching file named
+ just <literal><replaceable>NNNN</replaceable></literal> (without
+ the <literal>.<replaceable>NN</replaceable></literal> suffix), these
+ files should be removed manually.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [b8f2687fd] 2022-10-11 18:24:14 -0400
+Branch: REL_15_STABLE [07ce67698] 2022-10-11 18:24:14 -0400
+Branch: REL_14_STABLE [3162bd95c] 2022-10-11 18:24:14 -0400
+Branch: REL_13_STABLE [21e042b0b] 2022-10-11 18:24:14 -0400
+Branch: REL_12_STABLE [abc510fa2] 2022-10-11 18:24:15 -0400
+Branch: REL_11_STABLE [addde9bc6] 2022-10-11 18:24:15 -0400
+Branch: REL_10_STABLE [23e2a06ac] 2022-10-11 18:24:15 -0400
+-->
+ <para>
+ Fix handling of <literal>DEFAULT</literal> tokens that appear
+ in a multi-row <literal>VALUES</literal> clause of an
+ <command>INSERT</command> on an updatable view (Tom Lane)
+ </para>
+
+ <para>
+ This oversight could lead to <quote>cache lookup failed for
+ type</quote> errors, or in older branches even to crashes.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [797e313dc] 2022-10-17 12:14:39 -0400
+Branch: REL_15_STABLE [4a41a069e] 2022-10-17 12:14:39 -0400
+Branch: REL_14_STABLE [2f26cec48] 2022-10-17 12:14:39 -0400
+Branch: REL_13_STABLE [b21615d1e] 2022-10-17 12:14:39 -0400
+Branch: REL_12_STABLE [65c1106d8] 2022-10-17 12:14:39 -0400
+Branch: REL_11_STABLE [e9377e3e5] 2022-10-17 12:14:39 -0400
+Branch: REL_10_STABLE [ecf4ce689] 2022-10-17 12:14:39 -0400
+-->
+ <para>
+ Disallow rules named <literal>_RETURN</literal> that are
+ not <literal>ON SELECT</literal> (Tom Lane)
+ </para>
+
+ <para>
+ This avoids confusion between a view's <literal>ON SELECT</literal>
+ rule and any other rules it may have.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [d57534740] 2022-10-16 19:18:08 -0400
+Branch: REL_15_STABLE [d4abb0bc5] 2022-10-16 19:18:08 -0400
+Branch: REL_14_STABLE [8122160ff] 2022-10-16 19:18:08 -0400
+-->
+ <para>
+ Avoid failure in <command>EXPLAIN VERBOSE</command> for a query
+ using <literal>SEARCH BREADTH FIRST</literal> with constant
+ initial values (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [cba4e78f3] 2022-10-15 19:24:26 +0200
+Branch: REL_15_STABLE [16d11d684] 2022-10-15 19:24:26 +0200
+-->
+ <para>
+ Prevent use of <command>MERGE</command> on a partitioned table with
+ foreign-table partitions (&Aacute;lvaro Herrera)
+ </para>
+
+ <para>
+ The case isn't supported, and previously threw an incomprehensible
+ error.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [b0284bfb1] 2022-11-03 20:40:21 +0100
+Branch: REL_15_STABLE [c301e1c0c] 2022-11-03 20:40:21 +0100
+Branch: REL_14_STABLE [18865f4df] 2022-11-03 20:40:21 +0100
+Branch: REL_13_STABLE [41b6e7c9a] 2022-11-03 20:40:21 +0100
+Branch: REL_12_STABLE [ab70b3a52] 2022-11-03 20:40:21 +0100
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [614a406b4] 2022-10-07 19:37:48 +0200
+Branch: REL_15_STABLE Release: REL_15_0 [6083132ab] 2022-10-07 19:37:48 +0200
+Branch: REL_14_STABLE [483d26930] 2022-10-07 19:37:48 +0200
+Branch: REL_13_STABLE [7d520e68e] 2022-10-07 19:37:48 +0200
+Branch: REL_12_STABLE [669803af0] 2022-10-07 19:37:48 +0200
+-->
+ <para>
+ Fix construction of per-partition foreign key constraints while
+ doing <command>ALTER TABLE ATTACH PARTITION</command>
+ (Jehan-Guillaume de Rorthais, &Aacute;lvaro Herrera)
+ </para>
+
+ <para>
+ Previously, incorrect or duplicate constraints could be constructed
+ for the newly-added partition.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [f4857082b] 2022-11-01 14:34:44 -0400
+Branch: REL_15_STABLE [1f1865e90] 2022-11-01 14:34:44 -0400
+-->
+ <para>
+ Fix planner failure with extended statistics on partitioned or
+ inherited tables (Richard Guo, Justin Pryzby)
+ </para>
+
+ <para>
+ Some cases failed with <quote>cache lookup failed for statistics
+ object</quote>.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [56b662523] 2022-10-13 09:31:57 +0900
+Branch: REL_15_STABLE [ca4070f2b] 2022-10-26 09:41:13 +0900
+Branch: REL_14_STABLE [5a30d43fa] 2022-10-26 09:41:18 +0900
+Branch: REL_13_STABLE [594b97509] 2022-10-26 09:41:22 +0900
+Branch: REL_12_STABLE [51c24d9e2] 2022-10-26 09:41:26 +0900
+Branch: REL_11_STABLE [341fba2a6] 2022-10-26 09:41:28 +0900
+Branch: REL_10_STABLE [b02fc7df1] 2022-10-26 09:41:31 +0900
+-->
+ <para>
+ Fix mis-ordering of WAL operations in fast insert path for GIN
+ indexes (Matthias van de Meent, Zhang Mingli)
+ </para>
+
+ <para>
+ This mistake is not known to have any negative consequences within
+ core <productname>PostgreSQL</productname>, but it did cause issues
+ for some extensions.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [16b1fe003] 2022-10-20 08:49:48 +0530
+Branch: REL_15_STABLE [64ff0fe4e] 2022-10-20 09:43:59 +0530
+Branch: REL_14_STABLE [a592ed923] 2022-10-20 09:34:18 +0530
+Branch: REL_13_STABLE [25f7be1ca] 2022-10-20 09:25:13 +0530
+Branch: REL_12_STABLE [1bf4d9206] 2022-10-20 09:16:28 +0530
+Branch: REL_11_STABLE [5f7076cb6] 2022-10-20 09:07:04 +0530
+Branch: REL_10_STABLE [10ed7b9e4] 2022-10-20 08:58:11 +0530
+Branch: REL_15_STABLE [343afa967] 2022-10-21 10:03:35 +0530
+Branch: REL_14_STABLE [4fbe6096b] 2022-10-21 09:52:44 +0530
+Branch: REL_13_STABLE [38dbaaf27] 2022-10-21 09:42:24 +0530
+Branch: REL_12_STABLE [02600886c] 2022-10-21 09:32:21 +0530
+Branch: REL_11_STABLE [216af69ae] 2022-10-21 09:22:20 +0530
+-->
+ <para>
+ Fix bugs in logical decoding when replay starts from a point
+ between the beginning of a transaction and the beginning of its
+ subtransaction (Masahiko Sawada, Kuroda Hayato)
+ </para>
+
+ <para>
+ These errors could lead to assertion failures in debug builds, and
+ otherwise to memory leaks.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [ce20f8b9f] 2022-10-21 12:57:18 +0530
+Branch: REL_15_STABLE [10eaa9750] 2022-10-21 12:43:28 +0530
+Branch: REL_14_STABLE [36fc013fa] 2022-10-21 12:33:47 +0530
+Branch: REL_13_STABLE [1eed947f9] 2022-10-21 12:22:47 +0530
+Branch: REL_12_STABLE [f7f82cf05] 2022-10-21 12:10:11 +0530
+Branch: REL_11_STABLE [5c51afe23] 2022-10-21 12:08:14 +0530
+Branch: REL_10_STABLE [61838d2dd] 2022-10-21 11:54:34 +0530
+Author: Amit Kapila <akapila@postgresql.org>
+Branch: master [f972ec5c2] 2022-08-23 10:20:02 +0530
+Branch: REL_15_STABLE Release: REL_15_0 [42681dffa] 2022-08-23 10:08:43 +0530
+Branch: REL_14_STABLE [6d05d575b] 2022-08-23 09:24:51 +0530
+Branch: REL_13_STABLE [4985a4591] 2022-08-23 09:10:28 +0530
+Branch: REL_12_STABLE [9415873ae] 2022-08-23 08:51:20 +0530
+Branch: REL_11_STABLE [51e9469a4] 2022-08-23 08:42:51 +0530
+Branch: REL_10_STABLE [6b50433e8] 2022-08-23 08:39:31 +0530
+-->
+ <para>
+ Accept interrupts in more places during logical decoding (Amit
+ Kapila, Masahiko Sawada)
+ </para>
+
+ <para>
+ This ameliorates problems with slow shutdown of replication workers.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [be541efbf] 2022-11-02 12:29:39 -0400
+Branch: REL_15_STABLE [414d29a82] 2022-11-02 12:29:39 -0400
+Branch: REL_14_STABLE [a5b7821fc] 2022-11-02 12:29:39 -0400
+Branch: REL_13_STABLE [4d3f7e75c] 2022-11-02 12:29:39 -0400
+-->
+ <para>
+ Prevent attempts to replicate into a foreign-table partition in
+ replication workers (Shi Yu, Tom Lane)
+ </para>
+
+ <para>
+ Although partitioned tables can have foreign tables as partitions,
+ replicating into such a partition isn't currently supported.
+ The logical replication worker process would crash if it was
+ attempted. Now, an error is thrown.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [dea834938] 2022-11-03 12:02:14 -0400
+Branch: REL_15_STABLE [f2dc7f9e3] 2022-11-03 12:01:57 -0400
+Branch: REL_14_STABLE [2489c38cd] 2022-11-03 12:01:57 -0400
+Branch: REL_13_STABLE [b00f342ea] 2022-11-03 12:01:57 -0400
+Branch: REL_12_STABLE [d9ffccf8d] 2022-11-03 12:01:57 -0400
+Branch: REL_11_STABLE [ed019b5ef] 2022-11-03 12:01:57 -0400
+Branch: REL_10_STABLE [5f3cec77b] 2022-11-03 12:01:57 -0400
+-->
+ <para>
+ Avoid crash after function syntax error in replication workers
+ (Maxim Orlov, Anton Melnikov, Masahiko Sawada, Tom Lane)
+ </para>
+
+ <para>
+ If a syntax error occurred in a SQL-language or PL/pgSQL-language
+ <command>CREATE FUNCTION</command> or <command>DO</command> command
+ executed in a logical replication worker, the worker process would
+ crash with a null pointer dereference or assertion failure.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+Branch: master [9668c4a66] 2022-10-19 14:06:56 +0900
+Branch: REL_15_STABLE [5d2a47a29] 2022-10-19 14:07:01 +0900
+-->
+ <para>
+ Avoid double call of the shutdown callback of an archiver module
+ (Nathan Bossart, Bharath Rupireddy)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [eec346611] 2022-10-17 11:35:23 -0400
+Branch: REL_15_STABLE [2e3326929] 2022-10-17 11:35:23 -0400
+Branch: REL_14_STABLE [8c611602b] 2022-10-17 11:35:23 -0400
+Branch: REL_13_STABLE [62b263bf7] 2022-10-17 11:35:23 -0400
+Branch: REL_12_STABLE [99b6b705d] 2022-10-17 11:35:23 -0400
+-->
+ <para>
+ Add plan-time check for attempted access to a table that has no
+ table access method (Tom Lane)
+ </para>
+
+ <para>
+ This prevents a crash in some catalog-corruption scenarios, for
+ example use of a view whose <literal>ON SELECT</literal> rule is
+ missing.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [18a4a620e] 2022-10-11 18:54:31 -0400
+Branch: REL_15_STABLE [e7b4ff327] 2022-10-11 18:54:31 -0400
+Branch: REL_14_STABLE [b10546ecf] 2022-10-11 18:54:31 -0400
+Branch: REL_13_STABLE [744270137] 2022-10-11 18:54:31 -0400
+Branch: REL_12_STABLE [8f98352b5] 2022-10-11 18:54:31 -0400
+Branch: REL_11_STABLE [6c1de98ba] 2022-10-11 18:54:31 -0400
+Branch: REL_10_STABLE [ab35b9dd7] 2022-10-11 18:54:31 -0400
+-->
+ <para>
+ Prevent postmaster crash when shared-memory state is corrupted
+ (Tom Lane)
+ </para>
+
+ <para>
+ The postmaster process is supposed to survive and initiate a
+ database restart if shared memory becomes corrupted, but one
+ bit of code was being insufficiently cautious about that.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+Branch: master [db1b931a4] 2022-10-14 19:06:26 +0200
+Branch: REL_15_STABLE [27ca0bce5] 2022-10-14 19:06:26 +0200
+Branch: REL_14_STABLE [b8af4166f] 2022-10-14 19:06:26 +0200
+-->
+ <para>
+ In <application>libpq</application>, handle single-row mode
+ correctly when pipelining (Denis Laxalde)
+ </para>
+
+ <para>
+ The single-row flag was not reset at the correct time if pipeline
+ mode was also active.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+Branch: master [2598b76bf] 2022-10-22 09:42:52 +0200
+Branch: REL_15_STABLE [4a6de748d] 2022-10-22 09:41:38 +0200
+-->
+ <para>
+ Fix <application>psql</application>'s exit status when a
+ command-line query is canceled (Peter Eisentraut)
+ </para>
+
+ <para>
+ <literal>psql -c <replaceable>query</replaceable></literal> would
+ exit successfully if the query was canceled. Fix it to exit with
+ nonzero status, as in other error cases.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+Branch: master [1f0c4fa25] 2022-10-21 08:21:55 -0400
+Branch: REL_15_STABLE [5c013e620] 2022-10-21 08:31:39 -0400
+Branch: REL_14_STABLE [aaad8adb0] 2022-10-21 08:39:48 -0400
+Branch: REL_13_STABLE [0bf2cd160] 2022-10-21 08:45:08 -0400
+Branch: REL_12_STABLE [475e9daf3] 2022-10-21 08:59:26 -0400
+Branch: REL_11_STABLE [38214dabd] 2022-10-21 09:05:57 -0400
+Branch: REL_10_STABLE [ba58266eb] 2022-10-21 09:11:47 -0400
+-->
+ <para>
+ Allow cross-platform tablespace relocation
+ in <application>pg_basebackup</application> (Robert Haas)
+ </para>
+
+ <para>
+ Allow the remote path in <option>--tablespace-mapping</option> to be
+ either a Unix-style or Windows-style absolute path, since the source
+ server could be on a different OS than the local system.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [26ee7fb36] 2022-11-02 11:30:04 -0400
+Branch: REL_15_STABLE [0eede9625] 2022-11-02 11:30:04 -0400
+-->
+ <para>
+ Fix <application>pg_dump</application>'s failure to dump comments
+ attached to some <literal>CHECK</literal> constraints (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [34fa0ddae] 2022-11-04 10:39:52 -0400
+Branch: REL_15_STABLE [2c6d43650] 2022-11-04 10:39:52 -0400
+-->
+ <para>
+ Fix <command>CREATE DATABASE</command> to allow
+ its <literal>oid</literal> parameter to exceed
+ 2<superscript>31</superscript> (Tom Lane)
+ </para>
+
+ <para>
+ This oversight prevented <application>pg_upgrade</application> from
+ succeeding when the source installation contained databases with
+ OIDs larger than that.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [495e73c20] 2022-11-01 12:48:01 -0400
+Branch: REL_15_STABLE [8b0a5cf3f] 2022-11-01 12:48:01 -0400
+Branch: REL_14_STABLE [0f2f5645a] 2022-11-01 12:48:01 -0400
+Branch: REL_13_STABLE [a9fdb48b7] 2022-11-01 12:48:01 -0400
+Branch: REL_12_STABLE [ca4c6764b] 2022-11-01 12:48:01 -0400
+Branch: REL_11_STABLE [149e00192] 2022-11-01 12:48:01 -0400
+Branch: REL_10_STABLE [56083ff30] 2022-11-01 12:48:01 -0400
+-->
+ <para>
+ In <application>pg_stat_statements</application>, fix access to
+ already-freed memory (zhaoqigui)
+ </para>
+
+ <para>
+ This occurred if <application>pg_stat_statements</application>
+ tracked a <command>ROLLBACK</command> command issued via extended
+ query protocol. In debug builds it consistently led to an assertion
+ failure. In production builds there would often be no visible ill
+ effect; but if the freed memory had already been reused, the likely
+ result would be to store garbage for the query string.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+Branch: master [c2ae01f69] 2022-10-19 22:18:26 +1300
+Branch: REL_15_STABLE [af64846e1] 2022-10-19 22:18:54 +1300
+Branch: REL_14_STABLE [d033f8f8b] 2022-10-19 22:32:14 +1300
+Branch: REL_13_STABLE [cf94cb586] 2022-10-19 22:38:58 +1300
+Branch: REL_12_STABLE [aa34bc4e2] 2022-10-19 22:44:53 +1300
+Branch: REL_11_STABLE [da3a6825e] 2022-10-19 22:49:25 +1300
+-->
+ <para>
+ Fix incompatibilities with LLVM 15 (Thomas Munro, Andres Freund)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [1c72d82c2] 2022-11-02 17:37:29 -0400
+Branch: REL_15_STABLE [a5737e765] 2022-11-02 17:37:26 -0400
+Branch: REL_14_STABLE [058c7b5dd] 2022-11-02 17:37:26 -0400
+Branch: REL_13_STABLE [c479492c0] 2022-11-02 17:37:26 -0400
+Branch: REL_12_STABLE [5ecf836e9] 2022-11-02 17:37:26 -0400
+Branch: REL_11_STABLE [a0f9be1f9] 2022-11-02 17:37:26 -0400
+Branch: REL_10_STABLE [19cefebe7] 2022-11-02 17:37:26 -0400
+-->
+ <para>
+ Allow use of <function>__sync_lock_test_and_set()</function> for
+ spinlocks on any machine (Tom Lane)
+ </para>
+
+ <para>
+ This eases porting to new machine architectures, at least if you're
+ using a compiler that supports this GCC builtin function.
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [717ec1aae] 2022-10-16 15:27:04 -0400
+Branch: REL_15_STABLE [24c4c2617] 2022-10-16 15:27:04 -0400
+Branch: REL_14_STABLE [18e60712d] 2022-10-16 15:27:04 -0400
+Branch: REL_13_STABLE [bc7a40b42] 2022-10-16 15:27:04 -0400
+Branch: REL_12_STABLE [3d7df87c4] 2022-10-16 15:27:04 -0400
+Branch: REL_11_STABLE [6618c276b] 2022-10-16 15:27:04 -0400
+Branch: REL_10_STABLE [02d074e3e] 2022-10-16 15:27:04 -0400
+Branch: REL9_6_STABLE [9bfa043a1] 2022-10-16 15:27:04 -0400
+Branch: REL9_5_STABLE [377b37cf7] 2022-10-16 15:27:04 -0400
+Branch: REL9_4_STABLE [57dfb6ce6] 2022-10-16 15:27:04 -0400
+Branch: REL9_3_STABLE [ee4c44014] 2022-10-16 15:27:04 -0400
+Branch: REL9_2_STABLE [fec443414] 2022-10-16 15:27:04 -0400
+-->
+ <para>
+ Rename symbol <literal>REF</literal> to <literal>REF_P</literal> to
+ avoid compile failure on recent macOS (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [450ee7012] 2022-10-16 11:47:44 -0400
+Branch: REL_15_STABLE [bd4b2926e] 2022-10-16 11:47:44 -0400
+Branch: REL_14_STABLE [6fa431d84] 2022-10-16 11:47:44 -0400
+Branch: REL_13_STABLE [a2acafc7b] 2022-10-16 11:47:44 -0400
+Branch: REL_12_STABLE [d33ac1ec2] 2022-10-16 11:47:44 -0400
+-->
+ <para>
+ Avoid using <function>sprintf</function>, to avoid compile-time
+ deprecation warnings (Tom Lane)
+ </para>
+ </listitem>
+
+ <listitem>
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+Branch: master [e7c7605a7] 2022-11-01 17:08:28 -0400
+Branch: REL_15_STABLE [c3d16eb3d] 2022-11-01 17:08:49 -0400
+Branch: REL_14_STABLE [97bb80b1b] 2022-11-01 17:08:58 -0400
+Branch: REL_13_STABLE [ebf48810b] 2022-11-01 17:09:04 -0400
+Branch: REL_12_STABLE [ec9a000d8] 2022-11-01 17:09:09 -0400
+Branch: REL_11_STABLE [b1cb77bdf] 2022-11-01 17:09:16 -0400
+Branch: REL_10_STABLE [b3326a753] 2022-11-01 17:09:21 -0400
+-->
+ <para>
+ Update time zone data files to <application>tzdata</application>
+ release 2022f for DST law changes in Chile, Fiji, Iran, Jordan,
+ Mexico, Palestine, and Syria, plus historical corrections for Chile,
+ Crimea, Iran, and Mexico.
+ </para>
+
+ <para>
+ Also, the Europe/Kiev zone has been renamed to Europe/Kyiv.
+ Also, the following zones have been merged into nearby,
+ more-populous zones whose clocks have agreed with them since 1970:
+ Antarctica/Vostok, Asia/Brunei,
+ Asia/Kuala_Lumpur, Atlantic/Reykjavik, Europe/Amsterdam,
+ Europe/Copenhagen, Europe/Luxembourg, Europe/Monaco, Europe/Oslo,
+ Europe/Stockholm, Indian/Christmas, Indian/Cocos, Indian/Kerguelen,
+ Indian/Mahe, Indian/Reunion, Pacific/Chuuk, Pacific/Funafuti,
+ Pacific/Majuro, Pacific/Pohnpei, Pacific/Wake and Pacific/Wallis.
+ (This indirectly affects zones that were already links to one of
+ these: Arctic/Longyearbyen, Atlantic/Jan_Mayen, Iceland,
+ Pacific/Ponape, Pacific/Truk, and Pacific/Yap.) America/Nipigon,
+ America/Rainy_River, America/Thunder_Bay, Europe/Uzhgorod, and
+ Europe/Zaporozhye were also merged into nearby zones after
+ discovering that their claimed post-1970 differences from those
+ zones seem to have been errors.
+ In all these cases, the previous zone name remains as an alias;
+ but the actual data is that of the zone that was merged into.
+ </para>
+
+ <para>
+ These zone mergers result in loss of pre-1970 timezone history for
+ the merged zones, which may be troublesome for applications
+ expecting consistency of <type>timestamptz</type> display. As an
+ example, the stored value <literal>1944-06-01 12:00 UTC</literal>
+ would previously display as <literal>1944-06-01
+ 13:00:00+01</literal> if the Europe/Stockholm zone is selected, but
+ now it will read out as <literal>1944-06-01 14:00:00+02</literal>.
+ </para>
+
+ <para>
+ It is possible to build the time zone data files with options that
+ will restore the older zone data, but that choice also inserts a lot
+ of other old (and typically poorly-attested) zone data, resulting in
+ more total changes from the previous release than accepting these
+ upstream changes does. <productname>PostgreSQL</productname> has
+ chosen to ship the <productname>tzdb</productname> data
+ as-recommended, and so far as we are aware most major operating
+ system distributions are doing likewise. However, if these changes
+ cause significant problems for your application, a possible solution
+ is to install a local build of the time zone data files using
+ <productname>tzdb</productname>'s backwards-compatibility options
+ (see their <literal>PACKRATDATA</literal>
+ and <literal>PACKRATLIST</literal> options).
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="release-15">
+ <title>Release 15</title>
+
+ <formalpara>
+ <title>Release date:</title>
+ <para>2022-10-13</para>
+ </formalpara>
+
+ <sect2>
+ <title>Overview</title>
+
+ <para>
+ <productname>PostgreSQL</productname> 15 contains many new features
+ and enhancements, including:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Support for the <acronym>SQL</acronym>
+ <link linkend="sql-merge"><command>MERGE</command></link> command.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Selective publication of tables' contents within
+ <link linkend="logical-replication">logical replication</link>
+ publications, through the ability to specify column lists and
+ row filter conditions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ More options for compression, including support for Zstandard (zstd)
+ compression. This includes support for performing compression on
+ the server side during
+ <link linkend="app-pgbasebackup"><application>pg_basebackup</application></link>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Support for structured <link linkend="guc-log-destination">server
+ log output</link> using the <acronym>JSON</acronym> format.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Performance improvements, particularly for in-memory and on-disk
+ sorting.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The above items and other new features of
+ <productname>PostgreSQL</productname> 15 are explained in more detail
+ in the sections below.
+ </para>
+
+ </sect2>
+
+ <sect2>
+
+ <title>Migration to Version 15</title>
+
+ <para>
+ A dump/restore using <xref linkend="app-pg-dumpall"/> or use of
+ <xref linkend="pgupgrade"/> or logical replication is required for
+ those wishing to migrate data from any previous release. See <xref
+ linkend="upgrading"/> for general information on migrating to new
+ major releases.
+ </para>
+
+ <para>
+ Version 15 contains a number of changes that may affect compatibility
+ with previous releases. Observe the following incompatibilities:
+ </para>
+
+ <itemizedlist>
+
+<!--
+Author: Noah Misch <noah@leadboat.com>
+2021-09-09 [b073c3ccd] Revoke PUBLIC CREATE from public schema, now owned by pg
+-->
+
+ <listitem>
+ <para>
+ Remove <literal>PUBLIC</literal> creation permission on the <link
+ linkend="ddl-schemas-public"><literal>public</literal> schema</link>
+ (Noah Misch)
+ </para>
+
+ <para>
+ The new default is one of the secure schema usage patterns that <xref
+ linkend="ddl-schemas-patterns"/> has recommended since the security
+ release for CVE-2018-1058. The change applies to new database
+ clusters and to newly-created databases in existing clusters.
+ Upgrading a cluster or restoring a database dump will preserve
+ <literal>public</literal>'s existing permissions.
+ </para>
+
+ <para>
+ For existing databases, especially those having multiple users,
+ consider revoking <literal>CREATE</literal> permission on
+ the <literal>public</literal> schema to adopt this new default.
+ For new databases having no need to defend against insider threats,
+ granting <literal>CREATE</literal> permission will yield the behavior
+ of prior releases.
+ </para>
+ </listitem>
+
+<!--
+Author: Noah Misch <noah@leadboat.com>
+2021-09-09 [b073c3ccd] Revoke PUBLIC CREATE from public schema, now owned by pg
+-->
+
+ <listitem>
+ <para>
+ Change the owner of the <literal>public</literal> schema to be the
+ new <literal>pg_database_owner</literal> role (Noah Misch)
+ </para>
+
+ <para>
+ This allows each database's owner to have ownership privileges on
+ the <literal>public</literal> schema within their database.
+ Previously it was owned by the bootstrap superuser, so that
+ non-superuser database owners could not do anything with it.
+ </para>
+
+ <para>
+ This change applies to new database clusters and to newly-created
+ databases in existing clusters.
+ Upgrading a cluster or restoring a database dump will preserve
+ <literal>public</literal>'s existing ownership specification.
+ </para>
+ </listitem>
+
+<!--
+Author: Stephen Frost <sfrost@snowman.net>
+2022-04-06 [39969e2a1] Remove exclusive backup mode
+-->
+
+ <listitem>
+ <para>
+ Remove long-deprecated <link linkend="backup-base-backup">exclusive
+ backup mode</link> (David Steele, Nathan Bossart)
+ </para>
+
+ <para>
+ If the database server stops abruptly while in this mode, the
+ server could fail to start. The non-exclusive backup mode is
+ considered superior for all purposes. Functions
+ <function>pg_start_backup()</function>/<function>pg_stop_backup()</function>
+ have been renamed to
+ <function>pg_backup_start()</function>/<function>pg_backup_stop()</function>,
+ and the functions <function>pg_backup_start_time()</function>
+ and <function>pg_is_in_backup()</function> have been removed.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Geoghegan <pg@bowt.ie>
+2022-02-16 [8f388f6f5] Increase hash_mem_multiplier default to 2.0.
+-->
+
+ <listitem>
+ <para>
+ Increase <link
+ linkend="guc-hash-mem-multiplier"><varname>hash_mem_multiplier</varname></link>
+ default to 2.0 (Peter Geoghegan)
+ </para>
+
+ <para>
+ This allows query hash operations to use more
+ <link linkend="guc-work-mem"><varname>work_mem</varname></link>
+ memory than other operations.
+ </para>
+ </listitem>
+
+<!--
+Author: Andres Freund <andres@anarazel.de>
+2022-03-07 [76a29adee] plpython: Remove plpythonu, plpython2u and associated tr
+-->
+
+ <listitem>
+ <para>
+ Remove server-side language <link
+ linkend="plpython"><literal>plpython2u</literal></link> and generic
+ Python language <literal>plpythonu</literal> (Andres Freund)
+ </para>
+
+ <para>
+ Python 2.x is no longer supported. While the original intent of
+ <literal>plpythonu</literal> was that it could eventually refer
+ to <literal>plpython3u</literal>, changing it now seems more likely
+ to cause problems than solve them, so it's just been removed.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-11-06 [cbe25dcff] Disallow making an empty lexeme via array_to_tsvector().
+-->
+
+ <listitem>
+ <para>
+ Generate an error if <link
+ linkend="textsearch-functions-table"><function>array_to_tsvector()</function></link>
+ is passed an empty-string array element (Jean-Christophe Arnu)
+ </para>
+
+ <para>
+ This is prohibited because lexemes should never be empty. Users of
+ previous Postgres releases should verify that no empty lexemes
+ are stored because they can lead to dump/restore failures and
+ inconsistent results.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-12-06 [e9e63b702] Fix inappropriate uses of PG_GETARG_UINT32()
+-->
+
+ <listitem>
+ <para>
+ Generate an error when <link
+ linkend="functions-string-other"><function>chr()</function></link>
+ is supplied with a negative argument (Peter Eisentraut)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-15 [2523928b2] Reject change of output-column collation in CREATE OR RE
+-->
+
+ <listitem>
+ <para>
+ Prevent <link linkend="sql-createview"><command>CREATE OR REPLACE
+ VIEW</command></link> from changing the collation of an output column
+ (Tom Lane)
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-01-12 [a18b6d2dc] ecpg: Catch zero-length Unicode identifiers correctly
+-->
+
+ <listitem>
+ <para>
+ Disallow zero-length <link
+ linkend="sql-syntax-identifiers">Unicode identifiers</link>,
+ e.g., <literal>U&amp;""</literal>
+ (Peter Eisentraut)
+ </para>
+
+ <para>
+ Non-Unicode zero-length identifiers were already disallowed.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-02-16 [2549f0661] Reject trailing junk after numeric literals
+-->
+
+ <listitem>
+ <para>
+ Prevent <link linkend="sql-syntax-constants-numeric">numeric
+ literals</link> from having non-numeric trailing characters (Peter
+ Eisentraut)
+ </para>
+
+ <para>
+ Previously, query text like <literal>123abc</literal> would be
+ interpreted as <literal>123</literal> followed
+ by a separate token <literal>abc</literal>.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-03-28 [e26114c81] Make JSON path numeric literals more correct
+-->
+
+ <listitem>
+ <para>
+ Adjust <link linkend="datatype-json"><acronym>JSON</acronym></link>
+ numeric literal processing to match the
+ <acronym>SQL</acronym>/<acronym>JSON</acronym>-standard (Peter
+ Eisentraut)
+ </para>
+
+ <para>
+ This accepts numeric formats like <literal>.1</literal> and
+ <literal>1.</literal>, and disallows trailing junk after numeric
+ literals, like <literal>1.type()</literal>.
+ </para>
+ </listitem>
+
+<!--
+Author: Bruce Momjian <bruce@momjian.us>
+2021-08-03 [95ab1e0a9] interval: round values when spilling to months
+-->
+
+ <listitem>
+ <para>
+ When <link linkend="datatype-datetime"><type>interval</type></link>
+ input provides a fractional value for a unit greater than months,
+ round to the nearest month (Bruce Momjian)
+ </para>
+
+ <para>
+ For example, convert <literal>1.99 years</literal> to <literal>2
+ years</literal>, not <literal>1 year 11 months</literal> as before.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-03 [591e088dd] Fix portability issues in datetime parsing.
+-->
+
+ <listitem>
+ <para>
+ Improve consistency of <type>interval</type> parsing with trailing
+ periods (Tom Lane)
+ </para>
+
+ <para>
+ Numbers with trailing periods were rejected on some platforms.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-19 [a3d6264bb] interval_out() must be marked STABLE, not IMMUTABLE.
+-->
+
+ <listitem>
+ <para>
+ Mark the <type>interval</type> output
+ function as stable, not immutable, since it depends on <link
+ linkend="guc-intervalstyle"><varname>IntervalStyle</varname></link>
+ (Tom Lane)
+ </para>
+
+ <para>
+ This will, for example, cause creation of indexes relying on the
+ text output of <type>interval</type> values to fail.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-28 [54bd1e43c] Handle integer overflow in interval justification functi
+-->
+
+ <listitem>
+ <para>
+ Detect integer overflow in <link
+ linkend="functions-datetime-table">interval justification
+ functions</link> (Joe Koshakow)
+ </para>
+
+ <para>
+ The affected functions are <function>justify_interval()</function>,
+ <function>justify_hours()</function>, and
+ <function>justify_days()</function>.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-08-02 [c034b629c] Change type "char"'s I/O format for non-ASCII characters
+-->
+
+ <listitem>
+ <para>
+ Change the I/O format of type <type>"char"</type> for non-ASCII
+ characters (Tom Lane)
+ </para>
+
+ <para>
+ Bytes with the high bit set are now output as a backslash and three
+ octal digits, to avoid encoding issues.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-28 [79de9842a] Remove the ability of a role to administer itself.
+-->
+
+ <listitem>
+ <para>
+ Remove the default <link linkend="sql-createrole"><literal>ADMIN
+ OPTION</literal></link> privilege a login role has on its own role
+ membership (Robert Haas)
+ </para>
+
+ <para>
+ Previously, a login role could add/remove members of its own role,
+ even without <literal>ADMIN OPTION</literal> privilege.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2022-01-07 [a2ab9c06e] Respect permissions within logical replication.
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="logical-replication">logical replication</link>
+ to run as the owner of the subscription (Mark Dilger)
+ </para>
+
+ <para>
+ Because row-level security policies are not checked, only superusers,
+ roles with <literal>bypassrls</literal>, and table owners can
+ replicate into tables with row-level security policies.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2022-01-08 [96a6f11c0] More cleanup of a2ab9c06ea.
+-->
+
+ <listitem>
+ <para>
+ Prevent <command>UPDATE</command> and <command>DELETE</command>
+ <link linkend="logical-replication">logical replication</link>
+ operations on tables where the subscription owner does not have
+ <command>SELECT</command> permission on the table (Jeff Davis)
+ </para>
+
+ <para>
+ <command>UPDATE</command> and <command>DELETE</command> commands
+ typically involve reading the table as well, so require the
+ subscription owner to have table <command>SELECT</command>
+ permission.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-07-27 [48c5c9068] Use the "pg_temp" schema alias in EXPLAIN and related ou
+-->
+
+ <listitem>
+ <para>
+ When <link linkend="sql-explain"><command>EXPLAIN</command></link>
+ references the session's temporary object schema, refer to it as
+ <literal>pg_temp</literal> (Amul Sul)
+ </para>
+
+ <para>
+ Previously the actual schema name was reported, leading to
+ inconsistencies across sessions.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-03-24 [ce95c5437] Fix pg_statio_all_tables view for multiple TOAST indexes
+-->
+
+ <listitem>
+ <para>
+ Fix <link
+ linkend="monitoring-pg-statio-all-tables-view"><structname>pg_statio_all_tables</structname></link>
+ to sum values for the rare case of <acronym>TOAST</acronym> tables
+ with multiple indexes (Andrei Zubkov)
+ </para>
+
+ <para>
+ Previously such cases would show one row for each index.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-12-01 [75d22069e] Warning on SET of nonexisting setting with a prefix rese
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-27 [2ed8a8cc5] Rethink handling of settings with a prefix reserved by a
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-21 [88103567c] Disallow setting bogus GUCs within an extension's reserv
+-->
+
+ <listitem>
+ <para>
+ Disallow setting <link linkend="runtime-config-custom">custom
+ options</link> that match the name of an installed extension, but
+ are not one of the extension's declared variables
+ (Florin Irion, Tom Lane)
+ </para>
+
+ <para>
+ This change causes any such pre-existing variables to be deleted
+ during extension load, and then prevents new ones from being created
+ later in the session. The intent is to prevent confusion about
+ whether a variable is associated with an extension or not.
+ </para>
+ </listitem>
+
+<!--
+Author: Andres Freund <andres@anarazel.de>
+2022-04-06 [6f0cf8787] pgstat: remove stats_temp_directory.
+-->
+
+ <listitem>
+ <para>
+ Remove obsolete server variable
+ <varname>stats_temp_directory</varname> (Andres Freund, Kyotaro
+ Horiguchi)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-11-28 [3804539e4] Replace random(), pg_erand48(), etc with a better PRNG A
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-12 [d4f109e4a] Doc: update description of random() function.
+-->
+
+ <listitem>
+ <para>
+ Improve the algorithm used to compute <link
+ linkend="functions-math-random-table"><function>random()</function></link>
+ (Fabien Coelho)
+ </para>
+
+ <para>
+ This will cause <function>random()</function>'s results to differ
+ from what was emitted by prior versions, even for the same seed
+ value.
+ </para>
+ </listitem>
+
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-09-23 [bd8ac900d] Remove PQsendQuery support in pipeline mode
+-->
+
+ <listitem>
+ <para>
+ <application>libpq</application>'s <link
+ linkend="libpq-PQsendQuery"><function>PQsendQuery()</function></link>
+ function is no longer supported in pipeline mode (Álvaro Herrera)
+ </para>
+
+ <para>
+ Applications that are using that combination will need to be
+ modified to use <function>PQsendQueryParams()</function> instead.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-09 [376ce3e40] Prefer $HOME when looking up the current user's home dir
+-->
+
+ <listitem>
+ <para>
+ On non-Windows platforms, consult the <envar>HOME</envar> environment
+ variable to find the user's home directory (Anders Kaseorg)
+ </para>
+
+ <para>
+ If <envar>HOME</envar> is empty or unset, fall back to the previous
+ method of checking the <literal>&lt;pwd.h&gt;</literal> database.
+ This change affects <application>libpq</application> (for example,
+ while looking up <filename>~/.pgpass</filename>) as well as various
+ client application programs.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-15 [2a712066d] Remove pg_dump's - -no-synchronized-snapshots switch.
+-->
+
+ <listitem>
+ <para>
+ Remove <link
+ linkend="app-pgdump"><application>pg_dump</application></link>'s
+ <option>--no-synchronized-snapshots</option> option (Tom Lane)
+ </para>
+
+ <para>
+ All still-supported server versions support synchronized snapshots,
+ so there's no longer a need for this option.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-06-15 [a3ff08e0b] Tweak behavior of psql - -single-transaction depending
+-->
+
+ <listitem>
+ <para>
+ After an error is detected in <link
+ linkend="app-psql"><application>psql</application></link>'s
+ <option>--single-transaction</option> mode, change the
+ final <command>COMMIT</command> command
+ to <command>ROLLBACK</command> only
+ if <varname>ON_ERROR_STOP</varname> is set (Michael Paquier)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-11-12 [f8abb0f5e] postgres_fdw: suppress casts on constants in limited cas
+-->
+
+ <listitem>
+ <para>
+ Avoid unnecessary casting of constants in queries sent by <link
+ linkend="postgres-fdw">postgres_fdw</link> (Dian Fay)
+ </para>
+
+ <para>
+ When column types are intentionally different between local and
+ remote databases, such casts could cause errors.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-14 [fd2abeb7c] Delete contrib/xml2's legacy implementation of xml_is_we
+-->
+
+ <listitem>
+ <para>
+ Remove <link linkend="xml2">xml2</link>'s
+ <function>xml_is_well_formed()</function> function (Tom Lane)
+ </para>
+
+ <para>
+ This function has been implemented in the core backend since
+ Postgres 9.1.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-07-06 [955b3e0f9] Allow CustomScan providers to say whether they support p
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="custom-scan">custom scan providers</link>
+ to indicate if they support projections (Sven Klemm)
+ </para>
+
+ <para>
+ The default is now that custom scan providers are assumed to not
+ support projections; those that do will need to be updated for
+ this release.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect2>
+
+ <sect2>
+ <title>Changes</title>
+
+ <para>
+ Below you will find a detailed account of the changes between
+ <productname>PostgreSQL</productname> 15 and the previous major
+ release.
+ </para>
+
+ <sect3>
+ <title>Server</title>
+
+ <itemizedlist>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-02-14 [37851a8b8] Database-level collation version tracking
+-->
+
+ <listitem>
+ <para>
+ Record and check the collation version of each <link
+ linkend="sql-createdatabase">database</link> (Peter Eisentraut)
+ </para>
+
+ <para>
+ This feature is designed to detect collation version
+ changes to avoid index corruption. Function
+ <function>pg_database_collation_actual_version()</function>
+ reports the underlying operating system collation version, and
+ <command>ALTER DATABASE ... REFRESH</command> sets the recorded
+ database collation version to match the operating system collation
+ version.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-03-17 [f2553d430] Add option to use ICU as global locale provider
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="locale"><acronym>ICU</acronym></link>
+ collations to be set as the default for clusters and databases
+ (Peter Eisentraut)
+ </para>
+
+ <para>
+ Previously, only <application>libc</application>-based
+ collations could be selected at the cluster and database levels.
+ <acronym>ICU</acronym> collations could only be used via explicit
+ <literal>COLLATE</literal> clauses.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-03-29 [a2c84990b] Add system view pg_ident_file_mappings
+-->
+
+ <listitem>
+ <para>
+ Add system view <link
+ linkend="view-pg-ident-file-mappings"><structname>pg_ident_file_mappings</structname></link>
+ to report <filename>pg_ident.conf</filename> information (Julien
+ Rouhaud)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <sect4>
+ <title><link linkend="ddl-partitioning">Partitioning</link></title>
+
+ <itemizedlist>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2021-08-03 [475dbd0b7] Track a Bitmapset of non-pruned partitions in RelOptInfo
+-->
+
+ <listitem>
+ <para>
+ Improve planning time for queries referencing partitioned tables
+ (David Rowley)
+ </para>
+
+ <para>
+ This change helps when only a few of many partitions are relevant.
+ </para>
+ </listitem>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2021-08-03 [db632fbca] Allow ordered partition scans in more cases
+-->
+
+ <listitem>
+ <para>
+ Allow ordered scans of partitions to avoid sorting in more cases
+ (David Rowley)
+ </para>
+
+ <para>
+ Previously, a partitioned table with a <literal>DEFAULT</literal>
+ partition or a <literal>LIST</literal> partition containing
+ multiple values could not be used for ordered partition scans.
+ Now they can be used if such partitions are pruned during planning.
+ </para>
+ </listitem>
+
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-03-20 [ba9a7e392] Enforce foreign key correctly during cross-partition upd
+-->
+
+ <listitem>
+ <para>
+ Improve foreign key behavior of updates on partitioned tables
+ that move rows between partitions (Amit Langote)
+ </para>
+
+ <para>
+ Previously, such updates ran a delete action on the source
+ partition and an insert action on the target partition.
+ <productname>PostgreSQL</productname> will now run an update action
+ on the partition root, providing cleaner semantics.
+ </para>
+ </listitem>
+
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-04-02 [cfdd03f45] Allow CLUSTER on partitioned tables
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-04-14 [3f19e176a] Have CLUSTER ignore partitions not owned by caller
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-cluster"><command>CLUSTER</command></link>
+ on partitioned tables (Justin Pryzby)
+ </para>
+ </listitem>
+
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2021-07-22 [80ba4bb38] Make ALTER TRIGGER RENAME consistent for partitioned tab
+-->
+
+ <listitem>
+ <para>
+ Fix <link linkend="sql-altertable"><command>ALTER TRIGGER
+ RENAME</command></link> on partitioned tables to properly rename
+ triggers on all partitions (Arne Roland, Álvaro Herrera)
+ </para>
+
+ <para>
+ Also prohibit cloned triggers from being renamed.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title>Indexes</title>
+
+ <itemizedlist>
+
+<!--
+Author: Peter Geoghegan <pg@bowt.ie>
+2021-10-02 [2903f1404] Enable deduplication in system catalog indexes.
+-->
+
+ <listitem>
+ <para>
+ Allow btree indexes on system and <link
+ linkend="storage-toast"><acronym>TOAST</acronym></link>
+ tables to efficiently store duplicates (Peter Geoghegan)
+ </para>
+
+ <para>
+ Previously de-duplication was disabled for these types of indexes.
+ </para>
+ </listitem>
+
+<!--
+Author: Alexander Korotkov <akorotkov@postgresql.org>
+2022-02-07 [f1ea98a79] Reduce non-leaf keys overlap in GiST indexes produced by
+-->
+
+ <listitem>
+ <para>
+ Improve lookup performance
+ of <link linkend="gist"><acronym>GiST</acronym></link> indexes
+ that were built using sorting (Aliaksandr Kalenik, Sergei
+ Shoulbakov, Andrey Borodin)
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-02-03 [94aa7cc5f] Add UNIQUE null treatment option
+-->
+
+ <listitem>
+ <para>
+ Allow unique constraints and indexes to treat
+ <literal>NULL</literal> values as not distinct (Peter Eisentraut)
+ </para>
+
+ <para>
+ Previously <literal>NULL</literal> entries were always treated
+ as distinct values, but this can now be changed by creating
+ constraints and indexes using <literal>UNIQUE NULLS NOT
+ DISTINCT</literal>.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-11-17 [a148f8bc0] Add a planner support function for starts_with().
+-->
+
+ <listitem>
+ <para>
+ Allow the <link
+ linkend="functions-string-other"><literal>^@</literal></link>
+ starts-with operator and the <function>starts_with()</function>
+ function to use btree indexes if using the C collation (Tom Lane)
+ </para>
+
+ <para>
+ Previously these could only use <link
+ linkend="spgist"><acronym>SP-GiST</acronym></link> indexes.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title>Optimizer</title>
+
+ <itemizedlist>
+
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2022-01-16 [269b532ae] Add stxdinherit flag to pg_statistic_ext_data
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-createstatistics">extended
+ statistics</link> to record statistics for a parent with all its
+ children (Tomas Vondra, Justin Pryzby)
+ </para>
+
+ <para>
+ Regular statistics already tracked parent and
+ parent-plus-all-children statistics separately.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-03-24 [0bd7af082] Invent recursive_worktable_factor GUC to replace hard-wi
+-->
+
+ <listitem>
+ <para>
+ Add server variable <link
+ linkend="guc-recursive-worktable-factor"><varname>recursive_worktable_factor</varname></link>
+ to allow the user to specify the expected size of the working
+ table of a <link linkend="queries-with-recursive">recursive
+ query</link> (Simon Riggs)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title>General Performance</title>
+
+ <itemizedlist>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2021-07-07 [29f45e299] Use a hash table to speed up NOT IN(values)
+-->
+
+ <listitem>
+ <para>
+ Allow hash lookup for <link
+ linkend="functions-subquery-notin"><literal>NOT IN</literal></link>
+ clauses with many constants (David Rowley, James Coleman)
+ </para>
+
+ <para>
+ Previously the code always sequentially scanned the list of values.
+ </para>
+ </listitem>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2021-08-22 [22c4e88eb] Allow parallel DISTINCT
+-->
+
+ <listitem>
+ <para>
+ Allow <command>SELECT DISTINCT</command> to be parallelized
+ (David Rowley)
+ </para>
+ </listitem>
+
+<!--
+Author: John Naylor <john.naylor@postgresql.org>
+2021-12-20 [911588a3f] Add fast path for validating UTF-8 text
+-->
+
+ <listitem>
+ <para>
+ Speed up encoding validation of <acronym>UTF</acronym>-8 text
+ by processing 16 bytes at a time
+ (John Naylor, Heikki Linnakangas)
+ </para>
+
+ <para>
+ This will improve text-heavy operations like <link
+ linkend="sql-copy"><command>COPY FROM</command></link>.
+ </para>
+ </listitem>
+
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+2021-10-18 [65014000b] Replace polyphase merge algorithm with a simple balanced
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+2021-10-25 [166f94377] Clarify the logic in a few places in the new balanced me
+-->
+
+ <listitem>
+ <para>
+ Improve performance for sorts that exceed <link
+ linkend="guc-work-mem"><varname>work_mem</varname></link>
+ (Heikki Linnakangas)
+ </para>
+
+ <para>
+ When the sort data no longer fits in <varname>work_mem</varname>,
+ switch to a batch sorting algorithm that uses more output streams
+ than before.
+ </para>
+ </listitem>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2021-07-22 [91e9e89dc] Make nodeSort.c use Datum sorts for single column sorts
+Author: David Rowley <drowley@postgresql.org>
+2022-04-04 [40af10b57] Use Generation memory contexts to store tuples in sorts
+Author: John Naylor <john.naylor@postgresql.org>
+2022-04-02 [697492434] Specialize tuplesort routines for different kinds of abb
+-->
+
+ <listitem>
+ <para>
+ Improve performance and reduce memory consumption of in-memory
+ sorts (Ronan Dunklau, David Rowley, Thomas Munro, John Naylor)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-06-29 [4035cd5d4] Add support for LZ4 with compression of full-page writes
+Author: Michael Paquier <michael@paquier.xyz>
+2022-03-11 [e9537321a] Add support for zstd with compression of full-page write
+-->
+
+ <listitem>
+ <para>
+ Allow <acronym>WAL</acronym> <link
+ linkend="guc-full-page-writes">full page writes</link> to use
+ LZ4 and Zstandard compression (Andrey Borodin, Justin Pryzby)
+ </para>
+
+ <para>
+ This is controlled by the <link
+ linkend="guc-wal-compression"><varname>wal_compression</varname></link>
+ server setting.
+ </para>
+ </listitem>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2021-07-19 [2dbe89057] Support direct I/O on macOS.
+-->
+
+ <listitem>
+ <para>
+ Add support for writing <acronym>WAL</acronym>
+ using <link linkend="guc-wal-sync-method">direct I/O</link> on
+ macOS (Thomas Munro)
+ </para>
+
+ <para>
+ This only works if <literal>max_wal_senders = 0</literal>
+ and <literal>wal_level = minimal</literal>.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Geoghegan <pg@bowt.ie>
+2022-04-03 [0b018faba] Set relfrozenxid to oldest extant XID seen by VACUUM.
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="routine-vacuuming">vacuum</link> to be more
+ aggressive in setting the oldest frozen and multi transaction id
+ (Peter Geoghegan)
+ </para>
+ </listitem>
+
+<!--
+Author: Etsuro Fujita <efujita@postgresql.org>
+2022-04-06 [c2bb02bc2] Allow asynchronous execution in more cases.
+-->
+
+ <listitem>
+ <para>
+ Allow a query referencing multiple <link
+ linkend="ddl-foreign-data">foreign tables</link> to perform
+ parallel foreign table scans in more cases (Andrey Lepikhov,
+ Etsuro Fujita)
+ </para>
+ </listitem>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2022-04-08 [9d9c02ccd] Teach planner and executor about monotonic window funcs
+-->
+
+ <listitem>
+ <para>
+ Improve the performance of <link linkend="functions-window">window
+ functions</link> that use <function>row_number()</function>,
+ <function>rank()</function>, <function>dense_rank()</function> and
+ <function>count()</function>
+ (David Rowley)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-06 [a82a5eee3] Use ISB as a spin-delay instruction on ARM64.
+-->
+
+ <listitem>
+ <para>
+ Improve the performance of spinlocks on high-core-count ARM64
+ systems (Geoffrey Blake)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title>Monitoring</title>
+
+ <itemizedlist>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2021-12-13 [64da07c41] Default to log_checkpoints=on, log_autovacuum_min_durati
+-->
+
+ <listitem>
+ <para>
+ Enable default logging of checkpoints and slow autovacuum
+ operations (Bharath Rupireddy)
+ </para>
+
+ <para>
+ This changes the default of <link
+ linkend="guc-log-checkpoints"><varname>log_checkpoints</varname></link>
+ to <literal>on</literal> and that of <link
+ linkend="guc-log-autovacuum-min-duration"><varname>log_autovacuum_min_duration</varname></link>
+ to 10 minutes. This will cause even an idle server to generate
+ some log output, which might cause problems on
+ resource-constrained servers without log file rotation. These
+ defaults should be changed in such cases.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2021-10-25 [9ce346eab] Report progress of startup operations that take a long t
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2021-11-05 [e543906e2] Document default and changeability of log_startup_progre
+-->
+
+ <listitem>
+ <para>
+ Generate progress messages in the server log during slow server
+ starts (Nitin Jadhav, Robert Haas)
+ </para>
+
+ <para>
+ The messages report the cause of the delay. The time interval for
+ notification is controlled by the new server variable <link
+ linkend="guc-log-startup-progress-interval"><varname>log_startup_progress_interval</varname></link>.
+ </para>
+ </listitem>
+
+<!--
+Author: Andres Freund <andres@anarazel.de>
+2022-04-06 [5891c7a8e] pgstat: store statistics in shared memory.
+Author: Andres Freund <andres@anarazel.de>
+2022-04-07 [b3abca681] pgstat: Update docs to match the shared memory stats rea
+-->
+
+ <listitem>
+ <para>
+ Store <link linkend="monitoring-stats">cumulative statistics
+ system</link> data in shared memory (Kyotaro Horiguchi, Andres
+ Freund, Melanie Plageman)
+ </para>
+
+ <para>
+ Previously this data was sent to a statistics collector process
+ via <acronym>UDP</acronym> packets, and could only be read by
+ sessions after transferring it via the file system. There is no
+ longer a separate statistics collector process.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Geoghegan <pg@bowt.ie>
+2022-02-11 [872770fd6] Add VACUUM instrumentation for scanned pages, relfrozenx
+Author: Peter Geoghegan <pg@bowt.ie>
+2022-03-13 [6e20f4600] VACUUM VERBOSE: tweak scanned_pages logic.
+Author: Peter Geoghegan <pg@bowt.ie>
+2022-04-15 [bdb71dbe8] VACUUM VERBOSE: Show dead items for an empty table.
+-->
+
+ <listitem>
+ <para>
+ Add additional information to <command>VACUUM VERBOSE</command>
+ and autovacuum logging messages (Peter Geoghegan)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-04-08 [efb0ef909] Track I/O timing for temporary file blocks in EXPLAIN (B
+-->
+
+ <listitem>
+ <para>
+ Add <link linkend="sql-explain"><command>EXPLAIN
+ (BUFFERS)</command></link> output for temporary file block I/O
+ (Masahiko Sawada)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-01-17 [dc686681e] Introduce log_destination=jsonlog
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="guc-log-destination">log output</link> in
+ <acronym>JSON</acronym> format (Sehrope Sarkuni, Michael Paquier)
+ </para>
+
+ <para>
+ The new setting is <literal>log_destination = jsonlog</literal>.
+ </para>
+ </listitem>
+
+<!--
+Author: Fujii Masao <fujii@postgresql.org>
+2021-09-02 [e04267844] Enhance pg_stat_reset_single_table_counters function.
+-->
+
+ <listitem>
+ <para>
+ Allow <link
+ linkend="monitoring-stats-funcs-table"><function>pg_stat_reset_single_table_counters()</function></link>
+ to reset the counters of relations shared across all databases
+ (Sadhuprasad Patro)
+ </para>
+ </listitem>
+
+<!--
+Author: Fujii Masao <fujii@postgresql.org>
+2021-11-22 [1b06d7bac] Report wait events for local shell commands like archive
+-->
+
+ <listitem>
+ <para>
+ Add <link linkend="wait-event-table">wait events</link> for local
+ shell commands (Fujii Masao)
+ </para>
+
+ <para>
+ The new wait events are used when calling
+ <varname>archive_command</varname>,
+ <varname>archive_cleanup_command</varname>,
+ <varname>restore_command</varname> and
+ <varname>recovery_end_command</varname>.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title>Privileges</title>
+
+ <itemizedlist>
+
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+2022-03-22 [7faa5fc84] Add support for security invoker views.
+-->
+
+ <listitem>
+ <para>
+ Allow table accesses done by
+ a <link linkend="sql-createview">view</link> to optionally be
+ controlled by privileges of the view's caller (Christoph Heiss)
+ </para>
+
+ <para>
+ Previously, view accesses were always treated as being done by the
+ view's owner. That's still the default.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-28 [7f6772317] Adjust server-side backup to depend on pg_write_server_f
+-->
+
+ <listitem>
+ <para>
+ Allow members of the <link
+ linkend="predefined-roles-table"><literal>pg_write_server_files</literal></link>
+ predefined role to perform server-side base backups (Dagfinn
+ Ilmari Mannsåker)
+ </para>
+
+ <para>
+ Previously only superusers could perform such backups.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-06 [a0ffa885e] Allow granting SET and ALTER SYSTEM privileges on GUC pa
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-07-19 [a2944d872] Fix missed corner cases for grantable permissions on GUC
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-grant"><command>GRANT</command></link>
+ to grant permissions to change individual server variables via
+ <command>SET</command> and <command>ALTER SYSTEM</command>
+ (Mark Dilger)
+ </para>
+
+ <para>
+ The new function <function>has_parameter_privilege()</function>
+ reports on this privilege.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2021-11-09 [4168a4745] Add pg_checkpointer predefined role for CHECKPOINT comma
+Author: Robert Haas <rhaas@postgresql.org>
+2022-07-05 [d3526e59f] Rename pg_checkpointer predefined role to pg_checkpoint.
+-->
+
+ <listitem>
+ <para>
+ Add predefined role <link
+ linkend="predefined-roles-table"><literal>pg_checkpoint</literal></link>
+ that allows members to run <command>CHECKPOINT</command>
+ (Jeff Davis)
+ </para>
+
+ <para>
+ Previously checkpoints could only be run by superusers.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2021-10-27 [77ea4f943] Grant memory views to pg_read_all_stats.
+-->
+
+ <listitem>
+ <para>
+ Allow members of the <link
+ linkend="predefined-roles-table"><literal>pg_read_all_stats</literal></link>
+ predefined role to access the views <link
+ linkend="view-pg-backend-memory-contexts"><structname>pg_backend_memory_contexts</structname></link>
+ and <link
+ linkend="view-pg-shmem-allocations"><structname>pg_shmem_allocations</structname></link>
+ (Bharath Rupireddy)
+ </para>
+
+ <para>
+ Previously these views could only be accessed by superusers.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2021-10-26 [f0b051e32] Allow GRANT on pg_log_backend_memory_contexts().
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-grant"><command>GRANT</command></link>
+ to grant permissions on <link
+ linkend="functions-admin-signal"><function>pg_log_backend_memory_contexts()</function></link>
+ (Jeff Davis)
+ </para>
+
+ <para>
+ Previously this function could only be run by superusers.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title>Server Configuration</title>
+
+ <itemizedlist>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-09-08 [bd1788051] Introduce GUC shared_memory_size
+Author: Michael Paquier <michael@paquier.xyz>
+2021-09-09 [3b231596c] Make shared_memory_size a preset option
+-->
+
+ <listitem>
+ <para>
+ Add server variable <link
+ linkend="guc-shared-memory-size"><varname>shared_memory_size</varname></link>
+ to report the size of allocated shared memory (Nathan Bossart)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-09-21 [43c1c4f65] Introduce GUC shared_memory_size_in_huge_pages
+Author: Michael Paquier <michael@paquier.xyz>
+2022-03-24 [bbd4951b7] doc: Improve postgres command for shared_memory_size_in_
+-->
+
+ <listitem>
+ <para>
+ Add server variable <link
+ linkend="guc-shared-memory-size-in-huge-pages"><varname>shared_memory_size_in_huge_pages</varname></link>
+ to report the number of huge memory pages required (Nathan Bossart)
+ </para>
+
+ <para>
+ This is only supported on Linux.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2022-07-20 [2103266a3] Process shared_preload_libraries in single-user mode.
+-->
+
+ <listitem>
+ <para>
+ Honor server variable <link
+ linkend="guc-shared-preload-libraries"><varname>shared_preload_libraries</varname></link>
+ in single-user mode (Jeff Davis)
+ </para>
+
+ <para>
+ This change supports use
+ of <varname>shared_preload_libraries</varname> to load custom
+ access methods and WAL resource managers, which would be essential
+ for database access even in single-user mode.
+ </para>
+ </listitem>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2022-07-02 [a2b0719cc] Default to dynamic_shared_memory_type=sysv on Solaris.
+-->
+
+ <listitem>
+ <para>
+ On Solaris, make the default setting of <link
+ linkend="guc-dynamic-shared-memory-type"><varname>dynamic_shared_memory_type</varname></link>
+ be <literal>sysv</literal> (Thomas Munro)
+ </para>
+
+ <para>
+ The previous default choice, <literal>posix</literal>, can result
+ in spurious failures on this platform.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-09-16 [0c39c2920] Support "postgres -C" with runtime-computed GUCs
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="app-postgres"><command>postgres
+ -C</command></link> to properly report runtime-computed values
+ (Nathan Bossart)
+ </para>
+
+ <para>
+ Previously runtime-computed values <link
+ linkend="guc-data-checksums"><varname>data_checksums</varname></link>,
+ <link
+ linkend="guc-wal-segment-size"><varname>wal_segment_size</varname></link>,
+ and <link
+ linkend="guc-data-directory-mode"><varname>data_directory_mode</varname></link>
+ would report values that would not be accurate on the running
+ server. However, this does not work on a running server.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3>
+ <title>Streaming Replication and Recovery</title>
+
+ <itemizedlist>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-11 [dab298471] Add suport for server-side LZ4 base backup compression.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-08 [7cf085f07] Add support for zstd base backup compression.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-30 [51c0d186d] Allow parallel zstd compression when taking a base backu
+-->
+
+ <listitem>
+ <para>
+ Add support for LZ4 and Zstandard compression of server-side <link
+ linkend="backup-base-backup">base backups</link> (Jeevan Ladhe,
+ Robert Haas)
+ </para>
+ </listitem>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2021-08-02 [7ff23c6d2] Run checkpointer and bgwriter in crash recovery.
+-->
+
+ <listitem>
+ <para>
+ Run the checkpointer and bgwriter processes during crash recovery
+ (Thomas Munro)
+ </para>
+
+ <para>
+ This helps to speed up long crash recoveries.
+ </para>
+ </listitem>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2022-04-07 [5dc0418fa] Prefetch data referenced by the WAL, take II.
+-->
+
+ <listitem>
+ <para>
+ Allow <acronym>WAL</acronym> processing to pre-fetch needed file
+ contents (Thomas Munro)
+ </para>
+
+ <para>
+ This is controlled by the server variable <link
+ linkend="guc-recovery-prefetch"><varname>recovery_prefetch</varname></link>.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-03 [5ef1eefd7] Allow archiving via loadable modules.
+-->
+
+ <listitem>
+ <para>
+ Allow archiving via loadable modules (Nathan Bossart)
+ </para>
+
+ <para>
+ Previously, archiving was only done by calling shell commands.
+ The new server variable <link
+ linkend="guc-archive-library"><varname>archive_library</varname></link>
+ can be set to specify a library to be called for archiving.
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2021-07-09 [8e7811e95] Eliminate replication protocol error related to IDENTIFY
+-->
+
+ <listitem>
+ <para>
+ No longer require <link
+ linkend="protocol-replication"><literal>IDENTIFY_SYSTEM</literal></link>
+ to be run before <literal>START_REPLICATION</literal> (Jeff Davis)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <sect4>
+ <title><link linkend="logical-replication">Logical Replication</link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2021-10-27 [5a2832465] Allow publishing the tables of schema.
+Author: Amit Kapila <akapila@postgresql.org>
+2021-12-08 [1a2aaeb0d] Fix changing the ownership of ALL TABLES IN SCHEMA publi
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-09-22 [f256236fb] Remove ALL keyword from TABLES IN SCHEMA for publication
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-createpublication">publication</link> of
+ all tables in a schema (Vignesh C, Hou Zhijie, Amit Kapila)
+ </para>
+
+ <para>
+ For example, this syntax is now supported: <literal>CREATE
+ PUBLICATION pub1 FOR TABLES IN SCHEMA s1,s2</literal>.
+ <command>ALTER PUBLICATION</command> supports a similar syntax.
+ Tables added later to the listed schemas will also be replicated.
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2022-02-22 [52e4f0cd4] Allow specifying row filters for logical replication of
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2022-03-17 [5a0796622] Fix row filters with multiple publications
+Author: Amit Kapila <akapila@postgresql.org>
+2022-04-18 [676eeb6dd] Add additional documentation for row filters.
+-->
+
+ <listitem>
+ <para>
+ Allow publication content to be filtered using a
+ <literal>WHERE</literal> clause (Hou Zhijie, Euler Taveira,
+ Peter Smith, Ajin Cherian, Tomas Vondra, Amit Kapila)
+ </para>
+
+ <para>
+ Rows not satisfying the <literal>WHERE</literal> clause are not
+ published.
+ </para>
+ </listitem>
+
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2022-03-26 [923def9a5] Allow specifying column lists for logical replication
+-->
+
+ <listitem>
+ <para>
+ Allow publication content to
+ be restricted to specific columns (Tomas Vondra, Álvaro Herrera,
+ Rahila Syed)
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2022-03-22 [208c5d65b] Add ALTER SUBSCRIPTION ... SKIP.
+-->
+
+ <listitem>
+ <para>
+ Allow skipping of transactions on a subscriber using <link
+ linkend="sql-altersubscription"><command>ALTER SUBSCRIPTION
+ ... SKIP</command></link> (Masahiko Sawada)
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2021-06-30 [cda03cfed] Allow enabling two-phase option via replication protocol
+Author: Amit Kapila <akapila@postgresql.org>
+2021-07-14 [a8fd13cab] Add support for prepared transactions to built-in logica
+Author: Amit Kapila <akapila@postgresql.org>
+2021-08-04 [63cf61cde] Add prepare API support for streaming transactions in lo
+-->
+
+ <listitem>
+ <para>
+ Add support for prepared (two-phase) transactions to logical
+ replication (Peter Smith, Ajin Cherian, Amit Kapila, Nikhil
+ Sontakke, Stas Kelvich)
+ </para>
+
+ <para>
+ The new <link
+ linkend="protocol-replication"><literal>CREATE_REPLICATION_SLOT</literal></link>
+ option is called <literal>TWO_PHASE</literal>.
+ <application>pg_recvlogical</application> now supports a new
+ <option>--two-phase</option> option during slot creation.
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2022-03-30 [d5a9d86d8] Skip empty transactions for logical replication.
+-->
+
+ <listitem>
+ <para>
+ Prevent logical replication of empty transactions (Ajin Cherian,
+ Hou Zhijie, Euler Taveira)
+ </para>
+
+ <para>
+ Previously, publishers would send empty transactions to
+ subscribers if subscribed tables were not modified.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-11-23 [1922d7c6e] Add SQL functions to monitor the directory contents of r
+-->
+
+ <listitem>
+ <para>
+ Add <acronym>SQL</acronym> functions to monitor the directory
+ contents of logical replication slots (Bharath Rupireddy)
+ </para>
+
+ <para>
+ The new functions are <link
+ linkend="functions-admin-genfile-table"><function>pg_ls_logicalsnapdir()</function></link>,
+ <function>pg_ls_logicalmapdir()</function>, and
+ <function>pg_ls_replslotdir()</function>. They can be run by
+ members of the predefined <literal>pg_monitor</literal> role.
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2022-03-14 [705e20f85] Optionally disable subscriptions on error.
+-->
+
+ <listitem>
+ <para>
+ Allow subscribers to stop the application of logical replication changes on error
+ (Osumi Takamichi, Mark Dilger)
+ </para>
+
+ <para>
+ This is enabled with the subscriber option <link
+ linkend="sql-createsubscription"><literal>disable_on_error</literal></link>
+ and avoids possible infinite error loops during stream application.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-11-02 [f3d4019da] Ensure consistent logical replication of datetime and fl
+-->
+
+ <listitem>
+ <para>
+ Adjust subscriber server variables to match the publisher so
+ datetime and float8 values are interpreted consistently (Japin Li)
+ </para>
+
+ <para>
+ Some publishers might be relying on inconsistent behavior.
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2021-11-30 [8d74fc96d] Add a view to show the stats of subscription workers.
+Author: Amit Kapila <akapila@postgresql.org>
+2022-03-01 [7a8507329] Reconsider pg_stat_subscription_workers view.
+-->
+
+ <listitem>
+ <para>
+ Add system view <link
+ linkend="monitoring-pg-stat-subscription-stats"><structname>pg_stat_subscription_stats</structname></link>
+ to report on subscriber activity (Masahiko Sawada)
+ </para>
+
+ <para>
+ The new function <link
+ linkend="monitoring-stats-functions"><function>pg_stat_reset_subscription_stats()</function></link>
+ allows resetting these statistics counters.
+ </para>
+ </listitem>
+
+<!--
+Author: Amit Kapila <akapila@postgresql.org>
+2021-12-08 [a61bff2bf] De-duplicate the result of pg_publication_tables view.
+-->
+
+ <listitem>
+ <para>
+ Suppress duplicate entries in the <link
+ linkend="view-pg-publication-tables"><structname>pg_publication_tables</structname></link>
+ system view (Hou Zhijie)
+ </para>
+
+ <para>
+ In some cases a partition could appear more than once.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3>
+ <title>Utility Commands</title>
+
+ <itemizedlist>
+
+<!--
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-03-28 [7103ebb7a] Add support for MERGE SQL command
+-->
+
+ <listitem>
+ <para>
+ Add <acronym>SQL</acronym> <link
+ linkend="sql-merge"><command>MERGE</command></link>
+ command to adjust one table to match another (Simon Riggs, Pavan
+ Deolasee, Álvaro Herrera, Amit Langote)
+ </para>
+
+ <para>
+ This is similar to <command>INSERT ... ON CONFLICT</command>
+ but more batch-oriented.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-01-28 [43f33dc01] Add HEADER support to COPY text format
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-03-30 [072132f04] Add header matching mode to COPY FROM
+-->
+
+ <listitem>
+ <para>
+ Add support for <literal>HEADER</literal> option in <link
+ linkend="sql-copy"><command>COPY</command></link> text format
+ (Rémi Lapeyre)
+ </para>
+
+ <para>
+ The new option causes the column names to be output, and optionally
+ verified on input.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-29 [9c08aea6a] Add new block-by-block strategy for CREATE DATABASE.
+-->
+
+ <listitem>
+ <para>
+ Add new <acronym>WAL</acronym>-logged method for <link
+ linkend="sql-createdatabase">database creation</link> (Dilip Kumar)
+ </para>
+
+ <para>
+ This is the new default method for copying the template database,
+ as it avoids the need for checkpoints during database creation.
+ However, it might be slow if the template database is large, so
+ the old method is still available.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-24 [aa0105141] pg_upgrade: Preserve database OIDs.
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-createdatabase"><command>CREATE
+ DATABASE</command></link> to set the database <acronym>OID</acronym>
+ (Shruthi Gowda, Antonin Houska)
+ </para>
+ </listitem>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2022-02-12 [4eb217631] Fix DROP {DATABASE,TABLESPACE} on Windows.
+-->
+
+ <listitem>
+ <para>
+ Prevent <link linkend="sql-dropdatabase"><command>DROP
+ DATABASE</command></link>, <link
+ linkend="sql-droptablespace"><command>DROP
+ TABLESPACE</command></link>, and <link
+ linkend="sql-alterdatabase"><command>ALTER DATABASE SET
+ TABLESPACE</command></link> from occasionally failing during
+ concurrent use on Windows (Thomas Munro)
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-12-08 [d6f96ed94] Allow specifying column list for foreign key ON DELETE S
+-->
+
+ <listitem>
+ <para>
+ Allow foreign key <link linkend="ddl-constraints-fk"><literal>ON
+ DELETE SET</literal></link> actions to affect only specified columns
+ (Paul Martinez)
+ </para>
+
+ <para>
+ Previously, all of the columns in the foreign key were always
+ affected.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-07-28 [b0483263d] Add support for SET ACCESS METHOD in ALTER TABLE
+-->
+
+ <listitem>
+ <para>
+ Allow <link linkend="sql-altertable"><command>ALTER
+ TABLE</command></link> to modify a table's <literal>ACCESS
+ METHOD</literal> (Justin Pryzby, Jeff Davis)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-08-10 [7b565843a] Add call to object access hook at the end of table rewri
+-->
+
+ <listitem>
+ <para>
+ Properly call object access hooks when <link
+ linkend="sql-altertable"><command>ALTER TABLE</command></link>
+ causes table rewrites (Michael Paquier)
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-04-07 [344d62fb9] Unlogged sequences
+-->
+
+ <listitem>
+ <para>
+ Allow creation of unlogged <link
+ linkend="sql-createsequence">sequences</link> (Peter Eisentraut)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-07-22 [c2fa113dd] Close old gap in dependency checks for functions returni
+-->
+
+ <listitem>
+ <para>
+ Track dependencies on individual columns in the results of
+ functions returning composite types (Tom Lane)
+ </para>
+
+ <para>
+ Previously, if a view or rule contained a reference to a specific
+ column within the result of a composite-returning function, that
+ was not noted as a dependency; the view or rule was only considered
+ to depend on the composite type as a whole. This meant that
+ dropping the individual column would be allowed, causing problems
+ in later use of the view or rule. The column-level dependency is
+ now also noted, so that dropping such a column will be rejected
+ unless the view is changed or dropped.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title>Data Types</title>
+
+ <itemizedlist>
+
+<!--
+Author: Dean Rasheed <dean.a.rasheed@gmail.com>
+2021-07-26 [085f931f5] Allow numeric scale to be negative or greater than preci
+-->
+
+ <listitem>
+ <para>
+ Allow the scale of
+ a <link linkend="datatype-numeric"><type>numeric</type></link>
+ value to be negative, or greater than its precision (Dean Rasheed,
+ Tom Lane)
+ </para>
+
+ <para>
+ This allows rounding of values to the left of the decimal point,
+ e.g., <literal>'1234'::numeric(4, -2)</literal> returns 1200.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-02 [e39f99046] Fix overflow hazards in interval input and output conver
+-->
+
+ <listitem>
+ <para>
+ Improve overflow detection when casting values to <link
+ linkend="datatype-datetime">interval</link> (Joe Koshakow)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-08-02 [c034b629c] Change type "char"'s I/O format for non-ASCII characters
+-->
+
+ <listitem>
+ <para>
+ Change the I/O format of type <type>"char"</type> for non-ASCII
+ characters (Tom Lane)
+ </para>
+ </listitem>
+
+<!--
+Author: John Naylor <john.naylor@postgresql.org>
+2021-08-26 [bab982161] Update display widths as part of updating Unicode
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-09-15 [f7e56f1f5] Update Unicode data to Unicode 14.0.0
+-->
+
+ <listitem>
+ <para>
+ Update the display width information of modern Unicode characters,
+ like emojis (Jacob Champion)
+ </para>
+
+ <para>
+ Also update from Unicode 5.0 to 14.0.0. There is now an automated
+ way to keep Postgres updated with Unicode releases.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title>Functions</title>
+
+ <itemizedlist>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-03-30 [7ae1619bc] Add range_agg with multirange inputs
+-->
+
+ <listitem>
+ <para>
+ Add multirange input to <link
+ linkend="functions-aggregate-table"><function>range_agg()</function></link>
+ (Paul Jungwirth)
+ </para>
+ </listitem>
+
+<!--
+Author: Fujii Masao <fujii@postgresql.org>
+2022-02-10 [400fc6b64] Add min() and max() aggregates for xid8.
+-->
+
+ <listitem>
+ <para>
+ Add <link linkend="tutorial-agg"><function>MIN()</function></link>
+ and <function>MAX()</function> aggregates for the <link
+ linkend="datatype-int"><type>xid8</type></link> data type (Ken Kato)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-08-03 [642433707] Add assorted new regexp_xxx SQL functions.
+-->
+
+ <listitem>
+ <para>
+ Add regular expression functions for compatibility with other
+ relational systems (Gilles Darold, Tom Lane)
+ </para>
+
+ <para>
+ The new functions are <link
+ linkend="functions-string-other"><function>regexp_count()</function></link>,
+ <function>regexp_instr()</function>,
+ <function>regexp_like()</function>, and
+ <function>regexp_substr()</function>. Some new optional arguments
+ were also added to <function>regexp_replace()</function>.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-13 [c5c192d7b] Implement poly_distance().
+-->
+
+ <listitem>
+ <para>
+ Add the ability to compute the distance between <link
+ linkend="datatype-polygon"><type>polygons</type></link> (Tom Lane)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-14 [9dde82899] Support "of", "tzh", and "tzm" format codes.
+-->
+
+ <listitem>
+ <para>
+ Add <link
+ linkend="functions-formatting-table"><function>to_char()</function></link>
+ format codes <literal>of</literal>, <literal>tzh</literal>, and
+ <literal>tzm</literal> (Nitin Jadhav)
+ </para>
+
+ <para>
+ The upper-case equivalents of these were already supported.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-09-06 [388e71af8] Make timetz_zone() stable, and correct a bug for DYNTZ a
+-->
+
+ <listitem>
+ <para>
+ When applying <link
+ linkend="functions-datetime-zoneconvert"><literal>AT
+ TIME ZONE</literal></link> to a <type>time with time zone</type>
+ value, use the transaction start time rather than wall clock time
+ to determine whether DST applies (Aleksander Alekseev, Tom Lane)
+ </para>
+
+ <para>
+ This allows the conversion to be considered stable rather than
+ volatile, and it saves a kernel call per invocation.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-11-06 [cbe25dcff] Disallow making an empty lexeme via array_to_tsvector().
+-->
+
+ <listitem>
+ <para>
+ Ignore NULL array elements in <link
+ linkend="textsearch-functions-table"><function>ts_delete()</function></link> and
+ <function>setweight()</function> functions with array arguments
+ (Jean-Christophe Arnu)
+ </para>
+
+ <para>
+ These functions effectively ignore empty-string array elements
+ (since those could never match a valid lexeme). It seems
+ consistent to let them ignore NULL elements too, instead of
+ failing.
+ </para>
+ </listitem>
+
+<!--
+Author: David Rowley <drowley@postgresql.org>
+2021-07-09 [ca2e4472b] Teach pg_size_pretty and pg_size_bytes about petabytes
+-->
+
+ <listitem>
+ <para>
+ Add support for petabyte units to <link
+ linkend="functions-admin-dbsize"><function>pg_size_pretty()</function></link>
+ and <function>pg_size_bytes()</function> (David Christensen)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-07-27 [024515cac] In event triggers, use "pg_temp" only for our own temp s
+-->
+
+ <listitem>
+ <para>
+ Change <link
+ linkend="pg-event-trigger-ddl-command-end-functions"><function>pg_event_trigger_ddl_commands()</function></link>
+ to output references to other sessions' temporary schemas using the
+ actual schema name (Tom Lane)
+ </para>
+
+ <para>
+ Previously this function reported all temporary schemas as
+ <literal>pg_temp</literal>, but it's misleading to use that for any
+ but the current session's temporary schema.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title><link linkend="plpgsql">PL/pgSQL</link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-30 [ccd10a9bf] Tighten enforcement of variable CONSTANT markings in plp
+-->
+
+ <listitem>
+ <para>
+ Fix enforcement of PL/pgSQL variable <literal>CONSTANT</literal>
+ markings (Tom Lane)
+ </para>
+
+ <para>
+ Previously, a variable could be used as a <link
+ linkend="plpgsql-statements-calling-procedure"><command>CALL</command></link>
+ output parameter or refcursor <command>OPEN</command> variable
+ despite being marked <literal>CONSTANT</literal>.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title><link linkend="libpq">libpq</link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-04-01 [c1932e542] libpq: Allow IP address SANs in server certificates
+-->
+
+ <listitem>
+ <para>
+ Allow <acronym>IP</acronym> address matching against a server
+ certificate's Subject Alternative Name (Jacob Champion)
+ </para>
+ </listitem>
+
+<!--
+Author: Daniel Gustafsson <dgustafsson@postgresql.org>
+2022-03-29 [ebc8b7d44] Enable SSL library detection via PQsslAttribute()
+-->
+
+ <listitem>
+ <para>
+ Allow <function>PQsslAttribute()</function> to report the
+ <acronym>SSL</acronym> library type without requiring a libpq
+ connection (Jacob Champion)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-18 [5987feb70] Make PQcancel use the PGconn's tcp_user_timeout and keep
+-->
+
+ <listitem>
+ <para>
+ Change query cancellations sent by the client to use the same
+ <acronym>TCP</acronym> settings as normal client connections
+ (Jelte Fennema)
+ </para>
+
+ <para>
+ This allows configured <acronym>TCP</acronym> timeouts to apply
+ to query cancel connections.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-18 [ce1e7a2f7] Don't let libpq "event" procs break the state of PGresul
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-18 [2e372869a] Don't let libpq PGEVT_CONNRESET callbacks break a PGconn
+-->
+
+ <listitem>
+ <para>
+ Prevent libpq event callback failures from forcing an error result
+ (Tom Lane)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title>Client Applications</title>
+
+ <itemizedlist>
+
+<!--
+Author: Tatsuo Ishii <ishii@postgresql.org>
+2022-03-23 [4a39f87ac] Allow pgbench to retry in some cases.
+-->
+
+ <listitem>
+ <para>
+ Allow <link
+ linkend="pgbench"><application>pgbench</application></link> to
+ retry after serialization and deadlock failures (Yugo Nagata,
+ Marina Polyakova)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <sect4>
+ <title><xref linkend="app-psql"/></title>
+
+ <itemizedlist>
+
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+2021-07-14 [eec57115e] In psql \copy from, send data to server in larger chunks
+-->
+
+ <listitem>
+ <para>
+ Improve performance
+ of <application>psql</application>'s <command>\copy</command>
+ command, by sending data in larger chunks (Heikki Linnakangas)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-07 [3e707fbb4] psql: add \dconfig command to show server's configuratio
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-11 [5e70d8b5d] Tweak the default behavior of psql's \dconfig.
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-13 [139d46ee2] Further tweak the default behavior of psql's \dconfig.
+-->
+
+ <listitem>
+ <para>
+ Add <command>\dconfig</command> command to report server variables
+ (Mark Dilger, Tom Lane)
+ </para>
+
+ <para>
+ This is similar to the server-side <command>SHOW</command>
+ command, but it can process patterns to show multiple variables
+ conveniently.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-20 [33d3eeadb] Add a \getenv command to psql.
+-->
+
+ <listitem>
+ <para>
+ Add <command>\getenv</command> command
+ to assign the value of an environment variable to a
+ <application>psql</application> variable (Tom Lane)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-06 [328dfbdab] Extend psql's \lo_list/\dl to be able to print large obj
+-->
+
+ <listitem>
+ <para>
+ Add <literal>+</literal> option to the
+ <literal>\lo_list</literal> and <literal>\dl</literal> commands to
+ show large-object privileges (Pavel Luzanov)
+ </para>
+ </listitem>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2021-07-13 [7c09d2797] Add PSQL_WATCH_PAGER for psql's \watch command.
+-->
+
+ <listitem>
+ <para>
+ Add a pager option for the <command>\watch</command>
+ command (Pavel Stehule, Thomas Munro)
+ </para>
+
+ <para>
+ This is only supported on Unix and is controlled by the
+ <envar>PSQL_WATCH_PAGER</envar> environment variable.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-01 [83884682f] psql: include intra-query "- -" comments in what's sent t
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-01 [c2f654930] psql: treat "- -" comments between queries as separate hi
+-->
+
+ <listitem>
+ <para>
+ Make <application>psql</application> include intra-query double-hyphen
+ comments in queries sent to the server (Tom Lane, Greg Nancarrow)
+ </para>
+
+ <para>
+ Previously such comments were removed from the query
+ before being sent. Double-hyphen comments that are before any
+ query text are not sent, and are not recorded as separate
+ <application>psql</application> history entries.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-01 [3d858af07] psql: initialize comment-begin setting to a useful value
+-->
+
+ <listitem>
+ <para>
+ Adjust <application>psql</application> so
+ that <application>Readline</application>'s
+ meta-<literal>#</literal> command will insert a double-hyphen
+ comment marker (Tom Lane)
+ </para>
+
+ <para>
+ Previously a pound marker was inserted, unless the user had taken
+ the trouble to configure a non-default comment marker.
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-04-04 [7844c9918] psql: Show all query results by default
+-->
+
+ <listitem>
+ <para>
+ Make <application>psql</application> output all results when multiple
+ queries are passed to the server at once (Fabien Coelho)
+ </para>
+
+ <para>
+ Previously, only the last query result was displayed. The old
+ behavior can be restored by setting
+ the <literal>SHOW_ALL_RESULTS</literal> <application>psql</application>
+ variable to <literal>off</literal>.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-06-15 [a3ff08e0b] Tweak behavior of psql - -single-transaction depending
+-->
+
+ <listitem>
+ <para>
+ After an error is detected
+ in <option>--single-transaction</option> mode, change the
+ final <command>COMMIT</command> command
+ to <command>ROLLBACK</command> only
+ if <varname>ON_ERROR_STOP</varname> is set (Michael Paquier)
+ </para>
+
+ <para>
+ Previously, detection of an error in a <option>-c</option> command
+ or <option>-f</option> script file would lead to
+ issuing <command>ROLLBACK</command> at the end, regardless of the
+ value of <varname>ON_ERROR_STOP</varname>.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-08-10 [e2ce88b58] Add tab completion for DECLARE .. ASENSITIVE in psql
+Author: Michael Paquier <michael@paquier.xyz>
+2021-08-25 [346511313] Add tab completion for EXPLAIN .. EXECUTE in psql
+Author: Michael Paquier <michael@paquier.xyz>
+2021-08-30 [d3fa87657] Add more tab completion support for ALTER TABLE ADD in p
+Author: Michael Paquier <michael@paquier.xyz>
+2021-08-31 [f2bbadce6] Add tab completion for data types after ALTER TABLE ADD
+Author: Fujii Masao <fujii@postgresql.org>
+2021-09-01 [b0c066297] Improve tab-completion for CREATE PUBLICATION.
+Author: Fujii Masao <fujii@postgresql.org>
+2021-10-05 [0b0d277c3] psql: Improve tab-completion for LOCK TABLE.
+Author: Michael Paquier <michael@paquier.xyz>
+2021-11-05 [a5b336b8b] Improve psql tab completion for COMMENT
+Author: Michael Paquier <michael@paquier.xyz>
+2021-11-19 [0cd6d3b3c] Improve psql tab completion for transforms, domains and
+Author: Michael Paquier <michael@paquier.xyz>
+2021-11-29 [f44ceb46e] Improve psql tab completion for views, FDWs, sequences a
+Author: Michael Paquier <michael@paquier.xyz>
+2021-12-01 [9270778f4] Improve psql tab completion for various DROP commands
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-03 [dfe67c0e8] Tab completion: don't offer valid constraints in VALIDAT
+Author: Fujii Masao <fujii@postgresql.org>
+2022-01-15 [74527c3e0] Add tab-completion for CREATE FOREIGN TABLE.
+Author: Peter Eisentraut <peter@eisentraut.org>
+2022-01-27 [fefce9ef9] psql: Add tab completion for ALTER COLLATION / REFRESH V
+Author: Alvaro Herrera <alvherre@alvh.no-ip.org>
+2022-01-28 [95787e849] Tab-complete ALTER PUBLICATION ADD TABLE with list of ta
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-30 [02b8048ba] psql: improve tab-complete's handling of variant SQL nam
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-01 [020258fbd] Treat case of tab-completion keywords a bit more careful
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-02-09 [f0cd9097c] Further tweaks for psql's new tab-completion logic.
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-03-20 [7fa3db367] psql: handle tab completion of timezone names after "SET
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2022-03-25 [2d2232933] Update tab-completion for CREATE PUBLICATION with sequen
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-04-13 [b5607b074] Fix case sensitivity in psql's tab completion for GUC na
+-->
+
+ <listitem>
+ <para>
+ Improve <application>psql</application>'s tab completion (Shinya
+ Kato, Dagfinn Ilmari Mannsåker, Peter Smith, Koyu Tanigawa,
+ Ken Kato, David Fetter, Haiying Tang, Peter Eisentraut, Álvaro
+ Herrera, Tom Lane, Masahiko Sawada)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-16 [cf0cab868] Remove psql support for server versions preceding 9.2.
+-->
+
+ <listitem>
+ <para>
+ Limit support of <application>psql</application>'s backslash
+ commands to servers running <productname>PostgreSQL</productname>
+ 9.2 or later (Tom Lane)
+ </para>
+
+ <para>
+ Remove code that was only used when running with an older server.
+ Commands that do not require any version-specific adjustments
+ compared to 9.2 will still work.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title><link linkend="app-pgdump"><application>pg_dump</application></link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Noah Misch <noah@leadboat.com>
+2021-06-28 [a7a7be1f2] Dump public schema ownership and security labels.
+Author: Noah Misch <noah@leadboat.com>
+2021-06-28 [7ac10f692] Dump COMMENT ON SCHEMA public.
+-->
+
+ <listitem>
+ <para>
+ Make <application>pg_dump</application> dump
+ <literal>public</literal> schema ownership changes and security
+ labels (Noah Misch)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-06 [989596152] Avoid per-object queries in performance-critical paths i
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-06 [be85727a3] Use PREPARE/EXECUTE for repetitive per-object queries in
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-31 [d5e8930f5] pg_dump: minor performance improvements from eliminating
+-->
+
+ <listitem>
+ <para>
+ Improve performance of dumping databases with many objects
+ (Tom Lane)
+ </para>
+
+ <para>
+ This will also improve the performance of <link
+ linkend="pgupgrade"><application>pg_upgrade</application></link>.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-06 [65aaed22a] Account for TOAST data while scheduling parallel dumps.
+-->
+
+ <listitem>
+ <para>
+ Improve parallel <application>pg_dump</application>'s performance
+ for tables with large <acronym>TOAST</acronym> tables (Tom Lane)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-01-17 [215862886] Add support for - -no-table-access-method in pg_{dump,dum
+-->
+
+ <listitem>
+ <para>
+ Add dump/restore option <option>--no-table-access-method</option>
+ to force restore to only use the default table access method
+ (Justin Pryzby)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-14 [30e7c175b] Remove pg_dump/pg_dumpall support for dumping from pre-9
+-->
+
+ <listitem>
+ <para>
+ Limit support of <application>pg_dump</application> and <link
+ linkend="app-pg-dumpall"><application>pg_dumpall</application></link>
+ to servers running <productname>PostgreSQL</productname> 9.2 or
+ later (Tom Lane)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3>
+ <title>Server Applications</title>
+
+ <itemizedlist>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-20 [3500ccc39] Support base backup targets.
+-->
+
+ <listitem>
+ <para>
+ Add new <link
+ linkend="app-pgbasebackup"><application>pg_basebackup</application></link>
+ option <option>--target</option> to control the base backup location
+ (Robert Haas)
+ </para>
+
+ <para>
+ The new options are <literal>server</literal> to write the
+ backup locally and <literal>blackhole</literal> to discard the
+ backup (for testing).
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-11 [751b8d23b] pg_basebackup: Allow client-side LZ4 (de)compression.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-08 [7cf085f07] Add support for zstd base backup compression.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-24 [0ad803291] Server-side gzip compression.
+-->
+
+ <listitem>
+ <para>
+ Allow <application>pg_basebackup</application> to do server-side
+ gzip, LZ4, and Zstandard compression and client-side LZ4 and
+ Zstandard compression of base backup files (Dipesh Pandit,
+ Jeevan Ladhe)
+ </para>
+
+ <para>
+ Client-side <literal>gzip</literal> compression was already
+ supported.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-28 [d45099425] Allow server-side compression to be used with -Fp.
+-->
+
+ <listitem>
+ <para>
+ Allow <application>pg_basebackup</application> to compress on
+ the server side and decompress on the client side before storage
+ (Dipesh Pandit)
+ </para>
+
+ <para>
+ This is accomplished by specifying compression on the server side
+ and plain output format.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-01-21 [5c649fe15] Extend the options of pg_basebackup to control compressi
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-24 [0ad803291] Server-side gzip compression.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-25 [e1f860f13] Tidy up a few cosmetic issues related to pg_basebackup.
+-->
+
+ <listitem>
+ <para>
+ Allow <application>pg_basebackup</application>'s
+ <option>--compress</option> option to control the compression
+ location (server or client), compression method, and compression
+ options (Michael Paquier, Robert Haas)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-11-05 [babbbb595] Add support for LZ4 compression in pg_receivewal
+Author: Michael Paquier <michael@paquier.xyz>
+2022-04-13 [042a923ad] Rework compression options of pg_receivewal
+-->
+
+ <listitem>
+ <para>
+ Add the LZ4 compression method to <link
+ linkend="app-pgreceivewal"><application>pg_receivewal</application></link>
+ (Georgios Kokolatos)
+ </para>
+
+ <para>
+ This is enabled via <literal>--compress=lz4</literal> and requires
+ binaries to be built using <option>--with-lz4</option>.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-11-04 [d62bcc8b0] Rework compression options of pg_receivewal
+-->
+
+ <listitem>
+ <para>
+ Add additional capabilities to
+ <application>pg_receivewal</application>'s
+ <option>--compress</option> option (Georgios Kokolatos)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-10-26 [f61e1dd2c] Allow pg_receivewal to stream from a slot's restart LSN
+-->
+
+ <listitem>
+ <para>
+ Improve <application>pg_receivewal</application>'s ability to
+ restart at the proper <acronym>WAL</acronym> location (Ronan
+ Dunklau)
+ </para>
+
+ <para>
+ Previously, <application>pg_receivewal</application> would start
+ based on the <acronym>WAL</acronym> file stored in the local archive
+ directory, or at the sending server's current <acronym>WAL</acronym>
+ flush location. With this change, if the sending server is running
+ Postgres 15 or later, the local archive directory is empty, and
+ a replication slot is specified, the replication slot's restart
+ point will be used.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-04-07 [0d5c38757] Add option - -config-file to pg_rewind
+-->
+
+ <listitem>
+ <para>
+ Add <link
+ linkend="app-pgrewind"><application>pg_rewind</application></link>
+ option <option>--config-file</option> to simplify use when server
+ configuration files are stored outside the data directory (Gunnar
+ Bluth)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <sect4>
+ <title><link linkend="pgupgrade"><application>pg_upgrade</application></link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-02-06 [38bfae365] pg_upgrade: Move all the files generated internally to a
+Author: Michael Paquier <michael@paquier.xyz>
+2022-02-15 [a00849630] Fix thinko with subdirectories generated by pg_upgrade f
+Author: Michael Paquier <michael@paquier.xyz>
+2022-09-13 [f5047c129] Move any remaining files generated by pg_upgrade into an
+-->
+
+ <listitem>
+ <para>
+ Store <application>pg_upgrade</application>'s log and
+ temporary files in a subdirectory of the new cluster called
+ <filename>pg_upgrade_output.d</filename> (Justin Pryzby)
+ </para>
+
+ <para>
+ Previously such files were left in the current directory,
+ requiring manual cleanup. Now they are automatically removed on
+ successful completion of <application>pg_upgrade</application>.
+ </para>
+ </listitem>
+
+<!--
+Author: Andres Freund <andres@anarazel.de>
+2022-02-21 [27b02e070] pg_upgrade: Don't print progress status when output is n
+-->
+
+ <listitem>
+ <para>
+ Disable default status reporting during
+ <application>pg_upgrade</application> operation if the output is
+ not a terminal (Andres Freund)
+ </para>
+
+ <para>
+ The status reporting output can be enabled for non-tty usage by
+ using <option>--verbose</option>.
+ </para>
+ </listitem>
+
+<!--
+Author: Daniel Gustafsson <dgustafsson@postgresql.org>
+2022-03-24 [26ebb0e28] List offending databases in pg_upgrade datallowconn chec
+-->
+
+ <listitem>
+ <para>
+ Make <application>pg_upgrade</application> report all databases
+ with invalid connection settings (Jeevan Ladhe)
+ </para>
+
+ <para>
+ Previously only the first database with an invalid connection
+ setting was reported.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-17 [9a974cbcb] pg_upgrade: Preserve relfilenodes and tablespace OIDs.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-24 [aa0105141] pg_upgrade: Preserve database OIDs.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-07-28 [4ab5dae94] Use TRUNCATE to preserve relfilenode for pg_largeobject
+-->
+
+ <listitem>
+ <para>
+ Make <application>pg_upgrade</application> preserve tablespace
+ and database OIDs, as well as relation relfilenode numbers
+ (Shruthi Gowda, Antonin Houska)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-12-18 [3d5ffccb6] Add option -N/- -no-sync to pg_upgrade
+-->
+
+ <listitem>
+ <para>
+ Add a <option>--no-sync</option> option to
+ <application>pg_upgrade</application> (Michael Paquier)
+ </para>
+
+ <para>
+ This is recommended only for testing.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-14 [e469f0aaf] Remove pg_upgrade support for upgrading from pre-9.2 ser
+-->
+
+ <listitem>
+ <para>
+ Limit support of <application>pg_upgrade</application> to old
+ servers running <productname>PostgreSQL</productname> 9.2 or later
+ (Tom Lane)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ <sect4>
+ <title><link linkend="pgwaldump"><application>pg_waldump</application></link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Thomas Munro <tmunro@postgresql.org>
+2022-03-24 [127aea2a6] Add additional filtering options to pg_waldump.
+Author: Thomas Munro <tmunro@postgresql.org>
+2022-03-25 [52b556843] Improve command line options for pg_waldump.
+-->
+
+ <listitem>
+ <para>
+ Allow <application>pg_waldump</application> output to be filtered by
+ relation file node, block number, fork number, and full page images
+ (David Christensen, Thomas Munro)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-12-02 [f2c52eeba] pg_waldump: Emit stats summary when interrupted by SIGIN
+-->
+
+ <listitem>
+ <para>
+ Make <application>pg_waldump</application> report statistics
+ before an interrupted exit (Bharath Rupireddy)
+ </para>
+
+ <para>
+ For example, issuing a control-C in a terminal running
+ <command>pg_waldump --stats --follow</command> will report the
+ current statistics before exiting. This does not work on Windows.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-12-13 [c8b733c4c] Improve description of some WAL records with transaction
+-->
+
+ <listitem>
+ <para>
+ Improve descriptions of some transaction <acronym>WAL</acronym>
+ records reported by <application>pg_waldump</application>
+ (Masahiko Sawada, Michael Paquier)
+ </para>
+ </listitem>
+
+<!--
+Author: Heikki Linnakangas <heikki.linnakangas@iki.fi>
+2021-07-01 [c8bf5098c] Allow specifying pg_waldump - -rmgr option multiple times
+-->
+
+ <listitem>
+ <para>
+ Allow <application>pg_waldump</application> to dump information
+ about multiple resource managers (Heikki Linnakangas)
+ </para>
+
+ <para>
+ This is enabled by specifying the <option>--rmgr</option> option
+ multiple times.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ </sect3>
+
+ <sect3>
+ <title>Documentation</title>
+
+ <itemizedlist>
+
+<!--
+Author: Fujii Masao <fujii@postgresql.org>
+2021-10-05 [f6b5d05ba] doc: Document pg_encoding_to_char() and pg_char_to_encod
+-->
+
+ <listitem>
+ <para>
+ Add documentation for <link
+ linkend="functions-info-catalog-table"><function>pg_encoding_to_char()</function></link>
+ and <function>pg_char_to_encoding()</function> (Ian Lawrence
+ Barwick)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-10-09 [2ae5d72f0] Doc: improve documentation for ^@ starts-with operator.
+-->
+
+ <listitem>
+ <para>
+ Document the <link
+ linkend="functions-string-other"><literal>^@</literal></link>
+ starts-with operator (Tom Lane)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title>Source Code</title>
+
+ <itemizedlist>
+
+<!--
+Author: Andres Freund <andres@anarazel.de>
+2021-12-30 [93d973494] ci: Add continuous integration for github repositories v
+-->
+
+ <listitem>
+ <para>
+ Add support for continuous integration testing using cirrus-ci
+ (Andres Freund, Thomas Munro, Melanie Plageman)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-18 [6c417bbcc] Add support for building with ZSTD.
+-->
+
+ <listitem>
+ <para>
+ Add configure option <link
+ linkend="configure-options-features"><option>--with-zstd</option></link>
+ to enable Zstandard builds (Jeevan Ladhe, Robert Haas, Michael
+ Paquier)
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-11-22 [d6d1dfcc9] Add ABI extra field to fmgr magic block
+-->
+
+ <listitem>
+ <para>
+ Add an ABI identifier field to the magic block in loadable
+ libraries, allowing
+ non-community <productname>PostgreSQL</productname> distributions
+ to identify libraries that are not compatible with other builds
+ (Peter Eisentraut)
+ </para>
+
+ <para>
+ An ABI field mismatch will generate an error at load time.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-12-11 [07eee5a0d] Create a new type category for "internal use" types.
+-->
+
+ <listitem>
+ <para>
+ Create a new <link
+ linkend="catalog-pg-type"><structfield>pg_type.typcategory</structfield></link>
+ value for <type>"char"</type> (Tom Lane)
+ </para>
+
+ <para>
+ Some other internal-use-only types have also been assigned to this
+ category.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-18 [cc333f323] Modify pg_basebackup to use a new COPY subprotocol for b
+-->
+
+ <listitem>
+ <para>
+ Add new protocol message <link
+ linkend="protocol-replication-base-backup"><literal>TARGET</literal></link>
+ to specify a new <command>COPY</command> method to be used for base
+ backups (Robert Haas)
+ </para>
+
+ <para>
+ <link
+ linkend="app-pgbasebackup"><application>pg_basebackup</application></link>
+ now uses this method.
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-01-24 [0ad803291] Server-side gzip compression.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-23 [ffd53659c] Replace BASE_BACKUP COMPRESSION_LEVEL option with COMPRE
+-->
+
+ <listitem>
+ <para>
+ Add new protocol message <link
+ linkend="protocol-replication-base-backup"><literal>COMPRESSION</literal></link>
+ and <literal>COMPRESSION_DETAIL</literal> to specify the compression
+ method and options (Robert Haas)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-10 [9cd28c2e5] Remove server support for old BASE_BACKUP command syntax
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-10 [0d4513b61] Remove server support for the previous base backup proto
+-->
+
+ <listitem>
+ <para>
+ Remove server support for old <literal>BASE_BACKUP</literal>
+ command syntax and base backup protocol (Robert Haas)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-15 [e4ba69f3f] Allow extensions to add new backup targets.
+-->
+
+ <listitem>
+ <para>
+ Add support for extensions to set custom backup targets (Robert
+ Haas)
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2022-04-06 [5c279a6d3] Custom WAL Resource Managers.
+-->
+
+ <listitem>
+ <para>
+ Allow extensions to define custom <acronym>WAL</acronym>
+ resource managers (Jeff Davis)
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-01-31 [d10e41d42] Introduce pg_settings_get_flags() to find flags associat
+-->
+
+ <listitem>
+ <para>
+ Add function <link
+ linkend="functions-info-catalog-table"><function>pg_settings_get_flags()</function></link>
+ to get the flags of server variables (Justin Pryzby)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-04-08 [8ec569479] Apply PGDLLIMPORT markings broadly.
+-->
+
+ <listitem>
+ <para>
+ On Windows, export all the server's global variables using
+ <literal>PGDLLIMPORT</literal> markers (Robert Haas)
+ </para>
+
+ <para>
+ Previously, only specific variables were accessible to extensions
+ on Windows.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-07-23 [3b474a2e6] Increase minimum supported GNU make version to 3.81.
+-->
+
+ <listitem>
+ <para>
+ Require GNU <application>make</application> version 3.81 or later
+ to build <productname>PostgreSQL</productname> (Tom Lane)
+ </para>
+ </listitem>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-11-05 [db7d1a7b0] pgcrypto: Remove non-OpenSSL support
+-->
+
+ <listitem>
+ <para>
+ Require OpenSSL to build the <link
+ linkend="pgcrypto"><application>pgcrypto</application></link>
+ extension (Peter Eisentraut)
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-10-07 [92e6a98c3] Adjust configure to insist on Perl version &gt;= 5.8.3.
+-->
+
+ <listitem>
+ <para>
+ Require <application>Perl</application>
+ version 5.8.3 or later (Dagfinn Ilmari Mannsåker)
+ </para>
+ </listitem>
+
+<!--
+Author: Andres Freund <andres@anarazel.de>
+2022-02-16 [19252e8ec] plpython: Reject Python 2 during build configuration.
+-->
+
+ <listitem>
+ <para>
+ Require <application>Python</application>
+ version 3.2 or later (Andres Freund)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title>Additional Modules</title>
+
+ <itemizedlist>
+
+<!--
+Author: Peter Eisentraut <peter@eisentraut.org>
+2021-09-28 [c3b011d99] Support amcheck of sequences
+-->
+
+ <listitem>
+ <para>
+ Allow <link
+ linkend="amcheck"><application>amcheck</application></link> to
+ check sequences (Mark Dilger)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2021-11-05 [bd807be69] amcheck: Add additional TOAST pointer checks.
+-->
+
+ <listitem>
+ <para>
+ Improve <application>amcheck</application> sanity checks for
+ <acronym>TOAST</acronym> tables (Mark Dilger)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-15 [c6306db24] Add 'basebackup_to_shell' contrib module.
+Author: Robert Haas <rhaas@postgresql.org>
+2022-03-30 [26a0c025e] Document basebackup_to_shell.required_role.
+-->
+
+ <listitem>
+ <para>
+ Add new module <application><link
+ linkend="basebackup-to-shell">basebackup_to_shell</link></application>
+ as an example of a custom backup target (Robert Haas)
+ </para>
+ </listitem>
+
+<!--
+Author: Robert Haas <rhaas@postgresql.org>
+2022-02-03 [5ef1eefd7] Allow archiving via loadable modules.
+-->
+
+ <listitem>
+ <para>
+ Add new module <link
+ linkend="basic-archive"><application>basic_archive</application></link>
+ as an example of performing archiving via a library (Nathan Bossart)
+ </para>
+ </listitem>
+
+<!--
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2021-11-06 [57e3c5160] Add bool GiST opclass to btree_gist
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2021-11-08 [e2fbb8837] Fix gist_bool_ops to use gbtreekey2
+Author: Tomas Vondra <tomas.vondra@postgresql.org>
+2021-12-11 [4c6145b51] Add bool to btree_gist documentation
+-->
+
+ <listitem>
+ <para>
+ Allow <link
+ linkend="btree-gist"><application>btree_gist</application></link>
+ indexes on boolean columns (Emre Hasegeli)
+ </para>
+
+ <para>
+ These can be used for exclusion constraints.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2021-07-12 [127404fbe] pageinspect: Improve page_header() for pages of 32kB
+-->
+
+ <listitem>
+ <para>
+ Fix <link
+ linkend="pageinspect"><application>pageinspect</application></link>'s
+ <function>page_header()</function> to handle 32-kilobyte page sizes
+ (Quan Zongliang)
+ </para>
+
+ <para>
+ Previously, improper negative values could be returned in certain
+ cases.
+ </para>
+ </listitem>
+
+<!--
+Author: Michael Paquier <michael@paquier.xyz>
+2022-04-08 [76cbf7edb] pg_stat_statements: Track I/O timing for temporary file
+-->
+
+ <listitem>
+ <para>
+ Add counters for temporary file block I/O to <link
+ linkend="pgstatstatements"><application>pg_stat_statements</application></link>
+ (Masahiko Sawada)
+ </para>
+ </listitem>
+
+<!--
+Author: Magnus Hagander <magnus@hagander.net>
+2022-04-08 [57d6aea00] Add JIT counters to pg_stat_statements
+-->
+
+ <listitem>
+ <para>
+ Add <acronym>JIT</acronym> counters to pg_stat_statements (Magnus
+ Hagander)
+ </para>
+ </listitem>
+
+<!--
+Author: Jeff Davis <jdavis@postgresql.org>
+2022-04-08 [2258e76f9] Add contrib/pg_walinspect.
+-->
+
+ <listitem>
+ <para>
+ Add new module <link
+ linkend="pgwalinspect"><application>pg_walinspect</application></link>
+ (Bharath Rupireddy)
+ </para>
+
+ <para>
+ This gives <acronym>SQL</acronym>-level output similar to <link
+ linkend="pgwaldump"><application>pg_waldump</application></link>.
+ </para>
+ </listitem>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2022-01-12 [134d97463] Include permissive/enforcing state in sepgsql log messag
+-->
+
+ <listitem>
+ <para>
+ Indicate the permissive/enforcing state in <link
+ linkend="sepgsql"><application>sepgsql</application></link> log
+ messages (Dave Page)
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <sect4>
+ <title><link linkend="postgres-fdw"><application>postgres_fdw</application></link></title>
+
+ <itemizedlist>
+
+<!--
+Author: Tom Lane <tgl@sss.pgh.pa.us>
+2021-07-30 [5d44fff01] In postgres_fdw, allow CASE expressions to be pushed to
+-->
+
+ <listitem>
+ <para>
+ Allow postgres_fdw to push down <literal>CASE</literal> expressions
+ (Alexander Pyhalov)
+ </para>
+ </listitem>
+
+<!--
+Author: Fujii Masao <fujii@postgresql.org>
+2021-09-07 [449ab6350] postgres_fdw: Allow application_name of remote connectio
+Author: Fujii Masao <fujii@postgresql.org>
+2021-12-24 [6e0cb3dec] postgres_fdw: Allow postgres_fdw.application_name to inc
+Author: Fujii Masao <fujii@postgresql.org>
+2022-02-18 [94c49d534] postgres_fdw: Make postgres_fdw.application_name support
+-->
+
+ <listitem>
+ <para>
+ Add server variable
+ <varname>postgres_fdw.application_name</varname> to control the
+ application name of postgres_fdw connections (Hayato Kuroda)
+ </para>
+
+ <para>
+ Previously the remote session's <link
+ linkend="guc-application-name"><varname>application_name</varname></link>
+ could only be set on the remote server or via a
+ <application>postgres_fdw</application> connection specification.
+ <varname>postgres_fdw.application_name</varname> supports some
+ escape sequences for customization, making it easier to tell such
+ connections apart on the remote server.
+ </para>
+ </listitem>
+
+<!--
+Author: Etsuro Fujita <efujita@postgresql.org>
+2022-02-24 [04e706d42] postgres_fdw: Add support for parallel commit.
+-->
+
+ <listitem>
+ <para>
+ Allow parallel commit on <application>postgres_fdw</application>
+ servers (Etsuro Fujita)
+ </para>
+
+ <para>
+ This is enabled with the <literal>CREATE SERVER</literal> option
+ <literal>parallel_commit</literal>.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ </sect4>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="release-15-acknowledgements">
+ <title>Acknowledgments</title>
+
+ <para>
+ The following individuals (in alphabetical order) have contributed
+ to this release as patch authors, committers, reviewers, testers,
+ or reporters of issues.
+ </para>
+
+ <simplelist>
+ <member>Abhijit Menon-Sen</member>
+ <member>Adam Brusselback</member>
+ <member>Adam Mackler</member>
+ <member>Adrian Ho</member>
+ <member>Ahsan Hadi</member>
+ <member>Ajin Cherian</member>
+ <member>Alastair McKinley</member>
+ <member>Aleksander Alekseev</member>
+ <member>Ales Zeleny</member>
+ <member>Alex Kingsborough</member>
+ <member>Alex Kozhemyakin</member>
+ <member>Alexander Korotkov</member>
+ <member>Alexander Kukushkin</member>
+ <member>Alexander Lakhin</member>
+ <member>Alexander Nawratil</member>
+ <member>Alexander Pyhalov</member>
+ <member>Alexey Borzov</member>
+ <member>Alexey Ermakov</member>
+ <member>Aliaksandr Kalenik</member>
+ <member>Álvaro Herrera</member>
+ <member>Amit Kapila</member>
+ <member>Amit Khandekar</member>
+ <member>Amit Langote</member>
+ <member>Amul Sul</member>
+ <member>Anastasia Lubennikova</member>
+ <member>Anders Kaseorg</member>
+ <member>Andreas Dijkman</member>
+ <member>Andreas Grob</member>
+ <member>Andreas Seltenreich</member>
+ <member>Andrei Zubkov</member>
+ <member>Andres Freund</member>
+ <member>Andrew Alsup</member>
+ <member>Andrew Bille</member>
+ <member>Andrew Dunstan</member>
+ <member>Andrew Gierth</member>
+ <member>Andrew Kesper</member>
+ <member>Andrey Borodin</member>
+ <member>Andrey Lepikhov</member>
+ <member>Andrey Sokolov</member>
+ <member>Andy Fan</member>
+ <member>Anton Melnikov</member>
+ <member>Anton Voloshin</member>
+ <member>Antonin Houska</member>
+ <member>Arjan van de Ven</member>
+ <member>Arne Roland</member>
+ <member>Arthur Zakirov</member>
+ <member>Ashutosh Bapat</member>
+ <member>Ashutosh Sharma</member>
+ <member>Ashwin Agrawal</member>
+ <member>Asif Rehman</member>
+ <member>Asim Praveen</member>
+ <member>Atsushi Torikoshi</member>
+ <member>Aya Iwata</member>
+ <member>Bauyrzhan Sakhariyev</member>
+ <member>Benoit Lobréau</member>
+ <member>Bernd Dorn</member>
+ <member>Bertrand Drouvot</member>
+ <member>Bharath Rupireddy</member>
+ <member>Björn Harrtell</member>
+ <member>Boris Kolpackov</member>
+ <member>Boris Korzun</member>
+ <member>Brad Nicholson</member>
+ <member>Brar Piening</member>
+ <member>Bruce Momjian</member>
+ <member>Bruno da Silva</member>
+ <member>Bryn Llewellyn</member>
+ <member>Carl Sopchak</member>
+ <member>Cary Huang</member>
+ <member>Chapman Flack</member>
+ <member>Chen Jiaoqian</member>
+ <member>Chris Bandy</member>
+ <member>Chris Lowder</member>
+ <member>Christian Quest</member>
+ <member>Christoph Berg</member>
+ <member>Christoph Heiss</member>
+ <member>Christophe Pettus</member>
+ <member>Christopher Painter-Wakefield</member>
+ <member>Claudio Freire</member>
+ <member>Clemens Zeidler</member>
+ <member>Corey Huinker</member>
+ <member>Dag Lem</member>
+ <member>Dagfinn Ilmari Mannsåker</member>
+ <member>Dan Kubb</member>
+ <member>Daniel Cherniy</member>
+ <member>Daniel Gustafsson</member>
+ <member>Daniel Polski</member>
+ <member>Daniel Vérité</member>
+ <member>Daniel Westermann</member>
+ <member>Daniele Varrazzo</member>
+ <member>Daniil Anisimov</member>
+ <member>Danny Shemesh</member>
+ <member>Darafei Praliaskouski</member>
+ <member>Daria Lepikhova</member>
+ <member>Dave Cramer</member>
+ <member>Dave Page</member>
+ <member>David Christensen</member>
+ <member>David Fetter</member>
+ <member>David G. Johnston</member>
+ <member>David Rowley</member>
+ <member>David Steele</member>
+ <member>David Zhang</member>
+ <member>Dean Rasheed</member>
+ <member>Dian Fay</member>
+ <member>Dilip Kumar</member>
+ <member>Dipesh Pandit</member>
+ <member>Dmitry Dolgov</member>
+ <member>Dmitry Koval</member>
+ <member>Dmitry Marakasov</member>
+ <member>Dominique Devienne</member>
+ <member>Dong Wook</member>
+ <member>Drew DeVault</member>
+ <member>Eduard Català</member>
+ <member>Egor Chindyaskin</member>
+ <member>Egor Rogov</member>
+ <member>Ekaterina Kiryanova</member>
+ <member>Elena Indrupskaya</member>
+ <member>Elvis Pranskevichus</member>
+ <member>Emmanuel Quincerot</member>
+ <member>Emre Hasegeli</member>
+ <member>Eric Mutta</member>
+ <member>Erica Zhang</member>
+ <member>Erik Rijkers</member>
+ <member>Erki Eessaar</member>
+ <member>Etsuro Fujita</member>
+ <member>Euler Taveira</member>
+ <member>Fabien Coelho</member>
+ <member>Fabrice Chapuis</member>
+ <member>Fabrice Fontaine</member>
+ <member>Fabrízio de Royes Mello</member>
+ <member>Feike Steenbergen</member>
+ <member>Filip Gospodinov</member>
+ <member>Florin Irion</member>
+ <member>Floris Van Nee</member>
+ <member>Frédéric Yhuel</member>
+ <member>Gabriela Serventi</member>
+ <member>Gaurab Dey</member>
+ <member>Geoff Winkless</member>
+ <member>Geoffrey Blake</member>
+ <member>Georgios Kokolatos</member>
+ <member>Gilles Darold</member>
+ <member>Greg Nancarrow</member>
+ <member>Greg Rychlewski</member>
+ <member>Greg Sabino Mullane</member>
+ <member>Greg Stark</member>
+ <member>Gregory Smith</member>
+ <member>Guillaume Lelarge</member>
+ <member>Gunnar Bluth</member>
+ <member>Gurjeet Singh</member>
+ <member>Haiyang Wang</member>
+ <member>Haiying Tang</member>
+ <member>Hannu Krosing</member>
+ <member>Hans Buschmann</member>
+ <member>Hayato Kuroda</member>
+ <member>Heath Lord</member>
+ <member>Heikki Linnakangas</member>
+ <member>Herwig Goemans</member>
+ <member>Himanshu Upadhyaya</member>
+ <member>Holly Roberts</member>
+ <member>Hou Zhijie</member>
+ <member>Hubert Lubaczewski</member>
+ <member>Ian Barwick</member>
+ <member>Ian Campbell</member>
+ <member>Ibrar Ahmed</member>
+ <member>Ildus Kurbangaliev</member>
+ <member>Ilya Anfimov</member>
+ <member>Itamar Gafni</member>
+ <member>Jacob Champion</member>
+ <member>Jaime Casanova</member>
+ <member>Jakub Wartak</member>
+ <member>James Coleman</member>
+ <member>James Hilliard</member>
+ <member>James Inform</member>
+ <member>Jan Piotrowski</member>
+ <member>Japin Li</member>
+ <member>Jason Harvey</member>
+ <member>Jason Kim</member>
+ <member>Jean-Christophe Arnu</member>
+ <member>Jeevan Ladhe</member>
+ <member>Jeff Davis</member>
+ <member>Jeff Janes</member>
+ <member>Jehan-Guillaume de Rorthais</member>
+ <member>Jelte Fennema</member>
+ <member>Jeremy Evans</member>
+ <member>Jeremy Schneider</member>
+ <member>Jian Guo</member>
+ <member>Jian He</member>
+ <member>Jimmy Yih</member>
+ <member>Jiri Fejfar</member>
+ <member>Jitka Plesníková</member>
+ <member>Joe Conway</member>
+ <member>Joe Wildish</member>
+ <member>Joel Jacobson</member>
+ <member>Joey Bodoia</member>
+ <member>John Naylor</member>
+ <member>Jonathan Katz</member>
+ <member>Josef Simanek</member>
+ <member>Joseph Koshakow</member>
+ <member>Josh Soref</member>
+ <member>Joshua Brindle</member>
+ <member>Juan José Santamaría Flecha</member>
+ <member>Julien Rouhaud</member>
+ <member>Julien Roze</member>
+ <member>Junwang Zhao</member>
+ <member>Jürgen Purtz</member>
+ <member>Justin Pryzby</member>
+ <member>Ken Kato</member>
+ <member>Kevin Burke</member>
+ <member>Kevin Grittner</member>
+ <member>Kevin Humphreys</member>
+ <member>Kevin McKibbin</member>
+ <member>Kevin Sweet</member>
+ <member>Kevin Zheng</member>
+ <member>Klaudie Willis</member>
+ <member>Konstantin Knizhnik</member>
+ <member>Konstantina Skovola</member>
+ <member>Kosei Masumura</member>
+ <member>Kotaro Kawamoto</member>
+ <member>Koyu Tanigawa</member>
+ <member>Kuntal Ghosh</member>
+ <member>Kyotaro Horiguchi</member>
+ <member>Lars Kanis</member>
+ <member>Lauren Fliksteen</member>
+ <member>Laurent Hasson</member>
+ <member>Laurenz Albe</member>
+ <member>Leslie Lemaire</member>
+ <member>Liam Bowen</member>
+ <member>Lingjie Qiang</member>
+ <member>Liu Huailing</member>
+ <member>Louis Jachiet</member>
+ <member>Lukas Fittl</member>
+ <member>Ma Liangzhu</member>
+ <member>Maciek Sakrejda</member>
+ <member>Magnus Hagander</member>
+ <member>Mahendra Singh Thalor</member>
+ <member>Maksim Milyutin</member>
+ <member>Marc Bachmann</member>
+ <member>Marcin Krupowicz</member>
+ <member>Marcus Gartner</member>
+ <member>Marek Szuba</member>
+ <member>Marina Polyakova</member>
+ <member>Mario Emmenlauer</member>
+ <member>Mark Dilger</member>
+ <member>Mark Murawski</member>
+ <member>Mark Wong</member>
+ <member>Markus Wanner</member>
+ <member>Markus Winand</member>
+ <member>Martijn van Oosterhout</member>
+ <member>Martin Jurca</member>
+ <member>Martin Kalcher</member>
+ <member>Martín Marqués</member>
+ <member>Masahiko Sawada</member>
+ <member>Masahiro Ikeda</member>
+ <member>Masao Fujii</member>
+ <member>Masaya Kawamoto</member>
+ <member>Masayuki Hirose</member>
+ <member>Matthias van de Meent</member>
+ <member>Matthijs van der Vleuten</member>
+ <member>Maxim Orlov</member>
+ <member>Maxim Yablokov</member>
+ <member>Melanie Plageman</member>
+ <member>Michael Banck</member>
+ <member>Michael Harris</member>
+ <member>Michael J. Sullivan</member>
+ <member>Michael Meskes</member>
+ <member>Michael Mühlbeyer</member>
+ <member>Michael Paquier</member>
+ <member>Michael Powers</member>
+ <member>Mike Fiedler</member>
+ <member>Mike Oh</member>
+ <member>Mikhail Kulagin</member>
+ <member>Miles Delahunty</member>
+ <member>Naoki Okano</member>
+ <member>Nathan Bossart</member>
+ <member>Nathan Long</member>
+ <member>Nazir Bilal Yavuz</member>
+ <member>Neha Sharma</member>
+ <member>Neil Chen</member>
+ <member>Nicola Contu</member>
+ <member>Nicolas Lutic</member>
+ <member>Nikhil Benesch</member>
+ <member>Nikhil Shetty</member>
+ <member>Nikhil Sontakke</member>
+ <member>Nikita Glukhov</member>
+ <member>Nikolai Berkoff</member>
+ <member>Nikolay Samokhvalov</member>
+ <member>Nikolay Shaplov</member>
+ <member>Nitin Jadhav</member>
+ <member>Noah Misch</member>
+ <member>Noboru Saito</member>
+ <member>Noriyoshi Shinoda</member>
+ <member>Olaf Bohlen</member>
+ <member>Olly Betts</member>
+ <member>Onder Kalaci</member>
+ <member>Oskar Stenberg</member>
+ <member>Otto Kekalainen</member>
+ <member>Paul Guo</member>
+ <member>Paul Jungwirth</member>
+ <member>Paul Martinez</member>
+ <member>Pavan Deolasee</member>
+ <member>Pavel Borisov</member>
+ <member>Pavel Luzanov</member>
+ <member>Pavel Stehule</member>
+ <member>Peter Eisentraut</member>
+ <member>Peter Geoghegan</member>
+ <member>Peter Slavov</member>
+ <member>Peter Smith</member>
+ <member>Petr Jelínek</member>
+ <member>Phil Florent</member>
+ <member>Phil Krylov</member>
+ <member>Pierre-Aurélien Georges</member>
+ <member>Prabhat Sahu</member>
+ <member>Quan Zongliang</member>
+ <member>Rachel Heaton</member>
+ <member>Rahila Syed</member>
+ <member>Rajakavitha Kodhandapani</member>
+ <member>Rajkumar Raghuwanshi</member>
+ <member>Ranier Vilela</member>
+ <member>Rei Kamigishi</member>
+ <member>Reid Thompson</member>
+ <member>Rémi Lapeyre</member>
+ <member>Renan Soares Lopes</member>
+ <member>Richard Guo</member>
+ <member>Richard Wesley</member>
+ <member>RKN Sai Krishna</member>
+ <member>Robert Haas</member>
+ <member>Robert Treat</member>
+ <member>Roberto Mello</member>
+ <member>Robins Tharakan</member>
+ <member>Roger Mason</member>
+ <member>Roman Zharkov</member>
+ <member>Ronan Dunklau</member>
+ <member>Rui Zhao</member>
+ <member>Ryan Kelly</member>
+ <member>Ryo Matsumura</member>
+ <member>Ryohei Takahashi</member>
+ <member>Sadhuprasad Patro</member>
+ <member>Sait Talha Nisanci</member>
+ <member>Sami Imseih</member>
+ <member>Sandeep Thakkar</member>
+ <member>Sebastian Kemper</member>
+ <member>Sehrope Sarkuni</member>
+ <member>Sergei Kornilov</member>
+ <member>Sergei Shoulbakov</member>
+ <member>Sergey Shinderuk</member>
+ <member>Shay Rojansky</member>
+ <member>Shenhao Wang</member>
+ <member>Shi Yu</member>
+ <member>Shinya Kato</member>
+ <member>Shruthi Gowda</member>
+ <member>Simon Perepelitsa</member>
+ <member>Simon Riggs</member>
+ <member>Sirisha Chamarthi</member>
+ <member>Soumyadeep Chakraborty</member>
+ <member>Stan Hu</member>
+ <member>Stas Kelvich</member>
+ <member>Stefen Hillman</member>
+ <member>Stephen Frost</member>
+ <member>Steve Chavez</member>
+ <member>Sumanta Mukherjee</member>
+ <member>Suraj Khamkar</member>
+ <member>Suraj Kharage</member>
+ <member>Sven Klemm</member>
+ <member>Takamichi Osumi</member>
+ <member>Takayuki Tsunakawa</member>
+ <member>Takeshi Ideriha</member>
+ <member>Tatsuhiro Nakamori</member>
+ <member>Tatsuhito Kasahara</member>
+ <member>Tatsuo Ishii</member>
+ <member>Tatsuro Yamada</member>
+ <member>Teja Mupparti</member>
+ <member>Teodor Sigaev</member>
+ <member>Thibaud Walkowiak</member>
+ <member>Thom Brown</member>
+ <member>Thomas McKay</member>
+ <member>Thomas Munro</member>
+ <member>Tim McNamara</member>
+ <member>Timo Stolz</member>
+ <member>Timur Khanjanov</member>
+ <member>Tom Lane</member>
+ <member>Tomas Barton</member>
+ <member>Tomas Vondra</member>
+ <member>Tony Reix</member>
+ <member>Troy Frericks</member>
+ <member>Tushar Ahuja</member>
+ <member>Victor Wagner</member>
+ <member>Victor Yegorov</member>
+ <member>Vignesh C</member>
+ <member>Vik Fearing</member>
+ <member>Vincas Dargis</member>
+ <member>Vitaly Burovoy</member>
+ <member>Vitaly Voronov</member>
+ <member>Vladimir Sitnikov</member>
+ <member>Wang Ke</member>
+ <member>Wei Sun</member>
+ <member>Wei Wang</member>
+ <member>Whale Song</member>
+ <member>Will Mortensen</member>
+ <member>Wolfgang Walther</member>
+ <member>Yanliang Lei</member>
+ <member>Yaoguang Chen</member>
+ <member>Yogendra Suralkar</member>
+ <member>YoungHwan Joo</member>
+ <member>Yugo Nagata</member>
+ <member>Yukun Wang</member>
+ <member>Yura Sokolov</member>
+ <member>Yusuke Egashira</member>
+ <member>Yuzuko Hosoya</member>
+ <member>Zhang Mingli</member>
+ <member>Zhang Wenjie</member>
+ <member>Zhihong Yu</member>
+ <member>Zhiyong Wu</member>
+ </simplelist>
+ </sect2>
+
+ </sect1>
diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml
new file mode 100644
index 0000000..3ea5024
--- /dev/null
+++ b/doc/src/sgml/release.sgml
@@ -0,0 +1,95 @@
+<!-- doc/src/sgml/release.sgml -->
+<!--
+
+Typical markup:
+
+&<> use & escapes
+PostgreSQL <productname>
+postgresql.conf, pg_hba.conf <filename>
+\<[A-Z][A-Z_ ]+[A-Z_]\> <command>, <literal>, <envar>, <acronym>
+\<[A-Za-z_][A-Za-z0-9_]+() <function>
+\-\-?[A-Za-z_]+[-A-Za-z_]* <option> (use backslashes to avoid SGML markup)
+\<[A-Za-z_]+/[A-Za-z_]+\> <filename>
+psql <application>
+pg_[A-Za-z0-9_]+ <application>, <structname>
+\<[A-Z][A-Z][A-Z_ ]*\> <type>
+\<[a-z]+_[a-z_]+\> <varname>, <structfield>
+ <systemitem class="osname">
+
+non-ASCII characters find using grep -P '[\x80-\xFF]'
+ convert to HTML4 named entity (&) escapes
+
+ official: http://www.w3.org/TR/html4/sgml/entities.html
+ one page: http://www.zipcon.net/~swhite/docs/computers/browsers/entities_page.html
+ other lists: http://www.zipcon.net/~swhite/docs/computers/browsers/entities.html
+ http://www.zipcon.net/~swhite/docs/computers/browsers/entities_page.html
+ https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
+
+ We cannot use UTF8 because back branches still use SGML Docbook,
+ which does not support it. Also, rendering engines have to
+ support the referenced characters.
+
+ Do not use numeric _UTF_ numeric character escapes (&#nnn;),
+ we can only use Latin1.
+
+ Example: Alvaro Herrera is &Aacute;lvaro Herrera
+ Find non-ASCII characters (remove 'X'):
+ grep -X-color='auto' -P -n "[\x80-\xFF]"
+
+wrap long lines
+
+For new features, add links to the documentation sections.
+
+-->
+
+<appendix id="release">
+ <title>Release Notes</title>
+
+ <para>
+ The release notes contain the significant changes in each
+ <productname>PostgreSQL</productname> release, with major features and migration
+ issues listed at the top. The release notes do not contain changes
+ that affect only a few users or changes that are internal and therefore not
+ user-visible. For example, the optimizer is improved in almost every
+ release, but the improvements are usually observed by users as simply
+ faster queries.
+ </para>
+
+ <para>
+ A complete list of changes for each release can be obtained by
+ viewing the <link linkend="git">Git</link> logs for each release.
+ The <ulink
+ url="https://www.postgresql.org/list/pgsql-committers/"><literal>pgsql-committers</literal>
+ email list</ulink> records all source code changes as well. There is also
+ a <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=summary">web
+ interface</ulink> that shows changes to specific files.
+ </para>
+
+ <para>
+ The name appearing next to each item represents the major developer for
+ that item. Of course all changes involve community discussion and patch
+ review, so each item is truly a community effort.
+ </para>
+
+<!--
+ When beginning a new major-release series, create a new release-NN.sgml
+ file, removing the previous one, and change the &-reference here.
+ Don't forget to update filelist.sgml.
+
+ The reason for keeping each branch's release notes in a differently-named
+ file is to reduce confusion when preparing minor-release updates.
+ All the active branches have to be edited concurrently when doing that.
+-->
+
+&release-15;
+
+ <sect1 id="release-prior">
+ <title>Prior Releases</title>
+
+ <para>
+ Release notes for prior release branches can be found at
+ <ulink url="https://www.postgresql.org/docs/release/"><literal>https://www.postgresql.org/docs/release/</literal></ulink>
+ </para>
+ </sect1>
+
+</appendix>
diff --git a/doc/src/sgml/replication-origins.sgml b/doc/src/sgml/replication-origins.sgml
new file mode 100644
index 0000000..bb0fb62
--- /dev/null
+++ b/doc/src/sgml/replication-origins.sgml
@@ -0,0 +1,96 @@
+<!-- doc/src/sgml/replication-origins.sgml -->
+<chapter id="replication-origins">
+ <title>Replication Progress Tracking</title>
+
+ <indexterm zone="replication-origins">
+ <primary>Replication Progress Tracking</primary>
+ </indexterm>
+ <indexterm zone="replication-origins">
+ <primary>Replication Origins</primary>
+ </indexterm>
+
+ <para>
+ Replication origins are intended to make it easier to implement
+ logical replication solutions on top
+ of <link linkend="logicaldecoding">logical decoding</link>.
+ They provide a solution to two common problems:
+ <itemizedlist>
+ <listitem>
+ <para>How to safely keep track of replication progress</para>
+ </listitem>
+ <listitem>
+ <para>How to change replication behavior based on the
+ origin of a row; for example, to prevent loops in bi-directional
+ replication setups</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Replication origins have just two properties, a name and an ID. The name,
+ which is what should be used to refer to the origin across systems, is
+ free-form <type>text</type>. It should be used in a way that makes conflicts
+ between replication origins created by different replication solutions
+ unlikely; e.g., by prefixing the replication solution's name to it.
+ The ID is used only to avoid having to store the long version
+ in situations where space efficiency is important. It should never be shared
+ across systems.
+ </para>
+
+ <para>
+ Replication origins can be created using the function
+ <link linkend="pg-replication-origin-create"><function>pg_replication_origin_create()</function></link>;
+ dropped using
+ <link linkend="pg-replication-origin-drop"><function>pg_replication_origin_drop()</function></link>;
+ and seen in the
+ <link linkend="catalog-pg-replication-origin"><structname>pg_replication_origin</structname></link>
+ system catalog.
+ </para>
+
+ <para>
+ One nontrivial part of building a replication solution is to keep track of
+ replay progress in a safe manner. When the applying process, or the whole
+ cluster, dies, it needs to be possible to find out up to where data has
+ successfully been replicated. Naive solutions to this, such as updating a
+ row in a table for every replayed transaction, have problems like run-time
+ overhead and database bloat.
+ </para>
+
+ <para>
+ Using the replication origin infrastructure a session can be
+ marked as replaying from a remote node (using the
+ <link linkend="pg-replication-origin-session-setup"><function>pg_replication_origin_session_setup()</function></link>
+ function). Additionally the <acronym>LSN</acronym> and commit
+ time stamp of every source transaction can be configured on a per
+ transaction basis using
+ <link linkend="pg-replication-origin-xact-setup"><function>pg_replication_origin_xact_setup()</function></link>.
+ If that's done replication progress will persist in a crash safe
+ manner. Replay progress for all replication origins can be seen in the
+ <link linkend="view-pg-replication-origin-status">
+ <structname>pg_replication_origin_status</structname>
+ </link> view. An individual origin's progress, e.g., when resuming
+ replication, can be acquired using
+ <link linkend="pg-replication-origin-progress"><function>pg_replication_origin_progress()</function></link>
+ for any origin or
+ <link linkend="pg-replication-origin-session-progress"><function>pg_replication_origin_session_progress()</function></link>
+ for the origin configured in the current session.
+ </para>
+
+ <para>
+ In replication topologies more complex than replication from exactly one
+ system to one other system, another problem can be that it is hard to avoid
+ replicating replayed rows again. That can lead both to cycles in the
+ replication and inefficiencies. Replication origins provide an optional
+ mechanism to recognize and prevent that. When configured using the functions
+ referenced in the previous paragraph, every change and transaction passed to
+ output plugin callbacks (see <xref linkend="logicaldecoding-output-plugin"/>)
+ generated by the session is tagged with the replication origin of the
+ generating session. This allows treating them differently in the output
+ plugin, e.g., ignoring all but locally-originating rows. Additionally
+ the <link linkend="logicaldecoding-output-plugin-filter-origin">
+ <function>filter_by_origin_cb</function></link> callback can be used
+ to filter the logical decoding change stream based on the
+ source. While less flexible, filtering via that callback is
+ considerably more efficient than doing it in the output plugin.
+ </para>
+</chapter>
diff --git a/doc/src/sgml/rowtypes.sgml b/doc/src/sgml/rowtypes.sgml
new file mode 100644
index 0000000..417ccb0
--- /dev/null
+++ b/doc/src/sgml/rowtypes.sgml
@@ -0,0 +1,540 @@
+<!-- doc/src/sgml/rowtypes.sgml -->
+
+<sect1 id="rowtypes">
+ <title>Composite Types</title>
+
+ <indexterm>
+ <primary>composite type</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>row type</primary>
+ </indexterm>
+
+ <para>
+ A <firstterm>composite type</firstterm> represents the structure of a row or record;
+ it is essentially just a list of field names and their data types.
+ <productname>PostgreSQL</productname> allows composite types to be
+ used in many of the same ways that simple types can be used. For example, a
+ column of a table can be declared to be of a composite type.
+ </para>
+
+ <sect2 id="rowtypes-declaring">
+ <title>Declaration of Composite Types</title>
+
+ <para>
+ Here are two simple examples of defining composite types:
+<programlisting>
+CREATE TYPE complex AS (
+ r double precision,
+ i double precision
+);
+
+CREATE TYPE inventory_item AS (
+ name text,
+ supplier_id integer,
+ price numeric
+);
+</programlisting>
+ The syntax is comparable to <command>CREATE TABLE</command>, except that only
+ field names and types can be specified; no constraints (such as <literal>NOT
+ NULL</literal>) can presently be included. Note that the <literal>AS</literal> keyword
+ is essential; without it, the system will think a different kind
+ of <command>CREATE TYPE</command> command is meant, and you will get odd syntax
+ errors.
+ </para>
+
+ <para>
+ Having defined the types, we can use them to create tables:
+
+<programlisting>
+CREATE TABLE on_hand (
+ item inventory_item,
+ count integer
+);
+
+INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
+</programlisting>
+
+ or functions:
+
+<programlisting>
+CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric
+AS 'SELECT $1.price * $2' LANGUAGE SQL;
+
+SELECT price_extension(item, 10) FROM on_hand;
+</programlisting>
+
+ </para>
+
+ <para>
+ Whenever you create a table, a composite type is also automatically
+ created, with the same name as the table, to represent the table's
+ row type. For example, had we said:
+<programlisting>
+CREATE TABLE inventory_item (
+ name text,
+ supplier_id integer REFERENCES suppliers,
+ price numeric CHECK (price &gt; 0)
+);
+</programlisting>
+ then the same <literal>inventory_item</literal> composite type shown above would
+ come into being as a
+ byproduct, and could be used just as above. Note however an important
+ restriction of the current implementation: since no constraints are
+ associated with a composite type, the constraints shown in the table
+ definition <emphasis>do not apply</emphasis> to values of the composite type
+ outside the table. (To work around this, create a
+ <glossterm linkend="glossary-domain">domain</glossterm> over the composite
+ type, and apply the desired constraints as <literal>CHECK</literal>
+ constraints of the domain.)
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Constructing Composite Values</title>
+
+ <indexterm>
+ <primary>composite type</primary>
+ <secondary>constant</secondary>
+ </indexterm>
+
+ <para>
+ To write a composite value as a literal constant, enclose the field
+ values within parentheses and separate them by commas. You can put double
+ quotes around any field value, and must do so if it contains commas or
+ parentheses. (More details appear <link
+ linkend="rowtypes-io-syntax">below</link>.) Thus, the general format of
+ a composite constant is the following:
+<synopsis>
+'( <replaceable>val1</replaceable> , <replaceable>val2</replaceable> , ... )'
+</synopsis>
+ An example is:
+<programlisting>
+'("fuzzy dice",42,1.99)'
+</programlisting>
+ which would be a valid value of the <literal>inventory_item</literal> type
+ defined above. To make a field be NULL, write no characters at all
+ in its position in the list. For example, this constant specifies
+ a NULL third field:
+<programlisting>
+'("fuzzy dice",42,)'
+</programlisting>
+ If you want an empty string rather than NULL, write double quotes:
+<programlisting>
+'("",42,)'
+</programlisting>
+ Here the first field is a non-NULL empty string, the third is NULL.
+ </para>
+
+ <para>
+ (These constants are actually only a special case of
+ the generic type constants discussed in <xref
+ linkend="sql-syntax-constants-generic"/>. The constant is initially
+ treated as a string and passed to the composite-type input conversion
+ routine. An explicit type specification might be necessary to tell
+ which type to convert the constant to.)
+ </para>
+
+ <para>
+ The <literal>ROW</literal> expression syntax can also be used to
+ construct composite values. In most cases this is considerably
+ simpler to use than the string-literal syntax since you don't have
+ to worry about multiple layers of quoting. We already used this
+ method above:
+<programlisting>
+ROW('fuzzy dice', 42, 1.99)
+ROW('', 42, NULL)
+</programlisting>
+ The ROW keyword is actually optional as long as you have more than one
+ field in the expression, so these can be simplified to:
+<programlisting>
+('fuzzy dice', 42, 1.99)
+('', 42, NULL)
+</programlisting>
+ The <literal>ROW</literal> expression syntax is discussed in more detail in <xref
+ linkend="sql-syntax-row-constructors"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="rowtypes-accessing">
+ <title>Accessing Composite Types</title>
+
+ <para>
+ To access a field of a composite column, one writes a dot and the field
+ name, much like selecting a field from a table name. In fact, it's so
+ much like selecting from a table name that you often have to use parentheses
+ to keep from confusing the parser. For example, you might try to select
+ some subfields from our <literal>on_hand</literal> example table with something
+ like:
+
+<programlisting>
+SELECT item.name FROM on_hand WHERE item.price &gt; 9.99;
+</programlisting>
+
+ This will not work since the name <literal>item</literal> is taken to be a table
+ name, not a column name of <literal>on_hand</literal>, per SQL syntax rules.
+ You must write it like this:
+
+<programlisting>
+SELECT (item).name FROM on_hand WHERE (item).price &gt; 9.99;
+</programlisting>
+
+ or if you need to use the table name as well (for instance in a multitable
+ query), like this:
+
+<programlisting>
+SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price &gt; 9.99;
+</programlisting>
+
+ Now the parenthesized object is correctly interpreted as a reference to
+ the <literal>item</literal> column, and then the subfield can be selected from it.
+ </para>
+
+ <para>
+ Similar syntactic issues apply whenever you select a field from a composite
+ value. For instance, to select just one field from the result of a function
+ that returns a composite value, you'd need to write something like:
+
+<programlisting>
+SELECT (my_func(...)).field FROM ...
+</programlisting>
+
+ Without the extra parentheses, this will generate a syntax error.
+ </para>
+
+ <para>
+ The special field name <literal>*</literal> means <quote>all fields</quote>, as
+ further explained in <xref linkend="rowtypes-usage"/>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Modifying Composite Types</title>
+
+ <para>
+ Here are some examples of the proper syntax for inserting and updating
+ composite columns.
+ First, inserting or updating a whole column:
+
+<programlisting>
+INSERT INTO mytab (complex_col) VALUES((1.1,2.2));
+
+UPDATE mytab SET complex_col = ROW(1.1,2.2) WHERE ...;
+</programlisting>
+
+ The first example omits <literal>ROW</literal>, the second uses it; we
+ could have done it either way.
+ </para>
+
+ <para>
+ We can update an individual subfield of a composite column:
+
+<programlisting>
+UPDATE mytab SET complex_col.r = (complex_col).r + 1 WHERE ...;
+</programlisting>
+
+ Notice here that we don't need to (and indeed cannot)
+ put parentheses around the column name appearing just after
+ <literal>SET</literal>, but we do need parentheses when referencing the same
+ column in the expression to the right of the equal sign.
+ </para>
+
+ <para>
+ And we can specify subfields as targets for <command>INSERT</command>, too:
+
+<programlisting>
+INSERT INTO mytab (complex_col.r, complex_col.i) VALUES(1.1, 2.2);
+</programlisting>
+
+ Had we not supplied values for all the subfields of the column, the
+ remaining subfields would have been filled with null values.
+ </para>
+ </sect2>
+
+ <sect2 id="rowtypes-usage">
+ <title>Using Composite Types in Queries</title>
+
+ <para>
+ There are various special syntax rules and behaviors associated with
+ composite types in queries. These rules provide useful shortcuts,
+ but can be confusing if you don't know the logic behind them.
+ </para>
+
+ <para>
+ In <productname>PostgreSQL</productname>, a reference to a table name (or alias)
+ in a query is effectively a reference to the composite value of the
+ table's current row. For example, if we had a table
+ <structname>inventory_item</structname> as shown
+ <link linkend="rowtypes-declaring">above</link>, we could write:
+<programlisting>
+SELECT c FROM inventory_item c;
+</programlisting>
+ This query produces a single composite-valued column, so we might get
+ output like:
+<programlisting>
+ c
+------------------------
+ ("fuzzy dice",42,1.99)
+(1 row)
+</programlisting>
+ Note however that simple names are matched to column names before table
+ names, so this example works only because there is no column
+ named <structfield>c</structfield> in the query's tables.
+ </para>
+
+ <para>
+ The ordinary qualified-column-name
+ syntax <replaceable>table_name</replaceable><literal>.</literal><replaceable>column_name</replaceable>
+ can be understood as applying <link linkend="field-selection">field
+ selection</link> to the composite value of the table's current row.
+ (For efficiency reasons, it's not actually implemented that way.)
+ </para>
+
+ <para>
+ When we write
+<programlisting>
+SELECT c.* FROM inventory_item c;
+</programlisting>
+ then, according to the SQL standard, we should get the contents of the
+ table expanded into separate columns:
+<programlisting>
+ name | supplier_id | price
+------------+-------------+-------
+ fuzzy dice | 42 | 1.99
+(1 row)
+</programlisting>
+ as if the query were
+<programlisting>
+SELECT c.name, c.supplier_id, c.price FROM inventory_item c;
+</programlisting>
+ <productname>PostgreSQL</productname> will apply this expansion behavior to
+ any composite-valued expression, although as shown <link
+ linkend="rowtypes-accessing">above</link>, you need to write parentheses
+ around the value that <literal>.*</literal> is applied to whenever it's not a
+ simple table name. For example, if <function>myfunc()</function> is a function
+ returning a composite type with columns <structfield>a</structfield>,
+ <structfield>b</structfield>, and <structfield>c</structfield>, then these two queries have the
+ same result:
+<programlisting>
+SELECT (myfunc(x)).* FROM some_table;
+SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table;
+</programlisting>
+ </para>
+
+ <tip>
+ <para>
+ <productname>PostgreSQL</productname> handles column expansion by
+ actually transforming the first form into the second. So, in this
+ example, <function>myfunc()</function> would get invoked three times per row
+ with either syntax. If it's an expensive function you may wish to
+ avoid that, which you can do with a query like:
+<programlisting>
+SELECT m.* FROM some_table, LATERAL myfunc(x) AS m;
+</programlisting>
+ Placing the function in
+ a <literal>LATERAL</literal> <literal>FROM</literal> item keeps it from
+ being invoked more than once per row. <literal>m.*</literal> is still
+ expanded into <literal>m.a, m.b, m.c</literal>, but now those variables
+ are just references to the output of the <literal>FROM</literal> item.
+ (The <literal>LATERAL</literal> keyword is optional here, but we show it
+ to clarify that the function is getting <structfield>x</structfield>
+ from <structname>some_table</structname>.)
+ </para>
+ </tip>
+
+ <para>
+ The <replaceable>composite_value</replaceable><literal>.*</literal> syntax results in
+ column expansion of this kind when it appears at the top level of
+ a <link linkend="queries-select-lists"><command>SELECT</command> output
+ list</link>, a <link linkend="dml-returning"><literal>RETURNING</literal>
+ list</link> in <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>,
+ a <link linkend="queries-values"><literal>VALUES</literal> clause</link>, or
+ a <link linkend="sql-syntax-row-constructors">row constructor</link>.
+ In all other contexts (including when nested inside one of those
+ constructs), attaching <literal>.*</literal> to a composite value does not
+ change the value, since it means <quote>all columns</quote> and so the
+ same composite value is produced again. For example,
+ if <function>somefunc()</function> accepts a composite-valued argument,
+ these queries are the same:
+
+<programlisting>
+SELECT somefunc(c.*) FROM inventory_item c;
+SELECT somefunc(c) FROM inventory_item c;
+</programlisting>
+
+ In both cases, the current row of <structname>inventory_item</structname> is
+ passed to the function as a single composite-valued argument.
+ Even though <literal>.*</literal> does nothing in such cases, using it is good
+ style, since it makes clear that a composite value is intended. In
+ particular, the parser will consider <literal>c</literal> in <literal>c.*</literal> to
+ refer to a table name or alias, not to a column name, so that there is
+ no ambiguity; whereas without <literal>.*</literal>, it is not clear
+ whether <literal>c</literal> means a table name or a column name, and in fact
+ the column-name interpretation will be preferred if there is a column
+ named <literal>c</literal>.
+ </para>
+
+ <para>
+ Another example demonstrating these concepts is that all these queries
+ mean the same thing:
+<programlisting>
+SELECT * FROM inventory_item c ORDER BY c;
+SELECT * FROM inventory_item c ORDER BY c.*;
+SELECT * FROM inventory_item c ORDER BY ROW(c.*);
+</programlisting>
+ All of these <literal>ORDER BY</literal> clauses specify the row's composite
+ value, resulting in sorting the rows according to the rules described
+ in <xref linkend="composite-type-comparison"/>. However,
+ if <structname>inventory_item</structname> contained a column
+ named <structfield>c</structfield>, the first case would be different from the
+ others, as it would mean to sort by that column only. Given the column
+ names previously shown, these queries are also equivalent to those above:
+<programlisting>
+SELECT * FROM inventory_item c ORDER BY ROW(c.name, c.supplier_id, c.price);
+SELECT * FROM inventory_item c ORDER BY (c.name, c.supplier_id, c.price);
+</programlisting>
+ (The last case uses a row constructor with the key word <literal>ROW</literal>
+ omitted.)
+ </para>
+
+ <para>
+ Another special syntactical behavior associated with composite values is
+ that we can use <firstterm>functional notation</firstterm> for extracting a field
+ of a composite value. The simple way to explain this is that
+ the notations <literal><replaceable>field</replaceable>(<replaceable>table</replaceable>)</literal>
+ and <literal><replaceable>table</replaceable>.<replaceable>field</replaceable></literal>
+ are interchangeable. For example, these queries are equivalent:
+
+<programlisting>
+SELECT c.name FROM inventory_item c WHERE c.price &gt; 1000;
+SELECT name(c) FROM inventory_item c WHERE price(c) &gt; 1000;
+</programlisting>
+
+ Moreover, if we have a function that accepts a single argument of a
+ composite type, we can call it with either notation. These queries are
+ all equivalent:
+
+<programlisting>
+SELECT somefunc(c) FROM inventory_item c;
+SELECT somefunc(c.*) FROM inventory_item c;
+SELECT c.somefunc FROM inventory_item c;
+</programlisting>
+ </para>
+
+ <para>
+ This equivalence between functional notation and field notation
+ makes it possible to use functions on composite types to implement
+ <quote>computed fields</quote>.
+ <indexterm>
+ <primary>computed field</primary>
+ </indexterm>
+ <indexterm>
+ <primary>field</primary>
+ <secondary>computed</secondary>
+ </indexterm>
+ An application using the last query above wouldn't need to be directly
+ aware that <literal>somefunc</literal> isn't a real column of the table.
+ </para>
+
+ <tip>
+ <para>
+ Because of this behavior, it's unwise to give a function that takes a
+ single composite-type argument the same name as any of the fields of
+ that composite type. If there is ambiguity, the field-name
+ interpretation will be chosen if field-name syntax is used, while the
+ function will be chosen if function-call syntax is used. However,
+ <productname>PostgreSQL</productname> versions before 11 always chose the
+ field-name interpretation, unless the syntax of the call required it to
+ be a function call. One way to force the function interpretation in
+ older versions is to schema-qualify the function name, that is, write
+ <literal><replaceable>schema</replaceable>.<replaceable>func</replaceable>(<replaceable>compositevalue</replaceable>)</literal>.
+ </para>
+ </tip>
+ </sect2>
+
+ <sect2 id="rowtypes-io-syntax">
+ <title>Composite Type Input and Output Syntax</title>
+
+ <para>
+ The external text representation of a composite value consists of items that
+ are interpreted according to the I/O conversion rules for the individual
+ field types, plus decoration that indicates the composite structure.
+ The decoration consists of parentheses (<literal>(</literal> and <literal>)</literal>)
+ around the whole value, plus commas (<literal>,</literal>) between adjacent
+ items. Whitespace outside the parentheses is ignored, but within the
+ parentheses it is considered part of the field value, and might or might not be
+ significant depending on the input conversion rules for the field data type.
+ For example, in:
+<programlisting>
+'( 42)'
+</programlisting>
+ the whitespace will be ignored if the field type is integer, but not if
+ it is text.
+ </para>
+
+ <para>
+ As shown previously, when writing a composite value you can write double
+ quotes around any individual field value.
+ You <emphasis>must</emphasis> do so if the field value would otherwise
+ confuse the composite-value parser. In particular, fields containing
+ parentheses, commas, double quotes, or backslashes must be double-quoted.
+ To put a double quote or backslash in a quoted composite field value,
+ precede it with a backslash. (Also, a pair of double quotes within a
+ double-quoted field value is taken to represent a double quote character,
+ analogously to the rules for single quotes in SQL literal strings.)
+ Alternatively, you can avoid quoting and use backslash-escaping to
+ protect all data characters
+ that would otherwise be taken as composite syntax.
+ </para>
+
+ <para>
+ A completely empty field value (no characters at all between the commas
+ or parentheses) represents a NULL. To write a value that is an empty
+ string rather than NULL, write <literal>""</literal>.
+ </para>
+
+ <para>
+ The composite output routine will put double quotes around field values
+ if they are empty strings or contain parentheses, commas,
+ double quotes, backslashes, or white space. (Doing so for white space
+ is not essential, but aids legibility.) Double quotes and backslashes
+ embedded in field values will be doubled.
+ </para>
+
+ <note>
+ <para>
+ Remember that what you write in an SQL command will first be interpreted
+ as a string literal, and then as a composite. This doubles the number of
+ backslashes you need (assuming escape string syntax is used).
+ For example, to insert a <type>text</type> field
+ containing a double quote and a backslash in a composite
+ value, you'd need to write:
+<programlisting>
+INSERT ... VALUES ('("\"\\")');
+</programlisting>
+ The string-literal processor removes one level of backslashes, so that
+ what arrives at the composite-value parser looks like
+ <literal>("\"\\")</literal>. In turn, the string
+ fed to the <type>text</type> data type's input routine
+ becomes <literal>"\</literal>. (If we were working
+ with a data type whose input routine also treated backslashes specially,
+ <type>bytea</type> for example, we might need as many as eight backslashes
+ in the command to get one backslash into the stored composite field.)
+ Dollar quoting (see <xref linkend="sql-syntax-dollar-quoting"/>) can be
+ used to avoid the need to double backslashes.
+ </para>
+ </note>
+
+ <tip>
+ <para>
+ The <literal>ROW</literal> constructor syntax is usually easier to work with
+ than the composite-literal syntax when writing composite values in SQL
+ commands.
+ In <literal>ROW</literal>, individual field values are written the same way
+ they would be written when not members of a composite.
+ </para>
+ </tip>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml
new file mode 100644
index 0000000..be3d17c
--- /dev/null
+++ b/doc/src/sgml/rules.sgml
@@ -0,0 +1,2434 @@
+<!-- doc/src/sgml/rules.sgml -->
+
+<chapter id="rules">
+<title>The Rule System</title>
+
+ <indexterm zone="rules">
+ <primary>rule</primary>
+ </indexterm>
+
+<para>
+ This chapter discusses the rule system in
+ <productname>PostgreSQL</productname>. Production rule systems
+ are conceptually simple, but there are many subtle points
+ involved in actually using them.
+</para>
+
+<para>
+ Some other database systems define active database rules, which
+ are usually stored procedures and triggers. In
+ <productname>PostgreSQL</productname>, these can be implemented
+ using functions and triggers as well.
+</para>
+
+<para>
+ The rule system (more precisely speaking, the query rewrite rule
+ system) is totally different from stored procedures and triggers.
+ It modifies queries to take rules into consideration, and then
+ passes the modified query to the query planner for planning and
+ execution. It is very powerful, and can be used for many things
+ such as query language procedures, views, and versions. The
+ theoretical foundations and the power of this rule system are
+ also discussed in <xref linkend="ston90b"/> and <xref
+ linkend="ong90"/>.
+</para>
+
+<sect1 id="querytree">
+<title>The Query Tree</title>
+
+<indexterm zone="querytree">
+ <primary>query tree</primary>
+</indexterm>
+
+<para>
+ To understand how the rule system works it is necessary to know
+ when it is invoked and what its input and results are.
+</para>
+
+<para>
+ The rule system is located between the parser and the planner.
+ It takes the output of the parser, one query tree, and the user-defined
+ rewrite rules, which are also
+ query trees with some extra information, and creates zero or more
+ query trees as result. So its input and output are always things
+ the parser itself could have produced and thus, anything it sees
+ is basically representable as an <acronym>SQL</acronym> statement.
+</para>
+
+<para>
+ Now what is a query tree? It is an internal representation of an
+ <acronym>SQL</acronym> statement where the single parts that it is
+ built from are stored separately. These query trees can be shown
+ in the server log if you set the configuration parameters
+ <varname>debug_print_parse</varname>,
+ <varname>debug_print_rewritten</varname>, or
+ <varname>debug_print_plan</varname>. The rule actions are also
+ stored as query trees, in the system catalog
+ <structname>pg_rewrite</structname>. They are not formatted like
+ the log output, but they contain exactly the same information.
+</para>
+
+<para>
+ Reading a raw query tree requires some experience. But since
+ <acronym>SQL</acronym> representations of query trees are
+ sufficient to understand the rule system, this chapter will not
+ teach how to read them.
+</para>
+
+<para>
+ When reading the <acronym>SQL</acronym> representations of the
+ query trees in this chapter it is necessary to be able to identify
+ the parts the statement is broken into when it is in the query tree
+ structure. The parts of a query tree are
+
+<variablelist>
+ <varlistentry>
+ <term>
+ the command type
+ </term>
+ <listitem>
+ <para>
+ This is a simple value telling which command
+ (<command>SELECT</command>, <command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>) produced
+ the query tree.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ the range table
+ <indexterm><primary>range table</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The range table is a list of relations that are used in the query.
+ In a <command>SELECT</command> statement these are the relations given after
+ the <literal>FROM</literal> key word.
+ </para>
+
+ <para>
+ Every range table entry identifies a table or view and tells
+ by which name it is called in the other parts of the query.
+ In the query tree, the range table entries are referenced by
+ number rather than by name, so here it doesn't matter if there
+ are duplicate names as it would in an <acronym>SQL</acronym>
+ statement. This can happen after the range tables of rules
+ have been merged in. The examples in this chapter will not have
+ this situation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ the result relation
+ </term>
+ <listitem>
+ <para>
+ This is an index into the range table that identifies the
+ relation where the results of the query go.
+ </para>
+
+ <para>
+ <command>SELECT</command> queries don't have a result
+ relation. (The special case of <command>SELECT INTO</command> is
+ mostly identical to <command>CREATE TABLE</command> followed by
+ <literal>INSERT ... SELECT</literal>, and is not discussed
+ separately here.)
+ </para>
+
+ <para>
+ For <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> commands, the result relation is the table
+ (or view!) where the changes are to take effect.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ the target list
+ <indexterm><primary>target list</primary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The target list is a list of expressions that define the
+ result of the query. In the case of a
+ <command>SELECT</command>, these expressions are the ones that
+ build the final output of the query. They correspond to the
+ expressions between the key words <command>SELECT</command>
+ and <command>FROM</command>. (<literal>*</literal> is just an
+ abbreviation for all the column names of a relation. It is
+ expanded by the parser into the individual columns, so the
+ rule system never sees it.)
+ </para>
+
+ <para>
+ <command>DELETE</command> commands don't need a normal target list
+ because they don't produce any result. Instead, the planner
+ adds a special <acronym>CTID</acronym> entry to the empty target list,
+ to allow the executor to find the row to be deleted.
+ (<acronym>CTID</acronym> is added when the result relation is an ordinary
+ table. If it is a view, a whole-row variable is added instead, by
+ the rule system, as described in <xref linkend="rules-views-update"/>.)
+ </para>
+
+ <para>
+ For <command>INSERT</command> commands, the target list describes
+ the new rows that should go into the result relation. It consists of the
+ expressions in the <literal>VALUES</literal> clause or the ones from the
+ <command>SELECT</command> clause in <literal>INSERT
+ ... SELECT</literal>. The first step of the rewrite process adds
+ target list entries for any columns that were not assigned to by
+ the original command but have defaults. Any remaining columns (with
+ neither a given value nor a default) will be filled in by the
+ planner with a constant null expression.
+ </para>
+
+ <para>
+ For <command>UPDATE</command> commands, the target list
+ describes the new rows that should replace the old ones. In the
+ rule system, it contains just the expressions from the <literal>SET
+ column = expression</literal> part of the command. The planner will
+ handle missing columns by inserting expressions that copy the values
+ from the old row into the new one. Just as for <command>DELETE</command>,
+ a <acronym>CTID</acronym> or whole-row variable is added so that
+ the executor can identify the old row to be updated.
+ </para>
+
+ <para>
+ Every entry in the target list contains an expression that can
+ be a constant value, a variable pointing to a column of one
+ of the relations in the range table, a parameter, or an expression
+ tree made of function calls, constants, variables, operators, etc.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ the qualification
+ </term>
+ <listitem>
+ <para>
+ The query's qualification is an expression much like one of
+ those contained in the target list entries. The result value of
+ this expression is a Boolean that tells whether the operation
+ (<command>INSERT</command>, <command>UPDATE</command>,
+ <command>DELETE</command>, or <command>SELECT</command>) for the
+ final result row should be executed or not. It corresponds to the <literal>WHERE</literal> clause
+ of an <acronym>SQL</acronym> statement.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ the join tree
+ </term>
+ <listitem>
+ <para>
+ The query's join tree shows the structure of the <literal>FROM</literal> clause.
+ For a simple query like <literal>SELECT ... FROM a, b, c</literal>, the join tree is just
+ a list of the <literal>FROM</literal> items, because we are allowed to join them in
+ any order. But when <literal>JOIN</literal> expressions, particularly outer joins,
+ are used, we have to join in the order shown by the joins.
+ In that case, the join tree shows the structure of the <literal>JOIN</literal> expressions. The
+ restrictions associated with particular <literal>JOIN</literal> clauses (from <literal>ON</literal> or
+ <literal>USING</literal> expressions) are stored as qualification expressions attached
+ to those join-tree nodes. It turns out to be convenient to store
+ the top-level <literal>WHERE</literal> expression as a qualification attached to the
+ top-level join-tree item, too. So really the join tree represents
+ both the <literal>FROM</literal> and <literal>WHERE</literal> clauses of a <command>SELECT</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ the others
+ </term>
+ <listitem>
+ <para>
+ The other parts of the query tree like the <literal>ORDER BY</literal>
+ clause aren't of interest here. The rule system
+ substitutes some entries there while applying rules, but that
+ doesn't have much to do with the fundamentals of the rule
+ system.
+ </para>
+ </listitem>
+ </varlistentry>
+
+</variablelist>
+</para>
+</sect1>
+
+<sect1 id="rules-views">
+<title>Views and the Rule System</title>
+
+<indexterm zone="rules-views">
+ <primary>rule</primary>
+ <secondary>and views</secondary>
+</indexterm>
+
+<indexterm zone="rules-views">
+ <primary>view</primary>
+ <secondary>implementation through rules</secondary>
+</indexterm>
+
+<para>
+ Views in <productname>PostgreSQL</productname> are implemented
+ using the rule system. In fact, there is essentially no difference
+ between:
+
+<programlisting>
+CREATE VIEW myview AS SELECT * FROM mytab;
+</programlisting>
+
+ compared against the two commands:
+
+<programlisting>
+CREATE TABLE myview (<replaceable>same column list as mytab</replaceable>);
+CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD
+ SELECT * FROM mytab;
+</programlisting>
+
+ because this is exactly what the <command>CREATE VIEW</command>
+ command does internally. This has some side effects. One of them
+ is that the information about a view in the
+ <productname>PostgreSQL</productname> system catalogs is exactly
+ the same as it is for a table. So for the parser, there is
+ absolutely no difference between a table and a view. They are the
+ same thing: relations.
+</para>
+
+<sect2 id="rules-select">
+<title>How <command>SELECT</command> Rules Work</title>
+
+<indexterm zone="rules-select">
+ <primary>rule</primary>
+ <secondary sortas="SELECT">for SELECT</secondary>
+</indexterm>
+
+<para>
+ Rules <literal>ON SELECT</literal> are applied to all queries as the last step, even
+ if the command given is an <command>INSERT</command>,
+ <command>UPDATE</command> or <command>DELETE</command>. And they
+ have different semantics from rules on the other command types in that they modify the
+ query tree in place instead of creating a new one. So
+ <command>SELECT</command> rules are described first.
+</para>
+
+<para>
+ Currently, there can be only one action in an <literal>ON SELECT</literal> rule, and it must
+ be an unconditional <command>SELECT</command> action that is <literal>INSTEAD</literal>. This restriction was
+ required to make rules safe enough to open them for ordinary users, and
+ it restricts <literal>ON SELECT</literal> rules to act like views.
+</para>
+
+<para>
+ The examples for this chapter are two join views that do some
+ calculations and some more views using them in turn. One of the
+ two first views is customized later by adding rules for
+ <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> operations so that the final result will
+ be a view that behaves like a real table with some magic
+ functionality. This is not such a simple example to start from and
+ this makes things harder to get into. But it's better to have one
+ example that covers all the points discussed step by step rather
+ than having many different ones that might mix up in mind.
+</para>
+
+<para>
+ The real tables we need in the first two rule system descriptions
+ are these:
+
+<programlisting>
+CREATE TABLE shoe_data (
+ shoename text, -- primary key
+ sh_avail integer, -- available number of pairs
+ slcolor text, -- preferred shoelace color
+ slminlen real, -- minimum shoelace length
+ slmaxlen real, -- maximum shoelace length
+ slunit text -- length unit
+);
+
+CREATE TABLE shoelace_data (
+ sl_name text, -- primary key
+ sl_avail integer, -- available number of pairs
+ sl_color text, -- shoelace color
+ sl_len real, -- shoelace length
+ sl_unit text -- length unit
+);
+
+CREATE TABLE unit (
+ un_name text, -- primary key
+ un_fact real -- factor to transform to cm
+);
+</programlisting>
+
+ As you can see, they represent shoe-store data.
+</para>
+
+<para>
+ The views are created as:
+
+<programlisting>
+CREATE VIEW shoe AS
+ SELECT sh.shoename,
+ sh.sh_avail,
+ sh.slcolor,
+ sh.slminlen,
+ sh.slminlen * un.un_fact AS slminlen_cm,
+ sh.slmaxlen,
+ sh.slmaxlen * un.un_fact AS slmaxlen_cm,
+ sh.slunit
+ FROM shoe_data sh, unit un
+ WHERE sh.slunit = un.un_name;
+
+CREATE VIEW shoelace AS
+ SELECT s.sl_name,
+ s.sl_avail,
+ s.sl_color,
+ s.sl_len,
+ s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name;
+
+CREATE VIEW shoe_ready AS
+ SELECT rsh.shoename,
+ rsh.sh_avail,
+ rsl.sl_name,
+ rsl.sl_avail,
+ least(rsh.sh_avail, rsl.sl_avail) AS total_avail
+ FROM shoe rsh, shoelace rsl
+ WHERE rsl.sl_color = rsh.slcolor
+ AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
+ AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm;
+</programlisting>
+
+ The <command>CREATE VIEW</command> command for the
+ <literal>shoelace</literal> view (which is the simplest one we
+ have) will create a relation <literal>shoelace</literal> and an entry in
+ <structname>pg_rewrite</structname> that tells that there is a
+ rewrite rule that must be applied whenever the relation <literal>shoelace</literal>
+ is referenced in a query's range table. The rule has no rule
+ qualification (discussed later, with the non-<command>SELECT</command> rules, since
+ <command>SELECT</command> rules currently cannot have them) and it is <literal>INSTEAD</literal>. Note
+ that rule qualifications are not the same as query qualifications.
+ The action of our rule has a query qualification.
+ The action of the rule is one query tree that is a copy of the
+ <command>SELECT</command> statement in the view creation command.
+</para>
+
+ <note>
+ <para>
+ The two extra range
+ table entries for <literal>NEW</literal> and <literal>OLD</literal> that you can see in
+ the <structname>pg_rewrite</structname> entry aren't of interest
+ for <command>SELECT</command> rules.
+ </para>
+ </note>
+
+<para>
+ Now we populate <literal>unit</literal>, <literal>shoe_data</literal>
+ and <literal>shoelace_data</literal> and run a simple query on a view:
+
+<programlisting>
+INSERT INTO unit VALUES ('cm', 1.0);
+INSERT INTO unit VALUES ('m', 100.0);
+INSERT INTO unit VALUES ('inch', 2.54);
+
+INSERT INTO shoe_data VALUES ('sh1', 2, 'black', 70.0, 90.0, 'cm');
+INSERT INTO shoe_data VALUES ('sh2', 0, 'black', 30.0, 40.0, 'inch');
+INSERT INTO shoe_data VALUES ('sh3', 4, 'brown', 50.0, 65.0, 'cm');
+INSERT INTO shoe_data VALUES ('sh4', 3, 'brown', 40.0, 50.0, 'inch');
+
+INSERT INTO shoelace_data VALUES ('sl1', 5, 'black', 80.0, 'cm');
+INSERT INTO shoelace_data VALUES ('sl2', 6, 'black', 100.0, 'cm');
+INSERT INTO shoelace_data VALUES ('sl3', 0, 'black', 35.0 , 'inch');
+INSERT INTO shoelace_data VALUES ('sl4', 8, 'black', 40.0 , 'inch');
+INSERT INTO shoelace_data VALUES ('sl5', 4, 'brown', 1.0 , 'm');
+INSERT INTO shoelace_data VALUES ('sl6', 0, 'brown', 0.9 , 'm');
+INSERT INTO shoelace_data VALUES ('sl7', 7, 'brown', 60 , 'cm');
+INSERT INTO shoelace_data VALUES ('sl8', 1, 'brown', 40 , 'inch');
+
+SELECT * FROM shoelace;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+-----------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 7 | brown | 60 | cm | 60
+ sl3 | 0 | black | 35 | inch | 88.9
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl8 | 1 | brown | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 0 | brown | 0.9 | m | 90
+(8 rows)
+</programlisting>
+ </para>
+
+ <para>
+ This is the simplest <command>SELECT</command> you can do on our
+ views, so we take this opportunity to explain the basics of view
+ rules. The <literal>SELECT * FROM shoelace</literal> was
+ interpreted by the parser and produced the query tree:
+
+<programlisting>
+SELECT shoelace.sl_name, shoelace.sl_avail,
+ shoelace.sl_color, shoelace.sl_len,
+ shoelace.sl_unit, shoelace.sl_len_cm
+ FROM shoelace shoelace;
+</programlisting>
+
+ and this is given to the rule system. The rule system walks through the
+ range table and checks if there are rules
+ for any relation. When processing the range table entry for
+ <literal>shoelace</literal> (the only one up to now) it finds the
+ <literal>_RETURN</literal> rule with the query tree:
+
+<programlisting>
+SELECT s.sl_name, s.sl_avail,
+ s.sl_color, s.sl_len, s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace old, shoelace new,
+ shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name;
+</programlisting>
+</para>
+
+<para>
+ To expand the view, the rewriter simply creates a subquery range-table
+ entry containing the rule's action query tree, and substitutes this
+ range table entry for the original one that referenced the view. The
+ resulting rewritten query tree is almost the same as if you had typed:
+
+<programlisting>
+SELECT shoelace.sl_name, shoelace.sl_avail,
+ shoelace.sl_color, shoelace.sl_len,
+ shoelace.sl_unit, shoelace.sl_len_cm
+ FROM (SELECT s.sl_name,
+ s.sl_avail,
+ s.sl_color,
+ s.sl_len,
+ s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name) shoelace;
+</programlisting>
+
+ There is one difference however: the subquery's range table has two
+ extra entries <literal>shoelace old</literal> and <literal>shoelace new</literal>. These entries don't
+ participate directly in the query, since they aren't referenced by
+ the subquery's join tree or target list. The rewriter uses them
+ to store the access privilege check information that was originally present
+ in the range-table entry that referenced the view. In this way, the
+ executor will still check that the user has proper privileges to access
+ the view, even though there's no direct use of the view in the rewritten
+ query.
+</para>
+
+<para>
+ That was the first rule applied. The rule system will continue checking
+ the remaining range-table entries in the top query (in this example there
+ are no more), and it will recursively check the range-table entries in
+ the added subquery to see if any of them reference views. (But it
+ won't expand <literal>old</literal> or <literal>new</literal> &mdash; otherwise we'd have infinite recursion!)
+ In this example, there are no rewrite rules for <literal>shoelace_data</literal> or <literal>unit</literal>,
+ so rewriting is complete and the above is the final result given to
+ the planner.
+</para>
+
+<para>
+ Now we want to write a query that finds out for which shoes currently in the store
+ we have the matching shoelaces (color and length) and where the
+ total number of exactly matching pairs is greater than or equal to two.
+
+<programlisting>
+SELECT * FROM shoe_ready WHERE total_avail &gt;= 2;
+
+ shoename | sh_avail | sl_name | sl_avail | total_avail
+----------+----------+---------+----------+-------------
+ sh1 | 2 | sl1 | 5 | 2
+ sh3 | 4 | sl7 | 7 | 4
+(2 rows)
+</programlisting>
+</para>
+
+<para>
+ The output of the parser this time is the query tree:
+
+<programlisting>
+SELECT shoe_ready.shoename, shoe_ready.sh_avail,
+ shoe_ready.sl_name, shoe_ready.sl_avail,
+ shoe_ready.total_avail
+ FROM shoe_ready shoe_ready
+ WHERE shoe_ready.total_avail &gt;= 2;
+</programlisting>
+
+ The first rule applied will be the one for the
+ <literal>shoe_ready</literal> view and it results in the
+ query tree:
+
+<programlisting>
+SELECT shoe_ready.shoename, shoe_ready.sh_avail,
+ shoe_ready.sl_name, shoe_ready.sl_avail,
+ shoe_ready.total_avail
+ FROM (SELECT rsh.shoename,
+ rsh.sh_avail,
+ rsl.sl_name,
+ rsl.sl_avail,
+ least(rsh.sh_avail, rsl.sl_avail) AS total_avail
+ FROM shoe rsh, shoelace rsl
+ WHERE rsl.sl_color = rsh.slcolor
+ AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
+ AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm) shoe_ready
+ WHERE shoe_ready.total_avail &gt;= 2;
+</programlisting>
+
+ Similarly, the rules for <literal>shoe</literal> and
+ <literal>shoelace</literal> are substituted into the range table of
+ the subquery, leading to a three-level final query tree:
+
+<programlisting>
+SELECT shoe_ready.shoename, shoe_ready.sh_avail,
+ shoe_ready.sl_name, shoe_ready.sl_avail,
+ shoe_ready.total_avail
+ FROM (SELECT rsh.shoename,
+ rsh.sh_avail,
+ rsl.sl_name,
+ rsl.sl_avail,
+ least(rsh.sh_avail, rsl.sl_avail) AS total_avail
+ FROM (SELECT sh.shoename,
+ sh.sh_avail,
+ sh.slcolor,
+ sh.slminlen,
+ sh.slminlen * un.un_fact AS slminlen_cm,
+ sh.slmaxlen,
+ sh.slmaxlen * un.un_fact AS slmaxlen_cm,
+ sh.slunit
+ FROM shoe_data sh, unit un
+ WHERE sh.slunit = un.un_name) rsh,
+ (SELECT s.sl_name,
+ s.sl_avail,
+ s.sl_color,
+ s.sl_len,
+ s.sl_unit,
+ s.sl_len * u.un_fact AS sl_len_cm
+ FROM shoelace_data s, unit u
+ WHERE s.sl_unit = u.un_name) rsl
+ WHERE rsl.sl_color = rsh.slcolor
+ AND rsl.sl_len_cm &gt;= rsh.slminlen_cm
+ AND rsl.sl_len_cm &lt;= rsh.slmaxlen_cm) shoe_ready
+ WHERE shoe_ready.total_avail &gt; 2;
+</programlisting>
+ </para>
+
+ <para>
+ This might look inefficient, but the planner will collapse this into a
+ single-level query tree by <quote>pulling up</quote> the subqueries,
+ and then it will plan the joins just as if we'd written them out
+ manually. So collapsing the query tree is an optimization that the
+ rewrite system doesn't have to concern itself with.
+ </para>
+</sect2>
+
+<sect2>
+<title>View Rules in Non-<command>SELECT</command> Statements</title>
+
+<para>
+ Two details of the query tree aren't touched in the description of
+ view rules above. These are the command type and the result relation.
+ In fact, the command type is not needed by view rules, but the result
+ relation may affect the way in which the query rewriter works, because
+ special care needs to be taken if the result relation is a view.
+</para>
+
+<para>
+ There are only a few differences between a query tree for a
+ <command>SELECT</command> and one for any other
+ command. Obviously, they have a different command type and for a
+ command other than a <command>SELECT</command>, the result
+ relation points to the range-table entry where the result should
+ go. Everything else is absolutely the same. So having two tables
+ <literal>t1</literal> and <literal>t2</literal> with columns <literal>a</literal> and
+ <literal>b</literal>, the query trees for the two statements:
+
+<programlisting>
+SELECT t2.b FROM t1, t2 WHERE t1.a = t2.a;
+
+UPDATE t1 SET b = t2.b FROM t2 WHERE t1.a = t2.a;
+</programlisting>
+
+ are nearly identical. In particular:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The range tables contain entries for the tables <literal>t1</literal> and <literal>t2</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The target lists contain one variable that points to column
+ <literal>b</literal> of the range table entry for table <literal>t2</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The qualification expressions compare the columns <literal>a</literal> of both
+ range-table entries for equality.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The join trees show a simple join between <literal>t1</literal> and <literal>t2</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The consequence is, that both query trees result in similar
+ execution plans: They are both joins over the two tables. For the
+ <command>UPDATE</command> the missing columns from <literal>t1</literal> are added to
+ the target list by the planner and the final query tree will read
+ as:
+
+<programlisting>
+UPDATE t1 SET a = t1.a, b = t2.b FROM t2 WHERE t1.a = t2.a;
+</programlisting>
+
+ and thus the executor run over the join will produce exactly the
+ same result set as:
+
+<programlisting>
+SELECT t1.a, t2.b FROM t1, t2 WHERE t1.a = t2.a;
+</programlisting>
+
+ But there is a little problem in
+ <command>UPDATE</command>: the part of the executor plan that does
+ the join does not care what the results from the join are
+ meant for. It just produces a result set of rows. The fact that
+ one is a <command>SELECT</command> command and the other is an
+ <command>UPDATE</command> is handled higher up in the executor, where
+ it knows that this is an <command>UPDATE</command>, and it knows that
+ this result should go into table <literal>t1</literal>. But which of the rows
+ that are there has to be replaced by the new row?
+</para>
+
+<para>
+ To resolve this problem, another entry is added to the target list
+ in <command>UPDATE</command> (and also in
+ <command>DELETE</command>) statements: the current tuple ID
+ (<acronym>CTID</acronym>).<indexterm><primary>CTID</primary></indexterm>
+ This is a system column containing the
+ file block number and position in the block for the row. Knowing
+ the table, the <acronym>CTID</acronym> can be used to retrieve the
+ original row of <literal>t1</literal> to be updated. After adding the
+ <acronym>CTID</acronym> to the target list, the query actually looks like:
+
+<programlisting>
+SELECT t1.a, t2.b, t1.ctid FROM t1, t2 WHERE t1.a = t2.a;
+</programlisting>
+
+ Now another detail of <productname>PostgreSQL</productname> enters
+ the stage. Old table rows aren't overwritten, and this
+ is why <command>ROLLBACK</command> is fast. In an <command>UPDATE</command>,
+ the new result row is inserted into the table (after stripping the
+ <acronym>CTID</acronym>) and in the row header of the old row, which the
+ <acronym>CTID</acronym> pointed to, the <literal>cmax</literal> and
+ <literal>xmax</literal> entries are set to the current command counter
+ and current transaction ID. Thus the old row is hidden, and after
+ the transaction commits the vacuum cleaner can eventually remove
+ the dead row.
+</para>
+
+<para>
+ Knowing all that, we can simply apply view rules in absolutely
+ the same way to any command. There is no difference.
+</para>
+</sect2>
+
+<sect2>
+<title>The Power of Views in <productname>PostgreSQL</productname></title>
+
+<para>
+ The above demonstrates how the rule system incorporates view
+ definitions into the original query tree. In the second example, a
+ simple <command>SELECT</command> from one view created a final
+ query tree that is a join of 4 tables (<literal>unit</literal> was used twice with
+ different names).
+</para>
+
+<para>
+ The benefit of implementing views with the rule system is
+ that the planner has all
+ the information about which tables have to be scanned plus the
+ relationships between these tables plus the restrictive
+ qualifications from the views plus the qualifications from
+ the original query
+ in one single query tree. And this is still the situation
+ when the original query is already a join over views.
+ The planner has to decide which is
+ the best path to execute the query, and the more information
+ the planner has, the better this decision can be. And
+ the rule system as implemented in <productname>PostgreSQL</productname>
+ ensures that this is all information available about the query
+ up to that point.
+</para>
+</sect2>
+
+<sect2 id="rules-views-update">
+<title>Updating a View</title>
+
+<para>
+ What happens if a view is named as the target relation for an
+ <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command>? Doing the substitutions
+ described above would give a query tree in which the result
+ relation points at a subquery range-table entry, which will not
+ work. There are several ways in which <productname>PostgreSQL</productname>
+ can support the appearance of updating a view, however.
+ In order of user-experienced complexity those are: automatically substitute
+ in the underlying table for the view, execute a user-defined trigger,
+ or rewrite the query per a user-defined rule.
+ These options are discussed below.
+</para>
+
+<para>
+ If the subquery selects from a single base relation and is simple
+ enough, the rewriter can automatically replace the subquery with the
+ underlying base relation so that the <command>INSERT</command>,
+ <command>UPDATE</command>, or <command>DELETE</command> is applied to
+ the base relation in the appropriate way. Views that are
+ <quote>simple enough</quote> for this are called <firstterm>automatically
+ updatable</firstterm>. For detailed information on the kinds of view that can
+ be automatically updated, see <xref linkend="sql-createview"/>.
+</para>
+
+<para>
+ Alternatively, the operation may be handled by a user-provided
+ <literal>INSTEAD OF</literal> trigger on the view
+ (see <xref linkend="sql-createtrigger"/>).
+ Rewriting works slightly differently
+ in this case. For <command>INSERT</command>, the rewriter does
+ nothing at all with the view, leaving it as the result relation
+ for the query. For <command>UPDATE</command> and
+ <command>DELETE</command>, it's still necessary to expand the
+ view query to produce the <quote>old</quote> rows that the command will
+ attempt to update or delete. So the view is expanded as normal,
+ but another unexpanded range-table entry is added to the query
+ to represent the view in its capacity as the result relation.
+</para>
+
+<para>
+ The problem that now arises is how to identify the rows to be
+ updated in the view. Recall that when the result relation
+ is a table, a special <acronym>CTID</acronym> entry is added to the target
+ list to identify the physical locations of the rows to be updated.
+ This does not work if the result relation is a view, because a view
+ does not have any <acronym>CTID</acronym>, since its rows do not have
+ actual physical locations. Instead, for an <command>UPDATE</command>
+ or <command>DELETE</command> operation, a special <literal>wholerow</literal>
+ entry is added to the target list, which expands to include all
+ columns from the view. The executor uses this value to supply the
+ <quote>old</quote> row to the <literal>INSTEAD OF</literal> trigger. It is
+ up to the trigger to work out what to update based on the old and
+ new row values.
+</para>
+
+<para>
+ Another possibility is for the user to define <literal>INSTEAD</literal>
+ rules that specify substitute actions for <command>INSERT</command>,
+ <command>UPDATE</command>, and <command>DELETE</command> commands on
+ a view. These rules will rewrite the command, typically into a command
+ that updates one or more tables, rather than views. That is the topic
+ of <xref linkend="rules-update"/>.
+</para>
+
+<para>
+ Note that rules are evaluated first, rewriting the original query
+ before it is planned and executed. Therefore, if a view has
+ <literal>INSTEAD OF</literal> triggers as well as rules on <command>INSERT</command>,
+ <command>UPDATE</command>, or <command>DELETE</command>, then the rules will be
+ evaluated first, and depending on the result, the triggers may not be
+ used at all.
+</para>
+
+<para>
+ Automatic rewriting of an <command>INSERT</command>,
+ <command>UPDATE</command>, or <command>DELETE</command> query on a
+ simple view is always tried last. Therefore, if a view has rules or
+ triggers, they will override the default behavior of automatically
+ updatable views.
+</para>
+
+<para>
+ If there are no <literal>INSTEAD</literal> rules or <literal>INSTEAD OF</literal>
+ triggers for the view, and the rewriter cannot automatically rewrite
+ the query as an update on the underlying base relation, an error will
+ be thrown because the executor cannot update a view as such.
+</para>
+
+</sect2>
+
+</sect1>
+
+<sect1 id="rules-materializedviews">
+<title>Materialized Views</title>
+
+<indexterm zone="rules-materializedviews">
+ <primary>rule</primary>
+ <secondary>and materialized views</secondary>
+</indexterm>
+
+<indexterm zone="rules-materializedviews">
+ <primary>materialized view</primary>
+ <secondary>implementation through rules</secondary>
+</indexterm>
+
+<indexterm zone="rules-materializedviews">
+ <primary>view</primary>
+ <secondary>materialized</secondary>
+</indexterm>
+
+<para>
+ Materialized views in <productname>PostgreSQL</productname> use the
+ rule system like views do, but persist the results in a table-like form.
+ The main differences between:
+
+<programlisting>
+CREATE MATERIALIZED VIEW mymatview AS SELECT * FROM mytab;
+</programlisting>
+
+ and:
+
+<programlisting>
+CREATE TABLE mymatview AS SELECT * FROM mytab;
+</programlisting>
+
+ are that the materialized view cannot subsequently be directly updated
+ and that the query used to create the materialized view is stored in
+ exactly the same way that a view's query is stored, so that fresh data
+ can be generated for the materialized view with:
+
+<programlisting>
+REFRESH MATERIALIZED VIEW mymatview;
+</programlisting>
+
+ The information about a materialized view in the
+ <productname>PostgreSQL</productname> system catalogs is exactly
+ the same as it is for a table or view. So for the parser, a
+ materialized view is a relation, just like a table or a view. When
+ a materialized view is referenced in a query, the data is returned
+ directly from the materialized view, like from a table; the rule is
+ only used for populating the materialized view.
+</para>
+
+<para>
+ While access to the data stored in a materialized view is often much
+ faster than accessing the underlying tables directly or through a view,
+ the data is not always current; yet sometimes current data is not needed.
+ Consider a table which records sales:
+
+<programlisting>
+CREATE TABLE invoice (
+ invoice_no integer PRIMARY KEY,
+ seller_no integer, -- ID of salesperson
+ invoice_date date, -- date of sale
+ invoice_amt numeric(13,2) -- amount of sale
+);
+</programlisting>
+
+ If people want to be able to quickly graph historical sales data, they
+ might want to summarize, and they may not care about the incomplete data
+ for the current date:
+
+<programlisting>
+CREATE MATERIALIZED VIEW sales_summary AS
+ SELECT
+ seller_no,
+ invoice_date,
+ sum(invoice_amt)::numeric(13,2) as sales_amt
+ FROM invoice
+ WHERE invoice_date &lt; CURRENT_DATE
+ GROUP BY
+ seller_no,
+ invoice_date;
+
+CREATE UNIQUE INDEX sales_summary_seller
+ ON sales_summary (seller_no, invoice_date);
+</programlisting>
+
+ This materialized view might be useful for displaying a graph in the
+ dashboard created for salespeople. A job could be scheduled to update
+ the statistics each night using this SQL statement:
+
+<programlisting>
+REFRESH MATERIALIZED VIEW sales_summary;
+</programlisting>
+</para>
+
+<para>
+ Another use for a materialized view is to allow faster access to data
+ brought across from a remote system through a foreign data wrapper.
+ A simple example using <literal>file_fdw</literal> is below, with timings,
+ but since this is using cache on the local system the performance
+ difference compared to access to a remote system would usually be greater
+ than shown here. Notice we are also exploiting the ability to put an
+ index on the materialized view, whereas <literal>file_fdw</literal> does
+ not support indexes; this advantage might not apply for other sorts of
+ foreign data access.
+</para>
+
+<para>
+ Setup:
+
+<programlisting>
+CREATE EXTENSION file_fdw;
+CREATE SERVER local_file FOREIGN DATA WRAPPER file_fdw;
+CREATE FOREIGN TABLE words (word text NOT NULL)
+ SERVER local_file
+ OPTIONS (filename '/usr/share/dict/words');
+CREATE MATERIALIZED VIEW wrd AS SELECT * FROM words;
+CREATE UNIQUE INDEX wrd_word ON wrd (word);
+CREATE EXTENSION pg_trgm;
+CREATE INDEX wrd_trgm ON wrd USING gist (word gist_trgm_ops);
+VACUUM ANALYZE wrd;
+</programlisting>
+
+ Now let's spell-check a word. Using <literal>file_fdw</literal> directly:
+
+<programlisting>
+SELECT count(*) FROM words WHERE word = 'caterpiler';
+
+ count
+-------
+ 0
+(1 row)
+</programlisting>
+
+ With <command>EXPLAIN ANALYZE</command>, we see:
+
+<programlisting>
+ Aggregate (cost=21763.99..21764.00 rows=1 width=0) (actual time=188.180..188.181 rows=1 loops=1)
+ -&gt; Foreign Scan on words (cost=0.00..21761.41 rows=1032 width=0) (actual time=188.177..188.177 rows=0 loops=1)
+ Filter: (word = 'caterpiler'::text)
+ Rows Removed by Filter: 479829
+ Foreign File: /usr/share/dict/words
+ Foreign File Size: 4953699
+ Planning time: 0.118 ms
+ Execution time: 188.273 ms
+</programlisting>
+
+ If the materialized view is used instead, the query is much faster:
+
+<programlisting>
+ Aggregate (cost=4.44..4.45 rows=1 width=0) (actual time=0.042..0.042 rows=1 loops=1)
+ -&gt; Index Only Scan using wrd_word on wrd (cost=0.42..4.44 rows=1 width=0) (actual time=0.039..0.039 rows=0 loops=1)
+ Index Cond: (word = 'caterpiler'::text)
+ Heap Fetches: 0
+ Planning time: 0.164 ms
+ Execution time: 0.117 ms
+</programlisting>
+
+ Either way, the word is spelled wrong, so let's look for what we might
+ have wanted. Again using <literal>file_fdw</literal> and
+ <literal>pg_trgm</literal>:
+
+<programlisting>
+SELECT word FROM words ORDER BY word &lt;-&gt; 'caterpiler' LIMIT 10;
+
+ word
+---------------
+ cater
+ caterpillar
+ Caterpillar
+ caterpillars
+ caterpillar's
+ Caterpillar's
+ caterer
+ caterer's
+ caters
+ catered
+(10 rows)
+</programlisting>
+
+<programlisting>
+ Limit (cost=11583.61..11583.64 rows=10 width=32) (actual time=1431.591..1431.594 rows=10 loops=1)
+ -&gt; Sort (cost=11583.61..11804.76 rows=88459 width=32) (actual time=1431.589..1431.591 rows=10 loops=1)
+ Sort Key: ((word &lt;-&gt; 'caterpiler'::text))
+ Sort Method: top-N heapsort Memory: 25kB
+ -&gt; Foreign Scan on words (cost=0.00..9672.05 rows=88459 width=32) (actual time=0.057..1286.455 rows=479829 loops=1)
+ Foreign File: /usr/share/dict/words
+ Foreign File Size: 4953699
+ Planning time: 0.128 ms
+ Execution time: 1431.679 ms
+</programlisting>
+
+ Using the materialized view:
+
+<programlisting>
+ Limit (cost=0.29..1.06 rows=10 width=10) (actual time=187.222..188.257 rows=10 loops=1)
+ -&gt; Index Scan using wrd_trgm on wrd (cost=0.29..37020.87 rows=479829 width=10) (actual time=187.219..188.252 rows=10 loops=1)
+ Order By: (word &lt;-&gt; 'caterpiler'::text)
+ Planning time: 0.196 ms
+ Execution time: 198.640 ms
+</programlisting>
+
+ If you can tolerate periodic update of the remote data to the local
+ database, the performance benefit can be substantial.
+</para>
+
+</sect1>
+
+<sect1 id="rules-update">
+<title>Rules on <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command></title>
+
+<indexterm zone="rules-update">
+ <primary>rule</primary>
+ <secondary sortas="INSERT">for INSERT</secondary>
+</indexterm>
+
+<indexterm zone="rules-update">
+ <primary>rule</primary>
+ <secondary sortas="UPDATE">for UPDATE</secondary>
+</indexterm>
+
+<indexterm zone="rules-update">
+ <primary>rule</primary>
+ <secondary sortas="DELETE">for DELETE</secondary>
+</indexterm>
+
+<para>
+ Rules that are defined on <command>INSERT</command>, <command>UPDATE</command>,
+ and <command>DELETE</command> are significantly different from the view rules
+ described in the previous section. First, their <command>CREATE
+ RULE</command> command allows more:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ They are allowed to have no action.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ They can have multiple actions.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ They can be <literal>INSTEAD</literal> or <literal>ALSO</literal> (the default).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The pseudorelations <literal>NEW</literal> and <literal>OLD</literal> become useful.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ They can have rule qualifications.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Second, they don't modify the query tree in place. Instead they
+ create zero or more new query trees and can throw away the
+ original one.
+</para>
+
+<caution>
+ <para>
+ In many cases, tasks that could be performed by rules
+ on <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command> are better done
+ with triggers. Triggers are notationally a bit more complicated, but their
+ semantics are much simpler to understand. Rules tend to have surprising
+ results when the original query contains volatile functions: volatile
+ functions may get executed more times than expected in the process of
+ carrying out the rules.
+ </para>
+
+ <para>
+ Also, there are some cases that are not supported by these types of rules at
+ all, notably including <literal>WITH</literal> clauses in the original query and
+ multiple-assignment sub-<literal>SELECT</literal>s in the <literal>SET</literal> list
+ of <command>UPDATE</command> queries. This is because copying these constructs
+ into a rule query would result in multiple evaluations of the sub-query,
+ contrary to the express intent of the query's author.
+ </para>
+</caution>
+
+<sect2>
+<title>How Update Rules Work</title>
+
+<para>
+ Keep the syntax:
+
+<programlisting>
+CREATE [ OR REPLACE ] RULE <replaceable class="parameter">name</replaceable> AS ON <replaceable class="parameter">event</replaceable>
+ TO <replaceable class="parameter">table</replaceable> [ WHERE <replaceable class="parameter">condition</replaceable> ]
+ DO [ ALSO | INSTEAD ] { NOTHING | <replaceable class="parameter">command</replaceable> | ( <replaceable class="parameter">command</replaceable> ; <replaceable class="parameter">command</replaceable> ... ) }
+</programlisting>
+
+ in mind.
+ In the following, <firstterm>update rules</firstterm> means rules that are defined
+ on <command>INSERT</command>, <command>UPDATE</command>, or <command>DELETE</command>.
+</para>
+
+<para>
+ Update rules get applied by the rule system when the result
+ relation and the command type of a query tree are equal to the
+ object and event given in the <command>CREATE RULE</command> command.
+ For update rules, the rule system creates a list of query trees.
+ Initially the query-tree list is empty.
+ There can be zero (<literal>NOTHING</literal> key word), one, or multiple actions.
+ To simplify, we will look at a rule with one action. This rule
+ can have a qualification or not and it can be <literal>INSTEAD</literal> or
+ <literal>ALSO</literal> (the default).
+</para>
+
+<para>
+ What is a rule qualification? It is a restriction that tells
+ when the actions of the rule should be done and when not. This
+ qualification can only reference the pseudorelations <literal>NEW</literal> and/or <literal>OLD</literal>,
+ which basically represent the relation that was given as object (but with a
+ special meaning).
+</para>
+
+ <para>
+ So we have three cases that produce the following query trees for
+ a one-action rule.
+
+ <variablelist>
+ <varlistentry>
+ <term>No qualification, with either <literal>ALSO</literal> or
+ <literal>INSTEAD</literal></term>
+ <listitem>
+ <para>
+ the query tree from the rule action with the original query
+ tree's qualification added
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Qualification given and <literal>ALSO</literal></term>
+ <listitem>
+ <para>
+ the query tree from the rule action with the rule
+ qualification and the original query tree's qualification
+ added
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Qualification given and <literal>INSTEAD</literal></term>
+ <listitem>
+ <para>
+ the query tree from the rule action with the rule
+ qualification and the original query tree's qualification; and
+ the original query tree with the negated rule qualification
+ added
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ Finally, if the rule is <literal>ALSO</literal>, the unchanged original query tree is
+ added to the list. Since only qualified <literal>INSTEAD</literal> rules already add the
+ original query tree, we end up with either one or two output query trees
+ for a rule with one action.
+</para>
+
+<para>
+ For <literal>ON INSERT</literal> rules, the original query (if not suppressed by <literal>INSTEAD</literal>)
+ is done before any actions added by rules. This allows the actions to
+ see the inserted row(s). But for <literal>ON UPDATE</literal> and <literal>ON
+ DELETE</literal> rules, the original query is done after the actions added by rules.
+ This ensures that the actions can see the to-be-updated or to-be-deleted
+ rows; otherwise, the actions might do nothing because they find no rows
+ matching their qualifications.
+</para>
+
+<para>
+ The query trees generated from rule actions are thrown into the
+ rewrite system again, and maybe more rules get applied resulting
+ in additional or fewer query trees.
+ So a rule's actions must have either a different
+ command type or a different result relation than the rule itself is
+ on, otherwise this recursive process will end up in an infinite loop.
+ (Recursive expansion of a rule will be detected and reported as an
+ error.)
+</para>
+
+<para>
+ The query trees found in the actions of the
+ <structname>pg_rewrite</structname> system catalog are only
+ templates. Since they can reference the range-table entries for
+ <literal>NEW</literal> and <literal>OLD</literal>, some substitutions have to be made before they can be
+ used. For any reference to <literal>NEW</literal>, the target list of the original
+ query is searched for a corresponding entry. If found, that
+ entry's expression replaces the reference. Otherwise, <literal>NEW</literal> means the
+ same as <literal>OLD</literal> (for an <command>UPDATE</command>) or is replaced by
+ a null value (for an <command>INSERT</command>). Any reference to <literal>OLD</literal> is
+ replaced by a reference to the range-table entry that is the
+ result relation.
+</para>
+
+<para>
+ After the system is done applying update rules, it applies view rules to the
+ produced query tree(s). Views cannot insert new update actions so
+ there is no need to apply update rules to the output of view rewriting.
+</para>
+
+<sect3>
+<title>A First Rule Step by Step</title>
+
+<para>
+ Say we want to trace changes to the <literal>sl_avail</literal> column in the
+ <literal>shoelace_data</literal> relation. So we set up a log table
+ and a rule that conditionally writes a log entry when an
+ <command>UPDATE</command> is performed on
+ <literal>shoelace_data</literal>.
+
+<programlisting>
+CREATE TABLE shoelace_log (
+ sl_name text, -- shoelace changed
+ sl_avail integer, -- new available value
+ log_who text, -- who did it
+ log_when timestamp -- when
+);
+
+CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data
+ WHERE NEW.sl_avail &lt;&gt; OLD.sl_avail
+ DO INSERT INTO shoelace_log VALUES (
+ NEW.sl_name,
+ NEW.sl_avail,
+ current_user,
+ current_timestamp
+ );
+</programlisting>
+</para>
+
+<para>
+ Now someone does:
+
+<programlisting>
+UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';
+</programlisting>
+
+ and we look at the log table:
+
+<programlisting>
+SELECT * FROM shoelace_log;
+
+ sl_name | sl_avail | log_who | log_when
+---------+----------+---------+----------------------------------
+ sl7 | 6 | Al | Tue Oct 20 16:14:45 1998 MET DST
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ That's what we expected. What happened in the background is the following.
+ The parser created the query tree:
+
+<programlisting>
+UPDATE shoelace_data SET sl_avail = 6
+ FROM shoelace_data shoelace_data
+ WHERE shoelace_data.sl_name = 'sl7';
+</programlisting>
+
+ There is a rule <literal>log_shoelace</literal> that is <literal>ON UPDATE</literal> with the rule
+ qualification expression:
+
+<programlisting>
+NEW.sl_avail &lt;&gt; OLD.sl_avail
+</programlisting>
+
+ and the action:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old;
+</programlisting>
+
+ (This looks a little strange since you cannot normally write
+ <literal>INSERT ... VALUES ... FROM</literal>. The <literal>FROM</literal>
+ clause here is just to indicate that there are range-table entries
+ in the query tree for <literal>new</literal> and <literal>old</literal>.
+ These are needed so that they can be referenced by variables in
+ the <command>INSERT</command> command's query tree.)
+</para>
+
+<para>
+ The rule is a qualified <literal>ALSO</literal> rule, so the rule system
+ has to return two query trees: the modified rule action and the original
+ query tree. In step 1, the range table of the original query is
+ incorporated into the rule's action query tree. This results in:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ <emphasis>shoelace_data shoelace_data</emphasis>;
+</programlisting>
+
+ In step 2, the rule qualification is added to it, so the result set
+ is restricted to rows where <literal>sl_avail</literal> changes:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ <emphasis>WHERE new.sl_avail &lt;&gt; old.sl_avail</emphasis>;
+</programlisting>
+
+ (This looks even stranger, since <literal>INSERT ... VALUES</literal> doesn't have
+ a <literal>WHERE</literal> clause either, but the planner and executor will have no
+ difficulty with it. They need to support this same functionality
+ anyway for <literal>INSERT ... SELECT</literal>.)
+ </para>
+
+ <para>
+ In step 3, the original query tree's qualification is added,
+ restricting the result set further to only the rows that would have been touched
+ by the original query:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ new.sl_name, new.sl_avail,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ WHERE new.sl_avail &lt;&gt; old.sl_avail
+ <emphasis>AND shoelace_data.sl_name = 'sl7'</emphasis>;
+</programlisting>
+ </para>
+
+ <para>
+ Step 4 replaces references to <literal>NEW</literal> by the target list entries from the
+ original query tree or by the matching variable references
+ from the result relation:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ <emphasis>shoelace_data.sl_name</emphasis>, <emphasis>6</emphasis>,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ WHERE <emphasis>6</emphasis> &lt;&gt; old.sl_avail
+ AND shoelace_data.sl_name = 'sl7';
+</programlisting>
+
+ </para>
+
+ <para>
+ Step 5 changes <literal>OLD</literal> references into result relation references:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ shoelace_data.sl_name, 6,
+ current_user, current_timestamp )
+ FROM shoelace_data new, shoelace_data old,
+ shoelace_data shoelace_data
+ WHERE 6 &lt;&gt; <emphasis>shoelace_data.sl_avail</emphasis>
+ AND shoelace_data.sl_name = 'sl7';
+</programlisting>
+ </para>
+
+ <para>
+ That's it. Since the rule is <literal>ALSO</literal>, we also output the
+ original query tree. In short, the output from the rule system
+ is a list of two query trees that correspond to these statements:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ shoelace_data.sl_name, 6,
+ current_user, current_timestamp )
+ FROM shoelace_data
+ WHERE 6 &lt;&gt; shoelace_data.sl_avail
+ AND shoelace_data.sl_name = 'sl7';
+
+UPDATE shoelace_data SET sl_avail = 6
+ WHERE sl_name = 'sl7';
+</programlisting>
+
+ These are executed in this order, and that is exactly what
+ the rule was meant to do.
+ </para>
+
+ <para>
+ The substitutions and the added qualifications
+ ensure that, if the original query would be, say:
+
+<programlisting>
+UPDATE shoelace_data SET sl_color = 'green'
+ WHERE sl_name = 'sl7';
+</programlisting>
+
+ no log entry would get written. In that case, the original query
+ tree does not contain a target list entry for
+ <literal>sl_avail</literal>, so <literal>NEW.sl_avail</literal> will get
+ replaced by <literal>shoelace_data.sl_avail</literal>. Thus, the extra
+ command generated by the rule is:
+
+<programlisting>
+INSERT INTO shoelace_log VALUES (
+ shoelace_data.sl_name, <emphasis>shoelace_data.sl_avail</emphasis>,
+ current_user, current_timestamp )
+ FROM shoelace_data
+ WHERE <emphasis>shoelace_data.sl_avail</emphasis> &lt;&gt; shoelace_data.sl_avail
+ AND shoelace_data.sl_name = 'sl7';
+</programlisting>
+
+ and that qualification will never be true.
+ </para>
+
+ <para>
+ It will also work if the original query modifies multiple rows. So
+ if someone issued the command:
+
+<programlisting>
+UPDATE shoelace_data SET sl_avail = 0
+ WHERE sl_color = 'black';
+</programlisting>
+
+ four rows in fact get updated (<literal>sl1</literal>, <literal>sl2</literal>, <literal>sl3</literal>, and <literal>sl4</literal>).
+ But <literal>sl3</literal> already has <literal>sl_avail = 0</literal>. In this case, the original
+ query trees qualification is different and that results
+ in the extra query tree:
+
+<programlisting>
+INSERT INTO shoelace_log
+SELECT shoelace_data.sl_name, 0,
+ current_user, current_timestamp
+ FROM shoelace_data
+ WHERE 0 &lt;&gt; shoelace_data.sl_avail
+ AND <emphasis>shoelace_data.sl_color = 'black'</emphasis>;
+</programlisting>
+
+ being generated by the rule. This query tree will surely insert
+ three new log entries. And that's absolutely correct.
+</para>
+
+<para>
+ Here we can see why it is important that the original query tree
+ is executed last. If the <command>UPDATE</command> had been
+ executed first, all the rows would have already been set to zero, so the
+ logging <command>INSERT</command> would not find any row where
+ <literal>0 &lt;&gt; shoelace_data.sl_avail</literal>.
+</para>
+</sect3>
+
+</sect2>
+
+<sect2 id="rules-update-views">
+<title>Cooperation with Views</title>
+
+<indexterm zone="rules-update-views"><primary>view</primary><secondary>updating</secondary></indexterm>
+
+<para>
+ A simple way to protect view relations from the mentioned
+ possibility that someone can try to run <command>INSERT</command>,
+ <command>UPDATE</command>, or <command>DELETE</command> on them is
+ to let those query trees get thrown away. So we could create the rules:
+
+<programlisting>
+CREATE RULE shoe_ins_protect AS ON INSERT TO shoe
+ DO INSTEAD NOTHING;
+CREATE RULE shoe_upd_protect AS ON UPDATE TO shoe
+ DO INSTEAD NOTHING;
+CREATE RULE shoe_del_protect AS ON DELETE TO shoe
+ DO INSTEAD NOTHING;
+</programlisting>
+
+ If someone now tries to do any of these operations on the view
+ relation <literal>shoe</literal>, the rule system will
+ apply these rules. Since the rules have
+ no actions and are <literal>INSTEAD</literal>, the resulting list of
+ query trees will be empty and the whole query will become
+ nothing because there is nothing left to be optimized or
+ executed after the rule system is done with it.
+</para>
+
+<para>
+ A more sophisticated way to use the rule system is to
+ create rules that rewrite the query tree into one that
+ does the right operation on the real tables. To do that
+ on the <literal>shoelace</literal> view, we create
+ the following rules:
+
+<programlisting>
+CREATE RULE shoelace_ins AS ON INSERT TO shoelace
+ DO INSTEAD
+ INSERT INTO shoelace_data VALUES (
+ NEW.sl_name,
+ NEW.sl_avail,
+ NEW.sl_color,
+ NEW.sl_len,
+ NEW.sl_unit
+ );
+
+CREATE RULE shoelace_upd AS ON UPDATE TO shoelace
+ DO INSTEAD
+ UPDATE shoelace_data
+ SET sl_name = NEW.sl_name,
+ sl_avail = NEW.sl_avail,
+ sl_color = NEW.sl_color,
+ sl_len = NEW.sl_len,
+ sl_unit = NEW.sl_unit
+ WHERE sl_name = OLD.sl_name;
+
+CREATE RULE shoelace_del AS ON DELETE TO shoelace
+ DO INSTEAD
+ DELETE FROM shoelace_data
+ WHERE sl_name = OLD.sl_name;
+</programlisting>
+ </para>
+
+ <para>
+ If you want to support <literal>RETURNING</literal> queries on the view,
+ you need to make the rules include <literal>RETURNING</literal> clauses that
+ compute the view rows. This is usually pretty trivial for views on a
+ single table, but it's a bit tedious for join views such as
+ <literal>shoelace</literal>. An example for the insert case is:
+
+<programlisting>
+CREATE RULE shoelace_ins AS ON INSERT TO shoelace
+ DO INSTEAD
+ INSERT INTO shoelace_data VALUES (
+ NEW.sl_name,
+ NEW.sl_avail,
+ NEW.sl_color,
+ NEW.sl_len,
+ NEW.sl_unit
+ )
+ RETURNING
+ shoelace_data.*,
+ (SELECT shoelace_data.sl_len * u.un_fact
+ FROM unit u WHERE shoelace_data.sl_unit = u.un_name);
+</programlisting>
+
+ Note that this one rule supports both <command>INSERT</command> and
+ <command>INSERT RETURNING</command> queries on the view &mdash; the
+ <literal>RETURNING</literal> clause is simply ignored for <command>INSERT</command>.
+ </para>
+
+ <para>
+ Now assume that once in a while, a pack of shoelaces arrives at
+ the shop and a big parts list along with it. But you don't want
+ to manually update the <literal>shoelace</literal> view every
+ time. Instead we set up two little tables: one where you can
+ insert the items from the part list, and one with a special
+ trick. The creation commands for these are:
+
+<programlisting>
+CREATE TABLE shoelace_arrive (
+ arr_name text,
+ arr_quant integer
+);
+
+CREATE TABLE shoelace_ok (
+ ok_name text,
+ ok_quant integer
+);
+
+CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok
+ DO INSTEAD
+ UPDATE shoelace
+ SET sl_avail = sl_avail + NEW.ok_quant
+ WHERE sl_name = NEW.ok_name;
+</programlisting>
+
+ Now you can fill the table <literal>shoelace_arrive</literal> with
+ the data from the parts list:
+
+<programlisting>
+SELECT * FROM shoelace_arrive;
+
+ arr_name | arr_quant
+----------+-----------
+ sl3 | 10
+ sl6 | 20
+ sl8 | 20
+(3 rows)
+</programlisting>
+
+ Take a quick look at the current data:
+
+<programlisting>
+SELECT * FROM shoelace;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+----------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 6 | brown | 60 | cm | 60
+ sl3 | 0 | black | 35 | inch | 88.9
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl8 | 1 | brown | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 0 | brown | 0.9 | m | 90
+(8 rows)
+</programlisting>
+
+ Now move the arrived shoelaces in:
+
+<programlisting>
+INSERT INTO shoelace_ok SELECT * FROM shoelace_arrive;
+</programlisting>
+
+ and check the results:
+
+<programlisting>
+SELECT * FROM shoelace ORDER BY sl_name;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+----------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 6 | brown | 60 | cm | 60
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl3 | 10 | black | 35 | inch | 88.9
+ sl8 | 21 | brown | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 20 | brown | 0.9 | m | 90
+(8 rows)
+
+SELECT * FROM shoelace_log;
+
+ sl_name | sl_avail | log_who| log_when
+---------+----------+--------+----------------------------------
+ sl7 | 6 | Al | Tue Oct 20 19:14:45 1998 MET DST
+ sl3 | 10 | Al | Tue Oct 20 19:25:16 1998 MET DST
+ sl6 | 20 | Al | Tue Oct 20 19:25:16 1998 MET DST
+ sl8 | 21 | Al | Tue Oct 20 19:25:16 1998 MET DST
+(4 rows)
+</programlisting>
+ </para>
+
+ <para>
+ It's a long way from the one <literal>INSERT ... SELECT</literal>
+ to these results. And the description of the query-tree
+ transformation will be the last in this chapter. First, there is
+ the parser's output:
+
+<programlisting>
+INSERT INTO shoelace_ok
+SELECT shoelace_arrive.arr_name, shoelace_arrive.arr_quant
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok;
+</programlisting>
+
+ Now the first rule <literal>shoelace_ok_ins</literal> is applied and turns this
+ into:
+
+<programlisting>
+UPDATE shoelace
+ SET sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace
+ WHERE shoelace.sl_name = shoelace_arrive.arr_name;
+</programlisting>
+
+ and throws away the original <command>INSERT</command> on
+ <literal>shoelace_ok</literal>. This rewritten query is passed to
+ the rule system again, and the second applied rule
+ <literal>shoelace_upd</literal> produces:
+
+<programlisting>
+UPDATE shoelace_data
+ SET sl_name = shoelace.sl_name,
+ sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant,
+ sl_color = shoelace.sl_color,
+ sl_len = shoelace.sl_len,
+ sl_unit = shoelace.sl_unit
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace, shoelace old,
+ shoelace new, shoelace_data shoelace_data
+ WHERE shoelace.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = shoelace.sl_name;
+</programlisting>
+
+ Again it's an <literal>INSTEAD</literal> rule and the previous query tree is trashed.
+ Note that this query still uses the view <literal>shoelace</literal>.
+ But the rule system isn't finished with this step, so it continues
+ and applies the <literal>_RETURN</literal> rule on it, and we get:
+
+<programlisting>
+UPDATE shoelace_data
+ SET sl_name = s.sl_name,
+ sl_avail = s.sl_avail + shoelace_arrive.arr_quant,
+ sl_color = s.sl_color,
+ sl_len = s.sl_len,
+ sl_unit = s.sl_unit
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace, shoelace old,
+ shoelace new, shoelace_data shoelace_data,
+ shoelace old, shoelace new,
+ shoelace_data s, unit u
+ WHERE s.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = s.sl_name;
+</programlisting>
+
+ Finally, the rule <literal>log_shoelace</literal> gets applied,
+ producing the extra query tree:
+
+<programlisting>
+INSERT INTO shoelace_log
+SELECT s.sl_name,
+ s.sl_avail + shoelace_arrive.arr_quant,
+ current_user,
+ current_timestamp
+ FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
+ shoelace_ok old, shoelace_ok new,
+ shoelace shoelace, shoelace old,
+ shoelace new, shoelace_data shoelace_data,
+ shoelace old, shoelace new,
+ shoelace_data s, unit u,
+ shoelace_data old, shoelace_data new
+ shoelace_log shoelace_log
+ WHERE s.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = s.sl_name
+ AND (s.sl_avail + shoelace_arrive.arr_quant) &lt;&gt; s.sl_avail;
+</programlisting>
+
+ After that the rule system runs out of rules and returns the
+ generated query trees.
+ </para>
+
+ <para>
+ So we end up with two final query trees that are equivalent to the
+ <acronym>SQL</acronym> statements:
+
+<programlisting>
+INSERT INTO shoelace_log
+SELECT s.sl_name,
+ s.sl_avail + shoelace_arrive.arr_quant,
+ current_user,
+ current_timestamp
+ FROM shoelace_arrive shoelace_arrive, shoelace_data shoelace_data,
+ shoelace_data s
+ WHERE s.sl_name = shoelace_arrive.arr_name
+ AND shoelace_data.sl_name = s.sl_name
+ AND s.sl_avail + shoelace_arrive.arr_quant &lt;&gt; s.sl_avail;
+
+UPDATE shoelace_data
+ SET sl_avail = shoelace_data.sl_avail + shoelace_arrive.arr_quant
+ FROM shoelace_arrive shoelace_arrive,
+ shoelace_data shoelace_data,
+ shoelace_data s
+ WHERE s.sl_name = shoelace_arrive.sl_name
+ AND shoelace_data.sl_name = s.sl_name;
+</programlisting>
+
+ The result is that data coming from one relation inserted into another,
+ changed into updates on a third, changed into updating
+ a fourth plus logging that final update in a fifth
+ gets reduced into two queries.
+</para>
+
+<para>
+ There is a little detail that's a bit ugly. Looking at the two
+ queries, it turns out that the <literal>shoelace_data</literal>
+ relation appears twice in the range table where it could
+ definitely be reduced to one. The planner does not handle it and
+ so the execution plan for the rule systems output of the
+ <command>INSERT</command> will be
+
+<literallayout class="monospaced">
+Nested Loop
+ -&gt; Merge Join
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on s
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on shoelace_arrive
+ -&gt; Seq Scan on shoelace_data
+</literallayout>
+
+ while omitting the extra range table entry would result in a
+
+<literallayout class="monospaced">
+Merge Join
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on s
+ -&gt; Seq Scan
+ -&gt; Sort
+ -&gt; Seq Scan on shoelace_arrive
+</literallayout>
+
+ which produces exactly the same entries in the log table. Thus,
+ the rule system caused one extra scan on the table
+ <literal>shoelace_data</literal> that is absolutely not
+ necessary. And the same redundant scan is done once more in the
+ <command>UPDATE</command>. But it was a really hard job to make
+ that all possible at all.
+</para>
+
+<para>
+ Now we make a final demonstration of the
+ <productname>PostgreSQL</productname> rule system and its power.
+ Say you add some shoelaces with extraordinary colors to your
+ database:
+
+<programlisting>
+INSERT INTO shoelace VALUES ('sl9', 0, 'pink', 35.0, 'inch', 0.0);
+INSERT INTO shoelace VALUES ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0);
+</programlisting>
+
+ We would like to make a view to check which
+ <literal>shoelace</literal> entries do not fit any shoe in color.
+ The view for this is:
+
+<programlisting>
+CREATE VIEW shoelace_mismatch AS
+ SELECT * FROM shoelace WHERE NOT EXISTS
+ (SELECT shoename FROM shoe WHERE slcolor = sl_color);
+</programlisting>
+
+ Its output is:
+
+<programlisting>
+SELECT * FROM shoelace_mismatch;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+---------+----------+----------+--------+---------+-----------
+ sl9 | 0 | pink | 35 | inch | 88.9
+ sl10 | 1000 | magenta | 40 | inch | 101.6
+</programlisting>
+ </para>
+
+ <para>
+ Now we want to set it up so that mismatching shoelaces that are
+ not in stock are deleted from the database.
+ To make it a little harder for <productname>PostgreSQL</productname>,
+ we don't delete it directly. Instead we create one more view:
+
+<programlisting>
+CREATE VIEW shoelace_can_delete AS
+ SELECT * FROM shoelace_mismatch WHERE sl_avail = 0;
+</programlisting>
+
+ and do it this way:
+
+<programlisting>
+DELETE FROM shoelace WHERE EXISTS
+ (SELECT * FROM shoelace_can_delete
+ WHERE sl_name = shoelace.sl_name);
+</programlisting>
+
+ The results are:
+
+<programlisting>
+SELECT * FROM shoelace;
+
+ sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
+---------+----------+----------+--------+---------+-----------
+ sl1 | 5 | black | 80 | cm | 80
+ sl2 | 6 | black | 100 | cm | 100
+ sl7 | 6 | brown | 60 | cm | 60
+ sl4 | 8 | black | 40 | inch | 101.6
+ sl3 | 10 | black | 35 | inch | 88.9
+ sl8 | 21 | brown | 40 | inch | 101.6
+ sl10 | 1000 | magenta | 40 | inch | 101.6
+ sl5 | 4 | brown | 1 | m | 100
+ sl6 | 20 | brown | 0.9 | m | 90
+(9 rows)
+</programlisting>
+ </para>
+
+ <para>
+ A <command>DELETE</command> on a view, with a subquery qualification that
+ in total uses 4 nesting/joined views, where one of them
+ itself has a subquery qualification containing a view
+ and where calculated view columns are used,
+ gets rewritten into
+ one single query tree that deletes the requested data
+ from a real table.
+</para>
+
+<para>
+ There are probably only a few situations out in the real world
+ where such a construct is necessary. But it makes you feel
+ comfortable that it works.
+</para>
+</sect2>
+
+</sect1>
+
+<sect1 id="rules-privileges">
+<title>Rules and Privileges</title>
+
+<indexterm zone="rules-privileges">
+ <primary>privilege</primary>
+ <secondary sortas="Regeln">with rules</secondary>
+</indexterm>
+
+<indexterm zone="rules-privileges">
+ <primary>privilege</primary>
+ <secondary sortas="Sichten">with views</secondary>
+</indexterm>
+
+<para>
+ Due to rewriting of queries by the <productname>PostgreSQL</productname>
+ rule system, other tables/views than those used in the original
+ query get accessed. When update rules are used, this can include write access
+ to tables.
+</para>
+
+<para>
+ Rewrite rules don't have a separate owner. The owner of
+ a relation (table or view) is automatically the owner of the
+ rewrite rules that are defined for it.
+ The <productname>PostgreSQL</productname> rule system changes the
+ behavior of the default access control system. With the exception of
+ <literal>SELECT</literal> rules associated with security invoker views
+ (see <link linkend="sql-createview"><command>CREATE VIEW</command></link>),
+ all relations that are used due to rules get checked against the
+ privileges of the rule owner, not the user invoking the rule.
+ This means that, except for security invoker views, users only need the
+ required privileges for the tables/views that are explicitly named in
+ their queries.
+</para>
+
+<para>
+ For example: A user has a list of phone numbers where some of
+ them are private, the others are of interest for the assistant of the office.
+ The user can construct the following:
+
+<programlisting>
+CREATE TABLE phone_data (person text, phone text, private boolean);
+CREATE VIEW phone_number AS
+ SELECT person, CASE WHEN NOT private THEN phone END AS phone
+ FROM phone_data;
+GRANT SELECT ON phone_number TO assistant;
+</programlisting>
+
+ Nobody except that user (and the database superusers) can access the
+ <literal>phone_data</literal> table. But because of the <command>GRANT</command>,
+ the assistant can run a <command>SELECT</command> on the
+ <literal>phone_number</literal> view. The rule system will rewrite the
+ <command>SELECT</command> from <literal>phone_number</literal> into a
+ <command>SELECT</command> from <literal>phone_data</literal>.
+ Since the user is the owner of
+ <literal>phone_number</literal> and therefore the owner of the rule, the
+ read access to <literal>phone_data</literal> is now checked against the user's
+ privileges and the query is permitted. The check for accessing
+ <literal>phone_number</literal> is also performed, but this is done
+ against the invoking user, so nobody but the user and the
+ assistant can use it.
+</para>
+
+<para>
+ The privileges are checked rule by rule. So the assistant is for now the
+ only one who can see the public phone numbers. But the assistant can set up
+ another view and grant access to that to the public. Then, anyone
+ can see the <literal>phone_number</literal> data through the assistant's view.
+ What the assistant cannot do is to create a view that directly
+ accesses <literal>phone_data</literal>. (Actually the assistant can, but it will not work since
+ every access will be denied during the permission checks.)
+ And as soon as the user notices that the assistant opened
+ their <literal>phone_number</literal> view, the user can revoke the assistant's access. Immediately, any
+ access to the assistant's view would fail.
+</para>
+
+<para>
+ One might think that this rule-by-rule checking is a security
+ hole, but in fact it isn't. But if it did not work this way, the assistant
+ could set up a table with the same columns as <literal>phone_number</literal> and
+ copy the data to there once per day. Then it's the assistant's own data and
+ the assistant can grant access to everyone they want. A
+ <command>GRANT</command> command means, <quote>I trust you</quote>.
+ If someone you trust does the thing above, it's time to
+ think it over and then use <command>REVOKE</command>.
+</para>
+
+<para>
+ Note that while views can be used to hide the contents of certain
+ columns using the technique shown above, they cannot be used to reliably
+ conceal the data in unseen rows unless the
+ <literal>security_barrier</literal> flag has been set. For example,
+ the following view is insecure:
+<programlisting>
+CREATE VIEW phone_number AS
+ SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
+</programlisting>
+ This view might seem secure, since the rule system will rewrite any
+ <command>SELECT</command> from <literal>phone_number</literal> into a
+ <command>SELECT</command> from <literal>phone_data</literal> and add the
+ qualification that only entries where <literal>phone</literal> does not begin
+ with 412 are wanted. But if the user can create their own functions,
+ it is not difficult to convince the planner to execute the user-defined
+ function prior to the <function>NOT LIKE</function> expression.
+ For example:
+<programlisting>
+CREATE FUNCTION tricky(text, text) RETURNS bool AS $$
+BEGIN
+ RAISE NOTICE '% =&gt; %', $1, $2;
+ RETURN true;
+END;
+$$ LANGUAGE plpgsql COST 0.0000000000000000000001;
+
+SELECT * FROM phone_number WHERE tricky(person, phone);
+</programlisting>
+ Every person and phone number in the <literal>phone_data</literal> table will be
+ printed as a <literal>NOTICE</literal>, because the planner will choose to
+ execute the inexpensive <function>tricky</function> function before the
+ more expensive <function>NOT LIKE</function>. Even if the user is
+ prevented from defining new functions, built-in functions can be used in
+ similar attacks. (For example, most casting functions include their
+ input values in the error messages they produce.)
+</para>
+
+<para>
+ Similar considerations apply to update rules. In the examples of
+ the previous section, the owner of the tables in the example
+ database could grant the privileges <literal>SELECT</literal>,
+ <literal>INSERT</literal>, <literal>UPDATE</literal>, and <literal>DELETE</literal> on
+ the <literal>shoelace</literal> view to someone else, but only
+ <literal>SELECT</literal> on <literal>shoelace_log</literal>. The rule action to
+ write log entries will still be executed successfully, and that
+ other user could see the log entries. But they could not create fake
+ entries, nor could they manipulate or remove existing ones. In this
+ case, there is no possibility of subverting the rules by convincing
+ the planner to alter the order of operations, because the only rule
+ which references <literal>shoelace_log</literal> is an unqualified
+ <literal>INSERT</literal>. This might not be true in more complex scenarios.
+</para>
+
+<para>
+ When it is necessary for a view to provide row-level security, the
+ <literal>security_barrier</literal> attribute should be applied to
+ the view. This prevents maliciously-chosen functions and operators from
+ being passed values from rows until after the view has done its work. For
+ example, if the view shown above had been created like this, it would
+ be secure:
+<programlisting>
+CREATE VIEW phone_number WITH (security_barrier) AS
+ SELECT person, phone FROM phone_data WHERE phone NOT LIKE '412%';
+</programlisting>
+ Views created with the <literal>security_barrier</literal> may perform
+ far worse than views created without this option. In general, there is
+ no way to avoid this: the fastest possible plan must be rejected
+ if it may compromise security. For this reason, this option is not
+ enabled by default.
+</para>
+
+<para>
+ The query planner has more flexibility when dealing with functions that
+ have no side effects. Such functions are referred to as <literal>LEAKPROOF</literal>, and
+ include many simple, commonly used operators, such as many equality
+ operators. The query planner can safely allow such functions to be evaluated
+ at any point in the query execution process, since invoking them on rows
+ invisible to the user will not leak any information about the unseen rows.
+ Further, functions which do not take arguments or which are not passed any
+ arguments from the security barrier view do not have to be marked as
+ <literal>LEAKPROOF</literal> to be pushed down, as they never receive data
+ from the view. In contrast, a function that might throw an error depending
+ on the values received as arguments (such as one that throws an error in the
+ event of overflow or division by zero) is not leak-proof, and could provide
+ significant information about the unseen rows if applied before the security
+ view's row filters.
+</para>
+
+<para>
+ It is important to understand that even a view created with the
+ <literal>security_barrier</literal> option is intended to be secure only
+ in the limited sense that the contents of the invisible tuples will not be
+ passed to possibly-insecure functions. The user may well have other means
+ of making inferences about the unseen data; for example, they can see the
+ query plan using <command>EXPLAIN</command>, or measure the run time of
+ queries against the view. A malicious attacker might be able to infer
+ something about the amount of unseen data, or even gain some information
+ about the data distribution or most common values (since these things may
+ affect the run time of the plan; or even, since they are also reflected in
+ the optimizer statistics, the choice of plan). If these types of "covert
+ channel" attacks are of concern, it is probably unwise to grant any access
+ to the data at all.
+</para>
+</sect1>
+
+<sect1 id="rules-status">
+<title>Rules and Command Status</title>
+
+<para>
+ The <productname>PostgreSQL</productname> server returns a command
+ status string, such as <literal>INSERT 149592 1</literal>, for each
+ command it receives. This is simple enough when there are no rules
+ involved, but what happens when the query is rewritten by rules?
+</para>
+
+<para>
+ Rules affect the command status as follows:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ If there is no unconditional <literal>INSTEAD</literal> rule for the query, then
+ the originally given query will be executed, and its command
+ status will be returned as usual. (But note that if there were
+ any conditional <literal>INSTEAD</literal> rules, the negation of their qualifications
+ will have been added to the original query. This might reduce the
+ number of rows it processes, and if so the reported status will
+ be affected.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If there is any unconditional <literal>INSTEAD</literal> rule for the query, then
+ the original query will not be executed at all. In this case,
+ the server will return the command status for the last query
+ that was inserted by an <literal>INSTEAD</literal> rule (conditional or
+ unconditional) and is of the same command type
+ (<command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command>) as the original query. If no query
+ meeting those requirements is added by any rule, then the
+ returned command status shows the original query type and
+ zeroes for the row-count and OID fields.
+ </para>
+ </listitem>
+ </itemizedlist>
+</para>
+
+<para>
+ The programmer can ensure that any desired <literal>INSTEAD</literal> rule is the one
+ that sets the command status in the second case, by giving it the
+ alphabetically last rule name among the active rules, so that it
+ gets applied last.
+</para>
+</sect1>
+
+<sect1 id="rules-triggers">
+<title>Rules Versus Triggers</title>
+
+<indexterm zone="rules-triggers">
+ <primary>rule</primary>
+ <secondary sortas="Trigger">compared with triggers</secondary>
+</indexterm>
+
+<indexterm zone="rules-triggers">
+ <primary>trigger</primary>
+ <secondary sortas="Regeln">compared with rules</secondary>
+</indexterm>
+
+<para>
+ Many things that can be done using triggers can also be
+ implemented using the <productname>PostgreSQL</productname>
+ rule system. One of the things that cannot be implemented by
+ rules are some kinds of constraints, especially foreign keys. It is possible
+ to place a qualified rule that rewrites a command to <literal>NOTHING</literal>
+ if the value of a column does not appear in another table.
+ But then the data is silently thrown away and that's
+ not a good idea. If checks for valid values are required,
+ and in the case of an invalid value an error message should
+ be generated, it must be done by a trigger.
+</para>
+
+<para>
+ In this chapter, we focused on using rules to update views. All of
+ the update rule examples in this chapter can also be implemented
+ using <literal>INSTEAD OF</literal> triggers on the views. Writing such
+ triggers is often easier than writing rules, particularly if complex
+ logic is required to perform the update.
+</para>
+
+<para>
+ For the things that can be implemented by both, which is best
+ depends on the usage of the database.
+ A trigger is fired once for each affected row. A rule modifies
+ the query or generates an additional query. So if many
+ rows are affected in one statement, a rule issuing one extra
+ command is likely to be faster than a trigger that is
+ called for every single row and must re-determine what to do
+ many times. However, the trigger approach is conceptually far
+ simpler than the rule approach, and is easier for novices to get right.
+</para>
+
+<para>
+ Here we show an example of how the choice of rules versus triggers
+ plays out in one situation. There are two tables:
+
+<programlisting>
+CREATE TABLE computer (
+ hostname text, -- indexed
+ manufacturer text -- indexed
+);
+
+CREATE TABLE software (
+ software text, -- indexed
+ hostname text -- indexed
+);
+</programlisting>
+
+ Both tables have many thousands of rows and the indexes on
+ <structfield>hostname</structfield> are unique. The rule or trigger should
+ implement a constraint that deletes rows from <literal>software</literal>
+ that reference a deleted computer. The trigger would use this command:
+
+<programlisting>
+DELETE FROM software WHERE hostname = $1;
+</programlisting>
+
+ Since the trigger is called for each individual row deleted from
+ <literal>computer</literal>, it can prepare and save the plan for this
+ command and pass the <structfield>hostname</structfield> value in the
+ parameter. The rule would be written as:
+
+<programlisting>
+CREATE RULE computer_del AS ON DELETE TO computer
+ DO DELETE FROM software WHERE hostname = OLD.hostname;
+</programlisting>
+ </para>
+
+ <para>
+ Now we look at different types of deletes. In the case of a:
+
+<programlisting>
+DELETE FROM computer WHERE hostname = 'mypc.local.net';
+</programlisting>
+
+ the table <literal>computer</literal> is scanned by index (fast), and the
+ command issued by the trigger would also use an index scan (also fast).
+ The extra command from the rule would be:
+
+<programlisting>
+DELETE FROM software WHERE computer.hostname = 'mypc.local.net'
+ AND software.hostname = computer.hostname;
+</programlisting>
+
+ Since there are appropriate indexes set up, the planner
+ will create a plan of
+
+<literallayout class="monospaced">
+Nestloop
+ -&gt; Index Scan using comp_hostidx on computer
+ -&gt; Index Scan using soft_hostidx on software
+</literallayout>
+
+ So there would be not that much difference in speed between
+ the trigger and the rule implementation.
+ </para>
+
+ <para>
+ With the next delete we want to get rid of all the 2000 computers
+ where the <structfield>hostname</structfield> starts with
+ <literal>old</literal>. There are two possible commands to do that. One
+ is:
+
+<programlisting>
+DELETE FROM computer WHERE hostname &gt;= 'old'
+ AND hostname &lt; 'ole'
+</programlisting>
+
+ The command added by the rule will be:
+
+<programlisting>
+DELETE FROM software WHERE computer.hostname &gt;= 'old' AND computer.hostname &lt; 'ole'
+ AND software.hostname = computer.hostname;
+</programlisting>
+
+ with the plan
+
+<literallayout class="monospaced">
+Hash Join
+ -&gt; Seq Scan on software
+ -&gt; Hash
+ -&gt; Index Scan using comp_hostidx on computer
+</literallayout>
+
+ The other possible command is:
+
+<programlisting>
+DELETE FROM computer WHERE hostname ~ '^old';
+</programlisting>
+
+ which results in the following executing plan for the command
+ added by the rule:
+
+<literallayout class="monospaced">
+Nestloop
+ -&gt; Index Scan using comp_hostidx on computer
+ -&gt; Index Scan using soft_hostidx on software
+</literallayout>
+
+ This shows, that the planner does not realize that the
+ qualification for <structfield>hostname</structfield> in
+ <literal>computer</literal> could also be used for an index scan on
+ <literal>software</literal> when there are multiple qualification
+ expressions combined with <literal>AND</literal>, which is what it does
+ in the regular-expression version of the command. The trigger will
+ get invoked once for each of the 2000 old computers that have to be
+ deleted, and that will result in one index scan over
+ <literal>computer</literal> and 2000 index scans over
+ <literal>software</literal>. The rule implementation will do it with two
+ commands that use indexes. And it depends on the overall size of
+ the table <literal>software</literal> whether the rule will still be faster in the
+ sequential scan situation. 2000 command executions from the trigger over the SPI
+ manager take some time, even if all the index blocks will soon be in the cache.
+</para>
+
+<para>
+ The last command we look at is:
+
+<programlisting>
+DELETE FROM computer WHERE manufacturer = 'bim';
+</programlisting>
+
+ Again this could result in many rows to be deleted from
+ <literal>computer</literal>. So the trigger will again run many commands
+ through the executor. The command generated by the rule will be:
+
+<programlisting>
+DELETE FROM software WHERE computer.manufacturer = 'bim'
+ AND software.hostname = computer.hostname;
+</programlisting>
+
+ The plan for that command will again be the nested loop over two
+ index scans, only using a different index on <literal>computer</literal>:
+
+<programlisting>
+Nestloop
+ -&gt; Index Scan using comp_manufidx on computer
+ -&gt; Index Scan using soft_hostidx on software
+</programlisting>
+
+ In any of these cases, the extra commands from the rule system
+ will be more or less independent from the number of affected rows
+ in a command.
+</para>
+
+<para>
+ The summary is, rules will only be significantly slower than
+ triggers if their actions result in large and badly qualified
+ joins, a situation where the planner fails.
+</para>
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
new file mode 100644
index 0000000..2a34716
--- /dev/null
+++ b/doc/src/sgml/runtime.sgml
@@ -0,0 +1,2773 @@
+<!-- doc/src/sgml/runtime.sgml -->
+
+<chapter id="runtime">
+ <title>Server Setup and Operation</title>
+
+ <para>
+ This chapter discusses how to set up and run the database server,
+ and its interactions with the operating system.
+ </para>
+
+ <para>
+ The directions in this chapter assume that you are working with
+ plain <productname>PostgreSQL</productname> without any additional
+ infrastructure, for example a copy that you built from source
+ according to the directions in the preceding chapters.
+ If you are working with a pre-packaged or vendor-supplied
+ version of <productname>PostgreSQL</productname>, it is likely that
+ the packager has made special provisions for installing and starting
+ the database server according to your system's conventions.
+ Consult the package-level documentation for details.
+ </para>
+
+ <sect1 id="postgres-user">
+ <title>The <productname>PostgreSQL</productname> User Account</title>
+
+ <indexterm>
+ <primary>postgres user</primary>
+ </indexterm>
+
+ <para>
+ As with any server daemon that is accessible to the outside world,
+ it is advisable to run <productname>PostgreSQL</productname> under a
+ separate user account. This user account should only own the data
+ that is managed by the server, and should not be shared with other
+ daemons. (For example, using the user <literal>nobody</literal> is a bad
+ idea.) In particular, it is advisable that this user account not own
+ the <productname>PostgreSQL</productname> executable files, to ensure
+ that a compromised server process could not modify those executables.
+ </para>
+
+ <para>
+ Pre-packaged versions of <productname>PostgreSQL</productname> will
+ typically create a suitable user account automatically during
+ package installation.
+ </para>
+
+ <para>
+ To add a Unix user account to your system, look for a command
+ <command>useradd</command> or <command>adduser</command>. The user
+ name <systemitem>postgres</systemitem> is often used, and is assumed
+ throughout this book, but you can use another name if you like.
+ </para>
+ </sect1>
+
+ <sect1 id="creating-cluster">
+ <title>Creating a Database Cluster</title>
+
+ <indexterm>
+ <primary>database cluster</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>data area</primary>
+ <see>database cluster</see>
+ </indexterm>
+
+ <para>
+ Before you can do anything, you must initialize a database storage
+ area on disk. We call this a <firstterm>database cluster</firstterm>.
+ (The <acronym>SQL</acronym> standard uses the term catalog cluster.) A
+ database cluster is a collection of databases that is managed by a
+ single instance of a running database server. After initialization, a
+ database cluster will contain a database named <literal>postgres</literal>,
+ which is meant as a default database for use by utilities, users and third
+ party applications. The database server itself does not require the
+ <literal>postgres</literal> database to exist, but many external utility
+ programs assume it exists. There are two more databases created within
+ each cluster during initialization, named <literal>template1</literal>
+ and <literal>template0</literal>. As the names suggest, these will be
+ used as templates for subsequently-created databases; they should not be
+ used for actual work. (See <xref linkend="managing-databases"/> for
+ information about creating new databases within a cluster.)
+ </para>
+
+ <para>
+ In file system terms, a database cluster is a single directory
+ under which all data will be stored. We call this the <firstterm>data
+ directory</firstterm> or <firstterm>data area</firstterm>. It is
+ completely up to you where you choose to store your data. There is no
+ default, although locations such as
+ <filename>/usr/local/pgsql/data</filename> or
+ <filename>/var/lib/pgsql/data</filename> are popular.
+ The data directory must be initialized before being used, using the program
+ <xref linkend="app-initdb"/><indexterm><primary>initdb</primary></indexterm>
+ which is installed with <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ If you are using a pre-packaged version
+ of <productname>PostgreSQL</productname>, it may well have a specific
+ convention for where to place the data directory, and it may also
+ provide a script for creating the data directory. In that case you
+ should use that script in preference to
+ running <command>initdb</command> directly.
+ Consult the package-level documentation for details.
+ </para>
+
+ <para>
+ To initialize a database cluster manually,
+ run <command>initdb</command> and specify the desired
+ file system location of the database cluster with the
+ <option>-D</option> option, for example:
+<screen>
+<prompt>$</prompt> <userinput>initdb -D /usr/local/pgsql/data</userinput>
+</screen>
+ Note that you must execute this command while logged into the
+ <productname>PostgreSQL</productname> user account, which is
+ described in the previous section.
+ </para>
+
+ <tip>
+ <para>
+ As an alternative to the <option>-D</option> option, you can set
+ the environment variable <envar>PGDATA</envar>.
+ <indexterm><primary><envar>PGDATA</envar></primary></indexterm>
+ </para>
+ </tip>
+
+ <para>
+ Alternatively, you can run <command>initdb</command> via
+ the <xref linkend="app-pg-ctl"/>
+ program<indexterm><primary>pg_ctl</primary></indexterm> like so:
+<screen>
+<prompt>$</prompt> <userinput>pg_ctl -D /usr/local/pgsql/data initdb</userinput>
+</screen>
+ This may be more intuitive if you are
+ using <command>pg_ctl</command> for starting and stopping the
+ server (see <xref linkend="server-start"/>), so
+ that <command>pg_ctl</command> would be the sole command you use
+ for managing the database server instance.
+ </para>
+
+ <para>
+ <command>initdb</command> will attempt to create the directory you
+ specify if it does not already exist. Of course, this will fail if
+ <command>initdb</command> does not have permissions to write in the
+ parent directory. It's generally recommendable that the
+ <productname>PostgreSQL</productname> user own not just the data
+ directory but its parent directory as well, so that this should not
+ be a problem. If the desired parent directory doesn't exist either,
+ you will need to create it first, using root privileges if the
+ grandparent directory isn't writable. So the process might look
+ like this:
+<screen>
+root# <userinput>mkdir /usr/local/pgsql</userinput>
+root# <userinput>chown postgres /usr/local/pgsql</userinput>
+root# <userinput>su postgres</userinput>
+postgres$ <userinput>initdb -D /usr/local/pgsql/data</userinput>
+</screen>
+ </para>
+
+ <para>
+ <command>initdb</command> will refuse to run if the data directory
+ exists and already contains files; this is to prevent accidentally
+ overwriting an existing installation.
+ </para>
+
+ <para>
+ Because the data directory contains all the data stored in the
+ database, it is essential that it be secured from unauthorized
+ access. <command>initdb</command> therefore revokes access
+ permissions from everyone but the
+ <productname>PostgreSQL</productname> user, and optionally, group.
+ Group access, when enabled, is read-only. This allows an unprivileged
+ user in the same group as the cluster owner to take a backup of the
+ cluster data or perform other operations that only require read access.
+ </para>
+
+ <para>
+ Note that enabling or disabling group access on an existing cluster requires
+ the cluster to be shut down and the appropriate mode to be set on all
+ directories and files before restarting
+ <productname>PostgreSQL</productname>. Otherwise, a mix of modes might
+ exist in the data directory. For clusters that allow access only by the
+ owner, the appropriate modes are <literal>0700</literal> for directories
+ and <literal>0600</literal> for files. For clusters that also allow
+ reads by the group, the appropriate modes are <literal>0750</literal>
+ for directories and <literal>0640</literal> for files.
+ </para>
+
+ <para>
+ However, while the directory contents are secure, the default
+ client authentication setup allows any local user to connect to the
+ database and even become the database superuser. If you do not
+ trust other local users, we recommend you use one of
+ <command>initdb</command>'s <option>-W</option>, <option>--pwprompt</option>
+ or <option>--pwfile</option> options to assign a password to the
+ database superuser.<indexterm>
+ <primary>password</primary>
+ <secondary>of the superuser</secondary>
+ </indexterm>
+ Also, specify <option>-A scram-sha-256</option>
+ so that the default <literal>trust</literal> authentication
+ mode is not used; or modify the generated <filename>pg_hba.conf</filename>
+ file after running <command>initdb</command>, but
+ <emphasis>before</emphasis> you start the server for the first time. (Other
+ reasonable approaches include using <literal>peer</literal> authentication
+ or file system permissions to restrict connections. See <xref
+ linkend="client-authentication"/> for more information.)
+ </para>
+
+ <para>
+ <command>initdb</command> also initializes the default
+ locale<indexterm><primary>locale</primary></indexterm> for the database cluster.
+ Normally, it will just take the locale settings in the environment
+ and apply them to the initialized database. It is possible to
+ specify a different locale for the database; more information about
+ that can be found in <xref linkend="locale"/>. The default sort order used
+ within the particular database cluster is set by
+ <command>initdb</command>, and while you can create new databases using
+ different sort order, the order used in the template databases that initdb
+ creates cannot be changed without dropping and recreating them.
+ There is also a performance impact for using locales
+ other than <literal>C</literal> or <literal>POSIX</literal>. Therefore, it is
+ important to make this choice correctly the first time.
+ </para>
+
+ <para>
+ <command>initdb</command> also sets the default character set encoding
+ for the database cluster. Normally this should be chosen to match the
+ locale setting. For details see <xref linkend="multibyte"/>.
+ </para>
+
+ <para>
+ Non-<literal>C</literal> and non-<literal>POSIX</literal> locales rely on the
+ operating system's collation library for character set ordering.
+ This controls the ordering of keys stored in indexes. For this reason,
+ a cluster cannot switch to an incompatible collation library version,
+ either through snapshot restore, binary streaming replication, a
+ different operating system, or an operating system upgrade.
+ </para>
+
+ <sect2 id="creating-cluster-mount-points">
+ <title>Use of Secondary File Systems</title>
+
+ <indexterm zone="creating-cluster-mount-points">
+ <primary>file system mount points</primary>
+ </indexterm>
+
+ <para>
+ Many installations create their database clusters on file systems
+ (volumes) other than the machine's <quote>root</quote> volume. If you
+ choose to do this, it is not advisable to try to use the secondary
+ volume's topmost directory (mount point) as the data directory.
+ Best practice is to create a directory within the mount-point
+ directory that is owned by the <productname>PostgreSQL</productname>
+ user, and then create the data directory within that. This avoids
+ permissions problems, particularly for operations such
+ as <application>pg_upgrade</application>, and it also ensures clean failures if
+ the secondary volume is taken offline.
+ </para>
+
+ </sect2>
+
+ <sect2 id="creating-cluster-filesystem">
+ <title>File Systems</title>
+
+ <para>
+ Generally, any file system with POSIX semantics can be used for
+ PostgreSQL. Users prefer different file systems for a variety of reasons,
+ including vendor support, performance, and familiarity. Experience
+ suggests that, all other things being equal, one should not expect major
+ performance or behavior changes merely from switching file systems or
+ making minor file system configuration changes.
+ </para>
+
+ <sect3 id="creating-cluster-nfs">
+ <title>NFS</title>
+
+ <indexterm zone="creating-cluster-nfs">
+ <primary>NFS</primary>
+ </indexterm>
+
+ <para>
+ It is possible to use an <acronym>NFS</acronym> file system for storing
+ the <productname>PostgreSQL</productname> data directory.
+ <productname>PostgreSQL</productname> does nothing special for
+ <acronym>NFS</acronym> file systems, meaning it assumes
+ <acronym>NFS</acronym> behaves exactly like locally-connected drives.
+ <productname>PostgreSQL</productname> does not use any functionality that
+ is known to have nonstandard behavior on <acronym>NFS</acronym>, such as
+ file locking.
+ </para>
+
+ <para>
+ The only firm requirement for using <acronym>NFS</acronym> with
+ <productname>PostgreSQL</productname> is that the file system is mounted
+ using the <literal>hard</literal> option. With the
+ <literal>hard</literal> option, processes can <quote>hang</quote>
+ indefinitely if there are network problems, so this configuration will
+ require a careful monitoring setup. The <literal>soft</literal> option
+ will interrupt system calls in case of network problems, but
+ <productname>PostgreSQL</productname> will not repeat system calls
+ interrupted in this way, so any such interruption will result in an I/O
+ error being reported.
+ </para>
+
+ <para>
+ It is not necessary to use the <literal>sync</literal> mount option. The
+ behavior of the <literal>async</literal> option is sufficient, since
+ <productname>PostgreSQL</productname> issues <literal>fsync</literal>
+ calls at appropriate times to flush the write caches. (This is analogous
+ to how it works on a local file system.) However, it is strongly
+ recommended to use the <literal>sync</literal> export option on the NFS
+ <emphasis>server</emphasis> on systems where it exists (mainly Linux).
+ Otherwise, an <literal>fsync</literal> or equivalent on the NFS client is
+ not actually guaranteed to reach permanent storage on the server, which
+ could cause corruption similar to running with the parameter <xref
+ linkend="guc-fsync"/> off. The defaults of these mount and export
+ options differ between vendors and versions, so it is recommended to
+ check and perhaps specify them explicitly in any case to avoid any
+ ambiguity.
+ </para>
+
+ <para>
+ In some cases, an external storage product can be accessed either via NFS
+ or a lower-level protocol such as iSCSI. In the latter case, the storage
+ appears as a block device and any available file system can be created on
+ it. That approach might relieve the DBA from having to deal with some of
+ the idiosyncrasies of NFS, but of course the complexity of managing
+ remote storage then happens at other levels.
+ </para>
+ </sect3>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="server-start">
+ <title>Starting the Database Server</title>
+
+ <para>
+ Before anyone can access the database, you must start the database
+ server. The database server program is called
+ <command>postgres</command>.<indexterm><primary>postgres</primary></indexterm>
+ </para>
+
+ <para>
+ If you are using a pre-packaged version
+ of <productname>PostgreSQL</productname>, it almost certainly includes
+ provisions for running the server as a background task according to the
+ conventions of your operating system. Using the package's
+ infrastructure to start the server will be much less work than figuring
+ out how to do this yourself. Consult the package-level documentation
+ for details.
+ </para>
+
+ <para>
+ The bare-bones way to start the server manually is just to invoke
+ <command>postgres</command> directly, specifying the location of the
+ data directory with the <option>-D</option> option, for example:
+<screen>
+$ <userinput>postgres -D /usr/local/pgsql/data</userinput>
+</screen>
+ which will leave the server running in the foreground. This must be
+ done while logged into the <productname>PostgreSQL</productname> user
+ account. Without <option>-D</option>, the server will try to use
+ the data directory named by the environment variable <envar>PGDATA</envar>.
+ If that variable is not provided either, it will fail.
+ </para>
+
+ <para>
+ Normally it is better to start <command>postgres</command> in the
+ background. For this, use the usual Unix shell syntax:
+<screen>
+$ <userinput>postgres -D /usr/local/pgsql/data &gt;logfile 2&gt;&amp;1 &amp;</userinput>
+</screen>
+ It is important to store the server's <systemitem>stdout</systemitem> and
+ <systemitem>stderr</systemitem> output somewhere, as shown above. It will help
+ for auditing purposes and to diagnose problems. (See <xref
+ linkend="logfile-maintenance"/> for a more thorough discussion of log
+ file handling.)
+ </para>
+
+ <para>
+ The <command>postgres</command> program also takes a number of other
+ command-line options. For more information, see the
+ <xref linkend="app-postgres"/> reference page
+ and <xref linkend="runtime-config"/> below.
+ </para>
+
+ <para>
+ This shell syntax can get tedious quickly. Therefore the wrapper
+ program
+ <xref linkend="app-pg-ctl"/><indexterm><primary>pg_ctl</primary></indexterm>
+ is provided to simplify some tasks. For example:
+<programlisting>
+pg_ctl start -l logfile
+</programlisting>
+ will start the server in the background and put the output into the
+ named log file. The <option>-D</option> option has the same meaning
+ here as for <command>postgres</command>. <command>pg_ctl</command>
+ is also capable of stopping the server.
+ </para>
+
+ <para>
+ Normally, you will want to start the database server when the
+ computer boots.<indexterm>
+ <primary>booting</primary>
+ <secondary>starting the server during</secondary>
+ </indexterm>
+ Autostart scripts are operating-system-specific.
+ There are a few example scripts distributed with
+ <productname>PostgreSQL</productname> in the
+ <filename>contrib/start-scripts</filename> directory. Installing one will require
+ root privileges.
+ </para>
+
+ <para>
+ Different systems have different conventions for starting up daemons
+ at boot time. Many systems have a file
+ <filename>/etc/rc.local</filename> or
+ <filename>/etc/rc.d/rc.local</filename>. Others use <filename>init.d</filename> or
+ <filename>rc.d</filename> directories. Whatever you do, the server must be
+ run by the <productname>PostgreSQL</productname> user account
+ <emphasis>and not by root</emphasis> or any other user. Therefore you
+ probably should form your commands using
+ <literal>su postgres -c '...'</literal>. For example:
+<programlisting>
+su postgres -c 'pg_ctl start -D /usr/local/pgsql/data -l serverlog'
+</programlisting>
+ </para>
+
+ <para>
+ Here are a few more operating-system-specific suggestions. (In each
+ case be sure to use the proper installation directory and user
+ name where we show generic values.)
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ For <productname>FreeBSD</productname>, look at the file
+ <filename>contrib/start-scripts/freebsd</filename> in the
+ <productname>PostgreSQL</productname> source distribution.
+ <indexterm><primary>FreeBSD</primary><secondary>start script</secondary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>OpenBSD</productname>, add the following lines
+ to the file <filename>/etc/rc.local</filename>:
+ <indexterm><primary>OpenBSD</primary><secondary>start script</secondary></indexterm>
+<programlisting>
+if [ -x /usr/local/pgsql/bin/pg_ctl -a -x /usr/local/pgsql/bin/postgres ]; then
+ su -l postgres -c '/usr/local/pgsql/bin/pg_ctl start -s -l /var/postgresql/log -D /usr/local/pgsql/data'
+ echo -n ' postgresql'
+fi
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>Linux</productname> systems either add
+ <indexterm><primary>Linux</primary><secondary>start script</secondary></indexterm>
+<programlisting>
+/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data
+</programlisting>
+ to <filename>/etc/rc.d/rc.local</filename>
+ or <filename>/etc/rc.local</filename> or look at the file
+ <filename>contrib/start-scripts/linux</filename> in the
+ <productname>PostgreSQL</productname> source distribution.
+ </para>
+
+ <para>
+ When using <application>systemd</application>, you can use the following
+ service unit file (e.g.,
+ at <filename>/etc/systemd/system/postgresql.service</filename>):<indexterm><primary>systemd</primary></indexterm>
+<programlisting>
+[Unit]
+Description=PostgreSQL database server
+Documentation=man:postgres(1)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=notify
+User=postgres
+ExecStart=/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
+ExecReload=/bin/kill -HUP $MAINPID
+KillMode=mixed
+KillSignal=SIGINT
+TimeoutSec=infinity
+
+[Install]
+WantedBy=multi-user.target
+</programlisting>
+ Using <literal>Type=notify</literal> requires that the server binary was
+ built with <literal>configure --with-systemd</literal>.
+ </para>
+
+ <para>
+ Consider carefully the timeout
+ setting. <application>systemd</application> has a default timeout of 90
+ seconds as of this writing and will kill a process that does not report
+ readiness within that time. But a <productname>PostgreSQL</productname>
+ server that might have to perform crash recovery at startup could take
+ much longer to become ready. The suggested value
+ of <literal>infinity</literal> disables the timeout logic.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>NetBSD</productname>, use either the
+ <productname>FreeBSD</productname> or
+ <productname>Linux</productname> start scripts, depending on
+ preference.
+ <indexterm><primary>NetBSD</primary><secondary>start script</secondary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>Solaris</productname>, create a file called
+ <filename>/etc/init.d/postgresql</filename> that contains
+ the following line:
+ <indexterm><primary>Solaris</primary><secondary>start script</secondary></indexterm>
+<programlisting>
+su - postgres -c "/usr/local/pgsql/bin/pg_ctl start -l logfile -D /usr/local/pgsql/data"
+</programlisting>
+ Then, create a symbolic link to it in <filename>/etc/rc3.d</filename> as
+ <filename>S99postgresql</filename>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </para>
+
+ <para>
+ While the server is running, its
+ <acronym>PID</acronym> is stored in the file
+ <filename>postmaster.pid</filename> in the data directory. This is
+ used to prevent multiple server instances from
+ running in the same data directory and can also be used for
+ shutting down the server.
+ </para>
+
+ <sect2 id="server-start-failures">
+ <title>Server Start-up Failures</title>
+
+ <para>
+ There are several common reasons the server might fail to
+ start. Check the server's log file, or start it by hand (without
+ redirecting standard output or standard error) and see what error
+ messages appear. Below we explain some of the most common error
+ messages in more detail.
+ </para>
+
+ <para>
+<screen>
+LOG: could not bind IPv4 address "127.0.0.1": Address already in use
+HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
+FATAL: could not create any TCP/IP sockets
+</screen>
+ This usually means just what it suggests: you tried to start
+ another server on the same port where one is already running.
+ However, if the kernel error message is not <computeroutput>Address
+ already in use</computeroutput> or some variant of that, there might
+ be a different problem. For example, trying to start a server
+ on a reserved port number might draw something like:
+<screen>
+$ <userinput>postgres -p 666</userinput>
+LOG: could not bind IPv4 address "127.0.0.1": Permission denied
+HINT: Is another postmaster already running on port 666? If not, wait a few seconds and retry.
+FATAL: could not create any TCP/IP sockets
+</screen>
+ </para>
+
+ <para>
+ A message like:
+<screen>
+FATAL: could not create shared memory segment: Invalid argument
+DETAIL: Failed system call was shmget(key=5440001, size=4011376640, 03600).
+</screen>
+ probably means your kernel's limit on the size of shared memory is
+ smaller than the work area <productname>PostgreSQL</productname>
+ is trying to create (4011376640 bytes in this example).
+ This is only likely to happen if you have set <literal>shared_memory_type</literal>
+ to <literal>sysv</literal>. In that case, you
+ can try starting the server with a smaller-than-normal number of
+ buffers (<xref linkend="guc-shared-buffers"/>), or
+ reconfigure your kernel to increase the allowed shared memory
+ size. You might also see this message when trying to start multiple
+ servers on the same machine, if their total space requested
+ exceeds the kernel limit.
+ </para>
+
+ <para>
+ An error like:
+<screen>
+FATAL: could not create semaphores: No space left on device
+DETAIL: Failed system call was semget(5440126, 17, 03600).
+</screen>
+ does <emphasis>not</emphasis> mean you've run out of disk
+ space. It means your kernel's limit on the number of <systemitem
+ class="osname">System V</systemitem> semaphores is smaller than the number
+ <productname>PostgreSQL</productname> wants to create. As above,
+ you might be able to work around the problem by starting the
+ server with a reduced number of allowed connections
+ (<xref linkend="guc-max-connections"/>), but you'll eventually want to
+ increase the kernel limit.
+ </para>
+
+ <para>
+ Details about configuring <systemitem class="osname">System V</systemitem>
+ <acronym>IPC</acronym> facilities are given in <xref linkend="sysvipc"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="client-connection-problems">
+ <title>Client Connection Problems</title>
+
+ <para>
+ Although the error conditions possible on the client side are quite
+ varied and application-dependent, a few of them might be directly
+ related to how the server was started. Conditions other than
+ those shown below should be documented with the respective client
+ application.
+ </para>
+
+ <para>
+<screen>
+psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused
+ Is the server running on that host and accepting TCP/IP connections?
+</screen>
+ This is the generic <quote>I couldn't find a server to talk
+ to</quote> failure. It looks like the above when TCP/IP
+ communication is attempted. A common mistake is to forget to
+ configure the server to allow TCP/IP connections.
+ </para>
+
+ <para>
+ Alternatively, you might get this when attempting Unix-domain socket
+ communication to a local server:
+<screen>
+psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
+ Is the server running locally and accepting connections on that socket?
+</screen>
+ If the server is indeed running, check that the client's idea of the
+ socket path (here <literal>/tmp</literal>) agrees with the server's
+ <xref linkend="guc-unix-socket-directories"/> setting.
+ </para>
+
+ <para>
+ A connection failure message always shows the server address or socket
+ path name, which is useful in verifying that the client is trying to
+ connect to the right place. If there is in fact no server
+ listening there, the kernel error message will typically be either
+ <computeroutput>Connection refused</computeroutput> or
+ <computeroutput>No such file or directory</computeroutput>, as
+ illustrated. (It is important to realize that
+ <computeroutput>Connection refused</computeroutput> in this context
+ does <emphasis>not</emphasis> mean that the server got your
+ connection request and rejected it. That case will produce a
+ different message, as shown in <xref
+ linkend="client-authentication-problems"/>.) Other error messages
+ such as <computeroutput>Connection timed out</computeroutput> might
+ indicate more fundamental problems, like lack of network
+ connectivity, or a firewall blocking the connection.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="kernel-resources">
+ <title>Managing Kernel Resources</title>
+
+ <para>
+ <productname>PostgreSQL</productname> can sometimes exhaust various operating system
+ resource limits, especially when multiple copies of the server are running
+ on the same system, or in very large installations. This section explains
+ the kernel resources used by <productname>PostgreSQL</productname> and the steps you
+ can take to resolve problems related to kernel resource consumption.
+ </para>
+
+ <sect2 id="sysvipc">
+ <title>Shared Memory and Semaphores</title>
+
+ <indexterm zone="sysvipc">
+ <primary>shared memory</primary>
+ </indexterm>
+
+ <indexterm zone="sysvipc">
+ <primary>semaphores</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> requires the operating system to provide
+ inter-process communication (<acronym>IPC</acronym>) features, specifically
+ shared memory and semaphores. Unix-derived systems typically provide
+ <quote><systemitem class="osname">System V</systemitem></quote> <acronym>IPC</acronym>,
+ <quote><systemitem class="osname">POSIX</systemitem></quote> <acronym>IPC</acronym>, or both.
+ <systemitem class="osname">Windows</systemitem> has its own implementation of
+ these features and is not discussed here.
+ </para>
+
+ <para>
+ By default, <productname>PostgreSQL</productname> allocates
+ a very small amount of System V shared memory, as well as a much larger
+ amount of anonymous <function>mmap</function> shared memory.
+ Alternatively, a single large System V shared memory region can be used
+ (see <xref linkend="guc-shared-memory-type"/>).
+
+ In addition a significant number of semaphores, which can be either
+ System V or POSIX style, are created at server startup. Currently,
+ POSIX semaphores are used on Linux and FreeBSD systems while other
+ platforms use System V semaphores.
+ </para>
+
+ <para>
+ System V <acronym>IPC</acronym> features are typically constrained by
+ system-wide allocation limits.
+ When <productname>PostgreSQL</productname> exceeds one of these limits,
+ the server will refuse to start and
+ should leave an instructive error message describing the problem
+ and what to do about it. (See also <xref
+ linkend="server-start-failures"/>.) The relevant kernel
+ parameters are named consistently across different systems; <xref
+ linkend="sysvipc-parameters"/> gives an overview. The methods to set
+ them, however, vary. Suggestions for some platforms are given below.
+ </para>
+
+ <table id="sysvipc-parameters">
+ <title><systemitem class="osname">System V</systemitem> <acronym>IPC</acronym> Parameters</title>
+
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Description</entry>
+ <entry>Values needed to run one <productname>PostgreSQL</productname> instance</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><varname>SHMMAX</varname></entry>
+ <entry>Maximum size of shared memory segment (bytes)</entry>
+ <entry>at least 1kB, but the default is usually much higher</entry>
+ </row>
+
+ <row>
+ <entry><varname>SHMMIN</varname></entry>
+ <entry>Minimum size of shared memory segment (bytes)</entry>
+ <entry>1</entry>
+ </row>
+
+ <row>
+ <entry><varname>SHMALL</varname></entry>
+ <entry>Total amount of shared memory available (bytes or pages)</entry>
+ <entry>same as <varname>SHMMAX</varname> if bytes,
+ or <literal>ceil(SHMMAX/PAGE_SIZE)</literal> if pages,
+ plus room for other applications</entry>
+ </row>
+
+ <row>
+ <entry><varname>SHMSEG</varname></entry>
+ <entry>Maximum number of shared memory segments per process</entry>
+ <entry>only 1 segment is needed, but the default is much higher</entry>
+ </row>
+
+ <row>
+ <entry><varname>SHMMNI</varname></entry>
+ <entry>Maximum number of shared memory segments system-wide</entry>
+ <entry>like <varname>SHMSEG</varname> plus room for other applications</entry>
+ </row>
+
+ <row>
+ <entry><varname>SEMMNI</varname></entry>
+ <entry>Maximum number of semaphore identifiers (i.e., sets)</entry>
+ <entry>at least <literal>ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16)</literal> plus room for other applications</entry>
+ </row>
+
+ <row>
+ <entry><varname>SEMMNS</varname></entry>
+ <entry>Maximum number of semaphores system-wide</entry>
+ <entry><literal>ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17</literal> plus room for other applications</entry>
+ </row>
+
+ <row>
+ <entry><varname>SEMMSL</varname></entry>
+ <entry>Maximum number of semaphores per set</entry>
+ <entry>at least 17</entry>
+ </row>
+
+ <row>
+ <entry><varname>SEMMAP</varname></entry>
+ <entry>Number of entries in semaphore map</entry>
+ <entry>see text</entry>
+ </row>
+
+ <row>
+ <entry><varname>SEMVMX</varname></entry>
+ <entry>Maximum value of semaphore</entry>
+ <entry>at least 1000 (The default is often 32767; do not change unless necessary)</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <productname>PostgreSQL</productname> requires a few bytes of System V shared memory
+ (typically 48 bytes, on 64-bit platforms) for each copy of the server.
+ On most modern operating systems, this amount can easily be allocated.
+ However, if you are running many copies of the server or you explicitly
+ configure the server to use large amounts of System V shared memory (see
+ <xref linkend="guc-shared-memory-type"/> and <xref
+ linkend="guc-dynamic-shared-memory-type"/>), it may be necessary to
+ increase <varname>SHMALL</varname>, which is the total amount of System V shared
+ memory system-wide. Note that <varname>SHMALL</varname> is measured in pages
+ rather than bytes on many systems.
+ </para>
+
+ <para>
+ Less likely to cause problems is the minimum size for shared
+ memory segments (<varname>SHMMIN</varname>), which should be at most
+ approximately 32 bytes for <productname>PostgreSQL</productname> (it is
+ usually just 1). The maximum number of segments system-wide
+ (<varname>SHMMNI</varname>) or per-process (<varname>SHMSEG</varname>) are unlikely
+ to cause a problem unless your system has them set to zero.
+ </para>
+
+ <para>
+ When using System V semaphores,
+ <productname>PostgreSQL</productname> uses one semaphore per allowed connection
+ (<xref linkend="guc-max-connections"/>), allowed autovacuum worker process
+ (<xref linkend="guc-autovacuum-max-workers"/>) and allowed background
+ process (<xref linkend="guc-max-worker-processes"/>), in sets of 16.
+ Each such set will
+ also contain a 17th semaphore which contains a <quote>magic
+ number</quote>, to detect collision with semaphore sets used by
+ other applications. The maximum number of semaphores in the system
+ is set by <varname>SEMMNS</varname>, which consequently must be at least
+ as high as <varname>max_connections</varname> plus
+ <varname>autovacuum_max_workers</varname> plus <varname>max_wal_senders</varname>,
+ plus <varname>max_worker_processes</varname>, plus one extra for each 16
+ allowed connections plus workers (see the formula in <xref
+ linkend="sysvipc-parameters"/>). The parameter <varname>SEMMNI</varname>
+ determines the limit on the number of semaphore sets that can
+ exist on the system at one time. Hence this parameter must be at
+ least <literal>ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16)</literal>.
+ Lowering the number
+ of allowed connections is a temporary workaround for failures,
+ which are usually confusingly worded <quote>No space
+ left on device</quote>, from the function <function>semget</function>.
+ </para>
+
+ <para>
+ In some cases it might also be necessary to increase
+ <varname>SEMMAP</varname> to be at least on the order of
+ <varname>SEMMNS</varname>. If the system has this parameter
+ (many do not), it defines the size of the semaphore
+ resource map, in which each contiguous block of available semaphores
+ needs an entry. When a semaphore set is freed it is either added to
+ an existing entry that is adjacent to the freed block or it is
+ registered under a new map entry. If the map is full, the freed
+ semaphores get lost (until reboot). Fragmentation of the semaphore
+ space could over time lead to fewer available semaphores than there
+ should be.
+ </para>
+
+ <para>
+ Various other settings related to <quote>semaphore undo</quote>, such as
+ <varname>SEMMNU</varname> and <varname>SEMUME</varname>, do not affect
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ When using POSIX semaphores, the number of semaphores needed is the
+ same as for System V, that is one semaphore per allowed connection
+ (<xref linkend="guc-max-connections"/>), allowed autovacuum worker process
+ (<xref linkend="guc-autovacuum-max-workers"/>) and allowed background
+ process (<xref linkend="guc-max-worker-processes"/>).
+ On the platforms where this option is preferred, there is no specific
+ kernel limit on the number of POSIX semaphores.
+ </para>
+
+
+ <variablelist>
+ <varlistentry>
+ <term><systemitem class="osname">AIX</systemitem>
+ <indexterm><primary>AIX</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ It should not be necessary to do
+ any special configuration for such parameters as
+ <varname>SHMMAX</varname>, as it appears this is configured to
+ allow all memory to be used as shared memory. That is the
+ sort of configuration commonly used for other databases such
+ as <application>DB/2</application>.</para>
+
+ <para> It might, however, be necessary to modify the global
+ <command>ulimit</command> information in
+ <filename>/etc/security/limits</filename>, as the default hard
+ limits for file sizes (<varname>fsize</varname>) and numbers of
+ files (<varname>nofiles</varname>) might be too low.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><systemitem class="osname">FreeBSD</systemitem>
+ <indexterm><primary>FreeBSD</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The default shared memory settings are usually good enough, unless
+ you have set <literal>shared_memory_type</literal> to <literal>sysv</literal>.
+ System V semaphores are not used on this platform.
+ </para>
+
+ <para>
+ The default IPC settings can be changed using
+ the <command>sysctl</command> or
+ <command>loader</command> interfaces. The following
+ parameters can be set using <command>sysctl</command>:
+<screen>
+<prompt>#</prompt> <userinput>sysctl kern.ipc.shmall=32768</userinput>
+<prompt>#</prompt> <userinput>sysctl kern.ipc.shmmax=134217728</userinput>
+</screen>
+ To make these settings persist over reboots, modify
+ <filename>/etc/sysctl.conf</filename>.
+ </para>
+
+ <para>
+ If you have set <literal>shared_memory_type</literal> to
+ <literal>sysv</literal>, you might also want to configure your kernel
+ to lock System V shared memory into RAM and prevent it from being paged
+ out to swap. This can be accomplished using the <command>sysctl</command>
+ setting <literal>kern.ipc.shm_use_phys</literal>.
+ </para>
+
+ <para>
+ If running in a FreeBSD jail, you should set its
+ <literal>sysvshm</literal> parameter to <literal>new</literal>, so that
+ it has its own separate System V shared memory namespace.
+ (Before FreeBSD 11.0, it was necessary to enable shared access to
+ the host's IPC namespace from jails, and take measures to avoid
+ collisions.)
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem class="osname">NetBSD</systemitem>
+ <indexterm><primary>NetBSD</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The default shared memory settings are usually good enough, unless
+ you have set <literal>shared_memory_type</literal> to <literal>sysv</literal>.
+ You will usually want to increase <literal>kern.ipc.semmni</literal>
+ and <literal>kern.ipc.semmns</literal>,
+ as <systemitem class="osname">NetBSD</systemitem>'s default settings
+ for these are uncomfortably small.
+ </para>
+
+ <para>
+ IPC parameters can be adjusted using <command>sysctl</command>,
+ for example:
+<screen>
+<prompt>#</prompt> <userinput>sysctl -w kern.ipc.semmni=100</userinput>
+</screen>
+ To make these settings persist over reboots, modify
+ <filename>/etc/sysctl.conf</filename>.
+ </para>
+
+ <para>
+ If you have set <literal>shared_memory_type</literal> to
+ <literal>sysv</literal>, you might also want to configure your kernel
+ to lock System V shared memory into RAM and prevent it from being paged
+ out to swap. This can be accomplished using the <command>sysctl</command>
+ setting <literal>kern.ipc.shm_use_phys</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem class="osname">OpenBSD</systemitem>
+ <indexterm><primary>OpenBSD</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The default shared memory settings are usually good enough, unless
+ you have set <literal>shared_memory_type</literal> to <literal>sysv</literal>.
+ You will usually want to
+ increase <literal>kern.seminfo.semmni</literal>
+ and <literal>kern.seminfo.semmns</literal>,
+ as <systemitem class="osname">OpenBSD</systemitem>'s default settings
+ for these are uncomfortably small.
+ </para>
+
+ <para>
+ IPC parameters can be adjusted using <command>sysctl</command>,
+ for example:
+<screen>
+<prompt>#</prompt> <userinput>sysctl kern.seminfo.semmni=100</userinput>
+</screen>
+ To make these settings persist over reboots, modify
+ <filename>/etc/sysctl.conf</filename>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem class="osname">HP-UX</systemitem>
+ <indexterm><primary>HP-UX</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The default settings tend to suffice for normal installations.
+ </para>
+ <para>
+ <acronym>IPC</acronym> parameters can be set in the <application>System
+ Administration Manager</application> (<acronym>SAM</acronym>) under
+ <menuchoice><guimenu>Kernel
+ Configuration</guimenu><guimenuitem>Configurable Parameters</guimenuitem></menuchoice>. Choose
+ <guibutton>Create A New Kernel</guibutton> when you're done.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><systemitem class="osname">Linux</systemitem>
+ <indexterm><primary>Linux</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The default shared memory settings are usually good enough, unless
+ you have set <literal>shared_memory_type</literal> to <literal>sysv</literal>,
+ and even then only on older kernel versions that shipped with low defaults.
+ System V semaphores are not used on this platform.
+ </para>
+
+ <para>
+ The shared memory size settings can be changed via the
+ <command>sysctl</command> interface. For example, to allow 16 GB:
+<screen>
+<prompt>$</prompt> <userinput>sysctl -w kernel.shmmax=17179869184</userinput>
+<prompt>$</prompt> <userinput>sysctl -w kernel.shmall=4194304</userinput>
+</screen>
+ To make these settings persist over reboots, see
+ <filename>/etc/sysctl.conf</filename>.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term><systemitem class="osname">macOS</systemitem>
+ <indexterm><primary>macOS</primary><secondary>IPC configuration</secondary></indexterm>
+ </term>
+ <listitem>
+ <para>
+ The default shared memory and semaphore settings are usually good enough, unless
+ you have set <literal>shared_memory_type</literal> to <literal>sysv</literal>.
+ </para>
+ <para>
+ The recommended method for configuring shared memory in macOS
+ is to create a file named <filename>/etc/sysctl.conf</filename>,
+ containing variable assignments such as:
+<programlisting>
+kern.sysv.shmmax=4194304
+kern.sysv.shmmin=1
+kern.sysv.shmmni=32
+kern.sysv.shmseg=8
+kern.sysv.shmall=1024
+</programlisting>
+ Note that in some macOS versions,
+ <emphasis>all five</emphasis> shared-memory parameters must be set in
+ <filename>/etc/sysctl.conf</filename>, else the values will be ignored.
+ </para>
+
+ <para>
+ <varname>SHMMAX</varname> can only be set to a multiple of 4096.
+ </para>
+
+ <para>
+ <varname>SHMALL</varname> is measured in 4 kB pages on this platform.
+ </para>
+
+ <para>
+ It is possible to change all but <varname>SHMMNI</varname> on the fly, using
+ <application>sysctl</application>. But it's still best to set up your preferred
+ values via <filename>/etc/sysctl.conf</filename>, so that the values will be
+ kept across reboots.
+ </para>
+
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem class="osname">Solaris</systemitem></term>
+ <term><systemitem class="osname">illumos</systemitem></term>
+ <listitem>
+ <para>
+ The default shared memory and semaphore settings are usually good enough for most
+ <productname>PostgreSQL</productname> applications. Solaris defaults
+ to a <varname>SHMMAX</varname> of one-quarter of system <acronym>RAM</acronym>.
+ To further adjust this setting, use a project setting associated
+ with the <literal>postgres</literal> user. For example, run the
+ following as <literal>root</literal>:
+<programlisting>
+projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres
+</programlisting>
+ </para>
+
+ <para>
+ This command adds the <literal>user.postgres</literal> project and
+ sets the shared memory maximum for the <literal>postgres</literal>
+ user to 8GB, and takes effect the next time that user logs
+ in, or when you restart <productname>PostgreSQL</productname> (not reload).
+ The above assumes that <productname>PostgreSQL</productname> is run by
+ the <literal>postgres</literal> user in the <literal>postgres</literal>
+ group. No server reboot is required.
+ </para>
+
+ <para>
+ Other recommended kernel setting changes for database servers which will
+ have a large number of connections are:
+<programlisting>
+project.max-shm-ids=(priv,32768,deny)
+project.max-sem-ids=(priv,4096,deny)
+project.max-msg-ids=(priv,4096,deny)
+</programlisting>
+ </para>
+
+ <para>
+ Additionally, if you are running <productname>PostgreSQL</productname>
+ inside a zone, you may need to raise the zone resource usage
+ limits as well. See "Chapter2: Projects and Tasks" in the
+ <citetitle>System Administrator's Guide</citetitle> for more
+ information on <literal>projects</literal> and <command>prctl</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="systemd-removeipc">
+ <title>systemd RemoveIPC</title>
+
+ <indexterm>
+ <primary>systemd</primary>
+ <secondary>RemoveIPC</secondary>
+ </indexterm>
+
+ <para>
+ If <productname>systemd</productname> is in use, some care must be taken
+ that IPC resources (including shared memory) are not prematurely
+ removed by the operating system. This is especially of concern when
+ installing PostgreSQL from source. Users of distribution packages of
+ PostgreSQL are less likely to be affected, as
+ the <literal>postgres</literal> user is then normally created as a system
+ user.
+ </para>
+
+ <para>
+ The setting <literal>RemoveIPC</literal>
+ in <filename>logind.conf</filename> controls whether IPC objects are
+ removed when a user fully logs out. System users are exempt. This
+ setting defaults to on in stock <productname>systemd</productname>, but
+ some operating system distributions default it to off.
+ </para>
+
+ <para>
+ A typical observed effect when this setting is on is that shared memory
+ objects used for parallel query execution are removed at apparently random
+ times, leading to errors and warnings while attempting to open and remove
+ them, like
+<screen>
+WARNING: could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory
+</screen>
+ Different types of IPC objects (shared memory vs. semaphores, System V
+ vs. POSIX) are treated slightly differently
+ by <productname>systemd</productname>, so one might observe that some IPC
+ resources are not removed in the same way as others. But it is not
+ advisable to rely on these subtle differences.
+ </para>
+
+ <para>
+ A <quote>user logging out</quote> might happen as part of a maintenance
+ job or manually when an administrator logs in as
+ the <literal>postgres</literal> user or something similar, so it is hard
+ to prevent in general.
+ </para>
+
+ <para>
+ What is a <quote>system user</quote> is determined
+ at <productname>systemd</productname> compile time from
+ the <symbol>SYS_UID_MAX</symbol> setting
+ in <filename>/etc/login.defs</filename>.
+ </para>
+
+ <para>
+ Packaging and deployment scripts should be careful to create
+ the <literal>postgres</literal> user as a system user by
+ using <literal>useradd -r</literal>, <literal>adduser --system</literal>,
+ or equivalent.
+ </para>
+
+ <para>
+ Alternatively, if the user account was created incorrectly or cannot be
+ changed, it is recommended to set
+<programlisting>
+RemoveIPC=no
+</programlisting>
+ in <filename>/etc/systemd/logind.conf</filename> or another appropriate
+ configuration file.
+ </para>
+
+ <caution>
+ <para>
+ At least one of these two things has to be ensured, or the PostgreSQL
+ server will be very unreliable.
+ </para>
+ </caution>
+ </sect2>
+
+ <sect2>
+ <title>Resource Limits</title>
+
+ <para>
+ Unix-like operating systems enforce various kinds of resource limits
+ that might interfere with the operation of your
+ <productname>PostgreSQL</productname> server. Of particular
+ importance are limits on the number of processes per user, the
+ number of open files per process, and the amount of memory available
+ to each process. Each of these have a <quote>hard</quote> and a
+ <quote>soft</quote> limit. The soft limit is what actually counts
+ but it can be changed by the user up to the hard limit. The hard
+ limit can only be changed by the root user. The system call
+ <function>setrlimit</function> is responsible for setting these
+ parameters. The shell's built-in command <command>ulimit</command>
+ (Bourne shells) or <command>limit</command> (<application>csh</application>) is
+ used to control the resource limits from the command line. On
+ BSD-derived systems the file <filename>/etc/login.conf</filename>
+ controls the various resource limits set during login. See the
+ operating system documentation for details. The relevant
+ parameters are <varname>maxproc</varname>,
+ <varname>openfiles</varname>, and <varname>datasize</varname>. For
+ example:
+<programlisting>
+default:\
+...
+ :datasize-cur=256M:\
+ :maxproc-cur=256:\
+ :openfiles-cur=256:\
+...
+</programlisting>
+ (<literal>-cur</literal> is the soft limit. Append
+ <literal>-max</literal> to set the hard limit.)
+ </para>
+
+ <para>
+ Kernels can also have system-wide limits on some resources.
+ <itemizedlist>
+ <listitem>
+ <para>
+ On <productname>Linux</productname> the kernel parameter
+ <varname>fs.file-max</varname> determines the maximum number of open
+ files that the kernel will support. It can be changed with
+ <literal>sysctl -w fs.file-max=<replaceable>N</replaceable></literal>.
+ To make the setting persist across reboots, add an assignment
+ in <filename>/etc/sysctl.conf</filename>.
+ The maximum limit of files per process is fixed at the time the
+ kernel is compiled; see
+ <filename>/usr/src/linux/Documentation/proc.txt</filename> for
+ more information.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> server uses one process
+ per connection so you should provide for at least as many processes
+ as allowed connections, in addition to what you need for the rest
+ of your system. This is usually not a problem but if you run
+ several servers on one machine things might get tight.
+ </para>
+
+ <para>
+ The factory default limit on open files is often set to
+ <quote>socially friendly</quote> values that allow many users to
+ coexist on a machine without using an inappropriate fraction of
+ the system resources. If you run many servers on a machine this
+ is perhaps what you want, but on dedicated servers you might want to
+ raise this limit.
+ </para>
+
+ <para>
+ On the other side of the coin, some systems allow individual
+ processes to open large numbers of files; if more than a few
+ processes do so then the system-wide limit can easily be exceeded.
+ If you find this happening, and you do not want to alter the
+ system-wide limit, you can set <productname>PostgreSQL</productname>'s <xref
+ linkend="guc-max-files-per-process"/> configuration parameter to
+ limit the consumption of open files.
+ </para>
+
+ <para>
+ Another kernel limit that may be of concern when supporting large
+ numbers of client connections is the maximum socket connection queue
+ length. If more than that many connection requests arrive within a very
+ short period, some may get rejected before the postmaster can service
+ the requests, with those clients receiving unhelpful connection failure
+ errors such as <quote>Resource temporarily unavailable</quote> or
+ <quote>Connection refused</quote>. The default queue length limit is 128
+ on many platforms. To raise it, adjust the appropriate kernel parameter
+ via <application>sysctl</application>, then restart the postmaster.
+ The parameter is variously named <varname>net.core.somaxconn</varname>
+ on Linux, <varname>kern.ipc.soacceptqueue</varname> on newer FreeBSD,
+ and <varname>kern.ipc.somaxconn</varname> on macOS and other BSD
+ variants.
+ </para>
+ </sect2>
+
+ <sect2 id="linux-memory-overcommit">
+ <title>Linux Memory Overcommit</title>
+
+ <indexterm>
+ <primary>memory overcommit</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>OOM</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>overcommit</primary>
+ </indexterm>
+
+ <para>
+ The default virtual memory behavior on Linux is not
+ optimal for <productname>PostgreSQL</productname>. Because of the
+ way that the kernel implements memory overcommit, the kernel might
+ terminate the <productname>PostgreSQL</productname> postmaster (the
+ supervisor server process) if the memory demands of either
+ <productname>PostgreSQL</productname> or another process cause the
+ system to run out of virtual memory.
+ </para>
+
+ <para>
+ If this happens, you will see a kernel message that looks like
+ this (consult your system documentation and configuration on where
+ to look for such a message):
+<programlisting>
+Out of Memory: Killed process 12345 (postgres).
+</programlisting>
+ This indicates that the <filename>postgres</filename> process
+ has been terminated due to memory pressure.
+ Although existing database connections will continue to function
+ normally, no new connections will be accepted. To recover,
+ <productname>PostgreSQL</productname> will need to be restarted.
+ </para>
+
+ <para>
+ One way to avoid this problem is to run
+ <productname>PostgreSQL</productname> on a machine where you can
+ be sure that other processes will not run the machine out of
+ memory. If memory is tight, increasing the swap space of the
+ operating system can help avoid the problem, because the
+ out-of-memory (OOM) killer is invoked only when physical memory and
+ swap space are exhausted.
+ </para>
+
+ <para>
+ If <productname>PostgreSQL</productname> itself is the cause of the
+ system running out of memory, you can avoid the problem by changing
+ your configuration. In some cases, it may help to lower memory-related
+ configuration parameters, particularly
+ <link linkend="guc-shared-buffers"><varname>shared_buffers</varname></link>,
+ <link linkend="guc-work-mem"><varname>work_mem</varname></link>, and
+ <link linkend="guc-hash-mem-multiplier"><varname>hash_mem_multiplier</varname></link>.
+ In other cases, the problem may be caused by allowing too many
+ connections to the database server itself. In many cases, it may
+ be better to reduce
+ <link linkend="guc-max-connections"><varname>max_connections</varname></link>
+ and instead make use of external connection-pooling software.
+ </para>
+
+ <para>
+ It is possible to modify the
+ kernel's behavior so that it will not <quote>overcommit</quote> memory.
+ Although this setting will not prevent the <ulink
+ url="https://lwn.net/Articles/104179/">OOM killer</ulink> from being invoked
+ altogether, it will lower the chances significantly and will therefore
+ lead to more robust system behavior. This is done by selecting strict
+ overcommit mode via <command>sysctl</command>:
+<programlisting>
+sysctl -w vm.overcommit_memory=2
+</programlisting>
+ or placing an equivalent entry in <filename>/etc/sysctl.conf</filename>.
+ You might also wish to modify the related setting
+ <varname>vm.overcommit_ratio</varname>. For details see the kernel documentation
+ file <ulink url="https://www.kernel.org/doc/Documentation/vm/overcommit-accounting"></ulink>.
+ </para>
+
+ <para>
+ Another approach, which can be used with or without altering
+ <varname>vm.overcommit_memory</varname>, is to set the process-specific
+ <firstterm>OOM score adjustment</firstterm> value for the postmaster process to
+ <literal>-1000</literal>, thereby guaranteeing it will not be targeted by the OOM
+ killer. The simplest way to do this is to execute
+<programlisting>
+echo -1000 > /proc/self/oom_score_adj
+</programlisting>
+ in the postmaster's startup script just before invoking the postmaster.
+ Note that this action must be done as root, or it will have no effect;
+ so a root-owned startup script is the easiest place to do it. If you
+ do this, you should also set these environment variables in the startup
+ script before invoking the postmaster:
+<programlisting>
+export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
+export PG_OOM_ADJUST_VALUE=0
+</programlisting>
+ These settings will cause postmaster child processes to run with the
+ normal OOM score adjustment of zero, so that the OOM killer can still
+ target them at need. You could use some other value for
+ <envar>PG_OOM_ADJUST_VALUE</envar> if you want the child processes to run
+ with some other OOM score adjustment. (<envar>PG_OOM_ADJUST_VALUE</envar>
+ can also be omitted, in which case it defaults to zero.) If you do not
+ set <envar>PG_OOM_ADJUST_FILE</envar>, the child processes will run with the
+ same OOM score adjustment as the postmaster, which is unwise since the
+ whole point is to ensure that the postmaster has a preferential setting.
+ </para>
+
+ </sect2>
+
+ <sect2 id="linux-huge-pages">
+ <title>Linux Huge Pages</title>
+
+ <para>
+ Using huge pages reduces overhead when using large contiguous chunks of
+ memory, as <productname>PostgreSQL</productname> does, particularly when
+ using large values of <xref linkend="guc-shared-buffers"/>. To use this
+ feature in <productname>PostgreSQL</productname> you need a kernel
+ with <varname>CONFIG_HUGETLBFS=y</varname> and
+ <varname>CONFIG_HUGETLB_PAGE=y</varname>. You will also have to configure
+ the operating system to provide enough huge pages of the desired size.
+ To determine the number of huge pages needed, use the
+ <command>postgres</command> command to see the value of
+ <xref linkend="guc-shared-memory-size-in-huge-pages"/>. Note that the
+ server must be shut down to view this runtime-computed parameter.
+ This might look like:
+<programlisting>
+$ <userinput>postgres -D $PGDATA -C shared_memory_size_in_huge_pages</userinput>
+3170
+$ <userinput>grep ^Hugepagesize /proc/meminfo</userinput>
+Hugepagesize: 2048 kB
+$ <userinput>ls /sys/kernel/mm/hugepages</userinput>
+hugepages-1048576kB hugepages-2048kB
+</programlisting>
+
+ In this example the default is 2MB, but you can also explicitly request
+ either 2MB or 1GB with <xref linkend="guc-huge-page-size"/> to adapt
+ the number of pages calculated by
+ <varname>shared_memory_size_in_huge_pages</varname>.
+
+ While we need at least <literal>3170</literal> huge pages in this example,
+ a larger setting would be appropriate if other programs on the machine
+ also need huge pages.
+ We can set this with:
+<programlisting>
+# <userinput>sysctl -w vm.nr_hugepages=3170</userinput>
+</programlisting>
+ Don't forget to add this setting to <filename>/etc/sysctl.conf</filename>
+ so that it is reapplied after reboots. For non-default huge page sizes,
+ we can instead use:
+<programlisting>
+# <userinput>echo 3170 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages</userinput>
+</programlisting>
+ It is also possible to provide these settings at boot time using
+ kernel parameters such as <literal>hugepagesz=2M hugepages=3170</literal>.
+ </para>
+
+ <para>
+ Sometimes the kernel is not able to allocate the desired number of huge
+ pages immediately due to fragmentation, so it might be necessary
+ to repeat the command or to reboot. (Immediately after a reboot, most of
+ the machine's memory should be available to convert into huge pages.)
+ To verify the huge page allocation situation for a given size, use:
+<programlisting>
+$ <userinput>cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages</userinput>
+</programlisting>
+ </para>
+
+ <para>
+ It may also be necessary to give the database server's operating system
+ user permission to use huge pages by setting
+ <varname>vm.hugetlb_shm_group</varname> via <application>sysctl</application>, and/or
+ give permission to lock memory with <command>ulimit -l</command>.
+ </para>
+
+ <para>
+ The default behavior for huge pages in
+ <productname>PostgreSQL</productname> is to use them when possible, with
+ the system's default huge page size, and
+ to fall back to normal pages on failure. To enforce the use of huge
+ pages, you can set <xref linkend="guc-huge-pages"/>
+ to <literal>on</literal> in <filename>postgresql.conf</filename>.
+ Note that with this setting <productname>PostgreSQL</productname> will fail to
+ start if not enough huge pages are available.
+ </para>
+
+ <para>
+ For a detailed description of the <productname>Linux</productname> huge
+ pages feature have a look
+ at <ulink url="https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt"></ulink>.
+ </para>
+
+ </sect2>
+ </sect1>
+
+
+ <sect1 id="server-shutdown">
+ <title>Shutting Down the Server</title>
+
+ <indexterm zone="server-shutdown">
+ <primary>shutdown</primary>
+ </indexterm>
+
+ <para>
+ There are several ways to shut down the database server.
+ Under the hood, they all reduce to sending a signal to the supervisor
+ <command>postgres</command> process.
+ </para>
+
+ <para>
+ If you are using a pre-packaged version
+ of <productname>PostgreSQL</productname>, and you used its provisions
+ for starting the server, then you should also use its provisions for
+ stopping the server. Consult the package-level documentation for
+ details.
+ </para>
+
+ <para>
+ When managing the server directly, you can control the type of shutdown
+ by sending different signals to the <command>postgres</command>
+ process:
+
+ <variablelist>
+ <varlistentry>
+ <term><systemitem>SIGTERM</systemitem><indexterm><primary>SIGTERM</primary></indexterm></term>
+ <listitem>
+ <para>
+ This is the <firstterm>Smart Shutdown</firstterm> mode.
+ After receiving <systemitem>SIGTERM</systemitem>, the server
+ disallows new connections, but lets existing sessions end their
+ work normally. It shuts down only after all of the sessions terminate.
+ If the server is in recovery when a smart
+ shutdown is requested, recovery and streaming replication will be
+ stopped only after all regular sessions have terminated.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem>SIGINT</systemitem><indexterm><primary>SIGINT</primary></indexterm></term>
+ <listitem>
+ <para>
+ This is the <firstterm>Fast Shutdown</firstterm> mode.
+ The server disallows new connections and sends all existing
+ server processes <systemitem>SIGTERM</systemitem>, which will cause them
+ to abort their current transactions and exit promptly. It then
+ waits for all server processes to exit and finally shuts down.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><systemitem>SIGQUIT</systemitem><indexterm><primary>SIGQUIT</primary></indexterm></term>
+ <listitem>
+ <para>
+ This is the <firstterm>Immediate Shutdown</firstterm> mode.
+ The server will send <systemitem>SIGQUIT</systemitem> to all child
+ processes and wait for them to terminate. If any do not terminate
+ within 5 seconds, they will be sent <systemitem>SIGKILL</systemitem>.
+ The supervisor server process exits as soon as all child processes have
+ exited, without doing normal database shutdown processing.
+ This will lead to recovery (by
+ replaying the WAL log) upon next start-up. This is recommended
+ only in emergencies.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ The <xref linkend="app-pg-ctl"/> program provides a convenient
+ interface for sending these signals to shut down the server.
+ Alternatively, you can send the signal directly using <command>kill</command>
+ on non-Windows systems.
+ The <acronym>PID</acronym> of the <command>postgres</command> process can be
+ found using the <command>ps</command> program, or from the file
+ <filename>postmaster.pid</filename> in the data directory. For
+ example, to do a fast shutdown:
+<screen>
+$ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput>
+</screen>
+ </para>
+
+ <important>
+ <para>
+ It is best not to use <systemitem>SIGKILL</systemitem> to shut down the
+ server. Doing so will prevent the server from releasing shared memory and
+ semaphores. Furthermore, <systemitem>SIGKILL</systemitem> kills
+ the <command>postgres</command> process without letting it relay the
+ signal to its subprocesses, so it might be necessary to kill the
+ individual subprocesses by hand as well.
+ </para>
+ </important>
+
+ <para>
+ To terminate an individual session while allowing other sessions to
+ continue, use <function>pg_terminate_backend()</function> (see <xref
+ linkend="functions-admin-signal-table"/>) or send a
+ <systemitem>SIGTERM</systemitem> signal to the child process associated with
+ the session.
+ </para>
+ </sect1>
+
+ <sect1 id="upgrading">
+ <title>Upgrading a <productname>PostgreSQL</productname> Cluster</title>
+
+ <indexterm zone="upgrading">
+ <primary>upgrading</primary>
+ </indexterm>
+
+ <indexterm zone="upgrading">
+ <primary>version</primary>
+ <secondary>compatibility</secondary>
+ </indexterm>
+
+ <para>
+ This section discusses how to upgrade your database data from one
+ <productname>PostgreSQL</productname> release to a newer one.
+ </para>
+
+ <para>
+ Current <productname>PostgreSQL</productname> version numbers consist of a
+ major and a minor version number. For example, in the version number 10.1,
+ the 10 is the major version number and the 1 is the minor version number,
+ meaning this would be the first minor release of the major release 10. For
+ releases before <productname>PostgreSQL</productname> version 10.0, version
+ numbers consist of three numbers, for example, 9.5.3. In those cases, the
+ major version consists of the first two digit groups of the version number,
+ e.g., 9.5, and the minor version is the third number, e.g., 3, meaning this
+ would be the third minor release of the major release 9.5.
+ </para>
+
+ <para>
+ Minor releases never change the internal storage format and are always
+ compatible with earlier and later minor releases of the same major version
+ number. For example, version 10.1 is compatible with version 10.0 and
+ version 10.6. Similarly, for example, 9.5.3 is compatible with 9.5.0,
+ 9.5.1, and 9.5.6. To update between compatible versions, you simply
+ replace the executables while the server is down and restart the server.
+ The data directory remains unchanged &mdash; minor upgrades are that
+ simple.
+ </para>
+
+ <para>
+ For <emphasis>major</emphasis> releases of <productname>PostgreSQL</productname>, the
+ internal data storage format is subject to change, thus complicating
+ upgrades. The traditional method for moving data to a new major version
+ is to dump and restore the database, though this can be slow. A
+ faster method is <xref linkend="pgupgrade"/>. Replication methods are
+ also available, as discussed below.
+ (If you are using a pre-packaged version
+ of <productname>PostgreSQL</productname>, it may provide scripts to
+ assist with major version upgrades. Consult the package-level
+ documentation for details.)
+ </para>
+
+ <para>
+ New major versions also typically introduce some user-visible
+ incompatibilities, so application programming changes might be required.
+ All user-visible changes are listed in the release notes (<xref
+ linkend="release"/>); pay particular attention to the section
+ labeled "Migration". Though you can upgrade from one major version
+ to another without upgrading to intervening versions, you should read
+ the major release notes of all intervening versions.
+ </para>
+
+ <para>
+ Cautious users will want to test their client applications on the new
+ version before switching over fully; therefore, it's often a good idea to
+ set up concurrent installations of old and new versions. When
+ testing a <productname>PostgreSQL</productname> major upgrade, consider the
+ following categories of possible changes:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Administration</term>
+ <listitem>
+ <para>
+ The capabilities available for administrators to monitor and control
+ the server often change and improve in each major release.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SQL</term>
+ <listitem>
+ <para>
+ Typically this includes new SQL command capabilities and not changes
+ in behavior, unless specifically mentioned in the release notes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Library API</term>
+ <listitem>
+ <para>
+ Typically libraries like <application>libpq</application> only add new
+ functionality, again unless mentioned in the release notes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>System Catalogs</term>
+ <listitem>
+ <para>
+ System catalog changes usually only affect database management tools.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Server C-language API</term>
+ <listitem>
+ <para>
+ This involves changes in the backend function API, which is written
+ in the C programming language. Such changes affect code that
+ references backend functions deep inside the server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <sect2 id="upgrading-via-pgdumpall">
+ <title>Upgrading Data via <application>pg_dumpall</application></title>
+
+ <para>
+ One upgrade method is to dump data from one major version of
+ <productname>PostgreSQL</productname> and restore it in another &mdash; to do
+ this, you must use a <emphasis>logical</emphasis> backup tool like
+ <application>pg_dumpall</application>; file system
+ level backup methods will not work. (There are checks in place that prevent
+ you from using a data directory with an incompatible version of
+ <productname>PostgreSQL</productname>, so no great harm can be done by
+ trying to start the wrong server version on a data directory.)
+ </para>
+
+ <para>
+ It is recommended that you use the <application>pg_dump</application> and
+ <application>pg_dumpall</application> programs from the <emphasis>newer</emphasis>
+ version of
+ <productname>PostgreSQL</productname>, to take advantage of enhancements
+ that might have been made in these programs. Current releases of the
+ dump programs can read data from any server version back to 9.2.
+ </para>
+
+ <para>
+ These instructions assume that your existing installation is under the
+ <filename>/usr/local/pgsql</filename> directory, and that the data area is in
+ <filename>/usr/local/pgsql/data</filename>. Substitute your paths
+ appropriately.
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ If making a backup, make sure that your database is not being updated.
+ This does not affect the integrity of the backup, but the changed
+ data would of course not be included. If necessary, edit the
+ permissions in the file <filename>/usr/local/pgsql/data/pg_hba.conf</filename>
+ (or equivalent) to disallow access from everyone except you.
+ See <xref linkend="client-authentication"/> for additional information on
+ access control.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>pg_dumpall</primary>
+ <secondary>use during upgrade</secondary>
+ </indexterm>
+
+ To back up your database installation, type:
+<screen>
+<userinput>pg_dumpall &gt; <replaceable>outputfile</replaceable></userinput>
+</screen>
+ </para>
+
+ <para>
+ To make the backup, you can use the <application>pg_dumpall</application>
+ command from the version you are currently running; see <xref
+ linkend="backup-dump-all"/> for more details. For best
+ results, however, try to use the <application>pg_dumpall</application>
+ command from <productname>PostgreSQL</productname> &version;,
+ since this version contains bug fixes and improvements over older
+ versions. While this advice might seem idiosyncratic since you
+ haven't installed the new version yet, it is advisable to follow
+ it if you plan to install the new version in parallel with the
+ old version. In that case you can complete the installation
+ normally and transfer the data later. This will also decrease
+ the downtime.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Shut down the old server:
+<screen>
+<userinput>pg_ctl stop</userinput>
+</screen>
+ On systems that have <productname>PostgreSQL</productname> started at boot time,
+ there is probably a start-up file that will accomplish the same thing. For
+ example, on a <systemitem class="osname">Red Hat Linux</systemitem> system one
+ might find that this works:
+<screen>
+<userinput>/etc/rc.d/init.d/postgresql stop</userinput>
+</screen>
+ See <xref linkend="runtime"/> for details about starting and
+ stopping the server.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ If restoring from backup, rename or delete the old installation
+ directory if it is not version-specific. It is a good idea to
+ rename the directory, rather than
+ delete it, in case you have trouble and need to revert to it. Keep
+ in mind the directory might consume significant disk space. To rename
+ the directory, use a command like this:
+<screen>
+<userinput>mv /usr/local/pgsql /usr/local/pgsql.old</userinput>
+</screen>
+ (Be sure to move the directory as a single unit so relative paths
+ remain unchanged.)
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Install the new version of <productname>PostgreSQL</productname> as
+ outlined in <xref linkend="install-procedure"/>.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Create a new database cluster if needed. Remember that you must
+ execute these commands while logged in to the special database user
+ account (which you already have if you are upgrading).
+<programlisting>
+<userinput>/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data</userinput>
+</programlisting>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Restore your previous <filename>pg_hba.conf</filename> and any
+ <filename>postgresql.conf</filename> modifications.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Start the database server, again using the special database user
+ account:
+<programlisting>
+<userinput>/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data</userinput>
+</programlisting>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Finally, restore your data from backup with:
+<screen>
+<userinput>/usr/local/pgsql/bin/psql -d postgres -f <replaceable>outputfile</replaceable></userinput>
+</screen>
+ using the <emphasis>new</emphasis> <application>psql</application>.
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ The least downtime can be achieved by installing the new server in
+ a different directory and running both the old and the new servers
+ in parallel, on different ports. Then you can use something like:
+
+<programlisting>
+pg_dumpall -p 5432 | psql -d postgres -p 5433
+</programlisting>
+ to transfer your data.
+ </para>
+
+ </sect2>
+
+ <sect2 id="upgrading-via-pg-upgrade">
+ <title>Upgrading Data via <application>pg_upgrade</application></title>
+
+ <para>
+ The <xref linkend="pgupgrade"/> module allows an installation to
+ be migrated in-place from one major <productname>PostgreSQL</productname>
+ version to another. Upgrades can be performed in minutes,
+ particularly with <option>--link</option> mode. It requires steps similar to
+ <application>pg_dumpall</application> above, e.g., starting/stopping the server,
+ running <application>initdb</application>. The <application>pg_upgrade</application> <link
+ linkend="pgupgrade">documentation</link> outlines the necessary steps.
+ </para>
+
+ </sect2>
+
+ <sect2 id="upgrading-via-replication">
+ <title>Upgrading Data via Replication</title>
+
+ <para>
+ It is also possible to use logical replication methods to create a standby
+ server with the updated version of <productname>PostgreSQL</productname>.
+ This is possible because logical replication supports
+ replication between different major versions of
+ <productname>PostgreSQL</productname>. The standby can be on the same computer or
+ a different computer. Once it has synced up with the primary server
+ (running the older version of <productname>PostgreSQL</productname>), you can
+ switch primaries and make the standby the primary and shut down the older
+ database instance. Such a switch-over results in only several seconds
+ of downtime for an upgrade.
+ </para>
+
+ <para>
+ This method of upgrading can be performed using the built-in logical
+ replication facilities as well as using external logical replication
+ systems such as <productname>pglogical</productname>,
+ <productname>Slony</productname>, <productname>Londiste</productname>, and
+ <productname>Bucardo</productname>.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="preventing-server-spoofing">
+ <title>Preventing Server Spoofing</title>
+
+ <indexterm zone="preventing-server-spoofing">
+ <primary>server spoofing</primary>
+ </indexterm>
+
+ <para>
+ While the server is running, it is not possible for a malicious user
+ to take the place of the normal database server. However, when the
+ server is down, it is possible for a local user to spoof the normal
+ server by starting their own server. The spoof server could read
+ passwords and queries sent by clients, but could not return any data
+ because the <varname>PGDATA</varname> directory would still be secure because
+ of directory permissions. Spoofing is possible because any user can
+ start a database server; a client cannot identify an invalid server
+ unless it is specially configured.
+ </para>
+
+ <para>
+ One way to prevent spoofing of <literal>local</literal>
+ connections is to use a Unix domain socket directory (<xref
+ linkend="guc-unix-socket-directories"/>) that has write permission only
+ for a trusted local user. This prevents a malicious user from creating
+ their own socket file in that directory. If you are concerned that
+ some applications might still reference <filename>/tmp</filename> for the
+ socket file and hence be vulnerable to spoofing, during operating system
+ startup create a symbolic link <filename>/tmp/.s.PGSQL.5432</filename> that points
+ to the relocated socket file. You also might need to modify your
+ <filename>/tmp</filename> cleanup script to prevent removal of the symbolic link.
+ </para>
+
+ <para>
+ Another option for <literal>local</literal> connections is for clients to use
+ <link linkend="libpq-connect-requirepeer"><literal>requirepeer</literal></link>
+ to specify the required owner of the server process connected to
+ the socket.
+ </para>
+
+ <para>
+ To prevent spoofing on TCP connections, either use
+ SSL certificates and make sure that clients check the server's certificate,
+ or use GSSAPI encryption (or both, if they're on separate connections).
+ </para>
+
+ <para>
+ To prevent spoofing with SSL, the server
+ must be configured to accept only <literal>hostssl</literal> connections (<xref
+ linkend="auth-pg-hba-conf"/>) and have SSL key and certificate files
+ (<xref linkend="ssl-tcp"/>). The TCP client must connect using
+ <literal>sslmode=verify-ca</literal> or
+ <literal>verify-full</literal> and have the appropriate root certificate
+ file installed (<xref linkend="libq-ssl-certificates"/>).
+ </para>
+
+ <para>
+ To prevent spoofing with GSSAPI, the server must be configured to accept
+ only <literal>hostgssenc</literal> connections
+ (<xref linkend="auth-pg-hba-conf"/>) and use <literal>gss</literal>
+ authentication with them. The TCP client must connect
+ using <literal>gssencmode=require</literal>.
+ </para>
+ </sect1>
+
+ <sect1 id="encryption-options">
+ <title>Encryption Options</title>
+
+ <indexterm zone="encryption-options">
+ <primary>encryption</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> offers encryption at several
+ levels, and provides flexibility in protecting data from disclosure
+ due to database server theft, unscrupulous administrators, and
+ insecure networks. Encryption might also be required to secure
+ sensitive data such as medical records or financial transactions.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Password Encryption</term>
+ <listitem>
+
+ <para>
+ Database user passwords are stored as hashes (determined by the setting
+ <xref linkend="guc-password-encryption"/>), so the administrator cannot
+ determine the actual password assigned to the user. If SCRAM or MD5
+ encryption is used for client authentication, the unencrypted password is
+ never even temporarily present on the server because the client encrypts
+ it before being sent across the network. SCRAM is preferred, because it
+ is an Internet standard and is more secure than the PostgreSQL-specific
+ MD5 authentication protocol.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Encryption For Specific Columns</term>
+
+ <listitem>
+ <para>
+ The <xref linkend="pgcrypto"/> module allows certain fields to be
+ stored encrypted.
+ This is useful if only some of the data is sensitive.
+ The client supplies the decryption key and the data is decrypted
+ on the server and then sent to the client.
+ </para>
+
+ <para>
+ The decrypted data and the decryption key are present on the
+ server for a brief time while it is being decrypted and
+ communicated between the client and server. This presents a brief
+ moment where the data and keys can be intercepted by someone with
+ complete access to the database server, such as the system
+ administrator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Data Partition Encryption</term>
+
+ <listitem>
+ <para>
+ Storage encryption can be performed at the file system level or the
+ block level. Linux file system encryption options include eCryptfs
+ and EncFS, while FreeBSD uses PEFS. Block level or full disk
+ encryption options include dm-crypt + LUKS on Linux and GEOM
+ modules geli and gbde on FreeBSD. Many other operating systems
+ support this functionality, including Windows.
+ </para>
+
+ <para>
+ This mechanism prevents unencrypted data from being read from the
+ drives if the drives or the entire computer is stolen. This does
+ not protect against attacks while the file system is mounted,
+ because when mounted, the operating system provides an unencrypted
+ view of the data. However, to mount the file system, you need some
+ way for the encryption key to be passed to the operating system,
+ and sometimes the key is stored somewhere on the host that mounts
+ the disk.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Encrypting Data Across A Network</term>
+
+ <listitem>
+ <para>
+ SSL connections encrypt all data sent across the network: the
+ password, the queries, and the data returned. The
+ <filename>pg_hba.conf</filename> file allows administrators to specify
+ which hosts can use non-encrypted connections (<literal>host</literal>)
+ and which require SSL-encrypted connections
+ (<literal>hostssl</literal>). Also, clients can specify that they
+ connect to servers only via SSL.
+ </para>
+
+ <para>
+ GSSAPI-encrypted connections encrypt all data sent across the network,
+ including queries and data returned. (No password is sent across the
+ network.) The <filename>pg_hba.conf</filename> file allows
+ administrators to specify which hosts can use non-encrypted connections
+ (<literal>host</literal>) and which require GSSAPI-encrypted connections
+ (<literal>hostgssenc</literal>). Also, clients can specify that they
+ connect to servers only on GSSAPI-encrypted connections
+ (<literal>gssencmode=require</literal>).
+ </para>
+
+ <para>
+ <application>Stunnel</application> or
+ <application>SSH</application> can also be used to encrypt
+ transmissions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>SSL Host Authentication</term>
+
+ <listitem>
+ <para>
+ It is possible for both the client and server to provide SSL
+ certificates to each other. It takes some extra configuration
+ on each side, but this provides stronger verification of identity
+ than the mere use of passwords. It prevents a computer from
+ pretending to be the server just long enough to read the password
+ sent by the client. It also helps prevent <quote>man in the middle</quote>
+ attacks where a computer between the client and server pretends to
+ be the server and reads and passes all data between the client and
+ server.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Client-Side Encryption</term>
+
+ <listitem>
+ <para>
+ If the system administrator for the server's machine cannot be trusted,
+ it is necessary
+ for the client to encrypt the data; this way, unencrypted data
+ never appears on the database server. Data is encrypted on the
+ client before being sent to the server, and database results have
+ to be decrypted on the client before being used.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="ssl-tcp">
+ <title>Secure TCP/IP Connections with SSL</title>
+
+ <indexterm zone="ssl-tcp">
+ <primary>SSL</primary>
+ <secondary>TLS</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> has native support for using
+ <acronym>SSL</acronym> connections to encrypt client/server communications
+ for increased security. This requires that
+ <productname>OpenSSL</productname> is installed on both client and
+ server systems and that support in <productname>PostgreSQL</productname> is
+ enabled at build time (see <xref linkend="installation"/>).
+ </para>
+
+ <para>
+ The terms <acronym>SSL</acronym> and <acronym>TLS</acronym> are often used
+ interchangeably to mean a secure encrypted connection using a
+ <acronym>TLS</acronym> protocol. <acronym>SSL</acronym> protocols are the
+ precursors to <acronym>TLS</acronym> protocols, and the term
+ <acronym>SSL</acronym> is still used for encrypted connections even though
+ <acronym>SSL</acronym> protocols are no longer supported.
+ <acronym>SSL</acronym> is used interchangeably with <acronym>TLS</acronym>
+ in <productname>PostgreSQL</productname>.
+
+ </para>
+ <sect2 id="ssl-setup">
+ <title>Basic Setup</title>
+
+ <para>
+ With <acronym>SSL</acronym> support compiled in, the
+ <productname>PostgreSQL</productname> server can be started with
+ support for encrypted connections using <acronym>TLS</acronym> protocols
+ enabled by setting the parameter
+ <xref linkend="guc-ssl"/> to <literal>on</literal> in
+ <filename>postgresql.conf</filename>. The server will listen for both normal
+ and <acronym>SSL</acronym> connections on the same TCP port, and will negotiate
+ with any connecting client on whether to use <acronym>SSL</acronym>. By
+ default, this is at the client's option; see <xref
+ linkend="auth-pg-hba-conf"/> about how to set up the server to require
+ use of <acronym>SSL</acronym> for some or all connections.
+ </para>
+
+ <para>
+ To start in <acronym>SSL</acronym> mode, files containing the server certificate
+ and private key must exist. By default, these files are expected to be
+ named <filename>server.crt</filename> and <filename>server.key</filename>, respectively, in
+ the server's data directory, but other names and locations can be specified
+ using the configuration parameters <xref linkend="guc-ssl-cert-file"/>
+ and <xref linkend="guc-ssl-key-file"/>.
+ </para>
+
+ <para>
+ On Unix systems, the permissions on <filename>server.key</filename> must
+ disallow any access to world or group; achieve this by the command
+ <command>chmod 0600 server.key</command>. Alternatively, the file can be
+ owned by root and have group read access (that is, <literal>0640</literal>
+ permissions). That setup is intended for installations where certificate
+ and key files are managed by the operating system. The user under which
+ the <productname>PostgreSQL</productname> server runs should then be made a
+ member of the group that has access to those certificate and key files.
+ </para>
+
+ <para>
+ If the data directory allows group read access then certificate files may
+ need to be located outside of the data directory in order to conform to the
+ security requirements outlined above. Generally, group access is enabled
+ to allow an unprivileged user to backup the database, and in that case the
+ backup software will not be able to read the certificate files and will
+ likely error.
+ </para>
+
+ <para>
+ If the private key is protected with a passphrase, the
+ server will prompt for the passphrase and will not start until it has
+ been entered.
+ Using a passphrase by default disables the ability to change the server's
+ SSL configuration without a server restart, but see <xref
+ linkend="guc-ssl-passphrase-command-supports-reload"/>.
+ Furthermore, passphrase-protected private keys cannot be used at all
+ on Windows.
+ </para>
+
+ <para>
+ The first certificate in <filename>server.crt</filename> must be the
+ server's certificate because it must match the server's private key.
+ The certificates of <quote>intermediate</quote> certificate authorities
+ can also be appended to the file. Doing this avoids the necessity of
+ storing intermediate certificates on clients, assuming the root and
+ intermediate certificates were created with <literal>v3_ca</literal>
+ extensions. (This sets the certificate's basic constraint of
+ <literal>CA</literal> to <literal>true</literal>.)
+ This allows easier expiration of intermediate certificates.
+ </para>
+
+ <para>
+ It is not necessary to add the root certificate to
+ <filename>server.crt</filename>. Instead, clients must have the root
+ certificate of the server's certificate chain.
+ </para>
+ </sect2>
+
+ <sect2 id="ssl-openssl-config">
+ <title>OpenSSL Configuration</title>
+
+ <para>
+ <productname>PostgreSQL</productname> reads the system-wide
+ <productname>OpenSSL</productname> configuration file. By default, this
+ file is named <filename>openssl.cnf</filename> and is located in the
+ directory reported by <literal>openssl version -d</literal>.
+ This default can be overridden by setting environment variable
+ <envar>OPENSSL_CONF</envar> to the name of the desired configuration file.
+ </para>
+
+ <para>
+ <productname>OpenSSL</productname> supports a wide range of ciphers
+ and authentication algorithms, of varying strength. While a list of
+ ciphers can be specified in the <productname>OpenSSL</productname>
+ configuration file, you can specify ciphers specifically for use by
+ the database server by modifying <xref linkend="guc-ssl-ciphers"/> in
+ <filename>postgresql.conf</filename>.
+ </para>
+
+ <note>
+ <para>
+ It is possible to have authentication without encryption overhead by
+ using <literal>NULL-SHA</literal> or <literal>NULL-MD5</literal> ciphers. However,
+ a man-in-the-middle could read and pass communications between client
+ and server. Also, encryption overhead is minimal compared to the
+ overhead of authentication. For these reasons NULL ciphers are not
+ recommended.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="ssl-client-certificates">
+ <title>Using Client Certificates</title>
+
+ <para>
+ To require the client to supply a trusted certificate,
+ place certificates of the root certificate authorities
+ (<acronym>CA</acronym>s) you trust in a file in the data
+ directory, set the parameter <xref linkend="guc-ssl-ca-file"/> in
+ <filename>postgresql.conf</filename> to the new file name, and add the
+ authentication option <literal>clientcert=verify-ca</literal> or
+ <literal>clientcert=verify-full</literal> to the appropriate
+ <literal>hostssl</literal> line(s) in <filename>pg_hba.conf</filename>.
+ A certificate will then be requested from the client during SSL
+ connection startup. (See <xref linkend="libpq-ssl"/> for a description
+ of how to set up certificates on the client.)
+ </para>
+
+ <para>
+ For a <literal>hostssl</literal> entry with
+ <literal>clientcert=verify-ca</literal>, the server will verify
+ that the client's certificate is signed by one of the trusted
+ certificate authorities. If <literal>clientcert=verify-full</literal>
+ is specified, the server will not only verify the certificate
+ chain, but it will also check whether the username or its mapping
+ matches the <literal>cn</literal> (Common Name) of the provided certificate.
+ Note that certificate chain validation is always ensured when the
+ <literal>cert</literal> authentication method is used
+ (see <xref linkend="auth-cert"/>).
+ </para>
+
+ <para>
+ Intermediate certificates that chain up to existing root certificates
+ can also appear in the <xref linkend="guc-ssl-ca-file"/> file if
+ you wish to avoid storing them on clients (assuming the root and
+ intermediate certificates were created with <literal>v3_ca</literal>
+ extensions). Certificate Revocation List (CRL) entries are also
+ checked if the parameter <xref linkend="guc-ssl-crl-file"/> or
+ <xref linkend="guc-ssl-crl-dir"/> is set.
+ </para>
+
+ <para>
+ The <literal>clientcert</literal> authentication option is available for
+ all authentication methods, but only in <filename>pg_hba.conf</filename> lines
+ specified as <literal>hostssl</literal>. When <literal>clientcert</literal> is
+ not specified, the server verifies the client certificate against its CA
+ file only if a client certificate is presented and the CA is configured.
+ </para>
+
+ <para>
+ There are two approaches to enforce that users provide a certificate during login.
+ </para>
+
+ <para>
+ The first approach makes use of the <literal>cert</literal> authentication
+ method for <literal>hostssl</literal> entries in <filename>pg_hba.conf</filename>,
+ such that the certificate itself is used for authentication while also
+ providing ssl connection security. See <xref linkend="auth-cert"/> for details.
+ (It is not necessary to specify any <literal>clientcert</literal> options
+ explicitly when using the <literal>cert</literal> authentication method.)
+ In this case, the <literal>cn</literal> (Common Name) provided in
+ the certificate is checked against the user name or an applicable mapping.
+ </para>
+
+ <para>
+ The second approach combines any authentication method for <literal>hostssl</literal>
+ entries with the verification of client certificates by setting the
+ <literal>clientcert</literal> authentication option to <literal>verify-ca</literal>
+ or <literal>verify-full</literal>. The former option only enforces that
+ the certificate is valid, while the latter also ensures that the
+ <literal>cn</literal> (Common Name) in the certificate matches
+ the user name or an applicable mapping.
+ </para>
+ </sect2>
+
+ <sect2 id="ssl-server-files">
+ <title>SSL Server File Usage</title>
+
+ <para>
+ <xref linkend="ssl-file-usage"/> summarizes the files that are
+ relevant to the SSL setup on the server. (The shown file names are default
+ names. The locally configured names could be different.)
+ </para>
+
+ <table id="ssl-file-usage">
+ <title>SSL Server File Usage</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>File</entry>
+ <entry>Contents</entry>
+ <entry>Effect</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry><xref linkend="guc-ssl-cert-file"/> (<filename>$PGDATA/server.crt</filename>)</entry>
+ <entry>server certificate</entry>
+ <entry>sent to client to indicate server's identity</entry>
+ </row>
+
+ <row>
+ <entry><xref linkend="guc-ssl-key-file"/> (<filename>$PGDATA/server.key</filename>)</entry>
+ <entry>server private key</entry>
+ <entry>proves server certificate was sent by the owner; does not indicate
+ certificate owner is trustworthy</entry>
+ </row>
+
+ <row>
+ <entry><xref linkend="guc-ssl-ca-file"/></entry>
+ <entry>trusted certificate authorities</entry>
+ <entry>checks that client certificate is
+ signed by a trusted certificate authority</entry>
+ </row>
+
+ <row>
+ <entry><xref linkend="guc-ssl-crl-file"/></entry>
+ <entry>certificates revoked by certificate authorities</entry>
+ <entry>client certificate must not be on this list</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The server reads these files at server start and whenever the server
+ configuration is reloaded. On <systemitem class="osname">Windows</systemitem>
+ systems, they are also re-read whenever a new backend process is spawned
+ for a new client connection.
+ </para>
+
+ <para>
+ If an error in these files is detected at server start, the server will
+ refuse to start. But if an error is detected during a configuration
+ reload, the files are ignored and the old SSL configuration continues to
+ be used. On <systemitem class="osname">Windows</systemitem> systems, if an error in
+ these files is detected at backend start, that backend will be unable to
+ establish an SSL connection. In all these cases, the error condition is
+ reported in the server log.
+ </para>
+ </sect2>
+
+ <sect2 id="ssl-certificate-creation">
+ <title>Creating Certificates</title>
+
+ <para>
+ To create a simple self-signed certificate for the server, valid for 365
+ days, use the following <productname>OpenSSL</productname> command,
+ replacing <replaceable>dbhost.yourdomain.com</replaceable> with the
+ server's host name:
+<programlisting>
+openssl req -new -x509 -days 365 -nodes -text -out server.crt \
+ -keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</replaceable>"
+</programlisting>
+ Then do:
+<programlisting>
+chmod og-rwx server.key
+</programlisting>
+ because the server will reject the file if its permissions are more
+ liberal than this.
+ For more details on how to create your server private key and
+ certificate, refer to the <productname>OpenSSL</productname> documentation.
+ </para>
+
+ <para>
+ While a self-signed certificate can be used for testing, a certificate
+ signed by a certificate authority (<acronym>CA</acronym>) (usually an
+ enterprise-wide root <acronym>CA</acronym>) should be used in production.
+ </para>
+
+ <para>
+ To create a server certificate whose identity can be validated
+ by clients, first create a certificate signing request
+ (<acronym>CSR</acronym>) and a public/private key file:
+<programlisting>
+openssl req -new -nodes -text -out root.csr \
+ -keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</replaceable>"
+chmod og-rwx root.key
+</programlisting>
+ Then, sign the request with the key to create a root certificate
+ authority (using the default <productname>OpenSSL</productname>
+ configuration file location on <productname>Linux</productname>):
+<programlisting>
+openssl x509 -req -in root.csr -text -days 3650 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -signkey root.key -out root.crt
+</programlisting>
+ Finally, create a server certificate signed by the new root certificate
+ authority:
+<programlisting>
+openssl req -new -nodes -text -out server.csr \
+ -keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</replaceable>"
+chmod og-rwx server.key
+
+openssl x509 -req -in server.csr -text -days 365 \
+ -CA root.crt -CAkey root.key -CAcreateserial \
+ -out server.crt
+</programlisting>
+ <filename>server.crt</filename> and <filename>server.key</filename>
+ should be stored on the server, and <filename>root.crt</filename> should
+ be stored on the client so the client can verify that the server's leaf
+ certificate was signed by its trusted root certificate.
+ <filename>root.key</filename> should be stored offline for use in
+ creating future certificates.
+ </para>
+
+ <para>
+ It is also possible to create a chain of trust that includes
+ intermediate certificates:
+<programlisting>
+# root
+openssl req -new -nodes -text -out root.csr \
+ -keyout root.key -subj "/CN=<replaceable>root.yourdomain.com</replaceable>"
+chmod og-rwx root.key
+openssl x509 -req -in root.csr -text -days 3650 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -signkey root.key -out root.crt
+
+# intermediate
+openssl req -new -nodes -text -out intermediate.csr \
+ -keyout intermediate.key -subj "/CN=<replaceable>intermediate.yourdomain.com</replaceable>"
+chmod og-rwx intermediate.key
+openssl x509 -req -in intermediate.csr -text -days 1825 \
+ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
+ -CA root.crt -CAkey root.key -CAcreateserial \
+ -out intermediate.crt
+
+# leaf
+openssl req -new -nodes -text -out server.csr \
+ -keyout server.key -subj "/CN=<replaceable>dbhost.yourdomain.com</replaceable>"
+chmod og-rwx server.key
+openssl x509 -req -in server.csr -text -days 365 \
+ -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
+ -out server.crt
+</programlisting>
+ <filename>server.crt</filename> and
+ <filename>intermediate.crt</filename> should be concatenated
+ into a certificate file bundle and stored on the server.
+ <filename>server.key</filename> should also be stored on the server.
+ <filename>root.crt</filename> should be stored on the client so
+ the client can verify that the server's leaf certificate was signed
+ by a chain of certificates linked to its trusted root certificate.
+ <filename>root.key</filename> and <filename>intermediate.key</filename>
+ should be stored offline for use in creating future certificates.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="gssapi-enc">
+ <title>Secure TCP/IP Connections with GSSAPI Encryption</title>
+
+ <indexterm zone="gssapi-enc">
+ <primary>gssapi</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> also has native support for
+ using <acronym>GSSAPI</acronym> to encrypt client/server communications for
+ increased security. Support requires that a <acronym>GSSAPI</acronym>
+ implementation (such as MIT Kerberos) is installed on both client and server
+ systems, and that support in <productname>PostgreSQL</productname> is
+ enabled at build time (see <xref linkend="installation"/>).
+ </para>
+
+ <sect2 id="gssapi-setup">
+ <title>Basic Setup</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> server will listen for both
+ normal and <acronym>GSSAPI</acronym>-encrypted connections on the same TCP
+ port, and will negotiate with any connecting client whether to
+ use <acronym>GSSAPI</acronym> for encryption (and for authentication). By
+ default, this decision is up to the client (which means it can be
+ downgraded by an attacker); see <xref linkend="auth-pg-hba-conf"/> about
+ setting up the server to require the use of <acronym>GSSAPI</acronym> for
+ some or all connections.
+ </para>
+
+ <para>
+ When using <acronym>GSSAPI</acronym> for encryption, it is common to
+ use <acronym>GSSAPI</acronym> for authentication as well, since the
+ underlying mechanism will determine both client and server identities
+ (according to the <acronym>GSSAPI</acronym> implementation) in any
+ case. But this is not required;
+ another <productname>PostgreSQL</productname> authentication method
+ can be chosen to perform additional verification.
+ </para>
+
+ <para>
+ Other than configuration of the negotiation
+ behavior, <acronym>GSSAPI</acronym> encryption requires no setup beyond
+ that which is necessary for GSSAPI authentication. (For more information
+ on configuring that, see <xref linkend="gssapi-auth"/>.)
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="ssh-tunnels">
+ <title>Secure TCP/IP Connections with <application>SSH</application> Tunnels</title>
+
+ <indexterm zone="ssh-tunnels">
+ <primary>ssh</primary>
+ </indexterm>
+
+ <para>
+ It is possible to use <application>SSH</application> to encrypt the network
+ connection between clients and a
+ <productname>PostgreSQL</productname> server. Done properly, this
+ provides an adequately secure network connection, even for non-SSL-capable
+ clients.
+ </para>
+
+ <para>
+ First make sure that an <application>SSH</application> server is
+ running properly on the same machine as the
+ <productname>PostgreSQL</productname> server and that you can log in using
+ <command>ssh</command> as some user; you then can establish a
+ secure tunnel to the remote server. A secure tunnel listens on a
+ local port and forwards all traffic to a port on the remote machine.
+ Traffic sent to the remote port can arrive on its
+ <literal>localhost</literal> address, or different bind
+ address if desired; it does not appear as coming from your
+ local machine. This command creates a secure tunnel from the client
+ machine to the remote machine <literal>foo.com</literal>:
+<programlisting>
+ssh -L 63333:localhost:5432 joe@foo.com
+</programlisting>
+ The first number in the <option>-L</option> argument, 63333, is the
+ local port number of the tunnel; it can be any unused port. (IANA
+ reserves ports 49152 through 65535 for private use.) The name or IP
+ address after this is the remote bind address you are connecting to,
+ i.e., <literal>localhost</literal>, which is the default. The second
+ number, 5432, is the remote end of the tunnel, e.g., the port number
+ your database server is using. In order to connect to the database
+ server using this tunnel, you connect to port 63333 on the local
+ machine:
+<programlisting>
+psql -h localhost -p 63333 postgres
+</programlisting>
+ To the database server it will then look as though you are
+ user <literal>joe</literal> on host <literal>foo.com</literal>
+ connecting to the <literal>localhost</literal> bind address, and it
+ will use whatever authentication procedure was configured for
+ connections by that user to that bind address. Note that the server will not
+ think the connection is SSL-encrypted, since in fact it is not
+ encrypted between the
+ <application>SSH</application> server and the
+ <productname>PostgreSQL</productname> server. This should not pose any
+ extra security risk because they are on the same machine.
+ </para>
+
+ <para>
+ In order for the
+ tunnel setup to succeed you must be allowed to connect via
+ <command>ssh</command> as <literal>joe@foo.com</literal>, just
+ as if you had attempted to use <command>ssh</command> to create a
+ terminal session.
+ </para>
+
+ <para>
+ You could also have set up port forwarding as
+<programlisting>
+ssh -L 63333:foo.com:5432 joe@foo.com
+</programlisting>
+ but then the database server will see the connection as coming in
+ on its <literal>foo.com</literal> bind address, which is not opened by
+ the default setting <literal>listen_addresses =
+ 'localhost'</literal>. This is usually not what you want.
+ </para>
+
+ <para>
+ If you have to <quote>hop</quote> to the database server via some
+ login host, one possible setup could look like this:
+<programlisting>
+ssh -L 63333:db.foo.com:5432 joe@shell.foo.com
+</programlisting>
+ Note that this way the connection
+ from <literal>shell.foo.com</literal>
+ to <literal>db.foo.com</literal> will not be encrypted by the SSH
+ tunnel.
+ SSH offers quite a few configuration possibilities when the network
+ is restricted in various ways. Please refer to the SSH
+ documentation for details.
+ </para>
+
+ <tip>
+ <para>
+ Several other applications exist that can provide secure tunnels using
+ a procedure similar in concept to the one just described.
+ </para>
+ </tip>
+
+ </sect1>
+
+ <sect1 id="event-log-registration">
+ <title>Registering <application>Event Log</application> on <systemitem
+ class="osname">Windows</systemitem></title>
+
+ <indexterm zone="event-log-registration">
+ <primary>event log</primary>
+ <secondary>event log</secondary>
+ </indexterm>
+
+ <para>
+ To register a <systemitem class="osname">Windows</systemitem>
+ <application>event log</application> library with the operating system,
+ issue this command:
+<screen>
+<userinput>regsvr32 <replaceable>pgsql_library_directory</replaceable>/pgevent.dll</userinput>
+</screen>
+ This creates registry entries used by the event viewer, under the default
+ event source named <literal>PostgreSQL</literal>.
+ </para>
+
+ <para>
+ To specify a different event source name (see
+ <xref linkend="guc-event-source"/>), use the <literal>/n</literal>
+ and <literal>/i</literal> options:
+<screen>
+<userinput>regsvr32 /n /i:<replaceable>event_source_name</replaceable> <replaceable>pgsql_library_directory</replaceable>/pgevent.dll</userinput>
+</screen>
+ </para>
+
+ <para>
+ To unregister the <application>event log</application> library from
+ the operating system, issue this command:
+<screen>
+<userinput>regsvr32 /u [/i:<replaceable>event_source_name</replaceable>] <replaceable>pgsql_library_directory</replaceable>/pgevent.dll</userinput>
+</screen>
+ </para>
+
+ <note>
+ <para>
+ To enable event logging in the database server, modify
+ <xref linkend="guc-log-destination"/> to include
+ <literal>eventlog</literal> in <filename>postgresql.conf</filename>.
+ </para>
+ </note>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/seg.sgml b/doc/src/sgml/seg.sgml
new file mode 100644
index 0000000..9be69e3
--- /dev/null
+++ b/doc/src/sgml/seg.sgml
@@ -0,0 +1,415 @@
+<!-- doc/src/sgml/seg.sgml -->
+
+<sect1 id="seg" xreflabel="seg">
+ <title>seg</title>
+
+ <indexterm zone="seg">
+ <primary>seg</primary>
+ </indexterm>
+
+ <para>
+ This module implements a data type <type>seg</type> for
+ representing line segments, or floating point intervals.
+ <type>seg</type> can represent uncertainty in the interval endpoints,
+ making it especially useful for representing laboratory measurements.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Rationale</title>
+
+ <para>
+ The geometry of measurements is usually more complex than that of a
+ point in a numeric continuum. A measurement is usually a segment of
+ that continuum with somewhat fuzzy limits. The measurements come out
+ as intervals because of uncertainty and randomness, as well as because
+ the value being measured may naturally be an interval indicating some
+ condition, such as the temperature range of stability of a protein.
+ </para>
+
+ <para>
+ Using just common sense, it appears more convenient to store such data
+ as intervals, rather than pairs of numbers. In practice, it even turns
+ out more efficient in most applications.
+ </para>
+
+ <para>
+ Further along the line of common sense, the fuzziness of the limits
+ suggests that the use of traditional numeric data types leads to a
+ certain loss of information. Consider this: your instrument reads
+ 6.50, and you input this reading into the database. What do you get
+ when you fetch it? Watch:
+
+<screen>
+test=&gt; select 6.50 :: float8 as "pH";
+ pH
+---
+6.5
+(1 row)
+</screen>
+
+ In the world of measurements, 6.50 is not the same as 6.5. It may
+ sometimes be critically different. The experimenters usually write
+ down (and publish) the digits they trust. 6.50 is actually a fuzzy
+ interval contained within a bigger and even fuzzier interval, 6.5,
+ with their center points being (probably) the only common feature they
+ share. We definitely do not want such different data items to appear the
+ same.
+ </para>
+
+ <para>
+ Conclusion? It is nice to have a special data type that can record the
+ limits of an interval with arbitrarily variable precision. Variable in
+ the sense that each data element records its own precision.
+ </para>
+
+ <para>
+ Check this out:
+
+<screen>
+test=&gt; select '6.25 .. 6.50'::seg as "pH";
+ pH
+------------
+6.25 .. 6.50
+(1 row)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Syntax</title>
+
+ <para>
+ The external representation of an interval is formed using one or two
+ floating-point numbers joined by the range operator (<literal>..</literal>
+ or <literal>...</literal>). Alternatively, it can be specified as a
+ center point plus or minus a deviation.
+ Optional certainty indicators (<literal>&lt;</literal>,
+ <literal>&gt;</literal> or <literal>~</literal>) can be stored as well.
+ (Certainty indicators are ignored by all the built-in operators, however.)
+ <xref linkend="seg-repr-table"/> gives an overview of allowed
+ representations; <xref linkend="seg-input-examples"/> shows some
+ examples.
+ </para>
+
+ <para>
+ In <xref linkend="seg-repr-table"/>, <replaceable>x</replaceable>, <replaceable>y</replaceable>, and
+ <replaceable>delta</replaceable> denote
+ floating-point numbers. <replaceable>x</replaceable> and <replaceable>y</replaceable>, but
+ not <replaceable>delta</replaceable>, can be preceded by a certainty indicator.
+ </para>
+
+ <table id="seg-repr-table">
+ <title><type>seg</type> External Representations</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry><literal><replaceable>x</replaceable></literal></entry>
+ <entry>Single value (zero-length interval)
+ </entry>
+ </row>
+ <row>
+ <entry><literal><replaceable>x</replaceable> .. <replaceable>y</replaceable></literal></entry>
+ <entry>Interval from <replaceable>x</replaceable> to <replaceable>y</replaceable>
+ </entry>
+ </row>
+ <row>
+ <entry><literal><replaceable>x</replaceable> (+-) <replaceable>delta</replaceable></literal></entry>
+ <entry>Interval from <replaceable>x</replaceable> - <replaceable>delta</replaceable> to
+ <replaceable>x</replaceable> + <replaceable>delta</replaceable>
+ </entry>
+ </row>
+ <row>
+ <entry><literal><replaceable>x</replaceable> ..</literal></entry>
+ <entry>Open interval with lower bound <replaceable>x</replaceable>
+ </entry>
+ </row>
+ <row>
+ <entry><literal>.. <replaceable>x</replaceable></literal></entry>
+ <entry>Open interval with upper bound <replaceable>x</replaceable>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="seg-input-examples">
+ <title>Examples of Valid <type>seg</type> Input</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <tbody>
+ <row>
+ <entry><literal>5.0</literal></entry>
+ <entry>
+ Creates a zero-length segment (a point, if you will)
+ </entry>
+ </row>
+ <row>
+ <entry><literal>~5.0</literal></entry>
+ <entry>
+ Creates a zero-length segment and records
+ <literal>~</literal> in the data. <literal>~</literal> is ignored
+ by <type>seg</type> operations, but
+ is preserved as a comment.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>&lt;5.0</literal></entry>
+ <entry>
+ Creates a point at 5.0. <literal>&lt;</literal> is ignored but
+ is preserved as a comment.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>&gt;5.0</literal></entry>
+ <entry>
+ Creates a point at 5.0. <literal>&gt;</literal> is ignored but
+ is preserved as a comment.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>5(+-)0.3</literal></entry>
+ <entry>
+ Creates an interval <literal>4.7 .. 5.3</literal>.
+ Note that the <literal>(+-)</literal> notation isn't preserved.
+ </entry>
+ </row>
+ <row>
+ <entry><literal>50 .. </literal></entry>
+ <entry>Everything that is greater than or equal to 50</entry>
+ </row>
+ <row>
+ <entry><literal>.. 0</literal></entry>
+ <entry>Everything that is less than or equal to 0</entry>
+ </row>
+ <row>
+ <entry><literal>1.5e-2 .. 2E-2 </literal></entry>
+ <entry>Creates an interval <literal>0.015 .. 0.02</literal></entry>
+ </row>
+ <row>
+ <entry><literal>1 ... 2</literal></entry>
+ <entry>
+ The same as <literal>1...2</literal>, or <literal>1 .. 2</literal>,
+ or <literal>1..2</literal>
+ (spaces around the range operator are ignored)
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Because the <literal>...</literal> operator is widely used in data sources, it is allowed
+ as an alternative spelling of the <literal>..</literal> operator. Unfortunately, this
+ creates a parsing ambiguity: it is not clear whether the upper bound
+ in <literal>0...23</literal> is meant to be <literal>23</literal> or <literal>0.23</literal>.
+ This is resolved by requiring at least one digit before the decimal
+ point in all numbers in <type>seg</type> input.
+ </para>
+
+ <para>
+ As a sanity check, <type>seg</type> rejects intervals with the lower bound
+ greater than the upper, for example <literal>5 .. 2</literal>.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Precision</title>
+
+ <para>
+ <type>seg</type> values are stored internally as pairs of 32-bit floating point
+ numbers. This means that numbers with more than 7 significant digits
+ will be truncated.
+ </para>
+
+ <para>
+ Numbers with 7 or fewer significant digits retain their
+ original precision. That is, if your query returns 0.00, you will be
+ sure that the trailing zeroes are not the artifacts of formatting: they
+ reflect the precision of the original data. The number of leading
+ zeroes does not affect precision: the value 0.0067 is considered to
+ have just 2 significant digits.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Usage</title>
+
+ <para>
+ The <filename>seg</filename> module includes a GiST index operator class for
+ <type>seg</type> values.
+ The operators supported by the GiST operator class are shown in <xref linkend="seg-gist-operators"/>.
+ </para>
+
+ <table id="seg-gist-operators">
+ <title>Seg GiST Operators</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Operator
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>&lt;&lt;</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first <type>seg</type> entirely to the left of the second?
+ [a, b] &lt;&lt; [c, d] is true if b &lt; c.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>&gt;&gt;</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first <type>seg</type> entirely to the right of the second?
+ [a, b] &gt;&gt; [c, d] is true if a &gt; d.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>&amp;&lt;</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first <type>seg</type> not extend to the right of the
+ second?
+ [a, b] &amp;&lt; [c, d] is true if b &lt;= d.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>&amp;&gt;</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first <type>seg</type> not extend to the left of the
+ second?
+ [a, b] &amp;&gt; [c, d] is true if a &gt;= c.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>=</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Are the two <type>seg</type>s equal?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>&amp;&amp;</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Do the two <type>seg</type>s overlap?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>@&gt;</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Does the first <type>seg</type> contain the second?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <type>seg</type> <literal>&lt;@</literal> <type>seg</type>
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Is the first <type>seg</type> contained in the second?
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ In addition to the above operators, the usual comparison
+ operators shown in <xref linkend="functions-comparison-op-table"/> are
+ available for type <type>seg</type>. These operators
+ first compare (a) to (c),
+ and if these are equal, compare (b) to (d). That results in
+ reasonably good sorting in most cases, which is useful if
+ you want to use ORDER BY with this type.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Notes</title>
+
+ <para>
+ For examples of usage, see the regression test <filename>sql/seg.sql</filename>.
+ </para>
+
+ <para>
+ The mechanism that converts <literal>(+-)</literal> to regular ranges
+ isn't completely accurate in determining the number of significant digits
+ for the boundaries. For example, it adds an extra digit to the lower
+ boundary if the resulting interval includes a power of ten:
+
+<screen>
+postgres=&gt; select '10(+-)1'::seg as seg;
+ seg
+---------
+9.0 .. 11 -- should be: 9 .. 11
+</screen>
+ </para>
+
+ <para>
+ The performance of an R-tree index can largely depend on the initial
+ order of input values. It may be very helpful to sort the input table
+ on the <type>seg</type> column; see the script <filename>sort-segments.pl</filename>
+ for an example.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Credits</title>
+
+ <para>
+ Original author: Gene Selkov, Jr. <email>selkovjr@mcs.anl.gov</email>,
+ Mathematics and Computer Science Division, Argonne National Laboratory.
+ </para>
+
+ <para>
+ My thanks are primarily to Prof. Joe Hellerstein
+ (<ulink url="https://dsf.berkeley.edu/jmh/"></ulink>) for elucidating the
+ gist of the GiST (<ulink url="http://gist.cs.berkeley.edu/"></ulink>). I am
+ also grateful to all Postgres developers, present and past, for enabling
+ myself to create my own world and live undisturbed in it. And I would like
+ to acknowledge my gratitude to Argonne Lab and to the U.S. Department of
+ Energy for the years of faithful support of my database research.
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml
new file mode 100644
index 0000000..620d063
--- /dev/null
+++ b/doc/src/sgml/sepgsql.sgml
@@ -0,0 +1,828 @@
+<!-- doc/src/sgml/sepgsql.sgml -->
+
+<sect1 id="sepgsql" xreflabel="sepgsql">
+ <title>sepgsql</title>
+
+ <indexterm zone="sepgsql">
+ <primary>sepgsql</primary>
+ </indexterm>
+
+ <para>
+ <filename>sepgsql</filename> is a loadable module that supports label-based
+ mandatory access control (MAC) based on <productname>SELinux</productname> security
+ policy.
+ </para>
+
+ <warning>
+ <para>
+ The current implementation has significant limitations, and does not
+ enforce mandatory access control for all actions. See
+ <xref linkend="sepgsql-limitations"/>.
+ </para>
+ </warning>
+
+ <sect2 id="sepgsql-overview">
+ <title>Overview</title>
+
+ <para>
+ This module integrates with <productname>SELinux</productname> to provide an
+ additional layer of security checking above and beyond what is normally
+ provided by <productname>PostgreSQL</productname>. From the perspective of
+ <productname>SELinux</productname>, this module allows
+ <productname>PostgreSQL</productname> to function as a user-space object
+ manager. Each table or function access initiated by a DML query will be
+ checked against the system security policy. This check is in addition to
+ the usual SQL permissions checking performed by
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ <productname>SELinux</productname> access control decisions are made using
+ security labels, which are represented by strings such as
+ <literal>system_u:object_r:sepgsql_table_t:s0</literal>. Each access control
+ decision involves two labels: the label of the subject attempting to
+ perform the action, and the label of the object on which the operation is
+ to be performed. Since these labels can be applied to any sort of object,
+ access control decisions for objects stored within the database can be
+ (and, with this module, are) subjected to the same general criteria used
+ for objects of any other type, such as files. This design is intended to
+ allow a centralized security policy to protect information assets
+ independent of the particulars of how those assets are stored.
+ </para>
+
+ <para>
+ The <link linkend="sql-security-label"><command>SECURITY LABEL</command></link> statement allows assignment of
+ a security label to a database object.
+ </para>
+
+ </sect2>
+ <sect2 id="sepgsql-installation">
+ <title>Installation</title>
+
+ <para>
+ <filename>sepgsql</filename> can only be used on <productname>Linux</productname>
+ 2.6.28 or higher with <productname>SELinux</productname> enabled.
+ It is not available on any other platform. You will also need
+ <productname>libselinux</productname> 2.1.10 or higher and
+ <productname>selinux-policy</productname> 3.9.13 or higher (although some
+ distributions may backport the necessary rules into older policy
+ versions).
+ </para>
+
+ <para>
+ The <command>sestatus</command> command allows you to check the status of
+ <productname>SELinux</productname>. A typical display is:
+<screen>
+$ sestatus
+SELinux status: enabled
+SELinuxfs mount: /selinux
+Current mode: enforcing
+Mode from config file: enforcing
+Policy version: 24
+Policy from config file: targeted
+</screen>
+ If <productname>SELinux</productname> is disabled or not installed, you must set
+ that product up first before installing this module.
+ </para>
+
+ <para>
+ To build this module, include the option <literal>--with-selinux</literal> in
+ your PostgreSQL <literal>configure</literal> command. Be sure that the
+ <filename>libselinux-devel</filename> RPM is installed at build time.
+ </para>
+
+ <para>
+ To use this module, you must include <literal>sepgsql</literal>
+ in the <xref linkend="guc-shared-preload-libraries"/> parameter in
+ <filename>postgresql.conf</filename>. The module will not function correctly
+ if loaded in any other manner. Once the module is loaded, you
+ should execute <filename>sepgsql.sql</filename> in each database.
+ This will install functions needed for security label management, and
+ assign initial security labels.
+ </para>
+
+ <para>
+ Here is an example showing how to initialize a fresh database cluster
+ with <filename>sepgsql</filename> functions and security labels installed.
+ Adjust the paths shown as appropriate for your installation:
+ </para>
+
+<screen>
+$ export PGDATA=/path/to/data/directory
+$ initdb
+$ vi $PGDATA/postgresql.conf
+ change
+ #shared_preload_libraries = '' # (change requires restart)
+ to
+ shared_preload_libraries = 'sepgsql' # (change requires restart)
+$ for DBNAME in template0 template1 postgres; do
+ postgres --single -F -c exit_on_error=true $DBNAME \
+ &lt;/usr/local/pgsql/share/contrib/sepgsql.sql &gt;/dev/null
+ done
+</screen>
+
+ <para>
+ Please note that you may see some or all of the following notifications
+ depending on the particular versions you have of
+ <productname>libselinux</productname> and <productname>selinux-policy</productname>:
+<screen>
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 33 has invalid object type db_blobs
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 36 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 37 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 38 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 39 has invalid object type db_language
+/etc/selinux/targeted/contexts/sepgsql_contexts: line 40 has invalid object type db_language
+</screen>
+ These messages are harmless and should be ignored.
+ </para>
+
+ <para>
+ If the installation process completes without error, you can now start the
+ server normally.
+ </para>
+ </sect2>
+
+ <sect2 id="sepgsql-regression">
+ <title>Regression Tests</title>
+
+ <para>
+ Due to the nature of <productname>SELinux</productname>, running the
+ regression tests for <filename>sepgsql</filename> requires several extra
+ configuration steps, some of which must be done as root.
+ The regression tests will not be run by an ordinary
+ <literal>make check</literal> or <literal>make installcheck</literal> command; you must
+ set up the configuration and then invoke the test script manually.
+ The tests must be run in the <filename>contrib/sepgsql</filename> directory
+ of a configured PostgreSQL build tree. Although they require a build tree,
+ the tests are designed to be executed against an installed server,
+ that is they are comparable to <literal>make installcheck</literal> not
+ <literal>make check</literal>.
+ </para>
+
+ <para>
+ First, set up <filename>sepgsql</filename> in a working database
+ according to the instructions in <xref linkend="sepgsql-installation"/>.
+ Note that the current operating system user must be able to connect to the
+ database as superuser without password authentication.
+ </para>
+
+ <para>
+ Second, build and install the policy package for the regression test.
+ The <filename>sepgsql-regtest</filename> policy is a special purpose policy package
+ which provides a set of rules to be allowed during the regression tests.
+ It should be built from the policy source file
+ <filename>sepgsql-regtest.te</filename>, which is done using
+ <command>make</command> with a Makefile supplied by SELinux.
+ You will need to locate the appropriate
+ Makefile on your system; the path shown below is only an example.
+ (This Makefile is usually supplied by the
+ <filename>selinux-policy-devel</filename> or
+ <filename>selinux-policy</filename> RPM.)
+ Once built, install this policy package using the
+ <command>semodule</command> command, which loads supplied policy packages
+ into the kernel. If the package is correctly installed,
+ <literal><command>semodule</command> -l</literal> should list <literal>sepgsql-regtest</literal> as an
+ available policy package:
+ </para>
+
+<screen>
+$ cd .../contrib/sepgsql
+$ make -f /usr/share/selinux/devel/Makefile
+$ sudo semodule -u sepgsql-regtest.pp
+$ sudo semodule -l | grep sepgsql
+sepgsql-regtest 1.07
+</screen>
+
+ <para>
+ Third, turn on <literal>sepgsql_regression_test_mode</literal>.
+ For security reasons, the rules in <filename>sepgsql-regtest</filename>
+ are not enabled by default;
+ the <literal>sepgsql_regression_test_mode</literal> parameter enables
+ the rules needed to launch the regression tests.
+ It can be turned on using the <command>setsebool</command> command:
+ </para>
+
+<screen>
+$ sudo setsebool sepgsql_regression_test_mode on
+$ getsebool sepgsql_regression_test_mode
+sepgsql_regression_test_mode --> on
+</screen>
+
+ <para>
+ Fourth, verify your shell is operating in the <literal>unconfined_t</literal>
+ domain:
+ </para>
+<screen>
+$ id -Z
+unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+</screen>
+
+ <para>
+ See <xref linkend="sepgsql-resources"/> for details on adjusting your
+ working domain, if necessary.
+ </para>
+
+ <para>
+ Finally, run the regression test script:
+ </para>
+<screen>
+$ ./test_sepgsql
+</screen>
+
+ <para>
+ This script will attempt to verify that you have done all the configuration
+ steps correctly, and then it will run the regression tests for the
+ <filename>sepgsql</filename> module.
+ </para>
+
+ <para>
+ After completing the tests, it's recommended you disable
+ the <literal>sepgsql_regression_test_mode</literal> parameter:
+ </para>
+
+<screen>
+$ sudo setsebool sepgsql_regression_test_mode off
+</screen>
+
+ <para>
+ You might prefer to remove the <filename>sepgsql-regtest</filename> policy
+ entirely:
+ </para>
+
+<screen>
+$ sudo semodule -r sepgsql-regtest
+</screen>
+ </sect2>
+
+ <sect2 id="sepgsql-parameters">
+ <title>GUC Parameters</title>
+
+ <variablelist>
+ <varlistentry id="guc-sepgsql-permissive" xreflabel="sepgsql.permissive">
+ <term>
+ <varname>sepgsql.permissive</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>sepgsql.permissive</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter enables <filename>sepgsql</filename> to function
+ in permissive mode, regardless of the system setting.
+ The default is off.
+ This parameter can only be set in the <filename>postgresql.conf</filename>
+ file or on the server command line.
+ </para>
+
+ <para>
+ When this parameter is on, <filename>sepgsql</filename> functions
+ in permissive mode, even if SELinux in general is working in enforcing
+ mode. This parameter is primarily useful for testing purposes.
+ </para>
+ </listitem>
+
+ </varlistentry>
+ <varlistentry id="guc-sepgsql-debug-audit" xreflabel="sepgsql.debug_audit">
+ <term>
+ <varname>sepgsql.debug_audit</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>sepgsql.debug_audit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This parameter enables the printing of audit messages regardless of
+ the system policy settings.
+ The default is off, which means that messages will be printed according
+ to the system settings.
+ </para>
+
+ <para>
+ The security policy of <productname>SELinux</productname> also has rules to
+ control whether or not particular accesses are logged.
+ By default, access violations are logged, but allowed
+ accesses are not.
+ </para>
+
+ <para>
+ This parameter forces all possible logging to be turned on, regardless
+ of the system policy.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="sepgsql-features">
+ <title>Features</title>
+ <sect3>
+ <title>Controlled Object Classes</title>
+ <para>
+ The security model of <productname>SELinux</productname> describes all the access
+ control rules as relationships between a subject entity (typically,
+ a client of the database) and an object entity (such as a database
+ object), each of which is
+ identified by a security label. If access to an unlabeled object is
+ attempted, the object is treated as if it were assigned the label
+ <literal>unlabeled_t</literal>.
+ </para>
+
+ <para>
+ Currently, <filename>sepgsql</filename> allows security labels to be
+ assigned to schemas, tables, columns, sequences, views, and functions.
+ When <filename>sepgsql</filename> is in use, security labels are
+ automatically assigned to supported database objects at creation time.
+ This label is called a default security label, and is decided according
+ to the system security policy, which takes as input the creator's label,
+ the label assigned to the new object's parent object and optionally name
+ of the constructed object.
+ </para>
+
+ <para>
+ A new database object basically inherits the security label of the parent
+ object, except when the security policy has special rules known as
+ type-transition rules, in which case a different label may be applied.
+ For schemas, the parent object is the current database; for tables,
+ sequences, views, and functions, it is the containing schema; for columns,
+ it is the containing table.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>DML Permissions</title>
+
+ <para>
+ For tables, <literal>db_table:select</literal>, <literal>db_table:insert</literal>,
+ <literal>db_table:update</literal> or <literal>db_table:delete</literal> are
+ checked for all the referenced target tables depending on the kind of
+ statement; in addition, <literal>db_table:select</literal> is also checked for
+ all the tables that contain columns referenced in the
+ <literal>WHERE</literal> or <literal>RETURNING</literal> clause, as a data source
+ for <literal>UPDATE</literal>, and so on.
+ </para>
+
+ <para>
+ Column-level permissions will also be checked for each referenced column.
+ <literal>db_column:select</literal> is checked on not only the columns being
+ read using <literal>SELECT</literal>, but those being referenced in other DML
+ statements; <literal>db_column:update</literal> or <literal>db_column:insert</literal>
+ will also be checked for columns being modified by <literal>UPDATE</literal> or
+ <literal>INSERT</literal>.
+ </para>
+
+ <para>
+ For example, consider:
+<synopsis>
+UPDATE t1 SET x = 2, y = func1(y) WHERE z = 100;
+</synopsis>
+
+ Here, <literal>db_column:update</literal> will be checked for
+ <literal>t1.x</literal>, since it is being updated,
+ <literal>db_column:{select update}</literal> will be checked for
+ <literal>t1.y</literal>, since it is both updated and referenced, and
+ <literal>db_column:select</literal> will be checked for <literal>t1.z</literal>, since
+ it is only referenced.
+ <literal>db_table:{select update}</literal> will also be checked
+ at the table level.
+ </para>
+
+ <para>
+ For sequences, <literal>db_sequence:get_value</literal> is checked when we
+ reference a sequence object using <literal>SELECT</literal>; however, note that we
+ do not currently check permissions on execution of corresponding functions
+ such as <literal>lastval()</literal>.
+ </para>
+
+ <para>
+ For views, <literal>db_view:expand</literal> will be checked, then any other
+ required permissions will be checked on the objects being
+ expanded from the view, individually.
+ </para>
+
+ <para>
+ For functions, <literal>db_procedure:{execute}</literal> will be checked when
+ user tries to execute a function as a part of query, or using fast-path
+ invocation. If this function is a trusted procedure, it also checks
+ <literal>db_procedure:{entrypoint}</literal> permission to check whether it
+ can perform as entry point of trusted procedure.
+ </para>
+
+ <para>
+ In order to access any schema object, <literal>db_schema:search</literal>
+ permission is required on the containing schema. When an object is
+ referenced without schema qualification, schemas on which this
+ permission is not present will not be searched (just as if the user did
+ not have <literal>USAGE</literal> privilege on the schema). If an explicit schema
+ qualification is present, an error will occur if the user does not have
+ the requisite permission on the named schema.
+ </para>
+
+ <para>
+ The client must be allowed to access all referenced tables and
+ columns, even if they originated from views which were then expanded,
+ so that we apply consistent access control rules independent of the manner
+ in which the table contents are referenced.
+ </para>
+
+ <para>
+ The default database privilege system allows database superusers to
+ modify system catalogs using DML commands, and reference or modify
+ toast tables. These operations are prohibited when
+ <filename>sepgsql</filename> is enabled.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>DDL Permissions</title>
+ <para>
+ <productname>SELinux</productname> defines several permissions to control common
+ operations for each object type; such as creation, alter, drop and
+ relabel of security label. In addition, several object types have
+ special permissions to control their characteristic operations; such as
+ addition or deletion of name entries within a particular schema.
+ </para>
+ <para>
+ Creating a new database object requires <literal>create</literal> permission.
+ <productname>SELinux</productname> will grant or deny this permission based on the
+ client's security label and the proposed security label for the new
+ object. In some cases, additional privileges are required:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <link linkend="sql-createdatabase"><command>CREATE DATABASE</command></link> additionally requires
+ <literal>getattr</literal> permission for the source or template database.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Creating a schema object additionally requires <literal>add_name</literal>
+ permission on the parent schema.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Creating a table additionally requires permission to create each
+ individual table column, just as if each table column were a
+ separate top-level object.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Creating a function marked as <literal>LEAKPROOF</literal> additionally
+ requires <literal>install</literal> permission. (This permission is also
+ checked when <literal>LEAKPROOF</literal> is set for an existing function.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ When <literal>DROP</literal> command is executed, <literal>drop</literal> will be
+ checked on the object being removed. Permissions will be also checked for
+ objects dropped indirectly via <literal>CASCADE</literal>. Deletion of objects
+ contained within a particular schema (tables, views, sequences and
+ procedures) additionally requires <literal>remove_name</literal> on the schema.
+ </para>
+
+ <para>
+ When <literal>ALTER</literal> command is executed, <literal>setattr</literal> will be
+ checked on the object being modified for each object types, except for
+ subsidiary objects such as the indexes or triggers of a table, where
+ permissions are instead checked on the parent object. In some cases,
+ additional permissions are required:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Moving an object to a new schema additionally requires
+ <literal>remove_name</literal> permission on the old schema and
+ <literal>add_name</literal> permission on the new one.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Setting the <literal>LEAKPROOF</literal> attribute on a function requires
+ <literal>install</literal> permission.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Using <link linkend="sql-security-label"><command>SECURITY LABEL</command></link> on an object additionally
+ requires <literal>relabelfrom</literal> permission for the object in
+ conjunction with its old security label and <literal>relabelto</literal>
+ permission for the object in conjunction with its new security label.
+ (In cases where multiple label providers are installed and the user
+ tries to set a security label, but it is not managed by
+ <productname>SELinux</productname>, only <literal>setattr</literal> should be checked here.
+ This is currently not done due to implementation restrictions.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </sect3>
+
+ <sect3>
+ <title>Trusted Procedures</title>
+ <para>
+ Trusted procedures are similar to security definer functions or setuid
+ commands. <productname>SELinux</productname> provides a feature to allow trusted
+ code to run using a security label different from that of the client,
+ generally for the purpose of providing highly controlled access to
+ sensitive data (e.g., rows might be omitted, or the precision of stored
+ values might be reduced). Whether or not a function acts as a trusted
+ procedure is controlled by its security label and the operating system
+ security policy. For example:
+ </para>
+
+<screen>
+postgres=# CREATE TABLE customer (
+ cid int primary key,
+ cname text,
+ credit text
+ );
+CREATE TABLE
+postgres=# SECURITY LABEL ON COLUMN customer.credit
+ IS 'system_u:object_r:sepgsql_secret_table_t:s0';
+SECURITY LABEL
+postgres=# CREATE FUNCTION show_credit(int) RETURNS text
+ AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'')
+ FROM customer WHERE cid = $1'
+ LANGUAGE sql;
+CREATE FUNCTION
+postgres=# SECURITY LABEL ON FUNCTION show_credit(int)
+ IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0';
+SECURITY LABEL
+</screen>
+
+ <para>
+ The above operations should be performed by an administrative user.
+ </para>
+
+<screen>
+postgres=# SELECT * FROM customer;
+ERROR: SELinux: security policy violation
+postgres=# SELECT cid, cname, show_credit(cid) FROM customer;
+ cid | cname | show_credit
+-----+--------+---------------------
+ 1 | taro | 1111-2222-3333-xxxx
+ 2 | hanako | 5555-6666-7777-xxxx
+(2 rows)
+</screen>
+
+ <para>
+ In this case, a regular user cannot reference <literal>customer.credit</literal>
+ directly, but a trusted procedure <literal>show_credit</literal> allows the user
+ to print the credit card numbers of customers with some of the digits
+ masked out.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Dynamic Domain Transitions</title>
+ <para>
+ It is possible to use SELinux's dynamic domain transition feature
+ to switch the security label of the client process, the client domain,
+ to a new context, if that is allowed by the security policy.
+ The client domain needs the <literal>setcurrent</literal> permission and also
+ <literal>dyntransition</literal> from the old to the new domain.
+ </para>
+ <para>
+ Dynamic domain transitions should be considered carefully, because they
+ allow users to switch their label, and therefore their privileges,
+ at their option, rather than (as in the case of a trusted procedure)
+ as mandated by the system.
+ Thus, the <literal>dyntransition</literal> permission is only considered
+ safe when used to switch to a domain with a smaller set of privileges than
+ the original one. For example:
+ </para>
+<screen>
+regression=# select sepgsql_getcon();
+ sepgsql_getcon
+-------------------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
+(1 row)
+
+regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c4');
+ sepgsql_setcon
+----------------
+ t
+(1 row)
+
+regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c1023');
+ERROR: SELinux: security policy violation
+</screen>
+ <para>
+ In this example above we were allowed to switch from the larger MCS
+ range <literal>c1.c1023</literal> to the smaller range <literal>c1.c4</literal>, but
+ switching back was denied.
+ </para>
+ <para>
+ A combination of dynamic domain transition and trusted procedure
+ enables an interesting use case that fits the typical process life-cycle
+ of connection pooling software.
+ Even if your connection pooling software is not allowed to run most
+ of SQL commands, you can allow it to switch the security label
+ of the client using the <literal>sepgsql_setcon()</literal> function
+ from within a trusted procedure; that should take some
+ credential to authorize the request to switch the client label.
+ After that, this session will have the privileges of the target user,
+ rather than the connection pooler.
+ The connection pooler can later revert the security label change by
+ again using <literal>sepgsql_setcon()</literal> with
+ <literal>NULL</literal> argument, again invoked from within a trusted
+ procedure with appropriate permissions checks.
+ The point here is that only the trusted procedure actually has permission
+ to change the effective security label, and only does so when given proper
+ credentials. Of course, for secure operation, the credential store
+ (table, procedure definition, or whatever) must be protected from
+ unauthorized access.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Miscellaneous</title>
+ <para>
+ We reject the <link linkend="sql-load"><command>LOAD</command></link> command across the board, because
+ any module loaded could easily circumvent security policy enforcement.
+ </para>
+
+ </sect3>
+</sect2>
+
+ <sect2 id="sepgsql-functions">
+ <title>Sepgsql Functions</title>
+ <para>
+ <xref linkend="sepgsql-functions-table"/> shows the available functions.
+ </para>
+
+ <table id="sepgsql-functions-table">
+ <title>Sepgsql Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sepgsql_getcon</function> ()
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Returns the client domain, the current security label of the client.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sepgsql_setcon</function> ( <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Switches the client domain of the current session to the new domain,
+ if allowed by the security policy.
+ It also accepts <literal>NULL</literal> input as a request to transition
+ to the client's original domain.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sepgsql_mcstrans_in</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Translates the given qualified MLS/MCS range into raw format if
+ the mcstrans daemon is running.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sepgsql_mcstrans_out</function> ( <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Translates the given raw MLS/MCS range into qualified format if
+ the mcstrans daemon is running.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>sepgsql_restorecon</function> ( <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Sets up initial security labels for all objects within the
+ current database. The argument may be <literal>NULL</literal>, or the
+ name of a specfile to be used as alternative of the system default.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="sepgsql-limitations">
+ <title>Limitations</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>Data Definition Language (DDL) Permissions</term>
+ <listitem>
+ <para>
+ Due to implementation restrictions, some DDL operations do not
+ check permissions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Data Control Language (DCL) Permissions</term>
+ <listitem>
+ <para>
+ Due to implementation restrictions, DCL operations do not check
+ permissions.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Row-level access control</term>
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> supports row-level access, but
+ <filename>sepgsql</filename> does not.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Covert channels</term>
+ <listitem>
+ <para>
+ <filename>sepgsql</filename> does not try to hide the existence of
+ a certain object, even if the user is not allowed to reference it.
+ For example, we can infer the existence of an invisible object as
+ a result of primary key conflicts, foreign key violations, and so on,
+ even if we cannot obtain the contents of the object. The existence
+ of a top secret table cannot be hidden; we only hope to conceal its
+ contents.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="sepgsql-resources">
+ <title>External Resources</title>
+ <variablelist>
+ <varlistentry>
+ <term><ulink url="https://wiki.postgresql.org/wiki/SEPostgreSQL">SE-PostgreSQL Introduction</ulink></term>
+ <listitem>
+ <para>
+ This wiki page provides a brief overview, security design, architecture,
+ administration and upcoming features.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><ulink url="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/index">SELinux User's and Administrator's Guide</ulink></term>
+ <listitem>
+ <para>
+ This document provides a wide spectrum of knowledge to administer
+ <productname>SELinux</productname> on your systems.
+ It focuses primarily on Red Hat operating systems, but is not limited to them.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><ulink url="https://fedoraproject.org/wiki/SELinux_FAQ">Fedora SELinux FAQ</ulink></term>
+ <listitem>
+ <para>
+ This document answers frequently asked questions about
+ <productname>SELinux</productname>.
+ It focuses primarily on Fedora, but is not limited to Fedora.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="sepgsql-author">
+ <title>Author</title>
+ <para>
+ KaiGai Kohei <email>kaigai@ak.jp.nec.com</email>
+ </para>
+ </sect2>
+</sect1>
diff --git a/doc/src/sgml/sourcerepo.sgml b/doc/src/sgml/sourcerepo.sgml
new file mode 100644
index 0000000..0ed7f8a
--- /dev/null
+++ b/doc/src/sgml/sourcerepo.sgml
@@ -0,0 +1,94 @@
+<!-- doc/src/sgml/sourcerepo.sgml -->
+
+<appendix id="sourcerepo">
+ <title>The Source Code Repository</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> source code is stored and managed
+ using the <productname>Git</productname> version control system. A public
+ mirror of the master repository is available; it is updated within a minute
+ of any change to the master repository.
+ </para>
+
+ <para>
+ Our wiki, <ulink
+ url="https://wiki.postgresql.org/wiki/Working_with_Git"></ulink>,
+ has some discussion on working with Git.
+ </para>
+
+ <para>
+ Note that building <productname>PostgreSQL</productname> from the source
+ repository requires reasonably up-to-date versions of <application>bison</application>,
+ <application>flex</application>, and <application>Perl</application>. These tools are not needed
+ to build from a distribution tarball, because the files that these tools
+ are used to build are included in the tarball. Other tool requirements
+ are the same as shown in <xref linkend="install-requirements"/>.
+ </para>
+
+ <sect1 id="git">
+ <title>Getting the Source via <productname>Git</productname></title>
+
+ <para>
+ With <productname>Git</productname> you will make a copy of the entire code repository
+ on your local machine, so you will have access to all history and branches
+ offline. This is the fastest and most flexible way to develop or test
+ patches.
+ </para>
+
+ <procedure>
+ <title>Git</title>
+
+ <step>
+ <para>
+ You will need an installed version of <productname>Git</productname>, which you can
+ get from <ulink url="https://git-scm.com"></ulink>. Many systems already
+ have a recent version of <application>Git</application> installed by default, or
+ available in their package distribution system.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ To begin using the Git repository, make a clone of the official mirror:
+
+<programlisting>
+git clone https://git.postgresql.org/git/postgresql.git
+</programlisting>
+
+ This will copy the full repository to your local machine, so it may take
+ a while to complete, especially if you have a slow Internet connection.
+ The files will be placed in a new subdirectory <filename>postgresql</filename> of
+ your current directory.
+ </para>
+
+ <para>
+ The Git mirror can also be reached via the Git protocol. Just change the URL
+ prefix to <literal>git</literal>, as in:
+
+<programlisting>
+git clone git://git.postgresql.org/git/postgresql.git
+</programlisting>
+
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Whenever you want to get the latest updates in the system, <command>cd</command>
+ into the repository, and run:
+
+<programlisting>
+git fetch
+</programlisting>
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ <productname>Git</productname> can do a lot more things than just fetch the source. For
+ more information, consult the <productname>Git</productname> man pages, or see the
+ website at <ulink url="https://git-scm.com"></ulink>.
+ </para>
+ </sect1>
+
+</appendix>
diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml
new file mode 100644
index 0000000..e0a6f77
--- /dev/null
+++ b/doc/src/sgml/sources.sgml
@@ -0,0 +1,1035 @@
+<!-- doc/src/sgml/sources.sgml -->
+
+ <chapter id="source">
+ <title>PostgreSQL Coding Conventions</title>
+
+ <sect1 id="source-format">
+ <title>Formatting</title>
+
+ <para>
+ Source code formatting uses 4 column tab spacing, with
+ tabs preserved (i.e., tabs are not expanded to spaces).
+ Each logical indentation level is one additional tab stop.
+ </para>
+
+ <para>
+ Layout rules (brace positioning, etc.) follow BSD conventions. In
+ particular, curly braces for the controlled blocks of <literal>if</literal>,
+ <literal>while</literal>, <literal>switch</literal>, etc. go on their own lines.
+ </para>
+
+ <para>
+ Limit line lengths so that the code is readable in an 80-column window.
+ (This doesn't mean that you must never go past 80 columns. For instance,
+ breaking a long error message string in arbitrary places just to keep the
+ code within 80 columns is probably not a net gain in readability.)
+ </para>
+
+ <para>
+ To maintain a consistent coding style, do not use C++ style comments
+ (<literal>//</literal> comments). <application>pgindent</application>
+ will replace them with <literal>/* ... */</literal>.
+ </para>
+
+ <para>
+ The preferred style for multi-line comment blocks is
+<programlisting>
+/*
+ * comment text begins here
+ * and continues here
+ */
+</programlisting>
+ Note that comment blocks that begin in column 1 will be preserved as-is
+ by <application>pgindent</application>, but it will re-flow indented comment blocks
+ as though they were plain text. If you want to preserve the line breaks
+ in an indented block, add dashes like this:
+<programlisting>
+ /*----------
+ * comment text begins here
+ * and continues here
+ *----------
+ */
+</programlisting>
+ </para>
+
+ <para>
+ While submitted patches do not absolutely have to follow these formatting
+ rules, it's a good idea to do so. Your code will get run through
+ <application>pgindent</application> before the next release, so there's no point in
+ making it look nice under some other set of formatting conventions.
+ A good rule of thumb for patches is <quote>make the new code look like
+ the existing code around it</quote>.
+ </para>
+
+ <para>
+ The <filename>src/tools/editors</filename> directory contains sample settings
+ files that can be used with the <productname>Emacs</productname>,
+ <productname>xemacs</productname> or <productname>vim</productname>
+ editors to help ensure that they format code according to these
+ conventions.
+ </para>
+
+ <para>
+ If you'd like to run <application>pgindent</application> locally
+ to help make your code match project style, see
+ the <filename>src/tools/pgindent</filename> directory.
+ </para>
+
+ <para>
+ The text browsing tools <application>more</application> and
+ <application>less</application> can be invoked as:
+<programlisting>
+more -x4
+less -x4
+</programlisting>
+ to make them show tabs appropriately.
+ </para>
+ </sect1>
+
+ <sect1 id="error-message-reporting">
+ <title>Reporting Errors Within the Server</title>
+
+ <indexterm>
+ <primary>ereport</primary>
+ </indexterm>
+ <indexterm>
+ <primary>elog</primary>
+ </indexterm>
+
+ <para>
+ Error, warning, and log messages generated within the server code
+ should be created using <function>ereport</function>, or its older cousin
+ <function>elog</function>. The use of this function is complex enough to
+ require some explanation.
+ </para>
+
+ <para>
+ There are two required elements for every message: a severity level
+ (ranging from <literal>DEBUG</literal> to <literal>PANIC</literal>) and a primary
+ message text. In addition there are optional elements, the most
+ common of which is an error identifier code that follows the SQL spec's
+ SQLSTATE conventions.
+ <function>ereport</function> itself is just a shell macro that exists
+ mainly for the syntactic convenience of making message generation
+ look like a single function call in the C source code. The only parameter
+ accepted directly by <function>ereport</function> is the severity level.
+ The primary message text and any optional message elements are
+ generated by calling auxiliary functions, such as <function>errmsg</function>,
+ within the <function>ereport</function> call.
+ </para>
+
+ <para>
+ A typical call to <function>ereport</function> might look like this:
+<programlisting>
+ereport(ERROR,
+ errcode(ERRCODE_DIVISION_BY_ZERO),
+ errmsg("division by zero"));
+</programlisting>
+ This specifies error severity level <literal>ERROR</literal> (a run-of-the-mill
+ error). The <function>errcode</function> call specifies the SQLSTATE error code
+ using a macro defined in <filename>src/include/utils/errcodes.h</filename>. The
+ <function>errmsg</function> call provides the primary message text.
+ </para>
+
+ <para>
+ You will also frequently see this older style, with an extra set of
+ parentheses surrounding the auxiliary function calls:
+<programlisting>
+ereport(ERROR,
+ (errcode(ERRCODE_DIVISION_BY_ZERO),
+ errmsg("division by zero")));
+</programlisting>
+ The extra parentheses were required
+ before <productname>PostgreSQL</productname> version 12, but are now
+ optional.
+ </para>
+
+ <para>
+ Here is a more complex example:
+<programlisting>
+ereport(ERROR,
+ errcode(ERRCODE_AMBIGUOUS_FUNCTION),
+ errmsg("function %s is not unique",
+ func_signature_string(funcname, nargs,
+ NIL, actual_arg_types)),
+ errhint("Unable to choose a best candidate function. "
+ "You might need to add explicit typecasts."));
+</programlisting>
+ This illustrates the use of format codes to embed run-time values into
+ a message text. Also, an optional <quote>hint</quote> message is provided.
+ The auxiliary function calls can be written in any order, but
+ conventionally <function>errcode</function>
+ and <function>errmsg</function> appear first.
+ </para>
+
+ <para>
+ If the severity level is <literal>ERROR</literal> or higher,
+ <function>ereport</function> aborts execution of the current query
+ and does not return to the caller. If the severity level is
+ lower than <literal>ERROR</literal>, <function>ereport</function> returns normally.
+ </para>
+
+ <para>
+ The available auxiliary routines for <function>ereport</function> are:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <function>errcode(sqlerrcode)</function> specifies the SQLSTATE error identifier
+ code for the condition. If this routine is not called, the error
+ identifier defaults to
+ <literal>ERRCODE_INTERNAL_ERROR</literal> when the error severity level is
+ <literal>ERROR</literal> or higher, <literal>ERRCODE_WARNING</literal> when the
+ error level is <literal>WARNING</literal>, otherwise (for <literal>NOTICE</literal>
+ and below) <literal>ERRCODE_SUCCESSFUL_COMPLETION</literal>.
+ While these defaults are often convenient, always think whether they
+ are appropriate before omitting the <function>errcode()</function> call.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errmsg(const char *msg, ...)</function> specifies the primary error
+ message text, and possibly run-time values to insert into it. Insertions
+ are specified by <function>sprintf</function>-style format codes. In addition to
+ the standard format codes accepted by <function>sprintf</function>, the format
+ code <literal>%m</literal> can be used to insert the error message returned
+ by <function>strerror</function> for the current value of <literal>errno</literal>.
+ <footnote>
+ <para>
+ That is, the value that was current when the <function>ereport</function> call
+ was reached; changes of <literal>errno</literal> within the auxiliary reporting
+ routines will not affect it. That would not be true if you were to
+ write <literal>strerror(errno)</literal> explicitly in <function>errmsg</function>'s
+ parameter list; accordingly, do not do so.
+ </para>
+ </footnote>
+ <literal>%m</literal> does not require any
+ corresponding entry in the parameter list for <function>errmsg</function>.
+ Note that the message string will be run through <function>gettext</function>
+ for possible localization before format codes are processed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errmsg_internal(const char *msg, ...)</function> is the same as
+ <function>errmsg</function>, except that the message string will not be
+ translated nor included in the internationalization message dictionary.
+ This should be used for <quote>cannot happen</quote> cases that are probably
+ not worth expending translation effort on.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errmsg_plural(const char *fmt_singular, const char *fmt_plural,
+ unsigned long n, ...)</function> is like <function>errmsg</function>, but with
+ support for various plural forms of the message.
+ <replaceable>fmt_singular</replaceable> is the English singular format,
+ <replaceable>fmt_plural</replaceable> is the English plural format,
+ <replaceable>n</replaceable> is the integer value that determines which plural
+ form is needed, and the remaining arguments are formatted according
+ to the selected format string. For more information see
+ <xref linkend="nls-guidelines"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdetail(const char *msg, ...)</function> supplies an optional
+ <quote>detail</quote> message; this is to be used when there is additional
+ information that seems inappropriate to put in the primary message.
+ The message string is processed in just the same way as for
+ <function>errmsg</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdetail_internal(const char *msg, ...)</function> is the same
+ as <function>errdetail</function>, except that the message string will not be
+ translated nor included in the internationalization message dictionary.
+ This should be used for detail messages that are not worth expending
+ translation effort on, for instance because they are too technical to be
+ useful to most users.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdetail_plural(const char *fmt_singular, const char *fmt_plural,
+ unsigned long n, ...)</function> is like <function>errdetail</function>, but with
+ support for various plural forms of the message.
+ For more information see <xref linkend="nls-guidelines"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdetail_log(const char *msg, ...)</function> is the same as
+ <function>errdetail</function> except that this string goes only to the server
+ log, never to the client. If both <function>errdetail</function> (or one of
+ its equivalents above) and
+ <function>errdetail_log</function> are used then one string goes to the client
+ and the other to the log. This is useful for error details that are
+ too security-sensitive or too bulky to include in the report
+ sent to the client.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdetail_log_plural(const char *fmt_singular, const char
+ *fmt_plural, unsigned long n, ...)</function> is like
+ <function>errdetail_log</function>, but with support for various plural forms of
+ the message.
+ For more information see <xref linkend="nls-guidelines"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errhint(const char *msg, ...)</function> supplies an optional
+ <quote>hint</quote> message; this is to be used when offering suggestions
+ about how to fix the problem, as opposed to factual details about
+ what went wrong.
+ The message string is processed in just the same way as for
+ <function>errmsg</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errhint_plural(const char *fmt_singular, const char *fmt_plural,
+ unsigned long n, ...)</function> is like <function>errhint</function>, but with
+ support for various plural forms of the message.
+ For more information see <xref linkend="nls-guidelines"/>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errcontext(const char *msg, ...)</function> is not normally called
+ directly from an <function>ereport</function> message site; rather it is used
+ in <literal>error_context_stack</literal> callback functions to provide
+ information about the context in which an error occurred, such as the
+ current location in a PL function.
+ The message string is processed in just the same way as for
+ <function>errmsg</function>. Unlike the other auxiliary functions, this can
+ be called more than once per <function>ereport</function> call; the successive
+ strings thus supplied are concatenated with separating newlines.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errposition(int cursorpos)</function> specifies the textual location
+ of an error within a query string. Currently it is only useful for
+ errors detected in the lexical and syntactic analysis phases of
+ query processing.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errtable(Relation rel)</function> specifies a relation whose
+ name and schema name should be included as auxiliary fields in the error
+ report.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errtablecol(Relation rel, int attnum)</function> specifies
+ a column whose name, table name, and schema name should be included as
+ auxiliary fields in the error report.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errtableconstraint(Relation rel, const char *conname)</function>
+ specifies a table constraint whose name, table name, and schema name
+ should be included as auxiliary fields in the error report. Indexes
+ should be considered to be constraints for this purpose, whether or
+ not they have an associated <structname>pg_constraint</structname> entry. Be
+ careful to pass the underlying heap relation, not the index itself, as
+ <literal>rel</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdatatype(Oid datatypeOid)</function> specifies a data
+ type whose name and schema name should be included as auxiliary fields
+ in the error report.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errdomainconstraint(Oid datatypeOid, const char *conname)</function>
+ specifies a domain constraint whose name, domain name, and schema name
+ should be included as auxiliary fields in the error report.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errcode_for_file_access()</function> is a convenience function that
+ selects an appropriate SQLSTATE error identifier for a failure in a
+ file-access-related system call. It uses the saved
+ <literal>errno</literal> to determine which error code to generate.
+ Usually this should be used in combination with <literal>%m</literal> in the
+ primary error message text.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errcode_for_socket_access()</function> is a convenience function that
+ selects an appropriate SQLSTATE error identifier for a failure in a
+ socket-related system call.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errhidestmt(bool hide_stmt)</function> can be called to specify
+ suppression of the <literal>STATEMENT:</literal> portion of a message in the
+ postmaster log. Generally this is appropriate if the message text
+ includes the current statement already.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <function>errhidecontext(bool hide_ctx)</function> can be called to
+ specify suppression of the <literal>CONTEXT:</literal> portion of a message in
+ the postmaster log. This should only be used for verbose debugging
+ messages where the repeated inclusion of context would bloat the log
+ too much.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <note>
+ <para>
+ At most one of the functions <function>errtable</function>,
+ <function>errtablecol</function>, <function>errtableconstraint</function>,
+ <function>errdatatype</function>, or <function>errdomainconstraint</function> should
+ be used in an <function>ereport</function> call. These functions exist to
+ allow applications to extract the name of a database object associated
+ with the error condition without having to examine the
+ potentially-localized error message text.
+ These functions should be used in error reports for which it's likely
+ that applications would wish to have automatic error handling. As of
+ <productname>PostgreSQL</productname> 9.3, complete coverage exists only for
+ errors in SQLSTATE class 23 (integrity constraint violation), but this
+ is likely to be expanded in future.
+ </para>
+ </note>
+
+ <para>
+ There is an older function <function>elog</function> that is still heavily used.
+ An <function>elog</function> call:
+<programlisting>
+elog(level, "format string", ...);
+</programlisting>
+ is exactly equivalent to:
+<programlisting>
+ereport(level, errmsg_internal("format string", ...));
+</programlisting>
+ Notice that the SQLSTATE error code is always defaulted, and the message
+ string is not subject to translation.
+ Therefore, <function>elog</function> should be used only for internal errors and
+ low-level debug logging. Any message that is likely to be of interest to
+ ordinary users should go through <function>ereport</function>. Nonetheless,
+ there are enough internal <quote>cannot happen</quote> error checks in the
+ system that <function>elog</function> is still widely used; it is preferred for
+ those messages for its notational simplicity.
+ </para>
+
+ <para>
+ Advice about writing good error messages can be found in
+ <xref linkend="error-style-guide"/>.
+ </para>
+ </sect1>
+
+ <sect1 id="error-style-guide">
+ <title>Error Message Style Guide</title>
+
+ <para>
+ This style guide is offered in the hope of maintaining a consistent,
+ user-friendly style throughout all the messages generated by
+ <productname>PostgreSQL</productname>.
+ </para>
+
+ <simplesect>
+ <title>What Goes Where</title>
+
+ <para>
+ The primary message should be short, factual, and avoid reference to
+ implementation details such as specific function names.
+ <quote>Short</quote> means <quote>should fit on one line under normal
+ conditions</quote>. Use a detail message if needed to keep the primary
+ message short, or if you feel a need to mention implementation details
+ such as the particular system call that failed. Both primary and detail
+ messages should be factual. Use a hint message for suggestions about what
+ to do to fix the problem, especially if the suggestion might not always be
+ applicable.
+ </para>
+
+ <para>
+ For example, instead of:
+<programlisting>
+IpcMemoryCreate: shmget(key=%d, size=%u, 0%o) failed: %m
+(plus a long addendum that is basically a hint)
+</programlisting>
+ write:
+<programlisting>
+Primary: could not create shared memory segment: %m
+Detail: Failed syscall was shmget(key=%d, size=%u, 0%o).
+Hint: the addendum
+</programlisting>
+ </para>
+
+ <para>
+ Rationale: keeping the primary message short helps keep it to the point,
+ and lets clients lay out screen space on the assumption that one line is
+ enough for error messages. Detail and hint messages can be relegated to a
+ verbose mode, or perhaps a pop-up error-details window. Also, details and
+ hints would normally be suppressed from the server log to save
+ space. Reference to implementation details is best avoided since users
+ aren't expected to know the details.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Formatting</title>
+
+ <para>
+ Don't put any specific assumptions about formatting into the message
+ texts. Expect clients and the server log to wrap lines to fit their own
+ needs. In long messages, newline characters (\n) can be used to indicate
+ suggested paragraph breaks. Don't end a message with a newline. Don't
+ use tabs or other formatting characters. (In error context displays,
+ newlines are automatically added to separate levels of context such as
+ function calls.)
+ </para>
+
+ <para>
+ Rationale: Messages are not necessarily displayed on terminal-type
+ displays. In GUI displays or browsers these formatting instructions are
+ at best ignored.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Quotation Marks</title>
+
+ <para>
+ English text should use double quotes when quoting is appropriate.
+ Text in other languages should consistently use one kind of quotes that is
+ consistent with publishing customs and computer output of other programs.
+ </para>
+
+ <para>
+ Rationale: The choice of double quotes over single quotes is somewhat
+ arbitrary, but tends to be the preferred use. Some have suggested
+ choosing the kind of quotes depending on the type of object according to
+ SQL conventions (namely, strings single quoted, identifiers double
+ quoted). But this is a language-internal technical issue that many users
+ aren't even familiar with, it won't scale to other kinds of quoted terms,
+ it doesn't translate to other languages, and it's pretty pointless, too.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Use of Quotes</title>
+
+ <para>
+ Always use quotes to delimit file names, user-supplied identifiers, and
+ other variables that might contain words. Do not use them to mark up
+ variables that will not contain words (for example, operator names).
+ </para>
+
+ <para>
+ There are functions in the backend that will double-quote their own output
+ as needed (for example, <function>format_type_be()</function>). Do not put
+ additional quotes around the output of such functions.
+ </para>
+
+ <para>
+ Rationale: Objects can have names that create ambiguity when embedded in a
+ message. Be consistent about denoting where a plugged-in name starts and
+ ends. But don't clutter messages with unnecessary or duplicate quote
+ marks.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Grammar and Punctuation</title>
+
+ <para>
+ The rules are different for primary error messages and for detail/hint
+ messages:
+ </para>
+
+ <para>
+ Primary error messages: Do not capitalize the first letter. Do not end a
+ message with a period. Do not even think about ending a message with an
+ exclamation point.
+ </para>
+
+ <para>
+ Detail and hint messages: Use complete sentences, and end each with
+ a period. Capitalize the first word of sentences. Put two spaces after
+ the period if another sentence follows (for English text; might be
+ inappropriate in other languages).
+ </para>
+
+ <para>
+ Error context strings: Do not capitalize the first letter and do
+ not end the string with a period. Context strings should normally
+ not be complete sentences.
+ </para>
+
+ <para>
+ Rationale: Avoiding punctuation makes it easier for client applications to
+ embed the message into a variety of grammatical contexts. Often, primary
+ messages are not grammatically complete sentences anyway. (And if they're
+ long enough to be more than one sentence, they should be split into
+ primary and detail parts.) However, detail and hint messages are longer
+ and might need to include multiple sentences. For consistency, they should
+ follow complete-sentence style even when there's only one sentence.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Upper Case vs. Lower Case</title>
+
+ <para>
+ Use lower case for message wording, including the first letter of a
+ primary error message. Use upper case for SQL commands and key words if
+ they appear in the message.
+ </para>
+
+ <para>
+ Rationale: It's easier to make everything look more consistent this
+ way, since some messages are complete sentences and some not.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Avoid Passive Voice</title>
+
+ <para>
+ Use the active voice. Use complete sentences when there is an acting
+ subject (<quote>A could not do B</quote>). Use telegram style without
+ subject if the subject would be the program itself; do not use
+ <quote>I</quote> for the program.
+ </para>
+
+ <para>
+ Rationale: The program is not human. Don't pretend otherwise.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Present vs. Past Tense</title>
+
+ <para>
+ Use past tense if an attempt to do something failed, but could perhaps
+ succeed next time (perhaps after fixing some problem). Use present tense
+ if the failure is certainly permanent.
+ </para>
+
+ <para>
+ There is a nontrivial semantic difference between sentences of the form:
+<programlisting>
+could not open file "%s": %m
+</programlisting>
+and:
+<programlisting>
+cannot open file "%s"
+</programlisting>
+ The first one means that the attempt to open the file failed. The
+ message should give a reason, such as <quote>disk full</quote> or
+ <quote>file doesn't exist</quote>. The past tense is appropriate because
+ next time the disk might not be full anymore or the file in question might
+ exist.
+ </para>
+
+ <para>
+ The second form indicates that the functionality of opening the named file
+ does not exist at all in the program, or that it's conceptually
+ impossible. The present tense is appropriate because the condition will
+ persist indefinitely.
+ </para>
+
+ <para>
+ Rationale: Granted, the average user will not be able to draw great
+ conclusions merely from the tense of the message, but since the language
+ provides us with a grammar we should use it correctly.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Type of the Object</title>
+
+ <para>
+ When citing the name of an object, state what kind of object it is.
+ </para>
+
+ <para>
+ Rationale: Otherwise no one will know what <quote>foo.bar.baz</quote>
+ refers to.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Brackets</title>
+
+ <para>
+ Square brackets are only to be used (1) in command synopses to denote
+ optional arguments, or (2) to denote an array subscript.
+ </para>
+
+ <para>
+ Rationale: Anything else does not correspond to widely-known customary
+ usage and will confuse people.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Assembling Error Messages</title>
+
+ <para>
+ When a message includes text that is generated elsewhere, embed it in
+ this style:
+<programlisting>
+could not open file %s: %m
+</programlisting>
+ </para>
+
+ <para>
+ Rationale: It would be difficult to account for all possible error codes
+ to paste this into a single smooth sentence, so some sort of punctuation
+ is needed. Putting the embedded text in parentheses has also been
+ suggested, but it's unnatural if the embedded text is likely to be the
+ most important part of the message, as is often the case.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Reasons for Errors</title>
+
+ <para>
+ Messages should always state the reason why an error occurred.
+ For example:
+<programlisting>
+BAD: could not open file %s
+BETTER: could not open file %s (I/O failure)
+</programlisting>
+ If no reason is known you better fix the code.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Function Names</title>
+
+ <para>
+ Don't include the name of the reporting routine in the error text. We have
+ other mechanisms for finding that out when needed, and for most users it's
+ not helpful information. If the error text doesn't make as much sense
+ without the function name, reword it.
+<programlisting>
+BAD: pg_strtoint32: error in "z": cannot parse "z"
+BETTER: invalid input syntax for type integer: "z"
+</programlisting>
+ </para>
+
+ <para>
+ Avoid mentioning called function names, either; instead say what the code
+ was trying to do:
+<programlisting>
+BAD: open() failed: %m
+BETTER: could not open file %s: %m
+</programlisting>
+ If it really seems necessary, mention the system call in the detail
+ message. (In some cases, providing the actual values passed to the
+ system call might be appropriate information for the detail message.)
+ </para>
+
+ <para>
+ Rationale: Users don't know what all those functions do.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Tricky Words to Avoid</title>
+
+ <formalpara>
+ <title>Unable</title>
+ <para>
+ <quote>Unable</quote> is nearly the passive voice. Better use
+ <quote>cannot</quote> or <quote>could not</quote>, as appropriate.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Bad</title>
+ <para>
+ Error messages like <quote>bad result</quote> are really hard to interpret
+ intelligently. It's better to write why the result is <quote>bad</quote>,
+ e.g., <quote>invalid format</quote>.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Illegal</title>
+ <para>
+ <quote>Illegal</quote> stands for a violation of the law, the rest is
+ <quote>invalid</quote>. Better yet, say why it's invalid.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Unknown</title>
+ <para>
+ Try to avoid <quote>unknown</quote>. Consider <quote>error: unknown
+ response</quote>. If you don't know what the response is, how do you know
+ it's erroneous? <quote>Unrecognized</quote> is often a better choice.
+ Also, be sure to include the value being complained of.
+<programlisting>
+BAD: unknown node type
+BETTER: unrecognized node type: 42
+</programlisting>
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Find vs. Exists</title>
+ <para>
+ If the program uses a nontrivial algorithm to locate a resource (e.g., a
+ path search) and that algorithm fails, it is fair to say that the program
+ couldn't <quote>find</quote> the resource. If, on the other hand, the
+ expected location of the resource is known but the program cannot access
+ it there then say that the resource doesn't <quote>exist</quote>. Using
+ <quote>find</quote> in this case sounds weak and confuses the issue.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>May vs. Can vs. Might</title>
+ <para>
+ <quote>May</quote> suggests permission (e.g., "You may borrow my rake."),
+ and has little use in documentation or error messages.
+ <quote>Can</quote> suggests ability (e.g., "I can lift that log."),
+ and <quote>might</quote> suggests possibility (e.g., "It might rain
+ today."). Using the proper word clarifies meaning and assists
+ translation.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Contractions</title>
+ <para>
+ Avoid contractions, like <quote>can't</quote>; use
+ <quote>cannot</quote> instead.
+ </para>
+ </formalpara>
+
+ <formalpara>
+ <title>Non-negative</title>
+ <para>
+ Avoid <quote>non-negative</quote> as it is ambiguous
+ about whether it accepts zero. It's better to use
+ <quote>greater than zero</quote> or
+ <quote>greater than or equal to zero</quote>.
+ </para>
+ </formalpara>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Proper Spelling</title>
+
+ <para>
+ Spell out words in full. For instance, avoid:
+ <itemizedlist>
+ <listitem>
+ <para>
+ spec
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ stats
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ parens
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ auth
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ xact
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Rationale: This will improve consistency.
+ </para>
+
+ </simplesect>
+
+ <simplesect>
+ <title>Localization</title>
+
+ <para>
+ Keep in mind that error message texts need to be translated into other
+ languages. Follow the guidelines in <xref linkend="nls-guidelines"/>
+ to avoid making life difficult for translators.
+ </para>
+ </simplesect>
+
+ </sect1>
+
+ <sect1 id="source-conventions">
+ <title>Miscellaneous Coding Conventions</title>
+
+ <simplesect>
+ <title>C Standard</title>
+ <para>
+ Code in <productname>PostgreSQL</productname> should only rely on language
+ features available in the C99 standard. That means a conforming
+ C99 compiler has to be able to compile postgres, at least aside
+ from a few platform dependent pieces.
+ </para>
+ <para>
+ A few features included in the C99 standard are, at this time, not
+ permitted to be used in core <productname>PostgreSQL</productname>
+ code. This currently includes variable length arrays, intermingled
+ declarations and code, <literal>//</literal> comments, universal
+ character names. Reasons for that include portability and historical
+ practices.
+ </para>
+ <para>
+ Features from later revisions of the C standard or compiler specific
+ features can be used, if a fallback is provided.
+ </para>
+ <para>
+ For example <literal>_Static_assert()</literal> and
+ <literal>__builtin_constant_p</literal> are currently used, even though
+ they are from newer revisions of the C standard and a
+ <productname>GCC</productname> extension respectively. If not available
+ we respectively fall back to using a C99 compatible replacement that
+ performs the same checks, but emits rather cryptic messages and do not
+ use <literal>__builtin_constant_p</literal>.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Function-Like Macros and Inline Functions</title>
+ <para>
+ Both macros with arguments and <literal>static inline</literal>
+ functions may be used. The latter are preferable if there are
+ multiple-evaluation hazards when written as a macro, as e.g., the
+ case with
+<programlisting>
+#define Max(x, y) ((x) > (y) ? (x) : (y))
+</programlisting>
+ or when the macro would be very long. In other cases it's only
+ possible to use macros, or at least easier. For example because
+ expressions of various types need to be passed to the macro.
+ </para>
+ <para>
+ When the definition of an inline function references symbols
+ (i.e., variables, functions) that are only available as part of the
+ backend, the function may not be visible when included from frontend
+ code.
+<programlisting>
+#ifndef FRONTEND
+static inline MemoryContext
+MemoryContextSwitchTo(MemoryContext context)
+{
+ MemoryContext old = CurrentMemoryContext;
+
+ CurrentMemoryContext = context;
+ return old;
+}
+#endif /* FRONTEND */
+</programlisting>
+ In this example <literal>CurrentMemoryContext</literal>, which is only
+ available in the backend, is referenced and the function thus
+ hidden with a <literal>#ifndef FRONTEND</literal>. This rule
+ exists because some compilers emit references to symbols
+ contained in inline functions even if the function is not used.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Writing Signal Handlers</title>
+ <para>
+ To be suitable to run inside a signal handler code has to be
+ written very carefully. The fundamental problem is that, unless
+ blocked, a signal handler can interrupt code at any time. If code
+ inside the signal handler uses the same state as code outside
+ chaos may ensue. As an example consider what happens if a signal
+ handler tries to acquire a lock that's already held in the
+ interrupted code.
+ </para>
+ <para>
+ Barring special arrangements code in signal handlers may only
+ call async-signal safe functions (as defined in POSIX) and access
+ variables of type <literal>volatile sig_atomic_t</literal>. A few
+ functions in <command>postgres</command> are also deemed signal safe, importantly
+ <function>SetLatch()</function>.
+ </para>
+ <para>
+ In most cases signal handlers should do nothing more than note
+ that a signal has arrived, and wake up code running outside of
+ the handler using a latch. An example of such a handler is the
+ following:
+<programlisting>
+static void
+handle_sighup(SIGNAL_ARGS)
+{
+ int save_errno = errno;
+
+ got_SIGHUP = true;
+ SetLatch(MyLatch);
+
+ errno = save_errno;
+}
+</programlisting>
+ <varname>errno</varname> is saved and restored because
+ <function>SetLatch()</function> might change it. If that were not done
+ interrupted code that's currently inspecting <varname>errno</varname> might see the wrong
+ value.
+ </para>
+ </simplesect>
+
+ <simplesect>
+ <title>Calling Function Pointers</title>
+
+ <para>
+ For clarity, it is preferred to explicitly dereference a function pointer
+ when calling the pointed-to function if the pointer is a simple variable,
+ for example:
+<programlisting>
+(*emit_log_hook) (edata);
+</programlisting>
+ (even though <literal>emit_log_hook(edata)</literal> would also work).
+ When the function pointer is part of a structure, then the extra
+ punctuation can and usually should be omitted, for example:
+<programlisting>
+paramInfo->paramFetch(paramInfo, paramId);
+</programlisting>
+ </para>
+ </simplesect>
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml
new file mode 100644
index 0000000..102f862
--- /dev/null
+++ b/doc/src/sgml/spgist.sgml
@@ -0,0 +1,1076 @@
+<!-- doc/src/sgml/spgist.sgml -->
+
+<chapter id="spgist">
+<title>SP-GiST Indexes</title>
+
+ <indexterm>
+ <primary>index</primary>
+ <secondary>SP-GiST</secondary>
+ </indexterm>
+
+<sect1 id="spgist-intro">
+ <title>Introduction</title>
+
+ <para>
+ <acronym>SP-GiST</acronym> is an abbreviation for space-partitioned
+ <acronym>GiST</acronym>. <acronym>SP-GiST</acronym> supports partitioned
+ search trees, which facilitate development of a wide range of different
+ non-balanced data structures, such as quad-trees, k-d trees, and radix
+ trees (tries). The common feature of these structures is that they
+ repeatedly divide the search space into partitions that need not be
+ of equal size. Searches that are well matched to the partitioning rule
+ can be very fast.
+ </para>
+
+ <para>
+ These popular data structures were originally developed for in-memory
+ usage. In main memory, they are usually designed as a set of dynamically
+ allocated nodes linked by pointers. This is not suitable for direct
+ storing on disk, since these chains of pointers can be rather long which
+ would require too many disk accesses. In contrast, disk-based data
+ structures should have a high fanout to minimize I/O. The challenge
+ addressed by <acronym>SP-GiST</acronym> is to map search tree nodes to
+ disk pages in such a way that a search need access only a few disk pages,
+ even if it traverses many nodes.
+ </para>
+
+ <para>
+ Like <acronym>GiST</acronym>, <acronym>SP-GiST</acronym> is meant to allow
+ the development of custom data types with the appropriate access methods,
+ by an expert in the domain of the data type, rather than a database expert.
+ </para>
+
+ <para>
+ Some of the information here is derived from Purdue University's
+ SP-GiST Indexing Project
+ <ulink url="https://www.cs.purdue.edu/spgist/">web site</ulink>.
+ The <acronym>SP-GiST</acronym> implementation in
+ <productname>PostgreSQL</productname> is primarily maintained by Teodor
+ Sigaev and Oleg Bartunov, and there is more information on their
+ <!-- URL will be changed -->
+ <ulink url="http://www.sai.msu.su/~megera/wiki/spgist_dev">web site</ulink>.
+ </para>
+
+</sect1>
+
+<sect1 id="spgist-builtin-opclasses">
+ <title>Built-in Operator Classes</title>
+
+ <para>
+ The core <productname>PostgreSQL</productname> distribution
+ includes the <acronym>SP-GiST</acronym> operator classes shown in
+ <xref linkend="spgist-builtin-opclasses-table"/>.
+ </para>
+
+ <table id="spgist-builtin-opclasses-table">
+ <title>Built-in <acronym>SP-GiST</acronym> Operator Classes</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Name</entry>
+ <entry>Indexable Operators</entry>
+ <entry>Ordering Operators</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry valign="middle" morerows="11"><literal>box_ops</literal></entry>
+ <entry><literal>&lt;&lt; (box,box)</literal></entry>
+ <entry valign="middle" morerows="11"><literal>&lt;-&gt; (box,point)</literal></entry>
+ </row>
+ <row><entry><literal>&amp;&lt; (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>&lt;@ (box,box)</literal></entry></row>
+ <row><entry><literal>@&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>~= (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (box,box)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (box,box)</literal></entry></row>
+ <row><entry><literal>&amp;&lt;| (box,box)</literal></entry></row>
+ <row><entry><literal>|&amp;&gt; (box,box)</literal></entry></row>
+ <row><entry><literal>|&gt;&gt; (box,box)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="10"><literal>inet_ops</literal></entry>
+ <entry><literal>&lt;&lt; (inet,inet)</literal></entry>
+ <entry valign="middle" morerows="10"></entry>
+ </row>
+ <row><entry><literal>&lt;&lt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;&gt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&lt;&gt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&lt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&lt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt; (inet,inet)</literal></entry></row>
+ <row><entry><literal>&gt;= (inet,inet)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (inet,inet)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="5"><literal>kd_point_ops</literal></entry>
+ <entry><literal>|&gt;&gt; (point,point)</literal></entry>
+ <entry valign="middle" morerows="5"><literal>&lt;-&gt; (point,point)</literal></entry>
+ </row>
+ <row><entry><literal>&lt;&lt; (point,point)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (point,point)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (point,point)</literal></entry></row>
+ <row><entry><literal>~= (point,point)</literal></entry></row>
+ <row><entry><literal>&lt;@ (point,box)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="11"><literal>poly_ops</literal></entry>
+ <entry><literal>&lt;&lt; (polygon,polygon)</literal></entry>
+ <entry valign="middle" morerows="11"><literal>&lt;-&gt; (polygon,point)</literal></entry>
+ </row>
+ <row><entry><literal>&amp;&lt; (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>&lt;@ (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>@&gt; (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>~= (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>&amp;&amp; (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>&amp;&lt;| (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>|&gt;&gt; (polygon,polygon)</literal></entry></row>
+ <row><entry><literal>|&amp;&gt; (polygon,polygon)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="5"><literal>quad_point_ops</literal></entry>
+ <entry><literal>|&gt;&gt; (point,point)</literal></entry>
+ <entry valign="middle" morerows="5"><literal>&lt;-&gt; (point,point)</literal></entry>
+ </row>
+ <row><entry><literal>&lt;&lt; (point,point)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (point,point)</literal></entry></row>
+ <row><entry><literal>&lt;&lt;| (point,point)</literal></entry></row>
+ <row><entry><literal>~= (point,point)</literal></entry></row>
+ <row><entry><literal>&lt;@ (point,box)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="9"><literal>range_ops</literal></entry>
+ <entry><literal>= (anyrange,anyrange)</literal></entry>
+ <entry valign="middle" morerows="9"></entry>
+ </row>
+ <row><entry><literal>&amp;&amp; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange,anyelement)</literal></entry></row>
+ <row><entry><literal>@&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;@ (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&lt;&lt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&gt;&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&lt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>&amp;&gt; (anyrange,anyrange)</literal></entry></row>
+ <row><entry><literal>-|- (anyrange,anyrange)</literal></entry></row>
+
+ <row>
+ <entry valign="middle" morerows="9"><literal>text_ops</literal></entry>
+ <entry><literal>= (text,text)</literal></entry>
+ <entry valign="middle" morerows="9"></entry>
+ </row>
+ <row><entry><literal>&lt; (text,text)</literal></entry></row>
+ <row><entry><literal>&lt;= (text,text)</literal></entry></row>
+ <row><entry><literal>&gt; (text,text)</literal></entry></row>
+ <row><entry><literal>&gt;= (text,text)</literal></entry></row>
+ <row><entry><literal>~&lt;~ (text,text)</literal></entry></row>
+ <row><entry><literal>~&lt;=~ (text,text)</literal></entry></row>
+ <row><entry><literal>~&gt;=~ (text,text)</literal></entry></row>
+ <row><entry><literal>~&gt;~ (text,text)</literal></entry></row>
+ <row><entry><literal>^@ (text,text)</literal></entry></row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Of the two operator classes for type <type>point</type>,
+ <literal>quad_point_ops</literal> is the default. <literal>kd_point_ops</literal>
+ supports the same operators but uses a different index data structure that
+ may offer better performance in some applications.
+ </para>
+ <para>
+ The <literal>quad_point_ops</literal>, <literal>kd_point_ops</literal> and
+ <literal>poly_ops</literal> operator classes support the <literal>&lt;-&gt;</literal>
+ ordering operator, which enables the k-nearest neighbor (<literal>k-NN</literal>)
+ search over indexed point or polygon data sets.
+ </para>
+
+</sect1>
+
+<sect1 id="spgist-extensibility">
+ <title>Extensibility</title>
+
+ <para>
+ <acronym>SP-GiST</acronym> offers an interface with a high level of
+ abstraction, requiring the access method developer to implement only
+ methods specific to a given data type. The <acronym>SP-GiST</acronym> core
+ is responsible for efficient disk mapping and searching the tree structure.
+ It also takes care of concurrency and logging considerations.
+ </para>
+
+ <para>
+ Leaf tuples of an <acronym>SP-GiST</acronym> tree usually contain values
+ of the same data type as the indexed column, although it is also possible
+ for them to contain lossy representations of the indexed column.
+ Leaf tuples stored at the root level will directly represent
+ the original indexed data value, but leaf tuples at lower
+ levels might contain only a partial value, such as a suffix.
+ In that case the operator class support functions must be able to
+ reconstruct the original value using information accumulated from the
+ inner tuples that are passed through to reach the leaf level.
+ </para>
+
+ <para>
+ When an <acronym>SP-GiST</acronym> index is created with
+ <literal>INCLUDE</literal> columns, the values of those columns are also
+ stored in leaf tuples. The <literal>INCLUDE</literal> columns are of no
+ concern to the <acronym>SP-GiST</acronym> operator class, so they are
+ not discussed further here.
+ </para>
+
+ <para>
+ Inner tuples are more complex, since they are branching points in the
+ search tree. Each inner tuple contains a set of one or more
+ <firstterm>nodes</firstterm>, which represent groups of similar leaf values.
+ A node contains a downlink that leads either to another, lower-level inner
+ tuple, or to a short list of leaf tuples that all lie on the same index page.
+ Each node normally has a <firstterm>label</firstterm> that describes it; for example,
+ in a radix tree the node label could be the next character of the string
+ value. (Alternatively, an operator class can omit the node labels, if it
+ works with a fixed set of nodes for all inner tuples;
+ see <xref linkend="spgist-null-labels"/>.)
+ Optionally, an inner tuple can have a <firstterm>prefix</firstterm> value
+ that describes all its members. In a radix tree this could be the common
+ prefix of the represented strings. The prefix value is not necessarily
+ really a prefix, but can be any data needed by the operator class;
+ for example, in a quad-tree it can store the central point that the four
+ quadrants are measured with respect to. A quad-tree inner tuple would
+ then also contain four nodes corresponding to the quadrants around this
+ central point.
+ </para>
+
+ <para>
+ Some tree algorithms require knowledge of level (or depth) of the current
+ tuple, so the <acronym>SP-GiST</acronym> core provides the possibility for
+ operator classes to manage level counting while descending the tree.
+ There is also support for incrementally reconstructing the represented
+ value when that is needed, and for passing down additional data (called
+ <firstterm>traverse values</firstterm>) during a tree descent.
+ </para>
+
+ <note>
+ <para>
+ The <acronym>SP-GiST</acronym> core code takes care of null entries.
+ Although <acronym>SP-GiST</acronym> indexes do store entries for nulls
+ in indexed columns, this is hidden from the index operator class code:
+ no null index entries or search conditions will ever be passed to the
+ operator class methods. (It is assumed that <acronym>SP-GiST</acronym>
+ operators are strict and so cannot succeed for null values.) Null values
+ are therefore not discussed further here.
+ </para>
+ </note>
+
+ <para>
+ There are five user-defined methods that an index operator class for
+ <acronym>SP-GiST</acronym> must provide, and two are optional. All five
+ mandatory methods follow the convention of accepting two <type>internal</type>
+ arguments, the first of which is a pointer to a C struct containing input
+ values for the support method, while the second argument is a pointer to a
+ C struct where output values must be placed. Four of the mandatory methods just
+ return <type>void</type>, since all their results appear in the output struct; but
+ <function>leaf_consistent</function> returns a <type>boolean</type> result.
+ The methods must not modify any fields of their input structs. In all
+ cases, the output struct is initialized to zeroes before calling the
+ user-defined method. The optional sixth method <function>compress</function>
+ accepts a <type>datum</type> to be indexed as the only argument and returns a value suitable
+ for physical storage in a leaf tuple. The optional seventh method
+ <function>options</function> accepts an <type>internal</type> pointer to a C struct, where
+ opclass-specific parameters should be placed, and returns <type>void</type>.
+ </para>
+
+ <para>
+ The five mandatory user-defined methods are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>config</function></term>
+ <listitem>
+ <para>
+ Returns static information about the index implementation, including
+ the data type OIDs of the prefix and node label data types.
+ </para>
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+<programlisting>
+CREATE FUNCTION my_config(internal, internal) RETURNS void ...
+</programlisting>
+ The first argument is a pointer to a <structname>spgConfigIn</structname>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <structname>spgConfigOut</structname>
+ C struct, which the function must fill with result data.
+<programlisting>
+typedef struct spgConfigIn
+{
+ Oid attType; /* Data type to be indexed */
+} spgConfigIn;
+
+typedef struct spgConfigOut
+{
+ Oid prefixType; /* Data type of inner-tuple prefixes */
+ Oid labelType; /* Data type of inner-tuple node labels */
+ Oid leafType; /* Data type of leaf-tuple values */
+ bool canReturnData; /* Opclass can reconstruct original data */
+ bool longValuesOK; /* Opclass can cope with values &gt; 1 page */
+} spgConfigOut;
+</programlisting>
+
+ <structfield>attType</structfield> is passed in order to support polymorphic
+ index operator classes; for ordinary fixed-data-type operator classes, it
+ will always have the same value and so can be ignored.
+ </para>
+
+ <para>
+ For operator classes that do not use prefixes,
+ <structfield>prefixType</structfield> can be set to <literal>VOIDOID</literal>.
+ Likewise, for operator classes that do not use node labels,
+ <structfield>labelType</structfield> can be set to <literal>VOIDOID</literal>.
+ <structfield>canReturnData</structfield> should be set true if the operator class
+ is capable of reconstructing the originally-supplied index value.
+ <structfield>longValuesOK</structfield> should be set true only when the
+ <structfield>attType</structfield> is of variable length and the operator
+ class is capable of segmenting long values by repeated suffixing
+ (see <xref linkend="spgist-limits"/>).
+ </para>
+
+ <para>
+ <structfield>leafType</structfield> should match the index storage type
+ defined by the operator class's <structfield>opckeytype</structfield>
+ catalog entry.
+ (Note that <structfield>opckeytype</structfield> can be zero,
+ implying the storage type is the same as the operator class's input
+ type, which is the most common situation.)
+ For reasons of backward compatibility, the <function>config</function>
+ method can set <structfield>leafType</structfield> to some other value,
+ and that value will be used; but this is deprecated since the index
+ contents are then incorrectly identified in the catalogs.
+ Also, it's permissible to
+ leave <structfield>leafType</structfield> uninitialized (zero);
+ that is interpreted as meaning the index storage type derived from
+ <structfield>opckeytype</structfield>.
+ </para>
+
+ <para>
+ When <structfield>attType</structfield>
+ and <structfield>leafType</structfield> are different, the optional
+ method <function>compress</function> must be provided.
+ Method <function>compress</function> is responsible
+ for transformation of datums to be indexed from <structfield>attType</structfield>
+ to <structfield>leafType</structfield>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>choose</function></term>
+ <listitem>
+ <para>
+ Chooses a method for inserting a new value into an inner tuple.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+<programlisting>
+CREATE FUNCTION my_choose(internal, internal) RETURNS void ...
+</programlisting>
+ The first argument is a pointer to a <structname>spgChooseIn</structname>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <structname>spgChooseOut</structname>
+ C struct, which the function must fill with result data.
+<programlisting>
+typedef struct spgChooseIn
+{
+ Datum datum; /* original datum to be indexed */
+ Datum leafDatum; /* current datum to be stored at leaf */
+ int level; /* current level (counting from zero) */
+
+ /* Data from current inner tuple */
+ bool allTheSame; /* tuple is marked all-the-same? */
+ bool hasPrefix; /* tuple has a prefix? */
+ Datum prefixDatum; /* if so, the prefix value */
+ int nNodes; /* number of nodes in the inner tuple */
+ Datum *nodeLabels; /* node label values (NULL if none) */
+} spgChooseIn;
+
+typedef enum spgChooseResultType
+{
+ spgMatchNode = 1, /* descend into existing node */
+ spgAddNode, /* add a node to the inner tuple */
+ spgSplitTuple /* split inner tuple (change its prefix) */
+} spgChooseResultType;
+
+typedef struct spgChooseOut
+{
+ spgChooseResultType resultType; /* action code, see above */
+ union
+ {
+ struct /* results for spgMatchNode */
+ {
+ int nodeN; /* descend to this node (index from 0) */
+ int levelAdd; /* increment level by this much */
+ Datum restDatum; /* new leaf datum */
+ } matchNode;
+ struct /* results for spgAddNode */
+ {
+ Datum nodeLabel; /* new node's label */
+ int nodeN; /* where to insert it (index from 0) */
+ } addNode;
+ struct /* results for spgSplitTuple */
+ {
+ /* Info to form new upper-level inner tuple with one child tuple */
+ bool prefixHasPrefix; /* tuple should have a prefix? */
+ Datum prefixPrefixDatum; /* if so, its value */
+ int prefixNNodes; /* number of nodes */
+ Datum *prefixNodeLabels; /* their labels (or NULL for
+ * no labels) */
+ int childNodeN; /* which node gets child tuple */
+
+ /* Info to form new lower-level inner tuple with all old nodes */
+ bool postfixHasPrefix; /* tuple should have a prefix? */
+ Datum postfixPrefixDatum; /* if so, its value */
+ } splitTuple;
+ } result;
+} spgChooseOut;
+</programlisting>
+
+ <structfield>datum</structfield> is the original datum of
+ <structname>spgConfigIn</structname>.<structfield>attType</structfield>
+ type that was to be inserted into the index.
+ <structfield>leafDatum</structfield> is a value of
+ <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
+ type, which is initially a result of method
+ <function>compress</function> applied to <structfield>datum</structfield>
+ when method <function>compress</function> is provided, or the same value as
+ <structfield>datum</structfield> otherwise.
+ <structfield>leafDatum</structfield> can change at lower levels of the tree
+ if the <function>choose</function> or <function>picksplit</function>
+ methods change it. When the insertion search reaches a leaf page,
+ the current value of <structfield>leafDatum</structfield> is what will be stored
+ in the newly created leaf tuple.
+ <structfield>level</structfield> is the current inner tuple's level, starting at
+ zero for the root level.
+ <structfield>allTheSame</structfield> is true if the current inner tuple is
+ marked as containing multiple equivalent nodes
+ (see <xref linkend="spgist-all-the-same"/>).
+ <structfield>hasPrefix</structfield> is true if the current inner tuple contains
+ a prefix; if so,
+ <structfield>prefixDatum</structfield> is its value.
+ <structfield>nNodes</structfield> is the number of child nodes contained in the
+ inner tuple, and
+ <structfield>nodeLabels</structfield> is an array of their label values, or
+ NULL if there are no labels.
+ </para>
+
+ <para>
+ The <function>choose</function> function can determine either that
+ the new value matches one of the existing child nodes, or that a new
+ child node must be added, or that the new value is inconsistent with
+ the tuple prefix and so the inner tuple must be split to create a
+ less restrictive prefix.
+ </para>
+
+ <para>
+ If the new value matches one of the existing child nodes,
+ set <structfield>resultType</structfield> to <literal>spgMatchNode</literal>.
+ Set <structfield>nodeN</structfield> to the index (from zero) of that node in
+ the node array.
+ Set <structfield>levelAdd</structfield> to the increment in
+ <structfield>level</structfield> caused by descending through that node,
+ or leave it as zero if the operator class does not use levels.
+ Set <structfield>restDatum</structfield> to equal <structfield>leafDatum</structfield>
+ if the operator class does not modify datums from one level to the
+ next, or otherwise set it to the modified value to be used as
+ <structfield>leafDatum</structfield> at the next level.
+ </para>
+
+ <para>
+ If a new child node must be added,
+ set <structfield>resultType</structfield> to <literal>spgAddNode</literal>.
+ Set <structfield>nodeLabel</structfield> to the label to be used for the new
+ node, and set <structfield>nodeN</structfield> to the index (from zero) at which
+ to insert the node in the node array.
+ After the node has been added, the <function>choose</function>
+ function will be called again with the modified inner tuple;
+ that call should result in an <literal>spgMatchNode</literal> result.
+ </para>
+
+ <para>
+ If the new value is inconsistent with the tuple prefix,
+ set <structfield>resultType</structfield> to <literal>spgSplitTuple</literal>.
+ This action moves all the existing nodes into a new lower-level
+ inner tuple, and replaces the existing inner tuple with a tuple
+ having a single downlink pointing to the new lower-level inner tuple.
+ Set <structfield>prefixHasPrefix</structfield> to indicate whether the new
+ upper tuple should have a prefix, and if so set
+ <structfield>prefixPrefixDatum</structfield> to the prefix value. This new
+ prefix value must be sufficiently less restrictive than the original
+ to accept the new value to be indexed.
+ Set <structfield>prefixNNodes</structfield> to the number of nodes needed in the
+ new tuple, and set <structfield>prefixNodeLabels</structfield> to a palloc'd array
+ holding their labels, or to NULL if node labels are not required.
+ Note that the total size of the new upper tuple must be no more
+ than the total size of the tuple it is replacing; this constrains
+ the lengths of the new prefix and new labels.
+ Set <structfield>childNodeN</structfield> to the index (from zero) of the node
+ that will downlink to the new lower-level inner tuple.
+ Set <structfield>postfixHasPrefix</structfield> to indicate whether the new
+ lower-level inner tuple should have a prefix, and if so set
+ <structfield>postfixPrefixDatum</structfield> to the prefix value. The
+ combination of these two prefixes and the downlink node's label
+ (if any) must have the same meaning as the original prefix, because
+ there is no opportunity to alter the node labels that are moved to
+ the new lower-level tuple, nor to change any child index entries.
+ After the node has been split, the <function>choose</function>
+ function will be called again with the replacement inner tuple.
+ That call may return an <literal>spgAddNode</literal> result, if no suitable
+ node was created by the <literal>spgSplitTuple</literal> action. Eventually
+ <function>choose</function> must return <literal>spgMatchNode</literal> to
+ allow the insertion to descend to the next level.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>picksplit</function></term>
+ <listitem>
+ <para>
+ Decides how to create a new inner tuple over a set of leaf tuples.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+<programlisting>
+CREATE FUNCTION my_picksplit(internal, internal) RETURNS void ...
+</programlisting>
+ The first argument is a pointer to a <structname>spgPickSplitIn</structname>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <structname>spgPickSplitOut</structname>
+ C struct, which the function must fill with result data.
+<programlisting>
+typedef struct spgPickSplitIn
+{
+ int nTuples; /* number of leaf tuples */
+ Datum *datums; /* their datums (array of length nTuples) */
+ int level; /* current level (counting from zero) */
+} spgPickSplitIn;
+
+typedef struct spgPickSplitOut
+{
+ bool hasPrefix; /* new inner tuple should have a prefix? */
+ Datum prefixDatum; /* if so, its value */
+
+ int nNodes; /* number of nodes for new inner tuple */
+ Datum *nodeLabels; /* their labels (or NULL for no labels) */
+
+ int *mapTuplesToNodes; /* node index for each leaf tuple */
+ Datum *leafTupleDatums; /* datum to store in each new leaf tuple */
+} spgPickSplitOut;
+</programlisting>
+
+ <structfield>nTuples</structfield> is the number of leaf tuples provided.
+ <structfield>datums</structfield> is an array of their datum values of
+ <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
+ type.
+ <structfield>level</structfield> is the current level that all the leaf tuples
+ share, which will become the level of the new inner tuple.
+ </para>
+
+ <para>
+ Set <structfield>hasPrefix</structfield> to indicate whether the new inner
+ tuple should have a prefix, and if so set
+ <structfield>prefixDatum</structfield> to the prefix value.
+ Set <structfield>nNodes</structfield> to indicate the number of nodes that
+ the new inner tuple will contain, and
+ set <structfield>nodeLabels</structfield> to an array of their label values,
+ or to NULL if node labels are not required.
+ Set <structfield>mapTuplesToNodes</structfield> to an array that gives the index
+ (from zero) of the node that each leaf tuple should be assigned to.
+ Set <structfield>leafTupleDatums</structfield> to an array of the values to
+ be stored in the new leaf tuples (these will be the same as the
+ input <structfield>datums</structfield> if the operator class does not modify
+ datums from one level to the next).
+ Note that the <function>picksplit</function> function is
+ responsible for palloc'ing the
+ <structfield>nodeLabels</structfield>, <structfield>mapTuplesToNodes</structfield> and
+ <structfield>leafTupleDatums</structfield> arrays.
+ </para>
+
+ <para>
+ If more than one leaf tuple is supplied, it is expected that the
+ <function>picksplit</function> function will classify them into more than
+ one node; otherwise it is not possible to split the leaf tuples
+ across multiple pages, which is the ultimate purpose of this
+ operation. Therefore, if the <function>picksplit</function> function
+ ends up placing all the leaf tuples in the same node, the core
+ SP-GiST code will override that decision and generate an inner
+ tuple in which the leaf tuples are assigned at random to several
+ identically-labeled nodes. Such a tuple is marked
+ <literal>allTheSame</literal> to signify that this has happened. The
+ <function>choose</function> and <function>inner_consistent</function> functions
+ must take suitable care with such inner tuples.
+ See <xref linkend="spgist-all-the-same"/> for more information.
+ </para>
+
+ <para>
+ <function>picksplit</function> can be applied to a single leaf tuple only
+ in the case that the <function>config</function> function set
+ <structfield>longValuesOK</structfield> to true and a larger-than-a-page input
+ value has been supplied. In this case the point of the operation is
+ to strip off a prefix and produce a new, shorter leaf datum value.
+ The call will be repeated until a leaf datum short enough to fit on
+ a page has been produced. See <xref linkend="spgist-limits"/> for
+ more information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>inner_consistent</function></term>
+ <listitem>
+ <para>
+ Returns set of nodes (branches) to follow during tree search.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+<programlisting>
+CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ...
+</programlisting>
+ The first argument is a pointer to a <structname>spgInnerConsistentIn</structname>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <structname>spgInnerConsistentOut</structname>
+ C struct, which the function must fill with result data.
+
+<programlisting>
+typedef struct spgInnerConsistentIn
+{
+ ScanKey scankeys; /* array of operators and comparison values */
+ ScanKey orderbys; /* array of ordering operators and comparison
+ * values */
+ int nkeys; /* length of scankeys array */
+ int norderbys; /* length of orderbys array */
+
+ Datum reconstructedValue; /* value reconstructed at parent */
+ void *traversalValue; /* opclass-specific traverse value */
+ MemoryContext traversalMemoryContext; /* put new traverse values here */
+ int level; /* current level (counting from zero) */
+ bool returnData; /* original data must be returned? */
+
+ /* Data from current inner tuple */
+ bool allTheSame; /* tuple is marked all-the-same? */
+ bool hasPrefix; /* tuple has a prefix? */
+ Datum prefixDatum; /* if so, the prefix value */
+ int nNodes; /* number of nodes in the inner tuple */
+ Datum *nodeLabels; /* node label values (NULL if none) */
+} spgInnerConsistentIn;
+
+typedef struct spgInnerConsistentOut
+{
+ int nNodes; /* number of child nodes to be visited */
+ int *nodeNumbers; /* their indexes in the node array */
+ int *levelAdds; /* increment level by this much for each */
+ Datum *reconstructedValues; /* associated reconstructed values */
+ void **traversalValues; /* opclass-specific traverse values */
+ double **distances; /* associated distances */
+} spgInnerConsistentOut;
+</programlisting>
+
+ The array <structfield>scankeys</structfield>, of length <structfield>nkeys</structfield>,
+ describes the index search condition(s). These conditions are
+ combined with AND &mdash; only index entries that satisfy all of
+ them are interesting. (Note that <structfield>nkeys</structfield> = 0 implies
+ that all index entries satisfy the query.) Usually the consistent
+ function only cares about the <structfield>sk_strategy</structfield> and
+ <structfield>sk_argument</structfield> fields of each array entry, which
+ respectively give the indexable operator and comparison value.
+ In particular it is not necessary to check <structfield>sk_flags</structfield> to
+ see if the comparison value is NULL, because the SP-GiST core code
+ will filter out such conditions.
+ The array <structfield>orderbys</structfield>, of length <structfield>norderbys</structfield>,
+ describes ordering operators (if any) in the same manner.
+ <structfield>reconstructedValue</structfield> is the value reconstructed for the
+ parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
+ <function>inner_consistent</function> function did not provide a value at the
+ parent level.
+ <structfield>traversalValue</structfield> is a pointer to any traverse data
+ passed down from the previous call of <function>inner_consistent</function>
+ on the parent index tuple, or NULL at the root level.
+ <structfield>traversalMemoryContext</structfield> is the memory context in which
+ to store output traverse values (see below).
+ <structfield>level</structfield> is the current inner tuple's level, starting at
+ zero for the root level.
+ <structfield>returnData</structfield> is <literal>true</literal> if reconstructed data is
+ required for this query; this will only be so if the
+ <function>config</function> function asserted <structfield>canReturnData</structfield>.
+ <structfield>allTheSame</structfield> is true if the current inner tuple is
+ marked <quote>all-the-same</quote>; in this case all the nodes have the
+ same label (if any) and so either all or none of them match the query
+ (see <xref linkend="spgist-all-the-same"/>).
+ <structfield>hasPrefix</structfield> is true if the current inner tuple contains
+ a prefix; if so,
+ <structfield>prefixDatum</structfield> is its value.
+ <structfield>nNodes</structfield> is the number of child nodes contained in the
+ inner tuple, and
+ <structfield>nodeLabels</structfield> is an array of their label values, or
+ NULL if the nodes do not have labels.
+ </para>
+
+ <para>
+ <structfield>nNodes</structfield> must be set to the number of child nodes that
+ need to be visited by the search, and
+ <structfield>nodeNumbers</structfield> must be set to an array of their indexes.
+ If the operator class keeps track of levels, set
+ <structfield>levelAdds</structfield> to an array of the level increments
+ required when descending to each node to be visited. (Often these
+ increments will be the same for all the nodes, but that's not
+ necessarily so, so an array is used.)
+ If value reconstruction is needed, set
+ <structfield>reconstructedValues</structfield> to an array of the values
+ reconstructed for each child node to be visited; otherwise, leave
+ <structfield>reconstructedValues</structfield> as NULL.
+ The reconstructed values are assumed to be of type
+ <structname>spgConfigOut</structname>.<structfield>leafType</structfield>.
+ (However, since the core system will do nothing with them except
+ possibly copy them, it is sufficient for them to have the
+ same <literal>typlen</literal> and <literal>typbyval</literal>
+ properties as <structfield>leafType</structfield>.)
+ If ordered search is performed, set <structfield>distances</structfield>
+ to an array of distance values according to <structfield>orderbys</structfield>
+ array (nodes with lowest distances will be processed first). Leave it
+ NULL otherwise.
+ If it is desired to pass down additional out-of-band information
+ (<quote>traverse values</quote>) to lower levels of the tree search,
+ set <structfield>traversalValues</structfield> to an array of the appropriate
+ traverse values, one for each child node to be visited; otherwise,
+ leave <structfield>traversalValues</structfield> as NULL.
+ Note that the <function>inner_consistent</function> function is
+ responsible for palloc'ing the
+ <structfield>nodeNumbers</structfield>, <structfield>levelAdds</structfield>,
+ <structfield>distances</structfield>,
+ <structfield>reconstructedValues</structfield>, and
+ <structfield>traversalValues</structfield> arrays in the current memory context.
+ However, any output traverse values pointed to by
+ the <structfield>traversalValues</structfield> array should be allocated
+ in <structfield>traversalMemoryContext</structfield>.
+ Each traverse value must be a single palloc'd chunk.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>leaf_consistent</function></term>
+ <listitem>
+ <para>
+ Returns true if a leaf tuple satisfies a query.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+<programlisting>
+CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ...
+</programlisting>
+ The first argument is a pointer to a <structname>spgLeafConsistentIn</structname>
+ C struct, containing input data for the function.
+ The second argument is a pointer to a <structname>spgLeafConsistentOut</structname>
+ C struct, which the function must fill with result data.
+<programlisting>
+typedef struct spgLeafConsistentIn
+{
+ ScanKey scankeys; /* array of operators and comparison values */
+ ScanKey orderbys; /* array of ordering operators and comparison
+ * values */
+ int nkeys; /* length of scankeys array */
+ int norderbys; /* length of orderbys array */
+
+ Datum reconstructedValue; /* value reconstructed at parent */
+ void *traversalValue; /* opclass-specific traverse value */
+ int level; /* current level (counting from zero) */
+ bool returnData; /* original data must be returned? */
+
+ Datum leafDatum; /* datum in leaf tuple */
+} spgLeafConsistentIn;
+
+typedef struct spgLeafConsistentOut
+{
+ Datum leafValue; /* reconstructed original data, if any */
+ bool recheck; /* set true if operator must be rechecked */
+ bool recheckDistances; /* set true if distances must be rechecked */
+ double *distances; /* associated distances */
+} spgLeafConsistentOut;
+</programlisting>
+
+ The array <structfield>scankeys</structfield>, of length <structfield>nkeys</structfield>,
+ describes the index search condition(s). These conditions are
+ combined with AND &mdash; only index entries that satisfy all of
+ them satisfy the query. (Note that <structfield>nkeys</structfield> = 0 implies
+ that all index entries satisfy the query.) Usually the consistent
+ function only cares about the <structfield>sk_strategy</structfield> and
+ <structfield>sk_argument</structfield> fields of each array entry, which
+ respectively give the indexable operator and comparison value.
+ In particular it is not necessary to check <structfield>sk_flags</structfield> to
+ see if the comparison value is NULL, because the SP-GiST core code
+ will filter out such conditions.
+ The array <structfield>orderbys</structfield>, of length <structfield>norderbys</structfield>,
+ describes the ordering operators in the same manner.
+ <structfield>reconstructedValue</structfield> is the value reconstructed for the
+ parent tuple; it is <literal>(Datum) 0</literal> at the root level or if the
+ <function>inner_consistent</function> function did not provide a value at the
+ parent level.
+ <structfield>traversalValue</structfield> is a pointer to any traverse data
+ passed down from the previous call of <function>inner_consistent</function>
+ on the parent index tuple, or NULL at the root level.
+ <structfield>level</structfield> is the current leaf tuple's level, starting at
+ zero for the root level.
+ <structfield>returnData</structfield> is <literal>true</literal> if reconstructed data is
+ required for this query; this will only be so if the
+ <function>config</function> function asserted <structfield>canReturnData</structfield>.
+ <structfield>leafDatum</structfield> is the key value of
+ <structname>spgConfigOut</structname>.<structfield>leafType</structfield>
+ stored in the current leaf tuple.
+ </para>
+
+ <para>
+ The function must return <literal>true</literal> if the leaf tuple matches the
+ query, or <literal>false</literal> if not. In the <literal>true</literal> case,
+ if <structfield>returnData</structfield> is <literal>true</literal> then
+ <structfield>leafValue</structfield> must be set to the value (of type
+ <structname>spgConfigIn</structname>.<structfield>attType</structfield>)
+ originally supplied to be indexed for this leaf tuple. Also,
+ <structfield>recheck</structfield> may be set to <literal>true</literal> if the match
+ is uncertain and so the operator(s) must be re-applied to the actual
+ heap tuple to verify the match.
+ If ordered search is performed, set <structfield>distances</structfield>
+ to an array of distance values according to <structfield>orderbys</structfield>
+ array. Leave it NULL otherwise. If at least one of returned distances
+ is not exact, set <structfield>recheckDistances</structfield> to true.
+ In this case, the executor will calculate the exact distances after
+ fetching the tuple from the heap, and will reorder the tuples if needed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The optional user-defined methods are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><function>Datum compress(Datum in)</function></term>
+ <listitem>
+ <para>
+ Converts a data item into a format suitable for physical storage in
+ a leaf tuple of the index. It accepts a value of type
+ <structname>spgConfigIn</structname>.<structfield>attType</structfield>
+ and returns a value of type
+ <structname>spgConfigOut</structname>.<structfield>leafType</structfield>.
+ The output value must not contain an out-of-line TOAST pointer.
+ </para>
+
+ <para>
+ Note: the <function>compress</function> method is only applied to
+ values to be stored. The consistent methods receive query
+ <structfield>scankeys</structfield> unchanged, without transformation
+ using <function>compress</function>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><function>options</function></term>
+ <listitem>
+ <para>
+ Defines a set of user-visible parameters that control operator class
+ behavior.
+ </para>
+
+ <para>
+ The <acronym>SQL</acronym> declaration of the function must look like this:
+
+<programlisting>
+CREATE OR REPLACE FUNCTION my_options(internal)
+RETURNS void
+AS 'MODULE_PATHNAME'
+LANGUAGE C STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ The function is passed a pointer to a <structname>local_relopts</structname>
+ struct, which needs to be filled with a set of operator class
+ specific options. The options can be accessed from other support
+ functions using the <literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
+ <literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
+ </para>
+
+ <para>
+ Since the representation of the key in <acronym>SP-GiST</acronym> is
+ flexible, it may depend on user-specified parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ All the SP-GiST support methods are normally called in a short-lived
+ memory context; that is, <varname>CurrentMemoryContext</varname> will be reset
+ after processing of each tuple. It is therefore not very important to
+ worry about pfree'ing everything you palloc. (The <function>config</function>
+ method is an exception: it should try to avoid leaking memory. But
+ usually the <function>config</function> method need do nothing but assign
+ constants into the passed parameter struct.)
+ </para>
+
+ <para>
+ If the indexed column is of a collatable data type, the index collation
+ will be passed to all the support methods, using the standard
+ <function>PG_GET_COLLATION()</function> mechanism.
+ </para>
+
+</sect1>
+
+<sect1 id="spgist-implementation">
+ <title>Implementation</title>
+
+ <para>
+ This section covers implementation details and other tricks that are
+ useful for implementers of <acronym>SP-GiST</acronym> operator classes to
+ know.
+ </para>
+
+ <sect2 id="spgist-limits">
+ <title>SP-GiST Limits</title>
+
+ <para>
+ Individual leaf tuples and inner tuples must fit on a single index page
+ (8kB by default). Therefore, when indexing values of variable-length
+ data types, long values can only be supported by methods such as radix
+ trees, in which each level of the tree includes a prefix that is short
+ enough to fit on a page, and the final leaf level includes a suffix also
+ short enough to fit on a page. The operator class should set
+ <structfield>longValuesOK</structfield> to true only if it is prepared to arrange for
+ this to happen. Otherwise, the <acronym>SP-GiST</acronym> core will
+ reject any request to index a value that is too large to fit
+ on an index page.
+ </para>
+
+ <para>
+ Likewise, it is the operator class's responsibility that inner tuples
+ do not grow too large to fit on an index page; this limits the number
+ of child nodes that can be used in one inner tuple, as well as the
+ maximum size of a prefix value.
+ </para>
+
+ <para>
+ Another limitation is that when an inner tuple's node points to a set
+ of leaf tuples, those tuples must all be in the same index page.
+ (This is a design decision to reduce seeking and save space in the
+ links that chain such tuples together.) If the set of leaf tuples
+ grows too large for a page, a split is performed and an intermediate
+ inner tuple is inserted. For this to fix the problem, the new inner
+ tuple <emphasis>must</emphasis> divide the set of leaf values into more than one
+ node group. If the operator class's <function>picksplit</function> function
+ fails to do that, the <acronym>SP-GiST</acronym> core resorts to
+ extraordinary measures described in <xref linkend="spgist-all-the-same"/>.
+ </para>
+
+ <para>
+ When <structfield>longValuesOK</structfield> is true, it is expected
+ that successive levels of the <acronym>SP-GiST</acronym> tree will
+ absorb more and more information into the prefixes and node labels of
+ the inner tuples, making the required leaf datum smaller and smaller,
+ so that eventually it will fit on a page.
+ To prevent bugs in operator classes from causing infinite insertion
+ loops, the <acronym>SP-GiST</acronym> core will raise an error if the
+ leaf datum does not become any smaller within ten cycles
+ of <function>choose</function> method calls.
+ </para>
+ </sect2>
+
+ <sect2 id="spgist-null-labels">
+ <title>SP-GiST Without Node Labels</title>
+
+ <para>
+ Some tree algorithms use a fixed set of nodes for each inner tuple;
+ for example, in a quad-tree there are always exactly four nodes
+ corresponding to the four quadrants around the inner tuple's centroid
+ point. In such a case the code typically works with the nodes by
+ number, and there is no need for explicit node labels. To suppress
+ node labels (and thereby save some space), the <function>picksplit</function>
+ function can return NULL for the <structfield>nodeLabels</structfield> array,
+ and likewise the <function>choose</function> function can return NULL for
+ the <structfield>prefixNodeLabels</structfield> array during
+ a <literal>spgSplitTuple</literal> action.
+ This will in turn result in <structfield>nodeLabels</structfield> being NULL during
+ subsequent calls to <function>choose</function> and <function>inner_consistent</function>.
+ In principle, node labels could be used for some inner tuples and omitted
+ for others in the same index.
+ </para>
+
+ <para>
+ When working with an inner tuple having unlabeled nodes, it is an error
+ for <function>choose</function> to return <literal>spgAddNode</literal>, since the set
+ of nodes is supposed to be fixed in such cases.
+ </para>
+ </sect2>
+
+ <sect2 id="spgist-all-the-same">
+ <title><quote>All-the-Same</quote> Inner Tuples</title>
+
+ <para>
+ The <acronym>SP-GiST</acronym> core can override the results of the
+ operator class's <function>picksplit</function> function when
+ <function>picksplit</function> fails to divide the supplied leaf values into
+ at least two node categories. When this happens, the new inner tuple
+ is created with multiple nodes that each have the same label (if any)
+ that <function>picksplit</function> gave to the one node it did use, and the
+ leaf values are divided at random among these equivalent nodes.
+ The <literal>allTheSame</literal> flag is set on the inner tuple to warn the
+ <function>choose</function> and <function>inner_consistent</function> functions that the
+ tuple does not have the node set that they might otherwise expect.
+ </para>
+
+ <para>
+ When dealing with an <literal>allTheSame</literal> tuple, a <function>choose</function>
+ result of <literal>spgMatchNode</literal> is interpreted to mean that the new
+ value can be assigned to any of the equivalent nodes; the core code will
+ ignore the supplied <structfield>nodeN</structfield> value and descend into one
+ of the nodes at random (so as to keep the tree balanced). It is an
+ error for <function>choose</function> to return <literal>spgAddNode</literal>, since
+ that would make the nodes not all equivalent; the
+ <literal>spgSplitTuple</literal> action must be used if the value to be inserted
+ doesn't match the existing nodes.
+ </para>
+
+ <para>
+ When dealing with an <literal>allTheSame</literal> tuple, the
+ <function>inner_consistent</function> function should return either all or none
+ of the nodes as targets for continuing the index search, since they are
+ all equivalent. This may or may not require any special-case code,
+ depending on how much the <function>inner_consistent</function> function normally
+ assumes about the meaning of the nodes.
+ </para>
+ </sect2>
+
+</sect1>
+
+<sect1 id="spgist-examples">
+ <title>Examples</title>
+
+ <para>
+ The <productname>PostgreSQL</productname> source distribution includes
+ several examples of index operator classes for <acronym>SP-GiST</acronym>,
+ as described in <xref linkend="spgist-builtin-opclasses-table"/>. Look
+ into <filename>src/backend/access/spgist/</filename>
+ and <filename>src/backend/utils/adt/</filename> to see the code.
+ </para>
+
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml
new file mode 100644
index 0000000..16c3ab7
--- /dev/null
+++ b/doc/src/sgml/spi.sgml
@@ -0,0 +1,5400 @@
+<!-- doc/src/sgml/spi.sgml -->
+
+<chapter id="spi">
+ <title>Server Programming Interface</title>
+
+ <indexterm zone="spi">
+ <primary>SPI</primary>
+ </indexterm>
+
+ <para>
+ The <firstterm>Server Programming Interface</firstterm>
+ (<acronym>SPI</acronym>) gives writers of user-defined
+ <acronym>C</acronym> functions the ability to run
+ <acronym>SQL</acronym> commands inside their functions or procedures.
+ <acronym>SPI</acronym> is a set of
+ interface functions to simplify access to the parser, planner,
+ and executor. <acronym>SPI</acronym> also does some
+ memory management.
+ </para>
+
+ <note>
+ <para>
+ The available procedural languages provide various means to
+ execute SQL commands from functions. Most of these facilities are
+ based on SPI, so this documentation might be of use for users
+ of those languages as well.
+ </para>
+ </note>
+
+ <para>
+ Note that if a command invoked via SPI fails, then control will not be
+ returned to your C function. Rather, the
+ transaction or subtransaction in which your C function executes will be
+ rolled back. (This might seem surprising given that the SPI functions mostly
+ have documented error-return conventions. Those conventions only apply
+ for errors detected within the SPI functions themselves, however.)
+ It is possible to recover control after an error by establishing your own
+ subtransaction surrounding SPI calls that might fail.
+ </para>
+
+ <para>
+ <acronym>SPI</acronym> functions return a nonnegative result on
+ success (either via a returned integer value or in the global
+ variable <varname>SPI_result</varname>, as described below). On
+ error, a negative result or <symbol>NULL</symbol> will be returned.
+ </para>
+
+ <para>
+ Source code files that use SPI must include the header file
+ <filename>executor/spi.h</filename>.
+ </para>
+
+
+<sect1 id="spi-interface">
+ <title>Interface Functions</title>
+
+ <refentry id="spi-spi-connect">
+ <indexterm><primary>SPI_connect</primary></indexterm>
+ <indexterm><primary>SPI_connect_ext</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_connect</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_connect</refname>
+ <refname>SPI_connect_ext</refname>
+ <refpurpose>connect a C function to the SPI manager</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_connect(void)
+</synopsis>
+
+ <synopsis>
+int SPI_connect_ext(int <parameter>options</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_connect</function> opens a connection from a
+ C function invocation to the SPI manager. You must call this
+ function if you want to execute commands through SPI. Some utility
+ SPI functions can be called from unconnected C functions.
+ </para>
+
+ <para>
+ <function>SPI_connect_ext</function> does the same but has an argument that
+ allows passing option flags. Currently, the following option values are
+ available:
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OPT_NONATOMIC</symbol></term>
+ <listitem>
+ <para>
+ Sets the SPI connection to be <firstterm>nonatomic</firstterm>, which
+ means that transaction control calls (<function>SPI_commit</function>,
+ <function>SPI_rollback</function>) are allowed. Otherwise,
+ calling those functions will result in an immediate error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <literal>SPI_connect()</literal> is equivalent to
+ <literal>SPI_connect_ext(0)</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_CONNECT</symbol></term>
+ <listitem>
+ <para>
+ on success
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_CONNECT</symbol></term>
+ <listitem>
+ <para>
+ on error
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-finish">
+ <indexterm><primary>SPI_finish</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_finish</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_finish</refname>
+ <refpurpose>disconnect a C function from the SPI manager</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_finish(void)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_finish</function> closes an existing connection to
+ the SPI manager. You must call this function after completing the
+ SPI operations needed during your C function's current invocation.
+ You do not need to worry about making this happen, however, if you
+ abort the transaction via <literal>elog(ERROR)</literal>. In that
+ case SPI will clean itself up automatically.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_FINISH</symbol></term>
+ <listitem>
+ <para>
+ if properly disconnected
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected C function
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execute">
+ <indexterm><primary>SPI_execute</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execute</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execute</refname>
+ <refpurpose>execute a command</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execute(const char * <parameter>command</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execute</function> executes the specified SQL command
+ for <parameter>count</parameter> rows. If <parameter>read_only</parameter>
+ is <literal>true</literal>, the command must be read-only, and execution overhead
+ is somewhat reduced.
+ </para>
+
+ <para>
+ This function can only be called from a connected C function.
+ </para>
+
+ <para>
+ If <parameter>count</parameter> is zero then the command is executed
+ for all rows that it applies to. If <parameter>count</parameter>
+ is greater than zero, then no more than <parameter>count</parameter> rows
+ will be retrieved; execution stops when the count is reached, much like
+ adding a <literal>LIMIT</literal> clause to the query. For example,
+<programlisting>
+SPI_execute("SELECT * FROM foo", true, 5);
+</programlisting>
+ will retrieve at most 5 rows from the table. Note that such a limit
+ is only effective when the command actually returns rows. For example,
+<programlisting>
+SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
+</programlisting>
+ inserts all rows from <structname>bar</structname>, ignoring the
+ <parameter>count</parameter> parameter. However, with
+<programlisting>
+SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);
+</programlisting>
+ at most 5 rows would be inserted, since execution would stop after the
+ fifth <literal>RETURNING</literal> result row is retrieved.
+ </para>
+
+ <para>
+ You can pass multiple commands in one string;
+ <function>SPI_execute</function> returns the
+ result for the command executed last. The <parameter>count</parameter>
+ limit applies to each command separately (even though only the last
+ result will actually be returned). The limit is not applied to any
+ hidden commands generated by rules.
+ </para>
+
+ <para>
+ When <parameter>read_only</parameter> is <literal>false</literal>,
+ <function>SPI_execute</function> increments the command
+ counter and computes a new <firstterm>snapshot</firstterm> before executing each
+ command in the string. The snapshot does not actually change if the
+ current transaction isolation level is <literal>SERIALIZABLE</literal> or <literal>REPEATABLE READ</literal>, but in
+ <literal>READ COMMITTED</literal> mode the snapshot update allows each command to
+ see the results of newly committed transactions from other sessions.
+ This is essential for consistent behavior when the commands are modifying
+ the database.
+ </para>
+
+ <para>
+ When <parameter>read_only</parameter> is <literal>true</literal>,
+ <function>SPI_execute</function> does not update either the snapshot
+ or the command counter, and it allows only plain <command>SELECT</command>
+ commands to appear in the command string. The commands are executed
+ using the snapshot previously established for the surrounding query.
+ This execution mode is somewhat faster than the read/write mode due
+ to eliminating per-command overhead. It also allows genuinely
+ <firstterm>stable</firstterm> functions to be built: since successive executions
+ will all use the same snapshot, there will be no change in the results.
+ </para>
+
+ <para>
+ It is generally unwise to mix read-only and read-write commands within
+ a single function using SPI; that could result in very confusing behavior,
+ since the read-only queries would not see the results of any database
+ updates done by the read-write queries.
+ </para>
+
+ <para>
+ The actual number of rows for which the (last) command was executed
+ is returned in the global variable <varname>SPI_processed</varname>.
+ If the return value of the function is <symbol>SPI_OK_SELECT</symbol>,
+ <symbol>SPI_OK_INSERT_RETURNING</symbol>,
+ <symbol>SPI_OK_DELETE_RETURNING</symbol>, or
+ <symbol>SPI_OK_UPDATE_RETURNING</symbol>,
+ then you can use the
+ global pointer <literal>SPITupleTable *SPI_tuptable</literal> to
+ access the result rows. Some utility commands (such as
+ <command>EXPLAIN</command>) also return row sets, and <literal>SPI_tuptable</literal>
+ will contain the result in these cases too. Some utility commands
+ (<command>COPY</command>, <command>CREATE TABLE AS</command>) don't return a row set, so
+ <literal>SPI_tuptable</literal> is NULL, but they still return the number of
+ rows processed in <varname>SPI_processed</varname>.
+ </para>
+
+ <para>
+ The structure <structname>SPITupleTable</structname> is defined
+ thus:
+<programlisting>
+typedef struct SPITupleTable
+{
+ /* Public members */
+ TupleDesc tupdesc; /* tuple descriptor */
+ HeapTuple *vals; /* array of tuples */
+ uint64 numvals; /* number of valid tuples */
+
+ /* Private members, not intended for external callers */
+ uint64 alloced; /* allocated length of vals array */
+ MemoryContext tuptabcxt; /* memory context of result table */
+ slist_node next; /* link for internal bookkeeping */
+ SubTransactionId subid; /* subxact in which tuptable was created */
+} SPITupleTable;
+</programlisting>
+ The fields <structfield>tupdesc</structfield>,
+ <structfield>vals</structfield>, and
+ <structfield>numvals</structfield>
+ can be used by SPI callers; the remaining fields are internal.
+ <structfield>vals</structfield> is an array of pointers to rows.
+ The number of rows is given by <structfield>numvals</structfield>
+ (for somewhat historical reasons, this count is also returned
+ in <varname>SPI_processed</varname>).
+ <structfield>tupdesc</structfield> is a row descriptor which you can pass to
+ SPI functions dealing with rows.
+ </para>
+
+ <para>
+ <function>SPI_finish</function> frees all
+ <structname>SPITupleTable</structname>s allocated during the current
+ C function. You can free a particular result table earlier, if you
+ are done with it, by calling <function>SPI_freetuptable</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ string containing command to execute
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If the execution of the command was successful then one of the
+ following (nonnegative) values will be returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_SELECT</symbol></term>
+ <listitem>
+ <para>
+ if a <command>SELECT</command> (but not <command>SELECT
+ INTO</command>) was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_SELINTO</symbol></term>
+ <listitem>
+ <para>
+ if a <command>SELECT INTO</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_INSERT</symbol></term>
+ <listitem>
+ <para>
+ if an <command>INSERT</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_DELETE</symbol></term>
+ <listitem>
+ <para>
+ if a <command>DELETE</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_UPDATE</symbol></term>
+ <listitem>
+ <para>
+ if an <command>UPDATE</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_MERGE</symbol></term>
+ <listitem>
+ <para>
+ if a <command>MERGE</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_INSERT_RETURNING</symbol></term>
+ <listitem>
+ <para>
+ if an <command>INSERT RETURNING</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_DELETE_RETURNING</symbol></term>
+ <listitem>
+ <para>
+ if a <command>DELETE RETURNING</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_UPDATE_RETURNING</symbol></term>
+ <listitem>
+ <para>
+ if an <command>UPDATE RETURNING</command> was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_UTILITY</symbol></term>
+ <listitem>
+ <para>
+ if a utility command (e.g., <command>CREATE TABLE</command>)
+ was executed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_OK_REWRITTEN</symbol></term>
+ <listitem>
+ <para>
+ if the command was rewritten into another kind of command (e.g.,
+ <command>UPDATE</command> became an <command>INSERT</command>) by a <link linkend="rules">rule</link>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ On error, one of the following negative values is returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>command</parameter> is <symbol>NULL</symbol> or
+ <parameter>count</parameter> is less than 0
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_COPY</symbol></term>
+ <listitem>
+ <para>
+ if <command>COPY TO stdout</command> or <command>COPY FROM stdin</command>
+ was attempted
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_TRANSACTION</symbol></term>
+ <listitem>
+ <para>
+ if a transaction manipulation command was attempted
+ (<command>BEGIN</command>,
+ <command>COMMIT</command>,
+ <command>ROLLBACK</command>,
+ <command>SAVEPOINT</command>,
+ <command>PREPARE TRANSACTION</command>,
+ <command>COMMIT PREPARED</command>,
+ <command>ROLLBACK PREPARED</command>,
+ or any variant thereof)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_OPUNKNOWN</symbol></term>
+ <listitem>
+ <para>
+ if the command type is unknown (shouldn't happen)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected C function
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ All SPI query-execution functions set both
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> (just the pointer, not the contents
+ of the structure). Save these two global variables into local
+ C function variables if you need to access the result table of
+ <function>SPI_execute</function> or another query-execution function
+ across later calls.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-exec">
+ <indexterm><primary>SPI_exec</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_exec</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_exec</refname>
+ <refpurpose>execute a read/write command</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_exec</function> is the same as
+ <function>SPI_execute</function>, with the latter's
+ <parameter>read_only</parameter> parameter always taken as
+ <literal>false</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ string containing command to execute
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ See <function>SPI_execute</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execute-extended">
+ <indexterm><primary>SPI_execute_extended</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execute_extended</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execute_extended</refname>
+ <refpurpose>execute a command with out-of-line parameters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execute_extended(const char *<parameter>command</parameter>,
+ const SPIExecuteOptions * <parameter>options</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execute_extended</function> executes a command that might
+ include references to externally supplied parameters. The command text
+ refers to a parameter as <literal>$<replaceable>n</replaceable></literal>,
+ and the <parameter>options-&gt;params</parameter> object (if supplied)
+ provides values and type information for each such symbol.
+ Various execution options can be specified
+ in the <parameter>options</parameter> struct, too.
+ </para>
+
+ <para>
+ The <parameter>options-&gt;params</parameter> object should normally
+ mark each parameter with the <literal>PARAM_FLAG_CONST</literal> flag,
+ since a one-shot plan is always used for the query.
+ </para>
+
+ <para>
+ If <parameter>options-&gt;dest</parameter> is not NULL, then result
+ tuples are passed to that object as they are generated by the executor,
+ instead of being accumulated in <varname>SPI_tuptable</varname>. Using
+ a caller-supplied <literal>DestReceiver</literal> object is particularly
+ helpful for queries that might generate many tuples, since the data can
+ be processed on-the-fly instead of being accumulated in memory.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const SPIExecuteOptions * <parameter>options</parameter></literal></term>
+ <listitem>
+ <para>
+ struct containing optional arguments
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Callers should always zero out the entire <parameter>options</parameter>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <parameter>options</parameter> fields are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
+ <listitem>
+ <para>
+ data structure containing query parameter types and values; NULL if none
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>allow_nonatomic</parameter></literal></term>
+ <listitem>
+ <para>
+ <literal>true</literal> allows non-atomic execution of CALL and DO
+ statements
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>must_return_tuples</parameter></literal></term>
+ <listitem>
+ <para>
+ if <literal>true</literal>, raise error if the query is not of a kind
+ that returns tuples (this does not forbid the case where it happens to
+ return zero tuples)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>uint64 <parameter>tcount</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DestReceiver * <parameter>dest</parameter></literal></term>
+ <listitem>
+ <para>
+ <literal>DestReceiver</literal> object that will receive any tuples
+ emitted by the query; if NULL, result tuples are accumulated into
+ a <varname>SPI_tuptable</varname> structure, as
+ in <function>SPI_execute</function>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ResourceOwner <parameter>owner</parameter></literal></term>
+ <listitem>
+ <para>
+ This field is present for consistency
+ with <function>SPI_execute_plan_extended</function>, but it is
+ ignored, since the plan used
+ by <function>SPI_execute_extended</function> is never saved.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The return value is the same as for <function>SPI_execute</function>.
+ </para>
+
+ <para>
+ When <parameter>options-&gt;dest</parameter> is NULL,
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute</function>.
+ When <parameter>options-&gt;dest</parameter> is not NULL,
+ <varname>SPI_processed</varname> is set to zero and
+ <varname>SPI_tuptable</varname> is set to NULL. If a tuple count
+ is required, the caller's <literal>DestReceiver</literal> object must
+ calculate it.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execute-with-args">
+ <indexterm><primary>SPI_execute_with_args</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execute_with_args</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execute_with_args</refname>
+ <refpurpose>execute a command with out-of-line parameters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execute_with_args(const char *<parameter>command</parameter>,
+ int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>,
+ Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>,
+ bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execute_with_args</function> executes a command that might
+ include references to externally supplied parameters. The command text
+ refers to a parameter as <literal>$<replaceable>n</replaceable></literal>, and
+ the call specifies data types and values for each such symbol.
+ <parameter>read_only</parameter> and <parameter>count</parameter> have
+ the same interpretation as in <function>SPI_execute</function>.
+ </para>
+
+ <para>
+ The main advantage of this routine compared to
+ <function>SPI_execute</function> is that data values can be inserted
+ into the command without tedious quoting/escaping, and thus with much
+ less risk of SQL-injection attacks.
+ </para>
+
+ <para>
+ Similar results can be achieved with <function>SPI_prepare</function> followed by
+ <function>SPI_execute_plan</function>; however, when using this function
+ the query plan is always customized to the specific parameter values
+ provided.
+ For one-time query execution, this function should be preferred.
+ If the same command is to be executed with many different parameters,
+ either method might be faster, depending on the cost of re-planning
+ versus the benefit of custom plans.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>nargs</parameter></literal></term>
+ <listitem>
+ <para>
+ number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>nargs</parameter>, containing the
+ <acronym>OID</acronym>s of the data types of the parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>nargs</parameter>, containing the actual
+ parameter values
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>nargs</parameter>, describing which
+ parameters are null
+ </para>
+
+ <para>
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
+ <function>SPI_execute_with_args</function> assumes that no parameters
+ are null. Otherwise, each entry of the <parameter>nulls</parameter>
+ array should be <literal>'&nbsp;'</literal> if the corresponding parameter
+ value is non-null, or <literal>'n'</literal> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <parameter>values</parameter> entry doesn't matter.) Note
+ that <parameter>nulls</parameter> is not a text string, just an array:
+ it does not need a <literal>'\0'</literal> terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The return value is the same as for <function>SPI_execute</function>.
+ </para>
+
+ <para>
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute</function> if successful.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-prepare">
+ <indexterm><primary>SPI_prepare</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_prepare</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_prepare</refname>
+ <refpurpose>prepare a statement, without executing it yet</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>, Oid * <parameter>argtypes</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_prepare</function> creates and returns a prepared
+ statement for the specified command, but doesn't execute the command.
+ The prepared statement can later be executed repeatedly using
+ <function>SPI_execute_plan</function>.
+ </para>
+
+ <para>
+ When the same or a similar command is to be executed repeatedly, it
+ is generally advantageous to perform parse analysis only once, and
+ might furthermore be advantageous to re-use an execution plan for the
+ command.
+ <function>SPI_prepare</function> converts a command string into a
+ prepared statement that encapsulates the results of parse analysis.
+ The prepared statement also provides a place for caching an execution plan
+ if it is found that generating a custom plan for each execution is not
+ helpful.
+ </para>
+
+ <para>
+ A prepared command can be generalized by writing parameters
+ (<literal>$1</literal>, <literal>$2</literal>, etc.) in place of what would be
+ constants in a normal command. The actual values of the parameters
+ are then specified when <function>SPI_execute_plan</function> is called.
+ This allows the prepared command to be used over a wider range of
+ situations than would be possible without parameters.
+ </para>
+
+ <para>
+ The statement returned by <function>SPI_prepare</function> can be used
+ only in the current invocation of the C function, since
+ <function>SPI_finish</function> frees memory allocated for such a
+ statement. But the statement can be saved for longer using the functions
+ <function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>nargs</parameter></literal></term>
+ <listitem>
+ <para>
+ number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
+ <listitem>
+ <para>
+ pointer to an array containing the <acronym>OID</acronym>s of
+ the data types of the parameters
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <function>SPI_prepare</function> returns a non-null pointer to an
+ <type>SPIPlan</type>, which is an opaque struct representing a prepared
+ statement. On error, <symbol>NULL</symbol> will be returned,
+ and <varname>SPI_result</varname> will be set to one of the same
+ error codes used by <function>SPI_execute</function>, except that
+ it is set to <symbol>SPI_ERROR_ARGUMENT</symbol> if
+ <parameter>command</parameter> is <symbol>NULL</symbol>, or if
+ <parameter>nargs</parameter> is less than 0, or if <parameter>nargs</parameter> is
+ greater than 0 and <parameter>argtypes</parameter> is <symbol>NULL</symbol>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ If no parameters are defined, a generic plan will be created at the
+ first use of <function>SPI_execute_plan</function>, and used for all
+ subsequent executions as well. If there are parameters, the first few uses
+ of <function>SPI_execute_plan</function> will generate custom plans
+ that are specific to the supplied parameter values. After enough uses
+ of the same prepared statement, <function>SPI_execute_plan</function> will
+ build a generic plan, and if that is not too much more expensive than the
+ custom plans, it will start using the generic plan instead of re-planning
+ each time. If this default behavior is unsuitable, you can alter it by
+ passing the <literal>CURSOR_OPT_GENERIC_PLAN</literal> or
+ <literal>CURSOR_OPT_CUSTOM_PLAN</literal> flag to
+ <function>SPI_prepare_cursor</function>, to force use of generic or custom
+ plans respectively.
+ </para>
+
+ <para>
+ Although the main point of a prepared statement is to avoid repeated parse
+ analysis and planning of the statement, <productname>PostgreSQL</productname> will
+ force re-analysis and re-planning of the statement before using it
+ whenever database objects used in the statement have undergone
+ definitional (DDL) changes since the previous use of the prepared
+ statement. Also, if the value of <xref linkend="guc-search-path"/> changes
+ from one use to the next, the statement will be re-parsed using the new
+ <varname>search_path</varname>. (This latter behavior is new as of
+ <productname>PostgreSQL</productname> 9.3.) See <xref
+ linkend="sql-prepare"/> for more information about the behavior of prepared
+ statements.
+ </para>
+
+ <para>
+ This function should only be called from a connected C function.
+ </para>
+
+ <para>
+ <type>SPIPlanPtr</type> is declared as a pointer to an opaque struct type in
+ <filename>spi.h</filename>. It is unwise to try to access its contents
+ directly, as that makes your code much more likely to break in
+ future revisions of <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ The name <type>SPIPlanPtr</type> is somewhat historical, since the data
+ structure no longer necessarily contains an execution plan.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-prepare-cursor">
+ <indexterm><primary>SPI_prepare_cursor</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_prepare_cursor</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_prepare_cursor</refname>
+ <refpurpose>prepare a statement, without executing it yet</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>,
+ Oid * <parameter>argtypes</parameter>, int <parameter>cursorOptions</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_prepare_cursor</function> is identical to
+ <function>SPI_prepare</function>, except that it also allows specification
+ of the planner's <quote>cursor options</quote> parameter. This is a bit mask
+ having the values shown in <filename>nodes/parsenodes.h</filename>
+ for the <structfield>options</structfield> field of <structname>DeclareCursorStmt</structname>.
+ <function>SPI_prepare</function> always takes the cursor options as zero.
+ </para>
+
+ <para>
+ This function is now deprecated in favor
+ of <function>SPI_prepare_extended</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>nargs</parameter></literal></term>
+ <listitem>
+ <para>
+ number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
+ <listitem>
+ <para>
+ pointer to an array containing the <acronym>OID</acronym>s of
+ the data types of the parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>cursorOptions</parameter></literal></term>
+ <listitem>
+ <para>
+ integer bit mask of cursor options; zero produces default behavior
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <function>SPI_prepare_cursor</function> has the same return conventions as
+ <function>SPI_prepare</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Useful bits to set in <parameter>cursorOptions</parameter> include
+ <symbol>CURSOR_OPT_SCROLL</symbol>,
+ <symbol>CURSOR_OPT_NO_SCROLL</symbol>,
+ <symbol>CURSOR_OPT_FAST_PLAN</symbol>,
+ <symbol>CURSOR_OPT_GENERIC_PLAN</symbol>, and
+ <symbol>CURSOR_OPT_CUSTOM_PLAN</symbol>. Note in particular that
+ <symbol>CURSOR_OPT_HOLD</symbol> is ignored.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-prepare-extended">
+ <indexterm><primary>SPI_prepare_extended</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_prepare_extended</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_prepare_extended</refname>
+ <refpurpose>prepare a statement, without executing it yet</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SPIPlanPtr SPI_prepare_extended(const char * <parameter>command</parameter>,
+ const SPIPrepareOptions * <parameter>options</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_prepare_extended</function> creates and returns a prepared
+ statement for the specified command, but doesn't execute the command.
+ This function is equivalent to <function>SPI_prepare</function>,
+ with the addition that the caller can specify options to control
+ the parsing of external parameter references, as well as other facets
+ of query parsing and planning.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const SPIPrepareOptions * <parameter>options</parameter></literal></term>
+ <listitem>
+ <para>
+ struct containing optional arguments
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Callers should always zero out the entire <parameter>options</parameter>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <parameter>options</parameter> fields are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ParserSetupHook <parameter>parserSetup</parameter></literal></term>
+ <listitem>
+ <para>
+ Parser hook setup function
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>void * <parameter>parserSetupArg</parameter></literal></term>
+ <listitem>
+ <para>
+ pass-through argument for <parameter>parserSetup</parameter>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>RawParseMode <parameter>parseMode</parameter></literal></term>
+ <listitem>
+ <para>
+ mode for raw parsing; <literal>RAW_PARSE_DEFAULT</literal> (zero)
+ produces default behavior
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>cursorOptions</parameter></literal></term>
+ <listitem>
+ <para>
+ integer bit mask of cursor options; zero produces default behavior
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <function>SPI_prepare_extended</function> has the same return conventions as
+ <function>SPI_prepare</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-prepare-params">
+ <indexterm><primary>SPI_prepare_params</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_prepare_params</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_prepare_params</refname>
+ <refpurpose>prepare a statement, without executing it yet</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SPIPlanPtr SPI_prepare_params(const char * <parameter>command</parameter>,
+ ParserSetupHook <parameter>parserSetup</parameter>,
+ void * <parameter>parserSetupArg</parameter>,
+ int <parameter>cursorOptions</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_prepare_params</function> creates and returns a prepared
+ statement for the specified command, but doesn't execute the command.
+ This function is equivalent to <function>SPI_prepare_cursor</function>,
+ with the addition that the caller can specify parser hook functions
+ to control the parsing of external parameter references.
+ </para>
+
+ <para>
+ This function is now deprecated in favor
+ of <function>SPI_prepare_extended</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ParserSetupHook <parameter>parserSetup</parameter></literal></term>
+ <listitem>
+ <para>
+ Parser hook setup function
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>void * <parameter>parserSetupArg</parameter></literal></term>
+ <listitem>
+ <para>
+ pass-through argument for <parameter>parserSetup</parameter>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>cursorOptions</parameter></literal></term>
+ <listitem>
+ <para>
+ integer bit mask of cursor options; zero produces default behavior
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <function>SPI_prepare_params</function> has the same return conventions as
+ <function>SPI_prepare</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-getargcount">
+ <indexterm><primary>SPI_getargcount</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_getargcount</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_getargcount</refname>
+ <refpurpose>return the number of arguments needed by a statement
+ prepared by <function>SPI_prepare</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_getargcount(SPIPlanPtr <parameter>plan</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_getargcount</function> returns the number of arguments needed
+ to execute a statement prepared by <function>SPI_prepare</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+ <para>
+ The count of expected arguments for the <parameter>plan</parameter>.
+ If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
+ <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
+ and -1 is returned.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-getargtypeid">
+ <indexterm><primary>SPI_getargtypeid</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_getargtypeid</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_getargtypeid</refname>
+ <refpurpose>return the data type OID for an argument of
+ a statement prepared by <function>SPI_prepare</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Oid SPI_getargtypeid(SPIPlanPtr <parameter>plan</parameter>, int <parameter>argIndex</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_getargtypeid</function> returns the OID representing the type
+ for the <parameter>argIndex</parameter>'th argument of a statement prepared by
+ <function>SPI_prepare</function>. First argument is at index zero.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>argIndex</parameter></literal></term>
+ <listitem>
+ <para>
+ zero based index of the argument
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+ <para>
+ The type OID of the argument at the given index.
+ If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
+ or <parameter>argIndex</parameter> is less than 0 or
+ not less than the number of arguments declared for the
+ <parameter>plan</parameter>,
+ <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
+ and <symbol>InvalidOid</symbol> is returned.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-is-cursor-plan">
+ <indexterm><primary>SPI_is_cursor_plan</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_is_cursor_plan</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_is_cursor_plan</refname>
+ <refpurpose>return <symbol>true</symbol> if a statement
+ prepared by <function>SPI_prepare</function> can be used with
+ <function>SPI_cursor_open</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_is_cursor_plan</function> returns <symbol>true</symbol>
+ if a statement prepared by <function>SPI_prepare</function> can be passed
+ as an argument to <function>SPI_cursor_open</function>, or
+ <symbol>false</symbol> if that is not the case. The criteria are that the
+ <parameter>plan</parameter> represents one single command and that this
+ command returns tuples to the caller; for example, <command>SELECT</command>
+ is allowed unless it contains an <literal>INTO</literal> clause, and
+ <command>UPDATE</command> is allowed only if it contains a <literal>RETURNING</literal>
+ clause.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+ <para>
+ <symbol>true</symbol> or <symbol>false</symbol> to indicate if the
+ <parameter>plan</parameter> can produce a cursor or not, with
+ <varname>SPI_result</varname> set to zero.
+ If it is not possible to determine the answer (for example,
+ if the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
+ or if called when not connected to SPI), then
+ <varname>SPI_result</varname> is set to a suitable error code
+ and <symbol>false</symbol> is returned.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execute-plan">
+ <indexterm><primary>SPI_execute_plan</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execute_plan</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execute_plan</refname>
+ <refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
+ bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execute_plan</function> executes a statement prepared by
+ <function>SPI_prepare</function> or one of its siblings.
+ <parameter>read_only</parameter> and
+ <parameter>count</parameter> have the same interpretation as in
+ <function>SPI_execute</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
+ <listitem>
+ <para>
+ An array of actual parameter values. Must have same length as the
+ statement's number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
+ <listitem>
+ <para>
+ An array describing which parameters are null. Must have same length as
+ the statement's number of arguments.
+ </para>
+
+ <para>
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
+ <function>SPI_execute_plan</function> assumes that no parameters
+ are null. Otherwise, each entry of the <parameter>nulls</parameter>
+ array should be <literal>'&nbsp;'</literal> if the corresponding parameter
+ value is non-null, or <literal>'n'</literal> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <parameter>values</parameter> entry doesn't matter.) Note
+ that <parameter>nulls</parameter> is not a text string, just an array:
+ it does not need a <literal>'\0'</literal> terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The return value is the same as for <function>SPI_execute</function>,
+ with the following additional possible error (negative) results:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
+ or <parameter>count</parameter> is less than 0
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_PARAM</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>values</parameter> is <symbol>NULL</symbol> and
+ <parameter>plan</parameter> was prepared with some parameters
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute</function> if successful.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execute-plan-extended">
+ <indexterm><primary>SPI_execute_plan_extended</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execute_plan_extended</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execute_plan_extended</refname>
+ <refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execute_plan_extended(SPIPlanPtr <parameter>plan</parameter>,
+ const SPIExecuteOptions * <parameter>options</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execute_plan_extended</function> executes a statement
+ prepared by <function>SPI_prepare</function> or one of its siblings.
+ This function is equivalent to <function>SPI_execute_plan</function>,
+ except that information about the parameter values to be passed to the
+ query is presented differently, and additional execution-controlling
+ options can be passed.
+ </para>
+
+ <para>
+ Query parameter values are represented by
+ a <literal>ParamListInfo</literal> struct, which is convenient for passing
+ down values that are already available in that format. Dynamic parameter
+ sets can also be used, via hook functions specified
+ in <literal>ParamListInfo</literal>.
+ </para>
+
+ <para>
+ Also, instead of always accumulating the result tuples into a
+ <varname>SPI_tuptable</varname> structure, tuples can be passed to a
+ caller-supplied <literal>DestReceiver</literal> object as they are
+ generated by the executor. This is particularly helpful for queries
+ that might generate many tuples, since the data can be processed
+ on-the-fly instead of being accumulated in memory.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const SPIExecuteOptions * <parameter>options</parameter></literal></term>
+ <listitem>
+ <para>
+ struct containing optional arguments
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Callers should always zero out the entire <parameter>options</parameter>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <parameter>options</parameter> fields are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
+ <listitem>
+ <para>
+ data structure containing query parameter types and values; NULL if none
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>allow_nonatomic</parameter></literal></term>
+ <listitem>
+ <para>
+ <literal>true</literal> allows non-atomic execution of CALL and DO
+ statements
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>must_return_tuples</parameter></literal></term>
+ <listitem>
+ <para>
+ if <literal>true</literal>, raise error if the query is not of a kind
+ that returns tuples (this does not forbid the case where it happens to
+ return zero tuples)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>uint64 <parameter>tcount</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>DestReceiver * <parameter>dest</parameter></literal></term>
+ <listitem>
+ <para>
+ <literal>DestReceiver</literal> object that will receive any tuples
+ emitted by the query; if NULL, result tuples are accumulated into
+ a <varname>SPI_tuptable</varname> structure, as
+ in <function>SPI_execute_plan</function>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ResourceOwner <parameter>owner</parameter></literal></term>
+ <listitem>
+ <para>
+ The resource owner that will hold a reference count on the plan while
+ it is executed. If NULL, CurrentResourceOwner is used. Ignored for
+ non-saved plans, as SPI does not acquire reference counts on those.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The return value is the same as for <function>SPI_execute_plan</function>.
+ </para>
+
+ <para>
+ When <parameter>options-&gt;dest</parameter> is NULL,
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute_plan</function>.
+ When <parameter>options-&gt;dest</parameter> is not NULL,
+ <varname>SPI_processed</varname> is set to zero and
+ <varname>SPI_tuptable</varname> is set to NULL. If a tuple count
+ is required, the caller's <literal>DestReceiver</literal> object must
+ calculate it.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execute-plan-with-paramlist">
+ <indexterm><primary>SPI_execute_plan_with_paramlist</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execute_plan_with_paramlist</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execute_plan_with_paramlist</refname>
+ <refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execute_plan_with_paramlist(SPIPlanPtr <parameter>plan</parameter>,
+ ParamListInfo <parameter>params</parameter>,
+ bool <parameter>read_only</parameter>,
+ long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execute_plan_with_paramlist</function> executes a statement
+ prepared by <function>SPI_prepare</function>.
+ This function is equivalent to <function>SPI_execute_plan</function>
+ except that information about the parameter values to be passed to the
+ query is presented differently. The <literal>ParamListInfo</literal>
+ representation can be convenient for passing down values that are
+ already available in that format. It also supports use of dynamic
+ parameter sets via hook functions specified in <literal>ParamListInfo</literal>.
+ </para>
+
+ <para>
+ This function is now deprecated in favor
+ of <function>SPI_execute_plan_extended</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
+ <listitem>
+ <para>
+ data structure containing parameter types and values; NULL if none
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The return value is the same as for <function>SPI_execute_plan</function>.
+ </para>
+
+ <para>
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute_plan</function> if successful.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-execp">
+ <indexterm><primary>SPI_execp</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_execp</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_execp</refname>
+ <refpurpose>execute a statement in read/write mode</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_execp</function> is the same as
+ <function>SPI_execute_plan</function>, with the latter's
+ <parameter>read_only</parameter> parameter always taken as
+ <literal>false</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
+ <listitem>
+ <para>
+ An array of actual parameter values. Must have same length as the
+ statement's number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
+ <listitem>
+ <para>
+ An array describing which parameters are null. Must have same length as
+ the statement's number of arguments.
+ </para>
+
+ <para>
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
+ <function>SPI_execp</function> assumes that no parameters
+ are null. Otherwise, each entry of the <parameter>nulls</parameter>
+ array should be <literal>'&nbsp;'</literal> if the corresponding parameter
+ value is non-null, or <literal>'n'</literal> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <parameter>values</parameter> entry doesn't matter.) Note
+ that <parameter>nulls</parameter> is not a text string, just an array:
+ it does not need a <literal>'\0'</literal> terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to return,
+ or <literal>0</literal> for no limit
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ See <function>SPI_execute_plan</function>.
+ </para>
+
+ <para>
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute</function> if successful.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-open">
+ <indexterm><primary>SPI_cursor_open</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_open</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_open</refname>
+ <refpurpose>set up a cursor using a statement created with <function>SPI_prepare</function></refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>,
+ Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
+ bool <parameter>read_only</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_open</function> sets up a cursor (internally,
+ a portal) that will execute a statement prepared by
+ <function>SPI_prepare</function>. The parameters have the same
+ meanings as the corresponding parameters to
+ <function>SPI_execute_plan</function>.
+ </para>
+
+ <para>
+ Using a cursor instead of executing the statement directly has two
+ benefits. First, the result rows can be retrieved a few at a time,
+ avoiding memory overrun for queries that return many rows. Second,
+ a portal can outlive the current C function (it can, in fact, live
+ to the end of the current transaction). Returning the portal name
+ to the C function's caller provides a way of returning a row set as
+ result.
+ </para>
+
+ <para>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>name</parameter></literal></term>
+ <listitem>
+ <para>
+ name for portal, or <symbol>NULL</symbol> to let the system
+ select a name
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
+ <listitem>
+ <para>
+ An array of actual parameter values. Must have same length as the
+ statement's number of arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
+ <listitem>
+ <para>
+ An array describing which parameters are null. Must have same length as
+ the statement's number of arguments.
+ </para>
+
+ <para>
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
+ <function>SPI_cursor_open</function> assumes that no parameters
+ are null. Otherwise, each entry of the <parameter>nulls</parameter>
+ array should be <literal>'&nbsp;'</literal> if the corresponding parameter
+ value is non-null, or <literal>'n'</literal> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <parameter>values</parameter> entry doesn't matter.) Note
+ that <parameter>nulls</parameter> is not a text string, just an array:
+ it does not need a <literal>'\0'</literal> terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <function>elog</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-open-with-args">
+ <indexterm><primary>SPI_cursor_open_with_args</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_open_with_args</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_open_with_args</refname>
+ <refpurpose>set up a cursor using a query and parameters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>,
+ const char *<parameter>command</parameter>,
+ int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>,
+ Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>,
+ bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_open_with_args</function> sets up a cursor
+ (internally, a portal) that will execute the specified query.
+ Most of the parameters have the same meanings as the corresponding
+ parameters to <function>SPI_prepare_cursor</function>
+ and <function>SPI_cursor_open</function>.
+ </para>
+
+ <para>
+ For one-time query execution, this function should be preferred
+ over <function>SPI_prepare_cursor</function> followed by
+ <function>SPI_cursor_open</function>.
+ If the same command is to be executed with many different parameters,
+ either method might be faster, depending on the cost of re-planning
+ versus the benefit of custom plans.
+ </para>
+
+ <para>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </para>
+
+ <para>
+ This function is now deprecated in favor
+ of <function>SPI_cursor_parse_open</function>, which provides equivalent
+ functionality using a more modern API for handling query parameters.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>name</parameter></literal></term>
+ <listitem>
+ <para>
+ name for portal, or <symbol>NULL</symbol> to let the system
+ select a name
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>nargs</parameter></literal></term>
+ <listitem>
+ <para>
+ number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>nargs</parameter>, containing the
+ <acronym>OID</acronym>s of the data types of the parameters
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>nargs</parameter>, containing the actual
+ parameter values
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>nargs</parameter>, describing which
+ parameters are null
+ </para>
+
+ <para>
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
+ <function>SPI_cursor_open_with_args</function> assumes that no parameters
+ are null. Otherwise, each entry of the <parameter>nulls</parameter>
+ array should be <literal>'&nbsp;'</literal> if the corresponding parameter
+ value is non-null, or <literal>'n'</literal> if the corresponding parameter
+ value is null. (In the latter case, the actual value in the
+ corresponding <parameter>values</parameter> entry doesn't matter.) Note
+ that <parameter>nulls</parameter> is not a text string, just an array:
+ it does not need a <literal>'\0'</literal> terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>cursorOptions</parameter></literal></term>
+ <listitem>
+ <para>
+ integer bit mask of cursor options; zero produces default behavior
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <function>elog</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-open-with-paramlist">
+ <indexterm><primary>SPI_cursor_open_with_paramlist</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_open_with_paramlist</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_open_with_paramlist</refname>
+ <refpurpose>set up a cursor using parameters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Portal SPI_cursor_open_with_paramlist(const char *<parameter>name</parameter>,
+ SPIPlanPtr <parameter>plan</parameter>,
+ ParamListInfo <parameter>params</parameter>,
+ bool <parameter>read_only</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_open_with_paramlist</function> sets up a cursor
+ (internally, a portal) that will execute a statement prepared by
+ <function>SPI_prepare</function>.
+ This function is equivalent to <function>SPI_cursor_open</function>
+ except that information about the parameter values to be passed to the
+ query is presented differently. The <literal>ParamListInfo</literal>
+ representation can be convenient for passing down values that are
+ already available in that format. It also supports use of dynamic
+ parameter sets via hook functions specified in <literal>ParamListInfo</literal>.
+ </para>
+
+ <para>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>name</parameter></literal></term>
+ <listitem>
+ <para>
+ name for portal, or <symbol>NULL</symbol> to let the system
+ select a name
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ prepared statement (returned by <function>SPI_prepare</function>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
+ <listitem>
+ <para>
+ data structure containing parameter types and values; NULL if none
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <function>elog</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-parse-open">
+ <indexterm><primary>SPI_cursor_parse_open</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_parse_open</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_parse_open</refname>
+ <refpurpose>set up a cursor using a query string and parameters</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Portal SPI_cursor_parse_open(const char *<parameter>name</parameter>,
+ const char *<parameter>command</parameter>,
+ const SPIParseOpenOptions * <parameter>options</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_parse_open</function> sets up a cursor
+ (internally, a portal) that will execute the specified query string.
+ This is comparable to <function>SPI_prepare_cursor</function> followed
+ by <function>SPI_cursor_open_with_paramlist</function>, except that
+ parameter references within the query string are handled entirely by
+ supplying a <literal>ParamListInfo</literal> object.
+ </para>
+
+ <para>
+ For one-time query execution, this function should be preferred
+ over <function>SPI_prepare_cursor</function> followed by
+ <function>SPI_cursor_open_with_paramlist</function>.
+ If the same command is to be executed with many different parameters,
+ either method might be faster, depending on the cost of re-planning
+ versus the benefit of custom plans.
+ </para>
+
+ <para>
+ The <parameter>options-&gt;params</parameter> object should normally
+ mark each parameter with the <literal>PARAM_FLAG_CONST</literal> flag,
+ since a one-shot plan is always used for the query.
+ </para>
+
+ <para>
+ The passed-in parameter data will be copied into the cursor's portal, so it
+ can be freed while the cursor still exists.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>name</parameter></literal></term>
+ <listitem>
+ <para>
+ name for portal, or <symbol>NULL</symbol> to let the system
+ select a name
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>command</parameter></literal></term>
+ <listitem>
+ <para>
+ command string
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const SPIParseOpenOptions * <parameter>options</parameter></literal></term>
+ <listitem>
+ <para>
+ struct containing optional arguments
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Callers should always zero out the entire <parameter>options</parameter>
+ struct, then fill whichever fields they want to set. This ensures forward
+ compatibility of code, since any fields that are added to the struct in
+ future will be defined to behave backwards-compatibly if they are zero.
+ The currently available <parameter>options</parameter> fields are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
+ <listitem>
+ <para>
+ data structure containing query parameter types and values; NULL if none
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>cursorOptions</parameter></literal></term>
+ <listitem>
+ <para>
+ integer bit mask of cursor options; zero produces default behavior
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>read_only</parameter></literal></term>
+ <listitem>
+ <para><literal>true</literal> for read-only execution</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Pointer to portal containing the cursor. Note there is no error
+ return convention; any error will be reported via <function>elog</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-find">
+ <indexterm><primary>SPI_cursor_find</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_find</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_find</refname>
+ <refpurpose>find an existing cursor by name</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Portal SPI_cursor_find(const char * <parameter>name</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_find</function> finds an existing portal by
+ name. This is primarily useful to resolve a cursor name returned
+ as text by some other function.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>name</parameter></literal></term>
+ <listitem>
+ <para>
+ name of the portal
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ pointer to the portal with the specified name, or
+ <symbol>NULL</symbol> if none was found
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-fetch">
+ <indexterm><primary>SPI_cursor_fetch</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_fetch</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_fetch</refname>
+ <refpurpose>fetch some rows from a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_cursor_fetch(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_fetch</function> fetches some rows from a
+ cursor. This is equivalent to a subset of the SQL command
+ <command>FETCH</command> (see <function>SPI_scroll_cursor_fetch</function>
+ for more functionality).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Portal <parameter>portal</parameter></literal></term>
+ <listitem>
+ <para>
+ portal containing the cursor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>forward</parameter></literal></term>
+ <listitem>
+ <para>
+ true for fetch forward, false for fetch backward
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to fetch
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute</function> if successful.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Fetching backward may fail if the cursor's plan was not created
+ with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-move">
+ <indexterm><primary>SPI_cursor_move</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_move</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_move</refname>
+ <refpurpose>move a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_cursor_move(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_move</function> skips over some number of rows
+ in a cursor. This is equivalent to a subset of the SQL command
+ <command>MOVE</command> (see <function>SPI_scroll_cursor_move</function>
+ for more functionality).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Portal <parameter>portal</parameter></literal></term>
+ <listitem>
+ <para>
+ portal containing the cursor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool <parameter>forward</parameter></literal></term>
+ <listitem>
+ <para>
+ true for move forward, false for move backward
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ maximum number of rows to move
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ Moving backward may fail if the cursor's plan was not created
+ with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-scroll-cursor-fetch">
+ <indexterm><primary>SPI_scroll_cursor_fetch</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_scroll_cursor_fetch</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_scroll_cursor_fetch</refname>
+ <refpurpose>fetch some rows from a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_scroll_cursor_fetch(Portal <parameter>portal</parameter>, FetchDirection <parameter>direction</parameter>,
+ long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_scroll_cursor_fetch</function> fetches some rows from a
+ cursor. This is equivalent to the SQL command <command>FETCH</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Portal <parameter>portal</parameter></literal></term>
+ <listitem>
+ <para>
+ portal containing the cursor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FetchDirection <parameter>direction</parameter></literal></term>
+ <listitem>
+ <para>
+ one of <symbol>FETCH_FORWARD</symbol>,
+ <symbol>FETCH_BACKWARD</symbol>,
+ <symbol>FETCH_ABSOLUTE</symbol> or
+ <symbol>FETCH_RELATIVE</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ number of rows to fetch for
+ <symbol>FETCH_FORWARD</symbol> or
+ <symbol>FETCH_BACKWARD</symbol>; absolute row number to fetch for
+ <symbol>FETCH_ABSOLUTE</symbol>; or relative row number to fetch for
+ <symbol>FETCH_RELATIVE</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <varname>SPI_processed</varname> and
+ <varname>SPI_tuptable</varname> are set as in
+ <function>SPI_execute</function> if successful.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ See the SQL <xref linkend="sql-fetch"/> command
+ for details of the interpretation of the
+ <parameter>direction</parameter> and
+ <parameter>count</parameter> parameters.
+ </para>
+
+ <para>
+ Direction values other than <symbol>FETCH_FORWARD</symbol>
+ may fail if the cursor's plan was not created
+ with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-scroll-cursor-move">
+ <indexterm><primary>SPI_scroll_cursor_move</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_scroll_cursor_move</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_scroll_cursor_move</refname>
+ <refpurpose>move a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_scroll_cursor_move(Portal <parameter>portal</parameter>, FetchDirection <parameter>direction</parameter>,
+ long <parameter>count</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_scroll_cursor_move</function> skips over some number of rows
+ in a cursor. This is equivalent to the SQL command
+ <command>MOVE</command>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Portal <parameter>portal</parameter></literal></term>
+ <listitem>
+ <para>
+ portal containing the cursor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FetchDirection <parameter>direction</parameter></literal></term>
+ <listitem>
+ <para>
+ one of <symbol>FETCH_FORWARD</symbol>,
+ <symbol>FETCH_BACKWARD</symbol>,
+ <symbol>FETCH_ABSOLUTE</symbol> or
+ <symbol>FETCH_RELATIVE</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>long <parameter>count</parameter></literal></term>
+ <listitem>
+ <para>
+ number of rows to move for
+ <symbol>FETCH_FORWARD</symbol> or
+ <symbol>FETCH_BACKWARD</symbol>; absolute row number to move to for
+ <symbol>FETCH_ABSOLUTE</symbol>; or relative row number to move to for
+ <symbol>FETCH_RELATIVE</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <varname>SPI_processed</varname> is set as in
+ <function>SPI_execute</function> if successful.
+ <varname>SPI_tuptable</varname> is set to <symbol>NULL</symbol>, since
+ no rows are returned by this function.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ See the SQL <xref linkend="sql-fetch"/> command
+ for details of the interpretation of the
+ <parameter>direction</parameter> and
+ <parameter>count</parameter> parameters.
+ </para>
+
+ <para>
+ Direction values other than <symbol>FETCH_FORWARD</symbol>
+ may fail if the cursor's plan was not created
+ with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-cursor-close">
+ <indexterm><primary>SPI_cursor_close</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_cursor_close</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_cursor_close</refname>
+ <refpurpose>close a cursor</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_cursor_close(Portal <parameter>portal</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_cursor_close</function> closes a previously created
+ cursor and releases its portal storage.
+ </para>
+
+ <para>
+ All open cursors are closed automatically at the end of a
+ transaction. <function>SPI_cursor_close</function> need only be
+ invoked if it is desirable to release resources sooner.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Portal <parameter>portal</parameter></literal></term>
+ <listitem>
+ <para>
+ portal containing the cursor
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-keepplan">
+ <indexterm><primary>SPI_keepplan</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_keepplan</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_keepplan</refname>
+ <refpurpose>save a prepared statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_keepplan(SPIPlanPtr <parameter>plan</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_keepplan</function> saves a passed statement (prepared by
+ <function>SPI_prepare</function>) so that it will not be freed
+ by <function>SPI_finish</function> nor by the transaction manager.
+ This gives you the ability to reuse prepared statements in the subsequent
+ invocations of your C function in the current session.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ the prepared statement to be saved
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ 0 on success;
+ <symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
+ is <symbol>NULL</symbol> or invalid
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The passed-in statement is relocated to permanent storage by means
+ of pointer adjustment (no data copying is required). If you later
+ wish to delete it, use <function>SPI_freeplan</function> on it.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-saveplan">
+ <indexterm><primary>SPI_saveplan</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_saveplan</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_saveplan</refname>
+ <refpurpose>save a prepared statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_saveplan</function> copies a passed statement (prepared by
+ <function>SPI_prepare</function>) into memory that will not be freed
+ by <function>SPI_finish</function> nor by the transaction manager,
+ and returns a pointer to the copied statement. This gives you the
+ ability to reuse prepared statements in the subsequent invocations of
+ your C function in the current session.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ the prepared statement to be saved
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Pointer to the copied statement; or <symbol>NULL</symbol> if unsuccessful.
+ On error, <varname>SPI_result</varname> is set thus:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected C function
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ The originally passed-in statement is not freed, so you might wish to do
+ <function>SPI_freeplan</function> on it to avoid leaking memory
+ until <function>SPI_finish</function>.
+ </para>
+
+ <para>
+ In most cases, <function>SPI_keepplan</function> is preferred to this
+ function, since it accomplishes largely the same result without needing
+ to physically copy the prepared statement's data structures.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-register-relation">
+ <indexterm><primary>SPI_register_relation</primary></indexterm>
+
+ <indexterm>
+ <primary>ephemeral named relation</primary>
+ <secondary>registering with SPI</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_register_relation</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_register_relation</refname>
+ <refpurpose>make an ephemeral named relation available by name in SPI queries</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_register_relation(EphemeralNamedRelation <parameter>enr</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_register_relation</function> makes an ephemeral named
+ relation, with associated information, available to queries planned and
+ executed through the current SPI connection.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>EphemeralNamedRelation <parameter>enr</parameter></literal></term>
+ <listitem>
+ <para>
+ the ephemeral named relation registry entry
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_REL_REGISTER</symbol></term>
+ <listitem>
+ <para>
+ if the relation has been successfully registered by name
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ On error, one of the following negative values is returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>enr</parameter> is <symbol>NULL</symbol> or its
+ <varname>name</varname> field is <symbol>NULL</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected C function
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_REL_DUPLICATE</symbol></term>
+ <listitem>
+ <para>
+ if the name specified in the <varname>name</varname> field of
+ <parameter>enr</parameter> is already registered for this connection
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-unregister-relation">
+ <indexterm><primary>SPI_unregister_relation</primary></indexterm>
+
+ <indexterm>
+ <primary>ephemeral named relation</primary>
+ <secondary>unregistering from SPI</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_unregister_relation</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_unregister_relation</refname>
+ <refpurpose>remove an ephemeral named relation from the registry</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_unregister_relation(const char * <parameter>name</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_unregister_relation</function> removes an ephemeral named
+ relation from the registry for the current connection.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>const char * <parameter>name</parameter></literal></term>
+ <listitem>
+ <para>
+ the relation registry entry name
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_REL_UNREGISTER</symbol></term>
+ <listitem>
+ <para>
+ if the tuplestore has been successfully removed from the registry
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ On error, one of the following negative values is returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>name</parameter> is <symbol>NULL</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected C function
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_REL_NOT_FOUND</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>name</parameter> is not found in the registry for the
+ current connection
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-register-trigger-data">
+ <indexterm><primary>SPI_register_trigger_data</primary></indexterm>
+
+ <indexterm>
+ <primary>ephemeral named relation</primary>
+ <secondary>registering with SPI</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>transition tables</primary>
+ <secondary>implementation in PLs</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_register_trigger_data</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_register_trigger_data</refname>
+ <refpurpose>make ephemeral trigger data available in SPI queries</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_register_trigger_data(TriggerData *<parameter>tdata</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_register_trigger_data</function> makes any ephemeral
+ relations captured by a trigger available to queries planned and executed
+ through the current SPI connection. Currently, this means the transition
+ tables captured by an <literal>AFTER</literal> trigger defined with a
+ <literal>REFERENCING OLD/NEW TABLE AS</literal> ... clause. This function
+ should be called by a PL trigger handler function after connecting.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TriggerData *<parameter>tdata</parameter></literal></term>
+ <listitem>
+ <para>
+ the <structname>TriggerData</structname> object passed to a trigger
+ handler function as <literal>fcinfo->context</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_TD_REGISTER</symbol></term>
+ <listitem>
+ <para>
+ if the captured trigger data (if any) has been successfully registered
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ On error, one of the following negative values is returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>tdata</parameter> is <symbol>NULL</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected C function
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_REL_DUPLICATE</symbol></term>
+ <listitem>
+ <para>
+ if the name of any trigger data transient relation is already
+ registered for this connection
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+</sect1>
+
+<sect1 id="spi-interface-support">
+ <title>Interface Support Functions</title>
+
+ <para>
+ The functions described here provide an interface for extracting
+ information from result sets returned by <function>SPI_execute</function> and
+ other SPI functions.
+ </para>
+
+ <para>
+ All functions described in this section can be used by both
+ connected and unconnected C functions.
+ </para>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-fname">
+ <indexterm><primary>SPI_fname</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_fname</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_fname</refname>
+ <refpurpose>determine the column name for the specified column number</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+char * SPI_fname(TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_fname</function> returns a copy of the column name of the
+ specified column. (You can use <function>pfree</function> to
+ release the copy of the name when you don't need it anymore.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ input row description
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>colnumber</parameter></literal></term>
+ <listitem>
+ <para>
+ column number (count starts at 1)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The column name; <symbol>NULL</symbol> if
+ <parameter>colnumber</parameter> is out of range.
+ <varname>SPI_result</varname> set to
+ <symbol>SPI_ERROR_NOATTRIBUTE</symbol> on error.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-fnumber">
+ <indexterm><primary>SPI_fnumber</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_fnumber</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_fnumber</refname>
+ <refpurpose>determine the column number for the specified column name</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_fnumber(TupleDesc <parameter>rowdesc</parameter>, const char * <parameter>colname</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_fnumber</function> returns the column number for the
+ column with the specified name.
+ </para>
+
+ <para>
+ If <parameter>colname</parameter> refers to a system column (e.g.,
+ <literal>ctid</literal>) then the appropriate negative column number will
+ be returned. The caller should be careful to test the return value
+ for exact equality to <symbol>SPI_ERROR_NOATTRIBUTE</symbol> to
+ detect an error; testing the result for less than or equal to 0 is
+ not correct unless system columns should be rejected.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ input row description
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>colname</parameter></literal></term>
+ <listitem>
+ <para>
+ column name
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Column number (count starts at 1 for user-defined columns), or
+ <symbol>SPI_ERROR_NOATTRIBUTE</symbol> if the named column was not
+ found.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-getvalue">
+ <indexterm><primary>SPI_getvalue</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_getvalue</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_getvalue</refname>
+ <refpurpose>return the string value of the specified column</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+char * SPI_getvalue(HeapTuple <parameter>row</parameter>, TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_getvalue</function> returns the string representation
+ of the value of the specified column.
+ </para>
+
+ <para>
+ The result is returned in memory allocated using
+ <function>palloc</function>. (You can use
+ <function>pfree</function> to release the memory when you don't
+ need it anymore.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>HeapTuple <parameter>row</parameter></literal></term>
+ <listitem>
+ <para>
+ input row to be examined
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ input row description
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>colnumber</parameter></literal></term>
+ <listitem>
+ <para>
+ column number (count starts at 1)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ Column value, or <symbol>NULL</symbol> if the column is null,
+ <parameter>colnumber</parameter> is out of range
+ (<varname>SPI_result</varname> is set to
+ <symbol>SPI_ERROR_NOATTRIBUTE</symbol>), or no output function is
+ available (<varname>SPI_result</varname> is set to
+ <symbol>SPI_ERROR_NOOUTFUNC</symbol>).
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-getbinval">
+ <indexterm><primary>SPI_getbinval</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_getbinval</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_getbinval</refname>
+ <refpurpose>return the binary value of the specified column</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Datum SPI_getbinval(HeapTuple <parameter>row</parameter>, TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>,
+ bool * <parameter>isnull</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_getbinval</function> returns the value of the
+ specified column in the internal form (as type <type>Datum</type>).
+ </para>
+
+ <para>
+ This function does not allocate new space for the datum. In the
+ case of a pass-by-reference data type, the return value will be a
+ pointer into the passed row.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>HeapTuple <parameter>row</parameter></literal></term>
+ <listitem>
+ <para>
+ input row to be examined
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ input row description
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>colnumber</parameter></literal></term>
+ <listitem>
+ <para>
+ column number (count starts at 1)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool * <parameter>isnull</parameter></literal></term>
+ <listitem>
+ <para>
+ flag for a null value in the column
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The binary value of the column is returned. The variable pointed
+ to by <parameter>isnull</parameter> is set to true if the column is
+ null, else to false.
+ </para>
+
+ <para>
+ <varname>SPI_result</varname> is set to
+ <symbol>SPI_ERROR_NOATTRIBUTE</symbol> on error.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-gettype">
+ <indexterm><primary>SPI_gettype</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_gettype</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_gettype</refname>
+ <refpurpose>return the data type name of the specified column</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+char * SPI_gettype(TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_gettype</function> returns a copy of the data type name of the
+ specified column. (You can use <function>pfree</function> to
+ release the copy of the name when you don't need it anymore.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ input row description
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>colnumber</parameter></literal></term>
+ <listitem>
+ <para>
+ column number (count starts at 1)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The data type name of the specified column, or
+ <symbol>NULL</symbol> on error. <varname>SPI_result</varname> is
+ set to <symbol>SPI_ERROR_NOATTRIBUTE</symbol> on error.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-gettypeid">
+ <indexterm><primary>SPI_gettypeid</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_gettypeid</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_gettypeid</refname>
+ <refpurpose>return the data type <acronym>OID</acronym> of the specified column</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+Oid SPI_gettypeid(TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_gettypeid</function> returns the
+ <acronym>OID</acronym> of the data type of the specified column.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ input row description
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>colnumber</parameter></literal></term>
+ <listitem>
+ <para>
+ column number (count starts at 1)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The <acronym>OID</acronym> of the data type of the specified column
+ or <symbol>InvalidOid</symbol> on error. On error,
+ <varname>SPI_result</varname> is set to
+ <symbol>SPI_ERROR_NOATTRIBUTE</symbol>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-getrelname">
+ <indexterm><primary>SPI_getrelname</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_getrelname</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_getrelname</refname>
+ <refpurpose>return the name of the specified relation</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+char * SPI_getrelname(Relation <parameter>rel</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_getrelname</function> returns a copy of the name of the
+ specified relation. (You can use <function>pfree</function> to
+ release the copy of the name when you don't need it anymore.)
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Relation <parameter>rel</parameter></literal></term>
+ <listitem>
+ <para>
+ input relation
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The name of the specified relation.
+ </para>
+ </refsect1>
+</refentry>
+
+<refentry id="spi-spi-getnspname">
+ <indexterm><primary>SPI_getnspname</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_getnspname</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_getnspname</refname>
+ <refpurpose>return the namespace of the specified relation</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+char * SPI_getnspname(Relation <parameter>rel</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_getnspname</function> returns a copy of the name of
+ the namespace that the specified <structname>Relation</structname>
+ belongs to. This is equivalent to the relation's schema. You should
+ <function>pfree</function> the return value of this function when
+ you are finished with it.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Relation <parameter>rel</parameter></literal></term>
+ <listitem>
+ <para>
+ input relation
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ The name of the specified relation's namespace.
+ </para>
+ </refsect1>
+</refentry>
+
+<refentry id="spi-spi-result-code-string">
+ <indexterm><primary>SPI_result_code_string</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_result_code_string</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_result_code_string</refname>
+ <refpurpose>return error code as string</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+const char * SPI_result_code_string(int <parameter>code</parameter>);
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_result_code_string</function> returns a string representation
+ of the result code returned by various SPI functions or stored
+ in <varname>SPI_result</varname>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>int <parameter>code</parameter></literal></term>
+ <listitem>
+ <para>
+ result code
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ A string representation of the result code.
+ </para>
+ </refsect1>
+</refentry>
+
+ </sect1>
+
+ <sect1 id="spi-memory">
+ <title>Memory Management</title>
+
+ <para>
+ <indexterm>
+ <primary>memory context</primary>
+ <secondary>in SPI</secondary>
+ </indexterm>
+ <productname>PostgreSQL</productname> allocates memory within
+ <firstterm>memory contexts</firstterm>, which provide a convenient method of
+ managing allocations made in many different places that need to
+ live for differing amounts of time. Destroying a context releases
+ all the memory that was allocated in it. Thus, it is not necessary
+ to keep track of individual objects to avoid memory leaks; instead
+ only a relatively small number of contexts have to be managed.
+ <function>palloc</function> and related functions allocate memory
+ from the <quote>current</quote> context.
+ </para>
+
+ <para>
+ <function>SPI_connect</function> creates a new memory context and
+ makes it current. <function>SPI_finish</function> restores the
+ previous current memory context and destroys the context created by
+ <function>SPI_connect</function>. These actions ensure that
+ transient memory allocations made inside your C function are
+ reclaimed at C function exit, avoiding memory leakage.
+ </para>
+
+ <para>
+ However, if your C function needs to return an object in allocated
+ memory (such as a value of a pass-by-reference data type), you
+ cannot allocate that memory using <function>palloc</function>, at
+ least not while you are connected to SPI. If you try, the object
+ will be deallocated by <function>SPI_finish</function>, and your
+ C function will not work reliably. To solve this problem, use
+ <function>SPI_palloc</function> to allocate memory for your return
+ object. <function>SPI_palloc</function> allocates memory in the
+ <quote>upper executor context</quote>, that is, the memory context
+ that was current when <function>SPI_connect</function> was called,
+ which is precisely the right context for a value returned from your
+ C function. Several of the other utility functions described in
+ this section also return objects created in the upper executor context.
+ </para>
+
+ <para>
+ When <function>SPI_connect</function> is called, the private
+ context of the C function, which is created by
+ <function>SPI_connect</function>, is made the current context. All
+ allocations made by <function>palloc</function>,
+ <function>repalloc</function>, or SPI utility functions (except as
+ described in this section) are made in this context. When a
+ C function disconnects from the SPI manager (via
+ <function>SPI_finish</function>) the current context is restored to
+ the upper executor context, and all allocations made in the
+ C function memory context are freed and cannot be used any more.
+ </para>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-palloc">
+ <indexterm><primary>SPI_palloc</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_palloc</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_palloc</refname>
+ <refpurpose>allocate memory in the upper executor context</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void * SPI_palloc(Size <parameter>size</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_palloc</function> allocates memory in the upper
+ executor context.
+ </para>
+
+ <para>
+ This function can only be used while connected to SPI.
+ Otherwise, it throws an error.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Size <parameter>size</parameter></literal></term>
+ <listitem>
+ <para>
+ size in bytes of storage to allocate
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ pointer to new storage space of the specified size
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-realloc">
+ <indexterm><primary>SPI_repalloc</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_repalloc</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_repalloc</refname>
+ <refpurpose>reallocate memory in the upper executor context</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void * SPI_repalloc(void * <parameter>pointer</parameter>, Size <parameter>size</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_repalloc</function> changes the size of a memory
+ segment previously allocated using <function>SPI_palloc</function>.
+ </para>
+
+ <para>
+ This function is no longer different from plain
+ <function>repalloc</function>. It's kept just for backward
+ compatibility of existing code.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>void * <parameter>pointer</parameter></literal></term>
+ <listitem>
+ <para>
+ pointer to existing storage to change
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Size <parameter>size</parameter></literal></term>
+ <listitem>
+ <para>
+ size in bytes of storage to allocate
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ pointer to new storage space of specified size with the contents
+ copied from the existing area
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-pfree">
+ <indexterm><primary>SPI_pfree</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_pfree</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_pfree</refname>
+ <refpurpose>free memory in the upper executor context</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_pfree(void * <parameter>pointer</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_pfree</function> frees memory previously allocated
+ using <function>SPI_palloc</function> or
+ <function>SPI_repalloc</function>.
+ </para>
+
+ <para>
+ This function is no longer different from plain
+ <function>pfree</function>. It's kept just for backward
+ compatibility of existing code.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>void * <parameter>pointer</parameter></literal></term>
+ <listitem>
+ <para>
+ pointer to existing storage to free
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-copytuple">
+ <indexterm><primary>SPI_copytuple</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_copytuple</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_copytuple</refname>
+ <refpurpose>make a copy of a row in the upper executor context</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+HeapTuple SPI_copytuple(HeapTuple <parameter>row</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_copytuple</function> makes a copy of a row in the
+ upper executor context. This is normally used to return a modified
+ row from a trigger. In a function declared to return a composite
+ type, use <function>SPI_returntuple</function> instead.
+ </para>
+
+ <para>
+ This function can only be used while connected to SPI.
+ Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
+ <symbol>SPI_ERROR_UNCONNECTED</symbol>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>HeapTuple <parameter>row</parameter></literal></term>
+ <listitem>
+ <para>
+ row to be copied
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ the copied row, or <symbol>NULL</symbol> on error
+ (see <varname>SPI_result</varname> for an error indication)
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-returntuple">
+ <indexterm><primary>SPI_returntuple</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_returntuple</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_returntuple</refname>
+ <refpurpose>prepare to return a tuple as a Datum</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+HeapTupleHeader SPI_returntuple(HeapTuple <parameter>row</parameter>, TupleDesc <parameter>rowdesc</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_returntuple</function> makes a copy of a row in
+ the upper executor context, returning it in the form of a row type <type>Datum</type>.
+ The returned pointer need only be converted to <type>Datum</type> via <function>PointerGetDatum</function>
+ before returning.
+ </para>
+
+ <para>
+ This function can only be used while connected to SPI.
+ Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
+ <symbol>SPI_ERROR_UNCONNECTED</symbol>.
+ </para>
+
+ <para>
+ Note that this should be used for functions that are declared to return
+ composite types. It is not used for triggers; use
+ <function>SPI_copytuple</function> for returning a modified row in a trigger.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>HeapTuple <parameter>row</parameter></literal></term>
+ <listitem>
+ <para>
+ row to be copied
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
+ <listitem>
+ <para>
+ descriptor for row (pass the same descriptor each time for most
+ effective caching)
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ <type>HeapTupleHeader</type> pointing to copied row,
+ or <symbol>NULL</symbol> on error
+ (see <varname>SPI_result</varname> for an error indication)
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-modifytuple">
+ <indexterm><primary>SPI_modifytuple</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_modifytuple</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_modifytuple</refname>
+ <refpurpose>create a row by replacing selected fields of a given row</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+HeapTuple SPI_modifytuple(Relation <parameter>rel</parameter>, HeapTuple <parameter>row</parameter>, int <parameter>ncols</parameter>,
+ int * <parameter>colnum</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_modifytuple</function> creates a new row by
+ substituting new values for selected columns, copying the original
+ row's columns at other positions. The input row is not modified.
+ The new row is returned in the upper executor context.
+ </para>
+
+ <para>
+ This function can only be used while connected to SPI.
+ Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
+ <symbol>SPI_ERROR_UNCONNECTED</symbol>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>Relation <parameter>rel</parameter></literal></term>
+ <listitem>
+ <para>
+ Used only as the source of the row descriptor for the row.
+ (Passing a relation rather than a row descriptor is a
+ misfeature.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>HeapTuple <parameter>row</parameter></literal></term>
+ <listitem>
+ <para>
+ row to be modified
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int <parameter>ncols</parameter></literal></term>
+ <listitem>
+ <para>
+ number of columns to be changed
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>int * <parameter>colnum</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>ncols</parameter>, containing the numbers
+ of the columns that are to be changed (column numbers start at 1)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>Datum * <parameter>values</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>ncols</parameter>, containing the
+ new values for the specified columns
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>const char * <parameter>nulls</parameter></literal></term>
+ <listitem>
+ <para>
+ an array of length <parameter>ncols</parameter>, describing which
+ new values are null
+ </para>
+
+ <para>
+ If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
+ <function>SPI_modifytuple</function> assumes that no new values
+ are null. Otherwise, each entry of the <parameter>nulls</parameter>
+ array should be <literal>'&nbsp;'</literal> if the corresponding new value is
+ non-null, or <literal>'n'</literal> if the corresponding new value is
+ null. (In the latter case, the actual value in the corresponding
+ <parameter>values</parameter> entry doesn't matter.) Note that
+ <parameter>nulls</parameter> is not a text string, just an array: it
+ does not need a <literal>'\0'</literal> terminator.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ new row with modifications, allocated in the upper executor
+ context, or <symbol>NULL</symbol> on error
+ (see <varname>SPI_result</varname> for an error indication)
+ </para>
+
+ <para>
+ On error, <varname>SPI_result</varname> is set as follows:
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>rel</parameter> is <symbol>NULL</symbol>, or if
+ <parameter>row</parameter> is <symbol>NULL</symbol>, or if <parameter>ncols</parameter>
+ is less than or equal to 0, or if <parameter>colnum</parameter> is
+ <symbol>NULL</symbol>, or if <parameter>values</parameter> is <symbol>NULL</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_NOATTRIBUTE</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>colnum</parameter> contains an invalid column number (less
+ than or equal to 0 or greater than the number of columns in
+ <parameter>row</parameter>)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if SPI is not active
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-freetuple">
+ <indexterm><primary>SPI_freetuple</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_freetuple</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_freetuple</refname>
+ <refpurpose>free a row allocated in the upper executor context</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_freetuple(HeapTuple <parameter>row</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_freetuple</function> frees a row previously allocated
+ in the upper executor context.
+ </para>
+
+ <para>
+ This function is no longer different from plain
+ <function>heap_freetuple</function>. It's kept just for backward
+ compatibility of existing code.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>HeapTuple <parameter>row</parameter></literal></term>
+ <listitem>
+ <para>
+ row to free
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-freetupletable">
+ <indexterm><primary>SPI_freetuptable</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_freetuptable</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_freetuptable</refname>
+ <refpurpose>free a row set created by <function>SPI_execute</function> or a similar
+ function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_freetuptable(SPITupleTable * <parameter>tuptable</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_freetuptable</function> frees a row set created by a
+ prior SPI command execution function, such as
+ <function>SPI_execute</function>. Therefore, this function is often called
+ with the global variable <varname>SPI_tuptable</varname> as
+ argument.
+ </para>
+
+ <para>
+ This function is useful if an SPI-using C function needs to execute
+ multiple commands and does not want to keep the results of earlier
+ commands around until it ends. Note that any unfreed row sets will
+ be freed anyway at <function>SPI_finish</function>.
+ Also, if a subtransaction is started and then aborted within execution
+ of an SPI-using C function, SPI automatically frees any row sets created while
+ the subtransaction was running.
+ </para>
+
+ <para>
+ Beginning in <productname>PostgreSQL</productname> 9.3,
+ <function>SPI_freetuptable</function> contains guard logic to protect
+ against duplicate deletion requests for the same row set. In previous
+ releases, duplicate deletions would lead to crashes.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPITupleTable * <parameter>tuptable</parameter></literal></term>
+ <listitem>
+ <para>
+ pointer to row set to free, or NULL to do nothing
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-freeplan">
+ <indexterm><primary>SPI_freeplan</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_freeplan</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_freeplan</refname>
+ <refpurpose>free a previously saved prepared statement</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_freeplan(SPIPlanPtr <parameter>plan</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_freeplan</function> releases a prepared statement
+ previously returned by <function>SPI_prepare</function> or saved by
+ <function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
+ <listitem>
+ <para>
+ pointer to statement to free
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ 0 on success;
+ <symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
+ is <symbol>NULL</symbol> or invalid
+ </para>
+ </refsect1>
+</refentry>
+
+ </sect1>
+
+ <sect1 id="spi-transaction">
+ <title>Transaction Management</title>
+
+ <para>
+ It is not possible to run transaction control commands such
+ as <command>COMMIT</command> and <command>ROLLBACK</command> through SPI
+ functions such as <function>SPI_execute</function>. There are, however,
+ separate interface functions that allow transaction control through SPI.
+ </para>
+
+ <para>
+ It is not generally safe and sensible to start and end transactions in
+ arbitrary user-defined SQL-callable functions without taking into account
+ the context in which they are called. For example, a transaction boundary
+ in the middle of a function that is part of a complex SQL expression that
+ is part of some SQL command will probably result in obscure internal errors
+ or crashes. The interface functions presented here are primarily intended
+ to be used by procedural language implementations to support transaction
+ management in SQL-level procedures that are invoked by the <command>CALL</command>
+ command, taking the context of the <command>CALL</command> invocation into
+ account. SPI-using procedures implemented in C can implement the same logic, but
+ the details of that are beyond the scope of this documentation.
+ </para>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-commit">
+ <indexterm><primary>SPI_commit</primary></indexterm>
+ <indexterm><primary>SPI_commit_and_chain</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_commit</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_commit</refname>
+ <refname>SPI_commit_and_chain</refname>
+ <refpurpose>commit the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_commit(void)
+</synopsis>
+
+<synopsis>
+void SPI_commit_and_chain(void)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_commit</function> commits the current transaction. It is
+ approximately equivalent to running the SQL
+ command <command>COMMIT</command>. After the transaction is committed, a
+ new transaction is automatically started using default transaction
+ characteristics, so that the caller can continue using SPI facilities.
+ If there is a failure during commit, the current transaction is instead
+ rolled back and a new transaction is started, after which the error is
+ thrown in the usual way.
+ </para>
+
+ <para>
+ <function>SPI_commit_and_chain</function> is the same, but the new
+ transaction is started with the same transaction
+ characteristics as the just finished one, like with the SQL command
+ <command>COMMIT AND CHAIN</command>.
+ </para>
+
+ <para>
+ These functions can only be executed if the SPI connection has been set as
+ nonatomic in the call to <function>SPI_connect_ext</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-rollback">
+ <indexterm><primary>SPI_rollback</primary></indexterm>
+ <indexterm><primary>SPI_rollback_and_chain</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_rollback</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_rollback</refname>
+ <refname>SPI_rollback_and_chain</refname>
+ <refpurpose>abort the current transaction</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_rollback(void)
+</synopsis>
+
+<synopsis>
+void SPI_rollback_and_chain(void)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_rollback</function> rolls back the current transaction. It
+ is approximately equivalent to running the SQL
+ command <command>ROLLBACK</command>. After the transaction is rolled back,
+ a new transaction is automatically started using default transaction
+ characteristics, so that the caller can continue using SPI facilities.
+ </para>
+ <para>
+ <function>SPI_rollback_and_chain</function> is the same, but the new
+ transaction is started with the same transaction
+ characteristics as the just finished one, like with the SQL command
+ <command>ROLLBACK AND CHAIN</command>.
+ </para>
+
+ <para>
+ These functions can only be executed if the SPI connection has been set as
+ nonatomic in the call to <function>SPI_connect_ext</function>.
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
+<refentry id="spi-spi-start-transaction">
+ <indexterm><primary>SPI_start_transaction</primary></indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_start_transaction</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_start_transaction</refname>
+ <refpurpose>obsolete function</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+void SPI_start_transaction(void)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_start_transaction</function> does nothing, and exists
+ only for code compatibility with
+ earlier <productname>PostgreSQL</productname> releases. It used to
+ be required after calling <function>SPI_commit</function>
+ or <function>SPI_rollback</function>, but now those functions start
+ a new transaction automatically.
+ </para>
+ </refsect1>
+</refentry>
+
+ </sect1>
+
+ <sect1 id="spi-visibility">
+ <title>Visibility of Data Changes</title>
+
+ <para>
+ The following rules govern the visibility of data changes in
+ functions that use SPI (or any other C function):
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ During the execution of an SQL command, any data changes made by
+ the command are invisible to the command itself. For
+ example, in:
+<programlisting>
+INSERT INTO a SELECT * FROM a;
+</programlisting>
+ the inserted rows are invisible to the <command>SELECT</command>
+ part.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Changes made by a command C are visible to all commands that are
+ started after C, no matter whether they are started inside C
+ (during the execution of C) or after C is done.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Commands executed via SPI inside a function called by an SQL command
+ (either an ordinary function or a trigger) follow one or the
+ other of the above rules depending on the read/write flag passed
+ to SPI. Commands executed in read-only mode follow the first
+ rule: they cannot see changes of the calling command. Commands executed
+ in read-write mode follow the second rule: they can see all changes made
+ so far.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ All standard procedural languages set the SPI read-write mode
+ depending on the volatility attribute of the function. Commands of
+ <literal>STABLE</literal> and <literal>IMMUTABLE</literal> functions are done in
+ read-only mode, while commands of <literal>VOLATILE</literal> functions are
+ done in read-write mode. While authors of C functions are able to
+ violate this convention, it's unlikely to be a good idea to do so.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The next section contains an example that illustrates the
+ application of these rules.
+ </para>
+ </sect1>
+
+ <sect1 id="spi-examples">
+ <title>Examples</title>
+
+ <para>
+ This section contains a very simple example of SPI usage. The
+ C function <function>execq</function> takes an SQL command as its
+ first argument and a row count as its second, executes the command
+ using <function>SPI_exec</function> and returns the number of rows
+ that were processed by the command. You can find more complex
+ examples for SPI in the source tree in
+ <filename>src/test/regress/regress.c</filename> and in the
+ <xref linkend="contrib-spi"/> module.
+ </para>
+
+<programlisting>
+#include "postgres.h"
+
+#include "executor/spi.h"
+#include "utils/builtins.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(execq);
+
+Datum
+execq(PG_FUNCTION_ARGS)
+{
+ char *command;
+ int cnt;
+ int ret;
+ uint64 proc;
+
+ /* Convert given text object to a C string */
+ command = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ cnt = PG_GETARG_INT32(1);
+
+ SPI_connect();
+
+ ret = SPI_exec(command, cnt);
+
+ proc = SPI_processed;
+
+ /*
+ * If some rows were fetched, print them via elog(INFO).
+ */
+ if (ret &gt; 0 &amp;&amp; SPI_tuptable != NULL)
+ {
+ SPITupleTable *tuptable = SPI_tuptable;
+ TupleDesc tupdesc = tuptable-&gt;tupdesc;
+ char buf[8192];
+ uint64 j;
+
+ for (j = 0; j &lt; tuptable-&gt;numvals; j++)
+ {
+ HeapTuple tuple = tuptable-&gt;vals[j];
+ int i;
+
+ for (i = 1, buf[0] = 0; i &lt;= tupdesc-&gt;natts; i++)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s%s",
+ SPI_getvalue(tuple, tupdesc, i),
+ (i == tupdesc-&gt;natts) ? " " : " |");
+ elog(INFO, "EXECQ: %s", buf);
+ }
+ }
+
+ SPI_finish();
+ pfree(command);
+
+ PG_RETURN_INT64(proc);
+}
+</programlisting>
+
+ <para>
+ This is how you declare the function after having compiled it into
+ a shared library (details are in <xref linkend="dfunc"/>.):
+
+<programlisting>
+CREATE FUNCTION execq(text, integer) RETURNS int8
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ Here is a sample session:
+
+<programlisting>
+=&gt; SELECT execq('CREATE TABLE a (x integer)', 0);
+ execq
+-------
+ 0
+(1 row)
+
+=&gt; INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
+INSERT 0 1
+=&gt; SELECT execq('SELECT * FROM a', 0);
+INFO: EXECQ: 0 <lineannotation>-- inserted by execq</lineannotation>
+INFO: EXECQ: 1 <lineannotation>-- returned by execq and inserted by upper INSERT</lineannotation>
+
+ execq
+-------
+ 2
+(1 row)
+
+=&gt; SELECT execq('INSERT INTO a SELECT x + 2 FROM a RETURNING *', 1);
+INFO: EXECQ: 2 <lineannotation>-- 0 + 2, then execution was stopped by count</lineannotation>
+ execq
+-------
+ 1
+(1 row)
+
+=&gt; SELECT execq('SELECT * FROM a', 10);
+INFO: EXECQ: 0
+INFO: EXECQ: 1
+INFO: EXECQ: 2
+
+ execq
+-------
+ 3 <lineannotation>-- 10 is the max value only, 3 is the real number of rows</lineannotation>
+(1 row)
+
+=&gt; SELECT execq('INSERT INTO a SELECT x + 10 FROM a', 1);
+ execq
+-------
+ 3 <lineannotation>-- all rows processed; count does not stop it, because nothing is returned</lineannotation>
+(1 row)
+
+=&gt; SELECT * FROM a;
+ x
+----
+ 0
+ 1
+ 2
+ 10
+ 11
+ 12
+(6 rows)
+
+=&gt; DELETE FROM a;
+DELETE 6
+=&gt; INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
+INSERT 0 1
+=&gt; SELECT * FROM a;
+ x
+---
+ 1 <lineannotation>-- 0 (no rows in a) + 1</lineannotation>
+(1 row)
+
+=&gt; INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
+INFO: EXECQ: 1
+INSERT 0 1
+=&gt; SELECT * FROM a;
+ x
+---
+ 1
+ 2 <lineannotation>-- 1 (there was one row in a) + 1</lineannotation>
+(2 rows)
+
+<lineannotation>-- This demonstrates the data changes visibility rule.</lineannotation>
+<lineannotation>-- execq is called twice and sees different numbers of rows each time:</lineannotation>
+
+=&gt; INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
+INFO: EXECQ: 1 <lineannotation>-- results from first execq</lineannotation>
+INFO: EXECQ: 2
+INFO: EXECQ: 1 <lineannotation>-- results from second execq</lineannotation>
+INFO: EXECQ: 2
+INFO: EXECQ: 2
+INSERT 0 2
+=&gt; SELECT * FROM a;
+ x
+---
+ 1
+ 2
+ 2 <lineannotation>-- 2 rows * 1 (x in first row)</lineannotation>
+ 6 <lineannotation>-- 3 rows (2 + 1 just inserted) * 2 (x in second row)</lineannotation>
+(4 rows)
+</programlisting>
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/sslinfo.sgml b/doc/src/sgml/sslinfo.sgml
new file mode 100644
index 0000000..2a9c45a
--- /dev/null
+++ b/doc/src/sgml/sslinfo.sgml
@@ -0,0 +1,263 @@
+<!-- doc/src/sgml/sslinfo.sgml -->
+
+<sect1 id="sslinfo" xreflabel="sslinfo">
+ <title>sslinfo</title>
+
+ <indexterm zone="sslinfo">
+ <primary>sslinfo</primary>
+ </indexterm>
+
+ <para>
+ The <filename>sslinfo</filename> module provides information about the SSL
+ certificate that the current client provided when connecting to
+ <productname>PostgreSQL</productname>. The module is useless (most functions
+ will return NULL) if the current connection does not use SSL.
+ </para>
+
+ <para>
+ Some of the information available through this module can also be obtained
+ using the built-in system view <link linkend="monitoring-pg-stat-ssl-view">
+ <structname>pg_stat_ssl</structname></link>.
+ </para>
+
+ <para>
+ This extension won't build at all unless the installation was
+ configured with <literal>--with-ssl=openssl</literal>.
+ </para>
+
+ <sect2>
+ <title>Functions Provided</title>
+
+ <variablelist>
+ <varlistentry>
+ <term>
+ <function>ssl_is_used() returns boolean</function>
+ <indexterm>
+ <primary>ssl_is_used</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns true if current connection to server uses SSL, and false
+ otherwise.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_version() returns text</function>
+ <indexterm>
+ <primary>ssl_version</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0,
+ TLSv1.1, TLSv1.2 or TLSv1.3).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_cipher() returns text</function>
+ <indexterm>
+ <primary>ssl_cipher</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns the name of the cipher used for the SSL connection
+ (e.g., DHE-RSA-AES256-SHA).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_client_cert_present() returns boolean</function>
+ <indexterm>
+ <primary>ssl_client_cert_present</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns true if current client has presented a valid SSL client
+ certificate to the server, and false otherwise. (The server
+ might or might not be configured to require a client certificate.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_client_serial() returns numeric</function>
+ <indexterm>
+ <primary>ssl_client_serial</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns serial number of current client certificate. The combination of
+ certificate serial number and certificate issuer is guaranteed to
+ uniquely identify a certificate (but not its owner &mdash; the owner
+ ought to regularly change their keys, and get new certificates from the
+ issuer).
+ </para>
+
+ <para>
+ So, if you run your own CA and allow only certificates from this CA to
+ be accepted by the server, the serial number is the most reliable (albeit
+ not very mnemonic) means to identify a user.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_client_dn() returns text</function>
+ <indexterm>
+ <primary>ssl_client_dn</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns the full subject of the current client certificate, converting
+ character data into the current database encoding. It is assumed that
+ if you use non-ASCII characters in the certificate names, your
+ database is able to represent these characters, too. If your database
+ uses the SQL_ASCII encoding, non-ASCII characters in the name will be
+ represented as UTF-8 sequences.
+ </para>
+
+ <para>
+ The result looks like <literal>/CN=Somebody /C=Some country/O=Some organization</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_issuer_dn() returns text</function>
+ <indexterm>
+ <primary>ssl_issuer_dn</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Returns the full issuer name of the current client certificate, converting
+ character data into the current database encoding. Encoding conversions
+ are handled the same as for <function>ssl_client_dn</function>.
+ </para>
+ <para>
+ The combination of the return value of this function with the
+ certificate serial number uniquely identifies the certificate.
+ </para>
+ <para>
+ This function is really useful only if you have more than one trusted CA
+ certificate in your server's certificate authority file, or if this CA
+ has issued some intermediate certificate authority certificates.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_client_dn_field(fieldname text) returns text</function>
+ <indexterm>
+ <primary>ssl_client_dn_field</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ This function returns the value of the specified field in the
+ certificate subject, or NULL if the field is not present.
+ Field names are string constants that are converted into ASN1 object
+ identifiers using the <productname>OpenSSL</productname> object
+ database. The following values are acceptable:
+ </para>
+<literallayout class="monospaced">
+commonName (alias CN)
+surname (alias SN)
+name
+givenName (alias GN)
+countryName (alias C)
+localityName (alias L)
+stateOrProvinceName (alias ST)
+organizationName (alias O)
+organizationalUnitName (alias OU)
+title
+description
+initials
+postalCode
+streetAddress
+generationQualifier
+description
+dnQualifier
+x500UniqueIdentifier
+pseudonym
+role
+emailAddress
+</literallayout>
+ <para>
+ All of these fields are optional, except <structfield>commonName</structfield>.
+ It depends
+ entirely on your CA's policy which of them would be included and which
+ wouldn't. The meaning of these fields, however, is strictly defined by
+ the X.500 and X.509 standards, so you cannot just assign arbitrary
+ meaning to them.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_issuer_field(fieldname text) returns text</function>
+ <indexterm>
+ <primary>ssl_issuer_field</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Same as <function>ssl_client_dn_field</function>, but for the certificate issuer
+ rather than the certificate subject.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <function>ssl_extension_info() returns setof record</function>
+ <indexterm>
+ <primary>ssl_extension_info</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Provide information about extensions of client certificate: extension name,
+ extension value, and if it is a critical extension.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Victor Wagner <email>vitus@cryptocom.ru</email>, Cryptocom LTD
+ </para>
+
+ <para>
+ Dmitry Voronin <email>carriingfate92@yandex.ru</email>
+ </para>
+
+ <para>
+ E-Mail of Cryptocom OpenSSL development group:
+ <email>openssl@cryptocom.ru</email>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/standalone-install.xml b/doc/src/sgml/standalone-install.xml
new file mode 100644
index 0000000..5cb3bb3
--- /dev/null
+++ b/doc/src/sgml/standalone-install.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+<!--
+This file contains the stand-alone installation instructions that end up in
+the INSTALL file. This document stitches together parts of the installation
+instructions in the main documentation with some material that only appears
+in the stand-alone version.
+-->
+<article id="installation">
+ <title><productname>PostgreSQL</productname> Installation from Source Code</title>
+
+ <!-- This text replaces the introductory text of installation.sgml -->
+ <para>
+ This document describes the installation of
+ <productname>PostgreSQL</productname> using this source code distribution.
+ </para>
+
+ <para>
+ If you are building <productname>PostgreSQL</productname> for Microsoft
+ Windows, read this document if you intend to build with MinGW or Cygwin;
+ but if you intend to build with Microsoft's <productname>Visual
+ C++</productname>, see the main documentation instead.
+ </para>
+
+ <xi:include href="postgres.sgml" xpointer="install-short" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="postgres.sgml" xpointer="install-requirements" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="postgres.sgml" xpointer="install-procedure" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="postgres.sgml" xpointer="install-post" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+ <sect1 id="install-getting-started">
+ <title>Getting Started</title>
+
+ <para>
+ The following is a quick summary of how to get <productname>PostgreSQL</productname> up and
+ running once installed. The main documentation contains more information.
+ </para>
+
+ <procedure>
+ <step>
+ <para>
+ Create a user account for the <productname>PostgreSQL</productname>
+ server. This is the user the server will run as. For production
+ use you should create a separate, unprivileged account
+ (<quote>postgres</quote> is commonly used). If you do not have root
+ access or just want to play around, your own user account is
+ enough, but running the server as root is a security risk and
+ will not work.
+<screen><userinput>adduser postgres</userinput></screen>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Create a database installation with the <command>initdb</command>
+ command. To run <command>initdb</command> you must be logged in to your
+ <productname>PostgreSQL</productname> server account. It will not work as
+ root.
+<screen>root# <userinput>mkdir /usr/local/pgsql/data</userinput>
+root# <userinput>chown postgres /usr/local/pgsql/data</userinput>
+root# <userinput>su - postgres</userinput>
+postgres$ <userinput>/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data</userinput></screen>
+ </para>
+
+ <para>
+ The <option>-D</option> option specifies the location where the data
+ will be stored. You can use any path you want, it does not have
+ to be under the installation directory. Just make sure that the
+ server account can write to the directory (or create it, if it
+ doesn't already exist) before starting <command>initdb</command>, as
+ illustrated here.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ At this point, if you did not use the <command>initdb</command> <literal>-A</literal>
+ option, you might want to modify <filename>pg_hba.conf</filename> to control
+ local access to the server before you start it. The default is to
+ trust all local users.
+ </para>
+ </step>
+
+ <step>
+ <para>
+ The previous <command>initdb</command> step should have told you how to
+ start up the database server. Do so now. The command should look
+ something like:
+<programlisting>/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data start</programlisting>
+ </para>
+
+ <para>
+ To stop a server running in the background you can type:
+<programlisting>/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data stop</programlisting>
+ </para>
+ </step>
+
+ <step>
+ <para>
+ Create a database:
+<screen><userinput>/usr/local/pgsql/bin/createdb testdb</userinput></screen>
+ Then enter:
+<screen><userinput>/usr/local/pgsql/bin/psql testdb</userinput></screen>
+ to connect to that database. At the prompt you can enter SQL
+ commands and start experimenting.
+ </para>
+ </step>
+ </procedure>
+ </sect1>
+
+ <sect1 id="install-whatnow">
+ <title>What Now?</title>
+
+ <para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <productname>PostgreSQL</productname> distribution contains a
+ comprehensive documentation set, which you should read sometime.
+ After installation, the documentation can be accessed by
+ pointing your browser to
+ <filename>/usr/local/pgsql/doc/html/index.html</filename>, unless you
+ changed the installation directories.
+ </para>
+
+ <para>
+ The first few chapters of the main documentation are the Tutorial,
+ which should be your first reading if you are completely new to
+ <acronym>SQL</acronym> databases. If you are familiar with database
+ concepts then you want to proceed with part on server
+ administration, which contains information about how to set up
+ the database server, database users, and authentication.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Usually, you will want to modify your computer so that it will
+ automatically start the database server whenever it boots. Some
+ suggestions for this are in the documentation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Run the regression tests against the installed server (using
+ <command>make installcheck</command>). If you didn't run the
+ tests before installation, you should definitely do it now. This
+ is also explained in the documentation.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ By default, <productname>PostgreSQL</productname> is configured to run on
+ minimal hardware. This allows it to start up with almost any
+ hardware configuration. The default configuration is, however,
+ not designed for optimum performance. To achieve optimum
+ performance, several server parameters must be adjusted, the two
+ most common being <varname>shared_buffers</varname> and
+ <varname>work_mem</varname>.
+ Other parameters mentioned in the documentation also affect
+ performance.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect1>
+
+ <xi:include href="postgres.sgml" xpointer="supported-platforms" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="postgres.sgml" xpointer="installation-platform-notes" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+</article>
diff --git a/doc/src/sgml/standalone-profile.xsl b/doc/src/sgml/standalone-profile.xsl
new file mode 100644
index 0000000..ea8a8f1
--- /dev/null
+++ b/doc/src/sgml/standalone-profile.xsl
@@ -0,0 +1,85 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+<!--
+This is a preprocessing layer to convert the installation instructions into a
+variant without links and references to the main documentation.
+
+- To omit something in the stand-alone INSTALL file, give the element a
+ condition="standalone-ignore" attribute.
+
+- If there is no element that exactly covers what you want to change, wrap it
+ in a <phrase> element, which otherwise does nothing.
+
+- Otherwise, write a custom rule below.
+-->
+
+<xsl:output
+ doctype-public="-//OASIS//DTD DocBook XML V4.5//EN"
+ doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"/>
+
+<!-- copy everything by default -->
+
+<xsl:template match="@*|node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|node()" />
+ </xsl:copy>
+</xsl:template>
+
+<!-- particular conversions -->
+
+<xsl:template match="*[@condition='standalone-ignore']">
+</xsl:template>
+
+<xsl:template match="phrase/text()['chapter']">
+ <xsl:text>document</xsl:text>
+</xsl:template>
+
+<xsl:template match="phrase[@id='install-ldap-links']">
+ <xsl:text>the documentation about client authentication and libpq</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='docguide-toolsets']">
+ <xsl:text>the main documentation's appendix on documentation</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='dynamic-trace']">
+ <xsl:text>the documentation</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='guc-default-toast-compression']">
+ <xsl:text>the configuration parameter default_toast_compression</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='guc-wal-compression']">
+ <xsl:text>the configuration parameter wal_compression</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='install-windows']">
+ <xsl:text>the documentation</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='plpython-python23']">
+ <xsl:text>the </xsl:text><application>PL/Python</application><xsl:text> documentation</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='regress']">
+ <xsl:text>the file </xsl:text>
+ <filename>src/test/regress/README</filename>
+ <xsl:text> and the documentation</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='upgrading']">
+ <xsl:text>the documentation</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='uuid-ossp']">
+ <xsl:text>uuid-ossp</xsl:text>
+</xsl:template>
+
+<xsl:template match="xref[@linkend='xml2']">
+ <xsl:text>xml2</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/start.sgml b/doc/src/sgml/start.sgml
new file mode 100644
index 0000000..f4ae1d0
--- /dev/null
+++ b/doc/src/sgml/start.sgml
@@ -0,0 +1,409 @@
+<!-- doc/src/sgml/start.sgml -->
+
+ <chapter id="tutorial-start">
+ <title>Getting Started</title>
+
+ <sect1 id="tutorial-install">
+ <title>Installation</title>
+
+ <para>
+ Before you can use <productname>PostgreSQL</productname> you need
+ to install it, of course. It is possible that
+ <productname>PostgreSQL</productname> is already installed at your
+ site, either because it was included in your operating system
+ distribution or because the system administrator already installed
+ it. If that is the case, you should obtain information from the
+ operating system documentation or your system administrator about
+ how to access <productname>PostgreSQL</productname>.
+ </para>
+
+ <para>
+ If you are not sure whether <productname>PostgreSQL</productname>
+ is already available or whether you can use it for your
+ experimentation then you can install it yourself. Doing so is not
+ hard and it can be a good exercise.
+ <productname>PostgreSQL</productname> can be installed by any
+ unprivileged user; no superuser (<systemitem>root</systemitem>)
+ access is required.
+ </para>
+
+ <para>
+ If you are installing <productname>PostgreSQL</productname>
+ yourself, then refer to <xref linkend="installation"/>
+ for instructions on installation, and return to
+ this guide when the installation is complete. Be sure to follow
+ closely the section about setting up the appropriate environment
+ variables.
+ </para>
+
+ <para>
+ If your site administrator has not set things up in the default
+ way, you might have some more work to do. For example, if the
+ database server machine is a remote machine, you will need to set
+ the <envar>PGHOST</envar> environment variable to the name of the
+ database server machine. The environment variable
+ <envar>PGPORT</envar> might also have to be set. The bottom line is
+ this: if you try to start an application program and it complains
+ that it cannot connect to the database, you should consult your
+ site administrator or, if that is you, the documentation to make
+ sure that your environment is properly set up. If you did not
+ understand the preceding paragraph then read the next section.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-arch">
+ <title>Architectural Fundamentals</title>
+
+ <para>
+ Before we proceed, you should understand the basic
+ <productname>PostgreSQL</productname> system architecture.
+ Understanding how the parts of
+ <productname>PostgreSQL</productname> interact will make this
+ chapter somewhat clearer.
+ </para>
+
+ <para>
+ In database jargon, <productname>PostgreSQL</productname> uses a
+ client/server model. A <productname>PostgreSQL</productname>
+ session consists of the following cooperating processes
+ (programs):
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A server process, which manages the database files, accepts
+ connections to the database from client applications, and
+ performs database actions on behalf of the clients. The
+ database server program is called
+ <filename>postgres</filename>.
+ <indexterm><primary>postgres</primary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The user's client (frontend) application that wants to perform
+ database operations. Client applications can be very diverse
+ in nature: a client could be a text-oriented tool, a graphical
+ application, a web server that accesses the database to
+ display web pages, or a specialized database maintenance tool.
+ Some client applications are supplied with the
+ <productname>PostgreSQL</productname> distribution; most are
+ developed by users.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ As is typical of client/server applications, the client and the
+ server can be on different hosts. In that case they communicate
+ over a TCP/IP network connection. You should keep this in mind,
+ because the files that can be accessed on a client machine might
+ not be accessible (or might only be accessible using a different
+ file name) on the database server machine.
+ </para>
+
+ <para>
+ The <productname>PostgreSQL</productname> server can handle
+ multiple concurrent connections from clients. To achieve this it
+ starts (<quote>forks</quote>) a new process for each connection.
+ From that point on, the client and the new server process
+ communicate without intervention by the original
+ <filename>postgres</filename> process. Thus, the
+ supervisor server process is always running, waiting for
+ client connections, whereas client and associated server processes
+ come and go. (All of this is of course invisible to the user. We
+ only mention it here for completeness.)
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-createdb">
+ <title>Creating a Database</title>
+
+ <indexterm zone="tutorial-createdb">
+ <primary>database</primary>
+ <secondary>creating</secondary>
+ </indexterm>
+
+ <indexterm zone="tutorial-createdb">
+ <primary>createdb</primary>
+ </indexterm>
+
+ <para>
+ The first test to see whether you can access the database server
+ is to try to create a database. A running
+ <productname>PostgreSQL</productname> server can manage many
+ databases. Typically, a separate database is used for each
+ project or for each user.
+ </para>
+
+ <para>
+ Possibly, your site administrator has already created a database
+ for your use. In that case you can omit this step and skip ahead
+ to the next section.
+ </para>
+
+ <para>
+ To create a new database, in this example named
+ <literal>mydb</literal>, you use the following command:
+<screen>
+<prompt>$</prompt> <userinput>createdb mydb</userinput>
+</screen>
+ If this produces no response then this step was successful and you can skip over the
+ remainder of this section.
+ </para>
+
+ <para>
+ If you see a message similar to:
+<screen>
+createdb: command not found
+</screen>
+ then <productname>PostgreSQL</productname> was not installed properly. Either it was not
+ installed at all or your shell's search path was not set to include it.
+ Try calling the command with an absolute path instead:
+<screen>
+<prompt>$</prompt> <userinput>/usr/local/pgsql/bin/createdb mydb</userinput>
+</screen>
+ The path at your site might be different. Contact your site
+ administrator or check the installation instructions to
+ correct the situation.
+ </para>
+
+ <para>
+ Another response could be this:
+<screen>
+createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
+ Is the server running locally and accepting connections on that socket?
+</screen>
+ This means that the server was not started, or it is not listening
+ where <command>createdb</command> expects to contact it. Again, check the
+ installation instructions or consult the administrator.
+ </para>
+
+ <para>
+ Another response could be this:
+<screen>
+createdb: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: FATAL: role "joe" does not exist
+</screen>
+ where your own login name is mentioned. This will happen if the
+ administrator has not created a <productname>PostgreSQL</productname> user account
+ for you. (<productname>PostgreSQL</productname> user accounts are distinct from
+ operating system user accounts.) If you are the administrator, see
+ <xref linkend="user-manag"/> for help creating accounts. You will need to
+ become the operating system user under which <productname>PostgreSQL</productname>
+ was installed (usually <literal>postgres</literal>) to create the first user
+ account. It could also be that you were assigned a
+ <productname>PostgreSQL</productname> user name that is different from your
+ operating system user name; in that case you need to use the <option>-U</option>
+ switch or set the <envar>PGUSER</envar> environment variable to specify your
+ <productname>PostgreSQL</productname> user name.
+ </para>
+
+ <para>
+ If you have a user account but it does not have the privileges required to
+ create a database, you will see the following:
+<screen>
+createdb: error: database creation failed: ERROR: permission denied to create database
+</screen>
+ Not every user has authorization to create new databases. If
+ <productname>PostgreSQL</productname> refuses to create databases
+ for you then the site administrator needs to grant you permission
+ to create databases. Consult your site administrator if this
+ occurs. If you installed <productname>PostgreSQL</productname>
+ yourself then you should log in for the purposes of this tutorial
+ under the user account that you started the server as.
+
+ <footnote>
+ <para>
+ As an explanation for why this works:
+ <productname>PostgreSQL</productname> user names are separate
+ from operating system user accounts. When you connect to a
+ database, you can choose what
+ <productname>PostgreSQL</productname> user name to connect as;
+ if you don't, it will default to the same name as your current
+ operating system account. As it happens, there will always be a
+ <productname>PostgreSQL</productname> user account that has the
+ same name as the operating system user that started the server,
+ and it also happens that that user always has permission to
+ create databases. Instead of logging in as that user you can
+ also specify the <option>-U</option> option everywhere to select
+ a <productname>PostgreSQL</productname> user name to connect as.
+ </para>
+ </footnote>
+ </para>
+
+ <para>
+ You can also create databases with other names.
+ <productname>PostgreSQL</productname> allows you to create any
+ number of databases at a given site. Database names must have an
+ alphabetic first character and are limited to 63 bytes in
+ length. A convenient choice is to create a database with the same
+ name as your current user name. Many tools assume that database
+ name as the default, so it can save you some typing. To create
+ that database, simply type:
+<screen>
+<prompt>$</prompt> <userinput>createdb</userinput>
+</screen>
+ </para>
+
+ <para>
+ If you do not want to use your database anymore you can remove it.
+ For example, if you are the owner (creator) of the database
+ <literal>mydb</literal>, you can destroy it using the following
+ command:
+<screen>
+<prompt>$</prompt> <userinput>dropdb mydb</userinput>
+</screen>
+ (For this command, the database name does not default to the user
+ account name. You always need to specify it.) This action
+ physically removes all files associated with the database and
+ cannot be undone, so this should only be done with a great deal of
+ forethought.
+ </para>
+
+ <para>
+ More about <command>createdb</command> and <command>dropdb</command> can
+ be found in <xref linkend="app-createdb"/> and <xref linkend="app-dropdb"/>
+ respectively.
+ </para>
+ </sect1>
+
+
+ <sect1 id="tutorial-accessdb">
+ <title>Accessing a Database</title>
+
+ <indexterm zone="tutorial-accessdb">
+ <primary>psql</primary>
+ </indexterm>
+
+ <para>
+ Once you have created a database, you can access it by:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ Running the <productname>PostgreSQL</productname> interactive
+ terminal program, called <application><firstterm>psql</firstterm></application>, which allows you
+ to interactively enter, edit, and execute
+ <acronym>SQL</acronym> commands.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Using an existing graphical frontend tool like
+ <application>pgAdmin</application> or an office suite with
+ <acronym>ODBC</acronym> or <acronym>JDBC</acronym> support to create and manipulate a
+ database. These possibilities are not covered in this
+ tutorial.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Writing a custom application, using one of the several
+ available language bindings. These possibilities are discussed
+ further in <xref linkend="client-interfaces"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ You probably want to start up <command>psql</command> to try
+ the examples in this tutorial. It can be activated for the
+ <literal>mydb</literal> database by typing the command:
+<screen>
+<prompt>$</prompt> <userinput>psql mydb</userinput>
+</screen>
+ If you do not supply the database name then it will default to your
+ user account name. You already discovered this scheme in the
+ previous section using <command>createdb</command>.
+ </para>
+
+ <para>
+ In <command>psql</command>, you will be greeted with the following
+ message:
+<screen>
+psql (&version;)
+Type "help" for help.
+
+mydb=&gt;
+</screen>
+ <indexterm><primary>superuser</primary></indexterm>
+ The last line could also be:
+<screen>
+mydb=#
+</screen>
+ That would mean you are a database superuser, which is most likely
+ the case if you installed the <productname>PostgreSQL</productname> instance
+ yourself. Being a superuser means that you are not subject to
+ access controls. For the purposes of this tutorial that is not
+ important.
+ </para>
+
+ <para>
+ If you encounter problems starting <command>psql</command>
+ then go back to the previous section. The diagnostics of
+ <command>createdb</command> and <command>psql</command> are
+ similar, and if the former worked the latter should work as well.
+ </para>
+
+ <para>
+ The last line printed out by <command>psql</command> is the
+ prompt, and it indicates that <command>psql</command> is listening
+ to you and that you can type <acronym>SQL</acronym> queries into a
+ work space maintained by <command>psql</command>. Try out these
+ commands:
+ <indexterm><primary>version</primary></indexterm>
+<screen>
+<prompt>mydb=&gt;</prompt> <userinput>SELECT version();</userinput>
+ version
+-------------------------------------------------------------------&zwsp;-----------------------
+ PostgreSQL &version; on x86_64-pc-linux-gnu, compiled by gcc (Debian 4.9.2-10) 4.9.2, 64-bit
+(1 row)
+
+<prompt>mydb=&gt;</prompt> <userinput>SELECT current_date;</userinput>
+ date
+------------
+ 2016-01-07
+(1 row)
+
+<prompt>mydb=&gt;</prompt> <userinput>SELECT 2 + 2;</userinput>
+ ?column?
+----------
+ 4
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ The <command>psql</command> program has a number of internal
+ commands that are not SQL commands. They begin with the backslash
+ character, <quote><literal>\</literal></quote>.
+ For example,
+ you can get help on the syntax of various
+ <productname>PostgreSQL</productname> <acronym>SQL</acronym>
+ commands by typing:
+<screen>
+<prompt>mydb=&gt;</prompt> <userinput>\h</userinput>
+</screen>
+ </para>
+
+ <para>
+ To get out of <command>psql</command>, type:
+<screen>
+<prompt>mydb=&gt;</prompt> <userinput>\q</userinput>
+</screen>
+ and <command>psql</command> will quit and return you to your
+ command shell. (For more internal commands, type
+ <literal>\?</literal> at the <command>psql</command> prompt.) The
+ full capabilities of <command>psql</command> are documented in
+ <xref linkend="app-psql"/>. In this tutorial we will not use these
+ features explicitly, but you can use them yourself when it is helpful.
+ </para>
+
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml
new file mode 100644
index 0000000..148fb1b
--- /dev/null
+++ b/doc/src/sgml/storage.sgml
@@ -0,0 +1,1148 @@
+<!-- doc/src/sgml/storage.sgml -->
+
+<chapter id="storage">
+
+<title>Database Physical Storage</title>
+
+<para>
+This chapter provides an overview of the physical storage format used by
+<productname>PostgreSQL</productname> databases.
+</para>
+
+<sect1 id="storage-file-layout">
+
+<title>Database File Layout</title>
+
+<para>
+This section describes the storage format at the level of files and
+directories.
+</para>
+
+<para>
+Traditionally, the configuration and data files used by a database
+cluster are stored together within the cluster's data
+directory, commonly referred to as <varname>PGDATA</varname> (after the name of the
+environment variable that can be used to define it). A common location for
+<varname>PGDATA</varname> is <filename>/var/lib/pgsql/data</filename>. Multiple clusters,
+managed by different server instances, can exist on the same machine.
+</para>
+
+<para>
+The <varname>PGDATA</varname> directory contains several subdirectories and control
+files, as shown in <xref linkend="pgdata-contents-table"/>. In addition to
+these required items, the cluster configuration files
+<filename>postgresql.conf</filename>, <filename>pg_hba.conf</filename>, and
+<filename>pg_ident.conf</filename> are traditionally stored in
+<varname>PGDATA</varname>, although it is possible to place them elsewhere.
+</para>
+
+<table tocentry="1" id="pgdata-contents-table">
+<title>Contents of <varname>PGDATA</varname></title>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>
+Item
+</entry>
+<entry>Description</entry>
+</row>
+</thead>
+
+<tbody>
+
+<row>
+ <entry><filename>PG_VERSION</filename></entry>
+ <entry>A file containing the major version number of <productname>PostgreSQL</productname></entry>
+</row>
+
+<row>
+ <entry><filename>base</filename></entry>
+ <entry>Subdirectory containing per-database subdirectories</entry>
+</row>
+
+<row>
+ <entry><filename>current_logfiles</filename></entry>
+ <entry>File recording the log file(s) currently written to by the logging
+ collector</entry>
+</row>
+
+<row>
+ <entry><filename>global</filename></entry>
+ <entry>Subdirectory containing cluster-wide tables, such as
+ <structname>pg_database</structname></entry>
+</row>
+
+<row>
+ <entry><filename>pg_commit_ts</filename></entry>
+ <entry>Subdirectory containing transaction commit timestamp data</entry>
+</row>
+
+<row>
+ <entry><filename>pg_dynshmem</filename></entry>
+ <entry>Subdirectory containing files used by the dynamic shared memory
+ subsystem</entry>
+</row>
+
+<row>
+ <entry><filename>pg_logical</filename></entry>
+ <entry>Subdirectory containing status data for logical decoding</entry>
+</row>
+
+<row>
+ <entry><filename>pg_multixact</filename></entry>
+ <entry>Subdirectory containing multitransaction status data
+ (used for shared row locks)</entry>
+</row>
+
+<row>
+ <entry><filename>pg_notify</filename></entry>
+ <entry>Subdirectory containing LISTEN/NOTIFY status data</entry>
+</row>
+
+<row>
+ <entry><filename>pg_replslot</filename></entry>
+ <entry>Subdirectory containing replication slot data</entry>
+</row>
+
+<row>
+ <entry><filename>pg_serial</filename></entry>
+ <entry>Subdirectory containing information about committed serializable transactions</entry>
+</row>
+
+<row>
+ <entry><filename>pg_snapshots</filename></entry>
+ <entry>Subdirectory containing exported snapshots</entry>
+</row>
+
+<row>
+ <entry><filename>pg_stat</filename></entry>
+ <entry>Subdirectory containing permanent files for the statistics
+ subsystem</entry>
+</row>
+
+<row>
+ <entry><filename>pg_stat_tmp</filename></entry>
+ <entry>Subdirectory containing temporary files for the statistics
+ subsystem</entry>
+</row>
+
+<row>
+ <entry><filename>pg_subtrans</filename></entry>
+ <entry>Subdirectory containing subtransaction status data</entry>
+</row>
+
+<row>
+ <entry><filename>pg_tblspc</filename></entry>
+ <entry>Subdirectory containing symbolic links to tablespaces</entry>
+</row>
+
+<row>
+ <entry><filename>pg_twophase</filename></entry>
+ <entry>Subdirectory containing state files for prepared transactions</entry>
+</row>
+
+<row>
+ <entry><filename>pg_wal</filename></entry>
+ <entry>Subdirectory containing WAL (Write Ahead Log) files</entry>
+</row>
+
+<row>
+ <entry><filename>pg_xact</filename></entry>
+ <entry>Subdirectory containing transaction commit status data</entry>
+</row>
+
+<row>
+ <entry><filename>postgresql.auto.conf</filename></entry>
+ <entry>A file used for storing configuration parameters that are set by
+<command>ALTER SYSTEM</command></entry>
+</row>
+
+<row>
+ <entry><filename>postmaster.opts</filename></entry>
+ <entry>A file recording the command-line options the server was
+last started with</entry>
+</row>
+
+<row>
+ <entry><filename>postmaster.pid</filename></entry>
+ <entry>A lock file recording the current postmaster process ID (PID),
+ cluster data directory path,
+ postmaster start timestamp,
+ port number,
+ Unix-domain socket directory path (could be empty),
+ first valid listen_address (IP address or <literal>*</literal>, or empty if
+ not listening on TCP),
+ and shared memory segment ID
+ (this file is not present after server shutdown)</entry>
+</row>
+
+</tbody>
+</tgroup>
+</table>
+
+<para>
+For each database in the cluster there is a subdirectory within
+<varname>PGDATA</varname><filename>/base</filename>, named after the database's OID in
+<structname>pg_database</structname>. This subdirectory is the default location
+for the database's files; in particular, its system catalogs are stored
+there.
+</para>
+
+<para>
+ Note that the following sections describe the behavior of the builtin
+ <literal>heap</literal> <link linkend="tableam">table access method</link>,
+ and the builtin <link linkend="indexam">index access methods</link>. Due
+ to the extensible nature of <productname>PostgreSQL</productname>, other
+ access methods might work differently.
+</para>
+
+<para>
+Each table and index is stored in a separate file. For ordinary relations,
+these files are named after the table or index's <firstterm>filenode</firstterm> number,
+which can be found in <structname>pg_class</structname>.<structfield>relfilenode</structfield>. But
+for temporary relations, the file name is of the form
+<literal>t<replaceable>BBB</replaceable>_<replaceable>FFF</replaceable></literal>, where <replaceable>BBB</replaceable>
+is the backend ID of the backend which created the file, and <replaceable>FFF</replaceable>
+is the filenode number. In either case, in addition to the main file (a/k/a
+main fork), each table and index has a <firstterm>free space map</firstterm> (see <xref
+linkend="storage-fsm"/>), which stores information about free space available in
+the relation. The free space map is stored in a file named with the filenode
+number plus the suffix <literal>_fsm</literal>. Tables also have a
+<firstterm>visibility map</firstterm>, stored in a fork with the suffix <literal>_vm</literal>,
+to track which pages are known to have no dead tuples. The visibility map is
+described further in <xref linkend="storage-vm"/>. Unlogged tables and indexes
+have a third fork, known as the initialization fork, which is stored in a fork
+with the suffix <literal>_init</literal> (see <xref linkend="storage-init"/>).
+</para>
+
+<caution>
+<para>
+Note that while a table's filenode often matches its OID, this is
+<emphasis>not</emphasis> necessarily the case; some operations, like
+<command>TRUNCATE</command>, <command>REINDEX</command>, <command>CLUSTER</command> and some forms
+of <command>ALTER TABLE</command>, can change the filenode while preserving the OID.
+Avoid assuming that filenode and table OID are the same.
+Also, for certain system catalogs including <structname>pg_class</structname> itself,
+<structname>pg_class</structname>.<structfield>relfilenode</structfield> contains zero. The
+actual filenode number of these catalogs is stored in a lower-level data
+structure, and can be obtained using the <function>pg_relation_filenode()</function>
+function.
+</para>
+</caution>
+
+<para>
+When a table or index exceeds 1 GB, it is divided into gigabyte-sized
+<firstterm>segments</firstterm>. The first segment's file name is the same as the
+filenode; subsequent segments are named filenode.1, filenode.2, etc.
+This arrangement avoids problems on platforms that have file size limitations.
+(Actually, 1 GB is just the default segment size. The segment size can be
+adjusted using the configuration option <option>--with-segsize</option>
+when building <productname>PostgreSQL</productname>.)
+In principle, free space map and visibility map forks could require multiple
+segments as well, though this is unlikely to happen in practice.
+</para>
+
+<para>
+A table that has columns with potentially large entries will have an
+associated <firstterm>TOAST</firstterm> table, which is used for out-of-line storage of
+field values that are too large to keep in the table rows proper.
+<structname>pg_class</structname>.<structfield>reltoastrelid</structfield> links from a table to
+its <acronym>TOAST</acronym> table, if any.
+See <xref linkend="storage-toast"/> for more information.
+</para>
+
+<para>
+The contents of tables and indexes are discussed further in
+<xref linkend="storage-page-layout"/>.
+</para>
+
+<para>
+Tablespaces make the scenario more complicated. Each user-defined tablespace
+has a symbolic link inside the <varname>PGDATA</varname><filename>/pg_tblspc</filename>
+directory, which points to the physical tablespace directory (i.e., the
+location specified in the tablespace's <command>CREATE TABLESPACE</command> command).
+This symbolic link is named after
+the tablespace's OID. Inside the physical tablespace directory there is
+a subdirectory with a name that depends on the <productname>PostgreSQL</productname>
+server version, such as <literal>PG_9.0_201008051</literal>. (The reason for using
+this subdirectory is so that successive versions of the database can use
+the same <command>CREATE TABLESPACE</command> location value without conflicts.)
+Within the version-specific subdirectory, there is
+a subdirectory for each database that has elements in the tablespace, named
+after the database's OID. Tables and indexes are stored within that
+directory, using the filenode naming scheme.
+The <literal>pg_default</literal> tablespace is not accessed through
+<filename>pg_tblspc</filename>, but corresponds to
+<varname>PGDATA</varname><filename>/base</filename>. Similarly, the <literal>pg_global</literal>
+tablespace is not accessed through <filename>pg_tblspc</filename>, but corresponds to
+<varname>PGDATA</varname><filename>/global</filename>.
+</para>
+
+<para>
+The <function>pg_relation_filepath()</function> function shows the entire path
+(relative to <varname>PGDATA</varname>) of any relation. It is often useful
+as a substitute for remembering many of the above rules. But keep in
+mind that this function just gives the name of the first segment of the
+main fork of the relation &mdash; you may need to append a segment number
+and/or <literal>_fsm</literal>, <literal>_vm</literal>, or <literal>_init</literal> to find all
+the files associated with the relation.
+</para>
+
+<para>
+Temporary files (for operations such as sorting more data than can fit in
+memory) are created within <varname>PGDATA</varname><filename>/base/pgsql_tmp</filename>,
+or within a <filename>pgsql_tmp</filename> subdirectory of a tablespace directory
+if a tablespace other than <literal>pg_default</literal> is specified for them.
+The name of a temporary file has the form
+<filename>pgsql_tmp<replaceable>PPP</replaceable>.<replaceable>NNN</replaceable></filename>,
+where <replaceable>PPP</replaceable> is the PID of the owning backend and
+<replaceable>NNN</replaceable> distinguishes different temporary files of that backend.
+</para>
+
+</sect1>
+
+<sect1 id="storage-toast">
+
+<title>TOAST</title>
+
+ <indexterm>
+ <primary>TOAST</primary>
+ </indexterm>
+ <indexterm><primary>sliced bread</primary><see>TOAST</see></indexterm>
+
+<para>
+This section provides an overview of <acronym>TOAST</acronym> (The
+Oversized-Attribute Storage Technique).
+</para>
+
+<para>
+<productname>PostgreSQL</productname> uses a fixed page size (commonly
+8 kB), and does not allow tuples to span multiple pages. Therefore, it is
+not possible to store very large field values directly. To overcome
+this limitation, large field values are compressed and/or broken up into
+multiple physical rows. This happens transparently to the user, with only
+small impact on most of the backend code. The technique is affectionately
+known as <acronym>TOAST</acronym> (or <quote>the best thing since sliced bread</quote>).
+The <acronym>TOAST</acronym> infrastructure is also used to improve handling of
+large data values in-memory.
+</para>
+
+<para>
+Only certain data types support <acronym>TOAST</acronym> &mdash; there is no need to
+impose the overhead on data types that cannot produce large field values.
+To support <acronym>TOAST</acronym>, a data type must have a variable-length
+(<firstterm>varlena</firstterm>) representation, in which, ordinarily, the first
+four-byte word of any stored value contains the total length of the value in
+bytes (including itself). <acronym>TOAST</acronym> does not constrain the rest
+of the data type's representation. The special representations collectively
+called <firstterm><acronym>TOAST</acronym>ed values</firstterm> work by modifying or
+reinterpreting this initial length word. Therefore, the C-level functions
+supporting a <acronym>TOAST</acronym>-able data type must be careful about how they
+handle potentially <acronym>TOAST</acronym>ed input values: an input might not
+actually consist of a four-byte length word and contents until after it's
+been <firstterm>detoasted</firstterm>. (This is normally done by invoking
+<function>PG_DETOAST_DATUM</function> before doing anything with an input value,
+but in some cases more efficient approaches are possible.
+See <xref linkend="xtypes-toast"/> for more detail.)
+</para>
+
+<para>
+<acronym>TOAST</acronym> usurps two bits of the varlena length word (the high-order
+bits on big-endian machines, the low-order bits on little-endian machines),
+thereby limiting the logical size of any value of a <acronym>TOAST</acronym>-able
+data type to 1 GB (2<superscript>30</superscript> - 1 bytes). When both bits are zero,
+the value is an ordinary un-<acronym>TOAST</acronym>ed value of the data type, and
+the remaining bits of the length word give the total datum size (including
+length word) in bytes. When the highest-order or lowest-order bit is set,
+the value has only a single-byte header instead of the normal four-byte
+header, and the remaining bits of that byte give the total datum size
+(including length byte) in bytes. This alternative supports space-efficient
+storage of values shorter than 127 bytes, while still allowing the data type
+to grow to 1 GB at need. Values with single-byte headers aren't aligned on
+any particular boundary, whereas values with four-byte headers are aligned on
+at least a four-byte boundary; this omission of alignment padding provides
+additional space savings that is significant compared to short values.
+As a special case, if the remaining bits of a single-byte header are all
+zero (which would be impossible for a self-inclusive length), the value is
+a pointer to out-of-line data, with several possible alternatives as
+described below. The type and size of such a <firstterm>TOAST pointer</firstterm>
+are determined by a code stored in the second byte of the datum.
+Lastly, when the highest-order or lowest-order bit is clear but the adjacent
+bit is set, the content of the datum has been compressed and must be
+decompressed before use. In this case the remaining bits of the four-byte
+length word give the total size of the compressed datum, not the
+original data. Note that compression is also possible for out-of-line data
+but the varlena header does not tell whether it has occurred &mdash;
+the content of the <acronym>TOAST</acronym> pointer tells that, instead.
+</para>
+
+<para>
+The compression technique used for either in-line or out-of-line compressed
+data can be selected for each column by setting
+the <literal>COMPRESSION</literal> column option in <command>CREATE
+TABLE</command> or <command>ALTER TABLE</command>. The default for columns
+with no explicit setting is to consult the
+<xref linkend="guc-default-toast-compression"/> parameter at the time data is
+inserted.
+</para>
+
+<para>
+As mentioned, there are multiple types of <acronym>TOAST</acronym> pointer datums.
+The oldest and most common type is a pointer to out-of-line data stored in
+a <firstterm><acronym>TOAST</acronym> table</firstterm> that is separate from, but
+associated with, the table containing the <acronym>TOAST</acronym> pointer datum
+itself. These <firstterm>on-disk</firstterm> pointer datums are created by the
+<acronym>TOAST</acronym> management code (in <filename>access/common/toast_internals.c</filename>)
+when a tuple to be stored on disk is too large to be stored as-is.
+Further details appear in <xref linkend="storage-toast-ondisk"/>.
+Alternatively, a <acronym>TOAST</acronym> pointer datum can contain a pointer to
+out-of-line data that appears elsewhere in memory. Such datums are
+necessarily short-lived, and will never appear on-disk, but they are very
+useful for avoiding copying and redundant processing of large data values.
+Further details appear in <xref linkend="storage-toast-inmemory"/>.
+</para>
+
+<sect2 id="storage-toast-ondisk">
+ <title>Out-of-Line, On-Disk TOAST Storage</title>
+
+<para>
+If any of the columns of a table are <acronym>TOAST</acronym>-able, the table will
+have an associated <acronym>TOAST</acronym> table, whose OID is stored in the table's
+<structname>pg_class</structname>.<structfield>reltoastrelid</structfield> entry. On-disk
+<acronym>TOAST</acronym>ed values are kept in the <acronym>TOAST</acronym> table, as
+described in more detail below.
+</para>
+
+<para>
+Out-of-line values are divided (after compression if used) into chunks of at
+most <symbol>TOAST_MAX_CHUNK_SIZE</symbol> bytes (by default this value is chosen
+so that four chunk rows will fit on a page, making it about 2000 bytes).
+Each chunk is stored as a separate row in the <acronym>TOAST</acronym> table
+belonging to the owning table. Every
+<acronym>TOAST</acronym> table has the columns <structfield>chunk_id</structfield> (an OID
+identifying the particular <acronym>TOAST</acronym>ed value),
+<structfield>chunk_seq</structfield> (a sequence number for the chunk within its value),
+and <structfield>chunk_data</structfield> (the actual data of the chunk). A unique index
+on <structfield>chunk_id</structfield> and <structfield>chunk_seq</structfield> provides fast
+retrieval of the values. A pointer datum representing an out-of-line on-disk
+<acronym>TOAST</acronym>ed value therefore needs to store the OID of the
+<acronym>TOAST</acronym> table in which to look and the OID of the specific value
+(its <structfield>chunk_id</structfield>). For convenience, pointer datums also store the
+logical datum size (original uncompressed data length), physical stored size
+(different if compression was applied), and the compression method used, if
+any. Allowing for the varlena header bytes,
+the total size of an on-disk <acronym>TOAST</acronym> pointer datum is therefore 18
+bytes regardless of the actual size of the represented value.
+</para>
+
+<para>
+The <acronym>TOAST</acronym> management code is triggered only
+when a row value to be stored in a table is wider than
+<symbol>TOAST_TUPLE_THRESHOLD</symbol> bytes (normally 2 kB).
+The <acronym>TOAST</acronym> code will compress and/or move
+field values out-of-line until the row value is shorter than
+<symbol>TOAST_TUPLE_TARGET</symbol> bytes (also normally 2 kB, adjustable)
+or no more gains can be had. During an UPDATE
+operation, values of unchanged fields are normally preserved as-is; so an
+UPDATE of a row with out-of-line values incurs no <acronym>TOAST</acronym> costs if
+none of the out-of-line values change.
+</para>
+
+<para>
+The <acronym>TOAST</acronym> management code recognizes four different strategies
+for storing <acronym>TOAST</acronym>-able columns on disk:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>PLAIN</literal> prevents either compression or
+ out-of-line storage; furthermore it disables use of single-byte headers
+ for varlena types.
+ This is the only possible strategy for
+ columns of non-<acronym>TOAST</acronym>-able data types.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>EXTENDED</literal> allows both compression and out-of-line
+ storage. This is the default for most <acronym>TOAST</acronym>-able data types.
+ Compression will be attempted first, then out-of-line storage if
+ the row is still too big.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>EXTERNAL</literal> allows out-of-line storage but not
+ compression. Use of <literal>EXTERNAL</literal> will
+ make substring operations on wide <type>text</type> and
+ <type>bytea</type> columns faster (at the penalty of increased storage
+ space) because these operations are optimized to fetch only the
+ required parts of the out-of-line value when it is not compressed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>MAIN</literal> allows compression but not out-of-line
+ storage. (Actually, out-of-line storage will still be performed
+ for such columns, but only as a last resort when there is no other
+ way to make the row small enough to fit on a page.)
+ </para>
+ </listitem>
+ </itemizedlist>
+
+Each <acronym>TOAST</acronym>-able data type specifies a default strategy for columns
+of that data type, but the strategy for a given table column can be altered
+with <link linkend="sql-altertable"><command>ALTER TABLE ... SET STORAGE</command></link>.
+</para>
+
+<para>
+<symbol>TOAST_TUPLE_TARGET</symbol> can be adjusted for each table using
+<link linkend="sql-altertable"><command>ALTER TABLE ... SET (toast_tuple_target = N)</command></link>
+</para>
+
+<para>
+This scheme has a number of advantages compared to a more straightforward
+approach such as allowing row values to span pages. Assuming that queries are
+usually qualified by comparisons against relatively small key values, most of
+the work of the executor will be done using the main row entry. The big values
+of <acronym>TOAST</acronym>ed attributes will only be pulled out (if selected at all)
+at the time the result set is sent to the client. Thus, the main table is much
+smaller and more of its rows fit in the shared buffer cache than would be the
+case without any out-of-line storage. Sort sets shrink also, and sorts will
+more often be done entirely in memory. A little test showed that a table
+containing typical HTML pages and their URLs was stored in about half of the
+raw data size including the <acronym>TOAST</acronym> table, and that the main table
+contained only about 10% of the entire data (the URLs and some small HTML
+pages). There was no run time difference compared to an un-<acronym>TOAST</acronym>ed
+comparison table, in which all the HTML pages were cut down to 7 kB to fit.
+</para>
+
+</sect2>
+
+<sect2 id="storage-toast-inmemory">
+ <title>Out-of-Line, In-Memory TOAST Storage</title>
+
+<para>
+<acronym>TOAST</acronym> pointers can point to data that is not on disk, but is
+elsewhere in the memory of the current server process. Such pointers
+obviously cannot be long-lived, but they are nonetheless useful. There
+are currently two sub-cases:
+pointers to <firstterm>indirect</firstterm> data and
+pointers to <firstterm>expanded</firstterm> data.
+</para>
+
+<para>
+Indirect <acronym>TOAST</acronym> pointers simply point at a non-indirect varlena
+value stored somewhere in memory. This case was originally created merely
+as a proof of concept, but it is currently used during logical decoding to
+avoid possibly having to create physical tuples exceeding 1 GB (as pulling
+all out-of-line field values into the tuple might do). The case is of
+limited use since the creator of the pointer datum is entirely responsible
+that the referenced data survives for as long as the pointer could exist,
+and there is no infrastructure to help with this.
+</para>
+
+<para>
+Expanded <acronym>TOAST</acronym> pointers are useful for complex data types
+whose on-disk representation is not especially suited for computational
+purposes. As an example, the standard varlena representation of a
+<productname>PostgreSQL</productname> array includes dimensionality information, a
+nulls bitmap if there are any null elements, then the values of all the
+elements in order. When the element type itself is variable-length, the
+only way to find the <replaceable>N</replaceable>'th element is to scan through all the
+preceding elements. This representation is appropriate for on-disk storage
+because of its compactness, but for computations with the array it's much
+nicer to have an <quote>expanded</quote> or <quote>deconstructed</quote>
+representation in which all the element starting locations have been
+identified. The <acronym>TOAST</acronym> pointer mechanism supports this need by
+allowing a pass-by-reference Datum to point to either a standard varlena
+value (the on-disk representation) or a <acronym>TOAST</acronym> pointer that
+points to an expanded representation somewhere in memory. The details of
+this expanded representation are up to the data type, though it must have
+a standard header and meet the other API requirements given
+in <filename>src/include/utils/expandeddatum.h</filename>. C-level functions
+working with the data type can choose to handle either representation.
+Functions that do not know about the expanded representation, but simply
+apply <function>PG_DETOAST_DATUM</function> to their inputs, will automatically
+receive the traditional varlena representation; so support for an expanded
+representation can be introduced incrementally, one function at a time.
+</para>
+
+<para>
+<acronym>TOAST</acronym> pointers to expanded values are further broken down
+into <firstterm>read-write</firstterm> and <firstterm>read-only</firstterm> pointers.
+The pointed-to representation is the same either way, but a function that
+receives a read-write pointer is allowed to modify the referenced value
+in-place, whereas one that receives a read-only pointer must not; it must
+first create a copy if it wants to make a modified version of the value.
+This distinction and some associated conventions make it possible to avoid
+unnecessary copying of expanded values during query execution.
+</para>
+
+<para>
+For all types of in-memory <acronym>TOAST</acronym> pointer, the <acronym>TOAST</acronym>
+management code ensures that no such pointer datum can accidentally get
+stored on disk. In-memory <acronym>TOAST</acronym> pointers are automatically
+expanded to normal in-line varlena values before storage &mdash; and then
+possibly converted to on-disk <acronym>TOAST</acronym> pointers, if the containing
+tuple would otherwise be too big.
+</para>
+
+</sect2>
+
+</sect1>
+
+<sect1 id="storage-fsm">
+
+<title>Free Space Map</title>
+
+<indexterm>
+ <primary>Free Space Map</primary>
+</indexterm>
+<indexterm><primary>FSM</primary><see>Free Space Map</see></indexterm>
+
+<para>
+Each heap and index relation, except for hash indexes, has a Free Space Map
+(<acronym>FSM</acronym>) to keep track of available space in the relation.
+It's stored alongside the main relation data in a separate relation fork,
+named after the filenode number of the relation, plus a <literal>_fsm</literal>
+suffix. For example, if the filenode of a relation is 12345, the
+<acronym>FSM</acronym> is stored in a file called
+<filename>12345_fsm</filename>, in the same directory as the main relation file.
+</para>
+
+<para>
+The Free Space Map is organized as a tree of <acronym>FSM</acronym> pages. The
+bottom level <acronym>FSM</acronym> pages store the free space available on each
+heap (or index) page, using one byte to represent each such page. The upper
+levels aggregate information from the lower levels.
+</para>
+
+<para>
+Within each <acronym>FSM</acronym> page is a binary tree, stored in an array with
+one byte per node. Each leaf node represents a heap page, or a lower level
+<acronym>FSM</acronym> page. In each non-leaf node, the higher of its children's
+values is stored. The maximum value in the leaf nodes is therefore stored
+at the root.
+</para>
+
+<para>
+See <filename>src/backend/storage/freespace/README</filename> for more details on
+how the <acronym>FSM</acronym> is structured, and how it's updated and searched.
+The <xref linkend="pgfreespacemap"/> module
+can be used to examine the information stored in free space maps.
+</para>
+
+</sect1>
+
+<sect1 id="storage-vm">
+
+<title>Visibility Map</title>
+
+<indexterm>
+ <primary>Visibility Map</primary>
+</indexterm>
+<indexterm><primary>VM</primary><see>Visibility Map</see></indexterm>
+
+<para>
+Each heap relation has a Visibility Map
+(VM) to keep track of which pages contain only tuples that are known to be
+visible to all active transactions; it also keeps track of which pages contain
+only frozen tuples. It's stored
+alongside the main relation data in a separate relation fork, named after the
+filenode number of the relation, plus a <literal>_vm</literal> suffix. For example,
+if the filenode of a relation is 12345, the VM is stored in a file called
+<filename>12345_vm</filename>, in the same directory as the main relation file.
+Note that indexes do not have VMs.
+</para>
+
+<para>
+The visibility map stores two bits per heap page. The first bit, if set,
+indicates that the page is all-visible, or in other words that the page does
+not contain any tuples that need to be vacuumed.
+This information can also be used
+by <link linkend="indexes-index-only-scans"><firstterm>index-only
+scans</firstterm></link> to answer queries using only the index tuple.
+The second bit, if set, means that all tuples on the page have been frozen.
+That means that even an anti-wraparound vacuum need not revisit the page.
+</para>
+
+<para>
+The map is conservative in the sense that we make sure that whenever a bit is
+set, we know the condition is true, but if a bit is not set, it might or
+might not be true. Visibility map bits are only set by vacuum, but are
+cleared by any data-modifying operations on a page.
+</para>
+
+<para>
+The <xref linkend="pgvisibility"/> module can be used to examine the
+information stored in the visibility map.
+</para>
+
+</sect1>
+
+<sect1 id="storage-init">
+
+<title>The Initialization Fork</title>
+
+<indexterm>
+ <primary>Initialization Fork</primary>
+</indexterm>
+
+<para>
+Each unlogged table, and each index on an unlogged table, has an initialization
+fork. The initialization fork is an empty table or index of the appropriate
+type. When an unlogged table must be reset to empty due to a crash, the
+initialization fork is copied over the main fork, and any other forks are
+erased (they will be recreated automatically as needed).
+</para>
+
+</sect1>
+
+<sect1 id="storage-page-layout">
+
+<title>Database Page Layout</title>
+
+<para>
+This section provides an overview of the page format used within
+<productname>PostgreSQL</productname> tables and indexes.<footnote>
+ <para>
+ Actually, use of this page format is not required for either table or
+ index access methods. The <literal>heap</literal> table access method
+ always uses this format. All the existing index methods also use the
+ basic format, but the data kept on index metapages usually doesn't follow
+ the item layout rules.
+ </para>
+</footnote>
+Sequences and <acronym>TOAST</acronym> tables are formatted just like a regular table.
+</para>
+
+<para>
+In the following explanation, a
+<firstterm>byte</firstterm>
+is assumed to contain 8 bits. In addition, the term
+<firstterm>item</firstterm>
+refers to an individual data value that is stored on a page. In a table,
+an item is a row; in an index, an item is an index entry.
+</para>
+
+<para>
+Every table and index is stored as an array of <firstterm>pages</firstterm> of a
+fixed size (usually 8 kB, although a different page size can be selected
+when compiling the server). In a table, all the pages are logically
+equivalent, so a particular item (row) can be stored in any page. In
+indexes, the first page is generally reserved as a <firstterm>metapage</firstterm>
+holding control information, and there can be different types of pages
+within the index, depending on the index access method.
+</para>
+
+<para>
+<xref linkend="page-table"/> shows the overall layout of a page.
+There are five parts to each page.
+</para>
+
+<table tocentry="1" id="page-table">
+<title>Overall Page Layout</title>
+<titleabbrev>Page Layout</titleabbrev>
+<tgroup cols="2">
+<thead>
+<row>
+<entry>
+Item
+</entry>
+<entry>Description</entry>
+</row>
+</thead>
+
+<tbody>
+
+<row>
+ <entry>PageHeaderData</entry>
+ <entry>24 bytes long. Contains general information about the page, including
+free space pointers.</entry>
+</row>
+
+<row>
+<entry>ItemIdData</entry>
+<entry>Array of item identifiers pointing to the actual items. Each
+entry is an (offset,length) pair. 4 bytes per item.</entry>
+</row>
+
+<row>
+<entry>Free space</entry>
+<entry>The unallocated space. New item identifiers are allocated from
+the start of this area, new items from the end.</entry>
+</row>
+
+<row>
+<entry>Items</entry>
+<entry>The actual items themselves.</entry>
+</row>
+
+<row>
+<entry>Special space</entry>
+<entry>Index access method specific data. Different methods store different
+data. Empty in ordinary tables.</entry>
+</row>
+
+</tbody>
+</tgroup>
+</table>
+
+ <para>
+
+ The first 24 bytes of each page consists of a page header
+ (<structname>PageHeaderData</structname>). Its format is detailed in <xref
+ linkend="pageheaderdata-table"/>. The first field tracks the most
+ recent WAL entry related to this page. The second field contains
+ the page checksum if <xref linkend="app-initdb-data-checksums"/> are
+ enabled. Next is a 2-byte field containing flag bits. This is followed
+ by three 2-byte integer fields (<structfield>pd_lower</structfield>,
+ <structfield>pd_upper</structfield>, and
+ <structfield>pd_special</structfield>). These contain byte offsets
+ from the page start to the start of unallocated space, to the end of
+ unallocated space, and to the start of the special space. The next 2
+ bytes of the page header, <structfield>pd_pagesize_version</structfield>,
+ store both the page size and a version indicator. Beginning with
+ <productname>PostgreSQL</productname> 8.3 the version number is 4;
+ <productname>PostgreSQL</productname> 8.1 and 8.2 used version number 3;
+ <productname>PostgreSQL</productname> 8.0 used version number 2;
+ <productname>PostgreSQL</productname> 7.3 and 7.4 used version number 1;
+ prior releases used version number 0.
+ (The basic page layout and header format has not changed in most of these
+ versions, but the layout of heap row headers has.) The page size
+ is basically only present as a cross-check; there is no support for having
+ more than one page size in an installation.
+ The last field is a hint that shows whether pruning the page is likely
+ to be profitable: it tracks the oldest un-pruned XMAX on the page.
+
+ </para>
+
+ <table tocentry="1" id="pageheaderdata-table">
+ <title>PageHeaderData Layout</title>
+ <titleabbrev>PageHeaderData Layout</titleabbrev>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Field</entry>
+ <entry>Type</entry>
+ <entry>Length</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>pd_lsn</entry>
+ <entry>PageXLogRecPtr</entry>
+ <entry>8 bytes</entry>
+ <entry>LSN: next byte after last byte of WAL record for last change
+ to this page</entry>
+ </row>
+ <row>
+ <entry>pd_checksum</entry>
+ <entry>uint16</entry>
+ <entry>2 bytes</entry>
+ <entry>Page checksum</entry>
+ </row>
+ <row>
+ <entry>pd_flags</entry>
+ <entry>uint16</entry>
+ <entry>2 bytes</entry>
+ <entry>Flag bits</entry>
+ </row>
+ <row>
+ <entry>pd_lower</entry>
+ <entry>LocationIndex</entry>
+ <entry>2 bytes</entry>
+ <entry>Offset to start of free space</entry>
+ </row>
+ <row>
+ <entry>pd_upper</entry>
+ <entry>LocationIndex</entry>
+ <entry>2 bytes</entry>
+ <entry>Offset to end of free space</entry>
+ </row>
+ <row>
+ <entry>pd_special</entry>
+ <entry>LocationIndex</entry>
+ <entry>2 bytes</entry>
+ <entry>Offset to start of special space</entry>
+ </row>
+ <row>
+ <entry>pd_pagesize_version</entry>
+ <entry>uint16</entry>
+ <entry>2 bytes</entry>
+ <entry>Page size and layout version number information</entry>
+ </row>
+ <row>
+ <entry>pd_prune_xid</entry>
+ <entry>TransactionId</entry>
+ <entry>4 bytes</entry>
+ <entry>Oldest unpruned XMAX on page, or zero if none</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ All the details can be found in
+ <filename>src/include/storage/bufpage.h</filename>.
+ </para>
+
+ <para>
+ Following the page header are item identifiers
+ (<type>ItemIdData</type>), each requiring four bytes.
+ An item identifier contains a byte-offset to
+ the start of an item, its length in bytes, and a few attribute bits
+ which affect its interpretation.
+ New item identifiers are allocated
+ as needed from the beginning of the unallocated space.
+ The number of item identifiers present can be determined by looking at
+ <structfield>pd_lower</structfield>, which is increased to allocate a new identifier.
+ Because an item
+ identifier is never moved until it is freed, its index can be used on a
+ long-term basis to reference an item, even when the item itself is moved
+ around on the page to compact free space. In fact, every pointer to an
+ item (<type>ItemPointer</type>, also known as
+ <type>CTID</type>) created by
+ <productname>PostgreSQL</productname> consists of a page number and the
+ index of an item identifier.
+
+ </para>
+
+ <para>
+
+ The items themselves are stored in space allocated backwards from the end
+ of unallocated space. The exact structure varies depending on what the
+ table is to contain. Tables and sequences both use a structure named
+ <type>HeapTupleHeaderData</type>, described below.
+
+ </para>
+
+ <para>
+
+ The final section is the <quote>special section</quote> which can
+ contain anything the access method wishes to store. For example,
+ b-tree indexes store links to the page's left and right siblings,
+ as well as some other data relevant to the index structure.
+ Ordinary tables do not use a special section at all (indicated by setting
+ <structfield>pd_special</structfield> to equal the page size).
+
+ </para>
+
+ <para>
+ <xref linkend="storage-page-layout-figure"/> illustrates how these parts are
+ laid out in a page.
+ </para>
+
+ <figure id="storage-page-layout-figure">
+ <title>Page Layout</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/pagelayout.svg" format="SVG" width="100%"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+
+ <sect2 id="storage-tuple-layout">
+
+ <title>Table Row Layout</title>
+
+ <para>
+
+ All table rows are structured in the same way. There is a fixed-size
+ header (occupying 23 bytes on most machines), followed by an optional null
+ bitmap, an optional object ID field, and the user data. The header is
+ detailed
+ in <xref linkend="heaptupleheaderdata-table"/>. The actual user data
+ (columns of the row) begins at the offset indicated by
+ <structfield>t_hoff</structfield>, which must always be a multiple of the MAXALIGN
+ distance for the platform.
+ The null bitmap is
+ only present if the <firstterm>HEAP_HASNULL</firstterm> bit is set in
+ <structfield>t_infomask</structfield>. If it is present it begins just after
+ the fixed header and occupies enough bytes to have one bit per data column
+ (that is, the number of bits that equals the attribute count in
+ <structfield>t_infomask2</structfield>). In this list of bits, a
+ 1 bit indicates not-null, a 0 bit is a null. When the bitmap is not
+ present, all columns are assumed not-null.
+ The object ID is only present if the <firstterm>HEAP_HASOID_OLD</firstterm> bit
+ is set in <structfield>t_infomask</structfield>. If present, it appears just
+ before the <structfield>t_hoff</structfield> boundary. Any padding needed to make
+ <structfield>t_hoff</structfield> a MAXALIGN multiple will appear between the null
+ bitmap and the object ID. (This in turn ensures that the object ID is
+ suitably aligned.)
+
+ </para>
+
+ <table tocentry="1" id="heaptupleheaderdata-table">
+ <title>HeapTupleHeaderData Layout</title>
+ <titleabbrev>HeapTupleHeaderData Layout</titleabbrev>
+ <tgroup cols="4">
+ <thead>
+ <row>
+ <entry>Field</entry>
+ <entry>Type</entry>
+ <entry>Length</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>t_xmin</entry>
+ <entry>TransactionId</entry>
+ <entry>4 bytes</entry>
+ <entry>insert XID stamp</entry>
+ </row>
+ <row>
+ <entry>t_xmax</entry>
+ <entry>TransactionId</entry>
+ <entry>4 bytes</entry>
+ <entry>delete XID stamp</entry>
+ </row>
+ <row>
+ <entry>t_cid</entry>
+ <entry>CommandId</entry>
+ <entry>4 bytes</entry>
+ <entry>insert and/or delete CID stamp (overlays with t_xvac)</entry>
+ </row>
+ <row>
+ <entry>t_xvac</entry>
+ <entry>TransactionId</entry>
+ <entry>4 bytes</entry>
+ <entry>XID for VACUUM operation moving a row version</entry>
+ </row>
+ <row>
+ <entry>t_ctid</entry>
+ <entry>ItemPointerData</entry>
+ <entry>6 bytes</entry>
+ <entry>current TID of this or newer row version</entry>
+ </row>
+ <row>
+ <entry>t_infomask2</entry>
+ <entry>uint16</entry>
+ <entry>2 bytes</entry>
+ <entry>number of attributes, plus various flag bits</entry>
+ </row>
+ <row>
+ <entry>t_infomask</entry>
+ <entry>uint16</entry>
+ <entry>2 bytes</entry>
+ <entry>various flag bits</entry>
+ </row>
+ <row>
+ <entry>t_hoff</entry>
+ <entry>uint8</entry>
+ <entry>1 byte</entry>
+ <entry>offset to user data</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ All the details can be found in
+ <filename>src/include/access/htup_details.h</filename>.
+ </para>
+
+ <para>
+
+ Interpreting the actual data can only be done with information obtained
+ from other tables, mostly <structname>pg_attribute</structname>. The
+ key values needed to identify field locations are
+ <structfield>attlen</structfield> and <structfield>attalign</structfield>.
+ There is no way to directly get a
+ particular attribute, except when there are only fixed width fields and no
+ null values. All this trickery is wrapped up in the functions
+ <firstterm>heap_getattr</firstterm>, <firstterm>fastgetattr</firstterm>
+ and <firstterm>heap_getsysattr</firstterm>.
+
+ </para>
+ <para>
+
+ To read the data you need to examine each attribute in turn. First check
+ whether the field is NULL according to the null bitmap. If it is, go to
+ the next. Then make sure you have the right alignment. If the field is a
+ fixed width field, then all the bytes are simply placed. If it's a
+ variable length field (attlen = -1) then it's a bit more complicated.
+ All variable-length data types share the common header structure
+ <type>struct varlena</type>, which includes the total length of the stored
+ value and some flag bits. Depending on the flags, the data can be either
+ inline or in a <acronym>TOAST</acronym> table;
+ it might be compressed, too (see <xref linkend="storage-toast"/>).
+
+ </para>
+ </sect2>
+</sect1>
+
+<sect1 id="storage-hot">
+
+ <title>Heap-Only Tuples (<acronym>HOT</acronym>)</title>
+
+ <para>
+ To allow for high concurrency, <productname>PostgreSQL</productname>
+ uses <link linkend="mvcc-intro">multiversion concurrency
+ control</link> (<acronym>MVCC</acronym>) to store rows. However,
+ <acronym>MVCC</acronym> has some downsides for update queries.
+ Specifically, updates require new versions of rows to be added to
+ tables. This can also require new index entries for each updated row,
+ and removal of old versions of rows and their index entries can be
+ expensive.
+ </para>
+
+ <para>
+ To help reduce the overhead of updates,
+ <productname>PostgreSQL</productname> has an optimization called
+ heap-only tuples (<acronym>HOT</acronym>). This optimization is
+ possible when:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The update does not modify any columns referenced by the table's
+ indexes, including expression and partial indexes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ There is sufficient free space on the page containing the old row
+ for the updated row.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ In such cases, heap-only tuples provide two optimizations:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ New index entries are not needed to represent updated rows.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Old versions of updated rows can be completely removed during normal
+ operation, including <command>SELECT</command>s, instead of requiring
+ periodic vacuum operations. (This is possible because indexes
+ do not reference their <link linkend="storage-page-layout">page
+ item identifiers</link>.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In summary, heap-only tuple updates can only be created
+ if columns used by indexes are not updated. You can
+ increase the likelihood of sufficient page space for
+ <acronym>HOT</acronym> updates by decreasing a table's <link
+ linkend="reloption-fillfactor"><literal>fillfactor</literal></link>.
+ If you don't, <acronym>HOT</acronym> updates will still happen because
+ new rows will naturally migrate to new pages and existing pages with
+ sufficient free space for new row versions. The system view <link
+ linkend="monitoring-pg-stat-all-tables-view">pg_stat_all_tables</link>
+ allows monitoring of the occurrence of HOT and non-HOT updates.
+ </para>
+</sect1>
+
+</chapter>
diff --git a/doc/src/sgml/stylesheet-common.xsl b/doc/src/sgml/stylesheet-common.xsl
new file mode 100644
index 0000000..761484c
--- /dev/null
+++ b/doc/src/sgml/stylesheet-common.xsl
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+<!--
+ This file contains XSLT stylesheet customizations that are common to
+ all output formats (HTML, HTML Help, XSL-FO, etc.).
+ -->
+
+<xsl:include href="stylesheet-speedup-common.xsl" />
+
+<!-- Parameters -->
+
+<!--
+<xsl:param name="draft.mode">
+ <xsl:choose>
+ <xsl:when test="contains($pg.version, 'devel')">yes</xsl:when>
+ <xsl:otherwise>no</xsl:otherwise>
+ </xsl:choose>
+</xsl:param>
+-->
+
+<xsl:param name="show.comments">
+ <xsl:choose>
+ <xsl:when test="contains($pg.version, 'devel')">1</xsl:when>
+ <xsl:otherwise>0</xsl:otherwise>
+ </xsl:choose>
+</xsl:param>
+
+<xsl:param name="callout.graphics" select="'0'"></xsl:param>
+<xsl:param name="toc.section.depth">2</xsl:param>
+<xsl:param name="linenumbering.extension" select="'0'"></xsl:param>
+<xsl:param name="section.autolabel" select="1"></xsl:param>
+<xsl:param name="section.label.includes.component.label" select="1"></xsl:param>
+<xsl:param name="refentry.generate.name" select="0"></xsl:param>
+<xsl:param name="refentry.generate.title" select="1"></xsl:param>
+<xsl:param name="refentry.xref.manvolnum" select="0"/>
+<xsl:param name="formal.procedures" select="0"></xsl:param>
+<xsl:param name="generate.consistent.ids" select="1"/>
+<xsl:param name="punct.honorific" select="''"></xsl:param>
+<xsl:param name="variablelist.term.break.after">1</xsl:param>
+<xsl:param name="variablelist.term.separator"></xsl:param>
+<xsl:param name="xref.with.number.and.title" select="0"></xsl:param>
+
+
+<!-- Change display of some elements -->
+
+<xsl:template match="productname">
+ <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<!-- Render <returnvalue> with a right arrow then the type name -->
+<!-- Avoid adding unnecessary white space in this template! -->
+<xsl:template match="returnvalue">&#x2192; <xsl:call-template name="inline.monoseq"/></xsl:template>
+
+<xsl:template match="structfield">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="structname">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="symbol">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="systemitem">
+ <xsl:call-template name="inline.charseq"/>
+</xsl:template>
+
+<xsl:template match="token">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="type">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="programlisting/emphasis">
+ <xsl:call-template name="inline.boldseq"/>
+</xsl:template>
+
+
+<!-- Special support for Tcl synopses -->
+
+<xsl:template match="optional[@role='tcl']">
+ <xsl:text>?</xsl:text>
+ <xsl:call-template name="inline.charseq"/>
+ <xsl:text>?</xsl:text>
+</xsl:template>
+
+
+<!-- Support for generating xref link text to additional elements -->
+
+<xsl:template match="command" mode="xref-to">
+ <xsl:apply-templates select="." mode="xref"/>
+</xsl:template>
+
+<xsl:template match="function" mode="xref-to">
+ <xsl:apply-templates select="." mode="xref"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-fo.xsl b/doc/src/sgml/stylesheet-fo.xsl
new file mode 100644
index 0000000..0c4dff9
--- /dev/null
+++ b/doc/src/sgml/stylesheet-fo.xsl
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns:fo="http://www.w3.org/1999/XSL/Format">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl"/>
+<xsl:include href="stylesheet-common.xsl" />
+
+<xsl:param name="fop1.extensions" select="1"></xsl:param>
+<xsl:param name="tablecolumns.extension" select="0"></xsl:param>
+<xsl:param name="toc.max.depth">3</xsl:param>
+<xsl:param name="ulink.footnotes" select="1"></xsl:param>
+<xsl:param name="use.extensions" select="1"></xsl:param>
+<xsl:param name="variablelist.as.blocks" select="1"></xsl:param>
+<xsl:param name="orderedlist.label.width">1.5em</xsl:param>
+
+<xsl:attribute-set name="monospace.verbatim.properties"
+ use-attribute-sets="verbatim.properties monospace.properties">
+ <xsl:attribute name="wrap-option">wrap</xsl:attribute>
+</xsl:attribute-set>
+
+<xsl:attribute-set name="nongraphical.admonition.properties">
+ <xsl:attribute name="border-style">solid</xsl:attribute>
+ <xsl:attribute name="border-width">1pt</xsl:attribute>
+ <xsl:attribute name="border-color">black</xsl:attribute>
+ <xsl:attribute name="padding-start">12pt</xsl:attribute>
+ <xsl:attribute name="padding-end">12pt</xsl:attribute>
+ <xsl:attribute name="padding-top">6pt</xsl:attribute>
+ <xsl:attribute name="padding-bottom">6pt</xsl:attribute>
+</xsl:attribute-set>
+
+<xsl:attribute-set name="admonition.title.properties">
+ <xsl:attribute name="text-align">center</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- Make all tables default to left alignment, for consistency with HTML -->
+<xsl:attribute-set name="table.table.properties">
+ <xsl:attribute name="text-align">left</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- fix missing space after vertical simplelist
+ https://github.com/docbook/xslt10-stylesheets/issues/31 -->
+<xsl:attribute-set name="normal.para.spacing">
+ <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
+ <xsl:attribute name="space-after.minimum">0.8em</xsl:attribute>
+ <xsl:attribute name="space-after.maximum">1.2em</xsl:attribute>
+</xsl:attribute-set>
+
+<!-- Change display of some elements -->
+
+<xsl:template match="command">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="bibliography.mode">
+ <fo:inline>
+ <xsl:apply-templates select="conftitle/text()" mode="bibliography.mode"/>
+ <xsl:text>, </xsl:text>
+ <xsl:apply-templates select="confdates/text()" mode="bibliography.mode"/>
+ <xsl:value-of select="$biblioentry.item.separator"/>
+ </fo:inline>
+</xsl:template>
+
+<xsl:template match="isbn" mode="bibliography.mode">
+ <fo:inline>
+ <xsl:text>ISBN </xsl:text>
+ <xsl:apply-templates mode="bibliography.mode"/>
+ <xsl:value-of select="$biblioentry.item.separator"/>
+ </fo:inline>
+</xsl:template>
+
+<!-- formatting for entries in tables of functions -->
+<xsl:template match="entry[@role='func_table_entry']/para">
+ <fo:block margin-left="4em" text-align="left">
+ <xsl:if test="self::para[@role='func_signature']">
+ <xsl:attribute name="text-indent">-3.5em</xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </fo:block>
+</xsl:template>
+
+<!-- formatting for entries in tables of catalog/view columns -->
+<xsl:template match="entry[@role='catalog_table_entry']/para">
+ <fo:block margin-left="4em" text-align="left">
+ <xsl:if test="self::para[@role='column_definition']">
+ <xsl:attribute name="text-indent">-3.5em</xsl:attribute>
+ </xsl:if>
+ <xsl:apply-templates/>
+ </fo:block>
+</xsl:template>
+
+<!-- overrides stylesheet-common.xsl -->
+<!-- FOP needs us to be explicit about the font to use for right arrow -->
+<xsl:template match="returnvalue">
+ <fo:inline font-family="{$symbol.font.family}">&#x2192; </fo:inline>
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<!-- FOP needs us to be explicit about use of symbol font in some cases -->
+<xsl:template match="phrase[@role='symbol_font']">
+ <fo:inline font-family="{$symbol.font.family}"><xsl:value-of select="."/></fo:inline>
+</xsl:template>
+
+<!-- bug fix from <https://sourceforge.net/p/docbook/bugs/1360/#831b> -->
+
+<xsl:template match="varlistentry/term" mode="xref-to">
+ <xsl:param name="verbose" select="1"/>
+ <xsl:apply-templates mode="no.anchor.mode"/>
+</xsl:template>
+
+<!-- include refsects in PDF bookmarks
+ (https://github.com/docbook/xslt10-stylesheets/issues/46) -->
+
+<xsl:template match="refsect1|refsect2|refsect3"
+ mode="bookmark">
+
+ <xsl:variable name="id">
+ <xsl:call-template name="object.id"/>
+ </xsl:variable>
+ <xsl:variable name="bookmark-label">
+ <xsl:apply-templates select="." mode="object.title.markup"/>
+ </xsl:variable>
+
+ <fo:bookmark internal-destination="{$id}">
+ <xsl:attribute name="starting-state">
+ <xsl:value-of select="$bookmarks.state"/>
+ </xsl:attribute>
+ <fo:bookmark-title>
+ <xsl:value-of select="normalize-space($bookmark-label)"/>
+ </fo:bookmark-title>
+ <xsl:apply-templates select="*" mode="bookmark"/>
+ </fo:bookmark>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-hh.xsl b/doc/src/sgml/stylesheet-hh.xsl
new file mode 100644
index 0000000..6f4b706
--- /dev/null
+++ b/doc/src/sgml/stylesheet-hh.xsl
@@ -0,0 +1,47 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/htmlhelp/htmlhelp.xsl"/>
+<xsl:include href="stylesheet-common.xsl" />
+
+<!-- Parameters -->
+<xsl:param name="htmlhelp.use.hhk" select="'1'"/>
+
+<xsl:param name="base.dir" select="'htmlhelp/'"></xsl:param>
+<xsl:param name="html.stylesheet" select="'stylesheet.css'"></xsl:param>
+<xsl:param name="use.id.as.filename" select="'1'"></xsl:param>
+<xsl:param name="manifest.in.base.dir" select="1"/>
+<xsl:param name="make.valid.html" select="1"></xsl:param>
+<xsl:param name="generate.id.attributes" select="1"></xsl:param>
+<xsl:param name="generate.legalnotice.link" select="1"></xsl:param>
+<xsl:param name="link.mailto.url">pgsql-docs@lists.postgresql.org</xsl:param>
+<xsl:param name="chunker.output.indent" select="'yes'"/>
+<xsl:param name="chunk.quietly" select="1"></xsl:param>
+
+
+<!-- Change display of some elements -->
+
+<xsl:template match="command">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<!--
+ Format multiple terms in varlistentry vertically, instead
+ of comma-separated.
+ -->
+
+<xsl:template match="varlistentry/term[position()!=last()]">
+ <span class="term">
+ <xsl:call-template name="anchor"/>
+ <xsl:apply-templates/>
+ </span><br/>
+</xsl:template>
+
+
+<!-- strip directory name from image filerefs -->
+<xsl:template match="imagedata/@fileref">
+ <xsl:value-of select="substring-after(., '/')"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl
new file mode 100644
index 0000000..9df2782
--- /dev/null
+++ b/doc/src/sgml/stylesheet-html-common.xsl
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE xsl:stylesheet [
+<!ENTITY % common.entities SYSTEM "http://docbook.sourceforge.net/release/xsl/current/common/entities.ent">
+%common.entities;
+]>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0"
+ xmlns="http://www.w3.org/1999/xhtml">
+
+<!--
+ This file contains XSLT stylesheet customizations that are common to
+ all HTML output variants (chunked and single-page).
+ -->
+
+<!-- Parameters -->
+<xsl:param name="make.valid.html" select="1"></xsl:param>
+<xsl:param name="generate.id.attributes" select="1"></xsl:param>
+<xsl:param name="make.graphic.viewport" select="0"/>
+<xsl:param name="link.mailto.url">pgsql-docs@lists.postgresql.org</xsl:param>
+<xsl:param name="toc.max.depth">2</xsl:param>
+
+<!--
+ The below allows the stylesheets provided by the website to be applied fully
+ to the generated HTML.
+ -->
+<xsl:template name="body.attributes">
+ <xsl:attribute name="id">docContent</xsl:attribute>
+ <xsl:attribute name="class">container-fluid col-10</xsl:attribute>
+</xsl:template>
+
+<!-- Change display of some elements -->
+
+<xsl:template match="command">
+ <xsl:call-template name="inline.monoseq"/>
+</xsl:template>
+
+<xsl:template match="confgroup" mode="bibliography.mode">
+ <span>
+ <xsl:call-template name="common.html.attributes"/>
+ <xsl:call-template name="id.attribute"/>
+ <xsl:apply-templates select="conftitle/text()" mode="bibliography.mode"/>
+ <xsl:text>, </xsl:text>
+ <xsl:apply-templates select="confdates/text()" mode="bibliography.mode"/>
+ <xsl:copy-of select="$biblioentry.item.separator"/>
+ </span>
+</xsl:template>
+
+<xsl:template match="isbn" mode="bibliography.mode">
+ <span>
+ <xsl:call-template name="common.html.attributes"/>
+ <xsl:call-template name="id.attribute"/>
+ <xsl:text>ISBN </xsl:text>
+ <xsl:apply-templates mode="bibliography.mode"/>
+ <xsl:copy-of select="$biblioentry.item.separator"/>
+ </span>
+</xsl:template>
+
+
+<!-- table of contents configuration -->
+
+<xsl:param name="generate.toc">
+appendix toc,title
+article/appendix nop
+article toc,title
+book toc,title
+chapter toc,title
+part toc,title
+preface toc,title
+qandadiv toc
+qandaset toc
+reference toc,title
+sect1 toc
+sect2 toc
+sect3 toc
+sect4 toc
+sect5 toc
+section toc
+set toc,title
+</xsl:param>
+
+<xsl:param name="generate.section.toc.level" select="1"></xsl:param>
+
+<!-- include refentry under sect1 in tocs -->
+<xsl:template match="sect1" mode="toc">
+ <xsl:param name="toc-context" select="."/>
+ <xsl:call-template name="subtoc">
+ <xsl:with-param name="toc-context" select="$toc-context"/>
+ <xsl:with-param name="nodes" select="sect2|refentry
+ |bridgehead[$bridgehead.in.toc != 0]"/>
+ </xsl:call-template>
+</xsl:template>
+
+
+<!-- Put index "quicklinks" (A | B | C | ...) at the top of the bookindex page. -->
+
+<!-- from html/autoidx.xsl -->
+
+<xsl:template name="generate-basic-index">
+ <xsl:param name="scope" select="NOTANODE"/>
+
+ <xsl:variable name="role">
+ <xsl:if test="$index.on.role != 0">
+ <xsl:value-of select="@role"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:variable name="type">
+ <xsl:if test="$index.on.type != 0">
+ <xsl:value-of select="@type"/>
+ </xsl:if>
+ </xsl:variable>
+
+ <xsl:variable name="terms"
+ select="//indexterm
+ [count(.|key('letter',
+ translate(substring(&primary;, 1, 1),
+ &lowercase;,
+ &uppercase;))
+ [&scope;][1]) = 1
+ and not(@class = 'endofrange')]"/>
+
+ <xsl:variable name="alphabetical"
+ select="$terms[contains(concat(&lowercase;, &uppercase;),
+ substring(&primary;, 1, 1))]"/>
+
+ <xsl:variable name="others" select="$terms[not(contains(concat(&lowercase;,
+ &uppercase;),
+ substring(&primary;, 1, 1)))]"/>
+
+ <!-- pgsql-docs: added xmlns:xlink, autoidx.xsl doesn't include xlink in
+ exclude-result-prefixes. Without our customization that just leads to a
+ single xmlns:xlink in this div, but because we emit it it otherwise
+ gets pushed down to the elements output by autoidx.xsl -->
+ <div class="index" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <p class="indexdiv-quicklinks">
+ <a href="#indexdiv-Symbols">
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key" select="'index symbols'"/>
+ </xsl:call-template>
+ </a>
+ <xsl:apply-templates select="$alphabetical[count(.|key('letter',
+ translate(substring(&primary;, 1, 1),
+ &lowercase;,&uppercase;))[&scope;][1]) = 1]"
+ mode="index-div-quicklinks">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
+ </xsl:apply-templates>
+ </p>
+ <!-- pgsql-docs: end added stuff -->
+
+ <xsl:if test="$others">
+ <xsl:choose>
+ <xsl:when test="normalize-space($type) != '' and
+ $others[@type = $type][count(.|key('primary', &primary;)[&scope;][1]) = 1]">
+ <!-- pgsql-docs: added id attribute here for linking to it -->
+ <div class="indexdiv" id="indexdiv-Symbols">
+ <h3>
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key" select="'index symbols'"/>
+ </xsl:call-template>
+ </h3>
+ <dl>
+ <xsl:apply-templates select="$others[count(.|key('primary', &primary;)[&scope;][1]) = 1]"
+ mode="index-symbol-div">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
+ </xsl:apply-templates>
+ </dl>
+ </div>
+ </xsl:when>
+ <xsl:when test="normalize-space($type) != ''">
+ <!-- Output nothing, as there isn't a match for $other using this $type -->
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- pgsql-docs: added id attribute here for linking to it -->
+ <div class="indexdiv" id="indexdiv-Symbols">
+ <h3>
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key" select="'index symbols'"/>
+ </xsl:call-template>
+ </h3>
+ <dl>
+ <xsl:apply-templates select="$others[count(.|key('primary',
+ &primary;)[&scope;][1]) = 1]"
+ mode="index-symbol-div">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
+ </xsl:apply-templates>
+ </dl>
+ </div>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:if>
+
+ <xsl:apply-templates select="$alphabetical[count(.|key('letter',
+ translate(substring(&primary;, 1, 1),
+ &lowercase;,&uppercase;))[&scope;][1]) = 1]"
+ mode="index-div-basic">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
+ </xsl:apply-templates>
+ </div>
+</xsl:template>
+
+<xsl:template match="indexterm" mode="index-div-basic">
+ <xsl:param name="scope" select="."/>
+ <xsl:param name="role" select="''"/>
+ <xsl:param name="type" select="''"/>
+
+ <xsl:variable name="key"
+ select="translate(substring(&primary;, 1, 1),
+ &lowercase;,&uppercase;)"/>
+
+ <xsl:if test="key('letter', $key)[&scope;]
+ [count(.|key('primary', &primary;)[&scope;][1]) = 1]">
+ <div class="indexdiv">
+ <!-- pgsql-docs: added id attribute here for linking to it -->
+ <xsl:attribute name="id">
+ <xsl:value-of select="concat('indexdiv-', $key)"/>
+ </xsl:attribute>
+
+ <xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)">
+ <h3>
+ <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
+ </h3>
+ </xsl:if>
+ <dl>
+ <xsl:apply-templates select="key('letter', $key)[&scope;]
+ [count(.|key('primary', &primary;)
+ [&scope;][1])=1]"
+ mode="index-primary">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:sort select="translate(&primary;, &lowercase;, &uppercase;)"/>
+ </xsl:apply-templates>
+ </dl>
+ </div>
+ </xsl:if>
+</xsl:template>
+
+<!-- pgsql-docs -->
+<xsl:template match="indexterm" mode="index-div-quicklinks">
+ <xsl:param name="scope" select="."/>
+ <xsl:param name="role" select="''"/>
+ <xsl:param name="type" select="''"/>
+
+ <xsl:variable name="key"
+ select="translate(substring(&primary;, 1, 1),
+ &lowercase;,&uppercase;)"/>
+
+ <xsl:if test="key('letter', $key)[&scope;]
+ [count(.|key('primary', &primary;)[&scope;][1]) = 1]">
+ <xsl:if test="contains(concat(&lowercase;, &uppercase;), $key)">
+ |
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="concat('#indexdiv-', $key)"/>
+ </xsl:attribute>
+ <xsl:value-of select="translate($key, &lowercase;, &uppercase;)"/>
+ </a>
+ </xsl:if>
+ </xsl:if>
+</xsl:template>
+
+
+<!-- upper case HTML anchors for backward compatibility -->
+
+<xsl:template name="object.id">
+ <xsl:param name="object" select="."/>
+ <xsl:choose>
+ <xsl:when test="$object/@id">
+ <xsl:value-of select="translate($object/@id, &lowercase;, &uppercase;)"/>
+ </xsl:when>
+ <xsl:when test="$object/@xml:id">
+ <xsl:value-of select="$object/@xml:id"/>
+ </xsl:when>
+ <xsl:when test="$generate.consistent.ids != 0">
+ <!-- Make $object the current node -->
+ <xsl:for-each select="$object">
+ <xsl:text>id-</xsl:text>
+ <xsl:number level="multiple" count="*"/>
+ </xsl:for-each>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="generate-id($object)"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-html-nochunk.xsl b/doc/src/sgml/stylesheet-html-nochunk.xsl
new file mode 100644
index 0000000..8167127
--- /dev/null
+++ b/doc/src/sgml/stylesheet-html-nochunk.xsl
@@ -0,0 +1,21 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"/>
+<xsl:include href="stylesheet-common.xsl" />
+<xsl:include href="stylesheet-html-common.xsl" />
+<xsl:include href="stylesheet-speedup-xhtml.xsl" />
+
+<!-- embed SVG images into output file -->
+<xsl:template match="imagedata[@format='SVG']">
+ <xsl:variable name="filename">
+ <xsl:call-template name="mediaobject.filename">
+ <xsl:with-param name="object" select=".."/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:copy-of select="document($filename)"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-man.xsl b/doc/src/sgml/stylesheet-man.xsl
new file mode 100644
index 0000000..fcb485c
--- /dev/null
+++ b/doc/src/sgml/stylesheet-man.xsl
@@ -0,0 +1,226 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:exsl="http://exslt.org/common"
+ version='1.0'
+ exclude-result-prefixes="exsl">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl"/>
+<xsl:import href="stylesheet-common.xsl" />
+
+
+<!-- Parameters -->
+
+<xsl:param name="man.authors.section.enabled">0</xsl:param>
+<xsl:param name="man.copyright.section.enabled">0</xsl:param>
+<xsl:param name="man.endnotes.are.numbered">0</xsl:param> <!-- for performance -->
+<xsl:param name="man.output.base.dir"></xsl:param>
+<xsl:param name="man.output.in.separate.dir" select="1"></xsl:param>
+<xsl:param name="man.output.quietly" select="1"></xsl:param>
+<xsl:param name="man.th.title.max.length">32</xsl:param> <!-- enough room for "CREATE TEXT SEARCH CONFIGURATION" -->
+<xsl:param name="man.th.extra3.max.length">40</xsl:param> <!-- enough room for "PostgreSQL X.Ydevel Documentation" -->
+<xsl:param name="refentry.meta.get.quietly" select="0"></xsl:param>
+<xsl:param name="refentry.xref.manvolnum" select="1"/> <!-- overridden from stylesheet-common.xsl -->
+
+<!-- Fixup for apostrophe groff output. See the following references:
+ <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=457839>
+ <https://sourceforge.net/tracker/?func=detail&aid=2412738&group_id=21935&atid=373747>
+ -->
+<xsl:param name="man.string.subst.map.local.post">
+ <substitution oldstring="\'" newstring="\(aq"></substitution>
+</xsl:param>
+
+
+<!-- Custom templates -->
+
+<!-- Improve output of email element. See also
+ <https://sourceforge.net/tracker/?func=detail&aid=3524417&group_id=21935&atid=373747>
+ -->
+<xsl:template match="email">
+ <xsl:text>&lt;</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>&gt;</xsl:text>
+</xsl:template>
+
+
+<!-- Make superscripts visible in man pages (default is no decoration) -->
+<xsl:template match="superscript">
+ <xsl:text>^</xsl:text>
+ <xsl:apply-templates/>
+</xsl:template>
+
+
+<xsl:template match="refentry" mode="xref-to">
+ <xsl:param name="referrer"/>
+ <xsl:param name="xrefstyle"/>
+
+ <xsl:choose>
+ <!-- If the refname contains a space, we construct a reference
+ like CREATE DATABASE (CREATE_DATABASE(7)), so the reader
+ knows both the command name being referred to and the name of
+ the man page to read about it. -->
+ <xsl:when test="contains(refnamediv/refname[1],' ')">
+ <xsl:variable name="mangled.title">
+ <xsl:value-of select="translate(refnamediv/refname[1],' ','_')"/>
+ </xsl:variable>
+ <xsl:apply-templates select="refnamediv/refname[1]"/>
+ <xsl:text> (</xsl:text>
+ <xsl:call-template name="bold">
+ <xsl:with-param name="node" select="exsl:node-set($mangled.title)"/>
+ <xsl:with-param name="context" select="."/>
+ </xsl:call-template>
+ <xsl:apply-templates select="refmeta/manvolnum"/>
+ <xsl:text>)</xsl:text>
+ </xsl:when>
+
+ <!-- This is the original case, except that boldness has been
+ added, per the convention mentioned in man-pages(7). -->
+ <xsl:otherwise>
+ <xsl:choose>
+ <xsl:when test="refmeta/refentrytitle">
+ <xsl:call-template name="bold">
+ <xsl:with-param name="node" select="refmeta/refentrytitle"/>
+ <xsl:with-param name="context" select="."/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="bold">
+ <xsl:with-param name="node" select="refnamediv/refname[1]"/>
+ <xsl:with-param name="context" select="."/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:apply-templates select="refmeta/manvolnum"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+</xsl:template>
+
+
+<!-- For refentries we don't man to generate a man page for, leave out
+ manvolnum, let it default to 0, and skip writing out man files
+ with section 0. -->
+
+<!-- overridden from common/refentry.xsl -->
+<xsl:template name="get.refentry.section">
+ <xsl:choose>
+ <xsl:when test="refmeta/manvolnum">
+ <xsl:value-of select="refmeta/manvolnum"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>0</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<!-- overridden from manpages/other.xsl -->
+ <xsl:template name="write.man.file">
+ <xsl:param name="name"/>
+ <xsl:param name="section"/>
+ <xsl:param name="lang"/>
+ <xsl:param name="content"/>
+ <xsl:param name="filename">
+ <xsl:call-template name="make.adjusted.man.filename">
+ <xsl:with-param name="name" select="$name"/>
+ <xsl:with-param name="section" select="$section"/>
+ <xsl:with-param name="lang" select="$lang"/>
+ </xsl:call-template>
+ </xsl:param>
+ <xsl:if test="$section != 0">
+ <xsl:call-template name="write.text.chunk">
+ <xsl:with-param name="filename" select="$filename"/>
+ <xsl:with-param name="suppress-context-node-name" select="1"/>
+ <xsl:with-param name="quiet" select="$man.output.quietly"/>
+ <xsl:with-param
+ name="message-prolog"
+ >Note: </xsl:with-param>
+ <xsl:with-param name="encoding" select="$man.output.encoding"/>
+ <xsl:with-param name="content" select="$content"/>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:template>
+
+
+<!-- Overridden template as workaround for this problem:
+ <https://sourceforge.net/tracker/?func=detail&aid=2831602&group_id=21935&atid=373747>
+-->
+ <xsl:template name="write.stubs">
+ <xsl:param name="first.refname"/>
+ <xsl:param name="section"/>
+ <xsl:param name="lang"/>
+ <xsl:for-each select="refnamediv/refname">
+ <xsl:if test=". != $first.refname">
+ <xsl:call-template name="write.text.chunk">
+ <xsl:with-param name="filename">
+ <xsl:call-template name="make.adjusted.man.filename">
+ <xsl:with-param name="name" select="."/>
+ <xsl:with-param name="section" select="$section"/>
+ <xsl:with-param name="lang" select="$lang"/>
+ </xsl:call-template>
+ </xsl:with-param>
+ <xsl:with-param name="quiet" select="$man.output.quietly"/>
+ <xsl:with-param name="suppress-context-node-name" select="1"/>
+ <xsl:with-param name="message-prolog">Note: </xsl:with-param>
+ <xsl:with-param name="message-epilog"> (soelim stub)</xsl:with-param>
+ <xsl:with-param name="content">
+ <xsl:choose>
+ <xsl:when test="$man.output.in.separate.dir = 0">
+ <xsl:value-of select="concat('.so man', $section, '/')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="'.so '"/> <!-- added case -->
+ </xsl:otherwise>
+ </xsl:choose>
+ <xsl:call-template name="make.adjusted.man.filename">
+ <xsl:with-param name="name" select="$first.refname"/>
+ <xsl:with-param name="section" select="$section"/>
+ </xsl:call-template>
+ <xsl:text>&#10;</xsl:text>
+ </xsl:with-param>
+ </xsl:call-template>
+ </xsl:if>
+ </xsl:for-each>
+ </xsl:template>
+
+
+ <!-- https://sourceforge.net/tracker/?func=detail&aid=3545150&group_id=21935&atid=373747 -->
+ <xsl:template match="step/title">
+ <xsl:apply-templates/>
+ <xsl:text>: </xsl:text>
+ </xsl:template>
+
+
+ <!-- http://sourceforge.net/p/docbook/bugs/1340/ -->
+ <xsl:template match="indexterm"/>
+
+
+<!-- https://github.com/docbook/xslt10-stylesheets/issues/59 -->
+<xsl:template match="a/sup">
+ <xsl:apply-templates/>
+</xsl:template>
+
+
+<!-- Gentext customization -->
+
+<!-- see http://www.sagehill.net/docbookxsl/CustomGentext.html -->
+<xsl:param name="local.l10n.xml" select="document('')"/>
+<l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
+ <l:l10n language="en">
+ <!-- Use ISO 8601 date format. -->
+ <l:context name="datetime">
+ <l:template name="format" text="Y-m-d"/>
+ </l:context>
+
+ <!-- Slight rephrasing to indicate that missing sections are found
+ in the documentation. -->
+ <l:context name="xref-number-and-title">
+ <l:template name="chapter" text="Chapter %n, %t, in the documentation"/>
+ <l:template name="sect1" text="Section %n, “%t”, in the documentation"/>
+ <l:template name="sect2" text="Section %n, “%t”, in the documentation"/>
+ <l:template name="sect3" text="Section %n, “%t”, in the documentation"/>
+ <l:template name="sect4" text="Section %n, “%t”, in the documentation"/>
+ <l:template name="sect5" text="Section %n, “%t”, in the documentation"/>
+ </l:context>
+ </l:l10n>
+</l:i18n>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-speedup-common.xsl b/doc/src/sgml/stylesheet-speedup-common.xsl
new file mode 100644
index 0000000..e3fb582
--- /dev/null
+++ b/doc/src/sgml/stylesheet-speedup-common.xsl
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'>
+
+<!-- Performance-optimized versions of some upstream templates from common/
+ directory -->
+
+<!-- from common/labels.xsl -->
+
+<xsl:template match="chapter" mode="label.markup">
+ <xsl:choose>
+ <xsl:when test="@label">
+ <xsl:value-of select="@label"/>
+ </xsl:when>
+ <xsl:when test="string($chapter.autolabel) != 0">
+ <xsl:if test="$component.label.includes.part.label != 0 and
+ ancestor::part">
+ <xsl:variable name="part.label">
+ <xsl:apply-templates select="ancestor::part"
+ mode="label.markup"/>
+ </xsl:variable>
+ <xsl:if test="$part.label != ''">
+ <xsl:value-of select="$part.label"/>
+ <xsl:apply-templates select="ancestor::part"
+ mode="intralabel.punctuation">
+ <xsl:with-param name="object" select="."/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:if>
+ <xsl:variable name="format">
+ <xsl:call-template name="autolabel.format">
+ <xsl:with-param name="format" select="$chapter.autolabel"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$label.from.part != 0 and ancestor::part">
+ <xsl:number from="part" count="chapter" format="{$format}" level="any"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- Optimization for pgsql-docs: When counting to get label for
+ this chapter, preceding chapters can only be our siblings or
+ children of a preceding part, so only count those instead of
+ scanning the entire node tree. -->
+ <!-- <xsl:number from="book" count="chapter" format="{$format}" level="any"/> -->
+ <xsl:number value="count(../preceding-sibling::part/chapter) + count(preceding-sibling::chapter) + 1" format="{$format}"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template match="appendix" mode="label.markup">
+ <xsl:choose>
+ <xsl:when test="@label">
+ <xsl:value-of select="@label"/>
+ </xsl:when>
+ <xsl:when test="string($appendix.autolabel) != 0">
+ <xsl:if test="$component.label.includes.part.label != 0 and
+ ancestor::part">
+ <xsl:variable name="part.label">
+ <xsl:apply-templates select="ancestor::part"
+ mode="label.markup"/>
+ </xsl:variable>
+ <xsl:if test="$part.label != ''">
+ <xsl:value-of select="$part.label"/>
+ <xsl:apply-templates select="ancestor::part"
+ mode="intralabel.punctuation">
+ <xsl:with-param name="object" select="."/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:if>
+ <xsl:variable name="format">
+ <xsl:call-template name="autolabel.format">
+ <xsl:with-param name="format" select="$appendix.autolabel"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$label.from.part != 0 and ancestor::part">
+ <xsl:number from="part" count="appendix" format="{$format}" level="any"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <!-- Optimization for pgsql-docs: When counting to get label for
+ this appendix, preceding appendixes can only be our siblings or
+ children of a preceding part, so only count those instead of
+ scanning the entire node tree. -->
+ <!-- <xsl:number from="book|article" count="appendix" format="{$format}" level="any"/> -->
+ <xsl:number value="count(../preceding-sibling::part/appendix) + count(preceding-sibling::appendix) + 1" format="{$format}"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<!-- from common/l10n.xsl -->
+
+<!-- Just hardcode the language for the whole document, to make it faster. -->
+
+<xsl:template name="l10n.language">en</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-speedup-xhtml.xsl b/doc/src/sgml/stylesheet-speedup-xhtml.xsl
new file mode 100644
index 0000000..da0f2b5
--- /dev/null
+++ b/doc/src/sgml/stylesheet-speedup-xhtml.xsl
@@ -0,0 +1,345 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://www.w3.org/1999/xhtml"
+ version='1.0'>
+
+<!-- Performance-optimized versions of some upstream templates from xhtml/
+ directory -->
+
+<!-- from xhtml/autoidx.xsl -->
+
+<xsl:template match="indexterm" mode="reference">
+ <xsl:param name="scope" select="."/>
+ <xsl:param name="role" select="''"/>
+ <xsl:param name="type" select="''"/>
+ <xsl:param name="position"/>
+ <xsl:param name="separator" select="''"/>
+
+ <xsl:variable name="term.separator">
+ <xsl:call-template name="index.separator">
+ <xsl:with-param name="key" select="'index.term.separator'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="number.separator">
+ <xsl:call-template name="index.separator">
+ <xsl:with-param name="key" select="'index.number.separator'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:variable name="range.separator">
+ <xsl:call-template name="index.separator">
+ <xsl:with-param name="key" select="'index.range.separator'"/>
+ </xsl:call-template>
+ </xsl:variable>
+
+ <xsl:choose>
+ <xsl:when test="$separator != ''">
+ <xsl:value-of select="$separator"/>
+ </xsl:when>
+ <xsl:when test="$position = 1">
+ <xsl:value-of select="$term.separator"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$number.separator"/>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:choose>
+ <xsl:when test="@zone and string(@zone)">
+ <xsl:call-template name="reference">
+ <xsl:with-param name="zones" select="normalize-space(@zone)"/>
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <a>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+ <xsl:variable name="title">
+ <xsl:choose>
+ <xsl:when test="$index.prefer.titleabbrev != 0">
+ <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="titleabbrev.markup"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]" mode="title.markup"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+
+ <xsl:attribute name="href">
+ <xsl:choose>
+ <xsl:when test="$index.links.to.section = 1">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="(ancestor-or-self::set|ancestor-or-self::book|ancestor-or-self::part|ancestor-or-self::reference|ancestor-or-self::partintro|ancestor-or-self::chapter|ancestor-or-self::appendix|ancestor-or-self::preface|ancestor-or-self::article|ancestor-or-self::section|ancestor-or-self::sect1|ancestor-or-self::sect2|ancestor-or-self::sect3|ancestor-or-self::sect4|ancestor-or-self::sect5|ancestor-or-self::refentry|ancestor-or-self::refsect1|ancestor-or-self::refsect2|ancestor-or-self::refsect3|ancestor-or-self::simplesect|ancestor-or-self::bibliography|ancestor-or-self::glossary|ancestor-or-self::index|ancestor-or-self::webpage|ancestor-or-self::topic)[last()]"/>
+ <!-- Optimization for pgsql-docs: We only have an index as a
+ child of book, so look that up directly instead of
+ scanning the entire node tree. Also, don't look for
+ setindex. -->
+ <!-- <xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/> -->
+ <xsl:with-param name="context" select="(/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="."/>
+ <xsl:with-param name="context" select="(//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))] | //setindex[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))])[1]"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+
+ </xsl:attribute>
+
+ <xsl:value-of select="$title"/> <!-- text only -->
+ </a>
+
+ <xsl:variable name="id" select="(@id|@xml:id)[1]"/>
+ <xsl:if test="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))]">
+ <xsl:apply-templates select="key('endofrange', $id)[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][last()]" mode="reference">
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ <xsl:with-param name="separator" select="$range.separator"/>
+ </xsl:apply-templates>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="reference">
+ <xsl:param name="scope" select="."/>
+ <xsl:param name="role" select="''"/>
+ <xsl:param name="type" select="''"/>
+ <xsl:param name="zones"/>
+
+ <xsl:choose>
+ <xsl:when test="contains($zones, ' ')">
+ <xsl:variable name="zone" select="substring-before($zones, ' ')"/>
+ <xsl:variable name="target" select="key('sections', $zone)"/>
+
+ <a>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+<!-- Optimization for pgsql-docs: this call adds nothing but fails with docbook-xsl 1.76 -->
+<!-- <xsl:call-template name="id.attribute"/> -->
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$target[1]"/>
+ <xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
+ </a>
+ <xsl:text>, </xsl:text>
+ <xsl:call-template name="reference">
+ <xsl:with-param name="zones" select="substring-after($zones, ' ')"/>
+ <xsl:with-param name="position" select="position()"/>
+ <xsl:with-param name="scope" select="$scope"/>
+ <xsl:with-param name="role" select="$role"/>
+ <xsl:with-param name="type" select="$type"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="zone" select="$zones"/>
+ <xsl:variable name="target" select="key('sections', $zone)"/>
+
+ <a>
+ <xsl:apply-templates select="." mode="class.attribute"/>
+<!-- Optimization for pgsql-docs: this call adds nothing but fails with docbook-xsl 1.76 -->
+<!-- <xsl:call-template name="id.attribute"/> -->
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$target[1]"/>
+ <!-- Optimization for pgsql-docs: Only look for index under book
+ instead of searching the whole node tree. -->
+ <!-- <xsl:with-param name="context" select="//index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/> -->
+ <xsl:with-param name="context" select="/book/index[count(ancestor::node()|$scope) = count(ancestor::node()) and ($role = @role or $type = @type or (string-length($role) = 0 and string-length($type) = 0))][1]"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:apply-templates select="$target[1]" mode="index-title-content"/>
+ </a>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<!-- from xhtml/chunk-common.xsl -->
+
+<xsl:template name="chunk-all-sections">
+ <xsl:param name="content">
+ <xsl:apply-imports/>
+ </xsl:param>
+
+ <!-- Optimization for pgsql-docs: Since we set a fixed $chunk.section.depth,
+ we can do away with a bunch of complicated XPath searches for the
+ previous and next sections at various levels. -->
+
+ <xsl:if test="$chunk.section.depth != 1">
+ <xsl:message terminate="yes">
+ <xsl:text>Error: If you change $chunk.section.depth, then you must update the performance-optimized chunk-all-sections-template.</xsl:text>
+ </xsl:message>
+ </xsl:if>
+
+ <xsl:variable name="prev"
+ select="(preceding::book[1]
+ |preceding::preface[1]
+ |preceding::chapter[1]
+ |preceding::appendix[1]
+ |preceding::part[1]
+ |preceding::reference[1]
+ |preceding::refentry[1]
+ |preceding::colophon[1]
+ |preceding::article[1]
+ |preceding::topic[1]
+ |preceding::bibliography[parent::article or parent::book or parent::part][1]
+ |preceding::glossary[parent::article or parent::book or parent::part][1]
+ |preceding::index[$generate.index != 0]
+ [parent::article or parent::book or parent::part][1]
+ |preceding::setindex[$generate.index != 0][1]
+ |ancestor::set
+ |ancestor::book[1]
+ |ancestor::preface[1]
+ |ancestor::chapter[1]
+ |ancestor::appendix[1]
+ |ancestor::part[1]
+ |ancestor::reference[1]
+ |ancestor::article[1]
+ |ancestor::topic[1]
+ |preceding::sect1[1]
+ |ancestor::sect1[1])[last()]"/>
+
+ <xsl:variable name="next"
+ select="(following::book[1]
+ |following::preface[1]
+ |following::chapter[1]
+ |following::appendix[1]
+ |following::part[1]
+ |following::reference[1]
+ |following::refentry[1]
+ |following::colophon[1]
+ |following::bibliography[parent::article or parent::book or parent::part][1]
+ |following::glossary[parent::article or parent::book or parent::part][1]
+ |following::index[$generate.index != 0]
+ [parent::article or parent::book][1]
+ |following::article[1]
+ |following::topic[1]
+ |following::setindex[$generate.index != 0][1]
+ |descendant::book[1]
+ |descendant::preface[1]
+ |descendant::chapter[1]
+ |descendant::appendix[1]
+ |descendant::article[1]
+ |descendant::topic[1]
+ |descendant::bibliography[parent::article or parent::book][1]
+ |descendant::glossary[parent::article or parent::book or parent::part][1]
+ |descendant::index[$generate.index != 0]
+ [parent::article or parent::book][1]
+ |descendant::colophon[1]
+ |descendant::setindex[$generate.index != 0][1]
+ |descendant::part[1]
+ |descendant::reference[1]
+ |descendant::refentry[1]
+ |following::sect1[1]
+ |descendant::sect1[1])[1]"/>
+
+ <xsl:call-template name="process-chunk">
+ <xsl:with-param name="prev" select="$prev"/>
+ <xsl:with-param name="next" select="$next"/>
+ <xsl:with-param name="content" select="$content"/>
+ </xsl:call-template>
+</xsl:template>
+
+<xsl:template name="href.target">
+ <xsl:param name="context" select="."/>
+ <xsl:param name="object" select="."/>
+ <xsl:param name="toc-context" select="."/>
+ <!-- Optimization for pgsql-docs: Remove support for dbhtml processing
+ instruction here -->
+ <xsl:variable name="href.to.uri">
+ <xsl:call-template name="href.target.uri">
+ <xsl:with-param name="object" select="$object"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="href.from.uri">
+ <xsl:choose>
+ <xsl:when test="not($toc-context = .)">
+ <xsl:call-template name="href.target.uri">
+ <xsl:with-param name="object" select="$toc-context"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="href.target.uri">
+ <xsl:with-param name="object" select="$context"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="href.to">
+ <xsl:value-of select="$href.to.uri"/>
+ </xsl:variable>
+ <xsl:variable name="href.from">
+ <xsl:call-template name="trim.common.uri.paths">
+ <xsl:with-param name="uriA" select="$href.to.uri"/>
+ <xsl:with-param name="uriB" select="$href.from.uri"/>
+ <xsl:with-param name="return" select="'B'"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="depth">
+ <xsl:call-template name="count.uri.path.depth">
+ <xsl:with-param name="filename" select="$href.from"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="href">
+ <xsl:call-template name="copy-string">
+ <xsl:with-param name="string" select="'../'"/>
+ <xsl:with-param name="count" select="$depth"/>
+ </xsl:call-template>
+ <xsl:value-of select="$href.to"/>
+ </xsl:variable>
+ <xsl:value-of select="$href"/>
+</xsl:template>
+
+<xsl:template name="html.head">
+ <xsl:param name="prev" select="/foo"/>
+ <xsl:param name="next" select="/foo"/>
+
+ <!-- Optimization for pgsql-docs: Cut out a bunch of things we don't need
+ here, including an expensive //legalnotice search. -->
+
+ <head>
+ <xsl:call-template name="system.head.content"/>
+ <xsl:call-template name="head.content"/>
+
+ <xsl:if test="$prev">
+ <link rel="prev">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$prev"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$prev" mode="object.title.markup.textonly"/>
+ </xsl:attribute>
+ </link>
+ </xsl:if>
+
+ <xsl:if test="$next">
+ <link rel="next">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$next"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$next" mode="object.title.markup.textonly"/>
+ </xsl:attribute>
+ </link>
+ </xsl:if>
+
+ <xsl:call-template name="user.head.content"/>
+ </head>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet-text.xsl b/doc/src/sgml/stylesheet-text.xsl
new file mode 100644
index 0000000..529cc9e
--- /dev/null
+++ b/doc/src/sgml/stylesheet-text.xsl
@@ -0,0 +1,97 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'
+ xmlns="http://www.w3.org/1999/xhtml">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"/>
+<xsl:import href="stylesheet-common.xsl" />
+
+<!-- The customizations here are somewhat random in order to make the text
+ output look good. -->
+
+<!-- no section numbers or ToC -->
+<xsl:param name="chapter.autolabel" select="0"/>
+<xsl:param name="section.autolabel" select="0"/>
+<xsl:param name="generate.toc"></xsl:param>
+
+<!-- don't need them, and they mess up formatting -->
+<xsl:template match="indexterm">
+</xsl:template>
+
+<xsl:template match="step">
+ <li>
+ <xsl:call-template name="common.html.attributes"/>
+ <xsl:call-template name="id.attribute"/>
+<!-- messes up formatting
+ <xsl:call-template name="anchor"/>
+-->
+ <xsl:apply-templates/>
+ </li>
+</xsl:template>
+
+<!-- produce "ASCII markup" for emphasis and such -->
+
+<xsl:template match="emphasis">
+ <xsl:text>*</xsl:text>
+ <xsl:apply-templates/>
+ <xsl:text>*</xsl:text>
+</xsl:template>
+
+<xsl:template match="para/command|para/filename|para/option|para/replaceable">
+ <xsl:call-template name="gentext.startquote"/>
+ <xsl:apply-templates/>
+ <xsl:call-template name="gentext.endquote"/>
+</xsl:template>
+
+<xsl:template match="filename/replaceable|firstterm">
+ <xsl:apply-templates/>
+</xsl:template>
+
+<!-- tweak formatting for note, warning, etc. -->
+<xsl:template name="nongraphical.admonition">
+ <div>
+ <xsl:call-template name="common.html.attributes">
+ <xsl:with-param name="inherit" select="1"/>
+ </xsl:call-template>
+ <xsl:call-template name="id.attribute"/>
+
+ <xsl:if test="$admon.textlabel != 0 or title or info/title">
+ <p>
+ <b>
+ <xsl:call-template name="anchor"/>
+ <xsl:apply-templates select="." mode="object.title.markup"/>:
+ </b>
+ </p>
+ </xsl:if>
+
+ <xsl:apply-templates/>
+ </div>
+</xsl:template>
+
+<!-- horizontal rules before titles (matches old DSSSL style) -->
+
+<xsl:template match="sect1/title
+ |sect1/info/title
+ |sect1info/title"
+ mode="titlepage.mode" priority="2">
+ <hr/>
+ <xsl:call-template name="section.title"/>
+</xsl:template>
+
+<xsl:template match="sect2/title
+ |sect2/info/title
+ |sect2info/title"
+ mode="titlepage.mode" priority="2">
+ <hr/>
+ <xsl:call-template name="section.title"/>
+</xsl:template>
+
+<xsl:template match="sect3/title
+ |sect3/info/title
+ |sect3info/title"
+ mode="titlepage.mode" priority="2">
+ <hr/>
+ <xsl:call-template name="section.title"/>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/stylesheet.css b/doc/src/sgml/stylesheet.css
new file mode 100644
index 0000000..6410a47
--- /dev/null
+++ b/doc/src/sgml/stylesheet.css
@@ -0,0 +1,165 @@
+/* doc/src/sgml/stylesheet.css */
+
+/* color scheme similar to www.postgresql.org */
+
+body {
+ color: #000000;
+ background: #FFFFFF;
+ font-family: verdana, sans-serif;
+}
+
+a:link { color:#0066A2; }
+a:visited { color:#004E66; }
+a:active { color:#0066A2; }
+a:hover { color:#000000; }
+
+h1 {
+ font-size: 1.4em;
+ font-weight: bold;
+ margin-top: 0em;
+ margin-bottom: 0em;
+ color: #EC5800;
+}
+
+h2 {
+ font-size: 1.2em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: bold;
+ color: #666;
+}
+
+.titlepage h2.title,
+.refnamediv h2 {
+ color: #EC5800;
+}
+
+h3 {
+ font-size: 1.1em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: bold;
+ color: #666;
+}
+
+h4 {
+ font-size: 0.95em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: normal;
+ color: #666;
+}
+
+h5 {
+ font-size: 0.9em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: normal;
+}
+
+h6 {
+ font-size: 0.85em;
+ margin: 1.2em 0em 1.2em 0em;
+ font-weight: normal;
+}
+
+/* center some titles */
+
+.book .title, .book .corpauthor, .book .copyright {
+ text-align: center;
+}
+
+/* decoration for formal examples */
+
+div.example {
+ padding-left: 15px;
+ border-style: solid;
+ border-width: 0px;
+ border-left-width: 2px;
+ border-color: black;
+ margin: 0.5ex;
+}
+
+/* formatting for entries in tables of functions: indent all but first line */
+
+th.func_table_entry p,
+td.func_table_entry p {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+ text-align: left;
+}
+
+p.func_signature {
+ text-indent: -3.5em;
+}
+
+td.func_table_entry pre.programlisting {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+}
+
+/* formatting for entries in tables of catalog/view columns */
+
+th.catalog_table_entry p,
+td.catalog_table_entry p {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+ text-align: left;
+}
+
+th.catalog_table_entry p.column_definition {
+ text-indent: -3.5em;
+ word-spacing: 0.25em;
+}
+
+td.catalog_table_entry p.column_definition {
+ text-indent: -3.5em;
+}
+
+p.column_definition code.type {
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+}
+
+td.catalog_table_entry pre.programlisting {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+ padding-left: 4em;
+}
+
+/* Put these here instead of inside the HTML (see unsetting of
+ admon.style in XSL) so that the web site stylesheet can set its own
+ style. */
+
+.tip,
+.note,
+.important,
+.caution,
+.warning {
+ margin-left: 0.5in;
+ margin-right: 0.5in;
+}
+
+/* miscellaneous */
+
+pre.literallayout, .screen, .synopsis, .programlisting {
+ margin-left: 4ex;
+}
+
+ul.itemizedlist {
+ margin-left: 2.5rem;
+}
+
+.comment { color: red; }
+
+var { font-family: monospace; font-style: italic; }
+/* Konqueror's standard style for ACRONYM is italic. */
+acronym { font-style: inherit; }
+
+.option { white-space: nowrap; }
+
+/* make images not too wide on larger screens */
+@media (min-width: 800px) {
+ .mediaobject {
+ width: 75%;
+ }
+}
diff --git a/doc/src/sgml/stylesheet.xsl b/doc/src/sgml/stylesheet.xsl
new file mode 100644
index 0000000..b614130
--- /dev/null
+++ b/doc/src/sgml/stylesheet.xsl
@@ -0,0 +1,330 @@
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version='1.0'
+ xmlns="http://www.w3.org/1999/xhtml">
+
+<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/>
+<xsl:include href="stylesheet-common.xsl" />
+<xsl:include href="stylesheet-html-common.xsl" />
+<xsl:include href="stylesheet-speedup-xhtml.xsl" />
+
+
+<!-- Parameters -->
+<xsl:param name="base.dir" select="'html/'"></xsl:param>
+<xsl:param name="use.id.as.filename" select="'1'"></xsl:param>
+<xsl:param name="generate.legalnotice.link" select="1"></xsl:param>
+<xsl:param name="chunk.first.sections" select="1"/>
+<xsl:param name="chunk.quietly" select="1"></xsl:param>
+<xsl:param name="admon.style"></xsl:param> <!-- handled by CSS stylesheet -->
+
+<xsl:param name="website.stylesheet" select="0"/>
+
+<xsl:param name="html.stylesheet">
+ <xsl:choose>
+ <xsl:when test="$website.stylesheet = 0">stylesheet.css</xsl:when>
+ <xsl:otherwise>
+ https://www.postgresql.org/media/css/docs-complete.css
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:param>
+
+
+<!-- strip directory name from image filerefs -->
+<xsl:template match="imagedata/@fileref">
+ <xsl:value-of select="substring-after(., '/')"/>
+</xsl:template>
+
+
+<!--
+Customization of header
+- add Up and Home links
+- add tool tips to links
+
+(overrides html/chunk-common.xsl)
+-->
+<xsl:template name="header.navigation">
+ <xsl:param name="prev" select="/foo"/>
+ <xsl:param name="next" select="/foo"/>
+ <xsl:param name="nav.context"/>
+
+ <xsl:variable name="home" select="/*[1]"/>
+ <xsl:variable name="up" select="parent::*"/>
+
+ <xsl:variable name="row1" select="$navig.showtitles != 0"/>
+ <xsl:variable name="row2" select="count($prev) &gt; 0
+ or (count($up) &gt; 0
+ and $navig.showtitles != 0)
+ or count($next) &gt; 0"/>
+
+ <xsl:if test="$suppress.navigation = '0' and $suppress.header.navigation = '0'">
+ <div class="navheader">
+ <xsl:if test="$row1 or $row2">
+ <table width="100%" summary="Navigation header">
+ <xsl:if test="$row1">
+ <tr>
+ <th colspan="5" align="center">
+ <xsl:apply-templates select="." mode="object.title.markup"/>
+ </th>
+ </tr>
+ </xsl:if>
+
+ <xsl:if test="$row2">
+ <tr>
+ <td width="10%" align="{$direction.align.start}">
+ <xsl:if test="count($prev)>0">
+ <a accesskey="p">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$prev"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$prev" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'prev'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ <td width="10%" align="{$direction.align.start}">
+ <xsl:choose>
+ <xsl:when test="count($up)&gt;0">
+ <a accesskey="u">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$up"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$up" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'up'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>&#160;</xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <th width="60%" align="center">
+ <xsl:choose>
+ <xsl:when test="count($up) > 0
+ and $navig.showtitles != 0">
+ <xsl:apply-templates select="$up" mode="object.title.markup"/>
+ </xsl:when>
+ <xsl:otherwise>&#160;</xsl:otherwise>
+ </xsl:choose>
+ </th>
+ <td width="10%" align="{$direction.align.end}">
+ <xsl:choose>
+ <xsl:when test="$home != . or $nav.context = 'toc'">
+ <a accesskey="h">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$home"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$home" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'home'"/>
+ </xsl:call-template>
+ </a>
+ <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
+ <xsl:text>&#160;|&#160;</xsl:text>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>&#160;</xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td width="10%" align="{$direction.align.end}">
+ <xsl:text>&#160;</xsl:text>
+ <xsl:if test="count($next)>0">
+ <a accesskey="n">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$next"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$next" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'next'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+ </td>
+ </tr>
+ </xsl:if>
+ </table>
+ </xsl:if>
+ <xsl:if test="$header.rule != 0">
+ <hr/>
+ </xsl:if>
+ </div>
+ </xsl:if>
+</xsl:template>
+
+
+<!--
+Customization of footer
+- don't hide redundant Up link
+- add tool tips to links
+
+(overrides html/chunk-common.xsl)
+-->
+<xsl:template name="footer.navigation">
+ <xsl:param name="prev" select="/foo"/>
+ <xsl:param name="next" select="/foo"/>
+ <xsl:param name="nav.context"/>
+
+ <xsl:variable name="home" select="/*[1]"/>
+ <xsl:variable name="up" select="parent::*"/>
+
+ <xsl:variable name="row1" select="count($prev) &gt; 0
+ or count($up) &gt; 0
+ or count($next) &gt; 0"/>
+
+ <xsl:variable name="row2" select="($prev and $navig.showtitles != 0)
+ or (generate-id($home) != generate-id(.)
+ or $nav.context = 'toc')
+ or ($chunk.tocs.and.lots != 0
+ and $nav.context != 'toc')
+ or ($next and $navig.showtitles != 0)"/>
+
+ <xsl:if test="$suppress.navigation = '0' and $suppress.footer.navigation = '0'">
+ <div class="navfooter">
+ <xsl:if test="$footer.rule != 0">
+ <hr/>
+ </xsl:if>
+
+ <xsl:if test="$row1 or $row2">
+ <table width="100%" summary="Navigation footer">
+ <xsl:if test="$row1">
+ <tr>
+ <td width="40%" align="{$direction.align.start}">
+ <xsl:if test="count($prev)>0">
+ <a accesskey="p">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$prev"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$prev" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'prev'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ <td width="20%" align="center">
+ <xsl:choose>
+ <xsl:when test="count($up)&gt;0">
+ <a accesskey="u">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$up"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$up" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'up'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:when>
+ <xsl:otherwise>&#160;</xsl:otherwise>
+ </xsl:choose>
+ </td>
+ <td width="40%" align="{$direction.align.end}">
+ <xsl:text>&#160;</xsl:text>
+ <xsl:if test="count($next)>0">
+ <a accesskey="n">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$next"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$next" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'next'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+ </td>
+ </tr>
+ </xsl:if>
+
+ <xsl:if test="$row2">
+ <tr>
+ <td width="40%" align="{$direction.align.start}" valign="top">
+ <xsl:if test="$navig.showtitles != 0">
+ <xsl:apply-templates select="$prev" mode="object.title.markup"/>
+ </xsl:if>
+ <xsl:text>&#160;</xsl:text>
+ </td>
+ <td width="20%" align="center">
+ <xsl:choose>
+ <xsl:when test="$home != . or $nav.context = 'toc'">
+ <a accesskey="h">
+ <xsl:attribute name="href">
+ <xsl:call-template name="href.target">
+ <xsl:with-param name="object" select="$home"/>
+ </xsl:call-template>
+ </xsl:attribute>
+ <xsl:attribute name="title">
+ <xsl:apply-templates select="$home" mode="object.title.markup"/>
+ </xsl:attribute>
+ <xsl:call-template name="navig.content">
+ <xsl:with-param name="direction" select="'home'"/>
+ </xsl:call-template>
+ </a>
+ <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
+ <xsl:text>&#160;|&#160;</xsl:text>
+ </xsl:if>
+ </xsl:when>
+ <xsl:otherwise>&#160;</xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:if test="$chunk.tocs.and.lots != 0 and $nav.context != 'toc'">
+ <a accesskey="t">
+ <xsl:attribute name="href">
+ <xsl:value-of select="$chunked.filename.prefix"/>
+ <xsl:apply-templates select="/*[1]"
+ mode="recursive-chunk-filename">
+ <xsl:with-param name="recursive" select="true()"/>
+ </xsl:apply-templates>
+ <xsl:text>-toc</xsl:text>
+ <xsl:value-of select="$html.ext"/>
+ </xsl:attribute>
+ <xsl:call-template name="gentext">
+ <xsl:with-param name="key" select="'nav-toc'"/>
+ </xsl:call-template>
+ </a>
+ </xsl:if>
+ </td>
+ <td width="40%" align="{$direction.align.end}" valign="top">
+ <xsl:text>&#160;</xsl:text>
+ <xsl:if test="$navig.showtitles != 0">
+ <xsl:apply-templates select="$next" mode="object.title.markup"/>
+ </xsl:if>
+ </td>
+ </tr>
+ </xsl:if>
+ </table>
+ </xsl:if>
+ </div>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/doc/src/sgml/syntax.sgml b/doc/src/sgml/syntax.sgml
new file mode 100644
index 0000000..a99c243
--- /dev/null
+++ b/doc/src/sgml/syntax.sgml
@@ -0,0 +1,2737 @@
+<!-- doc/src/sgml/syntax.sgml -->
+
+<chapter id="sql-syntax">
+ <title>SQL Syntax</title>
+
+ <indexterm zone="sql-syntax">
+ <primary>syntax</primary>
+ <secondary>SQL</secondary>
+ </indexterm>
+
+ <para>
+ This chapter describes the syntax of SQL. It forms the foundation
+ for understanding the following chapters which will go into detail
+ about how SQL commands are applied to define and modify data.
+ </para>
+
+ <para>
+ We also advise users who are already familiar with SQL to read this
+ chapter carefully because it contains several rules and concepts that
+ are implemented inconsistently among SQL databases or that are
+ specific to <productname>PostgreSQL</productname>.
+ </para>
+
+ <sect1 id="sql-syntax-lexical">
+ <title>Lexical Structure</title>
+
+ <indexterm>
+ <primary>token</primary>
+ </indexterm>
+
+ <para>
+ SQL input consists of a sequence of
+ <firstterm>commands</firstterm>. A command is composed of a
+ sequence of <firstterm>tokens</firstterm>, terminated by a
+ semicolon (<quote>;</quote>). The end of the input stream also
+ terminates a command. Which tokens are valid depends on the syntax
+ of the particular command.
+ </para>
+
+ <para>
+ A token can be a <firstterm>key word</firstterm>, an
+ <firstterm>identifier</firstterm>, a <firstterm>quoted
+ identifier</firstterm>, a <firstterm>literal</firstterm> (or
+ constant), or a special character symbol. Tokens are normally
+ separated by whitespace (space, tab, newline), but need not be if
+ there is no ambiguity (which is generally only the case if a
+ special character is adjacent to some other token type).
+ </para>
+
+ <para>
+ For example, the following is (syntactically) valid SQL input:
+<programlisting>
+SELECT * FROM MY_TABLE;
+UPDATE MY_TABLE SET A = 5;
+INSERT INTO MY_TABLE VALUES (3, 'hi there');
+</programlisting>
+ This is a sequence of three commands, one per line (although this
+ is not required; more than one command can be on a line, and
+ commands can usefully be split across lines).
+ </para>
+
+ <para>
+ Additionally, <firstterm>comments</firstterm> can occur in SQL
+ input. They are not tokens, they are effectively equivalent to
+ whitespace.
+ </para>
+
+ <para>
+ The SQL syntax is not very consistent regarding what tokens
+ identify commands and which are operands or parameters. The first
+ few tokens are generally the command name, so in the above example
+ we would usually speak of a <quote>SELECT</quote>, an
+ <quote>UPDATE</quote>, and an <quote>INSERT</quote> command. But
+ for instance the <command>UPDATE</command> command always requires
+ a <token>SET</token> token to appear in a certain position, and
+ this particular variation of <command>INSERT</command> also
+ requires a <token>VALUES</token> in order to be complete. The
+ precise syntax rules for each command are described in <xref linkend="reference"/>.
+ </para>
+
+ <sect2 id="sql-syntax-identifiers">
+ <title>Identifiers and Key Words</title>
+
+ <indexterm zone="sql-syntax-identifiers">
+ <primary>identifier</primary>
+ <secondary>syntax of</secondary>
+ </indexterm>
+
+ <indexterm zone="sql-syntax-identifiers">
+ <primary>name</primary>
+ <secondary>syntax of</secondary>
+ </indexterm>
+
+ <indexterm zone="sql-syntax-identifiers">
+ <primary>key word</primary>
+ <secondary>syntax of</secondary>
+ </indexterm>
+
+ <para>
+ Tokens such as <token>SELECT</token>, <token>UPDATE</token>, or
+ <token>VALUES</token> in the example above are examples of
+ <firstterm>key words</firstterm>, that is, words that have a fixed
+ meaning in the SQL language. The tokens <token>MY_TABLE</token>
+ and <token>A</token> are examples of
+ <firstterm>identifiers</firstterm>. They identify names of
+ tables, columns, or other database objects, depending on the
+ command they are used in. Therefore they are sometimes simply
+ called <quote>names</quote>. Key words and identifiers have the
+ same lexical structure, meaning that one cannot know whether a
+ token is an identifier or a key word without knowing the language.
+ A complete list of key words can be found in <xref
+ linkend="sql-keywords-appendix"/>.
+ </para>
+
+ <para>
+ SQL identifiers and key words must begin with a letter
+ (<literal>a</literal>-<literal>z</literal>, but also letters with
+ diacritical marks and non-Latin letters) or an underscore
+ (<literal>_</literal>). Subsequent characters in an identifier or
+ key word can be letters, underscores, digits
+ (<literal>0</literal>-<literal>9</literal>), or dollar signs
+ (<literal>$</literal>). Note that dollar signs are not allowed in identifiers
+ according to the letter of the SQL standard, so their use might render
+ applications less portable.
+ The SQL standard will not define a key word that contains
+ digits or starts or ends with an underscore, so identifiers of this
+ form are safe against possible conflict with future extensions of the
+ standard.
+ </para>
+
+ <para>
+ <indexterm><primary>identifier</primary><secondary>length</secondary></indexterm>
+ The system uses no more than <symbol>NAMEDATALEN</symbol>-1
+ bytes of an identifier; longer names can be written in
+ commands, but they will be truncated. By default,
+ <symbol>NAMEDATALEN</symbol> is 64 so the maximum identifier
+ length is 63 bytes. If this limit is problematic, it can be raised by
+ changing the <symbol>NAMEDATALEN</symbol> constant in
+ <filename>src/include/pg_config_manual.h</filename>.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>case sensitivity</primary>
+ <secondary>of SQL commands</secondary>
+ </indexterm>
+ Key words and unquoted identifiers are case insensitive. Therefore:
+<programlisting>
+UPDATE MY_TABLE SET A = 5;
+</programlisting>
+ can equivalently be written as:
+<programlisting>
+uPDaTE my_TabLE SeT a = 5;
+</programlisting>
+ A convention often used is to write key words in upper
+ case and names in lower case, e.g.:
+<programlisting>
+UPDATE my_table SET a = 5;
+</programlisting>
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>quotation marks</primary>
+ <secondary>and identifiers</secondary>
+ </indexterm>
+ There is a second kind of identifier: the <firstterm>delimited
+ identifier</firstterm> or <firstterm>quoted
+ identifier</firstterm>. It is formed by enclosing an arbitrary
+ sequence of characters in double-quotes
+ (<literal>"</literal>). <!-- " font-lock mania --> A delimited
+ identifier is always an identifier, never a key word. So
+ <literal>"select"</literal> could be used to refer to a column or
+ table named <quote>select</quote>, whereas an unquoted
+ <literal>select</literal> would be taken as a key word and
+ would therefore provoke a parse error when used where a table or
+ column name is expected. The example can be written with quoted
+ identifiers like this:
+<programlisting>
+UPDATE "my_table" SET "a" = 5;
+</programlisting>
+ </para>
+
+ <para>
+ Quoted identifiers can contain any character, except the character
+ with code zero. (To include a double quote, write two double quotes.)
+ This allows constructing table or column names that would
+ otherwise not be possible, such as ones containing spaces or
+ ampersands. The length limitation still applies.
+ </para>
+
+ <para>
+ Quoting an identifier also makes it case-sensitive, whereas
+ unquoted names are always folded to lower case. For example, the
+ identifiers <literal>FOO</literal>, <literal>foo</literal>, and
+ <literal>"foo"</literal> are considered the same by
+ <productname>PostgreSQL</productname>, but
+ <literal>"Foo"</literal> and <literal>"FOO"</literal> are
+ different from these three and each other. (The folding of
+ unquoted names to lower case in <productname>PostgreSQL</productname> is
+ incompatible with the SQL standard, which says that unquoted names
+ should be folded to upper case. Thus, <literal>foo</literal>
+ should be equivalent to <literal>"FOO"</literal> not
+ <literal>"foo"</literal> according to the standard. If you want
+ to write portable applications you are advised to always quote a
+ particular name or never quote it.)
+ </para>
+
+ <indexterm>
+ <primary>Unicode escape</primary>
+ <secondary>in identifiers</secondary>
+ </indexterm>
+
+ <para>
+ A variant of quoted
+ identifiers allows including escaped Unicode characters identified
+ by their code points. This variant starts
+ with <literal>U&amp;</literal> (upper or lower case U followed by
+ ampersand) immediately before the opening double quote, without
+ any spaces in between, for example <literal>U&amp;"foo"</literal>.
+ (Note that this creates an ambiguity with the
+ operator <literal>&amp;</literal>. Use spaces around the operator to
+ avoid this problem.) Inside the quotes, Unicode characters can be
+ specified in escaped form by writing a backslash followed by the
+ four-digit hexadecimal code point number or alternatively a
+ backslash followed by a plus sign followed by a six-digit
+ hexadecimal code point number. For example, the
+ identifier <literal>"data"</literal> could be written as
+<programlisting>
+U&amp;"d\0061t\+000061"
+</programlisting>
+ The following less trivial example writes the Russian
+ word <quote>slon</quote> (elephant) in Cyrillic letters:
+<programlisting>
+U&amp;"\0441\043B\043E\043D"
+</programlisting>
+ </para>
+
+ <para>
+ If a different escape character than backslash is desired, it can
+ be specified using
+ the <literal>UESCAPE</literal><indexterm><primary>UESCAPE</primary></indexterm>
+ clause after the string, for example:
+<programlisting>
+U&amp;"d!0061t!+000061" UESCAPE '!'
+</programlisting>
+ The escape character can be any single character other than a
+ hexadecimal digit, the plus sign, a single quote, a double quote,
+ or a whitespace character. Note that the escape character is
+ written in single quotes, not double quotes,
+ after <literal>UESCAPE</literal>.
+ </para>
+
+ <para>
+ To include the escape character in the identifier literally, write
+ it twice.
+ </para>
+
+ <para>
+ Either the 4-digit or the 6-digit escape form can be used to
+ specify UTF-16 surrogate pairs to compose characters with code
+ points larger than U+FFFF, although the availability of the
+ 6-digit form technically makes this unnecessary. (Surrogate
+ pairs are not stored directly, but are combined into a single
+ code point.)
+ </para>
+
+ <para>
+ If the server encoding is not UTF-8, the Unicode code point identified
+ by one of these escape sequences is converted to the actual server
+ encoding; an error is reported if that's not possible.
+ </para>
+ </sect2>
+
+
+ <sect2 id="sql-syntax-constants">
+ <title>Constants</title>
+
+ <indexterm zone="sql-syntax-constants">
+ <primary>constant</primary>
+ </indexterm>
+
+ <para>
+ There are three kinds of <firstterm>implicitly-typed
+ constants</firstterm> in <productname>PostgreSQL</productname>:
+ strings, bit strings, and numbers.
+ Constants can also be specified with explicit types, which can
+ enable more accurate representation and more efficient handling by
+ the system. These alternatives are discussed in the following
+ subsections.
+ </para>
+
+ <sect3 id="sql-syntax-strings">
+ <title>String Constants</title>
+
+ <indexterm zone="sql-syntax-strings">
+ <primary>character string</primary>
+ <secondary>constant</secondary>
+ </indexterm>
+
+ <para>
+ <indexterm>
+ <primary>quotation marks</primary>
+ <secondary>escaping</secondary>
+ </indexterm>
+ A string constant in SQL is an arbitrary sequence of characters
+ bounded by single quotes (<literal>'</literal>), for example
+ <literal>'This is a string'</literal>. To include
+ a single-quote character within a string constant,
+ write two adjacent single quotes, e.g.,
+ <literal>'Dianne''s horse'</literal>.
+ Note that this is <emphasis>not</emphasis> the same as a double-quote
+ character (<literal>"</literal>). <!-- font-lock sanity: " -->
+ </para>
+
+ <para>
+ Two string constants that are only separated by whitespace
+ <emphasis>with at least one newline</emphasis> are concatenated
+ and effectively treated as if the string had been written as one
+ constant. For example:
+<programlisting>
+SELECT 'foo'
+'bar';
+</programlisting>
+ is equivalent to:
+<programlisting>
+SELECT 'foobar';
+</programlisting>
+ but:
+<programlisting>
+SELECT 'foo' 'bar';
+</programlisting>
+ is not valid syntax. (This slightly bizarre behavior is specified
+ by <acronym>SQL</acronym>; <productname>PostgreSQL</productname> is
+ following the standard.)
+ </para>
+ </sect3>
+
+ <sect3 id="sql-syntax-strings-escape">
+ <title>String Constants with C-Style Escapes</title>
+
+ <indexterm zone="sql-syntax-strings-escape">
+ <primary>escape string syntax</primary>
+ </indexterm>
+ <indexterm zone="sql-syntax-strings-escape">
+ <primary>backslash escapes</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> also accepts <quote>escape</quote>
+ string constants, which are an extension to the SQL standard.
+ An escape string constant is specified by writing the letter
+ <literal>E</literal> (upper or lower case) just before the opening single
+ quote, e.g., <literal>E'foo'</literal>. (When continuing an escape string
+ constant across lines, write <literal>E</literal> only before the first opening
+ quote.)
+ Within an escape string, a backslash character (<literal>\</literal>) begins a
+ C-like <firstterm>backslash escape</firstterm> sequence, in which the combination
+ of backslash and following character(s) represent a special byte
+ value, as shown in <xref linkend="sql-backslash-table"/>.
+ </para>
+
+ <table id="sql-backslash-table">
+ <title>Backslash Escape Sequences</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Backslash Escape Sequence</entry>
+ <entry>Interpretation</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><literal>\b</literal></entry>
+ <entry>backspace</entry>
+ </row>
+ <row>
+ <entry><literal>\f</literal></entry>
+ <entry>form feed</entry>
+ </row>
+ <row>
+ <entry><literal>\n</literal></entry>
+ <entry>newline</entry>
+ </row>
+ <row>
+ <entry><literal>\r</literal></entry>
+ <entry>carriage return</entry>
+ </row>
+ <row>
+ <entry><literal>\t</literal></entry>
+ <entry>tab</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>\<replaceable>o</replaceable></literal>,
+ <literal>\<replaceable>oo</replaceable></literal>,
+ <literal>\<replaceable>ooo</replaceable></literal>
+ (<replaceable>o</replaceable> = 0&ndash;7)
+ </entry>
+ <entry>octal byte value</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>\x<replaceable>h</replaceable></literal>,
+ <literal>\x<replaceable>hh</replaceable></literal>
+ (<replaceable>h</replaceable> = 0&ndash;9, A&ndash;F)
+ </entry>
+ <entry>hexadecimal byte value</entry>
+ </row>
+ <row>
+ <entry>
+ <literal>\u<replaceable>xxxx</replaceable></literal>,
+ <literal>\U<replaceable>xxxxxxxx</replaceable></literal>
+ (<replaceable>x</replaceable> = 0&ndash;9, A&ndash;F)
+ </entry>
+ <entry>16 or 32-bit hexadecimal Unicode character value</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Any other
+ character following a backslash is taken literally. Thus, to
+ include a backslash character, write two backslashes (<literal>\\</literal>).
+ Also, a single quote can be included in an escape string by writing
+ <literal>\'</literal>, in addition to the normal way of <literal>''</literal>.
+ </para>
+
+ <para>
+ It is your responsibility that the byte sequences you create,
+ especially when using the octal or hexadecimal escapes, compose
+ valid characters in the server character set encoding.
+ A useful alternative is to use Unicode escapes or the
+ alternative Unicode escape syntax, explained
+ in <xref linkend="sql-syntax-strings-uescape"/>; then the server
+ will check that the character conversion is possible.
+ </para>
+
+ <caution>
+ <para>
+ If the configuration parameter
+ <xref linkend="guc-standard-conforming-strings"/> is <literal>off</literal>,
+ then <productname>PostgreSQL</productname> recognizes backslash escapes
+ in both regular and escape string constants. However, as of
+ <productname>PostgreSQL</productname> 9.1, the default is <literal>on</literal>, meaning
+ that backslash escapes are recognized only in escape string constants.
+ This behavior is more standards-compliant, but might break applications
+ which rely on the historical behavior, where backslash escapes
+ were always recognized. As a workaround, you can set this parameter
+ to <literal>off</literal>, but it is better to migrate away from using backslash
+ escapes. If you need to use a backslash escape to represent a special
+ character, write the string constant with an <literal>E</literal>.
+ </para>
+
+ <para>
+ In addition to <varname>standard_conforming_strings</varname>, the configuration
+ parameters <xref linkend="guc-escape-string-warning"/> and
+ <xref linkend="guc-backslash-quote"/> govern treatment of backslashes
+ in string constants.
+ </para>
+ </caution>
+
+ <para>
+ The character with the code zero cannot be in a string constant.
+ </para>
+ </sect3>
+
+ <sect3 id="sql-syntax-strings-uescape">
+ <title>String Constants with Unicode Escapes</title>
+
+ <indexterm zone="sql-syntax-strings-uescape">
+ <primary>Unicode escape</primary>
+ <secondary>in string constants</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> also supports another type
+ of escape syntax for strings that allows specifying arbitrary
+ Unicode characters by code point. A Unicode escape string
+ constant starts with <literal>U&amp;</literal> (upper or lower case
+ letter U followed by ampersand) immediately before the opening
+ quote, without any spaces in between, for
+ example <literal>U&amp;'foo'</literal>. (Note that this creates an
+ ambiguity with the operator <literal>&amp;</literal>. Use spaces
+ around the operator to avoid this problem.) Inside the quotes,
+ Unicode characters can be specified in escaped form by writing a
+ backslash followed by the four-digit hexadecimal code point
+ number or alternatively a backslash followed by a plus sign
+ followed by a six-digit hexadecimal code point number. For
+ example, the string <literal>'data'</literal> could be written as
+<programlisting>
+U&amp;'d\0061t\+000061'
+</programlisting>
+ The following less trivial example writes the Russian
+ word <quote>slon</quote> (elephant) in Cyrillic letters:
+<programlisting>
+U&amp;'\0441\043B\043E\043D'
+</programlisting>
+ </para>
+
+ <para>
+ If a different escape character than backslash is desired, it can
+ be specified using
+ the <literal>UESCAPE</literal><indexterm><primary>UESCAPE</primary></indexterm>
+ clause after the string, for example:
+<programlisting>
+U&amp;'d!0061t!+000061' UESCAPE '!'
+</programlisting>
+ The escape character can be any single character other than a
+ hexadecimal digit, the plus sign, a single quote, a double quote,
+ or a whitespace character.
+ </para>
+
+ <para>
+ To include the escape character in the string literally, write
+ it twice.
+ </para>
+
+ <para>
+ Either the 4-digit or the 6-digit escape form can be used to
+ specify UTF-16 surrogate pairs to compose characters with code
+ points larger than U+FFFF, although the availability of the
+ 6-digit form technically makes this unnecessary. (Surrogate
+ pairs are not stored directly, but are combined into a single
+ code point.)
+ </para>
+
+ <para>
+ If the server encoding is not UTF-8, the Unicode code point identified
+ by one of these escape sequences is converted to the actual server
+ encoding; an error is reported if that's not possible.
+ </para>
+
+ <para>
+ Also, the Unicode escape syntax for string constants only works
+ when the configuration
+ parameter <xref linkend="guc-standard-conforming-strings"/> is
+ turned on. This is because otherwise this syntax could confuse
+ clients that parse the SQL statements to the point that it could
+ lead to SQL injections and similar security issues. If the
+ parameter is set to off, this syntax will be rejected with an
+ error message.
+ </para>
+ </sect3>
+
+ <sect3 id="sql-syntax-dollar-quoting">
+ <title>Dollar-Quoted String Constants</title>
+
+ <indexterm>
+ <primary>dollar quoting</primary>
+ </indexterm>
+
+ <para>
+ While the standard syntax for specifying string constants is usually
+ convenient, it can be difficult to understand when the desired string
+ contains many single quotes or backslashes, since each of those must
+ be doubled. To allow more readable queries in such situations,
+ <productname>PostgreSQL</productname> provides another way, called
+ <quote>dollar quoting</quote>, to write string constants.
+ A dollar-quoted string constant
+ consists of a dollar sign (<literal>$</literal>), an optional
+ <quote>tag</quote> of zero or more characters, another dollar
+ sign, an arbitrary sequence of characters that makes up the
+ string content, a dollar sign, the same tag that began this
+ dollar quote, and a dollar sign. For example, here are two
+ different ways to specify the string <quote>Dianne's horse</quote>
+ using dollar quoting:
+<programlisting>
+$$Dianne's horse$$
+$SomeTag$Dianne's horse$SomeTag$
+</programlisting>
+ Notice that inside the dollar-quoted string, single quotes can be
+ used without needing to be escaped. Indeed, no characters inside
+ a dollar-quoted string are ever escaped: the string content is always
+ written literally. Backslashes are not special, and neither are
+ dollar signs, unless they are part of a sequence matching the opening
+ tag.
+ </para>
+
+ <para>
+ It is possible to nest dollar-quoted string constants by choosing
+ different tags at each nesting level. This is most commonly used in
+ writing function definitions. For example:
+<programlisting>
+$function$
+BEGIN
+ RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
+END;
+$function$
+</programlisting>
+ Here, the sequence <literal>$q$[\t\r\n\v\\]$q$</literal> represents a
+ dollar-quoted literal string <literal>[\t\r\n\v\\]</literal>, which will
+ be recognized when the function body is executed by
+ <productname>PostgreSQL</productname>. But since the sequence does not match
+ the outer dollar quoting delimiter <literal>$function$</literal>, it is
+ just some more characters within the constant so far as the outer
+ string is concerned.
+ </para>
+
+ <para>
+ The tag, if any, of a dollar-quoted string follows the same rules
+ as an unquoted identifier, except that it cannot contain a dollar sign.
+ Tags are case sensitive, so <literal>$tag$String content$tag$</literal>
+ is correct, but <literal>$TAG$String content$tag$</literal> is not.
+ </para>
+
+ <para>
+ A dollar-quoted string that follows a keyword or identifier must
+ be separated from it by whitespace; otherwise the dollar quoting
+ delimiter would be taken as part of the preceding identifier.
+ </para>
+
+ <para>
+ Dollar quoting is not part of the SQL standard, but it is often a more
+ convenient way to write complicated string literals than the
+ standard-compliant single quote syntax. It is particularly useful when
+ representing string constants inside other constants, as is often needed
+ in procedural function definitions. With single-quote syntax, each
+ backslash in the above example would have to be written as four
+ backslashes, which would be reduced to two backslashes in parsing the
+ original string constant, and then to one when the inner string constant
+ is re-parsed during function execution.
+ </para>
+ </sect3>
+
+ <sect3 id="sql-syntax-bit-strings">
+ <title>Bit-String Constants</title>
+
+ <indexterm zone="sql-syntax-bit-strings">
+ <primary>bit string</primary>
+ <secondary>constant</secondary>
+ </indexterm>
+
+ <para>
+ Bit-string constants look like regular string constants with a
+ <literal>B</literal> (upper or lower case) immediately before the
+ opening quote (no intervening whitespace), e.g.,
+ <literal>B'1001'</literal>. The only characters allowed within
+ bit-string constants are <literal>0</literal> and
+ <literal>1</literal>.
+ </para>
+
+ <para>
+ Alternatively, bit-string constants can be specified in hexadecimal
+ notation, using a leading <literal>X</literal> (upper or lower case),
+ e.g., <literal>X'1FF'</literal>. This notation is equivalent to
+ a bit-string constant with four binary digits for each hexadecimal digit.
+ </para>
+
+ <para>
+ Both forms of bit-string constant can be continued
+ across lines in the same way as regular string constants.
+ Dollar quoting cannot be used in a bit-string constant.
+ </para>
+ </sect3>
+
+ <sect3 id="sql-syntax-constants-numeric">
+ <title>Numeric Constants</title>
+
+ <indexterm>
+ <primary>number</primary>
+ <secondary>constant</secondary>
+ </indexterm>
+
+ <para>
+ Numeric constants are accepted in these general forms:
+<synopsis>
+<replaceable>digits</replaceable>
+<replaceable>digits</replaceable>.<optional><replaceable>digits</replaceable></optional><optional>e<optional>+-</optional><replaceable>digits</replaceable></optional>
+<optional><replaceable>digits</replaceable></optional>.<replaceable>digits</replaceable><optional>e<optional>+-</optional><replaceable>digits</replaceable></optional>
+<replaceable>digits</replaceable>e<optional>+-</optional><replaceable>digits</replaceable>
+</synopsis>
+ where <replaceable>digits</replaceable> is one or more decimal
+ digits (0 through 9). At least one digit must be before or after the
+ decimal point, if one is used. At least one digit must follow the
+ exponent marker (<literal>e</literal>), if one is present.
+ There cannot be any spaces or other characters embedded in the
+ constant. Note that any leading plus or minus sign is not actually
+ considered part of the constant; it is an operator applied to the
+ constant.
+ </para>
+
+ <para>
+ These are some examples of valid numeric constants:
+<literallayout>
+42
+3.5
+4.
+.001
+5e2
+1.925e-3
+</literallayout>
+ </para>
+
+ <para>
+ <indexterm><primary>integer</primary></indexterm>
+ <indexterm><primary>bigint</primary></indexterm>
+ <indexterm><primary>numeric</primary></indexterm>
+ A numeric constant that contains neither a decimal point nor an
+ exponent is initially presumed to be type <type>integer</type> if its
+ value fits in type <type>integer</type> (32 bits); otherwise it is
+ presumed to be type <type>bigint</type> if its
+ value fits in type <type>bigint</type> (64 bits); otherwise it is
+ taken to be type <type>numeric</type>. Constants that contain decimal
+ points and/or exponents are always initially presumed to be type
+ <type>numeric</type>.
+ </para>
+
+ <para>
+ The initially assigned data type of a numeric constant is just a
+ starting point for the type resolution algorithms. In most cases
+ the constant will be automatically coerced to the most
+ appropriate type depending on context. When necessary, you can
+ force a numeric value to be interpreted as a specific data type
+ by casting it.<indexterm><primary>type cast</primary></indexterm>
+ For example, you can force a numeric value to be treated as type
+ <type>real</type> (<type>float4</type>) by writing:
+
+<programlisting>
+REAL '1.23' -- string style
+1.23::REAL -- PostgreSQL (historical) style
+</programlisting>
+
+ These are actually just special cases of the general casting
+ notations discussed next.
+ </para>
+ </sect3>
+
+ <sect3 id="sql-syntax-constants-generic">
+ <title>Constants of Other Types</title>
+
+ <indexterm>
+ <primary>data type</primary>
+ <secondary>constant</secondary>
+ </indexterm>
+
+ <para>
+ A constant of an <emphasis>arbitrary</emphasis> type can be
+ entered using any one of the following notations:
+<synopsis>
+<replaceable>type</replaceable> '<replaceable>string</replaceable>'
+'<replaceable>string</replaceable>'::<replaceable>type</replaceable>
+CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
+</synopsis>
+ The string constant's text is passed to the input conversion
+ routine for the type called <replaceable>type</replaceable>. The
+ result is a constant of the indicated type. The explicit type
+ cast can be omitted if there is no ambiguity as to the type the
+ constant must be (for example, when it is assigned directly to a
+ table column), in which case it is automatically coerced.
+ </para>
+
+ <para>
+ The string constant can be written using either regular SQL
+ notation or dollar-quoting.
+ </para>
+
+ <para>
+ It is also possible to specify a type coercion using a function-like
+ syntax:
+<synopsis>
+<replaceable>typename</replaceable> ( '<replaceable>string</replaceable>' )
+</synopsis>
+ but not all type names can be used in this way; see <xref
+ linkend="sql-syntax-type-casts"/> for details.
+ </para>
+
+ <para>
+ The <literal>::</literal>, <literal>CAST()</literal>, and
+ function-call syntaxes can also be used to specify run-time type
+ conversions of arbitrary expressions, as discussed in <xref
+ linkend="sql-syntax-type-casts"/>. To avoid syntactic ambiguity, the
+ <literal><replaceable>type</replaceable> '<replaceable>string</replaceable>'</literal>
+ syntax can only be used to specify the type of a simple literal constant.
+ Another restriction on the
+ <literal><replaceable>type</replaceable> '<replaceable>string</replaceable>'</literal>
+ syntax is that it does not work for array types; use <literal>::</literal>
+ or <literal>CAST()</literal> to specify the type of an array constant.
+ </para>
+
+ <para>
+ The <literal>CAST()</literal> syntax conforms to SQL. The
+ <literal><replaceable>type</replaceable> '<replaceable>string</replaceable>'</literal>
+ syntax is a generalization of the standard: SQL specifies this syntax only
+ for a few data types, but <productname>PostgreSQL</productname> allows it
+ for all types. The syntax with
+ <literal>::</literal> is historical <productname>PostgreSQL</productname>
+ usage, as is the function-call syntax.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2 id="sql-syntax-operators">
+ <title>Operators</title>
+
+ <indexterm zone="sql-syntax-operators">
+ <primary>operator</primary>
+ <secondary>syntax</secondary>
+ </indexterm>
+
+ <para>
+ An operator name is a sequence of up to <symbol>NAMEDATALEN</symbol>-1
+ (63 by default) characters from the following list:
+<literallayout>
++ - * / &lt; &gt; = ~ ! @ # % ^ &amp; | ` ?
+</literallayout>
+
+ There are a few restrictions on operator names, however:
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>--</literal> and <literal>/*</literal> cannot appear
+ anywhere in an operator name, since they will be taken as the
+ start of a comment.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A multiple-character operator name cannot end in <literal>+</literal> or <literal>-</literal>,
+ unless the name also contains at least one of these characters:
+<literallayout>
+~ ! @ # % ^ &amp; | ` ?
+</literallayout>
+ For example, <literal>@-</literal> is an allowed operator name,
+ but <literal>*-</literal> is not. This restriction allows
+ <productname>PostgreSQL</productname> to parse SQL-compliant
+ queries without requiring spaces between tokens.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ When working with non-SQL-standard operator names, you will usually
+ need to separate adjacent operators with spaces to avoid ambiguity.
+ For example, if you have defined a prefix operator named <literal>@</literal>,
+ you cannot write <literal>X*@Y</literal>; you must write
+ <literal>X* @Y</literal> to ensure that
+ <productname>PostgreSQL</productname> reads it as two operator names
+ not one.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-special-chars">
+ <title>Special Characters</title>
+
+ <para>
+ Some characters that are not alphanumeric have a special meaning
+ that is different from being an operator. Details on the usage can
+ be found at the location where the respective syntax element is
+ described. This section only exists to advise the existence and
+ summarize the purposes of these characters.
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A dollar sign (<literal>$</literal>) followed by digits is used
+ to represent a positional parameter in the body of a function
+ definition or a prepared statement. In other contexts the
+ dollar sign can be part of an identifier or a dollar-quoted string
+ constant.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Parentheses (<literal>()</literal>) have their usual meaning to
+ group expressions and enforce precedence. In some cases
+ parentheses are required as part of the fixed syntax of a
+ particular SQL command.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Brackets (<literal>[]</literal>) are used to select the elements
+ of an array. See <xref linkend="arrays"/> for more information
+ on arrays.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Commas (<literal>,</literal>) are used in some syntactical
+ constructs to separate the elements of a list.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The semicolon (<literal>;</literal>) terminates an SQL command.
+ It cannot appear anywhere within a command, except within a
+ string constant or quoted identifier.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The colon (<literal>:</literal>) is used to select
+ <quote>slices</quote> from arrays. (See <xref
+ linkend="arrays"/>.) In certain SQL dialects (such as Embedded
+ SQL), the colon is used to prefix variable names.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The asterisk (<literal>*</literal>) is used in some contexts to denote
+ all the fields of a table row or composite value. It also
+ has a special meaning when used as the argument of an
+ aggregate function, namely that the aggregate does not require
+ any explicit parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The period (<literal>.</literal>) is used in numeric
+ constants, and to separate schema, table, and column names.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-comments">
+ <title>Comments</title>
+
+ <indexterm zone="sql-syntax-comments">
+ <primary>comment</primary>
+ <secondary sortas="SQL">in SQL</secondary>
+ </indexterm>
+
+ <para>
+ A comment is a sequence of characters beginning with
+ double dashes and extending to the end of the line, e.g.:
+<programlisting>
+-- This is a standard SQL comment
+</programlisting>
+ </para>
+
+ <para>
+ Alternatively, C-style block comments can be used:
+<programlisting>
+/* multiline comment
+ * with nesting: /* nested block comment */
+ */
+</programlisting>
+ where the comment begins with <literal>/*</literal> and extends to
+ the matching occurrence of <literal>*/</literal>. These block
+ comments nest, as specified in the SQL standard but unlike C, so that one can
+ comment out larger blocks of code that might contain existing block
+ comments.
+ </para>
+
+ <para>
+ A comment is removed from the input stream before further syntax
+ analysis and is effectively replaced by whitespace.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-precedence">
+ <title>Operator Precedence</title>
+
+ <indexterm zone="sql-precedence">
+ <primary>operator</primary>
+ <secondary>precedence</secondary>
+ </indexterm>
+
+ <para>
+ <xref linkend="sql-precedence-table"/> shows the precedence and
+ associativity of the operators in <productname>PostgreSQL</productname>.
+ Most operators have the same precedence and are left-associative.
+ The precedence and associativity of the operators is hard-wired
+ into the parser.
+ Add parentheses if you want an expression with multiple operators
+ to be parsed in some other way than what the precedence rules imply.
+ </para>
+
+ <table id="sql-precedence-table">
+ <title>Operator Precedence (highest to lowest)</title>
+
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Operator/Element</entry>
+ <entry>Associativity</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><token>.</token></entry>
+ <entry>left</entry>
+ <entry>table/column name separator</entry>
+ </row>
+
+ <row>
+ <entry><token>::</token></entry>
+ <entry>left</entry>
+ <entry><productname>PostgreSQL</productname>-style typecast</entry>
+ </row>
+
+ <row>
+ <entry><token>[</token> <token>]</token></entry>
+ <entry>left</entry>
+ <entry>array element selection</entry>
+ </row>
+
+ <row>
+ <entry><token>+</token> <token>-</token></entry>
+ <entry>right</entry>
+ <entry>unary plus, unary minus</entry>
+ </row>
+
+ <row>
+ <entry><token>^</token></entry>
+ <entry>left</entry>
+ <entry>exponentiation</entry>
+ </row>
+
+ <row>
+ <entry><token>*</token> <token>/</token> <token>%</token></entry>
+ <entry>left</entry>
+ <entry>multiplication, division, modulo</entry>
+ </row>
+
+ <row>
+ <entry><token>+</token> <token>-</token></entry>
+ <entry>left</entry>
+ <entry>addition, subtraction</entry>
+ </row>
+
+ <row>
+ <entry>(any other operator)</entry>
+ <entry>left</entry>
+ <entry>all other native and user-defined operators</entry>
+ </row>
+
+ <row>
+ <entry><token>BETWEEN</token> <token>IN</token> <token>LIKE</token> <token>ILIKE</token> <token>SIMILAR</token></entry>
+ <entry></entry>
+ <entry>range containment, set membership, string matching</entry>
+ </row>
+
+ <row>
+ <entry><token>&lt;</token> <token>&gt;</token> <token>=</token> <token>&lt;=</token> <token>&gt;=</token> <token>&lt;&gt;</token>
+</entry>
+ <entry></entry>
+ <entry>comparison operators</entry>
+ </row>
+
+ <row>
+ <entry><token>IS</token> <token>ISNULL</token> <token>NOTNULL</token></entry>
+ <entry></entry>
+ <entry><literal>IS TRUE</literal>, <literal>IS FALSE</literal>, <literal>IS
+ NULL</literal>, <literal>IS DISTINCT FROM</literal>, etc.</entry>
+ </row>
+
+ <row>
+ <entry><token>NOT</token></entry>
+ <entry>right</entry>
+ <entry>logical negation</entry>
+ </row>
+
+ <row>
+ <entry><token>AND</token></entry>
+ <entry>left</entry>
+ <entry>logical conjunction</entry>
+ </row>
+
+ <row>
+ <entry><token>OR</token></entry>
+ <entry>left</entry>
+ <entry>logical disjunction</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Note that the operator precedence rules also apply to user-defined
+ operators that have the same names as the built-in operators
+ mentioned above. For example, if you define a
+ <quote>+</quote> operator for some custom data type it will have
+ the same precedence as the built-in <quote>+</quote> operator, no
+ matter what yours does.
+ </para>
+
+ <para>
+ When a schema-qualified operator name is used in the
+ <literal>OPERATOR</literal> syntax, as for example in:
+<programlisting>
+SELECT 3 OPERATOR(pg_catalog.+) 4;
+</programlisting>
+ the <literal>OPERATOR</literal> construct is taken to have the default precedence
+ shown in <xref linkend="sql-precedence-table"/> for
+ <quote>any other operator</quote>. This is true no matter
+ which specific operator appears inside <literal>OPERATOR()</literal>.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> versions before 9.5 used slightly different
+ operator precedence rules. In particular, <token>&lt;=</token>
+ <token>&gt;=</token> and <token>&lt;&gt;</token> used to be treated as
+ generic operators; <literal>IS</literal> tests used to have higher priority;
+ and <literal>NOT BETWEEN</literal> and related constructs acted inconsistently,
+ being taken in some cases as having the precedence of <literal>NOT</literal>
+ rather than <literal>BETWEEN</literal>. These rules were changed for better
+ compliance with the SQL standard and to reduce confusion from
+ inconsistent treatment of logically equivalent constructs. In most
+ cases, these changes will result in no behavioral change, or perhaps
+ in <quote>no such operator</quote> failures which can be resolved by adding
+ parentheses. However there are corner cases in which a query might
+ change behavior without any parsing error being reported.
+ </para>
+ </note>
+ </sect2>
+ </sect1>
+
+ <sect1 id="sql-expressions">
+ <title>Value Expressions</title>
+
+ <indexterm zone="sql-expressions">
+ <primary>expression</primary>
+ <secondary>syntax</secondary>
+ </indexterm>
+
+ <indexterm zone="sql-expressions">
+ <primary>value expression</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>scalar</primary>
+ <see>expression</see>
+ </indexterm>
+
+ <para>
+ Value expressions are used in a variety of contexts, such
+ as in the target list of the <command>SELECT</command> command, as
+ new column values in <command>INSERT</command> or
+ <command>UPDATE</command>, or in search conditions in a number of
+ commands. The result of a value expression is sometimes called a
+ <firstterm>scalar</firstterm>, to distinguish it from the result of
+ a table expression (which is a table). Value expressions are
+ therefore also called <firstterm>scalar expressions</firstterm> (or
+ even simply <firstterm>expressions</firstterm>). The expression
+ syntax allows the calculation of values from primitive parts using
+ arithmetic, logical, set, and other operations.
+ </para>
+
+ <para>
+ A value expression is one of the following:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A constant or literal value
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A column reference
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A positional parameter reference, in the body of a function definition
+ or prepared statement
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A subscripted expression
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A field selection expression
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ An operator invocation
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A function call
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ An aggregate expression
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A window function call
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A type cast
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A collation expression
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A scalar subquery
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ An array constructor
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ A row constructor
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Another value expression in parentheses (used to group
+ subexpressions and override
+ precedence<indexterm><primary>parenthesis</primary></indexterm>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In addition to this list, there are a number of constructs that can
+ be classified as an expression but do not follow any general syntax
+ rules. These generally have the semantics of a function or
+ operator and are explained in the appropriate location in <xref
+ linkend="functions"/>. An example is the <literal>IS NULL</literal>
+ clause.
+ </para>
+
+ <para>
+ We have already discussed constants in <xref
+ linkend="sql-syntax-constants"/>. The following sections discuss
+ the remaining options.
+ </para>
+
+ <sect2 id="sql-expressions-column-refs">
+ <title>Column References</title>
+
+ <indexterm>
+ <primary>column reference</primary>
+ </indexterm>
+
+ <para>
+ A column can be referenced in the form:
+<synopsis>
+<replaceable>correlation</replaceable>.<replaceable>columnname</replaceable>
+</synopsis>
+ </para>
+
+ <para>
+ <replaceable>correlation</replaceable> is the name of a
+ table (possibly qualified with a schema name), or an alias for a table
+ defined by means of a <literal>FROM</literal> clause.
+ The correlation name and separating dot can be omitted if the column name
+ is unique across all the tables being used in the current query. (See also <xref linkend="queries"/>.)
+ </para>
+ </sect2>
+
+ <sect2 id="sql-expressions-parameters-positional">
+ <title>Positional Parameters</title>
+
+ <indexterm>
+ <primary>parameter</primary>
+ <secondary>syntax</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>$</primary>
+ </indexterm>
+
+ <para>
+ A positional parameter reference is used to indicate a value
+ that is supplied externally to an SQL statement. Parameters are
+ used in SQL function definitions and in prepared queries. Some
+ client libraries also support specifying data values separately
+ from the SQL command string, in which case parameters are used to
+ refer to the out-of-line data values.
+ The form of a parameter reference is:
+<synopsis>
+$<replaceable>number</replaceable>
+</synopsis>
+ </para>
+
+ <para>
+ For example, consider the definition of a function,
+ <function>dept</function>, as:
+
+<programlisting>
+CREATE FUNCTION dept(text) RETURNS dept
+ AS $$ SELECT * FROM dept WHERE name = $1 $$
+ LANGUAGE SQL;
+</programlisting>
+
+ Here the <literal>$1</literal> references the value of the first
+ function argument whenever the function is invoked.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-expressions-subscripts">
+ <title>Subscripts</title>
+
+ <indexterm>
+ <primary>subscript</primary>
+ </indexterm>
+
+ <para>
+ If an expression yields a value of an array type, then a specific
+ element of the array value can be extracted by writing
+<synopsis>
+<replaceable>expression</replaceable>[<replaceable>subscript</replaceable>]
+</synopsis>
+ or multiple adjacent elements (an <quote>array slice</quote>) can be extracted
+ by writing
+<synopsis>
+<replaceable>expression</replaceable>[<replaceable>lower_subscript</replaceable>:<replaceable>upper_subscript</replaceable>]
+</synopsis>
+ (Here, the brackets <literal>[ ]</literal> are meant to appear literally.)
+ Each <replaceable>subscript</replaceable> is itself an expression,
+ which will be rounded to the nearest integer value.
+ </para>
+
+ <para>
+ In general the array <replaceable>expression</replaceable> must be
+ parenthesized, but the parentheses can be omitted when the expression
+ to be subscripted is just a column reference or positional parameter.
+ Also, multiple subscripts can be concatenated when the original array
+ is multidimensional.
+ For example:
+
+<programlisting>
+mytable.arraycolumn[4]
+mytable.two_d_column[17][34]
+$1[10:42]
+(arrayfunction(a,b))[42]
+</programlisting>
+
+ The parentheses in the last example are required.
+ See <xref linkend="arrays"/> for more about arrays.
+ </para>
+ </sect2>
+
+ <sect2 id="field-selection">
+ <title>Field Selection</title>
+
+ <indexterm>
+ <primary>field selection</primary>
+ </indexterm>
+
+ <para>
+ If an expression yields a value of a composite type (row type), then a
+ specific field of the row can be extracted by writing
+<synopsis>
+<replaceable>expression</replaceable>.<replaceable>fieldname</replaceable>
+</synopsis>
+ </para>
+
+ <para>
+ In general the row <replaceable>expression</replaceable> must be
+ parenthesized, but the parentheses can be omitted when the expression
+ to be selected from is just a table reference or positional parameter.
+ For example:
+
+<programlisting>
+mytable.mycolumn
+$1.somecolumn
+(rowfunction(a,b)).col3
+</programlisting>
+
+ (Thus, a qualified column reference is actually just a special case
+ of the field selection syntax.) An important special case is
+ extracting a field from a table column that is of a composite type:
+
+<programlisting>
+(compositecol).somefield
+(mytable.compositecol).somefield
+</programlisting>
+
+ The parentheses are required here to show that
+ <structfield>compositecol</structfield> is a column name not a table name,
+ or that <structname>mytable</structname> is a table name not a schema name
+ in the second case.
+ </para>
+
+ <para>
+ You can ask for all fields of a composite value by
+ writing <literal>.*</literal>:
+<programlisting>
+(compositecol).*
+</programlisting>
+ This notation behaves differently depending on context;
+ see <xref linkend="rowtypes-usage"/> for details.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-expressions-operator-calls">
+ <title>Operator Invocations</title>
+
+ <indexterm>
+ <primary>operator</primary>
+ <secondary>invocation</secondary>
+ </indexterm>
+
+ <para>
+ There are two possible syntaxes for an operator invocation:
+ <simplelist>
+ <member><replaceable>expression</replaceable> <replaceable>operator</replaceable> <replaceable>expression</replaceable> (binary infix operator)</member>
+ <member><replaceable>operator</replaceable> <replaceable>expression</replaceable> (unary prefix operator)</member>
+ </simplelist>
+ where the <replaceable>operator</replaceable> token follows the syntax
+ rules of <xref linkend="sql-syntax-operators"/>, or is one of the
+ key words <token>AND</token>, <token>OR</token>, and
+ <token>NOT</token>, or is a qualified operator name in the form:
+<synopsis>
+<literal>OPERATOR(</literal><replaceable>schema</replaceable><literal>.</literal><replaceable>operatorname</replaceable><literal>)</literal>
+</synopsis>
+ Which particular operators exist and whether
+ they are unary or binary depends on what operators have been
+ defined by the system or the user. <xref linkend="functions"/>
+ describes the built-in operators.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-expressions-function-calls">
+ <title>Function Calls</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>invocation</secondary>
+ </indexterm>
+
+ <para>
+ The syntax for a function call is the name of a function
+ (possibly qualified with a schema name), followed by its argument list
+ enclosed in parentheses:
+
+<synopsis>
+<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional> )
+</synopsis>
+ </para>
+
+ <para>
+ For example, the following computes the square root of 2:
+<programlisting>
+sqrt(2)
+</programlisting>
+ </para>
+
+ <para>
+ The list of built-in functions is in <xref linkend="functions"/>.
+ Other functions can be added by the user.
+ </para>
+
+ <para>
+ When issuing queries in a database where some users mistrust other users,
+ observe security precautions from <xref linkend="typeconv-func"/> when
+ writing function calls.
+ </para>
+
+ <para>
+ The arguments can optionally have names attached.
+ See <xref linkend="sql-syntax-calling-funcs"/> for details.
+ </para>
+
+ <note>
+ <para>
+ A function that takes a single argument of composite type can
+ optionally be called using field-selection syntax, and conversely
+ field selection can be written in functional style. That is, the
+ notations <literal>col(table)</literal> and <literal>table.col</literal> are
+ interchangeable. This behavior is not SQL-standard but is provided
+ in <productname>PostgreSQL</productname> because it allows use of functions to
+ emulate <quote>computed fields</quote>. For more information see
+ <xref linkend="rowtypes-usage"/>.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="syntax-aggregates">
+ <title>Aggregate Expressions</title>
+
+ <indexterm zone="syntax-aggregates">
+ <primary>aggregate function</primary>
+ <secondary>invocation</secondary>
+ </indexterm>
+
+ <indexterm zone="syntax-aggregates">
+ <primary>ordered-set aggregate</primary>
+ </indexterm>
+
+ <indexterm zone="syntax-aggregates">
+ <primary>WITHIN GROUP</primary>
+ </indexterm>
+
+ <indexterm zone="syntax-aggregates">
+ <primary>FILTER</primary>
+ </indexterm>
+
+ <para>
+ An <firstterm>aggregate expression</firstterm> represents the
+ application of an aggregate function across the rows selected by a
+ query. An aggregate function reduces multiple inputs to a single
+ output value, such as the sum or average of the inputs. The
+ syntax of an aggregate expression is one of the following:
+
+<synopsis>
+<replaceable>aggregate_name</replaceable> (<replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ]
+<replaceable>aggregate_name</replaceable> (ALL <replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ]
+<replaceable>aggregate_name</replaceable> (DISTINCT <replaceable>expression</replaceable> [ , ... ] [ <replaceable>order_by_clause</replaceable> ] ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ]
+<replaceable>aggregate_name</replaceable> ( * ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ]
+<replaceable>aggregate_name</replaceable> ( [ <replaceable>expression</replaceable> [ , ... ] ] ) WITHIN GROUP ( <replaceable>order_by_clause</replaceable> ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ]
+</synopsis>
+
+ where <replaceable>aggregate_name</replaceable> is a previously
+ defined aggregate (possibly qualified with a schema name) and
+ <replaceable>expression</replaceable> is
+ any value expression that does not itself contain an aggregate
+ expression or a window function call. The optional
+ <replaceable>order_by_clause</replaceable> and
+ <replaceable>filter_clause</replaceable> are described below.
+ </para>
+
+ <para>
+ The first form of aggregate expression invokes the aggregate
+ once for each input row.
+ The second form is the same as the first, since
+ <literal>ALL</literal> is the default.
+ The third form invokes the aggregate once for each distinct value
+ of the expression (or distinct set of values, for multiple expressions)
+ found in the input rows.
+ The fourth form invokes the aggregate once for each input row; since no
+ particular input value is specified, it is generally only useful
+ for the <function>count(*)</function> aggregate function.
+ The last form is used with <firstterm>ordered-set</firstterm> aggregate
+ functions, which are described below.
+ </para>
+
+ <para>
+ Most aggregate functions ignore null inputs, so that rows in which
+ one or more of the expression(s) yield null are discarded. This
+ can be assumed to be true, unless otherwise specified, for all
+ built-in aggregates.
+ </para>
+
+ <para>
+ For example, <literal>count(*)</literal> yields the total number
+ of input rows; <literal>count(f1)</literal> yields the number of
+ input rows in which <literal>f1</literal> is non-null, since
+ <function>count</function> ignores nulls; and
+ <literal>count(distinct f1)</literal> yields the number of
+ distinct non-null values of <literal>f1</literal>.
+ </para>
+
+ <para>
+ Ordinarily, the input rows are fed to the aggregate function in an
+ unspecified order. In many cases this does not matter; for example,
+ <function>min</function> produces the same result no matter what order it
+ receives the inputs in. However, some aggregate functions
+ (such as <function>array_agg</function> and <function>string_agg</function>) produce
+ results that depend on the ordering of the input rows. When using
+ such an aggregate, the optional <replaceable>order_by_clause</replaceable> can be
+ used to specify the desired ordering. The <replaceable>order_by_clause</replaceable>
+ has the same syntax as for a query-level <literal>ORDER BY</literal> clause, as
+ described in <xref linkend="queries-order"/>, except that its expressions
+ are always just expressions and cannot be output-column names or numbers.
+ For example:
+<programlisting>
+SELECT array_agg(a ORDER BY b DESC) FROM table;
+</programlisting>
+ </para>
+
+ <para>
+ When dealing with multiple-argument aggregate functions, note that the
+ <literal>ORDER BY</literal> clause goes after all the aggregate arguments.
+ For example, write this:
+<programlisting>
+SELECT string_agg(a, ',' ORDER BY a) FROM table;
+</programlisting>
+ not this:
+<programlisting>
+SELECT string_agg(a ORDER BY a, ',') FROM table; -- incorrect
+</programlisting>
+ The latter is syntactically valid, but it represents a call of a
+ single-argument aggregate function with two <literal>ORDER BY</literal> keys
+ (the second one being rather useless since it's a constant).
+ </para>
+
+ <para>
+ If <literal>DISTINCT</literal> is specified in addition to an
+ <replaceable>order_by_clause</replaceable>, then all the <literal>ORDER BY</literal>
+ expressions must match regular arguments of the aggregate; that is,
+ you cannot sort on an expression that is not included in the
+ <literal>DISTINCT</literal> list.
+ </para>
+
+ <note>
+ <para>
+ The ability to specify both <literal>DISTINCT</literal> and <literal>ORDER BY</literal>
+ in an aggregate function is a <productname>PostgreSQL</productname> extension.
+ </para>
+ </note>
+
+ <para>
+ Placing <literal>ORDER BY</literal> within the aggregate's regular argument
+ list, as described so far, is used when ordering the input rows for
+ general-purpose and statistical aggregates, for which ordering is
+ optional. There is a
+ subclass of aggregate functions called <firstterm>ordered-set
+ aggregates</firstterm> for which an <replaceable>order_by_clause</replaceable>
+ is <emphasis>required</emphasis>, usually because the aggregate's computation is
+ only sensible in terms of a specific ordering of its input rows.
+ Typical examples of ordered-set aggregates include rank and percentile
+ calculations. For an ordered-set aggregate,
+ the <replaceable>order_by_clause</replaceable> is written
+ inside <literal>WITHIN GROUP (...)</literal>, as shown in the final syntax
+ alternative above. The expressions in
+ the <replaceable>order_by_clause</replaceable> are evaluated once per
+ input row just like regular aggregate arguments, sorted as per
+ the <replaceable>order_by_clause</replaceable>'s requirements, and fed
+ to the aggregate function as input arguments. (This is unlike the case
+ for a non-<literal>WITHIN GROUP</literal> <replaceable>order_by_clause</replaceable>,
+ which is not treated as argument(s) to the aggregate function.) The
+ argument expressions preceding <literal>WITHIN GROUP</literal>, if any, are
+ called <firstterm>direct arguments</firstterm> to distinguish them from
+ the <firstterm>aggregated arguments</firstterm> listed in
+ the <replaceable>order_by_clause</replaceable>. Unlike regular aggregate
+ arguments, direct arguments are evaluated only once per aggregate call,
+ not once per input row. This means that they can contain variables only
+ if those variables are grouped by <literal>GROUP BY</literal>; this restriction
+ is the same as if the direct arguments were not inside an aggregate
+ expression at all. Direct arguments are typically used for things like
+ percentile fractions, which only make sense as a single value per
+ aggregation calculation. The direct argument list can be empty; in this
+ case, write just <literal>()</literal> not <literal>(*)</literal>.
+ (<productname>PostgreSQL</productname> will actually accept either spelling, but
+ only the first way conforms to the SQL standard.)
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>median</primary>
+ <seealso>percentile</seealso>
+ </indexterm>
+ An example of an ordered-set aggregate call is:
+
+<programlisting>
+SELECT percentile_cont(0.5) WITHIN GROUP (ORDER BY income) FROM households;
+ percentile_cont
+-----------------
+ 50489
+</programlisting>
+
+ which obtains the 50th percentile, or median, value of
+ the <structfield>income</structfield> column from table <structname>households</structname>.
+ Here, <literal>0.5</literal> is a direct argument; it would make no sense
+ for the percentile fraction to be a value varying across rows.
+ </para>
+
+ <para>
+ If <literal>FILTER</literal> is specified, then only the input
+ rows for which the <replaceable>filter_clause</replaceable>
+ evaluates to true are fed to the aggregate function; other rows
+ are discarded. For example:
+<programlisting>
+SELECT
+ count(*) AS unfiltered,
+ count(*) FILTER (WHERE i &lt; 5) AS filtered
+FROM generate_series(1,10) AS s(i);
+ unfiltered | filtered
+------------+----------
+ 10 | 4
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ The predefined aggregate functions are described in <xref
+ linkend="functions-aggregate"/>. Other aggregate functions can be added
+ by the user.
+ </para>
+
+ <para>
+ An aggregate expression can only appear in the result list or
+ <literal>HAVING</literal> clause of a <command>SELECT</command> command.
+ It is forbidden in other clauses, such as <literal>WHERE</literal>,
+ because those clauses are logically evaluated before the results
+ of aggregates are formed.
+ </para>
+
+ <para>
+ When an aggregate expression appears in a subquery (see
+ <xref linkend="sql-syntax-scalar-subqueries"/> and
+ <xref linkend="functions-subquery"/>), the aggregate is normally
+ evaluated over the rows of the subquery. But an exception occurs
+ if the aggregate's arguments (and <replaceable>filter_clause</replaceable>
+ if any) contain only outer-level variables:
+ the aggregate then belongs to the nearest such outer level, and is
+ evaluated over the rows of that query. The aggregate expression
+ as a whole is then an outer reference for the subquery it appears in,
+ and acts as a constant over any one evaluation of that subquery.
+ The restriction about
+ appearing only in the result list or <literal>HAVING</literal> clause
+ applies with respect to the query level that the aggregate belongs to.
+ </para>
+ </sect2>
+
+ <sect2 id="syntax-window-functions">
+ <title>Window Function Calls</title>
+
+ <indexterm zone="syntax-window-functions">
+ <primary>window function</primary>
+ <secondary>invocation</secondary>
+ </indexterm>
+
+ <indexterm zone="syntax-window-functions">
+ <primary>OVER clause</primary>
+ </indexterm>
+
+ <para>
+ A <firstterm>window function call</firstterm> represents the application
+ of an aggregate-like function over some portion of the rows selected
+ by a query. Unlike non-window aggregate calls, this is not tied
+ to grouping of the selected rows into a single output row &mdash; each
+ row remains separate in the query output. However the window function
+ has access to all the rows that would be part of the current row's
+ group according to the grouping specification (<literal>PARTITION BY</literal>
+ list) of the window function call.
+ The syntax of a window function call is one of the following:
+
+<synopsis>
+<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional>) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER <replaceable>window_name</replaceable>
+<replaceable>function_name</replaceable> (<optional><replaceable>expression</replaceable> <optional>, <replaceable>expression</replaceable> ... </optional></optional>) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER ( <replaceable class="parameter">window_definition</replaceable> )
+<replaceable>function_name</replaceable> ( * ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER <replaceable>window_name</replaceable>
+<replaceable>function_name</replaceable> ( * ) [ FILTER ( WHERE <replaceable>filter_clause</replaceable> ) ] OVER ( <replaceable class="parameter">window_definition</replaceable> )
+</synopsis>
+ where <replaceable class="parameter">window_definition</replaceable>
+ has the syntax
+<synopsis>
+[ <replaceable class="parameter">existing_window_name</replaceable> ]
+[ PARTITION BY <replaceable class="parameter">expression</replaceable> [, ...] ]
+[ ORDER BY <replaceable class="parameter">expression</replaceable> [ ASC | DESC | USING <replaceable class="parameter">operator</replaceable> ] [ NULLS { FIRST | LAST } ] [, ...] ]
+[ <replaceable class="parameter">frame_clause</replaceable> ]
+</synopsis>
+ The optional <replaceable class="parameter">frame_clause</replaceable>
+ can be one of
+<synopsis>
+{ RANGE | ROWS | GROUPS } <replaceable>frame_start</replaceable> [ <replaceable>frame_exclusion</replaceable> ]
+{ RANGE | ROWS | GROUPS } BETWEEN <replaceable>frame_start</replaceable> AND <replaceable>frame_end</replaceable> [ <replaceable>frame_exclusion</replaceable> ]
+</synopsis>
+ where <replaceable>frame_start</replaceable>
+ and <replaceable>frame_end</replaceable> can be one of
+<synopsis>
+UNBOUNDED PRECEDING
+<replaceable>offset</replaceable> PRECEDING
+CURRENT ROW
+<replaceable>offset</replaceable> FOLLOWING
+UNBOUNDED FOLLOWING
+</synopsis>
+ and <replaceable>frame_exclusion</replaceable> can be one of
+<synopsis>
+EXCLUDE CURRENT ROW
+EXCLUDE GROUP
+EXCLUDE TIES
+EXCLUDE NO OTHERS
+</synopsis>
+ </para>
+
+ <para>
+ Here, <replaceable>expression</replaceable> represents any value
+ expression that does not itself contain window function calls.
+ </para>
+
+ <para>
+ <replaceable>window_name</replaceable> is a reference to a named window
+ specification defined in the query's <literal>WINDOW</literal> clause.
+ Alternatively, a full <replaceable>window_definition</replaceable> can
+ be given within parentheses, using the same syntax as for defining a
+ named window in the <literal>WINDOW</literal> clause; see the
+ <xref linkend="sql-select"/> reference page for details. It's worth
+ pointing out that <literal>OVER wname</literal> is not exactly equivalent to
+ <literal>OVER (wname ...)</literal>; the latter implies copying and modifying the
+ window definition, and will be rejected if the referenced window
+ specification includes a frame clause.
+ </para>
+
+ <para>
+ The <literal>PARTITION BY</literal> clause groups the rows of the query into
+ <firstterm>partitions</firstterm>, which are processed separately by the window
+ function. <literal>PARTITION BY</literal> works similarly to a query-level
+ <literal>GROUP BY</literal> clause, except that its expressions are always just
+ expressions and cannot be output-column names or numbers.
+ Without <literal>PARTITION BY</literal>, all rows produced by the query are
+ treated as a single partition.
+ The <literal>ORDER BY</literal> clause determines the order in which the rows
+ of a partition are processed by the window function. It works similarly
+ to a query-level <literal>ORDER BY</literal> clause, but likewise cannot use
+ output-column names or numbers. Without <literal>ORDER BY</literal>, rows are
+ processed in an unspecified order.
+ </para>
+
+ <para>
+ The <replaceable class="parameter">frame_clause</replaceable> specifies
+ the set of rows constituting the <firstterm>window frame</firstterm>, which is a
+ subset of the current partition, for those window functions that act on
+ the frame instead of the whole partition. The set of rows in the frame
+ can vary depending on which row is the current row. The frame can be
+ specified in <literal>RANGE</literal>, <literal>ROWS</literal>
+ or <literal>GROUPS</literal> mode; in each case, it runs from
+ the <replaceable>frame_start</replaceable> to
+ the <replaceable>frame_end</replaceable>.
+ If <replaceable>frame_end</replaceable> is omitted, the end defaults
+ to <literal>CURRENT ROW</literal>.
+ </para>
+
+ <para>
+ A <replaceable>frame_start</replaceable> of <literal>UNBOUNDED PRECEDING</literal> means
+ that the frame starts with the first row of the partition, and similarly
+ a <replaceable>frame_end</replaceable> of <literal>UNBOUNDED FOLLOWING</literal> means
+ that the frame ends with the last row of the partition.
+ </para>
+
+ <para>
+ In <literal>RANGE</literal> or <literal>GROUPS</literal> mode,
+ a <replaceable>frame_start</replaceable> of
+ <literal>CURRENT ROW</literal> means the frame starts with the current
+ row's first <firstterm>peer</firstterm> row (a row that the
+ window's <literal>ORDER BY</literal> clause sorts as equivalent to the
+ current row), while a <replaceable>frame_end</replaceable> of
+ <literal>CURRENT ROW</literal> means the frame ends with the current
+ row's last peer row.
+ In <literal>ROWS</literal> mode, <literal>CURRENT ROW</literal> simply
+ means the current row.
+ </para>
+
+ <para>
+ In the <replaceable>offset</replaceable> <literal>PRECEDING</literal>
+ and <replaceable>offset</replaceable> <literal>FOLLOWING</literal> frame
+ options, the <replaceable>offset</replaceable> must be an expression not
+ containing any variables, aggregate functions, or window functions.
+ The meaning of the <replaceable>offset</replaceable> depends on the
+ frame mode:
+ <itemizedlist>
+ <listitem>
+ <para>
+ In <literal>ROWS</literal> mode,
+ the <replaceable>offset</replaceable> must yield a non-null,
+ non-negative integer, and the option means that the frame starts or
+ ends the specified number of rows before or after the current row.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In <literal>GROUPS</literal> mode,
+ the <replaceable>offset</replaceable> again must yield a non-null,
+ non-negative integer, and the option means that the frame starts or
+ ends the specified number of <firstterm>peer groups</firstterm>
+ before or after the current row's peer group, where a peer group is a
+ set of rows that are equivalent in the <literal>ORDER BY</literal>
+ ordering. (There must be an <literal>ORDER BY</literal> clause
+ in the window definition to use <literal>GROUPS</literal> mode.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In <literal>RANGE</literal> mode, these options require that
+ the <literal>ORDER BY</literal> clause specify exactly one column.
+ The <replaceable>offset</replaceable> specifies the maximum
+ difference between the value of that column in the current row and
+ its value in preceding or following rows of the frame. The data type
+ of the <replaceable>offset</replaceable> expression varies depending
+ on the data type of the ordering column. For numeric ordering
+ columns it is typically of the same type as the ordering column,
+ but for datetime ordering columns it is an <type>interval</type>.
+ For example, if the ordering column is of type <type>date</type>
+ or <type>timestamp</type>, one could write <literal>RANGE BETWEEN
+ '1 day' PRECEDING AND '10 days' FOLLOWING</literal>.
+ The <replaceable>offset</replaceable> is still required to be
+ non-null and non-negative, though the meaning
+ of <quote>non-negative</quote> depends on its data type.
+ </para>
+ </listitem>
+ </itemizedlist>
+ In any case, the distance to the end of the frame is limited by the
+ distance to the end of the partition, so that for rows near the partition
+ ends the frame might contain fewer rows than elsewhere.
+ </para>
+
+ <para>
+ Notice that in both <literal>ROWS</literal> and <literal>GROUPS</literal>
+ mode, <literal>0 PRECEDING</literal> and <literal>0 FOLLOWING</literal>
+ are equivalent to <literal>CURRENT ROW</literal>. This normally holds
+ in <literal>RANGE</literal> mode as well, for an appropriate
+ data-type-specific meaning of <quote>zero</quote>.
+ </para>
+
+ <para>
+ The <replaceable>frame_exclusion</replaceable> option allows rows around
+ the current row to be excluded from the frame, even if they would be
+ included according to the frame start and frame end options.
+ <literal>EXCLUDE CURRENT ROW</literal> excludes the current row from the
+ frame.
+ <literal>EXCLUDE GROUP</literal> excludes the current row and its
+ ordering peers from the frame.
+ <literal>EXCLUDE TIES</literal> excludes any peers of the current
+ row from the frame, but not the current row itself.
+ <literal>EXCLUDE NO OTHERS</literal> simply specifies explicitly the
+ default behavior of not excluding the current row or its peers.
+ </para>
+
+ <para>
+ The default framing option is <literal>RANGE UNBOUNDED PRECEDING</literal>,
+ which is the same as <literal>RANGE BETWEEN UNBOUNDED PRECEDING AND
+ CURRENT ROW</literal>. With <literal>ORDER BY</literal>, this sets the frame to be
+ all rows from the partition start up through the current row's last
+ <literal>ORDER BY</literal> peer. Without <literal>ORDER BY</literal>,
+ this means all rows of the partition are included in the window frame,
+ since all rows become peers of the current row.
+ </para>
+
+ <para>
+ Restrictions are that
+ <replaceable>frame_start</replaceable> cannot be <literal>UNBOUNDED FOLLOWING</literal>,
+ <replaceable>frame_end</replaceable> cannot be <literal>UNBOUNDED PRECEDING</literal>,
+ and the <replaceable>frame_end</replaceable> choice cannot appear earlier in the
+ above list of <replaceable>frame_start</replaceable>
+ and <replaceable>frame_end</replaceable> options than
+ the <replaceable>frame_start</replaceable> choice does &mdash; for example
+ <literal>RANGE BETWEEN CURRENT ROW AND <replaceable>offset</replaceable>
+ PRECEDING</literal> is not allowed.
+ But, for example, <literal>ROWS BETWEEN 7 PRECEDING AND 8
+ PRECEDING</literal> is allowed, even though it would never select any
+ rows.
+ </para>
+
+ <para>
+ If <literal>FILTER</literal> is specified, then only the input
+ rows for which the <replaceable>filter_clause</replaceable>
+ evaluates to true are fed to the window function; other rows
+ are discarded. Only window functions that are aggregates accept
+ a <literal>FILTER</literal> clause.
+ </para>
+
+ <para>
+ The built-in window functions are described in <xref
+ linkend="functions-window-table"/>. Other window functions can be added by
+ the user. Also, any built-in or user-defined general-purpose or
+ statistical aggregate can be used as a window function. (Ordered-set
+ and hypothetical-set aggregates cannot presently be used as window functions.)
+ </para>
+
+ <para>
+ The syntaxes using <literal>*</literal> are used for calling parameter-less
+ aggregate functions as window functions, for example
+ <literal>count(*) OVER (PARTITION BY x ORDER BY y)</literal>.
+ The asterisk (<literal>*</literal>) is customarily not used for
+ window-specific functions. Window-specific functions do not
+ allow <literal>DISTINCT</literal> or <literal>ORDER BY</literal> to be used within the
+ function argument list.
+ </para>
+
+ <para>
+ Window function calls are permitted only in the <literal>SELECT</literal>
+ list and the <literal>ORDER BY</literal> clause of the query.
+ </para>
+
+ <para>
+ More information about window functions can be found in
+ <xref linkend="tutorial-window"/>,
+ <xref linkend="functions-window"/>, and
+ <xref linkend="queries-window"/>.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-type-casts">
+ <title>Type Casts</title>
+
+ <indexterm>
+ <primary>data type</primary>
+ <secondary>type cast</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>type cast</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>::</primary>
+ </indexterm>
+
+ <para>
+ A type cast specifies a conversion from one data type to another.
+ <productname>PostgreSQL</productname> accepts two equivalent syntaxes
+ for type casts:
+<synopsis>
+CAST ( <replaceable>expression</replaceable> AS <replaceable>type</replaceable> )
+<replaceable>expression</replaceable>::<replaceable>type</replaceable>
+</synopsis>
+ The <literal>CAST</literal> syntax conforms to SQL; the syntax with
+ <literal>::</literal> is historical <productname>PostgreSQL</productname>
+ usage.
+ </para>
+
+ <para>
+ When a cast is applied to a value expression of a known type, it
+ represents a run-time type conversion. The cast will succeed only
+ if a suitable type conversion operation has been defined. Notice that this
+ is subtly different from the use of casts with constants, as shown in
+ <xref linkend="sql-syntax-constants-generic"/>. A cast applied to an
+ unadorned string literal represents the initial assignment of a type
+ to a literal constant value, and so it will succeed for any type
+ (if the contents of the string literal are acceptable input syntax for the
+ data type).
+ </para>
+
+ <para>
+ An explicit type cast can usually be omitted if there is no ambiguity as
+ to the type that a value expression must produce (for example, when it is
+ assigned to a table column); the system will automatically apply a
+ type cast in such cases. However, automatic casting is only done for
+ casts that are marked <quote>OK to apply implicitly</quote>
+ in the system catalogs. Other casts must be invoked with
+ explicit casting syntax. This restriction is intended to prevent
+ surprising conversions from being applied silently.
+ </para>
+
+ <para>
+ It is also possible to specify a type cast using a function-like
+ syntax:
+<synopsis>
+<replaceable>typename</replaceable> ( <replaceable>expression</replaceable> )
+</synopsis>
+ However, this only works for types whose names are also valid as
+ function names. For example, <literal>double precision</literal>
+ cannot be used this way, but the equivalent <literal>float8</literal>
+ can. Also, the names <literal>interval</literal>, <literal>time</literal>, and
+ <literal>timestamp</literal> can only be used in this fashion if they are
+ double-quoted, because of syntactic conflicts. Therefore, the use of
+ the function-like cast syntax leads to inconsistencies and should
+ probably be avoided.
+ </para>
+
+ <note>
+ <para>
+ The function-like syntax is in fact just a function call. When
+ one of the two standard cast syntaxes is used to do a run-time
+ conversion, it will internally invoke a registered function to
+ perform the conversion. By convention, these conversion functions
+ have the same name as their output type, and thus the <quote>function-like
+ syntax</quote> is nothing more than a direct invocation of the underlying
+ conversion function. Obviously, this is not something that a portable
+ application should rely on. For further details see
+ <xref linkend="sql-createcast"/>.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="sql-syntax-collate-exprs">
+ <title>Collation Expressions</title>
+
+ <indexterm>
+ <primary>COLLATE</primary>
+ </indexterm>
+
+ <para>
+ The <literal>COLLATE</literal> clause overrides the collation of
+ an expression. It is appended to the expression it applies to:
+<synopsis>
+<replaceable>expr</replaceable> COLLATE <replaceable>collation</replaceable>
+</synopsis>
+ where <replaceable>collation</replaceable> is a possibly
+ schema-qualified identifier. The <literal>COLLATE</literal>
+ clause binds tighter than operators; parentheses can be used when
+ necessary.
+ </para>
+
+ <para>
+ If no collation is explicitly specified, the database system
+ either derives a collation from the columns involved in the
+ expression, or it defaults to the default collation of the
+ database if no column is involved in the expression.
+ </para>
+
+ <para>
+ The two common uses of the <literal>COLLATE</literal> clause are
+ overriding the sort order in an <literal>ORDER BY</literal> clause, for
+ example:
+<programlisting>
+SELECT a, b, c FROM tbl WHERE ... ORDER BY a COLLATE "C";
+</programlisting>
+ and overriding the collation of a function or operator call that
+ has locale-sensitive results, for example:
+<programlisting>
+SELECT * FROM tbl WHERE a &gt; 'foo' COLLATE "C";
+</programlisting>
+ Note that in the latter case the <literal>COLLATE</literal> clause is
+ attached to an input argument of the operator we wish to affect.
+ It doesn't matter which argument of the operator or function call the
+ <literal>COLLATE</literal> clause is attached to, because the collation that is
+ applied by the operator or function is derived by considering all
+ arguments, and an explicit <literal>COLLATE</literal> clause will override the
+ collations of all other arguments. (Attaching non-matching
+ <literal>COLLATE</literal> clauses to more than one argument, however, is an
+ error. For more details see <xref linkend="collation"/>.)
+ Thus, this gives the same result as the previous example:
+<programlisting>
+SELECT * FROM tbl WHERE a COLLATE "C" &gt; 'foo';
+</programlisting>
+ But this is an error:
+<programlisting>
+SELECT * FROM tbl WHERE (a &gt; 'foo') COLLATE "C";
+</programlisting>
+ because it attempts to apply a collation to the result of the
+ <literal>&gt;</literal> operator, which is of the non-collatable data type
+ <type>boolean</type>.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-scalar-subqueries">
+ <title>Scalar Subqueries</title>
+
+ <indexterm>
+ <primary>subquery</primary>
+ </indexterm>
+
+ <para>
+ A scalar subquery is an ordinary
+ <command>SELECT</command> query in parentheses that returns exactly one
+ row with one column. (See <xref linkend="queries"/> for information about writing queries.)
+ The <command>SELECT</command> query is executed
+ and the single returned value is used in the surrounding value expression.
+ It is an error to use a query that
+ returns more than one row or more than one column as a scalar subquery.
+ (But if, during a particular execution, the subquery returns no rows,
+ there is no error; the scalar result is taken to be null.)
+ The subquery can refer to variables from the surrounding query,
+ which will act as constants during any one evaluation of the subquery.
+ See also <xref linkend="functions-subquery"/> for other expressions involving subqueries.
+ </para>
+
+ <para>
+ For example, the following finds the largest city population in each
+ state:
+<programlisting>
+SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)
+ FROM states;
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-array-constructors">
+ <title>Array Constructors</title>
+
+ <indexterm>
+ <primary>array</primary>
+ <secondary>constructor</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ARRAY</primary>
+ </indexterm>
+
+ <para>
+ An array constructor is an expression that builds an
+ array value using values for its member elements. A simple array
+ constructor
+ consists of the key word <literal>ARRAY</literal>, a left square bracket
+ <literal>[</literal>, a list of expressions (separated by commas) for the
+ array element values, and finally a right square bracket <literal>]</literal>.
+ For example:
+<programlisting>
+SELECT ARRAY[1,2,3+4];
+ array
+---------
+ {1,2,7}
+(1 row)
+</programlisting>
+ By default,
+ the array element type is the common type of the member expressions,
+ determined using the same rules as for <literal>UNION</literal> or
+ <literal>CASE</literal> constructs (see <xref linkend="typeconv-union-case"/>).
+ You can override this by explicitly casting the array constructor to the
+ desired type, for example:
+<programlisting>
+SELECT ARRAY[1,2,22.7]::integer[];
+ array
+----------
+ {1,2,23}
+(1 row)
+</programlisting>
+ This has the same effect as casting each expression to the array
+ element type individually.
+ For more on casting, see <xref linkend="sql-syntax-type-casts"/>.
+ </para>
+
+ <para>
+ Multidimensional array values can be built by nesting array
+ constructors.
+ In the inner constructors, the key word <literal>ARRAY</literal> can
+ be omitted. For example, these produce the same result:
+
+<programlisting>
+SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
+ array
+---------------
+ {{1,2},{3,4}}
+(1 row)
+
+SELECT ARRAY[[1,2],[3,4]];
+ array
+---------------
+ {{1,2},{3,4}}
+(1 row)
+</programlisting>
+
+ Since multidimensional arrays must be rectangular, inner constructors
+ at the same level must produce sub-arrays of identical dimensions.
+ Any cast applied to the outer <literal>ARRAY</literal> constructor propagates
+ automatically to all the inner constructors.
+ </para>
+
+ <para>
+ Multidimensional array constructor elements can be anything yielding
+ an array of the proper kind, not only a sub-<literal>ARRAY</literal> construct.
+ For example:
+<programlisting>
+CREATE TABLE arr(f1 int[], f2 int[]);
+
+INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);
+
+SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr;
+ array
+------------------------------------------------
+ {{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ You can construct an empty array, but since it's impossible to have an
+ array with no type, you must explicitly cast your empty array to the
+ desired type. For example:
+<programlisting>
+SELECT ARRAY[]::integer[];
+ array
+-------
+ {}
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ It is also possible to construct an array from the results of a
+ subquery. In this form, the array constructor is written with the
+ key word <literal>ARRAY</literal> followed by a parenthesized (not
+ bracketed) subquery. For example:
+<programlisting>
+SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
+ array
+------------------------------------------------------------------
+ {2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31,2412}
+(1 row)
+
+SELECT ARRAY(SELECT ARRAY[i, i*2] FROM generate_series(1,5) AS a(i));
+ array
+----------------------------------
+ {{1,2},{2,4},{3,6},{4,8},{5,10}}
+(1 row)
+</programlisting>
+ The subquery must return a single column.
+ If the subquery's output column is of a non-array type, the resulting
+ one-dimensional array will have an element for each row in the
+ subquery result, with an element type matching that of the
+ subquery's output column.
+ If the subquery's output column is of an array type, the result will be
+ an array of the same type but one higher dimension; in this case all
+ the subquery rows must yield arrays of identical dimensionality, else
+ the result would not be rectangular.
+ </para>
+
+ <para>
+ The subscripts of an array value built with <literal>ARRAY</literal>
+ always begin with one. For more information about arrays, see
+ <xref linkend="arrays"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="sql-syntax-row-constructors">
+ <title>Row Constructors</title>
+
+ <indexterm>
+ <primary>composite type</primary>
+ <secondary>constructor</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>row type</primary>
+ <secondary>constructor</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>ROW</primary>
+ </indexterm>
+
+ <para>
+ A row constructor is an expression that builds a row value (also
+ called a composite value) using values
+ for its member fields. A row constructor consists of the key word
+ <literal>ROW</literal>, a left parenthesis, zero or more
+ expressions (separated by commas) for the row field values, and finally
+ a right parenthesis. For example:
+<programlisting>
+SELECT ROW(1,2.5,'this is a test');
+</programlisting>
+ The key word <literal>ROW</literal> is optional when there is more than one
+ expression in the list.
+ </para>
+
+ <para>
+ A row constructor can include the syntax
+ <replaceable>rowvalue</replaceable><literal>.*</literal>,
+ which will be expanded to a list of the elements of the row value,
+ just as occurs when the <literal>.*</literal> syntax is used at the top level
+ of a <command>SELECT</command> list (see <xref linkend="rowtypes-usage"/>).
+ For example, if table <literal>t</literal> has
+ columns <literal>f1</literal> and <literal>f2</literal>, these are the same:
+<programlisting>
+SELECT ROW(t.*, 42) FROM t;
+SELECT ROW(t.f1, t.f2, 42) FROM t;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 8.2, the
+ <literal>.*</literal> syntax was not expanded in row constructors, so
+ that writing <literal>ROW(t.*, 42)</literal> created a two-field row whose first
+ field was another row value. The new behavior is usually more useful.
+ If you need the old behavior of nested row values, write the inner
+ row value without <literal>.*</literal>, for instance
+ <literal>ROW(t, 42)</literal>.
+ </para>
+ </note>
+
+ <para>
+ By default, the value created by a <literal>ROW</literal> expression is of
+ an anonymous record type. If necessary, it can be cast to a named
+ composite type &mdash; either the row type of a table, or a composite type
+ created with <command>CREATE TYPE AS</command>. An explicit cast might be needed
+ to avoid ambiguity. For example:
+<programlisting>
+CREATE TABLE mytable(f1 int, f2 float, f3 text);
+
+CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
+
+-- No cast needed since only one getf1() exists
+SELECT getf1(ROW(1,2.5,'this is a test'));
+ getf1
+-------
+ 1
+(1 row)
+
+CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
+
+CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
+
+-- Now we need a cast to indicate which function to call:
+SELECT getf1(ROW(1,2.5,'this is a test'));
+ERROR: function getf1(record) is not unique
+
+SELECT getf1(ROW(1,2.5,'this is a test')::mytable);
+ getf1
+-------
+ 1
+(1 row)
+
+SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
+ getf1
+-------
+ 11
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Row constructors can be used to build composite values to be stored
+ in a composite-type table column, or to be passed to a function that
+ accepts a composite parameter. Also,
+ it is possible to compare two row values or test a row with
+ <literal>IS NULL</literal> or <literal>IS NOT NULL</literal>, for example:
+<programlisting>
+SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');
+
+SELECT ROW(table.*) IS NULL FROM table; -- detect all-null rows
+</programlisting>
+ For more detail see <xref linkend="functions-comparisons"/>.
+ Row constructors can also be used in connection with subqueries,
+ as discussed in <xref linkend="functions-subquery"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="syntax-express-eval">
+ <title>Expression Evaluation Rules</title>
+
+ <indexterm>
+ <primary>expression</primary>
+ <secondary>order of evaluation</secondary>
+ </indexterm>
+
+ <para>
+ The order of evaluation of subexpressions is not defined. In
+ particular, the inputs of an operator or function are not necessarily
+ evaluated left-to-right or in any other fixed order.
+ </para>
+
+ <para>
+ Furthermore, if the result of an expression can be determined by
+ evaluating only some parts of it, then other subexpressions
+ might not be evaluated at all. For instance, if one wrote:
+<programlisting>
+SELECT true OR somefunc();
+</programlisting>
+ then <literal>somefunc()</literal> would (probably) not be called
+ at all. The same would be the case if one wrote:
+<programlisting>
+SELECT somefunc() OR true;
+</programlisting>
+ Note that this is not the same as the left-to-right
+ <quote>short-circuiting</quote> of Boolean operators that is found
+ in some programming languages.
+ </para>
+
+ <para>
+ As a consequence, it is unwise to use functions with side effects
+ as part of complex expressions. It is particularly dangerous to
+ rely on side effects or evaluation order in <literal>WHERE</literal> and <literal>HAVING</literal> clauses,
+ since those clauses are extensively reprocessed as part of
+ developing an execution plan. Boolean
+ expressions (<literal>AND</literal>/<literal>OR</literal>/<literal>NOT</literal> combinations) in those clauses can be reorganized
+ in any manner allowed by the laws of Boolean algebra.
+ </para>
+
+ <para>
+ When it is essential to force evaluation order, a <literal>CASE</literal>
+ construct (see <xref linkend="functions-conditional"/>) can be
+ used. For example, this is an untrustworthy way of trying to
+ avoid division by zero in a <literal>WHERE</literal> clause:
+<programlisting>
+SELECT ... WHERE x &gt; 0 AND y/x &gt; 1.5;
+</programlisting>
+ But this is safe:
+<programlisting>
+SELECT ... WHERE CASE WHEN x &gt; 0 THEN y/x &gt; 1.5 ELSE false END;
+</programlisting>
+ A <literal>CASE</literal> construct used in this fashion will defeat optimization
+ attempts, so it should only be done when necessary. (In this particular
+ example, it would be better to sidestep the problem by writing
+ <literal>y &gt; 1.5*x</literal> instead.)
+ </para>
+
+ <para>
+ <literal>CASE</literal> is not a cure-all for such issues, however.
+ One limitation of the technique illustrated above is that it does not
+ prevent early evaluation of constant subexpressions.
+ As described in <xref linkend="xfunc-volatility"/>, functions and
+ operators marked <literal>IMMUTABLE</literal> can be evaluated when
+ the query is planned rather than when it is executed. Thus for example
+<programlisting>
+SELECT CASE WHEN x &gt; 0 THEN x ELSE 1/0 END FROM tab;
+</programlisting>
+ is likely to result in a division-by-zero failure due to the planner
+ trying to simplify the constant subexpression,
+ even if every row in the table has <literal>x &gt; 0</literal> so that the
+ <literal>ELSE</literal> arm would never be entered at run time.
+ </para>
+
+ <para>
+ While that particular example might seem silly, related cases that don't
+ obviously involve constants can occur in queries executed within
+ functions, since the values of function arguments and local variables
+ can be inserted into queries as constants for planning purposes.
+ Within <application>PL/pgSQL</application> functions, for example, using an
+ <literal>IF</literal>-<literal>THEN</literal>-<literal>ELSE</literal> statement to protect
+ a risky computation is much safer than just nesting it in a
+ <literal>CASE</literal> expression.
+ </para>
+
+ <para>
+ Another limitation of the same kind is that a <literal>CASE</literal> cannot
+ prevent evaluation of an aggregate expression contained within it,
+ because aggregate expressions are computed before other
+ expressions in a <literal>SELECT</literal> list or <literal>HAVING</literal> clause
+ are considered. For example, the following query can cause a
+ division-by-zero error despite seemingly having protected against it:
+<programlisting>
+SELECT CASE WHEN min(employees) > 0
+ THEN avg(expenses / employees)
+ END
+ FROM departments;
+</programlisting>
+ The <function>min()</function> and <function>avg()</function> aggregates are computed
+ concurrently over all the input rows, so if any row
+ has <structfield>employees</structfield> equal to zero, the division-by-zero error
+ will occur before there is any opportunity to test the result of
+ <function>min()</function>. Instead, use a <literal>WHERE</literal>
+ or <literal>FILTER</literal> clause to prevent problematic input rows from
+ reaching an aggregate function in the first place.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="sql-syntax-calling-funcs">
+ <title>Calling Functions</title>
+
+ <indexterm zone="sql-syntax-calling-funcs">
+ <primary>notation</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> allows functions that have named
+ parameters to be called using either <firstterm>positional</firstterm> or
+ <firstterm>named</firstterm> notation. Named notation is especially
+ useful for functions that have a large number of parameters, since it
+ makes the associations between parameters and actual arguments more
+ explicit and reliable.
+ In positional notation, a function call is written with
+ its argument values in the same order as they are defined in the function
+ declaration. In named notation, the arguments are matched to the
+ function parameters by name and can be written in any order.
+ For each notation, also consider the effect of function argument types,
+ documented in <xref linkend="typeconv-func"/>.
+ </para>
+
+ <para>
+ In either notation, parameters that have default values given in the
+ function declaration need not be written in the call at all. But this
+ is particularly useful in named notation, since any combination of
+ parameters can be omitted; while in positional notation parameters can
+ only be omitted from right to left.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> also supports
+ <firstterm>mixed</firstterm> notation, which combines positional and
+ named notation. In this case, positional parameters are written first
+ and named parameters appear after them.
+ </para>
+
+ <para>
+ The following examples will illustrate the usage of all three
+ notations, using the following function definition:
+<programlisting>
+CREATE FUNCTION concat_lower_or_upper(a text, b text, uppercase boolean DEFAULT false)
+RETURNS text
+AS
+$$
+ SELECT CASE
+ WHEN $3 THEN UPPER($1 || ' ' || $2)
+ ELSE LOWER($1 || ' ' || $2)
+ END;
+$$
+LANGUAGE SQL IMMUTABLE STRICT;
+</programlisting>
+ Function <function>concat_lower_or_upper</function> has two mandatory
+ parameters, <literal>a</literal> and <literal>b</literal>. Additionally
+ there is one optional parameter <literal>uppercase</literal> which defaults
+ to <literal>false</literal>. The <literal>a</literal> and
+ <literal>b</literal> inputs will be concatenated, and forced to either
+ upper or lower case depending on the <literal>uppercase</literal>
+ parameter. The remaining details of this function
+ definition are not important here (see <xref linkend="extend"/> for
+ more information).
+ </para>
+
+ <sect2 id="sql-syntax-calling-funcs-positional">
+ <title>Using Positional Notation</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>positional notation</secondary>
+ </indexterm>
+
+ <para>
+ Positional notation is the traditional mechanism for passing arguments
+ to functions in <productname>PostgreSQL</productname>. An example is:
+<screen>
+SELECT concat_lower_or_upper('Hello', 'World', true);
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</screen>
+ All arguments are specified in order. The result is upper case since
+ <literal>uppercase</literal> is specified as <literal>true</literal>.
+ Another example is:
+<screen>
+SELECT concat_lower_or_upper('Hello', 'World');
+ concat_lower_or_upper
+-----------------------
+ hello world
+(1 row)
+</screen>
+ Here, the <literal>uppercase</literal> parameter is omitted, so it
+ receives its default value of <literal>false</literal>, resulting in
+ lower case output. In positional notation, arguments can be omitted
+ from right to left so long as they have defaults.
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-calling-funcs-named">
+ <title>Using Named Notation</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>named notation</secondary>
+ </indexterm>
+
+ <para>
+ In named notation, each argument's name is specified using
+ <literal>=&gt;</literal> to separate it from the argument expression.
+ For example:
+<screen>
+SELECT concat_lower_or_upper(a =&gt; 'Hello', b =&gt; 'World');
+ concat_lower_or_upper
+-----------------------
+ hello world
+(1 row)
+</screen>
+ Again, the argument <literal>uppercase</literal> was omitted
+ so it is set to <literal>false</literal> implicitly. One advantage of
+ using named notation is that the arguments may be specified in any
+ order, for example:
+<screen>
+SELECT concat_lower_or_upper(a =&gt; 'Hello', b =&gt; 'World', uppercase =&gt; true);
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+
+SELECT concat_lower_or_upper(a =&gt; 'Hello', uppercase =&gt; true, b =&gt; 'World');
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ An older syntax based on ":=" is supported for backward compatibility:
+<screen>
+SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="sql-syntax-calling-funcs-mixed">
+ <title>Using Mixed Notation</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>mixed notation</secondary>
+ </indexterm>
+
+ <para>
+ The mixed notation combines positional and named notation. However, as
+ already mentioned, named arguments cannot precede positional arguments.
+ For example:
+<screen>
+SELECT concat_lower_or_upper('Hello', 'World', uppercase =&gt; true);
+ concat_lower_or_upper
+-----------------------
+ HELLO WORLD
+(1 row)
+</screen>
+ In the above query, the arguments <literal>a</literal> and
+ <literal>b</literal> are specified positionally, while
+ <literal>uppercase</literal> is specified by name. In this example,
+ that adds little except documentation. With a more complex function
+ having numerous parameters that have default values, named or mixed
+ notation can save a great deal of writing and reduce chances for error.
+ </para>
+
+ <note>
+ <para>
+ Named and mixed call notations currently cannot be used when calling an
+ aggregate function (but they do work when an aggregate function is used
+ as a window function).
+ </para>
+ </note>
+ </sect2>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml
new file mode 100644
index 0000000..44733f5
--- /dev/null
+++ b/doc/src/sgml/system-views.sgml
@@ -0,0 +1,4746 @@
+<!-- doc/src/sgml/system-views.sgml -->
+<!--
+ Documentation of the system views, directed toward PostgreSQL developers
+ -->
+
+<chapter id="views">
+ <title>System Views</title>
+
+ <para>
+ In addition to the system catalogs, <productname>PostgreSQL</productname>
+ provides a number of built-in views. Some system views provide convenient
+ access to some commonly used queries on the system catalogs. Other views
+ provide access to internal server state.
+ </para>
+
+ <para>
+ The information schema (<xref linkend="information-schema"/>) provides
+ an alternative set of views which overlap the functionality of the system
+ views. Since the information schema is SQL-standard whereas the views
+ described here are <productname>PostgreSQL</productname>-specific,
+ it's usually better to use the information schema if it provides all
+ the information you need.
+ </para>
+
+ <para>
+ <xref linkend="view-table"/> lists the system views described here.
+ More detailed documentation of each view follows below.
+ There are some additional views that provide access to accumulated
+ statistics; they are described in
+ <xref linkend="monitoring-stats-views-table"/>.
+ </para>
+
+ <sect1 id="views-overview">
+ <title>Overview</title>
+
+ <para>
+ <xref linkend="view-table"/> lists the system views.
+ More detailed documentation of each catalog follows below.
+ Except where noted, all the views described here are read-only.
+ </para>
+
+ <table id="view-table">
+ <title>System Views</title>
+
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>View Name</entry>
+ <entry>Purpose</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><link linkend="view-pg-available-extensions"><structname>pg_available_extensions</structname></link></entry>
+ <entry>available extensions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-available-extension-versions"><structname>pg_available_extension_versions</structname></link></entry>
+ <entry>available versions of extensions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-backend-memory-contexts"><structname>pg_backend_memory_contexts</structname></link></entry>
+ <entry>backend memory contexts</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-config"><structname>pg_config</structname></link></entry>
+ <entry>compile-time configuration parameters</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-cursors"><structname>pg_cursors</structname></link></entry>
+ <entry>open cursors</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-file-settings"><structname>pg_file_settings</structname></link></entry>
+ <entry>summary of configuration file contents</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-group"><structname>pg_group</structname></link></entry>
+ <entry>groups of database users</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-hba-file-rules"><structname>pg_hba_file_rules</structname></link></entry>
+ <entry>summary of client authentication configuration file contents</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-ident-file-mappings"><structname>pg_ident_file_mappings</structname></link></entry>
+ <entry>summary of client user name mapping configuration file contents</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-indexes"><structname>pg_indexes</structname></link></entry>
+ <entry>indexes</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-locks"><structname>pg_locks</structname></link></entry>
+ <entry>locks currently held or awaited</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-matviews"><structname>pg_matviews</structname></link></entry>
+ <entry>materialized views</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-policies"><structname>pg_policies</structname></link></entry>
+ <entry>policies</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-prepared-statements"><structname>pg_prepared_statements</structname></link></entry>
+ <entry>prepared statements</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link></entry>
+ <entry>prepared transactions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-publication-tables"><structname>pg_publication_tables</structname></link></entry>
+ <entry>publications and information of their associated tables</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-replication-origin-status"><structname>pg_replication_origin_status</structname></link></entry>
+ <entry>information about replication origins, including replication progress</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-replication-slots"><structname>pg_replication_slots</structname></link></entry>
+ <entry>replication slot information</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-roles"><structname>pg_roles</structname></link></entry>
+ <entry>database roles</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-rules"><structname>pg_rules</structname></link></entry>
+ <entry>rules</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-seclabels"><structname>pg_seclabels</structname></link></entry>
+ <entry>security labels</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-sequences"><structname>pg_sequences</structname></link></entry>
+ <entry>sequences</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-settings"><structname>pg_settings</structname></link></entry>
+ <entry>parameter settings</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-shadow"><structname>pg_shadow</structname></link></entry>
+ <entry>database users</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-shmem-allocations"><structname>pg_shmem_allocations</structname></link></entry>
+ <entry>shared memory allocations</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-stats"><structname>pg_stats</structname></link></entry>
+ <entry>planner statistics</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-stats-ext"><structname>pg_stats_ext</structname></link></entry>
+ <entry>extended planner statistics</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-stats-ext-exprs"><structname>pg_stats_ext_exprs</structname></link></entry>
+ <entry>extended planner statistics for expressions</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-tables"><structname>pg_tables</structname></link></entry>
+ <entry>tables</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-timezone-abbrevs"><structname>pg_timezone_abbrevs</structname></link></entry>
+ <entry>time zone abbreviations</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-timezone-names"><structname>pg_timezone_names</structname></link></entry>
+ <entry>time zone names</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-user"><structname>pg_user</structname></link></entry>
+ <entry>database users</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-user-mappings"><structname>pg_user_mappings</structname></link></entry>
+ <entry>user mappings</entry>
+ </row>
+
+ <row>
+ <entry><link linkend="view-pg-views"><structname>pg_views</structname></link></entry>
+ <entry>views</entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="view-pg-available-extensions">
+ <title><structname>pg_available_extensions</structname></title>
+
+ <indexterm zone="view-pg-available-extensions">
+ <primary>pg_available_extensions</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_available_extensions</structname> view lists the
+ extensions that are available for installation.
+ See also the
+ <link linkend="catalog-pg-extension"><structname>pg_extension</structname></link>
+ catalog, which shows the extensions currently installed.
+ </para>
+
+ <table>
+ <title><structname>pg_available_extensions</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>name</type>
+ </para>
+ <para>
+ Extension name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>default_version</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of default version, or <literal>NULL</literal> if none is
+ specified
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>installed_version</structfield> <type>text</type>
+ </para>
+ <para>
+ Currently installed version of the extension,
+ or <literal>NULL</literal> if not installed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>comment</structfield> <type>text</type>
+ </para>
+ <para>
+ Comment string from the extension's control file
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_available_extensions</structname> view is read-only.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-available-extension-versions">
+ <title><structname>pg_available_extension_versions</structname></title>
+
+ <indexterm zone="view-pg-available-extension-versions">
+ <primary>pg_available_extension_versions</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_available_extension_versions</structname> view lists the
+ specific extension versions that are available for installation.
+ See also the <link
+ linkend="catalog-pg-extension"><structname>pg_extension</structname></link>
+ catalog, which shows the extensions currently installed.
+ </para>
+
+ <table>
+ <title><structname>pg_available_extension_versions</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>name</type>
+ </para>
+ <para>
+ Extension name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>version</structfield> <type>text</type>
+ </para>
+ <para>
+ Version name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>installed</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this version of this extension is currently
+ installed
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>superuser</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if only superusers are allowed to install this extension
+ (but see <structfield>trusted</structfield>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>trusted</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the extension can be installed by non-superusers
+ with appropriate privileges
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relocatable</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if extension can be relocated to another schema
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schema</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the schema that the extension must be installed into,
+ or <literal>NULL</literal> if partially or fully relocatable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>requires</structfield> <type>name[]</type>
+ </para>
+ <para>
+ Names of prerequisite extensions,
+ or <literal>NULL</literal> if none
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>comment</structfield> <type>text</type>
+ </para>
+ <para>
+ Comment string from the extension's control file
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_available_extension_versions</structname> view is
+ read-only.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-backend-memory-contexts">
+ <title><structname>pg_backend_memory_contexts</structname></title>
+
+ <indexterm zone="view-pg-backend-memory-contexts">
+ <primary>pg_backend_memory_contexts</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_backend_memory_contexts</structname> displays all
+ the memory contexts of the server process attached to the current session.
+ </para>
+ <para>
+ <structname>pg_backend_memory_contexts</structname> contains one row
+ for each memory context.
+ </para>
+
+ <table>
+ <title><structname>pg_backend_memory_contexts</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the memory context
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ident</structfield> <type>text</type>
+ </para>
+ <para>
+ Identification information of the memory context. This field is truncated at 1024 bytes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parent</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the parent of this memory context
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>level</structfield> <type>int4</type>
+ </para>
+ <para>
+ Distance from TopMemoryContext in context tree
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_bytes</structfield> <type>int8</type>
+ </para>
+ <para>
+ Total bytes allocated for this memory context
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>total_nblocks</structfield> <type>int8</type>
+ </para>
+ <para>
+ Total number of blocks allocated for this memory context
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>free_bytes</structfield> <type>int8</type>
+ </para>
+ <para>
+ Free space in bytes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>free_chunks</structfield> <type>int8</type>
+ </para>
+ <para>
+ Total number of free chunks
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>used_bytes</structfield> <type>int8</type>
+ </para>
+ <para>
+ Used space in bytes
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ By default, the <structname>pg_backend_memory_contexts</structname> view can be
+ read only by superusers or roles with the privileges of the
+ <literal>pg_read_all_stats</literal> role.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-config">
+ <title><structname>pg_config</structname></title>
+
+ <indexterm zone="view-pg-config">
+ <primary>pg_config</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_config</structname> describes the
+ compile-time configuration parameters of the currently installed
+ version of <productname>PostgreSQL</productname>. It is intended, for example, to
+ be used by software packages that want to interface to
+ <productname>PostgreSQL</productname> to facilitate finding the required header
+ files and libraries. It provides the same basic information as the
+ <xref linkend="app-pgconfig"/> <productname>PostgreSQL</productname> client
+ application.
+ </para>
+
+ <para>
+ By default, the <structname>pg_config</structname> view can be read
+ only by superusers.
+ </para>
+
+ <table>
+ <title><structname>pg_config</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ The parameter name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>setting</structfield> <type>text</type>
+ </para>
+ <para>
+ The parameter value
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-cursors">
+ <title><structname>pg_cursors</structname></title>
+
+ <indexterm zone="view-pg-cursors">
+ <primary>pg_cursors</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_cursors</structname> view lists the cursors that
+ are currently available. Cursors can be defined in several ways:
+ <itemizedlist>
+ <listitem>
+ <para>
+ via the <link linkend="sql-declare"><command>DECLARE</command></link>
+ statement in SQL
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ via the Bind message in the frontend/backend protocol, as
+ described in <xref linkend="protocol-flow-ext-query"/>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ via the Server Programming Interface (SPI), as described in
+ <xref linkend="spi-interface"/>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ The <structname>pg_cursors</structname> view displays cursors
+ created by any of these means. Cursors only exist for the duration
+ of the transaction that defines them, unless they have been
+ declared <literal>WITH HOLD</literal>. Therefore non-holdable
+ cursors are only present in the view until the end of their
+ creating transaction.
+
+ <note>
+ <para>
+ Cursors are used internally to implement some of the components
+ of <productname>PostgreSQL</productname>, such as procedural languages.
+ Therefore, the <structname>pg_cursors</structname> view might include cursors
+ that have not been explicitly created by the user.
+ </para>
+ </note>
+ </para>
+
+ <table>
+ <title><structname>pg_cursors</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ The name of the cursor
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statement</structfield> <type>text</type>
+ </para>
+ <para>
+ The verbatim query string submitted to declare this cursor
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_holdable</structfield> <type>bool</type>
+ </para>
+ <para>
+ <literal>true</literal> if the cursor is holdable (that is, it
+ can be accessed after the transaction that declared the cursor
+ has committed); <literal>false</literal> otherwise
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_binary</structfield> <type>bool</type>
+ </para>
+ <para>
+ <literal>true</literal> if the cursor was declared
+ <literal>BINARY</literal>; <literal>false</literal>
+ otherwise
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_scrollable</structfield> <type>bool</type>
+ </para>
+ <para>
+ <literal>true</literal> if the cursor is scrollable (that is, it
+ allows rows to be retrieved in a nonsequential manner);
+ <literal>false</literal> otherwise
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>creation_time</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ The time at which the cursor was declared
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_cursors</structname> view is read-only.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-file-settings">
+ <title><structname>pg_file_settings</structname></title>
+
+ <indexterm zone="view-pg-file-settings">
+ <primary>pg_file_settings</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_file_settings</structname> provides a summary of
+ the contents of the server's configuration file(s). A row appears in
+ this view for each <quote>name = value</quote> entry appearing in the files,
+ with annotations indicating whether the value could be applied
+ successfully. Additional row(s) may appear for problems not linked to
+ a <quote>name = value</quote> entry, such as syntax errors in the files.
+ </para>
+
+ <para>
+ This view is helpful for checking whether planned changes in the
+ configuration files will work, or for diagnosing a previous failure.
+ Note that this view reports on the <emphasis>current</emphasis> contents of the
+ files, not on what was last applied by the server. (The
+ <link linkend="view-pg-settings"><structname>pg_settings</structname></link>
+ view is usually sufficient to determine that.)
+ </para>
+
+ <para>
+ By default, the <structname>pg_file_settings</structname> view can be read
+ only by superusers.
+ </para>
+
+ <table>
+ <title><structname>pg_file_settings</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sourcefile</structfield> <type>text</type>
+ </para>
+ <para>
+ Full path name of the configuration file
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sourceline</structfield> <type>int4</type>
+ </para>
+ <para>
+ Line number within the configuration file where the entry appears
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>seqno</structfield> <type>int4</type>
+ </para>
+ <para>
+ Order in which the entries are processed (1..<replaceable>n</replaceable>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ Configuration parameter name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>setting</structfield> <type>text</type>
+ </para>
+ <para>
+ Value to be assigned to the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>applied</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the value can be applied successfully
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>error</structfield> <type>text</type>
+ </para>
+ <para>
+ If not null, an error message indicating why this entry could
+ not be applied
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ If the configuration file contains syntax errors or invalid parameter
+ names, the server will not attempt to apply any settings from it, and
+ therefore all the <structfield>applied</structfield> fields will read as false.
+ In such a case there will be one or more rows with
+ non-null <structfield>error</structfield> fields indicating the
+ problem(s). Otherwise, individual settings will be applied if possible.
+ If an individual setting cannot be applied (e.g., invalid value, or the
+ setting cannot be changed after server start) it will have an appropriate
+ message in the <structfield>error</structfield> field. Another way that
+ an entry might have <structfield>applied</structfield> = false is that it is
+ overridden by a later entry for the same parameter name; this case is not
+ considered an error so nothing appears in
+ the <structfield>error</structfield> field.
+ </para>
+
+ <para>
+ See <xref linkend="config-setting"/> for more information about the various
+ ways to change run-time parameters.
+ </para>
+
+</sect1>
+
+ <sect1 id="view-pg-group">
+ <title><structname>pg_group</structname></title>
+
+ <indexterm zone="view-pg-group">
+ <primary>pg_group</primary>
+ </indexterm>
+
+ <!-- Unlike information_schema.applicable_roles, this shows no members for
+ pg_database_owner. The v8.1 catalog would have shown no members if
+ that role had existed at the time. -->
+ <para>
+ The view <structname>pg_group</structname> exists for backwards
+ compatibility: it emulates a catalog that existed in
+ <productname>PostgreSQL</productname> before version 8.1.
+ It shows the names and members of all roles that are marked as not
+ <structfield>rolcanlogin</structfield>, which is an approximation to the set
+ of roles that are being used as groups.
+ </para>
+
+ <table>
+ <title><structname>pg_group</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>groname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Name of the group
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grosysid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ ID of this group
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>grolist</structfield> <type>oid[]</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ An array containing the IDs of the roles in this group
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-hba-file-rules">
+ <title><structname>pg_hba_file_rules</structname></title>
+
+ <indexterm zone="view-pg-hba-file-rules">
+ <primary>pg_hba_file_rules</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_hba_file_rules</structname> provides a summary of
+ the contents of the client authentication configuration file,
+ <link linkend="auth-pg-hba-conf"><filename>pg_hba.conf</filename></link>.
+ A row appears in this view for each
+ non-empty, non-comment line in the file, with annotations indicating
+ whether the rule could be applied successfully.
+ </para>
+
+ <para>
+ This view can be helpful for checking whether planned changes in the
+ authentication configuration file will work, or for diagnosing a previous
+ failure. Note that this view reports on the <emphasis>current</emphasis> contents
+ of the file, not on what was last loaded by the server.
+ </para>
+
+ <para>
+ By default, the <structname>pg_hba_file_rules</structname> view can be read
+ only by superusers.
+ </para>
+
+ <table>
+ <title><structname>pg_hba_file_rules</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>line_number</structfield> <type>int4</type>
+ </para>
+ <para>
+ Line number of this rule in <filename>pg_hba.conf</filename>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>type</structfield> <type>text</type>
+ </para>
+ <para>
+ Type of connection
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>database</structfield> <type>text[]</type>
+ </para>
+ <para>
+ List of database name(s) to which this rule applies
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>user_name</structfield> <type>text[]</type>
+ </para>
+ <para>
+ List of user and group name(s) to which this rule applies
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>address</structfield> <type>text</type>
+ </para>
+ <para>
+ Host name or IP address, or one
+ of <literal>all</literal>, <literal>samehost</literal>,
+ or <literal>samenet</literal>, or null for local connections
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>netmask</structfield> <type>text</type>
+ </para>
+ <para>
+ IP address mask, or null if not applicable
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>auth_method</structfield> <type>text</type>
+ </para>
+ <para>
+ Authentication method
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>options</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Options specified for authentication method, if any
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>error</structfield> <type>text</type>
+ </para>
+ <para>
+ If not null, an error message indicating why this
+ line could not be processed
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Usually, a row reflecting an incorrect entry will have values for only
+ the <structfield>line_number</structfield> and <structfield>error</structfield> fields.
+ </para>
+
+ <para>
+ See <xref linkend="client-authentication"/> for more information about
+ client authentication configuration.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-ident-file-mappings">
+ <title><structname>pg_ident_file_mappings</structname></title>
+
+ <indexterm zone="view-pg-ident-file-mappings">
+ <primary>pg_ident_file_mappings</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_ident_file_mappings</structname> provides a summary
+ of the contents of the client user name mapping configuration file,
+ <link linkend="auth-username-maps"><filename>pg_ident.conf</filename></link>.
+ A row appears in this view for each non-empty, non-comment line in the file,
+ with annotations indicating whether the map could be applied successfully.
+ </para>
+
+ <para>
+ This view can be helpful for checking whether planned changes in the
+ authentication configuration file will work, or for diagnosing a previous
+ failure. Note that this view reports on the <emphasis>current</emphasis>
+ contents of the file, not on what was last loaded by the server.
+ </para>
+
+ <para>
+ By default, the <structname>pg_ident_file_mappings</structname> view can be
+ read only by superusers.
+ </para>
+
+ <table>
+ <title><structname>pg_ident_file_mappings</structname> Columns</title> <tgroup
+ cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>line_number</structfield> <type>int4</type>
+ </para>
+ <para>
+ Line number of this map in <filename>pg_ident.conf</filename>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>map_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the map
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sys_name</structfield> <type>text</type>
+ </para>
+ <para>
+ Detected user name of the client
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pg_username</structfield> <type>text</type>
+ </para>
+ <para>
+ Requested PostgreSQL user name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>error</structfield> <type>text</type>
+ </para>
+ <para>
+ If not <literal>NULL</literal>, an error message indicating why this
+ line could not be processed
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Usually, a row reflecting an incorrect entry will have values for only
+ the <structfield>line_number</structfield> and <structfield>error</structfield> fields.
+ </para>
+
+ <para>
+ See <xref linkend="client-authentication"/> for more information about
+ client authentication configuration.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-indexes">
+ <title><structname>pg_indexes</structname></title>
+
+ <indexterm zone="view-pg-indexes">
+ <primary>pg_indexes</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_indexes</structname> provides access to
+ useful information about each index in the database.
+ </para>
+
+ <table>
+ <title><structname>pg_indexes</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table and index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table the index is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of index
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablespace</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.<structfield>spcname</structfield>)
+ </para>
+ <para>
+ Name of tablespace containing index (null if default for database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>indexdef</structfield> <type>text</type>
+ </para>
+ <para>
+ Index definition (a reconstructed <xref linkend="sql-createindex"/>
+ command)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-locks">
+ <title><structname>pg_locks</structname></title>
+
+ <indexterm zone="view-pg-locks">
+ <primary>pg_locks</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_locks</structname> provides access to
+ information about the locks held by active processes within the
+ database server. See <xref linkend="mvcc"/> for more discussion
+ of locking.
+ </para>
+
+ <para>
+ <structname>pg_locks</structname> contains one row per active lockable
+ object, requested lock mode, and relevant process. Thus, the same
+ lockable object might
+ appear many times, if multiple processes are holding or waiting
+ for locks on it. However, an object that currently has no locks on it
+ will not appear at all.
+ </para>
+
+ <para>
+ There are several distinct types of lockable objects:
+ whole relations (e.g., tables), individual pages of relations,
+ individual tuples of relations,
+ transaction IDs (both virtual and permanent IDs),
+ and general database objects (identified by class OID and object OID,
+ in the same way as in <link linkend="catalog-pg-description"><structname>pg_description</structname></link> or
+ <link linkend="catalog-pg-depend"><structname>pg_depend</structname></link>). Also, the right to extend a
+ relation is represented as a separate lockable object, as is the right to
+ update <structname>pg_database</structname>.<structfield>datfrozenxid</structfield>.
+ Also, <quote>advisory</quote> locks can be taken on numbers that have
+ user-defined meanings.
+ </para>
+
+ <table>
+ <title><structname>pg_locks</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>locktype</structfield> <type>text</type>
+ </para>
+ <para>
+ Type of the lockable object:
+ <literal>relation</literal>,
+ <literal>extend</literal>,
+ <literal>frozenid</literal>,
+ <literal>page</literal>,
+ <literal>tuple</literal>,
+ <literal>transactionid</literal>,
+ <literal>virtualxid</literal>,
+ <literal>spectoken</literal>,
+ <literal>object</literal>,
+ <literal>userlock</literal>, or
+ <literal>advisory</literal>.
+ (See also <xref linkend="wait-event-lock-table"/>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>database</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the database in which the lock target exists, or
+ zero if the target is a shared object, or
+ null if the target is a transaction ID
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>relation</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the relation targeted by the lock, or null if the target is not
+ a relation or part of a relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>page</structfield> <type>int4</type>
+ </para>
+ <para>
+ Page number targeted by the lock within the relation,
+ or null if the target is not a relation page or tuple
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tuple</structfield> <type>int2</type>
+ </para>
+ <para>
+ Tuple number targeted by the lock within the page,
+ or null if the target is not a tuple
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>virtualxid</structfield> <type>text</type>
+ </para>
+ <para>
+ Virtual ID of the transaction targeted by the lock,
+ or null if the target is not a virtual transaction ID
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>transactionid</structfield> <type>xid</type>
+ </para>
+ <para>
+ ID of the transaction targeted by the lock,
+ or null if the target is not a transaction ID
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the system catalog containing the lock target, or null if the
+ target is not a general database object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ OID of the lock target within its system catalog, or null if the
+ target is not a general database object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int2</type>
+ </para>
+ <para>
+ Column number targeted by the lock (the
+ <structfield>classid</structfield> and <structfield>objid</structfield> refer to the
+ table itself),
+ or zero if the target is some other general database object,
+ or null if the target is not a general database object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>virtualtransaction</structfield> <type>text</type>
+ </para>
+ <para>
+ Virtual ID of the transaction that is holding or awaiting this lock
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pid</structfield> <type>int4</type>
+ </para>
+ <para>
+ Process ID of the server process holding or awaiting this
+ lock, or null if the lock is held by a prepared transaction
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>mode</structfield> <type>text</type>
+ </para>
+ <para>
+ Name of the lock mode held or desired by this process (see <xref linkend="locking-tables"/> and <xref linkend="xact-serializable"/>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>granted</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if lock is held, false if lock is awaited
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>fastpath</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if lock was taken via fast path, false if taken via main
+ lock table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>waitstart</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ Time when the server process started waiting for this lock,
+ or null if the lock is held.
+ Note that this can be null for a very short period of time after
+ the wait started even though <structfield>granted</structfield>
+ is <literal>false</literal>.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ <structfield>granted</structfield> is true in a row representing a lock
+ held by the indicated process. False indicates that this process is
+ currently waiting to acquire this lock, which implies that at least one
+ other process is holding or waiting for a conflicting lock mode on the same
+ lockable object. The waiting process will sleep until the other lock is
+ released (or a deadlock situation is detected). A single process can be
+ waiting to acquire at most one lock at a time.
+ </para>
+
+ <para>
+ Throughout running a transaction, a server process holds an exclusive lock
+ on the transaction's virtual transaction ID. If a permanent ID is assigned
+ to the transaction (which normally happens only if the transaction changes
+ the state of the database), it also holds an exclusive lock on the
+ transaction's permanent transaction ID until it ends. When a process finds
+ it necessary to wait specifically for another transaction to end, it does
+ so by attempting to acquire share lock on the other transaction's ID
+ (either virtual or permanent ID depending on the situation). That will
+ succeed only when the other transaction terminates and releases its locks.
+ </para>
+
+ <para>
+ Although tuples are a lockable type of object,
+ information about row-level locks is stored on disk, not in memory,
+ and therefore row-level locks normally do not appear in this view.
+ If a process is waiting for a
+ row-level lock, it will usually appear in the view as waiting for the
+ permanent transaction ID of the current holder of that row lock.
+ </para>
+
+ <para>
+ Advisory locks can be acquired on keys consisting of either a single
+ <type>bigint</type> value or two integer values.
+ A <type>bigint</type> key is displayed with its
+ high-order half in the <structfield>classid</structfield> column, its low-order half
+ in the <structfield>objid</structfield> column, and <structfield>objsubid</structfield> equal
+ to 1. The original <type>bigint</type> value can be reassembled with the
+ expression <literal>(classid::bigint &lt;&lt; 32) |
+ objid::bigint</literal>. Integer keys are displayed with the
+ first key in the
+ <structfield>classid</structfield> column, the second key in the <structfield>objid</structfield>
+ column, and <structfield>objsubid</structfield> equal to 2. The actual meaning of
+ the keys is up to the user. Advisory locks are local to each database,
+ so the <structfield>database</structfield> column is meaningful for an advisory lock.
+ </para>
+
+ <para>
+ <structname>pg_locks</structname> provides a global view of all locks
+ in the database cluster, not only those relevant to the current database.
+ Although its <structfield>relation</structfield> column can be joined
+ against <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield> to identify locked
+ relations, this will only work correctly for relations in the current
+ database (those for which the <structfield>database</structfield> column
+ is either the current database's OID or zero).
+ </para>
+
+ <para>
+ The <structfield>pid</structfield> column can be joined to the
+ <structfield>pid</structfield> column of the
+ <link linkend="monitoring-pg-stat-activity-view">
+ <structname>pg_stat_activity</structname></link>
+ view to get more
+ information on the session holding or awaiting each lock,
+ for example
+<programlisting>
+SELECT * FROM pg_locks pl LEFT JOIN pg_stat_activity psa
+ ON pl.pid = psa.pid;
+</programlisting>
+ Also, if you are using prepared transactions, the
+ <structfield>virtualtransaction</structfield> column can be joined to the
+ <structfield>transaction</structfield> column of the <link
+ linkend="view-pg-prepared-xacts"><structname>pg_prepared_xacts</structname></link>
+ view to get more information on prepared transactions that hold locks.
+ (A prepared transaction can never be waiting for a lock,
+ but it continues to hold the locks it acquired while running.)
+ For example:
+<programlisting>
+SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
+ ON pl.virtualtransaction = '-1/' || ppx.transaction;
+</programlisting>
+ </para>
+
+ <para>
+ While it is possible to obtain information about which processes block
+ which other processes by joining <structname>pg_locks</structname> against
+ itself, this is very difficult to get right in detail. Such a query would
+ have to encode knowledge about which lock modes conflict with which
+ others. Worse, the <structname>pg_locks</structname> view does not expose
+ information about which processes are ahead of which others in lock wait
+ queues, nor information about which processes are parallel workers running
+ on behalf of which other client sessions. It is better to use
+ the <function>pg_blocking_pids()</function> function
+ (see <xref linkend="functions-info-session-table"/>) to identify which
+ process(es) a waiting process is blocked behind.
+ </para>
+
+ <para>
+ The <structname>pg_locks</structname> view displays data from both the
+ regular lock manager and the predicate lock manager, which are
+ separate systems; in addition, the regular lock manager subdivides its
+ locks into regular and <firstterm>fast-path</firstterm> locks.
+ This data is not guaranteed to be entirely consistent.
+ When the view is queried,
+ data on fast-path locks (with <structfield>fastpath</structfield> = <literal>true</literal>)
+ is gathered from each backend one at a time, without freezing the state of
+ the entire lock manager, so it is possible for locks to be taken or
+ released while information is gathered. Note, however, that these locks are
+ known not to conflict with any other lock currently in place. After
+ all backends have been queried for fast-path locks, the remainder of the
+ regular lock manager is locked as a unit, and a consistent snapshot of all
+ remaining locks is collected as an atomic action. After unlocking the
+ regular lock manager, the predicate lock manager is similarly locked and all
+ predicate locks are collected as an atomic action. Thus, with the exception
+ of fast-path locks, each lock manager will deliver a consistent set of
+ results, but as we do not lock both lock managers simultaneously, it is
+ possible for locks to be taken or released after we interrogate the regular
+ lock manager and before we interrogate the predicate lock manager.
+ </para>
+
+ <para>
+ Locking the regular and/or predicate lock manager could have some
+ impact on database performance if this view is very frequently accessed.
+ The locks are held only for the minimum amount of time necessary to
+ obtain data from the lock managers, but this does not completely eliminate
+ the possibility of a performance impact.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-matviews">
+ <title><structname>pg_matviews</structname></title>
+
+ <indexterm zone="view-pg-matviews">
+ <primary>pg_matviews</primary>
+ </indexterm>
+
+ <indexterm zone="view-pg-matviews">
+ <primary>materialized views</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_matviews</structname> provides access to
+ useful information about each materialized view in the database.
+ </para>
+
+ <table>
+ <title><structname>pg_matviews</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing materialized view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>matviewname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of materialized view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>matviewowner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Name of materialized view's owner
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablespace</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.<structfield>spcname</structfield>)
+ </para>
+ <para>
+ Name of tablespace containing materialized view (null if default for database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>hasindexes</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if materialized view has (or recently had) any indexes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>ispopulated</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if materialized view is currently populated
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>definition</structfield> <type>text</type>
+ </para>
+ <para>
+ Materialized view definition (a reconstructed <xref linkend="sql-select"/> query)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-policies">
+ <title><structname>pg_policies</structname></title>
+
+ <indexterm zone="view-pg-policies">
+ <primary>pg_policies</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_policies</structname> provides access to
+ useful information about each row-level security policy in the database.
+ </para>
+
+ <table>
+ <title><structname>pg_policies</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table policy is on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table policy is on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>policyname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-policy"><structname>pg_policy</structname></link>.<structfield>polname</structfield>)
+ </para>
+ <para>
+ Name of policy
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>permissive</structfield> <type>text</type>
+ </para>
+ <para>
+ Is the policy permissive or restrictive?
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>roles</structfield> <type>name[]</type>
+ </para>
+ <para>
+ The roles to which this policy applies
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cmd</structfield> <type>text</type>
+ </para>
+ <para>
+ The command type to which the policy is applied
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>qual</structfield> <type>text</type>
+ </para>
+ <para>
+ The expression added to the security barrier qualifications for
+ queries that this policy applies to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>with_check</structfield> <type>text</type>
+ </para>
+ <para>
+ The expression added to the WITH CHECK qualifications for
+ queries that attempt to add rows to this table
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-prepared-statements">
+ <title><structname>pg_prepared_statements</structname></title>
+
+ <indexterm zone="view-pg-prepared-statements">
+ <primary>pg_prepared_statements</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_prepared_statements</structname> view displays
+ all the prepared statements that are available in the current
+ session. See <xref linkend="sql-prepare"/> for more information about prepared
+ statements.
+ </para>
+
+ <para>
+ <structname>pg_prepared_statements</structname> contains one row
+ for each prepared statement. Rows are added to the view when a new
+ prepared statement is created and removed when a prepared statement
+ is released (for example, via the <link linkend="sql-deallocate"><command>DEALLOCATE</command></link> command).
+ </para>
+
+ <table>
+ <title><structname>pg_prepared_statements</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ The identifier of the prepared statement
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statement</structfield> <type>text</type>
+ </para>
+ <para>
+ The query string submitted by the client to create this
+ prepared statement. For prepared statements created via SQL,
+ this is the <command>PREPARE</command> statement submitted by
+ the client. For prepared statements created via the
+ frontend/backend protocol, this is the text of the prepared
+ statement itself.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prepare_time</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ The time at which the prepared statement was created
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>parameter_types</structfield> <type>regtype[]</type>
+ </para>
+ <para>
+ The expected parameter types for the prepared statement in the
+ form of an array of <type>regtype</type>. The OID corresponding
+ to an element of this array can be obtained by casting the
+ <type>regtype</type> value to <type>oid</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>from_sql</structfield> <type>bool</type>
+ </para>
+ <para>
+ <literal>true</literal> if the prepared statement was created
+ via the <command>PREPARE</command> SQL command;
+ <literal>false</literal> if the statement was prepared via the
+ frontend/backend protocol
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>generic_plans</structfield> <type>int8</type>
+ </para>
+ <para>
+ Number of times generic plan was chosen
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>custom_plans</structfield> <type>int8</type>
+ </para>
+ <para>
+ Number of times custom plan was chosen
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_prepared_statements</structname> view is read-only.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-prepared-xacts">
+ <title><structname>pg_prepared_xacts</structname></title>
+
+ <indexterm zone="view-pg-prepared-xacts">
+ <primary>pg_prepared_xacts</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_prepared_xacts</structname> displays
+ information about transactions that are currently prepared for two-phase
+ commit (see <xref linkend="sql-prepare-transaction"/> for details).
+ </para>
+
+ <para>
+ <structname>pg_prepared_xacts</structname> contains one row per prepared
+ transaction. An entry is removed when the transaction is committed or
+ rolled back.
+ </para>
+
+ <table>
+ <title><structname>pg_prepared_xacts</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>transaction</structfield> <type>xid</type>
+ </para>
+ <para>
+ Numeric transaction identifier of the prepared transaction
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>gid</structfield> <type>text</type>
+ </para>
+ <para>
+ Global transaction identifier that was assigned to the transaction
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>prepared</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ Time at which the transaction was prepared for commit
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>owner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Name of the user that executed the transaction
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>database</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>datname</structfield>)
+ </para>
+ <para>
+ Name of the database in which the transaction was executed
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ When the <structname>pg_prepared_xacts</structname> view is accessed, the
+ internal transaction manager data structures are momentarily locked, and
+ a copy is made for the view to display. This ensures that the
+ view produces a consistent set of results, while not blocking
+ normal operations longer than necessary. Nonetheless
+ there could be some impact on database performance if this view is
+ frequently accessed.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-publication-tables">
+ <title><structname>pg_publication_tables</structname></title>
+
+ <indexterm zone="view-pg-publication-tables">
+ <primary>pg_publication_tables</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_publication_tables</structname> provides
+ information about the mapping between publications and information of
+ tables they contain. Unlike the underlying catalog
+ <link linkend="catalog-pg-publication-rel"><structname>pg_publication_rel</structname></link>,
+ this view expands publications defined as <literal>FOR ALL TABLES</literal>
+ and <literal>FOR TABLES IN SCHEMA</literal>, so for such publications
+ there will be a row for each eligible table.
+ </para>
+
+ <table>
+ <title><structname>pg_publication_tables</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pubname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-publication"><structname>pg_publication</structname></link>.<structfield>pubname</structfield>)
+ </para>
+ <para>
+ Name of publication
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attnames</structfield> <type>name[]</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attname</structfield>)
+ </para>
+ <para>
+ Names of table columns included in the publication. This contains all
+ the columns of the table when the user didn't specify the column list
+ for the table.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rowfilter</structfield> <type>text</type>
+ </para>
+ <para>
+ Expression for the table's publication qualifying condition
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="view-pg-replication-origin-status">
+ <title><structname>pg_replication_origin_status</structname></title>
+
+ <indexterm zone="view-pg-replication-origin-status">
+ <primary>pg_replication_origin_status</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_replication_origin_status</structname> view
+ contains information about how far replay for a certain origin has
+ progressed. For more on replication origins
+ see <xref linkend="replication-origins"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_replication_origin_status</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>local_id</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-replication-origin"><structname>pg_replication_origin</structname></link>.<structfield>roident</structfield>)
+ </para>
+ <para>
+ internal node identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>external_id</structfield> <type>text</type>
+ (references <link linkend="catalog-pg-replication-origin"><structname>pg_replication_origin</structname></link>.<structfield>roname</structfield>)
+ </para>
+ <para>
+ external node identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>remote_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ The origin node's LSN up to which data has been replicated.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>local_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ This node's LSN at which <literal>remote_lsn</literal> has
+ been replicated. Used to flush commit records before persisting
+ data to disk when using asynchronous commits.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="view-pg-replication-slots">
+ <title><structname>pg_replication_slots</structname></title>
+
+ <indexterm zone="view-pg-replication-slots">
+ <primary>pg_replication_slots</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_replication_slots</structname> view provides a listing
+ of all replication slots that currently exist on the database cluster,
+ along with their current state.
+ </para>
+
+ <para>
+ For more on replication slots,
+ see <xref linkend="streaming-replication-slots"/> and <xref linkend="logicaldecoding"/>.
+ </para>
+
+ <table>
+ <title><structname>pg_replication_slots</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slot_name</structfield> <type>name</type>
+ </para>
+ <para>
+ A unique, cluster-wide identifier for the replication slot
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>plugin</structfield> <type>name</type>
+ </para>
+ <para>
+ The base name of the shared object containing the output plugin this logical slot is using, or null for physical slots.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>slot_type</structfield> <type>text</type>
+ </para>
+ <para>
+ The slot type: <literal>physical</literal> or <literal>logical</literal>
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>datoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the database this slot is associated with, or
+ null. Only logical slots have an associated database.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>database</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-database"><structname>pg_database</structname></link>.<structfield>datname</structfield>)
+ </para>
+ <para>
+ The name of the database this slot is associated with, or
+ null. Only logical slots have an associated database.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>temporary</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this is a temporary replication slot. Temporary slots are
+ not saved to disk and are automatically dropped on error or when
+ the session has finished.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>active</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this slot is currently actively being used
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>active_pid</structfield> <type>int4</type>
+ </para>
+ <para>
+ The process ID of the session using this slot if the slot
+ is currently actively being used. <literal>NULL</literal> if
+ inactive.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>xmin</structfield> <type>xid</type>
+ </para>
+ <para>
+ The oldest transaction that this slot needs the database to
+ retain. <literal>VACUUM</literal> cannot remove tuples deleted
+ by any later transaction.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>catalog_xmin</structfield> <type>xid</type>
+ </para>
+ <para>
+ The oldest transaction affecting the system catalogs that this
+ slot needs the database to retain. <literal>VACUUM</literal> cannot
+ remove catalog tuples deleted by any later transaction.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>restart_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ The address (<literal>LSN</literal>) of oldest WAL which still
+ might be required by the consumer of this slot and thus won't be
+ automatically removed during checkpoints unless this LSN
+ gets behind more than <xref linkend="guc-max-slot-wal-keep-size"/>
+ from the current LSN. <literal>NULL</literal>
+ if the <literal>LSN</literal> of this slot has never been reserved.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>confirmed_flush_lsn</structfield> <type>pg_lsn</type>
+ </para>
+ <para>
+ The address (<literal>LSN</literal>) up to which the logical
+ slot's consumer has confirmed receiving data. Data older than this is
+ not available anymore. <literal>NULL</literal> for physical slots.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>wal_status</structfield> <type>text</type>
+ </para>
+ <para>
+ Availability of WAL files claimed by this slot.
+ Possible values are:
+ <itemizedlist>
+ <listitem>
+ <para><literal>reserved</literal> means that the claimed files
+ are within <varname>max_wal_size</varname>.</para>
+ </listitem>
+ <listitem>
+ <para><literal>extended</literal> means
+ that <varname>max_wal_size</varname> is exceeded but the files are
+ still retained, either by the replication slot or
+ by <varname>wal_keep_size</varname>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>unreserved</literal> means that the slot no longer
+ retains the required WAL files and some of them are to be removed at
+ the next checkpoint. This state can return
+ to <literal>reserved</literal> or <literal>extended</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>lost</literal> means that some required WAL files have
+ been removed and this slot is no longer usable.
+ </para>
+ </listitem>
+ </itemizedlist>
+ The last two states are seen only when
+ <xref linkend="guc-max-slot-wal-keep-size"/> is
+ non-negative. If <structfield>restart_lsn</structfield> is NULL, this
+ field is null.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>safe_wal_size</structfield> <type>int8</type>
+ </para>
+ <para>
+ The number of bytes that can be written to WAL such that this slot
+ is not in danger of getting in state "lost". It is NULL for lost
+ slots, as well as if <varname>max_slot_wal_keep_size</varname>
+ is <literal>-1</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>two_phase</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if the slot is enabled for decoding prepared transactions. Always
+ false for physical slots.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="view-pg-roles">
+ <title><structname>pg_roles</structname></title>
+
+ <indexterm zone="view-pg-roles">
+ <primary>pg_roles</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_roles</structname> provides access to
+ information about database roles. This is simply a publicly
+ readable view of
+ <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>
+ that blanks out the password field.
+ </para>
+
+ <table>
+ <title><structname>pg_roles</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolname</structfield> <type>name</type>
+ </para>
+ <para>
+ Role name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolsuper</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role has superuser privileges
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolinherit</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role automatically inherits privileges of roles it is a
+ member of
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolcreaterole</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role can create more roles
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolcreatedb</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role can create databases
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolcanlogin</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role can log in. That is, this role can be given as the initial
+ session authorization identifier
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolreplication</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role is a replication role. A replication role can initiate replication
+ connections and create and drop replication slots.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolconnlimit</structfield> <type>int4</type>
+ </para>
+ <para>
+ For roles that can log in, this sets maximum number of concurrent
+ connections this role can make. -1 means no limit.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolpassword</structfield> <type>text</type>
+ </para>
+ <para>
+ Not the password (always reads as <literal>********</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolvaliduntil</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ Password expiry time (only used for password authentication);
+ null if no expiration
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolbypassrls</structfield> <type>bool</type>
+ </para>
+ <para>
+ Role bypasses every row-level security policy, see
+ <xref linkend="ddl-rowsecurity"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rolconfig</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Role-specific defaults for run-time configuration variables
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>oid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ ID of role
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-rules">
+ <title><structname>pg_rules</structname></title>
+
+ <indexterm zone="view-pg-rules">
+ <primary>pg_rules</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_rules</structname> provides access to
+ useful information about query rewrite rules.
+ </para>
+
+ <table>
+ <title><structname>pg_rules</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table the rule is for
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rulename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-rewrite"><structname>pg_rewrite</structname></link>.<structfield>rulename</structfield>)
+ </para>
+ <para>
+ Name of rule
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>definition</structfield> <type>text</type>
+ </para>
+ <para>
+ Rule definition (a reconstructed creation command)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_rules</structname> view excludes the <literal>ON SELECT</literal> rules
+ of views and materialized views; those can be seen in
+ <link linkend="view-pg-views"><structname>pg_views</structname></link> and <link linkend="view-pg-matviews"><structname>pg_matviews</structname></link>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-seclabels">
+ <title><structname>pg_seclabels</structname></title>
+
+ <indexterm zone="view-pg-seclabels">
+ <primary>pg_seclabels</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_seclabels</structname> provides information about
+ security labels. It as an easier-to-query version of the
+ <link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link> catalog.
+ </para>
+
+ <table>
+ <title><structname>pg_seclabels</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objoid</structfield> <type>oid</type>
+ (references any OID column)
+ </para>
+ <para>
+ The OID of the object this security label pertains to
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>classoid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the system catalog this object appears in
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objsubid</structfield> <type>int4</type>
+ </para>
+ <para>
+ For a security label on a table column, this is the column number (the
+ <structfield>objoid</structfield> and <structfield>classoid</structfield> refer to
+ the table itself). For all other object types, this column is
+ zero.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objtype</structfield> <type>text</type>
+ </para>
+ <para>
+ The type of object to which this label applies, as text.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objnamespace</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the namespace for this object, if applicable;
+ otherwise NULL.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>objname</structfield> <type>text</type>
+ </para>
+ <para>
+ The name of the object to which this label applies, as text.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>provider</structfield> <type>text</type>
+ (references <link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link>.<structfield>provider</structfield>)
+ </para>
+ <para>
+ The label provider associated with this label.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>label</structfield> <type>text</type>
+ (references <link linkend="catalog-pg-seclabel"><structname>pg_seclabel</structname></link>.<structfield>label</structfield>)
+ </para>
+ <para>
+ The security label applied to this object.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="view-pg-sequences">
+ <title><structname>pg_sequences</structname></title>
+
+ <indexterm zone="view-pg-sequences">
+ <primary>pg_sequences</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_sequences</structname> provides access to
+ useful information about each sequence in the database.
+ </para>
+
+ <table>
+ <title><structname>pg_sequences</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequencename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sequenceowner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Name of sequence's owner
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>data_type</structfield> <type>regtype</type>
+ (references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ Data type of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>start_value</structfield> <type>int8</type>
+ </para>
+ <para>
+ Start value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>min_value</structfield> <type>int8</type>
+ </para>
+ <para>
+ Minimum value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>max_value</structfield> <type>int8</type>
+ </para>
+ <para>
+ Maximum value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>increment_by</structfield> <type>int8</type>
+ </para>
+ <para>
+ Increment value of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cycle</structfield> <type>bool</type>
+ </para>
+ <para>
+ Whether the sequence cycles
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>cache_size</structfield> <type>int8</type>
+ </para>
+ <para>
+ Cache size of the sequence
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>last_value</structfield> <type>int8</type>
+ </para>
+ <para>
+ The last sequence value written to disk. If caching is used,
+ this value can be greater than the last value handed out from the
+ sequence. Null if the sequence has not been read from yet. Also, if
+ the current user does not have <literal>USAGE</literal>
+ or <literal>SELECT</literal> privilege on the sequence, the value is
+ null.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="view-pg-settings">
+ <title><structname>pg_settings</structname></title>
+
+ <indexterm zone="view-pg-settings">
+ <primary>pg_settings</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_settings</structname> provides access to
+ run-time parameters of the server. It is essentially an alternative
+ interface to the <link linkend="sql-show"><command>SHOW</command></link>
+ and <link linkend="sql-set"><command>SET</command></link> commands.
+ It also provides access to some facts about each parameter that are
+ not directly available from <link linkend="sql-show"><command>SHOW</command></link>, such as minimum and
+ maximum values.
+ </para>
+
+ <table>
+ <title><structname>pg_settings</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ Run-time configuration parameter name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>setting</structfield> <type>text</type>
+ </para>
+ <para>
+ Current value of the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>unit</structfield> <type>text</type>
+ </para>
+ <para>
+ Implicit unit of the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>category</structfield> <type>text</type>
+ </para>
+ <para>
+ Logical group of the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>short_desc</structfield> <type>text</type>
+ </para>
+ <para>
+ A brief description of the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>extra_desc</structfield> <type>text</type>
+ </para>
+ <para>
+ Additional, more detailed, description of the parameter
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>context</structfield> <type>text</type>
+ </para>
+ <para>
+ Context required to set the parameter's value (see below)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>vartype</structfield> <type>text</type>
+ </para>
+ <para>
+ Parameter type (<literal>bool</literal>, <literal>enum</literal>,
+ <literal>integer</literal>, <literal>real</literal>, or <literal>string</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>source</structfield> <type>text</type>
+ </para>
+ <para>
+ Source of the current parameter value
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>min_val</structfield> <type>text</type>
+ </para>
+ <para>
+ Minimum allowed value of the parameter (null for non-numeric
+ values)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>max_val</structfield> <type>text</type>
+ </para>
+ <para>
+ Maximum allowed value of the parameter (null for non-numeric
+ values)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>enumvals</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Allowed values of an enum parameter (null for non-enum
+ values)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>boot_val</structfield> <type>text</type>
+ </para>
+ <para>
+ Parameter value assumed at server startup if the parameter is
+ not otherwise set
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>reset_val</structfield> <type>text</type>
+ </para>
+ <para>
+ Value that <link linkend="sql-reset"><command>RESET</command></link> would reset the parameter to
+ in the current session
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sourcefile</structfield> <type>text</type>
+ </para>
+ <para>
+ Configuration file the current value was set in (null for
+ values set from sources other than configuration files, or when
+ examined by a user who neither is a superuser nor has privileges of
+ <literal>pg_read_all_settings</literal>); helpful when using
+ <literal>include</literal> directives in configuration files
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>sourceline</structfield> <type>int4</type>
+ </para>
+ <para>
+ Line number within the configuration file the current value was
+ set at (null for values set from sources other than configuration files,
+ or when examined by a user who neither is a superuser nor has privileges of
+ <literal>pg_read_all_settings</literal>).
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>pending_restart</structfield> <type>bool</type>
+ </para>
+ <para>
+ <literal>true</literal> if the value has been changed in the
+ configuration file but needs a restart; or <literal>false</literal>
+ otherwise.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ There are several possible values of <structfield>context</structfield>.
+ In order of decreasing difficulty of changing the setting, they are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <!-- PGC_INTERNAL -->
+ <term><literal>internal</literal></term>
+ <listitem>
+ <para>
+ These settings cannot be changed directly; they reflect internally
+ determined values. Some of them may be adjustable by rebuilding the
+ server with different configuration options, or by changing options
+ supplied to <application>initdb</application>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <!-- PGC_POSTMASTER -->
+ <term><literal>postmaster</literal></term>
+ <listitem>
+ <para>
+ These settings can only be applied when the server starts, so any change
+ requires restarting the server. Values for these settings are typically
+ stored in the <filename>postgresql.conf</filename> file, or passed on
+ the command line when starting the server. Of course, settings with any
+ of the lower <structfield>context</structfield> types can also be
+ set at server start time.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <!-- PGC_SIGHUP -->
+ <term><literal>sighup</literal></term>
+ <listitem>
+ <para>
+ Changes to these settings can be made in
+ <filename>postgresql.conf</filename> without restarting the server.
+ Send a <systemitem>SIGHUP</systemitem> signal to the postmaster to
+ cause it to re-read <filename>postgresql.conf</filename> and apply
+ the changes. The postmaster will also forward the
+ <systemitem>SIGHUP</systemitem> signal to its child processes so that
+ they all pick up the new value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <!-- PGC_SU_BACKEND -->
+ <term><literal>superuser-backend</literal></term>
+ <listitem>
+ <para>
+ Changes to these settings can be made in
+ <filename>postgresql.conf</filename> without restarting the server.
+ They can also be set for a particular session in the connection request
+ packet (for example, via <application>libpq</application>'s <literal>PGOPTIONS</literal>
+ environment variable), but only if the connecting user is a superuser
+ or has been granted the appropriate <literal>SET</literal> privilege.
+ However, these settings never change in a session after it is started.
+ If you change them in <filename>postgresql.conf</filename>, send a
+ <systemitem>SIGHUP</systemitem> signal to the postmaster to cause it to
+ re-read <filename>postgresql.conf</filename>. The new values will only
+ affect subsequently-launched sessions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <!-- PGC_BACKEND -->
+ <term><literal>backend</literal></term>
+ <listitem>
+ <para>
+ Changes to these settings can be made in
+ <filename>postgresql.conf</filename> without restarting the server.
+ They can also be set for a particular session in the connection request
+ packet (for example, via <application>libpq</application>'s <literal>PGOPTIONS</literal>
+ environment variable); any user can make such a change for their session.
+ However, these settings never change in a session after it is started.
+ If you change them in <filename>postgresql.conf</filename>, send a
+ <systemitem>SIGHUP</systemitem> signal to the postmaster to cause it to
+ re-read <filename>postgresql.conf</filename>. The new values will only
+ affect subsequently-launched sessions.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <!-- PGC_SUSET -->
+ <term><literal>superuser</literal></term>
+ <listitem>
+ <para>
+ These settings can be set from <filename>postgresql.conf</filename>,
+ or within a session via the <command>SET</command> command; but only superusers
+ and users with the appropriate <literal>SET</literal> privilege
+ can change them via <command>SET</command>. Changes in
+ <filename>postgresql.conf</filename> will affect existing sessions
+ only if no session-local value has been established with <command>SET</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <!-- PGC_USERSET -->
+ <term><literal>user</literal></term>
+ <listitem>
+ <para>
+ These settings can be set from <filename>postgresql.conf</filename>,
+ or within a session via the <command>SET</command> command. Any user is
+ allowed to change their session-local value. Changes in
+ <filename>postgresql.conf</filename> will affect existing sessions
+ only if no session-local value has been established with <command>SET</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ See <xref linkend="config-setting"/> for more information about the various
+ ways to change these parameters.
+ </para>
+
+ <para>
+ This view cannot be inserted into or deleted from, but it can be updated. An
+ <command>UPDATE</command> applied to a row of <structname>pg_settings</structname>
+ is equivalent to executing the <command>SET</command> command on that named
+ parameter. The change only affects the value used by the current
+ session. If an <command>UPDATE</command> is issued within a transaction
+ that is later aborted, the effects of the <command>UPDATE</command> command
+ disappear when the transaction is rolled back. Once the surrounding
+ transaction is committed, the effects will persist until the end of the
+ session, unless overridden by another <command>UPDATE</command> or
+ <command>SET</command>.
+ </para>
+
+ <para>
+ This view does not
+ display <link linkend="runtime-config-custom">customized options</link>
+ unless the extension module that defines them has been loaded by the
+ backend process executing the query (e.g., via a mention in
+ <xref linkend="guc-shared-preload-libraries"/>,
+ a call to a C function in the extension, or the
+ <link linkend="sql-load"><command>LOAD</command></link> command).
+ For example, since <link linkend="archive-modules">archive modules</link>
+ are normally loaded only by the archiver process not regular sessions,
+ this view will not display any customized options defined by such modules
+ unless special action is taken to load them into the backend process
+ executing the query.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-shadow">
+ <title><structname>pg_shadow</structname></title>
+
+ <indexterm zone="view-pg-shadow">
+ <primary>pg_shadow</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_shadow</structname> exists for backwards
+ compatibility: it emulates a catalog that existed in
+ <productname>PostgreSQL</productname> before version 8.1.
+ It shows properties of all roles that are marked as
+ <structfield>rolcanlogin</structfield> in
+ <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.
+ </para>
+
+ <para>
+ The name stems from the fact that this table
+ should not be readable by the public since it contains passwords.
+ <link linkend="view-pg-user"><structname>pg_user</structname></link>
+ is a publicly readable view on
+ <structname>pg_shadow</structname> that blanks out the password field.
+ </para>
+
+ <table>
+ <title><structname>pg_shadow</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ User name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usesysid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ ID of this user
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usecreatedb</structfield> <type>bool</type>
+ </para>
+ <para>
+ User can create databases
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usesuper</structfield> <type>bool</type>
+ </para>
+ <para>
+ User is a superuser
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>userepl</structfield> <type>bool</type>
+ </para>
+ <para>
+ User can initiate streaming replication and put the system in and
+ out of backup mode.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usebypassrls</structfield> <type>bool</type>
+ </para>
+ <para>
+ User bypasses every row-level security policy, see
+ <xref linkend="ddl-rowsecurity"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>passwd</structfield> <type>text</type>
+ </para>
+ <para>
+ Password (possibly encrypted); null if none. See
+ <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>
+ for details of how encrypted passwords are stored.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>valuntil</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ Password expiry time (only used for password authentication)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>useconfig</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Session defaults for run-time configuration variables
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-shmem-allocations">
+ <title><structname>pg_shmem_allocations</structname></title>
+
+ <indexterm zone="view-pg-shmem-allocations">
+ <primary>pg_shmem_allocations</primary>
+ </indexterm>
+
+ <para>
+ The <structname>pg_shmem_allocations</structname> view shows allocations
+ made from the server's main shared memory segment. This includes both
+ memory allocated by <productname>PostgreSQL</productname> itself and memory
+ allocated by extensions using the mechanisms detailed in
+ <xref linkend="xfunc-shared-addin" />.
+ </para>
+
+ <para>
+ Note that this view does not include memory allocated using the dynamic
+ shared memory infrastructure.
+ </para>
+
+ <table>
+ <title><structname>pg_shmem_allocations</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ The name of the shared memory allocation. NULL for unused memory
+ and <literal>&lt;anonymous&gt;</literal> for anonymous
+ allocations.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>off</structfield> <type>int8</type>
+ </para>
+ <para>
+ The offset at which the allocation starts. NULL for anonymous
+ allocations, since details related to them are not known.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>size</structfield> <type>int8</type>
+ </para>
+ <para>
+ Size of the allocation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>allocated_size</structfield> <type>int8</type>
+ </para>
+ <para>
+ Size of the allocation including padding. For anonymous
+ allocations, no information about padding is available, so the
+ <literal>size</literal> and <literal>allocated_size</literal> columns
+ will always be equal. Padding is not meaningful for free memory, so
+ the columns will be equal in that case also.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Anonymous allocations are allocations that have been made
+ with <literal>ShmemAlloc()</literal> directly, rather than via
+ <literal>ShmemInitStruct()</literal> or
+ <literal>ShmemInitHash()</literal>.
+ </para>
+
+ <para>
+ By default, the <structname>pg_shmem_allocations</structname> view can be
+ read only by superusers or roles with privileges of the
+ <literal>pg_read_all_stats</literal> role.
+ </para>
+ </sect1>
+
+ <sect1 id="view-pg-stats">
+ <title><structname>pg_stats</structname></title>
+
+ <indexterm zone="view-pg-stats">
+ <primary>pg_stats</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_stats</structname> provides access to
+ the information stored in the <link
+ linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>
+ catalog. This view allows access only to rows of
+ <link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link> that correspond to tables the
+ user has permission to read, and therefore it is safe to allow public
+ read access to this view.
+ </para>
+
+ <para>
+ <structname>pg_stats</structname> is also designed to present the
+ information in a more readable format than the underlying catalog
+ &mdash; at the cost that its schema must be extended whenever new slot types
+ are defined for <link linkend="catalog-pg-statistic"><structname>pg_statistic</structname></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_stats</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attname</structfield>)
+ </para>
+ <para>
+ Name of column described by this row
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inherited</structfield> <type>bool</type>
+ </para>
+ <para>
+ If true, this row includes values from child tables, not just the
+ values in the specified table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>null_frac</structfield> <type>float4</type>
+ </para>
+ <para>
+ Fraction of column entries that are null
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>avg_width</structfield> <type>int4</type>
+ </para>
+ <para>
+ Average width in bytes of column's entries
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_distinct</structfield> <type>float4</type>
+ </para>
+ <para>
+ If greater than zero, the estimated number of distinct values in the
+ column. If less than zero, the negative of the number of distinct
+ values divided by the number of rows. (The negated form is used when
+ <command>ANALYZE</command> believes that the number of distinct values is
+ likely to increase as the table grows; the positive form is used when
+ the column seems to have a fixed number of possible values.) For
+ example, -1 indicates a unique column in which the number of distinct
+ values is the same as the number of rows.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_vals</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ A list of the most common values in the column. (Null if
+ no values seem to be more common than any others.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_freqs</structfield> <type>float4[]</type>
+ </para>
+ <para>
+ A list of the frequencies of the most common values,
+ i.e., number of occurrences of each divided by total number of rows.
+ (Null when <structfield>most_common_vals</structfield> is.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>histogram_bounds</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ A list of values that divide the column's values into groups of
+ approximately equal population. The values in
+ <structfield>most_common_vals</structfield>, if present, are omitted from this
+ histogram calculation. (This column is null if the column data type
+ does not have a <literal>&lt;</literal> operator or if the
+ <structfield>most_common_vals</structfield> list accounts for the entire
+ population.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>correlation</structfield> <type>float4</type>
+ </para>
+ <para>
+ Statistical correlation between physical row ordering and
+ logical ordering of the column values. This ranges from -1 to +1.
+ When the value is near -1 or +1, an index scan on the column will
+ be estimated to be cheaper than when it is near zero, due to reduction
+ of random access to the disk. (This column is null if the column data
+ type does not have a <literal>&lt;</literal> operator.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_elems</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ A list of non-null element values most often appearing within values of
+ the column. (Null for scalar types.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_elem_freqs</structfield> <type>float4[]</type>
+ </para>
+ <para>
+ A list of the frequencies of the most common element values, i.e., the
+ fraction of rows containing at least one instance of the given value.
+ Two or three additional values follow the per-element frequencies;
+ these are the minimum and maximum of the preceding per-element
+ frequencies, and optionally the frequency of null elements.
+ (Null when <structfield>most_common_elems</structfield> is.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>elem_count_histogram</structfield> <type>float4[]</type>
+ </para>
+ <para>
+ A histogram of the counts of distinct non-null element values within the
+ values of the column, followed by the average number of distinct
+ non-null elements. (Null for scalar types.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The maximum number of entries in the array fields can be controlled on a
+ column-by-column basis using the <link linkend="sql-altertable"><command>ALTER
+ TABLE SET STATISTICS</command></link>
+ command, or globally by setting the
+ <xref linkend="guc-default-statistics-target"/> run-time parameter.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-stats-ext">
+ <title><structname>pg_stats_ext</structname></title>
+
+ <indexterm zone="view-pg-stats-ext">
+ <primary>pg_stats_ext</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_stats_ext</structname> provides access to
+ information about each extended statistics object in the database,
+ combining information stored in the <link
+ linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>
+ and <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>
+ catalogs. This view allows access only to rows of
+ <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link> and <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>
+ that correspond to tables the user has permission to read, and therefore
+ it is safe to allow public read access to this view.
+ </para>
+
+ <para>
+ <structname>pg_stats_ext</structname> is also designed to present the
+ information in a more readable format than the underlying catalogs
+ &mdash; at the cost that its schema must be extended whenever new types
+ of extended statistics are added to <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.
+ </para>
+
+ <table>
+ <title><structname>pg_stats_ext</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statistics_schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statistics_name</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxname</structfield>)
+ </para>
+ <para>
+ Name of extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statistics_owner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Owner of the extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>attnames</structfield> <type>name[]</type>
+ (references <link linkend="catalog-pg-attribute"><structname>pg_attribute</structname></link>.<structfield>attname</structfield>)
+ </para>
+ <para>
+ Names of the columns included in the extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>exprs</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Expressions included in the extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>kinds</structfield> <type>char[]</type>
+ </para>
+ <para>
+ Types of extended statistics object enabled for this record
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inherited</structfield> <type>bool</type>
+ (references <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>.<structfield>stxdinherit</structfield>)
+ </para>
+ <para>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_distinct</structfield> <type>pg_ndistinct</type>
+ </para>
+ <para>
+ N-distinct counts for combinations of column values. If greater
+ than zero, the estimated number of distinct values in the combination.
+ If less than zero, the negative of the number of distinct values divided
+ by the number of rows.
+ (The negated form is used when <command>ANALYZE</command> believes that
+ the number of distinct values is likely to increase as the table grows;
+ the positive form is used when the column seems to have a fixed number
+ of possible values.) For example, -1 indicates a unique combination of
+ columns in which the number of distinct combinations is the same as the
+ number of rows.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>dependencies</structfield> <type>pg_dependencies</type>
+ </para>
+ <para>
+ Functional dependency statistics
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_vals</structfield> <type>text[]</type>
+ </para>
+ <para>
+ A list of the most common combinations of values in the columns.
+ (Null if no combinations seem to be more common than any others.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_val_nulls</structfield> <type>bool[]</type>
+ </para>
+ <para>
+ A list of NULL flags for the most common combinations of values.
+ (Null when <structfield>most_common_vals</structfield> is.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_freqs</structfield> <type>float8[]</type>
+ </para>
+ <para>
+ A list of the frequencies of the most common combinations,
+ i.e., number of occurrences of each divided by total number of rows.
+ (Null when <structfield>most_common_vals</structfield> is.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_base_freqs</structfield> <type>float8[]</type>
+ </para>
+ <para>
+ A list of the base frequencies of the most common combinations,
+ i.e., product of per-value frequencies.
+ (Null when <structfield>most_common_vals</structfield> is.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The maximum number of entries in the array fields can be controlled on a
+ column-by-column basis using the <link linkend="sql-altertable"><command>ALTER
+ TABLE SET STATISTICS</command></link> command, or globally by setting the
+ <xref linkend="guc-default-statistics-target"/> run-time parameter.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-stats-ext-exprs">
+ <title><structname>pg_stats_ext_exprs</structname></title>
+
+ <indexterm zone="view-pg-stats-ext-exprs">
+ <primary>pg_stats_ext_exprs</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_stats_ext_exprs</structname> provides access to
+ information about all expressions included in extended statistics objects,
+ combining information stored in the <link
+ linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>
+ and <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>
+ catalogs. This view allows access only to rows of
+ <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link> and <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>
+ that correspond to tables the user has permission to read, and therefore
+ it is safe to allow public read access to this view.
+ </para>
+
+ <para>
+ <structname>pg_stats_ext_exprs</structname> is also designed to present
+ the information in a more readable format than the underlying catalogs
+ &mdash; at the cost that its schema must be extended whenever the structure
+ of statistics in <structname>pg_statistic_ext</structname> changes.
+ </para>
+
+ <table>
+ <title><structname>pg_stats_ext_exprs</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table the statistics object is defined on
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statistics_schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statistics_name</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-statistic-ext"><structname>pg_statistic_ext</structname></link>.<structfield>stxname</structfield>)
+ </para>
+ <para>
+ Name of extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>statistics_owner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Owner of the extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>expr</structfield> <type>text</type>
+ </para>
+ <para>
+ Expression included in the extended statistics object
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>inherited</structfield> <type>bool</type>
+ (references <link linkend="catalog-pg-statistic-ext-data"><structname>pg_statistic_ext_data</structname></link>.<structfield>stxdinherit</structfield>)
+ </para>
+ <para>
+ If true, the stats include values from child tables, not just the
+ values in the specified relation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>null_frac</structfield> <type>float4</type>
+ </para>
+ <para>
+ Fraction of expression entries that are null
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>avg_width</structfield> <type>int4</type>
+ </para>
+ <para>
+ Average width in bytes of expression's entries
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>n_distinct</structfield> <type>float4</type>
+ </para>
+ <para>
+ If greater than zero, the estimated number of distinct values in the
+ expression. If less than zero, the negative of the number of distinct
+ values divided by the number of rows. (The negated form is used when
+ <command>ANALYZE</command> believes that the number of distinct values is
+ likely to increase as the table grows; the positive form is used when
+ the expression seems to have a fixed number of possible values.) For
+ example, -1 indicates a unique expression in which the number of distinct
+ values is the same as the number of rows.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_vals</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ A list of the most common values in the expression. (Null if
+ no values seem to be more common than any others.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_freqs</structfield> <type>float4[]</type>
+ </para>
+ <para>
+ A list of the frequencies of the most common values,
+ i.e., number of occurrences of each divided by total number of rows.
+ (Null when <structfield>most_common_vals</structfield> is.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>histogram_bounds</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ A list of values that divide the expression's values into groups of
+ approximately equal population. The values in
+ <structfield>most_common_vals</structfield>, if present, are omitted from this
+ histogram calculation. (This expression is null if the expression data type
+ does not have a <literal>&lt;</literal> operator or if the
+ <structfield>most_common_vals</structfield> list accounts for the entire
+ population.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>correlation</structfield> <type>float4</type>
+ </para>
+ <para>
+ Statistical correlation between physical row ordering and
+ logical ordering of the expression values. This ranges from -1 to +1.
+ When the value is near -1 or +1, an index scan on the expression will
+ be estimated to be cheaper than when it is near zero, due to reduction
+ of random access to the disk. (This expression is null if the expression's
+ data type does not have a <literal>&lt;</literal> operator.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_elems</structfield> <type>anyarray</type>
+ </para>
+ <para>
+ A list of non-null element values most often appearing within values of
+ the expression. (Null for scalar types.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>most_common_elem_freqs</structfield> <type>float4[]</type>
+ </para>
+ <para>
+ A list of the frequencies of the most common element values, i.e., the
+ fraction of rows containing at least one instance of the given value.
+ Two or three additional values follow the per-element frequencies;
+ these are the minimum and maximum of the preceding per-element
+ frequencies, and optionally the frequency of null elements.
+ (Null when <structfield>most_common_elems</structfield> is.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>elem_count_histogram</structfield> <type>float4[]</type>
+ </para>
+ <para>
+ A histogram of the counts of distinct non-null element values within the
+ values of the expression, followed by the average number of distinct
+ non-null elements. (Null for scalar types.)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The maximum number of entries in the array fields can be controlled on a
+ column-by-column basis using the <link linkend="sql-altertable"><command>ALTER
+ TABLE SET STATISTICS</command></link> command, or globally by setting the
+ <xref linkend="guc-default-statistics-target"/> run-time parameter.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-tables">
+ <title><structname>pg_tables</structname></title>
+
+ <indexterm zone="view-pg-tables">
+ <primary>pg_tables</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_tables</structname> provides access to
+ useful information about each table in the database.
+ </para>
+
+ <table>
+ <title><structname>pg_tables</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablename</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of table
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tableowner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Name of table's owner
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>tablespace</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-tablespace"><structname>pg_tablespace</structname></link>.<structfield>spcname</structfield>)
+ </para>
+ <para>
+ Name of tablespace containing table (null if default for database)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>hasindexes</structfield> <type>bool</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relhasindex</structfield>)
+ </para>
+ <para>
+ True if table has (or recently had) any indexes
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>hasrules</structfield> <type>bool</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relhasrules</structfield>)
+ </para>
+ <para>
+ True if table has (or once had) rules
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>hastriggers</structfield> <type>bool</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relhastriggers</structfield>)
+ </para>
+ <para>
+ True if table has (or once had) triggers
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>rowsecurity</structfield> <type>bool</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relrowsecurity</structfield>)
+ </para>
+ <para>
+ True if row security is enabled on the table
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-timezone-abbrevs">
+ <title><structname>pg_timezone_abbrevs</structname></title>
+
+ <indexterm zone="view-pg-timezone-abbrevs">
+ <primary>pg_timezone_abbrevs</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_timezone_abbrevs</structname> provides a list
+ of time zone abbreviations that are currently recognized by the datetime
+ input routines. The contents of this view change when the
+ <xref linkend="guc-timezone-abbreviations"/> run-time parameter is modified.
+ </para>
+
+ <table>
+ <title><structname>pg_timezone_abbrevs</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>abbrev</structfield> <type>text</type>
+ </para>
+ <para>
+ Time zone abbreviation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>utc_offset</structfield> <type>interval</type>
+ </para>
+ <para>
+ Offset from UTC (positive means east of Greenwich)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_dst</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if this is a daylight-savings abbreviation
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ While most timezone abbreviations represent fixed offsets from UTC,
+ there are some that have historically varied in value
+ (see <xref linkend="datetime-config-files"/> for more information).
+ In such cases this view presents their current meaning.
+ </para>
+
+ </sect1>
+
+ <sect1 id="view-pg-timezone-names">
+ <title><structname>pg_timezone_names</structname></title>
+
+ <indexterm zone="view-pg-timezone-names">
+ <primary>pg_timezone_names</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_timezone_names</structname> provides a list
+ of time zone names that are recognized by <command>SET TIMEZONE</command>,
+ along with their associated abbreviations, UTC offsets,
+ and daylight-savings status. (Technically,
+ <productname>PostgreSQL</productname> does not use UTC because leap
+ seconds are not handled.)
+ Unlike the abbreviations shown in <link
+ linkend="view-pg-timezone-abbrevs"><structname>pg_timezone_abbrevs</structname></link>, many of these names imply a set of daylight-savings transition
+ date rules. Therefore, the associated information changes across local DST
+ boundaries. The displayed information is computed based on the current
+ value of <function>CURRENT_TIMESTAMP</function>.
+ </para>
+
+ <table>
+ <title><structname>pg_timezone_names</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>name</structfield> <type>text</type>
+ </para>
+ <para>
+ Time zone name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>abbrev</structfield> <type>text</type>
+ </para>
+ <para>
+ Time zone abbreviation
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>utc_offset</structfield> <type>interval</type>
+ </para>
+ <para>
+ Offset from UTC (positive means east of Greenwich)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>is_dst</structfield> <type>bool</type>
+ </para>
+ <para>
+ True if currently observing daylight savings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-user">
+ <title><structname>pg_user</structname></title>
+
+ <indexterm zone="view-pg-user">
+ <primary>pg_user</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_user</structname> provides access to
+ information about database users. This is simply a publicly
+ readable view of
+ <link linkend="view-pg-shadow"><structname>pg_shadow</structname></link>
+ that blanks out the password field.
+ </para>
+
+ <table>
+ <title><structname>pg_user</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usename</structfield> <type>name</type>
+ </para>
+ <para>
+ User name
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usesysid</structfield> <type>oid</type>
+ </para>
+ <para>
+ ID of this user
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usecreatedb</structfield> <type>bool</type>
+ </para>
+ <para>
+ User can create databases
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usesuper</structfield> <type>bool</type>
+ </para>
+ <para>
+ User is a superuser
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>userepl</structfield> <type>bool</type>
+ </para>
+ <para>
+ User can initiate streaming replication and put the system in and
+ out of backup mode.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usebypassrls</structfield> <type>bool</type>
+ </para>
+ <para>
+ User bypasses every row-level security policy, see
+ <xref linkend="ddl-rowsecurity"/> for more information.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>passwd</structfield> <type>text</type>
+ </para>
+ <para>
+ Not the password (always reads as <literal>********</literal>)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>valuntil</structfield> <type>timestamptz</type>
+ </para>
+ <para>
+ Password expiry time (only used for password authentication)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>useconfig</structfield> <type>text[]</type>
+ </para>
+ <para>
+ Session defaults for run-time configuration variables
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1 id="view-pg-user-mappings">
+ <title><structname>pg_user_mappings</structname></title>
+
+ <indexterm zone="view-pg-user-mappings">
+ <primary>pg_user_mappings</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_user_mappings</structname> provides access
+ to information about user mappings. This is essentially a publicly
+ readable view of
+ <link linkend="catalog-pg-user-mapping"><structname>pg_user_mapping</structname></link>
+ that leaves out the options field if the user has no rights to use
+ it.
+ </para>
+
+ <table>
+ <title><structname>pg_user_mappings</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>umid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-user-mapping"><structname>pg_user_mapping</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the user mapping
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvid</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-foreign-server"><structname>pg_foreign_server</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ The OID of the foreign server that contains this mapping
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>srvname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-foreign-server"><structname>pg_foreign_server</structname></link>.<structfield>srvname</structfield>)
+ </para>
+ <para>
+ Name of the foreign server
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>umuser</structfield> <type>oid</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
+ </para>
+ <para>
+ OID of the local role being mapped, or zero if the user mapping is public
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>usename</structfield> <type>name</type>
+ </para>
+ <para>
+ Name of the local user to be mapped
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>umoptions</structfield> <type>text[]</type>
+ </para>
+ <para>
+ User mapping specific options, as <quote>keyword=value</quote> strings
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ To protect password information stored as a user mapping option,
+ the <structfield>umoptions</structfield> column will read as null
+ unless one of the following applies:
+ <itemizedlist>
+ <listitem>
+ <para>
+ current user is the user being mapped, and owns the server or
+ holds <literal>USAGE</literal> privilege on it
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ current user is the server owner and mapping is for <literal>PUBLIC</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ current user is a superuser
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect1>
+
+
+ <sect1 id="view-pg-views">
+ <title><structname>pg_views</structname></title>
+
+ <indexterm zone="view-pg-views">
+ <primary>pg_views</primary>
+ </indexterm>
+
+ <para>
+ The view <structname>pg_views</structname> provides access to
+ useful information about each view in the database.
+ </para>
+
+ <table>
+ <title><structname>pg_views</structname> Columns</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ Column Type
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>schemaname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>nspname</structfield>)
+ </para>
+ <para>
+ Name of schema containing view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>viewname</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-class"><structname>pg_class</structname></link>.<structfield>relname</structfield>)
+ </para>
+ <para>
+ Name of view
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>viewowner</structfield> <type>name</type>
+ (references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>rolname</structfield>)
+ </para>
+ <para>
+ Name of view's owner
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="catalog_table_entry"><para role="column_definition">
+ <structfield>definition</structfield> <type>text</type>
+ </para>
+ <para>
+ View definition (a reconstructed <xref linkend="sql-select"/> query)
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/tableam.sgml b/doc/src/sgml/tableam.sgml
new file mode 100644
index 0000000..6a6eb2b
--- /dev/null
+++ b/doc/src/sgml/tableam.sgml
@@ -0,0 +1,108 @@
+<!-- doc/src/sgml/tableam.sgml -->
+
+<chapter id="tableam">
+ <title>Table Access Method Interface Definition</title>
+
+ <indexterm>
+ <primary>Table Access Method</primary>
+ </indexterm>
+ <indexterm>
+ <primary>tableam</primary>
+ <secondary>Table Access Method</secondary>
+ </indexterm>
+
+ <para>
+ This chapter explains the interface between the core
+ <productname>PostgreSQL</productname> system and <firstterm>table access
+ methods</firstterm>, which manage the storage for tables. The core system
+ knows little about these access methods beyond what is specified here, so
+ it is possible to develop entirely new access method types by writing
+ add-on code.
+ </para>
+
+ <para>
+ Each table access method is described by a row in the <link
+ linkend="catalog-pg-am"><structname>pg_am</structname></link> system
+ catalog. The <structname>pg_am</structname> entry specifies a name and a
+ <firstterm>handler function</firstterm> for the table access method. These
+ entries can be created and deleted using the <xref
+ linkend="sql-create-access-method"/> and <xref
+ linkend="sql-drop-access-method"/> SQL commands.
+ </para>
+
+ <para>
+ A table access method handler function must be declared to accept a single
+ argument of type <type>internal</type> and to return the pseudo-type
+ <type>table_am_handler</type>. The argument is a dummy value that simply
+ serves to prevent handler functions from being called directly from SQL commands.
+
+ The result of the function must be a pointer to a struct of type
+ <structname>TableAmRoutine</structname>, which contains everything that the
+ core code needs to know to make use of the table access method. The return
+ value needs to be of server lifetime, which is typically achieved by
+ defining it as a <literal>static const</literal> variable in global
+ scope. The <structname>TableAmRoutine</structname> struct, also called the
+ access method's <firstterm>API struct</firstterm>, defines the behavior of
+ the access method using callbacks. These callbacks are pointers to plain C
+ functions and are not visible or callable at the SQL level. All the
+ callbacks and their behavior is defined in the
+ <structname>TableAmRoutine</structname> structure (with comments inside the
+ struct defining the requirements for callbacks). Most callbacks have
+ wrapper functions, which are documented from the point of view of a user
+ (rather than an implementor) of the table access method. For details,
+ please refer to the <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/access/tableam.h;hb=HEAD">
+ <filename>src/include/access/tableam.h</filename></ulink> file.
+ </para>
+
+ <para>
+ To implement an access method, an implementor will typically need to
+ implement an AM-specific type of tuple table slot (see
+ <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/executor/tuptable.h;hb=HEAD">
+ <filename>src/include/executor/tuptable.h</filename></ulink>), which allows
+ code outside the access method to hold references to tuples of the AM, and
+ to access the columns of the tuple.
+ </para>
+
+ <para>
+ Currently, the way an AM actually stores data is fairly unconstrained. For
+ example, it's possible, but not required, to use postgres' shared buffer
+ cache. In case it is used, it likely makes sense to use
+ <productname>PostgreSQL</productname>'s standard page layout as described in
+ <xref linkend="storage-page-layout"/>.
+ </para>
+
+ <para>
+ One fairly large constraint of the table access method API is that,
+ currently, if the AM wants to support modifications and/or indexes, it is
+ necessary for each tuple to have a tuple identifier (<acronym>TID</acronym>)
+ consisting of a block number and an item number (see also <xref
+ linkend="storage-page-layout"/>). It is not strictly necessary that the
+ sub-parts of <acronym>TIDs</acronym> have the same meaning they e.g., have
+ for <literal>heap</literal>, but if bitmap scan support is desired (it is
+ optional), the block number needs to provide locality.
+ </para>
+
+ <para>
+ For crash safety, an AM can use postgres' <link
+ linkend="wal"><acronym>WAL</acronym></link>, or a custom implementation.
+ If <acronym>WAL</acronym> is chosen, either <link
+ linkend="generic-wal">Generic WAL Records</link> can be used,
+ or a <link linkend="custom-rmgr">Custom WAL Resource Manager</link> can be
+ implemented.
+ </para>
+
+ <para>
+ To implement transactional support in a manner that allows different table
+ access methods be accessed within a single transaction, it likely is
+ necessary to closely integrate with the machinery in
+ <filename>src/backend/access/transam/xlog.c</filename>.
+ </para>
+
+ <para>
+ Any developer of a new <literal>table access method</literal> can refer to
+ the existing <literal>heap</literal> implementation present in
+ <filename>src/backend/access/heap/heapam_handler.c</filename> for details of
+ its implementation.
+ </para>
+
+</chapter>
diff --git a/doc/src/sgml/tablefunc.sgml b/doc/src/sgml/tablefunc.sgml
new file mode 100644
index 0000000..808162b
--- /dev/null
+++ b/doc/src/sgml/tablefunc.sgml
@@ -0,0 +1,865 @@
+<!-- doc/src/sgml/tablefunc.sgml -->
+
+<sect1 id="tablefunc" xreflabel="tablefunc">
+ <title>tablefunc</title>
+
+ <indexterm zone="tablefunc">
+ <primary>tablefunc</primary>
+ </indexterm>
+
+ <para>
+ The <filename>tablefunc</filename> module includes various functions that return
+ tables (that is, multiple rows). These functions are useful both in their
+ own right and as examples of how to write C functions that return
+ multiple rows.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Functions Provided</title>
+
+ <para>
+ <xref linkend="tablefunc-functions"/> summarizes the functions provided
+ by the <filename>tablefunc</filename> module.
+ </para>
+
+ <table id="tablefunc-functions">
+ <title><filename>tablefunc</filename> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>normal_rand</function> ( <parameter>numvals</parameter> <type>integer</type>, <parameter>mean</parameter> <type>float8</type>, <parameter>stddev</parameter> <type>float8</type> )
+ <returnvalue>setof float8</returnvalue>
+ </para>
+ <para>
+ Produces a set of normally distributed random values.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>crosstab</function> ( <parameter>sql</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Produces a <quote>pivot table</quote> containing
+ row names plus <replaceable>N</replaceable> value columns, where
+ <replaceable>N</replaceable> is determined by the row type specified
+ in the calling query.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>crosstab<replaceable>N</replaceable></function> ( <parameter>sql</parameter> <type>text</type> )
+ <returnvalue>setof table_crosstab_<replaceable>N</replaceable></returnvalue>
+ </para>
+ <para>
+ Produces a <quote>pivot table</quote> containing
+ row names plus <replaceable>N</replaceable> value columns.
+ <function>crosstab2</function>, <function>crosstab3</function>, and
+ <function>crosstab4</function> are predefined, but you can create additional
+ <function>crosstab<replaceable>N</replaceable></function> functions as described below.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>crosstab</function> ( <parameter>source_sql</parameter> <type>text</type>, <parameter>category_sql</parameter> <type>text</type> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Produces a <quote>pivot table</quote>
+ with the value columns specified by a second query.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>crosstab</function> ( <parameter>sql</parameter> <type>text</type>, <parameter>N</parameter> <type>integer</type> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Obsolete version of <function>crosstab(text)</function>.
+ The parameter <parameter>N</parameter> is now ignored, since the
+ number of value columns is always determined by the calling query.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>connectby</primary></indexterm>
+ <function>connectby</function> ( <parameter>relname</parameter> <type>text</type>, <parameter>keyid_fld</parameter> <type>text</type>, <parameter>parent_keyid_fld</parameter> <type>text</type>
+ <optional>, <parameter>orderby_fld</parameter> <type>text</type> </optional>, <parameter>start_with</parameter> <type>text</type>, <parameter>max_depth</parameter> <type>integer</type>
+ <optional>, <parameter>branch_delim</parameter> <type>text</type> </optional> )
+ <returnvalue>setof record</returnvalue>
+ </para>
+ <para>
+ Produces a representation of a hierarchical tree structure.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect3>
+ <title><function>normal_rand</function></title>
+
+ <indexterm>
+ <primary>normal_rand</primary>
+ </indexterm>
+
+<synopsis>
+normal_rand(int numvals, float8 mean, float8 stddev) returns setof float8
+</synopsis>
+
+ <para>
+ <function>normal_rand</function> produces a set of normally distributed random
+ values (Gaussian distribution).
+ </para>
+
+ <para>
+ <parameter>numvals</parameter> is the number of values to be returned
+ from the function. <parameter>mean</parameter> is the mean of the normal
+ distribution of values and <parameter>stddev</parameter> is the standard
+ deviation of the normal distribution of values.
+ </para>
+
+ <para>
+ For example, this call requests 1000 values with a mean of 5 and a
+ standard deviation of 3:
+ </para>
+
+<screen>
+test=# SELECT * FROM normal_rand(1000, 5, 3);
+ normal_rand
+----------------------
+ 1.56556322244898
+ 9.10040991424657
+ 5.36957140345079
+ -0.369151492880995
+ 0.283600703686639
+ .
+ .
+ .
+ 4.82992125404908
+ 9.71308014517282
+ 2.49639286969028
+(1000 rows)
+</screen>
+ </sect3>
+
+ <sect3>
+ <title><function>crosstab(text)</function></title>
+
+ <indexterm>
+ <primary>crosstab</primary>
+ </indexterm>
+
+<synopsis>
+crosstab(text sql)
+crosstab(text sql, int N)
+</synopsis>
+
+ <para>
+ The <function>crosstab</function> function is used to produce <quote>pivot</quote>
+ displays, wherein data is listed across the page rather than down.
+ For example, we might have data like
+<programlisting>
+row1 val11
+row1 val12
+row1 val13
+...
+row2 val21
+row2 val22
+row2 val23
+...
+</programlisting>
+ which we wish to display like
+<programlisting>
+row1 val11 val12 val13 ...
+row2 val21 val22 val23 ...
+...
+</programlisting>
+ The <function>crosstab</function> function takes a text parameter that is an SQL
+ query producing raw data formatted in the first way, and produces a table
+ formatted in the second way.
+ </para>
+
+ <para>
+ The <parameter>sql</parameter> parameter is an SQL statement that produces
+ the source set of data. This statement must return one
+ <structfield>row_name</structfield> column, one
+ <structfield>category</structfield> column, and one
+ <structfield>value</structfield> column. <parameter>N</parameter> is an
+ obsolete parameter, ignored if supplied (formerly this had to match the
+ number of output value columns, but now that is determined by the
+ calling query).
+ </para>
+
+ <para>
+ For example, the provided query might produce a set something like:
+<programlisting>
+ row_name cat value
+----------+-------+-------
+ row1 cat1 val1
+ row1 cat2 val2
+ row1 cat3 val3
+ row1 cat4 val4
+ row2 cat1 val5
+ row2 cat2 val6
+ row2 cat3 val7
+ row2 cat4 val8
+</programlisting>
+ </para>
+
+ <para>
+ The <function>crosstab</function> function is declared to return <type>setof
+ record</type>, so the actual names and types of the output columns must be
+ defined in the <literal>FROM</literal> clause of the calling <command>SELECT</command>
+ statement, for example:
+<programlisting>
+SELECT * FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text);
+</programlisting>
+ This example produces a set something like:
+<programlisting>
+ &lt;== value columns ==&gt;
+ row_name category_1 category_2
+----------+------------+------------
+ row1 val1 val2
+ row2 val5 val6
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>FROM</literal> clause must define the output as one
+ <structfield>row_name</structfield> column (of the same data type as the first result
+ column of the SQL query) followed by N <structfield>value</structfield> columns
+ (all of the same data type as the third result column of the SQL query).
+ You can set up as many output value columns as you wish. The names of the
+ output columns are up to you.
+ </para>
+
+ <para>
+ The <function>crosstab</function> function produces one output row for each
+ consecutive group of input rows with the same
+ <structfield>row_name</structfield> value. It fills the output
+ <structfield>value</structfield> columns, left to right, with the
+ <structfield>value</structfield> fields from these rows. If there
+ are fewer rows in a group than there are output <structfield>value</structfield>
+ columns, the extra output columns are filled with nulls; if there are
+ more rows, the extra input rows are skipped.
+ </para>
+
+ <para>
+ In practice the SQL query should always specify <literal>ORDER BY 1,2</literal>
+ to ensure that the input rows are properly ordered, that is, values with
+ the same <structfield>row_name</structfield> are brought together and
+ correctly ordered within the row. Notice that <function>crosstab</function>
+ itself does not pay any attention to the second column of the query
+ result; it's just there to be ordered by, to control the order in which
+ the third-column values appear across the page.
+ </para>
+
+ <para>
+ Here is a complete example:
+<programlisting>
+CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3');
+INSERT INTO ct(rowid, attribute, value) VALUES('test1','att4','val4');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att1','val5');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att2','val6');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att3','val7');
+INSERT INTO ct(rowid, attribute, value) VALUES('test2','att4','val8');
+
+SELECT *
+FROM crosstab(
+ 'select rowid, attribute, value
+ from ct
+ where attribute = ''att2'' or attribute = ''att3''
+ order by 1,2')
+AS ct(row_name text, category_1 text, category_2 text, category_3 text);
+
+ row_name | category_1 | category_2 | category_3
+----------+------------+------------+------------
+ test1 | val2 | val3 |
+ test2 | val6 | val7 |
+(2 rows)
+</programlisting>
+ </para>
+
+ <para>
+ You can avoid always having to write out a <literal>FROM</literal> clause to
+ define the output columns, by setting up a custom crosstab function that
+ has the desired output row type wired into its definition. This is
+ described in the next section. Another possibility is to embed the
+ required <literal>FROM</literal> clause in a view definition.
+ </para>
+
+ <note>
+ <para>
+ See also the <command><link linkend="app-psql-meta-commands-crosstabview">\crosstabview</link></command>
+ command in <application>psql</application>, which provides functionality similar
+ to <function>crosstab()</function>.
+ </para>
+ </note>
+
+ </sect3>
+
+ <sect3>
+ <title><function>crosstab<replaceable>N</replaceable>(text)</function></title>
+
+ <indexterm>
+ <primary>crosstab</primary>
+ </indexterm>
+
+<synopsis>
+crosstab<replaceable>N</replaceable>(text sql)
+</synopsis>
+
+ <para>
+ The <function>crosstab<replaceable>N</replaceable></function> functions are examples of how
+ to set up custom wrappers for the general <function>crosstab</function> function,
+ so that you need not write out column names and types in the calling
+ <command>SELECT</command> query. The <filename>tablefunc</filename> module includes
+ <function>crosstab2</function>, <function>crosstab3</function>, and
+ <function>crosstab4</function>, whose output row types are defined as
+ </para>
+
+<programlisting>
+CREATE TYPE tablefunc_crosstab_N AS (
+ row_name TEXT,
+ category_1 TEXT,
+ category_2 TEXT,
+ .
+ .
+ .
+ category_N TEXT
+);
+</programlisting>
+
+ <para>
+ Thus, these functions can be used directly when the input query produces
+ <structfield>row_name</structfield> and <structfield>value</structfield> columns of type
+ <type>text</type>, and you want 2, 3, or 4 output values columns.
+ In all other ways they behave exactly as described above for the
+ general <function>crosstab</function> function.
+ </para>
+
+ <para>
+ For instance, the example given in the previous section would also
+ work as
+<programlisting>
+SELECT *
+FROM crosstab3(
+ 'select rowid, attribute, value
+ from ct
+ where attribute = ''att2'' or attribute = ''att3''
+ order by 1,2');
+</programlisting>
+ </para>
+
+ <para>
+ These functions are provided mostly for illustration purposes. You
+ can create your own return types and functions based on the
+ underlying <function>crosstab()</function> function. There are two ways
+ to do it:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Create a composite type describing the desired output columns,
+ similar to the examples in
+ <filename>contrib/tablefunc/tablefunc--1.0.sql</filename>.
+ Then define a
+ unique function name accepting one <type>text</type> parameter and returning
+ <type>setof your_type_name</type>, but linking to the same underlying
+ <function>crosstab</function> C function. For example, if your source data
+ produces row names that are <type>text</type>, and values that are
+ <type>float8</type>, and you want 5 value columns:
+<programlisting>
+CREATE TYPE my_crosstab_float8_5_cols AS (
+ my_row_name text,
+ my_category_1 float8,
+ my_category_2 float8,
+ my_category_3 float8,
+ my_category_4 float8,
+ my_category_5 float8
+);
+
+CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(text)
+ RETURNS setof my_crosstab_float8_5_cols
+ AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
+</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Use <literal>OUT</literal> parameters to define the return type implicitly.
+ The same example could also be done this way:
+<programlisting>
+CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(
+ IN text,
+ OUT my_row_name text,
+ OUT my_category_1 float8,
+ OUT my_category_2 float8,
+ OUT my_category_3 float8,
+ OUT my_category_4 float8,
+ OUT my_category_5 float8)
+ RETURNS setof record
+ AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
+</programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ </sect3>
+
+ <sect3>
+ <title><function>crosstab(text, text)</function></title>
+
+ <indexterm>
+ <primary>crosstab</primary>
+ </indexterm>
+
+<synopsis>
+crosstab(text source_sql, text category_sql)
+</synopsis>
+
+ <para>
+ The main limitation of the single-parameter form of <function>crosstab</function>
+ is that it treats all values in a group alike, inserting each value into
+ the first available column. If you want the value
+ columns to correspond to specific categories of data, and some groups
+ might not have data for some of the categories, that doesn't work well.
+ The two-parameter form of <function>crosstab</function> handles this case by
+ providing an explicit list of the categories corresponding to the
+ output columns.
+ </para>
+
+ <para>
+ <parameter>source_sql</parameter> is an SQL statement that produces the
+ source set of data. This statement must return one
+ <structfield>row_name</structfield> column, one
+ <structfield>category</structfield> column, and one
+ <structfield>value</structfield> column. It may also have one or more
+ <quote>extra</quote> columns.
+ The <structfield>row_name</structfield> column must be first. The
+ <structfield>category</structfield> and <structfield>value</structfield>
+ columns must be the last two columns, in that order. Any columns between
+ <structfield>row_name</structfield> and
+ <structfield>category</structfield> are treated as <quote>extra</quote>.
+ The <quote>extra</quote> columns are expected to be the same for all rows
+ with the same <structfield>row_name</structfield> value.
+ </para>
+
+ <para>
+ For example, <parameter>source_sql</parameter> might produce a set
+ something like:
+<programlisting>
+SELECT row_name, extra_col, cat, value FROM foo ORDER BY 1;
+
+ row_name extra_col cat value
+----------+------------+-----+---------
+ row1 extra1 cat1 val1
+ row1 extra1 cat2 val2
+ row1 extra1 cat4 val4
+ row2 extra2 cat1 val5
+ row2 extra2 cat2 val6
+ row2 extra2 cat3 val7
+ row2 extra2 cat4 val8
+</programlisting>
+ </para>
+
+ <para>
+ <parameter>category_sql</parameter> is an SQL statement that produces
+ the set of categories. This statement must return only one column.
+ It must produce at least one row, or an error will be generated.
+ Also, it must not produce duplicate values, or an error will be
+ generated. <parameter>category_sql</parameter> might be something like:
+
+<programlisting>
+SELECT DISTINCT cat FROM foo ORDER BY 1;
+ cat
+ -------
+ cat1
+ cat2
+ cat3
+ cat4
+</programlisting>
+ </para>
+
+ <para>
+ The <function>crosstab</function> function is declared to return <type>setof
+ record</type>, so the actual names and types of the output columns must be
+ defined in the <literal>FROM</literal> clause of the calling <command>SELECT</command>
+ statement, for example:
+
+<programlisting>
+SELECT * FROM crosstab('...', '...')
+ AS ct(row_name text, extra text, cat1 text, cat2 text, cat3 text, cat4 text);
+</programlisting>
+ </para>
+
+ <para>
+ This will produce a result something like:
+<programlisting>
+ &lt;== value columns ==&gt;
+row_name extra cat1 cat2 cat3 cat4
+---------+-------+------+------+------+------
+ row1 extra1 val1 val2 val4
+ row2 extra2 val5 val6 val7 val8
+</programlisting>
+ </para>
+
+ <para>
+ The <literal>FROM</literal> clause must define the proper number of output
+ columns of the proper data types. If there are <replaceable>N</replaceable>
+ columns in the <parameter>source_sql</parameter> query's result, the first
+ <replaceable>N</replaceable>-2 of them must match up with the first
+ <replaceable>N</replaceable>-2 output columns. The remaining output columns
+ must have the type of the last column of the <parameter>source_sql</parameter>
+ query's result, and there must be exactly as many of them as there
+ are rows in the <parameter>category_sql</parameter> query's result.
+ </para>
+
+ <para>
+ The <function>crosstab</function> function produces one output row for each
+ consecutive group of input rows with the same
+ <structfield>row_name</structfield> value. The output
+ <structfield>row_name</structfield> column, plus any <quote>extra</quote>
+ columns, are copied from the first row of the group. The output
+ <structfield>value</structfield> columns are filled with the
+ <structfield>value</structfield> fields from rows having matching
+ <structfield>category</structfield> values. If a row's <structfield>category</structfield>
+ does not match any output of the <parameter>category_sql</parameter>
+ query, its <structfield>value</structfield> is ignored. Output
+ columns whose matching category is not present in any input row
+ of the group are filled with nulls.
+ </para>
+
+ <para>
+ In practice the <parameter>source_sql</parameter> query should always
+ specify <literal>ORDER BY 1</literal> to ensure that values with the same
+ <structfield>row_name</structfield> are brought together. However,
+ ordering of the categories within a group is not important.
+ Also, it is essential to be sure that the order of the
+ <parameter>category_sql</parameter> query's output matches the specified
+ output column order.
+ </para>
+
+ <para>
+ Here are two complete examples:
+<programlisting>
+create table sales(year int, month int, qty int);
+insert into sales values(2007, 1, 1000);
+insert into sales values(2007, 2, 1500);
+insert into sales values(2007, 7, 500);
+insert into sales values(2007, 11, 1500);
+insert into sales values(2007, 12, 2000);
+insert into sales values(2008, 1, 1000);
+
+select * from crosstab(
+ 'select year, month, qty from sales order by 1',
+ 'select m from generate_series(1,12) m'
+) as (
+ year int,
+ "Jan" int,
+ "Feb" int,
+ "Mar" int,
+ "Apr" int,
+ "May" int,
+ "Jun" int,
+ "Jul" int,
+ "Aug" int,
+ "Sep" int,
+ "Oct" int,
+ "Nov" int,
+ "Dec" int
+);
+ year | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
+------+------+------+-----+-----+-----+-----+-----+-----+-----+-----+------+------
+ 2007 | 1000 | 1500 | | | | | 500 | | | | 1500 | 2000
+ 2008 | 1000 | | | | | | | | | | |
+(2 rows)
+</programlisting>
+
+<programlisting>
+CREATE TABLE cth(rowid text, rowdt timestamp, attribute text, val text);
+INSERT INTO cth VALUES('test1','01 March 2003','temperature','42');
+INSERT INTO cth VALUES('test1','01 March 2003','test_result','PASS');
+INSERT INTO cth VALUES('test1','01 March 2003','volts','2.6987');
+INSERT INTO cth VALUES('test2','02 March 2003','temperature','53');
+INSERT INTO cth VALUES('test2','02 March 2003','test_result','FAIL');
+INSERT INTO cth VALUES('test2','02 March 2003','test_startdate','01 March 2003');
+INSERT INTO cth VALUES('test2','02 March 2003','volts','3.1234');
+
+SELECT * FROM crosstab
+(
+ 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
+ 'SELECT DISTINCT attribute FROM cth ORDER BY 1'
+)
+AS
+(
+ rowid text,
+ rowdt timestamp,
+ temperature int4,
+ test_result text,
+ test_startdate timestamp,
+ volts float8
+);
+ rowid | rowdt | temperature | test_result | test_startdate | volts
+-------+--------------------------+-------------+-------------+--------------------------+--------
+ test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
+ test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
+(2 rows)
+</programlisting>
+ </para>
+
+ <para>
+ You can create predefined functions to avoid having to write out
+ the result column names and types in each query. See the examples
+ in the previous section. The underlying C function for this form
+ of <function>crosstab</function> is named <literal>crosstab_hash</literal>.
+ </para>
+
+ </sect3>
+
+ <sect3>
+ <title><function>connectby</function></title>
+
+ <indexterm>
+ <primary>connectby</primary>
+ </indexterm>
+
+<synopsis>
+connectby(text relname, text keyid_fld, text parent_keyid_fld
+ [, text orderby_fld ], text start_with, int max_depth
+ [, text branch_delim ])
+</synopsis>
+
+ <para>
+ The <function>connectby</function> function produces a display of hierarchical
+ data that is stored in a table. The table must have a key field that
+ uniquely identifies rows, and a parent-key field that references the
+ parent (if any) of each row. <function>connectby</function> can display the
+ sub-tree descending from any row.
+ </para>
+
+ <para>
+ <xref linkend="tablefunc-connectby-parameters"/> explains the
+ parameters.
+ </para>
+
+ <table id="tablefunc-connectby-parameters">
+ <title><function>connectby</function> Parameters</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Parameter</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><parameter>relname</parameter></entry>
+ <entry>Name of the source relation</entry>
+ </row>
+ <row>
+ <entry><parameter>keyid_fld</parameter></entry>
+ <entry>Name of the key field</entry>
+ </row>
+ <row>
+ <entry><parameter>parent_keyid_fld</parameter></entry>
+ <entry>Name of the parent-key field</entry>
+ </row>
+ <row>
+ <entry><parameter>orderby_fld</parameter></entry>
+ <entry>Name of the field to order siblings by (optional)</entry>
+ </row>
+ <row>
+ <entry><parameter>start_with</parameter></entry>
+ <entry>Key value of the row to start at</entry>
+ </row>
+ <row>
+ <entry><parameter>max_depth</parameter></entry>
+ <entry>Maximum depth to descend to, or zero for unlimited depth</entry>
+ </row>
+ <row>
+ <entry><parameter>branch_delim</parameter></entry>
+ <entry>String to separate keys with in branch output (optional)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The key and parent-key fields can be any data type, but they must be
+ the same type. Note that the <parameter>start_with</parameter> value must be
+ entered as a text string, regardless of the type of the key field.
+ </para>
+
+ <para>
+ The <function>connectby</function> function is declared to return <type>setof
+ record</type>, so the actual names and types of the output columns must be
+ defined in the <literal>FROM</literal> clause of the calling <command>SELECT</command>
+ statement, for example:
+ </para>
+
+<programlisting>
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text, pos int);
+</programlisting>
+
+ <para>
+ The first two output columns are used for the current row's key and
+ its parent row's key; they must match the type of the table's key field.
+ The third output column is the depth in the tree and must be of type
+ <type>integer</type>. If a <parameter>branch_delim</parameter> parameter was
+ given, the next output column is the branch display and must be of type
+ <type>text</type>. Finally, if an <parameter>orderby_fld</parameter>
+ parameter was given, the last output column is a serial number, and must
+ be of type <type>integer</type>.
+ </para>
+
+ <para>
+ The <quote>branch</quote> output column shows the path of keys taken to
+ reach the current row. The keys are separated by the specified
+ <parameter>branch_delim</parameter> string. If no branch display is
+ wanted, omit both the <parameter>branch_delim</parameter> parameter
+ and the branch column in the output column list.
+ </para>
+
+ <para>
+ If the ordering of siblings of the same parent is important,
+ include the <parameter>orderby_fld</parameter> parameter to
+ specify which field to order siblings by. This field can be of any
+ sortable data type. The output column list must include a final
+ integer serial-number column, if and only if
+ <parameter>orderby_fld</parameter> is specified.
+ </para>
+
+ <para>
+ The parameters representing table and field names are copied as-is
+ into the SQL queries that <function>connectby</function> generates internally.
+ Therefore, include double quotes if the names are mixed-case or contain
+ special characters. You may also need to schema-qualify the table name.
+ </para>
+
+ <para>
+ In large tables, performance will be poor unless there is an index on
+ the parent-key field.
+ </para>
+
+ <para>
+ It is important that the <parameter>branch_delim</parameter> string
+ not appear in any key values, else <function>connectby</function> may incorrectly
+ report an infinite-recursion error. Note that if
+ <parameter>branch_delim</parameter> is not provided, a default value
+ of <literal>~</literal> is used for recursion detection purposes.
+ <!-- That pretty well sucks. FIXME -->
+ </para>
+
+ <para>
+ Here is an example:
+<programlisting>
+CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int);
+
+INSERT INTO connectby_tree VALUES('row1',NULL, 0);
+INSERT INTO connectby_tree VALUES('row2','row1', 0);
+INSERT INTO connectby_tree VALUES('row3','row1', 0);
+INSERT INTO connectby_tree VALUES('row4','row2', 1);
+INSERT INTO connectby_tree VALUES('row5','row2', 0);
+INSERT INTO connectby_tree VALUES('row6','row4', 0);
+INSERT INTO connectby_tree VALUES('row7','row3', 0);
+INSERT INTO connectby_tree VALUES('row8','row6', 0);
+INSERT INTO connectby_tree VALUES('row9','row5', 0);
+
+-- with branch, without orderby_fld (order of results is not guaranteed)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text);
+ keyid | parent_keyid | level | branch
+-------+--------------+-------+---------------------
+ row2 | | 0 | row2
+ row4 | row2 | 1 | row2~row4
+ row6 | row4 | 2 | row2~row4~row6
+ row8 | row6 | 3 | row2~row4~row6~row8
+ row5 | row2 | 1 | row2~row5
+ row9 | row5 | 2 | row2~row5~row9
+(6 rows)
+
+-- without branch, without orderby_fld (order of results is not guaranteed)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0)
+ AS t(keyid text, parent_keyid text, level int);
+ keyid | parent_keyid | level
+-------+--------------+-------
+ row2 | | 0
+ row4 | row2 | 1
+ row6 | row4 | 2
+ row8 | row6 | 3
+ row5 | row2 | 1
+ row9 | row5 | 2
+(6 rows)
+
+-- with branch, with orderby_fld (notice that row5 comes before row4)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
+ AS t(keyid text, parent_keyid text, level int, branch text, pos int);
+ keyid | parent_keyid | level | branch | pos
+-------+--------------+-------+---------------------+-----
+ row2 | | 0 | row2 | 1
+ row5 | row2 | 1 | row2~row5 | 2
+ row9 | row5 | 2 | row2~row5~row9 | 3
+ row4 | row2 | 1 | row2~row4 | 4
+ row6 | row4 | 2 | row2~row4~row6 | 5
+ row8 | row6 | 3 | row2~row4~row6~row8 | 6
+(6 rows)
+
+-- without branch, with orderby_fld (notice that row5 comes before row4)
+SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0)
+ AS t(keyid text, parent_keyid text, level int, pos int);
+ keyid | parent_keyid | level | pos
+-------+--------------+-------+-----
+ row2 | | 0 | 1
+ row5 | row2 | 1 | 2
+ row9 | row5 | 2 | 3
+ row4 | row2 | 1 | 4
+ row6 | row4 | 2 | 5
+ row8 | row6 | 3 | 6
+(6 rows)
+</programlisting>
+ </para>
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Joe Conway
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/tablesample-method.sgml b/doc/src/sgml/tablesample-method.sgml
new file mode 100644
index 0000000..c821941
--- /dev/null
+++ b/doc/src/sgml/tablesample-method.sgml
@@ -0,0 +1,300 @@
+<!-- doc/src/sgml/tablesample-method.sgml -->
+
+<chapter id="tablesample-method">
+ <title>Writing a Table Sampling Method</title>
+
+ <indexterm zone="tablesample-method">
+ <primary>table sampling method</primary>
+ </indexterm>
+
+ <indexterm zone="tablesample-method">
+ <primary><literal>TABLESAMPLE</literal> method</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname>'s implementation of the <literal>TABLESAMPLE</literal>
+ clause supports custom table sampling methods, in addition to
+ the <literal>BERNOULLI</literal> and <literal>SYSTEM</literal> methods that are required
+ by the SQL standard. The sampling method determines which rows of the
+ table will be selected when the <literal>TABLESAMPLE</literal> clause is used.
+ </para>
+
+ <para>
+ At the SQL level, a table sampling method is represented by a single SQL
+ function, typically implemented in C, having the signature
+<programlisting>
+method_name(internal) RETURNS tsm_handler
+</programlisting>
+ The name of the function is the same method name appearing in the
+ <literal>TABLESAMPLE</literal> clause. The <type>internal</type> argument is a dummy
+ (always having value zero) that simply serves to prevent this function from
+ being called directly from an SQL command.
+ The result of the function must be a palloc'd struct of
+ type <type>TsmRoutine</type>, which contains pointers to support functions for
+ the sampling method. These support functions are plain C functions and
+ are not visible or callable at the SQL level. The support functions are
+ described in <xref linkend="tablesample-support-functions"/>.
+ </para>
+
+ <para>
+ In addition to function pointers, the <type>TsmRoutine</type> struct must
+ provide these additional fields:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>List *parameterTypes</literal></term>
+ <listitem>
+ <para>
+ This is an OID list containing the data type OIDs of the parameter(s)
+ that will be accepted by the <literal>TABLESAMPLE</literal> clause when this
+ sampling method is used. For example, for the built-in methods, this
+ list contains a single item with value <literal>FLOAT4OID</literal>, which
+ represents the sampling percentage. Custom sampling methods can have
+ more or different parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool repeatable_across_queries</literal></term>
+ <listitem>
+ <para>
+ If <literal>true</literal>, the sampling method can deliver identical samples
+ across successive queries, if the same parameters
+ and <literal>REPEATABLE</literal> seed value are supplied each time and the
+ table contents have not changed. When this is <literal>false</literal>,
+ the <literal>REPEATABLE</literal> clause is not accepted for use with the
+ sampling method.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>bool repeatable_across_scans</literal></term>
+ <listitem>
+ <para>
+ If <literal>true</literal>, the sampling method can deliver identical samples
+ across successive scans in the same query (assuming unchanging
+ parameters, seed value, and snapshot).
+ When this is <literal>false</literal>, the planner will not select plans that
+ would require scanning the sampled table more than once, since that
+ might result in inconsistent query output.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The <type>TsmRoutine</type> struct type is declared
+ in <filename>src/include/access/tsmapi.h</filename>, which see for additional
+ details.
+ </para>
+
+ <para>
+ The table sampling methods included in the standard distribution are good
+ references when trying to write your own. Look into
+ the <filename>src/backend/access/tablesample</filename> subdirectory of the source
+ tree for the built-in sampling methods, and into the <filename>contrib</filename>
+ subdirectory for add-on methods.
+ </para>
+
+ <sect1 id="tablesample-support-functions">
+ <title>Sampling Method Support Functions</title>
+
+ <para>
+ The TSM handler function returns a palloc'd <type>TsmRoutine</type> struct
+ containing pointers to the support functions described below. Most of
+ the functions are required, but some are optional, and those pointers can
+ be NULL.
+ </para>
+
+ <para>
+<programlisting>
+void
+SampleScanGetSampleSize (PlannerInfo *root,
+ RelOptInfo *baserel,
+ List *paramexprs,
+ BlockNumber *pages,
+ double *tuples);
+</programlisting>
+
+ This function is called during planning. It must estimate the number of
+ relation pages that will be read during a sample scan, and the number of
+ tuples that will be selected by the scan. (For example, these might be
+ determined by estimating the sampling fraction, and then multiplying
+ the <literal>baserel-&gt;pages</literal> and <literal>baserel-&gt;tuples</literal>
+ numbers by that, being sure to round the results to integral values.)
+ The <literal>paramexprs</literal> list holds the expression(s) that are
+ parameters to the <literal>TABLESAMPLE</literal> clause. It is recommended to
+ use <function>estimate_expression_value()</function> to try to reduce these
+ expressions to constants, if their values are needed for estimation
+ purposes; but the function must provide size estimates even if they cannot
+ be reduced, and it should not fail even if the values appear invalid
+ (remember that they're only estimates of what the run-time values will be).
+ The <literal>pages</literal> and <literal>tuples</literal> parameters are outputs.
+ </para>
+
+ <para>
+<programlisting>
+void
+InitSampleScan (SampleScanState *node,
+ int eflags);
+</programlisting>
+
+ Initialize for execution of a SampleScan plan node.
+ This is called during executor startup.
+ It should perform any initialization needed before processing can start.
+ The <structname>SampleScanState</structname> node has already been created, but
+ its <structfield>tsm_state</structfield> field is NULL.
+ The <function>InitSampleScan</function> function can palloc whatever internal
+ state data is needed by the sampling method, and store a pointer to
+ it in <literal>node-&gt;tsm_state</literal>.
+ Information about the table to scan is accessible through other fields
+ of the <structname>SampleScanState</structname> node (but note that the
+ <literal>node-&gt;ss.ss_currentScanDesc</literal> scan descriptor is not set
+ up yet).
+ <literal>eflags</literal> contains flag bits describing the executor's
+ operating mode for this plan node.
+ </para>
+
+ <para>
+ When <literal>(eflags &amp; EXEC_FLAG_EXPLAIN_ONLY)</literal> is true,
+ the scan will not actually be performed, so this function should only do
+ the minimum required to make the node state valid for <command>EXPLAIN</command>
+ and <function>EndSampleScan</function>.
+ </para>
+
+ <para>
+ This function can be omitted (set the pointer to NULL), in which case
+ <function>BeginSampleScan</function> must perform all initialization needed
+ by the sampling method.
+ </para>
+
+ <para>
+<programlisting>
+void
+BeginSampleScan (SampleScanState *node,
+ Datum *params,
+ int nparams,
+ uint32 seed);
+</programlisting>
+
+ Begin execution of a sampling scan.
+ This is called just before the first attempt to fetch a tuple, and
+ may be called again if the scan needs to be restarted.
+ Information about the table to scan is accessible through fields
+ of the <structname>SampleScanState</structname> node (but note that the
+ <literal>node-&gt;ss.ss_currentScanDesc</literal> scan descriptor is not set
+ up yet).
+ The <literal>params</literal> array, of length <literal>nparams</literal>, contains the
+ values of the parameters supplied in the <literal>TABLESAMPLE</literal> clause.
+ These will have the number and types specified in the sampling
+ method's <literal>parameterTypes</literal> list, and have been checked
+ to not be null.
+ <literal>seed</literal> contains a seed to use for any random numbers generated
+ within the sampling method; it is either a hash derived from the
+ <literal>REPEATABLE</literal> value if one was given, or the result
+ of <literal>random()</literal> if not.
+ </para>
+
+ <para>
+ This function may adjust the fields <literal>node-&gt;use_bulkread</literal>
+ and <literal>node-&gt;use_pagemode</literal>.
+ If <literal>node-&gt;use_bulkread</literal> is <literal>true</literal>, which it is by
+ default, the scan will use a buffer access strategy that encourages
+ recycling buffers after use. It might be reasonable to set this
+ to <literal>false</literal> if the scan will visit only a small fraction of the
+ table's pages.
+ If <literal>node-&gt;use_pagemode</literal> is <literal>true</literal>, which it is by
+ default, the scan will perform visibility checking in a single pass for
+ all tuples on each visited page. It might be reasonable to set this
+ to <literal>false</literal> if the scan will select only a small fraction of the
+ tuples on each visited page. That will result in fewer tuple visibility
+ checks being performed, though each one will be more expensive because it
+ will require more locking.
+ </para>
+
+ <para>
+ If the sampling method is
+ marked <literal>repeatable_across_scans</literal>, it must be able to
+ select the same set of tuples during a rescan as it did originally, that is
+ a fresh call of <function>BeginSampleScan</function> must lead to selecting the
+ same tuples as before (if the <literal>TABLESAMPLE</literal> parameters
+ and seed don't change).
+ </para>
+
+ <para>
+<programlisting>
+BlockNumber
+NextSampleBlock (SampleScanState *node, BlockNumber nblocks);
+</programlisting>
+
+ Returns the block number of the next page to be scanned, or
+ <literal>InvalidBlockNumber</literal> if no pages remain to be scanned.
+ </para>
+
+ <para>
+ This function can be omitted (set the pointer to NULL), in which case
+ the core code will perform a sequential scan of the entire relation.
+ Such a scan can use synchronized scanning, so that the sampling method
+ cannot assume that the relation pages are visited in the same order on
+ each scan.
+ </para>
+
+ <para>
+<programlisting>
+OffsetNumber
+NextSampleTuple (SampleScanState *node,
+ BlockNumber blockno,
+ OffsetNumber maxoffset);
+</programlisting>
+
+ Returns the offset number of the next tuple to be sampled on the
+ specified page, or <literal>InvalidOffsetNumber</literal> if no tuples remain to
+ be sampled. <literal>maxoffset</literal> is the largest offset number in use
+ on the page.
+ </para>
+
+ <note>
+ <para>
+ <function>NextSampleTuple</function> is not explicitly told which of the offset
+ numbers in the range <literal>1 .. maxoffset</literal> actually contain valid
+ tuples. This is not normally a problem since the core code ignores
+ requests to sample missing or invisible tuples; that should not result in
+ any bias in the sample. However, if necessary, the function can use
+ <literal>node-&gt;donetuples</literal> to examine how many of the tuples
+ it returned were valid and visible.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ <function>NextSampleTuple</function> must <emphasis>not</emphasis> assume
+ that <literal>blockno</literal> is the same page number returned by the most
+ recent <function>NextSampleBlock</function> call. It was returned by some
+ previous <function>NextSampleBlock</function> call, but the core code is allowed
+ to call <function>NextSampleBlock</function> in advance of actually scanning
+ pages, so as to support prefetching. It is OK to assume that once
+ sampling of a given page begins, successive <function>NextSampleTuple</function>
+ calls all refer to the same page until <literal>InvalidOffsetNumber</literal> is
+ returned.
+ </para>
+ </note>
+
+ <para>
+<programlisting>
+void
+EndSampleScan (SampleScanState *node);
+</programlisting>
+
+ End the scan and release resources. It is normally not important
+ to release palloc'd memory, but any externally-visible resources
+ should be cleaned up.
+ This function can be omitted (set the pointer to NULL) in the common
+ case where no such resources exist.
+ </para>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/tcn.sgml b/doc/src/sgml/tcn.sgml
new file mode 100644
index 0000000..82afe9a
--- /dev/null
+++ b/doc/src/sgml/tcn.sgml
@@ -0,0 +1,77 @@
+<!-- doc/src/sgml/tcn.sgml -->
+
+<sect1 id="tcn" xreflabel="tcn">
+ <title>tcn</title>
+
+ <indexterm zone="tcn">
+ <primary>tcn</primary>
+ </indexterm>
+
+ <indexterm zone="tcn">
+ <primary>triggered_change_notification</primary>
+ </indexterm>
+
+ <para>
+ The <filename>tcn</filename> module provides a trigger function that notifies
+ listeners of changes to any table on which it is attached. It must be
+ used as an <literal>AFTER</literal> trigger <literal>FOR EACH ROW</literal>.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <para>
+ Only one parameter may be supplied to the function in a
+ <literal>CREATE TRIGGER</literal> statement, and that is optional. If supplied
+ it will be used for the channel name for the notifications. If omitted
+ <literal>tcn</literal> will be used for the channel name.
+ </para>
+
+ <para>
+ The payload of the notifications consists of the table name, a letter to
+ indicate which type of operation was performed, and column name/value pairs
+ for primary key columns. Each part is separated from the next by a comma.
+ For ease of parsing using regular expressions, table and column names are
+ always wrapped in double quotes, and data values are always wrapped in
+ single quotes. Embedded quotes are doubled.
+ </para>
+
+ <para>
+ A brief example of using the extension follows.
+
+<programlisting>
+test=# create table tcndata
+test-# (
+test(# a int not null,
+test(# b date not null,
+test(# c text,
+test(# primary key (a, b)
+test(# );
+CREATE TABLE
+test=# create trigger tcndata_tcn_trigger
+test-# after insert or update or delete on tcndata
+test-# for each row execute function triggered_change_notification();
+CREATE TRIGGER
+test=# listen tcn;
+LISTEN
+test=# insert into tcndata values (1, date '2012-12-22', 'one'),
+test-# (1, date '2012-12-23', 'another'),
+test-# (2, date '2012-12-23', 'two');
+INSERT 0 3
+Asynchronous notification "tcn" with payload ""tcndata",I,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.
+Asynchronous notification "tcn" with payload ""tcndata",I,"a"='1',"b"='2012-12-23'" received from server process with PID 22770.
+Asynchronous notification "tcn" with payload ""tcndata",I,"a"='2',"b"='2012-12-23'" received from server process with PID 22770.
+test=# update tcndata set c = 'uno' where a = 1;
+UPDATE 2
+Asynchronous notification "tcn" with payload ""tcndata",U,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.
+Asynchronous notification "tcn" with payload ""tcndata",U,"a"='1',"b"='2012-12-23'" received from server process with PID 22770.
+test=# delete from tcndata where a = 1 and b = date '2012-12-22';
+DELETE 1
+Asynchronous notification "tcn" with payload ""tcndata",D,"a"='1',"b"='2012-12-22'" received from server process with PID 22770.
+</programlisting>
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/test-decoding.sgml b/doc/src/sgml/test-decoding.sgml
new file mode 100644
index 0000000..9b07195
--- /dev/null
+++ b/doc/src/sgml/test-decoding.sgml
@@ -0,0 +1,64 @@
+<!-- doc/src/sgml/test-decoding.sgml -->
+
+<sect1 id="test-decoding" xreflabel="test_decoding">
+ <title>test_decoding</title>
+
+ <indexterm zone="test-decoding">
+ <primary>test_decoding</primary>
+ </indexterm>
+
+ <para>
+ <filename>test_decoding</filename> is an example of a logical decoding
+ output plugin. It doesn't do anything especially useful, but can serve as
+ a starting point for developing your own output plugin.
+ </para>
+
+ <para>
+ <filename>test_decoding</filename> receives WAL through the logical decoding
+ mechanism and decodes it into text representations of the operations
+ performed.
+ </para>
+
+ <para>
+ Typical output from this plugin, used over the SQL logical decoding
+ interface, might be:
+
+<programlisting>
+postgres=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'include-xids', '0');
+ lsn | xid | data
+-----------+-----+--------------------------------------------------
+ 0/16D30F8 | 691 | BEGIN
+ 0/16D32A0 | 691 | table public.data: INSERT: id[int4]:2 data[text]:'arg'
+ 0/16D32A0 | 691 | table public.data: INSERT: id[int4]:3 data[text]:'demo'
+ 0/16D32A0 | 691 | COMMIT
+ 0/16D32D8 | 692 | BEGIN
+ 0/16D3398 | 692 | table public.data: DELETE: id[int4]:2
+ 0/16D3398 | 692 | table public.data: DELETE: id[int4]:3
+ 0/16D3398 | 692 | COMMIT
+(8 rows)
+</programlisting>
+ </para>
+
+<para>
+ We can also get the changes of the in-progress transaction, and the typical
+ output might be:
+
+<programlisting>
+postgres[33712]=#* SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'stream-changes', '1');
+ lsn | xid | data
+-----------+-----+--------------------------------------------------
+ 0/16B21F8 | 503 | opening a streamed block for transaction TXN 503
+ 0/16B21F8 | 503 | streaming change for TXN 503
+ 0/16B2300 | 503 | streaming change for TXN 503
+ 0/16B2408 | 503 | streaming change for TXN 503
+ 0/16BEBA0 | 503 | closing a streamed block for transaction TXN 503
+ 0/16B21F8 | 503 | opening a streamed block for transaction TXN 503
+ 0/16BECA8 | 503 | streaming change for TXN 503
+ 0/16BEDB0 | 503 | streaming change for TXN 503
+ 0/16BEEB8 | 503 | streaming change for TXN 503
+ 0/16BEBA0 | 503 | closing a streamed block for transaction TXN 503
+(10 rows)
+</programlisting>
+ </para>
+
+</sect1>
diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml
new file mode 100644
index 0000000..1550be5
--- /dev/null
+++ b/doc/src/sgml/textsearch.sgml
@@ -0,0 +1,4009 @@
+<!-- doc/src/sgml/textsearch.sgml -->
+
+<chapter id="textsearch">
+ <title>Full Text Search</title>
+
+ <indexterm zone="textsearch">
+ <primary>full text search</primary>
+ </indexterm>
+
+ <indexterm zone="textsearch">
+ <primary>text search</primary>
+ </indexterm>
+
+ <sect1 id="textsearch-intro">
+ <title>Introduction</title>
+
+ <para>
+ Full Text Searching (or just <firstterm>text search</firstterm>) provides
+ the capability to identify natural-language <firstterm>documents</firstterm> that
+ satisfy a <firstterm>query</firstterm>, and optionally to sort them by
+ relevance to the query. The most common type of search
+ is to find all documents containing given <firstterm>query terms</firstterm>
+ and return them in order of their <firstterm>similarity</firstterm> to the
+ query. Notions of <varname>query</varname> and
+ <varname>similarity</varname> are very flexible and depend on the specific
+ application. The simplest search considers <varname>query</varname> as a
+ set of words and <varname>similarity</varname> as the frequency of query
+ words in the document.
+ </para>
+
+ <para>
+ Textual search operators have existed in databases for years.
+ <productname>PostgreSQL</productname> has
+ <literal>~</literal>, <literal>~*</literal>, <literal>LIKE</literal>, and
+ <literal>ILIKE</literal> operators for textual data types, but they lack
+ many essential properties required by modern information systems:
+ </para>
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ There is no linguistic support, even for English. Regular expressions
+ are not sufficient because they cannot easily handle derived words, e.g.,
+ <literal>satisfies</literal> and <literal>satisfy</literal>. You might
+ miss documents that contain <literal>satisfies</literal>, although you
+ probably would like to find them when searching for
+ <literal>satisfy</literal>. It is possible to use <literal>OR</literal>
+ to search for multiple derived forms, but this is tedious and error-prone
+ (some words can have several thousand derivatives).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ They provide no ordering (ranking) of search results, which makes them
+ ineffective when thousands of matching documents are found.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ They tend to be slow because there is no index support, so they must
+ process all documents for every search.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Full text indexing allows documents to be <emphasis>preprocessed</emphasis>
+ and an index saved for later rapid searching. Preprocessing includes:
+ </para>
+
+ <itemizedlist mark="none">
+ <listitem>
+ <para>
+ <emphasis>Parsing documents into <firstterm>tokens</firstterm></emphasis>. It is
+ useful to identify various classes of tokens, e.g., numbers, words,
+ complex words, email addresses, so that they can be processed
+ differently. In principle token classes depend on the specific
+ application, but for most purposes it is adequate to use a predefined
+ set of classes.
+ <productname>PostgreSQL</productname> uses a <firstterm>parser</firstterm> to
+ perform this step. A standard parser is provided, and custom parsers
+ can be created for specific needs.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>Converting tokens into <firstterm>lexemes</firstterm></emphasis>.
+ A lexeme is a string, just like a token, but it has been
+ <firstterm>normalized</firstterm> so that different forms of the same word
+ are made alike. For example, normalization almost always includes
+ folding upper-case letters to lower-case, and often involves removal
+ of suffixes (such as <literal>s</literal> or <literal>es</literal> in English).
+ This allows searches to find variant forms of the
+ same word, without tediously entering all the possible variants.
+ Also, this step typically eliminates <firstterm>stop words</firstterm>, which
+ are words that are so common that they are useless for searching.
+ (In short, then, tokens are raw fragments of the document text, while
+ lexemes are words that are believed useful for indexing and searching.)
+ <productname>PostgreSQL</productname> uses <firstterm>dictionaries</firstterm> to
+ perform this step. Various standard dictionaries are provided, and
+ custom ones can be created for specific needs.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>Storing preprocessed documents optimized for
+ searching</emphasis>. For example, each document can be represented
+ as a sorted array of normalized lexemes. Along with the lexemes it is
+ often desirable to store positional information to use for
+ <firstterm>proximity ranking</firstterm>, so that a document that
+ contains a more <quote>dense</quote> region of query words is
+ assigned a higher rank than one with scattered query words.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Dictionaries allow fine-grained control over how tokens are normalized.
+ With appropriate dictionaries, you can:
+ </para>
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ Define stop words that should not be indexed.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Map synonyms to a single word using <application>Ispell</application>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Map phrases to a single word using a thesaurus.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Map different variations of a word to a canonical form using
+ an <application>Ispell</application> dictionary.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Map different variations of a word to a canonical form using
+ <application>Snowball</application> stemmer rules.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ A data type <type>tsvector</type> is provided for storing preprocessed
+ documents, along with a type <type>tsquery</type> for representing processed
+ queries (<xref linkend="datatype-textsearch"/>). There are many
+ functions and operators available for these data types
+ (<xref linkend="functions-textsearch"/>), the most important of which is
+ the match operator <literal>@@</literal>, which we introduce in
+ <xref linkend="textsearch-matching"/>. Full text searches can be accelerated
+ using indexes (<xref linkend="textsearch-indexes"/>).
+ </para>
+
+
+ <sect2 id="textsearch-document">
+ <title>What Is a Document?</title>
+
+ <indexterm zone="textsearch-document">
+ <primary>document</primary>
+ <secondary>text search</secondary>
+ </indexterm>
+
+ <para>
+ A <firstterm>document</firstterm> is the unit of searching in a full text search
+ system; for example, a magazine article or email message. The text search
+ engine must be able to parse documents and store associations of lexemes
+ (key words) with their parent document. Later, these associations are
+ used to search for documents that contain query words.
+ </para>
+
+ <para>
+ For searches within <productname>PostgreSQL</productname>,
+ a document is normally a textual field within a row of a database table,
+ or possibly a combination (concatenation) of such fields, perhaps stored
+ in several tables or obtained dynamically. In other words, a document can
+ be constructed from different parts for indexing and it might not be
+ stored anywhere as a whole. For example:
+
+<programlisting>
+SELECT title || ' ' || author || ' ' || abstract || ' ' || body AS document
+FROM messages
+WHERE mid = 12;
+
+SELECT m.title || ' ' || m.author || ' ' || m.abstract || ' ' || d.body AS document
+FROM messages m, docs d
+WHERE m.mid = d.did AND m.mid = 12;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ Actually, in these example queries, <function>coalesce</function>
+ should be used to prevent a single <literal>NULL</literal> attribute from
+ causing a <literal>NULL</literal> result for the whole document.
+ </para>
+ </note>
+
+ <para>
+ Another possibility is to store the documents as simple text files in the
+ file system. In this case, the database can be used to store the full text
+ index and to execute searches, and some unique identifier can be used to
+ retrieve the document from the file system. However, retrieving files
+ from outside the database requires superuser permissions or special
+ function support, so this is usually less convenient than keeping all
+ the data inside <productname>PostgreSQL</productname>. Also, keeping
+ everything inside the database allows easy access
+ to document metadata to assist in indexing and display.
+ </para>
+
+ <para>
+ For text search purposes, each document must be reduced to the
+ preprocessed <type>tsvector</type> format. Searching and ranking
+ are performed entirely on the <type>tsvector</type> representation
+ of a document &mdash; the original text need only be retrieved
+ when the document has been selected for display to a user.
+ We therefore often speak of the <type>tsvector</type> as being the
+ document, but of course it is only a compact representation of
+ the full document.
+ </para>
+ </sect2>
+
+ <sect2 id="textsearch-matching">
+ <title>Basic Text Matching</title>
+
+ <para>
+ Full text searching in <productname>PostgreSQL</productname> is based on
+ the match operator <literal>@@</literal>, which returns
+ <literal>true</literal> if a <type>tsvector</type>
+ (document) matches a <type>tsquery</type> (query).
+ It doesn't matter which data type is written first:
+
+<programlisting>
+SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat &amp; rat'::tsquery;
+ ?column?
+----------
+ t
+
+SELECT 'fat &amp; cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat rat'::tsvector;
+ ?column?
+----------
+ f
+</programlisting>
+ </para>
+
+ <para>
+ As the above example suggests, a <type>tsquery</type> is not just raw
+ text, any more than a <type>tsvector</type> is. A <type>tsquery</type>
+ contains search terms, which must be already-normalized lexemes, and
+ may combine multiple terms using AND, OR, NOT, and FOLLOWED BY operators.
+ (For syntax details see <xref linkend="datatype-tsquery"/>.) There are
+ functions <function>to_tsquery</function>, <function>plainto_tsquery</function>,
+ and <function>phraseto_tsquery</function>
+ that are helpful in converting user-written text into a proper
+ <type>tsquery</type>, primarily by normalizing words appearing in
+ the text. Similarly, <function>to_tsvector</function> is used to parse and
+ normalize a document string. So in practice a text search match would
+ look more like this:
+
+<programlisting>
+SELECT to_tsvector('fat cats ate fat rats') @@ to_tsquery('fat &amp; rat');
+ ?column?
+----------
+ t
+</programlisting>
+
+ Observe that this match would not succeed if written as
+
+<programlisting>
+SELECT 'fat cats ate fat rats'::tsvector @@ to_tsquery('fat &amp; rat');
+ ?column?
+----------
+ f
+</programlisting>
+
+ since here no normalization of the word <literal>rats</literal> will occur.
+ The elements of a <type>tsvector</type> are lexemes, which are assumed
+ already normalized, so <literal>rats</literal> does not match <literal>rat</literal>.
+ </para>
+
+ <para>
+ The <literal>@@</literal> operator also
+ supports <type>text</type> input, allowing explicit conversion of a text
+ string to <type>tsvector</type> or <type>tsquery</type> to be skipped
+ in simple cases. The variants available are:
+
+<programlisting>
+tsvector @@ tsquery
+tsquery @@ tsvector
+text @@ tsquery
+text @@ text
+</programlisting>
+ </para>
+
+ <para>
+ The first two of these we saw already.
+ The form <type>text</type> <literal>@@</literal> <type>tsquery</type>
+ is equivalent to <literal>to_tsvector(x) @@ y</literal>.
+ The form <type>text</type> <literal>@@</literal> <type>text</type>
+ is equivalent to <literal>to_tsvector(x) @@ plainto_tsquery(y)</literal>.
+ </para>
+
+ <para>
+ Within a <type>tsquery</type>, the <literal>&amp;</literal> (AND) operator
+ specifies that both its arguments must appear in the document to have a
+ match. Similarly, the <literal>|</literal> (OR) operator specifies that
+ at least one of its arguments must appear, while the <literal>!</literal> (NOT)
+ operator specifies that its argument must <emphasis>not</emphasis> appear in
+ order to have a match.
+ For example, the query <literal>fat &amp; ! rat</literal> matches documents that
+ contain <literal>fat</literal> but not <literal>rat</literal>.
+ </para>
+
+ <para>
+ Searching for phrases is possible with the help of
+ the <literal>&lt;-&gt;</literal> (FOLLOWED BY) <type>tsquery</type> operator, which
+ matches only if its arguments have matches that are adjacent and in the
+ given order. For example:
+
+<programlisting>
+SELECT to_tsvector('fatal error') @@ to_tsquery('fatal &lt;-&gt; error');
+ ?column?
+----------
+ t
+
+SELECT to_tsvector('error is not fatal') @@ to_tsquery('fatal &lt;-&gt; error');
+ ?column?
+----------
+ f
+</programlisting>
+
+ There is a more general version of the FOLLOWED BY operator having the
+ form <literal>&lt;<replaceable>N</replaceable>&gt;</literal>,
+ where <replaceable>N</replaceable> is an integer standing for the difference between
+ the positions of the matching lexemes. <literal>&lt;1&gt;</literal> is
+ the same as <literal>&lt;-&gt;</literal>, while <literal>&lt;2&gt;</literal>
+ allows exactly one other lexeme to appear between the matches, and so
+ on. The <literal>phraseto_tsquery</literal> function makes use of this
+ operator to construct a <literal>tsquery</literal> that can match a multi-word
+ phrase when some of the words are stop words. For example:
+
+<programlisting>
+SELECT phraseto_tsquery('cats ate rats');
+ phraseto_tsquery
+-------------------------------
+ 'cat' &lt;-&gt; 'ate' &lt;-&gt; 'rat'
+
+SELECT phraseto_tsquery('the cats ate the rats');
+ phraseto_tsquery
+-------------------------------
+ 'cat' &lt;-&gt; 'ate' &lt;2&gt; 'rat'
+</programlisting>
+ </para>
+
+ <para>
+ A special case that's sometimes useful is that <literal>&lt;0&gt;</literal>
+ can be used to require that two patterns match the same word.
+ </para>
+
+ <para>
+ Parentheses can be used to control nesting of the <type>tsquery</type>
+ operators. Without parentheses, <literal>|</literal> binds least tightly,
+ then <literal>&amp;</literal>, then <literal>&lt;-&gt;</literal>,
+ and <literal>!</literal> most tightly.
+ </para>
+
+ <para>
+ It's worth noticing that the AND/OR/NOT operators mean something subtly
+ different when they are within the arguments of a FOLLOWED BY operator
+ than when they are not, because within FOLLOWED BY the exact position of
+ the match is significant. For example, normally <literal>!x</literal> matches
+ only documents that do not contain <literal>x</literal> anywhere.
+ But <literal>!x &lt;-&gt; y</literal> matches <literal>y</literal> if it is not
+ immediately after an <literal>x</literal>; an occurrence of <literal>x</literal>
+ elsewhere in the document does not prevent a match. Another example is
+ that <literal>x &amp; y</literal> normally only requires that <literal>x</literal>
+ and <literal>y</literal> both appear somewhere in the document, but
+ <literal>(x &amp; y) &lt;-&gt; z</literal> requires <literal>x</literal>
+ and <literal>y</literal> to match at the same place, immediately before
+ a <literal>z</literal>. Thus this query behaves differently from
+ <literal>x &lt;-&gt; z &amp; y &lt;-&gt; z</literal>, which will match a
+ document containing two separate sequences <literal>x z</literal> and
+ <literal>y z</literal>. (This specific query is useless as written,
+ since <literal>x</literal> and <literal>y</literal> could not match at the same place;
+ but with more complex situations such as prefix-match patterns, a query
+ of this form could be useful.)
+ </para>
+ </sect2>
+
+ <sect2 id="textsearch-intro-configurations">
+ <title>Configurations</title>
+
+ <para>
+ The above are all simple text search examples. As mentioned before, full
+ text search functionality includes the ability to do many more things:
+ skip indexing certain words (stop words), process synonyms, and use
+ sophisticated parsing, e.g., parse based on more than just white space.
+ This functionality is controlled by <firstterm>text search
+ configurations</firstterm>. <productname>PostgreSQL</productname> comes with predefined
+ configurations for many languages, and you can easily create your own
+ configurations. (<application>psql</application>'s <command>\dF</command> command
+ shows all available configurations.)
+ </para>
+
+ <para>
+ During installation an appropriate configuration is selected and
+ <xref linkend="guc-default-text-search-config"/> is set accordingly
+ in <filename>postgresql.conf</filename>. If you are using the same text search
+ configuration for the entire cluster you can use the value in
+ <filename>postgresql.conf</filename>. To use different configurations
+ throughout the cluster but the same configuration within any one database,
+ use <command>ALTER DATABASE ... SET</command>. Otherwise, you can set
+ <varname>default_text_search_config</varname> in each session.
+ </para>
+
+ <para>
+ Each text search function that depends on a configuration has an optional
+ <type>regconfig</type> argument, so that the configuration to use can be
+ specified explicitly. <varname>default_text_search_config</varname>
+ is used only when this argument is omitted.
+ </para>
+
+ <para>
+ To make it easier to build custom text search configurations, a
+ configuration is built up from simpler database objects.
+ <productname>PostgreSQL</productname>'s text search facility provides
+ four types of configuration-related database objects:
+ </para>
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <firstterm>Text search parsers</firstterm> break documents into tokens
+ and classify each token (for example, as words or numbers).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <firstterm>Text search dictionaries</firstterm> convert tokens to normalized
+ form and reject stop words.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <firstterm>Text search templates</firstterm> provide the functions underlying
+ dictionaries. (A dictionary simply specifies a template and a set
+ of parameters for the template.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <firstterm>Text search configurations</firstterm> select a parser and a set
+ of dictionaries to use to normalize the tokens produced by the parser.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Text search parsers and templates are built from low-level C functions;
+ therefore it requires C programming ability to develop new ones, and
+ superuser privileges to install one into a database. (There are examples
+ of add-on parsers and templates in the <filename>contrib/</filename> area of the
+ <productname>PostgreSQL</productname> distribution.) Since dictionaries and
+ configurations just parameterize and connect together some underlying
+ parsers and templates, no special privilege is needed to create a new
+ dictionary or configuration. Examples of creating custom dictionaries and
+ configurations appear later in this chapter.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="textsearch-tables">
+ <title>Tables and Indexes</title>
+
+ <para>
+ The examples in the previous section illustrated full text matching using
+ simple constant strings. This section shows how to search table data,
+ optionally using indexes.
+ </para>
+
+ <sect2 id="textsearch-tables-search">
+ <title>Searching a Table</title>
+
+ <para>
+ It is possible to do a full text search without an index. A simple query
+ to print the <structname>title</structname> of each row that contains the word
+ <literal>friend</literal> in its <structfield>body</structfield> field is:
+
+<programlisting>
+SELECT title
+FROM pgweb
+WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend');
+</programlisting>
+
+ This will also find related words such as <literal>friends</literal>
+ and <literal>friendly</literal>, since all these are reduced to the same
+ normalized lexeme.
+ </para>
+
+ <para>
+ The query above specifies that the <literal>english</literal> configuration
+ is to be used to parse and normalize the strings. Alternatively we
+ could omit the configuration parameters:
+
+<programlisting>
+SELECT title
+FROM pgweb
+WHERE to_tsvector(body) @@ to_tsquery('friend');
+</programlisting>
+
+ This query will use the configuration set by <xref
+ linkend="guc-default-text-search-config"/>.
+ </para>
+
+ <para>
+ A more complex example is to
+ select the ten most recent documents that contain <literal>create</literal> and
+ <literal>table</literal> in the <structname>title</structname> or <structname>body</structname>:
+
+<programlisting>
+SELECT title
+FROM pgweb
+WHERE to_tsvector(title || ' ' || body) @@ to_tsquery('create &amp; table')
+ORDER BY last_mod_date DESC
+LIMIT 10;
+</programlisting>
+
+ For clarity we omitted the <function>coalesce</function> function calls
+ which would be needed to find rows that contain <literal>NULL</literal>
+ in one of the two fields.
+ </para>
+
+ <para>
+ Although these queries will work without an index, most applications
+ will find this approach too slow, except perhaps for occasional ad-hoc
+ searches. Practical use of text searching usually requires creating
+ an index.
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-tables-index">
+ <title>Creating Indexes</title>
+
+ <para>
+ We can create a <acronym>GIN</acronym> index (<xref
+ linkend="textsearch-indexes"/>) to speed up text searches:
+
+<programlisting>
+CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', body));
+</programlisting>
+
+ Notice that the 2-argument version of <function>to_tsvector</function> is
+ used. Only text search functions that specify a configuration name can
+ be used in expression indexes (<xref linkend="indexes-expressional"/>).
+ This is because the index contents must be unaffected by <xref
+ linkend="guc-default-text-search-config"/>. If they were affected, the
+ index contents might be inconsistent because different entries could
+ contain <type>tsvector</type>s that were created with different text search
+ configurations, and there would be no way to guess which was which. It
+ would be impossible to dump and restore such an index correctly.
+ </para>
+
+ <para>
+ Because the two-argument version of <function>to_tsvector</function> was
+ used in the index above, only a query reference that uses the 2-argument
+ version of <function>to_tsvector</function> with the same configuration
+ name will use that index. That is, <literal>WHERE
+ to_tsvector('english', body) @@ 'a &amp; b'</literal> can use the index,
+ but <literal>WHERE to_tsvector(body) @@ 'a &amp; b'</literal> cannot.
+ This ensures that an index will be used only with the same configuration
+ used to create the index entries.
+ </para>
+
+ <para>
+ It is possible to set up more complex expression indexes wherein the
+ configuration name is specified by another column, e.g.:
+
+<programlisting>
+CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector(config_name, body));
+</programlisting>
+
+ where <literal>config_name</literal> is a column in the <literal>pgweb</literal>
+ table. This allows mixed configurations in the same index while
+ recording which configuration was used for each index entry. This
+ would be useful, for example, if the document collection contained
+ documents in different languages. Again,
+ queries that are meant to use the index must be phrased to match, e.g.,
+ <literal>WHERE to_tsvector(config_name, body) @@ 'a &amp; b'</literal>.
+ </para>
+
+ <para>
+ Indexes can even concatenate columns:
+
+<programlisting>
+CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));
+</programlisting>
+ </para>
+
+ <para>
+ Another approach is to create a separate <type>tsvector</type> column
+ to hold the output of <function>to_tsvector</function>. To keep this
+ column automatically up to date with its source data, use a stored
+ generated column. This example is a
+ concatenation of <literal>title</literal> and <literal>body</literal>,
+ using <function>coalesce</function> to ensure that one field will still be
+ indexed when the other is <literal>NULL</literal>:
+
+<programlisting>
+ALTER TABLE pgweb
+ ADD COLUMN textsearchable_index_col tsvector
+ GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;
+</programlisting>
+
+ Then we create a <acronym>GIN</acronym> index to speed up the search:
+
+<programlisting>
+CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col);
+</programlisting>
+
+ Now we are ready to perform a fast full text search:
+
+<programlisting>
+SELECT title
+FROM pgweb
+WHERE textsearchable_index_col @@ to_tsquery('create &amp; table')
+ORDER BY last_mod_date DESC
+LIMIT 10;
+</programlisting>
+ </para>
+
+ <para>
+ One advantage of the separate-column approach over an expression index
+ is that it is not necessary to explicitly specify the text search
+ configuration in queries in order to make use of the index. As shown
+ in the example above, the query can depend on
+ <varname>default_text_search_config</varname>. Another advantage is that
+ searches will be faster, since it will not be necessary to redo the
+ <function>to_tsvector</function> calls to verify index matches. (This is more
+ important when using a GiST index than a GIN index; see <xref
+ linkend="textsearch-indexes"/>.) The expression-index approach is
+ simpler to set up, however, and it requires less disk space since the
+ <type>tsvector</type> representation is not stored explicitly.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="textsearch-controls">
+ <title>Controlling Text Search</title>
+
+ <para>
+ To implement full text searching there must be a function to create a
+ <type>tsvector</type> from a document and a <type>tsquery</type> from a
+ user query. Also, we need to return results in a useful order, so we need
+ a function that compares documents with respect to their relevance to
+ the query. It's also important to be able to display the results nicely.
+ <productname>PostgreSQL</productname> provides support for all of these
+ functions.
+ </para>
+
+ <sect2 id="textsearch-parsing-documents">
+ <title>Parsing Documents</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides the
+ function <function>to_tsvector</function> for converting a document to
+ the <type>tsvector</type> data type.
+ </para>
+
+ <indexterm>
+ <primary>to_tsvector</primary>
+ </indexterm>
+
+<synopsis>
+to_tsvector(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">document</replaceable> <type>text</type>) returns <type>tsvector</type>
+</synopsis>
+
+ <para>
+ <function>to_tsvector</function> parses a textual document into tokens,
+ reduces the tokens to lexemes, and returns a <type>tsvector</type> which
+ lists the lexemes together with their positions in the document.
+ The document is processed according to the specified or default
+ text search configuration.
+ Here is a simple example:
+
+<screen>
+SELECT to_tsvector('english', 'a fat cat sat on a mat - it ate a fat rats');
+ to_tsvector
+-----------------------------------------------------
+ 'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4
+</screen>
+ </para>
+
+ <para>
+ In the example above we see that the resulting <type>tsvector</type> does not
+ contain the words <literal>a</literal>, <literal>on</literal>, or
+ <literal>it</literal>, the word <literal>rats</literal> became
+ <literal>rat</literal>, and the punctuation sign <literal>-</literal> was
+ ignored.
+ </para>
+
+ <para>
+ The <function>to_tsvector</function> function internally calls a parser
+ which breaks the document text into tokens and assigns a type to
+ each token. For each token, a list of
+ dictionaries (<xref linkend="textsearch-dictionaries"/>) is consulted,
+ where the list can vary depending on the token type. The first dictionary
+ that <firstterm>recognizes</firstterm> the token emits one or more normalized
+ <firstterm>lexemes</firstterm> to represent the token. For example,
+ <literal>rats</literal> became <literal>rat</literal> because one of the
+ dictionaries recognized that the word <literal>rats</literal> is a plural
+ form of <literal>rat</literal>. Some words are recognized as
+ <firstterm>stop words</firstterm> (<xref linkend="textsearch-stopwords"/>), which
+ causes them to be ignored since they occur too frequently to be useful in
+ searching. In our example these are
+ <literal>a</literal>, <literal>on</literal>, and <literal>it</literal>.
+ If no dictionary in the list recognizes the token then it is also ignored.
+ In this example that happened to the punctuation sign <literal>-</literal>
+ because there are in fact no dictionaries assigned for its token type
+ (<literal>Space symbols</literal>), meaning space tokens will never be
+ indexed. The choices of parser, dictionaries and which types of tokens to
+ index are determined by the selected text search configuration (<xref
+ linkend="textsearch-configuration"/>). It is possible to have
+ many different configurations in the same database, and predefined
+ configurations are available for various languages. In our example
+ we used the default configuration <literal>english</literal> for the
+ English language.
+ </para>
+
+ <para>
+ The function <function>setweight</function> can be used to label the
+ entries of a <type>tsvector</type> with a given <firstterm>weight</firstterm>,
+ where a weight is one of the letters <literal>A</literal>, <literal>B</literal>,
+ <literal>C</literal>, or <literal>D</literal>.
+ This is typically used to mark entries coming from
+ different parts of a document, such as title versus body. Later, this
+ information can be used for ranking of search results.
+ </para>
+
+ <para>
+ Because <function>to_tsvector</function>(<literal>NULL</literal>) will
+ return <literal>NULL</literal>, it is recommended to use
+ <function>coalesce</function> whenever a field might be null.
+ Here is the recommended method for creating
+ a <type>tsvector</type> from a structured document:
+
+<programlisting>
+UPDATE tt SET ti =
+ setweight(to_tsvector(coalesce(title,'')), 'A') ||
+ setweight(to_tsvector(coalesce(keyword,'')), 'B') ||
+ setweight(to_tsvector(coalesce(abstract,'')), 'C') ||
+ setweight(to_tsvector(coalesce(body,'')), 'D');
+</programlisting>
+
+ Here we have used <function>setweight</function> to label the source
+ of each lexeme in the finished <type>tsvector</type>, and then merged
+ the labeled <type>tsvector</type> values using the <type>tsvector</type>
+ concatenation operator <literal>||</literal>. (<xref
+ linkend="textsearch-manipulate-tsvector"/> gives details about these
+ operations.)
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-parsing-queries">
+ <title>Parsing Queries</title>
+
+ <para>
+ <productname>PostgreSQL</productname> provides the
+ functions <function>to_tsquery</function>,
+ <function>plainto_tsquery</function>,
+ <function>phraseto_tsquery</function> and
+ <function>websearch_to_tsquery</function>
+ for converting a query to the <type>tsquery</type> data type.
+ <function>to_tsquery</function> offers access to more features
+ than either <function>plainto_tsquery</function> or
+ <function>phraseto_tsquery</function>, but it is less forgiving about its
+ input. <function>websearch_to_tsquery</function> is a simplified version
+ of <function>to_tsquery</function> with an alternative syntax, similar
+ to the one used by web search engines.
+ </para>
+
+ <indexterm>
+ <primary>to_tsquery</primary>
+ </indexterm>
+
+<synopsis>
+to_tsquery(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">querytext</replaceable> <type>text</type>) returns <type>tsquery</type>
+</synopsis>
+
+ <para>
+ <function>to_tsquery</function> creates a <type>tsquery</type> value from
+ <replaceable>querytext</replaceable>, which must consist of single tokens
+ separated by the <type>tsquery</type> operators <literal>&amp;</literal> (AND),
+ <literal>|</literal> (OR), <literal>!</literal> (NOT), and
+ <literal>&lt;-&gt;</literal> (FOLLOWED BY), possibly grouped
+ using parentheses. In other words, the input to
+ <function>to_tsquery</function> must already follow the general rules for
+ <type>tsquery</type> input, as described in <xref
+ linkend="datatype-tsquery"/>. The difference is that while basic
+ <type>tsquery</type> input takes the tokens at face value,
+ <function>to_tsquery</function> normalizes each token into a lexeme using
+ the specified or default configuration, and discards any tokens that are
+ stop words according to the configuration. For example:
+
+<screen>
+SELECT to_tsquery('english', 'The &amp; Fat &amp; Rats');
+ to_tsquery
+---------------
+ 'fat' &amp; 'rat'
+</screen>
+
+ As in basic <type>tsquery</type> input, weight(s) can be attached to each
+ lexeme to restrict it to match only <type>tsvector</type> lexemes of those
+ weight(s). For example:
+
+<screen>
+SELECT to_tsquery('english', 'Fat | Rats:AB');
+ to_tsquery
+------------------
+ 'fat' | 'rat':AB
+</screen>
+
+ Also, <literal>*</literal> can be attached to a lexeme to specify prefix matching:
+
+<screen>
+SELECT to_tsquery('supern:*A &amp; star:A*B');
+ to_tsquery
+--------------------------
+ 'supern':*A &amp; 'star':*AB
+</screen>
+
+ Such a lexeme will match any word in a <type>tsvector</type> that begins
+ with the given string.
+ </para>
+
+ <para>
+ <function>to_tsquery</function> can also accept single-quoted
+ phrases. This is primarily useful when the configuration includes a
+ thesaurus dictionary that may trigger on such phrases.
+ In the example below, a thesaurus contains the rule <literal>supernovae
+ stars : sn</literal>:
+
+<screen>
+SELECT to_tsquery('''supernovae stars'' &amp; !crab');
+ to_tsquery
+---------------
+ 'sn' &amp; !'crab'
+</screen>
+
+ Without quotes, <function>to_tsquery</function> will generate a syntax
+ error for tokens that are not separated by an AND, OR, or FOLLOWED BY
+ operator.
+ </para>
+
+ <indexterm>
+ <primary>plainto_tsquery</primary>
+ </indexterm>
+
+<synopsis>
+plainto_tsquery(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">querytext</replaceable> <type>text</type>) returns <type>tsquery</type>
+</synopsis>
+
+ <para>
+ <function>plainto_tsquery</function> transforms the unformatted text
+ <replaceable>querytext</replaceable> to a <type>tsquery</type> value.
+ The text is parsed and normalized much as for <function>to_tsvector</function>,
+ then the <literal>&amp;</literal> (AND) <type>tsquery</type> operator is
+ inserted between surviving words.
+ </para>
+
+ <para>
+ Example:
+
+<screen>
+SELECT plainto_tsquery('english', 'The Fat Rats');
+ plainto_tsquery
+-----------------
+ 'fat' &amp; 'rat'
+</screen>
+
+ Note that <function>plainto_tsquery</function> will not
+ recognize <type>tsquery</type> operators, weight labels,
+ or prefix-match labels in its input:
+
+<screen>
+SELECT plainto_tsquery('english', 'The Fat &amp; Rats:C');
+ plainto_tsquery
+---------------------
+ 'fat' &amp; 'rat' &amp; 'c'
+</screen>
+
+ Here, all the input punctuation was discarded.
+ </para>
+
+ <indexterm>
+ <primary>phraseto_tsquery</primary>
+ </indexterm>
+
+<synopsis>
+phraseto_tsquery(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">querytext</replaceable> <type>text</type>) returns <type>tsquery</type>
+</synopsis>
+
+ <para>
+ <function>phraseto_tsquery</function> behaves much like
+ <function>plainto_tsquery</function>, except that it inserts
+ the <literal>&lt;-&gt;</literal> (FOLLOWED BY) operator between
+ surviving words instead of the <literal>&amp;</literal> (AND) operator.
+ Also, stop words are not simply discarded, but are accounted for by
+ inserting <literal>&lt;<replaceable>N</replaceable>&gt;</literal> operators rather
+ than <literal>&lt;-&gt;</literal> operators. This function is useful
+ when searching for exact lexeme sequences, since the FOLLOWED BY
+ operators check lexeme order not just the presence of all the lexemes.
+ </para>
+
+ <para>
+ Example:
+
+<screen>
+SELECT phraseto_tsquery('english', 'The Fat Rats');
+ phraseto_tsquery
+------------------
+ 'fat' &lt;-&gt; 'rat'
+</screen>
+
+ Like <function>plainto_tsquery</function>, the
+ <function>phraseto_tsquery</function> function will not
+ recognize <type>tsquery</type> operators, weight labels,
+ or prefix-match labels in its input:
+
+<screen>
+SELECT phraseto_tsquery('english', 'The Fat &amp; Rats:C');
+ phraseto_tsquery
+-----------------------------
+ 'fat' &lt;-&gt; 'rat' &lt;-&gt; 'c'
+</screen>
+ </para>
+
+<synopsis>
+websearch_to_tsquery(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">querytext</replaceable> <type>text</type>) returns <type>tsquery</type>
+</synopsis>
+
+ <para>
+ <function>websearch_to_tsquery</function> creates a <type>tsquery</type>
+ value from <replaceable>querytext</replaceable> using an alternative
+ syntax in which simple unformatted text is a valid query.
+ Unlike <function>plainto_tsquery</function>
+ and <function>phraseto_tsquery</function>, it also recognizes certain
+ operators. Moreover, this function will never raise syntax errors,
+ which makes it possible to use raw user-supplied input for search.
+ The following syntax is supported:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <literal>unquoted text</literal>: text not inside quote marks will be
+ converted to terms separated by <literal>&amp;</literal> operators, as
+ if processed by <function>plainto_tsquery</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>"quoted text"</literal>: text inside quote marks will be
+ converted to terms separated by <literal>&lt;-&gt;</literal>
+ operators, as if processed by <function>phraseto_tsquery</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>OR</literal>: the word <quote>or</quote> will be converted to
+ the <literal>|</literal> operator.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>-</literal>: a dash will be converted to
+ the <literal>!</literal> operator.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Other punctuation is ignored. So
+ like <function>plainto_tsquery</function>
+ and <function>phraseto_tsquery</function>,
+ the <function>websearch_to_tsquery</function> function will not
+ recognize <type>tsquery</type> operators, weight labels, or prefix-match
+ labels in its input.
+ </para>
+
+ <para>
+ Examples:
+<screen>
+SELECT websearch_to_tsquery('english', 'The fat rats');
+ websearch_to_tsquery
+----------------------
+ 'fat' &amp; 'rat'
+(1 row)
+
+SELECT websearch_to_tsquery('english', '"supernovae stars" -crab');
+ websearch_to_tsquery
+----------------------------------
+ 'supernova' &lt;-&gt; 'star' &amp; !'crab'
+(1 row)
+
+SELECT websearch_to_tsquery('english', '"sad cat" or "fat rat"');
+ websearch_to_tsquery
+-----------------------------------
+ 'sad' &lt;-&gt; 'cat' | 'fat' &lt;-&gt; 'rat'
+(1 row)
+
+SELECT websearch_to_tsquery('english', 'signal -"segmentation fault"');
+ websearch_to_tsquery
+---------------------------------------
+ 'signal' &amp; !( 'segment' &lt;-&gt; 'fault' )
+(1 row)
+
+SELECT websearch_to_tsquery('english', '""" )( dummy \\ query &lt;-&gt;');
+ websearch_to_tsquery
+----------------------
+ 'dummi' &amp; 'queri'
+(1 row)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="textsearch-ranking">
+ <title>Ranking Search Results</title>
+
+ <para>
+ Ranking attempts to measure how relevant documents are to a particular
+ query, so that when there are many matches the most relevant ones can be
+ shown first. <productname>PostgreSQL</productname> provides two
+ predefined ranking functions, which take into account lexical, proximity,
+ and structural information; that is, they consider how often the query
+ terms appear in the document, how close together the terms are in the
+ document, and how important is the part of the document where they occur.
+ However, the concept of relevancy is vague and very application-specific.
+ Different applications might require additional information for ranking,
+ e.g., document modification time. The built-in ranking functions are only
+ examples. You can write your own ranking functions and/or combine their
+ results with additional factors to fit your specific needs.
+ </para>
+
+ <para>
+ The two ranking functions currently available are:
+
+ <variablelist>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>ts_rank</primary>
+ </indexterm>
+
+ <literal>ts_rank(<optional> <replaceable class="parameter">weights</replaceable> <type>float4[]</type>, </optional> <replaceable class="parameter">vector</replaceable> <type>tsvector</type>, <replaceable class="parameter">query</replaceable> <type>tsquery</type> <optional>, <replaceable class="parameter">normalization</replaceable> <type>integer</type> </optional>) returns <type>float4</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Ranks vectors based on the frequency of their matching lexemes.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>ts_rank_cd</primary>
+ </indexterm>
+
+ <literal>ts_rank_cd(<optional> <replaceable class="parameter">weights</replaceable> <type>float4[]</type>, </optional> <replaceable class="parameter">vector</replaceable> <type>tsvector</type>, <replaceable class="parameter">query</replaceable> <type>tsquery</type> <optional>, <replaceable class="parameter">normalization</replaceable> <type>integer</type> </optional>) returns <type>float4</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ This function computes the <firstterm>cover density</firstterm>
+ ranking for the given document vector and query, as described in
+ Clarke, Cormack, and Tudhope's "Relevance Ranking for One to Three
+ Term Queries" in the journal "Information Processing and Management",
+ 1999. Cover density is similar to <function>ts_rank</function> ranking
+ except that the proximity of matching lexemes to each other is
+ taken into consideration.
+ </para>
+
+ <para>
+ This function requires lexeme positional information to perform
+ its calculation. Therefore, it ignores any <quote>stripped</quote>
+ lexemes in the <type>tsvector</type>. If there are no unstripped
+ lexemes in the input, the result will be zero. (See <xref
+ linkend="textsearch-manipulate-tsvector"/> for more information
+ about the <function>strip</function> function and positional information
+ in <type>tsvector</type>s.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+
+ <para>
+ For both these functions,
+ the optional <replaceable class="parameter">weights</replaceable>
+ argument offers the ability to weigh word instances more or less
+ heavily depending on how they are labeled. The weight arrays specify
+ how heavily to weigh each category of word, in the order:
+
+<synopsis>
+{D-weight, C-weight, B-weight, A-weight}
+</synopsis>
+
+ If no <replaceable class="parameter">weights</replaceable> are provided,
+ then these defaults are used:
+
+<programlisting>
+{0.1, 0.2, 0.4, 1.0}
+</programlisting>
+
+ Typically weights are used to mark words from special areas of the
+ document, like the title or an initial abstract, so they can be
+ treated with more or less importance than words in the document body.
+ </para>
+
+ <para>
+ Since a longer document has a greater chance of containing a query term
+ it is reasonable to take into account document size, e.g., a hundred-word
+ document with five instances of a search word is probably more relevant
+ than a thousand-word document with five instances. Both ranking functions
+ take an integer <replaceable>normalization</replaceable> option that
+ specifies whether and how a document's length should impact its rank.
+ The integer option controls several behaviors, so it is a bit mask:
+ you can specify one or more behaviors using
+ <literal>|</literal> (for example, <literal>2|4</literal>).
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ 0 (the default) ignores the document length
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 1 divides the rank by 1 + the logarithm of the document length
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 2 divides the rank by the document length
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 4 divides the rank by the mean harmonic distance between extents
+ (this is implemented only by <function>ts_rank_cd</function>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 8 divides the rank by the number of unique words in document
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 16 divides the rank by 1 + the logarithm of the number
+ of unique words in document
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ 32 divides the rank by itself + 1
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ If more than one flag bit is specified, the transformations are
+ applied in the order listed.
+ </para>
+
+ <para>
+ It is important to note that the ranking functions do not use any global
+ information, so it is impossible to produce a fair normalization to 1% or
+ 100% as sometimes desired. Normalization option 32
+ (<literal>rank/(rank+1)</literal>) can be applied to scale all ranks
+ into the range zero to one, but of course this is just a cosmetic change;
+ it will not affect the ordering of the search results.
+ </para>
+
+ <para>
+ Here is an example that selects only the ten highest-ranked matches:
+
+<screen>
+SELECT title, ts_rank_cd(textsearch, query) AS rank
+FROM apod, to_tsquery('neutrino|(dark &amp; matter)') query
+WHERE query @@ textsearch
+ORDER BY rank DESC
+LIMIT 10;
+ title | rank
+-----------------------------------------------+----------
+ Neutrinos in the Sun | 3.1
+ The Sudbury Neutrino Detector | 2.4
+ A MACHO View of Galactic Dark Matter | 2.01317
+ Hot Gas and Dark Matter | 1.91171
+ The Virgo Cluster: Hot Plasma and Dark Matter | 1.90953
+ Rafting for Solar Neutrinos | 1.9
+ NGC 4650A: Strange Galaxy and Dark Matter | 1.85774
+ Hot Gas and Dark Matter | 1.6123
+ Ice Fishing for Cosmic Neutrinos | 1.6
+ Weak Lensing Distorts the Universe | 0.818218
+</screen>
+
+ This is the same example using normalized ranking:
+
+<screen>
+SELECT title, ts_rank_cd(textsearch, query, 32 /* rank/(rank+1) */ ) AS rank
+FROM apod, to_tsquery('neutrino|(dark &amp; matter)') query
+WHERE query @@ textsearch
+ORDER BY rank DESC
+LIMIT 10;
+ title | rank
+-----------------------------------------------+-------------------
+ Neutrinos in the Sun | 0.756097569485493
+ The Sudbury Neutrino Detector | 0.705882361190954
+ A MACHO View of Galactic Dark Matter | 0.668123210574724
+ Hot Gas and Dark Matter | 0.65655958650282
+ The Virgo Cluster: Hot Plasma and Dark Matter | 0.656301290640973
+ Rafting for Solar Neutrinos | 0.655172410958162
+ NGC 4650A: Strange Galaxy and Dark Matter | 0.650072921219637
+ Hot Gas and Dark Matter | 0.617195790024749
+ Ice Fishing for Cosmic Neutrinos | 0.615384618911517
+ Weak Lensing Distorts the Universe | 0.450010798361481
+</screen>
+ </para>
+
+ <para>
+ Ranking can be expensive since it requires consulting the
+ <type>tsvector</type> of each matching document, which can be I/O bound and
+ therefore slow. Unfortunately, it is almost impossible to avoid since
+ practical queries often result in large numbers of matches.
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-headline">
+ <title>Highlighting Results</title>
+
+ <para>
+ To present search results it is ideal to show a part of each document and
+ how it is related to the query. Usually, search engines show fragments of
+ the document with marked search terms. <productname>PostgreSQL</productname>
+ provides a function <function>ts_headline</function> that
+ implements this functionality.
+ </para>
+
+ <indexterm>
+ <primary>ts_headline</primary>
+ </indexterm>
+
+<synopsis>
+ts_headline(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">document</replaceable> <type>text</type>, <replaceable class="parameter">query</replaceable> <type>tsquery</type> <optional>, <replaceable class="parameter">options</replaceable> <type>text</type> </optional>) returns <type>text</type>
+</synopsis>
+
+ <para>
+ <function>ts_headline</function> accepts a document along
+ with a query, and returns an excerpt from
+ the document in which terms from the query are highlighted. The
+ configuration to be used to parse the document can be specified by
+ <replaceable>config</replaceable>; if <replaceable>config</replaceable>
+ is omitted, the
+ <varname>default_text_search_config</varname> configuration is used.
+ </para>
+
+ <para>
+ If an <replaceable>options</replaceable> string is specified it must
+ consist of a comma-separated list of one or more
+ <replaceable>option</replaceable><literal>=</literal><replaceable>value</replaceable> pairs.
+ The available options are:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <literal>MaxWords</literal>, <literal>MinWords</literal> (integers):
+ these numbers determine the longest and shortest headlines to output.
+ The default values are 35 and 15.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>ShortWord</literal> (integer): words of this length or less
+ will be dropped at the start and end of a headline, unless they are
+ query terms. The default value of three eliminates common English
+ articles.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>HighlightAll</literal> (boolean): if
+ <literal>true</literal> the whole document will be used as the
+ headline, ignoring the preceding three parameters. The default
+ is <literal>false</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>MaxFragments</literal> (integer): maximum number of text
+ fragments to display. The default value of zero selects a
+ non-fragment-based headline generation method. A value greater
+ than zero selects fragment-based headline generation (see below).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>StartSel</literal>, <literal>StopSel</literal> (strings):
+ the strings with which to delimit query words appearing in the
+ document, to distinguish them from other excerpted words. The
+ default values are <quote><literal>&lt;b&gt;</literal></quote> and
+ <quote><literal>&lt;/b&gt;</literal></quote>, which can be suitable
+ for HTML output.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>FragmentDelimiter</literal> (string): When more than one
+ fragment is displayed, the fragments will be separated by this string.
+ The default is <quote><literal> ... </literal></quote>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ These option names are recognized case-insensitively.
+ You must double-quote string values if they contain spaces or commas.
+ </para>
+
+ <para>
+ In non-fragment-based headline
+ generation, <function>ts_headline</function> locates matches for the
+ given <replaceable class="parameter">query</replaceable> and chooses a
+ single one to display, preferring matches that have more query words
+ within the allowed headline length.
+ In fragment-based headline generation, <function>ts_headline</function>
+ locates the query matches and splits each match
+ into <quote>fragments</quote> of no more than <literal>MaxWords</literal>
+ words each, preferring fragments with more query words, and when
+ possible <quote>stretching</quote> fragments to include surrounding
+ words. The fragment-based mode is thus more useful when the query
+ matches span large sections of the document, or when it's desirable to
+ display multiple matches.
+ In either mode, if no query matches can be identified, then a single
+ fragment of the first <literal>MinWords</literal> words in the document
+ will be displayed.
+ </para>
+
+ <para>
+ For example:
+
+<screen>
+SELECT ts_headline('english',
+ 'The most common type of search
+is to find all documents containing given query terms
+and return them in order of their similarity to the
+query.',
+ to_tsquery('english', 'query &amp; similarity'));
+ ts_headline
+------------------------------------------------------------
+ containing given &lt;b&gt;query&lt;/b&gt; terms +
+ and return them in order of their &lt;b&gt;similarity&lt;/b&gt; to the+
+ &lt;b&gt;query&lt;/b&gt;.
+
+SELECT ts_headline('english',
+ 'Search terms may occur
+many times in a document,
+requiring ranking of the search matches to decide which
+occurrences to display in the result.',
+ to_tsquery('english', 'search &amp; term'),
+ 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=&lt;&lt;, StopSel=&gt;&gt;');
+ ts_headline
+------------------------------------------------------------
+ &lt;&lt;Search&gt;&gt; &lt;&lt;terms&gt;&gt; may occur +
+ many times ... ranking of the &lt;&lt;search&gt;&gt; matches to decide
+</screen>
+ </para>
+
+ <para>
+ <function>ts_headline</function> uses the original document, not a
+ <type>tsvector</type> summary, so it can be slow and should be used with
+ care.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="textsearch-features">
+ <title>Additional Features</title>
+
+ <para>
+ This section describes additional functions and operators that are
+ useful in connection with text search.
+ </para>
+
+ <sect2 id="textsearch-manipulate-tsvector">
+ <title>Manipulating Documents</title>
+
+ <para>
+ <xref linkend="textsearch-parsing-documents"/> showed how raw textual
+ documents can be converted into <type>tsvector</type> values.
+ <productname>PostgreSQL</productname> also provides functions and
+ operators that can be used to manipulate documents that are already
+ in <type>tsvector</type> form.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>tsvector concatenation</primary>
+ </indexterm>
+
+ <literal><type>tsvector</type> || <type>tsvector</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ The <type>tsvector</type> concatenation operator
+ returns a vector which combines the lexemes and positional information
+ of the two vectors given as arguments. Positions and weight labels
+ are retained during the concatenation.
+ Positions appearing in the right-hand vector are offset by the largest
+ position mentioned in the left-hand vector, so that the result is
+ nearly equivalent to the result of performing <function>to_tsvector</function>
+ on the concatenation of the two original document strings. (The
+ equivalence is not exact, because any stop-words removed from the
+ end of the left-hand argument will not affect the result, whereas
+ they would have affected the positions of the lexemes in the
+ right-hand argument if textual concatenation were used.)
+ </para>
+
+ <para>
+ One advantage of using concatenation in the vector form, rather than
+ concatenating text before applying <function>to_tsvector</function>, is that
+ you can use different configurations to parse different sections
+ of the document. Also, because the <function>setweight</function> function
+ marks all lexemes of the given vector the same way, it is necessary
+ to parse the text and do <function>setweight</function> before concatenating
+ if you want to label different parts of the document with different
+ weights.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>setweight</primary>
+ </indexterm>
+
+ <literal>setweight(<replaceable class="parameter">vector</replaceable> <type>tsvector</type>, <replaceable class="parameter">weight</replaceable> <type>"char"</type>) returns <type>tsvector</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ <function>setweight</function> returns a copy of the input vector in which every
+ position has been labeled with the given <replaceable>weight</replaceable>, either
+ <literal>A</literal>, <literal>B</literal>, <literal>C</literal>, or
+ <literal>D</literal>. (<literal>D</literal> is the default for new
+ vectors and as such is not displayed on output.) These labels are
+ retained when vectors are concatenated, allowing words from different
+ parts of a document to be weighted differently by ranking functions.
+ </para>
+
+ <para>
+ Note that weight labels apply to <emphasis>positions</emphasis>, not
+ <emphasis>lexemes</emphasis>. If the input vector has been stripped of
+ positions then <function>setweight</function> does nothing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <indexterm>
+ <primary>length(tsvector)</primary>
+ </indexterm>
+
+ <literal>length(<replaceable class="parameter">vector</replaceable> <type>tsvector</type>) returns <type>integer</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the number of lexemes stored in the vector.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>strip</primary>
+ </indexterm>
+
+ <literal>strip(<replaceable class="parameter">vector</replaceable> <type>tsvector</type>) returns <type>tsvector</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns a vector that lists the same lexemes as the given vector, but
+ lacks any position or weight information. The result is usually much
+ smaller than an unstripped vector, but it is also less useful.
+ Relevance ranking does not work as well on stripped vectors as
+ unstripped ones. Also,
+ the <literal>&lt;-&gt;</literal> (FOLLOWED BY) <type>tsquery</type> operator
+ will never match stripped input, since it cannot determine the
+ distance between lexeme occurrences.
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ A full list of <type>tsvector</type>-related functions is available
+ in <xref linkend="textsearch-functions-table"/>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-manipulate-tsquery">
+ <title>Manipulating Queries</title>
+
+ <para>
+ <xref linkend="textsearch-parsing-queries"/> showed how raw textual
+ queries can be converted into <type>tsquery</type> values.
+ <productname>PostgreSQL</productname> also provides functions and
+ operators that can be used to manipulate queries that are already
+ in <type>tsquery</type> form.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+
+ <term>
+ <literal><type>tsquery</type> &amp;&amp; <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the AND-combination of the two given queries.
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <literal><type>tsquery</type> || <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the OR-combination of the two given queries.
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <literal>!! <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the negation (NOT) of the given query.
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <literal><type>tsquery</type> &lt;-&gt; <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns a query that searches for a match to the first given query
+ immediately followed by a match to the second given query, using
+ the <literal>&lt;-&gt;</literal> (FOLLOWED BY)
+ <type>tsquery</type> operator. For example:
+
+<screen>
+SELECT to_tsquery('fat') &lt;-&gt; to_tsquery('cat | rat');
+ ?column?
+----------------------------
+ 'fat' &lt;-&gt; ( 'cat' | 'rat' )
+</screen>
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>tsquery_phrase</primary>
+ </indexterm>
+
+ <literal>tsquery_phrase(<replaceable class="parameter">query1</replaceable> <type>tsquery</type>, <replaceable class="parameter">query2</replaceable> <type>tsquery</type> [, <replaceable class="parameter">distance</replaceable> <type>integer</type> ]) returns <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns a query that searches for a match to the first given query
+ followed by a match to the second given query at a distance of exactly
+ <replaceable>distance</replaceable> lexemes, using
+ the <literal>&lt;<replaceable>N</replaceable>&gt;</literal>
+ <type>tsquery</type> operator. For example:
+
+<screen>
+SELECT tsquery_phrase(to_tsquery('fat'), to_tsquery('cat'), 10);
+ tsquery_phrase
+------------------
+ 'fat' &lt;10&gt; 'cat'
+</screen>
+ </para>
+ </listitem>
+
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>numnode</primary>
+ </indexterm>
+
+ <literal>numnode(<replaceable class="parameter">query</replaceable> <type>tsquery</type>) returns <type>integer</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the number of nodes (lexemes plus operators) in a
+ <type>tsquery</type>. This function is useful
+ to determine if the <replaceable>query</replaceable> is meaningful
+ (returns &gt; 0), or contains only stop words (returns 0).
+ Examples:
+
+<screen>
+SELECT numnode(plainto_tsquery('the any'));
+NOTICE: query contains only stopword(s) or doesn't contain lexeme(s), ignored
+ numnode
+---------
+ 0
+
+SELECT numnode('foo &amp; bar'::tsquery);
+ numnode
+---------
+ 3
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm>
+ <primary>querytree</primary>
+ </indexterm>
+
+ <literal>querytree(<replaceable class="parameter">query</replaceable> <type>tsquery</type>) returns <type>text</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ Returns the portion of a <type>tsquery</type> that can be used for
+ searching an index. This function is useful for detecting
+ unindexable queries, for example those containing only stop words
+ or only negated terms. For example:
+
+<screen>
+SELECT querytree(to_tsquery('defined'));
+ querytree
+-----------
+ 'defin'
+
+SELECT querytree(to_tsquery('!defined'));
+ querytree
+-----------
+ T
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <sect3 id="textsearch-query-rewriting">
+ <title>Query Rewriting</title>
+
+ <indexterm zone="textsearch-query-rewriting">
+ <primary>ts_rewrite</primary>
+ </indexterm>
+
+ <para>
+ The <function>ts_rewrite</function> family of functions search a
+ given <type>tsquery</type> for occurrences of a target
+ subquery, and replace each occurrence with a
+ substitute subquery. In essence this operation is a
+ <type>tsquery</type>-specific version of substring replacement.
+ A target and substitute combination can be
+ thought of as a <firstterm>query rewrite rule</firstterm>. A collection
+ of such rewrite rules can be a powerful search aid.
+ For example, you can expand the search using synonyms
+ (e.g., <literal>new york</literal>, <literal>big apple</literal>, <literal>nyc</literal>,
+ <literal>gotham</literal>) or narrow the search to direct the user to some hot
+ topic. There is some overlap in functionality between this feature
+ and thesaurus dictionaries (<xref linkend="textsearch-thesaurus"/>).
+ However, you can modify a set of rewrite rules on-the-fly without
+ reindexing, whereas updating a thesaurus requires reindexing to be
+ effective.
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+
+ <term>
+ <literal>ts_rewrite (<replaceable class="parameter">query</replaceable> <type>tsquery</type>, <replaceable class="parameter">target</replaceable> <type>tsquery</type>, <replaceable class="parameter">substitute</replaceable> <type>tsquery</type>) returns <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ This form of <function>ts_rewrite</function> simply applies a single
+ rewrite rule: <replaceable class="parameter">target</replaceable>
+ is replaced by <replaceable class="parameter">substitute</replaceable>
+ wherever it appears in <replaceable
+ class="parameter">query</replaceable>. For example:
+
+<screen>
+SELECT ts_rewrite('a &amp; b'::tsquery, 'a'::tsquery, 'c'::tsquery);
+ ts_rewrite
+------------
+ 'b' &amp; 'c'
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <literal>ts_rewrite (<replaceable class="parameter">query</replaceable> <type>tsquery</type>, <replaceable class="parameter">select</replaceable> <type>text</type>) returns <type>tsquery</type></literal>
+ </term>
+
+ <listitem>
+ <para>
+ This form of <function>ts_rewrite</function> accepts a starting
+ <replaceable>query</replaceable> and an SQL <replaceable>select</replaceable> command, which
+ is given as a text string. The <replaceable>select</replaceable> must yield two
+ columns of <type>tsquery</type> type. For each row of the
+ <replaceable>select</replaceable> result, occurrences of the first column value
+ (the target) are replaced by the second column value (the substitute)
+ within the current <replaceable>query</replaceable> value. For example:
+
+<screen>
+CREATE TABLE aliases (t tsquery PRIMARY KEY, s tsquery);
+INSERT INTO aliases VALUES('a', 'c');
+
+SELECT ts_rewrite('a &amp; b'::tsquery, 'SELECT t,s FROM aliases');
+ ts_rewrite
+------------
+ 'b' &amp; 'c'
+</screen>
+ </para>
+
+ <para>
+ Note that when multiple rewrite rules are applied in this way,
+ the order of application can be important; so in practice you will
+ want the source query to <literal>ORDER BY</literal> some ordering key.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Let's consider a real-life astronomical example. We'll expand query
+ <literal>supernovae</literal> using table-driven rewriting rules:
+
+<screen>
+CREATE TABLE aliases (t tsquery primary key, s tsquery);
+INSERT INTO aliases VALUES(to_tsquery('supernovae'), to_tsquery('supernovae|sn'));
+
+SELECT ts_rewrite(to_tsquery('supernovae &amp; crab'), 'SELECT * FROM aliases');
+ ts_rewrite
+---------------------------------
+ 'crab' &amp; ( 'supernova' | 'sn' )
+</screen>
+
+ We can change the rewriting rules just by updating the table:
+
+<screen>
+UPDATE aliases
+SET s = to_tsquery('supernovae|sn &amp; !nebulae')
+WHERE t = to_tsquery('supernovae');
+
+SELECT ts_rewrite(to_tsquery('supernovae &amp; crab'), 'SELECT * FROM aliases');
+ ts_rewrite
+---------------------------------------------
+ 'crab' &amp; ( 'supernova' | 'sn' &amp; !'nebula' )
+</screen>
+ </para>
+
+ <para>
+ Rewriting can be slow when there are many rewriting rules, since it
+ checks every rule for a possible match. To filter out obvious non-candidate
+ rules we can use the containment operators for the <type>tsquery</type>
+ type. In the example below, we select only those rules which might match
+ the original query:
+
+<screen>
+SELECT ts_rewrite('a &amp; b'::tsquery,
+ 'SELECT t,s FROM aliases WHERE ''a &amp; b''::tsquery @&gt; t');
+ ts_rewrite
+------------
+ 'b' &amp; 'c'
+</screen>
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="textsearch-update-triggers">
+ <title>Triggers for Automatic Updates</title>
+
+ <indexterm>
+ <primary>trigger</primary>
+ <secondary>for updating a derived tsvector column</secondary>
+ </indexterm>
+
+ <note>
+ <para>
+ The method described in this section has been obsoleted by the use of
+ stored generated columns, as described in <xref
+ linkend="textsearch-tables-index"/>.
+ </para>
+ </note>
+
+ <para>
+ When using a separate column to store the <type>tsvector</type> representation
+ of your documents, it is necessary to create a trigger to update the
+ <type>tsvector</type> column when the document content columns change.
+ Two built-in trigger functions are available for this, or you can write
+ your own.
+ </para>
+
+<synopsis>
+tsvector_update_trigger(<replaceable class="parameter">tsvector_column_name</replaceable>,&zwsp; <replaceable class="parameter">config_name</replaceable>, <replaceable class="parameter">text_column_name</replaceable> <optional>, ... </optional>)
+tsvector_update_trigger_column(<replaceable class="parameter">tsvector_column_name</replaceable>,&zwsp; <replaceable class="parameter">config_column_name</replaceable>, <replaceable class="parameter">text_column_name</replaceable> <optional>, ... </optional>)
+</synopsis>
+
+ <para>
+ These trigger functions automatically compute a <type>tsvector</type>
+ column from one or more textual columns, under the control of
+ parameters specified in the <command>CREATE TRIGGER</command> command.
+ An example of their use is:
+
+<screen>
+CREATE TABLE messages (
+ title text,
+ body text,
+ tsv tsvector
+);
+
+CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
+ON messages FOR EACH ROW EXECUTE FUNCTION
+tsvector_update_trigger(tsv, 'pg_catalog.english', title, body);
+
+INSERT INTO messages VALUES('title here', 'the body text is here');
+
+SELECT * FROM messages;
+ title | body | tsv
+------------+-----------------------+----------------------------
+ title here | the body text is here | 'bodi':4 'text':5 'titl':1
+
+SELECT title, body FROM messages WHERE tsv @@ to_tsquery('title &amp; body');
+ title | body
+------------+-----------------------
+ title here | the body text is here
+</screen>
+
+ Having created this trigger, any change in <structfield>title</structfield> or
+ <structfield>body</structfield> will automatically be reflected into
+ <structfield>tsv</structfield>, without the application having to worry about it.
+ </para>
+
+ <para>
+ The first trigger argument must be the name of the <type>tsvector</type>
+ column to be updated. The second argument specifies the text search
+ configuration to be used to perform the conversion. For
+ <function>tsvector_update_trigger</function>, the configuration name is simply
+ given as the second trigger argument. It must be schema-qualified as
+ shown above, so that the trigger behavior will not change with changes
+ in <varname>search_path</varname>. For
+ <function>tsvector_update_trigger_column</function>, the second trigger argument
+ is the name of another table column, which must be of type
+ <type>regconfig</type>. This allows a per-row selection of configuration
+ to be made. The remaining argument(s) are the names of textual columns
+ (of type <type>text</type>, <type>varchar</type>, or <type>char</type>). These
+ will be included in the document in the order given. NULL values will
+ be skipped (but the other columns will still be indexed).
+ </para>
+
+ <para>
+ A limitation of these built-in triggers is that they treat all the
+ input columns alike. To process columns differently &mdash; for
+ example, to weight title differently from body &mdash; it is necessary
+ to write a custom trigger. Here is an example using
+ <application>PL/pgSQL</application> as the trigger language:
+
+<programlisting>
+CREATE FUNCTION messages_trigger() RETURNS trigger AS $$
+begin
+ new.tsv :=
+ setweight(to_tsvector('pg_catalog.english', coalesce(new.title,'')), 'A') ||
+ setweight(to_tsvector('pg_catalog.english', coalesce(new.body,'')), 'D');
+ return new;
+end
+$$ LANGUAGE plpgsql;
+
+CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
+ ON messages FOR EACH ROW EXECUTE FUNCTION messages_trigger();
+</programlisting>
+ </para>
+
+ <para>
+ Keep in mind that it is important to specify the configuration name
+ explicitly when creating <type>tsvector</type> values inside triggers,
+ so that the column's contents will not be affected by changes to
+ <varname>default_text_search_config</varname>. Failure to do this is likely to
+ lead to problems such as search results changing after a dump and restore.
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-statistics">
+ <title>Gathering Document Statistics</title>
+
+ <indexterm>
+ <primary>ts_stat</primary>
+ </indexterm>
+
+ <para>
+ The function <function>ts_stat</function> is useful for checking your
+ configuration and for finding stop-word candidates.
+ </para>
+
+<synopsis>
+ts_stat(<replaceable class="parameter">sqlquery</replaceable> <type>text</type>, <optional> <replaceable class="parameter">weights</replaceable> <type>text</type>, </optional>
+ OUT <replaceable class="parameter">word</replaceable> <type>text</type>, OUT <replaceable class="parameter">ndoc</replaceable> <type>integer</type>,
+ OUT <replaceable class="parameter">nentry</replaceable> <type>integer</type>) returns <type>setof record</type>
+</synopsis>
+
+ <para>
+ <replaceable>sqlquery</replaceable> is a text value containing an SQL
+ query which must return a single <type>tsvector</type> column.
+ <function>ts_stat</function> executes the query and returns statistics about
+ each distinct lexeme (word) contained in the <type>tsvector</type>
+ data. The columns returned are
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <replaceable>word</replaceable> <type>text</type> &mdash; the value of a lexeme
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>ndoc</replaceable> <type>integer</type> &mdash; number of documents
+ (<type>tsvector</type>s) the word occurred in
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>nentry</replaceable> <type>integer</type> &mdash; total number of
+ occurrences of the word
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ If <replaceable>weights</replaceable> is supplied, only occurrences
+ having one of those weights are counted.
+ </para>
+
+ <para>
+ For example, to find the ten most frequent words in a document collection:
+
+<programlisting>
+SELECT * FROM ts_stat('SELECT vector FROM apod')
+ORDER BY nentry DESC, ndoc DESC, word
+LIMIT 10;
+</programlisting>
+
+ The same, but counting only word occurrences with weight <literal>A</literal>
+ or <literal>B</literal>:
+
+<programlisting>
+SELECT * FROM ts_stat('SELECT vector FROM apod', 'ab')
+ORDER BY nentry DESC, ndoc DESC, word
+LIMIT 10;
+</programlisting>
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="textsearch-parsers">
+ <title>Parsers</title>
+
+ <para>
+ Text search parsers are responsible for splitting raw document text
+ into <firstterm>tokens</firstterm> and identifying each token's type, where
+ the set of possible types is defined by the parser itself.
+ Note that a parser does not modify the text at all &mdash; it simply
+ identifies plausible word boundaries. Because of this limited scope,
+ there is less need for application-specific custom parsers than there is
+ for custom dictionaries. At present <productname>PostgreSQL</productname>
+ provides just one built-in parser, which has been found to be useful for a
+ wide range of applications.
+ </para>
+
+ <para>
+ The built-in parser is named <literal>pg_catalog.default</literal>.
+ It recognizes 23 token types, shown in <xref linkend="textsearch-default-parser"/>.
+ </para>
+
+ <table id="textsearch-default-parser">
+ <title>Default Parser's Token Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <colspec colname="col3" colwidth="3*"/>
+ <thead>
+ <row>
+ <entry>Alias</entry>
+ <entry>Description</entry>
+ <entry>Example</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>asciiword</literal></entry>
+ <entry>Word, all ASCII letters</entry>
+ <entry><literal>elephant</literal></entry>
+ </row>
+ <row>
+ <entry><literal>word</literal></entry>
+ <entry>Word, all letters</entry>
+ <entry><literal>ma&ntilde;ana</literal></entry>
+ </row>
+ <row>
+ <entry><literal>numword</literal></entry>
+ <entry>Word, letters and digits</entry>
+ <entry><literal>beta1</literal></entry>
+ </row>
+ <row>
+ <entry><literal>asciihword</literal></entry>
+ <entry>Hyphenated word, all ASCII</entry>
+ <entry><literal>up-to-date</literal></entry>
+ </row>
+ <row>
+ <entry><literal>hword</literal></entry>
+ <entry>Hyphenated word, all letters</entry>
+ <entry><literal>l&oacute;gico-matem&aacute;tica</literal></entry>
+ </row>
+ <row>
+ <entry><literal>numhword</literal></entry>
+ <entry>Hyphenated word, letters and digits</entry>
+ <entry><literal>postgresql-beta1</literal></entry>
+ </row>
+ <row>
+ <entry><literal>hword_asciipart</literal></entry>
+ <entry>Hyphenated word part, all ASCII</entry>
+ <entry><literal>postgresql</literal> in the context <literal>postgresql-beta1</literal></entry>
+ </row>
+ <row>
+ <entry><literal>hword_part</literal></entry>
+ <entry>Hyphenated word part, all letters</entry>
+ <entry><literal>l&oacute;gico</literal> or <literal>matem&aacute;tica</literal>
+ in the context <literal>l&oacute;gico-matem&aacute;tica</literal></entry>
+ </row>
+ <row>
+ <entry><literal>hword_numpart</literal></entry>
+ <entry>Hyphenated word part, letters and digits</entry>
+ <entry><literal>beta1</literal> in the context
+ <literal>postgresql-beta1</literal></entry>
+ </row>
+ <row>
+ <entry><literal>email</literal></entry>
+ <entry>Email address</entry>
+ <entry><literal>foo@example.com</literal></entry>
+ </row>
+ <row>
+ <entry><literal>protocol</literal></entry>
+ <entry>Protocol head</entry>
+ <entry><literal>http://</literal></entry>
+ </row>
+ <row>
+ <entry><literal>url</literal></entry>
+ <entry>URL</entry>
+ <entry><literal>example.com/stuff/index.html</literal></entry>
+ </row>
+ <row>
+ <entry><literal>host</literal></entry>
+ <entry>Host</entry>
+ <entry><literal>example.com</literal></entry>
+ </row>
+ <row>
+ <entry><literal>url_path</literal></entry>
+ <entry>URL path</entry>
+ <entry><literal>/stuff/index.html</literal>, in the context of a URL</entry>
+ </row>
+ <row>
+ <entry><literal>file</literal></entry>
+ <entry>File or path name</entry>
+ <entry><literal>/usr/local/foo.txt</literal>, if not within a URL</entry>
+ </row>
+ <row>
+ <entry><literal>sfloat</literal></entry>
+ <entry>Scientific notation</entry>
+ <entry><literal>-1.234e56</literal></entry>
+ </row>
+ <row>
+ <entry><literal>float</literal></entry>
+ <entry>Decimal notation</entry>
+ <entry><literal>-1.234</literal></entry>
+ </row>
+ <row>
+ <entry><literal>int</literal></entry>
+ <entry>Signed integer</entry>
+ <entry><literal>-1234</literal></entry>
+ </row>
+ <row>
+ <entry><literal>uint</literal></entry>
+ <entry>Unsigned integer</entry>
+ <entry><literal>1234</literal></entry>
+ </row>
+ <row>
+ <entry><literal>version</literal></entry>
+ <entry>Version number</entry>
+ <entry><literal>8.3.0</literal></entry>
+ </row>
+ <row>
+ <entry><literal>tag</literal></entry>
+ <entry>XML tag</entry>
+ <entry><literal>&lt;a href="dictionaries.html"&gt;</literal></entry>
+ </row>
+ <row>
+ <entry><literal>entity</literal></entry>
+ <entry>XML entity</entry>
+ <entry><literal>&amp;amp;</literal></entry>
+ </row>
+ <row>
+ <entry><literal>blank</literal></entry>
+ <entry>Space symbols</entry>
+ <entry>(any whitespace or punctuation not otherwise recognized)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <note>
+ <para>
+ The parser's notion of a <quote>letter</quote> is determined by the database's
+ locale setting, specifically <varname>lc_ctype</varname>. Words containing
+ only the basic ASCII letters are reported as a separate token type,
+ since it is sometimes useful to distinguish them. In most European
+ languages, token types <literal>word</literal> and <literal>asciiword</literal>
+ should be treated alike.
+ </para>
+
+ <para>
+ <literal>email</literal> does not support all valid email characters as
+ defined by <ulink url="https://tools.ietf.org/html/rfc5322">RFC 5322</ulink>.
+ Specifically, the only non-alphanumeric characters supported for
+ email user names are period, dash, and underscore.
+ </para>
+ </note>
+
+ <para>
+ It is possible for the parser to produce overlapping tokens from the same
+ piece of text. As an example, a hyphenated word will be reported both
+ as the entire word and as each component:
+
+<screen>
+SELECT alias, description, token FROM ts_debug('foo-bar-beta1');
+ alias | description | token
+-----------------+------------------------------------------+---------------
+ numhword | Hyphenated word, letters and digits | foo-bar-beta1
+ hword_asciipart | Hyphenated word part, all ASCII | foo
+ blank | Space symbols | -
+ hword_asciipart | Hyphenated word part, all ASCII | bar
+ blank | Space symbols | -
+ hword_numpart | Hyphenated word part, letters and digits | beta1
+</screen>
+
+ This behavior is desirable since it allows searches to work for both
+ the whole compound word and for components. Here is another
+ instructive example:
+
+<screen>
+SELECT alias, description, token FROM ts_debug('http://example.com/stuff/index.html');
+ alias | description | token
+----------+---------------+------------------------------
+ protocol | Protocol head | http://
+ url | URL | example.com/stuff/index.html
+ host | Host | example.com
+ url_path | URL path | /stuff/index.html
+</screen>
+ </para>
+
+ </sect1>
+
+ <sect1 id="textsearch-dictionaries">
+ <title>Dictionaries</title>
+
+ <para>
+ Dictionaries are used to eliminate words that should not be considered in a
+ search (<firstterm>stop words</firstterm>), and to <firstterm>normalize</firstterm> words so
+ that different derived forms of the same word will match. A successfully
+ normalized word is called a <firstterm>lexeme</firstterm>. Aside from
+ improving search quality, normalization and removal of stop words reduce the
+ size of the <type>tsvector</type> representation of a document, thereby
+ improving performance. Normalization does not always have linguistic meaning
+ and usually depends on application semantics.
+ </para>
+
+ <para>
+ Some examples of normalization:
+
+ <itemizedlist spacing="compact" mark="bullet">
+
+ <listitem>
+ <para>
+ Linguistic &mdash; Ispell dictionaries try to reduce input words to a
+ normalized form; stemmer dictionaries remove word endings
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <acronym>URL</acronym> locations can be canonicalized to make
+ equivalent URLs match:
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ http://www.pgsql.ru/db/mw/index.html
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ http://www.pgsql.ru/db/mw/
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ http://www.pgsql.ru/db/../db/mw/index.html
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Color names can be replaced by their hexadecimal values, e.g.,
+ <literal>red, green, blue, magenta -> FF0000, 00FF00, 0000FF, FF00FF</literal>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If indexing numbers, we can
+ remove some fractional digits to reduce the range of possible
+ numbers, so for example <emphasis>3.14</emphasis>159265359,
+ <emphasis>3.14</emphasis>15926, <emphasis>3.14</emphasis> will be the same
+ after normalization if only two digits are kept after the decimal point.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ </para>
+
+ <para>
+ A dictionary is a program that accepts a token as
+ input and returns:
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ an array of lexemes if the input token is known to the dictionary
+ (notice that one token can produce more than one lexeme)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a single lexeme with the <literal>TSL_FILTER</literal> flag set, to replace
+ the original token with a new token to be passed to subsequent
+ dictionaries (a dictionary that does this is called a
+ <firstterm>filtering dictionary</firstterm>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ an empty array if the dictionary knows the token, but it is a stop word
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>NULL</literal> if the dictionary does not recognize the input token
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> provides predefined dictionaries for
+ many languages. There are also several predefined templates that can be
+ used to create new dictionaries with custom parameters. Each predefined
+ dictionary template is described below. If no existing
+ template is suitable, it is possible to create new ones; see the
+ <filename>contrib/</filename> area of the <productname>PostgreSQL</productname> distribution
+ for examples.
+ </para>
+
+ <para>
+ A text search configuration binds a parser together with a set of
+ dictionaries to process the parser's output tokens. For each token
+ type that the parser can return, a separate list of dictionaries is
+ specified by the configuration. When a token of that type is found
+ by the parser, each dictionary in the list is consulted in turn,
+ until some dictionary recognizes it as a known word. If it is identified
+ as a stop word, or if no dictionary recognizes the token, it will be
+ discarded and not indexed or searched for.
+ Normally, the first dictionary that returns a non-<literal>NULL</literal>
+ output determines the result, and any remaining dictionaries are not
+ consulted; but a filtering dictionary can replace the given word
+ with a modified word, which is then passed to subsequent dictionaries.
+ </para>
+
+ <para>
+ The general rule for configuring a list of dictionaries
+ is to place first the most narrow, most specific dictionary, then the more
+ general dictionaries, finishing with a very general dictionary, like
+ a <application>Snowball</application> stemmer or <literal>simple</literal>, which
+ recognizes everything. For example, for an astronomy-specific search
+ (<literal>astro_en</literal> configuration) one could bind token type
+ <type>asciiword</type> (ASCII word) to a synonym dictionary of astronomical
+ terms, a general English dictionary and a <application>Snowball</application> English
+ stemmer:
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION astro_en
+ ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;
+</programlisting>
+ </para>
+
+ <para>
+ A filtering dictionary can be placed anywhere in the list, except at the
+ end where it'd be useless. Filtering dictionaries are useful to partially
+ normalize words to simplify the task of later dictionaries. For example,
+ a filtering dictionary could be used to remove accents from accented
+ letters, as is done by the <xref linkend="unaccent"/> module.
+ </para>
+
+ <sect2 id="textsearch-stopwords">
+ <title>Stop Words</title>
+
+ <para>
+ Stop words are words that are very common, appear in almost every
+ document, and have no discrimination value. Therefore, they can be ignored
+ in the context of full text searching. For example, every English text
+ contains words like <literal>a</literal> and <literal>the</literal>, so it is
+ useless to store them in an index. However, stop words do affect the
+ positions in <type>tsvector</type>, which in turn affect ranking:
+
+<screen>
+SELECT to_tsvector('english', 'in the list of stop words');
+ to_tsvector
+----------------------------
+ 'list':3 'stop':5 'word':6
+</screen>
+
+ The missing positions 1,2,4 are because of stop words. Ranks
+ calculated for documents with and without stop words are quite different:
+
+<screen>
+SELECT ts_rank_cd (to_tsvector('english', 'in the list of stop words'), to_tsquery('list &amp; stop'));
+ ts_rank_cd
+------------
+ 0.05
+
+SELECT ts_rank_cd (to_tsvector('english', 'list stop words'), to_tsquery('list &amp; stop'));
+ ts_rank_cd
+------------
+ 0.1
+</screen>
+
+ </para>
+
+ <para>
+ It is up to the specific dictionary how it treats stop words. For example,
+ <literal>ispell</literal> dictionaries first normalize words and then
+ look at the list of stop words, while <literal>Snowball</literal> stemmers
+ first check the list of stop words. The reason for the different
+ behavior is an attempt to decrease noise.
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-simple-dictionary">
+ <title>Simple Dictionary</title>
+
+ <para>
+ The <literal>simple</literal> dictionary template operates by converting the
+ input token to lower case and checking it against a file of stop words.
+ If it is found in the file then an empty array is returned, causing
+ the token to be discarded. If not, the lower-cased form of the word
+ is returned as the normalized lexeme. Alternatively, the dictionary
+ can be configured to report non-stop-words as unrecognized, allowing
+ them to be passed on to the next dictionary in the list.
+ </para>
+
+ <para>
+ Here is an example of a dictionary definition using the <literal>simple</literal>
+ template:
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY public.simple_dict (
+ TEMPLATE = pg_catalog.simple,
+ STOPWORDS = english
+);
+</programlisting>
+
+ Here, <literal>english</literal> is the base name of a file of stop words.
+ The file's full name will be
+ <filename>$SHAREDIR/tsearch_data/english.stop</filename>,
+ where <literal>$SHAREDIR</literal> means the
+ <productname>PostgreSQL</productname> installation's shared-data directory,
+ often <filename>/usr/local/share/postgresql</filename> (use <command>pg_config
+ --sharedir</command> to determine it if you're not sure).
+ The file format is simply a list
+ of words, one per line. Blank lines and trailing spaces are ignored,
+ and upper case is folded to lower case, but no other processing is done
+ on the file contents.
+ </para>
+
+ <para>
+ Now we can test our dictionary:
+
+<screen>
+SELECT ts_lexize('public.simple_dict', 'YeS');
+ ts_lexize
+-----------
+ {yes}
+
+SELECT ts_lexize('public.simple_dict', 'The');
+ ts_lexize
+-----------
+ {}
+</screen>
+ </para>
+
+ <para>
+ We can also choose to return <literal>NULL</literal>, instead of the lower-cased
+ word, if it is not found in the stop words file. This behavior is
+ selected by setting the dictionary's <literal>Accept</literal> parameter to
+ <literal>false</literal>. Continuing the example:
+
+<screen>
+ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false );
+
+SELECT ts_lexize('public.simple_dict', 'YeS');
+ ts_lexize
+-----------
+
+
+SELECT ts_lexize('public.simple_dict', 'The');
+ ts_lexize
+-----------
+ {}
+</screen>
+ </para>
+
+ <para>
+ With the default setting of <literal>Accept</literal> = <literal>true</literal>,
+ it is only useful to place a <literal>simple</literal> dictionary at the end
+ of a list of dictionaries, since it will never pass on any token to
+ a following dictionary. Conversely, <literal>Accept</literal> = <literal>false</literal>
+ is only useful when there is at least one following dictionary.
+ </para>
+
+ <caution>
+ <para>
+ Most types of dictionaries rely on configuration files, such as files of
+ stop words. These files <emphasis>must</emphasis> be stored in UTF-8 encoding.
+ They will be translated to the actual database encoding, if that is
+ different, when they are read into the server.
+ </para>
+ </caution>
+
+ <caution>
+ <para>
+ Normally, a database session will read a dictionary configuration file
+ only once, when it is first used within the session. If you modify a
+ configuration file and want to force existing sessions to pick up the
+ new contents, issue an <command>ALTER TEXT SEARCH DICTIONARY</command> command
+ on the dictionary. This can be a <quote>dummy</quote> update that doesn't
+ actually change any parameter values.
+ </para>
+ </caution>
+
+ </sect2>
+
+ <sect2 id="textsearch-synonym-dictionary">
+ <title>Synonym Dictionary</title>
+
+ <para>
+ This dictionary template is used to create dictionaries that replace a
+ word with a synonym. Phrases are not supported (use the thesaurus
+ template (<xref linkend="textsearch-thesaurus"/>) for that). A synonym
+ dictionary can be used to overcome linguistic problems, for example, to
+ prevent an English stemmer dictionary from reducing the word <quote>Paris</quote> to
+ <quote>pari</quote>. It is enough to have a <literal>Paris paris</literal> line in the
+ synonym dictionary and put it before the <literal>english_stem</literal>
+ dictionary. For example:
+
+<screen>
+SELECT * FROM ts_debug('english', 'Paris');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------+----------------+--------------+---------
+ asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari}
+
+CREATE TEXT SEARCH DICTIONARY my_synonym (
+ TEMPLATE = synonym,
+ SYNONYMS = my_synonyms
+);
+
+ALTER TEXT SEARCH CONFIGURATION english
+ ALTER MAPPING FOR asciiword
+ WITH my_synonym, english_stem;
+
+SELECT * FROM ts_debug('english', 'Paris');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------+---------------------------+------------+---------
+ asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris}
+</screen>
+ </para>
+
+ <para>
+ The only parameter required by the <literal>synonym</literal> template is
+ <literal>SYNONYMS</literal>, which is the base name of its configuration file
+ &mdash; <literal>my_synonyms</literal> in the above example.
+ The file's full name will be
+ <filename>$SHAREDIR/tsearch_data/my_synonyms.syn</filename>
+ (where <literal>$SHAREDIR</literal> means the
+ <productname>PostgreSQL</productname> installation's shared-data directory).
+ The file format is just one line
+ per word to be substituted, with the word followed by its synonym,
+ separated by white space. Blank lines and trailing spaces are ignored.
+ </para>
+
+ <para>
+ The <literal>synonym</literal> template also has an optional parameter
+ <literal>CaseSensitive</literal>, which defaults to <literal>false</literal>. When
+ <literal>CaseSensitive</literal> is <literal>false</literal>, words in the synonym file
+ are folded to lower case, as are input tokens. When it is
+ <literal>true</literal>, words and tokens are not folded to lower case,
+ but are compared as-is.
+ </para>
+
+ <para>
+ An asterisk (<literal>*</literal>) can be placed at the end of a synonym
+ in the configuration file. This indicates that the synonym is a prefix.
+ The asterisk is ignored when the entry is used in
+ <function>to_tsvector()</function>, but when it is used in
+ <function>to_tsquery()</function>, the result will be a query item with
+ the prefix match marker (see
+ <xref linkend="textsearch-parsing-queries"/>).
+ For example, suppose we have these entries in
+ <filename>$SHAREDIR/tsearch_data/synonym_sample.syn</filename>:
+<programlisting>
+postgres pgsql
+postgresql pgsql
+postgre pgsql
+gogle googl
+indices index*
+</programlisting>
+ Then we will get these results:
+<screen>
+mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample');
+mydb=# SELECT ts_lexize('syn', 'indices');
+ ts_lexize
+-----------
+ {index}
+(1 row)
+
+mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple);
+mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn;
+mydb=# SELECT to_tsvector('tst', 'indices');
+ to_tsvector
+-------------
+ 'index':1
+(1 row)
+
+mydb=# SELECT to_tsquery('tst', 'indices');
+ to_tsquery
+------------
+ 'index':*
+(1 row)
+
+mydb=# SELECT 'indexes are very useful'::tsvector;
+ tsvector
+---------------------------------
+ 'are' 'indexes' 'useful' 'very'
+(1 row)
+
+mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst', 'indices');
+ ?column?
+----------
+ t
+(1 row)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="textsearch-thesaurus">
+ <title>Thesaurus Dictionary</title>
+
+ <para>
+ A thesaurus dictionary (sometimes abbreviated as <acronym>TZ</acronym>) is
+ a collection of words that includes information about the relationships
+ of words and phrases, i.e., broader terms (<acronym>BT</acronym>), narrower
+ terms (<acronym>NT</acronym>), preferred terms, non-preferred terms, related
+ terms, etc.
+ </para>
+
+ <para>
+ Basically a thesaurus dictionary replaces all non-preferred terms by one
+ preferred term and, optionally, preserves the original terms for indexing
+ as well. <productname>PostgreSQL</productname>'s current implementation of the
+ thesaurus dictionary is an extension of the synonym dictionary with added
+ <firstterm>phrase</firstterm> support. A thesaurus dictionary requires
+ a configuration file of the following format:
+
+<programlisting>
+# this is a comment
+sample word(s) : indexed word(s)
+more sample word(s) : more indexed word(s)
+...
+</programlisting>
+
+ where the colon (<symbol>:</symbol>) symbol acts as a delimiter between a
+ phrase and its replacement.
+ </para>
+
+ <para>
+ A thesaurus dictionary uses a <firstterm>subdictionary</firstterm> (which
+ is specified in the dictionary's configuration) to normalize the input
+ text before checking for phrase matches. It is only possible to select one
+ subdictionary. An error is reported if the subdictionary fails to
+ recognize a word. In that case, you should remove the use of the word or
+ teach the subdictionary about it. You can place an asterisk
+ (<symbol>*</symbol>) at the beginning of an indexed word to skip applying
+ the subdictionary to it, but all sample words <emphasis>must</emphasis> be known
+ to the subdictionary.
+ </para>
+
+ <para>
+ The thesaurus dictionary chooses the longest match if there are multiple
+ phrases matching the input, and ties are broken by using the last
+ definition.
+ </para>
+
+ <para>
+ Specific stop words recognized by the subdictionary cannot be
+ specified; instead use <literal>?</literal> to mark the location where any
+ stop word can appear. For example, assuming that <literal>a</literal> and
+ <literal>the</literal> are stop words according to the subdictionary:
+
+<programlisting>
+? one ? two : swsw
+</programlisting>
+
+ matches <literal>a one the two</literal> and <literal>the one a two</literal>;
+ both would be replaced by <literal>swsw</literal>.
+ </para>
+
+ <para>
+ Since a thesaurus dictionary has the capability to recognize phrases it
+ must remember its state and interact with the parser. A thesaurus dictionary
+ uses these assignments to check if it should handle the next word or stop
+ accumulation. The thesaurus dictionary must be configured
+ carefully. For example, if the thesaurus dictionary is assigned to handle
+ only the <literal>asciiword</literal> token, then a thesaurus dictionary
+ definition like <literal>one 7</literal> will not work since token type
+ <literal>uint</literal> is not assigned to the thesaurus dictionary.
+ </para>
+
+ <caution>
+ <para>
+ Thesauruses are used during indexing so any change in the thesaurus
+ dictionary's parameters <emphasis>requires</emphasis> reindexing.
+ For most other dictionary types, small changes such as adding or
+ removing stopwords does not force reindexing.
+ </para>
+ </caution>
+
+ <sect3 id="textsearch-thesaurus-config">
+ <title>Thesaurus Configuration</title>
+
+ <para>
+ To define a new thesaurus dictionary, use the <literal>thesaurus</literal>
+ template. For example:
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY thesaurus_simple (
+ TEMPLATE = thesaurus,
+ DictFile = mythesaurus,
+ Dictionary = pg_catalog.english_stem
+);
+</programlisting>
+
+ Here:
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <literal>thesaurus_simple</literal> is the new dictionary's name
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>mythesaurus</literal> is the base name of the thesaurus
+ configuration file.
+ (Its full name will be <filename>$SHAREDIR/tsearch_data/mythesaurus.ths</filename>,
+ where <literal>$SHAREDIR</literal> means the installation shared-data
+ directory.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <literal>pg_catalog.english_stem</literal> is the subdictionary (here,
+ a Snowball English stemmer) to use for thesaurus normalization.
+ Notice that the subdictionary will have its own
+ configuration (for example, stop words), which is not shown here.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ Now it is possible to bind the thesaurus dictionary <literal>thesaurus_simple</literal>
+ to the desired token types in a configuration, for example:
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION russian
+ ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
+ WITH thesaurus_simple;
+</programlisting>
+ </para>
+
+ </sect3>
+
+ <sect3 id="textsearch-thesaurus-examples">
+ <title>Thesaurus Example</title>
+
+ <para>
+ Consider a simple astronomical thesaurus <literal>thesaurus_astro</literal>,
+ which contains some astronomical word combinations:
+
+<programlisting>
+supernovae stars : sn
+crab nebulae : crab
+</programlisting>
+
+ Below we create a dictionary and bind some token types to
+ an astronomical thesaurus and English stemmer:
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY thesaurus_astro (
+ TEMPLATE = thesaurus,
+ DictFile = thesaurus_astro,
+ Dictionary = english_stem
+);
+
+ALTER TEXT SEARCH CONFIGURATION russian
+ ALTER MAPPING FOR asciiword, asciihword, hword_asciipart
+ WITH thesaurus_astro, english_stem;
+</programlisting>
+
+ Now we can see how it works.
+ <function>ts_lexize</function> is not very useful for testing a thesaurus,
+ because it treats its input as a single token. Instead we can use
+ <function>plainto_tsquery</function> and <function>to_tsvector</function>
+ which will break their input strings into multiple tokens:
+
+<screen>
+SELECT plainto_tsquery('supernova star');
+ plainto_tsquery
+-----------------
+ 'sn'
+
+SELECT to_tsvector('supernova star');
+ to_tsvector
+-------------
+ 'sn':1
+</screen>
+
+ In principle, one can use <function>to_tsquery</function> if you quote
+ the argument:
+
+<screen>
+SELECT to_tsquery('''supernova star''');
+ to_tsquery
+------------
+ 'sn'
+</screen>
+
+ Notice that <literal>supernova star</literal> matches <literal>supernovae
+ stars</literal> in <literal>thesaurus_astro</literal> because we specified
+ the <literal>english_stem</literal> stemmer in the thesaurus definition.
+ The stemmer removed the <literal>e</literal> and <literal>s</literal>.
+ </para>
+
+ <para>
+ To index the original phrase as well as the substitute, just include it
+ in the right-hand part of the definition:
+
+<screen>
+supernovae stars : sn supernovae stars
+
+SELECT plainto_tsquery('supernova star');
+ plainto_tsquery
+-----------------------------
+ 'sn' &amp; 'supernova' &amp; 'star'
+</screen>
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="textsearch-ispell-dictionary">
+ <title><application>Ispell</application> Dictionary</title>
+
+ <para>
+ The <application>Ispell</application> dictionary template supports
+ <firstterm>morphological dictionaries</firstterm>, which can normalize many
+ different linguistic forms of a word into the same lexeme. For example,
+ an English <application>Ispell</application> dictionary can match all declensions and
+ conjugations of the search term <literal>bank</literal>, e.g.,
+ <literal>banking</literal>, <literal>banked</literal>, <literal>banks</literal>,
+ <literal>banks'</literal>, and <literal>bank's</literal>.
+ </para>
+
+ <para>
+ The standard <productname>PostgreSQL</productname> distribution does
+ not include any <application>Ispell</application> configuration files.
+ Dictionaries for a large number of languages are available from <ulink
+ url="https://www.cs.hmc.edu/~geoff/ispell.html">Ispell</ulink>.
+ Also, some more modern dictionary file formats are supported &mdash; <ulink
+ url="https://en.wikipedia.org/wiki/MySpell">MySpell</ulink> (OO &lt; 2.0.1)
+ and <ulink url="https://hunspell.github.io/">Hunspell</ulink>
+ (OO &gt;= 2.0.2). A large list of dictionaries is available on the <ulink
+ url="https://wiki.openoffice.org/wiki/Dictionaries">OpenOffice
+ Wiki</ulink>.
+ </para>
+
+ <para>
+ To create an <application>Ispell</application> dictionary perform these steps:
+ </para>
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ download dictionary configuration files. <productname>OpenOffice</productname>
+ extension files have the <filename>.oxt</filename> extension. It is necessary
+ to extract <filename>.aff</filename> and <filename>.dic</filename> files, change
+ extensions to <filename>.affix</filename> and <filename>.dict</filename>. For some
+ dictionary files it is also needed to convert characters to the UTF-8
+ encoding with commands (for example, for a Norwegian language dictionary):
+<programlisting>
+iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff
+iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic
+</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ copy files to the <filename>$SHAREDIR/tsearch_data</filename> directory
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ load files into PostgreSQL with the following command:
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY english_hunspell (
+ TEMPLATE = ispell,
+ DictFile = en_us,
+ AffFile = en_us,
+ Stopwords = english);
+</programlisting>
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Here, <literal>DictFile</literal>, <literal>AffFile</literal>, and <literal>StopWords</literal>
+ specify the base names of the dictionary, affixes, and stop-words files.
+ The stop-words file has the same format explained above for the
+ <literal>simple</literal> dictionary type. The format of the other files is
+ not specified here but is available from the above-mentioned web sites.
+ </para>
+
+ <para>
+ Ispell dictionaries usually recognize a limited set of words, so they
+ should be followed by another broader dictionary; for
+ example, a Snowball dictionary, which recognizes everything.
+ </para>
+
+ <para>
+ The <filename>.affix</filename> file of <application>Ispell</application> has the following
+ structure:
+<programlisting>
+prefixes
+flag *A:
+ . > RE # As in enter > reenter
+suffixes
+flag T:
+ E > ST # As in late > latest
+ [^AEIOU]Y > -Y,IEST # As in dirty > dirtiest
+ [AEIOU]Y > EST # As in gray > grayest
+ [^EY] > EST # As in small > smallest
+</programlisting>
+ </para>
+ <para>
+ And the <filename>.dict</filename> file has the following structure:
+<programlisting>
+lapse/ADGRS
+lard/DGRS
+large/PRTY
+lark/MRS
+</programlisting>
+ </para>
+
+ <para>
+ Format of the <filename>.dict</filename> file is:
+<programlisting>
+basic_form/affix_class_name
+</programlisting>
+ </para>
+
+ <para>
+ In the <filename>.affix</filename> file every affix flag is described in the
+ following format:
+<programlisting>
+condition > [-stripping_letters,] adding_affix
+</programlisting>
+ </para>
+
+ <para>
+ Here, condition has a format similar to the format of regular expressions.
+ It can use groupings <literal>[...]</literal> and <literal>[^...]</literal>.
+ For example, <literal>[AEIOU]Y</literal> means that the last letter of the word
+ is <literal>"y"</literal> and the penultimate letter is <literal>"a"</literal>,
+ <literal>"e"</literal>, <literal>"i"</literal>, <literal>"o"</literal> or <literal>"u"</literal>.
+ <literal>[^EY]</literal> means that the last letter is neither <literal>"e"</literal>
+ nor <literal>"y"</literal>.
+ </para>
+
+ <para>
+ Ispell dictionaries support splitting compound words;
+ a useful feature.
+ Notice that the affix file should specify a special flag using the
+ <literal>compoundwords controlled</literal> statement that marks dictionary
+ words that can participate in compound formation:
+
+<programlisting>
+compoundwords controlled z
+</programlisting>
+
+ Here are some examples for the Norwegian language:
+
+<programlisting>
+SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
+ {over,buljong,terning,pakk,mester,assistent}
+SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
+ {sjokoladefabrikk,sjokolade,fabrikk}
+</programlisting>
+ </para>
+
+ <para>
+ <application>MySpell</application> format is a subset of <application>Hunspell</application>.
+ The <filename>.affix</filename> file of <application>Hunspell</application> has the following
+ structure:
+<programlisting>
+PFX A Y 1
+PFX A 0 re .
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+</programlisting>
+ </para>
+
+ <para>
+ The first line of an affix class is the header. Fields of an affix rules are
+ listed after the header:
+ </para>
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ parameter name (PFX or SFX)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ flag (name of the affix class)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ stripping characters from beginning (at prefix) or end (at suffix) of the
+ word
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ adding affix
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ condition that has a format similar to the format of regular expressions.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The <filename>.dict</filename> file looks like the <filename>.dict</filename> file of
+ <application>Ispell</application>:
+<programlisting>
+larder/M
+lardy/RT
+large/RSPMYT
+largehearted
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ <application>MySpell</application> does not support compound words.
+ <application>Hunspell</application> has sophisticated support for compound words. At
+ present, <productname>PostgreSQL</productname> implements only the basic
+ compound word operations of Hunspell.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="textsearch-snowball-dictionary">
+ <title><application>Snowball</application> Dictionary</title>
+
+ <para>
+ The <application>Snowball</application> dictionary template is based on a project
+ by Martin Porter, inventor of the popular Porter's stemming algorithm
+ for the English language. Snowball now provides stemming algorithms for
+ many languages (see the <ulink url="https://snowballstem.org/">Snowball
+ site</ulink> for more information). Each algorithm understands how to
+ reduce common variant forms of words to a base, or stem, spelling within
+ its language. A Snowball dictionary requires a <literal>language</literal>
+ parameter to identify which stemmer to use, and optionally can specify a
+ <literal>stopword</literal> file name that gives a list of words to eliminate.
+ (<productname>PostgreSQL</productname>'s standard stopword lists are also
+ provided by the Snowball project.)
+ For example, there is a built-in definition equivalent to
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY english_stem (
+ TEMPLATE = snowball,
+ Language = english,
+ StopWords = english
+);
+</programlisting>
+
+ The stopword file format is the same as already explained.
+ </para>
+
+ <para>
+ A <application>Snowball</application> dictionary recognizes everything, whether
+ or not it is able to simplify the word, so it should be placed
+ at the end of the dictionary list. It is useless to have it
+ before any other dictionary because a token will never pass through it to
+ the next dictionary.
+ </para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="textsearch-configuration">
+ <title>Configuration Example</title>
+
+ <para>
+ A text search configuration specifies all options necessary to transform a
+ document into a <type>tsvector</type>: the parser to use to break text
+ into tokens, and the dictionaries to use to transform each token into a
+ lexeme. Every call of
+ <function>to_tsvector</function> or <function>to_tsquery</function>
+ needs a text search configuration to perform its processing.
+ The configuration parameter
+ <xref linkend="guc-default-text-search-config"/>
+ specifies the name of the default configuration, which is the
+ one used by text search functions if an explicit configuration
+ parameter is omitted.
+ It can be set in <filename>postgresql.conf</filename>, or set for an
+ individual session using the <command>SET</command> command.
+ </para>
+
+ <para>
+ Several predefined text search configurations are available, and
+ you can create custom configurations easily. To facilitate management
+ of text search objects, a set of <acronym>SQL</acronym> commands
+ is available, and there are several <application>psql</application> commands that display information
+ about text search objects (<xref linkend="textsearch-psql"/>).
+ </para>
+
+ <para>
+ As an example we will create a configuration
+ <literal>pg</literal>, starting by duplicating the built-in
+ <literal>english</literal> configuration:
+
+<programlisting>
+CREATE TEXT SEARCH CONFIGURATION public.pg ( COPY = pg_catalog.english );
+</programlisting>
+ </para>
+
+ <para>
+ We will use a PostgreSQL-specific synonym list
+ and store it in <filename>$SHAREDIR/tsearch_data/pg_dict.syn</filename>.
+ The file contents look like:
+
+<programlisting>
+postgres pg
+pgsql pg
+postgresql pg
+</programlisting>
+
+ We define the synonym dictionary like this:
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY pg_dict (
+ TEMPLATE = synonym,
+ SYNONYMS = pg_dict
+);
+</programlisting>
+
+ Next we register the <productname>Ispell</productname> dictionary
+ <literal>english_ispell</literal>, which has its own configuration files:
+
+<programlisting>
+CREATE TEXT SEARCH DICTIONARY english_ispell (
+ TEMPLATE = ispell,
+ DictFile = english,
+ AffFile = english,
+ StopWords = english
+);
+</programlisting>
+
+ Now we can set up the mappings for words in configuration
+ <literal>pg</literal>:
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION pg
+ ALTER MAPPING FOR asciiword, asciihword, hword_asciipart,
+ word, hword, hword_part
+ WITH pg_dict, english_ispell, english_stem;
+</programlisting>
+
+ We choose not to index or search some token types that the built-in
+ configuration does handle:
+
+<programlisting>
+ALTER TEXT SEARCH CONFIGURATION pg
+ DROP MAPPING FOR email, url, url_path, sfloat, float;
+</programlisting>
+ </para>
+
+ <para>
+ Now we can test our configuration:
+
+<programlisting>
+SELECT * FROM ts_debug('public.pg', '
+PostgreSQL, the highly scalable, SQL compliant, open source object-relational
+database management system, is now undergoing beta testing of the next
+version of our software.
+');
+</programlisting>
+ </para>
+
+ <para>
+ The next step is to set the session to use the new configuration, which was
+ created in the <literal>public</literal> schema:
+
+<screen>
+=&gt; \dF
+ List of text search configurations
+ Schema | Name | Description
+---------+------+-------------
+ public | pg |
+
+SET default_text_search_config = 'public.pg';
+SET
+
+SHOW default_text_search_config;
+ default_text_search_config
+----------------------------
+ public.pg
+</screen>
+ </para>
+
+ </sect1>
+
+ <sect1 id="textsearch-debugging">
+ <title>Testing and Debugging Text Search</title>
+
+ <para>
+ The behavior of a custom text search configuration can easily become
+ confusing. The functions described
+ in this section are useful for testing text search objects. You can
+ test a complete configuration, or test parsers and dictionaries separately.
+ </para>
+
+ <sect2 id="textsearch-configuration-testing">
+ <title>Configuration Testing</title>
+
+ <para>
+ The function <function>ts_debug</function> allows easy testing of a
+ text search configuration.
+ </para>
+
+ <indexterm>
+ <primary>ts_debug</primary>
+ </indexterm>
+
+<synopsis>
+ts_debug(<optional> <replaceable class="parameter">config</replaceable> <type>regconfig</type>, </optional> <replaceable class="parameter">document</replaceable> <type>text</type>,
+ OUT <replaceable class="parameter">alias</replaceable> <type>text</type>,
+ OUT <replaceable class="parameter">description</replaceable> <type>text</type>,
+ OUT <replaceable class="parameter">token</replaceable> <type>text</type>,
+ OUT <replaceable class="parameter">dictionaries</replaceable> <type>regdictionary[]</type>,
+ OUT <replaceable class="parameter">dictionary</replaceable> <type>regdictionary</type>,
+ OUT <replaceable class="parameter">lexemes</replaceable> <type>text[]</type>)
+ returns setof record
+</synopsis>
+
+ <para>
+ <function>ts_debug</function> displays information about every token of
+ <replaceable class="parameter">document</replaceable> as produced by the
+ parser and processed by the configured dictionaries. It uses the
+ configuration specified by <replaceable
+ class="parameter">config</replaceable>,
+ or <varname>default_text_search_config</varname> if that argument is
+ omitted.
+ </para>
+
+ <para>
+ <function>ts_debug</function> returns one row for each token identified in the text
+ by the parser. The columns returned are
+
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>
+ <replaceable>alias</replaceable> <type>text</type> &mdash; short name of the token type
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>description</replaceable> <type>text</type> &mdash; description of the
+ token type
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>token</replaceable> <type>text</type> &mdash; text of the token
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>dictionaries</replaceable> <type>regdictionary[]</type> &mdash; the
+ dictionaries selected by the configuration for this token type
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>dictionary</replaceable> <type>regdictionary</type> &mdash; the dictionary
+ that recognized the token, or <literal>NULL</literal> if none did
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <replaceable>lexemes</replaceable> <type>text[]</type> &mdash; the lexeme(s) produced
+ by the dictionary that recognized the token, or <literal>NULL</literal> if
+ none did; an empty array (<literal>{}</literal>) means it was recognized as a
+ stop word
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Here is a simple example:
+
+<screen>
+SELECT * FROM ts_debug('english', 'a fat cat sat on a mat - it ate a fat rats');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------+----------------+--------------+---------
+ asciiword | Word, all ASCII | a | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | cat | {english_stem} | english_stem | {cat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | sat | {english_stem} | english_stem | {sat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | on | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | a | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | mat | {english_stem} | english_stem | {mat}
+ blank | Space symbols | | {} | |
+ blank | Space symbols | - | {} | |
+ asciiword | Word, all ASCII | it | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | ate | {english_stem} | english_stem | {ate}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | a | {english_stem} | english_stem | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | fat | {english_stem} | english_stem | {fat}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | rats | {english_stem} | english_stem | {rat}
+</screen>
+ </para>
+
+ <para>
+ For a more extensive demonstration, we
+ first create a <literal>public.english</literal> configuration and
+ Ispell dictionary for the English language:
+ </para>
+
+<programlisting>
+CREATE TEXT SEARCH CONFIGURATION public.english ( COPY = pg_catalog.english );
+
+CREATE TEXT SEARCH DICTIONARY english_ispell (
+ TEMPLATE = ispell,
+ DictFile = english,
+ AffFile = english,
+ StopWords = english
+);
+
+ALTER TEXT SEARCH CONFIGURATION public.english
+ ALTER MAPPING FOR asciiword WITH english_ispell, english_stem;
+</programlisting>
+
+<screen>
+SELECT * FROM ts_debug('public.english', 'The Brightest supernovaes');
+ alias | description | token | dictionaries | dictionary | lexemes
+-----------+-----------------+-------------+-------------------------------+----------------+-------------
+ asciiword | Word, all ASCII | The | {english_ispell,english_stem} | english_ispell | {}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | Brightest | {english_ispell,english_stem} | english_ispell | {bright}
+ blank | Space symbols | | {} | |
+ asciiword | Word, all ASCII | supernovaes | {english_ispell,english_stem} | english_stem | {supernova}
+</screen>
+
+ <para>
+ In this example, the word <literal>Brightest</literal> was recognized by the
+ parser as an <literal>ASCII word</literal> (alias <literal>asciiword</literal>).
+ For this token type the dictionary list is
+ <literal>english_ispell</literal> and
+ <literal>english_stem</literal>. The word was recognized by
+ <literal>english_ispell</literal>, which reduced it to the noun
+ <literal>bright</literal>. The word <literal>supernovaes</literal> is
+ unknown to the <literal>english_ispell</literal> dictionary so it
+ was passed to the next dictionary, and, fortunately, was recognized (in
+ fact, <literal>english_stem</literal> is a Snowball dictionary which
+ recognizes everything; that is why it was placed at the end of the
+ dictionary list).
+ </para>
+
+ <para>
+ The word <literal>The</literal> was recognized by the
+ <literal>english_ispell</literal> dictionary as a stop word (<xref
+ linkend="textsearch-stopwords"/>) and will not be indexed.
+ The spaces are discarded too, since the configuration provides no
+ dictionaries at all for them.
+ </para>
+
+ <para>
+ You can reduce the width of the output by explicitly specifying which columns
+ you want to see:
+
+<screen>
+SELECT alias, token, dictionary, lexemes
+FROM ts_debug('public.english', 'The Brightest supernovaes');
+ alias | token | dictionary | lexemes
+-----------+-------------+----------------+-------------
+ asciiword | The | english_ispell | {}
+ blank | | |
+ asciiword | Brightest | english_ispell | {bright}
+ blank | | |
+ asciiword | supernovaes | english_stem | {supernova}
+</screen>
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-parser-testing">
+ <title>Parser Testing</title>
+
+ <para>
+ The following functions allow direct testing of a text search parser.
+ </para>
+
+ <indexterm>
+ <primary>ts_parse</primary>
+ </indexterm>
+
+<synopsis>
+ts_parse(<replaceable class="parameter">parser_name</replaceable> <type>text</type>, <replaceable class="parameter">document</replaceable> <type>text</type>,
+ OUT <replaceable class="parameter">tokid</replaceable> <type>integer</type>, OUT <replaceable class="parameter">token</replaceable> <type>text</type>) returns <type>setof record</type>
+ts_parse(<replaceable class="parameter">parser_oid</replaceable> <type>oid</type>, <replaceable class="parameter">document</replaceable> <type>text</type>,
+ OUT <replaceable class="parameter">tokid</replaceable> <type>integer</type>, OUT <replaceable class="parameter">token</replaceable> <type>text</type>) returns <type>setof record</type>
+</synopsis>
+
+ <para>
+ <function>ts_parse</function> parses the given <replaceable>document</replaceable>
+ and returns a series of records, one for each token produced by
+ parsing. Each record includes a <varname>tokid</varname> showing the
+ assigned token type and a <varname>token</varname> which is the text of the
+ token. For example:
+
+<screen>
+SELECT * FROM ts_parse('default', '123 - a number');
+ tokid | token
+-------+--------
+ 22 | 123
+ 12 |
+ 12 | -
+ 1 | a
+ 12 |
+ 1 | number
+</screen>
+ </para>
+
+ <indexterm>
+ <primary>ts_token_type</primary>
+ </indexterm>
+
+<synopsis>
+ts_token_type(<replaceable class="parameter">parser_name</replaceable> <type>text</type>, OUT <replaceable class="parameter">tokid</replaceable> <type>integer</type>,
+ OUT <replaceable class="parameter">alias</replaceable> <type>text</type>, OUT <replaceable class="parameter">description</replaceable> <type>text</type>) returns <type>setof record</type>
+ts_token_type(<replaceable class="parameter">parser_oid</replaceable> <type>oid</type>, OUT <replaceable class="parameter">tokid</replaceable> <type>integer</type>,
+ OUT <replaceable class="parameter">alias</replaceable> <type>text</type>, OUT <replaceable class="parameter">description</replaceable> <type>text</type>) returns <type>setof record</type>
+</synopsis>
+
+ <para>
+ <function>ts_token_type</function> returns a table which describes each type of
+ token the specified parser can recognize. For each token type, the table
+ gives the integer <varname>tokid</varname> that the parser uses to label a
+ token of that type, the <varname>alias</varname> that names the token type
+ in configuration commands, and a short <varname>description</varname>. For
+ example:
+
+<screen>
+SELECT * FROM ts_token_type('default');
+ tokid | alias | description
+-------+-----------------+------------------------------------------
+ 1 | asciiword | Word, all ASCII
+ 2 | word | Word, all letters
+ 3 | numword | Word, letters and digits
+ 4 | email | Email address
+ 5 | url | URL
+ 6 | host | Host
+ 7 | sfloat | Scientific notation
+ 8 | version | Version number
+ 9 | hword_numpart | Hyphenated word part, letters and digits
+ 10 | hword_part | Hyphenated word part, all letters
+ 11 | hword_asciipart | Hyphenated word part, all ASCII
+ 12 | blank | Space symbols
+ 13 | tag | XML tag
+ 14 | protocol | Protocol head
+ 15 | numhword | Hyphenated word, letters and digits
+ 16 | asciihword | Hyphenated word, all ASCII
+ 17 | hword | Hyphenated word, all letters
+ 18 | url_path | URL path
+ 19 | file | File or path name
+ 20 | float | Decimal notation
+ 21 | int | Signed integer
+ 22 | uint | Unsigned integer
+ 23 | entity | XML entity
+</screen>
+ </para>
+
+ </sect2>
+
+ <sect2 id="textsearch-dictionary-testing">
+ <title>Dictionary Testing</title>
+
+ <para>
+ The <function>ts_lexize</function> function facilitates dictionary testing.
+ </para>
+
+ <indexterm>
+ <primary>ts_lexize</primary>
+ </indexterm>
+
+<synopsis>
+ts_lexize(<replaceable class="parameter">dict</replaceable> <type>regdictionary</type>, <replaceable class="parameter">token</replaceable> <type>text</type>) returns <type>text[]</type>
+</synopsis>
+
+ <para>
+ <function>ts_lexize</function> returns an array of lexemes if the input
+ <replaceable>token</replaceable> is known to the dictionary,
+ or an empty array if the token
+ is known to the dictionary but it is a stop word, or
+ <literal>NULL</literal> if it is an unknown word.
+ </para>
+
+ <para>
+ Examples:
+
+<screen>
+SELECT ts_lexize('english_stem', 'stars');
+ ts_lexize
+-----------
+ {star}
+
+SELECT ts_lexize('english_stem', 'a');
+ ts_lexize
+-----------
+ {}
+</screen>
+ </para>
+
+ <note>
+ <para>
+ The <function>ts_lexize</function> function expects a single
+ <emphasis>token</emphasis>, not text. Here is a case
+ where this can be confusing:
+
+<screen>
+SELECT ts_lexize('thesaurus_astro', 'supernovae stars') is null;
+ ?column?
+----------
+ t
+</screen>
+
+ The thesaurus dictionary <literal>thesaurus_astro</literal> does know the
+ phrase <literal>supernovae stars</literal>, but <function>ts_lexize</function>
+ fails since it does not parse the input text but treats it as a single
+ token. Use <function>plainto_tsquery</function> or <function>to_tsvector</function> to
+ test thesaurus dictionaries, for example:
+
+<screen>
+SELECT plainto_tsquery('supernovae stars');
+ plainto_tsquery
+-----------------
+ 'sn'
+</screen>
+ </para>
+ </note>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="textsearch-indexes">
+ <title>Preferred Index Types for Text Search</title>
+
+ <indexterm zone="textsearch-indexes">
+ <primary>text search</primary>
+ <secondary>indexes</secondary>
+ </indexterm>
+
+ <para>
+ There are two kinds of indexes that can be used to speed up full text
+ searches:
+ <link linkend="gin"><acronym>GIN</acronym></link> and
+ <link linkend="gist"><acronym>GiST</acronym></link>.
+ Note that indexes are not mandatory for full text searching, but in
+ cases where a column is searched on a regular basis, an index is
+ usually desirable.
+ </para>
+
+ <para>
+ To create such an index, do one of:
+
+ <variablelist>
+
+ <varlistentry>
+
+ <term>
+ <indexterm zone="textsearch-indexes">
+ <primary>index</primary>
+ <secondary>GIN</secondary>
+ <tertiary>text search</tertiary>
+ </indexterm>
+
+ <literal>CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> USING GIN (<replaceable>column</replaceable>);</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Creates a GIN (Generalized Inverted Index)-based index.
+ The <replaceable>column</replaceable> must be of <type>tsvector</type> type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+
+ <term>
+ <indexterm zone="textsearch-indexes">
+ <primary>index</primary>
+ <secondary>GiST</secondary>
+ <tertiary>text search</tertiary>
+ </indexterm>
+
+ <literal>CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> USING GIST (<replaceable>column</replaceable> [ { DEFAULT | tsvector_ops } (siglen = <replaceable>number</replaceable>) ] );</literal>
+ </term>
+
+ <listitem>
+ <para>
+ Creates a GiST (Generalized Search Tree)-based index.
+ The <replaceable>column</replaceable> can be of <type>tsvector</type> or
+ <type>tsquery</type> type.
+ Optional integer parameter <literal>siglen</literal> determines
+ signature length in bytes (see below for details).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+
+ <para>
+ GIN indexes are the preferred text search index type. As inverted
+ indexes, they contain an index entry for each word (lexeme), with a
+ compressed list of matching locations. Multi-word searches can find
+ the first match, then use the index to remove rows that are lacking
+ additional words. GIN indexes store only the words (lexemes) of
+ <type>tsvector</type> values, and not their weight labels. Thus a table
+ row recheck is needed when using a query that involves weights.
+ </para>
+
+ <para>
+ A GiST index is <firstterm>lossy</firstterm>, meaning that the index
+ might produce false matches, and it is necessary
+ to check the actual table row to eliminate such false matches.
+ (<productname>PostgreSQL</productname> does this automatically when needed.)
+ GiST indexes are lossy because each document is represented in the
+ index by a fixed-length signature. The signature length in bytes is determined
+ by the value of the optional integer parameter <literal>siglen</literal>.
+ The default signature length (when <literal>siglen</literal> is not specified) is
+ 124 bytes, the maximum signature length is 2024 bytes. The signature is generated by hashing
+ each word into a single bit in an n-bit string, with all these bits OR-ed
+ together to produce an n-bit document signature. When two words hash to
+ the same bit position there will be a false match. If all words in
+ the query have matches (real or false) then the table row must be
+ retrieved to see if the match is correct. Longer signatures lead to a more
+ precise search (scanning a smaller fraction of the index and fewer heap
+ pages), at the cost of a larger index.
+ </para>
+
+ <para>
+ A GiST index can be covering, i.e., use the <literal>INCLUDE</literal>
+ clause. Included columns can have data types without any GiST operator
+ class. Included attributes will be stored uncompressed.
+ </para>
+
+ <para>
+ Lossiness causes performance degradation due to unnecessary fetches of table
+ records that turn out to be false matches. Since random access to table
+ records is slow, this limits the usefulness of GiST indexes. The
+ likelihood of false matches depends on several factors, in particular the
+ number of unique words, so using dictionaries to reduce this number is
+ recommended.
+ </para>
+
+ <para>
+ Note that <acronym>GIN</acronym> index build time can often be improved
+ by increasing <xref linkend="guc-maintenance-work-mem"/>, while
+ <acronym>GiST</acronym> index build time is not sensitive to that
+ parameter.
+ </para>
+
+ <para>
+ Partitioning of big collections and the proper use of GIN and GiST indexes
+ allows the implementation of very fast searches with online update.
+ Partitioning can be done at the database level using table inheritance,
+ or by distributing documents over
+ servers and collecting external search results, e.g., via <link
+ linkend="ddl-foreign-data">Foreign Data</link> access.
+ The latter is possible because ranking functions use
+ only local information.
+ </para>
+
+ </sect1>
+
+ <sect1 id="textsearch-psql">
+ <title><application>psql</application> Support</title>
+
+ <para>
+ Information about text search configuration objects can be obtained
+ in <application>psql</application> using a set of commands:
+<synopsis>
+\dF{d,p,t}<optional>+</optional> <optional>PATTERN</optional>
+</synopsis>
+ An optional <literal>+</literal> produces more details.
+ </para>
+
+ <para>
+ The optional parameter <replaceable>PATTERN</replaceable> can be the name of
+ a text search object, optionally schema-qualified. If
+ <replaceable>PATTERN</replaceable> is omitted then information about all
+ visible objects will be displayed. <replaceable>PATTERN</replaceable> can be a
+ regular expression and can provide <emphasis>separate</emphasis> patterns
+ for the schema and object names. The following examples illustrate this:
+
+<screen>
+=&gt; \dF *fulltext*
+ List of text search configurations
+ Schema | Name | Description
+--------+--------------+-------------
+ public | fulltext_cfg |
+</screen>
+
+<screen>
+=&gt; \dF *.fulltext*
+ List of text search configurations
+ Schema | Name | Description
+----------+----------------------------
+ fulltext | fulltext_cfg |
+ public | fulltext_cfg |
+</screen>
+
+ The available commands are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>\dF<optional>+</optional> <optional>PATTERN</optional></literal></term>
+ <listitem>
+ <para>
+ List text search configurations (add <literal>+</literal> for more detail).
+<screen>
+=&gt; \dF russian
+ List of text search configurations
+ Schema | Name | Description
+------------+---------+------------------------------------
+ pg_catalog | russian | configuration for russian language
+
+=&gt; \dF+ russian
+Text search configuration "pg_catalog.russian"
+Parser: "pg_catalog.default"
+ Token | Dictionaries
+-----------------+--------------
+ asciihword | english_stem
+ asciiword | english_stem
+ email | simple
+ file | simple
+ float | simple
+ host | simple
+ hword | russian_stem
+ hword_asciipart | english_stem
+ hword_numpart | simple
+ hword_part | russian_stem
+ int | simple
+ numhword | simple
+ numword | simple
+ sfloat | simple
+ uint | simple
+ url | simple
+ url_path | simple
+ version | simple
+ word | russian_stem
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dFd<optional>+</optional> <optional>PATTERN</optional></literal></term>
+ <listitem>
+ <para>
+ List text search dictionaries (add <literal>+</literal> for more detail).
+<screen>
+=&gt; \dFd
+ List of text search dictionaries
+ Schema | Name | Description
+------------+-----------------+-----------------------------------------------------------
+ pg_catalog | arabic_stem | snowball stemmer for arabic language
+ pg_catalog | armenian_stem | snowball stemmer for armenian language
+ pg_catalog | basque_stem | snowball stemmer for basque language
+ pg_catalog | catalan_stem | snowball stemmer for catalan language
+ pg_catalog | danish_stem | snowball stemmer for danish language
+ pg_catalog | dutch_stem | snowball stemmer for dutch language
+ pg_catalog | english_stem | snowball stemmer for english language
+ pg_catalog | finnish_stem | snowball stemmer for finnish language
+ pg_catalog | french_stem | snowball stemmer for french language
+ pg_catalog | german_stem | snowball stemmer for german language
+ pg_catalog | greek_stem | snowball stemmer for greek language
+ pg_catalog | hindi_stem | snowball stemmer for hindi language
+ pg_catalog | hungarian_stem | snowball stemmer for hungarian language
+ pg_catalog | indonesian_stem | snowball stemmer for indonesian language
+ pg_catalog | irish_stem | snowball stemmer for irish language
+ pg_catalog | italian_stem | snowball stemmer for italian language
+ pg_catalog | lithuanian_stem | snowball stemmer for lithuanian language
+ pg_catalog | nepali_stem | snowball stemmer for nepali language
+ pg_catalog | norwegian_stem | snowball stemmer for norwegian language
+ pg_catalog | portuguese_stem | snowball stemmer for portuguese language
+ pg_catalog | romanian_stem | snowball stemmer for romanian language
+ pg_catalog | russian_stem | snowball stemmer for russian language
+ pg_catalog | serbian_stem | snowball stemmer for serbian language
+ pg_catalog | simple | simple dictionary: just lower case and check for stopword
+ pg_catalog | spanish_stem | snowball stemmer for spanish language
+ pg_catalog | swedish_stem | snowball stemmer for swedish language
+ pg_catalog | tamil_stem | snowball stemmer for tamil language
+ pg_catalog | turkish_stem | snowball stemmer for turkish language
+ pg_catalog | yiddish_stem | snowball stemmer for yiddish language
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dFp<optional>+</optional> <optional>PATTERN</optional></literal></term>
+ <listitem>
+ <para>
+ List text search parsers (add <literal>+</literal> for more detail).
+<screen>
+=&gt; \dFp
+ List of text search parsers
+ Schema | Name | Description
+------------+---------+---------------------
+ pg_catalog | default | default word parser
+=&gt; \dFp+
+ Text search parser "pg_catalog.default"
+ Method | Function | Description
+-----------------+----------------+-------------
+ Start parse | prsd_start |
+ Get next token | prsd_nexttoken |
+ End parse | prsd_end |
+ Get headline | prsd_headline |
+ Get token types | prsd_lextype |
+
+ Token types for parser "pg_catalog.default"
+ Token name | Description
+-----------------+------------------------------------------
+ asciihword | Hyphenated word, all ASCII
+ asciiword | Word, all ASCII
+ blank | Space symbols
+ email | Email address
+ entity | XML entity
+ file | File or path name
+ float | Decimal notation
+ host | Host
+ hword | Hyphenated word, all letters
+ hword_asciipart | Hyphenated word part, all ASCII
+ hword_numpart | Hyphenated word part, letters and digits
+ hword_part | Hyphenated word part, all letters
+ int | Signed integer
+ numhword | Hyphenated word, letters and digits
+ numword | Word, letters and digits
+ protocol | Protocol head
+ sfloat | Scientific notation
+ tag | XML tag
+ uint | Unsigned integer
+ url | URL
+ url_path | URL path
+ version | Version number
+ word | Word, all letters
+(23 rows)
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>\dFt<optional>+</optional> <optional>PATTERN</optional></literal></term>
+ <listitem>
+ <para>
+ List text search templates (add <literal>+</literal> for more detail).
+<screen>
+=&gt; \dFt
+ List of text search templates
+ Schema | Name | Description
+------------+-----------+-----------------------------------------------------------
+ pg_catalog | ispell | ispell dictionary
+ pg_catalog | simple | simple dictionary: just lower case and check for stopword
+ pg_catalog | snowball | snowball stemmer
+ pg_catalog | synonym | synonym dictionary: replace word by its synonym
+ pg_catalog | thesaurus | thesaurus dictionary: phrase by phrase substitution
+</screen>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="textsearch-limitations">
+ <title>Limitations</title>
+
+ <para>
+ The current limitations of <productname>PostgreSQL</productname>'s
+ text search features are:
+ <itemizedlist spacing="compact" mark="bullet">
+ <listitem>
+ <para>The length of each lexeme must be less than 2 kilobytes</para>
+ </listitem>
+ <listitem>
+ <para>The length of a <type>tsvector</type> (lexemes + positions) must be
+ less than 1 megabyte</para>
+ </listitem>
+ <listitem>
+ <!-- TODO: number of lexemes in what? This is unclear -->
+ <para>The number of lexemes must be less than
+ 2<superscript>64</superscript></para>
+ </listitem>
+ <listitem>
+ <para>Position values in <type>tsvector</type> must be greater than 0 and
+ no more than 16,383</para>
+ </listitem>
+ <listitem>
+ <para>The match distance in a <literal>&lt;<replaceable>N</replaceable>&gt;</literal>
+ (FOLLOWED BY) <type>tsquery</type> operator cannot be more than
+ 16,384</para>
+ </listitem>
+ <listitem>
+ <para>No more than 256 positions per lexeme</para>
+ </listitem>
+ <listitem>
+ <para>The number of nodes (lexemes + operators) in a <type>tsquery</type>
+ must be less than 32,768</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ For comparison, the <productname>PostgreSQL</productname> 8.1 documentation
+ contained 10,441 unique words, a total of 335,420 words, and the most
+ frequent word <quote>postgresql</quote> was mentioned 6,127 times in 655
+ documents.
+ </para>
+
+ <!-- TODO we need to put a date on these numbers? -->
+ <para>
+ Another example &mdash; the <productname>PostgreSQL</productname> mailing
+ list archives contained 910,989 unique words with 57,491,343 lexemes in
+ 461,020 messages.
+ </para>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml
new file mode 100644
index 0000000..6e1f370
--- /dev/null
+++ b/doc/src/sgml/trigger.sgml
@@ -0,0 +1,1032 @@
+<!-- doc/src/sgml/trigger.sgml -->
+
+ <chapter id="triggers">
+ <title>Triggers</title>
+
+ <indexterm zone="triggers">
+ <primary>trigger</primary>
+ </indexterm>
+
+ <para>
+ This chapter provides general information about writing trigger functions.
+ Trigger functions can be written in most of the available procedural
+ languages, including
+ <application>PL/pgSQL</application> (<xref linkend="plpgsql"/>),
+ <application>PL/Tcl</application> (<xref linkend="pltcl"/>),
+ <application>PL/Perl</application> (<xref linkend="plperl"/>), and
+ <application>PL/Python</application> (<xref linkend="plpython"/>).
+ After reading this chapter, you should consult the chapter for
+ your favorite procedural language to find out the language-specific
+ details of writing a trigger in it.
+ </para>
+
+ <para>
+ It is also possible to write a trigger function in C, although
+ most people find it easier to use one of the procedural languages.
+ It is not currently possible to write a trigger function in the
+ plain SQL function language.
+ </para>
+
+ <sect1 id="trigger-definition">
+ <title>Overview of Trigger Behavior</title>
+
+ <para>
+ A trigger is a specification that the database should automatically
+ execute a particular function whenever a certain type of operation is
+ performed. Triggers can be attached to tables (partitioned or not),
+ views, and foreign tables.
+ </para>
+
+ <para>
+ On tables and foreign tables, triggers can be defined to execute either
+ before or after any <command>INSERT</command>, <command>UPDATE</command>,
+ or <command>DELETE</command> operation, either once per modified row,
+ or once per <acronym>SQL</acronym> statement.
+ <command>UPDATE</command> triggers can moreover be set to fire only if
+ certain columns are mentioned in the <literal>SET</literal> clause of
+ the <command>UPDATE</command> statement. Triggers can also fire
+ for <command>TRUNCATE</command> statements. If a trigger event occurs,
+ the trigger's function is called at the appropriate time to handle the
+ event.
+ </para>
+
+ <para>
+ On views, triggers can be defined to execute instead of
+ <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> operations.
+ Such <literal>INSTEAD OF</literal> triggers
+ are fired once for each row that needs to be modified in the view.
+ It is the responsibility of the
+ trigger's function to perform the necessary modifications to the view's
+ underlying base table(s) and, where appropriate, return the modified
+ row as it will appear in the view. Triggers on views can also be defined
+ to execute once per <acronym>SQL</acronym> statement, before or after
+ <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> operations.
+ However, such triggers are fired only if there is also
+ an <literal>INSTEAD OF</literal> trigger on the view. Otherwise,
+ any statement targeting the view must be rewritten into a statement
+ affecting its underlying base table(s), and then the triggers
+ that will be fired are the ones attached to the base table(s).
+ </para>
+
+ <para>
+ The trigger function must be defined before the trigger itself can be
+ created. The trigger function must be declared as a
+ function taking no arguments and returning type <literal>trigger</literal>.
+ (The trigger function receives its input through a specially-passed
+ <structname>TriggerData</structname> structure, not in the form of ordinary function
+ arguments.)
+ </para>
+
+ <para>
+ Once a suitable trigger function has been created, the trigger is
+ established with
+ <xref linkend="sql-createtrigger"/>.
+ The same trigger function can be used for multiple triggers.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> offers both <firstterm>per-row</firstterm>
+ triggers and <firstterm>per-statement</firstterm> triggers. With a per-row
+ trigger, the trigger function
+ is invoked once for each row that is affected by the statement
+ that fired the trigger. In contrast, a per-statement trigger is
+ invoked only once when an appropriate statement is executed,
+ regardless of the number of rows affected by that statement. In
+ particular, a statement that affects zero rows will still result
+ in the execution of any applicable per-statement triggers. These
+ two types of triggers are sometimes called <firstterm>row-level</firstterm>
+ triggers and <firstterm>statement-level</firstterm> triggers,
+ respectively. Triggers on <command>TRUNCATE</command> may only be
+ defined at statement level, not per-row.
+ </para>
+
+ <para>
+ Triggers are also classified according to whether they fire
+ <firstterm>before</firstterm>, <firstterm>after</firstterm>, or
+ <firstterm>instead of</firstterm> the operation. These are referred to
+ as <literal>BEFORE</literal> triggers, <literal>AFTER</literal> triggers, and
+ <literal>INSTEAD OF</literal> triggers respectively.
+ Statement-level <literal>BEFORE</literal> triggers naturally fire before the
+ statement starts to do anything, while statement-level <literal>AFTER</literal>
+ triggers fire at the very end of the statement. These types of
+ triggers may be defined on tables, views, or foreign tables. Row-level
+ <literal>BEFORE</literal> triggers fire immediately before a particular row is
+ operated on, while row-level <literal>AFTER</literal> triggers fire at the end of
+ the statement (but before any statement-level <literal>AFTER</literal> triggers).
+ These types of triggers may only be defined on tables and
+ foreign tables, not views.
+ <literal>INSTEAD OF</literal> triggers may only be
+ defined on views, and only at row level; they fire immediately as each
+ row in the view is identified as needing to be operated on.
+ </para>
+
+ <para>
+ The execution of an <literal>AFTER</literal> trigger can be deferred
+ to the end of the transaction, rather than the end of the statement,
+ if it was defined as a <firstterm>constraint trigger</firstterm>.
+ In all cases, a trigger is executed as part of the same transaction as
+ the statement that triggered it, so if either the statement or the
+ trigger causes an error, the effects of both will be rolled back.
+ </para>
+
+ <para>
+ A statement that targets a parent table in an inheritance or partitioning
+ hierarchy does not cause the statement-level triggers of affected child
+ tables to be fired; only the parent table's statement-level triggers are
+ fired. However, row-level triggers of any affected child tables will be
+ fired.
+ </para>
+
+ <para>
+ If an <command>INSERT</command> contains an <literal>ON CONFLICT
+ DO UPDATE</literal> clause, it is possible that the effects of
+ row-level <literal>BEFORE</literal> <command>INSERT</command> triggers and
+ row-level <literal>BEFORE</literal> <command>UPDATE</command> triggers can
+ both be applied in a way that is apparent from the final state of
+ the updated row, if an <varname>EXCLUDED</varname> column is referenced.
+ There need not be an <varname>EXCLUDED</varname> column reference for
+ both sets of row-level <literal>BEFORE</literal> triggers to execute,
+ though. The
+ possibility of surprising outcomes should be considered when there
+ are both <literal>BEFORE</literal> <command>INSERT</command> and
+ <literal>BEFORE</literal> <command>UPDATE</command> row-level triggers
+ that change a row being inserted/updated (this can be
+ problematic even if the modifications are more or less equivalent, if
+ they're not also idempotent). Note that statement-level
+ <command>UPDATE</command> triggers are executed when <literal>ON
+ CONFLICT DO UPDATE</literal> is specified, regardless of whether or not
+ any rows were affected by the <command>UPDATE</command> (and
+ regardless of whether the alternative <command>UPDATE</command>
+ path was ever taken). An <command>INSERT</command> with an
+ <literal>ON CONFLICT DO UPDATE</literal> clause will execute
+ statement-level <literal>BEFORE</literal> <command>INSERT</command>
+ triggers first, then statement-level <literal>BEFORE</literal>
+ <command>UPDATE</command> triggers, followed by statement-level
+ <literal>AFTER</literal> <command>UPDATE</command> triggers and finally
+ statement-level <literal>AFTER</literal> <command>INSERT</command>
+ triggers.
+ </para>
+
+ <para>
+ If an <command>UPDATE</command> on a partitioned table causes a row to move
+ to another partition, it will be performed as a <command>DELETE</command>
+ from the original partition followed by an <command>INSERT</command> into
+ the new partition. In this case, all row-level <literal>BEFORE</literal>
+ <command>UPDATE</command> triggers and all row-level
+ <literal>BEFORE</literal> <command>DELETE</command> triggers are fired on
+ the original partition. Then all row-level <literal>BEFORE</literal>
+ <command>INSERT</command> triggers are fired on the destination partition.
+ The possibility of surprising outcomes should be considered when all these
+ triggers affect the row being moved. As far as <literal>AFTER ROW</literal>
+ triggers are concerned, <literal>AFTER</literal> <command>DELETE</command>
+ and <literal>AFTER</literal> <command>INSERT</command> triggers are
+ applied; but <literal>AFTER</literal> <command>UPDATE</command> triggers
+ are not applied because the <command>UPDATE</command> has been converted to
+ a <command>DELETE</command> and an <command>INSERT</command>. As far as
+ statement-level triggers are concerned, none of the
+ <command>DELETE</command> or <command>INSERT</command> triggers are fired,
+ even if row movement occurs; only the <command>UPDATE</command> triggers
+ defined on the target table used in the <command>UPDATE</command> statement
+ will be fired.
+ </para>
+
+ <para>
+ No separate triggers are defined for <command>MERGE</command>. Instead,
+ statement-level or row-level <command>UPDATE</command>,
+ <command>DELETE</command>, and <command>INSERT</command> triggers are fired
+ depending on (for statement-level triggers) what actions are specified in
+ the <command>MERGE</command> query and (for row-level triggers) what
+ actions are performed.
+ </para>
+
+ <para>
+ While running a <command>MERGE</command> command, statement-level
+ <literal>BEFORE</literal> and <literal>AFTER</literal> triggers are
+ fired for events specified in the actions of the <command>MERGE</command>
+ command, irrespective of whether or not the action is ultimately performed.
+ This is the same as an <command>UPDATE</command> statement that updates
+ no rows, yet statement-level triggers are fired.
+ The row-level triggers are fired only when a row is actually updated,
+ inserted or deleted. So it's perfectly legal that while statement-level
+ triggers are fired for certain types of action, no row-level triggers
+ are fired for the same kind of action.
+ </para>
+
+ <para>
+ Trigger functions invoked by per-statement triggers should always
+ return <symbol>NULL</symbol>. Trigger functions invoked by per-row
+ triggers can return a table row (a value of
+ type <structname>HeapTuple</structname>) to the calling executor,
+ if they choose. A row-level trigger fired before an operation has
+ the following choices:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ It can return <symbol>NULL</symbol> to skip the operation for the
+ current row. This instructs the executor to not perform the
+ row-level operation that invoked the trigger (the insertion,
+ modification, or deletion of a particular table row).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ For row-level <command>INSERT</command>
+ and <command>UPDATE</command> triggers only, the returned row
+ becomes the row that will be inserted or will replace the row
+ being updated. This allows the trigger function to modify the
+ row being inserted or updated.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ A row-level <literal>BEFORE</literal> trigger that does not intend to cause
+ either of these behaviors must be careful to return as its result the same
+ row that was passed in (that is, the <varname>NEW</varname> row
+ for <command>INSERT</command> and <command>UPDATE</command>
+ triggers, the <varname>OLD</varname> row for
+ <command>DELETE</command> triggers).
+ </para>
+
+ <para>
+ A row-level <literal>INSTEAD OF</literal> trigger should either return
+ <symbol>NULL</symbol> to indicate that it did not modify any data from
+ the view's underlying base tables, or it should return the view
+ row that was passed in (the <varname>NEW</varname> row
+ for <command>INSERT</command> and <command>UPDATE</command>
+ operations, or the <varname>OLD</varname> row for
+ <command>DELETE</command> operations). A nonnull return value is
+ used to signal that the trigger performed the necessary data
+ modifications in the view. This will cause the count of the number
+ of rows affected by the command to be incremented. For
+ <command>INSERT</command> and <command>UPDATE</command> operations only, the trigger
+ may modify the <varname>NEW</varname> row before returning it. This will
+ change the data returned by
+ <command>INSERT RETURNING</command> or <command>UPDATE RETURNING</command>,
+ and is useful when the view will not show exactly the same data
+ that was provided.
+ </para>
+
+ <para>
+ The return value is ignored for row-level triggers fired after an
+ operation, and so they can return <symbol>NULL</symbol>.
+ </para>
+
+ <para>
+ Some considerations apply for generated
+ columns.<indexterm><primary>generated column</primary><secondary>in
+ triggers</secondary></indexterm> Stored generated columns are computed after
+ <literal>BEFORE</literal> triggers and before <literal>AFTER</literal>
+ triggers. Therefore, the generated value can be inspected in
+ <literal>AFTER</literal> triggers. In <literal>BEFORE</literal> triggers,
+ the <literal>OLD</literal> row contains the old generated value, as one
+ would expect, but the <literal>NEW</literal> row does not yet contain the
+ new generated value and should not be accessed. In the C language
+ interface, the content of the column is undefined at this point; a
+ higher-level programming language should prevent access to a stored
+ generated column in the <literal>NEW</literal> row in a
+ <literal>BEFORE</literal> trigger. Changes to the value of a generated
+ column in a <literal>BEFORE</literal> trigger are ignored and will be
+ overwritten.
+ </para>
+
+ <para>
+ If more than one trigger is defined for the same event on the same
+ relation, the triggers will be fired in alphabetical order by
+ trigger name. In the case of <literal>BEFORE</literal> and
+ <literal>INSTEAD OF</literal> triggers, the possibly-modified row returned by
+ each trigger becomes the input to the next trigger. If any
+ <literal>BEFORE</literal> or <literal>INSTEAD OF</literal> trigger returns
+ <symbol>NULL</symbol>, the operation is abandoned for that row and subsequent
+ triggers are not fired (for that row).
+ </para>
+
+ <para>
+ A trigger definition can also specify a Boolean <literal>WHEN</literal>
+ condition, which will be tested to see whether the trigger should
+ be fired. In row-level triggers the <literal>WHEN</literal> condition can
+ examine the old and/or new values of columns of the row. (Statement-level
+ triggers can also have <literal>WHEN</literal> conditions, although the feature
+ is not so useful for them.) In a <literal>BEFORE</literal> trigger, the
+ <literal>WHEN</literal>
+ condition is evaluated just before the function is or would be executed,
+ so using <literal>WHEN</literal> is not materially different from testing the
+ same condition at the beginning of the trigger function. However, in
+ an <literal>AFTER</literal> trigger, the <literal>WHEN</literal> condition is evaluated
+ just after the row update occurs, and it determines whether an event is
+ queued to fire the trigger at the end of statement. So when an
+ <literal>AFTER</literal> trigger's
+ <literal>WHEN</literal> condition does not return true, it is not necessary
+ to queue an event nor to re-fetch the row at end of statement. This
+ can result in significant speedups in statements that modify many
+ rows, if the trigger only needs to be fired for a few of the rows.
+ <literal>INSTEAD OF</literal> triggers do not support
+ <literal>WHEN</literal> conditions.
+ </para>
+
+ <para>
+ Typically, row-level <literal>BEFORE</literal> triggers are used for checking or
+ modifying the data that will be inserted or updated. For example,
+ a <literal>BEFORE</literal> trigger might be used to insert the current time into a
+ <type>timestamp</type> column, or to check that two elements of the row are
+ consistent. Row-level <literal>AFTER</literal> triggers are most sensibly
+ used to propagate the updates to other tables, or make consistency
+ checks against other tables. The reason for this division of labor is
+ that an <literal>AFTER</literal> trigger can be certain it is seeing the final
+ value of the row, while a <literal>BEFORE</literal> trigger cannot; there might
+ be other <literal>BEFORE</literal> triggers firing after it. If you have no
+ specific reason to make a trigger <literal>BEFORE</literal> or
+ <literal>AFTER</literal>, the <literal>BEFORE</literal> case is more efficient, since
+ the information about
+ the operation doesn't have to be saved until end of statement.
+ </para>
+
+ <para>
+ If a trigger function executes SQL commands then these
+ commands might fire triggers again. This is known as cascading
+ triggers. There is no direct limitation on the number of cascade
+ levels. It is possible for cascades to cause a recursive invocation
+ of the same trigger; for example, an <command>INSERT</command>
+ trigger might execute a command that inserts an additional row
+ into the same table, causing the <command>INSERT</command> trigger
+ to be fired again. It is the trigger programmer's responsibility
+ to avoid infinite recursion in such scenarios.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>trigger</primary>
+ <secondary>arguments for trigger functions</secondary>
+ </indexterm>
+ When a trigger is being defined, arguments can be specified for
+ it. The purpose of including arguments in the
+ trigger definition is to allow different triggers with similar
+ requirements to call the same function. As an example, there
+ could be a generalized trigger function that takes as its
+ arguments two column names and puts the current user in one and
+ the current time stamp in the other. Properly written, this
+ trigger function would be independent of the specific table it is
+ triggering on. So the same function could be used for
+ <command>INSERT</command> events on any table with suitable
+ columns, to automatically track creation of records in a
+ transaction table for example. It could also be used to track
+ last-update events if defined as an <command>UPDATE</command>
+ trigger.
+ </para>
+
+ <para>
+ Each programming language that supports triggers has its own method
+ for making the trigger input data available to the trigger function.
+ This input data includes the type of trigger event (e.g.,
+ <command>INSERT</command> or <command>UPDATE</command>) as well as any
+ arguments that were listed in <command>CREATE TRIGGER</command>.
+ For a row-level trigger, the input data also includes the
+ <varname>NEW</varname> row for <command>INSERT</command> and
+ <command>UPDATE</command> triggers, and/or the <varname>OLD</varname> row
+ for <command>UPDATE</command> and <command>DELETE</command> triggers.
+ </para>
+
+ <para>
+ By default, statement-level triggers do not have any way to examine the
+ individual row(s) modified by the statement. But an <literal>AFTER
+ STATEMENT</literal> trigger can request that <firstterm>transition tables</firstterm>
+ be created to make the sets of affected rows available to the trigger.
+ <literal>AFTER ROW</literal> triggers can also request transition tables, so
+ that they can see the total changes in the table as well as the change in
+ the individual row they are currently being fired for. The method for
+ examining the transition tables again depends on the programming language
+ that is being used, but the typical approach is to make the transition
+ tables act like read-only temporary tables that can be accessed by SQL
+ commands issued within the trigger function.
+ </para>
+
+ </sect1>
+
+ <sect1 id="trigger-datachanges">
+ <title>Visibility of Data Changes</title>
+
+ <para>
+ If you execute SQL commands in your trigger function, and these
+ commands access the table that the trigger is for, then
+ you need to be aware of the data visibility rules, because they determine
+ whether these SQL commands will see the data change that the trigger
+ is fired for. Briefly:
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Statement-level triggers follow simple visibility rules: none of
+ the changes made by a statement are visible to statement-level
+ <literal>BEFORE</literal> triggers, whereas all
+ modifications are visible to statement-level <literal>AFTER</literal>
+ triggers.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The data change (insertion, update, or deletion) causing the
+ trigger to fire is naturally <emphasis>not</emphasis> visible
+ to SQL commands executed in a row-level <literal>BEFORE</literal> trigger,
+ because it hasn't happened yet.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ However, SQL commands executed in a row-level <literal>BEFORE</literal>
+ trigger <emphasis>will</emphasis> see the effects of data
+ changes for rows previously processed in the same outer
+ command. This requires caution, since the ordering of these
+ change events is not in general predictable; an SQL command that
+ affects multiple rows can visit the rows in any order.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Similarly, a row-level <literal>INSTEAD OF</literal> trigger will see the
+ effects of data changes made by previous firings of <literal>INSTEAD
+ OF</literal> triggers in the same outer command.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When a row-level <literal>AFTER</literal> trigger is fired, all data
+ changes made
+ by the outer command are already complete, and are visible to
+ the invoked trigger function.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ If your trigger function is written in any of the standard procedural
+ languages, then the above statements apply only if the function is
+ declared <literal>VOLATILE</literal>. Functions that are declared
+ <literal>STABLE</literal> or <literal>IMMUTABLE</literal> will not see changes made by
+ the calling command in any case.
+ </para>
+
+ <para>
+ Further information about data visibility rules can be found in
+ <xref linkend="spi-visibility"/>. The example in <xref
+ linkend="trigger-example"/> contains a demonstration of these rules.
+ </para>
+ </sect1>
+
+ <sect1 id="trigger-interface">
+ <title>Writing Trigger Functions in C</title>
+
+ <indexterm zone="trigger-interface">
+ <primary>trigger</primary>
+ <secondary>in C</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>transition tables</primary>
+ <secondary>referencing from C trigger</secondary>
+ </indexterm>
+
+ <para>
+ This section describes the low-level details of the interface to a
+ trigger function. This information is only needed when writing
+ trigger functions in C. If you are using a higher-level language then
+ these details are handled for you. In most cases you should consider
+ using a procedural language before writing your triggers in C. The
+ documentation of each procedural language explains how to write a
+ trigger in that language.
+ </para>
+
+ <para>
+ Trigger functions must use the <quote>version 1</quote> function manager
+ interface.
+ </para>
+
+ <para>
+ When a function is called by the trigger manager, it is not passed
+ any normal arguments, but it is passed a <quote>context</quote>
+ pointer pointing to a <structname>TriggerData</structname> structure. C
+ functions can check whether they were called from the trigger
+ manager or not by executing the macro:
+<programlisting>
+CALLED_AS_TRIGGER(fcinfo)
+</programlisting>
+ which expands to:
+<programlisting>
+((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, TriggerData))
+</programlisting>
+ If this returns true, then it is safe to cast
+ <literal>fcinfo-&gt;context</literal> to type <literal>TriggerData
+ *</literal> and make use of the pointed-to
+ <structname>TriggerData</structname> structure. The function must
+ <emphasis>not</emphasis> alter the <structname>TriggerData</structname>
+ structure or any of the data it points to.
+ </para>
+
+ <para>
+ <structname>struct TriggerData</structname> is defined in
+ <filename>commands/trigger.h</filename>:
+
+<programlisting>
+typedef struct TriggerData
+{
+ NodeTag type;
+ TriggerEvent tg_event;
+ Relation tg_relation;
+ HeapTuple tg_trigtuple;
+ HeapTuple tg_newtuple;
+ Trigger *tg_trigger;
+ TupleTableSlot *tg_trigslot;
+ TupleTableSlot *tg_newslot;
+ Tuplestorestate *tg_oldtable;
+ Tuplestorestate *tg_newtable;
+ const Bitmapset *tg_updatedcols;
+} TriggerData;
+</programlisting>
+
+ where the members are defined as follows:
+
+ <variablelist>
+ <varlistentry>
+ <term><structfield>type</structfield></term>
+ <listitem>
+ <para>
+ Always <literal>T_TriggerData</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_event</structfield></term>
+ <listitem>
+ <para>
+ Describes the event for which the function is called. You can use the
+ following macros to examine <literal>tg_event</literal>:
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_BEFORE(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger fired before the operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_AFTER(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger fired after the operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_INSTEAD(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger fired instead of the operation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_FOR_ROW(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger fired for a row-level event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_FOR_STATEMENT(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger fired for a statement-level event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_BY_INSERT(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger was fired by an <command>INSERT</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_BY_UPDATE(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger was fired by an <command>UPDATE</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_BY_DELETE(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger was fired by a <command>DELETE</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>TRIGGER_FIRED_BY_TRUNCATE(tg_event)</literal></term>
+ <listitem>
+ <para>
+ Returns true if the trigger was fired by a <command>TRUNCATE</command> command.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_relation</structfield></term>
+ <listitem>
+ <para>
+ A pointer to a structure describing the relation that the trigger fired for.
+ Look at <filename>utils/rel.h</filename> for details about
+ this structure. The most interesting things are
+ <literal>tg_relation-&gt;rd_att</literal> (descriptor of the relation
+ tuples) and <literal>tg_relation-&gt;rd_rel-&gt;relname</literal>
+ (relation name; the type is not <type>char*</type> but
+ <type>NameData</type>; use
+ <literal>SPI_getrelname(tg_relation)</literal> to get a <type>char*</type> if you
+ need a copy of the name).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_trigtuple</structfield></term>
+ <listitem>
+ <para>
+ A pointer to the row for which the trigger was fired. This is
+ the row being inserted, updated, or deleted. If this trigger
+ was fired for an <command>INSERT</command> or
+ <command>DELETE</command> then this is what you should return
+ from the function if you don't want to replace the row with
+ a different one (in the case of <command>INSERT</command>) or
+ skip the operation. For triggers on foreign tables, values of system
+ columns herein are unspecified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_newtuple</structfield></term>
+ <listitem>
+ <para>
+ A pointer to the new version of the row, if the trigger was
+ fired for an <command>UPDATE</command>, and <symbol>NULL</symbol> if
+ it is for an <command>INSERT</command> or a
+ <command>DELETE</command>. This is what you have to return
+ from the function if the event is an <command>UPDATE</command>
+ and you don't want to replace this row by a different one or
+ skip the operation. For triggers on foreign tables, values of system
+ columns herein are unspecified.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_trigger</structfield></term>
+ <listitem>
+ <para>
+ A pointer to a structure of type <structname>Trigger</structname>,
+ defined in <filename>utils/reltrigger.h</filename>:
+
+<programlisting>
+typedef struct Trigger
+{
+ Oid tgoid;
+ char *tgname;
+ Oid tgfoid;
+ int16 tgtype;
+ char tgenabled;
+ bool tgisinternal;
+ bool tgisclone;
+ Oid tgconstrrelid;
+ Oid tgconstrindid;
+ Oid tgconstraint;
+ bool tgdeferrable;
+ bool tginitdeferred;
+ int16 tgnargs;
+ int16 tgnattr;
+ int16 *tgattr;
+ char **tgargs;
+ char *tgqual;
+ char *tgoldtable;
+ char *tgnewtable;
+} Trigger;
+</programlisting>
+
+ where <structfield>tgname</structfield> is the trigger's name,
+ <structfield>tgnargs</structfield> is the number of arguments in
+ <structfield>tgargs</structfield>, and <structfield>tgargs</structfield> is an array of
+ pointers to the arguments specified in the <command>CREATE
+ TRIGGER</command> statement. The other members are for internal use
+ only.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_trigslot</structfield></term>
+ <listitem>
+ <para>
+ The slot containing <structfield>tg_trigtuple</structfield>,
+ or a <symbol>NULL</symbol> pointer if there is no such tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_newslot</structfield></term>
+ <listitem>
+ <para>
+ The slot containing <structfield>tg_newtuple</structfield>,
+ or a <symbol>NULL</symbol> pointer if there is no such tuple.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_oldtable</structfield></term>
+ <listitem>
+ <para>
+ A pointer to a structure of type <structname>Tuplestorestate</structname>
+ containing zero or more rows in the format specified by
+ <structfield>tg_relation</structfield>, or a <symbol>NULL</symbol> pointer
+ if there is no <literal>OLD TABLE</literal> transition relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_newtable</structfield></term>
+ <listitem>
+ <para>
+ A pointer to a structure of type <structname>Tuplestorestate</structname>
+ containing zero or more rows in the format specified by
+ <structfield>tg_relation</structfield>, or a <symbol>NULL</symbol> pointer
+ if there is no <literal>NEW TABLE</literal> transition relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_updatedcols</structfield></term>
+ <listitem>
+ <para>
+ For <literal>UPDATE</literal> triggers, a bitmap set indicating the
+ columns that were updated by the triggering command. Generic trigger
+ functions can use this to optimize actions by not having to deal with
+ columns that were not changed.
+ </para>
+
+ <para>
+ As an example, to determine whether a column with attribute number
+ <varname>attnum</varname> (1-based) is a member of this bitmap set,
+ call <literal>bms_is_member(attnum -
+ FirstLowInvalidHeapAttributeNumber,
+ trigdata->tg_updatedcols))</literal>.
+ </para>
+
+ <para>
+ For triggers other than <literal>UPDATE</literal> triggers, this will
+ be <symbol>NULL</symbol>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ To allow queries issued through SPI to reference transition tables, see
+ <xref linkend="spi-spi-register-trigger-data"/>.
+ </para>
+
+ <para>
+ A trigger function must return either a
+ <structname>HeapTuple</structname> pointer or a <symbol>NULL</symbol> pointer
+ (<emphasis>not</emphasis> an SQL null value, that is, do not set <parameter>isNull</parameter> true).
+ Be careful to return either
+ <structfield>tg_trigtuple</structfield> or <structfield>tg_newtuple</structfield>,
+ as appropriate, if you don't want to modify the row being operated on.
+ </para>
+ </sect1>
+
+ <sect1 id="trigger-example">
+ <title>A Complete Trigger Example</title>
+
+ <para>
+ Here is a very simple example of a trigger function written in C.
+ (Examples of triggers written in procedural languages can be found
+ in the documentation of the procedural languages.)
+ </para>
+
+ <para>
+ The function <function>trigf</function> reports the number of rows in the
+ table <structname>ttest</structname> and skips the actual operation if the
+ command attempts to insert a null value into the column
+ <structfield>x</structfield>. (So the trigger acts as a not-null constraint but
+ doesn't abort the transaction.)
+ </para>
+
+ <para>
+ First, the table definition:
+<programlisting>
+CREATE TABLE ttest (
+ x integer
+);
+</programlisting>
+ </para>
+
+ <para>
+ This is the source code of the trigger function:
+<programlisting><![CDATA[
+#include "postgres.h"
+#include "fmgr.h"
+#include "executor/spi.h" /* this is what you need to work with SPI */
+#include "commands/trigger.h" /* ... triggers ... */
+#include "utils/rel.h" /* ... and relations */
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(trigf);
+
+Datum
+trigf(PG_FUNCTION_ARGS)
+{
+ TriggerData *trigdata = (TriggerData *) fcinfo->context;
+ TupleDesc tupdesc;
+ HeapTuple rettuple;
+ char *when;
+ bool checknull = false;
+ bool isnull;
+ int ret, i;
+
+ /* make sure it's called as a trigger at all */
+ if (!CALLED_AS_TRIGGER(fcinfo))
+ elog(ERROR, "trigf: not called by trigger manager");
+
+ /* tuple to return to executor */
+ if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ rettuple = trigdata->tg_newtuple;
+ else
+ rettuple = trigdata->tg_trigtuple;
+
+ /* check for null values */
+ if (!TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)
+ && TRIGGER_FIRED_BEFORE(trigdata->tg_event))
+ checknull = true;
+
+ if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
+ when = "before";
+ else
+ when = "after ";
+
+ tupdesc = trigdata->tg_relation->rd_att;
+
+ /* connect to SPI manager */
+ if ((ret = SPI_connect()) < 0)
+ elog(ERROR, "trigf (fired %s): SPI_connect returned %d", when, ret);
+
+ /* get number of rows in table */
+ ret = SPI_exec("SELECT count(*) FROM ttest", 0);
+
+ if (ret < 0)
+ elog(ERROR, "trigf (fired %s): SPI_exec returned %d", when, ret);
+
+ /* count(*) returns int8, so be careful to convert */
+ i = DatumGetInt64(SPI_getbinval(SPI_tuptable->vals[0],
+ SPI_tuptable->tupdesc,
+ 1,
+ &isnull));
+
+ elog (INFO, "trigf (fired %s): there are %d rows in ttest", when, i);
+
+ SPI_finish();
+
+ if (checknull)
+ {
+ SPI_getbinval(rettuple, tupdesc, 1, &isnull);
+ if (isnull)
+ rettuple = NULL;
+ }
+
+ return PointerGetDatum(rettuple);
+}
+]]>
+</programlisting>
+ </para>
+
+ <para>
+ After you have compiled the source code (see <xref
+ linkend="dfunc"/>), declare the function and the triggers:
+<programlisting>
+CREATE FUNCTION trigf() RETURNS trigger
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C;
+
+CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest
+ FOR EACH ROW EXECUTE FUNCTION trigf();
+
+CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest
+ FOR EACH ROW EXECUTE FUNCTION trigf();
+</programlisting>
+ </para>
+
+ <para>
+ Now you can test the operation of the trigger:
+<screen>
+=&gt; INSERT INTO ttest VALUES (NULL);
+INFO: trigf (fired before): there are 0 rows in ttest
+INSERT 0 0
+
+-- Insertion skipped and AFTER trigger is not fired
+
+=&gt; SELECT * FROM ttest;
+ x
+---
+(0 rows)
+
+=&gt; INSERT INTO ttest VALUES (1);
+INFO: trigf (fired before): there are 0 rows in ttest
+INFO: trigf (fired after ): there are 1 rows in ttest
+ ^^^^^^^^
+ remember what we said about visibility.
+INSERT 167793 1
+vac=&gt; SELECT * FROM ttest;
+ x
+---
+ 1
+(1 row)
+
+=&gt; INSERT INTO ttest SELECT x * 2 FROM ttest;
+INFO: trigf (fired before): there are 1 rows in ttest
+INFO: trigf (fired after ): there are 2 rows in ttest
+ ^^^^^^
+ remember what we said about visibility.
+INSERT 167794 1
+=&gt; SELECT * FROM ttest;
+ x
+---
+ 1
+ 2
+(2 rows)
+
+=&gt; UPDATE ttest SET x = NULL WHERE x = 2;
+INFO: trigf (fired before): there are 2 rows in ttest
+UPDATE 0
+=&gt; UPDATE ttest SET x = 4 WHERE x = 2;
+INFO: trigf (fired before): there are 2 rows in ttest
+INFO: trigf (fired after ): there are 2 rows in ttest
+UPDATE 1
+vac=&gt; SELECT * FROM ttest;
+ x
+---
+ 1
+ 4
+(2 rows)
+
+=&gt; DELETE FROM ttest;
+INFO: trigf (fired before): there are 2 rows in ttest
+INFO: trigf (fired before): there are 1 rows in ttest
+INFO: trigf (fired after ): there are 0 rows in ttest
+INFO: trigf (fired after ): there are 0 rows in ttest
+ ^^^^^^
+ remember what we said about visibility.
+DELETE 2
+=&gt; SELECT * FROM ttest;
+ x
+---
+(0 rows)
+</screen>
+
+ </para>
+
+ <para>
+ There are more complex examples in
+ <filename>src/test/regress/regress.c</filename> and
+ in <xref linkend="contrib-spi"/>.
+ </para>
+ </sect1>
+ </chapter>
diff --git a/doc/src/sgml/tsm-system-rows.sgml b/doc/src/sgml/tsm-system-rows.sgml
new file mode 100644
index 0000000..d960aa3
--- /dev/null
+++ b/doc/src/sgml/tsm-system-rows.sgml
@@ -0,0 +1,69 @@
+<!-- doc/src/sgml/tsm-system-rows.sgml -->
+
+<sect1 id="tsm-system-rows" xreflabel="tsm_system_rows">
+ <title>tsm_system_rows</title>
+
+ <indexterm zone="tsm-system-rows">
+ <primary>tsm_system_rows</primary>
+ </indexterm>
+
+ <para>
+ The <filename>tsm_system_rows</filename> module provides the table sampling method
+ <literal>SYSTEM_ROWS</literal>, which can be used in
+ the <literal>TABLESAMPLE</literal> clause of a <link linkend="sql-select"><command>SELECT</command></link>
+ command.
+ </para>
+
+ <para>
+ This table sampling method accepts a single integer argument that is the
+ maximum number of rows to read. The resulting sample will always contain
+ exactly that many rows, unless the table does not contain enough rows, in
+ which case the whole table is selected.
+ </para>
+
+ <para>
+ Like the built-in <literal>SYSTEM</literal> sampling
+ method, <literal>SYSTEM_ROWS</literal> performs block-level sampling, so
+ that the sample is not completely random but may be subject to clustering
+ effects, especially if only a small number of rows are requested.
+ </para>
+
+ <para>
+ <literal>SYSTEM_ROWS</literal> does not support
+ the <literal>REPEATABLE</literal> clause.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>
+ Here is an example of selecting a sample of a table with
+ <literal>SYSTEM_ROWS</literal>. First install the extension:
+ </para>
+
+<programlisting>
+CREATE EXTENSION tsm_system_rows;
+</programlisting>
+
+ <para>
+ Then you can use it in a <command>SELECT</command> command, for instance:
+
+<programlisting>
+SELECT * FROM my_table TABLESAMPLE SYSTEM_ROWS(100);
+</programlisting>
+ </para>
+
+ <para>
+ This command will return a sample of 100 rows from the
+ table <structname>my_table</structname> (unless the table does not have 100
+ visible rows, in which case all its rows are returned).
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/tsm-system-time.sgml b/doc/src/sgml/tsm-system-time.sgml
new file mode 100644
index 0000000..df6e83a
--- /dev/null
+++ b/doc/src/sgml/tsm-system-time.sgml
@@ -0,0 +1,71 @@
+<!-- doc/src/sgml/tsm-system-time.sgml -->
+
+<sect1 id="tsm-system-time" xreflabel="tsm_system_time">
+ <title>tsm_system_time</title>
+
+ <indexterm zone="tsm-system-time">
+ <primary>tsm_system_time</primary>
+ </indexterm>
+
+ <para>
+ The <filename>tsm_system_time</filename> module provides the table sampling method
+ <literal>SYSTEM_TIME</literal>, which can be used in
+ the <literal>TABLESAMPLE</literal> clause of a <link linkend="sql-select"><command>SELECT</command></link>
+ command.
+ </para>
+
+ <para>
+ This table sampling method accepts a single floating-point argument that
+ is the maximum number of milliseconds to spend reading the table. This
+ gives you direct control over how long the query takes, at the price that
+ the size of the sample becomes hard to predict. The resulting sample will
+ contain as many rows as could be read in the specified time, unless the
+ whole table has been read first.
+ </para>
+
+ <para>
+ Like the built-in <literal>SYSTEM</literal> sampling
+ method, <literal>SYSTEM_TIME</literal> performs block-level sampling, so
+ that the sample is not completely random but may be subject to clustering
+ effects, especially if only a small number of rows are selected.
+ </para>
+
+ <para>
+ <literal>SYSTEM_TIME</literal> does not support
+ the <literal>REPEATABLE</literal> clause.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Examples</title>
+
+ <para>
+ Here is an example of selecting a sample of a table with
+ <literal>SYSTEM_TIME</literal>. First install the extension:
+ </para>
+
+<programlisting>
+CREATE EXTENSION tsm_system_time;
+</programlisting>
+
+ <para>
+ Then you can use it in a <command>SELECT</command> command, for instance:
+
+<programlisting>
+SELECT * FROM my_table TABLESAMPLE SYSTEM_TIME(1000);
+</programlisting>
+ </para>
+
+ <para>
+ This command will return as large a sample of <structname>my_table</structname> as
+ it can read in 1 second (1000 milliseconds). Of course, if the whole
+ table can be read in under 1 second, all its rows will be returned.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml
new file mode 100644
index 0000000..2874874
--- /dev/null
+++ b/doc/src/sgml/typeconv.sgml
@@ -0,0 +1,1262 @@
+<!-- doc/src/sgml/typeconv.sgml -->
+
+<chapter id="typeconv">
+<title>Type Conversion</title>
+
+<indexterm zone="typeconv">
+ <primary>data type</primary>
+ <secondary>conversion</secondary>
+</indexterm>
+
+<para>
+<acronym>SQL</acronym> statements can, intentionally or not, require
+the mixing of different data types in the same expression.
+<productname>PostgreSQL</productname> has extensive facilities for
+evaluating mixed-type expressions.
+</para>
+
+<para>
+In many cases a user does not need
+to understand the details of the type conversion mechanism.
+However, implicit conversions done by <productname>PostgreSQL</productname>
+can affect the results of a query. When necessary, these results
+can be tailored by using <emphasis>explicit</emphasis> type conversion.
+</para>
+
+<para>
+This chapter introduces the <productname>PostgreSQL</productname>
+type conversion mechanisms and conventions.
+Refer to the relevant sections in <xref linkend="datatype"/> and <xref linkend="functions"/>
+for more information on specific data types and allowed functions and
+operators.
+</para>
+
+<sect1 id="typeconv-overview">
+<title>Overview</title>
+
+<para>
+<acronym>SQL</acronym> is a strongly typed language. That is, every data item
+has an associated data type which determines its behavior and allowed usage.
+<productname>PostgreSQL</productname> has an extensible type system that is
+more general and flexible than other <acronym>SQL</acronym> implementations.
+Hence, most type conversion behavior in <productname>PostgreSQL</productname>
+is governed by general rules rather than by ad hoc
+heuristics. This allows the use of mixed-type expressions even with
+user-defined types.
+</para>
+
+<para>
+The <productname>PostgreSQL</productname> scanner/parser divides lexical
+elements into five fundamental categories: integers, non-integer numbers,
+strings, identifiers, and key words. Constants of most non-numeric types are
+first classified as strings. The <acronym>SQL</acronym> language definition
+allows specifying type names with strings, and this mechanism can be used in
+<productname>PostgreSQL</productname> to start the parser down the correct
+path. For example, the query:
+
+<screen>
+SELECT text 'Origin' AS "label", point '(0,0)' AS "value";
+
+ label | value
+--------+-------
+ Origin | (0,0)
+(1 row)
+</screen>
+
+has two literal constants, of type <type>text</type> and <type>point</type>.
+If a type is not specified for a string literal, then the placeholder type
+<type>unknown</type> is assigned initially, to be resolved in later
+stages as described below.
+</para>
+
+<para>
+There are four fundamental <acronym>SQL</acronym> constructs requiring
+distinct type conversion rules in the <productname>PostgreSQL</productname>
+parser:
+
+<variablelist>
+<varlistentry>
+<term>
+Function calls
+</term>
+<listitem>
+<para>
+Much of the <productname>PostgreSQL</productname> type system is built around a
+rich set of functions. Functions can have one or more arguments.
+Since <productname>PostgreSQL</productname> permits function
+overloading, the function name alone does not uniquely identify the function
+to be called; the parser must select the right function based on the data
+types of the supplied arguments.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+Operators
+</term>
+<listitem>
+<para>
+<productname>PostgreSQL</productname> allows expressions with
+prefix (one-argument) operators,
+as well as infix (two-argument) operators. Like functions, operators can
+be overloaded, so the same problem of selecting the right operator
+exists.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+Value Storage
+</term>
+<listitem>
+<para>
+<acronym>SQL</acronym> <command>INSERT</command> and <command>UPDATE</command> statements place the results of
+expressions into a table. The expressions in the statement must be matched up
+with, and perhaps converted to, the types of the target columns.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term>
+<literal>UNION</literal>, <literal>CASE</literal>, and related constructs
+</term>
+<listitem>
+<para>
+Since all query results from a unionized <command>SELECT</command> statement
+must appear in a single set of columns, the types of the results of each
+<command>SELECT</command> clause must be matched up and converted to a uniform set.
+Similarly, the result expressions of a <literal>CASE</literal> construct must be
+converted to a common type so that the <literal>CASE</literal> expression as a whole
+has a known output type. Some other constructs, such
+as <literal>ARRAY[]</literal> and the <function>GREATEST</function>
+and <function>LEAST</function> functions, likewise require determination of a
+common type for several subexpressions.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+
+<para>
+The system catalogs store information about which conversions, or
+<firstterm>casts</firstterm>, exist between which data types, and how to
+perform those conversions. Additional casts can be added by the user
+with the <xref linkend="sql-createcast"/>
+command. (This is usually
+done in conjunction with defining new data types. The set of casts
+between built-in types has been carefully crafted and is best not
+altered.)
+</para>
+
+<indexterm>
+ <primary>data type</primary>
+ <secondary>category</secondary>
+</indexterm>
+
+<para>
+An additional heuristic provided by the parser allows improved determination
+of the proper casting behavior among groups of types that have implicit casts.
+Data types are divided into several basic <firstterm>type
+categories</firstterm>, including <type>boolean</type>, <type>numeric</type>,
+<type>string</type>, <type>bitstring</type>, <type>datetime</type>,
+<type>timespan</type>, <type>geometric</type>, <type>network</type>, and
+user-defined. (For a list see <xref linkend="catalog-typcategory-table"/>;
+but note it is also possible to create custom type categories.) Within each
+category there can be one or more <firstterm>preferred types</firstterm>, which
+are preferred when there is a choice of possible types. With careful selection
+of preferred types and available implicit casts, it is possible to ensure that
+ambiguous expressions (those with multiple candidate parsing solutions) can be
+resolved in a useful way.
+</para>
+
+<para>
+All type conversion rules are designed with several principles in mind:
+
+<itemizedlist>
+<listitem>
+<para>
+Implicit conversions should never have surprising or unpredictable outcomes.
+</para>
+</listitem>
+
+<listitem>
+<para>
+There should be no extra overhead in the parser or executor
+if a query does not need implicit type conversion.
+That is, if a query is well-formed and the types already match, then the query should execute
+without spending extra time in the parser and without introducing unnecessary implicit conversion
+calls in the query.
+</para>
+</listitem>
+
+<listitem>
+<para>
+Additionally, if a query usually requires an implicit conversion for a function, and
+if then the user defines a new function with the correct argument types, the parser
+should use this new function and no longer do implicit conversion to use the old function.
+</para>
+</listitem>
+</itemizedlist>
+</para>
+
+</sect1>
+
+<sect1 id="typeconv-oper">
+<title>Operators</title>
+
+<indexterm zone="typeconv-oper">
+ <primary>operator</primary>
+ <secondary>type resolution in an invocation</secondary>
+</indexterm>
+
+ <para>
+ The specific operator that is referenced by an operator expression
+ is determined using the following procedure.
+ Note that this procedure is indirectly affected
+ by the precedence of the operators involved, since that will determine
+ which sub-expressions are taken to be the inputs of which operators.
+ See <xref linkend="sql-precedence"/> for more information.
+ </para>
+
+<procedure>
+<title>Operator Type Resolution</title>
+
+<step id="op-resol-select" performance="required">
+<para>
+Select the operators to be considered from the
+<classname>pg_operator</classname> system catalog. If a non-schema-qualified
+operator name was used (the usual case), the operators
+considered are those with the matching name and argument count that are
+visible in the current search path (see <xref linkend="ddl-schemas-path"/>).
+If a qualified operator name was given, only operators in the specified
+schema are considered.
+</para>
+
+<substeps>
+<step performance="optional">
+<para>
+If the search path finds multiple operators with identical argument types,
+only the one appearing earliest in the path is considered. Operators with
+different argument types are considered on an equal footing regardless of
+search path position.
+</para>
+</step>
+</substeps>
+</step>
+
+<step id="op-resol-exact-match" performance="required">
+<para>
+Check for an operator accepting exactly the input argument types.
+If one exists (there can be only one exact match in the set of
+operators considered), use it. Lack of an exact match creates a security
+hazard when calling, via qualified name
+ <footnote id="op-qualified-security">
+ <!-- If you edit this, consider editing func-qualified-security. -->
+ <para>
+ The hazard does not arise with a non-schema-qualified name, because a
+ search path containing schemas that permit untrusted users to create
+ objects is not a <link linkend="ddl-schemas-patterns">secure schema usage
+ pattern</link>.
+ </para>
+ </footnote>
+(not typical), any operator found in a schema that permits untrusted users to
+create objects. In such situations, cast arguments to force an exact match.
+</para>
+
+<substeps>
+<step id="op-resol-exact-unknown" performance="optional">
+<para>
+If one argument of a binary operator invocation is of the <type>unknown</type> type,
+then assume it is the same type as the other argument for this check.
+Invocations involving two <type>unknown</type> inputs, or a prefix operator
+with an <type>unknown</type> input, will never find a match at this step.
+</para>
+</step>
+<step id="op-resol-exact-domain" performance="optional">
+<para>
+If one argument of a binary operator invocation is of the <type>unknown</type>
+type and the other is of a domain type, next check to see if there is an
+operator accepting exactly the domain's base type on both sides; if so, use it.
+</para>
+</step>
+</substeps>
+</step>
+
+<step id="op-resol-best-match" performance="required">
+<para>
+Look for the best match.
+</para>
+<substeps>
+<step performance="required">
+<para>
+Discard candidate operators for which the input types do not match
+and cannot be converted (using an implicit conversion) to match.
+<type>unknown</type> literals are
+assumed to be convertible to anything for this purpose. If only one
+candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+If any input argument is of a domain type, treat it as being of the
+domain's base type for all subsequent steps. This ensures that domains
+act like their base types for purposes of ambiguous-operator resolution.
+</para>
+</step>
+<step performance="required">
+<para>
+Run through all candidates and keep those with the most exact matches
+on input types. Keep all candidates if none have exact matches.
+If only one candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+Run through all candidates and keep those that accept preferred types (of the
+input data type's type category) at the most positions where type conversion
+will be required.
+Keep all candidates if none accept preferred types.
+If only one candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+If any input arguments are <type>unknown</type>, check the type
+categories accepted at those argument positions by the remaining
+candidates. At each position, select the <type>string</type> category
+if any
+candidate accepts that category. (This bias towards string is appropriate
+since an unknown-type literal looks like a string.) Otherwise, if
+all the remaining candidates accept the same type category, select that
+category; otherwise fail because the correct choice cannot be deduced
+without more clues. Now discard
+candidates that do not accept the selected type category. Furthermore,
+if any candidate accepts a preferred type in that category,
+discard candidates that accept non-preferred types for that argument.
+Keep all candidates if none survive these tests.
+If only one candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step id="op-resol-last-unknown" performance="required">
+<para>
+If there are both <type>unknown</type> and known-type arguments, and all
+the known-type arguments have the same type, assume that the
+<type>unknown</type> arguments are also of that type, and check which
+candidates can accept that type at the <type>unknown</type>-argument
+positions. If exactly one candidate passes this test, use it.
+Otherwise, fail.
+</para>
+</step>
+</substeps>
+</step>
+</procedure>
+
+<para>
+Some examples follow.
+</para>
+
+<example>
+<title>Square Root Operator Type Resolution</title>
+
+<para>
+There is only one square root operator (prefix <literal>|/</literal>)
+defined in the standard catalog, and it takes an argument of type
+<type>double precision</type>.
+The scanner assigns an initial type of <type>integer</type> to the argument
+in this query expression:
+<screen>
+SELECT |/ 40 AS "square root of 40";
+ square root of 40
+-------------------
+ 6.324555320336759
+(1 row)
+</screen>
+
+So the parser does a type conversion on the operand and the query
+is equivalent to:
+
+<screen>
+SELECT |/ CAST(40 AS double precision) AS "square root of 40";
+</screen>
+</para>
+</example>
+
+<example>
+<title>String Concatenation Operator Type Resolution</title>
+
+<para>
+A string-like syntax is used for working with string types and for
+working with complex extension types.
+Strings with unspecified type are matched with likely operator candidates.
+</para>
+
+<para>
+An example with one unspecified argument:
+<screen>
+SELECT text 'abc' || 'def' AS "text and unknown";
+
+ text and unknown
+------------------
+ abcdef
+(1 row)
+</screen>
+</para>
+
+<para>
+In this case the parser looks to see if there is an operator taking <type>text</type>
+for both arguments. Since there is, it assumes that the second argument should
+be interpreted as type <type>text</type>.
+</para>
+
+<para>
+Here is a concatenation of two values of unspecified types:
+<screen>
+SELECT 'abc' || 'def' AS "unspecified";
+
+ unspecified
+-------------
+ abcdef
+(1 row)
+</screen>
+</para>
+
+<para>
+In this case there is no initial hint for which type to use, since no types
+are specified in the query. So, the parser looks for all candidate operators
+and finds that there are candidates accepting both string-category and
+bit-string-category inputs. Since string category is preferred when available,
+that category is selected, and then the
+preferred type for strings, <type>text</type>, is used as the specific
+type to resolve the unknown-type literals as.
+</para>
+</example>
+
+<example>
+<title>Absolute-Value and Negation Operator Type Resolution</title>
+
+<para>
+The <productname>PostgreSQL</productname> operator catalog has several
+entries for the prefix operator <literal>@</literal>, all of which implement
+absolute-value operations for various numeric data types. One of these
+entries is for type <type>float8</type>, which is the preferred type in
+the numeric category. Therefore, <productname>PostgreSQL</productname>
+will use that entry when faced with an <type>unknown</type> input:
+<screen>
+SELECT @ '-4.5' AS "abs";
+ abs
+-----
+ 4.5
+(1 row)
+</screen>
+Here the system has implicitly resolved the unknown-type literal as type
+<type>float8</type> before applying the chosen operator. We can verify that
+<type>float8</type> and not some other type was used:
+<screen>
+SELECT @ '-4.5e500' AS "abs";
+
+ERROR: "-4.5e500" is out of range for type double precision
+</screen>
+</para>
+
+<para>
+On the other hand, the prefix operator <literal>~</literal> (bitwise negation)
+is defined only for integer data types, not for <type>float8</type>. So, if we
+try a similar case with <literal>~</literal>, we get:
+<screen>
+SELECT ~ '20' AS "negation";
+
+ERROR: operator is not unique: ~ "unknown"
+HINT: Could not choose a best candidate operator. You might need to add
+explicit type casts.
+</screen>
+This happens because the system cannot decide which of the several
+possible <literal>~</literal> operators should be preferred. We can help
+it out with an explicit cast:
+<screen>
+SELECT ~ CAST('20' AS int8) AS "negation";
+
+ negation
+----------
+ -21
+(1 row)
+</screen>
+</para>
+</example>
+
+<example>
+<title>Array Inclusion Operator Type Resolution</title>
+
+<para>
+Here is another example of resolving an operator with one known and one
+unknown input:
+<screen>
+SELECT array[1,2] &lt;@ '{1,2,3}' as "is subset";
+
+ is subset
+-----------
+ t
+(1 row)
+</screen>
+The <productname>PostgreSQL</productname> operator catalog has several
+entries for the infix operator <literal>&lt;@</literal>, but the only two that
+could possibly accept an integer array on the left-hand side are
+array inclusion (<type>anyarray</type> <literal>&lt;@</literal> <type>anyarray</type>)
+and range inclusion (<type>anyelement</type> <literal>&lt;@</literal> <type>anyrange</type>).
+Since none of these polymorphic pseudo-types (see <xref
+linkend="datatype-pseudo"/>) are considered preferred, the parser cannot
+resolve the ambiguity on that basis.
+However, <xref linkend="op-resol-last-unknown"/> tells
+it to assume that the unknown-type literal is of the same type as the other
+input, that is, integer array. Now only one of the two operators can match,
+so array inclusion is selected. (Had range inclusion been selected, we would
+have gotten an error, because the string does not have the right format to be
+a range literal.)
+</para>
+</example>
+
+<example>
+<title>Custom Operator on a Domain Type</title>
+
+<para>
+Users sometimes try to declare operators applying just to a domain type.
+This is possible but is not nearly as useful as it might seem, because the
+operator resolution rules are designed to select operators applying to the
+domain's base type. As an example consider
+<screen>
+CREATE DOMAIN mytext AS text CHECK(...);
+CREATE FUNCTION mytext_eq_text (mytext, text) RETURNS boolean AS ...;
+CREATE OPERATOR = (procedure=mytext_eq_text, leftarg=mytext, rightarg=text);
+CREATE TABLE mytable (val mytext);
+
+SELECT * FROM mytable WHERE val = 'foo';
+</screen>
+This query will not use the custom operator. The parser will first see if
+there is a <type>mytext</type> <literal>=</literal> <type>mytext</type> operator
+(<xref linkend="op-resol-exact-unknown"/>), which there is not;
+then it will consider the domain's base type <type>text</type>, and see if
+there is a <type>text</type> <literal>=</literal> <type>text</type> operator
+(<xref linkend="op-resol-exact-domain"/>), which there is;
+so it resolves the <type>unknown</type>-type literal as <type>text</type> and
+uses the <type>text</type> <literal>=</literal> <type>text</type> operator.
+The only way to get the custom operator to be used is to explicitly cast
+the literal:
+<screen>
+SELECT * FROM mytable WHERE val = text 'foo';
+</screen>
+so that the <type>mytext</type> <literal>=</literal> <type>text</type> operator is found
+immediately according to the exact-match rule. If the best-match rules
+are reached, they actively discriminate against operators on domain types.
+If they did not, such an operator would create too many ambiguous-operator
+failures, because the casting rules always consider a domain as castable
+to or from its base type, and so the domain operator would be considered
+usable in all the same cases as a similarly-named operator on the base type.
+</para>
+</example>
+
+</sect1>
+
+<sect1 id="typeconv-func">
+<title>Functions</title>
+
+<indexterm zone="typeconv-func">
+ <primary>function</primary>
+ <secondary>type resolution in an invocation</secondary>
+</indexterm>
+
+ <para>
+ The specific function that is referenced by a function call
+ is determined using the following procedure.
+ </para>
+
+<procedure>
+<title>Function Type Resolution</title>
+
+<step performance="required">
+<para>
+Select the functions to be considered from the
+<classname>pg_proc</classname> system catalog. If a non-schema-qualified
+function name was used, the functions
+considered are those with the matching name and argument count that are
+visible in the current search path (see <xref linkend="ddl-schemas-path"/>).
+If a qualified function name was given, only functions in the specified
+schema are considered.
+</para>
+
+<substeps>
+<step performance="optional">
+<para>
+If the search path finds multiple functions of identical argument types,
+only the one appearing earliest in the path is considered. Functions of
+different argument types are considered on an equal footing regardless of
+search path position.
+</para>
+</step>
+<step performance="optional">
+<para>
+If a function is declared with a <literal>VARIADIC</literal> array parameter, and
+the call does not use the <literal>VARIADIC</literal> keyword, then the function
+is treated as if the array parameter were replaced by one or more occurrences
+of its element type, as needed to match the call. After such expansion the
+function might have effective argument types identical to some non-variadic
+function. In that case the function appearing earlier in the search path is
+used, or if the two functions are in the same schema, the non-variadic one is
+preferred.
+</para>
+<para>
+This creates a security hazard when calling, via qualified name
+ <footnote id="func-qualified-security">
+ <!-- If you edit this, consider editing op-qualified-security. -->
+ <para>
+ The hazard does not arise with a non-schema-qualified name, because a
+ search path containing schemas that permit untrusted users to create
+ objects is not a <link linkend="ddl-schemas-patterns">secure schema usage
+ pattern</link>.
+ </para>
+ </footnote>,
+a variadic function found in a schema that permits untrusted users to create
+objects. A malicious user can take control and execute arbitrary SQL
+functions as though you executed them. Substitute a call bearing
+the <literal>VARIADIC</literal> keyword, which bypasses this hazard. Calls
+populating <literal>VARIADIC "any"</literal> parameters often have no
+equivalent formulation containing the <literal>VARIADIC</literal> keyword. To
+issue those calls safely, the function's schema must permit only trusted users
+to create objects.
+</para>
+</step>
+<step performance="optional">
+<para>
+Functions that have default values for parameters are considered to match any
+call that omits zero or more of the defaultable parameter positions. If more
+than one such function matches a call, the one appearing earliest in the
+search path is used. If there are two or more such functions in the same
+schema with identical parameter types in the non-defaulted positions (which is
+possible if they have different sets of defaultable parameters), the system
+will not be able to determine which to prefer, and so an <quote>ambiguous
+function call</quote> error will result if no better match to the call can be
+found.
+</para>
+<para>
+This creates an availability hazard when calling, via qualified
+name<footnoteref linkend="func-qualified-security"/>, any function found in a
+schema that permits untrusted users to create objects. A malicious user can
+create a function with the name of an existing function, replicating that
+function's parameters and appending novel parameters having default values.
+This precludes new calls to the original function. To forestall this hazard,
+place functions in schemas that permit only trusted users to create objects.
+</para>
+</step>
+</substeps>
+</step>
+
+<step performance="required">
+<para>
+Check for a function accepting exactly the input argument types.
+If one exists (there can be only one exact match in the set of
+functions considered), use it. Lack of an exact match creates a security
+hazard when calling, via qualified
+name<footnoteref linkend="func-qualified-security"/>, a function found in a
+schema that permits untrusted users to create objects. In such situations,
+cast arguments to force an exact match. (Cases involving <type>unknown</type>
+will never find a match at this step.)
+</para>
+</step>
+
+<step performance="required">
+<para>
+If no exact match is found, see if the function call appears
+to be a special type conversion request. This happens if the function call
+has just one argument and the function name is the same as the (internal)
+name of some data type. Furthermore, the function argument must be either
+an unknown-type literal, or a type that is binary-coercible to the named
+data type, or a type that could be converted to the named data type by
+applying that type's I/O functions (that is, the conversion is either to or
+from one of the standard string types). When these conditions are met,
+the function call is treated as a form of <literal>CAST</literal> specification.
+ <footnote>
+ <para>
+ The reason for this step is to support function-style cast specifications
+ in cases where there is not an actual cast function. If there is a cast
+ function, it is conventionally named after its output type, and so there
+ is no need to have a special case. See
+ <xref linkend="sql-createcast"/>
+ for additional commentary.
+ </para>
+ </footnote>
+</para>
+</step>
+<step performance="required">
+<para>
+Look for the best match.
+</para>
+<substeps>
+<step performance="required">
+<para>
+Discard candidate functions for which the input types do not match
+and cannot be converted (using an implicit conversion) to match.
+<type>unknown</type> literals are
+assumed to be convertible to anything for this purpose. If only one
+candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+If any input argument is of a domain type, treat it as being of the
+domain's base type for all subsequent steps. This ensures that domains
+act like their base types for purposes of ambiguous-function resolution.
+</para>
+</step>
+<step performance="required">
+<para>
+Run through all candidates and keep those with the most exact matches
+on input types. Keep all candidates if none have exact matches.
+If only one candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+Run through all candidates and keep those that accept preferred types (of the
+input data type's type category) at the most positions where type conversion
+will be required.
+Keep all candidates if none accept preferred types.
+If only one candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+If any input arguments are <type>unknown</type>, check the type categories
+accepted
+at those argument positions by the remaining candidates. At each position,
+select the <type>string</type> category if any candidate accepts that category.
+(This bias towards string
+is appropriate since an unknown-type literal looks like a string.)
+Otherwise, if all the remaining candidates accept the same type category,
+select that category; otherwise fail because
+the correct choice cannot be deduced without more clues.
+Now discard candidates that do not accept the selected type category.
+Furthermore, if any candidate accepts a preferred type in that category,
+discard candidates that accept non-preferred types for that argument.
+Keep all candidates if none survive these tests.
+If only one candidate remains, use it; else continue to the next step.
+</para>
+</step>
+<step performance="required">
+<para>
+If there are both <type>unknown</type> and known-type arguments, and all
+the known-type arguments have the same type, assume that the
+<type>unknown</type> arguments are also of that type, and check which
+candidates can accept that type at the <type>unknown</type>-argument
+positions. If exactly one candidate passes this test, use it.
+Otherwise, fail.
+</para>
+</step>
+</substeps>
+</step>
+</procedure>
+
+<para>
+Note that the <quote>best match</quote> rules are identical for operator and
+function type resolution.
+Some examples follow.
+</para>
+
+<example>
+<title>Rounding Function Argument Type Resolution</title>
+
+<para>
+There is only one <function>round</function> function that takes two
+arguments; it takes a first argument of type <type>numeric</type> and
+a second argument of type <type>integer</type>.
+So the following query automatically converts
+the first argument of type <type>integer</type> to
+<type>numeric</type>:
+
+<screen>
+SELECT round(4, 4);
+
+ round
+--------
+ 4.0000
+(1 row)
+</screen>
+
+That query is actually transformed by the parser to:
+<screen>
+SELECT round(CAST (4 AS numeric), 4);
+</screen>
+</para>
+
+<para>
+Since numeric constants with decimal points are initially assigned the
+type <type>numeric</type>, the following query will require no type
+conversion and therefore might be slightly more efficient:
+<screen>
+SELECT round(4.0, 4);
+</screen>
+</para>
+</example>
+
+<example>
+<title>Variadic Function Resolution</title>
+
+<para>
+<screen>
+CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int
+ LANGUAGE sql AS 'SELECT 1';
+CREATE FUNCTION
+</screen>
+
+This function accepts, but does not require, the VARIADIC keyword. It
+tolerates both integer and numeric arguments:
+
+<screen>
+SELECT public.variadic_example(0),
+ public.variadic_example(0.0),
+ public.variadic_example(VARIADIC array[0.0]);
+ variadic_example | variadic_example | variadic_example
+------------------+------------------+------------------
+ 1 | 1 | 1
+(1 row)
+</screen>
+
+However, the first and second calls will prefer more-specific functions, if
+available:
+
+<screen>
+CREATE FUNCTION public.variadic_example(numeric) RETURNS int
+ LANGUAGE sql AS 'SELECT 2';
+CREATE FUNCTION
+
+CREATE FUNCTION public.variadic_example(int) RETURNS int
+ LANGUAGE sql AS 'SELECT 3';
+CREATE FUNCTION
+
+SELECT public.variadic_example(0),
+ public.variadic_example(0.0),
+ public.variadic_example(VARIADIC array[0.0]);
+ variadic_example | variadic_example | variadic_example
+------------------+------------------+------------------
+ 3 | 2 | 1
+(1 row)
+</screen>
+
+Given the default configuration and only the first function existing, the
+first and second calls are insecure. Any user could intercept them by
+creating the second or third function. By matching the argument type exactly
+and using the <literal>VARIADIC</literal> keyword, the third call is secure.
+</para>
+</example>
+
+<example>
+<title>Substring Function Type Resolution</title>
+
+<para>
+There are several <function>substr</function> functions, one of which
+takes types <type>text</type> and <type>integer</type>. If called
+with a string constant of unspecified type, the system chooses the
+candidate function that accepts an argument of the preferred category
+<literal>string</literal> (namely of type <type>text</type>).
+
+<screen>
+SELECT substr('1234', 3);
+
+ substr
+--------
+ 34
+(1 row)
+</screen>
+</para>
+
+<para>
+If the string is declared to be of type <type>varchar</type>, as might be the case
+if it comes from a table, then the parser will try to convert it to become <type>text</type>:
+<screen>
+SELECT substr(varchar '1234', 3);
+
+ substr
+--------
+ 34
+(1 row)
+</screen>
+
+This is transformed by the parser to effectively become:
+<screen>
+SELECT substr(CAST (varchar '1234' AS text), 3);
+</screen>
+</para>
+<para>
+<note>
+<para>
+The parser learns from the <structname>pg_cast</structname> catalog that
+<type>text</type> and <type>varchar</type>
+are binary-compatible, meaning that one can be passed to a function that
+accepts the other without doing any physical conversion. Therefore, no
+type conversion call is really inserted in this case.
+</para>
+</note>
+</para>
+
+<para>
+And, if the function is called with an argument of type <type>integer</type>,
+the parser will try to convert that to <type>text</type>:
+<screen>
+SELECT substr(1234, 3);
+ERROR: function substr(integer, integer) does not exist
+HINT: No function matches the given name and argument types. You might need
+to add explicit type casts.
+</screen>
+
+This does not work because <type>integer</type> does not have an implicit cast
+to <type>text</type>. An explicit cast will work, however:
+<screen>
+SELECT substr(CAST (1234 AS text), 3);
+
+ substr
+--------
+ 34
+(1 row)
+</screen>
+</para>
+</example>
+
+</sect1>
+
+<sect1 id="typeconv-query">
+<title>Value Storage</title>
+
+ <para>
+ Values to be inserted into a table are converted to the destination
+ column's data type according to the
+ following steps.
+ </para>
+
+<procedure>
+<title>Value Storage Type Conversion</title>
+
+<step performance="required">
+<para>
+Check for an exact match with the target.
+</para>
+</step>
+
+<step performance="required">
+<para>
+Otherwise, try to convert the expression to the target type. This is possible
+if an <firstterm>assignment cast</firstterm> between the two types is registered in the
+<structname>pg_cast</structname> catalog (see <xref linkend="sql-createcast"/>).
+Alternatively, if the expression is an unknown-type literal, the contents of
+the literal string will be fed to the input conversion routine for the target
+type.
+</para>
+</step>
+
+<step performance="required">
+<para>
+Check to see if there is a sizing cast for the target type. A sizing
+cast is a cast from that type to itself. If one is found in the
+<structname>pg_cast</structname> catalog, apply it to the expression before storing
+into the destination column. The implementation function for such a cast
+always takes an extra parameter of type <type>integer</type>, which receives
+the destination column's <structfield>atttypmod</structfield> value (typically its
+declared length, although the interpretation of <structfield>atttypmod</structfield>
+varies for different data types), and it may take a third <type>boolean</type>
+parameter that says whether the cast is explicit or implicit. The cast
+function
+is responsible for applying any length-dependent semantics such as size
+checking or truncation.
+</para>
+</step>
+
+</procedure>
+
+<example>
+<title><type>character</type> Storage Type Conversion</title>
+
+<para>
+For a target column declared as <type>character(20)</type> the following
+statement shows that the stored value is sized correctly:
+
+<screen>
+CREATE TABLE vv (v character(20));
+INSERT INTO vv SELECT 'abc' || 'def';
+SELECT v, octet_length(v) FROM vv;
+
+ v | octet_length
+----------------------+--------------
+ abcdef | 20
+(1 row)
+</screen>
+</para>
+
+<para>
+What has really happened here is that the two unknown literals are resolved
+to <type>text</type> by default, allowing the <literal>||</literal> operator
+to be resolved as <type>text</type> concatenation. Then the <type>text</type>
+result of the operator is converted to <type>bpchar</type> (<quote>blank-padded
+char</quote>, the internal name of the <type>character</type> data type) to match the target
+column type. (Since the conversion from <type>text</type> to
+<type>bpchar</type> is binary-coercible, this conversion does
+not insert any real function call.) Finally, the sizing function
+<literal>bpchar(bpchar, integer, boolean)</literal> is found in the system catalog
+and applied to the operator's result and the stored column length. This
+type-specific function performs the required length check and addition of
+padding spaces.
+</para>
+</example>
+</sect1>
+
+<sect1 id="typeconv-union-case">
+<title><literal>UNION</literal>, <literal>CASE</literal>, and Related Constructs</title>
+
+<indexterm zone="typeconv-union-case">
+ <primary>UNION</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<indexterm zone="typeconv-union-case">
+ <primary>CASE</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<indexterm zone="typeconv-union-case">
+ <primary>ARRAY</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<indexterm zone="typeconv-union-case">
+ <primary>VALUES</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<indexterm zone="typeconv-union-case">
+ <primary>GREATEST</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<indexterm zone="typeconv-union-case">
+ <primary>LEAST</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<para>
+SQL <literal>UNION</literal> constructs must match up possibly dissimilar
+types to become a single result set. The resolution algorithm is
+applied separately to each output column of a union query. The
+<literal>INTERSECT</literal> and <literal>EXCEPT</literal> constructs resolve
+dissimilar types in the same way as <literal>UNION</literal>.
+Some other constructs, including
+<literal>CASE</literal>, <literal>ARRAY</literal>, <literal>VALUES</literal>,
+and the <function>GREATEST</function> and <function>LEAST</function>
+functions, use the identical
+algorithm to match up their component expressions and select a result
+data type.
+</para>
+
+<procedure>
+<title>Type Resolution for <literal>UNION</literal>, <literal>CASE</literal>,
+and Related Constructs</title>
+
+<step performance="required">
+<para>
+If all inputs are of the same type, and it is not <type>unknown</type>,
+resolve as that type.
+</para>
+</step>
+
+<step performance="required">
+<para>
+If any input is of a domain type, treat it as being of the
+domain's base type for all subsequent steps.
+ <footnote>
+ <para>
+ Somewhat like the treatment of domain inputs for operators and
+ functions, this behavior allows a domain type to be preserved through
+ a <literal>UNION</literal> or similar construct, so long as the user is
+ careful to ensure that all inputs are implicitly or explicitly of that
+ exact type. Otherwise the domain's base type will be used.
+ </para>
+ </footnote>
+</para>
+</step>
+
+<step performance="required">
+<para>
+If all inputs are of type <type>unknown</type>, resolve as type
+<type>text</type> (the preferred type of the string category).
+Otherwise, <type>unknown</type> inputs are ignored for the purposes
+of the remaining rules.
+</para>
+</step>
+
+<step performance="required">
+<para>
+If the non-unknown inputs are not all of the same type category, fail.
+</para>
+</step>
+
+<step performance="required">
+<para>
+Select the first non-unknown input type as the candidate type,
+then consider each other non-unknown input type, left to right.
+ <footnote>
+ <para>
+ For historical reasons, <literal>CASE</literal> treats
+ its <literal>ELSE</literal> clause (if any) as the <quote>first</quote>
+ input, with the <literal>THEN</literal> clauses(s) considered after
+ that. In all other cases, <quote>left to right</quote> means the order
+ in which the expressions appear in the query text.
+ </para>
+ </footnote>
+If the candidate type can be implicitly converted to the other type,
+but not vice-versa, select the other type as the new candidate type.
+Then continue considering the remaining inputs. If, at any stage of this
+process, a preferred type is selected, stop considering additional
+inputs.
+</para>
+</step>
+
+<step performance="required">
+<para>
+Convert all inputs to the final candidate type. Fail if there is not an
+implicit conversion from a given input type to the candidate type.
+</para>
+</step>
+</procedure>
+
+<para>
+Some examples follow.
+</para>
+
+<example>
+<title>Type Resolution with Underspecified Types in a Union</title>
+
+<para>
+<screen>
+SELECT text 'a' AS "text" UNION SELECT 'b';
+
+ text
+------
+ a
+ b
+(2 rows)
+</screen>
+Here, the unknown-type literal <literal>'b'</literal> will be resolved to type <type>text</type>.
+</para>
+</example>
+
+<example>
+<title>Type Resolution in a Simple Union</title>
+
+<para>
+<screen>
+SELECT 1.2 AS "numeric" UNION SELECT 1;
+
+ numeric
+---------
+ 1
+ 1.2
+(2 rows)
+</screen>
+The literal <literal>1.2</literal> is of type <type>numeric</type>,
+and the <type>integer</type> value <literal>1</literal> can be cast implicitly to
+<type>numeric</type>, so that type is used.
+</para>
+</example>
+
+<example>
+<title>Type Resolution in a Transposed Union</title>
+
+<para>
+<screen>
+SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
+
+ real
+------
+ 1
+ 2.2
+(2 rows)
+</screen>
+Here, since type <type>real</type> cannot be implicitly cast to <type>integer</type>,
+but <type>integer</type> can be implicitly cast to <type>real</type>, the union
+result type is resolved as <type>real</type>.
+</para>
+</example>
+
+<example>
+<title>Type Resolution in a Nested Union</title>
+
+<para>
+<screen>
+SELECT NULL UNION SELECT NULL UNION SELECT 1;
+
+ERROR: UNION types text and integer cannot be matched
+</screen>
+This failure occurs because <productname>PostgreSQL</productname> treats
+multiple <literal>UNION</literal>s as a nest of pairwise operations;
+that is, this input is the same as
+<screen>
+(SELECT NULL UNION SELECT NULL) UNION SELECT 1;
+</screen>
+The inner <literal>UNION</literal> is resolved as emitting
+type <type>text</type>, according to the rules given above. Then the
+outer <literal>UNION</literal> has inputs of types <type>text</type>
+and <type>integer</type>, leading to the observed error. The problem
+can be fixed by ensuring that the leftmost <literal>UNION</literal>
+has at least one input of the desired result type.
+</para>
+
+<para>
+<literal>INTERSECT</literal> and <literal>EXCEPT</literal> operations are
+likewise resolved pairwise. However, the other constructs described in this
+section consider all of their inputs in one resolution step.
+</para>
+</example>
+</sect1>
+
+<sect1 id="typeconv-select">
+<title><literal>SELECT</literal> Output Columns</title>
+
+<indexterm zone="typeconv-select">
+ <primary>SELECT</primary>
+ <secondary>determination of result type</secondary>
+</indexterm>
+
+<para>
+The rules given in the preceding sections will result in assignment
+of non-<type>unknown</type> data types to all expressions in an SQL query,
+except for unspecified-type literals that appear as simple output
+columns of a <command>SELECT</command> command. For example, in
+
+<screen>
+SELECT 'Hello World';
+</screen>
+
+there is nothing to identify what type the string literal should be
+taken as. In this situation <productname>PostgreSQL</productname> will fall back
+to resolving the literal's type as <type>text</type>.
+</para>
+
+<para>
+When the <command>SELECT</command> is one arm of a <literal>UNION</literal>
+(or <literal>INTERSECT</literal> or <literal>EXCEPT</literal>) construct, or when it
+appears within <command>INSERT ... SELECT</command>, this rule is not applied
+since rules given in preceding sections take precedence. The type of an
+unspecified-type literal can be taken from the other <literal>UNION</literal> arm
+in the first case, or from the destination column in the second case.
+</para>
+
+<para>
+<literal>RETURNING</literal> lists are treated the same as <command>SELECT</command>
+output lists for this purpose.
+</para>
+
+<note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 10, this rule did not exist, and
+ unspecified-type literals in a <command>SELECT</command> output list were
+ left as type <type>unknown</type>. That had assorted bad consequences,
+ so it's been changed.
+ </para>
+</note>
+
+</sect1>
+</chapter>
diff --git a/doc/src/sgml/unaccent.sgml b/doc/src/sgml/unaccent.sgml
new file mode 100644
index 0000000..5cd716a
--- /dev/null
+++ b/doc/src/sgml/unaccent.sgml
@@ -0,0 +1,202 @@
+<!-- doc/src/sgml/unaccent.sgml -->
+
+<sect1 id="unaccent" xreflabel="unaccent">
+ <title>unaccent</title>
+
+ <indexterm zone="unaccent">
+ <primary>unaccent</primary>
+ </indexterm>
+
+ <para>
+ <filename>unaccent</filename> is a text search dictionary that removes accents
+ (diacritic signs) from lexemes.
+ It's a filtering dictionary, which means its output is
+ always passed to the next dictionary (if any), unlike the normal
+ behavior of dictionaries. This allows accent-insensitive processing
+ for full text search.
+ </para>
+
+ <para>
+ The current implementation of <filename>unaccent</filename> cannot be used as a
+ normalizing dictionary for the <filename>thesaurus</filename> dictionary.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title>Configuration</title>
+
+ <para>
+ An <literal>unaccent</literal> dictionary accepts the following options:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <literal>RULES</literal> is the base name of the file containing the list of
+ translation rules. This file must be stored in
+ <filename>$SHAREDIR/tsearch_data/</filename> (where <literal>$SHAREDIR</literal> means
+ the <productname>PostgreSQL</productname> installation's shared-data directory).
+ Its name must end in <literal>.rules</literal> (which is not to be included in
+ the <literal>RULES</literal> parameter).
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The rules file has the following format:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Each line represents one translation rule, consisting of a character with
+ accent followed by a character without accent. The first is translated
+ into the second. For example,
+<programlisting>
+&Agrave; A
+&Aacute; A
+&Acirc; A
+&Atilde; A
+&Auml; A
+&Aring; A
+&AElig; AE
+</programlisting>
+ The two characters must be separated by whitespace, and any leading or
+ trailing whitespace on a line is ignored.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Alternatively, if only one character is given on a line, instances of
+ that character are deleted; this is useful in languages where accents
+ are represented by separate characters.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Actually, each <quote>character</quote> can be any string not containing
+ whitespace, so <filename>unaccent</filename> dictionaries could be used for
+ other sorts of substring substitutions besides diacritic removal.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ As with other <productname>PostgreSQL</productname> text search configuration files,
+ the rules file must be stored in UTF-8 encoding. The data is
+ automatically translated into the current database's encoding when
+ loaded. Any lines containing untranslatable characters are silently
+ ignored, so that rules files can contain rules that are not applicable in
+ the current encoding.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ A more complete example, which is directly useful for most European
+ languages, can be found in <filename>unaccent.rules</filename>, which is installed
+ in <filename>$SHAREDIR/tsearch_data/</filename> when the <filename>unaccent</filename>
+ module is installed. This rules file translates characters with accents
+ to the same characters without accents, and it also expands ligatures
+ into the equivalent series of simple characters (for example, &AElig; to
+ AE).
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Usage</title>
+
+ <para>
+ Installing the <literal>unaccent</literal> extension creates a text
+ search template <literal>unaccent</literal> and a dictionary <literal>unaccent</literal>
+ based on it. The <literal>unaccent</literal> dictionary has the default
+ parameter setting <literal>RULES='unaccent'</literal>, which makes it immediately
+ usable with the standard <filename>unaccent.rules</filename> file.
+ If you wish, you can alter the parameter, for example
+
+<programlisting>
+mydb=# ALTER TEXT SEARCH DICTIONARY unaccent (RULES='my_rules');
+</programlisting>
+
+ or create new dictionaries based on the template.
+ </para>
+
+ <para>
+ To test the dictionary, you can try:
+<programlisting>
+mydb=# select ts_lexize('unaccent','H&ocirc;tel');
+ ts_lexize
+-----------
+ {Hotel}
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Here is an example showing how to insert the
+ <filename>unaccent</filename> dictionary into a text search configuration:
+<programlisting>
+mydb=# CREATE TEXT SEARCH CONFIGURATION fr ( COPY = french );
+mydb=# ALTER TEXT SEARCH CONFIGURATION fr
+ ALTER MAPPING FOR hword, hword_part, word
+ WITH unaccent, french_stem;
+mydb=# select to_tsvector('fr','H&ocirc;tels de la Mer');
+ to_tsvector
+-------------------
+ 'hotel':1 'mer':4
+(1 row)
+
+mydb=# select to_tsvector('fr','H&ocirc;tel de la Mer') @@ to_tsquery('fr','Hotels');
+ ?column?
+----------
+ t
+(1 row)
+
+mydb=# select ts_headline('fr','H&ocirc;tel de la Mer',to_tsquery('fr','Hotels'));
+ ts_headline
+------------------------
+ &lt;b&gt;H&ocirc;tel&lt;/b&gt; de la Mer
+(1 row)
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Functions</title>
+
+ <para>
+ The <function>unaccent()</function> function removes accents (diacritic signs) from
+ a given string. Basically, it's a wrapper around
+ <filename>unaccent</filename>-type dictionaries, but it can be used outside normal
+ text search contexts.
+ </para>
+
+ <indexterm>
+ <primary>unaccent</primary>
+ </indexterm>
+
+<synopsis>
+unaccent(<optional><replaceable class="parameter">dictionary</replaceable> <type>regdictionary</type>, </optional> <replaceable class="parameter">string</replaceable> <type>text</type>) returns <type>text</type>
+</synopsis>
+
+ <para>
+ If the <replaceable class="parameter">dictionary</replaceable> argument is
+ omitted, the text search dictionary named <literal>unaccent</literal> and
+ appearing in the same schema as the <function>unaccent()</function>
+ function itself is used.
+ </para>
+
+ <para>
+ For example:
+<programlisting>
+SELECT unaccent('unaccent', 'H&ocirc;tel');
+SELECT unaccent('H&ocirc;tel');
+</programlisting>
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml
new file mode 100644
index 0000000..9af9c00
--- /dev/null
+++ b/doc/src/sgml/user-manag.sgml
@@ -0,0 +1,732 @@
+<!-- doc/src/sgml/user-manag.sgml -->
+
+<chapter id="user-manag">
+ <title>Database Roles</title>
+
+ <para>
+ <productname>PostgreSQL</productname> manages database access permissions
+ using the concept of <firstterm>roles</firstterm>. A role can be thought of as
+ either a database user, or a group of database users, depending on how
+ the role is set up. Roles can own database objects (for example, tables
+ and functions) and can assign privileges on those objects to other roles to
+ control who has access to which objects. Furthermore, it is possible
+ to grant <firstterm>membership</firstterm> in a role to another role, thus
+ allowing the member role to use privileges assigned to another role.
+ </para>
+
+ <para>
+ The concept of roles subsumes the concepts of <quote>users</quote> and
+ <quote>groups</quote>. In <productname>PostgreSQL</productname> versions
+ before 8.1, users and groups were distinct kinds of entities, but now
+ there are only roles. Any role can act as a user, a group, or both.
+ </para>
+
+ <para>
+ This chapter describes how to create and manage roles.
+ More information about the effects of role privileges on various
+ database objects can be found in <xref linkend="ddl-priv"/>.
+ </para>
+
+ <sect1 id="database-roles">
+ <title>Database Roles</title>
+
+ <indexterm zone="database-roles">
+ <primary>role</primary>
+ </indexterm>
+
+ <indexterm zone="database-roles">
+ <primary>user</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>CREATE ROLE</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>DROP ROLE</primary>
+ </indexterm>
+
+ <para>
+ Database roles are conceptually completely separate from
+ operating system users. In practice it might be convenient to
+ maintain a correspondence, but this is not required. Database roles
+ are global across a database cluster installation (and not
+ per individual database). To create a role use the <link
+ linkend="sql-createrole"><command>CREATE ROLE</command></link> SQL command:
+<synopsis>
+CREATE ROLE <replaceable>name</replaceable>;
+</synopsis>
+ <replaceable>name</replaceable> follows the rules for SQL
+ identifiers: either unadorned without special characters, or
+ double-quoted. (In practice, you will usually want to add additional
+ options, such as <literal>LOGIN</literal>, to the command. More details appear
+ below.) To remove an existing role, use the analogous
+ <link linkend="sql-droprole"><command>DROP ROLE</command></link> command:
+<synopsis>
+DROP ROLE <replaceable>name</replaceable>;
+</synopsis>
+ </para>
+
+ <indexterm>
+ <primary>createuser</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>dropuser</primary>
+ </indexterm>
+
+ <para>
+ For convenience, the programs <xref linkend="app-createuser"/>
+ and <xref linkend="app-dropuser"/> are provided as wrappers
+ around these SQL commands that can be called from the shell command
+ line:
+<synopsis>
+createuser <replaceable>name</replaceable>
+dropuser <replaceable>name</replaceable>
+</synopsis>
+ </para>
+
+ <para>
+ To determine the set of existing roles, examine the <structname>pg_roles</structname>
+ system catalog, for example
+<synopsis>
+SELECT rolname FROM pg_roles;
+</synopsis>
+ The <xref linkend="app-psql"/> program's <literal>\du</literal> meta-command
+ is also useful for listing the existing roles.
+ </para>
+
+ <para>
+ In order to bootstrap the database system, a freshly initialized
+ system always contains one predefined role. This role is always
+ a <quote>superuser</quote>, and by default (unless altered when running
+ <command>initdb</command>) it will have the same name as the
+ operating system user that initialized the database
+ cluster. Customarily, this role will be named
+ <literal>postgres</literal>. In order to create more roles you
+ first have to connect as this initial role.
+ </para>
+
+ <para>
+ Every connection to the database server is made using the name of some
+ particular role, and this role determines the initial access privileges for
+ commands issued in that connection.
+ The role name to use for a particular database
+ connection is indicated by the client that is initiating the
+ connection request in an application-specific fashion. For example,
+ the <command>psql</command> program uses the
+ <option>-U</option> command line option to indicate the role to
+ connect as. Many applications assume the name of the current
+ operating system user by default (including
+ <command>createuser</command> and <command>psql</command>). Therefore it
+ is often convenient to maintain a naming correspondence between
+ roles and operating system users.
+ </para>
+
+ <para>
+ The set of database roles a given client connection can connect as
+ is determined by the client authentication setup, as explained in
+ <xref linkend="client-authentication"/>. (Thus, a client is not
+ limited to connect as the role matching
+ its operating system user, just as a person's login name
+ need not match his or her real name.) Since the role
+ identity determines the set of privileges available to a connected
+ client, it is important to carefully configure privileges when setting up
+ a multiuser environment.
+ </para>
+ </sect1>
+
+ <sect1 id="role-attributes">
+ <title>Role Attributes</title>
+
+ <para>
+ A database role can have a number of attributes that define its
+ privileges and interact with the client authentication system.
+
+ <variablelist>
+ <varlistentry>
+ <term>login privilege<indexterm><primary>login privilege</primary></indexterm></term>
+ <listitem>
+ <para>
+ Only roles that have the <literal>LOGIN</literal> attribute can be used
+ as the initial role name for a database connection. A role with
+ the <literal>LOGIN</literal> attribute can be considered the same
+ as a <quote>database user</quote>. To create a role with login privilege,
+ use either:
+<programlisting>
+CREATE ROLE <replaceable>name</replaceable> LOGIN;
+CREATE USER <replaceable>name</replaceable>;
+</programlisting>
+ (<command>CREATE USER</command> is equivalent to <command>CREATE ROLE</command>
+ except that <command>CREATE USER</command> includes <literal>LOGIN</literal> by
+ default, while <command>CREATE ROLE</command> does not.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>superuser status<indexterm><primary>superuser</primary></indexterm></term>
+ <listitem>
+ <para>
+ A database superuser bypasses all permission checks, except the right
+ to log in. This is a dangerous privilege and should not be used
+ carelessly; it is best to do most of your work as a role that is not a
+ superuser. To create a new database superuser, use <literal>CREATE
+ ROLE <replaceable>name</replaceable> SUPERUSER</literal>. You must do
+ this as a role that is already a superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>database creation<indexterm><primary>database</primary><secondary>privilege to create</secondary></indexterm></term>
+ <listitem>
+ <para>
+ A role must be explicitly given permission to create databases
+ (except for superusers, since those bypass all permission
+ checks). To create such a role, use <literal>CREATE ROLE
+ <replaceable>name</replaceable> CREATEDB</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term id='role-creation'>role creation<indexterm><primary>role</primary><secondary>privilege to create</secondary></indexterm></term>
+ <listitem>
+ <para>
+ A role must be explicitly given permission to create more roles
+ (except for superusers, since those bypass all permission
+ checks). To create such a role, use <literal>CREATE ROLE
+ <replaceable>name</replaceable> CREATEROLE</literal>.
+ A role with <literal>CREATEROLE</literal> privilege can alter and drop
+ other roles, too, as well as grant or revoke membership in them.
+ Altering a role includes most changes that can be made using
+ <literal>ALTER ROLE</literal>, including, for example, changing
+ passwords. It also includes modifications to a role that can
+ be made using the <literal>COMMENT</literal> and
+ <literal>SECURITY LABEL</literal> commands.
+ </para>
+ <para>
+ However, <literal>CREATEROLE</literal> does not convey the ability to
+ create <literal>SUPERUSER</literal> roles, nor does it convey any
+ power over <literal>SUPERUSER</literal> roles that already exist.
+ Furthermore, <literal>CREATEROLE</literal> does not convey the power
+ to create <literal>REPLICATION</literal> users, nor the ability to
+ grant or revoke the <literal>REPLICATION</literal> privilege, nor the
+ ability to modify the role properties of such users. However, it does
+ allow <literal>ALTER ROLE ... SET</literal> and
+ <literal>ALTER ROLE ... RENAME</literal> to be used on
+ <literal>REPLICATION</literal> roles, as well as the use of
+ <literal>COMMENT ON ROLE</literal>,
+ <literal>SECURITY LABEL ON ROLE</literal>,
+ and <literal>DROP ROLE</literal>.
+ Finally, <literal>CREATEROLE</literal> does not
+ confer the ability to grant or revoke the <literal>BYPASSRLS</literal>
+ privilege.
+ </para>
+ <para>
+ Because the <literal>CREATEROLE</literal> privilege allows a user
+ to grant or revoke membership even in roles to which it does not (yet)
+ have any access, a <literal>CREATEROLE</literal> user can obtain access
+ to the capabilities of every predefined role in the system, including
+ highly privileged roles such as
+ <literal>pg_execute_server_program</literal> and
+ <literal>pg_write_server_files</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>initiating replication<indexterm><primary>role</primary><secondary>privilege to initiate replication</secondary></indexterm></term>
+ <listitem>
+ <para>
+ A role must explicitly be given permission to initiate streaming
+ replication (except for superusers, since those bypass all permission
+ checks). A role used for streaming replication must
+ have <literal>LOGIN</literal> permission as well. To create such a role, use
+ <literal>CREATE ROLE <replaceable>name</replaceable> REPLICATION
+ LOGIN</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>password<indexterm><primary>password</primary></indexterm></term>
+ <listitem>
+ <para>
+ A password is only significant if the client authentication
+ method requires the user to supply a password when connecting
+ to the database. The <option>password</option> and
+ <option>md5</option> authentication methods
+ make use of passwords. Database passwords are separate from
+ operating system passwords. Specify a password upon role
+ creation with <literal>CREATE ROLE
+ <replaceable>name</replaceable> PASSWORD '<replaceable>string</replaceable>'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>inheritance of privileges<indexterm><primary>role</primary><secondary>privilege to inherit</secondary></indexterm></term>
+ <listitem>
+ <para>
+ A role is given permission to inherit the privileges of roles it is a
+ member of, by default. However, to create a role without the permission,
+ use <literal>CREATE ROLE <replaceable>name</replaceable> NOINHERIT</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>bypassing row-level security<indexterm><primary>role</primary><secondary>privilege to bypass</secondary></indexterm></term>
+ <listitem>
+ <para>
+ A role must be explicitly given permission to bypass every row-level security (RLS) policy
+ (except for superusers, since those bypass all permission checks).
+ To create such a role, use <literal>CREATE ROLE <replaceable>name</replaceable> BYPASSRLS</literal> as a superuser.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>connection limit<indexterm><primary>role</primary><secondary>privilege to limit connection</secondary></indexterm></term>
+ <listitem>
+ <para>
+ Connection limit can specify how many concurrent connections a role can make.
+ -1 (the default) means no limit. Specify connection limit upon role creation with
+ <literal>CREATE ROLE <replaceable>name</replaceable> CONNECTION LIMIT '<replaceable>integer</replaceable>'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ A role's attributes can be modified after creation with
+ <command>ALTER ROLE</command>.<indexterm><primary>ALTER ROLE</primary></indexterm>
+ See the reference pages for the <xref linkend="sql-createrole"/>
+ and <xref linkend="sql-alterrole"/> commands for details.
+ </para>
+
+ <para>
+ A role can also have role-specific defaults for many of the run-time
+ configuration settings described in <xref
+ linkend="runtime-config"/>. For example, if for some reason you
+ want to disable index scans (hint: not a good idea) anytime you
+ connect, you can use:
+<programlisting>
+ALTER ROLE myname SET enable_indexscan TO off;
+</programlisting>
+ This will save the setting (but not set it immediately). In
+ subsequent connections by this role it will appear as though
+ <literal>SET enable_indexscan TO off</literal> had been executed
+ just before the session started.
+ You can still alter this setting during the session; it will only
+ be the default. To remove a role-specific default setting, use
+ <literal>ALTER ROLE <replaceable>rolename</replaceable> RESET <replaceable>varname</replaceable></literal>.
+ Note that role-specific defaults attached to roles without
+ <literal>LOGIN</literal> privilege are fairly useless, since they will never
+ be invoked.
+ </para>
+ </sect1>
+
+ <sect1 id="role-membership">
+ <title>Role Membership</title>
+
+ <indexterm zone="role-membership">
+ <primary>role</primary><secondary>membership in</secondary>
+ </indexterm>
+
+ <para>
+ It is frequently convenient to group users together to ease
+ management of privileges: that way, privileges can be granted to, or
+ revoked from, a group as a whole. In <productname>PostgreSQL</productname>
+ this is done by creating a role that represents the group, and then
+ granting <firstterm>membership</firstterm> in the group role to individual user
+ roles.
+ </para>
+
+ <para>
+ To set up a group role, first create the role:
+<synopsis>
+CREATE ROLE <replaceable>name</replaceable>;
+</synopsis>
+ Typically a role being used as a group would not have the <literal>LOGIN</literal>
+ attribute, though you can set it if you wish.
+ </para>
+
+ <para>
+ Once the group role exists, you can add and remove members using the
+ <link linkend="sql-grant"><command>GRANT</command></link> and
+ <link linkend="sql-revoke"><command>REVOKE</command></link> commands:
+<synopsis>
+GRANT <replaceable>group_role</replaceable> TO <replaceable>role1</replaceable>, ... ;
+REVOKE <replaceable>group_role</replaceable> FROM <replaceable>role1</replaceable>, ... ;
+</synopsis>
+ You can grant membership to other group roles, too (since there isn't
+ really any distinction between group roles and non-group roles). The
+ database will not let you set up circular membership loops. Also,
+ it is not permitted to grant membership in a role to
+ <literal>PUBLIC</literal>.
+ </para>
+
+ <para>
+ The members of a group role can use the privileges of the role in two
+ ways. First, every member of a group can explicitly do
+ <link linkend="sql-set-role"><command>SET ROLE</command></link> to
+ temporarily <quote>become</quote> the group role. In this state, the
+ database session has access to the privileges of the group role rather
+ than the original login role, and any database objects created are
+ considered owned by the group role not the login role. Second, member
+ roles that have the <literal>INHERIT</literal> attribute automatically have use
+ of the privileges of roles of which they are members, including any
+ privileges inherited by those roles.
+ As an example, suppose we have done:
+<programlisting>
+CREATE ROLE joe LOGIN INHERIT;
+CREATE ROLE admin NOINHERIT;
+CREATE ROLE wheel NOINHERIT;
+GRANT admin TO joe;
+GRANT wheel TO admin;
+</programlisting>
+ Immediately after connecting as role <literal>joe</literal>, a database
+ session will have use of privileges granted directly to <literal>joe</literal>
+ plus any privileges granted to <literal>admin</literal>, because <literal>joe</literal>
+ <quote>inherits</quote> <literal>admin</literal>'s privileges. However, privileges
+ granted to <literal>wheel</literal> are not available, because even though
+ <literal>joe</literal> is indirectly a member of <literal>wheel</literal>, the
+ membership is via <literal>admin</literal> which has the <literal>NOINHERIT</literal>
+ attribute. After:
+<programlisting>
+SET ROLE admin;
+</programlisting>
+ the session would have use of only those privileges granted to
+ <literal>admin</literal>, and not those granted to <literal>joe</literal>. After:
+<programlisting>
+SET ROLE wheel;
+</programlisting>
+ the session would have use of only those privileges granted to
+ <literal>wheel</literal>, and not those granted to either <literal>joe</literal>
+ or <literal>admin</literal>. The original privilege state can be restored
+ with any of:
+<programlisting>
+SET ROLE joe;
+SET ROLE NONE;
+RESET ROLE;
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ The <command>SET ROLE</command> command always allows selecting any role
+ that the original login role is directly or indirectly a member of.
+ Thus, in the above example, it is not necessary to become
+ <literal>admin</literal> before becoming <literal>wheel</literal>.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ In the SQL standard, there is a clear distinction between users and roles,
+ and users do not automatically inherit privileges while roles do. This
+ behavior can be obtained in <productname>PostgreSQL</productname> by giving
+ roles being used as SQL roles the <literal>INHERIT</literal> attribute, while
+ giving roles being used as SQL users the <literal>NOINHERIT</literal> attribute.
+ However, <productname>PostgreSQL</productname> defaults to giving all roles
+ the <literal>INHERIT</literal> attribute, for backward compatibility with pre-8.1
+ releases in which users always had use of permissions granted to groups
+ they were members of.
+ </para>
+ </note>
+
+ <para>
+ The role attributes <literal>LOGIN</literal>, <literal>SUPERUSER</literal>,
+ <literal>CREATEDB</literal>, and <literal>CREATEROLE</literal> can be thought of as
+ special privileges, but they are never inherited as ordinary privileges
+ on database objects are. You must actually <command>SET ROLE</command> to a
+ specific role having one of these attributes in order to make use of
+ the attribute. Continuing the above example, we might choose to
+ grant <literal>CREATEDB</literal> and <literal>CREATEROLE</literal> to the
+ <literal>admin</literal> role. Then a session connecting as role <literal>joe</literal>
+ would not have these privileges immediately, only after doing
+ <command>SET ROLE admin</command>.
+ </para>
+
+ <para>
+ </para>
+
+ <para>
+ To destroy a group role, use <link
+ linkend="sql-droprole"><command>DROP ROLE</command></link>:
+<synopsis>
+DROP ROLE <replaceable>name</replaceable>;
+</synopsis>
+ Any memberships in the group role are automatically revoked (but the
+ member roles are not otherwise affected).
+ </para>
+ </sect1>
+
+ <sect1 id="role-removal">
+ <title>Dropping Roles</title>
+
+ <para>
+ Because roles can own database objects and can hold privileges
+ to access other objects, dropping a role is often not just a matter of a
+ quick <link linkend="sql-droprole"><command>DROP ROLE</command></link>. Any objects owned by the role must
+ first be dropped or reassigned to other owners; and any permissions
+ granted to the role must be revoked.
+ </para>
+
+ <para>
+ Ownership of objects can be transferred one at a time
+ using <command>ALTER</command> commands, for example:
+<programlisting>
+ALTER TABLE bobs_table OWNER TO alice;
+</programlisting>
+ Alternatively, the <link linkend="sql-reassign-owned"><command>REASSIGN OWNED</command></link> command can be
+ used to reassign ownership of all objects owned by the role-to-be-dropped
+ to a single other role. Because <command>REASSIGN OWNED</command> cannot access
+ objects in other databases, it is necessary to run it in each database
+ that contains objects owned by the role. (Note that the first
+ such <command>REASSIGN OWNED</command> will change the ownership of any
+ shared-across-databases objects, that is databases or tablespaces, that
+ are owned by the role-to-be-dropped.)
+ </para>
+
+ <para>
+ Once any valuable objects have been transferred to new owners, any
+ remaining objects owned by the role-to-be-dropped can be dropped with
+ the <link linkend="sql-drop-owned"><command>DROP OWNED</command></link> command. Again, this command cannot
+ access objects in other databases, so it is necessary to run it in each
+ database that contains objects owned by the role. Also, <command>DROP
+ OWNED</command> will not drop entire databases or tablespaces, so it is
+ necessary to do that manually if the role owns any databases or
+ tablespaces that have not been transferred to new owners.
+ </para>
+
+ <para>
+ <command>DROP OWNED</command> also takes care of removing any privileges granted
+ to the target role for objects that do not belong to it.
+ Because <command>REASSIGN OWNED</command> does not touch such objects, it's
+ typically necessary to run both <command>REASSIGN OWNED</command>
+ and <command>DROP OWNED</command> (in that order!) to fully remove the
+ dependencies of a role to be dropped.
+ </para>
+
+ <para>
+ In short then, the most general recipe for removing a role that has been
+ used to own objects is:
+ </para>
+<programlisting>
+REASSIGN OWNED BY doomed_role TO successor_role;
+DROP OWNED BY doomed_role;
+-- repeat the above commands in each database of the cluster
+DROP ROLE doomed_role;
+</programlisting>
+
+ <para>
+ When not all owned objects are to be transferred to the same successor
+ owner, it's best to handle the exceptions manually and then perform
+ the above steps to mop up.
+ </para>
+
+ <para>
+ If <command>DROP ROLE</command> is attempted while dependent objects still
+ remain, it will issue messages identifying which objects need to be
+ reassigned or dropped.
+ </para>
+ </sect1>
+
+ <sect1 id="predefined-roles">
+ <title>Predefined Roles</title>
+
+ <indexterm zone="predefined-roles">
+ <primary>role</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides a set of predefined roles
+ that provide access to certain, commonly needed, privileged capabilities
+ and information. Administrators (including roles that have the
+ <literal>CREATEROLE</literal> privilege) can <command>GRANT</command> these
+ roles to users and/or other roles in their environment, providing those
+ users with access to the specified capabilities and information.
+ </para>
+
+ <para>
+ The predefined roles are described in <xref linkend="predefined-roles-table"/>.
+ Note that the specific permissions for each of the roles may change in
+ the future as additional capabilities are added. Administrators
+ should monitor the release notes for changes.
+ </para>
+
+ <table tocentry="1" id="predefined-roles-table">
+ <title>Predefined Roles</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Role</entry>
+ <entry>Allowed Access</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>pg_read_all_data</entry>
+ <entry>Read all data (tables, views, sequences), as if having
+ <command>SELECT</command> rights on those objects, and USAGE rights on
+ all schemas, even without having it explicitly. This role does not have
+ the role attribute <literal>BYPASSRLS</literal> set. If RLS is being
+ used, an administrator may wish to set <literal>BYPASSRLS</literal> on
+ roles which this role is GRANTed to.</entry>
+ </row>
+ <row>
+ <entry>pg_write_all_data</entry>
+ <entry>Write all data (tables, views, sequences), as if having
+ <command>INSERT</command>, <command>UPDATE</command>, and
+ <command>DELETE</command> rights on those objects, and USAGE rights on
+ all schemas, even without having it explicitly. This role does not have
+ the role attribute <literal>BYPASSRLS</literal> set. If RLS is being
+ used, an administrator may wish to set <literal>BYPASSRLS</literal> on
+ roles which this role is GRANTed to.</entry>
+ </row>
+ <row>
+ <entry>pg_read_all_settings</entry>
+ <entry>Read all configuration variables, even those normally visible only to
+ superusers.</entry>
+ </row>
+ <row>
+ <entry>pg_read_all_stats</entry>
+ <entry>Read all pg_stat_* views and use various statistics related extensions,
+ even those normally visible only to superusers.</entry>
+ </row>
+ <row>
+ <entry>pg_stat_scan_tables</entry>
+ <entry>Execute monitoring functions that may take <literal>ACCESS SHARE</literal> locks on tables,
+ potentially for a long time.</entry>
+ </row>
+ <row>
+ <entry>pg_monitor</entry>
+ <entry>Read/execute various monitoring views and functions.
+ This role is a member of <literal>pg_read_all_settings</literal>,
+ <literal>pg_read_all_stats</literal> and
+ <literal>pg_stat_scan_tables</literal>.</entry>
+ </row>
+ <row>
+ <entry>pg_database_owner</entry>
+ <entry>None. Membership consists, implicitly, of the current database owner.</entry>
+ </row>
+ <row>
+ <entry>pg_signal_backend</entry>
+ <entry>Signal another backend to cancel a query or terminate its session.</entry>
+ </row>
+ <row>
+ <entry>pg_read_server_files</entry>
+ <entry>Allow reading files from any location the database can access on the server with COPY and
+ other file-access functions.</entry>
+ </row>
+ <row>
+ <entry>pg_write_server_files</entry>
+ <entry>Allow writing to files in any location the database can access on the server with COPY and
+ other file-access functions.</entry>
+ </row>
+ <row>
+ <entry>pg_execute_server_program</entry>
+ <entry>Allow executing programs on the database server as the user the database runs as with
+ COPY and other functions which allow executing a server-side program.</entry>
+ </row>
+ <row>
+ <entry>pg_checkpoint</entry>
+ <entry>Allow executing
+ the <link linkend="sql-checkpoint"><command>CHECKPOINT</command></link>
+ command.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <literal>pg_monitor</literal>, <literal>pg_read_all_settings</literal>,
+ <literal>pg_read_all_stats</literal> and <literal>pg_stat_scan_tables</literal>
+ roles are intended to allow administrators to easily configure a role for the
+ purpose of monitoring the database server. They grant a set of common privileges
+ allowing the role to read various useful configuration settings, statistics and
+ other system information normally restricted to superusers.
+ </para>
+
+ <para>
+ The <literal>pg_database_owner</literal> role has one implicit,
+ situation-dependent member, namely the owner of the current database. Like
+ any role, it can own objects or receive grants of access privileges.
+ Consequently, once <literal>pg_database_owner</literal> has rights within a
+ template database, each owner of a database instantiated from that template
+ will exercise those rights. <literal>pg_database_owner</literal> cannot be
+ a member of any role, and it cannot have non-implicit members. Initially,
+ this role owns the <literal>public</literal> schema, so each database owner
+ governs local use of the schema.
+ </para>
+
+ <para>
+ The <literal>pg_signal_backend</literal> role is intended to allow
+ administrators to enable trusted, but non-superuser, roles to send signals
+ to other backends. Currently this role enables sending of signals for
+ canceling a query on another backend or terminating its session. A user
+ granted this role cannot however send signals to a backend owned by a
+ superuser. See <xref linkend="functions-admin-signal"/>.
+ </para>
+
+ <para>
+ The <literal>pg_read_server_files</literal>, <literal>pg_write_server_files</literal> and
+ <literal>pg_execute_server_program</literal> roles are intended to allow administrators to have
+ trusted, but non-superuser, roles which are able to access files and run programs on the
+ database server as the user the database runs as. As these roles are able to access any file on
+ the server file system, they bypass all database-level permission checks when accessing files
+ directly and they could be used to gain superuser-level access, therefore
+ great care should be taken when granting these roles to users.
+ </para>
+
+ <para>
+ Care should be taken when granting these roles to ensure they are only used where
+ needed and with the understanding that these roles grant access to privileged
+ information.
+ </para>
+
+ <para>
+ Administrators can grant access to these roles to users using the
+ <link linkend="sql-grant"><command>GRANT</command></link> command, for example:
+
+<programlisting>
+GRANT pg_signal_backend TO admin_user;
+</programlisting>
+ </para>
+
+ </sect1>
+
+ <sect1 id="perm-functions">
+ <title>Function Security</title>
+
+ <para>
+ Functions, triggers and row-level security policies allow users to insert
+ code into the backend server that other users might execute
+ unintentionally. Hence, these mechanisms permit users to <quote>Trojan
+ horse</quote> others with relative ease. The strongest protection is tight
+ control over who can define objects. Where that is infeasible, write
+ queries referring only to objects having trusted owners. Remove
+ from <varname>search_path</varname> any schemas that permit untrusted users
+ to create objects.
+ </para>
+
+ <para>
+ Functions run inside the backend
+ server process with the operating system permissions of the
+ database server daemon. If the programming language
+ used for the function allows unchecked memory accesses, it is
+ possible to change the server's internal data structures.
+ Hence, among many other things, such functions can circumvent any
+ system access controls. Function languages that allow such access
+ are considered <quote>untrusted</quote>, and
+ <productname>PostgreSQL</productname> allows only superusers to
+ create functions written in those languages.
+ </para>
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/uuid-ossp.sgml b/doc/src/sgml/uuid-ossp.sgml
new file mode 100644
index 0000000..26bfb90
--- /dev/null
+++ b/doc/src/sgml/uuid-ossp.sgml
@@ -0,0 +1,242 @@
+<!-- doc/src/sgml/uuid-ossp.sgml -->
+
+<sect1 id="uuid-ossp" xreflabel="uuid-ossp">
+ <title>uuid-ossp</title>
+
+ <indexterm zone="uuid-ossp">
+ <primary>uuid-ossp</primary>
+ </indexterm>
+
+ <para>
+ The <filename>uuid-ossp</filename> module provides functions to generate universally
+ unique identifiers (UUIDs) using one of several standard algorithms. There
+ are also functions to produce certain special UUID constants.
+ This module is only necessary for special requirements beyond what is
+ available in core <productname>PostgreSQL</productname>. See <xref
+ linkend="functions-uuid"/> for built-in ways to generate UUIDs.
+ </para>
+
+ <para>
+ This module is considered <quote>trusted</quote>, that is, it can be
+ installed by non-superusers who have <literal>CREATE</literal> privilege
+ on the current database.
+ </para>
+
+ <sect2>
+ <title><literal>uuid-ossp</literal> Functions</title>
+
+ <para>
+ <xref linkend="uuid-ossp-functions"/> shows the functions available to
+ generate UUIDs.
+ The relevant standards ITU-T Rec. X.667, ISO/IEC 9834-8:2005, and
+ <ulink url="https://tools.ietf.org/html/rfc4122">RFC 4122</ulink>
+ specify four algorithms for generating UUIDs, identified by the
+ version numbers 1, 3, 4, and 5. (There is no version 2 algorithm.)
+ Each of these algorithms could be suitable for a different set of
+ applications.
+ </para>
+
+ <table id="uuid-ossp-functions">
+ <title>Functions for UUID Generation</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>uuid_generate_v1</primary></indexterm>
+ <function>uuid_generate_v1</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Generates a version 1 UUID. This involves the MAC
+ address of the computer and a time stamp. Note that UUIDs of this
+ kind reveal the identity of the computer that created the identifier
+ and the time at which it did so, which might make it unsuitable for
+ certain security-sensitive applications.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>uuid_generate_v1mc</primary></indexterm>
+ <function>uuid_generate_v1mc</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Generates a version 1 UUID, but uses a random multicast
+ MAC address instead of the real MAC address of the computer.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm><primary>uuid_generate_v3</primary></indexterm>
+ <function>uuid_generate_v3</function> ( <parameter>namespace</parameter> <type>uuid</type>, <parameter>name</parameter> <type>text</type> )
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Generates a version 3 UUID in the given namespace using
+ the specified input name. The namespace should be one of the special
+ constants produced by the <function>uuid_ns_*()</function> functions
+ shown in <xref linkend="uuid-ossp-constants"/>. (It could be any UUID
+ in theory.) The name is an identifier in the selected namespace.
+ </para>
+ <para>
+ For example:
+
+<programlisting>
+SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org');
+</programlisting>
+
+ The name parameter will be MD5-hashed, so the cleartext cannot be
+ derived from the generated UUID.
+ The generation of UUIDs by this method has no random or
+ environment-dependent element and is therefore reproducible.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_generate_v4</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Generates a version 4 UUID, which is derived entirely
+ from random numbers.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_generate_v5</function> ( <parameter>namespace</parameter> <type>uuid</type>, <parameter>name</parameter> <type>text</type> )
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Generates a version 5 UUID, which works like a version 3
+ UUID except that SHA-1 is used as a hashing method. Version 5 should
+ be preferred over version 3 because SHA-1 is thought to be more secure
+ than MD5.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table id="uuid-ossp-constants">
+ <title>Functions Returning UUID Constants</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_nil</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Returns a <quote>nil</quote> UUID constant, which does not occur as a
+ real UUID.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_ns_dns</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Returns a constant designating the DNS namespace for UUIDs.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_ns_url</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Returns a constant designating the URL namespace for UUIDs.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_ns_oid</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Returns a constant designating the ISO object identifier (OID) namespace for
+ UUIDs. (This pertains to ASN.1 OIDs, which are unrelated to the OIDs
+ used in <productname>PostgreSQL</productname>.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>uuid_ns_x500</function> ()
+ <returnvalue>uuid</returnvalue>
+ </para>
+ <para>
+ Returns a constant designating the X.500 distinguished name (DN)
+ namespace for UUIDs.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title>Building <filename>uuid-ossp</filename></title>
+
+ <para>
+ Historically this module depended on the OSSP UUID library, which accounts
+ for the module's name. While the OSSP UUID library can still be found
+ at <ulink url="http://www.ossp.org/pkg/lib/uuid/"></ulink>, it is not well
+ maintained, and is becoming increasingly difficult to port to newer
+ platforms. <filename>uuid-ossp</filename> can now be built without the OSSP
+ library on some platforms. On FreeBSD and some other BSD-derived
+ platforms, suitable UUID creation functions are included in the
+ core <filename>libc</filename> library. On Linux, macOS, and some other
+ platforms, suitable functions are provided in the <filename>libuuid</filename>
+ library, which originally came from the <literal>e2fsprogs</literal> project
+ (though on modern Linux it is considered part
+ of <literal>util-linux-ng</literal>). When invoking <filename>configure</filename>,
+ specify <option>--with-uuid=bsd</option> to use the BSD functions,
+ or <option>--with-uuid=e2fs</option> to
+ use <literal>e2fsprogs</literal>' <filename>libuuid</filename>, or
+ <option>--with-uuid=ossp</option> to use the OSSP UUID library.
+ More than one of these libraries might be available on a particular
+ machine, so <filename>configure</filename> does not automatically choose one.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ Peter Eisentraut <email>peter_e@gmx.net</email>
+ </para>
+
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/vacuumlo.sgml b/doc/src/sgml/vacuumlo.sgml
new file mode 100644
index 0000000..26b764d
--- /dev/null
+++ b/doc/src/sgml/vacuumlo.sgml
@@ -0,0 +1,231 @@
+<!-- doc/src/sgml/vacuumlo.sgml -->
+
+<refentry id="vacuumlo">
+ <indexterm zone="vacuumlo">
+ <primary>vacuumlo</primary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle><application>vacuumlo</application></refentrytitle>
+ <manvolnum>1</manvolnum>
+ <refmiscinfo>Application</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>vacuumlo</refname>
+ <refpurpose>remove orphaned large objects from a <productname>PostgreSQL</productname> database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>vacuumlo</command>
+ <arg choice="opt" rep="repeat"><replaceable>option</replaceable></arg>
+ <arg choice="plain" rep="repeat"><replaceable>dbname</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <application>vacuumlo</application> is a simple utility program that will remove any
+ <quote>orphaned</quote> large objects from a
+ <productname>PostgreSQL</productname> database. An orphaned large object (LO) is
+ considered to be any LO whose OID does not appear in any <type>oid</type> or
+ <type>lo</type> data column of the database.
+ </para>
+
+ <para>
+ If you use this, you may also be interested in the <function>lo_manage</function>
+ trigger in the <xref linkend="lo"/> module.
+ <function>lo_manage</function> is useful to try
+ to avoid creating orphaned LOs in the first place.
+ </para>
+
+ <para>
+ All databases named on the command line are processed.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Options</title>
+
+ <para>
+ <application>vacuumlo</application> accepts the following command-line arguments:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-l <replaceable class="parameter">limit</replaceable></option></term>
+ <term><option>--limit=<replaceable class="parameter">limit</replaceable></option></term>
+ <listitem>
+ <para>
+ Remove no more than <replaceable>limit</replaceable> large objects per
+ transaction (default 1000). Since the server acquires a lock per LO
+ removed, removing too many LOs in one transaction risks exceeding
+ <xref linkend="guc-max-locks-per-transaction"/>. Set the limit to
+ zero if you want all removals done in a single transaction.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-n</option></term>
+ <term><option>--dry-run</option></term>
+ <listitem>
+ <para>Don't remove anything, just show what would be done.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-v</option></term>
+ <term><option>--verbose</option></term>
+ <listitem>
+ <para>Write a lot of progress messages.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-V</option></term>
+ <term><option>--version</option></term>
+ <listitem>
+ <para>
+ Print the <application>vacuumlo</application> version and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-?</option></term>
+ <term><option>--help</option></term>
+ <listitem>
+ <para>
+ Show help about <application>vacuumlo</application> command line
+ arguments, and exit.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ <application>vacuumlo</application> also accepts the following command-line
+ arguments for connection parameters:
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
+ <term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
+ <listitem>
+ <para>Database server's host.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-p <replaceable>port</replaceable></option></term>
+ <term><option>--port=<replaceable class="parameter">port</replaceable></option></term>
+ <listitem>
+ <para>Database server's port.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-U <replaceable>username</replaceable></option></term>
+ <term><option>--username=<replaceable class="parameter">username</replaceable></option></term>
+ <listitem>
+ <para>User name to connect as.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-w</option></term>
+ <term><option>--no-password</option></term>
+ <listitem>
+ <para>
+ Never issue a password prompt. If the server requires password
+ authentication and a password is not available by other means
+ such as a <filename>.pgpass</filename> file, the connection
+ attempt will fail. This option can be useful in batch jobs and
+ scripts where no user is present to enter a password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>-W</option></term>
+ <term><option>--password</option></term>
+ <listitem>
+ <para>
+ Force <application>vacuumlo</application> to prompt for a
+ password before connecting to a database.
+ </para>
+
+ <para>
+ This option is never essential, since
+ <application>vacuumlo</application> will automatically prompt
+ for a password if the server demands password authentication.
+ However, <application>vacuumlo</application> will waste a
+ connection attempt finding out that the server wants a password.
+ In some cases it is worth typing <option>-W</option> to avoid the extra
+ connection attempt.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Environment</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><envar>PGHOST</envar></term>
+ <term><envar>PGPORT</envar></term>
+ <term><envar>PGUSER</envar></term>
+
+ <listitem>
+ <para>
+ Default connection parameters.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ This utility, like most other <productname>PostgreSQL</productname> utilities,
+ also uses the environment variables supported by <application>libpq</application>
+ (see <xref linkend="libpq-envars"/>).
+ </para>
+
+ <para>
+ The environment variable <envar>PG_COLOR</envar> specifies whether to use
+ color in diagnostic messages. Possible values are
+ <literal>always</literal>, <literal>auto</literal> and
+ <literal>never</literal>.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Notes</title>
+
+ <para>
+ <application>vacuumlo</application> works by the following method:
+ First, <application>vacuumlo</application> builds a temporary table which contains all
+ of the OIDs of the large objects in the selected database. It then scans
+ through all columns in the database that are of type
+ <type>oid</type> or <type>lo</type>, and removes matching entries from the temporary
+ table. (Note: Only types with these names are considered; in particular,
+ domains over them are not considered.) The remaining entries in the
+ temporary table identify orphaned LOs. These are removed.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Author</title>
+
+ <para>
+ Peter Mount <email>peter@retep.org.uk</email>
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml
new file mode 100644
index 0000000..27fb020
--- /dev/null
+++ b/doc/src/sgml/wal.sgml
@@ -0,0 +1,911 @@
+<!-- doc/src/sgml/wal.sgml -->
+
+<chapter id="wal">
+ <title>Reliability and the Write-Ahead Log</title>
+
+ <para>
+ This chapter explains how the Write-Ahead Log is used to obtain
+ efficient, reliable operation.
+ </para>
+
+ <sect1 id="wal-reliability">
+ <title>Reliability</title>
+
+ <para>
+ Reliability is an important property of any serious database
+ system, and <productname>PostgreSQL</productname> does everything possible to
+ guarantee reliable operation. One aspect of reliable operation is
+ that all data recorded by a committed transaction should be stored
+ in a nonvolatile area that is safe from power loss, operating
+ system failure, and hardware failure (except failure of the
+ nonvolatile area itself, of course). Successfully writing the data
+ to the computer's permanent storage (disk drive or equivalent)
+ ordinarily meets this requirement. In fact, even if a computer is
+ fatally damaged, if the disk drives survive they can be moved to
+ another computer with similar hardware and all committed
+ transactions will remain intact.
+ </para>
+
+ <para>
+ While forcing data to the disk platters periodically might seem like
+ a simple operation, it is not. Because disk drives are dramatically
+ slower than main memory and CPUs, several layers of caching exist
+ between the computer's main memory and the disk platters.
+ First, there is the operating system's buffer cache, which caches
+ frequently requested disk blocks and combines disk writes. Fortunately,
+ all operating systems give applications a way to force writes from
+ the buffer cache to disk, and <productname>PostgreSQL</productname> uses those
+ features. (See the <xref linkend="guc-wal-sync-method"/> parameter
+ to adjust how this is done.)
+ </para>
+
+ <para>
+ Next, there might be a cache in the disk drive controller; this is
+ particularly common on <acronym>RAID</acronym> controller cards. Some of
+ these caches are <firstterm>write-through</firstterm>, meaning writes are sent
+ to the drive as soon as they arrive. Others are
+ <firstterm>write-back</firstterm>, meaning data is sent to the drive at
+ some later time. Such caches can be a reliability hazard because the
+ memory in the disk controller cache is volatile, and will lose its
+ contents in a power failure. Better controller cards have
+ <firstterm>battery-backup units</firstterm> (<acronym>BBU</acronym>s), meaning
+ the card has a battery that
+ maintains power to the cache in case of system power loss. After power
+ is restored the data will be written to the disk drives.
+ </para>
+
+ <para>
+ And finally, most disk drives have caches. Some are write-through
+ while some are write-back, and the same concerns about data loss
+ exist for write-back drive caches as for disk controller
+ caches. Consumer-grade IDE and SATA drives are particularly likely
+ to have write-back caches that will not survive a power failure. Many
+ solid-state drives (SSD) also have volatile write-back caches.
+ </para>
+
+ <para>
+ These caches can typically be disabled; however, the method for doing
+ this varies by operating system and drive type:
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ On <productname>Linux</productname>, IDE and SATA drives can be queried using
+ <command>hdparm -I</command>; write caching is enabled if there is
+ a <literal>*</literal> next to <literal>Write cache</literal>. <command>hdparm -W 0</command>
+ can be used to turn off write caching. SCSI drives can be queried
+ using <ulink url="http://sg.danny.cz/sg/sdparm.html"><application>sdparm</application></ulink>.
+ Use <command>sdparm --get=WCE</command> to check
+ whether the write cache is enabled and <command>sdparm --clear=WCE</command>
+ to disable it.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>FreeBSD</productname>, IDE drives can be queried using
+ <command>atacontrol</command> and write caching turned off using
+ <literal>hw.ata.wc=0</literal> in <filename>/boot/loader.conf</filename>;
+ SCSI drives can be queried using <command>camcontrol identify</command>,
+ and the write cache both queried and changed using
+ <command>sdparm</command> when available.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>Solaris</productname>, the disk write cache is controlled by
+ <command>format -e</command>.
+ (The Solaris <acronym>ZFS</acronym> file system is safe with disk write-cache
+ enabled because it issues its own disk cache flush commands.)
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>Windows</productname>, if <varname>wal_sync_method</varname> is
+ <literal>open_datasync</literal> (the default), write caching can be disabled
+ by unchecking <literal>My Computer\Open\<replaceable>disk drive</replaceable>\Properties\Hardware\Properties\Policies\Enable write caching on the disk</literal>.
+ Alternatively, set <varname>wal_sync_method</varname> to
+ <literal>fsync</literal> or <literal>fsync_writethrough</literal>, which prevent
+ write caching.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ On <productname>macOS</productname>, write caching can be prevented by
+ setting <varname>wal_sync_method</varname> to <literal>fsync_writethrough</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ Recent SATA drives (those following <acronym>ATAPI-6</acronym> or later)
+ offer a drive cache flush command (<command>FLUSH CACHE EXT</command>),
+ while SCSI drives have long supported a similar command
+ <command>SYNCHRONIZE CACHE</command>. These commands are not directly
+ accessible to <productname>PostgreSQL</productname>, but some file systems
+ (e.g., <acronym>ZFS</acronym>, <acronym>ext4</acronym>) can use them to flush
+ data to the platters on write-back-enabled drives. Unfortunately, such
+ file systems behave suboptimally when combined with battery-backup unit
+ (<acronym>BBU</acronym>) disk controllers. In such setups, the synchronize
+ command forces all data from the controller cache to the disks,
+ eliminating much of the benefit of the BBU. You can run the
+ <xref linkend="pgtestfsync"/> program to see
+ if you are affected. If you are affected, the performance benefits
+ of the BBU can be regained by turning off write barriers in
+ the file system or reconfiguring the disk controller, if that is
+ an option. If write barriers are turned off, make sure the battery
+ remains functional; a faulty battery can potentially lead to data loss.
+ Hopefully file system and disk controller designers will eventually
+ address this suboptimal behavior.
+ </para>
+
+ <para>
+ When the operating system sends a write request to the storage hardware,
+ there is little it can do to make sure the data has arrived at a truly
+ non-volatile storage area. Rather, it is the
+ administrator's responsibility to make certain that all storage components
+ ensure integrity for both data and file-system metadata.
+ Avoid disk controllers that have non-battery-backed write caches.
+ At the drive level, disable write-back caching if the
+ drive cannot guarantee the data will be written before shutdown.
+ If you use SSDs, be aware that many of these do not honor cache flush
+ commands by default.
+ You can test for reliable I/O subsystem behavior using <ulink
+ url="https://brad.livejournal.com/2116715.html"><filename>diskchecker.pl</filename></ulink>.
+ </para>
+
+ <para>
+ Another risk of data loss is posed by the disk platter write
+ operations themselves. Disk platters are divided into sectors,
+ commonly 512 bytes each. Every physical read or write operation
+ processes a whole sector.
+ When a write request arrives at the drive, it might be for some multiple
+ of 512 bytes (<productname>PostgreSQL</productname> typically writes 8192 bytes, or
+ 16 sectors, at a time), and the process of writing could fail due
+ to power loss at any time, meaning some of the 512-byte sectors were
+ written while others were not. To guard against such failures,
+ <productname>PostgreSQL</productname> periodically writes full page images to
+ permanent WAL storage <emphasis>before</emphasis> modifying the actual page on
+ disk. By doing this, during crash recovery <productname>PostgreSQL</productname> can
+ restore partially-written pages from WAL. If you have file-system software
+ that prevents partial page writes (e.g., ZFS), you can turn off
+ this page imaging by turning off the <xref
+ linkend="guc-full-page-writes"/> parameter. Battery-Backed Unit
+ (BBU) disk controllers do not prevent partial page writes unless
+ they guarantee that data is written to the BBU as full (8kB) pages.
+ </para>
+ <para>
+ <productname>PostgreSQL</productname> also protects against some kinds of data corruption
+ on storage devices that may occur because of hardware errors or media failure over time,
+ such as reading/writing garbage data.
+ <itemizedlist>
+ <listitem>
+ <para>
+ Each individual record in a WAL file is protected by a CRC-32 (32-bit) check
+ that allows us to tell if record contents are correct. The CRC value
+ is set when we write each WAL record and checked during crash recovery,
+ archive recovery and replication.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Data pages are not currently checksummed by default, though full page images
+ recorded in WAL records will be protected; see <link
+ linkend="app-initdb-data-checksums"><application>initdb</application></link>
+ for details about enabling data checksums.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Internal data structures such as <filename>pg_xact</filename>, <filename>pg_subtrans</filename>, <filename>pg_multixact</filename>,
+ <filename>pg_serial</filename>, <filename>pg_notify</filename>, <filename>pg_stat</filename>, <filename>pg_snapshots</filename> are not directly
+ checksummed, nor are pages protected by full page writes. However, where
+ such data structures are persistent, WAL records are written that allow
+ recent changes to be accurately rebuilt at crash recovery and those
+ WAL records are protected as discussed above.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Individual state files in <filename>pg_twophase</filename> are protected by CRC-32.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Temporary data files used in larger SQL queries for sorts,
+ materializations and intermediate results are not currently checksummed,
+ nor will WAL records be written for changes to those files.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ <productname>PostgreSQL</productname> does not protect against correctable memory errors
+ and it is assumed you will operate using RAM that uses industry standard
+ Error Correcting Codes (ECC) or better protection.
+ </para>
+ </sect1>
+
+ <sect1 id="checksums">
+ <title>Data Checksums</title>
+ <indexterm>
+ <primary>checksums</primary>
+ </indexterm>
+
+ <para>
+ By default, data pages are not protected by checksums, but this can
+ optionally be enabled for a cluster. When enabled, each data page includes
+ a checksum that is updated when the page is written and verified each time
+ the page is read. Only data pages are protected by checksums; internal data
+ structures and temporary files are not.
+ </para>
+
+ <para>
+ Checksums are normally enabled when the cluster is initialized using <link
+ linkend="app-initdb-data-checksums"><application>initdb</application></link>.
+ They can also be enabled or disabled at a later time as an offline
+ operation. Data checksums are enabled or disabled at the full cluster
+ level, and cannot be specified individually for databases or tables.
+ </para>
+
+ <para>
+ The current state of checksums in the cluster can be verified by viewing the
+ value of the read-only configuration variable <xref
+ linkend="guc-data-checksums" /> by issuing the command <command>SHOW
+ data_checksums</command>.
+ </para>
+
+ <para>
+ When attempting to recover from page corruptions, it may be necessary to
+ bypass the checksum protection. To do this, temporarily set the
+ configuration parameter <xref linkend="guc-ignore-checksum-failure" />.
+ </para>
+
+ <sect2 id="checksums-offline-enable-disable">
+ <title>Off-line Enabling of Checksums</title>
+
+ <para>
+ The <link linkend="app-pgchecksums"><application>pg_checksums</application></link>
+ application can be used to enable or disable data checksums, as well as
+ verify checksums, on an offline cluster.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="wal-intro">
+ <title>Write-Ahead Logging (<acronym>WAL</acronym>)</title>
+
+ <indexterm zone="wal">
+ <primary>WAL</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>transaction log</primary>
+ <see>WAL</see>
+ </indexterm>
+
+ <para>
+ <firstterm>Write-Ahead Logging</firstterm> (<acronym>WAL</acronym>)
+ is a standard method for ensuring data integrity. A detailed
+ description can be found in most (if not all) books about
+ transaction processing. Briefly, <acronym>WAL</acronym>'s central
+ concept is that changes to data files (where tables and indexes
+ reside) must be written only after those changes have been logged,
+ that is, after log records describing the changes have been flushed
+ to permanent storage. If we follow this procedure, we do not need
+ to flush data pages to disk on every transaction commit, because we
+ know that in the event of a crash we will be able to recover the
+ database using the log: any changes that have not been applied to
+ the data pages can be redone from the log records. (This is
+ roll-forward recovery, also known as REDO.)
+ </para>
+
+ <tip>
+ <para>
+ Because <acronym>WAL</acronym> restores database file
+ contents after a crash, journaled file systems are not necessary for
+ reliable storage of the data files or WAL files. In fact, journaling
+ overhead can reduce performance, especially if journaling
+ causes file system <emphasis>data</emphasis> to be flushed
+ to disk. Fortunately, data flushing during journaling can
+ often be disabled with a file system mount option, e.g.,
+ <literal>data=writeback</literal> on a Linux ext3 file system.
+ Journaled file systems do improve boot speed after a crash.
+ </para>
+ </tip>
+
+
+ <para>
+ Using <acronym>WAL</acronym> results in a
+ significantly reduced number of disk writes, because only the log
+ file needs to be flushed to disk to guarantee that a transaction is
+ committed, rather than every data file changed by the transaction.
+ The log file is written sequentially,
+ and so the cost of syncing the log is much less than the cost of
+ flushing the data pages. This is especially true for servers
+ handling many small transactions touching different parts of the data
+ store. Furthermore, when the server is processing many small concurrent
+ transactions, one <function>fsync</function> of the log file may
+ suffice to commit many transactions.
+ </para>
+
+ <para>
+ <acronym>WAL</acronym> also makes it possible to support on-line
+ backup and point-in-time recovery, as described in <xref
+ linkend="continuous-archiving"/>. By archiving the WAL data we can support
+ reverting to any time instant covered by the available WAL data:
+ we simply install a prior physical backup of the database, and
+ replay the WAL log just as far as the desired time. What's more,
+ the physical backup doesn't have to be an instantaneous snapshot
+ of the database state &mdash; if it is made over some period of time,
+ then replaying the WAL log for that period will fix any internal
+ inconsistencies.
+ </para>
+ </sect1>
+
+ <sect1 id="wal-async-commit">
+ <title>Asynchronous Commit</title>
+
+ <indexterm>
+ <primary>synchronous commit</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>asynchronous commit</primary>
+ </indexterm>
+
+ <para>
+ <firstterm>Asynchronous commit</firstterm> is an option that allows transactions
+ to complete more quickly, at the cost that the most recent transactions may
+ be lost if the database should crash. In many applications this is an
+ acceptable trade-off.
+ </para>
+
+ <para>
+ As described in the previous section, transaction commit is normally
+ <firstterm>synchronous</firstterm>: the server waits for the transaction's
+ <acronym>WAL</acronym> records to be flushed to permanent storage
+ before returning a success indication to the client. The client is
+ therefore guaranteed that a transaction reported to be committed will
+ be preserved, even in the event of a server crash immediately after.
+ However, for short transactions this delay is a major component of the
+ total transaction time. Selecting asynchronous commit mode means that
+ the server returns success as soon as the transaction is logically
+ completed, before the <acronym>WAL</acronym> records it generated have
+ actually made their way to disk. This can provide a significant boost
+ in throughput for small transactions.
+ </para>
+
+ <para>
+ Asynchronous commit introduces the risk of data loss. There is a short
+ time window between the report of transaction completion to the client
+ and the time that the transaction is truly committed (that is, it is
+ guaranteed not to be lost if the server crashes). Thus asynchronous
+ commit should not be used if the client will take external actions
+ relying on the assumption that the transaction will be remembered.
+ As an example, a bank would certainly not use asynchronous commit for
+ a transaction recording an ATM's dispensing of cash. But in many
+ scenarios, such as event logging, there is no need for a strong
+ guarantee of this kind.
+ </para>
+
+ <para>
+ The risk that is taken by using asynchronous commit is of data loss,
+ not data corruption. If the database should crash, it will recover
+ by replaying <acronym>WAL</acronym> up to the last record that was
+ flushed. The database will therefore be restored to a self-consistent
+ state, but any transactions that were not yet flushed to disk will
+ not be reflected in that state. The net effect is therefore loss of
+ the last few transactions. Because the transactions are replayed in
+ commit order, no inconsistency can be introduced &mdash; for example,
+ if transaction B made changes relying on the effects of a previous
+ transaction A, it is not possible for A's effects to be lost while B's
+ effects are preserved.
+ </para>
+
+ <para>
+ The user can select the commit mode of each transaction, so that
+ it is possible to have both synchronous and asynchronous commit
+ transactions running concurrently. This allows flexible trade-offs
+ between performance and certainty of transaction durability.
+ The commit mode is controlled by the user-settable parameter
+ <xref linkend="guc-synchronous-commit"/>, which can be changed in any of
+ the ways that a configuration parameter can be set. The mode used for
+ any one transaction depends on the value of
+ <varname>synchronous_commit</varname> when transaction commit begins.
+ </para>
+
+ <para>
+ Certain utility commands, for instance <command>DROP TABLE</command>, are
+ forced to commit synchronously regardless of the setting of
+ <varname>synchronous_commit</varname>. This is to ensure consistency
+ between the server's file system and the logical state of the database.
+ The commands supporting two-phase commit, such as <command>PREPARE
+ TRANSACTION</command>, are also always synchronous.
+ </para>
+
+ <para>
+ If the database crashes during the risk window between an
+ asynchronous commit and the writing of the transaction's
+ <acronym>WAL</acronym> records,
+ then changes made during that transaction <emphasis>will</emphasis> be lost.
+ The duration of the
+ risk window is limited because a background process (the <quote>WAL
+ writer</quote>) flushes unwritten <acronym>WAL</acronym> records to disk
+ every <xref linkend="guc-wal-writer-delay"/> milliseconds.
+ The actual maximum duration of the risk window is three times
+ <varname>wal_writer_delay</varname> because the WAL writer is
+ designed to favor writing whole pages at a time during busy periods.
+ </para>
+
+ <caution>
+ <para>
+ An immediate-mode shutdown is equivalent to a server crash, and will
+ therefore cause loss of any unflushed asynchronous commits.
+ </para>
+ </caution>
+
+ <para>
+ Asynchronous commit provides behavior different from setting
+ <xref linkend="guc-fsync"/> = off.
+ <varname>fsync</varname> is a server-wide
+ setting that will alter the behavior of all transactions. It disables
+ all logic within <productname>PostgreSQL</productname> that attempts to synchronize
+ writes to different portions of the database, and therefore a system
+ crash (that is, a hardware or operating system crash, not a failure of
+ <productname>PostgreSQL</productname> itself) could result in arbitrarily bad
+ corruption of the database state. In many scenarios, asynchronous
+ commit provides most of the performance improvement that could be
+ obtained by turning off <varname>fsync</varname>, but without the risk
+ of data corruption.
+ </para>
+
+ <para>
+ <xref linkend="guc-commit-delay"/> also sounds very similar to
+ asynchronous commit, but it is actually a synchronous commit method
+ (in fact, <varname>commit_delay</varname> is ignored during an
+ asynchronous commit). <varname>commit_delay</varname> causes a delay
+ just before a transaction flushes <acronym>WAL</acronym> to disk, in
+ the hope that a single flush executed by one such transaction can also
+ serve other transactions committing at about the same time. The
+ setting can be thought of as a way of increasing the time window in
+ which transactions can join a group about to participate in a single
+ flush, to amortize the cost of the flush among multiple transactions.
+ </para>
+
+ </sect1>
+
+ <sect1 id="wal-configuration">
+ <title><acronym>WAL</acronym> Configuration</title>
+
+ <para>
+ There are several <acronym>WAL</acronym>-related configuration parameters that
+ affect database performance. This section explains their use.
+ Consult <xref linkend="runtime-config"/> for general information about
+ setting server configuration parameters.
+ </para>
+
+ <para>
+ <firstterm>Checkpoints</firstterm><indexterm><primary>checkpoint</primary></indexterm>
+ are points in the sequence of transactions at which it is guaranteed
+ that the heap and index data files have been updated with all
+ information written before that checkpoint. At checkpoint time, all
+ dirty data pages are flushed to disk and a special checkpoint record is
+ written to the log file. (The change records were previously flushed
+ to the <acronym>WAL</acronym> files.)
+ In the event of a crash, the crash recovery procedure looks at the latest
+ checkpoint record to determine the point in the log (known as the redo
+ record) from which it should start the REDO operation. Any changes made to
+ data files before that point are guaranteed to be already on disk.
+ Hence, after a checkpoint, log segments preceding the one containing
+ the redo record are no longer needed and can be recycled or removed. (When
+ <acronym>WAL</acronym> archiving is being done, the log segments must be
+ archived before being recycled or removed.)
+ </para>
+
+ <para>
+ The checkpoint requirement of flushing all dirty data pages to disk
+ can cause a significant I/O load. For this reason, checkpoint
+ activity is throttled so that I/O begins at checkpoint start and completes
+ before the next checkpoint is due to start; this minimizes performance
+ degradation during checkpoints.
+ </para>
+
+ <para>
+ The server's checkpointer process automatically performs
+ a checkpoint every so often. A checkpoint is begun every <xref
+ linkend="guc-checkpoint-timeout"/> seconds, or if
+ <xref linkend="guc-max-wal-size"/> is about to be exceeded,
+ whichever comes first.
+ The default settings are 5 minutes and 1 GB, respectively.
+ If no WAL has been written since the previous checkpoint, new checkpoints
+ will be skipped even if <varname>checkpoint_timeout</varname> has passed.
+ (If WAL archiving is being used and you want to put a lower limit on how
+ often files are archived in order to bound potential data loss, you should
+ adjust the <xref linkend="guc-archive-timeout"/> parameter rather than the
+ checkpoint parameters.)
+ It is also possible to force a checkpoint by using the SQL
+ command <command>CHECKPOINT</command>.
+ </para>
+
+ <para>
+ Reducing <varname>checkpoint_timeout</varname> and/or
+ <varname>max_wal_size</varname> causes checkpoints to occur
+ more often. This allows faster after-crash recovery, since less work
+ will need to be redone. However, one must balance this against the
+ increased cost of flushing dirty data pages more often. If
+ <xref linkend="guc-full-page-writes"/> is set (as is the default), there is
+ another factor to consider. To ensure data page consistency,
+ the first modification of a data page after each checkpoint results in
+ logging the entire page content. In that case,
+ a smaller checkpoint interval increases the volume of output to the WAL log,
+ partially negating the goal of using a smaller interval,
+ and in any case causing more disk I/O.
+ </para>
+
+ <para>
+ Checkpoints are fairly expensive, first because they require writing
+ out all currently dirty buffers, and second because they result in
+ extra subsequent WAL traffic as discussed above. It is therefore
+ wise to set the checkpointing parameters high enough so that checkpoints
+ don't happen too often. As a simple sanity check on your checkpointing
+ parameters, you can set the <xref linkend="guc-checkpoint-warning"/>
+ parameter. If checkpoints happen closer together than
+ <varname>checkpoint_warning</varname> seconds,
+ a message will be output to the server log recommending increasing
+ <varname>max_wal_size</varname>. Occasional appearance of such
+ a message is not cause for alarm, but if it appears often then the
+ checkpoint control parameters should be increased. Bulk operations such
+ as large <command>COPY</command> transfers might cause a number of such warnings
+ to appear if you have not set <varname>max_wal_size</varname> high
+ enough.
+ </para>
+
+ <para>
+ To avoid flooding the I/O system with a burst of page writes,
+ writing dirty buffers during a checkpoint is spread over a period of time.
+ That period is controlled by
+ <xref linkend="guc-checkpoint-completion-target"/>, which is
+ given as a fraction of the checkpoint interval (configured by using
+ <varname>checkpoint_timeout</varname>).
+ The I/O rate is adjusted so that the checkpoint finishes when the
+ given fraction of
+ <varname>checkpoint_timeout</varname> seconds have elapsed, or before
+ <varname>max_wal_size</varname> is exceeded, whichever is sooner.
+ With the default value of 0.9,
+ <productname>PostgreSQL</productname> can be expected to complete each checkpoint
+ a bit before the next scheduled checkpoint (at around 90% of the last checkpoint's
+ duration). This spreads out the I/O as much as possible so that the checkpoint
+ I/O load is consistent throughout the checkpoint interval. The disadvantage of
+ this is that prolonging checkpoints affects recovery time, because more WAL
+ segments will need to be kept around for possible use in recovery. A user
+ concerned about the amount of time required to recover might wish to reduce
+ <varname>checkpoint_timeout</varname> so that checkpoints occur more frequently
+ but still spread the I/O across the checkpoint interval. Alternatively,
+ <varname>checkpoint_completion_target</varname> could be reduced, but this would
+ result in times of more intense I/O (during the checkpoint) and times of less I/O
+ (after the checkpoint completed but before the next scheduled checkpoint) and
+ therefore is not recommended.
+ Although <varname>checkpoint_completion_target</varname> could be set as high as
+ 1.0, it is typically recommended to set it to no higher than 0.9 (the default)
+ since checkpoints include some other activities besides writing dirty buffers.
+ A setting of 1.0 is quite likely to result in checkpoints not being
+ completed on time, which would result in performance loss due to
+ unexpected variation in the number of WAL segments needed.
+ </para>
+
+ <para>
+ On Linux and POSIX platforms <xref linkend="guc-checkpoint-flush-after"/>
+ allows to force the OS that pages written by the checkpoint should be
+ flushed to disk after a configurable number of bytes. Otherwise, these
+ pages may be kept in the OS's page cache, inducing a stall when
+ <literal>fsync</literal> is issued at the end of a checkpoint. This setting will
+ often help to reduce transaction latency, but it also can have an adverse
+ effect on performance; particularly for workloads that are bigger than
+ <xref linkend="guc-shared-buffers"/>, but smaller than the OS's page cache.
+ </para>
+
+ <para>
+ The number of WAL segment files in <filename>pg_wal</filename> directory depends on
+ <varname>min_wal_size</varname>, <varname>max_wal_size</varname> and
+ the amount of WAL generated in previous checkpoint cycles. When old log
+ segment files are no longer needed, they are removed or recycled (that is,
+ renamed to become future segments in the numbered sequence). If, due to a
+ short-term peak of log output rate, <varname>max_wal_size</varname> is
+ exceeded, the unneeded segment files will be removed until the system
+ gets back under this limit. Below that limit, the system recycles enough
+ WAL files to cover the estimated need until the next checkpoint, and
+ removes the rest. The estimate is based on a moving average of the number
+ of WAL files used in previous checkpoint cycles. The moving average
+ is increased immediately if the actual usage exceeds the estimate, so it
+ accommodates peak usage rather than average usage to some extent.
+ <varname>min_wal_size</varname> puts a minimum on the amount of WAL files
+ recycled for future usage; that much WAL is always recycled for future use,
+ even if the system is idle and the WAL usage estimate suggests that little
+ WAL is needed.
+ </para>
+
+ <para>
+ Independently of <varname>max_wal_size</varname>,
+ the most recent <xref linkend="guc-wal-keep-size"/> megabytes of
+ WAL files plus one additional WAL file are
+ kept at all times. Also, if WAL archiving is used, old segments cannot be
+ removed or recycled until they are archived. If WAL archiving cannot keep up
+ with the pace that WAL is generated, or if <varname>archive_command</varname>
+ or <varname>archive_library</varname>
+ fails repeatedly, old WAL files will accumulate in <filename>pg_wal</filename>
+ until the situation is resolved. A slow or failed standby server that
+ uses a replication slot will have the same effect (see
+ <xref linkend="streaming-replication-slots"/>).
+ </para>
+
+ <para>
+ In archive recovery or standby mode, the server periodically performs
+ <firstterm>restartpoints</firstterm>,<indexterm><primary>restartpoint</primary></indexterm>
+ which are similar to checkpoints in normal operation: the server forces
+ all its state to disk, updates the <filename>pg_control</filename> file to
+ indicate that the already-processed WAL data need not be scanned again,
+ and then recycles any old log segment files in the <filename>pg_wal</filename>
+ directory.
+ Restartpoints can't be performed more frequently than checkpoints on the
+ primary because restartpoints can only be performed at checkpoint records.
+ A restartpoint is triggered when a checkpoint record is reached if at
+ least <varname>checkpoint_timeout</varname> seconds have passed since the last
+ restartpoint, or if WAL size is about to exceed
+ <varname>max_wal_size</varname>. However, because of limitations on when a
+ restartpoint can be performed, <varname>max_wal_size</varname> is often exceeded
+ during recovery, by up to one checkpoint cycle's worth of WAL.
+ (<varname>max_wal_size</varname> is never a hard limit anyway, so you should
+ always leave plenty of headroom to avoid running out of disk space.)
+ </para>
+
+ <para>
+ There are two commonly used internal <acronym>WAL</acronym> functions:
+ <function>XLogInsertRecord</function> and <function>XLogFlush</function>.
+ <function>XLogInsertRecord</function> is used to place a new record into
+ the <acronym>WAL</acronym> buffers in shared memory. If there is no
+ space for the new record, <function>XLogInsertRecord</function> will have
+ to write (move to kernel cache) a few filled <acronym>WAL</acronym>
+ buffers. This is undesirable because <function>XLogInsertRecord</function>
+ is used on every database low level modification (for example, row
+ insertion) at a time when an exclusive lock is held on affected
+ data pages, so the operation needs to be as fast as possible. What
+ is worse, writing <acronym>WAL</acronym> buffers might also force the
+ creation of a new log segment, which takes even more
+ time. Normally, <acronym>WAL</acronym> buffers should be written
+ and flushed by an <function>XLogFlush</function> request, which is
+ made, for the most part, at transaction commit time to ensure that
+ transaction records are flushed to permanent storage. On systems
+ with high log output, <function>XLogFlush</function> requests might
+ not occur often enough to prevent <function>XLogInsertRecord</function>
+ from having to do writes. On such systems
+ one should increase the number of <acronym>WAL</acronym> buffers by
+ modifying the <xref linkend="guc-wal-buffers"/> parameter. When
+ <xref linkend="guc-full-page-writes"/> is set and the system is very busy,
+ setting <varname>wal_buffers</varname> higher will help smooth response times
+ during the period immediately following each checkpoint.
+ </para>
+
+ <para>
+ The <xref linkend="guc-commit-delay"/> parameter defines for how many
+ microseconds a group commit leader process will sleep after acquiring a
+ lock within <function>XLogFlush</function>, while group commit
+ followers queue up behind the leader. This delay allows other server
+ processes to add their commit records to the WAL buffers so that all of
+ them will be flushed by the leader's eventual sync operation. No sleep
+ will occur if <xref linkend="guc-fsync"/> is not enabled, or if fewer
+ than <xref linkend="guc-commit-siblings"/> other sessions are currently
+ in active transactions; this avoids sleeping when it's unlikely that
+ any other session will commit soon. Note that on some platforms, the
+ resolution of a sleep request is ten milliseconds, so that any nonzero
+ <varname>commit_delay</varname> setting between 1 and 10000
+ microseconds would have the same effect. Note also that on some
+ platforms, sleep operations may take slightly longer than requested by
+ the parameter.
+ </para>
+
+ <para>
+ Since the purpose of <varname>commit_delay</varname> is to allow the
+ cost of each flush operation to be amortized across concurrently
+ committing transactions (potentially at the expense of transaction
+ latency), it is necessary to quantify that cost before the setting can
+ be chosen intelligently. The higher that cost is, the more effective
+ <varname>commit_delay</varname> is expected to be in increasing
+ transaction throughput, up to a point. The <xref
+ linkend="pgtestfsync"/> program can be used to measure the average time
+ in microseconds that a single WAL flush operation takes. A value of
+ half of the average time the program reports it takes to flush after a
+ single 8kB write operation is often the most effective setting for
+ <varname>commit_delay</varname>, so this value is recommended as the
+ starting point to use when optimizing for a particular workload. While
+ tuning <varname>commit_delay</varname> is particularly useful when the
+ WAL log is stored on high-latency rotating disks, benefits can be
+ significant even on storage media with very fast sync times, such as
+ solid-state drives or RAID arrays with a battery-backed write cache;
+ but this should definitely be tested against a representative workload.
+ Higher values of <varname>commit_siblings</varname> should be used in
+ such cases, whereas smaller <varname>commit_siblings</varname> values
+ are often helpful on higher latency media. Note that it is quite
+ possible that a setting of <varname>commit_delay</varname> that is too
+ high can increase transaction latency by so much that total transaction
+ throughput suffers.
+ </para>
+
+ <para>
+ When <varname>commit_delay</varname> is set to zero (the default), it
+ is still possible for a form of group commit to occur, but each group
+ will consist only of sessions that reach the point where they need to
+ flush their commit records during the window in which the previous
+ flush operation (if any) is occurring. At higher client counts a
+ <quote>gangway effect</quote> tends to occur, so that the effects of group
+ commit become significant even when <varname>commit_delay</varname> is
+ zero, and thus explicitly setting <varname>commit_delay</varname> tends
+ to help less. Setting <varname>commit_delay</varname> can only help
+ when (1) there are some concurrently committing transactions, and (2)
+ throughput is limited to some degree by commit rate; but with high
+ rotational latency this setting can be effective in increasing
+ transaction throughput with as few as two clients (that is, a single
+ committing client with one sibling transaction).
+ </para>
+
+ <para>
+ The <xref linkend="guc-wal-sync-method"/> parameter determines how
+ <productname>PostgreSQL</productname> will ask the kernel to force
+ <acronym>WAL</acronym> updates out to disk.
+ All the options should be the same in terms of reliability, with
+ the exception of <literal>fsync_writethrough</literal>, which can sometimes
+ force a flush of the disk cache even when other options do not do so.
+ However, it's quite platform-specific which one will be the fastest.
+ You can test the speeds of different options using the <xref
+ linkend="pgtestfsync"/> program.
+ Note that this parameter is irrelevant if <varname>fsync</varname>
+ has been turned off.
+ </para>
+
+ <para>
+ Enabling the <xref linkend="guc-wal-debug"/> configuration parameter
+ (provided that <productname>PostgreSQL</productname> has been
+ compiled with support for it) will result in each
+ <function>XLogInsertRecord</function> and <function>XLogFlush</function>
+ <acronym>WAL</acronym> call being logged to the server log. This
+ option might be replaced by a more general mechanism in the future.
+ </para>
+
+ <para>
+ There are two internal functions to write WAL data to disk:
+ <function>XLogWrite</function> and <function>issue_xlog_fsync</function>.
+ When <xref linkend="guc-track-wal-io-timing"/> is enabled, the total
+ amounts of time <function>XLogWrite</function> writes and
+ <function>issue_xlog_fsync</function> syncs WAL data to disk are counted as
+ <literal>wal_write_time</literal> and <literal>wal_sync_time</literal> in
+ <xref linkend="pg-stat-wal-view"/>, respectively.
+ <function>XLogWrite</function> is normally called by
+ <function>XLogInsertRecord</function> (when there is no space for the new
+ record in WAL buffers), <function>XLogFlush</function> and the WAL writer,
+ to write WAL buffers to disk and call <function>issue_xlog_fsync</function>.
+ <function>issue_xlog_fsync</function> is normally called by
+ <function>XLogWrite</function> to sync WAL files to disk.
+ If <varname>wal_sync_method</varname> is either
+ <literal>open_datasync</literal> or <literal>open_sync</literal>,
+ a write operation in <function>XLogWrite</function> guarantees to sync written
+ WAL data to disk and <function>issue_xlog_fsync</function> does nothing.
+ If <varname>wal_sync_method</varname> is either <literal>fdatasync</literal>,
+ <literal>fsync</literal>, or <literal>fsync_writethrough</literal>,
+ the write operation moves WAL buffers to kernel cache and
+ <function>issue_xlog_fsync</function> syncs them to disk. Regardless
+ of the setting of <varname>track_wal_io_timing</varname>, the number
+ of times <function>XLogWrite</function> writes and
+ <function>issue_xlog_fsync</function> syncs WAL data to disk are also
+ counted as <literal>wal_write</literal> and <literal>wal_sync</literal>
+ in <structname>pg_stat_wal</structname>, respectively.
+ </para>
+
+ <para>
+ The <xref linkend="guc-recovery-prefetch"/> parameter can be used to reduce
+ I/O wait times during recovery by instructing the kernel to initiate reads
+ of disk blocks that will soon be needed but are not currently in
+ <productname>PostgreSQL</productname>'s buffer pool.
+ The <xref linkend="guc-maintenance-io-concurrency"/> and
+ <xref linkend="guc-wal-decode-buffer-size"/> settings limit prefetching
+ concurrency and distance, respectively. By default, it is set to
+ <literal>try</literal>, which enables the feature on systems where
+ <function>posix_fadvise</function> is available.
+ </para>
+ </sect1>
+
+ <sect1 id="wal-internals">
+ <title>WAL Internals</title>
+
+ <indexterm zone="wal-internals">
+ <primary>LSN</primary>
+ </indexterm>
+
+ <para>
+ <acronym>WAL</acronym> is automatically enabled; no action is
+ required from the administrator except ensuring that the
+ disk-space requirements for the <acronym>WAL</acronym> logs are met,
+ and that any necessary tuning is done (see <xref
+ linkend="wal-configuration"/>).
+ </para>
+
+ <para>
+ <acronym>WAL</acronym> records are appended to the <acronym>WAL</acronym>
+ logs as each new record is written. The insert position is described by
+ a Log Sequence Number (<acronym>LSN</acronym>) that is a byte offset into
+ the logs, increasing monotonically with each new record.
+ <acronym>LSN</acronym> values are returned as the datatype
+ <link linkend="datatype-pg-lsn"><type>pg_lsn</type></link>. Values can be
+ compared to calculate the volume of <acronym>WAL</acronym> data that
+ separates them, so they are used to measure the progress of replication
+ and recovery.
+ </para>
+
+ <para>
+ <acronym>WAL</acronym> logs are stored in the directory
+ <filename>pg_wal</filename> under the data directory, as a set of
+ segment files, normally each 16 MB in size (but the size can be changed
+ by altering the <option>--wal-segsize</option> <application>initdb</application> option). Each segment is
+ divided into pages, normally 8 kB each (this size can be changed via the
+ <option>--with-wal-blocksize</option> configure option). The log record headers
+ are described in <filename>access/xlogrecord.h</filename>; the record
+ content is dependent on the type of event that is being logged. Segment
+ files are given ever-increasing numbers as names, starting at
+ <filename>000000010000000000000001</filename>. The numbers do not wrap,
+ but it will take a very, very long time to exhaust the
+ available stock of numbers.
+ </para>
+
+ <para>
+ It is advantageous if the log is located on a different disk from the
+ main database files. This can be achieved by moving the
+ <filename>pg_wal</filename> directory to another location (while the server
+ is shut down, of course) and creating a symbolic link from the
+ original location in the main data directory to the new location.
+ </para>
+
+ <para>
+ The aim of <acronym>WAL</acronym> is to ensure that the log is
+ written before database records are altered, but this can be subverted by
+ disk drives<indexterm><primary>disk drive</primary></indexterm> that falsely report a
+ successful write to the kernel,
+ when in fact they have only cached the data and not yet stored it
+ on the disk. A power failure in such a situation might lead to
+ irrecoverable data corruption. Administrators should try to ensure
+ that disks holding <productname>PostgreSQL</productname>'s
+ <acronym>WAL</acronym> log files do not make such false reports.
+ (See <xref linkend="wal-reliability"/>.)
+ </para>
+
+ <para>
+ After a checkpoint has been made and the log flushed, the
+ checkpoint's position is saved in the file
+ <filename>pg_control</filename>. Therefore, at the start of recovery,
+ the server first reads <filename>pg_control</filename> and
+ then the checkpoint record; then it performs the REDO operation by
+ scanning forward from the log location indicated in the checkpoint
+ record. Because the entire content of data pages is saved in the
+ log on the first page modification after a checkpoint (assuming
+ <xref linkend="guc-full-page-writes"/> is not disabled), all pages
+ changed since the checkpoint will be restored to a consistent
+ state.
+ </para>
+
+ <para>
+ To deal with the case where <filename>pg_control</filename> is
+ corrupt, we should support the possibility of scanning existing log
+ segments in reverse order &mdash; newest to oldest &mdash; in order to find the
+ latest checkpoint. This has not been implemented yet.
+ <filename>pg_control</filename> is small enough (less than one disk page)
+ that it is not subject to partial-write problems, and as of this writing
+ there have been no reports of database failures due solely to the inability
+ to read <filename>pg_control</filename> itself. So while it is
+ theoretically a weak spot, <filename>pg_control</filename> does not
+ seem to be a problem in practice.
+ </para>
+ </sect1>
+</chapter>
diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml
new file mode 100644
index 0000000..bdad8d3
--- /dev/null
+++ b/doc/src/sgml/xaggr.sgml
@@ -0,0 +1,670 @@
+<!-- doc/src/sgml/xaggr.sgml -->
+
+ <sect1 id="xaggr">
+ <title>User-Defined Aggregates</title>
+
+ <indexterm zone="xaggr">
+ <primary>aggregate function</primary>
+ <secondary>user-defined</secondary>
+ </indexterm>
+
+ <para>
+ Aggregate functions in <productname>PostgreSQL</productname>
+ are defined in terms of <firstterm>state values</firstterm>
+ and <firstterm>state transition functions</firstterm>.
+ That is, an aggregate operates using a state value that is updated
+ as each successive input row is processed.
+ To define a new aggregate
+ function, one selects a data type for the state value,
+ an initial value for the state, and a state transition
+ function. The state transition function takes the previous state
+ value and the aggregate's input value(s) for the current row, and
+ returns a new state value.
+ A <firstterm>final function</firstterm>
+ can also be specified, in case the desired result of the aggregate
+ is different from the data that needs to be kept in the running
+ state value. The final function takes the ending state value
+ and returns whatever is wanted as the aggregate result.
+ In principle, the transition and final functions are just ordinary
+ functions that could also be used outside the context of the
+ aggregate. (In practice, it's often helpful for performance reasons
+ to create specialized transition functions that can only work when
+ called as part of an aggregate.)
+ </para>
+
+ <para>
+ Thus, in addition to the argument and result data types seen by a user
+ of the aggregate, there is an internal state-value data type that
+ might be different from both the argument and result types.
+ </para>
+
+ <para>
+ If we define an aggregate that does not use a final function,
+ we have an aggregate that computes a running function of
+ the column values from each row. <function>sum</function> is an
+ example of this kind of aggregate. <function>sum</function> starts at
+ zero and always adds the current row's value to
+ its running total. For example, if we want to make a <function>sum</function>
+ aggregate to work on a data type for complex numbers,
+ we only need the addition function for that data type.
+ The aggregate definition would be:
+
+<programlisting>
+CREATE AGGREGATE sum (complex)
+(
+ sfunc = complex_add,
+ stype = complex,
+ initcond = '(0,0)'
+);
+</programlisting>
+
+ which we might use like this:
+
+<programlisting>
+SELECT sum(a) FROM test_complex;
+
+ sum
+-----------
+ (34,53.9)
+</programlisting>
+
+ (Notice that we are relying on function overloading: there is more than
+ one aggregate named <function>sum</function>, but
+ <productname>PostgreSQL</productname> can figure out which kind
+ of sum applies to a column of type <type>complex</type>.)
+ </para>
+
+ <para>
+ The above definition of <function>sum</function> will return zero
+ (the initial state value) if there are no nonnull input values.
+ Perhaps we want to return null in that case instead &mdash; the SQL standard
+ expects <function>sum</function> to behave that way. We can do this simply by
+ omitting the <literal>initcond</literal> phrase, so that the initial state
+ value is null. Ordinarily this would mean that the <literal>sfunc</literal>
+ would need to check for a null state-value input. But for
+ <function>sum</function> and some other simple aggregates like
+ <function>max</function> and <function>min</function>,
+ it is sufficient to insert the first nonnull input value into
+ the state variable and then start applying the transition function
+ at the second nonnull input value. <productname>PostgreSQL</productname>
+ will do that automatically if the initial state value is null and
+ the transition function is marked <quote>strict</quote> (i.e., not to be called
+ for null inputs).
+ </para>
+
+ <para>
+ Another bit of default behavior for a <quote>strict</quote> transition function
+ is that the previous state value is retained unchanged whenever a
+ null input value is encountered. Thus, null values are ignored. If you
+ need some other behavior for null inputs, do not declare your
+ transition function as strict; instead code it to test for null inputs and
+ do whatever is needed.
+ </para>
+
+ <para>
+ <function>avg</function> (average) is a more complex example of an aggregate.
+ It requires
+ two pieces of running state: the sum of the inputs and the count
+ of the number of inputs. The final result is obtained by dividing
+ these quantities. Average is typically implemented by using an
+ array as the state value. For example,
+ the built-in implementation of <function>avg(float8)</function>
+ looks like:
+
+<programlisting>
+CREATE AGGREGATE avg (float8)
+(
+ sfunc = float8_accum,
+ stype = float8[],
+ finalfunc = float8_avg,
+ initcond = '{0,0,0}'
+);
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ <function>float8_accum</function> requires a three-element array, not just
+ two elements, because it accumulates the sum of squares as well as
+ the sum and count of the inputs. This is so that it can be used for
+ some other aggregates as well as <function>avg</function>.
+ </para>
+ </note>
+
+ <para>
+ Aggregate function calls in SQL allow <literal>DISTINCT</literal>
+ and <literal>ORDER BY</literal> options that control which rows are fed
+ to the aggregate's transition function and in what order. These
+ options are implemented behind the scenes and are not the concern
+ of the aggregate's support functions.
+ </para>
+
+ <para>
+ For further details see the
+ <xref linkend="sql-createaggregate"/>
+ command.
+ </para>
+
+ <sect2 id="xaggr-moving-aggregates">
+ <title>Moving-Aggregate Mode</title>
+
+ <indexterm>
+ <primary>moving-aggregate mode</primary>
+ </indexterm>
+
+ <indexterm>
+ <primary>aggregate function</primary>
+ <secondary>moving aggregate</secondary>
+ </indexterm>
+
+ <para>
+ Aggregate functions can optionally support <firstterm>moving-aggregate
+ mode</firstterm>, which allows substantially faster execution of aggregate
+ functions within windows with moving frame starting points.
+ (See <xref linkend="tutorial-window"/>
+ and <xref linkend="syntax-window-functions"/> for information about use of
+ aggregate functions as window functions.)
+ The basic idea is that in addition to a normal <quote>forward</quote>
+ transition function, the aggregate provides an <firstterm>inverse
+ transition function</firstterm>, which allows rows to be removed from the
+ aggregate's running state value when they exit the window frame.
+ For example a <function>sum</function> aggregate, which uses addition as the
+ forward transition function, would use subtraction as the inverse
+ transition function. Without an inverse transition function, the window
+ function mechanism must recalculate the aggregate from scratch each time
+ the frame starting point moves, resulting in run time proportional to the
+ number of input rows times the average frame length. With an inverse
+ transition function, the run time is only proportional to the number of
+ input rows.
+ </para>
+
+ <para>
+ The inverse transition function is passed the current state value and the
+ aggregate input value(s) for the earliest row included in the current
+ state. It must reconstruct what the state value would have been if the
+ given input row had never been aggregated, but only the rows following
+ it. This sometimes requires that the forward transition function keep
+ more state than is needed for plain aggregation mode. Therefore, the
+ moving-aggregate mode uses a completely separate implementation from the
+ plain mode: it has its own state data type, its own forward transition
+ function, and its own final function if needed. These can be the same as
+ the plain mode's data type and functions, if there is no need for extra
+ state.
+ </para>
+
+ <para>
+ As an example, we could extend the <function>sum</function> aggregate given above
+ to support moving-aggregate mode like this:
+
+<programlisting>
+CREATE AGGREGATE sum (complex)
+(
+ sfunc = complex_add,
+ stype = complex,
+ initcond = '(0,0)',
+ msfunc = complex_add,
+ minvfunc = complex_sub,
+ mstype = complex,
+ minitcond = '(0,0)'
+);
+</programlisting>
+
+ The parameters whose names begin with <literal>m</literal> define the
+ moving-aggregate implementation. Except for the inverse transition
+ function <literal>minvfunc</literal>, they correspond to the plain-aggregate
+ parameters without <literal>m</literal>.
+ </para>
+
+ <para>
+ The forward transition function for moving-aggregate mode is not allowed
+ to return null as the new state value. If the inverse transition
+ function returns null, this is taken as an indication that the inverse
+ function cannot reverse the state calculation for this particular input,
+ and so the aggregate calculation will be redone from scratch for the
+ current frame starting position. This convention allows moving-aggregate
+ mode to be used in situations where there are some infrequent cases that
+ are impractical to reverse out of the running state value. The inverse
+ transition function can <quote>punt</quote> on these cases, and yet still come
+ out ahead so long as it can work for most cases. As an example, an
+ aggregate working with floating-point numbers might choose to punt when
+ a <literal>NaN</literal> (not a number) input has to be removed from the running
+ state value.
+ </para>
+
+ <para>
+ When writing moving-aggregate support functions, it is important to be
+ sure that the inverse transition function can reconstruct the correct
+ state value exactly. Otherwise there might be user-visible differences
+ in results depending on whether the moving-aggregate mode is used.
+ An example of an aggregate for which adding an inverse transition
+ function seems easy at first, yet where this requirement cannot be met
+ is <function>sum</function> over <type>float4</type> or <type>float8</type> inputs. A
+ naive declaration of <function>sum(<type>float8</type>)</function> could be
+
+<programlisting>
+CREATE AGGREGATE unsafe_sum (float8)
+(
+ stype = float8,
+ sfunc = float8pl,
+ mstype = float8,
+ msfunc = float8pl,
+ minvfunc = float8mi
+);
+</programlisting>
+
+ This aggregate, however, can give wildly different results than it would
+ have without the inverse transition function. For example, consider
+
+<programlisting>
+SELECT
+ unsafe_sum(x) OVER (ORDER BY n ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING)
+FROM (VALUES (1, 1.0e20::float8),
+ (2, 1.0::float8)) AS v (n,x);
+</programlisting>
+
+ This query returns <literal>0</literal> as its second result, rather than the
+ expected answer of <literal>1</literal>. The cause is the limited precision of
+ floating-point values: adding <literal>1</literal> to <literal>1e20</literal> results
+ in <literal>1e20</literal> again, and so subtracting <literal>1e20</literal> from that
+ yields <literal>0</literal>, not <literal>1</literal>. Note that this is a limitation
+ of floating-point arithmetic in general, not a limitation
+ of <productname>PostgreSQL</productname>.
+ </para>
+
+ </sect2>
+
+ <sect2 id="xaggr-polymorphic-aggregates">
+ <title>Polymorphic and Variadic Aggregates</title>
+
+ <indexterm>
+ <primary>aggregate function</primary>
+ <secondary>polymorphic</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>aggregate function</primary>
+ <secondary>variadic</secondary>
+ </indexterm>
+
+ <para>
+ Aggregate functions can use polymorphic
+ state transition functions or final functions, so that the same functions
+ can be used to implement multiple aggregates.
+ See <xref linkend="extend-types-polymorphic"/>
+ for an explanation of polymorphic functions.
+ Going a step further, the aggregate function itself can be specified
+ with polymorphic input type(s) and state type, allowing a single
+ aggregate definition to serve for multiple input data types.
+ Here is an example of a polymorphic aggregate:
+
+<programlisting>
+CREATE AGGREGATE array_accum (anycompatible)
+(
+ sfunc = array_append,
+ stype = anycompatiblearray,
+ initcond = '{}'
+);
+</programlisting>
+
+ Here, the actual state type for any given aggregate call is the array type
+ having the actual input type as elements. The behavior of the aggregate
+ is to concatenate all the inputs into an array of that type.
+ (Note: the built-in aggregate <function>array_agg</function> provides similar
+ functionality, with better performance than this definition would have.)
+ </para>
+
+ <para>
+ Here's the output using two different actual data types as arguments:
+
+<programlisting>
+SELECT attrelid::regclass, array_accum(attname)
+ FROM pg_attribute
+ WHERE attnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
+ GROUP BY attrelid;
+
+ attrelid | array_accum
+---------------+---------------------------------------
+ pg_tablespace | {spcname,spcowner,spcacl,spcoptions}
+(1 row)
+
+SELECT attrelid::regclass, array_accum(atttypid::regtype)
+ FROM pg_attribute
+ WHERE attnum &gt; 0 AND attrelid = 'pg_tablespace'::regclass
+ GROUP BY attrelid;
+
+ attrelid | array_accum
+---------------+---------------------------
+ pg_tablespace | {name,oid,aclitem[],text[]}
+(1 row)
+</programlisting>
+ </para>
+
+ <para>
+ Ordinarily, an aggregate function with a polymorphic result type has a
+ polymorphic state type, as in the above example. This is necessary
+ because otherwise the final function cannot be declared sensibly: it
+ would need to have a polymorphic result type but no polymorphic argument
+ type, which <command>CREATE FUNCTION</command> will reject on the grounds that
+ the result type cannot be deduced from a call. But sometimes it is
+ inconvenient to use a polymorphic state type. The most common case is
+ where the aggregate support functions are to be written in C and the
+ state type should be declared as <type>internal</type> because there is
+ no SQL-level equivalent for it. To address this case, it is possible to
+ declare the final function as taking extra <quote>dummy</quote> arguments
+ that match the input arguments of the aggregate. Such dummy arguments
+ are always passed as null values since no specific value is available when the
+ final function is called. Their only use is to allow a polymorphic
+ final function's result type to be connected to the aggregate's input
+ type(s). For example, the definition of the built-in
+ aggregate <function>array_agg</function> is equivalent to
+
+<programlisting>
+CREATE FUNCTION array_agg_transfn(internal, anynonarray)
+ RETURNS internal ...;
+CREATE FUNCTION array_agg_finalfn(internal, anynonarray)
+ RETURNS anyarray ...;
+
+CREATE AGGREGATE array_agg (anynonarray)
+(
+ sfunc = array_agg_transfn,
+ stype = internal,
+ finalfunc = array_agg_finalfn,
+ finalfunc_extra
+);
+</programlisting>
+
+ Here, the <literal>finalfunc_extra</literal> option specifies that the final
+ function receives, in addition to the state value, extra dummy
+ argument(s) corresponding to the aggregate's input argument(s).
+ The extra <type>anynonarray</type> argument allows the declaration
+ of <function>array_agg_finalfn</function> to be valid.
+ </para>
+
+ <para>
+ An aggregate function can be made to accept a varying number of arguments
+ by declaring its last argument as a <literal>VARIADIC</literal> array, in much
+ the same fashion as for regular functions; see
+ <xref linkend="xfunc-sql-variadic-functions"/>. The aggregate's transition
+ function(s) must have the same array type as their last argument. The
+ transition function(s) typically would also be marked <literal>VARIADIC</literal>,
+ but this is not strictly required.
+ </para>
+
+ <note>
+ <para>
+ Variadic aggregates are easily misused in connection with
+ the <literal>ORDER BY</literal> option (see <xref linkend="syntax-aggregates"/>),
+ since the parser cannot tell whether the wrong number of actual arguments
+ have been given in such a combination. Keep in mind that everything to
+ the right of <literal>ORDER BY</literal> is a sort key, not an argument to the
+ aggregate. For example, in
+<programlisting>
+SELECT myaggregate(a ORDER BY a, b, c) FROM ...
+</programlisting>
+ the parser will see this as a single aggregate function argument and
+ three sort keys. However, the user might have intended
+<programlisting>
+SELECT myaggregate(a, b, c ORDER BY a) FROM ...
+</programlisting>
+ If <literal>myaggregate</literal> is variadic, both these calls could be
+ perfectly valid.
+ </para>
+
+ <para>
+ For the same reason, it's wise to think twice before creating aggregate
+ functions with the same names and different numbers of regular arguments.
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2 id="xaggr-ordered-set-aggregates">
+ <title>Ordered-Set Aggregates</title>
+
+ <indexterm>
+ <primary>aggregate function</primary>
+ <secondary>ordered set</secondary>
+ </indexterm>
+
+ <para>
+ The aggregates we have been describing so far are <quote>normal</quote>
+ aggregates. <productname>PostgreSQL</productname> also
+ supports <firstterm>ordered-set aggregates</firstterm>, which differ from
+ normal aggregates in two key ways. First, in addition to ordinary
+ aggregated arguments that are evaluated once per input row, an
+ ordered-set aggregate can have <quote>direct</quote> arguments that are
+ evaluated only once per aggregation operation. Second, the syntax
+ for the ordinary aggregated arguments specifies a sort ordering
+ for them explicitly. An ordered-set aggregate is usually
+ used to implement a computation that depends on a specific row
+ ordering, for instance rank or percentile, so that the sort ordering
+ is a required aspect of any call. For example, the built-in
+ definition of <function>percentile_disc</function> is equivalent to:
+
+<programlisting>
+CREATE FUNCTION ordered_set_transition(internal, anyelement)
+ RETURNS internal ...;
+CREATE FUNCTION percentile_disc_final(internal, float8, anyelement)
+ RETURNS anyelement ...;
+
+CREATE AGGREGATE percentile_disc (float8 ORDER BY anyelement)
+(
+ sfunc = ordered_set_transition,
+ stype = internal,
+ finalfunc = percentile_disc_final,
+ finalfunc_extra
+);
+</programlisting>
+
+ This aggregate takes a <type>float8</type> direct argument (the percentile
+ fraction) and an aggregated input that can be of any sortable data type.
+ It could be used to obtain a median household income like this:
+
+<programlisting>
+SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households;
+ percentile_disc
+-----------------
+ 50489
+</programlisting>
+
+ Here, <literal>0.5</literal> is a direct argument; it would make no sense
+ for the percentile fraction to be a value varying across rows.
+ </para>
+
+ <para>
+ Unlike the case for normal aggregates, the sorting of input rows for
+ an ordered-set aggregate is <emphasis>not</emphasis> done behind the scenes,
+ but is the responsibility of the aggregate's support functions.
+ The typical implementation approach is to keep a reference to
+ a <quote>tuplesort</quote> object in the aggregate's state value, feed the
+ incoming rows into that object, and then complete the sorting and
+ read out the data in the final function. This design allows the
+ final function to perform special operations such as injecting
+ additional <quote>hypothetical</quote> rows into the data to be sorted.
+ While normal aggregates can often be implemented with support
+ functions written in <application>PL/pgSQL</application> or another
+ PL language, ordered-set aggregates generally have to be written in
+ C, since their state values aren't definable as any SQL data type.
+ (In the above example, notice that the state value is declared as
+ type <type>internal</type> &mdash; this is typical.)
+ Also, because the final function performs the sort, it is not possible
+ to continue adding input rows by executing the transition function again
+ later. This means the final function is not <literal>READ_ONLY</literal>;
+ it must be declared in <link linkend="sql-createaggregate"><command>CREATE AGGREGATE</command></link>
+ as <literal>READ_WRITE</literal>, or as <literal>SHAREABLE</literal> if
+ it's possible for additional final-function calls to make use of the
+ already-sorted state.
+ </para>
+
+ <para>
+ The state transition function for an ordered-set aggregate receives
+ the current state value plus the aggregated input values for
+ each row, and returns the updated state value. This is the
+ same definition as for normal aggregates, but note that the direct
+ arguments (if any) are not provided. The final function receives
+ the last state value, the values of the direct arguments if any,
+ and (if <literal>finalfunc_extra</literal> is specified) null values
+ corresponding to the aggregated input(s). As with normal
+ aggregates, <literal>finalfunc_extra</literal> is only really useful if the
+ aggregate is polymorphic; then the extra dummy argument(s) are needed
+ to connect the final function's result type to the aggregate's input
+ type(s).
+ </para>
+
+ <para>
+ Currently, ordered-set aggregates cannot be used as window functions,
+ and therefore there is no need for them to support moving-aggregate mode.
+ </para>
+
+ </sect2>
+
+ <sect2 id="xaggr-partial-aggregates">
+ <title>Partial Aggregation</title>
+
+ <indexterm>
+ <primary>aggregate function</primary>
+ <secondary>partial aggregation</secondary>
+ </indexterm>
+
+ <para>
+ Optionally, an aggregate function can support <firstterm>partial
+ aggregation</firstterm>. The idea of partial aggregation is to run the aggregate's
+ state transition function over different subsets of the input data
+ independently, and then to combine the state values resulting from those
+ subsets to produce the same state value that would have resulted from
+ scanning all the input in a single operation. This mode can be used for
+ parallel aggregation by having different worker processes scan different
+ portions of a table. Each worker produces a partial state value, and at
+ the end those state values are combined to produce a final state value.
+ (In the future this mode might also be used for purposes such as combining
+ aggregations over local and remote tables; but that is not implemented
+ yet.)
+ </para>
+
+ <para>
+ To support partial aggregation, the aggregate definition must provide
+ a <firstterm>combine function</firstterm>, which takes two values of the
+ aggregate's state type (representing the results of aggregating over two
+ subsets of the input rows) and produces a new value of the state type,
+ representing what the state would have been after aggregating over the
+ combination of those sets of rows. It is unspecified what the relative
+ order of the input rows from the two sets would have been. This means
+ that it's usually impossible to define a useful combine function for
+ aggregates that are sensitive to input row order.
+ </para>
+
+ <para>
+ As simple examples, <literal>MAX</literal> and <literal>MIN</literal> aggregates can be
+ made to support partial aggregation by specifying the combine function as
+ the same greater-of-two or lesser-of-two comparison function that is used
+ as their transition function. <literal>SUM</literal> aggregates just need an
+ addition function as combine function. (Again, this is the same as their
+ transition function, unless the state value is wider than the input data
+ type.)
+ </para>
+
+ <para>
+ The combine function is treated much like a transition function that
+ happens to take a value of the state type, not of the underlying input
+ type, as its second argument. In particular, the rules for dealing
+ with null values and strict functions are similar. Also, if the aggregate
+ definition specifies a non-null <literal>initcond</literal>, keep in mind that
+ that will be used not only as the initial state for each partial
+ aggregation run, but also as the initial state for the combine function,
+ which will be called to combine each partial result into that state.
+ </para>
+
+ <para>
+ If the aggregate's state type is declared as <type>internal</type>, it is
+ the combine function's responsibility that its result is allocated in
+ the correct memory context for aggregate state values. This means in
+ particular that when the first input is <literal>NULL</literal> it's invalid
+ to simply return the second input, as that value will be in the wrong
+ context and will not have sufficient lifespan.
+ </para>
+
+ <para>
+ When the aggregate's state type is declared as <type>internal</type>, it is
+ usually also appropriate for the aggregate definition to provide a
+ <firstterm>serialization function</firstterm> and a <firstterm>deserialization
+ function</firstterm>, which allow such a state value to be copied from one process
+ to another. Without these functions, parallel aggregation cannot be
+ performed, and future applications such as local/remote aggregation will
+ probably not work either.
+ </para>
+
+ <para>
+ A serialization function must take a single argument of
+ type <type>internal</type> and return a result of type <type>bytea</type>, which
+ represents the state value packaged up into a flat blob of bytes.
+ Conversely, a deserialization function reverses that conversion. It must
+ take two arguments of types <type>bytea</type> and <type>internal</type>, and
+ return a result of type <type>internal</type>. (The second argument is unused
+ and is always zero, but it is required for type-safety reasons.) The
+ result of the deserialization function should simply be allocated in the
+ current memory context, as unlike the combine function's result, it is not
+ long-lived.
+ </para>
+
+ <para>
+ Worth noting also is that for an aggregate to be executed in parallel,
+ the aggregate itself must be marked <literal>PARALLEL SAFE</literal>. The
+ parallel-safety markings on its support functions are not consulted.
+ </para>
+
+ </sect2>
+
+ <sect2 id="xaggr-support-functions">
+ <title>Support Functions for Aggregates</title>
+
+ <indexterm>
+ <primary>aggregate function</primary>
+ <secondary>support functions for</secondary>
+ </indexterm>
+
+ <para>
+ A function written in C can detect that it is being called as an
+ aggregate support function by calling
+ <function>AggCheckCallContext</function>, for example:
+<programlisting>
+if (AggCheckCallContext(fcinfo, NULL))
+</programlisting>
+ One reason for checking this is that when it is true, the first input
+ must be a temporary state value and can therefore safely be modified
+ in-place rather than allocating a new copy.
+ See <function>int8inc()</function> for an example.
+ (While aggregate transition functions are always allowed to modify
+ the transition value in-place, aggregate final functions are generally
+ discouraged from doing so; if they do so, the behavior must be declared
+ when creating the aggregate. See <xref linkend="sql-createaggregate"/>
+ for more detail.)
+ </para>
+
+ <para>
+ The second argument of <function>AggCheckCallContext</function> can be used to
+ retrieve the memory context in which aggregate state values are being kept.
+ This is useful for transition functions that wish to use <quote>expanded</quote>
+ objects (see <xref linkend="xtypes-toast"/>) as their state values.
+ On first call, the transition function should return an expanded object
+ whose memory context is a child of the aggregate state context, and then
+ keep returning the same expanded object on subsequent calls. See
+ <function>array_append()</function> for an example. (<function>array_append()</function>
+ is not the transition function of any built-in aggregate, but it is written
+ to behave efficiently when used as transition function of a custom
+ aggregate.)
+ </para>
+
+ <para>
+ Another support routine available to aggregate functions written in C
+ is <function>AggGetAggref</function>, which returns the <literal>Aggref</literal>
+ parse node that defines the aggregate call. This is mainly useful
+ for ordered-set aggregates, which can inspect the substructure of
+ the <literal>Aggref</literal> node to find out what sort ordering they are
+ supposed to implement. Examples can be found
+ in <filename>orderedsetaggs.c</filename> in the <productname>PostgreSQL</productname>
+ source code.
+ </para>
+
+ </sect2>
+
+ </sect1>
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
new file mode 100644
index 0000000..701432f
--- /dev/null
+++ b/doc/src/sgml/xfunc.sgml
@@ -0,0 +1,3639 @@
+<!-- doc/src/sgml/xfunc.sgml -->
+
+ <sect1 id="xfunc">
+ <title>User-Defined Functions</title>
+
+ <indexterm zone="xfunc">
+ <primary>function</primary>
+ <secondary>user-defined</secondary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> provides four kinds of
+ functions:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ query language functions (functions written in
+ <acronym>SQL</acronym>) (<xref linkend="xfunc-sql"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ procedural language functions (functions written in, for
+ example, <application>PL/pgSQL</application> or <application>PL/Tcl</application>)
+ (<xref linkend="xfunc-pl"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ internal functions (<xref linkend="xfunc-internal"/>)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ C-language functions (<xref linkend="xfunc-c"/>)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ Every kind
+ of function can take base types, composite types, or
+ combinations of these as arguments (parameters). In addition,
+ every kind of function can return a base type or
+ a composite type. Functions can also be defined to return
+ sets of base or composite values.
+ </para>
+
+ <para>
+ Many kinds of functions can take or return certain pseudo-types
+ (such as polymorphic types), but the available facilities vary.
+ Consult the description of each kind of function for more details.
+ </para>
+
+ <para>
+ It's easiest to define <acronym>SQL</acronym>
+ functions, so we'll start by discussing those.
+ Most of the concepts presented for <acronym>SQL</acronym> functions
+ will carry over to the other types of functions.
+ </para>
+
+ <para>
+ Throughout this chapter, it can be useful to look at the reference
+ page of the <link linkend="sql-createfunction"><command>CREATE
+ FUNCTION</command></link> command to
+ understand the examples better. Some examples from this chapter
+ can be found in <filename>funcs.sql</filename> and
+ <filename>funcs.c</filename> in the <filename>src/tutorial</filename>
+ directory in the <productname>PostgreSQL</productname> source
+ distribution.
+ </para>
+ </sect1>
+
+ <sect1 id="xproc">
+ <title>User-Defined Procedures</title>
+
+ <indexterm zone="xproc">
+ <primary>procedure</primary>
+ <secondary>user-defined</secondary>
+ </indexterm>
+
+ <para>
+ A procedure is a database object similar to a function.
+ The key differences are:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Procedures are defined with
+ the <link linkend="sql-createprocedure"><command>CREATE
+ PROCEDURE</command></link> command, not <command>CREATE
+ FUNCTION</command>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Procedures do not return a function value; hence <command>CREATE
+ PROCEDURE</command> lacks a <literal>RETURNS</literal> clause.
+ However, procedures can instead return data to their callers via
+ output parameters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ While a function is called as part of a query or DML command, a
+ procedure is called in isolation using
+ the <link linkend="sql-call"><command>CALL</command></link> command.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A procedure can commit or roll back transactions during its
+ execution (then automatically beginning a new transaction), so long
+ as the invoking <command>CALL</command> command is not part of an
+ explicit transaction block. A function cannot do that.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Certain function attributes, such as strictness, don't apply to
+ procedures. Those attributes control how the function is
+ used in a query, which isn't relevant to procedures.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The explanations in the following sections about how to define
+ user-defined functions apply to procedures as well, except for the
+ points made above.
+ </para>
+
+ <para>
+ Collectively, functions and procedures are also known
+ as <firstterm>routines</firstterm><indexterm><primary>routine</primary></indexterm>.
+ There are commands such as <link linkend="sql-alterroutine"><command>ALTER ROUTINE</command></link>
+ and <link linkend="sql-droproutine"><command>DROP ROUTINE</command></link> that can operate on functions and
+ procedures without having to know which kind it is. Note, however, that
+ there is no <literal>CREATE ROUTINE</literal> command.
+ </para>
+ </sect1>
+
+ <sect1 id="xfunc-sql">
+ <title>Query Language (<acronym>SQL</acronym>) Functions</title>
+
+ <indexterm zone="xfunc-sql">
+ <primary>function</primary>
+ <secondary>user-defined</secondary>
+ <tertiary>in SQL</tertiary>
+ </indexterm>
+
+ <para>
+ SQL functions execute an arbitrary list of SQL statements, returning
+ the result of the last query in the list.
+ In the simple (non-set)
+ case, the first row of the last query's result will be returned.
+ (Bear in mind that <quote>the first row</quote> of a multirow
+ result is not well-defined unless you use <literal>ORDER BY</literal>.)
+ If the last query happens
+ to return no rows at all, the null value will be returned.
+ </para>
+
+ <para>
+ Alternatively, an SQL function can be declared to return a set (that is,
+ multiple rows) by specifying the function's return type as <literal>SETOF
+ <replaceable>sometype</replaceable></literal>, or equivalently by declaring it as
+ <literal>RETURNS TABLE(<replaceable>columns</replaceable>)</literal>. In this case
+ all rows of the last query's result are returned. Further details appear
+ below.
+ </para>
+
+ <para>
+ The body of an SQL function must be a list of SQL
+ statements separated by semicolons. A semicolon after the last
+ statement is optional. Unless the function is declared to return
+ <type>void</type>, the last statement must be a <command>SELECT</command>,
+ or an <command>INSERT</command>, <command>UPDATE</command>, or <command>DELETE</command>
+ that has a <literal>RETURNING</literal> clause.
+ </para>
+
+ <para>
+ Any collection of commands in the <acronym>SQL</acronym>
+ language can be packaged together and defined as a function.
+ Besides <command>SELECT</command> queries, the commands can include data
+ modification queries (<command>INSERT</command>,
+ <command>UPDATE</command>, <command>DELETE</command>, and
+ <command>MERGE</command>), as well as
+ other SQL commands. (You cannot use transaction control commands, e.g.,
+ <command>COMMIT</command>, <command>SAVEPOINT</command>, and some utility
+ commands, e.g., <literal>VACUUM</literal>, in <acronym>SQL</acronym> functions.)
+ However, the final command
+ must be a <command>SELECT</command> or have a <literal>RETURNING</literal>
+ clause that returns whatever is
+ specified as the function's return type. Alternatively, if you
+ want to define an SQL function that performs actions but has no
+ useful value to return, you can define it as returning <type>void</type>.
+ For example, this function removes rows with negative salaries from
+ the <literal>emp</literal> table:
+
+<screen>
+CREATE FUNCTION clean_emp() RETURNS void AS '
+ DELETE FROM emp
+ WHERE salary &lt; 0;
+' LANGUAGE SQL;
+
+SELECT clean_emp();
+
+ clean_emp
+-----------
+
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ You can also write this as a procedure, thus avoiding the issue of the
+ return type. For example:
+<screen>
+CREATE PROCEDURE clean_emp() AS '
+ DELETE FROM emp
+ WHERE salary &lt; 0;
+' LANGUAGE SQL;
+
+CALL clean_emp();
+</screen>
+ In simple cases like this, the difference between a function returning
+ <type>void</type> and a procedure is mostly stylistic. However,
+ procedures offer additional functionality such as transaction control
+ that is not available in functions. Also, procedures are SQL standard
+ whereas returning <type>void</type> is a PostgreSQL extension.
+ </para>
+
+ <note>
+ <para>
+ The entire body of an SQL function is parsed before any of it is
+ executed. While an SQL function can contain commands that alter
+ the system catalogs (e.g., <command>CREATE TABLE</command>), the effects
+ of such commands will not be visible during parse analysis of
+ later commands in the function. Thus, for example,
+ <literal>CREATE TABLE foo (...); INSERT INTO foo VALUES(...);</literal>
+ will not work as desired if packaged up into a single SQL function,
+ since <structname>foo</structname> won't exist yet when the <command>INSERT</command>
+ command is parsed. It's recommended to use <application>PL/pgSQL</application>
+ instead of an SQL function in this type of situation.
+ </para>
+ </note>
+
+ <para>
+ The syntax of the <command>CREATE FUNCTION</command> command requires
+ the function body to be written as a string constant. It is usually
+ most convenient to use dollar quoting (see <xref
+ linkend="sql-syntax-dollar-quoting"/>) for the string constant.
+ If you choose to use regular single-quoted string constant syntax,
+ you must double single quote marks (<literal>'</literal>) and backslashes
+ (<literal>\</literal>) (assuming escape string syntax) in the body of
+ the function (see <xref linkend="sql-syntax-strings"/>).
+ </para>
+
+ <sect2 id="xfunc-sql-function-arguments">
+ <title>Arguments for <acronym>SQL</acronym> Functions</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>named argument</secondary>
+ </indexterm>
+
+ <para>
+ Arguments of an SQL function can be referenced in the function
+ body using either names or numbers. Examples of both methods appear
+ below.
+ </para>
+
+ <para>
+ To use a name, declare the function argument as having a name, and
+ then just write that name in the function body. If the argument name
+ is the same as any column name in the current SQL command within the
+ function, the column name will take precedence. To override this,
+ qualify the argument name with the name of the function itself, that is
+ <literal><replaceable>function_name</replaceable>.<replaceable>argument_name</replaceable></literal>.
+ (If this would conflict with a qualified column name, again the column
+ name wins. You can avoid the ambiguity by choosing a different alias for
+ the table within the SQL command.)
+ </para>
+
+ <para>
+ In the older numeric approach, arguments are referenced using the syntax
+ <literal>$<replaceable>n</replaceable></literal>: <literal>$1</literal> refers to the first input
+ argument, <literal>$2</literal> to the second, and so on. This will work
+ whether or not the particular argument was declared with a name.
+ </para>
+
+ <para>
+ If an argument is of a composite type, then the dot notation,
+ e.g., <literal><replaceable>argname</replaceable>.<replaceable>fieldname</replaceable></literal> or
+ <literal>$1.<replaceable>fieldname</replaceable></literal>, can be used to access attributes of the
+ argument. Again, you might need to qualify the argument's name with the
+ function name to make the form with an argument name unambiguous.
+ </para>
+
+ <para>
+ SQL function arguments can only be used as data values,
+ not as identifiers. Thus for example this is reasonable:
+<programlisting>
+INSERT INTO mytable VALUES ($1);
+</programlisting>
+but this will not work:
+<programlisting>
+INSERT INTO $1 VALUES (42);
+</programlisting>
+ </para>
+
+ <note>
+ <para>
+ The ability to use names to reference SQL function arguments was added
+ in <productname>PostgreSQL</productname> 9.2. Functions to be used in
+ older servers must use the <literal>$<replaceable>n</replaceable></literal> notation.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="xfunc-sql-base-functions">
+ <title><acronym>SQL</acronym> Functions on Base Types</title>
+
+ <para>
+ The simplest possible <acronym>SQL</acronym> function has no arguments and
+ simply returns a base type, such as <type>integer</type>:
+
+<screen>
+CREATE FUNCTION one() RETURNS integer AS $$
+ SELECT 1 AS result;
+$$ LANGUAGE SQL;
+
+-- Alternative syntax for string literal:
+CREATE FUNCTION one() RETURNS integer AS '
+ SELECT 1 AS result;
+' LANGUAGE SQL;
+
+SELECT one();
+
+ one
+-----
+ 1
+</screen>
+ </para>
+
+ <para>
+ Notice that we defined a column alias within the function body for the result of the function
+ (with the name <literal>result</literal>), but this column alias is not visible
+ outside the function. Hence, the result is labeled <literal>one</literal>
+ instead of <literal>result</literal>.
+ </para>
+
+ <para>
+ It is almost as easy to define <acronym>SQL</acronym> functions
+ that take base types as arguments:
+
+<screen>
+CREATE FUNCTION add_em(x integer, y integer) RETURNS integer AS $$
+ SELECT x + y;
+$$ LANGUAGE SQL;
+
+SELECT add_em(1, 2) AS answer;
+
+ answer
+--------
+ 3
+</screen>
+ </para>
+
+ <para>
+ Alternatively, we could dispense with names for the arguments and
+ use numbers:
+
+<screen>
+CREATE FUNCTION add_em(integer, integer) RETURNS integer AS $$
+ SELECT $1 + $2;
+$$ LANGUAGE SQL;
+
+SELECT add_em(1, 2) AS answer;
+
+ answer
+--------
+ 3
+</screen>
+ </para>
+
+ <para>
+ Here is a more useful function, which might be used to debit a
+ bank account:
+
+<programlisting>
+CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tf1.accountno;
+ SELECT 1;
+$$ LANGUAGE SQL;
+</programlisting>
+
+ A user could execute this function to debit account 17 by $100.00 as
+ follows:
+
+<programlisting>
+SELECT tf1(17, 100.0);
+</programlisting>
+ </para>
+
+ <para>
+ In this example, we chose the name <literal>accountno</literal> for the first
+ argument, but this is the same as the name of a column in the
+ <literal>bank</literal> table. Within the <command>UPDATE</command> command,
+ <literal>accountno</literal> refers to the column <literal>bank.accountno</literal>,
+ so <literal>tf1.accountno</literal> must be used to refer to the argument.
+ We could of course avoid this by using a different name for the argument.
+ </para>
+
+ <para>
+ In practice one would probably like a more useful result from the
+ function than a constant 1, so a more likely definition
+ is:
+
+<programlisting>
+CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tf1.accountno;
+ SELECT balance FROM bank WHERE accountno = tf1.accountno;
+$$ LANGUAGE SQL;
+</programlisting>
+
+ which adjusts the balance and returns the new balance.
+ The same thing could be done in one command using <literal>RETURNING</literal>:
+
+<programlisting>
+CREATE FUNCTION tf1 (accountno integer, debit numeric) RETURNS numeric AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tf1.accountno
+ RETURNING balance;
+$$ LANGUAGE SQL;
+</programlisting>
+ </para>
+
+ <para>
+ If the final <literal>SELECT</literal> or <literal>RETURNING</literal>
+ clause in an <acronym>SQL</acronym> function does not return exactly
+ the function's declared result
+ type, <productname>PostgreSQL</productname> will automatically cast
+ the value to the required type, if that is possible with an implicit
+ or assignment cast. Otherwise, you must write an explicit cast.
+ For example, suppose we wanted the
+ previous <function>add_em</function> function to return
+ type <type>float8</type> instead. It's sufficient to write
+
+<programlisting>
+CREATE FUNCTION add_em(integer, integer) RETURNS float8 AS $$
+ SELECT $1 + $2;
+$$ LANGUAGE SQL;
+</programlisting>
+
+ since the <type>integer</type> sum can be implicitly cast
+ to <type>float8</type>.
+ (See <xref linkend="typeconv"/> or <xref linkend="sql-createcast"/>
+ for more about casts.)
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-sql-composite-functions">
+ <title><acronym>SQL</acronym> Functions on Composite Types</title>
+
+ <para>
+ When writing functions with arguments of composite types, we must not
+ only specify which argument we want but also the desired attribute
+ (field) of that argument. For example, suppose that
+ <type>emp</type> is a table containing employee data, and therefore
+ also the name of the composite type of each row of the table. Here
+ is a function <function>double_salary</function> that computes what someone's
+ salary would be if it were doubled:
+
+<screen>
+CREATE TABLE emp (
+ name text,
+ salary numeric,
+ age integer,
+ cubicle point
+);
+
+INSERT INTO emp VALUES ('Bill', 4200, 45, '(2,1)');
+
+CREATE FUNCTION double_salary(emp) RETURNS numeric AS $$
+ SELECT $1.salary * 2 AS salary;
+$$ LANGUAGE SQL;
+
+SELECT name, double_salary(emp.*) AS dream
+ FROM emp
+ WHERE emp.cubicle ~= point '(2,1)';
+
+ name | dream
+------+-------
+ Bill | 8400
+</screen>
+ </para>
+
+ <para>
+ Notice the use of the syntax <literal>$1.salary</literal>
+ to select one field of the argument row value. Also notice
+ how the calling <command>SELECT</command> command
+ uses <replaceable>table_name</replaceable><literal>.*</literal> to select
+ the entire current row of a table as a composite value. The table
+ row can alternatively be referenced using just the table name,
+ like this:
+<screen>
+SELECT name, double_salary(emp) AS dream
+ FROM emp
+ WHERE emp.cubicle ~= point '(2,1)';
+</screen>
+ but this usage is deprecated since it's easy to get confused.
+ (See <xref linkend="rowtypes-usage"/> for details about these
+ two notations for the composite value of a table row.)
+ </para>
+
+ <para>
+ Sometimes it is handy to construct a composite argument value
+ on-the-fly. This can be done with the <literal>ROW</literal> construct.
+ For example, we could adjust the data being passed to the function:
+<screen>
+SELECT name, double_salary(ROW(name, salary*1.1, age, cubicle)) AS dream
+ FROM emp;
+</screen>
+ </para>
+
+ <para>
+ It is also possible to build a function that returns a composite type.
+ This is an example of a function
+ that returns a single <type>emp</type> row:
+
+<programlisting>
+CREATE FUNCTION new_emp() RETURNS emp AS $$
+ SELECT text 'None' AS name,
+ 1000.0 AS salary,
+ 25 AS age,
+ point '(2,2)' AS cubicle;
+$$ LANGUAGE SQL;
+</programlisting>
+
+ In this example we have specified each of the attributes
+ with a constant value, but any computation
+ could have been substituted for these constants.
+ </para>
+
+ <para>
+ Note two important things about defining the function:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The select list order in the query must be exactly the same as
+ that in which the columns appear in the composite type.
+ (Naming the columns, as we did above,
+ is irrelevant to the system.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ We must ensure each expression's type can be cast to that of
+ the corresponding column of the composite type.
+ Otherwise we'll get errors like this:
+<screen>
+<computeroutput>
+ERROR: return type mismatch in function declared to return emp
+DETAIL: Final statement returns text instead of point at column 4.
+</computeroutput>
+</screen>
+ As with the base-type case, the system will not insert explicit
+ casts automatically, only implicit or assignment casts.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ A different way to define the same function is:
+
+<programlisting>
+CREATE FUNCTION new_emp() RETURNS emp AS $$
+ SELECT ROW('None', 1000.0, 25, '(2,2)')::emp;
+$$ LANGUAGE SQL;
+</programlisting>
+
+ Here we wrote a <command>SELECT</command> that returns just a single
+ column of the correct composite type. This isn't really better
+ in this situation, but it is a handy alternative in some cases
+ &mdash; for example, if we need to compute the result by calling
+ another function that returns the desired composite value.
+ Another example is that if we are trying to write a function that
+ returns a domain over composite, rather than a plain composite type,
+ it is always necessary to write it as returning a single column,
+ since there is no way to cause a coercion of the whole row result.
+ </para>
+
+ <para>
+ We could call this function directly either by using it in
+ a value expression:
+
+<screen>
+SELECT new_emp();
+
+ new_emp
+--------------------------
+ (None,1000.0,25,"(2,2)")
+</screen>
+
+ or by calling it as a table function:
+
+<screen>
+SELECT * FROM new_emp();
+
+ name | salary | age | cubicle
+------+--------+-----+---------
+ None | 1000.0 | 25 | (2,2)
+</screen>
+
+ The second way is described more fully in <xref
+ linkend="xfunc-sql-table-functions"/>.
+ </para>
+
+ <para>
+ When you use a function that returns a composite type,
+ you might want only one field (attribute) from its result.
+ You can do that with syntax like this:
+
+<screen>
+SELECT (new_emp()).name;
+
+ name
+------
+ None
+</screen>
+
+ The extra parentheses are needed to keep the parser from getting
+ confused. If you try to do it without them, you get something like this:
+
+<screen>
+SELECT new_emp().name;
+ERROR: syntax error at or near "."
+LINE 1: SELECT new_emp().name;
+ ^
+</screen>
+ </para>
+
+ <para>
+ Another option is to use functional notation for extracting an attribute:
+
+<screen>
+SELECT name(new_emp());
+
+ name
+------
+ None
+</screen>
+
+ As explained in <xref linkend="rowtypes-usage"/>, the field notation and
+ functional notation are equivalent.
+ </para>
+
+ <para>
+ Another way to use a function returning a composite type is to pass the
+ result to another function that accepts the correct row type as input:
+
+<screen>
+CREATE FUNCTION getname(emp) RETURNS text AS $$
+ SELECT $1.name;
+$$ LANGUAGE SQL;
+
+SELECT getname(new_emp());
+ getname
+---------
+ None
+(1 row)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-output-parameters">
+ <title><acronym>SQL</acronym> Functions with Output Parameters</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>output parameter</secondary>
+ </indexterm>
+
+ <para>
+ An alternative way of describing a function's results is to define it
+ with <firstterm>output parameters</firstterm>, as in this example:
+
+<screen>
+CREATE FUNCTION add_em (IN x int, IN y int, OUT sum int)
+AS 'SELECT x + y'
+LANGUAGE SQL;
+
+SELECT add_em(3,7);
+ add_em
+--------
+ 10
+(1 row)
+</screen>
+
+ This is not essentially different from the version of <literal>add_em</literal>
+ shown in <xref linkend="xfunc-sql-base-functions"/>. The real value of
+ output parameters is that they provide a convenient way of defining
+ functions that return several columns. For example,
+
+<screen>
+CREATE FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int)
+AS 'SELECT x + y, x * y'
+LANGUAGE SQL;
+
+ SELECT * FROM sum_n_product(11,42);
+ sum | product
+-----+---------
+ 53 | 462
+(1 row)
+</screen>
+
+ What has essentially happened here is that we have created an anonymous
+ composite type for the result of the function. The above example has
+ the same end result as
+
+<screen>
+CREATE TYPE sum_prod AS (sum int, product int);
+
+CREATE FUNCTION sum_n_product (int, int) RETURNS sum_prod
+AS 'SELECT $1 + $2, $1 * $2'
+LANGUAGE SQL;
+</screen>
+
+ but not having to bother with the separate composite type definition
+ is often handy. Notice that the names attached to the output parameters
+ are not just decoration, but determine the column names of the anonymous
+ composite type. (If you omit a name for an output parameter, the
+ system will choose a name on its own.)
+ </para>
+
+ <para>
+ Notice that output parameters are not included in the calling argument
+ list when invoking such a function from SQL. This is because
+ <productname>PostgreSQL</productname> considers only the input
+ parameters to define the function's calling signature. That means
+ also that only the input parameters matter when referencing the function
+ for purposes such as dropping it. We could drop the above function
+ with either of
+
+<screen>
+DROP FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int);
+DROP FUNCTION sum_n_product (int, int);
+</screen>
+ </para>
+
+ <para>
+ Parameters can be marked as <literal>IN</literal> (the default),
+ <literal>OUT</literal>, <literal>INOUT</literal>, or <literal>VARIADIC</literal>.
+ An <literal>INOUT</literal>
+ parameter serves as both an input parameter (part of the calling
+ argument list) and an output parameter (part of the result record type).
+ <literal>VARIADIC</literal> parameters are input parameters, but are treated
+ specially as described below.
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-output-parameters-proc">
+ <title><acronym>SQL</acronym> Procedures with Output Parameters</title>
+
+ <indexterm>
+ <primary>procedures</primary>
+ <secondary>output parameter</secondary>
+ </indexterm>
+
+ <para>
+ Output parameters are also supported in procedures, but they work a bit
+ differently from functions. In <command>CALL</command> commands,
+ output parameters must be included in the argument list.
+ For example, the bank account debiting routine from earlier could be
+ written like this:
+<programlisting>
+CREATE PROCEDURE tp1 (accountno integer, debit numeric, OUT new_balance numeric) AS $$
+ UPDATE bank
+ SET balance = balance - debit
+ WHERE accountno = tp1.accountno
+ RETURNING balance;
+$$ LANGUAGE SQL;
+</programlisting>
+ To call this procedure, an argument matching the <literal>OUT</literal>
+ parameter must be included. It's customary to write
+ <literal>NULL</literal>:
+<programlisting>
+CALL tp1(17, 100.0, NULL);
+</programlisting>
+ If you write something else, it must be an expression that is implicitly
+ coercible to the declared type of the parameter, just as for input
+ parameters. Note however that such an expression will not be evaluated.
+ </para>
+
+ <para>
+ When calling a procedure from <application>PL/pgSQL</application>,
+ instead of writing <literal>NULL</literal> you must write a variable
+ that will receive the procedure's output. See <xref
+ linkend="plpgsql-statements-calling-procedure"/> for details.
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-sql-variadic-functions">
+ <title><acronym>SQL</acronym> Functions with Variable Numbers of Arguments</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>variadic</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>variadic function</primary>
+ </indexterm>
+
+ <para>
+ <acronym>SQL</acronym> functions can be declared to accept
+ variable numbers of arguments, so long as all the <quote>optional</quote>
+ arguments are of the same data type. The optional arguments will be
+ passed to the function as an array. The function is declared by
+ marking the last parameter as <literal>VARIADIC</literal>; this parameter
+ must be declared as being of an array type. For example:
+
+<screen>
+CREATE FUNCTION mleast(VARIADIC arr numeric[]) RETURNS numeric AS $$
+ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
+$$ LANGUAGE SQL;
+
+SELECT mleast(10, -1, 5, 4.4);
+ mleast
+--------
+ -1
+(1 row)
+</screen>
+
+ Effectively, all the actual arguments at or beyond the
+ <literal>VARIADIC</literal> position are gathered up into a one-dimensional
+ array, as if you had written
+
+<screen>
+SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work
+</screen>
+
+ You can't actually write that, though &mdash; or at least, it will
+ not match this function definition. A parameter marked
+ <literal>VARIADIC</literal> matches one or more occurrences of its element
+ type, not of its own type.
+ </para>
+
+ <para>
+ Sometimes it is useful to be able to pass an already-constructed array
+ to a variadic function; this is particularly handy when one variadic
+ function wants to pass on its array parameter to another one. Also,
+ this is the only secure way to call a variadic function found in a schema
+ that permits untrusted users to create objects; see
+ <xref linkend="typeconv-func"/>. You can do this by
+ specifying <literal>VARIADIC</literal> in the call:
+
+<screen>
+SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]);
+</screen>
+
+ This prevents expansion of the function's variadic parameter into its
+ element type, thereby allowing the array argument value to match
+ normally. <literal>VARIADIC</literal> can only be attached to the last
+ actual argument of a function call.
+ </para>
+
+ <para>
+ Specifying <literal>VARIADIC</literal> in the call is also the only way to
+ pass an empty array to a variadic function, for example:
+
+<screen>
+SELECT mleast(VARIADIC ARRAY[]::numeric[]);
+</screen>
+
+ Simply writing <literal>SELECT mleast()</literal> does not work because a
+ variadic parameter must match at least one actual argument.
+ (You could define a second function also named <literal>mleast</literal>,
+ with no parameters, if you wanted to allow such calls.)
+ </para>
+
+ <para>
+ The array element parameters generated from a variadic parameter are
+ treated as not having any names of their own. This means it is not
+ possible to call a variadic function using named arguments (<xref
+ linkend="sql-syntax-calling-funcs"/>), except when you specify
+ <literal>VARIADIC</literal>. For example, this will work:
+
+<screen>
+SELECT mleast(VARIADIC arr =&gt; ARRAY[10, -1, 5, 4.4]);
+</screen>
+
+ but not these:
+
+<screen>
+SELECT mleast(arr =&gt; 10);
+SELECT mleast(arr =&gt; ARRAY[10, -1, 5, 4.4]);
+</screen>
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-sql-parameter-defaults">
+ <title><acronym>SQL</acronym> Functions with Default Values for Arguments</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>default values for arguments</secondary>
+ </indexterm>
+
+ <para>
+ Functions can be declared with default values for some or all input
+ arguments. The default values are inserted whenever the function is
+ called with insufficiently many actual arguments. Since arguments
+ can only be omitted from the end of the actual argument list, all
+ parameters after a parameter with a default value have to have
+ default values as well. (Although the use of named argument notation
+ could allow this restriction to be relaxed, it's still enforced so that
+ positional argument notation works sensibly.) Whether or not you use it,
+ this capability creates a need for precautions when calling functions in
+ databases where some users mistrust other users; see
+ <xref linkend="typeconv-func"/>.
+ </para>
+
+ <para>
+ For example:
+<screen>
+CREATE FUNCTION foo(a int, b int DEFAULT 2, c int DEFAULT 3)
+RETURNS int
+LANGUAGE SQL
+AS $$
+ SELECT $1 + $2 + $3;
+$$;
+
+SELECT foo(10, 20, 30);
+ foo
+-----
+ 60
+(1 row)
+
+SELECT foo(10, 20);
+ foo
+-----
+ 33
+(1 row)
+
+SELECT foo(10);
+ foo
+-----
+ 15
+(1 row)
+
+SELECT foo(); -- fails since there is no default for the first argument
+ERROR: function foo() does not exist
+</screen>
+ The <literal>=</literal> sign can also be used in place of the
+ key word <literal>DEFAULT</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-sql-table-functions">
+ <title><acronym>SQL</acronym> Functions as Table Sources</title>
+
+ <para>
+ All SQL functions can be used in the <literal>FROM</literal> clause of a query,
+ but it is particularly useful for functions returning composite types.
+ If the function is defined to return a base type, the table function
+ produces a one-column table. If the function is defined to return
+ a composite type, the table function produces a column for each attribute
+ of the composite type.
+ </para>
+
+ <para>
+ Here is an example:
+
+<screen>
+CREATE TABLE foo (fooid int, foosubid int, fooname text);
+INSERT INTO foo VALUES (1, 1, 'Joe');
+INSERT INTO foo VALUES (1, 2, 'Ed');
+INSERT INTO foo VALUES (2, 1, 'Mary');
+
+CREATE FUNCTION getfoo(int) RETURNS foo AS $$
+ SELECT * FROM foo WHERE fooid = $1;
+$$ LANGUAGE SQL;
+
+SELECT *, upper(fooname) FROM getfoo(1) AS t1;
+
+ fooid | foosubid | fooname | upper
+-------+----------+---------+-------
+ 1 | 1 | Joe | JOE
+(1 row)
+</screen>
+
+ As the example shows, we can work with the columns of the function's
+ result just the same as if they were columns of a regular table.
+ </para>
+
+ <para>
+ Note that we only got one row out of the function. This is because
+ we did not use <literal>SETOF</literal>. That is described in the next section.
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-sql-functions-returning-set">
+ <title><acronym>SQL</acronym> Functions Returning Sets</title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>with SETOF</secondary>
+ </indexterm>
+
+ <para>
+ When an SQL function is declared as returning <literal>SETOF
+ <replaceable>sometype</replaceable></literal>, the function's final
+ query is executed to completion, and each row it
+ outputs is returned as an element of the result set.
+ </para>
+
+ <para>
+ This feature is normally used when calling the function in the <literal>FROM</literal>
+ clause. In this case each row returned by the function becomes
+ a row of the table seen by the query. For example, assume that
+ table <literal>foo</literal> has the same contents as above, and we say:
+
+<programlisting>
+CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
+ SELECT * FROM foo WHERE fooid = $1;
+$$ LANGUAGE SQL;
+
+SELECT * FROM getfoo(1) AS t1;
+</programlisting>
+
+ Then we would get:
+<screen>
+ fooid | foosubid | fooname
+-------+----------+---------
+ 1 | 1 | Joe
+ 1 | 2 | Ed
+(2 rows)
+</screen>
+ </para>
+
+ <para>
+ It is also possible to return multiple rows with the columns defined by
+ output parameters, like this:
+
+<programlisting>
+CREATE TABLE tab (y int, z int);
+INSERT INTO tab VALUES (1, 2), (3, 4), (5, 6), (7, 8);
+
+CREATE FUNCTION sum_n_product_with_tab (x int, OUT sum int, OUT product int)
+RETURNS SETOF record
+AS $$
+ SELECT $1 + tab.y, $1 * tab.y FROM tab;
+$$ LANGUAGE SQL;
+
+SELECT * FROM sum_n_product_with_tab(10);
+ sum | product
+-----+---------
+ 11 | 10
+ 13 | 30
+ 15 | 50
+ 17 | 70
+(4 rows)
+</programlisting>
+
+ The key point here is that you must write <literal>RETURNS SETOF record</literal>
+ to indicate that the function returns multiple rows instead of just one.
+ If there is only one output parameter, write that parameter's type
+ instead of <type>record</type>.
+ </para>
+
+ <para>
+ It is frequently useful to construct a query's result by invoking a
+ set-returning function multiple times, with the parameters for each
+ invocation coming from successive rows of a table or subquery. The
+ preferred way to do this is to use the <literal>LATERAL</literal> key word,
+ which is described in <xref linkend="queries-lateral"/>.
+ Here is an example using a set-returning function to enumerate
+ elements of a tree structure:
+
+<screen>
+SELECT * FROM nodes;
+ name | parent
+-----------+--------
+ Top |
+ Child1 | Top
+ Child2 | Top
+ Child3 | Top
+ SubChild1 | Child1
+ SubChild2 | Child1
+(6 rows)
+
+CREATE FUNCTION listchildren(text) RETURNS SETOF text AS $$
+ SELECT name FROM nodes WHERE parent = $1
+$$ LANGUAGE SQL STABLE;
+
+SELECT * FROM listchildren('Top');
+ listchildren
+--------------
+ Child1
+ Child2
+ Child3
+(3 rows)
+
+SELECT name, child FROM nodes, LATERAL listchildren(name) AS child;
+ name | child
+--------+-----------
+ Top | Child1
+ Top | Child2
+ Top | Child3
+ Child1 | SubChild1
+ Child1 | SubChild2
+(5 rows)
+</screen>
+
+ This example does not do anything that we couldn't have done with a
+ simple join, but in more complex calculations the option to put
+ some of the work into a function can be quite convenient.
+ </para>
+
+ <para>
+ Functions returning sets can also be called in the select list
+ of a query. For each row that the query
+ generates by itself, the set-returning function is invoked, and an output
+ row is generated for each element of the function's result set.
+ The previous example could also be done with queries like
+ these:
+
+<screen>
+SELECT listchildren('Top');
+ listchildren
+--------------
+ Child1
+ Child2
+ Child3
+(3 rows)
+
+SELECT name, listchildren(name) FROM nodes;
+ name | listchildren
+--------+--------------
+ Top | Child1
+ Top | Child2
+ Top | Child3
+ Child1 | SubChild1
+ Child1 | SubChild2
+(5 rows)
+</screen>
+
+ In the last <command>SELECT</command>,
+ notice that no output row appears for <literal>Child2</literal>, <literal>Child3</literal>, etc.
+ This happens because <function>listchildren</function> returns an empty set
+ for those arguments, so no result rows are generated. This is the same
+ behavior as we got from an inner join to the function result when using
+ the <literal>LATERAL</literal> syntax.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname>'s behavior for a set-returning function in a
+ query's select list is almost exactly the same as if the set-returning
+ function had been written in a <literal>LATERAL FROM</literal>-clause item
+ instead. For example,
+<programlisting>
+SELECT x, generate_series(1,5) AS g FROM tab;
+</programlisting>
+ is almost equivalent to
+<programlisting>
+SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g;
+</programlisting>
+ It would be exactly the same, except that in this specific example,
+ the planner could choose to put <structname>g</structname> on the outside of the
+ nested-loop join, since <structname>g</structname> has no actual lateral dependency
+ on <structname>tab</structname>. That would result in a different output row
+ order. Set-returning functions in the select list are always evaluated
+ as though they are on the inside of a nested-loop join with the rest of
+ the <literal>FROM</literal> clause, so that the function(s) are run to
+ completion before the next row from the <literal>FROM</literal> clause is
+ considered.
+ </para>
+
+ <para>
+ If there is more than one set-returning function in the query's select
+ list, the behavior is similar to what you get from putting the functions
+ into a single <literal>LATERAL ROWS FROM( ... )</literal> <literal>FROM</literal>-clause
+ item. For each row from the underlying query, there is an output row
+ using the first result from each function, then an output row using the
+ second result, and so on. If some of the set-returning functions
+ produce fewer outputs than others, null values are substituted for the
+ missing data, so that the total number of rows emitted for one
+ underlying row is the same as for the set-returning function that
+ produced the most outputs. Thus the set-returning functions
+ run <quote>in lockstep</quote> until they are all exhausted, and then
+ execution continues with the next underlying row.
+ </para>
+
+ <para>
+ Set-returning functions can be nested in a select list, although that is
+ not allowed in <literal>FROM</literal>-clause items. In such cases, each level
+ of nesting is treated separately, as though it were
+ a separate <literal>LATERAL ROWS FROM( ... )</literal> item. For example, in
+<programlisting>
+SELECT srf1(srf2(x), srf3(y)), srf4(srf5(z)) FROM tab;
+</programlisting>
+ the set-returning functions <function>srf2</function>, <function>srf3</function>,
+ and <function>srf5</function> would be run in lockstep for each row
+ of <structname>tab</structname>, and then <function>srf1</function> and <function>srf4</function>
+ would be applied in lockstep to each row produced by the lower
+ functions.
+ </para>
+
+ <para>
+ Set-returning functions cannot be used within conditional-evaluation
+ constructs, such as <literal>CASE</literal> or <literal>COALESCE</literal>. For
+ example, consider
+<programlisting>
+SELECT x, CASE WHEN x &gt; 0 THEN generate_series(1, 5) ELSE 0 END FROM tab;
+</programlisting>
+ It might seem that this should produce five repetitions of input rows
+ that have <literal>x &gt; 0</literal>, and a single repetition of those that do
+ not; but actually, because <function>generate_series(1, 5)</function> would be
+ run in an implicit <literal>LATERAL FROM</literal> item before
+ the <literal>CASE</literal> expression is ever evaluated, it would produce five
+ repetitions of every input row. To reduce confusion, such cases produce
+ a parse-time error instead.
+ </para>
+
+ <note>
+ <para>
+ If a function's last command is <command>INSERT</command>, <command>UPDATE</command>,
+ or <command>DELETE</command> with <literal>RETURNING</literal>, that command will
+ always be executed to completion, even if the function is not declared
+ with <literal>SETOF</literal> or the calling query does not fetch all the
+ result rows. Any extra rows produced by the <literal>RETURNING</literal>
+ clause are silently dropped, but the commanded table modifications
+ still happen (and are all completed before returning from the function).
+ </para>
+ </note>
+
+ <note>
+ <para>
+ Before <productname>PostgreSQL</productname> 10, putting more than one
+ set-returning function in the same select list did not behave very
+ sensibly unless they always produced equal numbers of rows. Otherwise,
+ what you got was a number of output rows equal to the least common
+ multiple of the numbers of rows produced by the set-returning
+ functions. Also, nested set-returning functions did not work as
+ described above; instead, a set-returning function could have at most
+ one set-returning argument, and each nest of set-returning functions
+ was run independently. Also, conditional execution (set-returning
+ functions inside <literal>CASE</literal> etc.) was previously allowed,
+ complicating things even more.
+ Use of the <literal>LATERAL</literal> syntax is recommended when writing
+ queries that need to work in older <productname>PostgreSQL</productname> versions,
+ because that will give consistent results across different versions.
+ If you have a query that is relying on conditional execution of a
+ set-returning function, you may be able to fix it by moving the
+ conditional test into a custom set-returning function. For example,
+<programlisting>
+SELECT x, CASE WHEN y &gt; 0 THEN generate_series(1, z) ELSE 5 END FROM tab;
+</programlisting>
+ could become
+<programlisting>
+CREATE FUNCTION case_generate_series(cond bool, start int, fin int, els int)
+ RETURNS SETOF int AS $$
+BEGIN
+ IF cond THEN
+ RETURN QUERY SELECT generate_series(start, fin);
+ ELSE
+ RETURN QUERY SELECT els;
+ END IF;
+END$$ LANGUAGE plpgsql;
+
+SELECT x, case_generate_series(y &gt; 0, 1, z, 5) FROM tab;
+</programlisting>
+ This formulation will work the same in all versions
+ of <productname>PostgreSQL</productname>.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="xfunc-sql-functions-returning-table">
+ <title><acronym>SQL</acronym> Functions Returning <literal>TABLE</literal></title>
+
+ <indexterm>
+ <primary>function</primary>
+ <secondary>RETURNS TABLE</secondary>
+ </indexterm>
+
+ <para>
+ There is another way to declare a function as returning a set,
+ which is to use the syntax
+ <literal>RETURNS TABLE(<replaceable>columns</replaceable>)</literal>.
+ This is equivalent to using one or more <literal>OUT</literal> parameters plus
+ marking the function as returning <literal>SETOF record</literal> (or
+ <literal>SETOF</literal> a single output parameter's type, as appropriate).
+ This notation is specified in recent versions of the SQL standard, and
+ thus may be more portable than using <literal>SETOF</literal>.
+ </para>
+
+ <para>
+ For example, the preceding sum-and-product example could also be
+ done this way:
+
+<programlisting>
+CREATE FUNCTION sum_n_product_with_tab (x int)
+RETURNS TABLE(sum int, product int) AS $$
+ SELECT $1 + tab.y, $1 * tab.y FROM tab;
+$$ LANGUAGE SQL;
+</programlisting>
+
+ It is not allowed to use explicit <literal>OUT</literal> or <literal>INOUT</literal>
+ parameters with the <literal>RETURNS TABLE</literal> notation &mdash; you must
+ put all the output columns in the <literal>TABLE</literal> list.
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-sql-polymorphic-functions">
+ <title>Polymorphic <acronym>SQL</acronym> Functions</title>
+
+ <para>
+ <acronym>SQL</acronym> functions can be declared to accept and
+ return the polymorphic types described in <xref
+ linkend="extend-types-polymorphic"/>. Here is a polymorphic
+ function <function>make_array</function> that builds up an array
+ from two arbitrary data type elements:
+<screen>
+CREATE FUNCTION make_array(anyelement, anyelement) RETURNS anyarray AS $$
+ SELECT ARRAY[$1, $2];
+$$ LANGUAGE SQL;
+
+SELECT make_array(1, 2) AS intarray, make_array('a'::text, 'b') AS textarray;
+ intarray | textarray
+----------+-----------
+ {1,2} | {a,b}
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ Notice the use of the typecast <literal>'a'::text</literal>
+ to specify that the argument is of type <type>text</type>. This is
+ required if the argument is just a string literal, since otherwise
+ it would be treated as type
+ <type>unknown</type>, and array of <type>unknown</type> is not a valid
+ type.
+ Without the typecast, you will get errors like this:
+<screen>
+ERROR: could not determine polymorphic type because input has type unknown
+</screen>
+ </para>
+
+ <para>
+ With <function>make_array</function> declared as above, you must
+ provide two arguments that are of exactly the same data type; the
+ system will not attempt to resolve any type differences. Thus for
+ example this does not work:
+<screen>
+SELECT make_array(1, 2.5) AS numericarray;
+ERROR: function make_array(integer, numeric) does not exist
+</screen>
+ An alternative approach is to use the <quote>common</quote> family of
+ polymorphic types, which allows the system to try to identify a
+ suitable common type:
+<screen>
+CREATE FUNCTION make_array2(anycompatible, anycompatible)
+RETURNS anycompatiblearray AS $$
+ SELECT ARRAY[$1, $2];
+$$ LANGUAGE SQL;
+
+SELECT make_array2(1, 2.5) AS numericarray;
+ numericarray
+--------------
+ {1,2.5}
+(1 row)
+</screen>
+ Because the rules for common type resolution default to choosing
+ type <type>text</type> when all inputs are of unknown types, this
+ also works:
+<screen>
+SELECT make_array2('a', 'b') AS textarray;
+ textarray
+-----------
+ {a,b}
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ It is permitted to have polymorphic arguments with a fixed
+ return type, but the converse is not. For example:
+<screen>
+CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$
+ SELECT $1 &gt; $2;
+$$ LANGUAGE SQL;
+
+SELECT is_greater(1, 2);
+ is_greater
+------------
+ f
+(1 row)
+
+CREATE FUNCTION invalid_func() RETURNS anyelement AS $$
+ SELECT 1;
+$$ LANGUAGE SQL;
+ERROR: cannot determine result data type
+DETAIL: A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange.
+</screen>
+ </para>
+
+ <para>
+ Polymorphism can be used with functions that have output arguments.
+ For example:
+<screen>
+CREATE FUNCTION dup (f1 anyelement, OUT f2 anyelement, OUT f3 anyarray)
+AS 'select $1, array[$1,$1]' LANGUAGE SQL;
+
+SELECT * FROM dup(22);
+ f2 | f3
+----+---------
+ 22 | {22,22}
+(1 row)
+</screen>
+ </para>
+
+ <para>
+ Polymorphism can also be used with variadic functions.
+ For example:
+<screen>
+CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$
+ SELECT min($1[i]) FROM generate_subscripts($1, 1) g(i);
+$$ LANGUAGE SQL;
+
+SELECT anyleast(10, -1, 5, 4);
+ anyleast
+----------
+ -1
+(1 row)
+
+SELECT anyleast('abc'::text, 'def');
+ anyleast
+----------
+ abc
+(1 row)
+
+CREATE FUNCTION concat_values(text, VARIADIC anyarray) RETURNS text AS $$
+ SELECT array_to_string($2, $1);
+$$ LANGUAGE SQL;
+
+SELECT concat_values('|', 1, 4, 2);
+ concat_values
+---------------
+ 1|4|2
+(1 row)
+</screen>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><acronym>SQL</acronym> Functions with Collations</title>
+
+ <indexterm>
+ <primary>collation</primary>
+ <secondary>in SQL functions</secondary>
+ </indexterm>
+
+ <para>
+ When an SQL function has one or more parameters of collatable data types,
+ a collation is identified for each function call depending on the
+ collations assigned to the actual arguments, as described in <xref
+ linkend="collation"/>. If a collation is successfully identified
+ (i.e., there are no conflicts of implicit collations among the arguments)
+ then all the collatable parameters are treated as having that collation
+ implicitly. This will affect the behavior of collation-sensitive
+ operations within the function. For example, using the
+ <function>anyleast</function> function described above, the result of
+<programlisting>
+SELECT anyleast('abc'::text, 'ABC');
+</programlisting>
+ will depend on the database's default collation. In <literal>C</literal> locale
+ the result will be <literal>ABC</literal>, but in many other locales it will
+ be <literal>abc</literal>. The collation to use can be forced by adding
+ a <literal>COLLATE</literal> clause to any of the arguments, for example
+<programlisting>
+SELECT anyleast('abc'::text, 'ABC' COLLATE "C");
+</programlisting>
+ Alternatively, if you wish a function to operate with a particular
+ collation regardless of what it is called with, insert
+ <literal>COLLATE</literal> clauses as needed in the function definition.
+ This version of <function>anyleast</function> would always use <literal>en_US</literal>
+ locale to compare strings:
+<programlisting>
+CREATE FUNCTION anyleast (VARIADIC anyarray) RETURNS anyelement AS $$
+ SELECT min($1[i] COLLATE "en_US") FROM generate_subscripts($1, 1) g(i);
+$$ LANGUAGE SQL;
+</programlisting>
+ But note that this will throw an error if applied to a non-collatable
+ data type.
+ </para>
+
+ <para>
+ If no common collation can be identified among the actual arguments,
+ then an SQL function treats its parameters as having their data types'
+ default collation (which is usually the database's default collation,
+ but could be different for parameters of domain types).
+ </para>
+
+ <para>
+ The behavior of collatable parameters can be thought of as a limited
+ form of polymorphism, applicable only to textual data types.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="xfunc-overload">
+ <title>Function Overloading</title>
+
+ <indexterm zone="xfunc-overload">
+ <primary>overloading</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+
+ <para>
+ More than one function can be defined with the same SQL name, so long
+ as the arguments they take are different. In other words,
+ function names can be <firstterm>overloaded</firstterm>. Whether or not
+ you use it, this capability entails security precautions when calling
+ functions in databases where some users mistrust other users; see
+ <xref linkend="typeconv-func"/>. When a query is executed, the server
+ will determine which function to call from the data types and the number
+ of the provided arguments. Overloading can also be used to simulate
+ functions with a variable number of arguments, up to a finite maximum
+ number.
+ </para>
+
+ <para>
+ When creating a family of overloaded functions, one should be
+ careful not to create ambiguities. For instance, given the
+ functions:
+<programlisting>
+CREATE FUNCTION test(int, real) RETURNS ...
+CREATE FUNCTION test(smallint, double precision) RETURNS ...
+</programlisting>
+ it is not immediately clear which function would be called with
+ some trivial input like <literal>test(1, 1.5)</literal>. The
+ currently implemented resolution rules are described in
+ <xref linkend="typeconv"/>, but it is unwise to design a system that subtly
+ relies on this behavior.
+ </para>
+
+ <para>
+ A function that takes a single argument of a composite type should
+ generally not have the same name as any attribute (field) of that type.
+ Recall that <literal><replaceable>attribute</replaceable>(<replaceable>table</replaceable>)</literal>
+ is considered equivalent
+ to <literal><replaceable>table</replaceable>.<replaceable>attribute</replaceable></literal>.
+ In the case that there is an
+ ambiguity between a function on a composite type and an attribute of
+ the composite type, the attribute will always be used. It is possible
+ to override that choice by schema-qualifying the function name
+ (that is, <literal><replaceable>schema</replaceable>.<replaceable>func</replaceable>(<replaceable>table</replaceable>)
+ </literal>) but it's better to
+ avoid the problem by not choosing conflicting names.
+ </para>
+
+ <para>
+ Another possible conflict is between variadic and non-variadic functions.
+ For instance, it is possible to create both <literal>foo(numeric)</literal> and
+ <literal>foo(VARIADIC numeric[])</literal>. In this case it is unclear which one
+ should be matched to a call providing a single numeric argument, such as
+ <literal>foo(10.1)</literal>. The rule is that the function appearing
+ earlier in the search path is used, or if the two functions are in the
+ same schema, the non-variadic one is preferred.
+ </para>
+
+ <para>
+ When overloading C-language functions, there is an additional
+ constraint: The C name of each function in the family of
+ overloaded functions must be different from the C names of all
+ other functions, either internal or dynamically loaded. If this
+ rule is violated, the behavior is not portable. You might get a
+ run-time linker error, or one of the functions will get called
+ (usually the internal one). The alternative form of the
+ <literal>AS</literal> clause for the SQL <command>CREATE
+ FUNCTION</command> command decouples the SQL function name from
+ the function name in the C source code. For instance:
+<programlisting>
+CREATE FUNCTION test(int) RETURNS int
+ AS '<replaceable>filename</replaceable>', 'test_1arg'
+ LANGUAGE C;
+CREATE FUNCTION test(int, int) RETURNS int
+ AS '<replaceable>filename</replaceable>', 'test_2arg'
+ LANGUAGE C;
+</programlisting>
+ The names of the C functions here reflect one of many possible conventions.
+ </para>
+ </sect1>
+
+ <sect1 id="xfunc-volatility">
+ <title>Function Volatility Categories</title>
+
+ <indexterm zone="xfunc-volatility">
+ <primary>volatility</primary>
+ <secondary>functions</secondary>
+ </indexterm>
+ <indexterm zone="xfunc-volatility">
+ <primary>VOLATILE</primary>
+ </indexterm>
+ <indexterm zone="xfunc-volatility">
+ <primary>STABLE</primary>
+ </indexterm>
+ <indexterm zone="xfunc-volatility">
+ <primary>IMMUTABLE</primary>
+ </indexterm>
+
+ <para>
+ Every function has a <firstterm>volatility</firstterm> classification, with
+ the possibilities being <literal>VOLATILE</literal>, <literal>STABLE</literal>, or
+ <literal>IMMUTABLE</literal>. <literal>VOLATILE</literal> is the default if the
+ <link linkend="sql-createfunction"><command>CREATE FUNCTION</command></link>
+ command does not specify a category. The volatility category is a
+ promise to the optimizer about the behavior of the function:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ A <literal>VOLATILE</literal> function can do anything, including modifying
+ the database. It can return different results on successive calls with
+ the same arguments. The optimizer makes no assumptions about the
+ behavior of such functions. A query using a volatile function will
+ re-evaluate the function at every row where its value is needed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ A <literal>STABLE</literal> function cannot modify the database and is
+ guaranteed to return the same results given the same arguments
+ for all rows within a single statement. This category allows the
+ optimizer to optimize multiple calls of the function to a single
+ call. In particular, it is safe to use an expression containing
+ such a function in an index scan condition. (Since an index scan
+ will evaluate the comparison value only once, not once at each
+ row, it is not valid to use a <literal>VOLATILE</literal> function in an
+ index scan condition.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An <literal>IMMUTABLE</literal> function cannot modify the database and is
+ guaranteed to return the same results given the same arguments forever.
+ This category allows the optimizer to pre-evaluate the function when
+ a query calls it with constant arguments. For example, a query like
+ <literal>SELECT ... WHERE x = 2 + 2</literal> can be simplified on sight to
+ <literal>SELECT ... WHERE x = 4</literal>, because the function underlying
+ the integer addition operator is marked <literal>IMMUTABLE</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ For best optimization results, you should label your functions with the
+ strictest volatility category that is valid for them.
+ </para>
+
+ <para>
+ Any function with side-effects <emphasis>must</emphasis> be labeled
+ <literal>VOLATILE</literal>, so that calls to it cannot be optimized away.
+ Even a function with no side-effects needs to be labeled
+ <literal>VOLATILE</literal> if its value can change within a single query;
+ some examples are <literal>random()</literal>, <literal>currval()</literal>,
+ <literal>timeofday()</literal>.
+ </para>
+
+ <para>
+ Another important example is that the <function>current_timestamp</function>
+ family of functions qualify as <literal>STABLE</literal>, since their values do
+ not change within a transaction.
+ </para>
+
+ <para>
+ There is relatively little difference between <literal>STABLE</literal> and
+ <literal>IMMUTABLE</literal> categories when considering simple interactive
+ queries that are planned and immediately executed: it doesn't matter
+ a lot whether a function is executed once during planning or once during
+ query execution startup. But there is a big difference if the plan is
+ saved and reused later. Labeling a function <literal>IMMUTABLE</literal> when
+ it really isn't might allow it to be prematurely folded to a constant during
+ planning, resulting in a stale value being re-used during subsequent uses
+ of the plan. This is a hazard when using prepared statements or when
+ using function languages that cache plans (such as
+ <application>PL/pgSQL</application>).
+ </para>
+
+ <para>
+ For functions written in SQL or in any of the standard procedural
+ languages, there is a second important property determined by the
+ volatility category, namely the visibility of any data changes that have
+ been made by the SQL command that is calling the function. A
+ <literal>VOLATILE</literal> function will see such changes, a <literal>STABLE</literal>
+ or <literal>IMMUTABLE</literal> function will not. This behavior is implemented
+ using the snapshotting behavior of MVCC (see <xref linkend="mvcc"/>):
+ <literal>STABLE</literal> and <literal>IMMUTABLE</literal> functions use a snapshot
+ established as of the start of the calling query, whereas
+ <literal>VOLATILE</literal> functions obtain a fresh snapshot at the start of
+ each query they execute.
+ </para>
+
+ <note>
+ <para>
+ Functions written in C can manage snapshots however they want, but it's
+ usually a good idea to make C functions work this way too.
+ </para>
+ </note>
+
+ <para>
+ Because of this snapshotting behavior,
+ a function containing only <command>SELECT</command> commands can safely be
+ marked <literal>STABLE</literal>, even if it selects from tables that might be
+ undergoing modifications by concurrent queries.
+ <productname>PostgreSQL</productname> will execute all commands of a
+ <literal>STABLE</literal> function using the snapshot established for the
+ calling query, and so it will see a fixed view of the database throughout
+ that query.
+ </para>
+
+ <para>
+ The same snapshotting behavior is used for <command>SELECT</command> commands
+ within <literal>IMMUTABLE</literal> functions. It is generally unwise to select
+ from database tables within an <literal>IMMUTABLE</literal> function at all,
+ since the immutability will be broken if the table contents ever change.
+ However, <productname>PostgreSQL</productname> does not enforce that you
+ do not do that.
+ </para>
+
+ <para>
+ A common error is to label a function <literal>IMMUTABLE</literal> when its
+ results depend on a configuration parameter. For example, a function
+ that manipulates timestamps might well have results that depend on the
+ <xref linkend="guc-timezone"/> setting. For safety, such functions should
+ be labeled <literal>STABLE</literal> instead.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> requires that <literal>STABLE</literal>
+ and <literal>IMMUTABLE</literal> functions contain no SQL commands other
+ than <command>SELECT</command> to prevent data modification.
+ (This is not a completely bulletproof test, since such functions could
+ still call <literal>VOLATILE</literal> functions that modify the database.
+ If you do that, you will find that the <literal>STABLE</literal> or
+ <literal>IMMUTABLE</literal> function does not notice the database changes
+ applied by the called function, since they are hidden from its snapshot.)
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="xfunc-pl">
+ <title>Procedural Language Functions</title>
+
+ <para>
+ <productname>PostgreSQL</productname> allows user-defined functions
+ to be written in other languages besides SQL and C. These other
+ languages are generically called <firstterm>procedural
+ languages</firstterm> (<acronym>PL</acronym>s).
+ Procedural languages aren't built into the
+ <productname>PostgreSQL</productname> server; they are offered
+ by loadable modules.
+ See <xref linkend="xplang"/> and following chapters for more
+ information.
+ </para>
+ </sect1>
+
+ <sect1 id="xfunc-internal">
+ <title>Internal Functions</title>
+
+ <indexterm zone="xfunc-internal"><primary>function</primary><secondary>internal</secondary></indexterm>
+
+ <para>
+ Internal functions are functions written in C that have been statically
+ linked into the <productname>PostgreSQL</productname> server.
+ The <quote>body</quote> of the function definition
+ specifies the C-language name of the function, which need not be the
+ same as the name being declared for SQL use.
+ (For reasons of backward compatibility, an empty body
+ is accepted as meaning that the C-language function name is the
+ same as the SQL name.)
+ </para>
+
+ <para>
+ Normally, all internal functions present in the
+ server are declared during the initialization of the database cluster
+ (see <xref linkend="creating-cluster"/>),
+ but a user could use <command>CREATE FUNCTION</command>
+ to create additional alias names for an internal function.
+ Internal functions are declared in <command>CREATE FUNCTION</command>
+ with language name <literal>internal</literal>. For instance, to
+ create an alias for the <function>sqrt</function> function:
+<programlisting>
+CREATE FUNCTION square_root(double precision) RETURNS double precision
+ AS 'dsqrt'
+ LANGUAGE internal
+ STRICT;
+</programlisting>
+ (Most internal functions expect to be declared <quote>strict</quote>.)
+ </para>
+
+ <note>
+ <para>
+ Not all <quote>predefined</quote> functions are
+ <quote>internal</quote> in the above sense. Some predefined
+ functions are written in SQL.
+ </para>
+ </note>
+ </sect1>
+
+ <sect1 id="xfunc-c">
+ <title>C-Language Functions</title>
+
+ <indexterm zone="xfunc-c">
+ <primary>function</primary>
+ <secondary>user-defined</secondary>
+ <tertiary>in C</tertiary>
+ </indexterm>
+
+ <para>
+ User-defined functions can be written in C (or a language that can
+ be made compatible with C, such as C++). Such functions are
+ compiled into dynamically loadable objects (also called shared
+ libraries) and are loaded by the server on demand. The dynamic
+ loading feature is what distinguishes <quote>C language</quote> functions
+ from <quote>internal</quote> functions &mdash; the actual coding conventions
+ are essentially the same for both. (Hence, the standard internal
+ function library is a rich source of coding examples for user-defined
+ C functions.)
+ </para>
+
+ <para>
+ Currently only one calling convention is used for C functions
+ (<quote>version 1</quote>). Support for that calling convention is
+ indicated by writing a <literal>PG_FUNCTION_INFO_V1()</literal> macro
+ call for the function, as illustrated below.
+ </para>
+
+ <sect2 id="xfunc-c-dynload">
+ <title>Dynamic Loading</title>
+
+ <indexterm zone="xfunc-c-dynload">
+ <primary>dynamic loading</primary>
+ </indexterm>
+
+ <para>
+ The first time a user-defined function in a particular
+ loadable object file is called in a session,
+ the dynamic loader loads that object file into memory so that the
+ function can be called. The <command>CREATE FUNCTION</command>
+ for a user-defined C function must therefore specify two pieces of
+ information for the function: the name of the loadable
+ object file, and the C name (link symbol) of the specific function to call
+ within that object file. If the C name is not explicitly specified then
+ it is assumed to be the same as the SQL function name.
+ </para>
+
+ <para>
+ The following algorithm is used to locate the shared object file
+ based on the name given in the <command>CREATE FUNCTION</command>
+ command:
+
+ <orderedlist>
+ <listitem>
+ <para>
+ If the name is an absolute path, the given file is loaded.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the name starts with the string <literal>$libdir</literal>,
+ that part is replaced by the <productname>PostgreSQL</productname> package
+ library directory
+ name, which is determined at build time.<indexterm><primary>$libdir</primary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ If the name does not contain a directory part, the file is
+ searched for in the path specified by the configuration variable
+ <xref linkend="guc-dynamic-library-path"/>.<indexterm><primary>dynamic_library_path</primary></indexterm>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Otherwise (the file was not found in the path, or it contains a
+ non-absolute directory part), the dynamic loader will try to
+ take the name as given, which will most likely fail. (It is
+ unreliable to depend on the current working directory.)
+ </para>
+ </listitem>
+ </orderedlist>
+
+ If this sequence does not work, the platform-specific shared
+ library file name extension (often <filename>.so</filename>) is
+ appended to the given name and this sequence is tried again. If
+ that fails as well, the load will fail.
+ </para>
+
+ <para>
+ It is recommended to locate shared libraries either relative to
+ <literal>$libdir</literal> or through the dynamic library path.
+ This simplifies version upgrades if the new installation is at a
+ different location. The actual directory that
+ <literal>$libdir</literal> stands for can be found out with the
+ command <literal>pg_config --pkglibdir</literal>.
+ </para>
+
+ <para>
+ The user ID the <productname>PostgreSQL</productname> server runs
+ as must be able to traverse the path to the file you intend to
+ load. Making the file or a higher-level directory not readable
+ and/or not executable by the <systemitem>postgres</systemitem>
+ user is a common mistake.
+ </para>
+
+ <para>
+ In any case, the file name that is given in the
+ <command>CREATE FUNCTION</command> command is recorded literally
+ in the system catalogs, so if the file needs to be loaded again
+ the same procedure is applied.
+ </para>
+
+ <note>
+ <para>
+ <productname>PostgreSQL</productname> will not compile a C function
+ automatically. The object file must be compiled before it is referenced
+ in a <command>CREATE
+ FUNCTION</command> command. See <xref linkend="dfunc"/> for additional
+ information.
+ </para>
+ </note>
+
+ <indexterm zone="xfunc-c-dynload">
+ <primary>magic block</primary>
+ </indexterm>
+
+ <para>
+ To ensure that a dynamically loaded object file is not loaded into an
+ incompatible server, <productname>PostgreSQL</productname> checks that the
+ file contains a <quote>magic block</quote> with the appropriate contents.
+ This allows the server to detect obvious incompatibilities, such as code
+ compiled for a different major version of
+ <productname>PostgreSQL</productname>. To include a magic block,
+ write this in one (and only one) of the module source files, after having
+ included the header <filename>fmgr.h</filename>:
+
+<programlisting>
+PG_MODULE_MAGIC;
+</programlisting>
+ </para>
+
+ <para>
+ After it is used for the first time, a dynamically loaded object
+ file is retained in memory. Future calls in the same session to
+ the function(s) in that file will only incur the small overhead of
+ a symbol table lookup. If you need to force a reload of an object
+ file, for example after recompiling it, begin a fresh session.
+ </para>
+
+ <indexterm zone="xfunc-c-dynload">
+ <primary>_PG_init</primary>
+ </indexterm>
+ <indexterm zone="xfunc-c-dynload">
+ <primary>library initialization function</primary>
+ </indexterm>
+
+ <para>
+ Optionally, a dynamically loaded file can contain an initialization
+ function. If the file includes a function named
+ <function>_PG_init</function>, that function will be called immediately after
+ loading the file. The function receives no parameters and should
+ return void. There is presently no way to unload a dynamically loaded file.
+ </para>
+
+ </sect2>
+
+ <sect2 id="xfunc-c-basetype">
+ <title>Base Types in C-Language Functions</title>
+
+ <indexterm zone="xfunc-c-basetype">
+ <primary>data type</primary>
+ <secondary>internal organization</secondary>
+ </indexterm>
+
+ <para>
+ To know how to write C-language functions, you need to know how
+ <productname>PostgreSQL</productname> internally represents base
+ data types and how they can be passed to and from functions.
+ Internally, <productname>PostgreSQL</productname> regards a base
+ type as a <quote>blob of memory</quote>. The user-defined
+ functions that you define over a type in turn define the way that
+ <productname>PostgreSQL</productname> can operate on it. That
+ is, <productname>PostgreSQL</productname> will only store and
+ retrieve the data from disk and use your user-defined functions
+ to input, process, and output the data.
+ </para>
+
+ <para>
+ Base types can have one of three internal formats:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ pass by value, fixed-length
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pass by reference, fixed-length
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ pass by reference, variable-length
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ By-value types can only be 1, 2, or 4 bytes in length
+ (also 8 bytes, if <literal>sizeof(Datum)</literal> is 8 on your machine).
+ You should be careful to define your types such that they will be the
+ same size (in bytes) on all architectures. For example, the
+ <literal>long</literal> type is dangerous because it is 4 bytes on some
+ machines and 8 bytes on others, whereas <type>int</type> type is 4 bytes
+ on most Unix machines. A reasonable implementation of the
+ <type>int4</type> type on Unix machines might be:
+
+<programlisting>
+/* 4-byte integer, passed by value */
+typedef int int4;
+</programlisting>
+
+ (The actual PostgreSQL C code calls this type <type>int32</type>, because
+ it is a convention in C that <type>int<replaceable>XX</replaceable></type>
+ means <replaceable>XX</replaceable> <emphasis>bits</emphasis>. Note
+ therefore also that the C type <type>int8</type> is 1 byte in size. The
+ SQL type <type>int8</type> is called <type>int64</type> in C. See also
+ <xref linkend="xfunc-c-type-table"/>.)
+ </para>
+
+ <para>
+ On the other hand, fixed-length types of any size can
+ be passed by-reference. For example, here is a sample
+ implementation of a <productname>PostgreSQL</productname> type:
+
+<programlisting>
+/* 16-byte structure, passed by reference */
+typedef struct
+{
+ double x, y;
+} Point;
+</programlisting>
+
+ Only pointers to such types can be used when passing
+ them in and out of <productname>PostgreSQL</productname> functions.
+ To return a value of such a type, allocate the right amount of
+ memory with <literal>palloc</literal>, fill in the allocated memory,
+ and return a pointer to it. (Also, if you just want to return the
+ same value as one of your input arguments that's of the same data type,
+ you can skip the extra <literal>palloc</literal> and just return the
+ pointer to the input value.)
+ </para>
+
+ <para>
+ Finally, all variable-length types must also be passed
+ by reference. All variable-length types must begin
+ with an opaque length field of exactly 4 bytes, which will be set
+ by <symbol>SET_VARSIZE</symbol>; never set this field directly! All data to
+ be stored within that type must be located in the memory
+ immediately following that length field. The
+ length field contains the total length of the structure,
+ that is, it includes the size of the length field
+ itself.
+ </para>
+
+ <para>
+ Another important point is to avoid leaving any uninitialized bits
+ within data type values; for example, take care to zero out any
+ alignment padding bytes that might be present in structs. Without
+ this, logically-equivalent constants of your data type might be
+ seen as unequal by the planner, leading to inefficient (though not
+ incorrect) plans.
+ </para>
+
+ <warning>
+ <para>
+ <emphasis>Never</emphasis> modify the contents of a pass-by-reference input
+ value. If you do so you are likely to corrupt on-disk data, since
+ the pointer you are given might point directly into a disk buffer.
+ The sole exception to this rule is explained in
+ <xref linkend="xaggr"/>.
+ </para>
+ </warning>
+
+ <para>
+ As an example, we can define the type <type>text</type> as
+ follows:
+
+<programlisting>
+typedef struct {
+ int32 length;
+ char data[FLEXIBLE_ARRAY_MEMBER];
+} text;
+</programlisting>
+
+ The <literal>[FLEXIBLE_ARRAY_MEMBER]</literal> notation means that the actual
+ length of the data part is not specified by this declaration.
+ </para>
+
+ <para>
+ When manipulating
+ variable-length types, we must be careful to allocate
+ the correct amount of memory and set the length field correctly.
+ For example, if we wanted to store 40 bytes in a <structname>text</structname>
+ structure, we might use a code fragment like this:
+
+<programlisting><![CDATA[
+#include "postgres.h"
+...
+char buffer[40]; /* our source data */
+...
+text *destination = (text *) palloc(VARHDRSZ + 40);
+SET_VARSIZE(destination, VARHDRSZ + 40);
+memcpy(destination->data, buffer, 40);
+...
+]]>
+</programlisting>
+
+ <literal>VARHDRSZ</literal> is the same as <literal>sizeof(int32)</literal>, but
+ it's considered good style to use the macro <literal>VARHDRSZ</literal>
+ to refer to the size of the overhead for a variable-length type.
+ Also, the length field <emphasis>must</emphasis> be set using the
+ <literal>SET_VARSIZE</literal> macro, not by simple assignment.
+ </para>
+
+ <para>
+ <xref linkend="xfunc-c-type-table"/> shows the C types
+ corresponding to many of the built-in SQL data types
+ of <productname>PostgreSQL</productname>.
+ The <quote>Defined In</quote> column gives the header file that
+ needs to be included to get the type definition. (The actual
+ definition might be in a different file that is included by the
+ listed file. It is recommended that users stick to the defined
+ interface.) Note that you should always include
+ <filename>postgres.h</filename> first in any source file of server
+ code, because it declares a number of things that you will need
+ anyway, and because including other headers first can cause
+ portability issues.
+ </para>
+
+ <table tocentry="1" id="xfunc-c-type-table">
+ <title>Equivalent C Types for Built-in SQL Types</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <colspec colname="col3" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>
+ SQL Type
+ </entry>
+ <entry>
+ C Type
+ </entry>
+ <entry>
+ Defined In
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><type>boolean</type></entry>
+ <entry><type>bool</type></entry>
+ <entry><filename>postgres.h</filename> (maybe compiler built-in)</entry>
+ </row>
+ <row>
+ <entry><type>box</type></entry>
+ <entry><type>BOX*</type></entry>
+ <entry><filename>utils/geo_decls.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>bytea</type></entry>
+ <entry><type>bytea*</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>"char"</type></entry>
+ <entry><type>char</type></entry>
+ <entry>(compiler built-in)</entry>
+ </row>
+ <row>
+ <entry><type>character</type></entry>
+ <entry><type>BpChar*</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>cid</type></entry>
+ <entry><type>CommandId</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>date</type></entry>
+ <entry><type>DateADT</type></entry>
+ <entry><filename>utils/date.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>float4</type> (<type>real</type>)</entry>
+ <entry><type>float4</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>float8</type> (<type>double precision</type>)</entry>
+ <entry><type>float8</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>int2</type> (<type>smallint</type>)</entry>
+ <entry><type>int16</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>int4</type> (<type>integer</type>)</entry>
+ <entry><type>int32</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>int8</type> (<type>bigint</type>)</entry>
+ <entry><type>int64</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>interval</type></entry>
+ <entry><type>Interval*</type></entry>
+ <entry><filename>datatype/timestamp.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>lseg</type></entry>
+ <entry><type>LSEG*</type></entry>
+ <entry><filename>utils/geo_decls.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>name</type></entry>
+ <entry><type>Name</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>numeric</type></entry>
+ <entry><type>Numeric</type></entry>
+ <entry><filename>utils/numeric.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>oid</type></entry>
+ <entry><type>Oid</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>oidvector</type></entry>
+ <entry><type>oidvector*</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>path</type></entry>
+ <entry><type>PATH*</type></entry>
+ <entry><filename>utils/geo_decls.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>point</type></entry>
+ <entry><type>POINT*</type></entry>
+ <entry><filename>utils/geo_decls.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>regproc</type></entry>
+ <entry><type>RegProcedure</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>text</type></entry>
+ <entry><type>text*</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>tid</type></entry>
+ <entry><type>ItemPointer</type></entry>
+ <entry><filename>storage/itemptr.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>time</type></entry>
+ <entry><type>TimeADT</type></entry>
+ <entry><filename>utils/date.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>time with time zone</type></entry>
+ <entry><type>TimeTzADT</type></entry>
+ <entry><filename>utils/date.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>timestamp</type></entry>
+ <entry><type>Timestamp</type></entry>
+ <entry><filename>datatype/timestamp.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>timestamp with time zone</type></entry>
+ <entry><type>TimestampTz</type></entry>
+ <entry><filename>datatype/timestamp.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>varchar</type></entry>
+ <entry><type>VarChar*</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ <row>
+ <entry><type>xid</type></entry>
+ <entry><type>TransactionId</type></entry>
+ <entry><filename>postgres.h</filename></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Now that we've gone over all of the possible structures
+ for base types, we can show some examples of real functions.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Version 1 Calling Conventions</title>
+
+ <para>
+ The version-1 calling convention relies on macros to suppress most
+ of the complexity of passing arguments and results. The C declaration
+ of a version-1 function is always:
+<programlisting>
+Datum funcname(PG_FUNCTION_ARGS)
+</programlisting>
+ In addition, the macro call:
+<programlisting>
+PG_FUNCTION_INFO_V1(funcname);
+</programlisting>
+ must appear in the same source file. (Conventionally, it's
+ written just before the function itself.) This macro call is not
+ needed for <literal>internal</literal>-language functions, since
+ <productname>PostgreSQL</productname> assumes that all internal functions
+ use the version-1 convention. It is, however, required for
+ dynamically-loaded functions.
+ </para>
+
+ <para>
+ In a version-1 function, each actual argument is fetched using a
+ <function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
+ macro that corresponds to the argument's data type. (In non-strict
+ functions there needs to be a previous check about argument null-ness
+ using <function>PG_ARGISNULL()</function>; see below.)
+ The result is returned using a
+ <function>PG_RETURN_<replaceable>xxx</replaceable>()</function>
+ macro for the return type.
+ <function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
+ takes as its argument the number of the function argument to
+ fetch, where the count starts at 0.
+ <function>PG_RETURN_<replaceable>xxx</replaceable>()</function>
+ takes as its argument the actual value to return.
+ </para>
+
+ <para>
+ Here are some examples using the version-1 calling convention:
+ </para>
+
+<programlisting><![CDATA[
+#include "postgres.h"
+#include <string.h>
+#include "fmgr.h"
+#include "utils/geo_decls.h"
+
+PG_MODULE_MAGIC;
+
+/* by value */
+
+PG_FUNCTION_INFO_V1(add_one);
+
+Datum
+add_one(PG_FUNCTION_ARGS)
+{
+ int32 arg = PG_GETARG_INT32(0);
+
+ PG_RETURN_INT32(arg + 1);
+}
+
+/* by reference, fixed length */
+
+PG_FUNCTION_INFO_V1(add_one_float8);
+
+Datum
+add_one_float8(PG_FUNCTION_ARGS)
+{
+ /* The macros for FLOAT8 hide its pass-by-reference nature. */
+ float8 arg = PG_GETARG_FLOAT8(0);
+
+ PG_RETURN_FLOAT8(arg + 1.0);
+}
+
+PG_FUNCTION_INFO_V1(makepoint);
+
+Datum
+makepoint(PG_FUNCTION_ARGS)
+{
+ /* Here, the pass-by-reference nature of Point is not hidden. */
+ Point *pointx = PG_GETARG_POINT_P(0);
+ Point *pointy = PG_GETARG_POINT_P(1);
+ Point *new_point = (Point *) palloc(sizeof(Point));
+
+ new_point->x = pointx->x;
+ new_point->y = pointy->y;
+
+ PG_RETURN_POINT_P(new_point);
+}
+
+/* by reference, variable length */
+
+PG_FUNCTION_INFO_V1(copytext);
+
+Datum
+copytext(PG_FUNCTION_ARGS)
+{
+ text *t = PG_GETARG_TEXT_PP(0);
+
+ /*
+ * VARSIZE_ANY_EXHDR is the size of the struct in bytes, minus the
+ * VARHDRSZ or VARHDRSZ_SHORT of its header. Construct the copy with a
+ * full-length header.
+ */
+ text *new_t = (text *) palloc(VARSIZE_ANY_EXHDR(t) + VARHDRSZ);
+ SET_VARSIZE(new_t, VARSIZE_ANY_EXHDR(t) + VARHDRSZ);
+
+ /*
+ * VARDATA is a pointer to the data region of the new struct. The source
+ * could be a short datum, so retrieve its data through VARDATA_ANY.
+ */
+ memcpy((void *) VARDATA(new_t), /* destination */
+ (void *) VARDATA_ANY(t), /* source */
+ VARSIZE_ANY_EXHDR(t)); /* how many bytes */
+ PG_RETURN_TEXT_P(new_t);
+}
+
+PG_FUNCTION_INFO_V1(concat_text);
+
+Datum
+concat_text(PG_FUNCTION_ARGS)
+{
+ text *arg1 = PG_GETARG_TEXT_PP(0);
+ text *arg2 = PG_GETARG_TEXT_PP(1);
+ int32 arg1_size = VARSIZE_ANY_EXHDR(arg1);
+ int32 arg2_size = VARSIZE_ANY_EXHDR(arg2);
+ int32 new_text_size = arg1_size + arg2_size + VARHDRSZ;
+ text *new_text = (text *) palloc(new_text_size);
+
+ SET_VARSIZE(new_text, new_text_size);
+ memcpy(VARDATA(new_text), VARDATA_ANY(arg1), arg1_size);
+ memcpy(VARDATA(new_text) + arg1_size, VARDATA_ANY(arg2), arg2_size);
+ PG_RETURN_TEXT_P(new_text);
+}
+]]>
+</programlisting>
+
+ <para>
+ Supposing that the above code has been prepared in file
+ <filename>funcs.c</filename> and compiled into a shared object,
+ we could define the functions to <productname>PostgreSQL</productname>
+ with commands like this:
+ </para>
+
+<programlisting>
+CREATE FUNCTION add_one(integer) RETURNS integer
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'add_one'
+ LANGUAGE C STRICT;
+
+-- note overloading of SQL function name "add_one"
+CREATE FUNCTION add_one(double precision) RETURNS double precision
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'add_one_float8'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION makepoint(point, point) RETURNS point
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'makepoint'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION copytext(text) RETURNS text
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'copytext'
+ LANGUAGE C STRICT;
+
+CREATE FUNCTION concat_text(text, text) RETURNS text
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'concat_text'
+ LANGUAGE C STRICT;
+</programlisting>
+
+ <para>
+ Here, <replaceable>DIRECTORY</replaceable> stands for the
+ directory of the shared library file (for instance the
+ <productname>PostgreSQL</productname> tutorial directory, which
+ contains the code for the examples used in this section).
+ (Better style would be to use just <literal>'funcs'</literal> in the
+ <literal>AS</literal> clause, after having added
+ <replaceable>DIRECTORY</replaceable> to the search path. In any
+ case, we can omit the system-specific extension for a shared
+ library, commonly <literal>.so</literal>.)
+ </para>
+
+ <para>
+ Notice that we have specified the functions as <quote>strict</quote>,
+ meaning that
+ the system should automatically assume a null result if any input
+ value is null. By doing this, we avoid having to check for null inputs
+ in the function code. Without this, we'd have to check for null values
+ explicitly, using <function>PG_ARGISNULL()</function>.
+ </para>
+
+ <para>
+ The macro <function>PG_ARGISNULL(<replaceable>n</replaceable>)</function>
+ allows a function to test whether each input is null. (Of course, doing
+ this is only necessary in functions not declared <quote>strict</quote>.)
+ As with the
+ <function>PG_GETARG_<replaceable>xxx</replaceable>()</function> macros,
+ the input arguments are counted beginning at zero. Note that one
+ should refrain from executing
+ <function>PG_GETARG_<replaceable>xxx</replaceable>()</function> until
+ one has verified that the argument isn't null.
+ To return a null result, execute <function>PG_RETURN_NULL()</function>;
+ this works in both strict and nonstrict functions.
+ </para>
+
+ <para>
+ At first glance, the version-1 coding conventions might appear
+ to be just pointless obscurantism, compared to using
+ plain <literal>C</literal> calling conventions. They do however allow
+ us to deal with <literal>NULL</literal>able arguments/return values,
+ and <quote>toasted</quote> (compressed or out-of-line) values.
+ </para>
+
+ <para>
+ Other options provided by the version-1 interface are two
+ variants of the
+ <function>PG_GETARG_<replaceable>xxx</replaceable>()</function>
+ macros. The first of these,
+ <function>PG_GETARG_<replaceable>xxx</replaceable>_COPY()</function>,
+ guarantees to return a copy of the specified argument that is
+ safe for writing into. (The normal macros will sometimes return a
+ pointer to a value that is physically stored in a table, which
+ must not be written to. Using the
+ <function>PG_GETARG_<replaceable>xxx</replaceable>_COPY()</function>
+ macros guarantees a writable result.)
+ The second variant consists of the
+ <function>PG_GETARG_<replaceable>xxx</replaceable>_SLICE()</function>
+ macros which take three arguments. The first is the number of the
+ function argument (as above). The second and third are the offset and
+ length of the segment to be returned. Offsets are counted from
+ zero, and a negative length requests that the remainder of the
+ value be returned. These macros provide more efficient access to
+ parts of large values in the case where they have storage type
+ <quote>external</quote>. (The storage type of a column can be specified using
+ <literal>ALTER TABLE <replaceable>tablename</replaceable> ALTER
+ COLUMN <replaceable>colname</replaceable> SET STORAGE
+ <replaceable>storagetype</replaceable></literal>. <replaceable>storagetype</replaceable> is one of
+ <literal>plain</literal>, <literal>external</literal>, <literal>extended</literal>,
+ or <literal>main</literal>.)
+ </para>
+
+ <para>
+ Finally, the version-1 function call conventions make it possible
+ to return set results (<xref linkend="xfunc-c-return-set"/>) and
+ implement trigger functions (<xref linkend="triggers"/>) and
+ procedural-language call handlers (<xref
+ linkend="plhandler"/>). For more details
+ see <filename>src/backend/utils/fmgr/README</filename> in the
+ source distribution.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Writing Code</title>
+
+ <para>
+ Before we turn to the more advanced topics, we should discuss
+ some coding rules for <productname>PostgreSQL</productname>
+ C-language functions. While it might be possible to load functions
+ written in languages other than C into
+ <productname>PostgreSQL</productname>, this is usually difficult
+ (when it is possible at all) because other languages, such as
+ C++, FORTRAN, or Pascal often do not follow the same calling
+ convention as C. That is, other languages do not pass argument
+ and return values between functions in the same way. For this
+ reason, we will assume that your C-language functions are
+ actually written in C.
+ </para>
+
+ <para>
+ The basic rules for writing and building C functions are as follows:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ Use <literal>pg_config
+ --includedir-server</literal><indexterm><primary>pg_config</primary><secondary>with user-defined C functions</secondary></indexterm>
+ to find out where the <productname>PostgreSQL</productname> server header
+ files are installed on your system (or the system that your
+ users will be running on).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Compiling and linking your code so that it can be dynamically
+ loaded into <productname>PostgreSQL</productname> always
+ requires special flags. See <xref linkend="dfunc"/> for a
+ detailed explanation of how to do it for your particular
+ operating system.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Remember to define a <quote>magic block</quote> for your shared library,
+ as described in <xref linkend="xfunc-c-dynload"/>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ When allocating memory, use the
+ <productname>PostgreSQL</productname> functions
+ <function>palloc</function><indexterm><primary>palloc</primary></indexterm> and <function>pfree</function><indexterm><primary>pfree</primary></indexterm>
+ instead of the corresponding C library functions
+ <function>malloc</function> and <function>free</function>.
+ The memory allocated by <function>palloc</function> will be
+ freed automatically at the end of each transaction, preventing
+ memory leaks.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Always zero the bytes of your structures using <function>memset</function>
+ (or allocate them with <function>palloc0</function> in the first place).
+ Even if you assign to each field of your structure, there might be
+ alignment padding (holes in the structure) that contain
+ garbage values. Without this, it's difficult to
+ support hash indexes or hash joins, as you must pick out only
+ the significant bits of your data structure to compute a hash.
+ The planner also sometimes relies on comparing constants via
+ bitwise equality, so you can get undesirable planning results if
+ logically-equivalent values aren't bitwise equal.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Most of the internal <productname>PostgreSQL</productname>
+ types are declared in <filename>postgres.h</filename>, while
+ the function manager interfaces
+ (<symbol>PG_FUNCTION_ARGS</symbol>, etc.) are in
+ <filename>fmgr.h</filename>, so you will need to include at
+ least these two files. For portability reasons it's best to
+ include <filename>postgres.h</filename> <emphasis>first</emphasis>,
+ before any other system or user header files. Including
+ <filename>postgres.h</filename> will also include
+ <filename>elog.h</filename> and <filename>palloc.h</filename>
+ for you.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Symbol names defined within object files must not conflict
+ with each other or with symbols defined in the
+ <productname>PostgreSQL</productname> server executable. You
+ will have to rename your functions or variables if you get
+ error messages to this effect.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+&dfunc;
+
+ <sect2>
+ <title>Composite-Type Arguments</title>
+
+ <para>
+ Composite types do not have a fixed layout like C structures.
+ Instances of a composite type can contain null fields. In
+ addition, composite types that are part of an inheritance
+ hierarchy can have different fields than other members of the
+ same inheritance hierarchy. Therefore,
+ <productname>PostgreSQL</productname> provides a function
+ interface for accessing fields of composite types from C.
+ </para>
+
+ <para>
+ Suppose we want to write a function to answer the query:
+
+<programlisting>
+SELECT name, c_overpaid(emp, 1500) AS overpaid
+ FROM emp
+ WHERE name = 'Bill' OR name = 'Sam';
+</programlisting>
+
+ Using the version-1 calling conventions, we can define
+ <function>c_overpaid</function> as:
+
+<programlisting><![CDATA[
+#include "postgres.h"
+#include "executor/executor.h" /* for GetAttributeByName() */
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(c_overpaid);
+
+Datum
+c_overpaid(PG_FUNCTION_ARGS)
+{
+ HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
+ int32 limit = PG_GETARG_INT32(1);
+ bool isnull;
+ Datum salary;
+
+ salary = GetAttributeByName(t, "salary", &isnull);
+ if (isnull)
+ PG_RETURN_BOOL(false);
+ /* Alternatively, we might prefer to do PG_RETURN_NULL() for null salary. */
+
+ PG_RETURN_BOOL(DatumGetInt32(salary) > limit);
+}
+]]>
+</programlisting>
+ </para>
+
+ <para>
+ <function>GetAttributeByName</function> is the
+ <productname>PostgreSQL</productname> system function that
+ returns attributes out of the specified row. It has
+ three arguments: the argument of type <type>HeapTupleHeader</type> passed
+ into
+ the function, the name of the desired attribute, and a
+ return parameter that tells whether the attribute
+ is null. <function>GetAttributeByName</function> returns a <type>Datum</type>
+ value that you can convert to the proper data type by using the
+ appropriate <function>DatumGet<replaceable>XXX</replaceable>()</function>
+ macro. Note that the return value is meaningless if the null flag is
+ set; always check the null flag before trying to do anything with the
+ result.
+ </para>
+
+ <para>
+ There is also <function>GetAttributeByNum</function>, which selects
+ the target attribute by column number instead of name.
+ </para>
+
+ <para>
+ The following command declares the function
+ <function>c_overpaid</function> in SQL:
+
+<programlisting>
+CREATE FUNCTION c_overpaid(emp, integer) RETURNS boolean
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'c_overpaid'
+ LANGUAGE C STRICT;
+</programlisting>
+
+ Notice we have used <literal>STRICT</literal> so that we did not have to
+ check whether the input arguments were NULL.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Returning Rows (Composite Types)</title>
+
+ <para>
+ To return a row or composite-type value from a C-language
+ function, you can use a special API that provides macros and
+ functions to hide most of the complexity of building composite
+ data types. To use this API, the source file must include:
+<programlisting>
+#include "funcapi.h"
+</programlisting>
+ </para>
+
+ <para>
+ There are two ways you can build a composite data value (henceforth
+ a <quote>tuple</quote>): you can build it from an array of Datum values,
+ or from an array of C strings that can be passed to the input
+ conversion functions of the tuple's column data types. In either
+ case, you first need to obtain or construct a <structname>TupleDesc</structname>
+ descriptor for the tuple structure. When working with Datums, you
+ pass the <structname>TupleDesc</structname> to <function>BlessTupleDesc</function>,
+ and then call <function>heap_form_tuple</function> for each row. When working
+ with C strings, you pass the <structname>TupleDesc</structname> to
+ <function>TupleDescGetAttInMetadata</function>, and then call
+ <function>BuildTupleFromCStrings</function> for each row. In the case of a
+ function returning a set of tuples, the setup steps can all be done
+ once during the first call of the function.
+ </para>
+
+ <para>
+ Several helper functions are available for setting up the needed
+ <structname>TupleDesc</structname>. The recommended way to do this in most
+ functions returning composite values is to call:
+<programlisting>
+TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo,
+ Oid *resultTypeId,
+ TupleDesc *resultTupleDesc)
+</programlisting>
+ passing the same <literal>fcinfo</literal> struct passed to the calling function
+ itself. (This of course requires that you use the version-1
+ calling conventions.) <varname>resultTypeId</varname> can be specified
+ as <literal>NULL</literal> or as the address of a local variable to receive the
+ function's result type OID. <varname>resultTupleDesc</varname> should be the
+ address of a local <structname>TupleDesc</structname> variable. Check that the
+ result is <literal>TYPEFUNC_COMPOSITE</literal>; if so,
+ <varname>resultTupleDesc</varname> has been filled with the needed
+ <structname>TupleDesc</structname>. (If it is not, you can report an error along
+ the lines of <quote>function returning record called in context that
+ cannot accept type record</quote>.)
+ </para>
+
+ <tip>
+ <para>
+ <function>get_call_result_type</function> can resolve the actual type of a
+ polymorphic function result; so it is useful in functions that return
+ scalar polymorphic results, not only functions that return composites.
+ The <varname>resultTypeId</varname> output is primarily useful for functions
+ returning polymorphic scalars.
+ </para>
+ </tip>
+
+ <note>
+ <para>
+ <function>get_call_result_type</function> has a sibling
+ <function>get_expr_result_type</function>, which can be used to resolve the
+ expected output type for a function call represented by an expression
+ tree. This can be used when trying to determine the result type from
+ outside the function itself. There is also
+ <function>get_func_result_type</function>, which can be used when only the
+ function's OID is available. However these functions are not able
+ to deal with functions declared to return <structname>record</structname>, and
+ <function>get_func_result_type</function> cannot resolve polymorphic types,
+ so you should preferentially use <function>get_call_result_type</function>.
+ </para>
+ </note>
+
+ <para>
+ Older, now-deprecated functions for obtaining
+ <structname>TupleDesc</structname>s are:
+<programlisting>
+TupleDesc RelationNameGetTupleDesc(const char *relname)
+</programlisting>
+ to get a <structname>TupleDesc</structname> for the row type of a named relation,
+ and:
+<programlisting>
+TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases)
+</programlisting>
+ to get a <structname>TupleDesc</structname> based on a type OID. This can
+ be used to get a <structname>TupleDesc</structname> for a base or
+ composite type. It will not work for a function that returns
+ <structname>record</structname>, however, and it cannot resolve polymorphic
+ types.
+ </para>
+
+ <para>
+ Once you have a <structname>TupleDesc</structname>, call:
+<programlisting>
+TupleDesc BlessTupleDesc(TupleDesc tupdesc)
+</programlisting>
+ if you plan to work with Datums, or:
+<programlisting>
+AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc)
+</programlisting>
+ if you plan to work with C strings. If you are writing a function
+ returning set, you can save the results of these functions in the
+ <structname>FuncCallContext</structname> structure &mdash; use the
+ <structfield>tuple_desc</structfield> or <structfield>attinmeta</structfield> field
+ respectively.
+ </para>
+
+ <para>
+ When working with Datums, use:
+<programlisting>
+HeapTuple heap_form_tuple(TupleDesc tupdesc, Datum *values, bool *isnull)
+</programlisting>
+ to build a <structname>HeapTuple</structname> given user data in Datum form.
+ </para>
+
+ <para>
+ When working with C strings, use:
+<programlisting>
+HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
+</programlisting>
+ to build a <structname>HeapTuple</structname> given user data
+ in C string form. <parameter>values</parameter> is an array of C strings,
+ one for each attribute of the return row. Each C string should be in
+ the form expected by the input function of the attribute data
+ type. In order to return a null value for one of the attributes,
+ the corresponding pointer in the <parameter>values</parameter> array
+ should be set to <symbol>NULL</symbol>. This function will need to
+ be called again for each row you return.
+ </para>
+
+ <para>
+ Once you have built a tuple to return from your function, it
+ must be converted into a <type>Datum</type>. Use:
+<programlisting>
+HeapTupleGetDatum(HeapTuple tuple)
+</programlisting>
+ to convert a <structname>HeapTuple</structname> into a valid Datum. This
+ <type>Datum</type> can be returned directly if you intend to return
+ just a single row, or it can be used as the current return value
+ in a set-returning function.
+ </para>
+
+ <para>
+ An example appears in the next section.
+ </para>
+
+ </sect2>
+
+ <sect2 id="xfunc-c-return-set">
+ <title>Returning Sets</title>
+
+ <para>
+ C-language functions have two options for returning sets (multiple
+ rows). In one method, called <firstterm>ValuePerCall</firstterm>
+ mode, a set-returning function is called repeatedly (passing the same
+ arguments each time) and it returns one new row on each call, until
+ it has no more rows to return and signals that by returning NULL.
+ The set-returning function (<acronym>SRF</acronym>) must therefore
+ save enough state across calls to remember what it was doing and
+ return the correct next item on each call.
+ In the other method, called <firstterm>Materialize</firstterm> mode,
+ an SRF fills and returns a tuplestore object containing its
+ entire result; then only one call occurs for the whole result, and
+ no inter-call state is needed.
+ </para>
+
+ <para>
+ When using ValuePerCall mode, it is important to remember that the
+ query is not guaranteed to be run to completion; that is, due to
+ options such as <literal>LIMIT</literal>, the executor might stop
+ making calls to the set-returning function before all rows have been
+ fetched. This means it is not safe to perform cleanup activities in
+ the last call, because that might not ever happen. It's recommended
+ to use Materialize mode for functions that need access to external
+ resources, such as file descriptors.
+ </para>
+
+ <para>
+ The remainder of this section documents a set of helper macros that
+ are commonly used (though not required to be used) for SRFs using
+ ValuePerCall mode. Additional details about Materialize mode can be
+ found in <filename>src/backend/utils/fmgr/README</filename>. Also,
+ the <filename>contrib</filename> modules in
+ the <productname>PostgreSQL</productname> source distribution contain
+ many examples of SRFs using both ValuePerCall and Materialize mode.
+ </para>
+
+ <para>
+ To use the ValuePerCall support macros described here,
+ include <filename>funcapi.h</filename>. These macros work with a
+ structure <structname>FuncCallContext</structname> that contains the
+ state that needs to be saved across calls. Within the calling
+ SRF, <literal>fcinfo-&gt;flinfo-&gt;fn_extra</literal> is used to
+ hold a pointer to <structname>FuncCallContext</structname> across
+ calls. The macros automatically fill that field on first use,
+ and expect to find the same pointer there on subsequent uses.
+<programlisting>
+typedef struct FuncCallContext
+{
+ /*
+ * Number of times we've been called before
+ *
+ * call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
+ * incremented for you every time SRF_RETURN_NEXT() is called.
+ */
+ uint64 call_cntr;
+
+ /*
+ * OPTIONAL maximum number of calls
+ *
+ * max_calls is here for convenience only and setting it is optional.
+ * If not set, you must provide alternative means to know when the
+ * function is done.
+ */
+ uint64 max_calls;
+
+ /*
+ * OPTIONAL pointer to miscellaneous user-provided context information
+ *
+ * user_fctx is for use as a pointer to your own data to retain
+ * arbitrary context information between calls of your function.
+ */
+ void *user_fctx;
+
+ /*
+ * OPTIONAL pointer to struct containing attribute type input metadata
+ *
+ * attinmeta is for use when returning tuples (i.e., composite data types)
+ * and is not used when returning base data types. It is only needed
+ * if you intend to use BuildTupleFromCStrings() to create the return
+ * tuple.
+ */
+ AttInMetadata *attinmeta;
+
+ /*
+ * memory context used for structures that must live for multiple calls
+ *
+ * multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
+ * by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
+ * context for any memory that is to be reused across multiple calls
+ * of the SRF.
+ */
+ MemoryContext multi_call_memory_ctx;
+
+ /*
+ * OPTIONAL pointer to struct containing tuple description
+ *
+ * tuple_desc is for use when returning tuples (i.e., composite data types)
+ * and is only needed if you are going to build the tuples with
+ * heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that
+ * the TupleDesc pointer stored here should usually have been run through
+ * BlessTupleDesc() first.
+ */
+ TupleDesc tuple_desc;
+
+} FuncCallContext;
+</programlisting>
+ </para>
+
+ <para>
+ The macros to be used by an <acronym>SRF</acronym> using this
+ infrastructure are:
+<programlisting>
+SRF_IS_FIRSTCALL()
+</programlisting>
+ Use this to determine if your function is being called for the first or a
+ subsequent time. On the first call (only), call:
+<programlisting>
+SRF_FIRSTCALL_INIT()
+</programlisting>
+ to initialize the <structname>FuncCallContext</structname>. On every function call,
+ including the first, call:
+<programlisting>
+SRF_PERCALL_SETUP()
+</programlisting>
+ to set up for using the <structname>FuncCallContext</structname>.
+ </para>
+
+ <para>
+ If your function has data to return in the current call, use:
+<programlisting>
+SRF_RETURN_NEXT(funcctx, result)
+</programlisting>
+ to return it to the caller. (<literal>result</literal> must be of type
+ <type>Datum</type>, either a single value or a tuple prepared as
+ described above.) Finally, when your function is finished
+ returning data, use:
+<programlisting>
+SRF_RETURN_DONE(funcctx)
+</programlisting>
+ to clean up and end the <acronym>SRF</acronym>.
+ </para>
+
+ <para>
+ The memory context that is current when the <acronym>SRF</acronym> is called is
+ a transient context that will be cleared between calls. This means
+ that you do not need to call <function>pfree</function> on everything
+ you allocated using <function>palloc</function>; it will go away anyway. However, if you want to allocate
+ any data structures to live across calls, you need to put them somewhere
+ else. The memory context referenced by
+ <structfield>multi_call_memory_ctx</structfield> is a suitable location for any
+ data that needs to survive until the <acronym>SRF</acronym> is finished running. In most
+ cases, this means that you should switch into
+ <structfield>multi_call_memory_ctx</structfield> while doing the
+ first-call setup.
+ Use <literal>funcctx-&gt;user_fctx</literal> to hold a pointer to
+ any such cross-call data structures.
+ (Data you allocate
+ in <structfield>multi_call_memory_ctx</structfield> will go away
+ automatically when the query ends, so it is not necessary to free
+ that data manually, either.)
+ </para>
+
+ <warning>
+ <para>
+ While the actual arguments to the function remain unchanged between
+ calls, if you detoast the argument values (which is normally done
+ transparently by the
+ <function>PG_GETARG_<replaceable>xxx</replaceable></function> macro)
+ in the transient context then the detoasted copies will be freed on
+ each cycle. Accordingly, if you keep references to such values in
+ your <structfield>user_fctx</structfield>, you must either copy them into the
+ <structfield>multi_call_memory_ctx</structfield> after detoasting, or ensure
+ that you detoast the values only in that context.
+ </para>
+ </warning>
+
+ <para>
+ A complete pseudo-code example looks like the following:
+<programlisting>
+Datum
+my_set_returning_function(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ Datum result;
+ <replaceable>further declarations as needed</replaceable>
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ MemoryContext oldcontext;
+
+ funcctx = SRF_FIRSTCALL_INIT();
+ oldcontext = MemoryContextSwitchTo(funcctx-&gt;multi_call_memory_ctx);
+ /* One-time setup code appears here: */
+ <replaceable>user code</replaceable>
+ <replaceable>if returning composite</replaceable>
+ <replaceable>build TupleDesc, and perhaps AttInMetadata</replaceable>
+ <replaceable>endif returning composite</replaceable>
+ <replaceable>user code</replaceable>
+ MemoryContextSwitchTo(oldcontext);
+ }
+
+ /* Each-time setup code appears here: */
+ <replaceable>user code</replaceable>
+ funcctx = SRF_PERCALL_SETUP();
+ <replaceable>user code</replaceable>
+
+ /* this is just one way we might test whether we are done: */
+ if (funcctx-&gt;call_cntr &lt; funcctx-&gt;max_calls)
+ {
+ /* Here we want to return another item: */
+ <replaceable>user code</replaceable>
+ <replaceable>obtain result Datum</replaceable>
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else
+ {
+ /* Here we are done returning items, so just report that fact. */
+ /* (Resist the temptation to put cleanup code here.) */
+ SRF_RETURN_DONE(funcctx);
+ }
+}
+</programlisting>
+ </para>
+
+ <para>
+ A complete example of a simple <acronym>SRF</acronym> returning a composite type
+ looks like:
+<programlisting><![CDATA[
+PG_FUNCTION_INFO_V1(retcomposite);
+
+Datum
+retcomposite(PG_FUNCTION_ARGS)
+{
+ FuncCallContext *funcctx;
+ int call_cntr;
+ int max_calls;
+ TupleDesc tupdesc;
+ AttInMetadata *attinmeta;
+
+ /* stuff done only on the first call of the function */
+ if (SRF_IS_FIRSTCALL())
+ {
+ MemoryContext oldcontext;
+
+ /* create a function context for cross-call persistence */
+ funcctx = SRF_FIRSTCALL_INIT();
+
+ /* switch to memory context appropriate for multiple function calls */
+ oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+ /* total number of tuples to be returned */
+ funcctx->max_calls = PG_GETARG_INT32(0);
+
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("function returning record called in context "
+ "that cannot accept type record")));
+
+ /*
+ * generate attribute metadata needed later to produce tuples from raw
+ * C strings
+ */
+ attinmeta = TupleDescGetAttInMetadata(tupdesc);
+ funcctx->attinmeta = attinmeta;
+
+ MemoryContextSwitchTo(oldcontext);
+ }
+
+ /* stuff done on every call of the function */
+ funcctx = SRF_PERCALL_SETUP();
+
+ call_cntr = funcctx->call_cntr;
+ max_calls = funcctx->max_calls;
+ attinmeta = funcctx->attinmeta;
+
+ if (call_cntr < max_calls) /* do when there is more left to send */
+ {
+ char **values;
+ HeapTuple tuple;
+ Datum result;
+
+ /*
+ * Prepare a values array for building the returned tuple.
+ * This should be an array of C strings which will
+ * be processed later by the type input functions.
+ */
+ values = (char **) palloc(3 * sizeof(char *));
+ values[0] = (char *) palloc(16 * sizeof(char));
+ values[1] = (char *) palloc(16 * sizeof(char));
+ values[2] = (char *) palloc(16 * sizeof(char));
+
+ snprintf(values[0], 16, "%d", 1 * PG_GETARG_INT32(1));
+ snprintf(values[1], 16, "%d", 2 * PG_GETARG_INT32(1));
+ snprintf(values[2], 16, "%d", 3 * PG_GETARG_INT32(1));
+
+ /* build a tuple */
+ tuple = BuildTupleFromCStrings(attinmeta, values);
+
+ /* make the tuple into a datum */
+ result = HeapTupleGetDatum(tuple);
+
+ /* clean up (this is not really necessary) */
+ pfree(values[0]);
+ pfree(values[1]);
+ pfree(values[2]);
+ pfree(values);
+
+ SRF_RETURN_NEXT(funcctx, result);
+ }
+ else /* do when there is no more left */
+ {
+ SRF_RETURN_DONE(funcctx);
+ }
+}
+]]>
+</programlisting>
+
+ One way to declare this function in SQL is:
+<programlisting>
+CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);
+
+CREATE OR REPLACE FUNCTION retcomposite(integer, integer)
+ RETURNS SETOF __retcomposite
+ AS '<replaceable>filename</replaceable>', 'retcomposite'
+ LANGUAGE C IMMUTABLE STRICT;
+</programlisting>
+ A different way is to use OUT parameters:
+<programlisting>
+CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
+ OUT f1 integer, OUT f2 integer, OUT f3 integer)
+ RETURNS SETOF record
+ AS '<replaceable>filename</replaceable>', 'retcomposite'
+ LANGUAGE C IMMUTABLE STRICT;
+</programlisting>
+ Notice that in this method the output type of the function is formally
+ an anonymous <structname>record</structname> type.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Polymorphic Arguments and Return Types</title>
+
+ <para>
+ C-language functions can be declared to accept and
+ return the polymorphic types described in <xref
+ linkend="extend-types-polymorphic"/>.
+ When a function's arguments or return types
+ are defined as polymorphic types, the function author cannot know
+ in advance what data type it will be called with, or
+ need to return. There are two routines provided in <filename>fmgr.h</filename>
+ to allow a version-1 C function to discover the actual data types
+ of its arguments and the type it is expected to return. The routines are
+ called <literal>get_fn_expr_rettype(FmgrInfo *flinfo)</literal> and
+ <literal>get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)</literal>.
+ They return the result or argument type OID, or <symbol>InvalidOid</symbol> if the
+ information is not available.
+ The structure <literal>flinfo</literal> is normally accessed as
+ <literal>fcinfo-&gt;flinfo</literal>. The parameter <literal>argnum</literal>
+ is zero based. <function>get_call_result_type</function> can also be used
+ as an alternative to <function>get_fn_expr_rettype</function>.
+ There is also <function>get_fn_expr_variadic</function>, which can be used to
+ find out whether variadic arguments have been merged into an array.
+ This is primarily useful for <literal>VARIADIC "any"</literal> functions,
+ since such merging will always have occurred for variadic functions
+ taking ordinary array types.
+ </para>
+
+ <para>
+ For example, suppose we want to write a function to accept a single
+ element of any type, and return a one-dimensional array of that type:
+
+<programlisting>
+PG_FUNCTION_INFO_V1(make_array);
+Datum
+make_array(PG_FUNCTION_ARGS)
+{
+ ArrayType *result;
+ Oid element_type = get_fn_expr_argtype(fcinfo-&gt;flinfo, 0);
+ Datum element;
+ bool isnull;
+ int16 typlen;
+ bool typbyval;
+ char typalign;
+ int ndims;
+ int dims[MAXDIM];
+ int lbs[MAXDIM];
+
+ if (!OidIsValid(element_type))
+ elog(ERROR, "could not determine data type of input");
+
+ /* get the provided element, being careful in case it's NULL */
+ isnull = PG_ARGISNULL(0);
+ if (isnull)
+ element = (Datum) 0;
+ else
+ element = PG_GETARG_DATUM(0);
+
+ /* we have one dimension */
+ ndims = 1;
+ /* and one element */
+ dims[0] = 1;
+ /* and lower bound is 1 */
+ lbs[0] = 1;
+
+ /* get required info about the element type */
+ get_typlenbyvalalign(element_type, &amp;typlen, &amp;typbyval, &amp;typalign);
+
+ /* now build the array */
+ result = construct_md_array(&amp;element, &amp;isnull, ndims, dims, lbs,
+ element_type, typlen, typbyval, typalign);
+
+ PG_RETURN_ARRAYTYPE_P(result);
+}
+</programlisting>
+ </para>
+
+ <para>
+ The following command declares the function
+ <function>make_array</function> in SQL:
+
+<programlisting>
+CREATE FUNCTION make_array(anyelement) RETURNS anyarray
+ AS '<replaceable>DIRECTORY</replaceable>/funcs', 'make_array'
+ LANGUAGE C IMMUTABLE;
+</programlisting>
+ </para>
+
+ <para>
+ There is a variant of polymorphism that is only available to C-language
+ functions: they can be declared to take parameters of type
+ <literal>"any"</literal>. (Note that this type name must be double-quoted,
+ since it's also an SQL reserved word.) This works like
+ <type>anyelement</type> except that it does not constrain different
+ <literal>"any"</literal> arguments to be the same type, nor do they help
+ determine the function's result type. A C-language function can also
+ declare its final parameter to be <literal>VARIADIC "any"</literal>. This will
+ match one or more actual arguments of any type (not necessarily the same
+ type). These arguments will <emphasis>not</emphasis> be gathered into an array
+ as happens with normal variadic functions; they will just be passed to
+ the function separately. The <function>PG_NARGS()</function> macro and the
+ methods described above must be used to determine the number of actual
+ arguments and their types when using this feature. Also, users of such
+ a function might wish to use the <literal>VARIADIC</literal> keyword in their
+ function call, with the expectation that the function would treat the
+ array elements as separate arguments. The function itself must implement
+ that behavior if wanted, after using <function>get_fn_expr_variadic</function> to
+ detect that the actual argument was marked with <literal>VARIADIC</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="xfunc-shared-addin">
+ <title>Shared Memory and LWLocks</title>
+
+ <para>
+ Add-ins can reserve LWLocks and an allocation of shared memory on server
+ startup. The add-in's shared library must be preloaded by specifying
+ it in
+ <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>.
+ The shared library should register a <literal>shmem_request_hook</literal>
+ in its <function>_PG_init</function> function. This
+ <literal>shmem_request_hook</literal> can reserve LWLocks or shared memory.
+ Shared memory is reserved by calling:
+<programlisting>
+void RequestAddinShmemSpace(int size)
+</programlisting>
+ from your <literal>shmem_request_hook</literal>.
+ </para>
+ <para>
+ LWLocks are reserved by calling:
+<programlisting>
+void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
+</programlisting>
+ from your <literal>shmem_request_hook</literal>. This will ensure that an array of
+ <literal>num_lwlocks</literal> LWLocks is available under the name
+ <literal>tranche_name</literal>. Use <function>GetNamedLWLockTranche</function>
+ to get a pointer to this array.
+ </para>
+ <para>
+ An example of a <literal>shmem_request_hook</literal> can be found in
+ <filename>contrib/pg_stat_statements/pg_stat_statements.c</filename> in the
+ <productname>PostgreSQL</productname> source tree.
+ </para>
+ <para>
+ To avoid possible race-conditions, each backend should use the LWLock
+ <function>AddinShmemInitLock</function> when connecting to and initializing
+ its allocation of shared memory, as shown here:
+<programlisting>
+static mystruct *ptr = NULL;
+
+if (!ptr)
+{
+ bool found;
+
+ LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
+ ptr = ShmemInitStruct("my struct name", size, &amp;found);
+ if (!found)
+ {
+ initialize contents of shmem area;
+ acquire any requested LWLocks using:
+ ptr->locks = GetNamedLWLockTranche("my tranche name");
+ }
+ LWLockRelease(AddinShmemInitLock);
+}
+</programlisting>
+ </para>
+ </sect2>
+
+ <sect2 id="extend-cpp">
+ <title>Using C++ for Extensibility</title>
+
+ <indexterm zone="extend-cpp">
+ <primary>C++</primary>
+ </indexterm>
+
+ <para>
+ Although the <productname>PostgreSQL</productname> backend is written in
+ C, it is possible to write extensions in C++ if these guidelines are
+ followed:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ All functions accessed by the backend must present a C interface
+ to the backend; these C functions can then call C++ functions.
+ For example, <literal>extern C</literal> linkage is required for
+ backend-accessed functions. This is also necessary for any
+ functions that are passed as pointers between the backend and
+ C++ code.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Free memory using the appropriate deallocation method. For example,
+ most backend memory is allocated using <function>palloc()</function>, so use
+ <function>pfree()</function> to free it. Using C++
+ <function>delete</function> in such cases will fail.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Prevent exceptions from propagating into the C code (use a catch-all
+ block at the top level of all <literal>extern C</literal> functions). This
+ is necessary even if the C++ code does not explicitly throw any
+ exceptions, because events like out-of-memory can still throw
+ exceptions. Any exceptions must be caught and appropriate errors
+ passed back to the C interface. If possible, compile C++ with
+ <option>-fno-exceptions</option> to eliminate exceptions entirely; in such
+ cases, you must check for failures in your C++ code, e.g., check for
+ NULL returned by <function>new()</function>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If calling backend functions from C++ code, be sure that the
+ C++ call stack contains only plain old data structures
+ (<acronym>POD</acronym>). This is necessary because backend errors
+ generate a distant <function>longjmp()</function> that does not properly
+ unroll a C++ call stack with non-POD objects.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ In summary, it is best to place C++ code behind a wall of
+ <literal>extern C</literal> functions that interface to the backend,
+ and avoid exception, memory, and call stack leakage.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="xfunc-optimization">
+ <title>Function Optimization Information</title>
+
+ <indexterm zone="xfunc-optimization">
+ <primary>optimization information</primary>
+ <secondary>for functions</secondary>
+ </indexterm>
+
+ <para>
+ By default, a function is just a <quote>black box</quote> that the
+ database system knows very little about the behavior of. However,
+ that means that queries using the function may be executed much less
+ efficiently than they could be. It is possible to supply additional
+ knowledge that helps the planner optimize function calls.
+ </para>
+
+ <para>
+ Some basic facts can be supplied by declarative annotations provided in
+ the <link linkend="sql-createfunction"><command>CREATE FUNCTION</command></link> command. Most important of
+ these is the function's <link linkend="xfunc-volatility">volatility
+ category</link> (<literal>IMMUTABLE</literal>, <literal>STABLE</literal>,
+ or <literal>VOLATILE</literal>); one should always be careful to
+ specify this correctly when defining a function.
+ The parallel safety property (<literal>PARALLEL
+ UNSAFE</literal>, <literal>PARALLEL RESTRICTED</literal>, or
+ <literal>PARALLEL SAFE</literal>) must also be specified if you hope
+ to use the function in parallelized queries.
+ It can also be useful to specify the function's estimated execution
+ cost, and/or the number of rows a set-returning function is estimated
+ to return. However, the declarative way of specifying those two
+ facts only allows specifying a constant value, which is often
+ inadequate.
+ </para>
+
+ <para>
+ It is also possible to attach a <firstterm>planner support
+ function</firstterm> to an SQL-callable function (called
+ its <firstterm>target function</firstterm>), and thereby provide
+ knowledge about the target function that is too complex to be
+ represented declaratively. Planner support functions have to be
+ written in C (although their target functions might not be), so this is
+ an advanced feature that relatively few people will use.
+ </para>
+
+ <para>
+ A planner support function must have the SQL signature
+<programlisting>
+supportfn(internal) returns internal
+</programlisting>
+ It is attached to its target function by specifying
+ the <literal>SUPPORT</literal> clause when creating the target function.
+ </para>
+
+ <para>
+ The details of the API for planner support functions can be found in
+ file <filename>src/include/nodes/supportnodes.h</filename> in the
+ <productname>PostgreSQL</productname> source code. Here we provide
+ just an overview of what planner support functions can do.
+ The set of possible requests to a support function is extensible,
+ so more things might be possible in future versions.
+ </para>
+
+ <para>
+ Some function calls can be simplified during planning based on
+ properties specific to the function. For example,
+ <literal>int4mul(n, 1)</literal> could be simplified to
+ just <literal>n</literal>. This type of transformation can be
+ performed by a planner support function, by having it implement
+ the <literal>SupportRequestSimplify</literal> request type.
+ The support function will be called for each instance of its target
+ function found in a query parse tree. If it finds that the particular
+ call can be simplified into some other form, it can build and return a
+ parse tree representing that expression. This will automatically work
+ for operators based on the function, too &mdash; in the example just
+ given, <literal>n * 1</literal> would also be simplified to
+ <literal>n</literal>.
+ (But note that this is just an example; this particular
+ optimization is not actually performed by
+ standard <productname>PostgreSQL</productname>.)
+ We make no guarantee that <productname>PostgreSQL</productname> will
+ never call the target function in cases that the support function could
+ simplify. Ensure rigorous equivalence between the simplified
+ expression and an actual execution of the target function.
+ </para>
+
+ <para>
+ For target functions that return <type>boolean</type>, it is often useful to estimate
+ the fraction of rows that will be selected by a <literal>WHERE</literal> clause using that
+ function. This can be done by a support function that implements
+ the <literal>SupportRequestSelectivity</literal> request type.
+ </para>
+
+ <para>
+ If the target function's run time is highly dependent on its inputs,
+ it may be useful to provide a non-constant cost estimate for it.
+ This can be done by a support function that implements
+ the <literal>SupportRequestCost</literal> request type.
+ </para>
+
+ <para>
+ For target functions that return sets, it is often useful to provide
+ a non-constant estimate for the number of rows that will be returned.
+ This can be done by a support function that implements
+ the <literal>SupportRequestRows</literal> request type.
+ </para>
+
+ <para>
+ For target functions that return <type>boolean</type>, it may be possible to
+ convert a function call appearing in <literal>WHERE</literal> into an indexable operator
+ clause or clauses. The converted clauses might be exactly equivalent
+ to the function's condition, or they could be somewhat weaker (that is,
+ they might accept some values that the function condition does not).
+ In the latter case the index condition is said to
+ be <firstterm>lossy</firstterm>; it can still be used to scan an index,
+ but the function call will have to be executed for each row returned by
+ the index to see if it really passes the <literal>WHERE</literal> condition or not.
+ To create such conditions, the support function must implement
+ the <literal>SupportRequestIndexCondition</literal> request type.
+ </para>
+ </sect1>
diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml
new file mode 100644
index 0000000..c753d80
--- /dev/null
+++ b/doc/src/sgml/xindex.sgml
@@ -0,0 +1,1452 @@
+<!-- doc/src/sgml/xindex.sgml -->
+
+<sect1 id="xindex">
+ <title>Interfacing Extensions to Indexes</title>
+
+ <indexterm zone="xindex">
+ <primary>index</primary>
+ <secondary>for user-defined data type</secondary>
+ </indexterm>
+
+ <para>
+ The procedures described thus far let you define new types, new
+ functions, and new operators. However, we cannot yet define an
+ index on a column of a new data type. To do this, we must define an
+ <firstterm>operator class</firstterm> for the new data type. Later in this
+ section, we will illustrate this concept in an example: a new
+ operator class for the B-tree index method that stores and sorts
+ complex numbers in ascending absolute value order.
+ </para>
+
+ <para>
+ Operator classes can be grouped into <firstterm>operator families</firstterm>
+ to show the relationships between semantically compatible classes.
+ When only a single data type is involved, an operator class is sufficient,
+ so we'll focus on that case first and then return to operator families.
+ </para>
+
+ <sect2 id="xindex-opclass">
+ <title>Index Methods and Operator Classes</title>
+
+ <para>
+ The <classname>pg_am</classname> table contains one row for every
+ index method (internally known as access method). Support for
+ regular access to tables is built into
+ <productname>PostgreSQL</productname>, but all index methods are
+ described in <classname>pg_am</classname>. It is possible to add a
+ new index access method by writing the necessary code and
+ then creating an entry in <classname>pg_am</classname> &mdash; but that is
+ beyond the scope of this chapter (see <xref linkend="indexam"/>).
+ </para>
+
+ <para>
+ The routines for an index method do not directly know anything
+ about the data types that the index method will operate on.
+ Instead, an <firstterm>operator
+ class</firstterm><indexterm><primary>operator class</primary></indexterm>
+ identifies the set of operations that the index method needs to use
+ to work with a particular data type. Operator classes are so
+ called because one thing they specify is the set of
+ <literal>WHERE</literal>-clause operators that can be used with an index
+ (i.e., can be converted into an index-scan qualification). An
+ operator class can also specify some <firstterm>support
+ function</firstterm> that are needed by the internal operations of the
+ index method, but do not directly correspond to any
+ <literal>WHERE</literal>-clause operator that can be used with the index.
+ </para>
+
+ <para>
+ It is possible to define multiple operator classes for the same
+ data type and index method. By doing this, multiple
+ sets of indexing semantics can be defined for a single data type.
+ For example, a B-tree index requires a sort ordering to be defined
+ for each data type it works on.
+ It might be useful for a complex-number data type
+ to have one B-tree operator class that sorts the data by complex
+ absolute value, another that sorts by real part, and so on.
+ Typically, one of the operator classes will be deemed most commonly
+ useful and will be marked as the default operator class for that
+ data type and index method.
+ </para>
+
+ <para>
+ The same operator class name
+ can be used for several different index methods (for example, both B-tree
+ and hash index methods have operator classes named
+ <literal>int4_ops</literal>), but each such class is an independent
+ entity and must be defined separately.
+ </para>
+ </sect2>
+
+ <sect2 id="xindex-strategies">
+ <title>Index Method Strategies</title>
+
+ <para>
+ The operators associated with an operator class are identified by
+ <quote>strategy numbers</quote>, which serve to identify the semantics of
+ each operator within the context of its operator class.
+ For example, B-trees impose a strict ordering on keys, lesser to greater,
+ and so operators like <quote>less than</quote> and <quote>greater than or equal
+ to</quote> are interesting with respect to a B-tree.
+ Because
+ <productname>PostgreSQL</productname> allows the user to define operators,
+ <productname>PostgreSQL</productname> cannot look at the name of an operator
+ (e.g., <literal>&lt;</literal> or <literal>&gt;=</literal>) and tell what kind of
+ comparison it is. Instead, the index method defines a set of
+ <quote>strategies</quote>, which can be thought of as generalized operators.
+ Each operator class specifies which actual operator corresponds to each
+ strategy for a particular data type and interpretation of the index
+ semantics.
+ </para>
+
+ <para>
+ The B-tree index method defines five strategies, shown in <xref
+ linkend="xindex-btree-strat-table"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-btree-strat-table">
+ <title>B-Tree Strategies</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operation</entry>
+ <entry>Strategy Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>less than</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>less than or equal</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry>equal</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry>greater than or equal</entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry>greater than</entry>
+ <entry>5</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Hash indexes support only equality comparisons, and so they use only one
+ strategy, shown in <xref linkend="xindex-hash-strat-table"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-hash-strat-table">
+ <title>Hash Strategies</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operation</entry>
+ <entry>Strategy Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>equal</entry>
+ <entry>1</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ GiST indexes are more flexible: they do not have a fixed set of
+ strategies at all. Instead, the <quote>consistency</quote> support routine
+ of each particular GiST operator class interprets the strategy numbers
+ however it likes. As an example, several of the built-in GiST index
+ operator classes index two-dimensional geometric objects, providing
+ the <quote>R-tree</quote> strategies shown in
+ <xref linkend="xindex-rtree-strat-table"/>. Four of these are true
+ two-dimensional tests (overlaps, same, contains, contained by);
+ four of them consider only the X direction; and the other four
+ provide the same tests in the Y direction.
+ </para>
+
+ <table tocentry="1" id="xindex-rtree-strat-table">
+ <title>GiST Two-Dimensional <quote>R-tree</quote> Strategies</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operation</entry>
+ <entry>Strategy Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>strictly left of</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>does not extend to right of</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry>overlaps</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry>does not extend to left of</entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry>strictly right of</entry>
+ <entry>5</entry>
+ </row>
+ <row>
+ <entry>same</entry>
+ <entry>6</entry>
+ </row>
+ <row>
+ <entry>contains</entry>
+ <entry>7</entry>
+ </row>
+ <row>
+ <entry>contained by</entry>
+ <entry>8</entry>
+ </row>
+ <row>
+ <entry>does not extend above</entry>
+ <entry>9</entry>
+ </row>
+ <row>
+ <entry>strictly below</entry>
+ <entry>10</entry>
+ </row>
+ <row>
+ <entry>strictly above</entry>
+ <entry>11</entry>
+ </row>
+ <row>
+ <entry>does not extend below</entry>
+ <entry>12</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ SP-GiST indexes are similar to GiST indexes in flexibility: they don't have
+ a fixed set of strategies. Instead the support routines of each operator
+ class interpret the strategy numbers according to the operator class's
+ definition. As an example, the strategy numbers used by the built-in
+ operator classes for points are shown in <xref
+ linkend="xindex-spgist-point-strat-table"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-spgist-point-strat-table">
+ <title>SP-GiST Point Strategies</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operation</entry>
+ <entry>Strategy Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>strictly left of</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>strictly right of</entry>
+ <entry>5</entry>
+ </row>
+ <row>
+ <entry>same</entry>
+ <entry>6</entry>
+ </row>
+ <row>
+ <entry>contained by</entry>
+ <entry>8</entry>
+ </row>
+ <row>
+ <entry>strictly below</entry>
+ <entry>10</entry>
+ </row>
+ <row>
+ <entry>strictly above</entry>
+ <entry>11</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ GIN indexes are similar to GiST and SP-GiST indexes, in that they don't
+ have a fixed set of strategies either. Instead the support routines of
+ each operator class interpret the strategy numbers according to the
+ operator class's definition. As an example, the strategy numbers used by
+ the built-in operator class for arrays are shown in
+ <xref linkend="xindex-gin-array-strat-table"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-gin-array-strat-table">
+ <title>GIN Array Strategies</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operation</entry>
+ <entry>Strategy Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>overlap</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>contains</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry>is contained by</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry>equal</entry>
+ <entry>4</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ BRIN indexes are similar to GiST, SP-GiST and GIN indexes in that they
+ don't have a fixed set of strategies either. Instead the support routines
+ of each operator class interpret the strategy numbers according to the
+ operator class's definition. As an example, the strategy numbers used by
+ the built-in <literal>Minmax</literal> operator classes are shown in
+ <xref linkend="xindex-brin-minmax-strat-table"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-brin-minmax-strat-table">
+ <title>BRIN Minmax Strategies</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Operation</entry>
+ <entry>Strategy Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>less than</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>less than or equal</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry>equal</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry>greater than or equal</entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry>greater than</entry>
+ <entry>5</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Notice that all the operators listed above return Boolean values. In
+ practice, all operators defined as index method search operators must
+ return type <type>boolean</type>, since they must appear at the top
+ level of a <literal>WHERE</literal> clause to be used with an index.
+ (Some index access methods also support <firstterm>ordering operators</firstterm>,
+ which typically don't return Boolean values; that feature is discussed
+ in <xref linkend="xindex-ordering-ops"/>.)
+ </para>
+ </sect2>
+
+ <sect2 id="xindex-support">
+ <title>Index Method Support Routines</title>
+
+ <para>
+ Strategies aren't usually enough information for the system to figure
+ out how to use an index. In practice, the index methods require
+ additional support routines in order to work. For example, the B-tree
+ index method must be able to compare two keys and determine whether one
+ is greater than, equal to, or less than the other. Similarly, the
+ hash index method must be able to compute hash codes for key values.
+ These operations do not correspond to operators used in qualifications in
+ SQL commands; they are administrative routines used by
+ the index methods, internally.
+ </para>
+
+ <para>
+ Just as with strategies, the operator class identifies which specific
+ functions should play each of these roles for a given data type and
+ semantic interpretation. The index method defines the set
+ of functions it needs, and the operator class identifies the correct
+ functions to use by assigning them to the <quote>support function numbers</quote>
+ specified by the index method.
+ </para>
+
+ <para>
+ Additionally, some opclasses allow users to specify parameters which
+ control their behavior. Each builtin index access method has an optional
+ <function>options</function> support function, which defines a set of
+ opclass-specific parameters.
+ </para>
+
+ <para>
+ B-trees require a comparison support function,
+ and allow four additional support functions to be
+ supplied at the operator class author's option, as shown in <xref
+ linkend="xindex-btree-support-table"/>.
+ The requirements for these support functions are explained further in
+ <xref linkend="btree-support-funcs"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-btree-support-table">
+ <title>B-Tree Support Functions</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="3*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Support Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ Compare two keys and return an integer less than zero, zero, or
+ greater than zero, indicating whether the first key is less than,
+ equal to, or greater than the second
+ </entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>
+ Return the addresses of C-callable sort support function(s)
+ (optional)
+ </entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry>
+ Compare a test value to a base value plus/minus an offset, and return
+ true or false according to the comparison result (optional)
+ </entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry>
+ Determine if it is safe for indexes that use the operator
+ class to apply the btree deduplication optimization (optional)
+ </entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry>
+ Define options that are specific to this operator class
+ (optional)
+ </entry>
+ <entry>5</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Hash indexes require one support function, and allow two additional ones to
+ be supplied at the operator class author's option, as shown in <xref
+ linkend="xindex-hash-support-table"/>.
+ </para>
+
+ <table tocentry="1" id="xindex-hash-support-table">
+ <title>Hash Support Functions</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="3*"/>
+ <colspec colname="col2" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Support Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Compute the 32-bit hash value for a key</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry>
+ Compute the 64-bit hash value for a key given a 64-bit salt; if
+ the salt is 0, the low 32 bits of the result must match the value
+ that would have been computed by function 1
+ (optional)
+ </entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry>
+ Define options that are specific to this operator class
+ (optional)
+ </entry>
+ <entry>3</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ GiST indexes have eleven support functions, six of which are optional,
+ as shown in <xref linkend="xindex-gist-support-table"/>.
+ (For more information see <xref linkend="gist"/>.)
+ </para>
+
+ <table tocentry="1" id="xindex-gist-support-table">
+ <title>GiST Support Functions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Description</entry>
+ <entry>Support Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><function>consistent</function></entry>
+ <entry>determine whether key satisfies the
+ query qualifier</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry><function>union</function></entry>
+ <entry>compute union of a set of keys</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry><function>compress</function></entry>
+ <entry>compute a compressed representation of a key or value
+ to be indexed (optional)</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry><function>decompress</function></entry>
+ <entry>compute a decompressed representation of a
+ compressed key (optional)</entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry><function>penalty</function></entry>
+ <entry>compute penalty for inserting new key into subtree
+ with given subtree's key</entry>
+ <entry>5</entry>
+ </row>
+ <row>
+ <entry><function>picksplit</function></entry>
+ <entry>determine which entries of a page are to be moved
+ to the new page and compute the union keys for resulting pages</entry>
+ <entry>6</entry>
+ </row>
+ <row>
+ <entry><function>same</function></entry>
+ <entry>compare two keys and return true if they are equal</entry>
+ <entry>7</entry>
+ </row>
+ <row>
+ <entry><function>distance</function></entry>
+ <entry>determine distance from key to query value (optional)</entry>
+ <entry>8</entry>
+ </row>
+ <row>
+ <entry><function>fetch</function></entry>
+ <entry>compute original representation of a compressed key for
+ index-only scans (optional)</entry>
+ <entry>9</entry>
+ </row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>define options that are specific to this operator class
+ (optional)</entry>
+ <entry>10</entry>
+ </row>
+ <row>
+ <entry><function>sortsupport</function></entry>
+ <entry>provide a sort comparator to be used in fast index builds
+ (optional)</entry>
+ <entry>11</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ SP-GiST indexes have six support functions, one of which is optional, as
+ shown in <xref linkend="xindex-spgist-support-table"/>.
+ (For more information see <xref linkend="spgist"/>.)
+ </para>
+
+ <table tocentry="1" id="xindex-spgist-support-table">
+ <title>SP-GiST Support Functions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Description</entry>
+ <entry>Support Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><function>config</function></entry>
+ <entry>provide basic information about the operator class</entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry><function>choose</function></entry>
+ <entry>determine how to insert a new value into an inner tuple</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry><function>picksplit</function></entry>
+ <entry>determine how to partition a set of values</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry><function>inner_consistent</function></entry>
+ <entry>determine which sub-partitions need to be searched for a
+ query</entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry><function>leaf_consistent</function></entry>
+ <entry>determine whether key satisfies the
+ query qualifier</entry>
+ <entry>5</entry>
+ </row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>define options that are specific to this operator class
+ (optional)</entry>
+ <entry>6</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ GIN indexes have seven support functions, four of which are optional,
+ as shown in <xref linkend="xindex-gin-support-table"/>.
+ (For more information see <xref linkend="gin"/>.)
+ </para>
+
+ <table tocentry="1" id="xindex-gin-support-table">
+ <title>GIN Support Functions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Description</entry>
+ <entry>Support Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><function>compare</function></entry>
+ <entry>
+ compare two keys and return an integer less than zero, zero,
+ or greater than zero, indicating whether the first key is less than,
+ equal to, or greater than the second
+ </entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry><function>extractValue</function></entry>
+ <entry>extract keys from a value to be indexed</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry><function>extractQuery</function></entry>
+ <entry>extract keys from a query condition</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry><function>consistent</function></entry>
+ <entry>
+ determine whether value matches query condition (Boolean variant)
+ (optional if support function 6 is present)
+ </entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry><function>comparePartial</function></entry>
+ <entry>
+ compare partial key from
+ query and key from index, and return an integer less than zero, zero,
+ or greater than zero, indicating whether GIN should ignore this index
+ entry, treat the entry as a match, or stop the index scan (optional)
+ </entry>
+ <entry>5</entry>
+ </row>
+ <row>
+ <entry><function>triConsistent</function></entry>
+ <entry>
+ determine whether value matches query condition (ternary variant)
+ (optional if support function 4 is present)
+ </entry>
+ <entry>6</entry>
+ </row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ define options that are specific to this operator class
+ (optional)
+ </entry>
+ <entry>7</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ BRIN indexes have five basic support functions, one of which is optional,
+ as shown in <xref linkend="xindex-brin-support-table"/>. Some versions of
+ the basic functions require additional support functions to be provided.
+ (For more information see <xref linkend="brin-extensibility"/>.)
+ </para>
+
+ <table tocentry="1" id="xindex-brin-support-table">
+ <title>BRIN Support Functions</title>
+ <tgroup cols="3">
+ <colspec colname="col1" colwidth="2*"/>
+ <colspec colname="col2" colwidth="3*"/>
+ <colspec colname="col3" colwidth="1*"/>
+ <thead>
+ <row>
+ <entry>Function</entry>
+ <entry>Description</entry>
+ <entry>Support Number</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><function>opcInfo</function></entry>
+ <entry>
+ return internal information describing the indexed columns'
+ summary data
+ </entry>
+ <entry>1</entry>
+ </row>
+ <row>
+ <entry><function>add_value</function></entry>
+ <entry>add a new value to an existing summary index tuple</entry>
+ <entry>2</entry>
+ </row>
+ <row>
+ <entry><function>consistent</function></entry>
+ <entry>determine whether value matches query condition</entry>
+ <entry>3</entry>
+ </row>
+ <row>
+ <entry><function>union</function></entry>
+ <entry>
+ compute union of two summary tuples
+ </entry>
+ <entry>4</entry>
+ </row>
+ <row>
+ <entry><function>options</function></entry>
+ <entry>
+ define options that are specific to this operator class
+ (optional)
+ </entry>
+ <entry>5</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ Unlike search operators, support functions return whichever data
+ type the particular index method expects; for example in the case
+ of the comparison function for B-trees, a signed integer. The number
+ and types of the arguments to each support function are likewise
+ dependent on the index method. For B-tree and hash the comparison and
+ hashing support functions take the same input data types as do the
+ operators included in the operator class, but this is not the case for
+ most GiST, SP-GiST, GIN, and BRIN support functions.
+ </para>
+ </sect2>
+
+ <sect2 id="xindex-example">
+ <title>An Example</title>
+
+ <para>
+ Now that we have seen the ideas, here is the promised example of
+ creating a new operator class.
+ (You can find a working copy of this example in
+ <filename>src/tutorial/complex.c</filename> and
+ <filename>src/tutorial/complex.sql</filename> in the source
+ distribution.)
+ The operator class encapsulates
+ operators that sort complex numbers in absolute value order, so we
+ choose the name <literal>complex_abs_ops</literal>. First, we need
+ a set of operators. The procedure for defining operators was
+ discussed in <xref linkend="xoper"/>. For an operator class on
+ B-trees, the operators we require are:
+
+ <itemizedlist spacing="compact">
+ <listitem><simpara>absolute-value less-than (strategy 1)</simpara></listitem>
+ <listitem><simpara>absolute-value less-than-or-equal (strategy 2)</simpara></listitem>
+ <listitem><simpara>absolute-value equal (strategy 3)</simpara></listitem>
+ <listitem><simpara>absolute-value greater-than-or-equal (strategy 4)</simpara></listitem>
+ <listitem><simpara>absolute-value greater-than (strategy 5)</simpara></listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The least error-prone way to define a related set of comparison operators
+ is to write the B-tree comparison support function first, and then write the
+ other functions as one-line wrappers around the support function. This
+ reduces the odds of getting inconsistent results for corner cases.
+ Following this approach, we first write:
+
+<programlisting><![CDATA[
+#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
+
+static int
+complex_abs_cmp_internal(Complex *a, Complex *b)
+{
+ double amag = Mag(a),
+ bmag = Mag(b);
+
+ if (amag < bmag)
+ return -1;
+ if (amag > bmag)
+ return 1;
+ return 0;
+}
+]]>
+</programlisting>
+
+ Now the less-than function looks like:
+
+<programlisting><![CDATA[
+PG_FUNCTION_INFO_V1(complex_abs_lt);
+
+Datum
+complex_abs_lt(PG_FUNCTION_ARGS)
+{
+ Complex *a = (Complex *) PG_GETARG_POINTER(0);
+ Complex *b = (Complex *) PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);
+}
+]]>
+</programlisting>
+
+ The other four functions differ only in how they compare the internal
+ function's result to zero.
+ </para>
+
+ <para>
+ Next we declare the functions and the operators based on the functions
+ to SQL:
+
+<programlisting>
+CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool
+ AS '<replaceable>filename</replaceable>', 'complex_abs_lt'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR &lt; (
+ leftarg = complex, rightarg = complex, procedure = complex_abs_lt,
+ commutator = &gt; , negator = &gt;= ,
+ restrict = scalarltsel, join = scalarltjoinsel
+);
+</programlisting>
+ It is important to specify the correct commutator and negator operators,
+ as well as suitable restriction and join selectivity
+ functions, otherwise the optimizer will be unable to make effective
+ use of the index.
+ </para>
+
+ <para>
+ Other things worth noting are happening here:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ There can only be one operator named, say, <literal>=</literal>
+ and taking type <type>complex</type> for both operands. In this
+ case we don't have any other operator <literal>=</literal> for
+ <type>complex</type>, but if we were building a practical data
+ type we'd probably want <literal>=</literal> to be the ordinary
+ equality operation for complex numbers (and not the equality of
+ the absolute values). In that case, we'd need to use some other
+ operator name for <function>complex_abs_eq</function>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Although <productname>PostgreSQL</productname> can cope with
+ functions having the same SQL name as long as they have different
+ argument data types, C can only cope with one global function
+ having a given name. So we shouldn't name the C function
+ something simple like <filename>abs_eq</filename>. Usually it's
+ a good practice to include the data type name in the C function
+ name, so as not to conflict with functions for other data types.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ We could have made the SQL name
+ of the function <filename>abs_eq</filename>, relying on
+ <productname>PostgreSQL</productname> to distinguish it by
+ argument data types from any other SQL function of the same name.
+ To keep the example simple, we make the function have the same
+ names at the C level and SQL level.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ The next step is the registration of the support routine required
+ by B-trees. The example C code that implements this is in the same
+ file that contains the operator functions. This is how we declare
+ the function:
+
+<programlisting>
+CREATE FUNCTION complex_abs_cmp(complex, complex)
+ RETURNS integer
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C IMMUTABLE STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ Now that we have the required operators and support routine,
+ we can finally create the operator class:
+
+<programlisting><![CDATA[
+CREATE OPERATOR CLASS complex_abs_ops
+ DEFAULT FOR TYPE complex USING btree AS
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ FUNCTION 1 complex_abs_cmp(complex, complex);
+]]>
+</programlisting>
+ </para>
+
+ <para>
+ And we're done! It should now be possible to create
+ and use B-tree indexes on <type>complex</type> columns.
+ </para>
+
+ <para>
+ We could have written the operator entries more verbosely, as in:
+<programlisting>
+ OPERATOR 1 &lt; (complex, complex) ,
+</programlisting>
+ but there is no need to do so when the operators take the same data type
+ we are defining the operator class for.
+ </para>
+
+ <para>
+ The above example assumes that you want to make this new operator class the
+ default B-tree operator class for the <type>complex</type> data type.
+ If you don't, just leave out the word <literal>DEFAULT</literal>.
+ </para>
+ </sect2>
+
+ <sect2 id="xindex-opfamily">
+ <title>Operator Classes and Operator Families</title>
+
+ <para>
+ So far we have implicitly assumed that an operator class deals with
+ only one data type. While there certainly can be only one data type in
+ a particular index column, it is often useful to index operations that
+ compare an indexed column to a value of a different data type. Also,
+ if there is use for a cross-data-type operator in connection with an
+ operator class, it is often the case that the other data type has a
+ related operator class of its own. It is helpful to make the connections
+ between related classes explicit, because this can aid the planner in
+ optimizing SQL queries (particularly for B-tree operator classes, since
+ the planner contains a great deal of knowledge about how to work with them).
+ </para>
+
+ <para>
+ To handle these needs, <productname>PostgreSQL</productname>
+ uses the concept of an <firstterm>operator
+ family</firstterm><indexterm><primary>operator family</primary></indexterm>.
+ An operator family contains one or more operator classes, and can also
+ contain indexable operators and corresponding support functions that
+ belong to the family as a whole but not to any single class within the
+ family. We say that such operators and functions are <quote>loose</quote>
+ within the family, as opposed to being bound into a specific class.
+ Typically each operator class contains single-data-type operators
+ while cross-data-type operators are loose in the family.
+ </para>
+
+ <para>
+ All the operators and functions in an operator family must have compatible
+ semantics, where the compatibility requirements are set by the index
+ method. You might therefore wonder why bother to single out particular
+ subsets of the family as operator classes; and indeed for many purposes
+ the class divisions are irrelevant and the family is the only interesting
+ grouping. The reason for defining operator classes is that they specify
+ how much of the family is needed to support any particular index.
+ If there is an index using an operator class, then that operator class
+ cannot be dropped without dropping the index &mdash; but other parts of
+ the operator family, namely other operator classes and loose operators,
+ could be dropped. Thus, an operator class should be specified to contain
+ the minimum set of operators and functions that are reasonably needed
+ to work with an index on a specific data type, and then related but
+ non-essential operators can be added as loose members of the operator
+ family.
+ </para>
+
+ <para>
+ As an example, <productname>PostgreSQL</productname> has a built-in
+ B-tree operator family <literal>integer_ops</literal>, which includes operator
+ classes <literal>int8_ops</literal>, <literal>int4_ops</literal>, and
+ <literal>int2_ops</literal> for indexes on <type>bigint</type> (<type>int8</type>),
+ <type>integer</type> (<type>int4</type>), and <type>smallint</type> (<type>int2</type>)
+ columns respectively. The family also contains cross-data-type comparison
+ operators allowing any two of these types to be compared, so that an index
+ on one of these types can be searched using a comparison value of another
+ type. The family could be duplicated by these definitions:
+
+<programlisting><![CDATA[
+CREATE OPERATOR FAMILY integer_ops USING btree;
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING btree FAMILY integer_ops AS
+ -- standard int8 comparisons
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ FUNCTION 1 btint8cmp(int8, int8) ,
+ FUNCTION 2 btint8sortsupport(internal) ,
+ FUNCTION 3 in_range(int8, int8, int8, boolean, boolean) ,
+ FUNCTION 4 btequalimage(oid) ;
+
+CREATE OPERATOR CLASS int4_ops
+DEFAULT FOR TYPE int4 USING btree FAMILY integer_ops AS
+ -- standard int4 comparisons
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ FUNCTION 1 btint4cmp(int4, int4) ,
+ FUNCTION 2 btint4sortsupport(internal) ,
+ FUNCTION 3 in_range(int4, int4, int4, boolean, boolean) ,
+ FUNCTION 4 btequalimage(oid) ;
+
+CREATE OPERATOR CLASS int2_ops
+DEFAULT FOR TYPE int2 USING btree FAMILY integer_ops AS
+ -- standard int2 comparisons
+ OPERATOR 1 < ,
+ OPERATOR 2 <= ,
+ OPERATOR 3 = ,
+ OPERATOR 4 >= ,
+ OPERATOR 5 > ,
+ FUNCTION 1 btint2cmp(int2, int2) ,
+ FUNCTION 2 btint2sortsupport(internal) ,
+ FUNCTION 3 in_range(int2, int2, int2, boolean, boolean) ,
+ FUNCTION 4 btequalimage(oid) ;
+
+ALTER OPERATOR FAMILY integer_ops USING btree ADD
+ -- cross-type comparisons int8 vs int2
+ OPERATOR 1 < (int8, int2) ,
+ OPERATOR 2 <= (int8, int2) ,
+ OPERATOR 3 = (int8, int2) ,
+ OPERATOR 4 >= (int8, int2) ,
+ OPERATOR 5 > (int8, int2) ,
+ FUNCTION 1 btint82cmp(int8, int2) ,
+
+ -- cross-type comparisons int8 vs int4
+ OPERATOR 1 < (int8, int4) ,
+ OPERATOR 2 <= (int8, int4) ,
+ OPERATOR 3 = (int8, int4) ,
+ OPERATOR 4 >= (int8, int4) ,
+ OPERATOR 5 > (int8, int4) ,
+ FUNCTION 1 btint84cmp(int8, int4) ,
+
+ -- cross-type comparisons int4 vs int2
+ OPERATOR 1 < (int4, int2) ,
+ OPERATOR 2 <= (int4, int2) ,
+ OPERATOR 3 = (int4, int2) ,
+ OPERATOR 4 >= (int4, int2) ,
+ OPERATOR 5 > (int4, int2) ,
+ FUNCTION 1 btint42cmp(int4, int2) ,
+
+ -- cross-type comparisons int4 vs int8
+ OPERATOR 1 < (int4, int8) ,
+ OPERATOR 2 <= (int4, int8) ,
+ OPERATOR 3 = (int4, int8) ,
+ OPERATOR 4 >= (int4, int8) ,
+ OPERATOR 5 > (int4, int8) ,
+ FUNCTION 1 btint48cmp(int4, int8) ,
+
+ -- cross-type comparisons int2 vs int8
+ OPERATOR 1 < (int2, int8) ,
+ OPERATOR 2 <= (int2, int8) ,
+ OPERATOR 3 = (int2, int8) ,
+ OPERATOR 4 >= (int2, int8) ,
+ OPERATOR 5 > (int2, int8) ,
+ FUNCTION 1 btint28cmp(int2, int8) ,
+
+ -- cross-type comparisons int2 vs int4
+ OPERATOR 1 < (int2, int4) ,
+ OPERATOR 2 <= (int2, int4) ,
+ OPERATOR 3 = (int2, int4) ,
+ OPERATOR 4 >= (int2, int4) ,
+ OPERATOR 5 > (int2, int4) ,
+ FUNCTION 1 btint24cmp(int2, int4) ,
+
+ -- cross-type in_range functions
+ FUNCTION 3 in_range(int4, int4, int8, boolean, boolean) ,
+ FUNCTION 3 in_range(int4, int4, int2, boolean, boolean) ,
+ FUNCTION 3 in_range(int2, int2, int8, boolean, boolean) ,
+ FUNCTION 3 in_range(int2, int2, int4, boolean, boolean) ;
+]]>
+</programlisting>
+
+ Notice that this definition <quote>overloads</quote> the operator strategy and
+ support function numbers: each number occurs multiple times within the
+ family. This is allowed so long as each instance of a
+ particular number has distinct input data types. The instances that have
+ both input types equal to an operator class's input type are the
+ primary operators and support functions for that operator class,
+ and in most cases should be declared as part of the operator class rather
+ than as loose members of the family.
+ </para>
+
+ <para>
+ In a B-tree operator family, all the operators in the family must sort
+ compatibly, as is specified in detail in <xref linkend="btree-behavior"/>.
+ For each
+ operator in the family there must be a support function having the same
+ two input data types as the operator. It is recommended that a family be
+ complete, i.e., for each combination of data types, all operators are
+ included. Each operator class should include just the non-cross-type
+ operators and support function for its data type.
+ </para>
+
+ <para>
+ To build a multiple-data-type hash operator family, compatible hash
+ support functions must be created for each data type supported by the
+ family. Here compatibility means that the functions are guaranteed to
+ return the same hash code for any two values that are considered equal
+ by the family's equality operators, even when the values are of different
+ types. This is usually difficult to accomplish when the types have
+ different physical representations, but it can be done in some cases.
+ Furthermore, casting a value from one data type represented in the operator
+ family to another data type also represented in the operator family via
+ an implicit or binary coercion cast must not change the computed hash value.
+ Notice that there is only one support function per data type, not one
+ per equality operator. It is recommended that a family be complete, i.e.,
+ provide an equality operator for each combination of data types.
+ Each operator class should include just the non-cross-type equality
+ operator and the support function for its data type.
+ </para>
+
+ <para>
+ GiST, SP-GiST, and GIN indexes do not have any explicit notion of
+ cross-data-type operations. The set of operators supported is just
+ whatever the primary support functions for a given operator class can
+ handle.
+ </para>
+
+ <para>
+ In BRIN, the requirements depends on the framework that provides the
+ operator classes. For operator classes based on <literal>minmax</literal>,
+ the behavior required is the same as for B-tree operator families:
+ all the operators in the family must sort compatibly, and casts must
+ not change the associated sort ordering.
+ </para>
+
+ <note>
+ <para>
+ Prior to <productname>PostgreSQL</productname> 8.3, there was no concept
+ of operator families, and so any cross-data-type operators intended to be
+ used with an index had to be bound directly into the index's operator
+ class. While this approach still works, it is deprecated because it
+ makes an index's dependencies too broad, and because the planner can
+ handle cross-data-type comparisons more effectively when both data types
+ have operators in the same operator family.
+ </para>
+ </note>
+ </sect2>
+
+ <sect2 id="xindex-opclass-dependencies">
+ <title>System Dependencies on Operator Classes</title>
+
+ <indexterm>
+ <primary>ordering operator</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> uses operator classes to infer the
+ properties of operators in more ways than just whether they can be used
+ with indexes. Therefore, you might want to create operator classes
+ even if you have no intention of indexing any columns of your data type.
+ </para>
+
+ <para>
+ In particular, there are SQL features such as <literal>ORDER BY</literal> and
+ <literal>DISTINCT</literal> that require comparison and sorting of values.
+ To implement these features on a user-defined data type,
+ <productname>PostgreSQL</productname> looks for the default B-tree operator
+ class for the data type. The <quote>equals</quote> member of this operator
+ class defines the system's notion of equality of values for
+ <literal>GROUP BY</literal> and <literal>DISTINCT</literal>, and the sort ordering
+ imposed by the operator class defines the default <literal>ORDER BY</literal>
+ ordering.
+ </para>
+
+ <para>
+ If there is no default B-tree operator class for a data type, the system
+ will look for a default hash operator class. But since that kind of
+ operator class only provides equality, it is only able to support grouping
+ not sorting.
+ </para>
+
+ <para>
+ When there is no default operator class for a data type, you will get
+ errors like <quote>could not identify an ordering operator</quote> if you
+ try to use these SQL features with the data type.
+ </para>
+
+ <note>
+ <para>
+ In <productname>PostgreSQL</productname> versions before 7.4,
+ sorting and grouping operations would implicitly use operators named
+ <literal>=</literal>, <literal>&lt;</literal>, and <literal>&gt;</literal>. The new
+ behavior of relying on default operator classes avoids having to make
+ any assumption about the behavior of operators with particular names.
+ </para>
+ </note>
+
+ <para>
+ Sorting by a non-default B-tree operator class is possible by specifying
+ the class's less-than operator in a <literal>USING</literal> option,
+ for example
+<programlisting>
+SELECT * FROM mytable ORDER BY somecol USING ~&lt;~;
+</programlisting>
+ Alternatively, specifying the class's greater-than operator
+ in <literal>USING</literal> selects a descending-order sort.
+ </para>
+
+ <para>
+ Comparison of arrays of a user-defined type also relies on the semantics
+ defined by the type's default B-tree operator class. If there is no
+ default B-tree operator class, but there is a default hash operator class,
+ then array equality is supported, but not ordering comparisons.
+ </para>
+
+ <para>
+ Another SQL feature that requires even more data-type-specific knowledge
+ is the <literal>RANGE</literal> <replaceable>offset</replaceable>
+ <literal>PRECEDING</literal>/<literal>FOLLOWING</literal> framing option
+ for window functions (see <xref linkend="syntax-window-functions"/>).
+ For a query such as
+<programlisting>
+SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING)
+ FROM mytable;
+</programlisting>
+ it is not sufficient to know how to order by <literal>x</literal>;
+ the database must also understand how to <quote>subtract 5</quote> or
+ <quote>add 10</quote> to the current row's value of <literal>x</literal>
+ to identify the bounds of the current window frame. Comparing the
+ resulting bounds to other rows' values of <literal>x</literal> is
+ possible using the comparison operators provided by the B-tree operator
+ class that defines the <literal>ORDER BY</literal> ordering &mdash; but
+ addition and subtraction operators are not part of the operator class, so
+ which ones should be used? Hard-wiring that choice would be undesirable,
+ because different sort orders (different B-tree operator classes) might
+ need different behavior. Therefore, a B-tree operator class can specify
+ an <firstterm>in_range</firstterm> support function that encapsulates the
+ addition and subtraction behaviors that make sense for its sort order.
+ It can even provide more than one in_range support function, in case
+ there is more than one data type that makes sense to use as the offset
+ in <literal>RANGE</literal> clauses.
+ If the B-tree operator class associated with the window's <literal>ORDER
+ BY</literal> clause does not have a matching in_range support function,
+ the <literal>RANGE</literal> <replaceable>offset</replaceable>
+ <literal>PRECEDING</literal>/<literal>FOLLOWING</literal>
+ option is not supported.
+ </para>
+
+ <para>
+ Another important point is that an equality operator that
+ appears in a hash operator family is a candidate for hash joins,
+ hash aggregation, and related optimizations. The hash operator family
+ is essential here since it identifies the hash function(s) to use.
+ </para>
+ </sect2>
+
+ <sect2 id="xindex-ordering-ops">
+ <title>Ordering Operators</title>
+
+ <para>
+ Some index access methods (currently, only GiST and SP-GiST) support the concept of
+ <firstterm>ordering operators</firstterm>. What we have been discussing so far
+ are <firstterm>search operators</firstterm>. A search operator is one for which
+ the index can be searched to find all rows satisfying
+ <literal>WHERE</literal>
+ <replaceable>indexed_column</replaceable>
+ <replaceable>operator</replaceable>
+ <replaceable>constant</replaceable>.
+ Note that nothing is promised about the order in which the matching rows
+ will be returned. In contrast, an ordering operator does not restrict the
+ set of rows that can be returned, but instead determines their order.
+ An ordering operator is one for which the index can be scanned to return
+ rows in the order represented by
+ <literal>ORDER BY</literal>
+ <replaceable>indexed_column</replaceable>
+ <replaceable>operator</replaceable>
+ <replaceable>constant</replaceable>.
+ The reason for defining ordering operators that way is that it supports
+ nearest-neighbor searches, if the operator is one that measures distance.
+ For example, a query like
+<programlisting><![CDATA[
+SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;
+]]>
+</programlisting>
+ finds the ten places closest to a given target point. A GiST index
+ on the location column can do this efficiently because
+ <literal>&lt;-&gt;</literal> is an ordering operator.
+ </para>
+
+ <para>
+ While search operators have to return Boolean results, ordering operators
+ usually return some other type, such as float or numeric for distances.
+ This type is normally not the same as the data type being indexed.
+ To avoid hard-wiring assumptions about the behavior of different data
+ types, the definition of an ordering operator is required to name
+ a B-tree operator family that specifies the sort ordering of the result
+ data type. As was stated in the previous section, B-tree operator families
+ define <productname>PostgreSQL</productname>'s notion of ordering, so
+ this is a natural representation. Since the point <literal>&lt;-&gt;</literal>
+ operator returns <type>float8</type>, it could be specified in an operator
+ class creation command like this:
+<programlisting><![CDATA[
+OPERATOR 15 <-> (point, point) FOR ORDER BY float_ops
+]]>
+</programlisting>
+ where <literal>float_ops</literal> is the built-in operator family that includes
+ operations on <type>float8</type>. This declaration states that the index
+ is able to return rows in order of increasing values of the
+ <literal>&lt;-&gt;</literal> operator.
+ </para>
+ </sect2>
+
+ <sect2 id="xindex-opclass-features">
+ <title>Special Features of Operator Classes</title>
+
+ <para>
+ There are two special features of operator classes that we have
+ not discussed yet, mainly because they are not useful
+ with the most commonly used index methods.
+ </para>
+
+ <para>
+ Normally, declaring an operator as a member of an operator class
+ (or family) means that the index method can retrieve exactly the set of rows
+ that satisfy a <literal>WHERE</literal> condition using the operator. For example:
+<programlisting>
+SELECT * FROM table WHERE integer_column &lt; 4;
+</programlisting>
+ can be satisfied exactly by a B-tree index on the integer column.
+ But there are cases where an index is useful as an inexact guide to
+ the matching rows. For example, if a GiST index stores only bounding boxes
+ for geometric objects, then it cannot exactly satisfy a <literal>WHERE</literal>
+ condition that tests overlap between nonrectangular objects such as
+ polygons. Yet we could use the index to find objects whose bounding
+ box overlaps the bounding box of the target object, and then do the
+ exact overlap test only on the objects found by the index. If this
+ scenario applies, the index is said to be <quote>lossy</quote> for the
+ operator. Lossy index searches are implemented by having the index
+ method return a <firstterm>recheck</firstterm> flag when a row might or might
+ not really satisfy the query condition. The core system will then
+ test the original query condition on the retrieved row to see whether
+ it should be returned as a valid match. This approach works if
+ the index is guaranteed to return all the required rows, plus perhaps
+ some additional rows, which can be eliminated by performing the original
+ operator invocation. The index methods that support lossy searches
+ (currently, GiST, SP-GiST and GIN) allow the support functions of individual
+ operator classes to set the recheck flag, and so this is essentially an
+ operator-class feature.
+ </para>
+
+ <para>
+ Consider again the situation where we are storing in the index only
+ the bounding box of a complex object such as a polygon. In this
+ case there's not much value in storing the whole polygon in the index
+ entry &mdash; we might as well store just a simpler object of type
+ <type>box</type>. This situation is expressed by the <literal>STORAGE</literal>
+ option in <command>CREATE OPERATOR CLASS</command>: we'd write something like:
+
+<programlisting>
+CREATE OPERATOR CLASS polygon_ops
+ DEFAULT FOR TYPE polygon USING gist AS
+ ...
+ STORAGE box;
+</programlisting>
+
+ At present, only the GiST, SP-GiST, GIN and BRIN index methods support a
+ <literal>STORAGE</literal> type that's different from the column data type.
+ The GiST <function>compress</function> and <function>decompress</function> support
+ routines must deal with data-type conversion when <literal>STORAGE</literal>
+ is used. SP-GiST likewise requires a <function>compress</function>
+ support function to convert to the storage type, when that is different;
+ if an SP-GiST opclass also supports retrieving data, the reverse
+ conversion must be handled by the <function>consistent</function> function.
+ In GIN, the <literal>STORAGE</literal> type identifies the type of
+ the <quote>key</quote> values, which normally is different from the type
+ of the indexed column &mdash; for example, an operator class for
+ integer-array columns might have keys that are just integers. The
+ GIN <function>extractValue</function> and <function>extractQuery</function> support
+ routines are responsible for extracting keys from indexed values.
+ BRIN is similar to GIN: the <literal>STORAGE</literal> type identifies the
+ type of the stored summary values, and operator classes' support
+ procedures are responsible for interpreting the summary values
+ correctly.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/xml2.sgml b/doc/src/sgml/xml2.sgml
new file mode 100644
index 0000000..47650d9
--- /dev/null
+++ b/doc/src/sgml/xml2.sgml
@@ -0,0 +1,443 @@
+<!-- doc/src/sgml/xml2.sgml -->
+
+<sect1 id="xml2" xreflabel="xml2">
+ <title>xml2</title>
+
+ <indexterm zone="xml2">
+ <primary>xml2</primary>
+ </indexterm>
+
+ <para>
+ The <filename>xml2</filename> module provides XPath querying and
+ XSLT functionality.
+ </para>
+
+ <sect2>
+ <title>Deprecation Notice</title>
+
+ <para>
+ From <productname>PostgreSQL</productname> 8.3 on, there is XML-related
+ functionality based on the SQL/XML standard in the core server.
+ That functionality covers XML syntax checking and XPath queries,
+ which is what this module does, and more, but the API is
+ not at all compatible. It is planned that this module will be
+ removed in a future version of PostgreSQL in favor of the newer standard API, so
+ you are encouraged to try converting your applications. If you
+ find that some of the functionality of this module is not
+ available in an adequate form with the newer API, please explain
+ your issue to <email>pgsql-hackers@lists.postgresql.org</email> so that the deficiency
+ can be addressed.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Description of Functions</title>
+
+ <para>
+ <xref linkend="xml2-functions-table"/> shows the functions provided by this module.
+ These functions provide straightforward XML parsing and XPath queries.
+ </para>
+
+ <table id="xml2-functions-table">
+ <title><filename>xml2</filename> Functions</title>
+ <tgroup cols="1">
+ <thead>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ Function
+ </para>
+ <para>
+ Description
+ </para></entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xml_valid</function> ( <parameter>document</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Parses the given document and returns true if the
+ document is well-formed XML. (Note: this is an alias for the standard
+ PostgreSQL function <function>xml_is_well_formed()</function>. The
+ name <function>xml_valid()</function> is technically incorrect since validity
+ and well-formedness have different meanings in XML.)
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_string</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Evaluates the XPath query on the supplied document, and
+ casts the result to <type>text</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_number</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type> )
+ <returnvalue>real</returnvalue>
+ </para>
+ <para>
+ Evaluates the XPath query on the supplied document, and
+ casts the result to <type>real</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_bool</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type> )
+ <returnvalue>boolean</returnvalue>
+ </para>
+ <para>
+ Evaluates the XPath query on the supplied document, and
+ casts the result to <type>boolean</type>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_nodeset</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type>, <parameter>toptag</parameter> <type>text</type>, <parameter>itemtag</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Evaluates the query on the document and wraps the result in XML
+ tags. If the result is multivalued, the output will look like:
+<synopsis>
+&lt;toptag&gt;
+&lt;itemtag&gt;Value 1 which could be an XML fragment&lt;/itemtag&gt;
+&lt;itemtag&gt;Value 2....&lt;/itemtag&gt;
+&lt;/toptag&gt;
+</synopsis>
+ If either <parameter>toptag</parameter>
+ or <parameter>itemtag</parameter> is an empty string, the relevant tag
+ is omitted.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_nodeset</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type>, <parameter>itemtag</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Like <function>xpath_nodeset(document, query, toptag, itemtag)</function> but result omits <parameter>toptag</parameter>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_nodeset</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Like <function>xpath_nodeset(document, query, toptag, itemtag)</function> but result omits both tags.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_list</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type>, <parameter>separator</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ Evaluates the query on the document and returns multiple values
+ separated by the specified separator, for example <literal>Value
+ 1,Value 2,Value 3</literal> if <parameter>separator</parameter>
+ is <literal>,</literal>.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <function>xpath_list</function> ( <parameter>document</parameter> <type>text</type>, <parameter>query</parameter> <type>text</type> )
+ <returnvalue>text</returnvalue>
+ </para>
+ <para>
+ This is a wrapper for the above function that uses <literal>,</literal>
+ as the separator.
+ </para></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2>
+ <title><literal>xpath_table</literal></title>
+
+ <indexterm>
+ <primary>xpath_table</primary>
+ </indexterm>
+
+<synopsis>
+xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
+</synopsis>
+
+ <para>
+ <function>xpath_table</function> is a table function that evaluates a set of XPath
+ queries on each of a set of documents and returns the results as a
+ table. The primary key field from the original document table is returned
+ as the first column of the result so that the result set
+ can readily be used in joins. The parameters are described in
+ <xref linkend="xml2-xpath-table-parameters"/>.
+ </para>
+
+ <table id="xml2-xpath-table-parameters">
+ <title><function>xpath_table</function> Parameters</title>
+ <tgroup cols="2">
+ <colspec colname="col1" colwidth="1*"/>
+ <colspec colname="col2" colwidth="2*"/>
+ <thead>
+ <row>
+ <entry>Parameter</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><parameter>key</parameter></entry>
+ <entry>
+ <para>
+ the name of the <quote>key</quote> field &mdash; this is just a field to be used as
+ the first column of the output table, i.e., it identifies the record from
+ which each output row came (see note below about multiple values)
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry><parameter>document</parameter></entry>
+ <entry>
+ <para>
+ the name of the field containing the XML document
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry><parameter>relation</parameter></entry>
+ <entry>
+ <para>
+ the name of the table or view containing the documents
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry><parameter>xpaths</parameter></entry>
+ <entry>
+ <para>
+ one or more XPath expressions, separated by <literal>|</literal>
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry><parameter>criteria</parameter></entry>
+ <entry>
+ <para>
+ the contents of the WHERE clause. This cannot be omitted, so use
+ <literal>true</literal> or <literal>1=1</literal> if you want to
+ process all the rows in the relation
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ These parameters (except the XPath strings) are just substituted
+ into a plain SQL SELECT statement, so you have some flexibility &mdash; the
+ statement is
+ </para>
+
+ <para>
+ <literal>
+ SELECT &lt;key&gt;, &lt;document&gt; FROM &lt;relation&gt; WHERE &lt;criteria&gt;
+ </literal>
+ </para>
+
+ <para>
+ so those parameters can be <emphasis>anything</emphasis> valid in those particular
+ locations. The result from this SELECT needs to return exactly two
+ columns (which it will unless you try to list multiple fields for key
+ or document). Beware that this simplistic approach requires that you
+ validate any user-supplied values to avoid SQL injection attacks.
+ </para>
+
+ <para>
+ The function has to be used in a <literal>FROM</literal> expression, with an
+ <literal>AS</literal> clause to specify the output columns; for example
+<programlisting>
+SELECT * FROM
+xpath_table('article_id',
+ 'article_xml',
+ 'articles',
+ '/article/author|/article/pages|/article/title',
+ 'date_entered > ''2003-01-01'' ')
+AS t(article_id integer, author text, page_count integer, title text);
+</programlisting>
+ The <literal>AS</literal> clause defines the names and types of the columns in the
+ output table. The first is the <quote>key</quote> field and the rest correspond
+ to the XPath queries.
+ If there are more XPath queries than result columns,
+ the extra queries will be ignored. If there are more result columns
+ than XPath queries, the extra columns will be NULL.
+ </para>
+
+ <para>
+ Notice that this example defines the <structname>page_count</structname> result
+ column as an integer. The function deals internally with string
+ representations, so when you say you want an integer in the output, it will
+ take the string representation of the XPath result and use PostgreSQL input
+ functions to transform it into an integer (or whatever type the <type>AS</type>
+ clause requests). An error will result if it can't do this &mdash; for
+ example if the result is empty &mdash; so you may wish to just stick to
+ <type>text</type> as the column type if you think your data has any problems.
+ </para>
+
+ <para>
+ The calling <command>SELECT</command> statement doesn't necessarily have to be
+ just <literal>SELECT *</literal> &mdash; it can reference the output
+ columns by name or join them to other tables. The function produces a
+ virtual table with which you can perform any operation you wish (e.g.,
+ aggregation, joining, sorting etc.). So we could also have:
+<programlisting>
+SELECT t.title, p.fullname, p.email
+FROM xpath_table('article_id', 'article_xml', 'articles',
+ '/article/title|/article/author/@id',
+ 'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
+ AS t(article_id integer, title text, author_id integer),
+ tblPeopleInfo AS p
+WHERE t.author_id = p.person_id;
+</programlisting>
+ as a more complicated example. Of course, you could wrap all
+ of this in a view for convenience.
+ </para>
+
+ <sect3>
+ <title>Multivalued Results</title>
+
+ <para>
+ The <function>xpath_table</function> function assumes that the results of each XPath query
+ might be multivalued, so the number of rows returned by the function
+ may not be the same as the number of input documents. The first row
+ returned contains the first result from each query, the second row the
+ second result from each query. If one of the queries has fewer values
+ than the others, null values will be returned instead.
+ </para>
+
+ <para>
+ In some cases, a user will know that a given XPath query will return
+ only a single result (perhaps a unique document identifier) &mdash; if used
+ alongside an XPath query returning multiple results, the single-valued
+ result will appear only on the first row of the result. The solution
+ to this is to use the key field as part of a join against a simpler
+ XPath query. As an example:
+
+<programlisting>
+CREATE TABLE test (
+ id int PRIMARY KEY,
+ xml text
+);
+
+INSERT INTO test VALUES (1, '&lt;doc num="C1"&gt;
+&lt;line num="L1"&gt;&lt;a&gt;1&lt;/a&gt;&lt;b&gt;2&lt;/b&gt;&lt;c&gt;3&lt;/c&gt;&lt;/line&gt;
+&lt;line num="L2"&gt;&lt;a&gt;11&lt;/a&gt;&lt;b&gt;22&lt;/b&gt;&lt;c&gt;33&lt;/c&gt;&lt;/line&gt;
+&lt;/doc&gt;');
+
+INSERT INTO test VALUES (2, '&lt;doc num="C2"&gt;
+&lt;line num="L1"&gt;&lt;a&gt;111&lt;/a&gt;&lt;b&gt;222&lt;/b&gt;&lt;c&gt;333&lt;/c&gt;&lt;/line&gt;
+&lt;line num="L2"&gt;&lt;a&gt;111&lt;/a&gt;&lt;b&gt;222&lt;/b&gt;&lt;c&gt;333&lt;/c&gt;&lt;/line&gt;
+&lt;/doc&gt;');
+
+SELECT * FROM
+ xpath_table('id','xml','test',
+ '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
+ 'true')
+ AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int, val2 int, val3 int)
+WHERE id = 1 ORDER BY doc_num, line_num
+
+ id | doc_num | line_num | val1 | val2 | val3
+----+---------+----------+------+------+------
+ 1 | C1 | L1 | 1 | 2 | 3
+ 1 | | L2 | 11 | 22 | 33
+</programlisting>
+ </para>
+
+ <para>
+ To get <literal>doc_num</literal> on every line, the solution is to use two invocations
+ of <function>xpath_table</function> and join the results:
+
+<programlisting>
+SELECT t.*,i.doc_num FROM
+ xpath_table('id', 'xml', 'test',
+ '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
+ 'true')
+ AS t(id int, line_num varchar(10), val1 int, val2 int, val3 int),
+ xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
+ AS i(id int, doc_num varchar(10))
+WHERE i.id=t.id AND i.id=1
+ORDER BY doc_num, line_num;
+
+ id | line_num | val1 | val2 | val3 | doc_num
+----+----------+------+------+------+---------
+ 1 | L1 | 1 | 2 | 3 | C1
+ 1 | L2 | 11 | 22 | 33 | C1
+(2 rows)
+</programlisting>
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>XSLT Functions</title>
+
+ <para>
+ The following functions are available if libxslt is installed:
+ </para>
+
+ <sect3>
+ <title><literal>xslt_process</literal></title>
+
+ <indexterm>
+ <primary>xslt_process</primary>
+ </indexterm>
+
+<synopsis>
+xslt_process(text document, text stylesheet, text paramlist) returns text
+</synopsis>
+
+ <para>
+ This function applies the XSL stylesheet to the document and returns
+ the transformed result. The <literal>paramlist</literal> is a list of parameter
+ assignments to be used in the transformation, specified in the form
+ <literal>a=1,b=2</literal>. Note that the
+ parameter parsing is very simple-minded: parameter values cannot
+ contain commas!
+ </para>
+
+ <para>
+ There is also a two-parameter version of <function>xslt_process</function> which
+ does not pass any parameters to the transformation.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Author</title>
+
+ <para>
+ John Gray <email>jgray@azuli.co.uk</email>
+ </para>
+
+ <para>
+ Development of this module was sponsored by Torchbox Ltd. (www.torchbox.com).
+ It has the same BSD license as PostgreSQL.
+ </para>
+ </sect2>
+
+</sect1>
diff --git a/doc/src/sgml/xoper.sgml b/doc/src/sgml/xoper.sgml
new file mode 100644
index 0000000..98f4c5c
--- /dev/null
+++ b/doc/src/sgml/xoper.sgml
@@ -0,0 +1,486 @@
+<!-- doc/src/sgml/xoper.sgml -->
+
+ <sect1 id="xoper">
+ <title>User-Defined Operators</title>
+
+ <indexterm zone="xoper">
+ <primary>operator</primary>
+ <secondary>user-defined</secondary>
+ </indexterm>
+
+ <para>
+ Every operator is <quote>syntactic sugar</quote> for a call to an
+ underlying function that does the real work; so you must
+ first create the underlying function before you can create
+ the operator. However, an operator is <emphasis>not merely</emphasis>
+ syntactic sugar, because it carries additional information
+ that helps the query planner optimize queries that use the
+ operator. The next section will be devoted to explaining
+ that additional information.
+ </para>
+
+ <para>
+ <productname>PostgreSQL</productname> supports prefix
+ and infix operators. Operators can be
+ overloaded;<indexterm><primary>overloading</primary><secondary>operators</secondary></indexterm>
+ that is, the same operator name can be used for different operators
+ that have different numbers and types of operands. When a query is
+ executed, the system determines the operator to call from the
+ number and types of the provided operands.
+ </para>
+
+ <para>
+ Here is an example of creating an operator for adding two complex
+ numbers. We assume we've already created the definition of type
+ <type>complex</type> (see <xref linkend="xtypes"/>). First we need a
+ function that does the work, then we can define the operator:
+
+<programlisting>
+CREATE FUNCTION complex_add(complex, complex)
+ RETURNS complex
+ AS '<replaceable>filename</replaceable>', 'complex_add'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE OPERATOR + (
+ leftarg = complex,
+ rightarg = complex,
+ function = complex_add,
+ commutator = +
+);
+</programlisting>
+ </para>
+
+ <para>
+ Now we could execute a query like this:
+
+<screen>
+SELECT (a + b) AS c FROM test_complex;
+
+ c
+-----------------
+ (5.2,6.05)
+ (133.42,144.95)
+</screen>
+ </para>
+
+ <para>
+ We've shown how to create a binary operator here. To create a prefix
+ operator, just omit the <literal>leftarg</literal>.
+ The <literal>function</literal>
+ clause and the argument clauses are the only required items in
+ <command>CREATE OPERATOR</command>. The <literal>commutator</literal>
+ clause shown in the example is an optional hint to the query
+ optimizer. Further details about <literal>commutator</literal> and other
+ optimizer hints appear in the next section.
+ </para>
+ </sect1>
+
+ <sect1 id="xoper-optimization">
+ <title>Operator Optimization Information</title>
+
+ <indexterm zone="xoper-optimization">
+ <primary>optimization information</primary>
+ <secondary>for operators</secondary>
+ </indexterm>
+
+ <para>
+ A <productname>PostgreSQL</productname> operator definition can include
+ several optional clauses that tell the system useful things about how
+ the operator behaves. These clauses should be provided whenever
+ appropriate, because they can make for considerable speedups in execution
+ of queries that use the operator. But if you provide them, you must be
+ sure that they are right! Incorrect use of an optimization clause can
+ result in slow queries, subtly wrong output, or other Bad Things.
+ You can always leave out an optimization clause if you are not sure
+ about it; the only consequence is that queries might run slower than
+ they need to.
+ </para>
+
+ <para>
+ Additional optimization clauses might be added in future versions of
+ <productname>PostgreSQL</productname>. The ones described here are all
+ the ones that release &version; understands.
+ </para>
+
+ <para>
+ It is also possible to attach a planner support function to the function
+ that underlies an operator, providing another way of telling the system
+ about the behavior of the operator.
+ See <xref linkend="xfunc-optimization"/> for more information.
+ </para>
+
+ <sect2>
+ <title><literal>COMMUTATOR</literal></title>
+
+ <para>
+ The <literal>COMMUTATOR</literal> clause, if provided, names an operator that is the
+ commutator of the operator being defined. We say that operator A is the
+ commutator of operator B if (x A y) equals (y B x) for all possible input
+ values x, y. Notice that B is also the commutator of A. For example,
+ operators <literal>&lt;</literal> and <literal>&gt;</literal> for a particular data type are usually each others'
+ commutators, and operator <literal>+</literal> is usually commutative with itself.
+ But operator <literal>-</literal> is usually not commutative with anything.
+ </para>
+
+ <para>
+ The left operand type of a commutable operator is the same as the
+ right operand type of its commutator, and vice versa. So the name of
+ the commutator operator is all that <productname>PostgreSQL</productname>
+ needs to be given to look up the commutator, and that's all that needs to
+ be provided in the <literal>COMMUTATOR</literal> clause.
+ </para>
+
+ <para>
+ It's critical to provide commutator information for operators that
+ will be used in indexes and join clauses, because this allows the
+ query optimizer to <quote>flip around</quote> such a clause to the forms
+ needed for different plan types. For example, consider a query with
+ a WHERE clause like <literal>tab1.x = tab2.y</literal>, where <literal>tab1.x</literal>
+ and <literal>tab2.y</literal> are of a user-defined type, and suppose that
+ <literal>tab2.y</literal> is indexed. The optimizer cannot generate an
+ index scan unless it can determine how to flip the clause around to
+ <literal>tab2.y = tab1.x</literal>, because the index-scan machinery expects
+ to see the indexed column on the left of the operator it is given.
+ <productname>PostgreSQL</productname> will <emphasis>not</emphasis> simply
+ assume that this is a valid transformation &mdash; the creator of the
+ <literal>=</literal> operator must specify that it is valid, by marking the
+ operator with commutator information.
+ </para>
+
+ <para>
+ When you are defining a self-commutative operator, you just do it.
+ When you are defining a pair of commutative operators, things are
+ a little trickier: how can the first one to be defined refer to the
+ other one, which you haven't defined yet? There are two solutions
+ to this problem:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ One way is to omit the <literal>COMMUTATOR</literal> clause in the first operator that
+ you define, and then provide one in the second operator's definition.
+ Since <productname>PostgreSQL</productname> knows that commutative
+ operators come in pairs, when it sees the second definition it will
+ automatically go back and fill in the missing <literal>COMMUTATOR</literal> clause in
+ the first definition.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The other, more straightforward way is just to include <literal>COMMUTATOR</literal> clauses
+ in both definitions. When <productname>PostgreSQL</productname> processes
+ the first definition and realizes that <literal>COMMUTATOR</literal> refers to a nonexistent
+ operator, the system will make a dummy entry for that operator in the
+ system catalog. This dummy entry will have valid data only
+ for the operator name, left and right operand types, and result type,
+ since that's all that <productname>PostgreSQL</productname> can deduce
+ at this point. The first operator's catalog entry will link to this
+ dummy entry. Later, when you define the second operator, the system
+ updates the dummy entry with the additional information from the second
+ definition. If you try to use the dummy operator before it's been filled
+ in, you'll just get an error message.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><literal>NEGATOR</literal></title>
+
+ <para>
+ The <literal>NEGATOR</literal> clause, if provided, names an operator that is the
+ negator of the operator being defined. We say that operator A
+ is the negator of operator B if both return Boolean results and
+ (x A y) equals NOT (x B y) for all possible inputs x, y.
+ Notice that B is also the negator of A.
+ For example, <literal>&lt;</literal> and <literal>&gt;=</literal> are a negator pair for most data types.
+ An operator can never validly be its own negator.
+ </para>
+
+ <para>
+ Unlike commutators, a pair of unary operators could validly be marked
+ as each other's negators; that would mean (A x) equals NOT (B x)
+ for all x.
+ </para>
+
+ <para>
+ An operator's negator must have the same left and/or right operand types
+ as the operator to be defined, so just as with <literal>COMMUTATOR</literal>, only the operator
+ name need be given in the <literal>NEGATOR</literal> clause.
+ </para>
+
+ <para>
+ Providing a negator is very helpful to the query optimizer since
+ it allows expressions like <literal>NOT (x = y)</literal> to be simplified into
+ <literal>x &lt;&gt; y</literal>. This comes up more often than you might think, because
+ <literal>NOT</literal> operations can be inserted as a consequence of other rearrangements.
+ </para>
+
+ <para>
+ Pairs of negator operators can be defined using the same methods
+ explained above for commutator pairs.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title><literal>RESTRICT</literal></title>
+
+ <para>
+ The <literal>RESTRICT</literal> clause, if provided, names a restriction selectivity
+ estimation function for the operator. (Note that this is a function
+ name, not an operator name.) <literal>RESTRICT</literal> clauses only make sense for
+ binary operators that return <type>boolean</type>. The idea behind a restriction
+ selectivity estimator is to guess what fraction of the rows in a
+ table will satisfy a <literal>WHERE</literal>-clause condition of the form:
+<programlisting>
+column OP constant
+</programlisting>
+ for the current operator and a particular constant value.
+ This assists the optimizer by
+ giving it some idea of how many rows will be eliminated by <literal>WHERE</literal>
+ clauses that have this form. (What happens if the constant is on
+ the left, you might be wondering? Well, that's one of the things that
+ <literal>COMMUTATOR</literal> is for...)
+ </para>
+
+ <para>
+ Writing new restriction selectivity estimation functions is far beyond
+ the scope of this chapter, but fortunately you can usually just use
+ one of the system's standard estimators for many of your own operators.
+ These are the standard restriction estimators:
+ <simplelist>
+ <member><function>eqsel</function> for <literal>=</literal></member>
+ <member><function>neqsel</function> for <literal>&lt;&gt;</literal></member>
+ <member><function>scalarltsel</function> for <literal>&lt;</literal></member>
+ <member><function>scalarlesel</function> for <literal>&lt;=</literal></member>
+ <member><function>scalargtsel</function> for <literal>&gt;</literal></member>
+ <member><function>scalargesel</function> for <literal>&gt;=</literal></member>
+ </simplelist>
+ </para>
+
+ <para>
+ You can frequently get away with using either <function>eqsel</function> or <function>neqsel</function> for
+ operators that have very high or very low selectivity, even if they
+ aren't really equality or inequality. For example, the
+ approximate-equality geometric operators use <function>eqsel</function> on the assumption that
+ they'll usually only match a small fraction of the entries in a table.
+ </para>
+
+ <para>
+ You can use <function>scalarltsel</function>, <function>scalarlesel</function>,
+ <function>scalargtsel</function> and <function>scalargesel</function> for comparisons on
+ data types that have some sensible means of being converted into numeric
+ scalars for range comparisons. If possible, add the data type to those
+ understood by the function <function>convert_to_scalar()</function> in
+ <filename>src/backend/utils/adt/selfuncs.c</filename>.
+ (Eventually, this function should be replaced by per-data-type functions
+ identified through a column of the <classname>pg_type</classname> system catalog; but that hasn't happened
+ yet.) If you do not do this, things will still work, but the optimizer's
+ estimates won't be as good as they could be.
+ </para>
+
+ <para>
+ Another useful built-in selectivity estimation function
+ is <function>matchingsel</function>, which will work for almost any
+ binary operator, if standard MCV and/or histogram statistics are
+ collected for the input data type(s). Its default estimate is set to
+ twice the default estimate used in <function>eqsel</function>, making
+ it most suitable for comparison operators that are somewhat less
+ strict than equality. (Or you could call the
+ underlying <function>generic_restriction_selectivity</function>
+ function, providing a different default estimate.)
+ </para>
+
+ <para>
+ There are additional selectivity estimation functions designed for geometric
+ operators in <filename>src/backend/utils/adt/geo_selfuncs.c</filename>: <function>areasel</function>, <function>positionsel</function>,
+ and <function>contsel</function>. At this writing these are just stubs, but you might want
+ to use them (or even better, improve them) anyway.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><literal>JOIN</literal></title>
+
+ <para>
+ The <literal>JOIN</literal> clause, if provided, names a join selectivity
+ estimation function for the operator. (Note that this is a function
+ name, not an operator name.) <literal>JOIN</literal> clauses only make sense for
+ binary operators that return <type>boolean</type>. The idea behind a join
+ selectivity estimator is to guess what fraction of the rows in a
+ pair of tables will satisfy a <literal>WHERE</literal>-clause condition of the form:
+<programlisting>
+table1.column1 OP table2.column2
+</programlisting>
+ for the current operator. As with the <literal>RESTRICT</literal> clause, this helps
+ the optimizer very substantially by letting it figure out which
+ of several possible join sequences is likely to take the least work.
+ </para>
+
+ <para>
+ As before, this chapter will make no attempt to explain how to write
+ a join selectivity estimator function, but will just suggest that
+ you use one of the standard estimators if one is applicable:
+ <simplelist>
+ <member><function>eqjoinsel</function> for <literal>=</literal></member>
+ <member><function>neqjoinsel</function> for <literal>&lt;&gt;</literal></member>
+ <member><function>scalarltjoinsel</function> for <literal>&lt;</literal></member>
+ <member><function>scalarlejoinsel</function> for <literal>&lt;=</literal></member>
+ <member><function>scalargtjoinsel</function> for <literal>&gt;</literal></member>
+ <member><function>scalargejoinsel</function> for <literal>&gt;=</literal></member>
+ <member><function>matchingjoinsel</function> for generic matching operators</member>
+ <member><function>areajoinsel</function> for 2D area-based comparisons</member>
+ <member><function>positionjoinsel</function> for 2D position-based comparisons</member>
+ <member><function>contjoinsel</function> for 2D containment-based comparisons</member>
+ </simplelist>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title><literal>HASHES</literal></title>
+
+ <para>
+ The <literal>HASHES</literal> clause, if present, tells the system that
+ it is permissible to use the hash join method for a join based on this
+ operator. <literal>HASHES</literal> only makes sense for a binary operator that
+ returns <literal>boolean</literal>, and in practice the operator must represent
+ equality for some data type or pair of data types.
+ </para>
+
+ <para>
+ The assumption underlying hash join is that the join operator can
+ only return true for pairs of left and right values that hash to the
+ same hash code. If two values get put in different hash buckets, the
+ join will never compare them at all, implicitly assuming that the
+ result of the join operator must be false. So it never makes sense
+ to specify <literal>HASHES</literal> for operators that do not represent
+ some form of equality. In most cases it is only practical to support
+ hashing for operators that take the same data type on both sides.
+ However, sometimes it is possible to design compatible hash functions
+ for two or more data types; that is, functions that will generate the
+ same hash codes for <quote>equal</quote> values, even though the values
+ have different representations. For example, it's fairly simple
+ to arrange this property when hashing integers of different widths.
+ </para>
+
+ <para>
+ To be marked <literal>HASHES</literal>, the join operator must appear
+ in a hash index operator family. This is not enforced when you create
+ the operator, since of course the referencing operator family couldn't
+ exist yet. But attempts to use the operator in hash joins will fail
+ at run time if no such operator family exists. The system needs the
+ operator family to find the data-type-specific hash function(s) for the
+ operator's input data type(s). Of course, you must also create suitable
+ hash functions before you can create the operator family.
+ </para>
+
+ <para>
+ Care should be exercised when preparing a hash function, because there
+ are machine-dependent ways in which it might fail to do the right thing.
+ For example, if your data type is a structure in which there might be
+ uninteresting pad bits, you cannot simply pass the whole structure to
+ <function>hash_any</function>. (Unless you write your other operators and
+ functions to ensure that the unused bits are always zero, which is the
+ recommended strategy.)
+ Another example is that on machines that meet the <acronym>IEEE</acronym>
+ floating-point standard, negative zero and positive zero are different
+ values (different bit patterns) but they are defined to compare equal.
+ If a float value might contain negative zero then extra steps are needed
+ to ensure it generates the same hash value as positive zero.
+ </para>
+
+ <para>
+ A hash-joinable operator must have a commutator (itself if the two
+ operand data types are the same, or a related equality operator
+ if they are different) that appears in the same operator family.
+ If this is not the case, planner errors might occur when the operator
+ is used. Also, it is a good idea (but not strictly required) for
+ a hash operator family that supports multiple data types to provide
+ equality operators for every combination of the data types; this
+ allows better optimization.
+ </para>
+
+ <note>
+ <para>
+ The function underlying a hash-joinable operator must be marked
+ immutable or stable. If it is volatile, the system will never
+ attempt to use the operator for a hash join.
+ </para>
+ </note>
+
+ <note>
+ <para>
+ If a hash-joinable operator has an underlying function that is marked
+ strict, the
+ function must also be complete: that is, it should return true or
+ false, never null, for any two nonnull inputs. If this rule is
+ not followed, hash-optimization of <literal>IN</literal> operations might
+ generate wrong results. (Specifically, <literal>IN</literal> might return
+ false where the correct answer according to the standard would be null;
+ or it might yield an error complaining that it wasn't prepared for a
+ null result.)
+ </para>
+ </note>
+
+ </sect2>
+
+ <sect2>
+ <title><literal>MERGES</literal></title>
+
+ <para>
+ The <literal>MERGES</literal> clause, if present, tells the system that
+ it is permissible to use the merge-join method for a join based on this
+ operator. <literal>MERGES</literal> only makes sense for a binary operator that
+ returns <literal>boolean</literal>, and in practice the operator must represent
+ equality for some data type or pair of data types.
+ </para>
+
+ <para>
+ Merge join is based on the idea of sorting the left- and right-hand tables
+ into order and then scanning them in parallel. So, both data types must
+ be capable of being fully ordered, and the join operator must be one
+ that can only succeed for pairs of values that fall at the
+ <quote>same place</quote>
+ in the sort order. In practice this means that the join operator must
+ behave like equality. But it is possible to merge-join two
+ distinct data types so long as they are logically compatible. For
+ example, the <type>smallint</type>-versus-<type>integer</type>
+ equality operator is merge-joinable.
+ We only need sorting operators that will bring both data types into a
+ logically compatible sequence.
+ </para>
+
+ <para>
+ To be marked <literal>MERGES</literal>, the join operator must appear
+ as an equality member of a <literal>btree</literal> index operator family.
+ This is not enforced when you create
+ the operator, since of course the referencing operator family couldn't
+ exist yet. But the operator will not actually be used for merge joins
+ unless a matching operator family can be found. The
+ <literal>MERGES</literal> flag thus acts as a hint to the planner that
+ it's worth looking for a matching operator family.
+ </para>
+
+ <para>
+ A merge-joinable operator must have a commutator (itself if the two
+ operand data types are the same, or a related equality operator
+ if they are different) that appears in the same operator family.
+ If this is not the case, planner errors might occur when the operator
+ is used. Also, it is a good idea (but not strictly required) for
+ a <literal>btree</literal> operator family that supports multiple data types to provide
+ equality operators for every combination of the data types; this
+ allows better optimization.
+ </para>
+
+ <note>
+ <para>
+ The function underlying a merge-joinable operator must be marked
+ immutable or stable. If it is volatile, the system will never
+ attempt to use the operator for a merge join.
+ </para>
+ </note>
+ </sect2>
+ </sect1>
diff --git a/doc/src/sgml/xplang.sgml b/doc/src/sgml/xplang.sgml
new file mode 100644
index 0000000..31d403c
--- /dev/null
+++ b/doc/src/sgml/xplang.sgml
@@ -0,0 +1,230 @@
+<!-- doc/src/sgml/xplang.sgml -->
+
+ <chapter id="xplang">
+ <title>Procedural Languages</title>
+
+ <indexterm zone="xplang">
+ <primary>procedural language</primary>
+ </indexterm>
+
+ <para>
+ <productname>PostgreSQL</productname> allows user-defined functions
+ to be written in other languages besides SQL and C. These other
+ languages are generically called <firstterm>procedural
+ languages</firstterm> (<acronym>PL</acronym>s). For a function
+ written in a procedural language, the database server has
+ no built-in knowledge about how to interpret the function's source
+ text. Instead, the task is passed to a special handler that knows
+ the details of the language. The handler could either do all the
+ work of parsing, syntax analysis, execution, etc. itself, or it
+ could serve as <quote>glue</quote> between
+ <productname>PostgreSQL</productname> and an existing implementation
+ of a programming language. The handler itself is a
+ C language function compiled into a shared object and
+ loaded on demand, just like any other C function.
+ </para>
+
+ <para>
+ There are currently four procedural languages available in the
+ standard <productname>PostgreSQL</productname> distribution:
+ <application>PL/pgSQL</application> (<xref linkend="plpgsql"/>),
+ <application>PL/Tcl</application> (<xref linkend="pltcl"/>),
+ <application>PL/Perl</application> (<xref linkend="plperl"/>), and
+ <application>PL/Python</application> (<xref linkend="plpython"/>).
+ There are additional procedural languages available that are not
+ included in the core distribution. <xref linkend="external-projects"/>
+ has information about finding them. In addition other languages can
+ be defined by users; the basics of developing a new procedural
+ language are covered in <xref linkend="plhandler"/>.
+ </para>
+
+ <sect1 id="xplang-install">
+ <title>Installing Procedural Languages</title>
+
+ <para>
+ A procedural language must be <quote>installed</quote> into each
+ database where it is to be used. But procedural languages installed in
+ the database <literal>template1</literal> are automatically available in all
+ subsequently created databases, since their entries in
+ <literal>template1</literal> will be copied by <command>CREATE DATABASE</command>.
+ So the database administrator can
+ decide which languages are available in which databases and can make
+ some languages available by default if desired.
+ </para>
+
+ <para>
+ For the languages supplied with the standard distribution, it is
+ only necessary to execute <command>CREATE EXTENSION</command>
+ <replaceable>language_name</replaceable> to install the language into the
+ current database.
+ The manual procedure described below is only recommended for
+ installing languages that have not been packaged as extensions.
+ </para>
+
+ <procedure>
+ <title>Manual Procedural Language Installation</title>
+
+ <para>
+ A procedural language is installed in a database in five steps,
+ which must be carried out by a database superuser. In most cases
+ the required SQL commands should be packaged as the installation script
+ of an <quote>extension</quote>, so that <command>CREATE EXTENSION</command> can be
+ used to execute them.
+ </para>
+
+ <step performance="required" id="xplang-install-cr1">
+ <para>
+ The shared object for the language handler must be compiled and
+ installed into an appropriate library directory. This works in the same
+ way as building and installing modules with regular user-defined C
+ functions does; see <xref linkend="dfunc"/>. Often, the language
+ handler will depend on an external library that provides the actual
+ programming language engine; if so, that must be installed as well.
+ </para>
+ </step>
+
+ <step performance="required" id="xplang-install-cr2">
+ <para>
+ The handler must be declared with the command
+<synopsis>
+CREATE FUNCTION <replaceable>handler_function_name</replaceable>()
+ RETURNS language_handler
+ AS '<replaceable>path-to-shared-object</replaceable>'
+ LANGUAGE C;
+</synopsis>
+ The special return type of <type>language_handler</type> tells
+ the database system that this function does not return one of
+ the defined <acronym>SQL</acronym> data types and is not directly usable
+ in <acronym>SQL</acronym> statements.
+ </para>
+ </step>
+
+ <step performance="optional" id="xplang-install-cr3">
+ <para>
+ Optionally, the language handler can provide an <quote>inline</quote>
+ handler function that executes anonymous code blocks
+ (<link linkend="sql-do"><command>DO</command></link> commands)
+ written in this language. If an inline handler function
+ is provided by the language, declare it with a command like
+<synopsis>
+CREATE FUNCTION <replaceable>inline_function_name</replaceable>(internal)
+ RETURNS void
+ AS '<replaceable>path-to-shared-object</replaceable>'
+ LANGUAGE C;
+</synopsis>
+ </para>
+ </step>
+
+ <step performance="optional" id="xplang-install-cr4">
+ <para>
+ Optionally, the language handler can provide a <quote>validator</quote>
+ function that checks a function definition for correctness without
+ actually executing it. The validator function is called by
+ <command>CREATE FUNCTION</command> if it exists. If a validator function
+ is provided by the language, declare it with a command like
+<synopsis>
+CREATE FUNCTION <replaceable>validator_function_name</replaceable>(oid)
+ RETURNS void
+ AS '<replaceable>path-to-shared-object</replaceable>'
+ LANGUAGE C STRICT;
+</synopsis>
+ </para>
+ </step>
+
+ <step performance="required" id="xplang-install-cr5">
+ <para>
+ Finally, the PL must be declared with the command
+<synopsis>
+CREATE <optional>TRUSTED</optional> LANGUAGE <replaceable>language_name</replaceable>
+ HANDLER <replaceable>handler_function_name</replaceable>
+ <optional>INLINE <replaceable>inline_function_name</replaceable></optional>
+ <optional>VALIDATOR <replaceable>validator_function_name</replaceable></optional> ;
+</synopsis>
+ The optional key word <literal>TRUSTED</literal> specifies that
+ the language does not grant access to data that the user would
+ not otherwise have. Trusted languages are designed for ordinary
+ database users (those without superuser privilege) and allows them
+ to safely create functions and
+ procedures. Since PL functions are executed inside the database
+ server, the <literal>TRUSTED</literal> flag should only be given
+ for languages that do not allow access to database server
+ internals or the file system. The languages
+ <application>PL/pgSQL</application>,
+ <application>PL/Tcl</application>, and
+ <application>PL/Perl</application>
+ are considered trusted; the languages
+ <application>PL/TclU</application>,
+ <application>PL/PerlU</application>, and
+ <application>PL/PythonU</application>
+ are designed to provide unlimited functionality and should
+ <emphasis>not</emphasis> be marked trusted.
+ </para>
+ </step>
+ </procedure>
+
+ <para>
+ <xref linkend="xplang-install-example"/> shows how the manual
+ installation procedure would work with the language
+ <application>PL/Perl</application>.
+ </para>
+
+ <example id="xplang-install-example">
+ <title>Manual Installation of <application>PL/Perl</application></title>
+
+ <para>
+ The following command tells the database server where to find the
+ shared object for the <application>PL/Perl</application> language's call
+ handler function:
+
+<programlisting>
+CREATE FUNCTION plperl_call_handler() RETURNS language_handler AS
+ '$libdir/plperl' LANGUAGE C;
+</programlisting>
+ </para>
+
+ <para>
+ <application>PL/Perl</application> has an inline handler function
+ and a validator function, so we declare those too:
+
+<programlisting>
+CREATE FUNCTION plperl_inline_handler(internal) RETURNS void AS
+ '$libdir/plperl' LANGUAGE C STRICT;
+
+CREATE FUNCTION plperl_validator(oid) RETURNS void AS
+ '$libdir/plperl' LANGUAGE C STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ The command:
+<programlisting>
+CREATE TRUSTED LANGUAGE plperl
+ HANDLER plperl_call_handler
+ INLINE plperl_inline_handler
+ VALIDATOR plperl_validator;
+</programlisting>
+ then defines that the previously declared functions
+ should be invoked for functions and procedures where the
+ language attribute is <literal>plperl</literal>.
+ </para>
+ </example>
+
+ <para>
+ In a default <productname>PostgreSQL</productname> installation,
+ the handler for the <application>PL/pgSQL</application> language
+ is built and installed into the <quote>library</quote>
+ directory; furthermore, the <application>PL/pgSQL</application> language
+ itself is installed in all databases.
+ If <application>Tcl</application> support is configured in, the handlers for
+ <application>PL/Tcl</application> and <application>PL/TclU</application> are built and installed
+ in the library directory, but the language itself is not installed in any
+ database by default.
+ Likewise, the <application>PL/Perl</application> and <application>PL/PerlU</application>
+ handlers are built and installed if Perl support is configured, and the
+ <application>PL/PythonU</application> handler is installed if Python support is
+ configured, but these languages are not installed by default.
+ </para>
+
+ </sect1>
+
+</chapter>
diff --git a/doc/src/sgml/xtypes.sgml b/doc/src/sgml/xtypes.sgml
new file mode 100644
index 0000000..e67e5bd
--- /dev/null
+++ b/doc/src/sgml/xtypes.sgml
@@ -0,0 +1,376 @@
+<!-- doc/src/sgml/xtypes.sgml -->
+
+ <sect1 id="xtypes">
+ <title>User-Defined Types</title>
+
+ <indexterm zone="xtypes">
+ <primary>data type</primary>
+ <secondary>user-defined</secondary>
+ </indexterm>
+
+ <para>
+ As described in <xref linkend="extend-type-system"/>,
+ <productname>PostgreSQL</productname> can be extended to support new
+ data types. This section describes how to define new base types,
+ which are data types defined below the level of the <acronym>SQL</acronym>
+ language. Creating a new base type requires implementing functions
+ to operate on the type in a low-level language, usually C.
+ </para>
+
+ <para>
+ The examples in this section can be found in
+ <filename>complex.sql</filename> and <filename>complex.c</filename>
+ in the <filename>src/tutorial</filename> directory of the source distribution.
+ See the <filename>README</filename> file in that directory for instructions
+ about running the examples.
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>input function</primary>
+ </indexterm>
+ <indexterm>
+ <primary>output function</primary>
+ </indexterm>
+ A user-defined type must always have input and output functions.
+ These functions determine how the type appears in strings (for input
+ by the user and output to the user) and how the type is organized in
+ memory. The input function takes a null-terminated character string
+ as its argument and returns the internal (in memory) representation
+ of the type. The output function takes the internal representation
+ of the type as argument and returns a null-terminated character
+ string. If we want to do anything more with the type than merely
+ store it, we must provide additional functions to implement whatever
+ operations we'd like to have for the type.
+ </para>
+
+ <para>
+ Suppose we want to define a type <type>complex</type> that represents
+ complex numbers. A natural way to represent a complex number in
+ memory would be the following C structure:
+
+<programlisting>
+typedef struct Complex {
+ double x;
+ double y;
+} Complex;
+</programlisting>
+
+ We will need to make this a pass-by-reference type, since it's too
+ large to fit into a single <type>Datum</type> value.
+ </para>
+
+ <para>
+ As the external string representation of the type, we choose a
+ string of the form <literal>(x,y)</literal>.
+ </para>
+
+ <para>
+ The input and output functions are usually not hard to write,
+ especially the output function. But when defining the external
+ string representation of the type, remember that you must eventually
+ write a complete and robust parser for that representation as your
+ input function. For instance:
+
+<programlisting><![CDATA[
+PG_FUNCTION_INFO_V1(complex_in);
+
+Datum
+complex_in(PG_FUNCTION_ARGS)
+{
+ char *str = PG_GETARG_CSTRING(0);
+ double x,
+ y;
+ Complex *result;
+
+ if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ errmsg("invalid input syntax for type %s: \"%s\"",
+ "complex", str)));
+
+ result = (Complex *) palloc(sizeof(Complex));
+ result->x = x;
+ result->y = y;
+ PG_RETURN_POINTER(result);
+}
+]]>
+</programlisting>
+
+ The output function can simply be:
+
+<programlisting><![CDATA[
+PG_FUNCTION_INFO_V1(complex_out);
+
+Datum
+complex_out(PG_FUNCTION_ARGS)
+{
+ Complex *complex = (Complex *) PG_GETARG_POINTER(0);
+ char *result;
+
+ result = psprintf("(%g,%g)", complex->x, complex->y);
+ PG_RETURN_CSTRING(result);
+}
+]]>
+</programlisting>
+ </para>
+
+ <para>
+ You should be careful to make the input and output functions inverses of
+ each other. If you do not, you will have severe problems when you
+ need to dump your data into a file and then read it back in. This
+ is a particularly common problem when floating-point numbers are
+ involved.
+ </para>
+
+ <para>
+ Optionally, a user-defined type can provide binary input and output
+ routines. Binary I/O is normally faster but less portable than textual
+ I/O. As with textual I/O, it is up to you to define exactly what the
+ external binary representation is. Most of the built-in data types
+ try to provide a machine-independent binary representation. For
+ <type>complex</type>, we will piggy-back on the binary I/O converters
+ for type <type>float8</type>:
+
+<programlisting><![CDATA[
+PG_FUNCTION_INFO_V1(complex_recv);
+
+Datum
+complex_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ Complex *result;
+
+ result = (Complex *) palloc(sizeof(Complex));
+ result->x = pq_getmsgfloat8(buf);
+ result->y = pq_getmsgfloat8(buf);
+ PG_RETURN_POINTER(result);
+}
+
+PG_FUNCTION_INFO_V1(complex_send);
+
+Datum
+complex_send(PG_FUNCTION_ARGS)
+{
+ Complex *complex = (Complex *) PG_GETARG_POINTER(0);
+ StringInfoData buf;
+
+ pq_begintypsend(&buf);
+ pq_sendfloat8(&buf, complex->x);
+ pq_sendfloat8(&buf, complex->y);
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+]]>
+</programlisting>
+ </para>
+
+ <para>
+ Once we have written the I/O functions and compiled them into a shared
+ library, we can define the <type>complex</type> type in SQL.
+ First we declare it as a shell type:
+
+<programlisting>
+CREATE TYPE complex;
+</programlisting>
+
+ This serves as a placeholder that allows us to reference the type while
+ defining its I/O functions. Now we can define the I/O functions:
+
+<programlisting>
+CREATE FUNCTION complex_in(cstring)
+ RETURNS complex
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION complex_out(complex)
+ RETURNS cstring
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION complex_recv(internal)
+ RETURNS complex
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION complex_send(complex)
+ RETURNS bytea
+ AS '<replaceable>filename</replaceable>'
+ LANGUAGE C IMMUTABLE STRICT;
+</programlisting>
+ </para>
+
+ <para>
+ Finally, we can provide the full definition of the data type:
+<programlisting>
+CREATE TYPE complex (
+ internallength = 16,
+ input = complex_in,
+ output = complex_out,
+ receive = complex_recv,
+ send = complex_send,
+ alignment = double
+);
+</programlisting>
+ </para>
+
+ <para>
+ <indexterm>
+ <primary>array</primary>
+ <secondary>of user-defined type</secondary>
+ </indexterm>
+ When you define a new base type,
+ <productname>PostgreSQL</productname> automatically provides support
+ for arrays of that type. The array type typically
+ has the same name as the base type with the underscore character
+ (<literal>_</literal>) prepended.
+ </para>
+
+ <para>
+ Once the data type exists, we can declare additional functions to
+ provide useful operations on the data type. Operators can then be
+ defined atop the functions, and if needed, operator classes can be
+ created to support indexing of the data type. These additional
+ layers are discussed in following sections.
+ </para>
+
+ <para>
+ If the internal representation of the data type is variable-length, the
+ internal representation must follow the standard layout for variable-length
+ data: the first four bytes must be a <type>char[4]</type> field which is
+ never accessed directly (customarily named <structfield>vl_len_</structfield>). You
+ must use the <function>SET_VARSIZE()</function> macro to store the total
+ size of the datum (including the length field itself) in this field
+ and <function>VARSIZE()</function> to retrieve it. (These macros exist
+ because the length field may be encoded depending on platform.)
+ </para>
+
+ <para>
+ For further details see the description of the
+ <xref linkend="sql-createtype"/> command.
+ </para>
+
+ <sect2 id="xtypes-toast">
+ <title>TOAST Considerations</title>
+ <indexterm>
+ <primary>TOAST</primary>
+ <secondary>and user-defined types</secondary>
+ </indexterm>
+
+ <para>
+ If the values of your data type vary in size (in internal form), it's
+ usually desirable to make the data type <acronym>TOAST</acronym>-able (see <xref
+ linkend="storage-toast"/>). You should do this even if the values are always
+ too small to be compressed or stored externally, because
+ <acronym>TOAST</acronym> can save space on small data too, by reducing header
+ overhead.
+ </para>
+
+ <para>
+ To support <acronym>TOAST</acronym> storage, the C functions operating on the data
+ type must always be careful to unpack any toasted values they are handed
+ by using <function>PG_DETOAST_DATUM</function>. (This detail is customarily hidden
+ by defining type-specific <function>GETARG_DATATYPE_P</function> macros.)
+ Then, when running the <command>CREATE TYPE</command> command, specify the
+ internal length as <literal>variable</literal> and select some appropriate storage
+ option other than <literal>plain</literal>.
+ </para>
+
+ <para>
+ If data alignment is unimportant (either just for a specific function or
+ because the data type specifies byte alignment anyway) then it's possible
+ to avoid some of the overhead of <function>PG_DETOAST_DATUM</function>. You can use
+ <function>PG_DETOAST_DATUM_PACKED</function> instead (customarily hidden by
+ defining a <function>GETARG_DATATYPE_PP</function> macro) and using the macros
+ <function>VARSIZE_ANY_EXHDR</function> and <function>VARDATA_ANY</function> to access
+ a potentially-packed datum.
+ Again, the data returned by these macros is not aligned even if the data
+ type definition specifies an alignment. If the alignment is important you
+ must go through the regular <function>PG_DETOAST_DATUM</function> interface.
+ </para>
+
+ <note>
+ <para>
+ Older code frequently declares <structfield>vl_len_</structfield> as an
+ <type>int32</type> field instead of <type>char[4]</type>. This is OK as long as
+ the struct definition has other fields that have at least <type>int32</type>
+ alignment. But it is dangerous to use such a struct definition when
+ working with a potentially unaligned datum; the compiler may take it as
+ license to assume the datum actually is aligned, leading to core dumps on
+ architectures that are strict about alignment.
+ </para>
+ </note>
+
+ <para>
+ Another feature that's enabled by <acronym>TOAST</acronym> support is the
+ possibility of having an <firstterm>expanded</firstterm> in-memory data
+ representation that is more convenient to work with than the format that
+ is stored on disk. The regular or <quote>flat</quote> varlena storage format
+ is ultimately just a blob of bytes; it cannot for example contain
+ pointers, since it may get copied to other locations in memory.
+ For complex data types, the flat format may be quite expensive to work
+ with, so <productname>PostgreSQL</productname> provides a way to <quote>expand</quote>
+ the flat format into a representation that is more suited to computation,
+ and then pass that format in-memory between functions of the data type.
+ </para>
+
+ <para>
+ To use expanded storage, a data type must define an expanded format that
+ follows the rules given in <filename>src/include/utils/expandeddatum.h</filename>,
+ and provide functions to <quote>expand</quote> a flat varlena value into
+ expanded format and <quote>flatten</quote> the expanded format back to the
+ regular varlena representation. Then ensure that all C functions for
+ the data type can accept either representation, possibly by converting
+ one into the other immediately upon receipt. This does not require fixing
+ all existing functions for the data type at once, because the standard
+ <function>PG_DETOAST_DATUM</function> macro is defined to convert expanded inputs
+ into regular flat format. Therefore, existing functions that work with
+ the flat varlena format will continue to work, though slightly
+ inefficiently, with expanded inputs; they need not be converted until and
+ unless better performance is important.
+ </para>
+
+ <para>
+ C functions that know how to work with an expanded representation
+ typically fall into two categories: those that can only handle expanded
+ format, and those that can handle either expanded or flat varlena inputs.
+ The former are easier to write but may be less efficient overall, because
+ converting a flat input to expanded form for use by a single function may
+ cost more than is saved by operating on the expanded format.
+ When only expanded format need be handled, conversion of flat inputs to
+ expanded form can be hidden inside an argument-fetching macro, so that
+ the function appears no more complex than one working with traditional
+ varlena input.
+ To handle both types of input, write an argument-fetching function that
+ will detoast external, short-header, and compressed varlena inputs, but
+ not expanded inputs. Such a function can be defined as returning a
+ pointer to a union of the flat varlena format and the expanded format.
+ Callers can use the <function>VARATT_IS_EXPANDED_HEADER()</function> macro to
+ determine which format they received.
+ </para>
+
+ <para>
+ The <acronym>TOAST</acronym> infrastructure not only allows regular varlena
+ values to be distinguished from expanded values, but also
+ distinguishes <quote>read-write</quote> and <quote>read-only</quote> pointers to
+ expanded values. C functions that only need to examine an expanded
+ value, or will only change it in safe and non-semantically-visible ways,
+ need not care which type of pointer they receive. C functions that
+ produce a modified version of an input value are allowed to modify an
+ expanded input value in-place if they receive a read-write pointer, but
+ must not modify the input if they receive a read-only pointer; in that
+ case they have to copy the value first, producing a new value to modify.
+ A C function that has constructed a new expanded value should always
+ return a read-write pointer to it. Also, a C function that is modifying
+ a read-write expanded value in-place should take care to leave the value
+ in a sane state if it fails partway through.
+ </para>
+
+ <para>
+ For examples of working with expanded values, see the standard array
+ infrastructure, particularly
+ <filename>src/backend/utils/adt/array_expanded.c</filename>.
+ </para>
+
+ </sect2>
+
+</sect1>